summaryrefslogtreecommitdiffstats
path: root/comm/third_party/libgcrypt
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/libgcrypt')
-rw-r--r--comm/third_party/libgcrypt/AUTHORS257
-rw-r--r--comm/third_party/libgcrypt/COPYING340
-rw-r--r--comm/third_party/libgcrypt/COPYING.LIB510
-rw-r--r--comm/third_party/libgcrypt/ChangeLog13947
-rw-r--r--comm/third_party/libgcrypt/ChangeLog-20111499
-rw-r--r--comm/third_party/libgcrypt/INSTALL234
-rw-r--r--comm/third_party/libgcrypt/LICENSES239
-rw-r--r--comm/third_party/libgcrypt/Makefile.am158
-rw-r--r--comm/third_party/libgcrypt/Makefile.in1019
-rw-r--r--comm/third_party/libgcrypt/NEWS1440
-rw-r--r--comm/third_party/libgcrypt/README276
-rw-r--r--comm/third_party/libgcrypt/README.GIT49
-rw-r--r--comm/third_party/libgcrypt/THANKS168
-rw-r--r--comm/third_party/libgcrypt/TODO59
-rw-r--r--comm/third_party/libgcrypt/VERSION1
-rw-r--r--comm/third_party/libgcrypt/acinclude.m4392
-rw-r--r--comm/third_party/libgcrypt/aclocal.m41201
-rw-r--r--comm/third_party/libgcrypt/autogen.rc13
-rwxr-xr-xcomm/third_party/libgcrypt/autogen.sh513
-rw-r--r--comm/third_party/libgcrypt/build-aux/ChangeLog-2011169
-rwxr-xr-xcomm/third_party/libgcrypt/build-aux/compile347
-rwxr-xr-xcomm/third_party/libgcrypt/build-aux/config.guess1456
-rwxr-xr-xcomm/third_party/libgcrypt/build-aux/config.rpath690
-rwxr-xr-xcomm/third_party/libgcrypt/build-aux/config.sub1823
-rwxr-xr-xcomm/third_party/libgcrypt/build-aux/depcomp791
-rw-r--r--comm/third_party/libgcrypt/build-aux/git-log-fix14
-rw-r--r--comm/third_party/libgcrypt/build-aux/git-log-footer14
-rwxr-xr-xcomm/third_party/libgcrypt/build-aux/install-sh527
-rw-r--r--comm/third_party/libgcrypt/build-aux/ltmain.sh9664
-rwxr-xr-xcomm/third_party/libgcrypt/build-aux/mdate-sh224
-rwxr-xr-xcomm/third_party/libgcrypt/build-aux/missing215
-rw-r--r--comm/third_party/libgcrypt/build-aux/texinfo.tex8638
-rw-r--r--comm/third_party/libgcrypt/cipher/ChangeLog-20114279
-rw-r--r--comm/third_party/libgcrypt/cipher/Makefile.am258
-rw-r--r--comm/third_party/libgcrypt/cipher/Makefile.in1445
-rw-r--r--comm/third_party/libgcrypt/cipher/arcfour-amd64.S108
-rw-r--r--comm/third_party/libgcrypt/cipher/arcfour.c216
-rw-r--r--comm/third_party/libgcrypt/cipher/asm-common-aarch64.h104
-rw-r--r--comm/third_party/libgcrypt/cipher/asm-common-amd64.h189
-rw-r--r--comm/third_party/libgcrypt/cipher/asm-common-s390x.h90
-rw-r--r--comm/third_party/libgcrypt/cipher/asm-inline-s390x.h157
-rw-r--r--comm/third_party/libgcrypt/cipher/asm-poly1305-aarch64.h245
-rw-r--r--comm/third_party/libgcrypt/cipher/asm-poly1305-amd64.h171
-rw-r--r--comm/third_party/libgcrypt/cipher/asm-poly1305-s390x.h140
-rw-r--r--comm/third_party/libgcrypt/cipher/bithelp.h123
-rw-r--r--comm/third_party/libgcrypt/cipher/blake2.c996
-rw-r--r--comm/third_party/libgcrypt/cipher/blake2b-amd64-avx2.S300
-rw-r--r--comm/third_party/libgcrypt/cipher/blake2s-amd64-avx.S278
-rw-r--r--comm/third_party/libgcrypt/cipher/blowfish-amd64.S601
-rw-r--r--comm/third_party/libgcrypt/cipher/blowfish-arm.S743
-rw-r--r--comm/third_party/libgcrypt/cipher/blowfish.c1142
-rw-r--r--comm/third_party/libgcrypt/cipher/bufhelp.h385
-rw-r--r--comm/third_party/libgcrypt/cipher/camellia-aarch64.S586
-rw-r--r--comm/third_party/libgcrypt/cipher/camellia-aesni-avx-amd64.S2618
-rw-r--r--comm/third_party/libgcrypt/cipher/camellia-aesni-avx2-amd64.S1782
-rw-r--r--comm/third_party/libgcrypt/cipher/camellia-arm.S626
-rw-r--r--comm/third_party/libgcrypt/cipher/camellia-glue.c1097
-rw-r--r--comm/third_party/libgcrypt/cipher/camellia.c1413
-rw-r--r--comm/third_party/libgcrypt/cipher/camellia.h95
-rw-r--r--comm/third_party/libgcrypt/cipher/cast5-amd64.S663
-rw-r--r--comm/third_party/libgcrypt/cipher/cast5-arm.S728
-rw-r--r--comm/third_party/libgcrypt/cipher/cast5.c1238
-rw-r--r--comm/third_party/libgcrypt/cipher/chacha20-aarch64.S648
-rw-r--r--comm/third_party/libgcrypt/cipher/chacha20-amd64-avx2.S601
-rw-r--r--comm/third_party/libgcrypt/cipher/chacha20-amd64-ssse3.S1012
-rw-r--r--comm/third_party/libgcrypt/cipher/chacha20-armv7-neon.S393
-rw-r--r--comm/third_party/libgcrypt/cipher/chacha20-ppc.c646
-rw-r--r--comm/third_party/libgcrypt/cipher/chacha20-s390x.S1561
-rw-r--r--comm/third_party/libgcrypt/cipher/chacha20.c1306
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-aeswrap.c209
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-cbc.c292
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-ccm.c415
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-cfb.c317
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-cmac.c292
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-ctr.c120
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-eax.c289
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-gcm-armv7-neon.S341
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-gcm-armv8-aarch32-ce.S433
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-gcm-armv8-aarch64-ce.S424
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-gcm-intel-pclmul.c712
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-gcm.c1207
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-internal.h809
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-ocb.c761
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-ofb.c108
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-poly1305.c375
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-selftest.c512
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-selftest.h69
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher-xts.c189
-rw-r--r--comm/third_party/libgcrypt/cipher/cipher.c1767
-rw-r--r--comm/third_party/libgcrypt/cipher/crc-armv8-aarch64-ce.S497
-rw-r--r--comm/third_party/libgcrypt/cipher/crc-armv8-ce.c229
-rw-r--r--comm/third_party/libgcrypt/cipher/crc-intel-pclmul.c939
-rw-r--r--comm/third_party/libgcrypt/cipher/crc-ppc.c656
-rw-r--r--comm/third_party/libgcrypt/cipher/crc.c955
-rw-r--r--comm/third_party/libgcrypt/cipher/des-amd64.S1111
-rw-r--r--comm/third_party/libgcrypt/cipher/des.c1507
-rw-r--r--comm/third_party/libgcrypt/cipher/dsa-common.c418
-rw-r--r--comm/third_party/libgcrypt/cipher/dsa.c1394
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc-common.h140
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc-curves.c1603
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc-ecdh.c127
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc-ecdsa.c248
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc-eddsa.c1182
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc-gost.c218
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc-misc.c438
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc-sm2.c569
-rw-r--r--comm/third_party/libgcrypt/cipher/ecc.c1779
-rw-r--r--comm/third_party/libgcrypt/cipher/elgamal.c1149
-rw-r--r--comm/third_party/libgcrypt/cipher/gost-s-box.c266
-rw-r--r--comm/third_party/libgcrypt/cipher/gost.h34
-rw-r--r--comm/third_party/libgcrypt/cipher/gost28147.c553
-rw-r--r--comm/third_party/libgcrypt/cipher/gostr3411-94.c383
-rw-r--r--comm/third_party/libgcrypt/cipher/hash-common.c193
-rw-r--r--comm/third_party/libgcrypt/cipher/hash-common.h62
-rw-r--r--comm/third_party/libgcrypt/cipher/idea.c382
-rw-r--r--comm/third_party/libgcrypt/cipher/kdf-internal.h40
-rw-r--r--comm/third_party/libgcrypt/cipher/kdf.c503
-rw-r--r--comm/third_party/libgcrypt/cipher/keccak-armv7-neon.S945
-rw-r--r--comm/third_party/libgcrypt/cipher/keccak.c1577
-rw-r--r--comm/third_party/libgcrypt/cipher/keccak_permute_32.h536
-rw-r--r--comm/third_party/libgcrypt/cipher/keccak_permute_64.h385
-rw-r--r--comm/third_party/libgcrypt/cipher/mac-cmac.c524
-rw-r--r--comm/third_party/libgcrypt/cipher/mac-gmac.c187
-rw-r--r--comm/third_party/libgcrypt/cipher/mac-hmac.c1495
-rw-r--r--comm/third_party/libgcrypt/cipher/mac-internal.h275
-rw-r--r--comm/third_party/libgcrypt/cipher/mac-poly1305.c364
-rw-r--r--comm/third_party/libgcrypt/cipher/mac.c808
-rw-r--r--comm/third_party/libgcrypt/cipher/md.c1639
-rw-r--r--comm/third_party/libgcrypt/cipher/md4.c296
-rw-r--r--comm/third_party/libgcrypt/cipher/md5.c322
-rw-r--r--comm/third_party/libgcrypt/cipher/poly1305-internal.h64
-rw-r--r--comm/third_party/libgcrypt/cipher/poly1305-s390x.S87
-rw-r--r--comm/third_party/libgcrypt/cipher/poly1305.c740
-rw-r--r--comm/third_party/libgcrypt/cipher/primegen.c1878
-rw-r--r--comm/third_party/libgcrypt/cipher/pubkey-internal.h105
-rw-r--r--comm/third_party/libgcrypt/cipher/pubkey-util.c1160
-rw-r--r--comm/third_party/libgcrypt/cipher/pubkey.c970
-rw-r--r--comm/third_party/libgcrypt/cipher/rfc2268.c378
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-aarch64.S514
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-aesni.c3965
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-amd64.S477
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-arm.S581
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-armv8-aarch32-ce.S1867
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-armv8-aarch64-ce.S1613
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-armv8-ce.c414
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-internal.h194
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-padlock.c110
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-ppc-common.h342
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-ppc-functions.h2020
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-ppc.c259
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-ppc9le.c102
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-s390x.c1155
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-ssse3-amd64-asm.S874
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-ssse3-amd64.c743
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael-tables.h227
-rw-r--r--comm/third_party/libgcrypt/cipher/rijndael.c2032
-rw-r--r--comm/third_party/libgcrypt/cipher/rmd160.c529
-rw-r--r--comm/third_party/libgcrypt/cipher/rsa-common.c1038
-rw-r--r--comm/third_party/libgcrypt/cipher/rsa.c2035
-rw-r--r--comm/third_party/libgcrypt/cipher/salsa20-amd64.S940
-rw-r--r--comm/third_party/libgcrypt/cipher/salsa20-armv7-neon.S899
-rw-r--r--comm/third_party/libgcrypt/cipher/salsa20.c600
-rw-r--r--comm/third_party/libgcrypt/cipher/scrypt.c322
-rw-r--r--comm/third_party/libgcrypt/cipher/seed.c478
-rw-r--r--comm/third_party/libgcrypt/cipher/serpent-armv7-neon.S1124
-rw-r--r--comm/third_party/libgcrypt/cipher/serpent-avx2-amd64.S1160
-rw-r--r--comm/third_party/libgcrypt/cipher/serpent-sse2-amd64.S1211
-rw-r--r--comm/third_party/libgcrypt/cipher/serpent.c1807
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1-armv7-neon.S526
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1-armv8-aarch32-ce.S220
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1-armv8-aarch64-ce.S201
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1-avx-amd64.S429
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1-avx-bmi2-amd64.S441
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1-avx2-bmi2-amd64.S573
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1-intel-shaext.c292
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1-ssse3-amd64.S437
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1.c765
-rw-r--r--comm/third_party/libgcrypt/cipher/sha1.h47
-rw-r--r--comm/third_party/libgcrypt/cipher/sha256-armv8-aarch32-ce.S231
-rw-r--r--comm/third_party/libgcrypt/cipher/sha256-armv8-aarch64-ce.S215
-rw-r--r--comm/third_party/libgcrypt/cipher/sha256-avx-amd64.S506
-rw-r--r--comm/third_party/libgcrypt/cipher/sha256-avx2-bmi2-amd64.S527
-rw-r--r--comm/third_party/libgcrypt/cipher/sha256-intel-shaext.c363
-rw-r--r--comm/third_party/libgcrypt/cipher/sha256-ppc.c795
-rw-r--r--comm/third_party/libgcrypt/cipher/sha256-ssse3-amd64.S528
-rw-r--r--comm/third_party/libgcrypt/cipher/sha256.c857
-rw-r--r--comm/third_party/libgcrypt/cipher/sha512-arm.S464
-rw-r--r--comm/third_party/libgcrypt/cipher/sha512-armv7-neon.S450
-rw-r--r--comm/third_party/libgcrypt/cipher/sha512-avx-amd64.S461
-rw-r--r--comm/third_party/libgcrypt/cipher/sha512-avx2-bmi2-amd64.S502
-rw-r--r--comm/third_party/libgcrypt/cipher/sha512-ppc.c969
-rw-r--r--comm/third_party/libgcrypt/cipher/sha512-ssse3-amd64.S467
-rw-r--r--comm/third_party/libgcrypt/cipher/sha512-ssse3-i386.c404
-rw-r--r--comm/third_party/libgcrypt/cipher/sha512.c1316
-rw-r--r--comm/third_party/libgcrypt/cipher/sm3.c473
-rw-r--r--comm/third_party/libgcrypt/cipher/sm4-aesni-avx-amd64.S987
-rw-r--r--comm/third_party/libgcrypt/cipher/sm4-aesni-avx2-amd64.S851
-rw-r--r--comm/third_party/libgcrypt/cipher/sm4.c1251
-rw-r--r--comm/third_party/libgcrypt/cipher/stribog.c1362
-rw-r--r--comm/third_party/libgcrypt/cipher/tiger.c860
-rw-r--r--comm/third_party/libgcrypt/cipher/twofish-aarch64.S321
-rw-r--r--comm/third_party/libgcrypt/cipher/twofish-amd64.S1184
-rw-r--r--comm/third_party/libgcrypt/cipher/twofish-arm.S363
-rw-r--r--comm/third_party/libgcrypt/cipher/twofish-avx2-amd64.S1048
-rw-r--r--comm/third_party/libgcrypt/cipher/twofish.c1793
-rw-r--r--comm/third_party/libgcrypt/cipher/whirlpool-sse2-amd64.S348
-rw-r--r--comm/third_party/libgcrypt/cipher/whirlpool.c1535
-rw-r--r--comm/third_party/libgcrypt/compat/Makefile.am48
-rw-r--r--comm/third_party/libgcrypt/compat/Makefile.in697
-rw-r--r--comm/third_party/libgcrypt/compat/clock.c36
-rw-r--r--comm/third_party/libgcrypt/compat/compat.c40
-rw-r--r--comm/third_party/libgcrypt/compat/getpid.c29
-rw-r--r--comm/third_party/libgcrypt/compat/libcompat.h37
-rw-r--r--comm/third_party/libgcrypt/config.h.in753
-rwxr-xr-xcomm/third_party/libgcrypt/configure22807
-rw-r--r--comm/third_party/libgcrypt/configure.ac3257
-rw-r--r--comm/third_party/libgcrypt/doc/ChangeLog-2011488
-rw-r--r--comm/third_party/libgcrypt/doc/DCO29
-rw-r--r--comm/third_party/libgcrypt/doc/HACKING143
-rw-r--r--comm/third_party/libgcrypt/doc/Makefile.am106
-rw-r--r--comm/third_party/libgcrypt/doc/Makefile.in982
-rw-r--r--comm/third_party/libgcrypt/doc/README.apichanges115
-rw-r--r--comm/third_party/libgcrypt/doc/fips-fsm.eps514
-rw-r--r--comm/third_party/libgcrypt/doc/fips-fsm.fig199
-rw-r--r--comm/third_party/libgcrypt/doc/fips-fsm.pdfbin0 -> 12084 bytes
-rw-r--r--comm/third_party/libgcrypt/doc/fips-fsm.pngbin0 -> 6884 bytes
-rw-r--r--comm/third_party/libgcrypt/doc/gcrypt.info135
-rw-r--r--comm/third_party/libgcrypt/doc/gcrypt.info-17269
-rw-r--r--comm/third_party/libgcrypt/doc/gcrypt.info-2bin0 -> 23526 bytes
-rw-r--r--comm/third_party/libgcrypt/doc/gcrypt.texi6944
-rw-r--r--comm/third_party/libgcrypt/doc/gpl.texi392
-rw-r--r--comm/third_party/libgcrypt/doc/lgpl.texi560
-rw-r--r--comm/third_party/libgcrypt/doc/libgcrypt-modules.eps322
-rw-r--r--comm/third_party/libgcrypt/doc/libgcrypt-modules.fig193
-rw-r--r--comm/third_party/libgcrypt/doc/libgcrypt-modules.pdfbin0 -> 6933 bytes
-rw-r--r--comm/third_party/libgcrypt/doc/libgcrypt-modules.pngbin0 -> 2535 bytes
-rw-r--r--comm/third_party/libgcrypt/doc/stamp-vti4
-rw-r--r--comm/third_party/libgcrypt/doc/version.texi4
-rw-r--r--comm/third_party/libgcrypt/doc/yat2m.c1649
-rw-r--r--comm/third_party/libgcrypt/m4/ChangeLog-201150
-rw-r--r--comm/third_party/libgcrypt/m4/Makefile.am2
-rw-r--r--comm/third_party/libgcrypt/m4/Makefile.in491
-rw-r--r--comm/third_party/libgcrypt/m4/ax_cc_for_build.m477
-rw-r--r--comm/third_party/libgcrypt/m4/gpg-error.m4188
-rw-r--r--comm/third_party/libgcrypt/m4/libtool.m48031
-rw-r--r--comm/third_party/libgcrypt/m4/ltoptions.m4384
-rw-r--r--comm/third_party/libgcrypt/m4/ltsugar.m4123
-rw-r--r--comm/third_party/libgcrypt/m4/ltversion.m423
-rw-r--r--comm/third_party/libgcrypt/m4/lt~obsolete.m498
-rw-r--r--comm/third_party/libgcrypt/m4/noexecstack.m455
-rw-r--r--comm/third_party/libgcrypt/m4/socklen.m476
-rw-r--r--comm/third_party/libgcrypt/m4/sys_socket_h.m423
-rwxr-xr-xcomm/third_party/libgcrypt/mkinstalldirs161
-rw-r--r--comm/third_party/libgcrypt/mpi/ChangeLog-2011831
-rw-r--r--comm/third_party/libgcrypt/mpi/Makefile.am179
-rw-r--r--comm/third_party/libgcrypt/mpi/Makefile.in947
-rw-r--r--comm/third_party/libgcrypt/mpi/aarch64/distfiles6
-rw-r--r--comm/third_party/libgcrypt/mpi/aarch64/mpi-asm-defs.h4
-rw-r--r--comm/third_party/libgcrypt/mpi/aarch64/mpih-add1.S74
-rw-r--r--comm/third_party/libgcrypt/mpi/aarch64/mpih-mul1.S99
-rw-r--r--comm/third_party/libgcrypt/mpi/aarch64/mpih-mul2.S111
-rw-r--r--comm/third_party/libgcrypt/mpi/aarch64/mpih-mul3.S124
-rw-r--r--comm/third_party/libgcrypt/mpi/aarch64/mpih-sub1.S74
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/README53
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/distfiles11
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/mpih-add1.S124
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/mpih-lshift.S122
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/mpih-mul1.S90
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/mpih-mul2.S97
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/mpih-mul3.S95
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/mpih-rshift.S118
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/mpih-sub1.S124
-rw-r--r--comm/third_party/libgcrypt/mpi/alpha/udiv-qrnnd.S159
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/distfiles9
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/func_abi.h56
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/mpi-asm-defs.h4
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/mpih-add1.S64
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/mpih-lshift.S79
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/mpih-mul1.S67
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/mpih-mul2.S66
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/mpih-mul3.S67
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/mpih-rshift.S82
-rw-r--r--comm/third_party/libgcrypt/mpi/amd64/mpih-sub1.S63
-rw-r--r--comm/third_party/libgcrypt/mpi/arm/distfiles6
-rw-r--r--comm/third_party/libgcrypt/mpi/arm/mpi-asm-defs.h4
-rw-r--r--comm/third_party/libgcrypt/mpi/arm/mpih-add1.S76
-rw-r--r--comm/third_party/libgcrypt/mpi/arm/mpih-mul1.S80
-rw-r--r--comm/third_party/libgcrypt/mpi/arm/mpih-mul2.S94
-rw-r--r--comm/third_party/libgcrypt/mpi/arm/mpih-mul3.S100
-rw-r--r--comm/third_party/libgcrypt/mpi/arm/mpih-sub1.S77
-rw-r--r--comm/third_party/libgcrypt/mpi/asm-common-aarch64.h26
-rw-r--r--comm/third_party/libgcrypt/mpi/config.links470
-rw-r--r--comm/third_party/libgcrypt/mpi/ec-ed25519.c37
-rw-r--r--comm/third_party/libgcrypt/mpi/ec-internal.h25
-rw-r--r--comm/third_party/libgcrypt/mpi/ec.c2062
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/distfiles10
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/mpi-asm-defs.h8
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/mpih-add1.c65
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/mpih-lshift.c68
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/mpih-mul1.c62
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/mpih-mul2.c68
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/mpih-mul3.c68
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/mpih-rshift.c67
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/mpih-sub1.c66
-rw-r--r--comm/third_party/libgcrypt/mpi/generic/udiv-w-sdiv.c133
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa/README84
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa/distfiles7
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa/mpih-add1.S70
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa/mpih-lshift.S77
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa/mpih-rshift.S73
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa/mpih-sub1.S78
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa/udiv-qrnnd.S297
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa1.1/distfiles5
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul1.S115
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul2.S117
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul3.S126
-rw-r--r--comm/third_party/libgcrypt/mpi/hppa1.1/udiv-qrnnd.S92
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/distfiles9
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/mpih-add1.S161
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/mpih-lshift.S102
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/mpih-mul1.S94
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/mpih-mul2.S96
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/mpih-mul3.S96
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/mpih-rshift.S105
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/mpih-sub1.S162
-rw-r--r--comm/third_party/libgcrypt/mpi/i386/syntax.h94
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/README26
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/distfiles9
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/mpih-add1.S135
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/mpih-lshift.S229
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/mpih-mul1.S89
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/mpih-mul2.S93
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/mpih-mul3.S93
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/mpih-rshift.S228
-rw-r--r--comm/third_party/libgcrypt/mpi/i586/mpih-sub1.S142
-rw-r--r--comm/third_party/libgcrypt/mpi/longlong.h1801
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/distfiles8
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/mc68020/distfiles3
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S104
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S94
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S97
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/mpih-add1.S92
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/mpih-lshift.S164
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/mpih-rshift.S162
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/mpih-sub1.S91
-rw-r--r--comm/third_party/libgcrypt/mpi/m68k/syntax.h185
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/README23
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/distfiles10
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/mpi-asm-defs.h10
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/mpih-add1.S124
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/mpih-lshift.S97
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/mpih-mul1.S89
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/mpih-mul2.S101
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/mpih-mul3.S101
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/mpih-rshift.S95
-rw-r--r--comm/third_party/libgcrypt/mpi/mips3/mpih-sub1.S125
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-add.c235
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-bit.c411
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-cmp.c130
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-div.c360
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-gcd.c52
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-inline.c35
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-inline.h161
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-internal.h300
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-inv.c565
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-mod.c188
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-mpow.c223
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-mul.c212
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-pow.c772
-rw-r--r--comm/third_party/libgcrypt/mpi/mpi-scan.c130
-rw-r--r--comm/third_party/libgcrypt/mpi/mpicoder.c958
-rw-r--r--comm/third_party/libgcrypt/mpi/mpih-const-time.c197
-rw-r--r--comm/third_party/libgcrypt/mpi/mpih-div.c532
-rw-r--r--comm/third_party/libgcrypt/mpi/mpih-mul.c529
-rw-r--r--comm/third_party/libgcrypt/mpi/mpiutil.c780
-rw-r--r--comm/third_party/libgcrypt/mpi/pa7100/distfiles3
-rw-r--r--comm/third_party/libgcrypt/mpi/pa7100/mpih-lshift.S96
-rw-r--r--comm/third_party/libgcrypt/mpi/pa7100/mpih-rshift.S92
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/README115
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/distfiles3
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/mmx/distfiles2
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S457
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S453
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/sse2/distfiles5
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-add1.S91
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S96
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S136
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S127
-rw-r--r--comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S112
-rw-r--r--comm/third_party/libgcrypt/mpi/power/distfiles7
-rw-r--r--comm/third_party/libgcrypt/mpi/power/mpih-add1.S87
-rw-r--r--comm/third_party/libgcrypt/mpi/power/mpih-lshift.S64
-rw-r--r--comm/third_party/libgcrypt/mpi/power/mpih-mul1.S115
-rw-r--r--comm/third_party/libgcrypt/mpi/power/mpih-mul2.S130
-rw-r--r--comm/third_party/libgcrypt/mpi/power/mpih-mul3.S135
-rw-r--r--comm/third_party/libgcrypt/mpi/power/mpih-rshift.S64
-rw-r--r--comm/third_party/libgcrypt/mpi/power/mpih-sub1.S88
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/distfiles9
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/mpih-add1.S136
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/mpih-lshift.S198
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul1.S120
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul2.S127
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul3.S130
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/mpih-rshift.S131
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/mpih-sub1.S133
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc32/syntax.h75
-rw-r--r--comm/third_party/libgcrypt/mpi/powerpc64/distfiles0
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32/distfiles5
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32/mpih-add1.S239
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32/mpih-lshift.S97
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32/mpih-rshift.S93
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32/udiv.S195
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32v8/distfiles4
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul1.S109
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul2.S132
-rw-r--r--comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul3.S67
-rw-r--r--comm/third_party/libgcrypt/mpi/supersparc/distfiles2
-rw-r--r--comm/third_party/libgcrypt/mpi/supersparc/udiv.S118
-rw-r--r--comm/third_party/libgcrypt/random/ChangeLog-2011191
-rw-r--r--comm/third_party/libgcrypt/random/Makefile.am69
-rw-r--r--comm/third_party/libgcrypt/random/Makefile.in744
-rw-r--r--comm/third_party/libgcrypt/random/jitterentropy-base-user.h134
-rw-r--r--comm/third_party/libgcrypt/random/jitterentropy-base.c791
-rw-r--r--comm/third_party/libgcrypt/random/jitterentropy.h148
-rw-r--r--comm/third_party/libgcrypt/random/rand-internal.h148
-rw-r--r--comm/third_party/libgcrypt/random/random-csprng.c1367
-rw-r--r--comm/third_party/libgcrypt/random/random-daemon.c336
-rw-r--r--comm/third_party/libgcrypt/random/random-drbg.c2668
-rw-r--r--comm/third_party/libgcrypt/random/random-system.c250
-rw-r--r--comm/third_party/libgcrypt/random/random.c584
-rw-r--r--comm/third_party/libgcrypt/random/random.h79
-rw-r--r--comm/third_party/libgcrypt/random/rndegd.c290
-rw-r--r--comm/third_party/libgcrypt/random/rndhw.c230
-rw-r--r--comm/third_party/libgcrypt/random/rndjent.c389
-rw-r--r--comm/third_party/libgcrypt/random/rndlinux.c366
-rw-r--r--comm/third_party/libgcrypt/random/rndunix.c937
-rw-r--r--comm/third_party/libgcrypt/random/rndw32.c1030
-rw-r--r--comm/third_party/libgcrypt/random/rndw32ce.c199
-rw-r--r--comm/third_party/libgcrypt/src/ChangeLog-20112398
-rw-r--r--comm/third_party/libgcrypt/src/Makefile.am162
-rw-r--r--comm/third_party/libgcrypt/src/Makefile.in1361
-rw-r--r--comm/third_party/libgcrypt/src/cipher-proto.h280
-rw-r--r--comm/third_party/libgcrypt/src/cipher.h244
-rw-r--r--comm/third_party/libgcrypt/src/context.c137
-rw-r--r--comm/third_party/libgcrypt/src/context.h32
-rw-r--r--comm/third_party/libgcrypt/src/dumpsexp.c768
-rw-r--r--comm/third_party/libgcrypt/src/ec-context.h106
-rw-r--r--comm/third_party/libgcrypt/src/fips.c884
-rw-r--r--comm/third_party/libgcrypt/src/g10lib.h503
-rw-r--r--comm/third_party/libgcrypt/src/gcrypt-int.h534
-rw-r--r--comm/third_party/libgcrypt/src/gcrypt-testapi.h69
-rw-r--r--comm/third_party/libgcrypt/src/gcrypt.h.in1845
-rw-r--r--comm/third_party/libgcrypt/src/gcryptrnd.c680
-rw-r--r--comm/third_party/libgcrypt/src/getrandom.c326
-rw-r--r--comm/third_party/libgcrypt/src/global.c1368
-rw-r--r--comm/third_party/libgcrypt/src/hmac256.c800
-rw-r--r--comm/third_party/libgcrypt/src/hmac256.h36
-rw-r--r--comm/third_party/libgcrypt/src/hwf-arm.c393
-rw-r--r--comm/third_party/libgcrypt/src/hwf-common.h28
-rw-r--r--comm/third_party/libgcrypt/src/hwf-ppc.c243
-rw-r--r--comm/third_party/libgcrypt/src/hwf-s390x.c230
-rw-r--r--comm/third_party/libgcrypt/src/hwf-x86.c409
-rw-r--r--comm/third_party/libgcrypt/src/hwfeatures.c237
-rw-r--r--comm/third_party/libgcrypt/src/libgcrypt-config.in201
-rw-r--r--comm/third_party/libgcrypt/src/libgcrypt.def292
-rw-r--r--comm/third_party/libgcrypt/src/libgcrypt.m4167
-rw-r--r--comm/third_party/libgcrypt/src/libgcrypt.pc.in18
-rw-r--r--comm/third_party/libgcrypt/src/libgcrypt.vers128
-rw-r--r--comm/third_party/libgcrypt/src/misc.c579
-rw-r--r--comm/third_party/libgcrypt/src/missing-string.c54
-rw-r--r--comm/third_party/libgcrypt/src/mpi.h327
-rw-r--r--comm/third_party/libgcrypt/src/mpicalc.c627
-rw-r--r--comm/third_party/libgcrypt/src/secmem.c952
-rw-r--r--comm/third_party/libgcrypt/src/secmem.h42
-rw-r--r--comm/third_party/libgcrypt/src/sexp.c2699
-rw-r--r--comm/third_party/libgcrypt/src/stdmem.c246
-rw-r--r--comm/third_party/libgcrypt/src/stdmem.h32
-rw-r--r--comm/third_party/libgcrypt/src/types.h136
-rw-r--r--comm/third_party/libgcrypt/src/versioninfo.rc.in51
-rw-r--r--comm/third_party/libgcrypt/src/visibility.c1599
-rw-r--r--comm/third_party/libgcrypt/src/visibility.h521
-rw-r--r--comm/third_party/libgcrypt/tests/ChangeLog-2011944
-rw-r--r--comm/third_party/libgcrypt/tests/Makefile.am113
-rw-r--r--comm/third_party/libgcrypt/tests/Makefile.in1293
-rw-r--r--comm/third_party/libgcrypt/tests/README9
-rw-r--r--comm/third_party/libgcrypt/tests/aeswrap.c284
-rw-r--r--comm/third_party/libgcrypt/tests/basic-disable-all-hwf.in4
-rw-r--r--comm/third_party/libgcrypt/tests/basic.c14576
-rwxr-xr-xcomm/third_party/libgcrypt/tests/basic_all_hwfeature_combinations.sh111
-rw-r--r--comm/third_party/libgcrypt/tests/bench-slope.c2349
-rw-r--r--comm/third_party/libgcrypt/tests/benchmark.c2037
-rw-r--r--comm/third_party/libgcrypt/tests/blake2b.h1539
-rw-r--r--comm/third_party/libgcrypt/tests/blake2s.h1027
-rwxr-xr-xcomm/third_party/libgcrypt/tests/cavs_driver.pl2243
-rwxr-xr-xcomm/third_party/libgcrypt/tests/cavs_tests.sh135
-rw-r--r--comm/third_party/libgcrypt/tests/curves.c190
-rw-r--r--comm/third_party/libgcrypt/tests/dsa-rfc6979.c983
-rw-r--r--comm/third_party/libgcrypt/tests/fips186-dsa.c572
-rw-r--r--comm/third_party/libgcrypt/tests/fipsdrv.c2865
-rw-r--r--comm/third_party/libgcrypt/tests/gchash.c123
-rw-r--r--comm/third_party/libgcrypt/tests/genhashdata.c160
-rwxr-xr-xcomm/third_party/libgcrypt/tests/hashtest-256g.in7
-rw-r--r--comm/third_party/libgcrypt/tests/hashtest.c451
-rw-r--r--comm/third_party/libgcrypt/tests/hmac.c203
-rw-r--r--comm/third_party/libgcrypt/tests/keygen.c787
-rw-r--r--comm/third_party/libgcrypt/tests/keygrip.c341
-rw-r--r--comm/third_party/libgcrypt/tests/mpitests.c610
-rw-r--r--comm/third_party/libgcrypt/tests/pkbench.c485
-rw-r--r--comm/third_party/libgcrypt/tests/pkcs1v2-oaep.h781
-rw-r--r--comm/third_party/libgcrypt/tests/pkcs1v2-pss.h968
-rw-r--r--comm/third_party/libgcrypt/tests/pkcs1v2-v15c.h3919
-rw-r--r--comm/third_party/libgcrypt/tests/pkcs1v2-v15s.h3660
-rw-r--r--comm/third_party/libgcrypt/tests/pkcs1v2.c676
-rw-r--r--comm/third_party/libgcrypt/tests/prime.c241
-rw-r--r--comm/third_party/libgcrypt/tests/pubkey.c1203
-rw-r--r--comm/third_party/libgcrypt/tests/random.c826
-rw-r--r--comm/third_party/libgcrypt/tests/rsa-16k.key18
-rw-r--r--comm/third_party/libgcrypt/tests/rsacvt.c399
-rw-r--r--comm/third_party/libgcrypt/tests/sha3-224.h1025
-rw-r--r--comm/third_party/libgcrypt/tests/sha3-256.h1025
-rw-r--r--comm/third_party/libgcrypt/tests/sha3-384.h1025
-rw-r--r--comm/third_party/libgcrypt/tests/sha3-512.h1025
-rw-r--r--comm/third_party/libgcrypt/tests/stopwatch.h113
-rw-r--r--comm/third_party/libgcrypt/tests/t-common.h198
-rw-r--r--comm/third_party/libgcrypt/tests/t-convert.c534
-rw-r--r--comm/third_party/libgcrypt/tests/t-cv25519.c650
-rw-r--r--comm/third_party/libgcrypt/tests/t-ed25519.c497
-rw-r--r--comm/third_party/libgcrypt/tests/t-ed25519.inp6172
-rw-r--r--comm/third_party/libgcrypt/tests/t-ed448.c537
-rw-r--r--comm/third_party/libgcrypt/tests/t-ed448.inp75
-rw-r--r--comm/third_party/libgcrypt/tests/t-kdf.c1292
-rw-r--r--comm/third_party/libgcrypt/tests/t-lock.c465
-rw-r--r--comm/third_party/libgcrypt/tests/t-mpi-bit.c362
-rw-r--r--comm/third_party/libgcrypt/tests/t-mpi-point.c1324
-rw-r--r--comm/third_party/libgcrypt/tests/t-secmem.c209
-rw-r--r--comm/third_party/libgcrypt/tests/t-sexp.c1344
-rw-r--r--comm/third_party/libgcrypt/tests/t-x448.c593
-rw-r--r--comm/third_party/libgcrypt/tests/testapi.c132
-rw-r--r--comm/third_party/libgcrypt/tests/testdrv.c888
-rw-r--r--comm/third_party/libgcrypt/tests/version.c165
540 files changed, 356544 insertions, 0 deletions
diff --git a/comm/third_party/libgcrypt/AUTHORS b/comm/third_party/libgcrypt/AUTHORS
new file mode 100644
index 0000000000..f6bfcb851f
--- /dev/null
+++ b/comm/third_party/libgcrypt/AUTHORS
@@ -0,0 +1,257 @@
+Library: Libgcrypt
+Homepage: https://www.gnupg.org/related_software/libgcrypt/
+Download: https://ftp.gnupg.org/ftp/gcrypt/libgcrypt/
+ ftp://ftp.gnupg.org/gcrypt/libgcrypt/
+Repository: git://git.gnupg.org/libgcrypt.git
+Maintainer: Werner Koch <wk@gnupg.org>
+Bug reports: https://bugs.gnupg.org
+Security related bug reports: <security@gnupg.org>
+End-of-life: TBD
+License (library): LGPLv2.1+
+License (manual and tools): GPLv2+
+
+
+Libgcrypt is free software. See the files COPYING.LIB and COPYING for
+copying conditions, and LICENSES for notices about a few contributions
+that require these additional notices to be distributed. License
+copyright years may be listed using range notation, e.g., 2000-2013,
+indicating that every year in the range, inclusive, is a copyrightable
+year that would otherwise be listed individually.
+
+
+List of Copyright holders
+=========================
+
+ Copyright (C) 1989,1991-2018 Free Software Foundation, Inc.
+ Copyright (C) 1994 X Consortium
+ Copyright (C) 1996 L. Peter Deutsch
+ Copyright (C) 1997 Werner Koch
+ Copyright (C) 1998 The Internet Society
+ Copyright (C) 1996-1999 Peter Gutmann, Paul Kendall, and Chris Wedgwood
+ Copyright (C) 1996-2006 Peter Gutmann, Matt Thomlinson and Blake Coverett
+ Copyright (C) 2003 Nikos Mavroyanopoulos
+ Copyright (C) 2006-2007 NTT (Nippon Telegraph and Telephone Corporation)
+ Copyright (C) 2012-2021 g10 Code GmbH
+ Copyright (C) 2012 Simon Josefsson, Niels Möller
+ Copyright (c) 2012 Intel Corporation
+ Copyright (C) 2013 Christian Grothoff
+ Copyright (C) 2013-2021 Jussi Kivilinna
+ Copyright (C) 2013-2014 Dmitry Eremin-Solenikov
+ Copyright (C) 2014 Stephan Mueller
+ Copyright (C) 2017 Jia Zhang
+ Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
+ Copyright (C) 2020 Alibaba Group.
+ Copyright (C) 2020 Tianjia Zhang
+
+
+Authors with a FSF copyright assignment
+=======================================
+
+LIBGCRYPT Werner Koch 2001-06-07
+Assigns past and future changes.
+Assignment for future changes terminated on 2012-12-04.
+wk@gnupg.org
+Designed and implemented Libgcrypt.
+
+GNUPG Matthew Skala 1998-08-10
+Disclaims changes.
+mskala@ansuz.sooke.bc.ca
+Wrote cipher/twofish.c.
+
+GNUPG Natural Resources Canada 1998-08-11
+Disclaims changes by Matthew Skala.
+
+GNUPG Michael Roth Germany 1998-09-17
+Assigns changes.
+mroth@nessie.de
+Wrote cipher/des.c.
+Changes and bug fixes all over the place.
+
+GNUPG Niklas Hernaeus 1998-09-18
+Disclaims changes.
+nh@df.lth.se
+Weak key patches.
+
+GNUPG Rémi Guyomarch 1999-05-25
+Assigns past and future changes. (g10/compress.c, g10/encr-data.c,
+g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c)
+rguyom@mail.dotcom.fr
+
+ANY g10 Code GmbH 2001-06-07
+Assignment for future changes terminated on 2012-12-04.
+Code marked with ChangeLog entries of g10 Code employees.
+
+LIBGCRYPT Timo Schulz 2001-08-31
+Assigns past and future changes.
+twoaday@freakmail.de
+
+LIBGCRYPT Simon Josefsson 2002-10-25
+Assigns past and future changes to FSF (cipher/{md4,crc}.c, CTR mode,
+CTS/MAC flags, self test improvements)
+simon@josefsson.org
+
+LIBGCRYPT Moritz Schulte 2003-04-17
+Assigns past and future changes.
+moritz@g10code.com
+
+GNUTLS Nikolaos Mavrogiannopoulos 2003-11-22
+nmav@gnutls.org
+Original code for cipher/rfc2268.c.
+
+LIBGCRYPT The Written Word 2005-04-15
+Assigns past and future changes. (new: src/libgcrypt.pc.in,
+src/Makefile.am, src/secmem.c, mpi/hppa1.1/mpih-mul3.S,
+mpi/hppa1.1/udiv-qrnnd.S, mpi/hppa1.1/mpih-mul2.S,
+mpi/hppa1.1/mpih-mul1.S, mpi/Makefile.am, tests/prime.c,
+tests/register.c, tests/ac.c, tests/basic.c, tests/tsexp.c,
+tests/keygen.c, tests/pubkey.c, configure.ac, acinclude.m4)
+
+LIBGCRYPT Brad Hards 2006-02-09
+Assigns Past and Future Changes
+bradh@frogmouth.net
+(Added OFB mode. Changed cipher/cipher.c, test/basic.c doc/gcrypt.tex.
+ added SHA-224, changed cipher/sha256.c, added HMAC tests.)
+
+LIBGCRYPT Hye-Shik Chang 2006-09-07
+Assigns Past and Future Changes
+perky@freebsd.org
+(SEED cipher)
+
+LIBGCRYPT Werner Dittmann 2009-05-20
+Assigns Past and Future Changes
+werner.dittmann@t-online.de
+(mpi/amd64, tests/mpitests.c)
+
+GNUPG David Shaw
+Assigns past and future changes.
+dshaw@jabberwocky.com
+(cipher/camellia-glue.c and related stuff)
+
+LIBGCRYPT Andrey Jivsov 2010-12-09
+Assigns Past and Future Changes
+openpgp@brainhub.org
+(cipher/ecc.c and related files)
+
+LIBGCRYPT Ulrich Müller 2012-02-15
+Assigns Past and Future Changes
+ulm@gentoo.org
+(Changes to cipher/idea.c and related files)
+
+LIBGCRYPT Vladimir Serbinenko 2012-04-26
+Assigns Past and Future Changes
+phcoder@gmail.com
+(cipher/serpent.c)
+
+
+Authors with a DCO
+==================
+
+Andrei Scherer <andsch@inbox.com>
+2014-08-22:BF7CEF794F9.000003F0andsch@inbox.com:
+
+Christian Aistleitner <christian@quelltextlich.at>
+2013-02-26:20130226110144.GA12678@quelltextlich.at:
+
+Christian Grothoff <christian@grothoff.org>
+2013-03-21:514B5D8A.6040705@grothoff.org:
+
+Dmitry Baryshkov <dbaryshkov@gmail.com>
+Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+2013-07-13:20130713144407.GA27334@fangorn.rup.mentorg.com:
+
+Dmitry Kasatkin <dmitry.kasatkin@intel.com>
+2012-12-14:50CAE2DB.80302@intel.com:
+
+H.J. Lu <hjl.tools@gmail.com>
+2020-01-19:20200119135241.GA4970@gmail.com:
+
+Jia Zhang <qianyue.zj@alibaba-inc.com>
+2017-10-17:59E56E30.9060503@alibaba-inc.com:
+
+Jérémie Courrèges-Anglas <jca@wxcvbn.org>
+2016-05-26:87bn3ssqg0.fsf@ritchie.wxcvbn.org:
+
+Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+2012-11-15:20121115172331.150537dzb5i6jmy8@www.dalek.fi:
+
+Jussi Kivilinna <jussi.kivilinna@iki.fi>
+2013-05-06:5186720A.4090101@iki.fi:
+
+Markus Teich <markus dot teich at stusta dot mhn dot de>
+2014-10-08:20141008180509.GA2770@trolle:
+
+Martin Storsjö <martin@martin.st>
+2018-03-28:dc1605ce-a47d-34c5-8851-d9569f9ea5d3@martin.st:
+
+Mathias L. Baumann <mathias.baumann at sociomantic.com>
+2017-01-30:07c06d79-0828-b564-d604-fd16c7c86ebe@sociomantic.com:
+
+Milan Broz <gmazyland@gmail.com>
+2014-01-13:52D44CC6.4050707@gmail.com:
+
+Paul Wolneykien <manowar@altlinux.org>
+2019-11-19:20191119204459.312927aa@rigel.localdomain:
+
+Peter Wu <peter@lekensteyn.nl>
+2015-07-22:20150722191325.GA8113@al:
+
+Rafaël Carré <funman@videolan.org>
+2012-04-20:4F91988B.1080502@videolan.org:
+
+Sergey V. <sftp.mtuci@gmail.com>
+2013-11-07:2066221.5IYa7Yq760@darkstar:
+
+Shawn Landden <shawn@git.icu>
+2019-07-09:2794651562684255@iva4-64850291ca1c.qloud-c.yandex.net:
+
+Stephan Mueller <smueller@chronox.de>
+2014-08-22:2008899.25OeoelVVA@myon.chronox.de:
+
+Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+2020-01-08:dcda0127-2f45-93a3-0736-27259a33bffa@linux.alibaba.com:
+
+Tomáš Mráz <tm@t8m.info>
+2012-04-16:1334571250.5056.52.camel@vespa.frost.loc:
+
+Vitezslav Cizek <vcizek@suse.com>
+2015-11-05:20151105131424.GA32700@kolac.suse.cz:
+
+Werner Koch <wk@gnupg.org> (g10 Code GmbH)
+2012-12-05:87obi8u4h2.fsf@vigenere.g10code.de:
+
+
+More credits
+============
+
+Libgcrypt used to be part of GnuPG but has been taken out into its own
+package on 2000-12-21.
+
+Most of the stuff in mpi has been taken from an old GMP library
+version by Torbjorn Granlund <tege@noisy.tmg.se>.
+
+The files cipher/rndunix.c and cipher/rndw32.c are based on those
+files from Cryptlib. Copyright Peter Gutmann, Paul Kendall, and Chris
+Wedgwood 1996-1999.
+
+The ECC code cipher/ecc.c was based on code by Sergi Blanch i Torne,
+sergi at calcurco dot org.
+
+The implementation of the Camellia cipher has been been taken from the
+original NTT provided GPL source.
+
+The CAVS testing program tests/cavs_driver.pl is not to be considered
+a part of libgcrypt proper. We distribute it merely for convenience.
+It has a permissive license and is copyrighted by atsec information
+security corporation. See the file for details.
+
+The file salsa20.c is based on D.J. Bernstein's public domain code and
+taken from Nettle. Copyright 2012 Simon Josefsson and Niels Möller.
+
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/comm/third_party/libgcrypt/COPYING b/comm/third_party/libgcrypt/COPYING
new file mode 100644
index 0000000000..d60c31a97a
--- /dev/null
+++ b/comm/third_party/libgcrypt/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/comm/third_party/libgcrypt/COPYING.LIB b/comm/third_party/libgcrypt/COPYING.LIB
new file mode 100644
index 0000000000..cf9b6b9972
--- /dev/null
+++ b/comm/third_party/libgcrypt/COPYING.LIB
@@ -0,0 +1,510 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must
+be allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+^L
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+^L
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+^L
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+^L
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+^L
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+^L
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+^L
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library 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.
+
+ This library 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 library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+ Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/comm/third_party/libgcrypt/ChangeLog b/comm/third_party/libgcrypt/ChangeLog
new file mode 100644
index 0000000000..72ea034caf
--- /dev/null
+++ b/comm/third_party/libgcrypt/ChangeLog
@@ -0,0 +1,13947 @@
+2021-02-17 Werner Koch <wk@gnupg.org>
+
+ Release 1.9.2.
+ + commit 24bd7e8215f7982b0c8db46fd87b47b370a52ec6
+
+
+2021-02-12 NIIBE Yutaka <gniibe@fsij.org>
+
+ random: Fix build for macOS.
+ + commit d78cdf42854b17e2216890e7b78f9e7e05c0b1f8
+ * random/rndlinux.c [__APPLE__] (HAVE_GETENTROPY): Valid only when the
+ macro __MAC_10_11 is available.
+
+2021-02-08 Werner Koch <wk@gnupg.org>
+
+ tests: Fix minor glitches.
+ + commit 82395f11b444651f544f5e51c62fc6b65c04f9ef
+ * tests/basic.c (ALWAYS_INLINE): Make sure it is defined.
+ * tests/version.c (main): Print the config info to stdout.
+
+ New test Makefile target xtestsuite.
+ + commit ebc4d5670a1ada54ad907a4836eb8f6f573c2c38
+ * tests/Makefile.am (xtestsuite, xcheck): New targets.
+
+ New test driver to allow for standalone regression tests.
+ + commit b142da4c88deef4798ef96061dac399df3ddd73d
+ * tests/testdrv.c: New.
+
+2021-02-03 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ sha256-avx2: fix reading beyond end of input buffer.
+ + commit 24af2a55d862d45fe3aef6b5626a52d9bb0fb17e
+ * cipher/sha256-avx2-bmi2-amd64.S
+ (_gcry_sha256_transform_amd64_avx2): Use 'last block' code path if
+ input length is only one block.
+ * tests/basic.c (check_one_md_final): Use dynamic allocated buffer
+ so that in future similar access errors get detected by
+ tests/basic + valgrind.
+
+ ecc-ecdh: fix memory leak.
+ + commit 289543544e41cd5fe90352c5c7548ac09da533cc
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Free 'ec' at function exit.
+
+ tests: allow running 'make check' with ASAN.
+ + commit f46a6bd9b3d7ef7d1a72c5b6da5cf34ace2ff156
+ * tests/t-secmem.c (main): Skip test if environment variable
+ GCRYPT_IN_ASAN_TEST is defined.
+ * tests/t-sexp.c (main): Do not initialize secmem if environment
+ variable GCRYPT_IN_ASAN_TEST is defined.
+
+ global: make sure that bulk config string is null-terminated.
+ + commit 8716e4b2ada21456802aee67c2bc8edfec78f820
+ * src/global.c (_gcry_get_config): Append null-terminator to output
+ in the 'what == NULL' case.
+
+ Add handling for -Og with O-flag munging.
+ + commit a71b7de32b0c7c41359335a488cfe4dd70c65121
+ * cipher/Makefile.am (o_flag_munging): Add handling for '-Og'.
+ * random/Makefile.am (o_flag_munging): Add handling for '-Og'.
+
+ jent: silence ubsan warning about signed overflow.
+ + commit 6fc11291282a668839040c72a1d558a6ebbd4972
+ * random/jitterentropy-base.c (jent_stuck): Cast 'delta2' values to
+ 'uint64_t' for calculation.
+
+ Fix ubsan warnings for i386 build.
+ + commit 364e9e9d10503b36f98fbb1b489e00026f22c9d7
+ * mpi/mpicoder.c (_gcry_mpi_set_buffer) [BYTES_PER_MPI_LIMB == 4]: Cast
+ "*p--" values to mpi_limb_t before left shifting.
+ * tests/t-lock.c (main): Cast 'time(NULL)' to unsigned type.
+
+ Fix building with --disable-asm on x86.
+ + commit af23ab5c5482d625ff52e60606cf044e2b0106c8
+ * cipher/keccak.c (USE_64BIT_BMI2, USE_64BIT_SHLD)
+ (USE_32BIT_BMI2): Depend also on HAVE_CPU_ARCH_X86.
+ * random/rndjent.c [__i386__ || __x86_64__] (USE_JENT): Depend
+ also on HAVE_CPU_ARCH_X86.
+
+ md: clear bctx.count at final function.
+ + commit cb95fc53003e9f34ff80fc33627ceda605de223c
+ * cipher/md4.c (md4_final): Set bctx.count zero after
+ finalizing.
+ * cipher/md5.c (md5_final): Ditto.
+ * cipher/rmd160.c (rmd160_final): Ditto.
+ * cipher/sha1.c (sha1_final): Ditto.
+ * cipher/sha256.c (sha256_final): Ditto.
+ * cipher/sha512.c (sha512_final): Ditto.
+ * cipher/sm3.c (sm3_final): Ditto.
+ * cipher/stribog.c (stribog_final): Ditto.
+ * cipher/tiger.c (tiger_final): Ditto.
+
+2021-02-02 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Add checking key for ECDSA.
+ + commit 598d0f3e0294a487e01b88cc714a8cd0a47329bb
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_verify): Validate public key.
+ * cipher/ecc-gost.c (_gcry_ecc_gost_verify): Likewise.
+ * cipher/ecc-sm2.c (_gcry_ecc_sm2_verify): Likewise.
+
+2021-01-29 Werner Koch <wk@gnupg.org>
+
+ Release 1.9.1.
+ + commit 466299b1ceb82ec7c4dd0ca376de50399a896adf
+ * configure.ac: Bump LT version to C23/A3/R1.
+
+2021-01-29 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ hash-common: fix heap overflow when writing more data after final.
+ + commit 512c0c75276949f13b6373b5c04f7065af750b08
+ * tests/basic.c (check_one_md): Test writing to digest after read.
+ * cipher/hash-common.c (_gcry_md_block_write): Reset 'hd->count' if
+ greater than blocksize.
+
+2021-01-28 Werner Koch <wk@gnupg.org>
+
+ Add a compliance keyword to gcry_get_config.
+ + commit aa3f595341eb263980210776c7fe377b2ed24c5e
+ * src/global.c (print_config): New config line.
+
+2021-01-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ asm-common-aarch64: add MacOS support for GET_DATA_POINTER.
+ + commit 014fed5153647641376b9131ea1d87dc5e88cf42
+ * cipher/asm-common-aarch64.h [__APPLE__] (GET_DATA_POINTER): Add MacOS
+ variant of macro.
+
+2021-01-27 NIIBE Yutaka <gniibe@fsij.org>
+
+ random: Use getentropy on macOS when available.
+ + commit 6cb0faf6ceec5b2e799e6fb5f04b85d135a7da9b
+ * random/rndlinux.c [__APPLE__ && __MACH__] (getentropy): Declare.
+ (_gcry_rndlinux_gather_random): Check the symbol and use getentropy.
+
+ mpi: Fix _gcry_mpih_mod implementation.
+ + commit f06ff4e31c8e162f4a59986241c7ab43d5085927
+ * mpi/mpih-const-time.c (_gcry_mpih_mod): Handle the overflow.
+
+ build: Check spawn.h for MacOS X Tiger.
+ + commit fc901e978a0c18a3524cad5d1ef3451ed11b9347
+ * configure.ac: Add check for spawn.h.
+ * tests/random.c: Only use posix_spawn if available.
+
+2021-01-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ global: fix compile error at pragma GCC diagnostic.
+ + commit 3d095206c30d772d5fc68bf69bfc384e43f766e9
+ * src/global.c (_gcry_vcontrol): Move "pragma GCC diagnostics" outside
+ function.
+
+ cipher-proto: remove forward typedef of cipher_bulk_ops_t.
+ + commit 17aad639d29c7c835a7effb89181c7c99b16cb6a
+ * cipher/cipher-proto (cipher_bulk_ops_t): Remove typedef, leave
+ forward declaration of 'struct cipher_bulk_ops'.
+ (gcry_cipher_setkey_t): Change 'bulk_ops' to
+ 'struct cipher_bulk_ops *'.
+ * cipher/arcfour.c: Include 'cipher-internal.h'.
+ * cipher/gost28147.c: Ditto.
+ * cipher/idea.c: Ditto.
+ * cipher/rfc2268.c: Ditto.
+ * cipher/salsa20.c: Ditto.
+ * cipher/seed.c: Ditto.
+ * cipher/mac-internal.h (CTX_MAGIC_NORMAL): Rename to...
+ (CTX_MAC_MAGIC_NORMAL): ... this.
+ (CTX_MAGIC_SECURE): Rename to...
+ (CTX_MAC_MAGIC_SECURE): ... this.
+ * cipher/mac-cmac.c (cmac_open): Use CTX_MAC_MAGIC_SECURE.
+ * cipher/mac-gmac.c (gmac_open): Ditto.
+ * cipher/mac-hmac.c (hmac_open): Ditto.
+ * cipher/mac-poly1305.c (poly1305mac_open): Ditto.
+ * cipher/mac.c (mac_open): Use CTX_MAC_MAGIC_SECURE and
+ CTX_MAC_MAGIC_NORMAL.
+
+2021-01-26 David Michael <fedora.dm0@gmail.com>
+
+ cipher/sha512: Fix non-NEON ARM assembly implementation.
+ + commit 1e72c50f864ae1c77ba80c191224b9ef1d22a2e2
+ * cipher/sha512.c (do_transform_generic)
+ [USE_ARM_ASM]: Switch to the non-NEON assembly implementation.
+
+2021-01-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ blake2: fix RIP register access for AVX/AVX2 implementations.
+ + commit b2f78ae034b8d4aa3d4cc7bf85262317832f6e0a
+ * cipher/blake2b-amd64-avx2.S: Use rRIP instead of (RIP).
+ * cipher/blake2s-amd64-avx.S: Use rRIP instead of (RIP).
+
+ sha512/sha256: remove assembler macros from AMD64 implementations.
+ + commit 9f49e806f9506533236fd44b17f17b85961b20f1
+ * configure.ac (gcry_cv_gcc_platform_as_ok_for_intel_syntax): Remove
+ assembler macro check from Intel syntax assembly support check.
+ * cipher/sha256-avx-amd64.S: Replace assembler macros with C
+ preprocessor counterparts.
+ * cipher/sha256-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha256-ssse3-amd64.S: Ditto.
+ * cipher/sha512-avx-amd64.S: Ditto.
+ * cipher/sha512-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha512-ssse3-amd64.S: Ditto.
+
+ configure.ac: run assembler checks through linker for better LTO support
+ + commit 393bd6c3d1aa2b2a1b05be0e2d7fb2514e6c5ad0
+ * configure.ac (gcry_cv_gcc_arm_platform_as_ok)
+ (gcry_cv_gcc_aarch64_platform_as_ok)
+ (gcry_cv_gcc_inline_asm_ssse3, gcry_cv_gcc_inline_asm_pclmul)
+ (gcry_cv_gcc_inline_asm_shaext, gcry_cv_gcc_inline_asm_sse41)
+ (gcry_cv_gcc_inline_asm_avx, gcry_cv_gcc_inline_asm_avx2)
+ (gcry_cv_gcc_inline_asm_bmi2, gcry_cv_gcc_as_const_division_ok)
+ (gcry_cv_gcc_as_const_division_with_wadivide_ok)
+ (gcry_cv_gcc_amd64_platform_as_ok, gcry_cv_gcc_win64_platform_as_ok)
+ (gcry_cv_gcc_platform_as_ok_for_intel_syntax)
+ (gcry_cv_gcc_inline_asm_neon, gcry_cv_gcc_inline_asm_aarch32_crypto)
+ (gcry_cv_gcc_inline_asm_aarch64_neon)
+ (gcry_cv_gcc_inline_asm_aarch64_crypto)
+ (gcry_cv_gcc_inline_asm_ppc_altivec)
+ (gcry_cv_gcc_inline_asm_ppc_arch_3_00)
+ (gcry_cv_gcc_inline_asm_s390x, gcry_cv_gcc_inline_asm_s390x): Use
+ AC_LINK_IFELSE check instead of AC_COMPILE_IFELSE.
+
+ rijndael: remove unused use_xxx flags.
+ + commit a14447f8169aff30a49f5c2ab06bd5bbd1cc3531
+ * cipher/rijndael-internal.h (RIJNDAEL_context_s): Remove unused
+ 'use_padlock', 'use_aesni', 'use_ssse3', 'use_arm_ce', 'use_ppc_crypto'
+ and 'use_ppc9le_crypto'.
+ * cipher/rijndael.c (do_setkey): Do not setup 'use_padlock',
+ 'use_aesni', 'use_ssse3', 'use_arm_ce', 'use_ppc_crypto' and
+ 'use_ppc9le_crypto'.
+
+ Define HW-feature flags per architecture.
+ + commit 8d404a629167d67ed56e45de3e65d1e0b7cdeb24
+ * random/rand-internal.h (_gcry_rndhw_poll_slow): Add requested length
+ parameter.
+ * random/rndhw.c (_gcry_rndhw_poll_slow): Limit accounted bytes to 50%
+ (or 25% for RDRAND) - this code is moved from caller side.
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Move
+ HWF_INTEL_RDRAND check to _gcry_rndhw_poll_slow.
+ * src/g10lib.h (HWF_PADLOCK_*, HWF_INTEL_*): Define only if
+ HAVE_CPU_ARCH_X86.
+ (HWF_ARM_*): Define only if HAVE_CPU_ARCH_ARM.
+ (HWF_PPC_*): Define only if HAVE_CPU_ARCH_PPC.
+ (HWF_S390X_*): Define only if HAVE_CPU_ARCH_S390X.
+
+ Add configure option to force enable 'soft' HW feature bits.
+ + commit 3b34bd6e178614d6021ee7d1140646f7c8ed7519
+ * configure.ac (force_soft_hwfeatures)
+ (ENABLE_FORCE_SOFT_HWFEATURES): New.
+ * src/hwf-x86.c (detect_x86_gnuc): Enable HWF_INTEL_FAST_SHLD
+ and HWF_INTEL_FAST_VPGATHER if ENABLE_FORCE_SOFT_HWFEATURES enabled.
+
+2021-01-26 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix Ed25519 private key handling for preceding ZEROs.
+ + commit 1b74f633bd3e358fb07a856a70597019980651d2
+ * cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Fill-up or remove
+ preceding ZEROs correctly, fixing the third argument of mpi_set_opaque.
+
+ ecc: Fix initialization of CTX for sign and verify.
+ + commit 652b102697cbfe2d7bc642fc7374cb21a9cf03e6
+ * cipher/ecc.c (ecc_sign, ecc_verify): Call
+ _gcry_pk_util_init_encoding_ctx at first.
+
+2021-01-21 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Fix build of tests with non-default installation.
+ + commit fa3420b011c105ca21894489e62c7e882a3ac4dd
+ * tests/Makefile.am: Add forgotten @LDADD_FOR_TESTS_KLUDGE@.
+
+2021-01-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Split inline assembly blocks with many memory operands.
+ + commit 00df9f27181d77166ceb55f319329400bf2e6a48
+ * cipher/rijndael-aesni.c (aesni_ocb_checksum, aesni_ocb_enc)
+ (aesni_ocb_dec, _gcry_aes_aesni_ocb_auth): Split assembly blocks
+ with more than 4 memory operands to smaller blocks.
+ * cipher/sha512-ssse3-i386.c (W2): Split big assembly block to
+ three smaller blocks.
+
+ tests/basic: fix build on ARM32 when NEON disabled.
+ + commit 81354e911bfa3e135d3e07f6a8d9e98033cd921a
+ * tests/basic.c (CLUTTER_VECTOR_REGISTER_NEON)
+ (CLUTTER_VECTOR_REGISTER_AARCH64): Remove check for __ARM_FEATURE_SIMD32.
+
+ kdf: make self-test test-vector array read-only.
+ + commit 097148bc89ec8c18b9e4795733e0f0b1ae0ecd1d
+ * cipher/kdf.c (selftest_pbkdf2): Make 'tv[]' constant.
+
+ kdf: add missing null-terminator for self-test test-vector array.
+ + commit c6425a5537294dfe2beaafc9105f7af4ceac677f
+ * cipher/kdf.c (selftest_pbkdf2): Add null-terminator to TV array.
+
+ cipher/bithelp: use __builtin_ctzl when available.
+ + commit 807827cda3bacf5f475167ee6d34657713111838
+ * cipher/bithelp.h (_gcry_ctz64): Use __builtin_ctzl if available.
+
+ mpi/longlong: make use of compiler provided __builtin_ctz/__builtin_clz.
+ + commit 477355047e5c75ad2b2238a8716e4646b861184c
+ * configure.ac (gcry_cv_have_builtin_ctzl, gcry_cv_have_builtin_clz)
+ (gcry_cv_have_builtin_clzl): New checks.
+ * mpi/longlong.h (count_leading_zeros, count_trailing_zeros): Use
+ __buildin_clz[l]/__builtin_ctz[l] if available and bit counting
+ macros not yet provided by inline assembly.
+
+2021-01-19 Werner Koch <wk@gnupg.org>
+
+ Release 1.9.0.
+ + commit 0dc49af9b5371c5e2f766b70c3bede2b10db9f7e
+
+
+2021-01-19 NIIBE Yutaka <gniibe@fsij.org>
+
+ Fix DSA for FIPS 186-3.
+ + commit 30ed9593f632c728d918598037358deaeccd1968
+ * cipher/dsa.c (generate_fips186): Supply INITIAL_SEED to
+ _gcry_generate_fips186_3_prime.
+ * tests/fips186-dsa.c (check_dsa_gen_186_2): Add where tv comes from.
+ (check_dsa_gen_186_3): Implement tests.
+ * tests/pubkey.c (get_dsa_key_fips186_with_seed_new): Use the qbits
+ and seed of tests/fips186-dsa.c.
+
+2021-01-19 NIIBE Yutaka <gniibe@fsij.org>
+ Tomáš Mráz <tm@t8m.info>
+
+ Check if FIPS is operational and error return if not.
+ + commit ebeae53222648c637907f4b358888fc0e7123dc9
+ * src/visibility.c (gcry_kdf_derive): Add the check.
+ (gcry_prime_generate, gcry_prime_group_generator): Likewise.
+ (gcry_mpi_randomize): Likewise, but no return.
+
+2021-01-18 Werner Koch <wk@gnupg.org>
+
+ ecc: Change an error code of gcry_ecc_mul_point.
+ + commit ca5a90bf70598247589078478d237287ca524453
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Return
+ GPG_ERR_UNKNOWN_CURVE.
+
+2021-01-15 NIIBE Yutaka <gniibe@fsij.org>
+ Tomáš Mráz <tm@t8m.info>
+
+ kdf: Add selftest.
+ + commit 7a0da24925361a3109474d0e433511467a9e35d1
+ * src/cipher-proto.h (_gcry_kdf_selftest): New.
+ * cipher/kdf.c (check_one, selftest_pbkdf2): New.
+ (_gcry_kdf_selftest): New.
+ * src/fips.c (run_kdf_selftests): New.
+ (_gcry_fips_run_selftests): Call run_kdf_selftests.
+
+2021-01-13 NIIBE Yutaka <gniibe@fsij.org>
+ Tomáš Mráz <tm@t8m.info>
+
+ cmac: Add selftest.
+ + commit 385a89e35b0b95f15b4c6e4d5482b1fc6906f7c5
+ * cipher/mac-cmac.c (check_one, selftests_cmac_3des): New.
+ (selftests_cmac_aes, cmac_selftest): New.
+ (cmac_ops): Add cmac_selftest.
+ * src/fips.c (run_mac_selftests): Add CMAC selftests.
+
+2021-01-13 NIIBE Yutaka <gniibe@fsij.org>
+
+ sexp: Raise an error when an integer is negative with USG.
+ + commit 00d7c1c632019066a4884930d413ccc044d81af5
+ * src/sexp.c (do_vsexp_sscan): Return GPG_ERR_INV_ARG if negative.
+
+2021-01-08 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Add backward compatibility support for Ed25519 key in SEXP.
+ + commit 4768baf74be03d8973d004725f796aef329c45bf
+ * cipher/ecc-curves.c (_gcry_ecc_get_curve): Support Ed25519 keys with
+ parameter {p,a,b,g,n}.
+
+ ecc: Minor implementation change for _gcry_ecc_get_curve.
+ + commit 3fe7036d05f283df9441d42242f0047b6ea11a32
+ * cipher/ecc-curves.c (_gcry_ecc_get_curve): Flatten.
+
+2020-12-30 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add s390x/zSeries implementation of Poly1305.
+ + commit 1f75681cbba895ea2f7ea0637900721f4522e729
+ * cipher/Makefile.am: Add 'poly1305-s390x.S' and
+ 'asm-poly1305-s390x.h'.
+ * cipher/asm-poly1305-s390x.h: New
+ * cipher/chacha20-s390x.S (_gcry_chacha20_poly1305_s390x_vx_blocks8)
+ (_gcry_chacha20_poly1305_s390x_vx_blocks4_2_1): New, stitched
+ chacha20-poly1305 implementation.
+ * cipher/chacha20.c (USE_S390X_VX_POLY1305): New.
+ (_gcry_chacha20_poly1305_s390x_vx_blocks8)
+ (_gcry_chacha20_poly1305_s390x_vx_blocks4_2_1): New prototypes.
+ (_gcry_chacha20_poly1305_encrypt, _gcry_chacha20_poly1305_decrypt): Add
+ s390x/VX stitched chacha20-poly1305 code-path.
+ * cipher/poly1305-s390x.S: New.
+ * cipher/poly1305.c (USE_S390X_ASM, HAVE_ASM_POLY1305_BLOCKS): New.
+ [USE_S390X_ASM] (_gcry_poly1305_s390x_blocks1, poly1305_blocks): New.
+ * configure.ac (gcry_cv_gcc_inline_asm_s390x): Check for 'risbgn' and
+ 'algrk' instructions.
+ * tests/basic.c (_check_poly1305_cipher): Add large chacha20-poly1305
+ test vector.
+
+ Add s390x/zSeries implementation of ChaCha20.
+ + commit 6a0bb9ab7f886087d7edb0725c90485086a1c0b4
+ * cipher/Makefile.am: Add 'asm-common-s390x.h' and 'chacha20-s390x.S'.
+ * cipher/asm-common-s390x.h: New.
+ * cipher/chacha20-s390x.S: New.
+ * cipher/chacha20.c (USE_S390X_VX): New.
+ (CHACHA20_context_t): Change 'use_*' bit-field to unsigned type; Add
+ 'use_s390x'.
+ (_gcry_chacha20_s390x_vx_blocks8)
+ (_gcry_chacha20_s390x_vx_blocks4_2_1): New.
+ (chacha20_do_setkey): Add HW feature detect for s390x/VX.
+ (chacha20_blocks, do_chacha20_encrypt_stream_tail): Add s390x/VX
+ code-path.
+ * configure.ac: Add 'chacha20-s390x.lo'.
+
+ hwf-s390x: add VX vector instruction set detection.
+ + commit 1d13794780e3d052cd5ed6f900bf5900cf44b377
+ * configure.ac (gcry_cv_gcc_inline_asm_s390x_vx): New check.
+ * src/g10lib.h (HWF_S390X_VX): New.
+ * src/hwf-s390x.c (HWCAP_S390_VXRS): New.
+ (s390x_features) [HAVE_GCC_INLINE_ASM_S390X_VX]: Add VX feature check.
+ * src/hwfeatures.c (hwlist): Add "s390x-vx".
+
+ mpi/longlong: add s390x/zSeries macros.
+ + commit 0252cc9b62dfe20c77211f093b4fda54786177d3
+ * mpi/longlong.h [__s390x__] (add_ssaaaa, sub_ddmmss, UTItype)
+ (umul_ppmm, udiv_qrnnd): New.
+
+2020-12-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ hwf-arm: fix incorrect HWCAP2 for SHA1 and SHA2 on AArch32.
+ + commit 6b6bfd57d0a6b2b4577c084db35078cd9fadafa5
+ * src/hwf-arm.c (HWCAP2_SHA1, HWCAP2_SHA2): Change from bit indexes to
+ flags.
+
+ Add missing prototype for _gcry_mac_selftest.
+ + commit e47f04b4a28947c90db70ccaf93e149cfd5213c9
+ * src/cipher-proto.h (_gcry_hmac_selftest): Rename to...
+ (_gcry_mac_selftest): ... this.
+
+2020-12-21 NIIBE Yutaka <gniibe@fsij.org>
+
+ Merge hmac-tests.c into mac-hmac.c.
+ + commit 2ab14b23afc092fd25395954c2a94db932ca4d95
+ * cipher/Makefile.am (EXTRA_DIST): Remove hmac-tests.c.
+ * cipher/hmac-tests.c: Remove, merge into...
+ * cipher/mac-hmac.c: ... here.
+
+2020-12-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add s390x/zSeries acceleration for SHA3.
+ + commit 7532e27cacb74c92fd561524a0897163b0fcd7f4
+ * cipher/asm-inline-s390x.h (KLMD_PADDING_STATE): New.
+ (kimd_execute): Change 'reg0' from read-only to read/write.
+ (klmd_shake_execute): New.
+ * cipher/keccak.c (USE_S390X_CRYPTO): New.
+ (KECCAK_CONTEXT) [USE_S390X_CRYPTO]: New members.
+ [USE_S390X_CRYPTO] (keccak_bwrite_s390x, keccak_final_s390x)
+ (keccak_bextract_s390x, keccak_write_s390x, keccak_extract_s390x): New.
+ (keccak_write) [USE_S390X_CRYPTO]: Use accelerated function if enabled.
+ (keccak_final) [USE_S390X_CRYPTO]: Likewise.
+ (keccak_extract) [USE_S390X_CRYPTO]: Likewise.
+ (keccak_init) [USE_S390X_CRYPTO]: Detect and setup zSeries
+ acceleration.
+
+ Add s390x/zSeries acceleration for SHA512.
+ + commit 45f0ec0c4e3b08627cbf7e65f5f110c321710d01
+ * cipher/sha512.c (USE_S390X_CRYPTO): New.
+ (SHA512_CONTEXT) [USE_S390X_CRYPTO]: New members.
+ (do_sha512_transform_s390x, do_sha512_final_s390x): New.
+ (sha512_init_common) [USE_S390X_CRYPTO]: Detect and setup s390x/zSeries
+ acceleration.
+ (sha512_final) [USE_S390X_CRYPTO]: Use accelerated final function.
+
+ Add s390x/zSeries acceleration for SHA256.
+ + commit 0b555c3cc7c2b80ec2628685946a6139a1996911
+ * cipher/sha256.c (USE_S390X_CRYPTO): New.
+ (SHA256_CONTEXT) [USE_S390X_CRYPTO]: New members.
+ (do_sha256_transform_s390x, do_sha256_final_s390x): New.
+ (sha256_common_init) [USE_S390X_CRYPTO]: Detect and setup s390x/zSeries
+ acceleration.
+ (sha256_final) [USE_S390X_CRYPTO]: Use accelerated final function.
+
+ Add s390x/zSeries acceleration for SHA1.
+ + commit 88570515b4ca92a44c4e40c31f877c11cc00ab68
+ * cipher/asm-inline-s390x.h (ALWAYS_INLINE): New.
+ (klmd_query): New.
+ (km_function_to_mask, kimd_execute, klmd_execute): Mark as always
+ inline.
+ * cipher/rijndael-s390x.c (ALWAYS_INLINE): Remove.
+ * cipher/sha1.c (do_sha1_transform_s390x, do_sha1_final_s390x): New.
+ (sha1_init) [SHA1_USE_S390X_CRYPTO]: Detect and setup s390x/zSeries
+ acceleration.
+ (sha1_final) [SHA1_USE_S390X_CRYPTO]: Use accelerated final function.
+ * cipher/sha1.h (SHA1_USE_S390X_CRYPTO): New.
+ (SHA1_CONTEXT) [SHA1_USE_S390X_CRYPTO]: New.
+
+ Add bulk AES-GCM acceleration for s390x/zSeries.
+ + commit 5aeb091f911398217b2e9facb9bdeb05c63d7844
+ * cipher/Makefile.am: Add 'asm-inline-s390x.h'.
+ * cipher/asm-inline-s390x.h: New.
+ * cipher/cipher-gcm.c [GCM_USE_S390X_CRYPTO] (ghash_s390x_kimd): New.
+ (setupM) [GCM_USE_S390X_CRYPTO]: Add setup for s390x GHASH function.
+ * cipher/cipher-internal.h (GCM_USE_S390X_CRYPTO): New.
+ * cipher/rijndael-s390x.c (u128_t, km_functions_e): Move to
+ 'asm-inline-s390x.h'.
+ (aes_s390x_gcm_crypt): New.
+ (_gcry_aes_s390x_setup_acceleration): Use 'km_function_to_mask'; Add
+ setup for GCM bulk function.
+
+ Add bulk function interface for GCM mode.
+ + commit f4e63e92dc0b79633f48b11d292dd7bdf2752ede
+ * cipher/cipher-gcm.c (do_ghash_buf): Proper handling for the case
+ where 'unused' gets filled to full blocksize.
+ (gcm_crypt_inner): New.
+ (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt): Use
+ 'gcm_crypt_inner'.
+ * cipher/cipher-internal.h (cipher_bulk_ops_t): Add 'gcm_crypt'.
+
+ Add s390x/zSeries acceleration for AES.
+ + commit 9219d9d1b60c01a4c7dbde05ee6b5b52e0d7d072
+ * configure.ac: Add 'rijndael-s390x.lo'.
+ * cipher/Makefile.am: Add 'rijndael-s390x.c'.
+ * cipher/rijndael-internal.c (USE_S390X_CRYPTO): New.
+ (RIJNDAEL_context_s) [USE_S390X_CRYPTO]: New 'km*_func' members.
+ * cipher/rijndael-s390x.c: New.
+ * cipher/rijndael.c (_gcry_aes_s390x_setup_acceleration)
+ (_gcry_aes_s390x_setup_setkey)
+ (_gcry_aes_s390x_setup_prepare_decryption, _gcry_aes_s390x_encrypt)
+ (_gcry_aes_s390x_decrypt): New.
+ (do_setkey) [USE_S390X_CRYPTO]: Add s390x acceleration setup.
+
+ Add bulk function interface for OFB mode.
+ + commit f12b6788f2297391265af93a7794bfbc503de6d7
+ * cipher/cipher-internal.h (cipher_bulk_ops): Add 'ofb_enc'.
+ * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt): Use bulk encryption
+ function if defined.
+ * cipher/basic.c (check_bulk_cipher_modes): Add OFB-AES test vectors.
+
+ hwf: add detection of s390x/zSeries hardware features.
+ + commit 128054767d5f864798a39d432997f7d38c4bf729
+ * configure.ac (gcry_cv_gcc_inline_asm_s390x)
+ (HAVE_CPU_ARCH_S390X): Add s390x detection support.
+ * mpi/config.links: Add setup for s390x links.
+ * src/Makefile.am: Add 'hwf-s390x.c'.
+ * src/g10lib.h (HWF_S390X_MSA, HWF_S390X_MSA_4, HWF_S390X_8): New.
+ * src/hwf_common.h (_gcry_hwf_detect_s390x): New.
+ * src/hwf-s390x.c: New.
+ * src/hwfeatures.c: Add "s390x-msa", "s390x-msa-4" and "s390x-msa-8".
+
+ tests/bench-slope: use same benchmarking for XTS as for other modes.
+ + commit 0e37bb32e215feb4716341f7053c4f54806645cb
+ * tests/bench-slope.c (bench_xts_encrypt_init): Use same buffer
+ sizes as other tests.
+ (bench_xts_encrypt_do_bench, bench_xts_decrypt_do_bench): Remove.
+ (xts_encrypt_ops): Use 'bench_encrypt_do_bench'.
+ (xts_decrypt_ops): Use 'bench_decrypt_do_bench'.
+
+ aarch64: mpi/longlong.h: fix operand size mismatch.
+ + commit c59b5b03a063ebc73935dbb10bc4f568faddbedf
+ * mpi/longlong.h [__aarch64__] (count_leading_zeros): Use correctly
+ sized temporary variable for asm output.
+
+ aarch64: use configure check for assembly ELF directives support.
+ + commit 8352b0ece5237e3f86f1525b072e8f690ad0fa94
+ * configure.ac (gcry_cv_gcc_asm_elf_directives): New check.
+ (HAVE_GCC_ASM_ELF_DIRECTIVES): New 'config.h' macro.
+ * cipher/asm-common-aarch64.h (ELF): Change feature macro check from
+ __ELF__ to HAVE_GCC_ASM_ELF_DIRECTIVES.
+
+2020-12-18 NIIBE Yutaka <gniibe@fsij.org>
+
+ Reorganize self-tests for HMAC.
+ + commit c90fb0d8fb7a84bbcc8d6832de6a554405591850
+ * cipher/Makefile.am: Prepare merge of hmac-test.c into mac-hmac.c.
+ * cipher/hmac-tests.c: Ifdef-out run_selftests and _gcry_hmac_selftest.
+ * cipher/mac-internal.h: Include cipher-proto.h for selftest.
+ (gcry_mac_spec_ops): Add selftest field.
+ * cipher/mac-hmac.c: Include hmac-tests.c for migration.
+ (hmac_selftest) New.
+ (hmac_ops): Add hmac_selftest.
+ * cipher/gost28147.c, cipher/mac-cmac.c: Add new field for selftest.
+ * cipher/mac-gmac.c, cipher/mac-poly1305.c: Likewise..
+ * cipher/mac.c (_gcry_mac_selftest): New.
+ * src/fips.c (run_mac_selftests): Rename from run_hmac_selftests.
+ Use GCRY_MAC_HMAC_*, and call _gcry_mac_selftest.
+ (_gcry_fips_run_selftests): Use run_mac_selftests.
+
+2020-12-03 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Prevent link-time optimization from inlining __gcry_burn_stack.
+ + commit 1a83df98b198902ee6d71549231a3af37088d452
+ * src/g10lib.h (NOINLINE_FUNC): New attribute macro.
+ * src/misc.c (__gcry_burn_stack): Add NOINLINE_FUNC attribute.
+
+ tests/basic: check 32-bit and 64-bit overflow for CTR and ChaCha20.
+ + commit 2065720b5b0642cc1a0e08086a434244ebb1abf2
+ * tests/basic.c (check_one_cipher_ctr_reset)
+ (check_one_cipher_ctr_overflow): New.
+ (check_one_cipher): Add counter overflow tests for ChaCha20 and CTR
+ mode.
+
+ chacha20-ppc: fix 32-bit counter overflow handling.
+ + commit ed45eac3b721c1313902b977379fbd4886ccca7b
+ * cipher/chacha20-ppc.c (vec_add_ctr_u64, ADD_U64): New.
+ (_gcry_chacha20_ppc8_blocks1, _gcry_chacha20_ppc8_blocks4)
+ (_gcry_chacha20_poly1305_ppc8_blocks4): Use ADD_U64 when incrementing
+ counter.
+
+2020-12-03 NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: Put a work around to tests/random for macOS.
+ + commit 9769b40b54cf010a0c41c4ab05a7a88e17d70613
+ * configure.ac [*-apple-darwin*] (USE_POSIX_SPAWN_FOR_TESTS): New.
+ * tests/random.c [USE_POSIX_SPAWN_FOR_TESTS] (run_all_rng_tests): New.
+
+2020-11-18 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Update to newer autoconf constructs.
+ + commit 9485ca7b5bf11194cff59edbfa6a0fba3bf6162a
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Use AS_MESSAGE_LOG_FD
+ instead of AC_FD_CC.
+ (GNUPG_CHECK_MLOCK): Use AC_LINK_IFELSE instead of AC_TRY_LINK.
+ Use AC_RUN_IFELSE instead of AC_TRY_RUN.
+ * configure.ac (AC_ISC_POSIX): Replace by AC_SEARCH_LIBS.
+ Use AC_USE_SYSTEM_EXTENSIONS instead of AC_GNU_SOURCE.
+ Use AS_HELP_STRING instead of AC_HELP_STRING.
+ (AC_TYPE_SIGNAL): Remove.
+ (AC_DECL_SYS_SIGLIST): Remove.
+ * m4/Makefile.am (EXTRA_DIST): Update.
+ * m4/onceonly.m4: Remove.
+ * m4/socklen.m4: Update from gnulib.
+ * m4/libtool.m4: Update from libgpg-error.
+ * m4/gpg-error.m4: Update from libgpg-error.
+ * m4/noexecstack.m4: Use AS_HELP_STRING instead of AC_HELP_STRING.
+
+ build: Use modern Autoconf check for type.
+ + commit 425bf499185d78aa8fcad6a30b8771e7865d449d
+ * configure.ac (byte, ushort, us6, u32, u64): Use AC_CHECK_TYPES.
+ * cipher/poly1305.c: Use HAVE_TYPE_U64.
+ * src/hmac256.c: HAVE_TYPE_U32.
+ * src/types.h: Use HAVE_TYPE_BYTE, HAVE_TYPE_USHORT, HAVE_TYPE_U16,
+ HAVE_TYPE_U32, and HAVE_TYPE_U64.
+
+ m4: Update with newer autoconf constructs.
+ + commit 908e347fb68b28e180ac816b5050406358e81a0f
+ * src/libgcrypt.m4: Replace AC_HELP_STRING to AS_HELP_STRING.
+
+2020-10-30 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Handle removed zeros at the beginning for Ed25519.
+ + commit 361a0588489cf4a539da8debd1771024a1faa218
+ * cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Accept private
+ key with removed zeros.
+
+2020-10-23 Werner Koch <wk@gnupg.org>
+
+ random: Allow for a Unicode random seed file on Windows.
+ + commit 24341f58f0d38bd62c45d285bcf8472f82b56135
+ * random/random-csprng.c (utf8_to_wchar) [W32]: New.
+ (any8bitchar) [W32]: New.
+ (my_open): New. Replace all calls to open with this.
+
+2020-10-01 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+
+ tests: Fix typo in comment.
+ + commit 4a50c6b88d6d8d843e50add851a8a5e691349097
+ * tests/basic.c: Fix typo in comment.
+
+2020-09-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: clean-up prepare_decryption function.
+ + commit 2051d5bd6f732a36e5a536cba734531a9e2e915f
+ * cipher/rijndael-internal.h (rijndael_prepare_decfn_t): New.
+ (RIJNDAEL_context_s): New member 'prepare_decryption'.
+ * cipher/rijndael-padlock.c (_gcry_aes_padlock_prepare_decryption): New.
+ * cipher/rijndael.c (_gcry_aes_padlock_prepare_decryption): New.
+ (do_setkey): Setup 'ctx->prepare_decryption' for each acceleration type.
+ (prepare_decryption): Remove calls to other prepare decryption functions.
+ (check_decryption_preparation): Call 'ctx->prepare_decryption' instead
+ of 'prepare_decryption'.
+
+ rijndael: clean-up generic bulk functions.
+ + commit 7679c918ade9d334bc80cb8c10916bbc847ff382
+ * cipher/rijndael.c (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec)
+ (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth, _gcry_aes_xts_crypt): Remove
+ calls to hardware accelerated AES bulk functions.
+
+ cipher: setup bulk functions at each algorithms key setup.
+ + commit 51271eb86bcb0eb89e55a2add9607c503f182c89
+ * cipher/cipher-internal.h (cipher_mode_ops_t, cipher_bulk_ops_t): New.
+ (gcry_cipher_handle): Define members 'mode_ops' and 'bulk' using new
+ types.
+ * cipher/cipher.c (_gcry_cipher_open_internal): Remove bulk function
+ setup.
+ (cipher_setkey): Pass context bulk function pointer to algorithm setkey
+ function.
+ * cipher/cipher-selftest.c (_gcry_selftest_helper_cbc)
+ (_gcry_selftest_helper_cfb, _gcry_selftest_helper_ctr): Remove bulk
+ function parameter; Use bulk function returned by setkey function.
+ * cipher/cipher-selftest.h (_gcry_selftest_helper_cbc)
+ (_gcry_selftest_helper_cfb, _gcry_selftest_helper_ctr): Remove bulk
+ function parameter.
+ * cipher/arcfour.c (arcfour_setkey): Change 'hd' parameter to
+ 'bulk_ops'.
+ * cipher/blowfish.c (bf_setkey): Change 'hd' parameter to
+ 'bulk_ops'; Setup 'bulk_ops' with bulk acceleration functions.
+ (_gcry_blowfish_ctr_enc, _gcry_blowfish_cbc_dec)
+ (_gcry_blowfish_cfb_dec): Make static.
+ (selftest_ctr, selftest_cbc, selftest_cfb): Do not pass bulk function
+ to selftest helper.
+ (selftest): Pass 'bulk_ops' to setkey function.
+ * cipher/camellia.c (camellia_setkey): Change 'hd' parameter to
+ 'bulk_ops'; Setup 'bulk_ops' with bulk acceleration functions.
+ (_gcry_camellia_ctr_enc, _gcry_camellia_cbc_dec)
+ (_gcry_camellia_cfb_dec, _gcry_camellia_ocb_crypt)
+ (_gcry_camellia_ocb_auth): Make static.
+ (selftest_ctr, selftest_cbc, selftest_cfb): Do not pass bulk function
+ to selftest helper.
+ (selftest): Pass 'bulk_ops' to setkey function.
+ * cipher/cast5.c (cast_setkey): Change 'hd' parameter to
+ 'bulk_ops'; Setup 'bulk_ops' with bulk acceleration functions.
+ (_gcry_cast5_ctr_enc, _gcry_cast5_cbc_dec, _gcry_cast5_cfb_dec): Make
+ static.
+ (selftest_ctr, selftest_cbc, selftest_cfb): Do not pass bulk function
+ to selftest helper.
+ (selftest): Pass 'bulk_ops' to setkey function.
+ * cipher/chacha20.c (chacha20_setkey): Change 'hd' parameter to
+ 'bulk_ops'.
+ * cipher/cast5.c (do_tripledes_setkey): Change 'hd' parameter to
+ 'bulk_ops'; Setup 'bulk_ops' with bulk acceleration functions.
+ (_gcry_3des_ctr_enc, _gcry_3des_cbc_dec, _gcry_3des_cfb_dec): Make
+ static.
+ (bulk_selftest_setkey): Change 'hd' parameter to 'bulk_ops'.
+ (selftest_ctr, selftest_cbc, selftest_cfb): Do not pass bulk function
+ to selftest helper.
+ (do_des_setkey): Change 'hd' parameter to 'bulk_ops'.
+ * cipher/gost28147.c (gost_setkey): Change 'hd' parameter to
+ 'bulk_ops'.
+ * cipher/idea.c (idea_setkey): Change 'hd' parameter to 'bulk_ops'.
+ * cipher/rfc2268.c (do_setkey): Change 'hd' parameter to 'bulk_ops'.
+ * cipher/rijndael.c (do_setkey): Change 'hd' parameter to
+ 'bulk_ops'; Setup 'bulk_ops' with bulk acceleration functions.
+ (rijndael_setkey): Change 'hd' parameter to 'bulk_ops'.
+ (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_enc)
+ (_gcry_aes_cbc_dec, _gcry_aes_ctr_enc, _gcry_aes_ocb_crypt)
+ (_gcry_aes_ocb_auth, _gcry_aes_xts_crypt): Make static.
+ (selftest_basic_128, selftest_basic_192, selftest_basic_256): Pass
+ 'bulk_ops' to setkey function.
+ (selftest_ctr, selftest_cbc, selftest_cfb): Do not pass bulk function
+ to selftest helper.
+ * cipher/salsa20.c (salsa20_setkey): Change 'hd' parameter to
+ 'bulk_ops'.
+ * cipher/seed.c (seed_setkey): Change 'hd' parameter to 'bulk_ops'.
+ * cipher/serpent.c (serpent_setkey): Change 'hd' parameter to
+ 'bulk_ops'; Setup 'bulk_ops' with bulk acceleration functions.
+ (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec, _gcry_serpent_cfb_dec)
+ (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): Make static.
+ (selftest_ctr_128, selftest_cbc_128, selftest_cfb_128): Do not pass
+ bulk function to selftest helper.
+ * cipher/sm4.c (sm4_setkey): Change 'hd' parameter to 'bulk_ops'; Setup
+ 'bulk_ops' with bulk acceleration functions.
+ (_gcry_sm4_ctr_enc, _gcry_sm4_cbc_dec, _gcry_sm4_cfb_dec)
+ (_gcry_sm4_ocb_crypt, _gcry_sm4_ocb_auth): Make static.
+ (selftest_ctr_128, selftest_cbc_128, selftest_cfb_128): Do not pass
+ bulk function to selftest helper.
+ * cipher/twofish.c (twofish_setkey): Change 'hd' parameter to
+ 'bulk_ops'; Setup 'bulk_ops' with bulk acceleration functions.
+ (_gcry_twofish_ctr_enc, _gcry_twofish_cbc_dec)
+ (_gcry_twofish_cfb_dec, _gcry_twofish_ocb_crypt)
+ (_gcry_twofish_ocb_auth): Make static.
+ (selftest_ctr, selftest_cbc, selftest_cfb): Do not pass bulk function
+ to selftest helper.
+ (selftest, main): Pass 'bulk_ops' to setkey function.
+ * src/cipher-proto.h: Forward declare 'cipher_bulk_ops_t'.
+ (gcry_cipher_setkey_t): Replace 'hd' with 'bulk_ops'.
+ * src/cipher.h: Remove bulk acceleration function prototypes for
+ 'aes', 'blowfish', 'cast5', 'camellia', '3des', 'serpent', 'sm4' and
+ 'twofish'.
+
+2020-09-21 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: tidy do_setkey little bit.
+ + commit e0829ae648d9d9da67cd8a8fae7aa05774a0d0f7
+ * cipher/rijndael.c (do_setkey): Reduce number of ifdefs by using
+ function pointer for accelerated key-setup.
+
+2020-09-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael-aesni: tweak x86_64 AES-NI for better performance on AMD Zen2.
+ + commit f96989f0e9085fa58b475131d29b37f68ba564ec
+ * cipher/rijndael-aesni.c (do_aesni_enc_vec8, do_aesni_dec_vec8): Move
+ first round key xoring and last round out to caller.
+ (do_aesni_ctr_4): Change low 8-bit counter overflow check to 8-bit
+ addition to low-bits and detect overflow from carry flag; Adjust
+ slow path to restore counter.
+ (do_aesni_ctr_8): Same as above; Interleave first round key xoring and
+ first round with CTR generation on fast path; Interleave last round
+ with output xoring.
+ (_gcry_aes_aesni_cfb_dec, _gcry_aes_aesni_cbc_dec): Add first round
+ key xoring; Change order of last round xoring and output xoring
+ (shorten the dependency path).
+ (_gcry_aes_aesni_ocb_auth): Add first round key xoring and last round
+ handling.
+
+2020-08-26 Werner Koch <wk@gnupg.org>
+
+ build: Allow customization of the signing key.
+ + commit 9cd92ebae21900e54cc3d8b607c8ed1afbf2eb9b
+ * Makefile.am (sign-release): Read variabales from user configuration.
+
+2020-08-21 NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: Fix basic.c.
+ + commit fd51bc523d095168ee9367fe3f18d18f7a88ad90
+ * tests/basic.c (check_one_hmac): Fix error paths.
+ (check_pubkey_crypt): Fix wrong call of gcry_sexp_new.
+
+ ecc: Fix an error path.
+ + commit 65a2cd139e21250e6581a4f610015937e7b91451
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Avoid null dereference on
+ error.
+
+2020-07-23 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ chacha20-aarch64: improve performance through higher SIMD interleaving.
+ + commit 8d7b1d0a52bde173646e5b42b31d23593eabecf2
+ * cipher/chacha20-aarch64.S (ROTATE2, ROTATE2_8, ROTATE2_16)
+ (QUARTERROUND2): Replace with...
+ (ROTATE4, ROTATE4_8, ROTATE4_16, QUARTERROUND4): ...these.
+ (_gcry_chacha20_aarch64_blocks4)
+ (_gcry_chacha20_poly1305_aarch64_blocks4): Adjust to use QUARTERROUND4.
+
+ tests/bench-slope: improve CPU frequency auto-detection.
+ + commit f1c3db3bf40e07cfd1a6a92209865ee7a98129ca
+ * configure.ac (gcry_cv_have_asm_volatile_memory): Check also if
+ assembly memory barrier with input/output register is supported.
+ * tests/bench-slope.c (auto_ghz_bench): Change to use base operation
+ that takes two CPU cycles and unroll loop by 1024 operations.
+
+ Enable jitter entropy also on non-x86 architectures.
+ + commit 886120f33bd3f10e6e6a09920eca1f9ed81044e7
+ * configure.ac: Do not force jentsupport to "n/a" on non-x86
+ architectures.
+
+ random/jitterentropy: fix USE_JENT == JENT_USES_GETTIME code path.
+ + commit 4ed9b949485448816a70d86260d572f08ae34621
+ * random/jitterentropy-base-user.h (jent_get_nstime): Use 'tv' variable
+ instead of non-existing 'time'.
+
+ Camellia AES-NI/AVX/AVX2 size optimization.
+ + commit 4c0e244fc53e0f7b927bfe4cf54695b5d282fd27
+ * cipher/camellia-aesni-avx-amd64.S: Use loop for handling repeating
+ '(enc|dec)_rounds16/fls16' portions of encryption/decryption.
+ * cipher/camellia-aesni-avx2-amd64.S: Use loop for handling repeating
+ '(enc|dec)_rounds32/fls32' portions of encryption/decryption.
+
+2020-07-14 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Support reading EC point in compressed format for good curves.
+ + commit e0dabf74bf276500257f15b85ded9cf24ccc8334
+ * cipher/ecc-curves.c (gcry_ecc_get_curve): Handle G, differently.
+ * cipher/ecc-misc.c (_gcry_ecc_sec_decodepoint): Support compressed
+ representation of EC point. Rename from _gcry_ecc_os2ec.
+ * cipher/ecc-sm2.c (_gcry_ecc_sm2_decrypt) Follow the change.
+ * cipher/ecc.c (ecc_decrypt_raw): Likewise.
+ * mpi/ec.c (_gcry_mpi_ec_set_point): Likewise.
+ * src/ec-context.h: API change _gcry_ecc_sec_decodepoint from
+ _gcry_ecc_os2ec.
+ * tests/basic.c (check_pubkey): Use compressed representation
+ for two public keys of NIST P192 and NIST P256.
+
+2020-07-06 Werner Koch <wk@gnupg.org>
+
+ mpi: Consider +0 and -0 the same in mpi_cmp.
+ + commit 1f3a92e103d4a8e019d8d022647a2b9fb2681327
+ * mpi/mpi-cmp.c (do_mpi_cmp): Check size of U an V.
+
+2020-06-23 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix length computation.
+ + commit 1db1dc7945b111b6e20a8420ad38a358316681ab
+ * cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Add one only for
+ Edwards case.
+
+2020-06-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add SM4 x86-64/AES-NI/AVX2 implementation.
+ + commit 35a78eb248d6bacd2a58477a122a0020d796ce63
+ * cipher/Makefile.am: Add 'sm4-aesni-avx2-amd64.S'.
+ * cipher/sm4-aesni-avx2-amd64.S: New.
+ * cipher/sm4.c (USE_AESNI_AVX2): New.
+ (SM4_context) [USE_AESNI_AVX2]: Add 'use_aesni_avx2'.
+ [USE_AESNI_AVX2] (_gcry_sm4_aesni_avx2_ctr_enc)
+ (_gcry_sm4_aesni_avx2_cbc_dec, _gcry_sm4_aesni_avx2_cfb_dec)
+ (_gcry_sm4_aesni_avx2_ocb_enc, _gcry_sm4_aesni_avx2_ocb_dec)
+ (_gcry_sm4_aesni_avx_ocb_auth): New.
+ (sm4_setkey): Enable AES-NI/AVX2 if supported by HW.
+ (_gcry_sm4_ctr_enc, _gcry_sm4_cbc_dec, _gcry_sm4_cfb_dec)
+ (_gcry_sm4_ocb_crypt, _gcry_sm4_ocb_auth) [USE_AESNI_AVX2]: Add
+ AES-NI/AVX2 bulk functions.
+ * configure.ac: Add ''sm4-aesni-avx2-amd64.lo'.
+
+ Add SM4 x86-64/AES-NI/AVX implementation.
+ + commit c9a3f1bb91e63033e3bf3e06bdd6075622626d0d
+ * cipher/Makefile.am: Add 'sm4-aesni-avx-amd64.S'.
+ * cipher/sm4-aesni-avx-amd64.S: New.
+ * cipher/sm4.c (USE_AESNI_AVX, ASM_FUNC_ABI): New.
+ (SM4_context) [USE_AESNI_AVX]: Add 'use_aesni_avx'.
+ [USE_AESNI_AVX] (_gcry_sm4_aesni_avx_expand_key)
+ (_gcry_sm4_aesni_avx_crypt_blk1_8, _gcry_sm4_aesni_avx_ctr_enc)
+ (_gcry_sm4_aesni_avx_cbc_dec, _gcry_sm4_aesni_avx_cfb_dec)
+ (_gcry_sm4_aesni_avx_ocb_enc, _gcry_sm4_aesni_avx_ocb_dec)
+ (_gcry_sm4_aesni_avx_ocb_auth, sm4_aesni_avx_crypt_blk1_8): New.
+ (sm4_expand_key) [USE_AESNI_AVX]: Use AES-NI/AVX key setup.
+ (sm4_setkey): Enable AES-NI/AVX if supported by HW.
+ (_gcry_sm4_ctr_enc, _gcry_sm4_cbc_dec, _gcry_sm4_cfb_dec)
+ (_gcry_sm4_ocb_crypt, _gcry_sm4_ocb_auth) [USE_AESNI_AVX]: Add
+ AES-NI/AVX bulk functions.
+ * configure.ac: Add ''sm4-aesni-avx-amd64.lo'.
+
+ Optimizations for SM4 cipher.
+ + commit 81fee26bbbae820a311a3ce3ac55e304655c2acd
+ * cipher/cipher.c (_gcry_cipher_open_internal): Add SM4 bulk
+ functions.
+ * cipher/sm4.c (ATTR_ALIGNED_64): New.
+ (sbox): Convert to ...
+ (sbox_table): ... this structure for sbox hardening as is done
+ for AES and GCM.
+ (prefetch_sbox_table): New.
+ (sm4_t_non_lin_sub): Make inline; Optimize sbox access pattern.
+ (sm4_key_lin_sub): Make inline; Tune slightly.
+ (sm4_key_sub, sm4_enc_sub): Make inline.
+ (sm4_round): Make inline; Take 'x' as separate parameters instead
+ of array.
+ (sm4_expand_key): Return void; Drop keylen; Unroll loops by 4;
+ Wipe sensitive variables at end; Move key-length check to
+ 'sm4_setkey'.
+ (sm4_setkey): Add initial self-test step; Add key-length check;
+ Remove burn stack (as variables wiped in 'sm4_expand_key').
+ (sm4_do_crypt): Return burn stack depth; Unroll loops by 4.
+ (sm4_encrypt, sm4_decrypt): Prefetch sbox table; Return burn
+ stack from 'sm4_do_crypt', as allows tail-call optimization
+ by compiler.
+ (sm4_do_crypt_blks2): New two parallel block function for greater
+ instruction level parallelism.
+ (sm4_crypt_blocks, _gcry_sm4_ctr_enc, _gcry_sm4_cbc_dec)
+ (_gcry_sm4_cfb_dec, _gcry_sm4_ocb_crypt, _gcry_sm4_ocb_auth): New
+ bulk processing functions.
+ (selftest_ctr_128, selftest_cbc_128, selftest_cfb_128): New
+ bulk processing self-tests.
+ (sm4_selftest): Clear SM4 context before use; Use 'sm4_expand_key'
+ instead of 'sm4_setkey'; Call bulk processing self-tests.
+ * src/cipher.h (_gcry_sm4_ctr_enc, _gcry_sm4_ctr_dec)
+ (_gcry_sm4_cfb_dec, _gcry_sm4_ocb_crypt, _gcry_sm4_ocb_auth): New.
+ * tests/basic.c (check_ocb_cipher): Add SM4-OCB test vector.
+
+2020-06-18 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: For Ed448, it's only for EdDSA.
+ + commit a6177e1bc948a7af052d62bcd62aa6b5825bfaff
+ * cipher/ecc.c (ecc_sign): Ed448 is only for EdDSA.
+ Hash algo is determined by the curve.
+ (ecc_verify): Likewise.
+ * tests/t-ed448.c (one_test): Don't specify (flags eddsa).
+ Don't specify hash-algo.
+
+ ecc: Fix the condition for EdDSA data handling.
+ + commit f2847d56cce2afdd993f797812a673495a41c234
+ * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): It may be
+ the encoding context which determines EdDSA. Hash-algo can be
+ omitted. Flags are OR-ed.
+
+ ecc: Support EdDSA with context and enabling PH(M).
+ + commit ba78ad8f19674b94edfdf4998f40feee081481bc
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_compute_h_d): Simplify.
+ (DOM4_0_NONE, DOM4_0_NONE_LEN): Remove.
+ (DOM25519, DOM25519_LEN): New.
+ (DOM448, DOM448_LEN): New.
+ (_gcry_ecc_eddsa_sign): Support EdDSA with context and PH.
+ (_gcry_ecc_eddsa_verify): Likewise.
+ * tests/t-ed448.c: Add tests with context and PH=1.
+ * tests/t-ed448.inp: Add test data.
+
+ ecc: Change EdDSA internal API.
+ + commit 2856ac14ae3e4c9e6288e1f0d8bc1945bb874081
+ * cipher/ecc-common.h (_gcry_ecc_eddsa_sign): Last arg is CTX.
+ (_gcry_ecc_eddsa_verify): Ditto.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_sign): Get hash algo from CTX.
+ (_gcry_ecc_eddsa_verify): Ditto.
+ * cipher/ecc.c (ecc_sign, ecc_verify): Follow the change.
+
+2020-06-17 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Support "label" for EdDSA context in data.
+ + commit 1cf49754694611620fd383327cf127e91f6883df
+ * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Handle ctx->label.
+
+ ecc: Initialize key before handling data.
+ + commit d51a9c259d49c63121fab48bce48d826e9b57733
+ * cipher/ecc.c (ecc_sign): Initialize key at first.
+ (ecc_verify): Likewise.
+
+ ecc: Add new flag "prehash".
+ + commit 9a640eba6dd7504c90a65151cdaf1e4093a8b475
+ * src/cipher.h (PUBKEY_FLAG_PREHASH): New.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Parse it.
+
+ ecc: No (flags eddsa) required for Ed448.
+ + commit b1721f9b291a4c226caa2bfbe4fefe8fde5216e0
+ * cipher/ecc.c (check_secret_key): Ed448 means EdDSA.
+ (ecc_generate): Likewise.
+ * tests/t-ed448.c (one_test): Remove the flag in key.
+
+ ecc: Support Ed448 by _gcry_ecc_compute_public.
+ + commit 5585ee4947082f932ee01d93dfe295c769e96671
+ * cipher/ecc-misc.c (_gcry_ecc_compute_public): Handle Ed448.
+
+2020-06-16 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+
+ tests: Add basic test-vectors for SM4.
+ + commit c1535d0b8797e9b3bbfb5193b6ab23bf788ffd36
+ * tests/basic.c (check_ciphers): Add SM4 check and test-vectors.
+
+ Add SM4 symmetric cipher algorithm.
+ + commit ddcce166ab8bc6f51f5b509bcbea13a8746384ec
+ * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add sm4.c.
+ * cipher/cipher.c (cipher_list, cipher_list_algo301): Add
+ _gcry_cipher_spec_sm4.
+ * cipher/mac-cmac.c (map_mac_algo_to_cipher): Add cmac SM4.
+ (_gcry_mac_type_spec_cmac_sm4): Add cmac SM4.
+ * cipher/mac-internal.h: Declare spec_cmac_sm4.
+ * cipher/mac.c (mac_list, mac_list_algo201): Add cmac SM4.
+ * cipher/sm4.c: New.
+ * configure.ac (available_ciphers): Add sm4.
+ * doc/gcrypt.texi: Add SM4 document.
+ * src/cipher.h: Add declarations for SM4 and cmac SM4.
+ * src/gcrypt.h.in (gcry_cipher_algos): Add algorithm ID for SM4.
+
+2020-06-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ doc: add GCRY_MD_SM3, GCRY_MAC_HMAC_SM3 and GCRY_MAC_GOST28147_IMIT.
+ + commit 6c571bfda6409d7d668f5d44cea0c6c31e2688be
+ * doc/gcrypt.texi: add GCRY_MD_SM3, GCRY_MAC_HMAC_SM3 and
+ GCRY_MAC_GOST28147_IMIT.
+
+2020-06-16 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix Ed448 key generation.
+ + commit c15cc1a38199cf0d758579eb01d0e88c99cd4b80
+ * cipher/ecc.c (ecc_generate): Fix point representation for Ed448.
+
+ ecc,test: Add testing Ed448.
+ + commit c7779e499e9051ee79ed720f576dbf40d90cdfb1
+
+
+ ecc: Support Ed448 for verify.
+ + commit d1baad35c65030e41fcba69854c57032eee0d111
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_verify): Support Ed448.
+
+ ecc: Support Ed448 signing.
+ + commit 951b37c5038667b461692454397bb058b5e1e184
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_sign): Support Ed448.
+
+ ecc: Use SHAKE256 in EdDSA with Ed448.
+ + commit 32d6d73d44d372dd1ec0b08ba03f1b7b085c09d9
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_compute_h_d): Fix for SHAKE256.
+
+ ecc: Support shake128 and shake256 for message digest.
+ + commit f6815a96e51be44a361ddcd3a20a5b969b1dab1b
+ * cipher/pubkey-util.c (get_hash_algo): Add shake128 and shake256.
+
+ ecc: Support Ed448 for key generation.
+ + commit e25446ecc04442b399302ce72db6d5ea2e9e85e8
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_compute_h_d): Support Ed448.
+ (_gcry_ecc_eddsa_genkey): Support Ed448, using
+ _gcry_ecc_eddsa_compute_h_d.
+
+ ecc: Support Ed448 in decoding point.
+ + commit bd22b029bbf50737f90535c506fba4f812bcf040
+ * cipher/ecc-eddsa.c (ecc_ed448_recover_x): New.
+ (_gcry_ecc_eddsa_recover_x): Support Ed448.
+ (_gcry_ecc_eddsa_decodepoint): Support Ed448.
+ * mpi/ec.c (_gcry_mpi_ec_decode_point): For Ed448, use
+ _gcry_ecc_eddsa_decodepoint.
+
+ ecc: Add new curve: Ed448.
+ + commit 339b03acf0971a31997901dd674fb75c4dde31d0
+ * cipher/ecc-curves.c (curve_aliases): Add Ed448.
+ (domain_parms): Add domain parameters for Ed448.
+ * tests/curves.c (N_CURVES): Increment.
+
+ ecc: Fix EdDSA encoding for Ed448.
+ + commit 3386aaf84d4d89b6ff931533df2ff82ed3f7c7f9
+ * cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Fix point/scalar
+ length condition.
+ * cipher/ecc-eddsa.c (eddsa_encodempi): The second argument is NBITS.
+ (eddsa_encode_x_y): Likewise.
+ (_gcry_ecc_eddsa_encodepoint): Follow the change.
+ (_gcry_ecc_eddsa_ensure_compact): Likewise.
+ (_gcry_ecc_eddsa_decodepoint): Likewise.
+ (_gcry_ecc_eddsa_sign): Likewise. Remove restriction of 256 bits.
+
+2020-06-12 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix NBITS in domain_parms.
+ + commit db7b2c591004868abedbc2c19d3bb2efebf8529d
+ * cipher/ecc-curves.c (cipher/ecc-curves.c): It's NBITS of 'p'.
+
+2020-06-08 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: fix UBSAN warning on left shift by 24 places with type 'int'
+ + commit 6cdd7268fe19b066ddb373e2f3c0b7ebf9b938dd
+ * cipher/rijndael.c (do_encrypt_fn, do_decrypt_fn): Cast final
+ sbox/inv_sbox look-ups to 'u32' type.
+
+ Disable all assembly modules with --disable-asm.
+ + commit 3060aadec396802af13f08c4b2dd1b28f2a68c5d
+ * configure.ac (try_asm_modules): Update description,
+ "MPI" => "MPI and cipher".
+ (gcry_cv_gcc_arm_platform_as_ok, gcry_cv_gcc_aarch64_platform_as_ok)
+ (gcry_cv_gcc_inline_asm_ssse3, gcry_cv_gcc_inline_asm_pclmul)
+ (gcry_cv_gcc_inline_asm_shaext, gcry_cv_gcc_inline_asm_sse41)
+ (gcry_cv_gcc_inline_asm_avx, gcry_cv_gcc_inline_asm_avx2)
+ (gcry_cv_gcc_inline_asm_bmi2, gcry_cv_gcc_amd64_platform_as_ok)
+ (gcry_cv_gcc_platform_as_ok_for_intel_syntax)
+ (gcry_cv_cc_arm_arch_is_v6, gcry_cv_gcc_inline_asm_neon)
+ (gcry_cv_gcc_inline_asm_aarch32_crypto)
+ (gcry_cv_gcc_inline_asm_aarch64_neon)
+ (gcry_cv_gcc_inline_asm_aarch64_crypto)
+ (gcry_cv_cc_ppc_altivec, gcry_cv_gcc_inline_asm_ppc_altivec)
+ (gcry_cv_gcc_inline_asm_ppc_arch_3_00): Check for "try_asm_modules".
+ * mpi/config.links: Set "mpi_cpu_arch" to "disabled"
+ with --disable-asm.
+
+2020-06-05 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ mpicalc: fix typo.
+ + commit 2dd3e27fc53cf408f799d2e7b379c1441e0d62c8
+ * src/mpicalc.c (print_help): fix typo in commands description.
+
+2020-06-04 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Fix flags in mpi_copy for opaque MPI.
+ + commit 78a5a1aa7627afaa24e2ea1eb9b08f1cfdd71561
+ * mpi/mpiutil.c (_gcry_mpi_copy): Copy flags.
+
+2020-06-03 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Use opaque MPI for 'd' of Ed25519/EdDSA.
+ + commit 0d8346f84a1f5865da3375ce92420d92fb5ae652
+ * cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Add FLAGS.
+ Use opaque MPI for Ed25519/EdDSA, too.
+ (_gcry_mpi_ec_internal_new): Follow the change.
+ (_gcry_mpi_ec_new): Likewise.
+
+2020-06-01 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ cipher-ocb: fix out-of-array stack memory access.
+ + commit 8cfaeae42522778052c36fceccab504826a30cbf
+ * cipher/cipher-ocb.c (bit_copy): Do not access memory beyond
+ 's' array when bitoff > 8.
+
+2020-06-01 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: More fix of off-by-one mistake mpi_invm_pow2.
+ + commit 6a2cd0fe78a9cdc78911694a84b08762dd8658b4
+ * mpi/mpi-inv.c (mpi_invm_pow2): Avoid out-of-band read/write.
+
+ ecc: Consistently handle parameters as unsigned value.
+ + commit 6f8b1d4cb798375e6d830fd6b73c71da93ee5f3f
+ * cipher/ecc-curves.c (_gcry_ecc_get_curve): Parse as unsigned value.
+
+2020-05-27 NIIBE Yutaka <gniibe@fsij.org>
+
+ sexp: Fix coding of line break.
+ + commit 33c972b6a6fe79aacb0a732d1df9a9deacafca29
+ * src/sexp.c (_gcry_sexp_vextract_param): Add missing newline.
+
+2020-05-14 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Make sure it's the fixed size bytes.
+ + commit eb2288f3b1f338a9aec11d559ec84bdb201960e1
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_decodepoint): Checking the size
+ of EC point representation, return GPG_ERR_INV_OBJ if not valid.
+
+2020-05-13 Werner Koch <wk@gnupg.org>
+
+ ecc: Detect the use of a Montgomery curve earlier in ecc_verify.
+ + commit d0f995afe2e0228d3b9e30b0fc7091631d7d0090
+ * cipher/ecc.c (ecc_verify): Do not allow a Montgomery curve.
+
+2020-05-13 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Fix off-by-one mistake mpi_invm_pow2.
+ + commit 69b55f87053ce2494cd4b38dc600f867bc4355be
+ * mpi/mpi-inv.c (mpi_invm_pow2): Avoid out-of-band read/write.
+
+2020-05-12 Werner Koch <wk@gnupg.org>
+
+ ecc: Initialize a dummy parameter.
+ + commit 75a7b17878e02c3882070d6c86e0d2efbc3d680a
+ * cipher/ecc.c (ecc_verify): Rename flags to dummy_flags and
+ initialize.
+
+2020-05-06 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ tests/benchmark.c: fix error message for invalid MAC algo.
+ + commit 79e196a610b1b734a1f573288b148d62787f5281
+
+
+2020-04-27 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+
+ ecc: Fix typo error in ecc-gost.
+ + commit fe688ce7e14f14d7d3a7e16aa0304d24b5b1a179
+ * cipher/ecc-gost.c (_gcry_ecc_gost_verify): Fix typo in comment.
+
+2020-04-27 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Fix the return value of mpi_invm_generic.
+ + commit f10eb240a30ac115cfeb63848c67a936e1059ab9
+ * mpi/mpi-inv.c (mpi_invm_generic): Return correct value.
+
+2020-04-24 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Fix return value of mpi_invm_generic.
+ + commit bc3b6a6a45cf9fa6cc0556da870628c53570f52f
+ * mpi/mpi-inv.c (mpi_invm_generic): Return 0 if inverse does not exist.
+
+ mpi: More use of mpih API for _gcry_mpi_invm.
+ + commit 559ba9b36c9cdf4762d28beb3b4c59665c671818
+ * mpi/mpi-inv.c (mpi_invm_pow2): Remove.
+ (_gcry_mpi_invm): Use mpih_invm_pow2 instead.
+
+ mpi: Use mpih interface internally for mpi-inv.
+ + commit beefbb90d71d7fbd0b4429472b7d4b39670ff64b
+ * mpi/mpi-inv.c (mpih_invm_pow2): Converted from mpi_invm_pow2.
+ (mpi_invm_pow2): Use mpih_invm_pow2.
+
+ mpi: Fix size of A in mpi_invm_pow2.
+ + commit efa5151ea1c2a2c049b2651581e71b6becba4e16
+ * mpi/mpi-inv.c (mpi_invm_pow2): Fix size of A.
+
+2020-04-23 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: More fix for _gcry_mpi_invm.
+ + commit f81a1dd7317513000e5bc4d1bfffd6d2bfb8c2a2
+ * mpi/mpi-inv.c (_gcry_mpi_invm): Fix comments and use of CRT path.
+
+2020-04-22 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Fix off-by-one mistake mpi_invm_pow2.
+ + commit 3bb9f74764b3626ed1116fc7e517921232d6be54
+ * mpi/mpi-inv.c (mpi_invm_pow2): Fix computation of iterations.
+
+2020-04-21 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Use mpi_invm_pow2 for mpi_invm.
+ + commit bac01a6cfb3d645ff8439cbd3b310d255735d792
+ * mpi/mpi-inv.c (_gcry_mpi_invm): Use mpi_invm_pow2.
+
+ mpi: Fix mpi_invm_pow2.
+ + commit 2a3c58a0b4db01c17da0bf8c035fb1def2af114c
+ * mpi/mpi-inv.c (mpi_invm_pow2): Fix the algo implementation.
+
+2020-04-19 Dmitry Baryshkov <dbaryshkov@gmail.com>
+
+ gost28147: implement special MAC mode called imitovstavka (IMIT)
+ + commit 45f21f871982753716d4a7676d948e8c7d644db5
+ * src/gcrypt.h.in (GCRY_MAC_GOST28147_IMIT): New.
+ * cipher/gost28147.c (gost_imit_open, gost_imit_close)
+ (gost_imit_setkey, gost_imit_setiv, gost_imit_reset, _gost_imit_block)
+ (gost_imit_block, gost_imit_write, gost_imit_finish, gost_imit_read)
+ (gost_imit_verify, gost_imit_get_maclen, gost_imit_get_keylen)
+ (gost_imit_set_extra_info): New functions implementing GOST 28147-89
+ MAC (imitovstavka, IMIT) mode.
+ * cipher/gost28147.c (gost_imit_ops)
+ (_gcry_mac_type_spec_gost28147_imit): declare GOST 28147-89 IMIT
+ handler.
+ * cipher/mac-internal.h (gcry_mac_handle): add fields to support GOST
+ 28147-89 IMIT mode.
+ * cipher/mac.c (mac_list): add _gcry_mac_type_spec_gost28147_imit.
+ (spec_from_algo): handle GCRY_MAC_GOST28147_IMIT.
+ * tests/basic.c (check_mac): add GOST28147-89 IMIT test vector.
+
+ mac: add support for gcry_mac_ctl(GCRYCTL_SET_SBOX)
+ + commit d7fa70ed9ddc6e0189a8b59016b1f17717a26865
+ * cipher/mac-internal.h (gcry_mac_spec_ops_t): add set_extra_info field
+ for providing additional settings.
+ * cipher/mac.c (_gcry_mac_ctl): support GCRYCTL_SET_SBOX call.
+ * cipher/mac-cmac.c (cmac_ops): set set_extra_info to NULL.
+ * cipher/mac-gmac.c (gmac_ops): the same.
+ * cipher/mac-hmac.c (hmac_ops): the same.
+ * cipher/mac-poly1305.c (poly1305mac_ops): the same.
+
+2020-04-17 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Use mpi_invm_pow2 for N=2^k.
+ + commit 469e2fefb64e3a4bd80995935f82caf416e3a4ae
+ * mpi/mpi-inv.c (mpi_invm_pow2): Fix.
+ (_gcry_mpi_invm): Use mpi_invm_pow2.
+
+ mpi: Rewrite mpi_invm_odd into mpih_invm_odd.
+ + commit 05ceac8e2f6f28f97428c005d0a318d71d7cf9d9
+ * mpi/mpi-inv.c (mpih_invm_odd): Use mpi_ptr_t API.
+ (_gcry_mpi_invm): Use _gcry_mpih_mod and mpih_invm_odd.
+
+ mpi: Add _gcry_mpih_cmp_ui.
+ + commit 128045a12139fe2e4be877df59da10c7d4857d9a
+ * mpi/mpih-const-time.c (_gcry_mpih_cmp_ui): New.
+
+ mpi: Add internal functipn mpi_invm_pow2.
+ + commit 515bd6e9fae448e966f71e23635503716201158d
+ * mpi/mpi-inv.c (mpi_invm_pow2): New.
+
+2020-04-16 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Add mpi_set_bit_cond.
+ + commit a91bd0211c4e5f0ce575b3a63a36049dd9edbf90
+ * mpi/mpiutil.c (_gcry_mpi_set_bit_cond): New.
+ * src/mpi.h (mpi_set_bit_cond): New macro.
+ (_gcry_mpi_set_bit_cond): New.
+
+ mpi: Add _gcry_mpih_mod.
+ + commit 95bdfd9ce9e114f447f3639e551e8f4f63d024fe
+ * mpi/mpi-internal.h (mpih_mod, _gcry_mpih_mod): New.
+ * mpi/mpih-const-time.c (_gcry_mpih_mod): New.
+
+ mpih: Expose const-time MPI helper functions.
+ + commit 9b7e0d89006fce0641da05d8ef2696b1fb73145b
+ * mpi/Makefile.am (libmpi_la_SOURCES): Add mpih-const-time.c.
+ * mpi/ec.c (mpih_set_cond): Move to mpih-const-time.c.
+ * mpi/mpi-internal.h: Add macros and declarations.
+ * mpi/mpi-inv.c (mpih_add_n_cond): Likewise.
+ (mpih_sub_n_cond, mpih_swap_cond, mpih_abs_cond): Likewise.
+ * mpi/mpih-const-time.c: New.
+
+2020-04-14 Werner Koch <wk@gnupg.org>
+
+ sexp: Extend gcry_sexp_extract_param with a multi-string extractor.
+ + commit 32b08e38628b3ed409054db05a7f73b1ab86464a
+ * src/sexp.c (_gcry_sexp_vextract_param): Implement "%#s" control
+ sequence.
+
+2020-04-14 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Remove hard-coded value for ECC_DIALECT_ED25519.
+ + commit 0ff36e04f7cdef961610e7bc674a9c9ef0fd4853
+ * mpi/ec.c (ec_p_init): Remove special handling for Ed25519.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_encodepoint): Fix assumption
+ ec->nbits is 256 for EdDSA.
+ (_gcry_ecc_eddsa_decodepoint): Likewise.
+ (_gcry_ecc_eddsa_verify): Likewise.
+
+2020-04-09 Werner Koch <wk@gnupg.org>
+
+ sexp: Extend gcry_sexp_extract_param with new format specifiers.
+ + commit 60c179b59e538aebb3a5f7621d92eee60b90c785
+ * src/sexp.c (_gcry_sexp_vextract_param): Add new conversion methods.
+ * tests/t-sexp.c (check_extract_param): Add corresponding tests.
+
+2020-04-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ ppc: avoid using vec_vsx_ld/vec_vsx_st for 2x64-bit vectors.
+ + commit 1250a9cd859d99f487ca8d76a98d70d464324bbe
+ * cipher/crc-ppc.c (CRC_VEC_U64_LOAD, CRC_VEC_U64_LOAD_LE)
+ (CRC_VEC_U64_LOAD_BE): Remove vec_vsx_ld usage.
+ (asm_vec_u64_load, asm_vec_u64_load_le): New.
+ * cipher/sha512-ppc.c (vec_vshasigma_u64): Use '__asm__' instead of
+ 'asm' for assembly block.
+ (vec_u64_load, vec_u64_store): New.
+ (_gcry_sha512_transform_ppc8): Use vec_u64_load/store instead of
+ vec_vsx_ld/vec_vsx_st.
+ * configure.ac (gcy_cv_cc_ppc_altivec)
+ (gcy_cv_cc_ppc_altivec_cflags): Add check for vec_vsx_ld with
+ 'unsigned int *' pointer type.
+
+2020-04-02 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ asm-poly1305-aarch64: fix building with clang.
+ + commit 89b3ded8df969fe5fb31313c60419dd34d36b605
+ * cipher/asm-poly1305-aarch64.h (POLY1305_BLOCK_PART25): Use correct
+ instruction format for right-shifting.
+
+2020-03-31 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+
+ libgcrypt.m4: Fix spelling.
+ + commit 6a5743469a4366b1e238d378e427442f04400950
+
+
+ libgcrypt.m4: Fix spelling.
+ + commit e16e7e619183f36720d17855419860d1dc6fe3a5
+
+
+2020-03-20 Dmitry Baryshkov <dbaryshkov@gmail.com>
+
+ tests/basic: add GOST 28147 keymeshing testcase from LibreSSL testsuite.
+ + commit 3441f4c94c49a589c5e323b1526d2d6b5974cf2f
+ * tests/basic.c (check_cfb_cipher): add check for GOST 28147 CFB with
+ KeyMeshing enabled.
+
+ gost28147: add support for CryptoPro key meshing per RFC 4357.
+ + commit dcee00adbd1c0a2cde1aeed1bb94421e81d0de3b
+ * cipher/gost28147.c (gost_do_set_sbox, cryptopro_key_meshing,
+ CryptoProMeshingKey, gost_encrypt_block_mesh): New.
+ (_gcry_cipher_spec_gost28147_mesh): New cipher with keymeshing,
+ (_gcry_cipher_spec_gost28147): Remove OIDs for this cipher should not
+ be selected using these OIDs (they are for CFB with keymeshing).
+
+ * cipher/cipher.c (cipher_list, cipher_list_algo301): add
+ _gcry_cipher_spec_gost28147_mesh.
+
+ * src/gcrypt.h.in (GCRY_CIPHER_GOST28147_MESH): New cipher with
+ keymeshing.
+
+ * doc/gcrypt.texi (GCRY_CIPHER_GOST28147_MESH): Add definition.
+
+ * tests/basic.c (check_gost28147_cipher, check_gost28147_cipher_basic):
+ Run basic tests on GCRY_CIPHER_GOST28147_MESH.
+
+ gost: add keymeshing support per RFC 4357.
+ + commit 18cd3f0c473ae909cdaa5a820faef50d7670fcbb
+ * cipher/gost-s-box.c (gost_sbox): define if keymeshing should be
+ enabled or not.
+ (main): output whether we should enable or disable keymeshing for a
+ particular parameters set.
+
+2020-03-18 NIIBE Yutaka <gniibe@fsij.org>
+
+ DSA,ECDSA: Fix use of mpi_invm.
+ + commit ada758e3019c2585213a132960613b1ac48502b8
+ * cipher/dsa.c (sign): Call mpi_invm before _gcry_dsa_modify_k.
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Likewise.
+
+ mpi: Constant time mpi_inv with some conditions.
+ + commit 20082ca965eab5665af60956c4ed72709836b1ed
+ * mpi/mpi-inv.c (mpih_add_n_cond, mpih_sub_n_cond, mpih_swap_cond)
+ (mpih_abs_cond): New.
+ (mpi_invm_odd): New.
+ (mpi_invm_generic): Rename from _gcry_mpi_invm.
+ (_gcry_mpi_invm): Use mpi_invm_odd for usual odd cases.
+
+2020-03-11 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Support opaque MPI with gcry_mpi_print.
+ + commit b4b04ae6c2e55bc2b24efc663d1eeaa0b3613f4c
+ * mpi/mpicoder.c (_gcry_mpi_get_buffer): Return the bytes as-is.
+
+2020-03-09 Werner Koch <wk@gnupg.org>
+
+ mpi: Abort on division by zero also in _gcry_mpi_tdiv_qr.
+ + commit afbab896fa04d9481dbb9f4d01f607b12e31dcbf
+ * mpi/mpi-div.c (_gcry_mpi_tdiv_qr): Error out on division by zero.
+
+2020-02-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: More accurate dependency to -lgpg-error.
+ + commit 9b8ac13761f0407bd701e43b0a65fbada204958f
+ * configure.ac (LIBGCRYPT_CONFIG_LIBS): Remove DL_LIBS.
+ * src/libgcrypt.c.in: Distinguish static link use case.
+ * tests/Makefile.am: Fix use of -lgpg-error.
+
+ build: Fix linking -ldl.
+ + commit c21e5d72e24e62752559f92b1825287298ae2f03
+ * src/Makefile.am (libgcrypt_la_LIBADD): Add DL_LIBS.
+ (mpicalc_LDADD): Remove DL_LIBS.
+ * tests/Makefile.am (standard_ldadd): Remove DL_LIBS.
+
+2020-02-02 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ crc-ppc: fix bad register used for vector load/store assembly.
+ + commit b64b029318e7d0b66123015146614118f466a7a9
+ * cipher/crc-ppc.c (CRC_VEC_U64_LOAD_BE): Move implementation to...
+ (asm_vec_u64_load_be): ...here; Add "r0" to clobber list for load
+ instruction when offset is not zero; Add zero offset path.
+
+ rinjdael-aes: use zero offset vector load/store when possible.
+ + commit 89776d45c824032409f581e5fd1db6bf149df57f
+ * cipher/rijndael-ppc-common.h (asm_aligned_ld, asm_aligned_st): Use
+ zero offset instruction variant when input offset is constant zero.
+ * cipher/rijndael-ppc.c (asm_load_be_noswap)
+ (asm_store_be_noswap): Likewise.
+
+ Add POWER9 little-endian variant of PPC AES implementation.
+ + commit 114bbc45e9717f9ad9641f64d8df8690db8da434
+ * configure.ac: Add 'rijndael-ppc9le.lo'.
+ * cipher/Makefile.am: Add 'rijndael-ppc9le.c', 'rijndael-ppc-common.h'
+ and 'rijndael-ppc-functions.h'.
+ * cipher/rijndael-internal.h (USE_PPC_CRYPTO_WITH_PPC9LE): New.
+ (RIJNDAEL_context_s): Add 'use_ppc9le_crypto'.
+ * cipher/rijndael.c (_gcry_aes_ppc9le_encrypt)
+ (_gcry_aes_ppc9le_decrypt, _gcry_aes_ppc9le_cfb_enc)
+ (_gcry_aes_ppc9le_cfb_dec, _gcry_aes_ppc9le_ctr_enc)
+ (_gcry_aes_ppc9le_cbc_enc, _gcry_aes_ppc9le_cbc_dec)
+ (_gcry_aes_ppc9le_ocb_crypt, _gcry_aes_ppc9le_ocb_auth)
+ (_gcry_aes_ppc9le_xts_crypt): New.
+ (do_setkey, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec)
+ (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth, _gcry_aes_xts_crypt)
+ [USE_PPC_CRYPTO_WITH_PPC9LE]: New.
+ * cipher/rijndael-ppc.c: Split common code to headers
+ 'rijndael-ppc-common.h' and 'rijndael-ppc-functions.h'.
+ * cipher/rijndael-ppc-common.h: Split from 'rijndael-ppc.c'.
+ (asm_add_uint64, asm_sra_int64, asm_swap_uint64_halfs): New.
+ * cipher/rijndael-ppc-functions.h: Split from 'rijndael-ppc.c'.
+ (CFB_ENC_FUNC, CBC_ENC_FUNC): Unroll loop by 2.
+ (XTS_CRYPT_FUNC, GEN_TWEAK): Tweak generation without vperm
+ instruction.
+ * cipher/rijndael-ppc9le.c: New.
+
+ Add gcry_cipher_ctl command to allow weak keys in testing use-cases.
+ + commit 5beadf201312d0c649971b0c1d4c3827b434a0b5
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add
+ 'marks.allow_weak_key' flag.
+ * cipher/cipher.c (cipher_setkey): Do not handle weak key as error when
+ weak keys are allowed.
+ (cipher_reset): Preserve 'marks.allow_weak_key' flag on object reset.
+ (_gcry_cipher_ctl): Add handling for GCRYCTL_SET_ALLOW_WEAK_KEY.
+ * src/gcrypt.h.in (gcry_ctl_cmds): Add GCRYCTL_SET_ALLOW_WEAK_KEY.
+ * tests/basic.c (check_ecb_cipher): Add tests for weak key errors and
+ for GCRYCTL_SET_ALLOW_WEAK_KEY.
+
+2020-01-23 NIIBE Yutaka <gniibe@fsij.org>
+
+ random: Fix include of config.h.
+ + commit e0898d0628789414da23e0526c87df1885c8b3ae
+ * random/random-drbg.c: Include config.h earlier.
+
+2020-01-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ sexp: fix cast from 'int' pointer to 'size_t' pointer.
+ + commit 8b31091da092e22dba78b2402c2f436bbffc1c73
+ * src/sexp.c (do_vsexp_sscan): Change 'datalen' from 'int' to
+ 'size_t'; Remove &datalen pointer cast to 'size_t *' type.
+
+ mpi/i386: fix DWARF CFI for _gcry_mpih_sub_n and _gcry_mpih_add_n.
+ + commit 5f098f7e6ceb899ac27a0a30ee036de5f1be4e3d
+ * mpi/i386/mpih-add1.S (_gcry_mpih_add_n) [PIC]: Adjust CFI CFA offset
+ when making call and restoring stack pointer.
+ * mpi/i386/mpih-sub1.S (_gcry_mpih_sub_n) [PIC]: Ditto.
+
+2020-01-22 H.J. Lu <hjl.tools@gmail.com>
+
+ i386: Add _CET_ENDBR to indirect jump targets.
+ + commit cb9f0a2df8225eed071ae0a56265e38e9f6ff184
+ * mpi/i386/mpih-add1.S (_gcry_mpih_add_n): Save and restore
+ %ebx if IBT is enabed. Add _CET_ENDBR to indirect jump targets
+ and adjust jump destination for _CET_ENDBR.
+ * mpi/i386/mpih-sub1.S (_gcry_mpih_sub_n): Likewise.
+
+ amd64: Always include <config.h> in cipher assembly codes.
+ + commit 22e577071790834f07753c42a191a568c9f2644d
+ * cipher/camellia-aesni-avx-amd64.S: Always include <config.h>.
+ * cipher/camellia-aesni-avx2-amd64.S: Likewise.
+ * cipher/serpent-avx2-amd64.S: Likewise.
+
+ mpi: Add .note.gnu.property section for Intel CET.
+ + commit 24b4d5c10a97aaf82ac7402cc3a5b429d580cd66
+ * mpi/config.links: Include <cet.h> in <asm-syntax.h>.
+
+ x86: Add .note.gnu.property section for Intel CET.
+ + commit 4c88c2bd2a418435506325cd53246acaaa52750c
+ * configure.ac: Include <cet.h> in <config.h> for assembly
+ codes.
+
+2020-01-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ tests/basic: add vector cluttering to detect implementation bugs.
+ + commit 4aa8ff904262f331abbb8c988069a7029ca13502
+ * src/global.c (_gcry_check_version): Fix missing newline.
+ * src/basic.c (ALWAYS_INLINE, CLUTTER_REGISTER_*, prepare_vector_data)
+ (clutter_vector_registers): New.
+ (progress_handler): Make static function.
+ (check_bulk_cipher_modes, check_one_cipher_core_reset)
+ (check_one_cipher_core, check_one_md, check_one_md_multi)
+ (check_one_md_final, check_one_mac): Clutter vector registers before
+ gcry_* calls to cipher/md/mac algorithms.
+
+2020-01-22 Marvin W <git@larma.de>
+
+ Set vZZ.16b register to zero before use in armv8 gcm implementation.
+ + commit 79ed620ec46adbb08f5cea6a4865a95a436e4109
+ * cipher/cipher-gcm-armv8-aarch64-ce.S
+ (_gcry_ghash_setup_armv8_ce_pmull): Set vZZ to zero.
+
+2020-01-21 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+
+ tests: Add basic test cases for sm2.
+ + commit aa9c78afa1d867bb7b9b3c695cf31a832c9419e5
+ * tests/basic.c (check_pubkey): Add test cases for ecc-sm2.
+
+ Add elliptic curve SM2 implementation.
+ + commit 6b55246c77089dd372eb1807808111660fd789c7
+ * configure.ac (enabled_pubkey_ciphers): Add ecc-sm2.
+ * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add ecc-sm2.c.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist,
+ _gcry_pk_util_preparse_sigval): Add sm2 flags.
+ * cipher/ecc.c: Support ecc-sm2.
+ * cipher/ecc-common.h: Add declarations for ecc-sm2.
+ * cipher/ecc-sm2.c: New.
+ * src/cipher.h: Define PUBKEY_FLAG_SM2.
+
+ ecc: Simplify signature code.
+ + commit 8d9958910e54f3fecbab6e133c3971843f6ef310
+ * cipher/ecc-gost.c (_gcry_ecc_gost_sign): Use implemented function.
+ * cipher/ecc.c (ecc_verify): Remove redundant code.
+
+2020-01-21 NIIBE Yutaka <gniibe@fsij.org>
+ NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: Fix check_pubkey.
+ + commit 95e9cee802419adf6f4b01b29d7874793004fa8d
+ * tests/basic.c (check_pubkey): Fix constants of pubkeys.
+
+2020-01-21 NIIBE Yutaka <gniibe@fsij.org>
+
+ Avoid use of ulong in internal code.
+ + commit 4997139b3e83761c9af0246cec829305c3d7d13b
+ * configure.ac (HAVE_ULONG_TYPEDEF): Remove.
+ * mpi/mpi-div.c (_gcry_mpi_fdiv_r_ui): Use unsigned long.
+ (_gcry_mpi_divisible_ui): Likewise.
+ * random/rndunix.c (_gcry_rndunix_gather_random): Likewise.
+ * random/rndw32.c (_gcry_rndw32_gather_random_fast): Likewise.
+ (ADDINT): Likewise.
+ * random/rndw32ce.c (_gcry_rndw32ce_gather_random_fast): Likewise.
+ * src/mpi.h: Follow the change.
+ * src/types.h (HAVE_ULONG_TYPEDEF): Remove.
+
+2020-01-19 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ gcrypt.texi: fix GCRYCTL_GET_ALGO_NENCR typo.
+ + commit 5ebb2f0671c902863eee91cbcfc85a72be506410
+ * doc/gcrypt.texi: Fix GCRYCTL_GET_ALGO_NENC to GCRYCTL_GET_ALGO_NENCR.
+
+2020-01-19 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+
+ mpi: Fix error that point not uninitialized.
+ + commit 7e3aac7ba49b3b6e6c5ebe7c880b5b323c423ef7
+ * cipher/ecc-curves.c (mpi_ec_get_elliptic_curve): Initialize E->G poing
+
+ ecc: Wrong flag and elements_enc fix.
+ + commit 43cfc1632dd3a9579a906f31cd3b6c88d242d1a5
+ * cipher/ecc.c (ecc_generate): Fix wrong flag and elements_enc.
+
+ Update .gitignore.
+ + commit 176a5f162acd0cfebc5517d061205681bc3658d0
+
+
+2020-01-16 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+
+ Add new curve named sm2p256v1.
+ + commit d154c1e9e11019980253f0a65758932cd0656470
+ * cipher/ecc-curves.c (domain_parms): Add sm2p256v1 for SM2.
+ * tests/curves.c (N_CURVES): Update N_CURVES for SM2.
+
+2019-12-23 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael-ppc: performance improvements.
+ + commit 110077505acacae62cec3d09b32a084b9cee0368
+ * cipher/rijndael-ppc.c (ALIGNED_LOAD, ALIGNED_STORE, VEC_LOAD_BE)
+ (VEC_STORE_BE): Rewrite.
+ (VEC_BE_SWAP, VEC_LOAD_BE_NOSWAP, VEC_STORE_BE_NOSWAP): New.
+ (PRELOAD_ROUND_KEYS, AES_ENCRYPT, AES_DECRYPT): Adjust to new
+ input parameters for vector load macros.
+ (ROUND_KEY_VARIABLES_ALL, PRELOAD_ROUND_KEYS_ALL)
+ (AES_ENCRYPT_ALL): New.
+ (vec_bswap32_const_neg): New.
+ (vec_aligned_ld, vec_aligned_st, vec_load_be_const): Rename to...
+ (asm_aligned_ls, asm_aligned_st, asm_load_be_const): ...these.
+ (asm_be_swap, asm_vperm1, asm_load_be_noswap)
+ (asm_store_be_noswap): New.
+ (vec_add_uint128): Rename to...
+ (asm_add_uint128): ...this.
+ (asm_xor, asm_cipher_be, asm_cipherlast_be, asm_ncipher_be)
+ (asm_ncipherlast_be): New inline assembly functions with volatile
+ keyword to allow manual instruction ordering.
+ (_gcry_aes_ppc8_setkey, aes_ppc8_prepare_decryption)
+ (_gcry_aes_ppc8_encrypt, _gcry_aes_ppc8_decrypt)
+ (_gcry_aes_ppc8_cfb_enc, _gcry_aes_ppc8_cbc_enc)
+ (_gcry_aes_ppc8_ocb_auth): Update to use new&rewritten helper macros.
+ (_gcry_aes_ppc8_cfb_dec, _gcry_aes_ppc8_cbc_dec)
+ (_gcry_aes_ppc8_ctr_enc, _gcry_aes_ppc8_ocb_crypt)
+ (_gcry_aes_ppc8_xts_crypt): Update to use new&rewritten helper
+ macros; Tune 8-block parallel paths with manual instruction ordering.
+
+ rijndael-ppc: fix bad register used for vector load/store assembly.
+ + commit 0837d7e6be3e604c1f7b86d18c582d8aa7ed858c
+ * cipher/rijndael-ppc.c (vec_aligned_ld, vec_load_be, vec_aligned_st)
+ (vec_store_be): Add "r0" to clobber list for load/store instructions.
+
+2019-12-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ cipher: fix typo in error log.
+ + commit 5b9ea3df0dc355d77b9f061f63064614a97b8b67
+ * cipher/cipher.c (_gcry_cipher_encrypt): Fix log "cipher_decrypt: ..."
+ to "cipher_encrypt: ...".
+
+2019-11-21 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ gost28147: inline gost_val function to speed up code.
+ + commit e5c4cf0efb8fd297963e6b4392ab98c41dbad536
+ * cipher/gost28147.c (gost_val): mark function as inline
+
+ gost28147: do not use GOST28147_CONTEXT outside of GOST 28147 calculation
+ + commit f9894240bed36eab17fabf5aa482799b148618e2
+ * cipher/gost28147.c (_gcry_gost_enc_data): remove unused context
+ argument
+ * cipher/gostr3411-94.c (GOSTR3411_CONTEXT, gostr3411_init,
+ do_hash_step): remove unused GOST 28147-89 context.
+
+ gost28147: simplify internal code.
+ + commit d164a8e7f6829163f1279517f07b61805311f8f2
+ * cipher/gost28147.c (gost_val, _gost_encrypt_data): don't use gost
+ context internally
+ * cipher/gost28147.c (gost_encrypt_block, gost_decrypt_block,
+ _gcry_gost_enc_data): adapt to internal changes.
+
+ gostr3411-94: small speedup.
+ + commit 8f573a67d12e6d9026f1676a6dae7813105bc490
+ * cipher/gostr3411-94.c (do_p): unroll loop for a small spedup
+
+2019-11-18 Paul Wolneykien <manowar@altlinux.org>
+
+ ecc: update GOST2012 curves.
+ + commit a3a866f63e7a527fe3c053758b84d70c142f8283
+ * cipher/ecc-curves.c (domain_parms): rename GOST 2012 curves to contain
+ curve bit size
+ (curve_aliases): rename curves, provide backwards-compatible
+ aliases, add new OIDs and two new curves.
+ * cipher/ecc-curves.c (curve_aliases): add new OIDs and aliases for
+ * tests/basic.c (check_pubkey): use new name for GOST2012 512-bit test
+ curve.
+ * tests/benchmark.c (ecc_bench): use new name for GOST2012 512-bit test
+ curve.
+
+2019-11-05 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ ec: fix left shift overflows on WIN64 build.
+ + commit bdbd032d1626dbb34e1840e5f5393524dd546a1d
+ * mpi/ec.c (ec_mulm_448): Cast constants to (mpi_limb_t) before
+ shifting left by 32.
+
+ mpi/amd64: use SSE2 for shifting instead of MMX.
+ + commit 1322c6a5d1e9aa0c69a2b259aa5ec7bcf5cb5653
+ * mpi/amd64/mpih-lshift.S: Convert to SSE2.
+ * mpi/amd64/mpih-rshift.S: Ditto.
+
+ Add i386/SSSE3 implementation of SHA512.
+ + commit b52dde860963c794b12d14b0a9c5848bca7ba51e
+ * LICENSES: Add 'sha512-ssse3-i386.c'.
+ * configure.ac: Add 'sha512-ssse3-i386.lo'.
+ * cipher/Makefile.am: Add 'sha512-ssse3-i386.c'.
+ * cipher/sha512-ssse3-i386.c: New.
+ * cipher/sha512.c (USE_SSSE3_I386, _gcry_sha512_transform_i386_ssse3)
+ (do_sha512_transform_i386_ssse3): New.
+ (_gcry_sha512_transform_arm) [USE_SSSE3_I386]: Use i386/SSSE3 transform
+ function if supported by CPU.
+
+2019-10-28 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Add Curve for X448 with ECC_DIALECT_SAFECURVE.
+ + commit d9c418305e1053decebefbd5a98a95f845404a09
+ * cipher/ecc-curves.c (domain_parms): Add X448.
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Support X448.
+ * mpi/ec.c (ec_addm_448, ec_subm_448, ec_mulm_448): New.
+ (ec_mul2_448, ec_pow2_448): New.
+ (field_table): Add for X448.
+ (curve448_bad_points): New.
+ (bad_points_table): New.
+ (ec_p_init): Use bad_points_table.
+ * tests/Makefile.am (t-x448): Add.
+ * tests/curves.c (N_CURVES): Update.
+ * tests/t-x448.c: New.
+
+2019-10-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Introduce new dialect: ECC_DIALECT_SAFECURVE.
+ + commit 498ab6d9f2f8b0775da41553be7868e59cf4cc2e
+ * src/mpi.h (ECC_DIALECT_SAFECURVE): New.
+ * cipher/ecc-misc.c (_gcry_ecc_dialect2str): Support the new dialect.
+ * cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Support opaque
+ MPI handling of secret 'd' for ECC_DIALECT_SAFECURVE.
+ * cipher/ecc.c (nist_generate_key): Support opaque secret for
+ ECC_DIALECT_SAFECURVE.
+ (test_ecdh_only_keys): Likewise.
+ (ecc_generate): Support native point representation for
+ ECC_DIALECT_SAFECURVE.
+ (ecc_encrypt_raw): Support opaque MPI handling of secret and
+ native point representation for ECC_DIALECT_SAFECURVE.
+ (ecc_decrypt_raw): Support native point representation for
+ ECC_DIALECT_SAFECURVE.
+ (_gcry_pk_ecc_get_sexp): Likewise.
+
+ ecc: Make _gcry_mpi_ec_mul_point friendly to X25519 computation.
+ + commit 2dfedafe08ac57a87e6892d1af4d72cbb398fe40
+ * mpi/ec.c (_gcry_mpi_ec_mul_point): Support scalar input as an opaque
+ MPI in little-endian native format.
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Use an opaque scalar.
+
+ pubkey: Support a method to get data as an opaque MPI.
+ + commit 050e0b4accfae6a49dda6b1bac52749edec5ce22
+ * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Support an
+ opaque MPI in old style.
+
+2019-10-24 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Support an opaque MPI handling in mpi_from_keyparam.
+ + commit 05a7d2f262bc5c2d108dcfa6e3d907dd895a4074
+ * cipher/ecc-curves.c (mpi_from_keyparam): Add OPAQUE argument.
+
+ ecc: Fix handling of point representation in EdDSA.
+ + commit 3d5a05767b84e0f781ed5dfe434adb4d4e9d2aa5
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_ensure_compact): Use
+ GCRYMPI_FMT_USG, since integer is defined as unsigned in SEC1.
+ (_gcry_ecc_eddsa_decodepoint): Likewise.
+
+ ecc: Return an opaque MPI by _gcry_ecc_ec2os.
+ + commit 8fce1027c2531127dd52a8b883f34333ffd3763b
+ * cipher/ecc-misc.c (_gcry_ecc_ec2os): Use mpi_set_opaque instead of
+ _gcry_mpi_scan to make an opaque MPI.
+
+ ecc: String constant fix.
+ + commit 35c1faaea2b0aee9b127d02d93158826d17eb107
+ * cipher/ecc-curves.c (domain_parms): Same string length for NIST
+ P-521.
+
+ ecc: Simplify _gcry_ecc_compute_public.
+ + commit ad8927f40169364003f72fc188ea60b295ef5e59
+ * cipher/ecc-misc.c (_gcry_ecc_compute_public): Don't need G and d.
+ Use ec->G and ec->d.
+ * cipher/ecc-curves.c (_gcry_ecc_get_mpi): Follow the change.
+ (_gcry_ecc_get_point): Likewise.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_compute_h_d): Don't need d,
+ but use ec->d.
+ (_gcry_ecc_eddsa_sign): Follow the change.
+
+2019-10-23 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Use opaque MPI for _gcry_ecc_mul_point.
+ + commit c5a7191c1bd18292a34ad4da45d743dfac035f9a
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Use opaque MPI for U.
+
+ ecc: Fix _gcry_ecc_mont_decodepoint for data by old implementation.
+ + commit bbe15758c893dbf546416c1a6bccdad1ab000ad7
+ * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Support data by old
+ implementation by opaque public key.
+ Fix confusion of endian, in the handling of data by normal MPI key.
+
+ ecc: ECDH clean up for use of ec->nbits.
+ + commit 27e848666b4a03939b0c8db15aa6e6f79bc7db30
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Use ec->nbits.
+ * cipher/ecc.c (test_ecdh_only_keys): Likewise.
+ (ecc_encrypt_raw): Likewise.
+ (ecc_generate): Fix debug output format.
+
+2019-10-22 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix key generation for ECDH.
+ + commit 82441bbb82903c21cd2b9b4e2d50202b14fdc24c
+ * cipher/ecc.c (test_ecdh_only_keys): Don't free EC here.
+
+ ecc: Fix debug output.
+ + commit 6d93812aa312a92d4de2dc034bdf87c276a24b8a
+ * cipher/ecc-curves.c (_gcry_mpi_ec_internal_new): Fix debug output.
+
+ ecc: Simplify using mpi_ec_t directly.
+ + commit 6a30a9a2cc48d2343c3e9815567dbd4bf9eec058
+ * cipher/ecc-common.h (ECC_public_key, ECC_secret_key): Remove.
+ (_gcry_ecc_ecdsa_sign, _gcry_ecc_ecdsa_verify): Use mpi_ec_t.
+ (_gcry_ecc_eddsa_genkey, gcry_ecc_eddsa_sign): Likewise.
+ (_gcry_ecc_eddsa_verify): Likewise.
+ (_gcry_ecc_gost_sign, _gcry_ecc_gost_verify): Likewise.
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Use mpi_ec_t directly.
+ (_gcry_ecc_ecdsa_verify): Likewise.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Likewise.
+ (_gcry_ecc_eddsa_sign, _gcry_ecc_eddsa_verify): Likewise.
+ * cipher/ecc-gost.c (_gcry_ecc_gost_sign): Likewise.
+ (_gcry_ecc_gost_verify): Likewise.
+
+ ecc: Fix for NBITS support.
+ + commit 975de38796917392e83152447c6575648a5a5ee3
+ * cipher/ecc-curves.c (mpi_ec_get_elliptic_curve): Fill curve
+ parameters by NBITS.
+ (_gcry_mpi_ec_internal_new): Show "EdDSA".
+
+ ecc: Add NAME member to struct mpi_ec_ctx_s.
+ + commit e921ad5b3ad093304312aca90a3c971de05cbf03
+ * src/ec-context.h (struct mpi_ec_ctx_s): Add NAME.
+ * cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Initialize NAME.
+
+ ecc: Add key generation support to mpi_ec_get_elliptic_curve.
+ + commit 488704be6e044e23770d95344511c5a347b533c5
+ * cipher/ecc-curves.c (mpi_ec_get_elliptic_curve): Handle params for
+ key generation.
+ (_gcry_mpi_ec_internal_new): Remove duplication for handling of flags.
+
+ ecc: Consolidate with _gcry_mpi_ec_internal_new.
+ + commit 5415bc578080018e1cd36aa44cf5c0a9995cbafc
+ * cipher/ecc-ecdh.c (prepare_ec): Use _gcry_mpi_ec_internal_new.
+ (_gcry_ecc_mul_point): Don't need to have E of elliptic_curve_t.
+ * cipher/ecc.c (ecc_encrypt_raw): Use _gcry_mpi_ec_internal_new.
+ (ecc_decrypt_raw): Likewise.
+
+ ecc: Support flags and debug print in _gcry_mpi_ec_internal_new.
+ + commit c2aa333dd88b4cd337329128a2018dd3b00f5114
+ * cipher/ecc-curves.c (mpi_ec_get_elliptic_curve): Don't set *r_flags.
+ (_gcry_mpi_ec_internal_new): Add r_flags argument.
+ Parse the flag list.
+ Output to debug channel when DBG_CIPHER.
+
+2019-10-21 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Add new function _gcry_mpi_ec_internal_new.
+ + commit c7b97ac9bdf96f5a89ae553cac12954043ab174d
+ * cipher/ecc-curves.c (mpi_ec_get_elliptic_curve)
+ (mpi_ec_setup_elliptic_curve): Factor out from _gcry_mpi_ec_new.
+ (_gcry_mpi_ec_internal_new): New.
+ (_gcry_mpi_ec_new): Rewrite using mpi_ec_get_elliptic_curve and
+ mpi_ec_setup_elliptic_curve.
+
+ ecc: Simplify ecc_encrypt_raw and ecc_decrypt_raw.
+ + commit 10b8cc280a535f14b017106c87f2b26bb68d9489
+ * cipher/ecc.c (ecc_encrypt_raw): Use elliptic_curve_t directly.
+ (ecc_decrypt_raw): Likewise.
+
+ ecc: More fixes for cofactor with PUBKEY_FLAG_PARAM.
+ + commit 61a0518282537ad52367354c96986c3d1b698d6f
+ * cipher/ecc.c (ecc_check_secret_key): Support "h" in KEYPARMS.
+ (ecc_sign, ecc_verify, ecc_encrypt_raw, ecc_decrypt_raw): Likewise.
+
+ ecc: Simply use unsigned int for cofactor, not MPI.
+ + commit a258ae728de62607b3ef4eca940cfbcf9965fa5f
+ * cipher/ecc-common.h (elliptic_curve_t): Use unsigned int for H.
+ * src/ec-context.h (struct mpi_ec_ctx_s): Ditto.
+ * cipher/ecc-curves.c (ecc_domain_parms_t): Ditto.
+ (domain_parms): Update for the cofactors.
+ (_gcry_ecc_fill_in_curve): H is no longer MPI, but unsigned int.
+ (_gcry_ecc_get_curve): Remove handling for H.
+ (_gcry_mpi_ec_new): In KEYPARM, cofactor is still MPI.
+ (_gcry_ecc_get_param_sexp): H is no longer MPI, but unsigned int.
+ (_gcry_ecc_get_mpi): Keep the API, returning MPI for "h".
+ (_gcry_ecc_set_mpi): Likewise.
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Fix for unsigned int.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Likewise.
+ * cipher/ecc-misc.c (_gcry_ecc_curve_free): Likewise.
+ * cipher/ecc.c (nist_generate_key, test_ecdh_only_keys): Likewise.
+ (test_ecdh_only_keys, ecc_generate, ecc_check_secret_key): Likewise.
+ (ecc_sign, ecc_verify, ecc_encrypt_raw, ecc_decrypt_raw): Likewise.
+ (_gcry_pk_ecc_get_sexp): Likewise.
+ * mpi/ec.c (ec_deinit): Likewise.
+
+2019-10-18 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Simplify compute_keygrip.
+ + commit 579d5d6017d63b5eabec588b24d1a22566455bac
+ * cipher/ecc-curves.c (_gcry_ecc_update_curve_param): Remove H.
+ * cipher/ecc.c (compute_keygrip): Don't get H, since it's not
+ used in the computation.
+
+ ecc: Clean up key generation code.
+ + commit 95cc9b8f4483fd7edfc7555199f6a05cfa68a236
+ * cipher/ecc.c (test_ecdh_only_keys): No need to make PK by SK.
+
+2019-10-14 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix building t-lock for WIN32.
+ + commit 7e1383cfd43fdc2b6f743e6a1304f0f0b2142847
+ * tests/t-lock.c (external_lock_test_init, external_lock_test_lock)
+ (externel_lock_test_unlock, external_lock_test_destroy)
+ (nonce_thread, get_rand, pick_account, pick_value, revision_thread)
+ (accountant_thread): Build also if _WIN32 defined in addition to
+ HAVE_PTHREAD.
+
+ hash-common: avoid integer division to reduce call overhead.
+ + commit f9d8b5a0369cc94e125d36d9c8864d5cd2eaa1d2
+ * cipher/hash-common.h (gcry_md_block_ctx): Replace 'blocksize' with
+ 'blocksize_shift'.
+ * cipher/hash-common.c (_gcry_md_block_write): Use bit-level operations
+ instead of division to get number of blocks.
+ * cipher/gostr2411-94.c (gost3411_init): Initialize 'blocksize_shift'
+ instead of 'blocksize'.
+ * cipher/md2.c (md2_init): Ditto.
+ * cipher/md4.c (md4_init): Ditto.
+ * cipher/md5.c (md5_init): Ditto.
+ * cipher/rmd160.c (rmd160_init): Ditto.
+ * cipher/sha1.c (sha1_init): Ditto.
+ * cipher/sha256.c (sha256_common_init): Ditto.
+ * cipher/sha512.c (sha512_init_common): Ditto.
+ * cipher/sm3.c (sm3_init): Ditto.
+ * cipher/stribog.c (stribog_init_512): Ditto.
+ * cipher/tiger.c (do_init): Ditto.
+ * cipher/whirlpool.c (whirlpool_init): Ditto.
+
+2019-10-11 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Handle ephemeral key as opaque octets.
+ + commit ff0f1782560eb45458d9a8dd97088dabeddb34e7
+ * cipher/ecc.c (ecc_decrypt_raw): Extract an ephemeral key
+ as opaque octets.
+
+2019-10-10 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Consolidate encoding a point for Montgomery curve.
+ + commit 80cf289905ace9f174eb06d7f55f38980f7e4dbd
+ * cipher/ecc-common.h (_gcry_ecc_mont_encodepoint): New.
+ * cipher/ecc-misc.c (_gcry_ecc_mont_encodepoint): New.
+ * cipher/ecc.c (ecc_generate): Use _gcry_ecc_mont_encodepoint.
+ (ecc_encrypt_raw, ecc_decrypt_raw, _gcry_pk_ecc_get_sexp): Likewise.
+
+2019-10-09 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: More clean-up for Ed25519 and Curve25519.
+ + commit ba0b31f2636632b1b39ebd2202de3ba5d60588b8
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_ensure_compact): Fix calc for
+ bytes.
+ * cipher/ecc.c (ecc_encrypt_raw): Use public key as opaque byte-string
+ with "/q" for both cases, since it is always fixed size with a prefix.
+ (compute_keygrip): Likewise.
+ Fix hard-coded value of 256 for Ed25519.
+ Handle Curve25519 differently.
+
+2019-10-08 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix hard-coded value for 25519 to allow other modern curves.
+ + commit d66a4856eb0c39823bf3414b3ca4cf6322f32aef
+ * cipher/ecc.c (nist_generate_key): Support other modern curves.
+ (test_ecdh_only_keys): Likewise.
+ (check_secret_key): Don't use ECC_DIALECT_ED25519 for the check.
+ (_gcry_pk_ecc_get_sexp): Support Montgomery curve.
+
+ ecc: Clean up for decoding point.
+ + commit 254c5279058f0aea2d3568d6e756002242e82f8f
+ * cipher/ecc-curves.c (point_from_keyparam): Possibly supporting
+ Montgomery curve, use _gcry_mpi_ec_decode_point.
+ (_gcry_ecc_set_mpi): Likewise.
+ * cipher/ecc.c (ecc_check_secret_key): Likewise.
+
+ random: Clean up unused old internal API.
+ + commit 6e57242c61bca38b3cc8fdf424b5667ab953e4cd
+ * random/random.h (_gcry_get_random_bits): Remove.
+
+2019-10-02 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix regression in keygrip computation for cv25519 (2).
+ + commit 1cfe2329b91cc7be30f7c3a14fc634ec89a1be96
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Recover g_y
+ for Curve25519.
+
+2019-09-28 Werner Koch <wk@gnupg.org>
+
+ ecc: Fix regression in keygrip computation for cv25519.
+ + commit f67b6492e0b0a2a661cd53a08b20f23e6e3f9f89
+ * cipher/ecc-curves.c (domain_parms): Revert g_y for cv25519.
+ * tests/keygrip.c: Add test case for cv25519.
+
+2019-09-24 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add stitched ChaCha20-Poly1305 ARMv8/AArch64 implementation.
+ + commit 4bebafb7bae8343f543728937caf7d3453c88b7c
+ * cipher/Makefile.am: Add 'asm-poly1305-aarch64.h'.
+ * cipher/asm-poly1305-aarch64.h: New.
+ * cipher/chacha20-aarch64.S (ROT8, _, ROTATE2_8): New.
+ (ROTATE2): Add interleave operator.
+ (QUARTERROUND2): Add interleave operators; Use ROTATE2_8.
+ (chacha20_data): Rename to...
+ (_gcry_chacha20_aarch64_blocks4_data_inc_counter): ...to this.
+ (_gcry_chacha20_aarch64_blocks4_data_rot8): New.
+ (_gcry_chacha20_aarch64_blocks4): Preload ROT8; Fill empty parameters
+ for QUARTERROUND2 interleave operators.
+ (_gcry_chacha20_poly1305_aarch64_blocks4): New.
+ * cipher/chacha20.c
+ [USE_AARCH64_SIMD] (_gcry_chacha20_poly1305_aarch64_blocks4): New.
+ (_gcry_chacha20_poly1305_encrypt, _gcry_chacha20_poly1305_decrypt)
+ [USE_AARCH64_SIMD]: Use stitched implementation if ctr->use_neon is
+ set.
+
+2019-09-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Small tweak for PowerPC Chacha20-Poly1305 round loop.
+ + commit 96b91e164160dfbd913aefe258f472d386f5b642
+ * cipher/chacha20-ppc.c (_gcry_chacha20_poly1305_ppc8_block4): Use
+ inner/outer round loop structure instead of two separate loops for
+ stitched and non-stitched parts.
+
+ Reduce size of x86-64 stitched Chacha20-Poly1305 implementations.
+ + commit 664370ea02df883d16db1ffdd9ada023335b0f63
+ * cipher/chacha20-amd64-avx2.c
+ (_gcry_chacha20_poly1305_amd64_avx2_blocks8): De-unroll round loop.
+ * cipher/chacha20-amd64-ssse3.c
+ (_gcry_chacha20_poly1305_amd64_ssse3_blocks4):
+ (_gcry_chacha20_poly1305_amd64_ssse3_blocks1): Ditto.
+
+2019-09-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add PowerPC extra CFLAGS also for chacha20-ppc and crc-ppc.
+ + commit 5516072451d46be8827455afff840eb6d49155fb
+ * cipher/Makefile.am: Add 'ppc_vcrypto_cflags' for chacha20-ppc.o/.lo
+ and crc-ppc.o/.lo.
+
+2019-09-15 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add PowerPC vpmsum implementation of CRC.
+ + commit 0486b85bd1fb65013e77f858cae9ea4530f868df
+ * cipher/Makefile.am: Add 'crc-ppc.c'.
+ * cipher/crc-armv8-ce.c: Remove 'USE_INTEL_PCLMUL' comment.
+ * cipher/crc-ppc.c: New.
+ * cipher/crc.c (USE_PPC_VPMSUM): New.
+ (CRC_CONTEXT): Add 'use_vpmsum'.
+ (_gcry_crc32_ppc8_vpmsum, _gcry_crc24rfc2440_ppc8_vpmsum): New.
+ (crc32_init, crc24rfc2440_init): Add HWF check for 'use_vpmsum'.
+ (crc32_write, crc24rfc2440_write): Add 'use_vpmsum' code-path.
+ * configure.ac: Add 'vpmsumd' instruction to PowerPC VSX inline
+ assembly check; Add 'crc-ppc.lo'.
+
+ Add PowerPC vector implementation of ChaCha20.
+ + commit 557702f0d53a7ad1cf2ce0333c9df799a8abad59
+ * cipher/Makefile.am: Add 'chacha20-ppc.c'.
+ * cipher/chacha20-ppc.c: New.
+ * cipher/chacha20.c (USE_PPC_VEC, _gcry_chacha20_ppc8_blocks4)
+ (_gcry_chacha20_ppc8_blocks1, USE_PPC_VEC_POLY1305)
+ (_gcry_chacha20_poly1305_ppc8_blocks4): New.
+ (CHACHA20_context_t): Add 'use_ppc'.
+ (chacha20_blocks, chacha20_keysetup)
+ (do_chacha20_encrypt_stream_tail): Add USE_PPC_VEC code.
+ (_gcry_chacha20_poly1305_encrypt, _gcry_chacha20_poly1305_decrypt): Add
+ USE_PPC_VEC_POLY1305 code.
+ * configure.ac: Add 'chacha20-ppc.lo'.
+ * src/g10lib.h (HWF_PPC_ARCH_2_07): New.
+ * src/hwf-ppc.c (PPC_FEATURE2_ARCH_2_07): New.
+ (ppc_features): Add HWF_PPC_ARCH_2_07.
+ * src/hwfeatures.c (hwflist): Add 'ppc-arch_2_07'.
+
+2019-09-06 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ poly1305: add fast addition macro for ppc64.
+ + commit 0564757b934d24c7fef10df8594099985fbbc0ac
+ * cipher/poly1305.c [USE_MPI_64BIT && __powerpc__] (ADD_1305_64): New.
+
+2019-09-03 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add SHA-512 implementations for POWER8 and POWER9.
+ + commit 93632f1adf57f142e5d9e9653c405f2ca8c601c0
+ * cipher/Makefile.am: Add 'sha512-ppc.c'; Add extra CFLAG handling for
+ 'sha512-ppc.c'.
+ * cipher/sha512-ppc.c: New.
+ * cipher/sha512.c (USE_PPC_CRYPTO, _gcry_sha512_transform_ppc8)
+ (_gcry_sha512_transform_ppc9, do_sha512_transform_ppc8)
+ (do_sha512_transform_ppc9): New.
+ (sha512_init_common): Add PowerPC HW feature detection and
+ implementation selection.
+ * configure.ac: Add 'vshasigmad' instruction to PowerPC assembly
+ support check; Add 'sha512-ppc.lo'.
+
+2019-08-31 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add SHA-256 implementations for POWER8 and POWER9.
+ + commit e19dc973bc8e2a0ce92dd87515df3ee338265a8d
+ * cipher/Makefile.am: Add 'sha256-ppc.c'; Add extra CFLAG handling for
+ 'sha256-ppc.c'.
+ * cipher/sha256-ppc.c: New.
+ * cipher/sha256.c (USE_PPC_CRYPTO, _gcry_sha256_transform_ppc8)
+ (_gcry_sha256_transform_ppc9, do_sha256_transform_ppc8)
+ (do_sha256_transform_ppc9): New.
+ (sha256_init, sha224_init): Split common part to new function named...
+ (sha256_common_init): ...this; Add PowerPC HW feature detection and
+ implementation selection.
+ * configure.ac: Add 'vshasigmaw' instruction to PowerPC assembly
+ support check; Add 'sha256-ppc.lo'.
+
+2019-08-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ hwf-ppc: add detection for PowerISA 3.00.
+ + commit 418179593080f3028426657c4ef1941cdad85513
+ * src/g10lib.h (HWF_PPC_ARCH_3_00): New.
+ * src/hwf-ppc.c (feature_map_s): Remove unused 'feature_match'.
+ (PPC_FEATURE2_ARCH_3_00): New.
+ (ppc_features, get_hwcap): Add PowerISA 3.00.
+ * src/hwfeatures.c (hwflist): Rename "ppc-crypto" to "ppc-vcrypto"; Add
+ "ppc-arch_3_00".
+
+ rijndael-ppc: add bulk modes for CBC, CFB, CTR and XTS.
+ + commit 81d555d3473016eb9382fb1df153ba1effbbe32e
+ * cipher/rijndael-ppc.c (vec_add_uint128, _gcry_aes_ppc8_cfb_enc)
+ (_gcry_aes_ppc8_cfb_dec, _gcry_aes_ppc8_cbc_enc)
+ (_gcry_aes_ppc8_cbc_dec, _gcry_aes_ppc8_ctr_enc)
+ (_gcry_aes_ppc8_xts_crypt): New.
+ * cipher/rijndael.c [USE_PPC_CRYPTO] (_gcry_aes_ppc8_cfb_enc)
+ (_gcry_aes_ppc8_cfb_dec, _gcry_aes_ppc8_cbc_enc)
+ (_gcry_aes_ppc8_cbc_dec, _gcry_aes_ppc8_ctr_enc)
+ (_gcry_aes_ppc8_xts_crypt): New.
+ (do_setkey, _gcry_aes_cfb_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_enc)
+ (_gcry_aes_cbc_dec, _gcry_aes_ctr_enc)
+ (_gcry_aes_xts_crypto) [USE_PPC_CRYPTO]: Enable PowerPC AES
+ CFB/CBC/CTR/XTS bulk implementations.
+ * configure.ac (gcry_cv_gcc_inline_asm_ppc_altivec): Add 'vadduwm'
+ instruction.
+
+ rijndael-ppc: add bulk mode for ocb_auth.
+ + commit bd1367bb607846d582ad09ded6c4ce4be4e52778
+ * cipher/rijndael-ppc.c (_gcry_aes_ppc8_ocb_auth): New.
+ * cipher/rijndael.c [USE_PPC_CRYPTO] (_gcry_aes_ppc8_ocb_auth): New
+ prototype.
+ (do_setkey, _gcry_aes_ocb_auth) [USE_PPC_CRYPTO]: Add PowerPC AES
+ ocb_auth.
+
+ rijndael-ppc: enable PowerPC AES-OCB implemention.
+ + commit 821602c60c7d144c978c335f91ae1641cf668df5
+ * cipher/rijndael-ppc.c (ROUND_KEY_VARIABLES, PRELOAD_ROUND_KEYS)
+ (AES_ENCRYPT, AES_DECRYPT): New.
+ (_gcry_aes_ppc8_prepare_decryption): Rename to...
+ (aes_ppc8_prepare_decryption): ... this.
+ (_gcry_aes_ppc8_prepare_decryption): New.
+ (aes_ppc8_encrypt_altivec, aes_ppc8_decrypt_altivec): Remove.
+ (_gcry_aes_ppc8_encrypt): Use AES_ENCRYPT macro.
+ (_gcry_aes_ppc8_decrypt): Use AES_DECRYPT macro.
+ (_gcry_aes_ppc8_ocb_crypt): Uncomment; Optimizations for OCB offset
+ calculations, etc; Use new load/store and encryption/decryption macros.
+ * cipher/rijndaelc [USE_PPC_CRYPTO] (_gcry_aes_ppc8_ocb_crypt): New
+ prototype.
+ (do_setkey, _gcry_aes_ocb_crypt) [USE_PPC_CRYPTO]: Add PowerPC AES OCB
+ encryption/decryption.
+
+ rijndael-ppc: add key setup and enable single block PowerPC AES.
+ + commit 9dca65ef71b4bdbd89a087f41f4dbba71e6d2822
+ * cipher/Makefile.am: Add 'rijndael-ppc.c'.
+ * cipher/rijndael-internal.h (USE_PPC_CRYPTO): New.
+ (RIJNDAEL_context): Add 'use_ppc_crypto'.
+ * cipher/rijndael-ppc.c (backwards, swap_if_le): Remove.
+ (u128_t, ALWAYS_INLINE, NO_INLINE, NO_INSTRUMENT_FUNCTION)
+ (ASM_FUNC_ATTR, ASM_FUNC_ATTR_INLINE, ASM_FUNC_ATTR_NOINLINE)
+ (ALIGNED_LOAD, ALIGNED_STORE, VEC_LOAD_BE, VEC_STORE_BE)
+ (vec_bswap32_const, vec_aligned_ld, vec_load_be_const)
+ (vec_load_be, vec_aligned_st, vec_store_be, _gcry_aes_sbox4_ppc8)
+ (_gcry_aes_ppc8_setkey, _gcry_aes_ppc8_prepare_decryption)
+ (aes_ppc8_encrypt_altivec, aes_ppc8_decrypt_altivec): New.
+ (_gcry_aes_ppc8_encrypt, _gcry_aes_ppc8_decrypt): Rewrite.
+ (_gcry_aes_ppc8_ocb_crypt): Comment out.
+ * cipher/rijndael.c [USE_PPC_CRYPTO] (_gcry_aes_ppc8_setkey)
+ (_gcry_aes_ppc8_prepare_decryption, _gcry_aes_ppc8_encrypt)
+ (_gcry_aes_ppc8_decrypt): New prototypes.
+ (do_setkey) [USE_PPC_CRYPTO]: Add setup for PowerPC AES.
+ (prepare_decryption) [USE_PPC_CRYPTO]: Ditto.
+ * configure.ac: Add 'rijndael-ppc.lo'.
+ (gcry_cv_ppc_altivec, gcry_cv_cc_ppc_altivec_cflags)
+ (gcry_cv_gcc_inline_asm_ppc_altivec)
+ (gcry_cv_gcc_inline_asm_ppc_arch_3_00): New checks.
+
+2019-08-26 Shawn Landden <shawn@git.icu>
+
+ rijndael/ppc: implement single-block mode, and implement OCB block cipher
+ + commit 92f38a619b1cf759057e9cd532ae7c1d0331100f
+ * cipher/rijndael-ppc.c: New implementation of single-block mode, and
+ implementation of OCB mode.
+
+ hwf: add detection of PowerPC hardware features.
+ + commit b4a3c76fabfa07c10fd18b90230f60b806ad9620
+ * src/Makefile.am: PowerPC hardware detection.
+ * src/g10lib.h: Likewise.
+ * src/hwf-common.h: Likewise.
+ * src/hwf-ppc.c: Likewise.
+ * src/hwfeatures.c: Likewise.
+ * configure.ac: Likewise.
+
+2019-08-20 NIIBE Yutaka <gniibe@fsij.org>
+
+ pkgconfig: Fix libgcrypt.pc.
+ + commit 761d12f140b77b907087590646651d9578b68a54
+ * src/libgcrypt.pc.in (Cflags, Libs): Have flags.
+
+2019-08-16 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Fix build with !HAVE_PTHREAD.
+ + commit 900647d96cb7806cd9b2de343e4a4bd66c073fba
+ * tests/t-lock.c [!HAVE_PTHREAD]: Buildable now.
+
+ ecdsa: Fix unblinding too early.
+ + commit cdaeb86f067b94d9dff4235ade20dde6479d9bb8
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Keep the blinding until
+ the last step.
+
+2019-08-12 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Fix testapi.c to be buildable.
+ + commit 376124f86097414cf1f9cbbc17af935d30064c82
+ * tests/testapi.c: Fix for xgcry_control.
+
+2019-08-08 NIIBE Yutaka <gniibe@fsij.org>
+
+ dsa,ecdsa: Fix use of nonce, use larger one.
+ + commit 7c2943309d14407b51c8166c4dcecb56a3628567
+ * cipher/dsa-common.c (_gcry_dsa_modify_k): New.
+ * cipher/pubkey-internal.h (_gcry_dsa_modify_k): New.
+ * cipher/dsa.c (sign): Use _gcry_dsa_modify_k.
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Likewise.
+ * cipher/ecc-gost.c (_gcry_ecc_gost_sign): Likewise.
+
+2019-08-07 NIIBE Yutaka <gniibe@fsij.org>
+ Ján JanÄár <johny@neuromancer.sk>
+
+ ecc: Add mitigation against timing attack.
+ + commit b9577f7c89b4327edc09f2231bc8b31521102c79
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Add the order N to K.
+ * mpi/ec.c (_gcry_mpi_ec_mul_point): Compute with NBITS of P or larger.
+
+2019-08-07 NIIBE Yutaka <gniibe@fsij.org>
+
+ dsa,ecdsa: Allocate secure memory for RFC6979 generation.
+ + commit 75c2fbc43d2f2cf5f4c60cb28001fda7324185c2
+ * cipher/dsa-common.c (_gcry_dsa_gen_rfc6979_k): Use secure memory
+ just like _gcry_dsa_gen_k does.
+
+2019-07-22 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Fix previous commit.
+ + commit 6126fc2f180a9b61064cea5c838d2ff7e0b7774a
+
+
+ build: Use {CFLAGS,CPPFLAGS,LDFLAGS}_FOR_BUILD for helper programs.
+ + commit 6d80f3f12dc2ff04b0eaa3ba29ee8725b6fb4f69
+ * configure.ac (CC_FOR_BUILD): Use AX_CC_FOR_BUILD.
+ * cipher/Makefile.am (gost-s-box): Add
+ {CFLAGS,CPPFLAGS,LDFLAGS}_FOR_BUILD.
+ * doc/Makefile.am (yat2m): Likewise.
+ * m4/ax_cc_for_build.m4: New.
+
+2019-07-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix use of AVX instruction in SHA1/SSSE3 assembly.
+ + commit 320ed47963032aab7aadd8aefa054b9a7725c9f7
+ * cipher/sha1-ssse3-amd64.S: Replace 'vmovdqa' with 'movdqa'
+ instruction.
+
+2019-07-15 Werner Koch <wk@gnupg.org>
+
+ sexp: Improve argument checking of sexp parser.
+ + commit 1c2cecbb35e1a0760121d76c327651fe7b2b791a
+ * src/sexp.c (do_vsexp_sscan): Check for bad length in '%b'.
+
+2019-07-15 NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: t-mpi-point: Remove implementation dependent checks.
+ + commit 8a0bde8c211c70756a2d8aa46e1bcf1f6f89e55d
+ * tests/t-mpi-point.c (basic_ec_math): Remove comparing X and Y,
+ only comparison of Z is relevant, mathematically.
+ Remove useless check, where different values in equivalence class
+ exist.
+ (basic_ec_math_simplified): Likewise.
+
+2019-06-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ sexp: Support reading base64.
+ + commit ab57613f10ad57d2fec648017c18d7abb189863b
+ * configure.ac (NEED_GPG_ERROR_VERSION): Require libgpg-error >= 1.27.
+ * src/sexp.c (do_vsexp_sscan): Support data in base64 format.
+ * tests/t-sexp.c (check_extract_param): Add a test case.
+
+2019-06-24 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Correctly return an error.
+ + commit b4a1114dc77617f0e772ddc4faf8820399b4354a
+ * cipher/ecc-ecdh.c (_gcry_ecc_get_algo_keylen): Return 0 for
+ unknow algorithm.
+ (_gcry_ecc_mul_point): Return GPG_ERR_UNSUPPORTED_ALGORITHM for
+ GCRY_ECC_CURVE448 for now.
+ Return GPG_ERR_UNKNOWN_ALGORITHM, otherwise.
+
+2019-06-21 NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: Fix the Curve25519 test.
+ + commit 6934711d572e13e9e78fb2c53bb119034b088c5a
+ * tests/t-cv25519.c (test_cv_x25519): Initialize SCALAR.
+
+ ecc: Improve new ECDH API.
+ + commit a658c9ccc2c741f40b0b5cdbcd184cfb9a841d17
+ * cipher/ecc-ecdh.c (_gcry_ecc_get_algo_keylen): New.
+ (_gcry_ecc_mul_point): Fill into the RESULT buffer, instead of
+ allocating new buffer.
+ * src/gcrypt-int.h: Change the API.
+ * src/gcrypt.h.in: Likewise.
+ * src/libgcrypt.def (gcry_ecc_get_algo_keylen): New.
+ * src/libgcrypt.vers (gcry_ecc_get_algo_keylen): New.
+ * src/visibility.c (gcry_ecc_get_algo_keylen): New.
+ * src/visibility.h (gcry_ecc_get_algo_keylen): New.
+ * tests/t-cv25519.c: Fix the use case.
+
+2019-06-20 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: X25519 API change to allow NULL for POINT.
+ + commit 6d77c2054ea0358fb4c6f59b4c91c673c0a83b03
+ * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Allow NULL for point,
+ meaning G.
+
+ ecc: Add an API for X25519 function as gcry_ecc_mul_point.
+ + commit ec8c2cdf977aa8d9ca5af0a9bd25aeb9190570b3
+ * configure.ac: Add ecc-ecdh.lo.
+ * cipher/Makefile.am: Add ecc-ecdh.c.
+ * cipher/ecc-common.h (reverse_buffer): Expose.
+ * cipher/ecc-eddsa.c (reverse_buffer): Expose.
+ * cipher/ecc-curves.c (domain_parms): Fix as the errata of RFC.
+ * cipher/ecc-ecdh.c: New.
+ * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Fix for other curves
+ than Curve25519.
+ * src/gcrypt-int.h (_gcry_ecc_mul_point): New.
+ * src/gcrypt.h.in (enum gcry_ecc_curves): New.
+ (gcry_ecc_mul_point): new.
+ * src/libgcrypt.def (gcry_ecc_mul_point): New.
+ * src/libgcrypt.vers (gcry_ecc_mul_point): New.
+ * src/visibility.h (gcry_ecc_mul_point): New.
+ * src/visibility.c (gcry_ecc_mul_point): New.
+ * tests/t-cv25519.c (test_cv_hl): Rename from test_cv.
+ (test_cv_x25519): New.
+ (test_cv): Call both of test_cv_hl and test_cv_x25519.
+
+2019-06-05 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ tests/basic: add CTR mode carry overflow test vectors.
+ + commit 971d372f512ff6805d5b8b54e9ac1446f3f66643
+ * tests/basic.c (check_ctr_cipher): Change tv structure 'plaintext'
+ and 'out' to pointers; Add counter carry overflow test vectors; Make
+ temporary buffer large enough for new test vectors.
+
+ GCM: move look-up table to .data section and unshare between processes.
+ + commit a4c561aab1014c3630bc88faf6f5246fee16b020
+ * cipher/cipher-gcm.c (ATTR_ALIGNED_64): New.
+ (gcmR): Move to 'gcm_table' structure.
+ (gcm_table): New structure for look-up table with counters before and
+ after.
+ (gcmR): New macro.
+ (prefetch_table): Handle input with length not multiple of 256.
+ (do_prefetch_tables): Modify pre- and post-table counters to unshare
+ look-up table pages between processes.
+
+ AES: move look-up tables to .data section and unshare between processes.
+ + commit daedbbb5541cd8ecda1459d3b843ea4d92788762
+ * cipher/rijndael-internal.h (ATTR_ALIGNED_64): New.
+ * cipher/rijndael-tables.h (encT): Move to 'enc_tables' structure.
+ (enc_tables): New structure for encryption table with counters before
+ and after.
+ (encT): New macro.
+ (dec_tables): Add counters before and after encryption table; Move
+ from .rodata to .data section.
+ (do_encrypt): Change 'encT' to 'enc_tables.T'.
+ (do_decrypt): Change '&dec_tables' to 'dec_tables.T'.
+ * cipher/cipher-gcm.c (prefetch_table): Make inline; Handle input
+ with length not multiple of 256.
+ (prefetch_enc, prefetch_dec): Modify pre- and post-table counters
+ to unshare look-up table pages between processes.
+
+2019-05-19 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ cipher/Makefile.am: add '-fcoverage-*' to instrumentation munging.
+ + commit c6ffa216976d80a13486b13f64d6776cdb8b6ccf
+ * cipher/Makefile.am: Remove '-fcoverage-*' flag for mixed asm/C
+ i386+amd64 implementations.
+
+2019-05-15 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ md: fix UBSAN warning.
+ + commit dad94696d9c48c18b59576776c7caa95123dfa1b
+ * cipher/md.c (gcry_md_list): Define 'context' as array of
+ PROPERLY_ALIGNED_TYPE.
+ (md_enable, _gcry_md_reset, _gcry_md_close, md_final, md_set_key)
+ (prepare_macpads, md_read, md_extract): Access md context through
+ 'gcry_md_list->context' pointer instead of 'gcry_md_list->context.c'.
+
+ Disable instrumentation on mixed Intel SSE C/assembly implementations.
+ + commit d24dae4538dbbda9e6c72a34fae69682cfb2fef0
+ * cipher/Makefile.am: Make 'tiger.o' and 'tiger.lo' depend on Makefile;
+ Add instrumentation option munging.
+ * cipher/cipher-gcm-intel-pcmul.c (ALWAYS_INLINE)
+ (NO_INSTRUMENT_FUNCTION, ASM_FUNC_ATTR, ASM_FUNC_ATTR_INLINE): New.
+ (reduction, gfmul_pclmul, gfmul_pclmul_aggr4, gfmul_pclmul_aggr8)
+ (gcm_lsh): Define with 'ASM_FUNC_ATTR_INLINE' instead of 'inline'.
+ (_gcry_ghash_setup_intel_pclmul, _gcry_ghash_intel_pclmul): Define with
+ 'ASM_FUNC_ATTR'.
+ * cipher/crc-intel-pcmul.c (ALWAYS_INLINE, NO_INSTRUMENT_FUNCTION)
+ (ASM_FUNC_ATTR, ASM_FUNC_ATTR_INLINE): New.
+ (crc32_reflected_bulk, crc32_reflected_less_than_16, crc32_bulk)
+ (crc32_less_than_16): Define with 'ASM_FUNC_ATTR_INLINE' instead of
+ 'inline'.
+ (_gcry_crc32_intel_pclmul, _gcry_crc24rfc2440_intel_pclmul): Define
+ with 'ASM_FUNC_ATTR'.
+ * cipher/rijndael-aesni.c (NO_INSTRUMENT_FUNCTION, ASM_FUNC_ATTR)
+ (ASM_FUNC_ATTR_INLINE, ASM_FUNC_ATTR_NOINLINE): New.
+ (aes_ocb_get_l, do_aesni_prepare_decryption, do_aesni_enc)
+ (do_aesni_dec, do_aesni_enc_vec4, do_aesni_dec_vec4, do_aesni_enc_vec8)
+ (do_aesni_dec_vec8, aesni_ocb_checksum): Define with
+ 'ASM_FUNC_ATTR_INLINE' instead of 'inline'.
+ (do_aesni_ctr, do_aesni_ctr_4, do_aesni_ctr_8): Define wtih
+ 'ASM_FUNC_ATTR_INLINE'.
+ (aesni_ocb_enc, aesni_ocb_dec): Define with 'ASM_FUNC_ATTR_NOINLINE'
+ instead of 'NO_INLINE'.
+ (_gcry_aes_aesni_do_setkey, _gcry_aes_aesni_prepare_decryption)
+ (_gcry_aes_aesni_encrypt, _gcry_aes_aesni_cfg_enc)
+ (_gcry_aes_aesni_cbc_enc, _gcry_aes_aesni_ctr_enc)
+ (_gcry_aes_aesni_decrypt, _gcry_aes_aesni_cfb_dec)
+ (_gcry_aes_aesni_cbc_dec, _gcry_aes_aesni_ocb_crypt)
+ (_gcry_aes_aesni_ocb_auth, _gcry_aes_aesni_xts_enc)
+ (_gcry_aes_aesni_xts_dec, _gcry_aes_aesni_xts_crypt): Define with
+ 'ASM_FUNC_ATTR'.
+ * cipher/rijndael-ssse3-amd64.c (ALWAYS_INLINE, NO_INSTRUMENT_FUNCTION)
+ (ASM_FUNC_ATTR, ASM_FUNC_ATTR_INLINE): New.
+ (aes_ocb_get_l, do_ssse3_prepare_decryption, do_vpaes_ssse3_enc)
+ (do_vpaes_ssse3_dec): Define with 'ASM_FUNC_ATTR_INLINE' instead of
+ 'inline'.
+ (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption)
+ (_gcry_aes_ssse3_encrypt, _gcry_aes_ssse3_cfb_enc)
+ (_gcry_aes_ssse3_cbc_enc, _gcry_aes_ssse3_ctr_enc)
+ (_gcry_aes_ssse3_decrypt, _gcry_aes_ssse3_cfb_dec)
+ (_gcry_aes_ssse3_cbc_dec, ssse3_ocb_enc, ssse3_ocb_dec)
+ (_gcry_aes_ssse3_ocb_crypt, _gcry_aes_ssse3_ocb_auth): Define with
+ 'ASM_FUNC_ATTR'.
+ * cipher/sha1-intel-shaext.c (NO_INSTRUMENT_FUNCTION)
+ (ASM_FUNC_ATTR): New.
+ (_gcry_sha1_transform_intel_shaext): Define with 'ASM_FUNC_ATTR'.
+ * cipher/sha256-intel-shaext.c (NO_INSTRUMENT_FUNCTION)
+ (ASM_FUNC_ATTR): New.
+ (_gcry_sha256_transform_intel_shaext): Define with 'ASM_FUNC_ATTR'.
+ * configure.ac (ENABLE_INSTRUMENTATION_MUNGING): New.
+
+ tests/basic: fix signed interger overflow.
+ + commit 3c7ff6bd1c40d5216d6c12b6b28f77fd1a57baa7
+ * tests/basic.c (check_ocb_cipher_largebuf_split): Cast to unsigned
+ when generating buffer values.
+
+2019-05-14 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ tests: do not use GCC variadic macro extension for xgcry_control.
+ + commit be567cb5dd629e9aa22d81b29d4326e5aa97efa7
+ * tests/t-common.h (xgcry_control): Use doubly nested parenthesis for
+ passing arguments for gcry_control instead of GCC specific variadic
+ macro extension.
+ * tests/aeswrap.c: Change xgcry_control to use doubly nested
+ parenthesis.
+ * tests/basic.c: Ditto.
+ * tests/bench-slope.c: Ditto.
+ * tests/benchmark.c: Ditto.
+ * tests/curves.c: Ditto.
+ * tests/dsa-rfc6979.c: Ditto.
+ * tests/fips186-dsa: Ditto.
+ * tests/fipsdrv.c: Ditto.
+ * tests/fipsrngdrv.c: Ditto.
+ * tests/gchash.c: Ditto.
+ * tests/hashtest.c: Ditto.
+ * tests/hmac.c: Ditto.
+ * tests/keygen.c: Ditto.
+ * tests/keygrip.c: Ditto.
+ * tests/mpitests.c: Ditto.
+ * tests/pkbench.c: Ditto.
+ * tests/pkcs1v2.c: Ditto.
+ * tests/prime.c: Ditto.
+ * tests/pubkey.c: Ditto.
+ * tests/random.c: Ditto.
+ * tests/rsacvt.c: Ditto.
+ * tests/t-convert.c: Ditto.
+ * tests/t-cv25519.c: Ditto.
+ * tests/t-ed25519.c: Ditto.
+ * tests/t-kdf.c: Ditto.
+ * tests/t-lock.c: Ditto.
+ * tests/t-mpi-bit.c: Ditto.
+ * tests/t-mpi-point.c: Ditto.
+ * tests/t-secmem.c: Ditto.
+ * tests/t-sexp.c: Ditto.
+ * tests/version.c: Ditto.
+
+2019-05-10 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ tests/basic: mark CFB and CFB8 as stream block cipher modes.
+ + commit 34e9306a66b47785ddbab6594ae4c23581d35b5a
+ * tests/basic.c (get_algo_mode_blklen): Return '1' for CFB and CFB8.
+
+2019-05-09 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix message digest final function for MD4, MD5 and RMD160.
+ + commit 15592cd52f543aadb2fab8f6c112c68075309ad6
+ * cipher/md4.c (md4_final): Use buffer offset '64 + 56' for bit count
+ on 'need one extra block' path.
+ * cipher/md5.c (md5_final): Ditto.
+ * cipher/rmd160.c (rmd160_final): Ditto.
+ * tests/basic.c (check_one_md_final): New.
+ (check_digest): Add new '*' test vectors and handle them with
+ check_one_md_final.
+
+2019-05-06 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Fix carry overflow in Stribog in 512-bit addition.
+ + commit da6cd4fea30f79cf9d8f9b2f1c6daf3aea39fa9c
+ * cipher/stribog.c (transform_bits): properly calculate carry flag
+ * tests/basic.c (check_digests): add two more test cases
+
+2019-04-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add support for explicit_memset.
+ + commit 71b0eb3fb75d2e6bbd86df055dc667b2debab0c1
+ * configure.ac: Add function check for 'explicit_memset'.
+ * src/misc.c (_gcry_fast_wipememory, _gcry_fast_wipememory2): Use
+ explicit_memset if available.
+
+ Fix CFI_PUSH/CFI_POP redefine build warning with AMD64 MPI.
+ + commit 78b1047eded8d5f8a13162d13160fce1809f6ee4
+ * mpi/amd64/func_abi.h: Move CFI macros into [__x86_64__] block.
+ * mpi/i386/syntax.h: Move CFI macros into [__i386__] block.
+
+ Enable four block aggregated GCM Intel PCLMUL implementation on i386.
+ + commit a6e7c411e5f67a9473675ca8d49017a4d13a8d3e
+ * cipher/cipher-gcm-intel-pclmul.c (reduction): Change "%%xmm7" to
+ "%%xmm5".
+ (gfmul_pclmul_aggr4): Move outside [__x86_64__] block; Remove usage of
+ XMM8-XMM15 registers; Do not preload H-values and be_mask to reduce
+ register usage for i386.
+ (_gcry_ghash_setup_intel_pclmul): Enable calculation of H2, H3 and H4
+ on i386.
+ (_gcry_ghash_intel_pclmul): Adjust to above gfmul_pclmul_aggr4
+ changes; Move 'aggr4' code path outside [__x86_64__] block.
+
+ Prefetch GCM look-up tables.
+ + commit 1374254c2904ab5b18ba4a890856824a102d4705
+ * cipher/cipher-gcm.c (prefetch_table, do_prefetch_tables)
+ (prefetch_tables): New.
+ (ghash_internal): Call prefetch_tables.
+
+ Optimizations for generic table-based GCM implementations.
+ + commit ecd02cdd61e8c690f48637656f0e1e08b750fe30
+ * cipher/cipher-gcm.c [GCM_TABLES_USE_U64] (do_fillM): Precalculate
+ M[32..63] values.
+ [GCM_TABLES_USE_U64] (do_ghash): Split processing of two 64-bit halfs
+ of the input to two separate loops; Use precalculated M[] values.
+ [GCM_USE_TABLES && !GCM_TABLES_USE_U64] (do_fillM): Precalculate
+ M[64..127] values.
+ [GCM_USE_TABLES && !GCM_TABLES_USE_U64] (do_ghash): Use precalculated
+ M[] values.
+ [GCM_USE_TABLES] (bshift): Avoid conditional execution for mask
+ calculation.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Double gcm_table size.
+
+2019-04-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Optimizations for GCM Intel/PCLMUL implementation.
+ + commit af5f3fb08674608acf6617ea622ed0b9a2ee77a5
+ * cipher/cipher-gcm-intel-pclmul.c (reduction): New.
+ (glmul_pclmul): Include shifting to left into pclmul operations; Use
+ 'reduction' helper function.
+ [__x86_64__] (gfmul_pclmul_aggr4): Reorder instructions and adjust
+ register usage to free up registers; Use 'reduction' helper function;
+ Include shifting to left into pclmul operations; Moving load H values
+ and input from caller into this function.
+ [__x86_64__] (gfmul_pclmul_aggr8): New.
+ (gcm_lsh): New.
+ (_gcry_ghash_setup_intel_pclmul): Left shift H values to left by
+ one; Preserve XMM6-XMM15 registers on WIN64.
+ (_gcry_ghash_intel_pclmul) [__x86_64__]: Use 8 block aggregated
+ reduction function.
+
+ Move data pointer macro for 64-bit ARM assembly to common header.
+ + commit b9be297bb8eba7a09fa8413261de1587adcfd381
+ * cipher/asm-common-aarch64.h (GET_DATA_POINTER): New.
+ * cipher/chacha20-aarch64.S (GET_DATA_POINTER): Remove.
+ * cipher/cipher-gcm-armv8-aarch64-ce.S (GET_DATA_POINTER): Remove.
+ * cipher/crc-armv8-aarch64-ce.S (GET_DATA_POINTER): Remove.
+ * cipher/rijndael-armv8-aarch64-ce.S (GET_DATA_POINTER): Remove.
+ * cipher/sha1-armv8-aarch64-ce.S (GET_DATA_POINTER): Remove.
+ * cipher/sha256-armv8-aarch64-ce.S (GET_DATA_POINTER): Remove.
+
+ Add CFI unwind assembly directives for 64-bit ARM assembly.
+ + commit 5a2a96a63517838e04f9fc0fb2d932fac5124b8a
+ * cipher/asm-common-aarch64.h (CFI_STARTPROC, CFI_ENDPROC)
+ (CFI_REMEMBER_STATE, CFI_RESTORE_STATE, CFI_ADJUST_CFA_OFFSET)
+ (CFI_REL_OFFSET, CFI_DEF_CFA_REGISTER, CFI_REGISTER, CFI_RESTORE)
+ (DW_REGNO_SP, DW_SLEB128_7BIT, DW_SLEB128_28BIT, CFI_CFA_ON_STACK)
+ (CFI_REG_ON_STACK): New.
+ * cipher/camellia-aarch64.S: Add CFI directives.
+ * cipher/chacha20-aarch64.S: Add CFI directives.
+ * cipher/cipher-gcm-armv8-aarch64-ce.S: Add CFI directives.
+ * cipher/crc-armv8-aarch64-ce.S: Add CFI directives.
+ * cipher/rijndael-aarch64.S: Add CFI directives.
+ * cipher/rijndael-armv8-aarch64-ce.S: Add CFI directives.
+ * cipher/sha1-armv8-aarch64-ce.S: Add CFI directives.
+ * cipher/sha256-armv8-aarch64-ce.S: Add CFI directives.
+ * cipher/twofish-aarch64.S: Add CFI directives.
+ * mpi/aarch64/mpih-add1.S: Add CFI directives.
+ * mpi/aarch64/mpih-mul1.S: Add CFI directives.
+ * mpi/aarch64/mpih-mul2.S: Add CFI directives.
+ * mpi/aarch64/mpih-mul3.S: Add CFI directives.
+ * mpi/aarch64/mpih-sub1.S: Add CFI directives.
+ * mpi/asm-common-aarch64.h: Include "../cipher/asm-common-aarch64.h".
+ (ELF): Remove.
+
+ Add 64-bit ARMv8/CE PMULL implementation of CRC.
+ + commit 14c8a593ede42f51f567ed7ba77b53124151aa38
+ * cipher/Makefile.am: Add 'crc-armv8-ce.c' and
+ 'crc-armv8-aarch64-ce.S'.
+ * cipher/asm-common-aarch64.h [HAVE_GCC_ASM_CFI_DIRECTIVES]: Add CFI
+ helper macros.
+ * cipher/crc-armv8-aarch64-ce.S: New.
+ * cipher/crc-armv8-ce.c: New.
+ * cipher/crc.c (USE_ARM_PMULL): New.
+ (CRC_CONTEXT) [USE_ARM_PMULL]: Add 'use_pmull'.
+ [USE_ARM_PMULL] (_gcry_crc32_armv8_ce_pmull)
+ (_gcry_crc24rfc2440_armv8_ce_pmull): New prototypes.
+ (crc32_init, crc32rfc1510_init, crc24rfc2440_init): Enable ARM PMULL
+ implementations if supported by HW features.
+ (crc32_write, crc24rfc2440_write) [USE_ARM_PMULL]: Use ARM PMULL
+ implementations if enabled.
+ * configure.ac: Add 'crc-armv8-ce.lo' and 'crc-armv8-aarch64-ce.lo'.
+
+2019-04-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ mpi: make stack unwinding work at i386 mpi functions.
+ + commit b878a986f3ab2c35aff89c7f66f137a91542ed5b
+ * mpi/i386/syntax.h: Include 'config.h'.
+ (CFI_STARTPROC, CFI_ENDPROC, CFI_ADJUST_CFA_OFFSET, CFI_REL_OFFSET)
+ (CFI_RESTORE, CFI_PUSH, CFI_POP): New.
+ * mpi/i386/mpih-add1.S: Add CFI directives.
+ * mpi/i386/mpih-lshift.S: Add CFI directives.
+ * mpi/i386/mpih-mul1.S: Add CFI directives.
+ * mpi/i386/mpih-mul2.S: Add CFI directives.
+ * mpi/i386/mpih-mul3.S: Add CFI directives.
+ * mpi/i386/mpih-rshift.S: Add CFI directives.
+ * mpi/i386/mpih-sub1.S: Add CFI directives.
+
+ hwf-x86: make stack unwinding work at i386 cpuid functions.
+ + commit 0bd18e8bf7d67072f8c77352140b4ed4cfde3c6c
+ * src/hwf-x86.c (FORCE_FUNC_FRAME_POINTER): New.
+ [__i386__] (is_cpuid_available): Force use of stack frame pointer as
+ inline assembly modifies stack register; Add 'memory' constraint for
+ inline assembly.
+ [__i386__] (get_cpuid): Avoid push/pop instruction when preserving
+ %ebx register over cpuid.
+
+ Limit and document Blowfish key lengths to 8-576 bits.
+ + commit 3546599e5578f89f9e77b08bf599f9c44b23da5f
+ * cipher/blowfish.c (BLOWFISH_KEY_MIN_BITS)
+ (BLOWFISH_KEY_MAX_BITS): New.
+ (do_bf_setkey): Check input key length to MIN_BITS and MAX_BITS.
+ * doc/gcrypt.texi: Update supported Blowfish key lengths.
+ * tests/basic.c (check_ecb_cipher): New, with Blowfish test vectors
+ for different key lengths.
+ (check_cipher_modes): Call 'check_ecb_cipher'.
+
+2019-04-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add CFI unwind assembly directives for AMD64 assembly.
+ + commit d11ae95d05dc39ec6b825d1109afadd964589880
+ * configure.ac (gcry_cv_gcc_asm_cfi_directives): New.
+ * cipher/asm-common-amd64.h (ADD_RIP, CFI_STARTPROC, CFI_ENDPROC)
+ (CFI_REMEMBER_STATE, CFI_RESTORE_STATE, CFI_ADJUST_CFA_OFFSET)
+ (CFI_REL_OFFSET, CFI_DEF_CFA_REGISTER, CFI_REGISTER, CFI_RESTORE)
+ (CFI_PUSH, CFI_POP, CFI_POP_TMP_REG, CFI_LEAVE, DW_REGNO)
+ (DW_SLEB128_7BIT, DW_SLEB128_28BIT, CFI_CFA_ON_STACK)
+ (CFI_REG_ON_STACK): New.
+ (ENTER_SYSV_FUNCPARAMS_0_4, EXIT_SYSV_FUNC): Add CFI directives.
+ * cipher/arcfour-amd64.S: Add CFI directives.
+ * cipher/blake2b-amd64-avx2.S: Add CFI directives.
+ * cipher/blake2s-amd64-avx.S: Add CFI directives.
+ * cipher/blowfish-amd64.S: Add CFI directives.
+ * cipher/camellia-aesni-avx-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/camellia-aesni-avx2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/cast5-amd64.S: Add CFI directives.
+ * cipher/chacha20-amd64-avx2.S: Add CFI directives.
+ * cipher/chacha20-amd64-ssse3.S: Add CFI directives.
+ * cipher/des-amd64.S: Add CFI directives.
+ * cipher/rijndael-amd64.S: Add CFI directives.
+ * cipher/rijndael-ssse3-amd64-asm.S: Add CFI directives.
+ * cipher/salsa20-amd64.S: Add CFI directives; Use 'asm-common-amd64.h'.
+ * cipher/serpent-avx2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/serpent-sse2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha1-avx-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha1-avx-bmi2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha1-avx2-bmi2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha1-ssse3-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha256-avx-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha256-avx2-bmi2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha256-ssse3-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha512-avx-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha512-avx2-bmi2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/sha512-ssse3-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/twofish-amd64.S: Add CFI directives.
+ * cipher/twofish-avx2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * cipher/whirlpool-sse2-amd64.S: Add CFI directives; Use
+ 'asm-common-amd64.h'.
+ * mpi/amd64/func_abi.h: Include 'config.h'.
+ (CFI_STARTPROC, CFI_ENDPROC, CFI_ADJUST_CFA_OFFSET, CFI_REL_OFFSET)
+ (CFI_RESTORE, CFI_PUSH, CFI_POP): New.
+ (FUNC_ENTRY, FUNC_EXIT): Add CFI directives.
+
+2019-04-15 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ twofish-amd64: do not use xchg instruction.
+ + commit 0903b215ef5a18332b740a24e6e2bfbed9e1d97b
+ * cipher/twofish-amd64.S (g1g2_3): Swap ab and cd registers using
+ 'movq' instructions instead of 'xchgq'.
+
+2019-04-09 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Use FreeBSD's elf_aux_info for detecting ARM HW features.
+ + commit 2ffc689d4757f31f1e2c4961b94b0b0c8dc302b7
+ * configure.ac: Add function check for 'elf_aux_info'.
+ * src/hwf-arm.c [HAVE_ELF_AUX_INFO]: Include 'sys/auxv.h'.
+ [HAVE_ELF_AUX_INFO && !HAVE_GETAUXVAL] (HAVE_GETAUXVAL)
+ (getauxval): New.
+
+2019-04-08 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Use getauxval system function for detecting ARM HW features.
+ + commit 6812a2c5bd2d9129bfdf34f3daf89cd8543ed8e5
+ * configure.ac: Add header check for 'sys/auxv.h'; Add function check
+ for 'getauxval'.
+ * src/hwf-arm.c [HAVE_SYS_AUXV_H && HAVE_GETAUXVAL]: Include
+ 'sys/auxv.h'.
+ (HAS_SYS_AT_HWCAP): Enable AT_HWCAP if have 'getauxval' in addition of
+ __linux__.
+ (AT_HWCAP, AT_HWCAP2, HWCAP_NEON, HWCAP2_AES, HWCAP2_PMULL)
+ (HWCAP2_SHA1, HWCAP2_SHA2, HWCAP_ASIMD, HWCAP_AES)
+ (HWCAP_PMULL, HWCAP_SHA1, HWCAP_SHA2): Define these macros only if not
+ already defined.
+ (get_hwcap) [HAVE_SYS_AUXV_H && HAVE_GETAUXVAL]: Use 'getauxval' to
+ fetch HW capability flags.
+
+ Disable SM3 in FIPS mode.
+ + commit 04a6c3c7482dd1ecb5113a049b1765b0d5f212fb
+ * cipher/sm3.h (_gcry_digest_spec_sm3): Set flags.fips to zero.
+
+2019-04-07 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Tune SHA-512/AVX2 and SHA-256/AVX2 implementations.
+ + commit 478581c5107ae75281c54e56cdcef5165f3155ca
+ * cipher/sha256-avx2-bmi2-amd64.S (ONE_ROUND_PART1, ONE_ROUND_PART2)
+ (ONE_ROUND): New round function.
+ (FOUR_ROUNDS_AND_SCHED, FOUR_ROUNDS): Use new round function.
+ (_gcry_sha256_transform_amd64_avx2): Exit early if number of blocks is
+ zero; Writing XFER to stack earlier and handle XREF writing in
+ FOUR_ROUNDS_AND_SCHED.
+ * cipher/sha512-avx2-bmi2-amd64.S (MASK_YMM_LO, MASK_YMM_LOx): New.
+ (ONE_ROUND_PART1, ONE_ROUND_PART2, ONE_ROUND): New round function.
+ (FOUR_ROUNDS_AND_SCHED, FOUR_ROUNDS): Use new round function.
+ (_gcry_sha512_transform_amd64_avx2): Writing XFER to stack earlier and
+ handle XREF writing in FOUR_ROUNDS_AND_SCHED.
+
+2019-04-05 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add SHA512/224 and SHA512/256 algorithms.
+ + commit a3683b6f623189a4b65bb584bb9e65e3ad7b3139
+ * cipher/mac-hmac.c (map_mac_algo_to_md): Add mapping for SHA512/224
+ and SHA512/256.
+ (_gcry_mac_type_spec_hmac_sha512_256)
+ (_gcry_mac_type_spec_hmac_sha512_224): New.
+ * cipher/mac-internal.h (_gcry_mac_type_spec_hmac_sha512_256)
+ (_gcry_mac_type_spec_hmac_sha512_224): New.
+ * cipher/mac.c (mac_list, mac_list_algo101): Add SHA512/224 and
+ SHA512/256.
+ * cipher/md.c (digest_list, digest_list_algo301)
+ (prepare_macpads): Ditto.
+ * cipher/sha512.c (run_selftests): Ditto.
+ (sha512_init_common): Move common initialization here.
+ (sha512_init, sha384_init): Use common initialization function.
+ (sha512_224_init, sha512_256_init, _gcry_sha512_224_hash_buffer)
+ (_gcry_sha512_224_hash_buffers, _gcry_sha512_256_hash_buffer)
+ (_gcry_sha512_256_hash_buffers, selftests_sha512_224)
+ (selftests_sha512_256, sha512_224_asn, oid_spec_sha512_224)
+ (_gcry_digest_spec_sha512_224, sha512_256_asn, oid_spec_sha512_256)
+ (_gcry_digest_spec_sha512_256): New.
+ * doc/gcrypt.texi: Add SHA512/224 and SHA512/256; Add missing
+ HMAC-BLAKE2s and HMAC-BLAKE2b.
+ * src/cipher.h (_gcry_digest_spec_sha512_224)
+ (_gcry_digest_spec_sha512_256): New.
+ * src/gcrypt.h.in (GCRY_MD_SHA512_256, GCRY_MD_SHA512_224): New.
+ (GCRY_MAC_HMAC_SHA512_256, GCRY_MAC_HMAC_SHA512_224): New.
+ * tests/basic.c (check_digests): Add SHA512/224 and SHA512/256
+ test vectors.
+
+ Remove extra buffer flush at begining of digest final functions.
+ + commit c6055aaccac86e1ca8a9d35c980d7abbacf2a9ff
+ * cipher/md2.c (md2_final): Remove _gcry_md_block_write flush call
+ from entry.
+ * cipher/md4.c (md4_final): Ditto.
+ * cipher/md5.c (md5_final): Ditto.
+ * cipher/rmd160.c (rmd160_final): Ditto.
+ * cipher/sha1.c (sha1_final): Ditto.
+ * cipher/sha256.c (sha256_final): Ditto.
+ * cipher/sha512.c (sha512_final): Ditto.
+ * cipher/sm3.c (sm3_final): Ditto.
+ * cipher/stribog.c (stribog_final): Ditto.
+ * cipher/tiger.c (tiger_final): Ditto.
+
+ Optimizations for digest final functions.
+ + commit e76cd0e2b1f6025c1319576a5848815d1d231aeb
+ * cipher/md4.c (md4_final): Avoid byte-by-byte buffer setting when
+ padding; Merge extra and last block processing.
+ * cipher/md5.c (md5_final): Ditto.
+ * cipher/rmd160.c (rmd160_final): Ditto.
+ * cipher/sha1.c (sha1_final): Ditto.
+ * cipher/sha256.c (sha256_final): Ditto.
+ * cipher/sm3.c (sm3_final): Ditto.
+ * cipher/tiger.c (tiger_final): Ditto.
+ * cipher/sha512.c (sha512_final): Avoid byte-by-byte buffer setting
+ when padding.
+ * cipher/stribog.c (stribog_final): Ditto.
+ * cipher/whirlpool.c (whirlpool_final): Ditto.
+
+ tests/basic: add hash test for small block sizes.
+ + commit c54b1c96c644c941f3eb3d2a09432b82f25b6ff1
+ * tests/basic.c (check_one_md): Compare hashing buffers sizes from 1 to
+ 129 as full buffer input and byte-by-byte input.
+
+ Burn stack in transform functions for SHA2 AMD64 implementations.
+ + commit 74ef3ecbf94e704975e238a99c0e0480cebf46ac
+ * cipher/sha256-avx-amd64.S: Burn stack inside transform functions.
+ * cipher/sha256-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha256-ssse3-amd64.S: Ditto.
+ * cipher/sha512-avx-amd64.S: Ditto.
+ * cipher/sha512-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha512-ssse3-amd64.S: Ditto.
+
+ Burn stack in transform functions for SHA1 AMD64 implementations.
+ + commit f3d4bd90662faaedd37ce0dae1f9e7f91748e91e
+ * cipher/sha1-avx-amd64.S: Burn stack inside transform functions.
+ * cipher/sha1-avx-bmi2-amd64.S: Ditto.
+ * cipher/sha1-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha1-ssse3-amd64.S: Ditto.
+
+ Add AVX2/BMI2 implementation of SHA1.
+ + commit b982900bfe6403e95a157271d8d811c9c573af9e
+ * cipher/Makefile.am: Add 'sha1-avx2-bmi2-amd64.S'.
+ * cipher/hash-common.h (MD_BLOCK_CTX_BUFFER_SIZE): New.
+ (gcry_md_block_ctx): Change buffer length to MD_BLOCK_CTX_BUFFER_SIZE.
+ * cipher/sha1-avx-amd64.S: Add missing .size for transform function.
+ * cipher/sha1-ssse3-amd64.S: Add missing .size for transform function.
+ * cipher/sha1-avx-bmi2-amd64.S: Add missing .size for transform
+ function; Tweak implementation for small ~1% speed increase.
+ * cipher/sha1-avx2-bmi2-amd64.S: New.
+ * cipher/sha1.c (USE_AVX2, _gcry_sha1_transform_amd64_avx2_bmi2)
+ (do_sha1_transform_amd64_avx2_bmi2): New.
+ (sha1_init) [USE_AVX2]: Enable AVX2 implementation if supported by
+ HW features.
+ (sha1_final): Merge processing of two last blocks when extra block is
+ needed.
+
+2019-03-31 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ blowfish: add three rounds parallel handling to generic C implementation
+ + commit ced7508c857c0cc37da2299a393e5b167dd28e54
+ * cipher/blowfish.c (BLOWFISH_ROUNDS): Remove.
+ [BLOWFISH_ROUNDS != 16] (function_F): Remove.
+ (F): Replace big-endian and little-endian version with single
+ endian-neutral version.
+ (R3, do_encrypt_3, do_decrypt_3): New.
+ (_gcry_blowfish_ctr_enc, _gcry_blowfish_cbc_dec)
+ (_gcry_blowfish_cfb_dec): Use new three block functions.
+
+ cast5: add three rounds parallel handling to generic C implementation.
+ + commit 4ec566b3689eff4a712eacfcbb4161eb243bb1df
+ * cipher/cast5.c (do_encrypt_block_3, do_decrypt_block_3): New.
+ (_gcry_cast5_ctr_enc, _gcry_cast5_cbc_dec, _gcry_cast5_cfb_dec): Use
+ new three block functions.
+
+ cast5: read Kr four blocks at time and shift for current round.
+ + commit 8a0e68be1020d0c359bf8191159ac1ebe32a5aa0
+ * cipher/cast5.c (do_encrypt_block, do_decrypt_block): Read Kr as
+ 32-bit words instead of bytes and shift value for each round.
+
+ Add helper function for adding value to cipher block.
+ + commit 0fe918fa897cca9e01cbdb80d14106cfe5af680e
+ * cipher/cipher-internal.h (cipher_block_add): New.
+ * cipher/blowfish.c (_gcry_blowfish_ctr_enc): Use new helper function
+ for CTR block increment.
+ * cipher/camellia-glue.c (_gcry_camellia_ctr_enc): Ditto.
+ * cipher/cast5.c (_gcry_cast5_ctr_enc): Ditto.
+ * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Ditto.
+ * cipher/des.c (_gcry_3des_ctr_enc): Ditto.
+ * cipher/rijndael.c (_gcry_aes_ctr_enc): Ditto.
+ * cipher/serpent.c (_gcry_serpent_ctr_enc): Ditto.
+ * cipher/twofish.c (_gcry_twofish_ctr_enc): Ditto.
+
+2019-03-28 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Optimize OCB set_key and set_nonce.
+ + commit efd700e31dc8e1e386d367d1b682000977e0c810
+ * cipher/cipher-ocb.c (double_block): Change to input/output
+ host-endian block instead of big-endian buffer.
+ (double_block_cpy): Remove.
+ (bit_copy): Use fixed length copy and 'u64' for calculations.
+ (ocb_get_L_big): Handle block endian conversions for double_block.
+ (_gcry_cipher_ocb_setkey): Handle block endian conversions for
+ double_block.
+ (_gcry_cipher_ocb_set_nonce): Set full length of 'ktop' to zero; Drop
+ length parameter for bit_copy.
+
+ AES-NI/OCB: Optimize last and first key XORing.
+ + commit eacbd59b1333b95858886999c8049e04bf72ad74
+ * cipher/rijndael-aesni.c (aesni_ocb_enc, aesni_ocb_dec)
+ [__x86_64__]: Reorder and mix first and last key XORing with OCB offset
+ XOR operations.
+
+ AES-NI/OCB: Perform checksumming inline with encryption.
+ + commit e924ce456d5728a81c148de4a6eb23373cb70ca0
+ * cipher/rijndael-aesni.c (aesni_ocb_enc): Remove call to
+ 'aesni_ocb_checksum', instead perform checksumming inline with offset
+ calculations.
+
+2019-03-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ AES-NI/OCB: Use stack for temporary storage.
+ + commit b82dbbedf027327e0b4444a01edb045f51c4152b
+ * cipher/rijndael-aesni.c (aesni_ocb_enc, aesni_ocb_dec): Use stack
+ allocated 'tmpbuf' instead of output buffer as temporary storage.
+
+2019-03-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ tests/basic: add large buffer testing for ciphers.
+ + commit cabeebfc1179c8f5982834a8cbce02c55b3468e2
+ * tests/basic.c (check_one_cipher_core): Allocate buffers from heap.
+ (check_one_cipher): Add testing with large buffer (~65 KiB) in addition
+ to medium size buffer (~2 KiB).
+
+ chacha20-poly1305: fix wrong en/decryption on large input buffers.
+ + commit 049376470b31832d3331fc0037d273b4147e9d38
+ * cipher/chacha20.c (_gcry_chacha20_poly1305_encrypt)
+ (_gcry_chacha20_poly1305_decrypt): Correctly use 'currlen' for chacha20
+ on the non-stitched code path.
+
+2019-03-24 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ doc: add mention about aligning data to cachelines for best performance.
+ + commit bb03edcbba95e06686188957a65c1967ee07cd6a
+ * doc/gcrypt.text: Add mention about aligning data to cachelines for
+ best performance.
+
+ random-drbg: do not use calloc for zero ctr.
+ + commit 5a20151213c2e496513c541c36e4ebd086b20be9
+ * random/random-drbg.c (DRBG_CTR_NULL_LEN): Move to 'constants'
+ section.
+ (drbg_state_s): Remove 'ctr_null' member.
+ (drbg_ctr_generate): Add 'drbg_ctr_null'.
+ (drbg_sym_fini, drbg_sym_init): Remove 'drbg->ctr_null' usage.
+
+2019-03-23 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add ARMv7/NEON accelerated GCM implementation.
+ + commit 2445cf7431fab921f6c1870da7084ee698992064
+ * cipher/Makefile.am: Add 'cipher-gcm-armv7-neon.S'.
+ * cipher/cipher-gcm-armv7-neon.S: New.
+ * cipher/cipher-gcm.c [GCM_USE_ARM_NEON] (_gcry_ghash_setup_armv7_neon)
+ (_gcry_ghash_armv7_neon, ghash_setup_armv7_neon)
+ (ghash_armv7_neon): New.
+ (setupM) [GCM_USE_ARM_NEON]: Use armv7/neon implementation if have
+ HWF_ARM_NEON.
+ * cipher/cipher-internal.h (GCM_USE_ARM_NEON): New.
+
+ Use memset instead of setting buffers byte by byte.
+ + commit 6f2391d2df029b0e1a4e5dde17c3d97cc594a1c7
+ * cipher/cipher-ccm.c (do_cbc_mac): Replace buffer setting loop with memset call.
+ * cipher/cipher-gcm.c (do_ghash_buf): Ditto.
+ * cipher/poly1305.c (poly1305_final): Ditto.
+
+ Use buf_cpy instead of copying buffers byte by byte.
+ + commit 4db6d8796c0d95ab89e9ad69336509b604b957cd
+ * cipher/bufhelp.h (buf_cpy): Skip memcpy if length is zero.
+ * cipher/cipher-ccm.c (do_cbc_mac): Replace buffer copy loops with buf_cpy call.
+ * cipher/cipher-cmac.c (_gcry_cmac_write): Ditto.
+ * cipher/cipher-ocb.c (_gcry_cipher_ocb_authenticate): Ditto.
+
+ Reduce overhead on generic hash write function.
+ + commit e76617cbab018dd8f41fd6b4ec6740b5303f7e13
+ * cipher/hash-common.c (_gcry_md_block_write): Remove recursive
+ function call; Use buf_cpy for copying buffers; Burn stack only once.
+
+ sha1-avx: use vmovdqa instead of movdqa.
+ + commit f8d14df1abd645c3279b14da43b4a7983d87f89f
+ * cipher/sha1-avx-amd64.S: Replace 'movdqa' with 'vmovdqa'.
+ * cipher/sha1-avx-bmi2-amd64.S: Replace 'movdqa' with 'vmovdqa'.
+
+ doc/gcrypt.texi: update HW feature list.
+ + commit 7abf65da84c7106250a5ed2de78b05610cf251f4
+ * doc/gcrypt.texi: Update FW feature list.
+
+2019-03-20 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+
+ ecc: Adjust debugging output.
+ + commit 54db6a4b44124ed7e95897174f32262482b4b0cb
+ * cipher/ecc.c (ecc_check_secret_key): Adjust debugging output to use
+ full column titles.
+
+2019-02-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ fips: Only test check_binary_integrity when fips_mode is enabled.
+ + commit ad133fc79757236359252e92244fe16e9adb45a3
+ * src/fips.c (_gcry_fips_run_selftests): Check the status of fips_mode
+ before calling check_binary_integrity.
+
+2019-02-07 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add 2-way path for SSSE3 version of ChaCha20.
+ + commit d455068988e5779b0200c51415ddab6b51e12dc4
+ * cipher/chacha20-amd64-ssse3.S (_gcry_chacha20_amd64_ssse3_blocks1)
+ (_gcry_chacha20_poly1305_amd64_ssse3_blocks1): Add 2-way code paths.
+ * cipher/chacha20.c (_gcry_chacha20_poly1305_encrypt): Add
+ preprosessing of 2 blocks with SSSE3.
+
+2019-01-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Do not precalculate OCB offset L0+L1+L0.
+ + commit afab94d222425ecb838eb56cb0723bdaf3e5de36
+ * cipher/cipher-internal.h (gcry_cipher_handle): Remove OCB L0L1L0.
+ * cipher/cipher-ocb.c (_gcry_cipher_ocb_setkey): Ditto.
+ * cipher/rijndael-aesni.c (aesni_ocb_enc, aesni_ocb_dec)
+ (_gcry_aes_aesni_ocb_auth): Replace L0L1L0 use with L1.
+
+ Calculate OCB L-tables when setting key instead of when setting nonce.
+ + commit c15409c49993166ab1325d45360b3a8fe72a5556
+ * cipher/cipher-internal.h (gcry_cipher_handle): Mark areas of
+ u_mode.ocb that are and are not cleared by gcry_cipher_reset.
+ (_gcry_cipher_ocb_setkey): New.
+ * cipher/cipher-ocb.c (_gcry_cipher_ocb_set_nonce): Split
+ L-table generation to ...
+ (_gcry_cipher_ocb_setkey): ... this new function.
+ * cipher/cipher.c (cipher_setkey): Add handling for OCB mode.
+ (cipher_reset): Do not clear L-values for OCB mode.
+
+ chacha20-amd64-avx2: optimize output xoring.
+ + commit 08e0650c21984bb9ddf5a1dabb1cc890fabf63ab
+ * cipher/chacha20-amd64-avx2.S (STACK_TMP2): Remove.
+ (transpose_16byte_2x2, xor_src_dst): New.
+ (BUF_XOR_256_TO_128): Remove.
+ (_gcry_chaha20_amd64_avx2_blocks8)
+ (_gcry_chacha20_poly1305_amd64_avx2_blocks8): Replace
+ BUF_XOR_256_TO_128 with transpose_16byte_2x2/xor_src_dst; Reduce stack
+ usage; Better interleave chacha20 state merging and output xoring.
+
+ tests/bench-slope: prevent auto-mhz detection getting stuck.
+ + commit 28614a77a28190ab902a2b98039de2cd0635c7c7
+ * cipher/bench-slope.c (bench_ghz, bench_ghz_diff): New static
+ variables.
+ (AUTO_GHZ_TARGET_DIFF): New macro.
+ (do_slope_benchmark): Reduce target auto-mhz accuracy after
+ repeated failures.
+ (bench_print_result_csv, bench_print_result_std): Print auto-ghz
+ different if 1 Mhz or more.
+ (do_slope_benchmark, bench_print_result_csv, bench_print_result_std)
+ (bench_print_result): Remove 'bench_ghz' parameter.
+ (cipher_bench_one, hash_bench_one, mac_bench_one)
+ (kdf_bench_one): Remove 'bench_ghz' variable.
+
+ tests/bench-slope: add missing cipher context reset.
+ + commit 546f13ae08918726791600cdd0d0be56cc52c790
+ * tests/bench-slope.c (bench_encrypt_do_bench)
+ (bench_decrypt_do_bench): Add call to 'gcry_cipher_reset'.
+
+ Add stitched ChaCha20-Poly1305 SSSE3 and AVX2 implementations.
+ + commit d6330dfb4b0e9fb3f8eef65ea13146060b804a97
+ * cipher/asm-poly1305-amd64.h: New.
+ * cipher/Makefile.am: Add 'asm-poly1305-amd64.h'.
+ * cipher/chacha20-amd64-avx2.S (QUATERROUND2): Add interleave
+ operators.
+ (_gcry_chacha20_poly1305_amd64_avx2_blocks8): New.
+ * cipher/chacha20-amd64-ssse3.S (QUATERROUND2): Add interleave
+ operators.
+ (_gcry_chacha20_poly1305_amd64_ssse3_blocks4)
+ (_gcry_chacha20_poly1305_amd64_ssse3_blocks1): New.
+ * cipher/chacha20.c (_gcry_chacha20_poly1305_amd64_ssse3_blocks4)
+ (_gcry_chacha20_poly1305_amd64_ssse3_blocks1)
+ (_gcry_chacha20_poly1305_amd64_avx2_blocks8): New prototypes.
+ (chacha20_encrypt_stream): Split tail to...
+ (do_chacha20_encrypt_stream_tail): ... new function.
+ (_gcry_chacha20_poly1305_encrypt)
+ (_gcry_chacha20_poly1305_decrypt): New.
+ * cipher/cipher-internal.h (_gcry_chacha20_poly1305_encrypt)
+ (_gcry_chacha20_poly1305_decrypt): New prototypes.
+ * cipher/cipher-poly1305.c (_gcry_cipher_poly1305_encrypt): Call
+ '_gcry_chacha20_poly1305_encrypt' if cipher is ChaCha20.
+ (_gcry_cipher_poly1305_decrypt): Call
+ '_gcry_chacha20_poly1305_decrypt' if cipher is ChaCha20.
+ * cipher/poly1305-internal.h (_gcry_cipher_poly1305_update_burn): New
+ prototype.
+ * cipher/poly1305.c (poly1305_blocks): Make static.
+ (_gcry_poly1305_update): Split main function body to ...
+ (_gcry_poly1305_update_burn): ... new function.
+
+ Add SSSE3 optimized non-parallel ChaCha20 function.
+ + commit 7d9b2f114f3edf4d13640616cf34c79364234781
+ * cipher/chacha20-amd64-ssse3.S (ROTATE_SHUF, ROTATE, WORD_SHUF)
+ (QUARTERROUND4, _gcry_chacha20_amd64_ssse3_blocks1): New.
+ * cipher/chacha20.c (_gcry_chacha20_amd64_ssse3_blocks1): New
+ prototype.
+ (chacha20_blocks): Rename to ...
+ (do_chacha20_blocks): ... this.
+ (chacha20_blocks): New.
+ (chacha20_encrypt_stream): Adjust for new chacha20_blocks function.
+
+ tests/basic: increase buffer size for check_one_cipher.
+ + commit 88e482d16ee80de41b6f133e77f0d15423fcd266
+ * tests/basic.c (check_one_cipher_core)
+ (check_one_cipher): Increase buffer from 1040 to 1904 bytes.
+
+ tests/basic: check AEAD tags in check_one_cipher test.
+ + commit eee1f152a5b3040f6723d287d1b01fb939be67b7
+ * tests/basic.c (get_algo_mode_taglen): New.
+ (check_one_cipher_core_reset): Check that tags are same with
+ AEAD modes.
+
+2019-01-15 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: With LD_LIBRARY_PATH defined, use --disable-new-dtags.
+ + commit e5c2f8a2cd2b89d90ea30de2dedb0e92498a5f70
+ * configure.ac (LDADD_FOR_TESTS_KLUDGE): New for --disable-new-dtags.
+ * tests/Makefile.am (LDADD, t_lock_LDADD): Use LDADD_FOR_TESTS_KLUDGE.
+
+ random: Fix previous commit for getentropy function.
+ + commit 17f246c7044ab9ed236f6ec73fc126654257f0f9
+ * random/rndlinux.c [__NR_getrandom] (_gcry_rndlinux_gather_random):
+ Check return value only for use of syscall.
+
+ random: Use getentropy when available for not GNU/Linux.
+ + commit 2677d7d482bf2d078c1dce64854747c5b148924b
+ * configure.ac: Detect getentropy.
+ * random/rndlinux.c [__linux__] (getentropy): Macro defined.
+ [HAVE_GETENTROPY] (_gcry_rndlinux_gather_random): Use getentropy.
+
+2019-01-14 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ camellia-aarch64: do not export look-up table globally.
+ + commit 09c27280cc09798d15369b3a143036b7ab5ddd69
+ * cipher/camellia-aarch64.S (_gcry_camellia_arm_tables): Remove
+ '.globl' export.
+
+2019-01-02 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Process CCM/EAX/GCM/Poly1305 AEAD cipher modes input in 24 KiB chucks.
+ + commit 3ee6588de8311b461ef8707c70ff86d2b252966d
+ * cipher/cipher-ccm.c (_gcry_cipher_ccm_encrypt)
+ (_gcry_cipher_ccm_decrypt): Process data in 24 KiB chunks.
+ * cipher/cipher-eax.c (_gcry_cipher_eax_encrypt)
+ (_gcry_cipher_eax_decrypt): Ditto.
+ * cipher/cipher-gcm.c (_gcry_cipher_gcm_encrypt)
+ (_gcry_cipher_gcm_decrypt): Ditto.
+ * cipher/cipher-poly1305.c (_gcry_cipher_poly1305_encrypt)
+ (_gcry_cipher_poly1305_decrypt): Ditto.
+
+ tests/benchmark: add Chacha20-Poly1305 benchmarking.
+ + commit 4871f11745f33c5c5051bfe6f325ac1c10764b04
+ * tests/benchmark.c (cipher_bench): Add Chacha20-Poly1305.
+
+ tests/benchmark: add --huge-buffers option for cipher tests.
+ + commit edde61f325e4b345f17c47369f3b6b1400656f04
+ * tests/benchmark.c (huge_buffers, cipher_encrypt, cipher_decrypt): New.
+ (cipher_bench): Add 'max_inlen' to modes structure; add huge buffers
+ mode selection.
+ (main): Add '--huge-buffers'.
+
+2018-12-19 NIIBE Yutaka <gniibe@fsij.org>
+
+ random: Add finalizer for rndjent.
+ + commit 3028a221d39c1b593ea0c1bcbfccd33959769692
+ * random/rand-internal.h (_gcry_rndjent_fini): New.
+ * random/rndjent.c (_gcry_rndjent_fini): New.
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Call the finalizer
+ when GCRYCTL_CLOSE_RANDOM_DEVICE.
+
+2018-12-12 Werner Koch <wk@gnupg.org>
+
+ secmem: Prepare for easier debugging.
+ + commit 876f7280e8604bc99ddda0526339ec5ec6b23c4b
+ * src/secmem.c (_gcry_secmem_dump_stats): Factor code out to ...
+ (secmem_dump_stats_internal): new.
+
+2018-12-01 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael-aesni: interleave last CTR encryption round with xoring.
+ + commit 66d2b7fc17258f1424f4ca4adb1096e48b818bd0
+ * cipher/rijndael-aesni.c (do_aesni_ctr_8): Interleave aesenclast
+ with input xoring.
+
+2018-11-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Use explicit_bzero for wipememory.
+ + commit 168668228c7c49e70612cb4d602d6d603a2add2c
+ * configure.ac (AC_CHECK_FUNCS): Check for 'explicit_bzero'.
+ * src/g10lib.h (wipememory2): Use _gcry_fast_wipememory if _SET is
+ zero.
+ (_gcry_fast_wipememory): New.
+ (_gcry_wipememory2): Rename to...
+ (_gcry_fast_wipememory2): ...this.
+ * src/misc.c (_gcry_wipememory): New.
+ (_gcry_wipememory2): Rename to...
+ (_gcry_fast_wipememory2): ...this.
+ (_gcry_fast_wipememory2) [HAVE_EXPLICIT_BZERO]: Use explicit_bzero if
+ SET is zero.
+ (_gcry_burn_stack): Use _gcry_fast_wipememory.
+
+ Add clang target pragma for mixed C/assembly x86-64 implementations.
+ + commit 9d9c4fd18b445ff414d11678285d54af3afdb222
+ * cipher/cipher-gcm-intel-pclmul.c: Add target 'no-sse' attribute
+ pragma for clang.
+ * cipher/crc-intel-pclmul.c: Ditto.
+ * cipher/rijndael-aesni.c: Ditto.
+ * cipher/rijndael-ssse3-amd64.c: Ditto.
+ * cipher/sha1-intel-shaext.c: Ditto.
+ * cipher/sha256-intel-shaext.c: Ditto.
+
+ Optimizations for AES-NI OCB.
+ + commit b42de67f34871a2520cfe370af513f2aab6e4f75
+ * cipher/cipher-internal.h (gcry_cipher_handle): New pre-computed OCB
+ values L0L1 and L0L1L0; Swap dimensions for OCB L table.
+ * cipher/cipher-ocb.c (_gcry_cipher_ocb_set_nonce): Setup L0L1 and
+ L0L1L0 values.
+ (ocb_crypt): Process input in 24KiB chunks for better cache locality
+ for checksumming.
+ * cipher/rijndael-aesni.c (ALWAYS_INLINE): New macro for always
+ inlining functions, change all functions with 'inline' to use
+ ALWAYS_INLINE.
+ (NO_INLINE): New macro.
+ (aesni_prepare_2_6_variable, aesni_prepare_7_15_variable): Rename to...
+ (aesni_prepare_2_7_variable, aesni_prepare_8_15_variable): ...these and
+ adjust accordingly (xmm7 moved from *_7_15 to *_2_7).
+ (aesni_prepare_2_6, aesni_prepare_7_15): Rename to...
+ (aesni_prepare_2_7, aesni_prepare_8_15): ...these and adjust
+ accordingly.
+ (aesni_cleanup_2_6, aesni_cleanup_7_15): Rename to...
+ (aesni_cleanup_2_7, aesni_cleanup_8_15): ...these and adjust
+ accordingly.
+ (aesni_ocb_checksum): New.
+ (aesni_ocb_enc, aesni_ocb_dec): Calculate OCB offsets in parallel
+ with help of pre-computed offsets L0+L1 ja L0+L1+L0; Do checksum
+ calculation as separate pass instead of inline; Use NO_INLINE.
+ (_gcry_aes_aesni_ocb_auth): Calculate OCB offsets in parallel
+ with help of pre-computed offsets L0+L1 ja L0+L1+L0.
+ * cipher/rijndael-internal.h (RIJNDAEL_context_s) [USE_AESNI]: Add
+ 'use_avx2' and 'use_avx'.
+ * cipher/rijndael.c (do_setkey) [USE_AESNI]: Set 'use_avx2' if
+ Intel AVX2 HW feature is available and 'use_avx' if Intel AVX HW
+ feature is available.
+ * tests/basic.c (do_check_ocb_cipher): New test vector; increase
+ size of temporary buffers for new test vector.
+ (check_ocb_cipher_largebuf_split): Make test plaintext non-uniform
+ for better checksum testing.
+ (check_ocb_cipher_checksum): New.
+ (check_ocb_cipher_largebuf): Call check_ocb_cipher_checksum.
+ (check_ocb_cipher): New expected tags for check_ocb_cipher_largebuf
+ test runs.
+
+2018-11-19 Andreas Metzler <ametzler@bebt.de>
+
+ doc: Fix library initialization examples.
+ + commit af0bbdb9019e0b4a72e87e8b1b4a55506d349834
+
+
+2018-11-14 Werner Koch <wk@gnupg.org>
+
+ random: Initialize variable as requested by valgrind.
+ + commit aa686dfc9b563ff79c01d2f8560b88f69c42ecba
+ random/jitterentropy-base.c: Init.
+
+2018-11-13 NIIBE Yutaka <gniibe@fsij.org>
+
+ libgcrypt.m4: Prefer gpgrt-config to SYSROOT support.
+ + commit 852245390ef7fd8ca9e36010886a4cf42cf710bf
+ * libgcrypt.m4: Move SYSROOT support after check of GPGRT_CONFIG.
+
+ build: Update autogen.rc.
+ + commit bea193446351c24b10a4342466978d57bd53f599
+ * autogen.rc: Remove obsolete --with-gpg-error-prefix option.
+
+2018-11-07 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix 'variable may be used uninitialized' warning for CTR mode.
+ + commit 3f76319803a4abcd33fa29a0ac39f8ed9d646226
+ * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Set N to BLOCKSIZE
+ before counter loop.
+
+2018-11-06 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix inlining of ocb_get_l for x86 AES implementations.
+ + commit 9d6431604b5ee21572c1c2cfa8376e6d81162cbb
+ * cipher/rijndael-aesni.c (aes_ocb_get_l): New.
+ (aesni_ocb_enc, aesni_ocb_dec, _gcry_aes_aesni_ocb_auth): Use
+ 'aes_ocb_get_l'.
+ * cipher/rijndael-ssse3-amd4.c (aes_ocb_get_l): New.
+ (ssse3_ocb_enc, ssse3_ocb_dec, _gcry_aes_ssse3_ocb_auth): Use
+ 'aes_ocb_get_l'.
+
+2018-11-05 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ stdmem: free: only call _gcry_secmem_free if needed.
+ + commit 23f56d3359ca7d152aa87874ddd6305171a91408
+ * src/stdmem.c (_gcry_private_free): Check if memory is secure before
+ calling _gcry_secmem_free to avoid unnecessarily taking secmem lock.
+
+ secmem: fix potential memory visibility issue.
+ + commit d6c6680ca31c05bafbb8becda56da051346eceb3
+ * configure.ac (gcry_cv_have_sync_synchronize): New check.
+ * src/secmem.c (pooldesc_s): Make next pointer volatile.
+ (memory_barrier): New.
+ (_gcry_secmem_malloc_internal): Insert memory barrier between
+ pool->next and mainpool.next assigments.
+ (_gcry_private_is_secure): Update comments.
+
+ wipememory: use memset for non-constant length or large buffer wipes.
+ + commit 4faeaa1cbd235a2560fa04a8ac3766a07029acd8
+ * src/g10lib.h (CONSTANT_P): New.
+ (_gcry_wipememory2): New prototype.
+ (wipememory2): Use _gcry_wipememory2 if _len not constant expression or
+ lenght is larger than 64 bytes.
+ (FASTWIPE_T, FASTWIPE_MULT, fast_wipememory2_unaligned_head): Remove.
+ (fast_wipememory2): Always handle buffer as unaligned.
+ * src/misc.c (__gcry_burn_stack): Move memset_ptr variable to...
+ (memset_ptr): ... here. New.
+ (_gcry_wipememory2): New.
+
+ Change buf_cpy and buf_xor* functions to use buf_put/buf_get helpers.
+ + commit 0068d41d9304ebcdb2caba1fa8848925e2bfaac7
+ * cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS)
+ (bufhelp_int_s, buf_xor_1): Remove.
+ (buf_cpy, buf_xor, buf_xor_2dst, buf_xor_n_copy_2): Use
+ buf_put/buf_get helpers to handle unaligned memory accesses.
+
+ rijndael: fix unused parameter warning.
+ + commit 30e783ec487466132324673f197d36b85a91b060
+ * cipher/rijndael.c (do_setkey): Silence unused 'hd' warning.
+
+ mpi/longlong.h: enable inline assembly for powerpc64.
+ + commit ec49013d23d9a7b874c42d77ceb08bd313ba69e1
+ * mpi/longlong.h [__powerpc__ && W_TYPE_SIZE == 64]: Remove '#if 0'.
+
+ Change remaining users of _gcry_fips_mode to use fips_mode.
+ + commit 2aece89d3967e692743541cea857f2e4771b0b62
+ * src/fips.c (_gcry_fips_mode): Remove.
+ (_gcry_enforced_fips_mode, _gcry_inactivate_fips_mode)
+ (_gcry_is_fips_mode_inactive): Use fips_mode.
+ * src/g10lib.h (_gcry_fips_mode): Remove.
+
+2018-11-02 NIIBE Yutaka <gniibe@fsij.org>
+
+ aarch64: mpi: Distribute the header file as a part of source.
+ + commit a2e0cb1542818ad8a71de34ccbf191adab0a0b86
+ * mpi/Makefile.am (EXTRA_libmpi_la_SOURCES): Add asm-common-aarch64.h.
+
+ build: Fix GCRYPT_HWF_MODULES.
+ + commit f7395338d71d4d82180a11707fd6e77787162e24
+ * configure.ac (GCRYPT_HWF_MODULES): Add libgcrypt_la- prefix.
+
+ build: Update gpg-error.m4 and libgcrypt.m4.
+ + commit f46286851158878d5041ac5381b2807ecec541eb
+ * m4/gpg-error.m4: Update to 2018-11-02.
+ * src/libgrypt.m4: Add AC_MSG_NOTICE.
+ Bump the version date.
+
+2018-10-29 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Update gpg-error.m4 and ksba.m4.
+ + commit 4a4d4a284ca996df874e2534f8529c1611289943
+ * m4/gpg-error.m4: Update to 2018-10-29.
+ * src/libgrypt.m4: Follow the change of gpgrt-config.
+ Bump the version date.
+
+2018-10-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix missing global initialization in fips_is_operational.
+ + commit 6e669e09603e5a98b59dcf35f77f346db6c81eac
+ * src/g10lib.h (_gcry_global_any_init_done): New extern.
+ (fips_is_operational): Check for _gcry_global_any_init_done and call
+ _gcry_global_is_operational.
+ * src/global.c (any_init_done): Rename to ...
+ (_gcry_global_any_init_done): ... this and make externally available.
+
+2018-10-26 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+
+ random: use getrandom() on Linux where available.
+ + commit 7e662680c170968661ee0105d132813f8281d229
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): use the
+ getrandom() syscall on Linux if it exists, regardless of what kind of
+ entropy was requested.
+
+2018-10-26 Werner Koch <wk@gnupg.org>
+
+ random: Make sure to re-open /dev/random after a fork.
+ + commit 319f55e6e5793c59f1ba4cfe481b562bca42194d
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Detect fork and
+ re-open devices.
+
+ primes: Avoid leaking bits of the prime test to pageable memory.
+ + commit 2e2e68ad4874a4678cfbe452b70ae987e0402eca
+ * cipher/primegen.c (gen_prime): Allocate MODS in secure memory.
+
+2018-10-26 NIIBE Yutaka <gniibe@fsij.org>
+
+ libgcrypt.m4: Better compatibility support.
+ + commit a755bd0ea09af2ae5a66e3f5aeb8707673c687cf
+ * src/gpg-error.m4: Update.
+ * src/libgcrypt.m4: Don't assume libgcrypt-config is newer.
+
+ build: Fix libgcrypt.m4.
+ + commit 630ece1b7e0a94442bca91d8e96d9b1d4cd3ec66
+ * src/libgcrypt.m4: Use AC_PATH_PROG to detect libgcrypt-config.
+
+ build: Relax build requirements.
+ + commit 8e5641ed65f86783542d5caccdeeee42eeb9457c
+ * m4/gpg-error.m4: Update from libgpg-error 1.33.
+ * src/libgcrypt.m4: Don't require AM_PATH_GPG_ERROR. Use GPGRT_CONFIG
+ instead of libgcrypt-config when it is confirmed that it is available
+ and working well.
+ * configure.ac (AM_PATH_GPG_ERROR): No requirement for newer version
+ (It was because of new gpgrt-config which supports *.pc files).
+
+2018-10-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Require libgpg-error >= 1.33.
+ + commit b376dc2abbb208b10bbc76998ff39adb2f301905
+ * configure.ac (NEED_GPG_ERROR_VERSION): Require 1.33.
+ * m4/gpg-error.m4: Update from libgpg-error 1.33.
+ * src/libgcrypt.m4: Bump version date.
+ Use --variable option.
+
+2018-10-24 Werner Koch <wk@gnupg.org>
+
+ build: Add release make target.
+ + commit 03bb25ee7ed6f1076bf788ab981ca68672880daa
+ * Makefile.am (release, sign-release): New targets.
+
+ build: Make distcheck work again.
+ + commit b0ad66e48c46b79af69349606e276cf0a6b9a020
+ * cipher/Makefile.am: Prettified source file lists.
+ EXTRA_libcipher_la_SOURCES): Add missing asm-common-aarch64.h.
+
+ Fix memory leak in secmem in out of core conditions.
+ + commit f74687fd43f5772a372f54031d5a9527597f4ce4
+ * src/secmem.c (_gcry_secmem_malloc_internal): Release pool descriptor
+ if the pool could not be allocated.
+
+ ecc: Fix memory leak in the error case of ecc_encrypt_raw.
+ + commit e57e75ea517f32109b508113f18298fc69fd1192
+ * cipher/ecc.c (ecc_encrypt_raw): Add proper error cleanup in the main
+ block.
+
+ ecc: Fix possible memory leakage in parameter check of eddsa.
+ + commit 149ceb3cae03d0385341d32430aa5ae57de90007
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_verify): Fix mem leak.
+
+2018-10-24 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Fix libgcrypt.pc.
+ + commit 0e071372fc0e6fed4a449955ed0789803ba5e709
+ * src/libgcrypt.pc.in: Fix typo.
+
+ build: Compatibility to pkg-config.
+ + commit c60eabb11435665fa84a3a82b2a15f48870cc4d7
+ * src/libgcrypt-config.in: Support --variable and --modversion.
+
+ build: Make libgcrypt.m4 use gpg-error-config.
+ + commit 7da887d69d72ea0ea0d106054c48a8c03e242a18
+ * src/libgcrypt.m4: Use gpg-error-config.
+
+ build: Provide libgcrypt.pc, generated by configure.
+ + commit 97194b422bc89a6137f4e218d4cdee118c63e96e
+ * configure.ac: Generate src/libgcrypt.pc.
+ * src/Makefile.am (pkgconfigdir, pkgconfig_DATA): New.
+ (EXTRA_DIST): Add libgcrypt.pc.in.
+ * src/libgcrypt-config.in: Use @PACKAGE_VERSION@.
+ * src/libgcrypt.pc.in: New.
+
+ build: Update gpg-error.m4 from libgpg-error.
+ + commit 5b1febb5e40d92072bef425bd9e63f7a07edd57e
+ * m4/gpg-error.m4: Update from libgpg-error 1.33.
+
+ build: Don't default to underscore=yes for cross-build.
+ + commit 0f4545b441b6fbdd6e9c4e95f5f2a367483e78ad
+ * acinclude.m4: Don't set ac_cv_sys_symbol_underscore
+ for cross build.
+
+2018-10-23 Werner Koch <wk@gnupg.org>
+
+ ecc: Fix potential unintended freeing of an internal param.
+ + commit e2da4e8dee4b371804f3b2659b53431fb6380d93
+ * cipher/ecc-curves.c (_gcry_ecc_get_mpi): Fix c+p error
+
+ sexp: Fix uninitialized use of a var in the error case.
+ + commit 9f2c7ec4d8b07e82663ad084c90c016d3c3b80c2
+ * src/sexp.c (_gcry_sexp_vextract_param): Initialize L1.
+
+2018-10-16 NIIBE Yutaka <gniibe@fsij.org>
+
+ build: Let configure create the VERSION file.
+ + commit 0f2c6ce2c9504c6df435463243edaa669e57b109
+ * autogen.sh: Update from libgpg-error.
+ * configure.ac: Use mym4_versoin to create VERSION file.
+ * Makefile.am (dist-hook): Do not create VERSION file.
+ (EXTRA_DIST): Add VERSION.
+
+2018-07-21 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add size optimized cipher block copy and xor functions.
+ + commit 86e5e06a97ae13b8bbf6923ecc76e02b9c429b46
+ * cipher/bufhelp.h (buf_get_he32, buf_put_he32, buf_get_he64)
+ (buf_put_he64): New.
+ * cipher/cipher-internal.h (cipher_block_cpy, cipher_block_xor)
+ (cipher_block_xor_1, cipher_block_xor_2dst, cipher_block_xor_n_copy_2)
+ (cipher_block_xor_n_copy): New.
+ * cipher/cipher-gcm-intel-pclmul.c
+ (_gcry_ghash_setup_intel_pclmul): Use assembly for swapping endianness
+ instead of buf_get_be64 and buf_cpy.
+ * cipher/blowfish.c: Use new cipher_block_* functions for cipher block
+ sized buf_cpy/xor* operations.
+ * cipher/camellia-glue.c: Ditto.
+ * cipher/cast5.c: Ditto.
+ * cipher/cipher-aeswrap.c: Ditto.
+ * cipher/cipher-cbc.c: Ditto.
+ * cipher/cipher-ccm.c: Ditto.
+ * cipher/cipher-cfb.c: Ditto.
+ * cipher/cipher-cmac.c: Ditto.
+ * cipher/cipher-ctr.c: Ditto.
+ * cipher/cipher-eax.c: Ditto.
+ * cipher/cipher-gcm.c: Ditto.
+ * cipher/cipher-ocb.c: Ditto.
+ * cipher/cipher-ofb.c: Ditto.
+ * cipher/cipher-xts.c: Ditto.
+ * cipher/des.c: Ditto.
+ * cipher/rijndael.c: Ditto.
+ * cipher/serpent.c: Ditto.
+ * cipher/twofish.c: Ditto.
+
+2018-07-04 NIIBE Yutaka <gniibe@fsij.org>
+
+ RFC-8439 was published.
+ + commit 9660c3fafd732b1857bb2697c6f43aed077b9ad6
+ * cipher/cipher-poly1305.c: Update RFC reference.
+
+2018-06-19 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Clean-up implementation selection for SHA1 and SHA2.
+ + commit 8a44c55d2fb758f726b8b436aa5c0b88a6c6f112
+ * cipher/sha1.c (ASM_EXTRA_STACK): Increase by sizeof(void*)*4.
+ (do_sha1_transform_amd64_ssse3, do_sha1_transform_amd64_avx)
+ (do_sha1_transform_amd64_avx_bmi2, do_sha1_transform_intel_shaext)
+ (do_sha1_transform_armv7_neon, do_sha1_transform_armv8_ce): New.
+ (transform_blk, transform): Merge to ...
+ (do_transform_generic): ... this and remove calls to assembly
+ implementations.
+ (sha1_init): Select hd->bctx.bwrite based on HW features.
+ (_gcry_sha1_mixblock, sha1_final): Call hd->bctx.bwrite instead of
+ transform.
+ * cipher/sha1.h (SHA1_CONTEXT): Remove implementation selection bits.
+ * cipher/sha256.h (SHA256_CONTEXT): Remove implementation selection
+ bits.
+ (ASM_EXTRA_STACK): Increase by sizeof(void*)*4.
+ (do_sha256_transform_amd64_ssse3, do_sha256_transform_amd64_avx)
+ (do_sha256_transform_amd64_avx2, do_sha256_transform_intel_shaext)
+ (do_sha256_transform_armv8_ce): New.
+ (transform_blk, transform): Merge to ...
+ (do_transform_generic): ... this and remove calls to assembly
+ implementations.
+ (sha256_init, sha224_init): Select hd->bctx.bwrite based on HW
+ features.
+ (sha256_final): Call hd->bctx.bwrite instead of transform.
+ * cipher/sha512-armv7-neon.S
+ (_gcry_sha512_transform_armv7_neon): Return zero.
+ * cipher/sha512.h (SHA512_CONTEXT): Remove implementation selection
+ bits.
+ (ASM_EXTRA_STACK): Increase by sizeof(void*)*4.
+ (do_sha512_transform_armv7_neon, do_sha512_transform_amd64_ssse3)
+ (do_sha512_transform_amd64_avx, do_sha512_transform_amd64_avx2): New.
+ [USE_ARM_ASM] (do_transform_generic): New.
+ (transform_blk, transform): Merge to ...
+ [!USE_ARM_ASM] (do_transform_generic): ... this and remove calls to
+ assembly implementations.
+ (sha512_init, sha384_init): Select hd->bctx.bwrite based on HW
+ features.
+ (sha512_final): Call hd->bctx.bwrite instead of transform.
+
+ Add hash_buffer and hash_buffers for SHA-224, SHA-385, SHA3 and BLAKE2.
+ + commit 59c4e344eec61cff45185e1caea6815b3266a0f8
+ * cipher/blake2.c (DEFINE_BLAKE2_VARIANT): Add hash_buffer and
+ hash_buffers functions for BLAKE2 variants.
+ * cipher/keccak.c (_gcry_sha3_hash_buffer, _gcry_sha3_hash_buffers)
+ (_gcry_sha3_224_hash_buffer, _gcry_sha3_224_hash_buffers)
+ (_gcry_sha3_256_hash_buffer, _gcry_sha3_256_hash_buffers)
+ (_gcry_sha3_384_hash_buffer, _gcry_sha3_384_hash_buffers)
+ (_gcry_sha3_512_hash_buffer, _gcry_sha3_512_hash_buffers): New.
+ * cipher/sha256.c (_gcry_sha224_hash_buffer)
+ (_gcry_sha224_hash_buffers): New.
+ * cipher/sha512.c (_gcry_sha384_hash_buffer)
+ (_gcry_sha384_hash_buffers): New.
+
+ Add hash_buffer and hash_buffers pointers to message digest spec.
+ + commit b136703ea0ddbd9fec6dfd1f8dfda8373653ba39
+ * src/cipher-proto.h (gcry_md_hash_buffer_t)
+ (gcry_md_hash_buffers_t): New.
+ (gcry_md_spec): Add hash_buffer and hash_buffers.
+ * cipher/md.c (_gcry_md_hash_buffer, _gcry_md_hash_buffers): Use
+ hash_buffer/hash_buffers from MD spec instead of hard-coding supported
+ algorithms.
+ * cipher/blake2.c: Add NULL to MD spec hash_buffer and hash_buffers
+ pointers.
+ * cipher/crc.c: Ditto.
+ * cipher/gostr3411-94.c: Ditto.
+ * cipher/keccak.c: Ditto.
+ * cipher/md2.c: Ditto.
+ * cipher/md4.c: Ditto.
+ * cipher/md5.c: Ditto.
+ * cipher/stribog.c: Ditto.
+ * cipher/tiger.c: Ditto.
+ * cipher/whirlpool.c: Ditto.
+ * cipher/rmd160.c (_gcry_rmd160_hash_buffers): New.
+ (_gcry_digest_spec_rmd160): Add hash_buffer and hash_buffers functions.
+ * cipher/sha1.c (_gcry_digest_spec_sha1): Add hash_buffer and
+ hash_buffers functions.
+ * cipher/sha256.c (_gcry_digest_spec_sha256): Add hash_buffer and
+ hash_buffers functions.
+ (_gcry_digest_spec_sha224): Add NULL pointers for hash_buffer and
+ hash_buffers.
+ * cipher/sha512.c (_gcry_digest_spec_sha1): Add hash_buffer and
+ hash_buffers functions.
+ (_gcry_digest_spec_sha384): Add NULL pointers for hash_buffer and
+ hash_buffers.
+ * cipher/sm3.c (_gcry_digest_spec_sha1): Add hash_buffer and
+ hash_buffers functions.
+
+ AES: setup cipher object bulk routines with optimized versions.
+ + commit a15c1def7e0f170f6663635db84fecab1cbfcca7
+ * cipher/rijndael-aesni.c
+ (_gcry_aes_aesni_prepare_decryption): Rename...
+ (do_aesni_prepare_decryption): .. to this.
+ (_gcry_aes_aesni_prepare_decryption): New.
+ (_gcry_aes_aesni_cfb_enc, _gcry_aes_aesni_cbc_enc)
+ (_gcry_aes_aesni_ctr_enc, _gcry_aes_aesni_cfb_dec)
+ (_gcry_aes_aesni_cbc_dec): Reorder parameters to match bulk
+ operations.
+ (_gcry_aes_aesni_cbc_dec, aesni_ocb_dec)
+ (_gcry_aes_aesni_xts_dec): Check and prepare decryption.
+ (_gcry_aes_aesni_ocb_crypt, _gcry_aes_aesni_ocb_auth): Change return
+ type to size_t.
+ * cipher/rijndael-armv8-ce.c
+ (_gcry_aes_armv8_ce_cfb_enc, _gcry_aes_armv8_ce_cbc_enc)
+ (_gcry_aes_armv8_ce_ctr_enc, _gcry_aes_armv8_ce_cfb_dec)
+ (_gcry_aes_armv8_ce_cbc_dec): Reorder parameters to match bulk
+ operations.
+ (_gcry_aes_armv8_ce_cbc_dec, _gcry_aes_armv8_ce_ocb_crypt)
+ (_gcry_aes_armv8_ce_xts_dec): Check and prepare decryption.
+ (_gcry_aes_armv8_ce_ocb_crypt, _gcry_aes_armv8_ce_ocb_auth): Change
+ return type to size_t.
+ * cipher/rijndael-ssse3-amd64.c
+ (_gcry_ssse3_prepare_decryption): Rename...
+ (do_ssse3_prepare_decryption): .. to this.
+ (_gcry_ssse3_prepare_decryption): New.
+ (_gcry_aes_ssse3_cfb_enc, _gcry_aes_ssse3_cbc_enc)
+ (_gcry_aes_ssse3_ctr_enc, _gcry_aes_ssse3_cfb_dec)
+ (_gcry_aes_ssse3_cbc_dec): Reorder parameters to match bulk
+ operations.
+ (_gcry_aes_ssse3_cbc_dec, ssse3_ocb_dec): Check and prepare decryption.
+ (_gcry_aes_ssse3_ocb_crypt, _gcry_aes_ssse3_ocb_auth): Change return
+ type to size_t.
+ * cipher/rijndael.c
+ (_gcry_aes_aesni_cfb_enc, _gcry_aes_aesni_cbc_enc)
+ (_gcry_aes_aesni_ctr_enc, _gcry_aes_aesni_cfb_dec)
+ (_gcry_aes_aesni_cbc_dec, _gcry_aes_aesni_ocb_crypt)
+ (_gcry_aes_aesni_ocb_auth, _gcry_aes_aesni_xts_crypt)
+ (_gcry_aes_ssse3_cfb_enc, _gcry_aes_ssse3_cbc_enc)
+ (_gcry_aes_ssse3_ctr_enc, _gcry_aes_ssse3_cfb_dec)
+ (_gcry_aes_ssse3_cbc_dec, _gcry_aes_ssse3_ocb_crypt)
+ (_gcry_aes_ssse3_ocb_auth, _gcry_aes_ssse3_xts_crypt)
+ (_gcry_aes_armv8_ce_cfb_enc, _gcry_aes_armv8_ce_cbc_enc)
+ (_gcry_aes_armv8_ce_ctr_enc, _gcry_aes_armv8_ce_cfb_dec)
+ (_gcry_aes_armv8_ce_cbc_dec, _gcry_aes_armv8_ce_ocb_crypt)
+ (_gcry_aes_armv8_ce_ocb_auth, _gcry_aes_armv8_ce_xts_crypt): Change
+ prototypes to match bulk operations.
+ (do_setkey): Setup bulk operations with optimized implementations.
+ (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc, _gcry_aes_ctr_enc)
+ (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec, _gcry_aes_ocb_crypt)
+ (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth, _gcry_aes_xts_crypt): Update
+ usage to match new prototypes, avoid prefetch and decryption
+ preparation on optimized code paths.
+
+ Pass cipher object pointer to setkey functions.
+ + commit ca21a24808efa5d562ac91f683504ae0d6dfa69f
+ * cipher/cipher.c (cipher_setkey): Pass cipher object pointer to
+ cipher's setkey function.
+ * cipher/arcfour.c: Add gcry_cipher_hd_t parameter for setkey
+ functions and update selftests to pass NULL pointer.
+ * cipher/blowfish.c: Ditto.
+ * cipher/camellia-glue.c: Ditto.
+ * cipher/cast5.c: Ditto.
+ * cipher/chacha20.c: Ditto.
+ * cipher/cipher-selftest.c: Ditto.
+ * cipher/des.c: Ditto.
+ * cipher/gost28147.c: Ditto.
+ * cipher/idea.c: Ditto.
+ * cipher/rfc2268.c: Ditto.
+ * cipher/rijndael.c: Ditto.
+ * cipher/salsa20.c: Ditto.
+ * cipher/seed.c: Ditto.
+ * cipher/serpent.c: Ditto.
+ * cipher/twofish.c: Ditto.
+ * src/cipher-proto.h: Ditto.
+
+ Add fast path for _gcry_fips_is_operational.
+ + commit b6e6ace324440f564df664e27f8276ef01f76795
+ * src/fips.c (no_fips_mode_required): Rename to...
+ (_gcry_no_fips_mode_required): ...this and make externally available.
+ * src/g10lib.h (_gcry_no_fips_mode_required): New extern.
+ (fips_mode): Inline _gcry_fips_mode to macro, use
+ _gcry_no_fips_mode_required directly.
+ (fips_is_operational): Inline fips_mode check from
+ _gcry_fips_in_operational.
+
+ Access cipher mode routines through routine pointers.
+ + commit 233e2049a2cc1c1110f541b6a7ef145a737e2c65
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add function pointers
+ for mode operations.
+ (_gcry_cipher_xts_crypt): Remove.
+ (_gcry_cipher_xts_encrypt, _gcry_cipher_xts_decrypt): New.
+ * cipher/cipher-xts.c (_gcry_cipher_xts_encrypt)
+ (_gcry_cipher_xts_decrypt): New.
+ * cipher/cipher.c (_gcry_cipher_setup_mode_ops): New.
+ (_gcry_cipher_open_internal): Setup mode routines.
+ (cipher_encrypt, cipher_decrypt): Remove.
+ (do_stream_encrypt, do_stream_decrypt, do_encrypt_none_unknown)
+ (do_decrypt_none_unknown): New.
+ (_gcry_cipher_encrypt, _gcry_cipher_decrypt, _gcry_cipher_setiv)
+ (_gcry_cipher_authenticate, _gcry_cipher_gettag)
+ (_gcry_cipher_checktag): Adapted to use mode routines through pointers.
+
+ Add separate handlers for CBC-CTS variant.
+ + commit 87d8caa47e00f1b1cea968fe38cf30c0ccc9749c
+ * cipher/cipher-cbc.c (cbc_encrypt_inner, cbc_decrypt_inner)
+ (_gcry_cipher_cbc_cts_encrypt, _gcry_cipher_cbc_cts_decrypt): New.
+ (_gcry_cipher_cbc_encrypt, _gcry_cipher_cbc_decrypt): Remove CTS
+ handling.
+ * cipher/cipher-internal.h (_gcry_cipher_cbc_cts_encrypt)
+ (_gcry_cipher_cbc_cts_decrypt): New.
+ * cipher/cipher.c (cipher_encrypt, cipher_decrypt): Call CBC-CTS
+ handler if CBC-CTS flag is set.
+
+ Avoid division by spec->blocksize in cipher mode handlers.
+ + commit f5168091c1930e948af8f25da11cad5dfa62c7ba
+ * cipher/cipher-internal.h (_gcry_blocksize_shift): New.
+ * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
+ (_gcry_cipherp_cbc_decrypt): Use bit-level operations instead of
+ division to get number of blocks and check input length against
+ blocksize.
+ * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
+ (_gcry_cipher_cfb_decrypt): Ditto.
+ * cipher/cipher-cmac.c (_gcry_cmac_write): Ditto.
+ * cipher/cipher-ctr.c (_gcry_cipher_ctr_crypt): Ditto.
+ * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt)
+ (_gcry_cipher_ofb_decrypt): Ditto.
+
+ Fix CBC-CTS+CBC-MAC flag check.
+ + commit a69021535b472556651eb2bab65666206c56c24b
+ * cipher/cipher.c (_gcry_cipher_open_internal): Check flags separately
+ instead of AND masking two flags to zero.
+
+ tests/basic: silence GCC-8 warning.
+ + commit 2a94bdfc0538a340a24c1a7b524bb0c5f606457c
+ * tests/basic.c (check_ofb_cipher, check_stream_cipher): Change
+ tv[].data[].inlen type from signed to unsigned integer.
+
+2018-06-19 Will Dietz <w@wdtz.org>
+
+ random: Fix hang of _gcry_rndjent_get_version.
+ + commit 355f5b7f69075c010fe33aa5b10ac60c08fae0c7
+ * random/rndjent.c (_gcry_rndjent_get_version): Move locking.
+
+2018-06-13 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Add blinding for ECDSA.
+ + commit 9010d1576e278a4274ad3f4aa15776c28f6ba965
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Blind secret D with
+ randomized nonce B.
+
+2018-06-06 Werner Koch <wk@gnupg.org>
+
+ ecc: Improve gcry_mpi_ec_curve_point.
+ + commit 7b6c2afd699e889f5f054cc3d202a61bd0ee1dcf
+ * mpi/ec.c (_gcry_mpi_ec_curve_point): Check range of coordinates.
+ * tests/t-mpi-point.c (point_on_curve): New.
+
+2018-06-05 Werner Koch <wk@gnupg.org>
+
+ mpi: New internal function _gcry_mpi_cmpabs.
+ + commit 6606ae44e0de1069b29dd4215ee9748280940e1b
+ * mpi/mpi-cmp.c (_gcry_mpi_cmp): Factor out to ...
+ (do_mpi_cmp): New. Add arg absmode.
+ (_gcry_mpi_cmpabs): New.
+ * src/gcrypt-int.h (mpi_cmpabs): New macro.
+
+2018-04-29 Werner Koch <wk@gnupg.org>
+
+ build: Convince gcc not to delete NULL ptr checks.
+ + commit 61dbb7c08ab11c10060e193b52e3e1d2ec6dd062
+ * configure.ac: Try to use -fno-delete-null-pointer-checks.
+
+2018-04-28 Werner Koch <wk@gnupg.org>
+
+ prime: Avoid rare assertion failure in gcry_prime_check.
+ + commit f3362f10f6f671246c38115ed12b0047966c200e
+ * cipher/primegen.c (is_prime): Don't fail on the assert X > 1.
+
+2018-04-17 Werner Koch <wk@gnupg.org>
+
+ mpi: Fix for buidling for MIPS64 with Clang.
+ + commit e7ae0ae243c8978a67c802169183187d88557be8
+ * mpi/longlong.h [MIPS64][__clang__]: Use the C version like we
+ already do for 32 bit MIPS.
+
+2018-04-11 NIIBE Yutaka <gniibe@fsij.org>
+
+ hmac: Use xtrymalloc.
+ + commit 3e3b520fb32a37c5c23762531a7b3168e112ac36
+ * src/hmac256.c (_gcry_hmac256_new): Use xtrymalloc.
+ (_gcry_hmac256_file): Likewise.
+
+2018-04-10 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ basic_all_hwfeature_combinations.sh: use $njobs to limit parallel tasks.
+ + commit 5e01705ca90830c27a4cbd8bad41243915f4538a
+ * tests/basic_all_hwfeature_combinations.sh: Use $njobs to limit
+ parallel tasks instead of fixed number "8".
+
+ Faster look-up for spec by algo for digests, ciphers and MAC.
+ + commit 634a85412a4073aa1890589ce5e97eac7b0f3ca3
+ * cipher/cipher.c (cipher_list_algo0, cipher_list_algo301): New cipher
+ spec lists with same order and spacing as 'gcry_cipher_algos'
+ enumeration.
+ (spec_from_algo): Use new spec lists for faster look-up.
+ * cipher/mac.c (mac_list_algo101, mac_list_algo201, mac_list_algo401)
+ (mac_list_algo501): New MAC spec lists with same order and spacing as
+ 'gcry_mac_algos' enumeration.
+ (spec_from_algo): Use new spec lists for faster look-up.
+ * cipher/md.c (digest_list_algo0, digest_list_algo301): New digest
+ spec lists with same order and spacing as 'gcry_md_algos'
+ enumeration.
+ (spec_from_algo): Use new spec lists for faster look-up.
+
+ Fix building with BLAKE2 disabled.
+ + commit 35b59d0ea52e8a1c30c43554dc4dbca97da4bf87
+ * cipher/md.c (md_setkey): Enclose Blake2 part with USE_BLAKE2.
+
+ Add missing BLAKE2, SM3 and GOSTR3411_CP to MAC-HMAC interface.
+ + commit 52e52eb0e3e5541cfc86e04c5047500db5d538b7
+ * cipher/mac-hmac.c (map_mac_algo_to_md): Add GOSTR3411_CP, BLAKE2 and
+ SM3.
+ (_gcry_mac_type_spec_hmac_gost3411_cp)
+ (_gcry_mac_type_spec_hmac_blake2b_512)
+ (_gcry_mac_type_spec_hmac_blake2b_384)
+ (_gcry_mac_type_spec_hmac_blake2b_256)
+ (_gcry_mac_type_spec_hmac_blake2b_160)
+ (_gcry_mac_type_spec_hmac_blake2s_256)
+ (_gcry_mac_type_spec_hmac_blake2s_224)
+ (_gcry_mac_type_spec_hmac_blake2s_160)
+ (_gcry_mac_type_spec_hmac_blake2s_128)
+ (_gcry_mac_type_spec_hmac_sm3): New.
+ * cipher/mac-internal.h (_gcry_mac_type_spec_hmac_gost3411_cp)
+ (_gcry_mac_type_spec_hmac_blake2b_512)
+ (_gcry_mac_type_spec_hmac_blake2b_384)
+ (_gcry_mac_type_spec_hmac_blake2b_256)
+ (_gcry_mac_type_spec_hmac_blake2b_160)
+ (_gcry_mac_type_spec_hmac_blake2s_256)
+ (_gcry_mac_type_spec_hmac_blake2s_224)
+ (_gcry_mac_type_spec_hmac_blake2s_160)
+ (_gcry_mac_type_spec_hmac_blake2s_128)
+ (_gcry_mac_type_spec_hmac_sm3): New.
+ * cipher/mac.c (mac_list): Add GOSTR3411_CP, BLAKE2 and SM3.
+ * src/gcrypt.h.in (GCRY_MAC_HMAC_GOSTR3411_CP)
+ (GCRY_MAC_HMAC_BLAKE2B_512, GCRY_MAC_HMAC_BLAKE2B_384)
+ (GCRY_MAC_HMAC_BLAKE2B_256, GCRY_MAC_HMAC_BLAKE2B_160)
+ (GCRY_MAC_HMAC_BLAKE2S_256, GCRY_MAC_HMAC_BLAKE2S_224)
+ (GCRY_MAC_HMAC_BLAKE2S_160, GCRY_MAC_HMAC_BLAKE2S_128)
+ (GCRY_MAC_HMAC_SM3): New.
+
+2018-04-10 NIIBE Yutaka <gniibe@fsij.org>
+
+ random: Protect another use of jent_rng_collector.
+ + commit 0de2a22fcf6607d0aecb550feefa414cee3731b2
+ * random/rndjent.c (_gcry_rndjent_get_version): Lock the access.
+
+2018-03-28 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ aarch64/assembly: only use the lower 32 bit of an int parameters.
+ + commit 9b58e4a03ba3aeff7bae3f40da706977870c9649
+ * cipher/camellia-aarch64.S (_gcry_camellia_arm_encrypt_block)
+ (__gcry_camellia_arm_decrypt_block): Make comment section about input
+ registers match usage.
+ * cipher/rijndael-armv8-aarch64-ce.S (_gcry_aes_ocb_auth_armv8_ce): Use
+ 'w12' and 'w7' instead of 'x12' and 'x7'.
+ (_gcry_aes_xts_enc_armv8_ce, _gcry_aes_xts_dec_armv8_ce): Fix function
+ prototype in comments.
+ * mpi/aarch64/mpih-add1.S: Use 32-bit registers for 32-bit mpi_size_t
+ parameters.
+ * mpi/aarch64/mpih-mul1.S: Ditto.
+ * mpi/aarch64/mpih-mul2.S: Ditto.
+ * mpi/aarch64/mpih-mul3.S: Ditto.
+ * mpi/aarch64/mpih-sub1.S: Ditto.
+
+ poly1305: silence compiler warning on clang/aarch64.
+ + commit 8cdb010f04528703a502344e00d52447de12547d
+ * cipher/poly1305.c (MUL_MOD_1305_64): cast zero constant to 64-bits.
+
+2018-03-28 Martin Storsjö <martin@martin.st>
+
+ aarch64: Enable building the aarch64 cipher assembly for windows.
+ + commit 0de2191a07d69ef1fa34ca4c5d5fc4985ff7b4c4
+ * cipher/asm-common-aarch64.h: New.
+ * cipher/camellia-aarch64.S: Use ELF macro, use x19 instead of x18.
+ * cipher/chacha20-aarch64.S: Use ELF macro, don't use GOT on windows.
+ * cipher/cipher-gcm-armv8-aarch64-ce.S: Use ELF macro.
+ * cipher/rijndael-aarch64.S: Use ELF macro.
+ * cipher/rijndael-armv8-aarch64-ce.S: Use ELF macro.
+ * cipher/sha1-armv8-aarch64-ce.S: Use ELF macro.
+ * cipher/sha256-armv8-aarch64-ce.S: Use ELF macro.
+ * cipher/twofish-aarch64.S: Use ELF macro.
+ * configure.ac: Don't require .size and .type in aarch64 assembly check.
+
+ aarch64: camellia: Only use the lower 32 bit of an int parameter.
+ + commit 4e1b628f492643d4e9b830bcdab7b49daaec5854
+ * cipher/camellia-aarch64.S: Use 'w3' instead of 'x3'.
+
+ aarch64: Fix assembling chacha20-aarch64.S with clang/llvm.
+ + commit 36e916fc332eda74963192b1c0bf6860a3e5d67b
+ * cipher/chacha20-aarch64.S: Remove superfluous lane counts.
+
+ aarch64: mpi: Fix building the mpi aarch64 assembly for windows.
+ + commit ec0a2f25c0f64a7b65b373508ce9081e10461965
+ * mpi/aarch64/mpih-add1.S: Use ELF macro.
+ * mpi/aarch64/mpih-mul1.S: Use ELF macro.
+ * mpi/aarch64/mpih-mul2.S: Use ELF macro.
+ * mpi/aarch64/mpih-mul3.S: Use ELF macro.
+ * mpi/aarch64/mpih-sub1.S: Use ELF macro.
+ * mpi/asm-common-aarch64.h: New.
+
+ random: Don't assume that _WIN64 implies x86_64.
+ + commit ed41d6d6fb4551342b22ef763de1bd60e964e186
+ * random/rndw32.c: Change _WIN64 ifdef into __x86_64__.
+
+2018-03-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ tests/aeswrap: add in-place encryption/decryption testing.
+ + commit 885f031fbd17abc1c0fedbb98df22823b647fc11
+ * tests/aeswrap.c (check): Rename to...
+ (check_one): ...this and add in-place testing.
+ (check): New.
+
+2018-03-22 Stephan Mueller <smueller@chronox.de>
+
+ AES-KW: fix in-place encryption.
+ + commit 330ec66e0babdabb658dc7d6db78f37b2a1b996e
+ * cipher/cipher-aeswrap.c: move memmove call before KW IV setting
+
+2018-03-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ bench-slope: add CPU frequency auto-detection.
+ + commit 617f5e746f8295cc36d1002c8c53edc95d04d0f6
+ * tests/bench-slope.c (bench_obj): Add 'hd'.
+ (bench_encrypt_init, bench_encrypt_free, bench_encrypt_do_bench)
+ (bench_decrypt_do_bench, bench_xts_encrypt_init)
+ (bench_xts_encrypt_do_bench, bench_xts_decrypt_do_bench)
+ (bench_ccm_encrypt_init, bench_ccm_encrypt_do_bench)
+ (bench_ccm_decrypt_do_bench, bench_aead_encrypt_init)
+ (bench_aead_encrypt_do_bench, bench_aead_decrypt_do_bench)
+ (bench_hash_init, bench_hash_free, bench_hash_do_bench)
+ (bench_mac_init, bench_mac_free, bench_mac_do_bench): Use 'obj->hd'
+ for storing pointer to crypto context.
+ (auto_ghz): New.
+ (do_slope_benchmark): Rename to...
+ (slope_benchmark): ...this.
+ (auto_ghz_init, auto_ghz_free, auto_ghz_bench, auto_ghz_detect_ops)
+ (get_auto_ghz, do_slope_benchmark): New.
+ (double_to_str): Round number larger than 1000 to integer.
+ (bench_print_result_csv, bench_print_result_std)
+ (bench_print_result, bench_print_header, cipher_bench_one)
+ (hash_bench_one, mac_bench_one, kdf_bench_one, kdf_bench): Add
+ auto-detected frequency printing.
+ (print_help): Help for CPU speed auto-detection mode.
+ (main): Add parsing for "--cpu-mhz auto".
+
+ _gcry_burn_stack: use memset for clearing memory.
+ + commit 3841b23c0ccb24d555b7570083bba958e3126d26
+ * src/misc.c (__gcry_burn_stack) [HAVE_VLA]: Use 'memset' for clearing
+ stack.
+
+ Improve constant-time buffer compare.
+ + commit a1127dbbada4302abf09eec90fbaceca87bfcdf0
+ * cipher/bufhelp.h (buf_eq_const): Rewrite logic.
+
+2018-02-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add Intel SHA Extensions accelerated SHA256 implementation.
+ + commit 0b3ec359e2279c3b46b171372b1b7733bba20cd7
+ * cipher/Makefile.am: Add 'sha256-intel-shaext.c'.
+ * cipher/sha256-intel-shaext.c: New.
+ * cipher/sha256.c (USE_SHAEXT)
+ (_gcry_sha256_transform_intel_shaext): New.
+ (SHA256_CONTEXT): Add 'use_shaext'.
+ (sha256_init, sha224_init) [USE_SHAEXT]: Use shaext if supported.
+ (transform) [USE_SHAEXT]: Use shaext if enabled.
+ (transform): Only add ASM_EXTRA_STACK if returned burn length is not
+ zero.
+ * configure.ac: Add 'sha256-intel-shaext.lo'.
+
+ Add Intel SHA Extensions accelerated SHA1 implementation.
+ + commit d02958bd300d2c80bc92b1e072103e95e256b297
+ * cipher/Makefile.am: Add 'sha1-intel-shaext.c'.
+ * cipher/sha1-intel-shaext.c: New.
+ * cipher/sha1.c (USE_SHAEXT, _gcry_sha1_transform_intel_shaext): New.
+ (sha1_init) [USE_SHAEXT]: Use shaext implementation is supported.
+ (transform) [USE_SHAEXT]: Use shaext if enabled.
+ (transform): Only add ASM_EXTRA_STACK if returned burn length is not
+ zero.
+ * cipher/sha1.h (SHA1_CONTEXT): Add 'use_shaext'.
+ * configure.ac: Add 'sha1-intel-shaext.lo'.
+ (shaextsupport, gcry_cv_gcc_inline_asm_shaext): New.
+ * src/g10lib.h: Add HWF_INTEL_SHAEXT and reorder HWF flags.
+ * src/hwf-x86.c (detect_x86_gnuc): Detect SHA Extensions.
+ * src/hwfeatures.c (hwflist): Add 'intel-shaext'.
+
+ AVX implementation of BLAKE2s.
+ + commit da58a62ac1b7a8d97b0895dcb41d15af531e45e5
+ * cipher/Makefile.am: Add 'blake2s-amd64-avx.S'.
+ * cipher/blake2.c (USE_AVX, _gry_blake2s_transform_amd64_avx): New.
+ (BLAKE2S_CONTEXT) [USE_AVX]: Add 'use_avx'.
+ (blake2s_transform): Rename to ...
+ (blake2s_transform_generic): ... this.
+ (blake2s_transform): New.
+ (blake2s_final): Pass 'ctx' pointer to transform function instead of
+ 'S'.
+ (blake2s_init_ctx): Check HW features and enable AVX implementation
+ if supported.
+ * cipher/blake2s-amd64-avx.S: New.
+ * configure.ac: Add 'blake2s-amd64-avx.lo'.
+
+2018-02-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ AVX2 implementation of BLAKE2b.
+ + commit af7fc732f9a7af7a70276f1e8364d2132db314f1
+ * cipher/Makefile.am: Add 'blake2b-amd64-avx2.S'.
+ * cipher/blake2.c (USE_AVX2, ASM_FUNC_ABI, ASM_EXTRA_STACK)
+ (_gry_blake2b_transform_amd64_avx2): New.
+ (BLAKE2B_CONTEXT) [USE_AVX2]: Add 'use_avx2'.
+ (blake2b_transform): Rename to ...
+ (blake2b_transform_generic): ... this.
+ (blake2b_transform): New.
+ (blake2b_final): Pass 'ctx' pointer to transform function instead of
+ 'S'.
+ (blake2b_init_ctx): Check HW features and enable AVX2 implementation
+ if supported.
+ * cipher/blake2b-amd64-avx2.S: New.
+ * configure.ac: Add 'blake2b-amd64-avx2.lo'.
+
+2018-01-31 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix incorrect counter overflow handling for GCM.
+ + commit ffdc6f3623a0bcb41324d562340b2cd1c288e387
+ * cipher/cipher-gcm.c (gcm_ctr_encrypt): New function to handle
+ 32-bit CTR increment for GCM.
+ (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt): Do not use
+ generic CTR implementation directly, use gcm_ctr_encrypt instead.
+ * tests/basic.c (_check_gcm_cipher): Add test-vectors for 32-bit
+ CTR overflow.
+ (check_gcm_cipher): Add 'split input to 15 bytes and 17 bytes'
+ test-runs.
+
+2018-01-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix use of AVX instructions in Chaha20 SSSE3 implementation.
+ + commit 0b55f349a8b8f4b0ac9ed724c2d5b8dcc9f5401c
+ * cipher/chacha20-amd64-ssse3.S: Replace two 'vmovdqa' instructions
+ with 'movdqa'.
+
+2018-01-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ doc: fix double "See" in front of reference.
+ + commit bd75f0e89817b5708c57efab49e3eb4e035186e2
+ * doc/gcrypt.texi: Change @xref to @ref when text already has 'see' in
+ the front.
+
+ Add EAX mode.
+ + commit e8629e535bd0e9711b07904d4501de8ad57aaecd
+ * cipher/Makefile.am: Add 'cipher-eax.c'.
+ * cipher/cipher-cmac.c (cmac_write): Rename to ...
+ (_gcry_cmac_write): ... this; Take CMAC context as new input
+ parameter; Return error code.
+ (cmac_generate_subkeys): Rename to ...
+ (_gcry_cmac_generate_subkeys): ... this; Take CMAC context as new
+ input parameter; Return error code.
+ (cmac_final): Rename to ...
+ (_gcry_cmac_final): ... this; Take CMAC context as new input
+ parameter; Return error code.
+ (cmac_tag): Take CMAC context as new input parameter.
+ (_gcry_cmac_reset): New.
+ (_gcry_cipher_cmac_authenticate): Remove duplicate tag flag check;
+ Adapt to changes above.
+ (_gcry_cipher_cmac_get_tag): Adapt to changes above.
+ (_gcry_cipher_cmac_check_tag): Ditto.
+ (_gcry_cipher_cmac_set_subkeys): Ditto.
+ * cipher-eax.c: New.
+ * cipher-internal.h (gcry_cmac_context_t): New.
+ (gcry_cipher_handle): Update u_mode.cmac; Add u_mode.eax.
+ (_gcry_cmac_write, _gcry_cmac_generate_subkeys, _gcry_cmac_final)
+ (_gcry_cmac_reset, _gcry_cipher_eax_encrypt, _gcry_cipher_eax_decrypt)
+ (_gcry_cipher_eax_set_nonce, _gcry_cipher_eax_authenticate)
+ (_gcry_cipher_eax_get_tag, _gcry_cipher_eax_check_tag)
+ (_gcry_cipher_eax_setkey): New prototypes.
+ * cipher/cipher.c (_gcry_cipher_open_internal, cipher_setkey)
+ (cipher_reset, cipher_encrypt, cipher_decrypt, _gcry_cipher_setiv)
+ (_gcry_cipher_authenticate, _gcry_cipher_gettag, _gcry_cipher_checktag)
+ (_gcry_cipher_info): Add EAX mode.
+ * doc/gcrypt.texi: Add EAX mode.
+ * src/gcrypt.h.in (GCRY_CIPHER_MODE_EAX): New.
+ * tests/basic.c (_check_gcm_cipher, _check_poly1305_cipher): Constify
+ test vectors array.
+ (_check_eax_cipher, check_eax_cipher): New.
+ (check_ciphers, check_cipher_modes): Add EAX mode.
+ * tests/bench-slope.c (bench_eax_encrypt_do_bench)
+ (bench_eax_decrypt_do_bench, bench_eax_authenticate_do_bench)
+ (eax_encrypt_ops, eax_decrypt_ops, eax_authenticate_ops): New.
+ (cipher_modes): Add EAX mode.
+ * tests/benchmark.c (cipher_bench): Add EAX mode.
+
+ cipher: constify spec arrays.
+ + commit cd7ed2e3546b12dd98df4211949f1cdbf5827013
+ * cipher/cipher.c (cipher_list): Constify array.
+ * cipher/mac.c (mac_list): Constify array.
+ * cipher/md.c (digest_list): Constify array.
+ * cipher/pubkey.c (pubkey_list): Constify array.
+
+ Add ARMv8/CE acceleration for AES-XTS.
+ + commit 93503c127a52c1f6a193750e2bf181a744ba3e6b
+ * cipher/rijndael-armv8-aarch32-ce.S (_gcry_aes_xts_enc_armv8_ce)
+ (_gcry_aes_xts_dec_armv8_ce): New.
+ * cipher/rijndael-armv8-aarch64-ce.S (_gcry_aes_xts_enc_armv8_ce)
+ (_gcry_aes_xts_dec_armv8_ce): New.
+ * cipher/rijndael-armv8-ce.c (_gcry_aes_xts_enc_armv8_ce)
+ (_gcry_aes_xts_dec_armv8_ce, xts_crypt_fn_t)
+ (_gcry_aes_armv8_ce_xts_crypt): New.
+ * cipher/rijndael.c (_gcry_aes_armv8_ce_xts_crypt): New.
+ (_gcry_aes_xts_crypt) [USE_ARM_CE]: New.
+
+2018-01-09 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael-ssse3: call assembly functions directly.
+ + commit c3d60acc3ab5c6d60c2258882175bf31351cc998
+ * cipher/rijndael-ssse3-amd64-asm.S (_gcry_aes_ssse3_enc_preload)
+ (_gcry_aes_ssse3_dec_preload, _gcry_aes_ssse3_encrypt_core)
+ (_gcry_aes_ssse3_decrypt_core, _gcry_aes_schedule_core): Add
+ ENTER_SYSV_FUNC_PARAMS_* at function entry and EXIT_SYSV_FUNC at exit.
+ (_gcry_aes_ssse3_encrypt_core, _gcry_aes_ssse3_decrypt_core): Change
+ to input parameters to RDI and RSI registers.
+ * cipher/rijndael-ssse3-amd64.c (_gcry_aes_ssse3_encrypt_core)
+ (_gcry_aes_ssse3_decrypt_core, _gcry_aes_schedule_core): Add parameters
+ for function prototypes.
+ (PUSH_STACK_PTR, POP_STACK_PTR): Remove.
+ (vpaes_ssse3_prepare_enc, vpaes_ssse3_prepare_dec)
+ (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption)
+ (do_vpaes_ssse3_enc, do_vpaes_ssse3_dec): Remove inline assembly to
+ call functions, and call directly instead.
+
+ Move AMD64 MS to SysV calling convention conversion to assembly side.
+ + commit a518b6680ea80a4325731028545a701c1d71fc02
+ * cipher/Makefile.am: Add 'asm-common-amd64.h'.
+ * cipher/asm-common-amd64.h: New.
+ * cipher/blowfish-amd64.S: Add ENTER_SYSV_FUNC_* and EXIT_SYSV_FUNC for
+ each global function from 'asm-common-amd64.h'.
+ * cipher/cast5-amd64.S: Ditto.
+ * cipher/des-amd64.S: Ditto.
+ * cipher/rijndael-amd64.S: Ditto.
+ * cipher/twofish-amd64.S: Ditto.
+ * cipher/arcfour-amd64.S: Ditto.
+ * cipher/blowfish.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
+ (call_sysv_fn): Remove.
+ * cipher/cast5.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
+ (call_sysv_fn): Remove.
+ * cipher/twofish.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
+ (call_sysv_fn, call_sysv_fn5, call_sysv_fn6): Remove.
+ * cipher/rijndael.c (do_encrypt, do_decrypt)
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Remove assembly block for
+ calling SysV ABI function.
+ * cipher/arcfour.c [USE_AMD64_ASM] (encrypt_stream): Ditto.
+
+ Make BMI2 inline assembly check more robust.
+ + commit 135250e3060e79be698d4f36a819aa8a880789f8
+ * configure.ac (gcry_cv_gcc_inline_asm_bmi2): New assembly test.
+
+ Add AES-NI acceleration for AES-XTS.
+ + commit a00c5b2988cea256c7823a76ce601febf02c790f
+ * cipher/cipher-internal.h (gcry_cipher_handle): Change bulk
+ XTS function to take cipher context.
+ * cipher/cipher-xts.c (_gcry_cipher_xts_crypt): Ditto.
+ * cipher/cipher.c (_gcry_cipher_open_internal): Setup AES-NI
+ XTS bulk function.
+ * cipher/rijndael-aesni.c (xts_gfmul_const, _gcry_aes_aesni_xts_enc)
+ (_gcry_aes_aesni_xts_enc, _gcry_aes_aesni_xts_crypt): New.
+ * cipher/rijndael.c (_gcry_aes_aesni_xts_crypt)
+ (_gcry_aes_xts_crypt): New.
+ * src/cipher.h (_gcry_aes_xts_crypt): New.
+
+ AES-NI improvements for AMD64.
+ + commit c9e9cb2eb6a1c659d3825ca627228b732f2f2152
+ * cipher/rijndael-aesni.c [__x86_64__] (aesni_prepare_7_15_variable)
+ (aesni_prepare_7_15, aesni_cleanup_7_15, do_aesni_enc_vec8)
+ (do_aesni_dec_vec8, do_aesni_ctr_8): New.
+ (_gcry_aes_aesni_ctr_enc, _gcry_aes_aesni_cfb_dec)
+ (_gcry_aes_aesni_cbc_dec, aesni_ocb_enc, aesni_ocb_dec)
+ (_gcry_aes_aesni_ocb_auth) [__x86_64__]: Add 8 parallel blocks
+ processing.
+
+ Add ARMv8/AArch64 implementation of chacha20.
+ + commit b3ec0f752c925cde36f560f0f9309ab6450bbfd9
+ * cipher/Makefile.am: Add 'chacha20-aarch64.S'.
+ * cipher/chacha20-aarch64.S: New.
+ * cipher/chacha20.c (USE_AARCH64_SIMD): New.
+ (_gcry_chacha20_aarch_blocks4): New.
+ (chacha20_do_setkey): Add HWF selection for Aarch64 implementation.
+ * configure.ac: Add 'chacha20-aarch64.lo'.
+
+ New ChaCha implementations.
+ + commit 172ad09cbedc893f147180875335f4c525393c0b
+ * cipher/Makefile.am: Remove 'chacha20-sse2-amd64.S',
+ 'chacha20-ssse3-amd64.S', 'chacha20-avx2-amd64.S'; Add
+ 'chacha20-amd64-ssse3.S', 'chacha20-amd64-avx2.S'.
+ * cipher/chacha20-amd64-avx2.S: New.
+ * cipher/chacha20-amd64-ssse3.S: New.
+ * cipher/chacha20-armv7-neon.S: Rewrite.
+ * cipher/chacha20-avx2-amd64.S: Remove.
+ * cipher/chacha20-sse2-amd64.S: Remove.
+ * cipher/chacha20-ssse3-amd64.S: Remove.
+ * cipher/chacha20.c (CHACHA20_INPUT_LENGTH, USE_SSE2, USE_NEON)
+ (ASM_EXTRA_STACK, chacha20_blocks_t, _gcry_chacha20_amd64_sse2_blocks)
+ (_gcry_chacha20_amd64_ssse3_blocks, _gcry_chacha20_amd64_avx2_blocks)
+ (_gcry_chacha20_armv7_neon_blocks, QROUND, QOUT, chacha20_core)
+ (chacha20_do_encrypt_stream): Remove.
+ (_gcry_chacha20_amd64_ssse3_blocks4, _gcry_chacha20_amd64_avx2_blocks8)
+ (_gcry_chacha20_armv7_neon_blocks4, ROTATE, XOR, PLUS, PLUSONE)
+ (QUARTERROUND, BUF_XOR_LE32): New.
+ (CHACHA20_context_s, chacha20_blocks, chacha20_keysetup)
+ (chacha20_encrypt_stream): Rewrite.
+ (chacha20_do_setkey): Adjust for new CHACHA20_context_s.
+ * configure.ac: Remove 'chacha20-sse2-amd64.lo',
+ 'chacha20-ssse3-amd64.lo', 'chacha20-avx2-amd64.lo'; Add
+ 'chacha20-amd64-ssse3.lo', 'chacha20-amd64-avx2.lo'.
+
+ New Poly1305 implementations.
+ + commit b9a471ccf5f02f89e25c7ccc29898d0e4e486099
+ * cipher/Makefile.am: Include '../mpi' for 'longlong.h'; Remove
+ 'poly1305-sse2-amd64.S', 'poly1305-avx2-amd64.S' and
+ 'poly1305-armv7-neon.S'.
+ * cipher/poly1305-armv7-neon.S: Remove.
+ * cipher/poly1305-avx2-amd64.S: Remove.
+ * cipher/poly1305-sse2-amd64.S: Remove.
+ * cipher/poly1305-internal.h (POLY1305_BLOCKSIZE)
+ (POLY1305_STATE): New.
+ (POLY1305_SYSV_FUNC_ABI, POLY1305_REF_BLOCKSIZE)
+ (POLY1305_REF_STATESIZE, POLY1305_REF_ALIGNMENT)
+ (POLY1305_USE_SSE2, POLY1305_SSE2_BLOCKSIZE, POLY1305_SSE2_STATESIZE)
+ (POLY1305_SSE2_ALIGNMENT, POLY1305_USE_AVX2, POLY1305_AVX2_BLOCKSIZE)
+ (POLY1305_AVX2_STATESIZE, POLY1305_AVX2_ALIGNMENT)
+ (POLY1305_USE_NEON, POLY1305_NEON_BLOCKSIZE, POLY1305_NEON_STATESIZE)
+ (POLY1305_NEON_ALIGNMENT, POLY1305_LARGEST_BLOCKSIZE)
+ (POLY1305_LARGEST_STATESIZE, POLY1305_LARGEST_ALIGNMENT)
+ (POLY1305_STATE_BLOCKSIZE, POLY1305_STATE_STATESIZE)
+ (POLY1305_STATE_ALIGNMENT, OPS_FUNC_ABI, poly1305_key_s)
+ (poly1305_ops_s): Remove.
+ (poly1305_context_s): Rewrite.
+ * cipher/poly1305.c (_gcry_poly1305_amd64_sse2_init_ext)
+ (_gcry_poly1305_amd64_sse2_finish_ext)
+ (_gcry_poly1305_amd64_sse2_blocks, poly1305_amd64_sse2_ops)
+ (poly1305_init_ext_ref32, poly1305_blocks_ref32)
+ (poly1305_finish_ext_ref32, poly1305_default_ops)
+ (_gcry_poly1305_amd64_avx2_init_ext)
+ (_gcry_poly1305_amd64_avx2_finish_ext)
+ (_gcry_poly1305_amd64_avx2_blocks)
+ (poly1305_amd64_avx2_ops, poly1305_get_state): Remove.
+ (poly1305_init): Rewrite.
+ (USE_MPI_64BIT, USE_MPI_32BIT): New.
+ [USE_MPI_64BIT] (ADD_1305_64, MUL_MOD_1305_64, poly1305_blocks)
+ (poly1305_final): New implementation using 64-bit limbs.
+ [USE_MPI_32BIT] (UMUL_ADD_32, ADD_1305_32, MUL_MOD_1305_32)
+ (poly1305_blocks): New implementation using 32-bit limbs.
+ (_gcry_poly1305_update, _gcry_poly1305_finish)
+ (_gcry_poly1305_init): Adapt to new implementation.
+ * configure.ac: Remove 'poly1305-sse2-amd64.lo',
+ 'poly1305-avx2-amd64.lo' and 'poly1305-armv7-neon.lo'.
+
+ mpi/ec: fix when 'unsigned long' is 32-bit but limb size is 64-bit.
+ + commit d39deb0a41dbeec81174704904d3d29c66d10d7e
+ * mpi/ec.c (ec_addm_25519, ec_subm_25519, ec_mulm_25519): Cast '1' to
+ mpi_limb_t before left shift.
+
+2017-11-24 Werner Koch <wk@gnupg.org>
+
+ sexp: Avoid a fatal error in case of ENOMEM in called functions.
+ + commit 2ad912d5b7794fb32192fddab1b559c7b86303a2
+ * src/sexp.c (do_vsexp_sscan): Replace BUG() by a proper error
+ return. Replace sprintf by snprintf.
+ (convert_to_hex): Replace sprintf by snprintf.
+ (convert_to_string): Ditto.
+ (_gcry_sexp_sprint): Ditto.
+
+ api: Add GCRYCTL_AUTO_EXPAND_SECMEM.
+ + commit 1f6b2f6099ebcfd785e2d2ae0aeca810394dbbac
+ * src/gcrypt.h.in (GCRYCTL_AUTO_EXPAND_SECMEM): New enum.
+ * src/global.c (_gcry_vcontrol): Implement that.
+ * src/secmem.c (auto_expand): New var.
+ (_gcry_secmem_set_auto_expand): New.
+ (_gcry_secmem_malloc_internal): Act upon AUTO_EXPAND.
+
+2017-11-14 NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: Add HAVE_MMAP check for MinGW.
+ + commit c594f187bd457b757112adc551ffa4db92962dc1
+ * tests/t-secmem.c (main): Conditionalize with HAVE_MMAP.
+
+2017-11-09 NIIBE Yutaka <gniibe@fsij.org>
+
+ Fix secmem test for machine with larger page.
+ + commit 621f5c4e837347308a6b06a8cfbfc47ca9fae69e
+ * tests/t-secmem.c (main): Detect page size and setup chunk size.
+ * src/secmem.c (init_pool): Simplify the expression.
+
+2017-10-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ Add OID information for SM3.
+ + commit 94b84360ca55c407222a3eb8222d8b1816fc617f
+ * cipher/sm3.c (asn_sm3, oid_spec_sm3): New.
+ (_gcry_digest_spec_sm3): Add asn_sm3, oid_spec_sm3.
+
+2017-10-24 Jia Zhang <qianyue.zj@alibaba-inc.com>
+
+ Add crypto hash SM3.
+ + commit 4423bf3cc4432b9bfe801ff74cb05e6f0dd3eccd
+ * configure.ac (available_digests): Add sm3.
+ * src/cipher.h: Add declarations for SM3.
+ * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add sm3.c.
+ * cipher/md.c [USE_SM3] (digest_list): Add _gcry_digest_spec_sm3.
+ * cipher/pubkey-util.c (hashnames): Add "sm3".
+ * cipher/sm3.c: New.
+ * tests/basic.c (check_digests): Add test vectors for SM3.
+ * tests/hashtest-256g.in (algos): Add SM3.
+ * tests/hashtest.c (testvectors): Add for SM3.
+
+2017-10-24 NIIBE Yutaka <gniibe@fsij.org>
+
+ Add new constant GCRY_MD_SM3 for crypto hash SM3.
+ + commit 5b31e22d9fc542bdccb1586ef2c83d9794a731d3
+ * src/gcrypt.h.in (GCRY_MD_SM3): New.
+
+2017-10-17 Werner Koch <wk@gnupg.org>
+
+ api: New function gcry_mpi_get_ui.
+ + commit c6e42e7ec3d1046969d783c443c13aad7cb61bb8
+ * src/gcrypt.h.in (gcry_mpi_get_ui): New.
+ (mpi_get_ui): New macro.
+ * src/libgcrypt.def, src/libgcrypt.vers: Add new function.
+ * src/visibility.c (gcry_mpi_get_ui): New.
+ * src/visibility.h: Mark that function.
+ (gcry_mpi_get_ui): New.
+ * mpi/mpiutil.c (MY_UINT_MAX): New macro.
+ (_gcry_mpi_get_ui): Re-implemented. This function existed but was
+ never imported or used.
+ * tests/mpitests.c (test_maxsize): Add some test for this function.
+
+2017-08-29 NIIBE Yutaka <gniibe@fsij.org>
+
+ Tweak GCC version check.
+ + commit e4dc458b0b7dc9b8417a2177ef17822d9b9064ec
+ * src/global.c (_gcry_vcontrol): It's GCC 4.2 which started to support
+ diagnostic pragma.
+
+ random: Fix warnings on Windows.
+ + commit 8126a6717c80d4fc1766d7f975e872bee2f9f203
+ * random/random-csprng.c (lock_seed_file): Vars with no use.
+
+ tests: Fix warnings on Windows.
+ + commit a848ef44470a524c05624afb54b92cf25595acd2
+ * tests/fipsdrv.c (print_dsa_domain_parameters, print_ecdsa_dq): Fix.
+
+ ecc: Fix scratch MPI.
+ + commit db3a8d6890fb4a6436e082b49378c0bd891563ca
+ * mpi/ec.c (ec_p_init): Check if scratch MPI is allocated.
+
+ ecc: Fix ec_mulm_25519.
+ + commit 1d5f726668b9cc32d6bb601f2329987058146c6c
+ * mpi/ec.c (ec_mulm_25519): Improve reduction to 25519.
+
+ ecc: Use 25519 method also for ed25519.
+ + commit fab712d654b2ccd24696ed90bc239860a128ad5b
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Don't use mpi_add
+ since it resizes to have more limbs.
+ * mpi/ec.c (point_resize): Fix for Edwards curve.
+ (ec_p_init): Support Edwards curve.
+ (_gcry_mpi_ec_get_affine): Use the methods.
+ (dup_point_edwards, add_points_edwards, sub_points_edwards): Ditto.
+ (_gcry_mpi_ec_mul_point): Resize MPIs of point to fixed size.
+ (_gcry_mpi_ec_curve_point): Use the methods.
+
+ ecc: Clean up curve specific method support.
+ + commit 1ac3d3637dd80013b78e03b9b9f582091710d908
+ * src/ec-context.h (struct mpi_ec_ctx_s): Remove MOD method.
+ * mpi/ec.c (ec_mod_25519): Remove.
+ (ec_p_init): Follow the removal of the MOD method.
+
+ ecc: Relax condition for 25519 computations.
+ + commit e9be23c4ad9f42c9d3198c706f912b7e27f574bc
+ * mpi/ec.c (ec_addm_25519, ec_subm_25519, ec_mulm_25519): Check number
+ of limbs, allocated more is OK.
+
+ ecc: Fix ec_mulm_25519.
+ + commit 449459a2770d3aecb1f36502bf1903e0cbd2873e
+ * mpi/ec.c (ec_mulm_25519): Fix the cases of 0 to 18.
+
+ ecc: field specific routines for 25519.
+ + commit 9ed0fb37bd637d1a2e9498c24097cfeadec682ec
+ * mpi/ec.c (point_resize): Improve for X25519.
+ (mpih_set_cond): New.
+ (ec_mod_25519, ec_addm_25519, ec_subm_25519, ec_mulm_25519)
+ (ec_mul2_25519, ec_pow2_25519): New.
+ (ec_p_init): Fill by FIELD_TABLE.
+
+ ecc: Add field specific computation methods.
+ + commit d4cd381defe5b37dda19bbda0986bdd38065bd31
+ * src/ec-context.h (struct mpi_ec_ctx_s): Add methods.
+ * mpi/ec.c (ec_p_init): Initialize the default methods.
+ (montgomery_ladder): Use the methods.
+
+2017-08-27 Werner Koch <wk@gnupg.org>
+
+ Release 1.8.1.
+ + commit 80fd8615048c3897b91a315cca22ab139b056ccd
+ * configure.ac: Set LT version to C22/A2/R1.
+
+2017-08-27 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Add input validation for X25519.
+ + commit bf76acbf0da6b0f245e491bec12c0f0a1b5be7c9
+ * cipher/ecc.c (ecc_decrypt_raw): Add input validation.
+ * mpi/ec.c (ec_p_init): Use scratch buffer for bad points.
+ (_gcry_mpi_ec_bad_point): New.
+
+2017-08-07 Marcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
+
+ cipher: Add OID for SHA384WithECDSA.
+ + commit a7bd2cbd3eabda88fb3cac5cbc13c21c97a7b315
+ * cipher/sha512.c (oid_spec_sha384): Add SHA384WithECDSA.
+
+2017-08-02 Werner Koch <wk@gnupg.org>
+
+ tests: Fix a printf glitch for a Windows test.
+ + commit df1e221b3012e96bbffbc7d5fd70836a9ae1cc19
+ * tests/t-convert.c (check_formats): Fix print format glitch on
+ Windows.
+ * tests/t-ed25519.c: Typo fix.
+
+ tests: Add benchmarking option to tests/random.
+ + commit 21d0f068a721c022f955084c28304934fd198c5e
+ * tests/random.c: Always include unistd.h.
+ (prepend_srcdir): New.
+ (run_benchmark): New.
+ (main): Add options --benchmark and --with-seed-file. Print whetehr
+ JENT has been used.
+ * tests/t-common.h (split_fields_colon): New. Taken from GnuPG.
+ License of that code changed to LGPLv2.1.
+
+ random: Add more bytes to the pool in addition to the seed file.
+ + commit eea36574f37830a6a80b4fad884825e815b2912f
+ * random/random-csprng.c (read_seed_file): Read 128 or 32 butes
+ depending on whether we have the Jitter RNG.
+
+2017-08-01 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add script to run basic tests with all supported HWF combinations.
+ + commit 94a92a3db909aef0ebcc009c2d7f5a2663e99004
+ * tests/basic_all_hwfeature_combinations.sh: New.
+ * tests/Makefile.am: Add basic_all_hwfeature_combinations.sh.
+
+2017-07-29 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix return value type for _gcry_md_extract.
+ + commit cf1528e7f2761774d06ace0de48f39c96b52dc4f
+ * src/gcrypt-int.h (_gcry_md_extract): Use gpg_err_code_t instead of
+ gpg_error_t for internal function return type.
+
+ Fix building AArch32 CE implementations when target is ARMv6 arch.
+ + commit 4a7aa30ae9f3ce798dd886c2f2d4164c43027748
+ * cipher/cipher-gcm-armv8-aarch32-ce.S: Select ARMv8 architecure.
+ * cipher/rijndael-armv8-aarch32-ce.S: Ditto.
+ * cipher/sha1-armv8-aarch32-ce.S: Ditto.
+ * cipher/sha256-armv8-aarch32-ce.S: Ditto.
+ * configure.ac (gcry_cv_gcc_inline_asm_aarch32_crypto): Ditto.
+
+2017-07-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ sexp: Add fall through annotation.
+ + commit b7cd44335d9cde43be6f693dca6399ed0762649c
+ * src/dumpsexp.c (parse_and_print): It's fall through.
+
+2017-07-24 Werner Koch <wk@gnupg.org>
+
+ random: Fix the command line munging for jitterbase.
+ + commit ac39522ab08fcd2483edc223334c6ab9d19e91f3
+ * random/Makefile.am (o_flag_munging): Make the first sed term also
+ global.
+
+2017-07-19 NIIBE Yutaka <gniibe@fsij.org>
+
+ Remove byte order mark.
+ + commit 1d8e4c2c3a7d0a4154caf5bd720a9a0b04179390
+ * random/jitterentropy-base.c, random/jitterentropy.h: Remove
+ byte order mark.
+
+2017-07-18 Werner Koch <wk@gnupg.org>
+
+ Release 1.8.0.
+ + commit 850aca744eeda5fd410f478a0778e353045ac962
+
+
+ mac: Add selftests for HMAC-SHA3-xxx.
+ + commit 95194c550443e8d5558856633f920daec8a975c4
+ * cipher/hmac-tests.c (check_one): Add arg trunc and change all
+ callers to pass false.
+ (selftests_sha3): New.
+ (run_selftests): Call new selftests.
+
+ api: New function gcry_mpi_point_copy.
+ + commit ecf73dafb7aafed0d0f339d07235b58c2113f94c
+ * src/gcrypt.h.in (gcry_mpi_point_copy): New.
+ (mpi_point_copy): New macro.
+ * src/visibility.c (gcry_mpi_point_copy): New.
+ * src/libgcrypt.def, src/libgcrypt.vers: Add function.
+ * mpi/ec.c (_gcry_mpi_point_copy): New.
+ * tests/t-mpi-point.c (set_get_point): Add test.
+
+2017-07-17 Werner Koch <wk@gnupg.org>
+
+ random: Minor fix for getting the rndjent version.
+ + commit 9d99c6b973caa7fdf93b53cf764066214f763803
+ * random/rndjent.c (_gcry_rndjent_get_version): Always set R_ACTIVE.
+ * tests/version.c (test_get_config): Check number of fields for
+ rng-type.
+
+2017-07-07 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Minor fix of mpi_pow.
+ + commit 61b0f52c1cc85bf8c3cac9aba40e28682e4e1b8b
+ * mpi/mpi-pow.c (_gcry_mpi_powm): Allocate size fix.
+
+ mpi: Fix mpi_pow alternative implementation.
+ + commit 66ed4d53789892def7b237756d8a0ab28df9d222
+ * mpi/mpi-pow.c
+ [USE_ALGORITHM_SIMPLE_EXPONENTIATION] (_gcry_mpi_powm): Use
+ mpi_set_cond.
+
+ Fix mpi_pow alternative implementation.
+ + commit 619ebae9847831f43314a95cc3180f4b329b4d3b
+ * mpi/mpi-pow.c [USE_ALGORITHM_SIMPLE_EXPONENTIATION] (_gcry_mpi_powm):
+ Allocate size fix.
+
+2017-07-06 Werner Koch <wk@gnupg.org>
+
+ rsa: Use modern MPI allocation function.
+ + commit 208aba6f9a0475ba049f5a66fe02cf9a6214a887
+ * cipher/rsa.c (secret_core_crt): Use modern function _gcry_mpi_snew.
+
+2017-07-05 Werner Koch <wk@gnupg.org>
+
+ build: Minor API fixes to fix build problems on AIX.
+ + commit 85a9a913da9ecc6b2cd6f743e90e49983251d706
+ * src/gcrypt.h.in (gcry_error_from_errno): Fix return type.
+ * src/visibility.c (gcry_md_extract): Change return type to match the
+ prototype.
+
+ tools: Add left shift to mpicalc.
+ + commit 0d30a4a9791d20c8881b5b12bd44611d9f4274cd
+ * src/mpicalc.c (do_lshift): New.
+ (main): Handle '<'.
+
+2017-07-04 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Fix mpi_set_secure.
+ + commit 5feaf1cc8f22c1f8d19a34850d86fe190f1432e2
+ * mpi/mpiutil.c (mpi_set_secure): Allocate by ->alloced.
+
+2017-06-29 NIIBE Yutaka <gniibe@fsij.org>
+ Werner Koch <wk@gnupg.org>
+
+ rsa: Add exponent blinding.
+ + commit 8725c99ffa41778f382ca97233183bcd687bb0ce
+ * cipher/rsa.c (secret_core_crt): Blind secret D with randomized
+ nonce R for mpi_powm computation.
+
+2017-06-28 NIIBE Yutaka <gniibe@fsij.org>
+
+ Same computation for square and multiply.
+ + commit 78130828e9a140a9de4dafadbc844dbb64cb709a
+ * mpi/mpi-pow.c (_gcry_mpi_powm): Compare msize for max_u_size. Move
+ the assignment to base_u into the loop. Copy content refered by RP to
+ BASE_U except the last of the loop.
+
+2017-06-24 Werner Koch <wk@gnupg.org>
+
+ rsa: Minor refactoring.
+ + commit e6a3dc9900433bbc8ad362a595a3837318c28fa9
+ * cipher/rsa.c (secret): Factor code out to ...
+ (secret_core_std, secret_core_crt): new functions.
+
+2017-06-23 Werner Koch <wk@gnupg.org>
+
+ random: Add missing dependency.
+ + commit d091610377b2c92cf385282b1adfc30fa6cd5c75
+ * random/Makefile.am (EXTRA_librandom_la_SOURCES): Fix file name.
+ (rndjent.o, rndjent.lo): Depend on jitterentropy-base-user.h.
+
+ random: Update jitterentropy to 2.1.0.
+ + commit 8dfae89ecd3e9ae0967586cb38d12ef9111fc7cd
+ * random/rndjent.c (jent_get_nstime, jent_zfree)
+ (jent_fips_enabled, jent_zalloc): Move functions and macros to ...
+ * random/jitterentropy-base-user.h: this file. That files was not
+ used before.
+ * random/Makefile.am (EXTRA_librandom_la_SOURCES): Add
+ jitterentropy-base-user.
+ * random/jitterentropy-base.c: Update to version 2.1.0.
+ * random/jitterentropy.h: Ditto.
+
+2017-06-21 Werner Koch <wk@gnupg.org>
+
+ api: New function gcry_get_config.
+ + commit 27148e60ba15b0cb73b47a75c688fcb48a1a3444
+ * src/misc.c (_gcry_log_info_with_dummy_fp): Remove.
+ * src/global.c (print_config): New arg WHAT. Remove arg FNC and use
+ gpgrt_fprintf directly.
+ (_gcry_get_config): New.
+ (_gcry_vcontrol) <GCRYCTL_PRINT_CONFIG>: Use _gcry_get_config instead
+ of print_config.
+ * src/gcrypt.h.in (gcry_get_config): New.
+ * src/libgcrypt.def, src/libgcrypt.vers: Add new function.
+ * src/visibility.c (gcry_get_config): New.
+ * src/visibility.h: Mark new function.
+
+ * tests/version.c (test_get_config): New.
+ (main): Call new test.
+
+ random: Allow building rndjent on non-x86.
+ + commit c2319464b03e61aaf34ef6d5f4b59b0c0483a373
+ * random/jitterentropy-base.c (jent_version): Uncomment function.
+ * random/rndjent.c: Include time.h
+ (JENT_USES_RDTSC): New.
+ (JENT_USES_GETTIME): New.
+ (JENT_USES_READ_REAL_TIME): New.
+ (jent_get_nstime): Support clock_gettime and AIX specific
+ function. Taken from Stephan Müller's code.
+ (is_rng_available): New.
+ (_gcry_rndjent_dump_stats): Use that function.
+ (_gcry_rndjent_poll): Use that fucntion. Allow an ADD of NULL for an
+ intialize only mode.
+ (_gcry_rndjent_get_version): New.
+
+2017-06-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael-padlock: change asm operands from read-only to read/write.
+ + commit 32b4ab209067f6f08b87b27bc78ec27dc497b708
+ * cipher/rijndael-padlock.c (do_padlock): Change ESI/EDI/ECX to use
+ read/write operands as XCRYPT instruction modifies these registers.
+
+2017-06-16 Werner Koch <wk@gnupg.org>
+
+ random: Make rndjent.c NTG.1 compliant.
+ + commit 82bc052eda5b3897724c7ad11e54f8203e8e88e9
+ * random/rndjent.c (_gcry_rndjent_poll): Hash the retrieved jitter.
+
+ md: Optimize gcry_md_hash_buffers for SHA-256 and SHA-512.
+ + commit e6f90a392a1fd59b19b16f7a2bc7c439ae369d5f
+ * cipher/sha256.c (_gcry_sha256_hash_buffer): New.
+ (_gcry_sha256_hash_buffers): New.
+ * cipher/sha512.c (_gcry_sha512_hash_buffer): New.
+ (_gcry_sha512_hash_buffers): New.
+ * cipher/md.c (_gcry_md_hash_buffer): Optimize for SHA246 and SHA512.
+ (_gcry_md_hash_buffers): Ditto.
+
+ random: Allow building rndjent.c with stats collecting enabled.
+ + commit ee3a74f5539cbc5182ce089994e37c16ce612149
+ * random/rndjent.c: Change license to the one used by jitterentropy.h.
+ (jent_init_statistic): New.
+ (jent_bit_count): New.
+ (jent_statistic_copy_stat): new.
+ (jent_calc_statistic): New.
+
+ New global config option "only-urandom".
+ + commit 8f6082e95f30c1ba68d2de23da90146f87f0c66c
+ * random/rand-internal.h (RANDOM_CONF_ONLY_URANDOM): New.
+ * random/random.c (_gcry_random_read_conf): Add option "only-urandom".
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Implement that
+ option.
+ * tests/keygen.c (main): Add option --no-quick for better manual
+ tests.
+
+ Implement global config file /etc/gcrypt/random.conf.
+ + commit b05a4abc358b204dba343d9cfbd59fdc828c1686
+ * src/hwfeatures.c (my_isascii): Move macro to ...
+ * src/g10lib.h: here.
+ * tests/random.c (main): Dump random stats.
+ * random/random.c (RANDOM_CONF_FILE): New.
+ (_gcry_random_read_conf): New.
+ (_gcry_random_dump_stats): Call rndjent stats.
+ * random/rndjent.c (jent_rng_totalcalls, jent_rng_totalbytes): New.
+ (_gcry_rndjent_poll): Take care of config option disable-jent. Wipe
+ buffer. Bump counters.
+ (_gcry_rndjent_dump_stats): New.
+
+2017-06-14 Werner Koch <wk@gnupg.org>
+
+ random: Add jitter RND based entropy collector.
+ + commit f5e7763ddca59dcd9ac9f2f4d50cb41b14a34a9e
+ * random/rndjent.c: New.
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Use rndjent.
+ * random/rndw32.c (_gcry_rndw32_gather_random): Use rndjent.
+ (slow_gatherer): Fix compiler warning.
+ * random/Makefile.am (librandom_la_SOURCES): Add rndjent.c
+ (EXTRA_librandom_la_SOURCES): Add jitterentropy-base.c and
+ jitterentropy.h.
+ (rndjent.o, rndjent.lo): New rules.
+ * configure.ac: New option --disbale-jent-support
+ (ENABLE_JENT_SUPPORT): New ac-define.
+
+ cipher: New helper function rol64.
+ + commit 6c882fb1fdb6c7cba2215fa7391110d63e24b9dc
+ * cipher/bithelp.h (rol64): New inline functions.
+
+ New hardware feature flag HWF_INTEL_RDTSC.
+ + commit 06f303a633ea2b992259688bef2b023c3f388f73
+ * src/g10lib.h (HWF_INTEL_RDTSC): New.
+ * src/hwfeatures.c (hwflist): Add "intel-rdtsc".
+ * src/hwf-x86.c (detect_x86_gnuc): Get EDX features and test for TSC.
+
+ random: Changes to original Jitter RNG implementation.
+ + commit a44c45675f8b631e11048a540bb1fbb7a022ebb4
+ * random/jitterentropy-base.c: Change double underscore symbols and
+ make all functions static.
+ * random/jitterentropy.h: Likewise.
+
+2017-06-13 Stephan Mueller <smueller@chronox.de>
+
+ random: Add original Jitter RNG implementation.
+ + commit f0ae18ecf48fbe2da0b9fb3f354d0dd3173d91d3
+ * random/jitterentropy-base-user.h: New.
+ * random/jitterentropy-base.c: New.
+ * random/jitterentropy.h: New.
+
+2017-06-08 Werner Koch <wk@gnupg.org>
+
+ build: Fix ChangeLog building for builds from other worktrees.
+ + commit cdfd7ea72a44657f037dd0dbba6e5ea0c2b344aa
+ * Makefile.am (gen-ChangeLog): Test for existance of ".git" regardless
+ on whether it is a file or directory.
+
+2017-06-02 NIIBE Yutaka <gniibe@fsij.org>
+
+ secmem: Fix SEGV and stat calculation.
+ + commit e0958debe1a7db1bec1283115cdc6a14bf3b43e5
+ * src/secmem (init_pool): Care about the header size.
+ (_gcry_secmem_malloc_internal): Likewise.
+ (_gcry_secmem_malloc_internal): Use mb->size for stats.
+
+2017-06-01 Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+
+ ecc: Store EdDSA session key in secure memory.
+ + commit 5a22de904a0a366ae79f03ff1e13a1232a89e26b
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_sign): use mpi_snew to allocate
+ session key.
+
+2017-05-31 Werner Koch <wk@gnupg.org>
+
+ api: Deprecate gcry_md_info.
+ + commit 45c39340c9926c2c5801dbab7609687c41e9ff1f
+
+
+2017-05-30 Werner Koch <wk@gnupg.org>
+
+ mpi: Distribute asm files for aarch64 and asm.
+ + commit c65f9558f12ffa2810538ef616e71b4052dacb81
+ * mpi/aarch64/distfiles: New.
+ * mpi/arm/distfiles: New.
+
+ mpi: Distribute asm definitions for amd64.
+ + commit 87e481137debabb7f989d7fa9b1c21c336e10c98
+ * mpi/amd64/distfiles: Add mpi-asm-defs.h.
+
+2017-05-23 Werner Koch <wk@gnupg.org>
+
+ cipher: Fix compiler warnings.
+ + commit d764c9894013727ff82eb194da6030209c273528
+ * cipher/poly1305.c (poly1305_default_ops): Move to the top. Add
+ prototypes and compile only if USE_SSE2 is not defined.
+ (poly1305_init_ext_ref32): Compile only if USE_SSE2 is not defined.
+ (poly1305_blocks_ref32): Ditto.
+ (poly1305_finish_ext_ref32): Ditto.
+
+ doc: Comment fixes.
+ + commit c1bb3d9fdb6fe5f336af1d5a03fc42bfdc1f8b0b
+
+
+2017-05-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael-ssse3: fix functions calls from assembly blocks.
+ + commit 4cd94994a9abec9b92fa5972869baf089a28fa76
+ * cipher/rijndael-ssse3-amd64.c (PUSH_STACK_PTR, POP_STACK_PTR): New.
+ (vpaes_ssse3_prepare_enc, vpaes_ssse3_prepare_dec)
+ (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption)
+ (do_vpaes_ssse3_enc, do_vpaes_ssse3_dec): Use PUSH_STACK_PTR and
+ POP_STACK_PTR.
+
+ chacha20-armv7-neon: fix to use fast code path when memory is aligned.
+ + commit 68861ae5d3e007d7a39f14ea27dc3dd8ef13ba02
+ * cipher/chacha20-armv7-neon.S (UNALIGNED_LDMIA4): Uncomment
+ instruction for jump to aligned code path.
+
+ Move data in AMD64 assembly to text section.
+ + commit 1a094bc5b2aa730833faf593a931d4e5d7f9ab4d
+ * cipher/camellia-aesni-avx-amd64.S: Move data to .text section to
+ ensure that RIP relative addressing of data will work.
+ * cipher/camellia-aesni-avx2-amd64.S: Ditto.
+ * cipher/chacha20-avx2-amd64.S: Ditto.
+ * cipher/chacha20-ssse3-amd64.S: Ditto.
+ * cipher/des-amd64.S: Ditto.
+ * cipher/serpent-avx2-amd64.S: Ditto.
+ * cipher/sha1-avx-amd64.S: Ditto.
+ * cipher/sha1-avx-bmi2-amd64.S: Ditto.
+ * cipher/sha1-ssse3-amd64.S: Ditto.
+ * cipher/sha256-avx-amd64.S: Ditto.
+ * cipher/sha256-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha256-ssse3-amd64.S: Ditto.
+ * cipher/sha512-avx-amd64.S: Ditto.
+ * cipher/sha512-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha512-ssse3-amd64.S: Ditto.
+
+ cast5-amd64: use 64-bit relocation with large PIC memory model.
+ + commit ff02fca39c83bcf30c79368611ac65e273e77f6c
+ * cipher/cast5-amd64.S [__code_model_large__]
+ (GET_EXTERN_POINTER): New.
+
+2017-05-13 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix building with x86-64 medium and large memory models.
+ + commit 434d4f2af39033fc626044ba9a060da298522293
+ * cipher/cast5-amd64.S [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
+ (GET_EXTERN_POINTER): Load 64-bit address instead of 32-bit.
+ * cipher/rijndael.c (do_encrypt, do_decrypt)
+ [USE_AMD64_ASM && !HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Load
+ table pointer through register instead of generic reference.
+
+2017-04-04 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Simplify mpi_powm.
+ + commit 719468e53133d3bdf12156c5bfdea2bf15f9f6f1
+ * mpi/mpi-pow.c (_gcry_mpi_powm): Simplify the loop.
+
+2017-03-08 Justus Winter <justus@g10code.com>
+
+ build: Use macOS' compatibility macros to enable all features.
+ + commit 654024081cfa103c87bb163b117ea3568171d408
+ * configure.ac: On macOS, use the compatibility macros to expose every
+ feature of the libc. This is the equivalent of _GNU_SOURCE on GNU
+ libc.
+
+2017-02-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add BLAKE2b and BLAKE2s hash algorithms (RFC 7693)
+ + commit 5bd530b8a4624f101b8d42e68f1b28bcc13f4f76
+ * cipher/blake2.c: New.
+ * cipher/Makefile.am: Add 'blake2.c'.
+ * cipher/md.c (digest_list, prepare_macpads): Add BLAKE2.
+ (md_setkey): New.
+ (_gcry_md_setkey): Call 'md_setkey' for non-HMAC md.
+ * configure.ac: Add BLAKE2 digest.
+ * doc/gcrypt.texi: Add BLAKE2.
+ * src/cipher.h (_gcry_blake2_init_with_key)
+ (_gcry_digest_spec_blake2b_512, _gcry_digest_spec_blake2b_384)
+ (_gcry_digest_spec_blake2b_256, _gcry_digest_spec_blake2b_160)
+ (_gcry_digest_spec_blake2s_256, _gcry_digest_spec_blake2s_224)
+ (_gcry_digest_spec_blake2s_160, _gcry_digest_spec_blake2s_128): New.
+ * src/gcrypt.h.in (GCRY_MD_BLAKE2B_512, GCRY_MD_BLAKE2B_384)
+ (GCRY_MD_BLAKE2B_256, GCRY_MD_BLAKE2B_160, GCRY_MD_BLAKE2S_256)
+ (GCRY_MD_BLAKE2S_224, GCRY_MD_BLAKE2S_160, GCRY_MD_BLAKE2S_128): New.
+ * tests/basic.c (check_one_md): Add testing for keyed hashes.
+ (check_digests): Add BLAKE2 test vectors; Add testing for keyed hashes.
+ * tests/blake2b.h: New.
+ * tests/blake2s.h: New.
+ * tests/Makefile.am: Add 'blake2b.h' and 'blake2s.h'.
+
+ Fix building with clang on ARM64/FreeBSD.
+ + commit da213db2c6cda6f57e5853e8c591d69bfa1cfa74
+ * cipher/cipher-gcm-armv8-aarch64-ce.S: Use '.cpu generic+simd+crypto'
+ instead of '.arch armv8-a+crypto'.
+ * cipher/rijndael-armv8-aarch64-ce.S: Ditto.
+ * cipher/sha1-armv8-aarch64-ce.S: Ditto.
+ * cipher/sha256-armv8-aarch64-ce.S: Ditto.
+ * configure.ac (gcry_cv_gcc_inline_asm_aarch64_neon): Ditto.
+ (gcry_cv_gcc_inline_asm_aarch64_crypto): Ditto; and include NEON
+ instructions to crypto instructions check.
+
+2017-02-07 Justus Winter <justus@g10code.com>
+
+ Fix building with a pre C99 compiler.
+ + commit 75d91ffeaf83098ade325bb3b6b2c8a76eb1f6a6
+ * cipher/cipher-cfb.c (_gcry_cipher_cfb8_encrypt): Move the
+ declaration of 'i' out of the loop.
+ (_gcry_cipher_cfb8_decrypt): Likewise.
+
+2017-02-04 Mathias L. Baumann <mathias.baumann_at_sociomantic.com>
+
+ Implement CFB with 8-bit mode.
+ + commit d1ee9a660571ce4a998c9ab2299d4f2419f99127
+ * cipher/cipher-cfb.c (_gcry_cipher_cfb8_encrypt)
+ (_gcry_cipher_cfg8_decrypt): Add 8-bit variants of decrypt/encrypt
+ functions.
+ * cipher/cipher-internal.h (_gcry_cipher_cfb8_encrypt)
+ (_gcry_cipher_cfg8_decrypt): Ditto.
+ * cipher/cipher.c: Adjust code flow to work with GCRY_CIPHER_MODE_CFB8.
+ * tests/basic.c: Add tests for cfb8 with AES and 3DES.
+
+2017-02-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rndhw: add missing "memory" clobbers.
+ + commit c67c728478e8f47b6e8296b643fd35d66d4a1052
+ * random/rndhw.c: (poll_padlock, rdrand_long): Add "memory" to asm
+ clobbers.
+
+ Add UNLIKELY and LIKELY macros.
+ + commit 4b7451d3e8e7b87d8e407fbbd924ad5b13bd0f00
+ * src/g10lib.h (LIKELY, UNLIKELY): New.
+ (gcry_assert): Use LIKELY for assert check.
+ (fast_wipememory2_unaligned_head): Use UNLIKELY for unaligned
+ branching.
+ * cipher/bufhelp.h (buf_cpy, buf_xor, buf_xor_1, buf_xor_2dst)
+ (buf_xor_n_copy_2): Ditto.
+
+ rndhw: avoid type-punching.
+ + commit 37b537600f33fcf8e1c8dc2c658a142fbba44199
+ * random/rndhw.c (rdrand_long, rdrand_nlong): Add 'volatile' for
+ pointer.
+ (poll_drng): Convert buffer to 'unsigned long[]' and make use of DIM
+ macro.
+
+2017-01-28 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ hwf-x86: avoid type-punching.
+ + commit 1407317a6112a23d4fec5827a9d74faef4196f66
+ * src/hwf-x86.c (detect_x86_gnuc): Use union for vendor_id.
+
+ cipher: add explicit blocksize checks to allow better optimization.
+ + commit efa9042f82ffed3d076b8e26ac62d29e00bb756a
+ * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
+ (_gcry_cipher_cbc_decrypt): Add explicit check for cipher blocksize of
+ 64-bit or 128-bit.
+ * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
+ (_gcry_cipher_cfb_decrypt): Ditto.
+ * cipher/cipher-cmac.c (cmac_write, cmac_generate_subkeys)
+ (cmac_final): Ditto.
+ * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Ditto.
+ * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt): Ditto.
+
+ bufhelp: use unaligned dword and qword types for endianess helpers.
+ + commit e7b941c3de9c9b6319298c02f844cc0cadbf8562
+ * cipher/bufhelp.h (BUFHELP_UNALIGNED_ACCESS): New, defined
+ if attributes 'packed', 'aligned' and 'may_alias' are supported.
+ (BUFHELP_FAST_UNALIGNED_ACCESS): Define if have
+ BUFHELP_UNALIGNED_ACCESS.
+
+ rijndael-aesni: fix u128_t strict-aliasing rule breaking.
+ + commit 92b4a29d2453712192ced2d7226abc49679dcb1e
+ * cipher/rijndael-aesni.c (u128_t): Add attributes to tell GCC and clang
+ that casting from 'char *' to 'u128_t *' is ok.
+
+ cipher-xts: fix pointer casting to wrong alignment and aliasing.
+ + commit 4f31d816dcc1e95dc647651e92acbdfed53f5c14
+ * cipher/cipher-xts.c (xts_gfmul_byA, xts_inc128): Use buf_get_le64
+ and buf_put_le64 for accessing data; Change parameter pointers to
+ 'unsigned char *' type.
+ (_gcry_cipher_xts_crypt): Do not cast buffer pointers to 'u64 *'
+ for helper functions.
+
+ crc-intel-pclmul: fix undefined behavior with unaligned access.
+ + commit 55cf1b5588705cab5f45e2817c4aa1d204dc0042
+ * cipher/crc-intel-pclmul.c (u16_unaligned_s): New.
+ (crc32_reflected_less_than_16, crc32_less_than_16): Use
+ 'u16_unaligned_s' for unaligned memory access.
+
+ configure.ac: fix attribute checks.
+ + commit b29b1b9f576f501d4b993be0a751567045274a1a
+ * configure.ac: Add -Werror flag for attribute checks.
+
+ configure.ac: fix may_alias attribute check.
+ + commit 136c8416ea540dd126be3997d94d7063b3aaf577
+ * configure.ac: Test may_alias attribute on type, not on variable.
+
+ bufhelp: add 'may_alias' attribute for properly aligned 'bufhelp_int_t'
+ + commit d1ae52a0e23308f33b78cffeba56005b687f23c0
+ * cipher/bufhelp.h [!BUFHELP_FAST_UNALIGNED_ACCESS]
+ (bufhelp_int_t): Add 'may_alias' attribute.
+
+2017-01-27 Werner Koch <wk@gnupg.org>
+
+ w32: New envvar GCRYPT_RNDW32_DBG.
+ + commit a351fbde8548ce3f57298c618426f043844fbc78
+ * random/rndw32.c (_gcry_rndw32_gather_random): Use getenv to set
+ DEBUG_ME.
+
+2017-01-23 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael-ssse3-amd64: fix building on x32.
+ + commit 39b9302da5d08bd52688d20befe626fee0b6c41d
+ * cipher/rijndael-ssse3-amd64.c: Use 64-bit call instructions
+ with 64-bit registers.
+
+ bufhelp: use 'may_alias' attribute unaligned pointer types.
+ + commit bf9e0b79e620ca2324224893b07522462b125412
+ * configure.ac (gcry_cv_gcc_attribute_may_alias)
+ (HAVE_GCC_ATTRIBUTE_MAY_ALIAS): New check for 'may_alias' attribute.
+ * cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS): Enable only if
+ HAVE_GCC_ATTRIBUTE_MAY_ALIAS is defined.
+ [BUFHELP_FAST_UNALIGNED_ACCESS] (bufhelp_int_t, bufhelp_u32_t)
+ (bufhelp_u64_t): Add 'may_alias' attribute.
+ * src/g10lib.h (fast_wipememory_t): Add HAVE_GCC_ATTRIBUTE_MAY_ALIAS
+ defined check; Add 'may_alias' attribute.
+
+2017-01-18 Werner Koch <wk@gnupg.org>
+
+ random: Call getrandom before select and emitting a progress callback.
+ + commit 623aab8a940ea61afe3fef650ad485a755ed9fe7
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Move the getrandom
+ call before the select.
+
+2017-01-06 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ mpi: amd64: fix too large jump alignment in mpih-rshift.
+ + commit ddcfe31e2425e88b280e7cdaf3f0eaaad8ccc023
+ * mpi/amd64/mpih-rshift.S (_gcry_mpih_rshift): Use 16-byte alignment
+ with 'ALIGN(4)' instead of 256-byte.
+
+ rijndael-ssse3: move assembly functions to separate source-file.
+ + commit 54c57bc49edb5c00e9ed8103cc4837bb72c5e863
+ * cipher/Makefile.am: Add 'rinjdael-ssse3-amd64-asm.S'.
+ * cipher/rinjdael-ssse3-amd64-asm.S: Moved assembly functions
+ here ...
+ * cipher/rinjdael-ssse3-amd64.c: ... from this file.
+ (_gcry_aes_ssse3_enc_preload, _gcry_aes_ssse3_dec_preload)
+ (_gcry_aes_ssse3_shedule_core, _gcry_aes_ssse3_encrypt_core)
+ (_gcry_aes_ssse3_decrypt_core): New.
+ (vpaes_ssse3_prepare_enc, vpaes_ssse3_prepare_dec)
+ (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption)
+ (do_vpaes_ssse3_enc, do_vpaes_ssse3_dec): Update to use external
+ assembly functions; remove 'aes_const_ptr' variable usage.
+ (_gcry_aes_ssse3_encrypt, _gcry_aes_ssse3_decrypt)
+ (_gcry_aes_ssse3_cfb_enc, _gcry_aes_ssse3_cbc_enc)
+ (_gcry_aes_ssse3_ctr_enc, _gcry_aes_ssse3_cfb_dec)
+ (_gcry_aes_ssse3_cbc_dec, ssse3_ocb_enc, ssse3_ocb_dec)
+ (_gcry_aes_ssse3_ocb_auth): Remove 'aes_const_ptr' variable usage.
+ * configure.ac: Add 'rinjdael-ssse3-amd64-asm.lo'.
+
+ Add AVX2/vpgather bulk implementation of Twofish.
+ + commit c59a8ce51ceb9a80169c44ef86a67e95cf8528c3
+ * cipher/Makefile.am: Add 'twofish-avx2-amd64.S'.
+ * cipher/twofish-avx2-amd64.S: New.
+ * cipher/twofish.c (USE_AVX2): New.
+ (TWOFISH_context) [USE_AVX2]: Add 'use_avx2' member.
+ (ASM_FUNC_ABI): New.
+ (twofish_setkey): Add check for AVX2 and fast VPGATHER HW features.
+ (_gcry_twofish_avx2_ctr_enc, _gcry_twofish_avx2_cbc_dec)
+ (_gcry_twofish_avx2_cfb_dec, _gcry_twofish_avx2_ocb_enc)
+ (_gcry_twofish_avx2_ocb_dec, _gcry_twofish_avx2_ocb_auth): New.
+ (_gcry_twofish_ctr_enc, _gcry_twofish_cbc_dec, _gcry_twofish_cfb_dec)
+ (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Add AVX2 bulk
+ handling.
+ (selftest_ctr, selftest_cbc, selftest_cfb): Increase nblocks from
+ 3+X to 16+X.
+ * configure.ac: Add 'twofish-avx2-amd64.lo'.
+ * src/g10lib.h (HWF_INTEL_FAST_VPGATHER): New.
+ * src/hwf-x86.c (detect_x86_gnuc): Add detection for
+ HWF_INTEL_FAST_VPGATHER.
+ * src/hwfeatures.c (HWF_INTEL_FAST_VPGATHER): Add
+ "intel-fast-vpgather" for HWF_INTEL_FAST_VPGATHER.
+
+ Add XTS cipher mode.
+ + commit 232a129b1f915fc54881506e4b07c89cf84932e6
+ * cipher/Makefile.am: Add 'cipher-xts.c'.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add 'bulk.xts_crypt'
+ and 'u_mode.xts' members.
+ (_gcry_cipher_xts_crypt): New prototype.
+ * cipher/cipher-xts.c: New.
+ * cipher/cipher.c (_gcry_cipher_open_internal, cipher_setkey)
+ (cipher_reset, cipher_encrypt, cipher_decrypt): Add XTS mode handling.
+ * doc/gcrypt.texi: Add XTS mode to documentation.
+ * src/gcrypt.h.in (GCRY_CIPHER_MODE_XTS, GCRY_XTS_BLOCK_LEN): New.
+ * tests/basic.c (do_check_xts_cipher, check_xts_cipher): New.
+ (check_bulk_cipher_modes): Add XTS test-vectors.
+ (check_one_cipher_core, check_one_cipher, check_ciphers): Add XTS
+ testing support.
+ (check_cipher_modes): Add XTS test.
+ * tests/bench-slope.c (bench_xts_encrypt_init)
+ (bench_xts_encrypt_do_bench, bench_xts_decrypt_do_bench)
+ (xts_encrypt_ops, xts_decrypt_ops): New.
+ (cipher_modes, cipher_bench_one): Add XTS.
+ * tests/benchmark.c (cipher_bench): Add XTS testing.
+
+2017-01-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael-ssse3: fix counter operand from read-only to read/write.
+ + commit aada604594fd42224d366d3cb98f67fd3b989cd6
+ * cipher/rijndael-ssse3-amd64.c (_gcry_aes_ssse3_ctr_enc): Change
+ 'ctrlow' operand from read-only to read-write.
+
+2017-01-03 Werner Koch <wk@gnupg.org>
+
+ Extend GCRYCTL_PRINT_CONFIG to print compiler version.
+ + commit 98b49695b1ffe3c406ae39a45051b8594f903b9d
+ * src/global.c (print_config): Print version of libgpg-error and used
+ compiler.
+
+ tests: Add option --disable-hwf to the version utility.
+ + commit 3582641469f1c74078f0d758c4d5458cc0ee5649
+ * src/hwfeatures.c (_gcry_disable_hw_feature): Rewrite to allow
+ passing a colon delimited feature set.
+ (parse_hwf_deny_file): Remove unused var I.
+ * tests/version.c (main): Add options --verbose and --disable-hwf.
+
+2016-12-15 Werner Koch <wk@gnupg.org>
+ Nicolas Porcel <nicolasporcel06@gmail.com>
+
+ Fix regression in broken mlock detection.
+ + commit 0a90f87799903a3fb97189ef7cba19e7b3534e1c
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Fix typo EGAIN->EAGAIN.
+
+2016-12-10 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ hwfeatures: add 'all' for disabling all hardware features.
+ + commit c83d0d2a26059cf471d09f5cb8e7fc5d76c4907b
+ * .gitignore: Add 'tests/basic-disable-all-hwf'.
+ * configure.ac: Ditto.
+ * tests/Makefile.am: Ditto.
+ * src/hwfeatures.c (_gcry_disable_hw_feature): Match 'all' for
+ masking all HW features off.
+ (parse_hwf_deny_file): Use '_gcry_disable_hw_feature' for matching.
+ * tests/basic-disable-all-hwf.in: New.
+
+ tests/hashtest-256g: add missing executable extension for Win32.
+ + commit 2b7b227b8a0bd5ff286258bc187782efac180a7e
+ * tests/hashtest-256g.in: Add @EXEEXT@.
+
+ OCB ARM CE: Move ocb_get_l handling to assembly part.
+ + commit 5c418e597f0f20a546d953161695e6caf1f57689
+ * cipher/rijndael-armv8-aarch32-ce.S: Add OCB 'L_{ntz(i)}' calculation.
+ * cipher/rijndael-armv8-aarch64-ce.S: Ditto.
+ * cipher/rijndael-armv8-ce.c (_gcry_aes_ocb_enc_armv8_ce)
+ (_gcry_aes_ocb_dec_armv8_ce, _gcry_aes_ocb_auth_armv8_ce)
+ (ocb_cryt_fn_t): Updated arguments.
+ (_gcry_aes_armv8_ce_ocb_crypt, _gcry_aes_armv8_ce_ocb_auth): Remove
+ 'ocb_get_l' handling and splitting input to 32 block chunks, instead
+ pass full buffers to assembly.
+
+ OCB: Move large L handling from bottom to upper level.
+ + commit 2d2e5286d53e1f62fe040dff4c6e01961f00afe2
+ * cipher/cipher-ocb.c (_gcry_cipher_ocb_get_l): Remove.
+ (ocb_get_L_big): New.
+ (_gcry_cipher_ocb_authenticate): L-big handling done in upper
+ processing loop, so that lower level never sees the case where
+ 'aad_nblocks % 65536 == 0'; Add missing stack burn.
+ (ocb_aad_finalize): Add missing stack burn.
+ (ocb_crypt): L-big handling done in upper processing loop, so that
+ lower level never sees the case where 'data_nblocks % 65536 == 0'.
+ * cipher/cipher-internal.h (_gcry_cipher_ocb_get_l): Remove.
+ (ocb_get_l): Remove 'l_tmp' usage and simplify since input
+ is more limited now, 'N is not multiple of 65536'.
+ * cipher/rijndael-aesni.c (get_l): Remove.
+ (aesni_ocb_enc, aesni_ocb_dec, _gcry_aes_aesni_ocb_auth): Remove
+ l_tmp; Use 'ocb_get_l'.
+ * cipher/rijndael-ssse3-amd64.c (get_l): Remove.
+ (ssse3_ocb_enc, ssse3_ocb_dec, _gcry_aes_ssse3_ocb_auth): Remove
+ l_tmp; Use 'ocb_get_l'.
+ * cipher/camellia-glue.c: Remove OCB l_tmp usage.
+ * cipher/rijndael-armv8-ce.c: Ditto.
+ * cipher/rijndael.c: Ditto.
+ * cipher/serpent.c: Ditto.
+ * cipher/twofish.c: Ditto.
+
+ OCB: remove 'int64_t' usage.
+ + commit 161d339f48c03be7fd0f4249d730f7f1767ef8e4
+ * cipher/cipher-ocb.c (double_block): Use alternative way to generate
+ sign-bit mask, without 'int64_t'.
+
+ random-drbg: use bufhelp function for big-endian store.
+ + commit 0b03b658bebc69a84d87ef13f9b60a27b0c42305
+ * random/random-drbg.c (drbg_cpu_to_be32): Remove.
+ (drbg_ctr_df, drbg_hash_df): Use 'buf_put_be32' instead of
+ 'drbg_cpu_to_be32'.
+
+2016-12-09 Werner Koch <wk@gnupg.org>
+
+ Improve handling of mlock error codes.
+ + commit 618b8978f46f4011c11512fd5f30c15e01652e2e
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Check also for EAGAIN which is a
+ legitimate return code and does not indicate a broken mlock().
+ * src/secmem.c (lock_pool_pages): Test ERR instead of ERRNO which
+ could have been overwritten by cap_from+text et al.
+
+2016-12-08 Stephan Mueller <smueller@chronox.de>
+
+ random: Eliminate unneeded memcpy invocations in the DRBG.
+ + commit 656395ba4cf34f42dda3a120bda3ed1220755a3d
+ * random/random-drbg.c (drbg_hash): Remove arg 'outval' and return a
+ pointer instead.
+ (drbg_instantiate): Reduce size of scratchpad.
+ (drbg_hmac_update): Avoid use of scratch buffers for the hash.
+ (drbg_hmac_generate, drbg_hash_df): Ditto.
+ (drbg_hash_process_addtl): Ditto.
+ (drbg_hash_hashgen): Ditto.
+ (drbg_hash_generate): Ditto.
+
+ random: Add performance improvements for the DRBG.
+ + commit 20886fdcb841b0bf89bb1d44303d42f1804e38cb
+ * random/random-drbg.c (struct drbg_state_ops_s): New function
+ pointers 'crypto_init' and 'crypto-fini'.
+ (struct drbg_state_s): New fields 'priv_data', 'ctr_handle', and
+ 'ctr_null'.
+ (drbg_hash_init, drbg_hash_fini): New.
+ (drbg_hmac_init, drbg_hmac_setkey): New.
+ (drbg_sym_fini, drbg_sym_init, drbg_sym_setkey): New.
+ (drbg_sym_ctr): New.
+ (drbg_ctr_bcc): Set the key.
+ (drbg_ctr_df): Ditto.
+ (drbg_hmac_update): Ditto.
+ (drbg_hmac_generate): Replace drgb_hmac by drbg_hash.
+ (drbg_hash_df): Ditto.
+ (drbg_hash_process_addtl): Ditto.
+ (drbg_hash_hashgen): Ditto.
+ (drbg_ctr_update): Rework.
+ (drbg_ctr_generate): Rework.
+ (drbg_ctr_ops): Init new functions pointers.
+ (drbg_uninstantiate): Call fini function.
+ (drbg_instantiate): Call init function.
+
+ cipher: New function for reading the counter in CTR mode.
+ + commit 227099f179df9dcf083d0ef6be9883c775df0874
+ * cipher/cipher.c (gcry_cipher_getctr): New.
+
+2016-12-07 Werner Koch <wk@gnupg.org>
+
+ Document the overflow pools and add a stupid test case.
+ + commit 95bac312644ad45e486c94c2efd25d0748b9a20b
+ * tests/t-secmem.c (test_secmem_overflow): New func.
+ (main): Disable warning and call new function.
+
+ Implement overflow secmem pools for xmalloc style allocators.
+ + commit b6870cf25c0b1eb9c127a94af8326c446421a472
+ * src/secmem.c (pooldesc_s): Add fields next, cur_alloced, and
+ cur_blocks.
+ (cur_alloced, cur_blocks): Remove vars.
+ (ptr_into_pool_p): Make it inline.
+ (stats_update): Add arg pool and update the new pool specific
+ counters.
+ (_gcry_secmem_malloc_internal): Add arg xhint and allocate overflow
+ pools as needed.
+ (_gcry_secmem_malloc): Pass XHINTS along.
+ (_gcry_secmem_realloc_internal): Ditto.
+ (_gcry_secmem_realloc): Ditto.
+ (_gcry_secmem_free_internal): Take multiple pools in account. Add
+ return value to indicate whether the arg was freed.
+ (_gcry_secmem_free): Add return value to indicate whether the arg was
+ freed.
+ (_gcry_private_is_secure): Take multiple pools in account.
+ (_gcry_secmem_term): Release all pools.
+ (_gcry_secmem_dump_stats): Print stats for all pools.
+ * src/stdmem.c (_gcry_private_free): Replace _gcry_private_is_secure
+ test with a direct call of _gcry_secmem_free to avoid double checking.
+
+ Give the secmem allocators a hint when a xmalloc calls them.
+ + commit b7df907dca4d525f8930c533b763ffce44ceed87
+ * src/secmem.c (_gcry_secmem_malloc): New not yet used arg XHINT.
+ (_gcry_secmem_realloc): Ditto.
+ * src/stdmem.c (_gcry_private_malloc_secure): New arg XHINT to be
+ passed to the secmem functions.
+ (_gcry_private_realloc): Ditto.
+ * src/g10lib.h (GCRY_ALLOC_FLAG_XHINT): New.
+ * src/global.c (do_malloc): Pass this flag as XHINT to the private
+ allocator.
+ (_gcry_malloc_secure): Factor code out to ...
+ (_gcry_malloc_secure_core): this. Add arg XHINT.
+ (_gcry_realloc): Factor code out to ...
+ (_gcry_realloc_core): here. Add arg XHINT.
+ (_gcry_strdup): Factor code out to ...
+ (_gcry_strdup_core): here. Add arg XHINT.
+ (_gcry_xrealloc): Use the core function and pass true for XHINT.
+ (_gcry_xmalloc_secure): Ditto.
+ (_gcry_xstrdup): Ditto.
+
+ tests: New test t-secmem.
+ + commit e366c19b34922c770af82cd035fd815680b29dee
+ * src/secmem.c (_gcry_secmem_dump_stats): Add arg EXTENDED and adjust
+ caller.
+ * src/gcrypt-testapi.h (PRIV_CTL_DUMP_SECMEM_STATS): New.
+ * src/global.c (_gcry_vcontrol): Implement that.
+ * tests/t-secmem.c: New.
+ * tests/Makefile.am (tests_bin): Add that test.
+
+2016-12-06 Werner Koch <wk@gnupg.org>
+
+ Fix compiler warning about possible-NULL-dreference.
+ + commit 995ce697308320c6a52a307f83dc49eeb8d784b4
+ * src/mpi.h (mpi_is_const, mpi_is_immutable): Do check arg before
+ deref-ing. The are only used at places where the arg shall not be NULL.
+
+ Fix possible NULL-deref in gcry_log_debugsxp.
+ + commit 984a97f0750f812f0ad3c343ee6a67560953a504
+ * src/misc.c (_gcry_log_printsxp): Prevent passing NULL to strlen.
+
+ Reorganize code in secmem.c.
+ + commit 603f479a919311f720a05da738150c2192d5e562
+ * src/secmem.c (pooldesc_t): New type to collect information about one
+ pool.
+ (pool_size): Remove. Now a member of pooldesc_t.
+ (pool_okay): Ditto.
+ (pool_is_mmapped): Ditto.
+ (pool): Rename variable ...
+ (mainpool): And change type to pooldesc_t.
+ (ptr_into_pool_p): Add arg 'pool'.
+ (mb_get_next): Ditto.
+ (mb_get_prev): Ditto.
+ (mb_merge): Ditto.
+ (mb_get_new): Ditto.
+ (init_pool): Ditto.
+ (lock_pool): Rename to ...
+ (look_pool_pages: this.
+ (secmem_init): Rename to ...
+ (_gcry_secmem_init_internal): this. Add local var POOL and init with
+ address of MAINPOOL.
+ (_gcry_secmem_malloc_internal): Add local var POOL and init with
+ address of MAINPOOL.
+ (_gcry_private_is_secure): Ditto.
+ (_gcry_secmem_term): Ditto.
+ (_gcry_secmem_dump_stats): Ditto.
+ (_gcry_secmem_free_internal): Ditto. Remove check for NULL arg.
+ (_gcry_secmem_free): Add check for NULL arg before taking the lock.
+ (_gcry_secmem_realloc): Factor most code out to ...
+ (_gcry_secmem_realloc_internal): this.
+
+2016-11-28 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ tests: Add PBKDF2 tests for Stribog512.
+ + commit a0580d446fef648a177ca4ab060d0e449780db84
+ * tests/t-kdf.c (check_pbkdf2): Add Stribog512 test cases from TC26's
+ additions to PKCS#5.
+
+ tests: Add Stribog HMAC tests from TC26ALG.
+ + commit fe6077e6ee8565bfcc91bad14a73e68f45b3c32b
+ * tests/basic.c (check_mac): add HMAC test vectors from TC26ALG document
+ for Stribog.
+
+ cipher: Add Stribog OIDs from TC26 space.
+ + commit ccffacaf6c3abe6120a0898db922981d28ab7af2
+ * cipher/stribog.c (oid_spec_stribog256, oid_spec_stribog512): New.
+
+2016-11-25 Justus Winter <justus@g10code.com>
+
+ tests: Fix memory leak.
+ + commit 5530a8234d703ce9b685f78fb6e951136eb0aeb2
+ * tests/basic.c (check_gost28147_cipher): Free cipher handles.
+
+2016-11-25 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Cast oid argument of gcry_cipher_set_sbox to disable compiler warning.
+ + commit 1a67e3195896704f8b3ba09e3db1214bab834491
+ * src/gcrypt.h.in (gcry_cipher_set_sbox): Cast oid to (void *).
+
+ gost: Rename tc26 s-box from A to Z.
+ + commit dc8ceb8d2dfef949f3afa14fc75f9de8cd07c7ad
+ * cipher/gost-s-box.c (gost_sboxes): Rename TC26_A to TC26_Z as it is
+ the name that ended up in all standards.
+
+ tests: Add test to verify GOST 28147-89 against known results.
+ + commit 4f5c26c73c66daf2e4aff966e43c22b2db7e0138
+ * tests/basic.c (check_gost28147_cipher): new test function.
+
+2016-11-17 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ cipher/gost28147: Fix CryptoPro-B S-BOX.
+ + commit 5ca63c92825453fdb369a97bbc19cb95b49b4296
+ * cipher/gost-s-box.c: CryptoPro_B s-box missed one line, resulting in
+ incorrect encryption/decryption using that s-box. Add missing data.
+
+2016-11-12 Werner Koch <wk@gnupg.org>
+
+ Put blocking calls into Libgpg-error's system call clamp.
+ + commit b829dfe9f0eeff08c956ba3f3a6b559b9d2199dd
+ * src/gcrypt.h.in (GCRYCTL_REINIT_SYSCALL_CLAMP): New.
+ * configure.ac: Require Libgpg-error 1.25. Set version number to
+ 1.8.0.
+ * src/gcrypt-int.h: Remove error code emulation.
+ * src/global.c (pre_syscall_func, post_syscall_func): New.
+ (global_init): Call gpgrt_get_syscall_clamp.
+ (_gcry_vcontrol) <GCRYCTL_REINIT_SYSCALL_CLAMP>: Ditto.
+ (_gcry_pre_syscall, _gcry_post_syscall): New.
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Use the new
+ functions.
+
+2016-11-01 NIIBE Yutaka <gniibe@fsij.org>
+
+ cipher: Fix IDEA cipher for clearing memory.
+ + commit bf6d5b10cb4173826f47ac080506b68bb001acb2
+ * cipher/idea.c (invert_key): Use wipememory, since this kind of memset
+ may be removed by compiler optimization.
+
+2016-10-09 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ GCM: Add bulk processing for ARMv8/AArch64 implementation.
+ + commit bfd732f53a9b5dfe14217a68a0fa289bf6913ec0
+ * cipher/cipher-gcm-armv8-aarch64-ce.S: Add 6 blocks bulk processing.
+
+ GCM: Add bulk processing for ARMv8/AArch32 implementation.
+ + commit 27747921cb1dfced83c5666cd1c474764724c52b
+ * cipher/cipher-gcm-armv8-aarch32-ce.S: Add 4 blocks bulk processing.
+ * tests/basic.c (check_digests): Print correct data length for "?"
+ tests.
+ (check_one_mac): Add large 1000000 bytes tests, when input is "!" or
+ "?".
+ (check_mac): Add "?" tests vectors for HMAC, CMAC, GMAC and POLY1305.
+
+2016-09-11 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add Aarch64 assembly implementation of Twofish.
+ + commit 5418d9ca4c0e087fd6872ad350a996fe74880d86
+ * cipher/Makefile.am: Add 'twofish-aarch64.S'.
+ * cipher/twofish-aarch64.S: New.
+ * cipher/twofish.c: Enable USE_ARM_ASM if __AARCH64EL__ and
+ HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS defined.
+ * configure.ac [host=aarch64]: Add 'twofish-aarch64.lo'.
+
+2016-09-05 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add Aarch64 assembly implementation of Camellia.
+ + commit de73a2e7237ba7c34ce48bb5fb671aa3993de832
+ * cipher/Makefile.am: Add 'camellia-aarch64.S'.
+ * cipher/camellia-aarch64.S: New.
+ * cipher/camellia-glue.c [USE_ARM_ASM][__aarch64__]: Set stack burn
+ size to zero.
+ * cipher/camellia.h: Enable USE_ARM_ASM if __AARCH64EL__ and
+ HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS defined.
+ * configure.ac [host=aarch64]: Add 'rijndael-aarch64.lo'.
+
+ Add ARMv8/AArch64 Crypto Extension implementation of AES.
+ + commit 4cd8d40d698564d24ece2af24546e34c58bf2961
+ * cipher/Makefile.am: Add 'rijndael-armv-aarch64-ce.S'.
+ * cipher/rijndael-armv8-aarch64-ce.S: New.
+ * cipher/rijndael-internal.h (USE_ARM_CE): Enable for ARMv8/AArch64.
+ * configure.ac: Add 'rijndael-armv-aarch64-ce.lo' and
+ 'rijndael-armv8-ce.lo' for ARMv8/AArch64.
+
+ Add ARMv8/AArch64 Crypto Extension implementation of GCM.
+ + commit 0b332c1aef03a735c1fb0df184f74d523deb2f98
+ * cipher/Makefile.am: Add 'cipher-gcm-armv8-aarch64-ce.S'.
+ * cipher/cipher-gcm-armv8-aarch64-ce.S: New.
+ * cipher/cipher-internal.h (GCM_USE_ARM_PMULL): Enable on
+ ARMv8/AArch64.
+
+ Add ARMv8/AArch64 Crypto Extension implementation of SHA-256.
+ + commit 2d4bbc0ad62c54bbdef77799f9db82d344b7219e
+ * cipher/Makefile.am: Add 'sha256-armv8-aarch64-ce.S'.
+ * cipher/sha256-armv8-aarch64-ce.S: New.
+ * cipher/sha256-armv8-aarch32-ce.S: Move round macros to correct
+ section.
+ * cipher/sha256.c (USE_ARM_CE): Enable on ARMv8/AArch64.
+ * configure.ac: Add 'sha256-armv8-aarch64-ce.lo'; Swap places for
+ 'sha512-arm.lo' and 'sha256-armv8-aarch32-ce.lo'.
+
+ Add ARMv8/AArch64 Crypto Extension implementation of SHA-1.
+ + commit e4eb03f56683317c908cb55be727832810dc8c72
+ * cipher/Makefile.am: Add 'sha1-armv8-aarch64-ce.S'.
+ * cipher/sha1-armv8-aarch64-ce.S: New.
+ * cipher/sha1.c (USE_ARM_CE): Enable on ARMv8/AArch64.
+ * configure.ac: Add 'sha1-armv8-aarch64-ce.lo'.
+
+2016-09-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add AArch64 assembly implementation of AES.
+ + commit 595251ad37bf1968261d7e781752513f67525803
+ * cipher/Makefile.am: Add 'rijndael-aarch64.S'.
+ * cipher/rijndael-aarch64.S: New.
+ * cipher/rijndael-internal.h: Enable USE_ARM_ASM if __AARCH64EL__ and
+ HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS defined.
+ * configure.ac (gcry_cv_gcc_aarch64_platform_as_ok): New check.
+ [host=aarch64]: Add 'rijndael-aarch64.lo'.
+
+2016-08-17 Werner Koch <wk@gnupg.org>
+
+ Release 1.7.3.
+ + commit f8241874971478bdcd2bc2082d901d05db7b256d
+ * configure.ac: Set LT version to C21/A1/R3.
+
+ random: Hash continuous areas in the csprng pool.
+ + commit 8dd45ad957b54b939c288a68720137386c7f6501
+ * random/random-csprng.c (mix_pool): Store the first hash at the end
+ of the pool.
+
+ random: Improve the diagram showing the random mixing.
+ + commit 2f62103b4bb6d6f9ce806e01afb7fdc58aa33513
+ * random/random-csprng.c (mix_pool): Use DIGESTLEN instead of 20.
+
+2016-07-19 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ crc-intel-pclmul: split assembly block to ease register pressure.
+ + commit f38199dbc290003898a1799adc367265267784c2
+ * cipher/crc-intel-pclmul.c (crc32_less_than_16): Split inline
+ assembly block handling 4 byte input into multiple blocks.
+
+ rijndael-aesni: split assembly block to ease register pressure.
+ + commit a4d1595a2638db63ac4c73e722c8ba95fdd85ff7
+ * cipher/rijndael-aesni.c (do_aesni_ctr_4): Use single register
+ constraint for passing 'bige_addb' to assembly block; split
+ first inline assembly block into two parts.
+
+2016-07-14 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add ARMv8/AArch32 Crypto Extension implementation of AES.
+ + commit 05a4cecae0c02d2b4ee1cadd9c08115beae3a94a
+ * cipher/Makefile.am: Add 'rijndael-armv8-ce.c' and
+ 'rijndael-armv-aarch32-ce.S'.
+ * cipher/rijndael-armv8-aarch32-ce.S: New.
+ * cipher/rijndael-armv8-ce.c: New.
+ * cipher/rijndael-internal.h (USE_ARM_CE): New.
+ (RIJNDAEL_context_s): Add 'use_arm_ce'.
+ * cipher/rijndael.c [USE_ARM_CE] (_gcry_aes_armv8_ce_setkey)
+ (_gcry_aes_armv8_ce_prepare_decryption)
+ (_gcry_aes_armv8_ce_encrypt, _gcry_aes_armv8_ce_decrypt)
+ (_gcry_aes_armv8_ce_cfb_enc, _gcry_aes_armv8_ce_cbc_enc)
+ (_gcry_aes_armv8_ce_ctr_enc, _gcry_aes_armv8_ce_cfb_dec)
+ (_gcry_aes_armv8_ce_cbc_dec, _gcry_aes_armv8_ce_ocb_crypt)
+ (_gcry_aes_armv8_ce_ocb_auth): New.
+ (do_setkey) [USE_ARM_CE]: Add ARM CE/AES HW feature check and key
+ setup for ARM CE.
+ (prepare_decryption, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec)
+ (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth) [USE_ARM_CE]: Add
+ ARM CE support.
+ * configure.ac: Add 'rijndael-armv8-ce.lo' and
+ 'rijndael-armv8-aarch32-ce.lo'.
+
+ Add ARMv8/AArch32 Crypto Extension implementation of GCM.
+ + commit 962b15470663db11e5c35b86768f1b5d8e600017
+ * cipher/Makefile.am: Add 'cipher-gcm-armv8-aarch32-ce.S'.
+ * cipher/cipher-gcm-armv8-aarch32-ce.S: New.
+ * cipher/cipher-gcm.c [GCM_USE_ARM_PMULL]
+ (_gcry_ghash_setup_armv8_ce_pmull, _gcry_ghash_armv8_ce_pmull)
+ (ghash_setup_armv8_ce_pmull, ghash_armv8_ce_pmull): New.
+ (setupM) [GCM_USE_ARM_PMULL]: Enable ARM PMULL implementation if
+ HWF_ARM_PULL HW feature flag is enabled.
+ * cipher/cipher-gcm.h (GCM_USE_ARM_PMULL): New.
+
+ Add ARMv8/AArch32 Crypto Extension implemenation of SHA-256.
+ + commit 34c64eb03178fbfd34190148fec5a189df2b8f83
+ * cipher/Makefile.am: Add 'sha256-armv8-aarch32-ce.S'.
+ * cipher/sha256-armv8-aarch32-ce.S: New.
+ * cipher/sha256.c (USE_ARM_CE): New.
+ (sha256_init, sha224_init): Check features for HWF_ARM_SHA1.
+ [USE_ARM_CE] (_gcry_sha256_transform_armv8_ce): New.
+ (transform) [USE_ARM_CE]: Use ARMv8 CE implementation if HW supports.
+ (SHA256_CONTEXT): Add 'use_arm_ce'.
+ * configure.ac: Add 'sha256-armv8-aarch32-ce.lo'.
+
+ Add ARMv8/AArch32 Crypto Extension implementation of SHA-1.
+ + commit 3d6334f8d94c2a4df10eed203ae928298a4332ef
+ * cipher/Makefile.am: Add 'sha1-armv8-aarch32-ce.S'.
+ * cipher/sha1-armv7-neon.S (_gcry_sha1_transform_armv7_neon): Add
+ missing size.
+ * cipher/sha1-armv8-aarch32-ce.S: New.
+ * cipher/sha1.c (USE_ARM_CE): New.
+ (sha1_init): Check features for HWF_ARM_SHA1.
+ [USE_ARM_CE] (_gcry_sha1_transform_armv8_ce): New.
+ (transform) [USE_ARM_CE]: Use ARMv8 CE implementation if HW supports
+ it.
+ * cipher/sha1.h (SHA1_CONTEXT): Add 'use_arm_ce'.
+ * configure.ac: Add 'sha1-armv8-aarch32-ce.lo'.
+
+ Add HW feature check for ARMv8 AArch64 and crypto extensions.
+ + commit eee78f6e1fbce7d54c43fb7efc5aa8be9f52755f
+ * configure.ac: Add '--disable-arm-crypto-support'; enable hwf-arm
+ module on 64-bit ARM.
+ (armcryptosupport, gcry_cv_gcc_inline_aarch32_crypto)
+ (gcry_cv_inline_asm_aarch64_neon)
+ (gcry_cv_gcc_inline_asm_aarch64_crypto): New.
+ * src/g10lib.h (HWF_ARM_AES, HWF_ARM_SHA1, HWF_ARM_SHA2)
+ (HWF_ARM_PMULL): New.
+ * src/hwf-arm.c [__aarch64__]: Enable building in AArch64 mode.
+ (feature_map_s): New.
+ [__arm__] (AT_HWCAP, AT_HWCAP2, HWCAP2_AES, HWCAP2_PMULL)
+ (HWCAP2_SHA1, HWCAP2_SHA2, arm_features): New.
+ [__aarch64__] (AT_HWCAP, AT_HWCAP2, HWCAP_ASIMD, HWCAP_AES)
+ (HWCAP_PMULL, HWCAP_SHA1, HWCAP_SHA2, arm_features): New.
+ (get_hwcap): Add reading of 'AT_HWCAP2'; Change auxv use
+ 'unsigned long'.
+ (detect_arm_at_hwcap): Add mapping of HWCAP/HWCAP2 to HWF flags.
+ (detect_arm_proc_cpuinfo): Add mapping of CPU features to HWF flags.
+ (_gcry_hwf_detect_arm): Use __ARM_NEON instead of legacy __ARM_NEON__.
+ * src/hwfeatures.c (hwflist): Add 'arm-aes', 'arm-sha1', 'arm-sha2'
+ and 'arm-pmull'.
+
+2016-07-14 Werner Koch <wk@gnupg.org>
+
+ Release 1.7.2.
+ + commit be0bec7d9208b2f2d2ffce9cc2ca6154853e7e59
+ * configure.ac: Set LT version to C21/A1/R2.
+ * Makefile.am (distcheck-hook): New.
+
+2016-07-13 Werner Koch <wk@gnupg.org>
+
+ build: Update config.{guess,sub} to {2016-05-15,2016-06-20}.
+ + commit e535ea1bdc42309553007d60599d3147b8defe93
+ * build-aux/config.guess: Update.
+ * build-aux/config.sub: Update.
+
+2016-07-08 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix unaligned accesses with ldm/stm in ChaCha20 and Poly1305 ARM/NEON.
+ + commit 1111d311fd6452abd4080d1072c75ddb1b5a3dd1
+ * cipher/chacha20-armv7-neon.S (UNALIGNED_STMIA8)
+ (UNALIGNED_LDMIA4): New.
+ (_gcry_chacha20_armv7_neon_blocks): Use new helper macros instead of
+ ldm/stm instructions directly.
+ * cipher/poly1305-armv7-neon.S (UNALIGNED_LDMIA2)
+ (UNALIGNED_LDMIA4): New.
+ (_gcry_poly1305_armv7_neon_init_ext, _gcry_poly1305_armv7_neon_blocks)
+ (_gcry_poly1305_armv7_neon_finish_ext): Use new helper macros instead
+ of ldm instruction directly.
+
+2016-07-03 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ bench-slope: add unaligned buffer mode.
+ + commit 496790940753226f96b731a43d950bd268acd97a
+ * tests/bench-slope.c (unaligned_mode): New.
+ (do_slope_benchmark): Unalign buffer if in unaligned mode enabled.
+ (print_help, main): Add '--unaligned' parameter.
+
+2016-07-01 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix static build.
+ + commit cb79630ec567a5f2e03e5f863cda168faa7b8cc8
+ * tests/pubkey.c (_gcry_pk_util_get_nbits): Make function 'static'.
+
+2016-06-30 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Disallow encryption/decryption if key is not set.
+ + commit 07de9858032826f5a7b08c372f6bcc73bbb503eb
+ * cipher/cipher.c (cipher_encrypt, cipher_decrypt): If mode is not
+ NONE, make sure that key is set.
+ * cipher/cipher-ccm.c (_gcry_cipher_ccm_set_nonce): Do not clear
+ 'marks.key' when reseting state.
+
+ Avoid unaligned accesses with ARM ldm/stm instructions.
+ + commit a6158a01a4d81a5d862e1e0a60bfd6063443311d
+ * cipher/rijndael-arm.S: Remove __ARM_FEATURE_UNALIGNED ifdefs, always
+ compile with unaligned load/store code paths.
+ * cipher/sha512-arm.S: Ditto.
+
+ Fix non-PIC reference in PIC for poly1305/ARMv7-NEON.
+ + commit a09126242a51c4ea4564b0f70b808e4f27fe5a91
+ * cipher/poly1305-armv7-neon.S (GET_DATA_POINTER): New.
+ (_gcry_poly1305_armv7_neon_init_ext): Use GET_DATA_POINTER.
+
+ Fix wrong CPU feature #ifdef for SHA1/AVX.
+ + commit 4a983e3bef58b9d056517e25e0ab10b72d12ceba
+ * cipher/sha1-avx-amd64.S: Check for HAVE_GCC_INLINE_ASM_AVX instead of
+ HAVE_GCC_INLINE_ASM_AVX2 & HAVE_GCC_INLINE_ASM_BMI2.
+
+2016-06-30 Werner Koch <wk@gnupg.org>
+
+ random: Remove debug message about not supported getrandom syscall.
+ + commit 6965515c73632a088fb126a4a55e95121671fa98
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Remove log_debug
+ for getrandom error ENOSYS.
+
+2016-06-27 Werner Koch <wk@gnupg.org>
+
+ tests: Do not test SHAKE128 et al with gcry_md_hash_buffer.
+ + commit 4d634a098742ff425b324e9f2a67b9f62de09744
+ * tests/benchmark.c (md_bench): Do not test variable lengths algos
+ with the gcry_md_hash_buffer.
+
+ md: Improve diagnostic when using SHAKE128 with gcry_md_hash_buffer.
+ + commit ae26edf4b60359bfa5fe3a27b2c24b336e7ec35c
+ * cipher/md.c (md_read): Detect missing read function.
+ (_gcry_md_hash_buffers): Return an error.
+
+2016-06-25 Werner Koch <wk@gnupg.org>
+
+ ecc: Fix memory leak.
+ + commit 7a7f7c147f888367dfee6093d26bfeaf750efc3a
+ * cipher/ecc.c (ecc_check_secret_key): Do not init point if already
+ set.
+
+ doc: Update yat2m.
+ + commit 1feb01940062a74c27230434fc3babdddca8caf4
+ * doc/yat2m.c: Update from Libgpg-error
+
+ tests: Add attributes to helper functions.
+ + commit c870cb5d385c1d6e1e28ca481cf9cf44b3bfeea9
+ * tests/t-common.h (die, fail, info): Add attributes.
+ * tests/random.c (die, inf): Ditto.
+ * tests/pubkey.c (die, fail, info): Add attributes.
+ * tests/fipsdrv.c (die): Add attribute.
+ (main): Take care of missing --key,--iv,--dt options.
+
+ Improve robustness and help lint.
+ + commit 5a5b055b81ee60a22a846bdf2031516b1c24df98
+ * cipher/rsa.c (rsa_encrypt): Check for !DATA.
+ * cipher/md.c (search_oid): Check early for !OID.
+ (md_copy): Use gpg_err_code_from_syserror. Replace chains of if(!err)
+ tests.
+ * cipher/cipher.c (search_oid): Check early for !OID.
+ * src/misc.c (do_printhex): Allow for BUFFER==NULL even with LENGTH>0.
+ * mpi/mpicoder.c (onecompl): Allow for A==NULL to help static
+ analyzers.
+
+ cipher: Improve fatal error message for bad use of gcry_md_read.
+ + commit 3f98b1e92d5afd720d7cea5b4e8295c5018bf9ac
+ * cipher/md.c (md_read): Use _gcry_fatal_error instead of BUG.
+
+2016-06-16 Niibe Yutaka <gniibe@fsij.org>
+
+ ecc: Default cofactor 1 for PUBKEY_FLAG_PARAM.
+ + commit b0b70e7fe37b1bf13ec0bfc8effcb5c7f5db6b7d
+ * cipher/ecc.c (ecc_check_secret_key, ecc_sign, ecc_verify)
+ (ecc_encrypt_raw, ecc_decrypt_raw, compute_keygrip): Set default
+ cofactor as 1, when not specified.
+
+ ecc: Default cofactor 1 for PUBKEY_FLAG_PARAM.
+ + commit 0f3a069211d8d24a61aa0dc2cc6c4ef04cc4fab7
+ * cipher/ecc.c (ecc_check_secret_key, ecc_sign, ecc_verify)
+ (ecc_encrypt_raw, ecc_decrypt_raw, compute_keygrip): Set default
+ cofactor as 1, when not specified.
+
+2016-06-15 Werner Koch <wk@gnupg.org>
+
+ Release 1.7.1.
+ + commit 48aa6d6602564d6ba0cef10cf08f9fb0c59b3223
+
+
+ doc: Describe envvars.
+ + commit c3173bbe3f1a9c73f81a538dd49ccfa0447bfcdc
+ * doc/gcrypt.texi: Add chapter Configuration.
+
+ random: Change names of debug envvars.
+ + commit 131b4f0634cee0e5c47d2250c59f51127b10f7b3
+ * random/rndunix.c (start_gatherer): Change GNUPG_RNDUNIX_DBG to
+ GCRYPT_RNDUNIX_DBG, change GNUPG_RNDUNIX_DBG to GCRYPT_RNDUNIX_DBG.
+ * random/rndw32.c (registry_poll): Change GNUPG_RNDW32_NOPERF to
+ GCRYPT_RNDW32_NOPERF.
+
+2016-06-14 Werner Koch <wk@gnupg.org>
+
+ cipher: Assign OIDs to the Serpent cipher.
+ + commit e13a6a1ba53127af602713d0c2aaa85c94b3cd7e
+ * cipher/serpent.c (serpent128_oids, serpent192_oids)
+ (serpent256_oids): New. Add them to the specs blow.
+ (serpent128_aliases): Add "SERPENT-128".
+ (serpent256_aliases, serpent192_aliases): New.
+
+ cipher: Assign OIDs to the Serpent cipher.
+ + commit 6cc2100c00a65dff07b095dea7b32cb5c5cd96d4
+ * cipher/serpent.c (serpent128_oids, serpent192_oids)
+ (serpent256_oids): New. Add them to the specs blow.
+ (serpent128_aliases): Add "SERPENT-128".
+ (serpent256_aliases, serpent192_aliases): New.
+
+2016-06-08 Werner Koch <wk@gnupg.org>
+
+ rsa: Implement blinding also for signing.
+ + commit 1f769e3e8442bae2f1f73c656920bb2df70153c0
+ * cipher/rsa.c (rsa_decrypt): Factor blinding code out to ...
+ (secret_blinded): new.
+ (rsa_sign): Use blinding by default.
+
+ random: Remove debug output for getrandom(2) output.
+ + commit 52cdfb1960808aaad48b5a501bbce0e3141c3961
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Remove debug
+ output.
+
+ Fix gcc portability on Solaris 9 SPARC boxes.
+ + commit b766ea14ad1c27d6160531b200cc70aaa479c6dc
+ * mpi/longlong.h: Use __sparcv8 as alias for __sparc_v8__.
+
+2016-06-08 Jérémie Courrèges-Anglas <jca@wxcvbn.org>
+
+ Check for compiler SSE4.1 support in PCLMUL CRC code.
+ + commit dc76313308c184c92eb78452b503405b90fc7ebd
+ * cipher/crc-intel-pclmul.c: Build PCLMUL CRC implementation only if
+ compiler supports PCLMUL *and* SSE4.1
+ * cipher/crc.c: Ditto
+ * configure.ac (sse41support, gcry_cv_gcc_inline_asm_sse41): New.
+
+2016-06-08 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix ecc_verify for cofactor support.
+ + commit bd39eb9fba47dc8500c83769a679cc8b683d6c6e
+ * cipher/ecc.c (ecc_verify): Fix the argument for cofactor "h".
+
+2016-06-08 Werner Koch <wk@gnupg.org>
+
+ random: Try to use getrandom() instead of /dev/urandom (Linux only).
+ + commit c05837211e5221d3f56146865e823bc20b4ff1ab
+ * configure.ac: Check for syscall.
+ * random/rndlinux.c [HAVE_SYSCALL]: Include sys/syscall.h.
+ (_gcry_rndlinux_gather_random): Use getrandom is available.
+
+2016-06-03 Werner Koch <wk@gnupg.org>
+
+ rsa: Implement blinding also for signing.
+ + commit ef6e4d004b10f5740bcd2125fb70e199dd21e3e8
+ * cipher/rsa.c (rsa_decrypt): Factor blinding code out to ...
+ (secret_blinded): new.
+ (rsa_sign): Use blinding by default.
+
+ random: Remove debug output for getrandom(2) output.
+ + commit 82df6c63a72fdd969c3923523f10d0cef5713ac7
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Remove debug
+ output.
+
+2016-06-02 Werner Koch <wk@gnupg.org>
+
+ Fix gcc portability on Solaris 9 SPARC boxes.
+ + commit 4121f15122501d8946f1589b303d1f7949c15e30
+ * mpi/longlong.h: Use __sparcv8 as alias for __sparc_v8__.
+
+2016-05-28 Jérémie Courrèges-Anglas <jca@wxcvbn.org>
+
+ Check for compiler SSE4.1 support in PCLMUL CRC code.
+ + commit 3e8074ecd3a534e8bd7f11cf17f0b22d252584c8
+ * cipher/crc-intel-pclmul.c: Build PCLMUL CRC implementation only if
+ compiler supports PCLMUL *and* SSE4.1
+ * cipher/crc.c: Ditto
+ * configure.ac (sse41support, gcry_cv_gcc_inline_asm_sse41): New.
+
+2016-05-06 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix ecc_verify for cofactor support.
+ + commit c7430aa752232aa690c5d8f16575a345442ad8d7
+ * cipher/ecc.c (ecc_verify): Fix the argument for cofactor "h".
+
+2016-04-26 Werner Koch <wk@gnupg.org>
+
+ random: Try to use getrandom() instead of /dev/urandom (Linux only).
+ + commit ee5a32226a7ca4ab067864e06623fc11a1768900
+ * configure.ac: Check for syscall.
+ * random/rndlinux.c [HAVE_SYSCALL]: Include sys/syscall.h.
+ (_gcry_rndlinux_gather_random): Use getrandom is available.
+
+2016-04-19 Werner Koch <wk@gnupg.org>
+
+ asm fix for older gcc versions.
+ + commit caa9d14c914bf6116ec3f773a322a94e2be0c0fb
+ * cipher/crc-intel-pclmul.c: Remove extra trailing colon from
+ asm statements.
+
+ asm fix for older gcc versions.
+ + commit 4545372c0f8dd35aef2a7abc12b588ed1a4a0363
+ * cipher/crc-intel-pclmul.c: Remove extra trailing colon from
+ asm statements.
+
+2016-04-15 Werner Koch <wk@gnupg.org>
+
+ Release 1.7.0.
+ + commit 795f9cb090c776658a0e3117996e3fb7e2ebd94a
+
+
+2016-04-14 Werner Koch <wk@gnupg.org>
+
+ tests: Add test vectors for 256 GiB test of SHA3-256.
+ + commit 1737c546dc7268fa9edcd4a23b7439c56d37ee4f
+ * tests/hashtest.c: Add new test vectros.
+
+2016-04-14 Justus Winter <justus@g10code.com>
+
+ src: Improve S-expression parsing.
+ + commit 491586bc7f7b9edc6b78331a77e653543983c9e4
+ * src/sexp.c (do_vsexp_sscan): Return an error if a closing
+ parenthesis is encountered with no matching opening parenthesis.
+
+2016-04-14 Werner Koch <wk@gnupg.org>
+
+ cipher: Add constant for 8 bit CFB mode.
+ + commit 47c6a1f88eb763e9baa394e34d873b761abcebbe
+ * src/gcrypt.h.in (GCRY_CIPHER_MODE_CFB8): New.
+ * tests/basic.c (check_cfb_cipher): Prepare for CFB-8 tests.
+
+ tests: Add a new test for S-expressions.
+ + commit 88c6b98350193abbdcfb227754979b0c097ee09c
+ * tests/t-sexp.c (compare_to_canon): New.
+ (back_and_forth_one): Add another test.
+
+2016-04-13 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix corner cases for X25519.
+ + commit 8472b71812e71c69d66e2fcc02a6e21b66755f8b
+ * cipher/ecc.c (ecc_encrypt_raw): For invalid input, returns
+ GPG_ERR_INV_DATA instead of aborting with log_fatal. For X25519,
+ it's not an error, thus, let it return 0.
+ (ecc_decrypt_raw): Use the flag PUBKEY_FLAG_DJB_TWEAK to distinguish
+ X25519, not by the name of the curve.
+ (ecc_decrypt_raw): For invalid input, returns GPG_ERR_INV_DATA instead
+ of aborting with log_fatal. For X25519, it's not an error by its
+ definition, but we deliberately let it return the error to detect
+ looks-like-encrypted-message.
+ * tests/t-cv25519.c: Add points to record the issue.
+
+2016-04-12 Werner Koch <wk@gnupg.org>
+
+ cipher: Buffer data from gcry_cipher_authenticate in OCB mode.
+ + commit b6d2a25a275a35ec4dbd53ecaa9ea0ed7aa99c7b
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add fields
+ aad_leftover and aad_nleftover to u_mode.ocb.
+ * cipher/cipher-ocb.c (_gcry_cipher_ocb_set_nonce): Clear
+ aad_nleftover.
+ (_gcry_cipher_ocb_authenticate): Add buffering and facor some code out
+ to ...
+ (ocb_aad_finalize): new.
+ (compute_tag_if_needed): Call new function.
+ * tests/basic.c (check_ocb_cipher_splitaad): New.
+ (check_ocb_cipher): Call new function.
+ (main): Also call check_cipher_modes with --ciper-modes.
+
+2016-04-12 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix X25519 computation on Curve25519.
+ + commit ee7e1a0e835f8ffcfbcba2a44abab8632db8fed5
+ * cipher/ecc.c (ecc_encrypt_raw): Tweak of bits when
+ PUBKEY_FLAG_DJB_TWEAK is enabled.
+ (ecc_decrypt_raw): Return 0 when PUBKEY_FLAG_DJB_TWEAK is enabled.
+ * tests/t-cv25519.c (test_cv): Update by using gcry_pk_encrypt.
+
+ ecc: Fix initialization of EC context.
+ + commit 7fbdb99b8c56360adfd1fb4e7f4c95e0f8aa34de
+ * cipher/ecc.c (test_ecdh_only_keys, ecc_generate)
+ (ecc_check_secret_key, ecc_encrypt_raw, ecc_decrypt_raw): Initialize
+ by _gcry_mpi_ec_p_internal_new should carry FLAGS.
+
+2016-04-06 Werner Koch <wk@gnupg.org>
+
+ Allow building with configure option --enable-hmac-binary-check.
+ + commit 65c63144b66392f40b991684789b8b793248e3ba
+ * src/Makefile.am (mpicalc_LDADD): Add DL_LIBS.
+ * src/fips.c (check_binary_integrity): Allow use of hmac256 output.
+ * src/hmac256.c (main): Add option --stdkey
+
+2016-04-06 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Positive values in computation.
+ + commit 6f386ceae86a058e26294f744750f1ed2a95e604
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Make sure
+ coefficients A and B are positive.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_recover_x): For negation, do
+ "P - T" instead of "-T", so that the result will be positive.
+ (_gcry_ecc_eddsa_verify): Likewise.
+ * cipher/ecc.c (ecc_check_secret_key): Use _gcry_ecc_fill_in_curve
+ instead of _gcry_ecc_update_curve_param.
+ * mpi/ec.c (ec_subm): Make sure the result will be positive.
+ (dup_point_edwards, sub_points_edwards, _gcry_mpi_ec_curve_point): Use
+ mpi_sub instead of mpi_neg.
+ (add_points_edwards): Simply use ec_addm.
+ * tests/t-mpi-point.c (test_curve): Define curves with positive
+ coefficients.
+
+2016-04-01 Werner Koch <wk@gnupg.org>
+
+ mpi: Explicitly limit the allowed input length for gcry_mpi_scan.
+ + commit 862cf19a119427dd7ee7959a36c72d905f5ea5ca
+ * mpi/mpicoder.c (MAX_EXTERN_SCAN_BYTES): New.
+ (mpi_fromstr): Check against this limit.
+ (_gcry_mpi_scan): Ditto.
+ * tests/mpitests.c (test_maxsize): New.
+ (main): Cal that test.
+
+2016-03-31 Werner Koch <wk@gnupg.org>
+
+ cipher: Remove specialized rmd160 functions.
+ + commit fcce0cb6e8af70b134c6ecc3f56afa07a7d31f27
+ * cipher/rmd160.c: Replace rmd.h by hash-common.h.
+ (RMD160_CONTEXT): Move from rmd.h to here.
+ (_gcry_rmd160_init): Remove.
+ (_gcry_rmd160_mixblock): Remove.
+ (_gcry_rmd160_hash_buffer): Use rmd160_init directly.
+ * cipher/md.c: Remove rmd.h which was not actually used.
+ * cipher/rmd.h: Remove.
+ * cipher/Makefile.am (libcipher_la_SOURCES): Remove rmd.h.
+ * configure.ac (USE_RMD160): Allow to build without RMD160.
+
+ random: Replace RMD160 by SHA-1 for mixing the CSPRNG pool.
+ + commit a9cbe2d1f6a517a831517da8bc1d29e3e0b2c0c0
+ * cipher/sha1.c (_gcry_sha1_mixblock_init): New.
+ (_gcry_sha1_mixblock): New.
+ * random/random-csprng.c: Include sha1.h instead of rmd.h.
+ (mix_pool): Use SHA-1 instead of RIPE-MD-160 for mixing.
+
+ cipher: Move sha1 context definition to a separate file.
+ + commit 142a479a484cb4e84d0561be9b05b44dac9e6fe2
+ * cipher/sha1.c: Replace hash-common.h by sha1.h.
+ (SHA1_CONTEXT): Move to ...
+ * cipher/sha1.h: new. Always include all flags.
+ * cipher/Makefile.am (libcipher_la_SOURCES): Add sha1.h.
+
+2016-03-29 Werner Koch <wk@gnupg.org>
+
+ tests: Fix buffer overflow in bench-slope.
+ + commit 48ee918400762281bec5b6fc218a9f0d119aac7c
+ * tests/bench-slope.c (bench_print_result_std): Remove wrong use of
+ strncat.
+
+2016-03-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ cipher: GCM: check that length of supplied tag is one of valid lengths.
+ + commit f2260e3a2e962ac80124ef938e54041bbea08561
+ * cipher/cipher-gcm.c (is_tag_length_valid): New.
+ (_gcry_cipher_gcm_tag): Check that 'outbuflen' has valid tag length.
+ * tests/basic.c (_check_gcm_cipher): Add test-vectors with different
+ valid tag lengths and negative test vectors with invalid lengths.
+
+2016-03-24 Peter Wu <peter@lekensteyn.nl>
+
+ cipher: Fix memleaks in (self)tests.
+ + commit 4a064e2a06fe737f344d1dfd8a45cc4c2abbe4c9
+ * cipher/dsa.c: Release memory for MPI and sexp structures.
+ * cipher/ecc.c: Release memory for sexp structure.
+ * tests/keygen.c: Likewise.
+
+ Mark constant MPIs as non-leaked.
+ + commit 470a30db241a2d567739ef2adb2a2ee64992d8b4
+ * mpi/mpiutil.c: Mark "constant" MPIs as explicitly leaked.
+
+2016-03-23 Werner Koch <wk@gnupg.org>
+
+ Add new control GCRYCTL_GET_TAGLEN for use with gcry_cipher_info.
+ + commit fea5971488e049f902d7912df22a945bc755ad6d
+ * src/gcrypt.h.in (GCRYCTL_GET_TAGLEN): New.
+ * cipher/cipher.c (_gcry_cipher_info): Add GCRYCTL_GET_TAGLEN feature.
+
+ * tests/basic.c (_check_gcm_cipher): Check that new feature.
+ (_check_poly1305_cipher): Ditto.
+ (check_ccm_cipher): Ditto.
+ (do_check_ocb_cipher): Ditto.
+ (check_ctr_cipher): Add negative test for new feature.
+
+ cipher: Avoid NULL-segv in GCM mode if a key has not been set.
+ + commit e709d86fe596a4bcf235799468947c13ae657d78
+ * cipher/cipher-gcm.c (_gcry_cipher_gcm_encrypt): Check that GHASH_FN
+ has been initialized.
+ (_gcry_cipher_gcm_decrypt): Ditto.
+ (_gcry_cipher_gcm_authenticate): Ditto.
+ (_gcry_cipher_gcm_initiv): Ditto.
+ (_gcry_cipher_gcm_tag): Ditto.
+
+ cipher: Check length of supplied tag in _gcry_cipher_poly1305_check_tag.
+ + commit 7c9c82feecf94a455c66d9c38576f36c9c4b484c
+ * cipher/cipher-poly1305.c (_gcry_cipher_poly1305_tag): Check that the
+ provided tag length matches the actual tag length.
+
+2016-03-23 Peter Wu <peter@lekensteyn.nl>
+
+ Fix buffer overrun in gettag for Poly1305.
+ + commit 6821e1bd94969106a70e3de17b86f6e6181f4e59
+ * cipher/cipher-poly1305.c: copy a fixed length instead of the
+ user-supplied number.
+
+2016-03-23 Werner Koch <wk@gnupg.org>
+
+ cipher: Check length of supplied tag in _gcry_cipher_gcm_check_tag.
+ + commit 15785bc9fb1787554bf371945ecb191830c15bfd
+ * cipher/cipher-gcm.c (_gcry_cipher_gcm_tag): Check that the provided
+ tag length matches the actual tag length. Avoid gratuitous return
+ statements.
+
+2016-03-23 Peter Wu <peter@lekensteyn.nl>
+
+ Fix buffer overrun in gettag for GCM.
+ + commit d3d7bdf8215275b3b20690dfde3f43dbe25b6f85
+ * cipher/cipher-gcm.c: copy a fixed length instead of the user-supplied
+ number.
+
+2016-03-22 Werner Koch <wk@gnupg.org>
+
+ tests: Add options --fips to keygen for manual tests.
+ + commit d328095dd4de83b839d9d8c4bdbeec0956971016
+ (main): Add option --fips.
+ * tests/keygen.c (check_rsa_keys): Create an 2048 bit key with e=65539
+ because that is valid in FIPS mode. Check that key generation fails
+ for too short keys in FIPS mode.
+ (check_ecc_keys): Check that key generation fails for Ed25519 keys in
+ FIPS mode.
+
+2016-03-22 Tomáš Mráz <tmraz@redhat.com>
+
+ rsa: Add FIPS 186-4 compliant RSA probable prime key generator.
+ + commit 5f9b3c2e220ca6d0eaff32324a973ef67933a844
+ * cipher/primegen.c (_gcry_fips186_4_prime_check): New.
+ * cipher/rsa.c (generate_fips): New.
+ (rsa_generate): Use new function in fips mode or with test-parms.
+
+ * tests/keygen.c (check_rsa_keys): Add test using e=65539.
+
+2016-03-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix ARM NEON support detection on ARMv6 target.
+ + commit 583919d70763671ed9feeaa14e1f66379aff88cc
+ * configure.ac (gcry_cv_gcc_inline_asm_neon): Use '.arm' directive
+ instead of '.thumb'.
+
+2016-03-18 Werner Koch <wk@gnupg.org>
+
+ Always require a 64 bit integer type.
+ + commit 897ccd21b7221982806b5c024518f4e989152f14
+ * configure.ac (available_digests_64): Merge with available_digests.
+ (available_kdfs_64): Merge with available_kdfs.
+ <64 bit datatype test>: Bail out if no such type is available.
+ * src/types.h: Emit #error if no u64 can be defined.
+ (PROPERLY_ALIGNED_TYPE): Always add u64 type.
+ * cipher/bithelp.h: Remove all code paths which handle the
+ case of !HAVE_U64_TYPEDEF.
+ * cipher/bufhelp.h: Ditto.
+ * cipher/cipher-ccm.c: Ditto.
+ * cipher/cipher-gcm.c: Ditto.
+ * cipher/cipher-internal.h: Ditto.
+ * cipher/cipher.c: Ditto.
+ * cipher/hash-common.h: Ditto.
+ * cipher/md.c: Ditto.
+ * cipher/poly1305.c: Ditto.
+ * cipher/scrypt.c: Ditto.
+ * cipher/tiger.c: Ditto.
+ * src/g10lib.h: Ditto.
+ * tests/basic.c: Ditto.
+ * tests/bench-slope.c: Ditto.
+ * tests/benchmark.c: Ditto.
+
+2016-03-18 Vitezslav Cizek <vcizek@suse.com>
+
+ tests: Fix testsuite after the FIPS adjustments.
+ + commit 9ecc2690181ba0bb44f66451a7dce2fc19965793
+ * tests/benchmark.c (ecc_bench): Avoid not approved curves in FIPS.
+ * tests/curves.c (check_get_params): Skip Brainpool curves in FIPS.
+ * tests/keygen.c (check_dsa_keys): Generate 2048 and 3072 bits keys.
+ (check_ecc_keys): Skip Ed25519 in FIPS mode.
+ * tests/random.c (main): Don't switch DRBG in FIPS mode.
+ * tests/t-ed25519.c (main): Ed25519 isn't supported in FIPS mode.
+ * tests/t-kdf.c (check_openpgp): Skip vectors using md5 in FIPS.
+ * tests/t-mpi-point.c (context_param): Skip P-192 and Ed25519 in FIPS.
+ (main): Skip math tests that use P-192 and Ed25519 in FIPS.
+
+ tests: Add new --pss option to fipsdrv.
+ + commit 1a02d741cacc3b57fe3d6ffebd794d53a60c9e97
+ * tests/fipsdrv.c (run_rsa_sign, run_rsa_verify): Set salt-length
+ to 0 for PSS.
+
+ cipher: Add option to specify salt length for PSS verification.
+ + commit 0bd8137e68c201b6c2290710e348aaf57efa2b2e
+ * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Check for
+ salt-length token.
+
+ tests: Add support for RSA keygen tests to fipsdrv.
+ + commit 2e139456369a834cf87d983da4f61241fda76efe
+ * tests/fipsdrv.c (run_rsa_keygen): New.
+ (main): Support RSA keygen and RSA keygen KAT tests.
+
+ tests: Fixes for RSA testsuite in FIPS mode.
+ + commit c690230af5a66b809f8f6fbab1a6262a5ba078cb
+ * tests/basic.c (get_keys_new): Generate 2048 bit key.
+ * tests/benchmark.c (rsa_bench): Skip keys of lengths different
+ than 2048 and 3072 in FIPS mode.
+ * tests/keygen.c (check_rsa_keys): Failure if short keys can be
+ generated in FIPS mode.
+ (check_dsa_keys): Ditto for DSA keys.
+ * tests/pubkey.c (check_x931_derived_key): Skip keys < 2048 in FIPS.
+
+ rsa: Use 2048 bit RSA keys for selftest.
+ + commit 78cec8b4754fdf774edb2d575000cb3e972e244c
+ * cipher/rsa.c (selftests_rsa): Use 2048 bit keys.
+ (selftest_encr_1024): Replaced by selftest_encr_2048.
+ (selftest_sign_1024): Replaced by selftest_sign_2048.
+ (selftest_encr_2048): Add check against known ciphertext.
+ (selftest_sign_2048): Add check against known signature.
+ (selftest_sign_2048): Free SIG_MPI.
+ * tests/pubkey.c (get_keys_new): Generate 2048 bit keys.
+
+ Disable non-allowed algorithms in FIPS mode.
+ + commit ce1cbe16992a7340edcf8e6576973e3508267640
+ * cipher/cipher.c (_gcry_cipher_init),
+ * cipher/mac.c (_gcry_mac_init),
+ * cipher/md.c (_gcry_md_init),
+ * cipher/pubkey.c (_gcry_pk_init): In the FIPS mode, disable all the
+ non-allowed ciphers.
+ * cipher/md5.c: Mark MD5 as not allowed in FIPS.
+ * src/g10lib.h (_gcry_mac_init): New.
+ * src/global.c (global_init): Call the new _gcry_mac_init.
+ * tests/basic.c (check_ciphers): Fix a typo.
+
+2016-03-18 Werner Koch <wk@gnupg.org>
+
+ kdf: Make PBKDF2 check work on all platforms.
+ + commit c478cf175887c84dc071c4f73a7667603b354789
+ * cipher/kdf.c (_gcry_kdf_pkdf2): Chnage DKLEN to unsigned long.
+
+2016-03-18 Vitezslav Cizek <vcizek@suse.com>
+
+ kdf: Add upper bound for derived key length in PBKDF2.
+ + commit 0f741b0704bac5c0e2d2a0c2b34b44b35baa76d6
+ * cipher/kdf.c (_gcry_kdf_pkdf2): limit dkLen.
+
+ ecc: ECDSA adjustments for FIPS 186-4.
+ + commit a242e3d9185e6e2dc13902ea9331131755bbba01
+ * cipher/ecc-curves.c: Unmark curve P-192 for FIPS.
+ * cipher/ecc.c: Add ECDSA self test.
+ * cipher/pubkey-util.c (_gcry_pk_util_init_encoding_ctx): Use SHA-2
+ in FIPS mode.
+ * tests/fipsdrv.c: Add support for ECDSA signatures.
+
+2016-03-18 Werner Koch <wk@gnupg.org>
+
+ dsa: Make regression tests work.
+ + commit e40939b2141306238cc30a340b867b60fa4dc2a3
+ * cipher/dsa.c (sample_secret_key_1024): Comment out unused constant.
+ (ogenerate_fips186): Make it work with use-fips183-2 flag.
+ * cipher/primegen.c (_gcry_generate_fips186_3_prime): Use Emacs
+ standard comment out format.
+ * tests/fips186-dsa.c (check_dsa_gen_186_3): New dummy fucntion.
+ (main): Call it.
+ (main): Compare against current version.
+ * tests/pubkey.c (get_dsa_key_fips186_new): Create 2048 bit key.
+ (get_dsa_key_fips186_with_seed_new): Ditto.
+ (get_dsa_key_fips186_with_domain_new): Comment out.
+ (check_run): Do not call that function.
+
+2016-03-18 Vitezslav Cizek <vcizek@suse.com>
+
+ dsa: Adjustments to conform with FIPS 186-4.
+ + commit 80e9f95e6f419daa765e4876c858e3e36e808897
+ * cipher/dsa.c (generate_fips186): FIPS 186-4 adjustments.
+ * cipher/primegen.c (_gcry_generate_fips186_3_prime): Fix incorrect
+ buflen passed to _gcry_mpi_scan.
+
+2016-03-16 Justus Winter <justus@g10code.com>
+
+ Update documentation for 'gcry_sexp_extract_param'.
+ + commit 4051fe7fec6ffdc7a2f5c3856665478866991ee7
+ * doc/gcrypt.texi (gcry_sexp_extract_param): Mention that all MIPs
+ must be set to NULL first, and document how the function behaves in
+ case of errors.
+ * src/sexp.c (_gcry_sexp_extract_param): Likewise.
+ * src/gcrypt.h.in (gcry_sexp_extract_param): Copy the comment from
+ '_gcry_sexp_extract_param'.
+
+ cipher: Update comment.
+ + commit fcf4358a7a7ba8d32bf385ea99ced5f47cbd3ae2
+ * cipher/ecc.c (ecc_get_nbits): Update comment to reflect the fact
+ that a curve parameter can be given.
+
+2016-03-12 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add Intel PCLMUL implementations of CRC algorithms.
+ + commit 5d601dd57fcb41aa2015ab655fd6fc51537da667
+ * cipher/Makefile.am: Add 'crc-intel-pclmul.c'.
+ * cipher/crc-intel-pclmul.c: New.
+ * cipher/crc.c (USE_INTEL_PCLMUL): New macro.
+ (CRC_CONTEXT) [USE_INTEL_PCLMUL]: Add 'use_pclmul'.
+ [USE_INTEL_PCLMUL] (_gcry_crc32_intel_pclmul)
+ (gcry_crc24rfc2440_intel_pclmul): New.
+ (crc32_init, crc32rfc1510_init, crc24rfc2440_init)
+ [USE_INTEL_PCLMUL]: Select PCLMUL implementation if SSE4.1 and PCLMUL
+ HW features detected.
+ (crc32_write, crc24rfc2440_write) [USE_INTEL_PCLMUL]: Use PCLMUL
+ implementation if enabled.
+ (crc24_init): Document storage format of 24-bit CRC.
+ (crc24_next4): Use only 'data' for last table look-up.
+ * configure.ac: Add 'crc-intel-pclmul.lo'.
+ * src/g10lib.h (HWF_*, HWF_INTEL_SSE4_1): Update HWF flags to include
+ Intel SSE4.1.
+ * src/hwf-x86.c (detect_x86_gnuc): Add SSE4.1 detection.
+ * src/hwfeatures.c (hwflist): Add 'intel-sse4.1'.
+ * tests/basic.c (fillbuf_count): New.
+ (check_one_md): Add "?" check (million byte data-set with byte pattern
+ 0x00,0x01,0x02,...); Test all buffer sizes 1 to 1000, for "!" and "?"
+ checks.
+ (check_one_md_multi): Skip "?".
+ (check_digests): Add "?" test-vectors for MD5, SHA1, SHA224, SHA256,
+ SHA384, SHA512, SHA3_224, SHA3_256, SHA3_384, SHA3_512, RIPEMD160,
+ CRC32, CRC32_RFC1510, CRC24_RFC2440, TIGER1 and WHIRLPOOL; Add "!"
+ test-vectors for CRC32_RFC1510 and CRC24_RFC2440.
+
+2016-02-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Normalize EXPO for mpi_powm.
+ + commit fdfa5bfefdde316688a3c8021bd3528c5273b0f4
+ * mpi/mpi-pow.c (gcry_mpi_powm): Normalize EP.
+
+2016-02-22 Andreas Metzler <ametzler@bebt.de>
+
+ Do not ship generated header file in tarball.
+ + commit 2b40a16333fa75f1cee85ab901a5aa9cff845a92
+ * src/Makefile.am: Move gcrypt.h from include_HEADERS to
+ nodist_include_HEADERS to prevent inclusion in release tarball.
+ This could break out-of-tree-builds because the potentially outdated
+ src/gcrypt.h was not updated but was in the compiler search path.
+
+2016-02-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix building random-drbg for Win32/64.
+ + commit 531b25aa94c58f6d2168a9537c8cea6c53d7bbe0
+ * random/random-drbg.c: Remove include for sys/types.h and asm/types.h.
+ (DRBG_PREDICTION_RESIST, DRBG_CTRAES, DRBG_CTRSERPENT, DRBG_CTRTWOFISH)
+ (DRBG_HASHSHA1, DRBG_HASHSHA224, DRBG_HASHSHA256, DRBG_HASHSHA384)
+ (DRBG_HASHSHA512, DRBG_HMAC, DRBG_SYM128, DRBG_SYM192)
+ (DRBG_SYM256): Change 'u_int32_t' to 'u32'.
+ (drbg_get_entropy) [USE_RNDUNIX, USE_RNDW32]: Fix parameters
+ 'drbg_read_cb' and 'len'.
+
+2016-02-20 Werner Koch <wk@gnupg.org>
+
+ tests: Do not test DRBG_REINIT from "make check"
+ + commit 839d12c221430b60db5e0d6fbb107f22e0a6837f
+ * tests/random.c (main): Run check_drbg_reinit only if the envvar
+ GCRYPT_IN_REGRESSION_TEST is set.
+
+ doc: Fix possible dependency problem.
+ + commit 3b57e5a1ba68e26dcaea38b763287fddba9b6b7c
+ * doc/Makefile.am (gcrypt.texi): Use the right traget.
+
+2016-02-19 Stephan Mueller <smueller@chronox.de>
+
+ random: Remove ANSI X9.31 DRNG.
+ + commit e9b692d25d1c149b5417b70e18f2ce173bc25b6d
+ * random-fips.c: Remove.
+
+2016-02-19 Werner Koch <wk@gnupg.org>
+
+ random: Add a test case for DRBG_REINIT.
+ + commit 934ba2ae5a95a96fdbb3b935b51ba43df66f11df
+ * src/global.c (_gcry_vcontrol) <DRBG_REINIT>: Test for FIPS RNG.
+ * tests/random.c (check_drbg_reinit): New.
+ (main): Call new test.
+
+ random: Allow DRBG_REINIT before initialization.
+ + commit 7cdbd6e6a3cf1ee366b981e148d41b1187a6fdcf
+ * random/random-drbg.c (DRBG_DEFAULT_TYPE): New.
+ (_drbg_init_internal): Set the default type if no type has been set
+ before.
+ (_gcry_rngdrbg_inititialize): Pass 0 for flags to use the default.
+
+ Add new private header gcrypt-testapi.h.
+ + commit 744b030cff61fd25114b0b25394c62782c153343
+ * src/gcrypt-testapi.h: New.
+ * src/Makefile.am (libgcrypt_la_SOURCES): Add new file.
+ * random/random.h: Include gcrypt-testapi.h.
+ (struct gcry_drbg_test_vector) : Move to gcrypt-testapi.h.
+ * src/global.c: Include gcrypt-testapi.h.
+ (_gcry_vcontrol): Use PRIV_CTL_* constants instead of 58, 59, 60, 61.
+ * cipher/cipher.c: Include gcrypt-testapi.h.
+ (_gcry_cipher_ctl): Use PRIV_CIPHERCTL_ constants instead of 61, 62.
+ * tests/fipsdrv.c: Include gcrypt-testapi.h. Remove definition of
+ PRIV_CTL_ constants and replace their use by the new PRIV_CIPHERCTL_
+ constants.
+ * tests/t-lock.c: Include gcrypt-testapi.h. Remove
+ PRIV_CTL_EXTERNAL_LOCK_TEST and EXTERNAL_LOCK_TEST_ constants.
+
+ * random/random-drbg.c (gcry_rngdrbg_cavs_test): Rename to ...
+ (_gcry_rngdrbg_cavs_test): this.
+ (gcry_rngdrbg_healthcheck_one): Rename to ...
+ (_gcry_rngdrbg_healthcheck_one): this.
+
+ random: Make the DRBG C-90 clean and use a flag string.
+ + commit 95f1db3affb9f5b8a2c814c211d4a02b30446c15
+ * random/random.h (struct gcry_drbg_test_vector): Rename "flags" to
+ "flagstr" and turn it into a string.
+ * random/random-drbg.c (drbg_test_pr, drbg_test_nopr): Replace use of
+ designated initializers. Use a string for the flags.
+ (gcry_rngdrbg_cavs_test): Parse the flag string into a flag value.
+ (drbg_healthcheck_sanity): Ditto.
+
+ random: Symbol name cleanup for random-drbg.c.
+ + commit 85ed07790552297586258e8fe09b546eee357a8b
+ * random/random-drbg.c: Rename all static objects and macros from
+ "gcry_drbg" to "drbg".
+ (drbg_string_t): New typedef.
+ (drbg_gen_t): New typedef.
+ (drbg_state_t): New typedef. Replace all "struct drbg_state_s *" by
+ this.
+ (_drbg_init_internal): Replace xcalloc_secure by xtrycalloc_secure so
+ that an error if actually returned.
+ (gcry_rngdrbg_cavs_test): Ditto.
+ (gcry_drbg_healthcheck_sanity): Ditto.
+
+ random: Use our symbol name pattern also for drbg functions.
+ + commit 7cf3c929331133e4381dbceac53d3addd921c929
+ * random/random-drbg.c: Rename global functions from _gcry_drbg_*
+ to _gcry_rngdrbg_*.
+ * random/random.c: Adjust for this change.
+ * src/global.c: Ditto.
+
+ random: Rename drbg.c to random-drbg.c.
+ + commit e49b3f2c10e012509b5930c0df4d6df378d3b9f4
+ * random/drbg.c: Rename to ...
+ * random/random-drbg.c: this.
+ * random/Makefile.am (librandom_la_SOURCES): Adjust accordingly.
+
+ random: Remove the new API introduced by the new DRBG.
+ + commit dfac2b13d0068b2b1b420d77e9771a49964b81c1
+ * src/gcrypt.h.in (struct gcry_drbg_gen): Move to random/drbg.c.
+ (struct gcry_drbg_string): Ditto.
+ (gcry_drbg_string_fill): Ditto.
+ (gcry_randomize_drbg): Remove.
+ * random/drbg.c (parse_flag_string): New.
+ (_gcry_drbg_reinit): Change the way the arguments are passed.
+ * src/global.c (_gcry_vcontrol) <GCRYCTL_DRBG_REINIT>: Change calling
+ convention.
+
+ Add helper function _gcry_strtokenize.
+ + commit 4e134b6e77f558730ec1eceb6b816b0bcfd845e9
+ * src/misc.c (_gcry_strtokenize): New.
+
+2016-02-18 Werner Koch <wk@gnupg.org>
+
+ random: Remove DRBG constants from the public API.
+ + commit fd13372fa9069d3a72947ea59c57e33637c936bf
+ * src/gcrypt.h.in (GCRY_DRBG_): Remove all new flags to ...
+ * random/drbg.c: here.
+
+2016-02-18 Stephan Mueller <smueller@chronox.de>
+
+ random: Add SP800-90A DRBG.
+ + commit ed57fed6de1465e02ec5e3bc0affeabdd35e2eb7
+ * random/drbg.c: New.
+ * random/random.c (_gcry_random_initialize): Replace rngfips init by
+ drbg init.
+ (__gcry_random_close_fds): Likewise.
+ (_gcry_random_dump_stats): Likewise.
+ (_gcry_random_is_faked): Likewise.
+ (do_randomize): Likewise.
+ (_gcry_random_selftest): Likewise.
+ (_gcry_create_nonce): Replace rngfips_create_noce by drbg_randomize.
+ (_gcry_random_init_external_test): Remove.
+ (_gcry_random_run_external_test): Remove.
+ (_gcry_random_deinit_external_test): Remove.
+ * random/random.h (struct gcry_drbg_test_vector): New.
+ * src/gcrypt.h.in (struct gcry_drbg_gen): New.
+ (struct gcry_drbg_string): New.
+ (gcry_drbg_string_fill): New.
+ (gcry_randomize_drbg): New.
+ (GCRY_DRBG_): Lots of new macros.
+ * src/global.c (_gcry_vcontrol) <Init external random test>: Turn into
+ a nop.
+ (_gcry_vcontrol) <Deinit external random test>: Ditto.
+ (_gcry_vcontrol) <Run external random test>: Change.
+ (_gcry_vcontrol) <GCRYCTL_DRBG_REINIT>: New.
+
+2016-02-13 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ bufhelp: disable unaligned memory accesses on powerpc.
+ + commit 1da793d089b65ac8c1ead65dacb6b8699f5b6e69
+ * cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS): Disable for
+ __powerpc__ and __powerpc64__.
+
+2016-02-12 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Not validate input point for Curve25519.
+ + commit 7a019bc7ecdbdfdef51094e090ce95e062da9b64
+ * cipher/ecc.c (ecc_decrypt_raw): Curve25519 is an exception.
+
+2016-02-10 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix memory leaks on error.
+ + commit b12dd550fd6af687ef95c584d0d8366c34965cc8
+ * cipher/ecc.c (ecc_decrypt_raw): Go to leave to release memory.
+ * mpi/ec.c (_gcry_mpi_ec_curve_point): Likewise.
+
+2016-02-09 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: input validation on ECDH.
+ + commit 23b72901f8a5ba9a78485b235c7a917fbc8faae0
+ * cipher/ecc.c (ecc_decrypt_raw): Validate the point.
+
+2016-02-08 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add ARM assembly implementation of SHA-512.
+ + commit 8353884bc65c820d5bcacaf1ac23cdee72091a09
+ * cipher/Makefile.am: Add 'sha512-arm.S'.
+ * cipher/sha512-arm.S: New.
+ * cipher/sha512.c (USE_ARM_ASM): New.
+ (_gcry_sha512_transform_arm): New.
+ (transform) [USE_ARM_ASM]: Use ARM assembly implementation instead of
+ generic.
+ * configure.ac: Add 'sha512-arm.lo'.
+
+2016-02-03 NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: Add a test for Curve25519.
+ + commit b8b3361504950689ef1e779fb3357cecf8a9f739
+ * tests/Makefile.am (tests_bin): Add t-cv25519.
+ * tests/t-cv25519.c: New.
+
+2016-02-02 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix Curve25519 for data by older implementation.
+ + commit 6cb6df9dddac6ad246002b83c2ce0aaa0ecf30e5
+ * cipher/ecc-misc.c (gcry_ecc_mont_decodepoint): Fix code path for
+ short length data.
+
+ ecc: more fix of Curve25519.
+ + commit 48ba5a50066611ecacea850ced13f5cb66097a81
+ * cipher/ecc-misc.c (gcry_ecc_mont_decodepoint): Fix removing of
+ prefix. Clear the MSB, according to RFC7748.
+
+ ecc: Fix ECDH of Curve25519.
+ + commit a2f9afcd7fcdafd5951498b07f34957f9766dce9
+ * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Fix calc of NBITS
+ and prefix detection.
+ * cipher/ecc.c (ecc_generate): Use NBITS instead of CTX->NBITS.
+ (ecc_encrypt_raw): Use NBITS from curve instead of from P.
+ Fix rawmpilen calculation.
+ (ecc_decrypt_raw): Likewise. Add debug output.
+
+2016-01-29 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Improve performance of generic SHA256 implementation.
+ + commit f3e51161036382429c3491c7c881f36c0a653c7b
+ * cipher/sha256.c (R): Let caller do variable shuffling.
+ (Chro, Maj, Sum0, Sum1): Convert from inline functions to macros.
+ (W, I): New.
+ (transform_blk): Unroll round loop; inline message expansion to rounds
+ to make message expansion buffer smaller.
+
+2016-01-28 Werner Koch <wk@gnupg.org>
+
+ ecc: New API function gcry_mpi_ec_decode_point.
+ + commit 2cf2ca7bb9741ac86e8aa92d8f03b1c5f5938897
+ * mpi/ec.c (_gcry_mpi_ec_decode_point): New.
+ * cipher/ecc-common.h: Move two prototypes to ...
+ * src/ec-context.h: here.
+ * src/gcrypt.h.in (gcry_mpi_ec_decode_point): New.
+ * src/libgcrypt.def (gcry_mpi_ec_decode_point): New.
+ * src/libgcrypt.vers (gcry_mpi_ec_decode_point): New.
+ * src/visibility.c (gcry_mpi_ec_decode_point): New.
+ * src/visibility.h: Add new function.
+
+2016-01-15 Werner Koch <wk@gnupg.org>
+
+ Fix build problem for rndegd.c.
+ + commit 191c2e4fe2dc0e00f61aa44e011a9596887e6ce1
+ * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Test all RND modules.
+ * random/rndegd.c (_gcry_rndegd_connect_socket)
+ (my_make_filename): Use functions with '_' prefix.
+
+ random: Fix possible AIX problem with sysconf in rndunix.
+ + commit 6303b0e83856ee89374b447e710f0ab2af61caec
+ * random/rndunix.c [HAVE_STDINT_H]: Include stdint.h.
+ (start_gatherer): Detect misbehaving sysconf.
+
+2015-12-27 Werner Koch <wk@gnupg.org>
+
+ random: Take at max 25% from RDRAND.
+ + commit 5a78e7f15e0dd96a8bf64e2bb142880bf8ea6965
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Change use of
+ RDRAND from 50% to 25%.
+
+2015-12-07 Justus Winter <justus@g10code.com>
+
+ cipher: Improve error handling.
+ + commit b9c02fbeb7efb7d0593b33485fb30c298291cf80
+ * cipher/ecc.c (ecc_decrypt_raw): Improve error handling.
+
+ cipher: Initialize 'flags'.
+ + commit ca06cd7f77acb317c2649c58918908f043dfe6bd
+ * cipher/ecc.c (ecc_encrypt_raw): Initialize 'flags' to 0.
+
+2015-12-05 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: CHANGE point representation of Curve25519.
+ + commit dd3d06e7f113cf7608f060ceb043262efd0b0c9d
+ * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Decode point with
+ the prefix 0x40, additional 0x00 by MPI handling, and shorter octets
+ by MPI normalization.
+ * cipher/ecc.c (ecc_generate, ecc_encrypt_raw, ecc_decrypt_raw):
+ Always add the prefix 0x40.
+
+2015-12-03 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ chacha20: fix alignment of self-test context.
+ + commit 6fadbcd088e2af3e48407b95d8d0c2a8b7ad6c38
+ * cipher/chacha20.c (selftest): Ensure 16-byte alignment for chacha20
+ context structure.
+
+ salsa20: fix alignment of self-test context.
+ + commit 2cba0dbda462237f55438d4199eccd10c5e3f6ca
+ * cipher/salsa20.c (selftest): Ensure 16-byte alignment for salsa20
+ context structure.
+
+2015-12-02 Justus Winter <justus@g10code.com>
+
+ random: Drop fake entropy gathering function.
+ + commit d421ac283ec46d0ecaf6278ba4c24843f65fb2fa
+ * random/random-csprng.c (faked_rng): Drop variable.
+ (gather_faked): Drop prototype and function.
+ (initialize): Drop fallback code.
+ (_gcry_rngcsprng_is_faked): Change accordingly.
+
+ random: Fix selection of entropy gathering function.
+ + commit 468a5796ffb1a7776db4004d534376c1b981d740
+ * random/random-csprng.c (getfnc_gather_random): Do return NULL if no
+ usable entropy gathering function is found. The callsite then
+ installs the fake gather function.
+
+2015-11-26 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: minor improvement of point multiplication.
+ + commit 3658afd09c3b03b4398aaa5748387220c93b1a94
+ * mpi/ec.c (_gcry_mpi_ec_mul_point): Move ec_subm out of the loop.
+
+2015-11-25 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Constant-time multiplication for Weierstrass curve.
+ + commit 88e1358962e902ff1cbec8d53ba3eee46407851a
+ * mpi/ec.c (_gcry_mpi_ec_mul_point): Use simple left-to-right binary
+ method for Weierstrass curve when SCALAR is secure.
+
+ mpi: fix gcry_mpi_swap_cond.
+ + commit f88adee3e1f3e2de7d63f92f90bfb3078afd3b4f
+ * mpi/mpiutil.c (_gcry_mpi_swap_cond): Relax the condition.
+
+ mpi: Fix mpi_set_cond and mpi_swap_cond .
+ + commit 8ad682c412047d3b9196950709dbd7bd14ac8732
+ * mpi/mpiutil.c (_gcry_mpi_set_cond, _gcry_mpi_swap_cond): Don't use
+ the operator of !!, but assume SET/SWAP is 0 or 1.
+
+ ecc: multiplication of Edwards curve to be constant-time.
+ + commit 295b1c3540752af4fc5e6f41480e6db215222fba
+ * mpi/ec.c (_gcry_mpi_ec_mul_point): Use point_swap_cond.
+
+ ecc: Add point_resize and point_swap_cond.
+ + commit b6015176df6bfae107ac82f9baa29ef2c175c9f9
+ * mpi/ec.c (point_resize, point_swap_cond): New.
+ (_gcry_mpi_ec_mul_point): Use point_resize and point_swap_cond.
+
+2015-11-18 Justus Winter <justus@g10code.com>
+
+ cipher: Fix error handling.
+ + commit 940dc8adc034a6c6c38742f6bfd7d837a532d537
+ * cipher/cipher.c (_gcry_cipher_ctl): Fix error handling.
+
+2015-11-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Tweak Keccak for small speed-up.
+ + commit 6571a64331839d7d952292163afbf34c8bef62e0
+ * cipher/keccak_permute_32.h (KECCAK_F1600_PERMUTE_FUNC_NAME): Track
+ rounds with round constant pointer instead of separate round counter.
+ * cipher/keccak_permute_64.h (KECCAK_F1600_PERMUTE_FUNC_NAME): Ditto.
+ (KECCAK_F1600_ABSORB_FUNC_NAME): Tweak lanes pointer increment for bulk
+ absorb loops.
+
+ Update license information for CRC.
+ + commit 15ea0acf8bb0aa307eccc23024a0bd7878fb8080
+ * LICENSES: Remove 'Simple permissive' and 'IETF permissive' licenses
+ for 'cipher/crc.c' as result of rewrite of CRC implementations.
+
+2015-11-17 Justus Winter <justus@g10code.com>
+
+ Fix typos found using codespell.
+ + commit 0e395944b70c7a92a6437f6bcc14f287c19ce9de
+ * cipher/cipher-ocb.c: Fix typos.
+ * cipher/des.c: Likewise.
+ * cipher/dsa-common.c: Likewise.
+ * cipher/ecc.c: Likewise.
+ * cipher/pubkey.c: Likewise.
+ * cipher/rsa-common.c: Likewise.
+ * cipher/scrypt.c: Likewise.
+ * random/random-csprng.c: Likewise.
+ * random/random-fips.c: Likewise.
+ * random/rndw32.c: Likewise.
+ * src/cipher-proto.h: Likewise.
+ * src/context.c: Likewise.
+ * src/fips.c: Likewise.
+ * src/gcrypt.h.in: Likewise.
+ * src/global.c: Likewise.
+ * src/sexp.c: Likewise.
+ * tests/mpitests.c: Likewise.
+ * tests/t-lock.c: Likewise.
+
+2015-11-01 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Improve performance of Tiger hash algorithms.
+ + commit 89fa74d6b3e58cd4fcd6e0939a35e46cbaca2ea0
+ * cipher/tiger.c (tiger_round, pass, key_schedule): Convert functions
+ to macros.
+ (transform_blk): Pass variable names instead of pointers to 'pass'.
+
+ Add ARMv7/NEON implementation of Keccak.
+ + commit a1cc7bb15473a2419b24ecac765ae0ce5989a13b
+ * cipher/Makefile.am: Add 'keccak-armv7-neon.S'.
+ * cipher/keccak-armv7-neon.S: New.
+ * cipher/keccak.c (USE_64BIT_ARM_NEON): New.
+ (NEED_COMMON64): Select if USE_64BIT_ARM_NEON.
+ [NEED_COMMON64] (round_consts_64bit): Rename to...
+ [NEED_COMMON64] (_gcry_keccak_round_consts_64bit): ...this; Add
+ terminator at end.
+ [USE_64BIT_ARM_NEON] (_gcry_keccak_permute_armv7_neon)
+ (_gcry_keccak_absorb_lanes64_armv7_neon, keccak_permute64_armv7_neon)
+ (keccak_absorb_lanes64_armv7_neon, keccak_armv7_neon_64_ops): New.
+ (keccak_init) [USE_64BIT_ARM_NEON]: Select ARM/NEON implementation
+ if supported by HW.
+ * cipher/keccak_permute_64.h (KECCAK_F1600_PERMUTE_FUNC_NAME): Update
+ to use new round constant table.
+ * configure.ac: Add 'keccak-armv7-neon.lo'.
+
+ Optimize Keccak 64-bit absorb functions.
+ + commit 2857cb89c6dc1c02266600bc1fd2967a3cd5cf88
+ * cipher/keccak.c [USE_64BIT] [__x86_64__] (absorb_lanes64_8)
+ (absorb_lanes64_4, absorb_lanes64_2, absorb_lanes64_1): New.
+ * cipher/keccak.c [USE_64BIT] [!__x86_64__] (absorb_lanes64_8)
+ (absorb_lanes64_4, absorb_lanes64_2, absorb_lanes64_1): New.
+ [USE_64BIT] (KECCAK_F1600_ABSORB_FUNC_NAME): New.
+ [USE_64BIT] (keccak_absorb_lanes64): Remove.
+ [USE_64BIT_SHLD] (KECCAK_F1600_ABSORB_FUNC_NAME): New.
+ [USE_64BIT_SHLD] (keccak_absorb_lanes64_shld): Remove.
+ [USE_64BIT_BMI2] (KECCAK_F1600_ABSORB_FUNC_NAME): New.
+ [USE_64BIT_BMI2] (keccak_absorb_lanes64_bmi2): Remove.
+ * cipher/keccak_permute_64.h (KECCAK_F1600_ABSORB_FUNC_NAME): New.
+
+2015-10-31 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Enable CRC test vectors with zero bytes.
+ + commit 07e4839e75a7bca3a6c0a94aecfe75efe61d7ff2
+ * tests/basic.c (check_digests): Enable CRC test-vectors with zero
+ bytes.
+
+ Keccak: Add SHAKE Extendable-Output Functions.
+ + commit c0b9eee2d93a13930244f9ce0c14ed6b4aeb6c29
+ * src/hash-common.c (_gcry_hash_selftest_check_one): Add handling for
+ XOFs.
+ * src/keccak.c (keccak_ops_t): Rename 'extract_inplace' to 'extract'
+ and add 'pos' argument.
+ (KECCAK_CONTEXT): Add 'suffix'.
+ (keccak_extract_inplace64): Rename to...
+ (keccak_extract64): ...this; Add handling for 'pos' argument.
+ (keccak_extract_inplace32bi): Rename to...
+ (keccak_extract32bi): ...this; Add handling for 'pos' argument.
+ (keccak_extract_inplace64): Rename to...
+ (keccak_extract64): ...this; Add handling for 'pos' argument.
+ (keccak_extract_inplace32bi_bmi2): Rename to...
+ (keccak_extract32bi_bmi2): ...this; Add handling for 'pos' argument.
+ (keccak_init): Setup 'suffix'; add SHAKE128 & SHAKE256.
+ (shake128_init, shake256_init): New.
+ (keccak_final): Do not initial permute for SHAKE output; use correct
+ suffix for SHAKE.
+ (keccak_extract): New.
+ (keccak_selftests_keccak): Add SHAKE128 & SHAKE256 test-vectors.
+ (run_selftests): Add SHAKE128 & SHAKE256.
+ (shake128_asn, oid_spec_shake128, shake256_asn, oid_spec_shake256)
+ (_gcry_digest_spec_shake128, _gcry_digest_spec_shake256): New.
+ * cipher/md.c (digest_list): Add SHAKE128 & SHAKE256.
+ * doc/gcrypt.texi: Ditto.
+ * src/cipher.h (_gcry_digest_spec_shake128)
+ (_gcry_digest_spec_shake256): New.
+ * src/gcrypt.h.in (GCRY_MD_SHAKE128, GCRY_MD_SHAKE256): New.
+ * tests/basic.c (check_one_md): Add XOF check; Add 'elen' argument.
+ (check_one_md_multi): Skip if algo is XOF.
+ (check_digests): Add SHAKE128 & SHAKE256 test vectors.
+ * tests/bench-slope.c (kdf_bench_one): Skip XOFs.
+
+ Few updates to documentation.
+ + commit 28de6f9e16e386018e81a9cdaee596be7616ccab
+ * doc/gcrypt.text: Add mention of new 'intel-fast-shld' hw feature
+ flag; Add mention of x86 RDRAND support in rndhw.
+
+ Add HMAC-SHA3 test vectors.
+ + commit 92ad19873562cfce7bcc4a0b5aed8195d8284cfc
+ * tests/basic.c (check_mac): Add HMAC_SHA3 test vectors.
+
+2015-10-28 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ md: add variable length output interface.
+ + commit 577dc2b63ceca6a8a716256d034ea4e7414f65fa
+ * cipher/crc.c (_gcry_digest_spec_crc32)
+ (_gcry_digest_spec_crc32_rfc1510, _gcry_digest_spec_crc24_rfc2440): Set
+ 'extract' NULL.
+ * cipher/gostr3411-94.c (_gcry_digest_spec_gost3411_94)
+ (_gcry_digest_spec_gost3411_cp): Ditto.
+ * cipher/keccak.c (_gcry_digest_spec_sha3_224)
+ (_gcry_digest_spec_sha3_256, _gcry_digest_spec_sha3_384)
+ (_gcry_digest_spec_sha3_512): Ditto.
+ * cipher/md2.c (_gcry_digest_spec_md2): Ditto.
+ * cipher/md4.c (_gcry_digest_spec_md4): Ditto.
+ * cipher/md5.c (_gcry_digest_spec_md5): Ditto.
+ * cipher/rmd160.c (_gcry_digest_spec_rmd160): Ditto.
+ * cipher/sha1.c (_gcry_digest_spec_sha1): Ditto.
+ * cipher/sha256.c (_gcry_digest_spec_sha224)
+ (_gcry_digest_spec_sha256): Ditto.
+ * cipher/sha512.c (_gcry_digest_spec_sha384)
+ (_gcry_digest_spec_sha512): Ditto.
+ * cipher/stribog.c (_gcry_digest_spec_stribog_256)
+ (_gcry_digest_spec_stribog_512): Ditto.
+ * cipher/tiger.c (_gcry_digest_spec_tiger)
+ (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): Ditto.
+ * cipher/whirlpool.c (_gcry_digest_spec_whirlpool): Ditto.
+ * cipher/md.c (md_enable): Do not allow combination of HMAC and
+ 'expandable-output function'.
+ (md_final): Check if spec->read is NULL before calling.
+ (md_read): Ditto.
+ (md_extract, _gcry_md_extract): New.
+ * doc/gcrypt.texi: Add SHA3 algorithms and gcry_md_extract.
+ * src/cipher-proto.h (gcry_md_extract_t): New.
+ (gcry_md_spec_t): Add 'extract'.
+ * src/gcrypt-int.g (_gcry_md_extract): New.
+ * src/gcrypt.h.in (gcry_md_extract): New.
+ * src/libgcrypt.def: Add gcry_md_extract.
+ * src/libgcrypt.vers: Add gcry_md_extract.
+ * src/visibility.c (gcry_md_extract): New.
+ * src/visibility.h (gcry_md_extract): New.
+
+ md: check hmac flag in prepare_macpads.
+ + commit cee2e122ec6c1886957a8d47498eb63a6a921725
+ * cipher/md.c (prepare_macpads): Check hmac flag.
+
+ keccak: rewrite for improved performance.
+ + commit 74184c28fbe7ff58cf57f0094ef957d94045da7d
+ * cipher/Makefile.am: Add 'keccak_permute_32.h' and
+ 'keccak_permute_64.h'.
+ * cipher/hash-common.h [USE_SHA3] (MD_BLOCK_MAX_BLOCKSIZE): Remove.
+ * cipher/keccak.c (USE_64BIT, USE_32BIT, USE_64BIT_BMI2)
+ (USE_64BIT_SHLD, USE_32BIT_BMI2, NEED_COMMON64, NEED_COMMON32BI)
+ (keccak_ops_t): New.
+ (KECCAK_STATE): Add 'state64' and 'state32bi' members.
+ (KECCAK_CONTEXT): Remove 'bctx'; add 'blocksize', 'count' and 'ops'.
+ (rol64, keccak_f1600_state_permute): Remove.
+ [NEED_COMMON64] (round_consts_64bit, keccak_extract_inplace64): New.
+ [NEED_COMMON32BI] (round_consts_32bit, keccak_extract_inplace32bi)
+ (keccak_absorb_lane32bi): New.
+ [USE_64BIT] (ANDN64, ROL64, keccak_f1600_state_permute64)
+ (keccak_absorb_lanes64, keccak_generic64_ops): New.
+ [USE_64BIT_SHLD] (ANDN64, ROL64, keccak_f1600_state_permute64_shld)
+ (keccak_absorb_lanes64_shld, keccak_shld_64_ops): New.
+ [USE_64BIT_BMI2] (ANDN64, ROL64, keccak_f1600_state_permute64_bmi2)
+ (keccak_absorb_lanes64_bmi2, keccak_bmi2_64_ops): New.
+ [USE_32BIT] (ANDN64, ROL64, keccak_f1600_state_permute32bi)
+ (keccak_absorb_lanes32bi, keccak_generic32bi_ops): New.
+ [USE_32BIT_BMI2] (ANDN64, ROL64, keccak_f1600_state_permute32bi_bmi2)
+ (pext, pdep, keccak_absorb_lane32bi_bmi2, keccak_absorb_lanes32bi_bmi2)
+ (keccak_extract_inplace32bi_bmi2, keccak_bmi2_32bi_ops): New.
+ (keccak_write): New.
+ (keccak_init): Adjust to KECCAK_CONTEXT changes; add implementation
+ selection based on HWF features.
+ (keccak_final): Adjust to KECCAK_CONTEXT changes; use selected 'ops'
+ for state manipulation.
+ (keccak_read): Adjust to KECCAK_CONTEXT changes.
+ (_gcry_digest_spec_sha3_224, _gcry_digest_spec_sha3_256)
+ (_gcry_digest_spec_sha3_348, _gcry_digest_spec_sha3_512): Use
+ 'keccak_write' instead of '_gcry_md_block_write'.
+ * cipher/keccak_permute_32.h: New.
+ * cipher/keccak_permute_64.h: New.
+
+ hwf-x86: add detection for Intel CPUs with fast SHLD instruction.
+ + commit 909644ef5883927262366c356eed530e55aba478
+ * cipher/sha1.c (sha1_init): Use HWF_INTEL_FAST_SHLD instead of
+ HWF_INTEL_CPU.
+ * cipher/sha256.c (sha256_init, sha224_init): Ditto.
+ * cipher/sha512.c (sha512_init, sha384_init): Ditto.
+ * src/g10lib.h (HWF_INTEL_FAST_SHLD): New.
+ (HWF_INTEL_BMI2, HWF_INTEL_SSSE3, HWF_INTEL_PCLMUL, HWF_INTEL_AESNI)
+ (HWF_INTEL_RDRAND, HWF_INTEL_AVX, HWF_INTEL_AVX2)
+ (HWF_ARM_NEON): Update.
+ * src/hwf-x86.c (detect_x86_gnuc): Add detection of Intel Core
+ CPUs with fast SHLD/SHRD instruction.
+ * src/hwfeatures.c (hwflist): Add "intel-fast-shld".
+
+ Fix OCB amd64 assembly implementations for x32.
+ + commit 16fd540f4d01eb6dc23d9509ae549353617c7a67
+ * cipher/camellia-glue.c (_gcry_camellia_aesni_avx_ocb_enc)
+ (_gcry_camellia_aesni_avx_ocb_dec, _gcry_camellia_aesni_avx_ocb_auth)
+ (_gcry_camellia_aesni_avx2_ocb_enc, _gcry_camellia_aesni_avx2_ocb_dec)
+ (_gcry_camellia_aesni_avx2_ocb_auth, _gcry_camellia_ocb_crypt)
+ (_gcry_camellia_ocb_auth): Change 'Ls' from pointer array to u64 array.
+ * cipher/serpent.c (_gcry_serpent_sse2_ocb_enc)
+ (_gcry_serpent_sse2_ocb_dec, _gcry_serpent_sse2_ocb_auth)
+ (_gcry_serpent_avx2_ocb_enc, _gcry_serpent_avx2_ocb_dec)
+ (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): Ditto.
+ * cipher/twofish.c (_gcry_twofish_amd64_ocb_enc)
+ (_gcry_twofish_amd64_ocb_dec, _gcry_twofish_amd64_ocb_auth)
+ (twofish_amd64_ocb_enc, twofish_amd64_ocb_dec, twofish_amd64_ocb_auth)
+ (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Ditto.
+
+ bench-slope: add KDF/PBKDF2 benchmark.
+ + commit ae40af427fd2a856b24ec2a41323ec8b80ffc9c0
+ * tests/bench-slope.c (bench_kdf_mode, bench_kdf_init, bench_kdf_free)
+ (bench_kdf_do_bench, kdf_ops, kdf_bench_one, kdf_bench): New.
+ (print_help): Add 'kdf'.
+ (main): Add KDF benchmarks.
+
+2015-10-22 NIIBE Yutaka <gniibe@fsij.org>
+
+ md: keep contexts for HMAC in GcryDigestEntry.
+ + commit f7505b550dd591e33d3a3fab9277c43c460f1bad
+ * cipher/md.c (struct gcry_md_context): Add flags.hmac.
+ Remove macpads and mcpads_Bsize.
+ (md_open): Initialize flags.hmac. Remove macpads initialization.
+ (md_enable): Allocate contexts when flags.hmac is enabled.
+ (md_copy): Remove macpads copying. Add copying contexts.
+ (_gcry_md_reset): When flags.hmac is enabled, restore precomputed
+ context with input pad
+ (md_close): Remove macpads wiping.
+ (md_final): When flags.hmac is enabled, compute hmac by precomputed
+ context with output pad.
+ (prepare_macpads): Prepare precomputed contexts with input pad and
+ output pad for each registered digest entry.
+ (_gcry_md_setkey): Just call prepare_macpads.
+
+2015-10-15 NIIBE Yutaka <gniibe@fsij.org>
+
+ Fix double free on error.
+ + commit 1c6d2698a84e4bf82735287c1d64954bfc1a1982
+ * src/hmac256.c (_gcry_hmac256_finalize): Don't free HD.
+
+2015-10-14 NIIBE Yutaka <gniibe@fsij.org>
+
+ Fix gpg_error_t and gpg_err_code_t confusion.
+ + commit 813565a07ca575c87e1252c6ed26018653ecd338
+ * src/gcrypt-int.h (_gcry_sexp_extract_param): Revert the change.
+ * cipher/dsa.c (dsa_check_secret_key): Ditto.
+ * src/sexp.c (_gcry_sexp_extract_param): Return gpg_err_code_t.
+
+ * src/gcrypt-int.h (_gcry_err_make_from_errno)
+ (_gcry_error_from_errno): Return gpg_error_t.
+ * cipher/cipher.c (_gcry_cipher_open_internal)
+ (_gcry_cipher_ctl, _gcry_cipher_ctl): Don't use gcry_error.
+ * src/global.c (_gcry_vcontrol): Likewise.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Use
+ gpg_err_code_from_syserror.
+ * cipher/mac.c (mac_reset, mac_setkey, mac_setiv, mac_write)
+ (mac_read, mac_verify): Return gcry_err_code_t.
+ * cipher/rsa-common.c (mgf1): Use gcry_err_code_t for ERR.
+ * src/visibility.c (gcry_error_from_errno): Return gpg_error_t.
+
+2015-10-13 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix compiling AES/AES-NI implementation on linux-i386.
+ + commit fa94b6111948a614ebdcb67f7942eced8b84c579
+ * cipher/rijndael-aesni.c (do_aesni_ctr_4): Split assembly block in
+ two parts to reduce number of register constraints needed.
+
+2015-10-13 NIIBE Yutaka <gniibe@fsij.org>
+
+ Fix declaration of return type.
+ + commit 73374fdd27c7ba28b19f9672c68a6f5b72252fe5
+ * src/gcrypt-int.h (_gcry_sexp_extract_param): Return gpg_error_t.
+ * cipher/dsa.c (dsa_generate): Fix call to _gcry_sexp_extract_param.
+ * src/g10lib.h (_gcry_vcontrol): Return gcry_err_code_t.
+ * src/visibility.c (gcry_mpi_snatch): Fix call to _gcry_mpi_snatch.
+
+2015-09-07 Werner Koch <wk@gnupg.org>
+
+ Improve GCRYCTL_DISABLE_PRIV_DROP by also disabling cap_ calls.
+ + commit 3a3d5410cc83f7069c7cb1ab384905f382292d32
+ * src/secmem.c (lock_pool, secmem_init): Do not call any cap_
+ functions if NO_PRIV_DROP is set.
+
+2015-09-04 Werner Koch <wk@gnupg.org>
+
+ w32: Avoid a few compiler warnings.
+ + commit e97c62a4a687b56d00a2d0a63e072a977f8eb81c
+ * cipher/cipher-selftest.c (_gcry_selftest_helper_cbc)
+ (_gcry_selftest_helper_cfb, _gcry_selftest_helper_ctr): Mark variable
+ as unused.
+ * random/rndw32.c (slow_gatherer): Avoid signed pointer mismatch
+ warning.
+ * src/secmem.c (init_pool): Avoid unused variable warning.
+ * tests/random.c (writen, readn): Include on if needed.
+
+ w32: Fix alignment problem with AESNI on Windows >= 8.
+ + commit e2785a2268702312529521df3bd2f4e6b43cea3a
+ * cipher/cipher-selftest.c (_gcry_cipher_selftest_alloc_ctx): New.
+ * cipher/rijndael.c (selftest_basic_128, selftest_basic_192)
+ (selftest_basic_256): Allocate context on the heap.
+
+2015-08-31 Werner Koch <wk@gnupg.org>
+
+ rsa: Add verify after sign to avoid Lenstra's CRT attack.
+ + commit c17f84bd02d7ee93845e92e20f6ddba814961588
+ * cipher/rsa.c (rsa_sign): Check the CRT.
+
+ Add pubkey algo id for EdDSA.
+ + commit dd87639abd38afc91a6f27af33f0ba17402ad02d
+ * src/gcrypt.h.in (GCRY_PK_EDDSA): New.
+
+2015-08-25 Werner Koch <wk@gnupg.org>
+
+ Add configure option --enable-build-timestamp.
+ + commit a785cc3db0c4e8eb8ebbf784b833a40d2c42ec3e
+ * configure.ac (BUILD_TIMESTAMP): Set to "<none>" by default.
+
+2015-08-23 Werner Koch <wk@gnupg.org>
+
+ tests: Add missing files for the make distcheck target.
+ + commit fb3cb47b0a29d3e73150297aa4495c20915e4a75
+ * tests/Makefile.am (EXTRA_DIST): Add sha3-x test vector files.
+
+2015-08-19 Werner Koch <wk@gnupg.org>
+
+ Change SHA-3 algorithm ids.
+ + commit 65639ecaaeba642e40487446c40d045482001285
+ * src/gcrypt.h.in (GCRY_MD_SHA3_224, GCRY_MD_SHA3_256)
+ (GCRY_MD_SHA3_384, GCRY_MD_SHA3_512): Change values.
+
+2015-08-12 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Keccak: Fix array indexes in θ step.
+ + commit 48822ae0b436bcea0fe92dbf0d88475ba3179320
+ * cipher/keccak.c (keccak_f1600_state_permute): Fix indexes for D[5].
+
+ Simplify OCB offset calculation for parallel implementations.
+ + commit 24ebf53f1e8a8afa27dcd768339bda70a740bb03
+ * cipher/camellia-glue.c (_gcry_camellia_ocb_crypt)
+ (_gcry_camellia_ocb_auth): Precalculate Ls array always, instead of
+ just if 'blkn % <parallel blocks> == 0'.
+ * cipher/serpent.c (_gcry_serpent_ocb_crypt)
+ (_gcry_serpent_ocb_auth): Ditto.
+ * cipher/rijndael-aesni.c (get_l): Remove low-bit checks.
+ (aes_ocb_enc, aes_ocb_dec, _gcry_aes_aesni_ocb_auth): Handle leading
+ blocks until block counter is multiple of 4, so that parallel block
+ processing loop can use 'c->u_mode.ocb.L' array directly.
+ * tests/basic.c (check_ocb_cipher_largebuf): Rename to...
+ (check_ocb_cipher_largebuf_split): ...this and add option to process
+ large buffer as two split buffers.
+ (check_ocb_cipher_largebuf): New.
+
+ Add carryless 8-bit addition fast-path for AES-NI CTR mode.
+ + commit e11895da1f4af9782d89e92ba2e6b1a63235b54b
+ * cipher/rijndael-aesni.c (do_aesni_ctr_4): Do addition using
+ CTR in big-endian form, if least-significant byte does not overflow.
+
+2015-08-10 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add additional SHA3 test-vectors.
+ + commit 80321eb3a63a20f86734d6eebb3f419c0ec895aa
+ * tests/basic.c (check_digests): Allow datalen to be specified so that
+ input data can have byte with value 0x00; Include sha3-*.h header files
+ to test-vector structure.
+ * tests/sha3-224.h: New.
+ * tests/sha3-256.h: New.
+ * tests/sha3-384.h: New.
+ * tests/sha3-512.h: New.
+
+ Add generic SHA3 implementation.
+ + commit 434ba17d1d5ad59c70d721ad3ecb376c2403a7e5
+ * cipher/hash-common.h (MD_BLOCK_MAX_BLOCKSIZE): Increase blocksize
+ USE_SHA3 enabled.
+ * cipher/keccak.c (SHA3_DELIMITED_SUFFIX, SHAKE_DELIMITED_SUFFIX): New.
+ (KECCAK_STATE): Add proper state.
+ (KECCAK_CONTEXT): Add 'outlen'.
+ (rol64, keccak_f1600_state_permute, transform_blk, transform): New.
+ (keccak_init): Add proper initialization.
+ (keccak_final): Add proper finalization.
+ (selftests_keccak): Add selftests.
+ (oid_spec_sha3_224, oid_spec_sha3_256, oid_spec_sha3_384)
+ (oid_spec_sha3_512): Add OID.
+ (_gcry_digest_spec_sha3_224, _gcry_digest_spec_sha3_256)
+ (_gcry_digest_spec_sha3_384, _gcry_digest_spec_sha3_512): Fix output
+ length.
+ * cipher/mac-hmac.c (map_mac_algo_to_md): Fix mapping for SHA3-512.
+ (hmac_get_keylen): Return proper blocksizes for SHA3 algorithms.
+ [USE_SHA3] (_gcry_mac_type_spec_hmac_sha3_224)
+ (_gcry_mac_type_spec_hmac_sha3_256, _gcry_mac_type_spec_hmac_sha3_384)
+ (_gcry_mac_type_spec_hmac_sha3_512): New.
+ * cipher/mac-internal [USE_SHA3] (_gcry_mac_type_spec_hmac_sha3_224)
+ (_gcry_mac_type_spec_hmac_sha3_256, _gcry_mac_type_spec_hmac_sha3_384)
+ (_gcry_mac_type_spec_hmac_sha3_512): New.
+ * cipher/mac.c (mac_list) [USE_SHA3]: Add SHA3 algorithms.
+ * cipher/md.c (md_open): Use proper SHA-3 blocksizes for HMAC macpads.
+ * tests/basic.c (check_digests): Add SHA3 test vectors.
+
+ Optimize OCB offset calculation.
+ + commit 49f52c67fb42c0656c8f9af655087f444562ca82
+ * cipher/cipher-internal.h (ocb_get_l): New.
+ * cipher/cipher-ocb.c (_gcry_cipher_ocb_authenticate)
+ (ocb_crypt): Use 'ocb_get_l' instead of '_gcry_cipher_ocb_get_l'.
+ * cipher/camellia-glue.c (get_l): Remove.
+ (_gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth): Precalculate
+ offset array when block count matches parallel operation size; Use
+ 'ocb_get_l' instead of 'get_l'.
+ * cipher/rijndael-aesni.c (get_l): Add fast path for 75% most common
+ offsets.
+ (aesni_ocb_enc, aesni_ocb_dec, _gcry_aes_aesni_ocb_auth): Precalculate
+ offset array when block count matches parallel operation size.
+ * cipher/rijndael-ssse3-amd64.c (get_l): Add fast path for 75% most
+ common offsets.
+ * cipher/rijndael.c (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): Use
+ 'ocb_get_l' instead of '_gcry_cipher_ocb_get_l'.
+ * cipher/serpent.c (get_l): Remove.
+ (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): Precalculate
+ offset array when block count matches parallel operation size; Use
+ 'ocb_get_l' instead of 'get_l'.
+ * cipher/twofish.c (get_l): Remove.
+ (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Use 'ocb_get_l'
+ instead of 'get_l'.
+
+2015-08-10 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: fix Montgomery curve bugs.
+ + commit ce746936b6c210e602d106cfbf45cf60b408d871
+ * cipher/ecc.c (check_secret_key): Y1 should not be NULL when check.
+ (ecc_check_secret_key): Support Montgomery curve.
+ * mpi/ec.c (_gcry_mpi_ec_curve_point): Fix condition.
+
+2015-08-08 Werner Koch <wk@gnupg.org>
+
+ Add framework to eventually support SHA3.
+ + commit 0e17f7a05bba309a87811992aa47a77af9935b99
+ * src/gcrypt.h.in (GCRY_MD_SHA3_224, GCRY_MD_SHA3_256)
+ (GCRY_MD_SHA3_384, GCRY_MD_SHA3_512): New.
+ (GCRY_MAC_HMAC_SHA3_224, GCRY_MAC_HMAC_SHA3_256)
+ (GCRY_MAC_HMAC_SHA3_384, GCRY_MAC_HMAC_SHA3_512): New.
+ * cipher/keccak.c: New with stub functions.
+ * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add keccak.c.
+ * configure.ac (available_digests): Add sha3.
+ (USE_SHA3): New.
+ * src/fips.c (run_hmac_selftests): Add SHA3 to the required selftests.
+ * cipher/md.c (digest_list) [USE_SHA3]: Add standard SHA3 algos.
+ (md_open): Ditto for hmac processing.
+ * cipher/mac-hmac.c (map_mac_algo_to_md): Add mapping.
+ * cipher/hmac-tests.c (run_selftests): Prepare for tests.
+ * cipher/pubkey-util.c (get_hash_algo): Add "sha3-xxx".
+
+2015-08-06 Werner Koch <wk@gnupg.org>
+
+ tools: Fix memory leak for functions "I" and "G".
+ + commit 10789e3cdda7b944acb4b59624c34a2ccfaea6e5
+ * src/mpicalc.c (do_inv, do_gcd): Init A after stack check.
+
+2015-08-06 Ismo Puustinen <ismo.puustinen@intel.com>
+
+ ecc: Free memory also when in error branch.
+ + commit 1d896371fbc94c605fce35eabcde01e24dd22892
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_sign): Init DISGEST and goto
+ leave on error.
+
+2015-08-06 NIIBE Yutaka <gniibe@fsij.org>
+
+ Add Curve25519 support.
+ + commit e93f4c21c59756604440ad8cbf27e67d29c99ffd
+ * cipher/ecc-curves.c (curve_aliases, domain_parms): Add Curve25519.
+ * tests/curves.c (N_CURVES): It's 22 now.
+ * src/cipher.h (PUBKEY_FLAG_DJB_TWEAK): New.
+ * cipher/ecc-common.h (_gcry_ecc_mont_decodepoint): New.
+ * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): New.
+ * cipher/ecc.c (nist_generate_key): Handle the case of
+ PUBKEY_FLAG_DJB_TWEAK and Montgomery curve.
+ (test_ecdh_only_keys, check_secret_key): Likewise.
+ (ecc_generate): Support Curve25519 which is Montgomery curve with flag
+ PUBKEY_FLAG_DJB_TWEAK and PUBKEY_FLAG_COMP.
+ (ecc_encrypt_raw): Get flags from KEYPARMS and handle
+ PUBKEY_FLAG_DJB_TWEAK and Montgomery curve.
+ (ecc_decrypt_raw): Likewise.
+ (compute_keygrip): Handle the case of PUBKEY_FLAG_DJB_TWEAK.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist):
+ PUBKEY_FLAG_EDDSA implies PUBKEY_FLAG_DJB_TWEAK.
+ Parse "djb-tweak" for PUBKEY_FLAG_DJB_TWEAK.
+
+2015-07-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Reduce code size for Twofish key-setup and remove key dependend branch.
+ + commit b4b1d872ba651bc44761b35d245b1a519a33f515
+ * cipher/twofish.c (poly_to_exp): Increase size by one, change type
+ from byte to u16 and insert '492' to index 0.
+ (exp_to_poly): Increase size by 256, let new cells have zero value.
+ (CALC_S): Execute unconditionally with help of modified tables.
+ (do_twofish_setkey): Change type for 'tmp' to 'unsigned int'; Un-unroll
+ CALC_K256 and CALC_K phases to reduce generated object size.
+
+ Reduce amount of duplicated code in OCB bulk implementations.
+ + commit e950052bc6f5ff11a7c23091ff3f6b5cc431e875
+ * cipher/cipher-ocb.c (_gcry_cipher_ocb_authenticate)
+ (ocb_crypt): Change bulk function to return number of unprocessed
+ blocks.
+ * src/cipher.h (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth)
+ (_gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth)
+ (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth)
+ (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Change return type
+ to 'size_t'.
+ * cipher/camellia-glue.c (get_l): Only if USE_AESNI_AVX or
+ USE_AESNI_AVX2 defined.
+ (_gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth): Change return type
+ to 'size_t' and return remaining blocks; Remove unaccelerated common
+ code path. Enable remaining common code only if USE_AESNI_AVX or
+ USE_AESNI_AVX2 defined; Remove unaccelerated common code.
+ * cipher/rijndael.c (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): Change
+ return type to 'size_t' and return zero.
+ * cipher/serpent.c (get_l): Only if USE_SSE2, USE_AVX2 or USE_NEON
+ defined.
+ (_gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): Change return type
+ to 'size_t' and return remaining blocks; Remove unaccelerated common
+ code path. Enable remaining common code only if USE_SSE2, USE_AVX2 or
+ USE_NEON defined; Remove unaccelerated common code.
+ * cipher/twofish.c (get_l): Only if USE_AMD64_ASM defined.
+ (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): Change return type
+ to 'size_t' and return remaining blocks; Remove unaccelerated common
+ code path. Enable remaining common code only if USE_AMD64_ASM defined;
+ Remove unaccelerated common code.
+
+ Add bulk OCB for Serpent SSE2, AVX2 and NEON implementations.
+ + commit adbdca0d58f9c06dc3850b95e3455e179c1e6960
+ * cipher/cipher.c (_gcry_cipher_open_internal): Setup OCB bulk
+ functions for Serpent.
+ * cipher/serpent-armv7-neon.S: Add OCB assembly functions.
+ * cipher/serpent-avx2-amd64.S: Add OCB assembly functions.
+ * cipher/serpent-sse2-amd64.S: Add OCB assembly functions.
+ * cipher/serpent.c (_gcry_serpent_sse2_ocb_enc)
+ (_gcry_serpent_sse2_ocb_dec, _gcry_serpent_sse2_ocb_auth)
+ (_gcry_serpent_neon_ocb_enc, _gcry_serpent_neon_ocb_dec)
+ (_gcry_serpent_neon_ocb_auth, _gcry_serpent_avx2_ocb_enc)
+ (_gcry_serpent_avx2_ocb_dec, _gcry_serpent_avx2_ocb_auth): New
+ prototypes.
+ (get_l, _gcry_serpent_ocb_crypt, _gcry_serpent_ocb_auth): New.
+ * src/cipher.h (_gcry_serpent_ocb_crypt)
+ (_gcry_serpent_ocb_auth): New.
+ * tests/basic.c (check_ocb_cipher): Add test-vector for serpent.
+
+ Add bulk OCB for Twofish AMD64 implementation.
+ + commit 7f6804c37c4b41d85fb26aa723b1c41e4a3cf278
+ * cipher/cipher.c (_gcry_cipher_open_internal): Setup OCB bulk
+ functions for Twofish.
+ * cipher/twofish-amd64.S: Add OCB assembly functions.
+ * cipher/twofish.c (_gcry_twofish_amd64_ocb_enc)
+ (_gcry_twofish_amd64_ocb_dec, _gcry_twofish_amd64_ocb_auth): New
+ prototypes.
+ (call_sysv_fn5, call_sysv_fn6, twofish_amd64_ocb_enc)
+ (twofish_amd64_ocb_dec, twofish_amd64_ocb_auth, get_l)
+ (_gcry_twofish_ocb_crypt, _gcry_twofish_ocb_auth): New.
+ * src/cipher.h (_gcry_twofish_ocb_crypt)
+ (_gcry_twofish_ocb_auth): New.
+ * tests/basic.c (check_ocb_cipher): Add test-vector for Twofish.
+
+ Add bulk OCB for Camellia AES-NI/AVX and AES-NI/AVX2 implementations.
+ + commit bb088c6b1620504fdc79e89af27c2bf3fb02b4b4
+ * cipher/camellia-aesni-avx-amd64.S: Add OCB assembly functions.
+ * cipher/camellia-aesni-avx2-amd64.S: Add OCB assembly functions.
+ * cipher/camellia-glue.c (_gcry_camellia_aesni_avx_ocb_enc)
+ (_gcry_camellia_aesni_avx_ocb_dec, _gcry_camellia_aesni_avx_ocb_auth)
+ (_gcry_camellia_aesni_avx2_ocb_enc, _gcry_camellia_aesni_avx2_ocb_dec)
+ (_gcry_camellia_aesni_avx2_ocb_auth): New prototypes.
+ (get_l, _gcry_camellia_ocb_crypt, _gcry_camellia_ocb_auth): New.
+ * cipher/cipher.c (_gcry_cipher_open_internal): Setup OCB bulk
+ functions for Camellia.
+ * src/cipher.h (_gcry_camellia_ocb_crypt)
+ (_gcry_camellia_ocb_auth): New.
+ * tests/basic.c (check_ocb_cipher): Add test-vector for Camellia.
+
+2015-07-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add OCB bulk mode for AES SSSE3 implementation.
+ + commit 620e1e0300c79943a1846a49563b04386dc60546
+ * cipher/rijndael-ssse3-amd64.c (SSSE3_STATE_SIZE): New.
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (vpaes_ssse3_prepare): Use
+ 'ssse3_state' for storing current SSSE3 state.
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
+ (vpaes_ssse3_cleanup): Restore SSSE3 state from 'ssse3_state'.
+ (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption)
+ (_gcry_aes_ssse3_encrypt, _gcry_aes_ssse3_cfb_enc)
+ (_gcry_aes_ssse3_cbc_enc, _gcry_aes_ssse3_ctr_enc)
+ (_gcry_aes_ssse3_decrypt, _gcry_aes_ssse3_cfb_dec)
+ (_gcry_aes_ssse3_cbc_dec, _gcry_aes_ssse3_cbc_dec): Add 'ssse3_state'
+ array.
+ (get_l, ssse3_ocb_enc, ssse3_ocb_dec, _gcry_aes_ssse3_ocb_crypt)
+ (_gcry_aes_ssse3_ocb_auth): New.
+ * cipher/rijndael.c (_gcry_aes_ssse3_ocb_crypt)
+ (_gcry_aes_ssse3_ocb_auth): New.
+ (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth) [USE_SSSE3]: Use SSSE3
+ implementation for OCB.
+
+2015-07-26 Peter Wu <peter@lekensteyn.nl>
+
+ Fix undefined behavior wrt memcpy.
+ + commit 46c072669eb81ed610cc5b3c0dc0c75a143afbb4
+ * cipher/cipher-gcm.c: Do not copy zero bytes from an empty buffer. Let
+ the function continue to add padding as needed though.
+ * cipher/mac-poly1305.c: If the caller requested to finish the hash
+ function without a copy of the result, return immediately.
+
+2015-07-23 Peter Wu <peter@lekensteyn.nl>
+
+ build: ignore scissor line for the commit-msg hook.
+ + commit ada0a7d302cca97b327faaacac7a5d0b8043df88
+ * build-aux/git-hooks/commit-msg: Stop processing more lines when the
+ scissor line is encountered.
+
+2015-07-16 Peter Wu <peter@lekensteyn.nl>
+
+ rsa: Fix error in comments.
+ + commit 9cd55e8e948f0049cb23495f536decf797d072f7
+ * cipher/rsa.c: Fix.
+
+2015-07-14 Peter Wu <peter@lekensteyn.nl>
+
+ sexp: Fix invalid deallocation in error path.
+ + commit 0f9532b186c1e0b54d7e7a6d76bce82b6226122b
+ * src/sexp.c: Fix wrong condition.
+
+2015-07-10 Peter Wu <peter@lekensteyn.nl>
+
+ ecc: fix memory leak.
+ + commit 2a7aa3ea4d03a9c808d5888f5509c08cd27aa27c
+ * cipher/ecc.c (ecc_verify): Release memory which was allocated before
+ by _gcry_pk_util_preparse_sigval.
+ (ecc_decrypt_raw): Likewise.
+
+2015-07-06 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: fix memory leaks.
+ + commit 0a7547e487a8bc4e7ac9599c55579eb2e4a13f06
+ cipher/ecc.c (ecc_generate): Fix memory leak on error of
+ _gcry_pk_util_parse_flaglist and _gcry_ecc_eddsa_encodepoint.
+ (ecc_check_secret_key): Fix memory leak on error of
+ _gcry_ecc_update_curve_param.
+ (ecc_sign, ecc_verify, ecc_encrypt_raw, ecc_decrypt_raw): Remove
+ unnecessary sexp_release and fix memory leak on error of
+ _gcry_ecc_fill_in_curve.
+ (ecc_decrypt_raw): Fix double free of the point kG and memory leak
+ on error of _gcry_ecc_os2ec.
+
+2015-06-11 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Support FreeBSD 10 or later.
+ + commit a36ee7501f68ad7ebcfe31f9659430b9d2c3ddd1
+ * mpi/config.links: Include FreeBSD 10 to 29.
+
+2015-05-21 Werner Koch <wk@gnupg.org>
+
+ ecc: Add key generation flag "no-keytest".
+ + commit 2bddd947fd1c11b4ec461576db65a5e34fea1b07
+ * src/cipher.h (PUBKEY_FLAG_NO_KEYTEST): New.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Add flag
+ "no-keytest". Return an error for invalid flags of length 10.
+
+ * cipher/ecc.c (nist_generate_key): Replace arg random_level by flags
+ set random level depending on flags.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Ditto.
+ * cipher/ecc.c (ecc_generate): Pass flags to generate fucntion and
+ remove var random_level.
+ (nist_generate_key): Implement "no-keytest" flag.
+
+ * tests/keygen.c (check_ecc_keys): Add tests for transient-key and
+ no-keytest.
+
+ ecc: Avoid double conversion to affine coordinates in keygen.
+ + commit 102d68b3bd77813a3ff989526855bb1e283bf9d7
+ * cipher/ecc.c (nist_generate_key): Add args r_x and r_y.
+ (ecc_generate): Rename vars. Convert to affine coordinates only if
+ not returned by the lower level generation function.
+
+ random: Change initial extra seeding from 2400 bits to 128 bits.
+ + commit 8124e357b732a719696bfd5271def4e528f2a1e1
+ * random/random-csprng.c (read_pool): Reduce initial seeding.
+
+2015-05-14 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Enable AMD64 Twofish implementation on WIN64.
+ + commit 9b0c6c8141ae9bd056392a3f6b5704b505fc8501
+ * cipher/twofish-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/twofish.c (USE_AMD64_ASM): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New.
+ (twofish_amd64_encrypt_block, twofish_amd64_decrypt_block)
+ (twofish_amd64_ctr_enc, twofish_amd64_cbc_dec)
+ (twofish_amd64_cfb_dec): New wrapper functions for AMD64
+ assembly functions.
+
+ Enable AMD64 Serpent implementations on WIN64.
+ + commit eb0ed576893b6c7990dbcb568510f831d246cea6
+ * cipher/serpent-avx2-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/serpent-sse2-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/chacha20.c (USE_SSE2, USE_AVX2): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [USE_SSE2 || USE_AVX2] (ASM_FUNC_ABI): New.
+ (_gcry_serpent_sse2_ctr_enc, _gcry_serpent_sse2_cbc_dec)
+ (_gcry_serpent_sse2_cfb_dec, _gcry_serpent_avx2_ctr_enc)
+ (_gcry_serpent_avx2_cbc_dec, _gcry_serpent_avx2_cfb_dec): Add
+ ASM_FUNC_ABI.
+
+ Enable AMD64 Salsa20 implementation on WIN64.
+ + commit 12bc93ca8187b8061c2e705427ef22f5a71d29b0
+ * cipher/salsa20-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/salsa20.c (USE_AMD64): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [USE_AMD64] (ASM_FUNC_ABI, ASM_EXTRA_STACK): New.
+ (_gcry_salsa20_amd64_keysetup, _gcry_salsa20_amd64_ivsetup)
+ (_gcry_salsa20_amd64_encrypt_blocks): Add ASM_FUNC_ABI.
+ [USE_AMD64] (salsa20_core): Add ASM_EXTRA_STACK.
+ (salsa20_do_encrypt_stream) [USE_AMD64]: Add ASM_EXTRA_STACK.
+
+ Enable AMD64 Poly1305 implementations on WIN64.
+ + commit 8d7de4dbf7732c6eb9e9853ad7c19c89075ace6f
+ * cipher/poly1305-avx2-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/poly1305-sse2-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/poly1305-internal.h (POLY1305_SYSV_FUNC_ABI): New.
+ (POLY1305_USE_SSE2, POLY1305_USE_AVX2): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (OPS_FUNC_ABI): New.
+ (poly1305_ops_t): Use OPS_FUNC_ABI.
+ * cipher/poly1305.c (_gcry_poly1305_amd64_sse2_init_ext)
+ (_gcry_poly1305_amd64_sse2_finish_ext)
+ (_gcry_poly1305_amd64_sse2_blocks, _gcry_poly1305_amd64_avx2_init_ext)
+ (_gcry_poly1305_amd64_avx2_finish_ext)
+ (_gcry_poly1305_amd64_avx2_blocks, _gcry_poly1305_armv7_neon_init_ext)
+ (_gcry_poly1305_armv7_neon_finish_ext)
+ (_gcry_poly1305_armv7_neon_blocks, poly1305_init_ext_ref32)
+ (poly1305_blocks_ref32, poly1305_finish_ext_ref32)
+ (poly1305_init_ext_ref8, poly1305_blocks_ref8)
+ (poly1305_finish_ext_ref8): Use OPS_FUNC_ABI.
+
+ Enable AMD64 3DES implementation on WIN64.
+ + commit b65e9e71d5ee992db5c96793c6af999545daad28
+ * cipher/des-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/des.c (USE_AMD64_ASM): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New.
+ (tripledes_ecb_crypt) [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Call
+ assembly function through 'call_sysv_fn'.
+ (tripledes_amd64_ctr_enc, tripledes_amd64_cbc_dec)
+ (tripledes_amd64_cfb_dec): New wrapper functions for bulk
+ assembly functions.
+
+ Enable AMD64 ChaCha20 implementations on WIN64.
+ + commit 9597cfddf03c467825da152be5ca0d12a8c30d88
+ * cipher/chacha20-avx2-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/chacha20-sse2-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/chacha20-ssse3-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/chacha20.c (USE_SSE2, USE_SSSE3, USE_AVX2): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ASM_FUNC_ABI, ASM_EXTRA_STACK): New.
+ (chacha20_blocks_t, _gcry_chacha20_amd64_sse2_blocks)
+ (_gcry_chacha20_amd64_ssse3_blocks, _gcry_chacha20_amd64_avx2_blocks)
+ (_gcry_chacha20_armv7_neon_blocks, chacha20_blocks): Add ASM_FUNC_ABI.
+ (chacha20_core): Add ASM_EXTRA_STACK.
+
+ Enable AMD64 CAST5 implementation on WIN64.
+ + commit 6a6646df80386204675d8b149ab60e74d7ca124c
+ * cipher/cast5-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (RIP): Remove.
+ (GET_EXTERN_POINTER): Use 'leaq' version on WIN64.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/cast5.c (USE_AMD64_ASM): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New.
+ (do_encrypt_block, do_decrypt_block)
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Call assembly
+ function through 'call_sysv_fn'.
+ (cast5_amd64_ctr_enc, cast5_amd64_cbc_dec)
+ (cast5_amd64_cfb_dec): New wrapper functions for bulk
+ assembly functions.
+
+ Enable AMD64 Camellia implementations on WIN64.
+ + commit 9a4fb3709864bf3e3918800d44ff576590cd4e92
+ * cipher/camellia-aesni-avx-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/camellia-aesni-avx2-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/camellia-glue.c (USE_AESNI_AVX, USE_AESNI_AVX2): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [USE_AESNI_AVX || USE_AESNI_AVX2] (ASM_FUNC_ABI, ASM_EXTRA_STACK): New.
+ (_gcry_camellia_aesni_avx_ctr_enc, _gcry_camellia_aesni_avx_cbc_dec)
+ (_gcry_camellia_aesni_avx_cfb_dec, _gcry_camellia_aesni_avx_keygen)
+ (_gcry_camellia_aesni_avx2_ctr_enc, _gcry_camellia_aesni_avx2_cbc_dec)
+ (_gcry_camellia_aesni_avx2_cfb_dec): Add ASM_FUNC_ABI.
+
+ Enable AMD64 Blowfish implementation on WIN64.
+ + commit e05682093ffb003b589a697428d918d755ac631d
+ * cipher/blowfish-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/blowfish.c (USE_AMD64_ASM): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (call_sysv_fn): New.
+ (do_encrypt, do_encrypt_block, do_decrypt_block)
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Call assembly
+ function through 'call_sysv_fn'.
+ (blowfish_amd64_ctr_enc, blowfish_amd64_cbc_dec)
+ (blowfish_amd64_cfb_dec): New wrapper functions for bulk
+ assembly functions.
+ ..
+
+ Enable AMD64 arcfour implementation on WIN64.
+ + commit c46b015bedba7ce0db68929bd33a86a54ab3d919
+ * cipher/arcfour-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/arcfour.c (USE_AMD64_ASM): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (do_encrypt, do_decrypt) [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Use
+ assembly block to call AMD64 assembly function.
+
+ Update documentation for Poly1305-ChaCha20 AEAD, RFC-7539.
+ + commit ee8fc4edcb3466b03246c8720b90731bf274ff1d
+ * cipher/cipher-poly1305.c: Add RFC-7539 to header.
+ * doc/gcrypt.texi: Update Poly1305 AEAD documentation with mention of
+ RFC-7539; Drop Salsa from supported stream ciphers for Poly1305 AEAD.
+
+ hwf-x86: use edi for passing value to ebx for i386 cpuid.
+ + commit bac42c68b069f17abcca810a21439c7233815747
+ * src/hwf-x86.c [__i386__] (get_cpuid): Use '=D' for regs[1] instead
+ of '=r'.
+
+ hwf-x86: add EDX as output register for xgetbv asm block.
+ + commit e15beb584a5ebdfc363e1ff15f87102508652d71
+ * src/hwf-x86.c (get_xgetbv): Add EDX as output.
+
+2015-05-04 Werner Koch <wk@gnupg.org>
+
+ build: Update build-aux files.
+ + commit 5a7d55eed3316f40ca61acbee032bfc285e28803
+
+
+ Fix possible regression on old 32 bit mingw compilers.
+ + commit 090ca7435156b5f52064357dd59059570d466f46
+ * acinclude.m4: Add new pattern for mingw32.
+
+ build: Add new file.
+ + commit 4af52b2e72ce004b7d8f99e09c4324e3c2a84379
+ * mpi/amd64/distfiles: Add func_abi.h.
+
+2015-05-03 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix WIN64 assembly glue for AES.
+ + commit 24a769a7c7601dbb85332e550f6fbd121b56df5f
+ * cipher/rinjdael.c (do_encrypt, do_decrypt)
+ [!HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Change input operands to
+ input+output to mark volatile nature of the used registers.
+
+ Add '1 million a characters' test vectors.
+ + commit 2f4fefdbc62857b6e2da26ce111ee140a068c471
+ * tests/basic.c (check_digests): Add "!" test vectors for MD5, SHA-384,
+ SHA-512, RIPEMD160 and CRC32.
+
+2015-05-02 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ More optimized CRC implementations.
+ + commit 06e122baa3321483a47bbf82fd2a4540becfa0c9
+ * cipher/crc.c (crc32_table, crc24_table): Replace with new table
+ contents.
+ (update_crc32, CRC24_INIT, CRC24_POLY): Remove.
+ (crc32_next, crc32_next4, crc24_init, crc24_next, crc24_next4)
+ (crc24_final): New.
+ (crc24rfc2440_init): Use crc24_init.
+ (crc32_write): Rewrite to use crc32_next & crc32_next4.
+ (crc24_write): Rewrite to use crc24_next & crc24_next4.
+ (crc32_final, crc32rfc1510_final): Use buf_put_be32.
+ (crc24rfc2440_final): Use crc24_final & buf_put_le32.
+ * tests/basic.c (check_digests): Add CRC "123456789" tests.
+
+ Enable AMD64 AES implementation for WIN64.
+ + commit 66129b3334a5aa54ff8a97981507e4704f759571
+ * cipher/rijndael-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/rijndael-internal.h (USE_AMD64_ASM): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (do_encrypt, do_decrypt)
+ [USE_AMD64_ASM && !HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Use
+ assembly block to call AMD64 assembly encrypt/decrypt function.
+
+ Enable AMD64 Whirlpool implementation for WIN64.
+ + commit 8422d5d699265b960bd1ca837044ee052fc5b614
+ * cipher/whirlpool-sse2-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/whirlpool.c (USE_AMD64_ASM): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [USE_AMD64_ASM] (ASM_FUNC_ABI, ASM_EXTRA_STACK): New.
+ [USE_AMD64_ASM] (_gcry_whirlpool_transform_amd64): Add ASM_FUNC_ABI to
+ prototype.
+ [USE_AMD64_ASM] (whirlpool_transform): Add ASM_EXTRA_STACK to stack
+ burn value.
+
+ Enable AMD64 SHA512 implementations for WIN64.
+ + commit 1089a13073c26a9a456e43ec38d937e6ee7f4077
+ * cipher/sha512-avx-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/sha512-avx-bmi2-amd64.S: Ditto.
+ * cipher/sha512-ssse3-amd64.S: Ditto.
+ * cipher/sha512.c (USE_SSSE3, USE_AVX, USE_AVX2): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [USE_SSSE3 || USE_AVX || USE_AVX2] (ASM_FUNC_ABI)
+ (ASM_EXTRA_STACK): New.
+ (_gcry_sha512_transform_amd64_ssse3, _gcry_sha512_transform_amd64_avx)
+ (_gcry_sha512_transform_amd64_avx_bmi2): Add ASM_FUNC_ABI to
+ prototypes.
+ (transform): Add ASM_EXTRA_STACK to stack burn value.
+
+ Enable AMD64 SHA256 implementations for WIN64.
+ + commit 022959099644f64df5f2a83ade21159864f64837
+ * cipher/sha256-avx-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/sha256-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha256-ssse3-amd64.S: Ditto.
+ * cipher/sha256.c (USE_SSSE3, USE_AVX, USE_AVX2): Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [USE_SSSE3 || USE_AVX || USE_AVX2] (ASM_FUNC_ABI)
+ (ASM_EXTRA_STACK): New.
+ (_gcry_sha256_transform_amd64_ssse3, _gcry_sha256_transform_amd64_avx)
+ (_gcry_sha256_transform_amd64_avx2): Add ASM_FUNC_ABI to prototypes.
+ (transform): Add ASM_EXTRA_STACK to stack burn value.
+
+ Enable AMD64 SHA1 implementations for WIN64.
+ + commit e433676a899fa0d274d40547166b03c7c8bd8e78
+ * cipher/sha1-avx-amd64.S: Enable when
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ (ELF): New macro to mask lines with ELF specific commands.
+ * cipher/sha1-avx-bmi2-amd64.S: Ditto.
+ * cipher/sha1-ssse3-amd64.S: Ditto.
+ * cipher/sha1.c (USE_SSSE3, USE_AVX, USE_BMI2): Enable
+ when HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
+ [USE_SSSE3 || USE_AVX || USE_BMI2] (ASM_FUNC_ABI)
+ (ASM_EXTRA_STACK): New.
+ (_gcry_sha1_transform_amd64_ssse3, _gcry_sha1_transform_amd64_avx)
+ (_gcry_sha1_transform_amd64_avx_bmi2): Add ASM_FUNC_ABI to
+ prototypes.
+ (transform): Add ASM_EXTRA_STACK to stack burn value.
+
+2015-05-01 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Enable AES/AES-NI, AES/SSSE3 and GCM/PCLMUL implementations on WIN64.
+ + commit 4e09aaa36d151c3312019724a77fc09aa345b82f
+ * cipher/cipher-gcm-intel-pclmul.c (_gcry_ghash_intel_pclmul)
+ ( _gcry_ghash_intel_pclmul) [__WIN64__]: Store non-volatile vector
+ registers before use and restore after.
+ * cipher/cipher-internal.h (GCM_USE_INTEL_PCLMUL): Remove dependency
+ on !defined(__WIN64__).
+ * cipher/rijndael-aesni.c [__WIN64__] (aesni_prepare_2_6_variable,
+ aesni_prepare, aesni_prepare_2_6, aesni_cleanup)
+ ( aesni_cleanup_2_6): New.
+ [!__WIN64__] (aesni_prepare_2_6_variable, aesni_prepare_2_6): New.
+ (_gcry_aes_aesni_do_setkey, _gcry_aes_aesni_cbc_enc)
+ (_gcry_aesni_ctr_enc, _gcry_aesni_cfb_dec, _gcry_aesni_cbc_dec)
+ (_gcry_aesni_ocb_crypt, _gcry_aesni_ocb_auth): Use
+ 'aesni_prepare_2_6'.
+ * cipher/rijndael-internal.h (USE_SSSE3): Enable if
+ HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS or
+ HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS.
+ (USE_AESNI): Remove dependency on !defined(__WIN64__)
+ * cipher/rijndael-ssse3-amd64.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
+ (vpaes_ssse3_prepare, vpaes_ssse3_cleanup): New.
+ [!HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (vpaes_ssse3_prepare): New.
+ (vpaes_ssse3_prepare_enc, vpaes_ssse3_prepare_dec): Use
+ 'vpaes_ssse3_prepare'.
+ (_gcry_aes_ssse3_do_setkey, _gcry_aes_ssse3_prepare_decryption): Use
+ 'vpaes_ssse3_prepare' and 'vpaes_ssse3_cleanup'.
+ [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS] (X): Add masking macro to
+ exclude '.type' and '.size' markers from assembly code, as they are
+ not support on WIN64/COFF objects.
+ * configure.ac (gcry_cv_gcc_attribute_ms_abi)
+ (gcry_cv_gcc_attribute_sysv_abi, gcry_cv_gcc_default_abi_is_ms_abi)
+ (gcry_cv_gcc_default_abi_is_sysv_abi)
+ (gcry_cv_gcc_win64_platform_as_ok): New checks.
+
+ Add W64 support for mpi amd64 assembly.
+ + commit 460355f23e770637d29e3af7b998a957a2b5bc88
+ acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Set
+ 'ac_cv_sys_symbol_underscore=no' on MingW-W64.
+ mpi/amd64/func_abi.h: New.
+ mpi/amd64/mpih-add1.S (_gcry_mpih_add_n): Add FUNC_ENTRY and FUNC_EXIT.
+ mpi/amd64/mpih-lshift.S (_gcry_mpih_lshift): Ditto.
+ mpi/amd64/mpih-mul1.S (_gcry_mpih_mul_1): Ditto.
+ mpi/amd64/mpih-mul2.S (_gcry_mpih_addmul_1): Ditto.
+ mpi/amd64/mpih-mul3.S (_gcry_mpih_submul_1): Ditto.
+ mpi/amd64/mpih-rshift.S (_gcry_mpih_rshift): Ditto.
+ mpi/amd64/mpih-sub1.S (_gcry_mpih_sub_n): Ditto.
+ mpi/config.links [host=x86_64-*mingw*]: Enable assembly modules.
+ [host=x86_64-*-*]: Append mpi/amd64/func_abi.h to mpi/asm-syntax.h.
+
+ DES: Silence compiler warnings on Windows.
+ + commit 6c21cf5fed1ad430fa41445eac2350802bc8aaed
+ * cipher/des.c (working_memcmp): Make pointer arguments 'const void *'.
+
+ Cast pointers to integers using uintptr_t instead of long.
+ + commit 9cf224322007d90193d4910f0da6e0e29ce01d70
+
+
+ Fix rndhw for 64-bit Windows build.
+ + commit d5a7e00b6b222566a5650639ef29684b047c1909
+ * configure.ac: Add sizeof check for 'void *'.
+ * random/rndhw.c (poll_padlock): Check for SIZEOF_VOID_P == 8
+ instead of defined(__LP64__).
+ (RDRAND_LONG): Check for SIZEOF_UNSIGNED_LONG == 8 instead of
+ defined(__LP64__).
+
+ Prepare random/win32.c fast poll for 64-bit Windows.
+ + commit 0cdd24456b33defc7f8176fa82ab694fbc284385
+ * random/win32.c (_gcry_rndw32_gather_random_fast) [ADD]: Rename to
+ ADDINT.
+ (_gcry_rndw32_gather_random_fast): Add ADDPTR.
+ (_gcry_rndw32_gather_random_fast): Disable entropy gathering from
+ GetQueueStatus(QS_ALLEVENTS).
+ (_gcry_rndw32_gather_random_fast): Change minimumWorkingSetSize and
+ maximumWorkingSetSize to SIZE_T from DWORD.
+ (_gcry_rndw32_gather_random_fast): Only add lower 32-bits of
+ minimumWorkingSetSize and maximumWorkingSetSize to random poll.
+ (_gcry_rndw32_gather_random_fast) [__WIN64__]: Read TSC directly
+ using intrinsic.
+
+ Disable GCM and AES-NI assembly implementations for WIN64.
+ + commit f701954555340a503f6e52cc18d58b0c515427b7
+ * cipher/cipher-internal.h (GCM_USE_INTEL_PCLMUL): Do not enable when
+ __WIN64__ defined.
+ * cipher/rijndael-internal.h (USE_AESNI): Ditto.
+
+ Disable building mpi assembly routines on WIN64.
+ + commit e78560a4b717f7154f910a8ce4128de152f586da
+ * mpi/config.links: Disable assembly for host 'x86_64-*mingw32*'.
+
+ Fix packed attribute check for Windows targets.
+ + commit e886e4f5e73fe6a9f9191f5155852ce5d8bb88fe
+ * configure.ac (gcry_cv_gcc_attribute_packed): Move 'long b' to its
+ own packed structure.
+
+ Fix tail handling in buf_xor_1.
+ + commit c2dba93e639639bdac139b3a3a456d10ddc61f79
+ * cipher/bufhelp.h (buf_xor_1): Increment source pointer at tail
+ handling.
+
+ Add --disable-hwf for basic tests.
+ + commit 839a3bbe2bb045139223b32753d656cc6c3d4669
+ * tests/basic.c (main): Add handling for '--disable-hwf'.
+
+ Use more odd chuck sizes for check_one_md.
+ + commit 9f086ffa43f2507b9d17522a0a2e394cb273baf8
+ * tests/basic.c (check_one_md): Make chuck size vary oddly, instead
+ of using fixed length of 1000 bytes.
+
+ Enable more modes in basic ciphers test.
+ + commit e40eff94f9f8654c3d29e03bbb7e5ee6a43c1435
+ * src/gcrypt.h.in (GCRY_OCB_BLOCK_LEN): New.
+ * tests/basic.c (check_one_cipher_core_reset): New.
+ (check_one_cipher_core): Use check_one_cipher_core_reset inplace of
+ gcry_cipher_reset.
+ (check_ciphers): Add CCM and OCB modes for block cipher tests.
+
+ Fix reseting cipher in OCB mode.
+ + commit 88842cbc68beb4f73c87fdbcb74182cba818f789
+ * cipher/cipher.c (cipher_reset): Setup default taglen for OCB after
+ clearing state.
+
+2015-04-30 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix buggy RC4 AMD64 assembly and add test to notice similar issues.
+ + commit 124dfce7c5a2d9405fa2b2832e91ac1267943830
+ * cipher/arcfour-amd64.S (_gcry_arcfour_amd64): Fix swapped store of
+ 'x' and 'y'.
+ * tests/basic.c (get_algo_mode_blklen): New.
+ (check_one_cipher_core): Add new tests for split buffer input on
+ encryption and decryption.
+
+2015-04-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Disallow compiler from generating SSE instructions in mixed C+asm source
+ + commit f88266c0f868d7bf51a215d5531bb9f2b4dad19e
+ * cipher/cipher-gcm-intel-pclmul.c [gcc-version >= 4.4]: Add GCC target
+ pragma to disable compiler use of SSE.
+ * cipher/rijndael-aesni.c [gcc-version >= 4.4]: Ditto.
+ * cipher/rijndael-ssse3-amd64.c [gcc-version >= 4.4]: Ditto.
+
+2015-04-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add OCB bulk crypt/auth functions for AES/AES-NI.
+ + commit 305cc878d395475c46b4ef52f4764bd0c85bf8ac
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add bulk.ocb_crypt
+ and bulk.ocb_auth.
+ (_gcry_cipher_ocb_get_l): New prototype.
+ * cipher/cipher-ocb.c (get_l): Rename to ...
+ (_gcry_cipher_ocb_get_l): ... this.
+ (_gcry_cipher_ocb_authenticate, ocb_crypt): Use bulk function when
+ available.
+ * cipher/cipher.c (_gcry_cipher_open_internal): Setup OCB bulk
+ functions for AES.
+ * cipher/rijndael-aesni.c (get_l, aesni_ocb_enc, aes_ocb_dec)
+ (_gcry_aes_aesni_ocb_crypt, _gcry_aes_aesni_ocb_auth): New.
+ * cipher/rijndael.c [USE_AESNI] (_gcry_aes_aesni_ocb_crypt)
+ (_gcry_aes_aesni_ocb_auth): New prototypes.
+ (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): New.
+ * src/cipher.h (_gcry_aes_ocb_crypt, _gcry_aes_ocb_auth): New
+ prototypes.
+ * tests/basic.c (check_ocb_cipher_largebuf): New.
+ (check_ocb_cipher): Add large buffer encryption/decryption test.
+
+2015-04-15 Werner Koch <wk@gnupg.org>
+
+ tests: Add option to time the S2K function.
+ + commit fe38d3815b4cd203cd529949e244aca80d32897f
+ * tests/t-kdf.c: Include stopwatch.h.
+ (dummy_consumer): new.
+ (bench_s2k): New.
+ (main): Add option parser and option --s2k.
+
+ tests: Improve stopwatch.h.
+ + commit 3b03a3b493233a472da531d8d9582d1be6d376b0
+ * tests/stopwatch.h (elapsed_time): Add arg divisor.
+
+2015-04-13 Werner Koch <wk@gnupg.org>
+
+ mpi: Fix gcry_mpi_copy for NULL opaque data.
+ + commit 9fca46864e1b5a9c788072113589454adb89fa97
+ * mpi/mpiutil.c (_gcry_mpi_copy): Copy opaque only if needed.
+
+2015-03-21 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ wipememory: use one-byte aligned type for unaligned memory accesses.
+ + commit a06fbc0d1e98eb1218eff55ad2f37d471e4f33b2
+ * src/g10lib.h (fast_wipememory2_unaligned_head): Enable unaligned
+ access only when HAVE_GCC_ATTRIBUTE_PACKED and
+ HAVE_GCC_ATTRIBUTE_ALIGNED defined.
+ (fast_wipememory_t): New.
+ (fast_wipememory2): Use 'fast_wipememory_t'.
+
+ bufhelp: use one-byte aligned type for unaligned memory accesses.
+ + commit 92fa5f16d69707e302c0f85b2e5e80af8dc037f1
+ * cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS): Enable only when
+ HAVE_GCC_ATTRIBUTE_PACKED and HAVE_GCC_ATTRIBUTE_ALIGNED are defined.
+ (bufhelp_int_t): New type.
+ (buf_cpy, buf_xor, buf_xor_1, buf_xor_2dst, buf_xor_n_copy_2): Use
+ 'bufhelp_int_t'.
+ [BUFHELP_FAST_UNALIGNED_ACCESS] (bufhelp_u32_t, bufhelp_u64_t): New.
+ [BUFHELP_FAST_UNALIGNED_ACCESS] (buf_get_be32, buf_get_le32)
+ (buf_put_be32, buf_put_le32, buf_get_be64, buf_get_le64)
+ (buf_put_be64, buf_put_le64): Use 'bufhelp_uXX_t'.
+ * configure.ac (gcry_cv_gcc_attribute_packed): New.
+
+ tests/bench-slope: fix memory-leak and use-after-free bugs.
+ + commit aa234561d00c3fb15fe501df4bf58f3db7c7c06b
+ * tests/bench-slope.c (do_slope_benchmark): Free 'measurements' at end.
+ (bench_mac_init): Move 'key' free at end of function.
+
+2015-03-19 Werner Koch <wk@gnupg.org>
+
+ Fix two pedantic warnings.
+ + commit f5832285b0e420d77be1b8da10a1e1d86583b414
+ * src/gcrypt.h.in (gcry_mpi_flag, gcry_mac_algos): Remove trailing
+ comma.
+
+2015-03-16 Werner Koch <wk@gnupg.org>
+
+ Use well defined type instead of size_t in secmem.c.
+ + commit db8ae3616987fa288173446398a107e31e2e28aa
+ * src/secmem.c (ptr_into_pool_p): Replace size_t by uintptr_t.
+
+ Make uintptr_t global available.
+ + commit f0f60c1a04d664936bcf52e8f46705bdc63e7ad9
+ * cipher/bufhelp.h: Move include for uintptr_t to ...
+ * src/types.h: here. Check that config.h has been included.
+
+ mpi: Remove useless condition.
+ + commit 0a9cdb8ae092d050ca12a7a4f2f50e25b82154ec
+ * mpi/mpi-pow.c: Remove condition rp==mp.
+
+ cipher: Remove useless NULL check.
+ + commit fbb97dcf763e28e81e01092ad4c934b3eaf88cc8
+ * cipher/hash-common.c (_gcry_md_block_write): Remove NUL check for
+ hd->buf.
+
+2015-02-28 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix in-place encryption for OCB mode.
+ + commit 5e66a4f8d5a63f58caeee367433dd8dd32346083
+ * cipher/cipher-ocb.c (ocb_checksum): New.
+ (ocb_crypt): Move checksum calculation outside main crypt loop, do
+ checksum calculation for encryption before inbuf is overwritten.
+ * tests/basic.c (check_ocb_cipher): Rename to ...
+ (do_check_ocb_cipher): ... to this and add argument for testing
+ in-place encryption/decryption.
+ (check_ocb_cipher): New.
+
+2015-02-27 NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: fix t-sexp.c.
+ + commit 505decf5369970219ddc9e78a20f97c623957b78
+ * tests/t-sexp.c (bug_1594): Free N and PUBKEY.
+
+ mpi: Avoid data-dependent timing variations in mpi_powm.
+ + commit 6636c4fd0c6ceab9f79827bf96967d1e112c0b82
+ * mpi/mpi-pow.c (mpi_powm): Access all data in the table by
+ mpi_set_cond.
+
+ mpi: Revise mpi_powm.
+ + commit 1fa8cdb933505960d4e4b4842b122d4e06953e88
+ * mpi/mpi-pow.c (_gcry_mpi_powm): Rename the table to PRECOMP.
+
+2015-02-23 Werner Koch <wk@gnupg.org>
+
+ cipher: Use ciphertext blinding for Elgamal decryption.
+ + commit 410d70bad9a650e3837055e36f157894ae49a57d
+ * cipher/elgamal.c (USE_BLINDING): New.
+ (decrypt): Rewrite to use ciphertext blinding.
+
+2015-02-12 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Add mpi_set_cond.
+ + commit 653a9fa1a3a4c35a4dc1841cb57d7e2a318f3288
+ * mpi/mpiutil.c (_gcry_mpi_set_cond): New.
+ (_gcry_mpi_swap_cond): Fix types.
+ * src/mpi.h (mpi_set_cond): New.
+
+2015-01-30 Werner Koch <wk@gnupg.org>
+
+ w32: Use -static-libgcc to avoid linking to libgcc_s_sjlj-1.dll.
+ + commit 40a7bdf50e19faaf106470897fed72af623adc50
+ * src/Makefile.am (extra_ltoptions): New.
+ (libgcrypt_la_LDFLAGS): Use it.
+
+2015-01-28 Werner Koch <wk@gnupg.org>
+
+ Fix building of GOST s-boxes when cross-compiling.
+ + commit 2564d204e408b296425ac0660c6bdc6270575fb6
+ * cipher/Makefile.am (gost-s-box): USe CC_FOR_BUILD.
+ (noinst_PROGRAMS): Remove.
+ (EXTRA_DIST): New.
+ (CLEANFILES): New.
+
+2015-01-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: fix wrong ifdef for SSSE3 setkey.
+ + commit ceaa97f0d849c07f3a15b642fc3a2b0a477b4a47
+ * cipher/rijndael.c (do_setkey): Use USE_SSSE3 instead of USE_AESNI
+ around SSSE3 setkey selection.
+
+2015-01-16 Werner Koch <wk@gnupg.org>
+
+ Add OCB cipher mode.
+ + commit 067d7d8752d4d8a98f8e0e5e9b1a5b13e1b7ff9c
+ * cipher/cipher-ocb.c: New.
+ * cipher/Makefile.am (libcipher_la_SOURCES): Add cipher-ocb.c
+ * cipher/cipher-internal.h (OCB_BLOCK_LEN, OCB_L_TABLE_SIZE): New.
+ (gcry_cipher_handle): Add fields marks.finalize and u_mode.ocb.
+ * cipher/cipher.c (_gcry_cipher_open_internal): Add OCB mode.
+ (_gcry_cipher_open_internal): Setup default taglen of OCB.
+ (cipher_reset): Clear OCB specific data.
+ (cipher_encrypt, cipher_decrypt, _gcry_cipher_authenticate)
+ (_gcry_cipher_gettag, _gcry_cipher_checktag): Call OCB functions.
+ (_gcry_cipher_setiv): Add OCB specific nonce setting.
+ (_gcry_cipher_ctl): Add GCRYCTL_FINALIZE and GCRYCTL_SET_TAGLEN
+
+ * src/gcrypt.h.in (GCRYCTL_SET_TAGLEN): New.
+ (gcry_cipher_final): New.
+
+ * cipher/bufhelp.h (buf_xor_1): New.
+
+ * tests/basic.c (hex2buffer): New.
+ (check_ocb_cipher): New.
+ (main): Call it here. Add option --cipher-modes.
+ * tests/bench-slope.c (bench_aead_encrypt_do_bench): Call
+ gcry_cipher_final.
+ (bench_aead_decrypt_do_bench): Ditto.
+ (bench_aead_authenticate_do_bench): Ditto. Check error code.
+ (bench_ocb_encrypt_do_bench): New.
+ (bench_ocb_decrypt_do_bench): New.
+ (bench_ocb_authenticate_do_bench): New.
+ (ocb_encrypt_ops): New.
+ (ocb_decrypt_ops): New.
+ (ocb_authenticate_ops): New.
+ (cipher_modes): Add them.
+ (cipher_bench_one): Skip wrong block length for OCB.
+ * tests/benchmark.c (cipher_bench): Add field noncelen to MODES. Add
+ OCB support.
+
+2015-01-15 Werner Koch <wk@gnupg.org>
+
+ Add functions to count trailing zero bits in a word.
+ + commit 9d2a22c94ae99f9301321082c4fb8d73f4085fda
+ * cipher/bithelp.h (_gcry_ctz, _gcry_ctz64): New.
+ * configure.ac (HAVE_BUILTIN_CTZ): Add new test.
+
+2015-01-08 Werner Koch <wk@gnupg.org>
+
+ cipher: Prepare for OCB mode.
+ + commit 9d328962660da72f094dc5424d5ef67abbaffdf6
+ * src/gcrypt.h.in (GCRY_CIPHER_MODE_OCB): New.
+
+2015-01-06 Werner Koch <wk@gnupg.org>
+
+ Make make distcheck work again.
+ + commit 4f7dcdc25af269b12275126edeef30b262fb891d
+ * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Remove --enable-ciphers.
+ * cipher/Makefile.am (DISTCLEANFILES): Add gost-sb.h.
+
+2015-01-06 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ stribog: Reduce table size to the needed one.
+ + commit e4de52378a85cf383994ded8edf0d5cf98dcb10c
+ * cipher/stribog.c (C16): Avoid allocating superfluous space.
+
+ gostr3411-94: Fix the iteration count for length filling loop.
+ + commit 05dc5bcd234909ae9c9366b653346076b9a834ed
+ * cipher/gostr3411-94.c (gost3411_final): Fix loop
+
+2015-01-05 Werner Koch <wk@gnupg.org>
+
+ random: Silent warning under NetBSD using rndunix.
+ + commit 817472358a093438e802380caecf7139406400cf
+ * random/rndunix.c (STDERR_FILENO): Define if needed.
+ (start_gatherer): Re-open standard descriptors. Fix an
+ unsigned/signed pointer warning.
+
+ primegen: Fix memory leak for invalid call sequences.
+ + commit 8c5eee51d9a25b143e41ffb7ff4a6b2a29b82d83
+ * cipher/primegen.c (prime_generate_internal): Refactor generator code
+ to not leak memory for non-implemented feature.
+ (_gcry_prime_group_generator): Refactor to not leak memory for invalid
+ args. Also make sure that R_G is set as soon as possible.
+
+ doc: Update yat2m to current upstream version (GnuPG).
+ + commit dd5df198727ea5d8f6b04288e14fd732051453c8
+
+
+ build: Require automake 1.14.
+ + commit f65276970a6dcd6d9bca94cecc49b68acdcc9492
+ * configure.ac (AM_INIT_AUTOMAKE): Add serial-tests.
+
+ Replace camel case of internal scrypt functions.
+ + commit 1a6d65ac0aab335541726d02f2046d883a768ec3
+ * cipher/scrypt.c (_salsa20_core): Rename to salsa20_core. Change
+ callers.
+ (_scryptBlockMix): Rename to scrypt_block_mix. Change callers.
+ (_scryptROMix): Rename to scrypt_ro_mix. Change callers.
+
+2015-01-02 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rmd160: restore native-endian store in _gcry_rmd160_mixblock.
+ + commit d7c7453cf5e6b8f3c6b522a30e680f844a28c9de
+ * cipher/rmd160.c (_gcry_rmd160_mixblock): Store result to buffer in
+ native-endianess.
+
+2014-12-27 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add Intel SSSE3 based vector permutation AES implementation.
+ + commit 8eabecc883332156adffc1df42d27f614c157e06
+ * cipher/Makefile.am: Add 'rijndael-ssse3-amd64.c'.
+ * cipher/rijndael-internal.h (USE_SSSE3): New.
+ (RIJNDAEL_context_s) [USE_SSSE3]: Add 'use_ssse3'.
+ * cipher/rijndael-ssse3-amd64.c: New.
+ * cipher/rijndael.c [USE_SSSE3] (_gcry_aes_ssse3_do_setkey)
+ (_gcry_aes_ssse3_prepare_decryption, _gcry_aes_ssse3_encrypt)
+ (_gcry_aes_ssse3_decrypt, _gcry_aes_ssse3_cfb_enc)
+ (_gcry_aes_ssse3_cbc_enc, _gcry_aes_ssse3_ctr_enc)
+ (_gcry_aes_ssse3_cfb_dec, _gcry_aes_ssse3_cbc_dec): New.
+ (do_setkey): Add HWF check for SSSE3 and setup for SSSE3
+ implementation.
+ (prepare_decryption, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Add
+ selection for SSSE3 implementation.
+ * configure.ac [host=x86_64]: Add 'rijndael-ssse3-amd64.lo'.
+
+2014-12-25 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ random-csprng: fix compiler warnings on ARM.
+ + commit c2e1f8fea271f3ef8027809547c4a52e0b1e24a2
+ * random/random-csprng.c (_gcry_rngcsprng_update_seed_file)
+ (read_pool): Cast keypool and rndpool to 'unsigned long *' through
+ 'void *'.
+
+ scrypt: fix compiler warnings on ARM.
+ + commit 1dab4c9422bf0f3cdc7a4d3ccf9db090abd90e94
+ * cipher/scrypt.c (_scryptBlockMix): Cast X to 'u32 *' through 'void *'.
+
+ secmem: fix compiler warnings on ARM.
+ + commit 99faf9cb34f872144313403f29f3379798debfc9
+ * src/secmem.c (ADDR_TO_BLOCK, mb_get_next, mb_get_new): Cast pointer
+ from 'char *' to 'memblock_t *' through 'void *'.
+ (MB_WIPE_OUT): Remove unneeded cast to 'memblock_t *'.
+
+ hash: fix compiler warning on ARM.
+ + commit 4515315f61fbf79413e150fbd1d5f5a2435f2bc5
+ * cipher/md.c (md_open, md_copy): Cast 'char *' to ctx through
+ 'void *'.
+ * cipher/md4.c (md4_final): Use buf_put_* helper instead of
+ converting 'char *' to 'u32 *'.
+ * cipher/md5.c (md5_final): Ditto.
+ * cipher/rmd160.c (_gcry_rmd160_mixblock, rmd160_final): Ditto.
+ * cipher/sha1.c (sha1_final): Ditto.
+ * cipher/sha256.c (sha256_final): Ditto.
+ * cipher/sha512.c (sha512_final): Ditto.
+ * cipher/tiger.c (tiger_final): Ditto.
+
+ rijndael: fix compiler warnings on ARM.
+ + commit cc26106dbebeb84d481661813edc3e5aea9a7d99
+ * cipher/rijndael-internal.h (RIJNDAEL_context_s): Add u32 variants of
+ keyschedule arrays to unions u1 and u2.
+ (keyschedenc32, keyscheddec32): New.
+ * cipher/rijndael.c (u32_a_t): Remove.
+ (do_setkey): Add and use tkk[].data32, k_u32, tk_u32 and W_u32; Remove
+ casting byte arrays to u32_a_t.
+ (prepare_decryption, do_encrypt_fn, do_decrypt_fn): Use keyschedenc32
+ and keyscheddec32; Remove casting byte arrays to u32_a_t.
+
+2014-12-23 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Poly1305-AEAD: updated implementation to match draft-irtf-cfrg-chacha20-poly1305-03
+ + commit 520070e02e2e6ee7228945015573a6e1f4895ec3
+ * cipher/cipher-internal.h (gcry_cipher_handle): Use separate byte
+ counters for AAD and data in Poly1305.
+ * cipher/cipher-poly1305.c (poly1305_fill_bytecount): Remove.
+ (poly1305_fill_bytecounts, poly1305_do_padding): New.
+ (poly1305_aad_finish): Fill padding to Poly1305 and do not fill AAD
+ length.
+ (_gcry_cipher_poly1305_authenticate, _gcry_cipher_poly1305_encrypt)
+ (_gcry_cipher_poly1305_decrypt): Update AAD and data length separately.
+ (_gcry_cipher_poly1305_tag): Fill padding and bytecounts to Poly1305.
+ (_gcry_cipher_poly1305_setkey, _gcry_cipher_poly1305_setiv): Reset
+ AAD and data byte counts; only allow 96-bit IV.
+ * cipher/cipher.c (_gcry_cipher_open_internal): Limit Poly1305-AEAD to
+ ChaCha20 cipher.
+ * tests/basic.c (_check_poly1305_cipher): Update test-vectors.
+ (check_ciphers): Limit Poly1305-AEAD checks to ChaCha20.
+ * tests/bench-slope.c (cipher_bench_one): Ditto.
+
+ chacha20: allow setting counter for stream random access.
+ + commit 11b8d2d449a7bc664b4371ae14c57caa6704d272
+ * cipher/chacha20.c (CHACHA20_CTR_SIZE): New.
+ (chacha20_ivsetup): Add setup for full counter.
+ (chacha20_setiv): Allow ivlen == CHACHA20_CTR_SIZE.
+
+ gcm: do not pass extra key pointer for setupM/fillM.
+ + commit c964321c8a1328e89d636d899a45d68802f5ac9f
+ * cipher/cipher-gcm-intel-pclmul.c
+ (_gcry_ghash_setup_intel_pclmul): Remove 'h' parameter.
+ * cipher/cipher-gcm.c (_gcry_ghash_setup_intel_pclmul): Ditto.
+ (fillM): Get 'h' pointer from 'c'.
+ (setupM): Remome 'h' parameter.
+ (_gcry_cipher_gcm_setkey): Only pass 'c' to setupM.
+
+ rijndael: use more compact look-up tables and add table prefetching.
+ + commit 2374753938df64f6fd8015b44613806a326eff1a
+ * cipher/rijndael-internal.h (rijndael_prefetchfn_t): New.
+ (RIJNDAEL_context): Add 'prefetch_enc_fn' and 'prefetch_dec_fn'.
+ * cipher/rijndael-tables.h (S, T1, T2, T3, T4, T5, T6, T7, T8, S5, U1)
+ (U2, U3, U4): Remove.
+ (encT, dec_tables, decT, inv_sbox): Add.
+ * cipher/rijndael.c (_gcry_aes_amd64_encrypt_block)
+ (_gcry_aes_amd64_decrypt_block, _gcry_aes_arm_encrypt_block)
+ (_gcry_aes_arm_encrypt_block): Add parameter for passing table pointer
+ to assembly implementation.
+ (prefetch_table, prefetch_enc, prefetch_dec): New.
+ (do_setkey): Setup context prefetch functions depending on selected
+ rijndael implementation; Use new tables for key setup.
+ (prepare_decryption): Use new tables for decryption key setup.
+ (do_encrypt_aligned): Rename to...
+ (do_encrypt_fn): ... to this, change to use new compact tables,
+ make handle unaligned input and unroll rounds loop by two.
+ (do_encrypt): Remove handling of unaligned input/output; pass table
+ pointer to assembly implementations.
+ (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec): Prefetch encryption tables
+ before encryption.
+ (do_decrypt_aligned): Rename to...
+ (do_decrypt_fn): ... to this, change to use new compact tables,
+ make handle unaligned input and unroll rounds loop by two.
+ (do_decrypt): Remove handling of unaligned input/output; pass table
+ pointer to assembly implementations.
+ (rijndael_decrypt, _gcry_aes_cbc_dec): Prefetch decryption tables
+ before decryption.
+ * cipher/rijndael-amd64.S: Use 1+1.25 KiB tables for
+ encryption+decryption; remove tables from assembly file.
+ * cipher/rijndael-arm.S: Ditto.
+
+2014-12-15 Werner Koch <wk@gnupg.org>
+
+ build: Add configure option --disable-doc.
+ + commit ad50e360ef4851e66e51a03fc420175636336b58
+ * Makefile.am (AUTOMAKE_OPTIONS): Remove.
+ (doc) [!BUILD_DOC]: Do not recurse into the dir.
+ * configure.ac (AM_INIT_AUTOMAKE): Add option formerly in Makefile.am.
+ (BUILD_DOC): Add new am_conditional.
+
+2014-12-12 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: further optimizations for AES-NI accelerated CBC and CFB bulk modes
+ + commit 4f46374502eb988d701b904f83819e2cf7b1755c
+ * cipher/rijndael-aesni.c (do_aesni_enc, do_aesni_dec): Pass
+ input/output through SSE register XMM0.
+ (do_aesni_cfb): Remove.
+ (_gcry_aes_aesni_encrypt, _gcry_aes_aesni_decrypt): Add loading/storing
+ input/output to/from XMM0.
+ (_gcry_aes_aesni_cfb_enc, _gcry_aes_aesni_cbc_enc)
+ (_gcry_aes_aesni_cfb_dec): Update to use renewed 'do_aesni_enc' and
+ move IV loading/storing outside loop.
+ (_gcry_aes_aesni_cbc_dec): Update to use renewed 'do_aesni_dec'.
+
+ GCM: move Intel PCLMUL accelerated implementation to separate file.
+ + commit 4a0795af021305f9240f23626a3796157db46bd7
+ * cipher/Makefile.am: Add 'cipher-gcm-intel-pclmul.c'.
+ * cipher/cipher-gcm-intel-pclmul.c: New.
+ * cipher/cipher-gcm.c [GCM_USE_INTEL_PCLMUL]
+ (_gcry_ghash_setup_intel_pclmul, _gcry_ghash_intel_pclmul): New
+ prototypes.
+ [GCM_USE_INTEL_PCLMUL] (gfmul_pclmul, gfmul_pclmul_aggr4): Move
+ to 'cipher-gcm-intel-pclmul.c'.
+ (ghash): Rename to...
+ (ghash_internal): ...this and move GCM_USE_INTEL_PCLMUL part to new
+ function in 'cipher-gcm-intel-pclmul.c'.
+ (setupM): Move GCM_USE_INTEL_PCLMUL part to new function in
+ 'cipher-gcm-intel-pclmul.c'; Add selection of ghash function based
+ on available HW acceleration.
+ (do_ghash_buf): Change use of 'ghash' to 'c->u_mode.gcm.ghash_fn'.
+ * cipher/internal.h (ghash_fn_t): New.
+ (gcry_cipher_handle): Remove 'use_intel_pclmul'; Add 'ghash_fn'.
+
+2014-12-06 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: split Padlock part to separate file.
+ + commit cbf4c8cb6bbda15eea61885279f2a6f1d4bcedfd
+ * cipher/Makefile.am: Add 'rijndael-padlock.c'.
+ * cipher/rijndael-padlock.c: New.
+ * cipher/rijndael.c (do_padlock, do_padlock_encrypt)
+ (do_padlock_decrypt): Move to 'rijndael-padlock.c'.
+ * configure.ac [mpi_cpu_arch=x86]: Add 'rijndael-padlock.lo'.
+
+2014-12-01 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: refactor to reduce number of #ifdefs and branches.
+ + commit 3d5b51786e2050c461e9791b59142a731462b66d
+ * cipher/rijndael-aesni.c (_gcry_aes_aesni_encrypt)
+ (_gcry_aes_aesni_decrypt): Make return stack burn depth.
+ * cipher/rijndael-amd64.S (_gcry_aes_amd64_encrypt_block)
+ (_gcry_aes_amd64_decrypt_block): Ditto.
+ * cipher/rijndael-arm.S (_gcry_aes_arm_encrypt_block)
+ (_gcry_aes_arm_decrypt_block): Ditto.
+ * cipher/rijndael-internal.h (RIJNDAEL_context_s)
+ (rijndael_cryptfn_t): New.
+ (RIJNDAEL_context): New members 'encrypt_fn' and 'decrypt_fn'.
+ * cipher/rijndael.c (_gcry_aes_amd64_encrypt_block)
+ (_gcry_aes_amd64_decrypt_block, _gcry_aes_aesni_encrypt)
+ (_gcry_aes_aesni_decrypt, _gcry_aes_arm_encrypt_block)
+ (_gcry_aes_arm_decrypt_block): Change prototypes.
+ (do_padlock_encrypt, do_padlock_decrypt): New.
+ (do_setkey): Separate key-length to rounds conversion from
+ HW features check; Add selection for ctx->encrypt_fn and
+ ctx->decrypt_fn.
+ (do_encrypt_aligned, do_decrypt_aligned): Move inside
+ '[!USE_AMD64_ASM && !USE_ARM_ASM]'; Move USE_AMD64_ASM and
+ USE_ARM_ASM to...
+ (do_encrypt, do_decrypt): ...here; Return stack depth; Remove second
+ temporary buffer from non-aligned input/output case.
+ (do_padlock): Move decrypt_flag to last argument; Return stack depth.
+ (rijndael_encrypt): Remove #ifdefs, just call ctx->encrypt_fn.
+ (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc): Remove USE_PADLOCK; Call
+ ctx->encrypt_fn in place of do_encrypt/do_encrypt_aligned.
+ (_gcry_aes_ctr_enc): Call ctx->encrypt_fn in place of
+ do_encrypt_aligned; Make tmp buffer 16-byte aligned and wipe buffer
+ after use.
+ (rijndael_encrypt): Remove #ifdefs, just call ctx->decrypt_fn.
+ (_gcry_aes_cfb_dec): Remove USE_PADLOCK; Call ctx->decrypt_fn in place
+ of do_decrypt/do_decrypt_aligned.
+ (_gcry_aes_cbc_dec): Ditto; Make savebuf buffer 16-byte aligned.
+
+ rijndael: move AES-NI blocks before Padlock.
+ + commit dbf9e95dd3891f6e6ad370e8ab78fec03595687b
+ * cipher/rijndael.c (do_setkey, rijndael_encrypt, _gcry_aes_cfb_enc)
+ (rijndael_decrypt, _gcry_aes_cfb_dec): Move USE_AESNI before
+ USE_PADLOCK.
+ (check_decryption_praparation) [USE_PADLOCK]: Move to...
+ (prepare_decryption) [USE_PADLOCK]: ...here.
+
+ rijndael: split AES-NI functions to separate file.
+ + commit 67d529630e838daeb8cb9c6d7ef660c01ef34fee
+ * cipher/Makefile.in: Add 'rijndael-aesni.c'.
+ * cipher/rijndael-aesni.c: New.
+ * cipher/rijndael-internal.h: New.
+ * cipher/rijndael.c (MAXKC, MAXROUNDS, BLOCKSIZE, ATTR_ALIGNED_16)
+ (USE_AMD64_ASM, USE_ARM_ASM, USE_PADLOCK, USE_AESNI, RIJNDAEL_context)
+ (keyschenc, keyschdec, padlockkey): Move to 'rijndael-internal.h'.
+ (u128_s, aesni_prepare, aesni_cleanup, aesni_cleanup_2_6)
+ (aesni_do_setkey, do_aesni_enc, do_aesni_dec, do_aesni_enc_vec4)
+ (do_aesni_dec_vec4, do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Move
+ to 'rijndael-aesni.c'.
+ (prepare_decryption, rijndael_encrypt, _gcry_aes_cfb_enc)
+ (_gcry_aes_cbc_enc, _gcry_aes_ctr_enc, rijndael_decrypt)
+ (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec) [USE_AESNI]: Move to functions
+ in 'rijdael-aesni.c'.
+ * configure.ac [mpi_cpu_arch=x86]: Add 'rijndael-aesni.lo'.
+
+2014-11-24 Werner Koch <wk@gnupg.org>
+
+ Remove duplicated prototypes.
+ + commit d53ea84bed37b973f7ce59262c50b33700cd8311
+ * src/gcrypt-int.h (_gcry_mpi_ec_new, _gcry_mpi_ec_set_mpi)
+ (gcry_mpi_ec_set_point): Remove.
+
+ tests: Add a prime mode to benchmark.
+ + commit 1b4210c204a5ef5e631187509e011b8468a134ef
+ * tests/benchmark.c (progress_cb): Add a single char mode.
+ (prime_bench): New.
+ (main): Add a "prime" mode. Factor with_progress out to file scope.
+
+2014-11-19 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Improve Montgomery curve implementation.
+ + commit e6130034506013d6153465a2bedb6fb08a43f74d
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Support
+ MPI_EC_MONTGOMERY.
+ * cipher/ecc.c (test_ecdh_only_keys): New.
+ (nist_generate_key): Call test_ecdh_only_keys for MPI_EC_MONTGOMERY.
+ (check_secret_key): Handle Montgomery curve of x-coordinate only.
+ * mpi/ec.c (_gcry_mpi_ec_mul_point): Resize points before the loop.
+ Simplify, using pointers of Q1, Q2, PRD, and SUM.
+
+2014-11-02 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Disable NEON for CPUs that are known to have broken NEON implementation.
+ + commit 95eef21583d8e998efc48f22898c1ae31b77cb48
+ * src/hwf-arm.c (detect_arm_proc_cpuinfo): Add parsing for CPU version
+ information and check if CPU is known to have broken NEON
+ implementation.
+ (_gcry_hwf_detect_arm): Filter out broken HW features.
+
+ Add ARM/NEON implementation of Poly1305.
+ + commit 0b520128551054d83fb0bb2db8873394f38de498
+ * cipher/Makefile.am: Add 'poly1305-armv7-neon.S'.
+ * cipher/poly1305-armv7-neon.S: New.
+ * cipher/poly1305-internal.h (POLY1305_USE_NEON)
+ (POLY1305_NEON_BLOCKSIZE, POLY1305_NEON_STATESIZE)
+ (POLY1305_NEON_ALIGNMENT): New.
+ * cipher/poly1305.c [POLY1305_USE_NEON]
+ (_gcry_poly1305_armv7_neon_init_ext)
+ (_gcry_poly1305_armv7_neon_finish_ext)
+ (_gcry_poly1305_armv7_neon_blocks, poly1305_armv7_neon_ops): New.
+ (_gcry_poly1305_init) [POLY1305_USE_NEON]: Select NEON implementation
+ if HWF_ARM_NEON set.
+ * configure.ac [neonsupport=yes]: Add 'poly1305-armv7-neon.lo'.
+
+ chacha20: add ARMv7/NEON implementation.
+ + commit c584f44543883346d5a565581ff99a0afce9c5e1
+ * cipher/Makefile.am: Add 'chacha20-armv7-neon.S'.
+ * cipher/chacha20-armv7-neon.S: New.
+ * cipher/chacha20.c (USE_NEON): New.
+ [USE_NEON] (_gcry_chacha20_armv7_neon_blocks): New.
+ (chacha20_do_setkey) [USE_NEON]: Use Neon implementation if
+ HWF_ARM_NEON flag set.
+ (selftest): Self-test encrypting buffer byte by byte.
+ * configure.ac [neonsupport=yes]: Add 'chacha20-armv7-neon.lo'.
+
+2014-10-08 Markus Teich <markus.teich@stusta.mhn.de>
+
+ mpi: Add gcry_mpi_ec_sub.
+ + commit 23ecadf309f8056c35cc092e58df801ac0eab862
+ * NEWS (gcry_mpi_ec_sub): New.
+ * doc/gcrypt.texi (gcry_mpi_ec_sub): New.
+ * mpi/ec.c (_gcry_mpi_ec_sub, sub_points_edwards): New.
+ (sub_points_montgomery, sub_points_weierstrass): New stubs.
+ * src/gcrypt-int.h (_gcry_mpi_ec_sub): New.
+ * src/gcrypt.h.in (gcry_mpi_ec_sub): New.
+ * src/libgcrypt.def (gcry_mpi_ec_sub): New.
+ * src/libgcrypt.vers (gcry_mpi_ec_sub): New.
+ * src/mpi.h (_gcry_mpi_ec_sub_points): New.
+ * src/visibility.c (gcry_mpi_ec_sub): New.
+ * src/visibility.h (gcry_mpi_ec_sub): New.
+
+2014-10-08 Werner Koch <wk@gnupg.org>
+
+ Fix prime test for 2 and lower and add check command to mpicalc.
+ + commit 5c906e2cdb14e93fb4915fdc69c7353a5fa35709
+ * cipher/primegen.c (check_prime): Return true for the small primes.
+ (_gcry_prime_check): Return correct values for 2 and lower numbers.
+
+ * src/mpicalc.c (do_primecheck): New.
+ (main): Add command 'P'.
+ (main): Allow for larger input data.
+
+2014-10-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add Whirlpool AMD64/SSE2 assembly implementation.
+ + commit de0ccd4dce7ec185a678d78878d4538dd609ca0f
+ * cipher/Makefile.am: Add 'whirlpool-sse2-amd64.S'.
+ * cipher/whirlpool-sse2-amd64.S: New.
+ * cipher/whirlpool.c (USE_AMD64_ASM): New.
+ (whirlpool_tables_s): New.
+ (rc, C0, C1, C2, C3, C4, C5, C6, C7): Combine these tables into single
+ structure and replace old tables with macros of same name.
+ (tab): New structure containing above tables.
+ [USE_AMD64_ASM] (_gcry_whirlpool_transform_amd64)
+ (whirlpool_transform): New.
+ * configure.ac [host=x86_64]: Add 'whirlpool-sse2-amd64.lo'.
+
+2014-10-04 Andrei Scherer <andsch@inbox.com>
+
+ Improved ripemd160 performance.
+ + commit 30bd759f398f45b04d0a783b875f59ce9bd1e51d
+ * cipher/rmd160.c (transform): Interleave the left and right lane
+ rounds to introduce more instruction level parallelism.
+
+2014-10-02 Werner Koch <wk@gnupg.org>
+
+ build: Document SYSROOT.
+ + commit 0ecd136a6ca02252f63ad229fa5240897bfe6544
+ * configure.ac: Mark SYSROOT as arg var.
+
+ build: Support SYSROOT based config script finding.
+ + commit 1e8b86494cf8fa045696bd447b16267ffd1797f0
+ * src/libgcrypt.m4: Add support for SYSROOT and set
+ gpg_config_script_warn. Use AC_PATH_PROG instead of AC_PATH_TOOL
+ because the config script is not expected to be installed with a
+ prefix for its name
+ * configure.ac: Print a library mismatch warning.
+ * m4/gpg-error.m4: Update from git master.
+
+2014-09-30 Werner Koch <wk@gnupg.org>
+
+ mac: Fix gcry_mac_close to allow for a NULL handle.
+ + commit 51dae8c8c4b63bb5e1685cbd8722e35342524737
+ * cipher/mac.c (_gcry_mac_close): Check for NULL.
+
+2014-09-03 Werner Koch <wk@gnupg.org>
+
+ Add a constant for a forthcoming new RNG.
+ + commit 8b960a807d168000d2690897a7634bd384ac1346
+ * src/gcrypt.h.in (GCRYCTL_DRBG_REINIT): New constant.
+
+2014-09-02 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add new Poly1305 MAC test vectors.
+ + commit 8a2a328742012a7c528dd007437185e4584c1e48
+ * tests/basic.c (check_mac): Add new test vectors for Poly1305 MAC.
+
+2014-09-02 Werner Koch <wk@gnupg.org>
+
+ asm: Allow building x86 and amd64 using old compilers.
+ + commit 5eec04a43e6c562e956353449be931dd43dfe1cc
+ * src/hwf-x86.c (get_xgetbv): Build only if AVX support is enabled.
+
+2014-08-21 Werner Koch <wk@gnupg.org>
+
+ sexp: Check args of gcry_sexp_build.
+ + commit e606d5f1bada1f2d21faeedd3fa2cf2dca7b274c
+ * src/sexp.c (do_vsexp_sscan): Return error for invalid args.
+
+ cipher: Fix a segv in case of calling with wrong parameters.
+ + commit f850add813d783f31ca6a60459dea25ef71bce7e
+ * cipher/md.c (_gcry_md_info): Fix arg testing.
+
+ cipher: Fix possible NULL deref in call to prime generator.
+ + commit 18056ace7f466cb8c1eaf08e5dc0400516d83b4c
+ * cipher/primegen.c (_gcry_generate_elg_prime): Change to return an
+ error code.
+ * cipher/dsa.c (generate): Take care of new return code.
+ * cipher/elgamal.c (generate): Change to return an error code. Take
+ care of _gcry_generate_elg_prime return code.
+ (generate_using_x): Take care of _gcry_generate_elg_prime return code.
+ (elg_generate): Propagate return code from generate.
+
+2014-08-12 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Support Montgomery curve for gcry_mpi_ec_mul_point.
+ + commit 34bb55ee36df3aca3ebca88f8b61c786cd0c0701
+ * mpi/ec.c (_gcry_mpi_ec_get_affine): Support Montgomery curve.
+ (montgomery_ladder): New.
+ (_gcry_mpi_ec_mul_point): Implemention using montgomery_ladder.
+ (_gcry_mpi_ec_curve_point): Check x-coordinate is valid.
+
+2014-08-09 Werner Koch <wk@gnupg.org>
+
+ tests: Add a benchmark for Elgamal.
+ + commit e6d354865bf8f3d4c1bb5e8157a76fdd442cff41
+ * tests/benchmark.c (sample_public_elg_key_1024): New.
+ (sample_private_elg_key_1024): New.
+ (sample_public_elg_key_2048, sample_private_elg_key_2048): New.
+ (sample_public_elg_key_3072, sample_private_elg_key_3072): New.
+ (elg_bench): New.
+ (main): Add elg_bench. Add commands "elg" and "public".
+
+2014-08-08 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Add cofactor to domain parameters.
+ + commit 9933b9e5e1a3f5b1019c75f93bd265d4a1ecc270
+ * src/ec-context.h (mpi_ec_ctx_s): Add cofactor 'h'.
+ * cipher/ecc-common.h (elliptic_curve_t): Add cofactor 'h'.
+ (_gcry_ecc_update_curve_param): New API adding cofactor.
+
+ * cipher/ecc-curves.c (ecc_domain_parms_t): Add cofactor 'h'.
+ (ecc_domain_parms_t domain_parms): Add cofactors.
+ (_gcry_ecc_fill_in_curve, _gcry_ecc_update_curve_param)
+ (_gcry_ecc_get_curve, _gcry_mpi_ec_new, _gcry_ecc_get_param_sexp)
+ (_gcry_ecc_get_mpi): Handle cofactor.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Likewise.
+ * cipher/ecc-misc.c (_gcry_ecc_curve_free)
+ (_gcry_ecc_curve_copy): Likewise.
+ * cipher/ecc.c (nist_generate_key, ecc_generate)
+ (ecc_check_secret_key, ecc_sign, ecc_verify, ecc_encrypt_raw)
+ (ecc_decrypt_raw, _gcry_pk_ecc_get_sexp, _gcry_pubkey_spec_ecc):
+ Likewise.
+ (compute_keygrip): Handle cofactor, but skip it for its computation.
+ * mpi/ec.c (ec_deinit): Likewise.
+ * tests/t-mpi-point.c (context_param): Likewise.
+ (test_curve): Add cofactors.
+ * tests/curves.c (sample_key_1, sample_key_2): Add cofactors.
+ * tests/keygrip.c (key_grips): Add cofactors.
+
+2014-08-05 Werner Koch <wk@gnupg.org>
+
+ mpi: Fix regression for powerpc-apple-darwin detection.
+ + commit 4ce77b0a810d3c889c07dfb385127d90fa1ae36a
+ * mpi/config.links: Add separate entry for powerpc-apple-darwin.
+
+ Fix bug inhibiting the use of the sentinel attribute.
+ + commit d2d28298ccc0d0f3c0b03fd323deb1e8808ef74f
+ * src/gcrypt.h.in: Fix typo in macro.
+
+ mpi: Use BSD syntax for x86_64-apple-darwin.
+ + commit 71939faa7c54e7b4b28d115e748a85f134876a02
+ * mpi/config.links: Add case for x86_64-apple-darwin.
+
+2014-08-05 Kristian Fiskerstrand <kf@sumptuouscapital.com>
+
+ Fix building for the x32 target without asm modules.
+ + commit a17c29844b63e9e869f7855d901bc9d859234ead
+ * mpi/generic/mpi-asm-defs.h: Use a fixed value for the x32 ABI.
+
+2014-07-25 Werner Koch <wk@gnupg.org>
+
+ ecc: Support the non-standard 0x40 compression flag for EdDSA.
+ + commit 4556f9b19c024f16bdf542da7173395c0741b91d
+ * cipher/ecc.c (ecc_generate): Check the "comp" flag for EdDSA.
+ * cipher/ecc-eddsa.c (eddsa_encode_x_y): Add arg WITH_PREFIX.
+ (_gcry_ecc_eddsa_encodepoint): Ditto.
+ (_gcry_ecc_eddsa_ensure_compact): Handle the 0x40 compression prefix.
+ (_gcry_ecc_eddsa_decodepoint): Ditto.
+ * tests/keygrip.c: Check an compresssed with prefix Ed25519 key.
+ * tests/t-ed25519.inp: Ditto.
+
+ mpi: Extend the internal mpi_get_buffer.
+ + commit 0e10902ad7584277ac966367efc712b183784532
+ * mpi/mpicoder.c (do_get_buffer): Add arg EXTRAALLOC.
+ (_gcry_mpi_get_buffer_extra): New.
+
+ cipher: Fix compiler warning for chacha20.
+ + commit 4e0bf1b9190ce08fb23eb3ae0c3be58954ff36ab
+ * cipher/chacha20.c (chacha20_blocks) [!USE_SSE2]: Do not build.
+
+2014-07-16 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: Add mpi_swap_cond.
+ + commit 4846e52728970e3117f3a046ef9010be089a3ae4
+ * mpi/mpiutil.c (_gcry_mpi_swap_cond): New.
+ * src/mpi.h (mpi_swap_cond): New.
+
+2014-06-29 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Speed-up SHA-1 NEON assembly implementation.
+ + commit 1b9b00bbe41bbed32563f1102049521e703e72bd
+ * cipher/sha1-armv7-neon.S: Tweak implementation for speed-up.
+
+2014-06-28 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ gostr3411_94: rewrite to use u32 mathematic.
+ + commit 066f068bd0bc4d8e01f1f18b6153cdc8d2c245d7
+ * cipher/gost28147.c (_gcry_gost_enc_data): New.
+ * cipher/gostr3411-94.c: Rewrite implementation to use u32 mathematic
+ internally.
+ * cipher/gost28147.c (_gcry_gost_enc_one): Remove.
+
+ gost28147: use bufhelp helpers.
+ + commit 7aeba6c449169926076df83b01ddbfa6b41fe411
+ * cipher/gost28147.c (gost_setkey, gost_encrypt_block, gost_decrypt_block):
+ use buf_get_le32/buf_put_le32 helpers.
+
+ Fixup curve name in the GOST2012 test case.
+ + commit b78d504fa8745b8b04589acbbcf7dd5fe9279d13
+ * tests/basic.c (check_pubkey): fixup curve name in public key.
+
+ Update PBKDF2 tests with GOST R 34.11-94 test cases.
+ + commit 7533b2ad46f42e98d9dba52e88e79c0311d2d3b7
+ * tests/t-kdf.c (check_pbkdf2): Add MD_GOSTR3411_CP test cases.
+
+ Add GOST R 34.11-94 variant using id-GostR3411-94-CryptoProParamSet.
+ + commit 25d6af77e2336b5979ddbe8b90978fe5b61dfaf9
+ * src/gcrypt.h.in (GCRY_MD_GOSTR3411_CP): New.
+ * src/cipher.h (_gcry_digest_spec_gost3411_cp): New.
+ * cipher/gost28147.c (_gcry_gost_enc_one): Differentiate between
+ CryptoPro and Test S-Boxes.
+ * cipher/gostr3411-94.c (_gcry_digest_spec_gost3411_cp,
+ gost3411_cp_init): New.
+ * cipher/md.c (md_open): GCRY_MD_GOSTR3411_CP also uses B=32.
+
+ gost28147: support GCRYCTL_SET_SBOX.
+ + commit 5ee35a04362c94e680ef3633fa83b72e0aee8626
+ cipher/gost28147.c (gost_set_extra_info, gost_set_sbox): New.
+
+ Support setting s-box for the ciphers that require it.
+ + commit fb074d113fcbf66a5c20592625cb19051f3430f5
+ * src/gcrypt.h.in (GCRYCTL_SET_SBOX, gcry_cipher_set_sbox): New.
+ * cipher/cipher.c (_gcry_cipher_ctl): pass GCRYCTL_SET_SBOX to
+ set_extra_info callback.
+
+ cipher/gost28147: generate optimized s-boxes from compact ones.
+ + commit 164738a0292b3f32c7747099ad9cadace58e5eda
+ * cipher/gost-s-box.c: New. Outputs optimized expanded representation of
+ s-boxes (4x256) from compact 16x8 representation.
+ * cipher/Makefile.am: Add gost-sb.h dependency to gost28147.lo
+ * cipher/gost.h: Add sbox to the GOST28147_context structure.
+ * cipher/gost28147.c (gost_setkey): Set default s-box to test s-box from
+ GOST R 34.11 (this was the only one S-box before).
+ * cipher/gost28147.c (gost_val): Use sbox from the context.
+
+ gost28147: add OIDs used to define cipher mode.
+ + commit 34a58010000288515636706811c3837f32957b2e
+ * cipher/gost28147 (oids_gost28147): Add OID from RFC4357.
+
+ GOST R 34.11-94 add OIDs.
+ + commit 8b221cf5ce233c8c49a4e4ecebb70d523fc37837
+ * cipher/gostr3411-94.c: Add OIDs for GOST R 34.11-94 from RFC 4357.
+
+2014-05-21 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ tests: add larger test-vectors for hash algorithms.
+ + commit f14fb5b427b5159fcd9603d2b3cde936889cf430
+ * tests/basic.c (check_digests): Add large test-vectors for MD5, SHA1,
+ SHA224, SHA256, SHA384, RMD160, CRC32, TIGER1, WHIRLPOOL and
+ GOSTR3411_94.
+
+ sha512: fix ARM/NEON implementation.
+ + commit beb901575f0d6cd6a0a27506ebea9a725754d0cc
+ * cipher/sha512-armv7-neon.S
+ (_gcry_sha512_transform_armv7_neon): Byte-swap RW67q and RW1011q
+ correctly in multi-block loop.
+ * tests/basic.c (check_digests): Add large test vector for SHA512.
+
+2014-05-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix ARM assembly when building __PIC__
+ + commit 994c758d8f5471c7e9c38c2834742cca2502d35f
+ * cipher/camellia-arm.S (GET_DATA_POINTER): New.
+ (_gcry_camellia_arm_encrypt_block): Use GET_DATA_POINTER.
+ (_gcry_camellia_arm_decrypt_block): Ditto.
+ * cipher/cast5-arm.S (GET_DATA_POINTER): New.
+ (_gcry_cast5_arm_encrypt_block, _gcry_cast5_arm_decrypt_block)
+ (_gcry_cast5_arm_enc_blk2, _gcry_cast5_arm_dec_blk2): Use
+ GET_DATA_POINTER.
+ * cipher/rijndael-arm.S (GET_DATA_POINTER): New.
+ (_gcry_aes_arm_encrypt_block, _gcry_aes_arm_decrypt_block): Use
+ GET_DATA_POINTER.
+ * cipher/sha1-armv7-neon.S (GET_DATA_POINTER): New.
+ (.LK_VEC): Move from .text to .data section.
+ (_gcry_sha1_transform_armv7_neon): Use GET_DATA_POINTER.
+
+2014-05-17 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add Poly1305 to documentation.
+ + commit bf4943932dae95a0573b63bf32a9b9acd5a6ddf3
+ * doc/gcrypt.texi: Add documentation for Poly1305 MACs and AEAD mode.
+
+2014-05-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ chacha20: add SSE2/AMD64 optimized implementation.
+ + commit 323b1eb80ff3396d83fedbe5bba9a4e6c412d192
+ * cipher/Makefile.am: Add 'chacha20-sse2-amd64.S'.
+ * cipher/chacha20-sse2-amd64.S: New.
+ * cipher/chacha20.c (USE_SSE2): New.
+ [USE_SSE2] (_gcry_chacha20_amd64_sse2_blocks): New.
+ (chacha20_do_setkey) [USE_SSE2]: Use SSE2 implementation for blocks
+ function.
+ * configure.ac [host=x86-64]: Add 'chacha20-sse2-amd64.lo'.
+
+ poly1305: add AMD64/AVX2 optimized implementation.
+ + commit 98f021961ee65669037bc8bb552a69fd78f610fc
+ * cipher/Makefile.am: Add 'poly1305-avx2-amd64.S'.
+ * cipher/poly1305-avx2-amd64.S: New.
+ * cipher/poly1305-internal.h (POLY1305_USE_AVX2)
+ (POLY1305_AVX2_BLOCKSIZE, POLY1305_AVX2_STATESIZE)
+ (POLY1305_AVX2_ALIGNMENT): New.
+ (POLY1305_LARGEST_BLOCKSIZE, POLY1305_LARGEST_STATESIZE)
+ (POLY1305_STATE_ALIGNMENT): Use AVX2 versions when needed.
+ * cipher/poly1305.c [POLY1305_USE_AVX2]
+ (_gcry_poly1305_amd64_avx2_init_ext)
+ (_gcry_poly1305_amd64_avx2_finish_ext)
+ (_gcry_poly1305_amd64_avx2_blocks, poly1305_amd64_avx2_ops): New.
+ (_gcry_poly1305_init) [POLY1305_USE_AVX2]: Use AVX2 implementation if
+ AVX2 supported by CPU.
+ * configure.ac [host=x86_64]: Add 'poly1305-avx2-amd64.lo'.
+
+2014-05-12 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ poly1305: add AMD64/SSE2 optimized implementation.
+ + commit 297532602ed2d881d8fdc393d1961068a143a891
+ * cipher/Makefile.am: Add 'poly1305-sse2-amd64.S'.
+ * cipher/poly1305-internal.h (POLY1305_USE_SSE2)
+ (POLY1305_SSE2_BLOCKSIZE, POLY1305_SSE2_STATESIZE)
+ (POLY1305_SSE2_ALIGNMENT): New.
+ (POLY1305_LARGEST_BLOCKSIZE, POLY1305_LARGEST_STATESIZE)
+ (POLY1305_STATE_ALIGNMENT): Use SSE2 versions when needed.
+ * cipher/poly1305-sse2-amd64.S: New.
+ * cipher/poly1305.c [POLY1305_USE_SSE2]
+ (_gcry_poly1305_amd64_sse2_init_ext)
+ (_gcry_poly1305_amd64_sse2_finish_ext)
+ (_gcry_poly1305_amd64_sse2_blocks, poly1305_amd64_sse2_ops): New.
+ (_gcry_polu1305_init) [POLY1305_USE_SSE2]: Use SSE2 version.
+ * configure.ac [host=x86_64]: Add 'poly1305-sse2-amd64.lo'.
+
+ Add Poly1305 based cipher AEAD mode.
+ + commit e813958419b0ec4439e6caf07d3b2234cffa2bfa
+ * cipher/Makefile.am: Add 'cipher-poly1305.c'.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add 'u_mode.poly1305'.
+ (_gcry_cipher_poly1305_encrypt, _gcry_cipher_poly1305_decrypt)
+ (_gcry_cipher_poly1305_setiv, _gcry_cipher_poly1305_authenticate)
+ (_gcry_cipher_poly1305_get_tag, _gcry_cipher_poly1305_check_tag): New.
+ * cipher/cipher-poly1305.c: New.
+ * cipher/cipher.c (_gcry_cipher_open_internal, cipher_setkey)
+ (cipher_reset, cipher_encrypt, cipher_decrypt, _gcry_cipher_setiv)
+ (_gcry_cipher_authenticate, _gcry_cipher_gettag)
+ (_gcry_cipher_checktag): Handle 'GCRY_CIPHER_MODE_POLY1305'.
+ (cipher_setiv): Move handling of 'GCRY_CIPHER_MODE_GCM' to ...
+ (_gcry_cipher_setiv): ... here, as with other modes.
+ * src/gcrypt.h.in: Add 'GCRY_CIPHER_MODE_POLY1305'.
+ * tests/basic.c (_check_poly1305_cipher, check_poly1305_cipher): New.
+ (check_ciphers): Add Poly1305 check.
+ (check_cipher_modes): Call 'check_poly1305_cipher'.
+ * tests/bench-slope.c (bench_gcm_encrypt_do_bench): Rename to
+ bench_aead_... and take nonce as argument.
+ (bench_gcm_decrypt_do_bench, bench_gcm_authenticate_do_bench): Ditto.
+ (bench_gcm_encrypt_do_bench, bench_gcm_decrypt_do_bench)
+ (bench_gcm_authenticate_do_bench, bench_poly1305_encrypt_do_bench)
+ (bench_poly1305_decrypt_do_bench)
+ (bench_poly1305_authenticate_do_bench, poly1305_encrypt_ops)
+ (poly1305_decrypt_ops, poly1305_authenticate_ops): New.
+ (cipher_modes): Add Poly1305.
+ (cipher_bench_one): Add special handling for Poly1305.
+
+ Add Poly1305-AES (-Camellia, etc) MACs.
+ + commit 73b3b75c2221a6e3bed4117e0a206a1193acd2ed
+ * cipher/mac-internal.h (_gcry_mac_type_spec_poly1305_aes)
+ (_gcry_mac_type_spec_poly1305_camellia)
+ (_gcry_mac_type_spec_poly1305_twofish)
+ (_gcry_mac_type_spec_poly1305_serpent)
+ (_gcry_mac_type_spec_poly1305_seed): New.
+ * cipher/mac-poly1305.c (poly1305mac_context_s): Add 'hd' and
+ 'nonce_set'.
+ (poly1305mac_open, poly1305mac_close, poly1305mac_setkey): Add handling
+ for Poly1305-*** MACs.
+ (poly1305mac_prepare_key, poly1305mac_setiv): New.
+ (poly1305mac_reset, poly1305mac_write, poly1305mac_read): Add handling
+ for 'nonce_set'.
+ (poly1305mac_ops): Add 'poly1305mac_setiv'.
+ (_gcry_mac_type_spec_poly1305_aes)
+ (_gcry_mac_type_spec_poly1305_camellia)
+ (_gcry_mac_type_spec_poly1305_twofish)
+ (_gcry_mac_type_spec_poly1305_serpent)
+ (_gcry_mac_type_spec_poly1305_seed): New.
+ * cipher/mac.c (mac_list): Add Poly1305-AES, Poly1305-Twofish,
+ Poly1305-Serpent, Poly1305-SEED and Poly1305-Camellia.
+ * src/gcrypt.h.in: Add 'GCRY_MAC_POLY1305_AES',
+ 'GCRY_MAC_POLY1305_CAMELLIA', 'GCRY_MAC_POLY1305_TWOFISH',
+ 'GCRY_MAC_POLY1305_SERPENT' and 'GCRY_MAC_POLY1305_SEED'.
+ * tests/basic.c (check_mac): Add Poly1305-AES test vectors.
+ * tests/bench-slope.c (bench_mac_init): Set IV for Poly1305-*** MACs.
+ * tests/bench-slope.c (mac_bench): Set IV for Poly1305-*** MACs.
+
+ Add Poly1305 MAC.
+ + commit b8794fed68ebe7567f4617141f0996ad290d9120
+ * cipher/Makefile.am: Add 'mac-poly1305.c', 'poly1305.c' and
+ 'poly1305-internal.h'.
+ * cipher/mac-internal.h (poly1305mac_context_s): New.
+ (gcry_mac_handle): Add 'u.poly1305mac'.
+ (_gcry_mac_type_spec_poly1305mac): New.
+ * cipher/mac-poly1305.c: New.
+ * cipher/mac.c (mac_list): Add Poly1305.
+ * cipher/poly1305-internal.h: New.
+ * cipher/poly1305.c: New.
+ * src/gcrypt.h.in: Add 'GCRY_MAC_POLY1305'.
+ * tests/basic.c (check_mac): Add Poly1035 test vectors; Allow
+ overriding lengths of data and key buffers.
+ * tests/bench-slope.c (mac_bench): Increase max algo number from 500 to
+ 600.
+ * tests/benchmark.c (mac_bench): Ditto.
+
+ chacha20/AVX2: clear upper-halfs of YMM registers on entry.
+ + commit c20daeeb05329bfc6cc2c562cbd4b965291fe0e1
+ * cipher/chacha20-avx2-amd64.S (_gcry_chacha20_amd64_avx2_blocks): Add
+ 'vzeroupper' at beginning.
+
+ chacha20/AVX2: check for ENABLE_AVX2_SUPPORT instead of HAVE_GCC_INLINE_ASM_AVX2
+ + commit a3062db748f272e0f7346e1ed9e0bf7ed61a4eae
+ * cipher/chacha20.c (USE_AVX2): Enable depending on
+ ENABLE_AVX2_SUPPORT, not HAVE_GCC_INLINE_ASM_AVX2.
+ * cipher/chacha20-avx2-amd64.S: Ditto.
+
+ chacha20/SSSE3: clear XMM registers after use.
+ + commit a7d9eeeba632b7eb4a5b15ff17f6565181642f3c
+ * cipher/chacha20-ssse3-amd64.S (_gcry_chacha20_amd64_ssse3_blocks): On
+ return, clear XMM registers.
+
+2014-05-11 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ chacha20: add AVX2/AMD64 assembly implementation.
+ + commit a39ee7555691d18cae97560f130aaf952bfbd278
+ * cipher/Makefile.am: Add 'chacha20-avx2-amd64.S'.
+ * cipher/chacha20-avx2-amd64.S: New.
+ * cipher/chacha20.c (USE_AVX2): New macro.
+ [USE_AVX2] (_gcry_chacha20_amd64_avx2_blocks): New.
+ (chacha20_do_setkey): Select AVX2 implementation if there is HW
+ support.
+ (selftest): Increase size of buf by 256.
+ * configure.ac [host=x86-64]: Add 'chacha20-avx2-amd64.lo'.
+
+ chacha20: add SSSE3 assembly implementation.
+ + commit def7d4cad386271c6d4e2f10aabe0cb4abd871e4
+ * cipher/Makefile.am: Add 'chacha20-ssse3-amd64.S'.
+ * cipher/chacha20-ssse3-amd64.S: New.
+ * cipher/chacha20.c (USE_SSSE3): New macro.
+ [USE_SSSE3] (_gcry_chacha20_amd64_ssse3_blocks): New.
+ (chacha20_do_setkey): Select SSSE3 implementation if there is HW
+ support.
+ * configure.ac [host=x86-64]: Add 'chacha20-ssse3-amd64.lo'.
+
+ Add ChaCha20 stream cipher.
+ + commit 23f33d57c9b6f2295a8ddfc9a8eee5a2c30cf406
+ * cipher/Makefile.am: Add 'chacha20.c'.
+ * cipher/chacha20.c: New.
+ * cipher/cipher.c (cipher_list): Add ChaCha20.
+ * configure.ac: Add ChaCha20.
+ * doc/gcrypt.texi: Add ChaCha20.
+ * src/cipher.h (_gcry_cipher_spec_chacha20): New.
+ * src/gcrypt.h.in (GCRY_CIPHER_CHACHA20): Add new algo.
+ * tests/basic.c (MAX_DATA_LEN): Increase to 128 from 100.
+ (check_stream_cipher): Add ChaCha20 test-vectors.
+ (check_ciphers): Add ChaCha20.
+
+2014-05-09 Werner Koch <wk@gnupg.org>
+
+ mpi: Fix a subtle bug setting spurious bits with in mpi_set_bit.
+ + commit 246b7aaae1ee459f440260bbc4ec2c01c5dc3362
+ * mpi/mpi-bit.c (_gcry_mpi_set_bit, _gcry_mpi_set_highbit): Clear
+ allocated but not used bits before resizing.
+ * tests/t-mpi-bits.c (set_bit_with_resize): New.
+
+2014-05-07 Werner Koch <wk@gnupg.org>
+
+ Bump LT version.
+ + commit fc6ff6f73a51bcbbbb3757dc1386da40aa3ae75d
+ * configure.ac: Bumb LT version to C21/A1/R0.
+
+2014-04-22 Werner Koch <wk@gnupg.org>
+
+ random: Small patch for consistency and really burn the stack.
+ + commit a79c4ad7c56ee4410f17beb73eeb58b0dd36bfc6
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): s/int/size_t/.
+ (_gcry_rndlinux_gather_random): Replace memset by wipememory.
+
+2014-04-16 Werner Koch <wk@gnupg.org>
+
+ pubkey: Re-map all depreccated RSA algo numbers.
+ + commit 773e23698218755e9172d2507031a8263c47cc0b
+ * cipher/pubkey.c (map_algo): Mape RSA_E and RSA_S.
+
+2014-04-15 Werner Koch <wk@gnupg.org>
+
+ cipher: Fix possible NULL dereference.
+ + commit ae1fbce6dacf14747af0126e640bd4e54cb8c680
+ * cipher/md.c (_gcry_md_selftest): Check for spec being NULL.
+
+2014-03-30 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ 3des: add amd64 assembly implementation for 3DES.
+ + commit b76b632a453b8d100d024e2439b4358454dc286e
+ * cipher/Makefile.am: Add 'des-amd64.S'.
+ * cipher/cipher-selftests.c (_gcry_selftest_helper_cbc)
+ (_gcry_selftest_helper_cfb, _gcry_selftest_helper_ctr): Handle failures
+ from 'setkey' function.
+ * cipher/cipher.c (_gcry_cipher_open_internal) [USE_DES]: Setup bulk
+ functions for 3DES.
+ * cipher/des-amd64.S: New file.
+ * cipher/des.c (USE_AMD64_ASM, ATTR_ALIGNED_16): New macros.
+ [USE_AMD64_ASM] (_gcry_3des_amd64_crypt_block)
+ (_gcry_3des_amd64_ctr_enc), _gcry_3des_amd64_cbc_dec)
+ (_gcry_3des_amd64_cfb_dec): New prototypes.
+ [USE_AMD64_ASM] (tripledes_ecb_crypt): New function.
+ (TRIPLEDES_ECB_BURN_STACK): New macro.
+ (_gcry_3des_ctr_enc, _gcry_3des_cbc_dec, _gcry_3des_cfb_dec)
+ (bulk_selftest_setkey, selftest_ctr, selftest_cbc, selftest_cfb): New
+ functions.
+ (selftest): Add call to CTR, CBC and CFB selftest functions.
+ (do_tripledes_encrypt, do_tripledes_decrypt): Use
+ TRIPLEDES_ECB_BURN_STACK.
+ * configure.ac [host=x86-64]: Add 'des-amd64.lo'.
+ * src/cipher.h (_gcry_3des_ctr_enc, _gcry_3des_cbc_dec)
+ (_gcry_3des_cfb_dec): New prototypes.
+
+2014-03-13 Werner Koch <wk@gnupg.org>
+
+ tests: Print diagnostics for skipped tests.
+ + commit 50aeee51a0b1a09dd9fff2bb71749a816fe7a791
+ * tests/basic.c (show_note): New.
+ (show_md_not_available):
+ (show_old_hmac_not_available):
+ (show_mac_not_available):
+ (check_digests): Remove USE_foo cpp tests from the test table. Call
+ show_md_not_available if algo is not available.
+ (check_hmac): Likewise.
+ (check_mac): Likewise.
+
+2014-03-11 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Add MD2 message digest implementation.
+ + commit 5a8e1504bf8a2ffbc018be576dea77b685200444
+ * cipher/md2.c: New.
+ * cipher/md.c (digest_list): add _gcry_digest_spec_md2.
+ * tests/basic.c (check_digests): add MD2 test vectors.
+ * configure.ac (default_digests): disable md2 by default.
+
+2014-03-04 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Add an utility to calculate hashes over a set of files.
+ + commit 2b5403c408dfbd71be24c7635f5fa0b61ab4c9bb
+ * tests/gchash.c: New.
+
+ Add a simple (raw) PKCS#1 padding mode.
+ + commit ea8d597726305274214224757b32730644e12bd8
+ * src/cipher.h (PUBKEY_ENC_PKCS1_RAW): New.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Handle pkcs1-raw
+ flag.
+ * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi):
+ Handle s-exp like (data (flags pkcs1-raw) (value xxxxx))
+ * cipher/rsa-common.c (_gcry_rsa_pkcs1_encode_raw_for_sig):
+ PKCS#1-encode data with embedded hash OID for signature verification.
+ * tests/basic.c (check_pubkey_sign): Add tests for s-exps with pkcs1-raw
+ flag.
+
+2014-02-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix ARMv6 detection when CFLAGS modify target CPU architecture.
+ + commit 6be3032048ee2466511d2384fcf2d28b856219b2
+ * configure.ac (gcry_cv_cc_arm_arch_is_v6): Use compiler test instead
+ of preprocessor test.
+
+2014-01-29 Werner Koch <wk@gnupg.org>
+
+ Reserve control code for FIPS extensions.
+ + commit aea96a64fbc58a0b6f9f435e97e93294c6eb1052
+ * src/gcrypt.h.in (GCRYCTL_INACTIVATE_FIPS_FLAG): New.
+ (GCRYCTL_REACTIVATE_FIPS_FLAG): New.
+ * src/global.c (_gcry_vcontrol): Add them but return not_implemented.
+
+2014-01-29 NIIBE Yutaka <gniibe@fsij.org>
+
+ Fix RSA Blinding.
+ + commit 121a90d8931944974054f7d94f63b7f89df87fa5
+ * cipher/rsa.c (rsa_decrypt): Loop to get multiplicative inverse.
+
+2014-01-28 Werner Koch <wk@gnupg.org>
+
+ cipher: Take care of ENABLE_NEON_SUPPORT.
+ + commit 52f7c48c901a3de51bd690a218f3de2f71e8d790
+ * cipher/salsa20.c (USE_ARM_NEON_ASM): Define only if
+ ENABLE_NEON_SUPPORT is defined.
+ * cipher/serpent.c (USE_NEON): Ditto.
+ * cipher/sha1.c (USE_NEON): Ditto.
+ * cipher/sha512.c (USE_ARM_NEON_ASM): Ditto.
+
+ sexp: Fix broken gcry_sexp_nth.
+ + commit cbdc355415f83ed62da4f3618767eba54d7e6d37
+ * src/sexp.c (_gcry_sexp_nth): Return a valid S-expression for a data
+ element.
+ (NODE): Remove unused typedef.
+ (ST_HINT): Comment unused macro.
+
+ * tests/t-sexp.c (bug_1594): New.
+ (main): Run new test.
+
+2014-01-27 Werner Koch <wk@gnupg.org>
+
+ tests: Improve t-common.h.
+ + commit 7460e9243b3cc050631c37ed4f2713ae7bcb6762
+ * tests/t-common.h: Add couple of macros. Check that config.h has
+ been included.
+ (show): Rename to info.
+ * tests/t-lock.c, tests/t-sexp.c: Adjust for changes.
+
+ mpi: Minor fix for Atari-mint.
+ + commit 3caa0f1319dc4779e0d6eee4460c1af2a12b2c3c
+ * mpi/config.links [m68k-atari-mint]: Do not assume 68020. Suggested
+ by Alan Hourihane.
+
+ (cherry picked from commit 420f42a5752e90a8b27d58ffa1ddfe6e4ab341e8)
+
+2014-01-27 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Fix most of memory leaks in tests code.
+ + commit 5c150ece094bf0a504a111ce6c7b72e8d0b0457a
+ * tests/basic.c (check_ccm_cipher): Close cipher after use.
+ * tests/basic.c (check_one_cipher): Correct length of used buffer.
+ * tests/benchmark.c (cipher_bench): Use xcalloc to make buffer
+ initialized.
+ * tests/keygen.c (check_ecc_keys): Release generated key.
+ * tests/t-mpi-point.c (context_param): Release mpi Q.
+ * tests/t-sexp.c (check_extract_param): Release extracted number.
+
+ Fix memory leaks in ecc code.
+ + commit 6d87e6abdfb7552323a95401f14e6367398a3e5a
+ * cipher/ecc-curves.c (_gcry_ecc_update_curve_param): Release passed mpi
+ values.
+ * cipher/ecc.c (compute_keygrip): Fix potential memory leak in error
+ path.
+ * cipher/ecc.c (_gcry_ecc_get_curve): Release temporary mpi.
+
+ Fix number of blocks passed used in _gcry_rmd160_mixblock.
+ + commit 5d23e7b9a77421f3ebfda4a84c459a8729f3bb41
+ * cipher/rmd160.c (_gcry_rmd160_mixblock): pass 1 to transform
+
+2014-01-27 Werner Koch <wk@gnupg.org>
+
+ Small Windows build tweaks.
+ + commit f7df906171854b6b6506b82d4fee2c2ebb0327ea
+ * configure.ac (HAVE_PTHREAD): Do test when building for Windows.
+
+ * tests/basic.c: Replace "%zi" by "%z" and a cast to make it work
+ under Windows.
+
+ Update gpg-error autoconf macros to fix threading problems.
+ + commit 79da0358fd555361e1ce4202f55494a8918eb8ae
+ * m4/gpg-error.m4: Update to version 2014-01-24.
+ * tests/Makefile.am (t_lock_LDADD): Use MT Libs.
+
+2014-01-24 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ tests: Pass -no-install to libtool.
+ + commit bf34bfa5c458ee5ece91f25e3b4194d768498ab6
+ * tests/Makefile.am: add AM_LDFLAGS = -no-install
+
+2014-01-24 Werner Koch <wk@gnupg.org>
+
+ tests: Add a test for the internal locking.
+ + commit ff91ec934ed52294cddcd7dcfacc04721a0487bf
+ * src/global.c (external_lock_test): New.
+ (_gcry_vcontrol): Call new function with formerly reserved code 61.
+
+ * tests/t-common.h: New. Taken from current libgpg-error.
+ * tests/t-lock.c: New. Based on t-lock.c from libgpg-error.
+ * configure.ac (HAVE_PTHREAD): Set macro to 1 if defined.
+ (AC_CHECK_FUNCS): Check for flockfile.
+ * tests/Makefile.am (tests_bin): Add t-lock.
+ (noinst_HEADERS): Add t-common.h
+ (LDADD): Move value to ...
+ (default_ldadd): new.
+ (t_lock_LDADD): New.
+
+ Check compiler features only for the relevant platform.
+ + commit 24e65d715812cea28732397870cb1585b8435521
+ * mpi/config.links (mpi_cpu_arch): Always set for ARM. Set for HPPA.
+ Set to "undefined" for unknown platforms.
+ (try_asm_modules): Act upon only after having detected the CPU.
+ * configure.ac: Move the call to config.links before the platform
+ specific compiler checks. Check platform specific features only if
+ the platform is targeted.
+
+2014-01-23 Werner Koch <wk@gnupg.org>
+
+ Support building using the latest mingw-w64 toolchain.
+ + commit 4ad3417acab5021db1f722c314314ce4b781833a
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Change mingw detection.
+
+2014-01-20 Werner Koch <wk@gnupg.org>
+
+ cipher: Fix commit 94030e44.
+ + commit dad06e4d1b835bac778b87090b1d3894b7535b14
+ * cipher/tiger.c (tiger_init): Add arg FLAGS.
+ (tiger1_init, tiger2_init): Ditto.
+
+ tests: Rename tsexp.c.
+ + commit 192e77d123fdb04c459c998b9eb1731618a833fa
+ * tests/tsexp.c: Rename to t-sexp.c
+
+2014-01-19 Werner Koch <wk@gnupg.org>
+
+ md: Add Whirlpool bug emulation feature.
+ + commit 94030e44aaff805d754e368507f16dd51a531b72
+ * src/gcrypt.h.in (GCRY_MD_FLAG_BUGEMU1): New.
+ * src/cipher-proto.h (gcry_md_init_t): Add arg FLAGS. Change all code
+ to implement that flag.
+ * cipher/md.c (gcry_md_context): Replace SECURE and FINALIZED by bit
+ field FLAGS. Add flag BUGEMU1. Change all users.
+ (md_open): Replace args SECURE and HMAC by FLAGS. Init flags.bugemu1.
+ (_gcry_md_open): Add for GCRY_MD_FLAG_BUGEMU1.
+ (md_enable): Pass bugemu1 flag to the hash init function.
+ (_gcry_md_reset): Ditto.
+
+2014-01-17 Werner Koch <wk@gnupg.org>
+
+ Actually check for uint64_t.
+ + commit c3b30bae7d1e157f8b65e32ba1b3a516f2bbf58b
+ * configure.ac: Check size of uint64_t and the UINT64_C macro.
+
+2014-01-16 Werner Koch <wk@gnupg.org>
+
+ Replace ath based mutexes by gpgrt based locks.
+ + commit cfc151ba637200e4fc05d9481a8df2071b2f9a47
+ * configure.ac (NEED_GPG_ERROR_VERSION): Require 1.13.
+ (gl_LOCK): Remove.
+ * src/ath.c, src/ath.h: Remove. Remove from all files. Replace all
+ mutexes by gpgrt based statically initialized locks.
+ * src/global.c (global_init): Remove ath_init.
+ (_gcry_vcontrol): Make ath install a dummy function.
+ (print_config): Remove threads info line.
+
+ * doc/gcrypt.texi: Simplify the multi-thread related documentation.
+
+2014-01-15 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Fix _gcry_mpi_ec_p_new to allow secp256k1.
+ + commit 49edeebb43174865cf4fa2c170a42a8e4274c4f0
+ * mpi/ec.c (_gcry_mpi_ec_p_new): Remove checking a!=0.
+ * tests/t-mpi-point.c (context_alloc): Remove two spurious tests.
+
+2014-01-14 Milan Broz <gmazyland@gmail.com>
+
+ PBKDF2: Use gcry_md_reset to speed up calculation.
+ + commit 04cda6b7cc16f3f52c12d9d3e46c56701003496e
+ * cipher/kdf.c (_gcry_kdf_pkdf2): Use gcry_md_reset
+ to speed up calculation.
+
+2014-01-13 Werner Koch <wk@gnupg.org>
+
+ Fix macro conflict in NetBSD.
+ + commit 5f2af6c26bc04975c0b518881532871d7387d7ce
+ * cipher/bithelp.h (bswap32): Rename to _gcry_bswap32.
+ (bswap64): Rename to _gcry_bswap64.
+
+ Use internal malloc function in fips.c.
+ + commit 518ae274a1845ce626b2b4223a9b3805cbbab1a7
+ * src/fips.c (check_binary_integrity): s/gcry_malloc/xtrymalloc/.
+
+2014-01-13 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Truncate hash values for ECDSA signature scheme.
+ + commit 9edcf1090e0485f9f383b6c54b18ea8ca3d4a225
+ * cipher/dsa-common (_gcry_dsa_normalize_hash): New. Truncate opaque
+ mpis as required for DSA and ECDSA signature schemas.
+ * cipher/dsa.c (verify): Return gpg_err_code_t value from verify() to
+ behave like the rest of internal sign/verify functions.
+ * cipher/dsa.c (sign, verify, dsa_verify): Factor out hash truncation.
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Factor out hash truncation.
+ * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_verify):
+ as required by ECDSA scheme, truncate hash values to bitlength of
+ used curve.
+ * tests/pubkey.c (check_ecc_sample_key): add a testcase for hash
+ truncation.
+
+ Add GOST R 34.10-2012 curves proposed by TC26.
+ + commit 2c5ec803100ed8261e51442fb93b75367b7725ea
+ * cipher/ecc-curves.c (domain_parmss): Add two GOST R 34.10-2012 curves
+ proposed/pending to standardization by TC26 (Russian cryptography
+ technical comitee).
+ * cipher/ecc-curves.c (curve_alias): Add OID aliases.
+ * tests/curves.c: Increase N_CURVES.
+
+ Add GOST R 34.10-2001 curves per RFC4357.
+ + commit 9bedc5c3b646dfe481678ca58f5466ac46decaf7
+ * cipher/ecc-curves.c (domain_parms): Add 3 curves defined in rfc4357.
+ * cipher/ecc-curves.c (curve_aliases): Add OID and Xch aliases for GOST
+ curves.
+ * tests/curves.c (N_CURVES): Update value.
+
+ Fix typo in search_oid.
+ + commit 7edcb574d8d6dffb6e234c2ba1996a9a04923859
+ * cipher/md.c (search_oid): Invert condition on oid comparison.
+
+ Add MD2-HMAC calculation support.
+ + commit 653b58cb5e85511b6c04c3f85ef3e372c2e9f74f
+ * src/gcrypt.h.in (GCRY_MAC_HMAC_MD2): New.
+ * cipher/mac-hmac.c: Support GCRY_MAC_HMAC_MD2.
+
+ Add a function to retrieve algorithm used by MAC handler.
+ + commit 8439a379c86ef1088465ea70ac10840759a1638e
+ * cipher/mac.c (_gcry_mac_get_algo): New function, returns used algo.
+ * src/visibility.c (gcry_mac_get_algo): New wrapper.
+ * src/visibility.h: Hanlde gcry_mac_get_algo.
+ * src/gcrypt-int.h (_gcry_mac_get_algo): New.
+ * src/gcrypt.h.in (gcry_mac_get_algo): New.
+ * src/libgcrypt.def (gcry_mac_get_algo): New.
+ * src/libgcrypt.vers (gcry_mac_get_algo): New.
+ * doc/gcrypt.texi: Document gcry_mac_get_algo.
+ * tests/basic.c (check_one_mac): Verify gcry_mac_get_algo.
+
+ Correct formatting of gcry_mac_get_algo_keylen documentation.
+ + commit 36c9e0e4eb4f935da90df1c8df484d1940bda5eb
+ * doc/gcrypt.texi: add braces near gcry_mac_get_algo_keylen
+ documentation.
+
+ Use braces around unsigned int in gcry_mac_get_algo_keylen
+ documentation, otherwise texinfo breaks that and uses 'int' as a
+ function definition.
+
+2014-01-13 Werner Koch <wk@gnupg.org>
+
+ ecc: Make a macro shorter.
+ + commit 2ef48ba59c32bfa1a9265d5eea8ab225a658903a
+ * src/mpi.h (MPI_EC_TWISTEDEDWARDS): Rename to MPI_EC_EDWARDS. CHnage
+ all users.
+ * cipher/ecc-curves.c (domain_parms): Add parameters for Curve3617 as
+ comment.
+ * mpi/ec.c (dup_point_twistededwards): Rename to dup_point_edwards.
+ (add_points_twistededwards): Rename to add_points_edwards.
+
+2014-01-12 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix assembly division check.
+ + commit ef3e66e168c4b9b86bfc4903001631e53a7125d8
+ * configure.ac (gcry_cv_gcc_as_const_division_ok): Correct variable
+ name mismatch at '--Wa,--divide' workaround check.
+
+2014-01-12 NIIBE Yutaka <gniibe@fsij.org>
+
+ Add secp256k1 curve.
+ + commit 019e0e9e8c77a2edf283745e05e9301673ea6a0a
+ * cipher/ecc-curves.c (curve_aliases): Add secp256k1 and its OID.
+ (domain_parms): Add secp256k1's domain paramerter.
+
+ * tests/basic.c (check_pubkey): Add a key of secp256k1.
+
+ * tests/curves.c (N_CURVES): Updated.
+
+2014-01-12 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix constant division for AMD64 assembly on Solaris/x86.
+ + commit 43376891c01f4aff1fbfb23beafebb5adfd0868c
+ * configure.ac (gcry_cv_gcc_as_const_division_ok): Add new check for
+ constant division in assembly and test for "-Wa,--divide" workaround.
+ (gcry_cv_gcc_amd64_platform_as_ok): Check for also constant division.
+
+2014-01-10 Werner Koch <wk@gnupg.org>
+
+ Use the generic autogen.sh script.
+ + commit b0ac1f9b143aa15855914ba93fef900288d45c9c
+ * autogen.rc: New.
+ * Makefile.am (EXTRA_DIST): Add it.
+ * autogen.sh: Update from current GnuPG.
+
+ Move all helper scripts to build-aux/
+ + commit df9b4eabf52faee6f289a4bc62219684442ae383
+ * scripts/: Rename to build-aux/.
+ * compile, config.guess, config.rpath, config.sub
+ * depcomp, doc/mdate-sh, doc/texinfo.tex
+ * install-sh, ltmain.sh, missing: Move to build-aux/.
+ * Makefile.am (EXTRA_DIST): Adjust.
+ * configure.ac (AC_CONFIG_AUX_DIR): New.
+ (AM_SILENT_RULES): New.
+
+2013-12-30 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add blowfish/serpent ARM assembly files to Makefile.am.
+ + commit 7fef7f481c0a1542be34d1dc831f58d41846ac29
+ * cipher/Makefile.am: Add 'blowfish-arm.S' and 'serpent-armv7-neon.S'.
+
+ Add AMD64 assembly implementation for arcfour.
+ + commit 7547898109c72a97e3102b2a045ee4fdb2aa40bf
+ * cipher/Makefile.am: Add 'arcfour-amd64.S'.
+ * cipher/arcfour-amd64.S: New.
+ * cipher/arcfour.c (USE_AMD64_ASM): New.
+ [USE_AMD64_ASM] (ARCFOUR_context, _gcry_arcfour_amd64)
+ (encrypt_stream): New.
+ * configure.ac [host=x86_64]: Add 'arcfour-amd64.lo'.
+
+ Parse /proc/cpuinfo for ARM HW features.
+ + commit a05be441d8cd89b90d8d58e3a343a436dae377d0
+ * src/hwf-arm.c [__linux__] (HAS_PROC_CPUINFO)
+ (detect_arm_proc_cpuinfo): New.
+ (_gcry_hwf_detect_arm) [HAS_PROC_CPUINFO]: Check '/proc/cpuinfo' for
+ HW features.
+
+ Fix buggy/incomplete detection of AVX/AVX2 support.
+ + commit bbcb12187afb1756cb27296166b57fa19ee45d4d
+ * configure.ac: Also check for 'xgetbv' instruction in AVX and AVX2
+ inline assembly checks.
+ * src/hwf-x86.c [__i386__] (get_xgetbv): New function.
+ [__x86_64__] (get_xgetbv): New function.
+ [HAS_X86_CPUID] (detect_x86_gnuc): Check for OSXSAVE and OS support for
+ XMM&YMM registers and enable AVX/AVX2 only if XMM&YMM registers are
+ supported by OS.
+
+2013-12-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Change utf-8 copyright characters to '(C)'
+ + commit b7e814f93ee40fcfe17a187a8989c07fde2ba0cd
+ cipher/blowfish-amd64.S: Change utf-8 encoded copyright character to
+ '(C)'.
+ cipher/blowfish-arm.S: Ditto.
+ cipher/bufhelp.h: Ditto.
+ cipher/camellia-aesni-avx-amd64.S: Ditto.
+ cipher/camellia-aesni-avx2-amd64.S: Ditto.
+ cipher/camellia-arm.S: Ditto.
+ cipher/cast5-amd64.S: Ditto.
+ cipher/cast5-arm.S: Ditto.
+ cipher/cipher-ccm.c: Ditto.
+ cipher/cipher-cmac.c: Ditto.
+ cipher/cipher-gcm.c: Ditto.
+ cipher/cipher-selftest.c: Ditto.
+ cipher/cipher-selftest.h: Ditto.
+ cipher/mac-cmac.c: Ditto.
+ cipher/mac-gmac.c: Ditto.
+ cipher/mac-hmac.c: Ditto.
+ cipher/mac-internal.h: Ditto.
+ cipher/mac.c: Ditto.
+ cipher/rijndael-amd64.S: Ditto.
+ cipher/rijndael-arm.S: Ditto.
+ cipher/salsa20-amd64.S: Ditto.
+ cipher/salsa20-armv7-neon.S: Ditto.
+ cipher/serpent-armv7-neon.S: Ditto.
+ cipher/serpent-avx2-amd64.S: Ditto.
+ cipher/serpent-sse2-amd64.S: Ditto.
+
+ Add ARM/NEON implementation for SHA-1.
+ + commit fc7dcf616937afaf73cfda1bf7bd79566a96b130
+ * cipher/Makefile.am: Add 'sha1-armv7-neon.S'.
+ * cipher/sha1-armv7-neon.S: New.
+ * cipher/sha1.c (USE_NEON): New.
+ (SHA1_CONTEXT, sha1_init) [USE_NEON]: Add and initialize 'use_neon'.
+ [USE_NEON] (_gcry_sha1_transform_armv7_neon): New.
+ (transform) [USE_NEON]: Use ARM/NEON assembly if enabled.
+ * configure.ac: Add 'sha1-armv7-neon.lo'.
+
+ Improve performance of SHA-512/ARM/NEON implementation.
+ + commit df629ba53a662427ebd3ddca90c3fe9ddd6511d3
+ * cipher/sha512-armv7-neon.S (RT01q, RT23q, RT45q, RT67q): New.
+ (round_0_63, round_64_79): Remove.
+ (rounds2_0_63, rounds2_64_79): New.
+ (_gcry_sha512_transform_armv7_neon): Add 'nblks' input; Handle multiple
+ input blocks; Use new round macros.
+ * cipher/sha512.c [USE_ARM_NEON_ASM]
+ (_gcry_sha512_transform_armv7_neon): Add 'num_blks'.
+ (transform) [USE_ARM_NEON_ASM]: Pass nblks to assembly.
+
+ Add AVX and AVX2/BMI implementations for SHA-256.
+ + commit a5c2bbfe0db515d739ab683297903c77b1eec124
+ * LICENSES: Add 'cipher/sha256-avx-amd64.S' and
+ 'cipher/sha256-avx2-bmi2-amd64.S'.
+ * cipher/Makefile.am: Add 'sha256-avx-amd64.S' and
+ 'sha256-avx2-bmi2-amd64.S'.
+ * cipher/sha256-avx-amd64.S: New.
+ * cipher/sha256-avx2-bmi2-amd64.S: New.
+ * cipher/sha256-ssse3-amd64.S: Use 'lea' instead of 'add' in few
+ places for tiny speed improvement.
+ * cipher/sha256.c (USE_AVX, USE_AVX2): New.
+ (SHA256_CONTEXT) [USE_AVX, USE_AVX2]: Add 'use_avx' and 'use_avx2'.
+ (sha256_init, sha224_init) [USE_AVX, USE_AVX2]: Initialize above
+ new context members.
+ [USE_AVX] (_gcry_sha256_transform_amd64_avx): New.
+ [USE_AVX2] (_gcry_sha256_transform_amd64_avx2): New.
+ (transform) [USE_AVX2]: Use AVX2 assembly if enabled.
+ (transform) [USE_AVX]: Use AVX assembly if enabled.
+ * configure.ac: Add 'sha256-avx-amd64.lo' and
+ 'sha256-avx2-bmi2-amd64.lo'.
+
+2013-12-17 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add AVX and AVX/BMI2 implementations for SHA-1.
+ + commit e4e458465b124e25b6aec7a60174bf1ca32dc5fd
+ * cipher/Makefile.am: Add 'sha1-avx-amd64.S' and
+ 'sha1-avx-bmi2-amd64.S'.
+ * cipher/sha1-avx-amd64.S: New.
+ * cipher/sha1-avx-bmi2-amd64.S: New.
+ * cipher/sha1.c (USE_AVX, USE_BMI2): New.
+ (SHA1_CONTEXT) [USE_AVX]: Add 'use_avx'.
+ (SHA1_CONTEXT) [USE_BMI2]: Add 'use_bmi2'.
+ (sha1_init): Initialize 'use_avx' and 'use_bmi2'.
+ [USE_AVX] (_gcry_sha1_transform_amd64_avx): New.
+ [USE_BMI2] (_gcry_sha1_transform_amd64_bmi2): New.
+ (transform) [USE_BMI2]: Use BMI2 assembly if enabled.
+ (transform) [USE_AVX]: Use AVX assembly if enabled.
+ * configure.ac: Add 'sha1-avx-amd64.lo' and 'sha1-avx-bmi2-amd64.lo'.
+
+ SHA-1/SSSE3: Improve performance on large buffers.
+ + commit 6fd0dd2a5f1362f91e2861cd9d300341a43842a5
+ * cipher/sha1-ssse3-amd64.S (RNBLKS): New.
+ (_gcry_sha1_transform_amd64_ssse3): Handle multiple input blocks, with
+ software pipelining of next data block processing.
+ * cipher/sha1.c [USE_SSSE3] (_gcry_sha1_transform_amd64_ssse3): Add
+ 'nblks'.
+ (transform) [USE_SSSE3]: Pass nblks to assembly function.
+
+ Add bulk processing for hash transform functions.
+ + commit 50b8c8342d023038a4b528af83153293dd2756ea
+ * cipher/hash-common.c (_gcry_md_block_write): Preload 'hd->blocksize'
+ to stack, pass number of blocks to 'hd->bwrite'.
+ * cipher/hash-common.c (_gcry_md_block_write_t): Add 'nblks'.
+ * cipher/gostr3411-94.c: Rename 'transform' function to
+ 'transform_blk', add new 'transform' function with 'nblks' as
+ additional input.
+ * cipher/md4.c: Ditto.
+ * cipher/md5.c: Ditto.
+ * cipher/md4.c: Ditto.
+ * cipher/rmd160.c: Ditto.
+ * cipher/sha1.c: Ditto.
+ * cipher/sha256.c: Ditto.
+ * cipher/sha512.c: Ditto.
+ * cipher/stribog.c: Ditto.
+ * cipher/tiger.c: Ditto.
+ * cipher/whirlpool.c: Ditto.
+
+2013-12-16 Werner Koch <wk@gnupg.org>
+
+ Release 1.6.0.
+ + commit 0ea9731e1c93a962f6266004ab0e7418c19d6277
+
+
+ doc: Change yat2m to allow arbitrary condition names.
+ + commit 9a912f8c4f366c53f1cdb94513b67b937e87178b
+ * doc/yat2m.c (MAX_CONDITION_NESTING): New.
+ (gpgone_defined): Remove.
+ (condition_s, condition_stack, condition_stack_idx): New.
+ (cond_is_active, cond_in_verbatim): New.
+ (add_predefined_macro, set_macro, macro_set_p): New.
+ (evaluate_conditions, push_condition, pop_condition): New.
+ (parse_file): Rewrite to use the condition stack.
+ (top_parse_file): Set prefined macros.
+ (main): Change -D to define arbitrary macros.
+
+ tests: Add SHA-512 to the long hash test.
+ + commit 0d3bd23d7f730b9bbc81fc8da8d99f4853c36020
+ * tests/hashtest.c (testvectors): Add vectors for 256GiB SHA-512.
+ * tests/hashtest-256g.in (algos): Add test for SHA-512.
+
+ Add configure option --enable-large-data-tests.
+ + commit a6b9304a889397ac98e1c2c4ac3e178669d94492
+ * configure.ac: Add option --enable-large-data-tests.
+ * tests/hashtest-256g.in: New.
+ * tests/Makefile.am (EXTRA_DIST): Add hashtest-256g.in.
+ (TESTS): Split up into tests_bin, tests_bin_last, tests_sh, and
+ tests_sh_last.
+ (tests_sh_last): Add hashtest-256g
+ (noinst_PROGRAMS): Add only tests_bin and tests_bin_last.
+ (bench-slope.log, hashtest-256g.log): New rules to enforce serial run.
+
+ random: Call random progress handler more often.
+ + commit 5a7ce59396fe56f0d681df314bfbdb5f7732d4b1
+ * random/rndlinux.c (_gcry_rndlinux_gather_random): Update progress
+ indicator earlier.
+
+ cipher: Normalize the MPIs used as input to secret key functions.
+ + commit dec048b2ec79271a2f4405be5b87b1e768b3f1a9
+ * cipher/dsa.c (sign): Normalize INPUT.
+ * cipher/elgamal.c (decrypt): Normalize A and B.
+ * cipher/rsa.c (secret): Normalize the INPUT.
+ (rsa_decrypt): Reduce DATA before passing to secret.
+
+2013-12-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Change dummy variable in mpih-div.c to mpi_limb_t type.
+ + commit 953535a7de68cf62b5b1ad6f96ea3a9edd83762c
+ * mpi/mpih-div.c (_gcry_mpih_mod_1, _gcry_mpih_divmod_1): Change dummy
+ variable to 'mpi_limb_t' type from 'int'.
+
+ Remove duplicate gcry_mac_hd_t typedef.
+ + commit 5c31990214b58c4e17edb01fbbe6d9f573975a22
+ * cipher/mac-internal.h (gcry_mac_hd_t): Remove.
+
+2013-12-15 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Use u64 for CCM data lengths.
+ + commit 110fed2d6b0bbc97cb5cc0a3a564e05fc42afa2d
+ * cipher/cipher-ccm.c: Move code inside [HAVE_U64_TYPEDEF].
+ [HAVE_U64_TYPEDEF] (_gcry_cipher_ccm_set_lengths): Use 'u64' for
+ data lengths.
+ [!HAVE_U64_TYPEDEF] (_gcry_cipher_ccm_encrypt)
+ (_gcry_cipher_ccm_decrypt, _gcry_cipher_ccm_set_nonce)
+ (_gcry_cipher_ccm_authenticate, _gcry_cipher_ccm_get_tag)
+ (_gcry_cipher_ccm_check_tag): Dummy functions returning
+ GPG_ERROR_NOT_SUPPORTED.
+ * cipher/cipher-internal.h (gcry_cipher_handle.u_mode.ccm)
+ (_gcry_cipher_ccm_set_lengths): Move inside [HAVE_U64_TYPEDEF] and use
+ u64 instead of size_t for CCM data lengths.
+ * cipher/cipher.c (_gcry_cipher_open_internal, cipher_reset)
+ (_gcry_cipher_ctl) [!HAVE_U64_TYPEDEF]: Return GPG_ERR_NOT_SUPPORTED
+ for CCM.
+ (_gcry_cipher_ctl) [HAVE_U64_TYPEDEF]: Use u64 for
+ GCRYCTL_SET_CCM_LENGTHS length parameters.
+ * tests/basic.c: Do not use CCM if !HAVE_U64_TYPEDEF.
+ * tests/bench-slope.c: Ditto.
+ * tests/benchmark.c: Ditto.
+
+2013-12-14 Werner Koch <wk@gnupg.org>
+
+ tests: Prevent rare failure of gcry_pk_decrypt test.
+ + commit bfb43a17d8db571fca4ed433ee8be5c366745844
+ * tests/basic.c (check_pubkey_crypt): Add special mode 1.
+ (main): Add option --loop.
+
+2013-12-14 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Minor fixes to SHA assembly implementations.
+ + commit ffd9b2aa5abda7f4d7790ed48116ed5d71ab9995
+ * cipher/Makefile.am: Correct 'sha256-avx*.S' to 'sha512-avx*.S'.
+ * cipher/sha1-ssse3-amd64.S: First line, correct filename.
+ * cipher/sha256-ssse3-amd64.S: Return correct stack burn depth.
+ * cipher/sha512-avx-amd64.S: Use 'vzeroall' to clear registers.
+ * cipher/sha512-avx2-bmi2-amd64.S: Ditto and return correct stack burn
+ depth.
+
+ SHA-1/SSSE3: Do not check for Intel syntax assembly support.
+ + commit c86c35534a153b13e880d0bb0ea3e48e1c0ecaf9
+ * cipher/sha1-ssse3-amd64.S: Remove check for
+ HAVE_INTEL_SYNTAX_PLATFORM_AS.
+ * cipher/sha1.c [USE_SSSE3]: Ditto.
+
+2013-12-13 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Convert SHA-1 SSSE3 implementation from mixed asm&C to pure asm.
+ + commit d2b853246c2ed056a92096d89c3ca057e45c9c92
+ * cipher/Makefile.am: Change 'sha1-ssse3-amd64.c' to
+ 'sha1-ssse3-amd64.S'.
+ * cipher/sha1-ssse3-amd64.c: Remove.
+ * cipher/sha1-ssse3-amd64.S: New.
+
+ SHA-1: Add SSSE3 implementation.
+ + commit be2238f68abcc6f2b4e8c38ad9141376ce622a22
+ * cipher/Makefile.am: Add 'sha1-ssse3-amd64.c'.
+ * cipher/sha1-ssse3-amd64.c: New.
+ * cipher/sha1.c (USE_SSSE3): New.
+ (SHA1_CONTEXT) [USE_SSSE3]: Add 'use_ssse3'.
+ (sha1_init) [USE_SSSE3]: Initialize 'use_ssse3'.
+ (transform): Rename to...
+ (_transform): this.
+ (transform): New.
+ * configure.ac [host=x86_64]: Add 'sha1-ssse3-amd64.lo'.
+
+ Add missing register clearing in to SHA-256 and SHA-512 assembly.
+ + commit 04615cc6803cdede25fa92e3ff697e252a23cd7a
+ * cipher/sha256-ssse3-amd64.S: Clear used XMM/YMM registers at return.
+ * cipher/sha512-avx-amd64.S: Ditto.
+ * cipher/sha512-avx2-bmi2-amd64.S: Ditto.
+ * cipher/sha512-ssse3-amd64.S: Ditto.
+
+2013-12-13 Werner Koch <wk@gnupg.org>
+
+ Update license information.
+ + commit 764643a3d5634bcbc47790bd8505f6a1a5280d9c
+ * LICENSES: New.
+ * Makefile.am (EXTRA_DIST): Add LICENSES.
+ * AUTHORS: Add list of copyright holders.
+ * README: Reference AUTHORS.
+
+2013-12-13 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix empty clobber in AVX2 assembly check.
+ + commit e41d605ee41469e8a33cdc4d38f742cfb931f835
+ * configure.ac (gcry_cv_gcc_inline_asm_avx2): Add "cc" as assembly
+ globber.
+
+ Fix W32 build.
+ + commit a71b810ddd67ca3a1773d8f929d162551abb58eb
+ * random/rndw32.c (register_poll, slow_gatherer): Change gcry_xmalloc to
+ xmalloc, and gcry_xrealloc to xrealloc.
+
+2013-12-12 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ SHA-512: Add AVX and AVX2 implementations for x86-64.
+ + commit 2e4253dc8eb512cd0e807360926dc6ba912c95b4
+ * cipher/Makefile.am: Add 'sha512-avx-amd64.S' and
+ 'sha512-avx2-bmi2-amd64.S'.
+ * cipher/sha512-avx-amd64.S: New.
+ * cipher/sha512-avx2-bmi2-amd64.S: New.
+ * cipher/sha512.c (USE_AVX, USE_AVX2): New.
+ (SHA512_CONTEXT) [USE_AVX]: Add 'use_avx'.
+ (SHA512_CONTEXT) [USE_AVX2]: Add 'use_avx2'.
+ (sha512_init, sha384_init) [USE_AVX]: Initialize 'use_avx'.
+ (sha512_init, sha384_init) [USE_AVX2]: Initialize 'use_avx2'.
+ [USE_AVX] (_gcry_sha512_transform_amd64_avx): New.
+ [USE_AVX2] (_gcry_sha512_transform_amd64_avx2): New.
+ (transform) [USE_AVX2]: Add call for AVX2 implementation.
+ (transform) [USE_AVX]: Add call for AVX implementation.
+ * configure.ac (HAVE_GCC_INLINE_ASM_BMI2): New check.
+ (sha512): Add 'sha512-avx-amd64.lo' and 'sha512-avx2-bmi2-amd64.lo'.
+ * doc/gcrypt.texi: Document 'intel-cpu' and 'intel-bmi2'.
+ * src/g10lib.h (HWF_INTEL_CPU, HWF_INTEL_BMI2): New.
+ * src/hwfeatures.c (hwflist): Add "intel-cpu" and "intel-bmi2".
+ * src/hwf-x86.c (detect_x86_gnuc): Check for HWF_INTEL_CPU and
+ HWF_INTEL_BMI2.
+
+ SHA-512: Add SSSE3 implementation for x86-64.
+ + commit 69a6d0f9562fcd26112a589318c13de66ce1700e
+ * cipher/Makefile.am: Add 'sha512-ssse3-amd64.S'.
+ * cipher/sha512-ssse3-amd64.S: New.
+ * cipher/sha512.c (USE_SSSE3): New.
+ (SHA512_CONTEXT) [USE_SSSE3]: Add 'use_ssse3'.
+ (sha512_init, sha384_init) [USE_SSSE3]: Initialize 'use_ssse3'.
+ [USE_SSSE3] (_gcry_sha512_transform_amd64_ssse3): New.
+ (transform) [USE_SSSE3]: Call SSSE3 implementation.
+ * configure.ac (sha512): Add 'sha512-ssse3-amd64.lo'.
+
+ SHA-256: Add SSSE3 implementation for x86-64.
+ + commit e1a3931263e67aacec3c0bfcaa86c7d1441d5c6a
+ * cipher/Makefile.am: Add 'sha256-ssse3-amd64.S'.
+ * cipher/sha256-ssse3-amd64.S: New.
+ * cipher/sha256.c (USE_SSSE3): New.
+ (SHA256_CONTEXT) [USE_SSSE3]: Add 'use_ssse3'.
+ (sha256_init, sha224_init) [USE_SSSE3]: Initialize 'use_ssse3'.
+ (transform): Rename to...
+ (_transform): This.
+ [USE_SSSE3] (_gcry_sha256_transform_amd64_ssse3): New.
+ (transform): New.
+ * configure.ac (HAVE_INTEL_SYNTAX_PLATFORM_AS): New check.
+ (sha256): Add 'sha256-ssse3-amd64.lo'.
+ * doc/gcrypt.texi: Document 'intel-ssse3'.
+ * src/g10lib.h (HWF_INTEL_SSSE3): New.
+ * src/hwfeatures.c (hwflist): Add "intel-ssse3".
+ * src/hwf-x86.c (detect_x86_gnuc): Test for SSSE3.
+
+2013-12-12 Werner Koch <wk@gnupg.org>
+
+ Add a configuration file to disable hardware features.
+ + commit 5e1239b1e2948211ff2675f45cce2b28c3379cfb
+ * src/hwfeatures.c: Inclyde syslog.h and ctype.h.
+ (HWF_DENY_FILE): New.
+ (my_isascii): New.
+ (parse_hwf_deny_file): New.
+ (_gcry_detect_hw_features): Call it.
+
+ * src/mpicalc.c (main): Correctly initialize Libgcrypt. Add options
+ "--print-config" and "--disable-hwf".
+
+ Move list of hardware features to hwfeatures.c.
+ + commit 4ae77322b681a13da62d01274bcab25be2af12d0
+ * src/global.c (hwflist, disabled_hw_features): Move to ..
+ * src/hwfeatures.c: here.
+ (_gcry_disable_hw_feature): New.
+ (_gcry_enum_hw_features): New.
+ (_gcry_detect_hw_features): Remove arg DISABLED_FEATURES.
+ * src/global.c (print_config, _gcry_vcontrol, global_init): Adjust
+ accordingly.
+
+ Remove macro hacks for internal vs. external functions. Part 2 and last.
+ + commit 3b30e9840d4b351c4de73b126e561154cb7df4cc
+ * src/visibility.h: Remove remaining define/undef hacks for symbol
+ visibility. Add macros to detect the use of the public functions.
+ Change all affected functions by replacing them by the x-macros.
+ * src/g10lib.h: Add internal prototypes.
+ (xtrymalloc, xtrycalloc, xtrymalloc_secure, xtrycalloc_secure)
+ (xtryrealloc, xtrystrdup, xmalloc, xcalloc, xmalloc_secure)
+ (xcalloc_secure, xrealloc, xstrdup, xfree): New macros.
+
+2013-12-11 Werner Koch <wk@gnupg.org>
+
+ random: Add a feature to close device file descriptors.
+ + commit cd548ba2dc777b8b27d8d33182ba733c20222120
+ * src/gcrypt.h.in (GCRYCTL_CLOSE_RANDOM_DEVICE): New.
+ * src/global.c (_gcry_vcontrol): Call _gcry_random_close_fds.
+ * random/random.c (_gcry_random_close_fds): New.
+ * random/random-csprng.c (_gcry_rngcsprng_close_fds): New.
+ * random/random-fips.c (_gcry_rngfips_close_fds): New.
+ * random/random-system.c (_gcry_rngsystem_close_fds): New.
+ * random/rndlinux.c (open_device): Add arg retry.
+ (_gcry_rndlinux_gather_random): Add mode to close open fds.
+
+ * tests/random.c (check_close_random_device): New.
+ (main): Call new test.
+
+2013-12-10 Werner Koch <wk@gnupg.org>
+
+ Fix last commit (9a37470c)
+ + commit eae1e7712e1b687bd77eb37d0eb505fc9d46d93c
+ * src/secmem.c (lock_pool): Remove remaining line. Reported by Ian
+ Goldberg.
+
+2013-12-09 Werner Koch <wk@gnupg.org>
+
+ Fix one-off memory leak when build with Linux capability support.
+ + commit 9a37470c50ee9966cb2652617a404ddd54a9c096
+ * src/secmem.c (lock_pool, secmem_init): Use cap_free. Reported by
+ Mike Crowe <mac@mcrowe.com>.
+
+2013-12-09 David 'Digit' Turner <digit@google.com>
+
+ Update libtool to support Android.
+ + commit 2516f0b660b1a7181ad38c44310c627f4f498595
+ * m4/libtool.m4: Add "linux*android*" case. Taken from the libtool
+ repository.
+
+2013-12-09 Werner Koch <wk@gnupg.org>
+
+ tests: Speed up benchmarks in regression test mode.
+ + commit 2e5354fe8db5288939733d0fb63ad4c87bc20105
+ * tests/tsexp.c (check_extract_param): Fix compiler warning.
+ * tests/Makefile.am (TESTS_ENVIRONMENT): Set GCRYPT_IN_REGRESSION_TEST.
+ * tests/bench-slope.c (main): Speed up if in regression test mode.
+ * tests/benchmark.c (main): Ditto.
+
+ tests: Add --csv option to bench-slope.
+ + commit 8072e9fa4b42ae8e65e266aa158fd903f1bb0927
+ * tests/bench-slope.c (STR, STR2): New.
+ (cvs_mode): New.
+ (num_measurement_repetitions): New. Replace use of
+ NUM_MEASUREMENT_REPETITIONS by this.
+ (current_section_name, current_algo_name, current_mode_name): New.
+ (bench_print_result_csv): New.
+ (bench_print_result_std): Rename from bench_print_result.
+ (bench_print_result): New. Divert depending on CSV_MODE.
+ (bench_print_header, bench_print_footer): take care of CSV_MODE.
+ (bench_print_algo, bench_print_mode): New. Use them instead of
+ explicit printfs.
+ (main): Add options --csv and --repetitions.
+
+2013-12-07 Werner Koch <wk@gnupg.org>
+
+ sexp: Allow long names and white space in gcry_sexp_extract_param.
+ + commit d4555433b6e422fa69a85cae99961f513e55d82b
+ * src/sexp.c (_gcry_sexp_vextract_param): Skip white space. Support
+ long parameter names.
+ * tests/tsexp.c (check_extract_param): Add test cases for long parameter
+ names and white space.
+
+2013-12-06 Werner Koch <wk@gnupg.org>
+
+ ecc: Merge partly duplicated code.
+ + commit 405021cb6d4e470337302c65dec5bc91491a89c1
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_sign): Factor A hashing out to ...
+ (_gcry_ecc_eddsa_compute_h_d): new function.
+ * cipher/ecc-misc.c (_gcry_ecc_compute_public): Use new function.
+ (reverse_buffer): Remove.
+
+ ecc: Remove unused internal function.
+ + commit 4cf2c65fe15173c8d68a141a01b34fc1fb9080b7
+ * src/cipher-proto.h (gcry_pk_spec): Remove get_param.
+ * cipher/ecc-curves.c (_gcry_ecc_get_param_sexp): Merge in code from
+ _gcry_ecc_get_param.
+ (_gcry_ecc_get_param): Remove.
+ * cipher/ecc.c (_gcry_pubkey_spec_ecc): Remove _gcry_ecc_get_param.
+
+2013-12-06 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix building on mingw32.
+ + commit 5917ce34e3b3eac4c15f62577e4723974024f818
+ * src/gcrypt-int.h: Include <types.h>.
+
+2013-12-05 Werner Koch <wk@gnupg.org>
+
+ ecc: Change OID for Ed25519.
+ + commit 7ef43d1eebb4f8226e860982dfe5fa2e2c82ad0f
+ * cipher/ecc-curves.c (curve_aliased): Add more suitable OID for
+ Ed25519.
+
+ Remove macro hacks for internal vs. external functions. Part 1.
+ + commit 7bacf1812b55fa78db63abaa1f5a9220e9c6cccc
+ * src/visibility.h: Remove almost all define/undef hacks for symbol
+ visibility. Add macros to detect the use of the public functions.
+ Change all affected functions by prefixing them explicitly with an
+ underscore and change all internal callers to call the underscore
+ prefixed versions. Provide convenience macros from sexp and mpi
+ functions.
+ * src/visibility.c: Change all functions to use only gpg_err_code_t
+ and translate to gpg_error_t only in visibility.c.
+
+2013-12-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ mpi: add inline assembly for x86-64.
+ + commit 85bb0a98ea5add0296cbcc415d557eaa1f6bd294
+ * mpi/longlong.h [__x86_64] (add_ssaaaa, sub_ddmmss, umul_ppmm)
+ (udiv_qrnnd, count_leading_zeros, count_trailing_zeros): New.
+
+2013-12-04 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: fix gcry_mpi_powm for negative base.
+ + commit c56080c26186d25dec05f01831494c77d8d07e13
+ * mpi/mpi-pow.c (gcry_mpi_powm) [USE_ALGORITHM_SIMPLE_EXPONENTIATION]:
+ Fix for the case where BASE is negative.
+ * tests/mpitests.c (test_powm): Add a test case of (-17)^6 mod 19.
+
+2013-12-03 Werner Koch <wk@gnupg.org>
+
+ Add build support for ppc64le.
+ + commit 2ff86db2e1b0f6cc22a1ca86037b526c5fa3be51
+ * config.guess, config.sub: Update to latest version (2013-11-29).
+ * m4/libtool.m4: Add patches for ppc64le.
+
+2013-12-03 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: fix compiler warning on aarch64.
+ + commit 59b1a1b7ee2923e1bf091071ae716d180c6c6006
+ * cipher/rijndael.c (do_setkey): Use braces for empty if statement
+ instead of semicolon.
+
+ Add aarch64 (arm64) mpi assembly.
+ + commit 80896bc8f5e6ed9a627374e34f040ad5f3617584
+ * mpi/aarch64/mpi-asm-defs.h: New.
+ * mpi/aarch64/mpih-add1.S: New.
+ * mpi/aarch64/mpih-mul1.S: New.
+ * mpi/aarch64/mpih-mul2.S: New.
+ * mpi/aarch64/mpih-mul3.S: New.
+ * mpi/aarch64/mpih-sub1.S: New.
+ * mpi/config.links [host=aarch64-*-*]: Add configguration for aarch64
+ assembly.
+ * mpi/longlong.h [__aarch64__] (add_ssaaaa, sub_ddmmss, umul_ppmm)
+ (count_leading_zeros): New.
+
+2013-12-02 Werner Koch <wk@gnupg.org>
+
+ ecc: Use constant time point operation for Twisted Edwards.
+ + commit d4ce0cfe0d35d7ec69c115456848b5b735c928ea
+ * mpi/ec.c (_gcry_mpi_ec_mul_point): Try to do a constant time
+ operation if needed.
+ * tests/benchmark.c (main): Add option --use-secmem.
+
+ ecc: Make gcry_pk_testkey work for Ed25519.
+ + commit 14ae6224b1b17abbfc80c26ad0f4c60f1e8635e2
+ * cipher/ecc-misc.c (_gcry_ecc_compute_public): Add optional args G
+ and d. Change all callers.
+ * cipher/ecc.c (gen_y_2): Remove.
+ (check_secret_key): Use generic public key compute function. Adjust
+ for use with Ed25519 and EdDSA.
+ (nist_generate_key): Do not use the compliant key thingy for Ed25519.
+ (ecc_check_secret_key): Make parameter parsing similar to the other
+ functions.
+ * cipher/ecc-curves.c (domain_parms): Zero prefix some parameters so
+ that _gcry_ecc_update_curve_param works correctly.
+ * tests/keygen.c (check_ecc_keys): Add "param" flag. Check all
+ Ed25519 keys.
+
+ ecc: Fix eddsa point decompression.
+ + commit 485f35124b1a74af0bad321ed70be3a79d8d11d7
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_recover_x): Fix the negative
+ case.
+
+ ecc: Fix gcry_mpi_ec_curve_point for Weierstrass.
+ + commit ecb90f8e7c6f2516080d27ed7da6a25f2314da3c
+ * mpi/ec.c (_gcry_mpi_ec_curve_point): Use correct equation.
+ (ec_pow3): New.
+ (ec_p_init): Always copy B.
+
+ mpi: Introduce 4 user flags for gcry_mpi_t.
+ + commit 29eddc2558d4cf39995f66d5fccd62f584d5b203
+ * src/gcrypt.h.in (GCRYMPI_FLAG_USER1, GCRYMPI_FLAG_USER2)
+ (GCRYMPI_FLAG_USER3, GCRYMPI_FLAG_USER4): New.
+ * mpi/mpiutil.c (gcry_mpi_set_flag, gcry_mpi_clear_flag)
+ (gcry_mpi_get_flag, _gcry_mpi_free): Implement them.
+ (gcry_mpi_set_opaque): Keep user flags.
+
+2013-11-29 Vladimir 'φ-coder/phcoder' Serbinenko <phcoder@gmail.com>
+
+ Fix armv3 compile error.
+ + commit 3b1cc9e6c357574f54160298d731c18f3d717b6c
+ * mpi/longlong.h [__arm__ && __ARM_ARCH < 4] (umul_ppmm): Use
+ __AND_CLOBBER_CC instead of __CLOBBER_CC.
+
+ longlong.h on mips with clang.
+ + commit 1ecbd0bca31d462719a2a6590c1d03244e76ef89
+ * mpi/longlong.h [__mips__]: Use C-language version with clang.
+
+2013-11-24 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Camellia: Tweaks for AES-NI implementations.
+ + commit 3ef21e7e1b8003db9792155044db95f9d9ced184
+ * cipher/camellia-aesni-avx-amd64.S: Align stack to 16 bytes; tweak
+ key-setup for small speed up.
+ * cipher/camellia-aesni-avx2-amd64.S: Use vmovdqu even with aligned
+ stack; reorder vinsert128 instructions; use rbp for stack frame.
+
+2013-11-21 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add GMAC to MAC API.
+ + commit a34448c929b13bfb7b66d69169c89e7319a18b31
+ * cipher/Makefile.am: Add 'mac-gmac.c'.
+ * cipher/mac-gmac.c: New.
+ * cipher/mac-internal.h (gcry_mac_handle): Add 'u.gcm'.
+ (_gcry_mac_type_spec_gmac_aes, _gcry_mac_type_spec_gmac_twofish)
+ (_gcry_mac_type_spec_gmac_serpent, _gcry_mac_type_spec_gmac_seed)
+ (_gcry_mac_type_spec_gmac_camellia): New externs.
+ * cipher/mac.c (mac_list): Add GMAC specifications.
+ * doc/gcrypt.texi: Add mention of GMAC.
+ * src/gcrypt.h.in (gcry_mac_algos): Add GCM algorithms.
+ * tests/basic.c (check_one_mac): Add support for MAC IVs.
+ (check_mac): Add support for MAC IVs and add GMAC test vectors.
+ * tests/bench-slope.c (mac_bench): Iterate algorithm numbers to 499.
+ * tests/benchmark.c (mac_bench): Iterate algorithm numbers to 499.
+
+ GCM: Move gcm_table initialization to setkey.
+ + commit dbfa651618693da7ea73b4d2d00d4efd411bfb46
+ * cipher/cipher-gcm.c: Change all 'c->u_iv.iv' to
+ 'c->u_mode.gcm.u_ghash_key.key'.
+ (_gcry_cipher_gcm_setkey): New.
+ (_gcry_cipher_gcm_initiv): Move ghash initialization to function above.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add
+ 'u_mode.gcm.u_ghash_key'; Reorder 'u_mode.gcm' members for partial
+ clearing in gcry_cipher_reset.
+ (_gcry_cipher_gcm_setkey): New prototype.
+ * cipher/cipher.c (cipher_setkey): Add GCM setkey.
+ (cipher_reset): Clear 'u_mode' only partially for GCM.
+
+2013-11-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ GCM: Add support for split data buffers and online operation.
+ + commit fb1e52e3fe231671de546eacd6becd31c26c4f7b
+ * cipher/cipher-gcm.c (do_ghash_buf): Add buffering for less than
+ blocksize length input and padding handling.
+ (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt): Add handling
+ for AAD padding and check if data has already being padded.
+ (_gcry_cipher_gcm_authenticate): Check that AAD or data has not being
+ padded yet.
+ (_gcry_cipher_gcm_initiv): Clear padding marks.
+ (_gcry_cipher_gcm_tag): Add finalization and padding; Clear sensitive
+ data from cipher handle, since they are not used after generating tag.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add 'u_mode.gcm.macbuf',
+ 'u_mode.gcm.mac_unused', 'u_mode.gcm.ghash_data_finalized' and
+ 'u_mode.gcm.ghash_aad_finalized'.
+ * tests/basic.c (check_gcm_cipher): Rename to...
+ (_check_gcm_cipher): ...this and add handling for different buffer step
+ lengths; Enable per byte buffer testing.
+ (check_gcm_cipher): Call _check_gcm_cipher with different buffer step
+ sizes.
+
+ GCM: Use size_t for buffer sizes.
+ + commit 2d870a9142e8c8b3f008e1ad8e83e4bdf7a8e4e7
+ * cipher/cipher-gcm.c (ghash, gcm_bytecounter_add, do_ghash_buf)
+ (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
+ (_gcry_cipher_gcm_authenticate, _gcry_cipher_gcm_geniv)
+ (_gcry_cipher_gcm_tag): Use size_t for buffer lengths.
+ * cipher/cipher-internal.h (_gcry_cipher_gcm_encrypt)
+ (_gcry_cipher_gcm_decrypt, _gcry_cipher_gcm_authenticate): Use size_t
+ for buffer lengths.
+
+ GCM: add FIPS mode restrictions.
+ + commit 56d352d6bdcf7abaa33c3399741f5063e2ddc32a
+ * cipher/cipher-gcm.c (_gcry_cipher_gcm_encrypt)
+ (_gcry_cipher_gcm_get_tag): Do not allow using in FIPS mode is setiv
+ was invocated directly.
+ (_gcry_cipher_gcm_setiv): Rename to...
+ (_gcry_cipher_gcm_initiv): ...this.
+ (_gcry_cipher_gcm_setiv): New setiv function with check for FIPS mode.
+ [TODO] (_gcry_cipher_gcm_getiv): New.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add
+ 'u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode'.
+
+ GCM: Add clearing and checking of marks.tag.
+ + commit 32a2da9abc91394b23cf565c1c833fa964394083
+ * cipher/cipher-gcm.c (_gcry_cipher_gcm_encrypt)
+ (_gcry_cipher_gcm_decrypt, _gcry_cipher_gcm_authenticate): Make sure
+ that tag has not been finalized yet.
+ (_gcry_cipher_gcm_setiv): Clear 'marks.tag'.
+
+ GCM: Add stack burning.
+ + commit 018f08354b1b116672e82f9ce942884b288aaf9e
+ * cipher/cipher-gcm.c (do_ghash, ghash): Return stack burn depth.
+ (setupM): Wipe 'tmp' buffer.
+ (do_ghash_buf): Wipe 'tmp' buffer and add stack burning.
+
+ Add aggregated bulk processing for GCM on x86-64.
+ + commit c9537fbf8ff0af919cff2bebadc4c6e7caea8076
+ * cipher/cipher-gcm.c [__x86_64__] (gfmul_pclmul_aggr4): New.
+ (ghash) [GCM_USE_INTEL_PCLMUL]: Add aggregated bulk processing
+ for __x86_64__.
+ (setupM) [__x86_64__]: Add initialization for aggregated bulk
+ processing.
+
+ GCM: Tweak Intel PCLMUL ghash loop for small speed-up.
+ + commit 9b6764944284fed733c2f88619b3d9eb5d5c259a
+ * cipher/cipher-gcm.c (do_ghash): Mark 'inline'.
+ [GCM_USE_INTEL_PCLMUL] (do_ghash_pclmul): Rename to...
+ [GCM_USE_INTEL_PCLMUL] (gfmul_pclmul): ..this and make inline function.
+ (ghash) [GCM_USE_INTEL_PCLMUL]: Preload data before ghash-pclmul loop.
+
+ GCM: Use counter mode code for speed-up.
+ + commit bd4bd23a2511a4bce63c3217cca0d4ecf0c79532
+ * cipher/cipher-gcm.c (ghash): Add process for multiple blocks.
+ (gcm_bytecounter_add, gcm_add32_be128, gcm_check_datalen)
+ (gcm_check_aadlen_or_ivlen, do_ghash_buf): New functions.
+ (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
+ (_gcry_cipher_gcm_authenticate, _gcry_cipher_gcm_set_iv)
+ (_gcry_cipher_gcm_tag): Adjust to use above new functions and
+ counter mode functions for encryption/decryption.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Remove 'length'; Add
+ 'u_mode.gcm.(addlen|datalen|tagiv|datalen_over_limits)'.
+ (_gcry_cipher_gcm_setiv): Return gcry_err_code_t.
+ * cipher/cipher.c (cipher_setiv): Return error code.
+ (_gcry_cipher_setiv): Handle error code from 'cipher_setiv'.
+
+ Add Intel PCLMUL acceleration for GCM.
+ + commit 5a65ffabadd50f174ab7375faad7a726cce49e61
+ * cipher/cipher-gcm.c (fillM): Rename...
+ (do_fillM): ...to this.
+ (ghash): Remove.
+ (fillM): New macro.
+ (GHASH): Use 'do_ghash' instead of 'ghash'.
+ [GCM_USE_INTEL_PCLMUL] (do_ghash_pclmul): New.
+ (ghash): New.
+ (setupM): New.
+ (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
+ (_gcry_cipher_gcm_authenticate, _gcry_cipher_gcm_setiv)
+ (_gcry_cipher_gcm_tag): Use 'ghash' instead of 'GHASH' and
+ 'c->u_mode.gcm.u_tag.tag' instead of 'c->u_tag.tag'.
+ * cipher/cipher-internal.h (GCM_USE_INTEL_PCLMUL): New.
+ (gcry_cipher_handle): Move 'u_tag' and 'gcm_table' under
+ 'u_mode.gcm'.
+ * configure.ac (pclmulsupport, gcry_cv_gcc_inline_asm_pclmul): New.
+ * src/g10lib.h (HWF_INTEL_PCLMUL): New.
+ * src/global.c: Add "intel-pclmul".
+ * src/hwf-x86.c (detect_x86_gnuc): Add check for Intel PCLMUL.
+
+ GCM: GHASH optimizations.
+ + commit 0e9e7d72f3c9eb7ac832746c3034855faaf8d02c
+ * cipher/cipher-gcm.c [GCM_USE_TABLES] (gcmR, ghash): Replace with new.
+ [GCM_USE_TABLES] [GCM_TABLES_USE_U64] (bshift, fillM, do_ghash): New.
+ [GCM_USE_TABLES] [!GCM_TABLES_USE_U64] (bshift, fillM): Replace with
+ new.
+ [GCM_USE_TABLES] [!GCM_TABLES_USE_U64] (do_ghash): New.
+ (_gcry_cipher_gcm_tag): Remove extra memcpy to outbuf and use
+ buf_eq_const for comparing authentication tag.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Different 'gcm_table'
+ for 32-bit and 64-bit platforms.
+
+ Add some documentation for GCM mode.
+ + commit 332da0ed7c8fab6c2bee841c94d8364c2ab4e30d
+ * doc/gcrypt.texi: Add mention of GCM mode.
+
+2013-11-19 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Initial implementation of GCM.
+ + commit 90cce18b9eced4f412ceeec5bcae18c4493322df
+ * cipher/Makefile.am: Add 'cipher-gcm.c'.
+ * cipher/cipher-ccm.c (_gcry_ciphert_ccm_set_lengths)
+ (_gcry_cipher_ccm_authenticate, _gcry_cipher_ccm_tag)
+ (_gcry_cipher_ccm_encrypt, _gcry_cipher_ccm_decrypt): Change
+ 'c->u_mode.ccm.tag' to 'c->marks.tag'.
+ * cipher/cipher-gcm.c: New.
+ * cipher/cipher-internal.h (GCM_USE_TABLES): New.
+ (gcry_cipher_handle): Add 'marks.tag', 'u_tag', 'length' and
+ 'gcm_table'; Remove 'u_mode.ccm.tag'.
+ (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
+ (_gcry_cipher_gcm_setiv, _gcry_cipher_gcm_authenticate)
+ (_gcry_cipher_gcm_get_tag, _gcry_cipher_gcm_check_tag): New.
+ * cipher/cipher.c (_gcry_cipher_open_internal, cipher_setkey)
+ (cipher_encrypt, cipher_decrypt, _gcry_cipher_authenticate)
+ (_gcry_cipher_gettag, _gcry_cipher_checktag): Add GCM mode handling.
+ * src/gcrypt.h.in (gcry_cipher_modes): Add GCRY_CIPHER_MODE_GCM.
+ (GCRY_GCM_BLOCK_LEN): New.
+ * tests/basic.c (check_gcm_cipher): New.
+ (check_ciphers): Add GCM check.
+ (check_cipher_modes): Call 'check_gcm_cipher'.
+ * tests/bench-slope.c (bench_gcm_encrypt_do_bench)
+ (bench_gcm_decrypt_do_bench, bench_gcm_authenticate_do_bench)
+ (gcm_encrypt_ops, gcm_decrypt_ops, gcm_authenticate_ops): New.
+ (cipher_modes): Add GCM enc/dec/auth.
+ (cipher_bench_one): Limit GCM to block ciphers with 16 byte block-size.
+ * tests/benchmark.c (cipher_bench): Add GCM.
+
+2013-11-19 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Camellia: fix compiler warning.
+ + commit 9816ae9d9931b75e4fdc9a5be10e6af447132313
+ * cipher/camellia-glue.c (camellia_setkey): Use braces around empty if
+ statement.
+
+ Tweak Camellia-AVX key-setup for small speed-up.
+ + commit 77922a82c3f2e30eca04511fa5a355208349c657
+ * cipher/camellia-aesni-avx-amd64.S (camellia_f): Merge S-function output
+ rotation with P-function.
+
+ Add CMAC (Cipher-based MAC) to MAC API.
+ + commit b49cd64aaaff2e5488a84665362ef7150683226c
+ * cipher/Makefile.am: Add 'cipher-cmac.c' and 'mac-cmac.c'.
+ * cipher/cipher-cmac.c: New.
+ * cipher/cipher-internal.h (gcry_cipher_handle.u_mode): Add 'cmac'.
+ * cipher/cipher.c (gcry_cipher_open): Rename to...
+ (_gcry_cipher_open_internal): ...this and add CMAC.
+ (gcry_cipher_open): New wrapper that disallows use of internal
+ modes (CMAC) from outside.
+ (cipher_setkey, cipher_encrypt, cipher_decrypt)
+ (_gcry_cipher_authenticate, _gcry_cipher_gettag)
+ (_gcry_cipher_checktag): Add handling for CMAC mode.
+ (cipher_reset): Do not reset 'marks.key' and do not clear subkeys in
+ 'u_mode' in CMAC mode.
+ * cipher/mac-cmac.c: New.
+ * cipher/mac-internal.h: Add CMAC support and algorithms.
+ * cipher/mac.c: Add CMAC algorithms.
+ * doc/gcrypt.texi: Add documentation for CMAC.
+ * src/cipher.h (gcry_cipher_internal_modes): New.
+ (_gcry_cipher_open_internal, _gcry_cipher_cmac_authenticate)
+ (_gcry_cipher_cmac_get_tag, _gcry_cipher_cmac_check_tag)
+ (_gcry_cipher_cmac_set_subkeys): New prototypes.
+ * src/gcrypt.h.in (gcry_mac_algos): Add CMAC algorithms.
+ * tests/basic.c (check_mac): Add CMAC test vectors.
+
+2013-11-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add new MAC API, initially with HMAC.
+ + commit fcd6da37d55f248d3558ee0ff385b41b866e7ded
+ * cipher/Makefile.am: Add 'mac.c', 'mac-internal.h' and 'mac-hmac.c'.
+ * cipher/bufhelp.h (buf_eq_const): New.
+ * cipher/cipher-ccm.c (_gcry_cipher_ccm_tag): Use 'buf_eq_const' for
+ constant-time compare.
+ * cipher/mac-hmac.c: New.
+ * cipher/mac-internal.h: New.
+ * cipher/mac.c: New.
+ * doc/gcrypt.texi: Add documentation for MAC API.
+ * src/gcrypt-int.h [GPG_ERROR_VERSION_NUMBER < 1.13]
+ (GPG_ERR_MAC_ALGO): New.
+ * src/gcrypt.h.in (gcry_mac_handle, gcry_mac_hd_t, gcry_mac_algos)
+ (gcry_mac_flags, gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+ (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+ (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+ (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name)
+ (gcry_mac_reset, gcry_mac_test_algo): New.
+ * src/libgcrypt.def (gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+ (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+ (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+ (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name): New.
+ * src/libgcrypt.vers (gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+ (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+ (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+ (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name): New.
+ * src/visibility.c (gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+ (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+ (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+ (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name): New.
+ * src/visibility.h (gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+ (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+ (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+ (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name): New.
+ * tests/basic.c (check_one_mac, check_mac): New.
+ (main): Call 'check_mac'.
+ * tests/bench-slope.c (bench_print_header, bench_print_footer): Allow
+ variable algorithm name width.
+ (_cipher_bench, hash_bench): Update to above change.
+ (bench_hash_do_bench): Add 'gcry_md_reset'.
+ (bench_mac_mode, bench_mac_init, bench_mac_free, bench_mac_do_bench)
+ (mac_ops, mac_modes, mac_bench_one, _mac_bench, mac_bench): New.
+ (main): Add 'mac' benchmark options.
+ * tests/benchmark.c (mac_repetitions, mac_bench): New.
+ (main): Add 'mac' benchmark options.
+
+ Use correct blocksize of 32 bytes for GOSTR3411-94 HMAC.
+ + commit b95a557a43aeed68ea5e5ce02aca42ee97bfdb3b
+ * cipher/md.c (md_open): Set macpads_Bsize to 32 for
+ GCRY_MD_GOST24311_94.
+
+2013-11-15 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ cipher: use size_t for internal buffer lengths.
+ + commit b787657a9d2c1d8e19f9fcb0b21e31cb062630cf
+ * cipher/arcfour.c (do_encrypt_stream, encrypt_stream): Use 'size_t'
+ for buffer lengths.
+ * cipher/blowfish.c (_gcry_blowfish_ctr_enc, _gcry_blowfish_cbc_dec)
+ (_gcry_blowfish_cfb_dec): Ditto.
+ * cipher/camellia-glue.c (_gcry_camellia_ctr_enc)
+ (_gcry_camellia_cbc_dec, _gcry_blowfish_cfb_dec): Ditto.
+ * cipher/cast5.c (_gcry_cast5_ctr_enc, _gcry_cast5_cbc_dec)
+ (_gcry_cast5_cfb_dec): Ditto.
+ * cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt)
+ (_gcry_cipher_aeswrap_decrypt): Ditto.
+ * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
+ (_gcry_cipher_cbc_decrypt): Ditto.
+ * cipher/cipher-ccm.c (_gcry_cipher_ccm_encrypt)
+ (_gcry_cipher_ccm_decrypt): Ditto.
+ * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
+ (_gcry_cipher_cfb_decrypt): Ditto.
+ * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Ditto.
+ * cipher/cipher-internal.h (gcry_cipher_handle->bulk)
+ (_gcry_cipher_cbc_encrypt, _gcry_cipher_cbc_decrypt)
+ (_gcry_cipher_cfb_encrypt, _gcry_cipher_cfb_decrypt)
+ (_gcry_cipher_ofb_encrypt, _gcry_cipher_ctr_encrypt)
+ (_gcry_cipher_aeswrap_encrypt, _gcry_cipher_aeswrap_decrypt)
+ (_gcry_cipher_ccm_encrypt, _gcry_cipher_ccm_decrypt): Ditto.
+ * cipher/cipher-ofb.c (_gcry_cipher_cbc_encrypt): Ditto.
+ * cipher/cipher-selftest.h (gcry_cipher_bulk_cbc_dec_t)
+ (gcry_cipher_bulk_cfb_dec_t, gcry_cipher_bulk_ctr_enc_t): Ditto.
+ * cipher/cipher.c (cipher_setkey, cipher_setiv, do_ecb_crypt)
+ (do_ecb_encrypt, do_ecb_decrypt, cipher_encrypt)
+ (cipher_decrypt): Ditto.
+ * cipher/rijndael.c (_gcry_aes_ctr_enc, _gcry_aes_cbc_dec)
+ (_gcry_aes_cfb_dec, _gcry_aes_cbc_enc, _gcry_aes_cfb_enc): Ditto.
+ * cipher/salsa20.c (salsa20_setiv, salsa20_do_encrypt_stream)
+ (salsa20_encrypt_stream, salsa20r12_encrypt_stream): Ditto.
+ * cipher/serpent.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+ (_gcry_serpent_cfb_dec): Ditto.
+ * cipher/twofish.c (_gcry_twofish_ctr_enc, _gcry_twofish_cbc_dec)
+ (_gcry_twofish_cfb_dec): Ditto.
+ * src/cipher-proto.h (gcry_cipher_stencrypt_t)
+ (gcry_cipher_stdecrypt_t, cipher_setiv_fuct_t): Ditto.
+ * src/cipher.h (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec)
+ (_gcry_aes_cbc_enc, _gcry_aes_cbc_dec, _gcry_aes_ctr_enc)
+ (_gcry_blowfish_cfb_dec, _gcry_blowfish_cbc_dec)
+ (_gcry_blowfish_ctr_enc, _gcry_cast5_cfb_dec, _gcry_cast5_cbc_dec)
+ (_gcry_cast5_ctr_enc, _gcry_camellia_cfb_dec, _gcry_camellia_cbc_dec)
+ (_gcry_camellia_ctr_enc, _gcry_serpent_cfb_dec, _gcry_serpent_cbc_dec)
+ (_gcry_serpent_ctr_enc, _gcry_twofish_cfb_dec, _gcry_twofish_cbc_dec)
+ (_gcry_twofish_ctr_enc): Ditto.
+
+ Camellia: Add AVX/AES-NI key setup.
+ + commit ef9f52cbb39e46918c96200b09c21e931eff174f
+ * cipher/camellia-aesni-avx-amd64.S (key_bitlength, key_table): New
+ order of fields in ctx.
+ (camellia_f, vec_rol128, vec_ror128): New macros.
+ (__camellia_avx_setup128, __camellia_avx_setup256)
+ (_gcry_camellia_aesni_avx_keygen): New functions.
+ * cipher/camellia-aesni-avx2-amd64.S (key_bitlength, key_table): New
+ order of fields in ctx.
+ * cipher/camellia-arm.S (CAMELLIA_TABLE_BYTE_LEN, key_length): Remove
+ unused macros.
+ * cipher/camellia-glue.c (CAMELLIA_context): Move keytable to head for
+ better alignment; Make 'use_aesni_avx' and 'use_aesni_avx2' bitfield
+ members.
+ [USE_AESNI_AVX] (_gcry_camellia_aesni_avx_keygen): New prototype.
+ (camellia_setkey) [USE_AESNI_AVX || USE_AESNI_AVX2]: Read hw features
+ to variable 'hwf' and match features from it.
+ (camellia_setkey) [USE_AESNI_AVX]: Use AES-NI/AVX key setup if
+ available.
+
+ Avoid unneeded stack burning with AES-NI and reduce number of 'decryption_prepared' checks
+ + commit c8ad83fb605fdbf6dc0b0dbcc8aedfbd477640da
+ * cipher/rijndael.c (RIJNDAEL_context): Make 'decryption_prepared',
+ 'use_padlock' and 'use_aesni' 1-bit members in bitfield.
+ (do_setkey): Move 'hwfeatures' inside [USE_AESNI || USE_PADLOCK].
+ (do_aesni_enc_aligned): Rename to...
+ (do_aesni_enc): ...this, as function does not require aligned input.
+ (do_aesni_dec_aligned): Rename to...
+ (do_aesni_dec): ...this, as function does not require aligned input.
+ (do_aesni): Remove.
+ (rijndael_encrypt): Call 'do_aesni_enc' instead of 'do_aesni'.
+ (rijndael_decrypt): Call 'do_aesni_dec' instead of 'do_aesni'.
+ (check_decryption_preparation): New.
+ (do_decrypt): Remove 'decryption_prepared' check.
+ (rijndael_decrypt): Ditto and call 'check_decryption_preparation'.
+ (_gcry_aes_cbc_dec): Ditto.
+ (_gcry_aes_cfb_enc): Add 'burn_depth' and burn stack only when needed.
+ (_gcry_aes_cbc_enc): Ditto.
+ (_gcry_aes_ctr_enc): Ditto.
+ (_gcry_aes_cfb_dec): Ditto.
+ (_gcry_aes_cbc_dec): Ditto and correct clearing of 'savebuf'.
+
+2013-11-14 Werner Koch <wk@gnupg.org>
+
+ md: Fix hashing for data >= 256 GB.
+ + commit c43a8c0d81a711161f7a81b24ef7c33a1353eee0
+ * cipher/hash-common.h (gcry_md_block_ctx): Add "nblocks_high".
+ * cipher/hash-common.c (_gcry_md_block_write): Bump NBLOCKS_HIGH.
+ * cipher/md4.c (md4_init, md4_final): Take care of NBLOCKS_HIGH.
+ * cipher/md5.c (md5_init, md5_final): Ditto.
+ * cipher/rmd160.c (_gcry_rmd160_init, rmd160_final): Ditto.
+ * cipher/sha1.c (sha1_init, sha1_final): Ditto.
+ * cipher/sha256.c (sha256_init, sha224_init, sha256_final): Ditto.
+ * cipher/sha512.c (sha512_init, sha384_init, sha512_final): Ditto.
+ * cipher/tiger.c (do_init, tiger_final): Ditto.
+ * cipher/whirlpool.c (whirlpool_final): Ditto.
+
+ * cipher/md.c (gcry_md_algo_info): Add GCRYCTL_SELFTEST.
+ (_gcry_md_selftest): Return "not implemented" as required.
+ * tests/hashtest.c: New.
+ * tests/genhashdata.c: New.
+ * tests/Makefile.am (TESTS): Add hashtest.
+ (noinst_PROGRAMS): Add genhashdata
+
+2013-11-13 Christian Grothoff <christian@grothoff.org>
+
+ ecc: Fix key generation for a plain Ed25519 key.
+ + commit 7d91e99bcd30a463dd4faed014b8521a663d8316
+ * cipher/ecc.c (nist_generate_key): Use custom code for ED25519.
+
+ ecc: Fix some memory leaks.
+ + commit c4f9af49f228df59c218381a25fa3c0f93ccbeae
+ * cipher/ecc-curves.c (_gcry_mpi_ec_new): Free ec->b before assigning.
+ * cipher/ecc.c (nist_generate_key): Release Q.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Ditto.
+
+2013-11-11 Werner Koch <wk@gnupg.org>
+
+ ecc: Change keygrip computation for Ed25519+EdDSA.
+ + commit 4fb3c8e5a7fc6a1568f54bcc0be17fecf75e0742
+ * cipher/ecc.c (compute_keygrip): Rework.
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_ensure_compact): New.
+ * cipher/ecc-curves.c (_gcry_ecc_update_curve_param): New.
+ * tests/keygrip.c (key_grips): Add flag param and test cases for
+ Ed25519.
+
+ mpi: Add special format GCRYMPI_FMT_OPAQUE.
+ + commit 8b3eecee2d89179297e43de7d650f74759c61a58
+ * src/gcrypt.h.in (GCRYMPI_FMT_OPAQUE): New.
+ (_gcry_sexp_nth_opaque_mpi): Remove.
+ * src/sexp.c (gcry_sexp_nth_mpi): Add support for GCRYMPI_FMT_OPAQUE.
+ (_gcry_sexp_vextract_param): Replace removed function by
+ GCRYMPI_FMT_OPAQUE.
+
+2013-11-10 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix error output in CTR selftest.
+ + commit 7b26586e35a6d407ca31b41528b0810b1408fd4b
+ * cipher/cipher-selftest.c (_gcry_selftest_helper_ctr): Change
+ fprintf(stderr,...) to syslog(); Correct error output for bulk
+ IV check, plaintext mismatch => ciphertext mismatch.
+
+2013-11-09 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix Serpent-AVX2 and Camellia-AVX2 counter modes.
+ + commit df29831d008e32faf74091d080a415731418d158
+ * cipher/camellia-aesni-avx2-amd64.S
+ (_gcry_camellia_aesni_avx2_ctr_enc): Byte-swap before checking for
+ overflow handling.
+ * cipher/camellia-glue.c (selftest_ctr_128, selftest_cfb_128)
+ (selftest_cbc_128): Add 16 to nblocks.
+ * cipher/cipher-selftest.c (_gcry_selftest_helper_ctr): Add test with
+ non-overflowing IV and modify overflow IV to detect broken endianness
+ handling.
+ * cipher/serpent-avx2-amd64.S (_gcry_serpent_avx2_ctr_enc): Byte-swap
+ before checking for overflow handling; Fix crazy-mixed-endian IV
+ construction to big-endian.
+ * cipher/serpent.c (selftest_ctr_128, selftest_cfb_128)
+ (selftest_cbc_128): Add 8 to nblocks.
+
+2013-11-09 Sergey V <sftp.mtuci@gmail.com>
+
+ cipher/gost28147: optimization: use precomputed S-box tables.
+ + commit 51501b638546665163bbb85a14308fdb99211a28
+ * cipher/gost.h (GOST28147_context): Remove unneeded subst and
+ subst_set members.
+ * cipher/gost28147.c (max): Remove unneeded macro.
+ (test_sbox): Replace with new precomputed tables.
+ (gost_set_subst): Remove function.
+ (gost_val): Use new S-box tables.
+ (gost_encrypt_block, gost_decrypt_block): Tweak to use new ctx and
+ S-box tables.
+
+2013-11-09 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix tail handling for AES-NI counter mode.
+ + commit 60ed0abbbc7cb15812f1e713143c72555acea69e
+ * cipher/rijndael.c (do_aesni_ctr): Fix outputting of updated
+ counter-IV.
+
+2013-11-08 Werner Koch <wk@gnupg.org>
+
+ ecc: Improve gcry_pk_get_curve.
+ + commit 03aed1acec611362285db5156a6b92c91604fba4
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Factor some code out
+ to ..
+ (find_domain_parms_idx): new.
+ (_gcry_ecc_get_curve): Find by curve name on error.
+
+ cipher: Avoid signed divisions in idea.c.
+ + commit e241dde1420475459e32608137829e52748d0212
+ * cipher/idea.c (mul_inv): Use unsigned division.
+
+ ecc: Implement the "nocomp" flag for key generation.
+ + commit 9f63c0f7a3b2c15c7e258cd17395cabd0a8f00cc
+ * cipher/ecc.c (ecc_generate): Support the "nocomp" flag.
+ * tests/keygen.c (check_ecc_keys): Add a test for it.
+
+ ecc: Make "noparam" the default and replace by "param".
+ + commit ed45fd2e60c88e2f005282e6eadd018b59dcf65b
+ * src/cipher.h (PUBKEY_FLAG_NOCOMP): New.
+ (PUBKEY_FLAG_NOPARAM): Remove.
+ (PUBKEY_FLAG_PARAM): New.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Support the new
+ flags and ignore the obsolete "noparam" flag.
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Return the curve name
+ also for curves selected by NBITS.
+ (_gcry_mpi_ec_new): Support the "param" flag.
+ * cipher/ecc.c (ecc_generate, ecc_sign, ecc_verify): Ditto.
+ * tests/keygen.c (check_ecc_keys): Remove the "noparam" flag.
+
+2013-11-07 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix decryption function size in AES AMD64 assembly.
+ + commit bfe4f6523b80bae0040328ef324b9000ee5b38a4
+ * cipher/rijndael-amd64.S (_gcry_aes_amd64_decrypt_block): Set '.size'
+ for '_gcry_aes_amd64_decrypt_block', not '..._encrypt_block'.
+
+ Change 64-bit shift to 32-bit in AES AMD64 assembly.
+ + commit 57b296ea3a5204cd3711b7bf57c8fb14d8542402
+ * cipher/rijndael-amd64.S (do16bit_shr): Change 'shrq' to 'shrl'.
+
+2013-11-06 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Speed-up AES-NI key setup.
+ + commit f702d62d888b30e24c19f203566a1473098b2b31
+ * cipher/rijndael.c [USE_AESNI] (m128i_t): Remove.
+ [USE_AESNI] (u128_t): New.
+ [USE_AESNI] (aesni_do_setkey): New.
+ (do_setkey) [USE_AESNI]: Move AES-NI accelerated key setup to
+ 'aesni_do_setkey'.
+ (do_setkey): Call _gcry_get_hw_features only once. Clear stack after
+ use in generic key setup part.
+ (rijndael_setkey): Remove stack burning.
+ (prepare_decryption) [USE_AESNI]: Use 'u128_t' instead of 'm128i_t' to
+ avoid compiler generated SSE2 instructions and XMM register usage,
+ unroll 'aesimc' setup loop
+ (prepare_decryption): Clear stack after use.
+ [USE_AESNI] (do_aesni_enc_aligned): Update comment about alignment.
+ (do_decrypt): Do not burning stack after prepare_decryption.
+
+ Avoid burn stack in Arcfour setkey.
+ + commit a50a6ba3540f49fc7dcdb32e691327d5942e3509
+ * cipher/arcfour.c (arcfour_setkey): Remove stack burning.
+
+ Avoid burn_stack in CAST5 setkey.
+ + commit 5797ebc268b4e953cedd0c729c5cdb1f8fd764e4
+ * cipher/cast5.c (do_cast_setkey): Use wipememory instead of memset.
+ (cast_setkey): Remove stack burning.
+
+ Improve Serpent key setup speed.
+ + commit 9897ccb381503455edc490679b2e9251a09ac5cb
+ * cipher/serpent.c (SBOX, SBOX_INVERSE): Remove index argument.
+ (serpent_subkeys_generate): Use smaller temporary arrays for subkey
+ generation and perform stack clearing locally.
+ (serpent_setkey_internal): Use wipememory to clear stack and remove
+ _gcry_burn_stack.
+ (serpent_setkey): Remove unneeded _gcry_burn_stack.
+
+ Modify encrypt/decrypt arguments for in-place.
+ + commit b8515aa70b00baba3fba8121ed305edcd029c8c7
+ * cipher/cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt): Modify
+ local arguments if in-place operation.
+
+ Speed up Stribog.
+ + commit a48d07ccadee4cb8b666a9a4ba2f00129bad5b2f
+ * cipher/stribog.c (STRIBOG_TABLES): Remove.
+ (Pi): Remove.
+ [!STRIBOG_TABLES] (A, strido): Remove.
+ (stribog_table): New table pre-reordered with Pi values.
+ (strido): Rewrite for new table.
+ (LPSX): Rewrite for new table.
+ (xor): Remove.
+ (g): Small tweaks.
+
+ Tweak AES-NI bulk CTR mode slightly.
+ + commit 3b5058b58a183fa23ecf3ef819e2ae6ac64c0216
+ * cipher/rijndael.c [USE_AESNI] (aesni_cleanup_2_5): Rename to...
+ (aesni_cleanup_2_6): ...this and clear also 'xmm6'.
+ [USE_AESNI && __i386__] (do_aesni_ctr, do_aesni_ctr_4): Prevent
+ inlining only on i386, allow on AMD64.
+ [USE_AESNI] (do_aesni_ctr, do_aesni_ctr_4): Use counter block from
+ 'xmm5' and byte-swap mask from 'xmm6'.
+ (_gcry_aes_ctr_enc) [USE_AESNI]: Preload counter block to 'xmm5' and
+ byte-swap mask to 'xmm6'.
+ (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use
+ 'aesni_cleanup_2_6'.
+
+ Tweak bench-slope parameters.
+ + commit 7e98eecc1a955bc253765f92a166b6560f085b8c
+ * tests/bench-slope.c (BUF_STEP_SIZE): Half step size to 64.
+ (NUM_MEASUREMENT_REPETITIONS): Double repetitions to 64.
+
+ Optimize Blowfish weak key check.
+ + commit 8e1c0f9b894c39b6554c544208dc000682f520c7
+ * cipher/blowfish.c (hashset_elem, val_to_hidx, add_val): New.
+ (do_bf_setkey): Use faster algorithm for detecting weak keys.
+ (bf_setkey): Move stack burning to do_bf_setkey.
+
+ Fix __builtin_bswap32/64 checks.
+ + commit 2590a5df6f5fc884614c8c379324027d2d61b9b5
+ * configure.ac (gcry_cv_have_builtin_bswap32)
+ (gcry_cv_have_builtin_bswap64): Change compile checks to link checks.
+
+ Fix 'u32' build error with Camellia.
+ + commit 84bcb400e7db7268abfc29b5ab1513b0c063b293
+ * cipher/camellia.c: Add include for <config.h> and "types.h".
+ (u32): Remove.
+ (u8): Typedef as 'byte'.
+
+2013-11-06 Werner Koch <wk@gnupg.org>
+
+ pubkey: Add forward compatibility feature.
+ + commit 6d169b654c7ff04c10f73afe80b2c70cefa410c1
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Add
+ "igninvflag".
+
+2013-11-05 Werner Koch <wk@gnupg.org>
+
+ ecc: Require "eddsa" flag for curve Ed25519.
+ + commit b9fd3988b54b50109f4e7179e7fe0739bb1d97c5
+ * src/cipher.h (PUBKEY_FLAG_ECDSA): Remove.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Remove "ecdsa".
+ * cipher/ecc.c (ecc_generate, ecc_sign, ecc_verify): Require "eddsa" flag.
+ * cipher/ecc-misc.c (_gcry_ecc_compute_public): Depend "eddsa" flag.
+ * tests/benchmark.c, tests/keygen.c, tests/pubkey.c
+ * tests/t-ed25519.c, tests/t-mpi-point.c: Adjust for changed flags.
+
+ ecc: Fully implement Ed25519 compression in ECDSA mode.
+ + commit f09ffe8a4802af65a116e79eceeb1cb4ed4fa2f4
+ * src/ec-context.h (mpi_ec_ctx_s): Add field FLAGS.
+ * mpi/ec.c (ec_p_init): Add arg FLAGS. Change all callers to pass it.
+ * cipher/ecc-curves.c (point_from_keyparam): Add arg EC, parse as
+ opaque mpi and use eddsa decoding depending on the flag.
+ (_gcry_mpi_ec_new): Rearrange to parse Q and D after knowing the
+ curve.
+
+ mpi: Add function gcry_mpi_set_opaque_copy.
+ + commit 630aca794ddf057fb7265b7dc346374743036af4
+ * src/gcrypt.h.in (gcry_mpi_set_opaque_copy): New.
+ * src/visibility.c (gcry_mpi_set_opaque_copy): New.
+ * src/visibility.h (gcry_mpi_set_opaque_copy): Mark visible.
+ * src/libgcrypt.def, src/libgcrypt.vers: Add new API.
+ * tests/mpitests.c (test_opaque): Add test.
+
+2013-11-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Make test vectors 'static const'
+ + commit d50a88d1e29124d038196fec6082fd093e922604
+ * cipher/arcfour.c (selftest): Change test vectors to 'static const'.
+ * cipher/blowfish.c (selftest): Ditto.
+ * cipher/camellia-glue.c (selftest): Ditto.
+ * cipher/cast5.c (selftest): Ditto.
+ * cipher/des.c (selftest): Ditto.
+ * cipher/rijndael.c (selftest): Ditto.
+ * tests/basic.c (cipher_cbc_mac_cipher, check_aes128_cbc_cts_cipher)
+ (check_ctr_cipher, check_cfb_cipher, check_ofb_cipher)
+ (check_ccm_cipher, check_stream_cipher)
+ (check_stream_cipher_large_block, check_bulk_cipher_modes)
+ (check_ciphers, check_digests, check_hmac, check_pubkey_sign)
+ (check_pubkey_sign_ecdsa, check_pubkey_crypt, check_pubkey): Ditto.
+
+2013-11-03 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Make jump labels local in Salsa20 assembly.
+ + commit d4697862266f3c96b6946dc92139dd8f3e81e5f6
+ * cipher/salsa20-amd64.S: Rename '._labels' to '.L_labels'.
+ * cipher/salsa20-armv7-neon.S: Ditto.
+
+2013-10-30 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ bithelp: fix undefined behaviour with rol and ror.
+ + commit d1cadd145199040299538891ab2ccd1208f7776e
+ * cipher/bithelp.h (rol, ror): Mask shift with 31.
+
+2013-10-29 Werner Koch <wk@gnupg.org>
+
+ tests: Add feature to skip benchmarks.
+ + commit ba6bffafd17bea11985afc500022d66da261d59a
+ * tests/benchmark.c (main): Add feature to skip the test.
+ * tests/bench-slope.c (main): Ditto.
+ (get_slope): Repace C++ style comment.
+ (double_cmp, cipher_bench, _hash_bench): Repalce system reserved
+ symbols.
+
+ ecc: Finish Ed25519/ECDSA hack.
+ + commit c284f15db99e9cb135612de710199abb23baafd3
+ * cipher/ecc.c (ecc_generate): Fix Ed25519/ECDSA case.
+ (ecc_verify): Implement ED25519/ECDSA uncompression.
+
+ ecc: Add flags "noparam" and "comp".
+ + commit ba892a0a874c8b2a83dbf0940608cd7e2911ce01
+ * src/cipher.h (PUBKEY_FLAG_NOPARAM, PUBKEY_FLAG_COMP): New.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Parse new flags
+ and change code for possible faster parsing.
+ * cipher/ecc.c (ecc_generate): Implement the "noparam" flag.
+ (ecc_sign): Ditto.
+ (ecc_verify): Ditto.
+ * tests/keygen.c (check_ecc_keys): Use the "noparam" flag.
+
+ * cipher/ecc.c (ecc_generate): Fix parsing of the deprecated
+ transient-flag parameter.
+ (ecc_verify): Do not make Q optional in the extract-param call.
+
+2013-10-28 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix typos in documentation.
+ + commit 1faa61845f180bd47e037e400dde2d864ee83c89
+ * doc/gcrypt.texi: Fix some typos.
+
+ Add ARM NEON assembly implementation of Serpent.
+ + commit 2cb6e1f323d24359b1c5b113be5c2f79a2a4cded
+ * cipher/Makefile.am: Add 'serpent-armv7-neon.S'.
+ * cipher/serpent-armv7-neon.S: New.
+ * cipher/serpent.c (USE_NEON): New macro.
+ (serpent_context_t) [USE_NEON]: Add 'use_neon'.
+ [USE_NEON] (_gcry_serpent_neon_ctr_enc, _gcry_serpent_neon_cfb_dec)
+ (_gcry_serpent_neon_cbc_dec): New prototypes.
+ (serpent_setkey_internal) [USE_NEON]: Detect NEON support.
+ (_gcry_serpent_neon_ctr_enc, _gcry_serpent_neon_cfb_dec)
+ (_gcry_serpent_neon_cbc_dec) [USE_NEON]: Use NEON implementations
+ to process eight blocks in parallel.
+ * configure.ac [neonsupport]: Add 'serpent-armv7-neon.lo'.
+
+ Add ARM NEON assembly implementation of Salsa20.
+ + commit 3ff9d2571c18cd7a34359f9c60a10d3b0f932b23
+ * cipher/Makefile.am: Add 'salsa20-armv7-neon.S'.
+ * cipher/salsa20-armv7-neon.S: New.
+ * cipher/salsa20.c [USE_ARM_NEON_ASM]: New macro.
+ (struct SALSA20_context_s, salsa20_core_t, salsa20_keysetup_t)
+ (salsa20_ivsetup_t): New.
+ (SALSA20_context_t) [USE_ARM_NEON_ASM]: Add 'use_neon'.
+ (SALSA20_context_t): Add 'keysetup', 'ivsetup' and 'core'.
+ (salsa20_core): Change 'src' argument to 'ctx'.
+ [USE_ARM_NEON_ASM] (_gcry_arm_neon_salsa20_encrypt): New prototype.
+ [USE_ARM_NEON_ASM] (salsa20_core_neon, salsa20_keysetup_neon)
+ (salsa20_ivsetup_neon): New.
+ (salsa20_do_setkey): Setup keysetup, ivsetup and core with default
+ functions.
+ (salsa20_do_setkey) [USE_ARM_NEON_ASM]: When NEON support detect,
+ set keysetup, ivsetup and core with ARM NEON functions.
+ (salsa20_do_setkey): Call 'ctx->keysetup'.
+ (salsa20_setiv): Call 'ctx->ivsetup'.
+ (salsa20_do_encrypt_stream) [USE_ARM_NEON_ASM]: Process large buffers
+ in ARM NEON implementation.
+ (salsa20_do_encrypt_stream): Call 'ctx->core' instead of directly
+ calling 'salsa20_core'.
+ (selftest): Add test to check large buffer processing and block counter
+ updating.
+ * configure.ac [neonsupport]: 'Add salsa20-armv7-neon.lo'.
+
+ Add AMD64 assembly implementation of Salsa20.
+ + commit 5a3d43485efdc09912be0967ee0a3ce345b3b15a
+ * cipher/Makefile.am: Add 'salsa20-amd64.S'.
+ * cipher/salsa20-amd64.S: New.
+ * cipher/salsa20.c (USE_AMD64): New macro.
+ [USE_AMD64] (_gcry_salsa20_amd64_keysetup, _gcry_salsa20_amd64_ivsetup)
+ (_gcry_salsa20_amd64_encrypt_blocks): New prototypes.
+ [USE_AMD64] (salsa20_keysetup, salsa20_ivsetup, salsa20_core): New.
+ [!USE_AMD64] (salsa20_core): Change 'src' to non-constant, update block
+ counter in 'salsa20_core' and return burn stack depth.
+ [!USE_AMD64] (salsa20_keysetup, salsa20_ivsetup): New.
+ (salsa20_do_setkey): Move generic key setup to 'salsa20_keysetup'.
+ (salsa20_setkey): Fix burn stack depth.
+ (salsa20_setiv): Move generic IV setup to 'salsa20_ivsetup'.
+ (salsa20_do_encrypt_stream) [USE_AMD64]: Process large buffers in AMD64
+ implementation.
+ (salsa20_do_encrypt_stream): Move stack burning to this function...
+ (salsa20_encrypt_stream, salsa20r12_encrypt_stream): ...from these
+ functions.
+ * configure.ac [x86-64]: Add 'salsa20-amd64.lo'.
+
+ Add new benchmarking utility, bench-slope.
+ + commit e214e8392671dd30e9c33260717b5e756debf3bf
+ * tests/Makefile.am (TESTS): Add 'bench-slope'.
+ * tests/bench-slope.c: New.
+
+ Change .global to .globl in assembly files.
+ + commit ebc8abfcb09d6106fcfce40f240a513e276f46e9
+ * cipher/blowfish-arm.S: Change '.global' to '.globl'.
+ * cipher/camellia-aesni-avx-amd64.S: Ditto.
+ * cipher/camellia-aesni-avx2-amd64.S: Ditto.
+ * cipher/camellia-arm.S: Ditto.
+ * cipher/cast5-amd64.S: Ditto.
+ * cipher/rijndael-amd64.S: Ditto.
+ * cipher/rijndael-arm.S: Ditto.
+ * cipher/serpent-avx2-amd64.S: Ditto.
+ * cipher/serpent-sse2-amd64.S: Ditto.
+ * cipher/twofish-amd64.S: Ditto.
+ * cipher/twofish-arm.S: Ditto.
+
+2013-10-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Deduplicate code for ECB encryption and decryption.
+ + commit 51f1beab3d1e879942a95f58b08de7dbcce75dce
+ * cipher/cipher.c (do_ecb_crypt): New, based on old 'do_ecb_encrypt'.
+ (do_ecb_encrypt): Use 'do_ecb_crypt', pass encryption function.
+ (do_ecb_decrypt): Use 'do_ecb_crypt', pass decryption function.
+
+2013-10-26 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Drop _gcry_cipher_ofb_decrypt as it duplicates _gcry_cipher_ofb_encrypt.
+ + commit d9431725952e40f201c7eda000d3c8511ebd5b33
+ * cipher/cipher.c (cipher_decrypt): Use _gcry_cipher_ofb_encrypt for OFB
+ decryption.
+ * cipher/cipher-internal.h: Remove _gcry_cipher_ofb_decrypt declaration.
+ * cipher/cipher-ofb.c (_gcry_cipher_ofb_decrypt): Remove.
+ (_gcry_cipher_ofb_encrypt): remove copying of IV to lastiv, it's
+ unused there.
+
+2013-10-25 Werner Koch <wk@gnupg.org>
+
+ tests: Add tests for mpi_cmp.
+ + commit 6c6d4810927de7310ae7bac61b4ff5467d7cb485
+ * tests/mpitests.c (die): Modernize.
+ (fail): New.
+ (test_opaque, test_add, test_sub, test_mul): Use gcry_log_xx
+ (main): Return error count.
+ (test_cmp): New.
+
+2013-10-24 Werner Koch <wk@gnupg.org>
+
+ ecc: Change algorithm for Ed25519 x recovery.
+ + commit c630fd71b336eb9209e914d24dc1e26a34521882
+ * cipher/ecc-eddsa.c (scanval): Add as temporary hack.
+ (_gcry_ecc_eddsa_recover_x): Use the algorithm from page 15 of the
+ paper. Return an error code.
+ (_gcry_ecc_eddsa_decodepoint): Take care of the error code.
+ * mpi/mpi-mul.c (gcry_mpi_mulm): Use truncated division.
+
+ ecc: Refactor _gcry_ecc_eddsa_decodepoint.
+ + commit 1cf5699b6febab1ef9d300531acc2ee33a7df739
+ * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_decodepoint): Factor some code
+ out to ..
+ (_gcry_ecc_eddsa_recover_x): new.
+
+2013-10-24 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ ecc-gost: Add missing include.
+ + commit 9ce54e5b512418ddf45ce18f2cbd48cdced779f5
+ * ecc-gost.c: Include "pubkey-internal.h".
+
+2013-10-23 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Replace architecture specific fast_wipememory2 with generic.
+ + commit 54df6fcd806f8c150cffe6cc09925bb8b638bb5b
+ * src/g10lib.h (fast_wipememory2): Remove architecture specific
+ implementations and add generic implementation.
+
+ Improve the speed of the cipher mode code.
+ + commit 293e93672fdabc829e35cc624c397276342bafe4
+ * cipher/bufhelp.h (buf_cpy): New.
+ (buf_xor, buf_xor_2dst): If buffers unaligned, always jump to per-byte
+ processing.
+ (buf_xor_n_copy_2): New.
+ (buf_xor_n_copy): Use 'buf_xor_n_copy_2'.
+ * cipher/blowfish.c (_gcry_blowfish_cbc_dec): Avoid extra memory copy
+ and use new 'buf_xor_n_copy_2'.
+ * cipher/camellia-glue.c (_gcry_camellia_cbc_dec): Ditto.
+ * cipher/cast5.c (_gcry_cast_cbc_dec): Ditto.
+ * cipher/serpent.c (_gcry_serpent_cbc_dec): Ditto.
+ * cipher/twofish.c (_gcry_twofish_cbc_dec): Ditto.
+ * cipher/rijndael.c (_gcry_aes_cbc_dec): Ditto.
+ (do_encrypt, do_decrypt): Use 'buf_cpy' instead of 'memcpy'.
+ (_gcry_aes_cbc_enc): Avoid copying IV, use 'last_iv' pointer instead.
+ * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt): Avoid copying IV,
+ update pointer to IV instead.
+ (_gcry_cipher_cbc_decrypt): Avoid extra memory copy and use new
+ 'buf_xor_n_copy_2'.
+ (_gcry_cipher_cbc_encrypt, _gcry_cipher_cbc_decrypt): Avoid extra
+ accesses to c->spec, use 'buf_cpy' instead of memcpy.
+ * cipher/cipher-ccm.c (do_cbc_mac): Ditto.
+ * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
+ (_gcry_cipher_cfb_decrypt): Ditto.
+ * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Ditto.
+ * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt)
+ (_gcry_cipher_ofb_decrypt): Ditto.
+ * cipher/cipher.c (do_ecb_encrypt, do_ecb_decrypt): Ditto.
+
+ bufhelp: enable unaligned memory accesses for AArch64 (64-bit ARM)
+ + commit 2901a10dbf1264707debc8402546c07eeac60932
+ * cipher/bufhelp.h [__aarch64__] (BUFHELP_FAST_UNALIGNED_ACCESS): Set
+ macro on AArch64.
+
+2013-10-23 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Enable assembler optimizations on earlier ARM cores.
+ + commit 2fd83faa876d0be91ab7884b1a9eaa7793559eb9
+ * cipher/blowfish-armv6.S => cipher/blowfish-arm.S: adapt to pre-armv6 CPUs.
+ * cipher/blowfish.c: enable assembly on armv4/armv5 little-endian CPUs.
+ * cipher/camellia-armv6.S => cipher/camellia-arm.S: adapt to pre-armv6 CPUs.
+ * cipher/camellia.c, cipher-camellia-glue.c: enable assembly on armv4/armv5
+ little-endian CPUs.
+ * cipher/cast5-armv6.S => cipher/cast5-arm.S: adapt to pre-armv6 CPUs.
+ * cipher/cast5.c: enable assembly on armv4/armv5 little-endian CPUs.
+ * cipher/rijndael-armv6.S => cipher/rijndael-arm.S: adapt to pre-armv6 CPUs.
+ * cipher/rijndael.c: enable assembly on armv4/armv5 little-endian CPUs.
+ * cipher/twofish-armv6.S => cipher/twofish-arm.S: adapt to pre-armv6 CPUs.
+ * cipher/twofish.c: enable assembly on armv4/armv5 little-endian CPUs.
+
+ mpi: enable assembler on all arm architectures.
+ + commit 0b39fce7e3ce6761d6bd5195d093ec6857edb7c2
+ * mpi/config.links: remove check for arm >= v6
+ * mpi/armv6 => mpi/arm: rename directory to reflect that is is generic
+ enough
+
+ Correct ASM assembly test in configure.ac.
+ + commit 10bf6a7e16ed193f90d2749970a420f00d1d3320
+ * configure.ac: correct HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS test to
+ require neither ARMv6, nor thumb mode. Our assembly code works
+ perfectly even on ARMv4 now.
+
+2013-10-23 Werner Koch <wk@gnupg.org>
+
+ ecc: Refactor ecc.c.
+ + commit 164eb8c85d773ef4f0939115ec45f5e4b47c1700
+ * cipher/ecc-ecdsa.c, cipher/ecc-eddsa.c, cipher/ecc-gost.c: New.
+ * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add new files.
+ * configure.ac (GCRYPT_PUBKEY_CIPHERS): Add new files.
+ * cipher/ecc.c (point_init, point_free): Move to ecc-common.h.
+ (sign_ecdsa): Move to ecc-ecdsa.c as _gcry_ecc_ecdsa_sign.
+ (verify_ecdsa): Move to ecc-ecdsa.c as _gcry_ecc_ecdsa_verify.
+ (sign_gost): Move to ecc-gots.c as _gcry_ecc_gost_sign.
+ (verify_gost): Move to ecc-gost.c as _gcry_ecc_gost_verify.
+ (sign_eddsa): Move to ecc-eddsa.c as _gcry_ecc_eddsa_sign.
+ (verify_eddsa): Move to ecc-eddsa.c as _gcry_ecc_eddsa_verify.
+ (eddsa_generate_key): Move to ecc-eddsa.c as _gcry_ecc_eddsa_genkey.
+ (reverse_buffer): Move to ecc-eddsa.c.
+ (eddsa_encodempi, eddsa_encode_x_y): Ditto.
+ (_gcry_ecc_eddsa_encodepoint, _gcry_ecc_eddsa_decodepoint): Ditto.
+
+ mpi: Fix scanning of negative SSH formats and add more tests.
+ + commit 45f6e6268bfdc4b608beaba6b7086b2286e33c71
+ * mpi/mpicoder.c (gcry_mpi_scan): Fix sign setting for SSH format.
+ * tests/t-convert.c (negative_zero): Test all formats.
+ (check_formats): Add tests for PGP and scan tests for SSH and USG.
+
+ * src/gcrypt.h.in (mpi_is_neg): Fix macro.
+
+ * mpi/mpi-scan.c (_gcry_mpi_getbyte, _gcry_mpi_putbyte): Comment out
+ these unused functions.
+
+2013-10-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ twofish: add ARMv6 assembly implementation.
+ + commit 98674fdaa30ab22a3ac86ca05d688b5b6112895d
+ * cipher/Makefile.am: Add 'twofish-armv6.S'.
+ * cipher/twofish-armv6.S: New.
+ * cipher/twofish.c (USE_ARMV6_ASM): New macro.
+ [USE_ARMV6_ASM] (_gcry_twofish_armv6_encrypt_block)
+ (_gcry_twofish_armv6_decrypt_block): New prototypes.
+ [USE_AMDV6_ASM] (twofish_encrypt, twofish_decrypt): Add.
+ [USE_AMD64_ASM] (do_twofish_encrypt, do_twofish_decrypt): Remove.
+ (_gcry_twofish_ctr_enc, _gcry_twofish_cfb_dec): Use 'twofish_encrypt'
+ instead of 'do_twofish_encrypt'.
+ (_gcry_twofish_cbc_dec): Use 'twofish_decrypt' instead of
+ 'do_twofish_decrypt'.
+ * configure.ac [arm]: Add 'twofish-armv6.lo'.
+
+ mpi: allow building with clang on ARM.
+ + commit e67c67321ce240c93dd0fa2b21c649c0a8e233f7
+ * mpi/longlong.h [__arm__] (add_ssaaaa, sub_ddmmss, umul_ppmm)
+ (count_leading_zeros): Do not cast assembly output arguments.
+ [__arm__] (umul_ppmm): Remove the extra '%' ahead of assembly comment.
+ [_ARM_ARCH >= 4] (umul_ppmm): Use correct inputs and outputs instead of
+ registers.
+
+ serpent-amd64: do not use GAS macros.
+ + commit c7efaa5fe0ee92e321a7b49d56752cc12eb75fe0
+ * cipher/serpent-avx2-amd64.S: Remove use of GAS macros.
+ * cipher/serpent-sse2-amd64.S: Ditto.
+ * configure.ac [HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Do not check
+ for GAS macros.
+
+ Add Counter with CBC-MAC mode (CCM)
+ + commit 335d9bf7b035815750b63a3a8334d6ce44dc4449
+ * cipher/Makefile.am: Add 'cipher-ccm.c'.
+ * cipher/cipher-ccm.c: New.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Add 'u_mode'.
+ (_gcry_cipher_ccm_encrypt, _gcry_cipher_ccm_decrypt)
+ (_gcry_cipher_ccm_set_nonce, _gcry_cipher_ccm_authenticate)
+ (_gcry_cipher_ccm_get_tag, _gcry_cipher_ccm_check_tag)
+ (_gcry_cipher_ccm_set_lengths): New prototypes.
+ * cipher/cipher.c (gcry_cipher_open, cipher_encrypt, cipher_decrypt)
+ (_gcry_cipher_setiv, _gcry_cipher_authenticate, _gcry_cipher_gettag)
+ (_gcry_cipher_checktag, gry_cipher_ctl): Add handling for CCM mode.
+ * doc/gcrypt.texi: Add documentation for GCRY_CIPHER_MODE_CCM.
+ * src/gcrypt.h.in (gcry_cipher_modes): Add 'GCRY_CIPHER_MODE_CCM'.
+ (gcry_ctl_cmds): Add 'GCRYCTL_SET_CCM_LENGTHS'.
+ (GCRY_CCM_BLOCK_LEN): New.
+ * tests/basic.c (check_ccm_cipher): New.
+ (check_cipher_modes): Call 'check_ccm_cipher'.
+ * tests/benchmark.c (ccm_aead_init): New.
+ (cipher_bench): Add handling for AEAD modes and add CCM benchmarking.
+
+ Add API to support AEAD cipher modes.
+ + commit 95654041f2aa62f71aac4d8614dafe8433d10f95
+ * cipher/cipher.c (_gcry_cipher_authenticate, _gcry_cipher_checktag)
+ (_gcry_cipher_gettag): New.
+ * doc/gcrypt.texi: Add documentation for new API functions.
+ * src/visibility.c (gcry_cipher_authenticate, gcry_cipher_checktag)
+ (gcry_cipher_gettag): New.
+ * src/gcrypt.h.in, src/visibility.h: add declarations of these
+ functions.
+ * src/libgcrypt.defs, src/libgcrypt.vers: export functions.
+
+2013-10-22 NIIBE Yutaka <gniibe@fsij.org>
+
+ ecc: Correct compliant key generation for Edwards curves.
+ + commit a5a277a9016ccb34f1858a65e0ed1791b2fc3db3
+ * cipher/ecc.c: Add case for Edwards curves.
+
+2013-10-17 Werner Koch <wk@gnupg.org>
+
+ tests: Add test options to keygen.
+ + commit f7711e6eb5f02d03c74911f6f037ab28075e7c0d
+ * tests/keygen.c (usage): New.
+ (main): Print usage info. Allow running just one algo.
+
+ mpi: Do not clear the sign of the mpi_mod result.
+ + commit 91e007606f1f6f8e1416c403fe809d47fddf9b1f
+ * mpi/mpi-mod.c (_gcry_mpi_mod): Remove sign setting.
+
+ ecc: Put the curve name again into the output of gcry_pk_genkey.
+ + commit 4776dcd394ce59fa50d959921857b3427c5a63c8
+ * cipher/ecc.c (ecc_generate): Use the correct var. Release
+ CURVE_FLAGS.
+
+ ecc: Support Weierstrass curves in gcry_mpi_ec_curve_point.
+ + commit b22417158c50ec3a0b2ff55b4ade063b42a87e8f
+ * mpi/ec.c (_gcry_mpi_ec_curve_point): Support MPI_EC_WEIERSTRASS.
+
+2013-10-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ arcfour: more optimized version for non-i386 architectures.
+ + commit f9371c026aad09ff48746d22c8333746c886e773
+ * cipher/arcfour.c (ARCFOUR_context): Reorder members.
+ (do_encrypt_stream) [!__i386__]: Faster implementation for non-i386.
+ (do_arcfour_setkey): Avoid modulo operations.
+
+ Avoid void* pointer arithmetic.
+ + commit c89ab921ccfaefe6c4f6a724d01e0df41a1a381f
+ * tests/tsexp.c (check_extract_param): Cast void* pointers to char*
+ before doing arithmetics.
+
+2013-10-16 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ ecc: Add support for GOST R 34.10-2001/-2012 signatures.
+ + commit 83902f1f1dbc8263a0c3f61be59cd2eb95293c97
+ * src/cipher.h: define PUBKEY_FLAG_GOST
+ * cipher/ecc-curves.c: Add GOST2001-test and GOST2012-test curves
+ defined in standards. Typical applications would use either those
+ curves, or curves defined in RFC 4357 (will be added later).
+ * cipher/ecc.c (sign_gost, verify_gost): New.
+ (ecc_sign, ecc_verify): use sign_gost/verify_gost if PUBKEY_FLAG_GOST
+ is set.
+ (ecc_names): add "gost" for gost signatures.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist,
+ _gcry_pk_util_preparse_sigval): set PUBKEY_FLAG_GOST if gost flag
+ is present in s-exp.
+ * tests/benchmark.c (ecc_bench): also benchmark GOST signatures.
+ * tests/basic.c (check_pubkey): add two public keys from
+ GOST R 34.10-2012 standard.
+ (check_pubkey_sign_ecdsa): add two data sets to check gost signatures.
+ * tests/curves.c: correct N_CURVES as we now have 2 more curves.
+
+
+ Removed some comments from the new curve definitions in ecc-curves.c
+ to avoid line wrapping. Eventually we will develop a precompiler to
+ avoid parsing those hex strings. -wk
+
+ Fix 256-bit ecdsa test key definition.
+ + commit 187b2bb541b985255aee262d181434a7cb4ae2e7
+ * tests/basic.c (check_pubkey): fix nistp256 testing key declaration -
+ add missing comma.
+
+2013-10-16 Werner Koch <wk@gnupg.org>
+
+ sexp: Add function gcry_sexp_extract_param.
+ + commit a329b6abf00c990faf1986f9fbad7b4d71c13bcb
+ * src/gcrypt.h.in (_GCRY_GCC_ATTR_SENTINEL): New.
+ (gcry_sexp_extract_param): New.
+ * src/visibility.c (gcry_sexp_extract_param): New.
+ * src/visibility.h (gcry_sexp_extract_param): Add hack to detect
+ internal use.
+ * cipher/pubkey-util.c (_gcry_pk_util_extract_mpis): Move and split
+ into ...
+ * src/sexp.c (_gcry_sexp_vextract_param)
+ (_gcry_sexp_extract_param): this. Change all callers. Add support for buffer
+ descriptors and a path option/
+
+ * tests/tsexp.c (die, hex2buffer, hex2mpi, hex2mpiopa): New.
+ (cmp_mpihex, cmp_bufhex): New.
+ (check_extract_param): New.
+
+2013-10-16 NIIBE Yutaka <gniibe@fsij.org>
+
+ mpi: mpi-pow improvement.
+ + commit 45aa6131e93fac89d46733b3436d960f35fb99b2
+ * mpi/mpi-pow.c (gcry_mpi_powm): New implementation of left-to-right
+ k-ary exponentiation.
+
+2013-10-15 Werner Koch <wk@gnupg.org>
+
+ ecc: Support use of Ed25519 with ECDSA.
+ + commit 537969fbbb1104b8305a7edb331b7666d54eff2c
+ * src/cipher.h (PUBKEY_FLAG_ECDSA): New.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Add flag "ecdsa".
+ * cipher/ecc.c (verify_ecdsa, verify_eddsa): Remove some debug output.
+ (ecc_generate, ecc_sign, ecc_verify): Support Ed25519 with ECDSA.
+ * tests/keygen.c (check_ecc_keys): Create such a test key.
+ * tests/pubkey.c (fail, info, data_from_hex, extract_cmp_data): New.
+ Take from dsa-6979.c
+ (check_ed25519ecdsa_sample_key): new.
+ (main): Call new test.
+
+2013-10-14 Werner Koch <wk@gnupg.org>
+
+ pubkey: Support flags list in gcry_pk_genkey.
+ + commit d3a605d7827b8a73ef844e9e5183590bd6b1389a
+ * src/cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): New.
+ (PUBKEY_FLAG_USE_X931): New.
+ (PUBKEY_FLAG_USE_FIPS186): New.
+ (PUBKEY_FLAG_USE_FIPS186_2): New.
+ * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Rename from
+ parse_flags_list. Parse new flags.
+ * cipher/dsa.c (dsa_generate): Support flag list.
+ * cipher/ecc.c (ecc_generate): Ditto.
+ * cipher/rsa.c (rsa_generate): Ditto.
+
+ pubkey: Remove duplicated flag parsing code.
+ + commit 5be2345ddec4147e535d5b039ee74f84bcacf9e4
+ * cipher/pubkey-util.c (_gcry_pk_util_preparse_encval)
+ (_gcry_pk_util_data_to_mpi): Factor flag parsing code out to ..
+ (parse_flag_list): New.
+ * src/cipher.h (PUBKEY_FLAG_RAW_FLAG): New.
+
+ mpicalc: Accept lowercase hex digits.
+ + commit 0cd551faa775ad5309a40629ae30bf86b75fca09
+ * src/mpicalc.c (main): Test for lowercase hex digits.
+
+2013-10-11 Werner Koch <wk@gnupg.org>
+
+ pubkey: Move sexp parsing of remaining fucntions to the modules.
+ + commit a951c061523e1c13f1358c9760fc3a9d787ab2d4
+ * cipher/pubkey.c (release_mpi_array): Remove.
+ (pubkey_check_secret_key): Remove.
+ (sexp_elements_extract): Remove.
+ (sexp_elements_extract_ecc): Remove.
+ (sexp_to_key): Remove.
+ (get_hash_algo): Remove.
+ (gcry_pk_testkey): Revamp.
+ (gcry_pk_get_curve): Revamp.
+ * cipher/rsa.c (rsa_check_secret_key): Revamp.
+ * cipher/elgamal.c (elg_check_secret_key): Revamp.
+ * cipher/dsa.c (dsa_check_secret_key): Revamp.
+ * cipher/ecc.c (ecc_check_secret_key): Revamp.
+ * cipher/ecc-curves.c: Include cipher.h and pubkey-internal.h
+ (_gcry_ecc_get_curve): Revamp.
+
+ * cipher/pubkey-util.c (_gcry_pk_util_extract_mpis): Set passed and
+ used parameters on error to NULL.
+
+ pubkey: Move sexp parsing for gcry_pk_decrypt to the modules.
+ + commit 07950c865a901afc48acb46f0695040cadfd5068
+ * cipher/rsa.c (rsa_decrypt): Revamp.
+ * cipher/elgamal.c (elg_decrypt): Revamp.
+ * cipher/ecc.c (ecc_decrypt_raw): Revamp.
+ * cipher/pubkey.c (gcry_pk_decrypt): Simplify.
+ (sexp_to_enc): Remove.
+ * cipher/pubkey-util.c (_gcry_pk_util_preparse_encval): New.
+
+ pubkey: Move sexp parsing for gcry_pk_encrypt to the modules.
+ + commit 6bd5d18c45a4a3ce8f0f66f56c83b80594877f53
+ * cipher/rsa.c (rsa_encrypt): Revamp.
+ * cipher/elgamal.c (elg_encrypt): Revamp.
+ * cipher/ecc.c (ecc_encrypt_raw): Revamp.
+ * cipher/pubkey.c (gcry_pk_encrypt): Simplify.
+
+ * tests/basic.c (check_pubkey_crypt): Init plain, ciph, and data so
+ that they are initialized even after an encrypt failure.
+
+ pubkey: Move sexp parsing for gcry_pk_sign to the modules.
+ + commit d0ae6635e4e6ae273c3a137c513d518f28f6eab3
+ * cipher/rsa.c (rsa_sign): Revamp.
+ * cipher/dsa.c (dsa_sign): Revamp.
+ * cipher/elgamal.c (elg_sign): Revamp.
+ * cipher/ecc.c (ecc_sign): Revamp.
+ * cipher/pubkey.c (gcry_pk_sign): Simplify.
+
+2013-10-10 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Prevent tail call optimization with _gcry_burn_stack.
+ + commit 150c0313f971bcea62d2802f0389c883e11ebb31
+ * configure.ac: New check, HAVE_GCC_ASM_VOLATILE_MEMORY.
+ * src/g10lib.h (_gcry_burn_stack): Rename to __gcry_burn_stack.
+ (__gcry_burn_stack_dummy): New.
+ (_gcry_burn_stack): New macro.
+ * src/misc.c (_gcry_burn_stack): Rename to __gcry_burn_stack.
+ (__gcry_burn_stack_dummy): New.
+
+2013-10-09 Werner Koch <wk@gnupg.org>
+
+ pubkey: Move sexp parsing for gcry_pk_verify to the modules.
+ + commit 94b652ecb006c29fa2ffb1badc9f02b758581737
+ * cipher/rsa.c (rsa_verify): Revamp.
+ * cipher/dsa.c (dsa_verify): Revamp.
+ * cipher/elgamal.c (elg_verify): Revamp.
+ * cipher/ecc.c (ecc_verify): Revamp.
+ * cipher/pubkey.c (sexp_to_sig): Remove.
+ (pss_verify_cmp): Move to pubkey-util.c
+ (sexp_data_to_mpi): Ditto.
+ (init_encoding_ctx): Ditto.
+ (gcry_pk_verify): Simplify.
+ * cipher/pubkey-util.c (_gcry_pk_util_init_encoding_ctx): Add. Take
+ from pubkey.c
+ (get_hash_algo): Ditto.
+ (_gcry_pk_util_data_to_mpi): Ditto.
+ (pss_verify_cmp): Ditto.
+ (_gcry_pk_util_extract_mpis): New.
+ (_gcry_pk_util_preparse_sigval): New.
+ (_gcry_pk_util_free_encoding_ctx): New.
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Make curve init
+ optional.
+
+ * src/g10lib.h (GCC_ATTR_SENTINEL): New.
+
+ * tests/basic.c (check_pubkey_sign): Print the algo name.
+ (main): Add option --pubkey.
+
+2013-10-08 Werner Koch <wk@gnupg.org>
+
+ pubkey: Move sexp parsing for gcry_pk_get_nbits to the modules.
+ + commit 4645f3728bb0900591b0aef85831fdee52c59e3c
+ * cipher/pubkey.c (spec_from_sexp): New.
+ (gcry_pk_get_nbits): Simplify.
+ * cipher/rsa.c (rsa_get_nbits): Take only PARMS as args and do sexp
+ parsing here.
+ * cipher/dsa.c (dsa_get_nbits): Ditto.
+ * cipher/elgamal.c (elg_get_nbits): Ditto.
+ * cipher/ecc.c (ecc_get_nbits): Ditto.
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Allow NULL for arg
+ CURVE.
+
+ pubkey: Move sexp parsing for gcry_pk_getkey to the modules.
+ + commit 3816e46ce211e63adf46dbc775510aa137572248
+ * cipher/pubkey-util.c: New.
+ (_gcry_pk_util_get_nbits): New. Based on code from gcry_pk_genkey.
+ (_gcry_pk_util_get_rsa_use_e): Ditto.
+ * cipher/pubkey.c (gcry_pk_genkey): Strip most code and pass.
+ * cipher/rsa.c (rsa_generate): Remove args ALGO, NBITS and EVALUE.
+ Call new fucntions to get these values.
+ * cipher/dsa.c (dsa_generate): Remove args ALGO, NBITS and EVALUE.
+ Call _gcry_pk_util_get_nbits to get nbits. Always parse genparms.
+ * cipher/elgamal.c (elg_generate): Ditto.
+ * cipher/ecc.c (ecc_generate): Ditto.
+
+ cipher: Deprecate GCRY_PK_ELG_E.
+ + commit f79d3e13d3229115c47cbe5007647cb44105fe3f
+ * cipher/elgamal.c (_gcry_pubkey_spec_elg_e): Remove.
+ * cipher/pubkey.c (pubkey_list): Remove double included
+ _gcry_pubkey_spec_elg.
+ (map_algo): MAke ELG_E to ELG.
+
+2013-10-02 Werner Koch <wk@gnupg.org>
+
+ Provide Pth compatiblity for use with GnuPG 2.0.
+ + commit 2f767f6a17f7e99da4075882f7fe3ca597b31bdb
+ * src/ath.c (ath_install): Call ath_init and declare Pth as
+ compatible.
+
+2013-10-02 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ sha512: fix building on ARM.
+ + commit 6410152338a2b2ac1216e70c153cd16f9199c94e
+ * cipher/sha512.c (transform) [USE_ARM_NEON_ASM]: Fix 'hd' to 'ctx'.
+
+2013-10-02 Werner Koch <wk@gnupg.org>
+
+ Remove deprecated control codes.
+ + commit f04a1db22d982627ba87da4e5df52df9b994c779
+ * src/gcrypt.h.in (GCRYCTL_SET_KEY): Remove.
+ (GCRYCTL_SET_IV): Remove.
+ (GCRYCTL_SET_CTR): Remove.
+ * cipher/md.c (gcry_md_ctl): Remove deprecated GCRYCTL_SET_KEY.
+ * cipher/cipher.c (gcry_cipher_ctl): Remove deprecated
+ GCRYCTL_SET_KEY, GCRYCTL_SET_IV, GCRYCTL_SET_CTR.
+
+2013-10-02 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Fix errors when building with Clang on PPC.
+ + commit 33757c1e03f1d885920633edf543cd1c77999455
+ * mpi/longlong.h (add_ssaaaa, sub_ddmmss, count_leading_zeros,
+ umul_ppmm): Do not cast asm output to USItype.
+
+2013-10-02 Werner Koch <wk@gnupg.org>
+
+ Remove last remains of the former module system.
+ + commit 628ed5ba0ef4b1f04b5a77e29e4bc49a1fe13c07
+ * src/gcrypt-module.h, src/module.c: Remove.
+ * src/visibility.h: Do not include gcrypt-module.h.
+ * src/g10lib.h: Remove all prototypes from module.c
+ (gcry_module): Remove.
+ * cipher/cipher-internal.h (gcry_cipher_handle): Remove unused field.
+
+ Fix missing prototype warning in visibility.c.
+ + commit 52783d483293d48cd468143ae6ae2cccbfe17200
+ * src/ec-context.h (_gcry_mpi_ec_new): Move prototype to mpi.h.
+
+ md: Simplify the message digest dispatcher md.c.
+ + commit 0d39997932617ba20656f8bcc230ba744b76c87e
+ * src/gcrypt-module.h (gcry_md_spec_t): Move to ...
+ * src/cipher-proto.h: here. Merge with md_extra_spec_t. Add fields
+ ALGO and FLAGS. Set these fields in all digest modules.
+ * cipher/md.c: Change most code to replace the former module
+ system by a simpler system to gain information about the algorithms.
+
+2013-10-01 Werner Koch <wk@gnupg.org>
+
+ cipher: Simplify the cipher dispatcher cipher.c.
+ + commit 3ca180b25e8df252fc16f802cfdc27496e307830
+ * src/gcrypt-module.h (gcry_cipher_spec_t): Move to ...
+ * src/cipher-proto.h (gcry_cipher_spec_t): here. Merge with
+ cipher_extra_spec_t. Add fields ALGO and FLAGS. Set these fields in
+ all cipher modules.
+ * cipher/cipher.c: Change most code to replace the former module
+ system by a simpler system to gain information about the algorithms.
+ (disable_pubkey_algo): Simplified. Not anymore thread-safe, though.
+
+ * cipher/md.c (_gcry_md_selftest): Use correct structure. Not a real
+ problem because both define the same function as their first field.
+
+ * cipher/pubkey.c (_gcry_pk_selftest): Take care of the disabled flag.
+
+ mpi: Fix gcry_mpi_neg.
+ + commit 4153fa859816e799e506055321a22e6450aacdcc
+ * mpi/mpiutil.c (_gcry_mpi_neg): Copy U to W.
+
+2013-10-01 Peter Wu <lekensteyn@gmail.com>
+
+ cipher: Add support for 128-bit keys in RC2.
+ + commit 738177ec0eae05069ec61bc4f724a69d4e052e42
+ * cipher/rfc2268.c (oids_rfc2268_128): New
+ (_gcry_cipher_spec_rfc2268_128): New.
+ * cipher/cipher.c (cipher_table_entry): Add GCRY_CIPHER_RFC2268_128.
+
+2013-09-30 Werner Koch <wk@gnupg.org>
+
+ ecc: Use faster b parameter for Ed25519.
+ + commit 1d85452412b65e7976bc94969fc513ff6b880ed8
+ * cipher/ecc-curves.c (domain_parms): Replace b.
+ * tests/t-mpi-point.c (test_curve): Ditto.
+
+ ecc: Prepare for future Ed25519 optimization.
+ + commit a2618c822e666d4121cba29bee3fd50bf70c9743
+ * mpi/ec-ed25519.c: New but empty file.
+ * mpi/ec-internal.h: New.
+ * mpi/ec.c: Include ec-internal.h.
+ (ec_mod): New.
+ (ec_addm): Use ec_mod.
+ (ec_mulm): Remove commented code. Use ec_mod.
+ (ec_subm): Call simple sub.
+ (ec_pow2): Use ec_mulm.
+ (ec_mul2): New.
+ (dup_point_weierstrass): Use ec_mul2.
+ (dup_point_twistededwards): Add special case for a == -1. Use
+ ec_mul2.
+ (add_points_weierstrass): Use ec_mul2.
+ (add_points_twistededwards): Add special case for a == -1.
+ (_gcry_mpi_ec_curve_point): Ditto.
+ (ec_p_init): Add hack to test Barrett functions.
+ * src/ec-context.h (mpi_ec_ctx_s): Add P_BARRETT.
+
+ * mpi/mpi-mod.c (_gcry_mpi_mod_barrett): Fix sign problem.
+
+ ecc: Fix recomputing of Q for Ed25519.
+ + commit c325adb8f5092b80a626bd3bb5e49cf7f3a29fc8
+ * cipher/ecc-misc.c (reverse_buffer): New.
+ (_gcry_ecc_compute_public): Add ED255519 specific code.
+ * cipher/ecc.c (sign_eddsa): Allocate DIGEST in secure memory. Get
+ rid of HASH_D.
+ * tests/t-mpi-point.c (context_param): Test recomputing of Q for
+ Ed25519.
+
+ log: Try to print s-expressions in a more compact format.
+ + commit d69a13d3d1c14ad6a6aa7cd349d6d2dfb152d422
+ * src/misc.c (count_closing_parens): New.
+ (_gcry_log_printsxp): Use new function.
+ * mpi/ec.c (_gcry_mpi_point_log): Take care of a NULL point.
+
+2013-09-30 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Make Whirlpool use the _gcry_md_block_write helper.
+ + commit 68cefd0f1d60ac33b58031df9b1d165cb1bf0f14
+ * cipher/whirlpool.c (whirlpool_context_t): Add 'bctx', remove
+ 'buffer', 'count' and 'nblocks'.
+ (whirlpool_init): Initialize 'bctx'.
+ (whirlpool_transform): Adjust context argument type and burn stack
+ depth.
+ (whirlpool_add): Remove.
+ (whirlpool_write): Use _gcry_md_block_write.
+ (whirlpool_final, whirlpool_read): Adjust for 'bctx' usage.
+
+ whirlpool: add stack burning after transform.
+ + commit a96d622e1a36d40d1504b7ada567e90ec9957443
+ * cipher/whirlpool.c (whirlpool_transform): Return burn stack depth.
+ (whirlpool_add): Do burn_stack.
+
+ whirlpool: do bitcount calculation in finalization part.
+ + commit 10d7351411f19bb2c03d2e24ca5a38dabe45023b
+ * cipher/whirlpool.c (whirlpool_context_t): Remove 'length', add
+ 'nblocks'.
+ (whirlpool_add): Update 'nblocks' instead of 'length', and add early
+ return at one spot.
+ (whirlpool_write): Check for 'nblocks' overflow.
+ (whirlpool_final): Convert 'nblocks' to bit-counter, and use
+ whirlpool_write instead of whirlpool_add.
+
+2013-09-30 Werner Koch <wk@gnupg.org>
+
+ Add logging functions to the API.
+ + commit d2076f27bb7c5d505abf25fc622d21794c4a5df3
+ * src/gcrypt.h.in (_GCRY_GCC_ATTR_PRINTF): New.
+ (gcry_log_debug, gcry_log_debughex, gcry_log_debugmpi): New.
+ (gcry_log_debugpnt, gcry_log_debugsxp): New.
+ * src/visibility.c (gcry_log_debug): New.
+ (gcry_log_debughex, gcry_log_debugmpi, gcry_log_debugpnt): New.
+ (gcry_log_debugsxp): New.
+ * src/libgcrypt.def, src/libgcrypt.vers: Add new functions.
+ * src/misc.c (_gcry_logv): Make public.
+ (_gcry_log_printsxp): New.
+ * src/g10lib.h (log_printsxp): New macro.
+
+2013-09-26 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Make libgcrypt build with Clang on i386.
+ + commit db60d828137c4f3682ca4ca2a54fe3d96d3db5f9
+ * cipher/longlong.h [__i386__] (add_ssaaaa, sub_ddmmss)
+ (umul_ppmm, udiv_qrnnd): Do not cast asm output to USItype.
+
+2013-09-25 Werner Koch <wk@gnupg.org>
+
+ mpi: Change not yet used _gcry_mpi_set_opaque_copy.
+ + commit 1c6660debdbf1e4c3e80074c846a3e3097f214bb
+ * mpi/mpiutil.c (_gcry_mpi_set_opaque_copy): Change prototype.
+ (_gcry_mpi_get_opaque_copy): Take care of gcry_malloc failure.
+
+ sexp: Improve printing of data with a leading zero.
+ + commit 9b7c49971588edf6acfc74bfb797eb79d19cb350
+ * src/sexp.c (suitable_encoding): Detect leading zero byte.
+
+ ecc: Allow the name "q@eddsa" to get/set the public key.
+ + commit d6683d2a6065986a9198d2d2eaa02c005b68cea4
+ * cipher/ecc-curves.c (_gcry_ecc_get_mpi): Support "q@eddsa".
+ (_gcry_ecc_set_mpi): Support "q".
+ * cipher/ecc.c (eddsa_encodepoint): Rename to ...
+ (_gcry_ecc_eddsa_encodepoint): this and make global. Remove arg
+ MINLEN and take from context.
+ (eddsa_decodepoint): Rename to
+ (_gcry_ecc_eddsa_decodepoint): this and make global. Remove arg LEN
+ and take from context.
+ (sign_eddsa, verify_eddsa): Take B from context.
+ (ecc_sign, ecc_verify): Add hack to set DIALECT.
+ (_gcry_pk_ecc_get_sexp): Use _gcry_ecc_compute_public. Handle EdDSA.
+ * src/ec-context.h (mpi_ec_ctx_s): Add field NBITS.
+ * mpi/ec.c (ec_p_init): Init NBITS.
+ * tests/t-mpi-point.c (test_curve): Add Ed25519.
+ (sample_ed25519_q): New.
+ (context_param): Check new sample key.
+ (hex2buffer, hex2mpiopa): New.
+ (cmp_mpihex): Take care of opaque MPIs.
+
+ mpicalc: Add statement to compute the number of bits.
+ + commit 9a4447ccd1b90bcd701941e80a7f484a1825fcea
+ * src/mpicalc.c (do_nbits): New.
+ (main): Add statement 'b'.
+
+ ecc: Refactor low-level access functions.
+ + commit 64a7d347847d606eb5f4c156e24ba060271b8f6b
+ * mpi/ec.c (point_copy): Move to cipher/ecc-curves.c.
+ (ec_get_reset): Rename to _gcry_mpi_ec_get_reset and make global.
+ (_gcry_mpi_ec_get_mpi): Factor most code out to _gcry_ecc_get_mpi.
+ (_gcry_mpi_ec_get_point): Factor most code out to _gcry_ecc_get_point.
+ (_gcry_mpi_ec_set_mpi): Factor most code out to _gcry_ecc_set_mpi.
+ (_gcry_mpi_ec_set_point): Factor most code out to _gcry_ecc_set_point.
+ * cipher/ecc-curves.c (_gcry_ecc_get_mpi): New.
+ (_gcry_ecc_get_point, _gcry_ecc_set_mpi, _gcry_ecc_set_point): New.
+ * cipher/ecc-misc.c (_gcry_ecc_compute_public): New.
+
+ ecc: Fix highly unlikely endless loop in sign_ecdsa.
+ + commit 1f5f4452e5bca105ec2197a4facbf9778e7dc31e
+ * cipher/ecc.c (sign_ecdsa): Turn while-do into do-while loops.
+
+2013-09-24 Werner Koch <wk@gnupg.org>
+
+ ecc: Allow the use of an uncompressed public key.
+ + commit df013c9820709421ef9550158ac5df0060d73379
+ * cipher/ecc.c (eddsa_encodepoint): Factor most code out to ...
+ (eddsa_encode_x_y): new fucntion.
+ (eddsa_decodepoint): Allow use of an uncompressed public key.
+ * tests/t-ed25519.c (N_TESTS): Adjust.
+ * tests/t-ed25519.inp: Add test 1025.
+
+2013-09-23 Werner Koch <wk@gnupg.org>
+
+ pk: Add algo id GCRY_PK_ECC and deprecate ECDSA and ECDH.
+ + commit d5f91466695c5736f441c9bf1998436184a4bf61
+ * src/gcrypt.h.in (GCRY_PK_ECC): New.
+ * cipher/pubkey.c (map_algo): New.
+ (spec_from_algo, gcry_pk_get_param, _gcry_pk_selftest): Use it.
+ * cipher/ecc.c (selftests_ecdsa): Report using GCRY_PK_ECC.
+ (run_selftests): Simplify.
+ (ecdh_names, ecdsa_names): Merge into a new ecc_names.
+ (_gcry_pubkey_spec_ecdh, _gcry_pubkey_spec_ecdsa): Merge into new
+ _gcry_pubkey_spec_ecc.
+
+ ec: Use mpi_mulm instead of mpi_powm.
+ + commit 4552437bb3c5ff96a889fd31e4bc504b2a12fac7
+ * mpi/ec.c (ec_pow2): New.
+ (ec_powm): Remove call to mpi_abs.
+ (dup_point_weierstrass, dup_point_twistededwards)
+ (add_points_weierstrass, add_points_twistededwards)
+ (_gcry_mpi_ec_curve_point): Use ec_pow2.
+
+2013-09-21 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ bufhelp: enable fast unaligned memory accesses on powerpc.
+ + commit 925d4fb3e8f2df3c5566ec6b5df7620a3d3504e5
+ * cipher/bufhelp.h [__powerpc__] (BUFHELP_FAST_UNALIGNED_ACCESS): Set
+ macro enabled.
+ [__powerpc64__] (BUFHELP_FAST_UNALIGNED_ACCESS): Ditto.
+
+ Remove i386 inline assembly version of rotation functions.
+ + commit cfea5c28a3822e1e7e401e5107ebe07ba7fdcf37
+ * cipher/bithelp.h (rol, ror): Remove i386 version, change
+ macros to inline functions.
+ * src/hmac256.c (ror): Ditto.
+
+ Optimize and cleanup 32-bit and 64-bit endianess transforms.
+ + commit 9337e03824a5bdd3bbbcb8382cabefe6d6c32e1e
+ * cipher/bithelp.h (bswap32, bswap64, le_bswap32, be_bswap32)
+ (le_bswap64, be_bswap64): New.
+ * cipher/bufhelp.h (buf_get_be32, buf_get_le32, buf_put_le32)
+ (buf_put_be32, buf_get_be64, buf_get_le64, buf_put_be64)
+ (buf_put_le64): New.
+ * cipher/blowfish.c (do_encrypt_block, do_decrypt_block): Use new
+ endian conversion helpers.
+ (do_bf_setkey): Turn endian specific code to generic.
+ * cipher/camellia.c (GETU32, PUTU32): Use new endian conversion
+ helpers.
+ * cipher/cast5.c (rol): Remove, use rol from bithelp.
+ (F1, F2, F3): Fix to use rol from bithelp.
+ (do_encrypt_block, do_decrypt_block, do_cast_setkey): Use new endian
+ conversion helpers.
+ * cipher/des.c (READ_64BIT_DATA, WRITE_64BIT_DATA): Ditto.
+ * cipher/md4.c (transform, md4_final): Ditto.
+ * cipher/md5.c (transform, md5_final): Ditto.
+ * cipher/rmd160.c (transform, rmd160_final): Ditto.
+ * cipher/salsa20.c (LE_SWAP32, LE_READ_UINT32): Ditto.
+ * cipher/scrypt.c (READ_UINT64, LE_READ_UINT64, LE_SWAP32): Ditto.
+ * cipher/seed.c (GETU32, PUTU32): Ditto.
+ * cipher/serpent.c (byte_swap_32): Remove.
+ (serpent_key_prepare, serpent_encrypt_internal)
+ (serpent_decrypt_internal): Use new endian conversion helpers.
+ * cipher/sha1.c (transform, sha1_final): Ditto.
+ * cipher/sha256.c (transform, sha256_final): Ditto.
+ * cipher/sha512.c (__transform, sha512_final): Ditto.
+ * cipher/stribog.c (transform, stribog_final): Ditto.
+ * cipher/tiger.c (transform, tiger_final): Ditto.
+ * cipher/twofish.c (INPACK, OUTUNPACK): Ditto.
+ * cipher/whirlpool.c (buffer_to_block, block_to_buffer): Ditto.
+ * configure.ac (gcry_cv_have_builtin_bswap32): Check for compiler
+ provided __builtin_bswap32.
+ (gcry_cv_have_builtin_bswap64): Check for compiler provided
+ __builtin_bswap64.
+
+ gostr3411_94: set better burn stack depth estimate.
+ + commit 7409de7bc28ff8847c9d71d8c3e35e1968d59d60
+ * cipher/gost28147.c (_gcry_gost_enc_one): Account function stack to
+ burn stack depth.
+ * cipher/gostr3411-94.c (max): New macro.
+ (do_hash_step, transform): Return stack burn depth.
+
+ Use hash transform function return type for passing burn stack depth.
+ + commit 592c2ab3deeeccbb6d3b078ed7bf0e6627c8e1fb
+ * cipher/gostr4311-94.c (transform): Return stack burn depth.
+ * cipher/hash-common.c (_gcry_md_block_write): Use stack burn depth
+ returned by 'hd->bwrite'.
+ * cipher/hash-common.h (_gcry_md_block_write_t): Change return type to
+ 'unsigned int'.
+ (gry_md_block_ctx_t): Remove 'stack_burn'.
+ * cipher/md4.c (transform): Return stack burn depth.
+ (md4_final): Use stack burn depth from transform.
+ * cipher/md5.c (transform): Return stack burn depth.
+ (md5_final): Use stack burn depth from transform.
+ * cipher/rmd160.c (transform): Return stack burn depth.
+ (rmd160_final): Use stack burn depth from transform.
+ * cipher/sha1.c (transform): Return stack burn depth.
+ (sha1_final): Use stack burn depth from transform.
+ * cipher/sha256.c (transform): Return stack burn depth.
+ (sha256_final): Use stack burn depth from transform.
+ * cipher/sha512.c (__transform, transform): Return stack burn depth.
+ (sha512_final): Use stack burn depth from transform.
+ * cipher/stribog.c (transform64): Return stack burn depth.
+ * cipher/tiger.c (transform): Return stack burn depth.
+ (tiger_final): Use stack burn depth from transform.
+
+ Make STRIBOG use the new _gcry_md_block_write helper.
+ + commit 902ea6052c11108bd19333c31b03e084bed1fb86
+ * cipher/stribog.c (STRIBOG_STRUCT): Add 'bctx' and remove 'buf' and
+ 'count'.
+ (stribog_init_512): Initialize 'bctx'.
+ (transform64): New function.
+ (stribog_write): Remove.
+ (stribog_final): Use _gcry_md_block_write and bctx.
+ (_gcry_digest_spec_stribog_256, _gcry_digest_spec_stribog_512): Use
+ _gcry_md_block_write.
+
+ Make SHA-512 use the new _gcry_md_block_write helper.
+ + commit cce7449efe471b076c5a97929ac8907162011394
+ * cipher/hash-common.c (_gcry_md_block_write): Check that hd->buf is
+ large enough.
+ * cipher/hash-common.h (MD_BLOCK_MAX_BLOCKSIZE, MD_NBLOCKS_TYPE): New
+ macros.
+ (gcry_md_block_ctx_t): Use above macros for 'nblocks' and 'buf'.
+ * cipher/sha512.c (SHA512_STATE): New struct.
+ (SHA512_CONTEXT): Add 'bctx' and 'state'.
+ (sha512_init, sha384_init): Initialize 'bctx'.
+ (__transform, _gcry_sha512_transform_armv7_neon): Use SHA512_STATE for
+ 'hd'.
+ (transform): For now, do not return burn stack.
+ (sha512_write): Remove.
+ (sha512_final): Use _gcry_md_block_write and bctx.
+ (_gcry_digest_spec_sha512, _gcry_digest_spec_sha384): Use
+ _gcry_md_block_write.
+
+2013-09-20 Werner Koch <wk@gnupg.org>
+
+ sexp: Change internal versions to always use gpg_err_code_t.
+ + commit 3e5cfa20acfeccb9df2c3fae2730344b40b36104
+ * src/sexp.c (gcry_sexp_new, gcry_sexp_create, gcry_sexp_build)
+ (gcry_sexp_build_array, gcry_sexp_canon_len): Change error return type
+ from gpg_error_t to gpg_err_code_t. Remove all calls to gpg_error.
+ * src/visibility.c (gcry_sexp_new, gcry_sexp_create, gcry_sexp_sscan)
+ (gcry_sexp_build, gcry_sexp_build_array, gcry_sexp_canon_len): Map
+ error codes via gpg_error.
+ * cipher/dsa.c, cipher/ecc.c, cipher/elgamal.c, cipher/rsa.c: Remove
+ use gpg_err_code wrappers.
+
+ pk: Move s-exp creation for gcry_pk_decrypt to the modules.
+ + commit 722bfc1e5f2268453db62f38cc46b5ec6ef3adee
+ * cipher/pubkey.c (sexp_to_enc): Remove RET_MODERN arg and merge it
+ into FLAGS.
+ (gcry_pk_decrypt): Move result s-exp building into the modules.
+ * src/cipher-proto.h (gcry_pk_decrypt_t): Add some args.
+ * cipher/ecc.c (ecc_decrypt_raw): Change to return an s-exp.
+ * cipher/elgamal.c (elg_decrypt): Ditto.
+ * cipher/rsa.c (rsa_decrypt): Ditto.
+ (rsa_blind, rsa_unblind): Merge into rsa_decrypt. This saves several
+ extra MPI allocations.
+
+ pk: Remove unused function.
+ + commit 64cd7ab93da7c95cc8aa320c61c6e29f9e2399c4
+ * cipher/pubkey.c (_gcry_pk_aliased_algo_name): Remove
+
+2013-09-19 Werner Koch <wk@gnupg.org>
+
+ Beautify debug output of the prime generator.
+ + commit 6576f0a7684292cb5691bfcabad0acca4c06c014
+ * cipher/primegen.c: Adjust output of log_mpidump to recently changed
+ log_mpidump code changes.
+
+ pk: Move s-expr creation for genkey to the modules.
+ + commit 1bf08850bf9343146c938bc03917417e16393e9a
+ * cipher/pubkey.c (pubkey_generate): Fold into gcry_pk_genkey
+ (gcry_pk_genkey): Move result s-exp creation into the modules.
+ * cipher/dsa.c (dsa_generate): Create result as s-exp.
+ * cipher/elgamal.c (elg_generate): Ditto.
+ * cipher/rsa.c (rsa_generate): Ditto.
+ * cipher/ecc.c (ecc_generate): Ditto.
+ * src/cipher-proto.h (pk_ext_generate_t): Remove type
+ (gcry_pk_spec): and remove from struct.
+
+ tests: Beautify some diagnostics.
+ + commit 2fe084873333c4d67bcfba0b527d63cd3cff6c47
+ * tests/benchmark.c (ecc_bench): Print the key sexp in very verbose
+ mode.
+ (main): Add option --pk-count.
+ * tests/keygen.c: Add Elgamal generation and improved diagnostics.
+ * tests/t-ed25519.c (check_ed25519): Print running number of tests
+ done.
+
+ sexp: Improve printing data representing a negative number.
+ + commit b3f3d47d347c14ed41d755cee580f000309b9c03
+ * src/sexp.c (suitable_encoding): Detect a negative number.
+
+ pk: Move RSA encoding functions to a new file.
+ + commit 071f70b9a766187fc70f6abc6a69d50752449285
+ * cipher/rsa-common: New.
+ * cipher/pubkey.c (pkcs1_encode_for_encryption): Move to rsa-common.c
+ and rename to _gcry_rsa_pkcs1_encode_for_enc.
+ (pkcs1_decode_for_encryption): Move to rsa-common.c and rename to
+ _gcry_rsa_pkcs1_decode_for_enc.
+ (pkcs1_encode_for_signature): Move to rsa-common.c and rename to
+ _gcry_rsa_pkcs1_encode_for_sig.
+ (oaep_encode): Move to rsa-common.c and rename to
+ _gcry_rsa_oaep_encode.
+ (oaep_decode): Move to rsa-common.c and rename to
+ _gcry_rsa_oaep_decode.
+ (pss_encode): Move to rsa-common.c and rename to _gcry_rsa_pss_encode.
+ (pss_verify): Move to rsa-common.c and rename to _gcry_rsa_pss_decode.
+ (octet_string_from_mpi, mgf1): Move to rsa-common.c.
+
+ pk: Move s-expr creation for sign and encrypt to the modules.
+ + commit eca9e2e50ddd4c9020fe1d4a9a3c77d20ebb90f6
+ * cipher/pubkey.c (pubkey_encrypt): Fold into gcry_pk_encrypt.
+ (pubkey_decrypt): Fold into gcry_pk_decrypt.
+ (pubkey_sign): Fold into gcry_pk_sign.
+ (pubkey_verify): Fold into gcry_pk_verify.
+ (octet_string_from_mpi): Make it a wrapper and factor code out to ...
+ * mpi/mpicoder.c (_gcry_mpi_to_octet_string): New function.
+
+ * src/cipher.h (PUBKEY_FLAG_FIXEDLEN): New.
+ * cipher/pubkey.c (sexp_data_to_mpi): Set flag for some encodings.
+ (gcry_pk_encrypt): Simply by moving the s-expr generation to the modules.
+ (gcry_pk_sign): Ditto.
+ * cipher/dsa.c (dsa_sign): Create s-expr.
+ * cipher/elgamal.c (elg_encrypt, elg_sign): Ditto.
+ * cipher/rsa.c (rsa_encrypt, rsa_sign): Ditto.
+ * cipher/ecc.c (ecc_sign, ecc_encrypt_raw): Ditto.
+ (ecdsa_names): Add "eddsa".
+ * tests/t-ed25519.c (one_test): Expect "eddsa" token.
+
+2013-09-19 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Fix Stribog digest on bigendian platforms.
+ + commit d399faf5db71d429bfd6fa4a9cfc82e2a55055f0
+ * cipher/stribog.c (stribog_final): swap bytes in the result of digest
+ calculations.
+
+2013-09-18 Werner Koch <wk@gnupg.org>
+
+ pk: Simplify the public key dispatcher pubkey.c.
+ + commit 85722afb379f7a392a8117b895de273fd88c4ebc
+ * src/cipher-proto.h (gcry_pk_spec_t): Add fields ALGO and FLAGS.
+ * cipher/dsa.c (_gcry_pubkey_spec_dsa): Set these fields.
+ * cipher/ecc.c (_gcry_pubkey_spec_ecdsa): Ditto.
+ (_gcry_pubkey_spec_ecdh): Ditto.
+ * cipher/rsa.c (_gcry_pubkey_spec_rsa): Ditto.
+ * cipher/elgamal.c (_gcry_pubkey_spec_elg): Ditto
+ (_gcry_pubkey_spec_elg_e): New.
+ * cipher/pubkey.c: Change most code to replace the former module
+ system by a simpler system to gain information about the algorithms.
+ (disable_pubkey_algo): SImplified. Not anymore thread-safe, though.
+
+ pk: Merge extraspecs struct with standard specs struct.
+ + commit 89103ce00e862cc709e80fa41f2ee13d54093ec5
+ * src/gcrypt-module.h (gcry_pk_spec_t): Move this typedef and the
+ corresponding function typedefs to ...
+ * src/cipher-proto.h: here.
+ (pk_extra_spec_t): Remove typedef and merge fields into
+ gcry_pk_spec_t.
+ * cipher/rsa.c, cipher/dsa.c, cipher/elg.c, cipher/ecc.c: Ditto.
+ * cipher/pubkey.c: Change accordingly.
+ * src/cipher.h (_gcry_pubkey_extraspec_rsa): Remove.
+ (_gcry_pubkey_extraspec_dsa): Remove.
+ (_gcry_pubkey_extraspec_elg): Remove.
+ (_gcry_pubkey_extraspec_ecdsa): Remove.
+
+2013-09-18 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix encryption/decryption return type for GOST28147.
+ + commit 2ad7ea9cb388fd31e4b0852b68d77f599ef4adce
+ * cipher/gost.h (_gcry_gost_enc_one): Change return type to
+ 'unsigned int'.
+ * cipher/gost28147.c (max): New macro.
+ (gost_encrypt_block, gost_decrypt_block): Return burn stack depth.
+ (_gcry_gost_enc_one): Return burn stack depth from gost_encrypt_block.
+
+2013-09-18 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ doc: fix building of ps and pdf documentation.
+ + commit bd33fa21c9afc6c81e0da24016fc13001e9c7390
+ * doc/gcrypt.texi, doc/gpl.texi, doc/lgpl.texi: fix texinfo errors.
+
+ Add GOST R 34.11-2012 implementation (Stribog)
+ + commit c22064bdd773a807801e300aa9214b2fdcafcf20
+ * src/gcrypt.h.in (GCRY_MD_GOSTR3411_12_256)
+ (GCRY_MD_GOSTR3411_12_512): New.
+ * cipher/stribog.c: New.
+ * configure.ac (available_digests_64): Add stribog.
+ * src/cipher.h: Declare Stribog declarations.
+ * cipher/md.c: Register Stribog digest.
+ * tests/basic.c (check_digests) Add 4 testcases for Stribog from
+ standard.
+ * doc/gcrypt.texi: Document new constants.
+
+ Add basic implementation of GOST R 34.11-94 message digest.
+ + commit b0579baaa04fb91eabbbdc295bcabea04cf84056
+ * src/gcrypt.h.in (GCRY_MD_GOSTR3411_94): New.
+ * cipher/gostr3411-94.c: New.
+ * configure.ac (available_digests): Add gostr3411-94.
+ * src/cipher.h: Add gostr3411-94 definitions.
+ * cipher/md.c: Register GOST R 34.11-94.
+ * tests/basic.c (check_digests): Add 4 tests for GOST R 34.11-94
+ hash algo. Two are defined in the standard itself, two other are
+ more or less common tests - an empty string an exclamation mark.
+ * doc/gcrypt.texi: Add an entry describing GOST R 34.11-94 to the MD
+ algorithms table.
+
+ Separate common md block code.
+ + commit ecde77ad98690540abb21db08e5531297ed72bd0
+ * cipher/hash-common.c (_gcry_md_block_write): New function to handle
+ block md operations. The current implementation is limited to 64 byte
+ buffer and u32 block counter.
+
+ * cipher/md4.c, cipher/md5.c, cipher/rmd.h, cipher/rmd160.c
+ *cipher/sha1.c, cipher/sha256.c, cipher/tiger.c: Convert to use
+ _gcry_md_block_write.
+
+ Add limited implementation of GOST 28147-89 cipher.
+ + commit 56b5949f71f501744998f5ebc12488ebf6f1c0b5
+ * src/gcrypt.h.in (GCRY_CIPHER_GOST28147): New.
+ * cipher/gost.h, cipher/gost28147.c: New.
+ * configure.ac (available_ciphers): Add gost28147.
+ * src/cipher.h: Add gost28147 definitions.
+ * cipher/cipher.c: Register gost28147.
+ * tests/basic.c (check_ciphers): Enable simple test for gost28147.
+ * doc/gcrypt.texi: document GCRY_CIPHER_GOST28147.
+
+2013-09-18 Werner Koch <wk@gnupg.org>
+
+ ecc: Add Ed25519 key generation and prepare for optimizations.
+ + commit 63cd3474425cb5a7ec4d1a56be15b248ecda4680
+ * src/mpi.h (enum ecc_dialects): New.
+ * src/ec-context.h (mpi_ec_ctx_s): Add field DIALECT.
+ * cipher/ecc-common.h (elliptic_curve_t): Ditto.
+ * cipher/ecc-curves.c (ecc_domain_parms_t): Ditto.
+ (domain_parms): Add dialect values.
+ (_gcry_ecc_fill_in_curve): Set dialect.
+ (_gcry_ecc_get_curve): Ditto.
+ (_gcry_mpi_ec_new): Ditto.
+ (_gcry_ecc_get_param): Use ECC_DIALECT_STANDARD for now.
+ * cipher/ecc-misc.c (_gcry_ecc_curve_copy): Copy dialect.
+ (_gcry_ecc_dialect2str): New.
+ * mpi/ec.c (ec_p_init): Add arg DIALECT.
+ (_gcry_mpi_ec_p_internal_new): Ditto.
+ (_gcry_mpi_ec_p_new): Ditto.
+
+ * mpi/mpiutil.c (gcry_mpi_set_opaque): Set the secure flag.
+ (_gcry_mpi_set_opaque_copy): New.
+
+ * cipher/ecc-misc.c (_gcry_ecc_os2ec): Take care of an opaque MPI.
+ * cipher/ecc.c (eddsa_generate_key): New.
+ (generate_key): Rename to nist_generate_key and factor some code out
+ to ...
+ (ecc_generate_ext): here. Divert to eddsa_generate_key if desired.
+ (eddsa_decodepoint): Take care of an opaque MPI.
+ (ecc_check_secret_key): Ditto.
+ (ecc_sign): Ditto.
+ * cipher/pubkey.c (sexp_elements_extract_ecc): Store public and secret
+ key as opaque MPIs.
+ (gcry_pk_genkey): Add the curve_name also to the private key part of
+ the result.
+
+ * tests/benchmark.c (ecc_bench): Support Ed25519.
+ (main): Add option --debug.
+ * tests/curves.c (sample_key_2): Make sure that P and N are positive.
+ * tests/keygen.c (show): New.
+ (check_ecc_keys): Support Ed25519.
+
+2013-09-17 Werner Koch <wk@gnupg.org>
+
+ mpi: Support printing of negative numbers.
+ + commit 89fe2173649a72019d75e059e6c6938efd10421f
+ * mpi/mpicoder.c (twocompl, onecompl): New.
+ (gcry_mpi_print): Use it for STD and SSH.
+ (gcry_mpi_scan): Use it for STD and SSH. Always set NSCANNED.
+ (gcry_mpi_aprint): Clear the extra allocated byte.
+ * tests/t-convert.c (showhex, showmpi): New.
+ (mpi2bitstr_nlz): New.
+ (check_formats): New.
+ (main): Call new test.
+
+2013-09-16 Werner Koch <wk@gnupg.org>
+
+ Fix bug in _gcry_mpi_tdiv_q_2exp.
+ + commit a7a9cdcaaf3979baa18dad51e722882581349f45
+ * mpi/mpi-internal.h (MPN_COPY_INCR): Make it work.
+
+ ecc: Implement Curve Ed25519 signing and verification.
+ + commit bc5199a02abe428ad377443280b3eda60141a1d6
+ * cipher/ecc-curves.c (domain_parms): Add curve "Ed25519".
+ * cipher/ecc.c (reverse_buffer): New.
+ (eddsa_encodempi): New.
+ (eddsa_encodepoint): New.
+ (eddsa_decodepoint): New.
+ (sign_eddsa): Implement.
+ (verify_eddsa): Implement.
+ (ecc_sign): Init unused Q. Pass public key to sign_eddsa.
+ (ecc_verify): Init pk.Q if not used. Pass public key verbatim to
+ verify_eddsa.
+ * cipher/pubkey.c (sexp_elements_extract): Add arg OPAQUE. Change all
+ callers to pass 0.
+ (sexp_to_sig): Add arg OPAQUE and pass it to sexp_elements_extract.
+ (sexp_data_to_mpi): Allow for a zero length "value".
+ (gcry_pk_verify): Reorder parameter processing. Pass OPAQUE flag as
+ required.
+ * mpi/ec.c (ec_invm): Print a warning if the inverse does not exist.
+ (_gcry_mpi_ec_get_affine): Implement for our Twisted Edwards curve
+ model.
+ (dup_point_twistededwards): Implement.
+ (add_points_twistededwards): Implement.
+ (_gcry_mpi_ec_mul_point): Support Twisted Edwards.
+
+ * mpi/mpicoder.c (do_get_buffer): Add arg FILL_LE.
+ (_gcry_mpi_get_buffer): Ditto. Change all callers.
+ (_gcry_mpi_get_secure_buffer): Ditto.
+
+ * src/sexp.c (_gcry_sexp_nth_opaque_mpi): New.
+
+ * tests/t-ed25519.c: New.
+ * tests/t-ed25519.inp: New.
+ * tests/t-mpi-point.c (basic_ec_math_simplified): Print some output
+ only in debug mode.
+ (twistededwards_math): New test.
+ (main): Call new test.
+
+ mpi: Add internal convenience function.
+ + commit 44a2c34e90ed7de149952398787906d8823b636b
+ * mpi/mpiutil.c (_gcry_mpi_get_opaque_copy): New.
+
+ mpi: Add debug function to print a point.
+ + commit 8ebc94d11a1eb93f2365c93f555e958700fdfbd4
+ * mpi/ec.c (_gcry_mpi_point_log): New.
+ * src/mpi.h (log_printpnt): new macro.
+
+ tests: Factor time measurement code out.
+ + commit 58eaf0c4332ac2f645ede28c4d18337389dfa753
+ * tests/benchmark.c (started_at, stopped_at, start_timer, stop_timer)
+ (elapsed time): Factor out to ..
+ * tests/stopwatch.h: new file.
+
+2013-09-12 Werner Koch <wk@gnupg.org>
+
+ Fix _gcry_log_printmpi to print 00 instead of a sole sign.
+ + commit 1c76349c69c70a62b516a4f837c6287def640807
+ * src/misc.c: Special case an mpi length of 0.
+
+2013-09-11 Werner Koch <wk@gnupg.org>
+
+ Streamline the use of the internal mpi and hex debug functions.
+ + commit e35ed615acc624a8b6c07576ea0650aac2bdb0db
+ * mpi/mpicoder.c (gcry_mpi_dump): Remove.
+ (_gcry_log_mpidump): Remove.
+ * src/misc.c (_gcry_log_printhex): Factor all code out to ...
+ (do_printhex): new. Add line wrapping a and compact printing.
+ (_gcry_log_printmpi): New.
+ * src/mpi.h (log_mpidump): Remove macro.
+ * src/g10lib.h (log_mpidump): Add compatibility macro.
+ (log_printmpi): New macro
+ * src/visibility.c (gcry_mpi_dump): Call _gcry_log_printmpi.
+ * cipher/primegen.c (prime_generate_internal): Replace gcry_mpi_dump
+ by log_printmpi.
+ (gcry_prime_group_generator): Ditto.
+ * cipher/pubkey.c: Remove extra colons from log_mpidump call.
+ * cipher/rsa.c (stronger_key_check): Use log_printmpi.
+
+2013-09-10 Werner Koch <wk@gnupg.org>
+
+ md: Add function gcry_md_hash_buffers.
+ + commit f3bca0c77c4979504f95fdbc618f7458e61e3e45
+ * src/gcrypt.h.in (gcry_buffer_t): new.
+ (gcry_md_hash_buffers): New.
+ * src/visibility.c, src/visibility.h: Add wrapper for new function.
+ * src/libgcrypt.def, src/libgcrypt.vers: Export new function.
+ * cipher/md.c (gcry_md_hash_buffers): New.
+ * cipher/sha1.c (_gcry_sha1_hash_buffers): New.
+ * tests/basic.c (check_one_md_multi): New.
+ (check_digests): Run that test.
+ * tests/hmac.c (check_hmac_multi): New.
+ (main): Run that test.
+
+ md: Fix Whirlpool flaw.
+ + commit 0a28b2d2c9181a536fc894e24626714832619923
+ * cipher/whirlpool.c (whirlpool_add): Remove shortcut return so that
+ byte counter is always properly updated.
+
+2013-09-07 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix static build on AMD64.
+ + commit 90fdf25f0dcc5feac7195ede55bd15948a11363e
+ * cipher/rijndael-amd64.S: Correct 'RIP' macro for non-PIC build.
+
+ scrypt: fix for big-endian systems.
+ + commit 38a038a135d82231eff9d84f1ae3c4a25c6a5e75
+ * cipher/scrypt.c (_salsa20_core): Fix endianess issues.
+
+2013-09-07 Werner Koch <wk@gnupg.org>
+
+ Use gcc "unused" attribute only with gcc >= 3.5.
+ + commit f7135e299e659d78906aac3dfdf30f380b5cf9c6
+ * src/g10lib.h (GCC_ATTR_UNUSED): Fix gcc version detection.
+
+2013-09-07 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Add support for Salsa20/12 - 12 round version of Salsa20.
+ + commit ae6f6c47d2e0c536f3eab0823b5f23d26956cda2
+ * src/gcrypt.h.in (GCRY_CIPHER_SALSA20R12): New.
+ * src/salsa20.c (salsa20_core, salsa20_do_encrypt_stream): Add support
+ for reduced round versions.
+ (salsa20r12_encrypt_stream, _gcry_cipher_spec_salsa20r12): Implement
+ Salsa20/12 - a 12 round version of Salsa20 selected by eStream.
+ * src/cipher.h: Declsare Salsa20/12 definition.
+ * cipher/cipher.c: Register Salsa20/12
+ * tests/basic.c: (check_stream_cipher, check_stream_cipher_large_block):
+ Populate Salsa20/12 tests with test vectors from ecrypt
+ (check_ciphers): Add simple test for Salsa20/12
+
+2013-09-07 Werner Koch <wk@gnupg.org>
+
+ Add configure option --disable-amd64-as-feature-detection.
+ + commit 49d5b9dcd622cdc87fb02a211bd51e3d46345bf2
+ * configure.ac: Implement new disable flag.
+
+ mpi: Improve support for non-Weierstrass support.
+ + commit 4d8c8c7aa88cddb1624301957e6245405f46d027
+ * mpi/ec.c (ec_p_init): Add args MODEL and P. Change all callers.
+ (_gcry_mpi_ec_p_internal_new): Ditto.
+ (_gcry_mpi_ec_p_new): Ditto.
+ * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Return
+ GPG_ERR_UNKNOWN_CURVE instead of invalid value. Init curve model.
+ * cipher/ecc.c (ecc_verify, ecc_encrypt_raw): Ditto.
+ * cipher/pubkey.c (sexp_data_to_mpi): Fix EDDSA flag error checking.
+
+ mpi: Add gcry_mpi_ec_curve_point.
+ + commit ddfefe429660cc5d798f3517208936449247ae5c
+ * mpi/ec.c (_gcry_mpi_ec_curve_point): New.
+ (ec_powm): Return the absolute value.
+ * src/visibility.c, src/visibility.c: Add wrappers.
+ * src/libgcrypt.def, src/libgcrypt.vers: Export them.
+
+ mpi: Add functions to manipulate the sign.
+ + commit 1bd2c67aa55b40589654d3fa5dea05cf1ed7dc5f
+ * src/gcrypt.h.in (gcry_mpi_is_neg): New.
+ (gcry_mpi_neg, gcry_mpi_abs): New.
+ * mpi/mpiutil.c (_gcry_mpi_is_neg): New.
+ (_gcry_mpi_neg, _gcry_mpi_abs): New.
+ * src/visibility.c, src/visibility.h: Add wrappers.
+ * src/libgcrypt.def, src/libgcrypt.vers: Export them.
+ * src/mpi.h (mpi_is_neg): New. Rename old macro to mpi_has_sign.
+ * mpi/mpi-mod.c (_gcry_mpi_mod_barrett): Use mpi_has_sign.
+ * mpi/mpi-mpow.c (calc_barrett): Ditto.
+ * cipher/primegen.c (_gcry_derive_x931_prime): Ditto
+ * cipher/rsa.c (secret): Ditto.
+
+2013-09-06 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Tune armv6 mpi assembly.
+ + commit 4e4440153258e2f0dfdcaa8443820af06984ecb1
+ * mpi/armv6/mpih-mul1.S: Tune assembly for Cortex-A8.
+ * mpi/armv6/mpih-mul2.S: Ditto.
+ * mpi/armv6/mpih-mul3.S: Ditto.
+
+2013-09-05 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Change _gcry_burn_stack take burn depth as unsigned integer.
+ + commit e0ae31fcce3bd57b24751ff3c82cba820e493c3a
+ * src/misc.c (_gcry_burn_stack): Change to handle 'unsigned int' bytes.
+
+ mpicalc: fix building on linux and win32.
+ + commit 50ec983666f0ca9d50c84aa1afad0d7bd5810779
+ * src/Makefile.am (mpicalc): Adjust CFLAGS and LDADD.
+
+2013-09-04 Werner Koch <wk@gnupg.org>
+
+ Change mpicalc to use Libgcrypt and install it.
+ + commit 1d23040b659661b4086c079cb9fd5f37189a7020
+ * src/mpicalc.c: Make use of gcry_ functions.
+ (MPICALC_VERSION): New. Set to 2.0.
+ (strusage): Remove.
+ (scan_mpi): New. Replaces mpi_fromstr.
+ (print_mpi): New. Replaces mpi_print.
+ (my_getc): New.
+ (print_help): New.
+ (main): Use simple option parser and print version info.
+ * src/Makefile.am (bin_PROGRAMS): Add mpicalc.
+ (mpicalc_SOURCES, mpicalc_CFLAGS, mpicalc_LDADD): New.
+
+ Add mpicalc.c to help with testing.
+ + commit a70c46e29c480fa0f56ab4814666a5b115f84fd7
+ * src/mpicalc.c: Take from GnuPG 1.4
+
+ Prepare support for EdDSA.
+ + commit c47d4001033f68212d2847b3074a0bdda990342e
+ * src/cipher.h (PUBKEY_FLAG_EDDSA): New.
+ * cipher/pubkey.c (pubkey_verify): Repalce args CMP and OPAQUEV by
+ CTX. Pass flags and hash algo to the verify function. Change all
+ verify functions to accept these args.
+ (sexp_data_to_mpi): Implement new flag "eddsa".
+ (gcry_pk_verify): Pass CTX instead of the compare function to
+ pubkey_verify.
+ * cipher/ecc.c (sign): Rename to sign_ecdsa. Change all callers.
+ (verify): Rename to verify_ecdsa. Change all callers.
+ (sign_eddsa, verify_eddsa): New stub functions.
+ (ecc_sign): Divert to sign_ecdsa or sign_eddsa.
+ (ecc_verify): Divert to verify_ecdsa or verify_eddsa.
+
+ Prepare support for non-Weierstrass EC equations.
+ + commit c26be7a337d0bf98193bc58e043209e46d0769bb
+ * src/mpi.h (gcry_mpi_ec_models): New.
+ * src/ec-context.h (mpi_ec_ctx_s): Add MODEL.
+ * cipher/ecc-common.h (elliptic_curve_t): Ditto.
+ * cipher/ecc-curves.c (ecc_domain_parms_t): Ditto.
+ (domain_parms): Mark als as Weierstrass.
+ (_gcry_ecc_fill_in_curve): Check model.
+ (_gcry_ecc_get_curve): Set model to Weierstrass.
+ * cipher/ecc-misc.c (_gcry_ecc_model2str): New.
+ * cipher/ecc.c (generate_key, ecc_generate_ext): Print model in the
+ debug output.
+
+ * mpi/ec.c (_gcry_mpi_ec_dup_point): Switch depending on model.
+ Factor code out to ...
+ (dup_point_weierstrass): new.
+ (dup_point_montgomery, dup_point_twistededwards): New stub functions.
+ (_gcry_mpi_ec_add_points): Switch depending on model. Factor code out
+ to ...
+ (add_points_weierstrass): new.
+ (add_points_montgomery, add_points_twistededwards): New stub
+ functions.
+
+ * tests/Makefile.am (TESTS): Reorder tests.
+
+ mpi: Suppress newer gcc warnings.
+ + commit 8698530b2f9ef95542f1dd550961de7af86cc256
+ * src/g10lib.h (GCC_ATTR_UNUSED): Define for gcc >= 3.5.
+ * mpi/mpih-div.c (_gcry_mpih_mod_1, _gcry_mpih_divmod_1): Mark dummy
+ as unused.
+ * mpi/mpi-internal.h (UDIV_QRNND_PREINV): Mark _ql as unused.
+
+ Do not check with cpp for typedefed constants.
+ + commit b28b1f732e1b4f9c62a9de87c22c6bb0d3f8fdb8
+ * src/gcrypt-int.h: Include error code replacements depeding on the
+ version of libgpg-error.
+
+2013-09-04 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Make _gcry_burn_stack use variable length array.
+ + commit 4b0edf53440239d3bcc95941980c062a0801a149
+ * configure.ac (HAVE_VLA): Add check.
+ * src/misc.c (_gcry_burn_stack) [HAVE_VLA]: Add VLA code.
+
+ Move stack burning from block ciphers to cipher modes.
+ + commit a3aaa6ad03388ea3eaa24304b604cb864633332f
+ * src/gcrypt-module.h (gcry_cipher_encrypt_t)
+ (gcry_cipher_decrypt_t): Return 'unsigned int'.
+ * cipher/cipher.c (dummy_encrypt_block, dummy_decrypt_block): Return
+ zero.
+ (do_ecb_encrypt, do_ecb_decrypt): Get largest stack burn depth from
+ block cipher crypt function and burn stack at end.
+ * cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt)
+ (_gcry_cipher_aeswrap_decrypt): Ditto.
+ * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
+ (_gcry_cipher_cbc_decrypt): Ditto.
+ * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
+ (_gcry_cipher_cfb_decrypt): Ditto.
+ * cipher/cipher-ctr.c (_gcry_cipher_cbc_encrypt): Ditto.
+ * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt)
+ (_gcry_cipher_ofb_decrypt): Ditto.
+ * cipher/blowfish.c (encrypt_block, decrypt_block): Return burn stack
+ depth.
+ * cipher/camellia-glue.c (camellia_encrypt, camellia_decrypt): Ditto.
+ * cipher/cast5.c (encrypt_block, decrypt_block): Ditto.
+ * cipher/des.c (do_tripledes_encrypt, do_tripledes_decrypt)
+ (do_des_encrypt, do_des_decrypt): Ditto.
+ * cipher/idea.c (idea_encrypt, idea_decrypt): Ditto.
+ * cipher/rijndael.c (rijndael_encrypt, rijndael_decrypt): Ditto.
+ * cipher/seed.c (seed_encrypt, seed_decrypt): Ditto.
+ * cipher/serpent.c (serpent_encrypt, serpent_decrypt): Ditto.
+ * cipher/twofish.c (twofish_encrypt, twofish_decrypt): Ditto.
+ * cipher/rfc2268.c (encrypt_block, decrypt_block): New.
+ (_gcry_cipher_spec_rfc2268_40): Use encrypt_block and decrypt_block.
+
+2013-09-01 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ camellia-aesni-avx2-amd64: Move register clearing to assembly functions.
+ + commit f3515240de9513ead975985c9f8ab714022cac8e
+ * cipher/camellia-aesni-avx2-amd64.S
+ (_gcry_camellia_aesni_avx2_ctr_enc): Add 'vzeroall'.
+ (_gcry_camellia_aesni_avx2_cbc_dec)
+ (_gcry_camellia_aesni_avx2_cfb_dec): Add 'vzeroupper' at head and
+ 'vzeroall' at tail.
+ * cipher/camellia-glue.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+ (_gcry_serpent_avx2_cfb_dec) [USE_AESNI_AVX2]: Remove register
+ clearing.
+
+ camellia-aesni-avx-amd64: Move register clearing to assembly functions.
+ + commit 8b735cb563dff7aafbf8a970972522b5621e665c
+ * cipher/camellia-aesni-avx-amd64.S (_gcry_camellia_aesni_avx_ctr_enc)
+ (_gcry_camellia_aesni_avx_cbc_dec)
+ (_gcry_camellia_aesni_avx_cfb_dec): Add 'vzeroupper' at head and
+ 'vzeroall' at tail.
+ * cipher/camellia-glue.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+ (_gcry_serpent_avx2_cfb_dec) [USE_AESNI_AVX]: Remove register clearing.
+
+ serpent-avx2-amd64: Move register clearing to assembly.
+ + commit d12828cd821a4b4428eae19de5aee02cf536e536
+ * cipher/serpent-avx2-amd64.S (_gcry_serpent_avx2_ctr_enc)
+ (_gcry_serpent_avx2_cbc_dec, _gcry_serpent_avx2_cfb_dec): Change last
+ 'vzeroupper' to 'vzeroall'.
+ * cipher/serpent.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+ (_gcry_serpent_avx2_cfb_dec) [USE_AVX2]: Remove register clearing with
+ 'vzeroall'.
+
+ Fix building for x32 target.
+ + commit fd6721c235a5bdcb332c8eb708fbd4f96e52e824
+ * mpi/amd64/mpi-asm-defs.h: New file.
+ * random/rndhw.c (poll_padlock) [__x86_64__]: Also check if __LP64__ is
+ defined.
+ [USE_DRNG, __x86_64__]: Also check if __LP64__ is defined.
+
+2013-08-31 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ sha512: add ARM/NEON assembly version of transform function.
+ + commit 99d15543b8d94a8f1ef66c6ccb862b0ce82c514d
+ * cipher/Makefile.am: Add 'sha512-armv7-neon.S'.
+ * cipher/sha512-armv7-neon.S: New file.
+ * cipher/sha512.c (USE_ARM_NEON_ASM): New macro.
+ (SHA512_CONTEXT) [USE_ARM_NEON_ASM]: Add 'use_neon'.
+ (sha512_init, sha384_init) [USE_ARM_NEON_ASM]: Enable 'use_neon' if
+ CPU support NEON instructions.
+ (k): Round constant array moved outside of 'transform' function.
+ (__transform): Renamed from 'tranform' function.
+ [USE_ARM_NEON_ASM] (_gcry_sha512_transform_armv7_neon): New prototype.
+ (transform): New wrapper function for different transform versions.
+ (sha512_write, sha512_final): Burn stack by the amount returned by
+ transform function.
+ * configure.ac (sha512) [neonsupport]: Add 'sha512-armv7-neon.lo'.
+
+ sha512: reduce stack use in transform function by 512 bytes.
+ + commit 03da7f8ba3ec24d4639a2bcebbc0d9d831734c08
+ * cipher/sha512.c (transform): Change 'u64 w[80]' to 'u64 w[16]' and
+ inline input expansion to first 64 rounds.
+ (sha512_write, sha512_final): Reduce burn_stack depth by 512 bytes.
+
+ Add ARM HW feature detection module and add NEON detection.
+ + commit 9c95be105f518d18407115c2c06893857c24b116
+ * configure.ac: Add option --disable-neon-support.
+ (HAVE_GCC_INLINE_ASM_NEON): New.
+ (ENABLE_NEON_SUPPORT): New.
+ [arm]: Add 'hwf-arm.lo' as HW feature module.
+ * src/Makefile.am: Add 'hwf-arm.c'.
+ * src/g10lib.h (HWF_ARM_NEON): New macro.
+ * src/global.c (hwflist): Add HWF_ARM_NEON entry.
+ * src/hwf-arm.c: New file.
+ * src/hwf-common.h (_gcry_hwf_detect_arm): New prototype.
+ * src/hwfeatures.c (_gcry_detect_hw_features) [HAVE_CPU_ARCH_ARM]: Add
+ call to _gcry_hwf_detect_arm.
+
+ Correct mpi_cpu_arch for ARMv6.
+ + commit 7b0ebe69fe35f2ee13e1e1beb2766a1eaadb7f0c
+ * mpi/config.links [armv6]: Set mpi_cpu_arch to "arm", instead of
+ "armv6".
+
+2013-08-30 Werner Koch <wk@gnupg.org>
+
+ mpi: Make gcry_mpi_print work with negative zeroes.
+ + commit e9b711e6ddb480a71d2996465074e436c752c005
+ * mpi/mpicoder.c (gcry_mpi_print): Take care of negative zero.
+ (gcry_mpi_aprint): Allocate at least 1 byte.
+ * tests/t-convert.c: New.
+ * tests/Makefile.am (TESTS): Add t-convert.
+
+ Refactor the ECC code into 3 files.
+ + commit 800d4e01376d52a94a157b53978c7c3f957fc476
+ * cipher/ecc-common.h, cipher/ecc-curves.c, cipher/ecc-misc.c: New.
+ * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add new files.
+ * configure.ac (GCRYPT_PUBKEY_CIPHERS): Add new .c files.
+ * cipher/ecc.c (curve_aliases, ecc_domain_parms_t, domain_parms)
+ (scanval): Move to ecc-curves.c.
+ (fill_in_curve): Move to ecc-curve.c as _gcry_ecc_fill_in_curve.
+ (ecc_get_curve): Move to ecc-curve.c as _gcry_ecc_get_curve.
+ (_gcry_mpi_ec_ec2os): Move to ecc-misc.c.
+ (ec2os): Move to ecc-misc.c as _gcry_ecc_ec2os.
+ (os2ec): Move to ecc-misc.c as _gcry_ecc_os2ec.
+ (point_set): Move as inline function to ecc-common.h.
+ (_gcry_ecc_curve_free): Move to ecc-misc.c as _gcry_ecc_curve_free.
+ (_gcry_ecc_curve_copy): Move to ecc-misc.c as _gcry_ecc_curve_copy.
+ (mpi_from_keyparam, point_from_keyparam): Move to ecc-curves.c.
+ (_gcry_mpi_ec_new): Move to ecc-curves.c.
+ (ecc_get_param): Move to ecc-curves.c as _gcry_ecc_get_param.
+ (ecc_get_param_sexp): Move to ecc-curves.c as _gcry_ecc_get_param_sexp.
+
+2013-08-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ serpent-sse2-amd64: Move register clearing to assembly functions.
+ + commit 040aa7688296e93659cb32ca31e9a001a6ab1edd
+ cipher/serpent-sse2-amd64.S (_gcry_serpent_sse2_ctr_enc)
+ (_gcry_serpent_sse2_cbc_dec, _gcry_serpent_sse2_cfb_dec): Clear used
+ XMM registers.
+ cipher/serpent.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+ ( _gcry_serpent_cfb_dec) [USE_SSE2]: Remove XMM register clearing from
+ bulk functions.
+
+ twofish-amd64: do not make __twofish_dec_blk3 global.
+ + commit 82db04a6a0058cf870485459abe7c1659b138ec5
+ * cipher/twofish-amd64.S (__twofish_dec_blk3): Do not export symbol as
+ global.
+ (__twofish_dec_blk3): Mark symbol as function.
+
+2013-08-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ mpi: add ARMv6 assembly.
+ + commit da327aef3fe24fdf98fffbc8aea69de42ed12456
+ * mpi/armv6/mpi-asm-defs.h: New.
+ * mpi/armv6/mpih-add1.S: New.
+ * mpi/armv6/mpih-mul1.S: New.
+ * mpi/armv6/mpih-mul2.S: New.
+ * mpi/armv6/mpih-mul3.S: New.
+ * mpi/armv6/mpih-sub1.S: New.
+ * mpi/config.links [arm]: Enable ARMv6 assembly.
+
+ Move ARMv6 detection to configure.ac.
+ + commit 151f1e518be2d16bed748ba832384b0472ddcf9b
+ * cipher/blowfish-armv6.S: Replace __ARM_ARCH >= 6 checks with
+ HAVE_ARM_ARCH_V6.
+ * cipher/blowfish.c: Ditto.
+ * cipher/camellia-armv6.S: Ditto.
+ * cipher/camellia.h: Ditto.
+ * cipher/cast5-armv6.S: Ditto.
+ * cipher/cast5.c: Ditto.
+ * cipher/rijndael-armv6.S: Ditto.
+ * cipher/rijndael.c: Ditto.
+ * configure.ac: Add HAVE_ARM_ARCH_V6 check.
+
+2013-08-19 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add optimized wipememory for ARM.
+ + commit c030e33533fb819afe195eff5f89ec39863b1fbc
+ src/g10lib.h [__arm__] (fast_wipememory2_unaligned_head)
+ (fast_wipememory2): New macros.
+
+ cipher: bufhelp: allow unaligned memory accesses on ARM.
+ + commit 796dda37b957b20dba391343937c6325a8c8b288
+ * cipher/bufhelp.h [__arm__ && __ARM_FEATURE_UNALIGNED]: Enable
+ BUFHELP_FAST_UNALIGNED_ACCESS.
+
+2013-08-17 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Remove burn_stack optimization.
+ + commit 79895b9459b9bf8c60cb7abf09d5bf16ed0cf6e3
+ * src/misc.c (_gcry_burn_stack): Remove SIZEOF_UNSIGNED_LONG == 4 or 8
+ optimization.
+
+2013-08-16 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ camellia: add ARMv6 assembly implementation.
+ + commit cafadc1e4fb97581262b0081ba251e05613d4394
+ * cipher/Makefile.am: Add 'camellia-armv6.S'.
+ * cipher/camellia-armv6.S: New file.
+ * cipher/camellia-glue.c [USE_ARMV6_ASM]
+ (_gcry_camellia_armv6_encrypt_block)
+ (_gcry_camellia_armv6_decrypt_block): New prototypes.
+ [USE_ARMV6_ASM] (Camellia_EncryptBlock, Camellia_DecryptBlock)
+ (camellia_encrypt, camellia_decrypt): New functions.
+ * cipher/camellia.c [!USE_ARMV6_ASM]: Compile encryption and decryption
+ routines if USE_ARMV6_ASM macro is _not_ defined.
+ * cipher/camellia.h (USE_ARMV6_ASM): New macro.
+ [!USE_ARMV6_ASM] (Camellia_EncryptBlock, Camellia_DecryptBlock): If
+ USE_ARMV6_ASM is defined, disable these function prototypes.
+ (camellia) [arm]: Add 'camellia-armv6.lo'.
+
+ blowfish: add ARMv6 assembly implementation.
+ + commit 31e4b1a96a07e9a3698fcb7be0643a136ebb8e5c
+ * cipher/Makefile.am: Add 'blowfish-armv6.S'.
+ * cipher/blowfish-armv6.S: New file.
+ * cipher/blowfish.c (USE_ARMV6_ASM): New macro.
+ [USE_ARMV6_ASM] (_gcry_blowfish_armv6_do_encrypt)
+ (_gcry_blowfish_armv6_encrypt_block)
+ (_gcry_blowfish_armv6_decrypt_block, _gcry_blowfish_armv6_ctr_enc)
+ (_gcry_blowfish_armv6_cbc_dec, _gcry_blowfish_armv6_cfb_dec): New
+ prototypes.
+ [USE_ARMV6_ASM] (do_encrypt, do_encrypt_block, do_decrypt_block)
+ (encrypt_block, decrypt_block): New functions.
+ (_gcry_blowfish_ctr_enc) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+ (_gcry_blowfish_cbc_dec) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+ (_gcry_blowfish_cfb_dec) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+ * configure.ac (blowfish) [arm]: Add 'blowfish-armv6.lo'.
+
+ cast5: add ARMv6 assembly implementation.
+ + commit 8d1faf56714598301580ce370e0bfa6d65e73644
+ * cipher/Makefile.am: Add 'cast5-armv6.S'.
+ * cipher/cast5-armv6.S: New file.
+ * cipher/cast5.c (USE_ARMV6_ASM): New macro.
+ (CAST5_context) [USE_ARMV6_ASM]: New members 'Kr_arm_enc' and
+ 'Kr_arm_dec'.
+ [USE_ARMV6_ASM] (_gcry_cast5_armv6_encrypt_block)
+ (_gcry_cast5_armv6_decrypt_block, _gcry_cast5_armv6_ctr_enc)
+ (_gcry_cast5_armv6_cbc_dec, _gcry_cast5_armv6_cfb_dec): New prototypes.
+ [USE_ARMV6_ASM] (do_encrypt_block, do_decrypt_block, encrypt_block)
+ (decrypt_block): New functions.
+ (_gcry_cast5_ctr_enc) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+ (_gcry_cast5_cbc_dec) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+ (_gcry_cast5_cfb_dec) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+ (do_cast_setkey) [USE_ARMV6_ASM]: Initialize 'Kr_arm_enc' and
+ 'Kr_arm_dec'.
+ * configure.ac (cast5) [arm]: Add 'cast5-armv6.lo'.
+
+2013-08-14 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rijndael: add ARMv6 assembly implementation.
+ + commit f365961422f1c8b3d89b8bcd9c99828f38c1f158
+ * cipher/Makefile.am: Add 'rijndael-armv6.S'.
+ * cipher/rijndael-armv6.S: New file.
+ * cipher/rijndael.c (USE_ARMV6_ASM): New macro.
+ [USE_ARMV6_ASM] (_gcry_aes_armv6_encrypt_block)
+ (_gcry_aes_armv6_decrypt_block): New prototypes.
+ (do_encrypt_aligned) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+ (do_encrypt): Disable input/output alignment when USE_ARMV6_ASM.
+ (do_decrypt_aligned) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+ (do_decrypt): Disable input/output alignment when USE_ARMV6_ASM.
+ * configure.ac (HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS): New check for
+ gcc/as compatibility with ARM assembly implementations.
+ (aes) [arm]: Add 'rijndael-armv6.lo'.
+
+2013-08-09 NIIBE Yutaka <gniibe@fsij.org>
+
+ cipher: fix memory leak.
+ + commit 2b5bbe264fcd61e5e458e5f71a6507ba0271c729
+ * cipher/pubkey.c (gcry_pk_sign): Handle the specific case of ECC,
+ where there is NULL whichi is not the sentinel.
+
+2013-08-08 Werner Koch <wk@gnupg.org>
+
+ mpi: Clear immutable flag on the result of gcry_mpi_set.
+ + commit 426cbc9feca0c8f46208fb3670adab95f9e46087
+ * mpi/mpiutil.c (gcry_mpi_set): Reset immutable and const flags.
+ * tests/mpitests.c (test_const_and_immutable): Add a test for this.
+
+2013-08-07 NIIBE Yutaka <gniibe@fsij.org>
+
+ tests: fix memory leaks.
+ + commit cc082642c1b0f2a3e9ca78e1ffd3f64417c204bd
+ * tests/benchmark.c (dsa_bench): Release SIG.
+
+ * tests/mpitests.c (test_powm): Release BASE, EXP, MOD, and RES.
+
+ * tests/prime.c (check_primes): Release PRIME.
+
+ * tests/tsexp.c (basic): Use intermediate variable M for constant.
+ Release S1, S2 and A.
+
+2013-08-07 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix building on W32 (cannot export symbol 'gcry_sexp_get_buffer')
+ + commit 065d446478bf68553339fc77a89b8369bd110a18
+ * src/libgcrypt.def: Change 'gcry_sexp_get_buffer' to
+ 'gcry_sexp_nth_buffer'.
+
+2013-08-06 NIIBE Yutaka <gniibe@fsij.org>
+
+ cipher: fix another memory leak.
+ + commit 9a421813123a2f5db0a91eaee4a45138efc9ad34
+ * cipher/ecc.c (ecc_get_curve): Free TMP.
+
+ tests: fix memory leaks.
+ + commit 87eddc31ccba6decbddd1761dd42a208666cd311
+ * tests/pubkey.c (check_keys_crypt): Release L, X0, and X1.
+ (check_keys): Release X.
+
+ cipher: fix memory leaks.
+ + commit ae6ffd9af38cbcac57c220960f683aab91db85cb
+ * cipher/elgamal.c (elg_generate_ext): Free XVALUE.
+
+ * cipher/pubkey.c (sexp_elements_extract): Don't use IDX for loop.
+ Call mpi_free.
+ (sexp_elements_extract_ecc): Call mpi_free.
+
+2013-08-05 Werner Koch <wk@gnupg.org>
+
+ mpi: Improve gcry_mpi_invm to detect bad input.
+ + commit d8e99a04dba6a606e879464cd11deee760d1e000
+ * mpi/mpi-inv.c (gcry_mpi_invm): Return 0 for bad input.
+
+2013-07-31 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Correct checks for ecc secret key.
+ + commit 10dfa41b43a906031bc674ea41cd3073701011f3
+ * cipher/ecc.c (check_secret_key): replace wrong comparison of Q and
+ sk->Q points with correct one.
+
+2013-07-29 Werner Koch <wk@gnupg.org>
+
+ sexp: Allow white space anywhere in a hex format.
+ + commit 43320961a8751ee28dc95cdb0ae01ea8a7ff7f91
+ * src/sexp.c (hextobyte): Remove.
+ (hextonibble): New.
+ (vsexp_sscan): Skip whtespace between hex nibbles.
+
+ Implement deterministic ECDSA as specified by rfc-6979.
+ + commit 6e0a9786637d649b48aae0e611a12e12beef9b3b
+ * cipher/ecc.c (sign): Add args FLAGS and HASHALGO. Convert an opaque
+ MPI as INPUT. Implement rfc-6979.
+ (ecc_sign): Remove the opaque MPI code and pass FLAGS to sign.
+ (verify): Do not allocate and compute Y; it is not used.
+ (ecc_verify): Truncate the hash value if needed.
+ * tests/dsa-rfc6979.c (check_dsa_rfc6979): Add ECDSA test cases.
+
+2013-07-26 Werner Koch <wk@gnupg.org>
+
+ Implement deterministic DSA as specified by rfc-6979.
+ + commit 1cfa79aabc5d0fd8d124901054475e90ab7d9cde
+ * cipher/dsa.c (dsa_sign): Move opaque mpi extraction to sign.
+ (sign): Add args FLAGS and HASHALGO. Implement deterministic DSA.
+ Add code path for R==0 to comply with the standard.
+ (dsa_verify): Left fill opaque mpi based hash values.
+ * cipher/dsa-common.c (int2octets, bits2octets): New.
+ (_gcry_dsa_gen_rfc6979_k): New.
+ * tests/dsa-rfc6979.c: New.
+ * tests/Makefile.am (TESTS): Add dsa-rfc6979.
+
+ Allow the use of a private-key s-expression with gcry_pk_verify.
+ + commit b72d312ad11887fc416aa821786f6bdb663c0f4a
+ * cipher/pubkey.c (sexp_to_key): Fallback to private key.
+
+2013-07-25 Werner Koch <wk@gnupg.org>
+
+ Mitigate a flush+reload cache attack on RSA secret exponents.
+ + commit 287bf0e543f244d784cf8b58340bf0ab3c6aba97
+ * mpi/mpi-pow.c (gcry_mpi_powm): Always perfrom the mpi_mul for
+ exponents in secure memory.
+
+2013-07-19 Werner Koch <wk@gnupg.org>
+
+ pk: Allow the use of a hash element for DSA sign and verify.
+ + commit 37d0a1ebdc2dc74df4fb6bf0621045018122a68f
+ * cipher/pubkey.c (pubkey_sign): Add arg ctx and pass it to the sign
+ module.
+ (gcry_pk_sign): Pass CTX to pubkey_sign.
+ (sexp_data_to_mpi): Add flag rfc6979 and code to alls hash with *DSA
+ * cipher/rsa.c (rsa_sign, rsa_verify): Return an error if an opaque
+ MPI is given for DATA/HASH.
+ * cipher/elgamal.c (elg_sign, elg_verify): Ditto.
+ * cipher/dsa.c (dsa_sign, dsa_verify): Convert a given opaque MPI.
+ * cipher/ecc.c (ecc_sign, ecc_verify): Ditto.
+ * tests/basic.c (check_pubkey_sign_ecdsa): Add a test for using a hash
+ element with DSA.
+
+ sexp: Add function gcry_sexp_nth_buffer.
+ + commit 2d3e8d4d9562d666420aadd9ffa8ac0456a1cd91
+ * src/sexp.c (gcry_sexp_nth_buffer): New.
+ * src/visibility.c, src/visibility.h: Add function wrapper.
+ * src/libgcrypt.vers, src/libgcrypt.def: Add to API.
+ * src/gcrypt.h.in: Add prototype.
+
+2013-07-18 Werner Koch <wk@gnupg.org>
+
+ Add support for Salsa20.
+ + commit c4885092088431e7928e4459fda20cc0e8ceb201
+ * src/gcrypt.h.in (GCRY_CIPHER_SALSA20): New.
+ * cipher/salsa20.c: New.
+ * configure.ac (available_ciphers): Add Salsa20.
+ * cipher/cipher.c: Register Salsa20.
+ (cipher_setiv): Allow to divert an IV to a cipher module.
+ * src/cipher-proto.h (cipher_setiv_func_t): New.
+ (cipher_extra_spec): Add field setiv.
+ * src/cipher.h: Declare Salsa20 definitions.
+ * tests/basic.c (check_stream_cipher): New.
+ (check_stream_cipher_large_block): New.
+ (check_cipher_modes): Run new test functions.
+ (check_ciphers): Add simple test for Salsa20.
+
+2013-07-17 Werner Koch <wk@gnupg.org>
+
+ Allow gcry_mpi_dump to print opaque MPIs.
+ + commit 364d019e3ffedfcb434576702f73e767cb9389ef
+ * mpi/mpicoder.c (gcry_mpi_dump): Detect abd print opaque MPIs.
+ * tests/mpitests.c (test_opaque): New.
+ (main): Call new test.
+
+ cipher: Prepare to pass extra info to the sign functions.
+ + commit 5940e66cbefea3de5924f494f18aed69bb694bff
+ * src/gcrypt-module.h (gcry_pk_sign_t): Add parms flags and hashalgo.
+ * cipher/rsa.c (rsa_sign): Add parms and mark them as unused.
+ * cipher/dsa.c (dsa_sign): Ditto.
+ * cipher/elgamal.c (elg_sign): Ditto.
+ * cipher/pubkey.c (dummy_sign): Ditto.
+ (pubkey_sign): Pass 0 for the new args.
+
+ Fix a special case bug in mpi_powm for e==0.
+ + commit 6e1adb05d290aeeb1c230c763970695f4a538526
+ * mpi/mpi-pow.c (gcry_mpi_powm): For a zero exponent, make sure that
+ the result has been allocated.
+
+2013-07-15 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+ Fix memory leak in t-mpi-point test.
+ + commit a7b80e9fba6b1b095f7c53469747967b40ebfbfd
+ * tests/t-mpi-point.c (basic_ec_math, basic_ec_math_simplified): add
+ calls to gcry_ctx_release() to free contexts after they become unused.
+
+2013-07-10 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Fix 'Please include winsock2.h before windows.h' warnings with mingw32.
+ + commit d6c9c86cb7f571ae0bd9aee4efa01a0f9c4c3104
+ * random/rndw32.c: include winsock2.h before windows.h.
+ * src/ath.h [_WIN32]: Ditto.
+ * tests/benchmark.c [_WIN32]: Ditto.
+
+ Remove duplicate header from mpi/amd64/mpih-mul2.S.
+ + commit c64a0dcbefc5b0055954e37a3c86b32ff7a1b1da
+ * mpi/amd64/mpih-mul2.S: remove duplicated header.
+
+ Fix i386/amd64 inline assembly "cc" clobbers.
+ + commit ed0a598172208ec67234a4edd73189bf6808fd04
+ * cipher/bithelp.h [__GNUC__, __i386__] (rol, ror): add "cc" globber
+ for inline assembly.
+ * cipher/cast5.c [__GNUC__, __i386__] (rol): Ditto.
+ * random/rndhw.c [USE_DRNG] (rdrand_long): Ditto.
+ * src/hmac256.c [__GNUC__, __i386__] (ror): Ditto.
+ * mpi/longlong.c [__i386__] (add_ssaaaa, sub_ddmmss, umul_ppmm)
+ (udiv_qrnnd, count_leading_zeros, count_trailing_zeros): Ditto.
+
+ bufhelp: Suppress 'cast increases required alignment' warning.
+ + commit c3902a6b5cea9acef2e15fbee24eb601eeb25168
+ * cipher/bufhelp.h (buf_xor, buf_xor_2dst, buf_xor_n_copy): Cast
+ to larger element pointer through (void *) to suppress -Wcast-error.
+
+ mpi: Add __ARM_ARCH for older GCC.
+ + commit 97f392f43cf2e4da1297cbecacbfbff33a869478
+ * mpi/longlong.h [__arm__]: Construct __ARM_ARCH if not provided by
+ compiler.
+
+ mpi: add missing "cc" clobber for ARM assembly.
+ + commit 8aa4f2161cf643ce36d87d2e2786b546736f8232
+ * mpi/longlong.h [__arm__] (add_ssaaaa, sub_ddmmss): Add __CLOBBER_CC.
+ [__arm__][__ARM_ARCH <= 3] (umul_ppmm): Ditto.
+
+ Tweak ARM inline assembly for mpi.
+ + commit 71dda4507053379433dc8b0fc6462c15de7299df
+ mpi/longlong.h [__arm__]: Enable inline assembly if __thumb2__ is
+ defined.
+ [__arm__]: Use __ARCH_ARM when defined.
+ [__arm__] [__ARM_ARCH >= 5] (count_leading_zeros): New.
+
+2013-06-26 Werner Koch <wk@gnupg.org>
+
+ Make gpg-error replacement defines more robust.
+ + commit 6540b84a6e9113813e7e49e3ad2024d4a0073300
+ * configure.ac (AH_BOTTOM): Move GPG_ERR_ replacement defines to ...
+ * src/gcrypt-int.h: new file.
+ * src/visibility.h, src/cipher.h: Replace gcrypt.h by gcrypt-int.h.
+ * tests/: Ditto for all test files.
+
+2013-06-20 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Check if assembler is compatible with AMD64 assembly implementations.
+ + commit 3544fa8aa63bef9a35abf236e9376191b5ec206b
+ * cipher/blowfish-amd64.S: Enable only if
+ HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS is defined.
+ * cipher/camellia-aesni-avx-amd64.S: Ditto.
+ * cipher/camellia-aesni-avx2-amd64.S: Ditto.
+ * cipher/cast5-amd64.S: Ditto.
+ * cipher/rinjdael-amd64.S: Ditto.
+ * cipher/serpent-avx2-amd64.S: Ditto.
+ * cipher/serpent-sse2-amd64.S: Ditto.
+ * cipher/twofish-amd64.S: Ditto.
+ * cipher/blowfish.c: Use AMD64 assembly implementation only if
+ HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS is defined
+ * cipher/camellia-glue.c: Ditto.
+ * cipher/cast5.c: Ditto.
+ * cipher/rijndael.c: Ditto.
+ * cipher/serpent.c: Ditto.
+ * cipher/twofish.c: Ditto.
+ * configure.ac: Check gcc/as compatibility with AMD64 assembly
+ implementations.
+
+2013-06-09 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Optimize _gcry_burn_stack for 32-bit and 64-bit architectures.
+ + commit ec2f8de409a93c80efa658134df22074a9bca5a4
+ * src/misc.c (_gcry_burn_stack): Add optimization for 32-bit and 64-bit
+ architectures.
+
+ Add Camellia AES-NI/AVX2 implementation.
+ + commit d94ec5f5f8a5d40a7d344025aa466f276f9718df
+ * cipher/Makefile.am: Add 'camellia-aesni-avx2-amd64.S'.
+ * cipher/camellia-aesni-avx2-amd64.S: New file.
+ * cipher/camellia-glue.c (USE_AESNI_AVX2): New macro.
+ (CAMELLIA_context) [USE_AESNI_AVX2]: Add 'use_aesni_avx2'.
+ [USE_AESNI_AVX2] (_gcry_camellia_aesni_avx2_ctr_enc)
+ (_gcry_camellia_aesni_avx2_cbc_dec)
+ (_gcry_camellia_aesni_avx2_cfb_dec): New prototypes.
+ (camellia_setkey) [USE_AESNI_AVX2]: Check AVX2+AES-NI capable hardware
+ and set 'ctx->use_aesni_avx2'.
+ (_gcry_camellia_ctr_enc) [USE_AESNI_AVX2]: Add AVX2 accelerated code.
+ (_gcry_camellia_cbc_dec) [USE_AESNI_AVX2]: Add AVX2 accelerated code.
+ (_gcry_camellia_cfb_dec) [USE_AESNI_AVX2]: Add AVX2 accelerated code.
+ (selftest_ctr_128, selftest_cbc_128, selftest_cfb_128): Grow 'nblocks'
+ so that AVX2 codepaths get tested.
+ * configure.ac (camellia) [avx2support, aesnisupport]: Add
+ 'camellia-aesni-avx2-amd64.lo'.
+
+ Add Serpent AVX2 implementation.
+ + commit e7ab4e1a7396f4609b9033207015b239ab4a5140
+ * cipher/Makefile.am: Add 'serpent-avx2-amd64.S'.
+ * cipher/serpent-avx2-amd64.S: New file.
+ * cipher/serpent.c (USE_AVX2): New macro.
+ (serpent_context_t) [USE_AVX2]: Add 'use_avx2'.
+ [USE_AVX2] (_gcry_serpent_avx2_ctr_enc, _gcry_serpent_avx2_cbc_dec)
+ (_gcry_serpent_avx2_cfb_dec): New prototypes.
+ (serpent_setkey_internal) [USE_AVX2]: Check for AVX2 capable hardware
+ and set 'use_avx2'.
+ (_gcry_serpent_ctr_enc) [USE_AVX2]: Use AVX2 accelerated functions.
+ (_gcry_serpent_cbc_dec) [USE_AVX2]: Use AVX2 accelerated functions.
+ (_gcry_serpent_cfb_dec) [USE_AVX2]: Use AVX2 accelerated functions.
+ (selftest_ctr_128, selftest_cbc_128, selftest_cfb_128): Grow 'nblocks'
+ so that AVX2 codepaths are tested.
+ * configure.ac (serpent) [avx2support]: Add 'serpent-avx2-amd64.lo'.
+
+ Add detection for Intel AVX2 instruction set.
+ + commit 3289bca708bdd02c69a331095ac6ca9a1efd74cc
+ * configure.ac: Add option --disable-avx2-support.
+ (HAVE_GCC_INLINE_ASM_AVX2): New.
+ (ENABLE_AVX2_SUPPORT): New.
+ * src/g10lib.h (HWF_INTEL_AVX2): New.
+ * src/global.c (hwflist): Add HWF_INTEL_AVX2.
+ * src/hwf-x86.c [__i386__] (get_cpuid): Initialize registers to zero
+ before cpuid.
+ [__x86_64__] (get_cpuid): Initialize registers to zero before cpuid.
+ (detect_x86_gnuc): Store maximum cpuid level.
+ (detect_x86_gnuc) [ENABLE_AVX2_SUPPORT]: Add detection for AVX2.
+
+ twofish: add amd64 assembly implementation.
+ + commit d325ab5d86e6107a46007a4d0131122bbd719f8c
+ * cipher/Makefile.am: Add 'twofish-amd64.S'.
+ * cipher/twofish-amd64.S: New file.
+ * cipher/twofish.c (USE_AMD64_ASM): New macro.
+ [USE_AMD64_ASM] (_gcry_twofish_amd64_encrypt_block)
+ (_gcry_twofish_amd64_decrypt_block, _gcry_twofish_amd64_ctr_enc)
+ (_gcry_twofish_amd64_cbc_dec, _gcry_twofish_amd64_cfb_dec): New
+ prototypes.
+ [USE_AMD64_ASM] (do_twofish_encrypt, do_twofish_decrypt)
+ (twofish_encrypt, twofish_decrypt): New functions.
+ (_gcry_twofish_ctr_enc, _gcry_twofish_cbc_dec, _gcry_twofish_cfb_dec)
+ (selftest_ctr, selftest_cbc, selftest_cfb): New functions.
+ (selftest): Call new bulk selftests.
+ * cipher/cipher.c (gcry_cipher_open) [USE_TWOFISH]: Register Twofish
+ bulk functions for ctr-enc, cbc-dec and cfb-dec.
+ * configure.ac (twofish) [x86_64]: Add 'twofish-amd64.lo'.
+ * src/cipher.h (_gcry_twofish_ctr_enc, _gcry_twofish_cbc_dec)
+ (gcry_twofish_cfb_dec): New prototypes.
+
+2013-05-29 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ rinjdael: add amd64 assembly implementation.
+ + commit 7317fcfadf00789df140e51c0d16b60f6b144b59
+ * cipher/Makefile.am: Add 'rijndael-amd64.S'.
+ * cipher/rijndael-amd64.S: New file.
+ * cipher/rijndael.c (USE_AMD64_ASM): New macro.
+ [USE_AMD64_ASM] (_gcry_aes_amd64_encrypt_block)
+ (_gcry_aes_amd64_decrypt_block): New prototypes.
+ (do_encrypt_aligned) [USE_AMD64_ASM]: Use amd64 assembly function.
+ (do_encrypt): Disable input/output alignment when USE_AMD64_ASM is set.
+ (do_decrypt_aligned) [USE_AMD64_ASM]: Use amd64 assembly function.
+ (do_decrypt): Disable input/output alignment when USE_AMD64_AES is set.
+ * configure.ac (aes) [x86-64]: Add 'rijndael-amd64.lo'.
+
+ blowfish: add amd64 assembly implementation.
+ + commit 9a61edd1f00cefe8ffa3ad54a53eed163883053c
+ * cipher/Makefile.am: Add 'blowfish-amd64.S'.
+ * cipher/blowfish-amd64.S: New file.
+ * cipher/blowfish.c (USE_AMD64_ASM): New macro.
+ [USE_AMD64_ASM] (_gcry_blowfish_amd64_do_encrypt)
+ (_gcry_blowfish_amd64_encrypt_block)
+ (_gcry_blowfish_amd64_decrypt_block, _gcry_blowfish_amd64_ctr_enc)
+ (_gcry_blowfish_amd64_cbc_dec, _gcry_blowfish_amd64_cfb_dec): New
+ prototypes.
+ [USE_AMD64_ASM] (do_encrypt, do_encrypt_block, do_decrypt_block)
+ (encrypt_block, decrypt_block): New functions.
+ (_gcry_blowfish_ctr_enc, _gcry_blowfish_cbc_dec)
+ (_gcry_blowfish_cfb_dec, selftest_ctr, selftest_cbc, selftest_cfb): New
+ functions.
+ (selftest): Call new bulk selftests.
+ * cipher/cipher.c (gcry_cipher_open) [USE_BLOWFISH]: Register Blowfish
+ bulk functions for ctr-enc, cbc-dec and cfb-dec.
+ * configure.ac (blowfish) [x86_64]: Add 'blowfish-amd64.lo'.
+ * src/cipher.h (_gcry_blowfish_ctr_enc, _gcry_blowfish_cbc_dec)
+ (gcry_blowfish_cfb_dec): New prototypes.
+
+2013-05-24 Werner Koch <wk@gnupg.org>
+
+ ecc: Simplify the compliant point generation.
+ + commit 99b18aa536703ef90c9a1f5c8f40bc68b2064593
+ * cipher/ecc.c (generate_key): Use point_snatch_set, replaces unneeded
+ variable copies, etc.
+
+ ecc: Fix a minor flaw in the generation of K.
+ + commit 9711384f75564a71979e3fb971b5f4cadcf1afef
+ * cipher/dsa.c (gen_k): Factor code out to ..
+ * cipher/dsa-common.c (_gcry_dsa_gen_k): new file and function. Add
+ arg security_level and re-indent a bit.
+ * cipher/ecc.c (gen_k): Remove and change callers to _gcry_dsa_gen_k.
+ * cipher/dsa.c: Include pubkey-internal.
+ * cipher/Makefile.am (libcipher_la_SOURCES): Add dsa-common.c
+
+2013-05-24 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ cast5: add amd64 assembly implementation.
+ + commit 0bdf26eea8cdbffefe7e37578f8f896c4f5f5275
+ * cipher/Makefile.am: Add 'cast5-amd64.S'.
+ * cipher/cast5-amd64.S: New file.
+ * cipher/cast5.c (USE_AMD64_ASM): New macro.
+ (_gcry_cast5_s1tos4): Merge arrays s1, s2, s3, s4 to single array to
+ simplify access from assembly implementation.
+ (s1, s2, s3, s4): New macros pointing to subarrays in
+ _gcry_cast5_s1tos4.
+ [USE_AMD64_ASM] (_gcry_cast5_amd64_encrypt_block)
+ (_gcry_cast5_amd64_decrypt_block, _gcry_cast5_amd64_ctr_enc)
+ (_gcry_cast5_amd64_cbc_dec, _gcry_cast5_amd64_cfb_dec): New prototypes.
+ [USE_AMD64_ASM] (do_encrypt_block, do_decrypt_block, encrypt_block)
+ (decrypt_block): New functions.
+ (_gcry_cast5_ctr_enc, _gcry_cast5_cbc_dec, _gcry_cast5_cfb_dec)
+ (selftest_ctr, selftest_cbc, selftest_cfb): New functions.
+ (selftest): Call new bulk selftests.
+ * cipher/cipher.c (gcry_cipher_open) [USE_CAST5]: Register CAST5 bulk
+ functions for ctr-enc, cbc-dec and cfb-dec.
+ * configure.ac (cast5) [x86_64]: Add 'cast5-amd64.lo'.
+ * src/cipher.h (_gcry_cast5_ctr_enc, _gcry_cast5_cbc_dec)
+ (gcry_cast5_cfb_dec): New prototypes.
+
+ cipher-selftest: make selftest work with any block-size.
+ + commit ab8fc70b5f0c396a5bc941267f59166e860b8c5d
+ * cipher/cipher-selftest.c (_gcry_selftest_helper_cbc_128)
+ (_gcry_selftest_helper_cfb_128, _gcry_selftest_helper_ctr_128): Renamed
+ functions from '<name>_128' to '<name>'.
+ (_gcry_selftest_helper_cbc, _gcry_selftest_helper_cfb)
+ (_gcry_selftest_helper_ctr): Make work with different block sizes.
+ * cipher/cipher-selftest.h (_gcry_selftest_helper_cbc_128)
+ (_gcry_selftest_helper_cfb_128, _gcry_selftest_helper_ctr_128): Renamed
+ prototypes from '<name>_128' to '<name>'.
+ * cipher/camellia-glue.c (selftest_ctr_128, selftest_cfb_128)
+ (selftest_ctr_128): Change to use new function names.
+ * cipher/rijndael.c (selftest_ctr_128, selftest_cfb_128)
+ (selftest_ctr_128): Change to use new function names.
+ * cipher/serpent.c (selftest_ctr_128, selftest_cfb_128)
+ (selftest_ctr_128): Change to use new function names.
+
+2013-05-23 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ serpent: add parallel processing for CFB decryption.
+ + commit 6deb0ccdf718a0670f80e6762a3842caf76437d6
+ * cipher/cipher.c (gcry_cipher_open): Add bulf CFB decryption function
+ for Serpent.
+ * cipher/serpent-sse2-amd64.S (_gcry_serpent_sse2_cfb_dec): New
+ function.
+ * cipher/serpent.c (_gcry_serpent_sse2_cfb_dec): New prototype.
+ (_gcry_serpent_cfb_dec) New function.
+ (selftest_cfb_128) New function.
+ (selftest) Call selftest_cfb_128.
+ * src/cipher.h (_gcry_serpent_cfb_dec): New prototype.
+
+ camellia: add parallel processing for CFB decryption.
+ + commit b60f06f70227c1e69e1010da8b47ea51ade48145
+ * cipher/camellia-aesni-avx-amd64.S
+ (_gcry_camellia_aesni_avx_cfb_dec): New function.
+ * cipher/camellia-glue.c (_gcry_camellia_aesni_avx_cfb_dec): New
+ prototype.
+ (_gcry_camellia_cfb_dec): New function.
+ (selftest_cfb_128): New function.
+ (selftest): Call selftest_cfb_128.
+ * cipher/cipher.c (gry_cipher_open): Add bulk CFB decryption function
+ for Camellia.
+ * src/cipher.h (_gcry_camellia_cfb_dec): New prototype.
+
+ rinjdael: add parallel processing for CFB decryption with AES-NI.
+ + commit 319ee14f2aab8db56a830fd7ac8926f91b4f738a
+ * cipher/cipher-selftest.c (_gcry_selftest_helper_cfb_128): New
+ function for CFB selftests.
+ * cipher/cipher-selftest.h (_gcry_selftest_helper_cfb_128): New
+ prototype.
+ * cipher/rijndael.c [USE_AESNI] (do_aesni_enc_vec4): New function.
+ (_gcry_aes_cfb_dec) [USE_AESNI]: Add parallelized CFB decryption.
+ (selftest_cfb_128): New function.
+ (selftest): Call selftest_cfb_128.
+
+2013-05-23 Werner Koch <wk@gnupg.org>
+
+ Avoid compiler warning due to the global symbol setkey.
+ + commit b402de8b9c4a9f269faf03ca952b1eb68a1f33c8
+ * cipher/cipher-selftest.c (_gcry_selftest_helper_cbc_128)
+ (_gcry_selftest_helper_ctr_128): Rename setkey to setkey_func.
+
+2013-05-23 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ serpent: add SSE2 accelerated amd64 implementation.
+ + commit 2fd06e207dcea1d8a7f0e7e92f3359615a99421b
+ * configure.ac (serpent): Add 'serpent-sse2-amd64.lo'.
+ * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add
+ 'serpent-sse2-amd64.S'.
+ * cipher/cipher.c (gcry_cipher_open) [USE_SERPENT]: Register bulk
+ functions for CBC-decryption and CTR-mode.
+ * cipher/serpent.c (USE_SSE2): New macro.
+ [USE_SSE2] (_gcry_serpent_sse2_ctr_enc, _gcry_serpent_sse2_cbc_dec):
+ New prototypes to assembler functions.
+ (serpent_setkey): Set 'serpent_init_done' before calling serpent_test.
+ (_gcry_serpent_ctr_enc): New function.
+ (_gcry_serpent_cbc_dec): New function.
+ (selftest_ctr_128): New function.
+ (selftest_cbc_128): New function.
+ (selftest): Call selftest_ctr_128 and selftest_cbc_128.
+ * cipher/serpent-sse2-amd64.S: New file.
+ * src/cipher.h (_gcry_serpent_ctr_enc): New prototype.
+ (_gcry_serpent_cbc_dec): New prototype.
+
+ Serpent: faster S-box implementation.
+ + commit c85501af8222913f0a1e20e77fceb88e93417925
+ * cipher/serpent.c (SBOX0, SBOX1, SBOX2, SBOX3, SBOX4, SBOX5, SBOX6)
+ (SBOX7, SBOX0_INVERSE, SBOX1_INVERSE, SBOX2_INVERSE, SBOX3_INVERSE)
+ (SBOX4_INVERSE, SBOX5_INVERSE, SBOX6_INVERSE, SBOX7_INVERSE): Replace
+ with new definitions.
+
+2013-05-22 Werner Koch <wk@gnupg.org>
+
+ w32: Fix installing of .def file.
+ + commit 4e46d8bc78008ba06f106b368cefb0dddf15fe38
+ * src/Makefile.am (install-def-file): Create libdir first.
+
+ Add control commands to disable mlock and setuid dropping.
+ + commit 2b8014af202c9e0f7619f7a4377f5eb752235220
+ * src/gcrypt.h.in (GCRYCTL_DISABLE_LOCKED_SECMEM): New.
+ (GCRYCTL_DISABLE_PRIV_DROP): New.
+ * src/global.c (_gcry_vcontrol): Implement them.
+ * src/secmem.h (GCRY_SECMEM_FLAG_NO_MLOCK): New.
+ (GCRY_SECMEM_FLAG_NO_PRIV_DROP): New.
+ * src/secmem.c (no_mlock, no_priv_drop): New.
+ (_gcry_secmem_set_flags, _gcry_secmem_get_flags): Set and get them.
+ (lock_pool): Handle no_mlock and no_priv_drop.
+
+ Fix libtool 2.4.2 to correctly detect .def files.
+ + commit 05b3e2dda61d3d532a7f1ffd2487a85ed1c4f3ab
+ * ltmain.sh (sed_uncomment_deffile): New.
+ (orig_export_symbols): Uncomment def file before testing for EXPORTS.
+ * m4/libtool.m4: Do the same for the generated code.
+
+2013-05-22 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+
+ Add AES bulk CBC decryption selftest.
+ + commit b65281a1b76d7898eb7607932246b78277d8570b
+ * cipher/rinjdael.c (selftest_cbc_128): New.
+ (selftest): Call selftest_cbc_128.
+
+ Change AES bulk CTR encryption selftest use new selftest helper function
+ + commit 3637bdbb5f30a5e06745d448a6a8ad00e5cdd740
+ * cipher/rinjdael.c: (selftest_ctr_128): Change to use new selftest
+ helper function.
+
+ Convert bulk CTR and CBC selftest functions in Camellia to generic selftest helper functions
+ + commit eed4042fa028b3f73bad6a768f5b0a82f642e545
+ * cipher/Makefile.am (libcipher_la_SOURCES): Add cipher-selftest files.
+ * cipher/camellia-glue.c (selftest_ctr_128, selftest_cbc_128): Change
+ to use the new selftest helper functions.
+ * cipher/cipher-selftest.c: New.
+ * cipher/cipher-selftest.h: New.
+
+ camellia: add bulk CBC decryption selftest.
+ + commit f2986f03d1ae59f973bae56ce4333e5457003de5
+ * cipher/camellia-glue.c: (selftest_cbc_128): New selftest function for
+ bulk CBC decryption.
+ (selftest): Add call to selftest_cbc_128.
+
+ camellia: Rename camellia_aesni_avx_x86-64.S to camellia-aesni-avx-amd64.S
+ + commit 194ae35da7830a76b96e9b21121a2e1248762d3f
+ * cipher/camellia_aesni_avx_x86-64.S: Remove.
+ * cipher/camellia-aesni-avx-amd64.S: New.
+ * cipher/Makefile.am: Use the new filename.
+ * configure.ac: Use the new filename.
+
+2013-05-21 Werner Koch <wk@gnupg.org>
+
+ Fix indentation and save on string space.
+ + commit 2ac3a7c2b7154379738d17cfde8cd9017dc142f0
+ * cipher/ecc.c (generate_key): Use the same string for both fatal
+ messages.
+
+2013-05-20 Andrey <andrey@brainhub.org>
+
+ cipher: Fix segv in last ECC change.
+ + commit eb4937914db3fb7317502e97e4f0e40c1857f59d
+ * cipher/ecc.c (generate_key): Make sure R is initialized.
+
+2013-05-09 Andrey <andrey@brainhub.org>
+
+ cipher: Generate compliant ECC keys.
+ + commit 296f38a2bd2e25788643a42e4881faed00884a40
+ * cipher/ecc.c (generate_key): Make sure a key is compliant for
+ using the compact representation.
+
+2013-04-18 Werner Koch <wk@gnupg.org>
+
+ cipher: Fix regression in Padlock support.
+ + commit 6c942ec4d63032539f1fc56c3b970cfec2369e2b
+ * cipher/rijndael.c (do_setkey): Remove dummy padlock key generation case
+ and use the standard one.
+
+ mpi: Yet another fix to get option flag munging right.
+ + commit 03557687a09b9c8878c77cbfdd0f5049940c72da
+ * cipher/Makefile.am (o_flag_munging): Yet another fix.
+
+ mpi: Make using gcc's -Ofast easier.
+ + commit 1ab26bc304c559b0a8d29823d656f7ad8d10a59d
+ * cipher/Makefile.am (o_flag_munging): Take -Ofast in account.
+
+ Fix alignment problem in idea.c.
+ + commit 3271b0dfda67e26c381d7ed667737f08f865ee40
+ * cipher/idea.c (cipher): Rework parameter use to fix alignment
+ problems.
+
+ * cipher/idea.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Remove unused macros.
+
+ Fix alignment problem in idea.c.
+
+ * cipher/idea.c (cipher): Rework parameter use to fix alignment
+ problems.
+
+ * cipher/idea.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Remove unused macros.
+
+
+ (cherry picked from 4cd279556777e02eda79973f68efaa4b741f9175)
+
+2013-04-18 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Add some const attributes.
+ + commit ff0b94c22b36600fff1db9f1d48f9de61f9038f7
+ * cipher/md4.c (transform): Add const attribute.
+ * cipher/md5.c (transform): Ditto.
+ * cipher/rmd160.c (transform): Ditto.
+
+ Fix alignment problem in serpent.c.
+ + commit 86e72b490a5790a9c23341067c7e4d3e38be1634
+ * cipher/serpent.c (serpent_key_prepare): Fix misaligned access.
+ (serpent_setkey): Likewise.
+ (serpent_encrypt_internal): Likewise.
+ (serpent_decrypt_internal): Likewise.
+ (serpent_encrypt): Don't put an alignment-increasing cast.
+ (serpent_decrypt): Likewise.
+ (serpent_test): Likewise.
+
+2013-04-16 Werner Koch <wk@wheatstone.g10code.de>
+
+ Fix multiply by zero in gcry_mpi_ec_mul.
+ + commit 78cd0ba8a8eceee9d0b3397a2ab3bda6ba37c8a4
+ * mpi/ec.c (_gcry_mpi_ec_mul_point): Handle case of SCALAR == 0.
+ * tests/t-mpi-point.c (basic_ec_math): Add a test case for this.
+
+2013-04-15 Werner Koch <wk@gnupg.org>
+
+ Add macros to return pre-defined MPIs.
+ + commit bd3afc27459a44df8cf501a7e1ae37bb849a8b0e
+ * src/gcrypt.h.in (GCRYMPI_CONST_ONE, GCRYMPI_CONST_TWO)
+ (GCRYMPI_CONST_THREE, GCRYMPI_CONST_FOUR, GCRYMPI_CONST_EIGHT): New.
+ (_gcry_mpi_get_const): New private function.
+ * src/visibility.c (_gcry_mpi_get_const): New.
+ * src/visibility.h: Mark it visible.
+
+ Fix addition of EC points.
+ + commit 71b25a5562f68aad81eae52cc1bab9ca7731a7e9
+ * mpi/ec.c (_gcry_mpi_ec_add_points): Fix case of P1 given in affine
+ coordinates.
+
+2013-04-12 Werner Koch <wk@gnupg.org>
+
+ Add hack to allow using an "ecc" key for "ecdsa" or "ecdh".
+ + commit af8a79aea80217a0c85a592db1fa001792a6bf0f
+ * cipher/pubkey.c (sexp_to_key): Add optional arg USE.
+ (gcry_pk_encrypt, gcry_pk_decrypt): Call sexp_to_key with usage sign.
+ (gcry_pk_sign, gcry_pk_verify): Call sexp_to_key with usage encrypt.
+ * tests/basic.c (show_sexp): New.
+ (check_pubkey_sign): Print test number and add cases for ecc.
+ (check_pubkey_sign_ecdsa): New.
+ (do_check_one_pubkey): Divert to new function.
+
+2013-04-11 Werner Koch <wk@gnupg.org>
+
+ Add gcry_pubkey_get_sexp.
+ + commit 1f3cfad66456dd6f2e48f20b8eb0c51343449a1c
+ * src/gcrypt.h.in (GCRY_PK_GET_PUBKEY): New.
+ (GCRY_PK_GET_SECKEY): New.
+ (gcry_pubkey_get_sexp): New.
+ * src/visibility.c (gcry_pubkey_get_sexp): New.
+ * src/visibility.h (gcry_pubkey_get_sexp): Mark visible.
+ * src/libgcrypt.def, src/libgcrypt.vers: Add new function.
+ * cipher/pubkey-internal.h: New.
+ * cipher/Makefile.am (libcipher_la_SOURCES): Add new file.
+ * cipher/ecc.c: Include pubkey-internal.h
+ (_gcry_pk_ecc_get_sexp): New.
+ * cipher/pubkey.c: Include pubkey-internal.h and context.h.
+ (_gcry_pubkey_get_sexp): New.
+ * src/context.c (_gcry_ctx_find_pointer): New.
+ * src/cipher-proto.h: Add _gcry_pubkey_get_sexp.
+ * tests/t-mpi-point.c (print_sexp): New.
+ (context_param, basic_ec_math_simplified): Add tests for the new
+ function.
+
+ * configure.ac (NEED_GPG_ERROR_VERSION): Set to 1.11.
+ (AH_BOTTOM) Add error codes from gpg-error 1.12
+ * src/g10lib.h (fips_not_operational): Use GPG_ERR_NOT_OPERATIONAL.
+
+ * mpi/ec.c (_gcry_mpi_ec_get_mpi): Fix computation of Q.
+ (_gcry_mpi_ec_get_point): Ditto.
+
+ Remove unused code.
+ + commit 7524da2ba83d83a766c22d704006380c893e1c49
+ * cipher/pubkey.c (_gcry_pk_module_lookup, _gcry_pk_module_release)
+ (_gcry_pk_get_elements): Remove.
+
+2013-04-05 Werner Koch <wk@gnupg.org>
+
+ Make the Q parameter optional for ECC signing.
+ + commit fe91a642c7c257aca095b96406fbcace88fa3df4
+ * cipher/ecc.c (ecc_sign): Remove the need for Q.
+ * cipher/pubkey.c (sexp_elements_extract_ecc): Make Q optional for a
+ private key.
+ (sexp_to_key): Add optional arg R_IS_ECC.
+ (gcry_pk_sign): Do not call gcry_pk_get_nbits for ECC keys.
+ * tests/pubkey.c (die): Make sure to print a LF.
+ (check_ecc_sample_key): New.
+ (main): Call new test.
+
+ Add test case for SCRYPT and rework the code.
+ + commit f23a068bcb6ec9788710698578d8be0a2a006dbc
+ * tests/t-kdf.c (check_scrypt): New.
+ (main): Call new test.
+
+ * configure.ac: Support disabling of the scrypt algorithm. Make KDF
+ enabling similar to the other algorithm classes. Disable scrypt if we
+ don't have a 64 bit type.
+ * cipher/memxor.c, cipher/memxor.h: Remove.
+ * cipher/scrypt.h: Remove.
+ * cipher/kdf-internal.h: New.
+ * cipher/Makefile.am: Remove files. Add new file. Move scrypt.c to
+ EXTRA_libcipher_la_SOURCES.
+ (GCRYPT_MODULES): Add GCRYPT_KDFS.
+ * src/gcrypt.h.in (GCRY_KDF_SCRYPT): Change value.
+ * cipher/kdf.c (pkdf2): Rename to _gcry_kdf_pkdf2.
+ (_gcry_kdf_pkdf2): Don't bail out for SALTLEN==0.
+ (gcry_kdf_derive): Allow for a passwordlen of zero for scrypt. Check
+ for SALTLEN > 0 for GCRY_KDF_PBKDF2. Pass algo to _gcry_kdf_scrypt.
+ (gcry_kdf_derive) [!USE_SCRYPT]: Return an error.
+ * cipher/scrypt.c: Replace memxor.h by bufhelp.h. Replace scrypt.h by
+ kdf-internal.h. Enable code only if HAVE_U64_TYPEDEF is defined.
+ Replace C99 types uint64_t, uint32_t, and uint8_t by libgcrypt types.
+ (_SALSA20_INPUT_LENGTH): Remove underscore from identifier.
+ (_scryptBlockMix): Replace memxor by buf_xor.
+ (_gcry_kdf_scrypt): Use gcry_malloc and gcry_free. Check for integer
+ overflow. Add hack to support blocksize of 1 for tests. Return
+ errors from calls to _gcry_kdf_pkdf2.
+
+ * cipher/kdf.c (openpgp_s2k): Make static.
+
+2013-04-04 Christian Grothoff <christian@grothoff.org>
+
+ Add the SCRYPT KDF function.
+ + commit 855b1a8f81b5a3b5b31d0c3c303675425f58a5af
+ * scrypt.c, scrypt.h: New files.
+ * memxor.c, memxor.h: New files.
+ * cipher/Makefile.am: Add new files.
+ * cipher/kdf.c (gcry_kdf_derive): Support GCRY_KDF_SCRYPT.
+ * src/gcrypt.h.in (GCRY_KDF_SCRYPT): New.
+
+2013-03-22 Werner Koch <wk@gnupg.org>
+
+ Replace deprecated AM_CONFIG_HEADER macro.
+ + commit d0c8fda5af45354ac32928c9a01e688d6893599d
+ * configure.ac: s/AM_CONFIG_HEADER/AC_CONFIG_HEADER/
+
+ Disable AES-NI support if as does not support SSSE3.
+ + commit 9f4df1612ae21a5ce70d98930cb194e5193f5e2d
+ * configure.ac (HAVE_GCC_INLINE_ASM_SSSE3): New test.
+ (ENABLE_AESNI_SUPPORT): Do not define without SSSE3 support.
+ (HAVE_GCC_INLINE_ASM_SSSE3, ENABLE_AVX_SUPPORT): Split up detection
+ and definition.
+
+2013-03-21 Werner Koch <wk@gnupg.org>
+
+ Fix make dependency regression.
+ + commit 2a1e03c5a481689c43d197dd8034a1d73de0a1a4
+ * src/Makefile.am (libgcrypt_la_DEPENDENCIES): Add missing backslash.
+ Reported by LRN.
+
+2013-03-20 Werner Koch <wk@gnupg.org>
+
+ Use finer grained on-the-fly helper computations for EC.
+ + commit 5fb3501aa0cf5f2b2a9012706bb9ad2b1c4bfd7d
+ * src/ec-context.h (mpi_ec_ctx_s): Replace NEED_SYNC by a bitfield.
+ * mpi/ec.c (ec_p_sync): Remove.
+ (ec_get_reset, ec_get_a_is_pminus3, ec_get_two_inv_p): New.
+ (ec_p_init): Use ec_get_reset.
+ (_gcry_mpi_ec_set_mpi, _gcry_mpi_ec_dup_point)
+ (_gcry_mpi_ec_add_points): Replace ec_p_sync by the ec_get_ accessors.
+
+ Allow building with w64-mingw32.
+ + commit b402e550041782b770a6ae267c7c28ca8324a12e
+ * autogen.sh <--build-w32>: Support the w64-mingw32 toolchain. Also
+ prepare for 64 bit building.
+
+ Provide GCRYPT_VERSION_NUMBER macro, add build info to the binary.
+ + commit 1eaad0a8c4cab227685a6a8768e539df2f1f4dac
+ * src/gcrypt.h.in (GCRYPT_VERSION_NUMBER): New.
+ * configure.ac (VERSION_NUMBER): New ac_subst.
+ * src/global.c (_gcry_vcontrol): Move call to above function ...
+ (gcry_check_version): .. here.
+
+ * configure.ac (BUILD_REVISION, BUILD_FILEVERSION)
+ (BUILD_TIMESTAMP): Define on all platforms.
+ * compat/compat.c (_gcry_compat_identification): Include revision and
+ timestamp.
+
+ Fix a memory leak in the new EC code.
+ + commit de07974d807b703a2554d6ba885ea249e648bd44
+ * cipher/ecc.c (point_from_keyparam): Always call mpi_free on A.
+
+2013-03-19 Werner Koch <wk@gnupg.org>
+
+ Extend the new EC interface and fix two bugs.
+ + commit 931e409e877d1e444edd53dead327ec8e64daf9a
+ * src/ec-context.h (mpi_ec_ctx_s): Add field NEED_SYNC.
+ * mpi/ec.c (ec_p_sync): New.
+ (ec_p_init): Only set NEED_SYNC.
+ (_gcry_mpi_ec_set_mpi): Set NEED_SYNC for 'p' and 'a'.
+ (_gcry_mpi_ec_dup_point, _gcry_mpi_ec_add_points)
+ (_gcry_mpi_ec_mul_point): Call ec_p_sync.
+ (_gcry_mpi_ec_get_point): Recompute 'q' is needed.
+ (_gcry_mpi_ec_get_mpi): Ditto. Also allow for names 'q', 'q.x',
+ 'q.y', and 'g'.
+ * cipher/ecc.c (_gcry_mpi_ec_ec2os): New.
+
+ * cipher/ecc.c (_gcry_mpi_ec_new): Fix init from parameters 'Q'->'q',
+ 'G'->'q'.
+
+2013-03-15 Werner Koch <wk@gnupg.org>
+
+ mpi: Add functions to manipulate an EC context.
+ + commit 229f3219f80c9369ed9624242c0436ae6d293201
+ * src/gcrypt.h.in (gcry_mpi_ec_p_new): Remove.
+ (gcry_mpi_ec_new): New.
+ (gcry_mpi_ec_get_mpi): New.
+ (gcry_mpi_ec_get_point): New.
+ (gcry_mpi_ec_set_mpi): New.
+ (gcry_mpi_ec_set_point): New.
+ * src/visibility.c (gcry_mpi_ec_p_new): Remove.
+ * mpi/ec.c (_gcry_mpi_ec_p_new): Make it an internal function and
+ change to return an error code.
+ (_gcry_mpi_ec_get_mpi): New.
+ (_gcry_mpi_ec_get_point): New.
+ (_gcry_mpi_ec_set_mpi): New.
+ (_gcry_mpi_ec_set_point): New.
+ * src/mpi.h: Add new prototypes.
+ * src/ec-context.h: New.
+ * mpi/ec.c: Include that header.
+ (mpi_ec_ctx_s): Move to ec-context.h, add new fields, and put some
+ fields into an inner struct.
+ (point_copy): New.
+ * cipher/ecc.c (fill_in_curve): Allow passing NULL for R_NBITS.
+ (mpi_from_keyparam, point_from_keyparam): New.
+ (_gcry_mpi_ec_new): New.
+
+ * tests/t-mpi-point.c (test-curve): New.
+ (ec_p_new): New. Use it instead of the removed gcry_mpi_ec_p_new.
+ (get_and_cmp_mpi, get_and_cmp_point): New.
+ (context_param): New test.
+ (basic_ec_math_simplified): New test.
+ (main): Call new tests.
+
+ * src/context.c (_gcry_ctx_get_pointer): Check for a NULL CTX.
+
+2013-03-13 Werner Koch <wk@gnupg.org>
+
+ Add GCRYMPI_FLAG_CONST and make use constants.
+ + commit e005629bd7bebb3e13945645c6e1230b44ab16a2
+ * src/gcrypt.h.in (GCRYMPI_FLAG_CONST): New.
+ * src/mpi.h (mpi_is_const, mpi_const): New.
+ (enum gcry_mpi_constants, MPI_NUMBER_OF_CONSTANTS): New.
+ * mpi/mpiutil.c (_gcry_mpi_init): New.
+ (constants): New.
+ (_gcry_mpi_free): Do not release a constant flagged MPI.
+ (gcry_mpi_copy): Clear the const and immutable flags.
+ (gcry_mpi_set_flag, gcry_mpi_clear_flag, gcry_mpi_get_flag): Support
+ GCRYMPI_FLAG_CONST.
+ (_gcry_mpi_const): New.
+ * src/global.c (global_init): Call _gcry_mpi_init.
+ * mpi/ec.c (mpi_ec_ctx_s): Remove fields one, two, three, four, and
+ eight. Change all users to call mpi_const() instead.
+
+ * src/mpiutils.c (gcry_mpi_set_opaque): Check the immutable flag.
+
+ Add GCRYMPI_FLAG_IMMUTABLE to help debugging.
+ + commit 1fecae98ee7e0fa49b29f98efa6817ca121ed98a
+ * src/gcrypt.h.in (GCRYMPI_FLAG_IMMUTABLE): New.
+ * src/mpi.h (mpi_is_immutable): New macro.
+ * mpi/mpiutil.c (gcry_mpi_set_flag, gcry_mpi_clear_flag)
+ (gcry_mpi_get_flag): Implement new flag
+ (_gcry_mpi_immutable_failed): New.
+
+ * mpi/mpiutil.c (_gcry_mpi_clear, _gcry_mpi_free, gcry_mpi_snatch)
+ (gcry_mpi_set, gcry_mpi_randomize): Act upon the immutable flag.
+ * mpi/mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit)
+ (gcry_mpi_clear_highbit, gcry_mpi_clear_bit)
+ (_gcry_mpi_rshift_limbs, gcry_mpi_lshift): Ditto.
+ * mpi/mpicoder.c (_gcry_mpi_set_buffer): Ditto.
+
+2013-03-08 Werner Koch <wk@gnupg.org>
+
+ mpi: Add an API for EC math.
+ + commit 8ac9e756d3ca545a9b97e61ad3d42fc2e877d788
+ * src/context.c, src/context.h: New.
+ * src/Makefile.am (libgcrypt_la_SOURCES): Add new files.
+ * src/gcrypt.h.in (struct gcry_context, gcry_ctx_t): New types.
+ (gcry_ctx_release): New prototype.
+ (gcry_mpi_ec_p_new, gcry_mpi_ec_get_affine, gcry_mpi_ec_dup)
+ (gcry_mpi_ec_add, gcry_mpi_ec_mul): New prototypes.
+ * mpi/ec.c: Include errno.h and context.h.
+ (_gcry_mpi_ec_init): Rename to ..
+ (ec_p_init): this, make static, remove allocation and add arg CTX.
+ (_gcry_mpi_ec_p_internal_new): New; to replace _gcry_mpi_ec_init.
+ Change all callers to use this func.
+ (_gcry_mpi_ec_free): Factor code out to ..
+ (ec_deinit): New func.
+ (gcry_mpi_ec_p_new): New.
+ * src/visibility.c: Include context.h and mpi.h.
+ (gcry_mpi_ec_p_new, gcry_mpi_ec_get_affine, gcry_mpi_ec_dup)
+ (gcry_mpi_ec_add, gcry_mpi_ec_mul)
+ (gcry_ctx_release): New wrapper functions.
+ * src/visibility.h: Mark new wrapper functions visible.
+ * src/libgcrypt.def, src/libgcrypt.vers: Add new symbols.
+ * tests/t-mpi-point.c (print_mpi, hex2mpi, cmp_mpihex): New.
+ (context_alloc): New.
+ (make_point, basic_ec_math): New.
+
+ mpi: Add an API for EC point operations.
+ + commit 7cce620acddac2df024ca421ed3abc32a88f3738
+ * mpi/ec.c (gcry_mpi_point_new, gcry_mpi_point_release): New.
+ (gcry_mpi_point_get, gcry_mpi_point_snatch_get): New.
+ (gcry_mpi_point_set, gcry_mpi_point_snatch_set): New.
+ * src/visibility.h, src/visibility.c: Add corresponding macros and
+ wrappers.
+ * src/gcrypt.h.in (struct gcry_mpi_point, gcry_mpi_point_t): New.
+ (gcry_mpi_point_new, gcry_mpi_point_release, gcry_mpi_point_get)
+ (gcry_mpi_point_snatch_get, gcry_mpi_point_set)
+ (gcry_mpi_point_snatch_set): New prototypes.
+ (mpi_point_new, mpi_point_release, mpi_point_get, mpi_point_snatch_get)
+ (mpi_point_set, mpi_point_snatch_set): New macros.
+ * src/libgcrypt.vers (gcry_mpi_point_new, gcry_mpi_point_release)
+ (gcry_mpi_point_get, gcry_mpi_point_snatch_get, gcry_mpi_point_set)
+ (gcry_mpi_point_snatch_set): New symbols.
+ * src/libgcrypt.def: Ditto.
+ * tests/t-mpi-point.c: New.
+ * tests/Makefile.am (TESTS): Add t-mpi-point
+
+2013-03-07 Werner Koch <wk@gnupg.org>
+
+ mpi: Add mpi_snatch and change an internal typedef.
+ + commit 6c4767637c512127a4362732b3ec51068554d328
+ * src/mpi.h (struct mpi_point_s): Rename to struct gcry_mpi_point.
+ (mpi_point_struct): New typedef.
+ (mpi_point_t): Change typedef to a pointer. Replace all occurrences
+ to use mpi_point_struct.
+ * mpi/ec.c (_gcry_mpi_ec_point_init): Rename to ..
+ (_gcry_mpi_point_init): this. Change all callers.
+ (_gcry_mpi_ec_point_free): Rename to ..
+ (_gcry_mpi_point_free_parts): this. Change all callers.
+
+ * mpi/mpiutil.c (gcry_mpi_snatch): New function.
+ * src/gcrypt.h.in (gcry_mpi_snatch, mpi_snatch): Add protoype and
+ macro.
+ * src/visibility.c (gcry_mpi_snatch): Add wrapper.
+ * src/visibility.h (gcry_mpi_snatch): Add macro magic.
+ * src/libgcrypt.def, src/libgcrypt.vers: Add new function.
+
+ Pretty print the configure feedback.
+ + commit c620099e4ab2f35e0196b395a805bb655c984ac2
+ * acinclude.m4 (GNUPG_MSG_PRINT): Remove.
+ (GCRY_MSG_SHOW, GCRY_MSG_WRAP): New.
+ * configure.ac: Use new macros for the feedback.
+
+2013-02-20 Werner Koch <wk@gnupg.org>
+
+ Fix building of hwf-x86.c.
+ + commit 70dcac663de06b012417015c175973d64e6980df
+ * src/Makefile.am (AM_CFLAGS): Set to GPG_ERROR_CFLAGS
+ (AM_CCASFLAGS): Set NOEXECSTACK_FLAGS.
+
+ Remove build hacks for FreeBSD.
+ + commit fb48ebf7081400a24ee48f8a9894a361e8834b6e
+ * configure.ac [freebsd]: Do not add /usr/local to CPPFLAGS and
+ LDFLAGS.
+
+2013-02-19 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+ Rinjdael: Fix use of SSE2 outside USE_AESNI/ctx->use_aesni.
+ + commit 0da77955a097bfd2469ad084b3e9fcac4fb1e3fa
+ * cipher/rijndael.c (_gcry_aes_cbc_enc): Check if AES-NI is enabled before
+ calling aesni_prepare() and aesni_cleanup().
+
+ Add AES-NI/AVX accelerated Camellia implementation.
+ + commit 63ac3ba07dba82fde040d31b90b4eff627bd92b9
+ * configure.ac: Add option --disable-avx-support.
+ (HAVE_GCC_INLINE_ASM_AVX): New.
+ (ENABLE_AVX_SUPPORT): New.
+ (camellia) [ENABLE_AVX_SUPPORT, ENABLE_AESNI_SUPPORT]: Add
+ camellia_aesni_avx_x86-64.lo.
+ * cipher/Makefile.am (AM_CCASFLAGS): Add.
+ (EXTRA_libcipher_la_SOURCES): Add camellia_aesni_avx_x86-64.S
+ * cipher/camellia-glue.c [ENABLE_AESNI_SUPPORT, ENABLE_AVX_SUPPORT]
+ [__x86_64__] (USE_AESNI_AVX): Add macro.
+ (struct Camellia_context) [USE_AESNI_AVX]: Add use_aesni_avx.
+ [USE_AESNI_AVX] (_gcry_camellia_aesni_avx_ctr_enc)
+ (_gcry_camellia_aesni_avx_cbc_dec): New prototypes to assembly
+ functions.
+ (camellia_setkey) [USE_AESNI_AVX]: Enable AES-NI/AVX if hardware
+ support both.
+ (_gcry_camellia_ctr_enc) [USE_AESNI_AVX]: Add AES-NI/AVX code.
+ (_gcry_camellia_cbc_dec) [USE_AESNI_AVX]: Add AES-NI/AVX code.
+ * cipher/camellia_aesni_avx_x86-64.S: New.
+ * src/g10lib.h (HWF_INTEL_AVX): New.
+ * src/global.c (hwflist): Add HWF_INTEL_AVX.
+ * src/hwf-x86.c (detect_x86_gnuc) [ENABLE_AVX_SUPPORT]: Add detection
+ for AVX.
+
+ camellia.c: Prepare for AES-NI/AVX implementation.
+ + commit 4de62d80644228fc5db2a9f9c94a7eb633d8de2e
+ * cipher/camellia-glue.c (CAMELLIA_encrypt_stack_burn_size)
+ (CAMELLIA_decrypt_stack_burn_size): Increase stack burn size.
+ * cipher/camellia.c (CAMELLIA_ROUNDSM): Move key-material mixing in
+ the front.
+ (camellia_setup128, camellia_setup256): Remove now unneeded
+ key-material mangling.
+ (camellia_encrypt128, camellia_decrypt128, amellia_encrypt256)
+ (camellia_decrypt256): Copy block to stack, so that compiler can
+ optimize it for register usage.
+
+ Camellia, prepare glue code for AES-NI/AVX implementation.
+ + commit 537f12ce072d568f9fa344c447d32b2e0efffbe8
+ * cipher/camellia-glue.c (ATTR_ALIGNED_16): Add macro.
+ (CAMELLIA_encrypt_stack_burn_size): Add macro.
+ (camellia_encrypt): Use macro above for stack burn size.
+ (CAMELLIA_decrypt_stack_burn_size): Add macro.
+ (camellia_decrypt): Use macro above for stack burn size.
+ (_gcry_camellia_ctr_enc): New function.
+ (_gcry_camellia_cbc_dec): New function.
+ (selftest_ctr_128): New function.
+ (selftest): Call function above.
+ * cipher/cipher.c (gcry_cipher_open) [USE_CAMELLIA]: Register bulk
+ functions for CBC-decryption and CTR-mode.
+ * src/cipher.h (_gcry_camellia_ctr_enc): New prototype.
+ (_gcry_camellia_cbc_dec): New prototype.
+
+2012-12-21 Werner Koch <wk@gnupg.org>
+
+ Prepare for hardware feature detection on other platforms.
+ + commit 09ac5d87d11aa0b1fa0e0a4184ab03b3671a73e2
+ * configure.ac (GCRYPT_HWF_MODULES): New.
+ (HAVE_CPU_ARCH_X86, HAVE_CPU_ARCH_ALPHA, HAVE_CPU_ARCH_SPARC)
+ (HAVE_CPU_ARCH_MIPS, HAVE_CPU_ARCH_M68K, HAVE_CPU_ARCH_PPC)
+ (HAVE_CPU_ARCH_ARM): New AC_DEFINEs.
+ * mpi/config.links (mpi_cpu_arch): New.
+ * src/global.c (print_config): Print new tag "cpu-arch".
+ * src/Makefile.am (libgcrypt_la_SOURCES): Add hwf-common.h
+ (EXTRA_libgcrypt_la_SOURCES): New.
+ (gcrypt_hwf_modules): New.
+ (libgcrypt_la_DEPENDENCIES, libgcrypt_la_LIBADD): Add that one.
+ * src/hwfeatures.c: Factor most code out to ...
+ * src/hwf-x86.c: New file.
+ (detect_x86_gnuc): Return the feature vector.
+ (_gcry_hwf_detect_x86): New.
+ * src/hwf-common.h: New.
+ * src/hwfeatures.c (_gcry_detect_hw_features): Dispatch using
+ HAVE_CPU_ARCH_ macros.
+
+2012-12-21 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+ Clean up i386/x86-64 cpuid usage in hwfeatures.c.
+ + commit d842eea55e22c05da3959a7a4422b5fcd7884f60
+ * src/hwfeatures.c [__i386__ && __GNUC__] (detect_ia32_gnuc): Remove.
+ [__x86_64__ && __GNUC__] (detect_x86_64_gnuc): Remove.
+ [__i386__ && __GNUC__] (is_cpuid_available, get_cpuid)
+ (HAS_X86_CPUID): New.
+ [__x86_64__ && __GNUC__] (is_cpuid_available, get_cpuid)
+ (HAS_X86_CPUID): New.
+ [HAS_X86_CPUID] (detect_x86_gnuc): New.
+ (_gcry_detect_hw_features) [__i386__ && GNUC]: Remove detect_ia32_gnuc
+ call.
+ (_gcry_detect_hw_features) [__x86_64__ && GNUC]: Remove
+ detect_x86_64_gnuc call.
+ (_gcry_detect_hw_features) [HAS_X86_CPUID]: Add detect_x86_gnuc call.
+
+2012-12-18 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
+
+ Add support for using DRNG random number generator.
+ + commit efd7002188e6d50013e4d9a920a8b9afa9d210e5
+ * configure.ac: Add option --disable-drng-support.
+ (ENABLE_DRNG_SUPPORT): New.
+ * random/rndhw.c (USE_DRNG): New.
+ (rdrand_long, rdrand_nlong, poll_drng): New.
+ (_gcry_rndhw_poll_fast, _gcry_rndhw_poll_slow): Call poll function.
+ * src/g10lib.h (HWF_INTEL_RDRAND): New.
+ * src/global.c (hwflist): Add "intel-rdrand".
+ * src/hwfeatures.c (detect_x86_64_gnuc) [ENABLE_DRNG_SUPPORT]: Detect
+ RDRAND.
+ (detect_ia32_gnuc) [ENABLE_DRNG_SUPPORT]: Detect RDRAND.
+
+2012-12-03 Werner Koch <wk@gnupg.org>
+
+ random: Add a RNG selection interface and system RNG wrapper.
+ + commit 7607ab81504ce44060ed0b331d309606f5da1e75
+ * random/random-system.c: New.
+ * random/Makefile.am (librandom_la_SOURCES): Add new module.
+ * random/random.c (struct rng_types): New.
+ (_gcry_set_preferred_rng_type, _gcry_get_rng_type): New.
+ (_gcry_random_initialize, gcry_random_add_bytes, do_randomize)
+ (_gcry_set_random_seed_file, _gcry_update_random_seed_file)
+ (_gcry_fast_random_poll): Dispatch to the actual RNG.
+ * src/gcrypt.h.in (GCRYCTL_SET_PREFERRED_RNG_TYPE): New.
+ GCRYCTL_GET_CURRENT_RNG_TYPE): New.
+ (gcry_rng_types): New.
+ * src/global.c (print_config): Print the TNG type.
+ (global_init, _gcry_vcontrol): Implement the new control codes.
+ * doc/gcrypt.texi (Controlling the library): Document the new control
+ codes.
+
+ * tests/benchmark.c (main): Add options to test the RNG types.
+ * tests/random.c (main): Add new options.
+ (print_hex): Print to stderr.
+ (progress_cb, rng_type): New.
+ (check_rng_type_switching, check_early_rng_type_switching): New.
+ (run_all_rng_tests): New.
+
+ tests: Allow use of random.c under Windows.
+ + commit 76c622e24a07f7c826812be173aa173b4334776b
+ * tests/Makefile.am (TESTS): Always include random.c
+ * tests/random.c [!W32]: Include sys/wait.h.
+ (inf): New.
+ (check_forking, check_nonce_forking): Print a notice what will be done.
+ (main) [W32]: Do not call signal.
+
+ Make random-fips.c work multi-threaded.
+ + commit 75760021b511ba438606af746431223357e7a155
+ * random/random-fips.c (basic_initialization): Fix reversed logic.
+
+ Move nonce creation from csprng backend to random main module.
+ + commit c324644aa14e54fc7051983b38222db32b8ab227
+ * random/random-csprng.c (_gcry_rngcsprng_create_nonce): Remove.
+ (nonce_buffer_lock): Remove.
+ (initialize_basics): Remove init of nonce_buffer_lock.
+ * random/random.c: Add a few header files.
+ (nonce_buffer_lock): New.
+ (_gcry_random_initialize): Init nonce_buffer_lock.
+ (gcry_create_nonce): Add code from _gcry_rngcsprng_create_nonce.
+
+ * random/random-daemon.c (_gcry_daemon_create_nonce): Remove.
+
+2012-12-03 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+ Fix building with CC="gcc -std=c90".
+ + commit f851b9a932ee64fa5a06000d1ac763ba4349f07d
+ * configure.ac: Add check for missing 'asm' keyword in C90 mode and
+ replacement with '__asm__'.
+
+2012-12-03 Werner Koch <wk@gnupg.org>
+
+ Try to use inttypes.h if stdint.h is not available.
+ + commit d9ec7aec1301b13a89e5c9c54d7ad52e1a29b846
+ * cipher/bufhelp.h [HAVE_INTTYPES_H]: Include inttypes.h
+
+2012-12-03 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+ Optimize buffer xoring.
+ + commit 162791bc08f4fc9b3882671e68ecdfd9e130ae59
+ * cipher/Makefile.am (libcipher_la_SOURCES): Add 'bufhelp.h'.
+ * cipher/bufhelp.h: New.
+ * cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt)
+ (_gcry_cipher_aeswrap_decrypt): Use 'buf_xor' for buffer xoring.
+ * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
+ (_gcry_cipher_cbc_decrypt): Use 'buf_xor' for buffer xoring and remove
+ resulting unused variables.
+ * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt) Use 'buf_xor_2dst'
+ for buffer xoring and remove resulting unused variables.
+ (_gcry_cipher_cfb_decrypt): Use 'buf_xor_n_copy' for buffer xoring and
+ remove resulting unused variables.
+ * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Use 'buf_xor' for
+ buffer xoring and remove resulting unused variables.
+ * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt)
+ (_gcry_cipher_ofb_decrypt): Use 'buf_xor' for buffer xoring and remove
+ resulting used variables.
+ * cipher/rijndael.c (_gry_aes_cfb_enc): Use 'buf_xor_2dst' for buffer
+ xoring and remove resulting unused variables.
+ (_gry_aes_cfb_dev): Use 'buf_xor_n_copy' for buffer xoring and remove
+ resulting unused variables.
+ (_gry_aes_cbc_enc, _gry_aes_ctr_enc, _gry_aes_cbc_dec): Use 'buf_xor'
+ for buffer xoring and remove resulting unused variables.
+
+2012-11-29 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+ Optimize AES-NI CTR mode.
+ + commit 9ee9e25f519696d509b1a5c1cc04ab0121e98a51
+ * cipher/rijndael.c [USE_AESNI] (do_aesni_ctr, do_aesni_ctr_4): Make
+ handling of 64-bit overflow and carry conditional. Avoid generic to
+ vector register passing of value '1'. Generate and use '-1' instead.
+
+2012-11-28 Werner Koch <wk@gnupg.org>
+
+ Make a cpp conditional in rijndael.c better readable.
+ + commit 6765e0a8618000d3dc7bda035163e0708c43791b
+ * cipher/rijndael.c (USE_AESNI): Modify cpp conditionals for better
+ readability.
+
+2012-11-28 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+ Fix building with Clang on x86-64 and i386.
+ + commit 99e272d938fe23efec25af409bdb91dae0e659e5
+ * cipher/rijndael.c [USE_AESNI] (do_aesni_enc_aligned)
+ (do_aesni_dec_vec4, do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Add
+ explicit suffix to 'cmp' instructions.
+
+2012-11-26 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+ Optimize wipememory2 for i386 and x86-64.
+ + commit faec12e23f03c7cd1614594bfdd51f1302cadb42
+ * src/g10lib.h (wipememory2): Add call to fast_wipememory2.
+ (fast_wipememory2): New macros for i386 and x86-64 architectures.
+ Empty macro provided for other architectures.
+
+ Fix missing 64bit carry handling in AES-NI CTR mode.
+ + commit fc37e805c6394c2e635d1a033670be961f36a6d2
+ * cipher/rijndael.c [USE_AESNI] (do_aesni_ctr, do_aesni_ctr_4): Add
+ carry handling to 64-bit addition.
+ (selftest_ctr_128): New function for testing IV handling in bulk CTR
+ function.
+ (selftest): Add call to selftest_ctr_128.
+
+ Add parallelized AES-NI CBC decryption.
+ + commit 35aff0cd43885b5f5c076432ec614698abeb63d8
+ * cipher/rijndael.c [USE_AESNI] (aesni_cleanup_5): New macro.
+ [USE_AESNI] (do_aesni_dec_vec4): New function.
+ (_gcry_aes_cbc_dec) [USE_AESNI]: Add parallelized CBC loop.
+ (_gcry_aes_cbc_dec) [USE_AESNI]: Change IV storage register from xmm3
+ to xmm5.
+
+ Clear xmm5 after use in AES-NI CTR mode.
+ + commit 5acd0e5ae2a58dda51c2b56c879b80a1a6d2c42f
+ * cipher/rijndael.c [USE_AESNI]: Rename aesni_cleanup_2_4 to
+ aesni_cleanup_2_5.
+ [USE_AESNI] (aesni_cleanup_2_5): Clear xmm5 register.
+ (_gcry_aes_ctr_enc, _gcry_aes_cbc_dec) [USE_AESNI]: Use
+ aesni_cleanup_2_5 instead of aesni_cleanup_2_4.
+
+ Optimize AES-NI CBC encryption.
+ + commit be3768994ad362dfc849a8cd0146b4c9bb287d20
+ * cipher/rijndeal.c (_gcry_aes_cbc_enc) [USE_AESNI]: Add AES-NI
+ spesific loop and use SSE2 assembler for xoring and copying of
+ blocks.
+
+ Improve parallelizability of CBC decryption for AES-NI.
+ + commit 3369d960158ab4231b83926a0f982e2a8819f173
+ * cipher/rijndael.c (_gcry_aes_cbc_dec) [USE_AESNI]: Add AES-NI
+ specific CBC mode loop with temporary block and IV stored in free SSE
+ registers.
+
+ Extend test of chained modes for 128bit ciphers.
+ + commit 55b96be08531664ed3f4230acebe0f45954bbc33
+ * tests/basic.c (check_one_cipher_core, check_one_cipher): Increase
+ input and output buffer sizes from 16 bytes to 1024+16=1040 bytes.
+ (check_one_cipher_core): Add asserts to verify sizes of temporary
+ buffers.
+
+2012-11-21 Werner Koch <wk@gnupg.org>
+
+ Fix for strict aliasing rules.
+ + commit dfb4673da8ee52d95e0a62c9f49ca8599943f22e
+ * cipher/rijndael.c (do_setkey, prepare_decryption): Use u32_a_t for
+ casting.
+
+ Do not detect AES-NI support if disabled by configure.
+ + commit 3047795794eb238aa684bd0729acf64c82a19e09
+ * src/hwfeatures.c (detect_ia32_gnuc): Detect AESNI support only if
+ that support has been enabled.
+
+2012-11-21 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+ Fix too large burn_stack in camellia-glue.c.
+ + commit 8afabc2813948778a3db52d9dee9a041a3dd50d4
+ * cipher/camellia-glue.c (camellia_encrypt, camellia_decrypt): Do not
+ take full array size of KEY_TABLE_TYPE, but argument size instead.
+
+ Add x86_64 support for AES-NI.
+ + commit d8bdfa42ed582655c180e7db9b16d4e756a12a6e
+ * cipher/rijndael.c [ENABLE_AESNI_SUPPORT]: Enable USE_AESNI on x86-64.
+ (do_setkey) [USE_AESNI_is_disabled_here]: Use %[key] and %[ksch]
+ directly as registers instead of using temporary register %%esi.
+ [USE_AESNI] (do_aesni_enc_aligned, do_aesni_dec_aligned, do_aesni_cfb,
+ do_aesni_ctr, do_aesni_ctr_4): Use %[key] directly as register instead
+ of using temporary register %%esi.
+ [USE_AESNI] (do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Change %[key]
+ from generic "g" type to register "r".
+ * src/hwfeatures.c (_gcry_detect_hw_features) [__x86_64__]: Do not
+ clear AES-NI feature flag.
+
+ Fix cpuid vendor-id check for i386 and x86-64.
+ + commit 9e1552517f68459a165ddebbba85e7cf37ff4f0c
+ * src/hwfeatures.c (detect_x86_64_gnuc, detect_ia32_gnuc): Allow
+ Intel features be detect from CPU by other vendors too.
+
+ Fix hwdetect assembler clobbers.
+ + commit 19b9efd1f47a5de9c450ce8212dfa3174a029c7a
+ * src/hwfeatures.c (detect_x86_64_gnuc): Add missing %ebx assembler
+ clobbers.
+ (detect_x86_64_gnuc, detect_ia32_gnuc) [ENABLE_PADLOCK_SUPPORT]: Add
+ missing %ecx assembler clobbers.
+
+2012-11-21 Werner Koch <wk@gnupg.org>
+
+ Use configure test for aligned attribute.
+ + commit 6368ed542150956ff4ba8170a15bbc534143675c
+ * configure.ac (HAVE_GCC_ATTRIBUTE_ALIGNED): New test and ac_define.
+ * cipher/cipher-internal.h, cipher/rijndael.c, random/rndhw.c: Use new
+ macro instead of a fixed test for __GNUC__.
+
+ Fix segv with AES-NI on some platforms.
+ + commit a96974de734beb51a733a89b3283bcf7b433b54c
+ * cipher/rijndael.c (RIJNDAEL_context): Align on 16 bytes.
+
+2012-11-16 Werner Koch <wk@gnupg.org>
+
+ Improve parsing of the GIT revision number.
+ + commit 4b18e530f417d4af401a3fd721ad2a07e5310e3e
+ * configure.ac (mmm4_revision): Use git rev-parse.
+
+2012-11-08 Werner Koch <wk@gnupg.org>
+
+ Fix extern inline use for gcc > 4.3 in c99 mode.
+ + commit 5abc06114e91beca0177331e1c79815f5fb6d7be
+ * mpi/mpi-inline.h [!G10_MPI_INLINE_DECL]: Take care of changed extern
+ inline semantics in gcc.
+
+2012-11-07 Werner Koch <wk@gnupg.org>
+
+ Fix memory leak in gcry_pk_testkey for ECC.
+ + commit 8cbbad5f94f6e0429fffe66d689aea20f7e35957
+ * cipher/ecc.c (check_secret_key): Restructure for easier allocation
+ tracking. Fix memory leak.
+
+2012-11-05 Werner Koch <wk@gnupg.org>
+
+ Prepare for a backported interface in 1.5.1.
+ + commit 7af98ef78d45e813f47ae4e180a02757a379953f
+ * configure.ac: Bump LT version at C20/A0/R0 to adjust for a planned
+ API update in 1.5.1.
+
+ Adjust for stricter autoconf requirements.
+ + commit 1241fbbc896e9bbad68f1007a17b20493f6cd1af
+ * configure.ac: Fix usage of AC_LANG_PROGRAM.
+
+ Update build helper scripts.
+ + commit a5c4d45e8d12737cd21b095c81da5c18e2afc39e
+ * config.guess, config.sub: Update to version 2012-07-31.
+ * ltmain.sh: Update to version 2.4.2.
+ * install-sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4
+ * m4/lt~obsolete.m4: Update to autoconf 2.69 versions.
+
+ Do not distribute a copy of gitlog-to-changelog.
+ + commit 40976d7da5420453bf93a9c99f0cc4c7044d0774
+ * Makefile.am (GITLOG_TO_CHANGELOG): New.
+ (gen-ChangeLog): Require an installed gitlog-to-changelog.
+ * scripts/gitlog-to-changelog: Remove.
+
+ * README.SVN: Remove.
+ * REMOVE.GIT: New.
+
+ Allow building with w64-mingw32.
+ + commit 4f6fb150558d0ed250bfbd50352c258a4456ba50
+ * autogen.sh <--build-w32>: Support the w64-mingw32 toolchain. Also
+ prepare for 64 bit building.
+ <git-setup>: Remove option -c from chmod.
+
+ Switch to the new automagic beta numbering scheme.
+ + commit 7d5195be76d9dd4adc28976ad153e8f7761c5855
+ * configure.ac: Add all the required m4 magic.
+
+ Avoid dereferencing pointer right after the end.
+ + commit 79502e2c1982047dcf2b776f52826f38bbd9b1fe
+ * mpi/mpicoder.c (do_get_buffer): Check the length before derefing P.
+
+2012-10-30 Werner Koch <wk@gnupg.org>
+
+ Make ancient test program useful again.
+ + commit 66adf76e634423bb72ce1f0b5ed78f4e4798f190
+ * tests/testapi.c (test_sexp): Adjust to current API. Print the
+ return code. Mark unused args.
+ (test_genkey): Mark unused args.
+ (main): Do not pass NULL to printf.
+
+ tests: Add ECC key generation tests.
+ + commit c13164884ade6b1e945cddacce2d244fd881de6b
+ * tests/keygen.c (check_generated_ecc_key): New.
+ (check_ecc_keys): New.
+ (main): Call simple ECC checks.
+
+2012-10-30 Milan Broz <mbroz@redhat.com>
+
+ PBKDF2: Allow empty passphrase.
+ + commit 8528f1ba40e587dc17e02822e529fbd7ac69a189
+ * cipher/kdf.c (gcry_kdf_derive): Allow empty passphrase for PBKDF2.
+ * tests/t-kdf.c (check_pbkdf2): Add test case for above.
+
+2012-08-16 Xi Wang <xi.wang@gmail.com>
+
+ Replace deliberate division by zero with _gcry_divide_by_zero.
+ + commit 2c54c4da19d3a79e9f749740828026dd41f0521a
+ * mpi/mpi-pow.c: Replace 1 / msize.
+ * mpi/mpih-div.c: Replace 1 / dsize.
+ * src/misc.c: Add _gcry_divide_by_zero.
+
+2012-06-21 Werner Koch <wk@gnupg.org>
+
+ Clear AESNI feature flag for x86_64.
+ + commit 2196728e2252917849c1be94417258076767021b
+ * src/hwfeatures.c (_gcry_detect_hw_features) [__x86_64__]: Clear
+ AESNI feature flag.
+
+ Beautify last change.
+ + commit 20e423212c9710ee663e12dd0f62580ceb245a6f
+ * cipher/rijndael.c: Replace C99 feature from last patch. Keep cpp
+ lines short.
+ * random/rndhw.c: Keep cpp lines short.
+ * src/hwfeatures.c (_gcry_detect_hw_features): Make cpp def chain
+ better readable.
+
+2012-06-21 Rafaël Carré <funman@videolan.org>
+
+ Enable VIA Padlock on x86_64 platforms.
+ + commit baf0dc7e9c26167ab43ba2adebcf2f1abc9d9b3b
+ * cipher/rijndael.c: Duplicate x86 assembly and convert to x86_64.
+ * random/rndhw.c: Likewise.
+ * src/hwfeatures.c: Likewise.
+
+2012-05-14 Werner Koch <wk@gnupg.org>
+
+ Add curve aliases from RFC-5656.
+ + commit 39c123b729a472ace039f8536d07f8b9a5f4675a
+ * cipher/ecc.c (curve_aliases): Add "nistp???" entries.
+
+2012-04-16 Werner Koch <wk@gnupg.org>
+
+ State new contribution rules.
+ + commit 3bb858551cd5d84e43b800edfa2b07d1529718a9
+ * doc/DCO: New.
+ * doc/HACKING: Document new rules.
+
+2012-04-04 Tomas Mraz <tmraz@fedoraproject.org>
+
+ Add GCRYCTL_SET_ENFORCED_FIPS_FLAG command.
+ + commit 90e49a11733bfba9c3c505ac487282d35757f682
+ * doc/gcrypt.texi: Add documentation of the new command.
+ * src/fips.c (_gcry_enforced_fips_mode): Report the enforced fips mode
+ only when fips mode is enabled.
+ (_gcry_set_enforced_fips_mode): New function.
+ * src/g10lib.h: Add the _gcry_set_enforced_fips_mode prototype.
+ * src/gcrypt.h.in: Add the GCRYCTL_SET_ENFORCED_FIPS_FLAG.
+ * src/global.c (_gcry_vcontrol): Handle the new command.
+
+2012-02-17 Ulrich Müller <ulm@gentoo.org>
+
+ Rework selftest in idea.c.
+ + commit 70cca617ed75ea292e1fed769114dda5cc1d76f1
+ * cipher/idea.c (do_setkey): Execute selftest when first called.
+ (decrypt_block): Remove commented-out code.
+ (selftest): Execute all selftests. Return NULL on success, or
+ string in case of error.
+
+2012-02-16 Werner Koch <wk@gnupg.org>
+
+ Fix missing prototype.
+ + commit 46035d28c9b413851d43a4008fdc8e4cdf5d686b
+ * src/g10lib.h (_gcry_secmem_module_init): Make it a real prototype.
+
+2012-02-16 Ulrich Müller <ulm@gentoo.org>
+
+ Add support for the IDEA cipher.
+ + commit 318fd85f377c060908d371f792d41e599b3b7483
+ Adapt idea.c to the Libgcrypt framework.
+ Add IDEA to cipher_table and to the build system.
+
+ Patents on IDEA have expired:
+ Europe: EP0482154 on 2011-05-16,
+ Japan: JP3225440 on 2011-05-16,
+ U.S.: 5,214,703 on 2012-01-07.
+
+ * configure.ac: Add idea to the list of available ciphers.
+ Define USE_IDEA if idea is enabled.
+ * cipher/cipher.c (cipher_table): Add entry for IDEA.
+ * cipher/idea.c: Update comment about patents.
+ Include proper header files and remove redundant declarations.
+ (expand_key, cipher, do_setkey, encrypt_block, decrypt_block):
+ Define function arguments as const where appropriate.
+ (cipher): Test for !WORDS_BIGENDIAN instead of LITTLE_ENDIAN_HOST.
+ (do_setkey, decrypt_block): Don't call selftest.
+ (idea_setkey): New function, wrapper for do_setkey.
+ (idea_encrypt): New function, wrapper for encrypt_block.
+ (_gcry_cipher_spec_idea): Define.
+ * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add idea.c.
+ * src/cipher.h (_gcry_cipher_spec_idea): Declare.
+ * tests/basic.c (check_ciphers): Add GCRY_CIPHER_IDEA.
+
+2012-01-09 Werner Koch <wk@gnupg.org>
+
+ Include an IDEA implementation.
+ + commit 6078b05f5340d886e0b9e6cee1d9b5043e0cb210
+ The code is the old IDEA test code, written by me back in 1997 and
+ distributed on a Danish FTP server. This commit is only for
+ reference. To use the code it has to be adjusted to the Libgcrypt
+ framework.
+
+2012-01-03 Marcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
+
+ Fix pthread locking and remove defunctional support for static lock init.
+ + commit 38fcd59ce774eaa3d65f2f7534c989afd860eb56
+ * src/ath.c: Include assert.h.
+ (ath_mutex_destroy, ath_mutex_lock, ath_mutex_unlock): Dereference LOCK.
+ * src/g10lib.h (_gcry_secmem_module_init): New declaration.
+ * src/global.c (global_init): Call _gcry_secmem_module_init.
+ * src/secmem.c (_gcry_secmem_module_init): New function.
+
+2011-12-16 Werner Koch <wk@gnupg.org>
+
+ Add alignment tests for the cipher tests.
+ + commit 14cf1f7e338fedb8edaff5631441746605152bd6
+ * tests/basic.c (check_one_cipher): Factor most code out to
+ check_one_cipher_core. Call that core function several times using
+ different alignment settings.
+ (check_one_cipher_core): New. Add extra args to allow alignment
+ testing.
+
+2011-12-07 Werner Koch <wk@gnupg.org>
+
+ tests/prime: Add option to create a well known private key.
+ + commit 16f5654643d584e3bc739b636752d779176b2191
+ * tests/prime.c (print_mpi, create_42prime): New.
+ (main): Add option --42.
+
+2011-12-01 Werner Koch <wk@gnupg.org>
+
+ Do not build the random-daemon by make distcheck.
+ + commit ea1fb538d99f1ec093f2fef86f4f29176ec27826
+ * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Disable building of the
+ random daemon
+
+ Generate the ChangeLog from commit logs.
+ + commit 137d73191c904926ba529376144ee8239af4ca02
+ * scripts/gitlog-to-changelog: New script. Taken from gnulib.
+ * scripts/git-log-fix: New file.
+ * scripts/git-log-footer: New file.
+ * doc/HACKING: Describe the ChangeLog policy
+ * ChangeLog: New file.
+ * Makefile.am (EXTRA_DIST): Add new files.
+ (gen-ChangeLog): New.
+ (dist-hook): Run gen-ChangeLog.
+
+ Rename all ChangeLog files to ChangeLog-2011.
+
+2011-12-01 Werner Koch <wk@gnupg.org>
+
+ NB: Changes done before December 1st, 2011 are described in
+ per directory files named ChangeLog-2011. See doc/HACKING for
+ details.
+
+ -----
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ Copying and distribution of this file and/or the original GIT
+ commit log messages, with or without modification, are
+ permitted provided the copyright notice and this notice are
+ preserved.
diff --git a/comm/third_party/libgcrypt/ChangeLog-2011 b/comm/third_party/libgcrypt/ChangeLog-2011
new file mode 100644
index 0000000000..3c70a1f8e9
--- /dev/null
+++ b/comm/third_party/libgcrypt/ChangeLog-2011
@@ -0,0 +1,1499 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-11-28 Jim Meyering <meyering@redhat.com>
+
+ accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix
+ * m4/gpg-error.m4: Update from git master.
+
+2011-09-16 Werner Koch <wk@g10code.com>
+
+ * configure.ac (HAVE_PTHREAD): New.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Bump LT version at C19/A0/R0 due to the ABI change.
+
+ * configure.ac (CC_FOR_BUILD): New.
+
+2011-06-29 Werner Koch <wk@g10code.com>
+
+ Release 1.5.0.
+
+ * configure.ac: Keep LT version at C18/A7/R0 because it has
+ already been bumped up at 2010-07-09.
+
+ * config.guess, config.sub: Update to 2011-06-03.
+
+2011-04-06 Werner Koch <wk@g10code.com>
+
+ * configure.ac (emacs_local_vars_begin): Move more to the top to
+ avoid Emacs warnings.
+
+2011-03-30 Werner Koch <wk@g10code.com>
+
+ * compat/compat.c (_gcry_compat_identification): Add version string.
+
+2011-03-08 Werner Koch <wk@g10code.com>
+
+ * configure.ac (BUILD_REVISION): Use new git_brevis macro.
+
+2011-02-23 Werner Koch <wk@g10code.com>
+
+ * configure.ac (LIBGCRYPT_CONFIG_HOST): New.
+
+ * acinclude.m4 (AM_PATH_GPG_ERROR): Remove.
+
+2011-02-21 Werner Koch <wk@g10code.com>
+
+ Release 1.5.0-beta1.
+
+2011-02-18 Werner Koch <wk@g10code.com>
+
+ * configure.ac [GCC]: Remove the use of -fno-strict-aliasing.
+
+2011-02-11 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add option --disbale-aesni-support.
+ (ENABLE_AESNI_SUPPORT): New macro.
+
+2011-02-04 Werner Koch <wk@g10code.com>
+
+ * autogen.sh: Install the git pre-commit if not yet done.
+
+2010-12-23 Werner Koch <wk@g10code.com>
+
+ * configure.ac (BUILD_REVISION): Use git_revision.
+
+2010-08-19 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Define GPG_ERR_ENABLE_ERRNO_MACROS. Remove
+ definition of _GNU_SOURCE.
+ (AC_GNU_SOURCE): New.
+
+2010-08-16 Werner Koch <wk@g10code.com>
+
+ * configure.ac (INSERT_SYS_SELECT_H): New.
+
+2010-07-09 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Bump LT version to C18/A7/R0 to prepare a backport
+ of a new API to the 1.4 series.
+
+2010-04-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Check for -fno-strict-aliasing.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * configure.ac: Print more verbose info at the end.
+
+2010-03-24 Werner Koch <wk@g10code.com>
+
+ * configure.ac (USE_RNDW32CE): New.
+
+2010-03-15 Werner Koch <wk@g10code.com>
+
+ * configure.ac (emacs_local_vars_begin)
+ (emacs_local_vars_read_only, emacs_local_vars_end): New.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * compat/Makefile.am: New.
+ * compat/compat.c: New.
+ * compat/libcompat.h: New.
+ * compat/getpid.c, compat/clock.c: New.
+
+ * configure.ac: Require libgpg-error 1.8.
+ (HAVE_W32CE_SYSTEM): New am_defines and am_conditionals.
+ (getpid): Check for replacement function.
+ (AC_CONFIG_LIBOBJ_DIR): New.
+ (AC_TYPE_PID_T): New.
+ (AM_INIT_AUTOMAKE): Use modern variant.
+ (AC_CONFIG_FILES): Add compat/Makfile.
+ * autogen.sh: Support W32CE.
+ * ltmain.sh: Update to 2.2.6b
+ (wrappers_required): Don't set for mingw32ce.
+ * Makefile.am (DIST_SUBDIRS, SUBDIRS): Add compat.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add option --disable-O-flag-munging.
+
+2009-12-08 Marcus Brinkmann <marcus@g10code.de>
+
+ Update to libtool 2.2.6a.
+ * configure.ac: Invoke AC_CONFIG_MACRO_DIR.
+ (AC_LIBTOOL_WIN32_DLL, AC_LIBTOOL_RC): Replace by ...
+ (LT_PREREQ, LT_INIT, LT_LANG): ... these.
+ * config.guess, config.sub, install-sh, ltmain.sh, m4/libtool.m4:
+ Updated to libtool 2.2.6a.
+ * m4/ltoptions.m4, m4/ltsugar.m4, m4/ltversion.m4,
+ m4/lt~obsolete.m4: New files from libtool 2.2.6a.
+
+2009-08-05 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Test for sys/msg.h.
+
+2009-04-23 Werner Koch <wk@g10code.com>
+
+ * README: Add a section on build problems.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Bump LT version to C17/A6/R0 to mark the start of
+ a new development series.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ Release 1.4.4.
+
+ * configure.ac: Bump LT version to C16/A5/R2.
+
+2008-10-30 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Remove option --enable-gcc-warnings. Autodetect
+ useful gcc warnings in maintainer mode.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ Release 1.4.3.
+
+ * configure.ac: Bump LT version to C16/A5/R1.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Cehck for syslog.
+
+2008-09-08 Werner Koch <wk@g10code.com>
+
+ Release 1.4.2.
+
+2008-09-01 Werner Koch <wk@g10code.com>
+
+ Release 1.4.2rc2.
+
+ * configure.ac: Update svn_revision macro.
+
+2008-08-22 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add option --enable-hmac-binary-check.
+ (DL_LIBS): Check whether -ldl is required.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ Release 1.4.2rc1.
+
+ * configure.ac: Bump LT version to C16/A5/R0.
+
+2008-08-18 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (EXTRA_DIST): Remove the unused BUGS file.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * configure.ac (AH_BOTTOM): Define GCRY_GPG_ERR_NOT_OPERATIONAL.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * random/: New.
+ * Makefile.am (DIST_SUBDIRS): Add random.
+ * configure.ac (AC_CONFIG_FILES): Add random/Makefile.
+
+2008-04-25 Werner Koch <wk@g10code.com>
+
+ Release 1.4.1.
+
+ * configure.ac: Bump LT version to C15/A4/R4.
+
+2008-04-22 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Set version to 1.4.1rc1.
+
+2008-04-18 Werner Koch <wk@g10code.com>
+
+ * configure.ac (AH_BOTTOM): Add CAMELLIA_EXT_SYM_PREFIX.
+ (NAME_OF_DEV_RANDOM): Remove special cases for Solaris etc. This
+ matches the gnupg 1.4.9 version.
+
+2008-04-01 Werner Koch <wk@g10code.com>
+
+ * configure.ac (AC_INIT): Fix quoting.
+
+2008-03-19 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Fix the tests for USE_<algo> to either define or
+ undef the macros. Suggested by Dirk Stoecker.
+
+2008-03-18 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Test for uintptr_t.
+
+2008-02-18 Werner Koch <wk@g10code.com>
+
+ * configure.ac (IS_DEVELOPMENT_VERSION): Set depending on the my_svn.
+
+2007-12-11 Werner Koch <wk@g10code.com>
+
+ * configure.ac: We actually require libgpg-error 1.4. Reported by
+ Tim Mooney.
+
+2007-12-10 Werner Koch <wk@g10code.com>
+
+ Released 1.4.0.
+
+ * configure.ac: Set LT to C15/A4/R3.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add option --disable-padlock-support.
+
+2007-12-03 Werner Koch <wk@g10code.com>
+
+ Released 1.3.2.
+
+ * configure.ac: Set LT to C15/A4/R2.
+
+ * config.sub, config.guess: Update to version 2007-11-19.
+
+2007-10-30 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Protect config.h against double inclusion.
+
+2007-10-26 Werner Koch <wk@g10code.com>
+
+ Released 1.3.1.
+
+ * configure.ac: Set LT to C15/A4/R1.
+
+2007-08-22 Werner Koch <wk@g10code.com>
+
+ * README: Rewrite the license description.
+ * configure.ac (USE_RNDW32, USE_RNDUNIX): Unmark as GPL modules.
+
+2007-08-08 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Use $host and not $target.
+
+2007-07-26 Werner Koch <wk@g10code.com>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Fix a syntax error
+ in the test program which lurked there for 4 years. Adjusted name
+ of libtools global_system_pipe variable and add extra cut stage.
+ Reported by Gregor Riepl.
+
+2007-06-15 Werner Koch <wk@g10code.com>
+
+ * autogen.sh (FORCE): Use = and not == in test to be POSIXly correct.
+
+2007-05-30 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Camellia is no longer GPL.
+
+2007-05-24 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Try to use -Wpointer-arith.
+
+2007-05-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Fix test for optional UDIV and UDIV_QRNND MPI
+ modules.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (ac_cv_mpi_config_done): Unused variable removed.
+ (ac_cv_mpi_mod_list, MPI_MOD_LIST_LO, MPI_MOD_LIST_O): Removed.
+ (MPI_MOD_ASM_MPIH_ADD1, MPI_MOD_ASM_MPIH_SUB1,
+ MPI_MOD_ASM_MPIH_MUL1, MPI_MOD_ASM_MPIH_MUL2,
+ MPI_MOD_ASM_MPIH_MUL3, MPI_MOD_ASM_MPIH_LSHIFT,
+ MPI_MOD_ASM_MPIH_RSHIFT, MPI_MOD_ASM_MPIH_UDIV,
+ MPI_MOD_ASM_MPIH_UDIV_QRNND, MPI_MOD_C_MPIH_ADD1,
+ MPI_MOD_C_MPIH_SUB1, MPI_MOD_C_MPIH_MUL1, MPI_MOD_C_MPIH_MUL2,
+ MPI_MOD_C_MPIH_MUL3, MPI_MOD_C_MPIH_LSHIFT, MPI_MOD_C_MPIH_RSHIFT,
+ MPI_MOD_C_MPIH_UDIV, MPI_MOD_C_MPIH_UDIV_QRNND): New automake
+ variables.
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ Released 1.3.0.
+
+ * configure.ac: Set LT to C15/A4/R0.
+
+ * configure.ac: Require automake 1.10
+ (AM_PROG_CC_C_O): New.
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Fix detection of GPLed random modules.
+
+2007-05-02 Werner Koch <wk@g10code.com>
+
+ * configure.ac (LIBGCRYPT_DIGESTS, LIBGCRYPT_CIPHERS)
+ (LIBGCRYPT_PUBKEY_CIPHERS): Ac_define lists of algorithms.
+ (default_ciphers): Don't make camellia a default.
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * NEWS, configure.ac: Add Camellia.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * README.apichanges: Move to doc/.
+ * Makefile.am (EXTRA_DIST): Removed that file.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Allow to specify additional search directories
+ with --enable-mpi-path.
+
+2007-04-16 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Check for sysconf.
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Try to use sysconf to get the
+ page size and use getpagesize only then if available.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add support for ECC.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Use
+ --enable-random-daemon.
+
+ * configure.ac: New option --enable-random-daemon.
+ Create versioninfo.rc and provide the build information.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * Makefile.am, configure.ac: Ignore w32-dll/.
+
+2007-02-20 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Bump LT version to C14/A3/R0 in preparation for a
+ release.
+
+ * autogen.sh: Add option --force.
+ * configure.ac: New option --disable-endian-check. Use a real
+ noexecstack test instead of requiring an option. Add SVN version
+ magic.
+
+2007-02-02 Werner Koch <wk@g10code.com>
+
+ * configure.ac (FALLBACK_SOCKLEN_T): Special case for mingw32.
+
+2006-11-15 Werner Koch <wk@g10code.com>
+
+ * autogen.sh: Add convenience option --build-amd64.
+
+2006-10-20 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (stowinstall): New convenience target.
+
+2006-10-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (FALLBACK_SOCKLEN_T): Third time is a charm.
+ Define gcry_socklen_t, to avoid conflicts with socklen_t
+ definitions by autoconf.
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (FALLBACK_SOCKLEN_T): Rewrite in terms of
+ socklen.m4.
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * acinclude.m4 (GNUPG_FIX_HDR_VERSION): Removed.
+ * configure.ac: Do not call GNUPG_FIX_HDR_VERSION.
+
+2006-10-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Invoke AC_CHECK_SOCKLEN_TYPE.
+ (AC_CONFIG_FILES): Add src/gcrypt.h.
+ (AC_CONFIG_SRCDIR): Change to src/libgcrypt.vers.
+
+2006-10-02 Werner Koch <wk@g10code.com>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Test on HOST and not
+ TARGET. Hardwire for mingw32. Allow setting via command line when
+ cross compiling.
+
+2006-08-29 Werner Koch <wk@g10code.com>
+
+ * configure.ac (USE_SEED): New.
+
+2006-07-26 Werner Koch <wk@g10code.com>
+
+ * configure.ac: New options --enable-noexecstack and
+ --disable-optimization.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Call AC_LIBTOO_WIN32_DLL and AC_LIBTOOL_RC.
+
+ * configure.ac: Call gl_TYPE_SOCKLEN_T instead of the other
+ socklen_t checks.
+
+2006-06-08 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (PTH_LIBS): Add --all to pth-config invocation.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Check for fctnl and ftruncate.
+ (HAVE_PTH): Check for GNU Pth.
+ (HAVE_W32_SYSTEM): Define it.
+ * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. Taken from GnuPG 1.4.
+
+2005-12-08 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Changed the random device names for netbsd. From
+ Christian Biere.
+
+2005-11-02 Moritz Schulte <moritz@g10code.com>
+
+ * NEWS: Documented minor API changes.
+
+2005-09-15 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (EXTRA_DIST): Depend on README.SVN, not on README.CVS.
+
+2005-06-25 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Removed src/libgcrypt.pc from AC_CONFIG_FILES.
+
+2005-06-10 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Move detection of basic stuff to the top. For
+ example we need to know whether gcc is used before testing for it.
+ Reported by Ralf Fassel.
+
+2005-04-23 Moritz Schulte <moritz@g10code.com>
+
+ * acinclude.m4 (TYPE_SOCKLEN_T): New type definition test;
+ provided by Albert Chin.
+ * configure.ac: Don't use $(CMD) as it's not portable; use CMD in
+ backticks instead. Simpler -lnsl/-lsocket test. Use
+ TYPE_SOCKLEN_T test. Don't forget to set `random_modules'
+ correctly.
+
+2005-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Added support for pkgconfig; provided by Albert
+ Chin.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Integrate Whirlpool.
+
+2005-01-04 Werner Koch <wk@g10code.com>
+
+ Updated to automake 1.9.
+
+ * acinclude.m4: Updated for use with automake 1.9.
+
+ * configure.ac: Require libgpg-error 1.0; not really needed but
+ that is the first stable version.
+
+ * Makefile.am (ACLOCAL_AMFLAGS): New for -I m4.
+ (AUTOMAKE_OPTIONS): New to create a bzip archive.
+
+2005-02-03 Moritz Schulte <moritz@g10code.com>
+
+ * THANKS: Updated.
+
+2004-08-09 Moritz Schulte <moritz@g10code.com>
+
+ * THANKS: Updated.
+
+2004-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * THANKS: Updated.
+
+2004-04-21 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Don't print a warning if GNU make was not found.
+
+2004-05-07 Moritz Schulte <moritz@g10code.de>
+
+ * THANKS: Updated.
+
+2004-04-02 Thomas Schwinge <schwinge@nic-nac-project.de>
+
+ * autogen.sh: Added ACLOCAL_FLAGS.
+
+2004-04-15 Werner Koch <wk@gnupg.org>
+
+ Released 1.2.0.
+
+ * configure.ac: Set LT to C12/A1/R1.
+
+2004-04-06 Werner Koch <wk@gnupg.org>
+
+ * config.guess, config.sub, ltmain.sh: Updated to those from
+ libtools 1.5.4.
+
+2004-03-29 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.94.
+
+ * configure.ac: Set LT to C12/A1/R0.
+
+2004-03-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (LIBGCRYPT_CONFIG_LIBS_PTHREAD,
+ LIBGCRYPT_CONFIG_CFLAGS_PTHREAD, LIBGCRYPT_CONFIG_LIBS_PTH,
+ LIBGCRYPT_CONFIG_CFLAGS_PTH, have_pth, have_pthread, AC_CHECK_PTH,
+ AC_CHECK_LIB(pthread), HAVE_PTH, HAVE_PTHREAD): Removed.
+
+2004-03-06 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.93.
+
+ * configure.ac (LIBGCRYPT_CONFIG_SONAME_NUMBER): Replaced by
+ LIBGCRYPT_CONPIG_API_VERSION. Set it to 1. Set LT to C11/A0/R1.
+
+2004-03-05 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (LIBGCRYPT_CONFIG_SONAME_NUMBER): New.
+
+2004-02-20 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.92.
+
+ * configure.ac: Set LT to C11/A0/R0.
+
+2004-02-11 Werner Koch <wk@gnupg.org>
+
+ * autogen.sh (check_version): Removed bashism and simplified.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Add rfc2268 cipher algorithm.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * THANKS: Updated.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.91.
+
+ * configure.ac: Bumbed LT version to C10/A3/R1.
+
+2003-12-08 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (dist-hook): Don't distribute stuff from the now
+ obsolete scripts dir.
+ (EXTRA_DIST): Remove README_alpha
+ * README-alpha: Removed.
+ * configure.ac (AM_CONFIG_AUX_DIR): Removed.
+
+ * COPYING.DOC: Removed.
+ * Makefile.am (EXTRA_DIST): Added README.CVS and
+ autogen.sh. Removed COPYING.DOC.
+
+2003-11-14 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.90.
+
+ * configure.ac: Bumbed LT version to C10/A3/R0.
+
+ * configure.ac (have_ld_version_script): Set the default in
+ a separate test.
+ (PRINTABLE_OS_NAME): Don't handle the Hurd extra, this leads to
+ conflicts with BSD based GNU systems. The Hurd has now a working
+ uname.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (USE_SHA1): Make sure it is always included.
+ (USE_RMD160): Removed this AM conditional.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Bumbed version number to 1.1.90-cvs for futher
+ development
+
+ Released 1.1.44.
+
+ * acinclude.m4 (AC_CHECK_PTH): Added.
+ * configure.ac: Use it here instead of the generic lib test.
+ Bumbed LT vesion to C9/A2/R0.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Give a hint on where libgpg-error is available.
+ Reformatted long lines. Don't include gcrypt-defs.h.
+ (--enable-gcc-warnings): New option.
+
+2003-10-24 Moritz Schulte <mo@g10code.com>
+
+ * configure.ac: Check for socklen_t.
+
+2003-10-11 Moritz Schulte <mo@g10code.com>
+
+ * acinclude.m4: Update AM_PATH_GPG_ERROR macro.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.43.
+
+ * configure.ac: Require libgpg-error 0.4 due to the prime interface.
+
+2003-08-29 Werner Koch <wk@gnupg.org>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Re-implemented.
+ * configure.ac: Use it here.
+
+2003-08-27 Moritz Schulte <mo@g10code.com>
+
+ * configure.ac: Substitute: LIBGCRYPT_CONFIG_LIBS_PTHREAD,
+ LIBGCRYPT_CONFIG_CFLAGS_PTHREAD, LIBGCRYPT_CONFIG_LIBS_PTH,
+ LIBGCRYPT_CONFIG_CFLAGS_PTH, LIBGCRYPT_THREAD_MODULES.
+
+2003-08-07 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Fail, if libgpg-error could not be found.
+
+2003-07-31 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.42.
+
+ * configure.ac: Set LT version to 7/0/0.
+
+2003-07-30 Werner Koch <wk@gnupg.org>
+
+ * AUTHORS (Maintainer): Assigned Moritz as Maintainer.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * NEWS: Include much more complete list of `Interface changes
+ relative to the 1.1.12 release'.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Bumbed version number up to 1.1.42-cvs.
+
+2003-07-09 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Reintroduce --disable-asm, since it is needed by
+ mpi/config.links.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * README: Few changes, mention libgpg-error.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac (available_ciphers): Removed Serpent, hrrm.
+
+2003-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * acinclude.m4: Removed macro definitions: GNUPG_CHECK_FAQPROG,
+ GNUPG_CHECK_ENDIAN, GNUPG_CHECK_CACHE, GNUPG_CHECK_PIC,
+ GNUPG_CHECK_EXPORTDYNAMIC, GNUPG_CHECK_IPC, GNUPG_PROG_NM,
+ GNUPG_SYS_SYMBOL_UNDERSCORE, GNUPG_FUNC_MKDIR_TAKES_ONE_ARG,
+ GPH_PROG_DB2ANY.
+ Added macro definitions: AM_PATH_GPG_ERROR.
+
+ * configure.ac: Use alternative approach for building based on
+ conditional sources, which does not make automake eat all your
+ memory, etc.
+ Removed unused tests.
+ Renamed --enable-static-rnd to --enable-random.
+ Use Autoconf's AC_C_BIGENDIAN macro instead of our own.
+ Re-organized the whole file.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac (AC_CONFIG_FILES): Removed doc/version.sgml.
+
+2003-06-11 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Remove --enable-libgpg-error flag.
+ Ue AC_PATH_GPG_ERROR.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * NEWS: Mention API changes and libgpg-error.
+
+2003-05-25 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac (USE_LIBGPG_ERROR): Implementation of the
+ --enable-libgpg-error switch.
+ Define USE_LIBGPG_ERROR in LIBGCRYPT_CONFIG_FLAGS, in case
+ libgpg-error is used.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac (AC_CHECK_HEADERS): Removed unused headers:
+ termio.h, langinfo.h.
+ (AC_CHECK_FUNCS): Removed unused functions: strsep, strlwr,
+ tcgetattr, setrlimit, strftime, nl_langinfo, sigaction,
+ sigprocmask, fopen64, fstat64.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * README: Documented new configure switches.
+ Mention the --enable-maintainer-switch.
+
+ * configure.ac: Merged some code from GnuPG's configure.ac for
+ disabling sha512/tiger in case no 64 data types are available.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Include support for sha512.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * AUTHORS: Updated.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Implement command line switches: --enable-ciphers,
+ --enable-pubkey-ciphers and --enable-digests.
+ Set Automake conditionals and config.h symbols depending on the
+ selected ciphers, pubkey-ciphers, digests and random-modules.
+
+ * acinclude.m4 (LIST_MEMBER): New macro.
+
+ * configure.ac: Simplified, removed code for parsing
+ EXTRA_PROGRAMS from Makefile.am.
+
+2003-04-08 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Merged random-module selection code from GnuPG's
+ configure.ac.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Removed code for generating contruct.c.
+ Remove digest modules from the static_modules list, only handle
+ random module selection.
+
+
+2003-03-24 Moritz Schulte <moritz@g10code.com>
+
+ * NEWS: Mention new CBC_MAC flag.
+
+ * AUTHORS (Maintainer): Update entry for Simon Josefsson.
+
+2003-03-04 Moritz Schulte <moritz@g10code.com>
+
+ * TODO: Remove item about resetting handles, since
+ gcry_cipher_reset is implemented by now.
+
+ * NEWS: Mentioned gcry_cipher_reset.
+
+2003-01-21 Werner Koch <wk@gnupg.org>
+
+ * README (Configure options): New.
+ * configure.ac (have_ld_version_script): New option
+ --enable-ld-version-script.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * configure.ac (MODULES_IN_CIPHER): Add crc.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.12.
+
+ * configure.ac (LIBGCRYPT_LT_REVISION): Bumbed up.
+
+2002-12-21 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.11.
+
+ * configure.ac (LIBGCRYPT_LT_CURRENT: Bumbed to 6/5/0 due to a new
+ interface
+
+2002-12-19 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (have_pthread): Check for pthreads in libc.
+ (have_ld_version_script): New.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (MODULES_IN_CIPHER): Add md4.c. By Simon Josefsson.
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.10.
+
+ * configure.ac (HAVE_DEV_RANDOM_IOCTL): Don't check for it; it is
+ not used.
+ (AS_CHECK_HEADERS): Check for sys/select.h.
+ * Makefile.am (DIST_SUBDIRS): New to include the w32-dll directory
+
+2002-09-18 Timo Schulz <ts@winpt.org>
+
+ * configure.ac: Added makefile for the W32 DLL.
+
+2002-09-17 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Check for Pth and Pthreads.
+
+2002-08-23 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.9.
+
+ * configure.ac (LIBGCRYPT_CONFIG_CFLAGS): Renamed from
+ LIBGCRYPT_CFLAGS and removed the libpath because it is set by the
+ config script.
+ (LIBGCRYPT_LT_REVISION): Set LT version to 5/4/1.
+
+2002-06-25 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.8.
+
+ * configure.ac: Set LT version to 5/4/0.
+
+2002-05-21 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.7.
+
+ * configure.ac: Set LT version to 4/3/0.
+
+2002-05-17 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Removed all the dynamic loading stuff.
+
+2002-05-16 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Reordered the C_CHECK_FUNCS.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Adjusted for new MPI module stuff.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license to the LGPL.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * jnlib/: Removed.
+ * Makefile.am (SUBDIRS): Removed jnlib.
+ * configure.ac (jnlib/Makefile): Removed.
+
+ * configure.ac: Define _REENTRANT.
+
+2002-02-18 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (MPI_EXTRA_ASM_OBJS): Use .lo suffix.
+ (AC_CANONICAL_TARGET): Added.
+
+2002-02-07 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.6.
+
+2002-01-24 Werner Koch <wk@gnupg.org>
+
+ * jnlib/: Replaced by a fresh copy from GnuPG (actually the NewPG
+ development branch). Adjusted Makefile.am and jnlib-config.h
+ accordingly.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.5.
+
+ * Makefile.am (dist-hook): Only look in mpi and scripts for
+ distfiles; this way we don't include those of a stale "make dist"
+ directory.
+
+ * acinclude.m4 (GNUPG_FIX_HDR_VERSION): Make it work with the new
+ automake.
+ * configure.ac: Don't chmod db2any.
+
+2001-08-06 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Removed cross compiling hacks.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.4.
+
+ * acinclude.m4 (GNUPG_CHECK_TYPEDEF): Define GNU Source.
+
+ Migrated to autoconf 2.52.
+ * acinclude.m4: Removed GNUPG_LINK_FILES and converted.
+ * acconfig.h: Removed
+ * configure.in: Replaced by...
+ * configure.ac: and modified for use with autoconf 2.52. Replaced
+ GNUPG_LINK_FILES with AC_CONFIG_LINKS and moved some informational
+ messages to the end. Removed --enable-m-debug
+
+ * tests/: New.
+ * Makefile.am: Included tests directory
+
+ * configure.in (DYNLINK_MOD_CFLAGS): Use -shared with dec-osf.
+ Reported by Chris Adams. Merged some cases.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.3.
+
+ * configure.in: Use _gcry_ prefix when creating the cipher constructor.
+
+ * acconfig.h (_GCRYPT_IN_LIBGCRYPT): Define it here.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * acinclude.m4 (GPH_PROG_DOCBOOK): Removed.
+ (GPH_PROG_DB2ANY): New. Taken from GPH.
+ * configure.in: Use it here.
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt. The directory gcrypt has been renamed to src.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ Version 1.1.2 released.
+
+2000-11-13 Werner Koch <wk@gnupg.org>
+
+ * acinclude.m4 (GNUPG_FIX_HDR_VERSION): VPATH build fix.
+
+2000-10-10 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (dist-hook): Create the version file.
+ * configure.in: Set the libtool version here, removed the need
+ for the version file.
+
+Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
+
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Removed that silly mkdir().
+
+ * configure.in: Changes to allow for Solaris random device.
+ By Nils Ellmenreich.
+ (--with-egd-socket): New.
+
+ * configure.in (GNUPG_HOMEDIR): New.
+
+ * configure.in: Check for fstat64 and fopen64
+
+ * acinclude.m4 (GNUPG_CHECK_FAQPROG): New.
+ * configure.in: Test for this.
+
+ * configure.in (DYNLINK_MOD_CFLAGS): Fix by David Champion.
+
+Tue Aug 22 14:31:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ Version 1.1.1
+
+Fri Aug 18 14:27:14 CEST 2000 Werner Koch <wk@openit.de>
+
+ * agent/: New.
+ * Makefile.am, configure.in: Support for the new directory.
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * configure.in (mingw32): Changes to allow for mingw32msvc
+
+Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
+
+ The big merge between this one and the stable branch 1.0. Still need
+ to merge TNANKS, AUTHORS and such. It probaly does not compile yet.
+
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Fixed syntax error in C code.
+
+ * configure.in: Add check for termio.h, wait unctiosn and sigaction.
+
+ * acinclude.m4, configure.in (GNUPG_CHECK_GNUMAKE): New.
+
+ * acinclude.m4 (MKDIR_TAKES_ONE_ARG): Check some headers. By Gaël Quéri.
+
+ * configure.in (AM_INIT_AUTOMAKE): Use this now. By Gaël.
+
+ * acinclude.m4 (GNUPG_CHECK_EXPORTDYNAMIC): Replacement for
+ GNUPG_CHECK_RDYNAMIC which should handle gcc with non GNU ld nicer.
+ Contributed by Dave Dykstra.
+ * configure.in (GNYPG_CHECK_RDYNAMIC): Replaced by the new check.
+
+ * configure.in: Add a test for unisgned long long.
+
+ * configure.in (DYNLINK_MOD_CFLAGS): Set different for NetBSD.
+
+ * configure.in: Add check for clock_gettime
+
+ * configure.in (ALL_LINGUAS): Add nl.
+ * configure.in (ALL_LINGUAS): Add Esperanto.
+ * configure.in (ALL_LINGUAS): Add sv and ja.
+
+ * configure.in: Use /usr/local for CFLAGS and LDFLAGS when
+ target is freebsd. By Rémi.
+
+ * configure.in: Do not set development version when the version has
+ a dash in it. Suggested by Dave Dykstra.
+
+ * configure.in: Removed substitution for doc/gph/Makefile.
+ Do all the gcc warning only in maintainer mode.
+
+ * configure.in (dlopen): Use CHECK_FUNC for a test of dlopen in libc.
+ Suggested by Alexandre Oliva.
+ (-Wall): Moved the settting of gcc warning options near to the end
+ so that tests don't get confused. Suggested by Paul D. Smith.
+
+ * acinclude.m4 (GNUPG_SYS_NM_PARSE): Added BSDI support.
+ (GNUPG_CHECK_RDYNAMIC): Ditto.
+
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Changed the way to test for
+ librt. Test suggested by Jeff Long.
+
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Do librt check only when
+ we can't link a test program. This way GNU systems don't need
+ to link against linrt.
+ (GNUPG_CHECK_IPC): Fixed use of TRY_COMPILE macro. From Tim Mooney.
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add support for
+ DJGPP.
+ (GNUPG_CHECK_MLOCK): Check whether mlock sits in librt.
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Add NetBSD. By Thomas Klausner.
+
+ * acconfig.h (HAVE_MLOCK): Added
+
+Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
+
+ * configure.in: Now uses the Docbook M4s from GPH.
+
+Mon Jan 31 17:46:35 CET 2000 Werner Koch <wk@>
+
+ * Makefile.am: Re-added tools. By Rémi.
+
+Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * configure.in: Create a symlink for types.h in gcrypt/.
+
+Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * configure.in (g10defs.h): Replaced by gnupg-defs.h
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * jnlib/ : New.
+
+ * configure.in: Do set development version when the version has
+ a dash in it. Suggested by Dave Dykstra.
+
+Thu Dec 9 17:22:27 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * acinclude.m4 (GNUPG_FIX_HDR_VERSION): New.
+ * configure.in: Check and fix the version number of gcrypt/gcrypt.h
+ so that it is always the save as VERSION.
+
+Thu Oct 28 16:17:46 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * Started with development series 1.1 on 1999-10-26
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * README-alpha: New
+
+ * configure.in: Fixed quoting in test for development version.
+
+ * THANKS: Add entries for Michael, Brenno and J Horacio who did
+ very nice Howto documents - I apoligize for forgetting to mention them
+ earlier.
+
+Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * configure.in: Add "-lcap" when capabilities are requested.
+ Add the conditional CROSS_COMPILING.
+ * Makefile.am: Don't use checks when CROSS_COMPILING.
+
+
+Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * configure.in (ALL_LINGUAS): Add pt_PT.
+
+ * configure.in: Some tweaks for cross compiling under MingW32
+ * acconfig.h (USE_STATIC_RNDW32): New.
+
+Tue Sep 7 17:08:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * VERSION: Set to 1.0.0.
+
+Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * configure.in: Create makefile in doc/gph
+
+ * acinclude.m4 (GNUPG_FUNC_MKDIR_TAKES_ONE_ARG): New
+ * configure.in: use the above.
+
+Thu Sep 2 16:40:55 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * VERSION: Set to 0.9.11.
+
+Tue Aug 31 17:20:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Minor changes to the OS/2 and Mingw32 system labels.
+ Add a printable name for Hurd.
+
+Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Some support for DJGPP (Mark Elbrecht)
+
+Wed Aug 4 10:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Set to 0.9.10.
+
+Mon Jul 26 09:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): remove init of ac_cv_...
+
+ * Makefile.am (DISCLEANFILES): New
+
+Fri Jul 23 13:53:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Set to 0.9.9.
+
+ * configure.in: Print a notice when rndunix is used.
+
+Thu Jul 15 10:15:35 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Fixed last modification.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Support for libtool.
+ * configure.in: Ditto.
+
+Tue Jun 29 21:44:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (use_local_zlib): The lost dollar is back.
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add EMX case.
+ * configure.in: Another variant of the MX vendor string
+
+ * configure.in (--with-capabilities): Some test code (Remi).
+
+Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Support for HPUX and IRIX.
+ * configure.in (HAVE_DL_SHL_LOAD): New for HPUX (Dave Dykstra).
+
+ * VERSION: Now 0.9.8
+
+Wed Jun 16 20:16:21 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Add test for docbook-to-man
+
+Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_SYS_NM_PARSE): Support for {net,free}bsd,
+
+Thu Jun 10 14:18:23 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (ZLIB,GDBM): Check both, header and lib.
+
+Sat Jun 5 15:30:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * pkclist.c (key_present_in_pk_list): New (Michael).
+
+Tue May 25 19:50:32 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (IS_DEVELOPMENT_VERSION): Fixed detection.
+
+Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): assume yes when
+ cross-compiling.
+
+Mon May 17 21:54:43 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (socket): Fix for Unisys by Katsuhiro Kondou.
+
+Sat May 8 19:28:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * NEWS: Add a marker line which I forgot to do for 0.9.6.
+
+Thu May 6 14:18:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * README: Minor updates
+
+ * VERSION: Now 0.9.6
+
+Thu Apr 8 09:35:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for
+ amiga-openbsd (Peter Reich)
+ (GNUPG_PROG_NM): Ditto
+
+Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am (g10defs.h): Removed.
+ * configure.in (AC_OUTPUT_COMMANDS): Create g10defs.h
+
+Sat Mar 20 12:55:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Now 0.9.5
+
+Sun Mar 14 19:34:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (AM_SYS_SYMBOL_UNDERSCORE): Removed because it is
+ now in the latest libtool.
+
+Thu Mar 11 16:39:46 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Removed the need for libtool
+
+Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (DLSYM_NEEDS_UNDERSCORE): Replaced.
+ * acinclude.in (AM_SYS_SYMBOL_UNDERSCORE): New.
+
+ * VERSION: Now 0.9.4
+
+Sun Feb 28 19:11:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (dld): Test disabled.
+
+Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * encode.c (encode_simple): temporary fix.
+
+Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: New option --enable-static-rnd.
+
+Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * BUGS: Now we assign bug numbers.
+ * OBUGS: New to keep rack o fixed bugs (CVS only)
+
+Fri Feb 19 18:01:54 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Released 0.9.3
+
+Fri Feb 19 15:49:15 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4: Removed gettext macros.
+
+Tue Feb 16 14:10:02 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (socket): Check for -lsocket and -lnsl.
+ (osf4): Disable all warnings for DEC's cc.
+ (-Wall): Add more warning options for gcc
+
+Sat Feb 13 12:04:43 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Changed detection of compiler flags.
+ * intl/ : Removed directory
+
+Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for freebsd 2.2
+
+ * configure.in: a lot of changes to allow selection of modules.
+ Add support for OS/2.
+
+ * acinclude.m4: add some more caching
+
+ * README: Spelling and grammar corrections (John A. Martin)
+ * INSTALL: Ditto.
+
+Wed Jan 20 21:40:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: --enable-m-guard is now default
+
+Wed Jan 13 12:49:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * INSTALL: Applied new information how to build rpms by Fabio Coatti
+ * Makefile.in (gnupg.spec): Changed the names.
+
+Tue Jan 12 11:17:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links (m68k-atari-mint): New
+
+Tue Jan 12 09:17:19 CET 1999 Gaël Quéri <gqueri@mail.dotcom.fr>
+
+ * all: Fixed typos all over the place
+
+Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Add a way to statically link rndunix
+
+Sun Jan 3 15:28:44 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): New.
+ * configure.in (DYNLOAD_CFLAGS): Use result from CHECK_RDYNAMIC
+
+Wed Dec 23 13:18:14 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * README: Replaced the command overview with a short intro.
+
+Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Add check for dlopen in libc (Greg Troxel)
+ and a new define
+ * acconfig.h (DLSYM_NEEDS_UNDERSCORE): New.
+
+Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m (GNUPG_CHECK_PIC): New
+ * configure.in, acinclude.m4: Renamed all WK_ to GNUPG_
+
+Tue Dec 8 15:09:29 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Set to 0.4.5
+
+Wed Nov 25 12:38:29 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (USE_RNDLINUX): New.
+
+Fri Nov 20 19:34:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * VERSION: Released 0.4.4
+
+ * configure.in (try_asm_modules): For option --disable-asm
+
+Tue Nov 10 19:32:40 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (MPI_SFLAGS): New.
+
+Tue Nov 10 13:44:53 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * ABOUT-NLS: New
+ * configure.in (AC_REVISION): New.
+
+Sun Nov 8 18:20:35 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * VERSION: Set to 0.4.3
+
+Sun Oct 25 19:49:37 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (g10defs.h): New macro GNUPG_DATADIR.
+
+Wed Oct 21 17:24:24 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in: Removed gettext kludge
+ * acinclude.m4: Add patched AM_WITH_NKS macro
+
+Tue Oct 20 19:03:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in: Kludge to make AM_GNU_GETTEXT work,
+ changed some macors to more modern versions. Also
+ changeg the all makefiles to remove duplicate ../intl.
+ * acinclude.m4: Removed the gettext stuff, as this
+ already comes with automake now.
+
+Wed Oct 14 12:11:34 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (NAME_OF_DEV_RANDOM): New.
+ (DYNLINK_MOD_CFLAGS): New.
+
+Thu Oct 8 10:55:15 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (g10defs.h): creates include file
+ * acconfig.h: now includes g10defs.h
+ * configure.in: Removed G10_LOCALEDIR and GNUPG_LIB
+
+Thu Sep 17 18:49:40 1998 Werner Koch (wk@(none))
+
+ * Makefile.am (dist-hook): Now creates RPM file.
+ * scripts/gnupg.spec: New template file for RPMs
+
+Thu Jul 30 19:17:07 1998 Werner Koch (wk@(none))
+
+ * acinclude.h (WK_CHECK_IPC): New
+ * configure.in : Add checks for SysV IPC
+
+Thu Jun 25 11:18:49 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (--disable-dynload): New.
+
+Wed Jun 10 07:48:59 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * configure.in (GNUPG_LIBDIR): New.
+
+Mon May 25 19:10:59 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c (fast_random_poll): fixed syntax bug.
+
+Mon May 11 10:21:31 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (PRINTABLE_OS_NAME): Linux is now GNU/Linux
+
+Tue Apr 14 19:08:05 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * [all files]: Applied Matthew Skala's typo and grammar fixes.
+
+Wed Mar 4 10:32:40 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (getrusage,gettimeofday): New tests.
+
+Fri Feb 27 13:14:17 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (--disable-m-guard): New.
+
+Thu Feb 26 17:09:27 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in, acinclude.m4, intl/, po/: New macros taken
+ from GNOME, switched to automake 1.2f
+
+Thu Feb 26 09:05:46 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (doc/Makefile): New
+
+Thu Feb 26 07:40:47 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in: Changed gettext stuff
+
+Wed Feb 25 11:44:10 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * checks/*test : restructured the directory.
+
+Tue Feb 24 15:59:12 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in: Changed the name of the package to GNUPG and
+ chnaged several other names too.
+
+Wed Feb 18 17:36:45 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (checks): New.
+
+Sat Feb 14 15:37:55 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (mpi_config_done): Removed asm links caching.
+
+Sat Feb 14 14:02:20 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (PRINTABLE_OS_NAME): New.
+ * acconfig.h: Likewise.
+
+Fri Feb 13 19:43:41 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in : Fixed zlib stuff
+ * Makefile.am: Likewise
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
+ 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/INSTALL b/comm/third_party/libgcrypt/INSTALL
new file mode 100644
index 0000000000..5458714e1e
--- /dev/null
+++ b/comm/third_party/libgcrypt/INSTALL
@@ -0,0 +1,234 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/comm/third_party/libgcrypt/LICENSES b/comm/third_party/libgcrypt/LICENSES
new file mode 100644
index 0000000000..31f8eae831
--- /dev/null
+++ b/comm/third_party/libgcrypt/LICENSES
@@ -0,0 +1,239 @@
+Additional license notices for Libgcrypt. -*- org -*-
+
+This file contains the copying permission notices for various files in
+the Libgcrypt distribution which are not covered by the GNU Lesser
+General Public License (LGPL) or the GNU General Public License (GPL).
+
+These notices all require that a copy of the notice be included
+in the accompanying documentation and be distributed with binary
+distributions of the code, so be sure to include this file along
+with any binary distributions derived from the GNU C Library.
+
+* BSD_3Clause
+
+ For files:
+ - cipher/sha256-avx-amd64.S
+ - cipher/sha256-avx2-bmi2-amd64.S
+ - cipher/sha256-ssse3-amd64.S
+ - cipher/sha512-avx-amd64.S
+ - cipher/sha512-avx2-bmi2-amd64.S
+ - cipher/sha512-ssse3-amd64.S
+ - cipher/sha512-ssse3-i386.c
+
+#+begin_quote
+ Copyright (c) 2012, Intel Corporation
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+
+ THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#+end_quote
+
+
+ For files:
+ - random/jitterentropy-base.c
+ - random/jitterentropy.h
+ - random/rndjent.c (plus common Libgcrypt copyright holders)
+
+#+begin_quote
+ * Copyright Stephan Mueller <smueller@chronox.de>, 2013
+ *
+ * License
+ * =======
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+#+end_quote
+
+* X License
+
+ For files:
+ - install.sh
+
+#+begin_quote
+ Copyright (C) 1994 X Consortium
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to
+ deal in the Software without restriction, including without limitation the
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+ TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of the X Consortium shall not
+ be used in advertising or otherwise to promote the sale, use or other deal-
+ ings in this Software without prior written authorization from the X Consor-
+ tium.
+#+end_quote
+
+* Public domain
+
+ For files:
+ - cipher/arcfour-amd64.S
+
+#+begin_quote
+ Author: Marc Bevand <bevand_m (at) epita.fr>
+ Licence: I hereby disclaim the copyright on this code and place it
+ in the public domain.
+#+end_quote
+
+* OCB license 1
+
+ For files:
+ - cipher/cipher-ocb.c
+
+#+begin_quote
+ OCB is covered by several patents but may be used freely by most
+ software. See http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm .
+ In particular license 1 is suitable for Libgcrypt: See
+ http://web.cs.ucdavis.edu/~rogaway/ocb/license1.pdf for the full
+ license document; it basically says:
+
+ License 1 — License for Open-Source Software Implementations of OCB
+ (Jan 9, 2013)
+
+ Under this license, you are authorized to make, use, and
+ distribute open-source software implementations of OCB. This
+ license terminates for you if you sue someone over their
+ open-source software implementation of OCB claiming that you have
+ a patent covering their implementation.
+
+
+
+ License for Open Source Software Implementations of OCB
+ January 9, 2013
+
+ 1 Definitions
+
+ 1.1 “Licensor†means Phillip Rogaway.
+
+ 1.2 “Licensed Patents†means any patent that claims priority to United
+ States Patent Application No. 09/918,615 entitled “Method and Apparatus
+ for Facilitating Efficient Authenticated Encryption,†and any utility,
+ divisional, provisional, continuation, continuations-in-part, reexamination,
+ reissue, or foreign counterpart patents that may issue with respect to the
+ aforesaid patent application. This includes, but is not limited to, United
+ States Patent No. 7,046,802; United States Patent No. 7,200,227; United
+ States Patent No. 7,949,129; United States Patent No. 8,321,675 ; and any
+ patent that issues out of United States Patent Application No. 13/669,114.
+
+ 1.3 “Use†means any practice of any invention claimed in the Licensed Patents.
+
+ 1.4 “Software Implementation†means any practice of any invention
+ claimed in the Licensed Patents that takes the form of software executing on
+ a user-programmable, general-purpose computer or that takes the form of a
+ computer-readable medium storing such software. Software Implementation does
+ not include, for example, application-specific integrated circuits (ASICs),
+ field-programmable gate arrays (FPGAs), embedded systems, or IP cores.
+
+ 1.5 “Open Source Software†means software whose source code is published
+ and made available for inspection and use by anyone because either (a) the
+ source code is subject to a license that permits recipients to copy, modify,
+ and distribute the source code without payment of fees or royalties, or
+ (b) the source code is in the public domain, including code released for
+ public use through a CC0 waiver. All licenses certified by the Open Source
+ Initiative at opensource.org as of January 9, 2013 and all Creative Commons
+ licenses identified on the creativecommons.org website as of January 9,
+ 2013, including the Public License Fallback of the CC0 waiver, satisfy these
+ requirements for the purposes of this license.
+
+ 1.6 “Open Source Software Implementation†means a Software
+ Implementation in which the software implicating the Licensed Patents is
+ Open Source Software. Open Source Software Implementation does not include
+ any Software Implementation in which the software implicating the Licensed
+ Patents is combined, so as to form a larger program, with software that is
+ not Open Source Software.
+
+ 2 License Grant
+
+ 2.1 License. Subject to your compliance with the term s of this license,
+ including the restriction set forth in Section 2.2, Licensor hereby
+ grants to you a perpetual, worldwide, non-exclusive, non-transferable,
+ non-sublicenseable, no-charge, royalty-free, irrevocable license to practice
+ any invention claimed in the Licensed Patents in any Open Source Software
+ Implementation.
+
+ 2.2 Restriction. If you or your affiliates institute patent litigation
+ (including, but not limited to, a cross-claim or counterclaim in a lawsuit)
+ against any entity alleging that any Use authorized by this license
+ infringes another patent, then any rights granted to you under this license
+ automatically terminate as of the date such litigation is filed.
+
+ 3 Disclaimer
+ YOUR USE OF THE LICENSED PATENTS IS AT YOUR OWN RISK AND UNLESS REQUIRED
+ BY APPLICABLE LAW, LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+ KIND CONCERNING THE LICENSED PATENTS OR ANY PRODUCT EMBODYING ANY LICENSED
+ PATENT, EXPRESS OR IMPLIED, STATUT ORY OR OTHERWISE, INCLUDING, WITHOUT
+ LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR
+ PURPOSE, OR NONINFRINGEMENT. IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM OR RELATED TO ANY USE OF THE LICENSED PATENTS, INCLUDING,
+ WITHOUT LIMITATION, DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE
+ OR SPECIAL DAMAGES, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGES PRIOR TO SUCH AN OCCURRENCE.
+#+end_quote
diff --git a/comm/third_party/libgcrypt/Makefile.am b/comm/third_party/libgcrypt/Makefile.am
new file mode 100644
index 0000000000..0c622b0e49
--- /dev/null
+++ b/comm/third_party/libgcrypt/Makefile.am
@@ -0,0 +1,158 @@
+## Process this file with automake to produce Makefile.in
+# Copyright (C) 1992, 1999, 2000, 2002 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 <http://www.gnu.org/licenses/>.
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+# Location of the released tarball archives. This is prefixed by
+# the variable RELEASE_ARCHIVE in ~/.gnupg-autogen.rc. For example:
+# RELEASE_ARCHIVE=wk@somehost:archive/tarballs
+RELEASE_ARCHIVE_SUFFIX = libgcrypt/v1.9
+# The variable RELEASE_SIGNING_KEY in ~/.gnupg-autogen.rc is used
+# to specify the key for signing. For example:
+# RELEASE_SIGNKEY=D8692123C4065DEA5E0F3AB5249B39D24F25E3B6
+
+
+ACLOCAL_AMFLAGS = -I m4
+DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon --enable-doc \
+ --enable-random=auto
+
+# (A suitable gitlog-to-changelog script can be found in GnuPG master.)
+GITLOG_TO_CHANGELOG=gitlog-to-changelog
+
+if BUILD_DOC
+doc = doc
+else
+doc =
+endif
+
+
+DIST_SUBDIRS = m4 compat mpi cipher random src doc tests
+SUBDIRS = compat mpi cipher random src $(doc) tests
+
+EXTRA_DIST = autogen.sh autogen.rc README.GIT LICENSES \
+ ChangeLog-2011 build-aux/ChangeLog-2011 doc/ChangeLog-2011 \
+ m4/ChangeLog-2011 cipher/ChangeLog-2011 src/ChangeLog-2011 \
+ random/ChangeLog-2011 tests/ChangeLog-2011 mpi/ChangeLog-2011 \
+ build-aux/git-log-footer build-aux/git-log-fix VERSION
+
+DISTCLEANFILES =
+
+
+# Add all the files listed in "distfiles" files to the distribution
+dist-hook: gen-ChangeLog
+ @set -e; \
+ for file in `cd $(top_srcdir); \
+ find mpi -type f -name distfiles`; do \
+ dir=`dirname $$file` ; $(mkinstalldirs) $(distdir)/$$dir ; \
+ for i in distfiles `cat $(top_srcdir)/$$file` ; do \
+ ln $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i 2> /dev/null \
+ || cp -p $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i; \
+ done ; \
+ done
+
+distcheck-hook:
+ set -e; ( \
+ pref="#+macro: $$(echo $(PACKAGE_NAME)|tr '-' '_')_" ;\
+ reldate="$$(date -u +%Y-%m-%d)" ;\
+ echo "$${pref}ver $(PACKAGE_VERSION)" ;\
+ echo "$${pref}date $${reldate}" ;\
+ list='$(DIST_ARCHIVES)'; for i in $$list; do \
+ case "$$i" in *.tar.bz2) \
+ echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\
+ echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\
+ echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\
+ esac;\
+ done ) | tee $(distdir).swdb
+
+
+
+gen_start_date = 2011-12-01T14:00:00
+.PHONY: gen-ChangeLog
+gen-ChangeLog:
+ if test -e $(top_srcdir)/.git; then \
+ (cd $(top_srcdir) && \
+ $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \
+ --amend=build-aux/git-log-fix \
+ --since=$(gen_start_date) ) > $(distdir)/cl-t; \
+ cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\
+ rm -f $(distdir)/ChangeLog; \
+ mv $(distdir)/cl-t $(distdir)/ChangeLog; \
+ fi
+
+
+
+stowinstall:
+ $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/libgcrypt
+
+# Macro to help the release target.
+RELEASE_NAME = $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)
+
+release:
+ +(set -e;\
+ if [ "$(abs_top_builddir)" = "$(abs_top_srcdir)" ]; then \
+ echo "error: build directory must not be the source directory" >&2;\
+ exit 2;\
+ fi ;\
+ echo "/* Build started at $$(date -uIseconds) */" ;\
+ cd $(top_srcdir); \
+ ./autogen.sh --force; \
+ cd $(abs_top_builddir); \
+ rm -rf dist; mkdir dist ; cd dist ; \
+ $(abs_top_srcdir)/configure --enable-maintainer-mode; \
+ $(MAKE) distcheck; \
+ echo "/* Build finished at $$(date -uIseconds) */" ;\
+ echo "/*" ;\
+ echo " * Please run the final step interactivly:" ;\
+ echo " * make sign-release" ;\
+ echo " */" ;\
+ ) 2>&1 | tee "$(RELEASE_NAME).buildlog"
+
+sign-release:
+ +(set -e; \
+ cd dist; \
+ x=$$(grep '^RELEASE_ARCHIVE=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\
+ if [ -z "$$x" ]; then \
+ echo "error: RELEASE_ARCHIVE missing in ~/.gnupg-autogen.rc">&2; \
+ exit 2;\
+ fi;\
+ myarchive="$$x/$(RELEASE_ARCHIVE_SUFFIX)";\
+ x=$$(grep '^RELEASE_SIGNKEY=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\
+ if [ -z "$$x" ]; then \
+ echo "error: RELEASE_SIGNKEY missing in ~/.gnupg-autogen.rc">&2; \
+ exit 2;\
+ fi;\
+ mysignkey="$$x";\
+ files1="$(RELEASE_NAME).tar.bz2 \
+ $(RELEASE_NAME).tar.gz" ; \
+ files2="$(RELEASE_NAME).tar.bz2.sig \
+ $(RELEASE_NAME).tar.gz.sig \
+ $(RELEASE_NAME).swdb \
+ $(RELEASE_NAME).buildlog" ;\
+ echo "/* Signing the source tarball ..." ;\
+ gpg -sbu $$mysignkey $(RELEASE_NAME).tar.bz2 ;\
+ gpg -sbu $$mysignkey $(RELEASE_NAME).tar.gz ;\
+ cat $(RELEASE_NAME).swdb >swdb.snippet;\
+ echo >>swdb.snippet ;\
+ sha1sum $${files1} >>swdb.snippet ;\
+ cat "../$(RELEASE_NAME).buildlog" swdb.snippet \
+ | gzip >$(RELEASE_NAME).buildlog ;\
+ echo "Copying to archive $$myarchive ..." ;\
+ scp -p $${files1} $${files2} $${myarchive}/ || true;\
+ echo '/*' ;\
+ echo ' * All done; for checksums see dist/swdb.snippet' ;\
+ echo ' */' ;\
+ )
diff --git a/comm/third_party/libgcrypt/Makefile.in b/comm/third_party/libgcrypt/Makefile.in
new file mode 100644
index 0000000000..6c8ca44a45
--- /dev/null
+++ b/comm/third_party/libgcrypt/Makefile.in
@@ -0,0 +1,1019 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 1992, 1999, 2000, 2002 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 <http://www.gnu.org/licenses/>.
+# SPDX-License-Identifier: LGPL-2.1-or-later
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ cscope distdir distdir-am dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/build-aux/compile \
+ $(top_srcdir)/build-aux/config.guess \
+ $(top_srcdir)/build-aux/config.sub \
+ $(top_srcdir)/build-aux/install-sh \
+ $(top_srcdir)/build-aux/ltmain.sh \
+ $(top_srcdir)/build-aux/missing AUTHORS COPYING COPYING.LIB \
+ ChangeLog INSTALL NEWS README THANKS TODO build-aux/compile \
+ build-aux/config.guess build-aux/config.rpath \
+ build-aux/config.sub build-aux/depcomp build-aux/install-sh \
+ build-aux/ltmain.sh build-aux/mdate-sh build-aux/missing \
+ build-aux/texinfo.tex mkinstalldirs
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
+GZIP_ENV = --best
+DIST_TARGETS = dist-bzip2 dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Location of the released tarball archives. This is prefixed by
+# the variable RELEASE_ARCHIVE in ~/.gnupg-autogen.rc. For example:
+# RELEASE_ARCHIVE=wk@somehost:archive/tarballs
+RELEASE_ARCHIVE_SUFFIX = libgcrypt/v1.9
+# The variable RELEASE_SIGNING_KEY in ~/.gnupg-autogen.rc is used
+# to specify the key for signing. For example:
+# RELEASE_SIGNKEY=D8692123C4065DEA5E0F3AB5249B39D24F25E3B6
+ACLOCAL_AMFLAGS = -I m4
+DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon --enable-doc \
+ --enable-random=auto
+
+
+# (A suitable gitlog-to-changelog script can be found in GnuPG master.)
+GITLOG_TO_CHANGELOG = gitlog-to-changelog
+@BUILD_DOC_FALSE@doc =
+@BUILD_DOC_TRUE@doc = doc
+DIST_SUBDIRS = m4 compat mpi cipher random src doc tests
+SUBDIRS = compat mpi cipher random src $(doc) tests
+EXTRA_DIST = autogen.sh autogen.rc README.GIT LICENSES \
+ ChangeLog-2011 build-aux/ChangeLog-2011 doc/ChangeLog-2011 \
+ m4/ChangeLog-2011 cipher/ChangeLog-2011 src/ChangeLog-2011 \
+ random/ChangeLog-2011 tests/ChangeLog-2011 mpi/ChangeLog-2011 \
+ build-aux/git-log-footer build-aux/git-log-fix VERSION
+
+DISTCLEANFILES =
+gen_start_date = 2011-12-01T14:00:00
+
+# Macro to help the release target.
+RELEASE_NAME = $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
+ $(am__post_remove_distdir)
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && $(MAKE) $(AM_MAKEFLAGS) distcheck-hook \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=../.. --prefix="$$dc_install_base" \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--refresh check check-am clean clean-cscope clean-generic \
+ clean-libtool cscope cscopelist-am ctags ctags-am dist \
+ dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \
+ dist-tarZ dist-xz dist-zip distcheck distclean \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-tags distcleancheck distdir distuninstallcheck dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Add all the files listed in "distfiles" files to the distribution
+dist-hook: gen-ChangeLog
+ @set -e; \
+ for file in `cd $(top_srcdir); \
+ find mpi -type f -name distfiles`; do \
+ dir=`dirname $$file` ; $(mkinstalldirs) $(distdir)/$$dir ; \
+ for i in distfiles `cat $(top_srcdir)/$$file` ; do \
+ ln $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i 2> /dev/null \
+ || cp -p $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i; \
+ done ; \
+ done
+
+distcheck-hook:
+ set -e; ( \
+ pref="#+macro: $$(echo $(PACKAGE_NAME)|tr '-' '_')_" ;\
+ reldate="$$(date -u +%Y-%m-%d)" ;\
+ echo "$${pref}ver $(PACKAGE_VERSION)" ;\
+ echo "$${pref}date $${reldate}" ;\
+ list='$(DIST_ARCHIVES)'; for i in $$list; do \
+ case "$$i" in *.tar.bz2) \
+ echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\
+ echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\
+ echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\
+ esac;\
+ done ) | tee $(distdir).swdb
+.PHONY: gen-ChangeLog
+gen-ChangeLog:
+ if test -e $(top_srcdir)/.git; then \
+ (cd $(top_srcdir) && \
+ $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \
+ --amend=build-aux/git-log-fix \
+ --since=$(gen_start_date) ) > $(distdir)/cl-t; \
+ cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\
+ rm -f $(distdir)/ChangeLog; \
+ mv $(distdir)/cl-t $(distdir)/ChangeLog; \
+ fi
+
+stowinstall:
+ $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/libgcrypt
+
+release:
+ +(set -e;\
+ if [ "$(abs_top_builddir)" = "$(abs_top_srcdir)" ]; then \
+ echo "error: build directory must not be the source directory" >&2;\
+ exit 2;\
+ fi ;\
+ echo "/* Build started at $$(date -uIseconds) */" ;\
+ cd $(top_srcdir); \
+ ./autogen.sh --force; \
+ cd $(abs_top_builddir); \
+ rm -rf dist; mkdir dist ; cd dist ; \
+ $(abs_top_srcdir)/configure --enable-maintainer-mode; \
+ $(MAKE) distcheck; \
+ echo "/* Build finished at $$(date -uIseconds) */" ;\
+ echo "/*" ;\
+ echo " * Please run the final step interactivly:" ;\
+ echo " * make sign-release" ;\
+ echo " */" ;\
+ ) 2>&1 | tee "$(RELEASE_NAME).buildlog"
+
+sign-release:
+ +(set -e; \
+ cd dist; \
+ x=$$(grep '^RELEASE_ARCHIVE=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\
+ if [ -z "$$x" ]; then \
+ echo "error: RELEASE_ARCHIVE missing in ~/.gnupg-autogen.rc">&2; \
+ exit 2;\
+ fi;\
+ myarchive="$$x/$(RELEASE_ARCHIVE_SUFFIX)";\
+ x=$$(grep '^RELEASE_SIGNKEY=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\
+ if [ -z "$$x" ]; then \
+ echo "error: RELEASE_SIGNKEY missing in ~/.gnupg-autogen.rc">&2; \
+ exit 2;\
+ fi;\
+ mysignkey="$$x";\
+ files1="$(RELEASE_NAME).tar.bz2 \
+ $(RELEASE_NAME).tar.gz" ; \
+ files2="$(RELEASE_NAME).tar.bz2.sig \
+ $(RELEASE_NAME).tar.gz.sig \
+ $(RELEASE_NAME).swdb \
+ $(RELEASE_NAME).buildlog" ;\
+ echo "/* Signing the source tarball ..." ;\
+ gpg -sbu $$mysignkey $(RELEASE_NAME).tar.bz2 ;\
+ gpg -sbu $$mysignkey $(RELEASE_NAME).tar.gz ;\
+ cat $(RELEASE_NAME).swdb >swdb.snippet;\
+ echo >>swdb.snippet ;\
+ sha1sum $${files1} >>swdb.snippet ;\
+ cat "../$(RELEASE_NAME).buildlog" swdb.snippet \
+ | gzip >$(RELEASE_NAME).buildlog ;\
+ echo "Copying to archive $$myarchive ..." ;\
+ scp -p $${files1} $${files2} $${myarchive}/ || true;\
+ echo '/*' ;\
+ echo ' * All done; for checksums see dist/swdb.snippet' ;\
+ echo ' */' ;\
+ )
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/NEWS b/comm/third_party/libgcrypt/NEWS
new file mode 100644
index 0000000000..69ab074394
--- /dev/null
+++ b/comm/third_party/libgcrypt/NEWS
@@ -0,0 +1,1440 @@
+Noteworthy changes in version 1.9.2 (2021-02-17) [C23/A3/R2]
+------------------------------------------------
+
+ * Bug fixes:
+
+ - Fix build problem for macOS in the random code. [#5268]
+
+ - Fix building with --disable-asm on x86. [#5277]
+
+ - Check public key for ECDSA verify operation. [#5282]
+
+ - Make sure gcry_get_config (NULL) returns a nul-terminated string.
+ [8716e4b2ad]
+
+ - Fix a memory leak in the ECDH code. [289543544e]
+
+ - Fix a reading beyond end of input buffer in SHA2-avx2.
+ [24af2a55d8]
+
+ * Other features:
+
+ - New test driver to allow for standalone regression
+ tests. [b142da4c88]
+
+ Release-info: https://dev.gnupg.org/T5276
+
+
+Noteworthy changes in version 1.9.1 (2021-01-29) [C23/A3/R1]
+------------------------------------------------
+
+ * Bug fixes:
+
+ - Fix exploitable bug in hash functions introduced with 1.9.0.
+ [#5275]
+
+ - Return an error if a negative MPI is used with sexp scan
+ functions. [#4964]
+
+ - Check for operational FIPS in the random and KDF functions.
+ [#5243]
+
+ - Fix compile error on ARMv7 with NEON disabled. [#5251]
+
+ - Fix self-test in KDF module. [#5254]
+
+ - Improve assembler checks for better LTO support. [#5255]
+
+ - Fix assember problem on macOS running on M1. [#5157]
+
+ - Support older macOS without posix_spawn. [#5159]
+
+ - Fix 32-bit cross build on x86. [#5257]
+
+ - Fix non-NEON ARM assembly implementation for SHA512. [#5263]
+
+ - Fix build problems with the cipher_bulk_ops_t typedef. [#5264]
+
+ - Fix Ed25519 private key handling for preceding ZEROs. [#5267]
+
+ - Fix overflow in modular inverse implementation. [#5269]
+
+ - Fix register access for AVX/AVX2 implementations of Blake2.
+ [#5271].
+
+ * Performance:
+
+ - Add optimized cipher and hash functions for s390x/zSeries.
+
+ - Use hardware bit counting functions when available.
+
+ * Internal changes:
+
+ - The macOS getentropy syscall is used when available. [#5268]
+
+ - Update DSA functions to match FIPS 186-3. [30ed9593f6]
+
+ - New self-tests for CMACs and KDFs. [385a89e35b,7a0da24925]
+
+ - Add bulk cipher functions for OFB and GCM modes.
+ [f12b6788f2,f4e63e92dc]
+
+ Release-info: https://dev.gnupg.org/T5259
+
+
+Noteworthy changes in version 1.9.0 (2021-01-19) [C23/A3/R0]
+------------------------------------------------
+
+ * New and extended interfaces:
+
+ - New curves Ed448, X448, and SM2.
+
+ - New cipher mode EAX.
+
+ - New cipher algo SM4.
+
+ - New hash algo SM3.
+
+ - New hash algo variants SHA512/224 and SHA512/256.
+
+ - New MAC algos for Blake-2 algorithms, the new SHA512 variants,
+ SM3, SM4 and for a GOST variant.
+
+ - New convenience function gcry_mpi_get_ui.
+
+ - gcry_sexp_extract_param understands new format specifiers to
+ directly store to integers and strings.
+
+ - New function gcry_ecc_mul_point and curve constants for Curve448
+ and Curve25519. [#4293]
+
+ - New function gcry_ecc_get_algo_keylen.
+
+ - New control code GCRYCTL_AUTO_EXPAND_SECMEM to allow growing the
+ secure memory area. Also in 1.8.2 as an undocumented feature.
+
+ * Performance:
+
+ - Optimized implementations for Aarch64.
+
+ - Faster implementations for Poly1305 and ChaCha. Also for
+ PowerPC. [b9a471ccf5,172ad09cbe,#4460]
+
+ - Optimized implementations of AES and SHA-256 on PowerPC.
+ [#4529,#4530]
+
+ - Improved use of AES-NI to speed up AES-XTS (6 times faster).
+ [a00c5b2988]
+
+ - Improved use of AES-NI for OCB. [eacbd59b13,e924ce456d]
+
+ - Speedup AES-XTS on ARMv8/CE (2.5 times faster). [93503c127a]
+
+ - New AVX and AVX2 implementations for Blake-2 (1.3/1.4 times
+ faster). [af7fc732f9, da58a62ac1]
+
+ - Use Intel SHA extension for SHA-1 and SHA-256 (4.0/3.7 times
+ faster). [d02958bd30, 0b3ec359e2]
+
+ - Use ARMv7/NEON accelerated GCM implementation (3 times faster).
+ [2445cf7431]
+
+ - Use of i386/SSSE3 for SHA-512 (4.5 times faster on Ryzen 7).
+ [b52dde8609]
+
+ - Use 64 bit ARMv8/CE PMULL for CRC (7 times faster). [14c8a593ed]
+
+ - Improve CAST5 (40% to 70% faster). [4ec566b368]
+
+ - Improve Blowfish (60% to 80% faster). [ced7508c85]
+
+ * Bug fixes:
+
+ - Fix infinite loop due to applications using fork the wrong
+ way. [#3491][also in 1.8.4]
+
+ - Fix possible leak of a few bits of secret primes to pageable
+ memory. [#3848][also in 1.8.4]
+
+ - Fix possible hang in the RNG (1.8.3 only). [#4034][also in 1.8.4]
+
+ - Several minor fixes. [#4102,#4208,#4209,#4210,#4211,#4212]
+ [also in 1.8.4]
+
+ - On Linux always make use of getrandom if possible and then use
+ its /dev/urandom behaviour. [#3894][also in 1.8.4]
+
+ - Use blinding for ECDSA signing to mitigate a novel side-channel
+ attack. [#4011,CVE-2018-0495] [also in 1.8.3, 1.7.10]
+
+ - Fix incorrect counter overflow handling for GCM when using an IV
+ size other than 96 bit. [#3764] [also in 1.8.3, 1.7.10]
+
+ - Fix incorrect output of AES-keywrap mode for in-place encryption
+ on some platforms. [also in 1.8.3, 1.7.10]
+
+ - Fix the gcry_mpi_ec_curve_point point validation function.
+ [also in 1.8.3, 1.7.10]
+
+ - Fix rare assertion failure in gcry_prime_check. [also in 1.8.3]
+
+ - Do not use /dev/srandom on OpenBSD. [also in 1.8.2]
+
+ - Fix test suite failure on systems with large pages. [#3351]
+ [also in 1.8.2]
+
+ - Fix test suite to not use mmap on Windows. [also in 1.8.2]
+
+ - Fix fatal out of secure memory status in the s-expression parser
+ on heavy loaded systems. [also in 1.8.2]
+
+ - Fix build problems on OpenIndiana et al. [#4818, also in 1.8.6]
+
+ - Fix GCM bug on arm64 which troubles for example OMEMO. [#4986,
+ also in 1.8.6]
+
+ - Detect a div-by-zero in a debug helper tool. [#4868, also in 1.8.6]
+
+ - Use a constant time mpi_inv and related changes. [#4869, partly
+ also in 1.8.6]
+
+ - Fix mpi_copy to correctly handle flags of opaque MPIs.
+ [also in 1.8.6]
+
+ - Fix mpi_cmp to consider +0 and -0 the same. [also in 1.8.6]
+
+ - Fix extra entropy collection via clock_gettime. Note that this
+ fallback code path is not used on any decent hardware. [#4966,
+ also in 1.8.7]
+
+ - Support opaque MPI with gcry_mpi_print. [#4872, also in 1.8.7]
+
+ - Allow for a Unicode random seed file on Windows. [#5098, also in
+ 1.8.7]
+
+ * Other features:
+
+ - Add OIDs from RFC-8410 as aliases for Ed25519 and Curve25519.
+ [also in 1.8.6]
+
+ - Add mitigation against ECC timing attack CVE-2019-13627. [#4626]
+
+ - Internal cleanup of the ECC implementation.
+
+ - Support reading EC point in compressed format for some curves.
+ [#4951]
+
+ * Interface changes relative to the 1.8.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gcry_mpi_get_ui NEW function.
+ GCRYCTL_AUTO_EXPAND_SECMEM NEW control code.
+ gcry_sexp_extract_param EXTENDED.
+ GCRY_CIPHER_GOST28147_MESH NEW cipher algo.
+ GCRY_CIPHER_SM4 NEW cipher algo.
+ GCRY_CIPHER_MODE_EAX NEW mode.
+ GCRY_ECC_CURVE25519 NEW curve id.
+ GCRY_ECC_CURVE448 NEW curve id.
+ gcry_ecc_get_algo_keylen NEW function.
+ gcry_ecc_mul_point NEW function.
+ GCRY_MD_SM3 NEW hash algo.
+ GCRY_MD_SHA512_256 NEW hash algo.
+ GCRY_MD_SHA512_224 NEW hash algo.
+ GCRY_MAC_GOST28147_IMIT NEW mac algo.
+ GCRY_MAC_HMAC_GOSTR3411_CP NEW mac algo.
+ GCRY_MAC_HMAC_BLAKE2B_512 NEW mac algo.
+ GCRY_MAC_HMAC_BLAKE2B_384 NEW mac algo.
+ GCRY_MAC_HMAC_BLAKE2B_256 NEW mac algo.
+ GCRY_MAC_HMAC_BLAKE2B_160 NEW mac algo.
+ GCRY_MAC_HMAC_BLAKE2S_256 NEW mac algo.
+ GCRY_MAC_HMAC_BLAKE2S_224 NEW mac algo.
+ GCRY_MAC_HMAC_BLAKE2S_160 NEW mac algo.
+ GCRY_MAC_HMAC_BLAKE2S_128 NEW mac algo.
+ GCRY_MAC_HMAC_SM3 NEW mac algo.
+ GCRY_MAC_HMAC_SHA512_256 NEW mac algo.
+ GCRY_MAC_HMAC_SHA512_224 NEW mac algo.
+ GCRY_MAC_CMAC_SM4 NEW mac algo.
+
+ Release-info: https://dev.gnupg.org/T4294
+
+ Release dates of 1.8.x versions:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Version 1.8.2 (2017-12-13)
+ Version 1.8.3 (2018-06-13)
+ Version 1.8.4 (2018-10-26)
+ Version 1.8.5 (2019-08-29)
+ Version 1.8.6 (2020-07-06)
+ Version 1.8.7 (2020-10-23)
+
+
+Noteworthy changes in version 1.8.1 (2017-08-27) [C22/A2/R1]
+------------------------------------------------
+
+ * Bug fixes:
+
+ - Mitigate a local side-channel attack on Curve25519 dubbed "May
+ the Fourth be With You". [CVE-2017-0379] [also in 1.7.9]
+
+ - Add more extra bytes to the pool after reading a seed file.
+
+ - Add the OID SHA384WithECDSA from RFC-7427 to SHA-384.
+
+ - Fix build problems with the Jitter RNG
+
+ - Fix assembler code build problems on Rasbian (ARMv8/AArch32-CE).
+
+
+Noteworthy changes in version 1.8.0 (2017-07-18) [C22/A2/R0]
+------------------------------------------------
+
+ * New interfaces:
+
+ - New cipher mode XTS
+
+ - New hash function Blake-2
+
+ - New function gcry_mpi_point_copy.
+
+ - New function gcry_get_config.
+
+ - GCRYCTL_REINIT_SYSCALL_CLAMP allows to init nPth after Libgcrypt.
+
+ - New global configuration file /etc/gcrypt/random.conf.
+
+ * Extended interfaces:
+
+ - GCRYCTL_PRINT_CONFIG does now also print build information for
+ libgpg-error and the used compiler version.
+
+ - GCRY_CIPHER_MODE_CFB8 is now supported.
+
+ - Add Stribog OIDs. [also in 1.7.4]
+
+ * Performance:
+
+ - A jitter based entropy collector is now used in addition to the
+ other entropy collectors.
+
+ - Optimized gcry_md_hash_buffers for SHA-256 and SHA-512.
+
+ - More ARMv8/AArch32 improvements for AES, GCM, SHA-256, and SHA-1.
+ [also in 1.7.4]
+
+ - Add ARMv8/AArch32 assembly implementation for Twofish and
+ Camellia. [also in 1.7.4]
+
+ - Add bulk processing implementation for ARMv8/AArch32.
+ [also in 1.7.4]
+
+ - Improve the DRBG performance and sync the code with the Linux
+ version. [also in 1.7.4]
+
+ * Internal changes:
+
+ - Libgpg-error 1.25 is now required. This avoids stalling of nPth
+ threads due to contention on internal Libgcrypt locks (e.g. the
+ random pool lock).
+
+ - The system call clamp of libgpg-error is now used to wrap the
+ blocking read of /dev/random. This allows other nPth threads to
+ run while Libgcrypt is gathering entropy.
+
+ - When secure memory is requested by the MPI functions or by
+ gcry_xmalloc_secure, they do not anymore lead to a fatal error if
+ the secure memory pool is used up. Instead new pools are
+ allocated as needed. These new pools are not protected against
+ being swapped out (mlock can't be used). However, these days
+ this is considered a minor issue and can easily be mitigated by
+ using encrypted swap space. [also in 1.7.4]
+
+ * Bug fixes:
+
+ - Fix AES CTR self-check detected failure in the SSSE3 based
+ implementation. [also in 1.7.6]
+
+ - Remove gratuitous select before the getrandom syscall.
+ [also in 1.7.6]
+
+ - Fix regression in mlock detection. [bug#2870] [also in 1.7.5]
+
+ - Fix GOST 28147 CryptoPro-B S-box. [also in 1.7.4]
+
+ - Fix error code handling of mlock calls. [also in 1.7.4]
+
+ - Fix possible timing attack on EdDSA session key. [also in 1.7.7]
+
+ - Fix long standing bug in secure memory implementation which could
+ lead to a segv on free. [bug#3027] [also in 1.7.7]
+
+ - Mitigate a flush+reload side-channel attack on RSA secret keys
+ dubbed "Sliding right into disaster". For details see
+ <https://eprint.iacr.org/2017/627>. [CVE-2017-7526] [also in 1.7.8]
+
+ * Interface changes relative to the 1.7.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gcry_get_config NEW function.
+ gcry_mpi_point_copy NEW function.
+ GCRYCTL_REINIT_SYSCALL_CLAMP NEW macro.
+ GCRY_MD_BLAKE2B_512 NEW constant.
+ GCRY_MD_BLAKE2B_384 NEW constant.
+ GCRY_MD_BLAKE2B_256 NEW constant.
+ GCRY_MD_BLAKE2B_160 NEW constant.
+ GCRY_MD_BLAKE2S_256 NEW constant.
+ GCRY_MD_BLAKE2S_224 NEW constant.
+ GCRY_MD_BLAKE2S_160 NEW constant.
+ GCRY_MD_BLAKE2S_128 NEW constant.
+ GCRY_CIPHER_MODE_XTS NEW constant.
+ gcry_md_info DEPRECATED.
+
+ * Release dates of 1.7.x versions:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Version 1.7.10 (2018-06-13) [C21/A1/R10]
+ Version 1.7.9 (2017-08-27) [C21/A1/R9]
+ Version 1.7.8 (2017-06-29) [C21/A1/R8]
+ Version 1.7.7 (2017-06-02) [C21/A1/R7]
+ Version 1.7.6 (2017-01-18) [C21/A1/R6]
+ Version 1.7.5 (2016-12-15) [C21/A1/R5]
+ Version 1.7.4 (2016-12-09) [C21/A1/R4]
+
+
+Noteworthy changes in version 1.7.3 (2016-08-17) [C21/A1/R3]
+------------------------------------------------
+
+ * Bug fixes:
+
+ - Fix critical security bug in the RNG [CVE-2016-6313]. An
+ attacker who obtains 580 bytes from the standard RNG can
+ trivially predict the next 20 bytes of output. Problem
+ detected by Felix Dörre and Vladimir Klebanov, KIT.
+
+ - Fix building of some asm modules with older compilers and CPUs.
+
+ * Performance:
+
+ - ARMv8/AArch32 improvements for AES, GCM, SHA-256, and SHA-1.
+
+
+Noteworthy changes in version 1.7.2 (2016-07-14) [C21/A1/R2]
+------------------------------------------------
+
+ * Bug fixes:
+
+ - Fix setting of the ECC cofactor if parameters are specified.
+
+ - Fix memory leak in the ECC code.
+
+ - Remove debug message about unsupported getrandom syscall.
+
+ - Fix build problems related to AVX use.
+
+ - Fix bus errors on ARM for Poly1305, ChaCha20, AES, and SHA-512.
+
+ * Internal changes:
+
+ - Improved fatal error message for wrong use of gcry_md_read.
+
+ - Disallow symmetric encryption/decryption if key is not set.
+
+
+Noteworthy changes in version 1.7.1 (2016-06-15) [C21/A1/R1]
+------------------------------------------------
+
+ * Bug fixes:
+
+ - Fix ecc_verify for cofactor support.
+
+ - Fix portability bug when using gcc with Solaris 9 SPARC.
+
+ - Build fix for OpenBSD/amd64
+
+ - Add OIDs to the Serpent ciphers.
+
+ * Internal changes:
+
+ - Use getrandom system call on Linux if available.
+
+ - Blinding is now also used for RSA signature creation.
+
+ - Changed names of debug envvars
+
+
+Noteworthy changes in version 1.7.0 (2016-04-15) [C21/A1/R0]
+------------------------------------------------
+
+ * New algorithms and modes:
+
+ - SHA3-224, SHA3-256, SHA3-384, SHA3-512, and MD2 hash algorithms.
+
+ - SHAKE128 and SHAKE256 extendable-output hash algorithms.
+
+ - ChaCha20 stream cipher.
+
+ - Poly1305 message authentication algorithm
+
+ - ChaCha20-Poly1305 Authenticated Encryption with Associated Data
+ mode.
+
+ - OCB mode.
+
+ - HMAC-MD2 for use by legacy applications.
+
+ * New curves for ECC:
+
+ - Curve25519.
+
+ - sec256k1.
+
+ - GOST R 34.10-2001 and GOST R 34.10-2012.
+
+ * Performance:
+
+ - Improved performance of KDF functions.
+
+ - Assembler optimized implementations of Blowfish and Serpent on
+ ARM.
+
+ - Assembler optimized implementation of 3DES on x86.
+
+ - Improved AES using the SSSE3 based vector permutation method by
+ Mike Hamburg.
+
+ - AVX/BMI is used for SHA-1 and SHA-256 on x86. This is for SHA-1
+ about 20% faster than SSSE3 and more than 100% faster than the
+ generic C implementation.
+
+ - 40% speedup for SHA-512 and 72% for SHA-1 on ARM Cortex-A8.
+
+ - 60-90% speedup for Whirlpool on x86.
+
+ - 300% speedup for RIPE MD-160.
+
+ - Up to 11 times speedup for CRC functions on x86.
+
+ * Other features:
+
+ - Improved ECDSA and FIPS 186-4 compliance.
+
+ - Support for Montgomery curves.
+
+ - gcry_cipher_set_sbox to tweak S-boxes of the gost28147 cipher
+ algorithm.
+
+ - gcry_mpi_ec_sub to subtract two points on a curve.
+
+ - gcry_mpi_ec_decode_point to decode an MPI into a point object.
+
+ - Emulation for broken Whirlpool code prior to 1.6.0. [from 1.6.1]
+
+ - Flag "pkcs1-raw" to enable PCKS#1 padding with a user supplied
+ hash part.
+
+ - Parameter "saltlen" to set a non-default salt length for RSA PSS.
+
+ - A SP800-90A conforming DRNG replaces the former X9.31 alternative
+ random number generator.
+
+ - Map deprecated RSA algo number to the RSA algo number for better
+ backward compatibility. [from 1.6.2]
+
+ - Use ciphertext blinding for Elgamal decryption [CVE-2014-3591].
+ See http://www.cs.tau.ac.il/~tromer/radioexp/ for details.
+ [from 1.6.3]
+
+ - Fixed data-dependent timing variations in modular exponentiation
+ [related to CVE-2015-0837, Last-Level Cache Side-Channel Attacks
+ are Practical]. [from 1.6.3]
+
+ - Flag "no-keytest" for ECC key generation. Due to a bug in
+ the parser that flag will also be accepted but ignored by older
+ version of Libgcrypt. [from 1.6.4]
+
+ - Speed up the random number generator by requiring less extra
+ seeding. [from 1.6.4]
+
+ - Always verify a created RSA signature to avoid private key leaks
+ due to hardware failures. [from 1.6.4]
+
+ - Mitigate side-channel attack on ECDH with Weierstrass curves
+ [CVE-2015-7511]. See http://www.cs.tau.ac.IL/~tromer/ecdh/ for
+ details. [from 1.6.5]
+
+ * Internal changes:
+
+ - Moved locking out to libgpg-error.
+
+ - Support of the SYSROOT envvar in the build system.
+
+ - Refactor some code.
+
+ - The availability of a 64 bit integer type is now mandatory.
+
+ * Bug fixes:
+
+ - Fixed message digest lookup by OID (regression in 1.6.0).
+
+ - Fixed a build problem on NetBSD
+
+ - Fixed memory leaks in ECC code.
+
+ - Fixed some asm build problems and feature detection bugs.
+
+ * Interface changes relative to the 1.6.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gcry_cipher_final NEW macro.
+ GCRY_CIPHER_MODE_CFB8 NEW constant.
+ GCRY_CIPHER_MODE_OCB NEW.
+ GCRY_CIPHER_MODE_POLY1305 NEW.
+ gcry_cipher_set_sbox NEW macro.
+ gcry_mac_get_algo NEW.
+ GCRY_MAC_HMAC_MD2 NEW.
+ GCRY_MAC_HMAC_SHA3_224 NEW.
+ GCRY_MAC_HMAC_SHA3_256 NEW.
+ GCRY_MAC_HMAC_SHA3_384 NEW.
+ GCRY_MAC_HMAC_SHA3_512 NEW.
+ GCRY_MAC_POLY1305 NEW.
+ GCRY_MAC_POLY1305_AES NEW.
+ GCRY_MAC_POLY1305_CAMELLIA NEW.
+ GCRY_MAC_POLY1305_SEED NEW.
+ GCRY_MAC_POLY1305_SERPENT NEW.
+ GCRY_MAC_POLY1305_TWOFISH NEW.
+ gcry_md_extract NEW.
+ GCRY_MD_FLAG_BUGEMU1 NEW [from 1.6.1].
+ GCRY_MD_GOSTR3411_CP NEW.
+ GCRY_MD_SHA3_224 NEW.
+ GCRY_MD_SHA3_256 NEW.
+ GCRY_MD_SHA3_384 NEW.
+ GCRY_MD_SHA3_512 NEW.
+ GCRY_MD_SHAKE128 NEW.
+ GCRY_MD_SHAKE256 NEW.
+ gcry_mpi_ec_decode_point NEW.
+ gcry_mpi_ec_sub NEW.
+ GCRY_PK_EDDSA NEW constant.
+ GCRYCTL_GET_TAGLEN NEW.
+ GCRYCTL_SET_SBOX NEW.
+ GCRYCTL_SET_TAGLEN NEW.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Version 1.6.5 (2016-02-09) [C20/A0/R5]
+Version 1.6.4 (2015-09-08) [C20/A0/R4]
+Version 1.6.3 (2015-02-27) [C20/A0/R3]
+Version 1.6.2 (2014-08-21) [C20/A0/R2]
+Version 1.6.1 (2014-01-29) [C20/A0/R1]
+
+
+Noteworthy changes in version 1.6.0 (2013-12-16) [C20/A0/R0]
+------------------------------------------------
+
+ * Removed the long deprecated gcry_ac interface. Thus Libgcrypt is
+ not anymore ABI compatible to previous versions if they used the ac
+ interface.
+
+ * Removed the module register subsystem.
+
+ * The deprecated message digest debug macros have been removed. Use
+ gcry_md_debug instead.
+
+ * Removed deprecated control codes.
+
+ * Improved performance of most cipher algorithms as well as for the
+ SHA family of hash functions.
+
+ * Added support for the IDEA cipher algorithm.
+
+ * Added support for the Salsa20 and reduced Salsa20/12 stream ciphers.
+
+ * Added limited support for the GOST 28147-89 cipher algorithm.
+
+ * Added support for the GOST R 34.11-94 and R 34.11-2012 (Stribog)
+ hash algorithms.
+
+ * Added a random number generator to directly use the system's RNG.
+ Also added an interface to prefer the use of a specified RNG.
+
+ * Added support for the SCRYPT algorithm.
+
+ * Mitigated the Yarom/Falkner flush+reload side-channel attack on RSA
+ secret keys. See <http://eprint.iacr.org/2013/448> [CVE-2013-4242].
+
+ * Added support for Deterministic DSA as per RFC-6979.
+
+ * Added support for curve Ed25519.
+
+ * Added a scatter gather hash convenience function.
+
+ * Added several MPI amd SEXP helper functions.
+
+ * Added support for negative numbers to gcry_mpi_print,
+ gcry_mpi_aprint and gcry_mpi_scan.
+
+ * The algorithm ids GCRY_PK_ECDSA and GCRY_PK_ECDH are now
+ deprecated. Use GCRY_PK_ECC if you need an algorithm id.
+
+ * Changed gcry_pk_genkey for "ecc" to only include the curve name and
+ not the parameters. The flag "param" may be used to revert this.
+
+ * Added a feature to globally disable selected hardware features.
+
+ * Added debug helper functions.
+
+ * Interface changes relative to the 1.5.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gcry_ac_* REMOVED.
+ GCRY_AC_* REMOVED.
+ gcry_module_t REMOVED.
+ gcry_cipher_register REMOVED.
+ gcry_cipher_unregister REMOVED.
+ gcry_cipher_list REMOVED.
+ gcry_pk_register REMOVED.
+ gcry_pk_unregister REMOVED.
+ gcry_pk_list REMOVED.
+ gcry_md_register REMOVED.
+ gcry_md_unregister REMOVED.
+ gcry_md_list REMOVED.
+ gcry_md_start_debug REMOVED (macro).
+ gcry_md_stop_debug REMOVED (macro).
+ GCRYCTL_SET_KEY REMOVED.
+ GCRYCTL_SET_IV REMOVED.
+ GCRYCTL_SET_CTR REMOVED.
+ GCRYCTL_DISABLE_ALGO CHANGED: Not anymore thread-safe.
+ gcry_pk_genkey CHANGED: ECC curve params not returned.
+ gcry_md_hash_buffers NEW.
+ gcry_buffer_t NEW.
+ GCRYCTL_SET_ENFORCED_FIPS_FLAG NEW.
+ GCRYCTL_SET_PREFERRED_RNG_TYPE NEW.
+ GCRYCTL_GET_CURRENT_RNG_TYPE NEW.
+ GCRYCTL_CLOSE_RANDOM_DEVICE NEW.
+ GCRY_RNG_TYPE_STANDARD NEW.
+ GCRY_RNG_TYPE_FIPS NEW.
+ GCRY_RNG_TYPE_SYSTEM NEW.
+ gcry_mpi_is_neg NEW.
+ gcry_mpi_neg NEW.
+ gcry_mpi_abs NEW.
+ gcry_mpi_snatch NEW.
+ gcry_mpi_set_opaque_copy NEW.
+ gcry_mpi_point_t NEW.
+ gcry_mpi_point_new NEW.
+ gcry_mpi_point_release NEW.
+ gcry_mpi_point_get NEW.
+ gcry_mpi_point_snatch_get NEW.
+ gcry_mpi_point_set NEW.
+ gcry_mpi_point_snatch_set NEW.
+ gcry_ctx_t NEW.
+ gcry_ctx_release NEW.
+ gcry_mpi_ec_new NEW.
+ gcry_mpi_ec_get_mpi NEW.
+ gcry_mpi_ec_get_point NEW.
+ gcry_mpi_ec_set_mpi NEW.
+ gcry_mpi_ec_set_point NEW.
+ gcry_mpi_ec_get_affine NEW.
+ gcry_mpi_ec_dup NEW.
+ gcry_mpi_ec_add NEW.
+ gcry_mpi_ec_mul NEW.
+ gcry_mpi_ec_curve_point NEW.
+ GCRYMPI_FLAG_IMMUTABLE NEW.
+ GCRYMPI_FLAG_CONST NEW.
+ GCRYMPI_FLAG_USER1 NEW.
+ GCRYMPI_FLAG_USER2 NEW.
+ GCRYMPI_FLAG_USER3 NEW.
+ GCRYMPI_FLAG_USER4 NEW.
+ GCRYMPI_CONST_ONE NEW.
+ GCRYMPI_CONST_TWO NEW.
+ GCRYMPI_CONST_THREE NEW.
+ GCRYMPI_CONST_FOUR NEW.
+ GCRYMPI_CONST_EIGHT NEW.
+ GCRYMPI_FMT_OPAQUE NEW.
+ GCRYPT_VERSION_NUMBER NEW.
+ GCRY_KDF_SCRYPT NEW.
+ gcry_pubkey_get_sexp NEW.
+ GCRYCTL_DISABLE_LOCKED_SECMEM NEW.
+ GCRYCTL_DISABLE_PRIV_DROP NEW.
+ GCRY_CIPHER_SALSA20 NEW.
+ gcry_sexp_nth_buffer NEW.
+ gcry_sexp_extract_param NEW.
+ GCRY_CIPHER_SALSA20R12 NEW.
+ GCRY_CIPHER_GOST28147 NEW.
+ GCRY_MD_GOSTR3411_94 NEW.
+ GCRY_MD_STRIBOG256 NEW.
+ GCRY_MD_STRIBOG512 NEW.
+ GCRY_PK_ECC NEW.
+ gcry_log_debug NEW.
+ gcry_log_debughex NEW.
+ gcry_log_debugmpi NEW.
+ gcry_log_debugpnt NEW.
+
+
+Noteworthy changes in version 1.5.0 (2011-06-29)
+------------------------------------------------
+
+ * New function gcry_kdf_derive implementing OpenPGP S2K algorithms
+ and PBKDF2.
+
+ * Support for WindowsCE.
+
+ * Support for ECDH.
+
+ * Support for OAEP and PSS methods as described by RFC-3447.
+
+ * Fixed PKCS v1.5 code to always return the leading zero.
+
+ * New format specifiers "%M" and "%u" for gcry_sexp_build.
+
+ * Support opaque MPIs with "%m" and "%M" in gcry_sexp_build.
+
+ * New functions gcry_pk_get_curve and gcry_pk_get_param to map ECC
+ parameters to a curve name and to retrieve parameter values.
+
+ * gcry_mpi_cmp applied to opaque values has a defined semantic now.
+
+ * Uses the Intel AES-NI instructions if available.
+
+ * The use of the deprecated Alternative Public Key Interface
+ (gcry_ac_*) will now print compile time warnings.
+
+ * The module register subsystem has been deprecated. This subsystem
+ is not flexible enough and would always require ABI changes to
+ extend the internal interfaces. It will eventually be removed.
+ Please contact us on the gcrypt-devel mailing list to discuss
+ whether you really need this feature or how it can be replaced by
+ an internal plugin mechanism.
+
+ * CTR mode may now be used with data chunks of arbitrary length.
+
+ * Changes also done in 1.4.6 (2010-07-13):
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ * New variants of the TIGER algorithm.
+
+ * New cipher algorithm mode for AES-WRAP.
+
+ * Changes also done in 1.4.5 (2009-12-11):
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ * Fixed minor memory leak in DSA key generation.
+
+ * No more switching to FIPS mode if /proc/version is not readable.
+
+ * Fixed sigill during Padlock detection on old CPUs.
+
+ * Fixed a hang on some W2000 machines.
+
+ * Boosted SHA-512 performance by 30% on ia32 boxes and gcc 4.3;
+ SHA-256 went up by 25%.
+
+ * Interface changes relative to the 1.4.6 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GCRY_PK_ECDH NEW.
+ gcry_pk_get_curve NEW.
+ gcry_pk_get_param NEW.
+ GCRYCTL_DISABLE_HWF NEW.
+ gcry_kdf_derive NEW.
+ gcry_pk_encrypt EXTENDED: Support OAEP.
+ gcry_pk_decrypt EXTENDED: Support OAEP.
+ gcry_pk_sign EXTENDED: Support PSS.
+ gcry_pk_verify EXTENDED: Support PSS.
+ gcry_sexp_build EXTENDED: Add format specifiers M and u.
+
+ * Interface changes relative to the 1.4.2 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GCRY_CIPHER_MODE_AESWRAP NEW.
+ GCRY_MD_TIGER1 NEW.
+ GCRY_MD_TIGER2 NEW.
+
+
+Noteworthy changes in version 1.4.4 (2009-01-22)
+------------------------------------------------
+
+ * Publish GCRY_MODULE_ID_USER and GCRY_MODULE_ID_USER_LAST constants.
+ This functionality has been in Libgcrypt since 1.3.0.
+
+ * MD5 may now be used in non-enforced fips mode.
+
+ * Fixed HMAC for SHA-384 and SHA-512 with keys longer than 64 bytes.
+
+ * In fips mode, RSA keys are now generated using the X9.31 algorithm
+ and DSA keys using the FIPS 186-2 algorithm.
+
+ * The transient-key flag is now also supported for DSA key
+ generation. DSA domain parameters may be given as well.
+
+
+Noteworthy changes in version 1.4.3 (2008-09-18)
+------------------------------------------------
+
+ * Try to auto-initialize Libgcrypt to minimize the effect of
+ applications not doing that correctly. This is not a perfect
+ solution but given that many applicationion would totally fail
+ without such a hack, we try to help at least with the most common
+ cases. Folks, please read the manual to learn how to properly
+ initialize Libgcrypt!
+
+ * Auto-initialize the secure memory to 32k instead of aborting the
+ process.
+
+ * Log fatal errors via syslog.
+
+ * Changed the name and the semantics of the fips mode config file.
+
+ * Add convenience macro gcry_fips_mode_active.
+
+ * More self-tests.
+
+ * Documentation cleanups.
+
+
+Noteworthy changes in version 1.4.2 (2008-09-08)
+------------------------------------------------
+
+ * The long missing gcry_mpi_lshift function has been added.
+
+ * RSA key generation now supports a "transient-key" flag.
+
+ * The keygrip computation for ECDSA has been implemented thus ECDSA
+ is now fully supported.
+
+ * A few macros have been replaced by functions for better type
+ checking.
+
+ * The thread initialization structure now carries version
+ information.
+
+ * The manual describes more clearly how to initialize Libgcrypt.
+
+ * The library may now be switched into a FIPS mode.
+
+ * Interface changes relative to the 1.3.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GCRYCTL_OPERATIONAL_P NEW.
+ GCRYCTL_FIPS_MODE_P NEW.
+ GCRYCTL_FORCE_FIPS_MODE NEW.
+ gcry_cipher_setkey NEW: Replaces macro.
+ gcry_cipher_setiv NEW: Replaces macro.
+ gcry_cipher_setctr NEW: Replaces macro.
+ gcry_mpi_lshift NEW.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Noteworthy changes in version 1.4.1 (2008-04-25)
+------------------------------------------------
+
+ * Fixed a bug introduced by 1.3.1 which led to the comsumption of far
+ too much entropy for the intial seeding.
+
+ * Improved AES performance for CFB and CBC modes.
+
+ * Removed build problems for the Padlock support.
+
+
+Noteworthy changes in version 1.4.0 (2007-12-10)
+------------------------------------------------
+
+ * New configure option --disable-padlock-support which is mostly
+ useful in case of build problems.
+
+
+Noteworthy changes in version 1.3.2 (2007-12-03)
+------------------------------------------------
+
+ * The visibility attribute is now used if supported by the toolchain.
+
+ * The ACE engine of VIA processors is now used for AES-128.
+
+ * The ASN.1 DER template for SHA-224 has been fixed.
+
+
+Noteworthy changes in version 1.3.1 (2007-10-26)
+------------------------------------------------
+
+ * The entire library is now under the LGPL. The helper programs and
+ the manual are under the GPL. Kudos to Peter Gutmann for giving
+ permissions to relicense the rndw32 and rndunix modules.
+
+ * The Camellia cipher is now under the LGPL and included by default.
+
+ * Fixed a bug in the detection of symbol prefixes which inhibited the
+ build of optimzied assembler code on certain systems.
+
+ * Updated the entropy gatherer for W32.
+
+
+Noteworthy changes in version 1.3.0 (2007-05-04)
+------------------------------------------------
+
+ * Changed the way the RNG gets initialized. This allows to keep it
+ uninitialized as long as no random numbers are used. To override
+ this, the new macro gcry_fast_random_poll may be used. It is in
+ general a good idea to spread this macro into the application code
+ to make sure that these polls happen often enough.
+
+ * Made the RNG immune against fork without exec.
+
+ * Reading and writing the random seed file is now protected by a
+ fcntl style file lock on systems that provide this function.
+
+ * Support for SHA-224 and HMAC using SHA-384 and SHA-512.
+
+ * Support for the SEED cipher.
+
+ * Support for the Camellia cipher. Note that Camellia is disabled by
+ default, and that enabling it changes the license of libgcrypt from
+ LGPL to GPL.
+
+ * Support for OFB encryption mode.
+
+ * gcry_mpi_rshift does not anymore truncate the shift count.
+
+ * Reserved algorithm ranges for use by applications.
+
+ * Support for DSA2.
+
+ * The new function gcry_md_debug should be used instead of the
+ gcry_md_start_debug and gcry_md_stop_debug macros.
+
+ * New configure option --enable-random-daemon to support a system
+ wide random daemon. The daemon code is experimental and not yet
+ very well working. It will eventually allow to keep a global
+ random pool for the sake of short living processes.
+
+ * Non executable stack support is now used by default on systems
+ supporting it.
+
+ * Support for Microsoft Windows.
+
+ * Assembler support for the AMD64 architecture.
+
+ * New configure option --enable-mpi-path for optimized builds.
+
+ * Experimental support for ECDSA; should only be used for testing.
+
+ * New control code GCRYCTL_PRINT_CONFIG to print the build
+ configuration.
+
+ * Minor changes to some function declarations. Buffer arguments are
+ now typed as void pointer. This should not affect any compilation.
+ Fixed two bugs in return values and clarified documentation.
+
+ * Interface changes relative to the 1.2.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gcry_fast_random_poll NEW
+ gcry_md_debug NEW
+ gcry_sexp_nth_string NEW
+ GCRY_MD_SHA224 NEW
+ GCRY_PK_USAGE_CERT NEW
+ GCRY_PK_USAGE_AUTH NEW
+ GCRY_PK_USAGE_UNKN NEW
+ GCRY_PK_ECDSA NEW
+ GCRY_CIPHER_SEED NEW
+ GCRY_CIPHER_CAMELLIA128 NEW
+ GCRY_CIPHER_CAMELLIA192 NEW
+ GCRY_CIPHER_CAMELLIA256 NEW
+ GCRYCTL_FAKED_RANDOM_P NEW
+ GCRYCTL_PRINT_CONFIG NEW
+ GCRYCTL_SET_RNDEGD_SOCKET NEW.
+ gcry_mpi_scan CHANGED: Argument BUFFER is now void*.
+ gcry_pk_algo_name CHANGED: Returns "?" instead of NULL.
+ gcry_cipher_algo_name CHANGED: Returns "?" instead of "".
+ gcry_pk_spec_t CHANGED: Element ALIASES is now const ptr.
+ gcry_md_write_t CHANGED: Argument BUF is now a const void*.
+ gcry_md_ctl CHANGED: Argument BUFFER is now void*.
+ gcry_cipher_encrypt CHANGED: Arguments IN and OUT are now void*.
+ gcry_cipher_decrypt CHANGED: Arguments IN and OUT are now void*.
+ gcry_sexp_sprint CHANGED: Argument BUFFER is now void*.
+ gcry_create_nonce CHANGED: Argument BUFFER is now void*.
+ gcry_randomize CHANGED: Argument BUFFER is now void*.
+ gcry_cipher_register CHANGED: Argument ALGORITHM_ID is now int*.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Noteworthy changes in version 1.2.0 (2004-04-15)
+------------------------------------------------
+
+ * First stable release.
+
+
+Noteworthy changes in version 1.1.94 (2004-03-29)
+-------------------------------------------------
+
+ * The support for multi-threaded users goes into its third
+ incarnation. We removed compile time support for thread libraries.
+ To support the thread library of your choice, you have to set up
+ callback handlers at initialization time. New data structures, a
+ new control command, and default initializers are provided for this
+ purpose.
+
+ * Interface changes relative to the 1.1.93 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+libgcrypt-config --thread OBSOLETE
+libgcrypt-pth.la REMOVED
+libgcrypt-pthread.la REMOVED
+GCRYCTL_SET_THREAD_CBS NEW
+struct gcrypt_thread_cbs NEW
+enum gcry_thread_option NEW
+GCRY_THREAD_OPTION_PTH_IMPL NEW
+GCRY_THREAD_OPTION_PTHREAD_IMPL NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Noteworthy changes in version 1.1.93 (2004-03-06)
+-------------------------------------------------
+
+ * The automatic thread library detection has finally been removed.
+ From now on, only linking explicitely to libgcrypt, libgcrypt-pth
+ or libgcrypt-pthread is supported.
+
+Noteworthy changes in version 1.1.92 (2004-02-20)
+-------------------------------------------------
+
+ * Minor bug fixes.
+
+ * Included a limited implementation of RFC2268.
+
+ * Changed API of the gcry_ac_ functions. Only a very few programs
+ should be affected by this.
+
+ * Interface changes relative to the 1.1.91 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GCRY_CIPHER_RFC2268_40 NEW.
+gcry_ac_data_set CHANGED: New argument FLAGS.
+gcry_ac_data_get_name CHANGED: New argument FLAGS.
+gcry_ac_data_get_index CHANGED: New argument FLAGS.
+gcry_ac_key_pair_generate CHANGED: New and reordered arguments.
+gcry_ac_key_test CHANGED: New argument HANDLE.
+gcry_ac_key_get_nbits CHANGED: New argument HANDLE.
+gcry_ac_key_get_grip CHANGED: New argument HANDLE.
+gcry_ac_data_search REMOVED.
+gcry_ac_data_add REMOVED.
+GCRY_AC_DATA_FLAG_NO_BLINDING REMOVED.
+GCRY_AC_FLAG_NO_BLINDING NEW: Replaces above.
+
+
+Noteworthy changes in version 1.1.91 (2003-12-19)
+-------------------------------------------------
+
+ * Code cleanups and minor bug fixes.
+
+
+Noteworthy changes in version 1.1.90 (2003-11-14)
+-------------------------------------------------
+
+ * The use of the GCRY_WEAK_RANDOM level is now deprecated in favor of
+ the new gcry_create_nonce function.
+
+ * gcry_sexp_build now supports a "%b" format to include a memory buffer.
+
+ * Minor configuration fixes.
+
+ * Interface changes relative to the 1.1.44 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_create_nonce NEW
+gcry_sexp_build ENHANCED
+
+
+Noteworthy changes in version 1.1.44 (2003-10-31)
+-------------------------------------------------
+
+ * Bug fixes and more code cleanups.
+
+ * Enhanced the prime API.
+
+ * Interface changes relative to the 1.1.43 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_prime_group_generator NEW
+gcry_prime_release_factors NEW
+
+
+Noteworthy changes in version 1.1.43 (2003-09-04)
+-------------------------------------------------
+
+ * Bug fixes and internal code cleanups.
+
+ * Support for the Serpent cipher algorithm.
+
+ * Interface changes relative to the 1.1.42 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_prime_generate NEW
+gcry_prime_check NEW
+
+
+Noteworthy changes in version 1.1.42 (2003-07-31)
+-------------------------------------------------
+
+ * Major API cleanup. Applications need to be converted to the new
+ API. See README.apichanges for hints on how to do that. Backward
+ compatibility is provided where it was possible without too much
+ effort and did not collide with the overall sanitization effort.
+ However, this is only for ease of transition. NO DEPRECATED
+ FUNCTION OR DATA TYPE IS CONSIDERED A PART OF THE API OR ABI AND
+ WILL BE DROPPED IN THE FUTURE WITHOUT CHANGING THE SONAME OF THE
+ LIBRARY.
+
+ * If gcrypt.h is included in sources compiled by GCC 3.1 or later,
+ deprecated attributes will warn about use of obsolete functions and
+ type definitions. You can suppress these warnings by passing
+ -Wno-deprecated-declarations to the gcc command.
+
+ * gcry_check_version must be called from now on to initialize the
+ library, it is not longer optional.
+
+ * Removed `libgcrypt errno' concept.
+
+ * Libgcrypt depends on libgpg-error, a library that provides error
+ codes and according functions for all GnuPG components. Functions
+ that used to return error codes asa `int' have been changed to
+ return a code of type `gcry_error_t'. All GCRYERR_* error symbols
+ have been removed, since they are now contained in libgpg-error
+ (GPG_ERR_*). All functions and types in libgpg-error have also been
+ wrapped in Libgcrypt. The new types are gcry_err_code_t and
+ gcry_err_source_t. The new functions are gcry_err_code,
+ gcry_err_source, gcry_error, gcry_err_make, gcry_error_from_errno,
+ gcry_err_make_from_errno, gcry_err_code_from_errno,
+ gcry_err_code_to_errno, gcry_strsource.
+
+ * New function gcry_mpi_dump to help in debugging.
+
+ * Added alternative interface for asymmetric cryptography.
+
+ * CRC-32, CRC-32 a'la RFC 1510, CRC-24 a'la RFC 2440 are now
+ supported.
+
+ * SHA-256, SHA-384 and SHA-512 are now supported.
+
+ * 128 bit Twofish is now supported.
+
+ * The random module won't print the "not enough random bytes
+ available" anymore. A new progress status is issued instead.
+
+ * CBC-MAC for block ciphers is now supported, by using a
+ GCRY_CIPHER_CBC_MAC cipher flag.
+
+ * CTR mode for block ciphers is now supported.
+
+ * The public RSA exponent can now be specified in key generation.
+
+ * RSA blinding is now supported and is used automatically for RSA
+ decryption. It can be explicitely disabled by using the
+ `no-blinding' symbol in the `flags' S-Expression or by using the
+ GCRY_AC_FLAG_DATA_NO_BLINDING flag when using the ac interface.
+
+ * gcry_sexp_canon_len does not use a `historically encoded' error
+ code anymore.
+
+
+ * Interface changes relative to the 1.1.12 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GCRY_MPI DEPRECATED; Use: gcry_mpi_t
+GcryMPI DEPRECATED; Use: gcry_mpi_t
+GCRY_SEXP DEPRECATED; Use: gcry_sexp_t
+GcrySexp DEPRECATED; Use: gcry_sexp_t
+GCRY_CIPHER_HD DEPRECATED; Use: gcry_cipher_hd_t
+GcryCipherHd DEPRECATED; Use: gcry_cipher_hd_t
+GCRY_MD_HD DEPRECATED; Use: gcry_md_hd_t
+GcryMDHd DEPRECATED; Use: gcry_md_hd_t
+gcry_error_t NEW
+gcry_err_code_t NEW
+gcry_err_source_t NEW
+gcry_err_make NEW
+gcry_error NEW
+gcry_err_code NEW
+gcry_err_source NEW
+gcry_err_code_from_errno NEW
+gcry_err_code_to_errno NEW
+gcry_err_make_from_errno NEW
+gcry_error_from_errno NEW
+gcry_strsource NEW
+GCRYERR_{some error code} REMOVED; Use GPG_ERR_*
+ from libgpg-error instead.
+gcry_errno REMOVED
+gcry_sexp_canon_len CHANGED
+gcry_sexp_build_array NEW
+gcry_mpi_scan CHANGED: New argument to separate in/out args.
+gcry_mpi_print CHANGED: Ditto.
+gcry_mpi_dump NEW
+gcry_cipher_open CHANGED
+gcry_cipher_reset NEW
+gcry_cipher_register NEW
+gcry_cipher_unregister NEW
+gcry_cipher_list NEW
+gcry_cipher_algo_keylen REPLACED macro with function.
+gcry_cipher_algo_blklen REPLACED macro with function.
+gcry_pk_register NEW
+gcry_pk_unregister NEW
+gcry_pk_list NEW
+gcry_pk_decrypt ENHANCED: Allows flag to return
+ complete S-expression.
+gcry_md_open CHANGED
+gcry_md_copy CHANGED
+gcry_md_is_enabled NEW
+gcry_md_is_secure NEW
+gcry_md_register NEW
+gcry_md_unregister NEW
+gcry_md_list NEW
+gcry_ac_data_t NEW
+gcry_ac_key_t NEW
+gcry_ac_key_pair_t NEW
+gcry_ac_handle_t NEW
+gcry_ac_key_spec_rsa_t NEW
+gcry_ac_data_new NEW
+gcry_ac_data_destroy NEW
+gcry_ac_data_set NEW
+gcry_ac_data_copy NEW
+gcry_ac_data_length NEW
+gcry_ac_data_get_name NEW
+gcry_ac_data_get_index NEW
+gcry_ac_data_clear NEW
+gcry_ac_open NEW
+gcry_ac_close NEW
+gcry_ac_key_init NEW
+gcry_ac_key_pair_generate NEW
+gcry_ac_key_pair_extract NEW
+gcry_ac_key_data_get NEW
+gcry_ac_key_test NEW
+gcry_ac_key_get_nbits NEW
+gcry_ac_key_get_grip NEW
+gcry_ac_key_destroy NEW
+gcry_ac_key_pair_destroy NEW
+gcry_ac_data_encrypt NEW
+gcry_ac_data_decrypt NEW
+gcry_ac_data_sign NEW
+gcry_ac_data_verify NEW
+gcry_ac_id_to_name NEW
+gcry_ac_name_to_id NEW
+gcry_handler_progress_t NEW
+gcry_handler_alloc_t NEW
+gcry_handler_secure_check_t NEW
+gcry_handle_realloc_t NEW
+gcry_handler_free_t NEW
+gcry_handler_no_mem_t NEW
+gcry_handler_error_t NEW
+gcry_handler_log_t NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Noteworthy changes in version 1.1.12 (2003-01-20)
+-------------------------------------------------
+
+ * gcry_pk_sign, gcry_pk_verify and gcry_pk_encrypt can now handle an
+ optional pkcs1 flags parameter in the S-expression. A similar flag
+ may be passed to gcry_pk_decrypt but it is only syntactically
+ implemented.
+
+ * New convenience macro gcry_md_get_asnoid.
+
+ * There is now some real stuff in the manual.
+
+
+Noteworthy changes in version 1.1.11 (2002-12-21)
+-------------------------------------------------
+
+ * Don't export internal symbols anymore (currently only for GNU systems)
+
+ * New algorithm: MD4
+
+ * Implemented ciphertext stealing.
+
+ * Smaller bugs fixes and a few new OIDs.
+
+ * Interface changes relative to the 1.1.8 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_cipher_cts NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Noteworthy changes in version 1.1.10 (2002-09-20)
+-------------------------------------------------
+
+ * Fixed shared library builds for i386, PPC and Sparc.
+
+ * Added simple benchmark tool.
+
+ * Replaced the internal mutexes by code which automatically adapts to
+ the used threading library. Currently Pth and Pthread are
+ supported. For non-ELF systems the GNU toolchain is now required..
+
+ * Added untested support to build Windows DLLs.
+
+Noteworthy changes in version 1.1.9 (2002-08-23)
+------------------------------------------------
+
+ * Support for plain old DES.
+
+
+Noteworthy changes in version 1.1.8 (2002-06-25)
+------------------------------------------------
+
+ * Minor cleanups and exported a few new functions.
+
+ * Interface changes relative to the 1.1.7 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_mpi_div NEW
+gcry_mpi_mod NEW
+gcry_mpi_invm NEW
+gcry_mpi_swap NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Noteworthy changes in version 1.1.7 (2002-05-21)
+------------------------------------------------
+
+* Libgcrypt is now distributed under the terms of the GNU Lesser
+ General Public License; see the README file for details.
+
+* It is possible to use libgcrypt w/o intialized secure memory.
+
+* Libgcrypt should now be thread safe after the initialization.
+ gcry_control (GCRYCRL_INITIALIZATION_FINISHED,NULL,0) should have
+ been called before creating additional threads.
+
+ * Interface changes relative to the 1.1.6 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GCRYCTL_DISABLE_INTERNAL_LOCKING NEW
+GCRYCTL_DISABLE_SECMEM NEW
+GCRYCTL_INITIALIZATION_FINISHED NEW
+GCRYCTL_INITIALIZATION_FINISHED_P NEW
+GCRYCTL_ANY_INITIALIZATION_P NEW
+gcry_strdup NEW
+gcry_sexp_create NEW
+gcry_sexp_new NEW
+gcry_set_progress_handler NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Noteworthy changes in version 1.1.6 (2002-02-07)
+------------------------------------------------
+
+ * Enhanced the S-expression conversion functions.
+
+Noteworthy changes in version 1.1.5 (2001-12-18)
+------------------------------------------------
+
+ * gcry_{cipher,md}_map_name are now able to map stringified object IDs.
+
+ * New functions gcry_sexp_canon_len and gcry_cipher_mode_from_oid.
+
+ * Closed some memory leaks.
+
+
+Noteworthy changes in version 1.1.4 (2001-08-03)
+------------------------------------------------
+
+ * Arcfour does now work.
+
+ * Some minor fixes.
+
+ * Added a first test program
+
+ * Migrated to autoconf 2.52.
+
+
+Noteworthy changes in version 1.1.3 (2001-05-31)
+------------------------------------------------
+
+ * First release of Libgcrypt which is a result of splitting GnuPG
+ into into libgcrypt and GnuPG.
+
+
+Copyright 2001, 2002, 2003, 2004, 2007, 2008,
+ 2009, 2011 Free Software Foundation, Inc.
+Copyright 2013 g10 Code GmbH
+
+This file is free software; as a special exception the author gives
+unlimited permission to copy and/or distribute it, with or without
+modifications, as long as this notice is preserved.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/comm/third_party/libgcrypt/README b/comm/third_party/libgcrypt/README
new file mode 100644
index 0000000000..1304669a1c
--- /dev/null
+++ b/comm/third_party/libgcrypt/README
@@ -0,0 +1,276 @@
+ Libgcrypt - The GNU Crypto Library
+ ------------------------------------
+ Version 1.9
+
+ Copyright (C) 1989,1991-2018 Free Software Foundation, Inc.
+ Copyright (C) 2012-2021 g10 Code GmbH
+ Copyright (C) 2013-2021 Jussi Kivilinna
+
+ Libgcrypt is free software. See the file AUTHORS for full copying
+ notices, and LICENSES for notices about contributions that require
+ these additional notices to be distributed.
+
+
+ Overview
+ --------
+
+ Libgcrypt is a general purpose crypto library based on the code
+ used in GnuPG. Libgcrypt depends on the library `libgpg-error',
+ which must be installed correctly before Libgcrypt is to be built.
+ Libgcrypt is distributed under the LGPL, see the section "License"
+ below for details.
+
+
+ Build Instructions
+ ------------------
+
+ The download canonical location for libgcrypt is:
+
+ ftp://ftp.gnupg.org/gcrypt/libgcrypt/
+ or
+ https://gnupg.org/ftp/gcrypt/libgcrypt/
+
+ To build libgcrypt you need libgpg-error:
+
+ ftp://ftp.gnupg.org/gcrypt/libgpg-error/
+ or
+ https://gnupg.org/ftp/gcrypt/libgpg-error/
+
+ You should get the latest versions of course.
+
+ After building and installing the libgpg-error package, you may
+ continue with Libgcrypt installation as with allmost all GNU
+ packages, you just have to do
+
+ ./configure
+ make
+ make check
+ make install
+
+ The "make check" is not required but a good idea to see whether
+ the library works as expected. The check takes some while and
+ prints some benchmarking results. Before doing "make install" you
+ probably need to become root.
+
+ To build libgcrypt for Microsoft Windows, you need to have the
+ mingw32 cross-building toolchain installed. Instead of running a
+ plain configure you use
+
+ ./autogen.sh --build-w32
+ make
+ make install
+
+ By default this command sequences expectsd a libgpg-error
+ installed below $HOME/w32root and installs libgcrypt to that
+ directory too. See the autogen.sh code for details.
+
+ The documentation is available as an Info file (gcrypt.info). To
+ build documentation in PDF, run this:
+
+ cd doc
+ make pdf
+
+
+
+ Mailing List
+ ------------
+
+ You may want to join the developer's mailing list
+ gcrypt-devel@gnupg.org by sending mail with a subject of
+ "subscribe" to gcrypt-devel-request@gnupg.org. An archive of this
+ list is available at https://lists.gnupg.org .
+
+
+ Configure options
+ -----------------
+ Here is a list of configure options which are sometimes useful
+ for installation.
+
+ --enable-large-data-tests
+ With this option a "make check" will take really
+ long due to extra checks for the hash algorithms.
+
+ --enable-m-guard
+ Enable the integrated malloc checking code. Please
+ note that this feature does not work on all CPUs
+ (e.g. SunOS 5.7 on UltraSparc-2) and might give
+ you a bus error.
+
+ --disable-asm
+ Do not use assembler modules. It is not possible
+ to use this on some CPU types.
+
+ --enable-ld-version-script
+ Libgcrypt tries to build a library where internal
+ symbols are not exported. This requires support
+ from ld and is currently enabled for a few OSes.
+ If you know that your ld supports the so called
+ ELF version scripts, you can use this option to
+ force its use. OTOH, if you get error message
+ from the linker, you probably want to use this
+ option to disable the use of version scripts.
+ Note, that you should never ever use an
+ undocumented symbol or one which is prefixed with
+ an underscore.
+
+ --enable-ciphers=list
+ --enable-pubkey-ciphers=list
+ --enable-digests=list
+ If not otherwise specified, all algorithms
+ included in the libgcrypt source tree are built.
+ An exception are algorithms, which depend on
+ features not provided by the system, like 64bit
+ data types. With these switches it is possible
+ to select exactly those algorithm modules, which
+ should be built. The algorithms are to be
+ separated by spaces, commas or colons. To view
+ the list used with the current build the program
+ tests/version may be used.
+
+ --disable-endian-check
+ Don't let configure test for the endianness but
+ try to use the OS provided macros at compile
+ time. This is helpful to create OS X fat binaries.
+
+ --enable-random-daemon
+ Include support for a global random daemon and
+ build the daemon. This is an experimental feature.
+
+ --enable-mpi-path=EXTRA_PATH
+ Prepend EXTRA_PATH to list of CPU specific
+ optimizations. For example, if you want to add
+ optimizations forn a Intel Pentium 4 compatible
+ CPU, you may use
+ --enable-mpi-path=pentium4/sse2:pentium4/mmx
+ Take care: The generated library may crash on
+ non-compatible CPUs.
+
+ --enable-random=NAME
+ Force the use of the random gathering module
+ NAME. Default is either to use /dev/random or
+ the auto mode. Possible values for NAME are:
+ egd - Use the module which accesses the
+ Entropy Gathering Daemon. See the webpages
+ for more information about it.
+ unix - Use the standard Unix module which does not
+ have a very good performance.
+ linux - Use the module which accesses /dev/random.
+ This is the first choice and the default one
+ for GNU/Linux or *BSD.
+ auto - Compile linux, egd and unix in and
+ automagically select at runtime.
+
+ --enable-hmac-binary-check
+ Include support to check the binary at runtime
+ against a HMAC checksum. This works only in FIPS
+ mode and on systems providing the dladdr function.
+
+ --disable-padlock-support
+ Disable support for the PadLock engine of VIA
+ processors. The default is to use PadLock if
+ available. Try this if you get problems with
+ assembler code.
+
+ --disable-aesni-support
+ Disable support for the AES-NI instructions of
+ newer Intel CPUs. The default is to use AES-NI
+ if available. Try this if you get problems with
+ assembler code.
+
+ --disable-O-flag-munging
+ Some code is too complex for some compilers while
+ in higher optimization modes, thus the compiler
+ invocation is modified to use a lower
+ optimization level. Usually this works very well
+ but on some platforms these rules break the
+ invocation. This option may be used to disable
+ the feature under the assumption that either good
+ CFLAGS are given or the compiler can grok the code.
+
+
+
+
+ Build Problems
+ --------------
+
+ If you have a problem with a a certain release, please first check
+ the Release-info URL given in the NEWS file.
+
+ We can't check all assembler files, so if you have problems
+ assembling them (or the program crashes) use --disable-asm with
+ ./configure. If you opt to delete individual replacement files in
+ hopes of using the remaining ones, be aware that the configure
+ scripts may consider several subdirectories to get all available
+ assembler files; be sure to delete the correct ones. Never delete
+ udiv-qrnnd.S in any CPU directory, because there may be no C
+ substitute (in mpi/genereic). Don't forget to delete
+ "config.cache" and run "./config.status --recheck". We got a few
+ reports about problems using versions of gcc earlier than 2.96
+ along with a non-GNU assembler (as). If this applies to your
+ platform, you can either upgrade gcc to a more recent version, or
+ use the GNU assembler.
+
+ Some make tools are broken - the best solution is to use GNU's
+ make. Try gmake or grab the sources from a GNU archive and
+ install them.
+
+ Specific problems on some machines:
+
+ * IBM RS/6000 running AIX
+
+ Due to a change in gcc (since version 2.8) the MPI stuff may
+ not build. In this case try to run configure using:
+ CFLAGS="-g -O2 -mcpu=powerpc" ./configure
+
+ * SVR4.2 (ESIX V4.2 cc)
+
+ Due to problems with the ESIX as(1), you probably want to do:
+ CFLAGS="-O -K pentium" ./configure --disable-asm
+
+ * SunOS 4.1.4
+
+ ./configure ac_cv_sys_symbol_underscore=yes
+
+ * Sparc64 CPUs
+
+ We have reports about failures in the AES module when
+ compiling using gcc (e.g. version 4.1.2) and the option -O3;
+ using -O2 solves the problem.
+
+
+ License
+ -------
+
+ The library is distributed under the terms of the GNU Lesser
+ General Public License (LGPL); see the file COPYING.LIB for the
+ actual terms.
+
+ The helper programs as well as the documentation are distributed
+ under the terms of the GNU General Public License (GPL); see the
+ file COPYING for the actual terms.
+
+ The file LICENSES has notices about contributions that require
+ that these additional notices are distributed.
+
+
+ Contact
+ -------
+
+ See the file AUTHORS.
+
+ Commercial grade support for Libgcrypt is available; for a listing
+ of offers see https://www.gnupg.org/service.html .
+
+ Since 2001 maintenance and development of Libgcrypt is done by g10
+ Code GmbH and mostly financed by donations. g10 Code currently
+ employs 3 full-time developers and two contractors. They all work
+ on GnuPG and closely related software like Libgcrypt. Please
+ visit https://gnupg.org/donate/ to see how you can help.
+
+ This file is Free Software; as a special exception the authors gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved. For conditions
+ of the whole package, please see the file COPYING. This file is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY, to the extent permitted by law; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/comm/third_party/libgcrypt/README.GIT b/comm/third_party/libgcrypt/README.GIT
new file mode 100644
index 0000000000..ee2c6383f4
--- /dev/null
+++ b/comm/third_party/libgcrypt/README.GIT
@@ -0,0 +1,49 @@
+If you are building from GIT, run the script
+
+./autogen.sh
+
+first, to make sure that you have all the necessary maintainer tools
+are installed and to build the actual configuration files. If you
+have just checked out from GIT, you should add the option "--force" to
+autogen.sh so that meta data is noticed by autom4te.cache. Then run
+
+./configure --enable-maintainer-mode
+
+followed by the usual make.
+
+If autogen.sh complains about insufficient versions of the required
+tools, or the tools are not installed, you may use environment
+variables to override the default tool names:
+
+ AUTOMAKE_SUFFIX is used as a suffix for all tools from the automake
+ package. For example
+ AUTOMAKE_SUFFIX="-1.7" ./autogen.sh
+ uses "automake-1.7" and "aclocal-1.7.
+ AUTOMAKE_PREFIX is used as a prefix for all tools from the automake
+ page and may be combined with AUTOMAKE_SUFFIX. e.g.:
+ AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh
+ uses "automake" and "aclocal" in the /usr/foo/bin
+ directory.
+ AUTOCONF_SUFFIX is used as a suffix for all tools from the automake
+ package
+ AUTOCONF_PREFIX is used as a prefix for all tools from the automake
+ package
+ GETTEXT_SUFFIX is used as a suffix for all tools from the gettext
+ package
+ GETTEXT_PREFIX is used as a prefix for all tools from the gettext
+ package
+
+It is also possible to use the variable name AUTOMAKE, AUTOCONF,
+ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name
+of the programs to run. It is however better to use the suffix and
+prefix forms as described above because that does not require
+knowledge about the actual tools used by autogen.sh.
+
+
+Please don't use autopoint, libtoolize or autoreconf unless you are
+the current maintainer and want to update the standard configuration
+files. All those files should be in GIT and only updated manually
+if the maintainer decides that newer versions are required. The
+maintainer should also make sure that the required version of automake
+et al. are properly indicated at the top of configure.ac and take care
+to copy the files and not merely use symlinks.
diff --git a/comm/third_party/libgcrypt/THANKS b/comm/third_party/libgcrypt/THANKS
new file mode 100644
index 0000000000..6a44eade05
--- /dev/null
+++ b/comm/third_party/libgcrypt/THANKS
@@ -0,0 +1,168 @@
+Libgcrypt is based on the GnuPG code. Here is a list of people, who
+helped in GnuPG and Libgcrypt development. Please help us to keep it
+complete and free of errors.
+
+Albert Chin china at thewrittenword com
+Allan Clark allanc@sco.com
+Anand Kumria wildfire@progsoc.uts.edu.au
+Andreas Metzler ametzler at downhill.at.eu.org
+Ariel T Glenn ariel@columbia.edu
+Aurelien Jarno aurel32 at debian.org
+Ben Hutchings ben decadent org uk
+Bodo Moeller Bodo_Moeller@public.uni-hamburg.de
+Brenno de Winter brenno@dewinter.com
+Brian Moore bem@cmc.net
+Brian Warner warner@lothar.com
+Brieuc Jeunhomme bbp@via.ecp.fr
+Bryan Fullerton bryanf@samurai.com
+Caskey L. Dickson caskey@technocage.com
+Cees van de Griend cees-list@griend.xs4all.nl
+Charles Levert charles@comm.polymtl.ca
+Christian Biere christianbiere@gmx.de
+Christian Grothoff christian at grothoff org
+Christian von Roques roques@pond.sub.org
+Christopher Oliver oliver@fritz.traverse.net
+Christian Recktenwald chris@citecs.de
+Daiki Ueno ueno at unixuser org
+Dan Fandrich dan at coneharvesters com
+Daniel Eisenbud eisenbud@cs.swarthmore.edu
+Daniel Koening dan@mail.isis.de
+David Ellement ellement@sdd.hp.com
+Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de
+Dirk Lattermann dlatt@t-online.de
+Dirk Stoecker gcrypt@dstoecker.de
+Ed Boraas ecxjo@esperanto.org
+Elie De Brauwer elie@de-brauwer.be
+Enzo Michelangeli em@MailAndNews.com
+Ernst Molitor ernst.molitor@uni-bonn.de
+Fabian Keil fk at fabiankeil de
+Fabio Coatti cova@felix.unife.it
+Felix von Leitner leitner@amdiv.de
+Frank Heckenbach heckenb@mi.uni-erlangen.de
+Frank Stajano frank.stajano@cl.cam.ac.uk
+Gabriele Monti psicus78 gmail com
+Gaël Quéri gqueri@mail.dotcom.fr
+Gregor Riepl seto-kun@freesurf.ch
+Gerlinde Klaes gk@u64.de
+Greg Louis glouis@dynamicro.on.ca
+Greg Troxel gdt@ir.bbn.com
+Gregory Steuck steuck@iname.com
+Geoff Keating geoffk@ozemail.com.au
+Harald Denker harry@hal.westfalen.de
+Hendrik Buschkamp buschkamp@rheumanet.org
+Holger Schurig holger@d.om.org
+Hugh Daniel hugh@toad.com
+Ian McKellar imckellar@harvestroad.com.au
+Ian Peters itp@ximian.com
+Janusz A. Urbanowicz alex@bofh.torun.pl
+James Troup james@nocrew.org
+Jean-loup Gailly gzip@prep.ai.mit.edu
+Jeff Johnson jbj@redhat.com
+Jens Bachem bachem@rrz.uni-koeln.de
+J Horacio MG homega@ciberia.es
+Joachim Backes backes@rhrk.uni-kl.de
+Jordi Mallach jordi@sindominio.net
+John A. Martin jam@jamux.com
+Johnny Teveßen j.tevessen@gmx.de
+Jörg Schilling schilling@fokus.gmd.de
+Jun Kuriyama kuriyama@sky.rim.or.jp
+Karl Fogel kfogel@guanabana.onshore.com
+Karsten Thygesen karthy@kom.auc.dk
+Katsuhiro Kondou kondou@nec.co.jp
+Kazu Yamamoto kazu@iijlab.net
+Lars Kellogg-Stedman lars@bu.edu
+Lee Fisher blibbet at gmail dot com
+Marco d'Itri md@linux.it
+Mark Adler madler@alumni.caltech.edu
+Mark Elbrecht snowball3@bigfoot.com
+Markus Friedl Markus.Friedl@informatik.uni-erlangen.de
+Matthias Urlichs smurf@smurf.noris.de
+Martin Kahlert martin.kahlert@provi.de
+Martin Hamilton
+Martin Schulte schulte@thp.uni-koeln.de
+Matthew Skala mskala@ansuz.sooke.bc.ca
+Max Kellermann max@duempel.org
+Max Valianskiy maxcom@maxcom.ml.org
+Michael Fischer v. Mollard mfvm@gmx.de
+Michael Roth mroth@nessie.de
+Michael Sobolev mss@despair.transas.com
+Michele Baldessari michele@pupazzo.org
+Modestas Vainius geromanas@mailas.com
+Neil Dunbar neil.dunbar at pobox.com
+Neil Spring nspring@cs.washington.edu
+Newton Hammet newton@hammet.net
+Nicolas Graner Nicolas.Graner@cri.u-psud.fr
+NIIBE Yutaka gniibe@chroot.org
+Niklas Hernaeus
+Nikolay Sturm sturm@sec.informatik.tu-darmstadt.de
+Nikos Mavroyanopoulos nmav@hellug.gr
+Nimrod Zimerman zimerman@forfree.at
+N J Doye nic@niss.ac.uk
+Oliver Haakert haakert@hsp.de
+Oskari Jääskeläinen f33003a@cc.hut.fi
+Paul D. Smith psmith@baynetworks.com
+Philippe Laliberte arsphl@oeil.qc.ca
+Peter Gutmann pgut001@cs.auckland.ac.nz
+QingLong qinglong@bolizm.ihep.su
+Rafael Ãvila de Espíndola rafael.espindola@gmail.com
+Rafaël Carré funman@videolan.org
+Ralf Fassel ralf@akutech.de
+Ralf Hildebrandt Ralf.Hildebrandt@innominate.com
+Ralf Schneider ralf@tapfere-schneiderleins.de
+Ralph Gillen gillen@theochem.uni-duesseldorf.de
+Rami Lehti Rami.Lehti@finland.sun.com
+Randolph Chung tausq@debian.org
+Randy mcclellr@oit.edu
+Rat ratinox@peorth.gweep.net
+Reinhard Wobst R.Wobst@ifw-dresden.de
+Rémi Guyomarch rguyom@mail.dotcom.fr
+Reuben Sumner rasumner@wisdom.weizmann.ac.il
+Richard Outerbridge outer@interlog.com
+Roddy Strachan roddy@satlink.com.au
+Roland Rosenfeld roland@spinnaker.rhein.de
+Ross Golder rossigee@bigfoot.com
+Serge Munhoven munhoven@mema.ucl.ac.be
+Sergi Blanch i Torné sergi at calcurco cat
+Simon Josefsson jas@extundo.com
+SL Baur steve@xemacs.org
+Stephan Austermuehle au@hcsd.de
+Stephan Müller smueller at atsec com
+Stephane Corthesy stephane@sente.ch
+Stefan Karrmann S.Karrmann@gmx.net
+Stefan Keller dres@cs.tu-berlin.de
+Stefan Krüger stadtkind2 at gmx de
+Steffen Ullrich ccrlphr@xensei.com
+Steffen Zahn zahn@berlin.snafu.de
+Steven Bakker steven@icoe.att.com
+Susanne Schultz schultz@hsp.de
+Sven Bjorn
+Szakats Istvan szaki.ms@gmail.com
+Thiago Jung Bauermann jungmann@cwb.matrix.com.br
+Thomas Roessler roessler@guug.de
+Tom Holroyd tomh@po.crl.go.jp
+Tom Spindler dogcow@home.merit.edu
+Tom Zerucha tzeruch@ceddec.com
+Tomas Fasth tomas.fasth@twinspot.net
+Tommi Komulainen Tommi.Komulainen@iki.fi
+Thomas Mikkelsen tbm@image.dk
+Ulf Möller 3umoelle@informatik.uni-hamburg.de
+Umberto Salsi salsi@icosaedro.it
+Uoti Urpala
+Urko Lusa ulusa@euskalnet.net
+Victor Stinner haypo@inl.fr
+Walter Koch koch@u32.de
+Werner Koch wk@gnupg.org
+Wim Vandeputte wim@kd85.com
+ nbecker@hns.com
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003,
+ 2009, 2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/comm/third_party/libgcrypt/TODO b/comm/third_party/libgcrypt/TODO
new file mode 100644
index 0000000000..7aa4de1af6
--- /dev/null
+++ b/comm/third_party/libgcrypt/TODO
@@ -0,0 +1,59 @@
+# What's left to do -*- org -*-
+
+* Next API break:
+** gcry_ac_io_t
+ Remove use of anonymous union.
+** gcry_ac
+ Consider to remove it.
+
+* udiv-qrnbd.o should get build as *.lo [HPUX]
+
+* Allow operation using RSA keys consisting of the OpenSSL keys.
+ This requires the introduction of a parameter names (say) U which
+ is calculated according to OpenSSL/PKCS#1 rules.
+
+* linker script test
+ Write an autoconf test to check whether the linker supports a
+ version script.
+
+* Add attributes to the MPI functions.
+
+* cipher/pubkey.c and pubkey implementations.
+ Don't rely on the secure memory based wiping function but add an
+ extra wiping.
+
+* Use builtin bit functions of gcc 3.4
+
+* Consider using a daemon to maintain the random pool
+ [Partly done] The down side of this is that we can't assume that the
+ random has has always been stored in "secure memory". And we rely
+ on that sniffing of Unix domain sockets is not possible. We can
+ implement this simply by detecting a special prefixed random seed
+ name and divert in this case to the daemon. There are several
+ benefits with such an approach: We keep the state of the RNG over
+ invocations of libgcrypt based applications, don't need time
+ consuming initialization of the pool and in case the entropy
+ collectros need to run that bunch of Unix utilities we don't waste
+ their precious results.
+
+* gcryptrnd.c
+ Requires a test for pth [done] as well as some other tests.
+
+* secmem.c
+ Check whether the memory block is valid before releasing it and
+ print a diagnosic, like glibc does.
+
+* threads
+** We need to document fork problems
+ In particular that reinitialization is required in random.c
+ However, there is no code yet to do it.
+
+* Tests
+ We need a lot more tests. Lets keep an ever growing list here.
+** Write tests for the progress function
+** mpitests does no real checks yet.
+** pthreads
+ To catch simple errors like the one fixed on 2007-03-16.
+** C++ tests
+ We have some code to allow using libgcrypt from C++, so we also
+ should have a test case.
diff --git a/comm/third_party/libgcrypt/VERSION b/comm/third_party/libgcrypt/VERSION
new file mode 100644
index 0000000000..8fdcf38694
--- /dev/null
+++ b/comm/third_party/libgcrypt/VERSION
@@ -0,0 +1 @@
+1.9.2
diff --git a/comm/third_party/libgcrypt/acinclude.m4 b/comm/third_party/libgcrypt/acinclude.m4
new file mode 100644
index 0000000000..3c8dfba711
--- /dev/null
+++ b/comm/third_party/libgcrypt/acinclude.m4
@@ -0,0 +1,392 @@
+dnl macros to configure Libgcrypt
+dnl Copyright (C) 1998, 1999, 2000, 2001, 2002,
+dnl 2003 Free Software Foundation, Inc.
+dnl Copyright (C) 2013 g10 Code GmbH
+dnl
+dnl This file is part of Libgcrypt.
+dnl
+dnl Libgcrypt is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU Lesser General Public License as
+dnl published by the Free Software Foundation; either version 2.1 of
+dnl the License, or (at your option) any later version.
+dnl
+dnl Libgcrypt is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+dnl GCRY_MSG_SHOW(PREFIX,STRING)
+dnl Print a message with a prefix.
+dnl
+define([GCRY_MSG_SHOW],
+ [
+ echo " $1 $2" 1>&AS_MESSAGE_FD([])
+ ])
+
+dnl GCRY_MSG_WRAP(PREFIX, ALGOLIST)
+dnl Print a nicely formatted list of algorithms
+dnl with an appropriate line wrap.
+dnl
+define([GCRY_MSG_WRAP],
+ [
+ tmp=" $1"
+ tmpi="abc"
+ if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+ dnl Without a POSIX shell, we don't botter to wrap it
+ echo "$tmp $2" 1>&AS_MESSAGE_FD([])
+ else
+ tmpi=`echo "$tmp"| sed 's/./ /g'`
+ echo $2 EOF | tr ' ' '\n' | \
+ while read word; do
+ if test "${#tmp}" -gt 70 ; then
+ echo "$tmp" 1>&AS_MESSAGE_FD([])
+ tmp="$tmpi"
+ fi
+ if test "$word" = "EOF" ; then
+ echo "$tmp" 1>&AS_MESSAGE_FD([])
+ else
+ tmp="$tmp $word"
+ fi
+ done
+ fi
+ ])
+
+
+dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME)
+dnl Check whether a typedef exists and create a #define $2 if it exists
+dnl
+AC_DEFUN([GNUPG_CHECK_TYPEDEF],
+ [ AC_MSG_CHECKING(for $1 typedef)
+ AC_CACHE_VAL(gnupg_cv_typedef_$1,
+ [AC_TRY_COMPILE([#define _GNU_SOURCE 1
+ #include <stdlib.h>
+ #include <sys/types.h>], [
+ #undef $1
+ int a = sizeof($1);
+ ], gnupg_cv_typedef_$1=yes, gnupg_cv_typedef_$1=no )])
+ AC_MSG_RESULT($gnupg_cv_typedef_$1)
+ if test "$gnupg_cv_typedef_$1" = yes; then
+ AC_DEFINE($2,1,[Defined if a `]$1[' is typedef'd])
+ fi
+ ])
+
+
+dnl GNUPG_CHECK_GNUMAKE
+dnl
+AC_DEFUN([GNUPG_CHECK_GNUMAKE],
+ [
+ if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then
+ :
+ else
+ AC_MSG_WARN([[
+***
+*** It seems that you are not using GNU make. Some make tools have serious
+*** flaws and you may not be able to build this software at all. Before you
+*** complain, please try GNU make: GNU make is easy to build and available
+*** at all GNU archives. It is always available from ftp.gnu.org:/gnu/make.
+***]])
+ fi
+ ])
+
+
+#
+# GNUPG_SYS_SYMBOL_UNDERSCORE
+# Does the compiler prefix global symbols with an underscore?
+#
+# Taken from GnuPG 1.2 and modified to use the libtool macros.
+AC_DEFUN([GNUPG_SYS_SYMBOL_UNDERSCORE],
+[tmp_do_check="no"
+case "${host}" in
+ i?86-mingw32* | i?86-*-mingw32*)
+ ac_cv_sys_symbol_underscore=yes
+ ;;
+ x86_64-*-mingw32*)
+ ac_cv_sys_symbol_underscore=no
+ ;;
+ i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp)
+ ac_cv_sys_symbol_underscore=yes
+ ;;
+ *)
+ if test "$cross_compiling" != yes; then
+ tmp_do_check="yes"
+ fi
+ ;;
+esac
+if test "$tmp_do_check" = "yes"; then
+ AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])
+ AC_MSG_CHECKING([for _ prefix in compiled symbols])
+ AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+ [ac_cv_sys_symbol_underscore=no
+ cat > conftest.$ac_ext <<EOF
+ void nm_test_func(){}
+ int main(){nm_test_func;return 0;}
+EOF
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ fi
+ else
+ echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.c >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf conftest*
+ ])
+ else
+ AC_MSG_CHECKING([for _ prefix in compiled symbols])
+ fi
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+ AC_DEFINE(WITH_SYMBOL_UNDERSCORE,1,
+ [Defined if compiled symbols have a leading underscore])
+fi
+])
+
+
+######################################################################
+# Check whether mlock is broken (hpux 10.20 raises a SIGBUS if mlock
+# is not called from uid 0 (not tested whether uid 0 works)
+# For DECs Tru64 we have also to check whether mlock is in librt
+# mlock is there a macro using memlk()
+######################################################################
+dnl GNUPG_CHECK_MLOCK
+dnl
+define(GNUPG_CHECK_MLOCK,
+ [ AC_CHECK_FUNCS(mlock)
+ if test "$ac_cv_func_mlock" = "no"; then
+ AC_CHECK_HEADERS(sys/mman.h)
+ if test "$ac_cv_header_sys_mman_h" = "yes"; then
+ # Add librt to LIBS:
+ AC_CHECK_LIB(rt, memlk)
+ AC_CACHE_CHECK([whether mlock is in sys/mman.h],
+ gnupg_cv_mlock_is_in_sys_mman,
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <assert.h>
+ #ifdef HAVE_SYS_MMAN_H
+ #include <sys/mman.h>
+ #endif
+ ]], [[
+int i;
+
+/* glibc defines this for functions which it implements
+ * to always fail with ENOSYS. Some functions are actually
+ * named something starting with __ and the normal name
+ * is an alias. */
+#if defined (__stub_mlock) || defined (__stub___mlock)
+choke me
+#else
+mlock(&i, 4);
+#endif
+; return 0;
+ ]])],
+ gnupg_cv_mlock_is_in_sys_mman=yes,
+ gnupg_cv_mlock_is_in_sys_mman=no)])
+ if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then
+ AC_DEFINE(HAVE_MLOCK,1,
+ [Defined if the system supports an mlock() call])
+ fi
+ fi
+ fi
+ if test "$ac_cv_func_mlock" = "yes"; then
+ AC_CHECK_FUNCS(sysconf getpagesize)
+ AC_MSG_CHECKING(whether mlock is broken)
+ AC_CACHE_VAL(gnupg_cv_have_broken_mlock,
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+int main()
+{
+ char *pool;
+ int err;
+ long int pgsize;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pgsize = sysconf (_SC_PAGESIZE);
+#elif defined (HAVE_GETPAGESIZE)
+ pgsize = getpagesize();
+#else
+ pgsize = -1;
+#endif
+
+ if (pgsize == -1)
+ pgsize = 4096;
+
+ pool = malloc( 4096 + pgsize );
+ if( !pool )
+ return 2;
+ pool += (pgsize - ((long int)pool % pgsize));
+
+ err = mlock( pool, 4096 );
+ if( !err || errno == EPERM || errno == EAGAIN)
+ return 0; /* okay */
+
+ return 1; /* hmmm */
+}
+ ]])],
+ gnupg_cv_have_broken_mlock="no",
+ gnupg_cv_have_broken_mlock="yes",
+ gnupg_cv_have_broken_mlock="assume-no"
+ )
+ )
+ if test "$gnupg_cv_have_broken_mlock" = "yes"; then
+ AC_DEFINE(HAVE_BROKEN_MLOCK,1,
+ [Defined if the mlock() call does not work])
+ AC_MSG_RESULT(yes)
+ else
+ if test "$gnupg_cv_have_broken_mlock" = "no"; then
+ AC_MSG_RESULT(no)
+ else
+ AC_MSG_RESULT(assuming no)
+ fi
+ fi
+ fi
+ ])
+
+# GNUPG_SYS_LIBTOOL_CYGWIN32 - find tools needed on cygwin32
+AC_DEFUN([GNUPG_SYS_LIBTOOL_CYGWIN32],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+dnl LIST_MEMBER()
+dnl Check whether an element ist contained in a list. Set `found' to
+dnl `1' if the element is found in the list, to `0' otherwise.
+AC_DEFUN([LIST_MEMBER],
+[
+name=$1
+list=$2
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+])
+
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+AC_DEFUN([TYPE_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int getpeername (int, $arg2 *, $t *);
+ ],[
+ $t len;
+ getpeername(0,0,&len);
+ ],[
+ socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$socklen_t_equiv" = x; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_MSG_RESULT($socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+
+
+# GNUPG_PTH_VERSION_CHECK(REQUIRED)
+#
+# If the version is sufficient, HAVE_PTH will be set to yes.
+#
+# Taken form the m4 macros which come with Pth
+AC_DEFUN([GNUPG_PTH_VERSION_CHECK],
+ [
+ _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'`
+ _req_version="ifelse([$1],,1.2.0,$1)"
+
+ AC_MSG_CHECKING(for PTH - version >= $_req_version)
+ for _var in _pth_version _req_version; do
+ eval "_val=\"\$${_var}\""
+ _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'`
+ _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'`
+ _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'`
+ _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'`
+ case $_rtype in
+ "a" ) _rtype=0 ;;
+ "b" ) _rtype=1 ;;
+ "." ) _rtype=2 ;;
+ esac
+ _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \
+ "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"`
+ eval "${_var}_hex=\"\$_hex\""
+ done
+ have_pth=no
+ if test ".$_pth_version_hex" != .; then
+ if test ".$_req_version_hex" != .; then
+ if test $_pth_version_hex -ge $_req_version_hex; then
+ have_pth=yes
+ fi
+ fi
+ fi
+ if test $have_pth = yes; then
+ AC_MSG_RESULT(yes)
+ AC_MSG_CHECKING([whether PTH installation is sane])
+ AC_CACHE_VAL(gnupg_cv_pth_is_sane,[
+ _gnupg_pth_save_cflags=$CFLAGS
+ _gnupg_pth_save_ldflags=$LDFLAGS
+ _gnupg_pth_save_libs=$LIBS
+ CFLAGS="$CFLAGS `$PTH_CONFIG --cflags`"
+ LDFLAGS="$LDFLAGS `$PTH_CONFIG --ldflags`"
+ LIBS="$LIBS `$PTH_CONFIG --libs`"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pth.h>
+ ],
+ [[ pth_init ();]])],
+ gnupg_cv_pth_is_sane=yes,
+ gnupg_cv_pth_is_sane=no)
+ CFLAGS=$_gnupg_pth_save_cflags
+ LDFLAGS=$_gnupg_pth_save_ldflags
+ LIBS=$_gnupg_pth_save_libs
+ ])
+ if test $gnupg_cv_pth_is_sane != yes; then
+ have_pth=no
+ fi
+ AC_MSG_RESULT($gnupg_cv_pth_is_sane)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ])
diff --git a/comm/third_party/libgcrypt/aclocal.m4 b/comm/third_party/libgcrypt/aclocal.m4
new file mode 100644
index 0000000000..55a2f8dbee
--- /dev/null
+++ b/comm/third_party/libgcrypt/aclocal.m4
@@ -0,0 +1,1201 @@
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.16'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.16.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.16.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Figure out how to run the assembler. -*- Autoconf -*-
+
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_AS
+# ----------
+AC_DEFUN([AM_PROG_AS],
+[# By default we simply use the C compiler to build assembly code.
+AC_REQUIRE([AC_PROG_CC])
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+AC_ARG_VAR([CCAS], [assembler compiler command (defaults to CC)])
+AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])
+_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
+])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ # TODO: see whether this extra hack can be removed once we start
+ # requiring Autoconf 2.70 or later.
+ AS_CASE([$CONFIG_FILES],
+ [*\'*], [eval set x "$CONFIG_FILES"],
+ [*], [set x $CONFIG_FILES])
+ shift
+ # Used to flag and report bootstrapping failures.
+ am_rc=0
+ for am_mf
+ do
+ # Strip MF so we end up with the name of the file.
+ am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile which includes
+ # dependency-tracking related rules and includes.
+ # Grep'ing the whole file directly is not great: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+ || continue
+ am_dirpart=`AS_DIRNAME(["$am_mf"])`
+ am_filepart=`AS_BASENAME(["$am_mf"])`
+ AM_RUN_LOG([cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles]) || am_rc=$?
+ done
+ if test $am_rc -ne 0; then
+ AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+ for automatic dependency tracking. Try re-running configure with the
+ '--disable-dependency-tracking' option to at least be able to build
+ the package (albeit without support for automatic dependency tracking).])
+ fi
+ AS_UNSET([am_dirpart])
+ AS_UNSET([am_filepart])
+ AS_UNSET([am_mf])
+ AS_UNSET([am_rc])
+ rm -f conftest-deps.mk
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
+am__doit:
+ @echo this is the am__doit target >confinc.out
+.PHONY: am__doit
+END
+am__include="#"
+am__quote=
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+ AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+ AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+ ['0:this is the am__doit target'],
+ [AS_CASE([$s],
+ [BSD], [am__include='.include' am__quote='"'],
+ [am__include='include' am__quote=''])])
+ if test "$am__include" != "#"; then
+ _am_result="yes ($s style)"
+ break
+ fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2018 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/ax_cc_for_build.m4])
+m4_include([m4/gpg-error.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/noexecstack.m4])
+m4_include([m4/socklen.m4])
+m4_include([acinclude.m4])
diff --git a/comm/third_party/libgcrypt/autogen.rc b/comm/third_party/libgcrypt/autogen.rc
new file mode 100644
index 0000000000..646f659cc0
--- /dev/null
+++ b/comm/third_party/libgcrypt/autogen.rc
@@ -0,0 +1,13 @@
+# autogen.sh configuration for Libgcrypt -*- sh -*-
+
+case "$myhost" in
+ w32)
+ configure_opts=""
+ ;;
+
+ amd64)
+ configure_opts=""
+ ;;
+esac
+
+final_info="./configure --enable-maintainer-mode && make"
diff --git a/comm/third_party/libgcrypt/autogen.sh b/comm/third_party/libgcrypt/autogen.sh
new file mode 100755
index 0000000000..9b36158121
--- /dev/null
+++ b/comm/third_party/libgcrypt/autogen.sh
@@ -0,0 +1,513 @@
+#! /bin/sh
+# autogen.sh
+# Copyright (C) 2003, 2014, 2017, 2018 g10 Code GmbH
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# This is a generic script to create the configure script and handle cross
+# build environments. It requires the presence of a autogen.rc file to
+# configure it for the respective package. It is maintained as part of
+# GnuPG and source copied by other packages.
+#
+# Version: 2018-07-10
+
+configure_ac="configure.ac"
+
+cvtver () {
+ awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}'
+}
+
+check_version () {
+ if [ $(( `("$1" --version || echo "0") | cvtver` >= $2 )) = 1 ]; then
+ return 0
+ fi
+ echo "**Error**: "\`$1\'" not installed or too old." >&2
+ echo ' Version '$3' or newer is required.' >&2
+ [ -n "$4" ] && echo ' Note that this is part of '\`$4\''.' >&2
+ DIE="yes"
+ return 1
+}
+
+fatal () {
+ echo "autogen.sh:" "$*" >&2
+ DIE=yes
+}
+
+info () {
+ if [ -z "${SILENT}" ]; then
+ echo "autogen.sh:" "$*" >&2
+ fi
+}
+
+die_p () {
+ if [ "$DIE" = "yes" ]; then
+ echo "autogen.sh: Stop." >&2
+ exit 1
+ fi
+}
+
+replace_sysroot () {
+ configure_opts=$(echo $configure_opts | sed "s#@SYSROOT@#${w32root}#g")
+ extraoptions=$(echo $extraoptions | sed "s#@SYSROOT@#${w32root}#g")
+}
+
+# Allow to override the default tool names
+AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
+AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
+
+AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX}
+ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX}
+
+GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX}
+MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
+
+DIE=no
+FORCE=
+SILENT=
+PRINT_HOST=no
+PRINT_BUILD=no
+tmp=$(dirname "$0")
+tsdir=$(cd "${tmp}"; pwd)
+
+if [ -n "${AUTOGEN_SH_SILENT}" ]; then
+ SILENT=" --silent"
+fi
+if test x"$1" = x"--help"; then
+ echo "usage: ./autogen.sh [OPTIONS] [ARGS]"
+ echo " Options:"
+ echo " --silent Silent operation"
+ echo " --force Pass --force to autoconf"
+ echo " --find-version Helper for configure.ac"
+ echo " --git-build Run all commands to build from a Git"
+ echo " --print-host Print only the host triplet"
+ echo " --print-build Print only the build platform triplet"
+ echo " --build-TYPE Configure to cross build for TYPE"
+ echo ""
+ echo " ARGS are passed to configure in --build-TYPE mode."
+ echo " Configuration for this script is expected in autogen.rc"
+ exit 0
+fi
+if test x"$1" = x"--silent"; then
+ SILENT=" --silent"
+ shift
+fi
+if test x"$1" = x"--force"; then
+ FORCE=" --force"
+ shift
+fi
+if test x"$1" = x"--print-host"; then
+ PRINT_HOST=yes
+ shift
+fi
+if test x"$1" = x"--print-build"; then
+ PRINT_BUILD=yes
+ shift
+fi
+
+
+# Reject unsafe characters in $HOME, $tsdir and cwd. We consider spaces
+# as unsafe because it is too easy to get scripts wrong in this regard.
+am_lf='
+'
+case `pwd` in
+ *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ fatal "unsafe working directory name" ;;
+esac
+case $tsdir in
+ *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ fatal "unsafe source directory: \`$tsdir'" ;;
+esac
+case $HOME in
+ *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ fatal "unsafe home directory: \`$HOME'" ;;
+esac
+die_p
+
+
+# List of variables sourced from autogen.rc. The strings '@SYSROOT@' in
+# these variables are replaced by the actual system root.
+configure_opts=
+extraoptions=
+# List of optional variables sourced from autogen.rc and ~/.gnupg-autogen.rc
+w32_toolprefixes=
+w32_extraoptions=
+w32ce_toolprefixes=
+w32ce_extraoptions=
+w64_toolprefixes=
+w64_extraoptions=
+amd64_toolprefixes=
+# End list of optional variables sourced from ~/.gnupg-autogen.rc
+# What follows are variables which are sourced but default to
+# environment variables or lacking them hardcoded values.
+#w32root=
+#w32ce_root=
+#w64root=
+#amd64root=
+
+# Convenience option to use certain configure options for some hosts.
+myhost=""
+myhostsub=""
+case "$1" in
+ --find-version)
+ myhost="find-version"
+ SILENT=" --silent"
+ shift
+ ;;
+ --git-build)
+ myhost="git-build"
+ shift
+ ;;
+ --build-w32)
+ myhost="w32"
+ shift
+ ;;
+ --build-w32ce)
+ myhost="w32"
+ myhostsub="ce"
+ shift
+ ;;
+ --build-w64)
+ myhost="w32"
+ myhostsub="64"
+ shift
+ ;;
+ --build-amd64)
+ myhost="amd64"
+ shift
+ ;;
+ --build*)
+ fatal "**Error**: invalid build option $1"
+ shift
+ ;;
+ *)
+ ;;
+esac
+die_p
+
+
+# **** GIT BUILD ****
+# This is a helper to build from git.
+if [ "$myhost" = "git-build" ]; then
+ tmp="$(pwd)"
+ cd "$tsdir" || fatal "error cd-ing to $tsdir"
+ ./autogen.sh || fatal "error running ./autogen.sh"
+ cd "$tmp" || fatal "error cd-ing back to $tmp"
+ die_p
+ "$tsdir"/configure || fatal "error running $tsdir/configure"
+ die_p
+ make || fatal "error running make"
+ die_p
+ make check || fatal "error running male check"
+ die_p
+ exit 0
+fi
+# **** end GIT BUILD ****
+
+
+# Source our configuration
+if [ -f "${tsdir}/autogen.rc" ]; then
+ . "${tsdir}/autogen.rc"
+fi
+
+# Source optional site specific configuration
+if [ -f "$HOME/.gnupg-autogen.rc" ]; then
+ info "sourcing extra definitions from $HOME/.gnupg-autogen.rc"
+ . "$HOME/.gnupg-autogen.rc"
+fi
+
+
+# **** FIND VERSION ****
+# This is a helper for the configure.ac M4 magic
+# Called
+# ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO]
+# returns a complete version string with automatic beta numbering.
+if [ "$myhost" = "find-version" ]; then
+ package="$1"
+ major="$2"
+ minor="$3"
+ micro="$4"
+
+ if [ -z "$package" -o -z "$major" -o -z "$minor" ]; then
+ echo "usage: ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO]" >&2
+ exit 1
+ fi
+
+ if [ -z "$micro" ]; then
+ matchstr1="$package-$major.[0-9]*"
+ matchstr2="$package-$major-base"
+ vers="$major.$minor"
+ else
+ matchstr1="$package-$major.$minor.[0-9]*"
+ matchstr2="$package-$major.$minor-base"
+ vers="$major.$minor.$micro"
+ fi
+
+ beta=no
+ if [ -e .git ]; then
+ ingit=yes
+ tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null)
+ tmp=$(echo "$tmp" | sed s/^"$package"//)
+ if [ -n "$tmp" ]; then
+ tmp=$(echo "$tmp" | sed s/^"$package"// \
+ | awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}')
+ else
+ tmp=$(git describe --match "${matchstr2}" --long 2>/dev/null \
+ | awk -F- '$4!=0{print"-beta"$4}')
+ fi
+ [ -n "$tmp" ] && beta=yes
+ rev=$(git rev-parse --short HEAD | tr -d '\n\r')
+ rvd=$((0x$(echo ${rev} | dd bs=1 count=4 2>/dev/null)))
+ else
+ ingit=no
+ beta=yes
+ tmp="-unknown"
+ rev="0000000"
+ rvd="0"
+ fi
+
+ echo "$package-$vers$tmp:$beta:$ingit:$vers$tmp:$vers:$tmp:$rev:$rvd:"
+ exit 0
+fi
+# **** end FIND VERSION ****
+
+
+if [ ! -f "$tsdir/build-aux/config.guess" ]; then
+ fatal "$tsdir/build-aux/config.guess not found"
+ exit 1
+fi
+build=`$tsdir/build-aux/config.guess`
+if [ $PRINT_BUILD = yes ]; then
+ echo "$build"
+ exit 0
+fi
+
+
+
+# ******************
+# W32 build script
+# ******************
+if [ "$myhost" = "w32" ]; then
+ case $myhostsub in
+ ce)
+ w32root="$w32ce_root"
+ [ -z "$w32root" ] && w32root="$HOME/w32ce_root"
+ toolprefixes="$w32ce_toolprefixes arm-mingw32ce"
+ extraoptions="$extraoptions $w32ce_extraoptions"
+ ;;
+ 64)
+ w32root="$w64root"
+ [ -z "$w32root" ] && w32root="$HOME/w64root"
+ toolprefixes="$w64_toolprefixes x86_64-w64-mingw32"
+ extraoptions="$extraoptions $w64_extraoptions"
+ ;;
+ *)
+ [ -z "$w32root" ] && w32root="$HOME/w32root"
+ toolprefixes="$w32_toolprefixes i686-w64-mingw32 i586-mingw32msvc"
+ toolprefixes="$toolprefixes i386-mingw32msvc mingw32"
+ extraoptions="$extraoptions $w32_extraoptions"
+ ;;
+ esac
+ info "Using $w32root as standard install directory"
+ replace_sysroot
+
+ # Locate the cross compiler
+ crossbindir=
+ for host in $toolprefixes; do
+ if ${host}-gcc --version >/dev/null 2>&1 ; then
+ crossbindir=/usr/${host}/bin
+ conf_CC="CC=${host}-gcc"
+ break;
+ fi
+ done
+ if [ -z "$crossbindir" ]; then
+ fatal "cross compiler kit not installed"
+ if [ -z "$myhostsub" ]; then
+ info "Under Debian GNU/Linux, you may install it using"
+ info " apt-get install mingw32 mingw32-runtime mingw32-binutils"
+ fi
+ die_p
+ fi
+ if [ $PRINT_HOST = yes ]; then
+ echo "$host"
+ exit 0
+ fi
+
+ if [ -f "$tsdir/config.log" ]; then
+ if ! head $tsdir/config.log | grep "$host" >/dev/null; then
+ fatal "Please run a 'make distclean' first"
+ die_p
+ fi
+ fi
+
+ $tsdir/configure --enable-maintainer-mode ${SILENT} \
+ --prefix=${w32root} \
+ --host=${host} --build=${build} SYSROOT=${w32root} \
+ PKG_CONFIG_LIBDIR=${w32root}/lib/pkgconfig \
+ ${configure_opts} ${extraoptions} "$@"
+ rc=$?
+ exit $rc
+fi
+# ***** end W32 build script *******
+
+# ***** AMD64 cross build script *******
+# Used to cross-compile for AMD64 (for testing)
+if [ "$myhost" = "amd64" ]; then
+ [ -z "$amd64root" ] && amd64root="$HOME/amd64root"
+ info "Using $amd64root as standard install directory"
+ replace_sysroot
+
+ toolprefixes="$amd64_toolprefixes x86_64-linux-gnu amd64-linux-gnu"
+
+ # Locate the cross compiler
+ crossbindir=
+ for host in $toolprefixes ; do
+ if ${host}-gcc --version >/dev/null 2>&1 ; then
+ crossbindir=/usr/${host}/bin
+ conf_CC="CC=${host}-gcc"
+ break;
+ fi
+ done
+ if [ -z "$crossbindir" ]; then
+ echo "Cross compiler kit not installed" >&2
+ echo "Stop." >&2
+ exit 1
+ fi
+ if [ $PRINT_HOST = yes ]; then
+ echo "$host"
+ exit 0
+ fi
+
+ if [ -f "$tsdir/config.log" ]; then
+ if ! head $tsdir/config.log | grep "$host" >/dev/null; then
+ echo "Please run a 'make distclean' first" >&2
+ exit 1
+ fi
+ fi
+
+ $tsdir/configure --enable-maintainer-mode ${SILENT} \
+ --prefix=${amd64root} \
+ --host=${host} --build=${build} \
+ ${configure_opts} ${extraoptions} "$@"
+ rc=$?
+ exit $rc
+fi
+# ***** end AMD64 cross build script *******
+
+
+# Grep the required versions from configure.ac
+autoconf_vers=`sed -n '/^AC_PREREQ(/ {
+s/^.*(\(.*\))/\1/p
+q
+}' ${configure_ac}`
+autoconf_vers_num=`echo "$autoconf_vers" | cvtver`
+
+automake_vers=`sed -n '/^min_automake_version=/ {
+s/^.*="\(.*\)"/\1/p
+q
+}' ${configure_ac}`
+automake_vers_num=`echo "$automake_vers" | cvtver`
+
+if [ -d "${tsdir}/po" ]; then
+ gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ {
+s/^.*\[\(.*\)])/\1/p
+q
+}' ${configure_ac}`
+ gettext_vers_num=`echo "$gettext_vers" | cvtver`
+else
+ gettext_vers="n/a"
+fi
+
+if [ -z "$autoconf_vers" -o -z "$automake_vers" -o -z "$gettext_vers" ]
+then
+ echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2
+ exit 1
+fi
+
+
+if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then
+ check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf
+fi
+if check_version $AUTOMAKE $automake_vers_num $automake_vers; then
+ check_version $ACLOCAL $automake_vers_num $autoconf_vers automake
+fi
+if [ "$gettext_vers" != "n/a" ]; then
+ if check_version $GETTEXT $gettext_vers_num $gettext_vers; then
+ check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext
+ fi
+fi
+
+if [ "$DIE" = "yes" ]; then
+ cat <<EOF
+
+Note that you may use alternative versions of the tools by setting
+the corresponding environment variables; see README.GIT for details.
+
+EOF
+ die_p
+fi
+
+# Check the git setup.
+if [ -d .git ]; then
+ CP="cp -p"
+ # If we have a GNU cp we can add -v
+ if cp --version >/dev/null 2>/dev/null; then
+ [ -z "${SILENT}" ] && CP="$CP -v"
+ fi
+ if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then
+ [ -z "${SILENT}" ] && cat <<EOF
+*** Activating trailing whitespace git pre-commit hook. ***
+ For more information see this thread:
+ https://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084.html
+ To deactivate this pre-commit hook again move .git/hooks/pre-commit
+ and .git/hooks/pre-commit.sample out of the way.
+EOF
+ $CP .git/hooks/pre-commit.sample .git/hooks/pre-commit
+ chmod +x .git/hooks/pre-commit
+ fi
+
+ if [ "$gettext_vers" != "n/a" ]; then
+ tmp=$(git config --get filter.cleanpo.clean)
+ if [ "$tmp" != \
+ "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ]
+ then
+ info "*** Adding GIT filter.cleanpo.clean configuration."
+ git config --add filter.cleanpo.clean \
+ "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'"
+ fi
+ fi
+ if [ -f build-aux/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then
+ [ -z "${SILENT}" ] && cat <<EOF
+*** Activating commit log message check hook. ***
+EOF
+ $CP build-aux/git-hooks/commit-msg .git/hooks/commit-msg
+ chmod +x .git/hooks/commit-msg
+ if [ x"${display_name}" != x ]; then
+ git config format.subjectPrefix "PATCH ${display_name}"
+ git config sendemail.to "${patches_to}"
+ fi
+ fi
+fi
+
+aclocal_flags="-I m4"
+if [ -n "${extra_aclocal_flags}" ]; then
+ aclocal_flags="${aclocal_flags} ${extra_aclocal_flags}"
+fi
+if [ -n "${ACLOCAL_FLAGS}" ]; then
+ aclocal_flags="${aclocal_flags} ${ACLOCAL_FLAGS}"
+fi
+info "Running $ACLOCAL ${aclocal_flags} ..."
+$ACLOCAL ${aclocal_flags}
+info "Running autoheader..."
+$AUTOHEADER
+info "Running automake --gnu ..."
+$AUTOMAKE --gnu;
+info "Running autoconf${FORCE} ..."
+$AUTOCONF${FORCE}
+
+info "You may now run:${am_lf} ${final_info}"
diff --git a/comm/third_party/libgcrypt/build-aux/ChangeLog-2011 b/comm/third_party/libgcrypt/build-aux/ChangeLog-2011
new file mode 100644
index 0000000000..85032cd38a
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/ChangeLog-2011
@@ -0,0 +1,169 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2003-12-08 Werner Koch <wk@gnupg.org>
+
+ * autogen.sh, config.sub, install-sh, mkinstalldirs, config.guess,
+ * missing: Removed
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * autogen.sh: Allow to override the tool name. Do not run
+ libtoolize. Update required version numbers.
+
+2003-07-30 Werner Koch <wk@gnupg.org>
+
+ * config.guess, config.sub: Updated from ftp.gnu.org/gnu/config/
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * autogen.sh: Undo last change.
+ * autogen.sh: Remove -a argument for automake.
+
+2003-03-06 Moritz Schulte <mo@g10code.com>
+
+ * autogen.sh (run): New function.
+ Let automake run with -a for adding missing files automatically
+
+2002-11-12 Werner Koch <wk@gnupg.org>
+
+ * config.sub, config.guess: Updated from ftp.gnu.org/gnu/config
+ to version 2002-11-08.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ * autogen.sh: Require version 2.53 of autoconf
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * distfiles: Remove files which are automatically added by automake.
+
+2001-08-06 Werner Koch <wk@gnupg.org>
+
+ * autogen.sh: Added --build-w32 option.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * db2html.in: Removed.
+ * db2any: New. Taken from GPH
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * config.gues, config.sub: Support for s390-ibm-linux-gnu; thanks
+ to Holger Smolinski. Add support for QNX; by Sam Roberts.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * commit: Remove leading and trailing empty lines when copying
+ Changes to Changelog
+
+Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gnupg.spec: Add Portuguese description
+
+Thu Sep 2 16:40:55 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mkdiff: changed format of diff file name and made script more
+ general.
+
+Wed Aug 4 10:34:18 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.guess: Updated from gnu/common and applied my emx patch again.
+ * config.sub: Updated from gnu/common.
+
+Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * ltmain.sh, ltconfig.sh : Updated to libtool 1.3.3
+
+Mon Jul 12 14:55:34 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * autogen.sh: Run libtoolize
+
+Sat May 22 22:47:26 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * autogen.sh: Fixed the error message for a missing libtool.
+
+Sat May 8 19:28:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mkinstalldirs, install-sh: New from GNU repository
+ * config.sub, config.guess: Merged with rep version.
+
+Sun Mar 14 19:34:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * autogen.sh: Add a check for libtool because some autoconf macros
+ are needed.
+
+Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * autogen.sh: Enhanced the version testing code (Philippe Laliberte)
+
+ * mkwebpage: Edits the buglist.
+
+Sat Feb 13 12:04:43 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * autogen.sh: Now uses gettextize
+
+Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.sub, config.guess: Support i386-emx-os2
+
+Sun Jan 17 11:04:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * autogen.sh: Now checks for installed gettext
+
+Sat Jan 16 09:27:30 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.guess (m68k-atari-mint): New.
+ * config.sub: Add support for atarist-MiNT
+
+Wed Jan 13 12:49:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gnupg.spec.in: New
+ * gnupg.spec: Removed
+
+Wed Dec 23 13:18:14 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gnupg.spec: Updated version by Fabio Coatti
+
+Thu Dec 17 18:31:15 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gnupg.spec: New version by Reuben Sumner and did some more
+ changes.
+
+Fri Nov 27 12:39:29 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * commit: New
+
+
+Fri Nov 20 12:01:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mkdiff: signs the patch file
+
+Sat Oct 17 16:10:16 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * autogen.sh: New.
+
+Wed Oct 14 09:55:25 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.guess (FreeBSD): Changes from Jun Kuriyama to support ELF
+ * config.sub: (freebsd): Add to maybe_os
+
+
+ Copyright 1998,1999,2000,2001,2002 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/build-aux/compile b/comm/third_party/libgcrypt/build-aux/compile
new file mode 100755
index 0000000000..531136b068
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program 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 General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/comm/third_party/libgcrypt/build-aux/config.guess b/comm/third_party/libgcrypt/build-aux/config.guess
new file mode 100755
index 0000000000..c4bd827a7b
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/config.guess
@@ -0,0 +1,1456 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2016 Free Software Foundation, Inc.
+
+timestamp='2016-05-15'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2016 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || \
+ echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
+ ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently (or will in the future) and ABI.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ os=netbsdelf
+ ;;
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # Determine ABI tags.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}${abi}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:Sortix:*:*)
+ echo ${UNAME_MACHINE}-unknown-sortix
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE=alpha ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE=alpha ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE=alpha ;;
+ "EV5 (21164)")
+ UNAME_MACHINE=alphaev5 ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE=alphaev56 ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE=alphapca56 ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE=alphapca57 ;;
+ "EV6 (21264)")
+ UNAME_MACHINE=alphaev6 ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE=alphaev67 ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE=alphaev69 ;;
+ "EV7 (21364)")
+ UNAME_MACHINE=alphaev7 ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE=alphaev79 ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH=i386
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH=x86_64
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = hppa2.0w ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH=hppa2.0w
+ else
+ HP_ARCH=hppa64
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ e2k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ k1om:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configure will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = x86; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = 386; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+ amd64:Isilon\ OneFS:*:*)
+ echo x86_64-unknown-onefs
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/comm/third_party/libgcrypt/build-aux/config.rpath b/comm/third_party/libgcrypt/build-aux/config.rpath
new file mode 100755
index 0000000000..c38b914d6b
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/config.rpath
@@ -0,0 +1,690 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2013 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ ecc*)
+ wl='-Wl,'
+ ;;
+ icc* | ifort*)
+ wl='-Wl,'
+ ;;
+ lf95*)
+ wl='-Wl,'
+ ;;
+ nagfor*)
+ wl='-Wl,-Wl,,'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ wl=
+ ;;
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ newsos6)
+ ;;
+ *nto* | *qnx*)
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ wl='-Qoption ld '
+ ;;
+ *)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ haiku*)
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ *nto* | *qnx*)
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix[4-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc*)
+ library_names_spec='$libname$shrext' ;;
+ m68k)
+ library_names_spec='$libname.a' ;;
+ esac
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ haiku*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ *nto* | *qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ tpf*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
diff --git a/comm/third_party/libgcrypt/build-aux/config.sub b/comm/third_party/libgcrypt/build-aux/config.sub
new file mode 100755
index 0000000000..9feb73bf08
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/config.sub
@@ -0,0 +1,1823 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2016 Free Software Foundation, Inc.
+
+timestamp='2016-06-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2016 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | ba \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | ba-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | e2k-* | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | riscv32-* | riscv64-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ e500v[12])
+ basic_machine=powerpc-unknown
+ os=$os"spe"
+ ;;
+ e500v[12]-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=$os"spe"
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* | -cloudabi* | -sortix* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+ | -onefs* | -tirtos* | -phoenix*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -ios)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/comm/third_party/libgcrypt/build-aux/depcomp b/comm/third_party/libgcrypt/build-aux/depcomp
new file mode 100755
index 0000000000..4ebd5b3a2f
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program 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 General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts '$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\' :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
+
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for ':'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+ "$@" $dashmflag |
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/comm/third_party/libgcrypt/build-aux/git-log-fix b/comm/third_party/libgcrypt/build-aux/git-log-fix
new file mode 100644
index 0000000000..3e3fd95c50
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/git-log-fix
@@ -0,0 +1,14 @@
+# This file is expected to be used via gitlog-to-changelog's --amend=FILE
+# option. It specifies what changes to make to each given SHA1's commit
+# log and metadata, using Perl-eval'able expressions.
+
+eb4937914db3fb7317502e97e4f0e40c1857f59d
+# Fix bad formatted entry dated 2013-05-20
+s/(?s)mpi_sub.*$/cipher: Fix segv in last ECC change.
+* cipher\/ecc.c (generate_key): Make sure R is initialized./
+
+296f38a2bd2e25788643a42e4881faed00884a40
+# Fix bad formatted entry dated 2013-05-09
+s/(?s)Generate ECC.*$/cipher: Generate compliant ECC keys.
+* cipher\/ecc.c (generate_key): Make sure a key is compliant for
+using the compact representation./
diff --git a/comm/third_party/libgcrypt/build-aux/git-log-footer b/comm/third_party/libgcrypt/build-aux/git-log-footer
new file mode 100644
index 0000000000..c31fe936a5
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/git-log-footer
@@ -0,0 +1,14 @@
+
+2011-12-01 Werner Koch <wk@gnupg.org>
+
+ NB: Changes done before December 1st, 2011 are described in
+ per directory files named ChangeLog-2011. See doc/HACKING for
+ details.
+
+ -----
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ Copying and distribution of this file and/or the original GIT
+ commit log messages, with or without modification, are
+ permitted provided the copyright notice and this notice are
+ preserved.
diff --git a/comm/third_party/libgcrypt/build-aux/install-sh b/comm/third_party/libgcrypt/build-aux/install-sh
new file mode 100755
index 0000000000..377bb8687f
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-11-20.07; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call 'install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for 'test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/comm/third_party/libgcrypt/build-aux/ltmain.sh b/comm/third_party/libgcrypt/build-aux/ltmain.sh
new file mode 100644
index 0000000000..859599aa3d
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/ltmain.sh
@@ -0,0 +1,9664 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --no-quiet, --no-silent
+# print informational messages (default)
+# --no-warn don't display warning messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print more informational messages than default
+# --no-verbose don't print the extra informational messages
+# --version print version information
+# -h, --help, --help-all print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE. When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.2 Debian-2.4.2-1"
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+ s@/\./@/@g
+ t dotsl
+ s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+# value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test "$func_normal_abspath_tpath" = / ; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result" ; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+# value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=${func_dirname_result}
+ if test "x$func_relative_path_tlibdir" = x ; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test "x$func_stripname_result" != x ; then
+ func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+ fi
+
+ # Normalisation. If bindir is libdir, return empty string,
+ # else relative path ending with a slash; either way, target
+ # file name can be directly appended.
+ if test ! -z "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result/"
+ func_relative_path_result=$func_stripname_result
+ fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Sed substitution to remove simple comments and empty
+# lines from a Windows .def file.
+sed_uncomment_deffile='/^;/d; /^[ ]*$/d'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "$1" | $SED \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $opt_debug
+
+ $SED -n '/(C)/!b go
+ :more
+ /\./!{
+ N
+ s/\n# / /
+ b more
+ }
+ :go
+ /^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/^# *.*--help/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ echo
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+ p
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
+ ret=$?
+ if test -z "$1"; then
+ exit $ret
+ fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $opt_debug
+
+ func_error "missing argument for $1."
+ exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
+
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+ # this just eases exit handling
+ while test $# -gt 0; do
+ opt="$1"
+ shift
+ case $opt in
+ --debug|-x) opt_debug='set -x'
+ func_echo "enabling shell trace mode"
+ $opt_debug
+ ;;
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+ shift
+ ;;
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=:
+ ;;
+ --features)
+ opt_features=:
+func_features
+ ;;
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
+ opt_silent=false
+func_append preserve_args " $opt"
+ ;;
+ --no-warning|--no-warn)
+ opt_warning=false
+func_append preserve_args " $opt"
+ ;;
+ --no-verbose)
+ opt_verbose=false
+func_append preserve_args " $opt"
+ ;;
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
+
+ # Separate optargs to long options:
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # Validate options:
+
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
+ fi
+
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
+
+
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case "$lt_sysroot:$1" in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result="=$func_stripname_result"
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $opt_debug
+ func_convert_core_file_wine_to_w32_result="$1"
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $opt_debug
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=""
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $opt_debug
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $opt_debug
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " \`$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result="$1"
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $opt_debug
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " \`$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result="$3"
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $opt_debug
+ case $4 in
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $opt_debug
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $opt_debug
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $opt_debug
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $opt_debug
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_append_quoted lastarg "$arg"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test "$opt_help" = :; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | sed -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ sed '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "\`$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument \`$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test "x$prev" = x-m && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=""
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname" ; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename="$func_basename_result"
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename" ; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $opt_debug
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $opt_debug
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ if test "$lock_old_archive_extraction" = yes; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test "$lock_old_archive_extraction" = yes; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+# define _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (strcmp (argv[i], debug_opt) == 0)
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $opt_debug
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir="$arg"
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps ; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test "$prefer_static_libs" = yes ||
+ test "$prefer_static_libs,$installed" = "built,no"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$lt_sysroot$libdir"
+ absdir="$lt_sysroot$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ case "$host" in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ echo
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$opt_mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$absdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$opt_mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ func_append libobjs " $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$opt_mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test "$want_nocaseglob" = yes; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Remove ${wl} instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED "$sed_uncomment_deffile" $export_symbols | $SED 1q`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd1 in $cmds; do
+ IFS="$save_ifs"
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test "$try_normal_branch" = yes \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=${output_objdir}/${output_la}.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ func_append oldobjs " $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ func_resolve_sysroot "$deplib"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test "x$bindir" != x ;
+ then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=yes ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ odir="$objdir"
+ else
+ odir="$dir/$objdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$opt_mode" = uninstall && odir="$dir"
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test "$opt_mode" = clean; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case "$opt_mode" in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$opt_mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ func_append rmfiles " $odir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
diff --git a/comm/third_party/libgcrypt/build-aux/mdate-sh b/comm/third_party/libgcrypt/build-aux/mdate-sh
new file mode 100755
index 0000000000..b3719cf761
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/mdate-sh
@@ -0,0 +1,224 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2010-08-21.06; # UTC
+
+# Copyright (C) 1995-2013 Free Software Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program 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 General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+fi
+
+case $1 in
+ '')
+ echo "$0: No file. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification day of FILE, in the format:
+1 January 1970
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "mdate-sh $scriptversion"
+ exit $?
+ ;;
+esac
+
+error ()
+{
+ echo "$0: $1" >&2
+ exit 1
+}
+
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# GNU ls changes its time format in response to the TIME_STYLE
+# variable. Since we cannot assume 'unset' works, revert this
+# variable to its documented default.
+if test "${TIME_STYLE+set}" = set; then
+ TIME_STYLE=posix-long-iso
+ export TIME_STYLE
+fi
+
+save_arg1=$1
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ ls_command='ls -L -l -d'
+else
+ ls_command='ls -l -d'
+fi
+# Avoid user/group names that might have spaces, when possible.
+if ls -n /dev/null 1>/dev/null 2>&1; then
+ ls_command="$ls_command -n"
+fi
+
+# A 'ls -l' line looks as follows on OS/2.
+# drwxrwx--- 0 Aug 11 2001 foo
+# This differs from Unix, which adds ownership information.
+# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month. This cannot work with files whose owner is a
+# user named "Jan", or "Feb", etc. However, it's unlikely that '/'
+# will be owned by a user whose name is a month. So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`$ls_command /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+ test $# -gt 0 || error "failed parsing '$ls_command /' output"
+ shift
+ # Add another shift to the command.
+ command="$command shift;"
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+test -n "$month" || error "failed parsing '$ls_command /' output"
+
+# Get the extended ls output of the file or directory.
+set dummy x`eval "$ls_command \"\\\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Because of the dummy argument above, month is in $2.
+#
+# On a POSIX system, we should have
+#
+# $# = 5
+# $1 = file size
+# $2 = month
+# $3 = day
+# $4 = year or time
+# $5 = filename
+#
+# On Darwin 7.7.0 and 7.6.0, we have
+#
+# $# = 4
+# $1 = day
+# $2 = month
+# $3 = year or time
+# $4 = filename
+
+# Get the month.
+case $2 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+esac
+
+case $3 in
+ ???*) day=$1;;
+ *) day=$3; shift;;
+esac
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/comm/third_party/libgcrypt/build-aux/missing b/comm/third_party/libgcrypt/build-aux/missing
new file mode 100755
index 0000000000..db98974ff5
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program 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 General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+fi
+
+case $1 in
+
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
+
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'autom4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/comm/third_party/libgcrypt/build-aux/texinfo.tex b/comm/third_party/libgcrypt/build-aux/texinfo.tex
new file mode 100644
index 0000000000..5a17f97938
--- /dev/null
+++ b/comm/third_party/libgcrypt/build-aux/texinfo.tex
@@ -0,0 +1,8638 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2007-05-03.09}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007 Free Software Foundation, Inc.
+%
+% This texinfo.tex file is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 3, or (at
+% your option) any later version.
+%
+% This texinfo.tex file 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 General Public License
+% along with this texinfo.tex file; see the file COPYING. If not,
+% see <http://www.gnu.org/licenses/>.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+% ftp://tug.org/tex/texinfo.tex
+% (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org. Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem. Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For a simple
+% manual foo.texi, however, you can get away with this:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent. You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar = `\-
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar = `\;
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+ ap-pen-dix bit-map bit-maps
+ data-base data-bases eshell fall-ing half-way long-est man-u-script
+ man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+ par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+ spell-ing spell-ings
+ stand-alone strong-est time-stamp time-stamps which-ever white-space
+ wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal. We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+ \tracingstats2
+ \tracingpages1
+ \tracinglostchars2 % 2 gives us more in etex
+ \tracingparagraphs1
+ \tracingoutput1
+ \tracingmacros2
+ \tracingrestores1
+ \showboxbreadth\maxdimen \showboxdepth\maxdimen
+ \ifx\eTeXversion\undefined\else % etex gives us more logging
+ \tracingscantokens1
+ \tracingifs1
+ \tracinggroups1
+ \tracingnesting2
+ \tracingassigns1
+ \fi
+ \tracingcommands3 % 3 gives us more in etex
+ \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions. If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+ \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+ \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+ \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ % We don't want .vr (or whatever) entries like this:
+ % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+ % "\acronym" won't work when it's read back in;
+ % it needs to be
+ % {\code {{\tt \backslashcurfont }acronym}
+ \shipout\vbox{%
+ % Do this early so pdf references go to the beginning of the page.
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+ %
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \vskip-\topandbottommargin
+ \vtop to0pt{%
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vss}%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingyyy.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 24pt
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \vbox to0pt{\vss
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ }%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \indexdummies
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\argtorun{#2}%
+ \begingroup
+ \obeylines
+ \spaceisspace
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ \argremovecomment #1\comment\ArgTerm%
+ }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+% @end itemize @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
+
+\def\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
+
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
+
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as environments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \badenverr
+ \fi
+}
+
+% Environment mismatch, #1 expected:
+\def\badenverr{%
+ \errhelp = \EMsimple
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ out of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ptexi
+ \else\ifx\temp\jmacro \j
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+ \kern-.15em
+ \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \plainfrenchspacing
+ \else\ifx\temp\offword \plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+ \fi\fi
+}
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large. This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material. In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom. The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+ % Ensure vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % If the @need value is less than one line space, it's useless.
+ \dimen0 = #1\mil
+ \dimen2 = \ht\strutbox
+ \advance\dimen2 by \dp\strutbox
+ \ifdim\dimen0 > \dimen2
+ %
+ % Do a \strut just to make the height of this box be normal, so the
+ % normal leading is inserted relative to the preceding line.
+ % And a page break here is fine.
+ \vtop to #1\mil{\strut\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+ \fi
+}
+
+% @br forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph. For more general purposes, use the \margin insertion
+% class. WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+ \nobreak
+ \kern-\strutdepth
+ \vtop to \strutdepth{%
+ \baselineskip=\strutdepth
+ \vss
+ % if you have multiple lines of stuff to put here, you'll need to
+ % make the vbox yourself of the appropriate size.
+ \ifx#1l%
+ \llap{\ignorespaces #2\hskip\inmarginspacing}%
+ \else
+ \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+ \fi
+ \null
+ }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \def\lefttext{#1}% have both texts
+ \def\righttext{#2}%
+ \else
+ \def\lefttext{#1}% have only one text
+ \def\righttext{#1}%
+ \fi
+ %
+ \ifodd\pageno
+ \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+ \else
+ \def\temp{\inleftmargin\lefttext}%
+ \fi
+ \temp
+}
+
+% @include file insert text of that file as input.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable
+ \def\temp{\input #1 }%
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
+ \catcode`\\=\other
+ \catcode`~=\other
+ \catcode`^=\other
+ \catcode`_=\other
+ \catcode`|=\other
+ \catcode`<=\other
+ \catcode`>=\other
+ \catcode`+=\other
+ \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+ \ifhmode
+ \let\next\centerH
+ \else
+ \let\next\centerV
+ \fi
+ \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+ {%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+ }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \defaultparindent = 0pt
+ \else
+ \defaultparindent = #1em
+ \fi
+ \fi
+ \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \lispnarrowing = 0pt
+ \else
+ \lispnarrowing = #1em
+ \fi
+ \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading. If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\noneword
+ \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+ \else\ifx\temp\insertword
+ \let\suppressfirstparagraphindent = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @firstparagraphindent option `\temp'}%
+ \fi\fi
+}
+
+% Here is how we actually suppress indentation. Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+ \gdef\indent{%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
+ }%
+ \global\everypar = {%
+ \kern -\parindent
+ \restorefirstparagraphindent
+ }%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
+
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care. Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ }
+}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \iflinks
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ \openin 1 texinfo.cnf
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
+ %
+ \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set). So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdftrue
+ \fi
+ \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places. Thus, we have to
+% double any backslashes. Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e. Not good.
+% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
+% (and related messages, the final outcome is that it is up to the TeX
+% user to double the backslashes and otherwise make the string valid, so
+% that's what we do).
+
+% double active backslashes.
+%
+{\catcode`\@=0 \catcode`\\=\active
+ @gdef@activebackslashdouble{%
+ @catcode`@\=@active
+ @let\=@doublebackslash}
+}
+
+% To handle parens, we must adopt a different approach, since parens are
+% not active characters. hyperref.dtx (which has the same problem as
+% us) handles it with this amazing macro to replace tokens, with minor
+% changes for Texinfo. It is included here under the GPL by permission
+% from the author, Heiko Oberdiek.
+%
+% #1 is the tokens to replace.
+% #2 is the replacement.
+% #3 is the control sequence with the string.
+%
+\def\HyPsdSubst#1#2#3{%
+ \def\HyPsdReplace##1#1##2\END{%
+ ##1%
+ \ifx\\##2\\%
+ \else
+ #2%
+ \HyReturnAfterFi{%
+ \HyPsdReplace##2\END
+ }%
+ \fi
+ }%
+ \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
+}
+\long\def\HyReturnAfterFi#1\fi{\fi#1}
+
+% #1 is a control sequence in which to do the replacements.
+\def\backslashparens#1{%
+ \xdef#1{#1}% redefine it as its expansion; the definition is simply
+ % \lastnode when called from \setref -> \pdfmkdest.
+ \HyPsdSubst{(}{\realbackslash(}{#1}%
+ \HyPsdSubst{)}{\realbackslash)}{#1}%
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found. (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+ \input pdfcolor
+ \pdfcatalog{/PageMode /UseOutlines}
+ %
+ % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+ \def\dopdfimage#1#2#3{%
+ \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ %
+ % pdftex (and the PDF format) support .png, .jpg, .pdf (among
+ % others). Let's try in that order.
+ \let\pdfimgext=\empty
+ \begingroup
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
+ \openin 1 #1.pdf \ifeof 1
+ \errhelp = \nopdfimagehelp
+ \errmessage{Could not find image file #1 for pdf}%
+ \else \gdef\pdfimgext{pdf}%
+ \fi
+ \else \gdef\pdfimgext{JPG}%
+ \fi
+ \else \gdef\pdfimgext{jpeg}%
+ \fi
+ \else \gdef\pdfimgext{jpg}%
+ \fi
+ \else \gdef\pdfimgext{png}%
+ \fi
+ \closein 1
+ \endgroup
+ %
+ % without \immediate, pdftex seg faults when the same image is
+ % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
+ \ifnum\pdftexversion < 14
+ \immediate\pdfimage
+ \else
+ \immediate\pdfximage
+ \fi
+ \ifdim \wd0 >0pt width \imagewidth \fi
+ \ifdim \wd2 >0pt height \imageheight \fi
+ \ifnum\pdftexversion<13
+ #1.\pdfimgext
+ \else
+ {#1.\pdfimgext}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ %
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code, and characters
+ % such as \, aren't expanded when present in a section title.
+ \indexnofonts
+ \turnoffactive
+ \activebackslashdouble
+ \makevalueexpandable
+ \def\pdfdestname{#1}%
+ \backslashparens\pdfdestname
+ \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+ }}
+ %
+ % used to mark target names; must be expandable.
+ \def\pdfmkpgn#1{#1}
+ %
+ % by default, use a color that is dark enough to print on paper as
+ % nearly black, but still distinguishable for online viewing.
+ % (Defined in pdfcolor.tex.)
+ \let\urlcolor = \BrickRed
+ \let\linkcolor = \BrickRed
+ \def\endlink{\Black\pdfendlink}
+ %
+ % Adding outlines to PDF; macros for calculating structure of outlines
+ % come from Petr Olsak
+ \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi}
+ \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+ \advance\tempnum by 1
+ \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+ %
+ % #1 is the section text, which is what will be displayed in the
+ % outline by the pdf viewer. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node text,
+ % which might be empty if this toc entry had no corresponding node.
+ % #4 is the page number
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worth the trouble, since most documents are normally structured.
+ \def\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty
+ \def\pdfoutlinedest{#4}%
+ \else
+ % Doubled backslashes in the name.
+ {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
+ \backslashparens\pdfoutlinedest}%
+ \fi
+ %
+ % Also double the backslashes in the display string.
+ {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
+ \backslashparens\pdfoutlinetext}%
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
+ % Thanh's hack / proper braces in bookmarks
+ \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+ \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+ %
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\numchapentry##1##2##3##4{%
+ \def\thischapnum{##2}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
+ \readdatafile{toc}%
+ %
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
+ %
+ % PDF outlines are displayed using system fonts, instead of
+ % document fonts. Therefore we cannot use special characters,
+ % since the encoding is unknown. For example, the eogonek from
+ % Latin 2 (0xea) gets translated to a | character. Info from
+ % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+ %
+ % xx to do this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Right
+ % now, I guess we'll just let the pdf reader have its way.
+ \indexnofonts
+ \setupdatafile
+ \catcode`\\=\active \otherbackslash
+ \input \jobname.toc
+ \endgroup
+ }
+ %
+ \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+ \ifx\PP\D\let\nextsp\relax
+ \else\let\nextsp\skipspaces
+ \ifx\p\space\else\addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
+ \fi
+ \fi
+ \nextsp}
+ \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+ \ifnum\pdftexversion < 14
+ \let \startlink \pdfannotlink
+ \else
+ \let \startlink \pdfstartlink
+ \fi
+ % make a live url in pdf output.
+ \def\pdfurl#1{%
+ \begingroup
+ % it seems we really need yet another set of dummies; have not
+ % tried to figure out what each command should do in the context
+ % of @url. for now, just make @/ a no-op, that's the only one
+ % people have actually reported a problem with.
+ %
+ \normalturnoffactive
+ \def\@{@}%
+ \let\/=\empty
+ \makevalueexpandable
+ \leavevmode\urlcolor
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+ \endgroup}
+ \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+ \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+ \def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makelink\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next}
+ \def\makelink{\addtokens{\toksB}%
+ {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+ \def\pdflink#1{%
+ \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+ \linkcolor #1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\linkcolor = \relax
+ \let\pdfmakeoutlines = \relax
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Default leading.
+\newdimen\textleading \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+ \normalbaselineskip = #1\relax
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+%
+% PDF CMaps. See also LaTeX's t1.cmap.
+%
+% \cmapOT1
+\ifpdf
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1IT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1TT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+\else
+ \expandafter\let\csname cmapOT1\endcsname\gobble
+ \expandafter\let\csname cmapOT1IT\endcsname\gobble
+ \expandafter\let\csname cmapOT1TT\endcsname\gobble
+\fi
+
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+% empty to omit).
+\def\setfont#1#2#3#4#5{%
+ \font#1=\fontprefix#2#3 scaled #4
+ \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt. This is the default in
+% Texinfo.
+%
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 11pt text font size definitions
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit. This is for the GNU
+% Press printing of the Emacs 22 manual. Maybe other manuals in the
+% future. Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+
+% reduce space between paragraphs
+\divide\parskip by 2
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 10pt text font size definitions
+
+
+% We provide the user-level command
+% @fonttextsize 10
+% (or 11) to redefine the text font size. pt is assumed.
+%
+\def\xword{10}
+\def\xiword{11}
+%
+\parseargdef\fonttextsize{%
+ \def\textsizearg{#1}%
+ \wlog{doing @fonttextsize \textsizearg}%
+ %
+ % Set \globaldefs so that documents can use this inside @tex, since
+ % makeinfo 4.8 does not support it, but we need it nonetheless.
+ %
+ \begingroup \globaldefs=1
+ \ifx\textsizearg\xword \definetextfontsizex
+ \else \ifx\textsizearg\xiword \definetextfontsizexi
+ \else
+ \errhelp=\EMsimple
+ \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+ \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+ \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+ \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tenttsl=\textttsl
+ \def\curfontsize{text}%
+ \def\lsize{reduced}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \def\curfontsize{title}%
+ \def\lsize{chap}\def\lllsize{subsec}%
+ \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \let\tenttsl=\chapttsl
+ \def\curfontsize{chap}%
+ \def\lsize{sec}\def\lllsize{text}%
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \let\tenttsl=\secttsl
+ \def\curfontsize{sec}%
+ \def\lsize{subsec}\def\lllsize{reduced}%
+ \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \let\tenttsl=\ssecttsl
+ \def\curfontsize{ssec}%
+ \def\lsize{text}\def\lllsize{small}%
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+ \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+ \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+ \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+ \let\tenttsl=\smallttsl
+ \def\curfontsize{small}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+ \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+ \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+ \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+ \let\tenttsl=\smallerttsl
+ \def\curfontsize{smaller}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+% 8.5x11=86 smallbook=72 a4=90 a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+% 8.5x11=90+ smallbook=80 a4=90+ a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt. So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+% 8.5x11=71 smallbook=60 a4=75 a5=58
+%
+% I wish the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+ \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+ \def\plainfrenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ \def\endofsentencespacefactor{1000}% for @. and friends
+ }
+ \def\plainnonfrenchspacing{%
+ \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+ \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+ \def\endofsentencespacefactor{3000}% for @. and friends
+ }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+\def\t#1{%
+ {\tt \rawbackslash \plainfrenchspacing #1}%
+ \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}{OT1}
+\font\keysy=cmsy9
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+ \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+ \vbox{\hrule\kern-0.4pt
+ \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+ \kern-0.4pt\hrule}%
+ \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+\def\key #1{{\nohyphenation \uppercase{#1}}\null}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \plainfrenchspacing
+ #1%
+ }%
+ \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+% -- rms.
+{
+ \catcode`\-=\active \catcode`\_=\active
+ \catcode`\'=\active \catcode`\`=\active
+ %
+ \global\def\code{\begingroup
+ \catcode\rquoteChar=\active \catcode\lquoteChar=\active
+ \let'\codequoteright \let`\codequoteleft
+ %
+ \catcode\dashChar=\active \catcode\underChar=\active
+ \ifallowcodebreaks
+ \let-\codedash
+ \let_\codeunder
+ \else
+ \let-\realdash
+ \let_\realunder
+ \fi
+ \codex
+ }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+ % this is all so @math{@code{var_name}+1} can work. In math mode, _
+ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+ % will therefore expand the active definition of _, which is us
+ % (inside @code that is), therefore an endless loop.
+ \ifusingtt{\ifmmode
+ \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+ \else\normalunderscore \fi
+ \discretionary{}{}{}}%
+ {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__. This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general. @allowcodebreaks provides a way to control this.
+%
+\newif\ifallowcodebreaks \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\keywordtrue
+ \allowcodebreakstrue
+ \else\ifx\txiarg\keywordfalse
+ \allowcodebreaksfalse
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+ \fi\fi
+}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself. First (mandatory) arg is the url. Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \code{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+ \def\email#1{\doemail#1,,\finish}
+ \def\doemail#1,#2,#3\finish{\begingroup
+ \unsepspaces
+ \pdfurl{mailto:#1}%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+ \endlink
+ \endgroup}
+\else
+ \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+ {\plainfrenchspacing #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
+ }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \begingroup
+ \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \let\page = \oldpage
+ \page
+ \null
+ }%
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+ \let\tt=\authortt}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \leftline{\titlefonts\rm #1}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ \def\quotationauthor{#1}% printed in \Equotation.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\authorfont \leftline{#1}}%
+ \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline % headline on even pages
+\newtoks\oddheadline % headline on odd pages
+\newtoks\evenfootline % footline on even pages
+\newtoks\oddfootline % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -12pt
+ \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+ \number\day\space
+ \ifcase\month
+ \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+ \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+ \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+ \fi
+ \space\number\year}
+\fi
+
+% @settitle line... specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemindicate{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. However, if
+ % what follows is an environment such as @example, there will be no
+ % \parskip glue; then the negative vskip we just inserted would
+ % cause the example and the item to crash together. So we use this
+ % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+ % \parskip glue after all. Section titles are handled this way also.
+ %
+ \penalty 10001
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line.
+ \noindent
+ % Do this with kerns and \unhbox so that if there is a footnote in
+ % the item text, it can migrate to the main vertical list and
+ % eventually be printed.
+ \nobreak\kern-\tableindent
+ \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+ \unhbox0
+ \nobreak\kern\dimen0
+ \endgroup
+ \itemxneedsnegativevskiptrue
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablecheck{table}%
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablecheck{ftable}%
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ \def\itemcontents{#1}%
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+ \advance\itemno by 1 % for enumerations
+ {\let\par=\endgraf \smallbreak}% reasonable place to break
+ {%
+ % If the document has an @itemize directly after a section title, a
+ % \nobreak will be last on the list, and \sectionheading will have
+ % done a \vskip-\parskip. In that case, we don't want to zero
+ % parskip, or the item text will crash with the heading. On the
+ % other hand, when there is normal text preceding the item (as there
+ % usually is), we do want to zero parskip, or there would be too much
+ % space. In that case, we won't have a \nobreak before. At least
+ % that's the theory.
+ \ifnum\lastpenalty<10000 \parskip=0in \fi
+ \noindent
+ \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ \vadjust{\penalty 1200}}% not good to break after first line of item.
+ \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1. We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+ \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+ \def\firstarg{#1}%
+ \ifx\firstarg\xendsetuptable
+ \let\go = \relax
+ \else
+ \ifx\firstarg\xcolumnfractions
+ \global\setpercenttrue
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction
+ \else
+ \global\advance\colcount by 1
+ \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+ % separator; typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi
+ \fi
+ \ifx\go\pickupwholefraction
+ % Put the argument back for the \pickupwholefraction call, so
+ % we'll always have a period there to be parsed.
+ \def\go{\pickupwholefraction#1}%
+ \else
+ \let\go = \setuptable
+ \fi%
+ \fi
+ \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry. Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp. But then the space in a template
+% line is not enough. That is bad. So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+% --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ % We use \def instead of \let so that if one of the multitable entries
+ % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+ % \endtemplate) expanding \doitemize.
+ \def\item{\crcr}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}%
+ \global\colcount=0 % Reset the column counter.
+ % Check for saved footnotes, etc.
+ \checkinserts
+ % Keeps underfull box messages off when table breaks over pages.
+ %\filbreak
+ % Maybe so, but it also creates really weird page breaks when the
+ % table breaks over pages. Wouldn't \vfil be better? Wait until the
+ % problem manifests itself, so it can be fixed for real --karl.
+ }%
+ }%
+ %
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup &%
+ \global\advance\colcount by 1
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively
+ % marking characters.
+ \noindent\ignorespaces##\unskip\multistrut
+ }\cr
+}
+\def\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%% If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+ % Scan in ``verbatim'' mode:
+ \obeylines
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \spaceisspace
+ %
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
+ %
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
+ %
+ \gdef\dodoignore#1{%
+ % #1 contains the command name as a string, e.g., `ifinfo'.
+ %
+ % Define a command to find the next `@end #1'.
+ \long\def\doignoretext##1^^M@end #1{%
+ \doignoretextyyy##1^^M@#1\_STOP_}%
+ %
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+ %
+ % And now expand that command.
+ \doignoretext ^^M%
+ }%
+}
+
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+ % Ignore anything after the last `@end #1'; this matters in verbatim
+ % environments, where otherwise the newline after an ignored conditional
+ % would result in a blank line in the output.
+ \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ {%
+ \makevalueexpandable
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+ }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \global\expandafter\let\csname SET#1\endcsname=\relax
+ }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+ \catcode`\- = \active \catcode`\_ = \active
+ %
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
+ \catcode`\-=\other \catcode`\_=\other
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\realdash \let_\normalunderscore
+ }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']}%
+ \message{Variable `#1', used in @value, is not set.}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+ % Only do \closeout if we haven't already done it, else we'll end up
+ % closing the target index.
+ \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \expandafter\closeout\csname#2indfile\endcsname
+ \expandafter\let\csname\donesynindex#2\endcsname = 1
+ \fi
+ % redefine \fooindfile:
+ \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+ \expandafter\let\csname#2indfile\endcsname=\temp
+ % redefine \fooindex:
+ \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+ \escapechar = `\\ % use backslash in output files.
+ \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+ \def\ {\realbackslash\space }%
+ %
+ % Need these in case \tex is in effect and \{ is a \delimiter again.
+ % But can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters.
+ \let\{ = \mylbrace
+ \let\} = \myrbrace
+ %
+ % I don't entirely understand this, but when an index entry is
+ % generated from a macro call, the \endinput which \scanmacro inserts
+ % causes processing to be prematurely terminated. This is,
+ % apparently, because \indexsorttmp is fully expanded, and \endinput
+ % is an expandable command. The redefinition below makes \endinput
+ % disappear altogether for that purpose -- although logging shows that
+ % processing continues to some further point. On the other hand, it
+ % seems \endinput does not hurt in the printed index arg, since that
+ % is still getting written without apparent harm.
+ %
+ % Sample source (mac-idx3.tex, reported by Graham Percival to
+ % help-texinfo, 22may06):
+ % @macro funindex {WORD}
+ % @findex xyz
+ % @end macro
+ % ...
+ % @funindex commtest
+ %
+ % The above is not enough to reproduce the bug, but it gives the flavor.
+ %
+ % Sample whatsit resulting:
+ % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+ %
+ % So:
+ \let\endinput = \empty
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux and toc files, @ is the escape character. So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files). When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % Do the redefinitions.
+ \commondummies
+ \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+ %
+ % \definedummyword defines \#1 as \string\#1\space, thus effectively
+ % preventing its expansion. This is used only for control% words,
+ % not control letters, because the \space would be incorrect for
+ % control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword ##1{\def##1{\string##1\space}}%
+ \def\definedummyletter##1{\def##1{\string##1}}%
+ \let\definedummyaccent\definedummyletter
+ %
+ \commondummiesnofonts
+ %
+ \definedummyletter\_%
+ %
+ % Non-English letters.
+ \definedummyword\AA
+ \definedummyword\AE
+ \definedummyword\L
+ \definedummyword\OE
+ \definedummyword\O
+ \definedummyword\aa
+ \definedummyword\ae
+ \definedummyword\l
+ \definedummyword\oe
+ \definedummyword\o
+ \definedummyword\ss
+ \definedummyword\exclamdown
+ \definedummyword\questiondown
+ \definedummyword\ordf
+ \definedummyword\ordm
+ %
+ % Although these internal commands shouldn't show up, sometimes they do.
+ \definedummyword\bf
+ \definedummyword\gtr
+ \definedummyword\hat
+ \definedummyword\less
+ \definedummyword\sf
+ \definedummyword\sl
+ \definedummyword\tclose
+ \definedummyword\tt
+ %
+ \definedummyword\LaTeX
+ \definedummyword\TeX
+ %
+ % Assorted special characters.
+ \definedummyword\bullet
+ \definedummyword\comma
+ \definedummyword\copyright
+ \definedummyword\registeredsymbol
+ \definedummyword\dots
+ \definedummyword\enddots
+ \definedummyword\equiv
+ \definedummyword\error
+ \definedummyword\euro
+ \definedummyword\expansion
+ \definedummyword\minus
+ \definedummyword\pounds
+ \definedummyword\point
+ \definedummyword\print
+ \definedummyword\result
+ \definedummyword\textdegree
+ %
+ % We want to disable all macros so that they are not expanded by \write.
+ \macrolist
+ %
+ \normalturnoffactive
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sc
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\acronym
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\pxref
+ \definedummyword\ref
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ \definedummyword\xref
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names. It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+ % Accent commands should become @asis.
+ \def\definedummyaccent##1{\let##1\asis}%
+ % We can just ignore other control letters.
+ \def\definedummyletter##1{\let##1\empty}%
+ % Hopefully, all control words can become @asis.
+ \let\definedummyword\definedummyaccent
+ %
+ \commondummiesnofonts
+ %
+ % Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |, etc.
+ % Likewise with the other plain tex font commands.
+ %\let\tt=\asis
+ %
+ \def\ { }%
+ \def\@{@}%
+ % how to handle braces?
+ \def\_{\normalunderscore}%
+ %
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\o{o}%
+ \def\ss{ss}%
+ \def\exclamdown{!}%
+ \def\questiondown{?}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ %
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+ %
+ % Assorted special characters.
+ % (The following {} will end up in the sort string, but that's ok.)
+ \def\bullet{bullet}%
+ \def\comma{,}%
+ \def\copyright{copyright}%
+ \def\registeredsymbol{R}%
+ \def\dots{...}%
+ \def\enddots{...}%
+ \def\equiv{==}%
+ \def\error{error}%
+ \def\euro{euro}%
+ \def\expansion{==>}%
+ \def\minus{-}%
+ \def\pounds{pounds}%
+ \def\point{.}%
+ \def\print{-|}%
+ \def\result{=>}%
+ \def\textdegree{degrees}%
+ %
+ % We need to get rid of all macros, leaving only the arguments (if present).
+ % Of course this is not nearly correct, but it is the best we can do for now.
+ % makeinfo does not expand macros in the argument to @deffn, which ends up
+ % writing an index entry, and texindex isn't prepared for an index sort entry
+ % that starts with \.
+ %
+ % Since macro invocations are followed by braces, we can just redefine them
+ % to take a single TeX argument. The case of a macro invocation that
+ % goes to end-of-line is not handled.
+ %
+ \macrolist
+}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \safewhatsit\dosubindwrite
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+ \fi
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+ }%
+ \temp
+}
+
+% Take care of unwanted page breaks/skips around a whatsit:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write or \pdfdest will make \lastskip zero. The result is that
+% sequences like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{%
+\ifhmode
+ #1%
+\else
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \whatsitskip = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \whatsitpenalty = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\skip0 glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\whatsitskip
+ \fi
+ %
+ #1%
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % If \lastskip was zero, perhaps the last item was a penalty, and
+ % perhaps it was >=10000, e.g., a \nobreak. In that case, we want
+ % to re-insert the same penalty (values >10000 are used for various
+ % signals); since we just inserted a non-discardable item, any
+ % following glue (such as a \parskip) would be a breakpoint. For example:
+ %
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\whatsitskip
+ \fi
+\fi
+}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \plainfrenchspacing
+ \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ \putwordIndexNonexistent
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ \putwordIndexIsEmpty
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\backslashcurfont}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+ % Some minor font changes for the special characters.
+ \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+ %
+ % Remove any glue we may have, we'll be inserting our own.
+ \removelastskip
+ %
+ % We like breaks before the index initials, so insert a bonus.
+ \nobreak
+ \vskip 0pt plus 3\baselineskip
+ \penalty 0
+ \vskip 0pt plus -3\baselineskip
+ %
+ % Typeset the initial. Making this add up to a whole number of
+ % baselineskips increases the chance of the dots lining up from column
+ % to column. It still won't often be perfect, because of the stretch
+ % we need before each entry, but it's better.
+ %
+ % No shrink because it confuses \balancecolumns.
+ \vskip 1.67\baselineskip plus .5\baselineskip
+ \leftline{\secbf #1}%
+ % Do our best not to break after the initial.
+ \nobreak
+ \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+% \def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which sets - active. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \def\tempa{{\rm }}%
+ \def\tempb{#1}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd
+ \ %
+ \else
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.%
+ \ \the\toksA
+ \else
+ \ #1%
+ \fi
+ \fi
+ \par
+ \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+ \parfillskip=0in
+ \parskip=0in
+ \hangindent=1in
+ \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+ \ifpdf
+ \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ \else
+ #2
+ \fi
+ \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case we just ship out what is in \partialpage with the normal
+ % output routine. Generally, \partialpage will be empty when this
+ % runs and this will be a no-op. See the indexspread.tex test case.
+ \ifvoid\partialpage \else
+ \onepageout{\pagecontents\partialpage}%
+ \fi
+ %
+ \global\setbox\partialpage = \vbox{%
+ % Unvbox the main output page.
+ \unvbox\PAGE
+ \kern-\topskip \kern\baselineskip
+ }%
+ }%
+ \eject % run that output routine to set \partialpage
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@ = \vsize
+ \divide\dimen@ by 2
+ \advance\dimen@ by -\ht\partialpage
+ %
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+ \unvbox\partialpage
+ %
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize
+ \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+ % The following penalty ensures that the page builder is exercised
+ % _before_ we change the output routine. This is necessary in the
+ % following situation:
+ %
+ % The last section of the index consists only of a single entry.
+ % Before this section, \pagetotal is less than \pagegoal, so no
+ % break occurs before the last section starts. However, the last
+ % section, consisting of \initial and the single \entry, does not
+ % fit on the page and has to be broken off. Without the following
+ % penalty the page builder will not be exercised until \eject
+ % below, and by that time we'll already have changed the output
+ % routine to the \balancecolumns version, so the next-to-last
+ % double-column page will be processed with \balancecolumns, which
+ % is wrong: The two columns will go to the main vertical list, with
+ % the broken-off section in the recent contributions. As soon as
+ % the output routine finishes, TeX starts reconsidering the page
+ % break. The two columns and the broken-off section both fit on the
+ % page, because the two columns now take up only half of the page
+ % goal. When TeX sees \eject from below which follows the final
+ % section, it invokes the new output routine that we've set after
+ % \balancecolumns below; \onepageout will try to fit the two columns
+ % and the final section into the vbox of \pageheight (see
+ % \pagebody), causing an overfull box.
+ %
+ % Note that glue won't work here, because glue does not exercise the
+ % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+ \penalty0
+ %
+ \output = {%
+ % Split the last of the double-column material. Leave it on the
+ % current page, no automatic page break.
+ \balancecolumns
+ %
+ % If we end up splitting too much material for the current page,
+ % though, there will be another page break right after this \output
+ % invocation ends. Having called \balancecolumns once, we do not
+ % want to call it again. Therefore, reset \output to its normal
+ % definition right away. (We hope \balancecolumns will never be
+ % called on to balance too much material, but if it is, this makes
+ % the output somewhat more palatable.)
+ \global\output = {\onepageout{\pagecontents\PAGE}}%
+ }%
+ \eject
+ \endgroup % started in \begindoublecolumns
+ %
+ % \pagegoal was set to the doubled \vsize above, since we restarted
+ % the current page. We're now back to normal single-column
+ % typesetting, so reset \pagegoal to the normal \vsize (after the
+ % \endgroup where \vsize got restored).
+ \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+ \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2 % target to split to
+ %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {%
+ \vbadness = 10000
+ \loop
+ \global\setbox3 = \copy0
+ \global\setbox1 = \vsplit3 to \dimen@
+ \ifdim\ht3>\dimen@
+ \global\advance\dimen@ by 1pt
+ \repeat
+ }%
+ %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ %
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+ \ifnum\appendixno=`A A%
+ \else\ifnum\appendixno=`B B%
+ \else\ifnum\appendixno=`C C%
+ \else\ifnum\appendixno=`D D%
+ \else\ifnum\appendixno=`E E%
+ \else\ifnum\appendixno=`F F%
+ \else\ifnum\appendixno=`G G%
+ \else\ifnum\appendixno=`H H%
+ \else\ifnum\appendixno=`I I%
+ \else\ifnum\appendixno=`J J%
+ \else\ifnum\appendixno=`K K%
+ \else\ifnum\appendixno=`L L%
+ \else\ifnum\appendixno=`M M%
+ \else\ifnum\appendixno=`N N%
+ \else\ifnum\appendixno=`O O%
+ \else\ifnum\appendixno=`P P%
+ \else\ifnum\appendixno=`Q Q%
+ \else\ifnum\appendixno=`R R%
+ \else\ifnum\appendixno=`S S%
+ \else\ifnum\appendixno=`T T%
+ \else\ifnum\appendixno=`U U%
+ \else\ifnum\appendixno=`V V%
+ \else\ifnum\appendixno=`W W%
+ \else\ifnum\appendixno=`X X%
+ \else\ifnum\appendixno=`Y Y%
+ \else\ifnum\appendixno=`Z Z%
+ % The \the is necessary, despite appearances, because \appendixletter is
+ % expanded while writing the .toc file. \char\appendixno is not
+ % expandable, thus it is written literally, thus all appendixes come out
+ % with the same letter (or @) in the toc without it.
+ \else\char\the\appendixno
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise.
+% However, they are not reliable, because we don't use marks.
+\def\thischapter{}
+\def\thissection{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+ % Compute the abs. sec. level:
+ \absseclevel=#2
+ \advance\absseclevel by \secbase
+ % Make sure \absseclevel doesn't fall outside the range:
+ \ifnum \absseclevel < 0
+ \absseclevel = 0
+ \else
+ \ifnum \absseclevel > 3
+ \absseclevel = 3
+ \fi
+ \fi
+ % The heading type:
+ \def\headtype{#1}%
+ \if \headtype U%
+ \ifnum \absseclevel < \unmlevel
+ \chardef\unmlevel = \absseclevel
+ \fi
+ \else
+ % Check for appendix sections:
+ \ifnum \absseclevel = 0
+ \edef\chapheadtype{\headtype}%
+ \else
+ \if \headtype A\if \chapheadtype N%
+ \errmessage{@appendix... within a non-appendix chapter}%
+ \fi\fi
+ \fi
+ % Check for numbered within unnumbered:
+ \ifnum \absseclevel > \unmlevel
+ \def\headtype{U}%
+ \else
+ \chardef\unmlevel = 3
+ \fi
+ \fi
+ % Now print the heading:
+ \if \headtype U%
+ \ifcase\absseclevel
+ \unnumberedzzz{#3}%
+ \or \unnumberedseczzz{#3}%
+ \or \unnumberedsubseczzz{#3}%
+ \or \unnumberedsubsubseczzz{#3}%
+ \fi
+ \else
+ \if \headtype A%
+ \ifcase\absseclevel
+ \appendixzzz{#3}%
+ \or \appendixsectionzzz{#3}%
+ \or \appendixsubseczzz{#3}%
+ \or \appendixsubsubseczzz{#3}%
+ \fi
+ \else
+ \ifcase\absseclevel
+ \chapterzzz{#3}%
+ \or \seczzz{#3}%
+ \or \numberedsubseczzz{#3}%
+ \or \numberedsubsubseczzz{#3}%
+ \fi
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ \message{\putwordChapter\space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ \def\appendixnum{\putwordAppendix\space \appendixletter}%
+ \message{\appendixnum}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message. Therefore, if #1 contained @-commands, TeX
+ % expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself. We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>. (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}%
+ \message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+ %
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+ % Well, we could do the following in a group, but that would break
+ % an assumption that \chapmacro is called at the outermost level.
+ % Thus we are safer this way: --kasal, 24feb04
+ \let\centerparametersmaybe = \centerparameters
+ \unnmhead0{#1}%
+ \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
+% 3) Likewise, headings look best if no \parindent is used, and
+% if justification is not attempted. Hence \raggedright.
+
+
+\def\majorheading{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+ {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+ \bigskip \par\penalty 200\relax
+ \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+ \pchapsepmacro
+ {%
+ \chapfonts \rm
+ %
+ % Have to define \thissection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\thissection{#1}%
+ \gdef\thischaptername{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \gdef\thischapternum{}%
+ \gdef\thischapter{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \gdef\thischapternum{}%
+ \gdef\thischapter{}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ \xdef\thischapternum{\appendixletter}%
+ % We don't substitute the actual chapter name into \thischapter
+ % because we don't want its macros evaluated now. And we don't
+ % use \thissection because that changes with each section.
+ %
+ \xdef\thischapter{\putwordAppendix{} \appendixletter:
+ \noexpand\thischaptername}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \xdef\thischapternum{\the\chapno}%
+ \xdef\thischapter{\putwordChapter{} \the\chapno:
+ \noexpand\thischaptername}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent=\wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt
+ \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+ \global\let\chapmacro=\chfopen
+ \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rm
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Only insert the space after the number if we have a section number.
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\thissection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \thissection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\thissection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\thissection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chapmacro.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chapmacro.
+ \donoderef{#3}%
+ %
+ % Interline glue will be inserted when the vbox is completed.
+ % That glue will be a valid breakpoint for the page, since it'll be
+ % preceded by a whatsit (usually from the \donoderef, or from the
+ % \writetocentry if there was no node). We don't want to allow that
+ % break, since then the whatsits could end up on page n while the
+ % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
+ \nobreak
+ %
+ % Output the actual section heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
+ }%
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
+ \nobreak
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.)
+ \vskip-\parskip
+ %
+ % This is purely so the last item on the list is a known \penalty >
+ % 10000. This is so \startdefun can avoid allowing breakpoints after
+ % section headings. Otherwise, it would insert a valid breakpoint between:
+ %
+ % @section sec-whatever
+ % @deffn def-whatever
+ \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ {\atdummies
+ \edef\temp{%
+ \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+ \temp
+ }%
+ \fi
+ \fi
+ %
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care. This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+ \catcode`\"=\active
+ \catcode`\$=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
+ \catcode`\\=\active
+ \catcode`\^=\active
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+ \setupdatafile
+ \activecatcodes
+ \input \jobname.toc
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \def\thischapter{}%
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+
+% Normal (long) toc.
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \closein 1
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+ \catcode `\%=14
+ \catcode `\+=\other
+ \catcode `\"=\other
+ \catcode `\|=\other
+ \catcode `\<=\other
+ \catcode `\>=\other
+ \escapechar=`\\
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\/=\ptexslash
+ \let\*=\ptexstar
+ \let\t=\ptext
+ \let\frenchspacing=\plainfrenchspacing
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+ % =10000 instead of <10000 because of a special case in \itemzzz and
+ % \sectionheading, q.v.
+ \ifnum \lastpenalty=10000 \else
+ \advance\envskipamount by \parskip
+ \endgraf
+ \ifdim\lastskip<\envskipamount
+ \removelastskip
+ % it's not a good place to break if the last penalty was \nobreak
+ % or better ...
+ \ifnum\lastpenalty<10000 \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing = t%
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+ \aboveenvbreak
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ \parindent = 0pt
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+% @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+ \ifx\SETdispenvsize\smallword
+ % end paragraph for sake of leading, in case document has no blank
+ % line. This is redundant with what happens in \aboveenvbreak, but
+ % we need to do it before changing the fonts, and it's inconvenient
+ % to change the fonts afterward.
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+\def\setsmalldispenv{%
+ \ifx\SETdispenvsize\nosmallword
+ \else
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+ \makedispenv{#1}{#3}
+ \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+ \nonfillstart
+ \tt\quoteexpand
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+ \nonfillstart
+ \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \advance\leftskip by 0pt plus 1fill
+ \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins. We keep \parskip nonzero in general, since
+% we're doing normal filling. So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+ \par
+ \ifx\quotationauthor\undefined\else
+ % indent a bit.
+ \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+ \fi
+ {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too. Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+ \do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+ \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+ \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+ \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+ \tt % easiest (and conventionally used) font for verbatim
+ \def\par{\leavevmode\endgraf}%
+ \catcode`\`=\active
+ \tabeightspaces
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+
+% Allow an option to not replace quotes with a regular directed right
+% quote/apostrophe (char 0x27), but instead use the undirected quote
+% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it
+% the default, but it works for pasting with more pdf viewers (at least
+% evince), the lilypond developers report. xpdf does work with the
+% regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else
+ \char'15
+ \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ `%
+ \else
+ \char'22
+ \fi
+}
+%
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabexpand{%
+ \catcode`\^^I=\active
+ \def^^I{\leavevmode\egroup
+ \dimen0=\wd0 % the width so far, or since the previous tab
+ \divide\dimen0 by\tabw
+ \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+ \advance\dimen0 by\tabw % advance to next multiple of \tabw
+ \wd0=\dimen0 \box0 \starttabbox
+ }%
+ }
+ \catcode`\'=\active
+ \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}%
+ %
+ \catcode`\`=\active
+ \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}%
+ %
+ \gdef\quoteexpand{\rquoteexpand \lquoteexpand}%
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ % Easiest (and conventionally used) font for verbatim
+ \tt
+ \def\par{\leavevmode\egroup\box0\endgraf}%
+ \catcode`\`=\active
+ \tabexpand
+ \quoteexpand
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+ \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters. Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+% \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+ \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+% \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+ \catcode`\ =\active
+ \obeylines %
+ % ignore everything up to the first ^^M, that's the newline at the end
+ % of the @verbatim input line itself. Otherwise we get an extra blank
+ % line in the output.
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \input #1
+ \afterenvbreak
+ }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+ \begingroup
+ \parindent = 0pt % paragraph indentation looks wrong on title page
+ \scanexp\copyingtext
+ \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \defunpenalty=10003 % Will keep this @deffn together with the
+ % following @def command, see below.
+ \else
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check specifically for penalty 10002, inserted
+ % by \printdefunline, instead of 10000, since the sectioning
+ % commands also insert a nobreak penalty, and we don't want to allow
+ % a break between a section heading and a defun.
+ %
+ % As a minor refinement, we avoid "club" headers by signalling
+ % with penalty of 10003 after the very first @deffn in the
+ % sequence (see above), and penalty of 10002 after any following
+ % @def command.
+ \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
+ \fi
+ %
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#1%
+ %
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+ %
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty\defunpenalty % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
+%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+ \envdef#1{%
+ \startdefun
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % How we'll format the type name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape.
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ % (plain.tex says that \dimen1 should be used only as global.)
+ \parshape 2 0in \dimen0 \defargsindent \dimen2
+ %
+ % Put the type name to the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% return value type
+ \ifx\temp\empty\else \tclose{\temp} \fi
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name. This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable. Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl),
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ %
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. Let's try @var for that.
+ \let\var=\ttslanted
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+\def\badparencount{%
+ \errmessage{Unbalanced parentheses in @def}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \errmessage{Unbalanced square braces in @def}%
+ \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+ \newwrite\macscribble
+ \def\scantokens#1{%
+ \toks0={#1}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
+\fi
+
+\def\scanmacro#1{%
+ \begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ % ... and \example
+ \spaceisspace
+ %
+ % Append \endinput to make sure that TeX does not see the ending newline.
+ % I've verified that it is necessary both for e-TeX and for ordinary TeX
+ % --kasal, 29nov03
+ \scantokens{#1\endinput}%
+ \endgroup
+}
+
+\def\scanexp#1{%
+ \edef\temp{\noexpand\scanmacro{#1}}%
+ \temp
+}
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+
+% List of all defined macros in the form
+% \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+ \toks0 = \expandafter{\macrolist\definedummyword#1}%
+ \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+% \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+ \expandafter\let
+ \csname#1\expandafter\endcsname
+ \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+ \catcode`\"=\other
+ \catcode`\+=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\~=\other
+}
+
+\def\scanargctxt{%
+ \scanctxt
+ \catcode`\\=\other
+ \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+ \scanctxt
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\^^M=\other
+ \usembodybackslash
+}
+
+\def\macroargctxt{%
+ \scanctxt
+ \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+ \getargs{#1}% now \macname is the macname and \argl the arglist
+ \ifx\argl\empty % no arguments
+ \paramno=0%
+ \else
+ \expandafter\parsemargdef \argl;%
+ \fi
+ \if1\csname ismacro.\the\macname\endcsname
+ \message{Warning: redefining \the\macname}%
+ \else
+ \expandafter\ifx\csname \the\macname\endcsname \relax
+ \else \errmessage{Macro name \the\macname\space already defined}\fi
+ \global\cslet{macsave.\the\macname}{\the\macname}%
+ \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+ \addtomacrolist{\the\macname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\parseargdef\unmacro{%
+ \if1\csname ismacro.#1\endcsname
+ \global\cslet{#1}{macsave.#1}%
+ \global\expandafter\let \csname ismacro.#1\endcsname=0%
+ % Remove the macro name from \macrolist:
+ \begingroup
+ \expandafter\let\csname#1\endcsname \relax
+ \let\definedummyword\unmacrodo
+ \xdef\macrolist{\macrolist}%
+ \endgroup
+ \else
+ \errmessage{Macro #1 not defined}%
+ \fi
+}
+
+% Called by \do from \dounmacro on each macro. The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+ \ifx #1\relax
+ % remove this
+ \else
+ \noexpand\definedummyword \noexpand#1%
+ \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list. Set up \paramno and \paramlist
+% so \defmacro knows what to do. Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX: let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+ \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\parsemargdefxxx
+ \advance\paramno by 1%
+ \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+ {\xeatspaces{\hash\the\paramno}}%
+ \edef\paramlist{\paramlist\hash\the\paramno,}%
+ \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+ \let\hash=##% convert placeholders to macro parameter chars
+ \ifrecursive
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\scanmacro{\temp}}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup\noexpand\scanmacro{\temp}}%
+ \else % many
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \fi
+ \else
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % many
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \fi
+ \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign. Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \addtomacrolist{#1}%
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references. The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross, , , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
+ \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \thissection,
+% or the anchor name.
+% 2) NAME-snt - section number and type, passed as the SNT arg, or
+% empty for anchors.
+% 3) NAME-pg - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat. In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \atdummies % preserve commands, but don't expand them
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\thissection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout
+ }%
+ \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual. All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \unsepspaces
+ \def\printedmanual{\ignorespaces #5}%
+ \def\printedrefname{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual\unskip}%
+ \setbox0=\hbox{\printedrefname\unskip}%
+ \ifdim \wd0 = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+ % Use the node name inside the square brackets.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ % Use the actual chapter/section title appear inside
+ % the square brackets. Use the real section title if we have it.
+ \ifdim \wd1 > 0pt
+ % It is in another manual, so we don't have it.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % Make link in pdf output.
+ \ifpdf
+ \leavevmode
+ \getfilename{#4}%
+ {\indexnofonts
+ \turnoffactive
+ % See comments at \activebackslashdouble.
+ {\activebackslashdouble \xdef\pdfxrefdest{#1}%
+ \backslashparens\pdfxrefdest}%
+ %
+ \ifnum\filenamelength>0
+ \startlink attr{/Border [0 0 0]}%
+ goto file{\the\filename.pdf} name{\pdfxrefdest}%
+ \else
+ \startlink attr{/Border [0 0 0]}%
+ goto name{\pdfmkpgn{\pdfxrefdest}}%
+ \fi
+ }%
+ \linkcolor
+ \fi
+ %
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname XR#1-title\endcsname
+ }%
+ \iffloat\Xthisreftitle
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd0 = 0pt
+ \refx{#1-snt}{}%
+ \else
+ \printedrefname
+ \fi
+ %
+ % if the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd1 > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+ % insert empty discretionaries after hyphens, which means that it will
+ % not find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens, this
+ % is a loss. Therefore, we give the text of the node name again, so it
+ % is as if TeX is seeing it for the first time.
+ \ifdim \wd1 > 0pt
+ \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+ \else
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via a macro so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output. It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents. Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+ \ifnum\secno=0
+ \putwordChapter@tie \the\chapno
+ \else \ifnum\subsecno=0
+ \putwordSection@tie \the\chapno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+\def\Yappendix{%
+ \ifnum\secno=0
+ \putwordAppendix@tie @char\the\appendixno{}%
+ \else \ifnum\subsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie
+ @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+ {%
+ \indexnofonts
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\thisrefX
+ \csname XR#1\endcsname
+ }%
+ \ifx\thisrefX\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ \message{\linenumber Undefined cross reference `#1'.}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \thisrefX
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file. Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions). But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+ {% The node name might contain 8-bit characters, which in our current
+ % implementation are changed to commands like @'e. Don't let these
+ % mess up the control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safexrefname{#1}%
+ }%
+ %
+ \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+ %
+ % Was that xref control sequence that we just defined for a float?
+ \expandafter\iffloat\csname XR\safexrefname\endcsname
+ % it was a float, and we have the (safe) float type in \iffloattype.
+ \expandafter\let\expandafter\floatlist
+ \csname floatlist\iffloattype\endcsname
+ %
+ % Is this the first time we've seen this float type?
+ \expandafter\ifx\floatlist\relax
+ \toks0 = {\do}% yes, so just \do
+ \else
+ % had it before, so preserve previous elements in list.
+ \toks0 = \expandafter{\floatlist\do}%
+ \fi
+ %
+ % Remember this xref in the control sequence \floatlistFLOATTYPE,
+ % for later use in \listoffloats.
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+ {\safexrefname}}%
+ \fi
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readdatafile{aux}%
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
+\def\setupdatafile{%
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\^=\other
+ %
+ % Special characters. Should be turned off anyway, but...
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`\%=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ %
+ % This is to support \ in node names and titles, since the \
+ % characters end up in a \csname. It's easier than
+ % leaving it active and making its active definition an actual \
+ % character. What I don't understand is why it works in the *value*
+ % of the xrdef. Seems like it should be a catcode12 \, and that
+ % should not typeset properly. But it works, so I'm moving on for
+ % now. --karl, 15jan04.
+ \catcode`\\=\other
+ %
+ % Make the characters 128-255 be printing characters.
+ {%
+ \count1=128
+ \def\loop{%
+ \catcode\count1=\other
+ \advance\count1 by 1
+ \ifnum \count1<256 \loop \fi
+ }%
+ }%
+ %
+ % @ is our escape character in .aux files, and we need braces.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+ \setupdatafile
+ \input\jobname.#1
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\gdef\dofootnote{%
+ \insert\footins\bgroup
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \hsize=\pagewidth
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ \smallfonts \rm
+ %
+ % Because we use hanging indentation in footnotes, a @noindent appears
+ % to exdent this text, so make it be a no-op. makeinfo does not use
+ % hanging indentation so @noindent can still be needed within footnote
+ % text after an @example or the like (not that this is good style).
+ \let\noindent = \relax
+ %
+ % Hang the footnote text off the number. Use \everypar in case the
+ % footnote extends for more than one paragraph.
+ \everypar = {\hang}%
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarly, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1%
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ % Do not bother showing banner with epsf.tex v2.7k (available in
+ % doc/epsf.tex and on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+ \ifx\epsfbox\undefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+ \catcode`\^^M = 5 % in case we're inside an example
+ \normalturnoffactive % allow _ et al. in names
+ % If the image is by itself, center it.
+ \ifvmode
+ \imagevmodetrue
+ \nobreak\bigskip
+ % Usually we'll have text after the image which will insert
+ % \parskip glue, so insert it here too to equalize the space
+ % above and below.
+ \nobreak\vskip\parskip
+ \nobreak
+ \line\bgroup
+ \fi
+ %
+ % Output the image.
+ \ifpdf
+ \dopdfimage{#1}{#2}{#3}%
+ \else
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ \epsfbox{#1.eps}%
+ \fi
+ %
+ \ifimagevmode \egroup \bigbreak \fi % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc. We don't actually implement floating yet, we always include the
+% float "here". But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ \let\thiscaption=\empty
+ \let\thisshortcaption=\empty
+ %
+ % don't lose footnotes inside @float.
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \startsavinginserts
+ %
+ % We can't be used inside a paragraph.
+ \par
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ %
+ \ifx\floattype\empty
+ \let\safefloattype=\empty
+ \else
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ \fi
+ %
+ % If label is given but no type, we handle that as the empty type.
+ \ifx\floatlabel\empty \else
+ % We want each FLOATTYPE to be numbered separately (Figure 1,
+ % Table 1, Figure 2, ...). (And if no label, no number.)
+ %
+ \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ {%
+ % This magic value for \thissection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % node and anchor labels. And \xrdef uses it to construct the
+ % lists of floats.
+ %
+ \edef\thissection{\floatmagic=\safefloattype}%
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ %
+ % start with \parskip glue, I guess.
+ \vskip\parskip
+ %
+ % Don't suppress indentation if a float happens to start a section.
+ \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption: Foo 1.1
+% @float Foo & @caption{Cap}: Foo: Cap
+% @float Foo & no caption: Foo
+% @float ,lbl & Caption{Cap}: 1.1: Cap
+% @float ,lbl & no caption: 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\floatident = \empty
+ %
+ % In all cases, if we have a float type, it comes first.
+ \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+ %
+ % If we have an xref label, the number comes next.
+ \ifx\floatlabel\empty \else
+ \ifx\floattype\empty \else % if also had float type, need tie first.
+ \appendtomacro\floatident{\tie}%
+ \fi
+ % the number.
+ \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+ \fi
+ %
+ % Start the printed caption with what we've constructed in
+ % \floatident, but keep it separate; we need \floatident again.
+ \let\captionline = \floatident
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\floatident\empty \else
+ \appendtomacro\captionline{: }% had ident, so need a colon between
+ \fi
+ %
+ % caption text.
+ \appendtomacro\captionline{\scanexp\thiscaption}%
+ \fi
+ %
+ % If we have anything to print, print it, with space before.
+ % Eventually this needs to become an \insert.
+ \ifx\captionline\empty \else
+ \vskip.5\parskip
+ \captionline
+ %
+ % Space below caption.
+ \vskip\parskip
+ \fi
+ %
+ % If have an xref label, write the list of floats info. Do this
+ % after the caption, to avoid chance of it being a breakpoint.
+ \ifx\floatlabel\empty \else
+ % Write the text that goes in the lof to the aux file as
+ % \floatlabel-lof. Besides \floatident, we include the short
+ % caption if specified, else the full caption if specified, else nothing.
+ {%
+ \atdummies
+ %
+ % since we read the caption text in the macro world, where ^^M
+ % is turned into a normal character, we have to scan it back, so
+ % we don't write the literal three characters "^^M" into the aux file.
+ \scanexp{%
+ \xdef\noexpand\gtemp{%
+ \ifx\thisshortcaption\empty
+ \thiscaption
+ \else
+ \thisshortcaption
+ \fi
+ }%
+ }%
+ \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+ \ifx\gtemp\empty \else : \gtemp \fi}}%
+ }%
+ \fi
+ \egroup % end of \vtop
+ %
+ % place the captured inserts
+ %
+ % BEWARE: when the floats start floating, we have to issue warning
+ % whenever an insert appears inside a float which could possibly
+ % float. --kasal, 26may04
+ %
+ \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref. That is, the magic
+% \thissection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string. If so, #2 will be the
+% (safe) float type for this float. We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+ \def\temp{#1}%
+ \def\iffloattype{#2}%
+ \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+ \def\floattype{#1}% floattype
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ %
+ % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+ \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+ \ifhavexrefs
+ % if the user said @listoffloats foo but never @float foo.
+ \message{\linenumber No `\safefloattype' floats to list.}%
+ \fi
+ \else
+ \begingroup
+ \leftskip=\tocindent % indent these entries like a toc
+ \let\do=\listoffloatsdo
+ \csname floatlist\safefloattype\endcsname
+ \endgroup
+ \fi
+}
+
+% This is called on each entry in a list of floats. We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file. We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+ % Can't fully expand XR#1-lof because it can contain anything. Just
+ % pass the control sequence. On the other hand, XR#1-pg is just the
+ % page number, and we want to fully expand that so we can get a link
+ % in pdf output.
+ \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+ %
+ % use the same \entry macro we use to generate the TOC and index.
+ \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+ \writeentry
+}}
+
+
+\message{localization,}
+
+% @documentlanguage is usually given very early, just after
+% @setfilename. If done too late, it may not override everything
+% properly. Single argument is the language abbreviation.
+% It would be nice if we could set up a hyphenation file here.
+%
+\parseargdef\documentlanguage{%
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \input txi-#1.tex
+ \fi
+ \closein 1
+ \endgroup
+}
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty. Maybe you need to install it? In the current directory
+should work if nowhere else does.}
+
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \global\catcode\count255=#1
+ \advance\count255 by 1
+ \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+ % Encoding being declared for the document.
+ \def\declaredencoding{\csname #1.enc\endcsname}%
+ %
+ % Supported encodings: names converted to tokens in order to be able
+ % to compare them with \ifx.
+ \def\ascii{\csname US-ASCII.enc\endcsname}%
+ \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+ \def\latone{\csname ISO-8859-1.enc\endcsname}%
+ \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+ \def\utfeight{\csname UTF-8.enc\endcsname}%
+ %
+ \ifx \declaredencoding \ascii
+ \asciichardefs
+ %
+ \else \ifx \declaredencoding \lattwo
+ \setnonasciicharscatcode\active
+ \lattwochardefs
+ %
+ \else \ifx \declaredencoding \latone
+ \setnonasciicharscatcode\active
+ \latonechardefs
+ %
+ \else \ifx \declaredencoding \latnine
+ \setnonasciicharscatcode\active
+ \latninechardefs
+ %
+ \else \ifx \declaredencoding \utfeight
+ \setnonasciicharscatcode\active
+ \utfeightchardefs
+ %
+ \else
+ \message{Unknown document encoding #1, ignoring.}%
+ %
+ \fi % utfeight
+ \fi % latnine
+ \fi % latone
+ \fi % lattwo
+ \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+ \gdef^^a0{~}
+ \gdef^^a1{\exclamdown}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a3{{\pounds}}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\missingcharmsg{YEN SIGN}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
+ \gdef^^aa{\ordf}
+ \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+ \gdef^^ac{$\lnot$}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
+ \gdef^^af{\={}}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{$\pm$}
+ \gdef^^b2{$^2$}
+ \gdef^^b3{$^3$}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{$\mu$}
+ \gdef^^b6{\P}
+ %
+ \gdef^^b7{$^.$}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{$^1$}
+ \gdef^^ba{\ordm}
+ %
+ \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+ \gdef^^bc{$1\over4$}
+ \gdef^^bd{$1\over2$}
+ \gdef^^be{$3\over4$}
+ \gdef^^bf{\questiondown}
+ %
+ \gdef^^c0{\`A}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\~A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\ringaccent A}
+ \gdef^^c6{\AE}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\`E}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\^E}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\`I}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\"I}
+ %
+ \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}}
+ \gdef^^d1{\~N}
+ \gdef^^d2{\`O}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\~O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\O}
+ \gdef^^d9{\`U}
+ \gdef^^da{\'U}
+ \gdef^^db{\^U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\`a}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\~a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\ringaccent a}
+ \gdef^^e6{\ae}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\`e}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\^e}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\`{\dotless i}}
+ \gdef^^ed{\'{\dotless i}}
+ \gdef^^ee{\^{\dotless i}}
+ \gdef^^ef{\"{\dotless i}}
+ %
+ \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}}
+ \gdef^^f1{\~n}
+ \gdef^^f2{\`o}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\~o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\o}
+ \gdef^^f9{\`u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\^u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}}
+ \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+ % Encoding is almost identical to Latin1.
+ \latonechardefs
+ %
+ \gdef^^a4{\euro}
+ \gdef^^a6{\v S}
+ \gdef^^a8{\v s}
+ \gdef^^b4{\v Z}
+ \gdef^^b8{\v z}
+ \gdef^^bc{\OE}
+ \gdef^^bd{\oe}
+ \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+ \gdef^^a0{~}
+ \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}}
+ \gdef^^a2{\u{}}
+ \gdef^^a3{\L}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\v L}
+ \gdef^^a6{\'S}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\v S}
+ \gdef^^aa{\cedilla S}
+ \gdef^^ab{\v T}
+ \gdef^^ac{\'Z}
+ \gdef^^ad{\-}
+ \gdef^^ae{\v Z}
+ \gdef^^af{\dotaccent Z}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}}
+ \gdef^^b2{\missingcharmsg{OGONEK}}
+ \gdef^^b3{\l}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{\v l}
+ \gdef^^b6{\'s}
+ \gdef^^b7{\v{}}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{\v s}
+ \gdef^^ba{\cedilla s}
+ \gdef^^bb{\v t}
+ \gdef^^bc{\'z}
+ \gdef^^bd{\H{}}
+ \gdef^^be{\v z}
+ \gdef^^bf{\dotaccent z}
+ %
+ \gdef^^c0{\'R}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\u A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\'L}
+ \gdef^^c6{\'C}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\v C}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\v E}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\v D}
+ %
+ \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}}
+ \gdef^^d1{\'N}
+ \gdef^^d2{\v N}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\H O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\v R}
+ \gdef^^d9{\ringaccent U}
+ \gdef^^da{\'U}
+ \gdef^^db{\H U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\cedilla T}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\'r}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\u a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\'l}
+ \gdef^^e6{\'c}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\v c}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\v e}
+ \gdef^^ed{\'\i}
+ \gdef^^ee{\^\i}
+ \gdef^^ef{\v d}
+ %
+ \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}}
+ \gdef^^f1{\'n}
+ \gdef^^f2{\v n}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\H o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\v r}
+ \gdef^^f9{\ringaccent u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\H u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\cedilla t}
+ \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions. It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+ \ifx #1\relax
+ \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+ \else
+ \expandafter #1%
+ \fi
+}
+
+\begingroup
+ \catcode`\~13
+ \catcode`\"12
+
+ \def\UTFviiiLoop{%
+ \global\catcode\countUTFx\active
+ \uccode`\~\countUTFx
+ \uppercase\expandafter{\UTFviiiTmp}%
+ \advance\countUTFx by 1
+ \ifnum\countUTFx < \countUTFy
+ \expandafter\UTFviiiLoop
+ \fi}
+
+ \countUTFx = "C2
+ \countUTFy = "E0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "E0
+ \countUTFy = "F0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "F0
+ \countUTFy = "F4
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+ \UTFviiiLoop
+\endgroup
+
+\begingroup
+ \catcode`\"=12
+ \catcode`\<=12
+ \catcode`\.=12
+ \catcode`\,=12
+ \catcode`\;=12
+ \catcode`\!=12
+ \catcode`\~=13
+
+ \gdef\DeclareUnicodeCharacter#1#2{%
+ \countUTFz = "#1\relax
+ \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ \begingroup
+ \parseXMLCharref
+ \def\UTFviiiTwoOctets##1##2{%
+ \csname u8:##1\string ##2\endcsname}%
+ \def\UTFviiiThreeOctets##1##2##3{%
+ \csname u8:##1\string ##2\string ##3\endcsname}%
+ \def\UTFviiiFourOctets##1##2##3##4{%
+ \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+ \expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter
+ \gdef\UTFviiiTmp{#2}%
+ \endgroup}
+
+ \gdef\parseXMLCharref{%
+ \ifnum\countUTFz < "A0\relax
+ \errhelp = \EMsimple
+ \errmessage{Cannot define Unicode char value < 00A0}%
+ \else\ifnum\countUTFz < "800\relax
+ \parseUTFviiiA,%
+ \parseUTFviiiB C\UTFviiiTwoOctets.,%
+ \else\ifnum\countUTFz < "10000\relax
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+ \else
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiA!%
+ \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+ \fi\fi\fi
+ }
+
+ \gdef\parseUTFviiiA#1{%
+ \countUTFx = \countUTFz
+ \divide\countUTFz by 64
+ \countUTFy = \countUTFz
+ \multiply\countUTFz by 64
+ \advance\countUTFx by -\countUTFz
+ \advance\countUTFx by 128
+ \uccode `#1\countUTFx
+ \countUTFz = \countUTFy}
+
+ \gdef\parseUTFviiiB#1#2#3#4{%
+ \advance\countUTFz by "#10\relax
+ \uccode `#3\countUTFz
+ \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+ \DeclareUnicodeCharacter{00A0}{\tie}
+ \DeclareUnicodeCharacter{00A1}{\exclamdown}
+ \DeclareUnicodeCharacter{00A3}{\pounds}
+ \DeclareUnicodeCharacter{00A8}{\"{ }}
+ \DeclareUnicodeCharacter{00A9}{\copyright}
+ \DeclareUnicodeCharacter{00AA}{\ordf}
+ \DeclareUnicodeCharacter{00AD}{\-}
+ \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+ \DeclareUnicodeCharacter{00AF}{\={ }}
+
+ \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+ \DeclareUnicodeCharacter{00B4}{\'{ }}
+ \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+ \DeclareUnicodeCharacter{00BA}{\ordm}
+ \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+ \DeclareUnicodeCharacter{00C0}{\`A}
+ \DeclareUnicodeCharacter{00C1}{\'A}
+ \DeclareUnicodeCharacter{00C2}{\^A}
+ \DeclareUnicodeCharacter{00C3}{\~A}
+ \DeclareUnicodeCharacter{00C4}{\"A}
+ \DeclareUnicodeCharacter{00C5}{\AA}
+ \DeclareUnicodeCharacter{00C6}{\AE}
+ \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+ \DeclareUnicodeCharacter{00C8}{\`E}
+ \DeclareUnicodeCharacter{00C9}{\'E}
+ \DeclareUnicodeCharacter{00CA}{\^E}
+ \DeclareUnicodeCharacter{00CB}{\"E}
+ \DeclareUnicodeCharacter{00CC}{\`I}
+ \DeclareUnicodeCharacter{00CD}{\'I}
+ \DeclareUnicodeCharacter{00CE}{\^I}
+ \DeclareUnicodeCharacter{00CF}{\"I}
+
+ \DeclareUnicodeCharacter{00D1}{\~N}
+ \DeclareUnicodeCharacter{00D2}{\`O}
+ \DeclareUnicodeCharacter{00D3}{\'O}
+ \DeclareUnicodeCharacter{00D4}{\^O}
+ \DeclareUnicodeCharacter{00D5}{\~O}
+ \DeclareUnicodeCharacter{00D6}{\"O}
+ \DeclareUnicodeCharacter{00D8}{\O}
+ \DeclareUnicodeCharacter{00D9}{\`U}
+ \DeclareUnicodeCharacter{00DA}{\'U}
+ \DeclareUnicodeCharacter{00DB}{\^U}
+ \DeclareUnicodeCharacter{00DC}{\"U}
+ \DeclareUnicodeCharacter{00DD}{\'Y}
+ \DeclareUnicodeCharacter{00DF}{\ss}
+
+ \DeclareUnicodeCharacter{00E0}{\`a}
+ \DeclareUnicodeCharacter{00E1}{\'a}
+ \DeclareUnicodeCharacter{00E2}{\^a}
+ \DeclareUnicodeCharacter{00E3}{\~a}
+ \DeclareUnicodeCharacter{00E4}{\"a}
+ \DeclareUnicodeCharacter{00E5}{\aa}
+ \DeclareUnicodeCharacter{00E6}{\ae}
+ \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+ \DeclareUnicodeCharacter{00E8}{\`e}
+ \DeclareUnicodeCharacter{00E9}{\'e}
+ \DeclareUnicodeCharacter{00EA}{\^e}
+ \DeclareUnicodeCharacter{00EB}{\"e}
+ \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+ \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{00F1}{\~n}
+ \DeclareUnicodeCharacter{00F2}{\`o}
+ \DeclareUnicodeCharacter{00F3}{\'o}
+ \DeclareUnicodeCharacter{00F4}{\^o}
+ \DeclareUnicodeCharacter{00F5}{\~o}
+ \DeclareUnicodeCharacter{00F6}{\"o}
+ \DeclareUnicodeCharacter{00F8}{\o}
+ \DeclareUnicodeCharacter{00F9}{\`u}
+ \DeclareUnicodeCharacter{00FA}{\'u}
+ \DeclareUnicodeCharacter{00FB}{\^u}
+ \DeclareUnicodeCharacter{00FC}{\"u}
+ \DeclareUnicodeCharacter{00FD}{\'y}
+ \DeclareUnicodeCharacter{00FF}{\"y}
+
+ \DeclareUnicodeCharacter{0100}{\=A}
+ \DeclareUnicodeCharacter{0101}{\=a}
+ \DeclareUnicodeCharacter{0102}{\u{A}}
+ \DeclareUnicodeCharacter{0103}{\u{a}}
+ \DeclareUnicodeCharacter{0106}{\'C}
+ \DeclareUnicodeCharacter{0107}{\'c}
+ \DeclareUnicodeCharacter{0108}{\^C}
+ \DeclareUnicodeCharacter{0109}{\^c}
+ \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+ \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+ \DeclareUnicodeCharacter{010C}{\v{C}}
+ \DeclareUnicodeCharacter{010D}{\v{c}}
+ \DeclareUnicodeCharacter{010E}{\v{D}}
+
+ \DeclareUnicodeCharacter{0112}{\=E}
+ \DeclareUnicodeCharacter{0113}{\=e}
+ \DeclareUnicodeCharacter{0114}{\u{E}}
+ \DeclareUnicodeCharacter{0115}{\u{e}}
+ \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+ \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+ \DeclareUnicodeCharacter{011A}{\v{E}}
+ \DeclareUnicodeCharacter{011B}{\v{e}}
+ \DeclareUnicodeCharacter{011C}{\^G}
+ \DeclareUnicodeCharacter{011D}{\^g}
+ \DeclareUnicodeCharacter{011E}{\u{G}}
+ \DeclareUnicodeCharacter{011F}{\u{g}}
+
+ \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+ \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+ \DeclareUnicodeCharacter{0124}{\^H}
+ \DeclareUnicodeCharacter{0125}{\^h}
+ \DeclareUnicodeCharacter{0128}{\~I}
+ \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+ \DeclareUnicodeCharacter{012A}{\=I}
+ \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+ \DeclareUnicodeCharacter{012C}{\u{I}}
+ \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+ \DeclareUnicodeCharacter{0131}{\dotless{i}}
+ \DeclareUnicodeCharacter{0132}{IJ}
+ \DeclareUnicodeCharacter{0133}{ij}
+ \DeclareUnicodeCharacter{0134}{\^J}
+ \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+ \DeclareUnicodeCharacter{0139}{\'L}
+ \DeclareUnicodeCharacter{013A}{\'l}
+
+ \DeclareUnicodeCharacter{0141}{\L}
+ \DeclareUnicodeCharacter{0142}{\l}
+ \DeclareUnicodeCharacter{0143}{\'N}
+ \DeclareUnicodeCharacter{0144}{\'n}
+ \DeclareUnicodeCharacter{0147}{\v{N}}
+ \DeclareUnicodeCharacter{0148}{\v{n}}
+ \DeclareUnicodeCharacter{014C}{\=O}
+ \DeclareUnicodeCharacter{014D}{\=o}
+ \DeclareUnicodeCharacter{014E}{\u{O}}
+ \DeclareUnicodeCharacter{014F}{\u{o}}
+
+ \DeclareUnicodeCharacter{0150}{\H{O}}
+ \DeclareUnicodeCharacter{0151}{\H{o}}
+ \DeclareUnicodeCharacter{0152}{\OE}
+ \DeclareUnicodeCharacter{0153}{\oe}
+ \DeclareUnicodeCharacter{0154}{\'R}
+ \DeclareUnicodeCharacter{0155}{\'r}
+ \DeclareUnicodeCharacter{0158}{\v{R}}
+ \DeclareUnicodeCharacter{0159}{\v{r}}
+ \DeclareUnicodeCharacter{015A}{\'S}
+ \DeclareUnicodeCharacter{015B}{\'s}
+ \DeclareUnicodeCharacter{015C}{\^S}
+ \DeclareUnicodeCharacter{015D}{\^s}
+ \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+ \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+ \DeclareUnicodeCharacter{0160}{\v{S}}
+ \DeclareUnicodeCharacter{0161}{\v{s}}
+ \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+ \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+ \DeclareUnicodeCharacter{0164}{\v{T}}
+
+ \DeclareUnicodeCharacter{0168}{\~U}
+ \DeclareUnicodeCharacter{0169}{\~u}
+ \DeclareUnicodeCharacter{016A}{\=U}
+ \DeclareUnicodeCharacter{016B}{\=u}
+ \DeclareUnicodeCharacter{016C}{\u{U}}
+ \DeclareUnicodeCharacter{016D}{\u{u}}
+ \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+ \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+ \DeclareUnicodeCharacter{0170}{\H{U}}
+ \DeclareUnicodeCharacter{0171}{\H{u}}
+ \DeclareUnicodeCharacter{0174}{\^W}
+ \DeclareUnicodeCharacter{0175}{\^w}
+ \DeclareUnicodeCharacter{0176}{\^Y}
+ \DeclareUnicodeCharacter{0177}{\^y}
+ \DeclareUnicodeCharacter{0178}{\"Y}
+ \DeclareUnicodeCharacter{0179}{\'Z}
+ \DeclareUnicodeCharacter{017A}{\'z}
+ \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+ \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+ \DeclareUnicodeCharacter{017D}{\v{Z}}
+ \DeclareUnicodeCharacter{017E}{\v{z}}
+
+ \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+ \DeclareUnicodeCharacter{01C5}{D\v{z}}
+ \DeclareUnicodeCharacter{01C6}{d\v{z}}
+ \DeclareUnicodeCharacter{01C7}{LJ}
+ \DeclareUnicodeCharacter{01C8}{Lj}
+ \DeclareUnicodeCharacter{01C9}{lj}
+ \DeclareUnicodeCharacter{01CA}{NJ}
+ \DeclareUnicodeCharacter{01CB}{Nj}
+ \DeclareUnicodeCharacter{01CC}{nj}
+ \DeclareUnicodeCharacter{01CD}{\v{A}}
+ \DeclareUnicodeCharacter{01CE}{\v{a}}
+ \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+ \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+ \DeclareUnicodeCharacter{01D1}{\v{O}}
+ \DeclareUnicodeCharacter{01D2}{\v{o}}
+ \DeclareUnicodeCharacter{01D3}{\v{U}}
+ \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+ \DeclareUnicodeCharacter{01E2}{\={\AE}}
+ \DeclareUnicodeCharacter{01E3}{\={\ae}}
+ \DeclareUnicodeCharacter{01E6}{\v{G}}
+ \DeclareUnicodeCharacter{01E7}{\v{g}}
+ \DeclareUnicodeCharacter{01E8}{\v{K}}
+ \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+ \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+ \DeclareUnicodeCharacter{01F1}{DZ}
+ \DeclareUnicodeCharacter{01F2}{Dz}
+ \DeclareUnicodeCharacter{01F3}{dz}
+ \DeclareUnicodeCharacter{01F4}{\'G}
+ \DeclareUnicodeCharacter{01F5}{\'g}
+ \DeclareUnicodeCharacter{01F8}{\`N}
+ \DeclareUnicodeCharacter{01F9}{\`n}
+ \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+ \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+ \DeclareUnicodeCharacter{01FE}{\'{\O}}
+ \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+ \DeclareUnicodeCharacter{021E}{\v{H}}
+ \DeclareUnicodeCharacter{021F}{\v{h}}
+
+ \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+ \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+ \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+ \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+ \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+ \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+ \DeclareUnicodeCharacter{0232}{\=Y}
+ \DeclareUnicodeCharacter{0233}{\=y}
+ \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+ \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+ \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+ \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+ \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+ \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+ \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+ \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+ \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+ \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+ \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+ \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+ \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+ \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+ \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+ \DeclareUnicodeCharacter{1E20}{\=G}
+ \DeclareUnicodeCharacter{1E21}{\=g}
+ \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+ \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+ \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+ \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+ \DeclareUnicodeCharacter{1E26}{\"H}
+ \DeclareUnicodeCharacter{1E27}{\"h}
+
+ \DeclareUnicodeCharacter{1E30}{\'K}
+ \DeclareUnicodeCharacter{1E31}{\'k}
+ \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+ \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+ \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+ \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+ \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+ \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+ \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+ \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+ \DeclareUnicodeCharacter{1E3E}{\'M}
+ \DeclareUnicodeCharacter{1E3F}{\'m}
+
+ \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+ \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+ \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+ \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+ \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+ \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+ \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+ \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+ \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+ \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+ \DeclareUnicodeCharacter{1E54}{\'P}
+ \DeclareUnicodeCharacter{1E55}{\'p}
+ \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+ \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+ \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+ \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+ \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+ \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+ \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+ \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+ \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+ \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+ \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+ \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+ \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+ \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+ \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+ \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+ \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+ \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+ \DeclareUnicodeCharacter{1E7C}{\~V}
+ \DeclareUnicodeCharacter{1E7D}{\~v}
+ \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+ \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+ \DeclareUnicodeCharacter{1E80}{\`W}
+ \DeclareUnicodeCharacter{1E81}{\`w}
+ \DeclareUnicodeCharacter{1E82}{\'W}
+ \DeclareUnicodeCharacter{1E83}{\'w}
+ \DeclareUnicodeCharacter{1E84}{\"W}
+ \DeclareUnicodeCharacter{1E85}{\"w}
+ \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+ \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+ \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+ \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+ \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+ \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+ \DeclareUnicodeCharacter{1E8C}{\"X}
+ \DeclareUnicodeCharacter{1E8D}{\"x}
+ \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+ \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+ \DeclareUnicodeCharacter{1E90}{\^Z}
+ \DeclareUnicodeCharacter{1E91}{\^z}
+ \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+ \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+ \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+ \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+ \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+ \DeclareUnicodeCharacter{1E97}{\"t}
+ \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+ \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+ \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+ \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+ \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+ \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+ \DeclareUnicodeCharacter{1EBC}{\~E}
+ \DeclareUnicodeCharacter{1EBD}{\~e}
+
+ \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+ \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+ \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+ \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+ \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+ \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+ \DeclareUnicodeCharacter{1EF2}{\`Y}
+ \DeclareUnicodeCharacter{1EF3}{\`y}
+ \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+ \DeclareUnicodeCharacter{1EF8}{\~Y}
+ \DeclareUnicodeCharacter{1EF9}{\~y}
+
+ \DeclareUnicodeCharacter{2013}{--}
+ \DeclareUnicodeCharacter{2014}{---}
+ \DeclareUnicodeCharacter{2022}{\bullet}
+ \DeclareUnicodeCharacter{2026}{\dots}
+ \DeclareUnicodeCharacter{20AC}{\euro}
+
+ \DeclareUnicodeCharacter{2192}{\expansion}
+ \DeclareUnicodeCharacter{21D2}{\result}
+
+ \DeclareUnicodeCharacter{2212}{\minus}
+ \DeclareUnicodeCharacter{2217}{\point}
+ \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+ \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+ \ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+ \else
+ \emergencystretch = .15\hsize
+ \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading. The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+ \voffset = #3\relax
+ \topskip = #6\relax
+ \splittopskip = \topskip
+ %
+ \vsize = #1\relax
+ \advance\vsize by \topskip
+ \outervsize = \vsize
+ \advance\outervsize by 2\topandbottommargin
+ \pageheight = \vsize
+ %
+ \hsize = #2\relax
+ \outerhsize = \hsize
+ \advance\outerhsize by 0.5in
+ \pagewidth = \hsize
+ %
+ \normaloffset = #4\relax
+ \bindingoffset = #5\relax
+ %
+ \ifpdf
+ \pdfpageheight #7\relax
+ \pdfpagewidth #8\relax
+ \fi
+ %
+ \setleading{\textleading}
+ %
+ \parindent = \defaultparindent
+ \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % If page is nothing but text, make it come out even.
+ \internalpagesizes{46\baselineskip}{6in}%
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {\voffset}{.25in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+ \parskip = 1.5pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.4in}{4.8in}%
+ {-.2in}{-.4in}%
+ {0pt}{14pt}%
+ {9in}{6in}%
+ %
+ \lispnarrowing = 0.25in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % Double-side printing via postscript on Laserjet 4050
+ % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+ % To change the settings for a different printer or situation, adjust
+ % \normaloffset until the front-side and back-side texts align. Then
+ % do the same for \bindingoffset. You can set these for testing in
+ % your texinfo source file like this:
+ % @tex
+ % \global\normaloffset = -6mm
+ % \global\bindingoffset = 10mm
+ % @end tex
+ \internalpagesizes{51\baselineskip}{160mm}
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{44pt}%
+ {297mm}{210mm}%
+ %
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+ \parskip = 2pt plus 1pt minus 0.1pt
+ \textleading = 12.5pt
+ %
+ \internalpagesizes{160mm}{120mm}%
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{8pt}%
+ {210mm}{148mm}%
+ %
+ \lispnarrowing = 0.2in
+ \tolerance = 800
+ \hfuzz = 1.2pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 2mm
+ \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{237mm}{150mm}%
+ {\voffset}{4.6mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ %
+ % Must explicitly reset to 0 because we call \afourpaper.
+ \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{241mm}{165mm}%
+ {\voffset}{-2.95mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+ \globaldefs = 1
+ %
+ \parskip = 3pt plus 2pt minus 1pt
+ \setleading{\textleading}%
+ %
+ \dimen0 = #1
+ \advance\dimen0 by \voffset
+ %
+ \dimen2 = \hsize
+ \advance\dimen2 by \normaloffset
+ %
+ \internalpagesizes{#1}{\hsize}%
+ {\voffset}{\normaloffset}%
+ {\bindingoffset}{44pt}%
+ {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font. Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts. But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+ \normalturnoffactive
+ \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active
+@def@normalbackslash{{@tt@backslashcurfont}}
+% On startup, @fixbackslash assigns:
+% @let \ = @normalbackslash
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.
+%
+@def@normalturnoffactive{%
+ @let\=@normalbackslash
+ @let"=@normaldoublequote
+ @let~=@normaltilde
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let<=@normalless
+ @let>=@normalgreater
+ @let+=@normalplus
+ @let$=@normaldollar %$ font-lock fix
+ @unsepspaces
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+ @ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active
+ @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+@catcode`@& = @other
+@catcode`@# = @other
+@catcode`@% = @other
+
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/comm/third_party/libgcrypt/cipher/ChangeLog-2011 b/comm/third_party/libgcrypt/cipher/ChangeLog-2011
new file mode 100644
index 0000000000..1ce6bd1e68
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ChangeLog-2011
@@ -0,0 +1,4279 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-09-16 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_primegen_init): New.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * cipher-cbc.c, cipher-cfb.c, cipher-ofb.c, cipher-ctr.c: New.
+ * cipher-aeswrap.c: New.
+ * cipher-internal.h: New.
+ * cipher.c (cipher_context_alignment_t, struct gcry_cipher_handle)
+ (CTX_MAGIC_NORMAL, CTX_MAGIC_SECURE, NEED_16BYTE_ALIGNED_CONTEXT)
+ (MAX_BLOCKSIZE): Move to cipher-internal.h.
+ (do_aeswrap_encrypt, do_aeswrap_encrypt)
+ (do_cbc_encrypt, do_cbc_decrypt, do_ctr_encrypt, do_ctr_decrypt)
+ (do_ofb_encrypt, do_ofb_decrypt, do_ctr_encrypt): Move to the
+ respective new cipher-foo.c files.
+ (do_ctr_decrypt): Remove.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_list): Remove.
+ (gcry_pk_unregister): Remove.
+ * md.c (gcry_md_list): Remove.
+ (gcry_md_unregister): Remove.
+ * cipher.c (gcry_cipher_list): Remove.
+ (gcry_cipher_unregister): Remove.
+ * ac.c: Remove.
+
+2011-06-29 Werner Koch <wk@g10code.com>
+
+ * cipher.c (cipher_get_keylen): Return zero for an invalid algorithm.
+ (cipher_get_blocksize): Ditto.
+
+2011-06-13 Werner Koch <wk@g10code.com>
+
+ * dsa.c (selftest_sign_1024): Use the raw and not the pkcs1 flag.
+
+ * pubkey.c (gcry_pk_sign): Special case output generation for PKCS1.
+ (sexp_data_to_mpi): Parse "random-override" for pkcs1 encryption.
+ (pkcs1_encode_for_encryption): Add args RANDOM_OVERRIDE and
+ RANDOM_OVERRIDE_LEN.
+ (gcry_pk_encrypt): Special case output generation for PKCS1.
+ (sexp_data_to_mpi): Use GCRYMPI_FMT_USG for raw encoding.
+
+2011-06-10 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_sign): Use format specifier '%M' to avoid
+ leading zeroes. Special case output generation for PSS.
+ (gcry_pk_encrypt): Special case output generation for OAEP.
+ (sexp_data_to_mpi): Use GCRYMPI_FMT_USG for PSS verify.
+
+2011-06-09 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (oaep_decode): Make use of octet_string_from_mpi.
+ (sexp_to_enc): Skip "random-override".
+
+ * pubkey.c (oaep_encode, pss_encode): Add args RANDOM_OVERRIDE and
+ RANDOM_OVERRIDE_LEN.
+ (sexp_data_to_mpi): Extract new random-override parameter.
+
+ * pubkey.c (pss_encode, pss_verify): Use VALUE verbatim for MHASH.
+ (octet_string_from_mpi): Add arg SPACE.
+
+2011-06-08 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pss_encode, pss_verify): Restructure and comment code
+ to match rfc-3447. Replace secure allocs by plain allocs and
+ wipememory. Use gcry_md_hash_buffer.
+ (octet_string_from_mpi): New.
+
+2011-06-03 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (oaep_decode): Add more comments and restructure to
+ match the description in RFC-3447.
+ (oaep_encode): Check for mgf1 error. s/dlen/hlen/.
+
+2011-05-31 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (mgf1): Optimize by using gcry_md_reset. Re-implement
+ for easier readability.
+ (oaep_encode): Add more comments and restructure to match the
+ description in RFC-3447.
+
+ * pubkey.c (pkcs1_encode_for_signature, oaep_decode): Change
+ return value from one MPI to a buffer.
+ (gcry_pk_decrypt): Adjust for this change.
+
+2011-05-30 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pkcs1_decode_for_encryption): Change handling of
+ leading zero byte.
+
+2011-05-27 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (gcry_pk_decrypt): Fix double-free when un-padding
+ invalid data. Thanks to Tom Ritter.
+
+2011-05-24 Daiki Ueno <ueno@unixuser.org>
+
+ * rsa.c (rsa_verify): Use CMP if given, to check the decrypted
+ sig.
+
+ * pubkey.c (sexp_to_enc, sexp_data_to_mpi): Factor out
+ CTX initialization to ...
+ (init_encoding_ctx): .. new.
+ (gcry_pk_verify): Pass verify func and the arg to pubkey_verify.
+ (pss_encode, pss_verify, pss_verify_cmp): New.
+
+2011-05-23 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (pkcs1_decode_for_encryption, oaep_decode): Fix memleak
+ when gcry_mpi_print fails.
+
+2011-05-18 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (sexp_data_to_mpi): Factor some code out to ...
+ (pkcs1_encode_for_encryption): .. new,
+ (pkcs1_encode_for_signature): .. new.
+ (pkcs1_decode_for_encryption): New.
+ (gcry_pk_decrypt): Do un-padding for PKCS#1 as well as OAEP.
+ (sexp_to_enc): Abolish "unpad" flag, which is not necessary since
+ we can do un-padding implicitly when "pkcs1" or "oaep" is given.
+
+2011-05-11 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_to_enc, sexp_data_to_mpi): Set LABEL to NULL
+ after free.
+ (sexp_to_enc, sexp_data_to_mpi): Do not allow multiple encoding
+ flags.
+ (oaep_encode, oaep_decode, sexp_to_key, sexp_to_sig)
+ (sexp_to_enc, sexp_data_to_mpi, gcry_pk_encrypt, gcry_pk_sign)
+ (gcry_pk_genkey, _gcry_pk_get_elements): Replace access to ERRNO
+ by gpg_err_code_from_syserror.
+
+2011-05-11 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (sexp_data_to_mpi): Factor some code out to ...
+ (get_hash_algo): .. new.
+ (mgf1, oaep_encode, oaep_decode): New.
+ (sexp_to_enc): Add arg CTX. Remove arg RET_WANT_PKCS1. Support
+ OAEP.
+ (sexp_data_to_mpi): Add arg CTX. Support OAEP.
+ (gcry_pk_encrypt): Pass a CTX to sexp_data_to_mpi.
+ (gcry_pk_decrypt): Pass a CTX tp sexp_to_enc and replace
+ WANT_PKCS1. Implement unpadding for OAEP.
+ (gcry_pk_sign): Pass NULL for CTX arg of sexp_data_to_mpi.
+ (gcry_pk_verify): Ditto.
+
+2011-04-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Replace gpg_err_code_from_errno by
+ gpg_err_code_from_syserror.
+
+2011-04-11 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Avoid double free of L2.
+
+ * cipher.c (_gcry_cipher_setctr): Clear unused lastiv info.
+ (gcry_cipher_ctl) <GCRYCTL_SET_CTR>: Implement by calling
+ _gcry_cipher_setctr.
+ (do_ctr_encrypt): Save last counter and reuse it.
+
+ * cipher.c (do_ctr_encrypt): Allow arbitrary length inputs to
+ match the 1.4 behaviour.
+
+2011-04-04 Werner Koch <wk@g10code.com>
+
+ * ecc.c (compute_keygrip): Release L1 while parsing "curve".
+
+ * pubkey.c (gcry_pk_get_keygrip): Always release NAME and L2.
+ Reported by Ben Kibbey.
+
+2011-03-28 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_elg_prime): Make sure that PRIME is
+ NULL if the called func ever returns an error.
+
+ * pubkey.c (gcry_pk_decrypt): Remove unused var PUBKEY.
+
+2011-03-09 Werner Koch <wk@g10code.com>
+
+ * kdf.c: New.
+
+2011-02-22 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (aesni_cleanup_2_4): New.
+ (aesenc_xmm1_xmm0, do_aesni_ctr_4): New.
+ (_gcry_aes_ctr_enc): New.
+ * cipher.c (struct gcry_cipher_handle): Add CTR_ENC. Move field
+ CTR into an u_ctr union and adjust all users.
+ (gcry_cipher_open): Use _gcry_aes_ctr_enc.
+ (do_ctr_encrypt): Use bulk mode.
+
+2011-02-18 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (u32_a_t): New.
+ (do_encrypt_aligned, do_encrypt_aligned): Use the new type to
+ avoid problems with strict aliasing rules.
+
+2011-02-16 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_aesni_cfb) [USE_AESNI]: New.
+ (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec) [USE_AESNI]: Use new fucntion.
+
+2011-02-15 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_aesni_enc_aligned, do_aesni_dec_aligned): Use
+ movdqa for the key but keep using movdqu for the data.
+ (do_aesni): Remove alignment detection. Don't burn the stack.
+ (aesni_prepare, aesni_cleanup): New macros.
+ (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (rijndael_decrypt, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use
+ these macros. Don't burn the stack in the USE_AESNI case.
+ (do_setkey): Add disabled code to use aeskeygenassist.
+
+2011-02-14 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (ATTR_ALIGNED_16): New
+ (do_aesni): Do not copy if already aligned.
+ (do_encrypt, do_decrypt): Ditto.
+ (rijndael_decrypt, rijndael_encrypt): Increase stack burning amount.
+
+ * rijndael.c (RIJNDAEL_context): Reorder fields. Change fieldname
+ ROUNDS to rounds. Move padlock_key into u1.
+ (keySched, keySched2): Rename macros to keyscherr and keyschdec
+ and change all users.
+ (padlockkey): New macro. Change all users of padlock_key.
+ * cipher.c (NEED_16BYTE_ALIGNED_CONTEXT): Always define if using gcc.
+ (struct gcry_cipher_handle): Align U_IV to at least 16 byte.
+
+2011-02-13 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_AESNI): New. Define for ia32 and gcc >= 4.
+ (m128i_t) [USE_AESNI]: New.
+ (RIJNDAEL_context) [USE_AESNI]: Add field use_aesni.
+ (do_setkey): Set USE_AESNI for all key lengths.
+ (prepare_decryption) [USE_AESNI]: Use aesimc instn if requested.
+ (do_aesni_enc_aligned, do_aesni_dec_aligned)
+ (do_aesni) [USE_AESNI]: New.
+ (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (rijndael_decrypt, _gcry_aes_cfb_dec)
+ (_gcry_aes_cbc_dec) [USE_AESNI]: Use do_aesni.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_curve): New.
+ (sexp_to_key): Add arg OVERRIDE_ELEMS.
+ (sexp_elements_extract_ecc): Allow for params only.
+ (gcry_pk_get_param): New.
+ * ecc.c (ecc_get_curve): New.
+ (ecc_get_param_sexp): New.
+
+2011-01-28 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Hack to insert the used curve name.
+
+2011-01-27 Werner Koch <wk@g10code.com>
+
+ * ecc.c (fill_in_curve): Remove.
+ (generate_curve): Rename to ..
+ (fill_in_curve): this. Remove setting of NAME_OID.
+ (ecc_encrypt_raw): Change name of arg DATA to K for better
+ readability. Use ECC_public_key instead of ECC_secret_key.
+ Require a caller to pass a complete pkey array.
+ (ecc_decrypt_raw): Require a caller to pass a complete skey array.
+ (elliptic_curve_t): Add field NAME.
+ (fill_in_curve): Set field.
+ (generate_key): Add arg R_USED_CURVE.
+ (ecc_generate_ext): Return used curve name.
+
+2011-01-13 Andrey Jivsov <openpgp@brainhub.org> (wk)
+
+ * ecc.c (ec2os): Do not free passed parameters X and Y. Adjust
+ callers.
+ (ecc_encrypt_raw, ecc_decrypt_raw): New.
+ (ecdh_names, _gcry_pubkey_spec_ecdh): New.
+ * pubkey.c (pubkey_table): Support ECDH.
+
+2010-08-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Remove double release of the module.
+ Fixes bug#1263.
+
+2010-06-10 Jeff Johnson <n3npq@mac.com> (wk)
+
+ * ecc.c (ecc_generate_ext): Parse transient-key flag.
+ (generate_key): Add arg TRANSIENT_KEY and use it to set the random
+ level.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-26 Werner Koch <wk@g10code.com>
+
+ * tiger.c (asn): Unfetter the old TIGER from an OID.
+ (TIGER_CONTEXT): Add field VARIANT.
+ (tiger_init): Factor code out to ...
+ (do_init): New.
+ (tiger1_init, tiger2_init): New.
+ (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): New.
+ * md.c (digest_table): Add TIGER1 and TIGER2 variants.
+
+2009-12-11 Werner Koch <wk@g10code.com>
+
+ * sha256.c (Cho, Maj, Sum0, Sum1): Turn macros into inline
+ functions.
+ (transform): Partly unroll to interweave the chain variables
+
+ * sha512.c (ROTR, Ch, Maj, Sum0, Sum1): Turn macros into inline
+ functions.
+ (transform): Partly unroll to interweave the chain variables.
+ Suggested by Christian Grothoff.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (o_flag_munging): New.
+ (tiger.o, tiger.lo): Use it.
+
+ * cipher.c (do_ctr_encrypt): Add arg OUTBUFLEN. Check for
+ suitable value. Add check for valid inputlen. Wipe temporary
+ memory.
+ (do_ctr_decrypt): Likewise.
+ (do_cbc_encrypt, do_cbc_decrypt): Add arg OUTBUFLEN. Check for
+ suitable value. Move check for valid inputlen to here; change
+ returned error from INV_ARG to INV_LENGTH.
+ (do_ecb_encrypt, do_ecb_decrypt): Ditto.
+ (do_cfb_encrypt, do_cfb_decrypt): Ditto.
+ (do_ofb_encrypt, do_ofb_decrypt): Ditto.
+ (cipher_encrypt, cipher_encrypt): Adjust for above changes.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Simplify.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Allow for GCRY_CIPHER_MODE_AESWRAP.
+ (cipher_encrypt, cipher_decrypt): Ditto.
+ (do_aeswrap_encrypt, do_aeswrap_decrypt): New.
+ (struct gcry_cipher_handle): Add field marks.
+ (cipher_setkey, cipher_setiv): Update marks flags.
+ (cipher_reset): Reset marks.
+ (cipher_encrypt, cipher_decrypt): Add new arg OUTBUFLEN.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Pass outbuflen to
+ cipher_encrypt. Replace GPG_ERR_TOO_SHORT by
+ GPG_ERR_BUFFER_TOO_SHORT.
+
+2009-08-21 Werner Koch <wk@g10code.com>
+
+ * dsa.c (dsa_generate_ext): Release retfactors array before
+ setting it to NULL. Reported by Daiko Ueno.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * md.c (md_read): Fix incomplete check for NULL.
+ Reported by Fabian Kail.
+
+2009-03-31 Werner Koch <wk@g10code.com>
+
+ * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not
+ GPG_ERR_PUBKEY_ALGO.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * rsa.c (generate_x931): Do not initialize TBL with automatic
+ variables.
+ * whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c
+ * md4.c, crc.c: Remove memory.h. This is garbage from gnupg.
+ Reported by Dan Fandrich.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * ecc.c (compute_keygrip): Remove superfluous const.
+
+2009-01-06 Werner Koch <wk@g10code.com>
+
+ * rmd160.c (oid_spec_rmd160): Add TeleTrust identifier.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add arg DOMAIN and use it if specified.
+ (generate_fips186): Ditto.
+ (dsa_generate_ext): Parse and check the optional "domain"
+ parameter and pass them to the generate functions.
+
+ * rijndael.c (rijndael_names): Add "AES128" and "AES-128".
+ (rijndael192_names): Add "AES-192".
+ (rijndael256_names): Add "AES-256".
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add arg TRANSIENT_KEY and use it to detrmine
+ the RNG quality needed.
+ (dsa_generate_ext): Parse the transient-key flag und pass it to
+ generate.
+
+2008-11-28 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate_fips186): Add arg DERIVEPARMS and use the seed
+ value if available.
+
+ * primegen.c (_gcry_generate_fips186_2_prime): Fix inner p loop.
+
+2008-11-26 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_fips186_3_prime): New.
+ * dsa.c (generate_fips186): Add arg USE_FIPS186_2.
+ (dsa_generate_ext): Parse new flag use-fips183-2.
+
+2008-11-25 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate_fips186): New.
+ (dsa_generate_ext): Use new function if derive-parms are given or
+ if in FIPS mode.
+ * primegen.c (_gcry_generate_fips186_2_prime): New.
+
+2008-11-24 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Insert code to output extrainfo.
+ (pubkey_generate): Add arg R_EXTRAINFO and pass it to the extended
+ key generation function.
+ * rsa.c (gen_x931_parm_xp, gen_x931_parm_xi): New.
+ (generate_x931): Generate params if not given.
+ (rsa_generate_ext): Parse use-x931 flag. Return p-q-swapped
+ indicator.
+ * dsa.c (dsa_generate_ext): Put RETFACTORS into R_EXTRAINFO if
+ possible.
+
+ * pubkey.c (gcry_pk_genkey): Remove parsing of almost all
+ parameters and pass the parameter S-expression to pubkey_generate.
+ (pubkey_generate): Simplify by requitring modules to parse the
+ parameters. Remove the special cases for Elgamal and ECC.
+ (sexp_elements_extract_ecc): Add arg EXTRASPEC and use it. Fix
+ small memory leak.
+ (sexp_to_key): Pass EXTRASPEC to sexp_elements_extract_ecc.
+ (pubkey_table) [USE_ELGAMAL]: Add real extraspec.
+ * rsa.c (rsa_generate_ext): Adjust for new calling convention.
+ * dsa.c (dsa_generate_ext): Ditto.
+ * elgamal.c (_gcry_elg_generate): Ditto. Rename to elg_generate_ext.
+ (elg_generate): New.
+ (_gcry_elg_generate_using_x): Remove after merging code with
+ elg_generate_ext.
+ (_gcry_pubkey_extraspec_elg): New.
+ (_gcry_elg_check_secret_key, _gcry_elg_encrypt, _gcry_elg_sign)
+ (_gcry_elg_verify, _gcry_elg_get_nbits): Make static and remove
+ _gcry_ prefix.
+ * ecc.c (_gcry_ecc_generate): Rename to ecc_generate_ext and
+ adjust for new calling convention.
+ (_gcry_ecc_get_param): Rename to ecc_get_param and make static.
+ (_gcry_pubkey_extraspec_ecdsa): Add ecc_generate_ext and
+ ecc_get_param.
+
+2008-11-20 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_generate): Add arg DERIVEPARMS.
+ (gcry_pk_genkey): Parse derive-parms and pass it to above.
+ * rsa.c (generate_x931): New.
+ (rsa_generate_ext): Add arg DERIVEPARMS and call new function in
+ fips mode or if DERIVEPARMS is given.
+ * primegen.c (_gcry_derive_x931_prime, find_x931_prime): New.
+
+2008-11-19 Werner Koch <wk@g10code.com>
+
+ * rsa.c (rsa_decrypt): Use gcry_create_nonce for blinding.
+ (generate): Rename to generate_std.
+
+2008-11-05 Werner Koch <wk@g10code.com>
+
+ * md.c (md_open): Use a switch to set the Bsize.
+ (prepare_macpads): Fix long key case for SHA384 and SHA512.
+
+ * cipher.c (gcry_cipher_handle): Add field EXTRASPEC.
+ (gcry_cipher_open): Set it.
+ (gcry_cipher_ctl): Add private control code to disable weak key
+ detection and to return the current input block.
+ * des.c (_tripledes_ctx): Add field FLAGS.
+ (do_tripledes_set_extra_info): New.
+ (_gcry_cipher_extraspec_tripledes): Add new function.
+ (do_tripledes_setkey): Disable weak key detection.
+
+2008-10-24 Werner Koch <wk@g10code.com>
+
+ * md.c (digest_table): Allow MD5 in fips mode.
+ (md_register_default): Take special action for MD5.
+ (md_enable, gcry_md_hash_buffer): Ditto.
+
+2008-09-30 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_setkey): Properly align "t" and "tk".
+ (prepare_decryption): Properly align "w". Fixes bug #936.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Parse domain parameter.
+ (pubkey_generate): Add new arg DOMAIN and remove special case for
+ DSA with qbits.
+ * rsa.c (rsa_generate): Add dummy args QBITS, NAME and DOMAIN and
+ rename to rsa_generate_ext. Change caller.
+ (_gcry_rsa_generate, _gcry_rsa_check_secret_key)
+ (_gcry_rsa_encrypt, _gcry_rsa_decrypt, _gcry_rsa_sign)
+ (_gcry_rsa_verify, _gcry_rsa_get_nbits): Make static and remove
+ _gcry_ prefix.
+ (_gcry_pubkey_spec_rsa, _gcry_pubkey_extraspec_rsa): Adjust names.
+ * dsa.c (dsa_generate_ext): New.
+ (_gcry_dsa_generate): Replace code by a call to dsa_generate.
+ (_gcry_dsa_check_secret_key, _gcry_dsa_sign, _gcry_dsa_verify)
+ (_gcry_dsa_get_nbits): Make static and remove _gcry prefix.
+ (_gcry_dsa_generate2): Remove.
+ (_gcry_pubkey_spec_dsa): Adjust to name changes.
+ (_gcry_pubkey_extraspec_rsa): Add dsa_generate_ext.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * ecc.c (run_selftests): Add arg EXTENDED.
+
+2008-09-12 Werner Koch <wk@g10code.com>
+
+ * rsa.c (test_keys): Do a bad case signature check.
+ * dsa.c (test_keys): Do a bad case check.
+
+ * cipher.c (_gcry_cipher_selftest): Add arg EXTENDED and pass it
+ to the called tests.
+ * md.c (_gcry_md_selftest): Ditto.
+ * pubkey.c (_gcry_pk_selftest): Ditto.
+ * rijndael.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftest_fips_128): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftest_fips_192): Add dummy arg EXTENDED.
+ (selftest_fips_256): Ditto.
+ * hmac-tests.c (_gcry_hmac_selftest): Ditto.
+ (run_selftests): Ditto.
+ (selftests_sha1): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha224, selftests_sha256): Ditto.
+ (selftests_sha384, selftests_sha512): Ditto.
+ * sha1.c (run_selftests): Add arg EXTENDED and pass it to the
+ called test.
+ (selftests_sha1): Add arg EXTENDED and run only one test
+ non-extended mode.
+ * sha256.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftests_sha224): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha256): Ditto.
+ * sha512.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftests_sha384): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha512): Ditto.
+ * des.c (run_selftests): Add arg EXTENDED and pass it to the
+ called test.
+ (selftest_fips): Add dummy arg EXTENDED.
+ * rsa.c (run_selftests): Add dummy arg EXTENDED.
+
+ * dsa.c (run_selftests): Add dummy arg EXTENDED.
+
+ * rsa.c (extract_a_from_sexp): New.
+ (selftest_encr_1024): Check that the ciphertext does not match the
+ plaintext.
+ (test_keys): Improve tests and return an error status.
+ (generate): Return an error if test_keys fails.
+ * dsa.c (test_keys): Add comments and return an error status.
+ (generate): Return an error if test_keys failed.
+
+2008-09-11 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_decrypt): Return an error instead of calling
+ BUG in case of a practically impossible condition.
+ (sample_secret_key, sample_public_key): New.
+ (selftest_sign_1024, selftest_encr_1024): New.
+ (selftests_rsa): Implement tests.
+ * dsa.c (sample_secret_key, sample_public_key): New.
+ (selftest_sign_1024): New.
+ (selftests_dsa): Implement tests.
+
+2008-09-09 Werner Koch <wk@g10code.com>
+
+ * hmac-tests.c (selftests_sha1): Add tests.
+ (selftests_sha224, selftests_sha384, selftests_sha512): Make up tests.
+
+ * hash-common.c, hash-common.h: New.
+ * sha1.c (selftests_sha1): Add 3 tests.
+ * sha256.c (selftests_sha256, selftests_sha224): Ditto.
+ * sha512.c (selftests_sha512, selftests_sha384): Ditto.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Remove the special case for RSA
+ and check whether a custom computation function has been setup.
+ * rsa.c (compute_keygrip): New.
+ (_gcry_pubkey_extraspec_rsa): Setup this function.
+ * ecc.c (compute_keygrip): New.
+ (_gcry_pubkey_extraspec_ecdsa): Setup this function.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * cipher.c (cipher_decrypt, cipher_encrypt): Return an error if
+ mode NONE is used.
+ (gcry_cipher_open): Allow mode NONE only with a debug flag set and
+ if not in FIPS mode.
+
+2008-08-26 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_generate): Add arg KEYGEN_FLAGS.
+ (gcry_pk_genkey): Implement new parameter "transient-key" and
+ pass it as flags to pubkey_generate.
+ (pubkey_generate): Make use of an ext_generate function.
+ * rsa.c (generate): Add new arg transient_key and pass appropriate
+ args to the prime generator.
+ (_gcry_rsa_generate): Factor all code out to ...
+ (rsa_generate): .. new func with extra arg KEYGEN_FLAGS.
+ (_gcry_pubkey_extraspec_ecdsa): Setup rsa_generate.
+ * primegen.c (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Add new arg RANDOM_LEVEL.
+
+2008-08-21 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Use a constant macro for the random
+ level.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_elements_extract_ecc) [!USE_ECC]: Do not allow
+ allow "curve" parameter.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (_gcry_pk_selftest): New.
+ * dsa.c (selftests_dsa, run_selftests): New.
+ * rsa.c (selftests_rsa, run_selftests): New.
+ * ecc.c (selftests_ecdsa, run_selftests): New.
+
+ * md.c (_gcry_md_selftest): New.
+ * sha1.c (run_selftests, selftests_sha1): New.
+ * sha256.c (selftests_sha224, selftests_sha256, run_selftests): New.
+ * sha512.c (selftests_sha384, selftests_sha512, run_selftests): New.
+
+ * des.c (selftest): Remove static variable form selftest.
+ (des_setkey): No on-the-fly self test in fips mode.
+ (tripledes_set3keys): Ditto.
+
+ * cipher.c (_gcry_cipher_setkey, _gcry_cipher_setiv):
+
+ * dsa.c (generate): Bail out in fips mode if NBITS is less than 1024.
+ * rsa.c (generate): Return an error code if the the requested size
+ is less than 1024 and we are in fpis mode.
+ (_gcry_rsa_generate): Take care of that error code.
+
+ * ecc.c (generate_curve): In fips mode enable only NIST curves.
+
+ * cipher.c (_gcry_cipher_selftest): New.
+
+ * sha512.c (_gcry_digest_extraspec_sha384)
+ (_gcry_digest_extraspec_sha512): New.
+ * sha256.c (_gcry_digest_extraspec_sha224)
+ (_gcry_digest_extraspec_sha256): New.
+ * sha1.c (_gcry_digest_extraspec_sha1): New.
+ * ecc.c (_gcry_pubkey_extraspec_ecdsa): New.
+ * dsa.c (_gcry_pubkey_extraspec_dsa): New.
+ * rsa.c (_gcry_pubkey_extraspec_rsa): New.
+ * rijndael.c (_gcry_cipher_extraspec_aes)
+ (_gcry_cipher_extraspec_aes192, _gcry_cipher_extraspec_aes256): New.
+ * des.c (_gcry_cipher_extraspec_tripledes): New.
+
+ * cipher.c (gcry_cipher_register): Rename to _gcry_cipher_register.
+ Add arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (cipher_table_entry): Add extraspec field.
+ * md.c (_gcry_md_register): Rename to _gcry_md_register. Add
+ arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (digest_table_entry): Add extraspec field.
+ * pubkey.c (gcry_pk_register): Rename to _gcry_pk_register. Add
+ arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (pubkey_table_entry): Add extraspec field.
+
+ * ac.c: Let most public functions return GPG_ERR_UNSUPPORTED in
+ fips mode.
+
+ * pubkey.c (pubkey_table_entry): Add field FIPS_ALLOWED and mark
+ appropriate algorithms.
+ (dummy_generate, dummy_check_secret_key, dummy_encrypt)
+ (dummy_decrypt, dummy_sign, dummy_verify, dummy_get_nbits): Signal
+ a fips error when used.
+ (gcry_pk_register): In fips mode do not allow to register new
+ algorithms.
+
+ * md.c (digest_table): Add field FIPS_ALLOWED and mark appropriate
+ algorithms.
+ (md_register_default): In fips mode register only fips algorithms.
+ (gcry_md_register): In fips mode do not allow to register new
+ algorithms.
+ (gcry_md_get): Signal a fips error if called.
+ (gcry_md_hash_buffer): Do not allow rmd160 when not in fips mode.
+ (md_start_debug): Disable in fips_mode.
+
+ * md.c (gcry_md_register_default): Rename to ..
+ (md_register_default): .. this.
+ (md_digest): Remove this commented fucntion.
+ * pubkey.c (gcry_pk_register_default): Rename to ..
+ (pk_register_default): .. this.
+
+ * cipher.c (cipher_table_entry): Add field FIPS_ALLOWED.
+ (gcry_cipher_register_default): Register only fips approved
+ algorithms.
+ (gcry_cipher_register): Do not allow to register new ciphers.
+ (cipher_setiv): Signal fips error.
+
+ * cipher (gcry_cipher_register_default): Rename to ..
+ (cipher_register_default): .. this.
+ (REGISTER_DEFAULT_CIPHERS): Adjust for that change.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c, random.h, rndhw.c, rndunix.c, rand-internal.h
+ * random.c, rndegd.c, rndlinux.c, rndw32.c: Move to ../cipher.
+ * Makefile.am: Remove random stuff.
+
+2008-06-24 Szakats Istvan <szaki.ms@gmail.com> (wk)
+
+ * ac.c (_gcry_ac_key_destroy, _gcry_ac_key_pair_generate): Relase
+ some more memory.
+
+2008-04-22 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use Padlock if possible.
+
+2008-04-18 Werner Koch <wk@g10code.com>
+
+ * sha1.c (transform_aligned): Remove. That is will obviosuly not
+ work because we need a scratch working area and our internal API
+ does not allow to modify the buffers.
+
+ * rijndael.c: Factor tables out to ..
+ * rijndael-tables.h: .. new.
+
+ * ac.c (ac_data_extract): Make static.
+
+ * camellia.h [HAVE_CONFIG_H]: Include config.h.
+
+ * rndw32.c (registry_poll): Only print the performance data
+ problem warning once. Suggested by Simon Josefsson.
+
+2008-03-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open) [USE_AES]: Init bulk encryption only
+ if requested. Suggested by Dirk Stoecker.
+
+2008-03-18 Werner Koch <wk@g10code.com>
+
+ * sha1.c: Include stdint.h.
+ (transform): Add arg NBLOCKS so that we can work on more than one
+ block and avoid updates of the chaining variables. Changed all
+ callers to use 1.
+ (sha1_write): Replace loop around transform.
+ (transform_aligned) [WORDS_BIGENDIAN]: New.
+ (TRANSFORM): New macro to replace all direct calls of transform.
+
+2008-03-17 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_dec): New.
+ (do_encrypt): Factor code out to ..
+ (do_encrypt_aligned): .. New.
+ (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec): Use new function.
+ (do_decrypt): Factor code out to ..
+ (do_decrypt_aligned): .. new.
+ (_gcry_aes_cbc_enc, _gcry_aes_cbc_dec): New.
+ * cipher.c (struct gcry_cipher_handle): Put field IV into new
+ union U_IV to enforce proper alignment. Change all users.
+ (do_cfb_decrypt): Optimize.
+ (do_cbc_encrypt, do_cbc_decrypt): Optimize.
+
+2008-03-15 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_enc): New.
+ * cipher.c (struct gcry_cipher_handle): Add field ALGO and BULK.
+ (gcry_cipher_open): Set ALGO and BULK.
+ (do_cfb_encrypt): Optimize.
+
+2008-02-18 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_verify) [IS_DEVELOPMENT_VERSION]: Print
+ intermediate results.
+
+2008-01-08 Werner Koch <wk@g10code.com>
+
+ * random.c (add_randomness): Do not just increment
+ POOL_FILLED_COUNTER but update it by the actual amount of data.
+
+2007-12-13 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Support SHA-224.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_PADLOCK): Depend on ENABLE_PADLOCK_SUPPORT.
+ * rndhw.c (USE_PADLOCK): Ditto
+
+ * rsa.c (secret): Fixed condition test for using CRT. Reported by
+ Dean Scarff. Fixes bug#864.
+ (_gcry_rsa_check_secret_key): Return an erro if the optional
+ parameters are missing.
+ * pubkey.c (sexp_elements_extract): Add arg ALGO_NAME. Changed all
+ callers to pass NULL. Add hack to allow for optional RSA
+ parameters.
+ (sexp_to_key): Pass algo name to sexp_elements_extract.
+
+2007-12-03 Werner Koch <wk@g10code.com>
+
+ * random.c (gcry_random_add_bytes): Implement it.
+ * rand-internal.h (RANDOM_ORIGIN_EXTERNAL): New.
+
+2007-11-30 Werner Koch <wk@g10code.com>
+
+ * rndhw.c: New.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Try to read 50%
+ directly from the hwrng.
+ * random.c (do_fast_random_poll): Also run the hw rng fast poll.
+ (_gcry_random_dump_stats): Tell whether the hw rng failed.
+
+2007-11-29 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_PADLOCK): Define new macro used for ia32.
+ (RIJNDAEL_context) [USE_PADLOCK]: Add fields USE_PADLOCK and
+ PADLOCK_KEY.
+ (do_setkey) [USE_PADLOCK]: Enable padlock if available for 128 bit
+ AES.
+ (do_padlock) [USE_PADLOCK]: New.
+ (rijndael_encrypt, rijndael_decrypt) [USE_PADLOCK]: Divert to
+ do_padlock.
+ * cipher.c (cipher_context_alignment_t): New. Use it in this
+ module in place of PROPERLY_ALIGNED_TYPE.
+ (NEED_16BYTE_ALIGNED_CONTEXT): Define macro for ia32.
+ (struct gcry_cipher_handle): Add field HANDLE_OFFSET.
+ (gcry_cipher_open): Take care of increased alignment requirements.
+ (gcry_cipher_close): Ditto.
+
+2007-11-28 Werner Koch <wk@g10code.com>
+
+ * sha256.c (asn224): Fixed wrong template. It happened due to a
+ bug in RFC4880. SHA-224 is not in the stable version of libgcrypt
+ so the consequences are limited to users of this devel version.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * ac.c (gcry_ac_data_new): Remove due to the visibility wrapper.
+ (gcry_ac_data_destroy, gcry_ac_data_copy, gcry_ac_data_length)
+ (gcry_ac_data_set, gcry_ac_data_get_name, gcry_ac_data_get_index)
+ (gcry_ac_data_to_sexp, gcry_ac_data_from_sexp)
+ (gcry_ac_data_clear, gcry_ac_io_init, gcry_ac_open)
+ (gcry_ac_close, gcry_ac_key_init, gcry_ac_key_pair_generate)
+ (gcry_ac_key_pair_extract, gcry_ac_key_destroy)
+ (gcry_ac_key_pair_destroy, gcry_ac_key_data_get)
+ (gcry_ac_key_test, gcry_ac_key_get_nbits, gcry_ac_key_get_grip)
+ (gcry_ac_data_encrypt, gcry_ac_data_decrypt, gcry_ac_data_sign)
+ (gcry_ac_data_verify, gcry_ac_data_encode, gcry_ac_data_decode)
+ (gcry_ac_mpi_to_os, gcry_ac_mpi_to_os_alloc, gcry_ac_os_to_mpi)
+ (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme)
+ (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme)
+ (gcry_ac_io_init_va): Ditto.
+ (gcry_ac_id_to_name, gcry_ac_name_to_id): Remove as these
+ deprecated functions are now implemented by visibility.c.
+
+2007-10-26 Werner Koch <wk@g10code.com>
+
+ * rndw32.c: Disable debug flag.
+
+2007-10-25 Werner Koch <wk@g10code.com>
+
+ * rndw32.c: Updated from current cryptlib snapshot and modified
+ for our use. Removed support from pre NT systems.
+ (slow_gatherer_windows95): Remove.
+ (_gcry_rndw32_gather_random): Require an NT platform.
+ (init_system_rng, read_system_rng, read_mbm_data): New.
+ (slow_gatherer_windowsNT): Rename to ...
+ (slow_gatherer): .. this. Read system RNG and MBM.
+ (registry_poll): New with code factored out from slow_gatherer.
+
+2007-08-23 Werner Koch <wk@g10code.com>
+
+ * random.c (pool_filled_counter): New.
+ (add_randomness): Use it.
+
+2007-08-22 Werner Koch <wk@g10code.com>
+
+ * rndw32.c, rndunix.c: Switched to LGPL.
+
+2007-05-30 Werner Koch <wk@g10code.com>
+
+ * camellia.h, camellia.c: Replace by new LGPL version and adjusted
+ camellia.h.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (_gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read):
+ Adjust users of gcry_ac_io_t because union is not anonymous
+ anymore.
+
+2007-05-02 Werner Koch <wk@g10code.com>
+
+ * camellia-glue.c (camellia_setkey, camellia_encrypt)
+ (camellia_decrypt): Recalculated used stack size in called
+ functions.
+ * camellia.h: Redefine external symbols.
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am, cipher.c: Add Camellia.
+
+ * camellia-glue.c: New. The necessary glue to interface libgcrypt
+ to the stock NTT Camellia distribution.
+
+ * camellia.h, camellia.c: The stock NTT Camellia distribution
+ (GPL).
+
+2007-04-30 David Shaw <dshaw@jabberwocky.com>
+
+ * cipher.c: Use #if instead of #ifdef as configure defines the
+ USE_cipher defines as 0 for disabled.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * rndegd.c (_gcry_rndegd_set_socket_name): New.
+
+2007-04-30 Marcus Brinkmann <marcus@g10code.de>
+
+ * ecc.c (ec2os): Fix relocation of short numbers.
+
+ * ecc.c (generate_key): Do not allocate D, which will be allocated
+ by GEN_K. Remove G. Fix test if g_x, g_y resp. q_x, q_y are
+ requested.
+ (_gcry_ecc_generate): Release unneeded members of SK.
+ * pubkey.c (sexp_to_key): Release NAME.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (gcry_ac_mpi): Remove member NAME_PROVIDED.
+ (ac_data_mpi_copy, _gcry_ac_data_set, _gcry_ac_data_get_name)
+ (_gcry_ac_data_get_index, ac_data_construct): Adjust handling of
+ NAME accordingly.
+
+2007-04-20 Werner Koch <wk@g10code.com>
+
+ * ecc.c (domain_parms): Add standard brainpool curves.
+
+2007-04-18 Werner Koch <wk@g10code.com>
+
+ * ecc.c (generate_curve): Implement alias mechanism.
+
+ * pubkey.c (sexp_elements_extract_ecc): New.
+ (sexp_to_key): Add special case for ecc.
+ (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_genkey): Replace
+ name_terminated stuff by a call to _gcry_sexp_nth_string.
+ (gcry_pk_get_keygrip): Ditto.
+
+2007-04-16 Werner Koch <wk@g10code.com>
+
+ * ecc.c (_gcry_ecc_generate): Renamed DUMMY to CURVE and use it.
+
+2007-04-13 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (ac_data_construct): Cast const away to suppress compiler
+ warning.
+
+ * ecc.c (ecc_generate): Avoid compiler warning for unused argument
+ DUMMY.
+ (ecc_verify): Avoid compiler warning for unused arguments CMP and
+ OPAQUEV.
+
+2007-04-06 Werner Koch <wk@g10code.com>
+
+ * sha1.c (oid_spec_sha1): Add another oid from X9.62.
+
+2007-03-28 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Do not issue misc-key-info if it is
+ empty.
+ (gcry_pk_genkey): New parameter "curve".
+
+ * ecc.c: Entirely rewritten with only a few traces of the old
+ code left.
+ (_gcry_ecc_generate): New.
+ (generate_key) New arg NAME.
+ (generate_curve): Ditto. Return actual number of NBITS.
+
+2007-03-26 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Increase size of SKEY array and add a
+ runtime bounds check.
+
+2007-03-23 Werner Koch <wk@g10code.com>
+
+ * ecc.c (ecc_ctx_init, ecc_ctx_free, ecc_mod, ecc_mulm): New.
+ (duplicate_point, sum_points, escalar_mult): Don't use a
+ copy of base->p. Replaced all mpi_mulm by ecc_mulm so that we can
+ experiment with different algorithms.
+ (generate_key, check_secret_key, sign, verify): Initialize a
+ computation context for use by ecc_mulm.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_table): Initialize ECC.
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Add ecc.c.
+ * ecc.c: New. Heavily reformatted and changed for use in libgcrypt.
+ (point_init): New.
+ (escalar_mult): Make arg R the first arg to be similar to the mpi
+ functions.
+ (duplicate_point): Ditto
+ (sum_points): Ditto
+ (sign, verify): Remove unneeded copy operations.
+ (sum_points): Removed memory leaks and optimized some compares.
+ (verify): Simplified input check.
+
+2007-03-14 Werner Koch <wk@g10code.com>
+
+ * random.c (MASK_LEVEL): Removed macro as it was used only at one
+ place. Open coded it there.
+ (gcry_randomize, _gcry_update_random_seed_file)
+ (_gcry_fast_random_poll): Factor lock code out to ..
+ (lock_pool, unlock_pool): .. new.
+ (initialize): Look the pool while allocating.
+ (read_random_source, do_fast_random_poll): Moved intialization to ...
+ (initialize): .. here.
+ (_gcry_enable_quick_random_gen): No more need for initialization.
+ (is_initialized): Moved this global flag to ..
+ (initialize): .. here and changed all users to unconditionally call
+ initialize.
+ (add_randomness): Remove initalization here. It simply can't
+ happen.
+
+ * random.c (enum random_origins): Moved to ..
+ * rand-internal.h: .. here.
+ * rndunix.c (_gcry_rndunix_gather_random): Use enum in prototype
+ for ORIGIN and renamed REQUESTOR to ORIGIN.
+ * rndegd.c (_gcry_rndegd_gather_random): Ditto.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Ditto.
+ * rndw32.c (_gcry_rndw32_gather_random): Ditto.
+ (_gcry_rndw32_gather_random_fast): Ditto.
+
+2007-03-13 Werner Koch <wk@g10code.com>
+
+ * random.c (enum random_origins): New.
+ (add_randomness): Renamed arg SOURCE to ORIGIN.
+ (read_random_source): Renamed arg REQUESTOR to ORIGIN.
+ (getfnc_gather_random): Removed static variable because this
+ function is only called one and thus we don't need this
+ optimization.
+ (_gcry_quick_random_gen): Removed and replaced by..
+ (_gcry_enable_quick_random_gen): .. this. It is onlyu used to
+ enable it and it does not make sense to disable it later. Changed
+ the only one caller too.
+ (get_random_bytes): Removed.
+ (gcry_random_bytes, gcry_random_bytes_secure): Implement in terms
+ of gcry_randomize.
+ * random-daemon.c (_gcry_daemon_get_random_bytes): Removed.
+
+2007-02-23 Werner Koch <wk@g10code.com>
+
+ * elgamal.c (generate): Removed unused variable TEMP.
+ (test_keys): New arg NODIE.
+ (generate_using_x, _gcry_elg_generate_using_x): New.
+ * pubkey.c (pubkey_generate): New arg XVALUE and direct call to
+ the new elgamal generate fucntion.
+ (gcry_pk_genkey): Parse the new "xvalue" tag.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Handle dynamically allocated
+ algorithms. Suggested by Neil Dunbar. Fixes bug#596.
+
+ * rndw32.c (_gcry_rndw32_gather_random_fast): Make it return void.
+
+ * cipher.c (gcry_cipher_algo_name): Simplified.
+
+ * random.c: Use the daemon only if compiled with USE_RANDOM_DAEMON.
+
+ * Makefile.am (libcipher_la_SOURCES): Build random-daemon support
+ only if requested.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * random.c (rndpool, keypool): Make unsigned.
+ (mix_pool): Change char* variables to unsigned char*.
+ (gcry_randomize): Make arg BUFFER a void*.
+ (gcry_create_nonce): Ditto.
+
+ * rmd160.c (gcry_rmd160_mixblock): Make BUFFER a void*.
+ (_gcry_rmd160_hash_buffer): Make OUTBUF and BUFFER void*.
+ * sha1.c (_gcry_sha1_hash_buffer): Ditto.
+
+ * cipher.c (gcry_cipher_encrypt, cry_cipher_decrypt): Change
+ buffer args to void*.
+ (gcry_cipher_register): Make ALGORITHM_ID a int *.
+
+ * md.c (md_start_debug): Make SUFFIX a const char*. Use snprintf.
+ (gcry_md_debug): New.
+ (gcry_md_ctl): Changed arg BUFFER from unsigned char*.
+
+ * md.c (md_write): Make INBUF a const void*.
+ (gcry_md_write): Remove needless cast.
+ * crc.c (crc32_write): Make INBUF a const void*
+ (update_crc32, crc24rfc2440_write): Ditto.
+ * sha512.c (sha512_write, transform): Ditto.
+ * sha256.c (sha256_write, transform): Ditto.
+ * rmd160.c (rmd160_write, transform): Ditto.
+ * md5.c (md5_write, transform): Ditto.
+ * md4.c (md4_write, transform): Ditto.
+ * sha1.c (sha1_write, transform): Ditto.
+
+ * tiger.c (tiger_write, transform): Ditto.
+ * whirlpool.c (whirlpool_write, whirlpool_add, transform): Ditto.
+
+ * elgamal.c (elg_names): Change to a const*.
+ * dsa.c (dsa_names): Ditto.
+ * rsa.c (rsa_names): Ditto.
+ * pubkey.c (gcry_pk_lookup_func_name): Make ALIASES a const.
+
+2007-02-20 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (open_device): Remove unsused arg MINOR.
+
+2007-01-30 Werner Koch <wk@g10code.com>
+
+ * sha256.c (oid_spec_sha256): Add alias from pkcs#1.
+ * sha512.c (oid_spec_sha512): Ditto.
+ (oid_spec_sha384): Ditto.
+
+2006-12-18 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (set_cloexec_flag): New.
+ (open_device): Set close-on-exit flags. Suggested by Max
+ Kellermann. Fixes Debian#403613.
+
+ * Makefile.am (AM_CPPFLAGS, AM_CFLAGS): Splitted and merged
+ Moritz' changes.
+ (INCLUDES): Removed.
+
+2006-11-30 Werner Koch <wk@g10code.com>
+
+ * serpent.c (byte_swap_32): Remove trailing semicolon.
+
+2006-11-15 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (INCLUDES): Include ../src/
+
+2006-11-03 Werner Koch <wk@g10code.com>
+
+ * random.c [HAVE_GETTIMEOFDAY]: Included sys/time.h and not
+ sys/times.h. Reported by Rafaël Carré.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
+ new gcrypt.h is used, not the one installed in the system.
+
+2006-10-25 Werner Koch <wk@g10code.com>
+
+ * primegen.c (prime_generate_internal): Tweaked use of secure
+ memory and entropy use. Safe unused primes from the pool. Allocate
+ at least a pool of 30.
+ (save_pool_prime, get_pool_prime): New.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * ac.c (_gcry_ac_data_from_sexp): Reset sexp_tmp for failsafe
+ means. Release sexp_cur if needed. Reported by Dirk Stoecker.
+
+ * pubkey.c (pubkeys_registered_lock): Intialized it. It is not
+ realy needed because this is a mere initialization to 0 anyway.
+ Noted by Victor Stinner.
+
+2006-10-17 Werner Koch <wk@g10code.com>
+
+ * dsa.c (_gcry_dsa_generate2): New.
+ (generate): New arg QBITS. Add sanity checks for reasonable qbits
+ and nbits.
+ * pubkey.c (gcry_pk_genkey): Parse an qbits element.
+ (pubkey_generate): New arg QBITS. Pass it to the DSA generation.
+
+2006-10-05 Werner Koch <wk@g10code.com>
+
+ * md.c (gcry_md_algo_info) <get_asnoid>: Check that the algo is
+ available.
+
+2006-10-04 David Shaw <dshaw@jabberwocky.com> (wk)
+
+ * tiger.c (round): Rename to tiger_round as gcc 4 has a built-in
+ round function that this conflicts with.
+
+2006-09-11 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (slow_gatherer_windowsNT): While adding data use the
+ size of the diskPerformance and not its address. Has been fixed in
+ GnuPG more than a year ago. Noted by Lee Fisher.
+
+2006-08-30 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Need to allow "ripemd160" here as
+ this is the canonical name.
+
+2006-08-29 Hye-Shik Chang <perky@FreeBSD.org> (wk)
+
+ * seed.c: New.
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c (_gcry_daemon_initialize_basics): Don't
+ initialize the socket. Remove arg SOCKETNAME.
+ (connect_to_socket): Make sure that daemon is set to -1 on error.
+ (call_daemon): Initialize the socket on the first call.
+ (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes)
+ (_gcry_daemon_create_nonce): New arg SOCKETNAME.
+ * random.c (initialize): Call new daemon initializator.
+ (get_random_bytes, gcry_randomize, gcry_create_nonce): Pass socket
+ name to daemon call and reset allow_daemon on failure.
+
+2006-07-26 Werner Koch <wk@g10code.com>
+
+ * rmd160.c (_gcry_rmd160_mixblock): Add cast to transform call.
+
+ * blowfish.c (selftest): Cast string to usnigned char*.
+
+ * primegen.c (prime_generate_internal): Cast unsigned/char*
+ mismatch in calling m_out_of_n.
+ (is_prime): Changed COUNT to unsigned int *.
+
+ * ac.c (_gcry_ac_data_copy): Initialize DATA_MPIS.
+
+ * random.c (gcry_create_nonce): Update the pid after a fork.
+ Reported by Uoti Urpala.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * sha512.c: Fix typo in copyright notice.
+
+2006-06-21 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_generate): Replace xcalloc by calloc.
+ * pubkey.c (gcry_pk_encrypt, gcry_pk_sign): Ditto.
+ (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_encrypt)
+ (gcry_pk_sign, gcry_pk_genkey, gcry_pk_get_keygrip): Ditto.
+ * md.c (md_copy): Ditto.
+
+2006-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * random-daemon.c (_gcry_daemon_initialize_basics): New argument:
+ SOCKETNAME. Passing on to connect_to_socket() if non-NULL.
+ (connect_to_socket, writen, readn, call_daemon): New functions.
+ (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes)
+ (_gcry_daemon_create_nonce): Call call_daemon().
+ (RANDOM_DAEMON_SOCKET): New symbol.
+ (daemon_socket): New static variable.
+
+ * random.h (_gcry_daemon_initialize_basics): New parameter:
+ SOCKETNAME.
+ (_gcry_set_random_daemon_socket): New declaration.
+
+ * random.c (initialize_basics): Pass DAEMON_SOCKET_NAME to
+ _gcry_daemon_initialize_basics.
+ (_gcry_set_random_daemon_socket): New function, setting
+ DAEMON_SOCKET_NAME.
+
+2006-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (eme_pkcs_v1_5_encode): Use KEY_SIZE directly, no need to
+ call gcry_ac_key_get_nbits.
+ (eme_pkcs_v1_5_decode): Likewise.
+ (ac_es_dencode_prepare_pkcs_v1_5): Fill options_em structure with
+ key_size.
+ (_gcry_ac_data_dump, gcry_ac_data_dump): New functions.
+ (_gcry_ac_data_to_sexp, _gcry_ac_data_from_sexp): More or less
+ rewritten; changed S-Expression format so that it matches the one
+ used in pubkey.c.
+
+2006-03-15 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c: New.
+ * random.c (_gcry_use_random_daemon): New.
+ (get_random_bytes, gcry_randomize, gcry_create_nonce): Try
+ diverting to the daemon functions.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * random.c (lock_seed_file): New.
+ (read_seed_file, _gcry_update_random_seed_file): Use it.
+
+ * random.c (gcry_create_nonce): Detect a fork and re-seed.
+ (read_pool): Fixed the fork detection; it used to work only for
+ multi-threaded processes.
+
+2006-03-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * md.c (md_open): Use new variable macpads_Bsize instead of
+ hardwiring the block size. Changed at all places.
+
+2006-03-10 Brad Hards <bradh@frogmouth.net> (wk, patch 2005-04-22)
+
+ * md.c, sha256.c: Add support for SHA-224.
+ (sha224_init): New.
+
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * cipher.c (cipher_encrypt, cipher_decrypt, do_ofb_encrypt)
+ (do_ofb_decrypt, gcry_cipher_open): Implement Output Feedback Mode.
+
+2005-11-02 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_algo_name): Return "?" instead of NULL for
+ unknown algorithm IDs.
+ * cipher.c (cipher_algo_to_string): Likewise.
+
+2005-11-01 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_algo_info): Don't forget to break after switch
+ case.
+
+2005-09-19 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add preliminary support for 2 and 4 keys.
+ Return an error code if the key size is not supported.
+ (_gcry_dsa_generate): Return an error.
+
+2005-08-22 Werner Koch <wk@g10code.com>
+
+ * primegen.c (check_prime): New arg RM_ROUNDS.
+ (prime_generate_internal): Call it here with 5 rounds as used
+ before.
+ (gcry_prime_check): But here with 64 rounds.
+ (is_prime): Make sure never to use less than 5 rounds.
+
+2005-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_init): New function.
+
+2005-04-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_io_write, _gcry_ac_io_read): Initialize err to
+ make the compiler happy.
+ Always use errno, now that gcry_malloc() is guaranteed to set
+ errno on failure.
+ (_gcry_ac_data_to_sexp): Don't forget to goto out after error in
+ loop.
+ (_gcry_ac_data_to_sexp): Remove unused variable: mpi_list;
+ (_gcry_ac_data_to_sexp): Always deallocate sexp_buffer.
+ (_gcry_ac_data_from_sexp): Don't forget to initialize data_set_new.
+ (_gcry_ac_data_from_sexp): Handle special case, which is
+ necessary, since gcry_sexp_nth() does not distinguish between
+ "element does not exist" and "element is the empty list".
+ (_gcry_ac_io_init_va): Use assert to make sure that mode and type
+ are correct.
+ Use gcry_error_t types where gcry_err_code_t types have been used
+ before.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_data_sign_scheme): Don't forget to initialize
+ buffer.
+
+ * whirlpool.c: New file.
+ * md.c (digest_table): Add whirlpool.
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Added: whirlpool.c.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_data_from_sexp): Use length of SEXP_CUR, not
+ length of SEXP; do not forget to set SEXP_TMP to NULL after it has
+ been released.
+
+ (struct gcry_ac_mpi): New member: name_provided.
+ (_gcry_ac_data_set): Rename variable `name_final' to `name_cp';
+ remove const qualifier; change code to not cast away const
+ qualifiers; use name_provided member as well.
+ (_gcry_ac_data_set, _gcry_ac_data_get_name): Use name_provided
+ member of named mpi structure.
+
+ (gcry_ac_name_to_id): Do not forget to initialize err.
+ (_gcry_ac_data_get_index): Do not forget to initialize mpi_return;
+ use gcry_free() instead of free(); remove unnecessary cast; rename
+ mpi_return and name_return to mpi_cp and name_cp; adjust code.
+ (ac_data_mpi_copy): Do not cast away const qualifier.
+ (ac_data_values_destroy): Likewise.
+ (ac_data_construct): Likewise.
+
+ (ac_data_mpi_copy): Initialize flags to GCRY_AC_FLAG_DEALLOC.
+ (ac_data_extract): Use GCRY_AC_FLAG_DEALLOC instead of
+ GCRY_AC_FLAG_COPY.
+
+ (_gcry_ac_io_init_va, _gcry_ac_io_init, gcry_ac_io_init)
+ (gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read)
+ (_gcry_ac_io_read_all, _gcry_ac_io_process): New functions.
+ (gry_ac_em_dencode_t): Use gcry_ac_io_t in prototype instead of
+ memroy strings directly; adjust encode/decode functions to use io
+ objects.
+ (emsa_pkcs_v1_5_encode_data_cb): New function ...
+ (emsa_pkcs_v1_5_encode): ... use it here.
+ (ac_data_dencode): Use io objects.
+ (_gcry_ac_data_encode, _gcry_ac_data_decode, gcry_ac_data_encode)
+ (gcry_ac_data_decode): Likewise.
+ (_gcry_ac_data_encrypt_scheme, gcry_ac_data_encrypt_scheme)
+ (_gcry_ac_data_decrypt_scheme, gcry_ac_data_decrypt_scheme)
+ (_gcry_ac_data_sign_scheme, gcry_ac_data_sign_scheme)
+ (_gcry_ac_data_verify_scheme, gcry_ac_data_verify_scheme):
+ Likewise.
+
+2005-03-23 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (_gcry_rndw32_gather_random_fast): While adding data
+ use the size of the object and not the one of its address. Bug
+ reported by Sascha Kiefer.
+
+2005-03-19 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (do_cbc_encrypt): Be careful to not overwrite data,
+ which is to be used later on. This happend, in case CTS is
+ enabled and OUTBUF is equal to INBUF.
+
+2005-02-25 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Allow for shadowed-private-key.
+
+2005-02-13 Moritz Schulte <moritz@g10code.com>
+
+ * serpent.c: Updated from 1.2 branch:
+
+ s/u32_t/u32/ and s/byte_t/byte/. Too match what we have always
+ used and are using in all other files too
+ (serpent_test): Moved prototype out of a fucntion.
+
+2005-02-07 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Major parts rewritten.
+ * pubkey.c (_gcry_pk_get_elements): New function.
+
+2004-12-09 Werner Koch <wk@g10code.com>
+
+ * serpent.c (serpent_setkey): Moved prototype of serpent_test to
+ outer scope.
+
+2004-09-11 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (pubkey_table): Added an alias entry for GCRY_PK_ELG_E.
+
+2004-08-23 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Do not include <assert.h>.
+ * rndegd.c: Likewise.
+ * sha1.c: Likewise.
+ * rndunix.c: Likewise.
+ * rndlinux.c: Likewise.
+ * rmd160.c: Likewise.
+ * md5.c: Likewise.
+ * md4.c: Likewise.
+ * cipher.c: Likewise.
+ * crc.c: Likewise.
+ * blowfish.c: Likewise.
+
+ * pubkey.c (dummy_generate, dummy_check_secret_key)
+ (dummy_encrypt, dummy_decrypt, dummy_sign, dummy_verify): Return
+ err code GPG_ERR_NOT_IMPLEMENTED instead of aborting through
+ log_bug().
+ (dummy_get_nbits): Return 0 instead of aborting though log_bug().
+
+2004-08-19 Werner Koch <wk@g10code.de>
+
+ * pubkey.c (sexp_data_to_mpi): Changed the zero random byte
+ substituting code to actually do clever things. Thanks to
+ Matthias Urlichs for noting the implementation problem.
+
+2004-08-09 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_sign): Fixed memory leak; fix provided by
+ Modestas Vainius.
+
+2004-07-16 Werner Koch <wk@gnupg.org>
+
+ * rijndael.c (do_encrypt): Fix alignment problem. Bugs found by
+ Matthias Urlichs.
+ (do_decrypt): Ditto.
+ (keySched, keySched2): Use 2 macros along with unions in the key
+ schedule context.
+
+2004-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_decrypt): Don't forget to free "a". Thanks to
+ Nikos Mavroyanopoulos.
+
+2004-05-09 Werner Koch <wk@gnupg.org>
+
+ * random.c (read_pool): Mix the PID in to better protect after a
+ fork.
+
+2004-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * serpent.c: Use "u32_t" instead of "unsigned long", do not
+ declare S-Box variables as "register". Fixes failure on
+ OpenBSD/sparc64, reported by Nikolay Sturm.
+
+2004-05-07 Werner Koch <wk@gnupg.org>
+
+ * random.c (initialize): Factored out some code to ..
+ (initialize_basics): .. new function.
+ (_gcry_random_initialize): Just call initialize_basics unless the
+ new arg FULL is set to TRUE.
+ (_gcry_fast_random_poll): Don't do anything unless the random
+ system has been really initialized.
+
+2004-05-07 Moritz Schulte <moritz@g10code.de>
+
+ * ac.c (gcry_ac_open): Do not dereference NULL pointer. Reported
+ by Umberto Salsi.
+
+2004-02-20 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (check_prime): New args CB_FUNC and CB_ARG; call them
+ at different stages. Pass these arguments through all callers.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * des.c: Add a new OID as used by pkcs#12.
+
+ * rfc2268.c: New. Taken from libgcrypt.
+ * cipher.c: Setup the rfc2268 algorithm.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * primegen.c (prime_generate_internal): Do not forget to free
+ `q_factor'; fixed by Brieuc Jeunhomme.
+ (prime_generate_internal): Do not forget to free `prime'.
+
+2004-01-14 Moritz Schulte <mo@g10code.com>
+
+ * ac.c (gcry_ac_data_set): New argument: flags; slightly
+ rewritten.
+ (gcry_ac_data_get_name, gcry_ac_data_get_index): Likewise.
+ (gcry_ac_key_pair_generate): New argument: misc_data; modified
+ order of arguments.
+ (gcry_ac_key_test): New argument: handle.
+ (gcry_ac_key_get_nbits, gcry_ac_key_get_grip): Likewise.
+ Use GCRY_AC_FLAG_NO_BLINDING instead of
+ GCRY_AC_DATA_FLAG_NO_BLINDING.
+ (gcry_ac_mpi): New member: flags.
+ (gcry_ac_data_search, gcry_ac_data_add): Removed functions.
+
+2003-12-22 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (is_prime): Release A2.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * md.c: Moved a couple of functions down below the data structure
+ definitions.
+ (struct gcry_md_context): New field ACTUAL_HANDLE_SIZE.
+ (md_open): Set it here.
+ (strcut gcry_md_list): New field ACTUAL_STRUCT_SIZE.
+ (md_enable): Set it here.
+ (md_close): Wipe the context memory.
+ secure memory.
+ * cipher.c (struct gcry_cipher_handle): New field ACTUAL_HANDLE_SIZE.
+ (gcry_cipher_open): Set it here.
+ (gcry_cipher_close): Use it to always wipe out the handle data.
+
+ * ac.c (gcry_ac_open): Make sure HANDLE gets initialized even when
+ the function is not successful.
+ (gcry_ac_close): Allow a NULL handle.
+ (gcry_ac_key_destroy, gcry_ac_key_pair_destroy): Ditto.
+ (gcry_ac_key_get_grip): Return INV_OBJ on error.
+
+ * primegen.c (prime_generate_internal): Fixed error code for
+ failed malloc. Replaced the !err if chain by gotos.
+ (gcry_prime_group_generator): Remove the extra sanity check.
+
+ * md.c: Minor code and comment cleanups.
+
+2003-12-16 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Doc fix. Thanks to Newton Hammet.
+
+2003-12-11 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (slow_poll): Don't use #warning but #error.
+
+ * rndegd.c: Changed indentation.
+ (my_make_filename): Removd the var_arg cruft becuase we
+ don't need it here. Changed caller.
+
+ * rndlinux.c: Changed indentation.
+ (open_device): Remove the superfluous stat call and clarify
+ comment.
+
+ * rsa.c: Changed indentation.
+ (secret): Use the standard algorithm if p, q and u are not
+ available.
+ (rsa_blind, rsa_unblind): Renamed from _gcry_rsa_blind,
+ _gcry_rsa_unblind and moved more to the top.
+
+ * md4.c: Changed indentation. Removed unnecessary casts.
+ * md5.c, rmd160.c, sha1.c, tiger.c: Ditto.
+ * rijndael.c, twofish.c: Ditto.
+ * serpent.c: Removed unnecessary casts.
+ * sha256.c, sha512.c: Ditto.
+
+2003-12-09 Werner Koch <wk@gnupg.org>
+
+ * dsa.c: Unified indentation style.
+ * elgamal.c: Ditto.
+ * des.c (des_key_schedule): Code beautifications.
+ * blowfish.c: Changed indentation style.
+ * cast5.c (do_cast_setkey): Ditto.
+
+ * pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests
+ by straightforward gotos. Other cleanups.
+ (gcry_pk_decrypt): Ditto.
+ (gcry_pk_sign): Ditto.
+ (gcry_pk_verify): Ditto.
+ (gcry_pk_genkey): Ditto. Use strtoul instead of strtol.
+ (gcry_pk_ctl): Use GPG_ERR_INV_ARG to indicate bad arguments.
+
+2003-12-07 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_register_default): Undef the helper macro.
+ (gcry_pk_map_name): Allow NULL for string.
+ (sexp_to_key): Use memcpy and not strncpy. Use gcry_free and not
+ free.
+ (sexp_to_sig): Ditto.
+ (sexp_to_enc): Ditto. Replaced the chain of if(!err) tests by
+ straightforward gotos.
+
+2003-12-05 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Documentation cleanups.
+ (gcry_cipher_mode_from_oid): Allow NULL for STRING.
+
+2003-12-03 Werner Koch <wk@gnupg.org>
+
+ * elgamal.c (sign, do_encrypt, gen_k): Make sure that a small K is
+ only used for encryption.
+
+2003-11-18 Werner Koch <wk@gnupg.org>
+
+ * random.h (rndw32_set_dll_name): Removed unused prototype.
+
+ * Makefile.am (EXTRA_DIST): Added Manifest.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * Manifest: New.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Use shortcut for SHA1
+ * sha1.c (_gcry_sha1_hash_buffer): New.
+
+ * random.c: Reformatted most functions.
+ (mix_pool): Moved the failsafe_digest from global
+ scope to here.
+ (do_fast_random_poll): Use the generic fucntions even if a fast
+ gathering function has been used.
+ (read_pool): Detect a fork and retry.
+ (gcry_randomize, get_random_bytes): Don't distinguish anymore
+ between weak and strong random.
+ (gcry_create_nonce): New.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * rndw32.c (slow_gatherer_windowsNT): Use a plain buffer for the
+ disk performance values and not the W32 API structure.
+
+ * dsa.c (verify): s/exp/ex/ due to shadowing of a builtin.
+ * elgamal.c (verify): Ditto.
+
+ * ac.c (gcry_ac_data_get_index): s/index/idx/
+ (gcry_ac_data_copy_internal): Remove the cast in _gcry_malloc.
+ (gcry_ac_data_add): Must use gcry_realloc instead of realloc.
+ * pubkey.c (sexp_elements_extract): s/index/idx/ as tribute to the
+ forehackers.
+ (gcry_pk_encrypt): Removed shadowed definition of I. Reordered
+ arguments to malloc for clarity.
+ (gcry_pk_sign, gcry_pk_genkey): Ditto.
+ * primegen.c (prime_generate_internal): s/random/randomlevel/.
+
+2003-10-27 Moritz Schulte <mo@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Don't forget to deallocate pkey.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_add_bytes): Return if buflen is zero to
+ avoid gcc warning about unsed parameter.
+ (MASK_LEVEL): Simplified; does now work for signed and unsigned
+ w/o warnings.
+
+ * md.c (md_start_debug): Removed the const from SUFFIX, because
+ this function is called from the control fucntion which does not
+ require const.
+
+ Prefixed all (pubkey,digest,cipher}_spec_* globale variables with
+ _gcry_.
+
+ * ac.c (ac_key_identifiers): Made static.
+
+ * random.c (getfnc_gather_random,getfnc_fast_random_poll): Move
+ prototypes to ..
+ * rand-internal.h: .. here
+ * random.c (getfnc_gather_random): Include rndw32 gatherer.
+ * rndunix.c, rndw32.c, rndegd.c: Include them here.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Prepend the _gcry_
+ prefix. Changed all callers.
+ * rndegd.c (_gcry_rndegd_gather_random): Likewise.
+ (_gcry_rndegd_connect_socket): Likewise.
+ * rndunix.c (_gcry_rndunix_gather_random): Likewise.
+ (waitpid): Made static.
+ * rndw32.c: Removed the old and unused winseed.dll cruft.
+ (_gcry_rndw32_gather_random_fast): Renamed from
+ gather_random_fast.
+ (_gcry_rndw32_gather_random): Renamed from gather_random. Note,
+ that the changes 2003-04-08 somehow got lost.
+
+ * sha512.c (sha512_init, sha384_init): Made static.
+
+ * cipher.c (do_ctr_decrypt): Removed "return" from this void
+ function.
+
+2003-10-24 Moritz Schulte <mo@g10code.com>
+
+ * serpent.c: Fix an issue on big-endian systems.
+
+ * rndw32.c: Removed IS_MODULE -cruft.
+ * rndlinux.c (rndlinux_gather_random): Likewise.
+
+2003-10-10 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Bail out if NBITS is less than 16.
+ (prime_generate_internal): Initialize prime variable to suppress
+ compiler warning. Check pbits, initialize qbits when passed as
+ zero.
+
+ * primegen.c (prime_generate_internal): New arg
+ ALL_FACTORS. Changed all callers.
+ (gcry_prime_generate): Make the factors arg optional. Request
+ all_factors. Make sure PRIME is set to NULL even on error.
+ (gcry_prime_group_generator): New.
+ (gcry_prime_release_factors): New.
+
+2003-10-06 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Assert that NBITS is never zero, it
+ would cause a segv.
+
+2003-09-28 Moritz Schulte <mo@g10code.com>
+
+ * ac.c: Include "cipher.h".
+
+2003-09-27 Moritz Schulte <mo@g10code.com>
+
+ * rndegd.c (do_read): Return nread instead of nbytes; thanks to
+ Michael Caerwyn.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (_gcry_pk_aliased_algo_name): New.
+ * ac.c (gcry_ac_open): Use it here.
+
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Add serpent.c
+
+2003-09-02 Moritz Schulte <mo@g10code.com>
+
+ * primegen.c (gcry_prime_check, gcry_prime_generate): New
+ functions.
+ (prime_generate_internal): New function, based on
+ _gcry_generate_elg_prime.
+ (_gcry_generate_elg_prime): Rewritten as a wrapper for
+ prime_generate_internal.
+
+2003-08-28 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_encrypt): Don't include the flags list in the
+ return value. This does not make sense and breaks any programs
+ parsing the output strictly (e.g. current gpgsm).
+ (gcry_pk_encrypt): If aliases for the algorithm name exists, take
+ the first one instead of the regular name to adhere to SPKI
+ conventions.
+ (gcry_pk_genkey): Ditto.
+ (gcry_pk_sign): Ditto. Removed unused KEY_ALGO_NAME.
+
+2003-08-19 Moritz Schulte <mo@g10code.com>
+
+ * cipher.c: Add support for Serpent
+ * serpent.c: New file.
+
+2003-08-10 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_blind, _gcry_rsa_unblind): Declare static.
+
+2003-08-09 Timo Schulz <twoaday@freakmail.de>
+
+ * random.c (getfnc_gather_random): Don't check NAME_OF_DEV_RANDOM
+ two times, but also the NAME_OF_DEV_URANDOM device.
+
+2003-08-08 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_enc): Fixed extraction of S-Expression: do not
+ fail if no `flags' sub S-Expression is found.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_lookup_func_oid): Allow for empty OID lists.
+
+2003-07-23 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_construct): New argument: include_flags, only
+ include `flags' S-expression, if include_flags is true. Adjust
+ callers. Thanks for triggering a bug caused by `flags'
+ sub-S-expression where they are not expected to Ralf Schneider.
+
+2003-07-21 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_lookup_func_name): Use new member name
+ `aliases' instead of `sexp_names'.
+
+ * ac.c (gcry_ac_key_data_get): New function.
+
+ * cipher.c (gcry_cipher_lookup_func_name): Fix return value.
+
+2003-07-20 Moritz Schulte <moritz@g10code.com>
+
+ * blowfish.c: Adjusted for new gcry_cipher_spec_t structure.
+ * cast5.c: Likewise.
+ * twofish.c: Likewise.
+ * arcfour.c: Likewise.
+ * rijndael.c (rijndael_oids, rijndael192_oids, rijndael256_oids):
+ New variables, adjust for new gcry_cipher_spec_t structure.
+ * des.c (oids_tripledes): New variable, adjust for new
+ gcry_cipher_spec_t structure.
+
+ * md.c (oid_table): Removed.
+
+ * tiger.c (oid_spec_tiger): New variable.
+ (digest_spec_tiger): Adjusted for new gry_md_spec_t structure.
+
+ * sha512.c (oid_spec_sha512): New variable.
+ (digest_spec_sha512): Adjusted for new gry_md_spec_t structure.
+
+ * sha512.c (oid_spec_sha384): New variable.
+ (digest_spec_sha384): Adjusted for new gry_md_spec_t structure.
+
+ * sha256.c (oid_spec_sha256): New variable.
+ (digest_spec_sha256): Adjusted for new gry_md_spec_t structure.
+
+ * sha1.c (oid_spec_sha1): New variable.
+ (digest_spec_sha1): Adjusted for new gry_md_spec_t structure.
+
+ * rmd160.c (oid_spec_rmd160): New variable.
+ (digest_spec_rnd160): Adjusted for new gry_md_spec_t structure.
+
+ * md5.c (oid_spec_md5): New variable.
+ (digest_spec_md5): Adjusted for new gry_md_spec_t structure.
+
+ * md4.c (oid_spec_md4): New variable.
+ (digest_spec_md4): Adjusted for new gry_md_spec_t structure.
+
+ * crc.c (digest_spec_crc32, digest_spec_crc32_rfc1510,
+ digest_spec_crc32_rfc2440): Adjusted for new gry_md_spec_t
+ structure.
+
+2003-07-19 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (gcry_md_lookup_func_oid): New function.
+ (search_oid): New function, copied from cipher.c.
+ (gcry_md_map_name): Adjust for new search_oid_interface.
+
+ * cipher.c (oid_table): Removed table.
+ (gcry_cipher_lookup_func_oid): New function.
+ (search_oid): Rewritten to use the module functions.
+ (gcry_cipher_map_name): Adjust for new search_oid interface.
+ (gcry_cipher_mode_from_oid): Likewise.
+
+2003-07-18 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Convert ERR to gpg_error_t in
+ gpg_strerror.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_lookup_func_name): Also check the cipher
+ name aliases, not just the primary name.
+ (gcry_cipher_map_name): Remove kludge for aliasing Rijndael to
+ AES.
+
+ * arcfour.c, blowfish.c, cast5.c, des.c, twofish.c: Adjust cipher
+ specification structures.
+
+ * rijndael.c (rijndael_names, rijndael192_names,
+ rijndael256_names): New variables, use them in the cipher
+ specifications.
+
+ * rmd160test.c: Removed file.
+
+ * ac.c, arcfour.c, blowfish.c, cast5.c, cipher.c, des.c, dsa.c,
+ elgamal.c, md.c, pubkey.c, random.c, rijndael.c, rsa.c, twofish.c:
+ Used gcry_err* wrappers for libgpg symbols.
+
+ * primegen.c (gen_prime): Correct the order arguments to
+ extra_check.
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Replaced all public occurences of gpg_error_t with
+ gcry_error_t.
+ * cipher.c: Likewise.
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+ * random.c: Likewise.
+
+ * cipher.c: Added support for TWOFISH128.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_copy_internal): New function, based on
+ gcry_ac_data_copy.
+ (gcry_ac_data_copy): Made public, use gcry_ac_data_copy_internal.
+ (gcry_ac_key_init): Use gcry_ac_data_copy_internal.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_set): Only release old MPI value if it is
+ different from the new value. Bug reported by Simon Josefsson
+ <jas@extundo.com>.
+
+ * pubkey.c (gcry_pk_list): New function.
+ * md.c (gcry_md_list): New function.
+
+ * ac.c (gcry_ac_key_pair_generate): Fix calculation of format
+ string size.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * md.c: Named struct of digest_table `digest_table_entry'.
+ (digest_table_entry): New member: algorithm; filled in.
+ (digest_table_entry): Removed unused member: flags.
+ (gcry_md_register): New argument: algorithm_id, filled in.
+ (gcry_md_register_default): Used algorithm ID from module
+ structure.
+ (gcry_md_map_name): Likewise.
+ (md_enable): Likewise.
+ (md_read): Likewise.
+ (gcry_md_info): Likewise.
+
+ * pubkey.c: Named truct for pubkey_table `pubkey_table_entry'.
+ (pubkey_table_entry): New member: algorithm; filled in.
+ (gcry_pk_register_default): Used algorithm ID from pubkey_table.
+ (gcry_pk_register): New argument: algorithm_id, filled in.
+ (gcry_pk_map_name): Used algorithm ID from module structure.
+ (gcry_pk_decrypt): Likewise.
+ (gcry_pk_encrypt): Likewise.
+ (gcry_pk_verify): Likewise.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_testkey): Likewise.
+ (gcry_pk_genkey): Likewise.
+ (gcry_pk_get_nbits): Likewise.
+ (sexp_to_key): Removed unused variable: algo.
+ (sexp_to_sig): Likewise.
+
+ * cipher.c: Named struct for cipher_table `cipher_table_entry'.
+ (cipher_table_entry): New member: algorithm; filled in.
+ (gcry_cipher_register_default): Used algorithm ID from
+ cipher_table.
+ (gcry_cipher_register): New argument: algorithm_id, filled in.
+ (gcry_cipher_map_name): Used algorithm ID from module structure.
+
+ * arcfour.c (cipher_spec_arcfour): Removed algorithm ID.
+ * blowfish.c (cipher_spec_blowfish): Likewise.
+ * cast5.c (cipher_spec_cast5): Likewise.
+ * crc.c (digest_spec_crc32): Likewise.
+ * crc.c (digest_spec_crc32_rfc1510): Likewise.
+ * crc.c (digest_spec_crc32_rfc2440): Likewise.
+ * des.c (cipher_spec_des): Likewise.
+ * des.c (cipher_spec_tripledes): Likewise.
+ * dsa.c (pubkey_spec_dsa): Likewise.
+ * elgamal.c (pubkey_spec_elg): Likewise.
+ * md4.c (digest_spec_md4): Likewise.
+ * md5.c (digest_spec_md5): Likewise.
+ * aes.c (cipher_spec_aes): Likewise.
+ * aes.c (cipher_spec_aes192): Likewise.
+ * aes.c (cipher_spec_aes256): Likewise.
+ * rsa.c (pubkey_spec_rsa): Likewise.
+ * sha1.c (digest_spec_sha1): Likewise.
+ * sha256.c (digest_spec_sha256): Likewise.
+ * sha512.c (digest_spec_sha512): Likewise.
+ * tiger.c (digest_spec_tiger): Likewise.
+ * twofish.c (cipher_spec_twofish): Likewise.
+ * twofish.c (cipher_spec_twofish128): Likewise.
+
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Fix list of source
+ files; reported by Simon Josefsson <jas@extundo.com>.
+
+ * pubkey.c: Replaced all occurences of `id' with `algorithm',
+ since `id' is a keyword in obj-c.
+ * md.c: Likewise.
+ * cipher.c: Likewise.
+
+ * crc.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, tiger.c:
+ Replaced all occurences of gcry_digest_spec_t with gcry_md_spec_t.
+
+ * dsa.c, rsa.c, elgamal.c: Replaced all occurencens of
+ gcry_pubkey_spec_t with gcry_pk_spec_t.
+
+ * md.c: Replaced all occurences of gcry_digest_spec_t with
+ gcry_md_spec_t.
+ (gcry_digest_register_default): Renamed to ...
+ (gcry_md_register_default): ... this; adjusted callers.
+ (gcry_digest_lookup_func_name): Renamed to ...
+ (gcry_md_lookup_func_name): ... this; adjusted callers.
+ (gcry_digest_lookup_name): Renamed to ...
+ (gcry_md_lookup_name): ... this; adjusted callers.
+ (gcry_digest_register): Renamed to ...
+ (gcry_md_register): ... this.
+ (gcry_digest_unregister): Renamed to ...
+ (gcry_md_unregister): ... this.
+
+ * pubkey.c (gcry_pubkey_register): Renamed to ...
+ (gcry_pk_register): ... this.
+ (gcry_pubkey_unregister): Renamed to ...
+ (gcry_pk_unregister): ... this.
+ Replaced all occurences of gcry_pubkey_spec_t with gcry_pk_spec_t.
+ (gcry_pubkey_register_default): Renamed to ...
+ (gcry_pk_register_default): ... this; adjusted callers.
+ (gcry_pubkey_lookup_func_name): Renamed to ...
+ (gcry_pk_lookup_func_name): ... this; adjusted callers.
+ (gcry_pubkey_lookup_name): Renamed to ...
+ (gcry_pk_lookup_name): ... this; adjusted callers.
+
+ * md.c (gcry_md_hash_buffer): Fix error checking. Thanks to Simon
+ Josefsson <jas@extunde.com>.
+
+2003-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_list): New function.
+
+2003-07-01 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_sig): Accept a `flags' S-expression to be more
+ consistent with sexp_to_enc.
+
+2003-06-30 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libcipher_la_SOURCES): Added: ac.c.
+
+ * pubkey.c (_gcry_pk_module_lookup): New function.
+ (_gcry_pk_module_release): New function.
+
+2003-06-29 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: New file.
+
+2003-06-26 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Trigger BUG correcly with new API.
+
+2003-06-19 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_is_enabled): Fixed.
+
+2003-06-18 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_get_algo_keylen): New.
+ (gcry_cipher_get_algo_blklen): New.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * arcfour.c, cipher.c, blowfish.c, md.c, cast5.c, pubkey.c, crc.c,
+ des.c, dsa.c, elgamal.c, md4.c, md5.c, random.c, rijndael.c,
+ rmd160.c, rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c:
+ Replaced older types GcryDigestSpec, GcryCipherSpec and
+ GcryPubkeySpec with newer types: gcry_digest_spec_t,
+ gcry_cipher_spec_t and gcry_pubkey_spec_t.
+
+ * md.c (gcry_digest_id_new): Removed function.
+ (gcry_digest_register): Removed code for generating a new module
+ ID.
+
+ * pubkey.c (gcry_pubkey_id_new): Removed function.
+ (gcry_pubkey_register): Removed code for generating a new module
+ ID.
+
+ * cipher.c, md.c, pubkey.c: Replace old type GcryModule with newer
+ one: gcry_module_t.
+ (gcry_cipher_id_new): Removed function.
+ (gcry_cipher_register): Removed code for generating a new module
+ ID.
+
+ * cipher.c (gcry_cipher_register): Adjust call to
+ _gcry_module_add.
+ (gcry_cipher_register_default): Likewise.
+ * pubkey.c (gcry_pubkey_register_default): Likewise.
+ (gcry_pubkey_register): Likewise.
+ * md.c (gcry_digest_register_default): Likewise.
+ (gcry_digest_register): Likewise.
+
+ * md.c (gcry_digest_lookup_func_id): Removed function.
+ (gcry_digest_lookup_id): Likewise.
+ (gcry_digest_id_new): Use _gcry_module_lookup_id instead of
+ gcry_digest_lookup_id.
+ (digest_algo_to_string): Likewise.
+ (check_digest_algo): Likewise.
+ (md_enable): Likewise.
+ (md_digest_length): Likewise.
+ (md_asn_oid): Likewise.
+
+ * pubkey.c (gcry_pubkey_lookup_id): Removed function.
+ (gcry_pubkey_lookup_func_id): Likewise.
+ (gcry_pubkey_id_new): Use _gcry_module_lookup_id instead of
+ gcry_pubkey_id_new.
+ (gcry_pk_algo_name): Likewise.
+ (disable_pubkey_algo): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_get_npkey): Likewise.
+ (pubkey_get_nskey): Likewise.
+ (pubkey_get_nsig): Likewise.
+ (pubkey_get_nenc): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (gcry_pk_algo_info): Likewise.
+
+ * cipher.c (gcry_cipher_lookup_func_id): Removed function.
+ (gcry_cipher_lookup_id): Likewise.
+ (cipher_algo_to_string): use _gcry_module_lookup_id instead of
+ gcry_cipher_lookup_id.
+ (disable_cipher_algo): Likewise.
+ (check_cipher_algo): Likewise.
+ (cipher_get_blocksize): Likewise.
+ (gcry_cipher_open): Likewise.
+ (gcry_cipher_id_new): Likewise.
+
+2003-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (GCRYPT_MODULES): Set to @GCRYPT_CIPHERS@,
+ @GCRYPT_PUBKEY_CIPHERS@, @GCRYPT_DIGESTS@ and @GCRYPT_RANDOM@.
+ (libcipher_la_DEPENDENCIES): Set to $(GCRYPT_MODULES).
+ (libcipher_la_LIBADD): Likewise.
+ (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+ (EXTRA_libcipher_la_SOURCES): Added all conditional sources.
+
+ * md.c (md_open): Use _gcry_fast_random_poll instead of
+ fast_random_poll.
+ * cipher.c (gcry_cipher_open): Likewise.
+
+ * random.h (fast_random_poll): Removed macro.
+
+ * blowfish.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, sha512.c,
+ tiger.c: Use Autoconf's WORDS_BIGENDIAN instead of our own
+ BIG_ENDIAN_HOST.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * random.c (getfnc_gather_random): Do not special-case
+ USE_ALL_RANDOM_MODULES, make it the default.
+
+ * dsa.c: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * elgamal.c: Likewise.
+ * primegen.c: Likewise.
+ * pubkey.c: Likewise.
+ * rsa.c: Likewise.
+
+2003-06-14 Moritz Schulte <moritz@g10code.com>
+
+ * des.c (des_setkey): Add selftest check.
+ (tripledes_set3keys): Likewise.
+ (do_tripledes_setkey): Remove selftest check.
+ (do_des_setkey): Likewise.
+
+2003-06-11 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (_gcry_md_init): New function.
+ * cipher.c (_gcry_cipher_init): New function.
+ * pubkey.c (_gcry_pk_init): New function.
+
+2003-06-13 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_get_algo): Reverted to old API. This is a
+ convenience function anyway and error checking is not approriate.
+ (gcry_md_is_secure): New.
+ (gcry_md_is_enabled): New.
+
+2003-06-12 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_open): Make sure HANDLE is set to NULL on
+ error.
+
+2003-06-11 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_open): Make sure H receives either NULL or an
+ valid handle.
+ (gcry_md_copy): Swapped arguments so that it is more in lione with
+ md_open and most other API fucntions like memcpy (destination
+ comes first). Make sure HANDLE is set to NULL on error.
+
+ * rijndael.c (do_encrypt): Hack to force correct alignment. It
+ seems not to be not sufficient, though. We should rework this
+ fucntions and remove all these ugly casts. Let the compiler
+ optimize or have an assembler implementation.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Removed rules serpent, since that is not commited
+ yet.
+
+2003-06-08 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Improve calculation for size of the
+ format string.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * arcfour.c, bithelp.h, blowfish.c, cast5.c, cipher.c, crc.c,
+ des.c, dsa.c, elgamal.c, md4.c, md5.c, md.c, primegen.c, pubkey.c,
+ rand-internal.h, random.c, random.h, rijndael.c, rmd160.c,
+ rmd160test.c, rmd.h, rndeged.c, rndlinux.c, rndunix.c, rndw32.c,
+ rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c: Edited all
+ preprocessor instructions to remove whitespace before the '#'.
+ This is not required by C89, but there are some compilers out
+ there that don't like it. Replaced any occurence of the now
+ deprecated type names with the new ones.
+
+2003-06-04 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Construct an arg_list and use
+ gcry_sexp_build_array instead of gcry_sexp_build.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_genkey): Likewise.
+
+2003-06-01 Moritz Schulte <moritz@g10code.com>
+
+ * dsa.c (_gcry_dsa_generate): Do not check wether the algorithm ID
+ does indeed belong to DSA.
+ (_gcry_dsa_sign): Likewise.
+ (_gcry_dsa_verify): Likewise.
+ (_gcry_dsa_get_nbits): Likewise.
+
+ * elgamal.c (_gcry_elg_check_secret_key): Do not check wether the
+ algorithm ID does indeed belong to ElGamal.
+ (_gcry_elg_encrypt): Likewise.
+ (_gcry_elg_decrypt): Likewise.
+ (_gcry_elg_sign): Likewise.
+ (_gcry_elg_verify): Likewise.
+ (_gcry_elg_get_nbits): Likewise.
+ (_gcry_elg_generate): Likewise.
+
+ * rsa.c (_gcry_rsa_generate): Do not check wether the algorithm ID
+ does indeed belong to RSA.
+ (_gcry_rsa_encrypt): Likewise.
+ (_gcry_rsa_decrypt): Likewise.
+ (_gcry_rsa_sign): Likewise.
+ (_gcry_rsa_verify): Likewise.
+ (_gcry_rsa_get_nbits): Likewise.
+
+2003-05-30 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_get_algo): Return zero in case to algorithm is enabled.
+
+ * md.c (gcry_md_info): Adjusted for new no-errno-API.
+ (md_final): Likewise.
+ (gcry_md_get_algo): Likewise.
+ * pubkey.c (gcry_pk_get_keygrip): Likewise.
+ (gcry_pk_ctl): Likewise.
+ (gcry_pk_algo_info): Likewise.
+ * des.c (selftest): Likewise.
+
+2003-05-29 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_enable): Do not forget to release module on error.
+ (gcry_md_open): Adjusted for new no-errno-API.
+ (md_open): Likewise.
+ (md_copy): Likewise.
+ (gcry_md_copy): Likewise.
+ (gcry_md_setkey): Likewise.
+ (gcry_md_algo_info): Likewise.
+
+ * cipher.c (gcry_cipher_open): Adjusted for new no-errno-API and
+ also fixed a locking bug.
+ (gcry_cipher_encrypt): Adjusted for new no-errno-API.
+ (gcry_cipher_decrypt): Likewise.
+ (gcry_cipher_ctl): Likewise.
+ (gcry_cipher_info): Likewise.
+ (gcry_cipher_algo_info): Likewise.
+
+2003-05-28 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_enable): Adjusted for libgpg-error.
+ (gcry_md_enable): Likewise.
+ (gcry_digest_register_default): Likewise.
+ (gcry_digest_register): Likewise.
+ (check_digest_algo): Likewise.
+ (prepare_macpads): Likewise.
+ (gcry_md_setkey): Likewise.
+ (gcry_md_ctl): Likewise.
+ (gcry_md_get): Likewise.
+ (gcry_md_algo_info): Likewise.
+ (gcry_md_info): Likewise.
+ * dsa.c (_gcry_dsa_generate): Likewise.
+ (_gcry_dsa_check_secret_key): Likewise.
+ (_gcry_dsa_sign): Likewie.
+ (_gcry_dsa_verify): Likewise.
+ * twofish.c (do_twofish_setkey): Likewise.
+ (twofish_setkey): Likewise.
+ * cipher.c (gcry_cipher_register): Likewise.
+
+2003-05-25 Moritz Schulte <moritz@g10code.com>
+
+ * rijndael.c (do_setkey): Adjusted for libgpg-error.
+ (rijndael_setkey): Likewise.
+ * random.c (gcry_random_add_bytes): Likewise.
+ * elgamal.c (_gcry_elg_generate): Likewise.
+ (_gcry_elg_check_secret_key): Likewise.
+ (_gcry_elg_encrypt): Likewise.
+ (_gcry_elg_decrypt): Likewise.
+ (_gcry_elg_sign): Likewise.
+ (_gcry_elg_verify): Likewise.
+ * rsa.c (_gcry_rsa_generate): Likewise.
+ (_gcry_rsa_check_secret_key): Likewise.
+ (_gcry_rsa_encrypt): Likewise.
+ (_gcry_rsa_decrypt): Likewise.
+ (_gcry_rsa_sign): Likewise.
+ (_gcry_rsa_verify): Likewise.
+ * pubkey.c (dummy_generate, dummy_check_secret_key, dummy_encrypt,
+ dummy_decrypt, dummy_sign, dummy_verify): Likewise.
+ (gcry_pubkey_register): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (sexp_elements_extract): Likewise.
+ (sexp_to_key): Likewise.
+ (sexp_to_sig): Likewise.
+ (sexp_to_enc): Likewise.
+ (sexp_data_to_mpi): Likewise.
+ (gcry_pk_encrypt): Likewise.
+ (gcry_pk_decrypt): Likewise.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_verify): Likewise.
+ (gcry_pk_testkey): Likewise.
+ (gcry_pk_genkey): Likewise.
+ (gcry_pk_ctl): Likewise.
+ * cipher.c (dummy_setkey): Likewise.
+ (check_cipher_algo): Likewise.
+ (gcry_cipher_open): Likewise.
+ (cipher_setkey): Likewise.
+ (gcry_cipher_ctl): Likewise.
+ (cipher_encrypt): Likewise.
+ (gcry_cipher_encrypt): Likewise.
+ (cipher_decrypt): Likewise.
+ (gcry_cipher_decrypt): Likewise.
+ (gcry_cipher_info): Likewise.
+ (gcry_cipher_algo_info): Likewise.
+ * cast5.c (cast_setkey): Likewise.
+ (do_cast_setkey): Likewise.
+ * arcfour.c (arcfour_setkey): Likewise.
+ (do_arcfour_setkey): Likewise.
+ * blowfish.c (do_bf_setkey): Likewise.
+ (bf_setkey): Likewise.
+ * des.c (do_des_setkey): Likewise.
+ (do_tripledes_setkey): Likewise.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * tiger.c: Merged code ussing the U64_C macro from GnuPG.
+
+ * sha512.c: Likewise.
+
+2003-05-17 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Fix type: acquire a lock, instead of
+ releasing it.
+
+2003-05-11 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_testkey): Call REGISTER_DEFAULT_CIPHERS.
+ (gcry_pk_ctl): Likewise.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Release sexp after extracted data has
+ been used.
+
+ * md.c (gcry_md_get_algo_dlen): Simplified, simply call
+ md_digest_length to do the job.
+
+ * des.c (do_des_setkey): Check for selftest failure not only
+ during initialization.
+ (do_tripledes_setkey): Include check for selftest failure.
+
+ * pubkey.c (gcry_pubkey_register_default): New macro
+ `pubkey_use_dummy', use it.
+
+ * elgamal.c (elg_names): New variable.
+ (pubkey_spec_elg): Include elg_names.
+
+ * dsa.c (dsa_names): New variable.
+ (pubkey_spec_dsa): Include dsa_names.
+
+ * rsa.c (rsa_names): New variable.
+ (pubkey_spec_rsa): Include rsa_names.
+
+ * pubkey.c (gcry_pubkey_lookup_func_name): Compare name also with
+ the names listed in `sexp_names'.
+
+2003-04-24 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_key): New variables: module, pubkey. Adjusted
+ to new module interface.
+ (sexp_to_key): Changend type of argument `retalgo' from `int *' to
+ `GcryModule **'. Adjusted all callers. Removed argument:
+ r_algotblidx.
+ (sexp_to_sig): Changend type of argument `retalgo' from `int *' to
+ `GcryModule **'. Adjusted all callers.
+ (sexp_to_enc): Likewise.
+
+ (pubkey_get_npkey, pubkey_get_nskey, pubkey_get_nsig,
+ pubkey_get_nenc): Use strlen to find out the number.
+
+ * rsa.c: Adjust pubkey_spec_rsa to new internal interface.
+ * dsa.c: Likewise.
+ * elgamal.c: Likewise.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_elements_extract): New function.
+ * pubkey.c (sexp_to_key): Removed variable `idx', added `err', use
+ sexp_elements_extract.
+ (sexp_to_sig): Likewise.
+ (sexp_to_enc): Likewise.
+
+ * pubkey.c: Terminate list correctly.
+ * md.c: Include sha512/sha384 in digest_table.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Include support for sha512.c.
+
+ * sha512.c: New file, merged from GnuPG, with few modifications
+ for libgcrypt.
+
+ * rand-internal.h: Removed declarations for constructor functions.
+
+ * md.c (md_copy): Call _gcry_module_use for incrementing the usage
+ counter of the digest modules.
+
+ * rsa.c: Do not include "rsa.h".
+ * dsa.c: Do not include "dsa.h".
+ * elgamal.c: Do not include "elgamal.h".
+ * des.c: Do not include "des.h".
+ * cast5.c: Do not include "cast5.h".
+ * blowfish.c: Do not include "blowfish.h".
+ * arcfour.c: Do not include "arcfour.h".
+
+ * Makefile.am (libcipher_la_DEPENDENCIES): Removed.
+ (libcipher_la_LIBADD): Removed.
+ Use Automake conditionals for conditional compilation.
+
+2003-04-13 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Call REGISTER_DEFAULT_CIPHERS.
+
+ * md.c (gcry_md_list): New member: module.
+ (md_enable): New variable: module, changed use of module and
+ digest.
+ (md_enable): Initialize member: module.
+ (md_close): Call _gcry_module_release.
+
+ * cipher.c (gcry_cipher_open): New variable: module, changed use of
+ module and cipher.
+ (struct gcry_cipher_handle): New member: module.
+ (gcry_cipher_open): Initialize member: module.
+ (gcry_cipher_close): Call _gcry_module_release.
+
+2003-04-09 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c: Include "ath.h".
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+
+ * cipher.c (ciphers_registered_lock): New variable.
+ * md.c (digests_registered_lock): New variable.
+ * pubkey.c (pubkeys_registered_lock): New variable.
+
+ * rndlinux.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndlinux_constructor): Removed function.
+
+ * rndegd.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndegd_constructor): Removed function.
+
+ * rndunix.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndunix_constructor): Removed function.
+
+ * rndw32.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndw32_constructor): Removed function.
+
+ * rndegd.c (rndegd_connect_socket): Simplify code for creating the
+ egd socket address.
+ (rndegd_connect_socket): Call log_fatal use instead of
+ g10_log_fatal.
+ (egd_gather_random): Renamed to ...
+ (rndegd_gather_random): ... here.
+
+2003-04-08 Moritz Schulte <moritz@g10code.com>
+
+ * rndlinux.c: Do not include "dynload.h".
+ * rndunix.c: Likewise.
+ * rndw32.c: Likewise.
+
+ * rndegd.c (rndegd_connect_socket): Factored out from ...
+ (egd_gather_random): here; call it.
+ (egd_socket): New variable.
+ (egd_gather_random): Initialize fd with egd_socket, do not declare
+ fd static.
+ (do_read): Merged few changes from GnuPG. FIXME - not finished?
+ Do not include "dynload.h".
+
+ * rndw32.c (gather_random): Renamed to rndw32_gather_random, do
+ not declare static.
+ (gather_random_fast): Renamed to rndw32_gather_random_fast, do not
+ declare static.
+
+ * rndunix.c (gather_random): Renamed to rndunix_gather_random, do
+ not declare static.
+ * rndegd.c (gather_random): Renamed to rndegd_gather_random, do
+ not declare static.
+ * rndlinux.c (gather_random): Renamed to rndlinux_gather_random,
+ do not declare static.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libcipher_la_SOURCES): Removed construct.c.
+ (libcipher_la_SOURCES): Added sha1.c, sha256.c, rmd160.c, md4.c,
+ md5.c, tiger.c and crc.c
+ (EXTRA_PROGRAMS): Removed sha1, sha256, rmd160, md4, md5, tiger
+ and crc. Removed definitions: EXTRA_md4_SOURCES,
+ EXTRA_md5_SOURCES, EXTRA_rmd160_SOURCES, EXTRA_sha1_SOURCES,
+ EXTRA_sha256_SOURCES, EXTRA_tiger_SOURCES and EXTRA_crc_SOURCES,
+ BUILT_SOURCES, DISTCLEANFILES.
+
+ * pubkey.c: Do not include "elgamal.h", "dsa.h" and "rsa.h".
+
+ * Makefile.am (libcipher_la_SOURCES): Removed rsa.h, elgamal.h,
+ dsa.h, des.h, cast5.h, arcfour.h and blowfish.h.
+
+ * rsa.h: Removed file.
+ * elgamal.h: Removed file.
+ * dsa.h: Removed file.
+ * des.h: Removed file.
+ * cast5.h: Removed file.
+ * arcfour.h: Removed file.
+ * blowfish.h: Removed file.
+
+ * Makefile.am (libcipher_la_SOURCES): Removed dynload.c and
+ dynload.h.
+
+ * rsa.c (pubkey_spec_rsa): New variable.
+ * dsa.c (pubkey_spec_rsa): New variable.
+ * elgamal.c (pubkey_spec_elg): New variable.
+
+ * rsa.c (_gcry_rsa_get_info): Removed function.
+ * elgamal.c (_gcry_elg_get_info): Removed function.
+ * dsa.c (_gcry_dsa_get_info): Removed function.
+
+ * tiger.c (tiger_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_tiger_constructor): Removed function.
+
+ * sha1.c (sha1_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_sha1_constructor): Removed function.
+
+ * sha256.c (sha256_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_sha256_constructor): Removed function.
+
+ * rmd160.c (rmd160_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rmd160_constructor): Removed function.
+
+ * md5.c (md5_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_md5_constructor): Removed function.
+
+ * md4.c (md4_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_md4_constructor): Removed function.
+
+ * crc.c (crc_get_info): Removed function.
+
+ * arcfour.c (do_arcfour_setkey): Changed type of context argument
+ to `void *', added local variable for cast, adjusted callers.
+ (arcfour_setkey): Likewise.
+ (encrypt_stream): Likewise.
+ * cast5.c (cast_setkey): Likewise.
+ (encrypt_block): Likewise.
+ * rijndael.c (rijndael_setkey): Likewise.
+ (rijndael_encrypt): Likewise.
+ (rijndael_decrypt): Likewise.
+ * twofish.c (twofish_setkey): Likewise.
+ (twofish_encrypt): Likewise.
+ (twofish_decrypt): Likewise.
+ * des.c (do_des_setkey): Likewise.
+ (do_des_encrypt): Likewise.
+ (do_des_encrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ * blowfish.c (bf_setkey: Likewise.
+ (encrypt_block): Likewise.
+ (decrypt_block): Likewise.
+
+ * arcfour.c (encrypt_stream): Likewise.
+
+ * rijndael.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func) Removed function.
+
+ * twofish.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func) Removed function.
+
+ * cast5.c (CIPHER_ALGO_CAST5): Removed.
+
+ * blowfish.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
+ (CIPHER_ALGO_BLOWFISH): Removed symbol.
+ * cast5.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Likewise.
+ * des.c (selftest_failed): Removed.
+ (initialized): New variable.
+ (do_des_setkey): Run selftest, if not yet done.
+ (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
+
+ * arcfour.c (_gcry_arcfour_get_info): Removed function.
+ * blowfish.c (_gcry_blowfish_get_info): Removed function.
+ * cast5.c (_gcry_cast5_get_info): Removed function.
+ * des.c (_gcry_des_get_info): Removed function.
+ * rijndael.c (_gcry_rijndael_get_info): Removed function.
+ * twofish.c (_gcry_twofish_get_info): Removed function.
+
+ * arcfour.c (cipher_spec_arcfour): New variable.
+ * twofish.c (cipher_spec_twofish, cipher_spec_twofish128): New
+ variables.
+ * rijndael.c (cipher_spec_aes, cipher_spec_aes192,
+ cipher_spec256): New variables.
+ * des.c (cipher_spec_des, cipher_spec_tripledes): New variables.
+ * cast5.c (cipher_spec_cast5): New variable.
+ * blowfish.c (cipher_spec_blowfish): Likewise.
+
+ * twofish.c: Do not include "dynload.h".
+ * rijndael.c: Likewise.
+ * des.c: Likewise.
+ * cast5.c: Likewise.
+ * blowfish.c: Likewise.
+ * cipher.c: Likewise.
+ * crc.c: Likewise.
+ * md4.c: Likewise.
+ * md5.c: Likewise.
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+ * rijndael.c: Likewise.
+ * sha1.c: Likewise.
+ * sha256.c: Likewise.
+
+ * arcfour.c: Include "cipher.h".
+ * twofish.c: Likewise.
+ * rijndael.c: Likewise.
+ * des.c: Likewise.
+ * cast5.c: Likewise.
+ * blowfish.c: Likewise.
+
+ * twofish.c (twofish_setkey): Declared argument `key' const.
+ (twofish_encrypt): Declared argument `inbuf' const.
+ (twofish_decrypt): Likewise.
+
+ * rijndael.c (rijndael_setkey): Declared argument `key' const.
+ (rijndael_encrypt): Declared argument `inbuf' const.
+ (rijndael_decrypt): Likewise.
+
+ * des.c (do_des_setkey): Declared argument `key' const.
+ (do_tripledes_setkey): Likewise.
+ (do_des_encrypt): Declared argument `inbuf' const.
+ (do_des_decrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ (do_tripledes_decrypt): Likewise.
+
+ * cast5.c (encrypt_block): Declared argument `inbuf' const.
+ (decrypt_block): Likewise.
+ (cast_setkey): Declared argument `key' const.
+
+ * blowfish.c (do_bf_setkey): Declared argument `key' const.
+ (encrypt_block): Declared argument `inbuf' const.
+ (encrypt_block): Likewise.
+
+
+
+ * cipher.c: Remove CIPHER_ALGO_DUMMY related code.
+ Removed struct cipher_table_s.
+ Changed definition of cipher_table.
+ Removed definition of disabled_algos.
+ (ciphers_registered, default_ciphers_registered): New variables.
+ (REGISTER_DEFAULT_CIPHERS): New macro.
+ (dummy_setkey): Declared argument `key' const.
+ (dummy_encrypt_block): Declared argument `inbuf' const.
+ (dummy_encrypt_block): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_setkey): Use `unsigned char' instead of `byte'.
+ (dummy_encrypt_block): Likewise.
+ (dummy_decrypt_block): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_decrypt_stream): Likewise.
+ (gcry_cipher_register_default): New function.
+ (gcry_cipher_lookup_func_id): New function.
+ (gcry_cipher_lookup_func_name): New function.
+ (gcry_cipher_lookup_id): New function.
+ (gcry_cipher_lookup_name): New function.
+ (gcry_cipher_id_new): New function.
+ (gcry_cipher_register): New function.
+ (gcry_cipher_unregister): New function.
+ (setup_cipher_table): Removed function.
+ (load_cipher_modules): Removed function.
+ (gcry_cipher_map_name): Adjusted to use new module management.
+ (cipher_algo_to_string): Likewise.
+ (disable_cipher_algo): Likewise.
+ (check_cipher_algo): Likewise.
+ (cipher_get_keylen): Likewise.
+ (cipher_get_blocksize): Likewise.
+ (gcry_cipher_open): Likewise.
+ (struct gcry_cipher_handle): Replaced members algo, algo_index,
+ blocksize, setkey, encrypt, decrypt, stencrypt, stdecrypt with one
+ member: cipher.
+ (gcry_cipher_open): Adjusted code for new handle structure.
+ (cipher_setkey): Likewise.
+ (cipher_setiv): Likewise.
+ (cipher_reset): Likewise.
+ (do_ecb_encrypt): Likewise.
+ (do_ecb_decrypt): Likewise.
+ (do_cbc_encrypt): Likewise.
+ (do_cbc_decrypt): Likewise.
+ (do_cfb_encrypt): Likewise.
+ (do_cfb_decrypt): Likewise.
+ (do_ctr_encrypt): Likewise.
+ (cipher_encrypt): Likewise.
+ (gcry_cipher_encrypt): Likewise.
+ (cipher_decrypt): Likewise.
+ (gcry_cipher_decrypt): Likewise.
+ (cipher_sync): Likewise.
+ (gcry_cipher_ctl): Likewise.
+
+ * pubkey.c: Removed struct pubkey_table_s.
+ Changed definition of pubkey_table.
+ Removed definition of disabled_algos.
+ (pubkeys_registered, default_pubkeys_registered): New variables.
+ (REGISTER_DEFAULT_PUBKEYS): New macro.
+ (setup_pubkey_table): Removed function.
+ (load_pubkey_modules): Removed function.
+ (gcry_pubkey_register_default): New function.
+ (gcry_pubkey_lookup_func_id): New function.
+ (gcry_pubkey_lookup_func_name): New function.
+ (gcry_pubkey_lookup_id): New function.
+ (gcry_pubkey_lookup_name): New function.
+ (gcry_pubkey_id_new): New function.
+ (gcry_pubkey_register): New function.
+ (gcry_pubkey_unregister): New function.
+ (gcry_pk_map_name): Adjusted to use new module management.
+ (gcry_pk_algo_name): Likewise.
+ (disable_pubkey_algo): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_get_npkey): Likewise.
+ (pubkey_get_nskey): Likewise.
+ (pubkey_get_nsig): Likewise.
+ (pubkey_get_nenc): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (gcry_pk_get_nbits): Likewise.
+ (gcry_pk_algo_info): Likewise.
+
+ * md.c: Removed struct md_digest_list_s.
+ (digest_list): Changed definition.
+ (digests_registered, default_digests_registered): New variables.
+ (REGISTER_DEFAULT_DIGESTS): New macro.
+ (new_list_item): Removed function.
+ (setup_md_table): Removed function.
+ (load_digest_module): Removed function.
+ (gcry_digest_register_default): New function.
+ (gcry_digest_lookup_func_id): New function.
+ (gcry_digest_lookup_func_name): New function.
+ (gcry_digest_lookup_id): New function.
+ (gcry_digest_lookup_name): New function.
+ (gcry_digest_id_new): New function.
+ (gcry_digest_register): New function.
+ (gcry_digest_unregister): New function.
+ (GcryDigestEntry): New type.
+ (struct gcry_md_context): Adjusted type of `list'.
+ (gcry_md_map_name): Adjusted to use new module management.
+ (digest_algo_to_string): Likewise.
+ (check_digest_algo): Likewise.
+ (md_enable): Likewise.
+ (md_digest_length): Likewise.
+ (md_asn_oid): Likewise.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA,
+ PUBKEY_ALGO_RSA with GCRY_PK_RSA and PUBKEY_ALGO_ELGAMAL with
+ GCRY_PK_ELG.
+
+ * dsa.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA.
+
+2003-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * des.c: Removed checks for GCRY_CIPHER_3DES and GCRY_CIPHER_DES.
+
+2003-03-31 Moritz Schulte <moritz@g10code.com>
+
+ * tiger.c (tiger_get_info): Do not declare static.
+ * sha256.c (sha256_get_info): Likewise.
+ * sha1.c (sha1_get_info): Likewise.
+ * rmd160.c (rmd160_get_info): Likewise.
+ * md5.c (md5_get_info): Likewise.
+ * md4.c (md4_get_info): Likewise.
+ * crc.c (crc_get_info): Likewise.
+
+ * md.c (load_digest_module): Call setup_md_table during
+ initialization.
+ (new_list_item): Link new element into digest_list.
+
+ * cipher.c (do_ctr_decrypt): Made do_ctr_encrypt act as a wrapper
+ for do_ctr_encrypt, since these functions are identical.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (struct gcry_cipher_handle): Add counter field.
+ (gcry_cipher_open): Add CTR.
+ (cipher_reset): Clear counter field.
+ (do_ctr_encrypt, do_ctr_decrypt): New functions.
+ (cipher_encrypt, cipher_decrypt): Call CTR functions.
+ (gcry_cipher_ctl): Add SET_CTR to set counter.
+
+2003-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_blind): New function.
+ (_gcry_rsa_unblind): New function.
+ (_gcry_rsa_decrypt): Use _gcry_rsa_blind and _gcry_rsa_decrypt.
+
+2003-03-26 Moritz Schulte <moritz@g10code.com>
+
+ * dynload.c (_gcry_enum_gnupgext_pubkeys): Adjust `encrypt' and
+ `decrypt' function arguments.
+ (_gcry_enum_gnupgext_pubkeys): Likewise.
+ * dynload.h: Likewise.
+
+ * pubkey.c (dummy_decrypt): Add argument: int flags.
+ (dummy_encrypt): Likewise.
+
+ * elgamal.c (_gcry_elg_encrypt): Add argument: int flags.
+ (_gcry_elg_decrypt): Likewise.
+
+ * rsa.c (_gcry_rsa_encrypt): Add argument: int flags.
+ (_gcry_rsa_decrypt): Likewise.
+
+ * pubkey.c: Add `flags' argument to members `encrypt' and
+ `decrypt' of struct `pubkey_table_s'.
+
+ * rsa.h: Add `flags' argument to function declarations.
+ * elgamal.h: Likewise.
+
+ * pubkey.c (sexp_data_to_mpi): New variable: int parsed_flags.
+ (sexp_data_to_mpi): Set `parsed_flags'.
+ (sexp_data_to_mpi): New argument: int *flags.
+ (gcry_pk_encrypt): New variable: int flags.
+ (gcry_pk_encrypt): Pass `flags' to pubkey_encrypt.
+ (pubkey_encrypt): New variable: int flags.
+ (pubkey_encrypt): Pass `flags' to pubkey encrypt function.
+ (pubkey_decrypt): Likewise.
+ (pubkey_decrypt): Pass `flags' to pubkey encrypt function.
+ (gcry_pk_encrypt): Include `flags' s-exp in return list.
+ (sexp_to_enc): New argument: int *flags.
+ (gcry_pk_decrypt): New variable: int flags.
+ (gcry_pk_decrypt): Pass `flags' to pubkey_decrypt.
+ (sexp_to_enc): New variable: int parsed_flags.
+ (sexp_to_enc): Set `parsed_flags'.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (gcry_cipher_open, do_cbc_encrypt)
+ (gcry_cipher_encrypt): Support GCRY_CIPHER_CBC_MAC.
+ (gcry_cipher_ctl): Support GCRYCTL_SET_CBC_MAC.
+
+2003-03-19 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): New args EXTRA_CHECK and EXTRA_CHECK_ARG
+ to allow for a user callback. Changed all callers.
+ (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Ditto, pass them to gen_prime.
+ * rsa.c (check_exponent): New.
+ (generate): Use a callback to ensure that a given exponent is
+ actually generated.
+
+2003-03-12 Moritz Schulte <moritz@g10code.com>
+
+ * primegen.c: Initialize `no_of_small_prime_numbers' statically.
+ (gen_prime): Remove calculation of `no_of_small_prime_numbers'.
+
+2003-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (gcry_md_ctl): Rewritten to use same style like the other
+ functions dispatchers.
+
+2003-03-02 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (struct gcry_cipher_handle): New member: algo_index.
+ (gcry_cipher_open): Allocate memory for two cipher contexts.
+ Initialize algo_index.
+ (cipher_setkey): Duplicate context into reserved memory.
+ (cipher_reset): New function, which resets the context and clear
+ the IV.
+ (gcry_cipher_ctl): Call cipher_reset.
+
+2003-02-23 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c: Remove (bogus) `digitp' macro definition.
+ * md.c: Likewise.
+
+ * blowfish.c (burn_stack): Removed.
+ * arcfour.c (burn_stack): Likewise.
+ * cast5.c (burn_stack): Likewise.
+ * des.c (burn_stack): Likewise.
+ * md4.c (burn_stack): Likewise.
+ * md5.c (burn_stack): Likewise.
+ * random.c (burn_stack): Likewise.
+ * rijndael.c (burn_stack): Likewise.
+ * rmd160.c (burn_stack): Likewise.
+ * sha1.c (burn_stack): Likewise.
+ * sha256.c (burn_stack): Likewise.
+ * tiger.c (burn_stack): Likewise.
+ * twofish.c (burn_stack): Likewise.
+
+ * blowfish.c: Changed all occurences of burn_stack to
+ _gcry_burn_stack.
+ * arcfour.c: Likewise.
+ * cast5.c: Likewise.
+ * des.c: Likewise.
+ * md4.c: Likewise.
+ * md5.c: Likewise.
+ * random.c: Likewise.
+ * rijndael.c: Likewise.
+ * rmd160.c: Likewise.
+ * sha1.c: Likewise.
+ * sha256.c: Likewise.
+ * tiger.c: Likewise.
+ * twofish.c: Likewise.
+
+ * arcfour.c (_gcry_arcfour_get_info): Use GCRY_CIPHER_ARCFOUR
+ instead of hard-coded value `301'.
+
+2003-01-24 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_register_random_progress): New.
+ (_gcry_random_progress): New.
+
+ * rndlinux.c (gather_random): Call the random progress function.
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): New arg USE_E to request a specific public
+ exponent.
+ (_gcry_rsa_generate): Ditto.
+ * elgamal.c (_gcry_elg_generate): Must add an dummy argument
+ instead of USE_E.
+ * dsa.c (_gcry_dsa_generate): Ditto.
+ * pubkey.c (dummy_generate): Ditto.
+ (pubkey_generate): Add USE_E arg and pass it down.
+ (gcry_pk_genkey): Detect "rsa-use-e" parameter and pass it to generate.
+
+ * pubkey.c (sexp_to_enc): New arg RET_MODERN.
+ (gcry_pk_decrypt): Make use of it to return a real S-expression.
+ Return better error codes.
+ (gcry_pk_verify): Return better error codes.
+
+2003-01-21 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_add_bytes): Add QUALITY argument, let
+ function return an error code and disable its core for now.
+
+2003-01-21 Timo Schulz <twoaday@freakmail.de>
+
+ * random.c (gcry_random_add_bytes): New. Function to add external
+ random to the pool.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * crc.c: New.
+ * Makefile.am (EXTRA_PROGRAMS, EXTRA_crc_SOURCES): Add crc.c.
+ * md.c (gcry_md_get_algo_dlen): Add values for CRC.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * sha256.c: New.
+ * bithelp.h (ror): New.
+ * Makfile.am: Add sha256.c.
+ * md.c (oid_table): Add values for SHA256 et al.
+ (gcry_md_get_algo_dlen): Likewise
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): Implemented keygrips for DSA
+ and ElGamal.
+
+2003-01-17 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_encrypt): Reworked so that the output will
+ never contain the plaintext even if the caller did not checked the
+ return value.
+
+ * md.c (gcry_md_get_algo): Changed error code to GCRYERR_GENERAL
+ because we don't have an invalid md algo but no algorithm enabled.
+
+ * pubkey.c (gcry_pk_genkey): Changed error code for bounds check
+ of table parameters to GCRYERR_INTERNAL.
+
+ * md.c (gcry_md_open): Partly reverted Timo's change from
+ 2002-10-10 by removing the check for the algorithm. An algorithm
+ of 0 is allowed and anyway we should not double check it or check
+ it using a different function. Also fixed the flags check.
+
+ * pubkey.c (gcry_pk_encrypt): Make sure that R_CIPH points to NULL
+ on error.
+ (gcry_pk_decrypt): Ditto for R_PLAIN.
+ (gcry_pk_sign): Ditto for R_SIG.
+ (gcry_pk_genkey): Ditto for R_KEY.
+
+2003-01-16 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_write): Changed 2nd argument type to void*.
+ (gcry_md_hash_buffer): Changed type of boths buffers to void*.
+ (gcry_md_setkey): Changed 2nd argument type to void*.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (sexp_data_to_mpi): New. This handles pkcs1 padding.
+ (gcry_pk_sign, gcry_pk_verify): Use it here.
+ (gcry_pk_encrypt): And here.
+ (pubkey_verify): Add debug code.
+ (sexp_to_enc): Handle flags in the input and return the pkcs1 flag
+ in a new parameter.
+ (gcry_pk_decrypt): Prepare for future pkcs1 handling.
+
+2002-12-19 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_random_initialize): New.
+
+2002-12-16 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Added a Teletrust specific OID for 3DES.
+
+2002-12-12 Werner Koch <wk@gnupg.org>
+
+ * md.c: Added another oddball OIW OID (sha-1WithRSAEncryption).
+
+2002-11-23 Werner Koch <wk@gnupg.org>
+
+ * md.c (load_digest_module): Enlarged checked_algos bitmap.
+ * md4.c (func_table): Fixed entry for md4.
+ Both by Simon Josephson.
+ (transform): Copy data to get the alignment straight. Tested only
+ on i386.
+
+2002-11-10 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (gcry_cipher_open): Don't reject CTS flag.
+ (do_cbc_encrypt, do_cbc_decrypt, cipher_encrypt)
+ (gcry_cipher_encrypt, cipher_decrypt)
+ (gcry_cipher_decrypt): Support CTS flag.
+ (gcry_cipher_ctl): Toggle CTS flag.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * md4.c: New. By Simon Josefsson.
+ * Makefile.am (EXTRA_PROGRAMS): Add md4.c.
+ * md.c (oid_table,gcry_md_get_algo_dlen): MD4 support.
+
+2002-10-14 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c (do_encrypt_stream): Don't use increment op when
+ assigning to the same variable.
+
+2002-10-10 Timo Schulz <ts@winpt.org>
+
+ * pubkey.c (gcry_pk_genkey): Check boundaries.
+
+ * md.c (gcry_md_open): Check that algo is available and only
+ valid flag values are used.
+ (gcry_md_get_algo): Add error handling.
+
+2002-09-26 Werner Koch <wk@gnupg.org>
+
+ * md.c: Include an OID for TIGER.
+ * tiger.c (tiger_get_info): Use a regular OID.
+
+2002-09-17 Werner Koch <wk@gnupg.org>
+
+ * random.c: Replaced mutex.h by the new ath.h. Changed all calls.
+
+2002-09-16 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c (do_encrypt_stream): Use register modifier and modulo.
+ According to Nikos Mavroyanopoulos this increases perfromace on
+ i386 system noticable. And I always tought gcc is clever enough.
+ * md5.c (transform): Use register modifier.
+ * rmd160.c (transform): Ditto.
+ * sha1.c (transform): Ditto. We hope that there are 6 free registers.
+ * random.c (gcry_randomize): Rewrote to avoid malloc calls.
+
+ * rndlinux.c (gather_random): Replaced remaining fprintfs by log_*.
+ * arcfour.c (do_arcfour_setkey): Ditto.
+ * twofish.c (do_twofish_setkey): Ditto.
+ * rndegd.c (gather_random): Ditto.
+ * rijndael.c (do_setkey): Ditto.
+ * random.c (_gcry_random_dump_stats): Ditto.
+ * primegen.c (_gcry_generate_elg_prime): Ditto.
+ * des.c (_gcry_des_get_info): Ditto.
+ * cast5.c (do_cast_setkey): Ditto.
+ * blowfish.c (do_bf_setkey): Ditto.
+
+2002-08-26 Werner Koch <wk@gnupg.org>
+
+ * des.c (weak_keys): Fixed one entry in the table and compared
+ all entries against the literature.
+ (selftest): Checksum the weak key table.
+
+2002-08-21 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c: Enable keygrip calculation for "openpgp-rsa".
+
+2002-08-17 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (setup_cipher_table): Don't overwrite the DES entry
+ with the entry for DUMMY.
+
+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * des.c (do_des_setkey,do_des_encrypt, do_des_decrypt): New.
+ (_gcry_des_get_info): Support plain old DES.
+ * cipher.c (setup_cipher_table): Put DES into the table.
+
+2002-07-25 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (_gcry_rndunix_constructor): Prefixed with _gcry_.
+ Noted by Stephan Austermuehle.
+
+2002-07-08 Timo Schulz <ts@winpt.org>
+
+ * rndw32.c: Replaced the m_ memory functions with the real
+ gcry_ functions. Renamed all g10_ prefixed functions to log_.
+
+2002-06-12 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): Use e = 65537 for now.
+
+2002-06-11 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): Allow a "protected-private-key".
+
+2002-06-05 Timo Schulz <ts@winpt.org>
+
+ * cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt):
+ Check that the input size is a multiple of the blocksize.
+
+2002-05-23 Werner Koch <wk@gnupg.org>
+
+ * md.c (oid_table): Add an rsadsi OID for MD5.
+
+2002-05-21 Werner Koch <wk@gnupg.org>
+
+ * primegen.c, elgamal.c, dsa.c (progress): Do not print anything
+ by default. Pass an extra identifying string to the callback and
+ reserved 2 argumenst for current and total counters. Changed the
+ register function prototype.
+
+2002-05-17 Werner Koch <wk@gnupg.org>
+
+ * rndegd.c (rndegd_constructor): Fixed name of register function
+ and prefixed the function name with _gcry_.
+ * rndw32.c (rndw32_constructor): Ditto.
+ * tiger.c (tiger_constructor): Ditto.
+
+ * Makefile.am: Removed all dynamic loading stuff.
+ * dynload.c: Ditto. Now only used for the constructor system.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_bytes,gcry_random_bytes_secure)
+ (gcry_randomize): Make sure we are initialized.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of most files to the LGPL.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_fast_random_poll): Initialize the module so the
+ mutex can be used.
+
+ * primegen.c (small_prime_numbers): Moved table from smallprime.c
+ * smallprime.c: File removed.
+
+ * des.c (leftkey_swap, rightkey_swap, working_memcmp): Made static.
+
+ * cipher.c (gcry_cipher_map_name): Map "RIJNDAEL" to "AES".
+ * rijndael.c (rijndael_get_info): We do only support a 128 bit
+ blocksize so it makes sense to change the algorithm strings to
+ AES.
+
+ * tiger.c (tiger_final): Removed superfluous token pasting operators.
+ * md5.c (md5_final): Ditto.
+
+2002-04-30 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Fixed list of copyright years.
+
+2002-03-18 Werner Koch <wk@gnupg.org>
+
+ * random.c (initialize): Initialize the new pool lock mutex.
+ (_gcry_fast_random_poll): Add locking and moved main
+ code out to...
+ (do_fast_random_poll): new function.
+ (read_pool): Use the new function here.
+ (get_random_bytes): Add locking.
+ (_gcry_update_random_seed_file): Ditto.
+
+2002-03-11 Werner Koch <wk@gnupg.org>
+
+ * md.c: Add rsaSignatureWithripemd160 to OID table.
+
+2002-02-20 Werner Koch <wk@gnupg.org>
+
+ * sha1.c: Removed a left over comment note. The code has been
+ rewritten from scratch in 1998. Thanks to Niels Möller for
+ reporting this misleading comment.
+
+2002-02-18 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (rndunix_constructor): Use the the new prefixed
+ function name. Reported by Jordi Mallach.
+
+2002-02-10 Werner Koch <wk@gnupg.org>
+
+ * random.c (mix_pool): Carry an extra failsafe_digest buffer
+ around to make the function more robust.
+
+2002-02-08 Werner Koch <wk@gnupg.org>
+
+ * random.c (add_randomness): Xor new data into the pool and not
+ just copy it. This avoids any choosen input attacks which are not
+ serious in our setting because an outsider won't be able to mix
+ data in and even then we keep going with a PRNG. Thanks to Stefan
+ Keller for pointing this out.
+
+2002-01-04 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_genkey): Do not release skey - it is static.
+
+ * primegen.c (gen_prime): Of course we should use set_bit
+ and not set_highbit to set the second high bit.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): Loop until we find the exact modulus size.
+ Changed the exponent to 41.
+ (rsa_get_info): s/usage/r_usage/ to avoid shadow warnings.
+ * primegen.c (gen_prime): Set 2 high order bits for secret primes.
+
+ * Makefile.am (DISTCLEANFILES): Include construct.c.
+
+2001-12-17 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): New - experimental.
+
+2001-12-11 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Added OIDs for AES.
+ (gcry_cipher_mode_from_oid): New.
+ (gcry_cipher_map_name): Moved OID search code to ..
+ (search_oid): .. new function.
+
+2001-12-10 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_encrypt): Find the signature algorithm by name
+ and not by number.
+
+ * pubkey.c (gcry_pk_encrypt,gcry_pk_decrypt,gcry_pk_sign)
+ (gcry_pk_verify,gcry_pk_testkey, gcry_pk_genkey)
+ (gcry_pk_get_nbits): Release the arrays. Noted by Nikos
+ Mavroyanopoulos.
+
+2001-12-06 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_map_name): Look also for OIDs prefixed
+ with "oid." or "OID.".
+
+2001-12-05 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (algo_info_table): Fixed entry for openpgp-rsa.
+
+2001-11-24 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c: Added the rsaEncryption OID to the tables.
+ (sexp_to_key): Add an arg to return the index of the algorithm,
+ changed all callers.
+ (gcry_pk_sign): Find the signature algorithm by name and not by
+ number.
+ (gcry_pk_get_nbits): Fixed so that we can now really pass a secret
+ key to get the result.
+
+ * md.c (gcry_md_map_name): Look also for OIDs prefixed with "oid."
+ or "OID." so that an OID string can be used as an S-Exp token.
+
+2001-11-20 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_map_name): Lookup by OID if the the name begins
+ with a digit.
+ (oid_table): New.
+
+2001-11-16 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_info): New operator GCRYCTL_IS_ALGO_ENABLED.
+
+2001-11-07 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Close the handle which was left open
+ for algorithms other than rmd160.
+
+2001-08-08 Werner Koch <wk@gnupg.org>
+
+ * rndw32.c (gather_random): Use toolhelp in addition to the NT
+ gatherer for Windows2000. Suggested by Sami Tolvanen.
+
+ * random.c (read_pool): Fixed length check, this used to be one
+ byte to strict. Made an assert out of it because the caller has
+ already made sure that only poolsize bytes are requested.
+ Reported by Marcus Brinkmann.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (cipher_encrypt, cipher_decrypt): Prepare to return
+ errors. We have to change the interface to all ciphers to make
+ this really work but we should do so to prepare for hardware
+ encryption modules.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Return the error and
+ set lasterr.
+ (gcry_cipher_ctl): Make sure that errors from setkey are returned.
+
+2001-08-02 Werner Koch <wk@gnupg.org>
+
+ * rndlinux.c (gather_random): casted a size_t arg to int so that
+ the format string is correct. Casting is okay here and avoids
+ translation changes.
+
+ * random.c (fast_random_poll): Do not check the return code of
+ getrusage.
+
+ * rndunix.c: Add a signal.h header to avoid warnings on Solaris 7
+ and 8.
+
+ * tiger.c (print_abc,print_data): Removed.
+
+ * rijndael.c, des.c, blowfish.c, twofish.c, cast5.c, arcfour.c
+ (burn_stack): New. Add wrappers for most functions to be able to
+ call burn_stack after the function invocation. This methods seems
+ to be the most portable way to zeroise the stack used. It does
+ only work on stack frame based machines but it is highly portable
+ and has no side effects. Just setting the automatic variables at
+ the end of a function to zero does not work well because the
+ compiler will optimize them away - marking them as volatile would
+ be bad for performance.
+ * md5.c, sha1.c, rmd160.c, tiger.c (burn_stack): Likewise.
+ * random.c (burn_stack): New.
+ (mix_pool): Use it here to burn the stack of the mixblock function.
+
+ * primegen.c (_gcry_generate_elg_prime): Freed q at 3 places.
+ Thanks to Tommi Komulainen.
+
+ * arcfour.c (arcfour_setkey): Check the minimim keylength against
+ bytes and not bits.
+ (selftest): Must reset the key before decryption.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * sha1.c (sha1_init): Made static.
+
+ Changed all g10_ prefixed function names as well as some mpi_
+ function names to cope with the introduced naming changes.
+
+ * md.c (prepare_macpads): Made key const.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * rndegd.c (gather_random): Removed the use of tty_printf.
+
+2001-03-29 Werner Koch <wk@gnupg.org>
+
+ * md5.c (md5_final): Fixed calculation of hashed length. Thanks
+ to disastry@saiknes.lv for pointing out that it was horrible wrong
+ for more than 512MB of input.
+ * sha1.c (sha1_final): Ditto.
+ * rmd160.c (rmd160_final): Ditto.
+ * tiger.c (tiger_final): Ditto.
+
+ * blowfish.c (encrypt,do_encrypt): Changed name to do_encrypt to
+ avoid name clashes with an encrypt function in stdlib.h of
+ Dynix/PIX. Thanks to Gene Carter.
+ * elgamal.c (encrypt,do_encrypt): Ditto.
+
+ * twofish.c (gnupgext_enum_func): Use only when when compiled as a
+ module.
+ * rijndael.c (gnupgext_enum_func): Ditto.
+
+ * tiger.c (tiger_get_info): Return "TIGER192" and not just
+ "TIGER". By Edwin Woudt.
+
+ * random.c: Always include time.h - standard requirement. Thanks
+ to James Troup.
+
+ * rndw32.c: Fixes to the macros.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (cipher_encrypt,gcry_cipher_encrypt): Use blocksize and
+ not 8.
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * dsa.c (test_keys): Replaced mpi_alloc by gcry_mpi_new and
+ mpi_free by gcry_mpi_release.
+ * elgamal.c (test_keys,generate): Ditto, also for mpi_alloc_secure.
+ * rsa.c (test_keys,generate,rsa_verify): Ditto.
+ * primegen.c (generate_elg_prime): Ditto.
+ (gen_prime): Ditto and removed nlimbs.
+
+ * rsa.c (generate): Allocate 2 more vars in secure memory.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-09 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c, arcfour.h: New.
+ * cipher.c (cipher_encrypt, cipher_decrypt): Add stream mode.
+ (setup_cipher_table): Add Arcfour.
+ (gcry_cipher_open): Kludge to allow stream mode.
+
+Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sha1.c (transform): Use rol() macro. Actually this is not needed
+ for a newer gcc but there are still aoter compilers.
+
+ * rsa.c (test_keys): Use new random function.
+
+ * md.c (gcry_md_setkey): New function to overcome problems with
+ const conflics.
+ (gcry_md_ctl): Pass set key to the new functions.
+
+ * rijndael.c: New.
+ * cipher.c: Add Rijndael support.
+
+Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
+
+ * rndlinux.c (open_device): Loose random device checking.
+ By Nils Ellmenreich.
+
+ * random.c (fast_random_poll): Check ENOSYS for getrusage.
+ * rndunix.c: Add 2 sources for QNX. By Sam Roberts.
+
+ * pubkey.c (gcry_pk_algo_info): Add GCRYCTL_GET_ALGO_USAGE.
+
+ * rsa.c: Changed the comment about the patent.
+ (secret): Speed up by using the CRT. For a 2k keys this
+ is about 3 times faster.
+ (stronger_key_check): New but unused code to check the secret key.
+ * Makefile.am: Included rsa.[ch].
+ * pubkey.c: Enabled RSA support.
+ (pubkey_get_npkey): Removed RSA workaround.
+
+Mon Jul 31 10:04:47 CEST 2000 Werner Koch <wk@openit.de>
+
+ * pubkey.c: Replaced all gcry_sexp_{car,cdr}_{data,mpi} by the new
+ gcry_sexp_nth_{data,mpi} functions.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * pubkey.c (exp_to_key,sexp_to_sig,sexp_to_enc,gcry_pk_encrypt,
+ gcry_pk_decrypt,gcry_pk_sign,gcry_pk_genkey): Changed to work with
+ the new S-Exp interface.
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * random.c (gather_faked): Replaced make_timestamp by time(2) again.
+
+Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
+
+ * md.c (gcry_md_ctl): Support GCRYCTL_{START,STOP}_DUMP.
+
+ * Makefile.am: Never compile mingw32 as module.
+
+ * Makefile.am: Tweaked module build and removed libtool
+
+ * Makefile.am: Replaced -O1 by -O. Suggested by Alec Habig.
+
+ * elgamal.c (sign): Removed inactive code.
+
+ * rsa.c, rsa.h: New based on the old module version (only in CVS for now).
+ * pubkey.c (setup_pubkey_table): Added commented support for RSA.
+
+ * rndunix.c (waitpid): New. For UTS 2.1. All by Dave Dykstra.
+ (my_popen): Do the FD_CLOEXEC only if it is available
+ (start_gatherer): Cope with missing _SC_OPEN_MAX
+
+ * rndunix.c: Add some more headers for QNX. By Sam Roberts.
+
+ * rndegd.c (gather_random): Shortcut level 0.
+ * rndunix.c (gather_random): Ditto.
+ * rndw32.c (gather_random): Ditto.
+
+ * rndw32.c: Replaced with code from Cryptlib and commented the old stuff.
+ * rndw32.c: Add some debuging code enabled by an environment variable.
+
+ * random.c (read_seed_file): Binary open for DOSish system
+ (update_random_seed_file): Ditto.
+ * random.c [MINGW32]: Include process.h for getpid.
+ * random.c (fast_random_poll): Add clock_gettime() as fallback for
+ system which support this POSIX.4 fucntion. By Sam Roberts.
+
+ * random.c (read_seed_file): Removed the S_ISLNK test becuase it
+ is already covered by !S_ISREG and is not defined in Unixware.
+ Reported by Dave Dykstra.
+ (update_random_seed_file): Silently ignore update request when pool
+ is not filled.
+
+ * random.c (read_seed_file): New.
+ (set_random_seed_file): New.
+ (read_pool): Try to read the seeding file.
+ (update_random_seed_file): New.
+
+ (read_pool): Do an initial extra seeding when level 2 quality random
+ is requested the first time. This requestes at least POOLSIZE/2 bytes
+ of entropy. Compined with the seeding file this should make normal
+ random bytes cheaper and increase the quality of the random bytes
+ used for key generation.
+
+ * random.c (read_pool): Print a more friendly error message in
+ cases when too much random is requested in one call.
+
+ * random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
+ this is not the case for some ESIX and Unixware, although they have
+ getrusage().
+
+ * primegen.c (generate_elg_prime): All primes are now generated with
+ the lowest random quality level. Because they are public anyway we
+ don't need stronger random and by this we do not drain the systems
+ entropy so much.
+
+ * primegen.c (register_primegen_progress): New.
+ * dsa.c (register_pk_dsa_progress): New.
+ * elgamal.c (register_pk_elg_progress): New.
+
+ * elgamal.c (wiener_map): New.
+ (gen_k): Use a much smaller k.
+ (generate): Calculate the qbits using the wiener map and
+ choose an x at a size comparable to the one choosen in gen_k
+
+ * rmd160.c (rmd160_get_info): Moved casting to the left side due to a
+ problem with UTS4.3. Suggested by Dave Dykstra.
+ * sha1.c (sha1_get_info): Ditto.
+ * tiger.c (tiger_get_info): Ditto.
+ * md5.c (md5_get_info): Ditto
+ * des.c (des_get_info): Ditto.
+ * blowfish.c (blowfish_get_info): Ditto.
+ * cast5.c (cast5_get_info): Ditto.
+ * twofish.c (twofish_get_info): Ditto.
+
+Fri Mar 24 11:25:45 CET 2000 Werner Koch <wk@openit.de>
+
+ * md.c (md_open): Add hmac arg and allocate space for the pads.
+ (md_finalize): Add HMAC support.
+ (md_copy): Ditto.
+ (md_close): Ditto.
+ (gcry_md_reset): Ditto.
+ (gcry_md_ctl): Ditto.
+ (prepare_macpdas): New.
+
+Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
+
+ * md.c (gcry_md_hash_buffer): Add support for the other algorithms.
+
+Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * genprime.c (generate_elg_prime): Fixed returned factors which never
+ worked for non-DSA keys.
+
+Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (sexp_to_key): Fixed mem leaks in case of errors.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (gcry_pk_decrypt): Implemented.
+ (gcry_pk_encrypt): Implemented.
+ (gcry_pk_testkey): New.
+ (gcry_pk_genkey): New.
+ (pubkey_decrypt): Made static.
+ (pubkey_encrypt): Ditto.
+ (pubkey_check_secret_key): Ditto.
+ (pubkey_generate): Ditto.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (pubkey_nbits): Removed and replaced by ...
+ (gcry_pk_get_nbits): this new one.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * dsa.c: s/mpi_powm/gcry_mpi_powm/g
+ * elgamal.c: Ditto.
+ * primegen.c: Ditto.
+
+ * : Replaced g10_opt_verbose by g10_log_verbosity().
+
+ * Makefile.am (INCLUDES): removed intl, add ../gcrypt
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * dynload.c (cmp_filenames): New to replaced compare_filename() in
+ module.
+ (register_cipher_extension): Removed the tilde expansion stuff.
+ * rndeg.c (my_make_filename): New.
+
+ * : Replaced header util.h by g10lib.h
+
+ * random.c (gather_faked): Replaced make_timestamp by time(2).
+ Disabled wrning printed with tty_printf.
+ * rndlinux.c (gather_random): Always use fprintf instead of tty_xxx;
+ this should be replaced by a callback function.
+
+ * primegen.c (gen_prime): Use gcry_mpi_randomize.
+ (is_prime): Ditto.
+ * elgamal.c (test_keys): Ditto.
+ * dsa.c (test_keys): Ditto.
+
+ * cipher.c (gcry_cipher_close): Die on invalid handle.
+
+Mon Nov 15 21:36:02 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * elgamal.c (gen_k): Use the new random API.
+ (generate): Ditto.
+ * dsa.c (gen_k): Ditto.
+ (generate): Ditto.
+
+Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (disable_pubkey_algo): Made static.
+ (gcry_pk_ctl): New.
+
+ * random.c (get_random_bits): Renamed to ...
+ (get_random_bytes): ... this and made static.
+ (gcry_random_bytes): New.
+ (gcry_random_bytes_secure): New.
+ (randomize_buffer): Renamed to ...
+ (gcry_randomize): ...this.
+
+ * md.c (gcry_md_hash_buffer): New.
+
+ * pubkey.c (gcry_pk_algo_info): 4 new commands.
+ (pubkey_get_npkey): Made static.
+ (pubkey_get_nskey): Made static.
+ (pubkey_get_nsig): Made static.
+ (pubkey_get_nenc): Made static.
+
+ * pubkey.c: Removed all G10ERR_xxx.
+ * cipher.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_CIPHER_ALGO.
+ * md.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_MD_ALGO.
+ * cast5.c (cast_setkey): Changed errocodes to GCRYERR_xxx.
+ * blowfish.c: Ditto.
+ * des.c: Ditto.
+ * twofish.c: Ditto.
+ * dsa.c: Ditto.
+ * elgamal.c: Ditto.
+
+ * g10c.c: Removed
+
+ * cipher.c (gcry_cipher_open): Replaced alloc functions and return NULL
+ if we are out of core.
+ * dynload.c: Replaced all memory allocation functions.
+ * md.c: Ditto.
+ * primegen.c: Ditto.
+ * pubkey.c: Ditto.
+ * random.c: Ditto.
+ * rndw32.c: Ditto.
+ * elgamal.c: Ditto.
+ * dsa.c: Ditto.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * elgamal.c (sign): Hugh found strange code here. Replaced by BUG().
+
+ * cipher.c: Merged with gcrypt/symapi.c.
+
+ * pubkey.c (string_to_pubkey_algo): Renamed function to ...
+ (gcry_pk_map_name): ... this.
+ (pubkey_algo_to_string): Renamed function to ...
+ (gcry_pk_algo_name): ... this.
+ (gcry_pk_algo_info): New.
+ * pubkey.c: Merged with gcrypt/pkapi.c.
+
+ * md.c (md_reset): Clear finalized; thanks to Ulf Moeller for
+ fixing this bug.
+
+ * md.c: Merged with gcrypt/mdapi.c
+
+Wed Sep 15 14:39:59 CEST 1999 Michael Roth <mroth@nessie.de>
+
+ * des.c: Various speed improvements: One bit pre rotation
+ trick after initial permutation (Richard Outerbridge).
+ Finished test of SSLeay Tripple-DES patterns.
+
+Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndw32.c: New.
+
+Mon Sep 13 10:51:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * bithelp.h: New.
+ * rmd160.h, sha1.h, md5.h: Use the rol macro from bithelp.h
+
+Tue Sep 7 16:23:36 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Fixed seds for latest egcc. By Ollivier Robert.
+
+Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * des.c (selftest): Add some testpattern
+
+Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (do_cbc_encrypt): Fixed serious bug occuring when not using
+ in place encryption. Pointed out by Frank Stajano.
+
+Mon Jul 26 09:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md5.c (md5_final): Fix for a SCO cpp bug.
+
+Thu Jul 15 10:15:35 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * elgamal.c (elg_check_secret_key,elg_encrypt
+ elg_decrypt,elg_sign,elg_verify): Sanity check on the args.
+ * dsa.c (dsa_check_secret_key,dsa_sign,dsa_verify): Ditto.
+
+ * pubkey.c (disable_pubkey_algo): New.
+ (check_pubkey_algo2): Look at disabled algo table.
+ * cipher.c (disable_cipher_algo): New.
+ (check_cipher_algo): Look at disabled algo table.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Support for libtool.
+
+Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dsa.c (gen_k): Changed algorithm to consume less random bytes
+ * elgamal.c (gen_k): Ditto.
+
+ * random.c (random_dump_stats): New.
+
+Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * primegen.c, elgamal.c, dsa.c (progess): New and replaced all
+ fputc with a call to this function.
+
+Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c (do_write): s/ssize_t/int/ due to SunOS 4.1 probs.
+
+ * cipher.c (do_cbc_encrypt, do_cbc_decrypt): New.
+
+ * dynload.c (HAVE_DL_SHL_LOAD): Map hpux API to dlopen (Dave Dykstra).
+ * Makefile.am (install-exec-hook): Removed.
+
+Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (setup_cipher_table): Enable Twofish
+
+ * random.c (fast_random_poll): Disable use of times() for mingw32.
+
+Mon May 17 21:54:43 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (register_internal_cipher_extension): Minor init fix.
+
+Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * primegen.c (gen_prime): Readded the Fermat test. Fixed the bug
+ that we didn't correct for step when passing the prime to the
+ Rabin-Miller test which led to bad performance (Stefan Keller).
+ (check_prime): Add a first Fermat test.
+
+Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (cipher_setiv): Add ivlen arg, changed all callers.
+
+ * random.c (randomize_buffer): alway use secure memory because
+ we can't use m_is_secure() on a statically allocated buffer.
+
+ * twofish.c: Replaced some macros by a loop to reduce text size.
+ * Makefile.am (twofish): No more need for sed editing.
+
+Fri Apr 9 12:26:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (cipher_open): Reversed the changes for AUTO_CFB.
+
+ * blowfish.c: Dropped the Blowfish 160 mode.
+ * cipher.c (cipher_open): Ditto.
+ (setup_cipher_table): Ditto. And removed support of twofish128
+
+Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+ * cipher.c (cipher_open): Now uses standard CFB for automode if
+ the blocksize is gt 8 (according to rfc2440).
+
+ * twofish.c: Applied Matthew Skala's patches for 256 bit key.
+
+Tue Apr 6 19:58:12 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+ * cipher.c (cipher_open): Now uses standard CFB for automode if
+ the blocksize is gt 8 (according to rfc2440).
+
+Sat Mar 20 11:44:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndlinux.c (tty_printf) [IS_MODULE]: Removed.
+
+ * rndegd.c (gather_random): Some fixes.
+
+Wed Mar 17 13:09:03 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c (do_read): New.
+ (gather_random): Changed the implementation.
+
+Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed.
+
+Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c: Nearly a total rewrote.
+
+Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (context): Fixed alignment
+ * md.c: Ditto.
+
+ * rndegd.c: New
+
+Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c: New.
+
+Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Modules are now figured out by configure
+ * construct.c: New. Generated by configure. Changed all modules
+ to work with that.
+ * sha1.h: Removed.
+ * md5.h: Removed.
+
+ * twofish.c: Changed interface to allow Twofish/256
+
+ * rndunix.c (start_gatherer): Die on SIGPIPE.
+
+Wed Jan 20 18:59:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (gather_random): Fix to avoid infinite loop.
+
+Sun Jan 17 11:04:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * des.c (is_weak_key): Replace system memcmp due to bugs
+ in SunOS's memcmp.
+ (des_get_info): Return error on failed selftest.
+ * twofish.c (twofish_setkey): Return error on failed selftest or
+ invalid keylength.
+ * cast5.c (cast_setkey): Ditto.
+ * blowfish.c (bf_setkey): Return error on failed selftest.
+
+Tue Jan 12 11:17:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (random_is_faked): New.
+
+ * tiger.c: Only compile if we have the u64 type
+
+Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (gather_random): check for setuid.
+
+ * Makefile.am: Add a way to staically link random modules
+
+Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c (md_stop_debug): Do a flush first.
+ (md_open): size of buffer now depends on the secure parameter
+
+Sun Jan 3 15:28:44 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (start_gatherer): Fixed stupid ==/= bug
+
+1998-12-31 Geoff Keating <geoffk@ozemail.com.au>
+
+ * des.c (is_weak_key): Rewrite loop end condition.
+
+Tue Dec 29 14:41:47 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c: add unistd.h for getpid().
+ (RAND_MAX): Fallback value for Sun.
+
+Wed Dec 23 17:12:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c (md_copy): Reset debug.
+
+Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (read_random_source): Changed the interface to the
+ random gathering function.
+ (gather_faked): Use new interface.
+ * dynload.c (dynload_getfnc_fast_random_poll): Ditto.
+ (dynload_getfnc_gather_random): Ditto.
+ * rndlinux.c (gather_random): Ditto.
+ * rndunix.c (gather_random): Ditto.
+
+Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (SYMBOL_VERSION): New to cope with system which needs
+ underscores.
+
+ * rndunix.c: Rewrote large parts
+
+Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (load_extension): increased needed verbosity level.
+
+ * random.c (fast_random_poll): Fallback to a default fast random
+ poll function.
+ (read_random_source): Always use the faked entroy gatherer if no
+ gather module is available.
+ * rndlinux.c (fast_poll): Removed.
+ * rndunix.c (fast_poll): Removed.
+
+
+Wed Nov 25 12:33:41 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-*.c: Removed.
+ * rndlinux.c : New.
+ * rndunix.c : New.
+ * random.c : Restructured the interface to the gather modules.
+ (intialize): Call constructor functions
+ (read_radnom_source): Moved to here.
+ * dynload.c (dynload_getfnc_gather_random): New.
+ (dynload_getfnc_fast_random_poll): New.
+ (register_internal_cipher_extension): New.
+ (register_cipher_extension): Support of internal modules.
+
+Sun Nov 8 17:44:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c (read_random_source): Removed the assert.
+
+Mon Oct 19 18:34:30 1998 me,,, (wk@tobold)
+
+ * pubkey.c: Hack to allow us to give some info about RSA keys back.
+
+Thu Oct 15 11:47:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dynload.c: Support for DLD
+
+Wed Oct 14 12:13:07 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c: Now uses names from configure for /dev/random.
+
+1998-10-10 SL Baur <steve@altair.xemacs.org>
+
+ * Makefile.am: fix sed -O substitutions to catch -O6, etc.
+
+Tue Oct 6 10:06:32 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c (HAVE_GETTIMEOFDAY): Fixed (was ..GETTIMEOFTIME :-)
+ * rand-dummy.c (HAVE_GETTIMEOFDAY): Ditto.
+
+Mon Sep 28 13:23:09 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_digest): New.
+ (md_reset): New.
+
+Wed Sep 23 12:27:02 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c (TIGER_CONTEXT): moved "buf", so that it is 64 bit aligned.
+
+Mon Sep 21 06:22:53 1998 Werner Koch (wk@(none))
+
+ * des.c: Some patches from Michael.
+
+Thu Sep 17 19:00:06 1998 Werner Koch (wk@(none))
+
+ * des.c : New file from Michael Roth <mroth@nessie.de>
+
+Mon Sep 14 11:10:55 1998 Werner Koch (wk@(none))
+
+ * blowfish.c (bf_setkey): Niklas Hernaeus patch to detect weak keys.
+
+Mon Sep 14 09:19:25 1998 Werner Koch (wk@(none))
+
+ * dynload.c (RTLD_NOW): Now defined to 1 if it is undefined.
+
+Mon Sep 7 17:04:33 1998 Werner Koch (wk@(none))
+
+ * Makefile.am: Fixes to allow a different build directory
+
+Thu Aug 6 17:25:38 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * random.c (get_random_byte): Removed and changed all callers
+ to use get_random_bits()
+
+Mon Jul 27 10:30:22 1998 Werner Koch (wk@(none))
+
+ * cipher.c : Support for other blocksizes
+ (cipher_get_blocksize): New.
+ * twofish.c: New.
+ * Makefile.am: Add twofish module.
+
+Mon Jul 13 21:30:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (read_pool): Simple alloc if secure_alloc is not set.
+ (get_random_bits): Ditto.
+
+Thu Jul 9 13:01:14 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dynload.c (load_extension): Function now nbails out if
+ the program is run setuid.
+
+Wed Jul 8 18:58:23 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (rmd160_hash_buffer): New.
+
+Thu Jul 2 10:50:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c (cipher_open): algos >=100 use standard CFB
+
+Thu Jun 25 11:18:25 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am: Support for extensions
+
+Thu Jun 18 12:09:38 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (mix_pool): simpler handling for level 0
+
+Mon Jun 15 14:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c: Removed from dist, will reappear as dynload module
+
+Sat Jun 13 14:16:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * pubkey.c: Major changes to allow extensions. Changed the inteface
+ of all public key ciphers and added the ability to load extensions
+ on demand.
+
+ * misc.c: Removed.
+
+Wed Jun 10 07:52:08 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * dynload.c: New.
+ * cipher.c: Major changes to allow extensions.
+
+Mon Jun 8 22:43:00 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: Major internal chnages to support extensions.
+ * blowfish.c (blowfish_get_info): New and made all internal
+ functions static, changed heder.
+ * cast5.c (cast5_get_info): Likewise.
+
+Mon Jun 8 12:27:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c (transform): Fix for big endian
+
+ * cipher.c (do_cfb_decrypt): Big endian fix.
+
+Fri May 22 07:30:39 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_get_oid): Add a new one for TIGER.
+
+Thu May 21 13:24:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: Add support for a dummy cipher
+
+Thu May 14 15:40:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (transform): fixed sigbus - I should better
+ add Christian von Roques's new implemenation of rmd160_write.
+
+Fri May 8 18:07:44 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-internal.h, rand-unix.c, rand-w32.c, rand_dummy.c: New
+ * random.c: Moved system specific functions to rand-****.c
+
+Fri May 8 14:01:17 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (fast_random_poll): add call to gethrtime.
+
+Tue May 5 21:28:55 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * elgamal.c (elg_generate): choosing x was not correct, could
+ yield 6 bytes which are not from the random pool, tsss, tsss..
+
+Tue May 5 14:09:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * primegen.c (generate_elg_prime): Add arg mode, changed all
+ callers and implemented mode 1.
+
+Mon Apr 27 14:41:58 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c (cipher_get_keylen): New.
+
+Sun Apr 26 14:44:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c, tiger.h: New.
+
+Wed Apr 8 14:57:11 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * misc.c (check_pubkey_algo2): New.
+
+Tue Apr 7 18:46:49 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: New
+ * misc.c (check_cipher_algo): Moved to cipher.c
+ * cast5.c: Moved many functions to cipher.c
+ * blowfish.c: Likewise.
+
+Sat Apr 4 19:52:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cast5.c: Implemented and tested.
+
+Wed Apr 1 16:38:27 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * elgamal.c (elg_generate): Faster generation of x in some cases.
+
+Thu Mar 19 13:54:48 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * blowfish.c (blowfish_decode_cfb): changed XOR operation
+ (blowfish_encode_cfb): Ditto.
+
+Thu Mar 12 14:04:05 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * sha1.c (transform): Rewrote
+
+ * blowfish.c (encrypt): Unrolled for rounds == 16
+ (decrypt): Ditto.
+
+Tue Mar 10 16:32:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (transform): Unrolled the loop.
+
+Tue Mar 10 13:05:14 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (read_pool): Add pool_balance stuff.
+ (get_random_bits): New.
+
+ * elgamal.c (elg_generate): Now uses get_random_bits to generate x.
+
+
+Tue Mar 10 11:33:51 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_digest_length): New.
+
+Tue Mar 10 11:27:41 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dsa.c (dsa_verify): Works.
+
+Mon Mar 9 12:59:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dsa.c, dsa.h: Removed some unused code.
+
+Wed Mar 4 10:39:22 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_open): Add call to fast_random_poll.
+ blowfish.c (blowfish_setkey): Ditto.
+
+Tue Mar 3 13:32:54 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (rmd160_mixblock): New.
+ * random.c: Restructured to start with a new RNG implementation.
+ * random.h: New.
+
+Mon Mar 2 19:21:46 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * gost.c, gost.h: Removed because they did only contain trash.
+
+Sun Mar 1 16:42:29 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (fill_buffer): removed error message if n == -1.
+
+Fri Feb 27 16:39:34 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_enable): No init if called twice.
+
+Thu Feb 26 07:57:02 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * primegen.c (generate_elg_prime): Changed the progress printing.
+ (gen_prime): Ditto.
+
+Tue Feb 24 12:28:42 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md5.c, md.5 : Replaced by a modified version of md5.c from
+ GNU textutils 1.22.
+
+Wed Feb 18 14:08:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c, md.h : New debugging support
+
+Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * misc.c (cipher_algo_to_string): New
+ (pubkey_algo_to_string): New.
+ (digest_algo_to_string): New.
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/cipher/Makefile.am b/comm/third_party/libgcrypt/cipher/Makefile.am
new file mode 100644
index 0000000000..d644005634
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/Makefile.am
@@ -0,0 +1,258 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# 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
+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-gcm-intel-pclmul.c cipher-gcm-armv7-neon.S \
+ cipher-gcm-armv8-aarch32-ce.S cipher-gcm-armv8-aarch64-ce.S \
+ cipher-poly1305.c \
+ cipher-ocb.c \
+ cipher-xts.c \
+ cipher-eax.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 \
+ poly1305-s390x.S \
+ 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-armv7-neon.S chacha20-aarch64.S \
+ chacha20-ppc.c chacha20-s390x.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 \
+ 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-armv8-ce.c rijndael-armv8-aarch32-ce.S \
+ rijndael-armv8-aarch64-ce.S rijndael-aarch64.S \
+ rijndael-ppc.c rijndael-ppc9le.c \
+ 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 \
+ 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-armv7-neon.S sha512-arm.S \
+ sha512-ppc.c sha512-ssse3-i386.c \
+ sm3.c \
+ 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.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
+ ./gost-s-box $@
+
+gost-s-box: 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 = -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) `
+
+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) `
diff --git a/comm/third_party/libgcrypt/cipher/Makefile.in b/comm/third_party/libgcrypt/cipher/Makefile.in
new file mode 100644
index 0000000000..ceba51b45a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/Makefile.in
@@ -0,0 +1,1445 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# 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 <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = cipher
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am_libcipher_la_OBJECTS = cipher.lo cipher-cbc.lo cipher-cfb.lo \
+ cipher-ofb.lo cipher-ctr.lo cipher-aeswrap.lo cipher-ccm.lo \
+ cipher-cmac.lo cipher-gcm.lo cipher-gcm-intel-pclmul.lo \
+ cipher-gcm-armv7-neon.lo cipher-gcm-armv8-aarch32-ce.lo \
+ cipher-gcm-armv8-aarch64-ce.lo cipher-poly1305.lo \
+ cipher-ocb.lo cipher-xts.lo cipher-eax.lo cipher-selftest.lo \
+ pubkey.lo pubkey-util.lo md.lo mac.lo mac-hmac.lo mac-cmac.lo \
+ mac-gmac.lo mac-poly1305.lo poly1305.lo poly1305-s390x.lo \
+ kdf.lo primegen.lo hash-common.lo dsa-common.lo rsa-common.lo
+libcipher_la_OBJECTS = $(am_libcipher_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/arcfour-amd64.Plo \
+ ./$(DEPDIR)/arcfour.Plo ./$(DEPDIR)/blake2.Plo \
+ ./$(DEPDIR)/blake2b-amd64-avx2.Plo \
+ ./$(DEPDIR)/blake2s-amd64-avx.Plo \
+ ./$(DEPDIR)/blowfish-amd64.Plo ./$(DEPDIR)/blowfish-arm.Plo \
+ ./$(DEPDIR)/blowfish.Plo ./$(DEPDIR)/camellia-aarch64.Plo \
+ ./$(DEPDIR)/camellia-aesni-avx-amd64.Plo \
+ ./$(DEPDIR)/camellia-aesni-avx2-amd64.Plo \
+ ./$(DEPDIR)/camellia-arm.Plo ./$(DEPDIR)/camellia-glue.Plo \
+ ./$(DEPDIR)/camellia.Plo ./$(DEPDIR)/cast5-amd64.Plo \
+ ./$(DEPDIR)/cast5-arm.Plo ./$(DEPDIR)/cast5.Plo \
+ ./$(DEPDIR)/chacha20-aarch64.Plo \
+ ./$(DEPDIR)/chacha20-amd64-avx2.Plo \
+ ./$(DEPDIR)/chacha20-amd64-ssse3.Plo \
+ ./$(DEPDIR)/chacha20-armv7-neon.Plo \
+ ./$(DEPDIR)/chacha20-ppc.Plo ./$(DEPDIR)/chacha20-s390x.Plo \
+ ./$(DEPDIR)/chacha20.Plo ./$(DEPDIR)/cipher-aeswrap.Plo \
+ ./$(DEPDIR)/cipher-cbc.Plo ./$(DEPDIR)/cipher-ccm.Plo \
+ ./$(DEPDIR)/cipher-cfb.Plo ./$(DEPDIR)/cipher-cmac.Plo \
+ ./$(DEPDIR)/cipher-ctr.Plo ./$(DEPDIR)/cipher-eax.Plo \
+ ./$(DEPDIR)/cipher-gcm-armv7-neon.Plo \
+ ./$(DEPDIR)/cipher-gcm-armv8-aarch32-ce.Plo \
+ ./$(DEPDIR)/cipher-gcm-armv8-aarch64-ce.Plo \
+ ./$(DEPDIR)/cipher-gcm-intel-pclmul.Plo \
+ ./$(DEPDIR)/cipher-gcm.Plo ./$(DEPDIR)/cipher-ocb.Plo \
+ ./$(DEPDIR)/cipher-ofb.Plo ./$(DEPDIR)/cipher-poly1305.Plo \
+ ./$(DEPDIR)/cipher-selftest.Plo ./$(DEPDIR)/cipher-xts.Plo \
+ ./$(DEPDIR)/cipher.Plo ./$(DEPDIR)/crc-armv8-aarch64-ce.Plo \
+ ./$(DEPDIR)/crc-armv8-ce.Plo ./$(DEPDIR)/crc-intel-pclmul.Plo \
+ ./$(DEPDIR)/crc-ppc.Plo ./$(DEPDIR)/crc.Plo \
+ ./$(DEPDIR)/des-amd64.Plo ./$(DEPDIR)/des.Plo \
+ ./$(DEPDIR)/dsa-common.Plo ./$(DEPDIR)/dsa.Plo \
+ ./$(DEPDIR)/ecc-curves.Plo ./$(DEPDIR)/ecc-ecdh.Plo \
+ ./$(DEPDIR)/ecc-ecdsa.Plo ./$(DEPDIR)/ecc-eddsa.Plo \
+ ./$(DEPDIR)/ecc-gost.Plo ./$(DEPDIR)/ecc-misc.Plo \
+ ./$(DEPDIR)/ecc-sm2.Plo ./$(DEPDIR)/ecc.Plo \
+ ./$(DEPDIR)/elgamal.Plo ./$(DEPDIR)/gost28147.Plo \
+ ./$(DEPDIR)/gostr3411-94.Plo ./$(DEPDIR)/hash-common.Plo \
+ ./$(DEPDIR)/idea.Plo ./$(DEPDIR)/kdf.Plo \
+ ./$(DEPDIR)/keccak-armv7-neon.Plo ./$(DEPDIR)/keccak.Plo \
+ ./$(DEPDIR)/mac-cmac.Plo ./$(DEPDIR)/mac-gmac.Plo \
+ ./$(DEPDIR)/mac-hmac.Plo ./$(DEPDIR)/mac-poly1305.Plo \
+ ./$(DEPDIR)/mac.Plo ./$(DEPDIR)/md.Plo ./$(DEPDIR)/md4.Plo \
+ ./$(DEPDIR)/md5.Plo ./$(DEPDIR)/poly1305-s390x.Plo \
+ ./$(DEPDIR)/poly1305.Plo ./$(DEPDIR)/primegen.Plo \
+ ./$(DEPDIR)/pubkey-util.Plo ./$(DEPDIR)/pubkey.Plo \
+ ./$(DEPDIR)/rfc2268.Plo ./$(DEPDIR)/rijndael-aarch64.Plo \
+ ./$(DEPDIR)/rijndael-aesni.Plo ./$(DEPDIR)/rijndael-amd64.Plo \
+ ./$(DEPDIR)/rijndael-arm.Plo \
+ ./$(DEPDIR)/rijndael-armv8-aarch32-ce.Plo \
+ ./$(DEPDIR)/rijndael-armv8-aarch64-ce.Plo \
+ ./$(DEPDIR)/rijndael-armv8-ce.Plo \
+ ./$(DEPDIR)/rijndael-padlock.Plo ./$(DEPDIR)/rijndael-ppc.Plo \
+ ./$(DEPDIR)/rijndael-ppc9le.Plo ./$(DEPDIR)/rijndael-s390x.Plo \
+ ./$(DEPDIR)/rijndael-ssse3-amd64-asm.Plo \
+ ./$(DEPDIR)/rijndael-ssse3-amd64.Plo ./$(DEPDIR)/rijndael.Plo \
+ ./$(DEPDIR)/rmd160.Plo ./$(DEPDIR)/rsa-common.Plo \
+ ./$(DEPDIR)/rsa.Plo ./$(DEPDIR)/salsa20-amd64.Plo \
+ ./$(DEPDIR)/salsa20-armv7-neon.Plo ./$(DEPDIR)/salsa20.Plo \
+ ./$(DEPDIR)/scrypt.Plo ./$(DEPDIR)/seed.Plo \
+ ./$(DEPDIR)/serpent-armv7-neon.Plo \
+ ./$(DEPDIR)/serpent-avx2-amd64.Plo \
+ ./$(DEPDIR)/serpent-sse2-amd64.Plo ./$(DEPDIR)/serpent.Plo \
+ ./$(DEPDIR)/sha1-armv7-neon.Plo \
+ ./$(DEPDIR)/sha1-armv8-aarch32-ce.Plo \
+ ./$(DEPDIR)/sha1-armv8-aarch64-ce.Plo \
+ ./$(DEPDIR)/sha1-avx-amd64.Plo \
+ ./$(DEPDIR)/sha1-avx-bmi2-amd64.Plo \
+ ./$(DEPDIR)/sha1-avx2-bmi2-amd64.Plo \
+ ./$(DEPDIR)/sha1-intel-shaext.Plo \
+ ./$(DEPDIR)/sha1-ssse3-amd64.Plo ./$(DEPDIR)/sha1.Plo \
+ ./$(DEPDIR)/sha256-armv8-aarch32-ce.Plo \
+ ./$(DEPDIR)/sha256-armv8-aarch64-ce.Plo \
+ ./$(DEPDIR)/sha256-avx-amd64.Plo \
+ ./$(DEPDIR)/sha256-avx2-bmi2-amd64.Plo \
+ ./$(DEPDIR)/sha256-intel-shaext.Plo ./$(DEPDIR)/sha256-ppc.Plo \
+ ./$(DEPDIR)/sha256-ssse3-amd64.Plo ./$(DEPDIR)/sha256.Plo \
+ ./$(DEPDIR)/sha512-arm.Plo ./$(DEPDIR)/sha512-armv7-neon.Plo \
+ ./$(DEPDIR)/sha512-avx-amd64.Plo \
+ ./$(DEPDIR)/sha512-avx2-bmi2-amd64.Plo \
+ ./$(DEPDIR)/sha512-ppc.Plo ./$(DEPDIR)/sha512-ssse3-amd64.Plo \
+ ./$(DEPDIR)/sha512-ssse3-i386.Plo ./$(DEPDIR)/sha512.Plo \
+ ./$(DEPDIR)/sm3.Plo ./$(DEPDIR)/sm4-aesni-avx-amd64.Plo \
+ ./$(DEPDIR)/sm4-aesni-avx2-amd64.Plo ./$(DEPDIR)/sm4.Plo \
+ ./$(DEPDIR)/stribog.Plo ./$(DEPDIR)/tiger.Plo \
+ ./$(DEPDIR)/twofish-aarch64.Plo ./$(DEPDIR)/twofish-amd64.Plo \
+ ./$(DEPDIR)/twofish-arm.Plo ./$(DEPDIR)/twofish-avx2-amd64.Plo \
+ ./$(DEPDIR)/twofish.Plo ./$(DEPDIR)/whirlpool-sse2-amd64.Plo \
+ ./$(DEPDIR)/whirlpool.Plo
+am__mv = mv -f
+CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CCASFLAGS) $(CCASFLAGS)
+AM_V_CPPAS = $(am__v_CPPAS_@AM_V@)
+am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@)
+am__v_CPPAS_0 = @echo " CPPAS " $@;
+am__v_CPPAS_1 =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libcipher_la_SOURCES) $(EXTRA_libcipher_la_SOURCES)
+DIST_SOURCES = $(libcipher_la_SOURCES) $(EXTRA_libcipher_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# 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
+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-gcm-intel-pclmul.c cipher-gcm-armv7-neon.S \
+ cipher-gcm-armv8-aarch32-ce.S cipher-gcm-armv8-aarch64-ce.S \
+ cipher-poly1305.c \
+ cipher-ocb.c \
+ cipher-xts.c \
+ cipher-eax.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 \
+ poly1305-s390x.S \
+ 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-armv7-neon.S chacha20-aarch64.S \
+ chacha20-ppc.c chacha20-s390x.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 \
+ 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-armv8-ce.c rijndael-armv8-aarch32-ce.S \
+ rijndael-armv8-aarch64-ce.S rijndael-aarch64.S \
+ rijndael-ppc.c rijndael-ppc9le.c \
+ 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 \
+ 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-armv7-neon.S sha512-arm.S \
+ sha512-ppc.c sha512-ssse3-i386.c \
+ sm3.c \
+ 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.S camellia-arm.S camellia-aarch64.S \
+ blake2.c \
+ blake2b-amd64-avx2.S blake2s-amd64-avx.S
+
+@ENABLE_O_FLAG_MUNGING_FALSE@o_flag_munging = cat
+@ENABLE_O_FLAG_MUNGING_TRUE@o_flag_munging = sed -e 's/-O\([2-9sg][2-9sg]*\)/-O1/' -e 's/-Ofast/-O1/g'
+@ENABLE_INSTRUMENTATION_MUNGING_FALSE@instrumentation_munging = cat
+
+# 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.
+@ENABLE_INSTRUMENTATION_MUNGING_TRUE@instrumentation_munging = sed \
+@ENABLE_INSTRUMENTATION_MUNGING_TRUE@ -e 's/-fsanitize[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g' \
+@ENABLE_INSTRUMENTATION_MUNGING_TRUE@ -e 's/-fprofile[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g' \
+@ENABLE_INSTRUMENTATION_MUNGING_TRUE@ -e 's/-fcoverage[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g'
+
+@ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_FALSE@ppc_vcrypto_cflags =
+@ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_TRUE@ppc_vcrypto_cflags = -maltivec -mvsx -mcrypto
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cipher/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cipher/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libcipher.la: $(libcipher_la_OBJECTS) $(libcipher_la_DEPENDENCIES) $(EXTRA_libcipher_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libcipher_la_OBJECTS) $(libcipher_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arcfour-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arcfour.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blake2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blake2b-amd64-avx2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blake2s-amd64-avx.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish-arm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-aarch64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-aesni-avx-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-aesni-avx2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-arm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-glue.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast5-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast5-arm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast5.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-aarch64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-amd64-avx2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-amd64-ssse3.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-armv7-neon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-ppc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20-s390x.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chacha20.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-aeswrap.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-cbc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ccm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-cfb.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-cmac.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ctr.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-eax.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-gcm-armv7-neon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-gcm-armv8-aarch32-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-gcm-armv8-aarch64-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-gcm-intel-pclmul.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-gcm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ocb.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ofb.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-poly1305.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-selftest.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-xts.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc-armv8-aarch64-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc-armv8-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc-intel-pclmul.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc-ppc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa-common.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-curves.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-ecdh.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-ecdsa.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-eddsa.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-gost.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-misc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-sm2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elgamal.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gost28147.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gostr3411-94.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash-common.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idea.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdf.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keccak-armv7-neon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keccak.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac-cmac.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac-gmac.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac-hmac.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac-poly1305.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md4.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poly1305-s390x.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poly1305.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/primegen.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey-util.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc2268.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-aarch64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-aesni.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-arm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-armv8-aarch32-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-armv8-aarch64-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-armv8-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-padlock.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-ppc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-ppc9le.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-s390x.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-ssse3-amd64-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-ssse3-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmd160.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa-common.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/salsa20-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/salsa20-armv7-neon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/salsa20.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scrypt.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seed.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent-armv7-neon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent-avx2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent-sse2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-armv7-neon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-armv8-aarch32-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-armv8-aarch64-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-avx-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-avx-bmi2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-avx2-bmi2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-intel-shaext.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1-ssse3-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-armv8-aarch32-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-armv8-aarch64-ce.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-avx-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-avx2-bmi2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-intel-shaext.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-ppc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256-ssse3-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-arm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-armv7-neon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-avx-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-avx2-bmi2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-ppc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-ssse3-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-ssse3-i386.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm3.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm4-aesni-avx-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm4-aesni-avx2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm4.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stribog.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiger.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish-aarch64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish-arm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish-avx2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whirlpool-sse2-amd64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whirlpool.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.S.o:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $<
+
+.S.obj:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.S.lo:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $<
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/arcfour-amd64.Plo
+ -rm -f ./$(DEPDIR)/arcfour.Plo
+ -rm -f ./$(DEPDIR)/blake2.Plo
+ -rm -f ./$(DEPDIR)/blake2b-amd64-avx2.Plo
+ -rm -f ./$(DEPDIR)/blake2s-amd64-avx.Plo
+ -rm -f ./$(DEPDIR)/blowfish-amd64.Plo
+ -rm -f ./$(DEPDIR)/blowfish-arm.Plo
+ -rm -f ./$(DEPDIR)/blowfish.Plo
+ -rm -f ./$(DEPDIR)/camellia-aarch64.Plo
+ -rm -f ./$(DEPDIR)/camellia-aesni-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/camellia-aesni-avx2-amd64.Plo
+ -rm -f ./$(DEPDIR)/camellia-arm.Plo
+ -rm -f ./$(DEPDIR)/camellia-glue.Plo
+ -rm -f ./$(DEPDIR)/camellia.Plo
+ -rm -f ./$(DEPDIR)/cast5-amd64.Plo
+ -rm -f ./$(DEPDIR)/cast5-arm.Plo
+ -rm -f ./$(DEPDIR)/cast5.Plo
+ -rm -f ./$(DEPDIR)/chacha20-aarch64.Plo
+ -rm -f ./$(DEPDIR)/chacha20-amd64-avx2.Plo
+ -rm -f ./$(DEPDIR)/chacha20-amd64-ssse3.Plo
+ -rm -f ./$(DEPDIR)/chacha20-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/chacha20-ppc.Plo
+ -rm -f ./$(DEPDIR)/chacha20-s390x.Plo
+ -rm -f ./$(DEPDIR)/chacha20.Plo
+ -rm -f ./$(DEPDIR)/cipher-aeswrap.Plo
+ -rm -f ./$(DEPDIR)/cipher-cbc.Plo
+ -rm -f ./$(DEPDIR)/cipher-ccm.Plo
+ -rm -f ./$(DEPDIR)/cipher-cfb.Plo
+ -rm -f ./$(DEPDIR)/cipher-cmac.Plo
+ -rm -f ./$(DEPDIR)/cipher-ctr.Plo
+ -rm -f ./$(DEPDIR)/cipher-eax.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm-armv8-aarch32-ce.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm-intel-pclmul.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm.Plo
+ -rm -f ./$(DEPDIR)/cipher-ocb.Plo
+ -rm -f ./$(DEPDIR)/cipher-ofb.Plo
+ -rm -f ./$(DEPDIR)/cipher-poly1305.Plo
+ -rm -f ./$(DEPDIR)/cipher-selftest.Plo
+ -rm -f ./$(DEPDIR)/cipher-xts.Plo
+ -rm -f ./$(DEPDIR)/cipher.Plo
+ -rm -f ./$(DEPDIR)/crc-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/crc-armv8-ce.Plo
+ -rm -f ./$(DEPDIR)/crc-intel-pclmul.Plo
+ -rm -f ./$(DEPDIR)/crc-ppc.Plo
+ -rm -f ./$(DEPDIR)/crc.Plo
+ -rm -f ./$(DEPDIR)/des-amd64.Plo
+ -rm -f ./$(DEPDIR)/des.Plo
+ -rm -f ./$(DEPDIR)/dsa-common.Plo
+ -rm -f ./$(DEPDIR)/dsa.Plo
+ -rm -f ./$(DEPDIR)/ecc-curves.Plo
+ -rm -f ./$(DEPDIR)/ecc-ecdh.Plo
+ -rm -f ./$(DEPDIR)/ecc-ecdsa.Plo
+ -rm -f ./$(DEPDIR)/ecc-eddsa.Plo
+ -rm -f ./$(DEPDIR)/ecc-gost.Plo
+ -rm -f ./$(DEPDIR)/ecc-misc.Plo
+ -rm -f ./$(DEPDIR)/ecc-sm2.Plo
+ -rm -f ./$(DEPDIR)/ecc.Plo
+ -rm -f ./$(DEPDIR)/elgamal.Plo
+ -rm -f ./$(DEPDIR)/gost28147.Plo
+ -rm -f ./$(DEPDIR)/gostr3411-94.Plo
+ -rm -f ./$(DEPDIR)/hash-common.Plo
+ -rm -f ./$(DEPDIR)/idea.Plo
+ -rm -f ./$(DEPDIR)/kdf.Plo
+ -rm -f ./$(DEPDIR)/keccak-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/keccak.Plo
+ -rm -f ./$(DEPDIR)/mac-cmac.Plo
+ -rm -f ./$(DEPDIR)/mac-gmac.Plo
+ -rm -f ./$(DEPDIR)/mac-hmac.Plo
+ -rm -f ./$(DEPDIR)/mac-poly1305.Plo
+ -rm -f ./$(DEPDIR)/mac.Plo
+ -rm -f ./$(DEPDIR)/md.Plo
+ -rm -f ./$(DEPDIR)/md4.Plo
+ -rm -f ./$(DEPDIR)/md5.Plo
+ -rm -f ./$(DEPDIR)/poly1305-s390x.Plo
+ -rm -f ./$(DEPDIR)/poly1305.Plo
+ -rm -f ./$(DEPDIR)/primegen.Plo
+ -rm -f ./$(DEPDIR)/pubkey-util.Plo
+ -rm -f ./$(DEPDIR)/pubkey.Plo
+ -rm -f ./$(DEPDIR)/rfc2268.Plo
+ -rm -f ./$(DEPDIR)/rijndael-aarch64.Plo
+ -rm -f ./$(DEPDIR)/rijndael-aesni.Plo
+ -rm -f ./$(DEPDIR)/rijndael-amd64.Plo
+ -rm -f ./$(DEPDIR)/rijndael-arm.Plo
+ -rm -f ./$(DEPDIR)/rijndael-armv8-aarch32-ce.Plo
+ -rm -f ./$(DEPDIR)/rijndael-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/rijndael-armv8-ce.Plo
+ -rm -f ./$(DEPDIR)/rijndael-padlock.Plo
+ -rm -f ./$(DEPDIR)/rijndael-ppc.Plo
+ -rm -f ./$(DEPDIR)/rijndael-ppc9le.Plo
+ -rm -f ./$(DEPDIR)/rijndael-s390x.Plo
+ -rm -f ./$(DEPDIR)/rijndael-ssse3-amd64-asm.Plo
+ -rm -f ./$(DEPDIR)/rijndael-ssse3-amd64.Plo
+ -rm -f ./$(DEPDIR)/rijndael.Plo
+ -rm -f ./$(DEPDIR)/rmd160.Plo
+ -rm -f ./$(DEPDIR)/rsa-common.Plo
+ -rm -f ./$(DEPDIR)/rsa.Plo
+ -rm -f ./$(DEPDIR)/salsa20-amd64.Plo
+ -rm -f ./$(DEPDIR)/salsa20-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/salsa20.Plo
+ -rm -f ./$(DEPDIR)/scrypt.Plo
+ -rm -f ./$(DEPDIR)/seed.Plo
+ -rm -f ./$(DEPDIR)/serpent-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/serpent-avx2-amd64.Plo
+ -rm -f ./$(DEPDIR)/serpent-sse2-amd64.Plo
+ -rm -f ./$(DEPDIR)/serpent.Plo
+ -rm -f ./$(DEPDIR)/sha1-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/sha1-armv8-aarch32-ce.Plo
+ -rm -f ./$(DEPDIR)/sha1-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/sha1-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha1-avx-bmi2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha1-avx2-bmi2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha1-intel-shaext.Plo
+ -rm -f ./$(DEPDIR)/sha1-ssse3-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha1.Plo
+ -rm -f ./$(DEPDIR)/sha256-armv8-aarch32-ce.Plo
+ -rm -f ./$(DEPDIR)/sha256-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/sha256-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha256-avx2-bmi2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha256-intel-shaext.Plo
+ -rm -f ./$(DEPDIR)/sha256-ppc.Plo
+ -rm -f ./$(DEPDIR)/sha256-ssse3-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha256.Plo
+ -rm -f ./$(DEPDIR)/sha512-arm.Plo
+ -rm -f ./$(DEPDIR)/sha512-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/sha512-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha512-avx2-bmi2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha512-ppc.Plo
+ -rm -f ./$(DEPDIR)/sha512-ssse3-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha512-ssse3-i386.Plo
+ -rm -f ./$(DEPDIR)/sha512.Plo
+ -rm -f ./$(DEPDIR)/sm3.Plo
+ -rm -f ./$(DEPDIR)/sm4-aesni-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/sm4-aesni-avx2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sm4.Plo
+ -rm -f ./$(DEPDIR)/stribog.Plo
+ -rm -f ./$(DEPDIR)/tiger.Plo
+ -rm -f ./$(DEPDIR)/twofish-aarch64.Plo
+ -rm -f ./$(DEPDIR)/twofish-amd64.Plo
+ -rm -f ./$(DEPDIR)/twofish-arm.Plo
+ -rm -f ./$(DEPDIR)/twofish-avx2-amd64.Plo
+ -rm -f ./$(DEPDIR)/twofish.Plo
+ -rm -f ./$(DEPDIR)/whirlpool-sse2-amd64.Plo
+ -rm -f ./$(DEPDIR)/whirlpool.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/arcfour-amd64.Plo
+ -rm -f ./$(DEPDIR)/arcfour.Plo
+ -rm -f ./$(DEPDIR)/blake2.Plo
+ -rm -f ./$(DEPDIR)/blake2b-amd64-avx2.Plo
+ -rm -f ./$(DEPDIR)/blake2s-amd64-avx.Plo
+ -rm -f ./$(DEPDIR)/blowfish-amd64.Plo
+ -rm -f ./$(DEPDIR)/blowfish-arm.Plo
+ -rm -f ./$(DEPDIR)/blowfish.Plo
+ -rm -f ./$(DEPDIR)/camellia-aarch64.Plo
+ -rm -f ./$(DEPDIR)/camellia-aesni-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/camellia-aesni-avx2-amd64.Plo
+ -rm -f ./$(DEPDIR)/camellia-arm.Plo
+ -rm -f ./$(DEPDIR)/camellia-glue.Plo
+ -rm -f ./$(DEPDIR)/camellia.Plo
+ -rm -f ./$(DEPDIR)/cast5-amd64.Plo
+ -rm -f ./$(DEPDIR)/cast5-arm.Plo
+ -rm -f ./$(DEPDIR)/cast5.Plo
+ -rm -f ./$(DEPDIR)/chacha20-aarch64.Plo
+ -rm -f ./$(DEPDIR)/chacha20-amd64-avx2.Plo
+ -rm -f ./$(DEPDIR)/chacha20-amd64-ssse3.Plo
+ -rm -f ./$(DEPDIR)/chacha20-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/chacha20-ppc.Plo
+ -rm -f ./$(DEPDIR)/chacha20-s390x.Plo
+ -rm -f ./$(DEPDIR)/chacha20.Plo
+ -rm -f ./$(DEPDIR)/cipher-aeswrap.Plo
+ -rm -f ./$(DEPDIR)/cipher-cbc.Plo
+ -rm -f ./$(DEPDIR)/cipher-ccm.Plo
+ -rm -f ./$(DEPDIR)/cipher-cfb.Plo
+ -rm -f ./$(DEPDIR)/cipher-cmac.Plo
+ -rm -f ./$(DEPDIR)/cipher-ctr.Plo
+ -rm -f ./$(DEPDIR)/cipher-eax.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm-armv8-aarch32-ce.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm-intel-pclmul.Plo
+ -rm -f ./$(DEPDIR)/cipher-gcm.Plo
+ -rm -f ./$(DEPDIR)/cipher-ocb.Plo
+ -rm -f ./$(DEPDIR)/cipher-ofb.Plo
+ -rm -f ./$(DEPDIR)/cipher-poly1305.Plo
+ -rm -f ./$(DEPDIR)/cipher-selftest.Plo
+ -rm -f ./$(DEPDIR)/cipher-xts.Plo
+ -rm -f ./$(DEPDIR)/cipher.Plo
+ -rm -f ./$(DEPDIR)/crc-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/crc-armv8-ce.Plo
+ -rm -f ./$(DEPDIR)/crc-intel-pclmul.Plo
+ -rm -f ./$(DEPDIR)/crc-ppc.Plo
+ -rm -f ./$(DEPDIR)/crc.Plo
+ -rm -f ./$(DEPDIR)/des-amd64.Plo
+ -rm -f ./$(DEPDIR)/des.Plo
+ -rm -f ./$(DEPDIR)/dsa-common.Plo
+ -rm -f ./$(DEPDIR)/dsa.Plo
+ -rm -f ./$(DEPDIR)/ecc-curves.Plo
+ -rm -f ./$(DEPDIR)/ecc-ecdh.Plo
+ -rm -f ./$(DEPDIR)/ecc-ecdsa.Plo
+ -rm -f ./$(DEPDIR)/ecc-eddsa.Plo
+ -rm -f ./$(DEPDIR)/ecc-gost.Plo
+ -rm -f ./$(DEPDIR)/ecc-misc.Plo
+ -rm -f ./$(DEPDIR)/ecc-sm2.Plo
+ -rm -f ./$(DEPDIR)/ecc.Plo
+ -rm -f ./$(DEPDIR)/elgamal.Plo
+ -rm -f ./$(DEPDIR)/gost28147.Plo
+ -rm -f ./$(DEPDIR)/gostr3411-94.Plo
+ -rm -f ./$(DEPDIR)/hash-common.Plo
+ -rm -f ./$(DEPDIR)/idea.Plo
+ -rm -f ./$(DEPDIR)/kdf.Plo
+ -rm -f ./$(DEPDIR)/keccak-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/keccak.Plo
+ -rm -f ./$(DEPDIR)/mac-cmac.Plo
+ -rm -f ./$(DEPDIR)/mac-gmac.Plo
+ -rm -f ./$(DEPDIR)/mac-hmac.Plo
+ -rm -f ./$(DEPDIR)/mac-poly1305.Plo
+ -rm -f ./$(DEPDIR)/mac.Plo
+ -rm -f ./$(DEPDIR)/md.Plo
+ -rm -f ./$(DEPDIR)/md4.Plo
+ -rm -f ./$(DEPDIR)/md5.Plo
+ -rm -f ./$(DEPDIR)/poly1305-s390x.Plo
+ -rm -f ./$(DEPDIR)/poly1305.Plo
+ -rm -f ./$(DEPDIR)/primegen.Plo
+ -rm -f ./$(DEPDIR)/pubkey-util.Plo
+ -rm -f ./$(DEPDIR)/pubkey.Plo
+ -rm -f ./$(DEPDIR)/rfc2268.Plo
+ -rm -f ./$(DEPDIR)/rijndael-aarch64.Plo
+ -rm -f ./$(DEPDIR)/rijndael-aesni.Plo
+ -rm -f ./$(DEPDIR)/rijndael-amd64.Plo
+ -rm -f ./$(DEPDIR)/rijndael-arm.Plo
+ -rm -f ./$(DEPDIR)/rijndael-armv8-aarch32-ce.Plo
+ -rm -f ./$(DEPDIR)/rijndael-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/rijndael-armv8-ce.Plo
+ -rm -f ./$(DEPDIR)/rijndael-padlock.Plo
+ -rm -f ./$(DEPDIR)/rijndael-ppc.Plo
+ -rm -f ./$(DEPDIR)/rijndael-ppc9le.Plo
+ -rm -f ./$(DEPDIR)/rijndael-s390x.Plo
+ -rm -f ./$(DEPDIR)/rijndael-ssse3-amd64-asm.Plo
+ -rm -f ./$(DEPDIR)/rijndael-ssse3-amd64.Plo
+ -rm -f ./$(DEPDIR)/rijndael.Plo
+ -rm -f ./$(DEPDIR)/rmd160.Plo
+ -rm -f ./$(DEPDIR)/rsa-common.Plo
+ -rm -f ./$(DEPDIR)/rsa.Plo
+ -rm -f ./$(DEPDIR)/salsa20-amd64.Plo
+ -rm -f ./$(DEPDIR)/salsa20-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/salsa20.Plo
+ -rm -f ./$(DEPDIR)/scrypt.Plo
+ -rm -f ./$(DEPDIR)/seed.Plo
+ -rm -f ./$(DEPDIR)/serpent-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/serpent-avx2-amd64.Plo
+ -rm -f ./$(DEPDIR)/serpent-sse2-amd64.Plo
+ -rm -f ./$(DEPDIR)/serpent.Plo
+ -rm -f ./$(DEPDIR)/sha1-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/sha1-armv8-aarch32-ce.Plo
+ -rm -f ./$(DEPDIR)/sha1-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/sha1-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha1-avx-bmi2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha1-avx2-bmi2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha1-intel-shaext.Plo
+ -rm -f ./$(DEPDIR)/sha1-ssse3-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha1.Plo
+ -rm -f ./$(DEPDIR)/sha256-armv8-aarch32-ce.Plo
+ -rm -f ./$(DEPDIR)/sha256-armv8-aarch64-ce.Plo
+ -rm -f ./$(DEPDIR)/sha256-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha256-avx2-bmi2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha256-intel-shaext.Plo
+ -rm -f ./$(DEPDIR)/sha256-ppc.Plo
+ -rm -f ./$(DEPDIR)/sha256-ssse3-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha256.Plo
+ -rm -f ./$(DEPDIR)/sha512-arm.Plo
+ -rm -f ./$(DEPDIR)/sha512-armv7-neon.Plo
+ -rm -f ./$(DEPDIR)/sha512-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha512-avx2-bmi2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha512-ppc.Plo
+ -rm -f ./$(DEPDIR)/sha512-ssse3-amd64.Plo
+ -rm -f ./$(DEPDIR)/sha512-ssse3-i386.Plo
+ -rm -f ./$(DEPDIR)/sha512.Plo
+ -rm -f ./$(DEPDIR)/sm3.Plo
+ -rm -f ./$(DEPDIR)/sm4-aesni-avx-amd64.Plo
+ -rm -f ./$(DEPDIR)/sm4-aesni-avx2-amd64.Plo
+ -rm -f ./$(DEPDIR)/sm4.Plo
+ -rm -f ./$(DEPDIR)/stribog.Plo
+ -rm -f ./$(DEPDIR)/tiger.Plo
+ -rm -f ./$(DEPDIR)/twofish-aarch64.Plo
+ -rm -f ./$(DEPDIR)/twofish-amd64.Plo
+ -rm -f ./$(DEPDIR)/twofish-arm.Plo
+ -rm -f ./$(DEPDIR)/twofish-avx2-amd64.Plo
+ -rm -f ./$(DEPDIR)/twofish.Plo
+ -rm -f ./$(DEPDIR)/whirlpool-sse2-amd64.Plo
+ -rm -f ./$(DEPDIR)/whirlpool.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+gost28147.lo: gost-sb.h
+gost-sb.h: gost-s-box
+ ./gost-s-box $@
+
+gost-s-box: gost-s-box.c
+ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) \
+ $(CPPFLAGS_FOR_BUILD)-o $@ $(srcdir)/gost-s-box.c
+
+# 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) `
+
+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) `
+
+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) `
+
+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) `
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/cipher/arcfour-amd64.S b/comm/third_party/libgcrypt/cipher/arcfour-amd64.S
new file mode 100644
index 0000000000..221dfeff77
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/arcfour-amd64.S
@@ -0,0 +1,108 @@
+/*
+** RC4 implementation optimized for AMD64.
+**
+** Author: Marc Bevand <bevand_m (at) epita.fr>
+** Licence: I hereby disclaim the copyright on this code and place it
+** in the public domain.
+**
+** The throughput achieved by this code is about 320 MBytes/sec, on
+** a 1.8 GHz AMD Opteron (rev C0) processor.
+**
+** 2013/12/20 <jussi.kivilinna@iki.fi>:
+** - Integrated to libgcrypt
+** - 4.18 cycles/byte on Intel i5-4570
+*/
+
+#ifdef __x86_64__
+#include <config.h>
+#if defined(USE_ARCFOUR) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#include "asm-common-amd64.h"
+
+.text
+.align 16
+.globl _gcry_arcfour_amd64
+ELF(.type _gcry_arcfour_amd64,@function)
+_gcry_arcfour_amd64:
+ CFI_STARTPROC()
+ ENTER_SYSV_FUNC_PARAMS_0_4
+ push %rbp
+ CFI_PUSH(%rbp)
+ push %rbx
+ CFI_PUSH(%rbx)
+ mov %rdi, %rbp # key = ARG(key)
+ mov %rsi, %rbx # rbx = ARG(len)
+ mov %rdx, %rsi # in = ARG(in)
+ mov %rcx, %rdi # out = ARG(out)
+ mov (4*256)(%rbp), %ecx # x = key->x
+ mov (4*256+4)(%rbp),%edx # y = key->y
+ inc %rcx # x++
+ and $255, %rcx # x &= 0xff
+ lea -8(%rbx,%rsi), %rbx # rbx = in+len-8
+ mov %rbx, %r9 # tmp = in+len-8
+ mov (%rbp,%rcx,4), %eax # tx = d[x]
+ cmp %rsi, %rbx # cmp in with in+len-8
+ jl .Lend # jump if (in+len-8 < in)
+
+.Lstart:
+ add $8, %rsi # increment in
+ add $8, %rdi # increment out
+
+ # generate the next 8 bytes of the rc4 stream into %r8
+ mov $8, %r11 # byte counter
+1: add %al, %dl # y += tx
+ mov (%rbp,%rdx,4), %ebx # ty = d[y]
+ mov %ebx, (%rbp,%rcx,4) # d[x] = ty
+ add %al, %bl # val = ty + tx
+ mov %eax, (%rbp,%rdx,4) # d[y] = tx
+ inc %cl # x++ (NEXT ROUND)
+ mov (%rbp,%rcx,4), %eax # tx = d[x] (NEXT ROUND)
+ shl $8, %r8
+ movb (%rbp,%rbx,4), %r8b # val = d[val]
+ dec %r11b
+ jnz 1b
+
+ # xor 8 bytes
+ bswap %r8
+ xor -8(%rsi), %r8
+ cmp %r9, %rsi # cmp in+len-8 with in
+ mov %r8, -8(%rdi)
+ jle .Lstart # jump if (in <= in+len-8)
+
+.Lend:
+ add $8, %r9 # tmp = in+len
+
+ # handle the last bytes, one by one
+1: cmp %rsi, %r9 # cmp in with in+len
+ jle .Lfinished # jump if (in+len <= in)
+ add %al, %dl # y += tx
+ mov (%rbp,%rdx,4), %ebx # ty = d[y]
+ mov %ebx, (%rbp,%rcx,4) # d[x] = ty
+ add %al, %bl # val = ty + tx
+ mov %eax, (%rbp,%rdx,4) # d[y] = tx
+ inc %cl # x++ (NEXT ROUND)
+ mov (%rbp,%rcx,4), %eax # tx = d[x] (NEXT ROUND)
+ movb (%rbp,%rbx,4), %r8b # val = d[val]
+ xor (%rsi), %r8b # xor 1 byte
+ movb %r8b, (%rdi)
+ inc %rsi # in++
+ inc %rdi # out++
+ jmp 1b
+
+.Lfinished:
+ dec %rcx # x--
+ movb %cl, (4*256)(%rbp) # key->y = y
+ movb %dl, (4*256+4)(%rbp) # key->x = x
+ pop %rbx
+ CFI_POP(%rbx)
+ pop %rbp
+ CFI_POP(%rbp)
+ EXIT_SYSV_FUNC
+ ret
+ CFI_ENDPROC()
+.L__gcry_arcfour_amd64_end:
+ELF(.size _gcry_arcfour_amd64,.L__gcry_arcfour_amd64_end-_gcry_arcfour_amd64)
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/arcfour.c b/comm/third_party/libgcrypt/cipher/arcfour.c
new file mode 100644
index 0000000000..353de00bd7
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/arcfour.c
@@ -0,0 +1,216 @@
+/* arcfour.c - The arcfour stream cipher
+ * Copyright (C) 2000, 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 397 ff.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "cipher-internal.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
+
+static const char *selftest(void);
+
+#ifdef USE_AMD64_ASM
+
+typedef struct {
+ u32 sbox[256];
+ u32 idx_i, idx_j;
+} ARCFOUR_context;
+
+void _gcry_arcfour_amd64(void *key, size_t len, const byte *indata,
+ byte *outdata);
+
+static void
+encrypt_stream (void *context,
+ byte *outbuf, const byte *inbuf, size_t length)
+{
+ _gcry_arcfour_amd64 (context, length, inbuf, outbuf );
+}
+
+#else /*!USE_AMD64_ASM*/
+
+typedef struct {
+ byte sbox[256];
+ int idx_i, idx_j;
+} ARCFOUR_context;
+
+static void
+do_encrypt_stream( ARCFOUR_context *ctx,
+ byte *outbuf, const byte *inbuf, size_t length )
+{
+#ifndef __i386__
+ register unsigned int i = ctx->idx_i;
+ register byte j = ctx->idx_j;
+ register byte *sbox = ctx->sbox;
+ register byte t, u;
+
+ while ( length-- )
+ {
+ i++;
+ t = sbox[(byte)i];
+ j += t;
+ u = sbox[j];
+ sbox[(byte)i] = u;
+ u += t;
+ sbox[j] = t;
+ *outbuf++ = sbox[u] ^ *inbuf++;
+ }
+
+ ctx->idx_i = (byte)i;
+ ctx->idx_j = (byte)j;
+#else /*__i386__*/
+ /* Old implementation of arcfour is faster on i386 than the version above.
+ * This is because version above increases register pressure which on i386
+ * would push some of the variables to memory/stack. Therefore keep this
+ * version for i386 to avoid regressing performance. */
+ register int i = ctx->idx_i;
+ register int j = ctx->idx_j;
+ register byte *sbox = ctx->sbox;
+ register int t;
+
+ while ( length-- )
+ {
+ i++;
+ i = i & 255; /* The and-op seems to be faster than the mod-op. */
+ j += sbox[i];
+ j &= 255;
+ t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t;
+ *outbuf++ = *inbuf++ ^ sbox[(sbox[i] + sbox[j]) & 255];
+ }
+
+ ctx->idx_i = i;
+ ctx->idx_j = j;
+#endif
+}
+
+static void
+encrypt_stream (void *context,
+ byte *outbuf, const byte *inbuf, size_t length)
+{
+ ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+ do_encrypt_stream (ctx, outbuf, inbuf, length );
+ _gcry_burn_stack (64);
+}
+
+#endif /*!USE_AMD64_ASM*/
+
+
+static gcry_err_code_t
+do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
+{
+ static int initialized;
+ static const char* selftest_failed;
+ int i, j;
+ byte karr[256];
+ ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+
+ if (!initialized )
+ {
+ initialized = 1;
+ selftest_failed = selftest();
+ if( selftest_failed )
+ log_error ("ARCFOUR selftest failed (%s)\n", selftest_failed );
+ }
+ if( selftest_failed )
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if( keylen < 40/8 ) /* we want at least 40 bits */
+ return GPG_ERR_INV_KEYLEN;
+
+ ctx->idx_i = ctx->idx_j = 0;
+ for (i=0; i < 256; i++ )
+ ctx->sbox[i] = i;
+ for (i=j=0; i < 256; i++,j++ )
+ {
+ if (j >= keylen)
+ j = 0;
+ karr[i] = key[j];
+ }
+ for (i=j=0; i < 256; i++ )
+ {
+ int t;
+ j = (j + ctx->sbox[i] + karr[i]) & 255;
+ t = ctx->sbox[i];
+ ctx->sbox[i] = ctx->sbox[j];
+ ctx->sbox[j] = t;
+ }
+ wipememory( karr, sizeof(karr) );
+
+ return GPG_ERR_NO_ERROR;
+}
+
+static gcry_err_code_t
+arcfour_setkey ( void *context, const byte *key, unsigned int keylen,
+ cipher_bulk_ops_t *bulk_ops )
+{
+ ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+ gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen );
+ (void)bulk_ops;
+ return rc;
+}
+
+
+static const char*
+selftest(void)
+{
+ ARCFOUR_context ctx;
+ byte scratch[16];
+
+ /* Test vector from Cryptlib labeled there: "from the
+ State/Commerce Department". */
+ static const byte key_1[] =
+ { 0x61, 0x8A, 0x63, 0xD2, 0xFB };
+ static const byte plaintext_1[] =
+ { 0xDC, 0xEE, 0x4C, 0xF9, 0x2C };
+ static const byte ciphertext_1[] =
+ { 0xF1, 0x38, 0x29, 0xC9, 0xDE };
+
+ arcfour_setkey( &ctx, key_1, sizeof(key_1), NULL);
+ encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1));
+ if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1)))
+ return "Arcfour encryption test 1 failed.";
+ arcfour_setkey( &ctx, key_1, sizeof(key_1), NULL);
+ encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */
+ if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1)))
+ return "Arcfour decryption test 1 failed.";
+ return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_arcfour =
+ {
+ GCRY_CIPHER_ARCFOUR, {0, 0},
+ "ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
+ arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
+ };
diff --git a/comm/third_party/libgcrypt/cipher/asm-common-aarch64.h b/comm/third_party/libgcrypt/cipher/asm-common-aarch64.h
new file mode 100644
index 0000000000..cf0afe1f87
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/asm-common-aarch64.h
@@ -0,0 +1,104 @@
+/* asm-common-aarch64.h - Common macros for AArch64 assembly
+ *
+ * Copyright (C) 2018 Martin Storsjö <martin@martin.st>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ASM_COMMON_AARCH64_H
+#define GCRY_ASM_COMMON_AARCH64_H
+
+#include <config.h>
+
+#ifdef HAVE_GCC_ASM_ELF_DIRECTIVES
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+#ifdef __APPLE__
+#define GET_DATA_POINTER(reg, name) \
+ adrp reg, name@GOTPAGE ; \
+ add reg, reg, name@GOTPAGEOFF ;
+#elif defined(_WIN32)
+#define GET_DATA_POINTER(reg, name) \
+ adrp reg, name ; \
+ add reg, reg, #:lo12:name ;
+#else
+#define GET_DATA_POINTER(reg, name) \
+ adrp reg, :got:name ; \
+ ldr reg, [reg, #:got_lo12:name] ;
+#endif
+
+#ifdef HAVE_GCC_ASM_CFI_DIRECTIVES
+/* CFI directives to emit DWARF stack unwinding information. */
+# define CFI_STARTPROC() .cfi_startproc
+# define CFI_ENDPROC() .cfi_endproc
+# define CFI_REMEMBER_STATE() .cfi_remember_state
+# define CFI_RESTORE_STATE() .cfi_restore_state
+# define CFI_ADJUST_CFA_OFFSET(off) .cfi_adjust_cfa_offset off
+# define CFI_REL_OFFSET(reg,off) .cfi_rel_offset reg, off
+# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
+# define CFI_REGISTER(ro,rn) .cfi_register ro, rn
+# define CFI_RESTORE(reg) .cfi_restore reg
+
+/* CFA expressions are used for pointing CFA and registers to
+ * SP relative offsets. */
+# define DW_REGNO_SP 31
+
+/* Fixed length encoding used for integers for now. */
+# define DW_SLEB128_7BIT(value) \
+ 0x00|((value) & 0x7f)
+# define DW_SLEB128_28BIT(value) \
+ 0x80|((value)&0x7f), \
+ 0x80|(((value)>>7)&0x7f), \
+ 0x80|(((value)>>14)&0x7f), \
+ 0x00|(((value)>>21)&0x7f)
+
+# define CFI_CFA_ON_STACK(rsp_offs,cfa_depth) \
+ .cfi_escape \
+ 0x0f, /* DW_CFA_def_cfa_expression */ \
+ DW_SLEB128_7BIT(11), /* length */ \
+ 0x8f, /* DW_OP_breg31, rsp + constant */ \
+ DW_SLEB128_28BIT(rsp_offs), \
+ 0x06, /* DW_OP_deref */ \
+ 0x23, /* DW_OP_plus_constu */ \
+ DW_SLEB128_28BIT((cfa_depth)+8)
+
+# define CFI_REG_ON_STACK(regno,rsp_offs) \
+ .cfi_escape \
+ 0x10, /* DW_CFA_expression */ \
+ DW_SLEB128_7BIT(regno), \
+ DW_SLEB128_7BIT(5), /* length */ \
+ 0x8f, /* DW_OP_breg31, rsp + constant */ \
+ DW_SLEB128_28BIT(rsp_offs)
+
+#else
+# define CFI_STARTPROC()
+# define CFI_ENDPROC()
+# define CFI_REMEMBER_STATE()
+# define CFI_RESTORE_STATE()
+# define CFI_ADJUST_CFA_OFFSET(off)
+# define CFI_REL_OFFSET(reg,off)
+# define CFI_DEF_CFA_REGISTER(reg)
+# define CFI_REGISTER(ro,rn)
+# define CFI_RESTORE(reg)
+
+# define CFI_CFA_ON_STACK(rsp_offs,cfa_depth)
+# define CFI_REG_ON_STACK(reg,rsp_offs)
+#endif
+
+#endif /* GCRY_ASM_COMMON_AARCH64_H */
diff --git a/comm/third_party/libgcrypt/cipher/asm-common-amd64.h b/comm/third_party/libgcrypt/cipher/asm-common-amd64.h
new file mode 100644
index 0000000000..9d4a028a04
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/asm-common-amd64.h
@@ -0,0 +1,189 @@
+/* asm-common-amd64.h - Common macros for AMD64 assembly
+ *
+ * Copyright (C) 2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ASM_COMMON_AMD64_H
+#define GCRY_ASM_COMMON_AMD64_H
+
+#include <config.h>
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+#ifdef __PIC__
+# define rRIP (%rip)
+#else
+# define rRIP
+#endif
+
+#ifdef __PIC__
+# define RIP %rip
+#else
+# define RIP
+#endif
+
+#ifdef __PIC__
+# define ADD_RIP +rip
+#else
+# define ADD_RIP
+#endif
+
+#if defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS) || !defined(__PIC__)
+# define GET_EXTERN_POINTER(name, reg) movabsq $name, reg
+#else
+# ifdef __code_model_large__
+# define GET_EXTERN_POINTER(name, reg) \
+ pushq %r15; \
+ pushq %r14; \
+ 1: leaq 1b(%rip), reg; \
+ movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \
+ movabsq $name@GOT, %r15; \
+ addq %r14, reg; \
+ popq %r14; \
+ movq (reg, %r15), reg; \
+ popq %r15;
+# else
+# define GET_EXTERN_POINTER(name, reg) movq name@GOTPCREL(%rip), reg
+# endif
+#endif
+
+#ifdef HAVE_GCC_ASM_CFI_DIRECTIVES
+/* CFI directives to emit DWARF stack unwinding information. */
+# define CFI_STARTPROC() .cfi_startproc
+# define CFI_ENDPROC() .cfi_endproc
+# define CFI_REMEMBER_STATE() .cfi_remember_state
+# define CFI_RESTORE_STATE() .cfi_restore_state
+# define CFI_ADJUST_CFA_OFFSET(off) .cfi_adjust_cfa_offset off
+# define CFI_REL_OFFSET(reg,off) .cfi_rel_offset reg, off
+# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
+# define CFI_REGISTER(ro,rn) .cfi_register ro, rn
+# define CFI_RESTORE(reg) .cfi_restore reg
+
+# define CFI_PUSH(reg) \
+ CFI_ADJUST_CFA_OFFSET(8); CFI_REL_OFFSET(reg, 0)
+# define CFI_POP(reg) \
+ CFI_ADJUST_CFA_OFFSET(-8); CFI_RESTORE(reg)
+# define CFI_POP_TMP_REG() \
+ CFI_ADJUST_CFA_OFFSET(-8);
+# define CFI_LEAVE() \
+ CFI_ADJUST_CFA_OFFSET(-8); CFI_DEF_CFA_REGISTER(%rsp)
+
+/* CFA expressions are used for pointing CFA and registers to
+ * %rsp relative offsets. */
+# define DW_REGNO_rax 0
+# define DW_REGNO_rdx 1
+# define DW_REGNO_rcx 2
+# define DW_REGNO_rbx 3
+# define DW_REGNO_rsi 4
+# define DW_REGNO_rdi 5
+# define DW_REGNO_rbp 6
+# define DW_REGNO_rsp 7
+# define DW_REGNO_r8 8
+# define DW_REGNO_r9 9
+# define DW_REGNO_r10 10
+# define DW_REGNO_r11 11
+# define DW_REGNO_r12 12
+# define DW_REGNO_r13 13
+# define DW_REGNO_r14 14
+# define DW_REGNO_r15 15
+
+# define DW_REGNO(reg) DW_REGNO_ ## reg
+
+/* Fixed length encoding used for integers for now. */
+# define DW_SLEB128_7BIT(value) \
+ 0x00|((value) & 0x7f)
+# define DW_SLEB128_28BIT(value) \
+ 0x80|((value)&0x7f), \
+ 0x80|(((value)>>7)&0x7f), \
+ 0x80|(((value)>>14)&0x7f), \
+ 0x00|(((value)>>21)&0x7f)
+
+# define CFI_CFA_ON_STACK(rsp_offs,cfa_depth) \
+ .cfi_escape \
+ 0x0f, /* DW_CFA_def_cfa_expression */ \
+ DW_SLEB128_7BIT(11), /* length */ \
+ 0x77, /* DW_OP_breg7, rsp + constant */ \
+ DW_SLEB128_28BIT(rsp_offs), \
+ 0x06, /* DW_OP_deref */ \
+ 0x23, /* DW_OP_plus_constu */ \
+ DW_SLEB128_28BIT((cfa_depth)+8)
+
+# define CFI_REG_ON_STACK(reg,rsp_offs) \
+ .cfi_escape \
+ 0x10, /* DW_CFA_expression */ \
+ DW_SLEB128_7BIT(DW_REGNO(reg)), \
+ DW_SLEB128_7BIT(5), /* length */ \
+ 0x77, /* DW_OP_breg7, rsp + constant */ \
+ DW_SLEB128_28BIT(rsp_offs)
+
+#else
+# define CFI_STARTPROC()
+# define CFI_ENDPROC()
+# define CFI_REMEMBER_STATE()
+# define CFI_RESTORE_STATE()
+# define CFI_ADJUST_CFA_OFFSET(off)
+# define CFI_REL_OFFSET(reg,off)
+# define CFI_DEF_CFA_REGISTER(reg)
+# define CFI_REGISTER(ro,rn)
+# define CFI_RESTORE(reg)
+
+# define CFI_PUSH(reg)
+# define CFI_POP(reg)
+# define CFI_POP_TMP_REG()
+# define CFI_LEAVE()
+
+# define CFI_CFA_ON_STACK(rsp_offs,cfa_depth)
+# define CFI_REG_ON_STACK(reg,rsp_offs)
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ENTER_SYSV_FUNC_PARAMS_0_4 \
+ pushq %rdi; \
+ CFI_PUSH(%rdi); \
+ pushq %rsi; \
+ CFI_PUSH(%rsi); \
+ movq %rcx, %rdi; \
+ movq %rdx, %rsi; \
+ movq %r8, %rdx; \
+ movq %r9, %rcx; \
+
+# define ENTER_SYSV_FUNC_PARAMS_5 \
+ ENTER_SYSV_FUNC_PARAMS_0_4; \
+ movq 0x38(%rsp), %r8;
+
+# define ENTER_SYSV_FUNC_PARAMS_6 \
+ ENTER_SYSV_FUNC_PARAMS_5; \
+ movq 0x40(%rsp), %r9;
+
+# define EXIT_SYSV_FUNC \
+ popq %rsi; \
+ CFI_POP(%rsi); \
+ popq %rdi; \
+ CFI_POP(%rdi);
+#else
+# define ENTER_SYSV_FUNC_PARAMS_0_4
+# define ENTER_SYSV_FUNC_PARAMS_5
+# define ENTER_SYSV_FUNC_PARAMS_6
+# define EXIT_SYSV_FUNC
+#endif
+
+#endif /* GCRY_ASM_COMMON_AMD64_H */
diff --git a/comm/third_party/libgcrypt/cipher/asm-common-s390x.h b/comm/third_party/libgcrypt/cipher/asm-common-s390x.h
new file mode 100644
index 0000000000..b3a996cd6e
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/asm-common-s390x.h
@@ -0,0 +1,90 @@
+/* asm-common-s390x.h - Common macros for zSeries assembly
+ *
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ASM_COMMON_S390X_H
+#define GCRY_ASM_COMMON_S390X_H
+
+#include <config.h>
+
+#ifdef HAVE_GCC_ASM_ELF_DIRECTIVES
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+#ifdef HAVE_GCC_ASM_CFI_DIRECTIVES
+/* CFI directives to emit DWARF stack unwinding information. */
+# define CFI_STARTPROC() .cfi_startproc
+# define CFI_ENDPROC() .cfi_endproc
+# define CFI_REMEMBER_STATE() .cfi_remember_state
+# define CFI_RESTORE_STATE() .cfi_restore_state
+# define CFI_ADJUST_CFA_OFFSET(off) .cfi_adjust_cfa_offset off
+# define CFI_REL_OFFSET(reg,off) .cfi_rel_offset reg, off
+# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
+# define CFI_REGISTER(ro,rn) .cfi_register ro, rn
+# define CFI_RESTORE(reg) .cfi_restore reg
+
+/* CFA expressions are used for pointing CFA and registers to
+ * SP relative offsets. */
+# define DW_REGNO_SP 15
+
+/* Fixed length encoding used for integers for now. */
+# define DW_SLEB128_7BIT(value) \
+ 0x00|((value) & 0x7f)
+# define DW_SLEB128_28BIT(value) \
+ 0x80|((value)&0x7f), \
+ 0x80|(((value)>>7)&0x7f), \
+ 0x80|(((value)>>14)&0x7f), \
+ 0x00|(((value)>>21)&0x7f)
+
+# define CFI_CFA_ON_STACK(rsp_offs,cfa_depth) \
+ .cfi_escape \
+ 0x0f, /* DW_CFA_def_cfa_expression */ \
+ DW_SLEB128_7BIT(11), /* length */ \
+ 0x7f, /* DW_OP_breg15, rsp + constant */ \
+ DW_SLEB128_28BIT(rsp_offs), \
+ 0x06, /* DW_OP_deref */ \
+ 0x23, /* DW_OP_plus_constu */ \
+ DW_SLEB128_28BIT((cfa_depth)+160)
+
+# define CFI_REG_ON_STACK(regno,rsp_offs) \
+ .cfi_escape \
+ 0x10, /* DW_CFA_expression */ \
+ DW_SLEB128_7BIT(regno), \
+ DW_SLEB128_7BIT(5), /* length */ \
+ 0x7f, /* DW_OP_breg15, rsp + constant */ \
+ DW_SLEB128_28BIT(rsp_offs)
+
+#else
+# define CFI_STARTPROC()
+# define CFI_ENDPROC()
+# define CFI_REMEMBER_STATE()
+# define CFI_RESTORE_STATE()
+# define CFI_ADJUST_CFA_OFFSET(off)
+# define CFI_REL_OFFSET(reg,off)
+# define CFI_DEF_CFA_REGISTER(reg)
+# define CFI_REGISTER(ro,rn)
+# define CFI_RESTORE(reg)
+
+# define CFI_CFA_ON_STACK(rsp_offs,cfa_depth)
+# define CFI_REG_ON_STACK(reg,rsp_offs)
+#endif
+
+#endif /* GCRY_ASM_COMMON_AMD64_H */
diff --git a/comm/third_party/libgcrypt/cipher/asm-inline-s390x.h b/comm/third_party/libgcrypt/cipher/asm-inline-s390x.h
new file mode 100644
index 0000000000..bacb45fe2e
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/asm-inline-s390x.h
@@ -0,0 +1,157 @@
+/* asm-inline-s390x.h - Common macros for zSeries inline assembly
+ *
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ASM_INLINE_S390X_H
+#define GCRY_ASM_INLINE_S390X_H
+
+#include <config.h>
+
+#define ALWAYS_INLINE inline __attribute__((always_inline))
+
+typedef unsigned int u128_t __attribute__ ((mode (TI)));
+
+enum kmxx_functions_e
+{
+ KM_FUNCTION_AES_128 = 18,
+ KM_FUNCTION_AES_192 = 19,
+ KM_FUNCTION_AES_256 = 20,
+ KM_FUNCTION_XTS_AES_128 = 50,
+ KM_FUNCTION_XTS_AES_256 = 52,
+
+ KMID_FUNCTION_SHA1 = 1,
+ KMID_FUNCTION_SHA256 = 2,
+ KMID_FUNCTION_SHA512 = 3,
+ KMID_FUNCTION_SHA3_224 = 32,
+ KMID_FUNCTION_SHA3_256 = 33,
+ KMID_FUNCTION_SHA3_384 = 34,
+ KMID_FUNCTION_SHA3_512 = 35,
+ KMID_FUNCTION_SHAKE128 = 36,
+ KMID_FUNCTION_SHAKE256 = 37,
+ KMID_FUNCTION_GHASH = 65,
+};
+
+enum kmxx_function_flags_e
+{
+ KM_ENCRYPT = 0 << 7,
+ KM_DECRYPT = 1 << 7,
+
+ KMF_LCFB_16 = 16 << 24,
+
+ KMA_LPC = 1 << 8,
+ KMA_LAAD = 1 << 9,
+ KMA_HS = 1 << 10,
+
+ KLMD_PADDING_STATE = 1 << 8,
+};
+
+static ALWAYS_INLINE u128_t km_function_to_mask(enum kmxx_functions_e func)
+{
+ return (u128_t)1 << (127 - func);
+}
+
+static inline u128_t kimd_query(void)
+{
+ static u128_t function_codes = 0;
+ static int initialized = 0;
+ register unsigned long reg0 asm("0") = 0;
+ register void *reg1 asm("1") = &function_codes;
+ u128_t r1;
+
+ if (initialized)
+ return function_codes;
+
+ asm volatile ("0: .insn rre,0xb93e << 16, 0, %[r1]\n\t"
+ " brc 1,0b\n\t"
+ : [r1] "=a" (r1)
+ : [reg0] "r" (reg0), [reg1] "r" (reg1)
+ : "cc", "memory");
+
+ initialized = 1;
+ return function_codes;
+}
+
+static inline u128_t klmd_query(void)
+{
+ static u128_t function_codes = 0;
+ static int initialized = 0;
+ register unsigned long reg0 asm("0") = 0;
+ register void *reg1 asm("1") = &function_codes;
+ u128_t r1;
+
+ if (initialized)
+ return function_codes;
+
+ asm volatile ("0: .insn rre,0xb93f << 16, 0, %[r1]\n\t"
+ " brc 1,0b\n\t"
+ : [r1] "=a" (r1)
+ : [reg0] "r" (reg0), [reg1] "r" (reg1)
+ : "cc", "memory");
+
+ initialized = 1;
+ return function_codes;
+}
+
+static ALWAYS_INLINE void
+kimd_execute(unsigned int func, void *param_block, const void *src,
+ size_t src_len)
+{
+ register unsigned long reg0 asm("0") = func;
+ register byte *reg1 asm("1") = param_block;
+ u128_t r1 = ((u128_t)(uintptr_t)src << 64) | (u64)src_len;
+
+ asm volatile ("0: .insn rre,0xb93e << 16, 0, %[r1]\n\t"
+ " brc 1,0b\n\t"
+ : [r1] "+a" (r1)
+ : [func] "r" (reg0), [param_ptr] "r" (reg1)
+ : "cc", "memory");
+}
+
+static ALWAYS_INLINE void
+klmd_execute(unsigned int func, void *param_block, const void *src,
+ size_t src_len)
+{
+ register unsigned long reg0 asm("0") = func;
+ register byte *reg1 asm("1") = param_block;
+ u128_t r1 = ((u128_t)(uintptr_t)src << 64) | (u64)src_len;
+
+ asm volatile ("0: .insn rre,0xb93f << 16, 0, %[r1]\n\t"
+ " brc 1,0b\n\t"
+ : [func] "+r" (reg0), [r1] "+a" (r1)
+ : [param_ptr] "r" (reg1)
+ : "cc", "memory");
+}
+
+static ALWAYS_INLINE void
+klmd_shake_execute(unsigned int func, void *param_block, void *dst,
+ size_t dst_len, const void *src, size_t src_len)
+{
+ register unsigned long reg0 asm("0") = func;
+ register byte *reg1 asm("1") = param_block;
+ u128_t r1 = ((u128_t)(uintptr_t)dst << 64) | (u64)dst_len;
+ u128_t r2 = ((u128_t)(uintptr_t)src << 64) | (u64)src_len;
+
+ asm volatile ("0: .insn rre,0xb93f << 16, %[r1], %[r2]\n\t"
+ " brc 1,0b\n\t"
+ : [func] "+r" (reg0), [r1] "+a" (r1), [r2] "+a" (r2)
+ : [param_ptr] "r" (reg1)
+ : "cc", "memory");
+}
+
+#endif /* GCRY_ASM_INLINE_S390X_H */
diff --git a/comm/third_party/libgcrypt/cipher/asm-poly1305-aarch64.h b/comm/third_party/libgcrypt/cipher/asm-poly1305-aarch64.h
new file mode 100644
index 0000000000..9009270956
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/asm-poly1305-aarch64.h
@@ -0,0 +1,245 @@
+/* asm-common-aarch64.h - Poly1305 macros for ARMv8/AArch64 assembly
+ *
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ASM_POLY1305_AARCH64_H
+#define GCRY_ASM_POLY1305_AARCH64_H
+
+#include "asm-common-aarch64.h"
+
+#ifdef __AARCH64EL__
+ #define le_to_host(reg) /*_*/
+#else
+ #define le_to_host(reg) rev reg, reg;
+#endif
+
+/**********************************************************************
+ poly1305 for stitched chacha20-poly1305 Aarch64 implementations
+ **********************************************************************/
+
+#define POLY_RSTATE x8
+#define POLY_RSRC x9
+
+#define POLY_R_H0 x10
+#define POLY_R_H1 x11
+#define POLY_R_H2 x12
+#define POLY_R_H2d w12
+#define POLY_R_R0 x13
+#define POLY_R_R1 x14
+#define POLY_R_R1_MUL5 x15
+#define POLY_R_X0_HI x16
+#define POLY_R_X0_LO x17
+#define POLY_R_X1_HI x19
+#define POLY_R_X1_LO x20
+#define POLY_R_ONE x21
+#define POLY_R_ONEd w21
+
+#define POLY_TMP0 x22
+#define POLY_TMP1 x23
+#define POLY_TMP2 x24
+#define POLY_TMP3 x25
+
+#define POLY_CHACHA_ROUND x26
+
+#define POLY_S_R0 (4 * 4 + 0 * 8)
+#define POLY_S_R1 (4 * 4 + 1 * 8)
+#define POLY_S_H0 (4 * 4 + 2 * 8 + 0 * 8)
+#define POLY_S_H1 (4 * 4 + 2 * 8 + 1 * 8)
+#define POLY_S_H2d (4 * 4 + 2 * 8 + 2 * 8)
+
+#define POLY1305_PUSH_REGS() \
+ stp x19, x20, [sp, #-16]!; \
+ CFI_ADJUST_CFA_OFFSET(16); \
+ CFI_REG_ON_STACK(19, 0); \
+ CFI_REG_ON_STACK(20, 8); \
+ stp x21, x22, [sp, #-16]!; \
+ CFI_ADJUST_CFA_OFFSET(16); \
+ CFI_REG_ON_STACK(21, 0); \
+ CFI_REG_ON_STACK(22, 8); \
+ stp x23, x24, [sp, #-16]!; \
+ CFI_ADJUST_CFA_OFFSET(16); \
+ CFI_REG_ON_STACK(23, 0); \
+ CFI_REG_ON_STACK(24, 8); \
+ stp x25, x26, [sp, #-16]!; \
+ CFI_ADJUST_CFA_OFFSET(16); \
+ CFI_REG_ON_STACK(25, 0); \
+ CFI_REG_ON_STACK(26, 8);
+
+#define POLY1305_POP_REGS() \
+ ldp x25, x26, [sp], #16; \
+ CFI_ADJUST_CFA_OFFSET(-16); \
+ CFI_RESTORE(x25); \
+ CFI_RESTORE(x26); \
+ ldp x23, x24, [sp], #16; \
+ CFI_ADJUST_CFA_OFFSET(-16); \
+ CFI_RESTORE(x23); \
+ CFI_RESTORE(x24); \
+ ldp x21, x22, [sp], #16; \
+ CFI_ADJUST_CFA_OFFSET(-16); \
+ CFI_RESTORE(x21); \
+ CFI_RESTORE(x22); \
+ ldp x19, x20, [sp], #16; \
+ CFI_ADJUST_CFA_OFFSET(-16); \
+ CFI_RESTORE(x19); \
+ CFI_RESTORE(x20);
+
+#define POLY1305_LOAD_STATE() \
+ ldr POLY_R_R1, [POLY_RSTATE, #(POLY_S_R1)]; \
+ ldr POLY_R_H0, [POLY_RSTATE, #(POLY_S_H0)]; \
+ ldr POLY_R_H1, [POLY_RSTATE, #(POLY_S_H1)]; \
+ ldr POLY_R_H2d, [POLY_RSTATE, #(POLY_S_H2d)]; \
+ ldr POLY_R_R0, [POLY_RSTATE, #(POLY_S_R0)]; \
+ add POLY_R_R1_MUL5, POLY_R_R1, POLY_R_R1, lsr #2; \
+ mov POLY_R_ONE, #1;
+
+#define POLY1305_STORE_STATE() \
+ str POLY_R_H0, [POLY_RSTATE, #(POLY_S_H0)]; \
+ str POLY_R_H1, [POLY_RSTATE, #(POLY_S_H1)]; \
+ str POLY_R_H2d, [POLY_RSTATE, #(POLY_S_H2d)];
+
+#define POLY1305_BLOCK_PART1(src_offset) \
+ /* a = h + m */ \
+ ldr POLY_TMP0, [POLY_RSRC, #((src_offset) + 0 * 8)];
+#define POLY1305_BLOCK_PART2(src_offset) \
+ ldr POLY_TMP1, [POLY_RSRC, #((src_offset) + 1 * 8)];
+#define POLY1305_BLOCK_PART3() \
+ le_to_host(POLY_TMP0);
+#define POLY1305_BLOCK_PART4() \
+ le_to_host(POLY_TMP1);
+#define POLY1305_BLOCK_PART5() \
+ adds POLY_R_H0, POLY_R_H0, POLY_TMP0;
+#define POLY1305_BLOCK_PART6() \
+ adcs POLY_R_H1, POLY_R_H1, POLY_TMP1;
+#define POLY1305_BLOCK_PART7() \
+ adc POLY_R_H2d, POLY_R_H2d, POLY_R_ONEd;
+
+#define POLY1305_BLOCK_PART8() \
+ /* h = a * r (partial mod 2^130-5): */ \
+ mul POLY_R_X1_LO, POLY_R_H0, POLY_R_R1; /* lo: h0 * r1 */
+#define POLY1305_BLOCK_PART9() \
+ mul POLY_TMP0, POLY_R_H1, POLY_R_R0; /* lo: h1 * r0 */
+#define POLY1305_BLOCK_PART10() \
+ mul POLY_R_X0_LO, POLY_R_H0, POLY_R_R0; /* lo: h0 * r0 */
+#define POLY1305_BLOCK_PART11() \
+ umulh POLY_R_X1_HI, POLY_R_H0, POLY_R_R1; /* hi: h0 * r1 */
+#define POLY1305_BLOCK_PART12() \
+ adds POLY_R_X1_LO, POLY_R_X1_LO, POLY_TMP0;
+#define POLY1305_BLOCK_PART13() \
+ umulh POLY_TMP1, POLY_R_H1, POLY_R_R0; /* hi: h1 * r0 */
+#define POLY1305_BLOCK_PART14() \
+ mul POLY_TMP2, POLY_R_H1, POLY_R_R1_MUL5; /* lo: h1 * r1 mod 2^130-5 */
+#define POLY1305_BLOCK_PART15() \
+ umulh POLY_R_X0_HI, POLY_R_H0, POLY_R_R0; /* hi: h0 * r0 */
+#define POLY1305_BLOCK_PART16() \
+ adc POLY_R_X1_HI, POLY_R_X1_HI, POLY_TMP1;
+#define POLY1305_BLOCK_PART17() \
+ umulh POLY_TMP3, POLY_R_H1, POLY_R_R1_MUL5; /* hi: h1 * r1 mod 2^130-5 */
+#define POLY1305_BLOCK_PART18() \
+ adds POLY_R_X0_LO, POLY_R_X0_LO, POLY_TMP2;
+#define POLY1305_BLOCK_PART19() \
+ mul POLY_R_H1, POLY_R_H2, POLY_R_R1_MUL5; /* h2 * r1 mod 2^130-5 */
+#define POLY1305_BLOCK_PART20() \
+ adc POLY_R_X0_HI, POLY_R_X0_HI, POLY_TMP3;
+#define POLY1305_BLOCK_PART21() \
+ mul POLY_R_H2, POLY_R_H2, POLY_R_R0; /* h2 * r0 */
+#define POLY1305_BLOCK_PART22() \
+ adds POLY_R_H1, POLY_R_H1, POLY_R_X1_LO;
+#define POLY1305_BLOCK_PART23() \
+ adc POLY_R_H0, POLY_R_H2, POLY_R_X1_HI;
+
+#define POLY1305_BLOCK_PART24() \
+ /* carry propagation */ \
+ and POLY_R_H2, POLY_R_H0, #3;
+#define POLY1305_BLOCK_PART25() \
+ lsr POLY_R_H0, POLY_R_H0, #2;
+#define POLY1305_BLOCK_PART26() \
+ add POLY_R_H0, POLY_R_H0, POLY_R_H0, lsl #2;
+#define POLY1305_BLOCK_PART27() \
+ adds POLY_R_H0, POLY_R_H0, POLY_R_X0_LO;
+#define POLY1305_BLOCK_PART28() \
+ adcs POLY_R_H1, POLY_R_H1, POLY_R_X0_HI;
+#define POLY1305_BLOCK_PART29() \
+ adc POLY_R_H2d, POLY_R_H2d, wzr;
+
+//#define TESTING_POLY1305_ASM
+#ifdef TESTING_POLY1305_ASM
+/* for testing only. */
+.align 3
+.globl _gcry_poly1305_aarch64_blocks1
+ELF(.type _gcry_poly1305_aarch64_blocks1,%function;)
+_gcry_poly1305_aarch64_blocks1:
+ /* input:
+ * x0: poly1305-state
+ * x1: src
+ * x2: nblks
+ */
+ CFI_STARTPROC()
+ POLY1305_PUSH_REGS();
+
+ mov POLY_RSTATE, x0;
+ mov POLY_RSRC, x1;
+
+ POLY1305_LOAD_STATE();
+
+.L_gcry_poly1305_aarch64_loop1:
+ POLY1305_BLOCK_PART1(0 * 16);
+ POLY1305_BLOCK_PART2(0 * 16);
+ add POLY_RSRC, POLY_RSRC, #16;
+ POLY1305_BLOCK_PART3();
+ POLY1305_BLOCK_PART4();
+ POLY1305_BLOCK_PART5();
+ POLY1305_BLOCK_PART6();
+ POLY1305_BLOCK_PART7();
+ POLY1305_BLOCK_PART8();
+ POLY1305_BLOCK_PART9();
+ POLY1305_BLOCK_PART10();
+ POLY1305_BLOCK_PART11();
+ POLY1305_BLOCK_PART12();
+ POLY1305_BLOCK_PART13();
+ POLY1305_BLOCK_PART14();
+ POLY1305_BLOCK_PART15();
+ POLY1305_BLOCK_PART16();
+ POLY1305_BLOCK_PART17();
+ POLY1305_BLOCK_PART18();
+ POLY1305_BLOCK_PART19();
+ POLY1305_BLOCK_PART20();
+ POLY1305_BLOCK_PART21();
+ POLY1305_BLOCK_PART22();
+ POLY1305_BLOCK_PART23();
+ POLY1305_BLOCK_PART24();
+ POLY1305_BLOCK_PART25();
+ POLY1305_BLOCK_PART26();
+ POLY1305_BLOCK_PART27();
+ POLY1305_BLOCK_PART28();
+ POLY1305_BLOCK_PART29();
+
+ subs x2, x2, #1;
+ b.ne .L_gcry_poly1305_aarch64_loop1;
+
+ POLY1305_STORE_STATE();
+
+ mov x0, #0;
+
+ POLY1305_POP_REGS();
+ ret;
+ CFI_ENDPROC()
+ELF(.size _gcry_poly1305_aarch64_blocks1, .-_gcry_poly1305_aarch64_blocks1;)
+#endif
+
+#endif /* GCRY_ASM_POLY1305_AARCH64_H */
diff --git a/comm/third_party/libgcrypt/cipher/asm-poly1305-amd64.h b/comm/third_party/libgcrypt/cipher/asm-poly1305-amd64.h
new file mode 100644
index 0000000000..3f99ea3e16
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/asm-poly1305-amd64.h
@@ -0,0 +1,171 @@
+/* asm-common-amd64.h - Poly1305 macros for AMD64 assembly
+ *
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ASM_POLY1305_AMD64_H
+#define GCRY_ASM_POLY1305_AMD64_H
+
+#include "asm-common-amd64.h"
+
+/**********************************************************************
+ poly1305 for stitched chacha20-poly1305 AMD64 implementations
+ **********************************************************************/
+
+#define POLY_RSTATE %r8
+#define POLY_RSRC %r9
+
+#define POLY_R_H0 %rbx
+#define POLY_R_H1 %rcx
+#define POLY_R_H2 %r10
+#define POLY_R_H2d %r10d
+#define POLY_R_R0 %r11
+#define POLY_R_R1_MUL5 %r12
+#define POLY_R_X0_HI %r13
+#define POLY_R_X0_LO %r14
+#define POLY_R_X1_HI %r15
+#define POLY_R_X1_LO %rsi
+
+#define POLY_S_R0 (4 * 4 + 0 * 8)(POLY_RSTATE)
+#define POLY_S_R1 (4 * 4 + 1 * 8)(POLY_RSTATE)
+#define POLY_S_H0 (4 * 4 + 2 * 8 + 0 * 8)(POLY_RSTATE)
+#define POLY_S_H1 (4 * 4 + 2 * 8 + 1 * 8)(POLY_RSTATE)
+#define POLY_S_H2d (4 * 4 + 2 * 8 + 2 * 8)(POLY_RSTATE)
+
+#define POLY1305_LOAD_STATE() \
+ movq POLY_S_H0, POLY_R_H0; \
+ movq POLY_S_H1, POLY_R_H1; \
+ movl POLY_S_H2d, POLY_R_H2d; \
+ movq POLY_S_R0, POLY_R_R0; \
+ movq POLY_S_R1, POLY_R_R1_MUL5; \
+ shrq $2, POLY_R_R1_MUL5; \
+ addq POLY_S_R1, POLY_R_R1_MUL5;
+
+#define POLY1305_STORE_STATE() \
+ movq POLY_R_H0, POLY_S_H0; \
+ movq POLY_R_H1, POLY_S_H1; \
+ movl POLY_R_H2d, POLY_S_H2d;
+
+/* a = h + m */
+#define POLY1305_BLOCK_PART1(src_offset) \
+ addq ((src_offset) + 0 * 8)(POLY_RSRC), POLY_R_H0; \
+ adcq ((src_offset) + 1 * 8)(POLY_RSRC), POLY_R_H1; \
+ adcl $1, POLY_R_H2d; \
+ \
+ /* h = a * r (partial mod 2^130-5): */ \
+ \
+ /* h0 * r1 */ \
+ movq POLY_R_H0, %rax; \
+ mulq POLY_S_R1; \
+ movq %rax, POLY_R_X1_LO; \
+ movq %rdx, POLY_R_X1_HI;
+
+#define POLY1305_BLOCK_PART2() \
+ \
+ /* h0 * r0 */ \
+ movq POLY_R_H0, %rax; \
+ mulq POLY_R_R0; \
+ movq %rax, POLY_R_X0_LO; \
+ movq %rdx, POLY_R_X0_HI;
+
+#define POLY1305_BLOCK_PART3() \
+ \
+ /* h1 * r0 */ \
+ movq POLY_R_H1, %rax; \
+ mulq POLY_R_R0; \
+ addq %rax, POLY_R_X1_LO; \
+ adcq %rdx, POLY_R_X1_HI; \
+ \
+ /* h1 * r1 mod 2^130-5 */ \
+ movq POLY_R_R1_MUL5, %rax; \
+ mulq POLY_R_H1;
+
+#define POLY1305_BLOCK_PART4() \
+ movq POLY_R_H2, POLY_R_H1; \
+ imulq POLY_R_R1_MUL5, POLY_R_H1; /* h2 * r1 mod 2^130-5 */ \
+ addq %rax, POLY_R_X0_LO; \
+ adcq %rdx, POLY_R_X0_HI; \
+ imulq POLY_R_R0, POLY_R_H2; /* h2 * r0 */ \
+ addq POLY_R_X1_LO, POLY_R_H1; \
+ adcq POLY_R_X1_HI, POLY_R_H2;
+
+#define POLY1305_BLOCK_PART5() \
+ \
+ /* carry propagation */ \
+ movq POLY_R_H2, POLY_R_H0; \
+ andl $3, POLY_R_H2d; \
+ shrq $2, POLY_R_H0; \
+ leaq (POLY_R_H0, POLY_R_H0, 4), POLY_R_H0; \
+ addq POLY_R_X0_LO, POLY_R_H0; \
+ adcq POLY_R_X0_HI, POLY_R_H1; \
+ adcl $0, POLY_R_H2d;
+
+#ifdef TESTING_POLY1305_ASM
+/* for testing only, mixed C/asm poly1305.c is marginally faster (~2%). */
+.align 8
+.globl _gcry_poly1305_amd64_ssse3_blocks1
+ELF(.type _gcry_poly1305_amd64_ssse3_blocks1,@function;)
+
+_gcry_poly1305_amd64_ssse3_blocks1:
+ /* input:
+ * %rdi: poly1305-state
+ * %rsi: src
+ * %rdx: nblks
+ */
+ pushq %rbp;
+ movq %rsp, %rbp;
+
+ subq $(10 * 8), %rsp;
+ movq %rbx, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ movq %r14, (4 * 8)(%rsp);
+ movq %r15, (5 * 8)(%rsp);
+
+ movq %rdx, (8 * 8)(%rsp); # NBLKS
+
+ movq %rdi, POLY_RSTATE;
+ movq %rsi, POLY_RSRC;
+
+ POLY1305_LOAD_STATE();
+
+.L_poly1:
+ POLY1305_BLOCK_PART1(0 * 16);
+ POLY1305_BLOCK_PART2();
+ POLY1305_BLOCK_PART3();
+ POLY1305_BLOCK_PART4();
+ POLY1305_BLOCK_PART5();
+
+ subq $1, (8 * 8)(%rsp); # NBLKS
+ leaq (16)(POLY_RSRC), POLY_RSRC;
+ jnz .L_poly1;
+
+ POLY1305_STORE_STATE();
+
+ movq (1 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ movq (4 * 8)(%rsp), %r14;
+ movq (5 * 8)(%rsp), %r15;
+
+ xorl %eax, %eax;
+ leave
+ ret;
+#endif
+
+#endif /* GCRY_ASM_POLY1305_AMD64_H */
diff --git a/comm/third_party/libgcrypt/cipher/asm-poly1305-s390x.h b/comm/third_party/libgcrypt/cipher/asm-poly1305-s390x.h
new file mode 100644
index 0000000000..113ab94913
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/asm-poly1305-s390x.h
@@ -0,0 +1,140 @@
+/* asm-common-amd64.h - Poly1305 macros for zSeries assembly
+ *
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ASM_POLY1305_S390X_H
+#define GCRY_ASM_POLY1305_S390X_H
+
+#include "asm-common-s390x.h"
+
+/**********************************************************************
+ poly1305 for stitched chacha20-poly1305
+ **********************************************************************/
+
+#define POLY_RSTATE %r1
+#define POLY_RSRC %r14
+
+#define POLY_R_H0_TMP_HI %r6 // even-
+#define POLY_R_H0 %r7 // odd pair
+#define POLY_R_H1_TMP_HI %r8 // even-
+#define POLY_R_H1 %r9 // odd pair
+#define POLY_R_H2 %r10
+#define POLY_R_R0 %r11
+#define POLY_R_R1 %r12
+#define POLY_R_R1_MUL5 %r13
+#define POLY_R_X0_HI %r2 // even-
+#define POLY_R_X0_LO %r3 // odd pair
+#define POLY_R_X1_HI %r4 // even-
+#define POLY_R_X1_LO %r5 // odd pair
+
+#define POLY_S_R0 (4 * 4 + 0 * 8)(POLY_RSTATE)
+#define POLY_S_R1 (4 * 4 + 1 * 8)(POLY_RSTATE)
+#define POLY_S_H0 (4 * 4 + 2 * 8 + 0 * 8)(POLY_RSTATE)
+#define POLY_S_H1 (4 * 4 + 2 * 8 + 1 * 8)(POLY_RSTATE)
+#define POLY_S_H2d (4 * 4 + 2 * 8 + 2 * 8)(POLY_RSTATE)
+
+#define INC_POLY1305_SRC(a) \
+ aghi POLY_RSRC, (a);
+
+#define POLY1305_LOAD_STATE() \
+ lg POLY_R_H0, POLY_S_H0; \
+ lg POLY_R_H1, POLY_S_H1; \
+ llgf POLY_R_H2, POLY_S_H2d; \
+ rllg POLY_R_H0, POLY_R_H0, 32; \
+ rllg POLY_R_H1, POLY_R_H1, 32; \
+ lg POLY_R_R0, POLY_S_R0; \
+ lg POLY_R_R1, POLY_S_R1; \
+ rllg POLY_R_R0, POLY_R_R0, 32; \
+ rllg POLY_R_R1, POLY_R_R1, 32; \
+ srlg POLY_R_R1_MUL5, POLY_R_R1, 2; \
+ algr POLY_R_R1_MUL5, POLY_R_R1;
+
+#define POLY1305_STORE_STATE() \
+ rllg POLY_R_H0, POLY_R_H0, 32; \
+ rllg POLY_R_H1, POLY_R_H1, 32; \
+ stg POLY_R_H0, POLY_S_H0; \
+ stg POLY_R_H1, POLY_S_H1; \
+ st POLY_R_H2, POLY_S_H2d;
+
+/* a = h + m */
+#define POLY1305_BLOCK_PART1_HB(src_offset, high_pad) \
+ lrvg POLY_R_X0_HI, ((src_offset) + 1 * 8)(POLY_RSRC); \
+ lrvg POLY_R_X0_LO, ((src_offset) + 0 * 8)(POLY_RSRC); \
+ lghi POLY_R_H1_TMP_HI, (high_pad);
+
+#define POLY1305_BLOCK_PART1(src_offset) \
+ POLY1305_BLOCK_PART1_HB(src_offset, 1);
+
+#define POLY1305_BLOCK_PART2() \
+ algr POLY_R_H0, POLY_R_X0_LO; \
+ alcgr POLY_R_H1, POLY_R_X0_HI; \
+ alcgr POLY_R_H2, POLY_R_H1_TMP_HI; \
+ lgr POLY_R_X1_LO, POLY_R_H0; \
+ lgr POLY_R_X0_LO, POLY_R_H0;
+
+#define POLY1305_BLOCK_PART3() \
+ /* h = a * r (partial mod 2^130-5): */ \
+ \
+ /* h0 * r1 */ \
+ mlgr POLY_R_X1_HI, POLY_R_R1; \
+ \
+ /* h1 * r0 */ \
+ lgr POLY_R_H0, POLY_R_H1; \
+ mlgr POLY_R_H0_TMP_HI, POLY_R_R0; \
+ \
+ /* h1 * r1 mod 2^130-5 */ \
+ mlgr POLY_R_H1_TMP_HI, POLY_R_R1_MUL5;
+
+#define POLY1305_BLOCK_PART4() \
+ \
+ /* h0 * r0 */ \
+ mlgr POLY_R_X0_HI, POLY_R_R0; \
+ \
+ algr POLY_R_X1_LO, POLY_R_H0; \
+ alcgr POLY_R_X1_HI, POLY_R_H0_TMP_HI; \
+ \
+ lgr POLY_R_H0_TMP_HI, POLY_R_H2; \
+ msgr POLY_R_H0_TMP_HI, POLY_R_R1_MUL5; /* h2 * r1 mod 2^130-5 */ \
+ msgr POLY_R_H2, POLY_R_R0; /* h2 * r0 */
+
+#define POLY1305_BLOCK_PART5() \
+ \
+ algr POLY_R_X0_LO, POLY_R_H1; \
+ alcgr POLY_R_X0_HI, POLY_R_H1_TMP_HI;
+
+#define POLY1305_BLOCK_PART6() \
+ \
+ algrk POLY_R_H1, POLY_R_H0_TMP_HI, POLY_R_X1_LO; \
+ alcgr POLY_R_H2, POLY_R_X1_HI;
+
+#define POLY1305_BLOCK_PART7() \
+ \
+ /* carry propagation */ \
+ srlg POLY_R_H0, POLY_R_H2, 2; \
+ risbgn POLY_R_X1_LO, POLY_R_H2, 0, 0x80 | 61, 0; \
+ lghi POLY_R_H1_TMP_HI, 0; \
+ agr POLY_R_H0, POLY_R_X1_LO; \
+ risbgn POLY_R_H2, POLY_R_H2, 62, 0x80 | 63, 0;
+
+#define POLY1305_BLOCK_PART8() \
+ algr POLY_R_H0, POLY_R_X0_LO; \
+ alcgr POLY_R_H1, POLY_R_X0_HI; \
+ alcgr POLY_R_H2, POLY_R_H1_TMP_HI;
+
+#endif /* GCRY_ASM_POLY1305_AMD64_H */
diff --git a/comm/third_party/libgcrypt/cipher/bithelp.h b/comm/third_party/libgcrypt/cipher/bithelp.h
new file mode 100644
index 0000000000..7793ce7ca3
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/bithelp.h
@@ -0,0 +1,123 @@
+/* bithelp.h - Some bit manipulation helpers
+ * Copyright (C) 1999, 2002 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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef GCRYPT_BITHELP_H
+#define GCRYPT_BITHELP_H
+
+#include "types.h"
+
+
+/****************
+ * Rotate the 32 bit unsigned integer X by N bits left/right
+ */
+static inline u32 rol(u32 x, int n)
+{
+ return ( (x << (n&(32-1))) | (x >> ((32-n)&(32-1))) );
+}
+
+static inline u32 ror(u32 x, int n)
+{
+ return ( (x >> (n&(32-1))) | (x << ((32-n)&(32-1))) );
+}
+
+static inline u64 rol64(u64 x, int n)
+{
+ return ( (x << (n&(64-1))) | (x >> ((64-n)&(64-1))) );
+}
+
+/* Byte swap for 32-bit and 64-bit integers. If available, use compiler
+ provided helpers. */
+#ifdef HAVE_BUILTIN_BSWAP32
+# define _gcry_bswap32 __builtin_bswap32
+#else
+static inline u32
+_gcry_bswap32(u32 x)
+{
+ return ((rol(x, 8) & 0x00ff00ffL) | (ror(x, 8) & 0xff00ff00L));
+}
+#endif
+
+#ifdef HAVE_BUILTIN_BSWAP64
+# define _gcry_bswap64 __builtin_bswap64
+#else
+static inline u64
+_gcry_bswap64(u64 x)
+{
+ return ((u64)_gcry_bswap32(x) << 32) | (_gcry_bswap32(x >> 32));
+}
+#endif
+
+/* Endian dependent byte swap operations. */
+#ifdef WORDS_BIGENDIAN
+# define le_bswap32(x) _gcry_bswap32(x)
+# define be_bswap32(x) ((u32)(x))
+# define le_bswap64(x) _gcry_bswap64(x)
+# define be_bswap64(x) ((u64)(x))
+#else
+# define le_bswap32(x) ((u32)(x))
+# define be_bswap32(x) _gcry_bswap32(x)
+# define le_bswap64(x) ((u64)(x))
+# define be_bswap64(x) _gcry_bswap64(x)
+#endif
+
+
+/* Count trailing zero bits in an unsigend int. We return an int
+ because that is what gcc's builtin does. Returns the number of
+ bits in X if X is 0. */
+static inline int
+_gcry_ctz (unsigned int x)
+{
+#if defined (HAVE_BUILTIN_CTZ)
+ return x ? __builtin_ctz (x) : 8 * sizeof (x);
+#else
+ /* See
+ * http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightModLookup
+ */
+ static const unsigned char mod37[] =
+ {
+ sizeof (unsigned int)*8,
+ 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13,
+ 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9,
+ 5, 20, 8, 19, 18
+ };
+ return (int)mod37[(-x & x) % 37];
+#endif
+}
+
+
+/* Count trailing zero bits in an u64. We return an int because that
+ is what gcc's builtin does. Returns the number of bits in X if X
+ is 0. */
+static inline int
+_gcry_ctz64(u64 x)
+{
+#if defined (HAVE_BUILTIN_CTZL) && SIZEOF_UNSIGNED_LONG >= 8
+ return x ? __builtin_ctzl (x) : 8 * sizeof (x);
+#elif defined (HAVE_BUILTIN_CTZ) && SIZEOF_UNSIGNED_INT >= 8
+#warning hello
+ return x ? __builtin_ctz (x) : 8 * sizeof (x);
+#else
+ if ((x & 0xffffffff))
+ return _gcry_ctz (x);
+ else
+ return 32 + _gcry_ctz (x >> 32);
+#endif
+}
+
+
+#endif /*GCRYPT_BITHELP_H*/
diff --git a/comm/third_party/libgcrypt/cipher/blake2.c b/comm/third_party/libgcrypt/cipher/blake2.c
new file mode 100644
index 0000000000..f2bf49e522
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/blake2.c
@@ -0,0 +1,996 @@
+/* blake2.c - BLAKE2b and BLAKE2s hash functions (RFC 7693)
+ * Copyright (C) 2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain/CC0 BLAKE2 reference implementation
+ * by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/ref
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ */
+
+#include <config.h>
+#include <string.h>
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+/* USE_AVX indicates whether to compile with Intel AVX code. */
+#undef USE_AVX
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX 1
+#endif
+
+/* USE_AVX2 indicates whether to compile with Intel AVX2 code. */
+#undef USE_AVX2
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX2 1
+#endif
+
+/* AMD64 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_AVX2) && defined(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
+
+#define BLAKE2B_BLOCKBYTES 128
+#define BLAKE2B_OUTBYTES 64
+#define BLAKE2B_KEYBYTES 64
+
+#define BLAKE2S_BLOCKBYTES 64
+#define BLAKE2S_OUTBYTES 32
+#define BLAKE2S_KEYBYTES 32
+
+typedef struct
+{
+ u64 h[8];
+ u64 t[2];
+ u64 f[2];
+} BLAKE2B_STATE;
+
+struct blake2b_param_s
+{
+ byte digest_length;
+ byte key_length;
+ byte fanout;
+ byte depth;
+ byte leaf_length[4];
+ byte node_offset[4];
+ byte xof_length[4];
+ byte node_depth;
+ byte inner_length;
+ byte reserved[14];
+ byte salt[16];
+ byte personal[16];
+};
+
+typedef struct BLAKE2B_CONTEXT_S
+{
+ BLAKE2B_STATE state;
+ byte buf[BLAKE2B_BLOCKBYTES];
+ size_t buflen;
+ size_t outlen;
+#ifdef USE_AVX2
+ unsigned int use_avx2:1;
+#endif
+} BLAKE2B_CONTEXT;
+
+typedef struct
+{
+ u32 h[8];
+ u32 t[2];
+ u32 f[2];
+} BLAKE2S_STATE;
+
+struct blake2s_param_s
+{
+ byte digest_length;
+ byte key_length;
+ byte fanout;
+ byte depth;
+ byte leaf_length[4];
+ byte node_offset[4];
+ byte xof_length[2];
+ byte node_depth;
+ byte inner_length;
+ /* byte reserved[0]; */
+ byte salt[8];
+ byte personal[8];
+};
+
+typedef struct BLAKE2S_CONTEXT_S
+{
+ BLAKE2S_STATE state;
+ byte buf[BLAKE2S_BLOCKBYTES];
+ size_t buflen;
+ size_t outlen;
+#ifdef USE_AVX
+ unsigned int use_avx:1;
+#endif
+} BLAKE2S_CONTEXT;
+
+typedef unsigned int (*blake2_transform_t)(void *S, const void *inblk,
+ size_t nblks);
+
+
+static const u64 blake2b_IV[8] =
+{
+ U64_C(0x6a09e667f3bcc908), U64_C(0xbb67ae8584caa73b),
+ U64_C(0x3c6ef372fe94f82b), U64_C(0xa54ff53a5f1d36f1),
+ U64_C(0x510e527fade682d1), U64_C(0x9b05688c2b3e6c1f),
+ U64_C(0x1f83d9abfb41bd6b), U64_C(0x5be0cd19137e2179)
+};
+
+static const u32 blake2s_IV[8] =
+{
+ 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
+ 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
+};
+
+static byte zero_block[BLAKE2B_BLOCKBYTES] = { 0, };
+
+
+static void blake2_write(void *S, const void *inbuf, size_t inlen,
+ byte *tmpbuf, size_t *tmpbuflen, size_t blkbytes,
+ blake2_transform_t transform_fn)
+{
+ const byte* in = inbuf;
+ unsigned int burn = 0;
+
+ if (inlen > 0)
+ {
+ size_t left = *tmpbuflen;
+ size_t fill = blkbytes - left;
+ size_t nblks;
+
+ if (inlen > fill)
+ {
+ if (fill > 0)
+ buf_cpy (tmpbuf + left, in, fill); /* Fill buffer */
+ left = 0;
+
+ burn = transform_fn (S, tmpbuf, 1); /* Increment counter + Compress */
+
+ in += fill;
+ inlen -= fill;
+
+ nblks = inlen / blkbytes - !(inlen % blkbytes);
+ if (nblks)
+ {
+ burn = transform_fn(S, in, nblks);
+ in += blkbytes * nblks;
+ inlen -= blkbytes * nblks;
+ }
+ }
+
+ gcry_assert (inlen > 0);
+
+ buf_cpy (tmpbuf + left, in, inlen);
+ *tmpbuflen = left + inlen;
+ }
+
+ if (burn)
+ _gcry_burn_stack (burn);
+
+ return;
+}
+
+
+static inline void blake2b_set_lastblock(BLAKE2B_STATE *S)
+{
+ S->f[0] = U64_C(0xffffffffffffffff);
+}
+
+static inline int blake2b_is_lastblock(const BLAKE2B_STATE *S)
+{
+ return S->f[0] != 0;
+}
+
+static inline void blake2b_increment_counter(BLAKE2B_STATE *S, const int inc)
+{
+ S->t[0] += (u64)inc;
+ S->t[1] += (S->t[0] < (u64)inc) - (inc < 0);
+}
+
+static inline u64 rotr64(u64 x, u64 n)
+{
+ return ((x >> (n & 63)) | (x << ((64 - n) & 63)));
+}
+
+static unsigned int blake2b_transform_generic(BLAKE2B_STATE *S,
+ const void *inblks,
+ size_t nblks)
+{
+ static const byte blake2b_sigma[12][16] =
+ {
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
+ };
+ const byte* in = inblks;
+ u64 m[16];
+ u64 v[16];
+
+ while (nblks--)
+ {
+ /* Increment counter */
+ blake2b_increment_counter (S, BLAKE2B_BLOCKBYTES);
+
+ /* Compress */
+ m[0] = buf_get_le64 (in + 0 * sizeof(m[0]));
+ m[1] = buf_get_le64 (in + 1 * sizeof(m[0]));
+ m[2] = buf_get_le64 (in + 2 * sizeof(m[0]));
+ m[3] = buf_get_le64 (in + 3 * sizeof(m[0]));
+ m[4] = buf_get_le64 (in + 4 * sizeof(m[0]));
+ m[5] = buf_get_le64 (in + 5 * sizeof(m[0]));
+ m[6] = buf_get_le64 (in + 6 * sizeof(m[0]));
+ m[7] = buf_get_le64 (in + 7 * sizeof(m[0]));
+ m[8] = buf_get_le64 (in + 8 * sizeof(m[0]));
+ m[9] = buf_get_le64 (in + 9 * sizeof(m[0]));
+ m[10] = buf_get_le64 (in + 10 * sizeof(m[0]));
+ m[11] = buf_get_le64 (in + 11 * sizeof(m[0]));
+ m[12] = buf_get_le64 (in + 12 * sizeof(m[0]));
+ m[13] = buf_get_le64 (in + 13 * sizeof(m[0]));
+ m[14] = buf_get_le64 (in + 14 * sizeof(m[0]));
+ m[15] = buf_get_le64 (in + 15 * sizeof(m[0]));
+
+ v[ 0] = S->h[0];
+ v[ 1] = S->h[1];
+ v[ 2] = S->h[2];
+ v[ 3] = S->h[3];
+ v[ 4] = S->h[4];
+ v[ 5] = S->h[5];
+ v[ 6] = S->h[6];
+ v[ 7] = S->h[7];
+ v[ 8] = blake2b_IV[0];
+ v[ 9] = blake2b_IV[1];
+ v[10] = blake2b_IV[2];
+ v[11] = blake2b_IV[3];
+ v[12] = blake2b_IV[4] ^ S->t[0];
+ v[13] = blake2b_IV[5] ^ S->t[1];
+ v[14] = blake2b_IV[6] ^ S->f[0];
+ v[15] = blake2b_IV[7] ^ S->f[1];
+
+#define G(r,i,a,b,c,d) \
+ do { \
+ a = a + b + m[blake2b_sigma[r][2*i+0]]; \
+ d = rotr64(d ^ a, 32); \
+ c = c + d; \
+ b = rotr64(b ^ c, 24); \
+ a = a + b + m[blake2b_sigma[r][2*i+1]]; \
+ d = rotr64(d ^ a, 16); \
+ c = c + d; \
+ b = rotr64(b ^ c, 63); \
+ } while(0)
+
+#define ROUND(r) \
+ do { \
+ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+ G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+ G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+ G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+ G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+ } while(0)
+
+ ROUND(0);
+ ROUND(1);
+ ROUND(2);
+ ROUND(3);
+ ROUND(4);
+ ROUND(5);
+ ROUND(6);
+ ROUND(7);
+ ROUND(8);
+ ROUND(9);
+ ROUND(10);
+ ROUND(11);
+
+#undef G
+#undef ROUND
+
+ S->h[0] = S->h[0] ^ v[0] ^ v[0 + 8];
+ S->h[1] = S->h[1] ^ v[1] ^ v[1 + 8];
+ S->h[2] = S->h[2] ^ v[2] ^ v[2 + 8];
+ S->h[3] = S->h[3] ^ v[3] ^ v[3 + 8];
+ S->h[4] = S->h[4] ^ v[4] ^ v[4 + 8];
+ S->h[5] = S->h[5] ^ v[5] ^ v[5 + 8];
+ S->h[6] = S->h[6] ^ v[6] ^ v[6 + 8];
+ S->h[7] = S->h[7] ^ v[7] ^ v[7 + 8];
+
+ in += BLAKE2B_BLOCKBYTES;
+ }
+
+ return sizeof(void *) * 4 + sizeof(u64) * 16 * 2;
+}
+
+#ifdef USE_AVX2
+unsigned int _gcry_blake2b_transform_amd64_avx2(BLAKE2B_STATE *S,
+ const void *inblks,
+ size_t nblks) ASM_FUNC_ABI;
+#endif
+
+static unsigned int blake2b_transform(void *ctx, const void *inblks,
+ size_t nblks)
+{
+ BLAKE2B_CONTEXT *c = ctx;
+ unsigned int nburn;
+
+ if (0)
+ {}
+#ifdef USE_AVX2
+ if (c->use_avx2)
+ nburn = _gcry_blake2b_transform_amd64_avx2(&c->state, inblks, nblks);
+#endif
+ else
+ nburn = blake2b_transform_generic(&c->state, inblks, nblks);
+
+ if (nburn)
+ nburn += ASM_EXTRA_STACK;
+
+ return nburn;
+}
+
+static void blake2b_final(void *ctx)
+{
+ BLAKE2B_CONTEXT *c = ctx;
+ BLAKE2B_STATE *S = &c->state;
+ unsigned int burn;
+ size_t i;
+
+ gcry_assert (sizeof(c->buf) >= c->outlen);
+ if (blake2b_is_lastblock(S))
+ return;
+
+ if (c->buflen < BLAKE2B_BLOCKBYTES)
+ memset (c->buf + c->buflen, 0, BLAKE2B_BLOCKBYTES - c->buflen); /* Padding */
+ blake2b_set_lastblock (S);
+ blake2b_increment_counter (S, (int)c->buflen - BLAKE2B_BLOCKBYTES);
+ burn = blake2b_transform (ctx, c->buf, 1);
+
+ /* Output full hash to buffer */
+ for (i = 0; i < 8; ++i)
+ buf_put_le64 (c->buf + sizeof(S->h[i]) * i, S->h[i]);
+
+ /* Zero out extra buffer bytes. */
+ if (c->outlen < sizeof(c->buf))
+ memset (c->buf + c->outlen, 0, sizeof(c->buf) - c->outlen);
+
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+static byte *blake2b_read(void *ctx)
+{
+ BLAKE2B_CONTEXT *c = ctx;
+ return c->buf;
+}
+
+static void blake2b_write(void *ctx, const void *inbuf, size_t inlen)
+{
+ BLAKE2B_CONTEXT *c = ctx;
+ BLAKE2B_STATE *S = &c->state;
+ blake2_write(S, inbuf, inlen, c->buf, &c->buflen, BLAKE2B_BLOCKBYTES,
+ blake2b_transform);
+}
+
+static inline void blake2b_init_param(BLAKE2B_STATE *S,
+ const struct blake2b_param_s *P)
+{
+ const byte *p = (const byte *)P;
+ size_t i;
+
+ /* init xors IV with input parameter block */
+
+ /* IV XOR ParamBlock */
+ for (i = 0; i < 8; ++i)
+ S->h[i] = blake2b_IV[i] ^ buf_get_le64(p + sizeof(S->h[i]) * i);
+}
+
+static inline gcry_err_code_t blake2b_init(BLAKE2B_CONTEXT *ctx,
+ const byte *key, size_t keylen)
+{
+ struct blake2b_param_s P[1] = { { 0, } };
+ BLAKE2B_STATE *S = &ctx->state;
+
+ if (!ctx->outlen || ctx->outlen > BLAKE2B_OUTBYTES)
+ return GPG_ERR_INV_ARG;
+ if (sizeof(P[0]) != sizeof(u64) * 8)
+ return GPG_ERR_INTERNAL;
+ if (keylen && (!key || keylen > BLAKE2B_KEYBYTES))
+ return GPG_ERR_INV_KEYLEN;
+
+ P->digest_length = ctx->outlen;
+ P->key_length = keylen;
+ P->fanout = 1;
+ P->depth = 1;
+
+ blake2b_init_param (S, P);
+ wipememory (P, sizeof(P));
+
+ if (key)
+ {
+ blake2b_write (ctx, key, keylen);
+ blake2b_write (ctx, zero_block, BLAKE2B_BLOCKBYTES - keylen);
+ }
+
+ return 0;
+}
+
+static gcry_err_code_t blake2b_init_ctx(void *ctx, unsigned int flags,
+ const byte *key, size_t keylen,
+ unsigned int dbits)
+{
+ BLAKE2B_CONTEXT *c = ctx;
+ unsigned int features = _gcry_get_hw_features ();
+
+ (void)features;
+ (void)flags;
+
+ memset (c, 0, sizeof (*c));
+
+#ifdef USE_AVX2
+ c->use_avx2 = !!(features & HWF_INTEL_AVX2);
+#endif
+
+ c->outlen = dbits / 8;
+ c->buflen = 0;
+ return blake2b_init(c, key, keylen);
+}
+
+static inline void blake2s_set_lastblock(BLAKE2S_STATE *S)
+{
+ S->f[0] = 0xFFFFFFFFUL;
+}
+
+static inline int blake2s_is_lastblock(BLAKE2S_STATE *S)
+{
+ return S->f[0] != 0;
+}
+
+static inline void blake2s_increment_counter(BLAKE2S_STATE *S, const int inc)
+{
+ S->t[0] += (u32)inc;
+ S->t[1] += (S->t[0] < (u32)inc) - (inc < 0);
+}
+
+static unsigned int blake2s_transform_generic(BLAKE2S_STATE *S,
+ const void *inblks,
+ size_t nblks)
+{
+ static const byte blake2s_sigma[10][16] =
+ {
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
+ };
+ unsigned int burn = 0;
+ const byte* in = inblks;
+ u32 m[16];
+ u32 v[16];
+
+ while (nblks--)
+ {
+ /* Increment counter */
+ blake2s_increment_counter (S, BLAKE2S_BLOCKBYTES);
+
+ /* Compress */
+ m[0] = buf_get_le32 (in + 0 * sizeof(m[0]));
+ m[1] = buf_get_le32 (in + 1 * sizeof(m[0]));
+ m[2] = buf_get_le32 (in + 2 * sizeof(m[0]));
+ m[3] = buf_get_le32 (in + 3 * sizeof(m[0]));
+ m[4] = buf_get_le32 (in + 4 * sizeof(m[0]));
+ m[5] = buf_get_le32 (in + 5 * sizeof(m[0]));
+ m[6] = buf_get_le32 (in + 6 * sizeof(m[0]));
+ m[7] = buf_get_le32 (in + 7 * sizeof(m[0]));
+ m[8] = buf_get_le32 (in + 8 * sizeof(m[0]));
+ m[9] = buf_get_le32 (in + 9 * sizeof(m[0]));
+ m[10] = buf_get_le32 (in + 10 * sizeof(m[0]));
+ m[11] = buf_get_le32 (in + 11 * sizeof(m[0]));
+ m[12] = buf_get_le32 (in + 12 * sizeof(m[0]));
+ m[13] = buf_get_le32 (in + 13 * sizeof(m[0]));
+ m[14] = buf_get_le32 (in + 14 * sizeof(m[0]));
+ m[15] = buf_get_le32 (in + 15 * sizeof(m[0]));
+
+ v[ 0] = S->h[0];
+ v[ 1] = S->h[1];
+ v[ 2] = S->h[2];
+ v[ 3] = S->h[3];
+ v[ 4] = S->h[4];
+ v[ 5] = S->h[5];
+ v[ 6] = S->h[6];
+ v[ 7] = S->h[7];
+ v[ 8] = blake2s_IV[0];
+ v[ 9] = blake2s_IV[1];
+ v[10] = blake2s_IV[2];
+ v[11] = blake2s_IV[3];
+ v[12] = S->t[0] ^ blake2s_IV[4];
+ v[13] = S->t[1] ^ blake2s_IV[5];
+ v[14] = S->f[0] ^ blake2s_IV[6];
+ v[15] = S->f[1] ^ blake2s_IV[7];
+
+#define G(r,i,a,b,c,d) \
+ do { \
+ a = a + b + m[blake2s_sigma[r][2*i+0]]; \
+ d = ror(d ^ a, 16); \
+ c = c + d; \
+ b = ror(b ^ c, 12); \
+ a = a + b + m[blake2s_sigma[r][2*i+1]]; \
+ d = ror(d ^ a, 8); \
+ c = c + d; \
+ b = ror(b ^ c, 7); \
+ } while(0)
+
+#define ROUND(r) \
+ do { \
+ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+ G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+ G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+ G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+ G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+ } while(0)
+
+ ROUND(0);
+ ROUND(1);
+ ROUND(2);
+ ROUND(3);
+ ROUND(4);
+ ROUND(5);
+ ROUND(6);
+ ROUND(7);
+ ROUND(8);
+ ROUND(9);
+
+#undef G
+#undef ROUND
+
+ S->h[0] = S->h[0] ^ v[0] ^ v[0 + 8];
+ S->h[1] = S->h[1] ^ v[1] ^ v[1 + 8];
+ S->h[2] = S->h[2] ^ v[2] ^ v[2 + 8];
+ S->h[3] = S->h[3] ^ v[3] ^ v[3 + 8];
+ S->h[4] = S->h[4] ^ v[4] ^ v[4 + 8];
+ S->h[5] = S->h[5] ^ v[5] ^ v[5 + 8];
+ S->h[6] = S->h[6] ^ v[6] ^ v[6 + 8];
+ S->h[7] = S->h[7] ^ v[7] ^ v[7 + 8];
+
+ in += BLAKE2S_BLOCKBYTES;
+ }
+
+ return burn;
+}
+
+#ifdef USE_AVX
+unsigned int _gcry_blake2s_transform_amd64_avx(BLAKE2S_STATE *S,
+ const void *inblks,
+ size_t nblks) ASM_FUNC_ABI;
+#endif
+
+static unsigned int blake2s_transform(void *ctx, const void *inblks,
+ size_t nblks)
+{
+ BLAKE2S_CONTEXT *c = ctx;
+ unsigned int nburn;
+
+ if (0)
+ {}
+#ifdef USE_AVX
+ if (c->use_avx)
+ nburn = _gcry_blake2s_transform_amd64_avx(&c->state, inblks, nblks);
+#endif
+ else
+ nburn = blake2s_transform_generic(&c->state, inblks, nblks);
+
+ if (nburn)
+ nburn += ASM_EXTRA_STACK;
+
+ return nburn;
+}
+
+static void blake2s_final(void *ctx)
+{
+ BLAKE2S_CONTEXT *c = ctx;
+ BLAKE2S_STATE *S = &c->state;
+ unsigned int burn;
+ size_t i;
+
+ gcry_assert (sizeof(c->buf) >= c->outlen);
+ if (blake2s_is_lastblock(S))
+ return;
+
+ if (c->buflen < BLAKE2S_BLOCKBYTES)
+ memset (c->buf + c->buflen, 0, BLAKE2S_BLOCKBYTES - c->buflen); /* Padding */
+ blake2s_set_lastblock (S);
+ blake2s_increment_counter (S, (int)c->buflen - BLAKE2S_BLOCKBYTES);
+ burn = blake2s_transform (ctx, c->buf, 1);
+
+ /* Output full hash to buffer */
+ for (i = 0; i < 8; ++i)
+ buf_put_le32 (c->buf + sizeof(S->h[i]) * i, S->h[i]);
+
+ /* Zero out extra buffer bytes. */
+ if (c->outlen < sizeof(c->buf))
+ memset (c->buf + c->outlen, 0, sizeof(c->buf) - c->outlen);
+
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+static byte *blake2s_read(void *ctx)
+{
+ BLAKE2S_CONTEXT *c = ctx;
+ return c->buf;
+}
+
+static void blake2s_write(void *ctx, const void *inbuf, size_t inlen)
+{
+ BLAKE2S_CONTEXT *c = ctx;
+ BLAKE2S_STATE *S = &c->state;
+ blake2_write(S, inbuf, inlen, c->buf, &c->buflen, BLAKE2S_BLOCKBYTES,
+ blake2s_transform);
+}
+
+static inline void blake2s_init_param(BLAKE2S_STATE *S,
+ const struct blake2s_param_s *P)
+{
+ const byte *p = (const byte *)P;
+ size_t i;
+
+ /* init2 xors IV with input parameter block */
+
+ /* IV XOR ParamBlock */
+ for (i = 0; i < 8; ++i)
+ S->h[i] ^= blake2s_IV[i] ^ buf_get_le32(&p[i * 4]);
+}
+
+static inline gcry_err_code_t blake2s_init(BLAKE2S_CONTEXT *ctx,
+ const byte *key, size_t keylen)
+{
+ struct blake2s_param_s P[1] = { { 0, } };
+ BLAKE2S_STATE *S = &ctx->state;
+
+ if (!ctx->outlen || ctx->outlen > BLAKE2S_OUTBYTES)
+ return GPG_ERR_INV_ARG;
+ if (sizeof(P[0]) != sizeof(u32) * 8)
+ return GPG_ERR_INTERNAL;
+ if (keylen && (!key || keylen > BLAKE2S_KEYBYTES))
+ return GPG_ERR_INV_KEYLEN;
+
+ P->digest_length = ctx->outlen;
+ P->key_length = keylen;
+ P->fanout = 1;
+ P->depth = 1;
+
+ blake2s_init_param (S, P);
+ wipememory (P, sizeof(P));
+
+ if (key)
+ {
+ blake2s_write (ctx, key, keylen);
+ blake2s_write (ctx, zero_block, BLAKE2S_BLOCKBYTES - keylen);
+ }
+
+ return 0;
+}
+
+static gcry_err_code_t blake2s_init_ctx(void *ctx, unsigned int flags,
+ const byte *key, size_t keylen,
+ unsigned int dbits)
+{
+ BLAKE2S_CONTEXT *c = ctx;
+ unsigned int features = _gcry_get_hw_features ();
+
+ (void)features;
+ (void)flags;
+
+ memset (c, 0, sizeof (*c));
+
+#ifdef USE_AVX
+ c->use_avx = !!(features & HWF_INTEL_AVX);
+#endif
+
+ c->outlen = dbits / 8;
+ c->buflen = 0;
+ return blake2s_init(c, key, keylen);
+}
+
+/* Selftests from "RFC 7693, Appendix E. BLAKE2b and BLAKE2s Self-Test
+ * Module C Source". */
+static void selftest_seq(byte *out, size_t len, u32 seed)
+{
+ size_t i;
+ u32 t, a, b;
+
+ a = 0xDEAD4BAD * seed;
+ b = 1;
+
+ for (i = 0; i < len; i++)
+ {
+ t = a + b;
+ a = b;
+ b = t;
+ out[i] = (t >> 24) & 0xFF;
+ }
+}
+
+static gpg_err_code_t
+selftests_blake2b (int algo, int extended, selftest_report_func_t report)
+{
+ static const byte blake2b_res[32] =
+ {
+ 0xC2, 0x3A, 0x78, 0x00, 0xD9, 0x81, 0x23, 0xBD,
+ 0x10, 0xF5, 0x06, 0xC6, 0x1E, 0x29, 0xDA, 0x56,
+ 0x03, 0xD7, 0x63, 0xB8, 0xBB, 0xAD, 0x2E, 0x73,
+ 0x7F, 0x5E, 0x76, 0x5A, 0x7B, 0xCC, 0xD4, 0x75
+ };
+ static const size_t b2b_md_len[4] = { 20, 32, 48, 64 };
+ static const size_t b2b_in_len[6] = { 0, 3, 128, 129, 255, 1024 };
+ size_t i, j, outlen, inlen;
+ byte in[1024], key[64];
+ BLAKE2B_CONTEXT ctx;
+ BLAKE2B_CONTEXT ctx2;
+ const char *what;
+ const char *errtxt;
+
+ (void)extended;
+
+ what = "rfc7693 BLAKE2b selftest";
+
+ /* 256-bit hash for testing */
+ if (blake2b_init_ctx(&ctx, 0, NULL, 0, 32 * 8))
+ {
+ errtxt = "init failed";
+ goto failed;
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ outlen = b2b_md_len[i];
+ for (j = 0; j < 6; j++)
+ {
+ inlen = b2b_in_len[j];
+
+ selftest_seq(in, inlen, inlen); /* unkeyed hash */
+ blake2b_init_ctx(&ctx2, 0, NULL, 0, outlen * 8);
+ blake2b_write(&ctx2, in, inlen);
+ blake2b_final(&ctx2);
+ blake2b_write(&ctx, ctx2.buf, outlen); /* hash the hash */
+
+ selftest_seq(key, outlen, outlen); /* keyed hash */
+ blake2b_init_ctx(&ctx2, 0, key, outlen, outlen * 8);
+ blake2b_write(&ctx2, in, inlen);
+ blake2b_final(&ctx2);
+ blake2b_write(&ctx, ctx2.buf, outlen); /* hash the hash */
+ }
+ }
+
+ /* compute and compare the hash of hashes */
+ blake2b_final(&ctx);
+ for (i = 0; i < 32; i++)
+ {
+ if (ctx.buf[i] != blake2b_res[i])
+ {
+ errtxt = "digest mismatch";
+ goto failed;
+ }
+ }
+
+ return 0;
+
+failed:
+ if (report)
+ report ("digest", algo, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_blake2s (int algo, int extended, selftest_report_func_t report)
+{
+ static const byte blake2s_res[32] =
+ {
+ 0x6A, 0x41, 0x1F, 0x08, 0xCE, 0x25, 0xAD, 0xCD,
+ 0xFB, 0x02, 0xAB, 0xA6, 0x41, 0x45, 0x1C, 0xEC,
+ 0x53, 0xC5, 0x98, 0xB2, 0x4F, 0x4F, 0xC7, 0x87,
+ 0xFB, 0xDC, 0x88, 0x79, 0x7F, 0x4C, 0x1D, 0xFE
+ };
+ static const size_t b2s_md_len[4] = { 16, 20, 28, 32 };
+ static const size_t b2s_in_len[6] = { 0, 3, 64, 65, 255, 1024 };
+ size_t i, j, outlen, inlen;
+ byte in[1024], key[32];
+ BLAKE2S_CONTEXT ctx;
+ BLAKE2S_CONTEXT ctx2;
+ const char *what;
+ const char *errtxt;
+
+ (void)extended;
+
+ what = "rfc7693 BLAKE2s selftest";
+
+ /* 256-bit hash for testing */
+ if (blake2s_init_ctx(&ctx, 0, NULL, 0, 32 * 8))
+ {
+ errtxt = "init failed";
+ goto failed;
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ outlen = b2s_md_len[i];
+ for (j = 0; j < 6; j++)
+ {
+ inlen = b2s_in_len[j];
+
+ selftest_seq(in, inlen, inlen); /* unkeyed hash */
+ blake2s_init_ctx(&ctx2, 0, NULL, 0, outlen * 8);
+ blake2s_write(&ctx2, in, inlen);
+ blake2s_final(&ctx2);
+ blake2s_write(&ctx, ctx2.buf, outlen); /* hash the hash */
+
+ selftest_seq(key, outlen, outlen); /* keyed hash */
+ blake2s_init_ctx(&ctx2, 0, key, outlen, outlen * 8);
+ blake2s_write(&ctx2, in, inlen);
+ blake2s_final(&ctx2);
+ blake2s_write(&ctx, ctx2.buf, outlen); /* hash the hash */
+ }
+ }
+
+ /* compute and compare the hash of hashes */
+ blake2s_final(&ctx);
+ for (i = 0; i < 32; i++)
+ {
+ if (ctx.buf[i] != blake2s_res[i])
+ {
+ errtxt = "digest mismatch";
+ goto failed;
+ }
+ }
+
+ return 0;
+
+failed:
+ if (report)
+ report ("digest", algo, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+gcry_err_code_t _gcry_blake2_init_with_key(void *ctx, unsigned int flags,
+ const unsigned char *key,
+ size_t keylen, int algo)
+{
+ gcry_err_code_t rc;
+ switch (algo)
+ {
+ case GCRY_MD_BLAKE2B_512:
+ rc = blake2b_init_ctx (ctx, flags, key, keylen, 512);
+ break;
+ case GCRY_MD_BLAKE2B_384:
+ rc = blake2b_init_ctx (ctx, flags, key, keylen, 384);
+ break;
+ case GCRY_MD_BLAKE2B_256:
+ rc = blake2b_init_ctx (ctx, flags, key, keylen, 256);
+ break;
+ case GCRY_MD_BLAKE2B_160:
+ rc = blake2b_init_ctx (ctx, flags, key, keylen, 160);
+ break;
+ case GCRY_MD_BLAKE2S_256:
+ rc = blake2s_init_ctx (ctx, flags, key, keylen, 256);
+ break;
+ case GCRY_MD_BLAKE2S_224:
+ rc = blake2s_init_ctx (ctx, flags, key, keylen, 224);
+ break;
+ case GCRY_MD_BLAKE2S_160:
+ rc = blake2s_init_ctx (ctx, flags, key, keylen, 160);
+ break;
+ case GCRY_MD_BLAKE2S_128:
+ rc = blake2s_init_ctx (ctx, flags, key, keylen, 128);
+ break;
+ default:
+ rc = GPG_ERR_DIGEST_ALGO;
+ break;
+ }
+
+ return rc;
+}
+
+
+#define DEFINE_BLAKE2_VARIANT(bs, BS, dbits, oid_branch) \
+ static void blake2##bs##_##dbits##_init(void *ctx, unsigned int flags) \
+ { \
+ int err = blake2##bs##_init_ctx (ctx, flags, NULL, 0, dbits); \
+ gcry_assert (err == 0); \
+ } \
+ static void \
+ _gcry_blake2##bs##_##dbits##_hash_buffer(void *outbuf, \
+ const void *buffer, size_t length) \
+ { \
+ BLAKE2##BS##_CONTEXT hd; \
+ blake2##bs##_##dbits##_init (&hd, 0); \
+ blake2##bs##_write (&hd, buffer, length); \
+ blake2##bs##_final (&hd); \
+ memcpy (outbuf, blake2##bs##_read (&hd), dbits / 8); \
+ } \
+ static void \
+ _gcry_blake2##bs##_##dbits##_hash_buffers(void *outbuf, \
+ const gcry_buffer_t *iov, int iovcnt) \
+ { \
+ BLAKE2##BS##_CONTEXT hd; \
+ blake2##bs##_##dbits##_init (&hd, 0); \
+ for (;iovcnt > 0; iov++, iovcnt--) \
+ blake2##bs##_write (&hd, (const char*)iov[0].data + iov[0].off, \
+ iov[0].len); \
+ blake2##bs##_final (&hd); \
+ memcpy (outbuf, blake2##bs##_read (&hd), dbits / 8); \
+ } \
+ static byte blake2##bs##_##dbits##_asn[] = { 0x30 }; \
+ static gcry_md_oid_spec_t oid_spec_blake2##bs##_##dbits[] = \
+ { \
+ { " 1.3.6.1.4.1.1722.12.2." oid_branch }, \
+ { NULL } \
+ }; \
+ gcry_md_spec_t _gcry_digest_spec_blake2##bs##_##dbits = \
+ { \
+ GCRY_MD_BLAKE2##BS##_##dbits, {0, 0}, \
+ "BLAKE2" #BS "_" #dbits, blake2##bs##_##dbits##_asn, \
+ DIM (blake2##bs##_##dbits##_asn), oid_spec_blake2##bs##_##dbits, \
+ dbits / 8, blake2##bs##_##dbits##_init, blake2##bs##_write, \
+ blake2##bs##_final, blake2##bs##_read, NULL, \
+ _gcry_blake2##bs##_##dbits##_hash_buffer, \
+ _gcry_blake2##bs##_##dbits##_hash_buffers, \
+ sizeof (BLAKE2##BS##_CONTEXT), selftests_blake2##bs \
+ };
+
+DEFINE_BLAKE2_VARIANT(b, B, 512, "1.16")
+DEFINE_BLAKE2_VARIANT(b, B, 384, "1.12")
+DEFINE_BLAKE2_VARIANT(b, B, 256, "1.8")
+DEFINE_BLAKE2_VARIANT(b, B, 160, "1.5")
+
+DEFINE_BLAKE2_VARIANT(s, S, 256, "2.8")
+DEFINE_BLAKE2_VARIANT(s, S, 224, "2.7")
+DEFINE_BLAKE2_VARIANT(s, S, 160, "2.5")
+DEFINE_BLAKE2_VARIANT(s, S, 128, "2.4")
diff --git a/comm/third_party/libgcrypt/cipher/blake2b-amd64-avx2.S b/comm/third_party/libgcrypt/cipher/blake2b-amd64-avx2.S
new file mode 100644
index 0000000000..357e8a5167
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/blake2b-amd64-avx2.S
@@ -0,0 +1,300 @@
+/* blake2b-amd64-avx2.S - AVX2 implementation of BLAKE2b
+ *
+ * Copyright (C) 2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain/CC0 BLAKE2 reference implementation
+ * by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/sse
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#include "asm-common-amd64.h"
+
+.text
+
+/* register macros */
+#define RSTATE %rdi
+#define RINBLKS %rsi
+#define RNBLKS %rdx
+#define RIV %rcx
+
+/* state structure */
+#define STATE_H 0
+#define STATE_T (STATE_H + 8 * 8)
+#define STATE_F (STATE_T + 2 * 8)
+
+/* vector registers */
+#define ROW1 %ymm0
+#define ROW2 %ymm1
+#define ROW3 %ymm2
+#define ROW4 %ymm3
+#define TMP1 %ymm4
+#define TMP1x %xmm4
+#define R16 %ymm5
+#define R24 %ymm6
+
+#define MA1 %ymm8
+#define MA2 %ymm9
+#define MA3 %ymm10
+#define MA4 %ymm11
+#define MA1x %xmm8
+#define MA2x %xmm9
+#define MA3x %xmm10
+#define MA4x %xmm11
+
+#define MB1 %ymm12
+#define MB2 %ymm13
+#define MB3 %ymm14
+#define MB4 %ymm15
+#define MB1x %xmm12
+#define MB2x %xmm13
+#define MB3x %xmm14
+#define MB4x %xmm15
+
+/**********************************************************************
+ blake2b/AVX2
+ **********************************************************************/
+
+#define GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ s0, s1, s2, s3, s4, s5, s6, s7, s8, \
+ s9, s10, s11, s12, s13, s14, s15) \
+ vmovq (s0)*8(RINBLKS), m1x; \
+ vmovq (s4)*8(RINBLKS), TMP1x; \
+ vpinsrq $1, (s2)*8(RINBLKS), m1x, m1x; \
+ vpinsrq $1, (s6)*8(RINBLKS), TMP1x, TMP1x; \
+ vinserti128 $1, TMP1x, m1, m1; \
+ vmovq (s1)*8(RINBLKS), m2x; \
+ vmovq (s5)*8(RINBLKS), TMP1x; \
+ vpinsrq $1, (s3)*8(RINBLKS), m2x, m2x; \
+ vpinsrq $1, (s7)*8(RINBLKS), TMP1x, TMP1x; \
+ vinserti128 $1, TMP1x, m2, m2; \
+ vmovq (s8)*8(RINBLKS), m3x; \
+ vmovq (s12)*8(RINBLKS), TMP1x; \
+ vpinsrq $1, (s10)*8(RINBLKS), m3x, m3x; \
+ vpinsrq $1, (s14)*8(RINBLKS), TMP1x, TMP1x; \
+ vinserti128 $1, TMP1x, m3, m3; \
+ vmovq (s9)*8(RINBLKS), m4x; \
+ vmovq (s13)*8(RINBLKS), TMP1x; \
+ vpinsrq $1, (s11)*8(RINBLKS), m4x, m4x; \
+ vpinsrq $1, (s15)*8(RINBLKS), TMP1x, TMP1x; \
+ vinserti128 $1, TMP1x, m4, m4;
+
+#define LOAD_MSG_0(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
+#define LOAD_MSG_1(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3)
+#define LOAD_MSG_2(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4)
+#define LOAD_MSG_3(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8)
+#define LOAD_MSG_4(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13)
+#define LOAD_MSG_5(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9)
+#define LOAD_MSG_6(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11)
+#define LOAD_MSG_7(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10)
+#define LOAD_MSG_8(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5)
+#define LOAD_MSG_9(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ GATHER_MSG(m1, m2, m3, m4, m1x, m2x, m3x, m4x, \
+ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0)
+#define LOAD_MSG_10(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ LOAD_MSG_0(m1, m2, m3, m4, m1x, m2x, m3x, m4x)
+#define LOAD_MSG_11(m1, m2, m3, m4, m1x, m2x, m3x, m4x) \
+ LOAD_MSG_1(m1, m2, m3, m4, m1x, m2x, m3x, m4x)
+
+#define LOAD_MSG(r, m1, m2, m3, m4) \
+ LOAD_MSG_##r(m1, m2, m3, m4, m1##x, m2##x, m3##x, m4##x)
+
+#define ROR_32(in, out) vpshufd $0xb1, in, out;
+
+#define ROR_24(in, out) vpshufb R24, in, out;
+
+#define ROR_16(in, out) vpshufb R16, in, out;
+
+#define ROR_63(in, out) \
+ vpsrlq $63, in, TMP1; \
+ vpaddq in, in, out; \
+ vpxor TMP1, out, out;
+
+#define G(r1, r2, r3, r4, m, ROR_A, ROR_B) \
+ vpaddq m, r1, r1; \
+ vpaddq r2, r1, r1; \
+ vpxor r1, r4, r4; \
+ ROR_A(r4, r4); \
+ vpaddq r4, r3, r3; \
+ vpxor r3, r2, r2; \
+ ROR_B(r2, r2);
+
+#define G1(r1, r2, r3, r4, m) \
+ G(r1, r2, r3, r4, m, ROR_32, ROR_24);
+
+#define G2(r1, r2, r3, r4, m) \
+ G(r1, r2, r3, r4, m, ROR_16, ROR_63);
+
+#define MM_SHUFFLE(z,y,x,w) \
+ (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
+
+#define DIAGONALIZE(r1, r2, r3, r4) \
+ vpermq $MM_SHUFFLE(0,3,2,1), r2, r2; \
+ vpermq $MM_SHUFFLE(1,0,3,2), r3, r3; \
+ vpermq $MM_SHUFFLE(2,1,0,3), r4, r4;
+
+#define UNDIAGONALIZE(r1, r2, r3, r4) \
+ vpermq $MM_SHUFFLE(2,1,0,3), r2, r2; \
+ vpermq $MM_SHUFFLE(1,0,3,2), r3, r3; \
+ vpermq $MM_SHUFFLE(0,3,2,1), r4, r4;
+
+#define ROUND(r, m1, m2, m3, m4) \
+ G1(ROW1, ROW2, ROW3, ROW4, m1); \
+ G2(ROW1, ROW2, ROW3, ROW4, m2); \
+ DIAGONALIZE(ROW1, ROW2, ROW3, ROW4); \
+ G1(ROW1, ROW2, ROW3, ROW4, m3); \
+ G2(ROW1, ROW2, ROW3, ROW4, m4); \
+ UNDIAGONALIZE(ROW1, ROW2, ROW3, ROW4);
+
+blake2b_data:
+.align 32
+.Liv:
+ .quad 0x6a09e667f3bcc908, 0xbb67ae8584caa73b
+ .quad 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1
+ .quad 0x510e527fade682d1, 0x9b05688c2b3e6c1f
+ .quad 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
+.Lshuf_ror16:
+ .byte 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9
+.Lshuf_ror24:
+ .byte 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10
+
+.align 64
+.globl _gcry_blake2b_transform_amd64_avx2
+ELF(.type _gcry_blake2b_transform_amd64_avx2,@function;)
+
+_gcry_blake2b_transform_amd64_avx2:
+ /* input:
+ * %rdi: state
+ * %rsi: blks
+ * %rdx: num_blks
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ addq $128, (STATE_T + 0)(RSTATE);
+ adcq $0, (STATE_T + 8)(RSTATE);
+
+ vbroadcasti128 .Lshuf_ror16 rRIP, R16;
+ vbroadcasti128 .Lshuf_ror24 rRIP, R24;
+
+ vmovdqa .Liv+(0 * 8) rRIP, ROW3;
+ vmovdqa .Liv+(4 * 8) rRIP, ROW4;
+
+ vmovdqu (STATE_H + 0 * 8)(RSTATE), ROW1;
+ vmovdqu (STATE_H + 4 * 8)(RSTATE), ROW2;
+
+ vpxor (STATE_T)(RSTATE), ROW4, ROW4;
+
+ LOAD_MSG(0, MA1, MA2, MA3, MA4);
+ LOAD_MSG(1, MB1, MB2, MB3, MB4);
+
+.Loop:
+ ROUND(0, MA1, MA2, MA3, MA4);
+ LOAD_MSG(2, MA1, MA2, MA3, MA4);
+ ROUND(1, MB1, MB2, MB3, MB4);
+ LOAD_MSG(3, MB1, MB2, MB3, MB4);
+ ROUND(2, MA1, MA2, MA3, MA4);
+ LOAD_MSG(4, MA1, MA2, MA3, MA4);
+ ROUND(3, MB1, MB2, MB3, MB4);
+ LOAD_MSG(5, MB1, MB2, MB3, MB4);
+ ROUND(4, MA1, MA2, MA3, MA4);
+ LOAD_MSG(6, MA1, MA2, MA3, MA4);
+ ROUND(5, MB1, MB2, MB3, MB4);
+ LOAD_MSG(7, MB1, MB2, MB3, MB4);
+ ROUND(6, MA1, MA2, MA3, MA4);
+ LOAD_MSG(8, MA1, MA2, MA3, MA4);
+ ROUND(7, MB1, MB2, MB3, MB4);
+ LOAD_MSG(9, MB1, MB2, MB3, MB4);
+ ROUND(8, MA1, MA2, MA3, MA4);
+ LOAD_MSG(10, MA1, MA2, MA3, MA4);
+ ROUND(9, MB1, MB2, MB3, MB4);
+ LOAD_MSG(11, MB1, MB2, MB3, MB4);
+ sub $1, RNBLKS;
+ jz .Loop_end;
+
+ lea 128(RINBLKS), RINBLKS;
+ addq $128, (STATE_T + 0)(RSTATE);
+ adcq $0, (STATE_T + 8)(RSTATE);
+
+ ROUND(10, MA1, MA2, MA3, MA4);
+ LOAD_MSG(0, MA1, MA2, MA3, MA4);
+ ROUND(11, MB1, MB2, MB3, MB4);
+ LOAD_MSG(1, MB1, MB2, MB3, MB4);
+
+ vpxor ROW3, ROW1, ROW1;
+ vpxor ROW4, ROW2, ROW2;
+
+ vmovdqa .Liv+(0 * 8) rRIP, ROW3;
+ vmovdqa .Liv+(4 * 8) rRIP, ROW4;
+
+ vpxor (STATE_H + 0 * 8)(RSTATE), ROW1, ROW1;
+ vpxor (STATE_H + 4 * 8)(RSTATE), ROW2, ROW2;
+
+ vmovdqu ROW1, (STATE_H + 0 * 8)(RSTATE);
+ vmovdqu ROW2, (STATE_H + 4 * 8)(RSTATE);
+
+ vpxor (STATE_T)(RSTATE), ROW4, ROW4;
+
+ jmp .Loop;
+
+.Loop_end:
+ ROUND(10, MA1, MA2, MA3, MA4);
+ ROUND(11, MB1, MB2, MB3, MB4);
+
+ vpxor ROW3, ROW1, ROW1;
+ vpxor ROW4, ROW2, ROW2;
+ vpxor (STATE_H + 0 * 8)(RSTATE), ROW1, ROW1;
+ vpxor (STATE_H + 4 * 8)(RSTATE), ROW2, ROW2;
+
+ vmovdqu ROW1, (STATE_H + 0 * 8)(RSTATE);
+ vmovdqu ROW2, (STATE_H + 4 * 8)(RSTATE);
+
+ xor %eax, %eax;
+ vzeroall;
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_blake2b_transform_amd64_avx2,
+ .-_gcry_blake2b_transform_amd64_avx2;)
+
+#endif /*defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/blake2s-amd64-avx.S b/comm/third_party/libgcrypt/cipher/blake2s-amd64-avx.S
new file mode 100644
index 0000000000..5b93675871
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/blake2s-amd64-avx.S
@@ -0,0 +1,278 @@
+/* blake2s-amd64-avx.S - AVX implementation of BLAKE2s
+ *
+ * Copyright (C) 2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain/CC0 BLAKE2 reference implementation
+ * by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/sse
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(HAVE_GCC_INLINE_ASM_AVX) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#include "asm-common-amd64.h"
+
+.text
+
+/* register macros */
+#define RSTATE %rdi
+#define RINBLKS %rsi
+#define RNBLKS %rdx
+#define RIV %rcx
+
+/* state structure */
+#define STATE_H 0
+#define STATE_T (STATE_H + 8 * 4)
+#define STATE_F (STATE_T + 2 * 4)
+
+/* vector registers */
+#define ROW1 %xmm0
+#define ROW2 %xmm1
+#define ROW3 %xmm2
+#define ROW4 %xmm3
+#define TMP1 %xmm4
+#define TMP1x %xmm4
+#define R16 %xmm5
+#define R8 %xmm6
+
+#define MA1 %xmm8
+#define MA2 %xmm9
+#define MA3 %xmm10
+#define MA4 %xmm11
+
+#define MB1 %xmm12
+#define MB2 %xmm13
+#define MB3 %xmm14
+#define MB4 %xmm15
+
+/**********************************************************************
+ blake2s/AVX
+ **********************************************************************/
+
+#define GATHER_MSG(m1, m2, m3, m4, \
+ s0, s1, s2, s3, s4, s5, s6, s7, s8, \
+ s9, s10, s11, s12, s13, s14, s15) \
+ vmovd (s0)*4(RINBLKS), m1; \
+ vmovd (s1)*4(RINBLKS), m2; \
+ vmovd (s8)*4(RINBLKS), m3; \
+ vmovd (s9)*4(RINBLKS), m4; \
+ vpinsrd $1, (s2)*4(RINBLKS), m1, m1; \
+ vpinsrd $1, (s3)*4(RINBLKS), m2, m2; \
+ vpinsrd $1, (s10)*4(RINBLKS), m3, m3; \
+ vpinsrd $1, (s11)*4(RINBLKS), m4, m4; \
+ vpinsrd $2, (s4)*4(RINBLKS), m1, m1; \
+ vpinsrd $2, (s5)*4(RINBLKS), m2, m2; \
+ vpinsrd $2, (s12)*4(RINBLKS), m3, m3; \
+ vpinsrd $2, (s13)*4(RINBLKS), m4, m4; \
+ vpinsrd $3, (s6)*4(RINBLKS), m1, m1; \
+ vpinsrd $3, (s7)*4(RINBLKS), m2, m2; \
+ vpinsrd $3, (s14)*4(RINBLKS), m3, m3; \
+ vpinsrd $3, (s15)*4(RINBLKS), m4, m4;
+
+#define LOAD_MSG_0(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
+#define LOAD_MSG_1(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3)
+#define LOAD_MSG_2(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4)
+#define LOAD_MSG_3(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8)
+#define LOAD_MSG_4(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13)
+#define LOAD_MSG_5(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9)
+#define LOAD_MSG_6(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11)
+#define LOAD_MSG_7(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10)
+#define LOAD_MSG_8(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5)
+#define LOAD_MSG_9(m1, m2, m3, m4) \
+ GATHER_MSG(m1, m2, m3, m4, \
+ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0)
+
+#define LOAD_MSG(r, m1, m2, m3, m4) LOAD_MSG_##r(m1, m2, m3, m4)
+
+#define ROR_16(in, out) vpshufb R16, in, out;
+
+#define ROR_8(in, out) vpshufb R8, in, out;
+
+#define ROR_12(in, out) \
+ vpsrld $12, in, TMP1; \
+ vpslld $(32 - 12), in, out; \
+ vpxor TMP1, out, out;
+
+#define ROR_7(in, out) \
+ vpsrld $7, in, TMP1; \
+ vpslld $(32 - 7), in, out; \
+ vpxor TMP1, out, out;
+
+#define G(r1, r2, r3, r4, m, ROR_A, ROR_B) \
+ vpaddd m, r1, r1; \
+ vpaddd r2, r1, r1; \
+ vpxor r1, r4, r4; \
+ ROR_A(r4, r4); \
+ vpaddd r4, r3, r3; \
+ vpxor r3, r2, r2; \
+ ROR_B(r2, r2);
+
+#define G1(r1, r2, r3, r4, m) \
+ G(r1, r2, r3, r4, m, ROR_16, ROR_12);
+
+#define G2(r1, r2, r3, r4, m) \
+ G(r1, r2, r3, r4, m, ROR_8, ROR_7);
+
+#define MM_SHUFFLE(z,y,x,w) \
+ (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
+
+#define DIAGONALIZE(r1, r2, r3, r4) \
+ vpshufd $MM_SHUFFLE(0,3,2,1), r2, r2; \
+ vpshufd $MM_SHUFFLE(1,0,3,2), r3, r3; \
+ vpshufd $MM_SHUFFLE(2,1,0,3), r4, r4;
+
+#define UNDIAGONALIZE(r1, r2, r3, r4) \
+ vpshufd $MM_SHUFFLE(2,1,0,3), r2, r2; \
+ vpshufd $MM_SHUFFLE(1,0,3,2), r3, r3; \
+ vpshufd $MM_SHUFFLE(0,3,2,1), r4, r4;
+
+#define ROUND(r, m1, m2, m3, m4) \
+ G1(ROW1, ROW2, ROW3, ROW4, m1); \
+ G2(ROW1, ROW2, ROW3, ROW4, m2); \
+ DIAGONALIZE(ROW1, ROW2, ROW3, ROW4); \
+ G1(ROW1, ROW2, ROW3, ROW4, m3); \
+ G2(ROW1, ROW2, ROW3, ROW4, m4); \
+ UNDIAGONALIZE(ROW1, ROW2, ROW3, ROW4);
+
+blake2s_data:
+.align 16
+.Liv:
+ .long 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A
+ .long 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
+.Lshuf_ror16:
+ .byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.Lshuf_ror8:
+ .byte 1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12
+
+.align 64
+.globl _gcry_blake2s_transform_amd64_avx
+ELF(.type _gcry_blake2s_transform_amd64_avx,@function;)
+
+_gcry_blake2s_transform_amd64_avx:
+ /* input:
+ * %rdi: state
+ * %rsi: blks
+ * %rdx: num_blks
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ addq $64, (STATE_T + 0)(RSTATE);
+
+ vmovdqa .Lshuf_ror16 rRIP, R16;
+ vmovdqa .Lshuf_ror8 rRIP, R8;
+
+ vmovdqa .Liv+(0 * 4) rRIP, ROW3;
+ vmovdqa .Liv+(4 * 4) rRIP, ROW4;
+
+ vmovdqu (STATE_H + 0 * 4)(RSTATE), ROW1;
+ vmovdqu (STATE_H + 4 * 4)(RSTATE), ROW2;
+
+ vpxor (STATE_T)(RSTATE), ROW4, ROW4;
+
+ LOAD_MSG(0, MA1, MA2, MA3, MA4);
+ LOAD_MSG(1, MB1, MB2, MB3, MB4);
+
+.Loop:
+ ROUND(0, MA1, MA2, MA3, MA4);
+ LOAD_MSG(2, MA1, MA2, MA3, MA4);
+ ROUND(1, MB1, MB2, MB3, MB4);
+ LOAD_MSG(3, MB1, MB2, MB3, MB4);
+ ROUND(2, MA1, MA2, MA3, MA4);
+ LOAD_MSG(4, MA1, MA2, MA3, MA4);
+ ROUND(3, MB1, MB2, MB3, MB4);
+ LOAD_MSG(5, MB1, MB2, MB3, MB4);
+ ROUND(4, MA1, MA2, MA3, MA4);
+ LOAD_MSG(6, MA1, MA2, MA3, MA4);
+ ROUND(5, MB1, MB2, MB3, MB4);
+ LOAD_MSG(7, MB1, MB2, MB3, MB4);
+ ROUND(6, MA1, MA2, MA3, MA4);
+ LOAD_MSG(8, MA1, MA2, MA3, MA4);
+ ROUND(7, MB1, MB2, MB3, MB4);
+ LOAD_MSG(9, MB1, MB2, MB3, MB4);
+ sub $1, RNBLKS;
+ jz .Loop_end;
+
+ lea 64(RINBLKS), RINBLKS;
+ addq $64, (STATE_T + 0)(RSTATE);
+
+ ROUND(8, MA1, MA2, MA3, MA4);
+ LOAD_MSG(0, MA1, MA2, MA3, MA4);
+ ROUND(9, MB1, MB2, MB3, MB4);
+ LOAD_MSG(1, MB1, MB2, MB3, MB4);
+
+ vpxor ROW3, ROW1, ROW1;
+ vpxor ROW4, ROW2, ROW2;
+
+ vmovdqa .Liv+(0 * 4) rRIP, ROW3;
+ vmovdqa .Liv+(4 * 4) rRIP, ROW4;
+
+ vpxor (STATE_H + 0 * 4)(RSTATE), ROW1, ROW1;
+ vpxor (STATE_H + 4 * 4)(RSTATE), ROW2, ROW2;
+
+ vmovdqu ROW1, (STATE_H + 0 * 4)(RSTATE);
+ vmovdqu ROW2, (STATE_H + 4 * 4)(RSTATE);
+
+ vpxor (STATE_T)(RSTATE), ROW4, ROW4;
+
+ jmp .Loop;
+
+.Loop_end:
+ ROUND(8, MA1, MA2, MA3, MA4);
+ ROUND(9, MB1, MB2, MB3, MB4);
+
+ vpxor ROW3, ROW1, ROW1;
+ vpxor ROW4, ROW2, ROW2;
+ vpxor (STATE_H + 0 * 4)(RSTATE), ROW1, ROW1;
+ vpxor (STATE_H + 4 * 4)(RSTATE), ROW2, ROW2;
+
+ vmovdqu ROW1, (STATE_H + 0 * 4)(RSTATE);
+ vmovdqu ROW2, (STATE_H + 4 * 4)(RSTATE);
+
+ xor %eax, %eax;
+ vzeroall;
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_blake2s_transform_amd64_avx,
+ .-_gcry_blake2s_transform_amd64_avx;)
+
+#endif /*defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/blowfish-amd64.S b/comm/third_party/libgcrypt/cipher/blowfish-amd64.S
new file mode 100644
index 0000000000..bdb361d7eb
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/blowfish-amd64.S
@@ -0,0 +1,601 @@
+/* blowfish-amd64.S - AMD64 assembly implementation of Blowfish cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(USE_BLOWFISH) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#include "asm-common-amd64.h"
+
+.text
+
+/* structure of BLOWFISH_context: */
+#define s0 0
+#define s1 ((s0) + 256 * 4)
+#define s2 ((s1) + 256 * 4)
+#define s3 ((s2) + 256 * 4)
+#define p ((s3) + 256 * 4)
+
+/* register macros */
+#define CTX %rdi
+#define RIO %rsi
+
+#define RX0 %rax
+#define RX1 %rbx
+#define RX2 %rcx
+#define RX3 %rdx
+
+#define RX0d %eax
+#define RX1d %ebx
+#define RX2d %ecx
+#define RX3d %edx
+
+#define RX0bl %al
+#define RX1bl %bl
+#define RX2bl %cl
+#define RX3bl %dl
+
+#define RX0bh %ah
+#define RX1bh %bh
+#define RX2bh %ch
+#define RX3bh %dh
+
+#define RT0 %rbp
+#define RT1 %rsi
+#define RT2 %r8
+#define RT3 %r9
+
+#define RT0d %ebp
+#define RT1d %esi
+#define RT2d %r8d
+#define RT3d %r9d
+
+#define RKEY %r10
+
+/***********************************************************************
+ * 1-way blowfish
+ ***********************************************************************/
+#define F() \
+ movzbl RX0bh, RT1d; \
+ movzbl RX0bl, RT3d; \
+ rorq $16, RX0; \
+ movzbl RX0bh, RT0d; \
+ movzbl RX0bl, RT2d; \
+ rorq $16, RX0; \
+ movl s0(CTX,RT0,4), RT0d; \
+ addl s1(CTX,RT2,4), RT0d; \
+ xorl s2(CTX,RT1,4), RT0d; \
+ addl s3(CTX,RT3,4), RT0d; \
+ xorq RT0, RX0;
+
+#define load_roundkey_enc(n) \
+ movq p+4*(n)(CTX), RX3;
+
+#define add_roundkey_enc() \
+ xorq RX3, RX0;
+
+#define round_enc(n) \
+ add_roundkey_enc(); \
+ load_roundkey_enc(n); \
+ \
+ F(); \
+ F();
+
+#define load_roundkey_dec(n) \
+ movq p+4*(n-1)(CTX), RX3; \
+ rorq $32, RX3;
+
+#define add_roundkey_dec() \
+ xorq RX3, RX0;
+
+#define round_dec(n) \
+ add_roundkey_dec(); \
+ load_roundkey_dec(n); \
+ \
+ F(); \
+ F();
+
+#define read_block() \
+ movq (RIO), RX0; \
+ rorq $32, RX0; \
+ bswapq RX0;
+
+#define write_block() \
+ bswapq RX0; \
+ movq RX0, (RIO);
+
+.align 8
+ELF(.type __blowfish_enc_blk1,@function;)
+
+__blowfish_enc_blk1:
+ /* input:
+ * %rdi: ctx, CTX
+ * RX0: input plaintext block
+ * output:
+ * RX0: output plaintext block
+ */
+ CFI_STARTPROC();
+ movq %rbp, %r11;
+ CFI_REGISTER(%rbp, %r11);
+
+ load_roundkey_enc(0);
+ round_enc(2);
+ round_enc(4);
+ round_enc(6);
+ round_enc(8);
+ round_enc(10);
+ round_enc(12);
+ round_enc(14);
+ round_enc(16);
+ add_roundkey_enc();
+
+ movq %r11, %rbp;
+ CFI_RESTORE(%rbp)
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __blowfish_enc_blk1,.-__blowfish_enc_blk1;)
+
+.align 8
+.globl _gcry_blowfish_amd64_do_encrypt
+ELF(.type _gcry_blowfish_amd64_do_encrypt,@function;)
+
+_gcry_blowfish_amd64_do_encrypt:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: u32 *ret_xl
+ * %rdx: u32 *ret_xr
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ movl (%rdx), RX0d;
+ shlq $32, RX0;
+ movl (%rsi), RT3d;
+ movq %rdx, %r10;
+ orq RT3, RX0;
+ movq %rsi, RX2;
+
+ call __blowfish_enc_blk1;
+
+ movl RX0d, (%r10);
+ shrq $32, RX0;
+ movl RX0d, (RX2);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_blowfish_amd64_do_encrypt,.-_gcry_blowfish_amd64_do_encrypt;)
+
+.align 8
+.globl _gcry_blowfish_amd64_encrypt_block
+ELF(.type _gcry_blowfish_amd64_encrypt_block,@function;)
+
+_gcry_blowfish_amd64_encrypt_block:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ movq %rsi, %r10;
+
+ movq %rdx, RIO;
+ read_block();
+
+ call __blowfish_enc_blk1;
+
+ movq %r10, RIO;
+ write_block();
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_blowfish_amd64_encrypt_block,.-_gcry_blowfish_amd64_encrypt_block;)
+
+.align 8
+.globl _gcry_blowfish_amd64_decrypt_block
+ELF(.type _gcry_blowfish_amd64_decrypt_block,@function;)
+
+_gcry_blowfish_amd64_decrypt_block:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ movq %rbp, %r11;
+ CFI_REGISTER(%rbp, %r11);
+
+ movq %rsi, %r10;
+ movq %rdx, RIO;
+
+ read_block();
+
+ load_roundkey_dec(17);
+ round_dec(15);
+ round_dec(13);
+ round_dec(11);
+ round_dec(9);
+ round_dec(7);
+ round_dec(5);
+ round_dec(3);
+ round_dec(1);
+ add_roundkey_dec();
+
+ movq %r10, RIO;
+ write_block();
+
+ movq %r11, %rbp;
+ CFI_RESTORE(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_blowfish_amd64_decrypt_block,.-_gcry_blowfish_amd64_decrypt_block;)
+
+/**********************************************************************
+ 4-way blowfish, four blocks parallel
+ **********************************************************************/
+#define F4(x) \
+ movzbl x ## bh, RT1d; \
+ movzbl x ## bl, RT3d; \
+ rorq $16, x; \
+ movzbl x ## bh, RT0d; \
+ movzbl x ## bl, RT2d; \
+ rorq $16, x; \
+ movl s0(CTX,RT0,4), RT0d; \
+ addl s1(CTX,RT2,4), RT0d; \
+ xorl s2(CTX,RT1,4), RT0d; \
+ addl s3(CTX,RT3,4), RT0d; \
+ xorq RT0, x;
+
+#define add_preloaded_roundkey4() \
+ xorq RKEY, RX0; \
+ xorq RKEY, RX1; \
+ xorq RKEY, RX2; \
+ xorq RKEY, RX3;
+
+#define preload_roundkey_enc(n) \
+ movq p+4*(n)(CTX), RKEY;
+
+#define add_roundkey_enc4(n) \
+ add_preloaded_roundkey4(); \
+ preload_roundkey_enc(n + 2);
+
+#define round_enc4(n) \
+ add_roundkey_enc4(n); \
+ \
+ F4(RX0); \
+ F4(RX1); \
+ F4(RX2); \
+ F4(RX3); \
+ \
+ F4(RX0); \
+ F4(RX1); \
+ F4(RX2); \
+ F4(RX3);
+
+#define preload_roundkey_dec(n) \
+ movq p+4*((n)-1)(CTX), RKEY; \
+ rorq $32, RKEY;
+
+#define add_roundkey_dec4(n) \
+ add_preloaded_roundkey4(); \
+ preload_roundkey_dec(n - 2);
+
+#define round_dec4(n) \
+ add_roundkey_dec4(n); \
+ \
+ F4(RX0); \
+ F4(RX1); \
+ F4(RX2); \
+ F4(RX3); \
+ \
+ F4(RX0); \
+ F4(RX1); \
+ F4(RX2); \
+ F4(RX3);
+
+#define inbswap_block4() \
+ rorq $32, RX0; \
+ bswapq RX0; \
+ rorq $32, RX1; \
+ bswapq RX1; \
+ rorq $32, RX2; \
+ bswapq RX2; \
+ rorq $32, RX3; \
+ bswapq RX3;
+
+#define inctrswap_block4() \
+ rorq $32, RX0; \
+ rorq $32, RX1; \
+ rorq $32, RX2; \
+ rorq $32, RX3;
+
+#define outbswap_block4() \
+ bswapq RX0; \
+ bswapq RX1; \
+ bswapq RX2; \
+ bswapq RX3;
+
+.align 8
+ELF(.type __blowfish_enc_blk4,@function;)
+
+__blowfish_enc_blk4:
+ /* input:
+ * %rdi: ctx, CTX
+ * RX0,RX1,RX2,RX3: four input inbswapped plaintext blocks
+ * output:
+ * RX0,RX1,RX2,RX3: four output ciphertext blocks
+ */
+ CFI_STARTPROC();
+ preload_roundkey_enc(0);
+
+ round_enc4(0);
+ round_enc4(2);
+ round_enc4(4);
+ round_enc4(6);
+ round_enc4(8);
+ round_enc4(10);
+ round_enc4(12);
+ round_enc4(14);
+ add_preloaded_roundkey4();
+
+ outbswap_block4();
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __blowfish_enc_blk4,.-__blowfish_enc_blk4;)
+
+.align 8
+ELF(.type __blowfish_dec_blk4,@function;)
+
+__blowfish_dec_blk4:
+ /* input:
+ * %rdi: ctx, CTX
+ * RX0,RX1,RX2,RX3: four input ciphertext blocks
+ * output:
+ * RX0,RX1,RX2,RX3: four output plaintext blocks
+ */
+ CFI_STARTPROC();
+ preload_roundkey_dec(17);
+
+ inbswap_block4();
+
+ round_dec4(17);
+ round_dec4(15);
+ round_dec4(13);
+ round_dec4(11);
+ round_dec4(9);
+ round_dec4(7);
+ round_dec4(5);
+ round_dec4(3);
+ add_preloaded_roundkey4();
+
+ outbswap_block4();
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __blowfish_dec_blk4,.-__blowfish_dec_blk4;)
+
+.align 8
+.globl _gcry_blowfish_amd64_ctr_enc
+ELF(.type _gcry_blowfish_amd64_ctr_enc,@function;)
+_gcry_blowfish_amd64_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (4 blocks)
+ * %rdx: src (4 blocks)
+ * %rcx: iv (big endian, 64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+
+ /* %r11-%r13 are not used by __blowfish_enc_blk4 */
+ movq %rcx, %r13; /*iv*/
+ movq %rdx, %r12; /*src*/
+ movq %rsi, %r11; /*dst*/
+
+ /* load IV and byteswap */
+ movq (%r13), RT0;
+ bswapq RT0;
+ movq RT0, RX0;
+
+ /* construct IVs */
+ leaq 1(RT0), RX1;
+ leaq 2(RT0), RX2;
+ leaq 3(RT0), RX3;
+ leaq 4(RT0), RT0;
+ bswapq RT0;
+
+ inctrswap_block4();
+
+ /* store new IV */
+ movq RT0, (%r13);
+
+ call __blowfish_enc_blk4;
+
+ /* XOR key-stream with plaintext */
+ xorq 0 * 8(%r12), RX0;
+ xorq 1 * 8(%r12), RX1;
+ xorq 2 * 8(%r12), RX2;
+ xorq 3 * 8(%r12), RX3;
+ movq RX0, 0 * 8(%r11);
+ movq RX1, 1 * 8(%r11);
+ movq RX2, 2 * 8(%r11);
+ movq RX3, 3 * 8(%r11);
+
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_blowfish_amd64_ctr_enc,.-_gcry_blowfish_amd64_ctr_enc;)
+
+.align 8
+.globl _gcry_blowfish_amd64_cbc_dec
+ELF(.type _gcry_blowfish_amd64_cbc_dec,@function;)
+_gcry_blowfish_amd64_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (4 blocks)
+ * %rdx: src (4 blocks)
+ * %rcx: iv (64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+
+ /* %r11-%r13 are not used by __blowfish_dec_blk4 */
+ movq %rsi, %r11; /*dst*/
+ movq %rdx, %r12; /*src*/
+ movq %rcx, %r13; /*iv*/
+
+ /* load input */
+ movq 0 * 8(%r12), RX0;
+ movq 1 * 8(%r12), RX1;
+ movq 2 * 8(%r12), RX2;
+ movq 3 * 8(%r12), RX3;
+
+ call __blowfish_dec_blk4;
+
+ movq 3 * 8(%r12), RT0;
+ xorq (%r13), RX0;
+ xorq 0 * 8(%r12), RX1;
+ xorq 1 * 8(%r12), RX2;
+ xorq 2 * 8(%r12), RX3;
+ movq RT0, (%r13); /* store new IV */
+
+ movq RX0, 0 * 8(%r11);
+ movq RX1, 1 * 8(%r11);
+ movq RX2, 2 * 8(%r11);
+ movq RX3, 3 * 8(%r11);
+
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_blowfish_amd64_cbc_dec,.-_gcry_blowfish_amd64_cbc_dec;)
+
+.align 8
+.globl _gcry_blowfish_amd64_cfb_dec
+ELF(.type _gcry_blowfish_amd64_cfb_dec,@function;)
+_gcry_blowfish_amd64_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (4 blocks)
+ * %rdx: src (4 blocks)
+ * %rcx: iv (64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+
+ /* %r11-%r13 are not used by __blowfish_enc_blk4 */
+ movq %rcx, %r13; /*iv*/
+ movq %rdx, %r12; /*src*/
+ movq %rsi, %r11; /*dst*/
+
+ /* Load input */
+ movq (%r13), RX0;
+ movq 0 * 8(%r12), RX1;
+ movq 1 * 8(%r12), RX2;
+ movq 2 * 8(%r12), RX3;
+
+ inbswap_block4();
+
+ /* Update IV */
+ movq 3 * 8(%r12), RT0;
+ movq RT0, (%r13);
+
+ call __blowfish_enc_blk4;
+
+ xorq 0 * 8(%r12), RX0;
+ xorq 1 * 8(%r12), RX1;
+ xorq 2 * 8(%r12), RX2;
+ xorq 3 * 8(%r12), RX3;
+ movq RX0, 0 * 8(%r11);
+ movq RX1, 1 * 8(%r11);
+ movq RX2, 2 * 8(%r11);
+ movq RX3, 3 * 8(%r11);
+
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_blowfish_amd64_cfb_dec,.-_gcry_blowfish_amd64_cfb_dec;)
+
+#endif /*defined(USE_BLOWFISH)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/blowfish-arm.S b/comm/third_party/libgcrypt/cipher/blowfish-arm.S
new file mode 100644
index 0000000000..b30aa31f1d
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/blowfish-arm.S
@@ -0,0 +1,743 @@
+/* blowfish-arm.S - ARM assembly implementation of Blowfish cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(__ARMEL__)
+#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+.text
+
+.syntax unified
+.arm
+
+/* structure of crypto context */
+#define s0 0
+#define s1 (s0 + (1 * 256) * 4)
+#define s2 (s0 + (2 * 256) * 4)
+#define s3 (s0 + (3 * 256) * 4)
+#define p (s3 + (1 * 256) * 4)
+
+/* register macros */
+#define CTXs0 %r0
+#define CTXs1 %r9
+#define CTXs2 %r8
+#define CTXs3 %r10
+#define RMASK %lr
+#define RKEYL %r2
+#define RKEYR %ip
+
+#define RL0 %r3
+#define RR0 %r4
+
+#define RL1 %r9
+#define RR1 %r10
+
+#define RT0 %r11
+#define RT1 %r7
+#define RT2 %r5
+#define RT3 %r6
+
+/* helper macros */
+#define ldr_unaligned_le(rout, rsrc, offs, rtmp) \
+ ldrb rout, [rsrc, #((offs) + 0)]; \
+ ldrb rtmp, [rsrc, #((offs) + 1)]; \
+ orr rout, rout, rtmp, lsl #8; \
+ ldrb rtmp, [rsrc, #((offs) + 2)]; \
+ orr rout, rout, rtmp, lsl #16; \
+ ldrb rtmp, [rsrc, #((offs) + 3)]; \
+ orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_le(rin, rdst, offs, rtmp0, rtmp1) \
+ mov rtmp0, rin, lsr #8; \
+ strb rin, [rdst, #((offs) + 0)]; \
+ mov rtmp1, rin, lsr #16; \
+ strb rtmp0, [rdst, #((offs) + 1)]; \
+ mov rtmp0, rin, lsr #24; \
+ strb rtmp1, [rdst, #((offs) + 2)]; \
+ strb rtmp0, [rdst, #((offs) + 3)];
+
+#define ldr_unaligned_be(rout, rsrc, offs, rtmp) \
+ ldrb rout, [rsrc, #((offs) + 3)]; \
+ ldrb rtmp, [rsrc, #((offs) + 2)]; \
+ orr rout, rout, rtmp, lsl #8; \
+ ldrb rtmp, [rsrc, #((offs) + 1)]; \
+ orr rout, rout, rtmp, lsl #16; \
+ ldrb rtmp, [rsrc, #((offs) + 0)]; \
+ orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_be(rin, rdst, offs, rtmp0, rtmp1) \
+ mov rtmp0, rin, lsr #8; \
+ strb rin, [rdst, #((offs) + 3)]; \
+ mov rtmp1, rin, lsr #16; \
+ strb rtmp0, [rdst, #((offs) + 2)]; \
+ mov rtmp0, rin, lsr #24; \
+ strb rtmp1, [rdst, #((offs) + 1)]; \
+ strb rtmp0, [rdst, #((offs) + 0)];
+
+#ifdef __ARMEL__
+ #define ldr_unaligned_host ldr_unaligned_le
+ #define str_unaligned_host str_unaligned_le
+
+ /* bswap on little-endian */
+#ifdef HAVE_ARM_ARCH_V6
+ #define host_to_be(reg, rtmp) \
+ rev reg, reg;
+ #define be_to_host(reg, rtmp) \
+ rev reg, reg;
+#else
+ #define host_to_be(reg, rtmp) \
+ eor rtmp, reg, reg, ror #16; \
+ mov rtmp, rtmp, lsr #8; \
+ bic rtmp, rtmp, #65280; \
+ eor reg, rtmp, reg, ror #8;
+ #define be_to_host(reg, rtmp) \
+ eor rtmp, reg, reg, ror #16; \
+ mov rtmp, rtmp, lsr #8; \
+ bic rtmp, rtmp, #65280; \
+ eor reg, rtmp, reg, ror #8;
+#endif
+#else
+ #define ldr_unaligned_host ldr_unaligned_be
+ #define str_unaligned_host str_unaligned_be
+
+ /* nop on big-endian */
+ #define host_to_be(reg, rtmp) /*_*/
+ #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define host_to_host(x, y) /*_*/
+
+/***********************************************************************
+ * 1-way blowfish
+ ***********************************************************************/
+#define F(l, r) \
+ and RT0, RMASK, l, lsr#(24 - 2); \
+ and RT1, RMASK, l, lsr#(16 - 2); \
+ ldr RT0, [CTXs0, RT0]; \
+ and RT2, RMASK, l, lsr#(8 - 2); \
+ ldr RT1, [CTXs1, RT1]; \
+ and RT3, RMASK, l, lsl#2; \
+ ldr RT2, [CTXs2, RT2]; \
+ add RT0, RT1; \
+ ldr RT3, [CTXs3, RT3]; \
+ eor RT0, RT2; \
+ add RT0, RT3; \
+ eor r, RT0;
+
+#define load_roundkey_enc(n) \
+ ldr RKEYL, [CTXs2, #((p - s2) + (4 * (n) + 0))]; \
+ ldr RKEYR, [CTXs2, #((p - s2) + (4 * (n) + 4))];
+
+#define add_roundkey_enc() \
+ eor RL0, RKEYL; \
+ eor RR0, RKEYR;
+
+#define round_enc(n) \
+ add_roundkey_enc(); \
+ load_roundkey_enc(n); \
+ \
+ F(RL0, RR0); \
+ F(RR0, RL0);
+
+#define load_roundkey_dec(n) \
+ ldr RKEYL, [CTXs2, #((p - s2) + (4 * ((n) - 1) + 4))]; \
+ ldr RKEYR, [CTXs2, #((p - s2) + (4 * ((n) - 1) + 0))];
+
+#define add_roundkey_dec() \
+ eor RL0, RKEYL; \
+ eor RR0, RKEYR;
+
+#define round_dec(n) \
+ add_roundkey_dec(); \
+ load_roundkey_dec(n); \
+ \
+ F(RL0, RR0); \
+ F(RR0, RL0);
+
+#define read_block_aligned(rin, offs, l0, r0, convert, rtmp) \
+ ldr l0, [rin, #((offs) + 0)]; \
+ ldr r0, [rin, #((offs) + 4)]; \
+ convert(l0, rtmp); \
+ convert(r0, rtmp);
+
+#define write_block_aligned(rout, offs, l0, r0, convert, rtmp) \
+ convert(l0, rtmp); \
+ convert(r0, rtmp); \
+ str l0, [rout, #((offs) + 0)]; \
+ str r0, [rout, #((offs) + 4)];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+ /* unaligned word reads allowed */
+ #define read_block(rin, offs, l0, r0, rtmp0) \
+ read_block_aligned(rin, offs, l0, r0, host_to_be, rtmp0)
+
+ #define write_block(rout, offs, r0, l0, rtmp0, rtmp1) \
+ write_block_aligned(rout, offs, r0, l0, be_to_host, rtmp0)
+
+ #define read_block_host(rin, offs, l0, r0, rtmp0) \
+ read_block_aligned(rin, offs, l0, r0, host_to_host, rtmp0)
+
+ #define write_block_host(rout, offs, r0, l0, rtmp0, rtmp1) \
+ write_block_aligned(rout, offs, r0, l0, host_to_host, rtmp0)
+#else
+ /* need to handle unaligned reads by byte reads */
+ #define read_block(rin, offs, l0, r0, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_be(l0, rin, (offs) + 0, rtmp0); \
+ ldr_unaligned_be(r0, rin, (offs) + 4, rtmp0); \
+ b 2f; \
+ 1:;\
+ read_block_aligned(rin, offs, l0, r0, host_to_be, rtmp0); \
+ 2:;
+
+ #define write_block(rout, offs, l0, r0, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_be(l0, rout, (offs) + 0, rtmp0, rtmp1); \
+ str_unaligned_be(r0, rout, (offs) + 4, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ write_block_aligned(rout, offs, l0, r0, be_to_host, rtmp0); \
+ 2:;
+
+ #define read_block_host(rin, offs, l0, r0, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_host(l0, rin, (offs) + 0, rtmp0); \
+ ldr_unaligned_host(r0, rin, (offs) + 4, rtmp0); \
+ b 2f; \
+ 1:;\
+ read_block_aligned(rin, offs, l0, r0, host_to_host, rtmp0); \
+ 2:;
+
+ #define write_block_host(rout, offs, l0, r0, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_host(l0, rout, (offs) + 0, rtmp0, rtmp1); \
+ str_unaligned_host(r0, rout, (offs) + 4, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ write_block_aligned(rout, offs, l0, r0, host_to_host); \
+ 2:;
+#endif
+
+.align 3
+.type __blowfish_enc_blk1,%function;
+
+__blowfish_enc_blk1:
+ /* input:
+ * preloaded: CTX
+ * [RL0, RR0]: src
+ * output:
+ * [RR0, RL0]: dst
+ */
+ push {%lr};
+
+ add CTXs1, CTXs0, #(s1 - s0);
+ add CTXs2, CTXs0, #(s2 - s0);
+ mov RMASK, #(0xff << 2); /* byte mask */
+ add CTXs3, CTXs1, #(s3 - s1);
+
+ load_roundkey_enc(0);
+ round_enc(2);
+ round_enc(4);
+ round_enc(6);
+ round_enc(8);
+ round_enc(10);
+ round_enc(12);
+ round_enc(14);
+ round_enc(16);
+ add_roundkey_enc();
+
+ pop {%pc};
+.size __blowfish_enc_blk1,.-__blowfish_enc_blk1;
+
+.align 8
+.globl _gcry_blowfish_arm_do_encrypt
+.type _gcry_blowfish_arm_do_encrypt,%function;
+
+_gcry_blowfish_arm_do_encrypt:
+ /* input:
+ * %r0: ctx, CTX
+ * %r1: u32 *ret_xl
+ * %r2: u32 *ret_xr
+ */
+ push {%r2, %r4-%r11, %ip, %lr};
+
+ ldr RL0, [%r1];
+ ldr RR0, [%r2];
+
+ bl __blowfish_enc_blk1;
+
+ pop {%r2};
+ str RR0, [%r1];
+ str RL0, [%r2];
+
+ pop {%r4-%r11, %ip, %pc};
+.size _gcry_blowfish_arm_do_encrypt,.-_gcry_blowfish_arm_do_encrypt;
+
+.align 3
+.globl _gcry_blowfish_arm_encrypt_block
+.type _gcry_blowfish_arm_encrypt_block,%function;
+
+_gcry_blowfish_arm_encrypt_block:
+ /* input:
+ * %r0: ctx, CTX
+ * %r1: dst
+ * %r2: src
+ */
+ push {%r4-%r11, %ip, %lr};
+
+ read_block(%r2, 0, RL0, RR0, RT0);
+
+ bl __blowfish_enc_blk1;
+
+ write_block(%r1, 0, RR0, RL0, RT0, RT1);
+
+ pop {%r4-%r11, %ip, %pc};
+.size _gcry_blowfish_arm_encrypt_block,.-_gcry_blowfish_arm_encrypt_block;
+
+.align 3
+.globl _gcry_blowfish_arm_decrypt_block
+.type _gcry_blowfish_arm_decrypt_block,%function;
+
+_gcry_blowfish_arm_decrypt_block:
+ /* input:
+ * %r0: ctx, CTX
+ * %r1: dst
+ * %r2: src
+ */
+ push {%r4-%r11, %ip, %lr};
+
+ add CTXs1, CTXs0, #(s1 - s0);
+ add CTXs2, CTXs0, #(s2 - s0);
+ mov RMASK, #(0xff << 2); /* byte mask */
+ add CTXs3, CTXs1, #(s3 - s1);
+
+ read_block(%r2, 0, RL0, RR0, RT0);
+
+ load_roundkey_dec(17);
+ round_dec(15);
+ round_dec(13);
+ round_dec(11);
+ round_dec(9);
+ round_dec(7);
+ round_dec(5);
+ round_dec(3);
+ round_dec(1);
+ add_roundkey_dec();
+
+ write_block(%r1, 0, RR0, RL0, RT0, RT1);
+
+ pop {%r4-%r11, %ip, %pc};
+.size _gcry_blowfish_arm_decrypt_block,.-_gcry_blowfish_arm_decrypt_block;
+
+/***********************************************************************
+ * 2-way blowfish
+ ***********************************************************************/
+#define F2(n, l0, r0, l1, r1, set_nextk, dec) \
+ \
+ and RT0, RMASK, l0, lsr#(24 - 2); \
+ and RT1, RMASK, l0, lsr#(16 - 2); \
+ and RT2, RMASK, l0, lsr#(8 - 2); \
+ add RT1, #(s1 - s0); \
+ \
+ ldr RT0, [CTXs0, RT0]; \
+ and RT3, RMASK, l0, lsl#2; \
+ ldr RT1, [CTXs0, RT1]; \
+ add RT3, #(s3 - s2); \
+ ldr RT2, [CTXs2, RT2]; \
+ add RT0, RT1; \
+ ldr RT3, [CTXs2, RT3]; \
+ \
+ and RT1, RMASK, l1, lsr#(24 - 2); \
+ eor RT0, RT2; \
+ and RT2, RMASK, l1, lsr#(16 - 2); \
+ add RT0, RT3; \
+ add RT2, #(s1 - s0); \
+ and RT3, RMASK, l1, lsr#(8 - 2); \
+ eor r0, RT0; \
+ \
+ ldr RT1, [CTXs0, RT1]; \
+ and RT0, RMASK, l1, lsl#2; \
+ ldr RT2, [CTXs0, RT2]; \
+ add RT0, #(s3 - s2); \
+ ldr RT3, [CTXs2, RT3]; \
+ add RT1, RT2; \
+ ldr RT0, [CTXs2, RT0]; \
+ \
+ and RT2, RMASK, r0, lsr#(24 - 2); \
+ eor RT1, RT3; \
+ and RT3, RMASK, r0, lsr#(16 - 2); \
+ add RT1, RT0; \
+ add RT3, #(s1 - s0); \
+ and RT0, RMASK, r0, lsr#(8 - 2); \
+ eor r1, RT1; \
+ \
+ ldr RT2, [CTXs0, RT2]; \
+ and RT1, RMASK, r0, lsl#2; \
+ ldr RT3, [CTXs0, RT3]; \
+ add RT1, #(s3 - s2); \
+ ldr RT0, [CTXs2, RT0]; \
+ add RT2, RT3; \
+ ldr RT1, [CTXs2, RT1]; \
+ \
+ and RT3, RMASK, r1, lsr#(24 - 2); \
+ eor RT2, RT0; \
+ and RT0, RMASK, r1, lsr#(16 - 2); \
+ add RT2, RT1; \
+ add RT0, #(s1 - s0); \
+ and RT1, RMASK, r1, lsr#(8 - 2); \
+ eor l0, RT2; \
+ \
+ ldr RT3, [CTXs0, RT3]; \
+ and RT2, RMASK, r1, lsl#2; \
+ ldr RT0, [CTXs0, RT0]; \
+ add RT2, #(s3 - s2); \
+ ldr RT1, [CTXs2, RT1]; \
+ eor l1, RKEYL; \
+ ldr RT2, [CTXs2, RT2]; \
+ \
+ eor r0, RKEYR; \
+ add RT3, RT0; \
+ eor r1, RKEYR; \
+ eor RT3, RT1; \
+ eor l0, RKEYL; \
+ add RT3, RT2; \
+ set_nextk(RKEYL, (p - s2) + (4 * (n) + ((dec) * 4))); \
+ eor l1, RT3; \
+ set_nextk(RKEYR, (p - s2) + (4 * (n) + (!(dec) * 4)));
+
+#define load_n_add_roundkey_enc2(n) \
+ load_roundkey_enc(n); \
+ eor RL0, RKEYL; \
+ eor RR0, RKEYR; \
+ eor RL1, RKEYL; \
+ eor RR1, RKEYR; \
+ load_roundkey_enc((n) + 2);
+
+#define next_key(reg, offs) \
+ ldr reg, [CTXs2, #(offs)];
+
+#define dummy(x, y) /* do nothing */
+
+#define round_enc2(n, load_next_key) \
+ F2((n) + 2, RL0, RR0, RL1, RR1, load_next_key, 0);
+
+#define load_n_add_roundkey_dec2(n) \
+ load_roundkey_dec(n); \
+ eor RL0, RKEYL; \
+ eor RR0, RKEYR; \
+ eor RL1, RKEYL; \
+ eor RR1, RKEYR; \
+ load_roundkey_dec((n) - 2);
+
+#define round_dec2(n, load_next_key) \
+ F2((n) - 3, RL0, RR0, RL1, RR1, load_next_key, 1);
+
+#define read_block2_aligned(rin, l0, r0, l1, r1, convert, rtmp) \
+ ldr l0, [rin, #(0)]; \
+ ldr r0, [rin, #(4)]; \
+ convert(l0, rtmp); \
+ ldr l1, [rin, #(8)]; \
+ convert(r0, rtmp); \
+ ldr r1, [rin, #(12)]; \
+ convert(l1, rtmp); \
+ convert(r1, rtmp);
+
+#define write_block2_aligned(rout, l0, r0, l1, r1, convert, rtmp) \
+ convert(l0, rtmp); \
+ convert(r0, rtmp); \
+ convert(l1, rtmp); \
+ str l0, [rout, #(0)]; \
+ convert(r1, rtmp); \
+ str r0, [rout, #(4)]; \
+ str l1, [rout, #(8)]; \
+ str r1, [rout, #(12)];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+ /* unaligned word reads allowed */
+ #define read_block2(rin, l0, r0, l1, r1, rtmp0) \
+ read_block2_aligned(rin, l0, r0, l1, r1, host_to_be, rtmp0)
+
+ #define write_block2(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+ write_block2_aligned(rout, l0, r0, l1, r1, be_to_host, rtmp0)
+
+ #define read_block2_host(rin, l0, r0, l1, r1, rtmp0) \
+ read_block2_aligned(rin, l0, r0, l1, r1, host_to_host, rtmp0)
+
+ #define write_block2_host(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+ write_block2_aligned(rout, l0, r0, l1, r1, host_to_host, rtmp0)
+#else
+ /* need to handle unaligned reads by byte reads */
+ #define read_block2(rin, l0, r0, l1, r1, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_be(l0, rin, 0, rtmp0); \
+ ldr_unaligned_be(r0, rin, 4, rtmp0); \
+ ldr_unaligned_be(l1, rin, 8, rtmp0); \
+ ldr_unaligned_be(r1, rin, 12, rtmp0); \
+ b 2f; \
+ 1:;\
+ read_block2_aligned(rin, l0, r0, l1, r1, host_to_be, rtmp0); \
+ 2:;
+
+ #define write_block2(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_be(l0, rout, 0, rtmp0, rtmp1); \
+ str_unaligned_be(r0, rout, 4, rtmp0, rtmp1); \
+ str_unaligned_be(l1, rout, 8, rtmp0, rtmp1); \
+ str_unaligned_be(r1, rout, 12, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ write_block2_aligned(rout, l0, r0, l1, r1, be_to_host, rtmp0); \
+ 2:;
+
+ #define read_block2_host(rin, l0, r0, l1, r1, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_host(l0, rin, 0, rtmp0); \
+ ldr_unaligned_host(r0, rin, 4, rtmp0); \
+ ldr_unaligned_host(l1, rin, 8, rtmp0); \
+ ldr_unaligned_host(r1, rin, 12, rtmp0); \
+ b 2f; \
+ 1:;\
+ read_block2_aligned(rin, l0, r0, l1, r1, host_to_host, rtmp0); \
+ 2:;
+
+ #define write_block2_host(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_host(l0, rout, 0, rtmp0, rtmp1); \
+ str_unaligned_host(r0, rout, 4, rtmp0, rtmp1); \
+ str_unaligned_host(l1, rout, 8, rtmp0, rtmp1); \
+ str_unaligned_host(r1, rout, 12, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ write_block2_aligned(rout, l0, r0, l1, r1, host_to_host, rtmp0); \
+ 2:;
+#endif
+
+.align 3
+.type _gcry_blowfish_arm_enc_blk2,%function;
+
+_gcry_blowfish_arm_enc_blk2:
+ /* input:
+ * preloaded: CTX
+ * [RL0, RR0], [RL1, RR1]: src
+ * output:
+ * [RR0, RL0], [RR1, RL1]: dst
+ */
+ push {RT0,%lr};
+
+ add CTXs2, CTXs0, #(s2 - s0);
+ mov RMASK, #(0xff << 2); /* byte mask */
+
+ load_n_add_roundkey_enc2(0);
+ round_enc2(2, next_key);
+ round_enc2(4, next_key);
+ round_enc2(6, next_key);
+ round_enc2(8, next_key);
+ round_enc2(10, next_key);
+ round_enc2(12, next_key);
+ round_enc2(14, next_key);
+ round_enc2(16, dummy);
+
+ host_to_be(RR0, RT0);
+ host_to_be(RL0, RT0);
+ host_to_be(RR1, RT0);
+ host_to_be(RL1, RT0);
+
+ pop {RT0,%pc};
+.size _gcry_blowfish_arm_enc_blk2,.-_gcry_blowfish_arm_enc_blk2;
+
+.align 3
+.globl _gcry_blowfish_arm_cfb_dec;
+.type _gcry_blowfish_arm_cfb_dec,%function;
+
+_gcry_blowfish_arm_cfb_dec:
+ /* input:
+ * %r0: CTX
+ * %r1: dst (2 blocks)
+ * %r2: src (2 blocks)
+ * %r3: iv (64bit)
+ */
+ push {%r2, %r4-%r11, %ip, %lr};
+
+ mov %lr, %r3;
+
+ /* Load input (iv/%r3 is aligned, src/%r2 might not be) */
+ ldm %r3, {RL0, RR0};
+ host_to_be(RL0, RT0);
+ host_to_be(RR0, RT0);
+ read_block(%r2, 0, RL1, RR1, RT0);
+
+ /* Update IV, load src[1] and save to iv[0] */
+ read_block_host(%r2, 8, %r5, %r6, RT0);
+ stm %lr, {%r5, %r6};
+
+ bl _gcry_blowfish_arm_enc_blk2;
+ /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+ /* %r1: dst, %r0: %src */
+ pop {%r0};
+
+ /* dst = src ^ result */
+ read_block2_host(%r0, %r5, %r6, %r7, %r8, %lr);
+ eor %r5, %r4;
+ eor %r6, %r3;
+ eor %r7, %r10;
+ eor %r8, %r9;
+ write_block2_host(%r1, %r5, %r6, %r7, %r8, %r9, %r10);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_blowfish_arm_cfb_dec,.-_gcry_blowfish_arm_cfb_dec;
+
+.align 3
+.globl _gcry_blowfish_arm_ctr_enc;
+.type _gcry_blowfish_arm_ctr_enc,%function;
+
+_gcry_blowfish_arm_ctr_enc:
+ /* input:
+ * %r0: CTX
+ * %r1: dst (2 blocks)
+ * %r2: src (2 blocks)
+ * %r3: iv (64bit, big-endian)
+ */
+ push {%r2, %r4-%r11, %ip, %lr};
+
+ mov %lr, %r3;
+
+ /* Load IV (big => host endian) */
+ read_block_aligned(%lr, 0, RL0, RR0, be_to_host, RT0);
+
+ /* Construct IVs */
+ adds RR1, RR0, #1; /* +1 */
+ adc RL1, RL0, #0;
+ adds %r6, RR1, #1; /* +2 */
+ adc %r5, RL1, #0;
+
+ /* Store new IV (host => big-endian) */
+ write_block_aligned(%lr, 0, %r5, %r6, host_to_be, RT0);
+
+ bl _gcry_blowfish_arm_enc_blk2;
+ /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+ /* %r1: dst, %r0: %src */
+ pop {%r0};
+
+ /* XOR key-stream with plaintext */
+ read_block2_host(%r0, %r5, %r6, %r7, %r8, %lr);
+ eor %r5, %r4;
+ eor %r6, %r3;
+ eor %r7, %r10;
+ eor %r8, %r9;
+ write_block2_host(%r1, %r5, %r6, %r7, %r8, %r9, %r10);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_blowfish_arm_ctr_enc,.-_gcry_blowfish_arm_ctr_enc;
+
+.align 3
+.type _gcry_blowfish_arm_dec_blk2,%function;
+
+_gcry_blowfish_arm_dec_blk2:
+ /* input:
+ * preloaded: CTX
+ * [RL0, RR0], [RL1, RR1]: src
+ * output:
+ * [RR0, RL0], [RR1, RL1]: dst
+ */
+ add CTXs2, CTXs0, #(s2 - s0);
+ mov RMASK, #(0xff << 2); /* byte mask */
+
+ load_n_add_roundkey_dec2(17);
+ round_dec2(15, next_key);
+ round_dec2(13, next_key);
+ round_dec2(11, next_key);
+ round_dec2(9, next_key);
+ round_dec2(7, next_key);
+ round_dec2(5, next_key);
+ round_dec2(3, next_key);
+ round_dec2(1, dummy);
+
+ host_to_be(RR0, RT0);
+ host_to_be(RL0, RT0);
+ host_to_be(RR1, RT0);
+ host_to_be(RL1, RT0);
+
+ b .Ldec_cbc_tail;
+.ltorg
+.size _gcry_blowfish_arm_dec_blk2,.-_gcry_blowfish_arm_dec_blk2;
+
+.align 3
+.globl _gcry_blowfish_arm_cbc_dec;
+.type _gcry_blowfish_arm_cbc_dec,%function;
+
+_gcry_blowfish_arm_cbc_dec:
+ /* input:
+ * %r0: CTX
+ * %r1: dst (2 blocks)
+ * %r2: src (2 blocks)
+ * %r3: iv (64bit)
+ */
+ push {%r2-%r11, %ip, %lr};
+
+ read_block2(%r2, RL0, RR0, RL1, RR1, RT0);
+
+ /* dec_blk2 is only used by cbc_dec, jump directly in/out instead
+ * of function call. */
+ b _gcry_blowfish_arm_dec_blk2;
+.Ldec_cbc_tail:
+ /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+ /* %r0: %src, %r1: dst, %r2: iv */
+ pop {%r0, %r2};
+
+ /* load IV+1 (src[0]) to %r7:%r8. Might be unaligned. */
+ read_block_host(%r0, 0, %r7, %r8, %r5);
+ /* load IV (iv[0]) to %r5:%r6. 'iv' is aligned. */
+ ldm %r2, {%r5, %r6};
+
+ /* out[1] ^= IV+1 */
+ eor %r10, %r7;
+ eor %r9, %r8;
+ /* out[0] ^= IV */
+ eor %r4, %r5;
+ eor %r3, %r6;
+
+ /* load IV+2 (src[1]) to %r7:%r8. Might be unaligned. */
+ read_block_host(%r0, 8, %r7, %r8, %r5);
+ /* store IV+2 to iv[0] (aligned). */
+ stm %r2, {%r7, %r8};
+
+ /* store result to dst[0-3]. Might be unaligned. */
+ write_block2_host(%r1, %r4, %r3, %r10, %r9, %r5, %r6);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_blowfish_arm_cbc_dec,.-_gcry_blowfish_arm_cbc_dec;
+
+#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
+#endif /*__ARM_ARCH >= 6*/
diff --git a/comm/third_party/libgcrypt/cipher/blowfish.c b/comm/third_party/libgcrypt/cipher/blowfish.c
new file mode 100644
index 0000000000..7b001306c7
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/blowfish.c
@@ -0,0 +1,1142 @@
+/* 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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/comm/third_party/libgcrypt/cipher/bufhelp.h b/comm/third_party/libgcrypt/cipher/bufhelp.h
new file mode 100644
index 0000000000..fa5b2e8ece
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/bufhelp.h
@@ -0,0 +1,385 @@
+/* bufhelp.h - Some buffer manipulation helpers
+ * Copyright (C) 2012-2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef GCRYPT_BUFHELP_H
+#define GCRYPT_BUFHELP_H
+
+
+#include "g10lib.h"
+#include "bithelp.h"
+
+
+#undef BUFHELP_UNALIGNED_ACCESS
+#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
+ defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
+ defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS)
+/* Compiler is supports attributes needed for automatically issuing unaligned
+ memory access instructions.
+ */
+# define BUFHELP_UNALIGNED_ACCESS 1
+#endif
+
+
+#ifndef BUFHELP_UNALIGNED_ACCESS
+
+/* Functions for loading and storing unaligned u32 values of different
+ endianness. */
+static inline u32 buf_get_be32(const void *_buf)
+{
+ const byte *in = _buf;
+ return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \
+ ((u32)in[2] << 8) | (u32)in[3];
+}
+
+static inline u32 buf_get_le32(const void *_buf)
+{
+ const byte *in = _buf;
+ return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \
+ ((u32)in[1] << 8) | (u32)in[0];
+}
+
+static inline void buf_put_be32(void *_buf, u32 val)
+{
+ byte *out = _buf;
+ out[0] = val >> 24;
+ out[1] = val >> 16;
+ out[2] = val >> 8;
+ out[3] = val;
+}
+
+static inline void buf_put_le32(void *_buf, u32 val)
+{
+ byte *out = _buf;
+ out[3] = val >> 24;
+ out[2] = val >> 16;
+ out[1] = val >> 8;
+ out[0] = val;
+}
+
+
+/* Functions for loading and storing unaligned u64 values of different
+ endianness. */
+static inline u64 buf_get_be64(const void *_buf)
+{
+ const byte *in = _buf;
+ return ((u64)in[0] << 56) | ((u64)in[1] << 48) | \
+ ((u64)in[2] << 40) | ((u64)in[3] << 32) | \
+ ((u64)in[4] << 24) | ((u64)in[5] << 16) | \
+ ((u64)in[6] << 8) | (u64)in[7];
+}
+
+static inline u64 buf_get_le64(const void *_buf)
+{
+ const byte *in = _buf;
+ return ((u64)in[7] << 56) | ((u64)in[6] << 48) | \
+ ((u64)in[5] << 40) | ((u64)in[4] << 32) | \
+ ((u64)in[3] << 24) | ((u64)in[2] << 16) | \
+ ((u64)in[1] << 8) | (u64)in[0];
+}
+
+static inline void buf_put_be64(void *_buf, u64 val)
+{
+ byte *out = _buf;
+ out[0] = val >> 56;
+ out[1] = val >> 48;
+ out[2] = val >> 40;
+ out[3] = val >> 32;
+ out[4] = val >> 24;
+ out[5] = val >> 16;
+ out[6] = val >> 8;
+ out[7] = val;
+}
+
+static inline void buf_put_le64(void *_buf, u64 val)
+{
+ byte *out = _buf;
+ out[7] = val >> 56;
+ out[6] = val >> 48;
+ out[5] = val >> 40;
+ out[4] = val >> 32;
+ out[3] = val >> 24;
+ out[2] = val >> 16;
+ out[1] = val >> 8;
+ out[0] = val;
+}
+
+#else /*BUFHELP_UNALIGNED_ACCESS*/
+
+typedef struct bufhelp_u32_s
+{
+ u32 a;
+} __attribute__((packed, aligned(1), may_alias)) bufhelp_u32_t;
+
+/* Functions for loading and storing unaligned u32 values of different
+ endianness. */
+static inline u32 buf_get_be32(const void *_buf)
+{
+ return be_bswap32(((const bufhelp_u32_t *)_buf)->a);
+}
+
+static inline u32 buf_get_le32(const void *_buf)
+{
+ return le_bswap32(((const bufhelp_u32_t *)_buf)->a);
+}
+
+static inline void buf_put_be32(void *_buf, u32 val)
+{
+ bufhelp_u32_t *out = _buf;
+ out->a = be_bswap32(val);
+}
+
+static inline void buf_put_le32(void *_buf, u32 val)
+{
+ bufhelp_u32_t *out = _buf;
+ out->a = le_bswap32(val);
+}
+
+
+typedef struct bufhelp_u64_s
+{
+ u64 a;
+} __attribute__((packed, aligned(1), may_alias)) bufhelp_u64_t;
+
+/* Functions for loading and storing unaligned u64 values of different
+ endianness. */
+static inline u64 buf_get_be64(const void *_buf)
+{
+ return be_bswap64(((const bufhelp_u64_t *)_buf)->a);
+}
+
+static inline u64 buf_get_le64(const void *_buf)
+{
+ return le_bswap64(((const bufhelp_u64_t *)_buf)->a);
+}
+
+static inline void buf_put_be64(void *_buf, u64 val)
+{
+ bufhelp_u64_t *out = _buf;
+ out->a = be_bswap64(val);
+}
+
+static inline void buf_put_le64(void *_buf, u64 val)
+{
+ bufhelp_u64_t *out = _buf;
+ out->a = le_bswap64(val);
+}
+
+#endif /*BUFHELP_UNALIGNED_ACCESS*/
+
+
+/* Host-endian get/put macros */
+#ifdef WORDS_BIGENDIAN
+# define buf_get_he32 buf_get_be32
+# define buf_put_he32 buf_put_be32
+# define buf_get_he64 buf_get_be64
+# define buf_put_he64 buf_put_be64
+#else
+# define buf_get_he32 buf_get_le32
+# define buf_put_he32 buf_put_le32
+# define buf_get_he64 buf_get_le64
+# define buf_put_he64 buf_put_le64
+#endif
+
+
+
+/* Optimized function for small buffer copying */
+static inline void
+buf_cpy(void *_dst, const void *_src, size_t len)
+{
+ byte *dst = _dst;
+ const byte *src = _src;
+
+#if __GNUC__ >= 4
+ if (!__builtin_constant_p (len))
+ {
+ if (UNLIKELY(len == 0))
+ return;
+ memcpy(_dst, _src, len);
+ return;
+ }
+#endif
+
+ while (len >= sizeof(u64))
+ {
+ buf_put_he64(dst, buf_get_he64(src));
+ dst += sizeof(u64);
+ src += sizeof(u64);
+ len -= sizeof(u64);
+ }
+
+ if (len >= sizeof(u32))
+ {
+ buf_put_he32(dst, buf_get_he32(src));
+ dst += sizeof(u32);
+ src += sizeof(u32);
+ len -= sizeof(u32);
+ }
+
+ /* Handle tail. */
+ for (; len; len--)
+ *dst++ = *src++;
+}
+
+
+/* Optimized function for buffer xoring */
+static inline void
+buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len)
+{
+ byte *dst = _dst;
+ const byte *src1 = _src1;
+ const byte *src2 = _src2;
+
+ while (len >= sizeof(u64))
+ {
+ buf_put_he64(dst, buf_get_he64(src1) ^ buf_get_he64(src2));
+ dst += sizeof(u64);
+ src1 += sizeof(u64);
+ src2 += sizeof(u64);
+ len -= sizeof(u64);
+ }
+
+ if (len > sizeof(u32))
+ {
+ buf_put_he32(dst, buf_get_he32(src1) ^ buf_get_he32(src2));
+ dst += sizeof(u32);
+ src1 += sizeof(u32);
+ src2 += sizeof(u32);
+ len -= sizeof(u32);
+ }
+
+ /* Handle tail. */
+ for (; len; len--)
+ *dst++ = *src1++ ^ *src2++;
+}
+
+
+/* Optimized function for buffer xoring with two destination buffers. Used
+ mainly by CFB mode encryption. */
+static inline void
+buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len)
+{
+ byte *dst1 = _dst1;
+ byte *dst2 = _dst2;
+ const byte *src = _src;
+
+ while (len >= sizeof(u64))
+ {
+ u64 temp = buf_get_he64(dst2) ^ buf_get_he64(src);
+ buf_put_he64(dst2, temp);
+ buf_put_he64(dst1, temp);
+ dst2 += sizeof(u64);
+ dst1 += sizeof(u64);
+ src += sizeof(u64);
+ len -= sizeof(u64);
+ }
+
+ if (len >= sizeof(u32))
+ {
+ u32 temp = buf_get_he32(dst2) ^ buf_get_he32(src);
+ buf_put_he32(dst2, temp);
+ buf_put_he32(dst1, temp);
+ dst2 += sizeof(u32);
+ dst1 += sizeof(u32);
+ src += sizeof(u32);
+ len -= sizeof(u32);
+ }
+
+ /* Handle tail. */
+ for (; len; len--)
+ *dst1++ = (*dst2++ ^= *src++);
+}
+
+
+/* Optimized function for combined buffer xoring and copying. Used by mainly
+ CBC mode decryption. */
+static inline void
+buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy,
+ const void *_src_cpy, size_t len)
+{
+ byte *dst_xor = _dst_xor;
+ byte *srcdst_cpy = _srcdst_cpy;
+ const byte *src_xor = _src_xor;
+ const byte *src_cpy = _src_cpy;
+
+ while (len >= sizeof(u64))
+ {
+ u64 temp = buf_get_he64(src_cpy);
+ buf_put_he64(dst_xor, buf_get_he64(srcdst_cpy) ^ buf_get_he64(src_xor));
+ buf_put_he64(srcdst_cpy, temp);
+ dst_xor += sizeof(u64);
+ srcdst_cpy += sizeof(u64);
+ src_xor += sizeof(u64);
+ src_cpy += sizeof(u64);
+ len -= sizeof(u64);
+ }
+
+ if (len >= sizeof(u32))
+ {
+ u32 temp = buf_get_he32(src_cpy);
+ buf_put_he32(dst_xor, buf_get_he32(srcdst_cpy) ^ buf_get_he32(src_xor));
+ buf_put_he32(srcdst_cpy, temp);
+ dst_xor += sizeof(u32);
+ srcdst_cpy += sizeof(u32);
+ src_xor += sizeof(u32);
+ src_cpy += sizeof(u32);
+ len -= sizeof(u32);
+ }
+
+ /* Handle tail. */
+ for (; len; len--)
+ {
+ byte temp = *src_cpy++;
+ *dst_xor++ = *srcdst_cpy ^ *src_xor++;
+ *srcdst_cpy++ = temp;
+ }
+}
+
+
+/* Optimized function for combined buffer xoring and copying. Used by mainly
+ CFB mode decryption. */
+static inline void
+buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len)
+{
+ buf_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, len);
+}
+
+
+/* Constant-time compare of two buffers. Returns 1 if buffers are equal,
+ and 0 if buffers differ. */
+static inline int
+buf_eq_const(const void *_a, const void *_b, size_t len)
+{
+ const byte *a = _a;
+ const byte *b = _b;
+ int ab, ba;
+ size_t i;
+
+ /* Constant-time compare. */
+ for (i = 0, ab = 0, ba = 0; i < len; i++)
+ {
+ /* If a[i] != b[i], either ab or ba will be negative. */
+ ab |= a[i] - b[i];
+ ba |= b[i] - a[i];
+ }
+
+ /* 'ab | ba' is negative when buffers are not equal. */
+ return (ab | ba) >= 0;
+}
+
+
+#endif /*GCRYPT_BUFHELP_H*/
diff --git a/comm/third_party/libgcrypt/cipher/camellia-aarch64.S b/comm/third_party/libgcrypt/cipher/camellia-aarch64.S
new file mode 100644
index 0000000000..f498086212
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/camellia-aarch64.S
@@ -0,0 +1,586 @@
+/* camellia-aarch64.S - ARMv8/AArch64 assembly implementation of Camellia
+ * cipher
+ *
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__)
+#ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS
+
+.text
+
+/* struct camellia_ctx: */
+#define key_table 0
+
+/* register macros */
+#define CTX x0
+#define RDST x1
+#define RSRC x2
+#define RKEYBITS w3
+
+#define RTAB1 x4
+#define RTAB2 x5
+#define RTAB3 x6
+#define RTAB4 x7
+#define RMASK w8
+
+#define IL w9
+#define IR w10
+
+#define xIL x9
+#define xIR x10
+
+#define XL w11
+#define XR w12
+#define YL w13
+#define YR w14
+
+#define RT0 w15
+#define RT1 w16
+#define RT2 w17
+#define RT3 w19
+
+#define xRT0 x15
+#define xRT1 x16
+#define xRT2 x17
+#define xRT3 x19
+
+#ifdef __AARCH64EL__
+ #define host_to_be(reg, rtmp) \
+ rev reg, reg;
+ #define be_to_host(reg, rtmp) \
+ rev reg, reg;
+#else
+ /* nop on big-endian */
+ #define host_to_be(reg, rtmp) /*_*/
+ #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define ldr_input_aligned_be(rin, a, b, c, d, rtmp) \
+ ldr a, [rin, #0]; \
+ ldr b, [rin, #4]; \
+ be_to_host(a, rtmp); \
+ ldr c, [rin, #8]; \
+ be_to_host(b, rtmp); \
+ ldr d, [rin, #12]; \
+ be_to_host(c, rtmp); \
+ be_to_host(d, rtmp);
+
+#define str_output_aligned_be(rout, a, b, c, d, rtmp) \
+ be_to_host(a, rtmp); \
+ be_to_host(b, rtmp); \
+ str a, [rout, #0]; \
+ be_to_host(c, rtmp); \
+ str b, [rout, #4]; \
+ be_to_host(d, rtmp); \
+ str c, [rout, #8]; \
+ str d, [rout, #12];
+
+/* unaligned word reads/writes allowed */
+#define ldr_input_be(rin, ra, rb, rc, rd, rtmp) \
+ ldr_input_aligned_be(rin, ra, rb, rc, rd, rtmp)
+
+#define str_output_be(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+ str_output_aligned_be(rout, ra, rb, rc, rd, rtmp0)
+
+/**********************************************************************
+ 1-way camellia
+ **********************************************************************/
+#define roundsm(xl, xr, kl, kr, yl, yr) \
+ ldr RT2, [CTX, #(key_table + ((kl) * 4))]; \
+ and IR, RMASK, xr, lsl#(4); /*sp1110*/ \
+ ldr RT3, [CTX, #(key_table + ((kr) * 4))]; \
+ and IL, RMASK, xl, lsr#(24 - 4); /*sp1110*/ \
+ and RT0, RMASK, xr, lsr#(16 - 4); /*sp3033*/ \
+ ldr IR, [RTAB1, xIR]; \
+ and RT1, RMASK, xl, lsr#(8 - 4); /*sp3033*/ \
+ eor yl, yl, RT2; \
+ ldr IL, [RTAB1, xIL]; \
+ eor yr, yr, RT3; \
+ \
+ ldr RT0, [RTAB3, xRT0]; \
+ ldr RT1, [RTAB3, xRT1]; \
+ \
+ and RT2, RMASK, xr, lsr#(24 - 4); /*sp0222*/ \
+ and RT3, RMASK, xl, lsr#(16 - 4); /*sp0222*/ \
+ \
+ eor IR, IR, RT0; \
+ eor IL, IL, RT1; \
+ \
+ ldr RT2, [RTAB2, xRT2]; \
+ and RT0, RMASK, xr, lsr#(8 - 4); /*sp4404*/ \
+ ldr RT3, [RTAB2, xRT3]; \
+ and RT1, RMASK, xl, lsl#(4); /*sp4404*/ \
+ \
+ ldr RT0, [RTAB4, xRT0]; \
+ ldr RT1, [RTAB4, xRT1]; \
+ \
+ eor IR, IR, RT2; \
+ eor IL, IL, RT3; \
+ eor IR, IR, RT0; \
+ eor IL, IL, RT1; \
+ \
+ eor IR, IR, IL; \
+ eor yr, yr, IL, ror#8; \
+ eor yl, yl, IR; \
+ eor yr, yr, IR;
+
+#define enc_rounds(n) \
+ roundsm(XL, XR, ((n) + 2) * 2 + 0, ((n) + 2) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 3) * 2 + 0, ((n) + 3) * 2 + 1, XL, XR); \
+ roundsm(XL, XR, ((n) + 4) * 2 + 0, ((n) + 4) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 5) * 2 + 0, ((n) + 5) * 2 + 1, XL, XR); \
+ roundsm(XL, XR, ((n) + 6) * 2 + 0, ((n) + 6) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 7) * 2 + 0, ((n) + 7) * 2 + 1, XL, XR);
+
+#define dec_rounds(n) \
+ roundsm(XL, XR, ((n) + 7) * 2 + 0, ((n) + 7) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 6) * 2 + 0, ((n) + 6) * 2 + 1, XL, XR); \
+ roundsm(XL, XR, ((n) + 5) * 2 + 0, ((n) + 5) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 4) * 2 + 0, ((n) + 4) * 2 + 1, XL, XR); \
+ roundsm(XL, XR, ((n) + 3) * 2 + 0, ((n) + 3) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 2) * 2 + 0, ((n) + 2) * 2 + 1, XL, XR);
+
+/* perform FL and FLâ»Â¹ */
+#define fls(ll, lr, rl, rr, kll, klr, krl, krr) \
+ ldr RT0, [CTX, #(key_table + ((kll) * 4))]; \
+ ldr RT2, [CTX, #(key_table + ((krr) * 4))]; \
+ and RT0, RT0, ll; \
+ ldr RT3, [CTX, #(key_table + ((krl) * 4))]; \
+ orr RT2, RT2, rr; \
+ ldr RT1, [CTX, #(key_table + ((klr) * 4))]; \
+ eor rl, rl, RT2; \
+ eor lr, lr, RT0, ror#31; \
+ and RT3, RT3, rl; \
+ orr RT1, RT1, lr; \
+ eor ll, ll, RT1; \
+ eor rr, rr, RT3, ror#31;
+
+#define enc_fls(n) \
+ fls(XL, XR, YL, YR, \
+ (n) * 2 + 0, (n) * 2 + 1, \
+ (n) * 2 + 2, (n) * 2 + 3);
+
+#define dec_fls(n) \
+ fls(XL, XR, YL, YR, \
+ (n) * 2 + 2, (n) * 2 + 3, \
+ (n) * 2 + 0, (n) * 2 + 1);
+
+#define inpack(n) \
+ ldr_input_be(RSRC, XL, XR, YL, YR, RT0); \
+ ldr RT0, [CTX, #(key_table + ((n) * 8) + 0)]; \
+ ldr RT1, [CTX, #(key_table + ((n) * 8) + 4)]; \
+ eor XL, XL, RT0; \
+ eor XR, XR, RT1;
+
+#define outunpack(n) \
+ ldr RT0, [CTX, #(key_table + ((n) * 8) + 0)]; \
+ ldr RT1, [CTX, #(key_table + ((n) * 8) + 4)]; \
+ eor YL, YL, RT0; \
+ eor YR, YR, RT1; \
+ str_output_be(RDST, YL, YR, XL, XR, RT0, RT1);
+
+.globl _gcry_camellia_arm_encrypt_block
+ELF(.type _gcry_camellia_arm_encrypt_block,@function;)
+
+_gcry_camellia_arm_encrypt_block:
+ CFI_STARTPROC()
+ stp x19, x30, [sp, #-16]!
+ CFI_ADJUST_CFA_OFFSET(16)
+ CFI_REG_ON_STACK(19, 0)
+ CFI_REG_ON_STACK(30, 8)
+
+ /* input:
+ * x0: keytable
+ * x1: dst
+ * x2: src
+ * w3: keybitlen
+ */
+
+ adr RTAB1, _gcry_camellia_arm_tables;
+ mov RMASK, #(0xff<<4); /* byte mask */
+ add RTAB2, RTAB1, #(1 * 4);
+ add RTAB3, RTAB1, #(2 * 4);
+ add RTAB4, RTAB1, #(3 * 4);
+
+ inpack(0);
+
+ enc_rounds(0);
+ enc_fls(8);
+ enc_rounds(8);
+ enc_fls(16);
+ enc_rounds(16);
+
+ cmp RKEYBITS, #(16 * 8);
+ bne .Lenc_256;
+
+ outunpack(24);
+
+ CFI_REMEMBER_STATE()
+ ldp x19, x30, [sp], #16
+ CFI_ADJUST_CFA_OFFSET(-16)
+ CFI_RESTORE(x19)
+ CFI_RESTORE(x30)
+ ret;
+ CFI_RESTORE_STATE()
+.ltorg
+
+.Lenc_256:
+ enc_fls(24);
+ enc_rounds(24);
+
+ outunpack(32);
+
+ ldp x19, x30, [sp], #16
+ CFI_ADJUST_CFA_OFFSET(-16)
+ CFI_RESTORE(x19)
+ CFI_RESTORE(x30)
+ ret;
+ CFI_ENDPROC()
+.ltorg
+ELF(.size _gcry_camellia_arm_encrypt_block,.-_gcry_camellia_arm_encrypt_block;)
+
+.globl _gcry_camellia_arm_decrypt_block
+ELF(.type _gcry_camellia_arm_decrypt_block,@function;)
+
+_gcry_camellia_arm_decrypt_block:
+ CFI_STARTPROC()
+ stp x19, x30, [sp, #-16]!
+ CFI_ADJUST_CFA_OFFSET(16)
+ CFI_REG_ON_STACK(19, 0)
+ CFI_REG_ON_STACK(30, 8)
+
+ /* input:
+ * x0: keytable
+ * x1: dst
+ * x2: src
+ * w3: keybitlen
+ */
+
+ adr RTAB1, _gcry_camellia_arm_tables;
+ mov RMASK, #(0xff<<4); /* byte mask */
+ add RTAB2, RTAB1, #(1 * 4);
+ add RTAB3, RTAB1, #(2 * 4);
+ add RTAB4, RTAB1, #(3 * 4);
+
+ cmp RKEYBITS, #(16 * 8);
+ bne .Ldec_256;
+
+ inpack(24);
+
+.Ldec_128:
+ dec_rounds(16);
+ dec_fls(16);
+ dec_rounds(8);
+ dec_fls(8);
+ dec_rounds(0);
+
+ outunpack(0);
+
+ CFI_REMEMBER_STATE()
+ ldp x19, x30, [sp], #16
+ CFI_ADJUST_CFA_OFFSET(-16)
+ CFI_RESTORE(x19)
+ CFI_RESTORE(x30)
+ ret;
+ CFI_RESTORE_STATE()
+.ltorg
+
+.Ldec_256:
+ inpack(32);
+ dec_rounds(24);
+ dec_fls(24);
+
+ b .Ldec_128;
+ CFI_ENDPROC()
+.ltorg
+ELF(.size _gcry_camellia_arm_decrypt_block,.-_gcry_camellia_arm_decrypt_block;)
+
+/* Encryption/Decryption tables */
+ELF(.type _gcry_camellia_arm_tables,@object;)
+.balign 32
+_gcry_camellia_arm_tables:
+.Lcamellia_sp1110:
+.long 0x70707000
+.Lcamellia_sp0222:
+ .long 0x00e0e0e0
+.Lcamellia_sp3033:
+ .long 0x38003838
+.Lcamellia_sp4404:
+ .long 0x70700070
+.long 0x82828200, 0x00050505, 0x41004141, 0x2c2c002c
+.long 0x2c2c2c00, 0x00585858, 0x16001616, 0xb3b300b3
+.long 0xececec00, 0x00d9d9d9, 0x76007676, 0xc0c000c0
+.long 0xb3b3b300, 0x00676767, 0xd900d9d9, 0xe4e400e4
+.long 0x27272700, 0x004e4e4e, 0x93009393, 0x57570057
+.long 0xc0c0c000, 0x00818181, 0x60006060, 0xeaea00ea
+.long 0xe5e5e500, 0x00cbcbcb, 0xf200f2f2, 0xaeae00ae
+.long 0xe4e4e400, 0x00c9c9c9, 0x72007272, 0x23230023
+.long 0x85858500, 0x000b0b0b, 0xc200c2c2, 0x6b6b006b
+.long 0x57575700, 0x00aeaeae, 0xab00abab, 0x45450045
+.long 0x35353500, 0x006a6a6a, 0x9a009a9a, 0xa5a500a5
+.long 0xeaeaea00, 0x00d5d5d5, 0x75007575, 0xeded00ed
+.long 0x0c0c0c00, 0x00181818, 0x06000606, 0x4f4f004f
+.long 0xaeaeae00, 0x005d5d5d, 0x57005757, 0x1d1d001d
+.long 0x41414100, 0x00828282, 0xa000a0a0, 0x92920092
+.long 0x23232300, 0x00464646, 0x91009191, 0x86860086
+.long 0xefefef00, 0x00dfdfdf, 0xf700f7f7, 0xafaf00af
+.long 0x6b6b6b00, 0x00d6d6d6, 0xb500b5b5, 0x7c7c007c
+.long 0x93939300, 0x00272727, 0xc900c9c9, 0x1f1f001f
+.long 0x45454500, 0x008a8a8a, 0xa200a2a2, 0x3e3e003e
+.long 0x19191900, 0x00323232, 0x8c008c8c, 0xdcdc00dc
+.long 0xa5a5a500, 0x004b4b4b, 0xd200d2d2, 0x5e5e005e
+.long 0x21212100, 0x00424242, 0x90009090, 0x0b0b000b
+.long 0xededed00, 0x00dbdbdb, 0xf600f6f6, 0xa6a600a6
+.long 0x0e0e0e00, 0x001c1c1c, 0x07000707, 0x39390039
+.long 0x4f4f4f00, 0x009e9e9e, 0xa700a7a7, 0xd5d500d5
+.long 0x4e4e4e00, 0x009c9c9c, 0x27002727, 0x5d5d005d
+.long 0x1d1d1d00, 0x003a3a3a, 0x8e008e8e, 0xd9d900d9
+.long 0x65656500, 0x00cacaca, 0xb200b2b2, 0x5a5a005a
+.long 0x92929200, 0x00252525, 0x49004949, 0x51510051
+.long 0xbdbdbd00, 0x007b7b7b, 0xde00dede, 0x6c6c006c
+.long 0x86868600, 0x000d0d0d, 0x43004343, 0x8b8b008b
+.long 0xb8b8b800, 0x00717171, 0x5c005c5c, 0x9a9a009a
+.long 0xafafaf00, 0x005f5f5f, 0xd700d7d7, 0xfbfb00fb
+.long 0x8f8f8f00, 0x001f1f1f, 0xc700c7c7, 0xb0b000b0
+.long 0x7c7c7c00, 0x00f8f8f8, 0x3e003e3e, 0x74740074
+.long 0xebebeb00, 0x00d7d7d7, 0xf500f5f5, 0x2b2b002b
+.long 0x1f1f1f00, 0x003e3e3e, 0x8f008f8f, 0xf0f000f0
+.long 0xcecece00, 0x009d9d9d, 0x67006767, 0x84840084
+.long 0x3e3e3e00, 0x007c7c7c, 0x1f001f1f, 0xdfdf00df
+.long 0x30303000, 0x00606060, 0x18001818, 0xcbcb00cb
+.long 0xdcdcdc00, 0x00b9b9b9, 0x6e006e6e, 0x34340034
+.long 0x5f5f5f00, 0x00bebebe, 0xaf00afaf, 0x76760076
+.long 0x5e5e5e00, 0x00bcbcbc, 0x2f002f2f, 0x6d6d006d
+.long 0xc5c5c500, 0x008b8b8b, 0xe200e2e2, 0xa9a900a9
+.long 0x0b0b0b00, 0x00161616, 0x85008585, 0xd1d100d1
+.long 0x1a1a1a00, 0x00343434, 0x0d000d0d, 0x04040004
+.long 0xa6a6a600, 0x004d4d4d, 0x53005353, 0x14140014
+.long 0xe1e1e100, 0x00c3c3c3, 0xf000f0f0, 0x3a3a003a
+.long 0x39393900, 0x00727272, 0x9c009c9c, 0xdede00de
+.long 0xcacaca00, 0x00959595, 0x65006565, 0x11110011
+.long 0xd5d5d500, 0x00ababab, 0xea00eaea, 0x32320032
+.long 0x47474700, 0x008e8e8e, 0xa300a3a3, 0x9c9c009c
+.long 0x5d5d5d00, 0x00bababa, 0xae00aeae, 0x53530053
+.long 0x3d3d3d00, 0x007a7a7a, 0x9e009e9e, 0xf2f200f2
+.long 0xd9d9d900, 0x00b3b3b3, 0xec00ecec, 0xfefe00fe
+.long 0x01010100, 0x00020202, 0x80008080, 0xcfcf00cf
+.long 0x5a5a5a00, 0x00b4b4b4, 0x2d002d2d, 0xc3c300c3
+.long 0xd6d6d600, 0x00adadad, 0x6b006b6b, 0x7a7a007a
+.long 0x51515100, 0x00a2a2a2, 0xa800a8a8, 0x24240024
+.long 0x56565600, 0x00acacac, 0x2b002b2b, 0xe8e800e8
+.long 0x6c6c6c00, 0x00d8d8d8, 0x36003636, 0x60600060
+.long 0x4d4d4d00, 0x009a9a9a, 0xa600a6a6, 0x69690069
+.long 0x8b8b8b00, 0x00171717, 0xc500c5c5, 0xaaaa00aa
+.long 0x0d0d0d00, 0x001a1a1a, 0x86008686, 0xa0a000a0
+.long 0x9a9a9a00, 0x00353535, 0x4d004d4d, 0xa1a100a1
+.long 0x66666600, 0x00cccccc, 0x33003333, 0x62620062
+.long 0xfbfbfb00, 0x00f7f7f7, 0xfd00fdfd, 0x54540054
+.long 0xcccccc00, 0x00999999, 0x66006666, 0x1e1e001e
+.long 0xb0b0b000, 0x00616161, 0x58005858, 0xe0e000e0
+.long 0x2d2d2d00, 0x005a5a5a, 0x96009696, 0x64640064
+.long 0x74747400, 0x00e8e8e8, 0x3a003a3a, 0x10100010
+.long 0x12121200, 0x00242424, 0x09000909, 0x00000000
+.long 0x2b2b2b00, 0x00565656, 0x95009595, 0xa3a300a3
+.long 0x20202000, 0x00404040, 0x10001010, 0x75750075
+.long 0xf0f0f000, 0x00e1e1e1, 0x78007878, 0x8a8a008a
+.long 0xb1b1b100, 0x00636363, 0xd800d8d8, 0xe6e600e6
+.long 0x84848400, 0x00090909, 0x42004242, 0x09090009
+.long 0x99999900, 0x00333333, 0xcc00cccc, 0xdddd00dd
+.long 0xdfdfdf00, 0x00bfbfbf, 0xef00efef, 0x87870087
+.long 0x4c4c4c00, 0x00989898, 0x26002626, 0x83830083
+.long 0xcbcbcb00, 0x00979797, 0xe500e5e5, 0xcdcd00cd
+.long 0xc2c2c200, 0x00858585, 0x61006161, 0x90900090
+.long 0x34343400, 0x00686868, 0x1a001a1a, 0x73730073
+.long 0x7e7e7e00, 0x00fcfcfc, 0x3f003f3f, 0xf6f600f6
+.long 0x76767600, 0x00ececec, 0x3b003b3b, 0x9d9d009d
+.long 0x05050500, 0x000a0a0a, 0x82008282, 0xbfbf00bf
+.long 0x6d6d6d00, 0x00dadada, 0xb600b6b6, 0x52520052
+.long 0xb7b7b700, 0x006f6f6f, 0xdb00dbdb, 0xd8d800d8
+.long 0xa9a9a900, 0x00535353, 0xd400d4d4, 0xc8c800c8
+.long 0x31313100, 0x00626262, 0x98009898, 0xc6c600c6
+.long 0xd1d1d100, 0x00a3a3a3, 0xe800e8e8, 0x81810081
+.long 0x17171700, 0x002e2e2e, 0x8b008b8b, 0x6f6f006f
+.long 0x04040400, 0x00080808, 0x02000202, 0x13130013
+.long 0xd7d7d700, 0x00afafaf, 0xeb00ebeb, 0x63630063
+.long 0x14141400, 0x00282828, 0x0a000a0a, 0xe9e900e9
+.long 0x58585800, 0x00b0b0b0, 0x2c002c2c, 0xa7a700a7
+.long 0x3a3a3a00, 0x00747474, 0x1d001d1d, 0x9f9f009f
+.long 0x61616100, 0x00c2c2c2, 0xb000b0b0, 0xbcbc00bc
+.long 0xdedede00, 0x00bdbdbd, 0x6f006f6f, 0x29290029
+.long 0x1b1b1b00, 0x00363636, 0x8d008d8d, 0xf9f900f9
+.long 0x11111100, 0x00222222, 0x88008888, 0x2f2f002f
+.long 0x1c1c1c00, 0x00383838, 0x0e000e0e, 0xb4b400b4
+.long 0x32323200, 0x00646464, 0x19001919, 0x78780078
+.long 0x0f0f0f00, 0x001e1e1e, 0x87008787, 0x06060006
+.long 0x9c9c9c00, 0x00393939, 0x4e004e4e, 0xe7e700e7
+.long 0x16161600, 0x002c2c2c, 0x0b000b0b, 0x71710071
+.long 0x53535300, 0x00a6a6a6, 0xa900a9a9, 0xd4d400d4
+.long 0x18181800, 0x00303030, 0x0c000c0c, 0xabab00ab
+.long 0xf2f2f200, 0x00e5e5e5, 0x79007979, 0x88880088
+.long 0x22222200, 0x00444444, 0x11001111, 0x8d8d008d
+.long 0xfefefe00, 0x00fdfdfd, 0x7f007f7f, 0x72720072
+.long 0x44444400, 0x00888888, 0x22002222, 0xb9b900b9
+.long 0xcfcfcf00, 0x009f9f9f, 0xe700e7e7, 0xf8f800f8
+.long 0xb2b2b200, 0x00656565, 0x59005959, 0xacac00ac
+.long 0xc3c3c300, 0x00878787, 0xe100e1e1, 0x36360036
+.long 0xb5b5b500, 0x006b6b6b, 0xda00dada, 0x2a2a002a
+.long 0x7a7a7a00, 0x00f4f4f4, 0x3d003d3d, 0x3c3c003c
+.long 0x91919100, 0x00232323, 0xc800c8c8, 0xf1f100f1
+.long 0x24242400, 0x00484848, 0x12001212, 0x40400040
+.long 0x08080800, 0x00101010, 0x04000404, 0xd3d300d3
+.long 0xe8e8e800, 0x00d1d1d1, 0x74007474, 0xbbbb00bb
+.long 0xa8a8a800, 0x00515151, 0x54005454, 0x43430043
+.long 0x60606000, 0x00c0c0c0, 0x30003030, 0x15150015
+.long 0xfcfcfc00, 0x00f9f9f9, 0x7e007e7e, 0xadad00ad
+.long 0x69696900, 0x00d2d2d2, 0xb400b4b4, 0x77770077
+.long 0x50505000, 0x00a0a0a0, 0x28002828, 0x80800080
+.long 0xaaaaaa00, 0x00555555, 0x55005555, 0x82820082
+.long 0xd0d0d000, 0x00a1a1a1, 0x68006868, 0xecec00ec
+.long 0xa0a0a000, 0x00414141, 0x50005050, 0x27270027
+.long 0x7d7d7d00, 0x00fafafa, 0xbe00bebe, 0xe5e500e5
+.long 0xa1a1a100, 0x00434343, 0xd000d0d0, 0x85850085
+.long 0x89898900, 0x00131313, 0xc400c4c4, 0x35350035
+.long 0x62626200, 0x00c4c4c4, 0x31003131, 0x0c0c000c
+.long 0x97979700, 0x002f2f2f, 0xcb00cbcb, 0x41410041
+.long 0x54545400, 0x00a8a8a8, 0x2a002a2a, 0xefef00ef
+.long 0x5b5b5b00, 0x00b6b6b6, 0xad00adad, 0x93930093
+.long 0x1e1e1e00, 0x003c3c3c, 0x0f000f0f, 0x19190019
+.long 0x95959500, 0x002b2b2b, 0xca00caca, 0x21210021
+.long 0xe0e0e000, 0x00c1c1c1, 0x70007070, 0x0e0e000e
+.long 0xffffff00, 0x00ffffff, 0xff00ffff, 0x4e4e004e
+.long 0x64646400, 0x00c8c8c8, 0x32003232, 0x65650065
+.long 0xd2d2d200, 0x00a5a5a5, 0x69006969, 0xbdbd00bd
+.long 0x10101000, 0x00202020, 0x08000808, 0xb8b800b8
+.long 0xc4c4c400, 0x00898989, 0x62006262, 0x8f8f008f
+.long 0x00000000, 0x00000000, 0x00000000, 0xebeb00eb
+.long 0x48484800, 0x00909090, 0x24002424, 0xcece00ce
+.long 0xa3a3a300, 0x00474747, 0xd100d1d1, 0x30300030
+.long 0xf7f7f700, 0x00efefef, 0xfb00fbfb, 0x5f5f005f
+.long 0x75757500, 0x00eaeaea, 0xba00baba, 0xc5c500c5
+.long 0xdbdbdb00, 0x00b7b7b7, 0xed00eded, 0x1a1a001a
+.long 0x8a8a8a00, 0x00151515, 0x45004545, 0xe1e100e1
+.long 0x03030300, 0x00060606, 0x81008181, 0xcaca00ca
+.long 0xe6e6e600, 0x00cdcdcd, 0x73007373, 0x47470047
+.long 0xdadada00, 0x00b5b5b5, 0x6d006d6d, 0x3d3d003d
+.long 0x09090900, 0x00121212, 0x84008484, 0x01010001
+.long 0x3f3f3f00, 0x007e7e7e, 0x9f009f9f, 0xd6d600d6
+.long 0xdddddd00, 0x00bbbbbb, 0xee00eeee, 0x56560056
+.long 0x94949400, 0x00292929, 0x4a004a4a, 0x4d4d004d
+.long 0x87878700, 0x000f0f0f, 0xc300c3c3, 0x0d0d000d
+.long 0x5c5c5c00, 0x00b8b8b8, 0x2e002e2e, 0x66660066
+.long 0x83838300, 0x00070707, 0xc100c1c1, 0xcccc00cc
+.long 0x02020200, 0x00040404, 0x01000101, 0x2d2d002d
+.long 0xcdcdcd00, 0x009b9b9b, 0xe600e6e6, 0x12120012
+.long 0x4a4a4a00, 0x00949494, 0x25002525, 0x20200020
+.long 0x90909000, 0x00212121, 0x48004848, 0xb1b100b1
+.long 0x33333300, 0x00666666, 0x99009999, 0x99990099
+.long 0x73737300, 0x00e6e6e6, 0xb900b9b9, 0x4c4c004c
+.long 0x67676700, 0x00cecece, 0xb300b3b3, 0xc2c200c2
+.long 0xf6f6f600, 0x00ededed, 0x7b007b7b, 0x7e7e007e
+.long 0xf3f3f300, 0x00e7e7e7, 0xf900f9f9, 0x05050005
+.long 0x9d9d9d00, 0x003b3b3b, 0xce00cece, 0xb7b700b7
+.long 0x7f7f7f00, 0x00fefefe, 0xbf00bfbf, 0x31310031
+.long 0xbfbfbf00, 0x007f7f7f, 0xdf00dfdf, 0x17170017
+.long 0xe2e2e200, 0x00c5c5c5, 0x71007171, 0xd7d700d7
+.long 0x52525200, 0x00a4a4a4, 0x29002929, 0x58580058
+.long 0x9b9b9b00, 0x00373737, 0xcd00cdcd, 0x61610061
+.long 0xd8d8d800, 0x00b1b1b1, 0x6c006c6c, 0x1b1b001b
+.long 0x26262600, 0x004c4c4c, 0x13001313, 0x1c1c001c
+.long 0xc8c8c800, 0x00919191, 0x64006464, 0x0f0f000f
+.long 0x37373700, 0x006e6e6e, 0x9b009b9b, 0x16160016
+.long 0xc6c6c600, 0x008d8d8d, 0x63006363, 0x18180018
+.long 0x3b3b3b00, 0x00767676, 0x9d009d9d, 0x22220022
+.long 0x81818100, 0x00030303, 0xc000c0c0, 0x44440044
+.long 0x96969600, 0x002d2d2d, 0x4b004b4b, 0xb2b200b2
+.long 0x6f6f6f00, 0x00dedede, 0xb700b7b7, 0xb5b500b5
+.long 0x4b4b4b00, 0x00969696, 0xa500a5a5, 0x91910091
+.long 0x13131300, 0x00262626, 0x89008989, 0x08080008
+.long 0xbebebe00, 0x007d7d7d, 0x5f005f5f, 0xa8a800a8
+.long 0x63636300, 0x00c6c6c6, 0xb100b1b1, 0xfcfc00fc
+.long 0x2e2e2e00, 0x005c5c5c, 0x17001717, 0x50500050
+.long 0xe9e9e900, 0x00d3d3d3, 0xf400f4f4, 0xd0d000d0
+.long 0x79797900, 0x00f2f2f2, 0xbc00bcbc, 0x7d7d007d
+.long 0xa7a7a700, 0x004f4f4f, 0xd300d3d3, 0x89890089
+.long 0x8c8c8c00, 0x00191919, 0x46004646, 0x97970097
+.long 0x9f9f9f00, 0x003f3f3f, 0xcf00cfcf, 0x5b5b005b
+.long 0x6e6e6e00, 0x00dcdcdc, 0x37003737, 0x95950095
+.long 0xbcbcbc00, 0x00797979, 0x5e005e5e, 0xffff00ff
+.long 0x8e8e8e00, 0x001d1d1d, 0x47004747, 0xd2d200d2
+.long 0x29292900, 0x00525252, 0x94009494, 0xc4c400c4
+.long 0xf5f5f500, 0x00ebebeb, 0xfa00fafa, 0x48480048
+.long 0xf9f9f900, 0x00f3f3f3, 0xfc00fcfc, 0xf7f700f7
+.long 0xb6b6b600, 0x006d6d6d, 0x5b005b5b, 0xdbdb00db
+.long 0x2f2f2f00, 0x005e5e5e, 0x97009797, 0x03030003
+.long 0xfdfdfd00, 0x00fbfbfb, 0xfe00fefe, 0xdada00da
+.long 0xb4b4b400, 0x00696969, 0x5a005a5a, 0x3f3f003f
+.long 0x59595900, 0x00b2b2b2, 0xac00acac, 0x94940094
+.long 0x78787800, 0x00f0f0f0, 0x3c003c3c, 0x5c5c005c
+.long 0x98989800, 0x00313131, 0x4c004c4c, 0x02020002
+.long 0x06060600, 0x000c0c0c, 0x03000303, 0x4a4a004a
+.long 0x6a6a6a00, 0x00d4d4d4, 0x35003535, 0x33330033
+.long 0xe7e7e700, 0x00cfcfcf, 0xf300f3f3, 0x67670067
+.long 0x46464600, 0x008c8c8c, 0x23002323, 0xf3f300f3
+.long 0x71717100, 0x00e2e2e2, 0xb800b8b8, 0x7f7f007f
+.long 0xbababa00, 0x00757575, 0x5d005d5d, 0xe2e200e2
+.long 0xd4d4d400, 0x00a9a9a9, 0x6a006a6a, 0x9b9b009b
+.long 0x25252500, 0x004a4a4a, 0x92009292, 0x26260026
+.long 0xababab00, 0x00575757, 0xd500d5d5, 0x37370037
+.long 0x42424200, 0x00848484, 0x21002121, 0x3b3b003b
+.long 0x88888800, 0x00111111, 0x44004444, 0x96960096
+.long 0xa2a2a200, 0x00454545, 0x51005151, 0x4b4b004b
+.long 0x8d8d8d00, 0x001b1b1b, 0xc600c6c6, 0xbebe00be
+.long 0xfafafa00, 0x00f5f5f5, 0x7d007d7d, 0x2e2e002e
+.long 0x72727200, 0x00e4e4e4, 0x39003939, 0x79790079
+.long 0x07070700, 0x000e0e0e, 0x83008383, 0x8c8c008c
+.long 0xb9b9b900, 0x00737373, 0xdc00dcdc, 0x6e6e006e
+.long 0x55555500, 0x00aaaaaa, 0xaa00aaaa, 0x8e8e008e
+.long 0xf8f8f800, 0x00f1f1f1, 0x7c007c7c, 0xf5f500f5
+.long 0xeeeeee00, 0x00dddddd, 0x77007777, 0xb6b600b6
+.long 0xacacac00, 0x00595959, 0x56005656, 0xfdfd00fd
+.long 0x0a0a0a00, 0x00141414, 0x05000505, 0x59590059
+.long 0x36363600, 0x006c6c6c, 0x1b001b1b, 0x98980098
+.long 0x49494900, 0x00929292, 0xa400a4a4, 0x6a6a006a
+.long 0x2a2a2a00, 0x00545454, 0x15001515, 0x46460046
+.long 0x68686800, 0x00d0d0d0, 0x34003434, 0xbaba00ba
+.long 0x3c3c3c00, 0x00787878, 0x1e001e1e, 0x25250025
+.long 0x38383800, 0x00707070, 0x1c001c1c, 0x42420042
+.long 0xf1f1f100, 0x00e3e3e3, 0xf800f8f8, 0xa2a200a2
+.long 0xa4a4a400, 0x00494949, 0x52005252, 0xfafa00fa
+.long 0x40404000, 0x00808080, 0x20002020, 0x07070007
+.long 0x28282800, 0x00505050, 0x14001414, 0x55550055
+.long 0xd3d3d300, 0x00a7a7a7, 0xe900e9e9, 0xeeee00ee
+.long 0x7b7b7b00, 0x00f6f6f6, 0xbd00bdbd, 0x0a0a000a
+.long 0xbbbbbb00, 0x00777777, 0xdd00dddd, 0x49490049
+.long 0xc9c9c900, 0x00939393, 0xe400e4e4, 0x68680068
+.long 0x43434300, 0x00868686, 0xa100a1a1, 0x38380038
+.long 0xc1c1c100, 0x00838383, 0xe000e0e0, 0xa4a400a4
+.long 0x15151500, 0x002a2a2a, 0x8a008a8a, 0x28280028
+.long 0xe3e3e300, 0x00c7c7c7, 0xf100f1f1, 0x7b7b007b
+.long 0xadadad00, 0x005b5b5b, 0xd600d6d6, 0xc9c900c9
+.long 0xf4f4f400, 0x00e9e9e9, 0x7a007a7a, 0xc1c100c1
+.long 0x77777700, 0x00eeeeee, 0xbb00bbbb, 0xe3e300e3
+.long 0xc7c7c700, 0x008f8f8f, 0xe300e3e3, 0xf4f400f4
+.long 0x80808000, 0x00010101, 0x40004040, 0xc7c700c7
+.long 0x9e9e9e00, 0x003d3d3d, 0x4f004f4f, 0x9e9e009e
+ELF(.size _gcry_camellia_arm_tables,.-_gcry_camellia_arm_tables;)
+
+#endif /*HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS*/
+#endif /*__AARCH64EL__*/
diff --git a/comm/third_party/libgcrypt/cipher/camellia-aesni-avx-amd64.S b/comm/third_party/libgcrypt/cipher/camellia-aesni-avx-amd64.S
new file mode 100644
index 0000000000..64cabaa51b
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/camellia-aesni-avx-amd64.S
@@ -0,0 +1,2618 @@
+/* camellia-avx-aesni-amd64.S - AES-NI/AVX implementation of Camellia cipher
+ *
+ * Copyright (C) 2013-2015,2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#ifdef __x86_64
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
+
+#include "asm-common-amd64.h"
+
+#define CAMELLIA_TABLE_BYTE_LEN 272
+
+/* struct CAMELLIA_context: */
+#define key_table 0
+#define key_bitlength CAMELLIA_TABLE_BYTE_LEN
+
+/* register macros */
+#define CTX %rdi
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+#define filter_8bit(x, lo_t, hi_t, mask4bit, tmp0) \
+ vpand x, mask4bit, tmp0; \
+ vpandn x, mask4bit, x; \
+ vpsrld $4, x, x; \
+ \
+ vpshufb tmp0, lo_t, tmp0; \
+ vpshufb x, hi_t, x; \
+ vpxor tmp0, x, x;
+
+/**********************************************************************
+ 16-way camellia
+ **********************************************************************/
+
+/*
+ * IN:
+ * x0..x7: byte-sliced AB state
+ * mem_cd: register pointer storing CD state
+ * key: index for key material
+ * OUT:
+ * x0..x7: new byte-sliced CD state
+ */
+#define roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, t0, t1, t2, t3, t4, t5, t6, \
+ t7, mem_cd, key) \
+ /* \
+ * S-function with AES subbytes \
+ */ \
+ vmovdqa .Linv_shift_row rRIP, t4; \
+ vbroadcastss .L0f0f0f0f rRIP, t7; \
+ vmovdqa .Lpre_tf_lo_s1 rRIP, t0; \
+ vmovdqa .Lpre_tf_hi_s1 rRIP, t1; \
+ \
+ /* AES inverse shift rows */ \
+ vpshufb t4, x0, x0; \
+ vpshufb t4, x7, x7; \
+ vpshufb t4, x1, x1; \
+ vpshufb t4, x4, x4; \
+ vpshufb t4, x2, x2; \
+ vpshufb t4, x5, x5; \
+ vpshufb t4, x3, x3; \
+ vpshufb t4, x6, x6; \
+ \
+ /* prefilter sboxes 1, 2 and 3 */ \
+ vmovdqa .Lpre_tf_lo_s4 rRIP, t2; \
+ vmovdqa .Lpre_tf_hi_s4 rRIP, t3; \
+ filter_8bit(x0, t0, t1, t7, t6); \
+ filter_8bit(x7, t0, t1, t7, t6); \
+ filter_8bit(x1, t0, t1, t7, t6); \
+ filter_8bit(x4, t0, t1, t7, t6); \
+ filter_8bit(x2, t0, t1, t7, t6); \
+ filter_8bit(x5, t0, t1, t7, t6); \
+ \
+ /* prefilter sbox 4 */ \
+ vpxor t4, t4, t4; \
+ filter_8bit(x3, t2, t3, t7, t6); \
+ filter_8bit(x6, t2, t3, t7, t6); \
+ \
+ /* AES subbytes + AES shift rows */ \
+ vmovdqa .Lpost_tf_lo_s1 rRIP, t0; \
+ vmovdqa .Lpost_tf_hi_s1 rRIP, t1; \
+ vaesenclast t4, x0, x0; \
+ vaesenclast t4, x7, x7; \
+ vaesenclast t4, x1, x1; \
+ vaesenclast t4, x4, x4; \
+ vaesenclast t4, x2, x2; \
+ vaesenclast t4, x5, x5; \
+ vaesenclast t4, x3, x3; \
+ vaesenclast t4, x6, x6; \
+ \
+ /* postfilter sboxes 1 and 4 */ \
+ vmovdqa .Lpost_tf_lo_s3 rRIP, t2; \
+ vmovdqa .Lpost_tf_hi_s3 rRIP, t3; \
+ filter_8bit(x0, t0, t1, t7, t6); \
+ filter_8bit(x7, t0, t1, t7, t6); \
+ filter_8bit(x3, t0, t1, t7, t6); \
+ filter_8bit(x6, t0, t1, t7, t6); \
+ \
+ /* postfilter sbox 3 */ \
+ vmovdqa .Lpost_tf_lo_s2 rRIP, t4; \
+ vmovdqa .Lpost_tf_hi_s2 rRIP, t5; \
+ filter_8bit(x2, t2, t3, t7, t6); \
+ filter_8bit(x5, t2, t3, t7, t6); \
+ \
+ vpxor t6, t6, t6; \
+ vmovq key, t0; \
+ \
+ /* postfilter sbox 2 */ \
+ filter_8bit(x1, t4, t5, t7, t2); \
+ filter_8bit(x4, t4, t5, t7, t2); \
+ \
+ vpsrldq $5, t0, t5; \
+ vpsrldq $1, t0, t1; \
+ vpsrldq $2, t0, t2; \
+ vpsrldq $3, t0, t3; \
+ vpsrldq $4, t0, t4; \
+ vpshufb t6, t0, t0; \
+ vpshufb t6, t1, t1; \
+ vpshufb t6, t2, t2; \
+ vpshufb t6, t3, t3; \
+ vpshufb t6, t4, t4; \
+ vpsrldq $2, t5, t7; \
+ vpshufb t6, t7, t7; \
+ \
+ /* P-function */ \
+ vpxor x5, x0, x0; \
+ vpxor x6, x1, x1; \
+ vpxor x7, x2, x2; \
+ vpxor x4, x3, x3; \
+ \
+ vpxor x2, x4, x4; \
+ vpxor x3, x5, x5; \
+ vpxor x0, x6, x6; \
+ vpxor x1, x7, x7; \
+ \
+ vpxor x7, x0, x0; \
+ vpxor x4, x1, x1; \
+ vpxor x5, x2, x2; \
+ vpxor x6, x3, x3; \
+ \
+ vpxor x3, x4, x4; \
+ vpxor x0, x5, x5; \
+ vpxor x1, x6, x6; \
+ vpxor x2, x7, x7; /* note: high and low parts swapped */ \
+ \
+ /* Add key material and result to CD (x becomes new CD) */ \
+ \
+ vpxor t3, x4, x4; \
+ vpxor 0 * 16(mem_cd), x4, x4; \
+ \
+ vpxor t2, x5, x5; \
+ vpxor 1 * 16(mem_cd), x5, x5; \
+ \
+ vpsrldq $1, t5, t3; \
+ vpshufb t6, t5, t5; \
+ vpshufb t6, t3, t6; \
+ \
+ vpxor t1, x6, x6; \
+ vpxor 2 * 16(mem_cd), x6, x6; \
+ \
+ vpxor t0, x7, x7; \
+ vpxor 3 * 16(mem_cd), x7, x7; \
+ \
+ vpxor t7, x0, x0; \
+ vpxor 4 * 16(mem_cd), x0, x0; \
+ \
+ vpxor t6, x1, x1; \
+ vpxor 5 * 16(mem_cd), x1, x1; \
+ \
+ vpxor t5, x2, x2; \
+ vpxor 6 * 16(mem_cd), x2, x2; \
+ \
+ vpxor t4, x3, x3; \
+ vpxor 7 * 16(mem_cd), x3, x3;
+
+/*
+ * IN/OUT:
+ * x0..x7: byte-sliced AB state preloaded
+ * mem_ab: byte-sliced AB state in memory
+ * mem_cb: byte-sliced CD state in memory
+ */
+#define two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, i, dir, store_ab) \
+ roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_cd, (key_table + (i) * 8)(CTX)); \
+ \
+ vmovdqu x4, 0 * 16(mem_cd); \
+ vmovdqu x5, 1 * 16(mem_cd); \
+ vmovdqu x6, 2 * 16(mem_cd); \
+ vmovdqu x7, 3 * 16(mem_cd); \
+ vmovdqu x0, 4 * 16(mem_cd); \
+ vmovdqu x1, 5 * 16(mem_cd); \
+ vmovdqu x2, 6 * 16(mem_cd); \
+ vmovdqu x3, 7 * 16(mem_cd); \
+ \
+ roundsm16(x4, x5, x6, x7, x0, x1, x2, x3, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, (key_table + ((i) + (dir)) * 8)(CTX)); \
+ \
+ store_ab(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab);
+
+#define dummy_store(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) /* do nothing */
+
+#define store_ab_state(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) \
+ /* Store new AB state */ \
+ vmovdqu x0, 0 * 16(mem_ab); \
+ vmovdqu x1, 1 * 16(mem_ab); \
+ vmovdqu x2, 2 * 16(mem_ab); \
+ vmovdqu x3, 3 * 16(mem_ab); \
+ vmovdqu x4, 4 * 16(mem_ab); \
+ vmovdqu x5, 5 * 16(mem_ab); \
+ vmovdqu x6, 6 * 16(mem_ab); \
+ vmovdqu x7, 7 * 16(mem_ab);
+
+#define enc_rounds16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, i) \
+ two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 2, 1, store_ab_state); \
+ two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 4, 1, store_ab_state); \
+ two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 6, 1, dummy_store);
+
+#define dec_rounds16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, i) \
+ two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 7, -1, store_ab_state); \
+ two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 5, -1, store_ab_state); \
+ two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 3, -1, dummy_store);
+
+/*
+ * IN:
+ * v0..3: byte-sliced 32-bit integers
+ * OUT:
+ * v0..3: (IN <<< 1)
+ */
+#define rol32_1_16(v0, v1, v2, v3, t0, t1, t2, zero) \
+ vpcmpgtb v0, zero, t0; \
+ vpaddb v0, v0, v0; \
+ vpabsb t0, t0; \
+ \
+ vpcmpgtb v1, zero, t1; \
+ vpaddb v1, v1, v1; \
+ vpabsb t1, t1; \
+ \
+ vpcmpgtb v2, zero, t2; \
+ vpaddb v2, v2, v2; \
+ vpabsb t2, t2; \
+ \
+ vpor t0, v1, v1; \
+ \
+ vpcmpgtb v3, zero, t0; \
+ vpaddb v3, v3, v3; \
+ vpabsb t0, t0; \
+ \
+ vpor t1, v2, v2; \
+ vpor t2, v3, v3; \
+ vpor t0, v0, v0;
+
+/*
+ * IN:
+ * r: byte-sliced AB state in memory
+ * l: byte-sliced CD state in memory
+ * OUT:
+ * x0..x7: new byte-sliced CD state
+ */
+#define fls16(l, l0, l1, l2, l3, l4, l5, l6, l7, r, t0, t1, t2, t3, tt0, \
+ tt1, tt2, tt3, kll, klr, krl, krr) \
+ /* \
+ * t0 = kll; \
+ * t0 &= ll; \
+ * lr ^= rol32(t0, 1); \
+ */ \
+ vpxor tt0, tt0, tt0; \
+ vmovd kll, t0; \
+ vpshufb tt0, t0, t3; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t2; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t1; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t0; \
+ \
+ vpand l0, t0, t0; \
+ vpand l1, t1, t1; \
+ vpand l2, t2, t2; \
+ vpand l3, t3, t3; \
+ \
+ rol32_1_16(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
+ \
+ vpxor l4, t0, l4; \
+ vmovdqu l4, 4 * 16(l); \
+ vpxor l5, t1, l5; \
+ vmovdqu l5, 5 * 16(l); \
+ vpxor l6, t2, l6; \
+ vmovdqu l6, 6 * 16(l); \
+ vpxor l7, t3, l7; \
+ vmovdqu l7, 7 * 16(l); \
+ \
+ /* \
+ * t2 = krr; \
+ * t2 |= rr; \
+ * rl ^= t2; \
+ */ \
+ \
+ vmovd krr, t0; \
+ vpshufb tt0, t0, t3; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t2; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t1; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t0; \
+ \
+ vpor 4 * 16(r), t0, t0; \
+ vpor 5 * 16(r), t1, t1; \
+ vpor 6 * 16(r), t2, t2; \
+ vpor 7 * 16(r), t3, t3; \
+ \
+ vpxor 0 * 16(r), t0, t0; \
+ vpxor 1 * 16(r), t1, t1; \
+ vpxor 2 * 16(r), t2, t2; \
+ vpxor 3 * 16(r), t3, t3; \
+ vmovdqu t0, 0 * 16(r); \
+ vmovdqu t1, 1 * 16(r); \
+ vmovdqu t2, 2 * 16(r); \
+ vmovdqu t3, 3 * 16(r); \
+ \
+ /* \
+ * t2 = krl; \
+ * t2 &= rl; \
+ * rr ^= rol32(t2, 1); \
+ */ \
+ vmovd krl, t0; \
+ vpshufb tt0, t0, t3; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t2; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t1; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t0; \
+ \
+ vpand 0 * 16(r), t0, t0; \
+ vpand 1 * 16(r), t1, t1; \
+ vpand 2 * 16(r), t2, t2; \
+ vpand 3 * 16(r), t3, t3; \
+ \
+ rol32_1_16(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
+ \
+ vpxor 4 * 16(r), t0, t0; \
+ vpxor 5 * 16(r), t1, t1; \
+ vpxor 6 * 16(r), t2, t2; \
+ vpxor 7 * 16(r), t3, t3; \
+ vmovdqu t0, 4 * 16(r); \
+ vmovdqu t1, 5 * 16(r); \
+ vmovdqu t2, 6 * 16(r); \
+ vmovdqu t3, 7 * 16(r); \
+ \
+ /* \
+ * t0 = klr; \
+ * t0 |= lr; \
+ * ll ^= t0; \
+ */ \
+ \
+ vmovd klr, t0; \
+ vpshufb tt0, t0, t3; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t2; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t1; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t0; \
+ \
+ vpor l4, t0, t0; \
+ vpor l5, t1, t1; \
+ vpor l6, t2, t2; \
+ vpor l7, t3, t3; \
+ \
+ vpxor l0, t0, l0; \
+ vmovdqu l0, 0 * 16(l); \
+ vpxor l1, t1, l1; \
+ vmovdqu l1, 1 * 16(l); \
+ vpxor l2, t2, l2; \
+ vmovdqu l2, 2 * 16(l); \
+ vpxor l3, t3, l3; \
+ vmovdqu l3, 3 * 16(l);
+
+#define transpose_4x4(x0, x1, x2, x3, t1, t2) \
+ vpunpckhdq x1, x0, t2; \
+ vpunpckldq x1, x0, x0; \
+ \
+ vpunpckldq x3, x2, t1; \
+ vpunpckhdq x3, x2, x2; \
+ \
+ vpunpckhqdq t1, x0, x1; \
+ vpunpcklqdq t1, x0, x0; \
+ \
+ vpunpckhqdq x2, t2, x3; \
+ vpunpcklqdq x2, t2, x2;
+
+#define byteslice_16x16b_fast(a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, \
+ a3, b3, c3, d3, st0, st1) \
+ vmovdqu d2, st0; \
+ vmovdqu d3, st1; \
+ transpose_4x4(a0, a1, a2, a3, d2, d3); \
+ transpose_4x4(b0, b1, b2, b3, d2, d3); \
+ vmovdqu st0, d2; \
+ vmovdqu st1, d3; \
+ \
+ vmovdqu a0, st0; \
+ vmovdqu a1, st1; \
+ transpose_4x4(c0, c1, c2, c3, a0, a1); \
+ transpose_4x4(d0, d1, d2, d3, a0, a1); \
+ \
+ vmovdqu .Lshufb_16x16b rRIP, a0; \
+ vmovdqu st1, a1; \
+ vpshufb a0, a2, a2; \
+ vpshufb a0, a3, a3; \
+ vpshufb a0, b0, b0; \
+ vpshufb a0, b1, b1; \
+ vpshufb a0, b2, b2; \
+ vpshufb a0, b3, b3; \
+ vpshufb a0, a1, a1; \
+ vpshufb a0, c0, c0; \
+ vpshufb a0, c1, c1; \
+ vpshufb a0, c2, c2; \
+ vpshufb a0, c3, c3; \
+ vpshufb a0, d0, d0; \
+ vpshufb a0, d1, d1; \
+ vpshufb a0, d2, d2; \
+ vpshufb a0, d3, d3; \
+ vmovdqu d3, st1; \
+ vmovdqu st0, d3; \
+ vpshufb a0, d3, a0; \
+ vmovdqu d2, st0; \
+ \
+ transpose_4x4(a0, b0, c0, d0, d2, d3); \
+ transpose_4x4(a1, b1, c1, d1, d2, d3); \
+ vmovdqu st0, d2; \
+ vmovdqu st1, d3; \
+ \
+ vmovdqu b0, st0; \
+ vmovdqu b1, st1; \
+ transpose_4x4(a2, b2, c2, d2, b0, b1); \
+ transpose_4x4(a3, b3, c3, d3, b0, b1); \
+ vmovdqu st0, b0; \
+ vmovdqu st1, b1; \
+ /* does not adjust output bytes inside vectors */
+
+#define transpose_8x8b(a, b, c, d, e, f, g, h, t0, t1, t2, t3, t4) \
+ vpunpcklbw a, b, t0; \
+ vpunpckhbw a, b, b; \
+ \
+ vpunpcklbw c, d, t1; \
+ vpunpckhbw c, d, d; \
+ \
+ vpunpcklbw e, f, t2; \
+ vpunpckhbw e, f, f; \
+ \
+ vpunpcklbw g, h, t3; \
+ vpunpckhbw g, h, h; \
+ \
+ vpunpcklwd t0, t1, g; \
+ vpunpckhwd t0, t1, t0; \
+ \
+ vpunpcklwd b, d, t1; \
+ vpunpckhwd b, d, e; \
+ \
+ vpunpcklwd t2, t3, c; \
+ vpunpckhwd t2, t3, t2; \
+ \
+ vpunpcklwd f, h, t3; \
+ vpunpckhwd f, h, b; \
+ \
+ vpunpcklwd e, b, t4; \
+ vpunpckhwd e, b, b; \
+ \
+ vpunpcklwd t1, t3, e; \
+ vpunpckhwd t1, t3, f; \
+ \
+ vmovdqa .Ltranspose_8x8_shuf rRIP, t3; \
+ \
+ vpunpcklwd g, c, d; \
+ vpunpckhwd g, c, c; \
+ \
+ vpunpcklwd t0, t2, t1; \
+ vpunpckhwd t0, t2, h; \
+ \
+ vpunpckhqdq b, h, a; \
+ vpshufb t3, a, a; \
+ vpunpcklqdq b, h, b; \
+ vpshufb t3, b, b; \
+ \
+ vpunpckhqdq e, d, g; \
+ vpshufb t3, g, g; \
+ vpunpcklqdq e, d, h; \
+ vpshufb t3, h, h; \
+ \
+ vpunpckhqdq f, c, e; \
+ vpshufb t3, e, e; \
+ vpunpcklqdq f, c, f; \
+ vpshufb t3, f, f; \
+ \
+ vpunpckhqdq t4, t1, c; \
+ vpshufb t3, c, c; \
+ vpunpcklqdq t4, t1, d; \
+ vpshufb t3, d, d;
+
+/* load blocks to registers and apply pre-whitening */
+#define inpack16_pre(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, rio, key) \
+ vmovq key, x0; \
+ vpshufb .Lpack_bswap rRIP, x0, x0; \
+ \
+ vpxor 0 * 16(rio), x0, y7; \
+ vpxor 1 * 16(rio), x0, y6; \
+ vpxor 2 * 16(rio), x0, y5; \
+ vpxor 3 * 16(rio), x0, y4; \
+ vpxor 4 * 16(rio), x0, y3; \
+ vpxor 5 * 16(rio), x0, y2; \
+ vpxor 6 * 16(rio), x0, y1; \
+ vpxor 7 * 16(rio), x0, y0; \
+ vpxor 8 * 16(rio), x0, x7; \
+ vpxor 9 * 16(rio), x0, x6; \
+ vpxor 10 * 16(rio), x0, x5; \
+ vpxor 11 * 16(rio), x0, x4; \
+ vpxor 12 * 16(rio), x0, x3; \
+ vpxor 13 * 16(rio), x0, x2; \
+ vpxor 14 * 16(rio), x0, x1; \
+ vpxor 15 * 16(rio), x0, x0;
+
+/* byteslice pre-whitened blocks and store to temporary memory */
+#define inpack16_post(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd) \
+ byteslice_16x16b_fast(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, \
+ y4, y5, y6, y7, (mem_ab), (mem_cd)); \
+ \
+ vmovdqu x0, 0 * 16(mem_ab); \
+ vmovdqu x1, 1 * 16(mem_ab); \
+ vmovdqu x2, 2 * 16(mem_ab); \
+ vmovdqu x3, 3 * 16(mem_ab); \
+ vmovdqu x4, 4 * 16(mem_ab); \
+ vmovdqu x5, 5 * 16(mem_ab); \
+ vmovdqu x6, 6 * 16(mem_ab); \
+ vmovdqu x7, 7 * 16(mem_ab); \
+ vmovdqu y0, 0 * 16(mem_cd); \
+ vmovdqu y1, 1 * 16(mem_cd); \
+ vmovdqu y2, 2 * 16(mem_cd); \
+ vmovdqu y3, 3 * 16(mem_cd); \
+ vmovdqu y4, 4 * 16(mem_cd); \
+ vmovdqu y5, 5 * 16(mem_cd); \
+ vmovdqu y6, 6 * 16(mem_cd); \
+ vmovdqu y7, 7 * 16(mem_cd);
+
+/* de-byteslice, apply post-whitening and store blocks */
+#define outunpack16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, \
+ y5, y6, y7, key, stack_tmp0, stack_tmp1) \
+ byteslice_16x16b_fast(y0, y4, x0, x4, y1, y5, x1, x5, y2, y6, x2, x6, \
+ y3, y7, x3, x7, stack_tmp0, stack_tmp1); \
+ \
+ vmovdqu x0, stack_tmp0; \
+ \
+ vmovq key, x0; \
+ vpshufb .Lpack_bswap rRIP, x0, x0; \
+ \
+ vpxor x0, y7, y7; \
+ vpxor x0, y6, y6; \
+ vpxor x0, y5, y5; \
+ vpxor x0, y4, y4; \
+ vpxor x0, y3, y3; \
+ vpxor x0, y2, y2; \
+ vpxor x0, y1, y1; \
+ vpxor x0, y0, y0; \
+ vpxor x0, x7, x7; \
+ vpxor x0, x6, x6; \
+ vpxor x0, x5, x5; \
+ vpxor x0, x4, x4; \
+ vpxor x0, x3, x3; \
+ vpxor x0, x2, x2; \
+ vpxor x0, x1, x1; \
+ vpxor stack_tmp0, x0, x0;
+
+#define write_output(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, rio) \
+ vmovdqu x0, 0 * 16(rio); \
+ vmovdqu x1, 1 * 16(rio); \
+ vmovdqu x2, 2 * 16(rio); \
+ vmovdqu x3, 3 * 16(rio); \
+ vmovdqu x4, 4 * 16(rio); \
+ vmovdqu x5, 5 * 16(rio); \
+ vmovdqu x6, 6 * 16(rio); \
+ vmovdqu x7, 7 * 16(rio); \
+ vmovdqu y0, 8 * 16(rio); \
+ vmovdqu y1, 9 * 16(rio); \
+ vmovdqu y2, 10 * 16(rio); \
+ vmovdqu y3, 11 * 16(rio); \
+ vmovdqu y4, 12 * 16(rio); \
+ vmovdqu y5, 13 * 16(rio); \
+ vmovdqu y6, 14 * 16(rio); \
+ vmovdqu y7, 15 * 16(rio);
+
+.text
+.align 16
+
+#define SHUFB_BYTES(idx) \
+ 0 + (idx), 4 + (idx), 8 + (idx), 12 + (idx)
+
+.Lshufb_16x16b:
+ .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3);
+
+.Lpack_bswap:
+ .long 0x00010203
+ .long 0x04050607
+ .long 0x80808080
+ .long 0x80808080
+
+/* For CTR-mode IV byteswap */
+.Lbswap128_mask:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+/*
+ * pre-SubByte transform
+ *
+ * pre-lookup for sbox1, sbox2, sbox3:
+ * swap_bitendianness(
+ * isom_map_camellia_to_aes(
+ * camellia_f(
+ * swap_bitendianess(in)
+ * )
+ * )
+ * )
+ *
+ * (note: '⊕ 0xc5' inside camellia_f())
+ */
+.Lpre_tf_lo_s1:
+ .byte 0x45, 0xe8, 0x40, 0xed, 0x2e, 0x83, 0x2b, 0x86
+ .byte 0x4b, 0xe6, 0x4e, 0xe3, 0x20, 0x8d, 0x25, 0x88
+.Lpre_tf_hi_s1:
+ .byte 0x00, 0x51, 0xf1, 0xa0, 0x8a, 0xdb, 0x7b, 0x2a
+ .byte 0x09, 0x58, 0xf8, 0xa9, 0x83, 0xd2, 0x72, 0x23
+
+/*
+ * pre-SubByte transform
+ *
+ * pre-lookup for sbox4:
+ * swap_bitendianness(
+ * isom_map_camellia_to_aes(
+ * camellia_f(
+ * swap_bitendianess(in <<< 1)
+ * )
+ * )
+ * )
+ *
+ * (note: '⊕ 0xc5' inside camellia_f())
+ */
+.Lpre_tf_lo_s4:
+ .byte 0x45, 0x40, 0x2e, 0x2b, 0x4b, 0x4e, 0x20, 0x25
+ .byte 0x14, 0x11, 0x7f, 0x7a, 0x1a, 0x1f, 0x71, 0x74
+.Lpre_tf_hi_s4:
+ .byte 0x00, 0xf1, 0x8a, 0x7b, 0x09, 0xf8, 0x83, 0x72
+ .byte 0xad, 0x5c, 0x27, 0xd6, 0xa4, 0x55, 0x2e, 0xdf
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox1, sbox4:
+ * swap_bitendianness(
+ * camellia_h(
+ * isom_map_aes_to_camellia(
+ * swap_bitendianness(
+ * aes_inverse_affine_transform(in)
+ * )
+ * )
+ * )
+ * )
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s1:
+ .byte 0x3c, 0xcc, 0xcf, 0x3f, 0x32, 0xc2, 0xc1, 0x31
+ .byte 0xdc, 0x2c, 0x2f, 0xdf, 0xd2, 0x22, 0x21, 0xd1
+.Lpost_tf_hi_s1:
+ .byte 0x00, 0xf9, 0x86, 0x7f, 0xd7, 0x2e, 0x51, 0xa8
+ .byte 0xa4, 0x5d, 0x22, 0xdb, 0x73, 0x8a, 0xf5, 0x0c
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox2:
+ * swap_bitendianness(
+ * camellia_h(
+ * isom_map_aes_to_camellia(
+ * swap_bitendianness(
+ * aes_inverse_affine_transform(in)
+ * )
+ * )
+ * )
+ * ) <<< 1
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s2:
+ .byte 0x78, 0x99, 0x9f, 0x7e, 0x64, 0x85, 0x83, 0x62
+ .byte 0xb9, 0x58, 0x5e, 0xbf, 0xa5, 0x44, 0x42, 0xa3
+.Lpost_tf_hi_s2:
+ .byte 0x00, 0xf3, 0x0d, 0xfe, 0xaf, 0x5c, 0xa2, 0x51
+ .byte 0x49, 0xba, 0x44, 0xb7, 0xe6, 0x15, 0xeb, 0x18
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox3:
+ * swap_bitendianness(
+ * camellia_h(
+ * isom_map_aes_to_camellia(
+ * swap_bitendianness(
+ * aes_inverse_affine_transform(in)
+ * )
+ * )
+ * )
+ * ) >>> 1
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s3:
+ .byte 0x1e, 0x66, 0xe7, 0x9f, 0x19, 0x61, 0xe0, 0x98
+ .byte 0x6e, 0x16, 0x97, 0xef, 0x69, 0x11, 0x90, 0xe8
+.Lpost_tf_hi_s3:
+ .byte 0x00, 0xfc, 0x43, 0xbf, 0xeb, 0x17, 0xa8, 0x54
+ .byte 0x52, 0xae, 0x11, 0xed, 0xb9, 0x45, 0xfa, 0x06
+
+/* For isolating SubBytes from AESENCLAST, inverse shift row */
+.Linv_shift_row:
+ .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
+ .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
+
+/* shuffle mask for 8x8 byte transpose */
+.Ltranspose_8x8_shuf:
+ .byte 0, 1, 4, 5, 2, 3, 6, 7, 8+0, 8+1, 8+4, 8+5, 8+2, 8+3, 8+6, 8+7
+
+.align 4
+/* 4-bit mask */
+.L0f0f0f0f:
+ .long 0x0f0f0f0f
+
+
+.align 8
+ELF(.type __camellia_enc_blk16,@function;)
+
+__camellia_enc_blk16:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rax: temporary storage, 256 bytes
+ * %r8d: 24 for 16 byte key, 32 for larger
+ * %xmm0..%xmm15: 16 plaintext blocks
+ * output:
+ * %xmm0..%xmm15: 16 encrypted blocks, order swapped:
+ * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+ */
+ CFI_STARTPROC();
+
+ leaq 8 * 16(%rax), %rcx;
+
+ leaq (-8 * 8)(CTX, %r8, 8), %r8;
+
+ inpack16_post(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15, %rax, %rcx);
+
+.align 8
+.Lenc_loop:
+ enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15, %rax, %rcx, 0);
+
+ cmpq %r8, CTX;
+ je .Lenc_done;
+ leaq (8 * 8)(CTX), CTX;
+
+ fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15,
+ ((key_table) + 0)(CTX),
+ ((key_table) + 4)(CTX),
+ ((key_table) + 8)(CTX),
+ ((key_table) + 12)(CTX));
+ jmp .Lenc_loop;
+
+.align 8
+.Lenc_done:
+ /* load CD for output */
+ vmovdqu 0 * 16(%rcx), %xmm8;
+ vmovdqu 1 * 16(%rcx), %xmm9;
+ vmovdqu 2 * 16(%rcx), %xmm10;
+ vmovdqu 3 * 16(%rcx), %xmm11;
+ vmovdqu 4 * 16(%rcx), %xmm12;
+ vmovdqu 5 * 16(%rcx), %xmm13;
+ vmovdqu 6 * 16(%rcx), %xmm14;
+ vmovdqu 7 * 16(%rcx), %xmm15;
+
+ outunpack16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15, ((key_table) + 8 * 8)(%r8), (%rax), 1 * 16(%rax));
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __camellia_enc_blk16,.-__camellia_enc_blk16;)
+
+.align 8
+ELF(.type __camellia_dec_blk16,@function;)
+
+__camellia_dec_blk16:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rax: temporary storage, 256 bytes
+ * %r8d: 24 for 16 byte key, 32 for larger
+ * %xmm0..%xmm15: 16 encrypted blocks
+ * output:
+ * %xmm0..%xmm15: 16 plaintext blocks, order swapped:
+ * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+ */
+ CFI_STARTPROC();
+
+ movq %r8, %rcx;
+ movq CTX, %r8
+ leaq (-8 * 8)(CTX, %rcx, 8), CTX;
+
+ leaq 8 * 16(%rax), %rcx;
+
+ inpack16_post(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15, %rax, %rcx);
+
+.align 8
+.Ldec_loop:
+ dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15, %rax, %rcx, 0);
+
+ cmpq %r8, CTX;
+ je .Ldec_done;
+
+ fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15,
+ ((key_table) + 8)(CTX),
+ ((key_table) + 12)(CTX),
+ ((key_table) + 0)(CTX),
+ ((key_table) + 4)(CTX));
+
+ leaq (-8 * 8)(CTX), CTX;
+ jmp .Ldec_loop;
+
+.align 8
+.Ldec_done:
+ /* load CD for output */
+ vmovdqu 0 * 16(%rcx), %xmm8;
+ vmovdqu 1 * 16(%rcx), %xmm9;
+ vmovdqu 2 * 16(%rcx), %xmm10;
+ vmovdqu 3 * 16(%rcx), %xmm11;
+ vmovdqu 4 * 16(%rcx), %xmm12;
+ vmovdqu 5 * 16(%rcx), %xmm13;
+ vmovdqu 6 * 16(%rcx), %xmm14;
+ vmovdqu 7 * 16(%rcx), %xmm15;
+
+ outunpack16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax));
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __camellia_dec_blk16,.-__camellia_dec_blk16;)
+
+#define inc_le128(x, minus_one, tmp) \
+ vpcmpeqq minus_one, x, tmp; \
+ vpsubq minus_one, x, x; \
+ vpslldq $8, tmp, tmp; \
+ vpsubq tmp, x, x;
+
+.align 8
+.globl _gcry_camellia_aesni_avx_ctr_enc
+ELF(.type _gcry_camellia_aesni_avx_ctr_enc,@function;)
+
+_gcry_camellia_aesni_avx_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv (big endian, 128bit)
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %eax;
+ cmovel %eax, %r8d; /* max */
+
+ subq $(16 * 16), %rsp;
+ andq $~31, %rsp;
+ movq %rsp, %rax;
+
+ vmovdqa .Lbswap128_mask rRIP, %xmm14;
+
+ /* load IV and byteswap */
+ vmovdqu (%rcx), %xmm15;
+ vmovdqu %xmm15, 15 * 16(%rax);
+ vpshufb %xmm14, %xmm15, %xmm0; /* be => le */
+
+ vpcmpeqd %xmm15, %xmm15, %xmm15;
+ vpsrldq $8, %xmm15, %xmm15; /* low: -1, high: 0 */
+
+ /* construct IVs */
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm13;
+ vmovdqu %xmm13, 14 * 16(%rax);
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm13;
+ vmovdqu %xmm13, 13 * 16(%rax);
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm12;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm11;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm10;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm9;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm8;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm7;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm6;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm5;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm4;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm3;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm2;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vpshufb %xmm14, %xmm0, %xmm1;
+ inc_le128(%xmm0, %xmm15, %xmm13);
+ vmovdqa %xmm0, %xmm13;
+ vpshufb %xmm14, %xmm0, %xmm0;
+ inc_le128(%xmm13, %xmm15, %xmm14);
+ vpshufb .Lbswap128_mask rRIP, %xmm13, %xmm13; /* le => be */
+ vmovdqu %xmm13, (%rcx);
+
+ /* inpack16_pre: */
+ vmovq (key_table)(CTX), %xmm15;
+ vpshufb .Lpack_bswap rRIP, %xmm15, %xmm15;
+ vpxor %xmm0, %xmm15, %xmm0;
+ vpxor %xmm1, %xmm15, %xmm1;
+ vpxor %xmm2, %xmm15, %xmm2;
+ vpxor %xmm3, %xmm15, %xmm3;
+ vpxor %xmm4, %xmm15, %xmm4;
+ vpxor %xmm5, %xmm15, %xmm5;
+ vpxor %xmm6, %xmm15, %xmm6;
+ vpxor %xmm7, %xmm15, %xmm7;
+ vpxor %xmm8, %xmm15, %xmm8;
+ vpxor %xmm9, %xmm15, %xmm9;
+ vpxor %xmm10, %xmm15, %xmm10;
+ vpxor %xmm11, %xmm15, %xmm11;
+ vpxor %xmm12, %xmm15, %xmm12;
+ vpxor 13 * 16(%rax), %xmm15, %xmm13;
+ vpxor 14 * 16(%rax), %xmm15, %xmm14;
+ vpxor 15 * 16(%rax), %xmm15, %xmm15;
+
+ call __camellia_enc_blk16;
+
+ vpxor 0 * 16(%rdx), %xmm7, %xmm7;
+ vpxor 1 * 16(%rdx), %xmm6, %xmm6;
+ vpxor 2 * 16(%rdx), %xmm5, %xmm5;
+ vpxor 3 * 16(%rdx), %xmm4, %xmm4;
+ vpxor 4 * 16(%rdx), %xmm3, %xmm3;
+ vpxor 5 * 16(%rdx), %xmm2, %xmm2;
+ vpxor 6 * 16(%rdx), %xmm1, %xmm1;
+ vpxor 7 * 16(%rdx), %xmm0, %xmm0;
+ vpxor 8 * 16(%rdx), %xmm15, %xmm15;
+ vpxor 9 * 16(%rdx), %xmm14, %xmm14;
+ vpxor 10 * 16(%rdx), %xmm13, %xmm13;
+ vpxor 11 * 16(%rdx), %xmm12, %xmm12;
+ vpxor 12 * 16(%rdx), %xmm11, %xmm11;
+ vpxor 13 * 16(%rdx), %xmm10, %xmm10;
+ vpxor 14 * 16(%rdx), %xmm9, %xmm9;
+ vpxor 15 * 16(%rdx), %xmm8, %xmm8;
+
+ write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+ %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ %xmm8, %rsi);
+
+ vzeroall;
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx_ctr_enc,.-_gcry_camellia_aesni_avx_ctr_enc;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_cbc_dec
+ELF(.type _gcry_camellia_aesni_avx_cbc_dec,@function;)
+
+_gcry_camellia_aesni_avx_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ movq %rcx, %r9;
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %eax;
+ cmovel %eax, %r8d; /* max */
+
+ inpack16_pre(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ %xmm15, %rdx, (key_table)(CTX, %r8, 8));
+
+ subq $(16 * 16), %rsp;
+ andq $~31, %rsp;
+ movq %rsp, %rax;
+
+ call __camellia_dec_blk16;
+
+ /* XOR output with IV */
+ vpxor (%r9), %xmm7, %xmm7;
+ vpxor (0 * 16)(%rdx), %xmm6, %xmm6;
+ vpxor (1 * 16)(%rdx), %xmm5, %xmm5;
+ vpxor (2 * 16)(%rdx), %xmm4, %xmm4;
+ vpxor (3 * 16)(%rdx), %xmm3, %xmm3;
+ vpxor (4 * 16)(%rdx), %xmm2, %xmm2;
+ vpxor (5 * 16)(%rdx), %xmm1, %xmm1;
+ vpxor (6 * 16)(%rdx), %xmm0, %xmm0;
+ vpxor (7 * 16)(%rdx), %xmm15, %xmm15;
+ vpxor (8 * 16)(%rdx), %xmm14, %xmm14;
+ vpxor (9 * 16)(%rdx), %xmm13, %xmm13;
+ vpxor (10 * 16)(%rdx), %xmm12, %xmm12;
+ vpxor (11 * 16)(%rdx), %xmm11, %xmm11;
+ vpxor (12 * 16)(%rdx), %xmm10, %xmm10;
+ vpxor (13 * 16)(%rdx), %xmm9, %xmm9;
+ vpxor (14 * 16)(%rdx), %xmm8, %xmm8;
+ movq (15 * 16 + 0)(%rdx), %r10;
+ movq (15 * 16 + 8)(%rdx), %r11;
+
+ write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+ %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ %xmm8, %rsi);
+
+ /* store new IV */
+ movq %r10, (0)(%r9);
+ movq %r11, (8)(%r9);
+
+ vzeroall;
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx_cbc_dec,.-_gcry_camellia_aesni_avx_cbc_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_cfb_dec
+ELF(.type _gcry_camellia_aesni_avx_cfb_dec,@function;)
+
+_gcry_camellia_aesni_avx_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %eax;
+ cmovel %eax, %r8d; /* max */
+
+ subq $(16 * 16), %rsp;
+ andq $~31, %rsp;
+ movq %rsp, %rax;
+
+ /* inpack16_pre: */
+ vmovq (key_table)(CTX), %xmm0;
+ vpshufb .Lpack_bswap rRIP, %xmm0, %xmm0;
+ vpxor (%rcx), %xmm0, %xmm15;
+ vmovdqu 15 * 16(%rdx), %xmm1;
+ vmovdqu %xmm1, (%rcx); /* store new IV */
+ vpxor 0 * 16(%rdx), %xmm0, %xmm14;
+ vpxor 1 * 16(%rdx), %xmm0, %xmm13;
+ vpxor 2 * 16(%rdx), %xmm0, %xmm12;
+ vpxor 3 * 16(%rdx), %xmm0, %xmm11;
+ vpxor 4 * 16(%rdx), %xmm0, %xmm10;
+ vpxor 5 * 16(%rdx), %xmm0, %xmm9;
+ vpxor 6 * 16(%rdx), %xmm0, %xmm8;
+ vpxor 7 * 16(%rdx), %xmm0, %xmm7;
+ vpxor 8 * 16(%rdx), %xmm0, %xmm6;
+ vpxor 9 * 16(%rdx), %xmm0, %xmm5;
+ vpxor 10 * 16(%rdx), %xmm0, %xmm4;
+ vpxor 11 * 16(%rdx), %xmm0, %xmm3;
+ vpxor 12 * 16(%rdx), %xmm0, %xmm2;
+ vpxor 13 * 16(%rdx), %xmm0, %xmm1;
+ vpxor 14 * 16(%rdx), %xmm0, %xmm0;
+
+ call __camellia_enc_blk16;
+
+ vpxor 0 * 16(%rdx), %xmm7, %xmm7;
+ vpxor 1 * 16(%rdx), %xmm6, %xmm6;
+ vpxor 2 * 16(%rdx), %xmm5, %xmm5;
+ vpxor 3 * 16(%rdx), %xmm4, %xmm4;
+ vpxor 4 * 16(%rdx), %xmm3, %xmm3;
+ vpxor 5 * 16(%rdx), %xmm2, %xmm2;
+ vpxor 6 * 16(%rdx), %xmm1, %xmm1;
+ vpxor 7 * 16(%rdx), %xmm0, %xmm0;
+ vpxor 8 * 16(%rdx), %xmm15, %xmm15;
+ vpxor 9 * 16(%rdx), %xmm14, %xmm14;
+ vpxor 10 * 16(%rdx), %xmm13, %xmm13;
+ vpxor 11 * 16(%rdx), %xmm12, %xmm12;
+ vpxor 12 * 16(%rdx), %xmm11, %xmm11;
+ vpxor 13 * 16(%rdx), %xmm10, %xmm10;
+ vpxor 14 * 16(%rdx), %xmm9, %xmm9;
+ vpxor 15 * 16(%rdx), %xmm8, %xmm8;
+
+ write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+ %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ %xmm8, %rsi);
+
+ vzeroall;
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx_cfb_dec,.-_gcry_camellia_aesni_avx_cfb_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_ocb_enc
+ELF(.type _gcry_camellia_aesni_avx_ocb_enc,@function;)
+
+_gcry_camellia_aesni_avx_ocb_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ subq $(16 * 16 + 4 * 8), %rsp;
+ andq $~31, %rsp;
+ movq %rsp, %rax;
+
+ movq %r10, (16 * 16 + 0 * 8)(%rsp);
+ movq %r11, (16 * 16 + 1 * 8)(%rsp);
+ movq %r12, (16 * 16 + 2 * 8)(%rsp);
+ movq %r13, (16 * 16 + 3 * 8)(%rsp);
+ CFI_REG_ON_STACK(r10, 16 * 16 + 0 * 8);
+ CFI_REG_ON_STACK(r11, 16 * 16 + 1 * 8);
+ CFI_REG_ON_STACK(r12, 16 * 16 + 2 * 8);
+ CFI_REG_ON_STACK(r13, 16 * 16 + 3 * 8);
+
+ vmovdqu (%rcx), %xmm14;
+ vmovdqu (%r8), %xmm15;
+
+ /* 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) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ vmovdqu (n * 16)(%rdx), xreg; \
+ vpxor (lreg), %xmm14, %xmm14; \
+ vpxor xreg, %xmm15, %xmm15; \
+ vpxor xreg, %xmm14, xreg; \
+ vmovdqu %xmm14, (n * 16)(%rsi);
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %xmm0);
+ vmovdqu %xmm0, (15 * 16)(%rax);
+ OCB_INPUT(1, %r11, %xmm0);
+ vmovdqu %xmm0, (14 * 16)(%rax);
+ OCB_INPUT(2, %r12, %xmm13);
+ OCB_INPUT(3, %r13, %xmm12);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %xmm11);
+ OCB_INPUT(5, %r11, %xmm10);
+ OCB_INPUT(6, %r12, %xmm9);
+ OCB_INPUT(7, %r13, %xmm8);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(8, %r10, %xmm7);
+ OCB_INPUT(9, %r11, %xmm6);
+ OCB_INPUT(10, %r12, %xmm5);
+ OCB_INPUT(11, %r13, %xmm4);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(12, %r10, %xmm3);
+ OCB_INPUT(13, %r11, %xmm2);
+ OCB_INPUT(14, %r12, %xmm1);
+ OCB_INPUT(15, %r13, %xmm0);
+#undef OCB_INPUT
+
+ vmovdqu %xmm14, (%rcx);
+ vmovdqu %xmm15, (%r8);
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %r10d;
+ cmovel %r10d, %r8d; /* max */
+
+ /* inpack16_pre: */
+ vmovq (key_table)(CTX), %xmm15;
+ vpshufb .Lpack_bswap rRIP, %xmm15, %xmm15;
+ vpxor %xmm0, %xmm15, %xmm0;
+ vpxor %xmm1, %xmm15, %xmm1;
+ vpxor %xmm2, %xmm15, %xmm2;
+ vpxor %xmm3, %xmm15, %xmm3;
+ vpxor %xmm4, %xmm15, %xmm4;
+ vpxor %xmm5, %xmm15, %xmm5;
+ vpxor %xmm6, %xmm15, %xmm6;
+ vpxor %xmm7, %xmm15, %xmm7;
+ vpxor %xmm8, %xmm15, %xmm8;
+ vpxor %xmm9, %xmm15, %xmm9;
+ vpxor %xmm10, %xmm15, %xmm10;
+ vpxor %xmm11, %xmm15, %xmm11;
+ vpxor %xmm12, %xmm15, %xmm12;
+ vpxor %xmm13, %xmm15, %xmm13;
+ vpxor 14 * 16(%rax), %xmm15, %xmm14;
+ vpxor 15 * 16(%rax), %xmm15, %xmm15;
+
+ call __camellia_enc_blk16;
+
+ vpxor 0 * 16(%rsi), %xmm7, %xmm7;
+ vpxor 1 * 16(%rsi), %xmm6, %xmm6;
+ vpxor 2 * 16(%rsi), %xmm5, %xmm5;
+ vpxor 3 * 16(%rsi), %xmm4, %xmm4;
+ vpxor 4 * 16(%rsi), %xmm3, %xmm3;
+ vpxor 5 * 16(%rsi), %xmm2, %xmm2;
+ vpxor 6 * 16(%rsi), %xmm1, %xmm1;
+ vpxor 7 * 16(%rsi), %xmm0, %xmm0;
+ vpxor 8 * 16(%rsi), %xmm15, %xmm15;
+ vpxor 9 * 16(%rsi), %xmm14, %xmm14;
+ vpxor 10 * 16(%rsi), %xmm13, %xmm13;
+ vpxor 11 * 16(%rsi), %xmm12, %xmm12;
+ vpxor 12 * 16(%rsi), %xmm11, %xmm11;
+ vpxor 13 * 16(%rsi), %xmm10, %xmm10;
+ vpxor 14 * 16(%rsi), %xmm9, %xmm9;
+ vpxor 15 * 16(%rsi), %xmm8, %xmm8;
+
+ write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+ %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ %xmm8, %rsi);
+
+ vzeroall;
+
+ movq (16 * 16 + 0 * 8)(%rsp), %r10;
+ movq (16 * 16 + 1 * 8)(%rsp), %r11;
+ movq (16 * 16 + 2 * 8)(%rsp), %r12;
+ movq (16 * 16 + 3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx_ocb_enc,.-_gcry_camellia_aesni_avx_ocb_enc;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_ocb_dec
+ELF(.type _gcry_camellia_aesni_avx_ocb_dec,@function;)
+
+_gcry_camellia_aesni_avx_ocb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ subq $(16 * 16 + 4 * 8), %rsp;
+ andq $~31, %rsp;
+ movq %rsp, %rax;
+
+ movq %r10, (16 * 16 + 0 * 8)(%rsp);
+ movq %r11, (16 * 16 + 1 * 8)(%rsp);
+ movq %r12, (16 * 16 + 2 * 8)(%rsp);
+ movq %r13, (16 * 16 + 3 * 8)(%rsp);
+ CFI_REG_ON_STACK(r10, 16 * 16 + 0 * 8);
+ CFI_REG_ON_STACK(r11, 16 * 16 + 1 * 8);
+ CFI_REG_ON_STACK(r12, 16 * 16 + 2 * 8);
+ CFI_REG_ON_STACK(r13, 16 * 16 + 3 * 8);
+
+ vmovdqu (%rcx), %xmm15;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ vmovdqu (n * 16)(%rdx), xreg; \
+ vpxor (lreg), %xmm15, %xmm15; \
+ vpxor xreg, %xmm15, xreg; \
+ vmovdqu %xmm15, (n * 16)(%rsi);
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %xmm0);
+ vmovdqu %xmm0, (15 * 16)(%rax);
+ OCB_INPUT(1, %r11, %xmm14);
+ OCB_INPUT(2, %r12, %xmm13);
+ OCB_INPUT(3, %r13, %xmm12);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %xmm11);
+ OCB_INPUT(5, %r11, %xmm10);
+ OCB_INPUT(6, %r12, %xmm9);
+ OCB_INPUT(7, %r13, %xmm8);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(8, %r10, %xmm7);
+ OCB_INPUT(9, %r11, %xmm6);
+ OCB_INPUT(10, %r12, %xmm5);
+ OCB_INPUT(11, %r13, %xmm4);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(12, %r10, %xmm3);
+ OCB_INPUT(13, %r11, %xmm2);
+ OCB_INPUT(14, %r12, %xmm1);
+ OCB_INPUT(15, %r13, %xmm0);
+#undef OCB_INPUT
+
+ vmovdqu %xmm15, (%rcx);
+
+ movq %r8, %r10;
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %r9d;
+ cmovel %r9d, %r8d; /* max */
+
+ /* inpack16_pre: */
+ vmovq (key_table)(CTX, %r8, 8), %xmm15;
+ vpshufb .Lpack_bswap rRIP, %xmm15, %xmm15;
+ vpxor %xmm0, %xmm15, %xmm0;
+ vpxor %xmm1, %xmm15, %xmm1;
+ vpxor %xmm2, %xmm15, %xmm2;
+ vpxor %xmm3, %xmm15, %xmm3;
+ vpxor %xmm4, %xmm15, %xmm4;
+ vpxor %xmm5, %xmm15, %xmm5;
+ vpxor %xmm6, %xmm15, %xmm6;
+ vpxor %xmm7, %xmm15, %xmm7;
+ vpxor %xmm8, %xmm15, %xmm8;
+ vpxor %xmm9, %xmm15, %xmm9;
+ vpxor %xmm10, %xmm15, %xmm10;
+ vpxor %xmm11, %xmm15, %xmm11;
+ vpxor %xmm12, %xmm15, %xmm12;
+ vpxor %xmm13, %xmm15, %xmm13;
+ vpxor %xmm14, %xmm15, %xmm14;
+ vpxor 15 * 16(%rax), %xmm15, %xmm15;
+
+ call __camellia_dec_blk16;
+
+ vpxor 0 * 16(%rsi), %xmm7, %xmm7;
+ vpxor 1 * 16(%rsi), %xmm6, %xmm6;
+ vpxor 2 * 16(%rsi), %xmm5, %xmm5;
+ vpxor 3 * 16(%rsi), %xmm4, %xmm4;
+ vpxor 4 * 16(%rsi), %xmm3, %xmm3;
+ vpxor 5 * 16(%rsi), %xmm2, %xmm2;
+ vpxor 6 * 16(%rsi), %xmm1, %xmm1;
+ vpxor 7 * 16(%rsi), %xmm0, %xmm0;
+ vmovdqu %xmm7, (7 * 16)(%rax);
+ vpxor 8 * 16(%rsi), %xmm15, %xmm15;
+ vpxor 9 * 16(%rsi), %xmm14, %xmm14;
+ vpxor 10 * 16(%rsi), %xmm13, %xmm13;
+ vpxor 11 * 16(%rsi), %xmm12, %xmm12;
+ vpxor 12 * 16(%rsi), %xmm11, %xmm11;
+ vpxor 13 * 16(%rsi), %xmm10, %xmm10;
+ vpxor 14 * 16(%rsi), %xmm9, %xmm9;
+ vpxor 15 * 16(%rsi), %xmm8, %xmm8;
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+
+ vpxor (%r10), %xmm7, %xmm7;
+ vpxor %xmm6, %xmm7, %xmm7;
+ vpxor %xmm5, %xmm7, %xmm7;
+ vpxor %xmm4, %xmm7, %xmm7;
+ vpxor %xmm3, %xmm7, %xmm7;
+ vpxor %xmm2, %xmm7, %xmm7;
+ vpxor %xmm1, %xmm7, %xmm7;
+ vpxor %xmm0, %xmm7, %xmm7;
+ vpxor %xmm15, %xmm7, %xmm7;
+ vpxor %xmm14, %xmm7, %xmm7;
+ vpxor %xmm13, %xmm7, %xmm7;
+ vpxor %xmm12, %xmm7, %xmm7;
+ vpxor %xmm11, %xmm7, %xmm7;
+ vpxor %xmm10, %xmm7, %xmm7;
+ vpxor %xmm9, %xmm7, %xmm7;
+ vpxor %xmm8, %xmm7, %xmm7;
+ vmovdqu %xmm7, (%r10);
+ vmovdqu (7 * 16)(%rax), %xmm7;
+
+ write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+ %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ %xmm8, %rsi);
+
+ vzeroall;
+
+ movq (16 * 16 + 0 * 8)(%rsp), %r10;
+ movq (16 * 16 + 1 * 8)(%rsp), %r11;
+ movq (16 * 16 + 2 * 8)(%rsp), %r12;
+ movq (16 * 16 + 3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx_ocb_dec,.-_gcry_camellia_aesni_avx_ocb_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_ocb_auth
+ELF(.type _gcry_camellia_aesni_avx_ocb_auth,@function;)
+
+_gcry_camellia_aesni_avx_ocb_auth:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: abuf (16 blocks)
+ * %rdx: offset
+ * %rcx: checksum
+ * %r8 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ subq $(16 * 16 + 4 * 8), %rsp;
+ andq $~31, %rsp;
+ movq %rsp, %rax;
+
+ movq %r10, (16 * 16 + 0 * 8)(%rsp);
+ movq %r11, (16 * 16 + 1 * 8)(%rsp);
+ movq %r12, (16 * 16 + 2 * 8)(%rsp);
+ movq %r13, (16 * 16 + 3 * 8)(%rsp);
+ CFI_REG_ON_STACK(r10, 16 * 16 + 0 * 8);
+ CFI_REG_ON_STACK(r11, 16 * 16 + 1 * 8);
+ CFI_REG_ON_STACK(r12, 16 * 16 + 2 * 8);
+ CFI_REG_ON_STACK(r13, 16 * 16 + 3 * 8);
+
+ vmovdqu (%rdx), %xmm15;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ vmovdqu (n * 16)(%rsi), xreg; \
+ vpxor (lreg), %xmm15, %xmm15; \
+ vpxor xreg, %xmm15, xreg;
+
+ movq (0 * 8)(%r8), %r10;
+ movq (1 * 8)(%r8), %r11;
+ movq (2 * 8)(%r8), %r12;
+ movq (3 * 8)(%r8), %r13;
+ OCB_INPUT(0, %r10, %xmm0);
+ vmovdqu %xmm0, (15 * 16)(%rax);
+ OCB_INPUT(1, %r11, %xmm14);
+ OCB_INPUT(2, %r12, %xmm13);
+ OCB_INPUT(3, %r13, %xmm12);
+ movq (4 * 8)(%r8), %r10;
+ movq (5 * 8)(%r8), %r11;
+ movq (6 * 8)(%r8), %r12;
+ movq (7 * 8)(%r8), %r13;
+ OCB_INPUT(4, %r10, %xmm11);
+ OCB_INPUT(5, %r11, %xmm10);
+ OCB_INPUT(6, %r12, %xmm9);
+ OCB_INPUT(7, %r13, %xmm8);
+ movq (8 * 8)(%r8), %r10;
+ movq (9 * 8)(%r8), %r11;
+ movq (10 * 8)(%r8), %r12;
+ movq (11 * 8)(%r8), %r13;
+ OCB_INPUT(8, %r10, %xmm7);
+ OCB_INPUT(9, %r11, %xmm6);
+ OCB_INPUT(10, %r12, %xmm5);
+ OCB_INPUT(11, %r13, %xmm4);
+ movq (12 * 8)(%r8), %r10;
+ movq (13 * 8)(%r8), %r11;
+ movq (14 * 8)(%r8), %r12;
+ movq (15 * 8)(%r8), %r13;
+ OCB_INPUT(12, %r10, %xmm3);
+ OCB_INPUT(13, %r11, %xmm2);
+ OCB_INPUT(14, %r12, %xmm1);
+ OCB_INPUT(15, %r13, %xmm0);
+#undef OCB_INPUT
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %r10d;
+ cmovel %r10d, %r8d; /* max */
+
+ vmovdqu %xmm15, (%rdx);
+
+ movq %rcx, %r10;
+
+ /* inpack16_pre: */
+ vmovq (key_table)(CTX), %xmm15;
+ vpshufb .Lpack_bswap rRIP, %xmm15, %xmm15;
+ vpxor %xmm0, %xmm15, %xmm0;
+ vpxor %xmm1, %xmm15, %xmm1;
+ vpxor %xmm2, %xmm15, %xmm2;
+ vpxor %xmm3, %xmm15, %xmm3;
+ vpxor %xmm4, %xmm15, %xmm4;
+ vpxor %xmm5, %xmm15, %xmm5;
+ vpxor %xmm6, %xmm15, %xmm6;
+ vpxor %xmm7, %xmm15, %xmm7;
+ vpxor %xmm8, %xmm15, %xmm8;
+ vpxor %xmm9, %xmm15, %xmm9;
+ vpxor %xmm10, %xmm15, %xmm10;
+ vpxor %xmm11, %xmm15, %xmm11;
+ vpxor %xmm12, %xmm15, %xmm12;
+ vpxor %xmm13, %xmm15, %xmm13;
+ vpxor %xmm14, %xmm15, %xmm14;
+ vpxor 15 * 16(%rax), %xmm15, %xmm15;
+
+ call __camellia_enc_blk16;
+
+ vpxor %xmm7, %xmm6, %xmm6;
+ vpxor %xmm5, %xmm4, %xmm4;
+ vpxor %xmm3, %xmm2, %xmm2;
+ vpxor %xmm1, %xmm0, %xmm0;
+ vpxor %xmm15, %xmm14, %xmm14;
+ vpxor %xmm13, %xmm12, %xmm12;
+ vpxor %xmm11, %xmm10, %xmm10;
+ vpxor %xmm9, %xmm8, %xmm8;
+
+ vpxor %xmm6, %xmm4, %xmm4;
+ vpxor %xmm2, %xmm0, %xmm0;
+ vpxor %xmm14, %xmm12, %xmm12;
+ vpxor %xmm10, %xmm8, %xmm8;
+
+ vpxor %xmm4, %xmm0, %xmm0;
+ vpxor %xmm12, %xmm8, %xmm8;
+
+ vpxor %xmm0, %xmm8, %xmm0;
+ vpxor (%r10), %xmm0, %xmm0;
+ vmovdqu %xmm0, (%r10);
+
+ vzeroall;
+
+ movq (16 * 16 + 0 * 8)(%rsp), %r10;
+ movq (16 * 16 + 1 * 8)(%rsp), %r11;
+ movq (16 * 16 + 2 * 8)(%rsp), %r12;
+ movq (16 * 16 + 3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx_ocb_auth,.-_gcry_camellia_aesni_avx_ocb_auth;)
+
+/*
+ * IN:
+ * ab: 64-bit AB state
+ * cd: 64-bit CD state
+ */
+#define camellia_f(ab, x, t0, t1, t2, t3, t4, inv_shift_row, sbox4mask, \
+ _0f0f0f0fmask, pre_s1lo_mask, pre_s1hi_mask, key) \
+ vmovq key, t0; \
+ vpxor x, x, t3; \
+ \
+ vpxor ab, t0, x; \
+ \
+ /* \
+ * S-function with AES subbytes \
+ */ \
+ \
+ /* input rotation for sbox4 (<<< 1) */ \
+ vpand x, sbox4mask, t0; \
+ vpandn x, sbox4mask, x; \
+ vpaddw t0, t0, t1; \
+ vpsrlw $7, t0, t0; \
+ vpor t0, t1, t0; \
+ vpand sbox4mask, t0, t0; \
+ vpor t0, x, x; \
+ \
+ vmovdqa .Lpost_tf_lo_s1 rRIP, t0; \
+ vmovdqa .Lpost_tf_hi_s1 rRIP, t1; \
+ \
+ /* prefilter sboxes */ \
+ filter_8bit(x, pre_s1lo_mask, pre_s1hi_mask, _0f0f0f0fmask, t2); \
+ \
+ /* AES subbytes + AES shift rows + AES inv shift rows */ \
+ vaesenclast t3, x, x; \
+ \
+ /* postfilter sboxes */ \
+ filter_8bit(x, t0, t1, _0f0f0f0fmask, t2); \
+ \
+ /* output rotation for sbox2 (<<< 1) */ \
+ /* output rotation for sbox3 (>>> 1) */ \
+ vpshufb inv_shift_row, x, t1; \
+ vpshufb .Lsp0044440444044404mask rRIP, x, t4; \
+ vpshufb .Lsp1110111010011110mask rRIP, x, x; \
+ vpaddb t1, t1, t2; \
+ vpsrlw $7, t1, t0; \
+ vpsllw $7, t1, t3; \
+ vpor t0, t2, t0; \
+ vpsrlw $1, t1, t1; \
+ vpshufb .Lsp0222022222000222mask rRIP, t0, t0; \
+ vpor t1, t3, t1; \
+ \
+ vpxor x, t4, t4; \
+ vpshufb .Lsp3033303303303033mask rRIP, t1, t1; \
+ vpxor t4, t0, t0; \
+ vpxor t1, t0, t0; \
+ vpsrldq $8, t0, x; \
+ vpxor t0, x, x;
+
+#define vec_rol128(in, out, nrol, t0) \
+ vpshufd $0x4e, in, out; \
+ vpsllq $(nrol), in, t0; \
+ vpsrlq $(64-(nrol)), out, out; \
+ vpaddd t0, out, out;
+
+#define vec_ror128(in, out, nror, t0) \
+ vpshufd $0x4e, in, out; \
+ vpsrlq $(nror), in, t0; \
+ vpsllq $(64-(nror)), out, out; \
+ vpaddd t0, out, out;
+
+
+.align 16
+.Linv_shift_row_and_unpcklbw:
+ .byte 0x00, 0xff, 0x0d, 0xff, 0x0a, 0xff, 0x07, 0xff
+ .byte 0x04, 0xff, 0x01, 0xff, 0x0e, 0xff, 0x0b, 0xff
+.Lsp0044440444044404mask:
+ .long 0xffff0404, 0x0404ff04;
+ .long 0x0d0dff0d, 0x0d0dff0d;
+.Lsp1110111010011110mask:
+ .long 0x000000ff, 0x000000ff;
+ .long 0x0bffff0b, 0x0b0b0bff;
+.Lsp0222022222000222mask:
+ .long 0xff060606, 0xff060606;
+ .long 0x0c0cffff, 0xff0c0c0c;
+.Lsp3033303303303033mask:
+ .long 0x04ff0404, 0x04ff0404;
+ .long 0xff0a0aff, 0x0aff0a0a;
+.Lsbox4_input_mask:
+ .byte 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00;
+.Lsigma1:
+ .long 0x3BCC908B, 0xA09E667F;
+.Lsigma2:
+ .long 0x4CAA73B2, 0xB67AE858;
+.Lsigma3:
+ .long 0xE94F82BE, 0xC6EF372F;
+.Lsigma4:
+ .long 0xF1D36F1C, 0x54FF53A5;
+.Lsigma5:
+ .long 0xDE682D1D, 0x10E527FA;
+.Lsigma6:
+ .long 0xB3E6C1FD, 0xB05688C2;
+
+
+.align 8
+ELF(.type __camellia_avx_setup128,@function;)
+__camellia_avx_setup128:
+ /* input:
+ * %rdi: ctx, CTX; subkey storage at key_table(CTX)
+ * %xmm0: key
+ */
+ CFI_STARTPROC();
+
+#define cmll_sub(n, ctx) (key_table+((n)*8))(ctx)
+#define KL128 %xmm0
+#define KA128 %xmm2
+
+ vpshufb .Lbswap128_mask rRIP, KL128, KL128;
+
+ vmovdqa .Linv_shift_row_and_unpcklbw rRIP, %xmm11;
+ vmovq .Lsbox4_input_mask rRIP, %xmm12;
+ vbroadcastss .L0f0f0f0f rRIP, %xmm13;
+ vmovdqa .Lpre_tf_lo_s1 rRIP, %xmm14;
+ vmovdqa .Lpre_tf_hi_s1 rRIP, %xmm15;
+
+ /*
+ * Generate KA
+ */
+ vpsrldq $8, KL128, %xmm2;
+ vmovdqa KL128, %xmm3;
+ vpslldq $8, %xmm3, %xmm3;
+ vpsrldq $8, %xmm3, %xmm3;
+
+ camellia_f(%xmm2, %xmm4, %xmm1,
+ %xmm5, %xmm6, %xmm7, %xmm8,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma1 rRIP);
+ vpxor %xmm4, %xmm3, %xmm3;
+ camellia_f(%xmm3, %xmm2, %xmm1,
+ %xmm5, %xmm6, %xmm7, %xmm8,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma2 rRIP);
+ camellia_f(%xmm2, %xmm3, %xmm1,
+ %xmm5, %xmm6, %xmm7, %xmm8,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma3 rRIP);
+ vpxor %xmm4, %xmm3, %xmm3;
+ camellia_f(%xmm3, %xmm4, %xmm1,
+ %xmm5, %xmm6, %xmm7, %xmm8,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma4 rRIP);
+
+ vpslldq $8, %xmm3, %xmm3;
+ vpxor %xmm4, %xmm2, %xmm2;
+ vpsrldq $8, %xmm3, %xmm3;
+ vpslldq $8, %xmm2, KA128;
+ vpor %xmm3, KA128, KA128;
+
+ /*
+ * Generate subkeys
+ */
+ vmovdqu KA128, cmll_sub(24, CTX);
+ vec_rol128(KL128, %xmm3, 15, %xmm15);
+ vec_rol128(KA128, %xmm4, 15, %xmm15);
+ vec_rol128(KA128, %xmm5, 30, %xmm15);
+ vec_rol128(KL128, %xmm6, 45, %xmm15);
+ vec_rol128(KA128, %xmm7, 45, %xmm15);
+ vec_rol128(KL128, %xmm8, 60, %xmm15);
+ vec_rol128(KA128, %xmm9, 60, %xmm15);
+ vec_ror128(KL128, %xmm10, 128-77, %xmm15);
+
+ /* absorb kw2 to other subkeys */
+ vpslldq $8, KL128, %xmm15;
+ vpsrldq $8, %xmm15, %xmm15;
+ vpxor %xmm15, KA128, KA128;
+ vpxor %xmm15, %xmm3, %xmm3;
+ vpxor %xmm15, %xmm4, %xmm4;
+
+ /* subl(1) ^= subr(1) & ~subr(9); */
+ vpandn %xmm15, %xmm5, %xmm13;
+ vpslldq $12, %xmm13, %xmm13;
+ vpsrldq $8, %xmm13, %xmm13;
+ vpxor %xmm13, %xmm15, %xmm15;
+ /* dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm5, %xmm14;
+ vpslld $1, %xmm14, %xmm11;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm11, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpxor %xmm15, %xmm6, %xmm6;
+ vpxor %xmm15, %xmm8, %xmm8;
+ vpxor %xmm15, %xmm9, %xmm9;
+
+ /* subl(1) ^= subr(1) & ~subr(17); */
+ vpandn %xmm15, %xmm10, %xmm13;
+ vpslldq $12, %xmm13, %xmm13;
+ vpsrldq $8, %xmm13, %xmm13;
+ vpxor %xmm13, %xmm15, %xmm15;
+ /* dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm10, %xmm14;
+ vpslld $1, %xmm14, %xmm11;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm11, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpshufd $0x1b, KL128, KL128;
+ vpshufd $0x1b, KA128, KA128;
+ vpshufd $0x1b, %xmm3, %xmm3;
+ vpshufd $0x1b, %xmm4, %xmm4;
+ vpshufd $0x1b, %xmm5, %xmm5;
+ vpshufd $0x1b, %xmm6, %xmm6;
+ vpshufd $0x1b, %xmm7, %xmm7;
+ vpshufd $0x1b, %xmm8, %xmm8;
+ vpshufd $0x1b, %xmm9, %xmm9;
+ vpshufd $0x1b, %xmm10, %xmm10;
+
+ vmovdqu KL128, cmll_sub(0, CTX);
+ vpshufd $0x1b, KL128, KL128;
+ vmovdqu KA128, cmll_sub(2, CTX);
+ vmovdqu %xmm3, cmll_sub(4, CTX);
+ vmovdqu %xmm4, cmll_sub(6, CTX);
+ vmovdqu %xmm5, cmll_sub(8, CTX);
+ vmovdqu %xmm6, cmll_sub(10, CTX);
+ vpsrldq $8, %xmm8, %xmm8;
+ vmovq %xmm7, cmll_sub(12, CTX);
+ vmovq %xmm8, cmll_sub(13, CTX);
+ vmovdqu %xmm9, cmll_sub(14, CTX);
+ vmovdqu %xmm10, cmll_sub(16, CTX);
+
+ vmovdqu cmll_sub(24, CTX), KA128;
+
+ vec_ror128(KL128, %xmm3, 128 - 94, %xmm7);
+ vec_ror128(KA128, %xmm4, 128 - 94, %xmm7);
+ vec_ror128(KL128, %xmm5, 128 - 111, %xmm7);
+ vec_ror128(KA128, %xmm6, 128 - 111, %xmm7);
+
+ vpxor %xmm15, %xmm3, %xmm3;
+ vpxor %xmm15, %xmm4, %xmm4;
+ vpxor %xmm15, %xmm5, %xmm5;
+ vpslldq $8, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm6, %xmm6;
+
+ /* absorb kw4 to other subkeys */
+ vpslldq $8, %xmm6, %xmm15;
+ vpxor %xmm15, %xmm5, %xmm5;
+ vpxor %xmm15, %xmm4, %xmm4;
+ vpxor %xmm15, %xmm3, %xmm3;
+
+ /* subl(25) ^= subr(25) & ~subr(16); */
+ vpshufd $0x1b, cmll_sub(16, CTX), %xmm10;
+ vpandn %xmm15, %xmm10, %xmm13;
+ vpslldq $4, %xmm13, %xmm13;
+ vpxor %xmm13, %xmm15, %xmm15;
+ /* dw = subl(25) & subl(16), subr(25) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm10, %xmm14;
+ vpslld $1, %xmm14, %xmm11;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm11, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpshufd $0x1b, %xmm3, %xmm3;
+ vpshufd $0x1b, %xmm4, %xmm4;
+ vpshufd $0x1b, %xmm5, %xmm5;
+ vpshufd $0x1b, %xmm6, %xmm6;
+
+ vmovdqu %xmm3, cmll_sub(18, CTX);
+ vmovdqu %xmm4, cmll_sub(20, CTX);
+ vmovdqu %xmm5, cmll_sub(22, CTX);
+ vmovdqu %xmm6, cmll_sub(24, CTX);
+
+ vpshufd $0x1b, cmll_sub(14, CTX), %xmm3;
+ vpshufd $0x1b, cmll_sub(12, CTX), %xmm4;
+ vpshufd $0x1b, cmll_sub(10, CTX), %xmm5;
+ vpshufd $0x1b, cmll_sub(8, CTX), %xmm6;
+
+ vpxor %xmm15, %xmm3, %xmm3;
+ vpxor %xmm15, %xmm4, %xmm4;
+ vpxor %xmm15, %xmm5, %xmm5;
+
+ /* subl(25) ^= subr(25) & ~subr(8); */
+ vpandn %xmm15, %xmm6, %xmm13;
+ vpslldq $4, %xmm13, %xmm13;
+ vpxor %xmm13, %xmm15, %xmm15;
+ /* dw = subl(25) & subl(8), subr(25) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm6, %xmm14;
+ vpslld $1, %xmm14, %xmm11;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm11, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpshufd $0x1b, %xmm3, %xmm3;
+ vpshufd $0x1b, %xmm4, %xmm4;
+ vpshufd $0x1b, %xmm5, %xmm5;
+
+ vmovdqu %xmm3, cmll_sub(14, CTX);
+ vmovdqu %xmm4, cmll_sub(12, CTX);
+ vmovdqu %xmm5, cmll_sub(10, CTX);
+
+ vpshufd $0x1b, cmll_sub(6, CTX), %xmm6;
+ vpshufd $0x1b, cmll_sub(4, CTX), %xmm4;
+ vpshufd $0x1b, cmll_sub(2, CTX), %xmm2;
+ vpshufd $0x1b, cmll_sub(0, CTX), %xmm0;
+
+ vpxor %xmm15, %xmm6, %xmm6;
+ vpxor %xmm15, %xmm4, %xmm4;
+ vpxor %xmm15, %xmm2, %xmm2;
+ vpxor %xmm15, %xmm0, %xmm0;
+
+ vpshufd $0x1b, %xmm6, %xmm6;
+ vpshufd $0x1b, %xmm4, %xmm4;
+ vpshufd $0x1b, %xmm2, %xmm2;
+ vpshufd $0x1b, %xmm0, %xmm0;
+
+ vpsrldq $8, %xmm2, %xmm3;
+ vpsrldq $8, %xmm4, %xmm5;
+ vpsrldq $8, %xmm6, %xmm7;
+
+ /*
+ * key XOR is end of F-function.
+ */
+ vpxor %xmm2, %xmm0, %xmm0;
+ vpxor %xmm4, %xmm2, %xmm2;
+
+ vmovq %xmm0, cmll_sub(0, CTX);
+ vmovq %xmm3, cmll_sub(2, CTX);
+ vpxor %xmm5, %xmm3, %xmm3;
+ vpxor %xmm6, %xmm4, %xmm4;
+ vpxor %xmm7, %xmm5, %xmm5;
+ vmovq %xmm2, cmll_sub(3, CTX);
+ vmovq %xmm3, cmll_sub(4, CTX);
+ vmovq %xmm4, cmll_sub(5, CTX);
+ vmovq %xmm5, cmll_sub(6, CTX);
+
+ vmovq cmll_sub(7, CTX), %xmm7;
+ vmovq cmll_sub(8, CTX), %xmm8;
+ vmovq cmll_sub(9, CTX), %xmm9;
+ vmovq cmll_sub(10, CTX), %xmm10;
+ /* tl = subl(10) ^ (subr(10) & ~subr(8)); */
+ vpandn %xmm10, %xmm8, %xmm15;
+ vpsrldq $4, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm10, %xmm0;
+ /* dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm8, %xmm0, %xmm15;
+ vpslld $1, %xmm15, %xmm14;
+ vpsrld $31, %xmm15, %xmm15;
+ vpaddd %xmm14, %xmm15, %xmm15;
+ vpslldq $12, %xmm15, %xmm15;
+ vpsrldq $8, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm0, %xmm0;
+
+ vpxor %xmm0, %xmm6, %xmm6;
+ vmovq %xmm6, cmll_sub(7, CTX);
+
+ vmovq cmll_sub(11, CTX), %xmm11;
+ vmovq cmll_sub(12, CTX), %xmm12;
+ vmovq cmll_sub(13, CTX), %xmm13;
+ vmovq cmll_sub(14, CTX), %xmm14;
+ vmovq cmll_sub(15, CTX), %xmm15;
+ /* tl = subl(7) ^ (subr(7) & ~subr(9)); */
+ vpandn %xmm7, %xmm9, %xmm1;
+ vpsrldq $4, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm7, %xmm0;
+ /* dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm9, %xmm0, %xmm1;
+ vpslld $1, %xmm1, %xmm2;
+ vpsrld $31, %xmm1, %xmm1;
+ vpaddd %xmm2, %xmm1, %xmm1;
+ vpslldq $12, %xmm1, %xmm1;
+ vpsrldq $8, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm0, %xmm0;
+
+ vpxor %xmm11, %xmm0, %xmm0;
+ vpxor %xmm12, %xmm10, %xmm10;
+ vpxor %xmm13, %xmm11, %xmm11;
+ vpxor %xmm14, %xmm12, %xmm12;
+ vpxor %xmm15, %xmm13, %xmm13;
+ vmovq %xmm0, cmll_sub(10, CTX);
+ vmovq %xmm10, cmll_sub(11, CTX);
+ vmovq %xmm11, cmll_sub(12, CTX);
+ vmovq %xmm12, cmll_sub(13, CTX);
+ vmovq %xmm13, cmll_sub(14, CTX);
+
+ vmovq cmll_sub(16, CTX), %xmm6;
+ vmovq cmll_sub(17, CTX), %xmm7;
+ vmovq cmll_sub(18, CTX), %xmm8;
+ vmovq cmll_sub(19, CTX), %xmm9;
+ vmovq cmll_sub(20, CTX), %xmm10;
+ /* tl = subl(18) ^ (subr(18) & ~subr(16)); */
+ vpandn %xmm8, %xmm6, %xmm1;
+ vpsrldq $4, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm8, %xmm0;
+ /* dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm6, %xmm0, %xmm1;
+ vpslld $1, %xmm1, %xmm2;
+ vpsrld $31, %xmm1, %xmm1;
+ vpaddd %xmm2, %xmm1, %xmm1;
+ vpslldq $12, %xmm1, %xmm1;
+ vpsrldq $8, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm0, %xmm0;
+
+ vpxor %xmm14, %xmm0, %xmm0;
+ vmovq %xmm0, cmll_sub(15, CTX);
+
+ /* tl = subl(15) ^ (subr(15) & ~subr(17)); */
+ vpandn %xmm15, %xmm7, %xmm1;
+ vpsrldq $4, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm15, %xmm0;
+ /* dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm7, %xmm0, %xmm1;
+ vpslld $1, %xmm1, %xmm2;
+ vpsrld $31, %xmm1, %xmm1;
+ vpaddd %xmm2, %xmm1, %xmm1;
+ vpslldq $12, %xmm1, %xmm1;
+ vpsrldq $8, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm0, %xmm0;
+
+ vmovq cmll_sub(21, CTX), %xmm1;
+ vmovq cmll_sub(22, CTX), %xmm2;
+ vmovq cmll_sub(23, CTX), %xmm3;
+ vmovq cmll_sub(24, CTX), %xmm4;
+
+ vpxor %xmm9, %xmm0, %xmm0;
+ vpxor %xmm10, %xmm8, %xmm8;
+ vpxor %xmm1, %xmm9, %xmm9;
+ vpxor %xmm2, %xmm10, %xmm10;
+ vpxor %xmm3, %xmm1, %xmm1;
+ vpxor %xmm4, %xmm3, %xmm3;
+
+ vmovq %xmm0, cmll_sub(18, CTX);
+ vmovq %xmm8, cmll_sub(19, CTX);
+ vmovq %xmm9, cmll_sub(20, CTX);
+ vmovq %xmm10, cmll_sub(21, CTX);
+ vmovq %xmm1, cmll_sub(22, CTX);
+ vmovq %xmm2, cmll_sub(23, CTX);
+ vmovq %xmm3, cmll_sub(24, CTX);
+
+ /* kw2 and kw4 are unused now. */
+ movq $0, cmll_sub(1, CTX);
+ movq $0, cmll_sub(25, CTX);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __camellia_avx_setup128,.-__camellia_avx_setup128;)
+
+.align 8
+ELF(.type __camellia_avx_setup256,@function;)
+
+__camellia_avx_setup256:
+ /* input:
+ * %rdi: ctx, CTX; subkey storage at key_table(CTX)
+ * %xmm0 & %xmm1: key
+ */
+ CFI_STARTPROC();
+
+#define KL128 %xmm0
+#define KR128 %xmm1
+#define KA128 %xmm2
+#define KB128 %xmm3
+
+ vpshufb .Lbswap128_mask rRIP, KL128, KL128;
+ vpshufb .Lbswap128_mask rRIP, KR128, KR128;
+
+ vmovdqa .Linv_shift_row_and_unpcklbw rRIP, %xmm11;
+ vmovq .Lsbox4_input_mask rRIP, %xmm12;
+ vbroadcastss .L0f0f0f0f rRIP, %xmm13;
+ vmovdqa .Lpre_tf_lo_s1 rRIP, %xmm14;
+ vmovdqa .Lpre_tf_hi_s1 rRIP, %xmm15;
+
+ /*
+ * Generate KA
+ */
+ vpxor KL128, KR128, %xmm3;
+ vpsrldq $8, KR128, %xmm6;
+ vpsrldq $8, %xmm3, %xmm2;
+ vpslldq $8, %xmm3, %xmm3;
+ vpsrldq $8, %xmm3, %xmm3;
+
+ camellia_f(%xmm2, %xmm4, %xmm5,
+ %xmm7, %xmm8, %xmm9, %xmm10,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma1 rRIP);
+ vpxor %xmm4, %xmm3, %xmm3;
+ camellia_f(%xmm3, %xmm2, %xmm5,
+ %xmm7, %xmm8, %xmm9, %xmm10,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma2 rRIP);
+ vpxor %xmm6, %xmm2, %xmm2;
+ camellia_f(%xmm2, %xmm3, %xmm5,
+ %xmm7, %xmm8, %xmm9, %xmm10,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma3 rRIP);
+ vpxor %xmm4, %xmm3, %xmm3;
+ vpxor KR128, %xmm3, %xmm3;
+ camellia_f(%xmm3, %xmm4, %xmm5,
+ %xmm7, %xmm8, %xmm9, %xmm10,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma4 rRIP);
+
+ vpslldq $8, %xmm3, %xmm3;
+ vpxor %xmm4, %xmm2, %xmm2;
+ vpsrldq $8, %xmm3, %xmm3;
+ vpslldq $8, %xmm2, KA128;
+ vpor %xmm3, KA128, KA128;
+
+ /*
+ * Generate KB
+ */
+ vpxor KA128, KR128, %xmm3;
+ vpsrldq $8, %xmm3, %xmm4;
+ vpslldq $8, %xmm3, %xmm3;
+ vpsrldq $8, %xmm3, %xmm3;
+
+ camellia_f(%xmm4, %xmm5, %xmm6,
+ %xmm7, %xmm8, %xmm9, %xmm10,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma5 rRIP);
+ vpxor %xmm5, %xmm3, %xmm3;
+
+ camellia_f(%xmm3, %xmm5, %xmm6,
+ %xmm7, %xmm8, %xmm9, %xmm10,
+ %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma6 rRIP);
+ vpslldq $8, %xmm3, %xmm3;
+ vpxor %xmm5, %xmm4, %xmm4;
+ vpsrldq $8, %xmm3, %xmm3;
+ vpslldq $8, %xmm4, %xmm4;
+ vpor %xmm3, %xmm4, KB128;
+
+ /*
+ * Generate subkeys
+ */
+ vmovdqu KB128, cmll_sub(32, CTX);
+ vec_rol128(KR128, %xmm4, 15, %xmm15);
+ vec_rol128(KA128, %xmm5, 15, %xmm15);
+ vec_rol128(KR128, %xmm6, 30, %xmm15);
+ vec_rol128(KB128, %xmm7, 30, %xmm15);
+ vec_rol128(KL128, %xmm8, 45, %xmm15);
+ vec_rol128(KA128, %xmm9, 45, %xmm15);
+ vec_rol128(KL128, %xmm10, 60, %xmm15);
+ vec_rol128(KR128, %xmm11, 60, %xmm15);
+ vec_rol128(KB128, %xmm12, 60, %xmm15);
+
+ /* absorb kw2 to other subkeys */
+ vpslldq $8, KL128, %xmm15;
+ vpsrldq $8, %xmm15, %xmm15;
+ vpxor %xmm15, KB128, KB128;
+ vpxor %xmm15, %xmm4, %xmm4;
+ vpxor %xmm15, %xmm5, %xmm5;
+
+ /* subl(1) ^= subr(1) & ~subr(9); */
+ vpandn %xmm15, %xmm6, %xmm13;
+ vpslldq $12, %xmm13, %xmm13;
+ vpsrldq $8, %xmm13, %xmm13;
+ vpxor %xmm13, %xmm15, %xmm15;
+ /* dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm6, %xmm14;
+ vpslld $1, %xmm14, %xmm13;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm13, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpxor %xmm15, %xmm7, %xmm7;
+ vpxor %xmm15, %xmm8, %xmm8;
+ vpxor %xmm15, %xmm9, %xmm9;
+
+ vpshufd $0x1b, KL128, KL128;
+ vpshufd $0x1b, KB128, KB128;
+ vpshufd $0x1b, %xmm4, %xmm4;
+ vpshufd $0x1b, %xmm5, %xmm5;
+ vpshufd $0x1b, %xmm6, %xmm6;
+ vpshufd $0x1b, %xmm7, %xmm7;
+ vpshufd $0x1b, %xmm8, %xmm8;
+ vpshufd $0x1b, %xmm9, %xmm9;
+
+ vmovdqu KL128, cmll_sub(0, CTX);
+ vpshufd $0x1b, KL128, KL128;
+ vmovdqu KB128, cmll_sub(2, CTX);
+ vmovdqu %xmm4, cmll_sub(4, CTX);
+ vmovdqu %xmm5, cmll_sub(6, CTX);
+ vmovdqu %xmm6, cmll_sub(8, CTX);
+ vmovdqu %xmm7, cmll_sub(10, CTX);
+ vmovdqu %xmm8, cmll_sub(12, CTX);
+ vmovdqu %xmm9, cmll_sub(14, CTX);
+
+ vmovdqu cmll_sub(32, CTX), KB128;
+
+ /* subl(1) ^= subr(1) & ~subr(17); */
+ vpandn %xmm15, %xmm10, %xmm13;
+ vpslldq $12, %xmm13, %xmm13;
+ vpsrldq $8, %xmm13, %xmm13;
+ vpxor %xmm13, %xmm15, %xmm15;
+ /* dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm10, %xmm14;
+ vpslld $1, %xmm14, %xmm13;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm13, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpxor %xmm15, %xmm11, %xmm11;
+ vpxor %xmm15, %xmm12, %xmm12;
+
+ vec_ror128(KL128, %xmm4, 128-77, %xmm14);
+ vec_ror128(KA128, %xmm5, 128-77, %xmm14);
+ vec_ror128(KR128, %xmm6, 128-94, %xmm14);
+ vec_ror128(KA128, %xmm7, 128-94, %xmm14);
+ vec_ror128(KL128, %xmm8, 128-111, %xmm14);
+ vec_ror128(KB128, %xmm9, 128-111, %xmm14);
+
+ vpxor %xmm15, %xmm4, %xmm4;
+
+ vpshufd $0x1b, %xmm10, %xmm10;
+ vpshufd $0x1b, %xmm11, %xmm11;
+ vpshufd $0x1b, %xmm12, %xmm12;
+ vpshufd $0x1b, %xmm4, %xmm4;
+
+ vmovdqu %xmm10, cmll_sub(16, CTX);
+ vmovdqu %xmm11, cmll_sub(18, CTX);
+ vmovdqu %xmm12, cmll_sub(20, CTX);
+ vmovdqu %xmm4, cmll_sub(22, CTX);
+
+ /* subl(1) ^= subr(1) & ~subr(25); */
+ vpandn %xmm15, %xmm5, %xmm13;
+ vpslldq $12, %xmm13, %xmm13;
+ vpsrldq $8, %xmm13, %xmm13;
+ vpxor %xmm13, %xmm15, %xmm15;
+ /* dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm5, %xmm14;
+ vpslld $1, %xmm14, %xmm13;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm13, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpxor %xmm15, %xmm6, %xmm6;
+ vpxor %xmm15, %xmm7, %xmm7;
+ vpxor %xmm15, %xmm8, %xmm8;
+ vpslldq $8, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm9, %xmm9;
+
+ /* absorb kw4 to other subkeys */
+ vpslldq $8, %xmm9, %xmm15;
+ vpxor %xmm15, %xmm8, %xmm8;
+ vpxor %xmm15, %xmm7, %xmm7;
+ vpxor %xmm15, %xmm6, %xmm6;
+
+ /* subl(33) ^= subr(33) & ~subr(24); */
+ vpandn %xmm15, %xmm5, %xmm14;
+ vpslldq $4, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+ /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm5, %xmm14;
+ vpslld $1, %xmm14, %xmm13;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm13, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpshufd $0x1b, %xmm5, %xmm5;
+ vpshufd $0x1b, %xmm6, %xmm6;
+ vpshufd $0x1b, %xmm7, %xmm7;
+ vpshufd $0x1b, %xmm8, %xmm8;
+ vpshufd $0x1b, %xmm9, %xmm9;
+
+ vmovdqu %xmm5, cmll_sub(24, CTX);
+ vmovdqu %xmm6, cmll_sub(26, CTX);
+ vmovdqu %xmm7, cmll_sub(28, CTX);
+ vmovdqu %xmm8, cmll_sub(30, CTX);
+ vmovdqu %xmm9, cmll_sub(32, CTX);
+
+ vpshufd $0x1b, cmll_sub(22, CTX), %xmm0;
+ vpshufd $0x1b, cmll_sub(20, CTX), %xmm1;
+ vpshufd $0x1b, cmll_sub(18, CTX), %xmm2;
+ vpshufd $0x1b, cmll_sub(16, CTX), %xmm3;
+ vpshufd $0x1b, cmll_sub(14, CTX), %xmm4;
+ vpshufd $0x1b, cmll_sub(12, CTX), %xmm5;
+ vpshufd $0x1b, cmll_sub(10, CTX), %xmm6;
+ vpshufd $0x1b, cmll_sub(8, CTX), %xmm7;
+
+ vpxor %xmm15, %xmm0, %xmm0;
+ vpxor %xmm15, %xmm1, %xmm1;
+ vpxor %xmm15, %xmm2, %xmm2;
+
+ /* subl(33) ^= subr(33) & ~subr(24); */
+ vpandn %xmm15, %xmm3, %xmm14;
+ vpslldq $4, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+ /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm3, %xmm14;
+ vpslld $1, %xmm14, %xmm13;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm13, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpxor %xmm15, %xmm4, %xmm4;
+ vpxor %xmm15, %xmm5, %xmm5;
+ vpxor %xmm15, %xmm6, %xmm6;
+
+ vpshufd $0x1b, %xmm0, %xmm0;
+ vpshufd $0x1b, %xmm1, %xmm1;
+ vpshufd $0x1b, %xmm2, %xmm2;
+ vpshufd $0x1b, %xmm4, %xmm4;
+ vpshufd $0x1b, %xmm5, %xmm5;
+ vpshufd $0x1b, %xmm6, %xmm6;
+
+ vmovdqu %xmm0, cmll_sub(22, CTX);
+ vmovdqu %xmm1, cmll_sub(20, CTX);
+ vmovdqu %xmm2, cmll_sub(18, CTX);
+ vmovdqu %xmm4, cmll_sub(14, CTX);
+ vmovdqu %xmm5, cmll_sub(12, CTX);
+ vmovdqu %xmm6, cmll_sub(10, CTX);
+
+ vpshufd $0x1b, cmll_sub(6, CTX), %xmm6;
+ vpshufd $0x1b, cmll_sub(4, CTX), %xmm4;
+ vpshufd $0x1b, cmll_sub(2, CTX), %xmm2;
+ vpshufd $0x1b, cmll_sub(0, CTX), %xmm0;
+
+ /* subl(33) ^= subr(33) & ~subr(24); */
+ vpandn %xmm15, %xmm7, %xmm14;
+ vpslldq $4, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+ /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
+ vpand %xmm15, %xmm7, %xmm14;
+ vpslld $1, %xmm14, %xmm13;
+ vpsrld $31, %xmm14, %xmm14;
+ vpaddd %xmm13, %xmm14, %xmm14;
+ vpsrldq $12, %xmm14, %xmm14;
+ vpslldq $8, %xmm14, %xmm14;
+ vpxor %xmm14, %xmm15, %xmm15;
+
+ vpxor %xmm15, %xmm6, %xmm6;
+ vpxor %xmm15, %xmm4, %xmm4;
+ vpxor %xmm15, %xmm2, %xmm2;
+ vpxor %xmm15, %xmm0, %xmm0;
+
+ vpshufd $0x1b, %xmm6, %xmm6;
+ vpshufd $0x1b, %xmm4, %xmm4;
+ vpshufd $0x1b, %xmm2, %xmm2;
+ vpshufd $0x1b, %xmm0, %xmm0;
+
+ vpsrldq $8, %xmm2, %xmm3;
+ vpsrldq $8, %xmm4, %xmm5;
+ vpsrldq $8, %xmm6, %xmm7;
+
+ /*
+ * key XOR is end of F-function.
+ */
+ vpxor %xmm2, %xmm0, %xmm0;
+ vpxor %xmm4, %xmm2, %xmm2;
+
+ vmovq %xmm0, cmll_sub(0, CTX);
+ vmovq %xmm3, cmll_sub(2, CTX);
+ vpxor %xmm5, %xmm3, %xmm3;
+ vpxor %xmm6, %xmm4, %xmm4;
+ vpxor %xmm7, %xmm5, %xmm5;
+ vmovq %xmm2, cmll_sub(3, CTX);
+ vmovq %xmm3, cmll_sub(4, CTX);
+ vmovq %xmm4, cmll_sub(5, CTX);
+ vmovq %xmm5, cmll_sub(6, CTX);
+
+ vmovq cmll_sub(7, CTX), %xmm7;
+ vmovq cmll_sub(8, CTX), %xmm8;
+ vmovq cmll_sub(9, CTX), %xmm9;
+ vmovq cmll_sub(10, CTX), %xmm10;
+ /* tl = subl(10) ^ (subr(10) & ~subr(8)); */
+ vpandn %xmm10, %xmm8, %xmm15;
+ vpsrldq $4, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm10, %xmm0;
+ /* dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm8, %xmm0, %xmm15;
+ vpslld $1, %xmm15, %xmm14;
+ vpsrld $31, %xmm15, %xmm15;
+ vpaddd %xmm14, %xmm15, %xmm15;
+ vpslldq $12, %xmm15, %xmm15;
+ vpsrldq $8, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm0, %xmm0;
+
+ vpxor %xmm0, %xmm6, %xmm6;
+ vmovq %xmm6, cmll_sub(7, CTX);
+
+ vmovq cmll_sub(11, CTX), %xmm11;
+ vmovq cmll_sub(12, CTX), %xmm12;
+ vmovq cmll_sub(13, CTX), %xmm13;
+ vmovq cmll_sub(14, CTX), %xmm14;
+ vmovq cmll_sub(15, CTX), %xmm15;
+ /* tl = subl(7) ^ (subr(7) & ~subr(9)); */
+ vpandn %xmm7, %xmm9, %xmm1;
+ vpsrldq $4, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm7, %xmm0;
+ /* dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm9, %xmm0, %xmm1;
+ vpslld $1, %xmm1, %xmm2;
+ vpsrld $31, %xmm1, %xmm1;
+ vpaddd %xmm2, %xmm1, %xmm1;
+ vpslldq $12, %xmm1, %xmm1;
+ vpsrldq $8, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm0, %xmm0;
+
+ vpxor %xmm11, %xmm0, %xmm0;
+ vpxor %xmm12, %xmm10, %xmm10;
+ vpxor %xmm13, %xmm11, %xmm11;
+ vpxor %xmm14, %xmm12, %xmm12;
+ vpxor %xmm15, %xmm13, %xmm13;
+ vmovq %xmm0, cmll_sub(10, CTX);
+ vmovq %xmm10, cmll_sub(11, CTX);
+ vmovq %xmm11, cmll_sub(12, CTX);
+ vmovq %xmm12, cmll_sub(13, CTX);
+ vmovq %xmm13, cmll_sub(14, CTX);
+
+ vmovq cmll_sub(16, CTX), %xmm6;
+ vmovq cmll_sub(17, CTX), %xmm7;
+ vmovq cmll_sub(18, CTX), %xmm8;
+ vmovq cmll_sub(19, CTX), %xmm9;
+ vmovq cmll_sub(20, CTX), %xmm10;
+ /* tl = subl(18) ^ (subr(18) & ~subr(16)); */
+ vpandn %xmm8, %xmm6, %xmm1;
+ vpsrldq $4, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm8, %xmm0;
+ /* dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm6, %xmm0, %xmm1;
+ vpslld $1, %xmm1, %xmm2;
+ vpsrld $31, %xmm1, %xmm1;
+ vpaddd %xmm2, %xmm1, %xmm1;
+ vpslldq $12, %xmm1, %xmm1;
+ vpsrldq $8, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm0, %xmm0;
+
+ vpxor %xmm14, %xmm0, %xmm0;
+ vmovq %xmm0, cmll_sub(15, CTX);
+
+ /* tl = subl(15) ^ (subr(15) & ~subr(17)); */
+ vpandn %xmm15, %xmm7, %xmm1;
+ vpsrldq $4, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm15, %xmm0;
+ /* dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm7, %xmm0, %xmm1;
+ vpslld $1, %xmm1, %xmm2;
+ vpsrld $31, %xmm1, %xmm1;
+ vpaddd %xmm2, %xmm1, %xmm1;
+ vpslldq $12, %xmm1, %xmm1;
+ vpsrldq $8, %xmm1, %xmm1;
+ vpxor %xmm1, %xmm0, %xmm0;
+
+ vmovq cmll_sub(21, CTX), %xmm1;
+ vmovq cmll_sub(22, CTX), %xmm2;
+ vmovq cmll_sub(23, CTX), %xmm3;
+ vmovq cmll_sub(24, CTX), %xmm4;
+
+ vpxor %xmm9, %xmm0, %xmm0;
+ vpxor %xmm10, %xmm8, %xmm8;
+ vpxor %xmm1, %xmm9, %xmm9;
+ vpxor %xmm2, %xmm10, %xmm10;
+ vpxor %xmm3, %xmm1, %xmm1;
+
+ vmovq %xmm0, cmll_sub(18, CTX);
+ vmovq %xmm8, cmll_sub(19, CTX);
+ vmovq %xmm9, cmll_sub(20, CTX);
+ vmovq %xmm10, cmll_sub(21, CTX);
+ vmovq %xmm1, cmll_sub(22, CTX);
+
+ vmovq cmll_sub(25, CTX), %xmm5;
+ vmovq cmll_sub(26, CTX), %xmm6;
+ vmovq cmll_sub(27, CTX), %xmm7;
+ vmovq cmll_sub(28, CTX), %xmm8;
+ vmovq cmll_sub(29, CTX), %xmm9;
+ vmovq cmll_sub(30, CTX), %xmm10;
+ vmovq cmll_sub(31, CTX), %xmm11;
+ vmovq cmll_sub(32, CTX), %xmm12;
+
+ /* tl = subl(26) ^ (subr(26) & ~subr(24)); */
+ vpandn %xmm6, %xmm4, %xmm15;
+ vpsrldq $4, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm6, %xmm0;
+ /* dw = tl & subl(26), tr = subr(24) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm4, %xmm0, %xmm15;
+ vpslld $1, %xmm15, %xmm14;
+ vpsrld $31, %xmm15, %xmm15;
+ vpaddd %xmm14, %xmm15, %xmm15;
+ vpslldq $12, %xmm15, %xmm15;
+ vpsrldq $8, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm0, %xmm0;
+
+ vpxor %xmm0, %xmm2, %xmm2;
+ vmovq %xmm2, cmll_sub(23, CTX);
+
+ /* tl = subl(23) ^ (subr(23) & ~subr(25)); */
+ vpandn %xmm3, %xmm5, %xmm15;
+ vpsrldq $4, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm3, %xmm0;
+ /* dw = tl & subl(26), tr = subr(24) ^ CAMELLIA_RL1(dw); */
+ vpand %xmm5, %xmm0, %xmm15;
+ vpslld $1, %xmm15, %xmm14;
+ vpsrld $31, %xmm15, %xmm15;
+ vpaddd %xmm14, %xmm15, %xmm15;
+ vpslldq $12, %xmm15, %xmm15;
+ vpsrldq $8, %xmm15, %xmm15;
+ vpxor %xmm15, %xmm0, %xmm0;
+
+ vpxor %xmm7, %xmm0, %xmm0;
+ vpxor %xmm8, %xmm6, %xmm6;
+ vpxor %xmm9, %xmm7, %xmm7;
+ vpxor %xmm10, %xmm8, %xmm8;
+ vpxor %xmm11, %xmm9, %xmm9;
+ vpxor %xmm12, %xmm11, %xmm11;
+
+ vmovq %xmm0, cmll_sub(26, CTX);
+ vmovq %xmm6, cmll_sub(27, CTX);
+ vmovq %xmm7, cmll_sub(28, CTX);
+ vmovq %xmm8, cmll_sub(29, CTX);
+ vmovq %xmm9, cmll_sub(30, CTX);
+ vmovq %xmm10, cmll_sub(31, CTX);
+ vmovq %xmm11, cmll_sub(32, CTX);
+
+ /* kw2 and kw4 are unused now. */
+ movq $0, cmll_sub(1, CTX);
+ movq $0, cmll_sub(33, CTX);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __camellia_avx_setup256,.-__camellia_avx_setup256;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx_keygen
+ELF(.type _gcry_camellia_aesni_avx_keygen,@function;)
+
+_gcry_camellia_aesni_avx_keygen:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: key
+ * %rdx: keylen
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ vmovdqu (%rsi), %xmm0;
+ cmpl $24, %edx;
+ jb __camellia_avx_setup128;
+ je .Lprepare_key192;
+
+ vmovdqu 16(%rsi), %xmm1;
+ jmp __camellia_avx_setup256;
+
+.Lprepare_key192:
+ vpcmpeqd %xmm2, %xmm2, %xmm2;
+ vmovq 16(%rsi), %xmm1;
+
+ vpxor %xmm1, %xmm2, %xmm2;
+ vpslldq $8, %xmm2, %xmm2;
+ vpor %xmm2, %xmm1, %xmm1;
+
+ jmp __camellia_avx_setup256;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx_keygen,.-_gcry_camellia_aesni_avx_keygen;)
+
+#endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/camellia-aesni-avx2-amd64.S b/comm/third_party/libgcrypt/cipher/camellia-aesni-avx2-amd64.S
new file mode 100644
index 0000000000..f620f04036
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/camellia-aesni-avx2-amd64.S
@@ -0,0 +1,1782 @@
+/* camellia-avx2-aesni-amd64.S - AES-NI/AVX2 implementation of Camellia cipher
+ *
+ * Copyright (C) 2013-2015,2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#ifdef __x86_64
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
+
+#include "asm-common-amd64.h"
+
+#define CAMELLIA_TABLE_BYTE_LEN 272
+
+/* struct CAMELLIA_context: */
+#define key_table 0
+#define key_bitlength CAMELLIA_TABLE_BYTE_LEN
+
+/* register macros */
+#define CTX %rdi
+#define RIO %r8
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+#define filter_8bit(x, lo_t, hi_t, mask4bit, tmp0) \
+ vpand x, mask4bit, tmp0; \
+ vpandn x, mask4bit, x; \
+ vpsrld $4, x, x; \
+ \
+ vpshufb tmp0, lo_t, tmp0; \
+ vpshufb x, hi_t, x; \
+ vpxor tmp0, x, x;
+
+#define ymm0_x xmm0
+#define ymm1_x xmm1
+#define ymm2_x xmm2
+#define ymm3_x xmm3
+#define ymm4_x xmm4
+#define ymm5_x xmm5
+#define ymm6_x xmm6
+#define ymm7_x xmm7
+#define ymm8_x xmm8
+#define ymm9_x xmm9
+#define ymm10_x xmm10
+#define ymm11_x xmm11
+#define ymm12_x xmm12
+#define ymm13_x xmm13
+#define ymm14_x xmm14
+#define ymm15_x xmm15
+
+/**********************************************************************
+ 32-way camellia
+ **********************************************************************/
+
+/*
+ * IN:
+ * x0..x7: byte-sliced AB state
+ * mem_cd: register pointer storing CD state
+ * key: index for key material
+ * OUT:
+ * x0..x7: new byte-sliced CD state
+ */
+#define roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, t0, t1, t2, t3, t4, t5, t6, \
+ t7, mem_cd, key) \
+ /* \
+ * S-function with AES subbytes \
+ */ \
+ vbroadcasti128 .Linv_shift_row rRIP, t4; \
+ vpbroadcastd .L0f0f0f0f rRIP, t7; \
+ vbroadcasti128 .Lpre_tf_lo_s1 rRIP, t5; \
+ vbroadcasti128 .Lpre_tf_hi_s1 rRIP, t6; \
+ vbroadcasti128 .Lpre_tf_lo_s4 rRIP, t2; \
+ vbroadcasti128 .Lpre_tf_hi_s4 rRIP, t3; \
+ \
+ /* AES inverse shift rows */ \
+ vpshufb t4, x0, x0; \
+ vpshufb t4, x7, x7; \
+ vpshufb t4, x3, x3; \
+ vpshufb t4, x6, x6; \
+ vpshufb t4, x2, x2; \
+ vpshufb t4, x5, x5; \
+ vpshufb t4, x1, x1; \
+ vpshufb t4, x4, x4; \
+ \
+ /* prefilter sboxes 1, 2 and 3 */ \
+ /* prefilter sbox 4 */ \
+ filter_8bit(x0, t5, t6, t7, t4); \
+ filter_8bit(x7, t5, t6, t7, t4); \
+ vextracti128 $1, x0, t0##_x; \
+ vextracti128 $1, x7, t1##_x; \
+ filter_8bit(x3, t2, t3, t7, t4); \
+ filter_8bit(x6, t2, t3, t7, t4); \
+ vextracti128 $1, x3, t3##_x; \
+ vextracti128 $1, x6, t2##_x; \
+ filter_8bit(x2, t5, t6, t7, t4); \
+ filter_8bit(x5, t5, t6, t7, t4); \
+ filter_8bit(x1, t5, t6, t7, t4); \
+ filter_8bit(x4, t5, t6, t7, t4); \
+ \
+ vpxor t4##_x, t4##_x, t4##_x; \
+ \
+ /* AES subbytes + AES shift rows */ \
+ vextracti128 $1, x2, t6##_x; \
+ vextracti128 $1, x5, t5##_x; \
+ vaesenclast t4##_x, x0##_x, x0##_x; \
+ vaesenclast t4##_x, t0##_x, t0##_x; \
+ vaesenclast t4##_x, x7##_x, x7##_x; \
+ vaesenclast t4##_x, t1##_x, t1##_x; \
+ vaesenclast t4##_x, x3##_x, x3##_x; \
+ vaesenclast t4##_x, t3##_x, t3##_x; \
+ vaesenclast t4##_x, x6##_x, x6##_x; \
+ vaesenclast t4##_x, t2##_x, t2##_x; \
+ vinserti128 $1, t0##_x, x0, x0; \
+ vinserti128 $1, t1##_x, x7, x7; \
+ vinserti128 $1, t3##_x, x3, x3; \
+ vinserti128 $1, t2##_x, x6, x6; \
+ vextracti128 $1, x1, t3##_x; \
+ vextracti128 $1, x4, t2##_x; \
+ vbroadcasti128 .Lpost_tf_lo_s1 rRIP, t0; \
+ vbroadcasti128 .Lpost_tf_hi_s1 rRIP, t1; \
+ vaesenclast t4##_x, x2##_x, x2##_x; \
+ vaesenclast t4##_x, t6##_x, t6##_x; \
+ vaesenclast t4##_x, x5##_x, x5##_x; \
+ vaesenclast t4##_x, t5##_x, t5##_x; \
+ vaesenclast t4##_x, x1##_x, x1##_x; \
+ vaesenclast t4##_x, t3##_x, t3##_x; \
+ vaesenclast t4##_x, x4##_x, x4##_x; \
+ vaesenclast t4##_x, t2##_x, t2##_x; \
+ vinserti128 $1, t6##_x, x2, x2; \
+ vinserti128 $1, t5##_x, x5, x5; \
+ vinserti128 $1, t3##_x, x1, x1; \
+ vinserti128 $1, t2##_x, x4, x4; \
+ \
+ /* postfilter sboxes 1 and 4 */ \
+ vbroadcasti128 .Lpost_tf_lo_s3 rRIP, t2; \
+ vbroadcasti128 .Lpost_tf_hi_s3 rRIP, t3; \
+ filter_8bit(x0, t0, t1, t7, t4); \
+ filter_8bit(x7, t0, t1, t7, t4); \
+ filter_8bit(x3, t0, t1, t7, t6); \
+ filter_8bit(x6, t0, t1, t7, t6); \
+ \
+ /* postfilter sbox 3 */ \
+ vbroadcasti128 .Lpost_tf_lo_s2 rRIP, t4; \
+ vbroadcasti128 .Lpost_tf_hi_s2 rRIP, t5; \
+ filter_8bit(x2, t2, t3, t7, t6); \
+ filter_8bit(x5, t2, t3, t7, t6); \
+ \
+ vpbroadcastq key, t0; /* higher 64-bit duplicate ignored */ \
+ \
+ /* postfilter sbox 2 */ \
+ filter_8bit(x1, t4, t5, t7, t2); \
+ filter_8bit(x4, t4, t5, t7, t2); \
+ vpxor t7, t7, t7; \
+ \
+ vpsrldq $1, t0, t1; \
+ vpsrldq $2, t0, t2; \
+ vpshufb t7, t1, t1; \
+ vpsrldq $3, t0, t3; \
+ \
+ /* P-function */ \
+ vpxor x5, x0, x0; \
+ vpxor x6, x1, x1; \
+ vpxor x7, x2, x2; \
+ vpxor x4, x3, x3; \
+ \
+ vpshufb t7, t2, t2; \
+ vpsrldq $4, t0, t4; \
+ vpshufb t7, t3, t3; \
+ vpsrldq $5, t0, t5; \
+ vpshufb t7, t4, t4; \
+ \
+ vpxor x2, x4, x4; \
+ vpxor x3, x5, x5; \
+ vpxor x0, x6, x6; \
+ vpxor x1, x7, x7; \
+ \
+ vpsrldq $6, t0, t6; \
+ vpshufb t7, t5, t5; \
+ vpshufb t7, t6, t6; \
+ \
+ vpxor x7, x0, x0; \
+ vpxor x4, x1, x1; \
+ vpxor x5, x2, x2; \
+ vpxor x6, x3, x3; \
+ \
+ vpxor x3, x4, x4; \
+ vpxor x0, x5, x5; \
+ vpxor x1, x6, x6; \
+ vpxor x2, x7, x7; /* note: high and low parts swapped */ \
+ \
+ /* Add key material and result to CD (x becomes new CD) */ \
+ \
+ vpxor t6, x1, x1; \
+ vpxor 5 * 32(mem_cd), x1, x1; \
+ \
+ vpsrldq $7, t0, t6; \
+ vpshufb t7, t0, t0; \
+ vpshufb t7, t6, t7; \
+ \
+ vpxor t7, x0, x0; \
+ vpxor 4 * 32(mem_cd), x0, x0; \
+ \
+ vpxor t5, x2, x2; \
+ vpxor 6 * 32(mem_cd), x2, x2; \
+ \
+ vpxor t4, x3, x3; \
+ vpxor 7 * 32(mem_cd), x3, x3; \
+ \
+ vpxor t3, x4, x4; \
+ vpxor 0 * 32(mem_cd), x4, x4; \
+ \
+ vpxor t2, x5, x5; \
+ vpxor 1 * 32(mem_cd), x5, x5; \
+ \
+ vpxor t1, x6, x6; \
+ vpxor 2 * 32(mem_cd), x6, x6; \
+ \
+ vpxor t0, x7, x7; \
+ vpxor 3 * 32(mem_cd), x7, x7;
+
+/*
+ * IN/OUT:
+ * x0..x7: byte-sliced AB state preloaded
+ * mem_ab: byte-sliced AB state in memory
+ * mem_cb: byte-sliced CD state in memory
+ */
+#define two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, i, dir, store_ab) \
+ roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_cd, (key_table + (i) * 8)(CTX)); \
+ \
+ vmovdqu x0, 4 * 32(mem_cd); \
+ vmovdqu x1, 5 * 32(mem_cd); \
+ vmovdqu x2, 6 * 32(mem_cd); \
+ vmovdqu x3, 7 * 32(mem_cd); \
+ vmovdqu x4, 0 * 32(mem_cd); \
+ vmovdqu x5, 1 * 32(mem_cd); \
+ vmovdqu x6, 2 * 32(mem_cd); \
+ vmovdqu x7, 3 * 32(mem_cd); \
+ \
+ roundsm32(x4, x5, x6, x7, x0, x1, x2, x3, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, (key_table + ((i) + (dir)) * 8)(CTX)); \
+ \
+ store_ab(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab);
+
+#define dummy_store(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) /* do nothing */
+
+#define store_ab_state(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) \
+ /* Store new AB state */ \
+ vmovdqu x4, 4 * 32(mem_ab); \
+ vmovdqu x5, 5 * 32(mem_ab); \
+ vmovdqu x6, 6 * 32(mem_ab); \
+ vmovdqu x7, 7 * 32(mem_ab); \
+ vmovdqu x0, 0 * 32(mem_ab); \
+ vmovdqu x1, 1 * 32(mem_ab); \
+ vmovdqu x2, 2 * 32(mem_ab); \
+ vmovdqu x3, 3 * 32(mem_ab);
+
+#define enc_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, i) \
+ two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 2, 1, store_ab_state); \
+ two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 4, 1, store_ab_state); \
+ two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 6, 1, dummy_store);
+
+#define dec_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, i) \
+ two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 7, -1, store_ab_state); \
+ two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 5, -1, store_ab_state); \
+ two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd, (i) + 3, -1, dummy_store);
+
+/*
+ * IN:
+ * v0..3: byte-sliced 32-bit integers
+ * OUT:
+ * v0..3: (IN <<< 1)
+ */
+#define rol32_1_32(v0, v1, v2, v3, t0, t1, t2, zero) \
+ vpcmpgtb v0, zero, t0; \
+ vpaddb v0, v0, v0; \
+ vpabsb t0, t0; \
+ \
+ vpcmpgtb v1, zero, t1; \
+ vpaddb v1, v1, v1; \
+ vpabsb t1, t1; \
+ \
+ vpcmpgtb v2, zero, t2; \
+ vpaddb v2, v2, v2; \
+ vpabsb t2, t2; \
+ \
+ vpor t0, v1, v1; \
+ \
+ vpcmpgtb v3, zero, t0; \
+ vpaddb v3, v3, v3; \
+ vpabsb t0, t0; \
+ \
+ vpor t1, v2, v2; \
+ vpor t2, v3, v3; \
+ vpor t0, v0, v0;
+
+/*
+ * IN:
+ * r: byte-sliced AB state in memory
+ * l: byte-sliced CD state in memory
+ * OUT:
+ * x0..x7: new byte-sliced CD state
+ */
+#define fls32(l, l0, l1, l2, l3, l4, l5, l6, l7, r, t0, t1, t2, t3, tt0, \
+ tt1, tt2, tt3, kll, klr, krl, krr) \
+ /* \
+ * t0 = kll; \
+ * t0 &= ll; \
+ * lr ^= rol32(t0, 1); \
+ */ \
+ vpbroadcastd kll, t0; /* only lowest 32-bit used */ \
+ vpxor tt0, tt0, tt0; \
+ vpshufb tt0, t0, t3; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t2; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t1; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t0; \
+ \
+ vpand l0, t0, t0; \
+ vpand l1, t1, t1; \
+ vpand l2, t2, t2; \
+ vpand l3, t3, t3; \
+ \
+ rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
+ \
+ vpxor l4, t0, l4; \
+ vpbroadcastd krr, t0; /* only lowest 32-bit used */ \
+ vmovdqu l4, 4 * 32(l); \
+ vpxor l5, t1, l5; \
+ vmovdqu l5, 5 * 32(l); \
+ vpxor l6, t2, l6; \
+ vmovdqu l6, 6 * 32(l); \
+ vpxor l7, t3, l7; \
+ vmovdqu l7, 7 * 32(l); \
+ \
+ /* \
+ * t2 = krr; \
+ * t2 |= rr; \
+ * rl ^= t2; \
+ */ \
+ \
+ vpshufb tt0, t0, t3; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t2; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t1; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t0; \
+ \
+ vpor 4 * 32(r), t0, t0; \
+ vpor 5 * 32(r), t1, t1; \
+ vpor 6 * 32(r), t2, t2; \
+ vpor 7 * 32(r), t3, t3; \
+ \
+ vpxor 0 * 32(r), t0, t0; \
+ vpxor 1 * 32(r), t1, t1; \
+ vpxor 2 * 32(r), t2, t2; \
+ vpxor 3 * 32(r), t3, t3; \
+ vmovdqu t0, 0 * 32(r); \
+ vpbroadcastd krl, t0; /* only lowest 32-bit used */ \
+ vmovdqu t1, 1 * 32(r); \
+ vmovdqu t2, 2 * 32(r); \
+ vmovdqu t3, 3 * 32(r); \
+ \
+ /* \
+ * t2 = krl; \
+ * t2 &= rl; \
+ * rr ^= rol32(t2, 1); \
+ */ \
+ vpshufb tt0, t0, t3; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t2; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t1; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t0; \
+ \
+ vpand 0 * 32(r), t0, t0; \
+ vpand 1 * 32(r), t1, t1; \
+ vpand 2 * 32(r), t2, t2; \
+ vpand 3 * 32(r), t3, t3; \
+ \
+ rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
+ \
+ vpxor 4 * 32(r), t0, t0; \
+ vpxor 5 * 32(r), t1, t1; \
+ vpxor 6 * 32(r), t2, t2; \
+ vpxor 7 * 32(r), t3, t3; \
+ vmovdqu t0, 4 * 32(r); \
+ vpbroadcastd klr, t0; /* only lowest 32-bit used */ \
+ vmovdqu t1, 5 * 32(r); \
+ vmovdqu t2, 6 * 32(r); \
+ vmovdqu t3, 7 * 32(r); \
+ \
+ /* \
+ * t0 = klr; \
+ * t0 |= lr; \
+ * ll ^= t0; \
+ */ \
+ \
+ vpshufb tt0, t0, t3; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t2; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t1; \
+ vpsrldq $1, t0, t0; \
+ vpshufb tt0, t0, t0; \
+ \
+ vpor l4, t0, t0; \
+ vpor l5, t1, t1; \
+ vpor l6, t2, t2; \
+ vpor l7, t3, t3; \
+ \
+ vpxor l0, t0, l0; \
+ vmovdqu l0, 0 * 32(l); \
+ vpxor l1, t1, l1; \
+ vmovdqu l1, 1 * 32(l); \
+ vpxor l2, t2, l2; \
+ vmovdqu l2, 2 * 32(l); \
+ vpxor l3, t3, l3; \
+ vmovdqu l3, 3 * 32(l);
+
+#define transpose_4x4(x0, x1, x2, x3, t1, t2) \
+ vpunpckhdq x1, x0, t2; \
+ vpunpckldq x1, x0, x0; \
+ \
+ vpunpckldq x3, x2, t1; \
+ vpunpckhdq x3, x2, x2; \
+ \
+ vpunpckhqdq t1, x0, x1; \
+ vpunpcklqdq t1, x0, x0; \
+ \
+ vpunpckhqdq x2, t2, x3; \
+ vpunpcklqdq x2, t2, x2;
+
+#define byteslice_16x16b_fast(a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, \
+ a3, b3, c3, d3, st0, st1) \
+ vmovdqu d2, st0; \
+ vmovdqu d3, st1; \
+ transpose_4x4(a0, a1, a2, a3, d2, d3); \
+ transpose_4x4(b0, b1, b2, b3, d2, d3); \
+ vmovdqu st0, d2; \
+ vmovdqu st1, d3; \
+ \
+ vmovdqu a0, st0; \
+ vmovdqu a1, st1; \
+ transpose_4x4(c0, c1, c2, c3, a0, a1); \
+ transpose_4x4(d0, d1, d2, d3, a0, a1); \
+ \
+ vbroadcasti128 .Lshufb_16x16b rRIP, a0; \
+ vmovdqu st1, a1; \
+ vpshufb a0, a2, a2; \
+ vpshufb a0, a3, a3; \
+ vpshufb a0, b0, b0; \
+ vpshufb a0, b1, b1; \
+ vpshufb a0, b2, b2; \
+ vpshufb a0, b3, b3; \
+ vpshufb a0, a1, a1; \
+ vpshufb a0, c0, c0; \
+ vpshufb a0, c1, c1; \
+ vpshufb a0, c2, c2; \
+ vpshufb a0, c3, c3; \
+ vpshufb a0, d0, d0; \
+ vpshufb a0, d1, d1; \
+ vpshufb a0, d2, d2; \
+ vpshufb a0, d3, d3; \
+ vmovdqu d3, st1; \
+ vmovdqu st0, d3; \
+ vpshufb a0, d3, a0; \
+ vmovdqu d2, st0; \
+ \
+ transpose_4x4(a0, b0, c0, d0, d2, d3); \
+ transpose_4x4(a1, b1, c1, d1, d2, d3); \
+ vmovdqu st0, d2; \
+ vmovdqu st1, d3; \
+ \
+ vmovdqu b0, st0; \
+ vmovdqu b1, st1; \
+ transpose_4x4(a2, b2, c2, d2, b0, b1); \
+ transpose_4x4(a3, b3, c3, d3, b0, b1); \
+ vmovdqu st0, b0; \
+ vmovdqu st1, b1; \
+ /* does not adjust output bytes inside vectors */
+
+/* load blocks to registers and apply pre-whitening */
+#define inpack32_pre(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, rio, key) \
+ vpbroadcastq key, x0; \
+ vpshufb .Lpack_bswap rRIP, x0, x0; \
+ \
+ vpxor 0 * 32(rio), x0, y7; \
+ vpxor 1 * 32(rio), x0, y6; \
+ vpxor 2 * 32(rio), x0, y5; \
+ vpxor 3 * 32(rio), x0, y4; \
+ vpxor 4 * 32(rio), x0, y3; \
+ vpxor 5 * 32(rio), x0, y2; \
+ vpxor 6 * 32(rio), x0, y1; \
+ vpxor 7 * 32(rio), x0, y0; \
+ vpxor 8 * 32(rio), x0, x7; \
+ vpxor 9 * 32(rio), x0, x6; \
+ vpxor 10 * 32(rio), x0, x5; \
+ vpxor 11 * 32(rio), x0, x4; \
+ vpxor 12 * 32(rio), x0, x3; \
+ vpxor 13 * 32(rio), x0, x2; \
+ vpxor 14 * 32(rio), x0, x1; \
+ vpxor 15 * 32(rio), x0, x0;
+
+/* byteslice pre-whitened blocks and store to temporary memory */
+#define inpack32_post(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, mem_ab, mem_cd) \
+ byteslice_16x16b_fast(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, \
+ y4, y5, y6, y7, (mem_ab), (mem_cd)); \
+ \
+ vmovdqu x0, 0 * 32(mem_ab); \
+ vmovdqu x1, 1 * 32(mem_ab); \
+ vmovdqu x2, 2 * 32(mem_ab); \
+ vmovdqu x3, 3 * 32(mem_ab); \
+ vmovdqu x4, 4 * 32(mem_ab); \
+ vmovdqu x5, 5 * 32(mem_ab); \
+ vmovdqu x6, 6 * 32(mem_ab); \
+ vmovdqu x7, 7 * 32(mem_ab); \
+ vmovdqu y0, 0 * 32(mem_cd); \
+ vmovdqu y1, 1 * 32(mem_cd); \
+ vmovdqu y2, 2 * 32(mem_cd); \
+ vmovdqu y3, 3 * 32(mem_cd); \
+ vmovdqu y4, 4 * 32(mem_cd); \
+ vmovdqu y5, 5 * 32(mem_cd); \
+ vmovdqu y6, 6 * 32(mem_cd); \
+ vmovdqu y7, 7 * 32(mem_cd);
+
+/* de-byteslice, apply post-whitening and store blocks */
+#define outunpack32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, \
+ y5, y6, y7, key, stack_tmp0, stack_tmp1) \
+ byteslice_16x16b_fast(y0, y4, x0, x4, y1, y5, x1, x5, y2, y6, x2, x6, \
+ y3, y7, x3, x7, stack_tmp0, stack_tmp1); \
+ \
+ vmovdqu x0, stack_tmp0; \
+ \
+ vpbroadcastq key, x0; \
+ vpshufb .Lpack_bswap rRIP, x0, x0; \
+ \
+ vpxor x0, y7, y7; \
+ vpxor x0, y6, y6; \
+ vpxor x0, y5, y5; \
+ vpxor x0, y4, y4; \
+ vpxor x0, y3, y3; \
+ vpxor x0, y2, y2; \
+ vpxor x0, y1, y1; \
+ vpxor x0, y0, y0; \
+ vpxor x0, x7, x7; \
+ vpxor x0, x6, x6; \
+ vpxor x0, x5, x5; \
+ vpxor x0, x4, x4; \
+ vpxor x0, x3, x3; \
+ vpxor x0, x2, x2; \
+ vpxor x0, x1, x1; \
+ vpxor stack_tmp0, x0, x0;
+
+#define write_output(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+ y6, y7, rio) \
+ vmovdqu x0, 0 * 32(rio); \
+ vmovdqu x1, 1 * 32(rio); \
+ vmovdqu x2, 2 * 32(rio); \
+ vmovdqu x3, 3 * 32(rio); \
+ vmovdqu x4, 4 * 32(rio); \
+ vmovdqu x5, 5 * 32(rio); \
+ vmovdqu x6, 6 * 32(rio); \
+ vmovdqu x7, 7 * 32(rio); \
+ vmovdqu y0, 8 * 32(rio); \
+ vmovdqu y1, 9 * 32(rio); \
+ vmovdqu y2, 10 * 32(rio); \
+ vmovdqu y3, 11 * 32(rio); \
+ vmovdqu y4, 12 * 32(rio); \
+ vmovdqu y5, 13 * 32(rio); \
+ vmovdqu y6, 14 * 32(rio); \
+ vmovdqu y7, 15 * 32(rio);
+
+.text
+.align 32
+
+#define SHUFB_BYTES(idx) \
+ 0 + (idx), 4 + (idx), 8 + (idx), 12 + (idx)
+
+.Lshufb_16x16b:
+ .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3)
+ .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3)
+
+.Lpack_bswap:
+ .long 0x00010203, 0x04050607, 0x80808080, 0x80808080
+ .long 0x00010203, 0x04050607, 0x80808080, 0x80808080
+
+/* For CTR-mode IV byteswap */
+.Lbswap128_mask:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+/*
+ * pre-SubByte transform
+ *
+ * pre-lookup for sbox1, sbox2, sbox3:
+ * swap_bitendianness(
+ * isom_map_camellia_to_aes(
+ * camellia_f(
+ * swap_bitendianess(in)
+ * )
+ * )
+ * )
+ *
+ * (note: '⊕ 0xc5' inside camellia_f())
+ */
+.Lpre_tf_lo_s1:
+ .byte 0x45, 0xe8, 0x40, 0xed, 0x2e, 0x83, 0x2b, 0x86
+ .byte 0x4b, 0xe6, 0x4e, 0xe3, 0x20, 0x8d, 0x25, 0x88
+.Lpre_tf_hi_s1:
+ .byte 0x00, 0x51, 0xf1, 0xa0, 0x8a, 0xdb, 0x7b, 0x2a
+ .byte 0x09, 0x58, 0xf8, 0xa9, 0x83, 0xd2, 0x72, 0x23
+
+/*
+ * pre-SubByte transform
+ *
+ * pre-lookup for sbox4:
+ * swap_bitendianness(
+ * isom_map_camellia_to_aes(
+ * camellia_f(
+ * swap_bitendianess(in <<< 1)
+ * )
+ * )
+ * )
+ *
+ * (note: '⊕ 0xc5' inside camellia_f())
+ */
+.Lpre_tf_lo_s4:
+ .byte 0x45, 0x40, 0x2e, 0x2b, 0x4b, 0x4e, 0x20, 0x25
+ .byte 0x14, 0x11, 0x7f, 0x7a, 0x1a, 0x1f, 0x71, 0x74
+.Lpre_tf_hi_s4:
+ .byte 0x00, 0xf1, 0x8a, 0x7b, 0x09, 0xf8, 0x83, 0x72
+ .byte 0xad, 0x5c, 0x27, 0xd6, 0xa4, 0x55, 0x2e, 0xdf
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox1, sbox4:
+ * swap_bitendianness(
+ * camellia_h(
+ * isom_map_aes_to_camellia(
+ * swap_bitendianness(
+ * aes_inverse_affine_transform(in)
+ * )
+ * )
+ * )
+ * )
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s1:
+ .byte 0x3c, 0xcc, 0xcf, 0x3f, 0x32, 0xc2, 0xc1, 0x31
+ .byte 0xdc, 0x2c, 0x2f, 0xdf, 0xd2, 0x22, 0x21, 0xd1
+.Lpost_tf_hi_s1:
+ .byte 0x00, 0xf9, 0x86, 0x7f, 0xd7, 0x2e, 0x51, 0xa8
+ .byte 0xa4, 0x5d, 0x22, 0xdb, 0x73, 0x8a, 0xf5, 0x0c
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox2:
+ * swap_bitendianness(
+ * camellia_h(
+ * isom_map_aes_to_camellia(
+ * swap_bitendianness(
+ * aes_inverse_affine_transform(in)
+ * )
+ * )
+ * )
+ * ) <<< 1
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s2:
+ .byte 0x78, 0x99, 0x9f, 0x7e, 0x64, 0x85, 0x83, 0x62
+ .byte 0xb9, 0x58, 0x5e, 0xbf, 0xa5, 0x44, 0x42, 0xa3
+.Lpost_tf_hi_s2:
+ .byte 0x00, 0xf3, 0x0d, 0xfe, 0xaf, 0x5c, 0xa2, 0x51
+ .byte 0x49, 0xba, 0x44, 0xb7, 0xe6, 0x15, 0xeb, 0x18
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox3:
+ * swap_bitendianness(
+ * camellia_h(
+ * isom_map_aes_to_camellia(
+ * swap_bitendianness(
+ * aes_inverse_affine_transform(in)
+ * )
+ * )
+ * )
+ * ) >>> 1
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s3:
+ .byte 0x1e, 0x66, 0xe7, 0x9f, 0x19, 0x61, 0xe0, 0x98
+ .byte 0x6e, 0x16, 0x97, 0xef, 0x69, 0x11, 0x90, 0xe8
+.Lpost_tf_hi_s3:
+ .byte 0x00, 0xfc, 0x43, 0xbf, 0xeb, 0x17, 0xa8, 0x54
+ .byte 0x52, 0xae, 0x11, 0xed, 0xb9, 0x45, 0xfa, 0x06
+
+/* For isolating SubBytes from AESENCLAST, inverse shift row */
+.Linv_shift_row:
+ .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
+ .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
+
+.align 4
+/* 4-bit mask */
+.L0f0f0f0f:
+ .long 0x0f0f0f0f
+
+
+.align 8
+ELF(.type __camellia_enc_blk32,@function;)
+
+__camellia_enc_blk32:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rax: temporary storage, 512 bytes
+ * %r8d: 24 for 16 byte key, 32 for larger
+ * %ymm0..%ymm15: 32 plaintext blocks
+ * output:
+ * %ymm0..%ymm15: 32 encrypted blocks, order swapped:
+ * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+ */
+ CFI_STARTPROC();
+
+ leaq 8 * 32(%rax), %rcx;
+
+ leaq (-8 * 8)(CTX, %r8, 8), %r8;
+
+ inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15, %rax, %rcx);
+
+.align 8
+.Lenc_loop:
+ enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15, %rax, %rcx, 0);
+
+ cmpq %r8, CTX;
+ je .Lenc_done;
+ leaq (8 * 8)(CTX), CTX;
+
+ fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15,
+ ((key_table) + 0)(CTX),
+ ((key_table) + 4)(CTX),
+ ((key_table) + 8)(CTX),
+ ((key_table) + 12)(CTX));
+ jmp .Lenc_loop;
+
+.align 8
+.Lenc_done:
+ /* load CD for output */
+ vmovdqu 0 * 32(%rcx), %ymm8;
+ vmovdqu 1 * 32(%rcx), %ymm9;
+ vmovdqu 2 * 32(%rcx), %ymm10;
+ vmovdqu 3 * 32(%rcx), %ymm11;
+ vmovdqu 4 * 32(%rcx), %ymm12;
+ vmovdqu 5 * 32(%rcx), %ymm13;
+ vmovdqu 6 * 32(%rcx), %ymm14;
+ vmovdqu 7 * 32(%rcx), %ymm15;
+
+ outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15, ((key_table) + 8 * 8)(%r8), (%rax), 1 * 32(%rax));
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __camellia_enc_blk32,.-__camellia_enc_blk32;)
+
+.align 8
+ELF(.type __camellia_dec_blk32,@function;)
+
+__camellia_dec_blk32:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rax: temporary storage, 512 bytes
+ * %r8d: 24 for 16 byte key, 32 for larger
+ * %ymm0..%ymm15: 16 encrypted blocks
+ * output:
+ * %ymm0..%ymm15: 16 plaintext blocks, order swapped:
+ * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+ */
+ CFI_STARTPROC();
+
+ movq %r8, %rcx;
+ movq CTX, %r8
+ leaq (-8 * 8)(CTX, %rcx, 8), CTX;
+
+ leaq 8 * 32(%rax), %rcx;
+
+ inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15, %rax, %rcx);
+
+.align 8
+.Ldec_loop:
+ dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15, %rax, %rcx, 0);
+
+ cmpq %r8, CTX;
+ je .Ldec_done;
+
+ fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15,
+ ((key_table) + 8)(CTX),
+ ((key_table) + 12)(CTX),
+ ((key_table) + 0)(CTX),
+ ((key_table) + 4)(CTX));
+
+ leaq (-8 * 8)(CTX), CTX;
+ jmp .Ldec_loop;
+
+.align 8
+.Ldec_done:
+ /* load CD for output */
+ vmovdqu 0 * 32(%rcx), %ymm8;
+ vmovdqu 1 * 32(%rcx), %ymm9;
+ vmovdqu 2 * 32(%rcx), %ymm10;
+ vmovdqu 3 * 32(%rcx), %ymm11;
+ vmovdqu 4 * 32(%rcx), %ymm12;
+ vmovdqu 5 * 32(%rcx), %ymm13;
+ vmovdqu 6 * 32(%rcx), %ymm14;
+ vmovdqu 7 * 32(%rcx), %ymm15;
+
+ outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax));
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __camellia_dec_blk32,.-__camellia_dec_blk32;)
+
+#define inc_le128(x, minus_one, tmp) \
+ vpcmpeqq minus_one, x, tmp; \
+ vpsubq minus_one, x, x; \
+ vpslldq $8, tmp, tmp; \
+ vpsubq tmp, x, x;
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_ctr_enc
+ELF(.type _gcry_camellia_aesni_avx2_ctr_enc,@function;)
+
+_gcry_camellia_aesni_avx2_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+ * %rdx: src (32 blocks)
+ * %rcx: iv (big endian, 128bit)
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ movq 8(%rcx), %r11;
+ bswapq %r11;
+
+ vzeroupper;
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %eax;
+ cmovel %eax, %r8d; /* max */
+
+ subq $(16 * 32), %rsp;
+ andq $~63, %rsp;
+ movq %rsp, %rax;
+
+ vpcmpeqd %ymm15, %ymm15, %ymm15;
+ vpsrldq $8, %ymm15, %ymm15; /* ab: -1:0 ; cd: -1:0 */
+
+ /* load IV and byteswap */
+ vmovdqu (%rcx), %xmm0;
+ vpshufb .Lbswap128_mask rRIP, %xmm0, %xmm0;
+ vmovdqa %xmm0, %xmm1;
+ inc_le128(%xmm0, %xmm15, %xmm14);
+ vbroadcasti128 .Lbswap128_mask rRIP, %ymm14;
+ vinserti128 $1, %xmm0, %ymm1, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm13;
+ vmovdqu %ymm13, 15 * 32(%rax);
+
+ /* check need for handling 64-bit overflow and carry */
+ cmpq $(0xffffffffffffffff - 32), %r11;
+ ja .Lload_ctr_carry;
+
+ /* construct IVs */
+ vpaddq %ymm15, %ymm15, %ymm15; /* ab: -2:0 ; cd: -2:0 */
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm13;
+ vmovdqu %ymm13, 14 * 32(%rax);
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm13;
+ vmovdqu %ymm13, 13 * 32(%rax);
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm12;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm11;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm10;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm9;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm8;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm7;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm6;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm5;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm4;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm3;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm2;
+ vpsubq %ymm15, %ymm0, %ymm0;
+ vpshufb %ymm14, %ymm0, %ymm1;
+ vpsubq %ymm15, %ymm0, %ymm0; /* +30 ; +31 */
+ vpsubq %xmm15, %xmm0, %xmm13; /* +32 */
+ vpshufb %ymm14, %ymm0, %ymm0;
+ vpshufb %xmm14, %xmm13, %xmm13;
+ vmovdqu %xmm13, (%rcx);
+
+ jmp .Lload_ctr_done;
+
+.align 4
+.Lload_ctr_carry:
+ /* construct IVs */
+ inc_le128(%ymm0, %ymm15, %ymm13); /* ab: le1 ; cd: le2 */
+ inc_le128(%ymm0, %ymm15, %ymm13); /* ab: le2 ; cd: le3 */
+ vpshufb %ymm14, %ymm0, %ymm13;
+ vmovdqu %ymm13, 14 * 32(%rax);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm13;
+ vmovdqu %ymm13, 13 * 32(%rax);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm12;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm11;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm10;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm9;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm8;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm7;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm6;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm5;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm4;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm3;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm2;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vpshufb %ymm14, %ymm0, %ymm1;
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ inc_le128(%ymm0, %ymm15, %ymm13);
+ vextracti128 $1, %ymm0, %xmm13;
+ vpshufb %ymm14, %ymm0, %ymm0;
+ inc_le128(%xmm13, %xmm15, %xmm14);
+ vpshufb .Lbswap128_mask rRIP, %xmm13, %xmm13;
+ vmovdqu %xmm13, (%rcx);
+
+.align 4
+.Lload_ctr_done:
+ /* inpack16_pre: */
+ vpbroadcastq (key_table)(CTX), %ymm15;
+ vpshufb .Lpack_bswap rRIP, %ymm15, %ymm15;
+ vpxor %ymm0, %ymm15, %ymm0;
+ vpxor %ymm1, %ymm15, %ymm1;
+ vpxor %ymm2, %ymm15, %ymm2;
+ vpxor %ymm3, %ymm15, %ymm3;
+ vpxor %ymm4, %ymm15, %ymm4;
+ vpxor %ymm5, %ymm15, %ymm5;
+ vpxor %ymm6, %ymm15, %ymm6;
+ vpxor %ymm7, %ymm15, %ymm7;
+ vpxor %ymm8, %ymm15, %ymm8;
+ vpxor %ymm9, %ymm15, %ymm9;
+ vpxor %ymm10, %ymm15, %ymm10;
+ vpxor %ymm11, %ymm15, %ymm11;
+ vpxor %ymm12, %ymm15, %ymm12;
+ vpxor 13 * 32(%rax), %ymm15, %ymm13;
+ vpxor 14 * 32(%rax), %ymm15, %ymm14;
+ vpxor 15 * 32(%rax), %ymm15, %ymm15;
+
+ call __camellia_enc_blk32;
+
+ vpxor 0 * 32(%rdx), %ymm7, %ymm7;
+ vpxor 1 * 32(%rdx), %ymm6, %ymm6;
+ vpxor 2 * 32(%rdx), %ymm5, %ymm5;
+ vpxor 3 * 32(%rdx), %ymm4, %ymm4;
+ vpxor 4 * 32(%rdx), %ymm3, %ymm3;
+ vpxor 5 * 32(%rdx), %ymm2, %ymm2;
+ vpxor 6 * 32(%rdx), %ymm1, %ymm1;
+ vpxor 7 * 32(%rdx), %ymm0, %ymm0;
+ vpxor 8 * 32(%rdx), %ymm15, %ymm15;
+ vpxor 9 * 32(%rdx), %ymm14, %ymm14;
+ vpxor 10 * 32(%rdx), %ymm13, %ymm13;
+ vpxor 11 * 32(%rdx), %ymm12, %ymm12;
+ vpxor 12 * 32(%rdx), %ymm11, %ymm11;
+ vpxor 13 * 32(%rdx), %ymm10, %ymm10;
+ vpxor 14 * 32(%rdx), %ymm9, %ymm9;
+ vpxor 15 * 32(%rdx), %ymm8, %ymm8;
+ leaq 32 * 16(%rdx), %rdx;
+
+ write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+ %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+ %ymm8, %rsi);
+
+ vzeroall;
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx2_ctr_enc,.-_gcry_camellia_aesni_avx2_ctr_enc;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_cbc_dec
+ELF(.type _gcry_camellia_aesni_avx2_cbc_dec,@function;)
+
+_gcry_camellia_aesni_avx2_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+ * %rdx: src (32 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ movq %rcx, %r9;
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %eax;
+ cmovel %eax, %r8d; /* max */
+
+ subq $(16 * 32), %rsp;
+ andq $~63, %rsp;
+ movq %rsp, %rax;
+
+ inpack32_pre(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ %ymm15, %rdx, (key_table)(CTX, %r8, 8));
+
+ call __camellia_dec_blk32;
+
+ /* XOR output with IV */
+ vmovdqu %ymm8, (%rax);
+ vmovdqu (%r9), %xmm8;
+ vinserti128 $1, (%rdx), %ymm8, %ymm8;
+ vpxor %ymm8, %ymm7, %ymm7;
+ vmovdqu (%rax), %ymm8;
+ vpxor (0 * 32 + 16)(%rdx), %ymm6, %ymm6;
+ vpxor (1 * 32 + 16)(%rdx), %ymm5, %ymm5;
+ vpxor (2 * 32 + 16)(%rdx), %ymm4, %ymm4;
+ vpxor (3 * 32 + 16)(%rdx), %ymm3, %ymm3;
+ vpxor (4 * 32 + 16)(%rdx), %ymm2, %ymm2;
+ vpxor (5 * 32 + 16)(%rdx), %ymm1, %ymm1;
+ vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm0;
+ vpxor (7 * 32 + 16)(%rdx), %ymm15, %ymm15;
+ vpxor (8 * 32 + 16)(%rdx), %ymm14, %ymm14;
+ vpxor (9 * 32 + 16)(%rdx), %ymm13, %ymm13;
+ vpxor (10 * 32 + 16)(%rdx), %ymm12, %ymm12;
+ vpxor (11 * 32 + 16)(%rdx), %ymm11, %ymm11;
+ vpxor (12 * 32 + 16)(%rdx), %ymm10, %ymm10;
+ vpxor (13 * 32 + 16)(%rdx), %ymm9, %ymm9;
+ vpxor (14 * 32 + 16)(%rdx), %ymm8, %ymm8;
+ movq (15 * 32 + 16 + 0)(%rdx), %rax;
+ movq (15 * 32 + 16 + 8)(%rdx), %rcx;
+
+ write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+ %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+ %ymm8, %rsi);
+
+ /* store new IV */
+ movq %rax, (0)(%r9);
+ movq %rcx, (8)(%r9);
+
+ vzeroall;
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx2_cbc_dec,.-_gcry_camellia_aesni_avx2_cbc_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_cfb_dec
+ELF(.type _gcry_camellia_aesni_avx2_cfb_dec,@function;)
+
+_gcry_camellia_aesni_avx2_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+ * %rdx: src (32 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %eax;
+ cmovel %eax, %r8d; /* max */
+
+ subq $(16 * 32), %rsp;
+ andq $~63, %rsp;
+ movq %rsp, %rax;
+
+ /* inpack16_pre: */
+ vpbroadcastq (key_table)(CTX), %ymm0;
+ vpshufb .Lpack_bswap rRIP, %ymm0, %ymm0;
+ vmovdqu (%rcx), %xmm15;
+ vinserti128 $1, (%rdx), %ymm15, %ymm15;
+ vpxor %ymm15, %ymm0, %ymm15;
+ vmovdqu (15 * 32 + 16)(%rdx), %xmm1;
+ vmovdqu %xmm1, (%rcx); /* store new IV */
+ vpxor (0 * 32 + 16)(%rdx), %ymm0, %ymm14;
+ vpxor (1 * 32 + 16)(%rdx), %ymm0, %ymm13;
+ vpxor (2 * 32 + 16)(%rdx), %ymm0, %ymm12;
+ vpxor (3 * 32 + 16)(%rdx), %ymm0, %ymm11;
+ vpxor (4 * 32 + 16)(%rdx), %ymm0, %ymm10;
+ vpxor (5 * 32 + 16)(%rdx), %ymm0, %ymm9;
+ vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm8;
+ vpxor (7 * 32 + 16)(%rdx), %ymm0, %ymm7;
+ vpxor (8 * 32 + 16)(%rdx), %ymm0, %ymm6;
+ vpxor (9 * 32 + 16)(%rdx), %ymm0, %ymm5;
+ vpxor (10 * 32 + 16)(%rdx), %ymm0, %ymm4;
+ vpxor (11 * 32 + 16)(%rdx), %ymm0, %ymm3;
+ vpxor (12 * 32 + 16)(%rdx), %ymm0, %ymm2;
+ vpxor (13 * 32 + 16)(%rdx), %ymm0, %ymm1;
+ vpxor (14 * 32 + 16)(%rdx), %ymm0, %ymm0;
+
+ call __camellia_enc_blk32;
+
+ vpxor 0 * 32(%rdx), %ymm7, %ymm7;
+ vpxor 1 * 32(%rdx), %ymm6, %ymm6;
+ vpxor 2 * 32(%rdx), %ymm5, %ymm5;
+ vpxor 3 * 32(%rdx), %ymm4, %ymm4;
+ vpxor 4 * 32(%rdx), %ymm3, %ymm3;
+ vpxor 5 * 32(%rdx), %ymm2, %ymm2;
+ vpxor 6 * 32(%rdx), %ymm1, %ymm1;
+ vpxor 7 * 32(%rdx), %ymm0, %ymm0;
+ vpxor 8 * 32(%rdx), %ymm15, %ymm15;
+ vpxor 9 * 32(%rdx), %ymm14, %ymm14;
+ vpxor 10 * 32(%rdx), %ymm13, %ymm13;
+ vpxor 11 * 32(%rdx), %ymm12, %ymm12;
+ vpxor 12 * 32(%rdx), %ymm11, %ymm11;
+ vpxor 13 * 32(%rdx), %ymm10, %ymm10;
+ vpxor 14 * 32(%rdx), %ymm9, %ymm9;
+ vpxor 15 * 32(%rdx), %ymm8, %ymm8;
+
+ write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+ %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+ %ymm8, %rsi);
+
+ vzeroall;
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx2_cfb_dec,.-_gcry_camellia_aesni_avx2_cfb_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_ocb_enc
+ELF(.type _gcry_camellia_aesni_avx2_ocb_enc,@function;)
+
+_gcry_camellia_aesni_avx2_ocb_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+ * %rdx: src (32 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[32])
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ subq $(16 * 32 + 4 * 8), %rsp;
+ andq $~63, %rsp;
+ movq %rsp, %rax;
+
+ movq %r10, (16 * 32 + 0 * 8)(%rsp);
+ movq %r11, (16 * 32 + 1 * 8)(%rsp);
+ movq %r12, (16 * 32 + 2 * 8)(%rsp);
+ movq %r13, (16 * 32 + 3 * 8)(%rsp);
+ CFI_REG_ON_STACK(r10, 16 * 32 + 0 * 8);
+ CFI_REG_ON_STACK(r11, 16 * 32 + 1 * 8);
+ CFI_REG_ON_STACK(r12, 16 * 32 + 2 * 8);
+ CFI_REG_ON_STACK(r13, 16 * 32 + 3 * 8);
+
+ vmovdqu (%rcx), %xmm14;
+ vmovdqu (%r8), %xmm13;
+
+ /* 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) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rdx), yreg; \
+ vpxor (l0reg), %xmm14, %xmm15; \
+ vpxor (l1reg), %xmm15, %xmm14; \
+ vinserti128 $1, %xmm14, %ymm15, %ymm15; \
+ vpxor yreg, %ymm13, %ymm13; \
+ vpxor yreg, %ymm15, yreg; \
+ vmovdqu %ymm15, (n * 32)(%rsi);
+
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %r11, %ymm0);
+ vmovdqu %ymm0, (15 * 32)(%rax);
+ OCB_INPUT(1, %r12, %r13, %ymm0);
+ vmovdqu %ymm0, (14 * 32)(%rax);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(2, %r10, %r11, %ymm0);
+ vmovdqu %ymm0, (13 * 32)(%rax);
+ OCB_INPUT(3, %r12, %r13, %ymm12);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %r11, %ymm11);
+ OCB_INPUT(5, %r12, %r13, %ymm10);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(6, %r10, %r11, %ymm9);
+ OCB_INPUT(7, %r12, %r13, %ymm8);
+ movq (16 * 8)(%r9), %r10;
+ movq (17 * 8)(%r9), %r11;
+ movq (18 * 8)(%r9), %r12;
+ movq (19 * 8)(%r9), %r13;
+ OCB_INPUT(8, %r10, %r11, %ymm7);
+ OCB_INPUT(9, %r12, %r13, %ymm6);
+ movq (20 * 8)(%r9), %r10;
+ movq (21 * 8)(%r9), %r11;
+ movq (22 * 8)(%r9), %r12;
+ movq (23 * 8)(%r9), %r13;
+ OCB_INPUT(10, %r10, %r11, %ymm5);
+ OCB_INPUT(11, %r12, %r13, %ymm4);
+ movq (24 * 8)(%r9), %r10;
+ movq (25 * 8)(%r9), %r11;
+ movq (26 * 8)(%r9), %r12;
+ movq (27 * 8)(%r9), %r13;
+ OCB_INPUT(12, %r10, %r11, %ymm3);
+ OCB_INPUT(13, %r12, %r13, %ymm2);
+ movq (28 * 8)(%r9), %r10;
+ movq (29 * 8)(%r9), %r11;
+ movq (30 * 8)(%r9), %r12;
+ movq (31 * 8)(%r9), %r13;
+ OCB_INPUT(14, %r10, %r11, %ymm1);
+ OCB_INPUT(15, %r12, %r13, %ymm0);
+#undef OCB_INPUT
+
+ vextracti128 $1, %ymm13, %xmm15;
+ vmovdqu %xmm14, (%rcx);
+ vpxor %xmm13, %xmm15, %xmm15;
+ vmovdqu %xmm15, (%r8);
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %r10d;
+ cmovel %r10d, %r8d; /* max */
+
+ /* inpack16_pre: */
+ vpbroadcastq (key_table)(CTX), %ymm15;
+ vpshufb .Lpack_bswap rRIP, %ymm15, %ymm15;
+ vpxor %ymm0, %ymm15, %ymm0;
+ vpxor %ymm1, %ymm15, %ymm1;
+ vpxor %ymm2, %ymm15, %ymm2;
+ vpxor %ymm3, %ymm15, %ymm3;
+ vpxor %ymm4, %ymm15, %ymm4;
+ vpxor %ymm5, %ymm15, %ymm5;
+ vpxor %ymm6, %ymm15, %ymm6;
+ vpxor %ymm7, %ymm15, %ymm7;
+ vpxor %ymm8, %ymm15, %ymm8;
+ vpxor %ymm9, %ymm15, %ymm9;
+ vpxor %ymm10, %ymm15, %ymm10;
+ vpxor %ymm11, %ymm15, %ymm11;
+ vpxor %ymm12, %ymm15, %ymm12;
+ vpxor 13 * 32(%rax), %ymm15, %ymm13;
+ vpxor 14 * 32(%rax), %ymm15, %ymm14;
+ vpxor 15 * 32(%rax), %ymm15, %ymm15;
+
+ call __camellia_enc_blk32;
+
+ vpxor 0 * 32(%rsi), %ymm7, %ymm7;
+ vpxor 1 * 32(%rsi), %ymm6, %ymm6;
+ vpxor 2 * 32(%rsi), %ymm5, %ymm5;
+ vpxor 3 * 32(%rsi), %ymm4, %ymm4;
+ vpxor 4 * 32(%rsi), %ymm3, %ymm3;
+ vpxor 5 * 32(%rsi), %ymm2, %ymm2;
+ vpxor 6 * 32(%rsi), %ymm1, %ymm1;
+ vpxor 7 * 32(%rsi), %ymm0, %ymm0;
+ vpxor 8 * 32(%rsi), %ymm15, %ymm15;
+ vpxor 9 * 32(%rsi), %ymm14, %ymm14;
+ vpxor 10 * 32(%rsi), %ymm13, %ymm13;
+ vpxor 11 * 32(%rsi), %ymm12, %ymm12;
+ vpxor 12 * 32(%rsi), %ymm11, %ymm11;
+ vpxor 13 * 32(%rsi), %ymm10, %ymm10;
+ vpxor 14 * 32(%rsi), %ymm9, %ymm9;
+ vpxor 15 * 32(%rsi), %ymm8, %ymm8;
+
+ write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+ %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+ %ymm8, %rsi);
+
+ vzeroall;
+
+ movq (16 * 32 + 0 * 8)(%rsp), %r10;
+ movq (16 * 32 + 1 * 8)(%rsp), %r11;
+ movq (16 * 32 + 2 * 8)(%rsp), %r12;
+ movq (16 * 32 + 3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx2_ocb_enc,.-_gcry_camellia_aesni_avx2_ocb_enc;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_ocb_dec
+ELF(.type _gcry_camellia_aesni_avx2_ocb_dec,@function;)
+
+_gcry_camellia_aesni_avx2_ocb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+ * %rdx: src (32 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[32])
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ subq $(16 * 32 + 4 * 8), %rsp;
+ andq $~63, %rsp;
+ movq %rsp, %rax;
+
+ movq %r10, (16 * 32 + 0 * 8)(%rsp);
+ movq %r11, (16 * 32 + 1 * 8)(%rsp);
+ movq %r12, (16 * 32 + 2 * 8)(%rsp);
+ movq %r13, (16 * 32 + 3 * 8)(%rsp);
+ CFI_REG_ON_STACK(r10, 16 * 32 + 0 * 8);
+ CFI_REG_ON_STACK(r11, 16 * 32 + 1 * 8);
+ CFI_REG_ON_STACK(r12, 16 * 32 + 2 * 8);
+ CFI_REG_ON_STACK(r13, 16 * 32 + 3 * 8);
+
+ vmovdqu (%rcx), %xmm14;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rdx), yreg; \
+ vpxor (l0reg), %xmm14, %xmm15; \
+ vpxor (l1reg), %xmm15, %xmm14; \
+ vinserti128 $1, %xmm14, %ymm15, %ymm15; \
+ vpxor yreg, %ymm15, yreg; \
+ vmovdqu %ymm15, (n * 32)(%rsi);
+
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %r11, %ymm0);
+ vmovdqu %ymm0, (15 * 32)(%rax);
+ OCB_INPUT(1, %r12, %r13, %ymm0);
+ vmovdqu %ymm0, (14 * 32)(%rax);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(2, %r10, %r11, %ymm13);
+ OCB_INPUT(3, %r12, %r13, %ymm12);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %r11, %ymm11);
+ OCB_INPUT(5, %r12, %r13, %ymm10);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(6, %r10, %r11, %ymm9);
+ OCB_INPUT(7, %r12, %r13, %ymm8);
+ movq (16 * 8)(%r9), %r10;
+ movq (17 * 8)(%r9), %r11;
+ movq (18 * 8)(%r9), %r12;
+ movq (19 * 8)(%r9), %r13;
+ OCB_INPUT(8, %r10, %r11, %ymm7);
+ OCB_INPUT(9, %r12, %r13, %ymm6);
+ movq (20 * 8)(%r9), %r10;
+ movq (21 * 8)(%r9), %r11;
+ movq (22 * 8)(%r9), %r12;
+ movq (23 * 8)(%r9), %r13;
+ OCB_INPUT(10, %r10, %r11, %ymm5);
+ OCB_INPUT(11, %r12, %r13, %ymm4);
+ movq (24 * 8)(%r9), %r10;
+ movq (25 * 8)(%r9), %r11;
+ movq (26 * 8)(%r9), %r12;
+ movq (27 * 8)(%r9), %r13;
+ OCB_INPUT(12, %r10, %r11, %ymm3);
+ OCB_INPUT(13, %r12, %r13, %ymm2);
+ movq (28 * 8)(%r9), %r10;
+ movq (29 * 8)(%r9), %r11;
+ movq (30 * 8)(%r9), %r12;
+ movq (31 * 8)(%r9), %r13;
+ OCB_INPUT(14, %r10, %r11, %ymm1);
+ OCB_INPUT(15, %r12, %r13, %ymm0);
+#undef OCB_INPUT
+
+ vmovdqu %xmm14, (%rcx);
+
+ movq %r8, %r10;
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %r9d;
+ cmovel %r9d, %r8d; /* max */
+
+ /* inpack16_pre: */
+ vpbroadcastq (key_table)(CTX, %r8, 8), %ymm15;
+ vpshufb .Lpack_bswap rRIP, %ymm15, %ymm15;
+ vpxor %ymm0, %ymm15, %ymm0;
+ vpxor %ymm1, %ymm15, %ymm1;
+ vpxor %ymm2, %ymm15, %ymm2;
+ vpxor %ymm3, %ymm15, %ymm3;
+ vpxor %ymm4, %ymm15, %ymm4;
+ vpxor %ymm5, %ymm15, %ymm5;
+ vpxor %ymm6, %ymm15, %ymm6;
+ vpxor %ymm7, %ymm15, %ymm7;
+ vpxor %ymm8, %ymm15, %ymm8;
+ vpxor %ymm9, %ymm15, %ymm9;
+ vpxor %ymm10, %ymm15, %ymm10;
+ vpxor %ymm11, %ymm15, %ymm11;
+ vpxor %ymm12, %ymm15, %ymm12;
+ vpxor %ymm13, %ymm15, %ymm13;
+ vpxor 14 * 32(%rax), %ymm15, %ymm14;
+ vpxor 15 * 32(%rax), %ymm15, %ymm15;
+
+ call __camellia_dec_blk32;
+
+ vpxor 0 * 32(%rsi), %ymm7, %ymm7;
+ vpxor 1 * 32(%rsi), %ymm6, %ymm6;
+ vpxor 2 * 32(%rsi), %ymm5, %ymm5;
+ vpxor 3 * 32(%rsi), %ymm4, %ymm4;
+ vpxor 4 * 32(%rsi), %ymm3, %ymm3;
+ vpxor 5 * 32(%rsi), %ymm2, %ymm2;
+ vpxor 6 * 32(%rsi), %ymm1, %ymm1;
+ vpxor 7 * 32(%rsi), %ymm0, %ymm0;
+ vmovdqu %ymm7, (7 * 32)(%rax);
+ vmovdqu %ymm6, (6 * 32)(%rax);
+ vpxor 8 * 32(%rsi), %ymm15, %ymm15;
+ vpxor 9 * 32(%rsi), %ymm14, %ymm14;
+ vpxor 10 * 32(%rsi), %ymm13, %ymm13;
+ vpxor 11 * 32(%rsi), %ymm12, %ymm12;
+ vpxor 12 * 32(%rsi), %ymm11, %ymm11;
+ vpxor 13 * 32(%rsi), %ymm10, %ymm10;
+ vpxor 14 * 32(%rsi), %ymm9, %ymm9;
+ vpxor 15 * 32(%rsi), %ymm8, %ymm8;
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+
+ vpxor %ymm5, %ymm7, %ymm7;
+ vpxor %ymm4, %ymm6, %ymm6;
+ vpxor %ymm3, %ymm7, %ymm7;
+ vpxor %ymm2, %ymm6, %ymm6;
+ vpxor %ymm1, %ymm7, %ymm7;
+ vpxor %ymm0, %ymm6, %ymm6;
+ vpxor %ymm15, %ymm7, %ymm7;
+ vpxor %ymm14, %ymm6, %ymm6;
+ vpxor %ymm13, %ymm7, %ymm7;
+ vpxor %ymm12, %ymm6, %ymm6;
+ vpxor %ymm11, %ymm7, %ymm7;
+ vpxor %ymm10, %ymm6, %ymm6;
+ vpxor %ymm9, %ymm7, %ymm7;
+ vpxor %ymm8, %ymm6, %ymm6;
+ vpxor %ymm7, %ymm6, %ymm7;
+
+ vextracti128 $1, %ymm7, %xmm6;
+ vpxor %xmm6, %xmm7, %xmm7;
+ vpxor (%r10), %xmm7, %xmm7;
+ vmovdqu %xmm7, (%r10);
+
+ vmovdqu 7 * 32(%rax), %ymm7;
+ vmovdqu 6 * 32(%rax), %ymm6;
+
+ write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+ %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+ %ymm8, %rsi);
+
+ vzeroall;
+
+ movq (16 * 32 + 0 * 8)(%rsp), %r10;
+ movq (16 * 32 + 1 * 8)(%rsp), %r11;
+ movq (16 * 32 + 2 * 8)(%rsp), %r12;
+ movq (16 * 32 + 3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx2_ocb_dec,.-_gcry_camellia_aesni_avx2_ocb_dec;)
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_ocb_auth
+ELF(.type _gcry_camellia_aesni_avx2_ocb_auth,@function;)
+
+_gcry_camellia_aesni_avx2_ocb_auth:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: abuf (16 blocks)
+ * %rdx: offset
+ * %rcx: checksum
+ * %r8 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ subq $(16 * 32 + 4 * 8), %rsp;
+ andq $~63, %rsp;
+ movq %rsp, %rax;
+
+ movq %r10, (16 * 32 + 0 * 8)(%rsp);
+ movq %r11, (16 * 32 + 1 * 8)(%rsp);
+ movq %r12, (16 * 32 + 2 * 8)(%rsp);
+ movq %r13, (16 * 32 + 3 * 8)(%rsp);
+ CFI_REG_ON_STACK(r10, 16 * 32 + 0 * 8);
+ CFI_REG_ON_STACK(r11, 16 * 32 + 1 * 8);
+ CFI_REG_ON_STACK(r12, 16 * 32 + 2 * 8);
+ CFI_REG_ON_STACK(r13, 16 * 32 + 3 * 8);
+
+ vmovdqu (%rdx), %xmm14;
+
+ /* 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) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rsi), yreg; \
+ vpxor (l0reg), %xmm14, %xmm15; \
+ vpxor (l1reg), %xmm15, %xmm14; \
+ vinserti128 $1, %xmm14, %ymm15, %ymm15; \
+ vpxor yreg, %ymm15, yreg;
+
+ movq (0 * 8)(%r8), %r10;
+ movq (1 * 8)(%r8), %r11;
+ movq (2 * 8)(%r8), %r12;
+ movq (3 * 8)(%r8), %r13;
+ OCB_INPUT(0, %r10, %r11, %ymm0);
+ vmovdqu %ymm0, (15 * 32)(%rax);
+ OCB_INPUT(1, %r12, %r13, %ymm0);
+ vmovdqu %ymm0, (14 * 32)(%rax);
+ movq (4 * 8)(%r8), %r10;
+ movq (5 * 8)(%r8), %r11;
+ movq (6 * 8)(%r8), %r12;
+ movq (7 * 8)(%r8), %r13;
+ OCB_INPUT(2, %r10, %r11, %ymm13);
+ OCB_INPUT(3, %r12, %r13, %ymm12);
+ movq (8 * 8)(%r8), %r10;
+ movq (9 * 8)(%r8), %r11;
+ movq (10 * 8)(%r8), %r12;
+ movq (11 * 8)(%r8), %r13;
+ OCB_INPUT(4, %r10, %r11, %ymm11);
+ OCB_INPUT(5, %r12, %r13, %ymm10);
+ movq (12 * 8)(%r8), %r10;
+ movq (13 * 8)(%r8), %r11;
+ movq (14 * 8)(%r8), %r12;
+ movq (15 * 8)(%r8), %r13;
+ OCB_INPUT(6, %r10, %r11, %ymm9);
+ OCB_INPUT(7, %r12, %r13, %ymm8);
+ movq (16 * 8)(%r8), %r10;
+ movq (17 * 8)(%r8), %r11;
+ movq (18 * 8)(%r8), %r12;
+ movq (19 * 8)(%r8), %r13;
+ OCB_INPUT(8, %r10, %r11, %ymm7);
+ OCB_INPUT(9, %r12, %r13, %ymm6);
+ movq (20 * 8)(%r8), %r10;
+ movq (21 * 8)(%r8), %r11;
+ movq (22 * 8)(%r8), %r12;
+ movq (23 * 8)(%r8), %r13;
+ OCB_INPUT(10, %r10, %r11, %ymm5);
+ OCB_INPUT(11, %r12, %r13, %ymm4);
+ movq (24 * 8)(%r8), %r10;
+ movq (25 * 8)(%r8), %r11;
+ movq (26 * 8)(%r8), %r12;
+ movq (27 * 8)(%r8), %r13;
+ OCB_INPUT(12, %r10, %r11, %ymm3);
+ OCB_INPUT(13, %r12, %r13, %ymm2);
+ movq (28 * 8)(%r8), %r10;
+ movq (29 * 8)(%r8), %r11;
+ movq (30 * 8)(%r8), %r12;
+ movq (31 * 8)(%r8), %r13;
+ OCB_INPUT(14, %r10, %r11, %ymm1);
+ OCB_INPUT(15, %r12, %r13, %ymm0);
+#undef OCB_INPUT
+
+ vmovdqu %xmm14, (%rdx);
+
+ cmpl $128, key_bitlength(CTX);
+ movl $32, %r8d;
+ movl $24, %r10d;
+ cmovel %r10d, %r8d; /* max */
+
+ movq %rcx, %r10;
+
+ /* inpack16_pre: */
+ vpbroadcastq (key_table)(CTX), %ymm15;
+ vpshufb .Lpack_bswap rRIP, %ymm15, %ymm15;
+ vpxor %ymm0, %ymm15, %ymm0;
+ vpxor %ymm1, %ymm15, %ymm1;
+ vpxor %ymm2, %ymm15, %ymm2;
+ vpxor %ymm3, %ymm15, %ymm3;
+ vpxor %ymm4, %ymm15, %ymm4;
+ vpxor %ymm5, %ymm15, %ymm5;
+ vpxor %ymm6, %ymm15, %ymm6;
+ vpxor %ymm7, %ymm15, %ymm7;
+ vpxor %ymm8, %ymm15, %ymm8;
+ vpxor %ymm9, %ymm15, %ymm9;
+ vpxor %ymm10, %ymm15, %ymm10;
+ vpxor %ymm11, %ymm15, %ymm11;
+ vpxor %ymm12, %ymm15, %ymm12;
+ vpxor %ymm13, %ymm15, %ymm13;
+ vpxor 14 * 32(%rax), %ymm15, %ymm14;
+ vpxor 15 * 32(%rax), %ymm15, %ymm15;
+
+ call __camellia_enc_blk32;
+
+ vpxor %ymm7, %ymm6, %ymm6;
+ vpxor %ymm5, %ymm4, %ymm4;
+ vpxor %ymm3, %ymm2, %ymm2;
+ vpxor %ymm1, %ymm0, %ymm0;
+ vpxor %ymm15, %ymm14, %ymm14;
+ vpxor %ymm13, %ymm12, %ymm12;
+ vpxor %ymm11, %ymm10, %ymm10;
+ vpxor %ymm9, %ymm8, %ymm8;
+
+ vpxor %ymm6, %ymm4, %ymm4;
+ vpxor %ymm2, %ymm0, %ymm0;
+ vpxor %ymm14, %ymm12, %ymm12;
+ vpxor %ymm10, %ymm8, %ymm8;
+
+ vpxor %ymm4, %ymm0, %ymm0;
+ vpxor %ymm12, %ymm8, %ymm8;
+
+ vpxor %ymm0, %ymm8, %ymm0;
+
+ vextracti128 $1, %ymm0, %xmm1;
+ vpxor (%r10), %xmm0, %xmm0;
+ vpxor %xmm0, %xmm1, %xmm0;
+ vmovdqu %xmm0, (%r10);
+
+ vzeroall;
+
+ movq (16 * 32 + 0 * 8)(%rsp), %r10;
+ movq (16 * 32 + 1 * 8)(%rsp), %r11;
+ movq (16 * 32 + 2 * 8)(%rsp), %r12;
+ movq (16 * 32 + 3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_camellia_aesni_avx2_ocb_auth,.-_gcry_camellia_aesni_avx2_ocb_auth;)
+
+#endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/camellia-arm.S b/comm/third_party/libgcrypt/cipher/camellia-arm.S
new file mode 100644
index 0000000000..a3d87d1109
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/camellia-arm.S
@@ -0,0 +1,626 @@
+/* camellia-arm.S - ARM assembly implementation of Camellia cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(__ARMEL__)
+#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+.text
+
+.syntax unified
+.arm
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+/* struct camellia_ctx: */
+#define key_table 0
+
+/* register macros */
+#define CTX %r0
+#define RTAB1 %ip
+#define RTAB3 %r1
+#define RMASK %lr
+
+#define IL %r2
+#define IR %r3
+
+#define XL %r4
+#define XR %r5
+#define YL %r6
+#define YR %r7
+
+#define RT0 %r8
+#define RT1 %r9
+#define RT2 %r10
+#define RT3 %r11
+
+/* helper macros */
+#define ldr_unaligned_be(rout, rsrc, offs, rtmp) \
+ ldrb rout, [rsrc, #((offs) + 3)]; \
+ ldrb rtmp, [rsrc, #((offs) + 2)]; \
+ orr rout, rout, rtmp, lsl #8; \
+ ldrb rtmp, [rsrc, #((offs) + 1)]; \
+ orr rout, rout, rtmp, lsl #16; \
+ ldrb rtmp, [rsrc, #((offs) + 0)]; \
+ orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_be(rin, rdst, offs, rtmp0, rtmp1) \
+ mov rtmp0, rin, lsr #8; \
+ strb rin, [rdst, #((offs) + 3)]; \
+ mov rtmp1, rin, lsr #16; \
+ strb rtmp0, [rdst, #((offs) + 2)]; \
+ mov rtmp0, rin, lsr #24; \
+ strb rtmp1, [rdst, #((offs) + 1)]; \
+ strb rtmp0, [rdst, #((offs) + 0)];
+
+#ifdef __ARMEL__
+#ifdef HAVE_ARM_ARCH_V6
+ #define host_to_be(reg, rtmp) \
+ rev reg, reg;
+ #define be_to_host(reg, rtmp) \
+ rev reg, reg;
+#else
+ #define host_to_be(reg, rtmp) \
+ eor rtmp, reg, reg, ror #16; \
+ mov rtmp, rtmp, lsr #8; \
+ bic rtmp, rtmp, #65280; \
+ eor reg, rtmp, reg, ror #8;
+ #define be_to_host(reg, rtmp) \
+ eor rtmp, reg, reg, ror #16; \
+ mov rtmp, rtmp, lsr #8; \
+ bic rtmp, rtmp, #65280; \
+ eor reg, rtmp, reg, ror #8;
+#endif
+#else
+ /* nop on big-endian */
+ #define host_to_be(reg, rtmp) /*_*/
+ #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define ldr_input_aligned_be(rin, a, b, c, d, rtmp) \
+ ldr a, [rin, #0]; \
+ ldr b, [rin, #4]; \
+ be_to_host(a, rtmp); \
+ ldr c, [rin, #8]; \
+ be_to_host(b, rtmp); \
+ ldr d, [rin, #12]; \
+ be_to_host(c, rtmp); \
+ be_to_host(d, rtmp);
+
+#define str_output_aligned_be(rout, a, b, c, d, rtmp) \
+ be_to_host(a, rtmp); \
+ be_to_host(b, rtmp); \
+ str a, [rout, #0]; \
+ be_to_host(c, rtmp); \
+ str b, [rout, #4]; \
+ be_to_host(d, rtmp); \
+ str c, [rout, #8]; \
+ str d, [rout, #12];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+ /* unaligned word reads/writes allowed */
+ #define ldr_input_be(rin, ra, rb, rc, rd, rtmp) \
+ ldr_input_aligned_be(rin, ra, rb, rc, rd, rtmp)
+
+ #define str_output_be(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+ str_output_aligned_be(rout, ra, rb, rc, rd, rtmp0)
+#else
+ /* need to handle unaligned reads/writes by byte reads */
+ #define ldr_input_be(rin, ra, rb, rc, rd, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_be(ra, rin, 0, rtmp0); \
+ ldr_unaligned_be(rb, rin, 4, rtmp0); \
+ ldr_unaligned_be(rc, rin, 8, rtmp0); \
+ ldr_unaligned_be(rd, rin, 12, rtmp0); \
+ b 2f; \
+ 1:;\
+ ldr_input_aligned_be(rin, ra, rb, rc, rd, rtmp0); \
+ 2:;
+
+ #define str_output_be(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_be(ra, rout, 0, rtmp0, rtmp1); \
+ str_unaligned_be(rb, rout, 4, rtmp0, rtmp1); \
+ str_unaligned_be(rc, rout, 8, rtmp0, rtmp1); \
+ str_unaligned_be(rd, rout, 12, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ str_output_aligned_be(rout, ra, rb, rc, rd, rtmp0); \
+ 2:;
+#endif
+
+/**********************************************************************
+ 1-way camellia
+ **********************************************************************/
+#define roundsm(xl, xr, kl, kr, yl, yr) \
+ ldr RT2, [CTX, #(key_table + ((kl) * 4))]; \
+ and IR, RMASK, xr, lsl#(4); /*sp1110*/ \
+ ldr RT3, [CTX, #(key_table + ((kr) * 4))]; \
+ and IL, RMASK, xl, lsr#(24 - 4); /*sp1110*/ \
+ and RT0, RMASK, xr, lsr#(16 - 4); /*sp3033*/ \
+ ldr IR, [RTAB1, IR]; \
+ and RT1, RMASK, xl, lsr#(8 - 4); /*sp3033*/ \
+ eor yl, RT2; \
+ ldr IL, [RTAB1, IL]; \
+ eor yr, RT3; \
+ \
+ ldr RT0, [RTAB3, RT0]; \
+ add RTAB1, #4; \
+ ldr RT1, [RTAB3, RT1]; \
+ add RTAB3, #4; \
+ \
+ and RT2, RMASK, xr, lsr#(24 - 4); /*sp0222*/ \
+ and RT3, RMASK, xl, lsr#(16 - 4); /*sp0222*/ \
+ \
+ eor IR, RT0; \
+ eor IL, RT1; \
+ \
+ ldr RT2, [RTAB1, RT2]; \
+ and RT0, RMASK, xr, lsr#(8 - 4); /*sp4404*/ \
+ ldr RT3, [RTAB1, RT3]; \
+ and RT1, RMASK, xl, lsl#(4); /*sp4404*/ \
+ \
+ ldr RT0, [RTAB3, RT0]; \
+ sub RTAB1, #4; \
+ ldr RT1, [RTAB3, RT1]; \
+ sub RTAB3, #4; \
+ \
+ eor IR, RT2; \
+ eor IL, RT3; \
+ eor IR, RT0; \
+ eor IL, RT1; \
+ \
+ eor IR, IL; \
+ eor yr, yr, IL, ror#8; \
+ eor yl, IR; \
+ eor yr, IR;
+
+#define enc_rounds(n) \
+ roundsm(XL, XR, ((n) + 2) * 2 + 0, ((n) + 2) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 3) * 2 + 0, ((n) + 3) * 2 + 1, XL, XR); \
+ roundsm(XL, XR, ((n) + 4) * 2 + 0, ((n) + 4) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 5) * 2 + 0, ((n) + 5) * 2 + 1, XL, XR); \
+ roundsm(XL, XR, ((n) + 6) * 2 + 0, ((n) + 6) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 7) * 2 + 0, ((n) + 7) * 2 + 1, XL, XR);
+
+#define dec_rounds(n) \
+ roundsm(XL, XR, ((n) + 7) * 2 + 0, ((n) + 7) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 6) * 2 + 0, ((n) + 6) * 2 + 1, XL, XR); \
+ roundsm(XL, XR, ((n) + 5) * 2 + 0, ((n) + 5) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 4) * 2 + 0, ((n) + 4) * 2 + 1, XL, XR); \
+ roundsm(XL, XR, ((n) + 3) * 2 + 0, ((n) + 3) * 2 + 1, YL, YR); \
+ roundsm(YL, YR, ((n) + 2) * 2 + 0, ((n) + 2) * 2 + 1, XL, XR);
+
+/* perform FL and FLâ»Â¹ */
+#define fls(ll, lr, rl, rr, kll, klr, krl, krr) \
+ ldr RT0, [CTX, #(key_table + ((kll) * 4))]; \
+ ldr RT2, [CTX, #(key_table + ((krr) * 4))]; \
+ and RT0, ll; \
+ ldr RT3, [CTX, #(key_table + ((krl) * 4))]; \
+ orr RT2, rr; \
+ ldr RT1, [CTX, #(key_table + ((klr) * 4))]; \
+ eor rl, RT2; \
+ eor lr, lr, RT0, ror#31; \
+ and RT3, rl; \
+ orr RT1, lr; \
+ eor ll, RT1; \
+ eor rr, rr, RT3, ror#31;
+
+#define enc_fls(n) \
+ fls(XL, XR, YL, YR, \
+ (n) * 2 + 0, (n) * 2 + 1, \
+ (n) * 2 + 2, (n) * 2 + 3);
+
+#define dec_fls(n) \
+ fls(XL, XR, YL, YR, \
+ (n) * 2 + 2, (n) * 2 + 3, \
+ (n) * 2 + 0, (n) * 2 + 1);
+
+#define inpack(n) \
+ ldr_input_be(%r2, XL, XR, YL, YR, RT0); \
+ ldr RT0, [CTX, #(key_table + ((n) * 8) + 0)]; \
+ ldr RT1, [CTX, #(key_table + ((n) * 8) + 4)]; \
+ eor XL, RT0; \
+ eor XR, RT1;
+
+#define outunpack(n) \
+ ldr RT0, [CTX, #(key_table + ((n) * 8) + 0)]; \
+ ldr RT1, [CTX, #(key_table + ((n) * 8) + 4)]; \
+ eor YL, RT0; \
+ eor YR, RT1; \
+ str_output_be(%r1, YL, YR, XL, XR, RT0, RT1);
+
+.align 3
+.globl _gcry_camellia_arm_encrypt_block
+.type _gcry_camellia_arm_encrypt_block,%function;
+
+_gcry_camellia_arm_encrypt_block:
+ /* input:
+ * %r0: keytable
+ * %r1: dst
+ * %r2: src
+ * %r3: keybitlen
+ */
+ push {%r1, %r4-%r11, %ip, %lr};
+
+ GET_DATA_POINTER(RTAB1, .Lcamellia_sp1110, RTAB3);
+ mov RMASK, #0xff;
+ add RTAB3, RTAB1, #(2 * 4);
+ push {%r3};
+ mov RMASK, RMASK, lsl#4 /* byte mask */
+
+ inpack(0);
+
+ enc_rounds(0);
+ enc_fls(8);
+ enc_rounds(8);
+ enc_fls(16);
+ enc_rounds(16);
+
+ pop {RT0};
+ cmp RT0, #(16 * 8);
+ bne .Lenc_256;
+
+ pop {%r1};
+ outunpack(24);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+
+.Lenc_256:
+ enc_fls(24);
+ enc_rounds(24);
+
+ pop {%r1};
+ outunpack(32);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_camellia_arm_encrypt_block,.-_gcry_camellia_arm_encrypt_block;
+
+.align 3
+.globl _gcry_camellia_arm_decrypt_block
+.type _gcry_camellia_arm_decrypt_block,%function;
+
+_gcry_camellia_arm_decrypt_block:
+ /* input:
+ * %r0: keytable
+ * %r1: dst
+ * %r2: src
+ * %r3: keybitlen
+ */
+ push {%r1, %r4-%r11, %ip, %lr};
+
+ GET_DATA_POINTER(RTAB1, .Lcamellia_sp1110, RTAB3);
+ mov RMASK, #0xff;
+ add RTAB3, RTAB1, #(2 * 4);
+ mov RMASK, RMASK, lsl#4 /* byte mask */
+
+ cmp %r3, #(16 * 8);
+ bne .Ldec_256;
+
+ inpack(24);
+
+.Ldec_128:
+ dec_rounds(16);
+ dec_fls(16);
+ dec_rounds(8);
+ dec_fls(8);
+ dec_rounds(0);
+
+ pop {%r1};
+ outunpack(0);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+
+.Ldec_256:
+ inpack(32);
+ dec_rounds(24);
+ dec_fls(24);
+
+ b .Ldec_128;
+.ltorg
+.size _gcry_camellia_arm_decrypt_block,.-_gcry_camellia_arm_decrypt_block;
+
+.data
+
+/* Encryption/Decryption tables */
+.align 5
+.Lcamellia_sp1110:
+.long 0x70707000
+.Lcamellia_sp0222:
+ .long 0x00e0e0e0
+.Lcamellia_sp3033:
+ .long 0x38003838
+.Lcamellia_sp4404:
+ .long 0x70700070
+.long 0x82828200, 0x00050505, 0x41004141, 0x2c2c002c
+.long 0x2c2c2c00, 0x00585858, 0x16001616, 0xb3b300b3
+.long 0xececec00, 0x00d9d9d9, 0x76007676, 0xc0c000c0
+.long 0xb3b3b300, 0x00676767, 0xd900d9d9, 0xe4e400e4
+.long 0x27272700, 0x004e4e4e, 0x93009393, 0x57570057
+.long 0xc0c0c000, 0x00818181, 0x60006060, 0xeaea00ea
+.long 0xe5e5e500, 0x00cbcbcb, 0xf200f2f2, 0xaeae00ae
+.long 0xe4e4e400, 0x00c9c9c9, 0x72007272, 0x23230023
+.long 0x85858500, 0x000b0b0b, 0xc200c2c2, 0x6b6b006b
+.long 0x57575700, 0x00aeaeae, 0xab00abab, 0x45450045
+.long 0x35353500, 0x006a6a6a, 0x9a009a9a, 0xa5a500a5
+.long 0xeaeaea00, 0x00d5d5d5, 0x75007575, 0xeded00ed
+.long 0x0c0c0c00, 0x00181818, 0x06000606, 0x4f4f004f
+.long 0xaeaeae00, 0x005d5d5d, 0x57005757, 0x1d1d001d
+.long 0x41414100, 0x00828282, 0xa000a0a0, 0x92920092
+.long 0x23232300, 0x00464646, 0x91009191, 0x86860086
+.long 0xefefef00, 0x00dfdfdf, 0xf700f7f7, 0xafaf00af
+.long 0x6b6b6b00, 0x00d6d6d6, 0xb500b5b5, 0x7c7c007c
+.long 0x93939300, 0x00272727, 0xc900c9c9, 0x1f1f001f
+.long 0x45454500, 0x008a8a8a, 0xa200a2a2, 0x3e3e003e
+.long 0x19191900, 0x00323232, 0x8c008c8c, 0xdcdc00dc
+.long 0xa5a5a500, 0x004b4b4b, 0xd200d2d2, 0x5e5e005e
+.long 0x21212100, 0x00424242, 0x90009090, 0x0b0b000b
+.long 0xededed00, 0x00dbdbdb, 0xf600f6f6, 0xa6a600a6
+.long 0x0e0e0e00, 0x001c1c1c, 0x07000707, 0x39390039
+.long 0x4f4f4f00, 0x009e9e9e, 0xa700a7a7, 0xd5d500d5
+.long 0x4e4e4e00, 0x009c9c9c, 0x27002727, 0x5d5d005d
+.long 0x1d1d1d00, 0x003a3a3a, 0x8e008e8e, 0xd9d900d9
+.long 0x65656500, 0x00cacaca, 0xb200b2b2, 0x5a5a005a
+.long 0x92929200, 0x00252525, 0x49004949, 0x51510051
+.long 0xbdbdbd00, 0x007b7b7b, 0xde00dede, 0x6c6c006c
+.long 0x86868600, 0x000d0d0d, 0x43004343, 0x8b8b008b
+.long 0xb8b8b800, 0x00717171, 0x5c005c5c, 0x9a9a009a
+.long 0xafafaf00, 0x005f5f5f, 0xd700d7d7, 0xfbfb00fb
+.long 0x8f8f8f00, 0x001f1f1f, 0xc700c7c7, 0xb0b000b0
+.long 0x7c7c7c00, 0x00f8f8f8, 0x3e003e3e, 0x74740074
+.long 0xebebeb00, 0x00d7d7d7, 0xf500f5f5, 0x2b2b002b
+.long 0x1f1f1f00, 0x003e3e3e, 0x8f008f8f, 0xf0f000f0
+.long 0xcecece00, 0x009d9d9d, 0x67006767, 0x84840084
+.long 0x3e3e3e00, 0x007c7c7c, 0x1f001f1f, 0xdfdf00df
+.long 0x30303000, 0x00606060, 0x18001818, 0xcbcb00cb
+.long 0xdcdcdc00, 0x00b9b9b9, 0x6e006e6e, 0x34340034
+.long 0x5f5f5f00, 0x00bebebe, 0xaf00afaf, 0x76760076
+.long 0x5e5e5e00, 0x00bcbcbc, 0x2f002f2f, 0x6d6d006d
+.long 0xc5c5c500, 0x008b8b8b, 0xe200e2e2, 0xa9a900a9
+.long 0x0b0b0b00, 0x00161616, 0x85008585, 0xd1d100d1
+.long 0x1a1a1a00, 0x00343434, 0x0d000d0d, 0x04040004
+.long 0xa6a6a600, 0x004d4d4d, 0x53005353, 0x14140014
+.long 0xe1e1e100, 0x00c3c3c3, 0xf000f0f0, 0x3a3a003a
+.long 0x39393900, 0x00727272, 0x9c009c9c, 0xdede00de
+.long 0xcacaca00, 0x00959595, 0x65006565, 0x11110011
+.long 0xd5d5d500, 0x00ababab, 0xea00eaea, 0x32320032
+.long 0x47474700, 0x008e8e8e, 0xa300a3a3, 0x9c9c009c
+.long 0x5d5d5d00, 0x00bababa, 0xae00aeae, 0x53530053
+.long 0x3d3d3d00, 0x007a7a7a, 0x9e009e9e, 0xf2f200f2
+.long 0xd9d9d900, 0x00b3b3b3, 0xec00ecec, 0xfefe00fe
+.long 0x01010100, 0x00020202, 0x80008080, 0xcfcf00cf
+.long 0x5a5a5a00, 0x00b4b4b4, 0x2d002d2d, 0xc3c300c3
+.long 0xd6d6d600, 0x00adadad, 0x6b006b6b, 0x7a7a007a
+.long 0x51515100, 0x00a2a2a2, 0xa800a8a8, 0x24240024
+.long 0x56565600, 0x00acacac, 0x2b002b2b, 0xe8e800e8
+.long 0x6c6c6c00, 0x00d8d8d8, 0x36003636, 0x60600060
+.long 0x4d4d4d00, 0x009a9a9a, 0xa600a6a6, 0x69690069
+.long 0x8b8b8b00, 0x00171717, 0xc500c5c5, 0xaaaa00aa
+.long 0x0d0d0d00, 0x001a1a1a, 0x86008686, 0xa0a000a0
+.long 0x9a9a9a00, 0x00353535, 0x4d004d4d, 0xa1a100a1
+.long 0x66666600, 0x00cccccc, 0x33003333, 0x62620062
+.long 0xfbfbfb00, 0x00f7f7f7, 0xfd00fdfd, 0x54540054
+.long 0xcccccc00, 0x00999999, 0x66006666, 0x1e1e001e
+.long 0xb0b0b000, 0x00616161, 0x58005858, 0xe0e000e0
+.long 0x2d2d2d00, 0x005a5a5a, 0x96009696, 0x64640064
+.long 0x74747400, 0x00e8e8e8, 0x3a003a3a, 0x10100010
+.long 0x12121200, 0x00242424, 0x09000909, 0x00000000
+.long 0x2b2b2b00, 0x00565656, 0x95009595, 0xa3a300a3
+.long 0x20202000, 0x00404040, 0x10001010, 0x75750075
+.long 0xf0f0f000, 0x00e1e1e1, 0x78007878, 0x8a8a008a
+.long 0xb1b1b100, 0x00636363, 0xd800d8d8, 0xe6e600e6
+.long 0x84848400, 0x00090909, 0x42004242, 0x09090009
+.long 0x99999900, 0x00333333, 0xcc00cccc, 0xdddd00dd
+.long 0xdfdfdf00, 0x00bfbfbf, 0xef00efef, 0x87870087
+.long 0x4c4c4c00, 0x00989898, 0x26002626, 0x83830083
+.long 0xcbcbcb00, 0x00979797, 0xe500e5e5, 0xcdcd00cd
+.long 0xc2c2c200, 0x00858585, 0x61006161, 0x90900090
+.long 0x34343400, 0x00686868, 0x1a001a1a, 0x73730073
+.long 0x7e7e7e00, 0x00fcfcfc, 0x3f003f3f, 0xf6f600f6
+.long 0x76767600, 0x00ececec, 0x3b003b3b, 0x9d9d009d
+.long 0x05050500, 0x000a0a0a, 0x82008282, 0xbfbf00bf
+.long 0x6d6d6d00, 0x00dadada, 0xb600b6b6, 0x52520052
+.long 0xb7b7b700, 0x006f6f6f, 0xdb00dbdb, 0xd8d800d8
+.long 0xa9a9a900, 0x00535353, 0xd400d4d4, 0xc8c800c8
+.long 0x31313100, 0x00626262, 0x98009898, 0xc6c600c6
+.long 0xd1d1d100, 0x00a3a3a3, 0xe800e8e8, 0x81810081
+.long 0x17171700, 0x002e2e2e, 0x8b008b8b, 0x6f6f006f
+.long 0x04040400, 0x00080808, 0x02000202, 0x13130013
+.long 0xd7d7d700, 0x00afafaf, 0xeb00ebeb, 0x63630063
+.long 0x14141400, 0x00282828, 0x0a000a0a, 0xe9e900e9
+.long 0x58585800, 0x00b0b0b0, 0x2c002c2c, 0xa7a700a7
+.long 0x3a3a3a00, 0x00747474, 0x1d001d1d, 0x9f9f009f
+.long 0x61616100, 0x00c2c2c2, 0xb000b0b0, 0xbcbc00bc
+.long 0xdedede00, 0x00bdbdbd, 0x6f006f6f, 0x29290029
+.long 0x1b1b1b00, 0x00363636, 0x8d008d8d, 0xf9f900f9
+.long 0x11111100, 0x00222222, 0x88008888, 0x2f2f002f
+.long 0x1c1c1c00, 0x00383838, 0x0e000e0e, 0xb4b400b4
+.long 0x32323200, 0x00646464, 0x19001919, 0x78780078
+.long 0x0f0f0f00, 0x001e1e1e, 0x87008787, 0x06060006
+.long 0x9c9c9c00, 0x00393939, 0x4e004e4e, 0xe7e700e7
+.long 0x16161600, 0x002c2c2c, 0x0b000b0b, 0x71710071
+.long 0x53535300, 0x00a6a6a6, 0xa900a9a9, 0xd4d400d4
+.long 0x18181800, 0x00303030, 0x0c000c0c, 0xabab00ab
+.long 0xf2f2f200, 0x00e5e5e5, 0x79007979, 0x88880088
+.long 0x22222200, 0x00444444, 0x11001111, 0x8d8d008d
+.long 0xfefefe00, 0x00fdfdfd, 0x7f007f7f, 0x72720072
+.long 0x44444400, 0x00888888, 0x22002222, 0xb9b900b9
+.long 0xcfcfcf00, 0x009f9f9f, 0xe700e7e7, 0xf8f800f8
+.long 0xb2b2b200, 0x00656565, 0x59005959, 0xacac00ac
+.long 0xc3c3c300, 0x00878787, 0xe100e1e1, 0x36360036
+.long 0xb5b5b500, 0x006b6b6b, 0xda00dada, 0x2a2a002a
+.long 0x7a7a7a00, 0x00f4f4f4, 0x3d003d3d, 0x3c3c003c
+.long 0x91919100, 0x00232323, 0xc800c8c8, 0xf1f100f1
+.long 0x24242400, 0x00484848, 0x12001212, 0x40400040
+.long 0x08080800, 0x00101010, 0x04000404, 0xd3d300d3
+.long 0xe8e8e800, 0x00d1d1d1, 0x74007474, 0xbbbb00bb
+.long 0xa8a8a800, 0x00515151, 0x54005454, 0x43430043
+.long 0x60606000, 0x00c0c0c0, 0x30003030, 0x15150015
+.long 0xfcfcfc00, 0x00f9f9f9, 0x7e007e7e, 0xadad00ad
+.long 0x69696900, 0x00d2d2d2, 0xb400b4b4, 0x77770077
+.long 0x50505000, 0x00a0a0a0, 0x28002828, 0x80800080
+.long 0xaaaaaa00, 0x00555555, 0x55005555, 0x82820082
+.long 0xd0d0d000, 0x00a1a1a1, 0x68006868, 0xecec00ec
+.long 0xa0a0a000, 0x00414141, 0x50005050, 0x27270027
+.long 0x7d7d7d00, 0x00fafafa, 0xbe00bebe, 0xe5e500e5
+.long 0xa1a1a100, 0x00434343, 0xd000d0d0, 0x85850085
+.long 0x89898900, 0x00131313, 0xc400c4c4, 0x35350035
+.long 0x62626200, 0x00c4c4c4, 0x31003131, 0x0c0c000c
+.long 0x97979700, 0x002f2f2f, 0xcb00cbcb, 0x41410041
+.long 0x54545400, 0x00a8a8a8, 0x2a002a2a, 0xefef00ef
+.long 0x5b5b5b00, 0x00b6b6b6, 0xad00adad, 0x93930093
+.long 0x1e1e1e00, 0x003c3c3c, 0x0f000f0f, 0x19190019
+.long 0x95959500, 0x002b2b2b, 0xca00caca, 0x21210021
+.long 0xe0e0e000, 0x00c1c1c1, 0x70007070, 0x0e0e000e
+.long 0xffffff00, 0x00ffffff, 0xff00ffff, 0x4e4e004e
+.long 0x64646400, 0x00c8c8c8, 0x32003232, 0x65650065
+.long 0xd2d2d200, 0x00a5a5a5, 0x69006969, 0xbdbd00bd
+.long 0x10101000, 0x00202020, 0x08000808, 0xb8b800b8
+.long 0xc4c4c400, 0x00898989, 0x62006262, 0x8f8f008f
+.long 0x00000000, 0x00000000, 0x00000000, 0xebeb00eb
+.long 0x48484800, 0x00909090, 0x24002424, 0xcece00ce
+.long 0xa3a3a300, 0x00474747, 0xd100d1d1, 0x30300030
+.long 0xf7f7f700, 0x00efefef, 0xfb00fbfb, 0x5f5f005f
+.long 0x75757500, 0x00eaeaea, 0xba00baba, 0xc5c500c5
+.long 0xdbdbdb00, 0x00b7b7b7, 0xed00eded, 0x1a1a001a
+.long 0x8a8a8a00, 0x00151515, 0x45004545, 0xe1e100e1
+.long 0x03030300, 0x00060606, 0x81008181, 0xcaca00ca
+.long 0xe6e6e600, 0x00cdcdcd, 0x73007373, 0x47470047
+.long 0xdadada00, 0x00b5b5b5, 0x6d006d6d, 0x3d3d003d
+.long 0x09090900, 0x00121212, 0x84008484, 0x01010001
+.long 0x3f3f3f00, 0x007e7e7e, 0x9f009f9f, 0xd6d600d6
+.long 0xdddddd00, 0x00bbbbbb, 0xee00eeee, 0x56560056
+.long 0x94949400, 0x00292929, 0x4a004a4a, 0x4d4d004d
+.long 0x87878700, 0x000f0f0f, 0xc300c3c3, 0x0d0d000d
+.long 0x5c5c5c00, 0x00b8b8b8, 0x2e002e2e, 0x66660066
+.long 0x83838300, 0x00070707, 0xc100c1c1, 0xcccc00cc
+.long 0x02020200, 0x00040404, 0x01000101, 0x2d2d002d
+.long 0xcdcdcd00, 0x009b9b9b, 0xe600e6e6, 0x12120012
+.long 0x4a4a4a00, 0x00949494, 0x25002525, 0x20200020
+.long 0x90909000, 0x00212121, 0x48004848, 0xb1b100b1
+.long 0x33333300, 0x00666666, 0x99009999, 0x99990099
+.long 0x73737300, 0x00e6e6e6, 0xb900b9b9, 0x4c4c004c
+.long 0x67676700, 0x00cecece, 0xb300b3b3, 0xc2c200c2
+.long 0xf6f6f600, 0x00ededed, 0x7b007b7b, 0x7e7e007e
+.long 0xf3f3f300, 0x00e7e7e7, 0xf900f9f9, 0x05050005
+.long 0x9d9d9d00, 0x003b3b3b, 0xce00cece, 0xb7b700b7
+.long 0x7f7f7f00, 0x00fefefe, 0xbf00bfbf, 0x31310031
+.long 0xbfbfbf00, 0x007f7f7f, 0xdf00dfdf, 0x17170017
+.long 0xe2e2e200, 0x00c5c5c5, 0x71007171, 0xd7d700d7
+.long 0x52525200, 0x00a4a4a4, 0x29002929, 0x58580058
+.long 0x9b9b9b00, 0x00373737, 0xcd00cdcd, 0x61610061
+.long 0xd8d8d800, 0x00b1b1b1, 0x6c006c6c, 0x1b1b001b
+.long 0x26262600, 0x004c4c4c, 0x13001313, 0x1c1c001c
+.long 0xc8c8c800, 0x00919191, 0x64006464, 0x0f0f000f
+.long 0x37373700, 0x006e6e6e, 0x9b009b9b, 0x16160016
+.long 0xc6c6c600, 0x008d8d8d, 0x63006363, 0x18180018
+.long 0x3b3b3b00, 0x00767676, 0x9d009d9d, 0x22220022
+.long 0x81818100, 0x00030303, 0xc000c0c0, 0x44440044
+.long 0x96969600, 0x002d2d2d, 0x4b004b4b, 0xb2b200b2
+.long 0x6f6f6f00, 0x00dedede, 0xb700b7b7, 0xb5b500b5
+.long 0x4b4b4b00, 0x00969696, 0xa500a5a5, 0x91910091
+.long 0x13131300, 0x00262626, 0x89008989, 0x08080008
+.long 0xbebebe00, 0x007d7d7d, 0x5f005f5f, 0xa8a800a8
+.long 0x63636300, 0x00c6c6c6, 0xb100b1b1, 0xfcfc00fc
+.long 0x2e2e2e00, 0x005c5c5c, 0x17001717, 0x50500050
+.long 0xe9e9e900, 0x00d3d3d3, 0xf400f4f4, 0xd0d000d0
+.long 0x79797900, 0x00f2f2f2, 0xbc00bcbc, 0x7d7d007d
+.long 0xa7a7a700, 0x004f4f4f, 0xd300d3d3, 0x89890089
+.long 0x8c8c8c00, 0x00191919, 0x46004646, 0x97970097
+.long 0x9f9f9f00, 0x003f3f3f, 0xcf00cfcf, 0x5b5b005b
+.long 0x6e6e6e00, 0x00dcdcdc, 0x37003737, 0x95950095
+.long 0xbcbcbc00, 0x00797979, 0x5e005e5e, 0xffff00ff
+.long 0x8e8e8e00, 0x001d1d1d, 0x47004747, 0xd2d200d2
+.long 0x29292900, 0x00525252, 0x94009494, 0xc4c400c4
+.long 0xf5f5f500, 0x00ebebeb, 0xfa00fafa, 0x48480048
+.long 0xf9f9f900, 0x00f3f3f3, 0xfc00fcfc, 0xf7f700f7
+.long 0xb6b6b600, 0x006d6d6d, 0x5b005b5b, 0xdbdb00db
+.long 0x2f2f2f00, 0x005e5e5e, 0x97009797, 0x03030003
+.long 0xfdfdfd00, 0x00fbfbfb, 0xfe00fefe, 0xdada00da
+.long 0xb4b4b400, 0x00696969, 0x5a005a5a, 0x3f3f003f
+.long 0x59595900, 0x00b2b2b2, 0xac00acac, 0x94940094
+.long 0x78787800, 0x00f0f0f0, 0x3c003c3c, 0x5c5c005c
+.long 0x98989800, 0x00313131, 0x4c004c4c, 0x02020002
+.long 0x06060600, 0x000c0c0c, 0x03000303, 0x4a4a004a
+.long 0x6a6a6a00, 0x00d4d4d4, 0x35003535, 0x33330033
+.long 0xe7e7e700, 0x00cfcfcf, 0xf300f3f3, 0x67670067
+.long 0x46464600, 0x008c8c8c, 0x23002323, 0xf3f300f3
+.long 0x71717100, 0x00e2e2e2, 0xb800b8b8, 0x7f7f007f
+.long 0xbababa00, 0x00757575, 0x5d005d5d, 0xe2e200e2
+.long 0xd4d4d400, 0x00a9a9a9, 0x6a006a6a, 0x9b9b009b
+.long 0x25252500, 0x004a4a4a, 0x92009292, 0x26260026
+.long 0xababab00, 0x00575757, 0xd500d5d5, 0x37370037
+.long 0x42424200, 0x00848484, 0x21002121, 0x3b3b003b
+.long 0x88888800, 0x00111111, 0x44004444, 0x96960096
+.long 0xa2a2a200, 0x00454545, 0x51005151, 0x4b4b004b
+.long 0x8d8d8d00, 0x001b1b1b, 0xc600c6c6, 0xbebe00be
+.long 0xfafafa00, 0x00f5f5f5, 0x7d007d7d, 0x2e2e002e
+.long 0x72727200, 0x00e4e4e4, 0x39003939, 0x79790079
+.long 0x07070700, 0x000e0e0e, 0x83008383, 0x8c8c008c
+.long 0xb9b9b900, 0x00737373, 0xdc00dcdc, 0x6e6e006e
+.long 0x55555500, 0x00aaaaaa, 0xaa00aaaa, 0x8e8e008e
+.long 0xf8f8f800, 0x00f1f1f1, 0x7c007c7c, 0xf5f500f5
+.long 0xeeeeee00, 0x00dddddd, 0x77007777, 0xb6b600b6
+.long 0xacacac00, 0x00595959, 0x56005656, 0xfdfd00fd
+.long 0x0a0a0a00, 0x00141414, 0x05000505, 0x59590059
+.long 0x36363600, 0x006c6c6c, 0x1b001b1b, 0x98980098
+.long 0x49494900, 0x00929292, 0xa400a4a4, 0x6a6a006a
+.long 0x2a2a2a00, 0x00545454, 0x15001515, 0x46460046
+.long 0x68686800, 0x00d0d0d0, 0x34003434, 0xbaba00ba
+.long 0x3c3c3c00, 0x00787878, 0x1e001e1e, 0x25250025
+.long 0x38383800, 0x00707070, 0x1c001c1c, 0x42420042
+.long 0xf1f1f100, 0x00e3e3e3, 0xf800f8f8, 0xa2a200a2
+.long 0xa4a4a400, 0x00494949, 0x52005252, 0xfafa00fa
+.long 0x40404000, 0x00808080, 0x20002020, 0x07070007
+.long 0x28282800, 0x00505050, 0x14001414, 0x55550055
+.long 0xd3d3d300, 0x00a7a7a7, 0xe900e9e9, 0xeeee00ee
+.long 0x7b7b7b00, 0x00f6f6f6, 0xbd00bdbd, 0x0a0a000a
+.long 0xbbbbbb00, 0x00777777, 0xdd00dddd, 0x49490049
+.long 0xc9c9c900, 0x00939393, 0xe400e4e4, 0x68680068
+.long 0x43434300, 0x00868686, 0xa100a1a1, 0x38380038
+.long 0xc1c1c100, 0x00838383, 0xe000e0e0, 0xa4a400a4
+.long 0x15151500, 0x002a2a2a, 0x8a008a8a, 0x28280028
+.long 0xe3e3e300, 0x00c7c7c7, 0xf100f1f1, 0x7b7b007b
+.long 0xadadad00, 0x005b5b5b, 0xd600d6d6, 0xc9c900c9
+.long 0xf4f4f400, 0x00e9e9e9, 0x7a007a7a, 0xc1c100c1
+.long 0x77777700, 0x00eeeeee, 0xbb00bbbb, 0xe3e300e3
+.long 0xc7c7c700, 0x008f8f8f, 0xe300e3e3, 0xf4f400f4
+.long 0x80808000, 0x00010101, 0x40004040, 0xc7c700c7
+.long 0x9e9e9e00, 0x003d3d3d, 0x4f004f4f, 0x9e9e009e
+
+#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
+#endif /*__ARM_ARCH >= 6*/
diff --git a/comm/third_party/libgcrypt/cipher/camellia-glue.c b/comm/third_party/libgcrypt/cipher/camellia-glue.c
new file mode 100644
index 0000000000..6577b6516a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/camellia-glue.c
@@ -0,0 +1,1097 @@
+/* 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 <config.h>
+#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 <config.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "camellia.h"
+#include "bufhelp.h"
+#include "cipher-internal.h"
+#include "cipher-selftest.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
+
+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. */
+#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 block 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;
+#endif
+
+#ifdef USE_AESNI_AVX2
+/* Assembler implementations of Camellia using AES-NI and AVX2. Process data
+ in 32 block 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;
+#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 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)
+ 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);
+#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;
+
+ 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. */
+ );
+ }
+
+ 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*/
+
+/* 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;
+ unsigned char tmpbuf[CAMELLIA_BLOCK_SIZE];
+ int burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
+
+#ifdef USE_AESNI_AVX2
+ if (ctx->use_aesni_avx2)
+ {
+ int did_use_aesni_avx2 = 0;
+
+ /* Process data in 32 block chunks. */
+ while (nblocks >= 32)
+ {
+ _gcry_camellia_aesni_avx2_ctr_enc(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)
+ {
+ int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ if (burn_stack_depth < avx2_burn_stack_depth)
+ burn_stack_depth = avx2_burn_stack_depth;
+ }
+
+ /* Use generic code to handle smaller chunks... */
+ /* TODO: use caching instead? */
+ }
+#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)
+ {
+ int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ if (burn_stack_depth < avx_burn_stack_depth)
+ burn_stack_depth = avx_burn_stack_depth;
+ }
+
+ /* Use generic code to handle smaller chunks... */
+ /* TODO: use caching instead? */
+ }
+#endif
+
+ for ( ;nblocks; nblocks-- )
+ {
+ /* Encrypt the counter. */
+ Camellia_EncryptBlock(ctx->keybitlength, ctr, ctx->keytable, tmpbuf);
+ /* XOR the input with the encrypted counter and store in output. */
+ cipher_block_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE);
+ outbuf += CAMELLIA_BLOCK_SIZE;
+ inbuf += CAMELLIA_BLOCK_SIZE;
+ /* Increment the counter. */
+ cipher_block_add(ctr, 1, CAMELLIA_BLOCK_SIZE);
+ }
+
+ 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_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;
+ unsigned char savebuf[CAMELLIA_BLOCK_SIZE];
+ int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
+
+#ifdef USE_AESNI_AVX2
+ if (ctx->use_aesni_avx2)
+ {
+ int did_use_aesni_avx2 = 0;
+
+ /* Process data in 32 block chunks. */
+ while (nblocks >= 32)
+ {
+ _gcry_camellia_aesni_avx2_cbc_dec(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)
+ {
+ int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;;
+
+ 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)
+ {
+ int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ if (burn_stack_depth < avx_burn_stack_depth)
+ burn_stack_depth = avx_burn_stack_depth;
+ }
+
+ /* 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. */
+ Camellia_DecryptBlock(ctx->keybitlength, inbuf, ctx->keytable, savebuf);
+
+ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf,
+ CAMELLIA_BLOCK_SIZE);
+ inbuf += CAMELLIA_BLOCK_SIZE;
+ outbuf += CAMELLIA_BLOCK_SIZE;
+ }
+
+ 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_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 = CAMELLIA_decrypt_stack_burn_size;
+
+#ifdef USE_AESNI_AVX2
+ if (ctx->use_aesni_avx2)
+ {
+ int did_use_aesni_avx2 = 0;
+
+ /* Process data in 32 block chunks. */
+ while (nblocks >= 32)
+ {
+ _gcry_camellia_aesni_avx2_cfb_dec(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)
+ {
+ int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ 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)
+ {
+ int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ if (burn_stack_depth < avx_burn_stack_depth)
+ burn_stack_depth = avx_burn_stack_depth;
+ }
+
+ /* Use generic code to handle smaller chunks... */
+ }
+#endif
+
+ for ( ;nblocks; nblocks-- )
+ {
+ Camellia_EncryptBlock(ctx->keybitlength, iv, ctx->keytable, iv);
+ cipher_block_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
+ outbuf += CAMELLIA_BLOCK_SIZE;
+ inbuf += CAMELLIA_BLOCK_SIZE;
+ }
+
+ _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;
+ u64 blkn = c->u_mode.ocb.data_nblocks;
+
+ burn_stack_depth = encrypt ? CAMELLIA_encrypt_stack_burn_size :
+ CAMELLIA_decrypt_stack_burn_size;
+#else
+ (void)c;
+ (void)outbuf_arg;
+ (void)inbuf_arg;
+ (void)encrypt;
+#endif
+
+#ifdef USE_AESNI_AVX2
+ if (ctx->use_aesni_avx2)
+ {
+ int did_use_aesni_avx2 = 0;
+ u64 Ls[32];
+ unsigned int n = 32 - (blkn % 32);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 32)
+ {
+ for (i = 0; i < 32; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ Ls[(15 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[4];
+ Ls[(23 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(31 + n) % 32];
+
+ /* Process data in 32 block chunks. */
+ while (nblocks >= 32)
+ {
+ blkn += 32;
+ *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 32);
+
+ if (encrypt)
+ _gcry_camellia_aesni_avx2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
+ c->u_ctr.ctr, Ls);
+ else
+ _gcry_camellia_aesni_avx2_ocb_dec(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)
+ {
+ int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ 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];
+ unsigned int n = 16 - (blkn % 16);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 16)
+ {
+ for (i = 0; i < 16; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(15 + n) % 16];
+
+ /* 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)
+ {
+ int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ 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)
+ 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;
+ u64 blkn = c->u_mode.ocb.aad_nblocks;
+
+ burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
+#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];
+ unsigned int n = 32 - (blkn % 32);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 32)
+ {
+ for (i = 0; i < 32; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ Ls[(15 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[4];
+ Ls[(23 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(31 + n) % 32];
+
+ /* Process data in 32 block chunks. */
+ while (nblocks >= 32)
+ {
+ blkn += 32;
+ *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 32);
+
+ _gcry_camellia_aesni_avx2_ocb_auth(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)
+ {
+ int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ 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];
+ unsigned int n = 16 - (blkn % 16);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 16)
+ {
+ for (i = 0; i < 16; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(15 + n) % 16];
+
+ /* 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)
+ {
+ int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
+ 2 * sizeof(void *) + ASM_EXTRA_STACK;
+
+ 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)
+ 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 = 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 = 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 = 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
+ <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
+ retrieved May 1, 2007. */
+
+static 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 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 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/comm/third_party/libgcrypt/cipher/camellia.c b/comm/third_party/libgcrypt/cipher/camellia.c
new file mode 100644
index 0000000000..e7085a7ec8
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/camellia.c
@@ -0,0 +1,1413 @@
+/* camellia.h ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This library 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.
+ *
+ * This library 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "types.h"
+#include "bufhelp.h"
+#include "camellia.h"
+
+typedef byte u8;
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L (0xA09E667FL)
+#define CAMELLIA_SIGMA1R (0x3BCC908BL)
+#define CAMELLIA_SIGMA2L (0xB67AE858L)
+#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L (0xC6EF372FL)
+#define CAMELLIA_SIGMA3R (0xE94F82BEL)
+#define CAMELLIA_SIGMA4L (0x54FF53A5L)
+#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L (0x10E527FAL)
+#define CAMELLIA_SIGMA5R (0xDE682D1DL)
+#define CAMELLIA_SIGMA6L (0xB05688C2L)
+#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
+
+/*
+ * macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt) buf_get_be32(pt)
+# define PUTU32(ct, st) buf_put_be32(ct, st)
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ ll = (ll << bits) + (lr >> (32 - bits)); \
+ lr = (lr << bits) + (rl >> (32 - bits)); \
+ rl = (rl << bits) + (rr >> (32 - bits)); \
+ rr = (rr << bits) + (w0 >> (32 - bits)); \
+ } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ w1 = lr; \
+ ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
+ lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
+ rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
+ rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
+ } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ il = xl ^ kl; \
+ ir = xr ^ kr; \
+ t0 = il >> 16; \
+ t1 = ir >> 16; \
+ yl = CAMELLIA_SP1110(ir & 0xff) \
+ ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \
+ ^ CAMELLIA_SP3033(t1 & 0xff) \
+ ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \
+ yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \
+ ^ CAMELLIA_SP0222(t0 & 0xff) \
+ ^ CAMELLIA_SP3033((il >> 8) & 0xff) \
+ ^ CAMELLIA_SP4404(il & 0xff); \
+ yl ^= yr; \
+ yr = CAMELLIA_RR8(yr); \
+ yr ^= yl; \
+ } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+ do { \
+ t0 = kll; \
+ t0 &= ll; \
+ lr ^= CAMELLIA_RL1(t0); \
+ t1 = klr; \
+ t1 |= lr; \
+ ll ^= t1; \
+ \
+ t2 = krr; \
+ t2 |= rr; \
+ rl ^= t2; \
+ t3 = krl; \
+ t3 &= rl; \
+ rr ^= CAMELLIA_RL1(t3); \
+ } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ yl ^= kl; \
+ yr ^= kr; \
+ ir = CAMELLIA_SP1110(xr & 0xff) \
+ ^ CAMELLIA_SP0222((xr >> 24) & 0xff) \
+ ^ CAMELLIA_SP3033((xr >> 16) & 0xff) \
+ ^ CAMELLIA_SP4404((xr >> 8) & 0xff); \
+ il = CAMELLIA_SP1110((xl >> 24) & 0xff) \
+ ^ CAMELLIA_SP0222((xl >> 16) & 0xff) \
+ ^ CAMELLIA_SP3033((xl >> 8) & 0xff) \
+ ^ CAMELLIA_SP4404(xl & 0xff); \
+ ir ^= il; \
+ il = CAMELLIA_RR8(il); \
+ il ^= ir; \
+ yl ^= ir; \
+ yr ^= il; \
+ } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+ 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+ 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+ 0xe4e4e400,0x85858500,0x57575700,0x35353500,
+ 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+ 0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+ 0x45454500,0x19191900,0xa5a5a500,0x21212100,
+ 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+ 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+ 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+ 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+ 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+ 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+ 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+ 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+ 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+ 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+ 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+ 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+ 0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+ 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+ 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+ 0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+ 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+ 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+ 0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+ 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+ 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+ 0x53535300,0x18181800,0xf2f2f200,0x22222200,
+ 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+ 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+ 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+ 0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+ 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+ 0xa1a1a100,0x89898900,0x62626200,0x97979700,
+ 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+ 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+ 0x10101000,0xc4c4c400,0x00000000,0x48484800,
+ 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+ 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+ 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+ 0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+ 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+ 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+ 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+ 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+ 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+ 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+ 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+ 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+ 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+ 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+ 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+ 0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+ 0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+ 0xd4d4d400,0x25252500,0xababab00,0x42424200,
+ 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+ 0x72727200,0x07070700,0xb9b9b900,0x55555500,
+ 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+ 0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+ 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+ 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+ 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+ 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+ 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+ 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+ 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+ 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+ 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+ 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+ 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+ 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+ 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+ 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+ 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+ 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+ 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+ 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+ 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+ 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+ 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+ 0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+ 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+ 0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+ 0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+ 0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+ 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+ 0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+ 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+ 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+ 0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+ 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+ 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+ 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+ 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+ 0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+ 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+ 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+ 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+ 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+ 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+ 0x00202020,0x00898989,0x00000000,0x00909090,
+ 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+ 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+ 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+ 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+ 0x009b9b9b,0x00949494,0x00212121,0x00666666,
+ 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+ 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+ 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+ 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+ 0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+ 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+ 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+ 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+ 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+ 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+ 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+ 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+ 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+ 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+ 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+ 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+ 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+ 0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+ 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+ 0x00777777,0x00939393,0x00868686,0x00838383,
+ 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+ 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+ 0x38003838,0x41004141,0x16001616,0x76007676,
+ 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+ 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+ 0x75007575,0x06000606,0x57005757,0xa000a0a0,
+ 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+ 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+ 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+ 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+ 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+ 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+ 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+ 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+ 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+ 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+ 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+ 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+ 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+ 0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+ 0x3a003a3a,0x09000909,0x95009595,0x10001010,
+ 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+ 0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+ 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+ 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+ 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+ 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+ 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+ 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+ 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+ 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+ 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+ 0x12001212,0x04000404,0x74007474,0x54005454,
+ 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+ 0x55005555,0x68006868,0x50005050,0xbe00bebe,
+ 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+ 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+ 0x70007070,0xff00ffff,0x32003232,0x69006969,
+ 0x08000808,0x62006262,0x00000000,0x24002424,
+ 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+ 0x45004545,0x81008181,0x73007373,0x6d006d6d,
+ 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+ 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+ 0xe600e6e6,0x25002525,0x48004848,0x99009999,
+ 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+ 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+ 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+ 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+ 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+ 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+ 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+ 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+ 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+ 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+ 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+ 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+ 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+ 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+ 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+ 0x7c007c7c,0x77007777,0x56005656,0x05000505,
+ 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+ 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+ 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+ 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+ 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+ 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+ 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+ 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+ 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+ 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+ 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+ 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+ 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+ 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+ 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+ 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+ 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+ 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+ 0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+ 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+ 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+ 0x24240024,0xe8e800e8,0x60600060,0x69690069,
+ 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+ 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+ 0x10100010,0x00000000,0xa3a300a3,0x75750075,
+ 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+ 0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+ 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+ 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+ 0x81810081,0x6f6f006f,0x13130013,0x63630063,
+ 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+ 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+ 0x78780078,0x06060006,0xe7e700e7,0x71710071,
+ 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+ 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+ 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+ 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+ 0x15150015,0xadad00ad,0x77770077,0x80800080,
+ 0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+ 0x85850085,0x35350035,0x0c0c000c,0x41410041,
+ 0xefef00ef,0x93930093,0x19190019,0x21210021,
+ 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+ 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+ 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+ 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+ 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+ 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+ 0x12120012,0x20200020,0xb1b100b1,0x99990099,
+ 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+ 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+ 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+ 0x0f0f000f,0x16160016,0x18180018,0x22220022,
+ 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+ 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+ 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+ 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+ 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+ 0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+ 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+ 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+ 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+ 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+ 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+ 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+ 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+ 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+ 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+ 0x49490049,0x68680068,0x38380038,0xa4a400a4,
+ 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+ 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+void camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+ u32 kll, klr, krl, krr;
+ u32 il, ir, t0, t1, w0, w1;
+ u32 kw4l, kw4r, dw, tl, tr;
+ u32 subL[26];
+ u32 subR[26];
+
+ /**
+ * k == kll || klr || krl || krr (|| is concatination)
+ */
+ kll = GETU32(key );
+ klr = GETU32(key + 4);
+ krl = GETU32(key + 8);
+ krr = GETU32(key + 12);
+ /**
+ * generate KL dependent subkeys
+ */
+ subl(0) = kll; subr(0) = klr;
+ subl(1) = krl; subr(1) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(4) = kll; subr(4) = klr;
+ subl(5) = krl; subr(5) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subl(10) = kll; subr(10) = klr;
+ subl(11) = krl; subr(11) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(13) = krl; subr(13) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(16) = kll; subr(16) = klr;
+ subl(17) = krl; subr(17) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(18) = kll; subr(18) = klr;
+ subl(19) = krl; subr(19) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(22) = kll; subr(22) = klr;
+ subl(23) = krl; subr(23) = krr;
+
+ /* generate KA */
+ kll = subl(0); klr = subr(0);
+ krl = subl(1); krr = subr(1);
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+ w0, w1, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+ kll, klr, il, ir, t0, t1);
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+ krl, krr, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0; klr ^= w1;
+
+ /* generate KA dependent subkeys */
+ subl(2) = kll; subr(2) = klr;
+ subl(3) = krl; subr(3) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(6) = kll; subr(6) = klr;
+ subl(7) = krl; subr(7) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(8) = kll; subr(8) = klr;
+ subl(9) = krl; subr(9) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(12) = kll; subr(12) = klr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(14) = kll; subr(14) = klr;
+ subl(15) = krl; subr(15) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subl(20) = kll; subr(20) = klr;
+ subl(21) = krl; subr(21) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(24) = kll; subr(24) = klr;
+ subl(25) = krl; subr(25) = krr;
+
+
+ /* absorb kw2 to other subkeys */
+ subl(3) ^= subl(1); subr(3) ^= subr(1);
+ subl(5) ^= subl(1); subr(5) ^= subr(1);
+ subl(7) ^= subl(1); subr(7) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(9);
+ dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(11) ^= subl(1); subr(11) ^= subr(1);
+ subl(13) ^= subl(1); subr(13) ^= subr(1);
+ subl(15) ^= subl(1); subr(15) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(17);
+ dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(19) ^= subl(1); subr(19) ^= subr(1);
+ subl(21) ^= subl(1); subr(21) ^= subr(1);
+ subl(23) ^= subl(1); subr(23) ^= subr(1);
+ subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subl(25); kw4r = subr(25);
+ subl(22) ^= kw4l; subr(22) ^= kw4r;
+ subl(20) ^= kw4l; subr(20) ^= kw4r;
+ subl(18) ^= kw4l; subr(18) ^= kw4r;
+ kw4l ^= kw4r & ~subr(16);
+ dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+ subl(14) ^= kw4l; subr(14) ^= kw4r;
+ subl(12) ^= kw4l; subr(12) ^= kw4r;
+ subl(10) ^= kw4l; subr(10) ^= kw4r;
+ kw4l ^= kw4r & ~subr(8);
+ dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+ subl(6) ^= kw4l; subr(6) ^= kw4r;
+ subl(4) ^= kw4l; subr(4) ^= kw4r;
+ subl(2) ^= kw4l; subr(2) ^= kw4r;
+ subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+ /* key XOR is end of F-function */
+ CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+ CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+ CamelliaSubkeyL(2) = subl(3);
+ CamelliaSubkeyR(2) = subr(3);
+ CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+ CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+ CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+ CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+ CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+ CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+ CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+ CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+ tl = subl(10) ^ (subr(10) & ~subr(8));
+ dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(7) = subl(6) ^ tl;
+ CamelliaSubkeyR(7) = subr(6) ^ tr;
+ CamelliaSubkeyL(8) = subl(8);
+ CamelliaSubkeyR(8) = subr(8);
+ CamelliaSubkeyL(9) = subl(9);
+ CamelliaSubkeyR(9) = subr(9);
+ tl = subl(7) ^ (subr(7) & ~subr(9));
+ dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(10) = tl ^ subl(11);
+ CamelliaSubkeyR(10) = tr ^ subr(11);
+ CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+ CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+ CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+ CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+ CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+ CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+ CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+ CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+ tl = subl(18) ^ (subr(18) & ~subr(16));
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(15) = subl(14) ^ tl;
+ CamelliaSubkeyR(15) = subr(14) ^ tr;
+ CamelliaSubkeyL(16) = subl(16);
+ CamelliaSubkeyR(16) = subr(16);
+ CamelliaSubkeyL(17) = subl(17);
+ CamelliaSubkeyR(17) = subr(17);
+ tl = subl(15) ^ (subr(15) & ~subr(17));
+ dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(18) = tl ^ subl(19);
+ CamelliaSubkeyR(18) = tr ^ subr(19);
+ CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+ CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+ CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+ CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+ CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+ CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+ CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+ CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+ CamelliaSubkeyL(23) = subl(22);
+ CamelliaSubkeyR(23) = subr(22);
+ CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+ CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+ return;
+}
+
+void camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+ u32 kll,klr,krl,krr; /* left half of key */
+ u32 krll,krlr,krrl,krrr; /* right half of key */
+ u32 il, ir, t0, t1, w0, w1; /* temporary variables */
+ u32 kw4l, kw4r, dw, tl, tr;
+ u32 subL[34];
+ u32 subR[34];
+
+ /**
+ * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+ * (|| is concatination)
+ */
+
+ kll = GETU32(key );
+ klr = GETU32(key + 4);
+ krl = GETU32(key + 8);
+ krr = GETU32(key + 12);
+ krll = GETU32(key + 16);
+ krlr = GETU32(key + 20);
+ krrl = GETU32(key + 24);
+ krrr = GETU32(key + 28);
+
+ /* generate KL dependent subkeys */
+ subl(0) = kll; subr(0) = klr;
+ subl(1) = krl; subr(1) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+ subl(12) = kll; subr(12) = klr;
+ subl(13) = krl; subr(13) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(16) = kll; subr(16) = klr;
+ subl(17) = krl; subr(17) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(22) = kll; subr(22) = klr;
+ subl(23) = krl; subr(23) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subl(30) = kll; subr(30) = klr;
+ subl(31) = krl; subr(31) = krr;
+
+ /* generate KR dependent subkeys */
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subl(4) = krll; subr(4) = krlr;
+ subl(5) = krrl; subr(5) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subl(8) = krll; subr(8) = krlr;
+ subl(9) = krrl; subr(9) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(18) = krll; subr(18) = krlr;
+ subl(19) = krrl; subr(19) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+ subl(26) = krll; subr(26) = krlr;
+ subl(27) = krrl; subr(27) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+ /* generate KA */
+ kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+ krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+ w0, w1, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+ kll, klr, il, ir, t0, t1);
+ kll ^= krll; klr ^= krlr;
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+ krl, krr, il, ir, t0, t1);
+ krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0; klr ^= w1;
+
+ /* generate KB */
+ krll ^= kll; krlr ^= klr;
+ krrl ^= krl; krrr ^= krr;
+ CAMELLIA_F(krll, krlr,
+ CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+ w0, w1, il, ir, t0, t1);
+ krrl ^= w0; krrr ^= w1;
+ CAMELLIA_F(krrl, krrr,
+ CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+ w0, w1, il, ir, t0, t1);
+ krll ^= w0; krlr ^= w1;
+
+ /* generate KA dependent subkeys */
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(6) = kll; subr(6) = klr;
+ subl(7) = krl; subr(7) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subl(14) = kll; subr(14) = klr;
+ subl(15) = krl; subr(15) = krr;
+ subl(24) = klr; subr(24) = krl;
+ subl(25) = krr; subr(25) = kll;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+ subl(28) = kll; subr(28) = klr;
+ subl(29) = krl; subr(29) = krr;
+
+ /* generate KB dependent subkeys */
+ subl(2) = krll; subr(2) = krlr;
+ subl(3) = krrl; subr(3) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(10) = krll; subr(10) = krlr;
+ subl(11) = krrl; subr(11) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(20) = krll; subr(20) = krlr;
+ subl(21) = krrl; subr(21) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+ subl(32) = krll; subr(32) = krlr;
+ subl(33) = krrl; subr(33) = krrr;
+
+ /* absorb kw2 to other subkeys */
+ subl(3) ^= subl(1); subr(3) ^= subr(1);
+ subl(5) ^= subl(1); subr(5) ^= subr(1);
+ subl(7) ^= subl(1); subr(7) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(9);
+ dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(11) ^= subl(1); subr(11) ^= subr(1);
+ subl(13) ^= subl(1); subr(13) ^= subr(1);
+ subl(15) ^= subl(1); subr(15) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(17);
+ dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(19) ^= subl(1); subr(19) ^= subr(1);
+ subl(21) ^= subl(1); subr(21) ^= subr(1);
+ subl(23) ^= subl(1); subr(23) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(25);
+ dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(27) ^= subl(1); subr(27) ^= subr(1);
+ subl(29) ^= subl(1); subr(29) ^= subr(1);
+ subl(31) ^= subl(1); subr(31) ^= subr(1);
+ subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subl(33); kw4r = subr(33);
+ subl(30) ^= kw4l; subr(30) ^= kw4r;
+ subl(28) ^= kw4l; subr(28) ^= kw4r;
+ subl(26) ^= kw4l; subr(26) ^= kw4r;
+ kw4l ^= kw4r & ~subr(24);
+ dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+ subl(22) ^= kw4l; subr(22) ^= kw4r;
+ subl(20) ^= kw4l; subr(20) ^= kw4r;
+ subl(18) ^= kw4l; subr(18) ^= kw4r;
+ kw4l ^= kw4r & ~subr(16);
+ dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+ subl(14) ^= kw4l; subr(14) ^= kw4r;
+ subl(12) ^= kw4l; subr(12) ^= kw4r;
+ subl(10) ^= kw4l; subr(10) ^= kw4r;
+ kw4l ^= kw4r & ~subr(8);
+ dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+ subl(6) ^= kw4l; subr(6) ^= kw4r;
+ subl(4) ^= kw4l; subr(4) ^= kw4r;
+ subl(2) ^= kw4l; subr(2) ^= kw4r;
+ subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+ /* key XOR is end of F-function */
+ CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+ CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+ CamelliaSubkeyL(2) = subl(3);
+ CamelliaSubkeyR(2) = subr(3);
+ CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+ CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+ CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+ CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+ CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+ CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+ CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+ CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+ tl = subl(10) ^ (subr(10) & ~subr(8));
+ dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(7) = subl(6) ^ tl;
+ CamelliaSubkeyR(7) = subr(6) ^ tr;
+ CamelliaSubkeyL(8) = subl(8);
+ CamelliaSubkeyR(8) = subr(8);
+ CamelliaSubkeyL(9) = subl(9);
+ CamelliaSubkeyR(9) = subr(9);
+ tl = subl(7) ^ (subr(7) & ~subr(9));
+ dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(10) = tl ^ subl(11);
+ CamelliaSubkeyR(10) = tr ^ subr(11);
+ CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+ CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+ CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+ CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+ CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+ CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+ CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+ CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+ tl = subl(18) ^ (subr(18) & ~subr(16));
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(15) = subl(14) ^ tl;
+ CamelliaSubkeyR(15) = subr(14) ^ tr;
+ CamelliaSubkeyL(16) = subl(16);
+ CamelliaSubkeyR(16) = subr(16);
+ CamelliaSubkeyL(17) = subl(17);
+ CamelliaSubkeyR(17) = subr(17);
+ tl = subl(15) ^ (subr(15) & ~subr(17));
+ dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(18) = tl ^ subl(19);
+ CamelliaSubkeyR(18) = tr ^ subr(19);
+ CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+ CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+ CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+ CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+ CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+ CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+ CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+ CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+ tl = subl(26) ^ (subr(26) & ~subr(24));
+ dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(23) = subl(22) ^ tl;
+ CamelliaSubkeyR(23) = subr(22) ^ tr;
+ CamelliaSubkeyL(24) = subl(24);
+ CamelliaSubkeyR(24) = subr(24);
+ CamelliaSubkeyL(25) = subl(25);
+ CamelliaSubkeyR(25) = subr(25);
+ tl = subl(23) ^ (subr(23) & ~subr(25));
+ dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(26) = tl ^ subl(27);
+ CamelliaSubkeyR(26) = tr ^ subr(27);
+ CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+ CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+ CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+ CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+ CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+ CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+ CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+ CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+ CamelliaSubkeyL(31) = subl(30);
+ CamelliaSubkeyR(31) = subr(30);
+ CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+ CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+ return;
+}
+
+void camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+ unsigned char kk[32];
+ u32 krll, krlr, krrl,krrr;
+
+ memcpy(kk, key, 24);
+ memcpy((unsigned char *)&krll, key+16,4);
+ memcpy((unsigned char *)&krlr, key+20,4);
+ krrl = ~krll;
+ krrr = ~krlr;
+ memcpy(kk+24, (unsigned char *)&krrl, 4);
+ memcpy(kk+28, (unsigned char *)&krrr, 4);
+ camellia_setup256(kk, subkey);
+ return;
+}
+
+
+#ifndef USE_ARM_ASM
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+void camellia_encrypt128(const u32 *subkey, u32 *blocks)
+{
+ u32 il, ir, t0, t1;
+ u32 io[4];
+
+ io[0] = blocks[0];
+ io[1] = blocks[1];
+ io[2] = blocks[2];
+ io[3] = blocks[3];
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(0);
+ io[1] ^= CamelliaSubkeyR(0);
+ /* main iteration */
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(24);
+ io[3] ^= CamelliaSubkeyR(24);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ blocks[0] = io[0];
+ blocks[1] = io[1];
+ blocks[2] = io[2];
+ blocks[3] = io[3];
+
+ return;
+}
+
+void camellia_decrypt128(const u32 *subkey, u32 *blocks)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+ u32 io[4];
+
+ io[0] = blocks[0];
+ io[1] = blocks[1];
+ io[2] = blocks[2];
+ io[3] = blocks[3];
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(24);
+ io[1] ^= CamelliaSubkeyR(24);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(0);
+ io[3] ^= CamelliaSubkeyR(0);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ blocks[0] = io[0];
+ blocks[1] = io[1];
+ blocks[2] = io[2];
+ blocks[3] = io[3];
+
+ return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+void camellia_encrypt256(const u32 *subkey, u32 *blocks)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+ u32 io[4];
+
+ io[0] = blocks[0];
+ io[1] = blocks[1];
+ io[2] = blocks[2];
+ io[3] = blocks[3];
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(0);
+ io[1] ^= CamelliaSubkeyR(0);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+ CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(32);
+ io[3] ^= CamelliaSubkeyR(32);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ blocks[0] = io[0];
+ blocks[1] = io[1];
+ blocks[2] = io[2];
+ blocks[3] = io[3];
+
+ return;
+}
+
+void camellia_decrypt256(const u32 *subkey, u32 *blocks)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+ u32 io[4];
+
+ io[0] = blocks[0];
+ io[1] = blocks[1];
+ io[2] = blocks[2];
+ io[3] = blocks[3];
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(32);
+ io[1] ^= CamelliaSubkeyR(32);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+ CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(0);
+ io[3] ^= CamelliaSubkeyR(0);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ blocks[0] = io[0];
+ blocks[1] = io[1];
+ blocks[2] = io[2];
+ blocks[3] = io[3];
+
+ return;
+}
+#endif /*!USE_ARM_ASM*/
+
+
+/***
+ *
+ * API for compatibility
+ */
+
+void Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
+ KEY_TABLE_TYPE keyTable)
+{
+ switch(keyBitLength) {
+ case 128:
+ camellia_setup128(rawKey, keyTable);
+ break;
+ case 192:
+ camellia_setup192(rawKey, keyTable);
+ break;
+ case 256:
+ camellia_setup256(rawKey, keyTable);
+ break;
+ default:
+ break;
+ }
+}
+
+
+#ifndef USE_ARM_ASM
+void Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *ciphertext)
+{
+ u32 tmp[4];
+
+ tmp[0] = GETU32(plaintext);
+ tmp[1] = GETU32(plaintext + 4);
+ tmp[2] = GETU32(plaintext + 8);
+ tmp[3] = GETU32(plaintext + 12);
+
+ switch (keyBitLength) {
+ case 128:
+ camellia_encrypt128(keyTable, tmp);
+ break;
+ case 192:
+ /* fall through */
+ case 256:
+ camellia_encrypt256(keyTable, tmp);
+ break;
+ default:
+ break;
+ }
+
+ PUTU32(ciphertext, tmp[0]);
+ PUTU32(ciphertext + 4, tmp[1]);
+ PUTU32(ciphertext + 8, tmp[2]);
+ PUTU32(ciphertext + 12, tmp[3]);
+}
+
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *ciphertext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *plaintext)
+{
+ u32 tmp[4];
+
+ tmp[0] = GETU32(ciphertext);
+ tmp[1] = GETU32(ciphertext + 4);
+ tmp[2] = GETU32(ciphertext + 8);
+ tmp[3] = GETU32(ciphertext + 12);
+
+ switch (keyBitLength) {
+ case 128:
+ camellia_decrypt128(keyTable, tmp);
+ break;
+ case 192:
+ /* fall through */
+ case 256:
+ camellia_decrypt256(keyTable, tmp);
+ break;
+ default:
+ break;
+ }
+ PUTU32(plaintext, tmp[0]);
+ PUTU32(plaintext + 4, tmp[1]);
+ PUTU32(plaintext + 8, tmp[2]);
+ PUTU32(plaintext + 12, tmp[3]);
+}
+#endif /*!USE_ARM_ASM*/
diff --git a/comm/third_party/libgcrypt/cipher/camellia.h b/comm/third_party/libgcrypt/cipher/camellia.h
new file mode 100644
index 0000000000..d7a1e6f4a0
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/camellia.h
@@ -0,0 +1,95 @@
+/* camellia.h ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This library 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.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+/* 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 <config.h>
+/* USE_ARM_ASM indicates whether to use ARM assembly code. */
+# undef USE_ARM_ASM
+# if defined(__ARMEL__)
+# ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+# define USE_ARM_ASM 1
+# endif
+# endif
+# if defined(__AARCH64EL__)
+# ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS
+# define USE_ARM_ASM 1
+# endif
+# endif
+#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*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+
+
+void Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
+ KEY_TABLE_TYPE keyTable);
+
+#ifndef USE_ARM_ASM
+void Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *cipherText);
+
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *cipherText,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *plaintext);
+#endif /*!USE_ARM_ASM*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_CAMELLIA_H */
diff --git a/comm/third_party/libgcrypt/cipher/cast5-amd64.S b/comm/third_party/libgcrypt/cipher/cast5-amd64.S
new file mode 100644
index 0000000000..82f678901d
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cast5-amd64.S
@@ -0,0 +1,663 @@
+/* cast5-amd64.S - AMD64 assembly implementation of CAST5 cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_CAST5)
+
+#include "asm-common-amd64.h"
+
+.text
+
+.extern _gcry_cast5_s1to4;
+
+#define s1 0
+#define s2 (s1 + (4 * 256))
+#define s3 (s2 + (4 * 256))
+#define s4 (s3 + (4 * 256))
+
+/* structure of CAST5_context: */
+#define Km 0
+#define Kr (Km + (16 * 4))
+
+/* register macros */
+#define CTX %rdi
+#define RIO %rsi
+#define RTAB %r8
+
+#define RLR0 %r9
+#define RLR1 %r10
+#define RLR2 %r11
+#define RLR3 %r12
+
+#define RLR0d %r9d
+#define RLR1d %r10d
+#define RLR2d %r11d
+#define RLR3d %r12d
+
+#define RX0 %rax
+#define RX1 %rbx
+#define RX2 %rdx
+
+#define RX0d %eax
+#define RX1d %ebx
+#define RX2d %edx
+
+#define RX0bl %al
+#define RX1bl %bl
+#define RX2bl %dl
+
+#define RX0bh %ah
+#define RX1bh %bh
+#define RX2bh %dh
+
+#define RKR %rcx
+#define RKRd %ecx
+#define RKRbl %cl
+
+#define RT0 %rbp
+#define RT1 %rsi
+
+#define RT0d %ebp
+#define RT1d %esi
+
+#define RKM0d %r13d
+#define RKM1d %r14d
+
+/***********************************************************************
+ * 1-way cast5
+ ***********************************************************************/
+#define dummy(x)
+
+#define shr_kr(none) \
+ shrq $8, RKR;
+
+#define F(km, load_next_kr, op0, op1, op2, op3) \
+ op0 ## l RLR0d, km ## d; \
+ roll RKRbl, km ## d; \
+ rorq $32, RLR0; \
+ movzbl km ## bh, RT0d; \
+ movzbl km ## bl, RT1d; \
+ roll $16, km ## d; \
+ movl s1(RTAB,RT0,4), RT0d; \
+ op1 ## l s2(RTAB,RT1,4), RT0d; \
+ load_next_kr(kr_next); \
+ movzbl km ## bh, RT1d; \
+ movzbl km ## bl, km ## d; \
+ op2 ## l s3(RTAB,RT1,4), RT0d; \
+ op3 ## l s4(RTAB,km,4), RT0d; \
+ xorq RT0, RLR0;
+
+#define F1(km, load_next_kr) \
+ F(##km, load_next_kr, add, xor, sub, add)
+#define F2(km, load_next_kr) \
+ F(##km, load_next_kr, xor, sub, add, xor)
+#define F3(km, load_next_kr) \
+ F(##km, load_next_kr, sub, add, xor, sub)
+
+#define get_round_km(n, km) \
+ movl Km+4*(n)(CTX), km;
+
+#define get_round_kr_enc(n) \
+ movq $0x1010101010101010, RKR; \
+ \
+ /* merge rorl rk and rorl $16 */ \
+ xorq Kr+(n)(CTX), RKR;
+
+#define get_round_kr_dec(n) \
+ movq $0x1010101010101010, RKR; \
+ \
+ /* merge rorl rk and rorl $16 */ \
+ xorq Kr+(n - 7)(CTX), RKR; \
+ bswapq RKR;
+
+#define round_enc(n, FA, FB, fn1, fn2) \
+ get_round_km(n + 1, RX2d); \
+ FA(RX0, fn1); \
+ get_round_km(n + 2, RX0d); \
+ FB(RX2, fn2);
+
+#define round_enc_last(n, FXA, FXB) \
+ get_round_km(n + 1, RX2d); \
+ \
+ FXA(RX0, shr_kr); \
+ FXB(RX2, dummy);
+
+#define round_enc_1(n, FA, FB) \
+ round_enc(n, FA, FB, shr_kr, shr_kr)
+
+#define round_enc_2(n, FA, FB) \
+ round_enc(n, FA, FB, shr_kr, dummy)
+
+#define round_dec(n, FA, FB, fn1, fn2) \
+ get_round_km(n - 1, RX2d); \
+ FA(RX0, fn1); \
+ get_round_km(n - 2, RX0d); \
+ FB(RX2, fn2);
+
+#define round_dec_last(n, FXA, FXB) \
+ get_round_km(n - 1, RX2d); \
+ FXA(RX0, shr_kr); \
+ FXB(RX2, dummy);
+
+#define round_dec_1(n, FA, FB) \
+ round_dec(n, FA, FB, shr_kr, shr_kr)
+
+#define round_dec_2(n, FA, FB) \
+ round_dec(n, FA, FB, shr_kr, dummy)
+
+#define read_block() \
+ movq (RIO), RLR0; \
+ bswapq RLR0;
+
+#define write_block() \
+ bswapq RLR0; \
+ rorq $32, RLR0; \
+ movq RLR0, (RIO);
+
+.align 8
+.globl _gcry_cast5_amd64_encrypt_block
+ELF(.type _gcry_cast5_amd64_encrypt_block,@function;)
+
+_gcry_cast5_amd64_encrypt_block:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+
+ movq %rsi, %r10;
+
+ GET_EXTERN_POINTER(_gcry_cast5_s1to4, RTAB);
+
+ movq %rdx, RIO;
+ read_block();
+
+ get_round_km(0, RX0d);
+ get_round_kr_enc(0);
+ round_enc_1(0, F1, F2);
+ round_enc_1(2, F3, F1);
+ round_enc_1(4, F2, F3);
+ round_enc_2(6, F1, F2);
+ get_round_kr_enc(8);
+ round_enc_1(8, F3, F1);
+ round_enc_1(10, F2, F3);
+ round_enc_1(12, F1, F2);
+ round_enc_last(14, F3, F1);
+
+ movq %r10, RIO;
+ write_block();
+
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_cast5_amd64_encrypt_block,.-_gcry_cast5_amd64_encrypt_block;)
+
+.align 8
+.globl _gcry_cast5_amd64_decrypt_block
+ELF(.type _gcry_cast5_amd64_decrypt_block,@function;)
+
+_gcry_cast5_amd64_decrypt_block:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+
+ movq %rsi, %r10;
+
+ GET_EXTERN_POINTER(_gcry_cast5_s1to4, RTAB);
+
+ movq %rdx, RIO;
+ read_block();
+
+ get_round_km(15, RX0d);
+ get_round_kr_dec(15);
+ round_dec_1(15, F1, F3);
+ round_dec_1(13, F2, F1);
+ round_dec_1(11, F3, F2);
+ round_dec_2(9, F1, F3);
+ get_round_kr_dec(7);
+ round_dec_1(7, F2, F1);
+ round_dec_1(5, F3, F2);
+ round_dec_1(3, F1, F3);
+ round_dec_last(1, F2, F1);
+
+ movq %r10, RIO;
+ write_block();
+
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_cast5_amd64_decrypt_block,.-_gcry_cast5_amd64_decrypt_block;)
+
+/**********************************************************************
+ 4-way cast5, four blocks parallel
+ **********************************************************************/
+#define F_tail(rlr, rx, op1, op2, op3) \
+ movzbl rx ## bh, RT0d; \
+ movzbl rx ## bl, RT1d; \
+ roll $16, rx ## d; \
+ movl s1(RTAB,RT0,4), RT0d; \
+ op1 ## l s2(RTAB,RT1,4), RT0d; \
+ movzbl rx ## bh, RT1d; \
+ movzbl rx ## bl, rx ## d; \
+ op2 ## l s3(RTAB,RT1,4), RT0d; \
+ op3 ## l s4(RTAB,rx,4), RT0d; \
+ xorq RT0, rlr;
+
+#define F4(km, load_next_kr, op0, op1, op2, op3) \
+ movl km, RX0d; \
+ op0 ## l RLR0d, RX0d; \
+ roll RKRbl, RX0d; \
+ rorq $32, RLR0; \
+ \
+ movl km, RX1d; \
+ op0 ## l RLR1d, RX1d; \
+ roll RKRbl, RX1d; \
+ rorq $32, RLR1; \
+ \
+ movl km, RX2d; \
+ op0 ## l RLR2d, RX2d; \
+ roll RKRbl, RX2d; \
+ rorq $32, RLR2; \
+ \
+ F_tail(RLR0, RX0, op1, op2, op3); \
+ F_tail(RLR1, RX1, op1, op2, op3); \
+ F_tail(RLR2, RX2, op1, op2, op3); \
+ \
+ movl km, RX0d; \
+ op0 ## l RLR3d, RX0d; \
+ roll RKRbl, RX0d; \
+ load_next_kr(); \
+ rorq $32, RLR3; \
+ \
+ F_tail(RLR3, RX0, op1, op2, op3);
+
+#define F4_1(km, load_next_kr) \
+ F4(km, load_next_kr, add, xor, sub, add)
+#define F4_2(km, load_next_kr) \
+ F4(km, load_next_kr, xor, sub, add, xor)
+#define F4_3(km, load_next_kr) \
+ F4(km, load_next_kr, sub, add, xor, sub)
+
+#define round_enc4(n, FA, FB, fn1, fn2) \
+ get_round_km(n + 1, RKM1d); \
+ FA(RKM0d, fn1); \
+ get_round_km(n + 2, RKM0d); \
+ FB(RKM1d, fn2);
+
+#define round_enc_last4(n, FXA, FXB) \
+ get_round_km(n + 1, RKM1d); \
+ FXA(RKM0d, shr_kr); \
+ FXB(RKM1d, dummy);
+
+#define round_enc4_1(n, FA, FB) \
+ round_enc4(n, FA, FB, shr_kr, shr_kr);
+
+#define round_enc4_2(n, FA, FB) \
+ round_enc4(n, FA, FB, shr_kr, dummy);
+
+#define round_dec4(n, FA, FB, fn1, fn2) \
+ get_round_km(n - 1, RKM1d); \
+ FA(RKM0d, fn1); \
+ get_round_km(n - 2, RKM0d); \
+ FB(RKM1d, fn2);
+
+#define round_dec_last4(n, FXA, FXB) \
+ get_round_km(n - 1, RKM1d); \
+ FXA(RKM0d, shr_kr); \
+ FXB(RKM1d, dummy);
+
+#define round_dec4_1(n, FA, FB) \
+ round_dec4(n, FA, FB, shr_kr, shr_kr);
+
+#define round_dec4_2(n, FA, FB) \
+ round_dec4(n, FA, FB, shr_kr, dummy);
+
+#define inbswap_block4(a, b, c, d) \
+ bswapq a; \
+ bswapq b; \
+ bswapq c; \
+ bswapq d;
+
+#define outbswap_block4(a, b, c, d) \
+ bswapq a; \
+ bswapq b; \
+ bswapq c; \
+ bswapq d; \
+ rorq $32, a; \
+ rorq $32, b; \
+ rorq $32, c; \
+ rorq $32, d;
+
+.align 8
+ELF(.type __cast5_enc_blk4,@function;)
+
+__cast5_enc_blk4:
+ /* input:
+ * %rdi: ctx, CTX
+ * RLR0,RLR1,RLR2,RLR3: four input plaintext blocks
+ * output:
+ * RLR0,RLR1,RLR2,RLR3: four output ciphertext blocks
+ */
+ CFI_STARTPROC();
+ GET_EXTERN_POINTER(_gcry_cast5_s1to4, RTAB);
+
+ get_round_km(0, RKM0d);
+ get_round_kr_enc(0);
+ round_enc4_1(0, F4_1, F4_2);
+ round_enc4_1(2, F4_3, F4_1);
+ round_enc4_1(4, F4_2, F4_3);
+ round_enc4_2(6, F4_1, F4_2);
+ get_round_kr_enc(8);
+ round_enc4_1(8, F4_3, F4_1);
+ round_enc4_1(10, F4_2, F4_3);
+ round_enc4_1(12, F4_1, F4_2);
+ round_enc_last4(14, F4_3, F4_1);
+
+ outbswap_block4(RLR0, RLR1, RLR2, RLR3);
+ ret;
+ CFI_ENDPROC();
+ELF(.size __cast5_enc_blk4,.-__cast5_enc_blk4;)
+
+.align 8
+ELF(.type __cast5_dec_blk4,@function;)
+
+__cast5_dec_blk4:
+ /* input:
+ * %rdi: ctx, CTX
+ * RLR0,RLR1,RLR2,RLR3: four input ciphertext blocks
+ * output:
+ * RLR0,RLR1,RLR2,RLR3: four output plaintext blocks
+ */
+ CFI_STARTPROC();
+ GET_EXTERN_POINTER(_gcry_cast5_s1to4, RTAB);
+
+ inbswap_block4(RLR0, RLR1, RLR2, RLR3);
+
+ get_round_km(15, RKM0d);
+ get_round_kr_dec(15);
+ round_dec4_1(15, F4_1, F4_3);
+ round_dec4_1(13, F4_2, F4_1);
+ round_dec4_1(11, F4_3, F4_2);
+ round_dec4_2(9, F4_1, F4_3);
+ get_round_kr_dec(7);
+ round_dec4_1(7, F4_2, F4_1);
+ round_dec4_1(5, F4_3, F4_2);
+ round_dec4_1(3, F4_1, F4_3);
+ round_dec_last4(1, F4_2, F4_1);
+
+ outbswap_block4(RLR0, RLR1, RLR2, RLR3);
+ CFI_ENDPROC();
+ ret;
+ELF(.size __cast5_dec_blk4,.-__cast5_dec_blk4;)
+
+.align 8
+.globl _gcry_cast5_amd64_ctr_enc
+ELF(.type _gcry_cast5_amd64_ctr_enc,@function;)
+_gcry_cast5_amd64_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (4 blocks)
+ * %rdx: src (4 blocks)
+ * %rcx: iv (big endian, 64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+ pushq %r14;
+ CFI_PUSH(%r14);
+
+ pushq %rsi;
+ CFI_PUSH(%rsi);
+ pushq %rdx;
+ CFI_PUSH(%rdx);
+
+ /* load IV and byteswap */
+ movq (%rcx), RX0;
+ bswapq RX0;
+ movq RX0, RLR0;
+
+ /* construct IVs */
+ leaq 1(RX0), RLR1;
+ leaq 2(RX0), RLR2;
+ leaq 3(RX0), RLR3;
+ leaq 4(RX0), RX0;
+ bswapq RX0;
+
+ /* store new IV */
+ movq RX0, (%rcx);
+
+ call __cast5_enc_blk4;
+
+ popq %r14; /*src*/
+ CFI_POP_TMP_REG();
+ popq %r13; /*dst*/
+ CFI_POP_TMP_REG();
+
+ /* XOR key-stream with plaintext */
+ xorq 0 * 8(%r14), RLR0;
+ xorq 1 * 8(%r14), RLR1;
+ xorq 2 * 8(%r14), RLR2;
+ xorq 3 * 8(%r14), RLR3;
+ movq RLR0, 0 * 8(%r13);
+ movq RLR1, 1 * 8(%r13);
+ movq RLR2, 2 * 8(%r13);
+ movq RLR3, 3 * 8(%r13);
+
+ popq %r14;
+ CFI_POP(%r14);
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_cast5_amd64_ctr_enc,.-_gcry_cast5_amd64_ctr_enc;)
+
+.align 8
+.globl _gcry_cast5_amd64_cbc_dec
+ELF(.type _gcry_cast5_amd64_cbc_dec,@function;)
+_gcry_cast5_amd64_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (4 blocks)
+ * %rdx: src (4 blocks)
+ * %rcx: iv (64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+ pushq %r14;
+ CFI_PUSH(%r14);
+
+ pushq %rcx;
+ CFI_PUSH(%rcx);
+ pushq %rsi;
+ CFI_PUSH(%rsi);
+ pushq %rdx;
+ CFI_PUSH(%rdx);
+
+ /* load input */
+ movq 0 * 8(%rdx), RLR0;
+ movq 1 * 8(%rdx), RLR1;
+ movq 2 * 8(%rdx), RLR2;
+ movq 3 * 8(%rdx), RLR3;
+
+ call __cast5_dec_blk4;
+
+ popq RX0; /*src*/
+ CFI_POP_TMP_REG();
+ popq RX1; /*dst*/
+ CFI_POP_TMP_REG();
+ popq RX2; /*iv*/
+ CFI_POP_TMP_REG();
+
+ movq 3 * 8(RX0), %r14;
+ xorq (RX2), RLR0;
+ xorq 0 * 8(RX0), RLR1;
+ xorq 1 * 8(RX0), RLR2;
+ xorq 2 * 8(RX0), RLR3;
+ movq %r14, (RX2); /* store new IV */
+
+ movq RLR0, 0 * 8(RX1);
+ movq RLR1, 1 * 8(RX1);
+ movq RLR2, 2 * 8(RX1);
+ movq RLR3, 3 * 8(RX1);
+
+ popq %r14;
+ CFI_POP(%r14);
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_cast5_amd64_cbc_dec,.-_gcry_cast5_amd64_cbc_dec;)
+
+.align 8
+.globl _gcry_cast5_amd64_cfb_dec
+ELF(.type _gcry_cast5_amd64_cfb_dec,@function;)
+_gcry_cast5_amd64_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (4 blocks)
+ * %rdx: src (4 blocks)
+ * %rcx: iv (64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+ pushq %r14;
+ CFI_PUSH(%r14);
+
+ pushq %rsi;
+ CFI_PUSH(%rsi);
+ pushq %rdx;
+ CFI_PUSH(%rdx);
+
+ /* Load input */
+ movq (%rcx), RLR0;
+ movq 0 * 8(%rdx), RLR1;
+ movq 1 * 8(%rdx), RLR2;
+ movq 2 * 8(%rdx), RLR3;
+
+ inbswap_block4(RLR0, RLR1, RLR2, RLR3);
+
+ /* Update IV */
+ movq 3 * 8(%rdx), %rdx;
+ movq %rdx, (%rcx);
+
+ call __cast5_enc_blk4;
+
+ popq %rdx; /*src*/
+ CFI_POP_TMP_REG();
+ popq %rcx; /*dst*/
+ CFI_POP_TMP_REG();
+
+ xorq 0 * 8(%rdx), RLR0;
+ xorq 1 * 8(%rdx), RLR1;
+ xorq 2 * 8(%rdx), RLR2;
+ xorq 3 * 8(%rdx), RLR3;
+ movq RLR0, 0 * 8(%rcx);
+ movq RLR1, 1 * 8(%rcx);
+ movq RLR2, 2 * 8(%rcx);
+ movq RLR3, 3 * 8(%rcx);
+
+ popq %r14;
+ CFI_POP(%r14);
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_cast5_amd64_cfb_dec,.-_gcry_cast5_amd64_cfb_dec;)
+
+#endif /*defined(USE_CAST5)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/cast5-arm.S b/comm/third_party/libgcrypt/cipher/cast5-arm.S
new file mode 100644
index 0000000000..76ddd2e335
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cast5-arm.S
@@ -0,0 +1,728 @@
+/* cast5-arm.S - ARM assembly implementation of CAST5 cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(__ARMEL__)
+#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+.text
+
+.syntax unified
+.arm
+
+.extern _gcry_cast5_s1to4;
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+/* structure of crypto context */
+#define Km 0
+#define Kr (Km + (16 * 4))
+#define Kr_arm_enc (Kr + (16))
+#define Kr_arm_dec (Kr_arm_enc + (16))
+
+/* register macros */
+#define CTX %r0
+#define Rs1 %r7
+#define Rs2 %r8
+#define Rs3 %r9
+#define Rs4 %r10
+#define RMASK %r11
+#define RKM %r1
+#define RKR %r2
+
+#define RL0 %r3
+#define RR0 %r4
+
+#define RL1 %r9
+#define RR1 %r10
+
+#define RT0 %lr
+#define RT1 %ip
+#define RT2 %r5
+#define RT3 %r6
+
+/* helper macros */
+#define ldr_unaligned_le(rout, rsrc, offs, rtmp) \
+ ldrb rout, [rsrc, #((offs) + 0)]; \
+ ldrb rtmp, [rsrc, #((offs) + 1)]; \
+ orr rout, rout, rtmp, lsl #8; \
+ ldrb rtmp, [rsrc, #((offs) + 2)]; \
+ orr rout, rout, rtmp, lsl #16; \
+ ldrb rtmp, [rsrc, #((offs) + 3)]; \
+ orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_le(rin, rdst, offs, rtmp0, rtmp1) \
+ mov rtmp0, rin, lsr #8; \
+ strb rin, [rdst, #((offs) + 0)]; \
+ mov rtmp1, rin, lsr #16; \
+ strb rtmp0, [rdst, #((offs) + 1)]; \
+ mov rtmp0, rin, lsr #24; \
+ strb rtmp1, [rdst, #((offs) + 2)]; \
+ strb rtmp0, [rdst, #((offs) + 3)];
+
+#define ldr_unaligned_be(rout, rsrc, offs, rtmp) \
+ ldrb rout, [rsrc, #((offs) + 3)]; \
+ ldrb rtmp, [rsrc, #((offs) + 2)]; \
+ orr rout, rout, rtmp, lsl #8; \
+ ldrb rtmp, [rsrc, #((offs) + 1)]; \
+ orr rout, rout, rtmp, lsl #16; \
+ ldrb rtmp, [rsrc, #((offs) + 0)]; \
+ orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_be(rin, rdst, offs, rtmp0, rtmp1) \
+ mov rtmp0, rin, lsr #8; \
+ strb rin, [rdst, #((offs) + 3)]; \
+ mov rtmp1, rin, lsr #16; \
+ strb rtmp0, [rdst, #((offs) + 2)]; \
+ mov rtmp0, rin, lsr #24; \
+ strb rtmp1, [rdst, #((offs) + 1)]; \
+ strb rtmp0, [rdst, #((offs) + 0)];
+
+#ifdef __ARMEL__
+ #define ldr_unaligned_host ldr_unaligned_le
+ #define str_unaligned_host str_unaligned_le
+
+ /* bswap on little-endian */
+#ifdef HAVE_ARM_ARCH_V6
+ #define host_to_be(reg, rtmp) \
+ rev reg, reg;
+ #define be_to_host(reg, rtmp) \
+ rev reg, reg;
+#else
+ #define host_to_be(reg, rtmp) \
+ eor rtmp, reg, reg, ror #16; \
+ mov rtmp, rtmp, lsr #8; \
+ bic rtmp, rtmp, #65280; \
+ eor reg, rtmp, reg, ror #8;
+ #define be_to_host(reg, rtmp) \
+ eor rtmp, reg, reg, ror #16; \
+ mov rtmp, rtmp, lsr #8; \
+ bic rtmp, rtmp, #65280; \
+ eor reg, rtmp, reg, ror #8;
+#endif
+#else
+ #define ldr_unaligned_host ldr_unaligned_be
+ #define str_unaligned_host str_unaligned_be
+
+ /* nop on big-endian */
+ #define host_to_be(reg, rtmp) /*_*/
+ #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define host_to_host(x, y) /*_*/
+
+/**********************************************************************
+ 1-way cast5
+ **********************************************************************/
+
+#define dummy(n) /*_*/
+
+#define load_kr(n) \
+ ldr RKR, [CTX, #(Kr_arm_enc + (n))]; /* Kr[n] */
+
+#define load_dec_kr(n) \
+ ldr RKR, [CTX, #(Kr_arm_dec + (n) - 3)]; /* Kr[n] */
+
+#define load_km(n) \
+ ldr RKM, [CTX, #(Km + (n) * 4)]; /* Km[n] */
+
+#define shift_kr(dummy) \
+ mov RKR, RKR, lsr #8;
+
+#define F(n, rl, rr, op1, op2, op3, op4, dec, loadkm, shiftkr, loadkr) \
+ op1 RKM, rr; \
+ mov RKM, RKM, ror RKR; \
+ \
+ and RT0, RMASK, RKM, ror #(24); \
+ and RT1, RMASK, RKM, lsr #(16); \
+ and RT2, RMASK, RKM, lsr #(8); \
+ ldr RT0, [Rs1, RT0]; \
+ and RT3, RMASK, RKM; \
+ ldr RT1, [Rs2, RT1]; \
+ shiftkr(RKR); \
+ \
+ ldr RT2, [Rs3, RT2]; \
+ \
+ op2 RT0, RT1; \
+ ldr RT3, [Rs4, RT3]; \
+ op3 RT0, RT2; \
+ loadkm((n) + (1 - ((dec) * 2))); \
+ op4 RT0, RT3; \
+ loadkr((n) + (1 - ((dec) * 2))); \
+ eor rl, RT0;
+
+#define F1(n, rl, rr, dec, loadkm, shiftkr, loadkr) \
+ F(n, rl, rr, add, eor, sub, add, dec, loadkm, shiftkr, loadkr)
+#define F2(n, rl, rr, dec, loadkm, shiftkr, loadkr) \
+ F(n, rl, rr, eor, sub, add, eor, dec, loadkm, shiftkr, loadkr)
+#define F3(n, rl, rr, dec, loadkm, shiftkr, loadkr) \
+ F(n, rl, rr, sub, add, eor, sub, dec, loadkm, shiftkr, loadkr)
+
+#define enc_round(n, Fx, rl, rr, loadkm, shiftkr, loadkr) \
+ Fx(n, rl, rr, 0, loadkm, shiftkr, loadkr)
+
+#define dec_round(n, Fx, rl, rr, loadkm, shiftkr, loadkr) \
+ Fx(n, rl, rr, 1, loadkm, shiftkr, loadkr)
+
+#define read_block_aligned(rin, offs, l0, r0, convert, rtmp) \
+ ldr l0, [rin, #((offs) + 0)]; \
+ ldr r0, [rin, #((offs) + 4)]; \
+ convert(l0, rtmp); \
+ convert(r0, rtmp);
+
+#define write_block_aligned(rout, offs, l0, r0, convert, rtmp) \
+ convert(l0, rtmp); \
+ convert(r0, rtmp); \
+ str l0, [rout, #((offs) + 0)]; \
+ str r0, [rout, #((offs) + 4)];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+ /* unaligned word reads allowed */
+ #define read_block(rin, offs, l0, r0, rtmp0) \
+ read_block_aligned(rin, offs, l0, r0, host_to_be, rtmp0)
+
+ #define write_block(rout, offs, r0, l0, rtmp0, rtmp1) \
+ write_block_aligned(rout, offs, r0, l0, be_to_host, rtmp0)
+
+ #define read_block_host(rin, offs, l0, r0, rtmp0) \
+ read_block_aligned(rin, offs, l0, r0, host_to_host, rtmp0)
+
+ #define write_block_host(rout, offs, r0, l0, rtmp0, rtmp1) \
+ write_block_aligned(rout, offs, r0, l0, host_to_host, rtmp0)
+#else
+ /* need to handle unaligned reads by byte reads */
+ #define read_block(rin, offs, l0, r0, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_be(l0, rin, (offs) + 0, rtmp0); \
+ ldr_unaligned_be(r0, rin, (offs) + 4, rtmp0); \
+ b 2f; \
+ 1:;\
+ read_block_aligned(rin, offs, l0, r0, host_to_be, rtmp0); \
+ 2:;
+
+ #define write_block(rout, offs, l0, r0, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_be(l0, rout, (offs) + 0, rtmp0, rtmp1); \
+ str_unaligned_be(r0, rout, (offs) + 4, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ write_block_aligned(rout, offs, l0, r0, be_to_host, rtmp0); \
+ 2:;
+
+ #define read_block_host(rin, offs, l0, r0, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_host(l0, rin, (offs) + 0, rtmp0); \
+ ldr_unaligned_host(r0, rin, (offs) + 4, rtmp0); \
+ b 2f; \
+ 1:;\
+ read_block_aligned(rin, offs, l0, r0, host_to_host, rtmp0); \
+ 2:;
+
+ #define write_block_host(rout, offs, l0, r0, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_host(l0, rout, (offs) + 0, rtmp0, rtmp1); \
+ str_unaligned_host(r0, rout, (offs) + 4, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ write_block_aligned(rout, offs, l0, r0, host_to_host, rtmp0); \
+ 2:;
+#endif
+
+.align 3
+.globl _gcry_cast5_arm_encrypt_block
+.type _gcry_cast5_arm_encrypt_block,%function;
+
+_gcry_cast5_arm_encrypt_block:
+ /* input:
+ * %r0: CTX
+ * %r1: dst
+ * %r2: src
+ */
+ push {%r1, %r4-%r11, %ip, %lr};
+
+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2);
+ mov RMASK, #(0xff << 2);
+ add Rs2, Rs1, #(0x100*4);
+ add Rs3, Rs1, #(0x100*4*2);
+ add Rs4, Rs1, #(0x100*4*3);
+
+ read_block(%r2, 0, RL0, RR0, RT0);
+
+ load_km(0);
+ load_kr(0);
+ enc_round(0, F1, RL0, RR0, load_km, shift_kr, dummy);
+ enc_round(1, F2, RR0, RL0, load_km, shift_kr, dummy);
+ enc_round(2, F3, RL0, RR0, load_km, shift_kr, dummy);
+ enc_round(3, F1, RR0, RL0, load_km, dummy, load_kr);
+ enc_round(4, F2, RL0, RR0, load_km, shift_kr, dummy);
+ enc_round(5, F3, RR0, RL0, load_km, shift_kr, dummy);
+ enc_round(6, F1, RL0, RR0, load_km, shift_kr, dummy);
+ enc_round(7, F2, RR0, RL0, load_km, dummy, load_kr);
+ enc_round(8, F3, RL0, RR0, load_km, shift_kr, dummy);
+ enc_round(9, F1, RR0, RL0, load_km, shift_kr, dummy);
+ enc_round(10, F2, RL0, RR0, load_km, shift_kr, dummy);
+ enc_round(11, F3, RR0, RL0, load_km, dummy, load_kr);
+ enc_round(12, F1, RL0, RR0, load_km, shift_kr, dummy);
+ enc_round(13, F2, RR0, RL0, load_km, shift_kr, dummy);
+ enc_round(14, F3, RL0, RR0, load_km, shift_kr, dummy);
+ enc_round(15, F1, RR0, RL0, dummy, dummy, dummy);
+
+ ldr %r1, [%sp], #4;
+ write_block(%r1, 0, RR0, RL0, RT0, RT1);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_encrypt_block,.-_gcry_cast5_arm_encrypt_block;
+
+.align 3
+.globl _gcry_cast5_arm_decrypt_block
+.type _gcry_cast5_arm_decrypt_block,%function;
+
+_gcry_cast5_arm_decrypt_block:
+ /* input:
+ * %r0: CTX
+ * %r1: dst
+ * %r2: src
+ */
+ push {%r1, %r4-%r11, %ip, %lr};
+
+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2);
+ mov RMASK, #(0xff << 2);
+ add Rs2, Rs1, #(0x100 * 4);
+ add Rs3, Rs1, #(0x100 * 4 * 2);
+ add Rs4, Rs1, #(0x100 * 4 * 3);
+
+ read_block(%r2, 0, RL0, RR0, RT0);
+
+ load_km(15);
+ load_dec_kr(15);
+ dec_round(15, F1, RL0, RR0, load_km, shift_kr, dummy);
+ dec_round(14, F3, RR0, RL0, load_km, shift_kr, dummy);
+ dec_round(13, F2, RL0, RR0, load_km, shift_kr, dummy);
+ dec_round(12, F1, RR0, RL0, load_km, dummy, load_dec_kr);
+ dec_round(11, F3, RL0, RR0, load_km, shift_kr, dummy);
+ dec_round(10, F2, RR0, RL0, load_km, shift_kr, dummy);
+ dec_round(9, F1, RL0, RR0, load_km, shift_kr, dummy);
+ dec_round(8, F3, RR0, RL0, load_km, dummy, load_dec_kr);
+ dec_round(7, F2, RL0, RR0, load_km, shift_kr, dummy);
+ dec_round(6, F1, RR0, RL0, load_km, shift_kr, dummy);
+ dec_round(5, F3, RL0, RR0, load_km, shift_kr, dummy);
+ dec_round(4, F2, RR0, RL0, load_km, dummy, load_dec_kr);
+ dec_round(3, F1, RL0, RR0, load_km, shift_kr, dummy);
+ dec_round(2, F3, RR0, RL0, load_km, shift_kr, dummy);
+ dec_round(1, F2, RL0, RR0, load_km, shift_kr, dummy);
+ dec_round(0, F1, RR0, RL0, dummy, dummy, dummy);
+
+ ldr %r1, [%sp], #4;
+ write_block(%r1, 0, RR0, RL0, RT0, RT1);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_decrypt_block,.-_gcry_cast5_arm_decrypt_block;
+
+/**********************************************************************
+ 2-way cast5
+ **********************************************************************/
+
+#define F_2w(n, rl0, rr0, rl1, rr1, op1, op2, op3, op4, dec, loadkm, shiftkr, \
+ loadkr) \
+ op1 RT3, RKM, rr0; \
+ op1 RKM, RKM, rr1; \
+ mov RT3, RT3, ror RKR; \
+ mov RKM, RKM, ror RKR; \
+ \
+ and RT0, RMASK, RT3, ror #(24); \
+ and RT1, RMASK, RT3, lsr #(16); \
+ and RT2, RMASK, RT3, lsr #(8); \
+ and RT3, RMASK, RT3; \
+ \
+ ldr RT0, [Rs1, RT0]; \
+ add RT2, #(0x100 * 4); \
+ ldr RT1, [Rs2, RT1]; \
+ add RT3, #(0x100 * 4 * 2); \
+ \
+ ldr RT2, [Rs2, RT2]; \
+ \
+ op2 RT0, RT1; \
+ ldr RT3, [Rs2, RT3]; \
+ and RT1, RMASK, RKM, ror #(24); \
+ op3 RT0, RT2; \
+ and RT2, RMASK, RKM, lsr #(16); \
+ op4 RT0, RT3; \
+ and RT3, RMASK, RKM, lsr #(8); \
+ eor rl0, RT0; \
+ add RT3, #(0x100 * 4); \
+ ldr RT1, [Rs1, RT1]; \
+ and RT0, RMASK, RKM; \
+ ldr RT2, [Rs2, RT2]; \
+ add RT0, #(0x100 * 4 * 2); \
+ \
+ ldr RT3, [Rs2, RT3]; \
+ \
+ op2 RT1, RT2; \
+ ldr RT0, [Rs2, RT0]; \
+ op3 RT1, RT3; \
+ loadkm((n) + (1 - ((dec) * 2))); \
+ op4 RT1, RT0; \
+ loadkr((n) + (1 - ((dec) * 2))); \
+ shiftkr(RKR); \
+ eor rl1, RT1;
+
+#define F1_2w(n, rl0, rr0, rl1, rr1, dec, loadkm, shiftkr, loadkr) \
+ F_2w(n, rl0, rr0, rl1, rr1, add, eor, sub, add, dec, \
+ loadkm, shiftkr, loadkr)
+#define F2_2w(n, rl0, rr0, rl1, rr1, dec, loadkm, shiftkr, loadkr) \
+ F_2w(n, rl0, rr0, rl1, rr1, eor, sub, add, eor, dec, \
+ loadkm, shiftkr, loadkr)
+#define F3_2w(n, rl0, rr0, rl1, rr1, dec, loadkm, shiftkr, loadkr) \
+ F_2w(n, rl0, rr0, rl1, rr1, sub, add, eor, sub, dec, \
+ loadkm, shiftkr, loadkr)
+
+#define enc_round2(n, Fx, rl, rr, loadkm, shiftkr, loadkr) \
+ Fx##_2w(n, rl##0, rr##0, rl##1, rr##1, 0, loadkm, shiftkr, loadkr)
+
+#define dec_round2(n, Fx, rl, rr, loadkm, shiftkr, loadkr) \
+ Fx##_2w(n, rl##0, rr##0, rl##1, rr##1, 1, loadkm, shiftkr, loadkr)
+
+#define read_block2_aligned(rin, l0, r0, l1, r1, convert, rtmp) \
+ ldr l0, [rin, #(0)]; \
+ ldr r0, [rin, #(4)]; \
+ convert(l0, rtmp); \
+ ldr l1, [rin, #(8)]; \
+ convert(r0, rtmp); \
+ ldr r1, [rin, #(12)]; \
+ convert(l1, rtmp); \
+ convert(r1, rtmp);
+
+#define write_block2_aligned(rout, l0, r0, l1, r1, convert, rtmp) \
+ convert(l0, rtmp); \
+ convert(r0, rtmp); \
+ convert(l1, rtmp); \
+ str l0, [rout, #(0)]; \
+ convert(r1, rtmp); \
+ str r0, [rout, #(4)]; \
+ str l1, [rout, #(8)]; \
+ str r1, [rout, #(12)];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+ /* unaligned word reads allowed */
+ #define read_block2(rin, l0, r0, l1, r1, rtmp0) \
+ read_block2_aligned(rin, l0, r0, l1, r1, host_to_be, rtmp0)
+
+ #define write_block2(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+ write_block2_aligned(rout, l0, r0, l1, r1, be_to_host, rtmp0)
+
+ #define read_block2_host(rin, l0, r0, l1, r1, rtmp0) \
+ read_block2_aligned(rin, l0, r0, l1, r1, host_to_host, rtmp0)
+
+ #define write_block2_host(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+ write_block2_aligned(rout, l0, r0, l1, r1, host_to_host, rtmp0)
+#else
+ /* need to handle unaligned reads by byte reads */
+ #define read_block2(rin, l0, r0, l1, r1, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_be(l0, rin, 0, rtmp0); \
+ ldr_unaligned_be(r0, rin, 4, rtmp0); \
+ ldr_unaligned_be(l1, rin, 8, rtmp0); \
+ ldr_unaligned_be(r1, rin, 12, rtmp0); \
+ b 2f; \
+ 1:;\
+ read_block2_aligned(rin, l0, r0, l1, r1, host_to_be, rtmp0); \
+ 2:;
+
+ #define write_block2(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_be(l0, rout, 0, rtmp0, rtmp1); \
+ str_unaligned_be(r0, rout, 4, rtmp0, rtmp1); \
+ str_unaligned_be(l1, rout, 8, rtmp0, rtmp1); \
+ str_unaligned_be(r1, rout, 12, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ write_block2_aligned(rout, l0, r0, l1, r1, be_to_host, rtmp0); \
+ 2:;
+
+ #define read_block2_host(rin, l0, r0, l1, r1, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_host(l0, rin, 0, rtmp0); \
+ ldr_unaligned_host(r0, rin, 4, rtmp0); \
+ ldr_unaligned_host(l1, rin, 8, rtmp0); \
+ ldr_unaligned_host(r1, rin, 12, rtmp0); \
+ b 2f; \
+ 1:;\
+ read_block2_aligned(rin, l0, r0, l1, r1, host_to_host, rtmp0); \
+ 2:;
+
+ #define write_block2_host(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_host(l0, rout, 0, rtmp0, rtmp1); \
+ str_unaligned_host(r0, rout, 4, rtmp0, rtmp1); \
+ str_unaligned_host(l1, rout, 8, rtmp0, rtmp1); \
+ str_unaligned_host(r1, rout, 12, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ write_block2_aligned(rout, l0, r0, l1, r1, host_to_host, rtmp0); \
+ 2:;
+#endif
+
+.align 3
+.type _gcry_cast5_arm_enc_blk2,%function;
+
+_gcry_cast5_arm_enc_blk2:
+ /* input:
+ * preloaded: CTX
+ * [RL0, RR0], [RL1, RR1]: src
+ * output:
+ * [RR0, RL0], [RR1, RL1]: dst
+ */
+ push {%lr};
+
+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2);
+ mov RMASK, #(0xff << 2);
+ add Rs2, Rs1, #(0x100 * 4);
+
+ load_km(0);
+ load_kr(0);
+ enc_round2(0, F1, RL, RR, load_km, shift_kr, dummy);
+ enc_round2(1, F2, RR, RL, load_km, shift_kr, dummy);
+ enc_round2(2, F3, RL, RR, load_km, shift_kr, dummy);
+ enc_round2(3, F1, RR, RL, load_km, dummy, load_kr);
+ enc_round2(4, F2, RL, RR, load_km, shift_kr, dummy);
+ enc_round2(5, F3, RR, RL, load_km, shift_kr, dummy);
+ enc_round2(6, F1, RL, RR, load_km, shift_kr, dummy);
+ enc_round2(7, F2, RR, RL, load_km, dummy, load_kr);
+ enc_round2(8, F3, RL, RR, load_km, shift_kr, dummy);
+ enc_round2(9, F1, RR, RL, load_km, shift_kr, dummy);
+ enc_round2(10, F2, RL, RR, load_km, shift_kr, dummy);
+ enc_round2(11, F3, RR, RL, load_km, dummy, load_kr);
+ enc_round2(12, F1, RL, RR, load_km, shift_kr, dummy);
+ enc_round2(13, F2, RR, RL, load_km, shift_kr, dummy);
+ enc_round2(14, F3, RL, RR, load_km, shift_kr, dummy);
+ enc_round2(15, F1, RR, RL, dummy, dummy, dummy);
+
+ host_to_be(RR0, RT0);
+ host_to_be(RL0, RT0);
+ host_to_be(RR1, RT0);
+ host_to_be(RL1, RT0);
+
+ pop {%pc};
+.ltorg
+.size _gcry_cast5_arm_enc_blk2,.-_gcry_cast5_arm_enc_blk2;
+
+.align 3
+.globl _gcry_cast5_arm_cfb_dec;
+.type _gcry_cast5_arm_cfb_dec,%function;
+
+_gcry_cast5_arm_cfb_dec:
+ /* input:
+ * %r0: CTX
+ * %r1: dst (2 blocks)
+ * %r2: src (2 blocks)
+ * %r3: iv (64bit)
+ */
+ push {%r1, %r2, %r4-%r11, %ip, %lr};
+
+ mov %lr, %r3;
+
+ /* Load input (iv/%r3 is aligned, src/%r2 might not be) */
+ ldm %r3, {RL0, RR0};
+ host_to_be(RL0, RT1);
+ host_to_be(RR0, RT1);
+ read_block(%r2, 0, RL1, RR1, %ip);
+
+ /* Update IV, load src[1] and save to iv[0] */
+ read_block_host(%r2, 8, %r5, %r6, %r7);
+ stm %lr, {%r5, %r6};
+
+ bl _gcry_cast5_arm_enc_blk2;
+ /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+ /* %r0: dst, %r1: %src */
+ pop {%r0, %r1};
+
+ /* dst = src ^ result */
+ read_block2_host(%r1, %r5, %r6, %r7, %r8, %lr);
+ eor %r5, %r4;
+ eor %r6, %r3;
+ eor %r7, %r10;
+ eor %r8, %r9;
+ write_block2_host(%r0, %r5, %r6, %r7, %r8, %r1, %r2);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_cfb_dec,.-_gcry_cast5_arm_cfb_dec;
+
+.align 3
+.globl _gcry_cast5_arm_ctr_enc;
+.type _gcry_cast5_arm_ctr_enc,%function;
+
+_gcry_cast5_arm_ctr_enc:
+ /* input:
+ * %r0: CTX
+ * %r1: dst (2 blocks)
+ * %r2: src (2 blocks)
+ * %r3: iv (64bit, big-endian)
+ */
+ push {%r1, %r2, %r4-%r11, %ip, %lr};
+
+ mov %lr, %r3;
+
+ /* Load IV (big => host endian) */
+ read_block_aligned(%lr, 0, RL0, RR0, be_to_host, RT1);
+
+ /* Construct IVs */
+ adds RR1, RR0, #1; /* +1 */
+ adc RL1, RL0, #0;
+ adds %r6, RR1, #1; /* +2 */
+ adc %r5, RL1, #0;
+
+ /* Store new IV (host => big-endian) */
+ write_block_aligned(%lr, 0, %r5, %r6, host_to_be, RT1);
+
+ bl _gcry_cast5_arm_enc_blk2;
+ /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+ /* %r0: dst, %r1: %src */
+ pop {%r0, %r1};
+
+ /* XOR key-stream with plaintext */
+ read_block2_host(%r1, %r5, %r6, %r7, %r8, %lr);
+ eor %r5, %r4;
+ eor %r6, %r3;
+ eor %r7, %r10;
+ eor %r8, %r9;
+ write_block2_host(%r0, %r5, %r6, %r7, %r8, %r1, %r2);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_ctr_enc,.-_gcry_cast5_arm_ctr_enc;
+
+.align 3
+.type _gcry_cast5_arm_dec_blk2,%function;
+
+_gcry_cast5_arm_dec_blk2:
+ /* input:
+ * preloaded: CTX
+ * [RL0, RR0], [RL1, RR1]: src
+ * output:
+ * [RR0, RL0], [RR1, RL1]: dst
+ */
+
+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2);
+ mov RMASK, #(0xff << 2);
+ add Rs2, Rs1, #(0x100 * 4);
+
+ load_km(15);
+ load_dec_kr(15);
+ dec_round2(15, F1, RL, RR, load_km, shift_kr, dummy);
+ dec_round2(14, F3, RR, RL, load_km, shift_kr, dummy);
+ dec_round2(13, F2, RL, RR, load_km, shift_kr, dummy);
+ dec_round2(12, F1, RR, RL, load_km, dummy, load_dec_kr);
+ dec_round2(11, F3, RL, RR, load_km, shift_kr, dummy);
+ dec_round2(10, F2, RR, RL, load_km, shift_kr, dummy);
+ dec_round2(9, F1, RL, RR, load_km, shift_kr, dummy);
+ dec_round2(8, F3, RR, RL, load_km, dummy, load_dec_kr);
+ dec_round2(7, F2, RL, RR, load_km, shift_kr, dummy);
+ dec_round2(6, F1, RR, RL, load_km, shift_kr, dummy);
+ dec_round2(5, F3, RL, RR, load_km, shift_kr, dummy);
+ dec_round2(4, F2, RR, RL, load_km, dummy, load_dec_kr);
+ dec_round2(3, F1, RL, RR, load_km, shift_kr, dummy);
+ dec_round2(2, F3, RR, RL, load_km, shift_kr, dummy);
+ dec_round2(1, F2, RL, RR, load_km, shift_kr, dummy);
+ dec_round2(0, F1, RR, RL, dummy, dummy, dummy);
+
+ host_to_be(RR0, RT0);
+ host_to_be(RL0, RT0);
+ host_to_be(RR1, RT0);
+ host_to_be(RL1, RT0);
+
+ b .Ldec_cbc_tail;
+.ltorg
+.size _gcry_cast5_arm_dec_blk2,.-_gcry_cast5_arm_dec_blk2;
+
+.align 3
+.globl _gcry_cast5_arm_cbc_dec;
+.type _gcry_cast5_arm_cbc_dec,%function;
+
+_gcry_cast5_arm_cbc_dec:
+ /* input:
+ * %r0: CTX
+ * %r1: dst (2 blocks)
+ * %r2: src (2 blocks)
+ * %r3: iv (64bit)
+ */
+ push {%r1-%r11, %ip, %lr};
+
+ read_block2(%r2, RL0, RR0, RL1, RR1, RT0);
+
+ /* dec_blk2 is only used by cbc_dec, jump directly in/out instead
+ * of function call. */
+ b _gcry_cast5_arm_dec_blk2;
+.Ldec_cbc_tail:
+ /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+ /* %r0: dst, %r1: %src, %r2: iv */
+ pop {%r0-%r2};
+
+ /* load IV+1 (src[0]) to %r7:%r8. Might be unaligned. */
+ read_block_host(%r1, 0, %r7, %r8, %r5);
+ /* load IV (iv[0]) to %r5:%r6. 'iv' is aligned. */
+ ldm %r2, {%r5, %r6};
+
+ /* out[1] ^= IV+1 */
+ eor %r10, %r7;
+ eor %r9, %r8;
+ /* out[0] ^= IV */
+ eor %r4, %r5;
+ eor %r3, %r6;
+
+ /* load IV+2 (src[1]) to %r7:%r8. Might be unaligned. */
+ read_block_host(%r1, 8, %r7, %r8, %r5);
+ /* store IV+2 to iv[0] (aligned). */
+ stm %r2, {%r7, %r8};
+
+ /* store result to dst[0-3]. Might be unaligned. */
+ write_block2_host(%r0, %r4, %r3, %r10, %r9, %r5, %r6);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_cbc_dec,.-_gcry_cast5_arm_cbc_dec;
+
+#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
+#endif /*__ARM_ARCH >= 6*/
diff --git a/comm/third_party/libgcrypt/cipher/cast5.c b/comm/third_party/libgcrypt/cipher/cast5.c
new file mode 100644
index 0000000000..837ea0fe57
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cast5.c
@@ -0,0 +1,1238 @@
+/* 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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/comm/third_party/libgcrypt/cipher/chacha20-aarch64.S b/comm/third_party/libgcrypt/cipher/chacha20-aarch64.S
new file mode 100644
index 0000000000..b8f9724a37
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/chacha20-aarch64.S
@@ -0,0 +1,648 @@
+/* chacha20-aarch64.S - ARMv8/AArch64 accelerated chacha20 blocks function
+ *
+ * Copyright (C) 2017-2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on D. J. Bernstein reference implementation at
+ * http://cr.yp.to/chacha.html:
+ *
+ * chacha-regs.c version 20080118
+ * D. J. Bernstein
+ * Public domain.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_NEON) && \
+ defined(USE_CHACHA20)
+
+.cpu generic+simd
+
+.text
+
+#include "asm-poly1305-aarch64.h"
+
+/* register macros */
+#define INPUT x0
+#define DST x1
+#define SRC x2
+#define NBLKS x3
+#define ROUND x4
+#define INPUT_CTR x5
+#define INPUT_POS x6
+#define CTR x7
+
+/* vector registers */
+#define X0 v16
+#define X1 v17
+#define X2 v18
+#define X3 v19
+#define X4 v20
+#define X5 v21
+#define X6 v22
+#define X7 v23
+#define X8 v24
+#define X9 v25
+#define X10 v26
+#define X11 v27
+#define X12 v28
+#define X13 v29
+#define X14 v30
+#define X15 v31
+
+#define VCTR v0
+#define VTMP0 v1
+#define VTMP1 v2
+#define VTMP2 v3
+#define VTMP3 v4
+#define X12_TMP v5
+#define X13_TMP v6
+#define ROT8 v7
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+#define _(...) __VA_ARGS__
+
+#define vpunpckldq(s1, s2, dst) \
+ zip1 dst.4s, s2.4s, s1.4s;
+
+#define vpunpckhdq(s1, s2, dst) \
+ zip2 dst.4s, s2.4s, s1.4s;
+
+#define vpunpcklqdq(s1, s2, dst) \
+ zip1 dst.2d, s2.2d, s1.2d;
+
+#define vpunpckhqdq(s1, s2, dst) \
+ zip2 dst.2d, s2.2d, s1.2d;
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
+ vpunpckhdq(x1, x0, t2); \
+ vpunpckldq(x1, x0, x0); \
+ \
+ vpunpckldq(x3, x2, t1); \
+ vpunpckhdq(x3, x2, x2); \
+ \
+ vpunpckhqdq(t1, x0, x1); \
+ vpunpcklqdq(t1, x0, x0); \
+ \
+ vpunpckhqdq(x2, t2, x3); \
+ vpunpcklqdq(x2, t2, x2);
+
+#define clear(x) \
+ eor x.16b, x.16b, x.16b;
+
+/**********************************************************************
+ 4-way chacha20
+ **********************************************************************/
+
+#define XOR(d,s1,s2) \
+ eor d.16b, s2.16b, s1.16b;
+
+#define PLUS(ds,s) \
+ add ds.4s, ds.4s, s.4s;
+
+#define ROTATE4(dst1,dst2,dst3,dst4,c,src1,src2,src3,src4,iop1,iop2,iop3) \
+ shl dst1.4s, src1.4s, #(c); \
+ shl dst2.4s, src2.4s, #(c); \
+ iop1; \
+ shl dst3.4s, src3.4s, #(c); \
+ shl dst4.4s, src4.4s, #(c); \
+ iop2; \
+ sri dst1.4s, src1.4s, #(32 - (c)); \
+ sri dst2.4s, src2.4s, #(32 - (c)); \
+ iop3; \
+ sri dst3.4s, src3.4s, #(32 - (c)); \
+ sri dst4.4s, src4.4s, #(32 - (c));
+
+#define ROTATE4_8(dst1,dst2,dst3,dst4,src1,src2,src3,src4,iop1,iop2,iop3) \
+ tbl dst1.16b, {src1.16b}, ROT8.16b; \
+ iop1; \
+ tbl dst2.16b, {src2.16b}, ROT8.16b; \
+ iop2; \
+ tbl dst3.16b, {src3.16b}, ROT8.16b; \
+ iop3; \
+ tbl dst4.16b, {src4.16b}, ROT8.16b;
+
+#define ROTATE4_16(dst1,dst2,dst3,dst4,src1,src2,src3,src4,iop1) \
+ rev32 dst1.8h, src1.8h; \
+ rev32 dst2.8h, src2.8h; \
+ iop1; \
+ rev32 dst3.8h, src3.8h; \
+ rev32 dst4.8h, src4.8h;
+
+#define QUARTERROUND4(a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,a4,b4,c4,d4,ign,tmp1,tmp2,tmp3,tmp4,\
+ iop1,iop2,iop3,iop4,iop5,iop6,iop7,iop8,iop9,iop10,iop11,iop12,iop13,iop14,\
+ iop15,iop16,iop17,iop18,iop19,iop20,iop21,iop22,iop23,iop24,iop25,iop26,\
+ iop27,iop28,iop29) \
+ PLUS(a1,b1); PLUS(a2,b2); iop1; \
+ PLUS(a3,b3); PLUS(a4,b4); iop2; \
+ XOR(tmp1,d1,a1); XOR(tmp2,d2,a2); iop3; \
+ XOR(tmp3,d3,a3); XOR(tmp4,d4,a4); iop4; \
+ ROTATE4_16(d1, d2, d3, d4, tmp1, tmp2, tmp3, tmp4, _(iop5)); \
+ iop6; \
+ PLUS(c1,d1); PLUS(c2,d2); iop7; \
+ PLUS(c3,d3); PLUS(c4,d4); iop8; \
+ XOR(tmp1,b1,c1); XOR(tmp2,b2,c2); iop9; \
+ XOR(tmp3,b3,c3); XOR(tmp4,b4,c4); iop10; \
+ ROTATE4(b1, b2, b3, b4, 12, tmp1, tmp2, tmp3, tmp4, \
+ _(iop11), _(iop12), _(iop13)); iop14; \
+ PLUS(a1,b1); PLUS(a2,b2); iop15; \
+ PLUS(a3,b3); PLUS(a4,b4); iop16; \
+ XOR(tmp1,d1,a1); XOR(tmp2,d2,a2); iop17; \
+ XOR(tmp3,d3,a3); XOR(tmp4,d4,a4); iop18; \
+ ROTATE4_8(d1, d2, d3, d4, tmp1, tmp2, tmp3, tmp4, \
+ _(iop19), _(iop20), _(iop21)); iop22; \
+ PLUS(c1,d1); PLUS(c2,d2); iop23; \
+ PLUS(c3,d3); PLUS(c4,d4); iop24; \
+ XOR(tmp1,b1,c1); XOR(tmp2,b2,c2); iop25; \
+ XOR(tmp3,b3,c3); XOR(tmp4,b4,c4); iop26; \
+ ROTATE4(b1, b2, b3, b4, 7, tmp1, tmp2, tmp3, tmp4, \
+ _(iop27), _(iop28), _(iop29));
+
+.align 4
+.globl _gcry_chacha20_aarch64_blocks4_data_inc_counter
+_gcry_chacha20_aarch64_blocks4_data_inc_counter:
+ .long 0,1,2,3
+
+.align 4
+.globl _gcry_chacha20_aarch64_blocks4_data_rot8
+_gcry_chacha20_aarch64_blocks4_data_rot8:
+ .byte 3,0,1,2
+ .byte 7,4,5,6
+ .byte 11,8,9,10
+ .byte 15,12,13,14
+
+.align 3
+.globl _gcry_chacha20_aarch64_blocks4
+ELF(.type _gcry_chacha20_aarch64_blocks4,%function;)
+
+_gcry_chacha20_aarch64_blocks4:
+ /* input:
+ * x0: input
+ * x1: dst
+ * x2: src
+ * x3: nblks (multiple of 4)
+ */
+ CFI_STARTPROC()
+
+ GET_DATA_POINTER(CTR, _gcry_chacha20_aarch64_blocks4_data_rot8);
+ add INPUT_CTR, INPUT, #(12*4);
+ ld1 {ROT8.16b}, [CTR];
+ GET_DATA_POINTER(CTR, _gcry_chacha20_aarch64_blocks4_data_inc_counter);
+ mov INPUT_POS, INPUT;
+ ld1 {VCTR.16b}, [CTR];
+
+.Loop4:
+ /* Construct counter vectors X12 and X13 */
+
+ ld1 {X15.16b}, [INPUT_CTR];
+ mov ROUND, #20;
+ ld1 {VTMP1.16b-VTMP3.16b}, [INPUT_POS];
+
+ dup X12.4s, X15.s[0];
+ dup X13.4s, X15.s[1];
+ ldr CTR, [INPUT_CTR];
+ add X12.4s, X12.4s, VCTR.4s;
+ dup X0.4s, VTMP1.s[0];
+ dup X1.4s, VTMP1.s[1];
+ dup X2.4s, VTMP1.s[2];
+ dup X3.4s, VTMP1.s[3];
+ dup X14.4s, X15.s[2];
+ cmhi VTMP0.4s, VCTR.4s, X12.4s;
+ dup X15.4s, X15.s[3];
+ add CTR, CTR, #4; /* Update counter */
+ dup X4.4s, VTMP2.s[0];
+ dup X5.4s, VTMP2.s[1];
+ dup X6.4s, VTMP2.s[2];
+ dup X7.4s, VTMP2.s[3];
+ sub X13.4s, X13.4s, VTMP0.4s;
+ dup X8.4s, VTMP3.s[0];
+ dup X9.4s, VTMP3.s[1];
+ dup X10.4s, VTMP3.s[2];
+ dup X11.4s, VTMP3.s[3];
+ mov X12_TMP.16b, X12.16b;
+ mov X13_TMP.16b, X13.16b;
+ str CTR, [INPUT_CTR];
+
+.Lround2:
+ subs ROUND, ROUND, #2
+ QUARTERROUND4(X0, X4, X8, X12, X1, X5, X9, X13,
+ X2, X6, X10, X14, X3, X7, X11, X15,
+ tmp:=,VTMP0,VTMP1,VTMP2,VTMP3,
+ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
+ QUARTERROUND4(X0, X5, X10, X15, X1, X6, X11, X12,
+ X2, X7, X8, X13, X3, X4, X9, X14,
+ tmp:=,VTMP0,VTMP1,VTMP2,VTMP3,
+ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
+ b.ne .Lround2;
+
+ ld1 {VTMP0.16b, VTMP1.16b}, [INPUT_POS], #32;
+
+ PLUS(X12, X12_TMP); /* INPUT + 12 * 4 + counter */
+ PLUS(X13, X13_TMP); /* INPUT + 13 * 4 + counter */
+
+ dup VTMP2.4s, VTMP0.s[0]; /* INPUT + 0 * 4 */
+ dup VTMP3.4s, VTMP0.s[1]; /* INPUT + 1 * 4 */
+ dup X12_TMP.4s, VTMP0.s[2]; /* INPUT + 2 * 4 */
+ dup X13_TMP.4s, VTMP0.s[3]; /* INPUT + 3 * 4 */
+ PLUS(X0, VTMP2);
+ PLUS(X1, VTMP3);
+ PLUS(X2, X12_TMP);
+ PLUS(X3, X13_TMP);
+
+ dup VTMP2.4s, VTMP1.s[0]; /* INPUT + 4 * 4 */
+ dup VTMP3.4s, VTMP1.s[1]; /* INPUT + 5 * 4 */
+ dup X12_TMP.4s, VTMP1.s[2]; /* INPUT + 6 * 4 */
+ dup X13_TMP.4s, VTMP1.s[3]; /* INPUT + 7 * 4 */
+ ld1 {VTMP0.16b, VTMP1.16b}, [INPUT_POS];
+ mov INPUT_POS, INPUT;
+ PLUS(X4, VTMP2);
+ PLUS(X5, VTMP3);
+ PLUS(X6, X12_TMP);
+ PLUS(X7, X13_TMP);
+
+ dup VTMP2.4s, VTMP0.s[0]; /* INPUT + 8 * 4 */
+ dup VTMP3.4s, VTMP0.s[1]; /* INPUT + 9 * 4 */
+ dup X12_TMP.4s, VTMP0.s[2]; /* INPUT + 10 * 4 */
+ dup X13_TMP.4s, VTMP0.s[3]; /* INPUT + 11 * 4 */
+ dup VTMP0.4s, VTMP1.s[2]; /* INPUT + 14 * 4 */
+ dup VTMP1.4s, VTMP1.s[3]; /* INPUT + 15 * 4 */
+ PLUS(X8, VTMP2);
+ PLUS(X9, VTMP3);
+ PLUS(X10, X12_TMP);
+ PLUS(X11, X13_TMP);
+ PLUS(X14, VTMP0);
+ PLUS(X15, VTMP1);
+
+ transpose_4x4(X0, X1, X2, X3, VTMP0, VTMP1, VTMP2);
+ transpose_4x4(X4, X5, X6, X7, VTMP0, VTMP1, VTMP2);
+ transpose_4x4(X8, X9, X10, X11, VTMP0, VTMP1, VTMP2);
+ transpose_4x4(X12, X13, X14, X15, VTMP0, VTMP1, VTMP2);
+
+ subs NBLKS, NBLKS, #4;
+
+ ld1 {VTMP0.16b-VTMP3.16b}, [SRC], #64;
+ ld1 {X12_TMP.16b-X13_TMP.16b}, [SRC], #32;
+ eor VTMP0.16b, X0.16b, VTMP0.16b;
+ eor VTMP1.16b, X4.16b, VTMP1.16b;
+ eor VTMP2.16b, X8.16b, VTMP2.16b;
+ eor VTMP3.16b, X12.16b, VTMP3.16b;
+ eor X12_TMP.16b, X1.16b, X12_TMP.16b;
+ eor X13_TMP.16b, X5.16b, X13_TMP.16b;
+ st1 {VTMP0.16b-VTMP3.16b}, [DST], #64;
+ ld1 {VTMP0.16b-VTMP3.16b}, [SRC], #64;
+ st1 {X12_TMP.16b-X13_TMP.16b}, [DST], #32;
+ ld1 {X12_TMP.16b-X13_TMP.16b}, [SRC], #32;
+ eor VTMP0.16b, X9.16b, VTMP0.16b;
+ eor VTMP1.16b, X13.16b, VTMP1.16b;
+ eor VTMP2.16b, X2.16b, VTMP2.16b;
+ eor VTMP3.16b, X6.16b, VTMP3.16b;
+ eor X12_TMP.16b, X10.16b, X12_TMP.16b;
+ eor X13_TMP.16b, X14.16b, X13_TMP.16b;
+ st1 {VTMP0.16b-VTMP3.16b}, [DST], #64;
+ ld1 {VTMP0.16b-VTMP3.16b}, [SRC], #64;
+ st1 {X12_TMP.16b-X13_TMP.16b}, [DST], #32;
+ eor VTMP0.16b, X3.16b, VTMP0.16b;
+ eor VTMP1.16b, X7.16b, VTMP1.16b;
+ eor VTMP2.16b, X11.16b, VTMP2.16b;
+ eor VTMP3.16b, X15.16b, VTMP3.16b;
+ st1 {VTMP0.16b-VTMP3.16b}, [DST], #64;
+
+ b.ne .Loop4;
+
+ /* clear the used vector registers and stack */
+ clear(VTMP0);
+ clear(VTMP1);
+ clear(VTMP2);
+ clear(VTMP3);
+ clear(X12_TMP);
+ clear(X13_TMP);
+ clear(X0);
+ clear(X1);
+ clear(X2);
+ clear(X3);
+ clear(X4);
+ clear(X5);
+ clear(X6);
+ clear(X7);
+ clear(X8);
+ clear(X9);
+ clear(X10);
+ clear(X11);
+ clear(X12);
+ clear(X13);
+ clear(X14);
+ clear(X15);
+
+ eor x0, x0, x0
+ ret
+ CFI_ENDPROC()
+ELF(.size _gcry_chacha20_aarch64_blocks4, .-_gcry_chacha20_aarch64_blocks4;)
+
+/**********************************************************************
+ 4-way stitched chacha20-poly1305
+ **********************************************************************/
+
+.align 3
+.globl _gcry_chacha20_poly1305_aarch64_blocks4
+ELF(.type _gcry_chacha20_poly1305_aarch64_blocks4,%function;)
+
+_gcry_chacha20_poly1305_aarch64_blocks4:
+ /* input:
+ * x0: input
+ * x1: dst
+ * x2: src
+ * x3: nblks (multiple of 4)
+ * x4: poly1305-state
+ * x5: poly1305-src
+ */
+ CFI_STARTPROC()
+ POLY1305_PUSH_REGS()
+
+ mov POLY_RSTATE, x4;
+ mov POLY_RSRC, x5;
+
+ GET_DATA_POINTER(CTR, _gcry_chacha20_aarch64_blocks4_data_rot8);
+ add INPUT_CTR, INPUT, #(12*4);
+ ld1 {ROT8.16b}, [CTR];
+ GET_DATA_POINTER(CTR, _gcry_chacha20_aarch64_blocks4_data_inc_counter);
+ mov INPUT_POS, INPUT;
+ ld1 {VCTR.16b}, [CTR];
+
+ POLY1305_LOAD_STATE()
+
+.Loop_poly4:
+ /* Construct counter vectors X12 and X13 */
+
+ ld1 {X15.16b}, [INPUT_CTR];
+ ld1 {VTMP1.16b-VTMP3.16b}, [INPUT_POS];
+
+ dup X12.4s, X15.s[0];
+ dup X13.4s, X15.s[1];
+ ldr CTR, [INPUT_CTR];
+ add X12.4s, X12.4s, VCTR.4s;
+ dup X0.4s, VTMP1.s[0];
+ dup X1.4s, VTMP1.s[1];
+ dup X2.4s, VTMP1.s[2];
+ dup X3.4s, VTMP1.s[3];
+ dup X14.4s, X15.s[2];
+ cmhi VTMP0.4s, VCTR.4s, X12.4s;
+ dup X15.4s, X15.s[3];
+ add CTR, CTR, #4; /* Update counter */
+ dup X4.4s, VTMP2.s[0];
+ dup X5.4s, VTMP2.s[1];
+ dup X6.4s, VTMP2.s[2];
+ dup X7.4s, VTMP2.s[3];
+ sub X13.4s, X13.4s, VTMP0.4s;
+ dup X8.4s, VTMP3.s[0];
+ dup X9.4s, VTMP3.s[1];
+ dup X10.4s, VTMP3.s[2];
+ dup X11.4s, VTMP3.s[3];
+ mov X12_TMP.16b, X12.16b;
+ mov X13_TMP.16b, X13.16b;
+ str CTR, [INPUT_CTR];
+
+ mov ROUND, #20
+.Lround4_with_poly1305_outer:
+ mov POLY_CHACHA_ROUND, #6;
+.Lround4_with_poly1305_inner1:
+ POLY1305_BLOCK_PART1(0 * 16)
+ QUARTERROUND4(X0, X4, X8, X12, X1, X5, X9, X13,
+ X2, X6, X10, X14, X3, X7, X11, X15,
+ tmp:=,VTMP0,VTMP1,VTMP2,VTMP3,
+ POLY1305_BLOCK_PART2(0 * 16),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6(),
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8(),
+ POLY1305_BLOCK_PART9(),
+ POLY1305_BLOCK_PART10(),
+ POLY1305_BLOCK_PART11(),
+ POLY1305_BLOCK_PART12(),
+ POLY1305_BLOCK_PART13(),
+ POLY1305_BLOCK_PART14(),
+ POLY1305_BLOCK_PART15(),
+ POLY1305_BLOCK_PART16(),
+ POLY1305_BLOCK_PART17(),
+ POLY1305_BLOCK_PART18(),
+ POLY1305_BLOCK_PART19(),
+ POLY1305_BLOCK_PART20(),
+ POLY1305_BLOCK_PART21(),
+ POLY1305_BLOCK_PART22(),
+ POLY1305_BLOCK_PART23(),
+ POLY1305_BLOCK_PART24(),
+ POLY1305_BLOCK_PART25(),
+ POLY1305_BLOCK_PART26(),
+ POLY1305_BLOCK_PART27(),
+ POLY1305_BLOCK_PART28(),
+ POLY1305_BLOCK_PART29(),
+ POLY1305_BLOCK_PART1(1 * 16))
+ POLY1305_BLOCK_PART2(1 * 16)
+ QUARTERROUND4(X0, X5, X10, X15, X1, X6, X11, X12,
+ X2, X7, X8, X13, X3, X4, X9, X14,
+ tmp:=,VTMP0,VTMP1,VTMP2,VTMP3,
+ _(add POLY_RSRC, POLY_RSRC, #(2*16)),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6(),
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8(),
+ POLY1305_BLOCK_PART9(),
+ POLY1305_BLOCK_PART10(),
+ POLY1305_BLOCK_PART11(),
+ POLY1305_BLOCK_PART12(),
+ POLY1305_BLOCK_PART13(),
+ POLY1305_BLOCK_PART14(),
+ POLY1305_BLOCK_PART15(),
+ POLY1305_BLOCK_PART16(),
+ POLY1305_BLOCK_PART17(),
+ POLY1305_BLOCK_PART18(),
+ POLY1305_BLOCK_PART19(),
+ POLY1305_BLOCK_PART20(),
+ POLY1305_BLOCK_PART21(),
+ POLY1305_BLOCK_PART22(),
+ POLY1305_BLOCK_PART23(),
+ POLY1305_BLOCK_PART24(),
+ POLY1305_BLOCK_PART25(),
+ POLY1305_BLOCK_PART26(),
+ POLY1305_BLOCK_PART27(),
+ POLY1305_BLOCK_PART28(),
+ POLY1305_BLOCK_PART29(),
+ _(subs POLY_CHACHA_ROUND, POLY_CHACHA_ROUND, #2));
+ b.ne .Lround4_with_poly1305_inner1;
+
+ mov POLY_CHACHA_ROUND, #4;
+.Lround4_with_poly1305_inner2:
+ POLY1305_BLOCK_PART1(0 * 16)
+ QUARTERROUND4(X0, X4, X8, X12, X1, X5, X9, X13,
+ X2, X6, X10, X14, X3, X7, X11, X15,
+ tmp:=,VTMP0,VTMP1,VTMP2,VTMP3,,
+ POLY1305_BLOCK_PART2(0 * 16),,
+ _(add POLY_RSRC, POLY_RSRC, #(1*16)),,
+ POLY1305_BLOCK_PART3(),,
+ POLY1305_BLOCK_PART4(),,
+ POLY1305_BLOCK_PART5(),,
+ POLY1305_BLOCK_PART6(),,
+ POLY1305_BLOCK_PART7(),,
+ POLY1305_BLOCK_PART8(),,
+ POLY1305_BLOCK_PART9(),,
+ POLY1305_BLOCK_PART10(),,
+ POLY1305_BLOCK_PART11(),,
+ POLY1305_BLOCK_PART12(),,
+ POLY1305_BLOCK_PART13(),,
+ POLY1305_BLOCK_PART14(),)
+ POLY1305_BLOCK_PART15()
+ QUARTERROUND4(X0, X5, X10, X15, X1, X6, X11, X12,
+ X2, X7, X8, X13, X3, X4, X9, X14,
+ tmp:=,VTMP0,VTMP1,VTMP2,VTMP3,
+ POLY1305_BLOCK_PART16(),,
+ POLY1305_BLOCK_PART17(),,
+ POLY1305_BLOCK_PART18(),,
+ POLY1305_BLOCK_PART19(),,
+ POLY1305_BLOCK_PART20(),,
+ POLY1305_BLOCK_PART21(),,
+ POLY1305_BLOCK_PART22(),,
+ POLY1305_BLOCK_PART23(),,
+ POLY1305_BLOCK_PART24(),,
+ POLY1305_BLOCK_PART25(),,
+ POLY1305_BLOCK_PART26(),,
+ POLY1305_BLOCK_PART27(),,
+ POLY1305_BLOCK_PART28(),,
+ POLY1305_BLOCK_PART29(),
+ _(subs POLY_CHACHA_ROUND, POLY_CHACHA_ROUND, #2),)
+ b.ne .Lround4_with_poly1305_inner2;
+
+ subs ROUND, ROUND, #10
+ b.ne .Lround4_with_poly1305_outer;
+
+ ld1 {VTMP0.16b, VTMP1.16b}, [INPUT_POS], #32;
+
+ PLUS(X12, X12_TMP); /* INPUT + 12 * 4 + counter */
+ PLUS(X13, X13_TMP); /* INPUT + 13 * 4 + counter */
+
+ dup VTMP2.4s, VTMP0.s[0]; /* INPUT + 0 * 4 */
+ dup VTMP3.4s, VTMP0.s[1]; /* INPUT + 1 * 4 */
+ dup X12_TMP.4s, VTMP0.s[2]; /* INPUT + 2 * 4 */
+ dup X13_TMP.4s, VTMP0.s[3]; /* INPUT + 3 * 4 */
+ PLUS(X0, VTMP2);
+ PLUS(X1, VTMP3);
+ PLUS(X2, X12_TMP);
+ PLUS(X3, X13_TMP);
+
+ dup VTMP2.4s, VTMP1.s[0]; /* INPUT + 4 * 4 */
+ dup VTMP3.4s, VTMP1.s[1]; /* INPUT + 5 * 4 */
+ dup X12_TMP.4s, VTMP1.s[2]; /* INPUT + 6 * 4 */
+ dup X13_TMP.4s, VTMP1.s[3]; /* INPUT + 7 * 4 */
+ ld1 {VTMP0.16b, VTMP1.16b}, [INPUT_POS];
+ mov INPUT_POS, INPUT;
+ PLUS(X4, VTMP2);
+ PLUS(X5, VTMP3);
+ PLUS(X6, X12_TMP);
+ PLUS(X7, X13_TMP);
+
+ dup VTMP2.4s, VTMP0.s[0]; /* INPUT + 8 * 4 */
+ dup VTMP3.4s, VTMP0.s[1]; /* INPUT + 9 * 4 */
+ dup X12_TMP.4s, VTMP0.s[2]; /* INPUT + 10 * 4 */
+ dup X13_TMP.4s, VTMP0.s[3]; /* INPUT + 11 * 4 */
+ dup VTMP0.4s, VTMP1.s[2]; /* INPUT + 14 * 4 */
+ dup VTMP1.4s, VTMP1.s[3]; /* INPUT + 15 * 4 */
+ PLUS(X8, VTMP2);
+ PLUS(X9, VTMP3);
+ PLUS(X10, X12_TMP);
+ PLUS(X11, X13_TMP);
+ PLUS(X14, VTMP0);
+ PLUS(X15, VTMP1);
+
+ transpose_4x4(X0, X1, X2, X3, VTMP0, VTMP1, VTMP2);
+ transpose_4x4(X4, X5, X6, X7, VTMP0, VTMP1, VTMP2);
+ transpose_4x4(X8, X9, X10, X11, VTMP0, VTMP1, VTMP2);
+ transpose_4x4(X12, X13, X14, X15, VTMP0, VTMP1, VTMP2);
+
+ subs NBLKS, NBLKS, #4;
+
+ ld1 {VTMP0.16b-VTMP3.16b}, [SRC], #64;
+ ld1 {X12_TMP.16b-X13_TMP.16b}, [SRC], #32;
+ eor VTMP0.16b, X0.16b, VTMP0.16b;
+ eor VTMP1.16b, X4.16b, VTMP1.16b;
+ eor VTMP2.16b, X8.16b, VTMP2.16b;
+ eor VTMP3.16b, X12.16b, VTMP3.16b;
+ eor X12_TMP.16b, X1.16b, X12_TMP.16b;
+ eor X13_TMP.16b, X5.16b, X13_TMP.16b;
+ st1 {VTMP0.16b-VTMP3.16b}, [DST], #64;
+ ld1 {VTMP0.16b-VTMP3.16b}, [SRC], #64;
+ st1 {X12_TMP.16b-X13_TMP.16b}, [DST], #32;
+ ld1 {X12_TMP.16b-X13_TMP.16b}, [SRC], #32;
+ eor VTMP0.16b, X9.16b, VTMP0.16b;
+ eor VTMP1.16b, X13.16b, VTMP1.16b;
+ eor VTMP2.16b, X2.16b, VTMP2.16b;
+ eor VTMP3.16b, X6.16b, VTMP3.16b;
+ eor X12_TMP.16b, X10.16b, X12_TMP.16b;
+ eor X13_TMP.16b, X14.16b, X13_TMP.16b;
+ st1 {VTMP0.16b-VTMP3.16b}, [DST], #64;
+ ld1 {VTMP0.16b-VTMP3.16b}, [SRC], #64;
+ st1 {X12_TMP.16b-X13_TMP.16b}, [DST], #32;
+ eor VTMP0.16b, X3.16b, VTMP0.16b;
+ eor VTMP1.16b, X7.16b, VTMP1.16b;
+ eor VTMP2.16b, X11.16b, VTMP2.16b;
+ eor VTMP3.16b, X15.16b, VTMP3.16b;
+ st1 {VTMP0.16b-VTMP3.16b}, [DST], #64;
+
+ b.ne .Loop_poly4;
+
+ POLY1305_STORE_STATE()
+
+ /* clear the used vector registers and stack */
+ clear(VTMP0);
+ clear(VTMP1);
+ clear(VTMP2);
+ clear(VTMP3);
+ clear(X12_TMP);
+ clear(X13_TMP);
+ clear(X0);
+ clear(X1);
+ clear(X2);
+ clear(X3);
+ clear(X4);
+ clear(X5);
+ clear(X6);
+ clear(X7);
+ clear(X8);
+ clear(X9);
+ clear(X10);
+ clear(X11);
+ clear(X12);
+ clear(X13);
+ clear(X14);
+ clear(X15);
+
+ eor x0, x0, x0
+ POLY1305_POP_REGS()
+ ret
+ CFI_ENDPROC()
+ELF(.size _gcry_chacha20_poly1305_aarch64_blocks4, .-_gcry_chacha20_poly1305_aarch64_blocks4;)
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/chacha20-amd64-avx2.S b/comm/third_party/libgcrypt/cipher/chacha20-amd64-avx2.S
new file mode 100644
index 0000000000..51e107be83
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/chacha20-amd64-avx2.S
@@ -0,0 +1,601 @@
+/* chacha20-amd64-avx2.S - AVX2 implementation of ChaCha20 cipher
+ *
+ * Copyright (C) 2017-2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on D. J. Bernstein reference implementation at
+ * http://cr.yp.to/chacha.html:
+ *
+ * chacha-regs.c version 20080118
+ * D. J. Bernstein
+ * Public domain.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+.text
+
+#include "asm-common-amd64.h"
+#include "asm-poly1305-amd64.h"
+
+/* register macros */
+#define INPUT %rdi
+#define DST %rsi
+#define SRC %rdx
+#define NBLKS %rcx
+#define ROUND %eax
+
+/* stack structure */
+#define STACK_VEC_X12 (32)
+#define STACK_VEC_X13 (32 + STACK_VEC_X12)
+#define STACK_TMP (32 + STACK_VEC_X13)
+#define STACK_TMP1 (32 + STACK_TMP)
+
+#define STACK_MAX (32 + STACK_TMP1)
+
+/* vector registers */
+#define X0 %ymm0
+#define X1 %ymm1
+#define X2 %ymm2
+#define X3 %ymm3
+#define X4 %ymm4
+#define X5 %ymm5
+#define X6 %ymm6
+#define X7 %ymm7
+#define X8 %ymm8
+#define X9 %ymm9
+#define X10 %ymm10
+#define X11 %ymm11
+#define X12 %ymm12
+#define X13 %ymm13
+#define X14 %ymm14
+#define X15 %ymm15
+
+#define X0h %xmm0
+#define X1h %xmm1
+#define X2h %xmm2
+#define X3h %xmm3
+#define X4h %xmm4
+#define X5h %xmm5
+#define X6h %xmm6
+#define X7h %xmm7
+#define X8h %xmm8
+#define X9h %xmm9
+#define X10h %xmm10
+#define X11h %xmm11
+#define X12h %xmm12
+#define X13h %xmm13
+#define X14h %xmm14
+#define X15h %xmm15
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4(x0,x1,x2,x3,t1,t2) \
+ vpunpckhdq x1, x0, t2; \
+ vpunpckldq x1, x0, x0; \
+ \
+ vpunpckldq x3, x2, t1; \
+ vpunpckhdq x3, x2, x2; \
+ \
+ vpunpckhqdq t1, x0, x1; \
+ vpunpcklqdq t1, x0, x0; \
+ \
+ vpunpckhqdq x2, t2, x3; \
+ vpunpcklqdq x2, t2, x2;
+
+/* 2x2 128-bit matrix transpose */
+#define transpose_16byte_2x2(x0,x1,t1) \
+ vmovdqa x0, t1; \
+ vperm2i128 $0x20, x1, x0, x0; \
+ vperm2i128 $0x31, x1, t1, x1;
+
+/* xor register with unaligned src and save to unaligned dst */
+#define xor_src_dst(dst, src, offset, xreg) \
+ vpxor offset(src), xreg, xreg; \
+ vmovdqu xreg, offset(dst);
+
+/**********************************************************************
+ 8-way chacha20
+ **********************************************************************/
+
+#define ROTATE2(v1,v2,c,tmp) \
+ vpsrld $(32 - (c)), v1, tmp; \
+ vpslld $(c), v1, v1; \
+ vpaddb tmp, v1, v1; \
+ vpsrld $(32 - (c)), v2, tmp; \
+ vpslld $(c), v2, v2; \
+ vpaddb tmp, v2, v2;
+
+#define ROTATE_SHUF_2(v1,v2,shuf) \
+ vpshufb shuf, v1, v1; \
+ vpshufb shuf, v2, v2;
+
+#define XOR(ds,s) \
+ vpxor s, ds, ds;
+
+#define PLUS(ds,s) \
+ vpaddd s, ds, ds;
+
+#define QUARTERROUND2(a1,b1,c1,d1,a2,b2,c2,d2,ign,tmp1,\
+ interleave_op1,interleave_op2,\
+ interleave_op3,interleave_op4) \
+ vbroadcasti128 .Lshuf_rol16 rRIP, tmp1; \
+ interleave_op1; \
+ PLUS(a1,b1); PLUS(a2,b2); XOR(d1,a1); XOR(d2,a2); \
+ ROTATE_SHUF_2(d1, d2, tmp1); \
+ interleave_op2; \
+ PLUS(c1,d1); PLUS(c2,d2); XOR(b1,c1); XOR(b2,c2); \
+ ROTATE2(b1, b2, 12, tmp1); \
+ vbroadcasti128 .Lshuf_rol8 rRIP, tmp1; \
+ interleave_op3; \
+ PLUS(a1,b1); PLUS(a2,b2); XOR(d1,a1); XOR(d2,a2); \
+ ROTATE_SHUF_2(d1, d2, tmp1); \
+ interleave_op4; \
+ PLUS(c1,d1); PLUS(c2,d2); XOR(b1,c1); XOR(b2,c2); \
+ ROTATE2(b1, b2, 7, tmp1);
+
+.align 32
+chacha20_data:
+.Lshuf_rol16:
+ .byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.Lshuf_rol8:
+ .byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+.Linc_counter:
+ .byte 0,1,2,3,4,5,6,7
+.Lunsigned_cmp:
+ .long 0x80000000
+
+.align 8
+.globl _gcry_chacha20_amd64_avx2_blocks8
+ELF(.type _gcry_chacha20_amd64_avx2_blocks8,@function;)
+
+_gcry_chacha20_amd64_avx2_blocks8:
+ /* input:
+ * %rdi: input
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: nblks (multiple of 8)
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ subq $STACK_MAX, %rsp;
+ andq $~31, %rsp;
+
+.Loop8:
+ mov $20, ROUND;
+
+ /* Construct counter vectors X12 and X13 */
+ vpmovzxbd .Linc_counter rRIP, X0;
+ vpbroadcastd .Lunsigned_cmp rRIP, X2;
+ vpbroadcastd (12 * 4)(INPUT), X12;
+ vpbroadcastd (13 * 4)(INPUT), X13;
+ vpaddd X0, X12, X12;
+ vpxor X2, X0, X0;
+ vpxor X2, X12, X1;
+ vpcmpgtd X1, X0, X0;
+ vpsubd X0, X13, X13;
+ vmovdqa X12, (STACK_VEC_X12)(%rsp);
+ vmovdqa X13, (STACK_VEC_X13)(%rsp);
+
+ /* Load vectors */
+ vpbroadcastd (0 * 4)(INPUT), X0;
+ vpbroadcastd (1 * 4)(INPUT), X1;
+ vpbroadcastd (2 * 4)(INPUT), X2;
+ vpbroadcastd (3 * 4)(INPUT), X3;
+ vpbroadcastd (4 * 4)(INPUT), X4;
+ vpbroadcastd (5 * 4)(INPUT), X5;
+ vpbroadcastd (6 * 4)(INPUT), X6;
+ vpbroadcastd (7 * 4)(INPUT), X7;
+ vpbroadcastd (8 * 4)(INPUT), X8;
+ vpbroadcastd (9 * 4)(INPUT), X9;
+ vpbroadcastd (10 * 4)(INPUT), X10;
+ vpbroadcastd (11 * 4)(INPUT), X11;
+ vpbroadcastd (14 * 4)(INPUT), X14;
+ vpbroadcastd (15 * 4)(INPUT), X15;
+ vmovdqa X15, (STACK_TMP)(%rsp);
+
+.Lround2:
+ QUARTERROUND2(X0, X4, X8, X12, X1, X5, X9, X13, tmp:=,X15,,,,)
+ vmovdqa (STACK_TMP)(%rsp), X15;
+ vmovdqa X8, (STACK_TMP)(%rsp);
+ QUARTERROUND2(X2, X6, X10, X14, X3, X7, X11, X15, tmp:=,X8,,,,)
+ QUARTERROUND2(X0, X5, X10, X15, X1, X6, X11, X12, tmp:=,X8,,,,)
+ vmovdqa (STACK_TMP)(%rsp), X8;
+ vmovdqa X15, (STACK_TMP)(%rsp);
+ QUARTERROUND2(X2, X7, X8, X13, X3, X4, X9, X14, tmp:=,X15,,,,)
+ sub $2, ROUND;
+ jnz .Lround2;
+
+ vmovdqa X8, (STACK_TMP1)(%rsp);
+
+ /* tmp := X15 */
+ vpbroadcastd (0 * 4)(INPUT), X15;
+ PLUS(X0, X15);
+ vpbroadcastd (1 * 4)(INPUT), X15;
+ PLUS(X1, X15);
+ vpbroadcastd (2 * 4)(INPUT), X15;
+ PLUS(X2, X15);
+ vpbroadcastd (3 * 4)(INPUT), X15;
+ PLUS(X3, X15);
+ vpbroadcastd (4 * 4)(INPUT), X15;
+ PLUS(X4, X15);
+ vpbroadcastd (5 * 4)(INPUT), X15;
+ PLUS(X5, X15);
+ vpbroadcastd (6 * 4)(INPUT), X15;
+ PLUS(X6, X15);
+ vpbroadcastd (7 * 4)(INPUT), X15;
+ PLUS(X7, X15);
+ transpose_4x4(X0, X1, X2, X3, X8, X15);
+ transpose_4x4(X4, X5, X6, X7, X8, X15);
+ vmovdqa (STACK_TMP1)(%rsp), X8;
+ transpose_16byte_2x2(X0, X4, X15);
+ transpose_16byte_2x2(X1, X5, X15);
+ transpose_16byte_2x2(X2, X6, X15);
+ transpose_16byte_2x2(X3, X7, X15);
+ vmovdqa (STACK_TMP)(%rsp), X15;
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 0), X0);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 0), X1);
+ vpbroadcastd (8 * 4)(INPUT), X0;
+ PLUS(X8, X0);
+ vpbroadcastd (9 * 4)(INPUT), X0;
+ PLUS(X9, X0);
+ vpbroadcastd (10 * 4)(INPUT), X0;
+ PLUS(X10, X0);
+ vpbroadcastd (11 * 4)(INPUT), X0;
+ PLUS(X11, X0);
+ vmovdqa (STACK_VEC_X12)(%rsp), X0;
+ PLUS(X12, X0);
+ vmovdqa (STACK_VEC_X13)(%rsp), X0;
+ PLUS(X13, X0);
+ vpbroadcastd (14 * 4)(INPUT), X0;
+ PLUS(X14, X0);
+ vpbroadcastd (15 * 4)(INPUT), X0;
+ PLUS(X15, X0);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 0), X2);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 0), X3);
+
+ /* Update counter */
+ addq $8, (12 * 4)(INPUT);
+
+ transpose_4x4(X8, X9, X10, X11, X0, X1);
+ transpose_4x4(X12, X13, X14, X15, X0, X1);
+ xor_src_dst(DST, SRC, (64 * 4 + 16 * 0), X4);
+ xor_src_dst(DST, SRC, (64 * 5 + 16 * 0), X5);
+ transpose_16byte_2x2(X8, X12, X0);
+ transpose_16byte_2x2(X9, X13, X0);
+ transpose_16byte_2x2(X10, X14, X0);
+ transpose_16byte_2x2(X11, X15, X0);
+ xor_src_dst(DST, SRC, (64 * 6 + 16 * 0), X6);
+ xor_src_dst(DST, SRC, (64 * 7 + 16 * 0), X7);
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 2), X8);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 2), X9);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 2), X10);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 2), X11);
+ xor_src_dst(DST, SRC, (64 * 4 + 16 * 2), X12);
+ xor_src_dst(DST, SRC, (64 * 5 + 16 * 2), X13);
+ xor_src_dst(DST, SRC, (64 * 6 + 16 * 2), X14);
+ xor_src_dst(DST, SRC, (64 * 7 + 16 * 2), X15);
+
+ sub $8, NBLKS;
+ lea (8 * 64)(DST), DST;
+ lea (8 * 64)(SRC), SRC;
+ jnz .Loop8;
+
+ /* clear the used vector registers and stack */
+ vpxor X0, X0, X0;
+ vmovdqa X0, (STACK_VEC_X12)(%rsp);
+ vmovdqa X0, (STACK_VEC_X13)(%rsp);
+ vmovdqa X0, (STACK_TMP)(%rsp);
+ vmovdqa X0, (STACK_TMP1)(%rsp);
+ vzeroall;
+
+ /* eax zeroed by round loop. */
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_amd64_avx2_blocks8,
+ .-_gcry_chacha20_amd64_avx2_blocks8;)
+
+/**********************************************************************
+ 8-way stitched chacha20-poly1305
+ **********************************************************************/
+
+#define _ /*_*/
+
+.align 8
+.globl _gcry_chacha20_poly1305_amd64_avx2_blocks8
+ELF(.type _gcry_chacha20_poly1305_amd64_avx2_blocks8,@function;)
+
+_gcry_chacha20_poly1305_amd64_avx2_blocks8:
+ /* input:
+ * %rdi: input
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: nblks (multiple of 8)
+ * %r9: poly1305-state
+ * %r8: poly1305-src
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ vzeroupper;
+
+ subq $(9 * 8) + STACK_MAX + 32, %rsp;
+ andq $~31, %rsp;
+
+ movq %rbx, (STACK_MAX + 0 * 8)(%rsp);
+ movq %r12, (STACK_MAX + 1 * 8)(%rsp);
+ movq %r13, (STACK_MAX + 2 * 8)(%rsp);
+ movq %r14, (STACK_MAX + 3 * 8)(%rsp);
+ movq %r15, (STACK_MAX + 4 * 8)(%rsp);
+ CFI_REG_ON_STACK(rbx, STACK_MAX + 0 * 8);
+ CFI_REG_ON_STACK(r12, STACK_MAX + 1 * 8);
+ CFI_REG_ON_STACK(r13, STACK_MAX + 2 * 8);
+ CFI_REG_ON_STACK(r14, STACK_MAX + 3 * 8);
+ CFI_REG_ON_STACK(r15, STACK_MAX + 4 * 8);
+
+ movq %rdx, (STACK_MAX + 5 * 8)(%rsp); # SRC
+ movq %rsi, (STACK_MAX + 6 * 8)(%rsp); # DST
+ movq %rcx, (STACK_MAX + 7 * 8)(%rsp); # NBLKS
+
+ /* Load state */
+ POLY1305_LOAD_STATE();
+
+.Loop_poly8:
+
+ /* Construct counter vectors X12 and X13 */
+ vpmovzxbd .Linc_counter rRIP, X0;
+ vpbroadcastd .Lunsigned_cmp rRIP, X2;
+ vpbroadcastd (12 * 4)(INPUT), X12;
+ vpbroadcastd (13 * 4)(INPUT), X13;
+ vpaddd X0, X12, X12;
+ vpxor X2, X0, X0;
+ vpxor X2, X12, X1;
+ vpcmpgtd X1, X0, X0;
+ vpsubd X0, X13, X13;
+ vmovdqa X12, (STACK_VEC_X12)(%rsp);
+ vmovdqa X13, (STACK_VEC_X13)(%rsp);
+
+ /* Load vectors */
+ vpbroadcastd (0 * 4)(INPUT), X0;
+ vpbroadcastd (1 * 4)(INPUT), X1;
+ vpbroadcastd (2 * 4)(INPUT), X2;
+ vpbroadcastd (3 * 4)(INPUT), X3;
+ vpbroadcastd (4 * 4)(INPUT), X4;
+ vpbroadcastd (5 * 4)(INPUT), X5;
+ vpbroadcastd (6 * 4)(INPUT), X6;
+ vpbroadcastd (7 * 4)(INPUT), X7;
+ vpbroadcastd (8 * 4)(INPUT), X8;
+ vpbroadcastd (9 * 4)(INPUT), X9;
+ vpbroadcastd (10 * 4)(INPUT), X10;
+ vpbroadcastd (11 * 4)(INPUT), X11;
+ vpbroadcastd (14 * 4)(INPUT), X14;
+ vpbroadcastd (15 * 4)(INPUT), X15;
+ vmovdqa X15, (STACK_TMP)(%rsp);
+
+ /* Process eight ChaCha20 blocks and 32 Poly1305 blocks. */
+
+ movl $20, (STACK_MAX + 8 * 8 + 4)(%rsp);
+.Lround8_with_poly1305_outer:
+ movl $6, (STACK_MAX + 8 * 8)(%rsp);
+.Lround8_with_poly1305_inner1:
+ /* rounds 0-5 & 10-15 */
+ POLY1305_BLOCK_PART1(0 * 16)
+ QUARTERROUND2(X0, X4, X8, X12, X1, X5, X9, X13, tmp:=,X15,
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5())
+ vmovdqa (STACK_TMP)(%rsp), X15;
+ vmovdqa X8, (STACK_TMP)(%rsp);
+ POLY1305_BLOCK_PART1(1 * 16)
+ QUARTERROUND2(X2, X6, X10, X14, X3, X7, X11, X15, tmp:=,X8,
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5())
+ POLY1305_BLOCK_PART1(2 * 16)
+ QUARTERROUND2(X0, X5, X10, X15, X1, X6, X11, X12, tmp:=,X8,
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5())
+ vmovdqa (STACK_TMP)(%rsp), X8;
+ vmovdqa X15, (STACK_TMP)(%rsp);
+ POLY1305_BLOCK_PART1(3 * 16)
+ lea (4 * 16)(POLY_RSRC), POLY_RSRC;
+ QUARTERROUND2(X2, X7, X8, X13, X3, X4, X9, X14, tmp:=,X15,
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5())
+
+ subl $2, (STACK_MAX + 8 * 8)(%rsp);
+ jnz .Lround8_with_poly1305_inner1;
+
+ movl $4, (STACK_MAX + 8 * 8)(%rsp);
+.Lround8_with_poly1305_inner2:
+ /* rounds 6-9 & 16-19 */
+ POLY1305_BLOCK_PART1(0 * 16)
+ QUARTERROUND2(X0, X4, X8, X12, X1, X5, X9, X13, tmp:=,X15,
+ POLY1305_BLOCK_PART2(),
+ _,
+ POLY1305_BLOCK_PART3(),
+ _)
+ vmovdqa (STACK_TMP)(%rsp), X15;
+ vmovdqa X8, (STACK_TMP)(%rsp);
+ QUARTERROUND2(X2, X6, X10, X14, X3, X7, X11, X15, tmp:=,X8,
+ _,
+ POLY1305_BLOCK_PART4(),
+ _,
+ POLY1305_BLOCK_PART5())
+ POLY1305_BLOCK_PART1(1 * 16);
+ lea (2 * 16)(POLY_RSRC), POLY_RSRC;
+ QUARTERROUND2(X0, X5, X10, X15, X1, X6, X11, X12, tmp:=,X8,
+ _,
+ POLY1305_BLOCK_PART2(),
+ _,
+ POLY1305_BLOCK_PART3())
+ vmovdqa (STACK_TMP)(%rsp), X8;
+ vmovdqa X15, (STACK_TMP)(%rsp);
+ QUARTERROUND2(X2, X7, X8, X13, X3, X4, X9, X14, tmp:=,X15,
+ POLY1305_BLOCK_PART4(),
+ _,
+ POLY1305_BLOCK_PART5(),
+ _)
+
+ subl $2, (STACK_MAX + 8 * 8)(%rsp);
+ jnz .Lround8_with_poly1305_inner2;
+
+ subl $10, (STACK_MAX + 8 * 8 + 4)(%rsp);
+ jnz .Lround8_with_poly1305_outer;
+
+ movq (STACK_MAX + 5 * 8)(%rsp), SRC;
+ movq (STACK_MAX + 6 * 8)(%rsp), DST;
+
+ vmovdqa X8, (STACK_TMP1)(%rsp);
+
+ /* tmp := X15 */
+ vpbroadcastd (0 * 4)(INPUT), X15;
+ PLUS(X0, X15);
+ vpbroadcastd (1 * 4)(INPUT), X15;
+ PLUS(X1, X15);
+ vpbroadcastd (2 * 4)(INPUT), X15;
+ PLUS(X2, X15);
+ vpbroadcastd (3 * 4)(INPUT), X15;
+ PLUS(X3, X15);
+ vpbroadcastd (4 * 4)(INPUT), X15;
+ PLUS(X4, X15);
+ vpbroadcastd (5 * 4)(INPUT), X15;
+ PLUS(X5, X15);
+ vpbroadcastd (6 * 4)(INPUT), X15;
+ PLUS(X6, X15);
+ vpbroadcastd (7 * 4)(INPUT), X15;
+ PLUS(X7, X15);
+ transpose_4x4(X0, X1, X2, X3, X8, X15);
+ transpose_4x4(X4, X5, X6, X7, X8, X15);
+ vmovdqa (STACK_TMP1)(%rsp), X8;
+ transpose_16byte_2x2(X0, X4, X15);
+ transpose_16byte_2x2(X1, X5, X15);
+ transpose_16byte_2x2(X2, X6, X15);
+ transpose_16byte_2x2(X3, X7, X15);
+ vmovdqa (STACK_TMP)(%rsp), X15;
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 0), X0);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 0), X1);
+ vpbroadcastd (8 * 4)(INPUT), X0;
+ PLUS(X8, X0);
+ vpbroadcastd (9 * 4)(INPUT), X0;
+ PLUS(X9, X0);
+ vpbroadcastd (10 * 4)(INPUT), X0;
+ PLUS(X10, X0);
+ vpbroadcastd (11 * 4)(INPUT), X0;
+ PLUS(X11, X0);
+ vmovdqa (STACK_VEC_X12)(%rsp), X0;
+ PLUS(X12, X0);
+ vmovdqa (STACK_VEC_X13)(%rsp), X0;
+ PLUS(X13, X0);
+ vpbroadcastd (14 * 4)(INPUT), X0;
+ PLUS(X14, X0);
+ vpbroadcastd (15 * 4)(INPUT), X0;
+ PLUS(X15, X0);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 0), X2);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 0), X3);
+
+ /* Update counter */
+ addq $8, (12 * 4)(INPUT);
+
+ transpose_4x4(X8, X9, X10, X11, X0, X1);
+ transpose_4x4(X12, X13, X14, X15, X0, X1);
+ xor_src_dst(DST, SRC, (64 * 4 + 16 * 0), X4);
+ xor_src_dst(DST, SRC, (64 * 5 + 16 * 0), X5);
+ transpose_16byte_2x2(X8, X12, X0);
+ transpose_16byte_2x2(X9, X13, X0);
+ transpose_16byte_2x2(X10, X14, X0);
+ transpose_16byte_2x2(X11, X15, X0);
+ xor_src_dst(DST, SRC, (64 * 6 + 16 * 0), X6);
+ xor_src_dst(DST, SRC, (64 * 7 + 16 * 0), X7);
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 2), X8);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 2), X9);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 2), X10);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 2), X11);
+ xor_src_dst(DST, SRC, (64 * 4 + 16 * 2), X12);
+ xor_src_dst(DST, SRC, (64 * 5 + 16 * 2), X13);
+ xor_src_dst(DST, SRC, (64 * 6 + 16 * 2), X14);
+ xor_src_dst(DST, SRC, (64 * 7 + 16 * 2), X15);
+
+ subq $8, (STACK_MAX + 7 * 8)(%rsp); # NBLKS
+
+ lea (8 * 64)(DST), DST;
+ lea (8 * 64)(SRC), SRC;
+ movq SRC, (STACK_MAX + 5 * 8)(%rsp);
+ movq DST, (STACK_MAX + 6 * 8)(%rsp);
+
+ jnz .Loop_poly8;
+
+ /* Store state */
+ POLY1305_STORE_STATE();
+
+ /* clear the used vector registers and stack */
+ vpxor X0, X0, X0;
+ vmovdqa X0, (STACK_VEC_X12)(%rsp);
+ vmovdqa X0, (STACK_VEC_X13)(%rsp);
+ vmovdqa X0, (STACK_TMP)(%rsp);
+ vmovdqa X0, (STACK_TMP1)(%rsp);
+ vzeroall;
+
+ movq (STACK_MAX + 0 * 8)(%rsp), %rbx;
+ movq (STACK_MAX + 1 * 8)(%rsp), %r12;
+ movq (STACK_MAX + 2 * 8)(%rsp), %r13;
+ movq (STACK_MAX + 3 * 8)(%rsp), %r14;
+ movq (STACK_MAX + 4 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+
+ xorl %eax, %eax;
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_poly1305_amd64_avx2_blocks8,
+ .-_gcry_chacha20_poly1305_amd64_avx2_blocks8;)
+
+#endif /*defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/chacha20-amd64-ssse3.S b/comm/third_party/libgcrypt/cipher/chacha20-amd64-ssse3.S
new file mode 100644
index 0000000000..9cdb69ae6d
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/chacha20-amd64-ssse3.S
@@ -0,0 +1,1012 @@
+/* chacha20-amd64-ssse3.S - SSSE3 implementation of ChaCha20 cipher
+ *
+ * Copyright (C) 2017-2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on D. J. Bernstein reference implementation at
+ * http://cr.yp.to/chacha.html:
+ *
+ * chacha-regs.c version 20080118
+ * D. J. Bernstein
+ * Public domain.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+.text
+
+#include "asm-common-amd64.h"
+#include "asm-poly1305-amd64.h"
+
+/* register macros */
+#define INPUT %rdi
+#define DST %rsi
+#define SRC %rdx
+#define NBLKS %rcx
+#define ROUND %eax
+
+/* stack structure */
+#define STACK_VEC_X12 (16)
+#define STACK_VEC_X13 (16 + STACK_VEC_X12)
+#define STACK_TMP (16 + STACK_VEC_X13)
+#define STACK_TMP1 (16 + STACK_TMP)
+#define STACK_TMP2 (16 + STACK_TMP1)
+
+#define STACK_MAX (16 + STACK_TMP2)
+
+/* vector registers */
+#define X0 %xmm0
+#define X1 %xmm1
+#define X2 %xmm2
+#define X3 %xmm3
+#define X4 %xmm4
+#define X5 %xmm5
+#define X6 %xmm6
+#define X7 %xmm7
+#define X8 %xmm8
+#define X9 %xmm9
+#define X10 %xmm10
+#define X11 %xmm11
+#define X12 %xmm12
+#define X13 %xmm13
+#define X14 %xmm14
+#define X15 %xmm15
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
+ movdqa x0, t2; \
+ punpckhdq x1, t2; \
+ punpckldq x1, x0; \
+ \
+ movdqa x2, t1; \
+ punpckldq x3, t1; \
+ punpckhdq x3, x2; \
+ \
+ movdqa x0, x1; \
+ punpckhqdq t1, x1; \
+ punpcklqdq t1, x0; \
+ \
+ movdqa t2, x3; \
+ punpckhqdq x2, x3; \
+ punpcklqdq x2, t2; \
+ movdqa t2, x2;
+
+/* fill xmm register with 32-bit value from memory */
+#define pbroadcastd(mem32, xreg) \
+ movd mem32, xreg; \
+ pshufd $0, xreg, xreg;
+
+/* xor with unaligned memory operand */
+#define pxor_u(umem128, xreg, t) \
+ movdqu umem128, t; \
+ pxor t, xreg;
+
+/* xor register with unaligned src and save to unaligned dst */
+#define xor_src_dst(dst, src, offset, xreg, t) \
+ pxor_u(offset(src), xreg, t); \
+ movdqu xreg, offset(dst);
+
+#define clear(x) pxor x,x;
+
+/**********************************************************************
+ 4-way chacha20
+ **********************************************************************/
+
+#define ROTATE2(v1,v2,c,tmp1,tmp2) \
+ movdqa v1, tmp1; \
+ movdqa v2, tmp2; \
+ psrld $(32 - (c)), v1; \
+ pslld $(c), tmp1; \
+ paddb tmp1, v1; \
+ psrld $(32 - (c)), v2; \
+ pslld $(c), tmp2; \
+ paddb tmp2, v2;
+
+#define ROTATE_SHUF_2(v1,v2,shuf) \
+ pshufb shuf, v1; \
+ pshufb shuf, v2;
+
+#define XOR(ds,s) \
+ pxor s, ds;
+
+#define PLUS(ds,s) \
+ paddd s, ds;
+
+#define QUARTERROUND2(a1,b1,c1,d1,a2,b2,c2,d2,ign,tmp1,tmp2,\
+ interleave_op1,interleave_op2) \
+ movdqa .Lshuf_rol16 rRIP, tmp1; \
+ interleave_op1; \
+ PLUS(a1,b1); PLUS(a2,b2); XOR(d1,a1); XOR(d2,a2); \
+ ROTATE_SHUF_2(d1, d2, tmp1); \
+ PLUS(c1,d1); PLUS(c2,d2); XOR(b1,c1); XOR(b2,c2); \
+ ROTATE2(b1, b2, 12, tmp1, tmp2); \
+ movdqa .Lshuf_rol8 rRIP, tmp1; \
+ interleave_op2; \
+ PLUS(a1,b1); PLUS(a2,b2); XOR(d1,a1); XOR(d2,a2); \
+ ROTATE_SHUF_2(d1, d2, tmp1); \
+ PLUS(c1,d1); PLUS(c2,d2); XOR(b1,c1); XOR(b2,c2); \
+ ROTATE2(b1, b2, 7, tmp1, tmp2);
+
+chacha20_data:
+.align 16
+.Lshuf_rol16:
+ .byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.Lshuf_rol8:
+ .byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+.Lcounter1:
+ .long 1,0,0,0
+.Linc_counter:
+ .long 0,1,2,3
+.Lunsigned_cmp:
+ .long 0x80000000,0x80000000,0x80000000,0x80000000
+
+.align 8
+.globl _gcry_chacha20_amd64_ssse3_blocks4
+ELF(.type _gcry_chacha20_amd64_ssse3_blocks4,@function;)
+
+_gcry_chacha20_amd64_ssse3_blocks4:
+ /* input:
+ * %rdi: input
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: nblks (multiple of 4)
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ subq $STACK_MAX, %rsp;
+ andq $~15, %rsp;
+
+.Loop4:
+ mov $20, ROUND;
+
+ /* Construct counter vectors X12 and X13 */
+ movdqa .Linc_counter rRIP, X0;
+ movdqa .Lunsigned_cmp rRIP, X2;
+ pbroadcastd((12 * 4)(INPUT), X12);
+ pbroadcastd((13 * 4)(INPUT), X13);
+ paddd X0, X12;
+ movdqa X12, X1;
+ pxor X2, X0;
+ pxor X2, X1;
+ pcmpgtd X1, X0;
+ psubd X0, X13;
+ movdqa X12, (STACK_VEC_X12)(%rsp);
+ movdqa X13, (STACK_VEC_X13)(%rsp);
+
+ /* Load vectors */
+ pbroadcastd((0 * 4)(INPUT), X0);
+ pbroadcastd((1 * 4)(INPUT), X1);
+ pbroadcastd((2 * 4)(INPUT), X2);
+ pbroadcastd((3 * 4)(INPUT), X3);
+ pbroadcastd((4 * 4)(INPUT), X4);
+ pbroadcastd((5 * 4)(INPUT), X5);
+ pbroadcastd((6 * 4)(INPUT), X6);
+ pbroadcastd((7 * 4)(INPUT), X7);
+ pbroadcastd((8 * 4)(INPUT), X8);
+ pbroadcastd((9 * 4)(INPUT), X9);
+ pbroadcastd((10 * 4)(INPUT), X10);
+ pbroadcastd((11 * 4)(INPUT), X11);
+ pbroadcastd((14 * 4)(INPUT), X14);
+ pbroadcastd((15 * 4)(INPUT), X15);
+ movdqa X11, (STACK_TMP)(%rsp);
+ movdqa X15, (STACK_TMP1)(%rsp);
+
+.Lround2_4:
+ QUARTERROUND2(X0, X4, X8, X12, X1, X5, X9, X13, tmp:=,X11,X15,,)
+ movdqa (STACK_TMP)(%rsp), X11;
+ movdqa (STACK_TMP1)(%rsp), X15;
+ movdqa X8, (STACK_TMP)(%rsp);
+ movdqa X9, (STACK_TMP1)(%rsp);
+ QUARTERROUND2(X2, X6, X10, X14, X3, X7, X11, X15, tmp:=,X8,X9,,)
+ QUARTERROUND2(X0, X5, X10, X15, X1, X6, X11, X12, tmp:=,X8,X9,,)
+ movdqa (STACK_TMP)(%rsp), X8;
+ movdqa (STACK_TMP1)(%rsp), X9;
+ movdqa X11, (STACK_TMP)(%rsp);
+ movdqa X15, (STACK_TMP1)(%rsp);
+ QUARTERROUND2(X2, X7, X8, X13, X3, X4, X9, X14, tmp:=,X11,X15,,)
+ sub $2, ROUND;
+ jnz .Lround2_4;
+
+ /* tmp := X15 */
+ movdqa (STACK_TMP)(%rsp), X11;
+ pbroadcastd((0 * 4)(INPUT), X15);
+ PLUS(X0, X15);
+ pbroadcastd((1 * 4)(INPUT), X15);
+ PLUS(X1, X15);
+ pbroadcastd((2 * 4)(INPUT), X15);
+ PLUS(X2, X15);
+ pbroadcastd((3 * 4)(INPUT), X15);
+ PLUS(X3, X15);
+ pbroadcastd((4 * 4)(INPUT), X15);
+ PLUS(X4, X15);
+ pbroadcastd((5 * 4)(INPUT), X15);
+ PLUS(X5, X15);
+ pbroadcastd((6 * 4)(INPUT), X15);
+ PLUS(X6, X15);
+ pbroadcastd((7 * 4)(INPUT), X15);
+ PLUS(X7, X15);
+ pbroadcastd((8 * 4)(INPUT), X15);
+ PLUS(X8, X15);
+ pbroadcastd((9 * 4)(INPUT), X15);
+ PLUS(X9, X15);
+ pbroadcastd((10 * 4)(INPUT), X15);
+ PLUS(X10, X15);
+ pbroadcastd((11 * 4)(INPUT), X15);
+ PLUS(X11, X15);
+ movdqa (STACK_VEC_X12)(%rsp), X15;
+ PLUS(X12, X15);
+ movdqa (STACK_VEC_X13)(%rsp), X15;
+ PLUS(X13, X15);
+ movdqa X13, (STACK_TMP)(%rsp);
+ pbroadcastd((14 * 4)(INPUT), X15);
+ PLUS(X14, X15);
+ movdqa (STACK_TMP1)(%rsp), X15;
+ movdqa X14, (STACK_TMP1)(%rsp);
+ pbroadcastd((15 * 4)(INPUT), X13);
+ PLUS(X15, X13);
+ movdqa X15, (STACK_TMP2)(%rsp);
+
+ /* Update counter */
+ addq $4, (12 * 4)(INPUT);
+
+ transpose_4x4(X0, X1, X2, X3, X13, X14, X15);
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 0), X0, X15);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 0), X1, X15);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 0), X2, X15);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 0), X3, X15);
+ transpose_4x4(X4, X5, X6, X7, X0, X1, X2);
+ movdqa (STACK_TMP)(%rsp), X13;
+ movdqa (STACK_TMP1)(%rsp), X14;
+ movdqa (STACK_TMP2)(%rsp), X15;
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 1), X4, X0);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 1), X5, X0);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 1), X6, X0);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 1), X7, X0);
+ transpose_4x4(X8, X9, X10, X11, X0, X1, X2);
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 2), X8, X0);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 2), X9, X0);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 2), X10, X0);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 2), X11, X0);
+ transpose_4x4(X12, X13, X14, X15, X0, X1, X2);
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 3), X12, X0);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 3), X13, X0);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 3), X14, X0);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 3), X15, X0);
+
+ sub $4, NBLKS;
+ lea (4 * 64)(DST), DST;
+ lea (4 * 64)(SRC), SRC;
+ jnz .Loop4;
+
+ /* clear the used vector registers and stack */
+ clear(X0);
+ movdqa X0, (STACK_VEC_X12)(%rsp);
+ movdqa X0, (STACK_VEC_X13)(%rsp);
+ movdqa X0, (STACK_TMP)(%rsp);
+ movdqa X0, (STACK_TMP1)(%rsp);
+ movdqa X0, (STACK_TMP2)(%rsp);
+ clear(X1);
+ clear(X2);
+ clear(X3);
+ clear(X4);
+ clear(X5);
+ clear(X6);
+ clear(X7);
+ clear(X8);
+ clear(X9);
+ clear(X10);
+ clear(X11);
+ clear(X12);
+ clear(X13);
+ clear(X14);
+ clear(X15);
+
+ /* eax zeroed by round loop. */
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_amd64_ssse3_blocks4,
+ .-_gcry_chacha20_amd64_ssse3_blocks4;)
+
+/**********************************************************************
+ 2-way && 1-way chacha20
+ **********************************************************************/
+
+#define ROTATE_SHUF(v1,shuf) \
+ pshufb shuf, v1;
+
+#define ROTATE(v1,c,tmp1) \
+ movdqa v1, tmp1; \
+ psrld $(32 - (c)), v1; \
+ pslld $(c), tmp1; \
+ paddb tmp1, v1;
+
+#define WORD_SHUF(v1,shuf) \
+ pshufd $shuf, v1, v1;
+
+#define QUARTERROUND4(x0,x1,x2,x3,shuf_rol8,shuf_rol16,tmp1,shuf_x1,\
+ shuf_x2,shuf_x3) \
+ PLUS(x0, x1); XOR(x3, x0); ROTATE_SHUF(x3, shuf_rol16); \
+ PLUS(x2, x3); XOR(x1, x2); ROTATE(x1, 12, tmp1); \
+ PLUS(x0, x1); XOR(x3, x0); ROTATE_SHUF(x3, shuf_rol8); \
+ PLUS(x2, x3); \
+ WORD_SHUF(x3, shuf_x3); \
+ XOR(x1, x2); \
+ WORD_SHUF(x2, shuf_x2); \
+ ROTATE(x1, 7, tmp1); \
+ WORD_SHUF(x1, shuf_x1);
+
+.align 8
+.globl _gcry_chacha20_amd64_ssse3_blocks1
+ELF(.type _gcry_chacha20_amd64_ssse3_blocks1,@function;)
+
+_gcry_chacha20_amd64_ssse3_blocks1:
+ /* input:
+ * %rdi: input
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: nblks
+ */
+ CFI_STARTPROC();
+
+ /* Load constants */
+ movdqa .Lcounter1 rRIP, X4;
+ movdqa .Lshuf_rol8 rRIP, X5;
+ movdqa .Lshuf_rol16 rRIP, X6;
+
+ /* Load state */
+ movdqu (0 * 4)(INPUT), X10;
+ movdqu (4 * 4)(INPUT), X11;
+ movdqu (8 * 4)(INPUT), X12;
+ movdqu (12 * 4)(INPUT), X13;
+
+ cmp $2, NBLKS;
+ jb .Loop1;
+
+ mov $20, ROUND;
+
+ movdqa X10, X0;
+ movdqa X11, X1;
+ movdqa X12, X2;
+ movdqa X13, X3;
+
+ movdqa X10, X8;
+ movdqa X11, X9;
+ movdqa X12, X14;
+ movdqa X13, X15;
+ paddq X4, X15;
+
+.Lround2_2:
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93);
+ QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93);
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39);
+ QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39);
+ sub $2, ROUND;
+ jnz .Lround2_2;
+
+ PLUS(X0, X10);
+ PLUS(X1, X11);
+ PLUS(X2, X12);
+ PLUS(X3, X13);
+
+ /* Update counter */
+ paddq X4, X13;
+
+ PLUS(X8, X10);
+ PLUS(X9, X11);
+ PLUS(X14, X12);
+ PLUS(X15, X13);
+
+ /* Update counter */
+ paddq X4, X13;
+
+ xor_src_dst(DST, SRC, 0 * 4, X0, X7);
+ xor_src_dst(DST, SRC, 4 * 4, X1, X7);
+ xor_src_dst(DST, SRC, 8 * 4, X2, X7);
+ xor_src_dst(DST, SRC, 12 * 4, X3, X7);
+ xor_src_dst(DST, SRC, 16 * 4, X8, X7);
+ xor_src_dst(DST, SRC, 20 * 4, X9, X7);
+ xor_src_dst(DST, SRC, 24 * 4, X14, X7);
+ xor_src_dst(DST, SRC, 28 * 4, X15, X7);
+
+ lea (2 * 64)(DST), DST;
+ lea (2 * 64)(SRC), SRC;
+
+ clear(X8);
+ clear(X9);
+ clear(X14);
+ clear(X15);
+
+ sub $2, NBLKS;
+ jz .Ldone1;
+
+.Loop1:
+ mov $20, ROUND;
+
+ movdqa X10, X0;
+ movdqa X11, X1;
+ movdqa X12, X2;
+ movdqa X13, X3;
+
+.Lround2_1:
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93);
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39);
+ sub $2, ROUND;
+ jnz .Lround2_1;
+
+ PLUS(X0, X10);
+ PLUS(X1, X11);
+ PLUS(X2, X12);
+ PLUS(X3, X13);
+
+ /* Update counter */
+ paddq X4, X13;
+
+ xor_src_dst(DST, SRC, 0 * 4, X0, X7);
+ xor_src_dst(DST, SRC, 4 * 4, X1, X7);
+ xor_src_dst(DST, SRC, 8 * 4, X2, X7);
+ xor_src_dst(DST, SRC, 12 * 4, X3, X7);
+
+ lea (64)(DST), DST;
+ lea (64)(SRC), SRC;
+
+ sub $1, NBLKS;
+ jnz .Loop1;
+
+.Ldone1:
+ /* Store counter */
+ movdqu X13, (12 * 4)(INPUT);
+
+ /* clear the used vector registers */
+ clear(X0);
+ clear(X1);
+ clear(X2);
+ clear(X3);
+ clear(X4);
+ clear(X5);
+ clear(X6);
+ clear(X7);
+ clear(X10);
+ clear(X11);
+ clear(X12);
+ clear(X13);
+
+ /* eax zeroed by round loop. */
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_amd64_ssse3_blocks1,
+ .-_gcry_chacha20_amd64_ssse3_blocks1;)
+
+/**********************************************************************
+ 4-way stitched chacha20-poly1305
+ **********************************************************************/
+
+#define _ /*_*/
+
+.align 8
+.globl _gcry_chacha20_poly1305_amd64_ssse3_blocks4
+ELF(.type _gcry_chacha20_poly1305_amd64_ssse3_blocks4,@function;)
+
+_gcry_chacha20_poly1305_amd64_ssse3_blocks4:
+ /* input:
+ * %rdi: input
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: nblks (multiple of 4)
+ * %r9: poly1305-state
+ * %r8: poly1305-src
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ subq $(9 * 8) + STACK_MAX + 16, %rsp;
+ andq $~15, %rsp;
+
+ movq %rbx, (STACK_MAX + 0 * 8)(%rsp);
+ movq %r12, (STACK_MAX + 1 * 8)(%rsp);
+ movq %r13, (STACK_MAX + 2 * 8)(%rsp);
+ movq %r14, (STACK_MAX + 3 * 8)(%rsp);
+ movq %r15, (STACK_MAX + 4 * 8)(%rsp);
+ CFI_REG_ON_STACK(rbx, STACK_MAX + 0 * 8);
+ CFI_REG_ON_STACK(r12, STACK_MAX + 1 * 8);
+ CFI_REG_ON_STACK(r13, STACK_MAX + 2 * 8);
+ CFI_REG_ON_STACK(r14, STACK_MAX + 3 * 8);
+ CFI_REG_ON_STACK(r15, STACK_MAX + 4 * 8);
+
+ movq %rdx, (STACK_MAX + 5 * 8)(%rsp); # SRC
+ movq %rsi, (STACK_MAX + 6 * 8)(%rsp); # DST
+ movq %rcx, (STACK_MAX + 7 * 8)(%rsp); # NBLKS
+
+ /* Load state */
+ POLY1305_LOAD_STATE();
+
+.Loop_poly4:
+
+ /* Construct counter vectors X12 and X13 */
+ movdqa .Linc_counter rRIP, X0;
+ movdqa .Lunsigned_cmp rRIP, X2;
+ pbroadcastd((12 * 4)(INPUT), X12);
+ pbroadcastd((13 * 4)(INPUT), X13);
+ paddd X0, X12;
+ movdqa X12, X1;
+ pxor X2, X0;
+ pxor X2, X1;
+ pcmpgtd X1, X0;
+ psubd X0, X13;
+ movdqa X12, (STACK_VEC_X12)(%rsp);
+ movdqa X13, (STACK_VEC_X13)(%rsp);
+
+ /* Load vectors */
+ pbroadcastd((0 * 4)(INPUT), X0);
+ pbroadcastd((1 * 4)(INPUT), X1);
+ pbroadcastd((2 * 4)(INPUT), X2);
+ pbroadcastd((3 * 4)(INPUT), X3);
+ pbroadcastd((4 * 4)(INPUT), X4);
+ pbroadcastd((5 * 4)(INPUT), X5);
+ pbroadcastd((6 * 4)(INPUT), X6);
+ pbroadcastd((7 * 4)(INPUT), X7);
+ pbroadcastd((8 * 4)(INPUT), X8);
+ pbroadcastd((9 * 4)(INPUT), X9);
+ pbroadcastd((10 * 4)(INPUT), X10);
+ pbroadcastd((11 * 4)(INPUT), X11);
+ pbroadcastd((14 * 4)(INPUT), X14);
+ pbroadcastd((15 * 4)(INPUT), X15);
+ movdqa X11, (STACK_TMP)(%rsp);
+ movdqa X15, (STACK_TMP1)(%rsp);
+
+ /* Process four ChaCha20 blocks and sixteen Poly1305 blocks. */
+
+ movl $20, (STACK_MAX + 8 * 8 + 4)(%rsp);
+.Lround4_with_poly1305_outer:
+ movl $6, (STACK_MAX + 8 * 8)(%rsp);
+.Lround4_with_poly1305_inner1:
+ /* rounds 0-5 & 10-15 */
+ POLY1305_BLOCK_PART1(0 * 16)
+ QUARTERROUND2(X0, X4, X8, X12, X1, X5, X9, X13, tmp:=,X11,X15,
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3())
+ movdqa (STACK_TMP)(%rsp), X11;
+ movdqa (STACK_TMP1)(%rsp), X15;
+ movdqa X8, (STACK_TMP)(%rsp);
+ movdqa X9, (STACK_TMP1)(%rsp);
+ QUARTERROUND2(X2, X6, X10, X14, X3, X7, X11, X15, tmp:=,X8,X9,
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5())
+ POLY1305_BLOCK_PART1(1 * 16)
+ lea (2 * 16)(POLY_RSRC), POLY_RSRC;
+ QUARTERROUND2(X0, X5, X10, X15, X1, X6, X11, X12, tmp:=,X8,X9,
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3())
+ movdqa (STACK_TMP)(%rsp), X8;
+ movdqa (STACK_TMP1)(%rsp), X9;
+ movdqa X11, (STACK_TMP)(%rsp);
+ movdqa X15, (STACK_TMP1)(%rsp);
+ QUARTERROUND2(X2, X7, X8, X13, X3, X4, X9, X14, tmp:=,X11,X15,
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5())
+
+ subl $2, (STACK_MAX + 8 * 8)(%rsp);
+ jnz .Lround4_with_poly1305_inner1;
+
+ movl $4, (STACK_MAX + 8 * 8)(%rsp);
+.Lround4_with_poly1305_inner2:
+ /* rounds 6-9 & 16-19 */
+ POLY1305_BLOCK_PART1(0 * 16)
+ lea (1 * 16)(POLY_RSRC), POLY_RSRC;
+ QUARTERROUND2(X0, X4, X8, X12, X1, X5, X9, X13, tmp:=,X11,X15,
+ POLY1305_BLOCK_PART2(),
+ _)
+ movdqa (STACK_TMP)(%rsp), X11;
+ movdqa (STACK_TMP1)(%rsp), X15;
+ movdqa X8, (STACK_TMP)(%rsp);
+ movdqa X9, (STACK_TMP1)(%rsp);
+ QUARTERROUND2(X2, X6, X10, X14, X3, X7, X11, X15, tmp:=,X8,X9,
+ POLY1305_BLOCK_PART3(),
+ _)
+ QUARTERROUND2(X0, X5, X10, X15, X1, X6, X11, X12, tmp:=,X8,X9,
+ POLY1305_BLOCK_PART4(),
+ _)
+ movdqa (STACK_TMP)(%rsp), X8;
+ movdqa (STACK_TMP1)(%rsp), X9;
+ movdqa X11, (STACK_TMP)(%rsp);
+ movdqa X15, (STACK_TMP1)(%rsp);
+ QUARTERROUND2(X2, X7, X8, X13, X3, X4, X9, X14, tmp:=,X11,X15,
+ POLY1305_BLOCK_PART5(),
+ _)
+
+ subl $2, (STACK_MAX + 8 * 8)(%rsp);
+ jnz .Lround4_with_poly1305_inner2;
+
+ subl $10, (STACK_MAX + 8 * 8 + 4)(%rsp);
+ jnz .Lround4_with_poly1305_outer;
+
+ /* tmp := X15 */
+ movdqa (STACK_TMP)(%rsp), X11;
+ pbroadcastd((0 * 4)(INPUT), X15);
+ PLUS(X0, X15);
+ pbroadcastd((1 * 4)(INPUT), X15);
+ PLUS(X1, X15);
+ pbroadcastd((2 * 4)(INPUT), X15);
+ PLUS(X2, X15);
+ pbroadcastd((3 * 4)(INPUT), X15);
+ PLUS(X3, X15);
+ pbroadcastd((4 * 4)(INPUT), X15);
+ PLUS(X4, X15);
+ pbroadcastd((5 * 4)(INPUT), X15);
+ PLUS(X5, X15);
+ pbroadcastd((6 * 4)(INPUT), X15);
+ PLUS(X6, X15);
+ pbroadcastd((7 * 4)(INPUT), X15);
+ PLUS(X7, X15);
+ pbroadcastd((8 * 4)(INPUT), X15);
+ PLUS(X8, X15);
+ pbroadcastd((9 * 4)(INPUT), X15);
+ PLUS(X9, X15);
+ pbroadcastd((10 * 4)(INPUT), X15);
+ PLUS(X10, X15);
+ pbroadcastd((11 * 4)(INPUT), X15);
+ PLUS(X11, X15);
+ movdqa (STACK_VEC_X12)(%rsp), X15;
+ PLUS(X12, X15);
+ movdqa (STACK_VEC_X13)(%rsp), X15;
+ PLUS(X13, X15);
+ movdqa X13, (STACK_TMP)(%rsp);
+ pbroadcastd((14 * 4)(INPUT), X15);
+ PLUS(X14, X15);
+ movdqa (STACK_TMP1)(%rsp), X15;
+ movdqa X14, (STACK_TMP1)(%rsp);
+ pbroadcastd((15 * 4)(INPUT), X13);
+ PLUS(X15, X13);
+ movdqa X15, (STACK_TMP2)(%rsp);
+
+ /* Update counter */
+ addq $4, (12 * 4)(INPUT);
+
+ movq (STACK_MAX + 5 * 8)(%rsp), SRC;
+ movq (STACK_MAX + 6 * 8)(%rsp), DST;
+
+ transpose_4x4(X0, X1, X2, X3, X13, X14, X15);
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 0), X0, X15);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 0), X1, X15);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 0), X2, X15);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 0), X3, X15);
+ transpose_4x4(X4, X5, X6, X7, X0, X1, X2);
+ movdqa (STACK_TMP)(%rsp), X13;
+ movdqa (STACK_TMP1)(%rsp), X14;
+ movdqa (STACK_TMP2)(%rsp), X15;
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 1), X4, X0);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 1), X5, X0);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 1), X6, X0);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 1), X7, X0);
+ transpose_4x4(X8, X9, X10, X11, X0, X1, X2);
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 2), X8, X0);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 2), X9, X0);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 2), X10, X0);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 2), X11, X0);
+ transpose_4x4(X12, X13, X14, X15, X0, X1, X2);
+ xor_src_dst(DST, SRC, (64 * 0 + 16 * 3), X12, X0);
+ xor_src_dst(DST, SRC, (64 * 1 + 16 * 3), X13, X0);
+ xor_src_dst(DST, SRC, (64 * 2 + 16 * 3), X14, X0);
+ xor_src_dst(DST, SRC, (64 * 3 + 16 * 3), X15, X0);
+
+ subq $4, (STACK_MAX + 7 * 8)(%rsp); # NBLKS
+
+ lea (4 * 64)(DST), DST;
+ lea (4 * 64)(SRC), SRC;
+ movq SRC, (STACK_MAX + 5 * 8)(%rsp);
+ movq DST, (STACK_MAX + 6 * 8)(%rsp);
+
+ jnz .Loop_poly4;
+
+ /* Store state */
+ POLY1305_STORE_STATE();
+
+ /* clear the used vector registers and stack */
+ clear(X0);
+ movdqa X0, (STACK_VEC_X12)(%rsp);
+ movdqa X0, (STACK_VEC_X13)(%rsp);
+ movdqa X0, (STACK_TMP)(%rsp);
+ movdqa X0, (STACK_TMP1)(%rsp);
+ movdqa X0, (STACK_TMP2)(%rsp);
+ clear(X1);
+ clear(X2);
+ clear(X3);
+ clear(X4);
+ clear(X5);
+ clear(X6);
+ clear(X7);
+ clear(X8);
+ clear(X9);
+ clear(X10);
+ clear(X11);
+ clear(X12);
+ clear(X13);
+ clear(X14);
+ clear(X15);
+
+ movq (STACK_MAX + 0 * 8)(%rsp), %rbx;
+ movq (STACK_MAX + 1 * 8)(%rsp), %r12;
+ movq (STACK_MAX + 2 * 8)(%rsp), %r13;
+ movq (STACK_MAX + 3 * 8)(%rsp), %r14;
+ movq (STACK_MAX + 4 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+
+ xorl %eax, %eax;
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_poly1305_amd64_ssse3_blocks4,
+ .-_gcry_chacha20_poly1305_amd64_ssse3_blocks4;)
+
+/**********************************************************************
+ 2-way && 1-way stitched chacha20-poly1305
+ **********************************************************************/
+
+.align 8
+.globl _gcry_chacha20_poly1305_amd64_ssse3_blocks1
+ELF(.type _gcry_chacha20_poly1305_amd64_ssse3_blocks1,@function;)
+
+_gcry_chacha20_poly1305_amd64_ssse3_blocks1:
+ /* input:
+ * %rdi: chacha20-state
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: nblks
+ * %r9: poly1305-state
+ * %r8: poly1305-src
+ */
+ CFI_STARTPROC();
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ movq %rsp, %rbp;
+ CFI_DEF_CFA_REGISTER(%rbp);
+
+ subq $(9 * 8), %rsp;
+ movq %rbx, (0 * 8)(%rsp);
+ movq %r12, (1 * 8)(%rsp);
+ movq %r13, (2 * 8)(%rsp);
+ movq %r14, (3 * 8)(%rsp);
+ movq %r15, (4 * 8)(%rsp);
+ CFI_REG_ON_STACK(rbx, 0 * 8);
+ CFI_REG_ON_STACK(r12, 1 * 8);
+ CFI_REG_ON_STACK(r13, 2 * 8);
+ CFI_REG_ON_STACK(r14, 3 * 8);
+ CFI_REG_ON_STACK(r15, 4 * 8);
+
+ movq %rdx, (5 * 8)(%rsp); # SRC
+ movq %rsi, (6 * 8)(%rsp); # DST
+ movq %rcx, (7 * 8)(%rsp); # NBLKS
+
+ /* Load constants */
+ movdqa .Lcounter1 rRIP, X4;
+ movdqa .Lshuf_rol8 rRIP, X5;
+ movdqa .Lshuf_rol16 rRIP, X6;
+
+ /* Load state */
+ movdqu (0 * 4)(INPUT), X10;
+ movdqu (4 * 4)(INPUT), X11;
+ movdqu (8 * 4)(INPUT), X12;
+ movdqu (12 * 4)(INPUT), X13;
+
+ POLY1305_LOAD_STATE();
+
+ cmpq $2, (7 * 8)(%rsp); #NBLKS
+ jb .Loop_poly1;
+
+ movdqa X10, X0;
+ movdqa X11, X1;
+ movdqa X12, X2;
+ movdqa X13, X3;
+
+ movdqa X10, X8;
+ movdqa X11, X9;
+ movdqa X12, X14;
+ movdqa X13, X15;
+ paddq X4, X15;
+
+ /* Process two ChaCha20 blocks and eight Poly1305 blocks. */
+
+ movl $20, (8 * 8 + 4)(%rsp);
+.Lround2_with_poly1305_outer:
+ movl $8, (8 * 8)(%rsp);
+.Lround2_with_poly1305_inner:
+ POLY1305_BLOCK_PART1(0 * 16);
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93);
+ lea (1 * 16)(POLY_RSRC), POLY_RSRC;
+ POLY1305_BLOCK_PART2();
+ QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93);
+ POLY1305_BLOCK_PART3();
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39);
+ POLY1305_BLOCK_PART4();
+ QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39);
+ POLY1305_BLOCK_PART5();
+
+ subl $2, (8 * 8)(%rsp);
+ jnz .Lround2_with_poly1305_inner;
+
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93);
+ QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93);
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39);
+ QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39);
+
+ subl $10, (8 * 8 + 4)(%rsp);
+ jnz .Lround2_with_poly1305_outer;
+
+ movq (5 * 8)(%rsp), SRC;
+ movq (6 * 8)(%rsp), DST;
+
+ PLUS(X0, X10);
+ PLUS(X1, X11);
+ PLUS(X2, X12);
+ PLUS(X3, X13);
+
+ /* Update counter */
+ paddq X4, X13;
+
+ PLUS(X8, X10);
+ PLUS(X9, X11);
+ PLUS(X14, X12);
+ PLUS(X15, X13);
+
+ /* Update counter */
+ paddq X4, X13;
+
+ xor_src_dst(DST, SRC, 0 * 4, X0, X7);
+ xor_src_dst(DST, SRC, 4 * 4, X1, X7);
+ xor_src_dst(DST, SRC, 8 * 4, X2, X7);
+ xor_src_dst(DST, SRC, 12 * 4, X3, X7);
+ xor_src_dst(DST, SRC, 16 * 4, X8, X7);
+ xor_src_dst(DST, SRC, 20 * 4, X9, X7);
+ xor_src_dst(DST, SRC, 24 * 4, X14, X7);
+ xor_src_dst(DST, SRC, 28 * 4, X15, X7);
+
+ clear(X8);
+ clear(X9);
+ clear(X14);
+ clear(X15);
+
+ subq $2, (7 * 8)(%rsp); # NBLKS
+ lea (2 * 64)(SRC), SRC;
+ lea (2 * 64)(DST), DST;
+ movq SRC, (5 * 8)(%rsp);
+ movq DST, (6 * 8)(%rsp);
+ jz .Ldone_poly1;
+
+.Loop_poly1:
+ movdqa X10, X0;
+ movdqa X11, X1;
+ movdqa X12, X2;
+ movdqa X13, X3;
+
+ /* Process one ChaCha20 block and four Poly1305 blocks. */
+
+ movl $20, (8 * 8 + 4)(%rsp);
+.Lround1_with_poly1305_outer:
+ movl $8, (8 * 8)(%rsp);
+.Lround1_with_poly1305_inner:
+ POLY1305_BLOCK_PART1(0 * 16);
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93);
+ POLY1305_BLOCK_PART2();
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39);
+ lea (1 * 16)(POLY_RSRC), POLY_RSRC;
+
+ POLY1305_BLOCK_PART3();
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93);
+ POLY1305_BLOCK_PART4();
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39);
+ POLY1305_BLOCK_PART5();
+
+ subl $4, (8 * 8)(%rsp);
+ jnz .Lround1_with_poly1305_inner;
+
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93);
+ QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39);
+
+ subl $10, (8 * 8 + 4)(%rsp);
+ jnz .Lround1_with_poly1305_outer;
+
+ movq (5 * 8)(%rsp), SRC;
+ movq (6 * 8)(%rsp), DST;
+
+ PLUS(X0, X10);
+ PLUS(X1, X11);
+ PLUS(X2, X12);
+ PLUS(X3, X13);
+
+ /* Update counter */
+ paddq X4, X13;
+
+ xor_src_dst(DST, SRC, 0 * 4, X0, X7);
+ xor_src_dst(DST, SRC, 4 * 4, X1, X7);
+ xor_src_dst(DST, SRC, 8 * 4, X2, X7);
+ xor_src_dst(DST, SRC, 12 * 4, X3, X7);
+
+ subq $1, (7 * 8)(%rsp); # NBLKS
+ lea (64)(SRC), SRC;
+ lea (64)(DST), DST;
+ movq SRC, (5 * 8)(%rsp);
+ movq DST, (6 * 8)(%rsp);
+
+ jnz .Loop_poly1;
+
+.Ldone_poly1:
+ /* Store state */
+ POLY1305_STORE_STATE();
+
+ movdqu X13, (12 * 4)(INPUT);
+
+ /* clear the used vector registers */
+ clear(X0);
+ clear(X1);
+ clear(X2);
+ clear(X3);
+ clear(X4);
+ clear(X5);
+ clear(X6);
+ clear(X7);
+ clear(X10);
+ clear(X11);
+ clear(X12);
+ clear(X13);
+
+ movq (0 * 8)(%rsp), %rbx;
+ movq (1 * 8)(%rsp), %r12;
+ movq (2 * 8)(%rsp), %r13;
+ movq (3 * 8)(%rsp), %r14;
+ movq (4 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+
+ xorl %eax, %eax;
+ leave;
+ CFI_LEAVE();
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_poly1305_amd64_ssse3_blocks1,
+ .-_gcry_chacha20_poly1305_amd64_ssse3_blocks1;)
+
+#endif /*defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/chacha20-armv7-neon.S b/comm/third_party/libgcrypt/cipher/chacha20-armv7-neon.S
new file mode 100644
index 0000000000..33a43df1f3
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/chacha20-armv7-neon.S
@@ -0,0 +1,393 @@
+/* chacha20-armv7-neon.S - ARMv7 NEON implementation of ChaCha20 cipher
+ *
+ * Copyright (C) 2017,2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on D. J. Bernstein reference implementation at
+ * http://cr.yp.to/chacha.html:
+ *
+ * chacha-regs.c version 20080118
+ * D. J. Bernstein
+ * Public domain.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_NEON)
+
+.syntax unified
+.fpu neon
+.arm
+
+.text
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+/* register macros */
+#define INPUT r0
+#define DST r1
+#define SRC r2
+#define NBLKS r3
+#define ROUND r4
+
+/* stack structure */
+#define STACK_VEC_X12 (16)
+#define STACK_VEC_X13 (STACK_VEC_X12 + 16)
+#define STACK_TMP (STACK_VEC_X13 + 16)
+#define STACK_TMP1 (16 + STACK_TMP)
+#define STACK_TMP2 (16 + STACK_TMP1)
+
+#define STACK_MAX (16 + STACK_TMP2)
+
+/* vector registers */
+#define X0 q0
+#define X1 q1
+#define X2 q2
+#define X3 q3
+#define X4 q4
+#define X5 q5
+#define X6 q6
+#define X7 q7
+#define X8 q8
+#define X9 q9
+#define X10 q10
+#define X11 q11
+#define X12 q12
+#define X13 q13
+#define X14 q14
+#define X15 q15
+
+#define X0l d0
+#define X1l d2
+#define X2l d4
+#define X3l d6
+#define X4l d8
+#define X5l d10
+#define X6l d12
+#define X7l d14
+#define X8l d16
+#define X9l d18
+#define X10l d20
+#define X11l d22
+#define X12l d24
+#define X13l d26
+#define X14l d28
+#define X15l d30
+
+#define X0h d1
+#define X1h d3
+#define X2h d5
+#define X3h d7
+#define X4h d9
+#define X5h d11
+#define X6h d13
+#define X7h d15
+#define X8h d17
+#define X9h d19
+#define X10h d21
+#define X11h d23
+#define X12h d25
+#define X13h d27
+#define X14h d29
+#define X15h d31
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4_part1(_q0, _q1, _q2, _q3) \
+ vtrn.32 _q0, _q1; \
+ vtrn.32 _q2, _q3;
+#define transpose_4x4_part2(_q0, _q1, _q2, _q3) \
+ vswp _q0##h, _q2##l; \
+ vswp _q1##h, _q3##l;
+
+#define clear(x) veor x,x,x;
+
+/**********************************************************************
+ 4-way chacha20
+ **********************************************************************/
+
+#define ROTATE2(dst1,dst2,c,src1,src2) \
+ vshl.u32 dst1, src1, #(c); \
+ vshl.u32 dst2, src2, #(c); \
+ vsri.u32 dst1, src1, #(32 - (c)); \
+ vsri.u32 dst2, src2, #(32 - (c));
+
+#define ROTATE2_16(dst1,dst2,src1,src2) \
+ vrev32.16 dst1, src1; \
+ vrev32.16 dst2, src2;
+
+#define XOR(d,s1,s2) \
+ veor d, s2, s1;
+
+#define PLUS(ds,s) \
+ vadd.u32 ds, ds, s;
+
+#define QUARTERROUND2(a1,b1,c1,d1,a2,b2,c2,d2,ign,tmp1,tmp2) \
+ PLUS(a1,b1); PLUS(a2,b2); XOR(tmp1,d1,a1); XOR(tmp2,d2,a2); \
+ ROTATE2_16(d1, d2, tmp1, tmp2); \
+ PLUS(c1,d1); PLUS(c2,d2); XOR(tmp1,b1,c1); XOR(tmp2,b2,c2); \
+ ROTATE2(b1, b2, 12, tmp1, tmp2); \
+ PLUS(a1,b1); PLUS(a2,b2); XOR(tmp1,d1,a1); XOR(tmp2,d2,a2); \
+ ROTATE2(d1, d2, 8, tmp1, tmp2); \
+ PLUS(c1,d1); PLUS(c2,d2); XOR(tmp1,b1,c1); XOR(tmp2,b2,c2); \
+ ROTATE2(b1, b2, 7, tmp1, tmp2);
+
+chacha20_data:
+.align 4
+.Linc_counter:
+ .long 0,1,2,3
+
+.align 3
+.globl _gcry_chacha20_armv7_neon_blocks4
+.type _gcry_chacha20_armv7_neon_blocks4,%function;
+
+_gcry_chacha20_armv7_neon_blocks4:
+ /* input:
+ * r0: input
+ * r1: dst
+ * r2: src
+ * r3: nblks (multiple of 4)
+ */
+
+ vpush {q4-q7};
+ push {r4-r12,lr};
+
+ mov r12, sp
+
+ mov r6, sp;
+ sub r6, r6, #(STACK_MAX);
+ and r6, r6, #(~15);
+ mov sp, r6;
+ GET_DATA_POINTER(r9, .Linc_counter, lr);
+ add lr, INPUT, #(12*4);
+ add r8, sp, #STACK_VEC_X12;
+
+.Loop4:
+ mov ROUND, #20;
+
+ /* Construct counter vectors X12 and X13 */
+
+ vld1.8 {X15}, [lr];
+ mov lr, INPUT;
+ vld1.8 {X8}, [r9];
+ vdup.32 X12, X15l[0];
+ vdup.32 X13, X15l[1];
+ vld1.8 {X3}, [lr]!;
+ vadd.u32 X12, X12, X8;
+ vdup.32 X0, X3l[0];
+ vdup.32 X1, X3l[1];
+ vdup.32 X2, X3h[0];
+ vcgt.u32 X8, X8, X12;
+ vdup.32 X3, X3h[1];
+ vdup.32 X14, X15h[0];
+ vdup.32 X15, X15h[1];
+ vsub.u32 X13, X13, X8;
+ vld1.8 {X7}, [lr]!;
+ vld1.8 {X11}, [lr];
+ vst1.8 {X12, X13}, [r8];
+ vdup.32 X4, X7l[0];
+ vdup.32 X5, X7l[1];
+ vdup.32 X6, X7h[0];
+ vdup.32 X7, X7h[1];
+ vdup.32 X8, X11l[0];
+ vdup.32 X9, X11l[1];
+ vdup.32 X10, X11h[0];
+ vdup.32 X11, X11h[1];
+
+ add r7, sp, #STACK_TMP2;
+ add r6, sp, #STACK_TMP1;
+ add r5, sp, #STACK_TMP;
+ vst1.8 {X15}, [r6];
+ vst1.8 {X11}, [r5];
+
+ mov lr, INPUT;
+.Lround2:
+ subs ROUND, ROUND, #2
+ QUARTERROUND2(X0, X4, X8, X12, X1, X5, X9, X13, tmp:=,X11,X15)
+ vld1.8 {X11}, [r5];
+ vld1.8 {X15}, [r6];
+ vst1.8 {X8}, [r5];
+ vst1.8 {X9}, [r6];
+ QUARTERROUND2(X2, X6, X10, X14, X3, X7, X11, X15, tmp:=,X8,X9)
+ QUARTERROUND2(X0, X5, X10, X15, X1, X6, X11, X12, tmp:=,X8,X9)
+ vld1.8 {X8}, [r5];
+ vld1.8 {X9}, [r6];
+ vst1.8 {X11}, [r5];
+ vst1.8 {X15}, [r6];
+ QUARTERROUND2(X2, X7, X8, X13, X3, X4, X9, X14, tmp:=,X11,X15)
+ bne .Lround2;
+
+ vld1.8 {X11}, [lr]!;
+ vst1.8 {X14}, [r7];
+
+ vdup.32 X14, X11l[0]; /* INPUT + 0 * 4 */
+ vdup.32 X15, X11l[1]; /* INPUT + 1 * 4 */
+ PLUS(X0, X14);
+ PLUS(X1, X15);
+ vdup.32 X14, X11h[0]; /* INPUT + 2 * 4 */
+ vdup.32 X15, X11h[1]; /* INPUT + 3 * 4 */
+ PLUS(X2, X14);
+ PLUS(X3, X15);
+
+ vld1.8 {X11}, [r5];
+ vld1.8 {X15}, [r6];
+ vst1.8 {X0}, [r5];
+ vld1.8 {X0}, [lr]!;
+ vst1.8 {X1}, [r6];
+
+ vdup.32 X14, X0l[0]; /* INPUT + 4 * 4 */
+ vdup.32 X1, X0l[1]; /* INPUT + 5 * 4 */
+ PLUS(X4, X14);
+ PLUS(X5, X1);
+ vdup.32 X14, X0h[0]; /* INPUT + 6 * 4 */
+ vdup.32 X1, X0h[1]; /* INPUT + 7 * 4 */
+ PLUS(X6, X14);
+ PLUS(X7, X1);
+
+ vld1.8 {X0}, [lr]!;
+
+ vdup.32 X14, X0l[0]; /* INPUT + 8 * 4 */
+ vdup.32 X1, X0l[1]; /* INPUT + 9 * 4 */
+ PLUS(X8, X14);
+ PLUS(X9, X1);
+ vdup.32 X14, X0h[0]; /* INPUT + 10 * 4 */
+ vdup.32 X1, X0h[1]; /* INPUT + 11 * 4 */
+ PLUS(X10, X14);
+ PLUS(X11, X1);
+
+ vld1.8 {X0}, [lr];
+ add lr, INPUT, #(12*4)
+ vld1.8 {X14}, [r7];
+
+ vdup.32 X1, X0h[0]; /* INPUT + 10 * 4 */
+ ldm lr, {r10, r11}; /* Update counter */
+ vdup.32 X0, X0h[1]; /* INPUT + 11 * 4 */
+ PLUS(X14, X1);
+ PLUS(X15, X0);
+ adds r10, r10, #4; /* Update counter */
+ vld1.8 {X0, X1}, [r8];
+
+ PLUS(X12, X0);
+ vld1.8 {X0}, [r5];
+ PLUS(X13, X1);
+ adc r11, r11, #0; /* Update counter */
+
+ vld1.8 {X1}, [r6];
+ stm lr, {r10, r11}; /* Update counter */
+ transpose_4x4_part1(X0, X1, X2, X3);
+ transpose_4x4_part1(X4, X5, X6, X7);
+ transpose_4x4_part1(X8, X9, X10, X11);
+ transpose_4x4_part1(X12, X13, X14, X15);
+ transpose_4x4_part2(X0, X1, X2, X3);
+ transpose_4x4_part2(X4, X5, X6, X7);
+ transpose_4x4_part2(X8, X9, X10, X11);
+ transpose_4x4_part2(X12, X13, X14, X15);
+
+ subs NBLKS, NBLKS, #4;
+
+ vst1.8 {X10}, [r5];
+ add lr, INPUT, #(12*4)
+ vst1.8 {X11}, [r6];
+ vld1.8 {X10, X11}, [SRC]!;
+ veor X10, X0, X10;
+ vld1.8 {X0}, [SRC]!;
+ veor X11, X4, X11;
+ vld1.8 {X4}, [SRC]!;
+ vst1.8 {X10, X11}, [DST]!;
+ vld1.8 {X10, X11}, [SRC]!;
+ veor X0, X8, X0;
+ veor X4, X12, X4;
+ veor X10, X1, X10;
+ veor X11, X5, X11;
+ vst1.8 {X0}, [DST]!;
+ vld1.8 {X0, X1}, [SRC]!;
+ vst1.8 {X4}, [DST]!;
+ vld1.8 {X4, X5}, [SRC]!;
+ vst1.8 {X10, X11}, [DST]!;
+ vld1.8 {X10}, [r5];
+ vld1.8 {X11}, [r6];
+ veor X0, X9, X0;
+ vld1.8 {X8, X9}, [SRC]!;
+ veor X1, X13, X1;
+ vld1.8 {X12, X13}, [SRC]!;
+ veor X4, X2, X4;
+ veor X5, X6, X5;
+ vst1.8 {X0, X1}, [DST]!;
+ vld1.8 {X0, X1}, [SRC]!;
+ vst1.8 {X4, X5}, [DST]!;
+ veor X8, X10, X8;
+ veor X9, X14, X9;
+ veor X12, X3, X12;
+ veor X13, X7, X13;
+ veor X0, X11, X0;
+ veor X1, X15, X1;
+ vst1.8 {X8, X9}, [DST]!;
+ vst1.8 {X12, X13}, [DST]!;
+ vst1.8 {X0, X1}, [DST]!;
+
+ bne .Loop4;
+
+ /* clear the used vector registers and stack */
+ clear(X0);
+ vst1.8 {X0}, [r5];
+ vst1.8 {X0}, [r6];
+ vst1.8 {X0}, [r7];
+ vst1.8 {X0}, [r8]!;
+ vst1.8 {X0}, [r8];
+
+ mov sp, r12
+ clear(X1);
+ clear(X2);
+ clear(X3);
+ clear(X4);
+ clear(X5);
+ clear(X6);
+ clear(X7);
+ clear(X8);
+ clear(X9);
+ clear(X10);
+ clear(X11);
+ clear(X12);
+ clear(X13);
+ clear(X14);
+ clear(X15);
+
+ pop {r4-r12,lr}
+ vpop {q4-q7}
+ eor r0, r0, r0
+ bx lr
+.size _gcry_chacha20_armv7_neon_blocks4, .-_gcry_chacha20_armv7_neon_blocks4;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/chacha20-ppc.c b/comm/third_party/libgcrypt/cipher/chacha20-ppc.c
new file mode 100644
index 0000000000..4a21b837d1
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/chacha20-ppc.c
@@ -0,0 +1,646 @@
+/* chacha20-ppc.c - PowerPC vector implementation of ChaCha20
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(ENABLE_PPC_CRYPTO_SUPPORT) && \
+ defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) && \
+ defined(USE_CHACHA20) && \
+ __GNUC__ >= 4
+
+#include <altivec.h>
+#include "bufhelp.h"
+#include "poly1305-internal.h"
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+typedef vector unsigned char vector16x_u8;
+typedef vector unsigned int vector4x_u32;
+typedef vector unsigned long long vector2x_u64;
+
+
+#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
+
+
+#ifdef WORDS_BIGENDIAN
+static const vector16x_u8 le_bswap_const =
+ { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 };
+#endif
+
+
+static ASM_FUNC_ATTR_INLINE vector4x_u32
+vec_rol_elems(vector4x_u32 v, unsigned int idx)
+{
+#ifndef WORDS_BIGENDIAN
+ return vec_sld (v, v, (16 - (4 * idx)) & 15);
+#else
+ return vec_sld (v, v, (4 * idx) & 15);
+#endif
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector4x_u32
+vec_load_le(unsigned long offset, const unsigned char *ptr)
+{
+ vector4x_u32 vec;
+ vec = vec_vsx_ld (offset, (const u32 *)ptr);
+#ifdef WORDS_BIGENDIAN
+ vec = (vector4x_u32)vec_perm((vector16x_u8)vec, (vector16x_u8)vec,
+ le_bswap_const);
+#endif
+ return vec;
+}
+
+
+static ASM_FUNC_ATTR_INLINE void
+vec_store_le(vector4x_u32 vec, unsigned long offset, unsigned char *ptr)
+{
+#ifdef WORDS_BIGENDIAN
+ vec = (vector4x_u32)vec_perm((vector16x_u8)vec, (vector16x_u8)vec,
+ le_bswap_const);
+#endif
+ vec_vsx_st (vec, offset, (u32 *)ptr);
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector4x_u32
+vec_add_ctr_u64(vector4x_u32 v, vector4x_u32 a)
+{
+#ifdef WORDS_BIGENDIAN
+ static const vector16x_u8 swap32 =
+ { 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11 };
+ vector2x_u64 vec, add, sum;
+
+ vec = (vector2x_u64)vec_perm((vector16x_u8)v, (vector16x_u8)v, swap32);
+ add = (vector2x_u64)vec_perm((vector16x_u8)a, (vector16x_u8)a, swap32);
+ sum = vec + add;
+ return (vector4x_u32)vec_perm((vector16x_u8)sum, (vector16x_u8)sum, swap32);
+#else
+ return (vector4x_u32)((vector2x_u64)(v) + (vector2x_u64)(a));
+#endif
+}
+
+
+/**********************************************************************
+ 2-way && 1-way chacha20
+ **********************************************************************/
+
+#define ROTATE(v1,rolv) \
+ __asm__ ("vrlw %0,%1,%2\n\t" : "=v" (v1) : "v" (v1), "v" (rolv))
+
+#define WORD_ROL(v1,c) \
+ ((v1) = vec_rol_elems((v1), (c)))
+
+#define XOR(ds,s) \
+ ((ds) ^= (s))
+
+#define PLUS(ds,s) \
+ ((ds) += (s))
+
+#define QUARTERROUND4(x0,x1,x2,x3,rol_x1,rol_x2,rol_x3) \
+ PLUS(x0, x1); XOR(x3, x0); ROTATE(x3, rotate_16); \
+ PLUS(x2, x3); XOR(x1, x2); ROTATE(x1, rotate_12); \
+ PLUS(x0, x1); XOR(x3, x0); ROTATE(x3, rotate_8); \
+ PLUS(x2, x3); \
+ WORD_ROL(x3, rol_x3); \
+ XOR(x1, x2); \
+ WORD_ROL(x2, rol_x2); \
+ ROTATE(x1, rotate_7); \
+ WORD_ROL(x1, rol_x1);
+
+#define ADD_U64(v,a) \
+ (v = vec_add_ctr_u64(v, a))
+
+unsigned int ASM_FUNC_ATTR
+_gcry_chacha20_ppc8_blocks1(u32 *state, byte *dst, const byte *src,
+ size_t nblks)
+{
+ vector4x_u32 counter_1 = { 1, 0, 0, 0 };
+ vector4x_u32 rotate_16 = { 16, 16, 16, 16 };
+ vector4x_u32 rotate_12 = { 12, 12, 12, 12 };
+ vector4x_u32 rotate_8 = { 8, 8, 8, 8 };
+ vector4x_u32 rotate_7 = { 7, 7, 7, 7 };
+ vector4x_u32 state0, state1, state2, state3;
+ vector4x_u32 v0, v1, v2, v3;
+ vector4x_u32 v4, v5, v6, v7;
+ int i;
+
+ /* force preload of constants to vector registers */
+ __asm__ ("": "+v" (counter_1) :: "memory");
+ __asm__ ("": "+v" (rotate_16) :: "memory");
+ __asm__ ("": "+v" (rotate_12) :: "memory");
+ __asm__ ("": "+v" (rotate_8) :: "memory");
+ __asm__ ("": "+v" (rotate_7) :: "memory");
+
+ state0 = vec_vsx_ld(0 * 16, state);
+ state1 = vec_vsx_ld(1 * 16, state);
+ state2 = vec_vsx_ld(2 * 16, state);
+ state3 = vec_vsx_ld(3 * 16, state);
+
+ while (nblks >= 2)
+ {
+ v0 = state0;
+ v1 = state1;
+ v2 = state2;
+ v3 = state3;
+
+ v4 = state0;
+ v5 = state1;
+ v6 = state2;
+ v7 = state3;
+ ADD_U64(v7, counter_1);
+
+ for (i = 20; i > 0; i -= 2)
+ {
+ QUARTERROUND4(v0, v1, v2, v3, 1, 2, 3);
+ QUARTERROUND4(v4, v5, v6, v7, 1, 2, 3);
+ QUARTERROUND4(v0, v1, v2, v3, 3, 2, 1);
+ QUARTERROUND4(v4, v5, v6, v7, 3, 2, 1);
+ }
+
+ v0 += state0;
+ v1 += state1;
+ v2 += state2;
+ v3 += state3;
+ ADD_U64(state3, counter_1); /* update counter */
+ v4 += state0;
+ v5 += state1;
+ v6 += state2;
+ v7 += state3;
+ ADD_U64(state3, counter_1); /* update counter */
+
+ v0 ^= vec_load_le(0 * 16, src);
+ v1 ^= vec_load_le(1 * 16, src);
+ v2 ^= vec_load_le(2 * 16, src);
+ v3 ^= vec_load_le(3 * 16, src);
+ vec_store_le(v0, 0 * 16, dst);
+ vec_store_le(v1, 1 * 16, dst);
+ vec_store_le(v2, 2 * 16, dst);
+ vec_store_le(v3, 3 * 16, dst);
+ src += 64;
+ dst += 64;
+ v4 ^= vec_load_le(0 * 16, src);
+ v5 ^= vec_load_le(1 * 16, src);
+ v6 ^= vec_load_le(2 * 16, src);
+ v7 ^= vec_load_le(3 * 16, src);
+ vec_store_le(v4, 0 * 16, dst);
+ vec_store_le(v5, 1 * 16, dst);
+ vec_store_le(v6, 2 * 16, dst);
+ vec_store_le(v7, 3 * 16, dst);
+ src += 64;
+ dst += 64;
+
+ nblks -= 2;
+ }
+
+ while (nblks)
+ {
+ v0 = state0;
+ v1 = state1;
+ v2 = state2;
+ v3 = state3;
+
+ for (i = 20; i > 0; i -= 2)
+ {
+ QUARTERROUND4(v0, v1, v2, v3, 1, 2, 3);
+ QUARTERROUND4(v0, v1, v2, v3, 3, 2, 1);
+ }
+
+ v0 += state0;
+ v1 += state1;
+ v2 += state2;
+ v3 += state3;
+ ADD_U64(state3, counter_1); /* update counter */
+
+ v0 ^= vec_load_le(0 * 16, src);
+ v1 ^= vec_load_le(1 * 16, src);
+ v2 ^= vec_load_le(2 * 16, src);
+ v3 ^= vec_load_le(3 * 16, src);
+ vec_store_le(v0, 0 * 16, dst);
+ vec_store_le(v1, 1 * 16, dst);
+ vec_store_le(v2, 2 * 16, dst);
+ vec_store_le(v3, 3 * 16, dst);
+ src += 64;
+ dst += 64;
+
+ nblks--;
+ }
+
+ vec_vsx_st(state3, 3 * 16, state); /* store counter */
+
+ return 0;
+}
+
+
+/**********************************************************************
+ 4-way chacha20
+ **********************************************************************/
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4(x0, x1, x2, x3) ({ \
+ vector4x_u32 t1 = vec_mergeh(x0, x2); \
+ vector4x_u32 t2 = vec_mergel(x0, x2); \
+ vector4x_u32 t3 = vec_mergeh(x1, x3); \
+ x3 = vec_mergel(x1, x3); \
+ x0 = vec_mergeh(t1, t3); \
+ x1 = vec_mergel(t1, t3); \
+ x2 = vec_mergeh(t2, x3); \
+ x3 = vec_mergel(t2, x3); \
+ })
+
+#define QUARTERROUND2(a1,b1,c1,d1,a2,b2,c2,d2) \
+ PLUS(a1,b1); PLUS(a2,b2); XOR(d1,a1); XOR(d2,a2); \
+ ROTATE(d1, rotate_16); ROTATE(d2, rotate_16); \
+ PLUS(c1,d1); PLUS(c2,d2); XOR(b1,c1); XOR(b2,c2); \
+ ROTATE(b1, rotate_12); ROTATE(b2, rotate_12); \
+ PLUS(a1,b1); PLUS(a2,b2); XOR(d1,a1); XOR(d2,a2); \
+ ROTATE(d1, rotate_8); ROTATE(d2, rotate_8); \
+ PLUS(c1,d1); PLUS(c2,d2); XOR(b1,c1); XOR(b2,c2); \
+ ROTATE(b1, rotate_7); ROTATE(b2, rotate_7);
+
+unsigned int ASM_FUNC_ATTR
+_gcry_chacha20_ppc8_blocks4(u32 *state, byte *dst, const byte *src,
+ size_t nblks)
+{
+ vector4x_u32 counters_0123 = { 0, 1, 2, 3 };
+ vector4x_u32 counter_4 = { 4, 0, 0, 0 };
+ vector4x_u32 rotate_16 = { 16, 16, 16, 16 };
+ vector4x_u32 rotate_12 = { 12, 12, 12, 12 };
+ vector4x_u32 rotate_8 = { 8, 8, 8, 8 };
+ vector4x_u32 rotate_7 = { 7, 7, 7, 7 };
+ vector4x_u32 state0, state1, state2, state3;
+ vector4x_u32 v0, v1, v2, v3, v4, v5, v6, v7;
+ vector4x_u32 v8, v9, v10, v11, v12, v13, v14, v15;
+ vector4x_u32 tmp;
+ int i;
+
+ /* force preload of constants to vector registers */
+ __asm__ ("": "+v" (counters_0123) :: "memory");
+ __asm__ ("": "+v" (counter_4) :: "memory");
+ __asm__ ("": "+v" (rotate_16) :: "memory");
+ __asm__ ("": "+v" (rotate_12) :: "memory");
+ __asm__ ("": "+v" (rotate_8) :: "memory");
+ __asm__ ("": "+v" (rotate_7) :: "memory");
+
+ state0 = vec_vsx_ld(0 * 16, state);
+ state1 = vec_vsx_ld(1 * 16, state);
+ state2 = vec_vsx_ld(2 * 16, state);
+ state3 = vec_vsx_ld(3 * 16, state);
+
+ do
+ {
+ v0 = vec_splat(state0, 0);
+ v1 = vec_splat(state0, 1);
+ v2 = vec_splat(state0, 2);
+ v3 = vec_splat(state0, 3);
+ v4 = vec_splat(state1, 0);
+ v5 = vec_splat(state1, 1);
+ v6 = vec_splat(state1, 2);
+ v7 = vec_splat(state1, 3);
+ v8 = vec_splat(state2, 0);
+ v9 = vec_splat(state2, 1);
+ v10 = vec_splat(state2, 2);
+ v11 = vec_splat(state2, 3);
+ v12 = vec_splat(state3, 0);
+ v13 = vec_splat(state3, 1);
+ v14 = vec_splat(state3, 2);
+ v15 = vec_splat(state3, 3);
+
+ v12 += counters_0123;
+ v13 -= vec_cmplt(v12, counters_0123);
+
+ for (i = 20; i > 0; i -= 2)
+ {
+ QUARTERROUND2(v0, v4, v8, v12, v1, v5, v9, v13)
+ QUARTERROUND2(v2, v6, v10, v14, v3, v7, v11, v15)
+ QUARTERROUND2(v0, v5, v10, v15, v1, v6, v11, v12)
+ QUARTERROUND2(v2, v7, v8, v13, v3, v4, v9, v14)
+ }
+
+ v0 += vec_splat(state0, 0);
+ v1 += vec_splat(state0, 1);
+ v2 += vec_splat(state0, 2);
+ v3 += vec_splat(state0, 3);
+ v4 += vec_splat(state1, 0);
+ v5 += vec_splat(state1, 1);
+ v6 += vec_splat(state1, 2);
+ v7 += vec_splat(state1, 3);
+ v8 += vec_splat(state2, 0);
+ v9 += vec_splat(state2, 1);
+ v10 += vec_splat(state2, 2);
+ v11 += vec_splat(state2, 3);
+ tmp = vec_splat(state3, 0);
+ tmp += counters_0123;
+ v12 += tmp;
+ v13 += vec_splat(state3, 1) - vec_cmplt(tmp, counters_0123);
+ v14 += vec_splat(state3, 2);
+ v15 += vec_splat(state3, 3);
+ ADD_U64(state3, counter_4); /* update counter */
+
+ transpose_4x4(v0, v1, v2, v3);
+ transpose_4x4(v4, v5, v6, v7);
+ transpose_4x4(v8, v9, v10, v11);
+ transpose_4x4(v12, v13, v14, v15);
+
+ v0 ^= vec_load_le((64 * 0 + 16 * 0), src);
+ v1 ^= vec_load_le((64 * 1 + 16 * 0), src);
+ v2 ^= vec_load_le((64 * 2 + 16 * 0), src);
+ v3 ^= vec_load_le((64 * 3 + 16 * 0), src);
+
+ v4 ^= vec_load_le((64 * 0 + 16 * 1), src);
+ v5 ^= vec_load_le((64 * 1 + 16 * 1), src);
+ v6 ^= vec_load_le((64 * 2 + 16 * 1), src);
+ v7 ^= vec_load_le((64 * 3 + 16 * 1), src);
+
+ v8 ^= vec_load_le((64 * 0 + 16 * 2), src);
+ v9 ^= vec_load_le((64 * 1 + 16 * 2), src);
+ v10 ^= vec_load_le((64 * 2 + 16 * 2), src);
+ v11 ^= vec_load_le((64 * 3 + 16 * 2), src);
+
+ v12 ^= vec_load_le((64 * 0 + 16 * 3), src);
+ v13 ^= vec_load_le((64 * 1 + 16 * 3), src);
+ v14 ^= vec_load_le((64 * 2 + 16 * 3), src);
+ v15 ^= vec_load_le((64 * 3 + 16 * 3), src);
+
+ vec_store_le(v0, (64 * 0 + 16 * 0), dst);
+ vec_store_le(v1, (64 * 1 + 16 * 0), dst);
+ vec_store_le(v2, (64 * 2 + 16 * 0), dst);
+ vec_store_le(v3, (64 * 3 + 16 * 0), dst);
+
+ vec_store_le(v4, (64 * 0 + 16 * 1), dst);
+ vec_store_le(v5, (64 * 1 + 16 * 1), dst);
+ vec_store_le(v6, (64 * 2 + 16 * 1), dst);
+ vec_store_le(v7, (64 * 3 + 16 * 1), dst);
+
+ vec_store_le(v8, (64 * 0 + 16 * 2), dst);
+ vec_store_le(v9, (64 * 1 + 16 * 2), dst);
+ vec_store_le(v10, (64 * 2 + 16 * 2), dst);
+ vec_store_le(v11, (64 * 3 + 16 * 2), dst);
+
+ vec_store_le(v12, (64 * 0 + 16 * 3), dst);
+ vec_store_le(v13, (64 * 1 + 16 * 3), dst);
+ vec_store_le(v14, (64 * 2 + 16 * 3), dst);
+ vec_store_le(v15, (64 * 3 + 16 * 3), dst);
+
+ src += 4*64;
+ dst += 4*64;
+
+ nblks -= 4;
+ }
+ while (nblks);
+
+ vec_vsx_st(state3, 3 * 16, state); /* store counter */
+
+ return 0;
+}
+
+
+#if SIZEOF_UNSIGNED_LONG == 8
+
+/**********************************************************************
+ 4-way stitched chacha20-poly1305
+ **********************************************************************/
+
+#define ADD_1305_64(A2, A1, A0, B2, B1, B0) \
+ __asm__ ("addc %0, %3, %0\n" \
+ "adde %1, %4, %1\n" \
+ "adde %2, %5, %2\n" \
+ : "+r" (A0), "+r" (A1), "+r" (A2) \
+ : "r" (B0), "r" (B1), "r" (B2) \
+ : "cc" )
+
+#define MUL_MOD_1305_64_PART1(H2, H1, H0, R1, R0, R1_MULT5) do { \
+ /* x = a * r (partial mod 2^130-5) */ \
+ umul_ppmm(x0_hi, x0_lo, H0, R0); /* h0 * r0 */ \
+ umul_ppmm(x1_hi, x1_lo, H0, R1); /* h0 * r1 */ \
+ \
+ umul_ppmm(t0_hi, t0_lo, H1, R1_MULT5); /* h1 * r1 mod 2^130-5 */ \
+ } while (0)
+
+#define MUL_MOD_1305_64_PART2(H2, H1, H0, R1, R0, R1_MULT5) do { \
+ add_ssaaaa(x0_hi, x0_lo, x0_hi, x0_lo, t0_hi, t0_lo); \
+ umul_ppmm(t1_hi, t1_lo, H1, R0); /* h1 * r0 */ \
+ add_ssaaaa(x1_hi, x1_lo, x1_hi, x1_lo, t1_hi, t1_lo); \
+ \
+ t1_lo = H2 * R1_MULT5; /* h2 * r1 mod 2^130-5 */ \
+ t1_hi = H2 * R0; /* h2 * r0 */ \
+ add_ssaaaa(H0, H1, x1_hi, x1_lo, t1_hi, t1_lo); \
+ \
+ /* carry propagation */ \
+ H2 = H0 & 3; \
+ H0 = (H0 >> 2) * 5; /* msb mod 2^130-5 */ \
+ ADD_1305_64(H2, H1, H0, (u64)0, x0_hi, x0_lo); \
+ } while (0)
+
+#define POLY1305_BLOCK_PART1(in_pos) do { \
+ m0 = buf_get_le64(poly1305_src + (in_pos) + 0); \
+ m1 = buf_get_le64(poly1305_src + (in_pos) + 8); \
+ /* a = h + m */ \
+ ADD_1305_64(h2, h1, h0, m2, m1, m0); \
+ /* h = a * r (partial mod 2^130-5) */ \
+ MUL_MOD_1305_64_PART1(h2, h1, h0, r1, r0, r1_mult5); \
+ } while (0)
+
+#define POLY1305_BLOCK_PART2(in_pos) do { \
+ MUL_MOD_1305_64_PART2(h2, h1, h0, r1, r0, r1_mult5); \
+ } while (0)
+
+unsigned int ASM_FUNC_ATTR
+_gcry_chacha20_poly1305_ppc8_blocks4(u32 *state, byte *dst, const byte *src,
+ size_t nblks, POLY1305_STATE *st,
+ const byte *poly1305_src)
+{
+ vector4x_u32 counters_0123 = { 0, 1, 2, 3 };
+ vector4x_u32 counter_4 = { 4, 0, 0, 0 };
+ vector4x_u32 rotate_16 = { 16, 16, 16, 16 };
+ vector4x_u32 rotate_12 = { 12, 12, 12, 12 };
+ vector4x_u32 rotate_8 = { 8, 8, 8, 8 };
+ vector4x_u32 rotate_7 = { 7, 7, 7, 7 };
+ vector4x_u32 state0, state1, state2, state3;
+ vector4x_u32 v0, v1, v2, v3, v4, v5, v6, v7;
+ vector4x_u32 v8, v9, v10, v11, v12, v13, v14, v15;
+ vector4x_u32 tmp;
+ u64 r0, r1, r1_mult5;
+ u64 h0, h1, h2;
+ u64 m0, m1, m2;
+ u64 x0_lo, x0_hi, x1_lo, x1_hi;
+ u64 t0_lo, t0_hi, t1_lo, t1_hi;
+ unsigned int i, o;
+
+ /* load poly1305 state */
+ m2 = 1;
+ h0 = st->h[0] + ((u64)st->h[1] << 32);
+ h1 = st->h[2] + ((u64)st->h[3] << 32);
+ h2 = st->h[4];
+ r0 = st->r[0] + ((u64)st->r[1] << 32);
+ r1 = st->r[2] + ((u64)st->r[3] << 32);
+ r1_mult5 = (r1 >> 2) + r1;
+
+ /* force preload of constants to vector registers */
+ __asm__ ("": "+v" (counters_0123) :: "memory");
+ __asm__ ("": "+v" (counter_4) :: "memory");
+ __asm__ ("": "+v" (rotate_16) :: "memory");
+ __asm__ ("": "+v" (rotate_12) :: "memory");
+ __asm__ ("": "+v" (rotate_8) :: "memory");
+ __asm__ ("": "+v" (rotate_7) :: "memory");
+
+ state0 = vec_vsx_ld(0 * 16, state);
+ state1 = vec_vsx_ld(1 * 16, state);
+ state2 = vec_vsx_ld(2 * 16, state);
+ state3 = vec_vsx_ld(3 * 16, state);
+
+ do
+ {
+ v0 = vec_splat(state0, 0);
+ v1 = vec_splat(state0, 1);
+ v2 = vec_splat(state0, 2);
+ v3 = vec_splat(state0, 3);
+ v4 = vec_splat(state1, 0);
+ v5 = vec_splat(state1, 1);
+ v6 = vec_splat(state1, 2);
+ v7 = vec_splat(state1, 3);
+ v8 = vec_splat(state2, 0);
+ v9 = vec_splat(state2, 1);
+ v10 = vec_splat(state2, 2);
+ v11 = vec_splat(state2, 3);
+ v12 = vec_splat(state3, 0);
+ v13 = vec_splat(state3, 1);
+ v14 = vec_splat(state3, 2);
+ v15 = vec_splat(state3, 3);
+
+ v12 += counters_0123;
+ v13 -= vec_cmplt(v12, counters_0123);
+
+ for (o = 20; o; o -= 10)
+ {
+ for (i = 8; i; i -= 2)
+ {
+ POLY1305_BLOCK_PART1(0 * 16);
+ QUARTERROUND2(v0, v4, v8, v12, v1, v5, v9, v13)
+ POLY1305_BLOCK_PART2();
+ QUARTERROUND2(v2, v6, v10, v14, v3, v7, v11, v15)
+ POLY1305_BLOCK_PART1(1 * 16);
+ poly1305_src += 2 * 16;
+ QUARTERROUND2(v0, v5, v10, v15, v1, v6, v11, v12)
+ POLY1305_BLOCK_PART2();
+ QUARTERROUND2(v2, v7, v8, v13, v3, v4, v9, v14)
+ }
+
+ QUARTERROUND2(v0, v4, v8, v12, v1, v5, v9, v13)
+ QUARTERROUND2(v2, v6, v10, v14, v3, v7, v11, v15)
+ QUARTERROUND2(v0, v5, v10, v15, v1, v6, v11, v12)
+ QUARTERROUND2(v2, v7, v8, v13, v3, v4, v9, v14)
+ }
+
+ v0 += vec_splat(state0, 0);
+ v1 += vec_splat(state0, 1);
+ v2 += vec_splat(state0, 2);
+ v3 += vec_splat(state0, 3);
+ v4 += vec_splat(state1, 0);
+ v5 += vec_splat(state1, 1);
+ v6 += vec_splat(state1, 2);
+ v7 += vec_splat(state1, 3);
+ v8 += vec_splat(state2, 0);
+ v9 += vec_splat(state2, 1);
+ v10 += vec_splat(state2, 2);
+ v11 += vec_splat(state2, 3);
+ tmp = vec_splat(state3, 0);
+ tmp += counters_0123;
+ v12 += tmp;
+ v13 += vec_splat(state3, 1) - vec_cmplt(tmp, counters_0123);
+ v14 += vec_splat(state3, 2);
+ v15 += vec_splat(state3, 3);
+ ADD_U64(state3, counter_4); /* update counter */
+
+ transpose_4x4(v0, v1, v2, v3);
+ transpose_4x4(v4, v5, v6, v7);
+ transpose_4x4(v8, v9, v10, v11);
+ transpose_4x4(v12, v13, v14, v15);
+
+ v0 ^= vec_load_le((64 * 0 + 16 * 0), src);
+ v1 ^= vec_load_le((64 * 1 + 16 * 0), src);
+ v2 ^= vec_load_le((64 * 2 + 16 * 0), src);
+ v3 ^= vec_load_le((64 * 3 + 16 * 0), src);
+
+ v4 ^= vec_load_le((64 * 0 + 16 * 1), src);
+ v5 ^= vec_load_le((64 * 1 + 16 * 1), src);
+ v6 ^= vec_load_le((64 * 2 + 16 * 1), src);
+ v7 ^= vec_load_le((64 * 3 + 16 * 1), src);
+
+ v8 ^= vec_load_le((64 * 0 + 16 * 2), src);
+ v9 ^= vec_load_le((64 * 1 + 16 * 2), src);
+ v10 ^= vec_load_le((64 * 2 + 16 * 2), src);
+ v11 ^= vec_load_le((64 * 3 + 16 * 2), src);
+
+ v12 ^= vec_load_le((64 * 0 + 16 * 3), src);
+ v13 ^= vec_load_le((64 * 1 + 16 * 3), src);
+ v14 ^= vec_load_le((64 * 2 + 16 * 3), src);
+ v15 ^= vec_load_le((64 * 3 + 16 * 3), src);
+
+ vec_store_le(v0, (64 * 0 + 16 * 0), dst);
+ vec_store_le(v1, (64 * 1 + 16 * 0), dst);
+ vec_store_le(v2, (64 * 2 + 16 * 0), dst);
+ vec_store_le(v3, (64 * 3 + 16 * 0), dst);
+
+ vec_store_le(v4, (64 * 0 + 16 * 1), dst);
+ vec_store_le(v5, (64 * 1 + 16 * 1), dst);
+ vec_store_le(v6, (64 * 2 + 16 * 1), dst);
+ vec_store_le(v7, (64 * 3 + 16 * 1), dst);
+
+ vec_store_le(v8, (64 * 0 + 16 * 2), dst);
+ vec_store_le(v9, (64 * 1 + 16 * 2), dst);
+ vec_store_le(v10, (64 * 2 + 16 * 2), dst);
+ vec_store_le(v11, (64 * 3 + 16 * 2), dst);
+
+ vec_store_le(v12, (64 * 0 + 16 * 3), dst);
+ vec_store_le(v13, (64 * 1 + 16 * 3), dst);
+ vec_store_le(v14, (64 * 2 + 16 * 3), dst);
+ vec_store_le(v15, (64 * 3 + 16 * 3), dst);
+
+ src += 4*64;
+ dst += 4*64;
+
+ nblks -= 4;
+ }
+ while (nblks);
+
+ vec_vsx_st(state3, 3 * 16, state); /* store counter */
+
+ /* store poly1305 state */
+ st->h[0] = h0;
+ st->h[1] = h0 >> 32;
+ st->h[2] = h1;
+ st->h[3] = h1 >> 32;
+ st->h[4] = h2;
+
+ return 0;
+}
+
+#endif /* SIZEOF_UNSIGNED_LONG == 8 */
+
+#endif /* ENABLE_PPC_CRYPTO_SUPPORT */
diff --git a/comm/third_party/libgcrypt/cipher/chacha20-s390x.S b/comm/third_party/libgcrypt/cipher/chacha20-s390x.S
new file mode 100644
index 0000000000..9b1d59c6ad
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/chacha20-s390x.S
@@ -0,0 +1,1561 @@
+/* chacha20-s390x.S - zSeries implementation of ChaCha20 cipher
+ *
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9
+#include <config.h>
+#if defined(HAVE_GCC_INLINE_ASM_S390X_VX)
+
+#include "asm-common-s390x.h"
+#include "asm-poly1305-s390x.h"
+
+.machine "z13+vx"
+.text
+
+.balign 16
+.Lconsts:
+.Lwordswap:
+ .byte 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3
+.Lbswap128:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+.Lbswap32:
+ .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
+.Lone:
+ .long 0, 0, 0, 1
+.Ladd_counter_0123:
+ .long 0, 1, 2, 3
+.Ladd_counter_4567:
+ .long 4, 5, 6, 7
+
+/* register macros */
+#define INPUT %r2
+#define DST %r3
+#define SRC %r4
+#define NBLKS %r0
+#define ROUND %r1
+
+/* stack structure */
+
+#define STACK_FRAME_STD (8 * 16 + 8 * 4)
+#define STACK_FRAME_F8_F15 (8 * 8)
+#define STACK_FRAME_Y0_Y15 (16 * 16)
+#define STACK_FRAME_CTR (4 * 16)
+#define STACK_FRAME_PARAMS (6 * 8)
+
+#define STACK_MAX (STACK_FRAME_STD + STACK_FRAME_F8_F15 + \
+ STACK_FRAME_Y0_Y15 + STACK_FRAME_CTR + \
+ STACK_FRAME_PARAMS)
+
+#define STACK_F8 (STACK_MAX - STACK_FRAME_F8_F15)
+#define STACK_F9 (STACK_F8 + 8)
+#define STACK_F10 (STACK_F9 + 8)
+#define STACK_F11 (STACK_F10 + 8)
+#define STACK_F12 (STACK_F11 + 8)
+#define STACK_F13 (STACK_F12 + 8)
+#define STACK_F14 (STACK_F13 + 8)
+#define STACK_F15 (STACK_F14 + 8)
+#define STACK_Y0_Y15 (STACK_F8 - STACK_FRAME_Y0_Y15)
+#define STACK_CTR (STACK_Y0_Y15 - STACK_FRAME_CTR)
+#define STACK_INPUT (STACK_CTR - STACK_FRAME_PARAMS)
+#define STACK_DST (STACK_INPUT + 8)
+#define STACK_SRC (STACK_DST + 8)
+#define STACK_NBLKS (STACK_SRC + 8)
+#define STACK_POCTX (STACK_NBLKS + 8)
+#define STACK_POSRC (STACK_POCTX + 8)
+
+#define STACK_G0_H3 STACK_Y0_Y15
+
+/* vector registers */
+#define A0 %v0
+#define A1 %v1
+#define A2 %v2
+#define A3 %v3
+
+#define B0 %v4
+#define B1 %v5
+#define B2 %v6
+#define B3 %v7
+
+#define C0 %v8
+#define C1 %v9
+#define C2 %v10
+#define C3 %v11
+
+#define D0 %v12
+#define D1 %v13
+#define D2 %v14
+#define D3 %v15
+
+#define E0 %v16
+#define E1 %v17
+#define E2 %v18
+#define E3 %v19
+
+#define F0 %v20
+#define F1 %v21
+#define F2 %v22
+#define F3 %v23
+
+#define G0 %v24
+#define G1 %v25
+#define G2 %v26
+#define G3 %v27
+
+#define H0 %v28
+#define H1 %v29
+#define H2 %v30
+#define H3 %v31
+
+#define IO0 E0
+#define IO1 E1
+#define IO2 E2
+#define IO3 E3
+#define IO4 F0
+#define IO5 F1
+#define IO6 F2
+#define IO7 F3
+
+#define S0 G0
+#define S1 G1
+#define S2 G2
+#define S3 G3
+
+#define TMP0 H0
+#define TMP1 H1
+#define TMP2 H2
+#define TMP3 H3
+
+#define X0 A0
+#define X1 A1
+#define X2 A2
+#define X3 A3
+#define X4 B0
+#define X5 B1
+#define X6 B2
+#define X7 B3
+#define X8 C0
+#define X9 C1
+#define X10 C2
+#define X11 C3
+#define X12 D0
+#define X13 D1
+#define X14 D2
+#define X15 D3
+
+#define Y0 E0
+#define Y1 E1
+#define Y2 E2
+#define Y3 E3
+#define Y4 F0
+#define Y5 F1
+#define Y6 F2
+#define Y7 F3
+#define Y8 G0
+#define Y9 G1
+#define Y10 G2
+#define Y11 G3
+#define Y12 H0
+#define Y13 H1
+#define Y14 H2
+#define Y15 H3
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+#define _ /*_*/
+
+#define CLEAR(x,...) vzero x;
+
+#define START_STACK(last_r) \
+ lgr %r0, %r15; \
+ lghi %r1, ~15; \
+ stmg %r6, last_r, 6 * 8(%r15); \
+ aghi %r0, -STACK_MAX; \
+ ngr %r0, %r1; \
+ lgr %r1, %r15; \
+ CFI_DEF_CFA_REGISTER(1); \
+ lgr %r15, %r0; \
+ stg %r1, 0(%r15); \
+ CFI_CFA_ON_STACK(0, 0); \
+ std %f8, STACK_F8(%r15); \
+ std %f9, STACK_F9(%r15); \
+ std %f10, STACK_F10(%r15); \
+ std %f11, STACK_F11(%r15); \
+ std %f12, STACK_F12(%r15); \
+ std %f13, STACK_F13(%r15); \
+ std %f14, STACK_F14(%r15); \
+ std %f15, STACK_F15(%r15);
+
+#define END_STACK(last_r) \
+ lg %r1, 0(%r15); \
+ ld %f8, STACK_F8(%r15); \
+ ld %f9, STACK_F9(%r15); \
+ ld %f10, STACK_F10(%r15); \
+ ld %f11, STACK_F11(%r15); \
+ ld %f12, STACK_F12(%r15); \
+ ld %f13, STACK_F13(%r15); \
+ ld %f14, STACK_F14(%r15); \
+ ld %f15, STACK_F15(%r15); \
+ lmg %r6, last_r, 6 * 8(%r1); \
+ lgr %r15, %r1; \
+ CFI_DEF_CFA_REGISTER(DW_REGNO_SP);
+
+#define PLUS(dst,src) \
+ vaf dst, dst, src;
+
+#define XOR(dst,src) \
+ vx dst, dst, src;
+
+#define ROTATE(v1,c) \
+ verllf v1, v1, (c)(0);
+
+#define WORD_ROTATE(v1,s) \
+ vsldb v1, v1, v1, ((s) * 4);
+
+#define DST_1(OPER, I, J) \
+ OPER(A##I, J);
+
+#define DST_2(OPER, I, J) \
+ OPER(A##I, J); OPER(B##I, J);
+
+#define DST_4(OPER, I, J) \
+ OPER(A##I, J); OPER(B##I, J); OPER(C##I, J); OPER(D##I, J);
+
+#define DST_8(OPER, I, J) \
+ OPER(A##I, J); OPER(B##I, J); OPER(C##I, J); OPER(D##I, J); \
+ OPER(E##I, J); OPER(F##I, J); OPER(G##I, J); OPER(H##I, J);
+
+#define DST_SRC_1(OPER, I, J) \
+ OPER(A##I, A##J);
+
+#define DST_SRC_2(OPER, I, J) \
+ OPER(A##I, A##J); OPER(B##I, B##J);
+
+#define DST_SRC_4(OPER, I, J) \
+ OPER(A##I, A##J); OPER(B##I, B##J); OPER(C##I, C##J); \
+ OPER(D##I, D##J);
+
+#define DST_SRC_8(OPER, I, J) \
+ OPER(A##I, A##J); OPER(B##I, B##J); OPER(C##I, C##J); \
+ OPER(D##I, D##J); OPER(E##I, E##J); OPER(F##I, F##J); \
+ OPER(G##I, G##J); OPER(H##I, H##J);
+
+/**********************************************************************
+ round macros
+ **********************************************************************/
+
+#define QUARTERROUND4_POLY(wrot_1,wrot_2,wrot_3,op1,op2) \
+ op1; DST_SRC_1(PLUS, 0, 1); DST_SRC_1(XOR, 3, 0); DST_1(ROTATE, 3, 16); \
+ DST_SRC_1(PLUS, 2, 3); DST_SRC_1(XOR, 1, 2); DST_1(ROTATE, 1, 12); \
+ DST_SRC_1(PLUS, 0, 1); DST_SRC_1(XOR, 3, 0); DST_1(ROTATE, 3, 8); \
+ op2; DST_SRC_1(PLUS, 2, 3); DST_SRC_1(XOR, 1, 2); DST_1(ROTATE, 1, 7); \
+ DST_1(WORD_ROTATE, 3, wrot_3); \
+ DST_1(WORD_ROTATE, 2, wrot_2); \
+ DST_1(WORD_ROTATE, 1, wrot_1);
+
+#define QUARTERROUND4(wrot_1,wrot_2,wrot_3) \
+ QUARTERROUND4_POLY(wrot_1,wrot_2,wrot_3,,)
+
+#define QUARTERROUND4_2_POLY(wrot_1,wrot_2,wrot_3,op1,op2,op3,op4) \
+ op1; DST_SRC_2(PLUS, 0, 1); DST_SRC_2(XOR, 3, 0); DST_2(ROTATE, 3, 16); \
+ DST_SRC_2(PLUS, 2, 3); op2; DST_SRC_2(XOR, 1, 2); DST_2(ROTATE, 1, 12); \
+ DST_SRC_2(PLUS, 0, 1); DST_SRC_2(XOR, 3, 0); op3; DST_2(ROTATE, 3, 8); \
+ DST_SRC_2(PLUS, 2, 3); DST_SRC_2(XOR, 1, 2); DST_2(ROTATE, 1, 7); op4; \
+ DST_2(WORD_ROTATE, 3, wrot_3); \
+ DST_2(WORD_ROTATE, 2, wrot_2); \
+ DST_2(WORD_ROTATE, 1, wrot_1);
+
+#define QUARTERROUND4_2(wrot_1,wrot_2,wrot_3) \
+ QUARTERROUND4_2_POLY(wrot_1,wrot_2,wrot_3,,,,)
+
+#define QUARTERROUND4_4_POLY(wrot_1,wrot_2,wrot_3,op1,op2,op3,op4,op5,op6) \
+ DST_SRC_4(PLUS, 0, 1); DST_SRC_4(XOR, 3, 0); op1; DST_4(ROTATE, 3, 16); \
+ DST_SRC_4(PLUS, 2, 3); op2; DST_SRC_4(XOR, 1, 2); DST_4(ROTATE, 1, 12); \
+ op3; DST_SRC_4(PLUS, 0, 1); DST_SRC_4(XOR, 3, 0); op4; DST_4(ROTATE, 3, 8); \
+ DST_SRC_4(PLUS, 2, 3); op5; DST_SRC_4(XOR, 1, 2); DST_4(ROTATE, 1, 7); \
+ op6; \
+ DST_4(WORD_ROTATE, 3, wrot_3); \
+ DST_4(WORD_ROTATE, 2, wrot_2); \
+ DST_4(WORD_ROTATE, 1, wrot_1);
+
+#define QUARTERROUND4_4(wrot_1,wrot_2,wrot_3) \
+ QUARTERROUND4_4_POLY(wrot_1,wrot_2,wrot_3,,,,,,)
+
+/**********************************************************************
+ 4-way && 2-way && 1-way chacha20 ("horizontal")
+ **********************************************************************/
+
+.balign 8
+.globl _gcry_chacha20_s390x_vx_blocks4_2_1
+ELF(.type _gcry_chacha20_s390x_vx_blocks4_2_1,@function;)
+
+_gcry_chacha20_s390x_vx_blocks4_2_1:
+ /* input:
+ * %r2: input
+ * %r3: dst
+ * %r4: src
+ * %r5: nblks
+ */
+ CFI_STARTPROC();
+
+ START_STACK(%r7);
+ lgr NBLKS, %r5;
+
+ /* Load constants. */
+ larl %r7, .Lconsts;
+ vl TMP0, (.Lwordswap - .Lconsts)(%r7);
+ vl TMP1, (.Lone - .Lconsts)(%r7);
+ vl TMP2, (.Lbswap128 - .Lconsts)(%r7);
+
+ /* Load state. */
+ vlm S0, S3, 0(INPUT);
+ vperm S0, S0, S0, TMP0;
+ vperm S1, S1, S1, TMP0;
+ vperm S2, S2, S2, TMP0;
+ vperm S3, S3, S3, TMP0;
+
+ clgijl NBLKS, 4, .Lloop2;
+
+.balign 4
+.Lloop4:
+ /* Process four chacha20 blocks. */
+ vlr TMP3, S3;
+ lghi ROUND, (20 / 2);
+ vlr A0, S0;
+ vlr A1, S1;
+ vlr A2, S2;
+ vlr A3, TMP3;
+ vag TMP3, TMP3, TMP1;
+ vlr B0, S0;
+ vlr B1, S1;
+ vlr B2, S2;
+ vlr B3, TMP3;
+ vag TMP3, TMP3, TMP1;
+ vlr C0, S0;
+ vlr C1, S1;
+ vlr C2, S2;
+ vlr C3, TMP3;
+ vlr D0, S0;
+ vlr D1, S1;
+ vlr D2, S2;
+ vag D3, TMP3, TMP1;
+
+ slgfi NBLKS, 4;
+
+.balign 4
+.Lround2_4:
+ QUARTERROUND4_4(3, 2, 1);
+ QUARTERROUND4_4(1, 2, 3);
+ brctg ROUND, .Lround2_4;
+
+ vlm IO0, IO7, 0(SRC);
+
+ PLUS(A0, S0);
+ PLUS(A1, S1);
+ PLUS(A2, S2);
+ PLUS(A3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ PLUS(B0, S0);
+ PLUS(B1, S1);
+ PLUS(B2, S2);
+ PLUS(B3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ vperm A0, A0, A0, TMP2;
+ vperm A1, A1, A1, TMP2;
+ vperm A2, A2, A2, TMP2;
+ vperm A3, A3, A3, TMP2;
+ vperm B0, B0, B0, TMP2;
+ vperm B1, B1, B1, TMP2;
+ vperm B2, B2, B2, TMP2;
+ vperm B3, B3, B3, TMP2;
+ PLUS(C0, S0);
+ PLUS(C1, S1);
+ PLUS(C2, S2);
+ PLUS(C3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ PLUS(D0, S0);
+ PLUS(D1, S1);
+ PLUS(D2, S2);
+ PLUS(D3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ vperm C0, C0, C0, TMP2;
+ vperm C1, C1, C1, TMP2;
+ vperm C2, C2, C2, TMP2;
+ vperm C3, C3, C3, TMP2;
+ vperm D0, D0, D0, TMP2;
+ vperm D1, D1, D1, TMP2;
+ vperm D2, D2, D2, TMP2;
+ vperm D3, D3, D3, TMP2;
+
+ XOR(IO0, A0);
+ XOR(IO1, A1);
+ XOR(IO2, A2);
+ XOR(IO3, A3);
+ XOR(IO4, B0);
+ XOR(IO5, B1);
+ XOR(IO6, B2);
+ XOR(IO7, B3);
+ vlm A0, B3, 128(SRC);
+ vstm IO0, IO7, 0(DST);
+ XOR(A0, C0);
+ XOR(A1, C1);
+ XOR(A2, C2);
+ XOR(A3, C3);
+ XOR(B0, D0);
+ XOR(B1, D1);
+ XOR(B2, D2);
+ XOR(B3, D3);
+ vstm A0, B3, 128(DST);
+
+ aghi SRC, 256;
+ aghi DST, 256;
+
+ clgijhe NBLKS, 4, .Lloop4;
+
+ CLEAR(C0);
+ CLEAR(C1);
+ CLEAR(C2);
+ CLEAR(C3);
+ CLEAR(D0);
+ CLEAR(D1);
+ CLEAR(D2);
+ CLEAR(D3);
+
+.balign 4
+.Lloop2:
+ clgijl NBLKS, 2, .Lloop1;
+
+ /* Process two chacha20 blocks. */
+ lghi ROUND, (20 / 2);
+ vlr A0, S0;
+ vlr A1, S1;
+ vlr A2, S2;
+ vlr A3, S3;
+ vlr B0, S0;
+ vlr B1, S1;
+ vlr B2, S2;
+ vag B3, S3, TMP1;
+
+ slgfi NBLKS, 2;
+
+.balign 4
+.Lround2_2:
+ QUARTERROUND4_2(3, 2, 1);
+ QUARTERROUND4_2(1, 2, 3);
+ brctg ROUND, .Lround2_2;
+
+ vlm IO0, IO7, 0(SRC);
+
+ PLUS(A0, S0);
+ PLUS(A1, S1);
+ PLUS(A2, S2);
+ PLUS(A3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ PLUS(B0, S0);
+ PLUS(B1, S1);
+ PLUS(B2, S2);
+ PLUS(B3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ vperm A0, A0, A0, TMP2;
+ vperm A1, A1, A1, TMP2;
+ vperm A2, A2, A2, TMP2;
+ vperm A3, A3, A3, TMP2;
+ vperm B0, B0, B0, TMP2;
+ vperm B1, B1, B1, TMP2;
+ vperm B2, B2, B2, TMP2;
+ vperm B3, B3, B3, TMP2;
+
+ XOR(IO0, A0);
+ XOR(IO1, A1);
+ XOR(IO2, A2);
+ XOR(IO3, A3);
+ XOR(IO4, B0);
+ XOR(IO5, B1);
+ XOR(IO6, B2);
+ XOR(IO7, B3);
+ vstm IO0, IO7, 0(DST);
+
+ aghi SRC, 128;
+ aghi DST, 128;
+
+ clgijhe NBLKS, 2, .Lloop2;
+
+ CLEAR(B0);
+ CLEAR(B1);
+ CLEAR(B2);
+ CLEAR(B3);
+
+.balign 4
+.Lloop1:
+ clgijl NBLKS, 1, .Ldone;
+
+ /* Process one chacha20 block.*/
+ lghi ROUND, (20 / 2);
+ vlr A0, S0;
+ vlr A1, S1;
+ vlr A2, S2;
+ vlr A3, S3;
+
+ slgfi NBLKS, 1;
+
+.balign 4
+.Lround2_1:
+ QUARTERROUND4(3, 2, 1);
+ QUARTERROUND4(1, 2, 3);
+ brct ROUND, .Lround2_1;
+
+ vlm IO0, IO3, 0(SRC);
+
+ PLUS(A0, S0);
+ PLUS(A1, S1);
+ PLUS(A2, S2);
+ PLUS(A3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+
+ vperm A0, A0, A0, TMP2;
+ vperm A1, A1, A1, TMP2;
+ vperm A2, A2, A2, TMP2;
+ vperm A3, A3, A3, TMP2;
+ XOR(IO0, A0);
+ XOR(IO1, A1);
+ XOR(IO2, A2);
+ XOR(IO3, A3);
+ vstm IO0, IO3, 0(DST);
+
+ aghi SRC, 64;
+ aghi DST, 64;
+
+ clgijhe NBLKS, 1, .Lloop1;
+
+.balign 4
+.Ldone:
+ /* Store counter. */
+ vperm S3, S3, S3, TMP0;
+ vst S3, (48)(INPUT);
+
+ /* Clear the used vector registers. */
+ CLEAR(A0);
+ CLEAR(A1);
+ CLEAR(A2);
+ CLEAR(A3);
+ CLEAR(IO0);
+ CLEAR(IO1);
+ CLEAR(IO2);
+ CLEAR(IO3);
+ CLEAR(IO4);
+ CLEAR(IO5);
+ CLEAR(IO6);
+ CLEAR(IO7);
+ CLEAR(TMP0);
+ CLEAR(TMP1);
+ CLEAR(TMP2);
+
+ END_STACK(%r7);
+ xgr %r2, %r2;
+ br %r14;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_s390x_vx_blocks4_2_1,
+ .-_gcry_chacha20_s390x_vx_blocks4_2_1;)
+
+/**********************************************************************
+ 4-way && 2-way && 1-way stitched chacha20-poly1305 ("horizontal")
+ **********************************************************************/
+
+.balign 8
+.globl _gcry_chacha20_poly1305_s390x_vx_blocks4_2_1
+ELF(.type _gcry_chacha20_poly1305_s390x_vx_blocks4_2_1,@function;)
+
+_gcry_chacha20_poly1305_s390x_vx_blocks4_2_1:
+ /* input:
+ * %r2: input
+ * %r3: dst
+ * %r4: src
+ * %r5: nblks
+ * %r6: poly1305 state
+ * 160(%r15): poly1305 src
+ */
+ CFI_STARTPROC();
+
+ START_STACK(%r14);
+ lgr NBLKS, %r5;
+
+ /* Load constants. */
+ larl %r8, .Lconsts;
+ vl TMP0, (.Lwordswap - .Lconsts)(%r8);
+ vl TMP1, (.Lone - .Lconsts)(%r8);
+ vl TMP2, (.Lbswap128 - .Lconsts)(%r8);
+
+ /* Load state. */
+ vlm S0, S3, 0(INPUT);
+ vperm S0, S0, S0, TMP0;
+ vperm S1, S1, S1, TMP0;
+ vperm S2, S2, S2, TMP0;
+ vperm S3, S3, S3, TMP0;
+
+ /* Store parameters to stack. */
+ stmg %r2, %r6, STACK_INPUT(%r15);
+
+ lgr POLY_RSTATE, %r6;
+ lgr NBLKS, %r5;
+
+ lg POLY_RSRC, 0(%r15);
+ lg POLY_RSRC, 160(POLY_RSRC);
+ stg POLY_RSRC, STACK_POSRC(%r15);
+
+ /* Load poly1305 state */
+ POLY1305_LOAD_STATE();
+
+ clgijl NBLKS, 4, .Lloop2_poly;
+
+.balign 4
+.Lloop4_poly:
+ /* Process four chacha20 blocks and 16 poly1305 blocks. */
+ vlr TMP3, S3;
+ lghi ROUND, (20 / 4);
+ vlr A0, S0;
+ vlr A1, S1;
+ vlr A2, S2;
+ vlr A3, TMP3;
+ vag TMP3, TMP3, TMP1;
+ vlr B0, S0;
+ vlr B1, S1;
+ vlr B2, S2;
+ vlr B3, TMP3;
+ vag TMP3, TMP3, TMP1;
+ vlr C0, S0;
+ vlr C1, S1;
+ vlr C2, S2;
+ vlr C3, TMP3;
+ vlr D0, S0;
+ vlr D1, S1;
+ vlr D2, S2;
+ vag D3, TMP3, TMP1;
+
+ slgfi NBLKS, 4;
+
+.balign 4
+.Lround4_4_poly:
+ /* Total 15 poly1305 blocks processed by this loop. */
+ QUARTERROUND4_4_POLY(3, 2, 1,
+ POLY1305_BLOCK_PART1(0 * 16),
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6());
+ QUARTERROUND4_4_POLY(1, 2, 3,
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8(),
+ POLY1305_BLOCK_PART1(1 * 16),
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4());
+ QUARTERROUND4_4_POLY(3, 2, 1,
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6(),
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8(),
+ POLY1305_BLOCK_PART1(2 * 16);
+ INC_POLY1305_SRC(3 * 16),
+ POLY1305_BLOCK_PART2());
+ QUARTERROUND4_4_POLY(1, 2, 3,
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6(),
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8());
+ brctg ROUND, .Lround4_4_poly;
+
+ POLY1305_BLOCK_PART1(0 * 16);
+ INC_POLY1305_SRC(1 * 16);
+ stg POLY_RSRC, STACK_POSRC(%r15);
+
+ lg %r14, STACK_SRC(%r15);
+ vlm IO0, IO7, 0(%r14);
+
+ PLUS(A0, S0);
+ PLUS(A1, S1);
+ PLUS(A2, S2);
+ PLUS(A3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ POLY1305_BLOCK_PART2();
+ PLUS(B0, S0);
+ PLUS(B1, S1);
+ PLUS(B2, S2);
+ PLUS(B3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ POLY1305_BLOCK_PART3();
+ vperm A0, A0, A0, TMP2;
+ vperm A1, A1, A1, TMP2;
+ vperm A2, A2, A2, TMP2;
+ vperm A3, A3, A3, TMP2;
+ vperm B0, B0, B0, TMP2;
+ vperm B1, B1, B1, TMP2;
+ vperm B2, B2, B2, TMP2;
+ vperm B3, B3, B3, TMP2;
+ POLY1305_BLOCK_PART4();
+ PLUS(C0, S0);
+ PLUS(C1, S1);
+ PLUS(C2, S2);
+ PLUS(C3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ PLUS(D0, S0);
+ PLUS(D1, S1);
+ PLUS(D2, S2);
+ PLUS(D3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ POLY1305_BLOCK_PART5();
+ vperm C0, C0, C0, TMP2;
+ vperm C1, C1, C1, TMP2;
+ vperm C2, C2, C2, TMP2;
+ vperm C3, C3, C3, TMP2;
+ vperm D0, D0, D0, TMP2;
+ vperm D1, D1, D1, TMP2;
+ vperm D2, D2, D2, TMP2;
+ vperm D3, D3, D3, TMP2;
+
+ POLY1305_BLOCK_PART6();
+ XOR(IO0, A0);
+ XOR(IO1, A1);
+ XOR(IO2, A2);
+ XOR(IO3, A3);
+ XOR(IO4, B0);
+ XOR(IO5, B1);
+ XOR(IO6, B2);
+ XOR(IO7, B3);
+ vlm A0, B3, 128(%r14);
+ aghi %r14, 256;
+ stg %r14, STACK_SRC(%r15);
+
+ lg %r14, STACK_DST(%r15);
+ POLY1305_BLOCK_PART7();
+ vstm IO0, IO7, 0(%r14);
+ XOR(A0, C0);
+ XOR(A1, C1);
+ XOR(A2, C2);
+ XOR(A3, C3);
+ XOR(B0, D0);
+ XOR(B1, D1);
+ XOR(B2, D2);
+ XOR(B3, D3);
+ POLY1305_BLOCK_PART8();
+ vstm A0, B3, 128(%r14);
+ aghi %r14, 256;
+ stg %r14, STACK_DST(%r15);
+
+ lg POLY_RSRC, STACK_POSRC(%r15);
+
+ clgijhe NBLKS, 4, .Lloop4_poly;
+
+ CLEAR(C0);
+ CLEAR(C1);
+ CLEAR(C2);
+ CLEAR(C3);
+ CLEAR(D0);
+ CLEAR(D1);
+ CLEAR(D2);
+ CLEAR(D3);
+
+.balign 4
+.Lloop2_poly:
+ clgijl NBLKS, 2, .Lloop1_poly;
+
+ /* Process two chacha20 and eight poly1305 blocks. */
+ lghi ROUND, ((20 - 4) / 2);
+ vlr A0, S0;
+ vlr A1, S1;
+ vlr A2, S2;
+ vlr A3, S3;
+ vlr B0, S0;
+ vlr B1, S1;
+ vlr B2, S2;
+ vag B3, S3, TMP1;
+
+ slgfi NBLKS, 2;
+
+.balign 4
+.Lround4_2_poly:
+ /* Total eight poly1305 blocks processed by this loop. */
+ QUARTERROUND4_2_POLY(3, 2, 1,
+ POLY1305_BLOCK_PART1(0 * 16),
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4());
+ INC_POLY1305_SRC(1 * 16);
+ QUARTERROUND4_2_POLY(1, 2, 3,
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6(),
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8());
+ brctg ROUND, .Lround4_2_poly;
+
+ stg POLY_RSRC, STACK_POSRC(%r15);
+ lg %r14, STACK_SRC(%r15);
+
+ QUARTERROUND4_2(3, 2, 1);
+ QUARTERROUND4_2(1, 2, 3);
+ QUARTERROUND4_2(3, 2, 1);
+ QUARTERROUND4_2(1, 2, 3);
+
+ vlm IO0, IO7, 0(%r14);
+ aghi %r14, 128;
+ stg %r14, STACK_SRC(%r15);
+
+ PLUS(A0, S0);
+ PLUS(A1, S1);
+ PLUS(A2, S2);
+ PLUS(A3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ PLUS(B0, S0);
+ PLUS(B1, S1);
+ PLUS(B2, S2);
+ PLUS(B3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+ vperm A0, A0, A0, TMP2;
+ vperm A1, A1, A1, TMP2;
+ vperm A2, A2, A2, TMP2;
+ vperm A3, A3, A3, TMP2;
+ vperm B0, B0, B0, TMP2;
+ vperm B1, B1, B1, TMP2;
+ vperm B2, B2, B2, TMP2;
+ vperm B3, B3, B3, TMP2;
+
+ lg %r14, STACK_DST(%r15);
+ XOR(IO0, A0);
+ XOR(IO1, A1);
+ XOR(IO2, A2);
+ XOR(IO3, A3);
+ XOR(IO4, B0);
+ XOR(IO5, B1);
+ XOR(IO6, B2);
+ XOR(IO7, B3);
+ vstm IO0, IO7, 0(%r14);
+ aghi %r14, 128;
+ stg %r14, STACK_DST(%r15);
+
+ lg POLY_RSRC, STACK_POSRC(%r15);
+
+ clgijhe NBLKS, 2, .Lloop2_poly;
+
+ CLEAR(B0);
+ CLEAR(B1);
+ CLEAR(B2);
+ CLEAR(B3);
+
+.balign 4
+.Lloop1_poly:
+ clgijl NBLKS, 1, .Ldone_poly;
+
+ /* Process one chacha20 block and four poly1305 blocks.*/
+ lghi ROUND, ((20 - 4) / 4);
+ vlr A0, S0;
+ vlr A1, S1;
+ vlr A2, S2;
+ vlr A3, S3;
+
+ slgfi NBLKS, 1;
+
+.balign 4
+.Lround4_1_poly:
+ /* Total four poly1305 blocks processed by this loop. */
+ QUARTERROUND4_POLY(3, 2, 1,
+ POLY1305_BLOCK_PART1(0 * 16),
+ POLY1305_BLOCK_PART2());
+ INC_POLY1305_SRC(1 * 16);
+ QUARTERROUND4_POLY(1, 2, 3,
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4());
+ QUARTERROUND4_POLY(3, 2, 1,
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6());
+ QUARTERROUND4_POLY(1, 2, 3,
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8());
+ brct ROUND, .Lround4_1_poly;
+
+ stg POLY_RSRC, STACK_POSRC(%r15);
+ lg %r14, STACK_SRC(%r15);
+
+ QUARTERROUND4(3, 2, 1);
+ QUARTERROUND4(1, 2, 3);
+ QUARTERROUND4(3, 2, 1);
+ QUARTERROUND4(1, 2, 3);
+
+ vlm IO0, IO3, 0(%r14);
+ aghi %r14, 64;
+ stg %r14, STACK_SRC(%r15);
+
+ PLUS(A0, S0);
+ PLUS(A1, S1);
+ PLUS(A2, S2);
+ PLUS(A3, S3);
+ vag S3, S3, TMP1; /* Update counter. */
+
+ lg %r14, STACK_DST(%r15);
+ vperm A0, A0, A0, TMP2;
+ vperm A1, A1, A1, TMP2;
+ vperm A2, A2, A2, TMP2;
+ vperm A3, A3, A3, TMP2;
+ XOR(IO0, A0);
+ XOR(IO1, A1);
+ XOR(IO2, A2);
+ XOR(IO3, A3);
+ vstm IO0, IO3, 0(%r14);
+ aghi %r14, 64;
+ stg %r14, STACK_DST(%r15);
+
+ lg POLY_RSRC, STACK_POSRC(%r15);
+
+ clgijhe NBLKS, 1, .Lloop1_poly;
+
+.balign 4
+.Ldone_poly:
+ /* Store poly1305 state */
+ lg POLY_RSTATE, STACK_POCTX(%r15);
+ POLY1305_STORE_STATE();
+
+ /* Store counter. */
+ lg INPUT, STACK_INPUT(%r15);
+ vperm S3, S3, S3, TMP0;
+ vst S3, (48)(INPUT);
+
+ /* Clear the used vector registers. */
+ CLEAR(A0);
+ CLEAR(A1);
+ CLEAR(A2);
+ CLEAR(A3);
+ CLEAR(IO0);
+ CLEAR(IO1);
+ CLEAR(IO2);
+ CLEAR(IO3);
+ CLEAR(IO4);
+ CLEAR(IO5);
+ CLEAR(IO6);
+ CLEAR(IO7);
+ CLEAR(TMP0);
+ CLEAR(TMP1);
+ CLEAR(TMP2);
+
+ END_STACK(%r14);
+ xgr %r2, %r2;
+ br %r14;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_poly1305_s390x_vx_blocks4_2_1,
+ .-_gcry_chacha20_poly1305_s390x_vx_blocks4_2_1;)
+
+/**********************************************************************
+ 8-way chacha20 ("vertical")
+ **********************************************************************/
+
+#define QUARTERROUND4_V8_POLY(x0,x1,x2,x3,x4,x5,x6,x7,\
+ x8,x9,x10,x11,x12,x13,x14,x15,\
+ y0,y1,y2,y3,y4,y5,y6,y7,\
+ y8,y9,y10,y11,y12,y13,y14,y15,\
+ op1,op2,op3,op4,op5,op6,op7,op8,\
+ op9,op10,op11,op12) \
+ op1; \
+ PLUS(x0, x1); PLUS(x4, x5); \
+ PLUS(x8, x9); PLUS(x12, x13); \
+ PLUS(y0, y1); PLUS(y4, y5); \
+ PLUS(y8, y9); PLUS(y12, y13); \
+ op2; \
+ XOR(x3, x0); XOR(x7, x4); \
+ XOR(x11, x8); XOR(x15, x12); \
+ XOR(y3, y0); XOR(y7, y4); \
+ XOR(y11, y8); XOR(y15, y12); \
+ op3; \
+ ROTATE(x3, 16); ROTATE(x7, 16); \
+ ROTATE(x11, 16); ROTATE(x15, 16); \
+ ROTATE(y3, 16); ROTATE(y7, 16); \
+ ROTATE(y11, 16); ROTATE(y15, 16); \
+ op4; \
+ PLUS(x2, x3); PLUS(x6, x7); \
+ PLUS(x10, x11); PLUS(x14, x15); \
+ PLUS(y2, y3); PLUS(y6, y7); \
+ PLUS(y10, y11); PLUS(y14, y15); \
+ op5; \
+ XOR(x1, x2); XOR(x5, x6); \
+ XOR(x9, x10); XOR(x13, x14); \
+ XOR(y1, y2); XOR(y5, y6); \
+ XOR(y9, y10); XOR(y13, y14); \
+ op6; \
+ ROTATE(x1,12); ROTATE(x5,12); \
+ ROTATE(x9,12); ROTATE(x13,12); \
+ ROTATE(y1,12); ROTATE(y5,12); \
+ ROTATE(y9,12); ROTATE(y13,12); \
+ op7; \
+ PLUS(x0, x1); PLUS(x4, x5); \
+ PLUS(x8, x9); PLUS(x12, x13); \
+ PLUS(y0, y1); PLUS(y4, y5); \
+ PLUS(y8, y9); PLUS(y12, y13); \
+ op8; \
+ XOR(x3, x0); XOR(x7, x4); \
+ XOR(x11, x8); XOR(x15, x12); \
+ XOR(y3, y0); XOR(y7, y4); \
+ XOR(y11, y8); XOR(y15, y12); \
+ op9; \
+ ROTATE(x3,8); ROTATE(x7,8); \
+ ROTATE(x11,8); ROTATE(x15,8); \
+ ROTATE(y3,8); ROTATE(y7,8); \
+ ROTATE(y11,8); ROTATE(y15,8); \
+ op10; \
+ PLUS(x2, x3); PLUS(x6, x7); \
+ PLUS(x10, x11); PLUS(x14, x15); \
+ PLUS(y2, y3); PLUS(y6, y7); \
+ PLUS(y10, y11); PLUS(y14, y15); \
+ op11; \
+ XOR(x1, x2); XOR(x5, x6); \
+ XOR(x9, x10); XOR(x13, x14); \
+ XOR(y1, y2); XOR(y5, y6); \
+ XOR(y9, y10); XOR(y13, y14); \
+ op12; \
+ ROTATE(x1,7); ROTATE(x5,7); \
+ ROTATE(x9,7); ROTATE(x13,7); \
+ ROTATE(y1,7); ROTATE(y5,7); \
+ ROTATE(y9,7); ROTATE(y13,7);
+
+#define QUARTERROUND4_V8(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,\
+ y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15) \
+ QUARTERROUND4_V8_POLY(x0,x1,x2,x3,x4,x5,x6,x7,\
+ x8,x9,x10,x11,x12,x13,x14,x15,\
+ y0,y1,y2,y3,y4,y5,y6,y7,\
+ y8,y9,y10,y11,y12,y13,y14,y15,\
+ ,,,,,,,,,,,)
+
+#define TRANSPOSE_4X4_2(v0,v1,v2,v3,va,vb,vc,vd,tmp0,tmp1,tmp2,tmpa,tmpb,tmpc) \
+ vmrhf tmp0, v0, v1; \
+ vmrhf tmp1, v2, v3; \
+ vmrlf tmp2, v0, v1; \
+ vmrlf v3, v2, v3; \
+ vmrhf tmpa, va, vb; \
+ vmrhf tmpb, vc, vd; \
+ vmrlf tmpc, va, vb; \
+ vmrlf vd, vc, vd; \
+ vpdi v0, tmp0, tmp1, 0; \
+ vpdi v1, tmp0, tmp1, 5; \
+ vpdi v2, tmp2, v3, 0; \
+ vpdi v3, tmp2, v3, 5; \
+ vpdi va, tmpa, tmpb, 0; \
+ vpdi vb, tmpa, tmpb, 5; \
+ vpdi vc, tmpc, vd, 0; \
+ vpdi vd, tmpc, vd, 5;
+
+.balign 8
+.globl _gcry_chacha20_s390x_vx_blocks8
+ELF(.type _gcry_chacha20_s390x_vx_blocks8,@function;)
+
+_gcry_chacha20_s390x_vx_blocks8:
+ /* input:
+ * %r2: input
+ * %r3: dst
+ * %r4: src
+ * %r5: nblks (multiple of 8)
+ */
+ CFI_STARTPROC();
+
+ START_STACK(%r8);
+ lgr NBLKS, %r5;
+
+ larl %r7, .Lconsts;
+
+ /* Load counter. */
+ lg %r8, (12 * 4)(INPUT);
+ rllg %r8, %r8, 32;
+
+.balign 4
+ /* Process eight chacha20 blocks per loop. */
+.Lloop8:
+ vlm Y0, Y3, 0(INPUT);
+
+ slgfi NBLKS, 8;
+ lghi ROUND, (20 / 2);
+
+ /* Construct counter vectors X12/X13 & Y12/Y13. */
+ vl X4, (.Ladd_counter_0123 - .Lconsts)(%r7);
+ vl Y4, (.Ladd_counter_4567 - .Lconsts)(%r7);
+ vrepf Y12, Y3, 0;
+ vrepf Y13, Y3, 1;
+ vaccf X5, Y12, X4;
+ vaccf Y5, Y12, Y4;
+ vaf X12, Y12, X4;
+ vaf Y12, Y12, Y4;
+ vaf X13, Y13, X5;
+ vaf Y13, Y13, Y5;
+
+ vrepf X0, Y0, 0;
+ vrepf X1, Y0, 1;
+ vrepf X2, Y0, 2;
+ vrepf X3, Y0, 3;
+ vrepf X4, Y1, 0;
+ vrepf X5, Y1, 1;
+ vrepf X6, Y1, 2;
+ vrepf X7, Y1, 3;
+ vrepf X8, Y2, 0;
+ vrepf X9, Y2, 1;
+ vrepf X10, Y2, 2;
+ vrepf X11, Y2, 3;
+ vrepf X14, Y3, 2;
+ vrepf X15, Y3, 3;
+
+ /* Store counters for blocks 0-7. */
+ vstm X12, X13, (STACK_CTR + 0 * 16)(%r15);
+ vstm Y12, Y13, (STACK_CTR + 2 * 16)(%r15);
+
+ vlr Y0, X0;
+ vlr Y1, X1;
+ vlr Y2, X2;
+ vlr Y3, X3;
+ vlr Y4, X4;
+ vlr Y5, X5;
+ vlr Y6, X6;
+ vlr Y7, X7;
+ vlr Y8, X8;
+ vlr Y9, X9;
+ vlr Y10, X10;
+ vlr Y11, X11;
+ vlr Y14, X14;
+ vlr Y15, X15;
+
+ /* Update and store counter. */
+ agfi %r8, 8;
+ rllg %r5, %r8, 32;
+ stg %r5, (12 * 4)(INPUT);
+
+.balign 4
+.Lround2_8:
+ QUARTERROUND4_V8(X0, X4, X8, X12, X1, X5, X9, X13,
+ X2, X6, X10, X14, X3, X7, X11, X15,
+ Y0, Y4, Y8, Y12, Y1, Y5, Y9, Y13,
+ Y2, Y6, Y10, Y14, Y3, Y7, Y11, Y15);
+ QUARTERROUND4_V8(X0, X5, X10, X15, X1, X6, X11, X12,
+ X2, X7, X8, X13, X3, X4, X9, X14,
+ Y0, Y5, Y10, Y15, Y1, Y6, Y11, Y12,
+ Y2, Y7, Y8, Y13, Y3, Y4, Y9, Y14);
+ brctg ROUND, .Lround2_8;
+
+ /* Store blocks 4-7. */
+ vstm Y0, Y15, STACK_Y0_Y15(%r15);
+
+ /* Load counters for blocks 0-3. */
+ vlm Y0, Y1, (STACK_CTR + 0 * 16)(%r15);
+
+ lghi ROUND, 1;
+ j .Lfirst_output_4blks_8;
+
+.balign 4
+.Lsecond_output_4blks_8:
+ /* Load blocks 4-7. */
+ vlm X0, X15, STACK_Y0_Y15(%r15);
+
+ /* Load counters for blocks 4-7. */
+ vlm Y0, Y1, (STACK_CTR + 2 * 16)(%r15);
+
+ lghi ROUND, 0;
+
+.balign 4
+ /* Output four chacha20 blocks per loop. */
+.Lfirst_output_4blks_8:
+ vlm Y12, Y15, 0(INPUT);
+ PLUS(X12, Y0);
+ PLUS(X13, Y1);
+ vrepf Y0, Y12, 0;
+ vrepf Y1, Y12, 1;
+ vrepf Y2, Y12, 2;
+ vrepf Y3, Y12, 3;
+ vrepf Y4, Y13, 0;
+ vrepf Y5, Y13, 1;
+ vrepf Y6, Y13, 2;
+ vrepf Y7, Y13, 3;
+ vrepf Y8, Y14, 0;
+ vrepf Y9, Y14, 1;
+ vrepf Y10, Y14, 2;
+ vrepf Y11, Y14, 3;
+ vrepf Y14, Y15, 2;
+ vrepf Y15, Y15, 3;
+ PLUS(X0, Y0);
+ PLUS(X1, Y1);
+ PLUS(X2, Y2);
+ PLUS(X3, Y3);
+ PLUS(X4, Y4);
+ PLUS(X5, Y5);
+ PLUS(X6, Y6);
+ PLUS(X7, Y7);
+ PLUS(X8, Y8);
+ PLUS(X9, Y9);
+ PLUS(X10, Y10);
+ PLUS(X11, Y11);
+ PLUS(X14, Y14);
+ PLUS(X15, Y15);
+
+ vl Y15, (.Lbswap32 - .Lconsts)(%r7);
+ TRANSPOSE_4X4_2(X0, X1, X2, X3, X4, X5, X6, X7,
+ Y9, Y10, Y11, Y12, Y13, Y14);
+ TRANSPOSE_4X4_2(X8, X9, X10, X11, X12, X13, X14, X15,
+ Y9, Y10, Y11, Y12, Y13, Y14);
+
+ vlm Y0, Y14, 0(SRC);
+ vperm X0, X0, X0, Y15;
+ vperm X1, X1, X1, Y15;
+ vperm X2, X2, X2, Y15;
+ vperm X3, X3, X3, Y15;
+ vperm X4, X4, X4, Y15;
+ vperm X5, X5, X5, Y15;
+ vperm X6, X6, X6, Y15;
+ vperm X7, X7, X7, Y15;
+ vperm X8, X8, X8, Y15;
+ vperm X9, X9, X9, Y15;
+ vperm X10, X10, X10, Y15;
+ vperm X11, X11, X11, Y15;
+ vperm X12, X12, X12, Y15;
+ vperm X13, X13, X13, Y15;
+ vperm X14, X14, X14, Y15;
+ vperm X15, X15, X15, Y15;
+ vl Y15, (15 * 16)(SRC);
+
+ XOR(Y0, X0);
+ XOR(Y1, X4);
+ XOR(Y2, X8);
+ XOR(Y3, X12);
+ XOR(Y4, X1);
+ XOR(Y5, X5);
+ XOR(Y6, X9);
+ XOR(Y7, X13);
+ XOR(Y8, X2);
+ XOR(Y9, X6);
+ XOR(Y10, X10);
+ XOR(Y11, X14);
+ XOR(Y12, X3);
+ XOR(Y13, X7);
+ XOR(Y14, X11);
+ XOR(Y15, X15);
+ vstm Y0, Y15, 0(DST);
+
+ aghi SRC, 256;
+ aghi DST, 256;
+
+ clgije ROUND, 1, .Lsecond_output_4blks_8;
+
+ clgijhe NBLKS, 8, .Lloop8;
+
+ /* Clear the used vector registers. */
+ DST_8(CLEAR, 0, _);
+ DST_8(CLEAR, 1, _);
+ DST_8(CLEAR, 2, _);
+ DST_8(CLEAR, 3, _);
+
+ /* Clear sensitive data in stack. */
+ vlm Y0, Y15, STACK_Y0_Y15(%r15);
+ vlm Y0, Y3, STACK_CTR(%r15);
+
+ END_STACK(%r8);
+ xgr %r2, %r2;
+ br %r14;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_s390x_vx_blocks8,
+ .-_gcry_chacha20_s390x_vx_blocks8;)
+
+/**********************************************************************
+ 8-way stitched chacha20-poly1305 ("vertical")
+ **********************************************************************/
+
+.balign 8
+.globl _gcry_chacha20_poly1305_s390x_vx_blocks8
+ELF(.type _gcry_chacha20_poly1305_s390x_vx_blocks8,@function;)
+
+_gcry_chacha20_poly1305_s390x_vx_blocks8:
+ /* input:
+ * %r2: input
+ * %r3: dst
+ * %r4: src
+ * %r5: nblks (multiple of 8)
+ * %r6: poly1305 state
+ * 160(%r15): poly1305 src
+ */
+ CFI_STARTPROC();
+
+ START_STACK(%r14);
+
+ /* Store parameters to stack. */
+ stmg %r2, %r6, STACK_INPUT(%r15);
+
+ lgr POLY_RSTATE, %r6;
+ lgr NBLKS, %r5;
+
+ lg POLY_RSRC, 0(%r15);
+ lg POLY_RSRC, 160(POLY_RSRC);
+ stg POLY_RSRC, STACK_POSRC(%r15);
+
+ /* Load poly1305 state */
+ POLY1305_LOAD_STATE();
+
+.balign 4
+ /* Process eight chacha20 blocks and 32 poly1305 blocks per loop. */
+.Lloop8_poly:
+ lg INPUT, STACK_INPUT(%r15);
+ larl %r8, .Lconsts;
+
+ vlm Y0, Y3, 0(INPUT);
+
+ slgfi NBLKS, 8;
+ lghi ROUND, (20 / 2);
+
+ /* Construct counter vectors X12/X13 & Y12/Y13. */
+ vl X4, (.Ladd_counter_0123 - .Lconsts)(%r8);
+ vl Y4, (.Ladd_counter_4567 - .Lconsts)(%r8);
+ lg %r8, (12 * 4)(INPUT); /* Update counter. */
+ vrepf Y12, Y3, 0;
+ vrepf Y13, Y3, 1;
+ vaccf X5, Y12, X4;
+ vaccf Y5, Y12, Y4;
+ vaf X12, Y12, X4;
+ vaf Y12, Y12, Y4;
+ vaf X13, Y13, X5;
+ vaf Y13, Y13, Y5;
+ rllg %r8, %r8, 32;
+
+ vrepf X0, Y0, 0;
+ vrepf X1, Y0, 1;
+ vrepf X2, Y0, 2;
+ vrepf X3, Y0, 3;
+ vrepf X4, Y1, 0;
+ vrepf X5, Y1, 1;
+ vrepf X6, Y1, 2;
+ vrepf X7, Y1, 3;
+ vrepf X8, Y2, 0;
+ vrepf X9, Y2, 1;
+ vrepf X10, Y2, 2;
+ vrepf X11, Y2, 3;
+ vrepf X14, Y3, 2;
+ vrepf X15, Y3, 3;
+ agfi %r8, 8;
+
+ /* Store counters for blocks 0-7. */
+ vstm X12, X13, (STACK_CTR + 0 * 16)(%r15);
+ vstm Y12, Y13, (STACK_CTR + 2 * 16)(%r15);
+ rllg %r8, %r8, 32;
+
+ vlr Y0, X0;
+ vlr Y1, X1;
+ vlr Y2, X2;
+ vlr Y3, X3;
+ vlr Y4, X4;
+ vlr Y5, X5;
+ vlr Y6, X6;
+ vlr Y7, X7;
+ vlr Y8, X8;
+ vlr Y9, X9;
+ vlr Y10, X10;
+ vlr Y11, X11;
+ vlr Y14, X14;
+ vlr Y15, X15;
+ stg %r8, (12 * 4)(INPUT);
+
+.balign 4
+.Lround2_8_poly:
+ /* Total 30 poly1305 blocks processed by this loop. */
+ QUARTERROUND4_V8_POLY(X0, X4, X8, X12, X1, X5, X9, X13,
+ X2, X6, X10, X14, X3, X7, X11, X15,
+ Y0, Y4, Y8, Y12, Y1, Y5, Y9, Y13,
+ Y2, Y6, Y10, Y14, Y3, Y7, Y11, Y15,
+ POLY1305_BLOCK_PART1(0 * 16),
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6(),
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8(),
+ POLY1305_BLOCK_PART1(1 * 16),
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4());
+ QUARTERROUND4_V8_POLY(X0, X5, X10, X15, X1, X6, X11, X12,
+ X2, X7, X8, X13, X3, X4, X9, X14,
+ Y0, Y5, Y10, Y15, Y1, Y6, Y11, Y12,
+ Y2, Y7, Y8, Y13, Y3, Y4, Y9, Y14,
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6(),
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8(),
+ POLY1305_BLOCK_PART1(2 * 16);
+ INC_POLY1305_SRC(3 * 16),
+ POLY1305_BLOCK_PART2(),
+ POLY1305_BLOCK_PART3(),
+ POLY1305_BLOCK_PART4(),
+ POLY1305_BLOCK_PART5(),
+ POLY1305_BLOCK_PART6(),
+ POLY1305_BLOCK_PART7(),
+ POLY1305_BLOCK_PART8());
+ brctg ROUND, .Lround2_8_poly;
+
+ POLY1305_BLOCK_PART1(0 * 16);
+
+ /* Store blocks 4-7. */
+ vstm Y0, Y15, STACK_Y0_Y15(%r15);
+
+ /* Load counters for blocks 0-3. */
+ vlm Y0, Y1, (STACK_CTR + 0 * 16)(%r15);
+
+ stg POLY_RSRC, STACK_POSRC(%r15); /* %r14 used for INPUT/SRC/DST pointer. */
+
+ lghi ROUND, 1;
+ j .Lfirst_output_4blks_8_poly;
+
+.balign 4
+.Lsecond_output_4blks_8_poly:
+
+ POLY1305_BLOCK_PART1(1 * 16);
+
+ /* Load blocks 4-7. */
+ vlm X0, X15, STACK_Y0_Y15(%r15);
+
+ /* Load counters for blocks 4-7. */
+ vlm Y0, Y1, (STACK_CTR + 2 * 16)(%r15);
+
+ INC_POLY1305_SRC(2 * 16);
+ stg POLY_RSRC, STACK_POSRC(%r15); /* %r14 used for INPUT/SRC/DST pointer. */
+
+ lghi ROUND, 0;
+
+.balign 4
+ /* Output four chacha20 blocks and one poly1305 block per loop. */
+.Lfirst_output_4blks_8_poly:
+ lg %r14, STACK_INPUT(%r15);
+ vlm Y12, Y15, 0(%r14);
+ POLY1305_BLOCK_PART2();
+ PLUS(X12, Y0);
+ PLUS(X13, Y1);
+ vrepf Y0, Y12, 0;
+ vrepf Y1, Y12, 1;
+ vrepf Y2, Y12, 2;
+ vrepf Y3, Y12, 3;
+ vrepf Y4, Y13, 0;
+ vrepf Y5, Y13, 1;
+ vrepf Y6, Y13, 2;
+ vrepf Y7, Y13, 3;
+ vrepf Y8, Y14, 0;
+ vrepf Y9, Y14, 1;
+ vrepf Y10, Y14, 2;
+ vrepf Y11, Y14, 3;
+ vrepf Y14, Y15, 2;
+ vrepf Y15, Y15, 3;
+ POLY1305_BLOCK_PART3();
+ PLUS(X0, Y0);
+ PLUS(X1, Y1);
+ PLUS(X2, Y2);
+ PLUS(X3, Y3);
+ PLUS(X4, Y4);
+ PLUS(X5, Y5);
+ PLUS(X6, Y6);
+ PLUS(X7, Y7);
+ PLUS(X8, Y8);
+ PLUS(X9, Y9);
+ PLUS(X10, Y10);
+ PLUS(X11, Y11);
+ PLUS(X14, Y14);
+ PLUS(X15, Y15);
+ POLY1305_BLOCK_PART4();
+
+ larl %r14, .Lconsts;
+ vl Y15, (.Lbswap32 - .Lconsts)(%r14);
+ TRANSPOSE_4X4_2(X0, X1, X2, X3, X4, X5, X6, X7,
+ Y9, Y10, Y11, Y12, Y13, Y14);
+ lg %r14, STACK_SRC(%r15);
+ POLY1305_BLOCK_PART5();
+ TRANSPOSE_4X4_2(X8, X9, X10, X11, X12, X13, X14, X15,
+ Y9, Y10, Y11, Y12, Y13, Y14);
+
+ vlm Y0, Y14, 0(%r14);
+ POLY1305_BLOCK_PART6();
+ vperm X0, X0, X0, Y15;
+ vperm X1, X1, X1, Y15;
+ vperm X2, X2, X2, Y15;
+ vperm X3, X3, X3, Y15;
+ vperm X4, X4, X4, Y15;
+ vperm X5, X5, X5, Y15;
+ vperm X6, X6, X6, Y15;
+ vperm X7, X7, X7, Y15;
+ vperm X8, X8, X8, Y15;
+ vperm X9, X9, X9, Y15;
+ vperm X10, X10, X10, Y15;
+ vperm X11, X11, X11, Y15;
+ vperm X12, X12, X12, Y15;
+ vperm X13, X13, X13, Y15;
+ vperm X14, X14, X14, Y15;
+ vperm X15, X15, X15, Y15;
+ vl Y15, (15 * 16)(%r14);
+ POLY1305_BLOCK_PART7();
+
+ aghi %r14, 256;
+ stg %r14, STACK_SRC(%r15);
+ lg %r14, STACK_DST(%r15);
+
+ XOR(Y0, X0);
+ XOR(Y1, X4);
+ XOR(Y2, X8);
+ XOR(Y3, X12);
+ XOR(Y4, X1);
+ XOR(Y5, X5);
+ XOR(Y6, X9);
+ XOR(Y7, X13);
+ XOR(Y8, X2);
+ XOR(Y9, X6);
+ XOR(Y10, X10);
+ XOR(Y11, X14);
+ XOR(Y12, X3);
+ XOR(Y13, X7);
+ XOR(Y14, X11);
+ XOR(Y15, X15);
+ POLY1305_BLOCK_PART8();
+ vstm Y0, Y15, 0(%r14);
+
+ aghi %r14, 256;
+ stg %r14, STACK_DST(%r15);
+
+ lg POLY_RSRC, STACK_POSRC(%r15);
+
+ clgije ROUND, 1, .Lsecond_output_4blks_8_poly;
+
+ clgijhe NBLKS, 8, .Lloop8_poly;
+
+ /* Store poly1305 state */
+ lg POLY_RSTATE, STACK_POCTX(%r15);
+ POLY1305_STORE_STATE();
+
+ /* Clear the used vector registers */
+ DST_8(CLEAR, 0, _);
+ DST_8(CLEAR, 1, _);
+ DST_8(CLEAR, 2, _);
+ DST_8(CLEAR, 3, _);
+
+ /* Clear sensitive data in stack. */
+ vlm Y0, Y15, STACK_Y0_Y15(%r15);
+ vlm Y0, Y3, STACK_CTR(%r15);
+
+ END_STACK(%r14);
+ xgr %r2, %r2;
+ br %r14;
+ CFI_ENDPROC();
+ELF(.size _gcry_chacha20_poly1305_s390x_vx_blocks8,
+ .-_gcry_chacha20_poly1305_s390x_vx_blocks8;)
+
+#endif /*HAVE_GCC_INLINE_ASM_S390X_VX*/
+#endif /*__s390x__*/
diff --git a/comm/third_party/libgcrypt/cipher/chacha20.c b/comm/third_party/libgcrypt/cipher/chacha20.c
new file mode 100644
index 0000000000..497594a0bb
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/chacha20.c
@@ -0,0 +1,1306 @@
+/* chacha20.c - Bernstein's ChaCha20 cipher
+ * Copyright (C) 2014,2017-2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * For a description of the algorithm, see:
+ * http://cr.yp.to/chacha.html
+ */
+
+/*
+ * Based on D. J. Bernstein reference implementation at
+ * http://cr.yp.to/chacha.html:
+ *
+ * chacha-regs.c version 20080118
+ * D. J. Bernstein
+ * Public domain.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "cipher-internal.h"
+#include "bufhelp.h"
+
+
+#define CHACHA20_MIN_KEY_SIZE 16 /* Bytes. */
+#define CHACHA20_MAX_KEY_SIZE 32 /* Bytes. */
+#define CHACHA20_BLOCK_SIZE 64 /* Bytes. */
+#define CHACHA20_MIN_IV_SIZE 8 /* Bytes. */
+#define CHACHA20_MAX_IV_SIZE 12 /* Bytes. */
+#define CHACHA20_CTR_SIZE 16 /* Bytes. */
+
+
+/* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
+#undef USE_SSSE3
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_SSSE3 1
+#endif
+
+/* USE_AVX2 indicates whether to compile with Intel AVX2 code. */
+#undef USE_AVX2
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX2 1
+#endif
+
+/* USE_ARMV7_NEON indicates whether to enable ARMv7 NEON assembly code. */
+#undef USE_ARMV7_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_ARMV7_NEON 1
+# endif
+#endif
+
+/* USE_AARCH64_SIMD indicates whether to enable ARMv8 SIMD assembly
+ * code. */
+#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
+
+/* USE_PPC_VEC indicates whether to enable PowerPC vector
+ * accelerated code. */
+#undef USE_PPC_VEC
+#ifdef ENABLE_PPC_CRYPTO_SUPPORT
+# if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC)
+# if __GNUC__ >= 4
+# define USE_PPC_VEC 1
+# endif
+# endif
+#endif
+
+/* USE_S390X_VX indicates whether to enable zSeries code. */
+#undef USE_S390X_VX
+#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9
+# if defined(HAVE_GCC_INLINE_ASM_S390X_VX)
+# define USE_S390X_VX 1
+# endif /* USE_S390X_VX */
+#endif
+
+/* 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(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+#else
+# define ASM_FUNC_ABI
+#endif
+
+
+typedef struct CHACHA20_context_s
+{
+ u32 input[16];
+ unsigned char pad[CHACHA20_BLOCK_SIZE];
+ unsigned int unused; /* bytes in the pad. */
+ unsigned int use_ssse3:1;
+ unsigned int use_avx2:1;
+ unsigned int use_neon:1;
+ unsigned int use_ppc:1;
+ unsigned int use_s390x:1;
+} CHACHA20_context_t;
+
+
+#ifdef USE_SSSE3
+
+unsigned int _gcry_chacha20_amd64_ssse3_blocks4(u32 *state, byte *dst,
+ const byte *src,
+ size_t nblks) ASM_FUNC_ABI;
+
+unsigned int _gcry_chacha20_amd64_ssse3_blocks1(u32 *state, byte *dst,
+ const byte *src,
+ size_t nblks) ASM_FUNC_ABI;
+
+unsigned int _gcry_chacha20_poly1305_amd64_ssse3_blocks4(
+ u32 *state, byte *dst, const byte *src, size_t nblks,
+ void *poly1305_state, const byte *poly1305_src) ASM_FUNC_ABI;
+
+unsigned int _gcry_chacha20_poly1305_amd64_ssse3_blocks1(
+ u32 *state, byte *dst, const byte *src, size_t nblks,
+ void *poly1305_state, const byte *poly1305_src) ASM_FUNC_ABI;
+
+#endif /* USE_SSSE3 */
+
+#ifdef USE_AVX2
+
+unsigned int _gcry_chacha20_amd64_avx2_blocks8(u32 *state, byte *dst,
+ const byte *src,
+ size_t nblks) ASM_FUNC_ABI;
+
+unsigned int _gcry_chacha20_poly1305_amd64_avx2_blocks8(
+ u32 *state, byte *dst, const byte *src, size_t nblks,
+ void *poly1305_state, const byte *poly1305_src) ASM_FUNC_ABI;
+
+#endif /* USE_AVX2 */
+
+#ifdef USE_PPC_VEC
+
+unsigned int _gcry_chacha20_ppc8_blocks4(u32 *state, byte *dst,
+ const byte *src,
+ size_t nblks);
+
+unsigned int _gcry_chacha20_ppc8_blocks1(u32 *state, byte *dst,
+ const byte *src,
+ size_t nblks);
+
+#undef USE_PPC_VEC_POLY1305
+#if SIZEOF_UNSIGNED_LONG == 8
+#define USE_PPC_VEC_POLY1305 1
+unsigned int _gcry_chacha20_poly1305_ppc8_blocks4(
+ u32 *state, byte *dst, const byte *src, size_t nblks,
+ POLY1305_STATE *st, const byte *poly1305_src);
+#endif /* SIZEOF_UNSIGNED_LONG == 8 */
+
+#endif /* USE_PPC_VEC */
+
+#ifdef USE_S390X_VX
+
+unsigned int _gcry_chacha20_s390x_vx_blocks8(u32 *state, byte *dst,
+ const byte *src, size_t nblks);
+
+unsigned int _gcry_chacha20_s390x_vx_blocks4_2_1(u32 *state, byte *dst,
+ const byte *src, size_t nblks);
+
+#undef USE_S390X_VX_POLY1305
+#if SIZEOF_UNSIGNED_LONG == 8
+#define USE_S390X_VX_POLY1305 1
+unsigned int _gcry_chacha20_poly1305_s390x_vx_blocks8(
+ u32 *state, byte *dst, const byte *src, size_t nblks,
+ POLY1305_STATE *st, const byte *poly1305_src);
+
+unsigned int _gcry_chacha20_poly1305_s390x_vx_blocks4_2_1(
+ u32 *state, byte *dst, const byte *src, size_t nblks,
+ POLY1305_STATE *st, const byte *poly1305_src);
+#endif /* SIZEOF_UNSIGNED_LONG == 8 */
+
+#endif /* USE_S390X_VX */
+
+#ifdef USE_ARMV7_NEON
+
+unsigned int _gcry_chacha20_armv7_neon_blocks4(u32 *state, byte *dst,
+ const byte *src,
+ size_t nblks);
+
+#endif /* USE_ARMV7_NEON */
+
+#ifdef USE_AARCH64_SIMD
+
+unsigned int _gcry_chacha20_aarch64_blocks4(u32 *state, byte *dst,
+ const byte *src, size_t nblks);
+
+unsigned int _gcry_chacha20_poly1305_aarch64_blocks4(
+ u32 *state, byte *dst, const byte *src, size_t nblks,
+ void *poly1305_state, const byte *poly1305_src);
+
+#endif /* USE_AARCH64_SIMD */
+
+
+static const char *selftest (void);
+
+
+#define ROTATE(v,c) (rol(v,c))
+#define XOR(v,w) ((v) ^ (w))
+#define PLUS(v,w) ((u32)((v) + (w)))
+#define PLUSONE(v) (PLUS((v),1))
+
+#define QUARTERROUND(a,b,c,d) \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
+
+#define BUF_XOR_LE32(dst, src, offset, x) \
+ buf_put_le32((dst) + (offset), buf_get_le32((src) + (offset)) ^ (x))
+
+static unsigned int
+do_chacha20_blocks (u32 *input, byte *dst, const byte *src, size_t nblks)
+{
+ u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
+ unsigned int i;
+
+ while (nblks)
+ {
+ x0 = input[0];
+ x1 = input[1];
+ x2 = input[2];
+ x3 = input[3];
+ x4 = input[4];
+ x5 = input[5];
+ x6 = input[6];
+ x7 = input[7];
+ x8 = input[8];
+ x9 = input[9];
+ x10 = input[10];
+ x11 = input[11];
+ x12 = input[12];
+ x13 = input[13];
+ x14 = input[14];
+ x15 = input[15];
+
+ for (i = 20; i > 0; i -= 2)
+ {
+ QUARTERROUND(x0, x4, x8, x12)
+ QUARTERROUND(x1, x5, x9, x13)
+ QUARTERROUND(x2, x6, x10, x14)
+ QUARTERROUND(x3, x7, x11, x15)
+ QUARTERROUND(x0, x5, x10, x15)
+ QUARTERROUND(x1, x6, x11, x12)
+ QUARTERROUND(x2, x7, x8, x13)
+ QUARTERROUND(x3, x4, x9, x14)
+ }
+
+ x0 = PLUS(x0, input[0]);
+ x1 = PLUS(x1, input[1]);
+ x2 = PLUS(x2, input[2]);
+ x3 = PLUS(x3, input[3]);
+ x4 = PLUS(x4, input[4]);
+ x5 = PLUS(x5, input[5]);
+ x6 = PLUS(x6, input[6]);
+ x7 = PLUS(x7, input[7]);
+ x8 = PLUS(x8, input[8]);
+ x9 = PLUS(x9, input[9]);
+ x10 = PLUS(x10, input[10]);
+ x11 = PLUS(x11, input[11]);
+ x12 = PLUS(x12, input[12]);
+ x13 = PLUS(x13, input[13]);
+ x14 = PLUS(x14, input[14]);
+ x15 = PLUS(x15, input[15]);
+
+ input[12] = PLUSONE(input[12]);
+ input[13] = PLUS(input[13], !input[12]);
+
+ BUF_XOR_LE32(dst, src, 0, x0);
+ BUF_XOR_LE32(dst, src, 4, x1);
+ BUF_XOR_LE32(dst, src, 8, x2);
+ BUF_XOR_LE32(dst, src, 12, x3);
+ BUF_XOR_LE32(dst, src, 16, x4);
+ BUF_XOR_LE32(dst, src, 20, x5);
+ BUF_XOR_LE32(dst, src, 24, x6);
+ BUF_XOR_LE32(dst, src, 28, x7);
+ BUF_XOR_LE32(dst, src, 32, x8);
+ BUF_XOR_LE32(dst, src, 36, x9);
+ BUF_XOR_LE32(dst, src, 40, x10);
+ BUF_XOR_LE32(dst, src, 44, x11);
+ BUF_XOR_LE32(dst, src, 48, x12);
+ BUF_XOR_LE32(dst, src, 52, x13);
+ BUF_XOR_LE32(dst, src, 56, x14);
+ BUF_XOR_LE32(dst, src, 60, x15);
+
+ src += CHACHA20_BLOCK_SIZE;
+ dst += CHACHA20_BLOCK_SIZE;
+ nblks--;
+ }
+
+ /* burn_stack */
+ return (17 * sizeof(u32) + 6 * sizeof(void *));
+}
+
+
+static unsigned int
+chacha20_blocks (CHACHA20_context_t *ctx, byte *dst, const byte *src,
+ size_t nblks)
+{
+#ifdef USE_SSSE3
+ if (ctx->use_ssse3)
+ {
+ return _gcry_chacha20_amd64_ssse3_blocks1(ctx->input, dst, src, nblks);
+ }
+#endif
+
+#ifdef USE_PPC_VEC
+ if (ctx->use_ppc)
+ {
+ return _gcry_chacha20_ppc8_blocks1(ctx->input, dst, src, nblks);
+ }
+#endif
+
+#ifdef USE_S390X_VX
+ if (ctx->use_s390x)
+ {
+ return _gcry_chacha20_s390x_vx_blocks4_2_1(ctx->input, dst, src, nblks);
+ }
+#endif
+
+ return do_chacha20_blocks (ctx->input, dst, src, nblks);
+}
+
+
+static void
+chacha20_keysetup (CHACHA20_context_t *ctx, const byte *key,
+ unsigned int keylen)
+{
+ static const char sigma[16] = "expand 32-byte k";
+ static const char tau[16] = "expand 16-byte k";
+ const char *constants;
+
+ ctx->input[4] = buf_get_le32(key + 0);
+ ctx->input[5] = buf_get_le32(key + 4);
+ ctx->input[6] = buf_get_le32(key + 8);
+ ctx->input[7] = buf_get_le32(key + 12);
+ if (keylen == CHACHA20_MAX_KEY_SIZE) /* 256 bits */
+ {
+ key += 16;
+ constants = sigma;
+ }
+ else /* 128 bits */
+ {
+ constants = tau;
+ }
+ ctx->input[8] = buf_get_le32(key + 0);
+ ctx->input[9] = buf_get_le32(key + 4);
+ ctx->input[10] = buf_get_le32(key + 8);
+ ctx->input[11] = buf_get_le32(key + 12);
+ ctx->input[0] = buf_get_le32(constants + 0);
+ ctx->input[1] = buf_get_le32(constants + 4);
+ ctx->input[2] = buf_get_le32(constants + 8);
+ ctx->input[3] = buf_get_le32(constants + 12);
+}
+
+
+static void
+chacha20_ivsetup (CHACHA20_context_t * ctx, const byte *iv, size_t ivlen)
+{
+ if (ivlen == CHACHA20_CTR_SIZE)
+ {
+ ctx->input[12] = buf_get_le32 (iv + 0);
+ ctx->input[13] = buf_get_le32 (iv + 4);
+ ctx->input[14] = buf_get_le32 (iv + 8);
+ ctx->input[15] = buf_get_le32 (iv + 12);
+ }
+ else if (ivlen == CHACHA20_MAX_IV_SIZE)
+ {
+ ctx->input[12] = 0;
+ ctx->input[13] = buf_get_le32 (iv + 0);
+ ctx->input[14] = buf_get_le32 (iv + 4);
+ ctx->input[15] = buf_get_le32 (iv + 8);
+ }
+ else if (ivlen == CHACHA20_MIN_IV_SIZE)
+ {
+ ctx->input[12] = 0;
+ ctx->input[13] = 0;
+ ctx->input[14] = buf_get_le32 (iv + 0);
+ ctx->input[15] = buf_get_le32 (iv + 4);
+ }
+ else
+ {
+ ctx->input[12] = 0;
+ ctx->input[13] = 0;
+ ctx->input[14] = 0;
+ ctx->input[15] = 0;
+ }
+}
+
+
+static void
+chacha20_setiv (void *context, const byte *iv, size_t ivlen)
+{
+ CHACHA20_context_t *ctx = (CHACHA20_context_t *) context;
+
+ /* draft-nir-cfrg-chacha20-poly1305-02 defines 96-bit and 64-bit nonce. */
+ if (iv && ivlen != CHACHA20_MAX_IV_SIZE && ivlen != CHACHA20_MIN_IV_SIZE
+ && ivlen != CHACHA20_CTR_SIZE)
+ log_info ("WARNING: chacha20_setiv: bad ivlen=%u\n", (u32) ivlen);
+
+ if (iv && (ivlen == CHACHA20_MAX_IV_SIZE || ivlen == CHACHA20_MIN_IV_SIZE
+ || ivlen == CHACHA20_CTR_SIZE))
+ chacha20_ivsetup (ctx, iv, ivlen);
+ else
+ chacha20_ivsetup (ctx, NULL, 0);
+
+ /* Reset the unused pad bytes counter. */
+ ctx->unused = 0;
+}
+
+
+static gcry_err_code_t
+chacha20_do_setkey (CHACHA20_context_t *ctx,
+ const byte *key, unsigned int keylen)
+{
+ static int initialized;
+ static const char *selftest_failed;
+ unsigned int features = _gcry_get_hw_features ();
+
+ if (!initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if (selftest_failed)
+ log_error ("CHACHA20 selftest failed (%s)\n", selftest_failed);
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if (keylen != CHACHA20_MAX_KEY_SIZE && keylen != CHACHA20_MIN_KEY_SIZE)
+ return GPG_ERR_INV_KEYLEN;
+
+#ifdef USE_SSSE3
+ ctx->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
+#endif
+#ifdef USE_AVX2
+ ctx->use_avx2 = (features & HWF_INTEL_AVX2) != 0;
+#endif
+#ifdef USE_ARMV7_NEON
+ ctx->use_neon = (features & HWF_ARM_NEON) != 0;
+#endif
+#ifdef USE_AARCH64_SIMD
+ ctx->use_neon = (features & HWF_ARM_NEON) != 0;
+#endif
+#ifdef USE_PPC_VEC
+ ctx->use_ppc = (features & HWF_PPC_ARCH_2_07) != 0;
+#endif
+#ifdef USE_S390X_VX
+ ctx->use_s390x = (features & HWF_S390X_VX) != 0;
+#endif
+
+ (void)features;
+
+ chacha20_keysetup (ctx, key, keylen);
+
+ /* We default to a zero nonce. */
+ chacha20_setiv (ctx, NULL, 0);
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+chacha20_setkey (void *context, const byte *key, unsigned int keylen,
+ cipher_bulk_ops_t *bulk_ops)
+{
+ CHACHA20_context_t *ctx = (CHACHA20_context_t *) context;
+ gcry_err_code_t rc = chacha20_do_setkey (ctx, key, keylen);
+ (void)bulk_ops;
+ _gcry_burn_stack (4 + sizeof (void *) + 4 * sizeof (void *));
+ return rc;
+}
+
+
+static unsigned int
+do_chacha20_encrypt_stream_tail (CHACHA20_context_t *ctx, byte *outbuf,
+ const byte *inbuf, size_t length)
+{
+ static const unsigned char zero_pad[CHACHA20_BLOCK_SIZE] = { 0, };
+ unsigned int nburn, burn = 0;
+
+#ifdef USE_AVX2
+ if (ctx->use_avx2 && length >= CHACHA20_BLOCK_SIZE * 8)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 8;
+ nburn = _gcry_chacha20_amd64_avx2_blocks8(ctx->input, outbuf, inbuf,
+ nblocks);
+ burn = nburn > burn ? nburn : burn;
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_SSSE3
+ if (ctx->use_ssse3 && length >= CHACHA20_BLOCK_SIZE * 4)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+ nburn = _gcry_chacha20_amd64_ssse3_blocks4(ctx->input, outbuf, inbuf,
+ nblocks);
+ burn = nburn > burn ? nburn : burn;
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_ARMV7_NEON
+ if (ctx->use_neon && length >= CHACHA20_BLOCK_SIZE * 4)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+ nburn = _gcry_chacha20_armv7_neon_blocks4(ctx->input, outbuf, inbuf,
+ nblocks);
+ burn = nburn > burn ? nburn : burn;
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_AARCH64_SIMD
+ if (ctx->use_neon && length >= CHACHA20_BLOCK_SIZE * 4)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+ nburn = _gcry_chacha20_aarch64_blocks4(ctx->input, outbuf, inbuf,
+ nblocks);
+ burn = nburn > burn ? nburn : burn;
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_PPC_VEC
+ if (ctx->use_ppc && length >= CHACHA20_BLOCK_SIZE * 4)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+ nburn = _gcry_chacha20_ppc8_blocks4(ctx->input, outbuf, inbuf, nblocks);
+ burn = nburn > burn ? nburn : burn;
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_S390X_VX
+ if (ctx->use_s390x && length >= CHACHA20_BLOCK_SIZE * 8)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 8;
+ nburn = _gcry_chacha20_s390x_vx_blocks8(ctx->input, outbuf, inbuf,
+ nblocks);
+ burn = nburn > burn ? nburn : burn;
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+ if (length >= CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nburn = chacha20_blocks(ctx, outbuf, inbuf, nblocks);
+ burn = nburn > burn ? nburn : burn;
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+
+ if (length > 0)
+ {
+ nburn = chacha20_blocks(ctx, ctx->pad, zero_pad, 1);
+ burn = nburn > burn ? nburn : burn;
+
+ buf_xor (outbuf, inbuf, ctx->pad, length);
+ ctx->unused = CHACHA20_BLOCK_SIZE - length;
+ }
+
+ if (burn)
+ burn += 5 * sizeof(void *);
+
+ return burn;
+}
+
+
+static void
+chacha20_encrypt_stream (void *context, byte *outbuf, const byte *inbuf,
+ size_t length)
+{
+ CHACHA20_context_t *ctx = (CHACHA20_context_t *) context;
+ unsigned int nburn, burn = 0;
+
+ if (!length)
+ return;
+
+ if (ctx->unused)
+ {
+ unsigned char *p = ctx->pad;
+ size_t n;
+
+ gcry_assert (ctx->unused < CHACHA20_BLOCK_SIZE);
+
+ n = ctx->unused;
+ if (n > length)
+ n = length;
+
+ buf_xor (outbuf, inbuf, p + CHACHA20_BLOCK_SIZE - ctx->unused, n);
+ length -= n;
+ outbuf += n;
+ inbuf += n;
+ ctx->unused -= n;
+
+ if (!length)
+ return;
+ gcry_assert (!ctx->unused);
+ }
+
+ nburn = do_chacha20_encrypt_stream_tail (ctx, outbuf, inbuf, length);
+ burn = nburn > burn ? nburn : burn;
+
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+
+gcry_err_code_t
+_gcry_chacha20_poly1305_encrypt(gcry_cipher_hd_t c, byte *outbuf,
+ const byte *inbuf, size_t length)
+{
+ CHACHA20_context_t *ctx = (void *) &c->context.c;
+ unsigned int nburn, burn = 0;
+ byte *authptr = NULL;
+
+ if (!length)
+ return 0;
+
+ if (ctx->unused)
+ {
+ unsigned char *p = ctx->pad;
+ size_t n;
+
+ gcry_assert (ctx->unused < CHACHA20_BLOCK_SIZE);
+
+ n = ctx->unused;
+ if (n > length)
+ n = length;
+
+ buf_xor (outbuf, inbuf, p + CHACHA20_BLOCK_SIZE - ctx->unused, n);
+ nburn = _gcry_poly1305_update_burn (&c->u_mode.poly1305.ctx, outbuf, n);
+ burn = nburn > burn ? nburn : burn;
+ length -= n;
+ outbuf += n;
+ inbuf += n;
+ ctx->unused -= n;
+
+ if (!length)
+ {
+ if (burn)
+ _gcry_burn_stack (burn);
+
+ return 0;
+ }
+ gcry_assert (!ctx->unused);
+ }
+
+ gcry_assert (c->u_mode.poly1305.ctx.leftover == 0);
+
+ if (0)
+ { }
+#ifdef USE_AVX2
+ else if (ctx->use_avx2 && length >= CHACHA20_BLOCK_SIZE * 8)
+ {
+ nburn = _gcry_chacha20_amd64_avx2_blocks8(ctx->input, outbuf, inbuf, 8);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 8 * CHACHA20_BLOCK_SIZE;
+ outbuf += 8 * CHACHA20_BLOCK_SIZE;
+ inbuf += 8 * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+#ifdef USE_SSSE3
+ else if (ctx->use_ssse3 && length >= CHACHA20_BLOCK_SIZE * 4)
+ {
+ nburn = _gcry_chacha20_amd64_ssse3_blocks4(ctx->input, outbuf, inbuf, 4);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 4 * CHACHA20_BLOCK_SIZE;
+ outbuf += 4 * CHACHA20_BLOCK_SIZE;
+ inbuf += 4 * CHACHA20_BLOCK_SIZE;
+ }
+ else if (ctx->use_ssse3 && length >= CHACHA20_BLOCK_SIZE * 2)
+ {
+ nburn = _gcry_chacha20_amd64_ssse3_blocks1(ctx->input, outbuf, inbuf, 2);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 2 * CHACHA20_BLOCK_SIZE;
+ outbuf += 2 * CHACHA20_BLOCK_SIZE;
+ inbuf += 2 * CHACHA20_BLOCK_SIZE;
+ }
+ else if (ctx->use_ssse3 && length >= CHACHA20_BLOCK_SIZE)
+ {
+ nburn = _gcry_chacha20_amd64_ssse3_blocks1(ctx->input, outbuf, inbuf, 1);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 1 * CHACHA20_BLOCK_SIZE;
+ outbuf += 1 * CHACHA20_BLOCK_SIZE;
+ inbuf += 1 * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+#ifdef USE_AARCH64_SIMD
+ else if (ctx->use_neon && length >= CHACHA20_BLOCK_SIZE * 4)
+ {
+ nburn = _gcry_chacha20_aarch64_blocks4(ctx->input, outbuf, inbuf, 4);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 4 * CHACHA20_BLOCK_SIZE;
+ outbuf += 4 * CHACHA20_BLOCK_SIZE;
+ inbuf += 4 * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+#ifdef USE_PPC_VEC_POLY1305
+ else if (ctx->use_ppc && length >= CHACHA20_BLOCK_SIZE * 4)
+ {
+ nburn = _gcry_chacha20_ppc8_blocks4(ctx->input, outbuf, inbuf, 4);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 4 * CHACHA20_BLOCK_SIZE;
+ outbuf += 4 * CHACHA20_BLOCK_SIZE;
+ inbuf += 4 * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+#ifdef USE_S390X_VX_POLY1305
+ else if (ctx->use_s390x && length >= 2 * CHACHA20_BLOCK_SIZE * 8)
+ {
+ nburn = _gcry_chacha20_s390x_vx_blocks8(ctx->input, outbuf, inbuf, 8);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 8 * CHACHA20_BLOCK_SIZE;
+ outbuf += 8 * CHACHA20_BLOCK_SIZE;
+ inbuf += 8 * CHACHA20_BLOCK_SIZE;
+ }
+ else if (ctx->use_s390x && length >= CHACHA20_BLOCK_SIZE * 4)
+ {
+ nburn = _gcry_chacha20_s390x_vx_blocks4_2_1(ctx->input, outbuf, inbuf, 4);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 4 * CHACHA20_BLOCK_SIZE;
+ outbuf += 4 * CHACHA20_BLOCK_SIZE;
+ inbuf += 4 * CHACHA20_BLOCK_SIZE;
+ }
+ else if (ctx->use_s390x && length >= CHACHA20_BLOCK_SIZE * 2)
+ {
+ nburn = _gcry_chacha20_s390x_vx_blocks4_2_1(ctx->input, outbuf, inbuf, 2);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 2 * CHACHA20_BLOCK_SIZE;
+ outbuf += 2 * CHACHA20_BLOCK_SIZE;
+ inbuf += 2 * CHACHA20_BLOCK_SIZE;
+ }
+ else if (ctx->use_s390x && length >= CHACHA20_BLOCK_SIZE)
+ {
+ nburn = _gcry_chacha20_s390x_vx_blocks4_2_1(ctx->input, outbuf, inbuf, 1);
+ burn = nburn > burn ? nburn : burn;
+
+ authptr = outbuf;
+ length -= 1 * CHACHA20_BLOCK_SIZE;
+ outbuf += 1 * CHACHA20_BLOCK_SIZE;
+ inbuf += 1 * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+ if (authptr)
+ {
+ size_t authoffset = outbuf - authptr;
+
+#ifdef USE_AVX2
+ if (ctx->use_avx2 &&
+ length >= 8 * CHACHA20_BLOCK_SIZE &&
+ authoffset >= 8 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 8;
+
+ nburn = _gcry_chacha20_poly1305_amd64_avx2_blocks8(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, authptr);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ authptr += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_SSSE3
+ if (ctx->use_ssse3)
+ {
+ if (length >= 4 * CHACHA20_BLOCK_SIZE &&
+ authoffset >= 4 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+
+ nburn = _gcry_chacha20_poly1305_amd64_ssse3_blocks4(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, authptr);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ authptr += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+
+ if (length >= CHACHA20_BLOCK_SIZE &&
+ authoffset >= CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+
+ nburn = _gcry_chacha20_poly1305_amd64_ssse3_blocks1(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, authptr);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ authptr += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+ }
+#endif
+
+#ifdef USE_AARCH64_SIMD
+ if (ctx->use_neon &&
+ length >= 4 * CHACHA20_BLOCK_SIZE &&
+ authoffset >= 4 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+
+ nburn = _gcry_chacha20_poly1305_aarch64_blocks4(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, authptr);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ authptr += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_PPC_VEC_POLY1305
+ if (ctx->use_ppc &&
+ length >= 4 * CHACHA20_BLOCK_SIZE &&
+ authoffset >= 4 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+
+ nburn = _gcry_chacha20_poly1305_ppc8_blocks4(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, authptr);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ authptr += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_S390X_VX_POLY1305
+ if (ctx->use_s390x)
+ {
+ if (length >= 8 * CHACHA20_BLOCK_SIZE &&
+ authoffset >= 8 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 8;
+
+ burn = _gcry_chacha20_poly1305_s390x_vx_blocks8(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, authptr);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ authptr += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+
+ if (length >= CHACHA20_BLOCK_SIZE &&
+ authoffset >= CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+
+ burn = _gcry_chacha20_poly1305_s390x_vx_blocks4_2_1(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, authptr);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ authptr += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+ }
+#endif
+
+ if (authoffset > 0)
+ {
+ _gcry_poly1305_update (&c->u_mode.poly1305.ctx, authptr, authoffset);
+ authptr += authoffset;
+ authoffset = 0;
+ }
+
+ gcry_assert(authptr == outbuf);
+ }
+
+ while (length)
+ {
+ size_t currlen = length;
+
+ /* Since checksumming is done after encryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for checksumming. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ nburn = do_chacha20_encrypt_stream_tail (ctx, outbuf, inbuf, currlen);
+ burn = nburn > burn ? nburn : burn;
+
+ nburn = _gcry_poly1305_update_burn (&c->u_mode.poly1305.ctx, outbuf,
+ currlen);
+ burn = nburn > burn ? nburn : burn;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ length -= currlen;
+ }
+
+ if (burn)
+ _gcry_burn_stack (burn);
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_chacha20_poly1305_decrypt(gcry_cipher_hd_t c, byte *outbuf,
+ const byte *inbuf, size_t length)
+{
+ CHACHA20_context_t *ctx = (void *) &c->context.c;
+ unsigned int nburn, burn = 0;
+
+ if (!length)
+ return 0;
+
+ if (ctx->unused)
+ {
+ unsigned char *p = ctx->pad;
+ size_t n;
+
+ gcry_assert (ctx->unused < CHACHA20_BLOCK_SIZE);
+
+ n = ctx->unused;
+ if (n > length)
+ n = length;
+
+ nburn = _gcry_poly1305_update_burn (&c->u_mode.poly1305.ctx, inbuf, n);
+ burn = nburn > burn ? nburn : burn;
+ buf_xor (outbuf, inbuf, p + CHACHA20_BLOCK_SIZE - ctx->unused, n);
+ length -= n;
+ outbuf += n;
+ inbuf += n;
+ ctx->unused -= n;
+
+ if (!length)
+ {
+ if (burn)
+ _gcry_burn_stack (burn);
+
+ return 0;
+ }
+ gcry_assert (!ctx->unused);
+ }
+
+ gcry_assert (c->u_mode.poly1305.ctx.leftover == 0);
+
+#ifdef USE_AVX2
+ if (ctx->use_avx2 && length >= 8 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 8;
+
+ nburn = _gcry_chacha20_poly1305_amd64_avx2_blocks8(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, inbuf);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_SSSE3
+ if (ctx->use_ssse3)
+ {
+ if (length >= 4 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+
+ nburn = _gcry_chacha20_poly1305_amd64_ssse3_blocks4(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, inbuf);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+
+ if (length >= CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+
+ nburn = _gcry_chacha20_poly1305_amd64_ssse3_blocks1(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, inbuf);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+ }
+#endif
+
+#ifdef USE_AARCH64_SIMD
+ if (ctx->use_neon && length >= 4 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+
+ nburn = _gcry_chacha20_poly1305_aarch64_blocks4(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, inbuf);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_PPC_VEC_POLY1305
+ if (ctx->use_ppc && length >= 4 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 4;
+
+ nburn = _gcry_chacha20_poly1305_ppc8_blocks4(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, inbuf);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+#endif
+
+#ifdef USE_S390X_VX_POLY1305
+ if (ctx->use_s390x)
+ {
+ if (length >= 8 * CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+ nblocks -= nblocks % 8;
+
+ nburn = _gcry_chacha20_poly1305_s390x_vx_blocks8(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, inbuf);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+
+ if (length >= CHACHA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / CHACHA20_BLOCK_SIZE;
+
+ nburn = _gcry_chacha20_poly1305_s390x_vx_blocks4_2_1(
+ ctx->input, outbuf, inbuf, nblocks,
+ &c->u_mode.poly1305.ctx.state, inbuf);
+ burn = nburn > burn ? nburn : burn;
+
+ length -= nblocks * CHACHA20_BLOCK_SIZE;
+ outbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ inbuf += nblocks * CHACHA20_BLOCK_SIZE;
+ }
+ }
+#endif
+
+ while (length)
+ {
+ size_t currlen = length;
+
+ /* Since checksumming is done before decryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for decryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ nburn = _gcry_poly1305_update_burn (&c->u_mode.poly1305.ctx, inbuf,
+ currlen);
+ burn = nburn > burn ? nburn : burn;
+
+ nburn = do_chacha20_encrypt_stream_tail (ctx, outbuf, inbuf, currlen);
+ burn = nburn > burn ? nburn : burn;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ length -= currlen;
+ }
+
+ if (burn)
+ _gcry_burn_stack (burn);
+
+ return 0;
+}
+
+
+static const char *
+selftest (void)
+{
+ byte ctxbuf[sizeof(CHACHA20_context_t) + 15];
+ CHACHA20_context_t *ctx;
+ byte scratch[127 + 1];
+ byte buf[512 + 64 + 4];
+ int i;
+
+ /* From draft-strombergson-chacha-test-vectors */
+ static byte key_1[] = {
+ 0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78,
+ 0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35,
+ 0x1f, 0x68, 0xed, 0x2e, 0x19, 0x4c, 0x79, 0xfb,
+ 0xc6, 0xae, 0xbe, 0xe1, 0xa6, 0x67, 0x97, 0x5d
+ };
+ static const byte nonce_1[] =
+ { 0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21 };
+ static const byte plaintext_1[127] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+ static const byte ciphertext_1[127] = {
+ 0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9,
+ 0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06,
+ 0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00,
+ 0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf,
+ 0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd,
+ 0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f,
+ 0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f,
+ 0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92,
+ 0xe5, 0xfb, 0xc3, 0x4e, 0x60, 0xa1, 0xd9, 0xa9,
+ 0xdb, 0x17, 0x34, 0x5b, 0x0a, 0x40, 0x27, 0x36,
+ 0x85, 0x3b, 0xf9, 0x10, 0xb0, 0x60, 0xbd, 0xf1,
+ 0xf8, 0x97, 0xb6, 0x29, 0x0f, 0x01, 0xd1, 0x38,
+ 0xae, 0x2c, 0x4c, 0x90, 0x22, 0x5b, 0xa9, 0xea,
+ 0x14, 0xd5, 0x18, 0xf5, 0x59, 0x29, 0xde, 0xa0,
+ 0x98, 0xca, 0x7a, 0x6c, 0xcf, 0xe6, 0x12, 0x27,
+ 0x05, 0x3c, 0x84, 0xe4, 0x9a, 0x4a, 0x33
+ };
+
+ /* 16-byte alignment required for amd64 implementation. */
+ ctx = (CHACHA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15);
+
+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL);
+ chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+ scratch[sizeof (scratch) - 1] = 0;
+ chacha20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1);
+ if (memcmp (scratch, ciphertext_1, sizeof ciphertext_1))
+ return "ChaCha20 encryption test 1 failed.";
+ if (scratch[sizeof (scratch) - 1])
+ return "ChaCha20 wrote too much.";
+ chacha20_setkey (ctx, key_1, sizeof (key_1), NULL);
+ chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+ chacha20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1);
+ if (memcmp (scratch, plaintext_1, sizeof plaintext_1))
+ return "ChaCha20 decryption test 1 failed.";
+
+ for (i = 0; i < sizeof buf; i++)
+ buf[i] = i;
+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL);
+ chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+ /*encrypt */
+ chacha20_encrypt_stream (ctx, buf, buf, sizeof buf);
+ /*decrypt */
+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL);
+ chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+ chacha20_encrypt_stream (ctx, buf, buf, 1);
+ chacha20_encrypt_stream (ctx, buf + 1, buf + 1, (sizeof buf) - 1 - 1);
+ chacha20_encrypt_stream (ctx, buf + (sizeof buf) - 1,
+ buf + (sizeof buf) - 1, 1);
+ for (i = 0; i < sizeof buf; i++)
+ if (buf[i] != (byte) i)
+ return "ChaCha20 encryption test 2 failed.";
+
+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL);
+ chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+ /* encrypt */
+ for (i = 0; i < sizeof buf; i++)
+ chacha20_encrypt_stream (ctx, &buf[i], &buf[i], 1);
+ /* decrypt */
+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL);
+ chacha20_setiv (ctx, nonce_1, sizeof nonce_1);
+ chacha20_encrypt_stream (ctx, buf, buf, sizeof buf);
+ for (i = 0; i < sizeof buf; i++)
+ if (buf[i] != (byte) i)
+ return "ChaCha20 encryption test 3 failed.";
+
+ return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_chacha20 = {
+ GCRY_CIPHER_CHACHA20,
+ {0, 0}, /* flags */
+ "CHACHA20", /* name */
+ NULL, /* aliases */
+ NULL, /* oids */
+ 1, /* blocksize in bytes. */
+ CHACHA20_MAX_KEY_SIZE * 8, /* standard key length in bits. */
+ sizeof (CHACHA20_context_t),
+ chacha20_setkey,
+ NULL,
+ NULL,
+ chacha20_encrypt_stream,
+ chacha20_encrypt_stream,
+ NULL,
+ NULL,
+ chacha20_setiv
+};
diff --git a/comm/third_party/libgcrypt/cipher/cipher-aeswrap.c b/comm/third_party/libgcrypt/cipher/cipher-aeswrap.c
new file mode 100644
index 0000000000..c182657e1f
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-aeswrap.c
@@ -0,0 +1,209 @@
+/* cipher-aeswrap.c - Generic AESWRAP mode implementation
+ * Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+/* Perform the AES-Wrap algorithm as specified by RFC3394. We
+ implement this as a mode usable with any cipher algorithm of
+ blocksize 128. */
+gcry_err_code_t
+_gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen )
+{
+ int j, x;
+ size_t n, i;
+ unsigned char *r, *a, *b;
+ unsigned char t[8];
+ unsigned int burn, nburn;
+
+#if MAX_BLOCKSIZE < 8
+#error Invalid block size
+#endif
+ /* We require a cipher with a 128 bit block length. */
+ if (c->spec->blocksize != 16)
+ return GPG_ERR_INV_LENGTH;
+
+ /* The output buffer must be able to hold the input data plus one
+ additional block. */
+ if (outbuflen < inbuflen + 8)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ /* Input data must be multiple of 64 bits. */
+ if (inbuflen % 8)
+ return GPG_ERR_INV_ARG;
+
+ n = inbuflen / 8;
+
+ /* We need at least two 64 bit blocks. */
+ if (n < 2)
+ return GPG_ERR_INV_ARG;
+
+ burn = 0;
+
+ r = outbuf;
+ a = outbuf; /* We store A directly in OUTBUF. */
+ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
+
+ /* Copy the inbuf to the outbuf. */
+ memmove (r+8, inbuf, inbuflen);
+
+ /* If an IV has been set we use that IV as the Alternative Initial
+ Value; if it has not been set we use the standard value. */
+ if (c->marks.iv)
+ memcpy (a, c->u_iv.iv, 8);
+ else
+ memset (a, 0xa6, 8);
+
+ memset (t, 0, sizeof t); /* t := 0. */
+
+ for (j = 0; j <= 5; j++)
+ {
+ for (i = 1; i <= n; i++)
+ {
+ /* B := AES_k( A | R[i] ) */
+ memcpy (b, a, 8);
+ memcpy (b+8, r+i*8, 8);
+ nburn = c->spec->encrypt (&c->context.c, b, b);
+ burn = nburn > burn ? nburn : burn;
+ /* t := t + 1 */
+ for (x = 7; x >= 0; x--)
+ {
+ t[x]++;
+ if (t[x])
+ break;
+ }
+ /* A := MSB_64(B) ^ t */
+ cipher_block_xor(a, b, t, 8);
+ /* R[i] := LSB_64(B) */
+ memcpy (r+i*8, b+8, 8);
+ }
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+/* Perform the AES-Unwrap algorithm as specified by RFC3394. We
+ implement this as a mode usable with any cipher algorithm of
+ blocksize 128. */
+gcry_err_code_t
+_gcry_cipher_aeswrap_decrypt (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ int j, x;
+ size_t n, i;
+ unsigned char *r, *a, *b;
+ unsigned char t[8];
+ unsigned int burn, nburn;
+
+#if MAX_BLOCKSIZE < 8
+#error Invalid block size
+#endif
+ /* We require a cipher with a 128 bit block length. */
+ if (c->spec->blocksize != 16)
+ return GPG_ERR_INV_LENGTH;
+
+ /* The output buffer must be able to hold the input data minus one
+ additional block. Fixme: The caller has more restrictive checks
+ - we may want to fix them for this mode. */
+ if (outbuflen + 8 < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ /* Input data must be multiple of 64 bits. */
+ if (inbuflen % 8)
+ return GPG_ERR_INV_ARG;
+
+ n = inbuflen / 8;
+
+ /* We need at least three 64 bit blocks. */
+ if (n < 3)
+ return GPG_ERR_INV_ARG;
+
+ burn = 0;
+
+ r = outbuf;
+ a = c->lastiv; /* We use c->LASTIV as buffer for A. */
+ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
+
+ /* Copy the inbuf to the outbuf and save A. */
+ memcpy (a, inbuf, 8);
+ memmove (r, inbuf+8, inbuflen-8);
+ n--; /* Reduce to actual number of data blocks. */
+
+ /* t := 6 * n */
+ i = n * 6; /* The range is valid because: n = inbuflen / 8 - 1. */
+ for (x=0; x < 8 && x < sizeof (i); x++)
+ t[7-x] = i >> (8*x);
+ for (; x < 8; x++)
+ t[7-x] = 0;
+
+ for (j = 5; j >= 0; j--)
+ {
+ for (i = n; i >= 1; i--)
+ {
+ /* B := AES_k^1( (A ^ t)| R[i] ) */
+ cipher_block_xor(b, a, t, 8);
+ memcpy (b+8, r+(i-1)*8, 8);
+ nburn = c->spec->decrypt (&c->context.c, b, b);
+ burn = nburn > burn ? nburn : burn;
+ /* t := t - 1 */
+ for (x = 7; x >= 0; x--)
+ {
+ t[x]--;
+ if (t[x] != 0xff)
+ break;
+ }
+ /* A := MSB_64(B) */
+ memcpy (a, b, 8);
+ /* R[i] := LSB_64(B) */
+ memcpy (r+(i-1)*8, b+8, 8);
+ }
+ }
+
+ /* If an IV has been set we compare against this Alternative Initial
+ Value; if it has not been set we compare against the standard IV. */
+ if (c->marks.iv)
+ j = memcmp (a, c->u_iv.iv, 8);
+ else
+ {
+ for (j=0, x=0; x < 8; x++)
+ if (a[x] != 0xa6)
+ {
+ j=1;
+ break;
+ }
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return j? GPG_ERR_CHECKSUM : 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-cbc.c b/comm/third_party/libgcrypt/cipher/cipher-cbc.c
new file mode 100644
index 0000000000..d4df1e72aa
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-cbc.c
@@ -0,0 +1,292 @@
+/* cipher-cbc.c - Generic CBC mode implementation
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "./cipher-internal.h"
+#include "bufhelp.h"
+
+
+
+static inline unsigned int
+cbc_encrypt_inner(gcry_cipher_hd_t c, unsigned char *outbuf,
+ const unsigned char *inbuf, size_t nblocks, size_t blocksize,
+ int is_cbc_cmac)
+{
+
+ unsigned int burn, nburn;
+ size_t n;
+
+ burn = 0;
+
+ if (c->bulk.cbc_enc)
+ {
+ c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
+ is_cbc_cmac);
+ }
+ else
+ {
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ unsigned char *ivp;
+
+ ivp = c->u_iv.iv;
+
+ for (n=0; n < nblocks; n++ )
+ {
+ cipher_block_xor (outbuf, inbuf, ivp, blocksize);
+ nburn = enc_fn ( &c->context.c, outbuf, outbuf );
+ burn = nburn > burn ? nburn : burn;
+ ivp = outbuf;
+ inbuf += blocksize;
+ if (!is_cbc_cmac)
+ outbuf += blocksize;
+ }
+
+ if (ivp != c->u_iv.iv)
+ cipher_block_cpy (c->u_iv.iv, ivp, blocksize);
+ }
+
+ return burn;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ size_t blocksize_mask = blocksize - 1;
+ size_t nblocks = inbuflen >> blocksize_shift;
+ int is_cbc_cmac = !!(c->flags & GCRY_CIPHER_CBC_MAC);
+ unsigned int burn;
+
+ if (outbuflen < (is_cbc_cmac ? blocksize : inbuflen))
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if (inbuflen & blocksize_mask)
+ return GPG_ERR_INV_LENGTH;
+
+ burn = cbc_encrypt_inner(c, outbuf, inbuf, nblocks, blocksize, is_cbc_cmac);
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cbc_cts_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ size_t blocksize_mask = blocksize - 1;
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t nblocks = inbuflen >> blocksize_shift;
+ unsigned int burn, nburn;
+ unsigned char *ivp;
+ int i;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ((inbuflen & blocksize_mask) && !(inbuflen > blocksize))
+ return GPG_ERR_INV_LENGTH;
+
+ burn = 0;
+
+ if (inbuflen > blocksize)
+ {
+ if ((inbuflen & blocksize_mask) == 0)
+ nblocks--;
+ }
+
+ burn = cbc_encrypt_inner(c, outbuf, inbuf, nblocks, blocksize, 0);
+ inbuf += nblocks << blocksize_shift;
+ outbuf += nblocks << blocksize_shift;
+
+ if (inbuflen > blocksize)
+ {
+ /* We have to be careful here, since outbuf might be equal to
+ inbuf. */
+ size_t restbytes;
+ unsigned char b;
+
+ if ((inbuflen & blocksize_mask) == 0)
+ restbytes = blocksize;
+ else
+ restbytes = inbuflen & blocksize_mask;
+
+ outbuf -= blocksize;
+ for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
+ {
+ b = inbuf[i];
+ outbuf[blocksize + i] = outbuf[i];
+ outbuf[i] = b ^ *ivp++;
+ }
+ for (; i < blocksize; i++)
+ outbuf[i] = 0 ^ *ivp++;
+
+ nburn = enc_fn (&c->context.c, outbuf, outbuf);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_cpy (c->u_iv.iv, outbuf, blocksize);
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+
+static inline unsigned int
+cbc_decrypt_inner(gcry_cipher_hd_t c, unsigned char *outbuf,
+ const unsigned char *inbuf, size_t nblocks, size_t blocksize)
+{
+ unsigned int burn, nburn;
+ size_t n;
+
+ burn = 0;
+
+ if (c->bulk.cbc_dec)
+ {
+ c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ }
+ else
+ {
+ gcry_cipher_decrypt_t dec_fn = c->spec->decrypt;
+
+ for (n = 0; n < nblocks; n++)
+ {
+ /* Because outbuf and inbuf might be the same, we must not overwrite
+ the original ciphertext block. We use LASTIV as intermediate
+ storage here because it is not used otherwise. */
+ nburn = dec_fn ( &c->context.c, c->lastiv, inbuf );
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor_n_copy_2 (outbuf, c->lastiv, c->u_iv.iv, inbuf,
+ blocksize);
+ inbuf += blocksize;
+ outbuf += blocksize;
+ }
+ }
+
+ return burn;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ size_t blocksize_mask = blocksize - 1;
+ size_t nblocks = inbuflen >> blocksize_shift;
+ unsigned int burn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if (inbuflen & blocksize_mask)
+ return GPG_ERR_INV_LENGTH;
+
+ burn = cbc_decrypt_inner(c, outbuf, inbuf, nblocks, blocksize);
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cbc_cts_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ size_t blocksize_mask = blocksize - 1;
+ gcry_cipher_decrypt_t dec_fn = c->spec->decrypt;
+ size_t nblocks = inbuflen >> blocksize_shift;
+ unsigned int burn, nburn;
+ int i;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ((inbuflen & blocksize_mask) && !(inbuflen > blocksize))
+ return GPG_ERR_INV_LENGTH;
+
+ burn = 0;
+
+ if (inbuflen > blocksize)
+ {
+ nblocks--;
+ if ((inbuflen & blocksize_mask) == 0)
+ nblocks--;
+ cipher_block_cpy (c->lastiv, c->u_iv.iv, blocksize);
+ }
+
+ burn = cbc_decrypt_inner(c, outbuf, inbuf, nblocks, blocksize);
+ inbuf += nblocks << blocksize_shift;
+ outbuf += nblocks << blocksize_shift;
+
+ if (inbuflen > blocksize)
+ {
+ size_t restbytes;
+
+ if ((inbuflen & blocksize_mask) == 0)
+ restbytes = blocksize;
+ else
+ restbytes = inbuflen & blocksize_mask;
+
+ cipher_block_cpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */
+ buf_cpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
+
+ nburn = dec_fn ( &c->context.c, outbuf, inbuf );
+ burn = nburn > burn ? nburn : burn;
+ buf_xor(outbuf, outbuf, c->u_iv.iv, restbytes);
+
+ buf_cpy (outbuf + blocksize, outbuf, restbytes);
+ for(i=restbytes; i < blocksize; i++)
+ c->u_iv.iv[i] = outbuf[i];
+ nburn = dec_fn (&c->context.c, outbuf, c->u_iv.iv);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor(outbuf, outbuf, c->lastiv, blocksize);
+ /* c->lastiv is now really lastlastiv, does this matter? */
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-ccm.c b/comm/third_party/libgcrypt/cipher/cipher-ccm.c
new file mode 100644
index 0000000000..dcb268d084
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-ccm.c
@@ -0,0 +1,415 @@
+/* cipher-ccm.c - CTR mode with CBC-MAC mode implementation
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+#define set_burn(burn, nburn) do { \
+ unsigned int __nburn = (nburn); \
+ (burn) = (burn) > __nburn ? (burn) : __nburn; } while (0)
+
+
+static unsigned int
+do_cbc_mac (gcry_cipher_hd_t c, const unsigned char *inbuf, size_t inlen,
+ int do_padding)
+{
+ const unsigned int blocksize = 16;
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ unsigned char tmp[blocksize];
+ unsigned int burn = 0;
+ unsigned int unused = c->u_mode.ccm.mac_unused;
+ size_t nblocks;
+ size_t n;
+
+ if (inlen == 0 && (unused == 0 || !do_padding))
+ return 0;
+
+ do
+ {
+ if (inlen + unused < blocksize || unused > 0)
+ {
+ n = (inlen > blocksize - unused) ? blocksize - unused : inlen;
+
+ buf_cpy (&c->u_mode.ccm.macbuf[unused], inbuf, n);
+ unused += n;
+ inlen -= n;
+ inbuf += n;
+ }
+ if (!inlen)
+ {
+ if (!do_padding)
+ break;
+
+ n = blocksize - unused;
+ if (n > 0)
+ {
+ memset (&c->u_mode.ccm.macbuf[unused], 0, n);
+ unused = blocksize;
+ }
+ }
+
+ if (unused > 0)
+ {
+ /* Process one block from macbuf. */
+ cipher_block_xor(c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.macbuf,
+ blocksize);
+ set_burn (burn, enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ));
+
+ unused = 0;
+ }
+
+ if (c->bulk.cbc_enc)
+ {
+ nblocks = inlen / blocksize;
+ c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, tmp, inbuf, nblocks, 1);
+ inbuf += nblocks * blocksize;
+ inlen -= nblocks * blocksize;
+
+ wipememory (tmp, sizeof(tmp));
+ }
+ else
+ {
+ while (inlen >= blocksize)
+ {
+ cipher_block_xor(c->u_iv.iv, c->u_iv.iv, inbuf, blocksize);
+
+ set_burn (burn, enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ));
+
+ inlen -= blocksize;
+ inbuf += blocksize;
+ }
+ }
+ }
+ while (inlen > 0);
+
+ c->u_mode.ccm.mac_unused = unused;
+
+ if (burn)
+ burn += 4 * sizeof(void *);
+
+ return burn;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_set_nonce (gcry_cipher_hd_t c, const unsigned char *nonce,
+ size_t noncelen)
+{
+ unsigned int marks_key;
+ size_t L = 15 - noncelen;
+ size_t L_;
+
+ L_ = L - 1;
+
+ if (!nonce)
+ return GPG_ERR_INV_ARG;
+ /* Length field must be 2, 3, ..., or 8. */
+ if (L < 2 || L > 8)
+ return GPG_ERR_INV_LENGTH;
+
+ /* Reset state */
+ marks_key = c->marks.key;
+ memset (&c->u_mode, 0, sizeof(c->u_mode));
+ memset (&c->marks, 0, sizeof(c->marks));
+ memset (&c->u_iv, 0, sizeof(c->u_iv));
+ memset (&c->u_ctr, 0, sizeof(c->u_ctr));
+ memset (c->lastiv, 0, sizeof(c->lastiv));
+ c->unused = 0;
+ c->marks.key = marks_key;
+
+ /* Setup CTR */
+ c->u_ctr.ctr[0] = L_;
+ memcpy (&c->u_ctr.ctr[1], nonce, noncelen);
+ memset (&c->u_ctr.ctr[1 + noncelen], 0, L);
+
+ /* Setup IV */
+ c->u_iv.iv[0] = L_;
+ memcpy (&c->u_iv.iv[1], nonce, noncelen);
+ /* Add (8 * M_ + 64 * flags) to iv[0] and set iv[noncelen + 1 ... 15] later
+ in set_aad. */
+ memset (&c->u_iv.iv[1 + noncelen], 0, L);
+
+ c->u_mode.ccm.nonce = 1;
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_set_lengths (gcry_cipher_hd_t c, u64 encryptlen, u64 aadlen,
+ u64 taglen)
+{
+ unsigned int burn = 0;
+ unsigned char b0[16];
+ size_t noncelen = 15 - (c->u_iv.iv[0] + 1);
+ u64 M = taglen;
+ u64 M_;
+ int i;
+
+ M_ = (M - 2) / 2;
+
+ /* Authentication field must be 4, 6, 8, 10, 12, 14 or 16. */
+ if ((M_ * 2 + 2) != M || M < 4 || M > 16)
+ return GPG_ERR_INV_LENGTH;
+ if (!c->u_mode.ccm.nonce || c->marks.tag)
+ return GPG_ERR_INV_STATE;
+ if (c->u_mode.ccm.lengths)
+ return GPG_ERR_INV_STATE;
+
+ c->u_mode.ccm.authlen = taglen;
+ c->u_mode.ccm.encryptlen = encryptlen;
+ c->u_mode.ccm.aadlen = aadlen;
+
+ /* Complete IV setup. */
+ c->u_iv.iv[0] += (aadlen > 0) * 64 + M_ * 8;
+ for (i = 16 - 1; i >= 1 + noncelen; i--)
+ {
+ c->u_iv.iv[i] = encryptlen & 0xff;
+ encryptlen >>= 8;
+ }
+
+ memcpy (b0, c->u_iv.iv, 16);
+ memset (c->u_iv.iv, 0, 16);
+
+ set_burn (burn, do_cbc_mac (c, b0, 16, 0));
+
+ if (aadlen == 0)
+ {
+ /* Do nothing. */
+ }
+ else if (aadlen > 0 && aadlen <= (unsigned int)0xfeff)
+ {
+ b0[0] = (aadlen >> 8) & 0xff;
+ b0[1] = aadlen & 0xff;
+ set_burn (burn, do_cbc_mac (c, b0, 2, 0));
+ }
+ else if (aadlen > 0xfeff && aadlen <= (unsigned int)0xffffffff)
+ {
+ b0[0] = 0xff;
+ b0[1] = 0xfe;
+ buf_put_be32(&b0[2], aadlen);
+ set_burn (burn, do_cbc_mac (c, b0, 6, 0));
+ }
+ else if (aadlen > (unsigned int)0xffffffff)
+ {
+ b0[0] = 0xff;
+ b0[1] = 0xff;
+ buf_put_be64(&b0[2], aadlen);
+ set_burn (burn, do_cbc_mac (c, b0, 10, 0));
+ }
+
+ /* Generate S_0 and increase counter. */
+ set_burn (burn, c->spec->encrypt ( &c->context.c, c->u_mode.ccm.s0,
+ c->u_ctr.ctr ));
+ c->u_ctr.ctr[15]++;
+
+ if (burn)
+ _gcry_burn_stack (burn + sizeof(void *) * 5);
+
+ c->u_mode.ccm.lengths = 1;
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
+ size_t abuflen)
+{
+ unsigned int burn;
+
+ if (abuflen > 0 && !abuf)
+ return GPG_ERR_INV_ARG;
+ if (!c->u_mode.ccm.nonce || !c->u_mode.ccm.lengths || c->marks.tag)
+ return GPG_ERR_INV_STATE;
+ if (abuflen > c->u_mode.ccm.aadlen)
+ return GPG_ERR_INV_LENGTH;
+
+ c->u_mode.ccm.aadlen -= abuflen;
+ burn = do_cbc_mac (c, abuf, abuflen, c->u_mode.ccm.aadlen == 0);
+
+ if (burn)
+ _gcry_burn_stack (burn + sizeof(void *) * 5);
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_tag (gcry_cipher_hd_t c, unsigned char *outbuf,
+ size_t outbuflen, int check)
+{
+ unsigned int burn;
+
+ if (!outbuf || outbuflen == 0)
+ return GPG_ERR_INV_ARG;
+ /* Tag length must be same as initial authlen. */
+ if (c->u_mode.ccm.authlen != outbuflen)
+ return GPG_ERR_INV_LENGTH;
+ if (!c->u_mode.ccm.nonce || !c->u_mode.ccm.lengths || c->u_mode.ccm.aadlen > 0)
+ return GPG_ERR_INV_STATE;
+ /* Initial encrypt length must match with length of actual data processed. */
+ if (c->u_mode.ccm.encryptlen > 0)
+ return GPG_ERR_UNFINISHED;
+
+ if (!c->marks.tag)
+ {
+ burn = do_cbc_mac (c, NULL, 0, 1); /* Perform final padding. */
+
+ /* Add S_0 */
+ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.s0, 16);
+
+ wipememory (c->u_ctr.ctr, 16);
+ wipememory (c->u_mode.ccm.s0, 16);
+ wipememory (c->u_mode.ccm.macbuf, 16);
+
+ if (burn)
+ _gcry_burn_stack (burn + sizeof(void *) * 5);
+
+ c->marks.tag = 1;
+ }
+
+ if (!check)
+ {
+ memcpy (outbuf, c->u_iv.iv, outbuflen);
+ return GPG_ERR_NO_ERROR;
+ }
+ else
+ {
+ return buf_eq_const(outbuf, c->u_iv.iv, outbuflen) ?
+ GPG_ERR_NO_ERROR : GPG_ERR_CHECKSUM;
+ }
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_get_tag (gcry_cipher_hd_t c, unsigned char *outtag,
+ size_t taglen)
+{
+ return _gcry_cipher_ccm_tag (c, outtag, taglen, 0);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+ size_t taglen)
+{
+ return _gcry_cipher_ccm_tag (c, (unsigned char *)intag, taglen, 1);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
+ size_t outbuflen, const unsigned char *inbuf,
+ size_t inbuflen)
+{
+ gcry_err_code_t err = 0;
+ unsigned int burn = 0;
+ unsigned int nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (!c->u_mode.ccm.nonce || c->marks.tag || !c->u_mode.ccm.lengths ||
+ c->u_mode.ccm.aadlen > 0)
+ return GPG_ERR_INV_STATE;
+ if (inbuflen > c->u_mode.ccm.encryptlen)
+ return GPG_ERR_INV_LENGTH;
+
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done before encryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for encryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ c->u_mode.ccm.encryptlen -= currlen;
+ nburn = do_cbc_mac (c, inbuf, currlen, 0);
+ burn = nburn > burn ? nburn : burn;
+
+ err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, currlen);
+ if (err)
+ break;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ if (burn)
+ _gcry_burn_stack (burn + sizeof(void *) * 5);
+ return err;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
+ size_t outbuflen, const unsigned char *inbuf,
+ size_t inbuflen)
+{
+ gcry_err_code_t err = 0;
+ unsigned int burn = 0;
+ unsigned int nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (!c->u_mode.ccm.nonce || c->marks.tag || !c->u_mode.ccm.lengths ||
+ c->u_mode.ccm.aadlen > 0)
+ return GPG_ERR_INV_STATE;
+ if (inbuflen > c->u_mode.ccm.encryptlen)
+ return GPG_ERR_INV_LENGTH;
+
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done after decryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for checksumming. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, currlen);
+ if (err)
+ break;
+
+ c->u_mode.ccm.encryptlen -= currlen;
+ nburn = do_cbc_mac (c, outbuf, currlen, 0);
+ burn = nburn > burn ? nburn : burn;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ if (burn)
+ _gcry_burn_stack (burn + sizeof(void *) * 5);
+ return err;
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-cfb.c b/comm/third_party/libgcrypt/cipher/cipher-cfb.c
new file mode 100644
index 0000000000..012c6c13c3
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-cfb.c
@@ -0,0 +1,317 @@
+/* cipher-cfb.c - Generic CFB mode implementation
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+gcry_err_code_t
+_gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ unsigned char *ivp;
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ size_t blocksize_x_2 = blocksize + blocksize;
+ unsigned int burn, nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ( inbuflen <= c->unused )
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ /* XOR the input with the IV and store input into IV. */
+ ivp = c->u_iv.iv + blocksize - c->unused;
+ buf_xor_2dst(outbuf, ivp, inbuf, inbuflen);
+ c->unused -= inbuflen;
+ return 0;
+ }
+
+ burn = 0;
+
+ if ( c->unused )
+ {
+ /* XOR the input with the IV and store input into IV */
+ inbuflen -= c->unused;
+ ivp = c->u_iv.iv + blocksize - c->unused;
+ buf_xor_2dst(outbuf, ivp, inbuf, c->unused);
+ outbuf += c->unused;
+ inbuf += c->unused;
+ c->unused = 0;
+ }
+
+ /* Now we can process complete blocks. We use a loop as long as we
+ have at least 2 blocks and use conditions for the rest. This
+ also allows to use a bulk encryption function if available. */
+ if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc)
+ {
+ size_t nblocks = inbuflen >> blocksize_shift;
+ c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ outbuf += nblocks << blocksize_shift;
+ inbuf += nblocks << blocksize_shift;
+ inbuflen -= nblocks << blocksize_shift;
+ }
+ else
+ {
+ while ( inbuflen >= blocksize_x_2 )
+ {
+ /* Encrypt the IV. */
+ nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+ /* XOR the input with the IV and store input into IV. */
+ cipher_block_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize);
+ outbuf += blocksize;
+ inbuf += blocksize;
+ inbuflen -= blocksize;
+ }
+ }
+
+ if ( inbuflen >= blocksize )
+ {
+ /* Save the current IV and then encrypt the IV. */
+ cipher_block_cpy( c->lastiv, c->u_iv.iv, blocksize );
+ nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+ /* XOR the input with the IV and store input into IV */
+ cipher_block_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize);
+ outbuf += blocksize;
+ inbuf += blocksize;
+ inbuflen -= blocksize;
+ }
+ if ( inbuflen )
+ {
+ /* Save the current IV and then encrypt the IV. */
+ cipher_block_cpy( c->lastiv, c->u_iv.iv, blocksize );
+ nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+ c->unused = blocksize;
+ /* Apply the XOR. */
+ c->unused -= inbuflen;
+ buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, inbuflen);
+ outbuf += inbuflen;
+ inbuf += inbuflen;
+ inbuflen = 0;
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ unsigned char *ivp;
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ size_t blocksize_x_2 = blocksize + blocksize;
+ unsigned int burn, nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if (inbuflen <= c->unused)
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ /* XOR the input with the IV and store input into IV. */
+ ivp = c->u_iv.iv + blocksize - c->unused;
+ buf_xor_n_copy(outbuf, ivp, inbuf, inbuflen);
+ c->unused -= inbuflen;
+ return 0;
+ }
+
+ burn = 0;
+
+ if (c->unused)
+ {
+ /* XOR the input with the IV and store input into IV. */
+ inbuflen -= c->unused;
+ ivp = c->u_iv.iv + blocksize - c->unused;
+ buf_xor_n_copy(outbuf, ivp, inbuf, c->unused);
+ outbuf += c->unused;
+ inbuf += c->unused;
+ c->unused = 0;
+ }
+
+ /* Now we can process complete blocks. We use a loop as long as we
+ have at least 2 blocks and use conditions for the rest. This
+ also allows to use a bulk encryption function if available. */
+ if (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec)
+ {
+ size_t nblocks = inbuflen >> blocksize_shift;
+ c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ outbuf += nblocks << blocksize_shift;
+ inbuf += nblocks << blocksize_shift;
+ inbuflen -= nblocks << blocksize_shift;
+ }
+ else
+ {
+ while (inbuflen >= blocksize_x_2 )
+ {
+ /* Encrypt the IV. */
+ nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+ /* XOR the input with the IV and store input into IV. */
+ cipher_block_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize);
+ outbuf += blocksize;
+ inbuf += blocksize;
+ inbuflen -= blocksize;
+ }
+ }
+
+ if (inbuflen >= blocksize )
+ {
+ /* Save the current IV and then encrypt the IV. */
+ cipher_block_cpy ( c->lastiv, c->u_iv.iv, blocksize);
+ nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+ /* XOR the input with the IV and store input into IV */
+ cipher_block_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize);
+ outbuf += blocksize;
+ inbuf += blocksize;
+ inbuflen -= blocksize;
+ }
+
+ if (inbuflen)
+ {
+ /* Save the current IV and then encrypt the IV. */
+ cipher_block_cpy ( c->lastiv, c->u_iv.iv, blocksize );
+ nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+ c->unused = blocksize;
+ /* Apply the XOR. */
+ c->unused -= inbuflen;
+ buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, inbuflen);
+ outbuf += inbuflen;
+ inbuf += inbuflen;
+ inbuflen = 0;
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cfb8_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize = c->spec->blocksize;
+ unsigned int burn, nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ burn = 0;
+
+ while ( inbuflen > 0)
+ {
+ int i;
+
+ /* Encrypt the IV. */
+ nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+
+ outbuf[0] = c->lastiv[0] ^ inbuf[0];
+
+ /* Bitshift iv by 8 bit to the left */
+ for (i = 0; i < blocksize-1; i++)
+ c->u_iv.iv[i] = c->u_iv.iv[i+1];
+
+ /* append cipher text to iv */
+ c->u_iv.iv[blocksize-1] = outbuf[0];
+
+ outbuf += 1;
+ inbuf += 1;
+ inbuflen -= 1;
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cfb8_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize = c->spec->blocksize;
+ unsigned int burn, nburn;
+ unsigned char appendee;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ burn = 0;
+
+ while (inbuflen > 0)
+ {
+ int i;
+
+ /* Encrypt the IV. */
+ nburn = enc_fn ( &c->context.c, c->lastiv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+
+ /* inbuf might == outbuf, make sure we keep the value
+ so we can append it later */
+ appendee = inbuf[0];
+
+ outbuf[0] = inbuf[0] ^ c->lastiv[0];
+
+ /* Bitshift iv by 8 bit to the left */
+ for (i = 0; i < blocksize-1; i++)
+ c->u_iv.iv[i] = c->u_iv.iv[i+1];
+
+ c->u_iv.iv[blocksize-1] = appendee;
+
+ outbuf += 1;
+ inbuf += 1;
+ inbuflen -= 1;
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-cmac.c b/comm/third_party/libgcrypt/cipher/cipher-cmac.c
new file mode 100644
index 0000000000..4efd1e19b4
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-cmac.c
@@ -0,0 +1,292 @@
+/* cmac.c - CMAC, Cipher-based MAC.
+ * Copyright (C) 2013,2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "cipher-internal.h"
+#include "bufhelp.h"
+
+
+#define set_burn(burn, nburn) do { \
+ unsigned int __nburn = (nburn); \
+ (burn) = (burn) > __nburn ? (burn) : __nburn; } while (0)
+
+
+gcry_err_code_t
+_gcry_cmac_write (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx,
+ const byte * inbuf, size_t inlen)
+{
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ byte outbuf[MAX_BLOCKSIZE];
+ unsigned int burn = 0;
+ unsigned int nblocks;
+ size_t n;
+
+ if (ctx->tag)
+ return GPG_ERR_INV_STATE;
+
+ if (!inbuf)
+ return GPG_ERR_INV_ARG;
+
+ if (inlen == 0)
+ return 0;
+
+ /* Last block is needed for cmac_final. */
+ if (ctx->mac_unused + inlen <= blocksize)
+ {
+ buf_cpy (&ctx->macbuf[ctx->mac_unused], inbuf, inlen);
+ ctx->mac_unused += inlen;
+ inbuf += inlen;
+ inlen -= inlen;
+
+ return 0;
+ }
+
+ if (ctx->mac_unused)
+ {
+ n = inlen;
+ if (n > blocksize - ctx->mac_unused)
+ n = blocksize - ctx->mac_unused;
+
+ buf_cpy (&ctx->macbuf[ctx->mac_unused], inbuf, n);
+ ctx->mac_unused += n;
+ inbuf += n;
+ inlen -= n;
+
+ cipher_block_xor (ctx->u_iv.iv, ctx->u_iv.iv, ctx->macbuf, blocksize);
+ set_burn (burn, enc_fn (&c->context.c, ctx->u_iv.iv, ctx->u_iv.iv));
+
+ ctx->mac_unused = 0;
+ }
+
+ if (c->bulk.cbc_enc && inlen > blocksize)
+ {
+ nblocks = inlen >> blocksize_shift;
+ nblocks -= ((nblocks << blocksize_shift) == inlen);
+
+ c->bulk.cbc_enc (&c->context.c, ctx->u_iv.iv, outbuf, inbuf, nblocks, 1);
+ inbuf += nblocks << blocksize_shift;
+ inlen -= nblocks << blocksize_shift;
+
+ wipememory (outbuf, sizeof (outbuf));
+ }
+ else
+ while (inlen > blocksize)
+ {
+ cipher_block_xor (ctx->u_iv.iv, ctx->u_iv.iv, inbuf, blocksize);
+ set_burn (burn, enc_fn (&c->context.c, ctx->u_iv.iv, ctx->u_iv.iv));
+ inlen -= blocksize;
+ inbuf += blocksize;
+ }
+
+ /* Make sure that last block is passed to cmac_final. */
+ if (inlen == 0)
+ BUG ();
+
+ n = inlen;
+ if (n > blocksize - ctx->mac_unused)
+ n = blocksize - ctx->mac_unused;
+
+ buf_cpy (&ctx->macbuf[ctx->mac_unused], inbuf, n);
+ ctx->mac_unused += n;
+ inbuf += n;
+ inlen -= n;
+
+ if (burn)
+ _gcry_burn_stack (burn + 4 * sizeof (void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cmac_generate_subkeys (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx)
+{
+ const unsigned int blocksize = c->spec->blocksize;
+ byte rb, carry, t, bi;
+ unsigned int burn;
+ int i, j;
+ union
+ {
+ size_t _aligned;
+ byte buf[MAX_BLOCKSIZE];
+ } u;
+
+ /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+ * length, to allow better optimization of this function. */
+ if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+ return GPG_ERR_INV_CIPHER_MODE;
+
+ if (MAX_BLOCKSIZE < blocksize)
+ BUG ();
+
+ /* encrypt zero block */
+ memset (u.buf, 0, blocksize);
+ burn = c->spec->encrypt (&c->context.c, u.buf, u.buf);
+
+ /* Currently supported blocksizes are 16 and 8. */
+ rb = blocksize == 16 ? 0x87 : 0x1B /* blocksize == 8 */ ;
+
+ for (j = 0; j < 2; j++)
+ {
+ /* Generate subkeys K1 and K2 */
+ carry = 0;
+ for (i = blocksize - 1; i >= 0; i--)
+ {
+ bi = u.buf[i];
+ t = carry | (bi << 1);
+ carry = bi >> 7;
+ u.buf[i] = t & 0xff;
+ ctx->subkeys[j][i] = u.buf[i];
+ }
+ u.buf[blocksize - 1] ^= carry ? rb : 0;
+ ctx->subkeys[j][blocksize - 1] = u.buf[blocksize - 1];
+ }
+
+ wipememory (&u, sizeof (u));
+ if (burn)
+ _gcry_burn_stack (burn + 4 * sizeof (void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cmac_final (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx)
+{
+ const unsigned int blocksize = c->spec->blocksize;
+ unsigned int count = ctx->mac_unused;
+ unsigned int burn;
+ byte *subkey;
+
+ /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+ * length, to allow better optimization of this function. */
+ if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+ return GPG_ERR_INV_CIPHER_MODE;
+
+ if (count == blocksize)
+ subkey = ctx->subkeys[0]; /* K1 */
+ else
+ {
+ subkey = ctx->subkeys[1]; /* K2 */
+ ctx->macbuf[count++] = 0x80;
+ while (count < blocksize)
+ ctx->macbuf[count++] = 0;
+ }
+
+ cipher_block_xor (ctx->macbuf, ctx->macbuf, subkey, blocksize);
+
+ cipher_block_xor (ctx->u_iv.iv, ctx->u_iv.iv, ctx->macbuf, blocksize);
+ burn = c->spec->encrypt (&c->context.c, ctx->u_iv.iv, ctx->u_iv.iv);
+ if (burn)
+ _gcry_burn_stack (burn + 4 * sizeof (void *));
+
+ ctx->mac_unused = 0;
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+cmac_tag (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx,
+ unsigned char *tag, size_t taglen, int check)
+{
+ gcry_err_code_t ret;
+
+ if (!tag || taglen == 0 || taglen > c->spec->blocksize)
+ return GPG_ERR_INV_ARG;
+
+ if (!ctx->tag)
+ {
+ ret = _gcry_cmac_final (c, ctx);
+ if (ret != 0)
+ return ret;
+
+ ctx->tag = 1;
+ }
+
+ if (!check)
+ {
+ memcpy (tag, ctx->u_iv.iv, taglen);
+ return GPG_ERR_NO_ERROR;
+ }
+ else
+ {
+ return buf_eq_const (tag, ctx->u_iv.iv, taglen) ?
+ GPG_ERR_NO_ERROR : GPG_ERR_CHECKSUM;
+ }
+}
+
+
+void
+_gcry_cmac_reset (gcry_cmac_context_t *ctx)
+{
+ char tmp_buf[sizeof(ctx->subkeys)];
+
+ /* Only keep subkeys when reseting context. */
+
+ buf_cpy (tmp_buf, ctx->subkeys, sizeof(ctx->subkeys));
+ memset (ctx, 0, sizeof(*ctx));
+ buf_cpy (ctx->subkeys, tmp_buf, sizeof(ctx->subkeys));
+ wipememory (tmp_buf, sizeof(tmp_buf));
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cmac_authenticate (gcry_cipher_hd_t c,
+ const unsigned char *abuf, size_t abuflen)
+{
+ if (abuflen > 0 && !abuf)
+ return GPG_ERR_INV_ARG;
+ /* To support new blocksize, update cmac_generate_subkeys() then add new
+ blocksize here. */
+ if (c->spec->blocksize != 16 && c->spec->blocksize != 8)
+ return GPG_ERR_INV_CIPHER_MODE;
+
+ return _gcry_cmac_write (c, &c->u_mode.cmac, abuf, abuflen);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cmac_get_tag (gcry_cipher_hd_t c,
+ unsigned char *outtag, size_t taglen)
+{
+ return cmac_tag (c, &c->u_mode.cmac, outtag, taglen, 0);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cmac_check_tag (gcry_cipher_hd_t c,
+ const unsigned char *intag, size_t taglen)
+{
+ return cmac_tag (c, &c->u_mode.cmac, (unsigned char *) intag, taglen, 1);
+}
+
+gcry_err_code_t
+_gcry_cipher_cmac_set_subkeys (gcry_cipher_hd_t c)
+{
+ return _gcry_cmac_generate_subkeys (c, &c->u_mode.cmac);
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-ctr.c b/comm/third_party/libgcrypt/cipher/cipher-ctr.c
new file mode 100644
index 0000000000..5f0afc2f88
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-ctr.c
@@ -0,0 +1,120 @@
+/* cipher-ctr.c - Generic CTR mode implementation
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+gcry_err_code_t
+_gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ size_t n;
+ int i;
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ size_t nblocks;
+ unsigned int burn, nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ burn = 0;
+
+ /* First process a left over encrypted counter. */
+ if (c->unused)
+ {
+ gcry_assert (c->unused < blocksize);
+ i = blocksize - c->unused;
+ n = c->unused > inbuflen ? inbuflen : c->unused;
+ buf_xor(outbuf, inbuf, &c->lastiv[i], n);
+ c->unused -= n;
+ inbuf += n;
+ outbuf += n;
+ inbuflen -= n;
+ }
+
+ /* Use a bulk method if available. */
+ nblocks = inbuflen >> blocksize_shift;
+ if (nblocks && c->bulk.ctr_enc)
+ {
+ c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
+ inbuf += nblocks << blocksize_shift;
+ outbuf += nblocks << blocksize_shift;
+ inbuflen -= nblocks << blocksize_shift;
+ }
+
+ /* If we don't have a bulk method use the standard method. We also
+ use this method for the a remaining partial block. */
+ if (inbuflen)
+ {
+ unsigned char tmp[MAX_BLOCKSIZE];
+
+ n = blocksize;
+ do
+ {
+ nburn = enc_fn (&c->context.c, tmp, c->u_ctr.ctr);
+ burn = nburn > burn ? nburn : burn;
+
+ cipher_block_add(c->u_ctr.ctr, 1, blocksize);
+
+ if (inbuflen < blocksize)
+ break;
+ cipher_block_xor(outbuf, inbuf, tmp, blocksize);
+
+ inbuflen -= n;
+ outbuf += n;
+ inbuf += n;
+ }
+ while (inbuflen);
+
+ if (inbuflen)
+ {
+ n = inbuflen;
+ buf_xor(outbuf, inbuf, tmp, inbuflen);
+
+ inbuflen -= n;
+ outbuf += n;
+ inbuf += n;
+ }
+
+ /* Save the unused bytes of the counter. */
+ c->unused = blocksize - n;
+ if (c->unused)
+ buf_cpy (c->lastiv+n, tmp+n, c->unused);
+
+ wipememory (tmp, sizeof tmp);
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-eax.c b/comm/third_party/libgcrypt/cipher/cipher-eax.c
new file mode 100644
index 0000000000..08f815a9e4
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-eax.c
@@ -0,0 +1,289 @@
+/* cipher-eax.c - EAX implementation
+ * Copyright (C) 2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+gcry_err_code_t
+_gcry_cipher_eax_encrypt (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ gcry_err_code_t err;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (c->marks.tag)
+ return GPG_ERR_INV_STATE;
+
+ if (!c->marks.iv)
+ {
+ err = _gcry_cipher_eax_set_nonce (c, NULL, 0);
+ if (err != 0)
+ return err;
+ }
+
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done after encryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for checksumming. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, currlen);
+ if (err != 0)
+ return err;
+
+ err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, outbuf,
+ currlen);
+ if (err != 0)
+ return err;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_eax_decrypt (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ gcry_err_code_t err;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (c->marks.tag)
+ return GPG_ERR_INV_STATE;
+
+ if (!c->marks.iv)
+ {
+ err = _gcry_cipher_eax_set_nonce (c, NULL, 0);
+ if (err != 0)
+ return err;
+ }
+
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done before decryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for decryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, inbuf,
+ currlen);
+ if (err != 0)
+ return err;
+
+ err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, currlen);
+ if (err != 0)
+ return err;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_eax_authenticate (gcry_cipher_hd_t c,
+ const byte * aadbuf, size_t aadbuflen)
+{
+ gcry_err_code_t err;
+
+ if (c->marks.tag)
+ return GPG_ERR_INV_STATE;
+
+ if (!c->marks.iv)
+ {
+ err = _gcry_cipher_eax_set_nonce (c, NULL, 0);
+ if (err != 0)
+ return err;
+ }
+
+ return _gcry_cmac_write (c, &c->u_mode.eax.cmac_header, aadbuf, aadbuflen);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_eax_setkey (gcry_cipher_hd_t c)
+{
+ gcry_err_code_t err;
+
+ err = _gcry_cmac_generate_subkeys (c, &c->u_mode.eax.cmac_header);
+ if (err != 0)
+ return err;
+
+ buf_cpy (c->u_mode.eax.cmac_ciphertext.subkeys,
+ c->u_mode.eax.cmac_header.subkeys,
+ sizeof(c->u_mode.eax.cmac_header.subkeys));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_eax_set_nonce (gcry_cipher_hd_t c, const byte *nonce,
+ size_t noncelen)
+{
+ gcry_cmac_context_t nonce_cmac;
+ unsigned char initbuf[MAX_BLOCKSIZE];
+ gcry_err_code_t err;
+
+ c->marks.iv = 0;
+ c->marks.tag = 0;
+
+ _gcry_cmac_reset (&c->u_mode.eax.cmac_header);
+ _gcry_cmac_reset (&c->u_mode.eax.cmac_ciphertext);
+
+ /* Calculate nonce CMAC */
+
+ memset(&nonce_cmac, 0, sizeof(nonce_cmac));
+ memset(&initbuf, 0, sizeof(initbuf));
+
+ buf_cpy (&nonce_cmac.subkeys, c->u_mode.eax.cmac_header.subkeys,
+ sizeof(c->u_mode.eax.cmac_header.subkeys));
+
+ err = _gcry_cmac_write (c, &nonce_cmac, initbuf, c->spec->blocksize);
+ if (err != 0)
+ return err;
+
+ if (noncelen != 0)
+ {
+ err = _gcry_cmac_write (c, &nonce_cmac, nonce, noncelen);
+ if (err != 0)
+ return err;
+ }
+
+ err = _gcry_cmac_final (c, &nonce_cmac);
+ if (err != 0)
+ return err;
+
+ cipher_block_cpy (c->u_iv.iv, nonce_cmac.u_iv.iv, MAX_BLOCKSIZE);
+ cipher_block_cpy (c->u_ctr.ctr, nonce_cmac.u_iv.iv, MAX_BLOCKSIZE);
+
+ wipememory (&nonce_cmac, sizeof(nonce_cmac));
+
+ /* Prepare header CMAC */
+
+ initbuf[c->spec->blocksize - 1] = 1;
+ err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_header, initbuf,
+ c->spec->blocksize);
+ if (err != 0)
+ return err;
+
+ /* Prepare ciphertext CMAC */
+
+ initbuf[c->spec->blocksize - 1] = 2;
+ err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, initbuf,
+ c->spec->blocksize);
+ if (err != 0)
+ return err;
+
+ c->marks.iv = 1;
+ c->marks.tag = 0;
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+_gcry_cipher_eax_tag (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen, int check)
+{
+ gcry_err_code_t err;
+
+ if (!c->marks.tag)
+ {
+ err = _gcry_cmac_final (c, &c->u_mode.eax.cmac_header);
+ if (err != 0)
+ return err;
+
+ err = _gcry_cmac_final (c, &c->u_mode.eax.cmac_ciphertext);
+ if (err != 0)
+ return err;
+
+ cipher_block_xor_1 (c->u_iv.iv, c->u_mode.eax.cmac_header.u_iv.iv,
+ MAX_BLOCKSIZE);
+ cipher_block_xor_1 (c->u_iv.iv, c->u_mode.eax.cmac_ciphertext.u_iv.iv,
+ MAX_BLOCKSIZE);
+
+ _gcry_cmac_reset (&c->u_mode.eax.cmac_header);
+ _gcry_cmac_reset (&c->u_mode.eax.cmac_ciphertext);
+
+ c->marks.tag = 1;
+ }
+
+ if (!check)
+ {
+ if (outbuflen > c->spec->blocksize)
+ outbuflen = c->spec->blocksize;
+
+ /* NB: We already checked that OUTBUF is large enough to hold
+ * the result or has valid truncated length. */
+ memcpy (outbuf, c->u_iv.iv, outbuflen);
+ }
+ else
+ {
+ /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF
+ * and thus we need to compare its length first. */
+ if (!(outbuflen <= c->spec->blocksize)
+ || !buf_eq_const (outbuf, c->u_iv.iv, outbuflen))
+ return GPG_ERR_CHECKSUM;
+ }
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_eax_get_tag (gcry_cipher_hd_t c, unsigned char *outtag,
+ size_t taglen)
+{
+ return _gcry_cipher_eax_tag (c, outtag, taglen, 0);
+}
+
+gcry_err_code_t
+_gcry_cipher_eax_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+ size_t taglen)
+{
+ return _gcry_cipher_eax_tag (c, (unsigned char *) intag, taglen, 1);
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-gcm-armv7-neon.S b/comm/third_party/libgcrypt/cipher/cipher-gcm-armv7-neon.S
new file mode 100644
index 0000000000..a801a5e57b
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-gcm-armv7-neon.S
@@ -0,0 +1,341 @@
+/* cipher-gcm-armv7-neon.S - ARM/NEON accelerated GHASH
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_NEON)
+
+.syntax unified
+.fpu neon
+.arm
+
+.text
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+
+/* Constants */
+
+.align 4
+gcry_gcm_reduction_constant:
+.Lrconst64:
+ .quad 0xc200000000000000
+
+/* Register macros */
+
+#define rhash q0
+#define rhash_l d0
+#define rhash_h d1
+
+#define rh1 q1
+#define rh1_l d2
+#define rh1_h d3
+
+#define rbuf q2
+#define rbuf_l d4
+#define rbuf_h d5
+
+#define rbuf1 q3
+#define rbuf1_l d6
+#define rbuf1_h d7
+
+#define t0q q4
+#define t0l d8
+#define t0h d9
+
+#define t1q q5
+#define t1l d10
+#define t1h d11
+
+#define t2q q6
+#define t2l d12
+#define t2h d13
+
+#define t3q q7
+#define t3l d14
+#define t3h d15
+
+/* q8 */
+#define k16 d16
+#define k32 d17
+
+/* q9 */
+#define k48 d18
+
+#define k0 q10
+
+#define rr0 q11
+#define rr0_l d22
+#define rr0_h d23
+
+#define rr1 q12
+#define rr1_l d24
+#define rr1_h d25
+
+#define rt0 q13
+#define rt0_l d26
+#define rt0_h d27
+
+#define rt1 q14
+#define rt1_l d28
+#define rt1_h d29
+
+#define rrconst q15
+#define rrconst_l d30
+#define rrconst_h d31
+
+/* Macro for 64x64=>128 carry-less multiplication using vmull.p8 instruction.
+ *
+ * From "Câmara, D.; Gouvêa, C. P. L.; López, J. & Dahab, R. Fast Software
+ * Polynomial Multiplication on ARM Processors using the NEON Engine. The
+ * Second International Workshop on Modern Cryptography and Security
+ * Engineering — MoCrySEn, 2013". */
+
+#define vmull_p64(rq, rl, rh, ad, bd) \
+ vext.8 t0l, ad, ad, $1; \
+ vmull.p8 t0q, t0l, bd; \
+ vext.8 rl, bd, bd, $1; \
+ vmull.p8 rq, ad, rl; \
+ vext.8 t1l, ad, ad, $2; \
+ vmull.p8 t1q, t1l, bd; \
+ vext.8 t3l, bd, bd, $2; \
+ vmull.p8 t3q, ad, t3l; \
+ vext.8 t2l, ad, ad, $3; \
+ vmull.p8 t2q, t2l, bd; \
+ veor t0q, t0q, rq; \
+ vext.8 rl, bd, bd, $3; \
+ vmull.p8 rq, ad, rl; \
+ veor t1q, t1q, t3q; \
+ vext.8 t3l, bd, bd, $4; \
+ vmull.p8 t3q, ad, t3l; \
+ veor t0l, t0l, t0h; \
+ vand t0h, t0h, k48; \
+ veor t1l, t1l, t1h; \
+ vand t1h, t1h, k32; \
+ veor t2q, t2q, rq; \
+ veor t0l, t0l, t0h; \
+ veor t1l, t1l, t1h; \
+ veor t2l, t2l, t2h; \
+ vand t2h, t2h, k16; \
+ veor t3l, t3l, t3h; \
+ vmov.i64 t3h, $0; \
+ vext.8 t0q, t0q, t0q, $15; \
+ veor t2l, t2l, t2h; \
+ vext.8 t1q, t1q, t1q, $14; \
+ vmull.p8 rq, ad, bd; \
+ vext.8 t2q, t2q, t2q, $13; \
+ vext.8 t3q, t3q, t3q, $12; \
+ veor t0q, t0q, t1q; \
+ veor t2q, t2q, t3q; \
+ veor rq, rq, t0q; \
+ veor rq, rq, t2q;
+
+/* GHASH macros.
+ *
+ * See "Gouvêa, C. P. L. & López, J. Implementing GCM on ARMv8. Topics in
+ * Cryptology — CT-RSA 2015" for details.
+ */
+
+/* Input: 'a' and 'b', Output: 'r0:r1' (low 128-bits in r0, high in r1)
+ * Note: 'r1' may be 'a' or 'b', 'r0' must not be either 'a' or 'b'.
+ */
+#define PMUL_128x128(r0, r1, a, b, t1, t2, interleave_op) \
+ veor t1##_h, b##_l, b##_h; \
+ veor t1##_l, a##_l, a##_h; \
+ vmull_p64( r0, r0##_l, r0##_h, a##_l, b##_l ); \
+ vmull_p64( r1, r1##_l, r1##_h, a##_h, b##_h ); \
+ vmull_p64( t2, t2##_h, t2##_l, t1##_h, t1##_l ); \
+ interleave_op; \
+ veor t2, r0; \
+ veor t2, r1; \
+ veor r0##_h, t2##_l; \
+ veor r1##_l, t2##_h;
+
+/* Reduction using Xor and Shift.
+ * Input: 'r0:r1', Output: 'a'
+ *
+ * See "Shay Gueron, Michael E. Kounavis. Intel Carry-Less Multiplication
+ * Instruction and its Usage for Computing the GCM Mode" for details.
+ */
+#define REDUCTION(a, r0, r1, t, interleave_op) \
+ vshl.u32 t0q, r0, #31; \
+ vshl.u32 t1q, r0, #30; \
+ vshl.u32 t2q, r0, #25; \
+ veor t0q, t0q, t1q; \
+ veor t0q, t0q, t2q; \
+ vext.8 t, t0q, k0, #4; \
+ vext.8 t0q, k0, t0q, #(16-12); \
+ veor r0, r0, t0q; \
+ interleave_op; \
+ vshr.u32 t0q, r0, #1; \
+ vshr.u32 t1q, r0, #2; \
+ vshr.u32 t2q, r0, #7; \
+ veor t0q, t0q, t1q; \
+ veor t0q, t0q, t2q; \
+ veor t0q, t0q, t; \
+ veor r0, r0, t0q; \
+ veor a, r0, r1;
+
+#define _(...) __VA_ARGS__
+#define __ _()
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) veor reg, reg;
+
+
+/*
+ * unsigned int _gcry_ghash_armv7_neon (void *gcm_key, byte *result,
+ * const byte *buf, size_t nblocks);
+ */
+.align 3
+.globl _gcry_ghash_armv7_neon
+.type _gcry_ghash_armv7_neon,%function;
+_gcry_ghash_armv7_neon:
+ /* input:
+ * r0: gcm_key
+ * r1: result/hash
+ * r2: buf
+ * r3: nblocks
+ */
+ push {r4-r6, lr}
+
+ cmp r3, #0
+ beq .Ldo_nothing
+
+ vpush {q4-q7}
+
+ vld1.64 {rhash}, [r1]
+ vld1.64 {rh1}, [r0]
+
+ vrev64.8 rhash, rhash /* byte-swap */
+
+ vmov.i64 k0, #0x0
+ vmov.i64 k16, #0xffff
+ vmov.i64 k32, #0xffffffff
+ vmov.i64 k48, #0xffffffffffff
+
+ vext.8 rhash, rhash, rhash, #8
+
+ /* Handle remaining blocks. */
+
+ vld1.64 {rbuf}, [r2]!
+ subs r3, r3, #1
+
+ vrev64.8 rbuf, rbuf /* byte-swap */
+ vext.8 rbuf, rbuf, rbuf, #8
+
+ veor rhash, rhash, rbuf
+
+ beq .Lend
+
+.Loop:
+ vld1.64 {rbuf}, [r2]!
+ PMUL_128x128(rr0, rr1, rhash, rh1, rt0, rt1, _(vrev64.8 rbuf, rbuf))
+ REDUCTION(rhash, rr0, rr1, rt0, _(vext.8 rbuf, rbuf, rbuf, #8))
+ subs r3, r3, #1
+ veor rhash, rhash, rbuf
+
+ bne .Loop
+
+.Lend:
+ PMUL_128x128(rr0, rr1, rhash, rh1, rt0, rt1, _(CLEAR_REG(rbuf)))
+ REDUCTION(rhash, rr0, rr1, rt0, _(CLEAR_REG(rh1)))
+
+.Ldone:
+ CLEAR_REG(rr1)
+ vrev64.8 rhash, rhash /* byte-swap */
+ CLEAR_REG(rt0)
+ CLEAR_REG(rr0)
+ vext.8 rhash, rhash, rhash, #8
+ CLEAR_REG(rt1)
+ CLEAR_REG(t0q)
+ CLEAR_REG(t1q)
+ CLEAR_REG(t2q)
+ CLEAR_REG(t3q)
+ vst1.64 {rhash}, [r1]
+ CLEAR_REG(rhash)
+
+ vpop {q4-q7}
+
+.Ldo_nothing:
+ mov r0, #0
+ pop {r4-r6, pc}
+.size _gcry_ghash_armv7_neon,.-_gcry_ghash_armv7_neon;
+
+
+/*
+ * void _gcry_ghash_armv7_neon (void *gcm_key);
+ */
+.align 3
+.globl _gcry_ghash_setup_armv7_neon
+.type _gcry_ghash_setup_armv7_neon,%function;
+_gcry_ghash_setup_armv7_neon:
+ /* input:
+ * r0: gcm_key
+ */
+
+ vpush {q4-q7}
+
+ GET_DATA_POINTER(r2, .Lrconst64, r3)
+
+ vld1.64 {rrconst_h}, [r2]
+
+#define GCM_LSH_1(r_out, ia, ib, const_d, oa, ob, ma) \
+ /* H <<< 1 */ \
+ vshr.s64 ma, ib, #63; \
+ vshr.u64 oa, ib, #63; \
+ vshr.u64 ob, ia, #63; \
+ vand ma, const_d; \
+ vshl.u64 ib, ib, #1; \
+ vshl.u64 ia, ia, #1; \
+ vorr ob, ib; \
+ vorr oa, ia; \
+ veor ob, ma; \
+ vst1.64 {oa, ob}, [r_out]
+
+ vld1.64 {rhash}, [r0]
+ vrev64.8 rhash, rhash /* byte-swap */
+ vext.8 rhash, rhash, rhash, #8
+
+ vmov rbuf1, rhash
+ GCM_LSH_1(r0, rhash_l, rhash_h, rrconst_h, rh1_l, rh1_h, rt1_l) /* H<<<1 */
+
+ CLEAR_REG(rh1)
+ CLEAR_REG(rhash)
+ CLEAR_REG(rbuf1)
+ CLEAR_REG(rrconst)
+ vpop {q4-q7}
+ bx lr
+.size _gcry_ghash_setup_armv7_neon,.-_gcry_ghash_setup_armv7_neon;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/cipher-gcm-armv8-aarch32-ce.S b/comm/third_party/libgcrypt/cipher/cipher-gcm-armv8-aarch32-ce.S
new file mode 100644
index 0000000000..1de66a1626
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-gcm-armv8-aarch32-ce.S
@@ -0,0 +1,433 @@
+/* cipher-gcm-armv8-aarch32-ce.S - ARM/CE accelerated GHASH
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO)
+
+.syntax unified
+.arch armv8-a
+.fpu crypto-neon-fp-armv8
+.arm
+
+.text
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+
+/* Constants */
+
+.align 4
+gcry_gcm_reduction_constant:
+.Lrconst64:
+ .quad 0xc200000000000000
+
+
+/* Register macros */
+
+#define rhash q0
+#define rhash_l d0
+#define rhash_h d1
+
+#define rh1 q1
+#define rh1_l d2
+#define rh1_h d3
+
+#define rbuf q2
+#define rbuf_l d4
+#define rbuf_h d5
+
+#define rbuf1 q3
+#define rbuf1_l d6
+#define rbuf1_h d7
+
+#define rbuf2 q4
+#define rbuf2_l d8
+#define rbuf2_h d9
+
+#define rbuf3 q5
+#define rbuf3_l d10
+#define rbuf3_h d11
+
+#define rh2 q6
+#define rh2_l d12
+#define rh2_h d13
+
+#define rh3 q7
+#define rh3_l d14
+#define rh3_h d15
+
+#define rh4 q8
+#define rh4_l d16
+#define rh4_h d17
+
+#define rr2 q9
+#define rr2_l d18
+#define rr2_h d19
+
+#define rr3 q10
+#define rr3_l d20
+#define rr3_h d21
+
+#define rr0 q11
+#define rr0_l d22
+#define rr0_h d23
+
+#define rr1 q12
+#define rr1_l d24
+#define rr1_h d25
+
+#define rt0 q13
+#define rt0_l d26
+#define rt0_h d27
+
+#define rt1 q14
+#define rt1_l d28
+#define rt1_h d29
+
+#define rrconst q15
+#define rrconst_l d30
+#define rrconst_h d31
+
+/* GHASH macros */
+
+/* See "Gouvêa, C. P. L. & López, J. Implementing GCM on ARMv8. Topics in
+ * Cryptology — CT-RSA 2015" for details.
+ */
+
+/* Input: 'a' and 'b', Output: 'r0:r1' (low 128-bits in r0, high in r1)
+ * Note: 'r1' may be 'a' or 'b', 'r0' must not be either 'a' or 'b'.
+ */
+#define PMUL_128x128(r0, r1, a, b, t, interleave_op) \
+ veor t##_h, b##_l, b##_h; \
+ veor t##_l, a##_l, a##_h; \
+ vmull.p64 r0, a##_l, b##_l; \
+ vmull.p64 r1, a##_h, b##_h; \
+ vmull.p64 t, t##_h, t##_l; \
+ interleave_op; \
+ veor t, r0; \
+ veor t, r1; \
+ veor r0##_h, t##_l; \
+ veor r1##_l, t##_h;
+
+/* Input: 'aA' and 'bA', Output: 'r0A:r1A' (low 128-bits in r0A, high in r1A)
+ * Note: 'r1A' may be 'aA' or 'bA', 'r0A' must not be either 'aA' or 'bA'.
+ * Input: 'aB' and 'bB', Output: 'r0B:r1B' (low 128-bits in r0B, high in r1B)
+ * Note: 'r1B' may be 'aB' or 'bB', 'r0B' must not be either 'aB' or 'bB'.
+ */
+#define PMUL_128x128_2(r0A, r1A, aA, bA, r0B, r1B, aB, bB, tA, tB, interleave_op) \
+ veor tA##_h, bA##_l, bA##_h; \
+ veor tA##_l, aA##_l, aA##_h; \
+ veor tB##_h, bB##_l, bB##_h; \
+ veor tB##_l, aB##_l, aB##_h; \
+ vmull.p64 r0A, aA##_l, bA##_l; \
+ vmull.p64 r1A, aA##_h, bA##_h; \
+ vmull.p64 tA, tA##_h, tA##_l; \
+ vmull.p64 r0B, aB##_l, bB##_l; \
+ vmull.p64 r1B, aB##_h, bB##_h; \
+ vmull.p64 tB, tB##_h, tB##_l; \
+ interleave_op; \
+ veor tA, r0A; \
+ veor tA, r1A; \
+ veor tB, r0B; \
+ veor tB, r1B; \
+ veor r0A##_h, tA##_l; \
+ veor r1A##_l, tA##_h; \
+ veor r0B##_h, tB##_l; \
+ veor r1B##_l, tB##_h; \
+
+/* Input: 'r0:r1', Output: 'a' */
+#define REDUCTION(a, r0, r1, rconst, t, interleave_op) \
+ vmull.p64 t, r0##_l, rconst; \
+ veor r0##_h, t##_l; \
+ veor r1##_l, t##_h; \
+ interleave_op; \
+ vmull.p64 t, r0##_h, rconst; \
+ veor r1, t; \
+ veor a, r0, r1;
+
+#define _(...) __VA_ARGS__
+#define __ _()
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) veor reg, reg;
+
+
+/*
+ * unsigned int _gcry_ghash_armv8_ce_pmull (void *gcm_key, byte *result,
+ * const byte *buf, size_t nblocks,
+ * void *gcm_table);
+ */
+.align 3
+.globl _gcry_ghash_armv8_ce_pmull
+.type _gcry_ghash_armv8_ce_pmull,%function;
+_gcry_ghash_armv8_ce_pmull:
+ /* input:
+ * r0: gcm_key
+ * r1: result/hash
+ * r2: buf
+ * r3: nblocks
+ * %st+0: gcm_table
+ */
+ push {r4-r6, lr}
+
+ cmp r3, #0
+ beq .Ldo_nothing
+
+ GET_DATA_POINTER(r4, .Lrconst64, lr)
+
+ vld1.64 {rhash}, [r1]
+ vld1.64 {rh1}, [r0]
+
+ vrev64.8 rhash, rhash /* byte-swap */
+ vld1.64 {rrconst_h}, [r4]
+ vext.8 rhash, rhash, rhash, #8
+
+ cmp r3, #4
+ blo .Less_than_4
+
+ /* Bulk processing of 4 blocks per loop iteration. */
+
+ ldr r5, [sp, #(4*4)];
+ add r6, r5, #32
+
+ vpush {q4-q7}
+
+ vld1.64 {rh2-rh3}, [r5]
+ vld1.64 {rh4}, [r6]
+
+ vld1.64 {rbuf-rbuf1}, [r2]!
+ sub r3, r3, #4
+ vld1.64 {rbuf2-rbuf3}, [r2]!
+
+ cmp r3, #4
+ vrev64.8 rbuf, rbuf /* byte-swap */
+ vrev64.8 rbuf1, rbuf1 /* byte-swap */
+ vrev64.8 rbuf2, rbuf2 /* byte-swap */
+ vrev64.8 rbuf3, rbuf3 /* byte-swap */
+
+ vext.8 rbuf, rbuf, rbuf, #8
+ vext.8 rbuf1, rbuf1, rbuf1, #8
+ vext.8 rbuf2, rbuf2, rbuf2, #8
+ vext.8 rbuf3, rbuf3, rbuf3, #8
+ veor rhash, rhash, rbuf /* in0 ^ hash */
+
+ blo .Lend_4
+
+.Loop_4:
+ /* (in0 ^ hash) * Hâ´ => rr2:rr3 */
+ /* (in1) * H³ => rr0:rr1 */
+ PMUL_128x128_2(rr0, rr1, rbuf1, rh3, rr2, rr3, rhash, rh4, rt1, rt0, __)
+
+ vld1.64 {rbuf-rbuf1}, [r2]!
+ sub r3, r3, #4
+ veor rr0, rr0, rr2
+ veor rr1, rr1, rr3
+
+ /* (in2) * H² => rr2:rr3 */
+ /* (in3) * H¹ => rhash:rbuf3 */
+ PMUL_128x128_2(rr2, rr3, rbuf2, rh2, rhash, rbuf3, rbuf3, rh1, rt0, rt1,
+ _(vrev64.8 rbuf, rbuf))
+
+ vld1.64 {rbuf2}, [r2]!
+
+ vrev64.8 rbuf1, rbuf1
+ veor rr0, rr0, rr2
+ veor rr1, rr1, rr3
+
+ cmp r3, #4
+ vext.8 rbuf, rbuf, rbuf, #8
+ vext.8 rbuf1, rbuf1, rbuf1, #8
+
+ veor rr0, rr0, rhash
+ veor rr1, rr1, rbuf3
+
+ vld1.64 {rbuf3}, [r2]!
+
+ REDUCTION(rhash, rr0, rr1, rrconst_h, rt1,
+ _(vrev64.8 rbuf2, rbuf2;
+ vrev64.8 rbuf3, rbuf3))
+
+ vext.8 rbuf2, rbuf2, rbuf2, #8
+ vext.8 rbuf3, rbuf3, rbuf3, #8
+ veor rhash, rhash, rbuf /* in0 ^ hash */
+
+ bhs .Loop_4
+
+.Lend_4:
+ /* (in0 ^ hash) * Hâ´ => rr2:rr3 */
+ /* (in1) * H³ => rr0:rr1 */
+ PMUL_128x128_2(rr0, rr1, rbuf1, rh3, rr2, rr3, rhash, rh4, rt1, rt0, __)
+
+ /* (in2) * H² => rhash:rbuf */
+ /* (in3) * H¹ => rbuf1:rbuf2 */
+ PMUL_128x128_2(rhash, rbuf, rbuf2, rh2, rbuf1, rbuf2, rbuf3, rh1, rt0, rt1,
+ _(veor rr0, rr0, rr2;
+ veor rr1, rr1, rr3))
+
+ veor rr0, rr0, rhash
+ veor rr1, rr1, rbuf
+
+ veor rr0, rr0, rbuf1
+ veor rr1, rr1, rbuf2
+
+ REDUCTION(rhash, rr0, rr1, rrconst_h, rt1,
+ _(CLEAR_REG(rr2);
+ CLEAR_REG(rr3);
+ CLEAR_REG(rbuf1);
+ CLEAR_REG(rbuf2);
+ CLEAR_REG(rbuf3);
+ CLEAR_REG(rh2);
+ CLEAR_REG(rh3);
+ CLEAR_REG(rh4)))
+
+ vpop {q4-q7}
+
+ cmp r3, #0
+ beq .Ldone
+
+.Less_than_4:
+ /* Handle remaining blocks. */
+
+ vld1.64 {rbuf}, [r2]!
+ subs r3, r3, #1
+
+ vrev64.8 rbuf, rbuf /* byte-swap */
+ vext.8 rbuf, rbuf, rbuf, #8
+
+ veor rhash, rhash, rbuf
+
+ beq .Lend
+
+.Loop:
+ vld1.64 {rbuf}, [r2]!
+ subs r3, r3, #1
+ PMUL_128x128(rr0, rr1, rhash, rh1, rt0, _(vrev64.8 rbuf, rbuf))
+ REDUCTION(rhash, rr0, rr1, rrconst_h, rt0, _(vext.8 rbuf, rbuf, rbuf, #8))
+ veor rhash, rhash, rbuf
+
+ bne .Loop
+
+.Lend:
+ PMUL_128x128(rr0, rr1, rhash, rh1, rt0, _(CLEAR_REG(rbuf)))
+ REDUCTION(rhash, rr0, rr1, rrconst_h, rt0, _(CLEAR_REG(rh1)))
+
+.Ldone:
+ CLEAR_REG(rr1)
+ vrev64.8 rhash, rhash /* byte-swap */
+ CLEAR_REG(rt0)
+ CLEAR_REG(rr0)
+ vext.8 rhash, rhash, rhash, #8
+ CLEAR_REG(rt1)
+ vst1.64 {rhash}, [r1]
+ CLEAR_REG(rhash)
+
+.Ldo_nothing:
+ mov r0, #0
+ pop {r4-r6, pc}
+.size _gcry_ghash_armv8_ce_pmull,.-_gcry_ghash_armv8_ce_pmull;
+
+
+/*
+ * void _gcry_ghash_setup_armv8_ce_pmull (void *gcm_key, void *gcm_table);
+ */
+.align 3
+.globl _gcry_ghash_setup_armv8_ce_pmull
+.type _gcry_ghash_setup_armv8_ce_pmull,%function;
+_gcry_ghash_setup_armv8_ce_pmull:
+ /* input:
+ * r0: gcm_key
+ * r1: gcm_table
+ */
+
+ vpush {q4-q7}
+
+ GET_DATA_POINTER(r2, .Lrconst64, r3)
+
+ vld1.64 {rrconst_h}, [r2]
+
+#define GCM_LSH_1(r_out, ia, ib, const_d, oa, ob, ma) \
+ /* H <<< 1 */ \
+ vshr.s64 ma, ib, #63; \
+ vshr.u64 oa, ib, #63; \
+ vshr.u64 ob, ia, #63; \
+ vand ma, const_d; \
+ vshl.u64 ib, ib, #1; \
+ vshl.u64 ia, ia, #1; \
+ vorr ob, ib; \
+ vorr oa, ia; \
+ veor ob, ma; \
+ vst1.64 {oa, ob}, [r_out]
+
+ vld1.64 {rhash}, [r0]
+ vrev64.8 rhash, rhash /* byte-swap */
+ vext.8 rhash, rhash, rhash, #8
+
+ vmov rbuf1, rhash
+ GCM_LSH_1(r0, rhash_l, rhash_h, rrconst_h, rh1_l, rh1_h, rt1_l) /* H<<<1 */
+
+ /* H² */
+ PMUL_128x128(rr0, rr1, rbuf1, rh1, rt0, __)
+ REDUCTION(rh2, rr0, rr1, rrconst_h, rt0, __)
+ vmov rhash, rh2
+ GCM_LSH_1(r1, rh2_l, rh2_h, rrconst_h, rbuf1_l, rbuf1_h, rt1_l) /* H²<<<1 */
+ add r1, r1, #16
+
+ /* H³ */
+ PMUL_128x128(rr0, rr1, rhash, rh1, rt1, __)
+ REDUCTION(rh3, rr0, rr1, rrconst_h, rt1, __)
+
+ /* Hâ´ */
+ PMUL_128x128(rr0, rr1, rhash, rbuf1, rt0, __)
+ REDUCTION(rh4, rr0, rr1, rrconst_h, rt0, __)
+
+ GCM_LSH_1(r1, rh3_l, rh3_h, rrconst_h, rt0_l, rt0_h, rt1_l) /* H³<<<1 */
+ add r1, r1, #16
+ GCM_LSH_1(r1, rh4_l, rh4_h, rrconst_h, rt0_l, rt0_h, rt1_l) /* Hâ´<<<1 */
+
+ CLEAR_REG(rt0)
+ CLEAR_REG(rt1)
+ CLEAR_REG(rr1)
+ CLEAR_REG(rr0)
+ CLEAR_REG(rh1)
+ CLEAR_REG(rh2)
+ CLEAR_REG(rh3)
+ CLEAR_REG(rh4)
+ CLEAR_REG(rhash)
+ CLEAR_REG(rbuf1)
+ CLEAR_REG(rrconst)
+ vpop {q4-q7}
+ bx lr
+.size _gcry_ghash_setup_armv8_ce_pmull,.-_gcry_ghash_setup_armv8_ce_pmull;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/cipher-gcm-armv8-aarch64-ce.S b/comm/third_party/libgcrypt/cipher/cipher-gcm-armv8-aarch64-ce.S
new file mode 100644
index 0000000000..877207d3e5
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-gcm-armv8-aarch64-ce.S
@@ -0,0 +1,424 @@
+/* cipher-gcm-armv8-aarch64-ce.S - ARM/CE accelerated GHASH
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+
+.cpu generic+simd+crypto
+
+.text
+
+
+/* Constants */
+
+.align 4
+gcry_gcm_reduction_constant:
+.Lrconst:
+ .quad 0x87
+
+
+/* Register macros */
+
+#define rhash v0
+#define rr0 v1
+#define rr1 v2
+#define rbuf v3
+#define rbuf1 v4
+#define rbuf2 v5
+#define rbuf3 v6
+#define rbuf4 v7
+#define rbuf5 v8
+#define rr2 v9
+#define rr3 v10
+#define rr4 v11
+#define rr5 v12
+#define rr6 v13
+#define rr7 v14
+#define rr8 v15
+#define rr9 v16
+
+#define rrconst v18
+#define rh1 v19
+#define rh2 v20
+#define rh3 v21
+#define rh4 v22
+#define rh5 v23
+#define rh6 v24
+#define t0 v25
+#define t1 v26
+#define t2 v27
+#define t3 v28
+#define t4 v29
+#define t5 v30
+#define vZZ v31
+
+/* GHASH macros */
+
+/* See "Gouvêa, C. P. L. & López, J. Implementing GCM on ARMv8. Topics in
+ * Cryptology — CT-RSA 2015" for details.
+ */
+
+/* Input: 'a' and 'b', Output: 'r0:r1' (low 128-bits in r0, high in r1) */
+#define PMUL_128x128(r0, r1, a, b, T0, T1, interleave_op) \
+ ext T0.16b, b.16b, b.16b, #8; \
+ pmull r0.1q, a.1d, b.1d; \
+ pmull2 r1.1q, a.2d, b.2d; \
+ pmull T1.1q, a.1d, T0.1d; \
+ pmull2 T0.1q, a.2d, T0.2d; \
+ interleave_op; \
+ eor T0.16b, T0.16b, T1.16b; \
+ ext T1.16b, vZZ.16b, T0.16b, #8; \
+ ext T0.16b, T0.16b, vZZ.16b, #8; \
+ eor r0.16b, r0.16b, T1.16b; \
+ eor r1.16b, r1.16b, T0.16b;
+
+/* Input: 'aA' and 'bA', Output: 'r0A:r1A' (low 128-bits in r0A, high in r1A)
+ * Input: 'aB' and 'bB', Output: 'r0B:r1B' (low 128-bits in r0B, high in r1B)
+ * Input: 'aC' and 'bC', Output: 'r0C:r1C' (low 128-bits in r0C, high in r1C)
+ */
+#define PMUL_128x128_3(r0A, r1A, aA, bA, t0A, t1A, \
+ r0B, r1B, aB, bB, t0B, t1B, \
+ r0C, r1C, aC, bC, t0C, t1C, interleave_op) \
+ ext t0A.16b, bA.16b, bA.16b, #8; \
+ pmull r0A.1q, aA.1d, bA.1d; \
+ pmull2 r1A.1q, aA.2d, bA.2d; \
+ ext t0B.16b, bB.16b, bB.16b, #8; \
+ pmull r0B.1q, aB.1d, bB.1d; \
+ pmull2 r1B.1q, aB.2d, bB.2d; \
+ ext t0C.16b, bC.16b, bC.16b, #8; \
+ pmull r0C.1q, aC.1d, bC.1d; \
+ pmull2 r1C.1q, aC.2d, bC.2d; \
+ pmull t1A.1q, aA.1d, t0A.1d; \
+ pmull2 t0A.1q, aA.2d, t0A.2d; \
+ pmull t1B.1q, aB.1d, t0B.1d; \
+ pmull2 t0B.1q, aB.2d, t0B.2d; \
+ pmull t1C.1q, aC.1d, t0C.1d; \
+ pmull2 t0C.1q, aC.2d, t0C.2d; \
+ eor t0A.16b, t0A.16b, t1A.16b; \
+ eor t0B.16b, t0B.16b, t1B.16b; \
+ eor t0C.16b, t0C.16b, t1C.16b; \
+ interleave_op; \
+ ext t1A.16b, vZZ.16b, t0A.16b, #8; \
+ ext t0A.16b, t0A.16b, vZZ.16b, #8; \
+ ext t1B.16b, vZZ.16b, t0B.16b, #8; \
+ ext t0B.16b, t0B.16b, vZZ.16b, #8; \
+ ext t1C.16b, vZZ.16b, t0C.16b, #8; \
+ ext t0C.16b, t0C.16b, vZZ.16b, #8; \
+ eor r0A.16b, r0A.16b, t1A.16b; \
+ eor r1A.16b, r1A.16b, t0A.16b; \
+ eor r0B.16b, r0B.16b, t1B.16b; \
+ eor r1B.16b, r1B.16b, t0B.16b; \
+ eor r0C.16b, r0C.16b, t1C.16b; \
+ eor r1C.16b, r1C.16b, t0C.16b; \
+
+/* Input: 'r0:r1', Output: 'a' */
+#define REDUCTION(a, r0, r1, rconst, T0, T1, interleave_op1, interleave_op2, \
+ interleave_op3) \
+ pmull2 T0.1q, r1.2d, rconst.2d; \
+ interleave_op1; \
+ ext T1.16b, T0.16b, vZZ.16b, #8; \
+ ext T0.16b, vZZ.16b, T0.16b, #8; \
+ interleave_op2; \
+ eor r1.16b, r1.16b, T1.16b; \
+ eor r0.16b, r0.16b, T0.16b; \
+ pmull T0.1q, r1.1d, rconst.1d; \
+ interleave_op3; \
+ eor a.16b, r0.16b, T0.16b;
+
+/* Other functional macros */
+
+#define _(...) __VA_ARGS__
+#define __ _()
+
+#define CLEAR_REG(reg) eor reg.16b, reg.16b, reg.16b;
+
+#define VPUSH_ABI \
+ stp d8, d9, [sp, #-16]!; \
+ CFI_ADJUST_CFA_OFFSET(16); \
+ stp d10, d11, [sp, #-16]!; \
+ CFI_ADJUST_CFA_OFFSET(16); \
+ stp d12, d13, [sp, #-16]!; \
+ CFI_ADJUST_CFA_OFFSET(16); \
+ stp d14, d15, [sp, #-16]!; \
+ CFI_ADJUST_CFA_OFFSET(16);
+
+#define VPOP_ABI \
+ ldp d14, d15, [sp], #16; \
+ CFI_ADJUST_CFA_OFFSET(-16); \
+ ldp d12, d13, [sp], #16; \
+ CFI_ADJUST_CFA_OFFSET(-16); \
+ ldp d10, d11, [sp], #16; \
+ CFI_ADJUST_CFA_OFFSET(-16); \
+ ldp d8, d9, [sp], #16; \
+ CFI_ADJUST_CFA_OFFSET(-16);
+
+/*
+ * unsigned int _gcry_ghash_armv8_ce_pmull (void *gcm_key, byte *result,
+ * const byte *buf, size_t nblocks,
+ * void *gcm_table);
+ */
+.align 3
+.globl _gcry_ghash_armv8_ce_pmull
+ELF(.type _gcry_ghash_armv8_ce_pmull,%function;)
+_gcry_ghash_armv8_ce_pmull:
+ /* input:
+ * x0: gcm_key
+ * x1: result/hash
+ * x2: buf
+ * x3: nblocks
+ * x4: gcm_table
+ */
+ CFI_STARTPROC();
+
+ cbz x3, .Ldo_nothing;
+
+ GET_DATA_POINTER(x5, .Lrconst)
+
+ eor vZZ.16b, vZZ.16b, vZZ.16b
+ ld1 {rhash.16b}, [x1]
+ ld1 {rh1.16b}, [x0]
+
+ rbit rhash.16b, rhash.16b /* bit-swap */
+ ld1r {rrconst.2d}, [x5]
+
+ cmp x3, #6
+ b.lo .Less_than_6
+
+ add x6, x4, #64
+ VPUSH_ABI
+
+ ld1 {rh2.16b-rh5.16b}, [x4]
+ ld1 {rh6.16b}, [x6]
+
+ sub x3, x3, #6
+
+ ld1 {rbuf.16b-rbuf2.16b}, [x2], #(3*16)
+ ld1 {rbuf3.16b-rbuf5.16b}, [x2], #(3*16)
+
+ rbit rbuf.16b, rbuf.16b /* bit-swap */
+ rbit rbuf1.16b, rbuf1.16b /* bit-swap */
+ rbit rbuf2.16b, rbuf2.16b /* bit-swap */
+ rbit rbuf3.16b, rbuf3.16b /* bit-swap */
+ rbit rbuf4.16b, rbuf4.16b /* bit-swap */
+ rbit rbuf5.16b, rbuf5.16b /* bit-swap */
+ eor rhash.16b, rhash.16b, rbuf.16b
+
+ cmp x3, #6
+ b.lo .Lend_6
+
+.Loop_6:
+
+ /* (in1) * Hâµ => rr0:rr1 */
+ /* (in2) * Hâ´ => rr2:rr3 */
+ /* (in0 ^ hash) * Hⶠ=> rr4:rr5 */
+ PMUL_128x128_3(rr0, rr1, rbuf1, rh5, t0, t1,
+ rr2, rr3, rbuf2, rh4, t2, t3,
+ rr4, rr5, rhash, rh6, t4, t5,
+ _(sub x3, x3, #6))
+
+ ld1 {rbuf.16b-rbuf2.16b}, [x2], #(3*16)
+ cmp x3, #6
+
+ eor rr0.16b, rr0.16b, rr2.16b
+ eor rr1.16b, rr1.16b, rr3.16b
+
+ /* (in3) * H³ => rr2:rr3 */
+ /* (in4) * H² => rr6:rr7 */
+ /* (in5) * H¹ => rr8:rr9 */
+ PMUL_128x128_3(rr2, rr3, rbuf3, rh3, t0, t1,
+ rr6, rr7, rbuf4, rh2, t2, t3,
+ rr8, rr9, rbuf5, rh1, t4, t5,
+ _(eor rr0.16b, rr0.16b, rr4.16b;
+ eor rr1.16b, rr1.16b, rr5.16b))
+
+ eor rr0.16b, rr0.16b, rr2.16b
+ eor rr1.16b, rr1.16b, rr3.16b
+ rbit rbuf.16b, rbuf.16b
+ eor rr0.16b, rr0.16b, rr6.16b
+ eor rr1.16b, rr1.16b, rr7.16b
+ rbit rbuf1.16b, rbuf1.16b
+ eor rr0.16b, rr0.16b, rr8.16b
+ eor rr1.16b, rr1.16b, rr9.16b
+ ld1 {rbuf3.16b-rbuf5.16b}, [x2], #(3*16)
+
+ REDUCTION(rhash, rr0, rr1, rrconst, t0, t1,
+ _(rbit rbuf2.16b, rbuf2.16b),
+ _(rbit rbuf3.16b, rbuf3.16b),
+ _(rbit rbuf4.16b, rbuf4.16b))
+
+ rbit rbuf5.16b, rbuf5.16b
+ eor rhash.16b, rhash.16b, rbuf.16b
+
+ b.hs .Loop_6
+
+.Lend_6:
+
+ /* (in1) * Hâµ => rr0:rr1 */
+ /* (in0 ^ hash) * Hⶠ=> rr2:rr3 */
+ /* (in2) * Hâ´ => rr4:rr5 */
+ PMUL_128x128_3(rr0, rr1, rbuf1, rh5, t0, t1,
+ rr2, rr3, rhash, rh6, t2, t3,
+ rr4, rr5, rbuf2, rh4, t4, t5,
+ __)
+ eor rr0.16b, rr0.16b, rr2.16b
+ eor rr1.16b, rr1.16b, rr3.16b
+ eor rr0.16b, rr0.16b, rr4.16b
+ eor rr1.16b, rr1.16b, rr5.16b
+
+ /* (in3) * H³ => rhash:rbuf */
+ /* (in4) * H² => rr6:rr7 */
+ /* (in5) * H¹ => rr8:rr9 */
+ PMUL_128x128_3(rhash, rbuf, rbuf3, rh3, t0, t1,
+ rr6, rr7, rbuf4, rh2, t2, t3,
+ rr8, rr9, rbuf5, rh1, t4, t5,
+ _(CLEAR_REG(rh4);
+ CLEAR_REG(rh5);
+ CLEAR_REG(rh6)))
+ eor rr0.16b, rr0.16b, rhash.16b
+ eor rr1.16b, rr1.16b, rbuf.16b
+ eor rr0.16b, rr0.16b, rr6.16b
+ eor rr1.16b, rr1.16b, rr7.16b
+ eor rr0.16b, rr0.16b, rr8.16b
+ eor rr1.16b, rr1.16b, rr9.16b
+
+ REDUCTION(rhash, rr0, rr1, rrconst, t0, t1,
+ _(CLEAR_REG(rh2);
+ CLEAR_REG(rh3);
+ CLEAR_REG(rr2);
+ CLEAR_REG(rbuf2);
+ CLEAR_REG(rbuf3)),
+ _(CLEAR_REG(rr3);
+ CLEAR_REG(rr4);
+ CLEAR_REG(rr5);
+ CLEAR_REG(rr6);
+ CLEAR_REG(rr7)),
+ _(CLEAR_REG(rr8);
+ CLEAR_REG(rr9);
+ CLEAR_REG(rbuf1);
+ CLEAR_REG(rbuf2)))
+
+ CLEAR_REG(rbuf4)
+ CLEAR_REG(rbuf5)
+ CLEAR_REG(t2)
+ CLEAR_REG(t3)
+ CLEAR_REG(t4)
+ CLEAR_REG(t5)
+
+ VPOP_ABI
+
+ cbz x3, .Ldone
+
+.Less_than_6:
+ /* Handle remaining blocks. */
+
+ ld1 {rbuf.16b}, [x2], #16
+ sub x3, x3, #1
+
+ rbit rbuf.16b, rbuf.16b /* bit-swap */
+
+ eor rhash.16b, rhash.16b, rbuf.16b
+
+ cbz x3, .Lend
+
+.Loop:
+ PMUL_128x128(rr0, rr1, rh1, rhash, t0, t1, _(ld1 {rbuf.16b}, [x2], #16))
+ REDUCTION(rhash, rr0, rr1, rrconst, t0, t1,
+ _(sub x3, x3, #1),
+ _(rbit rbuf.16b, rbuf.16b),
+ __)
+ eor rhash.16b, rhash.16b, rbuf.16b
+
+ cbnz x3, .Loop
+
+.Lend:
+ PMUL_128x128(rr0, rr1, rh1, rhash, t0, t1, _(CLEAR_REG(rbuf)))
+ REDUCTION(rhash, rr0, rr1, rrconst, t0, t1, __, _(CLEAR_REG(rh1)), __)
+
+.Ldone:
+ CLEAR_REG(rr1)
+ CLEAR_REG(rr0)
+ rbit rhash.16b, rhash.16b /* bit-swap */
+ CLEAR_REG(t0)
+ CLEAR_REG(t1)
+
+ st1 {rhash.2d}, [x1]
+ CLEAR_REG(rhash)
+
+.Ldo_nothing:
+ mov x0, #0
+ ret
+ CFI_ENDPROC()
+ELF(.size _gcry_ghash_armv8_ce_pmull,.-_gcry_ghash_armv8_ce_pmull;)
+
+
+/*
+ * void _gcry_ghash_setup_armv8_ce_pmull (void *gcm_key, void *gcm_table);
+ */
+.align 3
+.globl _gcry_ghash_setup_armv8_ce_pmull
+ELF(.type _gcry_ghash_setup_armv8_ce_pmull,%function;)
+_gcry_ghash_setup_armv8_ce_pmull:
+ /* input:
+ * x0: gcm_key
+ * x1: gcm_table
+ */
+ CFI_STARTPROC()
+
+ GET_DATA_POINTER(x2, .Lrconst)
+
+ eor vZZ.16b, vZZ.16b, vZZ.16b
+
+ /* H¹ */
+ ld1 {rh1.16b}, [x0]
+ rbit rh1.16b, rh1.16b
+ st1 {rh1.16b}, [x0]
+
+ ld1r {rrconst.2d}, [x2]
+
+ /* H² */
+ PMUL_128x128(rr0, rr1, rh1, rh1, t0, t1, __)
+ REDUCTION(rh2, rr0, rr1, rrconst, t0, t1, __, __, __)
+
+ /* H³ */
+ PMUL_128x128(rr0, rr1, rh2, rh1, t0, t1, __)
+ REDUCTION(rh3, rr0, rr1, rrconst, t0, t1, __, __, __)
+
+ /* Hâ´ */
+ PMUL_128x128(rr0, rr1, rh2, rh2, t0, t1, __)
+ REDUCTION(rh4, rr0, rr1, rrconst, t0, t1, __, __, __)
+
+ /* Hâµ */
+ PMUL_128x128(rr0, rr1, rh2, rh3, t0, t1, __)
+ REDUCTION(rh5, rr0, rr1, rrconst, t0, t1, __, __, __)
+
+ /* Hⶠ*/
+ PMUL_128x128(rr0, rr1, rh3, rh3, t0, t1, __)
+ REDUCTION(rh6, rr0, rr1, rrconst, t0, t1, __, __, __)
+
+ st1 {rh2.16b-rh4.16b}, [x1], #(3*16)
+ st1 {rh5.16b-rh6.16b}, [x1]
+
+ ret
+ CFI_ENDPROC()
+ELF(.size _gcry_ghash_setup_armv8_ce_pmull,.-_gcry_ghash_setup_armv8_ce_pmull;)
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/cipher-gcm-intel-pclmul.c b/comm/third_party/libgcrypt/cipher/cipher-gcm-intel-pclmul.c
new file mode 100644
index 0000000000..28165c653f
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-gcm-intel-pclmul.c
@@ -0,0 +1,712 @@
+/* cipher-gcm-intel-pclmul.c - Intel PCLMUL accelerated Galois Counter Mode
+ * implementation
+ * Copyright (C) 2013-2014,2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+#ifdef GCM_USE_INTEL_PCLMUL
+
+
+#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
+
+
+/*
+ Intel PCLMUL ghash based on white paper:
+ "Intel® Carry-Less Multiplication Instruction and its Usage for Computing the
+ GCM Mode - Rev 2.01"; Shay Gueron, Michael E. Kounavis.
+ */
+static ASM_FUNC_ATTR_INLINE void reduction(void)
+{
+ /* input: <xmm1:xmm3> */
+
+ asm volatile (/* first phase of the reduction */
+ "movdqa %%xmm3, %%xmm6\n\t"
+ "movdqa %%xmm3, %%xmm5\n\t"
+ "psllq $1, %%xmm6\n\t" /* packed right shifting << 63 */
+ "pxor %%xmm3, %%xmm6\n\t"
+ "psllq $57, %%xmm5\n\t" /* packed right shifting << 57 */
+ "psllq $62, %%xmm6\n\t" /* packed right shifting << 62 */
+ "pxor %%xmm5, %%xmm6\n\t" /* xor the shifted versions */
+ "pshufd $0x6a, %%xmm6, %%xmm5\n\t"
+ "pshufd $0xae, %%xmm6, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm3\n\t" /* first phase of the reduction
+ complete */
+
+ /* second phase of the reduction */
+ "pxor %%xmm3, %%xmm1\n\t" /* xor the shifted versions */
+ "psrlq $1, %%xmm3\n\t" /* packed left shifting >> 1 */
+ "pxor %%xmm3, %%xmm6\n\t"
+ "psrlq $1, %%xmm3\n\t" /* packed left shifting >> 2 */
+ "pxor %%xmm3, %%xmm1\n\t"
+ "psrlq $5, %%xmm3\n\t" /* packed left shifting >> 7 */
+ "pxor %%xmm3, %%xmm6\n\t"
+ "pxor %%xmm6, %%xmm1\n\t" /* the result is in xmm1 */
+ ::: "memory" );
+}
+
+static ASM_FUNC_ATTR_INLINE void gfmul_pclmul(void)
+{
+ /* Input: XMM0 and XMM1, Output: XMM1. Input XMM0 stays unmodified.
+ Input must be converted to little-endian.
+ */
+ asm volatile (/* gfmul, xmm0 has operator a and xmm1 has operator b. */
+ "pshufd $78, %%xmm0, %%xmm2\n\t"
+ "pshufd $78, %%xmm1, %%xmm4\n\t"
+ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 holds a0+a1 */
+ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 holds b0+b1 */
+
+ "movdqa %%xmm0, %%xmm3\n\t"
+ "pclmulqdq $0, %%xmm1, %%xmm3\n\t" /* xmm3 holds a0*b0 */
+ "pclmulqdq $17, %%xmm0, %%xmm1\n\t" /* xmm6 holds a1*b1 */
+ "movdqa %%xmm3, %%xmm5\n\t"
+ "pclmulqdq $0, %%xmm2, %%xmm4\n\t" /* xmm4 holds (a0+a1)*(b0+b1) */
+
+ "pxor %%xmm1, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */
+ "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */
+ "movdqa %%xmm4, %%xmm5\n\t"
+ "psrldq $8, %%xmm4\n\t"
+ "pslldq $8, %%xmm5\n\t"
+ "pxor %%xmm5, %%xmm3\n\t"
+ "pxor %%xmm4, %%xmm1\n\t" /* <xmm1:xmm3> holds the result of the
+ carry-less multiplication of xmm0
+ by xmm1 */
+ ::: "memory" );
+
+ reduction();
+}
+
+static ASM_FUNC_ATTR_INLINE void
+gfmul_pclmul_aggr4(const void *buf, const void *h_1, const void *h_table,
+ const unsigned char *be_mask)
+{
+ /* Input:
+ Hash: XMM1
+ Output:
+ Hash: XMM1
+ */
+ asm volatile (/* perform clmul and merge results... */
+ "movdqu 2*16(%[h_table]), %%xmm2\n\t" /* Load H4 */
+ "movdqu 0*16(%[buf]), %%xmm5\n\t"
+ "pshufb %[be_mask], %%xmm5\n\t" /* be => le */
+ "pxor %%xmm5, %%xmm1\n\t"
+
+ "pshufd $78, %%xmm2, %%xmm5\n\t"
+ "pshufd $78, %%xmm1, %%xmm4\n\t"
+ "pxor %%xmm2, %%xmm5\n\t" /* xmm5 holds 4:a0+a1 */
+ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 holds 4:b0+b1 */
+ "movdqa %%xmm2, %%xmm3\n\t"
+ "pclmulqdq $0, %%xmm1, %%xmm3\n\t" /* xmm3 holds 4:a0*b0 */
+ "pclmulqdq $17, %%xmm2, %%xmm1\n\t" /* xmm1 holds 4:a1*b1 */
+ "pclmulqdq $0, %%xmm5, %%xmm4\n\t" /* xmm4 holds 4:(a0+a1)*(b0+b1) */
+
+ "movdqu 1*16(%[h_table]), %%xmm5\n\t" /* Load H3 */
+ "movdqu 1*16(%[buf]), %%xmm2\n\t"
+ "pshufb %[be_mask], %%xmm2\n\t" /* be => le */
+
+ "pshufd $78, %%xmm5, %%xmm0\n\t"
+ "pshufd $78, %%xmm2, %%xmm7\n\t"
+ "pxor %%xmm5, %%xmm0\n\t" /* xmm0 holds 3:a0+a1 */
+ "pxor %%xmm2, %%xmm7\n\t" /* xmm7 holds 3:b0+b1 */
+ "movdqa %%xmm5, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm2, %%xmm6\n\t" /* xmm6 holds 3:a0*b0 */
+ "pclmulqdq $17, %%xmm5, %%xmm2\n\t" /* xmm2 holds 3:a1*b1 */
+ "pclmulqdq $0, %%xmm0, %%xmm7\n\t" /* xmm7 holds 3:(a0+a1)*(b0+b1) */
+
+ "movdqu 2*16(%[buf]), %%xmm5\n\t"
+ "pshufb %[be_mask], %%xmm5\n\t" /* be => le */
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 3+4:a0*b0 */
+ "pxor %%xmm2, %%xmm1\n\t" /* xmm1 holds 3+4:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 3+4:(a0+a1)*(b0+b1) */
+
+ "movdqu 0*16(%[h_table]), %%xmm2\n\t" /* Load H2 */
+
+ "pshufd $78, %%xmm2, %%xmm0\n\t"
+ "pshufd $78, %%xmm5, %%xmm7\n\t"
+ "pxor %%xmm2, %%xmm0\n\t" /* xmm0 holds 2:a0+a1 */
+ "pxor %%xmm5, %%xmm7\n\t" /* xmm7 holds 2:b0+b1 */
+ "movdqa %%xmm2, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm5, %%xmm6\n\t" /* xmm6 holds 2:a0*b0 */
+ "pclmulqdq $17, %%xmm2, %%xmm5\n\t" /* xmm5 holds 2:a1*b1 */
+ "pclmulqdq $0, %%xmm0, %%xmm7\n\t" /* xmm7 holds 2:(a0+a1)*(b0+b1) */
+
+ "movdqu 3*16(%[buf]), %%xmm2\n\t"
+ "pshufb %[be_mask], %%xmm2\n\t" /* be => le */
+ :
+ : [buf] "r" (buf),
+ [h_table] "r" (h_table),
+ [be_mask] "m" (*be_mask)
+ : "memory" );
+
+ asm volatile ("pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 2+3+4:a0*b0 */
+ "pxor %%xmm5, %%xmm1\n\t" /* xmm1 holds 2+3+4:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 2+3+4:(a0+a1)*(b0+b1) */
+
+ "movdqu %[h_1], %%xmm5\n\t" /* Load H1 */
+
+ "pshufd $78, %%xmm5, %%xmm0\n\t"
+ "pshufd $78, %%xmm2, %%xmm7\n\t"
+ "pxor %%xmm5, %%xmm0\n\t" /* xmm0 holds 1:a0+a1 */
+ "pxor %%xmm2, %%xmm7\n\t" /* xmm7 holds 1:b0+b1 */
+ "movdqa %%xmm5, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm2, %%xmm6\n\t" /* xmm6 holds 1:a0*b0 */
+ "pclmulqdq $17, %%xmm5, %%xmm2\n\t" /* xmm2 holds 1:a1*b1 */
+ "pclmulqdq $0, %%xmm0, %%xmm7\n\t" /* xmm7 holds 1:(a0+a1)*(b0+b1) */
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 1+2+3+4:a0*b0 */
+ "pxor %%xmm2, %%xmm1\n\t" /* xmm1 holds 1+2+3+4:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 1+2+3+4:(a0+a1)*(b0+b1) */
+
+ /* aggregated reduction... */
+ "movdqa %%xmm3, %%xmm5\n\t"
+ "pxor %%xmm1, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */
+ "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */
+ "movdqa %%xmm4, %%xmm5\n\t"
+ "psrldq $8, %%xmm4\n\t"
+ "pslldq $8, %%xmm5\n\t"
+ "pxor %%xmm5, %%xmm3\n\t"
+ "pxor %%xmm4, %%xmm1\n\t" /* <xmm1:xmm3> holds the result of the
+ carry-less multiplication of xmm0
+ by xmm1 */
+ :
+ : [h_1] "m" (*(const unsigned char *)h_1)
+ : "memory" );
+
+ reduction();
+}
+
+#ifdef __x86_64__
+static ASM_FUNC_ATTR_INLINE void
+gfmul_pclmul_aggr8(const void *buf, const void *h_table)
+{
+ /* Input:
+ H¹: XMM0
+ bemask: XMM15
+ Hash: XMM1
+ Output:
+ Hash: XMM1
+ Inputs XMM0 and XMM15 stays unmodified.
+ */
+ asm volatile (/* Load H6, H7, H8. */
+ "movdqu 6*16(%[h_table]), %%xmm10\n\t"
+ "movdqu 5*16(%[h_table]), %%xmm9\n\t"
+ "movdqu 4*16(%[h_table]), %%xmm8\n\t"
+
+ /* perform clmul and merge results... */
+ "movdqu 0*16(%[buf]), %%xmm5\n\t"
+ "movdqu 1*16(%[buf]), %%xmm2\n\t"
+ "pshufb %%xmm15, %%xmm5\n\t" /* be => le */
+ "pshufb %%xmm15, %%xmm2\n\t" /* be => le */
+ "pxor %%xmm5, %%xmm1\n\t"
+
+ "pshufd $78, %%xmm10, %%xmm5\n\t"
+ "pshufd $78, %%xmm1, %%xmm4\n\t"
+ "pxor %%xmm10, %%xmm5\n\t" /* xmm5 holds 8:a0+a1 */
+ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 holds 8:b0+b1 */
+ "movdqa %%xmm10, %%xmm3\n\t"
+ "pclmulqdq $0, %%xmm1, %%xmm3\n\t" /* xmm3 holds 8:a0*b0 */
+ "pclmulqdq $17, %%xmm10, %%xmm1\n\t" /* xmm1 holds 8:a1*b1 */
+ "pclmulqdq $0, %%xmm5, %%xmm4\n\t" /* xmm4 holds 8:(a0+a1)*(b0+b1) */
+
+ "pshufd $78, %%xmm9, %%xmm11\n\t"
+ "pshufd $78, %%xmm2, %%xmm7\n\t"
+ "pxor %%xmm9, %%xmm11\n\t" /* xmm11 holds 7:a0+a1 */
+ "pxor %%xmm2, %%xmm7\n\t" /* xmm7 holds 7:b0+b1 */
+ "movdqa %%xmm9, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm2, %%xmm6\n\t" /* xmm6 holds 7:a0*b0 */
+ "pclmulqdq $17, %%xmm9, %%xmm2\n\t" /* xmm2 holds 7:a1*b1 */
+ "pclmulqdq $0, %%xmm11, %%xmm7\n\t" /* xmm7 holds 7:(a0+a1)*(b0+b1) */
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 7+8:a0*b0 */
+ "pxor %%xmm2, %%xmm1\n\t" /* xmm1 holds 7+8:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 7+8:(a0+a1)*(b0+b1) */
+
+ "movdqu 2*16(%[buf]), %%xmm5\n\t"
+ "movdqu 3*16(%[buf]), %%xmm2\n\t"
+ "pshufb %%xmm15, %%xmm5\n\t" /* be => le */
+ "pshufb %%xmm15, %%xmm2\n\t" /* be => le */
+
+ "pshufd $78, %%xmm8, %%xmm11\n\t"
+ "pshufd $78, %%xmm5, %%xmm7\n\t"
+ "pxor %%xmm8, %%xmm11\n\t" /* xmm11 holds 6:a0+a1 */
+ "pxor %%xmm5, %%xmm7\n\t" /* xmm7 holds 6:b0+b1 */
+ "movdqa %%xmm8, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm5, %%xmm6\n\t" /* xmm6 holds 6:a0*b0 */
+ "pclmulqdq $17, %%xmm8, %%xmm5\n\t" /* xmm5 holds 6:a1*b1 */
+ "pclmulqdq $0, %%xmm11, %%xmm7\n\t" /* xmm7 holds 6:(a0+a1)*(b0+b1) */
+
+ /* Load H3, H4, H5. */
+ "movdqu 3*16(%[h_table]), %%xmm10\n\t"
+ "movdqu 2*16(%[h_table]), %%xmm9\n\t"
+ "movdqu 1*16(%[h_table]), %%xmm8\n\t"
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 6+7+8:a0*b0 */
+ "pxor %%xmm5, %%xmm1\n\t" /* xmm1 holds 6+7+8:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 6+7+8:(a0+a1)*(b0+b1) */
+
+ "pshufd $78, %%xmm10, %%xmm11\n\t"
+ "pshufd $78, %%xmm2, %%xmm7\n\t"
+ "pxor %%xmm10, %%xmm11\n\t" /* xmm11 holds 5:a0+a1 */
+ "pxor %%xmm2, %%xmm7\n\t" /* xmm7 holds 5:b0+b1 */
+ "movdqa %%xmm10, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm2, %%xmm6\n\t" /* xmm6 holds 5:a0*b0 */
+ "pclmulqdq $17, %%xmm10, %%xmm2\n\t" /* xmm2 holds 5:a1*b1 */
+ "pclmulqdq $0, %%xmm11, %%xmm7\n\t" /* xmm7 holds 5:(a0+a1)*(b0+b1) */
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 5+6+7+8:a0*b0 */
+ "pxor %%xmm2, %%xmm1\n\t" /* xmm1 holds 5+6+7+8:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 5+6+7+8:(a0+a1)*(b0+b1) */
+
+ "movdqu 4*16(%[buf]), %%xmm5\n\t"
+ "movdqu 5*16(%[buf]), %%xmm2\n\t"
+ "pshufb %%xmm15, %%xmm5\n\t" /* be => le */
+ "pshufb %%xmm15, %%xmm2\n\t" /* be => le */
+
+ "pshufd $78, %%xmm9, %%xmm11\n\t"
+ "pshufd $78, %%xmm5, %%xmm7\n\t"
+ "pxor %%xmm9, %%xmm11\n\t" /* xmm11 holds 4:a0+a1 */
+ "pxor %%xmm5, %%xmm7\n\t" /* xmm7 holds 4:b0+b1 */
+ "movdqa %%xmm9, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm5, %%xmm6\n\t" /* xmm6 holds 4:a0*b0 */
+ "pclmulqdq $17, %%xmm9, %%xmm5\n\t" /* xmm5 holds 4:a1*b1 */
+ "pclmulqdq $0, %%xmm11, %%xmm7\n\t" /* xmm7 holds 4:(a0+a1)*(b0+b1) */
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 4+5+6+7+8:a0*b0 */
+ "pxor %%xmm5, %%xmm1\n\t" /* xmm1 holds 4+5+6+7+8:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 4+5+6+7+8:(a0+a1)*(b0+b1) */
+
+ "pshufd $78, %%xmm8, %%xmm11\n\t"
+ "pshufd $78, %%xmm2, %%xmm7\n\t"
+ "pxor %%xmm8, %%xmm11\n\t" /* xmm11 holds 3:a0+a1 */
+ "pxor %%xmm2, %%xmm7\n\t" /* xmm7 holds 3:b0+b1 */
+ "movdqa %%xmm8, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm2, %%xmm6\n\t" /* xmm6 holds 3:a0*b0 */
+ "pclmulqdq $17, %%xmm8, %%xmm2\n\t" /* xmm2 holds 3:a1*b1 */
+ "pclmulqdq $0, %%xmm11, %%xmm7\n\t" /* xmm7 holds 3:(a0+a1)*(b0+b1) */
+
+ "movdqu 0*16(%[h_table]), %%xmm8\n\t" /* Load H2 */
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 3+4+5+6+7+8:a0*b0 */
+ "pxor %%xmm2, %%xmm1\n\t" /* xmm1 holds 3+4+5+6+7+8:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 3+4+5+6+7+8:(a0+a1)*(b0+b1) */
+
+ "movdqu 6*16(%[buf]), %%xmm5\n\t"
+ "movdqu 7*16(%[buf]), %%xmm2\n\t"
+ "pshufb %%xmm15, %%xmm5\n\t" /* be => le */
+ "pshufb %%xmm15, %%xmm2\n\t" /* be => le */
+
+ "pshufd $78, %%xmm8, %%xmm11\n\t"
+ "pshufd $78, %%xmm5, %%xmm7\n\t"
+ "pxor %%xmm8, %%xmm11\n\t" /* xmm11 holds 4:a0+a1 */
+ "pxor %%xmm5, %%xmm7\n\t" /* xmm7 holds 4:b0+b1 */
+ "movdqa %%xmm8, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm5, %%xmm6\n\t" /* xmm6 holds 4:a0*b0 */
+ "pclmulqdq $17, %%xmm8, %%xmm5\n\t" /* xmm5 holds 4:a1*b1 */
+ "pclmulqdq $0, %%xmm11, %%xmm7\n\t" /* xmm7 holds 4:(a0+a1)*(b0+b1) */
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 2+3+4+5+6+7+8:a0*b0 */
+ "pxor %%xmm5, %%xmm1\n\t" /* xmm1 holds 2+3+4+5+6+7+8:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 2+3+4+5+6+7+8:(a0+a1)*(b0+b1) */
+
+ "pshufd $78, %%xmm0, %%xmm11\n\t"
+ "pshufd $78, %%xmm2, %%xmm7\n\t"
+ "pxor %%xmm0, %%xmm11\n\t" /* xmm11 holds 3:a0+a1 */
+ "pxor %%xmm2, %%xmm7\n\t" /* xmm7 holds 3:b0+b1 */
+ "movdqa %%xmm0, %%xmm6\n\t"
+ "pclmulqdq $0, %%xmm2, %%xmm6\n\t" /* xmm6 holds 3:a0*b0 */
+ "pclmulqdq $17, %%xmm0, %%xmm2\n\t" /* xmm2 holds 3:a1*b1 */
+ "pclmulqdq $0, %%xmm11, %%xmm7\n\t" /* xmm7 holds 3:(a0+a1)*(b0+b1) */
+
+ "pxor %%xmm6, %%xmm3\n\t" /* xmm3 holds 1+2+3+3+4+5+6+7+8:a0*b0 */
+ "pxor %%xmm2, %%xmm1\n\t" /* xmm1 holds 1+2+3+3+4+5+6+7+8:a1*b1 */
+ "pxor %%xmm7, %%xmm4\n\t" /* xmm4 holds 1+2+3+3+4+5+6+7+8:(a0+a1)*(b0+b1) */
+
+ /* aggregated reduction... */
+ "movdqa %%xmm3, %%xmm5\n\t"
+ "pxor %%xmm1, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */
+ "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */
+ "movdqa %%xmm4, %%xmm5\n\t"
+ "psrldq $8, %%xmm4\n\t"
+ "pslldq $8, %%xmm5\n\t"
+ "pxor %%xmm5, %%xmm3\n\t"
+ "pxor %%xmm4, %%xmm1\n\t" /* <xmm1:xmm3> holds the result of the
+ carry-less multiplication of xmm0
+ by xmm1 */
+ :
+ : [buf] "r" (buf),
+ [h_table] "r" (h_table)
+ : "memory" );
+
+ reduction();
+}
+#endif
+
+static ASM_FUNC_ATTR_INLINE void gcm_lsh(void *h, unsigned int hoffs)
+{
+ static const u64 pconst[2] __attribute__ ((aligned (16))) =
+ { U64_C(0x0000000000000001), U64_C(0xc200000000000000) };
+
+ asm volatile ("movdqu (%[h]), %%xmm2\n\t"
+ "pshufd $0xff, %%xmm2, %%xmm3\n\t"
+ "movdqa %%xmm2, %%xmm4\n\t"
+ "psrad $31, %%xmm3\n\t"
+ "pslldq $8, %%xmm4\n\t"
+ "pand %[pconst], %%xmm3\n\t"
+ "paddq %%xmm2, %%xmm2\n\t"
+ "psrlq $63, %%xmm4\n\t"
+ "pxor %%xmm3, %%xmm2\n\t"
+ "pxor %%xmm4, %%xmm2\n\t"
+ "movdqu %%xmm2, (%[h])\n\t"
+ :
+ : [pconst] "m" (pconst),
+ [h] "r" ((byte *)h + hoffs)
+ : "memory" );
+}
+
+void ASM_FUNC_ATTR
+_gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c)
+{
+ 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 };
+#if defined(__x86_64__) && defined(__WIN64__)
+ char win64tmp[10 * 16];
+
+ /* XMM6-XMM15 need to be restored after use. */
+ 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" (win64tmp)
+ : "memory" );
+#endif
+
+ /* Swap endianness of hsub. */
+ asm volatile ("movdqu (%[key]), %%xmm0\n\t"
+ "pshufb %[be_mask], %%xmm0\n\t"
+ "movdqu %%xmm0, (%[key])\n\t"
+ :
+ : [key] "r" (c->u_mode.gcm.u_ghash_key.key),
+ [be_mask] "m" (*be_mask)
+ : "memory");
+
+ gcm_lsh(c->u_mode.gcm.u_ghash_key.key, 0); /* H <<< 1 */
+
+ asm volatile ("movdqa %%xmm0, %%xmm1\n\t"
+ "movdqu (%[key]), %%xmm0\n\t" /* load H <<< 1 */
+ :
+ : [key] "r" (c->u_mode.gcm.u_ghash_key.key)
+ : "memory");
+
+ gfmul_pclmul (); /* H<<<1•H => H² */
+
+ asm volatile ("movdqu %%xmm1, 0*16(%[h_table])\n\t"
+ "movdqa %%xmm1, %%xmm7\n\t"
+ :
+ : [h_table] "r" (c->u_mode.gcm.gcm_table)
+ : "memory");
+
+ gcm_lsh(c->u_mode.gcm.gcm_table, 0 * 16); /* H² <<< 1 */
+ gfmul_pclmul (); /* H<<<1•H² => H³ */
+
+ asm volatile ("movdqa %%xmm7, %%xmm0\n\t"
+ "movdqu %%xmm1, 1*16(%[h_table])\n\t"
+ "movdqu 0*16(%[h_table]), %%xmm1\n\t" /* load H² <<< 1 */
+ :
+ : [h_table] "r" (c->u_mode.gcm.gcm_table)
+ : "memory");
+
+ gfmul_pclmul (); /* H²<<<1•H² => Hⴠ*/
+
+ asm volatile ("movdqu %%xmm1, 2*16(%[h_table])\n\t"
+ "movdqa %%xmm1, %%xmm0\n\t"
+ "movdqu (%[key]), %%xmm1\n\t" /* load H <<< 1 */
+ :
+ : [h_table] "r" (c->u_mode.gcm.gcm_table),
+ [key] "r" (c->u_mode.gcm.u_ghash_key.key)
+ : "memory");
+
+ gcm_lsh(c->u_mode.gcm.gcm_table, 1 * 16); /* H³ <<< 1 */
+ gcm_lsh(c->u_mode.gcm.gcm_table, 2 * 16); /* Hâ´ <<< 1 */
+
+#ifdef __x86_64__
+ gfmul_pclmul (); /* H<<<1•Hⴠ=> Hⵠ*/
+
+ asm volatile ("movdqu %%xmm1, 3*16(%[h_table])\n\t"
+ "movdqu 0*16(%[h_table]), %%xmm1\n\t" /* load H² <<< 1 */
+ :
+ : [h_table] "r" (c->u_mode.gcm.gcm_table)
+ : "memory");
+
+ gfmul_pclmul (); /* H²<<<1•Hⴠ=> Hⶠ*/
+
+ asm volatile ("movdqu %%xmm1, 4*16(%[h_table])\n\t"
+ "movdqu 1*16(%[h_table]), %%xmm1\n\t" /* load H³ <<< 1 */
+ :
+ : [h_table] "r" (c->u_mode.gcm.gcm_table)
+ : "memory");
+
+ gfmul_pclmul (); /* H³<<<1•Hⴠ=> Hⷠ*/
+
+ asm volatile ("movdqu %%xmm1, 5*16(%[h_table])\n\t"
+ "movdqu 2*16(%[h_table]), %%xmm1\n\t" /* load Hâ´ <<< 1 */
+ :
+ : [h_table] "r" (c->u_mode.gcm.gcm_table)
+ : "memory");
+
+ gfmul_pclmul (); /* H³<<<1•Hⴠ=> H⸠*/
+
+ asm volatile ("movdqu %%xmm1, 6*16(%[h_table])\n\t"
+ :
+ : [h_table] "r" (c->u_mode.gcm.gcm_table)
+ : "memory");
+
+ gcm_lsh(c->u_mode.gcm.gcm_table, 3 * 16); /* Hâµ <<< 1 */
+ gcm_lsh(c->u_mode.gcm.gcm_table, 4 * 16); /* Hⶠ<<< 1 */
+ gcm_lsh(c->u_mode.gcm.gcm_table, 5 * 16); /* Hâ· <<< 1 */
+ gcm_lsh(c->u_mode.gcm.gcm_table, 6 * 16); /* H⸠<<< 1 */
+
+#ifdef __WIN64__
+ /* Clear/restore used registers. */
+ 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" (win64tmp)
+ : "memory" );
+#else
+ /* Clear used registers. */
+ 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"
+ "pxor %%xmm9, %%xmm9\n\t"
+ "pxor %%xmm10, %%xmm10\n\t"
+ "pxor %%xmm11, %%xmm11\n\t"
+ "pxor %%xmm12, %%xmm12\n\t"
+ "pxor %%xmm13, %%xmm13\n\t"
+ "pxor %%xmm14, %%xmm14\n\t"
+ "pxor %%xmm15, %%xmm15\n\t"
+ ::: "memory" );
+#endif
+#endif
+}
+
+
+unsigned int ASM_FUNC_ATTR
+_gcry_ghash_intel_pclmul (gcry_cipher_hd_t c, byte *result, const byte *buf,
+ 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 };
+ const unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
+#if defined(__x86_64__) && defined(__WIN64__)
+ char win64tmp[10 * 16];
+#endif
+
+ if (nblocks == 0)
+ return 0;
+
+#if defined(__x86_64__) && defined(__WIN64__)
+ /* XMM6-XMM15 need to be restored after use. */
+ 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" (win64tmp)
+ : "memory" );
+#endif
+
+ /* Preload hash. */
+ asm volatile ("movdqa %[be_mask], %%xmm7\n\t"
+ "movdqu %[hash], %%xmm1\n\t"
+ "pshufb %%xmm7, %%xmm1\n\t" /* be => le */
+ :
+ : [hash] "m" (*result),
+ [be_mask] "m" (*be_mask)
+ : "memory" );
+
+#ifdef __x86_64__
+ if (nblocks >= 8)
+ {
+ /* Preload H1. */
+ asm volatile ("movdqa %%xmm7, %%xmm15\n\t"
+ "movdqa %[h_1], %%xmm0\n\t"
+ :
+ : [h_1] "m" (*c->u_mode.gcm.u_ghash_key.key)
+ : "memory" );
+
+ while (nblocks >= 8)
+ {
+ gfmul_pclmul_aggr8 (buf, c->u_mode.gcm.gcm_table);
+
+ buf += 8 * blocksize;
+ nblocks -= 8;
+ }
+#ifndef __WIN64__
+ /* Clear used x86-64/XMM registers. */
+ asm volatile( "pxor %%xmm8, %%xmm8\n\t"
+ "pxor %%xmm9, %%xmm9\n\t"
+ "pxor %%xmm10, %%xmm10\n\t"
+ "pxor %%xmm11, %%xmm11\n\t"
+ "pxor %%xmm12, %%xmm12\n\t"
+ "pxor %%xmm13, %%xmm13\n\t"
+ "pxor %%xmm14, %%xmm14\n\t"
+ "pxor %%xmm15, %%xmm15\n\t"
+ ::: "memory" );
+#endif
+ }
+#endif
+
+ while (nblocks >= 4)
+ {
+ gfmul_pclmul_aggr4 (buf, c->u_mode.gcm.u_ghash_key.key,
+ c->u_mode.gcm.gcm_table, be_mask);
+
+ buf += 4 * blocksize;
+ nblocks -= 4;
+ }
+
+ if (nblocks)
+ {
+ /* Preload H1. */
+ asm volatile ("movdqa %[h_1], %%xmm0\n\t"
+ :
+ : [h_1] "m" (*c->u_mode.gcm.u_ghash_key.key)
+ : "memory" );
+
+ while (nblocks)
+ {
+ asm volatile ("movdqu %[buf], %%xmm2\n\t"
+ "pshufb %[be_mask], %%xmm2\n\t" /* be => le */
+ "pxor %%xmm2, %%xmm1\n\t"
+ :
+ : [buf] "m" (*buf), [be_mask] "m" (*be_mask)
+ : "memory" );
+
+ gfmul_pclmul ();
+
+ buf += blocksize;
+ nblocks--;
+ }
+ }
+
+ /* Store hash. */
+ asm volatile ("pshufb %[be_mask], %%xmm1\n\t" /* be => le */
+ "movdqu %%xmm1, %[hash]\n\t"
+ : [hash] "=m" (*result)
+ : [be_mask] "m" (*be_mask)
+ : "memory" );
+
+#if defined(__x86_64__) && defined(__WIN64__)
+ /* Clear/restore used registers. */
+ 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" (win64tmp)
+ : "memory" );
+#else
+ /* Clear used registers. */
+ 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"
+ ::: "memory" );
+#endif
+
+ return 0;
+}
+
+#if __clang__
+# pragma clang attribute pop
+#endif
+
+#endif /* GCM_USE_INTEL_PCLMUL */
diff --git a/comm/third_party/libgcrypt/cipher/cipher-gcm.c b/comm/third_party/libgcrypt/cipher/cipher-gcm.c
new file mode 100644
index 0000000000..7aad12776f
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-gcm.c
@@ -0,0 +1,1207 @@
+/* cipher-gcm.c - Generic Galois Counter Mode implementation
+ * Copyright (C) 2013 Dmitry Eremin-Solenikov
+ * Copyright (C) 2013, 2018-2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+/* Helper macro to force alignment to 16 or 64 bytes. */
+#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# define ATTR_ALIGNED_64 __attribute__ ((aligned (64)))
+#else
+# define ATTR_ALIGNED_64
+#endif
+
+
+#ifdef GCM_USE_INTEL_PCLMUL
+extern void _gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c);
+
+extern unsigned int _gcry_ghash_intel_pclmul (gcry_cipher_hd_t c, byte *result,
+ const byte *buf, size_t nblocks);
+#endif
+
+#ifdef GCM_USE_ARM_PMULL
+extern void _gcry_ghash_setup_armv8_ce_pmull (void *gcm_key, void *gcm_table);
+
+extern unsigned int _gcry_ghash_armv8_ce_pmull (void *gcm_key, byte *result,
+ const byte *buf, size_t nblocks,
+ void *gcm_table);
+
+static void
+ghash_setup_armv8_ce_pmull (gcry_cipher_hd_t c)
+{
+ _gcry_ghash_setup_armv8_ce_pmull(c->u_mode.gcm.u_ghash_key.key,
+ c->u_mode.gcm.gcm_table);
+}
+
+static unsigned int
+ghash_armv8_ce_pmull (gcry_cipher_hd_t c, byte *result, const byte *buf,
+ size_t nblocks)
+{
+ return _gcry_ghash_armv8_ce_pmull(c->u_mode.gcm.u_ghash_key.key, result, buf,
+ nblocks, c->u_mode.gcm.gcm_table);
+}
+#endif /* GCM_USE_ARM_PMULL */
+
+#ifdef GCM_USE_ARM_NEON
+extern void _gcry_ghash_setup_armv7_neon (void *gcm_key);
+
+extern unsigned int _gcry_ghash_armv7_neon (void *gcm_key, byte *result,
+ const byte *buf, size_t nblocks);
+
+static void
+ghash_setup_armv7_neon (gcry_cipher_hd_t c)
+{
+ _gcry_ghash_setup_armv7_neon(c->u_mode.gcm.u_ghash_key.key);
+}
+
+static unsigned int
+ghash_armv7_neon (gcry_cipher_hd_t c, byte *result, const byte *buf,
+ size_t nblocks)
+{
+ return _gcry_ghash_armv7_neon(c->u_mode.gcm.u_ghash_key.key, result, buf,
+ nblocks);
+}
+#endif /* GCM_USE_ARM_NEON */
+
+#ifdef GCM_USE_S390X_CRYPTO
+#include "asm-inline-s390x.h"
+
+static unsigned int
+ghash_s390x_kimd (gcry_cipher_hd_t c, byte *result, const byte *buf,
+ size_t nblocks)
+{
+ u128_t params[2];
+
+ memcpy (&params[0], result, 16);
+ memcpy (&params[1], c->u_mode.gcm.u_ghash_key.key, 16);
+
+ kimd_execute (KMID_FUNCTION_GHASH, &params, buf, nblocks * 16);
+
+ memcpy (result, &params[0], 16);
+ wipememory (params, sizeof(params));
+ return 0;
+}
+#endif /* GCM_USE_S390X_CRYPTO*/
+
+
+#ifdef GCM_USE_TABLES
+static struct
+{
+ volatile u32 counter_head;
+ u32 cacheline_align[64 / 4 - 1];
+ u16 R[256];
+ volatile u32 counter_tail;
+} gcm_table ATTR_ALIGNED_64 =
+ {
+ 0,
+ { 0, },
+ {
+ 0x0000, 0x01c2, 0x0384, 0x0246, 0x0708, 0x06ca, 0x048c, 0x054e,
+ 0x0e10, 0x0fd2, 0x0d94, 0x0c56, 0x0918, 0x08da, 0x0a9c, 0x0b5e,
+ 0x1c20, 0x1de2, 0x1fa4, 0x1e66, 0x1b28, 0x1aea, 0x18ac, 0x196e,
+ 0x1230, 0x13f2, 0x11b4, 0x1076, 0x1538, 0x14fa, 0x16bc, 0x177e,
+ 0x3840, 0x3982, 0x3bc4, 0x3a06, 0x3f48, 0x3e8a, 0x3ccc, 0x3d0e,
+ 0x3650, 0x3792, 0x35d4, 0x3416, 0x3158, 0x309a, 0x32dc, 0x331e,
+ 0x2460, 0x25a2, 0x27e4, 0x2626, 0x2368, 0x22aa, 0x20ec, 0x212e,
+ 0x2a70, 0x2bb2, 0x29f4, 0x2836, 0x2d78, 0x2cba, 0x2efc, 0x2f3e,
+ 0x7080, 0x7142, 0x7304, 0x72c6, 0x7788, 0x764a, 0x740c, 0x75ce,
+ 0x7e90, 0x7f52, 0x7d14, 0x7cd6, 0x7998, 0x785a, 0x7a1c, 0x7bde,
+ 0x6ca0, 0x6d62, 0x6f24, 0x6ee6, 0x6ba8, 0x6a6a, 0x682c, 0x69ee,
+ 0x62b0, 0x6372, 0x6134, 0x60f6, 0x65b8, 0x647a, 0x663c, 0x67fe,
+ 0x48c0, 0x4902, 0x4b44, 0x4a86, 0x4fc8, 0x4e0a, 0x4c4c, 0x4d8e,
+ 0x46d0, 0x4712, 0x4554, 0x4496, 0x41d8, 0x401a, 0x425c, 0x439e,
+ 0x54e0, 0x5522, 0x5764, 0x56a6, 0x53e8, 0x522a, 0x506c, 0x51ae,
+ 0x5af0, 0x5b32, 0x5974, 0x58b6, 0x5df8, 0x5c3a, 0x5e7c, 0x5fbe,
+ 0xe100, 0xe0c2, 0xe284, 0xe346, 0xe608, 0xe7ca, 0xe58c, 0xe44e,
+ 0xef10, 0xeed2, 0xec94, 0xed56, 0xe818, 0xe9da, 0xeb9c, 0xea5e,
+ 0xfd20, 0xfce2, 0xfea4, 0xff66, 0xfa28, 0xfbea, 0xf9ac, 0xf86e,
+ 0xf330, 0xf2f2, 0xf0b4, 0xf176, 0xf438, 0xf5fa, 0xf7bc, 0xf67e,
+ 0xd940, 0xd882, 0xdac4, 0xdb06, 0xde48, 0xdf8a, 0xddcc, 0xdc0e,
+ 0xd750, 0xd692, 0xd4d4, 0xd516, 0xd058, 0xd19a, 0xd3dc, 0xd21e,
+ 0xc560, 0xc4a2, 0xc6e4, 0xc726, 0xc268, 0xc3aa, 0xc1ec, 0xc02e,
+ 0xcb70, 0xcab2, 0xc8f4, 0xc936, 0xcc78, 0xcdba, 0xcffc, 0xce3e,
+ 0x9180, 0x9042, 0x9204, 0x93c6, 0x9688, 0x974a, 0x950c, 0x94ce,
+ 0x9f90, 0x9e52, 0x9c14, 0x9dd6, 0x9898, 0x995a, 0x9b1c, 0x9ade,
+ 0x8da0, 0x8c62, 0x8e24, 0x8fe6, 0x8aa8, 0x8b6a, 0x892c, 0x88ee,
+ 0x83b0, 0x8272, 0x8034, 0x81f6, 0x84b8, 0x857a, 0x873c, 0x86fe,
+ 0xa9c0, 0xa802, 0xaa44, 0xab86, 0xaec8, 0xaf0a, 0xad4c, 0xac8e,
+ 0xa7d0, 0xa612, 0xa454, 0xa596, 0xa0d8, 0xa11a, 0xa35c, 0xa29e,
+ 0xb5e0, 0xb422, 0xb664, 0xb7a6, 0xb2e8, 0xb32a, 0xb16c, 0xb0ae,
+ 0xbbf0, 0xba32, 0xb874, 0xb9b6, 0xbcf8, 0xbd3a, 0xbf7c, 0xbebe,
+ },
+ 0
+ };
+
+#define gcmR gcm_table.R
+
+static inline
+void prefetch_table(const void *tab, size_t len)
+{
+ const volatile byte *vtab = tab;
+ size_t i;
+
+ for (i = 0; len - i >= 8 * 32; i += 8 * 32)
+ {
+ (void)vtab[i + 0 * 32];
+ (void)vtab[i + 1 * 32];
+ (void)vtab[i + 2 * 32];
+ (void)vtab[i + 3 * 32];
+ (void)vtab[i + 4 * 32];
+ (void)vtab[i + 5 * 32];
+ (void)vtab[i + 6 * 32];
+ (void)vtab[i + 7 * 32];
+ }
+ for (; i < len; i += 32)
+ {
+ (void)vtab[i];
+ }
+
+ (void)vtab[len - 1];
+}
+
+static inline void
+do_prefetch_tables (const void *gcmM, size_t gcmM_size)
+{
+ /* 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. */
+ gcm_table.counter_head++;
+ gcm_table.counter_tail++;
+
+ /* Prefetch look-up tables to cache. */
+ prefetch_table(gcmM, gcmM_size);
+ prefetch_table(&gcm_table, sizeof(gcm_table));
+}
+
+#ifdef GCM_TABLES_USE_U64
+static void
+bshift (u64 * b0, u64 * b1)
+{
+ u64 t[2], mask;
+
+ t[0] = *b0;
+ t[1] = *b1;
+ mask = -(t[1] & 1) & 0xe1;
+ mask <<= 56;
+
+ *b1 = (t[1] >> 1) ^ (t[0] << 63);
+ *b0 = (t[0] >> 1) ^ mask;
+}
+
+static void
+do_fillM (unsigned char *h, u64 *M)
+{
+ int i, j;
+
+ M[0 + 0] = 0;
+ M[0 + 16] = 0;
+
+ M[8 + 0] = buf_get_be64 (h + 0);
+ M[8 + 16] = buf_get_be64 (h + 8);
+
+ for (i = 4; i > 0; i /= 2)
+ {
+ M[i + 0] = M[2 * i + 0];
+ M[i + 16] = M[2 * i + 16];
+
+ bshift (&M[i], &M[i + 16]);
+ }
+
+ for (i = 2; i < 16; i *= 2)
+ for (j = 1; j < i; j++)
+ {
+ M[(i + j) + 0] = M[i + 0] ^ M[j + 0];
+ M[(i + j) + 16] = M[i + 16] ^ M[j + 16];
+ }
+
+ for (i = 0; i < 16; i++)
+ {
+ M[i + 32] = (M[i + 0] >> 4) ^ ((u64) gcmR[(M[i + 16] & 0xf) << 4] << 48);
+ M[i + 48] = (M[i + 16] >> 4) ^ (M[i + 0] << 60);
+ }
+}
+
+static inline unsigned int
+do_ghash (unsigned char *result, const unsigned char *buf, const u64 *gcmM)
+{
+ u64 V[2];
+ u64 tmp[2];
+ const u64 *M;
+ u64 T;
+ u32 A;
+ int i;
+
+ cipher_block_xor (V, result, buf, 16);
+ V[0] = be_bswap64 (V[0]);
+ V[1] = be_bswap64 (V[1]);
+
+ /* First round can be manually tweaked based on fact that 'tmp' is zero. */
+ M = &gcmM[(V[1] & 0xf) + 32];
+ V[1] >>= 4;
+ tmp[0] = M[0];
+ tmp[1] = M[16];
+ tmp[0] ^= gcmM[(V[1] & 0xf) + 0];
+ tmp[1] ^= gcmM[(V[1] & 0xf) + 16];
+ V[1] >>= 4;
+
+ i = 6;
+ while (1)
+ {
+ M = &gcmM[(V[1] & 0xf) + 32];
+ V[1] >>= 4;
+
+ A = tmp[1] & 0xff;
+ T = tmp[0];
+ tmp[0] = (T >> 8) ^ ((u64) gcmR[A] << 48) ^ gcmM[(V[1] & 0xf) + 0];
+ tmp[1] = (T << 56) ^ (tmp[1] >> 8) ^ gcmM[(V[1] & 0xf) + 16];
+
+ tmp[0] ^= M[0];
+ tmp[1] ^= M[16];
+
+ if (i == 0)
+ break;
+
+ V[1] >>= 4;
+ --i;
+ }
+
+ i = 7;
+ while (1)
+ {
+ M = &gcmM[(V[0] & 0xf) + 32];
+ V[0] >>= 4;
+
+ A = tmp[1] & 0xff;
+ T = tmp[0];
+ tmp[0] = (T >> 8) ^ ((u64) gcmR[A] << 48) ^ gcmM[(V[0] & 0xf) + 0];
+ tmp[1] = (T << 56) ^ (tmp[1] >> 8) ^ gcmM[(V[0] & 0xf) + 16];
+
+ tmp[0] ^= M[0];
+ tmp[1] ^= M[16];
+
+ if (i == 0)
+ break;
+
+ V[0] >>= 4;
+ --i;
+ }
+
+ buf_put_be64 (result + 0, tmp[0]);
+ buf_put_be64 (result + 8, tmp[1]);
+
+ return (sizeof(V) + sizeof(T) + sizeof(tmp) +
+ sizeof(int)*2 + sizeof(void*)*5);
+}
+
+#else /*!GCM_TABLES_USE_U64*/
+
+static void
+bshift (u32 * M, int i)
+{
+ u32 t[4], mask;
+
+ t[0] = M[i * 4 + 0];
+ t[1] = M[i * 4 + 1];
+ t[2] = M[i * 4 + 2];
+ t[3] = M[i * 4 + 3];
+ mask = -(t[3] & 1) & 0xe1;
+
+ M[i * 4 + 3] = (t[3] >> 1) ^ (t[2] << 31);
+ M[i * 4 + 2] = (t[2] >> 1) ^ (t[1] << 31);
+ M[i * 4 + 1] = (t[1] >> 1) ^ (t[0] << 31);
+ M[i * 4 + 0] = (t[0] >> 1) ^ (mask << 24);
+}
+
+static void
+do_fillM (unsigned char *h, u32 *M)
+{
+ int i, j;
+
+ M[0 * 4 + 0] = 0;
+ M[0 * 4 + 1] = 0;
+ M[0 * 4 + 2] = 0;
+ M[0 * 4 + 3] = 0;
+
+ M[8 * 4 + 0] = buf_get_be32 (h + 0);
+ M[8 * 4 + 1] = buf_get_be32 (h + 4);
+ M[8 * 4 + 2] = buf_get_be32 (h + 8);
+ M[8 * 4 + 3] = buf_get_be32 (h + 12);
+
+ for (i = 4; i > 0; i /= 2)
+ {
+ M[i * 4 + 0] = M[2 * i * 4 + 0];
+ M[i * 4 + 1] = M[2 * i * 4 + 1];
+ M[i * 4 + 2] = M[2 * i * 4 + 2];
+ M[i * 4 + 3] = M[2 * i * 4 + 3];
+
+ bshift (M, i);
+ }
+
+ for (i = 2; i < 16; i *= 2)
+ for (j = 1; j < i; j++)
+ {
+ M[(i + j) * 4 + 0] = M[i * 4 + 0] ^ M[j * 4 + 0];
+ M[(i + j) * 4 + 1] = M[i * 4 + 1] ^ M[j * 4 + 1];
+ M[(i + j) * 4 + 2] = M[i * 4 + 2] ^ M[j * 4 + 2];
+ M[(i + j) * 4 + 3] = M[i * 4 + 3] ^ M[j * 4 + 3];
+ }
+
+ for (i = 0; i < 4 * 16; i += 4)
+ {
+ M[i + 0 + 64] = (M[i + 0] >> 4)
+ ^ ((u64) gcmR[(M[i + 3] << 4) & 0xf0] << 16);
+ M[i + 1 + 64] = (M[i + 1] >> 4) ^ (M[i + 0] << 28);
+ M[i + 2 + 64] = (M[i + 2] >> 4) ^ (M[i + 1] << 28);
+ M[i + 3 + 64] = (M[i + 3] >> 4) ^ (M[i + 2] << 28);
+ }
+}
+
+static inline unsigned int
+do_ghash (unsigned char *result, const unsigned char *buf, const u32 *gcmM)
+{
+ byte V[16];
+ u32 tmp[4];
+ u32 v;
+ const u32 *M, *m;
+ u32 T[3];
+ int i;
+
+ cipher_block_xor (V, result, buf, 16); /* V is big-endian */
+
+ /* First round can be manually tweaked based on fact that 'tmp' is zero. */
+ i = 15;
+
+ v = V[i];
+ M = &gcmM[(v & 0xf) * 4 + 64];
+ v = (v & 0xf0) >> 4;
+ m = &gcmM[v * 4];
+ v = V[--i];
+
+ tmp[0] = M[0] ^ m[0];
+ tmp[1] = M[1] ^ m[1];
+ tmp[2] = M[2] ^ m[2];
+ tmp[3] = M[3] ^ m[3];
+
+ while (1)
+ {
+ M = &gcmM[(v & 0xf) * 4 + 64];
+ v = (v & 0xf0) >> 4;
+ m = &gcmM[v * 4];
+
+ T[0] = tmp[0];
+ T[1] = tmp[1];
+ T[2] = tmp[2];
+ tmp[0] = (T[0] >> 8) ^ ((u32) gcmR[tmp[3] & 0xff] << 16) ^ m[0];
+ tmp[1] = (T[0] << 24) ^ (tmp[1] >> 8) ^ m[1];
+ tmp[2] = (T[1] << 24) ^ (tmp[2] >> 8) ^ m[2];
+ tmp[3] = (T[2] << 24) ^ (tmp[3] >> 8) ^ m[3];
+
+ tmp[0] ^= M[0];
+ tmp[1] ^= M[1];
+ tmp[2] ^= M[2];
+ tmp[3] ^= M[3];
+
+ if (i == 0)
+ break;
+
+ v = V[--i];
+ }
+
+ buf_put_be32 (result + 0, tmp[0]);
+ buf_put_be32 (result + 4, tmp[1]);
+ buf_put_be32 (result + 8, tmp[2]);
+ buf_put_be32 (result + 12, tmp[3]);
+
+ return (sizeof(V) + sizeof(T) + sizeof(tmp) +
+ sizeof(int)*2 + sizeof(void*)*6);
+}
+#endif /*!GCM_TABLES_USE_U64*/
+
+#define fillM(c) \
+ do_fillM (c->u_mode.gcm.u_ghash_key.key, c->u_mode.gcm.gcm_table)
+#define GHASH(c, result, buf) do_ghash (result, buf, c->u_mode.gcm.gcm_table)
+#define prefetch_tables(c) \
+ do_prefetch_tables(c->u_mode.gcm.gcm_table, sizeof(c->u_mode.gcm.gcm_table))
+
+#else
+
+static unsigned long
+bshift (unsigned long *b)
+{
+ unsigned long c;
+ int i;
+ c = b[3] & 1;
+ for (i = 3; i > 0; i--)
+ {
+ b[i] = (b[i] >> 1) | (b[i - 1] << 31);
+ }
+ b[i] >>= 1;
+ return c;
+}
+
+static unsigned int
+do_ghash (unsigned char *hsub, unsigned char *result, const unsigned char *buf)
+{
+ unsigned long V[4];
+ int i, j;
+ byte *p;
+
+#ifdef WORDS_BIGENDIAN
+ p = result;
+#else
+ unsigned long T[4];
+
+ cipher_block_xor (V, result, buf, 16);
+ for (i = 0; i < 4; i++)
+ {
+ V[i] = (V[i] & 0x00ff00ff) << 8 | (V[i] & 0xff00ff00) >> 8;
+ V[i] = (V[i] & 0x0000ffff) << 16 | (V[i] & 0xffff0000) >> 16;
+ }
+ p = (byte *) T;
+#endif
+
+ memset (p, 0, 16);
+
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0x80; j; j >>= 1)
+ {
+ if (hsub[i] & j)
+ cipher_block_xor (p, p, V, 16);
+ if (bshift (V))
+ V[0] ^= 0xe1000000;
+ }
+ }
+#ifndef WORDS_BIGENDIAN
+ for (i = 0, p = (byte *) T; i < 16; i += 4, p += 4)
+ {
+ result[i + 0] = p[3];
+ result[i + 1] = p[2];
+ result[i + 2] = p[1];
+ result[i + 3] = p[0];
+ }
+#endif
+
+ return (sizeof(V) + sizeof(T) + sizeof(int)*2 + sizeof(void*)*5);
+}
+
+#define fillM(c) do { } while (0)
+#define GHASH(c, result, buf) do_ghash (c->u_mode.gcm.u_ghash_key.key, result, buf)
+#define prefetch_tables(c) do {} while (0)
+
+#endif /* !GCM_USE_TABLES */
+
+
+static unsigned int
+ghash_internal (gcry_cipher_hd_t c, byte *result, const byte *buf,
+ size_t nblocks)
+{
+ const unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
+ unsigned int burn = 0;
+
+ prefetch_tables (c);
+
+ while (nblocks)
+ {
+ burn = GHASH (c, result, buf);
+ buf += blocksize;
+ nblocks--;
+ }
+
+ return burn + (burn ? 5*sizeof(void*) : 0);
+}
+
+
+static void
+setupM (gcry_cipher_hd_t c)
+{
+#if defined(GCM_USE_INTEL_PCLMUL) || defined(GCM_USE_ARM_PMULL) || \
+ defined(GCM_USE_S390X_CRYPTO)
+ unsigned int features = _gcry_get_hw_features ();
+#endif
+
+ c->u_mode.gcm.ghash_fn = NULL;
+
+ if (0)
+ ;
+#ifdef GCM_USE_INTEL_PCLMUL
+ else if (features & HWF_INTEL_PCLMUL)
+ {
+ c->u_mode.gcm.ghash_fn = _gcry_ghash_intel_pclmul;
+ _gcry_ghash_setup_intel_pclmul (c);
+ }
+#endif
+#ifdef GCM_USE_ARM_PMULL
+ else if (features & HWF_ARM_PMULL)
+ {
+ c->u_mode.gcm.ghash_fn = ghash_armv8_ce_pmull;
+ ghash_setup_armv8_ce_pmull (c);
+ }
+#endif
+#ifdef GCM_USE_ARM_NEON
+ else if (features & HWF_ARM_NEON)
+ {
+ c->u_mode.gcm.ghash_fn = ghash_armv7_neon;
+ ghash_setup_armv7_neon (c);
+ }
+#endif
+#ifdef GCM_USE_S390X_CRYPTO
+ else if (features & HWF_S390X_MSA)
+ {
+ if (kimd_query () & km_function_to_mask (KMID_FUNCTION_GHASH))
+ {
+ c->u_mode.gcm.ghash_fn = ghash_s390x_kimd;
+ }
+ }
+#endif
+
+ if (c->u_mode.gcm.ghash_fn == NULL)
+ {
+ c->u_mode.gcm.ghash_fn = ghash_internal;
+ fillM (c);
+ }
+}
+
+
+static inline void
+gcm_bytecounter_add (u32 ctr[2], size_t add)
+{
+ if (sizeof(add) > sizeof(u32))
+ {
+ u32 high_add = ((add >> 31) >> 1) & 0xffffffff;
+ ctr[1] += high_add;
+ }
+
+ ctr[0] += add;
+ if (ctr[0] >= add)
+ return;
+ ++ctr[1];
+}
+
+
+static inline u32
+gcm_add32_be128 (byte *ctr, unsigned int add)
+{
+ /* 'ctr' must be aligned to four bytes. */
+ const unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
+ u32 *pval = (u32 *)(void *)(ctr + blocksize - sizeof(u32));
+ u32 val;
+
+ val = be_bswap32(*pval) + add;
+ *pval = be_bswap32(val);
+
+ return val; /* return result as host-endian value */
+}
+
+
+static inline int
+gcm_check_datalen (u32 ctr[2])
+{
+ /* len(plaintext) <= 2^39-256 bits == 2^36-32 bytes == 2^32-2 blocks */
+ if (ctr[1] > 0xfU)
+ return 0;
+ if (ctr[1] < 0xfU)
+ return 1;
+
+ if (ctr[0] <= 0xffffffe0U)
+ return 1;
+
+ return 0;
+}
+
+
+static inline int
+gcm_check_aadlen_or_ivlen (u32 ctr[2])
+{
+ /* len(aad/iv) <= 2^64-1 bits ~= 2^61-1 bytes */
+ if (ctr[1] > 0x1fffffffU)
+ return 0;
+ if (ctr[1] < 0x1fffffffU)
+ return 1;
+
+ if (ctr[0] <= 0xffffffffU)
+ return 1;
+
+ return 0;
+}
+
+
+static void
+do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf,
+ size_t buflen, int do_padding)
+{
+ unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
+ unsigned int unused = c->u_mode.gcm.mac_unused;
+ ghash_fn_t ghash_fn = c->u_mode.gcm.ghash_fn;
+ size_t nblocks, n;
+ unsigned int burn = 0;
+
+ if (buflen == 0 && (unused == 0 || !do_padding))
+ return;
+
+ do
+ {
+ if (buflen > 0 && (buflen + unused < blocksize || unused > 0))
+ {
+ n = blocksize - unused;
+ n = n < buflen ? n : buflen;
+
+ buf_cpy (&c->u_mode.gcm.macbuf[unused], buf, n);
+
+ unused += n;
+ buf += n;
+ buflen -= n;
+ }
+ if (!buflen)
+ {
+ if (!do_padding && unused < blocksize)
+ {
+ break;
+ }
+
+ n = blocksize - unused;
+ if (n > 0)
+ {
+ memset (&c->u_mode.gcm.macbuf[unused], 0, n);
+ unused = blocksize;
+ }
+ }
+
+ if (unused > 0)
+ {
+ gcry_assert (unused == blocksize);
+
+ /* Process one block from macbuf. */
+ burn = ghash_fn (c, hash, c->u_mode.gcm.macbuf, 1);
+ unused = 0;
+ }
+
+ nblocks = buflen / blocksize;
+
+ if (nblocks)
+ {
+ burn = ghash_fn (c, hash, buf, nblocks);
+ buf += blocksize * nblocks;
+ buflen -= blocksize * nblocks;
+ }
+ }
+ while (buflen > 0);
+
+ c->u_mode.gcm.mac_unused = unused;
+
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+
+static gcry_err_code_t
+gcm_ctr_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ gcry_err_code_t err = 0;
+
+ while (inbuflen)
+ {
+ u32 nblocks_to_overflow;
+ u32 num_ctr_increments;
+ u32 curr_ctr_low;
+ size_t currlen = inbuflen;
+ byte ctr_copy[GCRY_GCM_BLOCK_LEN];
+ int fix_ctr = 0;
+
+ /* GCM CTR increments only least significant 32-bits, without carry
+ * to upper 96-bits of counter. Using generic CTR implementation
+ * directly would carry 32-bit overflow to upper 96-bit. Detect
+ * if input length is long enough to cause overflow, and limit
+ * input length so that CTR overflow happen but updated CTR value is
+ * not used to encrypt further input. After overflow, upper 96 bits
+ * of CTR are restored to cancel out modification done by generic CTR
+ * encryption. */
+
+ if (inbuflen > c->unused)
+ {
+ curr_ctr_low = gcm_add32_be128 (c->u_ctr.ctr, 0);
+
+ /* Number of CTR increments this inbuflen would cause. */
+ num_ctr_increments = (inbuflen - c->unused) / GCRY_GCM_BLOCK_LEN +
+ !!((inbuflen - c->unused) % GCRY_GCM_BLOCK_LEN);
+
+ if ((u32)(num_ctr_increments + curr_ctr_low) < curr_ctr_low)
+ {
+ nblocks_to_overflow = 0xffffffffU - curr_ctr_low + 1;
+ currlen = nblocks_to_overflow * GCRY_GCM_BLOCK_LEN + c->unused;
+ if (currlen > inbuflen)
+ {
+ currlen = inbuflen;
+ }
+
+ fix_ctr = 1;
+ cipher_block_cpy(ctr_copy, c->u_ctr.ctr, GCRY_GCM_BLOCK_LEN);
+ }
+ }
+
+ err = _gcry_cipher_ctr_encrypt(c, outbuf, outbuflen, inbuf, currlen);
+ if (err != 0)
+ return err;
+
+ if (fix_ctr)
+ {
+ /* Lower 32-bits of CTR should now be zero. */
+ gcry_assert(gcm_add32_be128 (c->u_ctr.ctr, 0) == 0);
+
+ /* Restore upper part of CTR. */
+ buf_cpy(c->u_ctr.ctr, ctr_copy, GCRY_GCM_BLOCK_LEN - sizeof(u32));
+
+ wipememory(ctr_copy, sizeof(ctr_copy));
+ }
+
+ inbuflen -= currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ outbuf += currlen;
+ }
+
+ return err;
+}
+
+
+static gcry_err_code_t
+gcm_crypt_inner (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen, int encrypt)
+{
+ gcry_err_code_t err;
+
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Use a bulk method if available. */
+ if (c->bulk.gcm_crypt)
+ {
+ /* Bulk method requires that there is no cached data. */
+ if (inbuflen >= GCRY_GCM_BLOCK_LEN && c->u_mode.gcm.mac_unused == 0)
+ {
+ size_t nblks = inbuflen / GCRY_GCM_BLOCK_LEN;
+ size_t nleft;
+ size_t ndone;
+
+ nleft = c->bulk.gcm_crypt (c, outbuf, inbuf, nblks, encrypt);
+ ndone = nblks - nleft;
+
+ inbuf += ndone * GCRY_GCM_BLOCK_LEN;
+ outbuf += ndone * GCRY_GCM_BLOCK_LEN;
+ inbuflen -= ndone * GCRY_GCM_BLOCK_LEN;
+ outbuflen -= ndone * GCRY_GCM_BLOCK_LEN;
+
+ if (inbuflen == 0)
+ break;
+
+ currlen = inbuflen;
+ }
+ else if (c->u_mode.gcm.mac_unused > 0
+ && inbuflen >= GCRY_GCM_BLOCK_LEN
+ + (16 - c->u_mode.gcm.mac_unused))
+ {
+ /* Handle just enough data so that cache is depleted, and on
+ * next loop iteration use bulk method. */
+ currlen = 16 - c->u_mode.gcm.mac_unused;
+
+ gcry_assert(currlen);
+ }
+ }
+
+ /* Since checksumming is done after/before encryption/decryption,
+ * process input in 24KiB chunks to keep data loaded in L1 cache for
+ * checksumming/decryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ if (!encrypt)
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, inbuf, currlen, 0);
+
+ err = gcm_ctr_encrypt(c, outbuf, outbuflen, inbuf, currlen);
+ if (err != 0)
+ return err;
+
+ if (encrypt)
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, outbuf, currlen, 0);
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_encrypt (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ static const unsigned char zerobuf[MAX_BLOCKSIZE];
+
+ if (c->spec->blocksize != GCRY_GCM_BLOCK_LEN)
+ return GPG_ERR_CIPHER_ALGO;
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (c->u_mode.gcm.datalen_over_limits)
+ return GPG_ERR_INV_LENGTH;
+ if (c->marks.tag
+ || c->u_mode.gcm.ghash_data_finalized
+ || !c->u_mode.gcm.ghash_fn)
+ return GPG_ERR_INV_STATE;
+
+ if (!c->marks.iv)
+ _gcry_cipher_gcm_setiv (c, zerobuf, GCRY_GCM_BLOCK_LEN);
+
+ if (c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode)
+ return GPG_ERR_INV_STATE;
+
+ if (!c->u_mode.gcm.ghash_aad_finalized)
+ {
+ /* Start of encryption marks end of AAD stream. */
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, NULL, 0, 1);
+ c->u_mode.gcm.ghash_aad_finalized = 1;
+ }
+
+ gcm_bytecounter_add(c->u_mode.gcm.datalen, inbuflen);
+ if (!gcm_check_datalen(c->u_mode.gcm.datalen))
+ {
+ c->u_mode.gcm.datalen_over_limits = 1;
+ return GPG_ERR_INV_LENGTH;
+ }
+
+ return gcm_crypt_inner (c, outbuf, outbuflen, inbuf, inbuflen, 1);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_decrypt (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ static const unsigned char zerobuf[MAX_BLOCKSIZE];
+
+ if (c->spec->blocksize != GCRY_GCM_BLOCK_LEN)
+ return GPG_ERR_CIPHER_ALGO;
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (c->u_mode.gcm.datalen_over_limits)
+ return GPG_ERR_INV_LENGTH;
+ if (c->marks.tag
+ || c->u_mode.gcm.ghash_data_finalized
+ || !c->u_mode.gcm.ghash_fn)
+ return GPG_ERR_INV_STATE;
+
+ if (!c->marks.iv)
+ _gcry_cipher_gcm_setiv (c, zerobuf, GCRY_GCM_BLOCK_LEN);
+
+ if (!c->u_mode.gcm.ghash_aad_finalized)
+ {
+ /* Start of decryption marks end of AAD stream. */
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, NULL, 0, 1);
+ c->u_mode.gcm.ghash_aad_finalized = 1;
+ }
+
+ gcm_bytecounter_add(c->u_mode.gcm.datalen, inbuflen);
+ if (!gcm_check_datalen(c->u_mode.gcm.datalen))
+ {
+ c->u_mode.gcm.datalen_over_limits = 1;
+ return GPG_ERR_INV_LENGTH;
+ }
+
+ return gcm_crypt_inner (c, outbuf, outbuflen, inbuf, inbuflen, 0);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_authenticate (gcry_cipher_hd_t c,
+ const byte * aadbuf, size_t aadbuflen)
+{
+ static const unsigned char zerobuf[MAX_BLOCKSIZE];
+
+ if (c->spec->blocksize != GCRY_GCM_BLOCK_LEN)
+ return GPG_ERR_CIPHER_ALGO;
+ if (c->u_mode.gcm.datalen_over_limits)
+ return GPG_ERR_INV_LENGTH;
+ if (c->marks.tag
+ || c->u_mode.gcm.ghash_aad_finalized
+ || c->u_mode.gcm.ghash_data_finalized
+ || !c->u_mode.gcm.ghash_fn)
+ return GPG_ERR_INV_STATE;
+
+ if (!c->marks.iv)
+ _gcry_cipher_gcm_setiv (c, zerobuf, GCRY_GCM_BLOCK_LEN);
+
+ gcm_bytecounter_add(c->u_mode.gcm.aadlen, aadbuflen);
+ if (!gcm_check_aadlen_or_ivlen(c->u_mode.gcm.aadlen))
+ {
+ c->u_mode.gcm.datalen_over_limits = 1;
+ return GPG_ERR_INV_LENGTH;
+ }
+
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, aadbuf, aadbuflen, 0);
+
+ return 0;
+}
+
+
+void
+_gcry_cipher_gcm_setkey (gcry_cipher_hd_t c)
+{
+ memset (c->u_mode.gcm.u_ghash_key.key, 0, GCRY_GCM_BLOCK_LEN);
+
+ c->spec->encrypt (&c->context.c, c->u_mode.gcm.u_ghash_key.key,
+ c->u_mode.gcm.u_ghash_key.key);
+ setupM (c);
+}
+
+
+static gcry_err_code_t
+_gcry_cipher_gcm_initiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
+{
+ memset (c->u_mode.gcm.aadlen, 0, sizeof(c->u_mode.gcm.aadlen));
+ memset (c->u_mode.gcm.datalen, 0, sizeof(c->u_mode.gcm.datalen));
+ memset (c->u_mode.gcm.u_tag.tag, 0, GCRY_GCM_BLOCK_LEN);
+ c->u_mode.gcm.datalen_over_limits = 0;
+ c->u_mode.gcm.ghash_data_finalized = 0;
+ c->u_mode.gcm.ghash_aad_finalized = 0;
+
+ if (ivlen == 0)
+ return GPG_ERR_INV_LENGTH;
+
+ if (ivlen != GCRY_GCM_BLOCK_LEN - 4)
+ {
+ u32 iv_bytes[2] = {0, 0};
+ u32 bitlengths[2][2];
+
+ if (!c->u_mode.gcm.ghash_fn)
+ return GPG_ERR_INV_STATE;
+
+ memset(c->u_ctr.ctr, 0, GCRY_GCM_BLOCK_LEN);
+
+ gcm_bytecounter_add(iv_bytes, ivlen);
+ if (!gcm_check_aadlen_or_ivlen(iv_bytes))
+ {
+ c->u_mode.gcm.datalen_over_limits = 1;
+ return GPG_ERR_INV_LENGTH;
+ }
+
+ do_ghash_buf(c, c->u_ctr.ctr, iv, ivlen, 1);
+
+ /* iv length, 64-bit */
+ bitlengths[1][1] = be_bswap32(iv_bytes[0] << 3);
+ bitlengths[1][0] = be_bswap32((iv_bytes[0] >> 29) |
+ (iv_bytes[1] << 3));
+ /* zeros, 64-bit */
+ bitlengths[0][1] = 0;
+ bitlengths[0][0] = 0;
+
+ do_ghash_buf(c, c->u_ctr.ctr, (byte*)bitlengths, GCRY_GCM_BLOCK_LEN, 1);
+
+ wipememory (iv_bytes, sizeof iv_bytes);
+ wipememory (bitlengths, sizeof bitlengths);
+ }
+ else
+ {
+ /* 96-bit IV is handled differently. */
+ memcpy (c->u_ctr.ctr, iv, ivlen);
+ c->u_ctr.ctr[12] = c->u_ctr.ctr[13] = c->u_ctr.ctr[14] = 0;
+ c->u_ctr.ctr[15] = 1;
+ }
+
+ c->spec->encrypt (&c->context.c, c->u_mode.gcm.tagiv, c->u_ctr.ctr);
+
+ gcm_add32_be128 (c->u_ctr.ctr, 1);
+
+ c->unused = 0;
+ c->marks.iv = 1;
+ c->marks.tag = 0;
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
+{
+ c->marks.iv = 0;
+ c->marks.tag = 0;
+ c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode = 0;
+
+ if (fips_mode ())
+ {
+ /* Direct invocation of GCM setiv in FIPS mode disables encryption. */
+ c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode = 1;
+ }
+
+ return _gcry_cipher_gcm_initiv (c, iv, ivlen);
+}
+
+
+#if 0 && TODO
+void
+_gcry_cipher_gcm_geniv (gcry_cipher_hd_t c,
+ byte *ivout, size_t ivoutlen, const byte *nonce,
+ size_t noncelen)
+{
+ /* nonce: user provided part (might be null) */
+ /* noncelen: check if proper length (if nonce not null) */
+ /* ivout: iv used to initialize gcm, output to user */
+ /* ivoutlen: check correct size */
+ byte iv[IVLEN];
+
+ if (!ivout)
+ return GPG_ERR_INV_ARG;
+ if (ivoutlen != IVLEN)
+ return GPG_ERR_INV_LENGTH;
+ if (nonce != NULL && !is_nonce_ok_len(noncelen))
+ return GPG_ERR_INV_ARG;
+
+ gcm_generate_iv(iv, nonce, noncelen);
+
+ c->marks.iv = 0;
+ c->marks.tag = 0;
+ c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode = 0;
+
+ _gcry_cipher_gcm_initiv (c, iv, IVLEN);
+
+ buf_cpy(ivout, iv, IVLEN);
+ wipememory(iv, sizeof(iv));
+}
+#endif
+
+
+static int
+is_tag_length_valid(size_t taglen)
+{
+ switch (taglen)
+ {
+ /* Allowed tag lengths from NIST SP 800-38D. */
+ case 128 / 8: /* GCRY_GCM_BLOCK_LEN */
+ case 120 / 8:
+ case 112 / 8:
+ case 104 / 8:
+ case 96 / 8:
+ case 64 / 8:
+ case 32 / 8:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+static gcry_err_code_t
+_gcry_cipher_gcm_tag (gcry_cipher_hd_t c,
+ byte * outbuf, size_t outbuflen, int check)
+{
+ if (!(is_tag_length_valid (outbuflen) || outbuflen >= GCRY_GCM_BLOCK_LEN))
+ return GPG_ERR_INV_LENGTH;
+ if (c->u_mode.gcm.datalen_over_limits)
+ return GPG_ERR_INV_LENGTH;
+
+ if (!c->marks.tag)
+ {
+ u32 bitlengths[2][2];
+
+ if (!c->u_mode.gcm.ghash_fn)
+ return GPG_ERR_INV_STATE;
+
+ /* aad length */
+ bitlengths[0][1] = be_bswap32(c->u_mode.gcm.aadlen[0] << 3);
+ bitlengths[0][0] = be_bswap32((c->u_mode.gcm.aadlen[0] >> 29) |
+ (c->u_mode.gcm.aadlen[1] << 3));
+ /* data length */
+ bitlengths[1][1] = be_bswap32(c->u_mode.gcm.datalen[0] << 3);
+ bitlengths[1][0] = be_bswap32((c->u_mode.gcm.datalen[0] >> 29) |
+ (c->u_mode.gcm.datalen[1] << 3));
+
+ /* Finalize data-stream. */
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, NULL, 0, 1);
+ c->u_mode.gcm.ghash_aad_finalized = 1;
+ c->u_mode.gcm.ghash_data_finalized = 1;
+
+ /* Add bitlengths to tag. */
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, (byte*)bitlengths,
+ GCRY_GCM_BLOCK_LEN, 1);
+ cipher_block_xor (c->u_mode.gcm.u_tag.tag, c->u_mode.gcm.tagiv,
+ c->u_mode.gcm.u_tag.tag, GCRY_GCM_BLOCK_LEN);
+ c->marks.tag = 1;
+
+ wipememory (bitlengths, sizeof (bitlengths));
+ wipememory (c->u_mode.gcm.macbuf, GCRY_GCM_BLOCK_LEN);
+ wipememory (c->u_mode.gcm.tagiv, GCRY_GCM_BLOCK_LEN);
+ wipememory (c->u_mode.gcm.aadlen, sizeof (c->u_mode.gcm.aadlen));
+ wipememory (c->u_mode.gcm.datalen, sizeof (c->u_mode.gcm.datalen));
+ }
+
+ if (!check)
+ {
+ if (outbuflen > GCRY_GCM_BLOCK_LEN)
+ outbuflen = GCRY_GCM_BLOCK_LEN;
+
+ /* NB: We already checked that OUTBUF is large enough to hold
+ * the result or has valid truncated length. */
+ memcpy (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen);
+ }
+ else
+ {
+ /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF
+ * and thus we need to compare its length first. */
+ if (!is_tag_length_valid (outbuflen)
+ || !buf_eq_const (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen))
+ return GPG_ERR_CHECKSUM;
+ }
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_get_tag (gcry_cipher_hd_t c, unsigned char *outtag,
+ size_t taglen)
+{
+ /* Outputting authentication tag is part of encryption. */
+ if (c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode)
+ return GPG_ERR_INV_STATE;
+
+ return _gcry_cipher_gcm_tag (c, outtag, taglen, 0);
+}
+
+gcry_err_code_t
+_gcry_cipher_gcm_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+ size_t taglen)
+{
+ return _gcry_cipher_gcm_tag (c, (unsigned char *) intag, taglen, 1);
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-internal.h b/comm/third_party/libgcrypt/cipher/cipher-internal.h
new file mode 100644
index 0000000000..59b36ce78b
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-internal.h
@@ -0,0 +1,809 @@
+/* cipher-internal.h - Internal defs for cipher.c
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G10_CIPHER_INTERNAL_H
+#define G10_CIPHER_INTERNAL_H
+
+#include "./poly1305-internal.h"
+
+
+/* The maximum supported size of a block in bytes. */
+#define MAX_BLOCKSIZE 16
+
+/* The length for an OCB block. Although OCB supports any block
+ length it does not make sense to use a 64 bit blocklen (and cipher)
+ because this reduces the security margin to an unacceptable state.
+ Thus we require a cipher with 128 bit blocklength. */
+#define OCB_BLOCK_LEN (128/8)
+
+/* The size of the pre-computed L table for OCB. This takes the same
+ size as the table used for GCM and thus we don't save anything by
+ not using such a table. */
+#define OCB_L_TABLE_SIZE 16
+
+
+/* Check the above constants. */
+#if OCB_BLOCK_LEN > MAX_BLOCKSIZE
+# error OCB_BLOCKLEN > MAX_BLOCKSIZE
+#endif
+
+
+
+/* Magic values for the context structure. */
+#define CTX_MAGIC_NORMAL 0x24091964
+#define CTX_MAGIC_SECURE 0x46919042
+
+/* Try to use 16 byte aligned cipher context for better performance.
+ We use the aligned attribute, thus it is only possible to implement
+ this with gcc. */
+#undef NEED_16BYTE_ALIGNED_CONTEXT
+#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# define NEED_16BYTE_ALIGNED_CONTEXT 1
+#endif
+
+/* Undef this symbol to trade GCM speed for 256 bytes of memory per context */
+#define GCM_USE_TABLES 1
+
+
+/* GCM_USE_INTEL_PCLMUL indicates whether to compile GCM with Intel PCLMUL
+ code. */
+#undef GCM_USE_INTEL_PCLMUL
+#if defined(ENABLE_PCLMUL_SUPPORT) && defined(GCM_USE_TABLES)
+# if ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
+# if __GNUC__ >= 4
+# define GCM_USE_INTEL_PCLMUL 1
+# endif
+# endif
+#endif /* GCM_USE_INTEL_PCLMUL */
+
+/* GCM_USE_ARM_PMULL indicates whether to compile GCM with ARMv8 PMULL code. */
+#undef GCM_USE_ARM_PMULL
+#if defined(ENABLE_ARM_CRYPTO_SUPPORT) && defined(GCM_USE_TABLES)
+# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
+ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
+ && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO)
+# define GCM_USE_ARM_PMULL 1
+# elif defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+# define GCM_USE_ARM_PMULL 1
+# endif
+#endif /* GCM_USE_ARM_PMULL */
+
+/* GCM_USE_ARM_NEON indicates whether to compile GCM with ARMv7 NEON code. */
+#undef GCM_USE_ARM_NEON
+#if defined(GCM_USE_TABLES)
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_NEON)
+# define GCM_USE_ARM_NEON 1
+#endif
+#endif /* GCM_USE_ARM_NEON */
+
+/* GCM_USE_S390X_CRYPTO indicates whether to enable zSeries code. */
+#undef GCM_USE_S390X_CRYPTO
+#if defined(HAVE_GCC_INLINE_ASM_S390X)
+# define GCM_USE_S390X_CRYPTO 1
+#endif /* GCM_USE_S390X_CRYPTO */
+
+typedef unsigned int (*ghash_fn_t) (gcry_cipher_hd_t c, byte *result,
+ const byte *buf, size_t nblocks);
+
+
+/* A structure with function pointers for mode operations. */
+typedef struct cipher_mode_ops
+{
+ gcry_err_code_t (*encrypt)(gcry_cipher_hd_t c, unsigned char *outbuf,
+ size_t outbuflen, const unsigned char *inbuf,
+ size_t inbuflen);
+ gcry_err_code_t (*decrypt)(gcry_cipher_hd_t c, unsigned char *outbuf,
+ size_t outbuflen, const unsigned char *inbuf,
+ size_t inbuflen);
+ gcry_err_code_t (*setiv)(gcry_cipher_hd_t c, const unsigned char *iv,
+ size_t ivlen);
+
+ gcry_err_code_t (*authenticate)(gcry_cipher_hd_t c,
+ const unsigned char *abuf, size_t abuflen);
+ gcry_err_code_t (*get_tag)(gcry_cipher_hd_t c, unsigned char *outtag,
+ size_t taglen);
+ gcry_err_code_t (*check_tag)(gcry_cipher_hd_t c, const unsigned char *intag,
+ size_t taglen);
+} cipher_mode_ops_t;
+
+
+/* A structure with function pointers for bulk operations. The cipher
+ algorithm setkey function initializes them when bulk operations are
+ available and the actual encryption routines use them if they are
+ not NULL. */
+typedef struct cipher_bulk_ops
+{
+ void (*cfb_enc)(void *context, unsigned char *iv, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks);
+ void (*cfb_dec)(void *context, unsigned char *iv, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks);
+ void (*cbc_enc)(void *context, unsigned char *iv, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks, int cbc_mac);
+ void (*cbc_dec)(void *context, unsigned char *iv, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks);
+ void (*ofb_enc)(void *context, unsigned char *iv, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks);
+ void (*ctr_enc)(void *context, unsigned char *iv, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks);
+ size_t (*ocb_crypt)(gcry_cipher_hd_t c, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks, int encrypt);
+ size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks);
+ void (*xts_crypt)(void *context, unsigned char *tweak, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks, int encrypt);
+ size_t (*gcm_crypt)(gcry_cipher_hd_t c, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks, int encrypt);
+} cipher_bulk_ops_t;
+
+
+/* A VIA processor with the Padlock engine as well as the Intel AES_NI
+ instructions require an alignment of most data on a 16 byte
+ boundary. Because we trick out the compiler while allocating the
+ context, the align attribute as used in rijndael.c does not work on
+ its own. Thus we need to make sure that the entire context
+ structure is a aligned on that boundary. We achieve this by
+ defining a new type and use that instead of our usual alignment
+ type. */
+typedef union
+{
+ PROPERLY_ALIGNED_TYPE foo;
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+ char bar[16] __attribute__ ((aligned (16)));
+#endif
+ char c[1];
+} cipher_context_alignment_t;
+
+
+/* Storage structure for CMAC, for CMAC and EAX modes. */
+typedef struct {
+ /* The initialization vector. Also contains tag after finalization. */
+ union {
+ cipher_context_alignment_t iv_align;
+ unsigned char iv[MAX_BLOCKSIZE];
+ } u_iv;
+
+ /* Subkeys for tag creation, not cleared by gcry_cipher_reset. */
+ unsigned char subkeys[2][MAX_BLOCKSIZE];
+
+ /* Space to save partial input lengths for MAC. */
+ unsigned char macbuf[MAX_BLOCKSIZE];
+
+ int mac_unused; /* Number of unprocessed bytes in MACBUF. */
+ unsigned int tag:1; /* Set to 1 if tag has been finalized. */
+} gcry_cmac_context_t;
+
+
+/* The handle structure. */
+struct gcry_cipher_handle
+{
+ int magic;
+ size_t actual_handle_size; /* Allocated size of this handle. */
+ size_t handle_offset; /* Offset to the malloced block. */
+ gcry_cipher_spec_t *spec;
+
+ /* The algorithm id. This is a hack required because the module
+ interface does not easily allow to retrieve this value. */
+ int algo;
+
+ /* A structure with function pointers for mode operations. */
+ cipher_mode_ops_t mode_ops;
+
+ /* A structure with function pointers for bulk operations. Due to
+ limitations of the module system (we don't want to change the
+ API) we need to keep these function pointers here. */
+ cipher_bulk_ops_t bulk;
+
+ int mode;
+ unsigned int flags;
+
+ struct {
+ unsigned int key:1; /* Set to 1 if a key has been set. */
+ unsigned int iv:1; /* Set to 1 if a IV has been set. */
+ unsigned int tag:1; /* Set to 1 if a tag is finalized. */
+ unsigned int finalize:1; /* Next encrypt/decrypt has the final data. */
+ unsigned int allow_weak_key:1; /* Set to 1 if weak keys are allowed. */
+ } marks;
+
+ /* The initialization vector. For best performance we make sure
+ that it is properly aligned. In particular some implementations
+ of bulk operations expect an 16 byte aligned IV. IV is also used
+ to store CBC-MAC in CCM mode; counter IV is stored in U_CTR. For
+ OCB mode it is used for the offset value. */
+ union {
+ cipher_context_alignment_t iv_align;
+ unsigned char iv[MAX_BLOCKSIZE];
+ } u_iv;
+
+ /* The counter for CTR mode. This field is also used by AESWRAP and
+ thus we can't use the U_IV union. For OCB mode it is used for
+ the checksum. */
+ union {
+ cipher_context_alignment_t iv_align;
+ unsigned char ctr[MAX_BLOCKSIZE];
+ } u_ctr;
+
+ /* Space to save an IV or CTR for chaining operations. */
+ unsigned char lastiv[MAX_BLOCKSIZE];
+ int unused; /* Number of unused bytes in LASTIV. */
+
+ union {
+ /* Mode specific storage for CCM mode. */
+ struct {
+ u64 encryptlen;
+ u64 aadlen;
+ unsigned int authlen;
+
+ /* Space to save partial input lengths for MAC. */
+ unsigned char macbuf[GCRY_CCM_BLOCK_LEN];
+ int mac_unused; /* Number of unprocessed bytes in MACBUF. */
+
+ unsigned char s0[GCRY_CCM_BLOCK_LEN];
+
+ unsigned int nonce:1; /* Set to 1 if nonce has been set. */
+ unsigned int lengths:1; /* Set to 1 if CCM length parameters has been
+ processed. */
+ } ccm;
+
+ /* Mode specific storage for Poly1305 mode. */
+ struct {
+ /* byte counter for AAD. */
+ u32 aadcount[2];
+
+ /* byte counter for data. */
+ u32 datacount[2];
+
+ unsigned int aad_finalized:1;
+ unsigned int bytecount_over_limits:1;
+
+ poly1305_context_t ctx;
+ } poly1305;
+
+ /* Mode specific storage for CMAC mode. */
+ gcry_cmac_context_t cmac;
+
+ /* Mode specific storage for EAX mode. */
+ struct {
+ /* CMAC for header (AAD). */
+ gcry_cmac_context_t cmac_header;
+
+ /* CMAC for ciphertext. */
+ gcry_cmac_context_t cmac_ciphertext;
+ } eax;
+
+ /* Mode specific storage for GCM mode. */
+ struct {
+ /* The interim tag for GCM mode. */
+ union {
+ cipher_context_alignment_t iv_align;
+ unsigned char tag[MAX_BLOCKSIZE];
+ } u_tag;
+
+ /* Space to save partial input lengths for MAC. */
+ unsigned char macbuf[GCRY_CCM_BLOCK_LEN];
+ int mac_unused; /* Number of unprocessed bytes in MACBUF. */
+
+ /* byte counters for GCM */
+ u32 aadlen[2];
+ u32 datalen[2];
+
+ /* encrypted tag counter */
+ unsigned char tagiv[MAX_BLOCKSIZE];
+
+ unsigned int ghash_data_finalized:1;
+ unsigned int ghash_aad_finalized:1;
+
+ unsigned int datalen_over_limits:1;
+ unsigned int disallow_encryption_because_of_setiv_in_fips_mode:1;
+
+ /* --- Following members are not cleared in gcry_cipher_reset --- */
+
+ /* GHASH multiplier from key. */
+ union {
+ cipher_context_alignment_t iv_align;
+ unsigned char key[MAX_BLOCKSIZE];
+ } u_ghash_key;
+
+ /* GHASH implementation in use. */
+ ghash_fn_t ghash_fn;
+
+ /* Pre-calculated table for GCM. */
+#ifdef GCM_USE_TABLES
+ #if (SIZEOF_UNSIGNED_LONG == 8 || defined(__x86_64__))
+ #define GCM_TABLES_USE_U64 1
+ u64 gcm_table[4 * 16];
+ #else
+ #undef GCM_TABLES_USE_U64
+ u32 gcm_table[8 * 16];
+ #endif
+#endif
+ } gcm;
+
+ /* Mode specific storage for OCB mode. */
+ struct {
+ /* --- Following members are not cleared in gcry_cipher_reset --- */
+
+ /* Helper variables and pre-computed table of L values. */
+ unsigned char L_star[OCB_BLOCK_LEN];
+ unsigned char L_dollar[OCB_BLOCK_LEN];
+ unsigned char L0L1[OCB_BLOCK_LEN];
+ unsigned char L[OCB_L_TABLE_SIZE][OCB_BLOCK_LEN];
+
+ /* --- Following members are cleared in gcry_cipher_reset --- */
+
+ /* The tag is valid if marks.tag has been set. */
+ unsigned char tag[OCB_BLOCK_LEN];
+
+ /* A buffer to hold the offset for the AAD processing. */
+ unsigned char aad_offset[OCB_BLOCK_LEN];
+
+ /* A buffer to hold the current sum of AAD processing. We can't
+ use tag here because tag may already hold the preprocessed
+ checksum of the data. */
+ unsigned char aad_sum[OCB_BLOCK_LEN];
+
+ /* A buffer to store AAD data not yet processed. */
+ unsigned char aad_leftover[OCB_BLOCK_LEN];
+
+ /* Number of data/aad blocks processed so far. */
+ u64 data_nblocks;
+ u64 aad_nblocks;
+
+ /* Number of valid bytes in AAD_LEFTOVER. */
+ unsigned char aad_nleftover;
+
+ /* Length of the tag. Fixed for now but may eventually be
+ specified using a set of gcry_cipher_flags. */
+ unsigned char taglen;
+
+ /* Flags indicating that the final data/aad block has been
+ processed. */
+ unsigned int data_finalized:1;
+ unsigned int aad_finalized:1;
+ } ocb;
+
+ /* Mode specific storage for XTS mode. */
+ struct {
+ /* Pointer to tweak cipher context, allocated after actual
+ * cipher context. */
+ char *tweak_context;
+ } xts;
+ } u_mode;
+
+ /* What follows are two contexts of the cipher in use. The first
+ one needs to be aligned well enough for the cipher operation
+ whereas the second one is a copy created by cipher_setkey and
+ used by cipher_reset. That second copy has no need for proper
+ aligment because it is only accessed by memcpy. */
+ cipher_context_alignment_t context;
+};
+
+
+/*-- cipher-cbc.c --*/
+gcry_err_code_t _gcry_cipher_cbc_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_cbc_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_cbc_cts_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_cbc_cts_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+
+/*-- cipher-cfb.c --*/
+gcry_err_code_t _gcry_cipher_cfb_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_cfb_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_cfb8_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_cfb8_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+
+
+/*-- cipher-ofb.c --*/
+gcry_err_code_t _gcry_cipher_ofb_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+
+/*-- cipher-ctr.c --*/
+gcry_err_code_t _gcry_cipher_ctr_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+
+
+/*-- cipher-aeswrap.c --*/
+gcry_err_code_t _gcry_cipher_aeswrap_encrypt
+/* */ (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_aeswrap_decrypt
+/* */ (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen);
+
+
+/*-- cipher-ccm.c --*/
+gcry_err_code_t _gcry_cipher_ccm_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_ccm_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_ccm_set_nonce
+/* */ (gcry_cipher_hd_t c, const unsigned char *nonce,
+ size_t noncelen);
+gcry_err_code_t _gcry_cipher_ccm_authenticate
+/* */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen);
+gcry_err_code_t _gcry_cipher_ccm_set_lengths
+/* */ (gcry_cipher_hd_t c, u64 encryptedlen, u64 aadlen, u64 taglen);
+gcry_err_code_t _gcry_cipher_ccm_get_tag
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_ccm_check_tag
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *intag, size_t taglen);
+
+
+/*-- cipher-cmac.c --*/
+gcry_err_code_t _gcry_cmac_generate_subkeys
+/* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx);
+gcry_err_code_t _gcry_cmac_write
+/* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx,
+ const byte * inbuf, size_t inlen);
+gcry_err_code_t _gcry_cmac_final
+/* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx);
+void _gcry_cmac_reset (gcry_cmac_context_t *ctx);
+
+
+/*-- cipher-eax.c --*/
+gcry_err_code_t _gcry_cipher_eax_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_eax_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_eax_set_nonce
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *nonce, size_t noncelen);
+gcry_err_code_t _gcry_cipher_eax_authenticate
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *aadbuf, size_t aadbuflen);
+gcry_err_code_t _gcry_cipher_eax_get_tag
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_eax_check_tag
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *intag, size_t taglen);
+gcry_err_code_t _gcry_cipher_eax_setkey
+/* */ (gcry_cipher_hd_t c);
+
+
+/*-- cipher-gcm.c --*/
+gcry_err_code_t _gcry_cipher_gcm_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_gcm_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_gcm_setiv
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *iv, size_t ivlen);
+gcry_err_code_t _gcry_cipher_gcm_authenticate
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *aadbuf, size_t aadbuflen);
+gcry_err_code_t _gcry_cipher_gcm_get_tag
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_gcm_check_tag
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *intag, size_t taglen);
+void _gcry_cipher_gcm_setkey
+/* */ (gcry_cipher_hd_t c);
+
+
+/*-- cipher-poly1305.c --*/
+gcry_err_code_t _gcry_cipher_poly1305_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_poly1305_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_poly1305_setiv
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *iv, size_t ivlen);
+gcry_err_code_t _gcry_cipher_poly1305_authenticate
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *aadbuf, size_t aadbuflen);
+gcry_err_code_t _gcry_cipher_poly1305_get_tag
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_poly1305_check_tag
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *intag, size_t taglen);
+void _gcry_cipher_poly1305_setkey
+/* */ (gcry_cipher_hd_t c);
+
+
+/*-- chacha20.c --*/
+gcry_err_code_t _gcry_chacha20_poly1305_encrypt
+/* */ (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+ size_t length);
+gcry_err_code_t _gcry_chacha20_poly1305_decrypt
+/* */ (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+ size_t length);
+
+
+/*-- cipher-ocb.c --*/
+gcry_err_code_t _gcry_cipher_ocb_encrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_ocb_decrypt
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_ocb_set_nonce
+/* */ (gcry_cipher_hd_t c, const unsigned char *nonce,
+ size_t noncelen);
+gcry_err_code_t _gcry_cipher_ocb_authenticate
+/* */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen);
+gcry_err_code_t _gcry_cipher_ocb_get_tag
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_ocb_check_tag
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *intag, size_t taglen);
+void _gcry_cipher_ocb_setkey
+/* */ (gcry_cipher_hd_t c);
+
+
+/*-- cipher-xts.c --*/
+gcry_err_code_t _gcry_cipher_xts_encrypt
+/* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_xts_decrypt
+/* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen);
+
+
+/* Return the L-value for block N. Note: 'cipher_ocb.c' ensures that N
+ * will never be multiple of 65536 (1 << OCB_L_TABLE_SIZE), thus N can
+ * be directly passed to _gcry_ctz() function and resulting index will
+ * never overflow the table. */
+static inline const unsigned char *
+ocb_get_l (gcry_cipher_hd_t c, u64 n)
+{
+ unsigned long ntz;
+
+#if ((defined(__i386__) || defined(__x86_64__)) && __GNUC__ >= 4)
+ /* Assumes that N != 0. */
+ asm ("rep;bsfl %k[low], %k[ntz]\n\t"
+ : [ntz] "=r" (ntz)
+ : [low] "r" ((unsigned long)n)
+ : "cc");
+#else
+ ntz = _gcry_ctz (n);
+#endif
+
+ return c->u_mode.ocb.L[ntz];
+}
+
+
+/* Return bit-shift of blocksize. */
+static inline unsigned int _gcry_blocksize_shift(gcry_cipher_hd_t c)
+{
+ /* Only blocksizes 8 and 16 are used. Return value in such way
+ * that compiler can optimize calling functions based on this. */
+ return c->spec->blocksize == 8 ? 3 : 4;
+}
+
+
+/* Optimized function for adding value to cipher block. */
+static inline void
+cipher_block_add(void *_dstsrc, unsigned int add, size_t blocksize)
+{
+ byte *dstsrc = _dstsrc;
+ u64 s[2];
+
+ if (blocksize == 8)
+ {
+ buf_put_be64(dstsrc + 0, buf_get_be64(dstsrc + 0) + add);
+ }
+ else /* blocksize == 16 */
+ {
+ s[0] = buf_get_be64(dstsrc + 8);
+ s[1] = buf_get_be64(dstsrc + 0);
+ s[0] += add;
+ s[1] += (s[0] < add);
+ buf_put_be64(dstsrc + 8, s[0]);
+ buf_put_be64(dstsrc + 0, s[1]);
+ }
+}
+
+
+/* Optimized function for cipher block copying */
+static inline void
+cipher_block_cpy(void *_dst, const void *_src, size_t blocksize)
+{
+ byte *dst = _dst;
+ const byte *src = _src;
+ u64 s[2];
+
+ if (blocksize == 8)
+ {
+ buf_put_he64(dst + 0, buf_get_he64(src + 0));
+ }
+ else /* blocksize == 16 */
+ {
+ s[0] = buf_get_he64(src + 0);
+ s[1] = buf_get_he64(src + 8);
+ buf_put_he64(dst + 0, s[0]);
+ buf_put_he64(dst + 8, s[1]);
+ }
+}
+
+
+/* Optimized function for cipher block xoring */
+static inline void
+cipher_block_xor(void *_dst, const void *_src1, const void *_src2,
+ size_t blocksize)
+{
+ byte *dst = _dst;
+ const byte *src1 = _src1;
+ const byte *src2 = _src2;
+ u64 s1[2];
+ u64 s2[2];
+
+ if (blocksize == 8)
+ {
+ buf_put_he64(dst + 0, buf_get_he64(src1 + 0) ^ buf_get_he64(src2 + 0));
+ }
+ else /* blocksize == 16 */
+ {
+ s1[0] = buf_get_he64(src1 + 0);
+ s1[1] = buf_get_he64(src1 + 8);
+ s2[0] = buf_get_he64(src2 + 0);
+ s2[1] = buf_get_he64(src2 + 8);
+ buf_put_he64(dst + 0, s1[0] ^ s2[0]);
+ buf_put_he64(dst + 8, s1[1] ^ s2[1]);
+ }
+}
+
+
+/* Optimized function for in-place cipher block xoring */
+static inline void
+cipher_block_xor_1(void *_dst, const void *_src, size_t blocksize)
+{
+ cipher_block_xor (_dst, _dst, _src, blocksize);
+}
+
+
+/* Optimized function for cipher block xoring with two destination cipher
+ blocks. Used mainly by CFB mode encryption. */
+static inline void
+cipher_block_xor_2dst(void *_dst1, void *_dst2, const void *_src,
+ size_t blocksize)
+{
+ byte *dst1 = _dst1;
+ byte *dst2 = _dst2;
+ const byte *src = _src;
+ u64 d2[2];
+ u64 s[2];
+
+ if (blocksize == 8)
+ {
+ d2[0] = buf_get_he64(dst2 + 0) ^ buf_get_he64(src + 0);
+ buf_put_he64(dst2 + 0, d2[0]);
+ buf_put_he64(dst1 + 0, d2[0]);
+ }
+ else /* blocksize == 16 */
+ {
+ s[0] = buf_get_he64(src + 0);
+ s[1] = buf_get_he64(src + 8);
+ d2[0] = buf_get_he64(dst2 + 0);
+ d2[1] = buf_get_he64(dst2 + 8);
+ d2[0] = d2[0] ^ s[0];
+ d2[1] = d2[1] ^ s[1];
+ buf_put_he64(dst2 + 0, d2[0]);
+ buf_put_he64(dst2 + 8, d2[1]);
+ buf_put_he64(dst1 + 0, d2[0]);
+ buf_put_he64(dst1 + 8, d2[1]);
+ }
+}
+
+
+/* Optimized function for combined cipher block xoring and copying.
+ Used by mainly CBC mode decryption. */
+static inline void
+cipher_block_xor_n_copy_2(void *_dst_xor, const void *_src_xor,
+ void *_srcdst_cpy, const void *_src_cpy,
+ size_t blocksize)
+{
+ byte *dst_xor = _dst_xor;
+ byte *srcdst_cpy = _srcdst_cpy;
+ const byte *src_xor = _src_xor;
+ const byte *src_cpy = _src_cpy;
+ u64 sc[2];
+ u64 sx[2];
+ u64 sdc[2];
+
+ if (blocksize == 8)
+ {
+ sc[0] = buf_get_he64(src_cpy + 0);
+ buf_put_he64(dst_xor + 0,
+ buf_get_he64(srcdst_cpy + 0) ^ buf_get_he64(src_xor + 0));
+ buf_put_he64(srcdst_cpy + 0, sc[0]);
+ }
+ else /* blocksize == 16 */
+ {
+ sc[0] = buf_get_he64(src_cpy + 0);
+ sc[1] = buf_get_he64(src_cpy + 8);
+ sx[0] = buf_get_he64(src_xor + 0);
+ sx[1] = buf_get_he64(src_xor + 8);
+ sdc[0] = buf_get_he64(srcdst_cpy + 0);
+ sdc[1] = buf_get_he64(srcdst_cpy + 8);
+ sx[0] ^= sdc[0];
+ sx[1] ^= sdc[1];
+ buf_put_he64(dst_xor + 0, sx[0]);
+ buf_put_he64(dst_xor + 8, sx[1]);
+ buf_put_he64(srcdst_cpy + 0, sc[0]);
+ buf_put_he64(srcdst_cpy + 8, sc[1]);
+ }
+}
+
+
+/* Optimized function for combined cipher block xoring and copying.
+ Used by mainly CFB mode decryption. */
+static inline void
+cipher_block_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src,
+ size_t blocksize)
+{
+ cipher_block_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, blocksize);
+}
+
+
+#endif /*G10_CIPHER_INTERNAL_H*/
diff --git a/comm/third_party/libgcrypt/cipher/cipher-ocb.c b/comm/third_party/libgcrypt/cipher/cipher-ocb.c
new file mode 100644
index 0000000000..24db6a9e2c
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-ocb.c
@@ -0,0 +1,761 @@
+/* cipher-ocb.c - OCB cipher mode
+ * Copyright (C) 2015, 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * OCB is covered by several patents but may be used freely by most
+ * software. See http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm .
+ * In particular license 1 is suitable for Libgcrypt: See
+ * http://web.cs.ucdavis.edu/~rogaway/ocb/license1.pdf for the full
+ * license document; it basically says:
+ *
+ * License 1 — License for Open-Source Software Implementations of OCB
+ * (Jan 9, 2013)
+ *
+ * Under this license, you are authorized to make, use, and
+ * distribute open-source software implementations of OCB. This
+ * license terminates for you if you sue someone over their
+ * open-source software implementation of OCB claiming that you have
+ * a patent covering their implementation.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+/* Double the OCB_BLOCK_LEN sized block B in-place. */
+static inline void
+double_block (u64 b[2])
+{
+ u64 l_0, l, r;
+
+ l = b[1];
+ r = b[0];
+
+ l_0 = -(l >> 63);
+ l = (l + l) ^ (r >> 63);
+ r = (r + r) ^ (l_0 & 135);
+
+ b[1] = l;
+ b[0] = r;
+}
+
+
+/* Copy OCB_BLOCK_LEN from buffer S starting at bit offset BITOFF to
+ * buffer D. */
+static void
+bit_copy (unsigned char d[16], const unsigned char s[24], unsigned int bitoff)
+{
+ u64 s0l, s1l, s1r, s2r;
+ unsigned int shift;
+ unsigned int byteoff;
+
+ byteoff = bitoff / 8;
+ shift = bitoff % 8;
+
+ s0l = buf_get_be64 (s + byteoff + 0);
+ s1l = buf_get_be64 (s + byteoff + 8);
+ s1r = shift ? s1l : 0;
+ s2r = shift ? buf_get_be64 (s + 16) << (8 * byteoff) : 0;
+
+ buf_put_be64 (d + 0, (s0l << shift) | (s1r >> ((64 - shift) & 63)));
+ buf_put_be64 (d + 8, (s1l << shift) | (s2r >> ((64 - shift) & 63)));
+}
+
+
+/* Get L_big value for block N, where N is multiple of 65536. */
+static void
+ocb_get_L_big (gcry_cipher_hd_t c, u64 n, unsigned char *l_buf)
+{
+ int ntz = _gcry_ctz64 (n);
+ u64 L[2];
+
+ gcry_assert(ntz >= OCB_L_TABLE_SIZE);
+
+ L[1] = buf_get_be64 (c->u_mode.ocb.L[OCB_L_TABLE_SIZE - 1]);
+ L[0] = buf_get_be64 (c->u_mode.ocb.L[OCB_L_TABLE_SIZE - 1] + 8);
+
+ for (ntz -= OCB_L_TABLE_SIZE - 1; ntz; ntz--)
+ double_block (L);
+
+ buf_put_be64 (l_buf + 0, L[1]);
+ buf_put_be64 (l_buf + 8, L[0]);
+}
+
+
+/* Called after key has been set. Sets up L table. */
+void _gcry_cipher_ocb_setkey (gcry_cipher_hd_t c)
+{
+ unsigned char ktop[OCB_BLOCK_LEN];
+ unsigned int burn = 0;
+ unsigned int nburn;
+ u64 L[2];
+ int i;
+
+ /* L_star = E(zero_128) */
+ memset (ktop, 0, OCB_BLOCK_LEN);
+ nburn = c->spec->encrypt (&c->context.c, c->u_mode.ocb.L_star, ktop);
+ burn = nburn > burn ? nburn : burn;
+ /* L_dollar = double(L_star) */
+ L[1] = buf_get_be64 (c->u_mode.ocb.L_star);
+ L[0] = buf_get_be64 (c->u_mode.ocb.L_star + 8);
+ double_block (L);
+ buf_put_be64 (c->u_mode.ocb.L_dollar + 0, L[1]);
+ buf_put_be64 (c->u_mode.ocb.L_dollar + 8, L[0]);
+ /* L_0 = double(L_dollar), ... */
+ double_block (L);
+ buf_put_be64 (c->u_mode.ocb.L[0] + 0, L[1]);
+ buf_put_be64 (c->u_mode.ocb.L[0] + 8, L[0]);
+ for (i = 1; i < OCB_L_TABLE_SIZE; i++)
+ {
+ double_block (L);
+ buf_put_be64 (c->u_mode.ocb.L[i] + 0, L[1]);
+ buf_put_be64 (c->u_mode.ocb.L[i] + 8, L[0]);
+ }
+ /* Precalculated offset L0+L1 */
+ cipher_block_xor (c->u_mode.ocb.L0L1,
+ c->u_mode.ocb.L[0], c->u_mode.ocb.L[1], OCB_BLOCK_LEN);
+
+ /* Cleanup */
+ wipememory (ktop, sizeof ktop);
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4*sizeof(void*));
+}
+
+
+/* Set the nonce for OCB. This requires that the key has been set.
+ Using it again resets start a new encryption cycle using the same
+ key. */
+gcry_err_code_t
+_gcry_cipher_ocb_set_nonce (gcry_cipher_hd_t c, const unsigned char *nonce,
+ size_t noncelen)
+{
+ unsigned char ktop[OCB_BLOCK_LEN];
+ unsigned char stretch[OCB_BLOCK_LEN + 8];
+ unsigned int bottom;
+ unsigned int burn = 0;
+ unsigned int nburn;
+
+ /* Check args. */
+ if (!c->marks.key)
+ return GPG_ERR_INV_STATE; /* Key must have been set first. */
+ switch (c->u_mode.ocb.taglen)
+ {
+ case 8:
+ case 12:
+ case 16:
+ break;
+ default:
+ return GPG_ERR_BUG; /* Invalid tag length. */
+ }
+
+ if (c->spec->blocksize != OCB_BLOCK_LEN)
+ return GPG_ERR_CIPHER_ALGO;
+ if (!nonce)
+ return GPG_ERR_INV_ARG;
+ /* 120 bit is the allowed maximum. In addition we impose a minimum
+ of 64 bit. */
+ if (noncelen > (120/8) || noncelen < (64/8) || noncelen >= OCB_BLOCK_LEN)
+ return GPG_ERR_INV_LENGTH;
+
+ /* Prepare the nonce. */
+ memset (ktop, 0, OCB_BLOCK_LEN);
+ buf_cpy (ktop + (OCB_BLOCK_LEN - noncelen), nonce, noncelen);
+ ktop[0] = ((c->u_mode.ocb.taglen * 8) % 128) << 1;
+ ktop[OCB_BLOCK_LEN - noncelen - 1] |= 1;
+ bottom = ktop[OCB_BLOCK_LEN - 1] & 0x3f;
+ ktop[OCB_BLOCK_LEN - 1] &= 0xc0; /* Zero the bottom bits. */
+ nburn = c->spec->encrypt (&c->context.c, ktop, ktop);
+ burn = nburn > burn ? nburn : burn;
+ /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
+ cipher_block_cpy (stretch, ktop, OCB_BLOCK_LEN);
+ cipher_block_xor (stretch + OCB_BLOCK_LEN, ktop, ktop + 1, 8);
+ /* Offset_0 = Stretch[1+bottom..128+bottom]
+ (We use the IV field to store the offset) */
+ bit_copy (c->u_iv.iv, stretch, bottom);
+ c->marks.iv = 1;
+
+ /* Checksum_0 = zeros(128)
+ (We use the CTR field to store the checksum) */
+ memset (c->u_ctr.ctr, 0, OCB_BLOCK_LEN);
+
+ /* Clear AAD buffer. */
+ memset (c->u_mode.ocb.aad_offset, 0, OCB_BLOCK_LEN);
+ memset (c->u_mode.ocb.aad_sum, 0, OCB_BLOCK_LEN);
+
+ /* Setup other values. */
+ memset (c->lastiv, 0, sizeof(c->lastiv));
+ c->unused = 0;
+ c->marks.tag = 0;
+ c->marks.finalize = 0;
+ c->u_mode.ocb.data_nblocks = 0;
+ c->u_mode.ocb.aad_nblocks = 0;
+ c->u_mode.ocb.aad_nleftover = 0;
+ c->u_mode.ocb.data_finalized = 0;
+ c->u_mode.ocb.aad_finalized = 0;
+
+ /* log_printhex ("L_* ", c->u_mode.ocb.L_star, OCB_BLOCK_LEN); */
+ /* log_printhex ("L_$ ", c->u_mode.ocb.L_dollar, OCB_BLOCK_LEN); */
+ /* log_printhex ("L_0 ", c->u_mode.ocb.L[0], OCB_BLOCK_LEN); */
+ /* log_printhex ("L_1 ", c->u_mode.ocb.L[1], OCB_BLOCK_LEN); */
+ /* log_debug ( "bottom : %u (decimal)\n", bottom); */
+ /* log_printhex ("Ktop ", ktop, OCB_BLOCK_LEN); */
+ /* log_printhex ("Stretch ", stretch, sizeof stretch); */
+ /* log_printhex ("Offset_0 ", c->u_iv.iv, OCB_BLOCK_LEN); */
+
+ /* Cleanup */
+ wipememory (ktop, sizeof ktop);
+ wipememory (stretch, sizeof stretch);
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4*sizeof(void*));
+
+ return 0;
+}
+
+
+/* Process additional authentication data. This implementation allows
+ to add additional authentication data at any time before the final
+ gcry_cipher_gettag. */
+gcry_err_code_t
+_gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
+ size_t abuflen)
+{
+ const size_t table_maxblks = 1 << OCB_L_TABLE_SIZE;
+ const u32 table_size_mask = ((1 << OCB_L_TABLE_SIZE) - 1);
+ unsigned char l_tmp[OCB_BLOCK_LEN];
+ unsigned int burn = 0;
+ unsigned int nburn;
+ size_t n;
+
+ /* Check that a nonce and thus a key has been set and that we have
+ not yet computed the tag. We also return an error if the aad has
+ been finalized (i.e. a short block has been processed). */
+ if (!c->marks.iv || c->marks.tag || c->u_mode.ocb.aad_finalized)
+ return GPG_ERR_INV_STATE;
+
+ /* Check correct usage and arguments. */
+ if (c->spec->blocksize != OCB_BLOCK_LEN)
+ return GPG_ERR_CIPHER_ALGO;
+
+ /* Process remaining data from the last call first. */
+ if (c->u_mode.ocb.aad_nleftover)
+ {
+ n = abuflen;
+ if (n > OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover)
+ n = OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover;
+
+ buf_cpy (&c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover],
+ abuf, n);
+ c->u_mode.ocb.aad_nleftover += n;
+ abuf += n;
+ abuflen -= n;
+
+ if (c->u_mode.ocb.aad_nleftover == OCB_BLOCK_LEN)
+ {
+ c->u_mode.ocb.aad_nblocks++;
+
+ if ((c->u_mode.ocb.aad_nblocks % table_maxblks) == 0)
+ {
+ /* Table overflow, L needs to be generated. */
+ ocb_get_L_big(c, c->u_mode.ocb.aad_nblocks + 1, l_tmp);
+ }
+ else
+ {
+ cipher_block_cpy (l_tmp, ocb_get_l (c, c->u_mode.ocb.aad_nblocks),
+ OCB_BLOCK_LEN);
+ }
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN);
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset,
+ c->u_mode.ocb.aad_leftover, OCB_BLOCK_LEN);
+ nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN);
+
+ c->u_mode.ocb.aad_nleftover = 0;
+ }
+ }
+
+ if (!abuflen)
+ {
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4*sizeof(void*));
+
+ return 0;
+ }
+
+ /* Full blocks handling. */
+ while (abuflen >= OCB_BLOCK_LEN)
+ {
+ size_t nblks = abuflen / OCB_BLOCK_LEN;
+ size_t nmaxblks;
+
+ /* Check how many blocks to process till table overflow. */
+ nmaxblks = (c->u_mode.ocb.aad_nblocks + 1) % table_maxblks;
+ nmaxblks = (table_maxblks - nmaxblks) % table_maxblks;
+
+ if (nmaxblks == 0)
+ {
+ /* Table overflow, generate L and process one block. */
+ c->u_mode.ocb.aad_nblocks++;
+ ocb_get_L_big(c, c->u_mode.ocb.aad_nblocks, l_tmp);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN);
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf,
+ OCB_BLOCK_LEN);
+ nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN);
+
+ abuf += OCB_BLOCK_LEN;
+ abuflen -= OCB_BLOCK_LEN;
+ nblks--;
+
+ /* With overflow handled, retry loop again. Next overflow will
+ * happen after 65535 blocks. */
+ continue;
+ }
+
+ nblks = nblks < nmaxblks ? nblks : nmaxblks;
+
+ /* Use a bulk method if available. */
+ if (nblks && c->bulk.ocb_auth)
+ {
+ size_t nleft;
+ size_t ndone;
+
+ nleft = c->bulk.ocb_auth (c, abuf, nblks);
+ ndone = nblks - nleft;
+
+ abuf += ndone * OCB_BLOCK_LEN;
+ abuflen -= ndone * OCB_BLOCK_LEN;
+ nblks = nleft;
+ }
+
+ /* Hash all full blocks. */
+ while (nblks)
+ {
+ c->u_mode.ocb.aad_nblocks++;
+
+ gcry_assert(c->u_mode.ocb.aad_nblocks & table_size_mask);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset,
+ ocb_get_l (c, c->u_mode.ocb.aad_nblocks),
+ OCB_BLOCK_LEN);
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf,
+ OCB_BLOCK_LEN);
+ nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN);
+
+ abuf += OCB_BLOCK_LEN;
+ abuflen -= OCB_BLOCK_LEN;
+ nblks--;
+ }
+ }
+
+ /* Store away the remaining data. */
+ if (abuflen)
+ {
+ n = abuflen;
+ if (n > OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover)
+ n = OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover;
+
+ buf_cpy (&c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover],
+ abuf, n);
+ c->u_mode.ocb.aad_nleftover += n;
+ abuf += n;
+ abuflen -= n;
+ }
+
+ gcry_assert (!abuflen);
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4*sizeof(void*));
+
+ return 0;
+}
+
+
+/* Hash final partial AAD block. */
+static void
+ocb_aad_finalize (gcry_cipher_hd_t c)
+{
+ unsigned char l_tmp[OCB_BLOCK_LEN];
+ unsigned int burn = 0;
+ unsigned int nburn;
+
+ /* Check that a nonce and thus a key has been set and that we have
+ not yet computed the tag. We also skip this if the aad has been
+ finalized. */
+ if (!c->marks.iv || c->marks.tag || c->u_mode.ocb.aad_finalized)
+ return;
+ if (c->spec->blocksize != OCB_BLOCK_LEN)
+ return; /* Ooops. */
+
+ /* Hash final partial block if any. */
+ if (c->u_mode.ocb.aad_nleftover)
+ {
+ /* Offset_* = Offset_m xor L_* */
+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset,
+ c->u_mode.ocb.L_star, OCB_BLOCK_LEN);
+ /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
+ buf_cpy (l_tmp, c->u_mode.ocb.aad_leftover, c->u_mode.ocb.aad_nleftover);
+ memset (l_tmp + c->u_mode.ocb.aad_nleftover, 0,
+ OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover);
+ l_tmp[c->u_mode.ocb.aad_nleftover] = 0x80;
+ cipher_block_xor_1 (l_tmp, c->u_mode.ocb.aad_offset, OCB_BLOCK_LEN);
+ /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
+ nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN);
+
+ c->u_mode.ocb.aad_nleftover = 0;
+ }
+
+ /* Mark AAD as finalized so that gcry_cipher_ocb_authenticate can
+ * return an erro when called again. */
+ c->u_mode.ocb.aad_finalized = 1;
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4*sizeof(void*));
+}
+
+
+
+/* Checksumming for encrypt and decrypt. */
+static void
+ocb_checksum (unsigned char *chksum, const unsigned char *plainbuf,
+ size_t nblks)
+{
+ while (nblks > 0)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ cipher_block_xor_1(chksum, plainbuf, OCB_BLOCK_LEN);
+
+ plainbuf += OCB_BLOCK_LEN;
+ nblks--;
+ }
+}
+
+
+/* Common code for encrypt and decrypt. */
+static gcry_err_code_t
+ocb_crypt (gcry_cipher_hd_t c, int encrypt,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ const size_t table_maxblks = 1 << OCB_L_TABLE_SIZE;
+ const u32 table_size_mask = ((1 << OCB_L_TABLE_SIZE) - 1);
+ unsigned char l_tmp[OCB_BLOCK_LEN];
+ unsigned int burn = 0;
+ unsigned int nburn;
+ gcry_cipher_encrypt_t crypt_fn =
+ encrypt ? c->spec->encrypt : c->spec->decrypt;
+
+ /* Check that a nonce and thus a key has been set and that we are
+ not yet in end of data state. */
+ if (!c->marks.iv || c->u_mode.ocb.data_finalized)
+ return GPG_ERR_INV_STATE;
+
+ /* Check correct usage and arguments. */
+ if (c->spec->blocksize != OCB_BLOCK_LEN)
+ return GPG_ERR_CIPHER_ALGO;
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (c->marks.finalize)
+ ; /* Allow arbitarty length. */
+ else if ((inbuflen % OCB_BLOCK_LEN))
+ return GPG_ERR_INV_LENGTH; /* We support only full blocks for now. */
+
+ /* Full blocks handling. */
+ while (inbuflen >= OCB_BLOCK_LEN)
+ {
+ size_t nblks = inbuflen / OCB_BLOCK_LEN;
+ size_t nmaxblks;
+
+ /* Check how many blocks to process till table overflow. */
+ nmaxblks = (c->u_mode.ocb.data_nblocks + 1) % table_maxblks;
+ nmaxblks = (table_maxblks - nmaxblks) % table_maxblks;
+
+ if (nmaxblks == 0)
+ {
+ /* Table overflow, generate L and process one block. */
+ c->u_mode.ocb.data_nblocks++;
+ ocb_get_L_big(c, c->u_mode.ocb.data_nblocks, l_tmp);
+
+ if (encrypt)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ocb_checksum (c->u_ctr.ctr, inbuf, 1);
+ }
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ cipher_block_xor_1 (c->u_iv.iv, l_tmp, OCB_BLOCK_LEN);
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+ cipher_block_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN);
+ nburn = crypt_fn (&c->context.c, outbuf, outbuf);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN);
+
+ if (!encrypt)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ocb_checksum (c->u_ctr.ctr, outbuf, 1);
+ }
+
+ inbuf += OCB_BLOCK_LEN;
+ inbuflen -= OCB_BLOCK_LEN;
+ outbuf += OCB_BLOCK_LEN;
+ outbuflen =- OCB_BLOCK_LEN;
+ nblks--;
+
+ /* With overflow handled, retry loop again. Next overflow will
+ * happen after 65535 blocks. */
+ continue;
+ }
+
+ nblks = nblks < nmaxblks ? nblks : nmaxblks;
+
+ /* Since checksum xoring is done before/after encryption/decryption,
+ process input in 24KiB chunks to keep data loaded in L1 cache for
+ checksumming. */
+ if (nblks > 24 * 1024 / OCB_BLOCK_LEN)
+ nblks = 24 * 1024 / OCB_BLOCK_LEN;
+
+ /* Use a bulk method if available. */
+ if (nblks && c->bulk.ocb_crypt)
+ {
+ size_t nleft;
+ size_t ndone;
+
+ nleft = c->bulk.ocb_crypt (c, outbuf, inbuf, nblks, encrypt);
+ ndone = nblks - nleft;
+
+ inbuf += ndone * OCB_BLOCK_LEN;
+ outbuf += ndone * OCB_BLOCK_LEN;
+ inbuflen -= ndone * OCB_BLOCK_LEN;
+ outbuflen -= ndone * OCB_BLOCK_LEN;
+ nblks = nleft;
+ }
+
+ if (nblks)
+ {
+ size_t nblks_chksum = nblks;
+
+ if (encrypt)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ocb_checksum (c->u_ctr.ctr, inbuf, nblks_chksum);
+ }
+
+ /* Encrypt all full blocks. */
+ while (nblks)
+ {
+ c->u_mode.ocb.data_nblocks++;
+
+ gcry_assert(c->u_mode.ocb.data_nblocks & table_size_mask);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ cipher_block_xor_1 (c->u_iv.iv,
+ ocb_get_l (c, c->u_mode.ocb.data_nblocks),
+ OCB_BLOCK_LEN);
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+ cipher_block_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN);
+ nburn = crypt_fn (&c->context.c, outbuf, outbuf);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN);
+
+ inbuf += OCB_BLOCK_LEN;
+ inbuflen -= OCB_BLOCK_LEN;
+ outbuf += OCB_BLOCK_LEN;
+ outbuflen =- OCB_BLOCK_LEN;
+ nblks--;
+ }
+
+ if (!encrypt)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ocb_checksum (c->u_ctr.ctr,
+ outbuf - nblks_chksum * OCB_BLOCK_LEN,
+ nblks_chksum);
+ }
+ }
+ }
+
+ /* Encrypt final partial block. Note that we expect INBUFLEN to be
+ shorter than OCB_BLOCK_LEN (see above). */
+ if (inbuflen)
+ {
+ unsigned char pad[OCB_BLOCK_LEN];
+
+ /* Offset_* = Offset_m xor L_* */
+ cipher_block_xor_1 (c->u_iv.iv, c->u_mode.ocb.L_star, OCB_BLOCK_LEN);
+ /* Pad = ENCIPHER(K, Offset_*) */
+ nburn = c->spec->encrypt (&c->context.c, pad, c->u_iv.iv);
+ burn = nburn > burn ? nburn : burn;
+
+ if (encrypt)
+ {
+ /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
+ /* Note that INBUFLEN is less than OCB_BLOCK_LEN. */
+ buf_cpy (l_tmp, inbuf, inbuflen);
+ memset (l_tmp + inbuflen, 0, OCB_BLOCK_LEN - inbuflen);
+ l_tmp[inbuflen] = 0x80;
+ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN);
+ /* C_* = P_* xor Pad[1..bitlen(P_*)] */
+ buf_xor (outbuf, inbuf, pad, inbuflen);
+ }
+ else
+ {
+ /* P_* = C_* xor Pad[1..bitlen(C_*)] */
+ /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
+ cipher_block_cpy (l_tmp, pad, OCB_BLOCK_LEN);
+ buf_cpy (l_tmp, inbuf, inbuflen);
+ cipher_block_xor_1 (l_tmp, pad, OCB_BLOCK_LEN);
+ l_tmp[inbuflen] = 0x80;
+ buf_cpy (outbuf, l_tmp, inbuflen);
+
+ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN);
+ }
+ }
+
+ /* Compute the tag if the finalize flag has been set. */
+ if (c->marks.finalize)
+ {
+ /* Tag = ENCIPHER(K, Checksum xor Offset xor L_$) xor HASH(K,A) */
+ cipher_block_xor (c->u_mode.ocb.tag, c->u_ctr.ctr, c->u_iv.iv,
+ OCB_BLOCK_LEN);
+ cipher_block_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.L_dollar,
+ OCB_BLOCK_LEN);
+ nburn = c->spec->encrypt (&c->context.c,
+ c->u_mode.ocb.tag, c->u_mode.ocb.tag);
+ burn = nburn > burn ? nburn : burn;
+
+ c->u_mode.ocb.data_finalized = 1;
+ /* Note that the the final part of the tag computation is done
+ by _gcry_cipher_ocb_get_tag. */
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4*sizeof(void*));
+
+ return 0;
+}
+
+
+/* Encrypt (INBUF,INBUFLEN) in OCB mode to OUTBUF. OUTBUFLEN gives
+ the allocated size of OUTBUF. This function accepts only multiples
+ of a full block unless gcry_cipher_final has been called in which
+ case the next block may have any length. */
+gcry_err_code_t
+_gcry_cipher_ocb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+
+{
+ return ocb_crypt (c, 1, outbuf, outbuflen, inbuf, inbuflen);
+}
+
+
+/* Decrypt (INBUF,INBUFLEN) in OCB mode to OUTBUF. OUTBUFLEN gives
+ the allocated size of OUTBUF. This function accepts only multiples
+ of a full block unless gcry_cipher_final has been called in which
+ case the next block may have any length. */
+gcry_err_code_t
+_gcry_cipher_ocb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ return ocb_crypt (c, 0, outbuf, outbuflen, inbuf, inbuflen);
+}
+
+
+/* Compute the tag. The last data operation has already done some
+ part of it. To allow adding AAD even after having done all data,
+ we finish the tag computation only here. */
+static void
+compute_tag_if_needed (gcry_cipher_hd_t c)
+{
+ if (!c->marks.tag)
+ {
+ ocb_aad_finalize (c);
+ cipher_block_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.aad_sum,
+ OCB_BLOCK_LEN);
+ c->marks.tag = 1;
+ }
+}
+
+
+/* Copy the already computed tag to OUTTAG. OUTTAGSIZE is the
+ allocated size of OUTTAG; the function returns an error if that is
+ too short to hold the tag. */
+gcry_err_code_t
+_gcry_cipher_ocb_get_tag (gcry_cipher_hd_t c,
+ unsigned char *outtag, size_t outtagsize)
+{
+ if (c->u_mode.ocb.taglen > outtagsize)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (!c->u_mode.ocb.data_finalized)
+ return GPG_ERR_INV_STATE; /* Data has not yet been finalized. */
+
+ compute_tag_if_needed (c);
+
+ memcpy (outtag, c->u_mode.ocb.tag, c->u_mode.ocb.taglen);
+
+ return 0;
+}
+
+
+/* Check that the tag (INTAG,TAGLEN) matches the computed tag for the
+ handle C. */
+gcry_err_code_t
+_gcry_cipher_ocb_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+ size_t taglen)
+{
+ size_t n;
+
+ if (!c->u_mode.ocb.data_finalized)
+ return GPG_ERR_INV_STATE; /* Data has not yet been finalized. */
+
+ compute_tag_if_needed (c);
+
+ n = c->u_mode.ocb.taglen;
+ if (taglen < n)
+ n = taglen;
+
+ if (!buf_eq_const (intag, c->u_mode.ocb.tag, n)
+ || c->u_mode.ocb.taglen != taglen)
+ return GPG_ERR_CHECKSUM;
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-ofb.c b/comm/third_party/libgcrypt/cipher/cipher-ofb.c
new file mode 100644
index 0000000000..09db397e65
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-ofb.c
@@ -0,0 +1,108 @@
+/* cipher-ofb.c - Generic OFB mode implementation
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+gcry_err_code_t
+_gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ unsigned char *ivp;
+ gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+ size_t blocksize_shift = _gcry_blocksize_shift(c);
+ size_t blocksize = 1 << blocksize_shift;
+ unsigned int burn, nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ( inbuflen <= c->unused )
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ /* XOR the input with the IV */
+ ivp = c->u_iv.iv + blocksize - c->unused;
+ buf_xor(outbuf, ivp, inbuf, inbuflen);
+ c->unused -= inbuflen;
+ return 0;
+ }
+
+ burn = 0;
+
+ if( c->unused )
+ {
+ inbuflen -= c->unused;
+ ivp = c->u_iv.iv + blocksize - c->unused;
+ buf_xor(outbuf, ivp, inbuf, c->unused);
+ outbuf += c->unused;
+ inbuf += c->unused;
+ c->unused = 0;
+ }
+
+ /* Now we can process complete blocks. */
+ if (c->bulk.ofb_enc)
+ {
+ size_t nblocks = inbuflen >> blocksize_shift;
+ c->bulk.ofb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ outbuf += nblocks << blocksize_shift;
+ inbuf += nblocks << blocksize_shift;
+ inbuflen -= nblocks << blocksize_shift;
+ }
+ else
+ {
+ while ( inbuflen >= blocksize )
+ {
+ /* Encrypt the IV (and save the current one). */
+ nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor(outbuf, c->u_iv.iv, inbuf, blocksize);
+ outbuf += blocksize;
+ inbuf += blocksize;
+ inbuflen -= blocksize;
+ }
+ }
+
+ if ( inbuflen )
+ { /* process the remaining bytes */
+ nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ burn = nburn > burn ? nburn : burn;
+ c->unused = blocksize;
+ c->unused -= inbuflen;
+ buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen);
+ outbuf += inbuflen;
+ inbuf += inbuflen;
+ inbuflen = 0;
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-poly1305.c b/comm/third_party/libgcrypt/cipher/cipher-poly1305.c
new file mode 100644
index 0000000000..bb475236b8
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-poly1305.c
@@ -0,0 +1,375 @@
+/* cipher-poly1305.c - Poly1305 based AEAD cipher mode, RFC-8439
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+#include "./poly1305-internal.h"
+
+
+static inline int
+poly1305_bytecounter_add (u32 ctr[2], size_t add)
+{
+ int overflow = 0;
+
+ if (sizeof(add) > sizeof(u32))
+ {
+ u32 high_add = ((add >> 31) >> 1) & 0xffffffff;
+ ctr[1] += high_add;
+ if (ctr[1] < high_add)
+ overflow = 1;
+ }
+
+ ctr[0] += add;
+ if (ctr[0] >= add)
+ return overflow;
+
+ ctr[1] += 1;
+ return (ctr[1] < 1) || overflow;
+}
+
+
+static void
+poly1305_fill_bytecounts (gcry_cipher_hd_t c)
+{
+ u32 lenbuf[4];
+
+ lenbuf[0] = le_bswap32(c->u_mode.poly1305.aadcount[0]);
+ lenbuf[1] = le_bswap32(c->u_mode.poly1305.aadcount[1]);
+ lenbuf[2] = le_bswap32(c->u_mode.poly1305.datacount[0]);
+ lenbuf[3] = le_bswap32(c->u_mode.poly1305.datacount[1]);
+ _gcry_poly1305_update (&c->u_mode.poly1305.ctx, (byte*)lenbuf,
+ sizeof(lenbuf));
+
+ wipememory(lenbuf, sizeof(lenbuf));
+}
+
+
+static void
+poly1305_do_padding (gcry_cipher_hd_t c, u32 ctr[2])
+{
+ static const byte zero_padding_buf[15] = {};
+ u32 padding_count;
+
+ /* Padding to 16 byte boundary. */
+ if (ctr[0] % 16 > 0)
+ {
+ padding_count = 16 - ctr[0] % 16;
+
+ _gcry_poly1305_update (&c->u_mode.poly1305.ctx, zero_padding_buf,
+ padding_count);
+ }
+}
+
+
+static void
+poly1305_aad_finish (gcry_cipher_hd_t c)
+{
+ /* After AAD, feed padding bytes so we get 16 byte alignment. */
+ poly1305_do_padding (c, c->u_mode.poly1305.aadcount);
+
+ /* Start of encryption marks end of AAD stream. */
+ c->u_mode.poly1305.aad_finalized = 1;
+
+ c->u_mode.poly1305.datacount[0] = 0;
+ c->u_mode.poly1305.datacount[1] = 0;
+}
+
+
+static gcry_err_code_t
+poly1305_set_zeroiv (gcry_cipher_hd_t c)
+{
+ byte zero[8] = { 0, };
+
+ return _gcry_cipher_poly1305_setiv (c, zero, sizeof(zero));
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_authenticate (gcry_cipher_hd_t c,
+ const byte * aadbuf, size_t aadbuflen)
+{
+ if (c->u_mode.poly1305.bytecount_over_limits)
+ return GPG_ERR_INV_LENGTH;
+ if (c->u_mode.poly1305.aad_finalized)
+ return GPG_ERR_INV_STATE;
+ if (c->marks.tag)
+ return GPG_ERR_INV_STATE;
+
+ if (!c->marks.iv)
+ poly1305_set_zeroiv(c);
+
+ if (poly1305_bytecounter_add(c->u_mode.poly1305.aadcount, aadbuflen))
+ {
+ c->u_mode.poly1305.bytecount_over_limits = 1;
+ return GPG_ERR_INV_LENGTH;
+ }
+
+ _gcry_poly1305_update (&c->u_mode.poly1305.ctx, aadbuf, aadbuflen);
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_encrypt (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ gcry_err_code_t err;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (c->marks.tag)
+ return GPG_ERR_INV_STATE;
+ if (c->u_mode.poly1305.bytecount_over_limits)
+ return GPG_ERR_INV_LENGTH;
+
+ if (!c->marks.iv)
+ {
+ err = poly1305_set_zeroiv(c);
+ if (err)
+ return err;
+ }
+
+ if (!c->u_mode.poly1305.aad_finalized)
+ poly1305_aad_finish(c);
+
+ if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen))
+ {
+ c->u_mode.poly1305.bytecount_over_limits = 1;
+ return GPG_ERR_INV_LENGTH;
+ }
+
+ if (LIKELY(inbuflen > 0) && LIKELY(c->spec->algo == GCRY_CIPHER_CHACHA20))
+ {
+ return _gcry_chacha20_poly1305_encrypt (c, outbuf, inbuf, inbuflen);
+ }
+
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done after encryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for checksumming. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ c->spec->stencrypt(&c->context.c, outbuf, (byte*)inbuf, currlen);
+
+ _gcry_poly1305_update (&c->u_mode.poly1305.ctx, outbuf, currlen);
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_decrypt (gcry_cipher_hd_t c,
+ byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ gcry_err_code_t err;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (c->marks.tag)
+ return GPG_ERR_INV_STATE;
+ if (c->u_mode.poly1305.bytecount_over_limits)
+ return GPG_ERR_INV_LENGTH;
+
+ if (!c->marks.iv)
+ {
+ err = poly1305_set_zeroiv(c);
+ if (err)
+ return err;
+ }
+
+ if (!c->u_mode.poly1305.aad_finalized)
+ poly1305_aad_finish(c);
+
+ if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen))
+ {
+ c->u_mode.poly1305.bytecount_over_limits = 1;
+ return GPG_ERR_INV_LENGTH;
+ }
+
+ if (LIKELY(inbuflen > 0) && LIKELY(c->spec->algo == GCRY_CIPHER_CHACHA20))
+ {
+ return _gcry_chacha20_poly1305_decrypt (c, outbuf, inbuf, inbuflen);
+ }
+
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done before decryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for decryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ _gcry_poly1305_update (&c->u_mode.poly1305.ctx, inbuf, currlen);
+
+ c->spec->stdecrypt(&c->context.c, outbuf, (byte*)inbuf, currlen);
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+_gcry_cipher_poly1305_tag (gcry_cipher_hd_t c,
+ byte * outbuf, size_t outbuflen, int check)
+{
+ gcry_err_code_t err;
+
+ if (outbuflen < POLY1305_TAGLEN)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (c->u_mode.poly1305.bytecount_over_limits)
+ return GPG_ERR_INV_LENGTH;
+
+ if (!c->marks.iv)
+ {
+ err = poly1305_set_zeroiv(c);
+ if (err)
+ return err;
+ }
+
+ if (!c->u_mode.poly1305.aad_finalized)
+ poly1305_aad_finish(c);
+
+ if (!c->marks.tag)
+ {
+ /* After data, feed padding bytes so we get 16 byte alignment. */
+ poly1305_do_padding (c, c->u_mode.poly1305.datacount);
+
+ /* Write byte counts to poly1305. */
+ poly1305_fill_bytecounts(c);
+
+ _gcry_poly1305_finish(&c->u_mode.poly1305.ctx, c->u_iv.iv);
+
+ c->marks.tag = 1;
+ }
+
+ if (!check)
+ {
+ memcpy (outbuf, c->u_iv.iv, POLY1305_TAGLEN);
+ }
+ else
+ {
+ /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF
+ * and thus we need to compare its length first. */
+ if (outbuflen != POLY1305_TAGLEN
+ || !buf_eq_const (outbuf, c->u_iv.iv, POLY1305_TAGLEN))
+ return GPG_ERR_CHECKSUM;
+ }
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_get_tag (gcry_cipher_hd_t c, unsigned char *outtag,
+ size_t taglen)
+{
+ return _gcry_cipher_poly1305_tag (c, outtag, taglen, 0);
+}
+
+gcry_err_code_t
+_gcry_cipher_poly1305_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+ size_t taglen)
+{
+ return _gcry_cipher_poly1305_tag (c, (unsigned char *) intag, taglen, 1);
+}
+
+
+void
+_gcry_cipher_poly1305_setkey (gcry_cipher_hd_t c)
+{
+ c->u_mode.poly1305.aadcount[0] = 0;
+ c->u_mode.poly1305.aadcount[1] = 0;
+
+ c->u_mode.poly1305.datacount[0] = 0;
+ c->u_mode.poly1305.datacount[1] = 0;
+
+ c->u_mode.poly1305.bytecount_over_limits = 0;
+ c->u_mode.poly1305.aad_finalized = 0;
+ c->marks.tag = 0;
+ c->marks.iv = 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_poly1305_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
+{
+ byte tmpbuf[64]; /* size of ChaCha20 block */
+ gcry_err_code_t err;
+
+ /* IV must be 96-bits */
+ if (!iv && ivlen != (96 / 8))
+ return GPG_ERR_INV_ARG;
+
+ memset(&c->u_mode.poly1305.ctx, 0, sizeof(c->u_mode.poly1305.ctx));
+
+ c->u_mode.poly1305.aadcount[0] = 0;
+ c->u_mode.poly1305.aadcount[1] = 0;
+
+ c->u_mode.poly1305.datacount[0] = 0;
+ c->u_mode.poly1305.datacount[1] = 0;
+
+ c->u_mode.poly1305.bytecount_over_limits = 0;
+ c->u_mode.poly1305.aad_finalized = 0;
+ c->marks.tag = 0;
+ c->marks.iv = 0;
+
+ /* Set up IV for stream cipher. */
+ c->spec->setiv (&c->context.c, iv, ivlen);
+
+ /* Get the first block from ChaCha20. */
+ memset(tmpbuf, 0, sizeof(tmpbuf));
+ c->spec->stencrypt(&c->context.c, tmpbuf, tmpbuf, sizeof(tmpbuf));
+
+ /* Use the first 32-bytes as Poly1305 key. */
+ err = _gcry_poly1305_init (&c->u_mode.poly1305.ctx, tmpbuf, POLY1305_KEYLEN);
+
+ wipememory(tmpbuf, sizeof(tmpbuf));
+
+ if (err)
+ return err;
+
+ c->marks.iv = 1;
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher-selftest.c b/comm/third_party/libgcrypt/cipher/cipher-selftest.c
new file mode 100644
index 0000000000..d7f38a4261
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-selftest.c
@@ -0,0 +1,512 @@
+/* cipher-selftest.c - Helper functions for bulk encryption selftests.
+ * Copyright (C) 2013,2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#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 <stdint.h> /* uintptr_t */
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#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 <block cipher>-CBC-<block size>, 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 <block cipher>-CFB-<block size>, 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 <block cipher>-CTR-<block size>, 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/comm/third_party/libgcrypt/cipher/cipher-selftest.h b/comm/third_party/libgcrypt/cipher/cipher-selftest.h
new file mode 100644
index 0000000000..c3090ad122
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-selftest.h
@@ -0,0 +1,69 @@
+/* cipher-selftest.h - Helper functions for bulk encryption selftests.
+ * Copyright (C) 2013,2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G10_SELFTEST_HELP_H
+#define G10_SELFTEST_HELP_H
+
+#include <config.h>
+#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/comm/third_party/libgcrypt/cipher/cipher-xts.c b/comm/third_party/libgcrypt/cipher/cipher-xts.c
new file mode 100644
index 0000000000..0522a271a1
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher-xts.c
@@ -0,0 +1,189 @@
+/* cipher-xts.c - XTS mode implementation
+ * Copyright (C) 2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+static inline void xts_gfmul_byA (unsigned char *out, const unsigned char *in)
+{
+ u64 hi = buf_get_le64 (in + 8);
+ u64 lo = buf_get_le64 (in + 0);
+ u64 carry = -(hi >> 63) & 0x87;
+
+ hi = (hi << 1) + (lo >> 63);
+ lo = (lo << 1) ^ carry;
+
+ buf_put_le64 (out + 8, hi);
+ buf_put_le64 (out + 0, lo);
+}
+
+
+static inline void xts_inc128 (unsigned char *seqno)
+{
+ u64 lo = buf_get_le64 (seqno + 0);
+ u64 hi = buf_get_le64 (seqno + 8);
+
+ hi += !(++lo);
+
+ buf_put_le64 (seqno + 0, lo);
+ buf_put_le64 (seqno + 8, hi);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_xts_crypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen,
+ int encrypt)
+{
+ gcry_cipher_encrypt_t tweak_fn = c->spec->encrypt;
+ gcry_cipher_encrypt_t crypt_fn =
+ encrypt ? c->spec->encrypt : c->spec->decrypt;
+ union
+ {
+ cipher_context_alignment_t xcx;
+ byte x1[GCRY_XTS_BLOCK_LEN];
+ u64 x64[GCRY_XTS_BLOCK_LEN / sizeof(u64)];
+ } tmp;
+ unsigned int burn, nburn;
+ size_t nblocks;
+
+ if (c->spec->blocksize != GCRY_XTS_BLOCK_LEN)
+ return GPG_ERR_CIPHER_ALGO;
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if (inbuflen < GCRY_XTS_BLOCK_LEN)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ /* Data-unit max length: 2^20 blocks. */
+ if (inbuflen > GCRY_XTS_BLOCK_LEN << 20)
+ return GPG_ERR_INV_LENGTH;
+
+ nblocks = inbuflen / GCRY_XTS_BLOCK_LEN;
+ nblocks -= !encrypt && (inbuflen % GCRY_XTS_BLOCK_LEN) != 0;
+
+ /* Generate first tweak value. */
+ burn = tweak_fn (c->u_mode.xts.tweak_context, c->u_ctr.ctr, c->u_iv.iv);
+
+ /* Use a bulk method if available. */
+ if (nblocks && c->bulk.xts_crypt)
+ {
+ c->bulk.xts_crypt (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks,
+ encrypt);
+ inbuf += nblocks * GCRY_XTS_BLOCK_LEN;
+ outbuf += nblocks * GCRY_XTS_BLOCK_LEN;
+ inbuflen -= nblocks * GCRY_XTS_BLOCK_LEN;
+ nblocks = 0;
+ }
+
+ /* If we don't have a bulk method use the standard method. We also
+ use this method for the a remaining partial block. */
+
+ while (nblocks)
+ {
+ /* Xor-Encrypt/Decrypt-Xor block. */
+ cipher_block_xor (tmp.x64, inbuf, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN);
+ nburn = crypt_fn (&c->context.c, tmp.x1, tmp.x1);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN);
+
+ outbuf += GCRY_XTS_BLOCK_LEN;
+ inbuf += GCRY_XTS_BLOCK_LEN;
+ inbuflen -= GCRY_XTS_BLOCK_LEN;
+ nblocks--;
+
+ /* Generate next tweak. */
+ xts_gfmul_byA (c->u_ctr.ctr, c->u_ctr.ctr);
+ }
+
+ /* Handle remaining data with ciphertext stealing. */
+ if (inbuflen)
+ {
+ if (!encrypt)
+ {
+ gcry_assert (inbuflen > GCRY_XTS_BLOCK_LEN);
+ gcry_assert (inbuflen < GCRY_XTS_BLOCK_LEN * 2);
+
+ /* Generate last tweak. */
+ xts_gfmul_byA (tmp.x1, c->u_ctr.ctr);
+
+ /* Decrypt last block first. */
+ cipher_block_xor (outbuf, inbuf, tmp.x64, GCRY_XTS_BLOCK_LEN);
+ nburn = crypt_fn (&c->context.c, outbuf, outbuf);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor (outbuf, outbuf, tmp.x64, GCRY_XTS_BLOCK_LEN);
+
+ inbuflen -= GCRY_XTS_BLOCK_LEN;
+ inbuf += GCRY_XTS_BLOCK_LEN;
+ outbuf += GCRY_XTS_BLOCK_LEN;
+ }
+
+ gcry_assert (inbuflen < GCRY_XTS_BLOCK_LEN);
+ outbuf -= GCRY_XTS_BLOCK_LEN;
+
+ /* Steal ciphertext from previous block. */
+ cipher_block_cpy (tmp.x64, outbuf, GCRY_XTS_BLOCK_LEN);
+ buf_cpy (tmp.x64, inbuf, inbuflen);
+ buf_cpy (outbuf + GCRY_XTS_BLOCK_LEN, outbuf, inbuflen);
+
+ /* Decrypt/Encrypt last block. */
+ cipher_block_xor (tmp.x64, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN);
+ nburn = crypt_fn (&c->context.c, tmp.x1, tmp.x1);
+ burn = nburn > burn ? nburn : burn;
+ cipher_block_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN);
+ }
+
+ /* Auto-increment data-unit sequence number */
+ xts_inc128 (c->u_iv.iv);
+
+ wipememory (&tmp, sizeof(tmp));
+ wipememory (c->u_ctr.ctr, sizeof(c->u_ctr.ctr));
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_xts_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ return _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 1);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_xts_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ return _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 0);
+}
diff --git a/comm/third_party/libgcrypt/cipher/cipher.c b/comm/third_party/libgcrypt/cipher/cipher.c
new file mode 100644
index 0000000000..1039dff728
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/cipher.c
@@ -0,0 +1,1767 @@
+/* cipher.c - cipher dispatcher
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2005, 2007, 2008, 2009, 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "../src/gcrypt-testapi.h"
+#include "cipher.h"
+#include "./cipher-internal.h"
+
+
+/* This is the list of the default ciphers, which are included in
+ libgcrypt. */
+static gcry_cipher_spec_t * const cipher_list[] =
+ {
+#if USE_BLOWFISH
+ &_gcry_cipher_spec_blowfish,
+#endif
+#if USE_DES
+ &_gcry_cipher_spec_des,
+ &_gcry_cipher_spec_tripledes,
+#endif
+#if USE_ARCFOUR
+ &_gcry_cipher_spec_arcfour,
+#endif
+#if USE_CAST5
+ &_gcry_cipher_spec_cast5,
+#endif
+#if USE_AES
+ &_gcry_cipher_spec_aes,
+ &_gcry_cipher_spec_aes192,
+ &_gcry_cipher_spec_aes256,
+#endif
+#if USE_TWOFISH
+ &_gcry_cipher_spec_twofish,
+ &_gcry_cipher_spec_twofish128,
+#endif
+#if USE_SERPENT
+ &_gcry_cipher_spec_serpent128,
+ &_gcry_cipher_spec_serpent192,
+ &_gcry_cipher_spec_serpent256,
+#endif
+#if USE_RFC2268
+ &_gcry_cipher_spec_rfc2268_40,
+ &_gcry_cipher_spec_rfc2268_128,
+#endif
+#if USE_SEED
+ &_gcry_cipher_spec_seed,
+#endif
+#if USE_CAMELLIA
+ &_gcry_cipher_spec_camellia128,
+ &_gcry_cipher_spec_camellia192,
+ &_gcry_cipher_spec_camellia256,
+#endif
+#ifdef USE_IDEA
+ &_gcry_cipher_spec_idea,
+#endif
+#if USE_SALSA20
+ &_gcry_cipher_spec_salsa20,
+ &_gcry_cipher_spec_salsa20r12,
+#endif
+#if USE_GOST28147
+ &_gcry_cipher_spec_gost28147,
+ &_gcry_cipher_spec_gost28147_mesh,
+#endif
+#if USE_CHACHA20
+ &_gcry_cipher_spec_chacha20,
+#endif
+#if USE_SM4
+ &_gcry_cipher_spec_sm4,
+#endif
+ NULL
+ };
+
+/* Cipher implementations starting with index 0 (enum gcry_cipher_algos) */
+static gcry_cipher_spec_t * const cipher_list_algo0[] =
+ {
+ NULL, /* GCRY_CIPHER_NONE */
+#ifdef USE_IDEA
+ &_gcry_cipher_spec_idea,
+#else
+ NULL,
+#endif
+#if USE_DES
+ &_gcry_cipher_spec_tripledes,
+#else
+ NULL,
+#endif
+#if USE_CAST5
+ &_gcry_cipher_spec_cast5,
+#else
+ NULL,
+#endif
+#if USE_BLOWFISH
+ &_gcry_cipher_spec_blowfish,
+#else
+ NULL,
+#endif
+ NULL, /* GCRY_CIPHER_SAFER_SK128 */
+ NULL, /* GCRY_CIPHER_DES_SK */
+#if USE_AES
+ &_gcry_cipher_spec_aes,
+ &_gcry_cipher_spec_aes192,
+ &_gcry_cipher_spec_aes256,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_cipher_spec_twofish
+#else
+ NULL
+#endif
+ };
+
+/* Cipher implementations starting with index 301 (enum gcry_cipher_algos) */
+static gcry_cipher_spec_t * const cipher_list_algo301[] =
+ {
+#if USE_ARCFOUR
+ &_gcry_cipher_spec_arcfour,
+#else
+ NULL,
+#endif
+#if USE_DES
+ &_gcry_cipher_spec_des,
+#else
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_cipher_spec_twofish128,
+#else
+ NULL,
+#endif
+#if USE_SERPENT
+ &_gcry_cipher_spec_serpent128,
+ &_gcry_cipher_spec_serpent192,
+ &_gcry_cipher_spec_serpent256,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_RFC2268
+ &_gcry_cipher_spec_rfc2268_40,
+ &_gcry_cipher_spec_rfc2268_128,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_SEED
+ &_gcry_cipher_spec_seed,
+#else
+ NULL,
+#endif
+#if USE_CAMELLIA
+ &_gcry_cipher_spec_camellia128,
+ &_gcry_cipher_spec_camellia192,
+ &_gcry_cipher_spec_camellia256,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_SALSA20
+ &_gcry_cipher_spec_salsa20,
+ &_gcry_cipher_spec_salsa20r12,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_GOST28147
+ &_gcry_cipher_spec_gost28147,
+#else
+ NULL,
+#endif
+#if USE_CHACHA20
+ &_gcry_cipher_spec_chacha20,
+#else
+ NULL,
+#endif
+#if USE_GOST28147
+ &_gcry_cipher_spec_gost28147_mesh,
+#else
+ NULL,
+#endif
+#if USE_SM4
+ &_gcry_cipher_spec_sm4,
+#else
+ NULL,
+#endif
+ };
+
+
+static void _gcry_cipher_setup_mode_ops(gcry_cipher_hd_t c, int mode);
+
+
+static int
+map_algo (int algo)
+{
+ return algo;
+}
+
+
+/* Return the spec structure for the cipher algorithm ALGO. For
+ an unknown algorithm NULL is returned. */
+static gcry_cipher_spec_t *
+spec_from_algo (int algo)
+{
+ gcry_cipher_spec_t *spec = NULL;
+
+ algo = map_algo (algo);
+
+ if (algo >= 0 && algo < DIM(cipher_list_algo0))
+ spec = cipher_list_algo0[algo];
+ else if (algo >= 301 && algo < 301 + DIM(cipher_list_algo301))
+ spec = cipher_list_algo301[algo - 301];
+
+ if (spec)
+ gcry_assert (spec->algo == algo);
+
+ return spec;
+}
+
+
+/* Lookup a cipher's spec by its name. */
+static gcry_cipher_spec_t *
+spec_from_name (const char *name)
+{
+ gcry_cipher_spec_t *spec;
+ int idx;
+ const char **aliases;
+
+ for (idx=0; (spec = cipher_list[idx]); idx++)
+ {
+ if (!stricmp (name, spec->name))
+ return spec;
+ if (spec->aliases)
+ {
+ for (aliases = spec->aliases; *aliases; aliases++)
+ if (!stricmp (name, *aliases))
+ return spec;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Lookup a cipher's spec by its OID. */
+static gcry_cipher_spec_t *
+spec_from_oid (const char *oid)
+{
+ gcry_cipher_spec_t *spec;
+ gcry_cipher_oid_spec_t *oid_specs;
+ int idx, j;
+
+ for (idx=0; (spec = cipher_list[idx]); idx++)
+ {
+ oid_specs = spec->oids;
+ if (oid_specs)
+ {
+ for (j = 0; oid_specs[j].oid; j++)
+ if (!stricmp (oid, oid_specs[j].oid))
+ return spec;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Locate the OID in the oid table and return the spec or NULL if not
+ found. An optional "oid." or "OID." prefix in OID is ignored, the
+ OID is expected to be in standard IETF dotted notation. A pointer
+ to the OID specification of the module implementing this algorithm
+ is return in OID_SPEC unless passed as NULL.*/
+static gcry_cipher_spec_t *
+search_oid (const char *oid, gcry_cipher_oid_spec_t *oid_spec)
+{
+ gcry_cipher_spec_t *spec;
+ int i;
+
+ if (!oid)
+ return NULL;
+
+ if (!strncmp (oid, "oid.", 4) || !strncmp (oid, "OID.", 4))
+ oid += 4;
+
+ spec = spec_from_oid (oid);
+ if (spec && spec->oids)
+ {
+ for (i = 0; spec->oids[i].oid; i++)
+ if (!stricmp (oid, spec->oids[i].oid))
+ {
+ if (oid_spec)
+ *oid_spec = spec->oids[i];
+ return spec;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Map STRING to the cipher algorithm identifier. Returns the
+ algorithm ID of the cipher for the given name or 0 if the name is
+ not known. It is valid to pass NULL for STRING which results in a
+ return value of 0. */
+int
+_gcry_cipher_map_name (const char *string)
+{
+ gcry_cipher_spec_t *spec;
+
+ if (!string)
+ return 0;
+
+ /* If the string starts with a digit (optionally prefixed with
+ either "OID." or "oid."), we first look into our table of ASN.1
+ object identifiers to figure out the algorithm */
+
+ spec = search_oid (string, NULL);
+ if (spec)
+ return spec->algo;
+
+ spec = spec_from_name (string);
+ if (spec)
+ return spec->algo;
+
+ return 0;
+}
+
+
+/* Given a STRING with an OID in dotted decimal notation, this
+ function returns the cipher mode (GCRY_CIPHER_MODE_*) associated
+ with that OID or 0 if no mode is known. Passing NULL for string
+ yields a return value of 0. */
+int
+_gcry_cipher_mode_from_oid (const char *string)
+{
+ gcry_cipher_spec_t *spec;
+ gcry_cipher_oid_spec_t oid_spec;
+
+ if (!string)
+ return 0;
+
+ spec = search_oid (string, &oid_spec);
+ if (spec)
+ return oid_spec.mode;
+
+ return 0;
+}
+
+
+/* Map the cipher algorithm identifier ALGORITHM to a string
+ representing this algorithm. This string is the default name as
+ used by Libgcrypt. A "?" is returned for an unknown algorithm.
+ NULL is never returned. */
+const char *
+_gcry_cipher_algo_name (int algorithm)
+{
+ gcry_cipher_spec_t *spec;
+
+ spec = spec_from_algo (algorithm);
+ return spec? spec->name : "?";
+}
+
+
+/* Flag the cipher algorithm with the identifier ALGORITHM as
+ disabled. There is no error return, the function does nothing for
+ unknown algorithms. Disabled algorithms are virtually not
+ available in Libgcrypt. This is not thread safe and should thus be
+ called early. */
+static void
+disable_cipher_algo (int algo)
+{
+ gcry_cipher_spec_t *spec = spec_from_algo (algo);
+
+ if (spec)
+ spec->flags.disabled = 1;
+}
+
+
+/* Return 0 if the cipher algorithm with identifier ALGORITHM is
+ available. Returns a basic error code value if it is not
+ available. */
+static gcry_err_code_t
+check_cipher_algo (int algorithm)
+{
+ gcry_cipher_spec_t *spec;
+
+ spec = spec_from_algo (algorithm);
+ if (spec && !spec->flags.disabled)
+ return 0;
+
+ return GPG_ERR_CIPHER_ALGO;
+}
+
+
+/* Return the standard length in bits of the key for the cipher
+ algorithm with the identifier ALGORITHM. */
+static unsigned int
+cipher_get_keylen (int algorithm)
+{
+ gcry_cipher_spec_t *spec;
+ unsigned len = 0;
+
+ spec = spec_from_algo (algorithm);
+ if (spec)
+ {
+ len = spec->keylen;
+ if (!len)
+ log_bug ("cipher %d w/o key length\n", algorithm);
+ }
+
+ return len;
+}
+
+
+/* Return the block length of the cipher algorithm with the identifier
+ ALGORITHM. This function return 0 for an invalid algorithm. */
+static unsigned int
+cipher_get_blocksize (int algorithm)
+{
+ gcry_cipher_spec_t *spec;
+ unsigned len = 0;
+
+ spec = spec_from_algo (algorithm);
+ if (spec)
+ {
+ len = spec->blocksize;
+ if (!len)
+ log_bug ("cipher %d w/o blocksize\n", algorithm);
+ }
+
+ return len;
+}
+
+
+/*
+ Open a cipher handle for use with cipher algorithm ALGORITHM, using
+ the cipher mode MODE (one of the GCRY_CIPHER_MODE_*) and return a
+ handle in HANDLE. Put NULL into HANDLE and return an error code if
+ something goes wrong. FLAGS may be used to modify the
+ operation. The defined flags are:
+
+ GCRY_CIPHER_SECURE: allocate all internal buffers in secure memory.
+ GCRY_CIPHER_ENABLE_SYNC: Enable the sync operation as used in OpenPGP.
+ GCRY_CIPHER_CBC_CTS: Enable CTS mode.
+ GCRY_CIPHER_CBC_MAC: Enable MAC mode.
+
+ Values for these flags may be combined using OR.
+ */
+gcry_err_code_t
+_gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags)
+{
+ gcry_err_code_t rc;
+ gcry_cipher_hd_t h = NULL;
+
+ if (mode >= GCRY_CIPHER_MODE_INTERNAL)
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ else
+ rc = _gcry_cipher_open_internal (&h, algo, mode, flags);
+
+ *handle = rc ? NULL : h;
+
+ return rc;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags)
+{
+ int secure = (flags & GCRY_CIPHER_SECURE);
+ gcry_cipher_spec_t *spec;
+ gcry_cipher_hd_t h = NULL;
+ gcry_err_code_t err;
+
+ /* If the application missed to call the random poll function, we do
+ it here to ensure that it is used once in a while. */
+ _gcry_fast_random_poll ();
+
+ spec = spec_from_algo (algo);
+ if (!spec)
+ err = GPG_ERR_CIPHER_ALGO;
+ else if (spec->flags.disabled)
+ err = GPG_ERR_CIPHER_ALGO;
+ else
+ err = 0;
+
+ /* check flags */
+ if ((! err)
+ && ((flags & ~(0
+ | GCRY_CIPHER_SECURE
+ | GCRY_CIPHER_ENABLE_SYNC
+ | GCRY_CIPHER_CBC_CTS
+ | GCRY_CIPHER_CBC_MAC))
+ || ((flags & GCRY_CIPHER_CBC_CTS) && (flags & GCRY_CIPHER_CBC_MAC))))
+ err = GPG_ERR_CIPHER_ALGO;
+
+ /* check that a valid mode has been requested */
+ if (! err)
+ switch (mode)
+ {
+ case GCRY_CIPHER_MODE_CCM:
+ if (spec->blocksize != GCRY_CCM_BLOCK_LEN)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ if (!spec->encrypt || !spec->decrypt)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_XTS:
+ if (spec->blocksize != GCRY_XTS_BLOCK_LEN)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ if (!spec->encrypt || !spec->decrypt)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_ECB:
+ case GCRY_CIPHER_MODE_CBC:
+ case GCRY_CIPHER_MODE_CFB:
+ case GCRY_CIPHER_MODE_CFB8:
+ case GCRY_CIPHER_MODE_OFB:
+ case GCRY_CIPHER_MODE_CTR:
+ case GCRY_CIPHER_MODE_AESWRAP:
+ case GCRY_CIPHER_MODE_CMAC:
+ case GCRY_CIPHER_MODE_EAX:
+ case GCRY_CIPHER_MODE_GCM:
+ if (!spec->encrypt || !spec->decrypt)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_POLY1305:
+ if (!spec->stencrypt || !spec->stdecrypt || !spec->setiv)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ else if (spec->algo != GCRY_CIPHER_CHACHA20)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_OCB:
+ /* Note that our implementation allows only for 128 bit block
+ length algorithms. Lower block lengths would be possible
+ but we do not implement them because they limit the
+ security too much. */
+ if (!spec->encrypt || !spec->decrypt)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ else if (spec->blocksize != (128/8))
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_STREAM:
+ if (!spec->stencrypt || !spec->stdecrypt)
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_NONE:
+ /* This mode may be used for debugging. It copies the main
+ text verbatim to the ciphertext. We do not allow this in
+ fips mode or if no debug flag has been set. */
+ if (fips_mode () || !_gcry_get_debug_flag (0))
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ default:
+ err = GPG_ERR_INV_CIPHER_MODE;
+ }
+
+ /* Perform selftest here and mark this with a flag in cipher_table?
+ No, we should not do this as it takes too long. Further it does
+ not make sense to exclude algorithms with failing selftests at
+ runtime: If a selftest fails there is something seriously wrong
+ with the system and thus we better die immediately. */
+
+ if (! err)
+ {
+ size_t size = (sizeof (*h)
+ + 2 * spec->contextsize
+ - sizeof (cipher_context_alignment_t)
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+ + 15 /* Space for leading alignment gap. */
+#endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
+ );
+
+ /* Space needed per mode. */
+ switch (mode)
+ {
+ case GCRY_CIPHER_MODE_XTS:
+ /* Additional cipher context for tweak. */
+ size += 2 * spec->contextsize + 15;
+ break;
+
+ default:
+ break;
+ }
+
+ if (secure)
+ h = xtrycalloc_secure (1, size);
+ else
+ h = xtrycalloc (1, size);
+
+ if (! h)
+ err = gpg_err_code_from_syserror ();
+ else
+ {
+ size_t off = 0;
+ char *tc;
+
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+ if ( ((uintptr_t)h & 0x0f) )
+ {
+ /* The malloced block is not aligned on a 16 byte
+ boundary. Correct for this. */
+ off = 16 - ((uintptr_t)h & 0x0f);
+ h = (void*)((char*)h + off);
+ }
+#endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
+
+ h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
+ h->actual_handle_size = size - off;
+ h->handle_offset = off;
+ h->spec = spec;
+ h->algo = algo;
+ h->mode = mode;
+ h->flags = flags;
+
+ /* Setup mode routines. */
+ _gcry_cipher_setup_mode_ops(h, mode);
+
+ /* Setup defaults depending on the mode. */
+ switch (mode)
+ {
+ case GCRY_CIPHER_MODE_OCB:
+ h->u_mode.ocb.taglen = 16; /* Bytes. */
+ break;
+
+ case GCRY_CIPHER_MODE_XTS:
+ tc = h->context.c + spec->contextsize * 2;
+ tc += (16 - (uintptr_t)tc % 16) % 16;
+ h->u_mode.xts.tweak_context = tc;
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ /* Done. */
+
+ *handle = err ? NULL : h;
+
+ return err;
+}
+
+
+/* Release all resources associated with the cipher handle H. H may be
+ NULL in which case this is a no-operation. */
+void
+_gcry_cipher_close (gcry_cipher_hd_t h)
+{
+ size_t off;
+
+ if (!h)
+ return;
+
+ if ((h->magic != CTX_MAGIC_SECURE)
+ && (h->magic != CTX_MAGIC_NORMAL))
+ _gcry_fatal_error(GPG_ERR_INTERNAL,
+ "gcry_cipher_close: already closed/invalid handle");
+ else
+ h->magic = 0;
+
+ /* We always want to wipe out the memory even when the context has
+ been allocated in secure memory. The user might have disabled
+ secure memory or is using his own implementation which does not
+ do the wiping. To accomplish this we need to keep track of the
+ actual size of this structure because we have no way to known
+ how large the allocated area was when using a standard malloc. */
+ off = h->handle_offset;
+ wipememory (h, h->actual_handle_size);
+
+ xfree ((char*)h - off);
+}
+
+
+/* Set the key to be used for the encryption context C to KEY with
+ length KEYLEN. The length should match the required length. */
+static gcry_err_code_t
+cipher_setkey (gcry_cipher_hd_t c, byte *key, size_t keylen)
+{
+ gcry_err_code_t rc;
+
+ if (c->mode == GCRY_CIPHER_MODE_XTS)
+ {
+ /* XTS uses two keys. */
+ if (keylen % 2)
+ return GPG_ERR_INV_KEYLEN;
+ keylen /= 2;
+
+ if (fips_mode ())
+ {
+ /* Reject key if subkeys Key_1 and Key_2 are equal.
+ See "Implementation Guidance for FIPS 140-2, A.9 XTS-AES
+ Key Generation Requirements" for details. */
+ if (buf_eq_const (key, key + keylen, keylen))
+ return GPG_ERR_WEAK_KEY;
+ }
+ }
+
+ rc = c->spec->setkey (&c->context.c, key, keylen, &c->bulk);
+ if (!rc || (c->marks.allow_weak_key && rc == GPG_ERR_WEAK_KEY))
+ {
+ /* Duplicate initial context. */
+ memcpy ((void *) ((char *) &c->context.c + c->spec->contextsize),
+ (void *) &c->context.c,
+ c->spec->contextsize);
+ c->marks.key = 1;
+
+ switch (c->mode)
+ {
+ case GCRY_CIPHER_MODE_CMAC:
+ rc = _gcry_cipher_cmac_set_subkeys (c);
+ break;
+
+ case GCRY_CIPHER_MODE_EAX:
+ rc = _gcry_cipher_eax_setkey (c);
+ break;
+
+ case GCRY_CIPHER_MODE_GCM:
+ _gcry_cipher_gcm_setkey (c);
+ break;
+
+ case GCRY_CIPHER_MODE_OCB:
+ _gcry_cipher_ocb_setkey (c);
+ break;
+
+ case GCRY_CIPHER_MODE_POLY1305:
+ _gcry_cipher_poly1305_setkey (c);
+ break;
+
+ case GCRY_CIPHER_MODE_XTS:
+ /* Setup tweak cipher with second part of XTS key. */
+ rc = c->spec->setkey (c->u_mode.xts.tweak_context, key + keylen,
+ keylen, &c->bulk);
+ if (!rc || (c->marks.allow_weak_key && rc == GPG_ERR_WEAK_KEY))
+ {
+ /* Duplicate initial tweak context. */
+ memcpy (c->u_mode.xts.tweak_context + c->spec->contextsize,
+ c->u_mode.xts.tweak_context, c->spec->contextsize);
+ }
+ else
+ c->marks.key = 0;
+ break;
+
+ default:
+ break;
+ };
+ }
+ else
+ c->marks.key = 0;
+
+ return rc;
+}
+
+
+/* Set the IV to be used for the encryption context C to IV with
+ length IVLEN. The length should match the required length. */
+static gcry_err_code_t
+cipher_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
+{
+ /* If the cipher has its own IV handler, we use only this one. This
+ is currently used for stream ciphers requiring a nonce. */
+ if (c->spec->setiv)
+ {
+ c->spec->setiv (&c->context.c, iv, ivlen);
+ return 0;
+ }
+
+ memset (c->u_iv.iv, 0, c->spec->blocksize);
+ if (iv)
+ {
+ if (ivlen != c->spec->blocksize)
+ {
+ log_info ("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
+ (unsigned int)ivlen, (unsigned int)c->spec->blocksize);
+ fips_signal_error ("IV length does not match blocklength");
+ }
+ if (ivlen > c->spec->blocksize)
+ ivlen = c->spec->blocksize;
+ memcpy (c->u_iv.iv, iv, ivlen);
+ c->marks.iv = 1;
+ }
+ else
+ c->marks.iv = 0;
+ c->unused = 0;
+
+ return 0;
+}
+
+
+/* Reset the cipher context to the initial context. This is basically
+ the same as an release followed by a new. */
+static void
+cipher_reset (gcry_cipher_hd_t c)
+{
+ unsigned int marks_key, marks_allow_weak_key;
+
+ marks_key = c->marks.key;
+ marks_allow_weak_key = c->marks.allow_weak_key;
+
+ memcpy (&c->context.c,
+ (char *) &c->context.c + c->spec->contextsize,
+ c->spec->contextsize);
+ memset (&c->marks, 0, sizeof c->marks);
+ memset (c->u_iv.iv, 0, c->spec->blocksize);
+ memset (c->lastiv, 0, c->spec->blocksize);
+ memset (c->u_ctr.ctr, 0, c->spec->blocksize);
+ c->unused = 0;
+
+ c->marks.key = marks_key;
+ c->marks.allow_weak_key = marks_allow_weak_key;
+
+ switch (c->mode)
+ {
+ case GCRY_CIPHER_MODE_CMAC:
+ _gcry_cmac_reset(&c->u_mode.cmac);
+ break;
+
+ case GCRY_CIPHER_MODE_EAX:
+ _gcry_cmac_reset(&c->u_mode.eax.cmac_header);
+ _gcry_cmac_reset(&c->u_mode.eax.cmac_ciphertext);
+ break;
+
+ case GCRY_CIPHER_MODE_GCM:
+ /* Only clear head of u_mode, keep ghash_key and gcm_table. */
+ {
+ byte *u_mode_pos = (void *)&c->u_mode;
+ byte *ghash_key_pos = c->u_mode.gcm.u_ghash_key.key;
+ size_t u_mode_head_length = ghash_key_pos - u_mode_pos;
+
+ memset (&c->u_mode, 0, u_mode_head_length);
+ }
+ break;
+
+ case GCRY_CIPHER_MODE_POLY1305:
+ memset (&c->u_mode.poly1305, 0, sizeof c->u_mode.poly1305);
+ break;
+
+ case GCRY_CIPHER_MODE_CCM:
+ memset (&c->u_mode.ccm, 0, sizeof c->u_mode.ccm);
+ break;
+
+ case GCRY_CIPHER_MODE_OCB:
+ /* Do not clear precalculated L-values */
+ {
+ byte *u_mode_head_pos = (void *)&c->u_mode.ocb;
+ byte *u_mode_tail_pos = (void *)&c->u_mode.ocb.tag;
+ size_t u_mode_head_length = u_mode_tail_pos - u_mode_head_pos;
+ size_t u_mode_tail_length = sizeof(c->u_mode.ocb) - u_mode_head_length;
+
+ memset (u_mode_tail_pos, 0, u_mode_tail_length);
+
+ /* Setup default taglen. */
+ c->u_mode.ocb.taglen = 16;
+ }
+ break;
+
+ case GCRY_CIPHER_MODE_XTS:
+ memcpy (c->u_mode.xts.tweak_context,
+ c->u_mode.xts.tweak_context + c->spec->contextsize,
+ c->spec->contextsize);
+ break;
+
+ default:
+ break; /* u_mode unused by other modes. */
+ }
+}
+
+
+
+static gcry_err_code_t
+do_ecb_crypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen,
+ gcry_cipher_encrypt_t crypt_fn)
+{
+ unsigned int blocksize = c->spec->blocksize;
+ size_t n, nblocks;
+ unsigned int burn, nburn;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if ((inbuflen % blocksize))
+ return GPG_ERR_INV_LENGTH;
+
+ nblocks = inbuflen / blocksize;
+ burn = 0;
+
+ for (n=0; n < nblocks; n++ )
+ {
+ nburn = crypt_fn (&c->context.c, outbuf, inbuf);
+ burn = nburn > burn ? nburn : burn;
+ inbuf += blocksize;
+ outbuf += blocksize;
+ }
+
+ if (burn > 0)
+ _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+ return 0;
+}
+
+static gcry_err_code_t
+do_ecb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ return do_ecb_crypt (c, outbuf, outbuflen, inbuf, inbuflen, c->spec->encrypt);
+}
+
+static gcry_err_code_t
+do_ecb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ return do_ecb_crypt (c, outbuf, outbuflen, inbuf, inbuflen, c->spec->decrypt);
+}
+
+
+static gcry_err_code_t
+do_stream_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ (void)outbuflen;
+ c->spec->stencrypt (&c->context.c, outbuf, (void *)inbuf, inbuflen);
+ return 0;
+}
+
+static gcry_err_code_t
+do_stream_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, size_t outbuflen,
+ const unsigned char *inbuf, size_t inbuflen)
+{
+ (void)outbuflen;
+ c->spec->stdecrypt (&c->context.c, outbuf, (void *)inbuf, inbuflen);
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_encrypt_none_unknown (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ gcry_err_code_t rc;
+
+ (void)outbuflen;
+
+ switch (c->mode)
+ {
+ case GCRY_CIPHER_MODE_CMAC:
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_NONE:
+ if (fips_mode () || !_gcry_get_debug_flag (0))
+ {
+ fips_signal_error ("cipher mode NONE used");
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+ else
+ {
+ if (inbuf != outbuf)
+ memmove (outbuf, inbuf, inbuflen);
+ rc = 0;
+ }
+ break;
+
+ default:
+ log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode );
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
+ }
+
+ return rc;
+}
+
+static gcry_err_code_t
+do_decrypt_none_unknown (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
+ const byte *inbuf, size_t inbuflen)
+{
+ gcry_err_code_t rc;
+
+ (void)outbuflen;
+
+ switch (c->mode)
+ {
+ case GCRY_CIPHER_MODE_CMAC:
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_NONE:
+ if (fips_mode () || !_gcry_get_debug_flag (0))
+ {
+ fips_signal_error ("cipher mode NONE used");
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+ else
+ {
+ if (inbuf != outbuf)
+ memmove (outbuf, inbuf, inbuflen);
+ rc = 0;
+ }
+ break;
+
+ default:
+ log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
+ }
+
+ return rc;
+}
+
+
+/****************
+ * Encrypt IN and write it to OUT. If IN is NULL, in-place encryption has
+ * been requested.
+ */
+gcry_err_code_t
+_gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ gcry_err_code_t rc;
+
+ if (!in) /* Caller requested in-place encryption. */
+ {
+ in = out;
+ inlen = outsize;
+ }
+
+ if (h->mode != GCRY_CIPHER_MODE_NONE && !h->marks.key)
+ {
+ log_error ("cipher_encrypt: key not set\n");
+ return GPG_ERR_MISSING_KEY;
+ }
+
+ rc = h->mode_ops.encrypt (h, out, outsize, in, inlen);
+
+ /* Failsafe: Make sure that the plaintext will never make it into
+ OUT if the encryption returned an error. */
+ if (rc && out)
+ memset (out, 0x42, outsize);
+
+ return rc;
+}
+
+
+/****************
+ * Decrypt IN and write it to OUT. If IN is NULL, in-place encryption has
+ * been requested.
+ */
+gcry_err_code_t
+_gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ if (!in) /* Caller requested in-place encryption. */
+ {
+ in = out;
+ inlen = outsize;
+ }
+
+ if (h->mode != GCRY_CIPHER_MODE_NONE && !h->marks.key)
+ {
+ log_error ("cipher_decrypt: key not set\n");
+ return GPG_ERR_MISSING_KEY;
+ }
+
+ return h->mode_ops.decrypt (h, out, outsize, in, inlen);
+}
+
+
+/****************
+ * Used for PGP's somewhat strange CFB mode. Only works if
+ * the corresponding flag is set.
+ */
+static void
+cipher_sync (gcry_cipher_hd_t c)
+{
+ if ((c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused)
+ {
+ memmove (c->u_iv.iv + c->unused,
+ c->u_iv.iv, c->spec->blocksize - c->unused);
+ memcpy (c->u_iv.iv,
+ c->lastiv + c->spec->blocksize - c->unused, c->unused);
+ c->unused = 0;
+ }
+}
+
+
+gcry_err_code_t
+_gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
+{
+ return cipher_setkey (hd, (void*)key, keylen);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
+{
+ return hd->mode_ops.setiv (hd, iv, ivlen);
+}
+
+
+/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of
+ block size length, or (NULL,0) to set the CTR to the all-zero
+ block. */
+gpg_err_code_t
+_gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
+{
+ if (ctr && ctrlen == hd->spec->blocksize)
+ {
+ memcpy (hd->u_ctr.ctr, ctr, hd->spec->blocksize);
+ hd->unused = 0;
+ }
+ else if (!ctr || !ctrlen)
+ {
+ memset (hd->u_ctr.ctr, 0, hd->spec->blocksize);
+ hd->unused = 0;
+ }
+ else
+ return GPG_ERR_INV_ARG;
+
+ return 0;
+}
+
+gpg_err_code_t
+_gcry_cipher_getctr (gcry_cipher_hd_t hd, void *ctr, size_t ctrlen)
+{
+ if (ctr && ctrlen == hd->spec->blocksize)
+ memcpy (ctr, hd->u_ctr.ctr, hd->spec->blocksize);
+ else
+ return GPG_ERR_INV_ARG;
+
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
+ size_t abuflen)
+{
+ gcry_err_code_t rc;
+
+ if (hd->mode_ops.authenticate)
+ {
+ rc = hd->mode_ops.authenticate (hd, abuf, abuflen);
+ }
+ else
+ {
+ log_error ("gcry_cipher_authenticate: invalid mode %d\n", hd->mode);
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+
+ return rc;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen)
+{
+ gcry_err_code_t rc;
+
+ if (hd->mode_ops.get_tag)
+ {
+ rc = hd->mode_ops.get_tag (hd, outtag, taglen);
+ }
+ else
+ {
+ log_error ("gcry_cipher_gettag: invalid mode %d\n", hd->mode);
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+
+ return rc;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen)
+{
+ gcry_err_code_t rc;
+
+ if (hd->mode_ops.check_tag)
+ {
+ rc = hd->mode_ops.check_tag (hd, intag, taglen);
+ }
+ else
+ {
+ log_error ("gcry_cipher_checktag: invalid mode %d\n", hd->mode);
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+
+ return rc;
+}
+
+
+
+static void
+_gcry_cipher_setup_mode_ops(gcry_cipher_hd_t c, int mode)
+{
+ /* Setup encryption and decryption routines. */
+ switch (mode)
+ {
+ case GCRY_CIPHER_MODE_STREAM:
+ c->mode_ops.encrypt = do_stream_encrypt;
+ c->mode_ops.decrypt = do_stream_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_ECB:
+ c->mode_ops.encrypt = do_ecb_encrypt;
+ c->mode_ops.decrypt = do_ecb_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_CBC:
+ if (!(c->flags & GCRY_CIPHER_CBC_CTS))
+ {
+ c->mode_ops.encrypt = _gcry_cipher_cbc_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_cbc_decrypt;
+ }
+ else
+ {
+ c->mode_ops.encrypt = _gcry_cipher_cbc_cts_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_cbc_cts_decrypt;
+ }
+ break;
+
+ case GCRY_CIPHER_MODE_CFB:
+ c->mode_ops.encrypt = _gcry_cipher_cfb_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_cfb_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_CFB8:
+ c->mode_ops.encrypt = _gcry_cipher_cfb8_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_cfb8_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_OFB:
+ c->mode_ops.encrypt = _gcry_cipher_ofb_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_ofb_encrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_CTR:
+ c->mode_ops.encrypt = _gcry_cipher_ctr_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_ctr_encrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_AESWRAP:
+ c->mode_ops.encrypt = _gcry_cipher_aeswrap_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_aeswrap_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_CCM:
+ c->mode_ops.encrypt = _gcry_cipher_ccm_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_ccm_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_EAX:
+ c->mode_ops.encrypt = _gcry_cipher_eax_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_eax_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_GCM:
+ c->mode_ops.encrypt = _gcry_cipher_gcm_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_gcm_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_POLY1305:
+ c->mode_ops.encrypt = _gcry_cipher_poly1305_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_poly1305_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_OCB:
+ c->mode_ops.encrypt = _gcry_cipher_ocb_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_ocb_decrypt;
+ break;
+
+ case GCRY_CIPHER_MODE_XTS:
+ c->mode_ops.encrypt = _gcry_cipher_xts_encrypt;
+ c->mode_ops.decrypt = _gcry_cipher_xts_decrypt;
+ break;
+
+ default:
+ c->mode_ops.encrypt = do_encrypt_none_unknown;
+ c->mode_ops.decrypt = do_decrypt_none_unknown;
+ break;
+ }
+
+ /* Setup IV setting routine. */
+ switch (mode)
+ {
+ case GCRY_CIPHER_MODE_CCM:
+ c->mode_ops.setiv = _gcry_cipher_ccm_set_nonce;
+ break;
+
+ case GCRY_CIPHER_MODE_EAX:
+ c->mode_ops.setiv = _gcry_cipher_eax_set_nonce;
+ break;
+
+ case GCRY_CIPHER_MODE_GCM:
+ c->mode_ops.setiv = _gcry_cipher_gcm_setiv;
+ break;
+
+ case GCRY_CIPHER_MODE_POLY1305:
+ c->mode_ops.setiv = _gcry_cipher_poly1305_setiv;
+ break;
+
+ case GCRY_CIPHER_MODE_OCB:
+ c->mode_ops.setiv = _gcry_cipher_ocb_set_nonce;
+ break;
+
+ default:
+ c->mode_ops.setiv = cipher_setiv;
+ break;
+ }
+
+
+ /* Setup authentication routines for AEAD modes. */
+ switch (mode)
+ {
+ case GCRY_CIPHER_MODE_CCM:
+ c->mode_ops.authenticate = _gcry_cipher_ccm_authenticate;
+ c->mode_ops.get_tag = _gcry_cipher_ccm_get_tag;
+ c->mode_ops.check_tag = _gcry_cipher_ccm_check_tag;
+ break;
+
+ case GCRY_CIPHER_MODE_CMAC:
+ c->mode_ops.authenticate = _gcry_cipher_cmac_authenticate;
+ c->mode_ops.get_tag = _gcry_cipher_cmac_get_tag;
+ c->mode_ops.check_tag = _gcry_cipher_cmac_check_tag;
+ break;
+
+ case GCRY_CIPHER_MODE_EAX:
+ c->mode_ops.authenticate = _gcry_cipher_eax_authenticate;
+ c->mode_ops.get_tag = _gcry_cipher_eax_get_tag;
+ c->mode_ops.check_tag = _gcry_cipher_eax_check_tag;
+ break;
+
+ case GCRY_CIPHER_MODE_GCM:
+ c->mode_ops.authenticate = _gcry_cipher_gcm_authenticate;
+ c->mode_ops.get_tag = _gcry_cipher_gcm_get_tag;
+ c->mode_ops.check_tag = _gcry_cipher_gcm_check_tag;
+ break;
+
+ case GCRY_CIPHER_MODE_POLY1305:
+ c->mode_ops.authenticate = _gcry_cipher_poly1305_authenticate;
+ c->mode_ops.get_tag = _gcry_cipher_poly1305_get_tag;
+ c->mode_ops.check_tag = _gcry_cipher_poly1305_check_tag;
+ break;
+
+ case GCRY_CIPHER_MODE_OCB:
+ c->mode_ops.authenticate = _gcry_cipher_ocb_authenticate;
+ c->mode_ops.get_tag = _gcry_cipher_ocb_get_tag;
+ c->mode_ops.check_tag = _gcry_cipher_ocb_check_tag;
+ break;
+
+ default:
+ c->mode_ops.authenticate = NULL;
+ c->mode_ops.get_tag = NULL;
+ c->mode_ops.check_tag = NULL;
+ break;
+ }
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+ gcry_err_code_t rc = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_RESET:
+ cipher_reset (h);
+ break;
+
+ case GCRYCTL_FINALIZE:
+ if (!h || buffer || buflen)
+ return GPG_ERR_INV_ARG;
+ h->marks.finalize = 1;
+ break;
+
+ case GCRYCTL_CFB_SYNC:
+ cipher_sync( h );
+ break;
+
+ case GCRYCTL_SET_CBC_CTS:
+ if (buflen)
+ if (h->flags & GCRY_CIPHER_CBC_MAC)
+ rc = GPG_ERR_INV_FLAG;
+ else
+ h->flags |= GCRY_CIPHER_CBC_CTS;
+ else
+ h->flags &= ~GCRY_CIPHER_CBC_CTS;
+ break;
+
+ case GCRYCTL_SET_CBC_MAC:
+ if (buflen)
+ if (h->flags & GCRY_CIPHER_CBC_CTS)
+ rc = GPG_ERR_INV_FLAG;
+ else
+ h->flags |= GCRY_CIPHER_CBC_MAC;
+ else
+ h->flags &= ~GCRY_CIPHER_CBC_MAC;
+ break;
+
+ case GCRYCTL_SET_CCM_LENGTHS:
+ {
+ u64 params[3];
+ size_t encryptedlen;
+ size_t aadlen;
+ size_t authtaglen;
+
+ if (h->mode != GCRY_CIPHER_MODE_CCM)
+ return GPG_ERR_INV_CIPHER_MODE;
+
+ if (!buffer || buflen != 3 * sizeof(u64))
+ return GPG_ERR_INV_ARG;
+
+ /* This command is used to pass additional length parameters needed
+ by CCM mode to initialize CBC-MAC. */
+ memcpy (params, buffer, sizeof(params));
+ encryptedlen = params[0];
+ aadlen = params[1];
+ authtaglen = params[2];
+
+ rc = _gcry_cipher_ccm_set_lengths (h, encryptedlen, aadlen, authtaglen);
+ }
+ break;
+
+ case GCRYCTL_SET_TAGLEN:
+ if (!h || !buffer || buflen != sizeof(int) )
+ return GPG_ERR_INV_ARG;
+ switch (h->mode)
+ {
+ case GCRY_CIPHER_MODE_OCB:
+ switch (*(int*)buffer)
+ {
+ case 8: case 12: case 16:
+ h->u_mode.ocb.taglen = *(int*)buffer;
+ break;
+ default:
+ rc = GPG_ERR_INV_LENGTH; /* Invalid tag length. */
+ break;
+ }
+ break;
+
+ default:
+ rc =GPG_ERR_INV_CIPHER_MODE;
+ break;
+ }
+ break;
+
+ case GCRYCTL_DISABLE_ALGO:
+ /* This command expects NULL for H and BUFFER to point to an
+ integer with the algo number. */
+ if( h || !buffer || buflen != sizeof(int) )
+ return GPG_ERR_CIPHER_ALGO;
+ disable_cipher_algo( *(int*)buffer );
+ break;
+
+ case PRIV_CIPHERCTL_DISABLE_WEAK_KEY: /* (private) */
+ if (h->spec->set_extra_info)
+ rc = h->spec->set_extra_info
+ (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
+ else
+ rc = GPG_ERR_NOT_SUPPORTED;
+ break;
+
+ case PRIV_CIPHERCTL_GET_INPUT_VECTOR: /* (private) */
+ /* This is the input block as used in CFB and OFB mode which has
+ initially been set as IV. The returned format is:
+ 1 byte Actual length of the block in bytes.
+ n byte The block.
+ If the provided buffer is too short, an error is returned. */
+ if (buflen < (1 + h->spec->blocksize))
+ rc = GPG_ERR_TOO_SHORT;
+ else
+ {
+ unsigned char *ivp;
+ unsigned char *dst = buffer;
+ int n = h->unused;
+
+ if (!n)
+ n = h->spec->blocksize;
+ gcry_assert (n <= h->spec->blocksize);
+ *dst++ = n;
+ ivp = h->u_iv.iv + h->spec->blocksize - n;
+ while (n--)
+ *dst++ = *ivp++;
+ }
+ break;
+
+ case GCRYCTL_SET_SBOX:
+ if (h->spec->set_extra_info)
+ rc = h->spec->set_extra_info
+ (&h->context.c, GCRYCTL_SET_SBOX, buffer, buflen);
+ else
+ rc = GPG_ERR_NOT_SUPPORTED;
+ break;
+
+ case GCRYCTL_SET_ALLOW_WEAK_KEY:
+ /* Expecting BUFFER to be NULL and buflen to be on/off flag (0 or 1). */
+ if (!h || buffer || buflen > 1)
+ return GPG_ERR_CIPHER_ALGO;
+ h->marks.allow_weak_key = buflen ? 1 : 0;
+ break;
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return rc;
+}
+
+
+/* Return information about the cipher handle H. CMD is the kind of
+ * information requested.
+ *
+ * CMD may be one of:
+ *
+ * GCRYCTL_GET_TAGLEN:
+ * Return the length of the tag for an AE algorithm mode. An
+ * error is returned for modes which do not support a tag.
+ * BUFFER must be given as NULL. On success the result is stored
+ * at NBYTES. The taglen is returned in bytes.
+ *
+ * The function returns 0 on success or an error code.
+ */
+gcry_err_code_t
+_gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t rc = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_GET_TAGLEN:
+ if (!h || buffer || !nbytes)
+ rc = GPG_ERR_INV_ARG;
+ else
+ {
+ switch (h->mode)
+ {
+ case GCRY_CIPHER_MODE_OCB:
+ *nbytes = h->u_mode.ocb.taglen;
+ break;
+
+ case GCRY_CIPHER_MODE_CCM:
+ *nbytes = h->u_mode.ccm.authlen;
+ break;
+
+ case GCRY_CIPHER_MODE_EAX:
+ *nbytes = h->spec->blocksize;
+ break;
+
+ case GCRY_CIPHER_MODE_GCM:
+ *nbytes = GCRY_GCM_BLOCK_LEN;
+ break;
+
+ case GCRY_CIPHER_MODE_POLY1305:
+ *nbytes = POLY1305_TAGLEN;
+ break;
+
+ default:
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
+ }
+ }
+ break;
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return rc;
+}
+
+/* Return information about the given cipher algorithm ALGO.
+
+ WHAT select the kind of information returned:
+
+ GCRYCTL_GET_KEYLEN:
+ Return the length of the key. If the algorithm ALGO
+ supports multiple key lengths, the maximum supported key length
+ is returned. The key length is returned as number of octets.
+ BUFFER and NBYTES must be zero.
+
+ GCRYCTL_GET_BLKLEN:
+ Return the blocklength of the algorithm ALGO counted in octets.
+ BUFFER and NBYTES must be zero.
+
+ GCRYCTL_TEST_ALGO:
+ Returns 0 if the specified algorithm ALGO is available for use.
+ BUFFER and NBYTES must be zero.
+
+ Note: Because this function is in most cases used to return an
+ integer value, we can make it easier for the caller to just look at
+ the return value. The caller will in all cases consult the value
+ and thereby detecting whether a error occurred or not (i.e. while
+ checking the block size)
+ */
+gcry_err_code_t
+_gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t rc = 0;
+ unsigned int ui;
+
+ switch (what)
+ {
+ case GCRYCTL_GET_KEYLEN:
+ if (buffer || (! nbytes))
+ rc = GPG_ERR_CIPHER_ALGO;
+ else
+ {
+ ui = cipher_get_keylen (algo);
+ if ((ui > 0) && (ui <= 512))
+ *nbytes = (size_t) ui / 8;
+ else
+ /* The only reason for an error is an invalid algo. */
+ rc = GPG_ERR_CIPHER_ALGO;
+ }
+ break;
+
+ case GCRYCTL_GET_BLKLEN:
+ if (buffer || (! nbytes))
+ rc = GPG_ERR_CIPHER_ALGO;
+ else
+ {
+ ui = cipher_get_blocksize (algo);
+ if ((ui > 0) && (ui < 10000))
+ *nbytes = ui;
+ else
+ {
+ /* The only reason is an invalid algo or a strange
+ blocksize. */
+ rc = GPG_ERR_CIPHER_ALGO;
+ }
+ }
+ break;
+
+ case GCRYCTL_TEST_ALGO:
+ if (buffer || nbytes)
+ rc = GPG_ERR_INV_ARG;
+ else
+ rc = check_cipher_algo (algo);
+ break;
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return rc;
+}
+
+
+/* This function returns length of the key for algorithm ALGO. If the
+ algorithm supports multiple key lengths, the maximum supported key
+ length is returned. On error 0 is returned. The key length is
+ returned as number of octets.
+
+ This is a convenience functions which should be preferred over
+ gcry_cipher_algo_info because it allows for proper type
+ checking. */
+size_t
+_gcry_cipher_get_algo_keylen (int algo)
+{
+ size_t n;
+
+ if (_gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &n))
+ n = 0;
+ return n;
+}
+
+
+/* This functions returns the blocklength of the algorithm ALGO
+ counted in octets. On error 0 is returned.
+
+ This is a convenience functions which should be preferred over
+ gcry_cipher_algo_info because it allows for proper type
+ checking. */
+size_t
+_gcry_cipher_get_algo_blklen (int algo)
+{
+ size_t n;
+
+ if (_gcry_cipher_algo_info( algo, GCRYCTL_GET_BLKLEN, NULL, &n))
+ n = 0;
+ return n;
+}
+
+
+/* Explicitly initialize this module. */
+gcry_err_code_t
+_gcry_cipher_init (void)
+{
+ if (fips_mode())
+ {
+ /* disable algorithms that are disallowed in fips */
+ int idx;
+ gcry_cipher_spec_t *spec;
+
+ for (idx = 0; (spec = cipher_list[idx]); idx++)
+ if (!spec->flags.fips)
+ spec->flags.disabled = 1;
+ }
+
+ return 0;
+}
+
+
+/* Run the selftests for cipher algorithm ALGO with optional reporting
+ function REPORT. */
+gpg_error_t
+_gcry_cipher_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_err_code_t ec = 0;
+ gcry_cipher_spec_t *spec;
+
+ spec = spec_from_algo (algo);
+ if (spec && !spec->flags.disabled && spec->selftest)
+ ec = spec->selftest (algo, extended, report);
+ else
+ {
+ ec = GPG_ERR_CIPHER_ALGO;
+ if (report)
+ report ("cipher", algo, "module",
+ (spec && !spec->flags.disabled)?
+ "no selftest available" :
+ spec? "algorithm disabled" : "algorithm not found");
+ }
+
+ return gpg_error (ec);
+}
diff --git a/comm/third_party/libgcrypt/cipher/crc-armv8-aarch64-ce.S b/comm/third_party/libgcrypt/cipher/crc-armv8-aarch64-ce.S
new file mode 100644
index 0000000000..060abdfe9a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/crc-armv8-aarch64-ce.S
@@ -0,0 +1,497 @@
+/* crc-armv8-aarch64-ce.S - ARMv8/CE PMULL accelerated CRC implementation
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+
+.cpu generic+simd+crypto
+
+.text
+
+
+/* Structure of crc32_consts_s */
+
+#define consts_k(idx) ((idx) * 8)
+#define consts_my_p(idx) (consts_k(6) + (idx) * 8)
+
+/* Constants */
+
+.align 6
+.Lcrc32_constants:
+.Lcrc32_partial_fold_input_mask:
+ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+.Lcrc32_refl_shuf_shift:
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+ .byte 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+.Lcrc32_shuf_shift:
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+.Lcrc32_bswap_shuf:
+ .byte 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08
+ .byte 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+
+
+/*
+ * void _gcry_crc32r_armv8_ce_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+ * const struct crc32_consts_s *consts);
+ */
+.align 3
+.globl _gcry_crc32r_armv8_ce_bulk
+ELF(.type _gcry_crc32r_armv8_ce_bulk,%function;)
+_gcry_crc32r_armv8_ce_bulk:
+ /* input:
+ * x0: pcrc
+ * x1: inbuf
+ * x2: inlen
+ * x3: consts
+ */
+ CFI_STARTPROC()
+
+ GET_DATA_POINTER(x7, .Lcrc32_constants)
+ add x9, x3, #consts_k(5 - 1)
+ cmp x2, #128
+
+ b.lo .Lcrc32r_fold_by_one_setup
+
+ eor v4.16b, v4.16b, v4.16b
+ add x4, x3, #consts_k(1 - 1)
+ ld1 {v4.s}[0], [x0] /* load pcrc */
+ ld1 {v0.16b-v3.16b}, [x1], #64 /* load 64 bytes of input */
+ sub x2, x2, #64
+ ld1 {v6.16b}, [x4]
+ eor v0.16b, v0.16b, v4.16b
+
+ add x4, x3, #consts_k(3 - 1)
+ add x5, x3, #consts_my_p(0)
+
+.Lcrc32r_fold_by_four:
+
+ /* Fold by 4. */
+ ld1 {v16.16b-v19.16b}, [x1], #64 /* load 64 bytes of input */
+ sub x2, x2, #64
+ pmull v20.1q, v0.1d, v6.1d
+ pmull v21.1q, v1.1d, v6.1d
+ pmull v22.1q, v2.1d, v6.1d
+ pmull v23.1q, v3.1d, v6.1d
+ cmp x2, #64
+ pmull2 v24.1q, v0.2d, v6.2d
+ pmull2 v25.1q, v1.2d, v6.2d
+ pmull2 v26.1q, v2.2d, v6.2d
+ pmull2 v27.1q, v3.2d, v6.2d
+ eor v0.16b, v20.16b, v16.16b
+ eor v1.16b, v21.16b, v17.16b
+ eor v2.16b, v22.16b, v18.16b
+ eor v3.16b, v23.16b, v19.16b
+ eor v0.16b, v0.16b, v24.16b
+ eor v1.16b, v1.16b, v25.16b
+ eor v2.16b, v2.16b, v26.16b
+ eor v3.16b, v3.16b, v27.16b
+ b.hs .Lcrc32r_fold_by_four
+
+ ld1 {v6.16b}, [x4]
+ ld1 {v5.16b}, [x5]
+
+ cmp x2, #16
+
+ /* Fold 4 to 1. */
+
+ pmull v16.1q, v0.1d, v6.1d
+ pmull2 v4.1q, v0.2d, v6.2d
+ eor v0.16b, v16.16b, v1.16b
+ eor v0.16b, v0.16b, v4.16b
+
+ pmull v16.1q, v0.1d, v6.1d
+ pmull2 v4.1q, v0.2d, v6.2d
+ eor v0.16b, v16.16b, v2.16b
+ eor v0.16b, v0.16b, v4.16b
+
+ pmull v16.1q, v0.1d, v6.1d
+ pmull2 v4.1q, v0.2d, v6.2d
+ eor v0.16b, v16.16b, v3.16b
+ eor v0.16b, v0.16b, v4.16b
+
+ b.lo .Lcrc32r_fold_by_one_done
+ b .Lcrc32r_fold_by_one
+
+.Lcrc32r_fold_by_one_setup:
+
+ eor v1.16b, v1.16b, v1.16b
+ add x4, x3, #consts_k(3 - 1)
+ add x5, x3, #consts_my_p(0)
+ sub x2, x2, #16
+ ld1 {v1.s}[0], [x0] /* load pcrc */
+ ld1 {v0.16b}, [x1], #16 /* load 16 bytes of input */
+ cmp x2, #16
+ ld1 {v6.16b}, [x4] /* load k3k4 */
+ ld1 {v5.16b}, [x5] /* load my_p */
+ eor v0.16b, v0.16b, v1.16b
+ b.lo .Lcrc32r_fold_by_one_done
+
+.Lcrc32r_fold_by_one:
+ sub x2, x2, #16
+ ld1 {v2.16b}, [x1], #16 /* load 16 bytes of input */
+ pmull v3.1q, v0.1d, v6.1d
+ pmull2 v1.1q, v0.2d, v6.2d
+ cmp x2, #16
+ eor v0.16b, v3.16b, v2.16b
+ eor v0.16b, v0.16b, v1.16b
+
+ b.hs .Lcrc32r_fold_by_one
+
+.Lcrc32r_fold_by_one_done:
+
+ cmp x2, #0
+ b.eq .Lcrc32r_final_fold
+
+ /* Partial fold. */
+
+ add x4, x7, #.Lcrc32_refl_shuf_shift - .Lcrc32_constants
+ add x5, x7, #.Lcrc32_refl_shuf_shift - .Lcrc32_constants + 16
+ add x6, x7, #.Lcrc32_partial_fold_input_mask - .Lcrc32_constants
+ sub x8, x2, #16
+ add x4, x4, x2
+ add x5, x5, x2
+ add x6, x6, x2
+ add x8, x1, x8
+
+ /* Load last input and add padding zeros. */
+ ld1 {v4.16b}, [x4]
+ eor x2, x2, x2
+ ld1 {v3.16b}, [x5]
+ ld1 {v2.16b}, [x6]
+ tbl v30.16b, {v0.16b}, v4.16b
+ ld1 {v4.16b}, [x8]
+ tbl v1.16b, {v0.16b}, v3.16b
+
+ pmull v0.1q, v30.1d, v6.1d
+ and v2.16b, v2.16b, v4.16b
+ pmull2 v31.1q, v30.2d, v6.2d
+ orr v2.16b, v2.16b, v1.16b
+ eor v0.16b, v0.16b, v31.16b
+ eor v0.16b, v0.16b, v2.16b
+
+.Lcrc32r_final_fold:
+
+ /* Final fold. */
+
+ eor v2.16b, v2.16b, v2.16b /* zero reg */
+ ld1 {v7.16b}, [x9]
+
+ /* reduce 128-bits to 96-bits */
+ ext v6.16b, v6.16b, v6.16b, #8 /* swap high and low parts */
+ mov v1.16b, v0.16b
+ pmull v0.1q, v0.1d, v6.1d
+ ext v6.16b, v5.16b, v5.16b, #8 /* swap high and low parts */
+ ext v1.16b, v1.16b, v2.16b, #8 /* high to low, high zeroed */
+ eor v3.16b, v0.16b, v1.16b
+
+ /* reduce 96-bits to 64-bits */
+ eor v1.16b, v1.16b, v1.16b
+ ext v0.16b, v3.16b, v2.16b, #4 /* [00][00][x2][x1] */
+ mov v1.s[0], v3.s[0] /* [00][00][00][x0] */
+ eor v3.16b, v3.16b, v3.16b
+ pmull v1.1q, v1.1d, v7.1d /* [00][00][xx][xx] */
+ eor v0.16b, v0.16b, v1.16b /* top 64-bit are zero */
+
+ /* barrett reduction */
+ mov v3.s[1], v0.s[0] /* [00][00][x1][00] */
+ ext v0.16b, v2.16b, v0.16b, #12 /* [??][x1][??][00] */
+ pmull v1.1q, v3.1d, v5.1d /* [00][xx][xx][00] */
+ pmull v1.1q, v1.1d, v6.1d /* [00][xx][xx][00] */
+ eor v0.16b, v0.16b, v1.16b
+
+ /* store CRC */
+ st1 {v0.s}[2], [x0]
+
+ ret
+ CFI_ENDPROC()
+ELF(.size _gcry_crc32r_armv8_ce_bulk,.-_gcry_crc32r_armv8_ce_bulk;)
+
+/*
+ * void _gcry_crc32r_armv8_ce_reduction_4 (u32 *pcrc, u32 data, u32 crc,
+ * const struct crc32_consts_s *consts);
+ */
+.align 3
+.globl _gcry_crc32r_armv8_ce_reduction_4
+ELF(.type _gcry_crc32r_armv8_ce_reduction_4,%function;)
+_gcry_crc32r_armv8_ce_reduction_4:
+ /* input:
+ * w0: data
+ * w1: crc
+ * x2: crc32 constants
+ */
+ CFI_STARTPROC()
+
+ eor v0.16b, v0.16b, v0.16b
+ add x2, x2, #consts_my_p(0)
+ eor v1.16b, v1.16b, v1.16b
+ ld1 {v5.16b}, [x2]
+
+ mov v0.s[0], w0
+ pmull v0.1q, v0.1d, v5.1d /* [00][00][xx][xx] */
+ mov v1.s[1], w1
+ mov v0.s[2], v0.s[0] /* [00][x0][x1][x0] */
+ pmull2 v0.1q, v0.2d, v5.2d /* [00][00][xx][xx] */
+ eor v0.16b, v0.16b, v1.16b
+
+ mov w0, v0.s[1]
+
+ ret
+ CFI_ENDPROC()
+ELF(.size _gcry_crc32r_armv8_ce_reduction_4,.-_gcry_crc32r_armv8_ce_reduction_4;)
+
+/*
+ * void _gcry_crc32_armv8_ce_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+ * const struct crc32_consts_s *consts);
+ */
+.align 3
+.globl _gcry_crc32_armv8_ce_bulk
+ELF(.type _gcry_crc32_armv8_ce_bulk,%function;)
+_gcry_crc32_armv8_ce_bulk:
+ /* input:
+ * x0: pcrc
+ * x1: inbuf
+ * x2: inlen
+ * x3: consts
+ */
+ CFI_STARTPROC()
+
+ GET_DATA_POINTER(x7, .Lcrc32_constants)
+ add x4, x7, #.Lcrc32_bswap_shuf - .Lcrc32_constants
+ cmp x2, #128
+ ld1 {v7.16b}, [x4]
+
+ b.lo .Lcrc32_fold_by_one_setup
+
+ eor v4.16b, v4.16b, v4.16b
+ add x4, x3, #consts_k(1 - 1)
+ ld1 {v4.s}[0], [x0] /* load pcrc */
+ ld1 {v0.16b-v3.16b}, [x1], #64 /* load 64 bytes of input */
+ sub x2, x2, #64
+ ld1 {v6.16b}, [x4]
+ eor v0.16b, v0.16b, v4.16b
+ ext v4.16b, v6.16b, v6.16b, #8
+ tbl v0.16b, { v0.16b }, v7.16b /* byte swap */
+ tbl v1.16b, { v1.16b }, v7.16b /* byte swap */
+ tbl v2.16b, { v2.16b }, v7.16b /* byte swap */
+ tbl v3.16b, { v3.16b }, v7.16b /* byte swap */
+
+ add x4, x3, #consts_k(3 - 1)
+ add x5, x3, #consts_my_p(0)
+
+.Lcrc32_fold_by_four:
+
+ /* Fold by 4. */
+ ld1 {v16.16b-v19.16b}, [x1], #64 /* load 64 bytes of input */
+ sub x2, x2, #64
+ tbl v16.16b, { v16.16b }, v7.16b /* byte swap */
+ tbl v17.16b, { v17.16b }, v7.16b /* byte swap */
+ tbl v18.16b, { v18.16b }, v7.16b /* byte swap */
+ tbl v19.16b, { v19.16b }, v7.16b /* byte swap */
+ cmp x2, #64
+ pmull2 v20.1q, v0.2d, v4.2d
+ pmull2 v21.1q, v1.2d, v4.2d
+ pmull2 v22.1q, v2.2d, v4.2d
+ pmull2 v23.1q, v3.2d, v4.2d
+ pmull v24.1q, v0.1d, v4.1d
+ pmull v25.1q, v1.1d, v4.1d
+ pmull v26.1q, v2.1d, v4.1d
+ pmull v27.1q, v3.1d, v4.1d
+ eor v0.16b, v20.16b, v16.16b
+ eor v1.16b, v21.16b, v17.16b
+ eor v2.16b, v22.16b, v18.16b
+ eor v3.16b, v23.16b, v19.16b
+ eor v0.16b, v0.16b, v24.16b
+ eor v1.16b, v1.16b, v25.16b
+ eor v2.16b, v2.16b, v26.16b
+ eor v3.16b, v3.16b, v27.16b
+ b.hs .Lcrc32_fold_by_four
+
+ ld1 {v6.16b}, [x4]
+ ld1 {v5.16b}, [x5]
+ ext v6.16b, v6.16b, v6.16b, #8
+ ext v5.16b, v5.16b, v5.16b, #8
+
+ cmp x2, #16
+
+ /* Fold 4 to 1. */
+
+ pmull2 v16.1q, v0.2d, v6.2d
+ pmull v4.1q, v0.1d, v6.1d
+ eor v0.16b, v16.16b, v1.16b
+ eor v0.16b, v0.16b, v4.16b
+
+ pmull2 v16.1q, v0.2d, v6.2d
+ pmull v4.1q, v0.1d, v6.1d
+ eor v0.16b, v16.16b, v2.16b
+ eor v0.16b, v0.16b, v4.16b
+
+ pmull2 v16.1q, v0.2d, v6.2d
+ pmull v4.1q, v0.1d, v6.1d
+ eor v0.16b, v16.16b, v3.16b
+ eor v0.16b, v0.16b, v4.16b
+
+ b.lo .Lcrc32_fold_by_one_done
+ b .Lcrc32_fold_by_one
+
+.Lcrc32_fold_by_one_setup:
+
+ eor v1.16b, v1.16b, v1.16b
+ add x4, x3, #consts_k(3 - 1)
+ add x5, x3, #consts_my_p(0)
+ ld1 {v1.s}[0], [x0] /* load pcrc */
+ sub x2, x2, #16
+ ld1 {v0.16b}, [x1], #16 /* load 16 bytes of input */
+ ld1 {v6.16b}, [x4] /* load k3k4 */
+ ld1 {v5.16b}, [x5] /* load my_p */
+ eor v0.16b, v0.16b, v1.16b
+ cmp x2, #16
+ ext v6.16b, v6.16b, v6.16b, #8 /* swap high and low parts */
+ ext v5.16b, v5.16b, v5.16b, #8 /* swap high and low parts */
+ tbl v0.16b, { v0.16b }, v7.16b /* byte swap */
+ b.lo .Lcrc32_fold_by_one_done
+
+.Lcrc32_fold_by_one:
+ sub x2, x2, #16
+ ld1 {v2.16b}, [x1], #16 /* load 16 bytes of input */
+ pmull2 v3.1q, v0.2d, v6.2d
+ tbl v2.16b, { v2.16b }, v7.16b /* byte swap */
+ pmull v1.1q, v0.1d, v6.1d
+ cmp x2, #16
+ eor v0.16b, v3.16b, v2.16b
+ eor v0.16b, v0.16b, v1.16b
+
+ b.hs .Lcrc32_fold_by_one
+
+.Lcrc32_fold_by_one_done:
+
+ cmp x2, #0
+ b.eq .Lcrc32_final_fold
+
+ /* Partial fold. */
+
+ add x4, x7, #.Lcrc32_refl_shuf_shift - .Lcrc32_constants + 32
+ add x5, x7, #.Lcrc32_shuf_shift - .Lcrc32_constants + 16
+ add x6, x7, #.Lcrc32_partial_fold_input_mask - .Lcrc32_constants
+ sub x8, x2, #16
+ sub x4, x4, x2
+ add x5, x5, x2
+ add x6, x6, x2
+ add x8, x1, x8
+
+ /* Load last input and add padding zeros. */
+ ld1 {v4.16b}, [x4]
+ eor x2, x2, x2
+ ld1 {v3.16b}, [x5]
+ ld1 {v2.16b}, [x6]
+ tbl v30.16b, {v0.16b}, v4.16b
+ ld1 {v4.16b}, [x8]
+ tbl v1.16b, {v0.16b}, v3.16b
+ and v2.16b, v2.16b, v4.16b
+
+ pmull2 v0.1q, v30.2d, v6.2d
+ orr v2.16b, v2.16b, v1.16b
+ pmull v1.1q, v30.1d, v6.1d
+ tbl v2.16b, {v2.16b}, v7.16b /* byte swap */
+ eor v0.16b, v0.16b, v1.16b
+ eor v0.16b, v0.16b, v2.16b
+
+.Lcrc32_final_fold:
+
+ /* Final fold. */
+
+ eor v2.16b, v2.16b, v2.16b /* zero reg */
+
+ /* reduce 128-bits to 96-bits */
+ add x4, x3, #consts_k(4)
+ ext v3.16b, v6.16b, v6.16b, #8 /* swap high and low parts */
+ eor v6.16b, v6.16b, v6.16b
+ mov v1.16b, v0.16b
+ pmull2 v0.1q, v0.2d, v3.2d
+ ld1 {v6.d}[1], [x4] /* load k4 */
+ ext v1.16b, v2.16b, v1.16b, #8 /* low to high, low zeroed */
+ eor v3.16b, v0.16b, v1.16b /* bottom 32-bit are zero */
+
+ /* reduce 96-bits to 64-bits */
+ eor v0.16b, v0.16b, v0.16b
+ eor v1.16b, v1.16b, v1.16b
+ mov v0.s[1], v3.s[1] /* [00][00][x1][00] */
+ mov v1.s[2], v3.s[3] /* [00][x3][00][00] */
+ mov v0.s[2], v3.s[2] /* [00][x2][x1][00] */
+ eor v3.16b, v3.16b, v3.16b
+ pmull2 v1.1q, v1.2d, v6.2d /* [00][xx][xx][00] */
+ eor v0.16b, v0.16b, v1.16b /* top and bottom 32-bit are zero */
+
+ /* barrett reduction */
+ mov v3.s[0], v0.s[1] /* [00][00][00][x1] */
+ pmull2 v0.1q, v0.2d, v5.2d /* [00][xx][xx][xx] */
+ ext v0.16b, v0.16b, v2.16b, #4 /* [00][00][xx][xx] */
+ pmull v0.1q, v0.1d, v5.1d
+ eor v0.16b, v0.16b, v3.16b
+
+ /* store CRC in input endian */
+ rev32 v0.8b, v0.8b /* byte swap */
+ st1 {v0.s}[0], [x0]
+
+ ret
+ CFI_ENDPROC()
+ELF(.size _gcry_crc32_armv8_ce_bulk,.-_gcry_crc32_armv8_ce_bulk;)
+
+/*
+ * void _gcry_crc32_armv8_ce_reduction_4 (u32 *pcrc, u32 data, u32 crc,
+ * const struct crc32_consts_s *consts);
+ */
+.align 3
+.globl _gcry_crc32_armv8_ce_reduction_4
+ELF(.type _gcry_crc32_armv8_ce_reduction_4,%function;)
+_gcry_crc32_armv8_ce_reduction_4:
+ /* input:
+ * w0: data
+ * w1: crc
+ * x2: crc32 constants
+ */
+ CFI_STARTPROC()
+
+ eor v0.16b, v0.16b, v0.16b
+ add x2, x2, #consts_my_p(0)
+ eor v1.16b, v1.16b, v1.16b
+ ld1 {v5.16b}, [x2]
+
+ mov v0.s[1], w0
+ pmull v0.1q, v0.1d, v5.1d /* [00][xx][xx][00] */
+ mov v1.s[0], w1
+ pmull2 v0.1q, v0.2d, v5.2d /* [00][00][xx][xx] */
+ eor v0.16b, v0.16b, v1.16b
+
+ rev32 v0.8b, v0.8b /* Return in input endian */
+ mov w0, v0.s[0]
+
+ ret
+ CFI_ENDPROC()
+ELF(.size _gcry_crc32_armv8_ce_reduction_4,.-_gcry_crc32_armv8_ce_reduction_4;)
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/crc-armv8-ce.c b/comm/third_party/libgcrypt/cipher/crc-armv8-ce.c
new file mode 100644
index 0000000000..17e5554821
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/crc-armv8-ce.c
@@ -0,0 +1,229 @@
+/* crc-armv8-ce.c - ARMv8-CE PMULL accelerated CRC implementation
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+
+#include "bithelp.h"
+#include "bufhelp.h"
+
+
+#if defined(ENABLE_ARM_CRYPTO_SUPPORT) && defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+
+
+#define ALIGNED_16 __attribute__ ((aligned (16)))
+
+
+struct u16_unaligned_s
+{
+ u16 a;
+} __attribute__((packed, aligned (1), may_alias));
+
+struct u32_unaligned_s
+{
+ u32 a;
+} __attribute__((packed, aligned (1), may_alias));
+
+
+/* Constants structure for generic reflected/non-reflected CRC32 PMULL
+ * functions. */
+struct crc32_consts_s
+{
+ /* k: { x^(32*17), x^(32*15), x^(32*5), x^(32*3), x^(32*2), 0 } mod P(x) */
+ u64 k[6];
+ /* my_p: { floor(x^64 / P(x)), P(x) } */
+ u64 my_p[2];
+};
+
+/* PMULL constants for CRC32 and CRC32RFC1510. */
+static const struct crc32_consts_s crc32_consts ALIGNED_16 =
+{
+ { /* k[6] = reverse_33bits( x^(32*y) mod P(x) ) */
+ U64_C(0x154442bd4), U64_C(0x1c6e41596), /* y = { 17, 15 } */
+ U64_C(0x1751997d0), U64_C(0x0ccaa009e), /* y = { 5, 3 } */
+ U64_C(0x163cd6124), 0 /* y = 2 */
+ },
+ { /* my_p[2] = reverse_33bits ( { floor(x^64 / P(x)), P(x) } ) */
+ U64_C(0x1f7011641), U64_C(0x1db710641)
+ }
+};
+
+/* PMULL constants for CRC24RFC2440 (polynomial multiplied with xâ¸). */
+static const struct crc32_consts_s crc24rfc2440_consts ALIGNED_16 =
+{
+ { /* k[6] = x^(32*y) mod P(x) << 32*/
+ U64_C(0x08289a00) << 32, U64_C(0x74b44a00) << 32, /* y = { 17, 15 } */
+ U64_C(0xc4b14d00) << 32, U64_C(0xfd7e0c00) << 32, /* y = { 5, 3 } */
+ U64_C(0xd9fe8c00) << 32, 0 /* y = 2 */
+ },
+ { /* my_p[2] = { floor(x^64 / P(x)), P(x) } */
+ U64_C(0x1f845fe24), U64_C(0x1864cfb00)
+ }
+};
+
+
+u32 _gcry_crc32r_armv8_ce_reduction_4 (u32 data, u32 crc,
+ const struct crc32_consts_s *consts);
+void _gcry_crc32r_armv8_ce_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts);
+
+u32 _gcry_crc32_armv8_ce_reduction_4 (u32 data, u32 crc,
+ const struct crc32_consts_s *consts);
+void _gcry_crc32_armv8_ce_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts);
+
+
+static inline void
+crc32r_less_than_16 (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ u32 crc = *pcrc;
+ u32 data;
+
+ while (inlen >= 4)
+ {
+ data = ((const struct u32_unaligned_s *)inbuf)->a;
+ data ^= crc;
+
+ inlen -= 4;
+ inbuf += 4;
+
+ crc = _gcry_crc32r_armv8_ce_reduction_4 (data, 0, consts);
+ }
+
+ switch (inlen)
+ {
+ case 0:
+ break;
+ case 1:
+ data = inbuf[0];
+ data ^= crc;
+ data <<= 24;
+ crc >>= 8;
+ crc = _gcry_crc32r_armv8_ce_reduction_4 (data, crc, consts);
+ break;
+ case 2:
+ data = ((const struct u16_unaligned_s *)inbuf)->a;
+ data ^= crc;
+ data <<= 16;
+ crc >>= 16;
+ crc = _gcry_crc32r_armv8_ce_reduction_4 (data, crc, consts);
+ break;
+ case 3:
+ data = ((const struct u16_unaligned_s *)inbuf)->a;
+ data |= inbuf[2] << 16;
+ data ^= crc;
+ data <<= 8;
+ crc >>= 24;
+ crc = _gcry_crc32r_armv8_ce_reduction_4 (data, crc, consts);
+ break;
+ }
+
+ *pcrc = crc;
+}
+
+static inline void
+crc32_less_than_16 (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ u32 crc = *pcrc;
+ u32 data;
+
+ while (inlen >= 4)
+ {
+ data = ((const struct u32_unaligned_s *)inbuf)->a;
+ data ^= crc;
+ data = _gcry_bswap32(data);
+
+ inlen -= 4;
+ inbuf += 4;
+
+ crc = _gcry_crc32_armv8_ce_reduction_4 (data, 0, consts);
+ }
+
+ switch (inlen)
+ {
+ case 0:
+ break;
+ case 1:
+ data = inbuf[0];
+ data ^= crc;
+ data = data & 0xffU;
+ crc = _gcry_bswap32(crc >> 8);
+ crc = _gcry_crc32_armv8_ce_reduction_4 (data, crc, consts);
+ break;
+ case 2:
+ data = ((const struct u16_unaligned_s *)inbuf)->a;
+ data ^= crc;
+ data = _gcry_bswap32(data << 16);
+ crc = _gcry_bswap32(crc >> 16);
+ crc = _gcry_crc32_armv8_ce_reduction_4 (data, crc, consts);
+ break;
+ case 3:
+ data = ((const struct u16_unaligned_s *)inbuf)->a;
+ data |= inbuf[2] << 16;
+ data ^= crc;
+ data = _gcry_bswap32(data << 8);
+ crc = crc & 0xff000000U;
+ crc = _gcry_crc32_armv8_ce_reduction_4 (data, crc, consts);
+ break;
+ }
+
+ *pcrc = crc;
+}
+
+void
+_gcry_crc32_armv8_ce_pmull (u32 *pcrc, const byte *inbuf, size_t inlen)
+{
+ const struct crc32_consts_s *consts = &crc32_consts;
+
+ if (!inlen)
+ return;
+
+ if (inlen >= 16)
+ _gcry_crc32r_armv8_ce_bulk (pcrc, inbuf, inlen, consts);
+ else
+ crc32r_less_than_16 (pcrc, inbuf, inlen, consts);
+}
+
+void
+_gcry_crc24rfc2440_armv8_ce_pmull (u32 *pcrc, const byte *inbuf, size_t inlen)
+{
+ const struct crc32_consts_s *consts = &crc24rfc2440_consts;
+
+ if (!inlen)
+ return;
+
+ /* Note: *pcrc in input endian. */
+
+ if (inlen >= 16)
+ _gcry_crc32_armv8_ce_bulk (pcrc, inbuf, inlen, consts);
+ else
+ crc32_less_than_16 (pcrc, inbuf, inlen, consts);
+}
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/crc-intel-pclmul.c b/comm/third_party/libgcrypt/cipher/crc-intel-pclmul.c
new file mode 100644
index 0000000000..8c8b1915ab
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/crc-intel-pclmul.c
@@ -0,0 +1,939 @@
+/* crc-intel-pclmul.c - Intel PCLMUL accelerated CRC implementation
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+
+#include "bithelp.h"
+#include "bufhelp.h"
+
+
+#if defined(ENABLE_PCLMUL_SUPPORT) && defined(ENABLE_SSE41_SUPPORT) && \
+ __GNUC__ >= 4 && \
+ ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
+
+
+#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
+
+
+#define ALIGNED_16 __attribute__ ((aligned (16)))
+
+
+struct u16_unaligned_s
+{
+ u16 a;
+} __attribute__((packed, aligned (1), may_alias));
+
+
+/* Constants structure for generic reflected/non-reflected CRC32 CLMUL
+ * functions. */
+struct crc32_consts_s
+{
+ /* k: { x^(32*17), x^(32*15), x^(32*5), x^(32*3), x^(32*2), 0 } mod P(x) */
+ u64 k[6];
+ /* my_p: { floor(x^64 / P(x)), P(x) } */
+ u64 my_p[2];
+};
+
+
+/* CLMUL constants for CRC32 and CRC32RFC1510. */
+static const struct crc32_consts_s crc32_consts ALIGNED_16 =
+{
+ { /* k[6] = reverse_33bits( x^(32*y) mod P(x) ) */
+ U64_C(0x154442bd4), U64_C(0x1c6e41596), /* y = { 17, 15 } */
+ U64_C(0x1751997d0), U64_C(0x0ccaa009e), /* y = { 5, 3 } */
+ U64_C(0x163cd6124), 0 /* y = 2 */
+ },
+ { /* my_p[2] = reverse_33bits ( { floor(x^64 / P(x)), P(x) } ) */
+ U64_C(0x1f7011641), U64_C(0x1db710641)
+ }
+};
+
+/* CLMUL constants for CRC24RFC2440 (polynomial multiplied with xâ¸). */
+static const struct crc32_consts_s crc24rfc2440_consts ALIGNED_16 =
+{
+ { /* k[6] = x^(32*y) mod P(x) << 32*/
+ U64_C(0x08289a00) << 32, U64_C(0x74b44a00) << 32, /* y = { 17, 15 } */
+ U64_C(0xc4b14d00) << 32, U64_C(0xfd7e0c00) << 32, /* y = { 5, 3 } */
+ U64_C(0xd9fe8c00) << 32, 0 /* y = 2 */
+ },
+ { /* my_p[2] = { floor(x^64 / P(x)), P(x) } */
+ U64_C(0x1f845fe24), U64_C(0x1864cfb00)
+ }
+};
+
+/* Common constants for CRC32 algorithms. */
+static const byte crc32_refl_shuf_shift[3 * 16] ALIGNED_16 =
+ {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+static const byte crc32_shuf_shift[3 * 16] ALIGNED_16 =
+ {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+static const byte *crc32_bswap_shuf = &crc32_shuf_shift[16];
+static const byte crc32_partial_fold_input_mask[16 + 16] ALIGNED_16 =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+static const u64 crc32_merge9to15_shuf[15 - 9 + 1][2] ALIGNED_16 =
+ {
+ { U64_C(0x0706050403020100), U64_C(0xffffffffffffff0f) }, /* 9 */
+ { U64_C(0x0706050403020100), U64_C(0xffffffffffff0f0e) },
+ { U64_C(0x0706050403020100), U64_C(0xffffffffff0f0e0d) },
+ { U64_C(0x0706050403020100), U64_C(0xffffffff0f0e0d0c) },
+ { U64_C(0x0706050403020100), U64_C(0xffffff0f0e0d0c0b) },
+ { U64_C(0x0706050403020100), U64_C(0xffff0f0e0d0c0b0a) },
+ { U64_C(0x0706050403020100), U64_C(0xff0f0e0d0c0b0a09) }, /* 15 */
+ };
+static const u64 crc32_merge5to7_shuf[7 - 5 + 1][2] ALIGNED_16 =
+ {
+ { U64_C(0xffffff0703020100), U64_C(0xffffffffffffffff) }, /* 5 */
+ { U64_C(0xffff070603020100), U64_C(0xffffffffffffffff) },
+ { U64_C(0xff07060503020100), U64_C(0xffffffffffffffff) }, /* 7 */
+ };
+
+/* PCLMUL functions for reflected CRC32. */
+static ASM_FUNC_ATTR_INLINE void
+crc32_reflected_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ if (inlen >= 8 * 16)
+ {
+ asm volatile ("movd %[crc], %%xmm4\n\t"
+ "movdqu %[inbuf_0], %%xmm0\n\t"
+ "movdqu %[inbuf_1], %%xmm1\n\t"
+ "movdqu %[inbuf_2], %%xmm2\n\t"
+ "movdqu %[inbuf_3], %%xmm3\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+ :
+ : [inbuf_0] "m" (inbuf[0 * 16]),
+ [inbuf_1] "m" (inbuf[1 * 16]),
+ [inbuf_2] "m" (inbuf[2 * 16]),
+ [inbuf_3] "m" (inbuf[3 * 16]),
+ [crc] "m" (*pcrc)
+ );
+
+ inbuf += 4 * 16;
+ inlen -= 4 * 16;
+
+ asm volatile ("movdqa %[k1k2], %%xmm4\n\t"
+ :
+ : [k1k2] "m" (consts->k[1 - 1])
+ );
+
+ /* Fold by 4. */
+ while (inlen >= 4 * 16)
+ {
+ asm volatile ("movdqu %[inbuf_0], %%xmm5\n\t"
+ "movdqa %%xmm0, %%xmm6\n\t"
+ "pclmulqdq $0x00, %%xmm4, %%xmm0\n\t"
+ "pclmulqdq $0x11, %%xmm4, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm0\n\t"
+ "pxor %%xmm6, %%xmm0\n\t"
+
+ "movdqu %[inbuf_1], %%xmm5\n\t"
+ "movdqa %%xmm1, %%xmm6\n\t"
+ "pclmulqdq $0x00, %%xmm4, %%xmm1\n\t"
+ "pclmulqdq $0x11, %%xmm4, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm1\n\t"
+ "pxor %%xmm6, %%xmm1\n\t"
+
+ "movdqu %[inbuf_2], %%xmm5\n\t"
+ "movdqa %%xmm2, %%xmm6\n\t"
+ "pclmulqdq $0x00, %%xmm4, %%xmm2\n\t"
+ "pclmulqdq $0x11, %%xmm4, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm2\n\t"
+ "pxor %%xmm6, %%xmm2\n\t"
+
+ "movdqu %[inbuf_3], %%xmm5\n\t"
+ "movdqa %%xmm3, %%xmm6\n\t"
+ "pclmulqdq $0x00, %%xmm4, %%xmm3\n\t"
+ "pclmulqdq $0x11, %%xmm4, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm3\n\t"
+ "pxor %%xmm6, %%xmm3\n\t"
+ :
+ : [inbuf_0] "m" (inbuf[0 * 16]),
+ [inbuf_1] "m" (inbuf[1 * 16]),
+ [inbuf_2] "m" (inbuf[2 * 16]),
+ [inbuf_3] "m" (inbuf[3 * 16])
+ );
+
+ inbuf += 4 * 16;
+ inlen -= 4 * 16;
+ }
+
+ asm volatile ("movdqa %[k3k4], %%xmm6\n\t"
+ "movdqa %[my_p], %%xmm5\n\t"
+ :
+ : [k3k4] "m" (consts->k[3 - 1]),
+ [my_p] "m" (consts->my_p[0])
+ );
+
+ /* Fold 4 to 1. */
+
+ asm volatile ("movdqa %%xmm0, %%xmm4\n\t"
+ "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x11, %%xmm6, %%xmm4\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+
+ "movdqa %%xmm0, %%xmm4\n\t"
+ "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x11, %%xmm6, %%xmm4\n\t"
+ "pxor %%xmm2, %%xmm0\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+
+ "movdqa %%xmm0, %%xmm4\n\t"
+ "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x11, %%xmm6, %%xmm4\n\t"
+ "pxor %%xmm3, %%xmm0\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+ :
+ :
+ );
+ }
+ else
+ {
+ asm volatile ("movd %[crc], %%xmm1\n\t"
+ "movdqu %[inbuf], %%xmm0\n\t"
+ "movdqa %[k3k4], %%xmm6\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ "movdqa %[my_p], %%xmm5\n\t"
+ :
+ : [inbuf] "m" (*inbuf),
+ [crc] "m" (*pcrc),
+ [k3k4] "m" (consts->k[3 - 1]),
+ [my_p] "m" (consts->my_p[0])
+ );
+
+ inbuf += 16;
+ inlen -= 16;
+ }
+
+ /* Fold by 1. */
+ if (inlen >= 16)
+ {
+ while (inlen >= 16)
+ {
+ /* Load next block to XMM2. Fold XMM0 to XMM0:XMM1. */
+ asm volatile ("movdqu %[inbuf], %%xmm2\n\t"
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x11, %%xmm6, %%xmm1\n\t"
+ "pxor %%xmm2, %%xmm0\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*inbuf)
+ );
+
+ inbuf += 16;
+ inlen -= 16;
+ }
+ }
+
+ /* Partial fold. */
+ if (inlen)
+ {
+ /* Load last input and add padding zeros. */
+ asm volatile ("movdqu %[shr_shuf], %%xmm3\n\t"
+ "movdqu %[shl_shuf], %%xmm4\n\t"
+ "movdqu %[mask], %%xmm2\n\t"
+
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pshufb %%xmm4, %%xmm0\n\t"
+ "movdqu %[inbuf], %%xmm4\n\t"
+ "pshufb %%xmm3, %%xmm1\n\t"
+ "pand %%xmm4, %%xmm2\n\t"
+ "por %%xmm1, %%xmm2\n\t"
+
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pclmulqdq $0x00, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x11, %%xmm6, %%xmm1\n\t"
+ "pxor %%xmm2, %%xmm0\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*(inbuf - 16 + inlen)),
+ [mask] "m" (crc32_partial_fold_input_mask[inlen]),
+ [shl_shuf] "m" (crc32_refl_shuf_shift[inlen]),
+ [shr_shuf] "m" (crc32_refl_shuf_shift[inlen + 16])
+ );
+
+ inbuf += inlen;
+ inlen -= inlen;
+ }
+
+ /* Final fold. */
+ asm volatile (/* reduce 128-bits to 96-bits */
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pclmulqdq $0x10, %%xmm6, %%xmm0\n\t"
+ "psrldq $8, %%xmm1\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+
+ /* reduce 96-bits to 64-bits */
+ "pshufd $0xfc, %%xmm0, %%xmm1\n\t" /* [00][00][00][x] */
+ "pshufd $0xf9, %%xmm0, %%xmm0\n\t" /* [00][00][x>>64][x>>32] */
+ "pclmulqdq $0x00, %[k5], %%xmm1\n\t" /* [00][00][xx][xx] */
+ "pxor %%xmm1, %%xmm0\n\t" /* top 64-bit are zero */
+
+ /* barrett reduction */
+ "pshufd $0xf3, %%xmm0, %%xmm1\n\t" /* [00][00][x>>32][00] */
+ "pslldq $4, %%xmm0\n\t" /* [??][x>>32][??][??] */
+ "pclmulqdq $0x00, %%xmm5, %%xmm1\n\t" /* [00][xx][xx][00] */
+ "pclmulqdq $0x10, %%xmm5, %%xmm1\n\t" /* [00][xx][xx][00] */
+ "pxor %%xmm1, %%xmm0\n\t"
+
+ /* store CRC */
+ "pextrd $2, %%xmm0, %[out]\n\t"
+ : [out] "=m" (*pcrc)
+ : [k5] "m" (consts->k[5 - 1])
+ );
+}
+
+static ASM_FUNC_ATTR_INLINE void
+crc32_reflected_less_than_16 (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ if (inlen < 4)
+ {
+ u32 crc = *pcrc;
+ u32 data;
+
+ asm volatile ("movdqa %[my_p], %%xmm5\n\t"
+ :
+ : [my_p] "m" (consts->my_p[0])
+ );
+
+ if (inlen == 1)
+ {
+ data = inbuf[0];
+ data ^= crc;
+ data <<= 24;
+ crc >>= 8;
+ }
+ else if (inlen == 2)
+ {
+ data = ((const struct u16_unaligned_s *)inbuf)->a;
+ data ^= crc;
+ data <<= 16;
+ crc >>= 16;
+ }
+ else
+ {
+ data = ((const struct u16_unaligned_s *)inbuf)->a;
+ data |= inbuf[2] << 16;
+ data ^= crc;
+ data <<= 8;
+ crc >>= 24;
+ }
+
+ /* Barrett reduction */
+ asm volatile ("movd %[in], %%xmm0\n\t"
+ "movd %[crc], %%xmm1\n\t"
+
+ "pclmulqdq $0x00, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+ "psllq $32, %%xmm1\n\t"
+ "pshufd $0xfc, %%xmm0, %%xmm0\n\t" /* [00][00][00][x] */
+ "pclmulqdq $0x10, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+ "pxor %%xmm1, %%xmm0\n\t"
+
+ "pextrd $1, %%xmm0, %[out]\n\t"
+ : [out] "=m" (*pcrc)
+ : [in] "rm" (data),
+ [crc] "rm" (crc)
+ );
+ }
+ else if (inlen == 4)
+ {
+ /* Barrett reduction */
+ asm volatile ("movd %[crc], %%xmm1\n\t"
+ "movd %[in], %%xmm0\n\t"
+ "movdqa %[my_p], %%xmm5\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+
+ "pclmulqdq $0x00, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+ "pshufd $0xfc, %%xmm0, %%xmm0\n\t" /* [00][00][00][x] */
+ "pclmulqdq $0x10, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+
+ "pextrd $1, %%xmm0, %[out]\n\t"
+ : [out] "=m" (*pcrc)
+ : [in] "m" (*inbuf),
+ [crc] "m" (*pcrc),
+ [my_p] "m" (consts->my_p[0])
+ );
+ }
+ else
+ {
+ asm volatile ("movdqu %[shuf], %%xmm4\n\t"
+ "movd %[crc], %%xmm1\n\t"
+ "movdqa %[my_p], %%xmm5\n\t"
+ "movdqa %[k3k4], %%xmm6\n\t"
+ :
+ : [shuf] "m" (crc32_refl_shuf_shift[inlen]),
+ [crc] "m" (*pcrc),
+ [my_p] "m" (consts->my_p[0]),
+ [k3k4] "m" (consts->k[3 - 1])
+ );
+
+ if (inlen >= 8)
+ {
+ asm volatile ("movq %[inbuf], %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*inbuf)
+ );
+ if (inlen > 8)
+ {
+ asm volatile (/*"pinsrq $1, %[inbuf_tail], %%xmm0\n\t"*/
+ "movq %[inbuf_tail], %%xmm2\n\t"
+ "punpcklqdq %%xmm2, %%xmm0\n\t"
+ "pshufb %[merge_shuf], %%xmm0\n\t"
+ :
+ : [inbuf_tail] "m" (inbuf[inlen - 8]),
+ [merge_shuf] "m"
+ (*crc32_merge9to15_shuf[inlen - 9])
+ );
+ }
+ }
+ else
+ {
+ asm volatile ("movd %[inbuf], %%xmm0\n\t"
+ "pinsrd $1, %[inbuf_tail], %%xmm0\n\t"
+ "pshufb %[merge_shuf], %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*inbuf),
+ [inbuf_tail] "m" (inbuf[inlen - 4]),
+ [merge_shuf] "m"
+ (*crc32_merge5to7_shuf[inlen - 5])
+ );
+ }
+
+ /* Final fold. */
+ asm volatile ("pxor %%xmm1, %%xmm0\n\t"
+ "pshufb %%xmm4, %%xmm0\n\t"
+
+ /* reduce 128-bits to 96-bits */
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pclmulqdq $0x10, %%xmm6, %%xmm0\n\t"
+ "psrldq $8, %%xmm1\n\t"
+ "pxor %%xmm1, %%xmm0\n\t" /* top 32-bit are zero */
+
+ /* reduce 96-bits to 64-bits */
+ "pshufd $0xfc, %%xmm0, %%xmm1\n\t" /* [00][00][00][x] */
+ "pshufd $0xf9, %%xmm0, %%xmm0\n\t" /* [00][00][x>>64][x>>32] */
+ "pclmulqdq $0x00, %[k5], %%xmm1\n\t" /* [00][00][xx][xx] */
+ "pxor %%xmm1, %%xmm0\n\t" /* top 64-bit are zero */
+
+ /* barrett reduction */
+ "pshufd $0xf3, %%xmm0, %%xmm1\n\t" /* [00][00][x>>32][00] */
+ "pslldq $4, %%xmm0\n\t" /* [??][x>>32][??][??] */
+ "pclmulqdq $0x00, %%xmm5, %%xmm1\n\t" /* [00][xx][xx][00] */
+ "pclmulqdq $0x10, %%xmm5, %%xmm1\n\t" /* [00][xx][xx][00] */
+ "pxor %%xmm1, %%xmm0\n\t"
+
+ /* store CRC */
+ "pextrd $2, %%xmm0, %[out]\n\t"
+ : [out] "=m" (*pcrc)
+ : [k5] "m" (consts->k[5 - 1])
+ );
+ }
+}
+
+/* PCLMUL functions for non-reflected CRC32. */
+static ASM_FUNC_ATTR_INLINE void
+crc32_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ asm volatile ("movdqa %[bswap], %%xmm7\n\t"
+ :
+ : [bswap] "m" (*crc32_bswap_shuf)
+ );
+
+ if (inlen >= 8 * 16)
+ {
+ asm volatile ("movd %[crc], %%xmm4\n\t"
+ "movdqu %[inbuf_0], %%xmm0\n\t"
+ "movdqu %[inbuf_1], %%xmm1\n\t"
+ "movdqu %[inbuf_2], %%xmm2\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+ "movdqu %[inbuf_3], %%xmm3\n\t"
+ "pshufb %%xmm7, %%xmm0\n\t"
+ "pshufb %%xmm7, %%xmm1\n\t"
+ "pshufb %%xmm7, %%xmm2\n\t"
+ "pshufb %%xmm7, %%xmm3\n\t"
+ :
+ : [inbuf_0] "m" (inbuf[0 * 16]),
+ [inbuf_1] "m" (inbuf[1 * 16]),
+ [inbuf_2] "m" (inbuf[2 * 16]),
+ [inbuf_3] "m" (inbuf[3 * 16]),
+ [crc] "m" (*pcrc)
+ );
+
+ inbuf += 4 * 16;
+ inlen -= 4 * 16;
+
+ asm volatile ("movdqa %[k1k2], %%xmm4\n\t"
+ :
+ : [k1k2] "m" (consts->k[1 - 1])
+ );
+
+ /* Fold by 4. */
+ while (inlen >= 4 * 16)
+ {
+ asm volatile ("movdqu %[inbuf_0], %%xmm5\n\t"
+ "movdqa %%xmm0, %%xmm6\n\t"
+ "pshufb %%xmm7, %%xmm5\n\t"
+ "pclmulqdq $0x01, %%xmm4, %%xmm0\n\t"
+ "pclmulqdq $0x10, %%xmm4, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm0\n\t"
+ "pxor %%xmm6, %%xmm0\n\t"
+
+ "movdqu %[inbuf_1], %%xmm5\n\t"
+ "movdqa %%xmm1, %%xmm6\n\t"
+ "pshufb %%xmm7, %%xmm5\n\t"
+ "pclmulqdq $0x01, %%xmm4, %%xmm1\n\t"
+ "pclmulqdq $0x10, %%xmm4, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm1\n\t"
+ "pxor %%xmm6, %%xmm1\n\t"
+
+ "movdqu %[inbuf_2], %%xmm5\n\t"
+ "movdqa %%xmm2, %%xmm6\n\t"
+ "pshufb %%xmm7, %%xmm5\n\t"
+ "pclmulqdq $0x01, %%xmm4, %%xmm2\n\t"
+ "pclmulqdq $0x10, %%xmm4, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm2\n\t"
+ "pxor %%xmm6, %%xmm2\n\t"
+
+ "movdqu %[inbuf_3], %%xmm5\n\t"
+ "movdqa %%xmm3, %%xmm6\n\t"
+ "pshufb %%xmm7, %%xmm5\n\t"
+ "pclmulqdq $0x01, %%xmm4, %%xmm3\n\t"
+ "pclmulqdq $0x10, %%xmm4, %%xmm6\n\t"
+ "pxor %%xmm5, %%xmm3\n\t"
+ "pxor %%xmm6, %%xmm3\n\t"
+ :
+ : [inbuf_0] "m" (inbuf[0 * 16]),
+ [inbuf_1] "m" (inbuf[1 * 16]),
+ [inbuf_2] "m" (inbuf[2 * 16]),
+ [inbuf_3] "m" (inbuf[3 * 16])
+ );
+
+ inbuf += 4 * 16;
+ inlen -= 4 * 16;
+ }
+
+ asm volatile ("movdqa %[k3k4], %%xmm6\n\t"
+ "movdqa %[my_p], %%xmm5\n\t"
+ :
+ : [k3k4] "m" (consts->k[3 - 1]),
+ [my_p] "m" (consts->my_p[0])
+ );
+
+ /* Fold 4 to 1. */
+
+ asm volatile ("movdqa %%xmm0, %%xmm4\n\t"
+ "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x10, %%xmm6, %%xmm4\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+
+ "movdqa %%xmm0, %%xmm4\n\t"
+ "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x10, %%xmm6, %%xmm4\n\t"
+ "pxor %%xmm2, %%xmm0\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+
+ "movdqa %%xmm0, %%xmm4\n\t"
+ "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x10, %%xmm6, %%xmm4\n\t"
+ "pxor %%xmm3, %%xmm0\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+ :
+ :
+ );
+ }
+ else
+ {
+ asm volatile ("movd %[crc], %%xmm1\n\t"
+ "movdqu %[inbuf], %%xmm0\n\t"
+ "movdqa %[k3k4], %%xmm6\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ "movdqa %[my_p], %%xmm5\n\t"
+ "pshufb %%xmm7, %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*inbuf),
+ [crc] "m" (*pcrc),
+ [k3k4] "m" (consts->k[3 - 1]),
+ [my_p] "m" (consts->my_p[0])
+ );
+
+ inbuf += 16;
+ inlen -= 16;
+ }
+
+ /* Fold by 1. */
+ if (inlen >= 16)
+ {
+ while (inlen >= 16)
+ {
+ /* Load next block to XMM2. Fold XMM0 to XMM0:XMM1. */
+ asm volatile ("movdqu %[inbuf], %%xmm2\n\t"
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+ "pshufb %%xmm7, %%xmm2\n\t"
+ "pclmulqdq $0x10, %%xmm6, %%xmm1\n\t"
+ "pxor %%xmm2, %%xmm0\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*inbuf)
+ );
+
+ inbuf += 16;
+ inlen -= 16;
+ }
+ }
+
+ /* Partial fold. */
+ if (inlen)
+ {
+ /* Load last input and add padding zeros. */
+ asm volatile ("movdqu %[shl_shuf], %%xmm4\n\t"
+ "movdqu %[shr_shuf], %%xmm3\n\t"
+ "movdqu %[mask], %%xmm2\n\t"
+
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pshufb %%xmm4, %%xmm0\n\t"
+ "movdqu %[inbuf], %%xmm4\n\t"
+ "pshufb %%xmm3, %%xmm1\n\t"
+ "pand %%xmm4, %%xmm2\n\t"
+ "por %%xmm1, %%xmm2\n\t"
+
+ "pshufb %%xmm7, %%xmm2\n\t"
+
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pclmulqdq $0x01, %%xmm6, %%xmm0\n\t"
+ "pclmulqdq $0x10, %%xmm6, %%xmm1\n\t"
+ "pxor %%xmm2, %%xmm0\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*(inbuf - 16 + inlen)),
+ [mask] "m" (crc32_partial_fold_input_mask[inlen]),
+ [shl_shuf] "m" (crc32_refl_shuf_shift[32 - inlen]),
+ [shr_shuf] "m" (crc32_shuf_shift[inlen + 16])
+ );
+
+ inbuf += inlen;
+ inlen -= inlen;
+ }
+
+ /* Final fold. */
+ asm volatile (/* reduce 128-bits to 96-bits */
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pclmulqdq $0x11, %%xmm6, %%xmm0\n\t"
+ "pslldq $8, %%xmm1\n\t"
+ "pxor %%xmm1, %%xmm0\n\t" /* bottom 32-bit are zero */
+
+ /* reduce 96-bits to 64-bits */
+ "pshufd $0x30, %%xmm0, %%xmm1\n\t" /* [00][x>>96][00][00] */
+ "pshufd $0x24, %%xmm0, %%xmm0\n\t" /* [00][xx][xx][00] */
+ "pclmulqdq $0x01, %[k5], %%xmm1\n\t" /* [00][xx][xx][00] */
+ "pxor %%xmm1, %%xmm0\n\t" /* top and bottom 32-bit are zero */
+
+ /* barrett reduction */
+ "pshufd $0x01, %%xmm0, %%xmm1\n\t" /* [00][00][00][x>>32] */
+ "pclmulqdq $0x01, %%xmm5, %%xmm0\n\t" /* [00][xx][xx][xx] */
+ "psrldq $4, %%xmm0\n\t" /* [00][00][xx][xx] */
+ "pclmulqdq $0x10, %%xmm5, %%xmm0\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+
+ /* store CRC in input endian */
+ "movd %%xmm0, %%eax\n\t"
+ "bswapl %%eax\n\t"
+ "movl %%eax, %[out]\n\t"
+ : [out] "=m" (*pcrc)
+ : [k5] "m" (consts->k[5 - 1])
+ : "eax" );
+}
+
+static ASM_FUNC_ATTR_INLINE void
+crc32_less_than_16 (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ if (inlen < 4)
+ {
+ u32 crc = *pcrc;
+ u32 data;
+
+ asm volatile ("movdqa %[my_p], %%xmm5\n\t"
+ :
+ : [my_p] "m" (consts->my_p[0])
+ );
+
+ if (inlen == 1)
+ {
+ data = inbuf[0];
+ data ^= crc;
+ data = _gcry_bswap32(data << 24);
+ crc = _gcry_bswap32(crc >> 8);
+ }
+ else if (inlen == 2)
+ {
+ data = ((const struct u16_unaligned_s *)inbuf)->a;
+ data ^= crc;
+ data = _gcry_bswap32(data << 16);
+ crc = _gcry_bswap32(crc >> 16);
+ }
+ else
+ {
+ data = ((const struct u16_unaligned_s *)inbuf)->a;
+ data |= inbuf[2] << 16;
+ data ^= crc;
+ data = _gcry_bswap32(data << 8);
+ crc = _gcry_bswap32(crc >> 24);
+ }
+
+ /* Barrett reduction */
+ asm volatile ("movd %[in], %%xmm0\n\t"
+ "psllq $32, %%xmm0\n\t" /* [00][00][xx][00] */
+ "movd %[crc], %%xmm1\n\t"
+
+ "pclmulqdq $0x00, %%xmm5, %%xmm0\n\t" /* [00][xx][xx][00] */
+ "pclmulqdq $0x11, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+ "pxor %%xmm1, %%xmm0\n\t"
+
+ /* store CRC in input endian */
+ "movd %%xmm0, %%eax\n\t"
+ "bswapl %%eax\n\t"
+ "movl %%eax, %[out]\n\t"
+ : [out] "=m" (*pcrc)
+ : [in] "r" (data),
+ [crc] "r" (crc)
+ : "eax" );
+ }
+ else if (inlen == 4)
+ {
+ /* Barrett reduction */
+ asm volatile ("movd %[crc], %%xmm0\n\t"
+ "movd %[in], %%xmm1\n\t"
+ "movdqa %[my_p], %%xmm5\n\t"
+ :
+ : [in] "m" (*inbuf),
+ [crc] "m" (*pcrc),
+ [my_p] "m" (consts->my_p[0])
+ : "cc" );
+
+ asm volatile ("pxor %%xmm1, %%xmm0\n\t"
+ "pshufb %[bswap], %%xmm0\n\t" /* [xx][00][00][00] */
+
+ "pclmulqdq $0x01, %%xmm5, %%xmm0\n\t" /* [00][xx][xx][00] */
+ "pclmulqdq $0x11, %%xmm5, %%xmm0\n\t" /* [00][00][xx][xx] */
+ :
+ : [bswap] "m" (*crc32_bswap_shuf)
+ : "cc" );
+
+ asm volatile (/* store CRC in input endian */
+ "movd %%xmm0, %%eax\n\t"
+ "bswapl %%eax\n\t"
+ "movl %%eax, %[out]\n\t"
+ : [out] "=m" (*pcrc)
+ :
+ : "eax", "cc" );
+ }
+ else
+ {
+ asm volatile ("movdqu %[shuf], %%xmm7\n\t"
+ "movd %[crc], %%xmm1\n\t"
+ "movdqa %[my_p], %%xmm5\n\t"
+ "movdqa %[k3k4], %%xmm6\n\t"
+ :
+ : [shuf] "m" (crc32_shuf_shift[32 - inlen]),
+ [crc] "m" (*pcrc),
+ [my_p] "m" (consts->my_p[0]),
+ [k3k4] "m" (consts->k[3 - 1])
+ );
+
+ if (inlen >= 8)
+ {
+ asm volatile ("movq %[inbuf], %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*inbuf)
+ );
+ if (inlen > 8)
+ {
+ asm volatile (/*"pinsrq $1, %[inbuf_tail], %%xmm0\n\t"*/
+ "movq %[inbuf_tail], %%xmm2\n\t"
+ "punpcklqdq %%xmm2, %%xmm0\n\t"
+ "pshufb %[merge_shuf], %%xmm0\n\t"
+ :
+ : [inbuf_tail] "m" (inbuf[inlen - 8]),
+ [merge_shuf] "m"
+ (*crc32_merge9to15_shuf[inlen - 9])
+ );
+ }
+ }
+ else
+ {
+ asm volatile ("movd %[inbuf], %%xmm0\n\t"
+ "pinsrd $1, %[inbuf_tail], %%xmm0\n\t"
+ "pshufb %[merge_shuf], %%xmm0\n\t"
+ :
+ : [inbuf] "m" (*inbuf),
+ [inbuf_tail] "m" (inbuf[inlen - 4]),
+ [merge_shuf] "m"
+ (*crc32_merge5to7_shuf[inlen - 5])
+ );
+ }
+
+ /* Final fold. */
+ asm volatile ("pxor %%xmm1, %%xmm0\n\t"
+ "pshufb %%xmm7, %%xmm0\n\t"
+
+ /* reduce 128-bits to 96-bits */
+ "movdqa %%xmm0, %%xmm1\n\t"
+ "pclmulqdq $0x11, %%xmm6, %%xmm0\n\t"
+ "pslldq $8, %%xmm1\n\t"
+ "pxor %%xmm1, %%xmm0\n\t" /* bottom 32-bit are zero */
+
+ /* reduce 96-bits to 64-bits */
+ "pshufd $0x30, %%xmm0, %%xmm1\n\t" /* [00][x>>96][00][00] */
+ "pshufd $0x24, %%xmm0, %%xmm0\n\t" /* [00][xx][xx][00] */
+ "pclmulqdq $0x01, %[k5], %%xmm1\n\t" /* [00][xx][xx][00] */
+ "pxor %%xmm1, %%xmm0\n\t" /* top and bottom 32-bit are zero */
+
+ /* barrett reduction */
+ "pshufd $0x01, %%xmm0, %%xmm1\n\t" /* [00][00][00][x>>32] */
+ "pclmulqdq $0x01, %%xmm5, %%xmm0\n\t" /* [00][xx][xx][xx] */
+ "psrldq $4, %%xmm0\n\t" /* [00][00][xx][xx] */
+ "pclmulqdq $0x10, %%xmm5, %%xmm0\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+
+ /* store CRC in input endian */
+ "movd %%xmm0, %%eax\n\t"
+ "bswapl %%eax\n\t"
+ "movl %%eax, %[out]\n\t"
+ : [out] "=m" (*pcrc)
+ : [k5] "m" (consts->k[5 - 1])
+ : "eax" );
+ }
+}
+
+void ASM_FUNC_ATTR
+_gcry_crc32_intel_pclmul (u32 *pcrc, const byte *inbuf, size_t inlen)
+{
+ const struct crc32_consts_s *consts = &crc32_consts;
+#if defined(__x86_64__) && defined(__WIN64__)
+ char win64tmp[2 * 16];
+
+ /* XMM6-XMM7 need to be restored after use. */
+ asm volatile ("movdqu %%xmm6, 0*16(%0)\n\t"
+ "movdqu %%xmm7, 1*16(%0)\n\t"
+ :
+ : "r" (win64tmp)
+ : "memory");
+#endif
+
+ if (!inlen)
+ return;
+
+ if (inlen >= 16)
+ crc32_reflected_bulk(pcrc, inbuf, inlen, consts);
+ else
+ crc32_reflected_less_than_16(pcrc, inbuf, inlen, consts);
+
+#if defined(__x86_64__) && defined(__WIN64__)
+ /* Restore used registers. */
+ asm volatile("movdqu 0*16(%0), %%xmm6\n\t"
+ "movdqu 1*16(%0), %%xmm7\n\t"
+ :
+ : "r" (win64tmp)
+ : "memory");
+#endif
+}
+
+void ASM_FUNC_ATTR
+_gcry_crc24rfc2440_intel_pclmul (u32 *pcrc, const byte *inbuf, size_t inlen)
+{
+ const struct crc32_consts_s *consts = &crc24rfc2440_consts;
+#if defined(__x86_64__) && defined(__WIN64__)
+ char win64tmp[2 * 16];
+
+ /* XMM6-XMM7 need to be restored after use. */
+ asm volatile ("movdqu %%xmm6, 0*16(%0)\n\t"
+ "movdqu %%xmm7, 1*16(%0)\n\t"
+ :
+ : "r" (win64tmp)
+ : "memory");
+#endif
+
+ if (!inlen)
+ return;
+
+ /* Note: *pcrc in input endian. */
+
+ if (inlen >= 16)
+ crc32_bulk(pcrc, inbuf, inlen, consts);
+ else
+ crc32_less_than_16(pcrc, inbuf, inlen, consts);
+
+#if defined(__x86_64__) && defined(__WIN64__)
+ /* Restore used registers. */
+ asm volatile("movdqu 0*16(%0), %%xmm6\n\t"
+ "movdqu 1*16(%0), %%xmm7\n\t"
+ :
+ : "r" (win64tmp)
+ : "memory");
+#endif
+}
+
+#if __clang__
+# pragma clang attribute pop
+#endif
+
+#endif /* USE_INTEL_PCLMUL */
diff --git a/comm/third_party/libgcrypt/cipher/crc-ppc.c b/comm/third_party/libgcrypt/cipher/crc-ppc.c
new file mode 100644
index 0000000000..b9a40130ce
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/crc-ppc.c
@@ -0,0 +1,656 @@
+/* crc-ppc.c - POWER8 vpmsum accelerated CRC implementation
+ * Copyright (C) 2019-2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+
+#include "bithelp.h"
+#include "bufhelp.h"
+
+
+#if defined(ENABLE_PPC_CRYPTO_SUPPORT) && \
+ defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) && \
+ __GNUC__ >= 4
+
+#include <altivec.h>
+#include "bufhelp.h"
+
+
+#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
+
+#define ALIGNED_64 __attribute__ ((aligned (64)))
+
+
+typedef vector unsigned char vector16x_u8;
+typedef vector unsigned int vector4x_u32;
+typedef vector unsigned long long vector2x_u64;
+
+
+/* Constants structure for generic reflected/non-reflected CRC32 PMULL
+ * functions. */
+struct crc32_consts_s
+{
+ /* k: { x^(32*17), x^(32*15), x^(32*5), x^(32*3), x^(32*2), 0 } mod P(x) */
+ unsigned long long k[6];
+ /* my_p: { floor(x^64 / P(x)), P(x) } */
+ unsigned long long my_p[2];
+};
+
+/* PMULL constants for CRC32 and CRC32RFC1510. */
+static const struct crc32_consts_s crc32_consts ALIGNED_64 =
+{
+ { /* k[6] = reverse_33bits( x^(32*y) mod P(x) ) */
+ U64_C(0x154442bd4), U64_C(0x1c6e41596), /* y = { 17, 15 } */
+ U64_C(0x1751997d0), U64_C(0x0ccaa009e), /* y = { 5, 3 } */
+ U64_C(0x163cd6124), 0 /* y = 2 */
+ },
+ { /* my_p[2] = reverse_33bits ( { floor(x^64 / P(x)), P(x) } ) */
+ U64_C(0x1f7011641), U64_C(0x1db710641)
+ }
+};
+
+/* PMULL constants for CRC24RFC2440 (polynomial multiplied with xâ¸). */
+static const struct crc32_consts_s crc24rfc2440_consts ALIGNED_64 =
+{
+ { /* k[6] = x^(32*y) mod P(x) << 32*/
+ U64_C(0x08289a00) << 32, U64_C(0x74b44a00) << 32, /* y = { 17, 15 } */
+ U64_C(0xc4b14d00) << 32, U64_C(0xfd7e0c00) << 32, /* y = { 5, 3 } */
+ U64_C(0xd9fe8c00) << 32, 0 /* y = 2 */
+ },
+ { /* my_p[2] = { floor(x^64 / P(x)), P(x) } */
+ U64_C(0x1f845fe24), U64_C(0x1864cfb00)
+ }
+};
+
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+asm_vpmsumd(vector2x_u64 a, vector2x_u64 b)
+{
+ __asm__("vpmsumd %0, %1, %2"
+ : "=v" (a)
+ : "v" (a), "v" (b));
+ return a;
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+asm_swap_u64(vector2x_u64 a)
+{
+ __asm__("xxswapd %x0, %x1"
+ : "=wa" (a)
+ : "wa" (a));
+ return a;
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector4x_u32
+vec_sld_u32(vector4x_u32 a, vector4x_u32 b, unsigned int idx)
+{
+ return vec_sld (a, b, (4 * idx) & 15);
+}
+
+
+static const byte crc32_partial_fold_input_mask[16 + 16] ALIGNED_64 =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+static const byte crc32_shuf_shift[3 * 16] ALIGNED_64 =
+ {
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ };
+static const byte crc32_refl_shuf_shift[3 * 16] ALIGNED_64 =
+ {
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ };
+static const vector16x_u8 bswap_const ALIGNED_64 =
+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+
+#define CRC_VEC_SWAP(v) ({ vector2x_u64 __vecu64 = (v); \
+ vec_perm(__vecu64, __vecu64, bswap_const); })
+
+#ifdef WORDS_BIGENDIAN
+# define CRC_VEC_U64_DEF(lo, hi) { (hi), (lo) }
+# define CRC_VEC_U64_LOAD(offs, ptr) \
+ asm_swap_u64(asm_vec_u64_load(offs, ptr))
+# define CRC_VEC_U64_LOAD_LE(offs, ptr) \
+ CRC_VEC_SWAP(asm_vec_u64_load(offs, ptr))
+# define CRC_VEC_U64_LOAD_BE(offs, ptr) \
+ asm_vec_u64_load(offs, ptr)
+# define CRC_VEC_SWAP_TO_LE(v) CRC_VEC_SWAP(v)
+# define CRC_VEC_SWAP_TO_BE(v) (v)
+# define VEC_U64_LO 1
+# define VEC_U64_HI 0
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+asm_vec_u64_load(unsigned long offset, const void *ptr)
+{
+ vector2x_u64 vecu64;
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ volatile ("lxvd2x %x0,0,%1\n\t"
+ : "=wa" (vecu64)
+ : "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ volatile ("lxvd2x %x0,%1,%2\n\t"
+ : "=wa" (vecu64)
+ : "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+ return vecu64;
+}
+#else
+# define CRC_VEC_U64_DEF(lo, hi) { (lo), (hi) }
+# define CRC_VEC_U64_LOAD(offs, ptr) asm_vec_u64_load_le(offs, ptr)
+# define CRC_VEC_U64_LOAD_LE(offs, ptr) asm_vec_u64_load_le(offs, ptr)
+# define CRC_VEC_U64_LOAD_BE(offs, ptr) asm_vec_u64_load_be(offs, ptr)
+# define CRC_VEC_SWAP_TO_LE(v) (v)
+# define CRC_VEC_SWAP_TO_BE(v) CRC_VEC_SWAP(v)
+# define VEC_U64_LO 0
+# define VEC_U64_HI 1
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+asm_vec_u64_load_le(unsigned long offset, const void *ptr)
+{
+ vector2x_u64 vecu64;
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ volatile ("lxvd2x %x0,0,%1\n\t"
+ : "=wa" (vecu64)
+ : "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ volatile ("lxvd2x %x0,%1,%2\n\t"
+ : "=wa" (vecu64)
+ : "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+ return asm_swap_u64(vecu64);
+}
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+asm_vec_u64_load_be(unsigned int offset, const void *ptr)
+{
+ static const vector16x_u8 vec_load_le_const =
+ { ~7, ~6, ~5, ~4, ~3, ~2, ~1, ~0, ~15, ~14, ~13, ~12, ~11, ~10, ~9, ~8 };
+ vector2x_u64 vecu64;
+
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ ("lxvd2x %%vs32,0,%1\n\t"
+ "vperm %0,%%v0,%%v0,%2\n\t"
+ : "=v" (vecu64)
+ : "r" ((uintptr_t)(ptr)), "v" (vec_load_le_const)
+ : "memory", "v0");
+#endif
+ else
+ __asm__ ("lxvd2x %%vs32,%1,%2\n\t"
+ "vperm %0,%%v0,%%v0,%3\n\t"
+ : "=v" (vecu64)
+ : "r" (offset), "r" ((uintptr_t)(ptr)),
+ "v" (vec_load_le_const)
+ : "memory", "r0", "v0");
+
+ return vecu64;
+}
+#endif
+
+
+static ASM_FUNC_ATTR_INLINE void
+crc32r_ppc8_ce_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ vector4x_u32 zero = { 0, 0, 0, 0 };
+ vector2x_u64 low_64bit_mask = CRC_VEC_U64_DEF((u64)-1, 0);
+ vector2x_u64 low_32bit_mask = CRC_VEC_U64_DEF((u32)-1, 0);
+ vector2x_u64 my_p = CRC_VEC_U64_LOAD(0, &consts->my_p[0]);
+ vector2x_u64 k1k2 = CRC_VEC_U64_LOAD(0, &consts->k[1 - 1]);
+ vector2x_u64 k3k4 = CRC_VEC_U64_LOAD(0, &consts->k[3 - 1]);
+ vector2x_u64 k4lo = CRC_VEC_U64_DEF(k3k4[VEC_U64_HI], 0);
+ vector2x_u64 k5lo = CRC_VEC_U64_LOAD(0, &consts->k[5 - 1]);
+ vector2x_u64 crc = CRC_VEC_U64_DEF(*pcrc, 0);
+ vector2x_u64 crc0, crc1, crc2, crc3;
+ vector2x_u64 v0;
+
+ if (inlen >= 8 * 16)
+ {
+ crc0 = CRC_VEC_U64_LOAD_LE(0 * 16, inbuf);
+ crc0 ^= crc;
+ crc1 = CRC_VEC_U64_LOAD_LE(1 * 16, inbuf);
+ crc2 = CRC_VEC_U64_LOAD_LE(2 * 16, inbuf);
+ crc3 = CRC_VEC_U64_LOAD_LE(3 * 16, inbuf);
+
+ inbuf += 4 * 16;
+ inlen -= 4 * 16;
+
+ /* Fold by 4. */
+ while (inlen >= 4 * 16)
+ {
+ v0 = CRC_VEC_U64_LOAD_LE(0 * 16, inbuf);
+ crc0 = asm_vpmsumd(crc0, k1k2) ^ v0;
+
+ v0 = CRC_VEC_U64_LOAD_LE(1 * 16, inbuf);
+ crc1 = asm_vpmsumd(crc1, k1k2) ^ v0;
+
+ v0 = CRC_VEC_U64_LOAD_LE(2 * 16, inbuf);
+ crc2 = asm_vpmsumd(crc2, k1k2) ^ v0;
+
+ v0 = CRC_VEC_U64_LOAD_LE(3 * 16, inbuf);
+ crc3 = asm_vpmsumd(crc3, k1k2) ^ v0;
+
+ inbuf += 4 * 16;
+ inlen -= 4 * 16;
+ }
+
+ /* Fold 4 to 1. */
+ crc1 ^= asm_vpmsumd(crc0, k3k4);
+ crc2 ^= asm_vpmsumd(crc1, k3k4);
+ crc3 ^= asm_vpmsumd(crc2, k3k4);
+ crc = crc3;
+ }
+ else
+ {
+ v0 = CRC_VEC_U64_LOAD_LE(0, inbuf);
+ crc ^= v0;
+
+ inbuf += 16;
+ inlen -= 16;
+ }
+
+ /* Fold by 1. */
+ while (inlen >= 16)
+ {
+ v0 = CRC_VEC_U64_LOAD_LE(0, inbuf);
+ crc = asm_vpmsumd(k3k4, crc);
+ crc ^= v0;
+
+ inbuf += 16;
+ inlen -= 16;
+ }
+
+ /* Partial fold. */
+ if (inlen)
+ {
+ /* Load last input and add padding zeros. */
+ vector2x_u64 mask = CRC_VEC_U64_LOAD_LE(inlen, crc32_partial_fold_input_mask);
+ vector2x_u64 shl_shuf = CRC_VEC_U64_LOAD_LE(inlen, crc32_refl_shuf_shift);
+ vector2x_u64 shr_shuf = CRC_VEC_U64_LOAD_LE(inlen + 16, crc32_refl_shuf_shift);
+
+ v0 = CRC_VEC_U64_LOAD_LE(inlen - 16, inbuf);
+ v0 &= mask;
+
+ crc = CRC_VEC_SWAP_TO_LE(crc);
+ v0 |= (vector2x_u64)vec_perm((vector16x_u8)crc, (vector16x_u8)zero,
+ (vector16x_u8)shr_shuf);
+ crc = (vector2x_u64)vec_perm((vector16x_u8)crc, (vector16x_u8)zero,
+ (vector16x_u8)shl_shuf);
+ crc = asm_vpmsumd(k3k4, crc);
+ crc ^= v0;
+
+ inbuf += inlen;
+ inlen -= inlen;
+ }
+
+ /* Final fold. */
+
+ /* reduce 128-bits to 96-bits */
+ v0 = asm_swap_u64(crc);
+ v0 &= low_64bit_mask;
+ crc = asm_vpmsumd(k4lo, crc);
+ crc ^= v0;
+
+ /* reduce 96-bits to 64-bits */
+ v0 = (vector2x_u64)vec_sld_u32((vector4x_u32)crc,
+ (vector4x_u32)crc, 3); /* [x0][x3][x2][x1] */
+ v0 &= low_64bit_mask; /* [00][00][x2][x1] */
+ crc = crc & low_32bit_mask; /* [00][00][00][x0] */
+ crc = v0 ^ asm_vpmsumd(k5lo, crc); /* [00][00][xx][xx] */
+
+ /* barrett reduction */
+ v0 = crc << 32; /* [00][00][x0][00] */
+ v0 = asm_vpmsumd(my_p, v0);
+ v0 = asm_swap_u64(v0);
+ v0 = asm_vpmsumd(my_p, v0);
+ crc = (vector2x_u64)vec_sld_u32((vector4x_u32)crc,
+ zero, 1); /* [00][x1][x0][00] */
+ crc ^= v0;
+
+ *pcrc = (u32)crc[VEC_U64_HI];
+}
+
+
+static ASM_FUNC_ATTR_INLINE u32
+crc32r_ppc8_ce_reduction_4 (u32 data, u32 crc,
+ const struct crc32_consts_s *consts)
+{
+ vector4x_u32 zero = { 0, 0, 0, 0 };
+ vector2x_u64 my_p = CRC_VEC_U64_LOAD(0, &consts->my_p[0]);
+ vector2x_u64 v0 = CRC_VEC_U64_DEF((u64)data, 0);
+ v0 = asm_vpmsumd(v0, my_p); /* [00][00][xx][xx] */
+ v0 = (vector2x_u64)vec_sld_u32((vector4x_u32)v0,
+ zero, 3); /* [x0][00][00][00] */
+ v0 = (vector2x_u64)vec_sld_u32((vector4x_u32)v0,
+ (vector4x_u32)v0, 3); /* [00][x0][00][00] */
+ v0 = asm_vpmsumd(v0, my_p); /* [00][00][xx][xx] */
+ return (v0[VEC_U64_LO] >> 32) ^ crc;
+}
+
+
+static ASM_FUNC_ATTR_INLINE void
+crc32r_less_than_16 (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ u32 crc = *pcrc;
+ u32 data;
+
+ while (inlen >= 4)
+ {
+ data = buf_get_le32(inbuf);
+ data ^= crc;
+
+ inlen -= 4;
+ inbuf += 4;
+
+ crc = crc32r_ppc8_ce_reduction_4 (data, 0, consts);
+ }
+
+ switch (inlen)
+ {
+ case 0:
+ break;
+ case 1:
+ data = inbuf[0];
+ data ^= crc;
+ data <<= 24;
+ crc >>= 8;
+ crc = crc32r_ppc8_ce_reduction_4 (data, crc, consts);
+ break;
+ case 2:
+ data = inbuf[0] << 0;
+ data |= inbuf[1] << 8;
+ data ^= crc;
+ data <<= 16;
+ crc >>= 16;
+ crc = crc32r_ppc8_ce_reduction_4 (data, crc, consts);
+ break;
+ case 3:
+ data = inbuf[0] << 0;
+ data |= inbuf[1] << 8;
+ data |= inbuf[2] << 16;
+ data ^= crc;
+ data <<= 8;
+ crc >>= 24;
+ crc = crc32r_ppc8_ce_reduction_4 (data, crc, consts);
+ break;
+ }
+
+ *pcrc = crc;
+}
+
+
+static ASM_FUNC_ATTR_INLINE void
+crc32_ppc8_ce_bulk (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ vector4x_u32 zero = { 0, 0, 0, 0 };
+ vector2x_u64 low_96bit_mask = CRC_VEC_U64_DEF(~0, ~((u64)(u32)-1 << 32));
+ vector2x_u64 p_my = asm_swap_u64(CRC_VEC_U64_LOAD(0, &consts->my_p[0]));
+ vector2x_u64 p_my_lo, p_my_hi;
+ vector2x_u64 k2k1 = asm_swap_u64(CRC_VEC_U64_LOAD(0, &consts->k[1 - 1]));
+ vector2x_u64 k4k3 = asm_swap_u64(CRC_VEC_U64_LOAD(0, &consts->k[3 - 1]));
+ vector2x_u64 k4hi = CRC_VEC_U64_DEF(0, consts->k[4 - 1]);
+ vector2x_u64 k5hi = CRC_VEC_U64_DEF(0, consts->k[5 - 1]);
+ vector2x_u64 crc = CRC_VEC_U64_DEF(0, _gcry_bswap64(*pcrc));
+ vector2x_u64 crc0, crc1, crc2, crc3;
+ vector2x_u64 v0;
+
+ if (inlen >= 8 * 16)
+ {
+ crc0 = CRC_VEC_U64_LOAD_BE(0 * 16, inbuf);
+ crc0 ^= crc;
+ crc1 = CRC_VEC_U64_LOAD_BE(1 * 16, inbuf);
+ crc2 = CRC_VEC_U64_LOAD_BE(2 * 16, inbuf);
+ crc3 = CRC_VEC_U64_LOAD_BE(3 * 16, inbuf);
+
+ inbuf += 4 * 16;
+ inlen -= 4 * 16;
+
+ /* Fold by 4. */
+ while (inlen >= 4 * 16)
+ {
+ v0 = CRC_VEC_U64_LOAD_BE(0 * 16, inbuf);
+ crc0 = asm_vpmsumd(crc0, k2k1) ^ v0;
+
+ v0 = CRC_VEC_U64_LOAD_BE(1 * 16, inbuf);
+ crc1 = asm_vpmsumd(crc1, k2k1) ^ v0;
+
+ v0 = CRC_VEC_U64_LOAD_BE(2 * 16, inbuf);
+ crc2 = asm_vpmsumd(crc2, k2k1) ^ v0;
+
+ v0 = CRC_VEC_U64_LOAD_BE(3 * 16, inbuf);
+ crc3 = asm_vpmsumd(crc3, k2k1) ^ v0;
+
+ inbuf += 4 * 16;
+ inlen -= 4 * 16;
+ }
+
+ /* Fold 4 to 1. */
+ crc1 ^= asm_vpmsumd(crc0, k4k3);
+ crc2 ^= asm_vpmsumd(crc1, k4k3);
+ crc3 ^= asm_vpmsumd(crc2, k4k3);
+ crc = crc3;
+ }
+ else
+ {
+ v0 = CRC_VEC_U64_LOAD_BE(0, inbuf);
+ crc ^= v0;
+
+ inbuf += 16;
+ inlen -= 16;
+ }
+
+ /* Fold by 1. */
+ while (inlen >= 16)
+ {
+ v0 = CRC_VEC_U64_LOAD_BE(0, inbuf);
+ crc = asm_vpmsumd(k4k3, crc);
+ crc ^= v0;
+
+ inbuf += 16;
+ inlen -= 16;
+ }
+
+ /* Partial fold. */
+ if (inlen)
+ {
+ /* Load last input and add padding zeros. */
+ vector2x_u64 mask = CRC_VEC_U64_LOAD_LE(inlen, crc32_partial_fold_input_mask);
+ vector2x_u64 shl_shuf = CRC_VEC_U64_LOAD_LE(32 - inlen, crc32_refl_shuf_shift);
+ vector2x_u64 shr_shuf = CRC_VEC_U64_LOAD_LE(inlen + 16, crc32_shuf_shift);
+
+ v0 = CRC_VEC_U64_LOAD_LE(inlen - 16, inbuf);
+ v0 &= mask;
+
+ crc = CRC_VEC_SWAP_TO_LE(crc);
+ crc2 = (vector2x_u64)vec_perm((vector16x_u8)crc, (vector16x_u8)zero,
+ (vector16x_u8)shr_shuf);
+ v0 |= crc2;
+ v0 = CRC_VEC_SWAP(v0);
+ crc = (vector2x_u64)vec_perm((vector16x_u8)crc, (vector16x_u8)zero,
+ (vector16x_u8)shl_shuf);
+ crc = asm_vpmsumd(k4k3, crc);
+ crc ^= v0;
+
+ inbuf += inlen;
+ inlen -= inlen;
+ }
+
+ /* Final fold. */
+
+ /* reduce 128-bits to 96-bits */
+ v0 = (vector2x_u64)vec_sld_u32((vector4x_u32)crc,
+ (vector4x_u32)zero, 2);
+ crc = asm_vpmsumd(k4hi, crc);
+ crc ^= v0; /* bottom 32-bit are zero */
+
+ /* reduce 96-bits to 64-bits */
+ v0 = crc & low_96bit_mask; /* [00][x2][x1][00] */
+ crc >>= 32; /* [00][x3][00][x0] */
+ crc = asm_vpmsumd(k5hi, crc); /* [00][xx][xx][00] */
+ crc ^= v0; /* top and bottom 32-bit are zero */
+
+ /* barrett reduction */
+ p_my_hi = p_my;
+ p_my_lo = p_my;
+ p_my_hi[VEC_U64_LO] = 0;
+ p_my_lo[VEC_U64_HI] = 0;
+ v0 = crc >> 32; /* [00][00][00][x1] */
+ crc = asm_vpmsumd(p_my_hi, crc); /* [00][xx][xx][xx] */
+ crc = (vector2x_u64)vec_sld_u32((vector4x_u32)crc,
+ (vector4x_u32)crc, 3); /* [x0][00][x2][x1] */
+ crc = asm_vpmsumd(p_my_lo, crc); /* [00][xx][xx][xx] */
+ crc ^= v0;
+
+ *pcrc = _gcry_bswap32(crc[VEC_U64_LO]);
+}
+
+
+static ASM_FUNC_ATTR_INLINE u32
+crc32_ppc8_ce_reduction_4 (u32 data, u32 crc,
+ const struct crc32_consts_s *consts)
+{
+ vector2x_u64 my_p = CRC_VEC_U64_LOAD(0, &consts->my_p[0]);
+ vector2x_u64 v0 = CRC_VEC_U64_DEF((u64)data << 32, 0);
+ v0 = asm_vpmsumd(v0, my_p); /* [00][x1][x0][00] */
+ v0[VEC_U64_LO] = 0; /* [00][x1][00][00] */
+ v0 = asm_vpmsumd(v0, my_p); /* [00][00][xx][xx] */
+ return _gcry_bswap32(v0[VEC_U64_LO]) ^ crc;
+}
+
+
+static ASM_FUNC_ATTR_INLINE void
+crc32_less_than_16 (u32 *pcrc, const byte *inbuf, size_t inlen,
+ const struct crc32_consts_s *consts)
+{
+ u32 crc = *pcrc;
+ u32 data;
+
+ while (inlen >= 4)
+ {
+ data = buf_get_le32(inbuf);
+ data ^= crc;
+ data = _gcry_bswap32(data);
+
+ inlen -= 4;
+ inbuf += 4;
+
+ crc = crc32_ppc8_ce_reduction_4 (data, 0, consts);
+ }
+
+ switch (inlen)
+ {
+ case 0:
+ break;
+ case 1:
+ data = inbuf[0];
+ data ^= crc;
+ data = data & 0xffU;
+ crc = crc >> 8;
+ crc = crc32_ppc8_ce_reduction_4 (data, crc, consts);
+ break;
+ case 2:
+ data = inbuf[0] << 0;
+ data |= inbuf[1] << 8;
+ data ^= crc;
+ data = _gcry_bswap32(data << 16);
+ crc = crc >> 16;
+ crc = crc32_ppc8_ce_reduction_4 (data, crc, consts);
+ break;
+ case 3:
+ data = inbuf[0] << 0;
+ data |= inbuf[1] << 8;
+ data |= inbuf[2] << 16;
+ data ^= crc;
+ data = _gcry_bswap32(data << 8);
+ crc = crc >> 24;
+ crc = crc32_ppc8_ce_reduction_4 (data, crc, consts);
+ break;
+ }
+
+ *pcrc = crc;
+}
+
+void ASM_FUNC_ATTR
+_gcry_crc32_ppc8_vpmsum (u32 *pcrc, const byte *inbuf, size_t inlen)
+{
+ const struct crc32_consts_s *consts = &crc32_consts;
+
+ if (!inlen)
+ return;
+
+ if (inlen >= 16)
+ crc32r_ppc8_ce_bulk (pcrc, inbuf, inlen, consts);
+ else
+ crc32r_less_than_16 (pcrc, inbuf, inlen, consts);
+}
+
+void ASM_FUNC_ATTR
+_gcry_crc24rfc2440_ppc8_vpmsum (u32 *pcrc, const byte *inbuf, size_t inlen)
+{
+ const struct crc32_consts_s *consts = &crc24rfc2440_consts;
+
+ if (!inlen)
+ return;
+
+ /* Note: *pcrc in input endian. */
+
+ if (inlen >= 16)
+ crc32_ppc8_ce_bulk (pcrc, inbuf, inlen, consts);
+ else
+ crc32_less_than_16 (pcrc, inbuf, inlen, consts);
+}
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/crc.c b/comm/third_party/libgcrypt/cipher/crc.c
new file mode 100644
index 0000000000..6d70f644f7
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/crc.c
@@ -0,0 +1,955 @@
+/* crc.c - Cyclic redundancy checks.
+ * Copyright (C) 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
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+#include "bufhelp.h"
+
+
+/* USE_INTEL_PCLMUL indicates whether to compile CRC with Intel PCLMUL/SSE4.1
+ * code. */
+#undef USE_INTEL_PCLMUL
+#if defined(ENABLE_PCLMUL_SUPPORT) && defined(ENABLE_SSE41_SUPPORT)
+# if ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
+# if __GNUC__ >= 4
+# define USE_INTEL_PCLMUL 1
+# endif
+# endif
+#endif /* USE_INTEL_PCLMUL */
+
+/* USE_ARM_PMULL indicates whether to compile GCM with ARMv8 PMULL code. */
+#undef USE_ARM_PMULL
+#if defined(ENABLE_ARM_CRYPTO_SUPPORT)
+# if defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+# define USE_ARM_PMULL 1
+# endif
+#endif /* USE_ARM_PMULL */
+
+/* USE_PPC_VPMSUM indicates whether to enable PowerPC vector
+ * accelerated code. */
+#undef USE_PPC_VPMSUM
+#ifdef ENABLE_PPC_CRYPTO_SUPPORT
+# if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC)
+# if __GNUC__ >= 4
+# define USE_PPC_VPMSUM 1
+# endif
+# endif
+#endif /* USE_PPC_VPMSUM */
+
+
+typedef struct
+{
+ u32 CRC;
+#ifdef USE_INTEL_PCLMUL
+ unsigned int use_pclmul:1; /* Intel PCLMUL shall be used. */
+#endif
+#ifdef USE_ARM_PMULL
+ unsigned int use_pmull:1; /* ARMv8 PMULL shall be used. */
+#endif
+#ifdef USE_PPC_VPMSUM
+ unsigned int use_vpmsum:1; /* POWER vpmsum shall be used. */
+#endif
+ byte buf[4];
+}
+CRC_CONTEXT;
+
+
+#ifdef USE_INTEL_PCLMUL
+/*-- crc-intel-pclmul.c --*/
+void _gcry_crc32_intel_pclmul (u32 *pcrc, const byte *inbuf, size_t inlen);
+void _gcry_crc24rfc2440_intel_pclmul (u32 *pcrc, const byte *inbuf,
+ size_t inlen);
+#endif
+
+#ifdef USE_ARM_PMULL
+/*-- crc-armv8-ce.c --*/
+void _gcry_crc32_armv8_ce_pmull (u32 *pcrc, const byte *inbuf, size_t inlen);
+void _gcry_crc24rfc2440_armv8_ce_pmull (u32 *pcrc, const byte *inbuf,
+ size_t inlen);
+#endif
+
+#ifdef USE_PPC_VPMSUM
+/*-- crc-ppc.c --*/
+void _gcry_crc32_ppc8_vpmsum (u32 *pcrc, const byte *inbuf, size_t inlen);
+void _gcry_crc24rfc2440_ppc8_vpmsum (u32 *pcrc, const byte *inbuf,
+ size_t inlen);
+#endif
+
+
+/*
+ * Code generated by universal_crc by Danjel McGougan
+ *
+ * CRC parameters used:
+ * bits: 32
+ * poly: 0x04c11db7
+ * init: 0xffffffff
+ * xor: 0xffffffff
+ * reverse: true
+ * non-direct: false
+ *
+ * CRC of the string "123456789" is 0xcbf43926
+ */
+
+static const u32 crc32_table[1024] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+ 0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3,
+ 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7,
+ 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb,
+ 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
+ 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
+ 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496,
+ 0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a,
+ 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
+ 0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761,
+ 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
+ 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69,
+ 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
+ 0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530,
+ 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034,
+ 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
+ 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
+ 0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6,
+ 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2,
+ 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce,
+ 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
+ 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97,
+ 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93,
+ 0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f,
+ 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
+ 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
+ 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60,
+ 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c,
+ 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
+ 0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35,
+ 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
+ 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d,
+ 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
+ 0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88,
+ 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c,
+ 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
+ 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
+ 0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9,
+ 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd,
+ 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1,
+ 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
+ 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a,
+ 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e,
+ 0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522,
+ 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
+ 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
+ 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f,
+ 0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773,
+ 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
+ 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d,
+ 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
+ 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85,
+ 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
+ 0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc,
+ 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8,
+ 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
+ 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
+ 0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f,
+ 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b,
+ 0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27,
+ 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
+ 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e,
+ 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a,
+ 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876,
+ 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72,
+ 0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59,
+ 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685,
+ 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1,
+ 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
+ 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
+ 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5,
+ 0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91,
+ 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
+ 0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9,
+ 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
+ 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901,
+ 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
+ 0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9,
+ 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315,
+ 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
+ 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
+ 0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399,
+ 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45,
+ 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221,
+ 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
+ 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9,
+ 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835,
+ 0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151,
+ 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
+ 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
+ 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5,
+ 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1,
+ 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
+ 0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609,
+ 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
+ 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1,
+ 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
+ 0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9,
+ 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05,
+ 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
+ 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
+ 0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9,
+ 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75,
+ 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711,
+ 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
+ 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339,
+ 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5,
+ 0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281,
+ 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
+ 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
+ 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895,
+ 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1,
+ 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
+ 0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819,
+ 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
+ 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1,
+ 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
+ 0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69,
+ 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5,
+ 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
+ 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
+ 0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9,
+ 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625,
+ 0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41,
+ 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
+ 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89,
+ 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555,
+ 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31,
+ 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed,
+ 0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee,
+ 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9,
+ 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701,
+ 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
+ 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
+ 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26,
+ 0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e,
+ 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
+ 0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0,
+ 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
+ 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f,
+ 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
+ 0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f,
+ 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018,
+ 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
+ 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
+ 0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3,
+ 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084,
+ 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c,
+ 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
+ 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c,
+ 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b,
+ 0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3,
+ 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
+ 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
+ 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba,
+ 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002,
+ 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
+ 0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72,
+ 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
+ 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d,
+ 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
+ 0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5,
+ 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82,
+ 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
+ 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
+ 0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a,
+ 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d,
+ 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5,
+ 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
+ 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb,
+ 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc,
+ 0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04,
+ 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
+ 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
+ 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623,
+ 0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b,
+ 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
+ 0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8,
+ 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
+ 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907,
+ 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
+ 0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677,
+ 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120,
+ 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
+ 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
+ 0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6,
+ 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981,
+ 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639,
+ 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
+ 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949,
+ 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e,
+ 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6,
+ 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1
+};
+
+/* CRC32 */
+
+static inline u32
+crc32_next (u32 crc, byte data)
+{
+ return (crc >> 8) ^ crc32_table[(crc & 0xff) ^ data];
+}
+
+/*
+ * Process 4 bytes in one go
+ */
+static inline u32
+crc32_next4 (u32 crc, u32 data)
+{
+ crc ^= data;
+ crc = crc32_table[(crc & 0xff) + 0x300] ^
+ crc32_table[((crc >> 8) & 0xff) + 0x200] ^
+ crc32_table[((crc >> 16) & 0xff) + 0x100] ^
+ crc32_table[(crc >> 24) & 0xff];
+ return crc;
+}
+
+static void
+crc32_init (void *context, unsigned int flags)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ u32 hwf = _gcry_get_hw_features ();
+
+#ifdef USE_INTEL_PCLMUL
+ ctx->use_pclmul = (hwf & HWF_INTEL_SSE4_1) && (hwf & HWF_INTEL_PCLMUL);
+#endif
+#ifdef USE_ARM_PMULL
+ ctx->use_pmull = (hwf & HWF_ARM_NEON) && (hwf & HWF_ARM_PMULL);
+#endif
+#ifdef USE_PPC_VPMSUM
+ ctx->use_vpmsum = !!(hwf & HWF_PPC_ARCH_2_07);
+#endif
+
+ (void)flags;
+ (void)hwf;
+
+ ctx->CRC = 0 ^ 0xffffffffL;
+}
+
+static void
+crc32_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ const byte *inbuf = inbuf_arg;
+ u32 crc;
+
+#ifdef USE_INTEL_PCLMUL
+ if (ctx->use_pclmul)
+ {
+ _gcry_crc32_intel_pclmul(&ctx->CRC, inbuf, inlen);
+ return;
+ }
+#endif
+#ifdef USE_ARM_PMULL
+ if (ctx->use_pmull)
+ {
+ _gcry_crc32_armv8_ce_pmull(&ctx->CRC, inbuf, inlen);
+ return;
+ }
+#endif
+#ifdef USE_PPC_VPMSUM
+ if (ctx->use_vpmsum)
+ {
+ _gcry_crc32_ppc8_vpmsum(&ctx->CRC, inbuf, inlen);
+ return;
+ }
+#endif
+
+ if (!inbuf || !inlen)
+ return;
+
+ crc = ctx->CRC;
+
+ while (inlen >= 16)
+ {
+ inlen -= 16;
+ crc = crc32_next4(crc, buf_get_le32(&inbuf[0]));
+ crc = crc32_next4(crc, buf_get_le32(&inbuf[4]));
+ crc = crc32_next4(crc, buf_get_le32(&inbuf[8]));
+ crc = crc32_next4(crc, buf_get_le32(&inbuf[12]));
+ inbuf += 16;
+ }
+
+ while (inlen >= 4)
+ {
+ inlen -= 4;
+ crc = crc32_next4(crc, buf_get_le32(inbuf));
+ inbuf += 4;
+ }
+
+ while (inlen--)
+ {
+ crc = crc32_next(crc, *inbuf++);
+ }
+
+ ctx->CRC = crc;
+}
+
+static byte *
+crc32_read (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ return ctx->buf;
+}
+
+static void
+crc32_final (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ ctx->CRC ^= 0xffffffffL;
+ buf_put_be32 (ctx->buf, ctx->CRC);
+}
+
+/* CRC32 a'la RFC 1510 */
+/* CRC of the string "123456789" is 0x2dfd2d88 */
+
+static void
+crc32rfc1510_init (void *context, unsigned int flags)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ u32 hwf = _gcry_get_hw_features ();
+
+#ifdef USE_INTEL_PCLMUL
+ ctx->use_pclmul = (hwf & HWF_INTEL_SSE4_1) && (hwf & HWF_INTEL_PCLMUL);
+#endif
+#ifdef USE_ARM_PMULL
+ ctx->use_pmull = (hwf & HWF_ARM_NEON) && (hwf & HWF_ARM_PMULL);
+#endif
+#ifdef USE_PPC_VPMSUM
+ ctx->use_vpmsum = !!(hwf & HWF_PPC_ARCH_2_07);
+#endif
+
+ (void)flags;
+ (void)hwf;
+
+ ctx->CRC = 0;
+}
+
+static void
+crc32rfc1510_final (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ buf_put_be32(ctx->buf, ctx->CRC);
+}
+
+/* CRC24 a'la RFC 2440 */
+/*
+ * Code generated by universal_crc by Danjel McGougan
+ *
+ * CRC parameters used:
+ * bits: 24
+ * poly: 0x864cfb
+ * init: 0xb704ce
+ * xor: 0x000000
+ * reverse: false
+ * non-direct: false
+ *
+ * CRC of the string "123456789" is 0x21cf02
+ */
+
+static const u32 crc24_table[1024] =
+{
+ 0x00000000, 0x00fb4c86, 0x000dd58a, 0x00f6990c,
+ 0x00e1e693, 0x001aaa15, 0x00ec3319, 0x00177f9f,
+ 0x003981a1, 0x00c2cd27, 0x0034542b, 0x00cf18ad,
+ 0x00d86732, 0x00232bb4, 0x00d5b2b8, 0x002efe3e,
+ 0x00894ec5, 0x00720243, 0x00849b4f, 0x007fd7c9,
+ 0x0068a856, 0x0093e4d0, 0x00657ddc, 0x009e315a,
+ 0x00b0cf64, 0x004b83e2, 0x00bd1aee, 0x00465668,
+ 0x005129f7, 0x00aa6571, 0x005cfc7d, 0x00a7b0fb,
+ 0x00e9d10c, 0x00129d8a, 0x00e40486, 0x001f4800,
+ 0x0008379f, 0x00f37b19, 0x0005e215, 0x00feae93,
+ 0x00d050ad, 0x002b1c2b, 0x00dd8527, 0x0026c9a1,
+ 0x0031b63e, 0x00cafab8, 0x003c63b4, 0x00c72f32,
+ 0x00609fc9, 0x009bd34f, 0x006d4a43, 0x009606c5,
+ 0x0081795a, 0x007a35dc, 0x008cacd0, 0x0077e056,
+ 0x00591e68, 0x00a252ee, 0x0054cbe2, 0x00af8764,
+ 0x00b8f8fb, 0x0043b47d, 0x00b52d71, 0x004e61f7,
+ 0x00d2a319, 0x0029ef9f, 0x00df7693, 0x00243a15,
+ 0x0033458a, 0x00c8090c, 0x003e9000, 0x00c5dc86,
+ 0x00eb22b8, 0x00106e3e, 0x00e6f732, 0x001dbbb4,
+ 0x000ac42b, 0x00f188ad, 0x000711a1, 0x00fc5d27,
+ 0x005beddc, 0x00a0a15a, 0x00563856, 0x00ad74d0,
+ 0x00ba0b4f, 0x004147c9, 0x00b7dec5, 0x004c9243,
+ 0x00626c7d, 0x009920fb, 0x006fb9f7, 0x0094f571,
+ 0x00838aee, 0x0078c668, 0x008e5f64, 0x007513e2,
+ 0x003b7215, 0x00c03e93, 0x0036a79f, 0x00cdeb19,
+ 0x00da9486, 0x0021d800, 0x00d7410c, 0x002c0d8a,
+ 0x0002f3b4, 0x00f9bf32, 0x000f263e, 0x00f46ab8,
+ 0x00e31527, 0x001859a1, 0x00eec0ad, 0x00158c2b,
+ 0x00b23cd0, 0x00497056, 0x00bfe95a, 0x0044a5dc,
+ 0x0053da43, 0x00a896c5, 0x005e0fc9, 0x00a5434f,
+ 0x008bbd71, 0x0070f1f7, 0x008668fb, 0x007d247d,
+ 0x006a5be2, 0x00911764, 0x00678e68, 0x009cc2ee,
+ 0x00a44733, 0x005f0bb5, 0x00a992b9, 0x0052de3f,
+ 0x0045a1a0, 0x00beed26, 0x0048742a, 0x00b338ac,
+ 0x009dc692, 0x00668a14, 0x00901318, 0x006b5f9e,
+ 0x007c2001, 0x00876c87, 0x0071f58b, 0x008ab90d,
+ 0x002d09f6, 0x00d64570, 0x0020dc7c, 0x00db90fa,
+ 0x00ccef65, 0x0037a3e3, 0x00c13aef, 0x003a7669,
+ 0x00148857, 0x00efc4d1, 0x00195ddd, 0x00e2115b,
+ 0x00f56ec4, 0x000e2242, 0x00f8bb4e, 0x0003f7c8,
+ 0x004d963f, 0x00b6dab9, 0x004043b5, 0x00bb0f33,
+ 0x00ac70ac, 0x00573c2a, 0x00a1a526, 0x005ae9a0,
+ 0x0074179e, 0x008f5b18, 0x0079c214, 0x00828e92,
+ 0x0095f10d, 0x006ebd8b, 0x00982487, 0x00636801,
+ 0x00c4d8fa, 0x003f947c, 0x00c90d70, 0x003241f6,
+ 0x00253e69, 0x00de72ef, 0x0028ebe3, 0x00d3a765,
+ 0x00fd595b, 0x000615dd, 0x00f08cd1, 0x000bc057,
+ 0x001cbfc8, 0x00e7f34e, 0x00116a42, 0x00ea26c4,
+ 0x0076e42a, 0x008da8ac, 0x007b31a0, 0x00807d26,
+ 0x009702b9, 0x006c4e3f, 0x009ad733, 0x00619bb5,
+ 0x004f658b, 0x00b4290d, 0x0042b001, 0x00b9fc87,
+ 0x00ae8318, 0x0055cf9e, 0x00a35692, 0x00581a14,
+ 0x00ffaaef, 0x0004e669, 0x00f27f65, 0x000933e3,
+ 0x001e4c7c, 0x00e500fa, 0x001399f6, 0x00e8d570,
+ 0x00c62b4e, 0x003d67c8, 0x00cbfec4, 0x0030b242,
+ 0x0027cddd, 0x00dc815b, 0x002a1857, 0x00d154d1,
+ 0x009f3526, 0x006479a0, 0x0092e0ac, 0x0069ac2a,
+ 0x007ed3b5, 0x00859f33, 0x0073063f, 0x00884ab9,
+ 0x00a6b487, 0x005df801, 0x00ab610d, 0x00502d8b,
+ 0x00475214, 0x00bc1e92, 0x004a879e, 0x00b1cb18,
+ 0x00167be3, 0x00ed3765, 0x001bae69, 0x00e0e2ef,
+ 0x00f79d70, 0x000cd1f6, 0x00fa48fa, 0x0001047c,
+ 0x002ffa42, 0x00d4b6c4, 0x00222fc8, 0x00d9634e,
+ 0x00ce1cd1, 0x00355057, 0x00c3c95b, 0x003885dd,
+ 0x00000000, 0x00488f66, 0x00901ecd, 0x00d891ab,
+ 0x00db711c, 0x0093fe7a, 0x004b6fd1, 0x0003e0b7,
+ 0x00b6e338, 0x00fe6c5e, 0x0026fdf5, 0x006e7293,
+ 0x006d9224, 0x00251d42, 0x00fd8ce9, 0x00b5038f,
+ 0x006cc771, 0x00244817, 0x00fcd9bc, 0x00b456da,
+ 0x00b7b66d, 0x00ff390b, 0x0027a8a0, 0x006f27c6,
+ 0x00da2449, 0x0092ab2f, 0x004a3a84, 0x0002b5e2,
+ 0x00015555, 0x0049da33, 0x00914b98, 0x00d9c4fe,
+ 0x00d88ee3, 0x00900185, 0x0048902e, 0x00001f48,
+ 0x0003ffff, 0x004b7099, 0x0093e132, 0x00db6e54,
+ 0x006e6ddb, 0x0026e2bd, 0x00fe7316, 0x00b6fc70,
+ 0x00b51cc7, 0x00fd93a1, 0x0025020a, 0x006d8d6c,
+ 0x00b44992, 0x00fcc6f4, 0x0024575f, 0x006cd839,
+ 0x006f388e, 0x0027b7e8, 0x00ff2643, 0x00b7a925,
+ 0x0002aaaa, 0x004a25cc, 0x0092b467, 0x00da3b01,
+ 0x00d9dbb6, 0x009154d0, 0x0049c57b, 0x00014a1d,
+ 0x004b5141, 0x0003de27, 0x00db4f8c, 0x0093c0ea,
+ 0x0090205d, 0x00d8af3b, 0x00003e90, 0x0048b1f6,
+ 0x00fdb279, 0x00b53d1f, 0x006dacb4, 0x002523d2,
+ 0x0026c365, 0x006e4c03, 0x00b6dda8, 0x00fe52ce,
+ 0x00279630, 0x006f1956, 0x00b788fd, 0x00ff079b,
+ 0x00fce72c, 0x00b4684a, 0x006cf9e1, 0x00247687,
+ 0x00917508, 0x00d9fa6e, 0x00016bc5, 0x0049e4a3,
+ 0x004a0414, 0x00028b72, 0x00da1ad9, 0x009295bf,
+ 0x0093dfa2, 0x00db50c4, 0x0003c16f, 0x004b4e09,
+ 0x0048aebe, 0x000021d8, 0x00d8b073, 0x00903f15,
+ 0x00253c9a, 0x006db3fc, 0x00b52257, 0x00fdad31,
+ 0x00fe4d86, 0x00b6c2e0, 0x006e534b, 0x0026dc2d,
+ 0x00ff18d3, 0x00b797b5, 0x006f061e, 0x00278978,
+ 0x002469cf, 0x006ce6a9, 0x00b47702, 0x00fcf864,
+ 0x0049fbeb, 0x0001748d, 0x00d9e526, 0x00916a40,
+ 0x00928af7, 0x00da0591, 0x0002943a, 0x004a1b5c,
+ 0x0096a282, 0x00de2de4, 0x0006bc4f, 0x004e3329,
+ 0x004dd39e, 0x00055cf8, 0x00ddcd53, 0x00954235,
+ 0x002041ba, 0x0068cedc, 0x00b05f77, 0x00f8d011,
+ 0x00fb30a6, 0x00b3bfc0, 0x006b2e6b, 0x0023a10d,
+ 0x00fa65f3, 0x00b2ea95, 0x006a7b3e, 0x0022f458,
+ 0x002114ef, 0x00699b89, 0x00b10a22, 0x00f98544,
+ 0x004c86cb, 0x000409ad, 0x00dc9806, 0x00941760,
+ 0x0097f7d7, 0x00df78b1, 0x0007e91a, 0x004f667c,
+ 0x004e2c61, 0x0006a307, 0x00de32ac, 0x0096bdca,
+ 0x00955d7d, 0x00ddd21b, 0x000543b0, 0x004dccd6,
+ 0x00f8cf59, 0x00b0403f, 0x0068d194, 0x00205ef2,
+ 0x0023be45, 0x006b3123, 0x00b3a088, 0x00fb2fee,
+ 0x0022eb10, 0x006a6476, 0x00b2f5dd, 0x00fa7abb,
+ 0x00f99a0c, 0x00b1156a, 0x006984c1, 0x00210ba7,
+ 0x00940828, 0x00dc874e, 0x000416e5, 0x004c9983,
+ 0x004f7934, 0x0007f652, 0x00df67f9, 0x0097e89f,
+ 0x00ddf3c3, 0x00957ca5, 0x004ded0e, 0x00056268,
+ 0x000682df, 0x004e0db9, 0x00969c12, 0x00de1374,
+ 0x006b10fb, 0x00239f9d, 0x00fb0e36, 0x00b38150,
+ 0x00b061e7, 0x00f8ee81, 0x00207f2a, 0x0068f04c,
+ 0x00b134b2, 0x00f9bbd4, 0x00212a7f, 0x0069a519,
+ 0x006a45ae, 0x0022cac8, 0x00fa5b63, 0x00b2d405,
+ 0x0007d78a, 0x004f58ec, 0x0097c947, 0x00df4621,
+ 0x00dca696, 0x009429f0, 0x004cb85b, 0x0004373d,
+ 0x00057d20, 0x004df246, 0x009563ed, 0x00ddec8b,
+ 0x00de0c3c, 0x0096835a, 0x004e12f1, 0x00069d97,
+ 0x00b39e18, 0x00fb117e, 0x002380d5, 0x006b0fb3,
+ 0x0068ef04, 0x00206062, 0x00f8f1c9, 0x00b07eaf,
+ 0x0069ba51, 0x00213537, 0x00f9a49c, 0x00b12bfa,
+ 0x00b2cb4d, 0x00fa442b, 0x0022d580, 0x006a5ae6,
+ 0x00df5969, 0x0097d60f, 0x004f47a4, 0x0007c8c2,
+ 0x00042875, 0x004ca713, 0x009436b8, 0x00dcb9de,
+ 0x00000000, 0x00d70983, 0x00555f80, 0x00825603,
+ 0x0051f286, 0x0086fb05, 0x0004ad06, 0x00d3a485,
+ 0x0059a88b, 0x008ea108, 0x000cf70b, 0x00dbfe88,
+ 0x00085a0d, 0x00df538e, 0x005d058d, 0x008a0c0e,
+ 0x00491c91, 0x009e1512, 0x001c4311, 0x00cb4a92,
+ 0x0018ee17, 0x00cfe794, 0x004db197, 0x009ab814,
+ 0x0010b41a, 0x00c7bd99, 0x0045eb9a, 0x0092e219,
+ 0x0041469c, 0x00964f1f, 0x0014191c, 0x00c3109f,
+ 0x006974a4, 0x00be7d27, 0x003c2b24, 0x00eb22a7,
+ 0x00388622, 0x00ef8fa1, 0x006dd9a2, 0x00bad021,
+ 0x0030dc2f, 0x00e7d5ac, 0x006583af, 0x00b28a2c,
+ 0x00612ea9, 0x00b6272a, 0x00347129, 0x00e378aa,
+ 0x00206835, 0x00f761b6, 0x007537b5, 0x00a23e36,
+ 0x00719ab3, 0x00a69330, 0x0024c533, 0x00f3ccb0,
+ 0x0079c0be, 0x00aec93d, 0x002c9f3e, 0x00fb96bd,
+ 0x00283238, 0x00ff3bbb, 0x007d6db8, 0x00aa643b,
+ 0x0029a4ce, 0x00fead4d, 0x007cfb4e, 0x00abf2cd,
+ 0x00785648, 0x00af5fcb, 0x002d09c8, 0x00fa004b,
+ 0x00700c45, 0x00a705c6, 0x002553c5, 0x00f25a46,
+ 0x0021fec3, 0x00f6f740, 0x0074a143, 0x00a3a8c0,
+ 0x0060b85f, 0x00b7b1dc, 0x0035e7df, 0x00e2ee5c,
+ 0x00314ad9, 0x00e6435a, 0x00641559, 0x00b31cda,
+ 0x003910d4, 0x00ee1957, 0x006c4f54, 0x00bb46d7,
+ 0x0068e252, 0x00bfebd1, 0x003dbdd2, 0x00eab451,
+ 0x0040d06a, 0x0097d9e9, 0x00158fea, 0x00c28669,
+ 0x001122ec, 0x00c62b6f, 0x00447d6c, 0x009374ef,
+ 0x001978e1, 0x00ce7162, 0x004c2761, 0x009b2ee2,
+ 0x00488a67, 0x009f83e4, 0x001dd5e7, 0x00cadc64,
+ 0x0009ccfb, 0x00dec578, 0x005c937b, 0x008b9af8,
+ 0x00583e7d, 0x008f37fe, 0x000d61fd, 0x00da687e,
+ 0x00506470, 0x00876df3, 0x00053bf0, 0x00d23273,
+ 0x000196f6, 0x00d69f75, 0x0054c976, 0x0083c0f5,
+ 0x00a9041b, 0x007e0d98, 0x00fc5b9b, 0x002b5218,
+ 0x00f8f69d, 0x002fff1e, 0x00ada91d, 0x007aa09e,
+ 0x00f0ac90, 0x0027a513, 0x00a5f310, 0x0072fa93,
+ 0x00a15e16, 0x00765795, 0x00f40196, 0x00230815,
+ 0x00e0188a, 0x00371109, 0x00b5470a, 0x00624e89,
+ 0x00b1ea0c, 0x0066e38f, 0x00e4b58c, 0x0033bc0f,
+ 0x00b9b001, 0x006eb982, 0x00ecef81, 0x003be602,
+ 0x00e84287, 0x003f4b04, 0x00bd1d07, 0x006a1484,
+ 0x00c070bf, 0x0017793c, 0x00952f3f, 0x004226bc,
+ 0x00918239, 0x00468bba, 0x00c4ddb9, 0x0013d43a,
+ 0x0099d834, 0x004ed1b7, 0x00cc87b4, 0x001b8e37,
+ 0x00c82ab2, 0x001f2331, 0x009d7532, 0x004a7cb1,
+ 0x00896c2e, 0x005e65ad, 0x00dc33ae, 0x000b3a2d,
+ 0x00d89ea8, 0x000f972b, 0x008dc128, 0x005ac8ab,
+ 0x00d0c4a5, 0x0007cd26, 0x00859b25, 0x005292a6,
+ 0x00813623, 0x00563fa0, 0x00d469a3, 0x00036020,
+ 0x0080a0d5, 0x0057a956, 0x00d5ff55, 0x0002f6d6,
+ 0x00d15253, 0x00065bd0, 0x00840dd3, 0x00530450,
+ 0x00d9085e, 0x000e01dd, 0x008c57de, 0x005b5e5d,
+ 0x0088fad8, 0x005ff35b, 0x00dda558, 0x000aacdb,
+ 0x00c9bc44, 0x001eb5c7, 0x009ce3c4, 0x004bea47,
+ 0x00984ec2, 0x004f4741, 0x00cd1142, 0x001a18c1,
+ 0x009014cf, 0x00471d4c, 0x00c54b4f, 0x001242cc,
+ 0x00c1e649, 0x0016efca, 0x0094b9c9, 0x0043b04a,
+ 0x00e9d471, 0x003eddf2, 0x00bc8bf1, 0x006b8272,
+ 0x00b826f7, 0x006f2f74, 0x00ed7977, 0x003a70f4,
+ 0x00b07cfa, 0x00677579, 0x00e5237a, 0x00322af9,
+ 0x00e18e7c, 0x003687ff, 0x00b4d1fc, 0x0063d87f,
+ 0x00a0c8e0, 0x0077c163, 0x00f59760, 0x00229ee3,
+ 0x00f13a66, 0x002633e5, 0x00a465e6, 0x00736c65,
+ 0x00f9606b, 0x002e69e8, 0x00ac3feb, 0x007b3668,
+ 0x00a892ed, 0x007f9b6e, 0x00fdcd6d, 0x002ac4ee,
+ 0x00000000, 0x00520936, 0x00a4126c, 0x00f61b5a,
+ 0x004825d8, 0x001a2cee, 0x00ec37b4, 0x00be3e82,
+ 0x006b0636, 0x00390f00, 0x00cf145a, 0x009d1d6c,
+ 0x002323ee, 0x00712ad8, 0x00873182, 0x00d538b4,
+ 0x00d60c6c, 0x0084055a, 0x00721e00, 0x00201736,
+ 0x009e29b4, 0x00cc2082, 0x003a3bd8, 0x006832ee,
+ 0x00bd0a5a, 0x00ef036c, 0x00191836, 0x004b1100,
+ 0x00f52f82, 0x00a726b4, 0x00513dee, 0x000334d8,
+ 0x00ac19d8, 0x00fe10ee, 0x00080bb4, 0x005a0282,
+ 0x00e43c00, 0x00b63536, 0x00402e6c, 0x0012275a,
+ 0x00c71fee, 0x009516d8, 0x00630d82, 0x003104b4,
+ 0x008f3a36, 0x00dd3300, 0x002b285a, 0x0079216c,
+ 0x007a15b4, 0x00281c82, 0x00de07d8, 0x008c0eee,
+ 0x0032306c, 0x0060395a, 0x00962200, 0x00c42b36,
+ 0x00111382, 0x00431ab4, 0x00b501ee, 0x00e708d8,
+ 0x0059365a, 0x000b3f6c, 0x00fd2436, 0x00af2d00,
+ 0x00a37f36, 0x00f17600, 0x00076d5a, 0x0055646c,
+ 0x00eb5aee, 0x00b953d8, 0x004f4882, 0x001d41b4,
+ 0x00c87900, 0x009a7036, 0x006c6b6c, 0x003e625a,
+ 0x00805cd8, 0x00d255ee, 0x00244eb4, 0x00764782,
+ 0x0075735a, 0x00277a6c, 0x00d16136, 0x00836800,
+ 0x003d5682, 0x006f5fb4, 0x009944ee, 0x00cb4dd8,
+ 0x001e756c, 0x004c7c5a, 0x00ba6700, 0x00e86e36,
+ 0x005650b4, 0x00045982, 0x00f242d8, 0x00a04bee,
+ 0x000f66ee, 0x005d6fd8, 0x00ab7482, 0x00f97db4,
+ 0x00474336, 0x00154a00, 0x00e3515a, 0x00b1586c,
+ 0x006460d8, 0x003669ee, 0x00c072b4, 0x00927b82,
+ 0x002c4500, 0x007e4c36, 0x0088576c, 0x00da5e5a,
+ 0x00d96a82, 0x008b63b4, 0x007d78ee, 0x002f71d8,
+ 0x00914f5a, 0x00c3466c, 0x00355d36, 0x00675400,
+ 0x00b26cb4, 0x00e06582, 0x00167ed8, 0x004477ee,
+ 0x00fa496c, 0x00a8405a, 0x005e5b00, 0x000c5236,
+ 0x0046ff6c, 0x0014f65a, 0x00e2ed00, 0x00b0e436,
+ 0x000edab4, 0x005cd382, 0x00aac8d8, 0x00f8c1ee,
+ 0x002df95a, 0x007ff06c, 0x0089eb36, 0x00dbe200,
+ 0x0065dc82, 0x0037d5b4, 0x00c1ceee, 0x0093c7d8,
+ 0x0090f300, 0x00c2fa36, 0x0034e16c, 0x0066e85a,
+ 0x00d8d6d8, 0x008adfee, 0x007cc4b4, 0x002ecd82,
+ 0x00fbf536, 0x00a9fc00, 0x005fe75a, 0x000dee6c,
+ 0x00b3d0ee, 0x00e1d9d8, 0x0017c282, 0x0045cbb4,
+ 0x00eae6b4, 0x00b8ef82, 0x004ef4d8, 0x001cfdee,
+ 0x00a2c36c, 0x00f0ca5a, 0x0006d100, 0x0054d836,
+ 0x0081e082, 0x00d3e9b4, 0x0025f2ee, 0x0077fbd8,
+ 0x00c9c55a, 0x009bcc6c, 0x006dd736, 0x003fde00,
+ 0x003cead8, 0x006ee3ee, 0x0098f8b4, 0x00caf182,
+ 0x0074cf00, 0x0026c636, 0x00d0dd6c, 0x0082d45a,
+ 0x0057ecee, 0x0005e5d8, 0x00f3fe82, 0x00a1f7b4,
+ 0x001fc936, 0x004dc000, 0x00bbdb5a, 0x00e9d26c,
+ 0x00e5805a, 0x00b7896c, 0x00419236, 0x00139b00,
+ 0x00ada582, 0x00ffacb4, 0x0009b7ee, 0x005bbed8,
+ 0x008e866c, 0x00dc8f5a, 0x002a9400, 0x00789d36,
+ 0x00c6a3b4, 0x0094aa82, 0x0062b1d8, 0x0030b8ee,
+ 0x00338c36, 0x00618500, 0x00979e5a, 0x00c5976c,
+ 0x007ba9ee, 0x0029a0d8, 0x00dfbb82, 0x008db2b4,
+ 0x00588a00, 0x000a8336, 0x00fc986c, 0x00ae915a,
+ 0x0010afd8, 0x0042a6ee, 0x00b4bdb4, 0x00e6b482,
+ 0x00499982, 0x001b90b4, 0x00ed8bee, 0x00bf82d8,
+ 0x0001bc5a, 0x0053b56c, 0x00a5ae36, 0x00f7a700,
+ 0x00229fb4, 0x00709682, 0x00868dd8, 0x00d484ee,
+ 0x006aba6c, 0x0038b35a, 0x00cea800, 0x009ca136,
+ 0x009f95ee, 0x00cd9cd8, 0x003b8782, 0x00698eb4,
+ 0x00d7b036, 0x0085b900, 0x0073a25a, 0x0021ab6c,
+ 0x00f493d8, 0x00a69aee, 0x005081b4, 0x00028882,
+ 0x00bcb600, 0x00eebf36, 0x0018a46c, 0x004aad5a
+};
+
+static inline
+u32 crc24_init (void)
+{
+ /* Transformed to 32-bit CRC by multiplied by x⸠and then byte swapped. */
+ return 0xce04b7; /* _gcry_bswap(0xb704ce << 8) */
+}
+
+static inline
+u32 crc24_next (u32 crc, byte data)
+{
+ return (crc >> 8) ^ crc24_table[(crc & 0xff) ^ data];
+}
+
+/*
+ * Process 4 bytes in one go
+ */
+static inline
+u32 crc24_next4 (u32 crc, u32 data)
+{
+ crc ^= data;
+ crc = crc24_table[(crc & 0xff) + 0x300] ^
+ crc24_table[((crc >> 8) & 0xff) + 0x200] ^
+ crc24_table[((crc >> 16) & 0xff) + 0x100] ^
+ crc24_table[(data >> 24) & 0xff];
+ return crc;
+}
+
+static inline
+u32 crc24_final (u32 crc)
+{
+ return crc & 0xffffff;
+}
+
+static void
+crc24rfc2440_init (void *context, unsigned int flags)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ u32 hwf = _gcry_get_hw_features ();
+
+#ifdef USE_INTEL_PCLMUL
+ ctx->use_pclmul = (hwf & HWF_INTEL_SSE4_1) && (hwf & HWF_INTEL_PCLMUL);
+#endif
+#ifdef USE_ARM_PMULL
+ ctx->use_pmull = (hwf & HWF_ARM_NEON) && (hwf & HWF_ARM_PMULL);
+#endif
+#ifdef USE_PPC_VPMSUM
+ ctx->use_vpmsum = !!(hwf & HWF_PPC_ARCH_2_07);
+#endif
+
+ (void)hwf;
+ (void)flags;
+
+ ctx->CRC = crc24_init();
+}
+
+static void
+crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ u32 crc;
+
+#ifdef USE_INTEL_PCLMUL
+ if (ctx->use_pclmul)
+ {
+ _gcry_crc24rfc2440_intel_pclmul(&ctx->CRC, inbuf, inlen);
+ return;
+ }
+#endif
+#ifdef USE_ARM_PMULL
+ if (ctx->use_pmull)
+ {
+ _gcry_crc24rfc2440_armv8_ce_pmull(&ctx->CRC, inbuf, inlen);
+ return;
+ }
+#endif
+#ifdef USE_PPC_VPMSUM
+ if (ctx->use_vpmsum)
+ {
+ _gcry_crc24rfc2440_ppc8_vpmsum(&ctx->CRC, inbuf, inlen);
+ return;
+ }
+#endif
+
+ if (!inbuf || !inlen)
+ return;
+
+ crc = ctx->CRC;
+
+ while (inlen >= 16)
+ {
+ inlen -= 16;
+ crc = crc24_next4(crc, buf_get_le32(&inbuf[0]));
+ crc = crc24_next4(crc, buf_get_le32(&inbuf[4]));
+ crc = crc24_next4(crc, buf_get_le32(&inbuf[8]));
+ crc = crc24_next4(crc, buf_get_le32(&inbuf[12]));
+ inbuf += 16;
+ }
+
+ while (inlen >= 4)
+ {
+ inlen -= 4;
+ crc = crc24_next4(crc, buf_get_le32(inbuf));
+ inbuf += 4;
+ }
+
+ while (inlen--)
+ {
+ crc = crc24_next(crc, *inbuf++);
+ }
+
+ ctx->CRC = crc;
+}
+
+static void
+crc24rfc2440_final (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ ctx->CRC = crc24_final(ctx->CRC);
+ buf_put_le32 (ctx->buf, ctx->CRC);
+}
+
+/* We allow the CRC algorithms even in FIPS mode because they are
+ actually no cryptographic primitives. */
+
+gcry_md_spec_t _gcry_digest_spec_crc32 =
+ {
+ GCRY_MD_CRC32, {0, 1},
+ "CRC32", NULL, 0, NULL, 4,
+ crc32_init, crc32_write, crc32_final, crc32_read, NULL,
+ NULL, NULL,
+ sizeof (CRC_CONTEXT)
+ };
+
+gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
+ {
+ GCRY_MD_CRC32_RFC1510, {0, 1},
+ "CRC32RFC1510", NULL, 0, NULL, 4,
+ crc32rfc1510_init, crc32_write, crc32rfc1510_final, crc32_read, NULL,
+ NULL, NULL,
+ sizeof (CRC_CONTEXT)
+ };
+
+gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
+ {
+ GCRY_MD_CRC24_RFC2440, {0, 1},
+ "CRC24RFC2440", NULL, 0, NULL, 3,
+ crc24rfc2440_init, crc24rfc2440_write, crc24rfc2440_final, crc32_read, NULL,
+ NULL, NULL,
+ sizeof (CRC_CONTEXT)
+ };
diff --git a/comm/third_party/libgcrypt/cipher/des-amd64.S b/comm/third_party/libgcrypt/cipher/des-amd64.S
new file mode 100644
index 0000000000..a211dac38a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/des-amd64.S
@@ -0,0 +1,1111 @@
+/* des-amd64.S - AMD64 assembly implementation of 3DES cipher
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(USE_DES) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#include "asm-common-amd64.h"
+
+.text
+
+#define s1 0
+#define s2 ((s1) + (64*8))
+#define s3 ((s2) + (64*8))
+#define s4 ((s3) + (64*8))
+#define s5 ((s4) + (64*8))
+#define s6 ((s5) + (64*8))
+#define s7 ((s6) + (64*8))
+#define s8 ((s7) + (64*8))
+
+/* register macros */
+#define CTX %rdi
+#define SBOXES %rbp
+
+#define RL0 %r8
+#define RL1 %r9
+#define RL2 %r10
+
+#define RL0d %r8d
+#define RL1d %r9d
+#define RL2d %r10d
+
+#define RR0 %r11
+#define RR1 %r12
+#define RR2 %r13
+
+#define RR0d %r11d
+#define RR1d %r12d
+#define RR2d %r13d
+
+#define RW0 %rax
+#define RW1 %rbx
+#define RW2 %rcx
+
+#define RW0d %eax
+#define RW1d %ebx
+#define RW2d %ecx
+
+#define RW0bl %al
+#define RW1bl %bl
+#define RW2bl %cl
+
+#define RW0bh %ah
+#define RW1bh %bh
+#define RW2bh %ch
+
+#define RT0 %r15
+#define RT1 %rsi
+#define RT2 %r14
+#define RT3 %rdx
+
+#define RT0d %r15d
+#define RT1d %esi
+#define RT2d %r14d
+#define RT3d %edx
+
+/***********************************************************************
+ * 1-way 3DES
+ ***********************************************************************/
+#define do_permutation(a, b, offset, mask) \
+ movl a, RT0d; \
+ shrl $(offset), RT0d; \
+ xorl b, RT0d; \
+ andl $(mask), RT0d; \
+ xorl RT0d, b; \
+ shll $(offset), RT0d; \
+ xorl RT0d, a;
+
+#define expand_to_64bits(val, mask) \
+ movl val##d, RT0d; \
+ rorl $4, RT0d; \
+ shlq $32, RT0; \
+ orq RT0, val; \
+ andq mask, val;
+
+#define compress_to_64bits(val) \
+ movq val, RT0; \
+ shrq $32, RT0; \
+ roll $4, RT0d; \
+ orl RT0d, val##d;
+
+#define initial_permutation(left, right) \
+ do_permutation(left##d, right##d, 4, 0x0f0f0f0f); \
+ do_permutation(left##d, right##d, 16, 0x0000ffff); \
+ do_permutation(right##d, left##d, 2, 0x33333333); \
+ do_permutation(right##d, left##d, 8, 0x00ff00ff); \
+ movabs $0x3f3f3f3f3f3f3f3f, RT3; \
+ movl left##d, RW0d; \
+ roll $1, right##d; \
+ xorl right##d, RW0d; \
+ andl $0xaaaaaaaa, RW0d; \
+ xorl RW0d, left##d; \
+ xorl RW0d, right##d; \
+ roll $1, left##d; \
+ expand_to_64bits(right, RT3); \
+ expand_to_64bits(left, RT3);
+
+#define final_permutation(left, right) \
+ compress_to_64bits(right); \
+ compress_to_64bits(left); \
+ movl right##d, RW0d; \
+ rorl $1, left##d; \
+ xorl left##d, RW0d; \
+ andl $0xaaaaaaaa, RW0d; \
+ xorl RW0d, right##d; \
+ xorl RW0d, left##d; \
+ rorl $1, right##d; \
+ do_permutation(right##d, left##d, 8, 0x00ff00ff); \
+ do_permutation(right##d, left##d, 2, 0x33333333); \
+ do_permutation(left##d, right##d, 16, 0x0000ffff); \
+ do_permutation(left##d, right##d, 4, 0x0f0f0f0f);
+
+#define round1(n, from, to, load_next_key) \
+ xorq from, RW0; \
+ \
+ movzbl RW0bl, RT0d; \
+ movzbl RW0bh, RT1d; \
+ shrq $16, RW0; \
+ movzbl RW0bl, RT2d; \
+ movzbl RW0bh, RT3d; \
+ shrq $16, RW0; \
+ movq s8(SBOXES, RT0, 8), RT0; \
+ xorq s6(SBOXES, RT1, 8), to; \
+ movzbl RW0bl, RL1d; \
+ movzbl RW0bh, RT1d; \
+ shrl $16, RW0d; \
+ xorq s4(SBOXES, RT2, 8), RT0; \
+ xorq s2(SBOXES, RT3, 8), to; \
+ movzbl RW0bl, RT2d; \
+ movzbl RW0bh, RT3d; \
+ xorq s7(SBOXES, RL1, 8), RT0; \
+ xorq s5(SBOXES, RT1, 8), to; \
+ xorq s3(SBOXES, RT2, 8), RT0; \
+ load_next_key(n, RW0); \
+ xorq RT0, to; \
+ xorq s1(SBOXES, RT3, 8), to; \
+
+#define load_next_key(n, RWx) \
+ movq (((n) + 1) * 8)(CTX), RWx;
+
+#define dummy2(a, b) /*_*/
+
+#define read_block(io, left, right) \
+ movl (io), left##d; \
+ movl 4(io), right##d; \
+ bswapl left##d; \
+ bswapl right##d;
+
+#define write_block(io, left, right) \
+ bswapl left##d; \
+ bswapl right##d; \
+ movl left##d, (io); \
+ movl right##d, 4(io);
+
+.align 8
+.globl _gcry_3des_amd64_crypt_block
+ELF(.type _gcry_3des_amd64_crypt_block,@function;)
+
+_gcry_3des_amd64_crypt_block:
+ /* input:
+ * %rdi: round keys, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+ pushq %r14;
+ CFI_PUSH(%r14);
+ pushq %r15;
+ CFI_PUSH(%r15);
+ pushq %rsi; /*dst*/
+ CFI_PUSH(%rsi);
+
+ leaq .L_s1 rRIP, SBOXES;
+
+ read_block(%rdx, RL0, RR0);
+ initial_permutation(RL0, RR0);
+
+ movq (CTX), RW0;
+
+ round1(0, RR0, RL0, load_next_key);
+ round1(1, RL0, RR0, load_next_key);
+ round1(2, RR0, RL0, load_next_key);
+ round1(3, RL0, RR0, load_next_key);
+ round1(4, RR0, RL0, load_next_key);
+ round1(5, RL0, RR0, load_next_key);
+ round1(6, RR0, RL0, load_next_key);
+ round1(7, RL0, RR0, load_next_key);
+ round1(8, RR0, RL0, load_next_key);
+ round1(9, RL0, RR0, load_next_key);
+ round1(10, RR0, RL0, load_next_key);
+ round1(11, RL0, RR0, load_next_key);
+ round1(12, RR0, RL0, load_next_key);
+ round1(13, RL0, RR0, load_next_key);
+ round1(14, RR0, RL0, load_next_key);
+ round1(15, RL0, RR0, load_next_key);
+
+ round1(16+0, RL0, RR0, load_next_key);
+ round1(16+1, RR0, RL0, load_next_key);
+ round1(16+2, RL0, RR0, load_next_key);
+ round1(16+3, RR0, RL0, load_next_key);
+ round1(16+4, RL0, RR0, load_next_key);
+ round1(16+5, RR0, RL0, load_next_key);
+ round1(16+6, RL0, RR0, load_next_key);
+ round1(16+7, RR0, RL0, load_next_key);
+ round1(16+8, RL0, RR0, load_next_key);
+ round1(16+9, RR0, RL0, load_next_key);
+ round1(16+10, RL0, RR0, load_next_key);
+ round1(16+11, RR0, RL0, load_next_key);
+ round1(16+12, RL0, RR0, load_next_key);
+ round1(16+13, RR0, RL0, load_next_key);
+ round1(16+14, RL0, RR0, load_next_key);
+ round1(16+15, RR0, RL0, load_next_key);
+
+ round1(32+0, RR0, RL0, load_next_key);
+ round1(32+1, RL0, RR0, load_next_key);
+ round1(32+2, RR0, RL0, load_next_key);
+ round1(32+3, RL0, RR0, load_next_key);
+ round1(32+4, RR0, RL0, load_next_key);
+ round1(32+5, RL0, RR0, load_next_key);
+ round1(32+6, RR0, RL0, load_next_key);
+ round1(32+7, RL0, RR0, load_next_key);
+ round1(32+8, RR0, RL0, load_next_key);
+ round1(32+9, RL0, RR0, load_next_key);
+ round1(32+10, RR0, RL0, load_next_key);
+ round1(32+11, RL0, RR0, load_next_key);
+ round1(32+12, RR0, RL0, load_next_key);
+ round1(32+13, RL0, RR0, load_next_key);
+ round1(32+14, RR0, RL0, load_next_key);
+ round1(32+15, RL0, RR0, dummy2);
+
+ popq RW2; /*dst*/
+ CFI_POP_TMP_REG();
+ final_permutation(RR0, RL0);
+ write_block(RW2, RR0, RL0);
+
+ popq %r15;
+ CFI_POP(%r15);
+ popq %r14;
+ CFI_POP(%r14);
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_3des_amd64_crypt_block,.-_gcry_3des_amd64_crypt_block;)
+
+/***********************************************************************
+ * 3-way 3DES
+ ***********************************************************************/
+#define expand_to_64bits(val, mask) \
+ movl val##d, RT0d; \
+ rorl $4, RT0d; \
+ shlq $32, RT0; \
+ orq RT0, val; \
+ andq mask, val;
+
+#define compress_to_64bits(val) \
+ movq val, RT0; \
+ shrq $32, RT0; \
+ roll $4, RT0d; \
+ orl RT0d, val##d;
+
+#define initial_permutation3(left, right) \
+ do_permutation(left##0d, right##0d, 4, 0x0f0f0f0f); \
+ do_permutation(left##0d, right##0d, 16, 0x0000ffff); \
+ do_permutation(left##1d, right##1d, 4, 0x0f0f0f0f); \
+ do_permutation(left##1d, right##1d, 16, 0x0000ffff); \
+ do_permutation(left##2d, right##2d, 4, 0x0f0f0f0f); \
+ do_permutation(left##2d, right##2d, 16, 0x0000ffff); \
+ \
+ do_permutation(right##0d, left##0d, 2, 0x33333333); \
+ do_permutation(right##0d, left##0d, 8, 0x00ff00ff); \
+ do_permutation(right##1d, left##1d, 2, 0x33333333); \
+ do_permutation(right##1d, left##1d, 8, 0x00ff00ff); \
+ do_permutation(right##2d, left##2d, 2, 0x33333333); \
+ do_permutation(right##2d, left##2d, 8, 0x00ff00ff); \
+ \
+ movabs $0x3f3f3f3f3f3f3f3f, RT3; \
+ \
+ movl left##0d, RW0d; \
+ roll $1, right##0d; \
+ xorl right##0d, RW0d; \
+ andl $0xaaaaaaaa, RW0d; \
+ xorl RW0d, left##0d; \
+ xorl RW0d, right##0d; \
+ roll $1, left##0d; \
+ expand_to_64bits(right##0, RT3); \
+ expand_to_64bits(left##0, RT3); \
+ movl left##1d, RW1d; \
+ roll $1, right##1d; \
+ xorl right##1d, RW1d; \
+ andl $0xaaaaaaaa, RW1d; \
+ xorl RW1d, left##1d; \
+ xorl RW1d, right##1d; \
+ roll $1, left##1d; \
+ expand_to_64bits(right##1, RT3); \
+ expand_to_64bits(left##1, RT3); \
+ movl left##2d, RW2d; \
+ roll $1, right##2d; \
+ xorl right##2d, RW2d; \
+ andl $0xaaaaaaaa, RW2d; \
+ xorl RW2d, left##2d; \
+ xorl RW2d, right##2d; \
+ roll $1, left##2d; \
+ expand_to_64bits(right##2, RT3); \
+ expand_to_64bits(left##2, RT3);
+
+#define final_permutation3(left, right) \
+ compress_to_64bits(right##0); \
+ compress_to_64bits(left##0); \
+ movl right##0d, RW0d; \
+ rorl $1, left##0d; \
+ xorl left##0d, RW0d; \
+ andl $0xaaaaaaaa, RW0d; \
+ xorl RW0d, right##0d; \
+ xorl RW0d, left##0d; \
+ rorl $1, right##0d; \
+ compress_to_64bits(right##1); \
+ compress_to_64bits(left##1); \
+ movl right##1d, RW1d; \
+ rorl $1, left##1d; \
+ xorl left##1d, RW1d; \
+ andl $0xaaaaaaaa, RW1d; \
+ xorl RW1d, right##1d; \
+ xorl RW1d, left##1d; \
+ rorl $1, right##1d; \
+ compress_to_64bits(right##2); \
+ compress_to_64bits(left##2); \
+ movl right##2d, RW2d; \
+ rorl $1, left##2d; \
+ xorl left##2d, RW2d; \
+ andl $0xaaaaaaaa, RW2d; \
+ xorl RW2d, right##2d; \
+ xorl RW2d, left##2d; \
+ rorl $1, right##2d; \
+ \
+ do_permutation(right##0d, left##0d, 8, 0x00ff00ff); \
+ do_permutation(right##0d, left##0d, 2, 0x33333333); \
+ do_permutation(right##1d, left##1d, 8, 0x00ff00ff); \
+ do_permutation(right##1d, left##1d, 2, 0x33333333); \
+ do_permutation(right##2d, left##2d, 8, 0x00ff00ff); \
+ do_permutation(right##2d, left##2d, 2, 0x33333333); \
+ \
+ do_permutation(left##0d, right##0d, 16, 0x0000ffff); \
+ do_permutation(left##0d, right##0d, 4, 0x0f0f0f0f); \
+ do_permutation(left##1d, right##1d, 16, 0x0000ffff); \
+ do_permutation(left##1d, right##1d, 4, 0x0f0f0f0f); \
+ do_permutation(left##2d, right##2d, 16, 0x0000ffff); \
+ do_permutation(left##2d, right##2d, 4, 0x0f0f0f0f);
+
+#define round3(n, from, to, load_next_key, do_movq) \
+ xorq from##0, RW0; \
+ movzbl RW0bl, RT3d; \
+ movzbl RW0bh, RT1d; \
+ shrq $16, RW0; \
+ xorq s8(SBOXES, RT3, 8), to##0; \
+ xorq s6(SBOXES, RT1, 8), to##0; \
+ movzbl RW0bl, RT3d; \
+ movzbl RW0bh, RT1d; \
+ shrq $16, RW0; \
+ xorq s4(SBOXES, RT3, 8), to##0; \
+ xorq s2(SBOXES, RT1, 8), to##0; \
+ movzbl RW0bl, RT3d; \
+ movzbl RW0bh, RT1d; \
+ shrl $16, RW0d; \
+ xorq s7(SBOXES, RT3, 8), to##0; \
+ xorq s5(SBOXES, RT1, 8), to##0; \
+ movzbl RW0bl, RT3d; \
+ movzbl RW0bh, RT1d; \
+ load_next_key(n, RW0); \
+ xorq s3(SBOXES, RT3, 8), to##0; \
+ xorq s1(SBOXES, RT1, 8), to##0; \
+ xorq from##1, RW1; \
+ movzbl RW1bl, RT3d; \
+ movzbl RW1bh, RT1d; \
+ shrq $16, RW1; \
+ xorq s8(SBOXES, RT3, 8), to##1; \
+ xorq s6(SBOXES, RT1, 8), to##1; \
+ movzbl RW1bl, RT3d; \
+ movzbl RW1bh, RT1d; \
+ shrq $16, RW1; \
+ xorq s4(SBOXES, RT3, 8), to##1; \
+ xorq s2(SBOXES, RT1, 8), to##1; \
+ movzbl RW1bl, RT3d; \
+ movzbl RW1bh, RT1d; \
+ shrl $16, RW1d; \
+ xorq s7(SBOXES, RT3, 8), to##1; \
+ xorq s5(SBOXES, RT1, 8), to##1; \
+ movzbl RW1bl, RT3d; \
+ movzbl RW1bh, RT1d; \
+ do_movq(RW0, RW1); \
+ xorq s3(SBOXES, RT3, 8), to##1; \
+ xorq s1(SBOXES, RT1, 8), to##1; \
+ xorq from##2, RW2; \
+ movzbl RW2bl, RT3d; \
+ movzbl RW2bh, RT1d; \
+ shrq $16, RW2; \
+ xorq s8(SBOXES, RT3, 8), to##2; \
+ xorq s6(SBOXES, RT1, 8), to##2; \
+ movzbl RW2bl, RT3d; \
+ movzbl RW2bh, RT1d; \
+ shrq $16, RW2; \
+ xorq s4(SBOXES, RT3, 8), to##2; \
+ xorq s2(SBOXES, RT1, 8), to##2; \
+ movzbl RW2bl, RT3d; \
+ movzbl RW2bh, RT1d; \
+ shrl $16, RW2d; \
+ xorq s7(SBOXES, RT3, 8), to##2; \
+ xorq s5(SBOXES, RT1, 8), to##2; \
+ movzbl RW2bl, RT3d; \
+ movzbl RW2bh, RT1d; \
+ do_movq(RW0, RW2); \
+ xorq s3(SBOXES, RT3, 8), to##2; \
+ xorq s1(SBOXES, RT1, 8), to##2;
+
+#define __movq(src, dst) \
+ movq src, dst;
+
+#define read_block(io, left, right) \
+ movl (io), left##d; \
+ movl 4(io), right##d; \
+ bswapl left##d; \
+ bswapl right##d;
+
+#define write_block(io, left, right) \
+ bswapl left##d; \
+ bswapl right##d; \
+ movl left##d, (io); \
+ movl right##d, 4(io);
+
+.align 8
+ELF(.type _gcry_3des_amd64_crypt_blk3,@function;)
+_gcry_3des_amd64_crypt_blk3:
+ /* input:
+ * %rdi: round keys, CTX
+ * RL0d, RR0d, RL1d, RR1d, RL2d, RR2d: 3 input blocks
+ * RR0d, RL0d, RR1d, RL1d, RR2d, RL2d: 3 output blocks
+ */
+ CFI_STARTPROC();
+
+ leaq .L_s1 rRIP, SBOXES;
+
+ initial_permutation3(RL, RR);
+
+ movq 0(CTX), RW0;
+ movq RW0, RW1;
+ movq RW0, RW2;
+
+ round3(0, RR, RL, load_next_key, __movq);
+ round3(1, RL, RR, load_next_key, __movq);
+ round3(2, RR, RL, load_next_key, __movq);
+ round3(3, RL, RR, load_next_key, __movq);
+ round3(4, RR, RL, load_next_key, __movq);
+ round3(5, RL, RR, load_next_key, __movq);
+ round3(6, RR, RL, load_next_key, __movq);
+ round3(7, RL, RR, load_next_key, __movq);
+ round3(8, RR, RL, load_next_key, __movq);
+ round3(9, RL, RR, load_next_key, __movq);
+ round3(10, RR, RL, load_next_key, __movq);
+ round3(11, RL, RR, load_next_key, __movq);
+ round3(12, RR, RL, load_next_key, __movq);
+ round3(13, RL, RR, load_next_key, __movq);
+ round3(14, RR, RL, load_next_key, __movq);
+ round3(15, RL, RR, load_next_key, __movq);
+
+ round3(16+0, RL, RR, load_next_key, __movq);
+ round3(16+1, RR, RL, load_next_key, __movq);
+ round3(16+2, RL, RR, load_next_key, __movq);
+ round3(16+3, RR, RL, load_next_key, __movq);
+ round3(16+4, RL, RR, load_next_key, __movq);
+ round3(16+5, RR, RL, load_next_key, __movq);
+ round3(16+6, RL, RR, load_next_key, __movq);
+ round3(16+7, RR, RL, load_next_key, __movq);
+ round3(16+8, RL, RR, load_next_key, __movq);
+ round3(16+9, RR, RL, load_next_key, __movq);
+ round3(16+10, RL, RR, load_next_key, __movq);
+ round3(16+11, RR, RL, load_next_key, __movq);
+ round3(16+12, RL, RR, load_next_key, __movq);
+ round3(16+13, RR, RL, load_next_key, __movq);
+ round3(16+14, RL, RR, load_next_key, __movq);
+ round3(16+15, RR, RL, load_next_key, __movq);
+
+ round3(32+0, RR, RL, load_next_key, __movq);
+ round3(32+1, RL, RR, load_next_key, __movq);
+ round3(32+2, RR, RL, load_next_key, __movq);
+ round3(32+3, RL, RR, load_next_key, __movq);
+ round3(32+4, RR, RL, load_next_key, __movq);
+ round3(32+5, RL, RR, load_next_key, __movq);
+ round3(32+6, RR, RL, load_next_key, __movq);
+ round3(32+7, RL, RR, load_next_key, __movq);
+ round3(32+8, RR, RL, load_next_key, __movq);
+ round3(32+9, RL, RR, load_next_key, __movq);
+ round3(32+10, RR, RL, load_next_key, __movq);
+ round3(32+11, RL, RR, load_next_key, __movq);
+ round3(32+12, RR, RL, load_next_key, __movq);
+ round3(32+13, RL, RR, load_next_key, __movq);
+ round3(32+14, RR, RL, load_next_key, __movq);
+ round3(32+15, RL, RR, dummy2, dummy2);
+
+ final_permutation3(RR, RL);
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_3des_amd64_crypt_blk3,.-_gcry_3des_amd64_crypt_blk3;)
+
+.align 8
+.globl _gcry_3des_amd64_cbc_dec
+ELF(.type _gcry_3des_amd64_cbc_dec,@function;)
+_gcry_3des_amd64_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (3 blocks)
+ * %rdx: src (3 blocks)
+ * %rcx: iv (64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+ pushq %r14;
+ CFI_PUSH(%r14);
+ pushq %r15;
+ CFI_PUSH(%r15);
+
+ pushq %rsi; /*dst*/
+ CFI_PUSH(%rsi);
+ pushq %rdx; /*src*/
+ CFI_PUSH(%rdx);
+ pushq %rcx; /*iv*/
+ CFI_PUSH(%rcx);
+
+ /* load input */
+ movl 0 * 4(%rdx), RL0d;
+ movl 1 * 4(%rdx), RR0d;
+ movl 2 * 4(%rdx), RL1d;
+ movl 3 * 4(%rdx), RR1d;
+ movl 4 * 4(%rdx), RL2d;
+ movl 5 * 4(%rdx), RR2d;
+
+ bswapl RL0d;
+ bswapl RR0d;
+ bswapl RL1d;
+ bswapl RR1d;
+ bswapl RL2d;
+ bswapl RR2d;
+
+ call _gcry_3des_amd64_crypt_blk3;
+
+ popq %rcx; /*iv*/
+ CFI_POP_TMP_REG();
+ popq %rdx; /*src*/
+ CFI_POP_TMP_REG();
+ popq %rsi; /*dst*/
+ CFI_POP_TMP_REG();
+
+ bswapl RR0d;
+ bswapl RL0d;
+ bswapl RR1d;
+ bswapl RL1d;
+ bswapl RR2d;
+ bswapl RL2d;
+
+ movq 2 * 8(%rdx), RT0;
+ xorl 0 * 4(%rcx), RR0d;
+ xorl 1 * 4(%rcx), RL0d;
+ xorl 0 * 4(%rdx), RR1d;
+ xorl 1 * 4(%rdx), RL1d;
+ xorl 2 * 4(%rdx), RR2d;
+ xorl 3 * 4(%rdx), RL2d;
+ movq RT0, (%rcx); /* store new IV */
+
+ movl RR0d, 0 * 4(%rsi);
+ movl RL0d, 1 * 4(%rsi);
+ movl RR1d, 2 * 4(%rsi);
+ movl RL1d, 3 * 4(%rsi);
+ movl RR2d, 4 * 4(%rsi);
+ movl RL2d, 5 * 4(%rsi);
+
+ popq %r15;
+ CFI_POP(%r15);
+ popq %r14;
+ CFI_POP(%r14);
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;)
+
+.align 8
+.globl _gcry_3des_amd64_ctr_enc
+ELF(.type _gcry_3des_amd64_ctr_enc,@function;)
+_gcry_3des_amd64_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (3 blocks)
+ * %rdx: src (3 blocks)
+ * %rcx: iv (64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+ pushq %r14;
+ CFI_PUSH(%r14);
+ pushq %r15;
+ CFI_PUSH(%r15);
+
+ pushq %rsi; /*dst*/
+ CFI_PUSH(%rsi);
+ pushq %rdx; /*src*/
+ CFI_PUSH(%rdx);
+ movq %rcx, RW2;
+
+ /* load IV and byteswap */
+ movq (RW2), RT0;
+ bswapq RT0;
+ movq RT0, RR0;
+
+ /* construct IVs */
+ leaq 1(RT0), RR1;
+ leaq 2(RT0), RR2;
+ leaq 3(RT0), RT0;
+ movq RR0, RL0;
+ movq RR1, RL1;
+ movq RR2, RL2;
+ bswapq RT0;
+ shrq $32, RL0;
+ shrq $32, RL1;
+ shrq $32, RL2;
+
+ /* store new IV */
+ movq RT0, (RW2);
+
+ call _gcry_3des_amd64_crypt_blk3;
+
+ popq %rdx; /*src*/
+ CFI_POP_TMP_REG();
+ popq %rsi; /*dst*/
+ CFI_POP_TMP_REG();
+
+ bswapl RR0d;
+ bswapl RL0d;
+ bswapl RR1d;
+ bswapl RL1d;
+ bswapl RR2d;
+ bswapl RL2d;
+
+ xorl 0 * 4(%rdx), RR0d;
+ xorl 1 * 4(%rdx), RL0d;
+ xorl 2 * 4(%rdx), RR1d;
+ xorl 3 * 4(%rdx), RL1d;
+ xorl 4 * 4(%rdx), RR2d;
+ xorl 5 * 4(%rdx), RL2d;
+
+ movl RR0d, 0 * 4(%rsi);
+ movl RL0d, 1 * 4(%rsi);
+ movl RR1d, 2 * 4(%rsi);
+ movl RL1d, 3 * 4(%rsi);
+ movl RR2d, 4 * 4(%rsi);
+ movl RL2d, 5 * 4(%rsi);
+
+ popq %r15;
+ CFI_POP(%r15);
+ popq %r14;
+ CFI_POP(%r14);
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;)
+
+.align 8
+.globl _gcry_3des_amd64_cfb_dec
+ELF(.type _gcry_3des_amd64_cfb_dec,@function;)
+_gcry_3des_amd64_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (3 blocks)
+ * %rdx: src (3 blocks)
+ * %rcx: iv (64bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %r12;
+ CFI_PUSH(%r12);
+ pushq %r13;
+ CFI_PUSH(%r13);
+ pushq %r14;
+ CFI_PUSH(%r14);
+ pushq %r15;
+ CFI_PUSH(%r15);
+
+ pushq %rsi; /*dst*/
+ CFI_PUSH(%rsi);
+ pushq %rdx; /*src*/
+ CFI_PUSH(%rdx);
+ movq %rcx, RW2;
+
+ /* Load input */
+ movl 0 * 4(RW2), RL0d;
+ movl 1 * 4(RW2), RR0d;
+ movl 0 * 4(%rdx), RL1d;
+ movl 1 * 4(%rdx), RR1d;
+ movl 2 * 4(%rdx), RL2d;
+ movl 3 * 4(%rdx), RR2d;
+
+ bswapl RL0d;
+ bswapl RR0d;
+ bswapl RL1d;
+ bswapl RR1d;
+ bswapl RL2d;
+ bswapl RR2d;
+
+ /* Update IV */
+ movq 4 * 4(%rdx), RW0;
+ movq RW0, (RW2);
+
+ call _gcry_3des_amd64_crypt_blk3;
+
+ popq %rdx; /*src*/
+ CFI_POP_TMP_REG();
+ popq %rsi; /*dst*/
+ CFI_POP_TMP_REG();
+
+ bswapl RR0d;
+ bswapl RL0d;
+ bswapl RR1d;
+ bswapl RL1d;
+ bswapl RR2d;
+ bswapl RL2d;
+
+ xorl 0 * 4(%rdx), RR0d;
+ xorl 1 * 4(%rdx), RL0d;
+ xorl 2 * 4(%rdx), RR1d;
+ xorl 3 * 4(%rdx), RL1d;
+ xorl 4 * 4(%rdx), RR2d;
+ xorl 5 * 4(%rdx), RL2d;
+
+ movl RR0d, 0 * 4(%rsi);
+ movl RL0d, 1 * 4(%rsi);
+ movl RR1d, 2 * 4(%rsi);
+ movl RL1d, 3 * 4(%rsi);
+ movl RR2d, 4 * 4(%rsi);
+ movl RL2d, 5 * 4(%rsi);
+
+ popq %r15;
+ CFI_POP(%r15);
+ popq %r14;
+ CFI_POP(%r14);
+ popq %r13;
+ CFI_POP(%r13);
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbx;
+ CFI_POP(%rbx);
+ popq %rbp;
+ CFI_POP(%rbp);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_3des_amd64_cfb_dec,.-_gcry_3des_amd64_cfb_dec;)
+
+.align 16
+.L_s1:
+ .quad 0x0010100001010400, 0x0000000000000000
+ .quad 0x0000100000010000, 0x0010100001010404
+ .quad 0x0010100001010004, 0x0000100000010404
+ .quad 0x0000000000000004, 0x0000100000010000
+ .quad 0x0000000000000400, 0x0010100001010400
+ .quad 0x0010100001010404, 0x0000000000000400
+ .quad 0x0010000001000404, 0x0010100001010004
+ .quad 0x0010000001000000, 0x0000000000000004
+ .quad 0x0000000000000404, 0x0010000001000400
+ .quad 0x0010000001000400, 0x0000100000010400
+ .quad 0x0000100000010400, 0x0010100001010000
+ .quad 0x0010100001010000, 0x0010000001000404
+ .quad 0x0000100000010004, 0x0010000001000004
+ .quad 0x0010000001000004, 0x0000100000010004
+ .quad 0x0000000000000000, 0x0000000000000404
+ .quad 0x0000100000010404, 0x0010000001000000
+ .quad 0x0000100000010000, 0x0010100001010404
+ .quad 0x0000000000000004, 0x0010100001010000
+ .quad 0x0010100001010400, 0x0010000001000000
+ .quad 0x0010000001000000, 0x0000000000000400
+ .quad 0x0010100001010004, 0x0000100000010000
+ .quad 0x0000100000010400, 0x0010000001000004
+ .quad 0x0000000000000400, 0x0000000000000004
+ .quad 0x0010000001000404, 0x0000100000010404
+ .quad 0x0010100001010404, 0x0000100000010004
+ .quad 0x0010100001010000, 0x0010000001000404
+ .quad 0x0010000001000004, 0x0000000000000404
+ .quad 0x0000100000010404, 0x0010100001010400
+ .quad 0x0000000000000404, 0x0010000001000400
+ .quad 0x0010000001000400, 0x0000000000000000
+ .quad 0x0000100000010004, 0x0000100000010400
+ .quad 0x0000000000000000, 0x0010100001010004
+.L_s2:
+ .quad 0x0801080200100020, 0x0800080000000000
+ .quad 0x0000080000000000, 0x0001080200100020
+ .quad 0x0001000000100000, 0x0000000200000020
+ .quad 0x0801000200100020, 0x0800080200000020
+ .quad 0x0800000200000020, 0x0801080200100020
+ .quad 0x0801080000100000, 0x0800000000000000
+ .quad 0x0800080000000000, 0x0001000000100000
+ .quad 0x0000000200000020, 0x0801000200100020
+ .quad 0x0001080000100000, 0x0001000200100020
+ .quad 0x0800080200000020, 0x0000000000000000
+ .quad 0x0800000000000000, 0x0000080000000000
+ .quad 0x0001080200100020, 0x0801000000100000
+ .quad 0x0001000200100020, 0x0800000200000020
+ .quad 0x0000000000000000, 0x0001080000100000
+ .quad 0x0000080200000020, 0x0801080000100000
+ .quad 0x0801000000100000, 0x0000080200000020
+ .quad 0x0000000000000000, 0x0001080200100020
+ .quad 0x0801000200100020, 0x0001000000100000
+ .quad 0x0800080200000020, 0x0801000000100000
+ .quad 0x0801080000100000, 0x0000080000000000
+ .quad 0x0801000000100000, 0x0800080000000000
+ .quad 0x0000000200000020, 0x0801080200100020
+ .quad 0x0001080200100020, 0x0000000200000020
+ .quad 0x0000080000000000, 0x0800000000000000
+ .quad 0x0000080200000020, 0x0801080000100000
+ .quad 0x0001000000100000, 0x0800000200000020
+ .quad 0x0001000200100020, 0x0800080200000020
+ .quad 0x0800000200000020, 0x0001000200100020
+ .quad 0x0001080000100000, 0x0000000000000000
+ .quad 0x0800080000000000, 0x0000080200000020
+ .quad 0x0800000000000000, 0x0801000200100020
+ .quad 0x0801080200100020, 0x0001080000100000
+.L_s3:
+ .quad 0x0000002000000208, 0x0000202008020200
+ .quad 0x0000000000000000, 0x0000200008020008
+ .quad 0x0000002008000200, 0x0000000000000000
+ .quad 0x0000202000020208, 0x0000002008000200
+ .quad 0x0000200000020008, 0x0000000008000008
+ .quad 0x0000000008000008, 0x0000200000020000
+ .quad 0x0000202008020208, 0x0000200000020008
+ .quad 0x0000200008020000, 0x0000002000000208
+ .quad 0x0000000008000000, 0x0000000000000008
+ .quad 0x0000202008020200, 0x0000002000000200
+ .quad 0x0000202000020200, 0x0000200008020000
+ .quad 0x0000200008020008, 0x0000202000020208
+ .quad 0x0000002008000208, 0x0000202000020200
+ .quad 0x0000200000020000, 0x0000002008000208
+ .quad 0x0000000000000008, 0x0000202008020208
+ .quad 0x0000002000000200, 0x0000000008000000
+ .quad 0x0000202008020200, 0x0000000008000000
+ .quad 0x0000200000020008, 0x0000002000000208
+ .quad 0x0000200000020000, 0x0000202008020200
+ .quad 0x0000002008000200, 0x0000000000000000
+ .quad 0x0000002000000200, 0x0000200000020008
+ .quad 0x0000202008020208, 0x0000002008000200
+ .quad 0x0000000008000008, 0x0000002000000200
+ .quad 0x0000000000000000, 0x0000200008020008
+ .quad 0x0000002008000208, 0x0000200000020000
+ .quad 0x0000000008000000, 0x0000202008020208
+ .quad 0x0000000000000008, 0x0000202000020208
+ .quad 0x0000202000020200, 0x0000000008000008
+ .quad 0x0000200008020000, 0x0000002008000208
+ .quad 0x0000002000000208, 0x0000200008020000
+ .quad 0x0000202000020208, 0x0000000000000008
+ .quad 0x0000200008020008, 0x0000202000020200
+.L_s4:
+ .quad 0x1008020000002001, 0x1000020800002001
+ .quad 0x1000020800002001, 0x0000000800000000
+ .quad 0x0008020800002000, 0x1008000800000001
+ .quad 0x1008000000000001, 0x1000020000002001
+ .quad 0x0000000000000000, 0x0008020000002000
+ .quad 0x0008020000002000, 0x1008020800002001
+ .quad 0x1000000800000001, 0x0000000000000000
+ .quad 0x0008000800000000, 0x1008000000000001
+ .quad 0x1000000000000001, 0x0000020000002000
+ .quad 0x0008000000000000, 0x1008020000002001
+ .quad 0x0000000800000000, 0x0008000000000000
+ .quad 0x1000020000002001, 0x0000020800002000
+ .quad 0x1008000800000001, 0x1000000000000001
+ .quad 0x0000020800002000, 0x0008000800000000
+ .quad 0x0000020000002000, 0x0008020800002000
+ .quad 0x1008020800002001, 0x1000000800000001
+ .quad 0x0008000800000000, 0x1008000000000001
+ .quad 0x0008020000002000, 0x1008020800002001
+ .quad 0x1000000800000001, 0x0000000000000000
+ .quad 0x0000000000000000, 0x0008020000002000
+ .quad 0x0000020800002000, 0x0008000800000000
+ .quad 0x1008000800000001, 0x1000000000000001
+ .quad 0x1008020000002001, 0x1000020800002001
+ .quad 0x1000020800002001, 0x0000000800000000
+ .quad 0x1008020800002001, 0x1000000800000001
+ .quad 0x1000000000000001, 0x0000020000002000
+ .quad 0x1008000000000001, 0x1000020000002001
+ .quad 0x0008020800002000, 0x1008000800000001
+ .quad 0x1000020000002001, 0x0000020800002000
+ .quad 0x0008000000000000, 0x1008020000002001
+ .quad 0x0000000800000000, 0x0008000000000000
+ .quad 0x0000020000002000, 0x0008020800002000
+.L_s5:
+ .quad 0x0000001000000100, 0x0020001002080100
+ .quad 0x0020000002080000, 0x0420001002000100
+ .quad 0x0000000000080000, 0x0000001000000100
+ .quad 0x0400000000000000, 0x0020000002080000
+ .quad 0x0400001000080100, 0x0000000000080000
+ .quad 0x0020001002000100, 0x0400001000080100
+ .quad 0x0420001002000100, 0x0420000002080000
+ .quad 0x0000001000080100, 0x0400000000000000
+ .quad 0x0020000002000000, 0x0400000000080000
+ .quad 0x0400000000080000, 0x0000000000000000
+ .quad 0x0400001000000100, 0x0420001002080100
+ .quad 0x0420001002080100, 0x0020001002000100
+ .quad 0x0420000002080000, 0x0400001000000100
+ .quad 0x0000000000000000, 0x0420000002000000
+ .quad 0x0020001002080100, 0x0020000002000000
+ .quad 0x0420000002000000, 0x0000001000080100
+ .quad 0x0000000000080000, 0x0420001002000100
+ .quad 0x0000001000000100, 0x0020000002000000
+ .quad 0x0400000000000000, 0x0020000002080000
+ .quad 0x0420001002000100, 0x0400001000080100
+ .quad 0x0020001002000100, 0x0400000000000000
+ .quad 0x0420000002080000, 0x0020001002080100
+ .quad 0x0400001000080100, 0x0000001000000100
+ .quad 0x0020000002000000, 0x0420000002080000
+ .quad 0x0420001002080100, 0x0000001000080100
+ .quad 0x0420000002000000, 0x0420001002080100
+ .quad 0x0020000002080000, 0x0000000000000000
+ .quad 0x0400000000080000, 0x0420000002000000
+ .quad 0x0000001000080100, 0x0020001002000100
+ .quad 0x0400001000000100, 0x0000000000080000
+ .quad 0x0000000000000000, 0x0400000000080000
+ .quad 0x0020001002080100, 0x0400001000000100
+.L_s6:
+ .quad 0x0200000120000010, 0x0204000020000000
+ .quad 0x0000040000000000, 0x0204040120000010
+ .quad 0x0204000020000000, 0x0000000100000010
+ .quad 0x0204040120000010, 0x0004000000000000
+ .quad 0x0200040020000000, 0x0004040100000010
+ .quad 0x0004000000000000, 0x0200000120000010
+ .quad 0x0004000100000010, 0x0200040020000000
+ .quad 0x0200000020000000, 0x0000040100000010
+ .quad 0x0000000000000000, 0x0004000100000010
+ .quad 0x0200040120000010, 0x0000040000000000
+ .quad 0x0004040000000000, 0x0200040120000010
+ .quad 0x0000000100000010, 0x0204000120000010
+ .quad 0x0204000120000010, 0x0000000000000000
+ .quad 0x0004040100000010, 0x0204040020000000
+ .quad 0x0000040100000010, 0x0004040000000000
+ .quad 0x0204040020000000, 0x0200000020000000
+ .quad 0x0200040020000000, 0x0000000100000010
+ .quad 0x0204000120000010, 0x0004040000000000
+ .quad 0x0204040120000010, 0x0004000000000000
+ .quad 0x0000040100000010, 0x0200000120000010
+ .quad 0x0004000000000000, 0x0200040020000000
+ .quad 0x0200000020000000, 0x0000040100000010
+ .quad 0x0200000120000010, 0x0204040120000010
+ .quad 0x0004040000000000, 0x0204000020000000
+ .quad 0x0004040100000010, 0x0204040020000000
+ .quad 0x0000000000000000, 0x0204000120000010
+ .quad 0x0000000100000010, 0x0000040000000000
+ .quad 0x0204000020000000, 0x0004040100000010
+ .quad 0x0000040000000000, 0x0004000100000010
+ .quad 0x0200040120000010, 0x0000000000000000
+ .quad 0x0204040020000000, 0x0200000020000000
+ .quad 0x0004000100000010, 0x0200040120000010
+.L_s7:
+ .quad 0x0002000000200000, 0x2002000004200002
+ .quad 0x2000000004000802, 0x0000000000000000
+ .quad 0x0000000000000800, 0x2000000004000802
+ .quad 0x2002000000200802, 0x0002000004200800
+ .quad 0x2002000004200802, 0x0002000000200000
+ .quad 0x0000000000000000, 0x2000000004000002
+ .quad 0x2000000000000002, 0x0000000004000000
+ .quad 0x2002000004200002, 0x2000000000000802
+ .quad 0x0000000004000800, 0x2002000000200802
+ .quad 0x2002000000200002, 0x0000000004000800
+ .quad 0x2000000004000002, 0x0002000004200000
+ .quad 0x0002000004200800, 0x2002000000200002
+ .quad 0x0002000004200000, 0x0000000000000800
+ .quad 0x2000000000000802, 0x2002000004200802
+ .quad 0x0002000000200800, 0x2000000000000002
+ .quad 0x0000000004000000, 0x0002000000200800
+ .quad 0x0000000004000000, 0x0002000000200800
+ .quad 0x0002000000200000, 0x2000000004000802
+ .quad 0x2000000004000802, 0x2002000004200002
+ .quad 0x2002000004200002, 0x2000000000000002
+ .quad 0x2002000000200002, 0x0000000004000000
+ .quad 0x0000000004000800, 0x0002000000200000
+ .quad 0x0002000004200800, 0x2000000000000802
+ .quad 0x2002000000200802, 0x0002000004200800
+ .quad 0x2000000000000802, 0x2000000004000002
+ .quad 0x2002000004200802, 0x0002000004200000
+ .quad 0x0002000000200800, 0x0000000000000000
+ .quad 0x2000000000000002, 0x2002000004200802
+ .quad 0x0000000000000000, 0x2002000000200802
+ .quad 0x0002000004200000, 0x0000000000000800
+ .quad 0x2000000004000002, 0x0000000004000800
+ .quad 0x0000000000000800, 0x2002000000200002
+.L_s8:
+ .quad 0x0100010410001000, 0x0000010000001000
+ .quad 0x0000000000040000, 0x0100010410041000
+ .quad 0x0100000010000000, 0x0100010410001000
+ .quad 0x0000000400000000, 0x0100000010000000
+ .quad 0x0000000400040000, 0x0100000010040000
+ .quad 0x0100010410041000, 0x0000010000041000
+ .quad 0x0100010010041000, 0x0000010400041000
+ .quad 0x0000010000001000, 0x0000000400000000
+ .quad 0x0100000010040000, 0x0100000410000000
+ .quad 0x0100010010001000, 0x0000010400001000
+ .quad 0x0000010000041000, 0x0000000400040000
+ .quad 0x0100000410040000, 0x0100010010041000
+ .quad 0x0000010400001000, 0x0000000000000000
+ .quad 0x0000000000000000, 0x0100000410040000
+ .quad 0x0100000410000000, 0x0100010010001000
+ .quad 0x0000010400041000, 0x0000000000040000
+ .quad 0x0000010400041000, 0x0000000000040000
+ .quad 0x0100010010041000, 0x0000010000001000
+ .quad 0x0000000400000000, 0x0100000410040000
+ .quad 0x0000010000001000, 0x0000010400041000
+ .quad 0x0100010010001000, 0x0000000400000000
+ .quad 0x0100000410000000, 0x0100000010040000
+ .quad 0x0100000410040000, 0x0100000010000000
+ .quad 0x0000000000040000, 0x0100010410001000
+ .quad 0x0000000000000000, 0x0100010410041000
+ .quad 0x0000000400040000, 0x0100000410000000
+ .quad 0x0100000010040000, 0x0100010010001000
+ .quad 0x0100010410001000, 0x0000000000000000
+ .quad 0x0100010410041000, 0x0000010000041000
+ .quad 0x0000010000041000, 0x0000010400001000
+ .quad 0x0000010400001000, 0x0000000400040000
+ .quad 0x0100000010000000, 0x0100010010041000
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/des.c b/comm/third_party/libgcrypt/cipher/des.c
new file mode 100644
index 0000000000..1580ea4ec5
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/des.c
@@ -0,0 +1,1507 @@
+/* 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 <mroth@nessie.de>, 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 <config.h>
+#include <stdio.h>
+#include <string.h> /* 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<<offset;
+
+
+/*
+ * This performs the 'initial permutation' of the data to be encrypted
+ * or decrypted. Additionally the resulting two words are rotated one bit
+ * to the left.
+ */
+#define INITIAL_PERMUTATION(left, temp, right) \
+ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
+ DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
+ DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
+ DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
+ right = (right << 1) | (right >> 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; i<sizeof(testdata)/sizeof(*testdata); ++i)
+ {
+ tripledes_set3keys (des3, testdata[i].key,
+ testdata[i].key + 8, testdata[i].key + 16);
+
+ tripledes_ecb_encrypt (des3, testdata[i].plain, result);
+ if (memcmp (testdata[i].cipher, result, 8))
+ return "Triple-DES SSLeay test failed on encryption.";
+
+ tripledes_ecb_decrypt (des3, testdata[i].cipher, result);
+ if (memcmp (testdata[i].plain, result, 8))
+ return "Triple-DES SSLeay test failed on decryption.";;
+ }
+ }
+
+ /*
+ * Check the weak key detection. We simply assume that the table
+ * with weak keys is ok and check every key in the table if it is
+ * detected... (This test is a little bit stupid).
+ */
+ {
+ int i;
+ unsigned char *p;
+ gcry_md_hd_t h;
+
+ if (_gcry_md_open (&h, GCRY_MD_SHA1, 0))
+ return "SHA1 not available";
+
+ for (i = 0; i < 64; ++i)
+ _gcry_md_write (h, weak_keys[i], 8);
+ p = _gcry_md_read (h, GCRY_MD_SHA1);
+ i = memcmp (p, weak_keys_chksum, 20);
+ _gcry_md_close (h);
+ if (i)
+ return "weak key table defect";
+
+ for (i = 0; i < 64; ++i)
+ if (!is_weak_key(weak_keys[i]))
+ return "DES weak key detection failed";
+ }
+
+ if ( (r = selftest_cbc ()) )
+ return r;
+
+ if ( (r = selftest_cfb ()) )
+ return r;
+
+ if ( (r = selftest_ctr ()) )
+ return r;
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_tripledes_setkey ( void *context, const byte *key, unsigned keylen,
+ cipher_bulk_ops_t *bulk_ops )
+{
+ struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+
+ if( keylen != 24 )
+ return GPG_ERR_INV_KEYLEN;
+
+ /* Setup bulk encryption routines. */
+ memset (bulk_ops, 0, sizeof(*bulk_ops));
+ bulk_ops->cbc_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 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, 1},
+ "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/comm/third_party/libgcrypt/cipher/dsa-common.c b/comm/third_party/libgcrypt/cipher/dsa-common.c
new file mode 100644
index 0000000000..fe49248dd6
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/dsa-common.c
@@ -0,0 +1,418 @@
+/* dsa-common.c - Common code for DSA
+ * Copyright (C) 1998, 1999 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+/*
+ * Modify K, so that computation time difference can be small,
+ * by making K large enough.
+ *
+ * Originally, (EC)DSA computation requires k where 0 < k < q. Here,
+ * we add q (the order), to keep k in a range: q < k < 2*q (or,
+ * addming more q, to keep k in a range: 2*q < k < 3*q), so that
+ * timing difference of the EC multiply (or exponentiation) operation
+ * can be small. The result of (EC)DSA computation is same.
+ */
+void
+_gcry_dsa_modify_k (gcry_mpi_t k, gcry_mpi_t q, int qbits)
+{
+ gcry_mpi_t k1 = mpi_new (qbits+2);
+
+ mpi_resize (k, (qbits+2+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB);
+ k->nlimbs = k->alloced;
+ mpi_add (k, k, q);
+ mpi_add (k1, k, q);
+ mpi_set_cond (k, k1, !mpi_test_bit (k, qbits));
+
+ mpi_free (k1);
+}
+
+/*
+ * Generate a random secret exponent K less than Q.
+ * Note that ECDSA uses this code also to generate D.
+ */
+gcry_mpi_t
+_gcry_dsa_gen_k (gcry_mpi_t q, int security_level)
+{
+ gcry_mpi_t k = mpi_alloc_secure (mpi_get_nlimbs (q));
+ unsigned int nbits = mpi_get_nbits (q);
+ unsigned int nbytes = (nbits+7)/8;
+ char *rndbuf = NULL;
+
+ /* To learn why we don't use mpi_mod to get the requested bit size,
+ read the paper: "The Insecurity of the Digital Signature
+ Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
+ Journal of Cryptology, New York. Vol 15, nr 3 (2003) */
+
+ if (DBG_CIPHER)
+ log_debug ("choosing a random k of %u bits at seclevel %d\n",
+ nbits, security_level);
+ for (;;)
+ {
+ if ( !rndbuf || nbits < 32 )
+ {
+ xfree (rndbuf);
+ rndbuf = _gcry_random_bytes_secure (nbytes, security_level);
+ }
+ else
+ { /* Change only some of the higher bits. We could improve
+ this by directly requesting more memory at the first call
+ to get_random_bytes() and use these extra bytes here.
+ However the required management code is more complex and
+ thus we better use this simple method. */
+ char *pp = _gcry_random_bytes_secure (4, security_level);
+ memcpy (rndbuf, pp, 4);
+ xfree (pp);
+ }
+ _gcry_mpi_set_buffer (k, rndbuf, nbytes, 0);
+
+ /* Make sure we have the requested number of bits. This code
+ looks a bit funny but it is easy to understand if you
+ consider that mpi_set_highbit clears all higher bits. We
+ don't have a clear_highbit, thus we first set the high bit
+ and then clear it again. */
+ if (mpi_test_bit (k, nbits-1))
+ mpi_set_highbit (k, nbits-1);
+ else
+ {
+ mpi_set_highbit (k, nbits-1);
+ mpi_clear_bit (k, nbits-1);
+ }
+
+ if (!(mpi_cmp (k, q) < 0)) /* check: k < q */
+ {
+ if (DBG_CIPHER)
+ log_debug ("\tk too large - again\n");
+ continue; /* no */
+ }
+ if (!(mpi_cmp_ui (k, 0) > 0)) /* check: k > 0 */
+ {
+ if (DBG_CIPHER)
+ log_debug ("\tk is zero - again\n");
+ continue; /* no */
+ }
+ break; /* okay */
+ }
+ xfree (rndbuf);
+
+ return k;
+}
+
+
+/* Turn VALUE into an octet string and store it in an allocated buffer
+ at R_FRAME. If the resulting octet string is shorter than NBYTES
+ the result will be left padded with zeroes. If VALUE does not fit
+ into NBYTES an error code is returned. */
+static gpg_err_code_t
+int2octets (unsigned char **r_frame, gcry_mpi_t value, size_t nbytes)
+{
+ gpg_err_code_t rc;
+ size_t nframe, noff, n;
+ unsigned char *frame;
+
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
+ if (rc)
+ return rc;
+ if (nframe > nbytes)
+ return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES. */
+
+ noff = (nframe < nbytes)? nbytes - nframe : 0;
+ n = nframe + noff;
+ frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
+ if (!frame)
+ return gpg_err_code_from_syserror ();
+ if (noff)
+ memset (frame, 0, noff);
+ nframe += noff;
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
+ if (rc)
+ {
+ xfree (frame);
+ return rc;
+ }
+
+ *r_frame = frame;
+ return 0;
+}
+
+
+/* Connert the bit string BITS of length NBITS into an octet string
+ with a length of (QBITS+7)/8 bytes. On success store the result at
+ R_FRAME. */
+static gpg_err_code_t
+bits2octets (unsigned char **r_frame,
+ const void *bits, unsigned int nbits,
+ gcry_mpi_t q, unsigned int qbits)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t z1;
+
+ /* z1 = bits2int (b) */
+ rc = _gcry_mpi_scan (&z1, GCRYMPI_FMT_USG, bits, (nbits+7)/8, NULL);
+ if (rc)
+ return rc;
+ if (nbits > qbits)
+ mpi_rshift (z1, z1, nbits - qbits);
+
+ /* z2 - z1 mod q */
+ if (mpi_cmp (z1, q) >= 0)
+ mpi_sub (z1, z1, q);
+
+ /* Convert to an octet string. */
+ rc = int2octets (r_frame, z1, (qbits+7)/8);
+
+ mpi_free (z1);
+ return rc;
+}
+
+
+/*
+ * Generate a deterministic secret exponent K less than DSA_Q. H1 is
+ * the to be signed digest with a length of HLEN bytes. HALGO is the
+ * algorithm used to create the hash. On success the value for K is
+ * stored at R_K.
+ */
+gpg_err_code_t
+_gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k,
+ gcry_mpi_t dsa_q, gcry_mpi_t dsa_x,
+ const unsigned char *h1, unsigned int hlen,
+ int halgo, unsigned int extraloops)
+{
+ gpg_err_code_t rc;
+ unsigned char *V = NULL;
+ unsigned char *K = NULL;
+ unsigned char *x_buf = NULL;
+ unsigned char *h1_buf = NULL;
+ gcry_md_hd_t hd = NULL;
+ unsigned char *t = NULL;
+ gcry_mpi_t k = NULL;
+ unsigned int tbits, qbits;
+ int i;
+
+ qbits = mpi_get_nbits (dsa_q);
+
+ if (!qbits || !h1 || !hlen)
+ return GPG_ERR_EINVAL;
+
+ if (_gcry_md_get_algo_dlen (halgo) != hlen)
+ return GPG_ERR_DIGEST_ALGO;
+
+ /* Step b: V = 0x01 0x01 0x01 ... 0x01 */
+ V = xtrymalloc (hlen);
+ if (!V)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ for (i=0; i < hlen; i++)
+ V[i] = 1;
+
+ /* Step c: K = 0x00 0x00 0x00 ... 0x00 */
+ K = xtrycalloc (1, hlen);
+ if (!K)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ rc = int2octets (&x_buf, dsa_x, (qbits+7)/8);
+ if (rc)
+ goto leave;
+
+ rc = bits2octets (&h1_buf, h1, hlen*8, dsa_q, qbits);
+ if (rc)
+ goto leave;
+
+ /* Create a handle to compute the HMACs. */
+ rc = _gcry_md_open (&hd, halgo, (GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC));
+ if (rc)
+ goto leave;
+
+ /* Step d: K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ _gcry_md_write (hd, "", 1);
+ _gcry_md_write (hd, x_buf, (qbits+7)/8);
+ _gcry_md_write (hd, h1_buf, (qbits+7)/8);
+ memcpy (K, _gcry_md_read (hd, 0), hlen);
+
+ /* Step e: V = HMAC_K(V) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+ /* Step f: K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ _gcry_md_write (hd, "\x01", 1);
+ _gcry_md_write (hd, x_buf, (qbits+7)/8);
+ _gcry_md_write (hd, h1_buf, (qbits+7)/8);
+ memcpy (K, _gcry_md_read (hd, 0), hlen);
+
+ /* Step g: V = HMAC_K(V) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+ /* Step h. */
+ t = xtrymalloc_secure ((qbits+7)/8+hlen);
+ if (!t)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ again:
+ for (tbits = 0; tbits < qbits;)
+ {
+ /* V = HMAC_K(V) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+ /* T = T || V */
+ memcpy (t+(tbits+7)/8, V, hlen);
+ tbits += 8*hlen;
+ }
+
+ /* k = bits2int (T) */
+ mpi_free (k);
+ k = NULL;
+ rc = _gcry_mpi_scan (&k, GCRYMPI_FMT_USG, t, (tbits+7)/8, NULL);
+ if (rc)
+ goto leave;
+ if (tbits > qbits)
+ mpi_rshift (k, k, tbits - qbits);
+
+ /* Check: k < q and k > 1 */
+ if (!(mpi_cmp (k, dsa_q) < 0 && mpi_cmp_ui (k, 0) > 0))
+ {
+ /* K = HMAC_K(V || 0x00) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ _gcry_md_write (hd, "", 1);
+ memcpy (K, _gcry_md_read (hd, 0), hlen);
+
+ /* V = HMAC_K(V) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+ goto again;
+ }
+
+ /* The caller may have requested that we introduce some extra loops.
+ This is for example useful if the caller wants another value for
+ K because the last returned one yielded an R of 0. Because this
+ is very unlikely we implement it in a straightforward way. */
+ if (extraloops)
+ {
+ extraloops--;
+
+ /* K = HMAC_K(V || 0x00) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ _gcry_md_write (hd, "", 1);
+ memcpy (K, _gcry_md_read (hd, 0), hlen);
+
+ /* V = HMAC_K(V) */
+ rc = _gcry_md_setkey (hd, K, hlen);
+ if (rc)
+ goto leave;
+ _gcry_md_write (hd, V, hlen);
+ memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+ goto again;
+ }
+
+ /* log_mpidump (" k", k); */
+
+ leave:
+ xfree (t);
+ _gcry_md_close (hd);
+ xfree (h1_buf);
+ xfree (x_buf);
+ xfree (K);
+ xfree (V);
+
+ if (rc)
+ mpi_free (k);
+ else
+ *r_k = k;
+ return rc;
+}
+
+/*
+ * Truncate opaque hash value to qbits for DSA.
+ * Non-opaque input is not truncated, in hope that user
+ * knows what is passed. It is not possible to correctly
+ * trucate non-opaque inputs.
+ */
+gpg_err_code_t
+_gcry_dsa_normalize_hash (gcry_mpi_t input,
+ gcry_mpi_t *out,
+ unsigned int qbits)
+{
+ gpg_err_code_t rc = 0;
+ const void *abuf;
+ unsigned int abits;
+ gcry_mpi_t hash;
+
+ if (mpi_is_opaque (input))
+ {
+ abuf = mpi_get_opaque (input, &abits);
+ rc = _gcry_mpi_scan (&hash, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
+ if (rc)
+ return rc;
+ if (abits > qbits)
+ mpi_rshift (hash, hash, abits - qbits);
+ }
+ else
+ hash = input;
+
+ *out = hash;
+
+ return rc;
+}
diff --git a/comm/third_party/libgcrypt/cipher/dsa.c b/comm/third_party/libgcrypt/cipher/dsa.c
new file mode 100644
index 0000000000..d793b9aaf2
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/dsa.c
@@ -0,0 +1,1394 @@
+/* dsa.c - DSA signature algorithm
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ * 2006, 2008 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t q; /* group order */
+ gcry_mpi_t g; /* group generator */
+ gcry_mpi_t y; /* g^x mod p */
+} DSA_public_key;
+
+
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t q; /* group order */
+ gcry_mpi_t g; /* group generator */
+ gcry_mpi_t y; /* g^x mod p */
+ gcry_mpi_t x; /* secret exponent */
+} DSA_secret_key;
+
+
+/* A structure used to hold domain parameters. */
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t q; /* group order */
+ gcry_mpi_t g; /* group generator */
+} dsa_domain_t;
+
+
+static const char *dsa_names[] =
+ {
+ "dsa",
+ "openpgp-dsa",
+ NULL,
+ };
+
+
+/* A sample 1024 bit DSA key used for the selftests. Not anymore
+ * used, kept only for reference. */
+#if 0
+static const char sample_secret_key_1024[] =
+"(private-key"
+" (dsa"
+" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
+" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
+" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
+" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
+" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
+/* A sample 1024 bit DSA key used for the selftests (public only). */
+static const char sample_public_key_1024[] =
+"(public-key"
+" (dsa"
+" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
+" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
+" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
+" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))";
+#endif /*0*/
+
+/* 2048 DSA key from RFC 6979 A.2.2 */
+static const char sample_public_key_2048[] =
+"(public-key"
+" (dsa"
+" (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
+" (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
+" (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
+" (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)))";
+
+static const char sample_secret_key_2048[] =
+"(private-key"
+" (dsa"
+" (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
+" (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
+" (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
+" (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)"
+" (x #69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC#)))";
+
+
+
+static int test_keys (DSA_secret_key *sk, unsigned int qbits);
+static int check_secret_key (DSA_secret_key *sk);
+static gpg_err_code_t generate (DSA_secret_key *sk,
+ unsigned int nbits,
+ unsigned int qbits,
+ int transient_key,
+ dsa_domain_t *domain,
+ gcry_mpi_t **ret_factors);
+static gpg_err_code_t sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+ DSA_secret_key *skey, int flags, int hashalgo);
+static gpg_err_code_t verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+ DSA_public_key *pkey);
+static unsigned int dsa_get_nbits (gcry_sexp_t parms);
+
+
+static void (*progress_cb) (void *,const char *, int, int, int );
+static void *progress_cb_data;
+
+
+void
+_gcry_register_pk_dsa_progress (void (*cb) (void *, const char *,
+ int, int, int),
+ void *cb_data)
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+
+static void
+progress (int c)
+{
+ if (progress_cb)
+ progress_cb (progress_cb_data, "pk_dsa", c, 0, 0);
+}
+
+
+/* Check that a freshly generated key actually works. Returns 0 on success. */
+static int
+test_keys (DSA_secret_key *sk, unsigned int qbits)
+{
+ int result = -1; /* Default to failure. */
+ DSA_public_key pk;
+ gcry_mpi_t data = mpi_new (qbits);
+ gcry_mpi_t sig_a = mpi_new (qbits);
+ gcry_mpi_t sig_b = mpi_new (qbits);
+
+ /* Put the relevant parameters into a public key structure. */
+ pk.p = sk->p;
+ pk.q = sk->q;
+ pk.g = sk->g;
+ pk.y = sk->y;
+
+ /* Create a random plaintext. */
+ _gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
+
+ /* Sign DATA using the secret key. */
+ sign (sig_a, sig_b, data, sk, 0, 0);
+
+ /* Verify the signature using the public key. */
+ if ( verify (sig_a, sig_b, data, &pk) )
+ goto leave; /* Signature does not match. */
+
+ /* Modify the data and check that the signing fails. */
+ mpi_add_ui (data, data, 1);
+ if ( !verify (sig_a, sig_b, data, &pk) )
+ goto leave; /* Signature matches but should not. */
+
+ result = 0; /* The test succeeded. */
+
+ leave:
+ _gcry_mpi_release (sig_b);
+ _gcry_mpi_release (sig_a);
+ _gcry_mpi_release (data);
+ return result;
+}
+
+
+
+/*
+ Generate a DSA key pair with a key of size NBITS. If transient_key
+ is true the key is generated using the standard RNG and not the
+ very secure one.
+
+ Returns: 2 structures filled with all needed values
+ and an array with the n-1 factors of (p-1)
+ */
+static gpg_err_code_t
+generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
+ int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t p; /* the prime */
+ gcry_mpi_t q; /* the 160 bit prime factor */
+ gcry_mpi_t g; /* the generator */
+ gcry_mpi_t y; /* g^x mod p */
+ gcry_mpi_t x; /* the secret exponent */
+ gcry_mpi_t h, e; /* helper */
+ unsigned char *rndbuf;
+ gcry_random_level_t random_level;
+
+ if (qbits)
+ ; /* Caller supplied qbits. Use this value. */
+ else if ( nbits >= 512 && nbits <= 1024 )
+ qbits = 160;
+ else if ( nbits == 2048 )
+ qbits = 224;
+ else if ( nbits == 3072 )
+ qbits = 256;
+ else if ( nbits == 7680 )
+ qbits = 384;
+ else if ( nbits == 15360 )
+ qbits = 512;
+ else
+ return GPG_ERR_INV_VALUE;
+
+ if (qbits < 160 || qbits > 512 || (qbits%8) )
+ return GPG_ERR_INV_VALUE;
+ if (nbits < 2*qbits || nbits > 15360)
+ return GPG_ERR_INV_VALUE;
+
+ if (fips_mode ())
+ {
+ if (nbits < 1024)
+ return GPG_ERR_INV_VALUE;
+ if (transient_key)
+ return GPG_ERR_INV_VALUE;
+ }
+
+ if (domain->p && domain->q && domain->g)
+ {
+ /* Domain parameters are given; use them. */
+ p = mpi_copy (domain->p);
+ q = mpi_copy (domain->q);
+ g = mpi_copy (domain->g);
+ gcry_assert (mpi_get_nbits (p) == nbits);
+ gcry_assert (mpi_get_nbits (q) == qbits);
+ h = mpi_alloc (0);
+ e = NULL;
+ }
+ else
+ {
+ /* Generate new domain parameters. */
+ rc = _gcry_generate_elg_prime (1, nbits, qbits, NULL, &p, ret_factors);
+ if (rc)
+ return rc;
+
+ /* Get q out of factors. */
+ q = mpi_copy ((*ret_factors)[0]);
+ gcry_assert (mpi_get_nbits (q) == qbits);
+
+ /* Find a generator g (h and e are helpers).
+ e = (p-1)/q */
+ e = mpi_alloc (mpi_get_nlimbs (p));
+ mpi_sub_ui (e, p, 1);
+ mpi_fdiv_q (e, e, q);
+ g = mpi_alloc (mpi_get_nlimbs (p));
+ h = mpi_alloc_set_ui (1); /* (We start with 2.) */
+ do
+ {
+ mpi_add_ui (h, h, 1);
+ /* g = h^e mod p */
+ mpi_powm (g, h, e, p);
+ }
+ while (!mpi_cmp_ui (g, 1)); /* Continue until g != 1. */
+ }
+
+ /* Select a random number X with the property:
+ * 0 < x < q-1
+ *
+ * FIXME: Why do we use the requirement x < q-1 ? It should be
+ * sufficient to test for x < q. FIPS-186-3 check x < q-1 but it
+ * does not check for 0 < x because it makes sure that Q is unsigned
+ * and finally adds one to the result so that 0 will never be
+ * returned. We should replace the code below with _gcry_dsa_gen_k.
+ *
+ * This must be a very good random number because this is the secret
+ * part. The random quality depends on the transient_key flag. */
+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+ if (DBG_CIPHER)
+ log_debug("choosing a random x%s\n", transient_key? " (transient-key)":"");
+ gcry_assert( qbits >= 160 );
+ x = mpi_alloc_secure( mpi_get_nlimbs(q) );
+ mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
+ rndbuf = NULL;
+ do
+ {
+ if( DBG_CIPHER )
+ progress('.');
+ if( !rndbuf )
+ rndbuf = _gcry_random_bytes_secure ((qbits+7)/8, random_level);
+ else
+ { /* Change only some of the higher bits (= 2 bytes)*/
+ char *r = _gcry_random_bytes_secure (2, random_level);
+ memcpy(rndbuf, r, 2 );
+ xfree(r);
+ }
+
+ _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
+ mpi_clear_highbit( x, qbits+1 );
+ }
+ while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
+ xfree(rndbuf);
+ mpi_free( e );
+ mpi_free( h );
+
+ /* y = g^x mod p */
+ y = mpi_alloc( mpi_get_nlimbs(p) );
+ mpi_powm (y, g, x, p);
+
+ if( DBG_CIPHER )
+ {
+ progress('\n');
+ log_mpidump("dsa p", p );
+ log_mpidump("dsa q", q );
+ log_mpidump("dsa g", g );
+ log_mpidump("dsa y", y );
+ log_mpidump("dsa x", x );
+ }
+
+ /* Copy the stuff to the key structures. */
+ sk->p = p;
+ sk->q = q;
+ sk->g = g;
+ sk->y = y;
+ sk->x = x;
+
+ /* Now we can test our keys (this should never fail!). */
+ if ( test_keys (sk, qbits) )
+ {
+ _gcry_mpi_release (sk->p); sk->p = NULL;
+ _gcry_mpi_release (sk->q); sk->q = NULL;
+ _gcry_mpi_release (sk->g); sk->g = NULL;
+ _gcry_mpi_release (sk->y); sk->y = NULL;
+ _gcry_mpi_release (sk->x); sk->x = NULL;
+ fips_signal_error ("self-test after key generation failed");
+ return GPG_ERR_SELFTEST_FAILED;
+ }
+ return 0;
+}
+
+
+/* Generate a DSA key pair with a key of size NBITS using the
+ algorithm given in FIPS-186-3. If USE_FIPS186_2 is true,
+ FIPS-186-2 is used and thus the length is restricted to 1024/160.
+ If DERIVEPARMS is not NULL it may contain a seed value. If domain
+ parameters are specified in DOMAIN, DERIVEPARMS may not be given
+ and NBITS and QBITS must match the specified domain parameters. */
+static gpg_err_code_t
+generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
+ gcry_sexp_t deriveparms, int use_fips186_2,
+ dsa_domain_t *domain,
+ int *r_counter, void **r_seed, size_t *r_seedlen,
+ gcry_mpi_t *r_h)
+{
+ gpg_err_code_t ec;
+ struct {
+ gcry_sexp_t sexp;
+ const void *seed;
+ size_t seedlen;
+ } initial_seed = { NULL, NULL, 0 };
+ gcry_mpi_t prime_q = NULL;
+ gcry_mpi_t prime_p = NULL;
+ gcry_mpi_t value_g = NULL; /* The generator. */
+ gcry_mpi_t value_y = NULL; /* g^x mod p */
+ gcry_mpi_t value_x = NULL; /* The secret exponent. */
+ gcry_mpi_t value_h = NULL; /* Helper. */
+ gcry_mpi_t value_e = NULL; /* Helper. */
+ gcry_mpi_t value_c = NULL; /* helper for x */
+ gcry_mpi_t value_qm2 = NULL; /* q - 2 */
+
+ /* Preset return values. */
+ *r_counter = 0;
+ *r_seed = NULL;
+ *r_seedlen = 0;
+ *r_h = NULL;
+
+ /* Derive QBITS from NBITS if requested */
+ if (!qbits)
+ {
+ if (nbits == 1024)
+ qbits = 160;
+ else if (nbits == 2048)
+ qbits = 224;
+ else if (nbits == 3072)
+ qbits = 256;
+ }
+
+ /* Check that QBITS and NBITS match the standard. Note that FIPS
+ 186-3 uses N for QBITS and L for NBITS. */
+ if (nbits == 1024 && qbits == 160 && use_fips186_2)
+ ; /* Allowed in FIPS 186-2 mode. */
+ else if (nbits == 2048 && qbits == 224)
+ ;
+ else if (nbits == 2048 && qbits == 256)
+ ;
+ else if (nbits == 3072 && qbits == 256)
+ ;
+ else
+ return GPG_ERR_INV_VALUE;
+
+ if (domain->p && domain->q && domain->g)
+ {
+ /* Domain parameters are given; use them. */
+ prime_p = mpi_copy (domain->p);
+ prime_q = mpi_copy (domain->q);
+ value_g = mpi_copy (domain->g);
+ gcry_assert (mpi_get_nbits (prime_p) == nbits);
+ gcry_assert (mpi_get_nbits (prime_q) == qbits);
+ gcry_assert (!deriveparms);
+ ec = 0;
+ }
+ else
+ {
+ /* Generate new domain parameters. */
+
+ /* Get an initial seed value. */
+ if (deriveparms)
+ {
+ initial_seed.sexp = sexp_find_token (deriveparms, "seed", 0);
+ if (initial_seed.sexp)
+ initial_seed.seed = sexp_nth_data (initial_seed.sexp, 1,
+ &initial_seed.seedlen);
+ }
+
+ if (use_fips186_2)
+ ec = _gcry_generate_fips186_2_prime (nbits, qbits,
+ initial_seed.seed,
+ initial_seed.seedlen,
+ &prime_q, &prime_p,
+ r_counter,
+ r_seed, r_seedlen);
+ else
+ ec = _gcry_generate_fips186_3_prime (nbits, qbits,
+ initial_seed.seed,
+ initial_seed.seedlen,
+ &prime_q, &prime_p,
+ r_counter,
+ r_seed, r_seedlen, NULL);
+ sexp_release (initial_seed.sexp);
+ if (ec)
+ goto leave;
+
+ /* Find a generator g (h and e are helpers).
+ * e = (p-1)/q
+ */
+ value_e = mpi_alloc_like (prime_p);
+ mpi_sub_ui (value_e, prime_p, 1);
+ mpi_fdiv_q (value_e, value_e, prime_q );
+ value_g = mpi_alloc_like (prime_p);
+ value_h = mpi_alloc_set_ui (1);
+ do
+ {
+ mpi_add_ui (value_h, value_h, 1);
+ /* g = h^e mod p */
+ mpi_powm (value_g, value_h, value_e, prime_p);
+ }
+ while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */
+ }
+
+ value_c = mpi_snew (qbits);
+ value_x = mpi_snew (qbits);
+ value_qm2 = mpi_snew (qbits);
+ mpi_sub_ui (value_qm2, prime_q, 2);
+
+ /* FIPS 186-4 B.1.2 steps 4-6 */
+ do
+ {
+ if( DBG_CIPHER )
+ progress('.');
+ _gcry_mpi_randomize (value_c, qbits, GCRY_VERY_STRONG_RANDOM);
+ mpi_clear_highbit (value_c, qbits+1);
+ }
+ while (!(mpi_cmp_ui (value_c, 0) > 0 && mpi_cmp (value_c, value_qm2) < 0));
+ /* while (mpi_cmp (value_c, value_qm2) > 0); */
+
+ /* x = c + 1 */
+ mpi_add_ui(value_x, value_c, 1);
+
+ /* y = g^x mod p */
+ value_y = mpi_alloc_like (prime_p);
+ mpi_powm (value_y, value_g, value_x, prime_p);
+
+ if (DBG_CIPHER)
+ {
+ progress('\n');
+ log_mpidump("dsa p", prime_p );
+ log_mpidump("dsa q", prime_q );
+ log_mpidump("dsa g", value_g );
+ log_mpidump("dsa y", value_y );
+ log_mpidump("dsa x", value_x );
+ log_mpidump("dsa h", value_h );
+ }
+
+ /* Copy the stuff to the key structures. */
+ sk->p = prime_p; prime_p = NULL;
+ sk->q = prime_q; prime_q = NULL;
+ sk->g = value_g; value_g = NULL;
+ sk->y = value_y; value_y = NULL;
+ sk->x = value_x; value_x = NULL;
+ *r_h = value_h; value_h = NULL;
+
+ leave:
+ _gcry_mpi_release (prime_p);
+ _gcry_mpi_release (prime_q);
+ _gcry_mpi_release (value_g);
+ _gcry_mpi_release (value_y);
+ _gcry_mpi_release (value_x);
+ _gcry_mpi_release (value_h);
+ _gcry_mpi_release (value_e);
+ _gcry_mpi_release (value_c);
+ _gcry_mpi_release (value_qm2);
+
+ /* As a last step test this keys (this should never fail of course). */
+ if (!ec && test_keys (sk, qbits) )
+ {
+ _gcry_mpi_release (sk->p); sk->p = NULL;
+ _gcry_mpi_release (sk->q); sk->q = NULL;
+ _gcry_mpi_release (sk->g); sk->g = NULL;
+ _gcry_mpi_release (sk->y); sk->y = NULL;
+ _gcry_mpi_release (sk->x); sk->x = NULL;
+ fips_signal_error ("self-test after key generation failed");
+ ec = GPG_ERR_SELFTEST_FAILED;
+ }
+
+ if (ec)
+ {
+ *r_counter = 0;
+ xfree (*r_seed); *r_seed = NULL;
+ *r_seedlen = 0;
+ _gcry_mpi_release (*r_h); *r_h = NULL;
+ }
+
+ return ec;
+}
+
+
+
+/*
+ Test whether the secret key is valid.
+ Returns: if this is a valid key.
+ */
+static int
+check_secret_key( DSA_secret_key *sk )
+{
+ int rc;
+ gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
+
+ mpi_powm( y, sk->g, sk->x, sk->p );
+ rc = !mpi_cmp( y, sk->y );
+ mpi_free( y );
+ return rc;
+}
+
+
+
+/*
+ Make a DSA signature from INPUT and put it into r and s.
+
+ INPUT may either be a plain MPI or an opaque MPI which is then
+ internally converted to a plain MPI. FLAGS and HASHALGO may both
+ be 0 for standard operation mode.
+
+ The return value is 0 on success or an error code. Note that for
+ backward compatibility the function will not return any error if
+ FLAGS and HASHALGO are both 0 and INPUT is a plain MPI.
+ */
+static gpg_err_code_t
+sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey,
+ int flags, int hashalgo)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t hash;
+ gcry_mpi_t k;
+ gcry_mpi_t kinv;
+ gcry_mpi_t tmp;
+ const void *abuf;
+ unsigned int abits, qbits;
+ int extraloops = 0;
+
+ qbits = mpi_get_nbits (skey->q);
+
+ /* Convert the INPUT into an MPI. */
+ rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+ if (rc)
+ return rc;
+
+ again:
+ /* Create the K value. */
+ if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
+ {
+ /* Use Pornin's method for deterministic DSA. If this flag is
+ set, it is expected that HASH is an opaque MPI with the to be
+ signed hash. That hash is also used as h1 from 3.2.a. */
+ if (!mpi_is_opaque (input))
+ {
+ rc = GPG_ERR_CONFLICT;
+ goto leave;
+ }
+
+ abuf = mpi_get_opaque (input, &abits);
+ rc = _gcry_dsa_gen_rfc6979_k (&k, skey->q, skey->x,
+ abuf, (abits+7)/8, hashalgo, extraloops);
+ if (rc)
+ goto leave;
+ }
+ else
+ {
+ /* Select a random k with 0 < k < q */
+ k = _gcry_dsa_gen_k (skey->q, GCRY_STRONG_RANDOM);
+ }
+
+ /* kinv = k^(-1) mod q */
+ kinv = mpi_alloc( mpi_get_nlimbs(k) );
+ mpi_invm(kinv, k, skey->q );
+
+ _gcry_dsa_modify_k (k, skey->q, qbits);
+
+ /* r = (a^k mod p) mod q */
+ mpi_powm( r, skey->g, k, skey->p );
+ mpi_fdiv_r( r, r, skey->q );
+
+ /* s = (kinv * ( hash + x * r)) mod q */
+ tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
+ mpi_mul( tmp, skey->x, r );
+ mpi_add( tmp, tmp, hash );
+ mpi_mulm( s , kinv, tmp, skey->q );
+
+ mpi_free(k);
+ mpi_free(kinv);
+ mpi_free(tmp);
+
+ if (!mpi_cmp_ui (r, 0))
+ {
+ /* This is a highly unlikely code path. */
+ extraloops++;
+ goto again;
+ }
+
+ rc = 0;
+
+ leave:
+ if (hash != input)
+ mpi_free (hash);
+
+ return rc;
+}
+
+
+/*
+ Returns true if the signature composed from R and S is valid.
+ */
+static gpg_err_code_t
+verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_public_key *pkey )
+{
+ gpg_err_code_t rc = 0;
+ gcry_mpi_t w, u1, u2, v;
+ gcry_mpi_t base[3];
+ gcry_mpi_t ex[3];
+ gcry_mpi_t hash;
+ unsigned int nbits;
+
+ if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */
+ if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */
+
+ nbits = mpi_get_nbits (pkey->q);
+ rc = _gcry_dsa_normalize_hash (input, &hash, nbits);
+ if (rc)
+ return rc;
+
+ w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+ u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+ u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+ v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
+
+ /* w = s^(-1) mod q */
+ mpi_invm( w, s, pkey->q );
+
+ /* u1 = (hash * w) mod q */
+ mpi_mulm( u1, hash, w, pkey->q );
+
+ /* u2 = r * w mod q */
+ mpi_mulm( u2, r, w, pkey->q );
+
+ /* v = g^u1 * y^u2 mod p mod q */
+ base[0] = pkey->g; ex[0] = u1;
+ base[1] = pkey->y; ex[1] = u2;
+ base[2] = NULL; ex[2] = NULL;
+ mpi_mulpowm( v, base, ex, pkey->p );
+ mpi_fdiv_r( v, v, pkey->q );
+
+ if (mpi_cmp( v, r ))
+ {
+ if (DBG_CIPHER)
+ {
+ log_mpidump (" i", input);
+ log_mpidump (" h", hash);
+ log_mpidump (" v", v);
+ log_mpidump (" r", r);
+ log_mpidump (" s", s);
+ }
+ rc = GPG_ERR_BAD_SIGNATURE;
+ }
+
+ mpi_free(w);
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(v);
+ if (hash != input)
+ mpi_free (hash);
+
+ return rc;
+}
+
+
+/*********************************************
+ ************** interface ******************
+ *********************************************/
+
+static gcry_err_code_t
+dsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+{
+ gpg_err_code_t rc;
+ unsigned int nbits;
+ gcry_sexp_t domainsexp;
+ DSA_secret_key sk;
+ gcry_sexp_t l1;
+ unsigned int qbits = 0;
+ gcry_sexp_t deriveparms = NULL;
+ gcry_sexp_t seedinfo = NULL;
+ gcry_sexp_t misc_info = NULL;
+ int flags = 0;
+ dsa_domain_t domain;
+ gcry_mpi_t *factors = NULL;
+
+ memset (&sk, 0, sizeof sk);
+ memset (&domain, 0, sizeof domain);
+
+ rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+ if (rc)
+ return rc;
+
+ /* Parse the optional flags list. */
+ l1 = sexp_find_token (genparms, "flags", 0);
+ if (l1)
+ {
+ rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+ sexp_release (l1);
+ if (rc)
+ return rc;\
+ }
+
+ /* Parse the optional qbits element. */
+ l1 = sexp_find_token (genparms, "qbits", 0);
+ if (l1)
+ {
+ char buf[50];
+ const char *s;
+ size_t n;
+
+ s = sexp_nth_data (l1, 1, &n);
+ if (!s || n >= DIM (buf) - 1 )
+ {
+ sexp_release (l1);
+ return GPG_ERR_INV_OBJ; /* No value or value too large. */
+ }
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ qbits = (unsigned int)strtoul (buf, NULL, 0);
+ sexp_release (l1);
+ }
+
+ /* Parse the optional transient-key flag. */
+ if (!(flags & PUBKEY_FLAG_TRANSIENT_KEY))
+ {
+ l1 = sexp_find_token (genparms, "transient-key", 0);
+ if (l1)
+ {
+ flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+ sexp_release (l1);
+ }
+ }
+
+ /* Get the optional derive parameters. */
+ deriveparms = sexp_find_token (genparms, "derive-parms", 0);
+
+ /* Parse the optional "use-fips186" flags. */
+ if (!(flags & PUBKEY_FLAG_USE_FIPS186))
+ {
+ l1 = sexp_find_token (genparms, "use-fips186", 0);
+ if (l1)
+ {
+ flags |= PUBKEY_FLAG_USE_FIPS186;
+ sexp_release (l1);
+ }
+ }
+ if (!(flags & PUBKEY_FLAG_USE_FIPS186_2))
+ {
+ l1 = sexp_find_token (genparms, "use-fips186-2", 0);
+ if (l1)
+ {
+ flags |= PUBKEY_FLAG_USE_FIPS186_2;
+ sexp_release (l1);
+ }
+ }
+
+ /* Check whether domain parameters are given. */
+ domainsexp = sexp_find_token (genparms, "domain", 0);
+ if (domainsexp)
+ {
+ /* DERIVEPARMS can't be used together with domain parameters.
+ NBITS abnd QBITS may not be specified because there values
+ are derived from the domain parameters. */
+ if (deriveparms || qbits || nbits)
+ {
+ sexp_release (domainsexp);
+ sexp_release (deriveparms);
+ return GPG_ERR_INV_VALUE;
+ }
+
+ /* Put all domain parameters into the domain object. */
+ l1 = sexp_find_token (domainsexp, "p", 0);
+ domain.p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ l1 = sexp_find_token (domainsexp, "q", 0);
+ domain.q = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ l1 = sexp_find_token (domainsexp, "g", 0);
+ domain.g = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ sexp_release (domainsexp);
+
+ /* Check that all domain parameters are available. */
+ if (!domain.p || !domain.q || !domain.g)
+ {
+ _gcry_mpi_release (domain.p);
+ _gcry_mpi_release (domain.q);
+ _gcry_mpi_release (domain.g);
+ sexp_release (deriveparms);
+ return GPG_ERR_MISSING_VALUE;
+ }
+
+ /* Get NBITS and QBITS from the domain parameters. */
+ nbits = mpi_get_nbits (domain.p);
+ qbits = mpi_get_nbits (domain.q);
+ }
+
+ if (deriveparms
+ || (flags & PUBKEY_FLAG_USE_FIPS186)
+ || (flags & PUBKEY_FLAG_USE_FIPS186_2)
+ || fips_mode ())
+ {
+ int counter;
+ void *seed;
+ size_t seedlen;
+ gcry_mpi_t h_value;
+
+ rc = generate_fips186 (&sk, nbits, qbits, deriveparms,
+ !!(flags & PUBKEY_FLAG_USE_FIPS186_2),
+ &domain,
+ &counter, &seed, &seedlen, &h_value);
+ if (!rc && h_value)
+ {
+ /* Format the seed-values unless domain parameters are used
+ for which a H_VALUE of NULL is an indication. */
+ rc = sexp_build (&seedinfo, NULL,
+ "(seed-values(counter %d)(seed %b)(h %m))",
+ counter, (int)seedlen, seed, h_value);
+ xfree (seed);
+ _gcry_mpi_release (h_value);
+ }
+ }
+ else
+ {
+ rc = generate (&sk, nbits, qbits,
+ !!(flags & PUBKEY_FLAG_TRANSIENT_KEY),
+ &domain, &factors);
+ }
+
+ if (!rc)
+ {
+ /* Put the factors into MISC_INFO. Note that the factors are
+ not confidential thus we can store them in standard memory. */
+ int nfactors, i, j;
+ char *p;
+ char *format = NULL;
+ void **arg_list = NULL;
+
+ for (nfactors=0; factors && factors[nfactors]; nfactors++)
+ ;
+ /* Allocate space for the format string:
+ "(misc-key-info%S(pm1-factors%m))"
+ with one "%m" for each factor and construct it. */
+ format = xtrymalloc (50 + 2*nfactors);
+ if (!format)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ p = stpcpy (format, "(misc-key-info");
+ if (seedinfo)
+ p = stpcpy (p, "%S");
+ if (nfactors)
+ {
+ p = stpcpy (p, "(pm1-factors");
+ for (i=0; i < nfactors; i++)
+ p = stpcpy (p, "%m");
+ p = stpcpy (p, ")");
+ }
+ p = stpcpy (p, ")");
+
+ /* Allocate space for the list of factors plus one for the
+ seedinfo s-exp plus an extra NULL entry for safety and
+ fill it with the factors. */
+ arg_list = xtrycalloc (nfactors+1+1, sizeof *arg_list);
+ if (!arg_list)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ i = 0;
+ if (seedinfo)
+ arg_list[i++] = &seedinfo;
+ for (j=0; j < nfactors; j++)
+ arg_list[i++] = factors + j;
+ arg_list[i] = NULL;
+
+ rc = sexp_build_array (&misc_info, NULL, format, arg_list);
+ }
+ }
+
+ xfree (arg_list);
+ xfree (format);
+ }
+
+ if (!rc)
+ rc = sexp_build (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (dsa(p%m)(q%m)(g%m)(y%m)))"
+ " (private-key"
+ " (dsa(p%m)(q%m)(g%m)(y%m)(x%m)))"
+ " %S)",
+ sk.p, sk.q, sk.g, sk.y,
+ sk.p, sk.q, sk.g, sk.y, sk.x,
+ misc_info);
+
+
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+
+ _gcry_mpi_release (domain.p);
+ _gcry_mpi_release (domain.q);
+ _gcry_mpi_release (domain.g);
+
+ sexp_release (seedinfo);
+ sexp_release (misc_info);
+ sexp_release (deriveparms);
+ if (factors)
+ {
+ gcry_mpi_t *mp;
+ for (mp = factors; *mp; mp++)
+ mpi_free (*mp);
+ xfree (factors);
+ }
+ return rc;
+}
+
+
+
+static gcry_err_code_t
+dsa_check_secret_key (gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
+
+ rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
+ &sk.p, &sk.q, &sk.g, &sk.y, &sk.x,
+ NULL);
+ if (rc)
+ goto leave;
+
+ if (!check_secret_key (&sk))
+ rc = GPG_ERR_BAD_SECKEY;
+
+ leave:
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+ if (DBG_CIPHER)
+ log_debug ("dsa_testkey => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+dsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t data = NULL;
+ DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
+ dsa_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("dsa_sign data", data);
+
+ /* Extract the key. */
+ rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
+ &sk.p, &sk.q, &sk.g, &sk.y, &sk.x, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("dsa_sign p", sk.p);
+ log_mpidump ("dsa_sign q", sk.q);
+ log_mpidump ("dsa_sign g", sk.g);
+ log_mpidump ("dsa_sign y", sk.y);
+ if (!fips_mode ())
+ log_mpidump ("dsa_sign x", sk.x);
+ }
+
+ sig_r = mpi_new (0);
+ sig_s = mpi_new (0);
+ rc = sign (sig_r, sig_s, data, &sk, ctx.flags, ctx.hash_algo);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("dsa_sign sig_r", sig_r);
+ log_mpidump ("dsa_sign sig_s", sig_s);
+ }
+ rc = sexp_build (r_sig, NULL, "(sig-val(dsa(r%M)(s%M)))", sig_r, sig_s);
+
+ leave:
+ _gcry_mpi_release (sig_r);
+ _gcry_mpi_release (sig_s);
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+ _gcry_mpi_release (data);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("dsa_sign => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+dsa_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+ gcry_mpi_t data = NULL;
+ DSA_public_key pk = { NULL, NULL, NULL, NULL };
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+ dsa_get_nbits (s_keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("dsa_verify data", data);
+
+ /* Extract the signature value. */
+ rc = _gcry_pk_util_preparse_sigval (s_sig, dsa_names, &l1, NULL);
+ if (rc)
+ goto leave;
+ rc = _gcry_sexp_extract_param (l1, NULL, "rs", &sig_r, &sig_s, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("dsa_verify s_r", sig_r);
+ log_mpidump ("dsa_verify s_s", sig_s);
+ }
+
+ /* Extract the key. */
+ rc = _gcry_sexp_extract_param (s_keyparms, NULL, "pqgy",
+ &pk.p, &pk.q, &pk.g, &pk.y, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("dsa_verify p", pk.p);
+ log_mpidump ("dsa_verify q", pk.q);
+ log_mpidump ("dsa_verify g", pk.g);
+ log_mpidump ("dsa_verify y", pk.y);
+ }
+
+ /* Verify the signature. */
+ rc = verify (sig_r, sig_s, data, &pk);
+
+ leave:
+ _gcry_mpi_release (pk.p);
+ _gcry_mpi_release (pk.q);
+ _gcry_mpi_release (pk.g);
+ _gcry_mpi_release (pk.y);
+ _gcry_mpi_release (data);
+ _gcry_mpi_release (sig_r);
+ _gcry_mpi_release (sig_s);
+ sexp_release (l1);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("dsa_verify => %s\n", rc?gpg_strerror (rc):"Good");
+ return rc;
+}
+
+
+/* Return the number of bits for the key described by PARMS. On error
+ * 0 is returned. The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ * (dsa
+ * (p <mpi>)
+ * (q <mpi>)
+ * (g <mpi>)
+ * (y <mpi>))
+ *
+ * More parameters may be given but we only need P here.
+ */
+static unsigned int
+dsa_get_nbits (gcry_sexp_t parms)
+{
+ gcry_sexp_t l1;
+ gcry_mpi_t p;
+ unsigned int nbits;
+
+ l1 = sexp_find_token (parms, "p", 1);
+ if (!l1)
+ return 0; /* Parameter P not found. */
+
+ p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ nbits = p? mpi_get_nbits (p) : 0;
+ _gcry_mpi_release (p);
+ return nbits;
+}
+
+
+
+/*
+ Self-test section.
+ */
+
+static const char *
+selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+ /* Sample data from RFC 6979 section A.2.2, hash is of message "sample" */
+ static const char sample_data[] =
+ "(data (flags rfc6979)"
+ " (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e9891562113d8a62add1bf#))";
+ static const char sample_data_bad[] =
+ "(data (flags rfc6979)"
+ " (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e9891562113d8a62add1bf#))";
+ static const char signature_r[] =
+ "eace8bdbbe353c432a795d9ec556c6d021f7a03f42c36e9bc87e4ac7932cc809";
+ static const char signature_s[] =
+ "7081e175455f9247b812b74583e9e94f9ea79bd640dc962533b0680793a38d53";
+
+ const char *errtxt = NULL;
+ gcry_error_t err;
+ gcry_sexp_t data = NULL;
+ gcry_sexp_t data_bad = NULL;
+ gcry_sexp_t sig = NULL;
+ gcry_sexp_t l1 = NULL;
+ gcry_sexp_t l2 = NULL;
+ gcry_mpi_t r = NULL;
+ gcry_mpi_t s = NULL;
+ gcry_mpi_t calculated_r = NULL;
+ gcry_mpi_t calculated_s = NULL;
+ int cmp;
+
+ err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
+ if (!err)
+ err = sexp_sscan (&data_bad, NULL,
+ sample_data_bad, strlen (sample_data_bad));
+ if (!err)
+ err = _gcry_mpi_scan (&r, GCRYMPI_FMT_HEX, signature_r, 0, NULL);
+ if (!err)
+ err = _gcry_mpi_scan (&s, GCRYMPI_FMT_HEX, signature_s, 0, NULL);
+
+ if (err)
+ {
+ errtxt = "converting data failed";
+ goto leave;
+ }
+
+ err = _gcry_pk_sign (&sig, data, skey);
+ if (err)
+ {
+ errtxt = "signing failed";
+ goto leave;
+ }
+
+ /* check against known signature */
+ errtxt = "signature validity failed";
+ l1 = _gcry_sexp_find_token (sig, "sig-val", 0);
+ if (!l1)
+ goto leave;
+ l2 = _gcry_sexp_find_token (l1, "dsa", 0);
+ if (!l2)
+ goto leave;
+
+ sexp_release (l1);
+ l1 = l2;
+
+ l2 = _gcry_sexp_find_token (l1, "r", 0);
+ if (!l2)
+ goto leave;
+ calculated_r = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!calculated_r)
+ goto leave;
+
+ sexp_release (l2);
+ l2 = _gcry_sexp_find_token (l1, "s", 0);
+ if (!l2)
+ goto leave;
+ calculated_s = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!calculated_s)
+ goto leave;
+
+ errtxt = "known sig check failed";
+
+ cmp = _gcry_mpi_cmp (r, calculated_r);
+ if (cmp)
+ goto leave;
+ cmp = _gcry_mpi_cmp (s, calculated_s);
+ if (cmp)
+ goto leave;
+
+ errtxt = NULL;
+
+
+ err = _gcry_pk_verify (sig, data, pkey);
+ if (err)
+ {
+ errtxt = "verify failed";
+ goto leave;
+ }
+ err = _gcry_pk_verify (sig, data_bad, pkey);
+ if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
+ {
+ errtxt = "bad signature not detected";
+ goto leave;
+ }
+
+
+ leave:
+ _gcry_mpi_release (calculated_s);
+ _gcry_mpi_release (calculated_r);
+ _gcry_mpi_release (s);
+ _gcry_mpi_release (r);
+ sexp_release (l2);
+ sexp_release (l1);
+ sexp_release (sig);
+ sexp_release (data_bad);
+ sexp_release (data);
+ return errtxt;
+}
+
+
+static gpg_err_code_t
+selftests_dsa_2048 (selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+ gcry_error_t err;
+ gcry_sexp_t skey = NULL;
+ gcry_sexp_t pkey = NULL;
+
+ /* Convert the S-expressions into the internal representation. */
+ what = "convert";
+ err = sexp_sscan (&skey, NULL, sample_secret_key_2048, strlen (sample_secret_key_2048));
+ if (!err)
+ err = sexp_sscan (&pkey, NULL,
+ sample_public_key_2048, strlen (sample_public_key_2048));
+ if (err)
+ {
+ errtxt = _gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "key consistency";
+ err = _gcry_pk_testkey (skey);
+ if (err)
+ {
+ errtxt = _gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "sign";
+ errtxt = selftest_sign (pkey, skey);
+ if (errtxt)
+ goto failed;
+
+ sexp_release (pkey);
+ sexp_release (skey);
+ return 0; /* Succeeded. */
+
+ failed:
+ sexp_release (pkey);
+ sexp_release (skey);
+ if (report)
+ report ("pubkey", GCRY_PK_DSA, 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;
+
+ (void)extended;
+
+ switch (algo)
+ {
+ case GCRY_PK_DSA:
+ ec = selftests_dsa_2048 (report);
+ break;
+ default:
+ ec = GPG_ERR_PUBKEY_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+gcry_pk_spec_t _gcry_pubkey_spec_dsa =
+ {
+ GCRY_PK_DSA, { 0, 1 },
+ GCRY_PK_USAGE_SIGN,
+ "DSA", dsa_names,
+ "pqgy", "pqgyx", "", "rs", "pqgy",
+ dsa_generate,
+ dsa_check_secret_key,
+ NULL,
+ NULL,
+ dsa_sign,
+ dsa_verify,
+ dsa_get_nbits,
+ run_selftests
+ };
diff --git a/comm/third_party/libgcrypt/cipher/ecc-common.h b/comm/third_party/libgcrypt/cipher/ecc-common.h
new file mode 100644
index 0000000000..25c3111263
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc-common.h
@@ -0,0 +1,140 @@
+/* ecc-common.h - Declarations of common ECC code
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ECC_COMMON_H
+#define GCRY_ECC_COMMON_H
+
+
+/* Definition of a curve. */
+typedef struct
+{
+ enum gcry_mpi_ec_models model;/* The model descrinbing this curve. */
+ enum ecc_dialects dialect; /* The dialect used with the curve. */
+ gcry_mpi_t p; /* Prime specifying the field GF(p). */
+ gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */
+ gcry_mpi_t b; /* Second coefficient of the Weierstrass equation.
+ or d as used by Twisted Edwards curves. */
+ mpi_point_struct G; /* Base point (generator). */
+ gcry_mpi_t n; /* Order of G. */
+ unsigned int h; /* Cofactor. */
+ const char *name; /* Name of the curve or NULL. */
+} elliptic_curve_t;
+
+
+
+/* Set the value from S into D. */
+static inline void
+point_set (mpi_point_t d, mpi_point_t s)
+{
+ mpi_set (d->x, s->x);
+ mpi_set (d->y, s->y);
+ mpi_set (d->z, s->z);
+}
+
+#define point_init(a) _gcry_mpi_point_init ((a))
+#define point_free(a) _gcry_mpi_point_free_parts ((a))
+
+
+/*-- ecc-curves.c --*/
+gpg_err_code_t _gcry_ecc_fill_in_curve (unsigned int nbits,
+ const char *name,
+ elliptic_curve_t *curve,
+ unsigned int *r_nbits);
+gpg_err_code_t _gcry_ecc_update_curve_param (const char *name,
+ enum gcry_mpi_ec_models *model,
+ enum ecc_dialects *dialect,
+ gcry_mpi_t *p, gcry_mpi_t *a,
+ gcry_mpi_t *b, gcry_mpi_t *g,
+ gcry_mpi_t *n);
+
+const char *_gcry_ecc_get_curve (gcry_sexp_t keyparms,
+ int iterator,
+ unsigned int *r_nbits);
+gcry_sexp_t _gcry_ecc_get_param_sexp (const char *name);
+
+/*-- ecc-misc.c --*/
+void _gcry_ecc_curve_free (elliptic_curve_t *E);
+elliptic_curve_t _gcry_ecc_curve_copy (elliptic_curve_t E);
+const char *_gcry_ecc_model2str (enum gcry_mpi_ec_models model);
+const char *_gcry_ecc_dialect2str (enum ecc_dialects dialect);
+gcry_mpi_t _gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p);
+
+mpi_point_t _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec);
+gpg_err_code_t _gcry_ecc_mont_encodepoint (gcry_mpi_t x, unsigned int nbits,
+ int with_prefix,
+ unsigned char **r_buffer,
+ unsigned int *r_buflen);
+
+
+/*-- ecc.c --*/
+
+/*-- ecc-ecdsa.c --*/
+gpg_err_code_t _gcry_ecc_ecdsa_sign (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s,
+ int flags, int hashalgo);
+gpg_err_code_t _gcry_ecc_ecdsa_verify (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s);
+
+/*-- ecc-eddsa.c --*/
+gpg_err_code_t _gcry_ecc_eddsa_recover_x (gcry_mpi_t x, gcry_mpi_t y, int sign,
+ mpi_ec_t ec);
+gpg_err_code_t _gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ctx,
+ gcry_mpi_t x, gcry_mpi_t y,
+ int with_prefix,
+ unsigned char **r_buffer,
+ unsigned int *r_buflen);
+gpg_err_code_t _gcry_ecc_eddsa_ensure_compact (gcry_mpi_t value,
+ unsigned int nbits);
+
+
+gpg_err_code_t _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest,
+ mpi_ec_t ec);
+
+gpg_err_code_t _gcry_ecc_eddsa_genkey (mpi_ec_t ec, int flags);
+gpg_err_code_t _gcry_ecc_eddsa_sign (gcry_mpi_t input,
+ mpi_ec_t ec,
+ gcry_mpi_t r_r, gcry_mpi_t s,
+ struct pk_encoding_ctx *ctx);
+gpg_err_code_t _gcry_ecc_eddsa_verify (gcry_mpi_t input,
+ mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s,
+ struct pk_encoding_ctx *ctx);
+void reverse_buffer (unsigned char *buffer, unsigned int length);
+
+
+/*-- ecc-gost.c --*/
+gpg_err_code_t _gcry_ecc_gost_sign (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s);
+gpg_err_code_t _gcry_ecc_gost_verify (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s);
+
+
+/*-- ecc-sm2.c --*/
+gpg_err_code_t _gcry_ecc_sm2_encrypt (gcry_sexp_t *r_ciph,
+ gcry_mpi_t input, mpi_ec_t ec);
+gpg_err_code_t _gcry_ecc_sm2_decrypt (gcry_sexp_t *r_plain,
+ gcry_sexp_t data_list, mpi_ec_t ec);
+gpg_err_code_t _gcry_ecc_sm2_sign (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s,
+ int flags, int hashalgo);
+gpg_err_code_t _gcry_ecc_sm2_verify (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s);
+
+
+#endif /*GCRY_ECC_COMMON_H*/
diff --git a/comm/third_party/libgcrypt/cipher/ecc-curves.c b/comm/third_party/libgcrypt/cipher/ecc-curves.c
new file mode 100644
index 0000000000..900b668aac
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc-curves.c
@@ -0,0 +1,1603 @@
+/* ecc-curves.c - Elliptic Curve parameter mangement
+ * Copyright (C) 2007, 2008, 2010, 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "mpi-internal.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "pubkey-internal.h"
+#include "ecc-common.h"
+
+
+static gpg_err_code_t
+point_from_keyparam (gcry_mpi_point_t *r_a,
+ gcry_sexp_t keyparam, const char *name, mpi_ec_t ec);
+
+/* This tables defines aliases for curve names. */
+static const struct
+{
+ const char *name; /* Our name. */
+ const char *other; /* Other name. */
+} curve_aliases[] =
+ {
+ { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, /* OpenPGP */
+ { "Ed25519", "1.3.101.112" }, /* rfc8410 */
+
+ { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, /* OpenPGP */
+ { "Curve25519", "1.3.101.110" }, /* rfc8410 */
+ { "Curve25519", "X25519" }, /* rfc8410 */
+
+ { "Ed448", "1.3.101.113" }, /* rfc8410 */
+ { "X448", "1.3.101.111" }, /* rfc8410 */
+
+ { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */
+ { "NIST P-192", "prime192v1" }, /* X9.62 name. */
+ { "NIST P-192", "secp192r1" }, /* SECP name. */
+ { "NIST P-192", "nistp192" }, /* rfc5656. */
+
+ { "NIST P-224", "secp224r1" },
+ { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */
+ { "NIST P-224", "nistp224" }, /* rfc5656. */
+
+ { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */
+ { "NIST P-256", "prime256v1" },
+ { "NIST P-256", "secp256r1" },
+ { "NIST P-256", "nistp256" }, /* rfc5656. */
+
+ { "NIST P-384", "secp384r1" },
+ { "NIST P-384", "1.3.132.0.34" },
+ { "NIST P-384", "nistp384" }, /* rfc5656. */
+
+ { "NIST P-521", "secp521r1" },
+ { "NIST P-521", "1.3.132.0.35" },
+ { "NIST P-521", "nistp521" }, /* rfc5656. */
+
+ { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
+ { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
+ { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
+ { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
+ { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
+ { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
+ { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
+
+ { "GOST2001-test", "1.2.643.2.2.35.0" },
+ { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" },
+ { "GOST2001-CryptoPro-B", "1.2.643.2.2.35.2" },
+ { "GOST2001-CryptoPro-C", "1.2.643.2.2.35.3" },
+ { "GOST2001-CryptoPro-A", "GOST2001-CryptoPro-XchA" },
+ { "GOST2001-CryptoPro-C", "GOST2001-CryptoPro-XchB" },
+ { "GOST2001-CryptoPro-A", "1.2.643.2.2.36.0" },
+ { "GOST2001-CryptoPro-C", "1.2.643.2.2.36.1" },
+
+ { "GOST2012-256-tc26-A", "1.2.643.7.1.2.1.1.1" },
+ { "GOST2001-CryptoPro-A", "1.2.643.7.1.2.1.1.2" },
+ { "GOST2001-CryptoPro-A", "GOST2012-256-tc26-B" },
+ { "GOST2001-CryptoPro-B", "1.2.643.7.1.2.1.1.3" },
+ { "GOST2001-CryptoPro-B", "GOST2012-256-tc26-C" },
+ { "GOST2001-CryptoPro-C", "1.2.643.7.1.2.1.1.4" },
+ { "GOST2001-CryptoPro-C", "GOST2012-256-tc26-D" },
+
+ { "GOST2012-512-test", "GOST2012-test" },
+ { "GOST2012-512-test", "1.2.643.7.1.2.1.2.0" },
+ { "GOST2012-512-tc26-A", "GOST2012-tc26-A" },
+ { "GOST2012-512-tc26-B", "GOST2012-tc26-B" },
+ { "GOST2012-512-tc26-A", "1.2.643.7.1.2.1.2.1" },
+ { "GOST2012-512-tc26-B", "1.2.643.7.1.2.1.2.2" },
+ { "GOST2012-512-tc26-C", "1.2.643.7.1.2.1.2.3" },
+
+ { "secp256k1", "1.3.132.0.10" },
+
+ { "sm2p256v1", "1.2.156.10197.1.301" },
+
+ { NULL, NULL}
+ };
+
+
+typedef struct
+{
+ const char *desc; /* Description of the curve. */
+ unsigned int nbits; /* Number of bits. */
+ unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */
+
+ /* The model describing this curve. This is mainly used to select
+ the group equation. */
+ enum gcry_mpi_ec_models model;
+
+ /* The actual ECC dialect used. This is used for curve specific
+ optimizations and to select encodings etc. */
+ enum ecc_dialects dialect;
+
+ const char *p; /* The prime defining the field. */
+ const char *a, *b; /* The coefficients. For Twisted Edwards
+ Curves b is used for d. For Montgomery
+ Curves (a,b) has ((A-2)/4,B^-1). */
+ const char *n; /* The order of the base point. */
+ const char *g_x, *g_y; /* Base point. */
+ unsigned int h; /* Cofactor. */
+} ecc_domain_parms_t;
+
+
+/* This static table defines all available curves. */
+static const ecc_domain_parms_t domain_parms[] =
+ {
+ {
+ /* (-x^2 + y^2 = 1 + dx^2y^2) */
+ "Ed25519", 255, 0,
+ MPI_EC_EDWARDS, ECC_DIALECT_ED25519,
+ "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+ "-0x01",
+ "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A",
+ "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
+ "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
+ "0x6666666666666666666666666666666666666666666666666666666666666658",
+ 8
+ },
+ {
+ /* (y^2 = x^3 + 486662*x^2 + x) */
+ "Curve25519", 255, 0,
+ MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD,
+ "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+ "0x01DB41",
+ "0x01",
+ "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
+ "0x0000000000000000000000000000000000000000000000000000000000000009",
+ "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9",
+ 8
+ /* Note: As per RFC-7748 errata eid4730 the g_y value should be
+ * "0x5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14"
+ * but that breaks the keygrip. The new value is recovered in
+ * the function _gcry_ecc_fill_in_curve. See bug #4712.
+ */
+ },
+ {
+ /* (x^2 + y^2 = 1 + dx^2y^2) */
+ "Ed448", 448, 0,
+ MPI_EC_EDWARDS, ECC_DIALECT_SAFECURVE,
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ "0x01",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756",
+ "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3",
+ "0x4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324"
+ "A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E",
+ "0x693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E"
+ "05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14",
+ 4,
+ },
+ {
+ /* (y^2 = x^3 + 156326*x^2 + x) */
+ "X448", 448, 0,
+ MPI_EC_MONTGOMERY, ECC_DIALECT_SAFECURVE,
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ "0x98A9",
+ "0x01",
+ "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3",
+ "0x00000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000005",
+ "0x7D235D1295F5B1F66C98AB6E58326FCECBAE5D34F55545D060F75DC2"
+ "8DF3F6EDB8027E2346430D211312C4B150677AF76FD7223D457B5B1A",
+ 4,
+ },
+#if 0 /* No real specs yet found. */
+ {
+ /* x^2 + y^2 = 1 + 3617x^2y^2 mod 2^414 - 17 */
+ "Curve3617",
+ "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF",
+ MPI_EC_EDWARDS, 0,
+ "0x01",
+ "0x0e21",
+ "0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB3CC92414CF"
+ "706022B36F1C0338AD63CF181B0E71A5E106AF79",
+ "0x1A334905141443300218C0631C326E5FCD46369F44C03EC7F57FF35498A4AB4D"
+ "6D6BA111301A73FAA8537C64C4FD3812F3CBC595",
+ "0x22",
+ 8
+ },
+#endif /*0*/
+ {
+ "NIST P-192", 192, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
+ "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
+ "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
+ "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
+
+ "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
+ "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
+ 1
+ },
+ {
+ "NIST P-224", 224, 1,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xffffffffffffffffffffffffffffffff000000000000000000000001",
+ "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
+ "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
+ "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
+
+ "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+ "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
+ 1
+ },
+ {
+ "NIST P-256", 256, 1,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+ "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+ "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+ "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+
+ "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+ "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
+ 1
+ },
+ {
+ "NIST P-384", 384, 1,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+ "ffffffff0000000000000000ffffffff",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+ "ffffffff0000000000000000fffffffc",
+ "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
+ "c656398d8a2ed19d2a85c8edd3ec2aef",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
+ "581a0db248b0a77aecec196accc52973",
+
+ "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
+ "5502f25dbf55296c3a545e3872760ab7",
+ "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
+ "0a60b1ce1d7e819d7a431d7c90ea0e5f",
+ 1
+ },
+ {
+ "NIST P-521", 521, 1,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
+ "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
+ "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+
+ "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d"
+ "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+ "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e"
+ "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
+ 1
+ },
+
+ { "brainpoolP160r1", 160, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
+ "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
+ "0x1e589a8595423412134faa2dbdec95c8d8675e58",
+ "0xe95e4a5f737059dc60df5991d45029409e60fc09",
+ "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
+ "0x1667cb477a1a8ec338f94741669c976316da6321",
+ 1
+ },
+
+ { "brainpoolP192r1", 192, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
+ "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
+ "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
+ "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
+ "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
+ "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f",
+ 1
+ },
+
+ { "brainpoolP224r1", 224, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
+ "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
+ "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
+ "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
+ "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
+ "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd",
+ 1
+ },
+
+ { "brainpoolP256r1", 256, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
+ "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
+ "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
+ "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
+ "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
+ "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997",
+ 1
+ },
+
+ { "brainpoolP320r1", 320, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
+ "fcd412b1f1b32e27",
+ "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
+ "92f375a97d860eb4",
+ "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
+ "6f5eb4ac8fb1f1a6",
+ "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
+ "8691555b44c59311",
+ "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
+ "10af8d0d39e20611",
+ "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
+ "d35245d1692e8ee1",
+ 1
+ },
+
+ { "brainpoolP384r1", 384, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
+ "acd3a729901d1a71874700133107ec53",
+ "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
+ "8aa5814a503ad4eb04a8c7dd22ce2826",
+ "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
+ "7cb4390295dbc9943ab78696fa504c11",
+ "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
+ "cf3ab6af6b7fc3103b883202e9046565",
+ "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
+ "e826e03436d646aaef87b2e247d4af1e",
+ "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
+ "0e4646217791811142820341263c5315",
+ 1
+ },
+
+ { "brainpoolP512r1", 512, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
+ "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
+ "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
+ "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
+ "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
+ "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
+ "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
+ "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
+ "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
+ "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
+ "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
+ "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892",
+ 1
+ },
+ {
+ "GOST2001-test", 256, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0x8000000000000000000000000000000000000000000000000000000000000431",
+ "0x0000000000000000000000000000000000000000000000000000000000000007",
+ "0x5fbff498aa938ce739b8e022fbafef40563f6e6a3472fc2a514c0ce9dae23b7e",
+ "0x8000000000000000000000000000000150fe8a1892976154c59cfc193accf5b3",
+
+ "0x0000000000000000000000000000000000000000000000000000000000000002",
+ "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8",
+ 1
+ },
+ {
+ "GOST2001-CryptoPro-A", 256, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd94",
+ "0x00000000000000000000000000000000000000000000000000000000000000a6",
+ "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893",
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14",
+ 1
+ },
+ {
+ "GOST2001-CryptoPro-B", 256, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0x8000000000000000000000000000000000000000000000000000000000000c99",
+ "0x8000000000000000000000000000000000000000000000000000000000000c96",
+ "0x3e1af419a269a5f866a7d3c25c3df80ae979259373ff2b182f49d4ce7e1bbc8b",
+ "0x800000000000000000000000000000015f700cfff1a624e5e497161bcc8a198f",
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc",
+ 1
+ },
+ {
+ "GOST2001-CryptoPro-C", 256, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d759b",
+ "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d7598",
+ "0x000000000000000000000000000000000000000000000000000000000000805a",
+ "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67",
+ 1
+ },
+ {
+ "GOST2012-256-A", 256, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97",
+ "0xc2173f1513981673af4892c23035a27ce25e2013bf95aa33b22c656f277e7335",
+ "0x295f9bae7428ed9ccc20e7c359a9d41a22fccd9108e17bf7ba9337a6f8ae9513",
+ "0x400000000000000000000000000000000fd8cddfc87b6635c115af556c360c67",
+ "0x91e38443a5e82c0d880923425712b2bb658b9196932e02c78b2582fe742daa28",
+ "0x32879423ab1a0375895786c4bb46e9565fde0b5344766740af268adb32322e5c",
+ 4
+ },
+ {
+ "GOST2012-512-test", 511, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d"
+ "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373",
+ "0x0000000000000000000000000000000000000000000000000000000000000007",
+ "0x1cff0806a31116da29d8cfa54e57eb748bc5f377e49400fdd788b649eca1ac4"
+ "361834013b2ad7322480a89ca58e0cf74bc9e540c2add6897fad0a3084f302adc",
+ "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d"
+ "a82f2d7ecb1dbac719905c5eecc423f1d86e25edbe23c595d644aaf187e6e6df",
+
+ "0x24d19cc64572ee30f396bf6ebbfd7a6c5213b3b3d7057cc825f91093a68cd762"
+ "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a",
+ "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2"
+ "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e",
+ 1
+ },
+ {
+ "GOST2012-512-tc26-A", 512, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc4",
+ "0xe8c2505dedfc86ddc1bd0b2b6667f1da34b82574761cb0e879bd081cfd0b6265"
+ "ee3cb090f30d27614cb4574010da90dd862ef9d4ebee4761503190785a71c760",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "27e69532f48d89116ff22b8d4e0560609b4b38abfad2b85dcacdb1411f10b275",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000003",
+ "0x7503cfe87a836ae3a61b8816e25450e6ce5e1c93acf1abc1778064fdcbefa921"
+ "df1626be4fd036e93d75e6a50e3a41e98028fe5fc235f5b889a589cb5215f2a4",
+ 1
+ },
+ {
+ "GOST2012-512-tc26-B", 512, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0x8000000000000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000000000006f",
+ "0x8000000000000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000000000006c",
+ "0x687d1b459dc841457e3e06cf6f5e2517b97c7d614af138bcbf85dc806c4b289f"
+ "3e965d2db1416d217f8b276fad1ab69c50f78bee1fa3106efb8ccbc7c5140116",
+ "0x8000000000000000000000000000000000000000000000000000000000000001"
+ "49a1ec142565a545acfdb77bd9d40cfa8b996712101bea0ec6346c54374f25bd",
+ "0x0000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000000002",
+ "0x1a8f7eda389b094c2c071e3647a8940f3c123b697578c213be6dd9e6c8ec7335"
+ "dcb228fd1edf4a39152cbcaaf8c0398828041055f94ceeec7e21340780fe41bd",
+ 1
+ },
+ {
+ "GOST2012-512-tc26-C", 512, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7",
+ "0xdc9203e514a721875485a529d2c722fb187bc8980eb866644de41c68e1430645"
+ "46e861c0e2c9edd92ade71f46fcf50ff2ad97f951fda9f2a2eb6546f39689bd3",
+ "0xb4c4ee28cebc6c2c8ac12952cf37f16ac7efb6a9f69f4b57ffda2e4f0de5ade0"
+ "38cbc2fff719d2c18de0284b8bfef3b52b8cc7a5f5bf0a3c8d2319a5312557e1",
+ "0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "c98cdba46506ab004c33a9ff5147502cc8eda9e7a769a12694623cef47f023ed",
+ "0xe2e31edfc23de7bdebe241ce593ef5de2295b7a9cbaef021d385f7074cea043a"
+ "a27272a7ae602bf2a7b9033db9ed3610c6fb85487eae97aac5bc7928c1950148",
+ "0xf5ce40d95b5eb899abbccff5911cb8577939804d6527378b8c108c3d2090ff9be"
+ "18e2d33e3021ed2ef32d85822423b6304f726aa854bae07d0396e9a9addc40f",
+ 4
+ },
+
+ {
+ "secp256k1", 256, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000007",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
+ "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
+ "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
+ 1
+ },
+
+ {
+ "sm2p256v1", 256, 0,
+ MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+ "0xfffffffeffffffffffffffffffffffffffffffff00000000ffffffffffffffff",
+ "0xfffffffeffffffffffffffffffffffffffffffff00000000fffffffffffffffc",
+ "0x28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93",
+ "0xfffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123",
+ "0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7",
+ "0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0",
+ 1
+ },
+
+ { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }
+ };
+
+
+
+
+/* Return a copy of POINT. */
+static gcry_mpi_point_t
+point_copy (gcry_mpi_point_t point)
+{
+ gcry_mpi_point_t newpoint;
+
+ if (point)
+ {
+ newpoint = mpi_point_new (0);
+ point_set (newpoint, point);
+ }
+ else
+ newpoint = NULL;
+ return newpoint;
+}
+
+
+/* Helper to scan a hex string. */
+static gcry_mpi_t
+scanval (const char *string)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t val;
+
+ rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (rc)
+ log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc));
+ return val;
+}
+
+
+/* Return the index of the domain_parms table for a curve with NAME.
+ Return -1 if not found. */
+static int
+find_domain_parms_idx (const char *name)
+{
+ int idx, aliasno;
+
+ /* First check our native curves. */
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ if (!strcmp (name, domain_parms[idx].desc))
+ return idx;
+
+ /* If not found consult the alias table. */
+ if (!domain_parms[idx].desc)
+ {
+ for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
+ if (!strcmp (name, curve_aliases[aliasno].other))
+ break;
+ if (curve_aliases[aliasno].name)
+ {
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ if (!strcmp (curve_aliases[aliasno].name, domain_parms[idx].desc))
+ return idx;
+ }
+ }
+
+ return -1;
+}
+
+
+/* Generate the crypto system setup. This function takes the NAME of
+ a curve or the desired number of bits and stores at R_CURVE the
+ parameters of the named curve or those of a suitable curve. If
+ R_NBITS is not NULL, the chosen number of bits is stored there.
+ NULL may be given for R_CURVE, if the value is not required and for
+ example only a quick test for availability is desired. Note that
+ the curve fields should be initialized to zero because fields which
+ are not NULL are skipped. */
+gpg_err_code_t
+_gcry_ecc_fill_in_curve (unsigned int nbits, const char *name,
+ elliptic_curve_t *curve, unsigned int *r_nbits)
+{
+ int idx;
+ const char *resname = NULL; /* Set to a found curve name. */
+
+ if (name)
+ idx = find_domain_parms_idx (name);
+ else
+ {
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ if (nbits == domain_parms[idx].nbits
+ && domain_parms[idx].model == MPI_EC_WEIERSTRASS)
+ break;
+ if (!domain_parms[idx].desc)
+ idx = -1;
+ }
+ if (idx < 0)
+ return GPG_ERR_UNKNOWN_CURVE;
+
+ resname = domain_parms[idx].desc;
+
+ /* In fips mode we only support NIST curves. Note that it is
+ possible to bypass this check by specifying the curve parameters
+ directly. */
+ if (fips_mode () && !domain_parms[idx].fips )
+ return GPG_ERR_NOT_SUPPORTED;
+
+ switch (domain_parms[idx].model)
+ {
+ case MPI_EC_WEIERSTRASS:
+ case MPI_EC_EDWARDS:
+ case MPI_EC_MONTGOMERY:
+ break;
+ default:
+ return GPG_ERR_BUG;
+ }
+
+
+ if (r_nbits)
+ *r_nbits = domain_parms[idx].nbits;
+
+ if (curve)
+ {
+ curve->model = domain_parms[idx].model;
+ curve->dialect = domain_parms[idx].dialect;
+ if (!curve->p)
+ curve->p = scanval (domain_parms[idx].p);
+ if (!curve->a)
+ {
+ curve->a = scanval (domain_parms[idx].a);
+ if (curve->a->sign)
+ {
+ mpi_resize (curve->a, curve->p->nlimbs);
+ _gcry_mpih_sub_n (curve->a->d, curve->p->d,
+ curve->a->d, curve->p->nlimbs);
+ curve->a->nlimbs = curve->p->nlimbs;
+ curve->a->sign = 0;
+ }
+ }
+ if (!curve->b)
+ {
+ curve->b = scanval (domain_parms[idx].b);
+ if (curve->b->sign)
+ {
+ mpi_resize (curve->b, curve->p->nlimbs);
+ _gcry_mpih_sub_n (curve->b->d, curve->p->d,
+ curve->b->d, curve->p->nlimbs);
+ curve->b->nlimbs = curve->p->nlimbs;
+ curve->b->sign = 0;
+ }
+ }
+ if (!curve->n)
+ curve->n = scanval (domain_parms[idx].n);
+ if (!curve->G.x)
+ curve->G.x = scanval (domain_parms[idx].g_x);
+ if (!curve->G.y)
+ curve->G.y = scanval (domain_parms[idx].g_y);
+ curve->h = domain_parms[idx].h;
+
+ /*
+ * In the constants of domain_parms, we defined Curve25519
+ * domain parameters as the ones in RFC-7748 before the errata
+ * (eid4730). To keep the computation having exact same values,
+ * we recover the new value of g_y, here.
+ */
+ if (!strcmp (resname, "Curve25519"))
+ mpi_sub (curve->G.y, curve->p, curve->G.y);
+
+ if (!curve->G.z)
+ curve->G.z = mpi_alloc_set_ui (1);
+ if (!curve->name)
+ curve->name = resname;
+ }
+
+ return 0;
+}
+
+
+/* Give the name of the curve NAME, store the curve parameters into P,
+ A, B, G, and N if they point to NULL value. Note that G is
+ returned in standard uncompressed format. Also update MODEL and
+ DIALECT if they are not NULL. */
+gpg_err_code_t
+_gcry_ecc_update_curve_param (const char *name,
+ enum gcry_mpi_ec_models *model,
+ enum ecc_dialects *dialect,
+ gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b,
+ gcry_mpi_t *g, gcry_mpi_t *n)
+{
+ int idx;
+
+ idx = find_domain_parms_idx (name);
+ if (idx < 0)
+ return GPG_ERR_UNKNOWN_CURVE;
+
+ if (g)
+ {
+ char *buf;
+ size_t len;
+
+ len = 4;
+ len += strlen (domain_parms[idx].g_x+2);
+ len += strlen (domain_parms[idx].g_y+2);
+ len++;
+ buf = xtrymalloc (len);
+ if (!buf)
+ return gpg_err_code_from_syserror ();
+ strcpy (stpcpy (stpcpy (buf, "0x04"), domain_parms[idx].g_x+2),
+ domain_parms[idx].g_y+2);
+ _gcry_mpi_release (*g);
+ *g = scanval (buf);
+ xfree (buf);
+ }
+ if (model)
+ *model = domain_parms[idx].model;
+ if (dialect)
+ *dialect = domain_parms[idx].dialect;
+ if (p)
+ {
+ _gcry_mpi_release (*p);
+ *p = scanval (domain_parms[idx].p);
+ }
+ if (a)
+ {
+ _gcry_mpi_release (*a);
+ *a = scanval (domain_parms[idx].a);
+ }
+ if (b)
+ {
+ _gcry_mpi_release (*b);
+ *b = scanval (domain_parms[idx].b);
+ }
+ if (n)
+ {
+ _gcry_mpi_release (*n);
+ *n = scanval (domain_parms[idx].n);
+ }
+ return 0;
+}
+
+
+/* Return the name matching the parameters in PKEY. This works only
+ with curves described by the Weierstrass equation. */
+const char *
+_gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits)
+{
+ gpg_err_code_t rc;
+ const char *result = NULL;
+ elliptic_curve_t E;
+ gcry_mpi_point_t G = NULL;
+ gcry_mpi_t tmp = NULL;
+ int idx;
+
+ memset (&E, 0, sizeof E);
+
+ if (r_nbits)
+ *r_nbits = 0;
+
+ if (!keyparms)
+ {
+ idx = iterator;
+ if (idx >= 0 && idx < DIM (domain_parms))
+ {
+ result = domain_parms[idx].desc;
+ if (r_nbits)
+ *r_nbits = domain_parms[idx].nbits;
+ }
+ return result;
+ }
+
+
+ /*
+ * Extract the curve parameters..
+ */
+ rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "pabn",
+ &E.p, &E.a, &E.b, &E.n, NULL));
+ if (rc == GPG_ERR_NO_OBJ)
+ {
+ /* This might be the second use case of checking whether a
+ specific curve given by name is supported. */
+ gcry_sexp_t l1;
+ char *name;
+
+ l1 = sexp_find_token (keyparms, "curve", 5);
+ if (!l1)
+ goto leave; /* No curve name parameter. */
+
+ name = sexp_nth_string (l1, 1);
+ sexp_release (l1);
+ if (!name)
+ goto leave; /* Name missing or out of core. */
+
+ idx = find_domain_parms_idx (name);
+ xfree (name);
+ if (idx >= 0) /* Curve found. */
+ {
+ result = domain_parms[idx].desc;
+ if (r_nbits)
+ *r_nbits = domain_parms[idx].nbits;
+ }
+ return result;
+ }
+
+ if (rc)
+ goto leave;
+
+ rc = point_from_keyparam (&G, keyparms, "g", NULL);
+ if (rc)
+ goto leave;
+
+ _gcry_mpi_point_init (&E.G);
+ _gcry_mpi_point_set (&E.G, G->x, G->y, G->z);
+
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].p);
+ if (mpi_cmp (tmp, E.p))
+ continue;
+
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].a);
+ if (tmp->sign)
+ {
+ if (!mpi_cmpabs (tmp, E.a))
+ /* For backward compatibility to <= libgcrypt 1.8, we
+ allow this match to support existing keys in SEXP. */
+ ;
+ else
+ {
+ mpi_resize (tmp, E.p->nlimbs);
+ _gcry_mpih_sub_n (tmp->d, E.p->d,
+ tmp->d, E.p->nlimbs);
+ tmp->nlimbs = E.p->nlimbs;
+ tmp->sign = 0;
+ if (mpi_cmp (tmp, E.a))
+ continue;
+ }
+ }
+ else if (mpi_cmp (tmp, E.a))
+ continue;
+
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].b);
+ if (tmp->sign)
+ {
+ if (!mpi_cmpabs (tmp, E.b))
+ /* Same for backward compatibility, see above. */
+ ;
+ else
+ {
+ mpi_resize (tmp, E.p->nlimbs);
+ _gcry_mpih_sub_n (tmp->d, E.p->d,
+ tmp->d, E.p->nlimbs);
+ tmp->nlimbs = E.p->nlimbs;
+ tmp->sign = 0;
+ if (mpi_cmp (tmp, E.b))
+ continue;
+ }
+ }
+ else if (mpi_cmp (tmp, E.b))
+ continue;
+
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].n);
+ if (mpi_cmp (tmp, E.n))
+ continue;
+
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].g_x);
+ if (mpi_cmp (tmp, E.G.x))
+ continue;
+
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].g_y);
+ if (mpi_cmp (tmp, E.G.y))
+ continue;
+
+ result = domain_parms[idx].desc;
+ if (r_nbits)
+ *r_nbits = domain_parms[idx].nbits;
+ break;
+ }
+
+ leave:
+ _gcry_mpi_point_release (G);
+ _gcry_mpi_release (tmp);
+ _gcry_mpi_release (E.p);
+ _gcry_mpi_release (E.a);
+ _gcry_mpi_release (E.b);
+ _gcry_mpi_point_free_parts (&E.G);
+ _gcry_mpi_release (E.n);
+ return result;
+}
+
+
+/* Helper to extract an MPI from key parameters. */
+static gpg_err_code_t
+mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name,
+ int opaque)
+{
+ gcry_err_code_t ec = 0;
+ gcry_sexp_t l1;
+
+ l1 = sexp_find_token (keyparam, name, 0);
+ if (l1)
+ {
+ *r_a = sexp_nth_mpi (l1, 1, opaque? GCRYMPI_FMT_OPAQUE : GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ if (!*r_a)
+ ec = GPG_ERR_INV_OBJ;
+ }
+ return ec;
+}
+
+/* Helper to extract a point from key parameters. If no parameter
+ with NAME is found, the functions tries to find a non-encoded point
+ by appending ".x", ".y" and ".z" to NAME. ".z" is in this case
+ optional and defaults to 1. EC is the context which at this point
+ may not be fully initialized. */
+static gpg_err_code_t
+point_from_keyparam (gcry_mpi_point_t *r_a,
+ gcry_sexp_t keyparam, const char *name, mpi_ec_t ec)
+{
+ gcry_err_code_t rc;
+ gcry_sexp_t l1;
+ gcry_mpi_point_t point;
+
+ l1 = sexp_find_token (keyparam, name, 0);
+ if (l1)
+ {
+ gcry_mpi_t a;
+
+ a = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE);
+ sexp_release (l1);
+ if (!a)
+ return GPG_ERR_INV_OBJ;
+
+ point = mpi_point_new (0);
+ rc = _gcry_mpi_ec_decode_point (point, a, ec);
+ mpi_free (a);
+ if (rc)
+ {
+ mpi_point_release (point);
+ return rc;
+ }
+ }
+ else
+ {
+ char *tmpname;
+ gcry_mpi_t x = NULL;
+ gcry_mpi_t y = NULL;
+ gcry_mpi_t z = NULL;
+
+ tmpname = xtrymalloc (strlen (name) + 2 + 1);
+ if (!tmpname)
+ return gpg_err_code_from_syserror ();
+ strcpy (stpcpy (tmpname, name), ".x");
+ rc = mpi_from_keyparam (&x, keyparam, tmpname, 0);
+ if (rc)
+ {
+ xfree (tmpname);
+ return rc;
+ }
+ strcpy (stpcpy (tmpname, name), ".y");
+ rc = mpi_from_keyparam (&y, keyparam, tmpname, 0);
+ if (rc)
+ {
+ mpi_free (x);
+ xfree (tmpname);
+ return rc;
+ }
+ strcpy (stpcpy (tmpname, name), ".z");
+ rc = mpi_from_keyparam (&z, keyparam, tmpname, 0);
+ if (rc)
+ {
+ mpi_free (y);
+ mpi_free (x);
+ xfree (tmpname);
+ return rc;
+ }
+ if (!z)
+ z = mpi_set_ui (NULL, 1);
+ if (x && y)
+ point = mpi_point_snatch_set (NULL, x, y, z);
+ else
+ {
+ mpi_free (x);
+ mpi_free (y);
+ mpi_free (z);
+ point = NULL;
+ }
+ xfree (tmpname);
+ }
+
+ if (point)
+ *r_a = point;
+ return 0;
+}
+
+
+
+static gpg_err_code_t
+mpi_ec_get_elliptic_curve (elliptic_curve_t *E, int *r_flags,
+ gcry_sexp_t keyparam, const char *curvename)
+{
+ gpg_err_code_t errc;
+ unsigned int nbits;
+ gcry_sexp_t l1;
+
+ errc = _gcry_pk_util_get_nbits (keyparam, &nbits);
+ if (errc)
+ return errc;
+
+ E->model = MPI_EC_WEIERSTRASS;
+ E->dialect = ECC_DIALECT_STANDARD;
+ E->h = 1;
+
+ if (keyparam)
+ {
+ /* Parse an optional flags list. */
+ l1 = sexp_find_token (keyparam, "flags", 0);
+ if (l1)
+ {
+ int flags = 0;
+
+ errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+ sexp_release (l1);
+ l1 = NULL;
+ if (errc)
+ goto leave;
+
+ *r_flags |= flags;
+ }
+
+ /* Parse the deprecated optional transient-key flag. */
+ l1 = sexp_find_token (keyparam, "transient-key", 0);
+ if (l1)
+ {
+ *r_flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+ sexp_release (l1);
+ }
+
+ /* Check whether a curve name was given. */
+ l1 = sexp_find_token (keyparam, "curve", 5);
+
+ /* If we don't have a curve name or if override parameters have
+ explicitly been requested, parse them. */
+ if (!l1 || (*r_flags & PUBKEY_FLAG_PARAM))
+ {
+ gcry_mpi_point_t G = NULL;
+ gcry_mpi_t cofactor = NULL;
+
+ errc = mpi_from_keyparam (&E->p, keyparam, "p", 0);
+ if (errc)
+ goto leave;
+ errc = mpi_from_keyparam (&E->a, keyparam, "a", 0);
+ if (errc)
+ goto leave;
+ errc = mpi_from_keyparam (&E->b, keyparam, "b", 0);
+ if (errc)
+ goto leave;
+ errc = point_from_keyparam (&G, keyparam, "g", NULL);
+ if (errc)
+ goto leave;
+ if (G)
+ {
+ _gcry_mpi_point_init (&E->G);
+ mpi_point_set (&E->G, G->x, G->y, G->z);
+ mpi_point_set (G, NULL, NULL, NULL);
+ mpi_point_release (G);
+ }
+ errc = mpi_from_keyparam (&E->n, keyparam, "n", 0);
+ if (errc)
+ goto leave;
+ errc = mpi_from_keyparam (&cofactor, keyparam, "h", 0);
+ if (errc)
+ goto leave;
+ if (cofactor)
+ {
+ mpi_get_ui (&E->h, cofactor);
+ mpi_free (cofactor);
+ }
+ }
+ }
+ else
+ l1 = NULL; /* No curvename. */
+
+ /* Check whether a curve parameter is available and use that to fill
+ in missing values. If no curve parameter is available try an
+ optional provided curvename. If only the curvename has been
+ given use that one. */
+ if (l1 || curvename || nbits)
+ {
+ char *name;
+
+ if (l1)
+ {
+ name = sexp_nth_string (l1, 1);
+ sexp_release (l1);
+ if (!name)
+ {
+ errc = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
+ goto leave;
+ }
+ }
+ else
+ name = NULL;
+
+ errc = _gcry_ecc_fill_in_curve (nbits, name? name : curvename, E, NULL);
+ xfree (name);
+ if (errc)
+ goto leave;
+ }
+
+ leave:
+ return errc;
+}
+
+static gpg_err_code_t
+mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags,
+ elliptic_curve_t *E, gcry_sexp_t keyparam)
+{
+ gpg_err_code_t errc = 0;
+
+ ec->G = mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z);
+ E->G.x = NULL;
+ E->G.y = NULL;
+ E->G.z = NULL;
+ ec->n = E->n;
+ E->n = NULL;
+ ec->h = E->h;
+ ec->name = E->name;
+
+ /* Now that we know the curve name we can look for the public key
+ Q. point_from_keyparam needs to know the curve parameters so
+ that it is able to use the correct decompression. Parsing
+ the private key D could have been done earlier but it is less
+ surprising if we do it here as well. */
+ if (keyparam)
+ {
+ int is_opaque_bytes = ((ec->dialect == ECC_DIALECT_ED25519
+ && (flags & PUBKEY_FLAG_EDDSA))
+ || (ec->dialect == ECC_DIALECT_SAFECURVE));
+
+ errc = point_from_keyparam (&ec->Q, keyparam, "q", ec);
+ if (errc)
+ return errc;
+ errc = mpi_from_keyparam (&ec->d, keyparam, "d", is_opaque_bytes);
+
+ /* Size of opaque bytes should match size of P. */
+ if (!errc && ec->d && is_opaque_bytes)
+ {
+ unsigned int n = mpi_get_nbits (ec->d);
+ unsigned int len;
+
+ len = (ec->nbits+7)/8;
+ /* EdDSA requires additional bit for sign. */
+ if ((ec->nbits%8) == 0 && ec->model == MPI_EC_EDWARDS)
+ len++;
+
+ if ((n+7)/8 != len)
+ {
+ if (ec->dialect == ECC_DIALECT_ED25519)
+ {
+ /*
+ * GnuPG (<= 2.2) or OpenPGP implementations with no
+ * SOS support may remove zeros at the beginning.
+ * Recover those zeros.
+ */
+ /*
+ * Also, GnuPG (<= 2.2) may add additional zero at
+ * the beginning, when private key is moved from
+ * OpenPGP to gpg-agent. Remove such a zero-prefix.
+ */
+ const unsigned char *buf;
+ unsigned char *value;
+
+ buf = mpi_get_opaque (ec->d, &n);
+ if (!buf)
+ return GPG_ERR_INV_OBJ;
+
+ value = xtrymalloc_secure (len);
+ if (!value)
+ return gpg_err_code_from_syserror ();
+
+ if ((n+7)/8 < len)
+ /* Recover zeros. */
+ {
+ memset (value, 0, len - (n+7)/8);
+ memcpy (value + len - (n+7)/8, buf, (n+7)/8);
+ }
+ else if ((n+7)/8 == len + 1)
+ /* Remove a zero. */
+ memcpy (value, buf+1, len);
+ else
+ {
+ xfree (value);
+ return GPG_ERR_INV_OBJ;
+ }
+
+ mpi_set_opaque (ec->d, value, len*8);
+ }
+ else
+ {
+ if (DBG_CIPHER)
+ log_debug ("scalar size (%d) != prime size (%d)",
+ (n+7)/8, len);
+
+ errc = GPG_ERR_INV_OBJ;
+ }
+ }
+ }
+ }
+
+ return errc;
+}
+
+gpg_err_code_t
+_gcry_mpi_ec_internal_new (mpi_ec_t *r_ec, int *r_flags, const char *name_op,
+ gcry_sexp_t keyparam, const char *curvename)
+{
+ gpg_err_code_t errc;
+ elliptic_curve_t E;
+ mpi_ec_t ec;
+
+ *r_ec = NULL;
+
+ memset (&E, 0, sizeof E);
+ errc = mpi_ec_get_elliptic_curve (&E, r_flags, keyparam, curvename);
+ if (errc)
+ goto leave;
+
+ ec = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, *r_flags,
+ E.p, E.a, E.b);
+ if (!ec)
+ goto leave;
+
+ errc = mpi_ec_setup_elliptic_curve (ec, *r_flags, &E, keyparam);
+ if (errc)
+ {
+ _gcry_mpi_ec_free (ec);
+ goto leave;
+ }
+ else
+ *r_ec = ec;
+
+ if (!errc && DBG_CIPHER)
+ {
+ gcry_mpi_t mpi_q = NULL;
+ gcry_sexp_t l1;
+ char msg[80];
+
+ l1 = sexp_find_token (keyparam, "q", 0);
+ if (l1)
+ {
+ mpi_q = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE);
+ sexp_release (l1);
+ }
+
+ log_debug ("%s info: %s/%s%s\n", name_op,
+ _gcry_ecc_model2str (ec->model),
+ _gcry_ecc_dialect2str (ec->dialect),
+ (*r_flags & PUBKEY_FLAG_EDDSA)? "+EdDSA" : "");
+ if (ec->name)
+ log_debug ("%s name: %s\n", name_op, ec->name);
+ snprintf (msg, sizeof msg, "%s p", name_op);
+ log_printmpi (msg, ec->p);
+ snprintf (msg, sizeof msg, "%s a", name_op);
+ log_printmpi (msg, ec->a);
+ snprintf (msg, sizeof msg, "%s b", name_op);
+ log_printmpi (msg, ec->b);
+ snprintf (msg, sizeof msg, "%s g", name_op);
+ log_printpnt (msg, ec->G, NULL);
+ snprintf (msg, sizeof msg, "%s n", name_op);
+ log_printmpi (msg, ec->n);
+ log_debug ("%s h:+%02x\n", name_op, ec->h);
+ if (mpi_q)
+ {
+ snprintf (msg, sizeof msg, "%s q", name_op);
+ log_printmpi (msg, mpi_q);
+ mpi_free (mpi_q);
+ }
+ if (!fips_mode () && ec->d)
+ {
+ snprintf (msg, sizeof msg, "%s d", name_op);
+ log_printmpi (msg, ec->d);
+ }
+ }
+
+ leave:
+ _gcry_ecc_curve_free (&E);
+ return errc;
+}
+
+/* This function creates a new context for elliptic curve operations.
+ Either KEYPARAM or CURVENAME must be given. If both are given and
+ KEYPARAM has no curve parameter, CURVENAME is used to add missing
+ parameters. On success 0 is returned and the new context stored at
+ R_CTX. On error NULL is stored at R_CTX and an error code is
+ returned. The context needs to be released using
+ gcry_ctx_release. */
+gpg_err_code_t
+_gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
+ gcry_sexp_t keyparam, const char *curvename)
+{
+ gpg_err_code_t errc;
+ elliptic_curve_t E;
+ gcry_ctx_t ctx = NULL;
+ int flags = 0;
+ mpi_ec_t ec;
+
+ *r_ctx = NULL;
+
+ memset (&E, 0, sizeof E);
+ errc = mpi_ec_get_elliptic_curve (&E, &flags, keyparam, curvename);
+ if (errc)
+ goto leave;
+
+ errc = _gcry_mpi_ec_p_new (&ctx, E.model, E.dialect, flags, E.p, E.a, E.b);
+ if (errc)
+ goto leave;
+
+ ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+ errc = mpi_ec_setup_elliptic_curve (ec, flags, &E, keyparam);
+ if (errc)
+ goto leave;
+
+ *r_ctx = ctx;
+ ctx = NULL;
+
+ leave:
+ _gcry_ecc_curve_free (&E);
+ _gcry_ctx_release (ctx);
+ return errc;
+}
+
+
+/* Return the parameters of the curve NAME as an S-expression. */
+gcry_sexp_t
+_gcry_ecc_get_param_sexp (const char *name)
+{
+ unsigned int nbits;
+ elliptic_curve_t E;
+ mpi_ec_t ctx;
+ gcry_mpi_t g_x, g_y;
+ gcry_mpi_t pkey[5];
+ gcry_sexp_t result;
+ int i;
+
+ memset (&E, 0, sizeof E);
+ if (_gcry_ecc_fill_in_curve (0, name, &E, &nbits))
+ return NULL;
+
+ g_x = mpi_new (0);
+ g_y = mpi_new (0);
+ ctx = _gcry_mpi_ec_p_internal_new (E.model,
+ E.dialect,
+ 0,
+ E.p, E.a, E.b);
+ if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
+ log_fatal ("ecc get param: Failed to get affine coordinates\n");
+ _gcry_mpi_ec_free (ctx);
+ _gcry_mpi_point_free_parts (&E.G);
+
+ pkey[0] = E.p;
+ pkey[1] = E.a;
+ pkey[2] = E.b;
+ pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p);
+ pkey[4] = E.n;
+
+ mpi_free (g_x);
+ mpi_free (g_y);
+
+ if (sexp_build (&result, NULL,
+ "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)))",
+ pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], E.h))
+ result = NULL;
+
+ for (i=0; i < DIM (pkey); i++)
+ _gcry_mpi_release (pkey[i]);
+
+ return result;
+}
+
+
+/* Return an MPI (or opaque MPI) described by NAME and the context EC.
+ If COPY is true a copy is returned, if not a const MPI may be
+ returned. In any case mpi_free must be used. */
+gcry_mpi_t
+_gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy)
+{
+ if (!*name)
+ return NULL;
+
+ if (!strcmp (name, "p") && ec->p)
+ return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p);
+ if (!strcmp (name, "a") && ec->a)
+ return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a);
+ if (!strcmp (name, "b") && ec->b)
+ return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b);
+ if (!strcmp (name, "n") && ec->n)
+ return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n);
+ if (!strcmp (name, "h"))
+ {
+ gcry_mpi_t h = _gcry_mpi_get_const (ec->h);
+
+ return !copy? h : mpi_set (NULL, h);
+ }
+ if (!strcmp (name, "d") && ec->d)
+ return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d);
+
+ /* Return a requested point coordinate. */
+ if (!strcmp (name, "g.x") && ec->G && ec->G->x)
+ return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x);
+ if (!strcmp (name, "g.y") && ec->G && ec->G->y)
+ return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y);
+ if (!strcmp (name, "q.x") && ec->Q && ec->Q->x)
+ return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x);
+ if (!strcmp (name, "q.y") && ec->Q && ec->Q->y)
+ return mpi_is_const (ec->Q->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y);
+
+ /* If the base point has been requested, return it in standard
+ encoding. */
+ if (!strcmp (name, "g") && ec->G)
+ return _gcry_mpi_ec_ec2os (ec->G, ec);
+
+ /* If the public key has been requested, return it by default in
+ standard uncompressed encoding or if requested in other
+ encodings. */
+ if (*name == 'q' && (!name[1] || name[1] == '@'))
+ {
+ /* If only the private key is given, compute the public key. */
+ if (!ec->Q)
+ ec->Q = _gcry_ecc_compute_public (NULL, ec);
+
+ if (!ec->Q)
+ return NULL;
+
+ if (name[1] != '@')
+ return _gcry_mpi_ec_ec2os (ec->Q, ec);
+
+ if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_EDWARDS)
+ {
+ unsigned char *encpk;
+ unsigned int encpklen;
+
+ if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0,
+ &encpk, &encpklen))
+ return mpi_set_opaque (NULL, encpk, encpklen*8);
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Return a point described by NAME and the context EC. */
+gcry_mpi_point_t
+_gcry_ecc_get_point (const char *name, mpi_ec_t ec)
+{
+ if (!strcmp (name, "g") && ec->G)
+ return point_copy (ec->G);
+ if (!strcmp (name, "q"))
+ {
+ /* If only the private key is given, compute the public key. */
+ if (!ec->Q)
+ ec->Q = _gcry_ecc_compute_public (NULL, ec);
+
+ if (ec->Q)
+ return point_copy (ec->Q);
+ }
+
+ return NULL;
+}
+
+
+/* Store the MPI NEWVALUE into the context EC under NAME. */
+gpg_err_code_t
+_gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec)
+{
+ gpg_err_code_t rc = 0;
+
+ if (!*name)
+ ;
+ else if (!strcmp (name, "p"))
+ {
+ mpi_free (ec->p);
+ ec->p = mpi_copy (newvalue);
+ _gcry_mpi_ec_get_reset (ec);
+ }
+ else if (!strcmp (name, "a"))
+ {
+ mpi_free (ec->a);
+ ec->a = mpi_copy (newvalue);
+ _gcry_mpi_ec_get_reset (ec);
+ }
+ else if (!strcmp (name, "b"))
+ {
+ mpi_free (ec->b);
+ ec->b = mpi_copy (newvalue);
+ }
+ else if (!strcmp (name, "n"))
+ {
+ mpi_free (ec->n);
+ ec->n = mpi_copy (newvalue);
+ }
+ else if (!strcmp (name, "h"))
+ {
+ mpi_get_ui (&ec->h, newvalue);
+ }
+ else if (*name == 'q' && (!name[1] || name[1] == '@'))
+ {
+ if (newvalue)
+ {
+ if (!ec->Q)
+ ec->Q = mpi_point_new (0);
+ rc = _gcry_mpi_ec_decode_point (ec->Q, newvalue, ec);
+ }
+ if (rc || !newvalue)
+ {
+ _gcry_mpi_point_release (ec->Q);
+ ec->Q = NULL;
+ }
+ /* Note: We assume that Q matches d and thus do not reset d. */
+ }
+ else if (!strcmp (name, "d"))
+ {
+ mpi_free (ec->d);
+ ec->d = mpi_copy (newvalue);
+ if (ec->d)
+ {
+ /* We need to reset the public key because it may not
+ anymore match. */
+ _gcry_mpi_point_release (ec->Q);
+ ec->Q = NULL;
+ }
+ }
+ else
+ rc = GPG_ERR_UNKNOWN_NAME;
+
+ return rc;
+}
+
+
+/* Store the point NEWVALUE into the context EC under NAME. */
+gpg_err_code_t
+_gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec)
+{
+ if (!strcmp (name, "g"))
+ {
+ _gcry_mpi_point_release (ec->G);
+ ec->G = point_copy (newvalue);
+ }
+ else if (!strcmp (name, "q"))
+ {
+ _gcry_mpi_point_release (ec->Q);
+ ec->Q = point_copy (newvalue);
+ }
+ else
+ return GPG_ERR_UNKNOWN_NAME;
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/ecc-ecdh.c b/comm/third_party/libgcrypt/cipher/ecc-ecdh.c
new file mode 100644
index 0000000000..d6b8991af6
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc-ecdh.c
@@ -0,0 +1,127 @@
+/* ecc-ecdh.c - Elliptic Curve Diffie-Hellman key agreement
+ * Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ecc-common.h"
+
+#define ECC_CURVE25519_BYTES 32
+#define ECC_CURVE448_BYTES 56
+
+static gpg_err_code_t
+prepare_ec (mpi_ec_t *r_ec, const char *name)
+{
+ int flags = 0;
+
+ if (!strcmp (name, "Curve25519"))
+ flags = PUBKEY_FLAG_DJB_TWEAK;
+
+ return _gcry_mpi_ec_internal_new (r_ec, &flags, "ecc_mul_point", NULL, name);
+}
+
+unsigned int
+_gcry_ecc_get_algo_keylen (int curveid)
+{
+ unsigned int len = 0;
+
+ if (curveid == GCRY_ECC_CURVE25519)
+ len = ECC_CURVE25519_BYTES;
+ else if (curveid == GCRY_ECC_CURVE448)
+ len = ECC_CURVE448_BYTES;
+
+ return len;
+}
+
+gpg_error_t
+_gcry_ecc_mul_point (int curveid, unsigned char *result,
+ const unsigned char *scalar, const unsigned char *point)
+{
+ unsigned int nbits;
+ unsigned int nbytes;
+ const char *curve;
+ gpg_err_code_t err;
+ gcry_mpi_t mpi_k;
+ mpi_ec_t ec;
+ mpi_point_struct Q;
+ gcry_mpi_t x;
+ unsigned int len;
+ unsigned char *buf;
+
+ if (curveid == GCRY_ECC_CURVE25519)
+ curve = "Curve25519";
+ else if (curveid == GCRY_ECC_CURVE448)
+ curve = "X448";
+ else
+ return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+
+ err = prepare_ec (&ec, curve);
+ if (err)
+ return err;
+
+ nbits = ec->nbits;
+ nbytes = (nbits + 7)/8;
+
+ mpi_k = _gcry_mpi_set_opaque_copy (NULL, scalar, nbytes*8);
+ x = mpi_new (nbits);
+ point_init (&Q);
+
+ if (point)
+ {
+ gcry_mpi_t mpi_u = _gcry_mpi_set_opaque_copy (NULL, point, nbytes*8);
+ mpi_point_struct P;
+
+ point_init (&P);
+ err = _gcry_ecc_mont_decodepoint (mpi_u, ec, &P);
+ _gcry_mpi_release (mpi_u);
+ if (err)
+ goto leave;
+ _gcry_mpi_ec_mul_point (&Q, mpi_k, &P, ec);
+ point_free (&P);
+ }
+ else
+ _gcry_mpi_ec_mul_point (&Q, mpi_k, ec->G, ec);
+
+ _gcry_mpi_ec_get_affine (x, NULL, &Q, ec);
+
+ buf = _gcry_mpi_get_buffer (x, nbytes, &len, NULL);
+ if (!buf)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ memcpy (result, buf, nbytes);
+ xfree (buf);
+ }
+
+ leave:
+ _gcry_mpi_release (x);
+ point_free (&Q);
+ _gcry_mpi_release (mpi_k);
+ _gcry_mpi_ec_free (ec);
+ return err;
+}
diff --git a/comm/third_party/libgcrypt/cipher/ecc-ecdsa.c b/comm/third_party/libgcrypt/cipher/ecc-ecdsa.c
new file mode 100644
index 0000000000..30103f1417
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc-ecdsa.c
@@ -0,0 +1,248 @@
+/* ecc-ecdsa.c - Elliptic Curve ECDSA signatures
+ * Copyright (C) 2007, 2008, 2010, 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "pubkey-internal.h"
+#include "ecc-common.h"
+
+
+/* Compute an ECDSA signature.
+ * Return the signature struct (r,s) from the message hash. The caller
+ * must have allocated R and S.
+ */
+gpg_err_code_t
+_gcry_ecc_ecdsa_sign (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s,
+ int flags, int hashalgo)
+{
+ gpg_err_code_t rc = 0;
+ int extraloops = 0;
+ gcry_mpi_t k, dr, sum, k_1, x;
+ mpi_point_struct I;
+ gcry_mpi_t hash;
+ const void *abuf;
+ unsigned int abits, qbits;
+ gcry_mpi_t b; /* Random number needed for blinding. */
+ gcry_mpi_t bi; /* multiplicative inverse of B. */
+
+ if (DBG_CIPHER)
+ log_mpidump ("ecdsa sign hash ", input );
+
+ qbits = mpi_get_nbits (ec->n);
+
+ /* Convert the INPUT into an MPI if needed. */
+ rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+ if (rc)
+ return rc;
+
+ b = mpi_snew (qbits);
+ bi = mpi_snew (qbits);
+ do
+ {
+ _gcry_mpi_randomize (b, qbits, GCRY_WEAK_RANDOM);
+ mpi_mod (b, b, ec->n);
+ }
+ while (!mpi_invm (bi, b, ec->n));
+
+ k = NULL;
+ dr = mpi_alloc (0);
+ sum = mpi_alloc (0);
+ k_1 = mpi_alloc (0);
+ x = mpi_alloc (0);
+ point_init (&I);
+
+ /* Two loops to avoid R or S are zero. This is more of a joke than
+ a real demand because the probability of them being zero is less
+ than any hardware failure. Some specs however require it. */
+ do
+ {
+ do
+ {
+ mpi_free (k);
+ k = NULL;
+ if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
+ {
+ /* Use Pornin's method for deterministic DSA. If this
+ flag is set, it is expected that HASH is an opaque
+ MPI with the to be signed hash. That hash is also
+ used as h1 from 3.2.a. */
+ if (!mpi_is_opaque (input))
+ {
+ rc = GPG_ERR_CONFLICT;
+ goto leave;
+ }
+
+ abuf = mpi_get_opaque (input, &abits);
+ rc = _gcry_dsa_gen_rfc6979_k (&k, ec->n, ec->d,
+ abuf, (abits+7)/8,
+ hashalgo, extraloops);
+ if (rc)
+ goto leave;
+ extraloops++;
+ }
+ else
+ k = _gcry_dsa_gen_k (ec->n, GCRY_STRONG_RANDOM);
+
+ mpi_invm (k_1, k, ec->n); /* k_1 = k^(-1) mod n */
+
+ _gcry_dsa_modify_k (k, ec->n, qbits);
+
+ _gcry_mpi_ec_mul_point (&I, k, ec->G, ec);
+ if (_gcry_mpi_ec_get_affine (x, NULL, &I, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc sign: Failed to get affine coordinates\n");
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ mpi_mod (r, x, ec->n); /* r = x mod n */
+ }
+ while (!mpi_cmp_ui (r, 0));
+
+ /* Computation of dr, sum, and s are blinded with b. */
+ mpi_mulm (dr, b, ec->d, ec->n);
+ mpi_mulm (dr, dr, r, ec->n); /* dr = d*r mod n */
+ mpi_mulm (sum, b, hash, ec->n);
+ mpi_addm (sum, sum, dr, ec->n); /* sum = hash + (d*r) mod n */
+ mpi_mulm (s, k_1, sum, ec->n); /* s = k^(-1)*(hash+(d*r)) mod n */
+ /* Undo blinding by b^-1 */
+ mpi_mulm (s, bi, s, ec->n);
+ }
+ while (!mpi_cmp_ui (s, 0));
+
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("ecdsa sign result r ", r);
+ log_mpidump ("ecdsa sign result s ", s);
+ }
+
+ leave:
+ mpi_free (b);
+ mpi_free (bi);
+ point_free (&I);
+ mpi_free (x);
+ mpi_free (k_1);
+ mpi_free (sum);
+ mpi_free (dr);
+ mpi_free (k);
+
+ if (hash != input)
+ mpi_free (hash);
+
+ return rc;
+}
+
+
+/* Verify an ECDSA signature.
+ * Check if R and S verifies INPUT.
+ */
+gpg_err_code_t
+_gcry_ecc_ecdsa_verify (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s)
+{
+ gpg_err_code_t err = 0;
+ gcry_mpi_t hash, h, h1, h2, x;
+ mpi_point_struct Q, Q1, Q2;
+ unsigned int nbits;
+
+ if (!_gcry_mpi_ec_curve_point (ec->Q, ec))
+ return GPG_ERR_BROKEN_PUBKEY;
+
+ if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, ec->n) < 0) )
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */
+ if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, ec->n) < 0) )
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */
+
+ nbits = mpi_get_nbits (ec->n);
+ err = _gcry_dsa_normalize_hash (input, &hash, nbits);
+ if (err)
+ return err;
+
+ h = mpi_alloc (0);
+ h1 = mpi_alloc (0);
+ h2 = mpi_alloc (0);
+ x = mpi_alloc (0);
+ point_init (&Q);
+ point_init (&Q1);
+ point_init (&Q2);
+
+ /* h = s^(-1) (mod n) */
+ mpi_invm (h, s, ec->n);
+ /* h1 = hash * s^(-1) (mod n) */
+ mpi_mulm (h1, hash, h, ec->n);
+ /* Q1 = [ hash * s^(-1) ]G */
+ _gcry_mpi_ec_mul_point (&Q1, h1, ec->G, ec);
+ /* h2 = r * s^(-1) (mod n) */
+ mpi_mulm (h2, r, h, ec->n);
+ /* Q2 = [ r * s^(-1) ]Q */
+ _gcry_mpi_ec_mul_point (&Q2, h2, ec->Q, ec);
+ /* Q = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
+ _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ec);
+
+ if (!mpi_cmp_ui (Q.z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc verify: Rejected\n");
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc verify: Failed to get affine coordinates\n");
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ mpi_mod (x, x, ec->n); /* x = x mod E_n */
+ if (mpi_cmp (x, r)) /* x != r */
+ {
+ if (DBG_CIPHER)
+ {
+ log_mpidump (" x", x);
+ log_mpidump (" r", r);
+ log_mpidump (" s", s);
+ }
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ leave:
+ point_free (&Q2);
+ point_free (&Q1);
+ point_free (&Q);
+ mpi_free (x);
+ mpi_free (h2);
+ mpi_free (h1);
+ mpi_free (h);
+ if (hash != input)
+ mpi_free (hash);
+
+ return err;
+}
diff --git a/comm/third_party/libgcrypt/cipher/ecc-eddsa.c b/comm/third_party/libgcrypt/cipher/ecc-eddsa.c
new file mode 100644
index 0000000000..2a1a89073c
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc-eddsa.c
@@ -0,0 +1,1182 @@
+/* ecc-eddsa.c - Elliptic Curve EdDSA signatures
+ * Copyright (C) 2013, 2014 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ecc-common.h"
+
+
+
+void
+reverse_buffer (unsigned char *buffer, unsigned int length)
+{
+ unsigned int tmp, i;
+
+ for (i=0; i < length/2; i++)
+ {
+ tmp = buffer[i];
+ buffer[i] = buffer[length-1-i];
+ buffer[length-1-i] = tmp;
+ }
+}
+
+
+/* Helper to scan a hex string. */
+static gcry_mpi_t
+scanval (const char *string)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t val;
+
+ rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (rc)
+ log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc));
+ return val;
+}
+
+
+
+/* Encode MPI using the EdDSA scheme. MINLEN specifies the required
+ length of the buffer in bytes. On success 0 is returned an a
+ malloced buffer with the encoded point is stored at R_BUFFER; the
+ length of this buffer is stored at R_BUFLEN. */
+static gpg_err_code_t
+eddsa_encodempi (gcry_mpi_t mpi, unsigned int nbits,
+ unsigned char **r_buffer, unsigned int *r_buflen)
+{
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+ unsigned int minlen = (nbits%8) == 0 ? (nbits/8 + 1): (nbits+7)/8;
+
+ rawmpi = _gcry_mpi_get_buffer (mpi, minlen, &rawmpilen, NULL);
+ if (!rawmpi)
+ return gpg_err_code_from_syserror ();
+
+ *r_buffer = rawmpi;
+ *r_buflen = rawmpilen;
+ return 0;
+}
+
+
+/* Encode (X,Y) using the EdDSA scheme. NBITS is the number of bits
+ of the field of the curve. If WITH_PREFIX is set the returned
+ buffer is prefixed with a 0x40 byte. On success 0 is returned and
+ a malloced buffer with the encoded point is stored at R_BUFFER; the
+ length of this buffer is stored at R_BUFLEN. */
+static gpg_err_code_t
+eddsa_encode_x_y (gcry_mpi_t x, gcry_mpi_t y, unsigned int nbits,
+ int with_prefix,
+ unsigned char **r_buffer, unsigned int *r_buflen)
+{
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+ int off = with_prefix? 1:0;
+ unsigned int minlen = (nbits%8) == 0 ? (nbits/8 + 1): (nbits+7)/8;
+
+ rawmpi = _gcry_mpi_get_buffer_extra (y, minlen, off?-1:0, &rawmpilen, NULL);
+ if (!rawmpi)
+ return gpg_err_code_from_syserror ();
+ if (mpi_test_bit (x, 0) && rawmpilen)
+ rawmpi[off + rawmpilen - 1] |= 0x80; /* Set sign bit. */
+ if (off)
+ rawmpi[0] = 0x40;
+
+ *r_buffer = rawmpi;
+ *r_buflen = rawmpilen + off;
+ return 0;
+}
+
+/* Encode POINT using the EdDSA scheme. X and Y are either scratch
+ variables supplied by the caller or NULL. CTX is the usual
+ context. If WITH_PREFIX is set the returned buffer is prefixed
+ with a 0x40 byte. On success 0 is returned and a malloced buffer
+ with the encoded point is stored at R_BUFFER; the length of this
+ buffer is stored at R_BUFLEN. */
+gpg_err_code_t
+_gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ec,
+ gcry_mpi_t x_in, gcry_mpi_t y_in,
+ int with_prefix,
+ unsigned char **r_buffer, unsigned int *r_buflen)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t x, y;
+
+ x = x_in? x_in : mpi_new (0);
+ y = y_in? y_in : mpi_new (0);
+
+ if (_gcry_mpi_ec_get_affine (x, y, point, ec))
+ {
+ log_error ("eddsa_encodepoint: Failed to get affine coordinates\n");
+ rc = GPG_ERR_INTERNAL;
+ }
+ else
+ rc = eddsa_encode_x_y (x, y, ec->nbits, with_prefix, r_buffer, r_buflen);
+
+ if (!x_in)
+ mpi_free (x);
+ if (!y_in)
+ mpi_free (y);
+ return rc;
+}
+
+
+/* Make sure that the opaque MPI VALUE is in compact EdDSA format.
+ This function updates MPI if needed. */
+gpg_err_code_t
+_gcry_ecc_eddsa_ensure_compact (gcry_mpi_t value, unsigned int nbits)
+{
+ gpg_err_code_t rc;
+ const unsigned char *buf;
+ unsigned int rawmpilen;
+ gcry_mpi_t x, y;
+ unsigned char *enc;
+ unsigned int enclen;
+
+ if (!mpi_is_opaque (value))
+ return GPG_ERR_INV_OBJ;
+ buf = mpi_get_opaque (value, &rawmpilen);
+ if (!buf)
+ return GPG_ERR_INV_OBJ;
+ rawmpilen = (rawmpilen + 7)/8;
+
+ if (rawmpilen > 1 && (rawmpilen%2))
+ {
+ if (buf[0] == 0x04)
+ {
+ /* Buffer is in SEC1 uncompressed format. Extract y and
+ compress. */
+ rc = _gcry_mpi_scan (&x, GCRYMPI_FMT_USG,
+ buf+1, (rawmpilen-1)/2, NULL);
+ if (rc)
+ return rc;
+ rc = _gcry_mpi_scan (&y, GCRYMPI_FMT_USG,
+ buf+1+(rawmpilen-1)/2, (rawmpilen-1)/2, NULL);
+ if (rc)
+ {
+ mpi_free (x);
+ return rc;
+ }
+
+ rc = eddsa_encode_x_y (x, y, nbits, 0, &enc, &enclen);
+ mpi_free (x);
+ mpi_free (y);
+ if (rc)
+ return rc;
+
+ mpi_set_opaque (value, enc, 8*enclen);
+ }
+ else if (buf[0] == 0x40)
+ {
+ /* Buffer is compressed but with our SEC1 alike compression
+ indicator. Remove that byte. FIXME: We should write and
+ use a function to manipulate an opaque MPI in place. */
+ if (!_gcry_mpi_set_opaque_copy (value, buf + 1, (rawmpilen - 1)*8))
+ return gpg_err_code_from_syserror ();
+ }
+ }
+
+ return 0;
+}
+
+
+static gpg_err_code_t
+ecc_ed448_recover_x (gcry_mpi_t x, gcry_mpi_t y, int x_0, mpi_ec_t ec)
+{
+ gpg_err_code_t rc = 0;
+ gcry_mpi_t u, v, u3, v3, t;
+ static gcry_mpi_t p34; /* Hard coded (P-3)/4 */
+
+ if (mpi_cmp (y, ec->p) >= 0)
+ rc = GPG_ERR_INV_OBJ;
+
+ if (!p34)
+ p34 = scanval ("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+
+ u = mpi_new (0);
+ v = mpi_new (0);
+ u3 = mpi_new (0);
+ v3 = mpi_new (0);
+ t = mpi_new (0);
+
+ /* Compute u and v */
+ /* u = y^2 */
+ mpi_mulm (u, y, y, ec->p);
+ /* v = b*y^2 */
+ mpi_mulm (v, ec->b, u, ec->p);
+ /* u = y^2-1 */
+ mpi_sub_ui (u, u, 1);
+ /* v = b*y^2-1 */
+ mpi_sub_ui (v, v, 1);
+
+ /* Compute sqrt(u/v) */
+ /* u3 = u^3 */
+ mpi_powm (u3, u, mpi_const (MPI_C_THREE), ec->p);
+ mpi_powm (v3, v, mpi_const (MPI_C_THREE), ec->p);
+ /* t = u^4 * u * v3 = u^5 * v^3 */
+ mpi_powm (t, u, mpi_const (MPI_C_FOUR), ec->p);
+ mpi_mulm (t, t, u, ec->p);
+ mpi_mulm (t, t, v3, ec->p);
+ /* t = t^((p-3)/4) = (u^5 * v^3)^((p-3)/4) */
+ mpi_powm (t, t, p34, ec->p);
+ /* x = t * u^3 * v = (u^3 * v) * (u^5 * v^3)^((p-3)/4) */
+ mpi_mulm (t, t, u3, ec->p);
+ mpi_mulm (x, t, v, ec->p);
+
+ /* t = v * x^2 */
+ mpi_mulm (t, x, x, ec->p);
+ mpi_mulm (t, t, v, ec->p);
+
+ if (mpi_cmp (t, u) != 0)
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ if (!mpi_cmp_ui (x, 0) && x_0)
+ rc = GPG_ERR_INV_OBJ;
+
+ /* Choose the desired square root according to parity */
+ if (mpi_test_bit (x, 0) != !!x_0)
+ mpi_sub (x, ec->p, x);
+ }
+
+ mpi_free (t);
+ mpi_free (u3);
+ mpi_free (v3);
+ mpi_free (v);
+ mpi_free (u);
+
+ return rc;
+}
+
+
+/* Recover X from Y and SIGN (which actually is a parity bit). */
+gpg_err_code_t
+_gcry_ecc_eddsa_recover_x (gcry_mpi_t x, gcry_mpi_t y, int sign, mpi_ec_t ec)
+{
+ gpg_err_code_t rc = 0;
+ gcry_mpi_t u, v, v3, t;
+ static gcry_mpi_t p58, seven;
+
+ /*
+ * This routine is actually curve specific. Now, only supports
+ * Ed25519 and Ed448.
+ */
+
+ if (ec->dialect != ECC_DIALECT_ED25519)
+ /* For now, it's only Ed448. */
+ return ecc_ed448_recover_x (x, y, sign, ec);
+
+ /* It's Ed25519. */
+
+ if (!p58)
+ p58 = scanval ("0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD");
+ if (!seven)
+ seven = mpi_set_ui (NULL, 7);
+
+ u = mpi_new (0);
+ v = mpi_new (0);
+ v3 = mpi_new (0);
+ t = mpi_new (0);
+
+ /* Compute u and v */
+ /* u = y^2 */
+ mpi_mulm (u, y, y, ec->p);
+ /* v = b*y^2 */
+ mpi_mulm (v, ec->b, u, ec->p);
+ /* u = y^2-1 */
+ mpi_sub_ui (u, u, 1);
+ /* v = b*y^2+1 */
+ mpi_add_ui (v, v, 1);
+
+ /* Compute sqrt(u/v) */
+ /* v3 = v^3 */
+ mpi_powm (v3, v, mpi_const (MPI_C_THREE), ec->p);
+ /* t = v3 * v3 * u * v = u * v^7 */
+ mpi_powm (t, v, seven, ec->p);
+ mpi_mulm (t, t, u, ec->p);
+ /* t = t^((p-5)/8) = (u * v^7)^((p-5)/8) */
+ mpi_powm (t, t, p58, ec->p);
+ /* x = t * u * v^3 = (u * v^3) * (u * v^7)^((p-5)/8) */
+ mpi_mulm (t, t, u, ec->p);
+ mpi_mulm (x, t, v3, ec->p);
+
+ /* Adjust if needed. */
+ /* t = v * x^2 */
+ mpi_mulm (t, x, x, ec->p);
+ mpi_mulm (t, t, v, ec->p);
+ /* -t == u ? x = x * sqrt(-1) */
+ mpi_sub (t, ec->p, t);
+ if (!mpi_cmp (t, u))
+ {
+ static gcry_mpi_t m1; /* Fixme: this is not thread-safe. */
+ if (!m1)
+ m1 = scanval ("2B8324804FC1DF0B2B4D00993DFBD7A7"
+ "2F431806AD2FE478C4EE1B274A0EA0B0");
+ mpi_mulm (x, x, m1, ec->p);
+ /* t = v * x^2 */
+ mpi_mulm (t, x, x, ec->p);
+ mpi_mulm (t, t, v, ec->p);
+ /* -t == u ? x = x * sqrt(-1) */
+ mpi_sub (t, ec->p, t);
+ if (!mpi_cmp (t, u))
+ rc = GPG_ERR_INV_OBJ;
+ }
+
+ /* Choose the desired square root according to parity */
+ if (mpi_test_bit (x, 0) != !!sign)
+ mpi_sub (x, ec->p, x);
+
+ mpi_free (t);
+ mpi_free (v3);
+ mpi_free (v);
+ mpi_free (u);
+
+ return rc;
+}
+
+
+/* Decode the EdDSA style encoded PK and set it into RESULT. CTX is
+ the usual curve context. If R_ENCPK is not NULL, the encoded PK is
+ stored at that address; this is a new copy to be released by the
+ caller. In contrast to the supplied PK, this is not an MPI and
+ thus guaranteed to be properly padded. R_ENCPKLEN receives the
+ length of that encoded key. */
+gpg_err_code_t
+_gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result,
+ unsigned char **r_encpk, unsigned int *r_encpklen)
+{
+ gpg_err_code_t rc;
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+ int sign;
+
+ if (mpi_is_opaque (pk))
+ {
+ const unsigned char *buf;
+ unsigned int len;
+
+ len = (ctx->nbits%8) == 0 ? (ctx->nbits/8 + 1): (ctx->nbits+7)/8;
+
+ buf = mpi_get_opaque (pk, &rawmpilen);
+ if (!buf)
+ return GPG_ERR_INV_OBJ;
+ rawmpilen = (rawmpilen + 7)/8;
+
+ if (!(rawmpilen == len
+ || rawmpilen == len + 1
+ || rawmpilen == len * 2 + 1))
+ return GPG_ERR_INV_OBJ;
+
+ /* Handle compression prefixes. The size of the buffer will be
+ odd in this case. */
+ if (rawmpilen > 1 && (rawmpilen == len + 1 || rawmpilen == len * 2 + 1))
+ {
+ /* First check whether the public key has been given in
+ standard uncompressed format (SEC1). No need to recover
+ x in this case. */
+ if (buf[0] == 0x04)
+ {
+ gcry_mpi_t x, y;
+
+ rc = _gcry_mpi_scan (&x, GCRYMPI_FMT_USG,
+ buf+1, (rawmpilen-1)/2, NULL);
+ if (rc)
+ return rc;
+ rc = _gcry_mpi_scan (&y, GCRYMPI_FMT_USG,
+ buf+1+(rawmpilen-1)/2, (rawmpilen-1)/2,NULL);
+ if (rc)
+ {
+ mpi_free (x);
+ return rc;
+ }
+
+ if (r_encpk)
+ {
+ rc = eddsa_encode_x_y (x, y, ctx->nbits, 0,
+ r_encpk, r_encpklen);
+ if (rc)
+ {
+ mpi_free (x);
+ mpi_free (y);
+ return rc;
+ }
+ }
+ mpi_snatch (result->x, x);
+ mpi_snatch (result->y, y);
+ mpi_set_ui (result->z, 1);
+ return 0;
+ }
+
+ /* Check whether the public key has been prefixed with a 0x40
+ byte to explicitly indicate compressed format using a SEC1
+ alike prefix byte. This is a Libgcrypt extension. */
+ if (buf[0] == 0x40)
+ {
+ rawmpilen--;
+ buf++;
+ }
+ }
+
+ /* EdDSA compressed point. */
+ rawmpi = xtrymalloc (rawmpilen);
+ if (!rawmpi)
+ return gpg_err_code_from_syserror ();
+ memcpy (rawmpi, buf, rawmpilen);
+ reverse_buffer (rawmpi, rawmpilen);
+ }
+ else
+ {
+ /* Note: Without using an opaque MPI it is not reliable possible
+ to find out whether the public key has been given in
+ uncompressed format. Thus we expect native EdDSA format. */
+ rawmpi = _gcry_mpi_get_buffer (pk, (ctx->nbits+7)/8, &rawmpilen, NULL);
+ if (!rawmpi)
+ return gpg_err_code_from_syserror ();
+ }
+
+ if (rawmpilen)
+ {
+ sign = !!(rawmpi[0] & 0x80);
+ rawmpi[0] &= 0x7f;
+ }
+ else
+ sign = 0;
+ _gcry_mpi_set_buffer (result->y, rawmpi, rawmpilen, 0);
+ if (r_encpk)
+ {
+ /* Revert to little endian. */
+ if (sign && rawmpilen)
+ rawmpi[0] |= 0x80;
+ reverse_buffer (rawmpi, rawmpilen);
+ *r_encpk = rawmpi;
+ if (r_encpklen)
+ *r_encpklen = rawmpilen;
+ }
+ else
+ xfree (rawmpi);
+
+ rc = _gcry_ecc_eddsa_recover_x (result->x, result->y, sign, ctx);
+ mpi_set_ui (result->z, 1);
+
+ return rc;
+}
+
+
+/* Compute the A value as used by EdDSA. The caller needs to provide
+ the context EC and the actual secret D as an MPI. The function
+ returns a newly allocated 64 byte buffer at r_digest; the first 32
+ bytes represent the A value. NULL is returned on error and NULL
+ stored at R_DIGEST. */
+gpg_err_code_t
+_gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest, mpi_ec_t ec)
+{
+ gpg_err_code_t rc;
+ unsigned char *rawmpi = NULL;
+ unsigned int rawmpilen;
+ unsigned char *digest;
+ int hashalgo, b;
+
+ *r_digest = NULL;
+
+ b = (ec->nbits+7)/8;
+
+ /*
+ * Choice of hashalgo is curve specific.
+ * For now, it's determine by the bit size of the field.
+ */
+ if (ec->nbits == 255)
+ hashalgo = GCRY_MD_SHA512;
+ else if (ec->nbits == 448)
+ {
+ b++;
+ hashalgo = GCRY_MD_SHAKE256;
+ }
+ else
+ return GPG_ERR_NOT_IMPLEMENTED;
+
+ /* Note that we clear DIGEST so we can use it as input to left pad
+ the key with zeroes for hashing. */
+ digest = xtrycalloc_secure (2, b);
+ if (!digest)
+ return gpg_err_code_from_syserror ();
+
+ rawmpi = _gcry_mpi_get_buffer (ec->d, 0, &rawmpilen, NULL);
+ if (!rawmpi)
+ {
+ xfree (digest);
+ return gpg_err_code_from_syserror ();
+ }
+
+ if (hashalgo == GCRY_MD_SHAKE256)
+ {
+ gcry_error_t err;
+ gcry_md_hd_t hd;
+
+ err = _gcry_md_open (&hd, hashalgo, 0);
+ if (err)
+ rc = gcry_err_code (err);
+ else
+ {
+ _gcry_md_write (hd, rawmpi, rawmpilen);
+ _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+ _gcry_md_extract (hd, GCRY_MD_SHAKE256, digest, 2*b);
+ _gcry_md_close (hd);
+ rc = 0;
+ }
+ }
+ else
+ {
+ gcry_buffer_t hvec[2];
+
+ memset (hvec, 0, sizeof hvec);
+
+ hvec[0].data = digest;
+ hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
+ hvec[1].data = rawmpi;
+ hvec[1].len = rawmpilen;
+ rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
+ }
+
+ xfree (rawmpi);
+ if (rc)
+ {
+ xfree (digest);
+ return rc;
+ }
+
+ /* Compute the A value. */
+ reverse_buffer (digest, b); /* Only the first half of the hash. */
+
+ /* Field specific handling of clearing/setting bits. */
+ if (ec->nbits == 255)
+ {
+ digest[0] = (digest[0] & 0x7f) | 0x40;
+ digest[31] &= 0xf8;
+ }
+ else
+ {
+ digest[0] = 0;
+ digest[1] |= 0x80;
+ digest[56] &= 0xfc;
+ }
+
+ *r_digest = digest;
+ return 0;
+}
+
+
+/**
+ * _gcry_ecc_eddsa_genkey - EdDSA version of the key generation.
+ *
+ * @ec: Elliptic curve computation context.
+ * @flags: Flags controlling aspects of the creation.
+ *
+ * Return: An error code.
+ *
+ * The only @flags bit used by this function is %PUBKEY_FLAG_TRANSIENT
+ * to use a faster RNG.
+ */
+gpg_err_code_t
+_gcry_ecc_eddsa_genkey (mpi_ec_t ec, int flags)
+{
+ gpg_err_code_t rc;
+ int b;
+ gcry_mpi_t a, x, y;
+ mpi_point_struct Q;
+ gcry_random_level_t random_level;
+ char *dbuf;
+ size_t dlen;
+ unsigned char *hash_d = NULL;
+
+ point_init (&Q);
+
+ if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
+ random_level = GCRY_STRONG_RANDOM;
+ else
+ random_level = GCRY_VERY_STRONG_RANDOM;
+
+ b = (ec->nbits+7)/8;
+
+ if (ec->nbits == 255)
+ ;
+ else if (ec->nbits == 448)
+ b++;
+ else
+ return GPG_ERR_NOT_IMPLEMENTED;
+
+ dlen = b;
+
+ a = mpi_snew (0);
+ x = mpi_new (0);
+ y = mpi_new (0);
+
+ /* Generate a secret. */
+ dbuf = _gcry_random_bytes_secure (dlen, random_level);
+ ec->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8);
+ rc = _gcry_ecc_eddsa_compute_h_d (&hash_d, ec);
+ if (rc)
+ goto leave;
+
+ _gcry_mpi_set_buffer (a, hash_d, b, 0);
+ xfree (hash_d);
+ /* log_printmpi ("ecgen a", a); */
+
+ /* Compute Q. */
+ _gcry_mpi_ec_mul_point (&Q, a, ec->G, ec);
+ if (DBG_CIPHER)
+ log_printpnt ("ecgen pk", &Q, ec);
+
+ ec->Q = mpi_point_snatch_set (NULL, Q.x, Q.y, Q.z);
+ Q.x = NULL;
+ Q.y = NULL;
+ Q.x = NULL;
+
+ leave:
+ _gcry_mpi_release (a);
+ _gcry_mpi_release (x);
+ _gcry_mpi_release (y);
+ return rc;
+}
+
+
+/* Compute an EdDSA signature. See:
+ * [ed25519] 23pp. (PDF) Daniel J. Bernstein, Niels Duif, Tanja
+ * Lange, Peter Schwabe, Bo-Yin Yang. High-speed high-security
+ * signatures. Journal of Cryptographic Engineering 2 (2012), 77-89.
+ * Document ID: a1a62a2f76d23f65d622484ddd09caf8.
+ * URL: http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
+ *
+ * Despite that this function requires the specification of a hash
+ * algorithm, we only support what has been specified by the paper.
+ * This may change in the future.
+ *
+ * Return the signature struct (r,s) from the message hash. The caller
+ * must have allocated R_R and S.
+ */
+
+/* String to be used with Ed448 */
+#define DOM25519 "SigEd25519 no Ed25519 collisions"
+#define DOM25519_LEN 32
+#define DOM448 "SigEd448"
+#define DOM448_LEN 8
+
+gpg_err_code_t
+_gcry_ecc_eddsa_sign (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r_r, gcry_mpi_t s,
+ struct pk_encoding_ctx *ctx)
+{
+ int rc;
+ unsigned int tmp;
+ unsigned char *digest = NULL;
+ const void *mbuf;
+ size_t mlen;
+ unsigned char *rawmpi = NULL;
+ unsigned int rawmpilen;
+ unsigned char *encpk = NULL; /* Encoded public key. */
+ unsigned int encpklen;
+ mpi_point_struct I; /* Intermediate value. */
+ gcry_mpi_t a, x, y, r;
+ int b;
+ unsigned char x_olen[2];
+ unsigned char prehashed_msg[64];
+
+ b = (ec->nbits+7)/8;
+
+ if (ec->nbits == 255)
+ ;
+ else if (ec->nbits == 448)
+ b++;
+ else
+ return GPG_ERR_NOT_IMPLEMENTED;
+
+ if (!mpi_is_opaque (input))
+ return GPG_ERR_INV_DATA;
+
+ /* Initialize some helpers. */
+ point_init (&I);
+ a = mpi_snew (0);
+ x = mpi_new (0);
+ y = mpi_new (0);
+ r = mpi_snew (0);
+
+ rc = _gcry_ecc_eddsa_compute_h_d (&digest, ec);
+ if (rc)
+ goto leave;
+ _gcry_mpi_set_buffer (a, digest, b, 0);
+
+ /* Compute the public key if it's not available (only secret part). */
+ if (ec->Q == NULL)
+ {
+ mpi_point_struct Q;
+
+ point_init (&Q);
+ _gcry_mpi_ec_mul_point (&Q, a, ec->G, ec);
+ ec->Q = mpi_point_snatch_set (NULL, Q.x, Q.y, Q.z);
+ }
+ rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, x, y, 0, &encpk, &encpklen);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_printhex (" e_pk", encpk, encpklen);
+
+ /* Compute R. */
+ mbuf = mpi_get_opaque (input, &tmp);
+ mlen = (tmp +7)/8;
+ if (DBG_CIPHER)
+ log_printhex (" m", mbuf, mlen);
+
+ if (ctx->hash_algo == GCRY_MD_SHAKE256)
+ {
+ gcry_error_t err;
+ gcry_md_hd_t hd;
+
+ err = _gcry_md_open (&hd, ctx->hash_algo, 0);
+ if (err)
+ rc = gcry_err_code (err);
+ else
+ {
+ _gcry_md_write (hd, DOM448, DOM448_LEN);
+ x_olen[0] = !!(ctx->flags & PUBKEY_FLAG_PREHASH);
+ x_olen[1] = ctx->labellen;
+ _gcry_md_write (hd, x_olen, 2);
+ if (ctx->labellen)
+ _gcry_md_write (hd, ctx->label, ctx->labellen);
+ _gcry_md_write (hd, digest+b, b);
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH))
+ {
+ gcry_md_hd_t hd2;
+
+ err = _gcry_md_open (&hd2, ctx->hash_algo, 0);
+ if (err)
+ {
+ rc = gcry_err_code (err);
+ _gcry_md_close (hd);
+ goto leave;
+ }
+ _gcry_md_write (hd2, mbuf, mlen);
+ _gcry_md_ctl (hd2, GCRYCTL_FINALIZE, NULL, 0);
+ _gcry_md_extract (hd2, GCRY_MD_SHAKE256, prehashed_msg, 64);
+ _gcry_md_close (hd2);
+ _gcry_md_write (hd, prehashed_msg, 64);
+ }
+ else
+ _gcry_md_write (hd, mbuf, mlen);
+ _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+ _gcry_md_extract (hd, GCRY_MD_SHAKE256, digest, 2*b);
+ _gcry_md_close (hd);
+ rc = 0;
+ }
+ }
+ else
+ {
+ gcry_buffer_t hvec[6];
+ int i = 0;
+
+ memset (hvec, 0, sizeof hvec);
+
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH) || ctx->labellen)
+ {
+ hvec[i].data = (void *)DOM25519;
+ hvec[i].len = DOM25519_LEN;
+ i++;
+ x_olen[0] = !!(ctx->flags & PUBKEY_FLAG_PREHASH);
+ x_olen[1] = ctx->labellen;
+ hvec[i].data = x_olen;
+ hvec[i].len = 2;
+ i++;
+ if (ctx->labellen)
+ {
+ hvec[i].data = ctx->label;
+ hvec[i].len = ctx->labellen;
+ i++;
+ }
+ }
+
+ hvec[i].data = digest;
+ hvec[i].off = b;
+ hvec[i].len = b;
+ i++;
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH))
+ {
+ _gcry_md_hash_buffer (ctx->hash_algo, prehashed_msg, mbuf, mlen);
+ hvec[i].data = (char*)prehashed_msg;
+ hvec[i].len = 64;
+ }
+ else
+ {
+ hvec[i].data = (char*)mbuf;
+ hvec[i].len = mlen;
+ }
+ i++;
+ rc = _gcry_md_hash_buffers (ctx->hash_algo, 0, digest, hvec, i);
+ }
+
+ if (rc)
+ goto leave;
+ reverse_buffer (digest, 2*b);
+ if (DBG_CIPHER)
+ log_printhex (" r", digest, 2*b);
+ _gcry_mpi_set_buffer (r, digest, 2*b, 0);
+ mpi_mod (r, r, ec->n);
+ _gcry_mpi_ec_mul_point (&I, r, ec->G, ec);
+ if (DBG_CIPHER)
+ log_printpnt (" r", &I, ec);
+
+ /* Convert R into affine coordinates and apply encoding. */
+ rc = _gcry_ecc_eddsa_encodepoint (&I, ec, x, y, 0, &rawmpi, &rawmpilen);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_printhex (" e_r", rawmpi, rawmpilen);
+
+ if (ctx->hash_algo == GCRY_MD_SHAKE256)
+ {
+ gcry_error_t err;
+ gcry_md_hd_t hd;
+
+ err = _gcry_md_open (&hd, ctx->hash_algo, 0);
+ if (err)
+ rc = gcry_err_code (err);
+ else
+ {
+ _gcry_md_write (hd, DOM448, DOM448_LEN);
+ x_olen[0] = !!(ctx->flags & PUBKEY_FLAG_PREHASH);
+ x_olen[1] = ctx->labellen;
+ _gcry_md_write (hd, x_olen, 2);
+ if (ctx->labellen)
+ _gcry_md_write (hd, ctx->label, ctx->labellen);
+ _gcry_md_write (hd, rawmpi, rawmpilen);
+ _gcry_md_write (hd, encpk, encpklen);
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH))
+ _gcry_md_write (hd, prehashed_msg, 64);
+ else
+ _gcry_md_write (hd, mbuf, mlen);
+ _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+ _gcry_md_extract (hd, GCRY_MD_SHAKE256, digest, 2*b);
+ _gcry_md_close (hd);
+ rc = 0;
+ }
+ }
+ else
+ {
+ gcry_buffer_t hvec[6];
+ int i = 0;
+
+ memset (hvec, 0, sizeof hvec);
+
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH) || ctx->labellen)
+ {
+ hvec[i].data = (void *)DOM25519;
+ hvec[i].len = DOM25519_LEN;
+ i++;
+ x_olen[0] = !!(ctx->flags & PUBKEY_FLAG_PREHASH);
+ x_olen[1] = ctx->labellen;
+ hvec[i].data = x_olen;
+ hvec[i].len = 2;
+ i++;
+ if (ctx->labellen)
+ {
+ hvec[i].data = ctx->label;
+ hvec[i].len = ctx->labellen;
+ i++;
+ }
+ }
+
+ /* S = r + a * H(dom2(F,C)+encodepoint(R)+encodepoint(pk)+m) mod n */
+ hvec[i].data = rawmpi; /* (this is R) */
+ hvec[i].len = rawmpilen;
+ i++;
+ hvec[i].data = encpk;
+ hvec[i].len = encpklen;
+ i++;
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH))
+ {
+ hvec[i].data = (char*)prehashed_msg;
+ hvec[i].len = 64;
+ }
+ else
+ {
+ hvec[i].data = (char*)mbuf;
+ hvec[i].len = mlen;
+ }
+ i++;
+ rc = _gcry_md_hash_buffers (ctx->hash_algo, 0, digest, hvec, i);
+ }
+
+ if (rc)
+ goto leave;
+
+ /* No more need for RAWMPI thus we now transfer it to R_R. */
+ mpi_set_opaque (r_r, rawmpi, rawmpilen*8);
+ rawmpi = NULL;
+
+ reverse_buffer (digest, 2*b);
+ if (DBG_CIPHER)
+ log_printhex (" H(R+)", digest, 2*b);
+ _gcry_mpi_set_buffer (s, digest, 2*b, 0);
+ mpi_mulm (s, s, a, ec->n);
+ mpi_addm (s, s, r, ec->n);
+ rc = eddsa_encodempi (s, ec->nbits, &rawmpi, &rawmpilen);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_printhex (" e_s", rawmpi, rawmpilen);
+ mpi_set_opaque (s, rawmpi, rawmpilen*8);
+ rawmpi = NULL;
+
+ rc = 0;
+
+ leave:
+ _gcry_mpi_release (a);
+ _gcry_mpi_release (x);
+ _gcry_mpi_release (y);
+ _gcry_mpi_release (r);
+ xfree (digest);
+ point_free (&I);
+ xfree (encpk);
+ xfree (rawmpi);
+ return rc;
+}
+
+
+/* Verify an EdDSA signature. See sign_eddsa for the reference.
+ * Check if R_IN and S_IN verifies INPUT.
+ */
+gpg_err_code_t
+_gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r_in, gcry_mpi_t s_in,
+ struct pk_encoding_ctx *ctx)
+{
+ int rc;
+ int b;
+ unsigned int tmp;
+ unsigned char *encpk = NULL; /* Encoded public key. */
+ unsigned int encpklen;
+ const void *mbuf, *rbuf;
+ unsigned char *tbuf = NULL;
+ size_t mlen, rlen;
+ unsigned int tlen;
+ unsigned char digest[114];
+ gcry_mpi_t h, s;
+ mpi_point_struct Ia, Ib;
+ unsigned char x_olen[2];
+ unsigned char prehashed_msg[64];
+
+ if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in))
+ return GPG_ERR_INV_DATA;
+
+ point_init (&Ia);
+ point_init (&Ib);
+ h = mpi_new (0);
+ s = mpi_new (0);
+
+ b = (ec->nbits+7)/8;
+
+ if (ec->nbits == 255)
+ ;
+ else if (ec->nbits == 448)
+ b++;
+ else
+ return GPG_ERR_NOT_IMPLEMENTED;
+
+ /* Encode and check the public key. */
+ rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0,
+ &encpk, &encpklen);
+ if (rc)
+ goto leave;
+ if (!_gcry_mpi_ec_curve_point (ec->Q, ec))
+ {
+ rc = GPG_ERR_BROKEN_PUBKEY;
+ goto leave;
+ }
+ if (DBG_CIPHER)
+ log_printhex (" e_pk", encpk, encpklen);
+ if (encpklen != b)
+ {
+ rc = GPG_ERR_INV_LENGTH;
+ goto leave;
+ }
+
+ /* Convert the other input parameters. */
+ mbuf = mpi_get_opaque (input, &tmp);
+ mlen = (tmp +7)/8;
+ if (DBG_CIPHER)
+ log_printhex (" m", mbuf, mlen);
+ rbuf = mpi_get_opaque (r_in, &tmp);
+ rlen = (tmp +7)/8;
+ if (DBG_CIPHER)
+ log_printhex (" r", rbuf, rlen);
+ if (rlen != b)
+ {
+ rc = GPG_ERR_INV_LENGTH;
+ goto leave;
+ }
+
+ if (ctx->hash_algo == GCRY_MD_SHAKE256)
+ {
+ gcry_error_t err;
+ gcry_md_hd_t hd;
+
+ err = _gcry_md_open (&hd, ctx->hash_algo, 0);
+ if (err)
+ rc = gcry_err_code (err);
+ else
+ {
+ _gcry_md_write (hd, DOM448, DOM448_LEN);
+ x_olen[0] = !!(ctx->flags & PUBKEY_FLAG_PREHASH);
+ x_olen[1] = ctx->labellen;
+ _gcry_md_write (hd, x_olen, 2);
+ if (ctx->labellen)
+ _gcry_md_write (hd, ctx->label, ctx->labellen);
+ _gcry_md_write (hd, rbuf, rlen);
+ _gcry_md_write (hd, encpk, encpklen);
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH))
+ {
+ gcry_md_hd_t hd2;
+
+ err = _gcry_md_open (&hd2, ctx->hash_algo, 0);
+ if (err)
+ {
+ rc = gcry_err_code (err);
+ _gcry_md_close (hd);
+ goto leave;
+ }
+ _gcry_md_write (hd2, mbuf, mlen);
+ _gcry_md_ctl (hd2, GCRYCTL_FINALIZE, NULL, 0);
+ _gcry_md_extract (hd2, GCRY_MD_SHAKE256, prehashed_msg, 64);
+ _gcry_md_close (hd2);
+ _gcry_md_write (hd, prehashed_msg, 64);
+ }
+ else
+ _gcry_md_write (hd, mbuf, mlen);
+ _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+ _gcry_md_extract (hd, GCRY_MD_SHAKE256, digest, 2*b);
+ _gcry_md_close (hd);
+ rc = 0;
+ }
+ }
+ else
+ {
+ gcry_buffer_t hvec[6];
+ int i = 0;
+
+ memset (hvec, 0, sizeof hvec);
+
+ /* h = H(dom2(F,C)+encodepoint(R)+encodepoint(pk)+m) */
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH) || ctx->labellen)
+ {
+ hvec[i].data = (void *)DOM25519;
+ hvec[i].len = DOM25519_LEN;
+ i++;
+ x_olen[0] = !!(ctx->flags & PUBKEY_FLAG_PREHASH);
+ x_olen[1] = ctx->labellen;
+ hvec[i].data = x_olen;
+ hvec[i].len = 2;
+ i++;
+ if (ctx->labellen)
+ {
+ hvec[i].data = ctx->label;
+ hvec[i].len = ctx->labellen;
+ i++;
+ }
+ }
+
+ hvec[i].data = (char*)rbuf;
+ hvec[i].len = rlen;
+ i++;
+ hvec[i].data = encpk;
+ hvec[i].len = encpklen;
+ i++;
+ if ((ctx->flags & PUBKEY_FLAG_PREHASH))
+ {
+ _gcry_md_hash_buffer (ctx->hash_algo, prehashed_msg, mbuf, mlen);
+ hvec[i].data = (char*)prehashed_msg;
+ hvec[i].len = 64;
+ }
+ else
+ {
+ hvec[i].data = (char*)mbuf;
+ hvec[i].len = mlen;
+ }
+ i++;
+ rc = _gcry_md_hash_buffers (ctx->hash_algo, 0, digest, hvec, i);
+ }
+
+ if (rc)
+ goto leave;
+ reverse_buffer (digest, 2*b);
+ if (DBG_CIPHER)
+ log_printhex (" H(R+)", digest, 2*b);
+ _gcry_mpi_set_buffer (h, digest, 2*b, 0);
+
+ /* According to the paper the best way for verification is:
+ encodepoint(sG - h·Q) = encodepoint(r)
+ because we don't need to decode R. */
+ {
+ void *sbuf;
+ unsigned int slen;
+
+ sbuf = _gcry_mpi_get_opaque_copy (s_in, &tmp);
+ slen = (tmp +7)/8;
+ reverse_buffer (sbuf, slen);
+ if (DBG_CIPHER)
+ log_printhex (" s", sbuf, slen);
+ _gcry_mpi_set_buffer (s, sbuf, slen, 0);
+ xfree (sbuf);
+ if (slen != b)
+ {
+ rc = GPG_ERR_INV_LENGTH;
+ goto leave;
+ }
+ }
+
+ _gcry_mpi_ec_mul_point (&Ia, s, ec->G, ec);
+ _gcry_mpi_ec_mul_point (&Ib, h, ec->Q, ec);
+ _gcry_mpi_sub (Ib.x, ec->p, Ib.x);
+ _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ec);
+ rc = _gcry_ecc_eddsa_encodepoint (&Ia, ec, s, h, 0, &tbuf, &tlen);
+ if (rc)
+ goto leave;
+ if (tlen != rlen || memcmp (tbuf, rbuf, tlen))
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ rc = 0;
+
+ leave:
+ xfree (encpk);
+ xfree (tbuf);
+ _gcry_mpi_release (s);
+ _gcry_mpi_release (h);
+ point_free (&Ia);
+ point_free (&Ib);
+ return rc;
+}
diff --git a/comm/third_party/libgcrypt/cipher/ecc-gost.c b/comm/third_party/libgcrypt/cipher/ecc-gost.c
new file mode 100644
index 0000000000..36230f8a32
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc-gost.c
@@ -0,0 +1,218 @@
+/* ecc-gots.c - Elliptic Curve GOST signatures
+ * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Dmitry Eremin-Solenikov
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ecc-common.h"
+#include "pubkey-internal.h"
+
+
+/* Compute an GOST R 34.10-01/-12 signature.
+ * Return the signature struct (r,s) from the message hash. The caller
+ * must have allocated R and S.
+ */
+gpg_err_code_t
+_gcry_ecc_gost_sign (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s)
+{
+ gpg_err_code_t rc = 0;
+ gcry_mpi_t k, dr, sum, ke, x, e;
+ mpi_point_struct I;
+ gcry_mpi_t hash;
+ unsigned int qbits;
+
+ if (DBG_CIPHER)
+ log_mpidump ("gost sign hash ", input );
+
+ qbits = mpi_get_nbits (ec->n);
+
+ /* Convert the INPUT into an MPI if needed. */
+ rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+ if (rc)
+ return rc;
+
+ k = NULL;
+ dr = mpi_alloc (0);
+ sum = mpi_alloc (0);
+ ke = mpi_alloc (0);
+ e = mpi_alloc (0);
+ x = mpi_alloc (0);
+ point_init (&I);
+
+ mpi_mod (e, input, ec->n); /* e = hash mod n */
+
+ if (!mpi_cmp_ui (e, 0))
+ mpi_set_ui (e, 1);
+
+ /* Two loops to avoid R or S are zero. This is more of a joke than
+ a real demand because the probability of them being zero is less
+ than any hardware failure. Some specs however require it. */
+ do
+ {
+ do
+ {
+ mpi_free (k);
+ k = _gcry_dsa_gen_k (ec->n, GCRY_STRONG_RANDOM);
+
+ _gcry_dsa_modify_k (k, ec->n, qbits);
+
+ _gcry_mpi_ec_mul_point (&I, k, ec->G, ec);
+ if (_gcry_mpi_ec_get_affine (x, NULL, &I, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc sign: Failed to get affine coordinates\n");
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ mpi_mod (r, x, ec->n); /* r = x mod n */
+ }
+ while (!mpi_cmp_ui (r, 0));
+ mpi_mulm (dr, ec->d, r, ec->n); /* dr = d*r mod n */
+ mpi_mulm (ke, k, e, ec->n); /* ke = k*e mod n */
+ mpi_addm (s, ke, dr, ec->n); /* sum = (k*e+ d*r) mod n */
+ }
+ while (!mpi_cmp_ui (s, 0));
+
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("gost sign result r ", r);
+ log_mpidump ("gost sign result s ", s);
+ }
+
+ leave:
+ point_free (&I);
+ mpi_free (x);
+ mpi_free (e);
+ mpi_free (ke);
+ mpi_free (sum);
+ mpi_free (dr);
+ mpi_free (k);
+
+ if (hash != input)
+ mpi_free (hash);
+
+ return rc;
+}
+
+
+/* Verify a GOST R 34.10-01/-12 signature.
+ * Check if R and S verifies INPUT.
+ */
+gpg_err_code_t
+_gcry_ecc_gost_verify (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s)
+{
+ gpg_err_code_t err = 0;
+ gcry_mpi_t e, x, z1, z2, v, rv, zero;
+ mpi_point_struct Q, Q1, Q2;
+
+ if (!_gcry_mpi_ec_curve_point (ec->Q, ec))
+ return GPG_ERR_BROKEN_PUBKEY;
+
+ if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, ec->n) < 0) )
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */
+ if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, ec->n) < 0) )
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */
+
+ x = mpi_alloc (0);
+ e = mpi_alloc (0);
+ z1 = mpi_alloc (0);
+ z2 = mpi_alloc (0);
+ v = mpi_alloc (0);
+ rv = mpi_alloc (0);
+ zero = mpi_alloc (0);
+
+ point_init (&Q);
+ point_init (&Q1);
+ point_init (&Q2);
+
+ mpi_mod (e, input, ec->n); /* e = hash mod n */
+ if (!mpi_cmp_ui (e, 0))
+ mpi_set_ui (e, 1);
+ mpi_invm (v, e, ec->n); /* v = e^(-1) (mod n) */
+ mpi_mulm (z1, s, v, ec->n); /* z1 = s*v (mod n) */
+ mpi_mulm (rv, r, v, ec->n); /* rv = r*v (mod n) */
+ mpi_subm (z2, zero, rv, ec->n); /* z2 = -r*v (mod n) */
+
+ _gcry_mpi_ec_mul_point (&Q1, z1, ec->G, ec);
+/* log_mpidump ("Q1.x", Q1.x); */
+/* log_mpidump ("Q1.y", Q1.y); */
+/* log_mpidump ("Q1.z", Q1.z); */
+ _gcry_mpi_ec_mul_point (&Q2, z2, ec->Q, ec);
+/* log_mpidump ("Q2.x", Q2.x); */
+/* log_mpidump ("Q2.y", Q2.y); */
+/* log_mpidump ("Q2.z", Q2.z); */
+ _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ec);
+/* log_mpidump (" Q.x", Q.x); */
+/* log_mpidump (" Q.y", Q.y); */
+/* log_mpidump (" Q.z", Q.z); */
+
+ if (!mpi_cmp_ui (Q.z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc verify: Rejected\n");
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc verify: Failed to get affine coordinates\n");
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ mpi_mod (x, x, ec->n); /* x = x mod E_n */
+ if (mpi_cmp (x, r)) /* x != r */
+ {
+ if (DBG_CIPHER)
+ {
+ log_mpidump (" x", x);
+ log_mpidump (" r", r);
+ log_mpidump (" s", s);
+ log_debug ("ecc verify: Not verified\n");
+ }
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ if (DBG_CIPHER)
+ log_debug ("ecc verify: Accepted\n");
+
+ leave:
+ point_free (&Q2);
+ point_free (&Q1);
+ point_free (&Q);
+ mpi_free (zero);
+ mpi_free (rv);
+ mpi_free (v);
+ mpi_free (z2);
+ mpi_free (z1);
+ mpi_free (x);
+ mpi_free (e);
+ return err;
+}
diff --git a/comm/third_party/libgcrypt/cipher/ecc-misc.c b/comm/third_party/libgcrypt/cipher/ecc-misc.c
new file mode 100644
index 0000000000..6470a83bf4
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc-misc.c
@@ -0,0 +1,438 @@
+/* ecc-misc.c - Elliptic Curve miscellaneous functions
+ * Copyright (C) 2007, 2008, 2010, 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ecc-common.h"
+
+
+/*
+ * Release a curve object.
+ */
+void
+_gcry_ecc_curve_free (elliptic_curve_t *E)
+{
+ mpi_free (E->p); E->p = NULL;
+ mpi_free (E->a); E->a = NULL;
+ mpi_free (E->b); E->b = NULL;
+ _gcry_mpi_point_free_parts (&E->G);
+ mpi_free (E->n); E->n = NULL;
+}
+
+
+/*
+ * Return a copy of a curve object.
+ */
+elliptic_curve_t
+_gcry_ecc_curve_copy (elliptic_curve_t E)
+{
+ elliptic_curve_t R;
+
+ R.model = E.model;
+ R.dialect = E.dialect;
+ R.name = E.name;
+ R.p = mpi_copy (E.p);
+ R.a = mpi_copy (E.a);
+ R.b = mpi_copy (E.b);
+ _gcry_mpi_point_init (&R.G);
+ point_set (&R.G, &E.G);
+ R.n = mpi_copy (E.n);
+ R.h = E.h;
+
+ return R;
+}
+
+
+/*
+ * Return a description of the curve model.
+ */
+const char *
+_gcry_ecc_model2str (enum gcry_mpi_ec_models model)
+{
+ const char *str = "?";
+ switch (model)
+ {
+ case MPI_EC_WEIERSTRASS: str = "Weierstrass"; break;
+ case MPI_EC_MONTGOMERY: str = "Montgomery"; break;
+ case MPI_EC_EDWARDS: str = "Edwards"; break;
+ }
+ return str;
+}
+
+
+/*
+ * Return a description of the curve dialect.
+ */
+const char *
+_gcry_ecc_dialect2str (enum ecc_dialects dialect)
+{
+ const char *str = "?";
+ switch (dialect)
+ {
+ case ECC_DIALECT_STANDARD: str = "Standard"; break;
+ case ECC_DIALECT_ED25519: str = "Ed25519"; break;
+ case ECC_DIALECT_SAFECURVE: str = "SafeCurve"; break;
+ }
+ return str;
+}
+
+
+gcry_mpi_t
+_gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
+{
+ gpg_err_code_t rc;
+ int pbytes = (mpi_get_nbits (p)+7)/8;
+ size_t n;
+ unsigned char *buf, *ptr;
+
+ buf = xmalloc ( 1 + 2*pbytes );
+ *buf = 04; /* Uncompressed point. */
+ ptr = buf+1;
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x);
+ if (rc)
+ log_fatal ("mpi_print failed: %s\n", gpg_strerror (rc));
+ if (n < pbytes)
+ {
+ memmove (ptr+(pbytes-n), ptr, n);
+ memset (ptr, 0, (pbytes-n));
+ }
+ ptr += pbytes;
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y);
+ if (rc)
+ log_fatal ("mpi_print failed: %s\n", gpg_strerror (rc));
+ if (n < pbytes)
+ {
+ memmove (ptr+(pbytes-n), ptr, n);
+ memset (ptr, 0, (pbytes-n));
+ }
+
+ return mpi_set_opaque (NULL, buf, (1+2*pbytes)*8);
+}
+
+
+/* Convert POINT into affine coordinates using the context CTX and
+ return a newly allocated MPI. If the conversion is not possible
+ NULL is returned. This function won't print an error message. */
+gcry_mpi_t
+_gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ec)
+{
+ gcry_mpi_t g_x, g_y, result;
+
+ g_x = mpi_new (0);
+ g_y = mpi_new (0);
+ if (_gcry_mpi_ec_get_affine (g_x, g_y, point, ec))
+ result = NULL;
+ else
+ result = _gcry_ecc_ec2os (g_x, g_y, ec->p);
+ mpi_free (g_x);
+ mpi_free (g_y);
+
+ return result;
+}
+
+
+/* Decode octet string in VALUE into RESULT, in the format defined by SEC 1.
+ RESULT must have been initialized and is set on success to the
+ point given by VALUE. */
+gpg_err_code_t
+_gcry_ecc_sec_decodepoint (gcry_mpi_t value, mpi_ec_t ec, mpi_point_t result)
+{
+ gpg_err_code_t rc;
+ size_t n;
+ const unsigned char *buf;
+ unsigned char *buf_memory;
+ gcry_mpi_t x, y;
+
+ if (mpi_is_opaque (value))
+ {
+ unsigned int nbits;
+
+ buf = mpi_get_opaque (value, &nbits);
+ if (!buf)
+ return GPG_ERR_INV_OBJ;
+ n = (nbits + 7)/8;
+ buf_memory = NULL;
+ }
+ else
+ {
+ n = (mpi_get_nbits (value)+7)/8;
+ buf_memory = xmalloc (n);
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, buf_memory, n, &n, value);
+ if (rc)
+ {
+ xfree (buf_memory);
+ return rc;
+ }
+ buf = buf_memory;
+ }
+
+ if (n < 1)
+ {
+ xfree (buf_memory);
+ return GPG_ERR_INV_OBJ;
+ }
+
+ if (*buf == 2 || *buf == 3)
+ {
+ gcry_mpi_t x3;
+ gcry_mpi_t t;
+ gcry_mpi_t p1_4;
+ int y_bit = (*buf == 3);
+
+ if (!mpi_test_bit (ec->p, 1))
+ {
+ xfree (buf_memory);
+ return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression. */
+ }
+
+ n = n - 1;
+ rc = _gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
+ xfree (buf_memory);
+ if (rc)
+ return rc;
+
+ /*
+ * Recover Y. The Weierstrass curve: y^2 = x^3 + a*x + b
+ */
+
+ x3 = mpi_new (0);
+ t = mpi_new (0);
+ p1_4 = mpi_new (0);
+ y = mpi_new (0);
+
+ /* Compute right hand side. */
+ mpi_powm (x3, x, mpi_const (MPI_C_THREE), ec->p);
+ mpi_mul (t, ec->a, x);
+ mpi_mod (t, t, ec->p);
+ mpi_add (t, t, ec->b);
+ mpi_mod (t, t, ec->p);
+ mpi_add (t, t, x3);
+ mpi_mod (t, t, ec->p);
+
+ /*
+ * When p mod 4 = 3, modular square root of A can be computed by
+ * A^((p+1)/4) mod p
+ */
+
+ /* Compute (p+1)/4 into p1_4 */
+ mpi_rshift (p1_4, ec->p, 2);
+ _gcry_mpi_add_ui (p1_4, p1_4, 1);
+
+ mpi_powm (y, t, p1_4, ec->p);
+
+ if (y_bit != mpi_test_bit (y, 0))
+ mpi_sub (y, ec->p, y);
+
+ mpi_free (p1_4);
+ mpi_free (t);
+ mpi_free (x3);
+ }
+ else if (*buf == 4)
+ {
+ if ( ((n-1)%2) )
+ {
+ xfree (buf_memory);
+ return GPG_ERR_INV_OBJ;
+ }
+ n = (n-1)/2;
+ rc = _gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
+ if (rc)
+ {
+ xfree (buf_memory);
+ return rc;
+ }
+ rc = _gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL);
+ xfree (buf_memory);
+ if (rc)
+ {
+ mpi_free (x);
+ return rc;
+ }
+ }
+ else
+ {
+ xfree (buf_memory);
+ return GPG_ERR_INV_OBJ;
+ }
+
+ mpi_set (result->x, x);
+ mpi_set (result->y, y);
+ mpi_set_ui (result->z, 1);
+
+ mpi_free (x);
+ mpi_free (y);
+
+ return 0;
+}
+
+
+/* Compute the public key from the the context EC. Obviously a
+ requirement is that the secret key is available in EC. On success
+ Q is returned; on error NULL. If Q is NULL a newly allocated point
+ is returned. If G or D are given they override the values taken
+ from EC. */
+mpi_point_t
+_gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec)
+{
+ if (!ec->d || !ec->G || !ec->p || !ec->a)
+ return NULL;
+ if (ec->model == MPI_EC_EDWARDS && !ec->b)
+ return NULL;
+
+ if ((ec->dialect == ECC_DIALECT_ED25519 && (ec->flags & PUBKEY_FLAG_EDDSA))
+ || (ec->model == MPI_EC_EDWARDS && ec->dialect == ECC_DIALECT_SAFECURVE))
+ {
+ gcry_mpi_t a;
+ unsigned char *digest;
+
+ if (_gcry_ecc_eddsa_compute_h_d (&digest, ec))
+ return NULL;
+
+ a = mpi_snew (0);
+ _gcry_mpi_set_buffer (a, digest, 32, 0);
+ xfree (digest);
+
+ /* And finally the public key. */
+ if (!Q)
+ Q = mpi_point_new (0);
+ if (Q)
+ _gcry_mpi_ec_mul_point (Q, a, ec->G, ec);
+ mpi_free (a);
+ }
+ else
+ {
+ if (!Q)
+ Q = mpi_point_new (0);
+ if (Q)
+ _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec);
+ }
+
+ return Q;
+}
+
+
+gpg_err_code_t
+_gcry_ecc_mont_encodepoint (gcry_mpi_t x, unsigned int nbits,
+ int with_prefix,
+ unsigned char **r_buffer, unsigned int *r_buflen)
+{
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+
+ rawmpi = _gcry_mpi_get_buffer_extra (x, (nbits+7)/8,
+ with_prefix? -1 : 0, &rawmpilen, NULL);
+ if (rawmpi == NULL)
+ return gpg_err_code_from_syserror ();
+
+ if (with_prefix)
+ {
+ rawmpi[0] = 0x40;
+ rawmpilen++;
+ }
+
+ *r_buffer = rawmpi;
+ *r_buflen = rawmpilen;
+ return 0;
+}
+
+
+gpg_err_code_t
+_gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ec, mpi_point_t result)
+{
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+ unsigned int nbytes = (ec->nbits+7)/8;
+
+ /*
+ * It is not reliable to assume that the first byte of 0x40
+ * means the prefix.
+ *
+ * For newer implementation, it is reliable since we always put
+ * 0x40 for x-only coordinate.
+ *
+ * For data by older implementation (non-released development
+ * version in 2015), there is no 0x40 prefix added.
+ *
+ * So, it is possible to have shorter length of data when it was
+ * handled as MPI, removing preceding zeros.
+ *
+ * Besides, when data was parsed as MPI, we might have 0x00
+ * prefix (when the MSB in the first byte is set).
+ */
+
+ if (mpi_is_opaque (pk))
+ {
+ const unsigned char *buf;
+ unsigned char *p;
+
+ buf = mpi_get_opaque (pk, &rawmpilen);
+ if (!buf)
+ return GPG_ERR_INV_OBJ;
+ rawmpilen = (rawmpilen + 7)/8;
+
+ if (rawmpilen > nbytes
+ && (buf[0] == 0x00 || buf[0] == 0x40))
+ {
+ rawmpilen--;
+ buf++;
+ }
+
+ rawmpi = xtrymalloc (nbytes);
+ if (!rawmpi)
+ return gpg_err_code_from_syserror ();
+
+ p = rawmpi + rawmpilen;
+ while (p > rawmpi)
+ *--p = *buf++;
+
+ if (rawmpilen < nbytes)
+ memset (rawmpi + nbytes - rawmpilen, 0, nbytes - rawmpilen);
+ }
+ else
+ {
+ rawmpi = _gcry_mpi_get_buffer (pk, nbytes, &rawmpilen, NULL);
+ if (!rawmpi)
+ return gpg_err_code_from_syserror ();
+ /*
+ * When we have the prefix (0x40 or 0x00), it comes at the end,
+ * since it is taken by _gcry_mpi_get_buffer with little endian.
+ * Just setting RAWMPILEN to NBYTES is enough in this case.
+ * Othewise, RAWMPILEN is NBYTES already.
+ */
+ rawmpilen = nbytes;
+ }
+
+ if ((ec->nbits % 8))
+ rawmpi[0] &= (1 << (ec->nbits % 8)) - 1;
+ _gcry_mpi_set_buffer (result->x, rawmpi, rawmpilen, 0);
+ xfree (rawmpi);
+ mpi_set_ui (result->z, 1);
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/ecc-sm2.c b/comm/third_party/libgcrypt/cipher/ecc-sm2.c
new file mode 100644
index 0000000000..c52629fd3f
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc-sm2.c
@@ -0,0 +1,569 @@
+/* ecc-sm2.c - Elliptic Curve SM2 implementation
+ * Copyright (C) 2020 Tianjia Zhang
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "pubkey-internal.h"
+#include "ecc-common.h"
+
+#define MPI_NBYTES(m) ((mpi_get_nbits(m) + 7) / 8)
+
+
+/* Key derivation function from X9.63/SECG */
+static gpg_err_code_t
+kdf_x9_63 (int algo, const void *in, size_t inlen, void *out, size_t outlen)
+{
+ gpg_err_code_t rc;
+ gcry_md_hd_t hd;
+ int mdlen;
+ u32 counter = 1;
+ u32 counter_be;
+ unsigned char *dgst;
+ unsigned char *pout = out;
+ size_t rlen = outlen;
+ size_t len;
+
+ rc = _gcry_md_open (&hd, algo, 0);
+ if (rc)
+ return rc;
+
+ mdlen = _gcry_md_get_algo_dlen (algo);
+
+ while (rlen > 0)
+ {
+ counter_be = be_bswap32 (counter); /* cpu_to_be32 */
+ counter++;
+
+ _gcry_md_write (hd, in, inlen);
+ _gcry_md_write (hd, &counter_be, sizeof(counter_be));
+
+ dgst = _gcry_md_read (hd, algo);
+ if (dgst == NULL)
+ {
+ rc = GPG_ERR_DIGEST_ALGO;
+ break;
+ }
+
+ len = mdlen < rlen ? mdlen : rlen; /* min(mdlen, rlen) */
+ memcpy (pout, dgst, len);
+ rlen -= len;
+ pout += len;
+
+ _gcry_md_reset (hd);
+ }
+
+ _gcry_md_close (hd);
+ return rc;
+}
+
+
+/* _gcry_ecc_sm2_encrypt description:
+ * input:
+ * data[0] : octet string
+ * output: A new S-expression with the parameters:
+ * a: c1 : generated ephemeral public key (kG)
+ * b: c3 : Hash(x2 || IN || y2)
+ * c: c2 : cipher
+ *
+ * sm2_decrypt description:
+ * in contrast to encrypt
+ */
+gpg_err_code_t
+_gcry_ecc_sm2_encrypt (gcry_sexp_t *r_ciph, gcry_mpi_t input, mpi_ec_t ec)
+{
+ gpg_err_code_t rc;
+ const int algo = GCRY_MD_SM3;
+ gcry_md_hd_t md = NULL;
+ int mdlen;
+ unsigned char *dgst;
+ gcry_mpi_t k = NULL;
+ mpi_point_struct kG, kP;
+ gcry_mpi_t x1, y1;
+ gcry_mpi_t x2, y2;
+ gcry_mpi_t x2y2 = NULL;
+ unsigned char *in = NULL;
+ unsigned int inlen;
+ unsigned char *raw;
+ unsigned int rawlen;
+ unsigned char *cipher = NULL;
+ int i;
+
+ point_init (&kG);
+ point_init (&kP);
+ x1 = mpi_new (0);
+ y1 = mpi_new (0);
+ x2 = mpi_new (0);
+ y2 = mpi_new (0);
+
+ in = _gcry_mpi_get_buffer (input, 0, &inlen, NULL);
+ if (!in)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ cipher = xtrymalloc (inlen);
+ if (!cipher)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ /* rand k in [1, n-1] */
+ k = _gcry_dsa_gen_k (ec->n, GCRY_VERY_STRONG_RANDOM);
+
+ /* [k]G = (x1, y1) */
+ _gcry_mpi_ec_mul_point (&kG, k, ec->G, ec);
+ if (_gcry_mpi_ec_get_affine (x1, y1, &kG, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: kG can not be a Point at Infinity!\n");
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* [k]P = (x2, y2) */
+ _gcry_mpi_ec_mul_point (&kP, k, ec->Q, ec);
+ if (_gcry_mpi_ec_get_affine (x2, y2, &kP, ec))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* t = KDF(x2 || y2, klen) */
+ x2y2 = _gcry_mpi_ec_ec2os (&kP, ec);
+ raw = mpi_get_opaque (x2y2, &rawlen);
+ rawlen = (rawlen + 7) / 8;
+
+ /* skip the prefix '0x04' */
+ raw += 1;
+ rawlen -= 1;
+ rc = kdf_x9_63 (algo, raw, rawlen, cipher, inlen);
+ if (rc)
+ goto leave;
+
+ /* cipher = t xor in */
+ for (i = 0; i < inlen; i++)
+ cipher[i] ^= in[i];
+
+ /* hash(x2 || IN || y2) */
+ mdlen = _gcry_md_get_algo_dlen (algo);
+ rc = _gcry_md_open (&md, algo, 0);
+ if (rc)
+ goto leave;
+ _gcry_md_write (md, raw, MPI_NBYTES(x2));
+ _gcry_md_write (md, in, inlen);
+ _gcry_md_write (md, raw + MPI_NBYTES(x2), MPI_NBYTES(y2));
+ dgst = _gcry_md_read (md, algo);
+ if (dgst == NULL)
+ {
+ rc = GPG_ERR_DIGEST_ALGO;
+ goto leave;
+ }
+
+ if (!rc)
+ {
+ gcry_mpi_t c1;
+ gcry_mpi_t c3;
+ gcry_mpi_t c2;
+
+ c3 = mpi_new (0);
+ c2 = mpi_new (0);
+
+ c1 = _gcry_ecc_ec2os (x1, y1, ec->p);
+ _gcry_mpi_set_opaque_copy (c3, dgst, mdlen * 8);
+ _gcry_mpi_set_opaque_copy (c2, cipher, inlen * 8);
+
+ rc = sexp_build (r_ciph, NULL,
+ "(enc-val(flags sm2)(sm2(a%M)(b%M)(c%M)))",
+ c1, c3, c2);
+
+ mpi_free (c1);
+ mpi_free (c3);
+ mpi_free (c2);
+ }
+
+leave:
+ _gcry_md_close (md);
+ mpi_free (x2y2);
+ mpi_free (k);
+
+ point_free (&kG);
+ point_free (&kP);
+ mpi_free (x1);
+ mpi_free (y1);
+ mpi_free (x2);
+ mpi_free (y2);
+
+ xfree (cipher);
+ xfree (in);
+
+ return rc;
+}
+
+
+gpg_err_code_t
+_gcry_ecc_sm2_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t data_list, mpi_ec_t ec)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t data_c1 = NULL;
+ gcry_mpi_t data_c3 = NULL;
+ gcry_mpi_t data_c2 = NULL;
+
+ /*
+ * Extract the data.
+ */
+ rc = sexp_extract_param (data_list, NULL, "/a/b/c",
+ &data_c1, &data_c3, &data_c2, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_printmpi ("ecc_decrypt d_c1", data_c1);
+ log_printmpi ("ecc_decrypt d_c3", data_c3);
+ log_printmpi ("ecc_decrypt d_c2", data_c2);
+ }
+
+ {
+ const int algo = GCRY_MD_SM3;
+ gcry_md_hd_t md = NULL;
+ int mdlen;
+ unsigned char *dgst;
+ mpi_point_struct c1;
+ mpi_point_struct kP;
+ gcry_mpi_t x2, y2;
+ gcry_mpi_t x2y2 = NULL;
+ unsigned char *in = NULL;
+ unsigned int inlen;
+ unsigned char *plain = NULL;
+ unsigned char *raw;
+ unsigned int rawlen;
+ unsigned char *c3 = NULL;
+ unsigned int c3_len;
+ int i;
+
+ point_init (&c1);
+ point_init (&kP);
+ x2 = mpi_new (0);
+ y2 = mpi_new (0);
+
+ in = mpi_get_opaque (data_c2, &inlen);
+ inlen = (inlen + 7) / 8;
+ plain = xtrymalloc (inlen);
+ if (!plain)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave_main;
+ }
+
+ rc = _gcry_ecc_sec_decodepoint (data_c1, ec, &c1);
+ if (rc)
+ goto leave_main;
+
+ if (!_gcry_mpi_ec_curve_point (&c1, ec))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave_main;
+ }
+
+ /* [d]C1 = (x2, y2), C1 = [k]G */
+ _gcry_mpi_ec_mul_point (&kP, ec->d, &c1, ec);
+ if (_gcry_mpi_ec_get_affine (x2, y2, &kP, ec))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave_main;
+ }
+
+ /* t = KDF(x2 || y2, inlen) */
+ x2y2 = _gcry_mpi_ec_ec2os (&kP, ec);
+ raw = mpi_get_opaque (x2y2, &rawlen);
+ rawlen = (rawlen + 7) / 8;
+ /* skip the prefix '0x04' */
+ raw += 1;
+ rawlen -= 1;
+ rc = kdf_x9_63 (algo, raw, rawlen, plain, inlen);
+ if (rc)
+ goto leave_main;
+
+ /* plain = C2 xor t */
+ for (i = 0; i < inlen; i++)
+ plain[i] ^= in[i];
+
+ /* Hash(x2 || IN || y2) == C3 */
+ mdlen = _gcry_md_get_algo_dlen (algo);
+ rc = _gcry_md_open (&md, algo, 0);
+ if (rc)
+ goto leave_main;
+ _gcry_md_write (md, raw, MPI_NBYTES(x2));
+ _gcry_md_write (md, plain, inlen);
+ _gcry_md_write (md, raw + MPI_NBYTES(x2), MPI_NBYTES(y2));
+ dgst = _gcry_md_read (md, algo);
+ if (dgst == NULL)
+ {
+ memset (plain, 0, inlen);
+ rc = GPG_ERR_DIGEST_ALGO;
+ goto leave_main;
+ }
+ c3 = mpi_get_opaque (data_c3, &c3_len);
+ c3_len = (c3_len + 7) / 8;
+ if (c3_len != mdlen || memcmp (dgst, c3, c3_len) != 0)
+ {
+ memset (plain, 0, inlen);
+ rc = GPG_ERR_INV_DATA;
+ goto leave_main;
+ }
+
+ if (!rc)
+ {
+ gcry_mpi_t r;
+
+ r = mpi_new (inlen * 8);
+ _gcry_mpi_set_buffer (r, plain, inlen, 0);
+
+ rc = sexp_build (r_plain, NULL, "(value %m)", r);
+
+ mpi_free (r);
+ }
+
+ leave_main:
+ _gcry_md_close (md);
+ mpi_free (x2y2);
+ xfree (plain);
+
+ point_free (&c1);
+ point_free (&kP);
+ mpi_free (x2);
+ mpi_free (y2);
+ }
+
+ leave:
+ _gcry_mpi_release (data_c1);
+ _gcry_mpi_release (data_c3);
+ _gcry_mpi_release (data_c2);
+
+ return rc;
+}
+
+
+/* Compute an SM2 signature.
+ * Return the signature struct (r,s) from the message hash. The caller
+ * must have allocated R and S.
+ */
+gpg_err_code_t
+_gcry_ecc_sm2_sign (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s,
+ int flags, int hashalgo)
+{
+ gpg_err_code_t rc = 0;
+ int extraloops = 0;
+ gcry_mpi_t hash;
+ const void *abuf;
+ unsigned int abits, qbits;
+ gcry_mpi_t tmp = NULL;
+ gcry_mpi_t k = NULL;
+ gcry_mpi_t rk = NULL;
+ mpi_point_struct kG;
+ gcry_mpi_t x1;
+
+ if (DBG_CIPHER)
+ log_mpidump ("sm2 sign hash ", input);
+
+ qbits = mpi_get_nbits (ec->n);
+
+ /* Convert the INPUT into an MPI if needed. */
+ rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+ if (rc)
+ return rc;
+
+ point_init (&kG);
+ x1 = mpi_new (0);
+ rk = mpi_new (0);
+ tmp = mpi_new (0);
+
+ for (;;)
+ {
+ /* rand k in [1, n-1] */
+ if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
+ {
+ /* Use Pornin's method for deterministic DSA. If this
+ flag is set, it is expected that HASH is an opaque
+ MPI with the to be signed hash. That hash is also
+ used as h1 from 3.2.a. */
+ if (!mpi_is_opaque (input))
+ {
+ rc = GPG_ERR_CONFLICT;
+ goto leave;
+ }
+
+ abuf = mpi_get_opaque (input, &abits);
+ rc = _gcry_dsa_gen_rfc6979_k (&k, ec->n, ec->d,
+ abuf, (abits+7)/8,
+ hashalgo, extraloops);
+ if (rc)
+ goto leave;
+ extraloops++;
+ }
+ else
+ k = _gcry_dsa_gen_k (ec->n, GCRY_VERY_STRONG_RANDOM);
+
+ _gcry_dsa_modify_k (k, ec->n, qbits);
+
+ /* [k]G = (x1, y1) */
+ _gcry_mpi_ec_mul_point (&kG, k, ec->G, ec);
+ if (_gcry_mpi_ec_get_affine (x1, NULL, &kG, ec))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* r = (e + x1) % n */
+ mpi_addm (r, hash, x1, ec->n);
+
+ /* r != 0 && r + k != n */
+ if (mpi_cmp_ui (r, 0) == 0)
+ continue;
+ mpi_add (rk, r, k);
+ if (mpi_cmp (rk, ec->n) == 0)
+ continue;
+
+ /* s = ((d + 1)^-1 * (k - rd)) % n */
+ mpi_addm (s, ec->d, GCRYMPI_CONST_ONE, ec->n);
+ mpi_invm (s, s, ec->n);
+ mpi_mulm (tmp, r, ec->d, ec->n);
+ mpi_subm (tmp, k, tmp, ec->n);
+ mpi_mulm (s, s, tmp, ec->n);
+
+ /* s != 0 */
+ if (mpi_cmp_ui (s, 0) == 0)
+ continue;
+
+ break; /* Okay */
+ }
+
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("sm2 sign result r ", r);
+ log_mpidump ("sm2 sign result s ", s);
+ }
+
+leave:
+ point_free (&kG);
+ mpi_free (k);
+ mpi_free (x1);
+ mpi_free (rk);
+ mpi_free (tmp);
+
+ if (hash != input)
+ mpi_free (hash);
+
+ return rc;
+}
+
+
+/* Verify an SM2 signature.
+ * Check if R and S verifies INPUT.
+ */
+gpg_err_code_t
+_gcry_ecc_sm2_verify (gcry_mpi_t input, mpi_ec_t ec,
+ gcry_mpi_t r, gcry_mpi_t s)
+{
+ gpg_err_code_t err = 0;
+ gcry_mpi_t hash = NULL;
+ gcry_mpi_t t = NULL;
+ mpi_point_struct sG, tP;
+ gcry_mpi_t x1, y1;
+ unsigned int nbits;
+
+ if (!_gcry_mpi_ec_curve_point (ec->Q, ec))
+ return GPG_ERR_BROKEN_PUBKEY;
+
+ /* r, s within [1, n-1] */
+ if (mpi_cmp_ui (r, 1) < 0 || mpi_cmp (r, ec->n) > 0)
+ return GPG_ERR_BAD_SIGNATURE;
+ if (mpi_cmp_ui (s, 1) < 0 || mpi_cmp (s, ec->n) > 0)
+ return GPG_ERR_BAD_SIGNATURE;
+
+ nbits = mpi_get_nbits (ec->n);
+ err = _gcry_dsa_normalize_hash (input, &hash, nbits);
+ if (err)
+ return err;
+
+ point_init (&sG);
+ point_init (&tP);
+ x1 = mpi_new (0);
+ y1 = mpi_new (0);
+ t = mpi_new (0);
+
+ /* t = (r + s) % n, t != 0 */
+ mpi_addm (t, r, s, ec->n);
+ if (mpi_cmp_ui (t, 0) == 0)
+ {
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* sG + tP = (x1, y1) */
+ _gcry_mpi_ec_mul_point (&sG, s, ec->G, ec);
+ _gcry_mpi_ec_mul_point (&tP, t, ec->Q, ec);
+ _gcry_mpi_ec_add_points (&sG, &sG, &tP, ec);
+ if (_gcry_mpi_ec_get_affine (x1, y1, &sG, ec))
+ {
+ err = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* R = (e + x1) % n */
+ mpi_addm (t, hash, x1, ec->n);
+
+ /* check R == r */
+ if (mpi_cmp (t, r))
+ {
+ if (DBG_CIPHER)
+ {
+ log_mpidump (" R", t);
+ log_mpidump (" r", r);
+ log_mpidump (" s", s);
+ }
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ if (DBG_CIPHER)
+ log_debug ("sm2 verify: Accepted\n");
+
+ leave:
+ point_free (&sG);
+ point_free (&tP);
+ mpi_free (x1);
+ mpi_free (y1);
+ mpi_free (t);
+ if (hash != input)
+ mpi_free (hash);
+
+ return err;
+}
diff --git a/comm/third_party/libgcrypt/cipher/ecc.c b/comm/third_party/libgcrypt/cipher/ecc.c
new file mode 100644
index 0000000000..5d8c7607ab
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/ecc.c
@@ -0,0 +1,1779 @@
+/* ecc.c - Elliptic Curve Cryptography
+ * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2015 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* This code is originally based on the Patch 0.1.6 for the gnupg
+ 1.4.x branch as retrieved on 2007-03-21 from
+ http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2
+ The original authors are:
+ Written by
+ Sergi Blanch i Torne <d4372211 at alumnes.eup.udl.es>,
+ Ramiro Moreno Chiral <ramiro at eup.udl.es>
+ Maintainers
+ Sergi Blanch i Torne
+ Ramiro Moreno Chiral
+ Mikael Mylnikov (mmr)
+ For use in Libgcrypt the code has been heavily modified and cleaned
+ up. In fact there is not much left of the originally code except for
+ some variable names and the text book implementaion of the sign and
+ verification algorithms. The arithmetic functions have entirely
+ been rewritten and moved to mpi/ec.c.
+
+ ECDH encrypt and decrypt code written by Andrey Jivsov.
+*/
+
+
+/* TODO:
+
+ - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
+ special case in mpi_powm or check whether mpi_mulm is faster.
+
+*/
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "pubkey-internal.h"
+#include "ecc-common.h"
+
+
+static const char *ecc_names[] =
+ {
+ "ecc",
+ "ecdsa",
+ "ecdh",
+ "eddsa",
+ "gost",
+ "sm2",
+ NULL,
+ };
+
+
+/* Sample NIST P-256 key from RFC 6979 A.2.5 */
+static const char sample_public_key_secp256[] =
+ "(public-key"
+ " (ecc"
+ " (curve secp256r1)"
+ " (q #04"
+ /**/ "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
+ /**/ "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)))";
+
+static const char sample_secret_key_secp256[] =
+ "(private-key"
+ " (ecc"
+ " (curve secp256r1)"
+ " (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)"
+ " (q #04"
+ /**/ "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
+ /**/ "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)))";
+
+
+/* Registered progress function and its callback value. */
+static void (*progress_cb) (void *, const char*, int, int, int);
+static void *progress_cb_data;
+
+
+
+/* Local prototypes. */
+static void test_keys (mpi_ec_t ec, unsigned int nbits);
+static void test_ecdh_only_keys (mpi_ec_t ec, unsigned int nbits, int flags);
+static unsigned int ecc_get_nbits (gcry_sexp_t parms);
+
+
+
+
+void
+_gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
+ int, int, int),
+ void *cb_data)
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+/* static void */
+/* progress (int c) */
+/* { */
+/* if (progress_cb) */
+/* progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
+/* } */
+
+
+
+/**
+ * nist_generate_key - Standard version of the ECC key generation.
+ * @ec: Elliptic curve computation context.
+ * @flags: Flags controlling aspects of the creation.
+ * @r_x: On success this receives an allocated MPI with the affine
+ * x-coordinate of the poblic key. On error NULL is stored.
+ * @r_y: Ditto for the y-coordinate.
+ *
+ * Return: An error code.
+ *
+ * The @flags bits used by this function are %PUBKEY_FLAG_TRANSIENT to
+ * use a faster RNG, and %PUBKEY_FLAG_NO_KEYTEST to skip the assertion
+ * that the key works as expected.
+ *
+ * FIXME: Check whether N is needed.
+ */
+static gpg_err_code_t
+nist_generate_key (mpi_ec_t ec, int flags,
+ gcry_mpi_t *r_x, gcry_mpi_t *r_y)
+{
+ mpi_point_struct Q;
+ gcry_random_level_t random_level;
+ gcry_mpi_t x, y;
+ const unsigned int pbits = ec->nbits;
+
+ point_init (&Q);
+
+ if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
+ random_level = GCRY_STRONG_RANDOM;
+ else
+ random_level = GCRY_VERY_STRONG_RANDOM;
+
+ /* Generate a secret. */
+ if (ec->dialect == ECC_DIALECT_ED25519
+ || ec->dialect == ECC_DIALECT_SAFECURVE
+ || (flags & PUBKEY_FLAG_DJB_TWEAK))
+ {
+ char *rndbuf;
+ int len = (pbits+7)/8;
+
+ rndbuf = _gcry_random_bytes_secure (len, random_level);
+ if (ec->dialect == ECC_DIALECT_SAFECURVE)
+ ec->d = mpi_set_opaque (NULL, rndbuf, len*8);
+ else
+ {
+ ec->d = mpi_snew (pbits);
+ if ((pbits % 8))
+ rndbuf[0] &= (1 << (pbits % 8)) - 1;
+ rndbuf[0] |= (1 << ((pbits + 7) % 8));
+ rndbuf[len-1] &= (256 - ec->h);
+ _gcry_mpi_set_buffer (ec->d, rndbuf, len, 0);
+ xfree (rndbuf);
+ }
+ }
+ else
+ ec->d = _gcry_dsa_gen_k (ec->n, random_level);
+
+ /* Compute Q. */
+ _gcry_mpi_ec_mul_point (&Q, ec->d, ec->G, ec);
+
+ x = mpi_new (pbits);
+ if (r_y == NULL)
+ y = NULL;
+ else
+ y = mpi_new (pbits);
+ if (_gcry_mpi_ec_get_affine (x, y, &Q, ec))
+ log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
+
+ /* We want the Q=(x,y) be a "compliant key" in terms of the
+ * http://tools.ietf.org/html/draft-jivsov-ecc-compact, which simply
+ * means that we choose either Q=(x,y) or -Q=(x,p-y) such that we
+ * end up with the min(y,p-y) as the y coordinate. Such a public
+ * key allows the most efficient compression: y can simply be
+ * dropped because we know that it's a minimum of the two
+ * possibilities without any loss of security. Note that we don't
+ * do that for Ed25519 so that we do not violate the special
+ * construction of the secret key. */
+ if (r_y == NULL || ec->dialect == ECC_DIALECT_ED25519)
+ ec->Q = mpi_point_set (NULL, Q.x, Q.y, Q.z);
+ else
+ {
+ gcry_mpi_t negative;
+
+ negative = mpi_new (pbits);
+
+ if (ec->model == MPI_EC_WEIERSTRASS)
+ mpi_sub (negative, ec->p, y); /* negative = p - y */
+ else
+ mpi_sub (negative, ec->p, x); /* negative = p - x */
+
+ if (mpi_cmp (negative, y) < 0) /* p - y < p */
+ {
+ /* We need to end up with -Q; this assures that new Q's y is
+ the smallest one */
+ if (ec->model == MPI_EC_WEIERSTRASS)
+ {
+ mpi_free (y);
+ y = negative;
+ }
+ else
+ {
+ mpi_free (x);
+ x = negative;
+ }
+ mpi_sub (ec->d, ec->n, ec->d); /* d = order - d */
+ ec->Q = mpi_point_set (NULL, x, y, mpi_const (MPI_C_ONE));
+
+ if (DBG_CIPHER)
+ log_debug ("ecgen converted Q to a compliant point\n");
+ }
+ else /* p - y >= p */
+ {
+ /* No change is needed exactly 50% of the time: just copy. */
+ mpi_free (negative);
+ ec->Q = mpi_point_set (NULL, Q.x, Q.y, Q.z);
+ if (DBG_CIPHER)
+ log_debug ("ecgen didn't need to convert Q to a compliant point\n");
+ }
+ }
+
+ *r_x = x;
+ if (r_y)
+ *r_y = y;
+
+ point_free (&Q);
+ /* Now we can test our keys (this should never fail!). */
+ if ((flags & PUBKEY_FLAG_NO_KEYTEST))
+ ; /* User requested to skip the test. */
+ else if (ec->model == MPI_EC_MONTGOMERY)
+ test_ecdh_only_keys (ec, ec->nbits - 63, flags);
+ else
+ test_keys (ec, ec->nbits - 64);
+
+ return 0;
+}
+
+
+/*
+ * To verify correct skey it use a random information.
+ * First, encrypt and decrypt this dummy value,
+ * test if the information is recuperated.
+ * Second, test with the sign and verify functions.
+ */
+static void
+test_keys (mpi_ec_t ec, unsigned int nbits)
+{
+ gcry_mpi_t test = mpi_new (nbits);
+ mpi_point_struct R_;
+ gcry_mpi_t c = mpi_new (nbits);
+ gcry_mpi_t out = mpi_new (nbits);
+ gcry_mpi_t r = mpi_new (nbits);
+ gcry_mpi_t s = mpi_new (nbits);
+
+ if (DBG_CIPHER)
+ log_debug ("Testing key.\n");
+
+ point_init (&R_);
+
+ _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
+
+ if (_gcry_ecc_ecdsa_sign (test, ec, r, s, 0, 0) )
+ log_fatal ("ECDSA operation: sign failed\n");
+
+ if (_gcry_ecc_ecdsa_verify (test, ec, r, s))
+ {
+ log_fatal ("ECDSA operation: sign, verify failed\n");
+ }
+
+ if (DBG_CIPHER)
+ log_debug ("ECDSA operation: sign, verify ok.\n");
+
+ point_free (&R_);
+ mpi_free (s);
+ mpi_free (r);
+ mpi_free (out);
+ mpi_free (c);
+ mpi_free (test);
+}
+
+
+static void
+test_ecdh_only_keys (mpi_ec_t ec, unsigned int nbits, int flags)
+{
+ gcry_mpi_t test;
+ mpi_point_struct R_;
+ gcry_mpi_t x0, x1;
+
+ if (DBG_CIPHER)
+ log_debug ("Testing ECDH only key.\n");
+
+ point_init (&R_);
+
+ if (ec->dialect == ECC_DIALECT_SAFECURVE || (flags & PUBKEY_FLAG_DJB_TWEAK))
+ {
+ char *rndbuf;
+ const unsigned int pbits = ec->nbits;
+ int len = (pbits+7)/8;
+
+ rndbuf = _gcry_random_bytes (len, GCRY_WEAK_RANDOM);
+ if (ec->dialect == ECC_DIALECT_SAFECURVE)
+ test = mpi_set_opaque (NULL, rndbuf, len*8);
+ else
+ {
+ test = mpi_new (pbits);
+ if ((pbits % 8))
+ rndbuf[0] &= (1 << (pbits % 8)) - 1;
+ rndbuf[0] |= (1 << ((pbits + 7) % 8));
+ rndbuf[len-1] &= (256 - ec->h);
+ _gcry_mpi_set_buffer (test, rndbuf, len, 0);
+ xfree (rndbuf);
+ }
+ }
+ else
+ {
+ test = mpi_new (nbits);
+ _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
+ }
+
+ x0 = mpi_new (0);
+ x1 = mpi_new (0);
+
+ /* R_ = hkQ <=> R_ = hkdG */
+ _gcry_mpi_ec_mul_point (&R_, test, ec->Q, ec);
+ if (ec->dialect == ECC_DIALECT_STANDARD && !(flags & PUBKEY_FLAG_DJB_TWEAK))
+ _gcry_mpi_ec_mul_point (&R_, _gcry_mpi_get_const (ec->h), &R_, ec);
+ if (_gcry_mpi_ec_get_affine (x0, NULL, &R_, ec))
+ log_fatal ("ecdh: Failed to get affine coordinates for hkQ\n");
+
+ _gcry_mpi_ec_mul_point (&R_, test, ec->G, ec);
+ _gcry_mpi_ec_mul_point (&R_, ec->d, &R_, ec);
+ /* R_ = hdkG */
+ if (ec->dialect == ECC_DIALECT_STANDARD && !(flags & PUBKEY_FLAG_DJB_TWEAK))
+ _gcry_mpi_ec_mul_point (&R_, _gcry_mpi_get_const (ec->h), &R_, ec);
+
+ if (_gcry_mpi_ec_get_affine (x1, NULL, &R_, ec))
+ log_fatal ("ecdh: Failed to get affine coordinates for hdkG\n");
+
+ if (mpi_cmp (x0, x1))
+ {
+ log_fatal ("ECDH test failed.\n");
+ }
+
+ mpi_free (x0);
+ mpi_free (x1);
+
+ point_free (&R_);
+ mpi_free (test);
+}
+
+
+/*
+ * To check the validity of the value, recalculate the correspondence
+ * between the public value and the secret one.
+ */
+static int
+check_secret_key (mpi_ec_t ec, int flags)
+{
+ int rc = 1;
+ mpi_point_struct Q;
+ gcry_mpi_t x1, y1;
+ gcry_mpi_t x2 = NULL;
+ gcry_mpi_t y2 = NULL;
+
+ point_init (&Q);
+ x1 = mpi_new (0);
+ if (ec->model == MPI_EC_MONTGOMERY)
+ y1 = NULL;
+ else
+ y1 = mpi_new (0);
+
+ /* G in E(F_p) */
+ if (!_gcry_mpi_ec_curve_point (ec->G, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
+ goto leave;
+ }
+
+ /* G != PaI */
+ if (!mpi_cmp_ui (ec->G->z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
+ goto leave;
+ }
+
+ /* Check order of curve. */
+ if (ec->dialect == ECC_DIALECT_STANDARD && !(flags & PUBKEY_FLAG_DJB_TWEAK))
+ {
+ _gcry_mpi_ec_mul_point (&Q, ec->n, ec->G, ec);
+ if (mpi_cmp_ui (Q.z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("check_secret_key: E is not a curve of order n\n");
+ goto leave;
+ }
+ }
+
+ /* Pubkey cannot be PaI */
+ if (!mpi_cmp_ui (ec->Q->z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: Q can not be a Point at Infinity!\n");
+ goto leave;
+ }
+
+ /* pubkey = [d]G over E */
+ if (!_gcry_ecc_compute_public (&Q, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: computation of dG failed\n");
+ goto leave;
+ }
+ if (_gcry_mpi_ec_get_affine (x1, y1, &Q, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: Q can not be a Point at Infinity!\n");
+ goto leave;
+ }
+
+ if ((flags & PUBKEY_FLAG_EDDSA)
+ || (ec->model == MPI_EC_EDWARDS && ec->dialect == ECC_DIALECT_SAFECURVE))
+ ; /* Fixme: EdDSA is special. */
+ else if (!mpi_cmp_ui (ec->Q->z, 1))
+ {
+ /* Fast path if Q is already in affine coordinates. */
+ if (mpi_cmp (x1, ec->Q->x) || (y1 && mpi_cmp (y1, ec->Q->y)))
+ {
+ if (DBG_CIPHER)
+ log_debug
+ ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
+ goto leave;
+ }
+ }
+ else
+ {
+ x2 = mpi_new (0);
+ y2 = mpi_new (0);
+ if (_gcry_mpi_ec_get_affine (x2, y2, ec->Q, ec))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: Q can not be a Point at Infinity!\n");
+ goto leave;
+ }
+
+ if (mpi_cmp (x1, x2) || mpi_cmp (y1, y2))
+ {
+ if (DBG_CIPHER)
+ log_debug
+ ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
+ goto leave;
+ }
+ }
+ rc = 0; /* Okay. */
+
+ leave:
+ mpi_free (x2);
+ mpi_free (x1);
+ mpi_free (y1);
+ mpi_free (y2);
+ point_free (&Q);
+ return rc;
+}
+
+
+
+/*********************************************
+ ************** interface ******************
+ *********************************************/
+
+static gcry_err_code_t
+ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t Gx = NULL;
+ gcry_mpi_t Gy = NULL;
+ gcry_mpi_t Qx = NULL;
+ gcry_mpi_t Qy = NULL;
+ mpi_ec_t ec = NULL;
+ gcry_sexp_t curve_info = NULL;
+ gcry_sexp_t curve_flags = NULL;
+ gcry_mpi_t base = NULL;
+ gcry_mpi_t public = NULL;
+ int flags = 0;
+
+ rc = _gcry_mpi_ec_internal_new (&ec, &flags, "ecgen curve", genparms, NULL);
+ if (rc)
+ goto leave;
+
+ if ((flags & PUBKEY_FLAG_EDDSA)
+ || (ec->model == MPI_EC_EDWARDS && ec->dialect == ECC_DIALECT_SAFECURVE))
+ rc = _gcry_ecc_eddsa_genkey (ec, flags);
+ else if (ec->model == MPI_EC_MONTGOMERY)
+ rc = nist_generate_key (ec, flags, &Qx, NULL);
+ else
+ rc = nist_generate_key (ec, flags, &Qx, &Qy);
+ if (rc)
+ goto leave;
+
+ /* Copy data to the result. */
+ Gx = mpi_new (0);
+ Gy = mpi_new (0);
+ if (ec->model != MPI_EC_MONTGOMERY)
+ {
+ if (_gcry_mpi_ec_get_affine (Gx, Gy, ec->G, ec))
+ log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
+ base = _gcry_ecc_ec2os (Gx, Gy, ec->p);
+ }
+ if (((ec->dialect == ECC_DIALECT_SAFECURVE && ec->model == MPI_EC_EDWARDS)
+ || ec->dialect == ECC_DIALECT_ED25519 || ec->model == MPI_EC_MONTGOMERY)
+ && !(flags & PUBKEY_FLAG_NOCOMP))
+ {
+ unsigned char *encpk;
+ unsigned int encpklen;
+
+ if (ec->model == MPI_EC_MONTGOMERY)
+ rc = _gcry_ecc_mont_encodepoint (Qx, ec->nbits,
+ ec->dialect != ECC_DIALECT_SAFECURVE,
+ &encpk, &encpklen);
+ else
+ /* (Gx and Gy are used as scratch variables) */
+ rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, Gx, Gy,
+ (ec->dialect != ECC_DIALECT_SAFECURVE
+ && !!(flags & PUBKEY_FLAG_COMP)),
+ &encpk, &encpklen);
+ if (rc)
+ goto leave;
+ public = mpi_new (0);
+ mpi_set_opaque (public, encpk, encpklen*8);
+ }
+ else
+ {
+ if (!Qx)
+ {
+ /* This is the case for a key from _gcry_ecc_eddsa_generate
+ with no compression. */
+ Qx = mpi_new (0);
+ Qy = mpi_new (0);
+ if (_gcry_mpi_ec_get_affine (Qx, Qy, ec->Q, ec))
+ log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
+ }
+ public = _gcry_ecc_ec2os (Qx, Qy, ec->p);
+ }
+ if (ec->name)
+ {
+ rc = sexp_build (&curve_info, NULL, "(curve %s)", ec->name);
+ if (rc)
+ goto leave;
+ }
+
+ if ((flags & PUBKEY_FLAG_PARAM) || (flags & PUBKEY_FLAG_EDDSA)
+ || (flags & PUBKEY_FLAG_DJB_TWEAK))
+ {
+ rc = sexp_build
+ (&curve_flags, NULL,
+ ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
+ "(flags param eddsa)" :
+ ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_DJB_TWEAK))?
+ "(flags param djb-tweak)" :
+ ((flags & PUBKEY_FLAG_PARAM))?
+ "(flags param)" : ((flags & PUBKEY_FLAG_EDDSA))?
+ "(flags eddsa)" : "(flags djb-tweak)" );
+ if (rc)
+ goto leave;
+ }
+
+ if ((flags & PUBKEY_FLAG_PARAM) && ec->name)
+ rc = sexp_build (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)(q%m)))"
+ " (private-key"
+ " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)(q%m)(d%m)))"
+ " )",
+ curve_info, curve_flags,
+ ec->p, ec->a, ec->b, base, ec->n, ec->h, public,
+ curve_info, curve_flags,
+ ec->p, ec->a, ec->b, base, ec->n, ec->h, public,
+ ec->d);
+ else
+ rc = sexp_build (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (ecc%S%S(q%m)))"
+ " (private-key"
+ " (ecc%S%S(q%m)(d%m)))"
+ " )",
+ curve_info, curve_flags,
+ public,
+ curve_info, curve_flags,
+ public, ec->d);
+ if (rc)
+ goto leave;
+
+ if (DBG_CIPHER)
+ {
+ log_printmpi ("ecgen result p", ec->p);
+ log_printmpi ("ecgen result a", ec->a);
+ log_printmpi ("ecgen result b", ec->b);
+ log_printmpi ("ecgen result G", base);
+ log_printmpi ("ecgen result n", ec->n);
+ log_debug ("ecgen result h:+%02x\n", ec->h);
+ log_printmpi ("ecgen result Q", public);
+ log_printmpi ("ecgen result d", ec->d);
+ if ((flags & PUBKEY_FLAG_EDDSA))
+ log_debug ("ecgen result using Ed25519+EdDSA\n");
+ }
+
+ leave:
+ mpi_free (public);
+ mpi_free (base);
+ mpi_free (Gx);
+ mpi_free (Gy);
+ mpi_free (Qx);
+ mpi_free (Qy);
+ _gcry_mpi_ec_free (ec);
+ sexp_release (curve_flags);
+ sexp_release (curve_info);
+ return rc;
+}
+
+
+static gcry_err_code_t
+ecc_check_secret_key (gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ int flags = 0;
+ mpi_ec_t ec = NULL;
+
+ /*
+ * Extract the key.
+ */
+ rc = _gcry_mpi_ec_internal_new (&ec, &flags, "ecc_testkey", keyparms, NULL);
+ if (rc)
+ goto leave;
+ if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->Q || !ec->d)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+
+ if (check_secret_key (ec, flags))
+ rc = GPG_ERR_BAD_SECKEY;
+
+ leave:
+ _gcry_mpi_ec_free (ec);
+ if (DBG_CIPHER)
+ log_debug ("ecc_testkey => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t data = NULL;
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+ mpi_ec_t ec = NULL;
+ int flags = 0;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, 0);
+
+ /*
+ * Extract the key.
+ */
+ rc = _gcry_mpi_ec_internal_new (&ec, &flags, "ecc_sign", keyparms, NULL);
+ if (rc)
+ goto leave;
+ if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->d)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+
+ ctx.flags |= flags;
+ if (ec->model == MPI_EC_EDWARDS && ec->dialect == ECC_DIALECT_SAFECURVE)
+ ctx.flags |= PUBKEY_FLAG_EDDSA;
+ /* Clear hash algo for EdDSA. */
+ if ((ctx.flags & PUBKEY_FLAG_EDDSA))
+ ctx.hash_algo = GCRY_MD_NONE;
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("ecc_sign data", data);
+
+ /* Hash algo is determined by curve in EdDSA. Fill it if not specified. */
+ if ((ctx.flags & PUBKEY_FLAG_EDDSA) && !ctx.hash_algo)
+ {
+ if (ec->dialect == ECC_DIALECT_ED25519)
+ ctx.hash_algo = GCRY_MD_SHA512;
+ else if (ec->dialect == ECC_DIALECT_SAFECURVE)
+ ctx.hash_algo = GCRY_MD_SHAKE256;
+ }
+
+ sig_r = mpi_new (0);
+ sig_s = mpi_new (0);
+ if ((ctx.flags & PUBKEY_FLAG_EDDSA))
+ {
+ /* EdDSA requires the public key. */
+ rc = _gcry_ecc_eddsa_sign (data, ec, sig_r, sig_s, &ctx);
+ if (!rc)
+ rc = sexp_build (r_sig, NULL,
+ "(sig-val(eddsa(r%M)(s%M)))", sig_r, sig_s);
+ }
+ else if ((ctx.flags & PUBKEY_FLAG_GOST))
+ {
+ rc = _gcry_ecc_gost_sign (data, ec, sig_r, sig_s);
+ if (!rc)
+ rc = sexp_build (r_sig, NULL,
+ "(sig-val(gost(r%M)(s%M)))", sig_r, sig_s);
+ }
+ else if ((ctx.flags & PUBKEY_FLAG_SM2))
+ {
+ rc = _gcry_ecc_sm2_sign (data, ec, sig_r, sig_s,
+ ctx.flags, ctx.hash_algo);
+ if (!rc)
+ rc = sexp_build (r_sig, NULL,
+ "(sig-val(sm2(r%M)(s%M)))", sig_r, sig_s);
+ }
+ else
+ {
+ rc = _gcry_ecc_ecdsa_sign (data, ec, sig_r, sig_s,
+ ctx.flags, ctx.hash_algo);
+ if (!rc)
+ rc = sexp_build (r_sig, NULL,
+ "(sig-val(ecdsa(r%M)(s%M)))", sig_r, sig_s);
+ }
+
+ leave:
+ _gcry_mpi_release (sig_r);
+ _gcry_mpi_release (sig_s);
+ _gcry_mpi_release (data);
+ _gcry_mpi_ec_free (ec);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("ecc_sign => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+ gcry_mpi_t data = NULL;
+ int sigflags;
+ mpi_ec_t ec = NULL;
+ int flags = 0;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+ ecc_get_nbits (s_keyparms));
+
+ /*
+ * Extract the key.
+ */
+ rc = _gcry_mpi_ec_internal_new (&ec, &flags, "ecc_verify",
+ s_keyparms, NULL);
+ if (rc)
+ goto leave;
+ if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->Q)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+
+ if (ec->model == MPI_EC_MONTGOMERY)
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc_verify: Can't use a Montgomery curve\n");
+ rc = GPG_ERR_INTERNAL;
+ goto leave;
+ }
+
+ ctx.flags |= flags;
+ if (ec->model == MPI_EC_EDWARDS && ec->dialect == ECC_DIALECT_SAFECURVE)
+ ctx.flags |= PUBKEY_FLAG_EDDSA;
+ /* Clear hash algo for EdDSA. */
+ if ((ctx.flags & PUBKEY_FLAG_EDDSA))
+ ctx.hash_algo = GCRY_MD_NONE;
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("ecc_verify data", data);
+
+ /* Hash algo is determined by curve in EdDSA. Fill it if not specified. */
+ if ((ctx.flags & PUBKEY_FLAG_EDDSA) && !ctx.hash_algo)
+ {
+ if (ec->dialect == ECC_DIALECT_ED25519)
+ ctx.hash_algo = GCRY_MD_SHA512;
+ else if (ec->dialect == ECC_DIALECT_SAFECURVE)
+ ctx.hash_algo = GCRY_MD_SHAKE256;
+ }
+
+ /*
+ * Extract the signature value.
+ */
+ rc = _gcry_pk_util_preparse_sigval (s_sig, ecc_names, &l1, &sigflags);
+ if (rc)
+ goto leave;
+ rc = sexp_extract_param (l1, NULL, (sigflags & PUBKEY_FLAG_EDDSA)? "/rs":"rs",
+ &sig_r, &sig_s, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("ecc_verify s_r", sig_r);
+ log_mpidump ("ecc_verify s_s", sig_s);
+ }
+ if ((ctx.flags & PUBKEY_FLAG_EDDSA) ^ (sigflags & PUBKEY_FLAG_EDDSA))
+ {
+ rc = GPG_ERR_CONFLICT; /* Inconsistent use of flag/algoname. */
+ goto leave;
+ }
+
+ /*
+ * Verify the signature.
+ */
+ if ((sigflags & PUBKEY_FLAG_EDDSA))
+ {
+ rc = _gcry_ecc_eddsa_verify (data, ec, sig_r, sig_s, &ctx);
+ }
+ else if ((sigflags & PUBKEY_FLAG_GOST))
+ {
+ rc = _gcry_ecc_gost_verify (data, ec, sig_r, sig_s);
+ }
+ else if ((sigflags & PUBKEY_FLAG_SM2))
+ {
+ rc = _gcry_ecc_sm2_verify (data, ec, sig_r, sig_s);
+ }
+ else
+ {
+ rc = _gcry_ecc_ecdsa_verify (data, ec, sig_r, sig_s);
+ }
+
+ leave:
+ _gcry_mpi_release (data);
+ _gcry_mpi_release (sig_r);
+ _gcry_mpi_release (sig_s);
+ _gcry_mpi_ec_free (ec);
+ sexp_release (l1);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("ecc_verify => %s\n", rc?gpg_strerror (rc):"Good");
+ return rc;
+}
+
+
+/* ecdh raw is classic 2-round DH protocol published in 1976.
+ *
+ * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
+ *
+ * As with any PK operation, encrypt version uses a public key and
+ * decrypt -- private.
+ *
+ * Symbols used below:
+ * G - field generator point
+ * d - private long-term scalar
+ * dG - public long-term key
+ * k - ephemeral scalar
+ * kG - ephemeral public key
+ * dkG - shared secret
+ *
+ * ecc_encrypt_raw description:
+ * input:
+ * data[0] : private scalar (k)
+ * output: A new S-expression with the parameters:
+ * s : shared point (kdG)
+ * e : generated ephemeral public key (kG)
+ *
+ * ecc_decrypt_raw description:
+ * input:
+ * data[0] : a point kG (ephemeral public key)
+ * output:
+ * result[0] : shared point (kdG)
+ */
+static gcry_err_code_t
+ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ unsigned int nbits;
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t mpi_s = NULL;
+ gcry_mpi_t mpi_e = NULL;
+ gcry_mpi_t data = NULL;
+ mpi_ec_t ec = NULL;
+ int flags = 0;
+ int no_error_on_infinity;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+ (nbits = ecc_get_nbits (keyparms)));
+
+ /*
+ * Extract the key.
+ */
+ rc = _gcry_mpi_ec_internal_new (&ec, &flags, "ecc_encrypt", keyparms, NULL);
+ if (rc)
+ goto leave;
+
+ if (ec->dialect == ECC_DIALECT_SAFECURVE)
+ {
+ ctx.flags |= PUBKEY_FLAG_RAW_FLAG;
+ no_error_on_infinity = 1;
+ }
+ else if ((flags & PUBKEY_FLAG_DJB_TWEAK))
+ no_error_on_infinity = 1;
+ else
+ no_error_on_infinity = 0;
+
+ /*
+ * Extract the data.
+ */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+
+ /*
+ * Tweak the scalar bits by cofactor and number of bits of the field.
+ * It assumes the cofactor is a power of 2.
+ */
+ if ((flags & PUBKEY_FLAG_DJB_TWEAK))
+ {
+ int i;
+
+ for (i = 0; (ec->h & (1 << i)) == 0; i++)
+ mpi_clear_bit (data, i);
+ mpi_set_highbit (data, ec->nbits - 1);
+ }
+ if (DBG_CIPHER)
+ log_mpidump ("ecc_encrypt data", data);
+
+ if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->Q)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+
+ if ((ctx.flags & PUBKEY_FLAG_SM2))
+ {
+ /* All encryption will be done, return it. */
+ rc = _gcry_ecc_sm2_encrypt (r_ciph, data, ec);
+ goto leave;
+ }
+
+ /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
+ {
+ mpi_point_struct R; /* Result that we return. */
+ gcry_mpi_t x, y;
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+
+ rc = 0;
+ x = mpi_new (0);
+ if (ec->model == MPI_EC_MONTGOMERY)
+ y = NULL;
+ else
+ y = mpi_new (0);
+
+ point_init (&R);
+
+ /* R = kQ <=> R = kdG */
+ _gcry_mpi_ec_mul_point (&R, data, ec->Q, ec);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
+ {
+ /*
+ * Here, X is 0. In the X25519 computation on Curve25519, X0
+ * function maps infinity to zero. So, when PUBKEY_FLAG_DJB_TWEAK
+ * is enabled, return the result of 0 not raising an error.
+ *
+ * This is a corner case. It never occurs with properly
+ * generated public keys, but it might happen with blindly
+ * imported public key which might not follow the key
+ * generation procedure.
+ */
+ if (!no_error_on_infinity)
+ { /* It's not for X25519, then, the input data was simply wrong. */
+ rc = GPG_ERR_INV_DATA;
+ goto leave_main;
+ }
+ }
+ if (y)
+ mpi_s = _gcry_ecc_ec2os (x, y, ec->p);
+ else
+ {
+ rc = _gcry_ecc_mont_encodepoint (x, nbits,
+ ec->dialect != ECC_DIALECT_SAFECURVE,
+ &rawmpi, &rawmpilen);
+ if (rc)
+ goto leave_main;
+ mpi_s = mpi_new (0);
+ mpi_set_opaque (mpi_s, rawmpi, rawmpilen*8);
+ }
+
+ /* R = kG */
+ _gcry_mpi_ec_mul_point (&R, data, ec->G, ec);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave_main;
+ }
+ if (y)
+ mpi_e = _gcry_ecc_ec2os (x, y, ec->p);
+ else
+ {
+ rc = _gcry_ecc_mont_encodepoint (x, nbits,
+ ec->dialect != ECC_DIALECT_SAFECURVE,
+ &rawmpi, &rawmpilen);
+ if (!rc)
+ {
+ mpi_e = mpi_new (0);
+ mpi_set_opaque (mpi_e, rawmpi, rawmpilen*8);
+ }
+ }
+
+ leave_main:
+ mpi_free (x);
+ mpi_free (y);
+ point_free (&R);
+ if (rc)
+ goto leave;
+ }
+
+ if (!rc)
+ rc = sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))", mpi_s, mpi_e);
+
+ leave:
+ _gcry_mpi_release (data);
+ _gcry_mpi_release (mpi_s);
+ _gcry_mpi_release (mpi_e);
+ _gcry_mpi_ec_free (ec);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("ecc_encrypt => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+/* input:
+ * data[0] : a point kG (ephemeral public key)
+ * output:
+ * resaddr[0] : shared point kdG
+ *
+ * see ecc_encrypt_raw for details.
+ */
+static gcry_err_code_t
+ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ unsigned int nbits;
+ gpg_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ gcry_mpi_t data_e = NULL;
+ mpi_ec_t ec = NULL;
+ mpi_point_struct kG;
+ mpi_point_struct R;
+ gcry_mpi_t r = NULL;
+ int flags = 0;
+ int enable_specific_point_validation;
+
+ point_init (&kG);
+ point_init (&R);
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
+ (nbits = ecc_get_nbits (keyparms)));
+
+ /*
+ * Extract the key.
+ */
+ rc = _gcry_mpi_ec_internal_new (&ec, &flags, "ecc_decrypt", keyparms, NULL);
+ if (rc)
+ goto leave;
+
+ if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->d)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+
+ /*
+ * Extract the data.
+ */
+ rc = _gcry_pk_util_preparse_encval (s_data, ecc_names, &l1, &ctx);
+ if (rc)
+ goto leave;
+ if ((ctx.flags & PUBKEY_FLAG_SM2))
+ {
+ /* All decryption will be done, return it. */
+ rc = _gcry_ecc_sm2_decrypt (r_plain, l1, ec);
+ goto leave;
+ }
+ else
+ {
+ rc = sexp_extract_param (l1, NULL, "/e", &data_e, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_printmpi ("ecc_decrypt d_e", data_e);
+ }
+
+ if (ec->dialect == ECC_DIALECT_SAFECURVE || (flags & PUBKEY_FLAG_DJB_TWEAK))
+ enable_specific_point_validation = 1;
+ else
+ enable_specific_point_validation = 0;
+
+ /*
+ * Compute the plaintext.
+ */
+ if (ec->model == MPI_EC_MONTGOMERY)
+ rc = _gcry_ecc_mont_decodepoint (data_e, ec, &kG);
+ else
+ rc = _gcry_ecc_sec_decodepoint (data_e, ec, &kG);
+ if (rc)
+ goto leave;
+
+ if (DBG_CIPHER)
+ log_printpnt ("ecc_decrypt kG", &kG, NULL);
+
+ if (enable_specific_point_validation)
+ {
+ /* For X25519, by its definition, validation should not be done. */
+ /* (Instead, we do output check.)
+ *
+ * However, to mitigate secret key leak from our implementation,
+ * we also do input validation here. For constant-time
+ * implementation, we can remove this input validation.
+ */
+ if (_gcry_mpi_ec_bad_point (&kG, ec))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+ }
+ else if (!_gcry_mpi_ec_curve_point (&kG, ec))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* R = dkG */
+ _gcry_mpi_ec_mul_point (&R, ec->d, &kG, ec);
+
+ /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */
+ {
+ gcry_mpi_t x, y;
+
+ x = mpi_new (0);
+ if (ec->model == MPI_EC_MONTGOMERY)
+ y = NULL;
+ else
+ y = mpi_new (0);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ /*
+ * Note for X25519.
+ *
+ * By the definition of X25519, this is the case where X25519
+ * returns 0, mapping infinity to zero. However, we
+ * deliberately let it return an error.
+ *
+ * For X25519 ECDH, comming here means that it might be
+ * decrypted by anyone with the shared secret of 0 (the result
+ * of this function could be always 0 by other scalar values,
+ * other than the private key of D).
+ *
+ * So, it looks like an encrypted message but it can be
+ * decrypted by anyone, or at least something wrong
+ * happens. Recipient should not proceed as if it were
+ * properly encrypted message.
+ *
+ * This handling is needed for our major usage of GnuPG,
+ * where it does the One-Pass Diffie-Hellman method,
+ * C(1, 1, ECC CDH), with an ephemeral key.
+ */
+ }
+
+ if (y)
+ r = _gcry_ecc_ec2os (x, y, ec->p);
+ else
+ {
+
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+
+ rc = _gcry_ecc_mont_encodepoint (x, nbits,
+ ec->dialect != ECC_DIALECT_SAFECURVE,
+ &rawmpi, &rawmpilen);
+ if (rc)
+ goto leave;
+
+ r = mpi_new (0);
+ mpi_set_opaque (r, rawmpi, rawmpilen*8);
+ }
+ if (!r)
+ rc = gpg_err_code_from_syserror ();
+ else
+ rc = 0;
+ mpi_free (x);
+ mpi_free (y);
+ }
+ if (DBG_CIPHER)
+ log_printmpi ("ecc_decrypt res", r);
+
+ if (!rc)
+ rc = sexp_build (r_plain, NULL, "(value %m)", r);
+
+ leave:
+ point_free (&R);
+ point_free (&kG);
+ _gcry_mpi_release (r);
+ _gcry_mpi_release (data_e);
+ sexp_release (l1);
+ _gcry_mpi_ec_free (ec);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("ecc_decrypt => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+/* Return the number of bits for the key described by PARMS. On error
+ * 0 is returned. The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ * (ecc
+ * (curve <name>)
+ * (p <mpi>)
+ * (a <mpi>)
+ * (b <mpi>)
+ * (g <mpi>)
+ * (n <mpi>)
+ * (q <mpi>))
+ *
+ * More parameters may be given. Either P or CURVE is needed.
+ */
+static unsigned int
+ecc_get_nbits (gcry_sexp_t parms)
+{
+ gcry_sexp_t l1;
+ gcry_mpi_t p;
+ unsigned int nbits = 0;
+ char *curve;
+
+ l1 = sexp_find_token (parms, "p", 1);
+ if (!l1)
+ { /* Parameter P not found - check whether we have "curve". */
+ l1 = sexp_find_token (parms, "curve", 5);
+ if (!l1)
+ return 0; /* Neither P nor CURVE found. */
+
+ curve = sexp_nth_string (l1, 1);
+ sexp_release (l1);
+ if (!curve)
+ return 0; /* No curve name given (or out of core). */
+
+ if (_gcry_ecc_fill_in_curve (0, curve, NULL, &nbits))
+ nbits = 0;
+ xfree (curve);
+ }
+ else
+ {
+ p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ if (p)
+ {
+ nbits = mpi_get_nbits (p);
+ _gcry_mpi_release (p);
+ }
+ }
+ return nbits;
+}
+
+
+/* See rsa.c for a description of this function. */
+static gpg_err_code_t
+compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
+{
+#define N_COMPONENTS 6
+ static const char names[N_COMPONENTS] = "pabgnq";
+ gpg_err_code_t rc;
+ gcry_sexp_t l1;
+ gcry_mpi_t values[N_COMPONENTS];
+ int idx;
+ char *curvename = NULL;
+ int flags = 0;
+ enum gcry_mpi_ec_models model = 0;
+ enum ecc_dialects dialect = 0;
+ const unsigned char *raw;
+ unsigned int n;
+
+ /* Clear the values first. */
+ for (idx=0; idx < N_COMPONENTS; idx++)
+ values[idx] = NULL;
+
+
+ /* Look for flags. */
+ l1 = sexp_find_token (keyparms, "flags", 0);
+ if (l1)
+ {
+ rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+ if (rc)
+ goto leave;
+ }
+
+ /* Extract the parameters. */
+ if ((flags & PUBKEY_FLAG_PARAM))
+ rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?/q",
+ &values[0], &values[1], &values[2],
+ &values[3], &values[4], &values[5],
+ NULL);
+ else
+ rc = sexp_extract_param (keyparms, NULL, "/q", &values[5], NULL);
+ if (rc)
+ goto leave;
+
+ /* Check whether a curve parameter is available and use that to fill
+ in missing values. */
+ sexp_release (l1);
+ l1 = sexp_find_token (keyparms, "curve", 5);
+ if (l1)
+ {
+ curvename = sexp_nth_string (l1, 1);
+ if (curvename)
+ {
+ rc = _gcry_ecc_update_curve_param (curvename,
+ &model, &dialect,
+ &values[0], &values[1], &values[2],
+ &values[3], &values[4]);
+ if (rc)
+ goto leave;
+ }
+ }
+
+ /* Guess required fields if a curve parameter has not been given.
+ FIXME: This is a crude hacks. We need to fix that. */
+ if (!curvename)
+ {
+ model = ((flags & PUBKEY_FLAG_EDDSA)
+ ? MPI_EC_EDWARDS
+ : MPI_EC_WEIERSTRASS);
+ dialect = ((flags & PUBKEY_FLAG_EDDSA)
+ ? ECC_DIALECT_ED25519
+ : ECC_DIALECT_STANDARD);
+ }
+
+ /* Check that all parameters are known and normalize all MPIs (that
+ should not be required but we use an internal function later and
+ thus we better make 100% sure that they are normalized). */
+ for (idx = 0; idx < N_COMPONENTS; idx++)
+ if (!values[idx])
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+ else
+ _gcry_mpi_normalize (values[idx]);
+
+ /* Uncompress the public key with the exception of EdDSA where
+ compression is the default and we thus compute the keygrip using
+ the compressed version. Because we don't support any non-eddsa
+ compression, the only thing we need to do is to compress
+ EdDSA. */
+ if ((flags & PUBKEY_FLAG_EDDSA) && dialect == ECC_DIALECT_ED25519)
+ {
+ const unsigned int pbits = mpi_get_nbits (values[0]);
+
+ rc = _gcry_ecc_eddsa_ensure_compact (values[5], pbits);
+ if (rc)
+ goto leave;
+ }
+ else if ((flags & PUBKEY_FLAG_DJB_TWEAK))
+ {
+ /* Remove the prefix 0x40 for keygrip computation. */
+ raw = mpi_get_opaque (values[5], &n);
+ if (raw)
+ {
+ n = (n + 7)/8;
+
+ if (n > 1 && (n%2) && raw[0] == 0x40)
+ if (!_gcry_mpi_set_opaque_copy (values[5], raw + 1, (n - 1)*8))
+ rc = gpg_err_code_from_syserror ();
+ }
+ else
+ {
+ rc = GPG_ERR_INV_OBJ;
+ goto leave;
+ }
+ }
+
+ /* Hash them all. */
+ for (idx = 0; idx < N_COMPONENTS; idx++)
+ {
+ char buf[30];
+
+ if (mpi_is_opaque (values[idx]))
+ {
+ raw = mpi_get_opaque (values[idx], &n);
+ n = (n + 7)/8;
+ snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], n);
+ _gcry_md_write (md, buf, strlen (buf));
+ _gcry_md_write (md, raw, n);
+ _gcry_md_write (md, ")", 1);
+ }
+ else
+ {
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+
+ rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
+ if (!rawmpi)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
+ _gcry_md_write (md, buf, strlen (buf));
+ _gcry_md_write (md, rawmpi, rawmpilen);
+ _gcry_md_write (md, ")", 1);
+ xfree (rawmpi);
+ }
+ }
+
+ leave:
+ xfree (curvename);
+ sexp_release (l1);
+ for (idx = 0; idx < N_COMPONENTS; idx++)
+ _gcry_mpi_release (values[idx]);
+
+ return rc;
+#undef N_COMPONENTS
+}
+
+
+
+/*
+ Low-level API helper functions.
+ */
+
+/* This is the worker function for gcry_pubkey_get_sexp for ECC
+ algorithms. Note that the caller has already stored NULL at
+ R_SEXP. */
+gpg_err_code_t
+_gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t mpi_G = NULL;
+ gcry_mpi_t mpi_Q = NULL;
+
+ if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
+ return GPG_ERR_BAD_CRYPT_CTX;
+
+ if (mode == GCRY_PK_GET_SECKEY && !ec->d)
+ return GPG_ERR_NO_SECKEY;
+
+ /* Compute the public point if it is missing. */
+ if (!ec->Q && ec->d)
+ ec->Q = _gcry_ecc_compute_public (NULL, ec);
+
+ /* Encode G and Q. */
+ mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
+ if (!mpi_G)
+ {
+ rc = GPG_ERR_BROKEN_PUBKEY;
+ goto leave;
+ }
+ if (!ec->Q)
+ {
+ rc = GPG_ERR_BAD_CRYPT_CTX;
+ goto leave;
+ }
+
+ if (ec->dialect == ECC_DIALECT_ED25519)
+ {
+ unsigned char *encpk;
+ unsigned int encpklen;
+
+ rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0,
+ &encpk, &encpklen);
+ if (rc)
+ goto leave;
+ mpi_Q = mpi_set_opaque (NULL, encpk, encpklen*8);
+ encpk = NULL;
+ }
+ else if (ec->model == MPI_EC_MONTGOMERY)
+ {
+ unsigned char *encpk;
+ unsigned int encpklen;
+
+ rc = _gcry_ecc_mont_encodepoint (ec->Q->x, ec->nbits,
+ ec->dialect != ECC_DIALECT_SAFECURVE,
+ &encpk, &encpklen);
+ if (rc)
+ goto leave;
+ mpi_Q = mpi_set_opaque (NULL, encpk, encpklen*8);
+ }
+ else
+ {
+ mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
+ }
+ if (!mpi_Q)
+ {
+ rc = GPG_ERR_BROKEN_PUBKEY;
+ goto leave;
+ }
+
+ /* Fixme: We should return a curve name instead of the parameters if
+ if know that they match a curve. */
+
+ if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
+ {
+ /* Let's return a private key. */
+ rc = sexp_build (r_sexp, NULL,
+ "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)(q%m)(d%m)))",
+ ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q, ec->d);
+ }
+ else if (ec->Q)
+ {
+ /* Let's return a public key. */
+ rc = sexp_build (r_sexp, NULL,
+ "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)(q%m)))",
+ ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q);
+ }
+ else
+ rc = GPG_ERR_BAD_CRYPT_CTX;
+
+ leave:
+ mpi_free (mpi_Q);
+ mpi_free (mpi_G);
+ return rc;
+}
+
+
+
+/*
+ Self-test section.
+ */
+
+static const char *
+selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+ /* Sample data from RFC 6979 section A.2.5, hash is of message "sample" */
+ static const char sample_data[] =
+ "(data (flags rfc6979)"
+ " (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
+ /**/ "62113d8a62add1bf#))";
+ static const char sample_data_bad[] =
+ "(data (flags rfc6979)"
+ " (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
+ /**/ "62113d8a62add1bf#))";
+ static const char signature_r[] =
+ "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716";
+ static const char signature_s[] =
+ "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8";
+
+ const char *errtxt = NULL;
+ gcry_error_t err;
+ gcry_sexp_t data = NULL;
+ gcry_sexp_t data_bad = NULL;
+ gcry_sexp_t sig = NULL;
+ gcry_sexp_t l1 = NULL;
+ gcry_sexp_t l2 = NULL;
+ gcry_mpi_t r = NULL;
+ gcry_mpi_t s = NULL;
+ gcry_mpi_t calculated_r = NULL;
+ gcry_mpi_t calculated_s = NULL;
+ int cmp;
+
+ err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
+ if (!err)
+ err = sexp_sscan (&data_bad, NULL,
+ sample_data_bad, strlen (sample_data_bad));
+ if (!err)
+ err = _gcry_mpi_scan (&r, GCRYMPI_FMT_HEX, signature_r, 0, NULL);
+ if (!err)
+ err = _gcry_mpi_scan (&s, GCRYMPI_FMT_HEX, signature_s, 0, NULL);
+
+ if (err)
+ {
+ errtxt = "converting data failed";
+ goto leave;
+ }
+
+ err = _gcry_pk_sign (&sig, data, skey);
+ if (err)
+ {
+ errtxt = "signing failed";
+ goto leave;
+ }
+
+ /* check against known signature */
+ errtxt = "signature validity failed";
+ l1 = _gcry_sexp_find_token (sig, "sig-val", 0);
+ if (!l1)
+ goto leave;
+ l2 = _gcry_sexp_find_token (l1, "ecdsa", 0);
+ if (!l2)
+ goto leave;
+
+ sexp_release (l1);
+ l1 = l2;
+
+ l2 = _gcry_sexp_find_token (l1, "r", 0);
+ if (!l2)
+ goto leave;
+ calculated_r = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!calculated_r)
+ goto leave;
+
+ sexp_release (l2);
+ l2 = _gcry_sexp_find_token (l1, "s", 0);
+ if (!l2)
+ goto leave;
+ calculated_s = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!calculated_s)
+ goto leave;
+
+ errtxt = "known sig check failed";
+
+ cmp = _gcry_mpi_cmp (r, calculated_r);
+ if (cmp)
+ goto leave;
+ cmp = _gcry_mpi_cmp (s, calculated_s);
+ if (cmp)
+ goto leave;
+
+ errtxt = NULL;
+
+ /* verify generated signature */
+ err = _gcry_pk_verify (sig, data, pkey);
+ if (err)
+ {
+ errtxt = "verify failed";
+ goto leave;
+ }
+ err = _gcry_pk_verify (sig, data_bad, pkey);
+ if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
+ {
+ errtxt = "bad signature not detected";
+ goto leave;
+ }
+
+
+ leave:
+ sexp_release (sig);
+ sexp_release (data_bad);
+ sexp_release (data);
+ sexp_release (l1);
+ sexp_release (l2);
+ mpi_release (r);
+ mpi_release (s);
+ mpi_release (calculated_r);
+ mpi_release (calculated_s);
+ return errtxt;
+}
+
+
+static gpg_err_code_t
+selftests_ecdsa (selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+ gcry_error_t err;
+ gcry_sexp_t skey = NULL;
+ gcry_sexp_t pkey = NULL;
+
+ what = "convert";
+ err = sexp_sscan (&skey, NULL, sample_secret_key_secp256,
+ strlen (sample_secret_key_secp256));
+ if (!err)
+ err = sexp_sscan (&pkey, NULL, sample_public_key_secp256,
+ strlen (sample_public_key_secp256));
+ if (err)
+ {
+ errtxt = _gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "key consistency";
+ err = ecc_check_secret_key(skey);
+ if (err)
+ {
+ errtxt = _gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "sign";
+ errtxt = selftest_sign (pkey, skey);
+ if (errtxt)
+ goto failed;
+
+ sexp_release(pkey);
+ sexp_release(skey);
+ return 0; /* Succeeded. */
+
+ failed:
+ sexp_release(pkey);
+ sexp_release(skey);
+ if (report)
+ report ("pubkey", GCRY_PK_ECC, 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)
+{
+ (void)extended;
+
+ if (algo != GCRY_PK_ECC)
+ return GPG_ERR_PUBKEY_ALGO;
+
+ return selftests_ecdsa (report);
+}
+
+
+
+
+gcry_pk_spec_t _gcry_pubkey_spec_ecc =
+ {
+ GCRY_PK_ECC, { 0, 1 },
+ (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
+ "ECC", ecc_names,
+ "pabgnhq", "pabgnhqd", "se", "rs", "pabgnhq",
+ ecc_generate,
+ ecc_check_secret_key,
+ ecc_encrypt_raw,
+ ecc_decrypt_raw,
+ ecc_sign,
+ ecc_verify,
+ ecc_get_nbits,
+ run_selftests,
+ compute_keygrip,
+ _gcry_ecc_get_curve,
+ _gcry_ecc_get_param_sexp
+ };
diff --git a/comm/third_party/libgcrypt/cipher/elgamal.c b/comm/third_party/libgcrypt/cipher/elgamal.c
new file mode 100644
index 0000000000..4eb52d620b
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/elgamal.c
@@ -0,0 +1,1149 @@
+/* Elgamal.c - Elgamal Public Key encryption
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ * 2008 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 <http://www.gnu.org/licenses/>.
+ *
+ * For a description of the algorithm, see:
+ * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ * ISBN 0-471-11709-9. Pages 476 ff.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+/* Blinding is used to mitigate side-channel attacks. You may undef
+ this to speed up the operation in case the system is secured
+ against physical and network mounted side-channel attacks. */
+#define USE_BLINDING 1
+
+
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t g; /* group generator */
+ gcry_mpi_t y; /* g^x mod p */
+} ELG_public_key;
+
+
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t g; /* group generator */
+ gcry_mpi_t y; /* g^x mod p */
+ gcry_mpi_t x; /* secret exponent */
+} ELG_secret_key;
+
+
+static const char *elg_names[] =
+ {
+ "elg",
+ "openpgp-elg",
+ "openpgp-elg-sig",
+ NULL,
+ };
+
+
+static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie);
+static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k);
+static gcry_err_code_t generate (ELG_secret_key *sk, unsigned nbits,
+ gcry_mpi_t **factors);
+static int check_secret_key (ELG_secret_key *sk);
+static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+ ELG_public_key *pkey);
+static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b,
+ ELG_secret_key *skey);
+static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+ ELG_secret_key *skey);
+static int verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+ ELG_public_key *pkey);
+static unsigned int elg_get_nbits (gcry_sexp_t parms);
+
+
+static void (*progress_cb) (void *, const char *, int, int, int);
+static void *progress_cb_data;
+
+void
+_gcry_register_pk_elg_progress (void (*cb) (void *, const char *,
+ int, int, int),
+ void *cb_data)
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+
+static void
+progress (int c)
+{
+ if (progress_cb)
+ progress_cb (progress_cb_data, "pk_elg", c, 0, 0);
+}
+
+
+/****************
+ * Michael Wiener's table on subgroup sizes to match field sizes.
+ * (floating around somewhere, probably based on the paper from
+ * Eurocrypt 96, page 332)
+ */
+static unsigned int
+wiener_map( unsigned int n )
+{
+ static struct { unsigned int p_n, q_n; } t[] =
+ { /* p q attack cost */
+ { 512, 119 }, /* 9 x 10^17 */
+ { 768, 145 }, /* 6 x 10^21 */
+ { 1024, 165 }, /* 7 x 10^24 */
+ { 1280, 183 }, /* 3 x 10^27 */
+ { 1536, 198 }, /* 7 x 10^29 */
+ { 1792, 212 }, /* 9 x 10^31 */
+ { 2048, 225 }, /* 8 x 10^33 */
+ { 2304, 237 }, /* 5 x 10^35 */
+ { 2560, 249 }, /* 3 x 10^37 */
+ { 2816, 259 }, /* 1 x 10^39 */
+ { 3072, 269 }, /* 3 x 10^40 */
+ { 3328, 279 }, /* 8 x 10^41 */
+ { 3584, 288 }, /* 2 x 10^43 */
+ { 3840, 296 }, /* 4 x 10^44 */
+ { 4096, 305 }, /* 7 x 10^45 */
+ { 4352, 313 }, /* 1 x 10^47 */
+ { 4608, 320 }, /* 2 x 10^48 */
+ { 4864, 328 }, /* 2 x 10^49 */
+ { 5120, 335 }, /* 3 x 10^50 */
+ { 0, 0 }
+ };
+ int i;
+
+ for(i=0; t[i].p_n; i++ )
+ {
+ if( n <= t[i].p_n )
+ return t[i].q_n;
+ }
+ /* Not in table - use an arbitrary high number. */
+ return n / 8 + 200;
+}
+
+static int
+test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
+{
+ ELG_public_key pk;
+ gcry_mpi_t test = mpi_new ( 0 );
+ gcry_mpi_t out1_a = mpi_new ( nbits );
+ gcry_mpi_t out1_b = mpi_new ( nbits );
+ gcry_mpi_t out2 = mpi_new ( nbits );
+ int failed = 0;
+
+ pk.p = sk->p;
+ pk.g = sk->g;
+ pk.y = sk->y;
+
+ _gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );
+
+ do_encrypt ( out1_a, out1_b, test, &pk );
+ decrypt ( out2, out1_a, out1_b, sk );
+ if ( mpi_cmp( test, out2 ) )
+ failed |= 1;
+
+ sign ( out1_a, out1_b, test, sk );
+ if ( !verify( out1_a, out1_b, test, &pk ) )
+ failed |= 2;
+
+ _gcry_mpi_release ( test );
+ _gcry_mpi_release ( out1_a );
+ _gcry_mpi_release ( out1_b );
+ _gcry_mpi_release ( out2 );
+
+ if (failed && !nodie)
+ log_fatal ("Elgamal test key for %s %s failed\n",
+ (failed & 1)? "encrypt+decrypt":"",
+ (failed & 2)? "sign+verify":"");
+ if (failed && DBG_CIPHER)
+ log_debug ("Elgamal test key for %s %s failed\n",
+ (failed & 1)? "encrypt+decrypt":"",
+ (failed & 2)? "sign+verify":"");
+
+ return failed;
+}
+
+
+/****************
+ * Generate a random secret exponent k from prime p, so that k is
+ * relatively prime to p-1. With SMALL_K set, k will be selected for
+ * better encryption performance - this must never be used signing!
+ */
+static gcry_mpi_t
+gen_k( gcry_mpi_t p, int small_k )
+{
+ gcry_mpi_t k = mpi_alloc_secure( 0 );
+ gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) );
+ gcry_mpi_t p_1 = mpi_copy(p);
+ unsigned int orig_nbits = mpi_get_nbits(p);
+ unsigned int nbits, nbytes;
+ char *rndbuf = NULL;
+
+ if (small_k)
+ {
+ /* Using a k much lesser than p is sufficient for encryption and
+ * it greatly improves the encryption performance. We use
+ * Wiener's table and add a large safety margin. */
+ nbits = wiener_map( orig_nbits ) * 3 / 2;
+ if( nbits >= orig_nbits )
+ BUG();
+ }
+ else
+ nbits = orig_nbits;
+
+
+ nbytes = (nbits+7)/8;
+ if( DBG_CIPHER )
+ log_debug("choosing a random k\n");
+ mpi_sub_ui( p_1, p, 1);
+ for(;;)
+ {
+ if( !rndbuf || nbits < 32 )
+ {
+ xfree(rndbuf);
+ rndbuf = _gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
+ }
+ else
+ {
+ /* Change only some of the higher bits. We could improve
+ this by directly requesting more memory at the first call
+ to get_random_bytes() and use this the here maybe it is
+ easier to do this directly in random.c Anyway, it is
+ highly inlikely that we will ever reach this code. */
+ char *pp = _gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
+ memcpy( rndbuf, pp, 4 );
+ xfree(pp);
+ }
+ _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
+
+ for(;;)
+ {
+ if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */
+ {
+ if( DBG_CIPHER )
+ progress('+');
+ break; /* no */
+ }
+ if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
+ {
+ if( DBG_CIPHER )
+ progress('-');
+ break; /* no */
+ }
+ if (mpi_gcd( temp, k, p_1 ))
+ goto found; /* okay, k is relative prime to (p-1) */
+ mpi_add_ui( k, k, 1 );
+ if( DBG_CIPHER )
+ progress('.');
+ }
+ }
+ found:
+ xfree (rndbuf);
+ if( DBG_CIPHER )
+ progress('\n');
+ mpi_free(p_1);
+ mpi_free(temp);
+
+ return k;
+}
+
+/****************
+ * Generate a key pair with a key of size NBITS
+ * Returns: 2 structures filled with all needed values
+ * and an array with n-1 factors of (p-1)
+ */
+static gcry_err_code_t
+generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
+{
+ gcry_err_code_t rc;
+ gcry_mpi_t p; /* the prime */
+ gcry_mpi_t p_min1;
+ gcry_mpi_t g;
+ gcry_mpi_t x; /* the secret exponent */
+ gcry_mpi_t y;
+ unsigned int qbits;
+ unsigned int xbits;
+ byte *rndbuf;
+
+ p_min1 = mpi_new ( nbits );
+ qbits = wiener_map( nbits );
+ if( qbits & 1 ) /* better have a even one */
+ qbits++;
+ g = mpi_alloc(1);
+ rc = _gcry_generate_elg_prime (0, nbits, qbits, g, &p, ret_factors);
+ if (rc)
+ {
+ mpi_free (p_min1);
+ mpi_free (g);
+ return rc;
+ }
+ mpi_sub_ui(p_min1, p, 1);
+
+
+ /* Select a random number which has these properties:
+ * 0 < x < p-1
+ * This must be a very good random number because this is the
+ * secret part. The prime is public and may be shared anyway,
+ * so a random generator level of 1 is used for the prime.
+ *
+ * I don't see a reason to have a x of about the same size
+ * as the p. It should be sufficient to have one about the size
+ * of q or the later used k plus a large safety margin. Decryption
+ * will be much faster with such an x.
+ */
+ xbits = qbits * 3 / 2;
+ if( xbits >= nbits )
+ BUG();
+ x = mpi_snew ( xbits );
+ if( DBG_CIPHER )
+ log_debug("choosing a random x of size %u\n", xbits );
+ rndbuf = NULL;
+ do
+ {
+ if( DBG_CIPHER )
+ progress('.');
+ if( rndbuf )
+ { /* Change only some of the higher bits */
+ if( xbits < 16 ) /* should never happen ... */
+ {
+ xfree(rndbuf);
+ rndbuf = _gcry_random_bytes_secure ((xbits+7)/8,
+ GCRY_VERY_STRONG_RANDOM);
+ }
+ else
+ {
+ char *r = _gcry_random_bytes_secure (2, GCRY_VERY_STRONG_RANDOM);
+ memcpy(rndbuf, r, 2 );
+ xfree (r);
+ }
+ }
+ else
+ {
+ rndbuf = _gcry_random_bytes_secure ((xbits+7)/8,
+ GCRY_VERY_STRONG_RANDOM );
+ }
+ _gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
+ mpi_clear_highbit( x, xbits+1 );
+ }
+ while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
+ xfree(rndbuf);
+
+ y = mpi_new (nbits);
+ mpi_powm( y, g, x, p );
+
+ if( DBG_CIPHER )
+ {
+ progress ('\n');
+ log_mpidump ("elg p", p );
+ log_mpidump ("elg g", g );
+ log_mpidump ("elg y", y );
+ log_mpidump ("elg x", x );
+ }
+
+ /* Copy the stuff to the key structures */
+ sk->p = p;
+ sk->g = g;
+ sk->y = y;
+ sk->x = x;
+
+ _gcry_mpi_release ( p_min1 );
+
+ /* Now we can test our keys (this should never fail!) */
+ test_keys ( sk, nbits - 64, 0 );
+
+ return 0;
+}
+
+
+/* Generate a key pair with a key of size NBITS not using a random
+ value for the secret key but the one given as X. This is useful to
+ implement a passphrase based decryption for a public key based
+ encryption. It has appliactions in backup systems.
+
+ Returns: A structure filled with all needed values and an array
+ with n-1 factors of (p-1). */
+static gcry_err_code_t
+generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
+ gcry_mpi_t **ret_factors )
+{
+ gcry_err_code_t rc;
+ gcry_mpi_t p; /* The prime. */
+ gcry_mpi_t p_min1; /* The prime minus 1. */
+ gcry_mpi_t g; /* The generator. */
+ gcry_mpi_t y; /* g^x mod p. */
+ unsigned int qbits;
+ unsigned int xbits;
+
+ sk->p = NULL;
+ sk->g = NULL;
+ sk->y = NULL;
+ sk->x = NULL;
+
+ /* Do a quick check to see whether X is suitable. */
+ xbits = mpi_get_nbits (x);
+ if ( xbits < 64 || xbits >= nbits )
+ return GPG_ERR_INV_VALUE;
+
+ p_min1 = mpi_new ( nbits );
+ qbits = wiener_map ( nbits );
+ if ( (qbits & 1) ) /* Better have an even one. */
+ qbits++;
+ g = mpi_alloc (1);
+ rc = _gcry_generate_elg_prime (0, nbits, qbits, g, &p, ret_factors );
+ if (rc)
+ {
+ mpi_free (p_min1);
+ mpi_free (g);
+ return rc;
+ }
+ mpi_sub_ui (p_min1, p, 1);
+
+ if (DBG_CIPHER)
+ log_debug ("using a supplied x of size %u", xbits );
+ if ( !(mpi_cmp_ui ( x, 0 ) > 0 && mpi_cmp ( x, p_min1 ) <0 ) )
+ {
+ _gcry_mpi_release ( p_min1 );
+ _gcry_mpi_release ( p );
+ _gcry_mpi_release ( g );
+ return GPG_ERR_INV_VALUE;
+ }
+
+ y = mpi_new (nbits);
+ mpi_powm ( y, g, x, p );
+
+ if ( DBG_CIPHER )
+ {
+ progress ('\n');
+ log_mpidump ("elg p", p );
+ log_mpidump ("elg g", g );
+ log_mpidump ("elg y", y );
+ log_mpidump ("elg x", x );
+ }
+
+ /* Copy the stuff to the key structures */
+ sk->p = p;
+ sk->g = g;
+ sk->y = y;
+ sk->x = mpi_copy (x);
+
+ _gcry_mpi_release ( p_min1 );
+
+ /* Now we can test our keys. */
+ if ( test_keys ( sk, nbits - 64, 1 ) )
+ {
+ _gcry_mpi_release ( sk->p ); sk->p = NULL;
+ _gcry_mpi_release ( sk->g ); sk->g = NULL;
+ _gcry_mpi_release ( sk->y ); sk->y = NULL;
+ _gcry_mpi_release ( sk->x ); sk->x = NULL;
+ return GPG_ERR_BAD_SECKEY;
+ }
+
+ return 0;
+}
+
+
+/****************
+ * Test whether the secret key is valid.
+ * Returns: if this is a valid key.
+ */
+static int
+check_secret_key( ELG_secret_key *sk )
+{
+ int rc;
+ gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
+
+ mpi_powm (y, sk->g, sk->x, sk->p);
+ rc = !mpi_cmp( y, sk->y );
+ mpi_free( y );
+ return rc;
+}
+
+
+static void
+do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
+{
+ gcry_mpi_t k;
+
+ /* Note: maybe we should change the interface, so that it
+ * is possible to check that input is < p and return an
+ * error code.
+ */
+
+ k = gen_k( pkey->p, 1 );
+ mpi_powm (a, pkey->g, k, pkey->p);
+
+ /* b = (y^k * input) mod p
+ * = ((y^k mod p) * (input mod p)) mod p
+ * and because input is < p
+ * = ((y^k mod p) * input) mod p
+ */
+ mpi_powm (b, pkey->y, k, pkey->p);
+ mpi_mulm (b, b, input, pkey->p);
+#if 0
+ if( DBG_CIPHER )
+ {
+ log_mpidump("elg encrypted y", pkey->y);
+ log_mpidump("elg encrypted p", pkey->p);
+ log_mpidump("elg encrypted k", k);
+ log_mpidump("elg encrypted M", input);
+ log_mpidump("elg encrypted a", a);
+ log_mpidump("elg encrypted b", b);
+ }
+#endif
+ mpi_free(k);
+}
+
+
+
+
+static void
+decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
+{
+ gcry_mpi_t t1, t2, r;
+ unsigned int nbits = mpi_get_nbits (skey->p);
+
+ mpi_normalize (a);
+ mpi_normalize (b);
+
+ t1 = mpi_snew (nbits);
+
+#ifdef USE_BLINDING
+
+ t2 = mpi_snew (nbits);
+ r = mpi_new (nbits);
+
+ /* We need a random number of about the prime size. The random
+ number merely needs to be unpredictable; thus we use level 0. */
+ _gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM);
+
+ /* t1 = r^x mod p */
+ mpi_powm (t1, r, skey->x, skey->p);
+ /* t2 = (a * r)^-x mod p */
+ mpi_mulm (t2, a, r, skey->p);
+ mpi_powm (t2, t2, skey->x, skey->p);
+ mpi_invm (t2, t2, skey->p);
+ /* t1 = (t1 * t2) mod p*/
+ mpi_mulm (t1, t1, t2, skey->p);
+
+ mpi_free (r);
+ mpi_free (t2);
+
+#else /*!USE_BLINDING*/
+
+ /* output = b/(a^x) mod p */
+ mpi_powm (t1, a, skey->x, skey->p);
+ mpi_invm (t1, t1, skey->p);
+
+#endif /*!USE_BLINDING*/
+
+ mpi_mulm (output, b, t1, skey->p);
+
+#if 0
+ if( DBG_CIPHER )
+ {
+ log_mpidump ("elg decrypted x", skey->x);
+ log_mpidump ("elg decrypted p", skey->p);
+ log_mpidump ("elg decrypted a", a);
+ log_mpidump ("elg decrypted b", b);
+ log_mpidump ("elg decrypted M", output);
+ }
+#endif
+ mpi_free (t1);
+}
+
+
+/****************
+ * Make an Elgamal signature out of INPUT
+ */
+
+static void
+sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
+{
+ gcry_mpi_t k;
+ gcry_mpi_t t = mpi_alloc( mpi_get_nlimbs(a) );
+ gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
+ gcry_mpi_t p_1 = mpi_copy(skey->p);
+
+ /*
+ * b = (t * inv) mod (p-1)
+ * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
+ * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
+ *
+ */
+ mpi_sub_ui(p_1, p_1, 1);
+ k = gen_k( skey->p, 0 /* no small K ! */ );
+ mpi_powm( a, skey->g, k, skey->p );
+ mpi_mul(t, skey->x, a );
+ mpi_subm(t, input, t, p_1 );
+ mpi_invm(inv, k, p_1 );
+ mpi_mulm(b, t, inv, p_1 );
+
+#if 0
+ if( DBG_CIPHER )
+ {
+ log_mpidump ("elg sign p", skey->p);
+ log_mpidump ("elg sign g", skey->g);
+ log_mpidump ("elg sign y", skey->y);
+ log_mpidump ("elg sign x", skey->x);
+ log_mpidump ("elg sign k", k);
+ log_mpidump ("elg sign M", input);
+ log_mpidump ("elg sign a", a);
+ log_mpidump ("elg sign b", b);
+ }
+#endif
+ mpi_free(k);
+ mpi_free(t);
+ mpi_free(inv);
+ mpi_free(p_1);
+}
+
+
+/****************
+ * Returns true if the signature composed of A and B is valid.
+ */
+static int
+verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
+{
+ int rc;
+ gcry_mpi_t t1;
+ gcry_mpi_t t2;
+ gcry_mpi_t base[4];
+ gcry_mpi_t ex[4];
+
+ if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
+ return 0; /* assertion 0 < a < p failed */
+
+ t1 = mpi_alloc( mpi_get_nlimbs(a) );
+ t2 = mpi_alloc( mpi_get_nlimbs(a) );
+
+#if 0
+ /* t1 = (y^a mod p) * (a^b mod p) mod p */
+ gcry_mpi_powm( t1, pkey->y, a, pkey->p );
+ gcry_mpi_powm( t2, a, b, pkey->p );
+ mpi_mulm( t1, t1, t2, pkey->p );
+
+ /* t2 = g ^ input mod p */
+ gcry_mpi_powm( t2, pkey->g, input, pkey->p );
+
+ rc = !mpi_cmp( t1, t2 );
+#elif 0
+ /* t1 = (y^a mod p) * (a^b mod p) mod p */
+ base[0] = pkey->y; ex[0] = a;
+ base[1] = a; ex[1] = b;
+ base[2] = NULL; ex[2] = NULL;
+ mpi_mulpowm( t1, base, ex, pkey->p );
+
+ /* t2 = g ^ input mod p */
+ gcry_mpi_powm( t2, pkey->g, input, pkey->p );
+
+ rc = !mpi_cmp( t1, t2 );
+#else
+ /* t1 = g ^ - input * y ^ a * a ^ b mod p */
+ mpi_invm(t2, pkey->g, pkey->p );
+ base[0] = t2 ; ex[0] = input;
+ base[1] = pkey->y; ex[1] = a;
+ base[2] = a; ex[2] = b;
+ base[3] = NULL; ex[3] = NULL;
+ mpi_mulpowm( t1, base, ex, pkey->p );
+ rc = !mpi_cmp_ui( t1, 1 );
+
+#endif
+
+ mpi_free(t1);
+ mpi_free(t2);
+ return rc;
+}
+
+/*********************************************
+ ************** interface ******************
+ *********************************************/
+
+static gpg_err_code_t
+elg_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+{
+ gpg_err_code_t rc;
+ unsigned int nbits;
+ ELG_secret_key sk;
+ gcry_mpi_t xvalue = NULL;
+ gcry_sexp_t l1;
+ gcry_mpi_t *factors = NULL;
+ gcry_sexp_t misc_info = NULL;
+
+ memset (&sk, 0, sizeof sk);
+
+ rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+ if (rc)
+ return rc;
+
+ /* Parse the optional xvalue element. */
+ l1 = sexp_find_token (genparms, "xvalue", 0);
+ if (l1)
+ {
+ xvalue = sexp_nth_mpi (l1, 1, 0);
+ sexp_release (l1);
+ if (!xvalue)
+ return GPG_ERR_BAD_MPI;
+ }
+
+ if (xvalue)
+ {
+ rc = generate_using_x (&sk, nbits, xvalue, &factors);
+ mpi_free (xvalue);
+ }
+ else
+ {
+ rc = generate (&sk, nbits, &factors);
+ }
+ if (rc)
+ goto leave;
+
+ if (factors && factors[0])
+ {
+ int nfac;
+ void **arg_list;
+ char *buffer, *p;
+
+ for (nfac = 0; factors[nfac]; nfac++)
+ ;
+ arg_list = xtrycalloc (nfac+1, sizeof *arg_list);
+ if (!arg_list)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ buffer = xtrymalloc (30 + nfac*2 + 2 + 1);
+ if (!buffer)
+ {
+ rc = gpg_err_code_from_syserror ();
+ xfree (arg_list);
+ goto leave;
+ }
+ p = stpcpy (buffer, "(misc-key-info(pm1-factors");
+ for(nfac = 0; factors[nfac]; nfac++)
+ {
+ p = stpcpy (p, "%m");
+ arg_list[nfac] = factors + nfac;
+ }
+ p = stpcpy (p, "))");
+ rc = sexp_build_array (&misc_info, NULL, buffer, arg_list);
+ xfree (arg_list);
+ xfree (buffer);
+ if (rc)
+ goto leave;
+ }
+
+ rc = sexp_build (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (elg(p%m)(g%m)(y%m)))"
+ " (private-key"
+ " (elg(p%m)(g%m)(y%m)(x%m)))"
+ " %S)",
+ sk.p, sk.g, sk.y,
+ sk.p, sk.g, sk.y, sk.x,
+ misc_info);
+
+ leave:
+ mpi_free (sk.p);
+ mpi_free (sk.g);
+ mpi_free (sk.y);
+ mpi_free (sk.x);
+ sexp_release (misc_info);
+ if (factors)
+ {
+ gcry_mpi_t *mp;
+ for (mp = factors; *mp; mp++)
+ mpi_free (*mp);
+ xfree (factors);
+ }
+
+ return rc;
+}
+
+
+static gcry_err_code_t
+elg_check_secret_key (gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ ELG_secret_key sk = {NULL, NULL, NULL, NULL};
+
+ rc = sexp_extract_param (keyparms, NULL, "pgyx",
+ &sk.p, &sk.g, &sk.y, &sk.x,
+ NULL);
+ if (rc)
+ goto leave;
+
+ if (!check_secret_key (&sk))
+ rc = GPG_ERR_BAD_SECKEY;
+
+ leave:
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+ if (DBG_CIPHER)
+ log_debug ("elg_testkey => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+elg_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t mpi_a = NULL;
+ gcry_mpi_t mpi_b = NULL;
+ gcry_mpi_t data = NULL;
+ ELG_public_key pk = { NULL, NULL, NULL };
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+ elg_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("elg_encrypt data", data);
+ if (mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the key. */
+ rc = sexp_extract_param (keyparms, NULL, "pgy",
+ &pk.p, &pk.g, &pk.y, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("elg_encrypt p", pk.p);
+ log_mpidump ("elg_encrypt g", pk.g);
+ log_mpidump ("elg_encrypt y", pk.y);
+ }
+
+ /* Do Elgamal computation and build result. */
+ mpi_a = mpi_new (0);
+ mpi_b = mpi_new (0);
+ do_encrypt (mpi_a, mpi_b, data, &pk);
+ rc = sexp_build (r_ciph, NULL, "(enc-val(elg(a%m)(b%m)))", mpi_a, mpi_b);
+
+ leave:
+ _gcry_mpi_release (mpi_a);
+ _gcry_mpi_release (mpi_b);
+ _gcry_mpi_release (pk.p);
+ _gcry_mpi_release (pk.g);
+ _gcry_mpi_release (pk.y);
+ _gcry_mpi_release (data);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("elg_encrypt => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+elg_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ gpg_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ gcry_mpi_t data_a = NULL;
+ gcry_mpi_t data_b = NULL;
+ ELG_secret_key sk = {NULL, NULL, NULL, NULL};
+ gcry_mpi_t plain = NULL;
+ unsigned char *unpad = NULL;
+ size_t unpadlen = 0;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
+ elg_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_preparse_encval (s_data, elg_names, &l1, &ctx);
+ if (rc)
+ goto leave;
+ rc = sexp_extract_param (l1, NULL, "ab", &data_a, &data_b, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_printmpi ("elg_decrypt d_a", data_a);
+ log_printmpi ("elg_decrypt d_b", data_b);
+ }
+ if (mpi_is_opaque (data_a) || mpi_is_opaque (data_b))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the key. */
+ rc = sexp_extract_param (keyparms, NULL, "pgyx",
+ &sk.p, &sk.g, &sk.y, &sk.x,
+ NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_printmpi ("elg_decrypt p", sk.p);
+ log_printmpi ("elg_decrypt g", sk.g);
+ log_printmpi ("elg_decrypt y", sk.y);
+ if (!fips_mode ())
+ log_printmpi ("elg_decrypt x", sk.x);
+ }
+
+ plain = mpi_snew (ctx.nbits);
+ decrypt (plain, data_a, data_b, &sk);
+ if (DBG_CIPHER)
+ log_printmpi ("elg_decrypt res", plain);
+
+ /* Reverse the encoding and build the s-expression. */
+ switch (ctx.encoding)
+ {
+ case PUBKEY_ENC_PKCS1:
+ rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, ctx.nbits, plain);
+ mpi_free (plain); plain = NULL;
+ if (!rc)
+ rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad);
+ break;
+
+ case PUBKEY_ENC_OAEP:
+ rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen,
+ ctx.nbits, ctx.hash_algo, plain,
+ ctx.label, ctx.labellen);
+ mpi_free (plain); plain = NULL;
+ if (!rc)
+ rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad);
+ break;
+
+ default:
+ /* Raw format. For backward compatibility we need to assume a
+ signed mpi by using the sexp format string "%m". */
+ rc = sexp_build (r_plain, NULL,
+ (ctx.flags & PUBKEY_FLAG_LEGACYRESULT)
+ ? "%m" : "(value %m)",
+ plain);
+ break;
+ }
+
+
+ leave:
+ xfree (unpad);
+ _gcry_mpi_release (plain);
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+ _gcry_mpi_release (data_a);
+ _gcry_mpi_release (data_b);
+ sexp_release (l1);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("elg_decrypt => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+elg_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t data = NULL;
+ ELG_secret_key sk = {NULL, NULL, NULL, NULL};
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
+ elg_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("elg_sign data", data);
+ if (mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the key. */
+ rc = sexp_extract_param (keyparms, NULL, "pgyx",
+ &sk.p, &sk.g, &sk.y, &sk.x, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("elg_sign p", sk.p);
+ log_mpidump ("elg_sign g", sk.g);
+ log_mpidump ("elg_sign y", sk.y);
+ if (!fips_mode ())
+ log_mpidump ("elg_sign x", sk.x);
+ }
+
+ sig_r = mpi_new (0);
+ sig_s = mpi_new (0);
+ sign (sig_r, sig_s, data, &sk);
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("elg_sign sig_r", sig_r);
+ log_mpidump ("elg_sign sig_s", sig_s);
+ }
+ rc = sexp_build (r_sig, NULL, "(sig-val(elg(r%M)(s%M)))", sig_r, sig_s);
+
+ leave:
+ _gcry_mpi_release (sig_r);
+ _gcry_mpi_release (sig_s);
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+ _gcry_mpi_release (data);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("elg_sign => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+elg_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+ gcry_mpi_t data = NULL;
+ ELG_public_key pk = { NULL, NULL, NULL };
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+ elg_get_nbits (s_keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("elg_verify data", data);
+ if (mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the signature value. */
+ rc = _gcry_pk_util_preparse_sigval (s_sig, elg_names, &l1, NULL);
+ if (rc)
+ goto leave;
+ rc = sexp_extract_param (l1, NULL, "rs", &sig_r, &sig_s, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("elg_verify s_r", sig_r);
+ log_mpidump ("elg_verify s_s", sig_s);
+ }
+
+ /* Extract the key. */
+ rc = sexp_extract_param (s_keyparms, NULL, "pgy",
+ &pk.p, &pk.g, &pk.y, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("elg_verify p", pk.p);
+ log_mpidump ("elg_verify g", pk.g);
+ log_mpidump ("elg_verify y", pk.y);
+ }
+
+ /* Verify the signature. */
+ if (!verify (sig_r, sig_s, data, &pk))
+ rc = GPG_ERR_BAD_SIGNATURE;
+
+ leave:
+ _gcry_mpi_release (pk.p);
+ _gcry_mpi_release (pk.g);
+ _gcry_mpi_release (pk.y);
+ _gcry_mpi_release (data);
+ _gcry_mpi_release (sig_r);
+ _gcry_mpi_release (sig_s);
+ sexp_release (l1);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("elg_verify => %s\n", rc?gpg_strerror (rc):"Good");
+ return rc;
+}
+
+
+/* Return the number of bits for the key described by PARMS. On error
+ * 0 is returned. The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ * (dsa
+ * (p <mpi>)
+ * (g <mpi>)
+ * (y <mpi>))
+ *
+ * More parameters may be given but we only need P here.
+ */
+static unsigned int
+elg_get_nbits (gcry_sexp_t parms)
+{
+ gcry_sexp_t l1;
+ gcry_mpi_t p;
+ unsigned int nbits;
+
+ l1 = sexp_find_token (parms, "p", 1);
+ if (!l1)
+ return 0; /* Parameter P not found. */
+
+ p= sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ nbits = p? mpi_get_nbits (p) : 0;
+ _gcry_mpi_release (p);
+ return nbits;
+}
+
+
+
+gcry_pk_spec_t _gcry_pubkey_spec_elg =
+ {
+ GCRY_PK_ELG, { 0, 0 },
+ (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
+ "ELG", elg_names,
+ "pgy", "pgyx", "ab", "rs", "pgy",
+ elg_generate,
+ elg_check_secret_key,
+ elg_encrypt,
+ elg_decrypt,
+ elg_sign,
+ elg_verify,
+ elg_get_nbits,
+ };
diff --git a/comm/third_party/libgcrypt/cipher/gost-s-box.c b/comm/third_party/libgcrypt/cipher/gost-s-box.c
new file mode 100644
index 0000000000..5d5ed7dc44
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/gost-s-box.c
@@ -0,0 +1,266 @@
+/* gost-s-box.c - GOST 28147-89 S-Box expander
+ * Copyright (C) 2013 Dmitry Eremin-Solenikov
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+
+struct gost_sbox
+{
+ const char *name;
+ const char *oid;
+ unsigned int keymeshing;
+ unsigned char sbox[16*8];
+} gost_sboxes[] = {
+ { "test_3411", "1.2.643.2.2.30.0", 0,
+ {
+ 0x4, 0xE, 0x5, 0x7, 0x6, 0x4, 0xD, 0x1,
+ 0xA, 0xB, 0x8, 0xD, 0xC, 0xB, 0xB, 0xF,
+ 0x9, 0x4, 0x1, 0xA, 0x7, 0xA, 0x4, 0xD,
+ 0x2, 0xC, 0xD, 0x1, 0x1, 0x0, 0x1, 0x0,
+
+ 0xD, 0x6, 0xA, 0x0, 0x5, 0x7, 0x3, 0x5,
+ 0x8, 0xD, 0x3, 0x8, 0xF, 0x2, 0xF, 0x7,
+ 0x0, 0xF, 0x4, 0x9, 0xD, 0x1, 0x5, 0xA,
+ 0xE, 0xA, 0x2, 0xF, 0x8, 0xD, 0x9, 0x4,
+
+ 0x6, 0x2, 0xE, 0xE, 0x4, 0x3, 0x0, 0x9,
+ 0xB, 0x3, 0xF, 0x4, 0xA, 0x6, 0xA, 0x2,
+ 0x1, 0x8, 0xC, 0x6, 0x9, 0x8, 0xE, 0x3,
+ 0xC, 0x1, 0x7, 0xC, 0xE, 0x5, 0x7, 0xE,
+
+ 0x7, 0x0, 0x6, 0xB, 0x0, 0x9, 0x6, 0x6,
+ 0xF, 0x7, 0x0, 0x2, 0x3, 0xC, 0x8, 0xB,
+ 0x5, 0x5, 0x9, 0x5, 0xB, 0xF, 0x2, 0x8,
+ 0x3, 0x9, 0xB, 0x3, 0x2, 0xE, 0xC, 0xC,
+ }
+ },
+ { "CryptoPro_3411", "1.2.643.2.2.30.1", 0,
+ {
+ 0xA, 0x5, 0x7, 0x4, 0x7, 0x7, 0xD, 0x1,
+ 0x4, 0xF, 0xF, 0xA, 0x6, 0x6, 0xE, 0x3,
+ 0x5, 0x4, 0xC, 0x7, 0x4, 0x2, 0x4, 0xA,
+ 0x6, 0x0, 0xE, 0xC, 0xB, 0x4, 0x1, 0x9,
+
+ 0x8, 0x2, 0x9, 0x0, 0x9, 0xD, 0x7, 0x5,
+ 0x1, 0xD, 0x4, 0xF, 0xC, 0x9, 0x0, 0xB,
+ 0x3, 0xB, 0x1, 0x2, 0x2, 0xF, 0x5, 0x4,
+ 0x7, 0x9, 0x0, 0x8, 0xA, 0x0, 0xA, 0xF,
+
+ 0xD, 0x1, 0x3, 0xE, 0x1, 0xA, 0x3, 0x8,
+ 0xC, 0x7, 0xB, 0x1, 0x8, 0x1, 0xC, 0x6,
+ 0xE, 0x6, 0x5, 0x6, 0x0, 0x5, 0x8, 0x7,
+ 0x0, 0x3, 0x2, 0x5, 0xE, 0xB, 0xF, 0xE,
+
+ 0x9, 0xC, 0x6, 0xD, 0xF, 0x8, 0x6, 0xD,
+ 0x2, 0xE, 0xA, 0xB, 0xD, 0xE, 0x2, 0x0,
+ 0xB, 0xA, 0x8, 0x9, 0x3, 0xC, 0x9, 0x2,
+ 0xF, 0x8, 0xD, 0x3, 0x5, 0x3, 0xB, 0xC,
+ }
+ },
+ { "Test_89", "1.2.643.2.2.31.0", 0,
+ {
+ 0x4, 0xC, 0xD, 0xE, 0x3, 0x8, 0x9, 0xC,
+ 0x2, 0x9, 0x8, 0x9, 0xE, 0xF, 0xB, 0x6,
+ 0xF, 0xF, 0xE, 0xB, 0x5, 0x6, 0xC, 0x5,
+ 0x5, 0xE, 0xC, 0x2, 0x9, 0xB, 0x0, 0x2,
+
+ 0x9, 0x8, 0x7, 0x5, 0x6, 0x1, 0x3, 0xB,
+ 0x1, 0x1, 0x3, 0xF, 0x8, 0x9, 0x6, 0x0,
+ 0x0, 0x3, 0x9, 0x7, 0x0, 0xC, 0x7, 0x9,
+ 0x8, 0xA, 0xA, 0x1, 0xD, 0x5, 0x5, 0xD,
+
+ 0xE, 0x2, 0x1, 0x0, 0xA, 0xD, 0x4, 0x3,
+ 0x3, 0x7, 0x5, 0xD, 0xB, 0x3, 0x8, 0xE,
+ 0xB, 0x4, 0x2, 0xC, 0x7, 0x7, 0xE, 0x7,
+ 0xC, 0xD, 0x4, 0x6, 0xC, 0xA, 0xF, 0xA,
+
+ 0xD, 0x6, 0x6, 0xA, 0x2, 0x0, 0x1, 0xF,
+ 0x7, 0x0, 0xF, 0x4, 0x1, 0xE, 0xA, 0x4,
+ 0xA, 0xB, 0x0, 0x3, 0xF, 0x2, 0x2, 0x1,
+ 0x6, 0x5, 0xB, 0x8, 0x4, 0x4, 0xD, 0x8,
+ }
+ },
+ { "CryptoPro_A", "1.2.643.2.2.31.1", 1,
+ {
+ 0x9, 0x3, 0xE, 0xE, 0xB, 0x3, 0x1, 0xB,
+ 0x6, 0x7, 0x4, 0x7, 0x5, 0xA, 0xD, 0xA,
+ 0x3, 0xE, 0x6, 0xA, 0x1, 0xD, 0x2, 0xF,
+ 0x2, 0x9, 0x2, 0xC, 0x9, 0xC, 0x9, 0x5,
+
+ 0x8, 0x8, 0xB, 0xD, 0x8, 0x1, 0x7, 0x0,
+ 0xB, 0xA, 0x3, 0x1, 0xD, 0x2, 0xA, 0xC,
+ 0x1, 0xF, 0xD, 0x3, 0xF, 0x0, 0x6, 0xE,
+ 0x7, 0x0, 0x8, 0x9, 0x0, 0xB, 0x0, 0x8,
+
+ 0xA, 0x5, 0xC, 0x0, 0xE, 0x7, 0x8, 0x6,
+ 0x4, 0x2, 0xF, 0x2, 0x4, 0x5, 0xC, 0x2,
+ 0xE, 0x6, 0x5, 0xB, 0x2, 0x9, 0x4, 0x3,
+ 0xF, 0xC, 0xA, 0x4, 0x3, 0x4, 0x5, 0x9,
+
+ 0xC, 0xB, 0x0, 0xF, 0xC, 0x8, 0xF, 0x1,
+ 0x0, 0x4, 0x7, 0x8, 0x7, 0xF, 0x3, 0x7,
+ 0xD, 0xD, 0x1, 0x5, 0xA, 0xE, 0xB, 0xD,
+ 0x5, 0x1, 0x9, 0x6, 0x6, 0x6, 0xE, 0x4,
+ }
+ },
+ { "CryptoPro_B", "1.2.643.2.2.31.2", 1,
+ {
+ 0x8, 0x0, 0xE, 0x7, 0x2, 0x8, 0x5, 0x0,
+ 0x4, 0x1, 0xC, 0x5, 0x7, 0x3, 0x2, 0x4,
+ 0xB, 0x2, 0x0, 0x0, 0xC, 0x2, 0xA, 0xB,
+ 0x1, 0xA, 0xA, 0xD, 0xF, 0x6, 0xB, 0xE,
+
+ 0x3, 0x4, 0x9, 0xB, 0x9, 0x4, 0x9, 0x8,
+ 0x5, 0xD, 0x2, 0x6, 0x5, 0xD, 0x1, 0x3,
+ 0x0, 0x5, 0xD, 0x1, 0xA, 0xE, 0xC, 0x7,
+ 0x9, 0xC, 0xB, 0x2, 0xB, 0xB, 0x3, 0x1,
+
+ 0x2, 0x9, 0x7, 0x3, 0x1, 0xC, 0x7, 0xA,
+ 0xE, 0x7, 0x5, 0xA, 0x4, 0x1, 0x4, 0x2,
+ 0xA, 0x3, 0x8, 0xC, 0x0, 0x7, 0xD, 0x9,
+ 0xC, 0xF, 0xF, 0xF, 0xD, 0xF, 0x0, 0x6,
+
+ 0xD, 0xB, 0x3, 0x4, 0x6, 0xA, 0x6, 0xF,
+ 0x6, 0x8, 0x6, 0xE, 0x8, 0x0, 0xF, 0xD,
+ 0x7, 0x6, 0x1, 0x9, 0xE, 0x9, 0x8, 0x5,
+ 0xF, 0xE, 0x4, 0x8, 0x3, 0x5, 0xE, 0xC,
+ }
+ },
+ { "CryptoPro_C", "1.2.643.2.2.31.3", 1,
+ {
+ 0x1, 0x0, 0x8, 0x3, 0x8, 0xC, 0xA, 0x7,
+ 0xB, 0x1, 0x2, 0x6, 0xD, 0x9, 0x9, 0x4,
+ 0xC, 0x7, 0x5, 0x0, 0xB, 0xB, 0x6, 0x0,
+ 0x2, 0xD, 0x0, 0x1, 0x0, 0x1, 0x8, 0x5,
+
+ 0x9, 0xB, 0x4, 0x5, 0x4, 0x8, 0xD, 0xA,
+ 0xD, 0x4, 0x9, 0xD, 0x5, 0xE, 0xE, 0x2,
+ 0x0, 0x5, 0xF, 0xA, 0x1, 0x2, 0x2, 0xF,
+ 0xF, 0x2, 0xA, 0x8, 0x2, 0x4, 0x0, 0xE,
+
+ 0x4, 0x8, 0x3, 0xB, 0x9, 0x7, 0xF, 0xC,
+ 0x5, 0xE, 0x7, 0x2, 0x3, 0x3, 0x3, 0x6,
+ 0x8, 0xF, 0xC, 0x9, 0xC, 0x6, 0x5, 0x1,
+ 0xE, 0xC, 0xD, 0x7, 0xE, 0x5, 0xB, 0xB,
+
+ 0xA, 0x9, 0x6, 0xE, 0x6, 0xA, 0x4, 0xD,
+ 0x7, 0xA, 0xE, 0xF, 0xF, 0x0, 0x1, 0x9,
+ 0x6, 0x6, 0x1, 0xC, 0xA, 0xF, 0xC, 0x3,
+ 0x3, 0x3, 0xB, 0x4, 0x7, 0xD, 0x7, 0x8,
+ }
+ },
+ { "CryptoPro_D", "1.2.643.2.2.31.4", 1,
+ {
+ 0xF, 0xB, 0x1, 0x1, 0x0, 0x8, 0x3, 0x1,
+ 0xC, 0x6, 0xC, 0x5, 0xC, 0x0, 0x0, 0xA,
+ 0x2, 0x3, 0xB, 0xE, 0x8, 0xF, 0x6, 0x6,
+ 0xA, 0x4, 0x0, 0xC, 0x9, 0x3, 0xF, 0x8,
+
+ 0x6, 0xC, 0xF, 0xA, 0xD, 0x2, 0x1, 0xF,
+ 0x4, 0xF, 0xE, 0x7, 0x2, 0x5, 0xE, 0xB,
+ 0x5, 0xE, 0x6, 0x0, 0xA, 0xE, 0x9, 0x0,
+ 0x0, 0x2, 0x5, 0xD, 0xB, 0xB, 0x2, 0x4,
+
+ 0x7, 0x7, 0xA, 0x6, 0x7, 0x1, 0xD, 0xC,
+ 0x9, 0xD, 0xD, 0x2, 0x3, 0xA, 0x8, 0x3,
+ 0xE, 0x8, 0x4, 0xB, 0x6, 0x4, 0xC, 0x5,
+ 0xD, 0x0, 0x8, 0x4, 0x5, 0x7, 0x4, 0x9,
+
+ 0x1, 0x5, 0x9, 0x9, 0x4, 0xC, 0xB, 0x7,
+ 0xB, 0xA, 0x3, 0x3, 0xE, 0x9, 0xA, 0xD,
+ 0x8, 0x9, 0x7, 0xF, 0xF, 0xD, 0x5, 0x2,
+ 0x3, 0x1, 0x2, 0x8, 0x1, 0x6, 0x7, 0xE,
+ }
+ },
+ { "TC26_Z", "1.2.643.7.1.2.5.1.1", 1,
+ {
+ 0xc, 0x6, 0xb, 0xc, 0x7, 0x5, 0x8, 0x1,
+ 0x4, 0x8, 0x3, 0x8, 0xf, 0xd, 0xe, 0x7,
+ 0x6, 0x2, 0x5, 0x2, 0x5, 0xf, 0x2, 0xe,
+ 0x2, 0x3, 0x8, 0x1, 0xa, 0x6, 0x5, 0xd,
+
+ 0xa, 0x9, 0x2, 0xd, 0x8, 0x9, 0x6, 0x0,
+ 0x5, 0xa, 0xf, 0x4, 0x1, 0x2, 0x9, 0x5,
+ 0xb, 0x5, 0xa, 0xf, 0x6, 0xc, 0x1, 0x8,
+ 0x9, 0xc, 0xd, 0x6, 0xd, 0xa, 0xc, 0x3,
+
+ 0xe, 0x1, 0xe, 0x7, 0x0, 0xb, 0xf, 0x4,
+ 0x8, 0xe, 0x1, 0x0, 0x9, 0x7, 0x4, 0xf,
+ 0xd, 0x4, 0x7, 0xa, 0x3, 0x8, 0xb, 0xa,
+ 0x7, 0x7, 0x4, 0x5, 0xe, 0x1, 0x0, 0x6,
+
+ 0x0, 0xb, 0xc, 0x3, 0xb, 0x4, 0xd, 0x9,
+ 0x3, 0xd, 0x9, 0xe, 0x4, 0x3, 0xa, 0xc,
+ 0xf, 0x0, 0x6, 0x9, 0x2, 0xe, 0x3, 0xb,
+ 0x1, 0xf, 0x0, 0xb, 0xc, 0x0, 0x7, 0x2,
+ }
+ },
+};
+
+int main(int argc, char **argv)
+{
+ unsigned int i, j, s;
+ FILE *f;
+
+ if (argc == 1)
+ f = stdin;
+ else
+ f = fopen(argv[1], "w");
+
+ if (!f)
+ {
+ perror("fopen");
+ exit(1);
+ }
+
+ for (s = 0; s < DIM(gost_sboxes); s++)
+ {
+ unsigned char *sbox = gost_sboxes[s].sbox;
+ fprintf (f, "static const u32 sbox_%s[4*256] =\n {", gost_sboxes[s].name);
+ for (i = 0; i < 4; i++) {
+ fprintf (f, "\n /* %d */\n ", i);
+ for (j = 0; j < 256; j++) {
+ unsigned int val;
+ if (j % 4 == 0 && j != 0)
+ fprintf (f, "\n ");
+ val = sbox[ (j & 0xf) * 8 + 2 * i + 0] |
+ (sbox[ (j >> 4) * 8 + 2 * i + 1] << 4);
+ val <<= (8*i);
+ val = (val << 11) | (val >> 21);
+ fprintf (f, " 0x%08x,", val);
+ }
+ }
+ fprintf (f, "\n };\n\n");
+ }
+
+ fprintf (f, "static struct\n{\n const char *oid;\n const u32 *sbox;\n const int keymeshing;\n} gost_oid_map[] = {\n");
+
+ for (s = 0; s < DIM(gost_sboxes); s++)
+ {
+ fprintf (f, " { \"%s\", sbox_%s, %d },\n", gost_sboxes[s].oid, gost_sboxes[s].name, gost_sboxes[s].keymeshing );
+ }
+
+ fprintf(f, " { NULL, NULL, 0 }\n};\n");
+
+ fclose (f);
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/cipher/gost.h b/comm/third_party/libgcrypt/cipher/gost.h
new file mode 100644
index 0000000000..53a4050503
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/gost.h
@@ -0,0 +1,34 @@
+/* gost.h - GOST 28147-89 implementation
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GCRY_GOST_H
+#define _GCRY_GOST_H
+
+typedef struct {
+ u32 key[8];
+ const u32 *sbox;
+ unsigned int mesh_counter;
+ unsigned int mesh_limit;
+} GOST28147_context;
+
+/* This is a simple interface that will be used by GOST R 34.11-94 */
+unsigned int _gcry_gost_enc_data (const u32 *key,
+ u32 *o1, u32 *o2, u32 n1, u32 n2, int cryptopro);
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/gost28147.c b/comm/third_party/libgcrypt/cipher/gost28147.c
new file mode 100644
index 0000000000..9445b378c4
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/gost28147.c
@@ -0,0 +1,553 @@
+/* gost28147.c - GOST 28147-89 implementation for Libgcrypt
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* GOST 28147-89 defines several modes of encryption:
+ * - ECB which should be used only for key transfer
+ * - CFB mode
+ * - OFB-like mode with additional transformation on keystream
+ * RFC 5830 names this 'counter encryption' mode
+ * Original GOST text uses the term 'gammirovanie'
+ * - MAC mode ('imitovstavka')
+ *
+ * This implementation handles ECB and CFB modes via usual libgcrypt handling.
+ * OFB-like modes are unsupported.
+ */
+
+#include <config.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "mac-internal.h"
+#include "bufhelp.h"
+#include "cipher-internal.h"
+
+#include "gost.h"
+#include "gost-sb.h"
+
+static void
+gost_do_set_sbox (GOST28147_context *ctx, unsigned int index)
+{
+ ctx->sbox = gost_oid_map[index].sbox;
+ ctx->mesh_limit = gost_oid_map[index].keymeshing ? 1024 : 0;
+}
+
+static gcry_err_code_t
+gost_setkey (void *c, const byte *key, unsigned keylen,
+ cipher_bulk_ops_t *bulk_ops)
+{
+ int i;
+ GOST28147_context *ctx = c;
+
+ (void)bulk_ops;
+
+ if (keylen != 256 / 8)
+ return GPG_ERR_INV_KEYLEN;
+
+ if (!ctx->sbox)
+ gost_do_set_sbox (ctx, 0);
+
+ for (i = 0; i < 8; i++)
+ {
+ ctx->key[i] = buf_get_le32(&key[4*i]);
+ }
+
+ ctx->mesh_counter = 0;
+
+ return GPG_ERR_NO_ERROR;
+}
+
+static inline u32
+gost_val (u32 subkey, u32 cm1, const u32 *sbox)
+{
+ cm1 += subkey;
+ cm1 = sbox[0*256 + ((cm1 >> 0) & 0xff)] |
+ sbox[1*256 + ((cm1 >> 8) & 0xff)] |
+ sbox[2*256 + ((cm1 >> 16) & 0xff)] |
+ sbox[3*256 + ((cm1 >> 24) & 0xff)];
+ return cm1;
+}
+
+static unsigned int
+_gost_encrypt_data (const u32 *sbox, const u32 *key, u32 *o1, u32 *o2, u32 n1, u32 n2)
+{
+ n2 ^= gost_val (key[0], n1, sbox); n1 ^= gost_val (key[1], n2, sbox);
+ n2 ^= gost_val (key[2], n1, sbox); n1 ^= gost_val (key[3], n2, sbox);
+ n2 ^= gost_val (key[4], n1, sbox); n1 ^= gost_val (key[5], n2, sbox);
+ n2 ^= gost_val (key[6], n1, sbox); n1 ^= gost_val (key[7], n2, sbox);
+
+ n2 ^= gost_val (key[0], n1, sbox); n1 ^= gost_val (key[1], n2, sbox);
+ n2 ^= gost_val (key[2], n1, sbox); n1 ^= gost_val (key[3], n2, sbox);
+ n2 ^= gost_val (key[4], n1, sbox); n1 ^= gost_val (key[5], n2, sbox);
+ n2 ^= gost_val (key[6], n1, sbox); n1 ^= gost_val (key[7], n2, sbox);
+
+ n2 ^= gost_val (key[0], n1, sbox); n1 ^= gost_val (key[1], n2, sbox);
+ n2 ^= gost_val (key[2], n1, sbox); n1 ^= gost_val (key[3], n2, sbox);
+ n2 ^= gost_val (key[4], n1, sbox); n1 ^= gost_val (key[5], n2, sbox);
+ n2 ^= gost_val (key[6], n1, sbox); n1 ^= gost_val (key[7], n2, sbox);
+
+ n2 ^= gost_val (key[7], n1, sbox); n1 ^= gost_val (key[6], n2, sbox);
+ n2 ^= gost_val (key[5], n1, sbox); n1 ^= gost_val (key[4], n2, sbox);
+ n2 ^= gost_val (key[3], n1, sbox); n1 ^= gost_val (key[2], n2, sbox);
+ n2 ^= gost_val (key[1], n1, sbox); n1 ^= gost_val (key[0], n2, sbox);
+
+ *o1 = n2;
+ *o2 = n1;
+
+ return /* burn_stack */ 4*sizeof(void*) /* func call */ +
+ 3*sizeof(void*) /* stack */ +
+ 4*sizeof(void*) /* gost_val call */;
+}
+
+static unsigned int
+gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf)
+{
+ GOST28147_context *ctx = c;
+ u32 n1, n2;
+ unsigned int burn;
+
+ n1 = buf_get_le32 (inbuf);
+ n2 = buf_get_le32 (inbuf+4);
+
+ burn = _gost_encrypt_data(ctx->sbox, ctx->key, &n1, &n2, n1, n2);
+
+ buf_put_le32 (outbuf+0, n1);
+ buf_put_le32 (outbuf+4, n2);
+
+ return /* burn_stack */ burn + 6*sizeof(void*) /* func call */;
+}
+
+unsigned int _gcry_gost_enc_data (const u32 *key,
+ u32 *o1, u32 *o2, u32 n1, u32 n2, int cryptopro)
+{
+ const u32 *sbox;
+ if (cryptopro)
+ sbox = sbox_CryptoPro_3411;
+ else
+ sbox = sbox_test_3411;
+ return _gost_encrypt_data (sbox, key, o1, o2, n1, n2) + 7 * sizeof(void *);
+}
+
+static unsigned int
+gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf)
+{
+ GOST28147_context *ctx = c;
+ u32 n1, n2;
+ const u32 *sbox = ctx->sbox;
+
+ n1 = buf_get_le32 (inbuf);
+ n2 = buf_get_le32 (inbuf+4);
+
+ n2 ^= gost_val (ctx->key[0], n1, sbox); n1 ^= gost_val (ctx->key[1], n2, sbox);
+ n2 ^= gost_val (ctx->key[2], n1, sbox); n1 ^= gost_val (ctx->key[3], n2, sbox);
+ n2 ^= gost_val (ctx->key[4], n1, sbox); n1 ^= gost_val (ctx->key[5], n2, sbox);
+ n2 ^= gost_val (ctx->key[6], n1, sbox); n1 ^= gost_val (ctx->key[7], n2, sbox);
+
+ n2 ^= gost_val (ctx->key[7], n1, sbox); n1 ^= gost_val (ctx->key[6], n2, sbox);
+ n2 ^= gost_val (ctx->key[5], n1, sbox); n1 ^= gost_val (ctx->key[4], n2, sbox);
+ n2 ^= gost_val (ctx->key[3], n1, sbox); n1 ^= gost_val (ctx->key[2], n2, sbox);
+ n2 ^= gost_val (ctx->key[1], n1, sbox); n1 ^= gost_val (ctx->key[0], n2, sbox);
+
+ n2 ^= gost_val (ctx->key[7], n1, sbox); n1 ^= gost_val (ctx->key[6], n2, sbox);
+ n2 ^= gost_val (ctx->key[5], n1, sbox); n1 ^= gost_val (ctx->key[4], n2, sbox);
+ n2 ^= gost_val (ctx->key[3], n1, sbox); n1 ^= gost_val (ctx->key[2], n2, sbox);
+ n2 ^= gost_val (ctx->key[1], n1, sbox); n1 ^= gost_val (ctx->key[0], n2, sbox);
+
+ n2 ^= gost_val (ctx->key[7], n1, sbox); n1 ^= gost_val (ctx->key[6], n2, sbox);
+ n2 ^= gost_val (ctx->key[5], n1, sbox); n1 ^= gost_val (ctx->key[4], n2, sbox);
+ n2 ^= gost_val (ctx->key[3], n1, sbox); n1 ^= gost_val (ctx->key[2], n2, sbox);
+ n2 ^= gost_val (ctx->key[1], n1, sbox); n1 ^= gost_val (ctx->key[0], n2, sbox);
+
+ buf_put_le32 (outbuf+0, n2);
+ buf_put_le32 (outbuf+4, n1);
+
+ return /* burn_stack */ 4*sizeof(void*) /* func call */ +
+ 3*sizeof(void*) /* stack */ +
+ 4*sizeof(void*) /* gost_val call */;
+}
+
+static gpg_err_code_t
+gost_set_sbox (GOST28147_context *ctx, const char *oid)
+{
+ int i;
+
+ for (i = 0; gost_oid_map[i].oid; i++)
+ {
+ if (!strcmp(gost_oid_map[i].oid, oid))
+ {
+ gost_do_set_sbox (ctx, i);
+ return 0;
+ }
+ }
+ return GPG_ERR_VALUE_NOT_FOUND;
+}
+
+static gpg_err_code_t
+gost_set_extra_info (void *c, int what, const void *buffer, size_t buflen)
+{
+ GOST28147_context *ctx = c;
+ gpg_err_code_t ec = 0;
+
+ (void)buffer;
+ (void)buflen;
+
+ switch (what)
+ {
+ case GCRYCTL_SET_SBOX:
+ ec = gost_set_sbox (ctx, buffer);
+ break;
+
+ default:
+ ec = GPG_ERR_INV_OP;
+ break;
+ }
+ return ec;
+}
+
+static const byte CryptoProKeyMeshingKey[] = {
+ 0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23,
+ 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
+ 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
+ 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
+};
+
+/* Implements key meshing algorithm by modifing ctx and returning new IV.
+ Thanks to Dmitry Belyavskiy. */
+static void
+cryptopro_key_meshing (GOST28147_context *ctx)
+{
+ unsigned char newkey[32];
+ unsigned int i;
+
+ /* "Decrypt" the static keymeshing key */
+ for (i = 0; i < 4; i++)
+ {
+ gost_decrypt_block (ctx, newkey + i*8, CryptoProKeyMeshingKey + i*8);
+ }
+
+ /* Set new key */
+ for (i = 0; i < 8; i++)
+ {
+ ctx->key[i] = buf_get_le32(&newkey[4*i]);
+ }
+
+ ctx->mesh_counter = 0;
+}
+
+static unsigned int
+gost_encrypt_block_mesh (void *c, byte *outbuf, const byte *inbuf)
+{
+ GOST28147_context *ctx = c;
+ u32 n1, n2;
+ unsigned int burn;
+
+ n1 = buf_get_le32 (inbuf);
+ n2 = buf_get_le32 (inbuf+4);
+
+ if (ctx->mesh_limit && (ctx->mesh_counter == ctx->mesh_limit))
+ {
+ cryptopro_key_meshing (ctx);
+ /* Yes, encrypt twice: once for KeyMeshing procedure per RFC 4357,
+ * once for block encryption */
+ _gost_encrypt_data(ctx->sbox, ctx->key, &n1, &n2, n1, n2);
+ }
+
+ burn = _gost_encrypt_data(ctx->sbox, ctx->key, &n1, &n2, n1, n2);
+
+ ctx->mesh_counter += 8;
+
+ buf_put_le32 (outbuf+0, n1);
+ buf_put_le32 (outbuf+4, n2);
+
+ return /* burn_stack */ burn + 6*sizeof(void*) /* func call */;
+}
+
+static gcry_cipher_oid_spec_t oids_gost28147_mesh[] =
+ {
+ { "1.2.643.2.2.21", GCRY_CIPHER_MODE_CFB },
+ /* { "1.2.643.2.2.31.0", GCRY_CIPHER_MODE_CNTGOST }, */
+ { "1.2.643.2.2.31.1", GCRY_CIPHER_MODE_CFB },
+ { "1.2.643.2.2.31.2", GCRY_CIPHER_MODE_CFB },
+ { "1.2.643.2.2.31.3", GCRY_CIPHER_MODE_CFB },
+ { "1.2.643.2.2.31.4", GCRY_CIPHER_MODE_CFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_gost28147 =
+ {
+ GCRY_CIPHER_GOST28147, {0, 0},
+ "GOST28147", NULL, NULL, 8, 256,
+ sizeof (GOST28147_context),
+ gost_setkey,
+ gost_encrypt_block,
+ gost_decrypt_block,
+ NULL, NULL, NULL, gost_set_extra_info,
+ };
+
+/* Meshing is used only for CFB, so no need to have separate
+ * gost_decrypt_block_mesh.
+ * Moreover key meshing is specified as encrypting the block (IV). Decrypting
+ * it afterwards would be meaningless. */
+gcry_cipher_spec_t _gcry_cipher_spec_gost28147_mesh =
+ {
+ GCRY_CIPHER_GOST28147_MESH, {0, 0},
+ "GOST28147_MESH", NULL, oids_gost28147_mesh, 8, 256,
+ sizeof (GOST28147_context),
+ gost_setkey,
+ gost_encrypt_block_mesh,
+ gost_decrypt_block,
+ NULL, NULL, NULL, gost_set_extra_info,
+ };
+
+static gcry_err_code_t
+gost_imit_open (gcry_mac_hd_t h)
+{
+ memset(&h->u.imit, 0, sizeof(h->u.imit));
+ return 0;
+}
+
+static void
+gost_imit_close (gcry_mac_hd_t h)
+{
+ (void) h;
+}
+
+static gcry_err_code_t
+gost_imit_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+ int i;
+
+ if (keylen != 256 / 8)
+ return GPG_ERR_INV_KEYLEN;
+
+ if (!h->u.imit.ctx.sbox)
+ h->u.imit.ctx.sbox = sbox_CryptoPro_A;
+
+ for (i = 0; i < 8; i++)
+ {
+ h->u.imit.ctx.key[i] = buf_get_le32(&key[4*i]);
+ }
+
+ return 0;
+}
+
+static gcry_err_code_t
+gost_imit_setiv (gcry_mac_hd_t h,
+ const unsigned char *iv,
+ size_t ivlen)
+{
+ if (ivlen != 8)
+ return GPG_ERR_INV_LENGTH;
+
+ h->u.imit.n1 = buf_get_le32 (iv + 0);
+ h->u.imit.n2 = buf_get_le32 (iv + 4);
+
+ return 0;
+}
+
+static gcry_err_code_t
+gost_imit_reset (gcry_mac_hd_t h)
+{
+ h->u.imit.n1 = h->u.imit.n2 = 0;
+ h->u.imit.unused = 0;
+ return 0;
+}
+
+static unsigned int
+_gost_imit_block (const u32 *sbox, const u32 *key, u32 *o1, u32 *o2, u32 n1, u32 n2)
+{
+ n1 ^= *o1;
+ n2 ^= *o2;
+
+ n2 ^= gost_val (key[0], n1, sbox); n1 ^= gost_val (key[1], n2, sbox);
+ n2 ^= gost_val (key[2], n1, sbox); n1 ^= gost_val (key[3], n2, sbox);
+ n2 ^= gost_val (key[4], n1, sbox); n1 ^= gost_val (key[5], n2, sbox);
+ n2 ^= gost_val (key[6], n1, sbox); n1 ^= gost_val (key[7], n2, sbox);
+
+ n2 ^= gost_val (key[0], n1, sbox); n1 ^= gost_val (key[1], n2, sbox);
+ n2 ^= gost_val (key[2], n1, sbox); n1 ^= gost_val (key[3], n2, sbox);
+ n2 ^= gost_val (key[4], n1, sbox); n1 ^= gost_val (key[5], n2, sbox);
+ n2 ^= gost_val (key[6], n1, sbox); n1 ^= gost_val (key[7], n2, sbox);
+
+ *o1 = n1;
+ *o2 = n2;
+
+ return /* burn_stack */ 4*sizeof(void*) /* func call */ +
+ 3*sizeof(void*) /* stack */ +
+ 4*sizeof(void*) /* gost_val call */;
+}
+
+static inline unsigned int
+gost_imit_block (GOST28147_context *ctx, u32 *n1, u32 *n2, const unsigned char *buf)
+{
+ if (ctx->mesh_limit && (ctx->mesh_counter == ctx->mesh_limit))
+ cryptopro_key_meshing (ctx);
+
+ return _gost_imit_block (ctx->sbox, ctx->key,
+ n1, n2,
+ buf_get_le32 (buf+0),
+ buf_get_le32 (buf+4));
+}
+
+static gcry_err_code_t
+gost_imit_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ const int blocksize = 8;
+ unsigned int burn = 0;
+ if (!buflen || !buf)
+ return GPG_ERR_NO_ERROR;
+
+ if (h->u.imit.unused)
+ {
+ for (; buflen && h->u.imit.unused < blocksize; buflen --)
+ h->u.imit.lastiv[h->u.imit.unused++] = *buf++;
+
+ if (h->u.imit.unused < blocksize)
+ return GPG_ERR_NO_ERROR;
+
+ h->u.imit.count ++;
+ burn = gost_imit_block (&h->u.imit.ctx,
+ &h->u.imit.n1, &h->u.imit.n2,
+ h->u.imit.lastiv);
+
+ h->u.imit.unused = 0;
+ }
+
+ while (buflen >= blocksize)
+ {
+ h->u.imit.count ++;
+ burn = gost_imit_block (&h->u.imit.ctx,
+ &h->u.imit.n1, &h->u.imit.n2,
+ buf);
+ buf += blocksize;
+ buflen -= blocksize;
+ }
+
+ for (; buflen; buflen--)
+ h->u.imit.lastiv[h->u.imit.unused++] = *buf++;
+
+ _gcry_burn_stack (burn);
+
+ return GPG_ERR_NO_ERROR;
+}
+
+static void
+gost_imit_finish (gcry_mac_hd_t h)
+{
+ static const unsigned char zero[8] = {0};
+
+ /* Fill till full block */
+ if (h->u.imit.unused)
+ gost_imit_write(h, zero, 8 - h->u.imit.unused);
+
+ if (h->u.imit.count == 1)
+ gost_imit_write(h, zero, 8);
+}
+
+static gcry_err_code_t
+gost_imit_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
+{
+ unsigned int dlen = 8;
+ unsigned char digest[8];
+
+ gost_imit_finish (h);
+
+ buf_put_le32 (digest+0, h->u.imit.n1);
+ buf_put_le32 (digest+4, h->u.imit.n2);
+
+ if (*outlen <= dlen)
+ buf_cpy (outbuf, digest, *outlen);
+ else
+ {
+ buf_cpy (outbuf, digest, dlen);
+ *outlen = dlen;
+ }
+ return 0;
+}
+
+static gcry_err_code_t
+gost_imit_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ unsigned char tbuf[8];
+
+ gost_imit_finish (h);
+
+ buf_put_le32 (tbuf+0, h->u.imit.n1);
+ buf_put_le32 (tbuf+4, h->u.imit.n2);
+
+ return buf_eq_const(tbuf, buf, buflen) ?
+ GPG_ERR_NO_ERROR : GPG_ERR_CHECKSUM;
+}
+
+static unsigned int
+gost_imit_get_maclen (int algo)
+{
+ (void) algo;
+ return 4; /* or 8 */
+}
+
+
+static unsigned int
+gost_imit_get_keylen (int algo)
+{
+ (void) algo;
+ return 256 / 8;
+}
+
+static gpg_err_code_t
+gost_imit_set_extra_info (gcry_mac_hd_t hd, int what, const void *buffer, size_t buflen)
+{
+ gpg_err_code_t ec = 0;
+
+ (void)buffer;
+ (void)buflen;
+
+ switch (what)
+ {
+ case GCRYCTL_SET_SBOX:
+ ec = gost_set_sbox (&hd->u.imit.ctx, buffer);
+ break;
+
+ default:
+ ec = GPG_ERR_INV_OP;
+ break;
+ }
+ return ec;
+}
+
+
+static gcry_mac_spec_ops_t gost_imit_ops = {
+ gost_imit_open,
+ gost_imit_close,
+ gost_imit_setkey,
+ gost_imit_setiv,
+ gost_imit_reset,
+ gost_imit_write,
+ gost_imit_read,
+ gost_imit_verify,
+ gost_imit_get_maclen,
+ gost_imit_get_keylen,
+ gost_imit_set_extra_info,
+ NULL
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_gost28147_imit =
+ {
+ GCRY_MAC_GOST28147_IMIT, {0, 0}, "GOST28147_IMIT",
+ &gost_imit_ops
+ };
diff --git a/comm/third_party/libgcrypt/cipher/gostr3411-94.c b/comm/third_party/libgcrypt/cipher/gostr3411-94.c
new file mode 100644
index 0000000000..7cf0637e26
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/gostr3411-94.c
@@ -0,0 +1,383 @@
+/* gostr3411-94.c - GOST R 34.11-94 hash function
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+#include "gost.h"
+
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+
+typedef struct {
+ gcry_md_block_ctx_t bctx;
+ union {
+ u32 h[8];
+ byte result[32];
+ };
+ u32 sigma[8];
+ u32 len;
+ int cryptopro;
+} GOSTR3411_CONTEXT;
+
+static unsigned int
+transform (void *c, const unsigned char *data, size_t nblks);
+
+static void
+gost3411_init (void *context, unsigned int flags)
+{
+ GOSTR3411_CONTEXT *hd = context;
+
+ (void)flags;
+
+ memset (hd->h, 0, 32);
+ memset (hd->sigma, 0, 32);
+
+ hd->bctx.nblocks = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize_shift = _gcry_ctz(32);
+ hd->bctx.bwrite = transform;
+ hd->cryptopro = 0;
+}
+
+static void
+gost3411_cp_init (void *context, unsigned int flags)
+{
+ GOSTR3411_CONTEXT *hd = context;
+ gost3411_init (context, flags);
+ hd->cryptopro = 1;
+}
+
+static void
+do_p (u32 *p, u32 *u, u32 *v)
+{
+ int k;
+ u32 t[8];
+
+ for (k = 0; k < 8; k++)
+ t[k] = u[k] ^ v[k];
+
+ k = 0;
+ p[k+0] = ((t[0] >> (8*k)) & 0xff) << 0 |
+ ((t[2] >> (8*k)) & 0xff) << 8 |
+ ((t[4] >> (8*k)) & 0xff) << 16 |
+ ((t[6] >> (8*k)) & 0xff) << 24;
+ p[k+4] = ((t[1] >> (8*k)) & 0xff) << 0 |
+ ((t[3] >> (8*k)) & 0xff) << 8 |
+ ((t[5] >> (8*k)) & 0xff) << 16 |
+ ((t[7] >> (8*k)) & 0xff) << 24;
+
+ k = 1;
+ p[k+0] = ((t[0] >> (8*k)) & 0xff) << 0 |
+ ((t[2] >> (8*k)) & 0xff) << 8 |
+ ((t[4] >> (8*k)) & 0xff) << 16 |
+ ((t[6] >> (8*k)) & 0xff) << 24;
+ p[k+4] = ((t[1] >> (8*k)) & 0xff) << 0 |
+ ((t[3] >> (8*k)) & 0xff) << 8 |
+ ((t[5] >> (8*k)) & 0xff) << 16 |
+ ((t[7] >> (8*k)) & 0xff) << 24;
+
+ k = 2;
+ p[k+0] = ((t[0] >> (8*k)) & 0xff) << 0 |
+ ((t[2] >> (8*k)) & 0xff) << 8 |
+ ((t[4] >> (8*k)) & 0xff) << 16 |
+ ((t[6] >> (8*k)) & 0xff) << 24;
+ p[k+4] = ((t[1] >> (8*k)) & 0xff) << 0 |
+ ((t[3] >> (8*k)) & 0xff) << 8 |
+ ((t[5] >> (8*k)) & 0xff) << 16 |
+ ((t[7] >> (8*k)) & 0xff) << 24;
+
+ k = 3;
+ p[k+0] = ((t[0] >> (8*k)) & 0xff) << 0 |
+ ((t[2] >> (8*k)) & 0xff) << 8 |
+ ((t[4] >> (8*k)) & 0xff) << 16 |
+ ((t[6] >> (8*k)) & 0xff) << 24;
+ p[k+4] = ((t[1] >> (8*k)) & 0xff) << 0 |
+ ((t[3] >> (8*k)) & 0xff) << 8 |
+ ((t[5] >> (8*k)) & 0xff) << 16 |
+ ((t[7] >> (8*k)) & 0xff) << 24;
+}
+
+static void
+do_a (u32 *u)
+{
+ u32 t[2];
+ int i;
+ memcpy(t, u, 2*4);
+ for (i = 0; i < 6; i++)
+ u[i] = u[i+2];
+ u[6] = u[0] ^ t[0];
+ u[7] = u[1] ^ t[1];
+}
+/* apply do_a twice: 1 2 3 4 -> 3 4 1^2 2^3 */
+static void
+do_a2 (u32 *u)
+{
+ u32 t[4];
+ int i;
+ memcpy (t, u, 16);
+ memcpy (u, u + 4, 16);
+ for (i = 0; i < 2; i++)
+ {
+ u[4+i] = t[i] ^ t[i + 2];
+ u[6+i] = u[i] ^ t[i + 2];
+ }
+}
+
+static void
+do_apply_c2 (u32 *u)
+{
+ u[ 0] ^= 0xff00ff00;
+ u[ 1] ^= 0xff00ff00;
+ u[ 2] ^= 0x00ff00ff;
+ u[ 3] ^= 0x00ff00ff;
+ u[ 4] ^= 0x00ffff00;
+ u[ 5] ^= 0xff0000ff;
+ u[ 6] ^= 0x000000ff;
+ u[ 7] ^= 0xff00ffff;
+}
+
+#define do_chi_step12(e) \
+ e[6] ^= ((e[6] >> 16) ^ e[7] ^ (e[7] >> 16) ^ e[4] ^ (e[5] >>16)) & 0xffff;
+
+#define do_chi_step13(e) \
+ e[6] ^= ((e[7] ^ (e[7] >> 16) ^ e[0] ^ (e[4] >> 16) ^ e[6]) & 0xffff) << 16;
+
+#define do_chi_doublestep(e, i) \
+ e[i] ^= (e[i] >> 16) ^ (e[(i+1)%8] << 16) ^ e[(i+1)%8] ^ (e[(i+1)%8] >> 16) ^ (e[(i+2)%8] << 16) ^ e[(i+6)%8] ^ (e[(i+7)%8] >> 16); \
+ e[i] ^= (e[i] << 16);
+
+static void
+do_chi_submix12 (u32 *e, u32 *x)
+{
+ e[6] ^= x[0];
+ e[7] ^= x[1];
+ e[0] ^= x[2];
+ e[1] ^= x[3];
+ e[2] ^= x[4];
+ e[3] ^= x[5];
+ e[4] ^= x[6];
+ e[5] ^= x[7];
+}
+
+static void
+do_chi_submix13 (u32 *e, u32 *x)
+{
+ e[6] ^= (x[0] << 16) | (x[7] >> 16);
+ e[7] ^= (x[1] << 16) | (x[0] >> 16);
+ e[0] ^= (x[2] << 16) | (x[1] >> 16);
+ e[1] ^= (x[3] << 16) | (x[2] >> 16);
+ e[2] ^= (x[4] << 16) | (x[3] >> 16);
+ e[3] ^= (x[5] << 16) | (x[4] >> 16);
+ e[4] ^= (x[6] << 16) | (x[5] >> 16);
+ e[5] ^= (x[7] << 16) | (x[6] >> 16);
+}
+
+static void
+do_add (u32 *s, u32 *a)
+{
+ u32 carry = 0;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ u32 op = carry + a[i];
+ s[i] += op;
+ carry = (a[i] > op) || (op > s[i]);
+ }
+}
+
+static unsigned int
+do_hash_step (GOSTR3411_CONTEXT *hd, u32 *h, u32 *m)
+{
+ u32 u[8], v[8];
+ u32 s[8];
+ u32 k[8];
+ unsigned int burn;
+ int i;
+
+ memcpy (u, h, 32);
+ memcpy (v, m, 32);
+
+ for (i = 0; i < 4; i++) {
+ do_p (k, u, v);
+
+ burn = _gcry_gost_enc_data (k, &s[2*i], &s[2*i+1], h[2*i], h[2*i+1], hd->cryptopro);
+
+ do_a (u);
+ if (i == 1)
+ do_apply_c2 (u);
+ do_a2 (v);
+ }
+
+ for (i = 0; i < 5; i++)
+ {
+ do_chi_doublestep (s, 0);
+ do_chi_doublestep (s, 1);
+ do_chi_doublestep (s, 2);
+ do_chi_doublestep (s, 3);
+ do_chi_doublestep (s, 4);
+ /* That is in total 12 + 1 + 61 = 74 = 16 * 4 + 10 rounds */
+ if (i == 4)
+ break;
+ do_chi_doublestep (s, 5);
+ if (i == 0)
+ do_chi_submix12(s, m);
+ do_chi_step12 (s);
+ if (i == 0)
+ do_chi_submix13(s, h);
+ do_chi_step13 (s);
+ do_chi_doublestep (s, 7);
+ }
+
+ memcpy (h, s+5, 12);
+ memcpy (h+3, s, 20);
+
+ return /* burn_stack */ 4 * sizeof(void*) /* func call (ret addr + args) */ +
+ 4 * 32 + 2 * sizeof(int) /* stack */ +
+ max(burn /* _gcry_gost_enc_one */,
+ sizeof(void*) * 2 /* do_a2 call */ +
+ 16 + sizeof(int) /* do_a2 stack */ );
+}
+
+static unsigned int
+transform_blk (void *ctx, const unsigned char *data)
+{
+ GOSTR3411_CONTEXT *hd = ctx;
+ u32 m[8];
+ unsigned int burn;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ m[i] = buf_get_le32(data + i*4);
+ burn = do_hash_step (hd, hd->h, m);
+ do_add (hd->sigma, m);
+
+ return /* burn_stack */ burn + 3 * sizeof(void*) + 32 + 2 * sizeof(void*);
+}
+
+
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+ unsigned int burn;
+
+ do
+ {
+ burn = transform_blk (c, data);
+ data += 32;
+ }
+ while (--nblks);
+
+ return burn;
+}
+
+
+/*
+ The routine finally terminates the computation and returns the
+ digest. The handle is prepared for a new cycle, but adding bytes
+ to the handle will the destroy the returned buffer. Returns: 32
+ bytes with the message the digest. */
+static void
+gost3411_final (void *context)
+{
+ GOSTR3411_CONTEXT *hd = context;
+ size_t padlen = 0;
+ u32 l[8];
+ int i;
+ MD_NBLOCKS_TYPE nblocks;
+
+ if (hd->bctx.count > 0)
+ {
+ padlen = 32 - hd->bctx.count;
+ memset (hd->bctx.buf + hd->bctx.count, 0, padlen);
+ hd->bctx.count += padlen;
+ _gcry_md_block_write (hd, NULL, 0); /* flush */;
+ }
+
+ if (hd->bctx.count != 0)
+ return; /* Something went wrong */
+
+ memset (l, 0, 32);
+
+ nblocks = hd->bctx.nblocks;
+ if (padlen)
+ {
+ nblocks --;
+ l[0] = 256 - padlen * 8;
+ }
+ l[0] |= nblocks << 8;
+ nblocks >>= 24;
+
+ for (i = 1; i < 8 && nblocks != 0; i++)
+ {
+ l[i] = nblocks;
+ nblocks >>= 24;
+ }
+
+ do_hash_step (hd, hd->h, l);
+ do_hash_step (hd, hd->h, hd->sigma);
+ for (i = 0; i < 8; i++)
+ hd->h[i] = le_bswap32(hd->h[i]);
+}
+
+static byte *
+gost3411_read (void *context)
+{
+ GOSTR3411_CONTEXT *hd = context;
+
+ return hd->result;
+}
+
+static unsigned char asn[6] = /* Object ID is 1.2.643.2.2.3 */
+ { 0x2a, 0x85, 0x03, 0x02, 0x02, 0x03 };
+
+static gcry_md_oid_spec_t oid_spec_gostr3411[] =
+ {
+ /* iso.member-body.ru.rans.cryptopro.3 (gostR3411-94-with-gostR3410-2001) */
+ { "1.2.643.2.2.3" },
+ /* iso.member-body.ru.rans.cryptopro.9 (gostR3411-94) */
+ { "1.2.643.2.2.9" },
+ {NULL},
+ };
+
+gcry_md_spec_t _gcry_digest_spec_gost3411_94 =
+ {
+ GCRY_MD_GOSTR3411_94, {0, 0},
+ "GOSTR3411_94", NULL, 0, NULL, 32,
+ gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read, NULL,
+ NULL, NULL,
+ sizeof (GOSTR3411_CONTEXT)
+ };
+gcry_md_spec_t _gcry_digest_spec_gost3411_cp =
+ {
+ GCRY_MD_GOSTR3411_CP, {0, 0},
+ "GOSTR3411_CP", asn, DIM (asn), oid_spec_gostr3411, 32,
+ gost3411_cp_init, _gcry_md_block_write, gost3411_final, gost3411_read, NULL,
+ NULL, NULL,
+ sizeof (GOSTR3411_CONTEXT)
+ };
diff --git a/comm/third_party/libgcrypt/cipher/hash-common.c b/comm/third_party/libgcrypt/cipher/hash-common.c
new file mode 100644
index 0000000000..ed2d7cacd1
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/hash-common.c
@@ -0,0 +1,193 @@
+/* hash-common.c - Common code for hash algorithms
+ * Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "g10lib.h"
+#include "bufhelp.h"
+#include "hash-common.h"
+
+
+/* Run a selftest for hash algorithm ALGO. If the resulting digest
+ matches EXPECT/EXPECTLEN and everything else is fine as well,
+ return NULL. If an error occurs, return a static text string
+ describing the error.
+
+ DATAMODE controls what will be hashed according to this table:
+
+ 0 - Hash the supplied DATA of DATALEN.
+ 1 - Hash one million times a 'a'. DATA and DATALEN are ignored.
+
+*/
+const char *
+_gcry_hash_selftest_check_one (int algo,
+ int datamode, const void *data, size_t datalen,
+ const void *expect, size_t expectlen)
+{
+ const char *result = NULL;
+ gcry_error_t err = 0;
+ gcry_md_hd_t hd;
+ unsigned char *digest;
+ char aaa[1000];
+ int xof = 0;
+
+ if (_gcry_md_get_algo_dlen (algo) == 0)
+ xof = 1;
+ else if (_gcry_md_get_algo_dlen (algo) != expectlen)
+ return "digest size does not match expected size";
+
+ err = _gcry_md_open (&hd, algo, 0);
+ if (err)
+ return "gcry_md_open failed";
+
+ switch (datamode)
+ {
+ case 0:
+ _gcry_md_write (hd, data, datalen);
+ break;
+
+ case 1: /* Hash one million times an "a". */
+ {
+ int i;
+
+ /* Write in odd size chunks so that we test the buffering. */
+ memset (aaa, 'a', 1000);
+ for (i = 0; i < 1000; i++)
+ _gcry_md_write (hd, aaa, 1000);
+ }
+ break;
+
+ default:
+ result = "invalid DATAMODE";
+ }
+
+ if (!result)
+ {
+ if (!xof)
+ {
+ digest = _gcry_md_read (hd, algo);
+
+ if ( memcmp (digest, expect, expectlen) )
+ result = "digest mismatch";
+ }
+ else
+ {
+ gcry_assert(expectlen <= sizeof(aaa));
+
+ err = _gcry_md_extract (hd, algo, aaa, expectlen);
+ if (err)
+ result = "error extracting output from XOF";
+ else if ( memcmp (aaa, expect, expectlen) )
+ result = "digest mismatch";
+ }
+ }
+
+ _gcry_md_close (hd);
+
+ return result;
+}
+
+
+/* Common function to write a chunk of data to the transform function
+ of a hash algorithm. Note that the use of the term "block" does
+ not imply a fixed size block. Note that we explicitly allow to use
+ this function after the context has been finalized; the result does
+ not have any meaning but writing after finalize is sometimes
+ helpful to mitigate timing attacks. */
+void
+_gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ gcry_md_block_ctx_t *hd = context;
+ unsigned int stack_burn = 0;
+ unsigned int nburn;
+ const unsigned int blocksize_shift = hd->blocksize_shift;
+ const unsigned int blocksize = 1 << blocksize_shift;
+ size_t inblocks;
+ size_t copylen;
+
+ if (sizeof(hd->buf) < blocksize)
+ BUG();
+
+ if (!hd->bwrite)
+ return;
+
+ if (hd->count > blocksize)
+ {
+ /* This happens only when gcry_md_write is called after final.
+ * Writing after final is used for mitigating timing attacks. */
+ hd->count = 0;
+ }
+
+ while (hd->count)
+ {
+ if (hd->count == blocksize) /* Flush the buffer. */
+ {
+ nburn = hd->bwrite (hd, hd->buf, 1);
+ stack_burn = nburn > stack_burn ? nburn : stack_burn;
+ hd->count = 0;
+ if (!++hd->nblocks)
+ hd->nblocks_high++;
+ }
+ else
+ {
+ copylen = inlen;
+ if (copylen > blocksize - hd->count)
+ copylen = blocksize - hd->count;
+
+ if (copylen == 0)
+ break;
+
+ buf_cpy (&hd->buf[hd->count], inbuf, copylen);
+ hd->count += copylen;
+ inbuf += copylen;
+ inlen -= copylen;
+ }
+ }
+
+ if (inlen == 0)
+ return;
+
+ if (inlen >= blocksize)
+ {
+ inblocks = inlen >> blocksize_shift;
+ nburn = hd->bwrite (hd, inbuf, inblocks);
+ stack_burn = nburn > stack_burn ? nburn : stack_burn;
+ hd->count = 0;
+ hd->nblocks_high += (hd->nblocks + inblocks < inblocks);
+ hd->nblocks += inblocks;
+ inlen -= inblocks << blocksize_shift;
+ inbuf += inblocks << blocksize_shift;
+ }
+
+ if (inlen)
+ {
+ buf_cpy (hd->buf, inbuf, inlen);
+ hd->count = inlen;
+ }
+
+ if (stack_burn > 0)
+ _gcry_burn_stack (stack_burn);
+}
diff --git a/comm/third_party/libgcrypt/cipher/hash-common.h b/comm/third_party/libgcrypt/cipher/hash-common.h
new file mode 100644
index 0000000000..561e77a7e5
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/hash-common.h
@@ -0,0 +1,62 @@
+/* hash-common.h - Declarations of common code for hash algorithms.
+ * Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_HASH_COMMON_H
+#define GCRY_HASH_COMMON_H
+
+#include "types.h"
+
+
+const char * _gcry_hash_selftest_check_one
+/**/ (int algo,
+ int datamode, const void *data, size_t datalen,
+ const void *expect, size_t expectlen);
+
+/* Type for the md_write helper function. */
+typedef unsigned int (*_gcry_md_block_write_t) (void *c,
+ const unsigned char *blks,
+ size_t nblks);
+
+#if (defined(USE_SHA512) || defined(USE_WHIRLPOOL))
+/* SHA-512 and Whirlpool needs u64. SHA-512 needs larger buffer. */
+# define MD_BLOCK_MAX_BLOCKSIZE 128
+# define MD_NBLOCKS_TYPE u64
+#else
+# define MD_BLOCK_MAX_BLOCKSIZE 64
+# define MD_NBLOCKS_TYPE u32
+#endif
+
+/* SHA1 needs 2x64 bytes and SHA-512 needs 128 bytes. */
+#define MD_BLOCK_CTX_BUFFER_SIZE 128
+
+typedef struct gcry_md_block_ctx
+{
+ byte buf[MD_BLOCK_CTX_BUFFER_SIZE];
+ MD_NBLOCKS_TYPE nblocks;
+ MD_NBLOCKS_TYPE nblocks_high;
+ int count;
+ unsigned int blocksize_shift;
+ _gcry_md_block_write_t bwrite;
+} gcry_md_block_ctx_t;
+
+
+void
+_gcry_md_block_write( void *context, const void *inbuf_arg, size_t inlen);
+
+#endif /*GCRY_HASH_COMMON_H*/
diff --git a/comm/third_party/libgcrypt/cipher/idea.c b/comm/third_party/libgcrypt/cipher/idea.c
new file mode 100644
index 0000000000..0a81081810
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/idea.c
@@ -0,0 +1,382 @@
+/* idea.c - IDEA function
+ * Copyright 1997, 1998, 1999, 2001 Werner Koch (dd9jn)
+ * Copyright 2013 g10 Code GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * WERNER KOCH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Werner Koch shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Werner Koch.
+ *
+ * Patents on IDEA have expired:
+ * Europe: EP0482154 on 2011-05-16,
+ * Japan: JP3225440 on 2011-05-16,
+ * U.S.: 5,214,703 on 2012-01-07.
+ */
+
+/*
+ * Please see http://www.noepatents.org/ to learn why software patents
+ * are bad for society and what you can do to fight them.
+ *
+ * The code herein is based on the one from:
+ * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ * ISBN 0-471-11709-9.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+#include "cipher-internal.h"
+
+
+#define IDEA_KEYSIZE 16
+#define IDEA_BLOCKSIZE 8
+#define IDEA_ROUNDS 8
+#define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
+
+typedef struct {
+ u16 ek[IDEA_KEYLEN];
+ u16 dk[IDEA_KEYLEN];
+ int have_dk;
+} IDEA_context;
+
+static const char *selftest(void);
+
+
+static u16
+mul_inv( u16 x )
+{
+ u16 t0, t1;
+ u16 q, y;
+
+ if( x < 2 )
+ return x;
+ t1 = 0x10001UL / x;
+ y = 0x10001UL % x;
+ if( y == 1 )
+ return (1-t1) & 0xffff;
+
+ t0 = 1;
+ do {
+ q = x / y;
+ x = x % y;
+ t0 += q * t1;
+ if( x == 1 )
+ return t0;
+ q = y / x;
+ y = y % x;
+ t1 += q * t0;
+ } while( y != 1 );
+ return (1-t1) & 0xffff;
+}
+
+
+
+static void
+expand_key( const byte *userkey, u16 *ek )
+{
+ int i,j;
+
+ for(j=0; j < 8; j++ ) {
+ ek[j] = (*userkey << 8) + userkey[1];
+ userkey += 2;
+ }
+ for(i=0; j < IDEA_KEYLEN; j++ ) {
+ i++;
+ ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
+ ek += i & 8;
+ i &= 7;
+ }
+}
+
+
+static void
+invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
+{
+ int i;
+ u16 t1, t2, t3;
+ u16 temp[IDEA_KEYLEN];
+ u16 *p = temp + IDEA_KEYLEN;
+
+ t1 = mul_inv( *ek++ );
+ t2 = -*ek++;
+ t3 = -*ek++;
+ *--p = mul_inv( *ek++ );
+ *--p = t3;
+ *--p = t2;
+ *--p = t1;
+
+ for(i=0; i < IDEA_ROUNDS-1; i++ ) {
+ t1 = *ek++;
+ *--p = *ek++;
+ *--p = t1;
+
+ t1 = mul_inv( *ek++ );
+ t2 = -*ek++;
+ t3 = -*ek++;
+ *--p = mul_inv( *ek++ );
+ *--p = t2;
+ *--p = t3;
+ *--p = t1;
+ }
+ t1 = *ek++;
+ *--p = *ek++;
+ *--p = t1;
+
+ t1 = mul_inv( *ek++ );
+ t2 = -*ek++;
+ t3 = -*ek++;
+ *--p = mul_inv( *ek++ );
+ *--p = t3;
+ *--p = t2;
+ *--p = t1;
+ memcpy(dk, temp, sizeof(temp) );
+ wipememory(temp, sizeof(temp));
+}
+
+
+static void
+cipher( byte *outbuf, const byte *inbuf, u16 *key )
+{
+ u16 s2, s3;
+ u16 in[4];
+ int r = IDEA_ROUNDS;
+#define x1 (in[0])
+#define x2 (in[1])
+#define x3 (in[2])
+#define x4 (in[3])
+#define MUL(x,y) \
+ do {u16 _t16; u32 _t32; \
+ if( (_t16 = (y)) ) { \
+ if( (x = (x)&0xffff) ) { \
+ _t32 = (u32)x * _t16; \
+ x = _t32 & 0xffff; \
+ _t16 = _t32 >> 16; \
+ x = ((x)-_t16) + (x<_t16?1:0); \
+ } \
+ else { \
+ x = 1 - _t16; \
+ } \
+ } \
+ else { \
+ x = 1 - x; \
+ } \
+ } while(0)
+
+ memcpy (in, inbuf, sizeof in);
+#ifndef WORDS_BIGENDIAN
+ x1 = (x1>>8) | (x1<<8);
+ x2 = (x2>>8) | (x2<<8);
+ x3 = (x3>>8) | (x3<<8);
+ x4 = (x4>>8) | (x4<<8);
+#endif
+ do {
+ MUL(x1, *key++);
+ x2 += *key++;
+ x3 += *key++;
+ MUL(x4, *key++ );
+
+ s3 = x3;
+ x3 ^= x1;
+ MUL(x3, *key++);
+ s2 = x2;
+ x2 ^=x4;
+ x2 += x3;
+ MUL(x2, *key++);
+ x3 += x2;
+
+ x1 ^= x2;
+ x4 ^= x3;
+
+ x2 ^= s3;
+ x3 ^= s2;
+ } while( --r );
+ MUL(x1, *key++);
+ x3 += *key++;
+ x2 += *key++;
+ MUL(x4, *key);
+
+#ifndef WORDS_BIGENDIAN
+ x1 = (x1>>8) | (x1<<8);
+ x2 = (x2>>8) | (x2<<8);
+ x3 = (x3>>8) | (x3<<8);
+ x4 = (x4>>8) | (x4<<8);
+#endif
+ memcpy (outbuf+0, &x1, 2);
+ memcpy (outbuf+2, &x3, 2);
+ memcpy (outbuf+4, &x2, 2);
+ memcpy (outbuf+6, &x4, 2);
+#undef MUL
+#undef x1
+#undef x2
+#undef x3
+#undef x4
+}
+
+
+static int
+do_setkey( IDEA_context *c, const byte *key, unsigned int keylen )
+{
+ static int initialized = 0;
+ static const char *selftest_failed = 0;
+
+ if( !initialized ) {
+ initialized = 1;
+ selftest_failed = selftest();
+ if( selftest_failed )
+ log_error( "%s\n", selftest_failed );
+ }
+ if( selftest_failed )
+ return GPG_ERR_SELFTEST_FAILED;
+
+ assert(keylen == 16);
+ c->have_dk = 0;
+ expand_key( key, c->ek );
+ invert_key( c->ek, c->dk );
+ return 0;
+}
+
+static gcry_err_code_t
+idea_setkey (void *context, const byte *key, unsigned int keylen,
+ cipher_bulk_ops_t *bulk_ops)
+{
+ IDEA_context *ctx = context;
+ int rc = do_setkey (ctx, key, keylen);
+ (void)bulk_ops;
+ _gcry_burn_stack (23+6*sizeof(void*));
+ return rc;
+}
+
+static void
+encrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf )
+{
+ cipher( outbuf, inbuf, c->ek );
+}
+
+static unsigned int
+idea_encrypt (void *context, byte *out, const byte *in)
+{
+ IDEA_context *ctx = context;
+ encrypt_block (ctx, out, in);
+ return /*burn_stack*/ (24+3*sizeof (void*));
+}
+
+static void
+decrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf )
+{
+ if( !c->have_dk ) {
+ c->have_dk = 1;
+ invert_key( c->ek, c->dk );
+ }
+ cipher( outbuf, inbuf, c->dk );
+}
+
+static unsigned int
+idea_decrypt (void *context, byte *out, const byte *in)
+{
+ IDEA_context *ctx = context;
+ decrypt_block (ctx, out, in);
+ return /*burn_stack*/ (24+3*sizeof (void*));
+}
+
+
+static const char *
+selftest( void )
+{
+static struct {
+ byte key[16];
+ byte plain[8];
+ byte cipher[8];
+} test_vectors[] = {
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 },
+ { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+ { 0x54, 0x0E, 0x5F, 0xEA, 0x18, 0xC2, 0xF8, 0xB1 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x00, 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF },
+ { 0x9F, 0x0A, 0x0A, 0xB6, 0xE1, 0x0C, 0xED, 0x78 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0xF5, 0x20, 0x2D, 0x5B, 0x9C, 0x67, 0x1B, 0x08 },
+ { 0xCF, 0x18, 0xFD, 0x73, 0x55, 0xE2, 0xC5, 0xC5 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0xFA, 0xE6, 0xD2, 0xBE, 0xAA, 0x96, 0x82, 0x6E },
+ { 0x85, 0xDF, 0x52, 0x00, 0x56, 0x08, 0x19, 0x3D } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50 },
+ { 0x2F, 0x7D, 0xE7, 0x50, 0x21, 0x2F, 0xB7, 0x34 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28 },
+ { 0x7B, 0x73, 0x14, 0x92, 0x5D, 0xE5, 0x9C, 0x09 } },
+ { { 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14,
+ 0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28 },
+ { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+ { 0x3E, 0xC0, 0x47, 0x80, 0xBE, 0xFF, 0x6E, 0x20 } },
+ { { 0x3A, 0x98, 0x4E, 0x20, 0x00, 0x19, 0x5D, 0xB3,
+ 0x2E, 0xE5, 0x01, 0xC8, 0xC4, 0x7C, 0xEA, 0x60 },
+ { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+ { 0x97, 0xBC, 0xD8, 0x20, 0x07, 0x80, 0xDA, 0x86 } },
+ { { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90,
+ 0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 },
+ { 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA },
+ { 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED } },
+ { { 0x9D, 0x40, 0x75, 0xC1, 0x03, 0xBC, 0x32, 0x2A,
+ 0xFB, 0x03, 0xE7, 0xBE, 0x6A, 0xB3, 0x00, 0x06 },
+ { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 },
+ { 0xF5, 0xDB, 0x1A, 0xC4, 0x5E, 0x5E, 0xF9, 0xF9 } }
+};
+ IDEA_context c;
+ byte buffer[8];
+ int i;
+
+ for(i=0; i < DIM(test_vectors); i++ ) {
+ do_setkey( &c, test_vectors[i].key, 16 );
+ encrypt_block( &c, buffer, test_vectors[i].plain );
+ if( memcmp( buffer, test_vectors[i].cipher, 8 ) )
+ return "IDEA test encryption failed.";
+ decrypt_block( &c, buffer, test_vectors[i].cipher );
+ if( memcmp( buffer, test_vectors[i].plain, 8 ) )
+ return "IDEA test decryption failed.";
+ }
+
+ return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_idea =
+ {
+ GCRY_CIPHER_IDEA, {0, 0},
+ "IDEA", NULL, NULL, IDEA_BLOCKSIZE, 128,
+ sizeof (IDEA_context),
+ idea_setkey, idea_encrypt, idea_decrypt
+ };
diff --git a/comm/third_party/libgcrypt/cipher/kdf-internal.h b/comm/third_party/libgcrypt/cipher/kdf-internal.h
new file mode 100644
index 0000000000..7079860e99
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/kdf-internal.h
@@ -0,0 +1,40 @@
+/* kdf-internal.h - Internal defs for kdf.c
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_KDF_INTERNAL_H
+#define GCRY_KDF_INTERNAL_H
+
+/*-- kdf.c --*/
+gpg_err_code_t
+_gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
+ int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer);
+
+/*-- scrypt.c --*/
+gcry_err_code_t
+_gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
+ int algo, int subalgo,
+ const unsigned char *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t dklen, unsigned char *dk);
+
+
+#endif /*GCRY_KDF_INTERNAL_H*/
diff --git a/comm/third_party/libgcrypt/cipher/kdf.c b/comm/third_party/libgcrypt/cipher/kdf.c
new file mode 100644
index 0000000000..93c2c9f65e
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/kdf.c
@@ -0,0 +1,503 @@
+/* kdf.c - Key Derivation Functions
+ * Copyright (C) 1998, 2008, 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "kdf-internal.h"
+
+
+/* Transform a passphrase into a suitable key of length KEYSIZE and
+ store this key in the caller provided buffer KEYBUFFER. The caller
+ must provide an HASHALGO, a valid ALGO and depending on that algo a
+ SALT of 8 bytes and the number of ITERATIONS. Code taken from
+ gnupg/agent/protect.c:hash_passphrase. */
+static gpg_err_code_t
+openpgp_s2k (const void *passphrase, size_t passphraselen,
+ int algo, int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+ gcry_md_hd_t md;
+ char *key = keybuffer;
+ int pass, i;
+ int used = 0;
+ int secmode;
+
+ if ((algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
+ && (!salt || saltlen != 8))
+ return GPG_ERR_INV_VALUE;
+
+ secmode = _gcry_is_secure (passphrase) || _gcry_is_secure (keybuffer);
+
+ ec = _gcry_md_open (&md, hashalgo, secmode? GCRY_MD_FLAG_SECURE : 0);
+ if (ec)
+ return ec;
+
+ for (pass=0; used < keysize; pass++)
+ {
+ if (pass)
+ {
+ _gcry_md_reset (md);
+ for (i=0; i < pass; i++) /* Preset the hash context. */
+ _gcry_md_putc (md, 0);
+ }
+
+ if (algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
+ {
+ int len2 = passphraselen + 8;
+ unsigned long count = len2;
+
+ if (algo == GCRY_KDF_ITERSALTED_S2K)
+ {
+ count = iterations;
+ if (count < len2)
+ count = len2;
+ }
+
+ while (count > len2)
+ {
+ _gcry_md_write (md, salt, saltlen);
+ _gcry_md_write (md, passphrase, passphraselen);
+ count -= len2;
+ }
+ if (count < saltlen)
+ _gcry_md_write (md, salt, count);
+ else
+ {
+ _gcry_md_write (md, salt, saltlen);
+ count -= saltlen;
+ _gcry_md_write (md, passphrase, count);
+ }
+ }
+ else
+ _gcry_md_write (md, passphrase, passphraselen);
+
+ _gcry_md_final (md);
+ i = _gcry_md_get_algo_dlen (hashalgo);
+ if (i > keysize - used)
+ i = keysize - used;
+ memcpy (key+used, _gcry_md_read (md, hashalgo), i);
+ used += i;
+ }
+ _gcry_md_close (md);
+ return 0;
+}
+
+
+/* Transform a passphrase into a suitable key of length KEYSIZE and
+ store this key in the caller provided buffer KEYBUFFER. The caller
+ must provide PRFALGO which indicates the pseudorandom function to
+ use: This shall be the algorithms id of a hash algorithm; it is
+ used in HMAC mode. SALT is a salt of length SALTLEN and ITERATIONS
+ gives the number of iterations. */
+gpg_err_code_t
+_gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
+ int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+ gcry_md_hd_t md;
+ int secmode;
+ unsigned long dklen = keysize;
+ char *dk = keybuffer;
+ unsigned int hlen; /* Output length of the digest function. */
+ unsigned int l; /* Rounded up number of blocks. */
+ unsigned int r; /* Number of octets in the last block. */
+ char *sbuf; /* Malloced buffer to concatenate salt and iter
+ as well as space to hold TBUF and UBUF. */
+ char *tbuf; /* Buffer for T; ptr into SBUF, size is HLEN. */
+ char *ubuf; /* Buffer for U; ptr into SBUF, size is HLEN. */
+ unsigned int lidx; /* Current block number. */
+ unsigned long iter; /* Current iteration number. */
+ unsigned int i;
+
+ /* We allow for a saltlen of 0 here to support scrypt. It is not
+ clear whether rfc2898 allows for this this, thus we do a test on
+ saltlen > 0 only in gcry_kdf_derive. */
+ if (!salt || !iterations || !dklen)
+ return GPG_ERR_INV_VALUE;
+
+ hlen = _gcry_md_get_algo_dlen (hashalgo);
+ if (!hlen)
+ return GPG_ERR_DIGEST_ALGO;
+
+ secmode = _gcry_is_secure (passphrase) || _gcry_is_secure (keybuffer);
+
+ /* Step 1 */
+ /* If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
+ * stop. We use a stronger inequality but only if our type can hold
+ * a larger value. */
+
+#if SIZEOF_UNSIGNED_LONG > 4
+ if (dklen > 0xffffffffU)
+ return GPG_ERR_INV_VALUE;
+#endif
+
+
+ /* Step 2 */
+ l = ((dklen - 1)/ hlen) + 1;
+ r = dklen - (l - 1) * hlen;
+
+ /* Setup buffers and prepare a hash context. */
+ sbuf = (secmode
+ ? xtrymalloc_secure (saltlen + 4 + hlen + hlen)
+ : xtrymalloc (saltlen + 4 + hlen + hlen));
+ if (!sbuf)
+ return gpg_err_code_from_syserror ();
+ tbuf = sbuf + saltlen + 4;
+ ubuf = tbuf + hlen;
+
+ ec = _gcry_md_open (&md, hashalgo, (GCRY_MD_FLAG_HMAC
+ | (secmode?GCRY_MD_FLAG_SECURE:0)));
+ if (ec)
+ {
+ xfree (sbuf);
+ return ec;
+ }
+
+ ec = _gcry_md_setkey (md, passphrase, passphraselen);
+ if (ec)
+ {
+ _gcry_md_close (md);
+ xfree (sbuf);
+ return ec;
+ }
+
+ /* Step 3 and 4. */
+ memcpy (sbuf, salt, saltlen);
+ for (lidx = 1; lidx <= l; lidx++)
+ {
+ for (iter = 0; iter < iterations; iter++)
+ {
+ _gcry_md_reset (md);
+ if (!iter) /* Compute U_1: */
+ {
+ sbuf[saltlen] = (lidx >> 24);
+ sbuf[saltlen + 1] = (lidx >> 16);
+ sbuf[saltlen + 2] = (lidx >> 8);
+ sbuf[saltlen + 3] = lidx;
+ _gcry_md_write (md, sbuf, saltlen + 4);
+ memcpy (ubuf, _gcry_md_read (md, 0), hlen);
+ memcpy (tbuf, ubuf, hlen);
+ }
+ else /* Compute U_(2..c): */
+ {
+ _gcry_md_write (md, ubuf, hlen);
+ memcpy (ubuf, _gcry_md_read (md, 0), hlen);
+ for (i=0; i < hlen; i++)
+ tbuf[i] ^= ubuf[i];
+ }
+ }
+ if (lidx == l) /* Last block. */
+ memcpy (dk, tbuf, r);
+ else
+ {
+ memcpy (dk, tbuf, hlen);
+ dk += hlen;
+ }
+ }
+
+ _gcry_md_close (md);
+ xfree (sbuf);
+ return 0;
+}
+
+
+/* Derive a key from a passphrase. KEYSIZE gives the requested size
+ of the keys in octets. KEYBUFFER is a caller provided buffer
+ filled on success with the derived key. The input passphrase is
+ taken from (PASSPHRASE,PASSPHRASELEN) which is an arbitrary memory
+ buffer. ALGO specifies the KDF algorithm to use; these are the
+ constants GCRY_KDF_*. SUBALGO specifies an algorithm used
+ internally by the KDF algorithms; this is usually a hash algorithm
+ but certain KDF algorithm may use it differently. {SALT,SALTLEN}
+ is a salt as needed by most KDF algorithms. ITERATIONS is a
+ positive integer parameter to most KDFs. 0 is returned on success,
+ or an error code on failure. */
+gpg_err_code_t
+_gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int subalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+
+ if (!passphrase)
+ {
+ ec = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ if (!keybuffer || !keysize)
+ {
+ ec = GPG_ERR_INV_VALUE;
+ goto leave;
+ }
+
+
+ switch (algo)
+ {
+ case GCRY_KDF_SIMPLE_S2K:
+ case GCRY_KDF_SALTED_S2K:
+ case GCRY_KDF_ITERSALTED_S2K:
+ if (!passphraselen)
+ ec = GPG_ERR_INV_DATA;
+ else
+ ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+ break;
+
+ case GCRY_KDF_PBKDF1:
+ ec = GPG_ERR_UNSUPPORTED_ALGORITHM;
+ break;
+
+ case GCRY_KDF_PBKDF2:
+ if (!saltlen)
+ ec = GPG_ERR_INV_VALUE;
+ else
+ ec = _gcry_kdf_pkdf2 (passphrase, passphraselen, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+ break;
+
+ case 41:
+ case GCRY_KDF_SCRYPT:
+#if USE_SCRYPT
+ ec = _gcry_kdf_scrypt (passphrase, passphraselen, algo, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+#else
+ ec = GPG_ERR_UNSUPPORTED_ALGORITHM;
+#endif /*USE_SCRYPT*/
+ break;
+
+ default:
+ ec = GPG_ERR_UNKNOWN_ALGORITHM;
+ break;
+ }
+
+ leave:
+ return ec;
+}
+
+
+/* Check one KDF call with ALGO and HASH_ALGO using the regular KDF
+ * API. (passphrase,passphraselen) is the password to be derived,
+ * (salt,saltlen) the salt for the key derivation,
+ * iterations is the number of the kdf iterations,
+ * and (expect,expectlen) the expected result. Returns NULL on
+ * success or a string describing the failure. */
+
+static const char *
+check_one (int algo, int hash_algo,
+ const void *passphrase, size_t passphraselen,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ const void *expect, size_t expectlen)
+{
+ unsigned char key[512]; /* hardcoded to avoid allocation */
+ size_t keysize = expectlen;
+
+ if (keysize > sizeof(key))
+ return "invalid tests data";
+
+ if (_gcry_kdf_derive (passphrase, passphraselen, algo,
+ hash_algo, salt, saltlen, iterations,
+ keysize, key))
+ return "gcry_kdf_derive failed";
+
+ if (memcmp (key, expect, expectlen))
+ return "does not match";
+
+ return NULL;
+}
+
+
+static gpg_err_code_t
+selftest_pbkdf2 (int extended, selftest_report_func_t report)
+{
+ static const struct {
+ const char *desc;
+ const char *p; /* Passphrase. */
+ size_t plen; /* Length of P. */
+ const char *salt;
+ size_t saltlen;
+ int hashalgo;
+ unsigned long c; /* Iterations. */
+ int dklen; /* Requested key length. */
+ const char *dk; /* Derived key. */
+ int disabled;
+ } tv[] = {
+#if USE_SHA1
+#define NUM_TEST_VECTORS 9
+ /* SHA1 test vectors are from RFC-6070. */
+ {
+ "Basic PBKDF2 SHA1 #1",
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 1,
+ 20,
+ "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
+ "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"
+ },
+ {
+ "Basic PBKDF2 SHA1 #2",
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 2,
+ 20,
+ "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
+ "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"
+ },
+ {
+ "Basic PBKDF2 SHA1 #3",
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 4096,
+ 20,
+ "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
+ "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1"
+ },
+ {
+ "Basic PBKDF2 SHA1 #4",
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 16777216,
+ 20,
+ "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
+ "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84",
+ 1 /* This test takes too long. */
+ },
+ {
+ "Basic PBKDF2 SHA1 #5",
+ "passwordPASSWORDpassword", 24,
+ "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+ GCRY_MD_SHA1,
+ 4096,
+ 25,
+ "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8"
+ "\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96"
+ "\x4c\xf2\xf0\x70\x38"
+ },
+ {
+ "Basic PBKDF2 SHA1 #6",
+ "pass\0word", 9,
+ "sa\0lt", 5,
+ GCRY_MD_SHA1,
+ 4096,
+ 16,
+ "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37"
+ "\xd7\xf0\x34\x25\xe0\xc3"
+ },
+ { /* empty password test, not in RFC-6070 */
+ "Basic PBKDF2 SHA1 #7",
+ "", 0,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 2,
+ 20,
+ "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2"
+ "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97"
+ },
+#else
+#define NUM_TEST_VECTORS 2
+#endif
+ {
+ "Basic PBKDF2 SHA256",
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA256,
+ 2,
+ 32,
+ "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0"
+ "\x2a\x30\x3f\x8e\xf3\xc2\x51\xdf\xd6\xe2\xd8\x5a\x95\x47\x4c\x43"
+ },
+ {
+ "Extended PBKDF2 SHA256",
+ "passwordPASSWORDpassword", 24,
+ "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+ GCRY_MD_SHA256,
+ 4096,
+ 40,
+ "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf"
+ "\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c\x4e\x2a\x1f\xb8\xdd\x53\xe1"
+ "\xc6\x35\x51\x8c\x7d\xac\x47\xe9"
+ },
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ if (tv[tvidx].disabled)
+ continue;
+ errtxt = check_one (GCRY_KDF_PBKDF2, tv[tvidx].hashalgo,
+ tv[tvidx].p, tv[tvidx].plen,
+ tv[tvidx].salt, tv[tvidx].saltlen,
+ tv[tvidx].c,
+ tv[tvidx].dk, tv[tvidx].dklen);
+ if (errtxt)
+ goto failed;
+ if (tvidx >= NUM_TEST_VECTORS - 1 && !extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("kdf", GCRY_KDF_PBKDF2, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run the selftests for KDF with KDF algorithm ALGO with optional
+ reporting function REPORT. */
+gpg_error_t
+_gcry_kdf_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_err_code_t ec = 0;
+
+ if (algo == GCRY_KDF_PBKDF2)
+ ec = selftest_pbkdf2 (extended, report);
+ else
+ {
+ ec = GPG_ERR_UNSUPPORTED_ALGORITHM;
+ if (report)
+ report ("kdf", algo, "module", "algorithm not available");
+ }
+ return gpg_error (ec);
+}
diff --git a/comm/third_party/libgcrypt/cipher/keccak-armv7-neon.S b/comm/third_party/libgcrypt/cipher/keccak-armv7-neon.S
new file mode 100644
index 0000000000..0bec8d50a9
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/keccak-armv7-neon.S
@@ -0,0 +1,945 @@
+/* keccak-armv7-neon.S - ARMv7/NEON implementation of Keccak
+ *
+ * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_NEON)
+
+/* Based on public-domain/CC0 implementation from SUPERCOP package
+ * (keccakc1024/inplace-armv7a-neon/keccak2.s)
+ *
+ * Original copyright header follows:
+ */
+
+@ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
+@ Michaël Peeters and Gilles Van Assche. For more information, feedback or
+@ questions, please refer to our website: http://keccak.noekeon.org/
+@
+@ Implementation by Ronny Van Keer, hereby denoted as "the implementer".
+@
+@ To the extent possible under law, the implementer has waived all copyright
+@ and related or neighboring rights to the source code in this file.
+@ http://creativecommons.org/publicdomain/zero/1.0/
+
+.text
+
+.syntax unified
+.fpu neon
+.arm
+
+
+.extern _gcry_keccak_round_consts_64bit;
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+
+@// --- offsets in state
+.equ Aba, 0*8
+.equ Aga, 1*8
+.equ Aka, 2*8
+.equ Ama, 3*8
+.equ Asa, 4*8
+
+@// --- macros
+
+.macro KeccakThetaRhoPiChiIota argA1, argA2, argA3, argA4, argA5
+
+ @Prepare Theta
+ @Ca = Aba^Aga^Aka^Ama^Asa@
+ @Ce = Abe^Age^Ake^Ame^Ase@
+ @Ci = Abi^Agi^Aki^Ami^Asi@
+ @Co = Abo^Ago^Ako^Amo^Aso@
+ @Cu = Abu^Agu^Aku^Amu^Asu@
+ @De = Ca^ROL64(Ci, 1)@
+ @Di = Ce^ROL64(Co, 1)@
+ @Do = Ci^ROL64(Cu, 1)@
+ @Du = Co^ROL64(Ca, 1)@
+ @Da = Cu^ROL64(Ce, 1)@
+
+ veor.64 q4, q6, q7
+ veor.64 q5, q9, q10
+ veor.64 d8, d8, d9
+ veor.64 d10, d10, d11
+ veor.64 d1, d8, d16
+ veor.64 d2, d10, d17
+
+ veor.64 q4, q11, q12
+ veor.64 q5, q14, q15
+ veor.64 d8, d8, d9
+ veor.64 d10, d10, d11
+ veor.64 d3, d8, d26
+
+ vadd.u64 q4, q1, q1
+ veor.64 d4, d10, d27
+ vmov.64 d0, d5
+ vsri.64 q4, q1, #63
+
+ vadd.u64 q5, q2, q2
+ veor.64 q4, q4, q0
+ vsri.64 q5, q2, #63
+ vadd.u64 d7, d1, d1
+ veor.64 \argA2, \argA2, d8
+ veor.64 q5, q5, q1
+
+ vsri.64 d7, d1, #63
+ vshl.u64 d1, \argA2, #44
+ veor.64 \argA3, \argA3, d9
+ veor.64 d7, d7, d4
+
+ @Ba = argA1^Da@
+ @Be = ROL64((argA2^De), 44)@
+ @Bi = ROL64((argA3^Di), 43)@
+ @Bo = ROL64((argA4^Do), 21)@
+ @Bu = ROL64((argA5^Du), 14)@
+ @argA2 = Be ^((~Bi)& Bo )@
+ @argA3 = Bi ^((~Bo)& Bu )@
+ @argA4 = Bo ^((~Bu)& Ba )@
+ @argA5 = Bu ^((~Ba)& Be )@
+ @argA1 = Ba ^((~Be)& Bi )@ argA1 ^= KeccakF1600RoundConstants[i+round]@
+ vsri.64 d1, \argA2, #64-44
+ vshl.u64 d2, \argA3, #43
+ vldr.64 d0, [sp, #\argA1]
+ veor.64 \argA4, \argA4, d10
+ vsri.64 d2, \argA3, #64-43
+ vshl.u64 d3, \argA4, #21
+ veor.64 \argA5, \argA5, d11
+ veor.64 d0, d0, d7
+ vsri.64 d3, \argA4, #64-21
+ vbic.64 d5, d2, d1
+ vshl.u64 d4, \argA5, #14
+ vbic.64 \argA2, d3, d2
+ vld1.64 d6, [ip]!
+ veor.64 d5, d0
+ vsri.64 d4, \argA5, #64-14
+ veor.64 d5, d6
+ vbic.64 \argA5, d1, d0
+ vbic.64 \argA3, d4, d3
+ vbic.64 \argA4, d0, d4
+ veor.64 \argA2, d1
+ vstr.64 d5, [sp, #\argA1]
+ veor.64 \argA3, d2
+ veor.64 \argA4, d3
+ veor.64 \argA5, d4
+
+ .endm
+
+.macro KeccakThetaRhoPiChi1 argA1, argA2, argA3, argA4, argA5
+
+ @d2 = ROL64((argA1^Da), 3)@
+ @d3 = ROL64((argA2^De), 45)@
+ @d4 = ROL64((argA3^Di), 61)@
+ @d0 = ROL64((argA4^Do), 28)@
+ @d1 = ROL64((argA5^Du), 20)@
+ @argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
+ @argA2 = Be ^((~Bi)& Bo )@
+ @argA3 = Bi ^((~Bo)& Bu )@
+ @argA4 = Bo ^((~Bu)& Ba )@
+ @argA5 = Bu ^((~Ba)& Be )@
+
+ veor.64 \argA2, \argA2, d8
+ veor.64 \argA3, \argA3, d9
+ vshl.u64 d3, \argA2, #45
+ vldr.64 d6, [sp, #\argA1]
+ vshl.u64 d4, \argA3, #61
+ veor.64 \argA4, \argA4, d10
+ vsri.64 d3, \argA2, #64-45
+ veor.64 \argA5, \argA5, d11
+ vsri.64 d4, \argA3, #64-61
+ vshl.u64 d0, \argA4, #28
+ veor.64 d6, d6, d7
+ vshl.u64 d1, \argA5, #20
+ vbic.64 \argA3, d4, d3
+ vsri.64 d0, \argA4, #64-28
+ vbic.64 \argA4, d0, d4
+ vshl.u64 d2, d6, #3
+ vsri.64 d1, \argA5, #64-20
+ veor.64 \argA4, d3
+ vsri.64 d2, d6, #64-3
+ vbic.64 \argA5, d1, d0
+ vbic.64 d6, d2, d1
+ vbic.64 \argA2, d3, d2
+ veor.64 d6, d0
+ veor.64 \argA2, d1
+ vstr.64 d6, [sp, #\argA1]
+ veor.64 \argA3, d2
+ veor.64 d5, d6
+ veor.64 \argA5, d4
+
+ .endm
+
+.macro KeccakThetaRhoPiChi2 argA1, argA2, argA3, argA4, argA5
+
+ @d4 = ROL64((argA1^Da), 18)@
+ @d0 = ROL64((argA2^De), 1)@
+ @d1 = ROL64((argA3^Di), 6)@
+ @d2 = ROL64((argA4^Do), 25)@
+ @d3 = ROL64((argA5^Du), 8)@
+ @argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
+ @argA2 = Be ^((~Bi)& Bo )@
+ @argA3 = Bi ^((~Bo)& Bu )@
+ @argA4 = Bo ^((~Bu)& Ba )@
+ @argA5 = Bu ^((~Ba)& Be )@
+
+ veor.64 \argA3, \argA3, d9
+ veor.64 \argA4, \argA4, d10
+ vshl.u64 d1, \argA3, #6
+ vldr.64 d6, [sp, #\argA1]
+ vshl.u64 d2, \argA4, #25
+ veor.64 \argA5, \argA5, d11
+ vsri.64 d1, \argA3, #64-6
+ veor.64 \argA2, \argA2, d8
+ vsri.64 d2, \argA4, #64-25
+ vext.8 d3, \argA5, \argA5, #7
+ veor.64 d6, d6, d7
+ vbic.64 \argA3, d2, d1
+ vadd.u64 d0, \argA2, \argA2
+ vbic.64 \argA4, d3, d2
+ vsri.64 d0, \argA2, #64-1
+ vshl.u64 d4, d6, #18
+ veor.64 \argA2, d1, \argA4
+ veor.64 \argA3, d0
+ vsri.64 d4, d6, #64-18
+ vstr.64 \argA3, [sp, #\argA1]
+ veor.64 d5, \argA3
+ vbic.64 \argA5, d1, d0
+ vbic.64 \argA3, d4, d3
+ vbic.64 \argA4, d0, d4
+ veor.64 \argA3, d2
+ veor.64 \argA4, d3
+ veor.64 \argA5, d4
+
+ .endm
+
+.macro KeccakThetaRhoPiChi3 argA1, argA2, argA3, argA4, argA5
+
+ @d1 = ROL64((argA1^Da), 36)@
+ @d2 = ROL64((argA2^De), 10)@
+ @d3 = ROL64((argA3^Di), 15)@
+ @d4 = ROL64((argA4^Do), 56)@
+ @d0 = ROL64((argA5^Du), 27)@
+ @argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
+ @argA2 = Be ^((~Bi)& Bo )@
+ @argA3 = Bi ^((~Bo)& Bu )@
+ @argA4 = Bo ^((~Bu)& Ba )@
+ @argA5 = Bu ^((~Ba)& Be )@
+
+ veor.64 \argA2, \argA2, d8
+ veor.64 \argA3, \argA3, d9
+ vshl.u64 d2, \argA2, #10
+ vldr.64 d6, [sp, #\argA1]
+ vshl.u64 d3, \argA3, #15
+ veor.64 \argA4, \argA4, d10
+ vsri.64 d2, \argA2, #64-10
+ vsri.64 d3, \argA3, #64-15
+ veor.64 \argA5, \argA5, d11
+ vext.8 d4, \argA4, \argA4, #1
+ vbic.64 \argA2, d3, d2
+ vshl.u64 d0, \argA5, #27
+ veor.64 d6, d6, d7
+ vbic.64 \argA3, d4, d3
+ vsri.64 d0, \argA5, #64-27
+ vshl.u64 d1, d6, #36
+ veor.64 \argA3, d2
+ vbic.64 \argA4, d0, d4
+ vsri.64 d1, d6, #64-36
+
+ veor.64 \argA4, d3
+ vbic.64 d6, d2, d1
+ vbic.64 \argA5, d1, d0
+ veor.64 d6, d0
+ veor.64 \argA2, d1
+ vstr.64 d6, [sp, #\argA1]
+ veor.64 d5, d6
+ veor.64 \argA5, d4
+
+ .endm
+
+.macro KeccakThetaRhoPiChi4 argA1, argA2, argA3, argA4, argA5
+
+ @d3 = ROL64((argA1^Da), 41)@
+ @d4 = ROL64((argA2^De), 2)@
+ @d0 = ROL64((argA3^Di), 62)@
+ @d1 = ROL64((argA4^Do), 55)@
+ @d2 = ROL64((argA5^Du), 39)@
+ @argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
+ @argA2 = Be ^((~Bi)& Bo )@
+ @argA3 = Bi ^((~Bo)& Bu )@
+ @argA4 = Bo ^((~Bu)& Ba )@
+ @argA5 = Bu ^((~Ba)& Be )@
+
+ veor.64 \argA2, \argA2, d8
+ veor.64 \argA3, \argA3, d9
+ vshl.u64 d4, \argA2, #2
+ veor.64 \argA5, \argA5, d11
+ vshl.u64 d0, \argA3, #62
+ vldr.64 d6, [sp, #\argA1]
+ vsri.64 d4, \argA2, #64-2
+ veor.64 \argA4, \argA4, d10
+ vsri.64 d0, \argA3, #64-62
+
+ vshl.u64 d1, \argA4, #55
+ veor.64 d6, d6, d7
+ vshl.u64 d2, \argA5, #39
+ vsri.64 d1, \argA4, #64-55
+ vbic.64 \argA4, d0, d4
+ vsri.64 d2, \argA5, #64-39
+ vbic.64 \argA2, d1, d0
+ vshl.u64 d3, d6, #41
+ veor.64 \argA5, d4, \argA2
+ vbic.64 \argA2, d2, d1
+ vsri.64 d3, d6, #64-41
+ veor.64 d6, d0, \argA2
+
+ vbic.64 \argA2, d3, d2
+ vbic.64 \argA3, d4, d3
+ veor.64 \argA2, d1
+ vstr.64 d6, [sp, #\argA1]
+ veor.64 d5, d6
+ veor.64 \argA3, d2
+ veor.64 \argA4, d3
+
+ .endm
+
+
+@// --- code
+
+@not callable from C!
+.p2align 3
+.type KeccakF_armv7a_neon_asm,%function;
+KeccakF_armv7a_neon_asm: @
+
+.LroundLoop:
+
+ KeccakThetaRhoPiChiIota Aba, d13, d19, d25, d31
+ KeccakThetaRhoPiChi1 Aka, d15, d21, d22, d28
+ KeccakThetaRhoPiChi2 Asa, d12, d18, d24, d30
+ KeccakThetaRhoPiChi3 Aga, d14, d20, d26, d27
+ KeccakThetaRhoPiChi4 Ama, d16, d17, d23, d29
+
+ KeccakThetaRhoPiChiIota Aba, d15, d18, d26, d29
+ KeccakThetaRhoPiChi1 Asa, d14, d17, d25, d28
+ KeccakThetaRhoPiChi2 Ama, d13, d21, d24, d27
+ KeccakThetaRhoPiChi3 Aka, d12, d20, d23, d31
+ KeccakThetaRhoPiChi4 Aga, d16, d19, d22, d30
+
+ KeccakThetaRhoPiChiIota Aba, d14, d21, d23, d30
+ KeccakThetaRhoPiChi1 Ama, d12, d19, d26, d28
+ KeccakThetaRhoPiChi2 Aga, d15, d17, d24, d31
+ KeccakThetaRhoPiChi3 Asa, d13, d20, d22, d29
+ KeccakThetaRhoPiChi4 Aka, d16, d18, d25, d27
+
+ KeccakThetaRhoPiChiIota Aba, d12, d17, d22, d27
+ KeccakThetaRhoPiChi1 Aga, d13, d18, d23, d28
+ KeccakThetaRhoPiChi2 Aka, d14, d19, d24, d29
+ ldr r0, [ip]
+ KeccakThetaRhoPiChi3 Ama, d15, d20, d25, d30
+ cmp r0, #0xFFFFFFFF
+ KeccakThetaRhoPiChi4 Asa, d16, d21, d26, d31
+
+ bne .LroundLoop
+ sub ip, #(8*24)
+ bx lr
+.p2align 2
+.ltorg
+.size KeccakF_armv7a_neon_asm,.-KeccakF_armv7a_neon_asm;
+
+
+@//unsigned _gcry_keccak_permute_armv7_neon(u64 *state) callable from C
+.p2align 3
+.global _gcry_keccak_permute_armv7_neon
+.type _gcry_keccak_permute_armv7_neon,%function;
+_gcry_keccak_permute_armv7_neon:
+
+ push {ip, lr}
+ vpush {q4-q7}
+ sub sp,sp, #5*8
+
+ vldr.64 d0, [r0, #0*8]
+ vldr.64 d12, [r0, #1*8]
+ vldr.64 d17, [r0, #2*8]
+ vldr.64 d22, [r0, #3*8]
+ vldr.64 d27, [r0, #4*8]
+
+ GET_DATA_POINTER(ip, _gcry_keccak_round_consts_64bit, lr);
+
+ vldr.64 d1, [r0, #5*8]
+ vldr.64 d13, [r0, #6*8]
+ vldr.64 d18, [r0, #7*8]
+ vldr.64 d23, [r0, #8*8]
+ vldr.64 d28, [r0, #9*8]
+
+ vldr.64 d2, [r0, #10*8]
+ vldr.64 d14, [r0, #11*8]
+ vldr.64 d19, [r0, #12*8]
+ vldr.64 d24, [r0, #13*8]
+ vldr.64 d29, [r0, #14*8]
+
+ vldr.64 d3, [r0, #15*8]
+ vldr.64 d15, [r0, #16*8]
+ vldr.64 d20, [r0, #17*8]
+ vldr.64 d25, [r0, #18*8]
+ vldr.64 d30, [r0, #19*8]
+
+ vldr.64 d4, [r0, #20*8]
+ vldr.64 d16, [r0, #21*8]
+ vldr.64 d21, [r0, #22*8]
+ vldr.64 d26, [r0, #23*8]
+ vldr.64 d31, [r0, #24*8]
+
+ vstr.64 d0, [sp, #Aba]
+ vstr.64 d1, [sp, #Aga]
+ veor.64 q0, q0, q1
+ vstr.64 d2, [sp, #Aka]
+ veor.64 d5, d0, d1
+ vstr.64 d3, [sp, #Ama]
+ mov r1, r0
+ vstr.64 d4, [sp, #Asa]
+ veor.64 d5, d5, d4
+
+ bl KeccakF_armv7a_neon_asm
+
+ vpop.64 { d0- d4 }
+
+ vstr.64 d0, [r1, #0*8]
+ vstr.64 d12, [r1, #1*8]
+ vstr.64 d17, [r1, #2*8]
+ vstr.64 d22, [r1, #3*8]
+ vstr.64 d27, [r1, #4*8]
+
+ vstr.64 d1, [r1, #5*8]
+ vstr.64 d13, [r1, #6*8]
+ vstr.64 d18, [r1, #7*8]
+ vstr.64 d23, [r1, #8*8]
+ vstr.64 d28, [r1, #9*8]
+
+ vstr.64 d2, [r1, #10*8]
+ vstr.64 d14, [r1, #11*8]
+ vstr.64 d19, [r1, #12*8]
+ vstr.64 d24, [r1, #13*8]
+ vstr.64 d29, [r1, #14*8]
+
+ vstr.64 d3, [r1, #15*8]
+ vstr.64 d15, [r1, #16*8]
+ vstr.64 d20, [r1, #17*8]
+ vstr.64 d25, [r1, #18*8]
+ vstr.64 d30, [r1, #19*8]
+
+ vstr.64 d4, [r1, #20*8]
+ vstr.64 d16, [r1, #21*8]
+ vstr.64 d21, [r1, #22*8]
+ vstr.64 d26, [r1, #23*8]
+ vstr.64 d31, [r1, #24*8]
+
+ mov r0, #112
+ vpop {q4-q7}
+ pop {ip, pc}
+.p2align 2
+.ltorg
+.size _gcry_keccak_permute_armv7_neon,.-_gcry_keccak_permute_armv7_neon;
+
+@//unsigned _gcry_keccak_permute_armv7_neon(u64 *state, @r4
+@ int pos, @r1
+@ const byte *lanes, @r2
+@ unsigned int nlanes, @r3
+@ int blocklanes) @ r5 callable from C
+.p2align 3
+.global _gcry_keccak_absorb_lanes64_armv7_neon
+.type _gcry_keccak_absorb_lanes64_armv7_neon,%function;
+_gcry_keccak_absorb_lanes64_armv7_neon:
+
+ cmp r3, #0 @ nlanes == 0
+ itt eq
+ moveq r0, #0
+ bxeq lr
+
+ push {r4-r5, ip, lr}
+ beq .Lout
+ mov r4, r0
+ ldr r5, [sp, #(4*4)]
+ vpush {q4-q7}
+
+ @ load state
+ vldr.64 d0, [r4, #0*8]
+ vldr.64 d12, [r4, #1*8]
+ vldr.64 d17, [r4, #2*8]
+ vldr.64 d22, [r4, #3*8]
+ vldr.64 d27, [r4, #4*8]
+
+ GET_DATA_POINTER(ip, _gcry_keccak_round_consts_64bit, lr);
+
+ vldr.64 d1, [r4, #5*8]
+ vldr.64 d13, [r4, #6*8]
+ vldr.64 d18, [r4, #7*8]
+ vldr.64 d23, [r4, #8*8]
+ vldr.64 d28, [r4, #9*8]
+
+ vldr.64 d2, [r4, #10*8]
+ vldr.64 d14, [r4, #11*8]
+ vldr.64 d19, [r4, #12*8]
+ vldr.64 d24, [r4, #13*8]
+ vldr.64 d29, [r4, #14*8]
+
+ vldr.64 d3, [r4, #15*8]
+ vldr.64 d15, [r4, #16*8]
+ vldr.64 d20, [r4, #17*8]
+ vldr.64 d25, [r4, #18*8]
+ vldr.64 d30, [r4, #19*8]
+
+ vldr.64 d4, [r4, #20*8]
+ vldr.64 d16, [r4, #21*8]
+ vldr.64 d21, [r4, #22*8]
+ vldr.64 d26, [r4, #23*8]
+ vldr.64 d31, [r4, #24*8]
+
+.Lmain_loop:
+
+ @ detect absorb mode (full blocks vs lanes)
+
+ cmp r1, #0 @ pos != 0
+ bne .Llanes_loop
+
+.Lmain_loop_pos0:
+
+ @ full blocks mode
+
+ @ switch (blocksize)
+ cmp r5, #21
+ beq .Lfull_block_21
+ cmp r5, #18
+ beq .Lfull_block_18
+ cmp r5, #17
+ beq .Lfull_block_17
+ cmp r5, #13
+ beq .Lfull_block_13
+ cmp r5, #9
+ beq .Lfull_block_9
+
+ @ unknown blocksize
+ b .Llanes_loop
+
+.Lfull_block_21:
+
+ @ SHAKE128
+
+ cmp r3, #21 @ nlanes < blocklanes
+ blo .Llanes_loop
+
+ sub sp,sp, #5*8
+
+ vld1.64 {d5-d8}, [r2]!
+ veor d0, d5
+ vld1.64 {d9-d11}, [r2]!
+ veor d12, d6
+ veor d17, d7
+ veor d22, d8
+ vld1.64 {d5-d8}, [r2]!
+ veor d27, d9
+
+ veor d1, d10
+ veor d13, d11
+ vld1.64 {d9-d11}, [r2]!
+ veor d18, d5
+ veor d23, d6
+ veor d28, d7
+
+ veor d2, d8
+ vld1.64 {d5-d8}, [r2]!
+ veor d14, d9
+ veor d19, d10
+ veor d24, d11
+ vld1.64 {d9-d11}, [r2]!
+ veor d29, d5
+
+ veor d3, d6
+ veor d15, d7
+ veor d20, d8
+ veor d25, d9
+ veor d30, d10
+
+ veor d4, d11
+
+ vstr.64 d0, [sp, #Aba]
+ vstr.64 d1, [sp, #Aga]
+ veor.64 q0, q0, q1
+ vstr.64 d2, [sp, #Aka]
+ veor.64 d5, d0, d1
+ vstr.64 d3, [sp, #Ama]
+ vstr.64 d4, [sp, #Asa]
+ veor.64 d5, d5, d4
+
+ bl KeccakF_armv7a_neon_asm
+
+ subs r3, #21 @ nlanes -= 21
+ vpop.64 { d0-d4 }
+
+ beq .Ldone
+
+ b .Lfull_block_21
+
+.Lfull_block_18:
+
+ @ SHA3-224
+
+ cmp r3, #18 @ nlanes < blocklanes
+ blo .Llanes_loop
+
+ sub sp,sp, #5*8
+
+ vld1.64 {d5-d8}, [r2]!
+ veor d0, d5
+ vld1.64 {d9-d11}, [r2]!
+ veor d12, d6
+ veor d17, d7
+ veor d22, d8
+ vld1.64 {d5-d8}, [r2]!
+ veor d27, d9
+
+ veor d1, d10
+ veor d13, d11
+ vld1.64 {d9-d11}, [r2]!
+ veor d18, d5
+ veor d23, d6
+ veor d28, d7
+
+ veor d2, d8
+ vld1.64 {d5-d8}, [r2]!
+ veor d14, d9
+ veor d19, d10
+ veor d24, d11
+ veor d29, d5
+
+ veor d3, d6
+ veor d15, d7
+ veor d20, d8
+
+ vstr.64 d0, [sp, #Aba]
+ vstr.64 d1, [sp, #Aga]
+ veor.64 q0, q0, q1
+ vstr.64 d2, [sp, #Aka]
+ veor.64 d5, d0, d1
+ vstr.64 d3, [sp, #Ama]
+ vstr.64 d4, [sp, #Asa]
+ veor.64 d5, d5, d4
+
+ bl KeccakF_armv7a_neon_asm
+
+ subs r3, #18 @ nlanes -= 18
+ vpop.64 { d0-d4 }
+
+ beq .Ldone
+
+ b .Lfull_block_18
+
+.Lfull_block_17:
+
+ @ SHA3-256 & SHAKE256
+
+ cmp r3, #17 @ nlanes < blocklanes
+ blo .Llanes_loop
+
+ sub sp,sp, #5*8
+
+ vld1.64 {d5-d8}, [r2]!
+ veor d0, d5
+ vld1.64 {d9-d11}, [r2]!
+ veor d12, d6
+ veor d17, d7
+ veor d22, d8
+ vld1.64 {d5-d8}, [r2]!
+ veor d27, d9
+
+ veor d1, d10
+ veor d13, d11
+ vld1.64 {d9-d11}, [r2]!
+ veor d18, d5
+ veor d23, d6
+ veor d28, d7
+
+ veor d2, d8
+ vld1.64 {d5-d7}, [r2]!
+ veor d14, d9
+ veor d19, d10
+ veor d24, d11
+ veor d29, d5
+
+ veor d3, d6
+ veor d15, d7
+
+ vstr.64 d0, [sp, #Aba]
+ vstr.64 d1, [sp, #Aga]
+ veor.64 q0, q0, q1
+ vstr.64 d2, [sp, #Aka]
+ veor.64 d5, d0, d1
+ vstr.64 d3, [sp, #Ama]
+ vstr.64 d4, [sp, #Asa]
+ veor.64 d5, d5, d4
+
+ bl KeccakF_armv7a_neon_asm
+
+ subs r3, #17 @ nlanes -= 17
+ vpop.64 { d0-d4 }
+
+ beq .Ldone
+
+ b .Lfull_block_17
+
+.Lfull_block_13:
+
+ @ SHA3-384
+
+ cmp r3, #13 @ nlanes < blocklanes
+ blo .Llanes_loop
+
+ sub sp,sp, #5*8
+
+ vld1.64 {d5-d8}, [r2]!
+ veor d0, d5
+ vld1.64 {d9-d11}, [r2]!
+ veor d12, d6
+ veor d17, d7
+ veor d22, d8
+ vld1.64 {d5-d8}, [r2]!
+ veor d27, d9
+
+ veor d1, d10
+ veor d13, d11
+ vld1.64 {d9-d10}, [r2]!
+ veor d18, d5
+ veor d23, d6
+ veor d28, d7
+
+ veor d2, d8
+ veor d14, d9
+ veor d19, d10
+
+ vstr.64 d0, [sp, #Aba]
+ vstr.64 d1, [sp, #Aga]
+ veor.64 q0, q0, q1
+ vstr.64 d2, [sp, #Aka]
+ veor.64 d5, d0, d1
+ vstr.64 d3, [sp, #Ama]
+ vstr.64 d4, [sp, #Asa]
+ veor.64 d5, d5, d4
+
+ bl KeccakF_armv7a_neon_asm
+
+ subs r3, #13 @ nlanes -= 13
+ vpop.64 { d0-d4 }
+
+ beq .Ldone
+
+ b .Lfull_block_13
+
+.Lfull_block_9:
+
+ @ SHA3-512
+
+ cmp r3, #9 @ nlanes < blocklanes
+ blo .Llanes_loop
+
+ sub sp,sp, #5*8
+
+ vld1.64 {d5-d8}, [r2]!
+ veor d0, d5
+ vld1.64 {d9-d11}, [r2]!
+ veor d12, d6
+ veor d17, d7
+ veor d22, d8
+ vld1.64 {d5-d6}, [r2]!
+ veor d27, d9
+
+ veor d1, d10
+ veor d13, d11
+ veor d18, d5
+ veor d23, d6
+
+ vstr.64 d0, [sp, #Aba]
+ vstr.64 d1, [sp, #Aga]
+ veor.64 q0, q0, q1
+ vstr.64 d2, [sp, #Aka]
+ veor.64 d5, d0, d1
+ vstr.64 d3, [sp, #Ama]
+ vstr.64 d4, [sp, #Asa]
+ veor.64 d5, d5, d4
+
+ bl KeccakF_armv7a_neon_asm
+
+ subs r3, #9 @ nlanes -= 9
+ vpop.64 { d0-d4 }
+
+ beq .Ldone
+
+ b .Lfull_block_9
+
+.Llanes_loop:
+
+ @ per-lane mode
+
+ @ switch (pos)
+ ldrb r0, [pc, r1]
+ add pc, pc, r0, lsl #2
+.Lswitch_table:
+ .byte (.Llane0-.Lswitch_table-4)/4
+ .byte (.Llane1-.Lswitch_table-4)/4
+ .byte (.Llane2-.Lswitch_table-4)/4
+ .byte (.Llane3-.Lswitch_table-4)/4
+ .byte (.Llane4-.Lswitch_table-4)/4
+ .byte (.Llane5-.Lswitch_table-4)/4
+ .byte (.Llane6-.Lswitch_table-4)/4
+ .byte (.Llane7-.Lswitch_table-4)/4
+ .byte (.Llane8-.Lswitch_table-4)/4
+ .byte (.Llane9-.Lswitch_table-4)/4
+ .byte (.Llane10-.Lswitch_table-4)/4
+ .byte (.Llane11-.Lswitch_table-4)/4
+ .byte (.Llane12-.Lswitch_table-4)/4
+ .byte (.Llane13-.Lswitch_table-4)/4
+ .byte (.Llane14-.Lswitch_table-4)/4
+ .byte (.Llane15-.Lswitch_table-4)/4
+ .byte (.Llane16-.Lswitch_table-4)/4
+ .byte (.Llane17-.Lswitch_table-4)/4
+ .byte (.Llane18-.Lswitch_table-4)/4
+ .byte (.Llane19-.Lswitch_table-4)/4
+ .byte (.Llane20-.Lswitch_table-4)/4
+ .byte (.Llane21-.Lswitch_table-4)/4
+ .byte (.Llane22-.Lswitch_table-4)/4
+ .byte (.Llane23-.Lswitch_table-4)/4
+ .byte (.Llane24-.Lswitch_table-4)/4
+.p2align 2
+
+#define ABSORB_LANE(label, vreg) \
+ label: \
+ add r1, #1; \
+ vld1.64 d5, [r2]!; \
+ cmp r1, r5; /* pos == blocklanes */ \
+ veor vreg, vreg, d5; \
+ beq .Llanes_permute; \
+ subs r3, #1; \
+ beq .Ldone;
+
+ ABSORB_LANE(.Llane0, d0)
+ ABSORB_LANE(.Llane1, d12)
+ ABSORB_LANE(.Llane2, d17)
+ ABSORB_LANE(.Llane3, d22)
+ ABSORB_LANE(.Llane4, d27)
+
+ ABSORB_LANE(.Llane5, d1)
+ ABSORB_LANE(.Llane6, d13)
+ ABSORB_LANE(.Llane7, d18)
+ ABSORB_LANE(.Llane8, d23)
+ ABSORB_LANE(.Llane9, d28)
+
+ ABSORB_LANE(.Llane10, d2)
+ ABSORB_LANE(.Llane11, d14)
+ ABSORB_LANE(.Llane12, d19)
+ ABSORB_LANE(.Llane13, d24)
+ ABSORB_LANE(.Llane14, d29)
+
+ ABSORB_LANE(.Llane15, d3)
+ ABSORB_LANE(.Llane16, d15)
+ ABSORB_LANE(.Llane17, d20)
+ ABSORB_LANE(.Llane18, d25)
+ ABSORB_LANE(.Llane19, d30)
+
+ ABSORB_LANE(.Llane20, d4)
+ ABSORB_LANE(.Llane21, d16)
+ ABSORB_LANE(.Llane22, d21)
+ ABSORB_LANE(.Llane23, d26)
+ ABSORB_LANE(.Llane24, d31)
+
+ b .Llanes_loop
+
+.Llanes_permute:
+
+ sub sp,sp, #5*8
+ vstr.64 d0, [sp, #Aba]
+ vstr.64 d1, [sp, #Aga]
+ veor.64 q0, q0, q1
+ vstr.64 d2, [sp, #Aka]
+ veor.64 d5, d0, d1
+ vstr.64 d3, [sp, #Ama]
+ vstr.64 d4, [sp, #Asa]
+ veor.64 d5, d5, d4
+
+ bl KeccakF_armv7a_neon_asm
+
+ mov r1, #0 @ pos <= 0
+ subs r3, #1
+
+ vpop.64 { d0-d4 }
+
+ beq .Ldone
+
+ b .Lmain_loop_pos0
+
+.Ldone:
+
+ @ save state
+ vstr.64 d0, [r4, #0*8]
+ vstr.64 d12, [r4, #1*8]
+ vstr.64 d17, [r4, #2*8]
+ vstr.64 d22, [r4, #3*8]
+ vstr.64 d27, [r4, #4*8]
+
+ vstr.64 d1, [r4, #5*8]
+ vstr.64 d13, [r4, #6*8]
+ vstr.64 d18, [r4, #7*8]
+ vstr.64 d23, [r4, #8*8]
+ vstr.64 d28, [r4, #9*8]
+
+ vstr.64 d2, [r4, #10*8]
+ vstr.64 d14, [r4, #11*8]
+ vstr.64 d19, [r4, #12*8]
+ vstr.64 d24, [r4, #13*8]
+ vstr.64 d29, [r4, #14*8]
+
+ vstr.64 d3, [r4, #15*8]
+ vstr.64 d15, [r4, #16*8]
+ vstr.64 d20, [r4, #17*8]
+ vstr.64 d25, [r4, #18*8]
+ vstr.64 d30, [r4, #19*8]
+
+ vstr.64 d4, [r4, #20*8]
+ vstr.64 d16, [r4, #21*8]
+ vstr.64 d21, [r4, #22*8]
+ vstr.64 d26, [r4, #23*8]
+ vstr.64 d31, [r4, #24*8]
+
+ mov r0, #120
+ vpop {q4-q7}
+.Lout:
+ pop {r4-r5, ip, pc}
+.p2align 2
+.ltorg
+.size _gcry_keccak_absorb_lanes64_armv7_neon,.-_gcry_keccak_absorb_lanes64_armv7_neon;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/keccak.c b/comm/third_party/libgcrypt/cipher/keccak.c
new file mode 100644
index 0000000000..795a02e5b9
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/keccak.c
@@ -0,0 +1,1577 @@
+/* keccak.c - SHA3 hash functions
+ * Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <config.h>
+#include <string.h>
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+
+/* USE_64BIT indicates whether to use 64-bit generic implementation.
+ * USE_32BIT indicates whether to use 32-bit generic implementation. */
+#undef USE_64BIT
+#if defined(__x86_64__) || SIZEOF_UNSIGNED_LONG == 8
+# define USE_64BIT 1
+#else
+# define USE_32BIT 1
+#endif
+
+
+/* USE_64BIT_BMI2 indicates whether to compile with 64-bit Intel BMI2 code. */
+#undef USE_64BIT_BMI2
+#if defined(USE_64BIT) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+ defined(HAVE_CPU_ARCH_X86)
+# define USE_64BIT_BMI2 1
+#endif
+
+
+/* USE_64BIT_SHLD indicates whether to compile with 64-bit Intel SHLD code. */
+#undef USE_64BIT_SHLD
+#if defined(USE_64BIT) && defined (__GNUC__) && defined(__x86_64__) && \
+ defined(HAVE_CPU_ARCH_X86)
+# define USE_64BIT_SHLD 1
+#endif
+
+
+/* USE_32BIT_BMI2 indicates whether to compile with 32-bit Intel BMI2 code. */
+#undef USE_32BIT_BMI2
+#if defined(USE_32BIT) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+ defined(HAVE_CPU_ARCH_X86)
+# define USE_32BIT_BMI2 1
+#endif
+
+
+/* USE_64BIT_ARM_NEON indicates whether to enable 64-bit ARM/NEON assembly
+ * code. */
+#undef USE_64BIT_ARM_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_64BIT_ARM_NEON 1
+# endif
+#endif /*ENABLE_NEON_SUPPORT*/
+
+
+/* USE_S390X_CRYPTO indicates whether to enable zSeries code. */
+#undef USE_S390X_CRYPTO
+#if defined(HAVE_GCC_INLINE_ASM_S390X)
+# define USE_S390X_CRYPTO 1
+#endif /* USE_S390X_CRYPTO */
+
+
+#if defined(USE_64BIT) || defined(USE_64BIT_ARM_NEON)
+# define NEED_COMMON64 1
+#endif
+
+#ifdef USE_32BIT
+# define NEED_COMMON32BI 1
+#endif
+
+
+#define SHA3_DELIMITED_SUFFIX 0x06
+#define SHAKE_DELIMITED_SUFFIX 0x1F
+
+
+typedef struct
+{
+ union {
+#ifdef NEED_COMMON64
+ u64 state64[25];
+#endif
+#ifdef NEED_COMMON32BI
+ u32 state32bi[50];
+#endif
+ } u;
+} KECCAK_STATE;
+
+
+typedef struct
+{
+ unsigned int (*permute)(KECCAK_STATE *hd);
+ unsigned int (*absorb)(KECCAK_STATE *hd, int pos, const byte *lanes,
+ unsigned int nlanes, int blocklanes);
+ unsigned int (*extract) (KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+ unsigned int outlen);
+} keccak_ops_t;
+
+
+typedef struct KECCAK_CONTEXT_S
+{
+ KECCAK_STATE state;
+ unsigned int outlen;
+ unsigned int blocksize;
+ unsigned int count;
+ unsigned int suffix;
+ const keccak_ops_t *ops;
+#ifdef USE_S390X_CRYPTO
+ unsigned int kimd_func;
+ unsigned int buf_pos;
+ byte buf[1344 / 8]; /* SHAKE128 requires biggest buffer, 1344 bits. */
+#endif
+} KECCAK_CONTEXT;
+
+
+
+#ifdef NEED_COMMON64
+
+const u64 _gcry_keccak_round_consts_64bit[24 + 1] =
+{
+ U64_C(0x0000000000000001), U64_C(0x0000000000008082),
+ U64_C(0x800000000000808A), U64_C(0x8000000080008000),
+ U64_C(0x000000000000808B), U64_C(0x0000000080000001),
+ U64_C(0x8000000080008081), U64_C(0x8000000000008009),
+ U64_C(0x000000000000008A), U64_C(0x0000000000000088),
+ U64_C(0x0000000080008009), U64_C(0x000000008000000A),
+ U64_C(0x000000008000808B), U64_C(0x800000000000008B),
+ U64_C(0x8000000000008089), U64_C(0x8000000000008003),
+ U64_C(0x8000000000008002), U64_C(0x8000000000000080),
+ U64_C(0x000000000000800A), U64_C(0x800000008000000A),
+ U64_C(0x8000000080008081), U64_C(0x8000000000008080),
+ U64_C(0x0000000080000001), U64_C(0x8000000080008008),
+ U64_C(0xFFFFFFFFFFFFFFFF)
+};
+
+static unsigned int
+keccak_extract64(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+ unsigned int outlen)
+{
+ unsigned int i;
+
+ /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+ for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
+ {
+ u64 tmp = hd->u.state64[i];
+ buf_put_le64(outbuf, tmp);
+ outbuf += 8;
+ }
+
+ return 0;
+}
+
+#endif /* NEED_COMMON64 */
+
+
+#ifdef NEED_COMMON32BI
+
+static const u32 round_consts_32bit[2 * 24] =
+{
+ 0x00000001UL, 0x00000000UL, 0x00000000UL, 0x00000089UL,
+ 0x00000000UL, 0x8000008bUL, 0x00000000UL, 0x80008080UL,
+ 0x00000001UL, 0x0000008bUL, 0x00000001UL, 0x00008000UL,
+ 0x00000001UL, 0x80008088UL, 0x00000001UL, 0x80000082UL,
+ 0x00000000UL, 0x0000000bUL, 0x00000000UL, 0x0000000aUL,
+ 0x00000001UL, 0x00008082UL, 0x00000000UL, 0x00008003UL,
+ 0x00000001UL, 0x0000808bUL, 0x00000001UL, 0x8000000bUL,
+ 0x00000001UL, 0x8000008aUL, 0x00000001UL, 0x80000081UL,
+ 0x00000000UL, 0x80000081UL, 0x00000000UL, 0x80000008UL,
+ 0x00000000UL, 0x00000083UL, 0x00000000UL, 0x80008003UL,
+ 0x00000001UL, 0x80008088UL, 0x00000000UL, 0x80000088UL,
+ 0x00000001UL, 0x00008000UL, 0x00000000UL, 0x80008082UL
+};
+
+static unsigned int
+keccak_extract32bi(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+ unsigned int outlen)
+{
+ unsigned int i;
+ u32 x0;
+ u32 x1;
+ u32 t;
+
+ /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+ for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
+ {
+ x0 = hd->u.state32bi[i * 2 + 0];
+ x1 = hd->u.state32bi[i * 2 + 1];
+
+ t = (x0 & 0x0000FFFFUL) + (x1 << 16);
+ x1 = (x0 >> 16) + (x1 & 0xFFFF0000UL);
+ x0 = t;
+ t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8);
+ t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4);
+ t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2);
+ t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1);
+ t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8);
+ t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4);
+ t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
+ t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
+
+ buf_put_le32(&outbuf[0], x0);
+ buf_put_le32(&outbuf[4], x1);
+ outbuf += 8;
+ }
+
+ return 0;
+}
+
+static inline void
+keccak_absorb_lane32bi(u32 *lane, u32 x0, u32 x1)
+{
+ u32 t;
+
+ t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1);
+ t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2);
+ t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4);
+ t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8);
+ t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
+ t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
+ t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4);
+ t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8);
+ lane[0] ^= (x0 & 0x0000FFFFUL) + (x1 << 16);
+ lane[1] ^= (x0 >> 16) + (x1 & 0xFFFF0000UL);
+}
+
+#endif /* NEED_COMMON32BI */
+
+
+/* Construct generic 64-bit implementation. */
+#ifdef USE_64BIT
+
+#if __GNUC__ >= 4 && defined(__x86_64__)
+
+static inline void absorb_lanes64_8(u64 *dst, const byte *in)
+{
+ asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
+ "movdqu 0*16(%[in]), %%xmm4\n\t"
+ "movdqu 1*16(%[dst]), %%xmm1\n\t"
+ "movdqu 1*16(%[in]), %%xmm5\n\t"
+ "movdqu 2*16(%[dst]), %%xmm2\n\t"
+ "movdqu 3*16(%[dst]), %%xmm3\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+ "pxor %%xmm5, %%xmm1\n\t"
+ "movdqu 2*16(%[in]), %%xmm4\n\t"
+ "movdqu 3*16(%[in]), %%xmm5\n\t"
+ "movdqu %%xmm0, 0*16(%[dst])\n\t"
+ "pxor %%xmm4, %%xmm2\n\t"
+ "movdqu %%xmm1, 1*16(%[dst])\n\t"
+ "pxor %%xmm5, %%xmm3\n\t"
+ "movdqu %%xmm2, 2*16(%[dst])\n\t"
+ "movdqu %%xmm3, 3*16(%[dst])\n\t"
+ :
+ : [dst] "r" (dst), [in] "r" (in)
+ : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "memory");
+}
+
+static inline void absorb_lanes64_4(u64 *dst, const byte *in)
+{
+ asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
+ "movdqu 0*16(%[in]), %%xmm4\n\t"
+ "movdqu 1*16(%[dst]), %%xmm1\n\t"
+ "movdqu 1*16(%[in]), %%xmm5\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+ "pxor %%xmm5, %%xmm1\n\t"
+ "movdqu %%xmm0, 0*16(%[dst])\n\t"
+ "movdqu %%xmm1, 1*16(%[dst])\n\t"
+ :
+ : [dst] "r" (dst), [in] "r" (in)
+ : "xmm0", "xmm1", "xmm4", "xmm5", "memory");
+}
+
+static inline void absorb_lanes64_2(u64 *dst, const byte *in)
+{
+ asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
+ "movdqu 0*16(%[in]), %%xmm4\n\t"
+ "pxor %%xmm4, %%xmm0\n\t"
+ "movdqu %%xmm0, 0*16(%[dst])\n\t"
+ :
+ : [dst] "r" (dst), [in] "r" (in)
+ : "xmm0", "xmm4", "memory");
+}
+
+#else /* __x86_64__ */
+
+static inline void absorb_lanes64_8(u64 *dst, const byte *in)
+{
+ dst[0] ^= buf_get_le64(in + 8 * 0);
+ dst[1] ^= buf_get_le64(in + 8 * 1);
+ dst[2] ^= buf_get_le64(in + 8 * 2);
+ dst[3] ^= buf_get_le64(in + 8 * 3);
+ dst[4] ^= buf_get_le64(in + 8 * 4);
+ dst[5] ^= buf_get_le64(in + 8 * 5);
+ dst[6] ^= buf_get_le64(in + 8 * 6);
+ dst[7] ^= buf_get_le64(in + 8 * 7);
+}
+
+static inline void absorb_lanes64_4(u64 *dst, const byte *in)
+{
+ dst[0] ^= buf_get_le64(in + 8 * 0);
+ dst[1] ^= buf_get_le64(in + 8 * 1);
+ dst[2] ^= buf_get_le64(in + 8 * 2);
+ dst[3] ^= buf_get_le64(in + 8 * 3);
+}
+
+static inline void absorb_lanes64_2(u64 *dst, const byte *in)
+{
+ dst[0] ^= buf_get_le64(in + 8 * 0);
+ dst[1] ^= buf_get_le64(in + 8 * 1);
+}
+
+#endif /* !__x86_64__ */
+
+static inline void absorb_lanes64_1(u64 *dst, const byte *in)
+{
+ dst[0] ^= buf_get_le64(in + 8 * 0);
+}
+
+
+# define ANDN64(x, y) (~(x) & (y))
+# define ROL64(x, n) (((x) << ((unsigned int)n & 63)) | \
+ ((x) >> ((64 - (unsigned int)(n)) & 63)))
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64
+# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64
+# include "keccak_permute_64.h"
+
+# undef ANDN64
+# undef ROL64
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+# undef KECCAK_F1600_ABSORB_FUNC_NAME
+
+static const keccak_ops_t keccak_generic64_ops =
+{
+ .permute = keccak_f1600_state_permute64,
+ .absorb = keccak_absorb_lanes64,
+ .extract = keccak_extract64,
+};
+
+#endif /* USE_64BIT */
+
+
+/* Construct 64-bit Intel SHLD implementation. */
+#ifdef USE_64BIT_SHLD
+
+# define ANDN64(x, y) (~(x) & (y))
+# define ROL64(x, n) ({ \
+ u64 tmp = (x); \
+ asm ("shldq %1, %0, %0" \
+ : "+r" (tmp) \
+ : "J" ((n) & 63) \
+ : "cc"); \
+ tmp; })
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_shld
+# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_shld
+# include "keccak_permute_64.h"
+
+# undef ANDN64
+# undef ROL64
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+# undef KECCAK_F1600_ABSORB_FUNC_NAME
+
+static const keccak_ops_t keccak_shld_64_ops =
+{
+ .permute = keccak_f1600_state_permute64_shld,
+ .absorb = keccak_absorb_lanes64_shld,
+ .extract = keccak_extract64,
+};
+
+#endif /* USE_64BIT_SHLD */
+
+
+/* Construct 64-bit Intel BMI2 implementation. */
+#ifdef USE_64BIT_BMI2
+
+# define ANDN64(x, y) ({ \
+ u64 tmp; \
+ asm ("andnq %2, %1, %0" \
+ : "=r" (tmp) \
+ : "r0" (x), "rm" (y)); \
+ tmp; })
+
+# define ROL64(x, n) ({ \
+ u64 tmp; \
+ asm ("rorxq %2, %1, %0" \
+ : "=r" (tmp) \
+ : "rm0" (x), "J" (64 - ((n) & 63))); \
+ tmp; })
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_bmi2
+# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_bmi2
+# include "keccak_permute_64.h"
+
+# undef ANDN64
+# undef ROL64
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+# undef KECCAK_F1600_ABSORB_FUNC_NAME
+
+static const keccak_ops_t keccak_bmi2_64_ops =
+{
+ .permute = keccak_f1600_state_permute64_bmi2,
+ .absorb = keccak_absorb_lanes64_bmi2,
+ .extract = keccak_extract64,
+};
+
+#endif /* USE_64BIT_BMI2 */
+
+
+/* 64-bit ARMv7/NEON implementation. */
+#ifdef USE_64BIT_ARM_NEON
+
+unsigned int _gcry_keccak_permute_armv7_neon(u64 *state);
+unsigned int _gcry_keccak_absorb_lanes64_armv7_neon(u64 *state, int pos,
+ const byte *lanes,
+ unsigned int nlanes,
+ int blocklanes);
+
+static unsigned int keccak_permute64_armv7_neon(KECCAK_STATE *hd)
+{
+ return _gcry_keccak_permute_armv7_neon(hd->u.state64);
+}
+
+static unsigned int
+keccak_absorb_lanes64_armv7_neon(KECCAK_STATE *hd, int pos, const byte *lanes,
+ unsigned int nlanes, int blocklanes)
+{
+ if (blocklanes < 0)
+ {
+ /* blocklanes == -1, permutationless absorb from keccak_final. */
+
+ while (nlanes)
+ {
+ hd->u.state64[pos] ^= buf_get_le64(lanes);
+ lanes += 8;
+ nlanes--;
+ }
+
+ return 0;
+ }
+ else
+ {
+ return _gcry_keccak_absorb_lanes64_armv7_neon(hd->u.state64, pos, lanes,
+ nlanes, blocklanes);
+ }
+}
+
+static const keccak_ops_t keccak_armv7_neon_64_ops =
+{
+ .permute = keccak_permute64_armv7_neon,
+ .absorb = keccak_absorb_lanes64_armv7_neon,
+ .extract = keccak_extract64,
+};
+
+#endif /* USE_64BIT_ARM_NEON */
+
+
+/* Construct generic 32-bit implementation. */
+#ifdef USE_32BIT
+
+# define ANDN32(x, y) (~(x) & (y))
+# define ROL32(x, n) (((x) << ((unsigned int)n & 31)) | \
+ ((x) >> ((32 - (unsigned int)(n)) & 31)))
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute32bi
+# include "keccak_permute_32.h"
+
+# undef ANDN32
+# undef ROL32
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+
+static unsigned int
+keccak_absorb_lanes32bi(KECCAK_STATE *hd, int pos, const byte *lanes,
+ unsigned int nlanes, int blocklanes)
+{
+ unsigned int burn = 0;
+
+ while (nlanes)
+ {
+ keccak_absorb_lane32bi(&hd->u.state32bi[pos * 2],
+ buf_get_le32(lanes + 0),
+ buf_get_le32(lanes + 4));
+ lanes += 8;
+ nlanes--;
+
+ if (++pos == blocklanes)
+ {
+ burn = keccak_f1600_state_permute32bi(hd);
+ pos = 0;
+ }
+ }
+
+ return burn;
+}
+
+static const keccak_ops_t keccak_generic32bi_ops =
+{
+ .permute = keccak_f1600_state_permute32bi,
+ .absorb = keccak_absorb_lanes32bi,
+ .extract = keccak_extract32bi,
+};
+
+#endif /* USE_32BIT */
+
+
+/* Construct 32-bit Intel BMI2 implementation. */
+#ifdef USE_32BIT_BMI2
+
+# define ANDN32(x, y) ({ \
+ u32 tmp; \
+ asm ("andnl %2, %1, %0" \
+ : "=r" (tmp) \
+ : "r0" (x), "rm" (y)); \
+ tmp; })
+
+# define ROL32(x, n) ({ \
+ u32 tmp; \
+ asm ("rorxl %2, %1, %0" \
+ : "=r" (tmp) \
+ : "rm0" (x), "J" (32 - ((n) & 31))); \
+ tmp; })
+
+# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute32bi_bmi2
+# include "keccak_permute_32.h"
+
+# undef ANDN32
+# undef ROL32
+# undef KECCAK_F1600_PERMUTE_FUNC_NAME
+
+static inline u32 pext(u32 x, u32 mask)
+{
+ u32 tmp;
+ asm ("pextl %2, %1, %0" : "=r" (tmp) : "r0" (x), "rm" (mask));
+ return tmp;
+}
+
+static inline u32 pdep(u32 x, u32 mask)
+{
+ u32 tmp;
+ asm ("pdepl %2, %1, %0" : "=r" (tmp) : "r0" (x), "rm" (mask));
+ return tmp;
+}
+
+static inline void
+keccak_absorb_lane32bi_bmi2(u32 *lane, u32 x0, u32 x1)
+{
+ x0 = pdep(pext(x0, 0x55555555), 0x0000ffff) | (pext(x0, 0xaaaaaaaa) << 16);
+ x1 = pdep(pext(x1, 0x55555555), 0x0000ffff) | (pext(x1, 0xaaaaaaaa) << 16);
+
+ lane[0] ^= (x0 & 0x0000FFFFUL) + (x1 << 16);
+ lane[1] ^= (x0 >> 16) + (x1 & 0xFFFF0000UL);
+}
+
+static unsigned int
+keccak_absorb_lanes32bi_bmi2(KECCAK_STATE *hd, int pos, const byte *lanes,
+ unsigned int nlanes, int blocklanes)
+{
+ unsigned int burn = 0;
+
+ while (nlanes)
+ {
+ keccak_absorb_lane32bi_bmi2(&hd->u.state32bi[pos * 2],
+ buf_get_le32(lanes + 0),
+ buf_get_le32(lanes + 4));
+ lanes += 8;
+ nlanes--;
+
+ if (++pos == blocklanes)
+ {
+ burn = keccak_f1600_state_permute32bi_bmi2(hd);
+ pos = 0;
+ }
+ }
+
+ return burn;
+}
+
+static unsigned int
+keccak_extract32bi_bmi2(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+ unsigned int outlen)
+{
+ unsigned int i;
+ u32 x0;
+ u32 x1;
+ u32 t;
+
+ /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+ for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
+ {
+ x0 = hd->u.state32bi[i * 2 + 0];
+ x1 = hd->u.state32bi[i * 2 + 1];
+
+ t = (x0 & 0x0000FFFFUL) + (x1 << 16);
+ x1 = (x0 >> 16) + (x1 & 0xFFFF0000UL);
+ x0 = t;
+
+ x0 = pdep(pext(x0, 0xffff0001), 0xaaaaaaab) | pdep(x0 >> 1, 0x55555554);
+ x1 = pdep(pext(x1, 0xffff0001), 0xaaaaaaab) | pdep(x1 >> 1, 0x55555554);
+
+ buf_put_le32(&outbuf[0], x0);
+ buf_put_le32(&outbuf[4], x1);
+ outbuf += 8;
+ }
+
+ return 0;
+}
+
+static const keccak_ops_t keccak_bmi2_32bi_ops =
+{
+ .permute = keccak_f1600_state_permute32bi_bmi2,
+ .absorb = keccak_absorb_lanes32bi_bmi2,
+ .extract = keccak_extract32bi_bmi2,
+};
+
+#endif /* USE_32BIT_BMI2 */
+
+
+#ifdef USE_S390X_CRYPTO
+#include "asm-inline-s390x.h"
+
+static inline void
+keccak_bwrite_s390x (void *context, const byte *in, size_t inlen)
+{
+ KECCAK_CONTEXT *ctx = context;
+
+ /* Write full-blocks. */
+ kimd_execute (ctx->kimd_func, &ctx->state, in, inlen);
+ return;
+}
+
+static inline void
+keccak_final_s390x (void *context)
+{
+ KECCAK_CONTEXT *ctx = context;
+
+ if (ctx->suffix == SHA3_DELIMITED_SUFFIX)
+ {
+ klmd_execute (ctx->kimd_func, &ctx->state, ctx->buf, ctx->count);
+ }
+ else
+ {
+ klmd_shake_execute (ctx->kimd_func, &ctx->state, NULL, 0, ctx->buf,
+ ctx->count);
+ ctx->count = 0;
+ ctx->buf_pos = 0;
+ }
+
+ return;
+}
+
+static inline void
+keccak_bextract_s390x (void *context, byte *out, size_t outlen)
+{
+ KECCAK_CONTEXT *ctx = context;
+
+ /* Extract full-blocks. */
+ klmd_shake_execute (ctx->kimd_func | KLMD_PADDING_STATE, &ctx->state,
+ out, outlen, NULL, 0);
+ return;
+}
+
+static void
+keccak_write_s390x (void *context, const byte *inbuf, size_t inlen)
+{
+ KECCAK_CONTEXT *hd = context;
+ const size_t blocksize = hd->blocksize;
+ size_t inblocks;
+ size_t copylen;
+
+ while (hd->count)
+ {
+ if (hd->count == blocksize) /* Flush the buffer. */
+ {
+ keccak_bwrite_s390x (hd, hd->buf, blocksize);
+ hd->count = 0;
+ }
+ else
+ {
+ copylen = inlen;
+ if (copylen > blocksize - hd->count)
+ copylen = blocksize - hd->count;
+
+ if (copylen == 0)
+ break;
+
+ buf_cpy (&hd->buf[hd->count], inbuf, copylen);
+ hd->count += copylen;
+ inbuf += copylen;
+ inlen -= copylen;
+ }
+ }
+
+ if (inlen == 0)
+ return;
+
+ if (inlen >= blocksize)
+ {
+ inblocks = inlen / blocksize;
+ keccak_bwrite_s390x (hd, inbuf, inblocks * blocksize);
+ hd->count = 0;
+ inlen -= inblocks * blocksize;
+ inbuf += inblocks * blocksize;
+ }
+
+ if (inlen)
+ {
+ buf_cpy (hd->buf, inbuf, inlen);
+ hd->count = inlen;
+ }
+}
+
+static void
+keccak_extract_s390x (void *context, void *outbuf_arg, size_t outlen)
+{
+ KECCAK_CONTEXT *hd = context;
+ const size_t blocksize = hd->blocksize;
+ byte *outbuf = outbuf_arg;
+
+ while (outlen)
+ {
+ gcry_assert(hd->count == 0 || hd->buf_pos < hd->count);
+
+ if (hd->buf_pos < hd->count && outlen)
+ {
+ size_t copylen = hd->count - hd->buf_pos;
+
+ if (copylen > outlen)
+ copylen = outlen;
+
+ buf_cpy (outbuf, &hd->buf[hd->buf_pos], copylen);
+
+ outbuf += copylen;
+ outlen -= copylen;
+ hd->buf_pos += copylen;
+ }
+
+ if (hd->buf_pos == hd->count)
+ {
+ hd->buf_pos = 0;
+ hd->count = 0;
+ }
+
+ if (outlen == 0)
+ return;
+
+ if (outlen >= blocksize)
+ {
+ size_t outblocks = outlen / blocksize;
+
+ keccak_bextract_s390x (context, outbuf, outblocks * blocksize);
+
+ outlen -= outblocks * blocksize;
+ outbuf += outblocks * blocksize;
+
+ if (outlen == 0)
+ return;
+ }
+
+ keccak_bextract_s390x (context, hd->buf, blocksize);
+ hd->count = blocksize;
+ }
+}
+#endif /* USE_S390X_CRYPTO */
+
+
+static void
+keccak_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+ KECCAK_CONTEXT *ctx = context;
+ const size_t bsize = ctx->blocksize;
+ const size_t blocklanes = bsize / 8;
+ const byte *inbuf = inbuf_arg;
+ unsigned int nburn, burn = 0;
+ unsigned int count, i;
+ unsigned int pos, nlanes;
+
+#ifdef USE_S390X_CRYPTO
+ if (ctx->kimd_func)
+ {
+ keccak_write_s390x (context, inbuf, inlen);
+ return;
+ }
+#endif
+
+ count = ctx->count;
+
+ if (inlen && (count % 8))
+ {
+ byte lane[8] = { 0, };
+
+ /* Complete absorbing partial input lane. */
+
+ pos = count / 8;
+
+ for (i = count % 8; inlen && i < 8; i++)
+ {
+ lane[i] = *inbuf++;
+ inlen--;
+ count++;
+ }
+
+ if (count == bsize)
+ count = 0;
+
+ nburn = ctx->ops->absorb(&ctx->state, pos, lane, 1,
+ (count % 8) ? -1 : blocklanes);
+ burn = nburn > burn ? nburn : burn;
+ }
+
+ /* Absorb full input lanes. */
+
+ pos = count / 8;
+ nlanes = inlen / 8;
+ if (nlanes > 0)
+ {
+ nburn = ctx->ops->absorb(&ctx->state, pos, inbuf, nlanes, blocklanes);
+ burn = nburn > burn ? nburn : burn;
+ inlen -= nlanes * 8;
+ inbuf += nlanes * 8;
+ count += nlanes * 8;
+ count = count % bsize;
+ }
+
+ if (inlen)
+ {
+ byte lane[8] = { 0, };
+
+ /* Absorb remaining partial input lane. */
+
+ pos = count / 8;
+
+ for (i = count % 8; inlen && i < 8; i++)
+ {
+ lane[i] = *inbuf++;
+ inlen--;
+ count++;
+ }
+
+ nburn = ctx->ops->absorb(&ctx->state, pos, lane, 1, -1);
+ burn = nburn > burn ? nburn : burn;
+
+ gcry_assert(count < bsize);
+ }
+
+ ctx->count = count;
+
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+
+static void
+keccak_init (int algo, void *context, unsigned int flags)
+{
+ KECCAK_CONTEXT *ctx = context;
+ KECCAK_STATE *hd = &ctx->state;
+ unsigned int features = _gcry_get_hw_features ();
+
+ (void)flags;
+ (void)features;
+
+ memset (hd, 0, sizeof *hd);
+
+ ctx->count = 0;
+
+ /* Select generic implementation. */
+#ifdef USE_64BIT
+ ctx->ops = &keccak_generic64_ops;
+#elif defined USE_32BIT
+ ctx->ops = &keccak_generic32bi_ops;
+#endif
+
+ /* Select optimized implementation based in hw features. */
+ if (0) {}
+#ifdef USE_64BIT_ARM_NEON
+ else if (features & HWF_ARM_NEON)
+ ctx->ops = &keccak_armv7_neon_64_ops;
+#endif
+#ifdef USE_64BIT_BMI2
+ else if (features & HWF_INTEL_BMI2)
+ ctx->ops = &keccak_bmi2_64_ops;
+#endif
+#ifdef USE_32BIT_BMI2
+ else if (features & HWF_INTEL_BMI2)
+ ctx->ops = &keccak_bmi2_32bi_ops;
+#endif
+#ifdef USE_64BIT_SHLD
+ else if (features & HWF_INTEL_FAST_SHLD)
+ ctx->ops = &keccak_shld_64_ops;
+#endif
+
+ /* Set input block size, in Keccak terms this is called 'rate'. */
+
+ switch (algo)
+ {
+ case GCRY_MD_SHA3_224:
+ ctx->suffix = SHA3_DELIMITED_SUFFIX;
+ ctx->blocksize = 1152 / 8;
+ ctx->outlen = 224 / 8;
+ break;
+ case GCRY_MD_SHA3_256:
+ ctx->suffix = SHA3_DELIMITED_SUFFIX;
+ ctx->blocksize = 1088 / 8;
+ ctx->outlen = 256 / 8;
+ break;
+ case GCRY_MD_SHA3_384:
+ ctx->suffix = SHA3_DELIMITED_SUFFIX;
+ ctx->blocksize = 832 / 8;
+ ctx->outlen = 384 / 8;
+ break;
+ case GCRY_MD_SHA3_512:
+ ctx->suffix = SHA3_DELIMITED_SUFFIX;
+ ctx->blocksize = 576 / 8;
+ ctx->outlen = 512 / 8;
+ break;
+ case GCRY_MD_SHAKE128:
+ ctx->suffix = SHAKE_DELIMITED_SUFFIX;
+ ctx->blocksize = 1344 / 8;
+ ctx->outlen = 0;
+ break;
+ case GCRY_MD_SHAKE256:
+ ctx->suffix = SHAKE_DELIMITED_SUFFIX;
+ ctx->blocksize = 1088 / 8;
+ ctx->outlen = 0;
+ break;
+ default:
+ BUG();
+ }
+
+#ifdef USE_S390X_CRYPTO
+ ctx->kimd_func = 0;
+ if ((features & HWF_S390X_MSA) != 0)
+ {
+ unsigned int kimd_func = 0;
+
+ switch (algo)
+ {
+ case GCRY_MD_SHA3_224:
+ kimd_func = KMID_FUNCTION_SHA3_224;
+ break;
+ case GCRY_MD_SHA3_256:
+ kimd_func = KMID_FUNCTION_SHA3_256;
+ break;
+ case GCRY_MD_SHA3_384:
+ kimd_func = KMID_FUNCTION_SHA3_384;
+ break;
+ case GCRY_MD_SHA3_512:
+ kimd_func = KMID_FUNCTION_SHA3_512;
+ break;
+ case GCRY_MD_SHAKE128:
+ kimd_func = KMID_FUNCTION_SHAKE128;
+ break;
+ case GCRY_MD_SHAKE256:
+ kimd_func = KMID_FUNCTION_SHAKE256;
+ break;
+ }
+
+ if ((kimd_query () & km_function_to_mask (kimd_func)) &&
+ (klmd_query () & km_function_to_mask (kimd_func)))
+ {
+ ctx->kimd_func = kimd_func;
+ }
+ }
+#endif
+}
+
+static void
+sha3_224_init (void *context, unsigned int flags)
+{
+ keccak_init (GCRY_MD_SHA3_224, context, flags);
+}
+
+static void
+sha3_256_init (void *context, unsigned int flags)
+{
+ keccak_init (GCRY_MD_SHA3_256, context, flags);
+}
+
+static void
+sha3_384_init (void *context, unsigned int flags)
+{
+ keccak_init (GCRY_MD_SHA3_384, context, flags);
+}
+
+static void
+sha3_512_init (void *context, unsigned int flags)
+{
+ keccak_init (GCRY_MD_SHA3_512, context, flags);
+}
+
+static void
+shake128_init (void *context, unsigned int flags)
+{
+ keccak_init (GCRY_MD_SHAKE128, context, flags);
+}
+
+static void
+shake256_init (void *context, unsigned int flags)
+{
+ keccak_init (GCRY_MD_SHAKE256, context, flags);
+}
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 64 bytes representing the digest. When used for sha384,
+ * we take the leftmost 48 of those bytes.
+ */
+static void
+keccak_final (void *context)
+{
+ KECCAK_CONTEXT *ctx = context;
+ KECCAK_STATE *hd = &ctx->state;
+ const size_t bsize = ctx->blocksize;
+ const byte suffix = ctx->suffix;
+ unsigned int nburn, burn = 0;
+ unsigned int lastbytes;
+ byte lane[8];
+
+#ifdef USE_S390X_CRYPTO
+ if (ctx->kimd_func)
+ {
+ keccak_final_s390x (context);
+ return;
+ }
+#endif
+
+ lastbytes = ctx->count;
+
+ /* Do the padding and switch to the squeezing phase */
+
+ /* Absorb the last few bits and add the first bit of padding (which
+ coincides with the delimiter in delimited suffix) */
+ buf_put_le64(lane, (u64)suffix << ((lastbytes % 8) * 8));
+ nburn = ctx->ops->absorb(&ctx->state, lastbytes / 8, lane, 1, -1);
+ burn = nburn > burn ? nburn : burn;
+
+ /* Add the second bit of padding. */
+ buf_put_le64(lane, (u64)0x80 << (((bsize - 1) % 8) * 8));
+ nburn = ctx->ops->absorb(&ctx->state, (bsize - 1) / 8, lane, 1, -1);
+ burn = nburn > burn ? nburn : burn;
+
+ if (suffix == SHA3_DELIMITED_SUFFIX)
+ {
+ /* Switch to the squeezing phase. */
+ nburn = ctx->ops->permute(hd);
+ burn = nburn > burn ? nburn : burn;
+
+ /* Squeeze out the SHA3 digest. */
+ nburn = ctx->ops->extract(hd, 0, (void *)hd, ctx->outlen);
+ burn = nburn > burn ? nburn : burn;
+ }
+ else
+ {
+ /* Output for SHAKE can now be read with md_extract(). */
+
+ ctx->count = 0;
+ }
+
+ wipememory(lane, sizeof(lane));
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+
+static byte *
+keccak_read (void *context)
+{
+ KECCAK_CONTEXT *ctx = (KECCAK_CONTEXT *) context;
+ KECCAK_STATE *hd = &ctx->state;
+ return (byte *)&hd->u;
+}
+
+
+static void
+keccak_extract (void *context, void *out, size_t outlen)
+{
+ KECCAK_CONTEXT *ctx = context;
+ KECCAK_STATE *hd = &ctx->state;
+ const size_t bsize = ctx->blocksize;
+ unsigned int nburn, burn = 0;
+ byte *outbuf = out;
+ unsigned int nlanes;
+ unsigned int nleft;
+ unsigned int count;
+ unsigned int i;
+ byte lane[8];
+
+#ifdef USE_S390X_CRYPTO
+ if (ctx->kimd_func)
+ {
+ keccak_extract_s390x (context, out, outlen);
+ return;
+ }
+#endif
+
+ count = ctx->count;
+
+ while (count && outlen && (outlen < 8 || count % 8))
+ {
+ /* Extract partial lane. */
+ nburn = ctx->ops->extract(hd, count / 8, lane, 8);
+ burn = nburn > burn ? nburn : burn;
+
+ for (i = count % 8; outlen && i < 8; i++)
+ {
+ *outbuf++ = lane[i];
+ outlen--;
+ count++;
+ }
+
+ gcry_assert(count <= bsize);
+
+ if (count == bsize)
+ count = 0;
+ }
+
+ if (outlen >= 8 && count)
+ {
+ /* Extract tail of partial block. */
+ nlanes = outlen / 8;
+ nleft = (bsize - count) / 8;
+ nlanes = nlanes < nleft ? nlanes : nleft;
+
+ nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
+ burn = nburn > burn ? nburn : burn;
+ outlen -= nlanes * 8;
+ outbuf += nlanes * 8;
+ count += nlanes * 8;
+
+ gcry_assert(count <= bsize);
+
+ if (count == bsize)
+ count = 0;
+ }
+
+ while (outlen >= bsize)
+ {
+ gcry_assert(count == 0);
+
+ /* Squeeze more. */
+ nburn = ctx->ops->permute(hd);
+ burn = nburn > burn ? nburn : burn;
+
+ /* Extract full block. */
+ nburn = ctx->ops->extract(hd, 0, outbuf, bsize);
+ burn = nburn > burn ? nburn : burn;
+
+ outlen -= bsize;
+ outbuf += bsize;
+ }
+
+ if (outlen)
+ {
+ gcry_assert(outlen < bsize);
+
+ if (count == 0)
+ {
+ /* Squeeze more. */
+ nburn = ctx->ops->permute(hd);
+ burn = nburn > burn ? nburn : burn;
+ }
+
+ if (outlen >= 8)
+ {
+ /* Extract head of partial block. */
+ nlanes = outlen / 8;
+ nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
+ burn = nburn > burn ? nburn : burn;
+ outlen -= nlanes * 8;
+ outbuf += nlanes * 8;
+ count += nlanes * 8;
+
+ gcry_assert(count < bsize);
+ }
+
+ if (outlen)
+ {
+ /* Extract head of partial lane. */
+ nburn = ctx->ops->extract(hd, count / 8, lane, 8);
+ burn = nburn > burn ? nburn : burn;
+
+ for (i = count % 8; outlen && i < 8; i++)
+ {
+ *outbuf++ = lane[i];
+ outlen--;
+ count++;
+ }
+
+ gcry_assert(count < bsize);
+ }
+ }
+
+ ctx->count = count;
+
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 'spec->mdlen' bytes. */
+static void
+_gcry_sha3_hash_buffer (void *outbuf, const void *buffer, size_t length,
+ const gcry_md_spec_t *spec)
+{
+ KECCAK_CONTEXT hd;
+
+ spec->init (&hd, 0);
+ keccak_write (&hd, buffer, length);
+ keccak_final (&hd);
+ memcpy (outbuf, keccak_read (&hd), spec->mdlen);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers. */
+static void
+_gcry_sha3_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt,
+ const gcry_md_spec_t *spec)
+{
+ KECCAK_CONTEXT hd;
+
+ spec->init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ keccak_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len);
+ keccak_final (&hd);
+ memcpy (outbuf, keccak_read (&hd), spec->mdlen);
+}
+
+
+static void
+_gcry_sha3_224_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ _gcry_sha3_hash_buffer (outbuf, buffer, length, &_gcry_digest_spec_sha3_224);
+}
+
+static void
+_gcry_sha3_256_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ _gcry_sha3_hash_buffer (outbuf, buffer, length, &_gcry_digest_spec_sha3_256);
+}
+
+static void
+_gcry_sha3_384_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ _gcry_sha3_hash_buffer (outbuf, buffer, length, &_gcry_digest_spec_sha3_384);
+}
+
+static void
+_gcry_sha3_512_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ _gcry_sha3_hash_buffer (outbuf, buffer, length, &_gcry_digest_spec_sha3_512);
+}
+
+static void
+_gcry_sha3_224_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+ int iovcnt)
+{
+ _gcry_sha3_hash_buffers (outbuf, iov, iovcnt, &_gcry_digest_spec_sha3_224);
+}
+
+static void
+_gcry_sha3_256_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+ int iovcnt)
+{
+ _gcry_sha3_hash_buffers (outbuf, iov, iovcnt, &_gcry_digest_spec_sha3_256);
+}
+
+static void
+_gcry_sha3_384_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+ int iovcnt)
+{
+ _gcry_sha3_hash_buffers (outbuf, iov, iovcnt, &_gcry_digest_spec_sha3_384);
+}
+
+static void
+_gcry_sha3_512_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+ int iovcnt)
+{
+ _gcry_sha3_hash_buffers (outbuf, iov, iovcnt, &_gcry_digest_spec_sha3_512);
+}
+
+
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_keccak (int algo, int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+ const char *short_hash;
+ const char *long_hash;
+ const char *one_million_a_hash;
+ int hash_len;
+
+ switch (algo)
+ {
+ default:
+ BUG();
+
+ case GCRY_MD_SHA3_224:
+ short_hash =
+ "\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";
+ long_hash =
+ "\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";
+ one_million_a_hash =
+ "\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";
+ hash_len = 28;
+ break;
+
+ case GCRY_MD_SHA3_256:
+ short_hash =
+ "\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";
+ long_hash =
+ "\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";
+ one_million_a_hash =
+ "\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";
+ hash_len = 32;
+ break;
+
+ case GCRY_MD_SHA3_384:
+ short_hash =
+ "\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";
+ long_hash =
+ "\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";
+ one_million_a_hash =
+ "\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";
+ hash_len = 48;
+ break;
+
+ case GCRY_MD_SHA3_512:
+ short_hash =
+ "\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";
+ long_hash =
+ "\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";
+ one_million_a_hash =
+ "\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";
+ hash_len = 64;
+ break;
+
+ case GCRY_MD_SHAKE128:
+ short_hash =
+ "\x58\x81\x09\x2d\xd8\x18\xbf\x5c\xf8\xa3\xdd\xb7\x93\xfb\xcb\xa7"
+ "\x40\x97\xd5\xc5\x26\xa6\xd3\x5f\x97\xb8\x33\x51\x94\x0f\x2c\xc8";
+ long_hash =
+ "\x7b\x6d\xf6\xff\x18\x11\x73\xb6\xd7\x89\x8d\x7f\xf6\x3f\xb0\x7b"
+ "\x7c\x23\x7d\xaf\x47\x1a\x5a\xe5\x60\x2a\xdb\xcc\xef\x9c\xcf\x4b";
+ one_million_a_hash =
+ "\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";
+ hash_len = 32;
+ break;
+
+ case GCRY_MD_SHAKE256:
+ short_hash =
+ "\x48\x33\x66\x60\x13\x60\xa8\x77\x1c\x68\x63\x08\x0c\xc4\x11\x4d"
+ "\x8d\xb4\x45\x30\xf8\xf1\xe1\xee\x4f\x94\xea\x37\xe7\x8b\x57\x39";
+ long_hash =
+ "\x98\xbe\x04\x51\x6c\x04\xcc\x73\x59\x3f\xef\x3e\xd0\x35\x2e\xa9"
+ "\xf6\x44\x39\x42\xd6\x95\x0e\x29\xa3\x72\xa6\x81\xc3\xde\xaf\x45";
+ one_million_a_hash =
+ "\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";
+ hash_len = 32;
+ break;
+ }
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one (algo, 0, "abc", 3, short_hash,
+ hash_len);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (algo, 0,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ long_hash, hash_len);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one (algo, 1, NULL, 0,
+ one_million_a_hash, hash_len);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+failed:
+ if (report)
+ report ("digest", algo, 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_MD_SHA3_224:
+ case GCRY_MD_SHA3_256:
+ case GCRY_MD_SHA3_384:
+ case GCRY_MD_SHA3_512:
+ case GCRY_MD_SHAKE128:
+ case GCRY_MD_SHAKE256:
+ ec = selftests_keccak (algo, extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+ }
+
+ return ec;
+}
+
+
+
+
+static byte sha3_224_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_sha3_224[] =
+ {
+ { "2.16.840.1.101.3.4.2.7" },
+ /* PKCS#1 sha3_224WithRSAEncryption */
+ { "?" },
+ { NULL }
+ };
+static byte sha3_256_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_sha3_256[] =
+ {
+ { "2.16.840.1.101.3.4.2.8" },
+ /* PKCS#1 sha3_256WithRSAEncryption */
+ { "?" },
+ { NULL }
+ };
+static byte sha3_384_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_sha3_384[] =
+ {
+ { "2.16.840.1.101.3.4.2.9" },
+ /* PKCS#1 sha3_384WithRSAEncryption */
+ { "?" },
+ { NULL }
+ };
+static byte sha3_512_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_sha3_512[] =
+ {
+ { "2.16.840.1.101.3.4.2.10" },
+ /* PKCS#1 sha3_512WithRSAEncryption */
+ { "?" },
+ { NULL }
+ };
+static byte shake128_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_shake128[] =
+ {
+ { "2.16.840.1.101.3.4.2.11" },
+ /* PKCS#1 shake128WithRSAEncryption */
+ { "?" },
+ { NULL }
+ };
+static byte shake256_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_shake256[] =
+ {
+ { "2.16.840.1.101.3.4.2.12" },
+ /* PKCS#1 shake256WithRSAEncryption */
+ { "?" },
+ { NULL }
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha3_224 =
+ {
+ GCRY_MD_SHA3_224, {0, 1},
+ "SHA3-224", sha3_224_asn, DIM (sha3_224_asn), oid_spec_sha3_224, 28,
+ sha3_224_init, keccak_write, keccak_final, keccak_read, NULL,
+ _gcry_sha3_224_hash_buffer, _gcry_sha3_224_hash_buffers,
+ sizeof (KECCAK_CONTEXT),
+ run_selftests
+ };
+gcry_md_spec_t _gcry_digest_spec_sha3_256 =
+ {
+ GCRY_MD_SHA3_256, {0, 1},
+ "SHA3-256", sha3_256_asn, DIM (sha3_256_asn), oid_spec_sha3_256, 32,
+ sha3_256_init, keccak_write, keccak_final, keccak_read, NULL,
+ _gcry_sha3_256_hash_buffer, _gcry_sha3_256_hash_buffers,
+ sizeof (KECCAK_CONTEXT),
+ run_selftests
+ };
+gcry_md_spec_t _gcry_digest_spec_sha3_384 =
+ {
+ GCRY_MD_SHA3_384, {0, 1},
+ "SHA3-384", sha3_384_asn, DIM (sha3_384_asn), oid_spec_sha3_384, 48,
+ sha3_384_init, keccak_write, keccak_final, keccak_read, NULL,
+ _gcry_sha3_384_hash_buffer, _gcry_sha3_384_hash_buffers,
+ sizeof (KECCAK_CONTEXT),
+ run_selftests
+ };
+gcry_md_spec_t _gcry_digest_spec_sha3_512 =
+ {
+ GCRY_MD_SHA3_512, {0, 1},
+ "SHA3-512", sha3_512_asn, DIM (sha3_512_asn), oid_spec_sha3_512, 64,
+ sha3_512_init, keccak_write, keccak_final, keccak_read, NULL,
+ _gcry_sha3_512_hash_buffer, _gcry_sha3_512_hash_buffers,
+ sizeof (KECCAK_CONTEXT),
+ run_selftests
+ };
+gcry_md_spec_t _gcry_digest_spec_shake128 =
+ {
+ GCRY_MD_SHAKE128, {0, 1},
+ "SHAKE128", shake128_asn, DIM (shake128_asn), oid_spec_shake128, 0,
+ shake128_init, keccak_write, keccak_final, NULL, keccak_extract,
+ NULL, NULL,
+ sizeof (KECCAK_CONTEXT),
+ run_selftests
+ };
+gcry_md_spec_t _gcry_digest_spec_shake256 =
+ {
+ GCRY_MD_SHAKE256, {0, 1},
+ "SHAKE256", shake256_asn, DIM (shake256_asn), oid_spec_shake256, 0,
+ shake256_init, keccak_write, keccak_final, NULL, keccak_extract,
+ NULL, NULL,
+ sizeof (KECCAK_CONTEXT),
+ run_selftests
+ };
diff --git a/comm/third_party/libgcrypt/cipher/keccak_permute_32.h b/comm/third_party/libgcrypt/cipher/keccak_permute_32.h
new file mode 100644
index 0000000000..1ce42a42fc
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/keccak_permute_32.h
@@ -0,0 +1,536 @@
+/* keccak_permute_32.h - Keccak permute function (simple 32bit bit-interleaved)
+ * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain/CC0 "keccakc1024/simple32bi/
+ * Keccak-simple32BI.c" implementation by Ronny Van Keer from SUPERCOP toolkit
+ * package.
+ */
+
+/* Function that computes the Keccak-f[1600] permutation on the given state. */
+static unsigned int
+KECCAK_F1600_PERMUTE_FUNC_NAME(KECCAK_STATE *hd)
+{
+ const u32 *round_consts = round_consts_32bit;
+ const u32 *round_consts_end = round_consts_32bit + 2 * 24;
+ u32 Aba0, Abe0, Abi0, Abo0, Abu0;
+ u32 Aba1, Abe1, Abi1, Abo1, Abu1;
+ u32 Aga0, Age0, Agi0, Ago0, Agu0;
+ u32 Aga1, Age1, Agi1, Ago1, Agu1;
+ u32 Aka0, Ake0, Aki0, Ako0, Aku0;
+ u32 Aka1, Ake1, Aki1, Ako1, Aku1;
+ u32 Ama0, Ame0, Ami0, Amo0, Amu0;
+ u32 Ama1, Ame1, Ami1, Amo1, Amu1;
+ u32 Asa0, Ase0, Asi0, Aso0, Asu0;
+ u32 Asa1, Ase1, Asi1, Aso1, Asu1;
+ u32 BCa0, BCe0, BCi0, BCo0, BCu0;
+ u32 BCa1, BCe1, BCi1, BCo1, BCu1;
+ u32 Da0, De0, Di0, Do0, Du0;
+ u32 Da1, De1, Di1, Do1, Du1;
+ u32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0;
+ u32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1;
+ u32 Ega0, Ege0, Egi0, Ego0, Egu0;
+ u32 Ega1, Ege1, Egi1, Ego1, Egu1;
+ u32 Eka0, Eke0, Eki0, Eko0, Eku0;
+ u32 Eka1, Eke1, Eki1, Eko1, Eku1;
+ u32 Ema0, Eme0, Emi0, Emo0, Emu0;
+ u32 Ema1, Eme1, Emi1, Emo1, Emu1;
+ u32 Esa0, Ese0, Esi0, Eso0, Esu0;
+ u32 Esa1, Ese1, Esi1, Eso1, Esu1;
+ u32 *state = hd->u.state32bi;
+
+ Aba0 = state[0];
+ Aba1 = state[1];
+ Abe0 = state[2];
+ Abe1 = state[3];
+ Abi0 = state[4];
+ Abi1 = state[5];
+ Abo0 = state[6];
+ Abo1 = state[7];
+ Abu0 = state[8];
+ Abu1 = state[9];
+ Aga0 = state[10];
+ Aga1 = state[11];
+ Age0 = state[12];
+ Age1 = state[13];
+ Agi0 = state[14];
+ Agi1 = state[15];
+ Ago0 = state[16];
+ Ago1 = state[17];
+ Agu0 = state[18];
+ Agu1 = state[19];
+ Aka0 = state[20];
+ Aka1 = state[21];
+ Ake0 = state[22];
+ Ake1 = state[23];
+ Aki0 = state[24];
+ Aki1 = state[25];
+ Ako0 = state[26];
+ Ako1 = state[27];
+ Aku0 = state[28];
+ Aku1 = state[29];
+ Ama0 = state[30];
+ Ama1 = state[31];
+ Ame0 = state[32];
+ Ame1 = state[33];
+ Ami0 = state[34];
+ Ami1 = state[35];
+ Amo0 = state[36];
+ Amo1 = state[37];
+ Amu0 = state[38];
+ Amu1 = state[39];
+ Asa0 = state[40];
+ Asa1 = state[41];
+ Ase0 = state[42];
+ Ase1 = state[43];
+ Asi0 = state[44];
+ Asi1 = state[45];
+ Aso0 = state[46];
+ Aso1 = state[47];
+ Asu0 = state[48];
+ Asu1 = state[49];
+
+ do
+ {
+ /* prepareTheta */
+ BCa0 = Aba0 ^ Aga0 ^ Aka0 ^ Ama0 ^ Asa0;
+ BCa1 = Aba1 ^ Aga1 ^ Aka1 ^ Ama1 ^ Asa1;
+ BCe0 = Abe0 ^ Age0 ^ Ake0 ^ Ame0 ^ Ase0;
+ BCe1 = Abe1 ^ Age1 ^ Ake1 ^ Ame1 ^ Ase1;
+ BCi0 = Abi0 ^ Agi0 ^ Aki0 ^ Ami0 ^ Asi0;
+ BCi1 = Abi1 ^ Agi1 ^ Aki1 ^ Ami1 ^ Asi1;
+ BCo0 = Abo0 ^ Ago0 ^ Ako0 ^ Amo0 ^ Aso0;
+ BCo1 = Abo1 ^ Ago1 ^ Ako1 ^ Amo1 ^ Aso1;
+ BCu0 = Abu0 ^ Agu0 ^ Aku0 ^ Amu0 ^ Asu0;
+ BCu1 = Abu1 ^ Agu1 ^ Aku1 ^ Amu1 ^ Asu1;
+
+ /* thetaRhoPiChiIota(round , A, E) */
+ Da0 = BCu0 ^ ROL32(BCe1, 1);
+ Da1 = BCu1 ^ BCe0;
+ De0 = BCa0 ^ ROL32(BCi1, 1);
+ De1 = BCa1 ^ BCi0;
+ Di0 = BCe0 ^ ROL32(BCo1, 1);
+ Di1 = BCe1 ^ BCo0;
+ Do0 = BCi0 ^ ROL32(BCu1, 1);
+ Do1 = BCi1 ^ BCu0;
+ Du0 = BCo0 ^ ROL32(BCa1, 1);
+ Du1 = BCo1 ^ BCa0;
+
+ Aba0 ^= Da0;
+ BCa0 = Aba0;
+ Age0 ^= De0;
+ BCe0 = ROL32(Age0, 22);
+ Aki1 ^= Di1;
+ BCi0 = ROL32(Aki1, 22);
+ Amo1 ^= Do1;
+ BCo0 = ROL32(Amo1, 11);
+ Asu0 ^= Du0;
+ BCu0 = ROL32(Asu0, 7);
+ Eba0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Eba0 ^= *(round_consts++);
+ Ebe0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Ebi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Ebo0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Ebu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Aba1 ^= Da1;
+ BCa1 = Aba1;
+ Age1 ^= De1;
+ BCe1 = ROL32(Age1, 22);
+ Aki0 ^= Di0;
+ BCi1 = ROL32(Aki0, 21);
+ Amo0 ^= Do0;
+ BCo1 = ROL32(Amo0, 10);
+ Asu1 ^= Du1;
+ BCu1 = ROL32(Asu1, 7);
+ Eba1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Eba1 ^= *(round_consts++);
+ Ebe1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Ebi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Ebo1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Ebu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ Abo0 ^= Do0;
+ BCa0 = ROL32(Abo0, 14);
+ Agu0 ^= Du0;
+ BCe0 = ROL32(Agu0, 10);
+ Aka1 ^= Da1;
+ BCi0 = ROL32(Aka1, 2);
+ Ame1 ^= De1;
+ BCo0 = ROL32(Ame1, 23);
+ Asi1 ^= Di1;
+ BCu0 = ROL32(Asi1, 31);
+ Ega0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Ege0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Egi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Ego0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Egu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Abo1 ^= Do1;
+ BCa1 = ROL32(Abo1, 14);
+ Agu1 ^= Du1;
+ BCe1 = ROL32(Agu1, 10);
+ Aka0 ^= Da0;
+ BCi1 = ROL32(Aka0, 1);
+ Ame0 ^= De0;
+ BCo1 = ROL32(Ame0, 22);
+ Asi0 ^= Di0;
+ BCu1 = ROL32(Asi0, 30);
+ Ega1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Ege1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Egi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Ego1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Egu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ Abe1 ^= De1;
+ BCa0 = ROL32(Abe1, 1);
+ Agi0 ^= Di0;
+ BCe0 = ROL32(Agi0, 3);
+ Ako1 ^= Do1;
+ BCi0 = ROL32(Ako1, 13);
+ Amu0 ^= Du0;
+ BCo0 = ROL32(Amu0, 4);
+ Asa0 ^= Da0;
+ BCu0 = ROL32(Asa0, 9);
+ Eka0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Eke0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Eki0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Eko0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Eku0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Abe0 ^= De0;
+ BCa1 = Abe0;
+ Agi1 ^= Di1;
+ BCe1 = ROL32(Agi1, 3);
+ Ako0 ^= Do0;
+ BCi1 = ROL32(Ako0, 12);
+ Amu1 ^= Du1;
+ BCo1 = ROL32(Amu1, 4);
+ Asa1 ^= Da1;
+ BCu1 = ROL32(Asa1, 9);
+ Eka1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Eke1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Eki1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Eko1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Eku1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ Abu1 ^= Du1;
+ BCa0 = ROL32(Abu1, 14);
+ Aga0 ^= Da0;
+ BCe0 = ROL32(Aga0, 18);
+ Ake0 ^= De0;
+ BCi0 = ROL32(Ake0, 5);
+ Ami1 ^= Di1;
+ BCo0 = ROL32(Ami1, 8);
+ Aso0 ^= Do0;
+ BCu0 = ROL32(Aso0, 28);
+ Ema0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Eme0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Emi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Emo0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Emu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Abu0 ^= Du0;
+ BCa1 = ROL32(Abu0, 13);
+ Aga1 ^= Da1;
+ BCe1 = ROL32(Aga1, 18);
+ Ake1 ^= De1;
+ BCi1 = ROL32(Ake1, 5);
+ Ami0 ^= Di0;
+ BCo1 = ROL32(Ami0, 7);
+ Aso1 ^= Do1;
+ BCu1 = ROL32(Aso1, 28);
+ Ema1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Eme1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Emi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Emo1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Emu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ Abi0 ^= Di0;
+ BCa0 = ROL32(Abi0, 31);
+ Ago1 ^= Do1;
+ BCe0 = ROL32(Ago1, 28);
+ Aku1 ^= Du1;
+ BCi0 = ROL32(Aku1, 20);
+ Ama1 ^= Da1;
+ BCo0 = ROL32(Ama1, 21);
+ Ase0 ^= De0;
+ BCu0 = ROL32(Ase0, 1);
+ Esa0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Ese0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Esi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Eso0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Esu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Abi1 ^= Di1;
+ BCa1 = ROL32(Abi1, 31);
+ Ago0 ^= Do0;
+ BCe1 = ROL32(Ago0, 27);
+ Aku0 ^= Du0;
+ BCi1 = ROL32(Aku0, 19);
+ Ama0 ^= Da0;
+ BCo1 = ROL32(Ama0, 20);
+ Ase1 ^= De1;
+ BCu1 = ROL32(Ase1, 1);
+ Esa1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Ese1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Esi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Eso1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Esu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ /* prepareTheta */
+ BCa0 = Eba0 ^ Ega0 ^ Eka0 ^ Ema0 ^ Esa0;
+ BCa1 = Eba1 ^ Ega1 ^ Eka1 ^ Ema1 ^ Esa1;
+ BCe0 = Ebe0 ^ Ege0 ^ Eke0 ^ Eme0 ^ Ese0;
+ BCe1 = Ebe1 ^ Ege1 ^ Eke1 ^ Eme1 ^ Ese1;
+ BCi0 = Ebi0 ^ Egi0 ^ Eki0 ^ Emi0 ^ Esi0;
+ BCi1 = Ebi1 ^ Egi1 ^ Eki1 ^ Emi1 ^ Esi1;
+ BCo0 = Ebo0 ^ Ego0 ^ Eko0 ^ Emo0 ^ Eso0;
+ BCo1 = Ebo1 ^ Ego1 ^ Eko1 ^ Emo1 ^ Eso1;
+ BCu0 = Ebu0 ^ Egu0 ^ Eku0 ^ Emu0 ^ Esu0;
+ BCu1 = Ebu1 ^ Egu1 ^ Eku1 ^ Emu1 ^ Esu1;
+
+ /* thetaRhoPiChiIota(round+1, E, A) */
+ Da0 = BCu0 ^ ROL32(BCe1, 1);
+ Da1 = BCu1 ^ BCe0;
+ De0 = BCa0 ^ ROL32(BCi1, 1);
+ De1 = BCa1 ^ BCi0;
+ Di0 = BCe0 ^ ROL32(BCo1, 1);
+ Di1 = BCe1 ^ BCo0;
+ Do0 = BCi0 ^ ROL32(BCu1, 1);
+ Do1 = BCi1 ^ BCu0;
+ Du0 = BCo0 ^ ROL32(BCa1, 1);
+ Du1 = BCo1 ^ BCa0;
+
+ Eba0 ^= Da0;
+ BCa0 = Eba0;
+ Ege0 ^= De0;
+ BCe0 = ROL32(Ege0, 22);
+ Eki1 ^= Di1;
+ BCi0 = ROL32(Eki1, 22);
+ Emo1 ^= Do1;
+ BCo0 = ROL32(Emo1, 11);
+ Esu0 ^= Du0;
+ BCu0 = ROL32(Esu0, 7);
+ Aba0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Aba0 ^= *(round_consts++);
+ Abe0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Abi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Abo0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Abu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Eba1 ^= Da1;
+ BCa1 = Eba1;
+ Ege1 ^= De1;
+ BCe1 = ROL32(Ege1, 22);
+ Eki0 ^= Di0;
+ BCi1 = ROL32(Eki0, 21);
+ Emo0 ^= Do0;
+ BCo1 = ROL32(Emo0, 10);
+ Esu1 ^= Du1;
+ BCu1 = ROL32(Esu1, 7);
+ Aba1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Aba1 ^= *(round_consts++);
+ Abe1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Abi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Abo1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Abu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ Ebo0 ^= Do0;
+ BCa0 = ROL32(Ebo0, 14);
+ Egu0 ^= Du0;
+ BCe0 = ROL32(Egu0, 10);
+ Eka1 ^= Da1;
+ BCi0 = ROL32(Eka1, 2);
+ Eme1 ^= De1;
+ BCo0 = ROL32(Eme1, 23);
+ Esi1 ^= Di1;
+ BCu0 = ROL32(Esi1, 31);
+ Aga0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Age0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Agi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Ago0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Agu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Ebo1 ^= Do1;
+ BCa1 = ROL32(Ebo1, 14);
+ Egu1 ^= Du1;
+ BCe1 = ROL32(Egu1, 10);
+ Eka0 ^= Da0;
+ BCi1 = ROL32(Eka0, 1);
+ Eme0 ^= De0;
+ BCo1 = ROL32(Eme0, 22);
+ Esi0 ^= Di0;
+ BCu1 = ROL32(Esi0, 30);
+ Aga1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Age1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Agi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Ago1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Agu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ Ebe1 ^= De1;
+ BCa0 = ROL32(Ebe1, 1);
+ Egi0 ^= Di0;
+ BCe0 = ROL32(Egi0, 3);
+ Eko1 ^= Do1;
+ BCi0 = ROL32(Eko1, 13);
+ Emu0 ^= Du0;
+ BCo0 = ROL32(Emu0, 4);
+ Esa0 ^= Da0;
+ BCu0 = ROL32(Esa0, 9);
+ Aka0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Ake0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Aki0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Ako0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Aku0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Ebe0 ^= De0;
+ BCa1 = Ebe0;
+ Egi1 ^= Di1;
+ BCe1 = ROL32(Egi1, 3);
+ Eko0 ^= Do0;
+ BCi1 = ROL32(Eko0, 12);
+ Emu1 ^= Du1;
+ BCo1 = ROL32(Emu1, 4);
+ Esa1 ^= Da1;
+ BCu1 = ROL32(Esa1, 9);
+ Aka1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Ake1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Aki1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Ako1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Aku1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ Ebu1 ^= Du1;
+ BCa0 = ROL32(Ebu1, 14);
+ Ega0 ^= Da0;
+ BCe0 = ROL32(Ega0, 18);
+ Eke0 ^= De0;
+ BCi0 = ROL32(Eke0, 5);
+ Emi1 ^= Di1;
+ BCo0 = ROL32(Emi1, 8);
+ Eso0 ^= Do0;
+ BCu0 = ROL32(Eso0, 28);
+ Ama0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Ame0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Ami0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Amo0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Amu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Ebu0 ^= Du0;
+ BCa1 = ROL32(Ebu0, 13);
+ Ega1 ^= Da1;
+ BCe1 = ROL32(Ega1, 18);
+ Eke1 ^= De1;
+ BCi1 = ROL32(Eke1, 5);
+ Emi0 ^= Di0;
+ BCo1 = ROL32(Emi0, 7);
+ Eso1 ^= Do1;
+ BCu1 = ROL32(Eso1, 28);
+ Ama1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Ame1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Ami1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Amo1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Amu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+
+ Ebi0 ^= Di0;
+ BCa0 = ROL32(Ebi0, 31);
+ Ego1 ^= Do1;
+ BCe0 = ROL32(Ego1, 28);
+ Eku1 ^= Du1;
+ BCi0 = ROL32(Eku1, 20);
+ Ema1 ^= Da1;
+ BCo0 = ROL32(Ema1, 21);
+ Ese0 ^= De0;
+ BCu0 = ROL32(Ese0, 1);
+ Asa0 = BCa0 ^ ANDN32(BCe0, BCi0);
+ Ase0 = BCe0 ^ ANDN32(BCi0, BCo0);
+ Asi0 = BCi0 ^ ANDN32(BCo0, BCu0);
+ Aso0 = BCo0 ^ ANDN32(BCu0, BCa0);
+ Asu0 = BCu0 ^ ANDN32(BCa0, BCe0);
+
+ Ebi1 ^= Di1;
+ BCa1 = ROL32(Ebi1, 31);
+ Ego0 ^= Do0;
+ BCe1 = ROL32(Ego0, 27);
+ Eku0 ^= Du0;
+ BCi1 = ROL32(Eku0, 19);
+ Ema0 ^= Da0;
+ BCo1 = ROL32(Ema0, 20);
+ Ese1 ^= De1;
+ BCu1 = ROL32(Ese1, 1);
+ Asa1 = BCa1 ^ ANDN32(BCe1, BCi1);
+ Ase1 = BCe1 ^ ANDN32(BCi1, BCo1);
+ Asi1 = BCi1 ^ ANDN32(BCo1, BCu1);
+ Aso1 = BCo1 ^ ANDN32(BCu1, BCa1);
+ Asu1 = BCu1 ^ ANDN32(BCa1, BCe1);
+ }
+ while (round_consts < round_consts_end);
+
+ state[0] = Aba0;
+ state[1] = Aba1;
+ state[2] = Abe0;
+ state[3] = Abe1;
+ state[4] = Abi0;
+ state[5] = Abi1;
+ state[6] = Abo0;
+ state[7] = Abo1;
+ state[8] = Abu0;
+ state[9] = Abu1;
+ state[10] = Aga0;
+ state[11] = Aga1;
+ state[12] = Age0;
+ state[13] = Age1;
+ state[14] = Agi0;
+ state[15] = Agi1;
+ state[16] = Ago0;
+ state[17] = Ago1;
+ state[18] = Agu0;
+ state[19] = Agu1;
+ state[20] = Aka0;
+ state[21] = Aka1;
+ state[22] = Ake0;
+ state[23] = Ake1;
+ state[24] = Aki0;
+ state[25] = Aki1;
+ state[26] = Ako0;
+ state[27] = Ako1;
+ state[28] = Aku0;
+ state[29] = Aku1;
+ state[30] = Ama0;
+ state[31] = Ama1;
+ state[32] = Ame0;
+ state[33] = Ame1;
+ state[34] = Ami0;
+ state[35] = Ami1;
+ state[36] = Amo0;
+ state[37] = Amo1;
+ state[38] = Amu0;
+ state[39] = Amu1;
+ state[40] = Asa0;
+ state[41] = Asa1;
+ state[42] = Ase0;
+ state[43] = Ase1;
+ state[44] = Asi0;
+ state[45] = Asi1;
+ state[46] = Aso0;
+ state[47] = Aso1;
+ state[48] = Asu0;
+ state[49] = Asu1;
+
+ return sizeof(void *) * 4 + sizeof(u32) * 12 * 5 * 2;
+}
diff --git a/comm/third_party/libgcrypt/cipher/keccak_permute_64.h b/comm/third_party/libgcrypt/cipher/keccak_permute_64.h
new file mode 100644
index 0000000000..b28c871ec1
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/keccak_permute_64.h
@@ -0,0 +1,385 @@
+/* keccak_permute_64.h - Keccak permute function (simple 64bit)
+ * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* The code is based on public-domain/CC0 "keccakc1024/simple/Keccak-simple.c"
+ * implementation by Ronny Van Keer from SUPERCOP toolkit package.
+ */
+
+/* Function that computes the Keccak-f[1600] permutation on the given state. */
+static unsigned int
+KECCAK_F1600_PERMUTE_FUNC_NAME(KECCAK_STATE *hd)
+{
+ const u64 *round_consts = _gcry_keccak_round_consts_64bit;
+ const u64 *round_consts_end = _gcry_keccak_round_consts_64bit + 24;
+ u64 Aba, Abe, Abi, Abo, Abu;
+ u64 Aga, Age, Agi, Ago, Agu;
+ u64 Aka, Ake, Aki, Ako, Aku;
+ u64 Ama, Ame, Ami, Amo, Amu;
+ u64 Asa, Ase, Asi, Aso, Asu;
+ u64 BCa, BCe, BCi, BCo, BCu;
+ u64 Da, De, Di, Do, Du;
+ u64 Eba, Ebe, Ebi, Ebo, Ebu;
+ u64 Ega, Ege, Egi, Ego, Egu;
+ u64 Eka, Eke, Eki, Eko, Eku;
+ u64 Ema, Eme, Emi, Emo, Emu;
+ u64 Esa, Ese, Esi, Eso, Esu;
+ u64 *state = hd->u.state64;
+
+ Aba = state[0];
+ Abe = state[1];
+ Abi = state[2];
+ Abo = state[3];
+ Abu = state[4];
+ Aga = state[5];
+ Age = state[6];
+ Agi = state[7];
+ Ago = state[8];
+ Agu = state[9];
+ Aka = state[10];
+ Ake = state[11];
+ Aki = state[12];
+ Ako = state[13];
+ Aku = state[14];
+ Ama = state[15];
+ Ame = state[16];
+ Ami = state[17];
+ Amo = state[18];
+ Amu = state[19];
+ Asa = state[20];
+ Ase = state[21];
+ Asi = state[22];
+ Aso = state[23];
+ Asu = state[24];
+
+ do
+ {
+ /* prepareTheta */
+ BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
+ BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
+ BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
+ BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
+ BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
+
+ /* thetaRhoPiChiIotaPrepareTheta(round , A, E) */
+ Da = BCu ^ ROL64(BCe, 1);
+ De = BCa ^ ROL64(BCi, 1);
+ Di = BCe ^ ROL64(BCo, 1);
+ Do = BCi ^ ROL64(BCu, 1);
+ Du = BCo ^ ROL64(BCa, 1);
+
+ Aba ^= Da;
+ BCa = Aba;
+ Age ^= De;
+ BCe = ROL64(Age, 44);
+ Aki ^= Di;
+ BCi = ROL64(Aki, 43);
+ Amo ^= Do;
+ BCo = ROL64(Amo, 21);
+ Asu ^= Du;
+ BCu = ROL64(Asu, 14);
+ Eba = BCa ^ ANDN64(BCe, BCi);
+ Eba ^= *(round_consts++);
+ Ebe = BCe ^ ANDN64(BCi, BCo);
+ Ebi = BCi ^ ANDN64(BCo, BCu);
+ Ebo = BCo ^ ANDN64(BCu, BCa);
+ Ebu = BCu ^ ANDN64(BCa, BCe);
+
+ Abo ^= Do;
+ BCa = ROL64(Abo, 28);
+ Agu ^= Du;
+ BCe = ROL64(Agu, 20);
+ Aka ^= Da;
+ BCi = ROL64(Aka, 3);
+ Ame ^= De;
+ BCo = ROL64(Ame, 45);
+ Asi ^= Di;
+ BCu = ROL64(Asi, 61);
+ Ega = BCa ^ ANDN64(BCe, BCi);
+ Ege = BCe ^ ANDN64(BCi, BCo);
+ Egi = BCi ^ ANDN64(BCo, BCu);
+ Ego = BCo ^ ANDN64(BCu, BCa);
+ Egu = BCu ^ ANDN64(BCa, BCe);
+
+ Abe ^= De;
+ BCa = ROL64(Abe, 1);
+ Agi ^= Di;
+ BCe = ROL64(Agi, 6);
+ Ako ^= Do;
+ BCi = ROL64(Ako, 25);
+ Amu ^= Du;
+ BCo = ROL64(Amu, 8);
+ Asa ^= Da;
+ BCu = ROL64(Asa, 18);
+ Eka = BCa ^ ANDN64(BCe, BCi);
+ Eke = BCe ^ ANDN64(BCi, BCo);
+ Eki = BCi ^ ANDN64(BCo, BCu);
+ Eko = BCo ^ ANDN64(BCu, BCa);
+ Eku = BCu ^ ANDN64(BCa, BCe);
+
+ Abu ^= Du;
+ BCa = ROL64(Abu, 27);
+ Aga ^= Da;
+ BCe = ROL64(Aga, 36);
+ Ake ^= De;
+ BCi = ROL64(Ake, 10);
+ Ami ^= Di;
+ BCo = ROL64(Ami, 15);
+ Aso ^= Do;
+ BCu = ROL64(Aso, 56);
+ Ema = BCa ^ ANDN64(BCe, BCi);
+ Eme = BCe ^ ANDN64(BCi, BCo);
+ Emi = BCi ^ ANDN64(BCo, BCu);
+ Emo = BCo ^ ANDN64(BCu, BCa);
+ Emu = BCu ^ ANDN64(BCa, BCe);
+
+ Abi ^= Di;
+ BCa = ROL64(Abi, 62);
+ Ago ^= Do;
+ BCe = ROL64(Ago, 55);
+ Aku ^= Du;
+ BCi = ROL64(Aku, 39);
+ Ama ^= Da;
+ BCo = ROL64(Ama, 41);
+ Ase ^= De;
+ BCu = ROL64(Ase, 2);
+ Esa = BCa ^ ANDN64(BCe, BCi);
+ Ese = BCe ^ ANDN64(BCi, BCo);
+ Esi = BCi ^ ANDN64(BCo, BCu);
+ Eso = BCo ^ ANDN64(BCu, BCa);
+ Esu = BCu ^ ANDN64(BCa, BCe);
+
+ /* prepareTheta */
+ BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
+ BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
+ BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
+ BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
+ BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
+
+ /* thetaRhoPiChiIotaPrepareTheta(round+1, E, A) */
+ Da = BCu ^ ROL64(BCe, 1);
+ De = BCa ^ ROL64(BCi, 1);
+ Di = BCe ^ ROL64(BCo, 1);
+ Do = BCi ^ ROL64(BCu, 1);
+ Du = BCo ^ ROL64(BCa, 1);
+
+ Eba ^= Da;
+ BCa = Eba;
+ Ege ^= De;
+ BCe = ROL64(Ege, 44);
+ Eki ^= Di;
+ BCi = ROL64(Eki, 43);
+ Emo ^= Do;
+ BCo = ROL64(Emo, 21);
+ Esu ^= Du;
+ BCu = ROL64(Esu, 14);
+ Aba = BCa ^ ANDN64(BCe, BCi);
+ Aba ^= *(round_consts++);
+ Abe = BCe ^ ANDN64(BCi, BCo);
+ Abi = BCi ^ ANDN64(BCo, BCu);
+ Abo = BCo ^ ANDN64(BCu, BCa);
+ Abu = BCu ^ ANDN64(BCa, BCe);
+
+ Ebo ^= Do;
+ BCa = ROL64(Ebo, 28);
+ Egu ^= Du;
+ BCe = ROL64(Egu, 20);
+ Eka ^= Da;
+ BCi = ROL64(Eka, 3);
+ Eme ^= De;
+ BCo = ROL64(Eme, 45);
+ Esi ^= Di;
+ BCu = ROL64(Esi, 61);
+ Aga = BCa ^ ANDN64(BCe, BCi);
+ Age = BCe ^ ANDN64(BCi, BCo);
+ Agi = BCi ^ ANDN64(BCo, BCu);
+ Ago = BCo ^ ANDN64(BCu, BCa);
+ Agu = BCu ^ ANDN64(BCa, BCe);
+
+ Ebe ^= De;
+ BCa = ROL64(Ebe, 1);
+ Egi ^= Di;
+ BCe = ROL64(Egi, 6);
+ Eko ^= Do;
+ BCi = ROL64(Eko, 25);
+ Emu ^= Du;
+ BCo = ROL64(Emu, 8);
+ Esa ^= Da;
+ BCu = ROL64(Esa, 18);
+ Aka = BCa ^ ANDN64(BCe, BCi);
+ Ake = BCe ^ ANDN64(BCi, BCo);
+ Aki = BCi ^ ANDN64(BCo, BCu);
+ Ako = BCo ^ ANDN64(BCu, BCa);
+ Aku = BCu ^ ANDN64(BCa, BCe);
+
+ Ebu ^= Du;
+ BCa = ROL64(Ebu, 27);
+ Ega ^= Da;
+ BCe = ROL64(Ega, 36);
+ Eke ^= De;
+ BCi = ROL64(Eke, 10);
+ Emi ^= Di;
+ BCo = ROL64(Emi, 15);
+ Eso ^= Do;
+ BCu = ROL64(Eso, 56);
+ Ama = BCa ^ ANDN64(BCe, BCi);
+ Ame = BCe ^ ANDN64(BCi, BCo);
+ Ami = BCi ^ ANDN64(BCo, BCu);
+ Amo = BCo ^ ANDN64(BCu, BCa);
+ Amu = BCu ^ ANDN64(BCa, BCe);
+
+ Ebi ^= Di;
+ BCa = ROL64(Ebi, 62);
+ Ego ^= Do;
+ BCe = ROL64(Ego, 55);
+ Eku ^= Du;
+ BCi = ROL64(Eku, 39);
+ Ema ^= Da;
+ BCo = ROL64(Ema, 41);
+ Ese ^= De;
+ BCu = ROL64(Ese, 2);
+ Asa = BCa ^ ANDN64(BCe, BCi);
+ Ase = BCe ^ ANDN64(BCi, BCo);
+ Asi = BCi ^ ANDN64(BCo, BCu);
+ Aso = BCo ^ ANDN64(BCu, BCa);
+ Asu = BCu ^ ANDN64(BCa, BCe);
+ }
+ while (round_consts < round_consts_end);
+
+ state[0] = Aba;
+ state[1] = Abe;
+ state[2] = Abi;
+ state[3] = Abo;
+ state[4] = Abu;
+ state[5] = Aga;
+ state[6] = Age;
+ state[7] = Agi;
+ state[8] = Ago;
+ state[9] = Agu;
+ state[10] = Aka;
+ state[11] = Ake;
+ state[12] = Aki;
+ state[13] = Ako;
+ state[14] = Aku;
+ state[15] = Ama;
+ state[16] = Ame;
+ state[17] = Ami;
+ state[18] = Amo;
+ state[19] = Amu;
+ state[20] = Asa;
+ state[21] = Ase;
+ state[22] = Asi;
+ state[23] = Aso;
+ state[24] = Asu;
+
+ return sizeof(void *) * 4 + sizeof(u64) * 12 * 5;
+}
+
+static unsigned int
+KECCAK_F1600_ABSORB_FUNC_NAME(KECCAK_STATE *hd, int pos, const byte *lanes,
+ unsigned int nlanes, int blocklanes)
+{
+ unsigned int burn = 0;
+
+ while (nlanes)
+ {
+ switch (blocklanes)
+ {
+ case 21:
+ /* SHAKE128 */
+ while (pos == 0 && nlanes >= 21)
+ {
+ nlanes -= 21;
+ absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+ absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
+ absorb_lanes64_4(&hd->u.state64[16], lanes); lanes += 8 * 4;
+ absorb_lanes64_1(&hd->u.state64[20], lanes); lanes += 8 * 1;
+
+ burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+ }
+ break;
+
+ case 18:
+ /* SHA3-224 */
+ while (pos == 0 && nlanes >= 18)
+ {
+ nlanes -= 18;
+ absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+ absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
+ absorb_lanes64_2(&hd->u.state64[16], lanes); lanes += 8 * 2;
+
+ burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+ }
+ break;
+
+ case 17:
+ /* SHA3-256 & SHAKE256 */
+ while (pos == 0 && nlanes >= 17)
+ {
+ nlanes -= 17;
+ absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+ absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
+ absorb_lanes64_1(&hd->u.state64[16], lanes); lanes += 8 * 1;
+
+ burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+ }
+ break;
+
+ case 13:
+ /* SHA3-384 */
+ while (pos == 0 && nlanes >= 13)
+ {
+ nlanes -= 13;
+ absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+ absorb_lanes64_4(&hd->u.state64[8], lanes); lanes += 8 * 4;
+ absorb_lanes64_1(&hd->u.state64[12], lanes); lanes += 8 * 1;
+
+ burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+ }
+ break;
+
+ case 9:
+ /* SHA3-512 */
+ while (pos == 0 && nlanes >= 9)
+ {
+ nlanes -= 9;
+ absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
+ absorb_lanes64_1(&hd->u.state64[8], lanes); lanes += 8 * 1;
+
+ burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+ }
+ break;
+ }
+
+ while (nlanes)
+ {
+ hd->u.state64[pos] ^= buf_get_le64(lanes);
+ lanes += 8;
+ nlanes--;
+
+ if (++pos == blocklanes)
+ {
+ burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
+ pos = 0;
+ break;
+ }
+ }
+ }
+
+ return burn;
+}
diff --git a/comm/third_party/libgcrypt/cipher/mac-cmac.c b/comm/third_party/libgcrypt/cipher/mac-cmac.c
new file mode 100644
index 0000000000..8d5d5ca304
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/mac-cmac.c
@@ -0,0 +1,524 @@
+/* mac-cmac.c - CMAC glue for MAC API
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "./mac-internal.h"
+
+
+static int
+map_mac_algo_to_cipher (int mac_algo)
+{
+ switch (mac_algo)
+ {
+ default:
+ return GCRY_CIPHER_NONE;
+ case GCRY_MAC_CMAC_AES:
+ return GCRY_CIPHER_AES;
+ case GCRY_MAC_CMAC_3DES:
+ return GCRY_CIPHER_3DES;
+ case GCRY_MAC_CMAC_CAMELLIA:
+ return GCRY_CIPHER_CAMELLIA128;
+ case GCRY_MAC_CMAC_IDEA:
+ return GCRY_CIPHER_IDEA;
+ case GCRY_MAC_CMAC_CAST5:
+ return GCRY_CIPHER_CAST5;
+ case GCRY_MAC_CMAC_BLOWFISH:
+ return GCRY_CIPHER_BLOWFISH;
+ case GCRY_MAC_CMAC_TWOFISH:
+ return GCRY_CIPHER_TWOFISH;
+ case GCRY_MAC_CMAC_SERPENT:
+ return GCRY_CIPHER_SERPENT128;
+ case GCRY_MAC_CMAC_SEED:
+ return GCRY_CIPHER_SEED;
+ case GCRY_MAC_CMAC_RFC2268:
+ return GCRY_CIPHER_RFC2268_128;
+ case GCRY_MAC_CMAC_GOST28147:
+ return GCRY_CIPHER_GOST28147;
+ case GCRY_MAC_CMAC_SM4:
+ return GCRY_CIPHER_SM4;
+ }
+}
+
+
+static gcry_err_code_t
+cmac_open (gcry_mac_hd_t h)
+{
+ gcry_err_code_t err;
+ gcry_cipher_hd_t hd;
+ int secure = (h->magic == CTX_MAC_MAGIC_SECURE);
+ int cipher_algo;
+ unsigned int flags;
+
+ cipher_algo = map_mac_algo_to_cipher (h->spec->algo);
+ flags = (secure ? GCRY_CIPHER_SECURE : 0);
+
+ err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_CMAC,
+ flags);
+ if (err)
+ return err;
+
+ h->u.cmac.cipher_algo = cipher_algo;
+ h->u.cmac.ctx = hd;
+ h->u.cmac.blklen = _gcry_cipher_get_algo_blklen (cipher_algo);
+ return 0;
+}
+
+
+static void
+cmac_close (gcry_mac_hd_t h)
+{
+ _gcry_cipher_close (h->u.cmac.ctx);
+ h->u.cmac.ctx = NULL;
+}
+
+
+static gcry_err_code_t
+cmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+ return _gcry_cipher_setkey (h->u.cmac.ctx, key, keylen);
+}
+
+
+static gcry_err_code_t
+cmac_reset (gcry_mac_hd_t h)
+{
+ return _gcry_cipher_reset (h->u.cmac.ctx);
+}
+
+
+static gcry_err_code_t
+cmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ return _gcry_cipher_cmac_authenticate (h->u.cmac.ctx, buf, buflen);
+}
+
+
+static gcry_err_code_t
+cmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
+{
+ if (*outlen > h->u.cmac.blklen)
+ *outlen = h->u.cmac.blklen;
+ return _gcry_cipher_cmac_get_tag (h->u.cmac.ctx, outbuf, *outlen);
+}
+
+
+static gcry_err_code_t
+cmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ return _gcry_cipher_cmac_check_tag (h->u.cmac.ctx, buf, buflen);
+}
+
+
+static unsigned int
+cmac_get_maclen (int algo)
+{
+ return _gcry_cipher_get_algo_blklen (map_mac_algo_to_cipher (algo));
+}
+
+
+static unsigned int
+cmac_get_keylen (int algo)
+{
+ return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo));
+}
+
+
+/* Check one CMAC with MAC ALGO using the regular MAC
+ * API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key
+ * and (EXPECT,EXPECTLEN) the expected result. Returns NULL on
+ * success or a string describing the failure. */
+static const char *
+check_one (int algo, const char *data, size_t datalen,
+ const char *key, size_t keylen,
+ const char *expect, size_t expectlen)
+{
+ gcry_mac_hd_t hd;
+ unsigned char mac[512]; /* hardcoded to avoid allocation */
+ unsigned int maclen;
+ size_t macoutlen;
+ int i;
+ gcry_error_t err = 0;
+
+ err = _gcry_mac_open (&hd, algo, 0, NULL);
+ if (err)
+ return "gcry_mac_open failed";
+
+ i = _gcry_mac_get_algo (hd);
+ if (i != algo)
+ return "gcry_mac_get_algo failed";
+
+ maclen = _gcry_mac_get_algo_maclen (algo);
+ if (maclen < 1 || maclen > 500)
+ return "gcry_mac_get_algo_maclen failed";
+
+ if (maclen != expectlen)
+ return "invalid tests data";
+
+ err = _gcry_mac_setkey (hd, key, keylen);
+ if (err)
+ {
+ _gcry_mac_close (hd);
+ return "gcry_mac_setkey failed";
+ }
+
+ err = _gcry_mac_write (hd, data, datalen);
+ if (err)
+ {
+ _gcry_mac_close (hd);
+ return "gcry_mac_write failed";
+ }
+
+ err = _gcry_mac_verify (hd, expect, maclen);
+ if (err)
+ {
+ _gcry_mac_close (hd);
+ return "gcry_mac_verify failed";
+ }
+
+ macoutlen = maclen;
+ err = _gcry_mac_read (hd, mac, &macoutlen);
+ _gcry_mac_close (hd);
+ if (err)
+ return "gcry_mac_read failed";
+
+ if (memcmp (mac, expect, maclen))
+ return "does not match";
+
+ return NULL;
+}
+
+
+/*
+ * CMAC AES and DES test vectors are from
+ * http://web.archive.org/web/20130930212819/http://csrc.nist.gov/publica \
+ * tions/nistpubs/800-38B/Updated_CMAC_Examples.pdf
+ */
+
+static gpg_err_code_t
+selftests_cmac_3des (int extended, selftest_report_func_t report)
+{
+ static const struct
+ {
+ const char *desc;
+ const char *data;
+ const char *key;
+ const char *expect;
+ } tv[] =
+ {
+ { "Basic 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" },
+ { "Extended 3DES #1",
+ "",
+ "\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" },
+ { "Extended 3DES #2",
+ "\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" },
+ { "Extended 3DES #3",
+ "\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" },
+ { "Extended 3DES #4",
+ "",
+ "\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" },
+ { "Extended 3DES #5",
+ "\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" },
+ { "Extended 3DES #6",
+ "\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" },
+ { "Extended 3DES #7",
+ "\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" },
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MAC_CMAC_3DES,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, 8);
+ if (errtxt)
+ goto failed;
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cmac", GCRY_MAC_CMAC_3DES, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+static gpg_err_code_t
+selftests_cmac_aes (int extended, selftest_report_func_t report)
+{
+ static const struct
+ {
+ const char *desc;
+ const char *data;
+ const char *key;
+ const char *expect;
+ } tv[] =
+ {
+ { "Basic AES128",
+ "\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" },
+ { "Basic AES192",
+ "\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" },
+ { "Basic AES256",
+ "\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" },
+ { "Extended AES #1",
+ "",
+ "\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" },
+ { "Extended AES #2",
+ "\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" },
+ { "Extended AES #3",
+ "\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" },
+ { "Extended AES #4",
+ "\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" },
+ { "Extended AES #5",
+ "\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" },
+ { "Extended AES #6",
+ "",
+ "\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" },
+ { "Extended AES #7",
+ "\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" },
+ { "Extended AES #8",
+ "",
+ "\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" },
+ { "Extended AES #9",
+ "\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" },
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MAC_CMAC_AES,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, strlen (tv[tvidx].expect));
+ if (errtxt)
+ goto failed;
+ if (tvidx >= 2 && !extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cmac", GCRY_MAC_CMAC_AES, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+cmac_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_MAC_CMAC_3DES:
+ ec = selftests_cmac_3des (extended, report);
+ break;
+ case GCRY_MAC_CMAC_AES:
+ ec = selftests_cmac_aes (extended, report);
+ break;
+
+ default:
+ ec = GPG_ERR_MAC_ALGO;
+ break;
+ }
+
+ return ec;
+}
+
+
+static gcry_mac_spec_ops_t cmac_ops = {
+ cmac_open,
+ cmac_close,
+ cmac_setkey,
+ NULL,
+ cmac_reset,
+ cmac_write,
+ cmac_read,
+ cmac_verify,
+ cmac_get_maclen,
+ cmac_get_keylen,
+ NULL,
+ cmac_selftest
+};
+
+
+#if USE_BLOWFISH
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_blowfish = {
+ GCRY_MAC_CMAC_BLOWFISH, {0, 0}, "CMAC_BLOWFISH",
+ &cmac_ops
+};
+#endif
+#if USE_DES
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_tripledes = {
+ GCRY_MAC_CMAC_3DES, {0, 1}, "CMAC_3DES",
+ &cmac_ops
+};
+#endif
+#if USE_CAST5
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_cast5 = {
+ GCRY_MAC_CMAC_CAST5, {0, 0}, "CMAC_CAST5",
+ &cmac_ops
+};
+#endif
+#if USE_AES
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_aes = {
+ GCRY_MAC_CMAC_AES, {0, 1}, "CMAC_AES",
+ &cmac_ops
+};
+#endif
+#if USE_TWOFISH
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_twofish = {
+ GCRY_MAC_CMAC_TWOFISH, {0, 0}, "CMAC_TWOFISH",
+ &cmac_ops
+};
+#endif
+#if USE_SERPENT
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_serpent = {
+ GCRY_MAC_CMAC_SERPENT, {0, 0}, "CMAC_SERPENT",
+ &cmac_ops
+};
+#endif
+#if USE_RFC2268
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_rfc2268 = {
+ GCRY_MAC_CMAC_RFC2268, {0, 0}, "CMAC_RFC2268",
+ &cmac_ops
+};
+#endif
+#if USE_SEED
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_seed = {
+ GCRY_MAC_CMAC_SEED, {0, 0}, "CMAC_SEED",
+ &cmac_ops
+};
+#endif
+#if USE_CAMELLIA
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_camellia = {
+ GCRY_MAC_CMAC_CAMELLIA, {0, 0}, "CMAC_CAMELLIA",
+ &cmac_ops
+};
+#endif
+#ifdef USE_IDEA
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_idea = {
+ GCRY_MAC_CMAC_IDEA, {0, 0}, "CMAC_IDEA",
+ &cmac_ops
+};
+#endif
+#if USE_GOST28147
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_gost28147 = {
+ GCRY_MAC_CMAC_GOST28147, {0, 0}, "CMAC_GOST28147",
+ &cmac_ops
+};
+#endif
+#if USE_SM4
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_sm4 = {
+ GCRY_MAC_CMAC_SM4, {0, 0}, "CMAC_SM4",
+ &cmac_ops
+};
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/mac-gmac.c b/comm/third_party/libgcrypt/cipher/mac-gmac.c
new file mode 100644
index 0000000000..e04c6d1ef0
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/mac-gmac.c
@@ -0,0 +1,187 @@
+/* mac-gmac.c - GMAC glue for MAC API
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "./mac-internal.h"
+
+
+static int
+map_mac_algo_to_cipher (int mac_algo)
+{
+ switch (mac_algo)
+ {
+ default:
+ return GCRY_CIPHER_NONE;
+ case GCRY_MAC_GMAC_AES:
+ return GCRY_CIPHER_AES;
+ case GCRY_MAC_GMAC_CAMELLIA:
+ return GCRY_CIPHER_CAMELLIA128;
+ case GCRY_MAC_GMAC_TWOFISH:
+ return GCRY_CIPHER_TWOFISH;
+ case GCRY_MAC_GMAC_SERPENT:
+ return GCRY_CIPHER_SERPENT128;
+ case GCRY_MAC_GMAC_SEED:
+ return GCRY_CIPHER_SEED;
+ }
+}
+
+
+static gcry_err_code_t
+gmac_open (gcry_mac_hd_t h)
+{
+ gcry_err_code_t err;
+ gcry_cipher_hd_t hd;
+ int secure = (h->magic == CTX_MAC_MAGIC_SECURE);
+ int cipher_algo;
+ unsigned int flags;
+
+ cipher_algo = map_mac_algo_to_cipher (h->spec->algo);
+ flags = (secure ? GCRY_CIPHER_SECURE : 0);
+
+ err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_GCM,
+ flags);
+ if (err)
+ return err;
+
+ h->u.gmac.cipher_algo = cipher_algo;
+ h->u.gmac.ctx = hd;
+ return 0;
+}
+
+
+static void
+gmac_close (gcry_mac_hd_t h)
+{
+ _gcry_cipher_close (h->u.gmac.ctx);
+ h->u.gmac.ctx = NULL;
+}
+
+
+static gcry_err_code_t
+gmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+ return _gcry_cipher_setkey (h->u.gmac.ctx, key, keylen);
+}
+
+
+static gcry_err_code_t
+gmac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen)
+{
+ return _gcry_cipher_setiv (h->u.gmac.ctx, iv, ivlen);
+}
+
+
+static gcry_err_code_t
+gmac_reset (gcry_mac_hd_t h)
+{
+ return _gcry_cipher_reset (h->u.gmac.ctx);
+}
+
+
+static gcry_err_code_t
+gmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ return _gcry_cipher_authenticate (h->u.gmac.ctx, buf, buflen);
+}
+
+
+static gcry_err_code_t
+gmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
+{
+ if (*outlen > GCRY_GCM_BLOCK_LEN)
+ *outlen = GCRY_GCM_BLOCK_LEN;
+ return _gcry_cipher_gettag (h->u.gmac.ctx, outbuf, *outlen);
+}
+
+
+static gcry_err_code_t
+gmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ return _gcry_cipher_checktag (h->u.gmac.ctx, buf, buflen);
+}
+
+
+static unsigned int
+gmac_get_maclen (int algo)
+{
+ (void)algo;
+ return GCRY_GCM_BLOCK_LEN;
+}
+
+
+static unsigned int
+gmac_get_keylen (int algo)
+{
+ return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo));
+}
+
+
+static gcry_mac_spec_ops_t gmac_ops = {
+ gmac_open,
+ gmac_close,
+ gmac_setkey,
+ gmac_setiv,
+ gmac_reset,
+ gmac_write,
+ gmac_read,
+ gmac_verify,
+ gmac_get_maclen,
+ gmac_get_keylen,
+ NULL,
+ NULL
+};
+
+
+#if USE_AES
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = {
+ GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES",
+ &gmac_ops
+};
+#endif
+#if USE_TWOFISH
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_twofish = {
+ GCRY_MAC_GMAC_TWOFISH, {0, 0}, "GMAC_TWOFISH",
+ &gmac_ops
+};
+#endif
+#if USE_SERPENT
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_serpent = {
+ GCRY_MAC_GMAC_SERPENT, {0, 0}, "GMAC_SERPENT",
+ &gmac_ops
+};
+#endif
+#if USE_SEED
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed = {
+ GCRY_MAC_GMAC_SEED, {0, 0}, "GMAC_SEED",
+ &gmac_ops
+};
+#endif
+#if USE_CAMELLIA
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia = {
+ GCRY_MAC_GMAC_CAMELLIA, {0, 0}, "GMAC_CAMELLIA",
+ &gmac_ops
+};
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/mac-hmac.c b/comm/third_party/libgcrypt/cipher/mac-hmac.c
new file mode 100644
index 0000000000..4e10dd2c9e
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/mac-hmac.c
@@ -0,0 +1,1495 @@
+/* mac-hmac.c - HMAC glue for MAC API
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "./mac-internal.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hmac256.h"
+
+
+static int
+map_mac_algo_to_md (int mac_algo)
+{
+ switch (mac_algo)
+ {
+ default:
+ return GCRY_MD_NONE;
+ case GCRY_MAC_HMAC_MD2:
+ return GCRY_MD_MD2;
+ case GCRY_MAC_HMAC_MD4:
+ return GCRY_MD_MD4;
+ case GCRY_MAC_HMAC_MD5:
+ return GCRY_MD_MD5;
+ case GCRY_MAC_HMAC_SHA1:
+ return GCRY_MD_SHA1;
+ case GCRY_MAC_HMAC_SHA224:
+ return GCRY_MD_SHA224;
+ case GCRY_MAC_HMAC_SHA256:
+ return GCRY_MD_SHA256;
+ case GCRY_MAC_HMAC_SHA384:
+ return GCRY_MD_SHA384;
+ case GCRY_MAC_HMAC_SHA512:
+ return GCRY_MD_SHA512;
+ case GCRY_MAC_HMAC_SHA512_256:
+ return GCRY_MD_SHA512_256;
+ case GCRY_MAC_HMAC_SHA512_224:
+ return GCRY_MD_SHA512_224;
+ case GCRY_MAC_HMAC_SHA3_224:
+ return GCRY_MD_SHA3_224;
+ case GCRY_MAC_HMAC_SHA3_256:
+ return GCRY_MD_SHA3_256;
+ case GCRY_MAC_HMAC_SHA3_384:
+ return GCRY_MD_SHA3_384;
+ case GCRY_MAC_HMAC_SHA3_512:
+ return GCRY_MD_SHA3_512;
+ case GCRY_MAC_HMAC_RMD160:
+ return GCRY_MD_RMD160;
+ case GCRY_MAC_HMAC_TIGER1:
+ return GCRY_MD_TIGER1;
+ case GCRY_MAC_HMAC_WHIRLPOOL:
+ return GCRY_MD_WHIRLPOOL;
+ case GCRY_MAC_HMAC_GOSTR3411_94:
+ return GCRY_MD_GOSTR3411_94;
+ case GCRY_MAC_HMAC_GOSTR3411_CP:
+ return GCRY_MD_GOSTR3411_CP;
+ case GCRY_MAC_HMAC_STRIBOG256:
+ return GCRY_MD_STRIBOG256;
+ case GCRY_MAC_HMAC_STRIBOG512:
+ return GCRY_MD_STRIBOG512;
+ case GCRY_MAC_HMAC_BLAKE2B_512:
+ return GCRY_MD_BLAKE2B_512;
+ case GCRY_MAC_HMAC_BLAKE2B_384:
+ return GCRY_MD_BLAKE2B_384;
+ case GCRY_MAC_HMAC_BLAKE2B_256:
+ return GCRY_MD_BLAKE2B_256;
+ case GCRY_MAC_HMAC_BLAKE2B_160:
+ return GCRY_MD_BLAKE2B_160;
+ case GCRY_MAC_HMAC_BLAKE2S_256:
+ return GCRY_MD_BLAKE2S_256;
+ case GCRY_MAC_HMAC_BLAKE2S_224:
+ return GCRY_MD_BLAKE2S_224;
+ case GCRY_MAC_HMAC_BLAKE2S_160:
+ return GCRY_MD_BLAKE2S_160;
+ case GCRY_MAC_HMAC_BLAKE2S_128:
+ return GCRY_MD_BLAKE2S_128;
+ case GCRY_MAC_HMAC_SM3:
+ return GCRY_MD_SM3;
+ }
+}
+
+
+static gcry_err_code_t
+hmac_open (gcry_mac_hd_t h)
+{
+ gcry_err_code_t err;
+ gcry_md_hd_t hd;
+ int secure = (h->magic == CTX_MAC_MAGIC_SECURE);
+ unsigned int flags;
+ int md_algo;
+
+ md_algo = map_mac_algo_to_md (h->spec->algo);
+
+ flags = GCRY_MD_FLAG_HMAC;
+ flags |= (secure ? GCRY_MD_FLAG_SECURE : 0);
+
+ err = _gcry_md_open (&hd, md_algo, flags);
+ if (err)
+ return err;
+
+ h->u.hmac.md_algo = md_algo;
+ h->u.hmac.md_ctx = hd;
+ return 0;
+}
+
+
+static void
+hmac_close (gcry_mac_hd_t h)
+{
+ _gcry_md_close (h->u.hmac.md_ctx);
+ h->u.hmac.md_ctx = NULL;
+}
+
+
+static gcry_err_code_t
+hmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+ return _gcry_md_setkey (h->u.hmac.md_ctx, key, keylen);
+}
+
+
+static gcry_err_code_t
+hmac_reset (gcry_mac_hd_t h)
+{
+ _gcry_md_reset (h->u.hmac.md_ctx);
+ return 0;
+}
+
+
+static gcry_err_code_t
+hmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ _gcry_md_write (h->u.hmac.md_ctx, buf, buflen);
+ return 0;
+}
+
+
+static gcry_err_code_t
+hmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
+{
+ unsigned int dlen;
+ const unsigned char *digest;
+
+ dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
+ digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
+
+ if (*outlen <= dlen)
+ buf_cpy (outbuf, digest, *outlen);
+ else
+ {
+ buf_cpy (outbuf, digest, dlen);
+ *outlen = dlen;
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+hmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ unsigned int dlen;
+ const unsigned char *digest;
+
+ dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
+ digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
+
+ if (buflen > dlen)
+ return GPG_ERR_INV_LENGTH;
+
+ return buf_eq_const (buf, digest, buflen) ? 0 : GPG_ERR_CHECKSUM;
+}
+
+
+static unsigned int
+hmac_get_maclen (int algo)
+{
+ return _gcry_md_get_algo_dlen (map_mac_algo_to_md (algo));
+}
+
+
+static unsigned int
+hmac_get_keylen (int algo)
+{
+ /* Return blocksize for default key length. */
+ switch (algo)
+ {
+ case GCRY_MD_SHA3_224:
+ return 1152 / 8;
+ case GCRY_MD_SHA3_256:
+ return 1088 / 8;
+ case GCRY_MD_SHA3_384:
+ return 832 / 8;
+ case GCRY_MD_SHA3_512:
+ return 576 / 8;
+ case GCRY_MAC_HMAC_SHA384:
+ case GCRY_MAC_HMAC_SHA512:
+ return 128;
+ case GCRY_MAC_HMAC_GOSTR3411_94:
+ return 32;
+ default:
+ return 64;
+ }
+}
+
+
+/* Check one HMAC with digest ALGO using the regualr HAMC
+ * API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key
+ * and (EXPECT,EXPECTLEN) the expected result. If TRUNC is set, the
+ * EXPECTLEN may be less than the digest length. Returns NULL on
+ * success or a string describing the failure. */
+static const char *
+check_one (int algo,
+ const void *data, size_t datalen,
+ const void *key, size_t keylen,
+ const void *expect, size_t expectlen, int trunc)
+{
+ gcry_md_hd_t hd;
+ const unsigned char *digest;
+
+/* printf ("HMAC algo %d\n", algo); */
+ if (trunc)
+ {
+ if (_gcry_md_get_algo_dlen (algo) < expectlen)
+ return "invalid tests data";
+ }
+ else
+ {
+ if (_gcry_md_get_algo_dlen (algo) != expectlen)
+ return "invalid tests data";
+ }
+ if (_gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC))
+ return "gcry_md_open failed";
+ if (_gcry_md_setkey (hd, key, keylen))
+ {
+ _gcry_md_close (hd);
+ return "gcry_md_setkey failed";
+ }
+ _gcry_md_write (hd, data, datalen);
+ digest = _gcry_md_read (hd, algo);
+ if (!digest)
+ {
+ _gcry_md_close (hd);
+ return "gcry_md_read failed";
+ }
+ if (memcmp (digest, expect, expectlen))
+ {
+/* int i; */
+
+/* fputs (" {", stdout); */
+/* for (i=0; i < expectlen-1; i++) */
+/* { */
+/* if (i && !(i % 8)) */
+/* fputs ("\n ", stdout); */
+/* printf (" 0x%02x,", digest[i]); */
+/* } */
+/* printf (" 0x%02x } },\n", digest[i]); */
+
+ _gcry_md_close (hd);
+ return "does not match";
+ }
+ _gcry_md_close (hd);
+ return NULL;
+}
+
+
+static gpg_err_code_t
+selftests_sha1 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+ unsigned char key[128];
+ int i, j;
+
+ what = "FIPS-198a, A.1";
+ for (i=0; i < 64; i++)
+ key[i] = i;
+ errtxt = check_one (GCRY_MD_SHA1,
+ "Sample #1", 9,
+ key, 64,
+ "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
+ "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a", 20, 0);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "FIPS-198a, A.2";
+ for (i=0, j=0x30; i < 20; i++)
+ key[i] = j++;
+ errtxt = check_one (GCRY_MD_SHA1,
+ "Sample #2", 9,
+ key, 20,
+ "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
+ "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20, 0);
+ if (errtxt)
+ goto failed;
+
+ what = "FIPS-198a, A.3";
+ for (i=0, j=0x50; i < 100; i++)
+ key[i] = j++;
+ errtxt = check_one (GCRY_MD_SHA1,
+ "Sample #3", 9,
+ key, 100,
+ "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
+ "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20, 0);
+ if (errtxt)
+ goto failed;
+
+ what = "FIPS-198a, A.4";
+ for (i=0, j=0x70; i < 49; i++)
+ key[i] = j++;
+ errtxt = check_one (GCRY_MD_SHA1,
+ "Sample #4", 9,
+ key, 49,
+ "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
+ "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20, 0);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA1, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+static gpg_err_code_t
+selftests_sha224 (int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect[28];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf,
+ 0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f,
+ 0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00,
+ 0x8f, 0xd0, 0x5e, 0x44 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19,
+ 0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f,
+ 0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f,
+ 0x53, 0x68, 0x4b, 0x22 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\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",
+ { 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6,
+ 0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, 0xd2, 0x64,
+ 0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1,
+ 0xec, 0x83, 0x33, 0xea } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\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",
+ { 0x6c, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3c, 0xac,
+ 0x6a, 0x2a, 0xbc, 0x1b, 0xb3, 0x82, 0x62, 0x7c,
+ 0xec, 0x6a, 0x90, 0xd8, 0x6e, 0xfc, 0x01, 0x2d,
+ 0xe7, 0xaf, 0xec, 0x5a } },
+
+ { "data-54 key-131",
+ "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",
+ { 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad,
+ 0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2,
+ 0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27,
+ 0x3f, 0xa6, 0x87, 0x0e } },
+
+ { "data-152 key-131",
+ "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",
+ { 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02,
+ 0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, 0x9d, 0xbd,
+ 0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9,
+ 0xf6, 0xf5, 0x65, 0xd1 } },
+
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MD_SHA224,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, DIM (tv[tvidx].expect), 0);
+ if (errtxt)
+ goto failed;
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA224, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha256 (int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect[32];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+ 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+ 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+ 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
+ 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
+ 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
+ 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\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",
+ { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
+ 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
+ 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
+ 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\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",
+ { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
+ 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
+ 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
+ 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
+
+ { "data-54 key-131",
+ "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",
+ { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
+ 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
+ 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
+ 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
+
+ { "data-152 key-131",
+ "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",
+ { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
+ 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
+ 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
+ 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
+
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ hmac256_context_t hmachd;
+ const unsigned char *digest;
+ size_t dlen;
+
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MD_SHA256,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, DIM (tv[tvidx].expect), 0);
+ if (errtxt)
+ goto failed;
+
+ hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
+ if (!hmachd)
+ {
+ errtxt = "_gcry_hmac256_new failed";
+ goto failed;
+ }
+ _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
+ digest = _gcry_hmac256_finalize (hmachd, &dlen);
+ if (!digest)
+ {
+ errtxt = "_gcry_hmac256_finalize failed";
+ _gcry_hmac256_release (hmachd);
+ goto failed;
+ }
+ if (dlen != DIM (tv[tvidx].expect)
+ || memcmp (digest, tv[tvidx].expect, DIM (tv[tvidx].expect)))
+ {
+ errtxt = "does not match in second implementation";
+ _gcry_hmac256_release (hmachd);
+ goto failed;
+ }
+ _gcry_hmac256_release (hmachd);
+
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA256, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha384 (int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect[48];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
+ 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
+ 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
+ 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
+ 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
+ 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
+ 0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
+ 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
+ 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
+ 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
+ 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\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",
+ { 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a,
+ 0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f,
+ 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
+ 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b,
+ 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
+ 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\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",
+ { 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85,
+ 0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7,
+ 0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
+ 0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e,
+ 0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
+ 0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb } },
+
+ { "data-54 key-131",
+ "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",
+ { 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
+ 0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
+ 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
+ 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
+ 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
+ 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 } },
+
+ { "data-152 key-131",
+ "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",
+ { 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
+ 0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
+ 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
+ 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
+ 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
+ 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e } },
+
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MD_SHA384,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, DIM (tv[tvidx].expect), 0);
+ if (errtxt)
+ goto failed;
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA384, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha512 (int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect[64];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
+ 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
+ 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
+ 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
+ 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
+ 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
+ 0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
+ 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
+ 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
+ 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
+ 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
+ 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
+ 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
+ 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
+ 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\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",
+ { 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
+ 0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
+ 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
+ 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
+ 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
+ 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
+ 0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26,
+ 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\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",
+ { 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
+ 0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
+ 0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
+ 0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
+ 0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
+ 0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
+ 0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d,
+ 0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd } },
+
+ { "data-54 key-131",
+ "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",
+ { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
+ 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
+ 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
+ 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
+ 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
+ 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
+ 0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
+ 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 } },
+
+ { "data-152 key-131",
+ "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",
+ { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
+ 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
+ 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
+ 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
+ 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
+ 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
+ 0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
+ 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 } },
+
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MD_SHA512,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, DIM (tv[tvidx].expect), 0);
+ if (errtxt)
+ goto failed;
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA512, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+/* Test for the SHA3 algorithms. Vectors taken on 2017-07-18 from
+ * http://www.wolfgang-ehrhardt.de/hmac-sha3-testvectors.html */
+static gpg_err_code_t
+selftests_sha3 (int hashalgo, int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect_224[28];
+ const char expect_256[32];
+ const char expect_384[48];
+ const char expect_512[64];
+ unsigned char trunc;
+ } tv[] =
+ {
+ { "data-9 key-20", /* Test 1 */
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+
+ { 0x3b, 0x16, 0x54, 0x6b, 0xbc, 0x7b, 0xe2, 0x70,
+ 0x6a, 0x03, 0x1d, 0xca, 0xfd, 0x56, 0x37, 0x3d,
+ 0x98, 0x84, 0x36, 0x76, 0x41, 0xd8, 0xc5, 0x9a,
+ 0xf3, 0xc8, 0x60, 0xf7 },
+ { 0xba, 0x85, 0x19, 0x23, 0x10, 0xdf, 0xfa, 0x96,
+ 0xe2, 0xa3, 0xa4, 0x0e, 0x69, 0x77, 0x43, 0x51,
+ 0x14, 0x0b, 0xb7, 0x18, 0x5e, 0x12, 0x02, 0xcd,
+ 0xcc, 0x91, 0x75, 0x89, 0xf9, 0x5e, 0x16, 0xbb },
+ { 0x68, 0xd2, 0xdc, 0xf7, 0xfd, 0x4d, 0xdd, 0x0a,
+ 0x22, 0x40, 0xc8, 0xa4, 0x37, 0x30, 0x5f, 0x61,
+ 0xfb, 0x73, 0x34, 0xcf, 0xb5, 0xd0, 0x22, 0x6e,
+ 0x1b, 0xc2, 0x7d, 0xc1, 0x0a, 0x2e, 0x72, 0x3a,
+ 0x20, 0xd3, 0x70, 0xb4, 0x77, 0x43, 0x13, 0x0e,
+ 0x26, 0xac, 0x7e, 0x3d, 0x53, 0x28, 0x86, 0xbd },
+ { 0xeb, 0x3f, 0xbd, 0x4b, 0x2e, 0xaa, 0xb8, 0xf5,
+ 0xc5, 0x04, 0xbd, 0x3a, 0x41, 0x46, 0x5a, 0xac,
+ 0xec, 0x15, 0x77, 0x0a, 0x7c, 0xab, 0xac, 0x53,
+ 0x1e, 0x48, 0x2f, 0x86, 0x0b, 0x5e, 0xc7, 0xba,
+ 0x47, 0xcc, 0xb2, 0xc6, 0xf2, 0xaf, 0xce, 0x8f,
+ 0x88, 0xd2, 0x2b, 0x6d, 0xc6, 0x13, 0x80, 0xf2,
+ 0x3a, 0x66, 0x8f, 0xd3, 0x88, 0x8b, 0xb8, 0x05,
+ 0x37, 0xc0, 0xa0, 0xb8, 0x64, 0x07, 0x68, 0x9e }
+ },
+
+ { "data-28 key-4", /* Test 2 */
+ /* Test with a key shorter than the length of the HMAC output. */
+ "what do ya want for nothing?",
+ "Jefe",
+
+ { 0x7f, 0xdb, 0x8d, 0xd8, 0x8b, 0xd2, 0xf6, 0x0d,
+ 0x1b, 0x79, 0x86, 0x34, 0xad, 0x38, 0x68, 0x11,
+ 0xc2, 0xcf, 0xc8, 0x5b, 0xfa, 0xf5, 0xd5, 0x2b,
+ 0xba, 0xce, 0x5e, 0x66 },
+ { 0xc7, 0xd4, 0x07, 0x2e, 0x78, 0x88, 0x77, 0xae,
+ 0x35, 0x96, 0xbb, 0xb0, 0xda, 0x73, 0xb8, 0x87,
+ 0xc9, 0x17, 0x1f, 0x93, 0x09, 0x5b, 0x29, 0x4a,
+ 0xe8, 0x57, 0xfb, 0xe2, 0x64, 0x5e, 0x1b, 0xa5 },
+ { 0xf1, 0x10, 0x1f, 0x8c, 0xbf, 0x97, 0x66, 0xfd,
+ 0x67, 0x64, 0xd2, 0xed, 0x61, 0x90, 0x3f, 0x21,
+ 0xca, 0x9b, 0x18, 0xf5, 0x7c, 0xf3, 0xe1, 0xa2,
+ 0x3c, 0xa1, 0x35, 0x08, 0xa9, 0x32, 0x43, 0xce,
+ 0x48, 0xc0, 0x45, 0xdc, 0x00, 0x7f, 0x26, 0xa2,
+ 0x1b, 0x3f, 0x5e, 0x0e, 0x9d, 0xf4, 0xc2, 0x0a },
+ { 0x5a, 0x4b, 0xfe, 0xab, 0x61, 0x66, 0x42, 0x7c,
+ 0x7a, 0x36, 0x47, 0xb7, 0x47, 0x29, 0x2b, 0x83,
+ 0x84, 0x53, 0x7c, 0xdb, 0x89, 0xaf, 0xb3, 0xbf,
+ 0x56, 0x65, 0xe4, 0xc5, 0xe7, 0x09, 0x35, 0x0b,
+ 0x28, 0x7b, 0xae, 0xc9, 0x21, 0xfd, 0x7c, 0xa0,
+ 0xee, 0x7a, 0x0c, 0x31, 0xd0, 0x22, 0xa9, 0x5e,
+ 0x1f, 0xc9, 0x2b, 0xa9, 0xd7, 0x7d, 0xf8, 0x83,
+ 0x96, 0x02, 0x75, 0xbe, 0xb4, 0xe6, 0x20, 0x24 }
+ },
+
+ { "data-50 key-20", /* Test 3 */
+ /* Test with a combined length of key and data that is larger
+ * than 64 bytes (= block-size of SHA-224 and SHA-256). */
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\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",
+
+ { 0x67, 0x6c, 0xfc, 0x7d, 0x16, 0x15, 0x36, 0x38,
+ 0x78, 0x03, 0x90, 0x69, 0x2b, 0xe1, 0x42, 0xd2,
+ 0xdf, 0x7c, 0xe9, 0x24, 0xb9, 0x09, 0xc0, 0xc0,
+ 0x8d, 0xbf, 0xdc, 0x1a },
+ { 0x84, 0xec, 0x79, 0x12, 0x4a, 0x27, 0x10, 0x78,
+ 0x65, 0xce, 0xdd, 0x8b, 0xd8, 0x2d, 0xa9, 0x96,
+ 0x5e, 0x5e, 0xd8, 0xc3, 0x7b, 0x0a, 0xc9, 0x80,
+ 0x05, 0xa7, 0xf3, 0x9e, 0xd5, 0x8a, 0x42, 0x07 },
+ { 0x27, 0x5c, 0xd0, 0xe6, 0x61, 0xbb, 0x8b, 0x15,
+ 0x1c, 0x64, 0xd2, 0x88, 0xf1, 0xf7, 0x82, 0xfb,
+ 0x91, 0xa8, 0xab, 0xd5, 0x68, 0x58, 0xd7, 0x2b,
+ 0xab, 0xb2, 0xd4, 0x76, 0xf0, 0x45, 0x83, 0x73,
+ 0xb4, 0x1b, 0x6a, 0xb5, 0xbf, 0x17, 0x4b, 0xec,
+ 0x42, 0x2e, 0x53, 0xfc, 0x31, 0x35, 0xac, 0x6e },
+ { 0x30, 0x9e, 0x99, 0xf9, 0xec, 0x07, 0x5e, 0xc6,
+ 0xc6, 0xd4, 0x75, 0xed, 0xa1, 0x18, 0x06, 0x87,
+ 0xfc, 0xf1, 0x53, 0x11, 0x95, 0x80, 0x2a, 0x99,
+ 0xb5, 0x67, 0x74, 0x49, 0xa8, 0x62, 0x51, 0x82,
+ 0x85, 0x1c, 0xb3, 0x32, 0xaf, 0xb6, 0xa8, 0x9c,
+ 0x41, 0x13, 0x25, 0xfb, 0xcb, 0xcd, 0x42, 0xaf,
+ 0xcb, 0x7b, 0x6e, 0x5a, 0xab, 0x7e, 0xa4, 0x2c,
+ 0x66, 0x0f, 0x97, 0xfd, 0x85, 0x84, 0xbf, 0x03 }
+ },
+
+ { "data-50 key-25", /* Test 4 */
+ /* Test with a combined length of key and data that is larger
+ * than 64 bytes (= block-size of SHA-224 and SHA-256). */
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\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",
+
+ { 0xa9, 0xd7, 0x68, 0x5a, 0x19, 0xc4, 0xe0, 0xdb,
+ 0xd9, 0xdf, 0x25, 0x56, 0xcc, 0x8a, 0x7d, 0x2a,
+ 0x77, 0x33, 0xb6, 0x76, 0x25, 0xce, 0x59, 0x4c,
+ 0x78, 0x27, 0x0e, 0xeb },
+ { 0x57, 0x36, 0x6a, 0x45, 0xe2, 0x30, 0x53, 0x21,
+ 0xa4, 0xbc, 0x5a, 0xa5, 0xfe, 0x2e, 0xf8, 0xa9,
+ 0x21, 0xf6, 0xaf, 0x82, 0x73, 0xd7, 0xfe, 0x7b,
+ 0xe6, 0xcf, 0xed, 0xb3, 0xf0, 0xae, 0xa6, 0xd7 },
+ { 0x3a, 0x5d, 0x7a, 0x87, 0x97, 0x02, 0xc0, 0x86,
+ 0xbc, 0x96, 0xd1, 0xdd, 0x8a, 0xa1, 0x5d, 0x9c,
+ 0x46, 0x44, 0x6b, 0x95, 0x52, 0x13, 0x11, 0xc6,
+ 0x06, 0xfd, 0xc4, 0xe3, 0x08, 0xf4, 0xb9, 0x84,
+ 0xda, 0x2d, 0x0f, 0x94, 0x49, 0xb3, 0xba, 0x84,
+ 0x25, 0xec, 0x7f, 0xb8, 0xc3, 0x1b, 0xc1, 0x36 },
+ { 0xb2, 0x7e, 0xab, 0x1d, 0x6e, 0x8d, 0x87, 0x46,
+ 0x1c, 0x29, 0xf7, 0xf5, 0x73, 0x9d, 0xd5, 0x8e,
+ 0x98, 0xaa, 0x35, 0xf8, 0xe8, 0x23, 0xad, 0x38,
+ 0xc5, 0x49, 0x2a, 0x20, 0x88, 0xfa, 0x02, 0x81,
+ 0x99, 0x3b, 0xbf, 0xff, 0x9a, 0x0e, 0x9c, 0x6b,
+ 0xf1, 0x21, 0xae, 0x9e, 0xc9, 0xbb, 0x09, 0xd8,
+ 0x4a, 0x5e, 0xba, 0xc8, 0x17, 0x18, 0x2e, 0xa9,
+ 0x74, 0x67, 0x3f, 0xb1, 0x33, 0xca, 0x0d, 0x1d }
+ },
+
+ { "data-20 key-20 trunc", /* Test 5 */
+ /* Test with a truncation of output to 128 bits. */
+ "Test With Truncation",
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c",
+
+ { 0x49, 0xfd, 0xd3, 0xab, 0xd0, 0x05, 0xeb, 0xb8,
+ 0xae, 0x63, 0xfe, 0xa9, 0x46, 0xd1, 0x88, 0x3c },
+ { 0x6e, 0x02, 0xc6, 0x45, 0x37, 0xfb, 0x11, 0x80,
+ 0x57, 0xab, 0xb7, 0xfb, 0x66, 0xa2, 0x3b, 0x3c },
+ { 0x47, 0xc5, 0x1a, 0xce, 0x1f, 0xfa, 0xcf, 0xfd,
+ 0x74, 0x94, 0x72, 0x46, 0x82, 0x61, 0x57, 0x83 },
+ { 0x0f, 0xa7, 0x47, 0x59, 0x48, 0xf4, 0x3f, 0x48,
+ 0xca, 0x05, 0x16, 0x67, 0x1e, 0x18, 0x97, 0x8c },
+ 16
+ },
+
+ { "data-54 key-131", /* Test 6 */
+ /* Test with a key larger than 128 bytes (= block-size of
+ * SHA-384 and SHA-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",
+
+ { 0xb4, 0xa1, 0xf0, 0x4c, 0x00, 0x28, 0x7a, 0x9b,
+ 0x7f, 0x60, 0x75, 0xb3, 0x13, 0xd2, 0x79, 0xb8,
+ 0x33, 0xbc, 0x8f, 0x75, 0x12, 0x43, 0x52, 0xd0,
+ 0x5f, 0xb9, 0x99, 0x5f },
+ { 0xed, 0x73, 0xa3, 0x74, 0xb9, 0x6c, 0x00, 0x52,
+ 0x35, 0xf9, 0x48, 0x03, 0x2f, 0x09, 0x67, 0x4a,
+ 0x58, 0xc0, 0xce, 0x55, 0x5c, 0xfc, 0x1f, 0x22,
+ 0x3b, 0x02, 0x35, 0x65, 0x60, 0x31, 0x2c, 0x3b },
+ { 0x0f, 0xc1, 0x95, 0x13, 0xbf, 0x6b, 0xd8, 0x78,
+ 0x03, 0x70, 0x16, 0x70, 0x6a, 0x0e, 0x57, 0xbc,
+ 0x52, 0x81, 0x39, 0x83, 0x6b, 0x9a, 0x42, 0xc3,
+ 0xd4, 0x19, 0xe4, 0x98, 0xe0, 0xe1, 0xfb, 0x96,
+ 0x16, 0xfd, 0x66, 0x91, 0x38, 0xd3, 0x3a, 0x11,
+ 0x05, 0xe0, 0x7c, 0x72, 0xb6, 0x95, 0x3b, 0xcc },
+ { 0x00, 0xf7, 0x51, 0xa9, 0xe5, 0x06, 0x95, 0xb0,
+ 0x90, 0xed, 0x69, 0x11, 0xa4, 0xb6, 0x55, 0x24,
+ 0x95, 0x1c, 0xdc, 0x15, 0xa7, 0x3a, 0x5d, 0x58,
+ 0xbb, 0x55, 0x21, 0x5e, 0xa2, 0xcd, 0x83, 0x9a,
+ 0xc7, 0x9d, 0x2b, 0x44, 0xa3, 0x9b, 0xaf, 0xab,
+ 0x27, 0xe8, 0x3f, 0xde, 0x9e, 0x11, 0xf6, 0x34,
+ 0x0b, 0x11, 0xd9, 0x91, 0xb1, 0xb9, 0x1b, 0xf2,
+ 0xee, 0xe7, 0xfc, 0x87, 0x24, 0x26, 0xc3, 0xa4 }
+ },
+
+ { "data-54 key-147", /* Test 6a */
+ /* Test with a key larger than 144 bytes (= block-size of
+ * 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",
+
+ { 0xb9, 0x6d, 0x73, 0x0c, 0x14, 0x8c, 0x2d, 0xaa,
+ 0xd8, 0x64, 0x9d, 0x83, 0xde, 0xfa, 0xa3, 0x71,
+ 0x97, 0x38, 0xd3, 0x47, 0x75, 0x39, 0x7b, 0x75,
+ 0x71, 0xc3, 0x85, 0x15 },
+ { 0xa6, 0x07, 0x2f, 0x86, 0xde, 0x52, 0xb3, 0x8b,
+ 0xb3, 0x49, 0xfe, 0x84, 0xcd, 0x6d, 0x97, 0xfb,
+ 0x6a, 0x37, 0xc4, 0xc0, 0xf6, 0x2a, 0xae, 0x93,
+ 0x98, 0x11, 0x93, 0xa7, 0x22, 0x9d, 0x34, 0x67 },
+ { 0x71, 0x3d, 0xff, 0x03, 0x02, 0xc8, 0x50, 0x86,
+ 0xec, 0x5a, 0xd0, 0x76, 0x8d, 0xd6, 0x5a, 0x13,
+ 0xdd, 0xd7, 0x90, 0x68, 0xd8, 0xd4, 0xc6, 0x21,
+ 0x2b, 0x71, 0x2e, 0x41, 0x64, 0x94, 0x49, 0x11,
+ 0x14, 0x80, 0x23, 0x00, 0x44, 0x18, 0x5a, 0x99,
+ 0x10, 0x3e, 0xd8, 0x20, 0x04, 0xdd, 0xbf, 0xcc },
+ { 0xb1, 0x48, 0x35, 0xc8, 0x19, 0xa2, 0x90, 0xef,
+ 0xb0, 0x10, 0xac, 0xe6, 0xd8, 0x56, 0x8d, 0xc6,
+ 0xb8, 0x4d, 0xe6, 0x0b, 0xc4, 0x9b, 0x00, 0x4c,
+ 0x3b, 0x13, 0xed, 0xa7, 0x63, 0x58, 0x94, 0x51,
+ 0xe5, 0xdd, 0x74, 0x29, 0x28, 0x84, 0xd1, 0xbd,
+ 0xce, 0x64, 0xe6, 0xb9, 0x19, 0xdd, 0x61, 0xdc,
+ 0x9c, 0x56, 0xa2, 0x82, 0xa8, 0x1c, 0x0b, 0xd1,
+ 0x4f, 0x1f, 0x36, 0x5b, 0x49, 0xb8, 0x3a, 0x5b }
+ },
+
+ { "data-152 key-131", /* Test 7 */
+ /* Test with a key and data that is larger than 128 bytes (=
+ * block-size of SHA-384 and SHA-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",
+
+ { 0x05, 0xd8, 0xcd, 0x6d, 0x00, 0xfa, 0xea, 0x8d,
+ 0x1e, 0xb6, 0x8a, 0xde, 0x28, 0x73, 0x0b, 0xbd,
+ 0x3c, 0xba, 0xb6, 0x92, 0x9f, 0x0a, 0x08, 0x6b,
+ 0x29, 0xcd, 0x62, 0xa0 },
+ { 0x65, 0xc5, 0xb0, 0x6d, 0x4c, 0x3d, 0xe3, 0x2a,
+ 0x7a, 0xef, 0x87, 0x63, 0x26, 0x1e, 0x49, 0xad,
+ 0xb6, 0xe2, 0x29, 0x3e, 0xc8, 0xe7, 0xc6, 0x1e,
+ 0x8d, 0xe6, 0x17, 0x01, 0xfc, 0x63, 0xe1, 0x23 },
+ { 0x02, 0x6f, 0xdf, 0x6b, 0x50, 0x74, 0x1e, 0x37,
+ 0x38, 0x99, 0xc9, 0xf7, 0xd5, 0x40, 0x6d, 0x4e,
+ 0xb0, 0x9f, 0xc6, 0x66, 0x56, 0x36, 0xfc, 0x1a,
+ 0x53, 0x00, 0x29, 0xdd, 0xf5, 0xcf, 0x3c, 0xa5,
+ 0xa9, 0x00, 0xed, 0xce, 0x01, 0xf5, 0xf6, 0x1e,
+ 0x2f, 0x40, 0x8c, 0xdf, 0x2f, 0xd3, 0xe7, 0xe8 },
+ { 0x38, 0xa4, 0x56, 0xa0, 0x04, 0xbd, 0x10, 0xd3,
+ 0x2c, 0x9a, 0xb8, 0x33, 0x66, 0x84, 0x11, 0x28,
+ 0x62, 0xc3, 0xdb, 0x61, 0xad, 0xcc, 0xa3, 0x18,
+ 0x29, 0x35, 0x5e, 0xaf, 0x46, 0xfd, 0x5c, 0x73,
+ 0xd0, 0x6a, 0x1f, 0x0d, 0x13, 0xfe, 0xc9, 0xa6,
+ 0x52, 0xfb, 0x38, 0x11, 0xb5, 0x77, 0xb1, 0xb1,
+ 0xd1, 0xb9, 0x78, 0x9f, 0x97, 0xae, 0x5b, 0x83,
+ 0xc6, 0xf4, 0x4d, 0xfc, 0xf1, 0xd6, 0x7e, 0xba }
+ },
+
+ { "data-152 key-147", /* Test 7a */
+ /* Test with a key larger than 144 bytes (= block-size of
+ * 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",
+
+ { 0xc7, 0x9c, 0x9b, 0x09, 0x34, 0x24, 0xe5, 0x88,
+ 0xa9, 0x87, 0x8b, 0xbc, 0xb0, 0x89, 0xe0, 0x18,
+ 0x27, 0x00, 0x96, 0xe9, 0xb4, 0xb1, 0xa9, 0xe8,
+ 0x22, 0x0c, 0x86, 0x6a },
+ { 0xe6, 0xa3, 0x6d, 0x9b, 0x91, 0x5f, 0x86, 0xa0,
+ 0x93, 0xca, 0xc7, 0xd1, 0x10, 0xe9, 0xe0, 0x4c,
+ 0xf1, 0xd6, 0x10, 0x0d, 0x30, 0x47, 0x55, 0x09,
+ 0xc2, 0x47, 0x5f, 0x57, 0x1b, 0x75, 0x8b, 0x5a },
+ { 0xca, 0xd1, 0x8a, 0x8f, 0xf6, 0xc4, 0xcc, 0x3a,
+ 0xd4, 0x87, 0xb9, 0x5f, 0x97, 0x69, 0xe9, 0xb6,
+ 0x1c, 0x06, 0x2a, 0xef, 0xd6, 0x95, 0x25, 0x69,
+ 0xe6, 0xe6, 0x42, 0x18, 0x97, 0x05, 0x4c, 0xfc,
+ 0x70, 0xb5, 0xfd, 0xc6, 0x60, 0x5c, 0x18, 0x45,
+ 0x71, 0x12, 0xfc, 0x6a, 0xaa, 0xd4, 0x55, 0x85 },
+ { 0xdc, 0x03, 0x0e, 0xe7, 0x88, 0x70, 0x34, 0xf3,
+ 0x2c, 0xf4, 0x02, 0xdf, 0x34, 0x62, 0x2f, 0x31,
+ 0x1f, 0x3e, 0x6c, 0xf0, 0x48, 0x60, 0xc6, 0xbb,
+ 0xd7, 0xfa, 0x48, 0x86, 0x74, 0x78, 0x2b, 0x46,
+ 0x59, 0xfd, 0xbd, 0xf3, 0xfd, 0x87, 0x78, 0x52,
+ 0x88, 0x5c, 0xfe, 0x6e, 0x22, 0x18, 0x5f, 0xe7,
+ 0xb2, 0xee, 0x95, 0x20, 0x43, 0x62, 0x9b, 0xc9,
+ 0xd5, 0xf3, 0x29, 0x8a, 0x41, 0xd0, 0x2c, 0x66 }
+ }/*,*/
+
+ /* Our API does not allow to specify a bit count and thus we
+ * can't use the following test. */
+ /* { "data-5bit key-4", /\* Test 8 *\/ */
+ /* /\* Test with data bit size no multiple of 8, the data bits are */
+ /* * '11001' from the NIST example using SHA-3 order (= 5 bits */
+ /* * from LSB hex byte 13 or 5 bits from MSB hex byte c8). *\/ */
+ /* "\xc8", */
+ /* "Jefe", */
+
+ /* { 0x5f, 0x8c, 0x0e, 0xa7, 0xfa, 0xfe, 0xcd, 0x0c, */
+ /* 0x34, 0x63, 0xaa, 0xd0, 0x97, 0x42, 0xce, 0xce, */
+ /* 0xb1, 0x42, 0xfe, 0x0a, 0xb6, 0xf4, 0x53, 0x94, */
+ /* 0x38, 0xc5, 0x9d, 0xe8 }, */
+ /* { 0xec, 0x82, 0x22, 0x77, 0x3f, 0xac, 0x68, 0xb3, */
+ /* 0xd3, 0xdc, 0xb1, 0x82, 0xae, 0xc8, 0xb0, 0x50, */
+ /* 0x7a, 0xce, 0x44, 0x48, 0xd2, 0x0a, 0x11, 0x47, */
+ /* 0xe6, 0x82, 0x11, 0x8d, 0xa4, 0xe3, 0xf4, 0x4c }, */
+ /* { 0x21, 0xfb, 0xd3, 0xbf, 0x3e, 0xbb, 0xa3, 0xcf, */
+ /* 0xc9, 0xef, 0x64, 0xc0, 0x59, 0x1c, 0x92, 0xc5, */
+ /* 0xac, 0xb2, 0x65, 0xe9, 0x2d, 0x87, 0x61, 0xd1, */
+ /* 0xf9, 0x1a, 0x52, 0xa1, 0x03, 0xa6, 0xc7, 0x96, */
+ /* 0x94, 0xcf, 0xd6, 0x7a, 0x9a, 0x2a, 0xc1, 0x32, */
+ /* 0x4f, 0x02, 0xfe, 0xa6, 0x3b, 0x81, 0xef, 0xfc }, */
+ /* { 0x27, 0xf9, 0x38, 0x8c, 0x15, 0x67, 0xef, 0x4e, */
+ /* 0xf2, 0x00, 0x60, 0x2a, 0x6c, 0xf8, 0x71, 0xd6, */
+ /* 0x8a, 0x6f, 0xb0, 0x48, 0xd4, 0x73, 0x7a, 0xc4, */
+ /* 0x41, 0x8a, 0x2f, 0x02, 0x12, 0x89, 0xd1, 0x3d, */
+ /* 0x1f, 0xd1, 0x12, 0x0f, 0xec, 0xb9, 0xcf, 0x96, */
+ /* 0x4c, 0x5b, 0x11, 0x7a, 0xb5, 0xb1, 0x1c, 0x61, */
+ /* 0x4b, 0x2d, 0xa3, 0x9d, 0xad, 0xd5, 0x1f, 0x2f, */
+ /* 0x5e, 0x22, 0xaa, 0xcc, 0xec, 0x7d, 0x57, 0x6e } */
+ /* } */
+
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+ const char *expect;
+ int nexpect;
+
+ for (tvidx=0; tvidx < DIM(tv); tvidx++)
+ {
+ what = tv[tvidx].desc;
+ if (hashalgo == GCRY_MD_SHA3_224)
+ {
+ expect = tv[tvidx].expect_224;
+ nexpect = DIM (tv[tvidx].expect_224);
+ }
+ else if (hashalgo == GCRY_MD_SHA3_256)
+ {
+ expect = tv[tvidx].expect_256;
+ nexpect = DIM (tv[tvidx].expect_256);
+ }
+ else if (hashalgo == GCRY_MD_SHA3_384)
+ {
+ expect = tv[tvidx].expect_384;
+ nexpect = DIM (tv[tvidx].expect_384);
+ }
+ else if (hashalgo == GCRY_MD_SHA3_512)
+ {
+ expect = tv[tvidx].expect_512;
+ nexpect = DIM (tv[tvidx].expect_512);
+ }
+ else
+ BUG();
+
+ if (tv[tvidx].trunc && tv[tvidx].trunc < nexpect)
+ nexpect = tv[tvidx].trunc;
+
+ errtxt = check_one (hashalgo,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ expect, nexpect, !!tv[tvidx].trunc);
+ if (errtxt)
+ goto failed;
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", hashalgo, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+hmac_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_MAC_HMAC_SHA1:
+ ec = selftests_sha1 (extended, report);
+ break;
+ case GCRY_MAC_HMAC_SHA224:
+ ec = selftests_sha224 (extended, report);
+ break;
+ case GCRY_MAC_HMAC_SHA256:
+ ec = selftests_sha256 (extended, report);
+ break;
+ case GCRY_MAC_HMAC_SHA384:
+ ec = selftests_sha384 (extended, report);
+ break;
+ case GCRY_MAC_HMAC_SHA512:
+ ec = selftests_sha512 (extended, report);
+ break;
+
+ case GCRY_MAC_HMAC_SHA3_224:
+ case GCRY_MAC_HMAC_SHA3_256:
+ case GCRY_MAC_HMAC_SHA3_384:
+ case GCRY_MAC_HMAC_SHA3_512:
+ {
+ int md_algo = map_mac_algo_to_md (algo);
+ ec = selftests_sha3 (md_algo, extended, report);
+ }
+ break;
+
+ default:
+ ec = GPG_ERR_MAC_ALGO;
+ break;
+ }
+
+ return ec;
+}
+
+
+static const gcry_mac_spec_ops_t hmac_ops = {
+ hmac_open,
+ hmac_close,
+ hmac_setkey,
+ NULL,
+ hmac_reset,
+ hmac_write,
+ hmac_read,
+ hmac_verify,
+ hmac_get_maclen,
+ hmac_get_keylen,
+ NULL,
+ hmac_selftest
+};
+
+
+#if USE_SHA1
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha1 = {
+ GCRY_MAC_HMAC_SHA1, {0, 1}, "HMAC_SHA1",
+ &hmac_ops
+};
+#endif
+#if USE_SHA256
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha256 = {
+ GCRY_MAC_HMAC_SHA256, {0, 1}, "HMAC_SHA256",
+ &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha224 = {
+ GCRY_MAC_HMAC_SHA224, {0, 1}, "HMAC_SHA224",
+ &hmac_ops
+};
+#endif
+#if USE_SHA512
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512 = {
+ GCRY_MAC_HMAC_SHA512, {0, 1}, "HMAC_SHA512",
+ &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha384 = {
+ GCRY_MAC_HMAC_SHA384, {0, 1}, "HMAC_SHA384",
+ &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512_256 = {
+ GCRY_MAC_HMAC_SHA512_256, {0, 1}, "HMAC_SHA512_256",
+ &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512_224 = {
+ GCRY_MAC_HMAC_SHA512_224, {0, 1}, "HMAC_SHA512_224",
+ &hmac_ops
+};
+
+#endif
+#if USE_SHA3
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_224 = {
+ GCRY_MAC_HMAC_SHA3_224, {0, 1}, "HMAC_SHA3_224",
+ &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_256 = {
+ GCRY_MAC_HMAC_SHA3_256, {0, 1}, "HMAC_SHA3_256",
+ &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_384 = {
+ GCRY_MAC_HMAC_SHA3_384, {0, 1}, "HMAC_SHA3_384",
+ &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_512 = {
+ GCRY_MAC_HMAC_SHA3_512, {0, 1}, "HMAC_SHA3_512",
+ &hmac_ops
+};
+#endif
+#ifdef USE_GOST_R_3411_94
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_94 = {
+ GCRY_MAC_HMAC_GOSTR3411_94, {0, 0}, "HMAC_GOSTR3411_94",
+ &hmac_ops
+};
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_cp = {
+ GCRY_MAC_HMAC_GOSTR3411_CP, {0, 0}, "HMAC_GOSTR3411_CP",
+ &hmac_ops
+};
+#endif
+#ifdef USE_GOST_R_3411_12
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog256 = {
+ GCRY_MAC_HMAC_STRIBOG256, {0, 0}, "HMAC_STRIBOG256",
+ &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog512 = {
+ GCRY_MAC_HMAC_STRIBOG512, {0, 0}, "HMAC_STRIBOG512",
+ &hmac_ops
+};
+#endif
+#if USE_WHIRLPOOL
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_whirlpool = {
+ GCRY_MAC_HMAC_WHIRLPOOL, {0, 0}, "HMAC_WHIRLPOOL",
+ &hmac_ops
+};
+#endif
+#if USE_RMD160
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_rmd160 = {
+ GCRY_MAC_HMAC_RMD160, {0, 0}, "HMAC_RIPEMD160",
+ &hmac_ops
+};
+#endif
+#if USE_TIGER
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_tiger1 = {
+ GCRY_MAC_HMAC_TIGER1, {0, 0}, "HMAC_TIGER",
+ &hmac_ops
+};
+#endif
+#if USE_MD5
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_md5 = {
+ GCRY_MAC_HMAC_MD5, {0, 0}, "HMAC_MD5",
+ &hmac_ops
+};
+#endif
+#if USE_MD4
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_md4 = {
+ GCRY_MAC_HMAC_MD4, {0, 0}, "HMAC_MD4",
+ &hmac_ops
+};
+#endif
+#if USE_MD2
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_md2 = {
+ GCRY_MAC_HMAC_MD2, {0, 0}, "HMAC_MD2",
+ &hmac_ops
+};
+#endif
+#if USE_BLAKE2
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2b_512 = {
+ GCRY_MAC_HMAC_BLAKE2B_512, {0, 0}, "HMAC_BLAKE2B_512",
+ &hmac_ops
+};
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2b_384 = {
+ GCRY_MAC_HMAC_BLAKE2B_384, {0, 0}, "HMAC_BLAKE2B_384",
+ &hmac_ops
+};
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2b_256 = {
+ GCRY_MAC_HMAC_BLAKE2B_256, {0, 0}, "HMAC_BLAKE2B_256",
+ &hmac_ops
+};
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2b_160 = {
+ GCRY_MAC_HMAC_BLAKE2B_160, {0, 0}, "HMAC_BLAKE2B_160",
+ &hmac_ops
+};
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2s_256 = {
+ GCRY_MAC_HMAC_BLAKE2S_256, {0, 0}, "HMAC_BLAKE2S_256",
+ &hmac_ops
+};
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2s_224 = {
+ GCRY_MAC_HMAC_BLAKE2S_224, {0, 0}, "HMAC_BLAKE2S_224",
+ &hmac_ops
+};
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2s_160 = {
+ GCRY_MAC_HMAC_BLAKE2S_160, {0, 0}, "HMAC_BLAKE2S_160",
+ &hmac_ops
+};
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2s_128 = {
+ GCRY_MAC_HMAC_BLAKE2S_128, {0, 0}, "HMAC_BLAKE2S_128",
+ &hmac_ops
+};
+#endif
+#if USE_SM3
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sm3 = {
+ GCRY_MAC_HMAC_SM3, {0, 0}, "HMAC_SM3",
+ &hmac_ops
+};
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/mac-internal.h b/comm/third_party/libgcrypt/cipher/mac-internal.h
new file mode 100644
index 0000000000..e49885beec
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/mac-internal.h
@@ -0,0 +1,275 @@
+/* mac-internal.h - Internal defs for mac.c
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "g10lib.h"
+#include "cipher-proto.h"
+#include "gost.h"
+
+
+/* The data object used to hold a handle to an encryption object. */
+struct gcry_mac_handle;
+
+/* The data object used to hold poly1305-mac context. */
+struct poly1305mac_context_s;
+
+
+/*
+ *
+ * Message authentication code related definitions.
+ *
+ */
+
+
+/* Magic values for the context structure. */
+#define CTX_MAC_MAGIC_NORMAL 0x59d9b8af
+#define CTX_MAC_MAGIC_SECURE 0x12c27cd0
+
+
+/* MAC module functions. */
+typedef gcry_err_code_t (*gcry_mac_open_func_t)(gcry_mac_hd_t h);
+typedef void (*gcry_mac_close_func_t)(gcry_mac_hd_t h);
+typedef gcry_err_code_t (*gcry_mac_setkey_func_t)(gcry_mac_hd_t h,
+ const unsigned char *key,
+ size_t keylen);
+typedef gcry_err_code_t (*gcry_mac_setiv_func_t)(gcry_mac_hd_t h,
+ const unsigned char *iv,
+ size_t ivlen);
+typedef gcry_err_code_t (*gcry_mac_reset_func_t)(gcry_mac_hd_t h);
+typedef gcry_err_code_t (*gcry_mac_write_func_t)(gcry_mac_hd_t h,
+ const unsigned char *inbuf,
+ size_t inlen);
+typedef gcry_err_code_t (*gcry_mac_read_func_t)(gcry_mac_hd_t h,
+ unsigned char *outbuf,
+ size_t *outlen);
+typedef gcry_err_code_t (*gcry_mac_verify_func_t)(gcry_mac_hd_t h,
+ const unsigned char *inbuf,
+ size_t inlen);
+typedef unsigned int (*gcry_mac_get_maclen_func_t)(int algo);
+typedef unsigned int (*gcry_mac_get_keylen_func_t)(int algo);
+
+/* The type used to convey additional information to a MAC. */
+typedef gpg_err_code_t (*gcry_mac_set_extra_info_t)
+ (gcry_mac_hd_t h, int what, const void *buffer, size_t buflen);
+
+typedef struct gcry_mac_spec_ops
+{
+ gcry_mac_open_func_t open;
+ gcry_mac_close_func_t close;
+ gcry_mac_setkey_func_t setkey;
+ gcry_mac_setiv_func_t setiv;
+ gcry_mac_reset_func_t reset;
+ gcry_mac_write_func_t write;
+ gcry_mac_read_func_t read;
+ gcry_mac_verify_func_t verify;
+ gcry_mac_get_maclen_func_t get_maclen;
+ gcry_mac_get_keylen_func_t get_keylen;
+ gcry_mac_set_extra_info_t set_extra_info;
+ selftest_func_t selftest;
+} gcry_mac_spec_ops_t;
+
+
+/* Module specification structure for message authentication codes. */
+typedef struct gcry_mac_spec
+{
+ int algo;
+ struct {
+ unsigned int disabled:1;
+ unsigned int fips:1;
+ } flags;
+ const char *name;
+ const gcry_mac_spec_ops_t *ops;
+} gcry_mac_spec_t;
+
+/* The handle structure. */
+struct gcry_mac_handle
+{
+ int magic;
+ int algo;
+ const gcry_mac_spec_t *spec;
+ gcry_ctx_t gcry_ctx;
+ union {
+ struct {
+ gcry_md_hd_t md_ctx;
+ int md_algo;
+ } hmac;
+ struct {
+ gcry_cipher_hd_t ctx;
+ int cipher_algo;
+ unsigned int blklen;
+ } cmac;
+ struct {
+ gcry_cipher_hd_t ctx;
+ int cipher_algo;
+ } gmac;
+ struct {
+ struct poly1305mac_context_s *ctx;
+ } poly1305mac;
+ struct {
+ GOST28147_context ctx;
+ u32 n1, n2;
+ unsigned int unused;
+ unsigned int count;
+ unsigned char lastiv[8]; /* IMIT blocksize */
+ } imit;
+ } u;
+};
+
+
+/*
+ * The HMAC algorithm specifications (mac-hmac.c).
+ */
+#if USE_SHA1
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha1;
+#endif
+#if USE_SHA256
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha256;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha224;
+#endif
+#if USE_SHA512
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha384;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512_224;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512_256;
+#endif
+#if USE_SHA3
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_224;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_256;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_384;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_512;
+#endif
+#ifdef USE_GOST_R_3411_94
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_94;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_cp;
+#endif
+#ifdef USE_GOST_R_3411_12
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog256;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog512;
+#endif
+#if USE_WHIRLPOOL
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_whirlpool;
+#endif
+#if USE_RMD160
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_rmd160;
+#endif
+#if USE_TIGER
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_tiger1;
+#endif
+#if USE_MD5
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_md5;
+#endif
+#if USE_MD4
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_md4;
+#endif
+#if USE_BLAKE2
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2b_512;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2b_384;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2b_256;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2b_160;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2s_256;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2s_224;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2s_160;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_blake2s_128;
+#endif
+#if USE_SM3
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sm3;
+#endif
+
+/*
+ * The CMAC algorithm specifications (mac-cmac.c).
+ */
+#if USE_BLOWFISH
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_blowfish;
+#endif
+#if USE_DES
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_tripledes;
+#endif
+#if USE_CAST5
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_cast5;
+#endif
+#if USE_AES
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_aes;
+#endif
+#if USE_TWOFISH
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_twofish;
+#endif
+#if USE_SERPENT
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_serpent;
+#endif
+#if USE_RFC2268
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_rfc2268;
+#endif
+#if USE_SEED
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_seed;
+#endif
+#if USE_CAMELLIA
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_camellia;
+#endif
+#ifdef USE_IDEA
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_idea;
+#endif
+#if USE_GOST28147
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_gost28147;
+#endif
+#if USE_GOST28147
+extern gcry_mac_spec_t _gcry_mac_type_spec_gost28147_imit;
+#endif
+#if USE_SM4
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_sm4;
+#endif
+
+/*
+ * The GMAC algorithm specifications (mac-gmac.c).
+ */
+#if USE_AES
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes;
+#endif
+#if USE_TWOFISH
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_twofish;
+#endif
+#if USE_SERPENT
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_serpent;
+#endif
+#if USE_SEED
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed;
+#endif
+#if USE_CAMELLIA
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia;
+#endif
+
+/*
+ * The Poly1305 MAC algorithm specifications (mac-poly1305.c).
+ */
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac;
+#if USE_AES
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_aes;
+#endif
+#if USE_CAMELLIA
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_camellia;
+#endif
+#if USE_TWOFISH
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_twofish;
+#endif
+#if USE_SERPENT
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_serpent;
+#endif
+#if USE_SEED
+extern gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_seed;
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/mac-poly1305.c b/comm/third_party/libgcrypt/cipher/mac-poly1305.c
new file mode 100644
index 0000000000..46ea735f89
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/mac-poly1305.c
@@ -0,0 +1,364 @@
+/* mac-poly1305.c - Poly1305 based MACs
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mac-internal.h"
+#include "poly1305-internal.h"
+
+
+struct poly1305mac_context_s {
+ poly1305_context_t ctx;
+ gcry_cipher_hd_t hd;
+ struct {
+ unsigned int key_set:1;
+ unsigned int nonce_set:1;
+ unsigned int tag:1;
+ } marks;
+ byte tag[POLY1305_TAGLEN];
+ byte key[POLY1305_KEYLEN];
+};
+
+
+static gcry_err_code_t
+poly1305mac_open (gcry_mac_hd_t h)
+{
+ struct poly1305mac_context_s *mac_ctx;
+ int secure = (h->magic == CTX_MAC_MAGIC_SECURE);
+ unsigned int flags = (secure ? GCRY_CIPHER_SECURE : 0);
+ gcry_err_code_t err;
+ int cipher_algo;
+
+ if (secure)
+ mac_ctx = xtrycalloc_secure (1, sizeof(*mac_ctx));
+ else
+ mac_ctx = xtrycalloc (1, sizeof(*mac_ctx));
+
+ if (!mac_ctx)
+ return gpg_err_code_from_syserror ();
+
+ h->u.poly1305mac.ctx = mac_ctx;
+
+ switch (h->spec->algo)
+ {
+ default:
+ /* already checked. */
+ case GCRY_MAC_POLY1305:
+ /* plain Poly1305. */
+ cipher_algo = -1;
+ return 0;
+ case GCRY_MAC_POLY1305_AES:
+ cipher_algo = GCRY_CIPHER_AES;
+ break;
+ case GCRY_MAC_POLY1305_CAMELLIA:
+ cipher_algo = GCRY_CIPHER_CAMELLIA128;
+ break;
+ case GCRY_MAC_POLY1305_TWOFISH:
+ cipher_algo = GCRY_CIPHER_TWOFISH;
+ break;
+ case GCRY_MAC_POLY1305_SERPENT:
+ cipher_algo = GCRY_CIPHER_SERPENT128;
+ break;
+ case GCRY_MAC_POLY1305_SEED:
+ cipher_algo = GCRY_CIPHER_SEED;
+ break;
+ }
+
+ err = _gcry_cipher_open_internal (&mac_ctx->hd, cipher_algo,
+ GCRY_CIPHER_MODE_ECB, flags);
+ if (err)
+ goto err_free;
+
+ return 0;
+
+err_free:
+ xfree(h->u.poly1305mac.ctx);
+ return err;
+}
+
+
+static void
+poly1305mac_close (gcry_mac_hd_t h)
+{
+ struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+
+ if (h->spec->algo != GCRY_MAC_POLY1305)
+ _gcry_cipher_close (mac_ctx->hd);
+
+ xfree(mac_ctx);
+}
+
+
+static gcry_err_code_t
+poly1305mac_prepare_key (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+ struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+ size_t block_keylen = keylen - 16;
+
+ /* Need at least 16 + 1 byte key. */
+ if (keylen <= 16)
+ return GPG_ERR_INV_KEYLEN;
+
+ /* For Poly1305-AES, first part of key is passed to Poly1305 as is. */
+ memcpy (mac_ctx->key, key + block_keylen, 16);
+
+ /* Remaining part is used as key for the block cipher. */
+ return _gcry_cipher_setkey (mac_ctx->hd, key, block_keylen);
+}
+
+
+static gcry_err_code_t
+poly1305mac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+ struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+ gcry_err_code_t err;
+
+ memset(&mac_ctx->ctx, 0, sizeof(mac_ctx->ctx));
+ memset(&mac_ctx->tag, 0, sizeof(mac_ctx->tag));
+ memset(&mac_ctx->key, 0, sizeof(mac_ctx->key));
+
+ mac_ctx->marks.key_set = 0;
+ mac_ctx->marks.nonce_set = 0;
+ mac_ctx->marks.tag = 0;
+
+ if (h->spec->algo != GCRY_MAC_POLY1305)
+ {
+ err = poly1305mac_prepare_key (h, key, keylen);
+ if (err)
+ return err;
+
+ /* Poly1305-AES/etc also need nonce. */
+ mac_ctx->marks.key_set = 1;
+ mac_ctx->marks.nonce_set = 0;
+ }
+ else
+ {
+ /* For plain Poly1305, key is the nonce and setup is complete now. */
+
+ if (keylen != POLY1305_KEYLEN)
+ return GPG_ERR_INV_KEYLEN;
+
+ memcpy (mac_ctx->key, key, keylen);
+
+ err = _gcry_poly1305_init (&mac_ctx->ctx, mac_ctx->key, POLY1305_KEYLEN);
+ if (err)
+ {
+ memset(&mac_ctx->key, 0, sizeof(mac_ctx->key));
+ return err;
+ }
+
+ mac_ctx->marks.key_set = 1;
+ mac_ctx->marks.nonce_set = 1;
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+poly1305mac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen)
+{
+ struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+ gcry_err_code_t err;
+
+ if (h->spec->algo == GCRY_MAC_POLY1305)
+ return GPG_ERR_INV_ARG;
+
+ if (ivlen != 16)
+ return GPG_ERR_INV_ARG;
+
+ if (!mac_ctx->marks.key_set)
+ return 0;
+
+ memset(&mac_ctx->ctx, 0, sizeof(mac_ctx->ctx));
+ memset(&mac_ctx->tag, 0, sizeof(mac_ctx->tag));
+ mac_ctx->marks.nonce_set = 0;
+ mac_ctx->marks.tag = 0;
+
+ /* Prepare second part of the poly1305 key. */
+
+ err = _gcry_cipher_encrypt (mac_ctx->hd, mac_ctx->key + 16, 16, iv, 16);
+ if (err)
+ return err;
+
+ err = _gcry_poly1305_init (&mac_ctx->ctx, mac_ctx->key, POLY1305_KEYLEN);
+ if (err)
+ return err;
+
+ mac_ctx->marks.nonce_set = 1;
+ return 0;
+}
+
+
+static gcry_err_code_t
+poly1305mac_reset (gcry_mac_hd_t h)
+{
+ struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+
+ if (!mac_ctx->marks.key_set || !mac_ctx->marks.nonce_set)
+ return GPG_ERR_INV_STATE;
+
+ memset(&mac_ctx->ctx, 0, sizeof(mac_ctx->ctx));
+ memset(&mac_ctx->tag, 0, sizeof(mac_ctx->tag));
+
+ mac_ctx->marks.key_set = 1;
+ mac_ctx->marks.nonce_set = 1;
+ mac_ctx->marks.tag = 0;
+
+ return _gcry_poly1305_init (&mac_ctx->ctx, mac_ctx->key, POLY1305_KEYLEN);
+}
+
+
+static gcry_err_code_t
+poly1305mac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+
+ if (!mac_ctx->marks.key_set || !mac_ctx->marks.nonce_set ||
+ mac_ctx->marks.tag)
+ return GPG_ERR_INV_STATE;
+
+ _gcry_poly1305_update (&mac_ctx->ctx, buf, buflen);
+ return 0;
+}
+
+
+static gcry_err_code_t
+poly1305mac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t *outlen)
+{
+ struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+
+ if (!mac_ctx->marks.key_set || !mac_ctx->marks.nonce_set)
+ return GPG_ERR_INV_STATE;
+
+ if (!mac_ctx->marks.tag)
+ {
+ _gcry_poly1305_finish(&mac_ctx->ctx, mac_ctx->tag);
+
+ memset(&mac_ctx->ctx, 0, sizeof(mac_ctx->ctx));
+ mac_ctx->marks.tag = 1;
+ }
+
+ if (*outlen == 0)
+ return 0;
+
+ if (*outlen <= POLY1305_TAGLEN)
+ buf_cpy (outbuf, mac_ctx->tag, *outlen);
+ else
+ {
+ buf_cpy (outbuf, mac_ctx->tag, POLY1305_TAGLEN);
+ *outlen = POLY1305_TAGLEN;
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+poly1305mac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+ struct poly1305mac_context_s *mac_ctx = h->u.poly1305mac.ctx;
+ gcry_err_code_t err;
+ size_t outlen = 0;
+
+ /* Check and finalize tag. */
+ err = poly1305mac_read(h, NULL, &outlen);
+ if (err)
+ return err;
+
+ if (buflen > POLY1305_TAGLEN)
+ return GPG_ERR_INV_LENGTH;
+
+ return buf_eq_const (buf, mac_ctx->tag, buflen) ? 0 : GPG_ERR_CHECKSUM;
+}
+
+
+static unsigned int
+poly1305mac_get_maclen (int algo)
+{
+ (void)algo;
+
+ return POLY1305_TAGLEN;
+}
+
+
+static unsigned int
+poly1305mac_get_keylen (int algo)
+{
+ (void)algo;
+
+ return POLY1305_KEYLEN;
+}
+
+
+static gcry_mac_spec_ops_t poly1305mac_ops = {
+ poly1305mac_open,
+ poly1305mac_close,
+ poly1305mac_setkey,
+ poly1305mac_setiv,
+ poly1305mac_reset,
+ poly1305mac_write,
+ poly1305mac_read,
+ poly1305mac_verify,
+ poly1305mac_get_maclen,
+ poly1305mac_get_keylen,
+ NULL,
+ NULL,
+};
+
+
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac = {
+ GCRY_MAC_POLY1305, {0, 0}, "POLY1305",
+ &poly1305mac_ops
+};
+#if USE_AES
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_aes = {
+ GCRY_MAC_POLY1305_AES, {0, 0}, "POLY1305_AES",
+ &poly1305mac_ops
+};
+#endif
+#if USE_CAMELLIA
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_camellia = {
+ GCRY_MAC_POLY1305_CAMELLIA, {0, 0}, "POLY1305_CAMELLIA",
+ &poly1305mac_ops
+};
+#endif
+#if USE_TWOFISH
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_twofish = {
+ GCRY_MAC_POLY1305_TWOFISH, {0, 0}, "POLY1305_TWOFISH",
+ &poly1305mac_ops
+};
+#endif
+#if USE_SERPENT
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_serpent = {
+ GCRY_MAC_POLY1305_SERPENT, {0, 0}, "POLY1305_SERPENT",
+ &poly1305mac_ops
+};
+#endif
+#if USE_SEED
+gcry_mac_spec_t _gcry_mac_type_spec_poly1305mac_seed = {
+ GCRY_MAC_POLY1305_SEED, {0, 0}, "POLY1305_SEED",
+ &poly1305mac_ops
+};
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/mac.c b/comm/third_party/libgcrypt/cipher/mac.c
new file mode 100644
index 0000000000..babe99e3a8
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/mac.c
@@ -0,0 +1,808 @@
+/* mac.c - message authentication code dispatcher
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mac-internal.h"
+
+
+/* This is the list of the digest implementations included in
+ libgcrypt. */
+static gcry_mac_spec_t * const mac_list[] = {
+#if USE_SHA1
+ &_gcry_mac_type_spec_hmac_sha1,
+#endif
+#if USE_SHA256
+ &_gcry_mac_type_spec_hmac_sha256,
+ &_gcry_mac_type_spec_hmac_sha224,
+#endif
+#if USE_SHA512
+ &_gcry_mac_type_spec_hmac_sha512,
+ &_gcry_mac_type_spec_hmac_sha384,
+ &_gcry_mac_type_spec_hmac_sha512_256,
+ &_gcry_mac_type_spec_hmac_sha512_224,
+#endif
+#if USE_SHA3
+ &_gcry_mac_type_spec_hmac_sha3_224,
+ &_gcry_mac_type_spec_hmac_sha3_256,
+ &_gcry_mac_type_spec_hmac_sha3_384,
+ &_gcry_mac_type_spec_hmac_sha3_512,
+#endif
+#ifdef USE_GOST_R_3411_94
+ &_gcry_mac_type_spec_hmac_gost3411_94,
+ &_gcry_mac_type_spec_hmac_gost3411_cp,
+#endif
+#ifdef USE_GOST_R_3411_12
+ &_gcry_mac_type_spec_hmac_stribog256,
+ &_gcry_mac_type_spec_hmac_stribog512,
+#endif
+#if USE_WHIRLPOOL
+ &_gcry_mac_type_spec_hmac_whirlpool,
+#endif
+#if USE_RMD160
+ &_gcry_mac_type_spec_hmac_rmd160,
+#endif
+#if USE_TIGER
+ &_gcry_mac_type_spec_hmac_tiger1,
+#endif
+#if USE_MD5
+ &_gcry_mac_type_spec_hmac_md5,
+#endif
+#if USE_MD4
+ &_gcry_mac_type_spec_hmac_md4,
+#endif
+#if USE_BLAKE2
+ &_gcry_mac_type_spec_hmac_blake2b_512,
+ &_gcry_mac_type_spec_hmac_blake2b_384,
+ &_gcry_mac_type_spec_hmac_blake2b_256,
+ &_gcry_mac_type_spec_hmac_blake2b_160,
+ &_gcry_mac_type_spec_hmac_blake2s_256,
+ &_gcry_mac_type_spec_hmac_blake2s_224,
+ &_gcry_mac_type_spec_hmac_blake2s_160,
+ &_gcry_mac_type_spec_hmac_blake2s_128,
+#endif
+#if USE_SM3
+ &_gcry_mac_type_spec_hmac_sm3,
+#endif
+#if USE_BLOWFISH
+ &_gcry_mac_type_spec_cmac_blowfish,
+#endif
+#if USE_DES
+ &_gcry_mac_type_spec_cmac_tripledes,
+#endif
+#if USE_CAST5
+ &_gcry_mac_type_spec_cmac_cast5,
+#endif
+#if USE_AES
+ &_gcry_mac_type_spec_cmac_aes,
+ &_gcry_mac_type_spec_gmac_aes,
+ &_gcry_mac_type_spec_poly1305mac_aes,
+#endif
+#if USE_TWOFISH
+ &_gcry_mac_type_spec_cmac_twofish,
+ &_gcry_mac_type_spec_gmac_twofish,
+ &_gcry_mac_type_spec_poly1305mac_twofish,
+#endif
+#if USE_SERPENT
+ &_gcry_mac_type_spec_cmac_serpent,
+ &_gcry_mac_type_spec_gmac_serpent,
+ &_gcry_mac_type_spec_poly1305mac_serpent,
+#endif
+#if USE_RFC2268
+ &_gcry_mac_type_spec_cmac_rfc2268,
+#endif
+#if USE_SEED
+ &_gcry_mac_type_spec_cmac_seed,
+ &_gcry_mac_type_spec_gmac_seed,
+ &_gcry_mac_type_spec_poly1305mac_seed,
+#endif
+#if USE_CAMELLIA
+ &_gcry_mac_type_spec_cmac_camellia,
+ &_gcry_mac_type_spec_gmac_camellia,
+ &_gcry_mac_type_spec_poly1305mac_camellia,
+#endif
+#ifdef USE_IDEA
+ &_gcry_mac_type_spec_cmac_idea,
+#endif
+#if USE_GOST28147
+ &_gcry_mac_type_spec_cmac_gost28147,
+ &_gcry_mac_type_spec_gost28147_imit,
+#endif
+ &_gcry_mac_type_spec_poly1305mac,
+#if USE_SM4
+ &_gcry_mac_type_spec_cmac_sm4,
+#endif
+ NULL,
+};
+
+/* HMAC implementations start with index 101 (enum gcry_mac_algos) */
+static gcry_mac_spec_t * const mac_list_algo101[] =
+ {
+#if USE_SHA256
+ &_gcry_mac_type_spec_hmac_sha256,
+ &_gcry_mac_type_spec_hmac_sha224,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_SHA512
+ &_gcry_mac_type_spec_hmac_sha512,
+ &_gcry_mac_type_spec_hmac_sha384,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_SHA1
+ &_gcry_mac_type_spec_hmac_sha1,
+#else
+ NULL,
+#endif
+#if USE_MD5
+ &_gcry_mac_type_spec_hmac_md5,
+#else
+ NULL,
+#endif
+#if USE_MD4
+ &_gcry_mac_type_spec_hmac_md4,
+#else
+ NULL,
+#endif
+#if USE_RMD160
+ &_gcry_mac_type_spec_hmac_rmd160,
+#else
+ NULL,
+#endif
+#if USE_TIGER
+ &_gcry_mac_type_spec_hmac_tiger1,
+#else
+ NULL,
+#endif
+#if USE_WHIRLPOOL
+ &_gcry_mac_type_spec_hmac_whirlpool,
+#else
+ NULL,
+#endif
+#ifdef USE_GOST_R_3411_94
+ &_gcry_mac_type_spec_hmac_gost3411_94,
+#else
+ NULL,
+#endif
+#ifdef USE_GOST_R_3411_12
+ &_gcry_mac_type_spec_hmac_stribog256,
+ &_gcry_mac_type_spec_hmac_stribog512,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_MD2
+ &_gcry_mac_type_spec_hmac_md2,
+#else
+ NULL,
+#endif
+#if USE_SHA3
+ &_gcry_mac_type_spec_hmac_sha3_224,
+ &_gcry_mac_type_spec_hmac_sha3_256,
+ &_gcry_mac_type_spec_hmac_sha3_384,
+ &_gcry_mac_type_spec_hmac_sha3_512,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
+#ifdef USE_GOST_R_3411_94
+ &_gcry_mac_type_spec_hmac_gost3411_cp,
+#else
+ NULL,
+#endif
+#if USE_BLAKE2
+ &_gcry_mac_type_spec_hmac_blake2b_512,
+ &_gcry_mac_type_spec_hmac_blake2b_384,
+ &_gcry_mac_type_spec_hmac_blake2b_256,
+ &_gcry_mac_type_spec_hmac_blake2b_160,
+ &_gcry_mac_type_spec_hmac_blake2s_256,
+ &_gcry_mac_type_spec_hmac_blake2s_224,
+ &_gcry_mac_type_spec_hmac_blake2s_160,
+ &_gcry_mac_type_spec_hmac_blake2s_128,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_SM3
+ &_gcry_mac_type_spec_hmac_sm3,
+#else
+ NULL,
+#endif
+#if USE_SHA512
+ &_gcry_mac_type_spec_hmac_sha512_256,
+ &_gcry_mac_type_spec_hmac_sha512_224,
+#else
+ NULL,
+ NULL,
+#endif
+ };
+
+/* CMAC implementations start with index 201 (enum gcry_mac_algos) */
+static gcry_mac_spec_t * const mac_list_algo201[] =
+ {
+#if USE_AES
+ &_gcry_mac_type_spec_cmac_aes,
+#else
+ NULL,
+#endif
+#if USE_DES
+ &_gcry_mac_type_spec_cmac_tripledes,
+#else
+ NULL,
+#endif
+#if USE_CAMELLIA
+ &_gcry_mac_type_spec_cmac_camellia,
+#else
+ NULL,
+#endif
+#if USE_CAST5
+ &_gcry_mac_type_spec_cmac_cast5,
+#else
+ NULL,
+#endif
+#if USE_BLOWFISH
+ &_gcry_mac_type_spec_cmac_blowfish,
+#else
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_mac_type_spec_cmac_twofish,
+#else
+ NULL,
+#endif
+#if USE_SERPENT
+ &_gcry_mac_type_spec_cmac_serpent,
+#else
+ NULL,
+#endif
+#if USE_SEED
+ &_gcry_mac_type_spec_cmac_seed,
+#else
+ NULL,
+#endif
+#if USE_RFC2268
+ &_gcry_mac_type_spec_cmac_rfc2268,
+#else
+ NULL,
+#endif
+#ifdef USE_IDEA
+ &_gcry_mac_type_spec_cmac_idea,
+#else
+ NULL,
+#endif
+#if USE_GOST28147
+ &_gcry_mac_type_spec_cmac_gost28147,
+#else
+ NULL,
+#endif
+#if USE_SM4
+ &_gcry_mac_type_spec_cmac_sm4
+#else
+ NULL
+#endif
+ };
+
+/* GMAC implementations start with index 401 (enum gcry_mac_algos) */
+static gcry_mac_spec_t * const mac_list_algo401[] =
+ {
+#if USE_AES
+ &_gcry_mac_type_spec_gmac_aes,
+#else
+ NULL,
+#endif
+#if USE_CAMELLIA
+ &_gcry_mac_type_spec_gmac_camellia,
+#else
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_mac_type_spec_gmac_twofish,
+#else
+ NULL,
+#endif
+#if USE_SERPENT
+ &_gcry_mac_type_spec_gmac_serpent,
+#else
+ NULL,
+#endif
+#if USE_SEED
+ &_gcry_mac_type_spec_gmac_seed
+#else
+ NULL
+#endif
+ };
+
+/* Poly1305-MAC implementations start with index 501 (enum gcry_mac_algos) */
+static gcry_mac_spec_t * const mac_list_algo501[] =
+ {
+ &_gcry_mac_type_spec_poly1305mac,
+#if USE_AES
+ &_gcry_mac_type_spec_poly1305mac_aes,
+#else
+ NULL,
+#endif
+#if USE_CAMELLIA
+ &_gcry_mac_type_spec_poly1305mac_camellia,
+#else
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_mac_type_spec_poly1305mac_twofish,
+#else
+ NULL,
+#endif
+#if USE_SERPENT
+ &_gcry_mac_type_spec_poly1305mac_serpent,
+#else
+ NULL,
+#endif
+#if USE_SEED
+ &_gcry_mac_type_spec_poly1305mac_seed
+#else
+ NULL
+#endif
+ };
+
+
+
+
+/* Explicitly initialize this module. */
+gcry_err_code_t
+_gcry_mac_init (void)
+{
+ if (fips_mode())
+ {
+ /* disable algorithms that are disallowed in fips */
+ int idx;
+ gcry_mac_spec_t *spec;
+
+ for (idx = 0; (spec = mac_list[idx]); idx++)
+ if (!spec->flags.fips)
+ spec->flags.disabled = 1;
+ }
+
+ return 0;
+}
+
+
+/* Return the spec structure for the MAC algorithm ALGO. For an
+ unknown algorithm NULL is returned. */
+static gcry_mac_spec_t *
+spec_from_algo (int algo)
+{
+ gcry_mac_spec_t *spec = NULL;
+
+ if (algo >= 101 && algo < 101 + DIM(mac_list_algo101))
+ spec = mac_list_algo101[algo - 101];
+ else if (algo >= 201 && algo < 201 + DIM(mac_list_algo201))
+ spec = mac_list_algo201[algo - 201];
+ else if (algo >= 401 && algo < 401 + DIM(mac_list_algo401))
+ spec = mac_list_algo401[algo - 401];
+ else if (algo >= 501 && algo < 501 + DIM(mac_list_algo501))
+ spec = mac_list_algo501[algo - 501];
+#ifdef USE_GOST28147
+ else if (algo == GCRY_MAC_GOST28147_IMIT)
+ spec = &_gcry_mac_type_spec_gost28147_imit;
+#endif
+
+ if (spec)
+ gcry_assert (spec->algo == algo);
+
+ return spec;
+}
+
+
+/* Lookup a mac's spec by its name. */
+static gcry_mac_spec_t *
+spec_from_name (const char *name)
+{
+ gcry_mac_spec_t *spec;
+ int idx;
+
+ for (idx = 0; (spec = mac_list[idx]); idx++)
+ if (!stricmp (name, spec->name))
+ return spec;
+
+ return NULL;
+}
+
+
+/****************
+ * Map a string to the mac algo
+ */
+int
+_gcry_mac_map_name (const char *string)
+{
+ gcry_mac_spec_t *spec;
+
+ if (!string)
+ return 0;
+
+ /* Not found, search a matching mac name. */
+ spec = spec_from_name (string);
+ if (spec)
+ return spec->algo;
+
+ return 0;
+}
+
+
+/****************
+ * This function simply returns the name of the algorithm or some constant
+ * string when there is no algo. It will never return NULL.
+ * Use the macro gcry_mac_test_algo() to check whether the algorithm
+ * is valid.
+ */
+const char *
+_gcry_mac_algo_name (int algorithm)
+{
+ gcry_mac_spec_t *spec;
+
+ spec = spec_from_algo (algorithm);
+ return spec ? spec->name : "?";
+}
+
+
+static gcry_err_code_t
+check_mac_algo (int algorithm)
+{
+ gcry_mac_spec_t *spec;
+
+ spec = spec_from_algo (algorithm);
+ if (spec && !spec->flags.disabled)
+ return 0;
+
+ return GPG_ERR_MAC_ALGO;
+}
+
+
+/****************
+ * Open a message digest handle for use with algorithm ALGO.
+ */
+static gcry_err_code_t
+mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
+{
+ gcry_mac_spec_t *spec;
+ gcry_err_code_t err;
+ gcry_mac_hd_t h;
+
+ spec = spec_from_algo (algo);
+ if (!spec)
+ return GPG_ERR_MAC_ALGO;
+ else if (spec->flags.disabled)
+ return GPG_ERR_MAC_ALGO;
+ else if (!spec->ops)
+ return GPG_ERR_MAC_ALGO;
+ else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey ||
+ !spec->ops->read || !spec->ops->verify || !spec->ops->reset)
+ return GPG_ERR_MAC_ALGO;
+
+ if (secure)
+ h = xtrycalloc_secure (1, sizeof (*h));
+ else
+ h = xtrycalloc (1, sizeof (*h));
+
+ if (!h)
+ return gpg_err_code_from_syserror ();
+
+ h->magic = secure ? CTX_MAC_MAGIC_SECURE : CTX_MAC_MAGIC_NORMAL;
+ h->spec = spec;
+ h->algo = algo;
+ h->gcry_ctx = ctx;
+
+ err = h->spec->ops->open (h);
+ if (err)
+ xfree (h);
+ else
+ *hd = h;
+
+ return err;
+}
+
+
+static gcry_err_code_t
+mac_reset (gcry_mac_hd_t hd)
+{
+ if (hd->spec->ops->reset)
+ return hd->spec->ops->reset (hd);
+
+ return 0;
+}
+
+
+static void
+mac_close (gcry_mac_hd_t hd)
+{
+ if (hd->spec->ops->close)
+ hd->spec->ops->close (hd);
+
+ wipememory (hd, sizeof (*hd));
+
+ xfree (hd);
+}
+
+
+static gcry_err_code_t
+mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
+{
+ if (!hd->spec->ops->setkey)
+ return GPG_ERR_INV_ARG;
+ if (keylen > 0 && !key)
+ return GPG_ERR_INV_ARG;
+
+ return hd->spec->ops->setkey (hd, key, keylen);
+}
+
+
+static gcry_err_code_t
+mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
+{
+ if (!hd->spec->ops->setiv)
+ return GPG_ERR_INV_ARG;
+ if (ivlen > 0 && !iv)
+ return GPG_ERR_INV_ARG;
+
+ return hd->spec->ops->setiv (hd, iv, ivlen);
+}
+
+
+static gcry_err_code_t
+mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
+{
+ if (!hd->spec->ops->write)
+ return GPG_ERR_INV_ARG;
+ if (inlen > 0 && !inbuf)
+ return GPG_ERR_INV_ARG;
+
+ return hd->spec->ops->write (hd, inbuf, inlen);
+}
+
+
+static gcry_err_code_t
+mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
+{
+ if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
+ return GPG_ERR_INV_ARG;
+
+ return hd->spec->ops->read (hd, outbuf, outlen);
+}
+
+
+static gcry_err_code_t
+mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
+{
+ if (!buf || buflen == 0 || !hd->spec->ops->verify)
+ return GPG_ERR_INV_ARG;
+
+ return hd->spec->ops->verify (hd, buf, buflen);
+}
+
+
+/* Create a MAC object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of the gcry_mac_flags values.
+ H is guaranteed to be a valid handle or NULL on error. */
+gpg_err_code_t
+_gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
+ gcry_ctx_t ctx)
+{
+ gcry_err_code_t rc;
+ gcry_mac_hd_t hd = NULL;
+
+ if ((flags & ~GCRY_MAC_FLAG_SECURE))
+ rc = GPG_ERR_INV_ARG;
+ else
+ rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx);
+
+ *h = rc ? NULL : hd;
+ return rc;
+}
+
+
+void
+_gcry_mac_close (gcry_mac_hd_t hd)
+{
+ if (hd)
+ mac_close (hd);
+}
+
+
+gcry_err_code_t
+_gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
+{
+ return mac_setkey (hd, key, keylen);
+}
+
+
+gcry_err_code_t
+_gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
+{
+ return mac_setiv (hd, iv, ivlen);
+}
+
+
+gcry_err_code_t
+_gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
+{
+ return mac_write (hd, inbuf, inlen);
+}
+
+
+gcry_err_code_t
+_gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
+{
+ return mac_read (hd, outbuf, outlen);
+}
+
+
+gcry_err_code_t
+_gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
+{
+ return mac_verify (hd, buf, buflen);
+}
+
+
+int
+_gcry_mac_get_algo (gcry_mac_hd_t hd)
+{
+ return hd->algo;
+}
+
+
+unsigned int
+_gcry_mac_get_algo_maclen (int algo)
+{
+ gcry_mac_spec_t *spec;
+
+ spec = spec_from_algo (algo);
+ if (!spec || !spec->ops || !spec->ops->get_maclen)
+ return 0;
+
+ return spec->ops->get_maclen (algo);
+}
+
+
+unsigned int
+_gcry_mac_get_algo_keylen (int algo)
+{
+ gcry_mac_spec_t *spec;
+
+ spec = spec_from_algo (algo);
+ if (!spec || !spec->ops || !spec->ops->get_keylen)
+ return 0;
+
+ return spec->ops->get_keylen (algo);
+}
+
+
+gcry_err_code_t
+_gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen)
+{
+ gcry_err_code_t rc;
+
+ /* Currently not used. */
+ (void) hd;
+ (void) buffer;
+ (void) buflen;
+
+ switch (cmd)
+ {
+ case GCRYCTL_RESET:
+ rc = mac_reset (hd);
+ break;
+ case GCRYCTL_SET_SBOX:
+ if (hd->spec->ops->set_extra_info)
+ rc = hd->spec->ops->set_extra_info
+ (hd, GCRYCTL_SET_SBOX, buffer, buflen);
+ else
+ rc = GPG_ERR_NOT_SUPPORTED;
+ break;
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+ return rc;
+}
+
+
+/* Return information about the given MAC algorithm ALGO.
+
+ GCRYCTL_TEST_ALGO:
+ Returns 0 if the specified algorithm ALGO is available for use.
+ BUFFER and NBYTES must be zero.
+
+ Note: Because this function is in most cases used to return an
+ integer value, we can make it easier for the caller to just look at
+ the return value. The caller will in all cases consult the value
+ and thereby detecting whether a error occurred or not (i.e. while
+ checking the block size)
+ */
+gcry_err_code_t
+_gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes)
+{
+ gcry_err_code_t rc = 0;
+ unsigned int ui;
+
+ switch (what)
+ {
+ case GCRYCTL_GET_KEYLEN:
+ if (buffer || (!nbytes))
+ rc = GPG_ERR_INV_ARG;
+ else
+ {
+ ui = _gcry_mac_get_algo_keylen (algo);
+ if (ui > 0)
+ *nbytes = (size_t) ui;
+ else
+ /* The only reason for an error is an invalid algo. */
+ rc = GPG_ERR_MAC_ALGO;
+ }
+ break;
+ case GCRYCTL_TEST_ALGO:
+ if (buffer || nbytes)
+ rc = GPG_ERR_INV_ARG;
+ else
+ rc = check_mac_algo (algo);
+ break;
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return rc;
+}
+
+
+/* Run the self-tests for the MAC. */
+gpg_error_t
+_gcry_mac_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_err_code_t ec;
+ gcry_mac_spec_t *spec;
+
+ spec = spec_from_algo (algo);
+ if (spec && !spec->flags.disabled && spec->ops && spec->ops->selftest)
+ ec = spec->ops->selftest (algo, extended, report);
+ else
+ {
+ ec = GPG_ERR_MAC_ALGO;
+ if (report)
+ report ("mac", algo, "module",
+ spec && !spec->flags.disabled?
+ "no selftest available" :
+ spec? "algorithm disabled" :
+ "algorithm not found");
+ }
+
+ return gpg_error (ec);
+}
diff --git a/comm/third_party/libgcrypt/cipher/md.c b/comm/third_party/libgcrypt/cipher/md.c
new file mode 100644
index 0000000000..efb7376a1a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/md.c
@@ -0,0 +1,1639 @@
+/* md.c - message digest dispatcher
+ * Copyright (C) 1998, 1999, 2002, 2003, 2006,
+ * 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+
+
+/* This is the list of the digest implementations included in
+ libgcrypt. */
+static gcry_md_spec_t * const digest_list[] =
+ {
+#if USE_CRC
+ &_gcry_digest_spec_crc32,
+ &_gcry_digest_spec_crc32_rfc1510,
+ &_gcry_digest_spec_crc24_rfc2440,
+#endif
+#if USE_SHA1
+ &_gcry_digest_spec_sha1,
+#endif
+#if USE_SHA256
+ &_gcry_digest_spec_sha256,
+ &_gcry_digest_spec_sha224,
+#endif
+#if USE_SHA512
+ &_gcry_digest_spec_sha512,
+ &_gcry_digest_spec_sha384,
+ &_gcry_digest_spec_sha512_256,
+ &_gcry_digest_spec_sha512_224,
+#endif
+#if USE_SHA3
+ &_gcry_digest_spec_sha3_224,
+ &_gcry_digest_spec_sha3_256,
+ &_gcry_digest_spec_sha3_384,
+ &_gcry_digest_spec_sha3_512,
+ &_gcry_digest_spec_shake128,
+ &_gcry_digest_spec_shake256,
+#endif
+#if USE_GOST_R_3411_94
+ &_gcry_digest_spec_gost3411_94,
+ &_gcry_digest_spec_gost3411_cp,
+#endif
+#if USE_GOST_R_3411_12
+ &_gcry_digest_spec_stribog_256,
+ &_gcry_digest_spec_stribog_512,
+#endif
+#if USE_WHIRLPOOL
+ &_gcry_digest_spec_whirlpool,
+#endif
+#if USE_RMD160
+ &_gcry_digest_spec_rmd160,
+#endif
+#if USE_TIGER
+ &_gcry_digest_spec_tiger,
+ &_gcry_digest_spec_tiger1,
+ &_gcry_digest_spec_tiger2,
+#endif
+#if USE_MD5
+ &_gcry_digest_spec_md5,
+#endif
+#if USE_MD4
+ &_gcry_digest_spec_md4,
+#endif
+#if USE_MD2
+ &_gcry_digest_spec_md2,
+#endif
+#if USE_BLAKE2
+ &_gcry_digest_spec_blake2b_512,
+ &_gcry_digest_spec_blake2b_384,
+ &_gcry_digest_spec_blake2b_256,
+ &_gcry_digest_spec_blake2b_160,
+ &_gcry_digest_spec_blake2s_256,
+ &_gcry_digest_spec_blake2s_224,
+ &_gcry_digest_spec_blake2s_160,
+ &_gcry_digest_spec_blake2s_128,
+#endif
+#if USE_SM3
+ &_gcry_digest_spec_sm3,
+#endif
+ NULL
+ };
+
+/* Digest implementations starting with index 0 (enum gcry_md_algos) */
+static gcry_md_spec_t * const digest_list_algo0[] =
+ {
+ NULL, /* GCRY_MD_NONE */
+#if USE_MD5
+ &_gcry_digest_spec_md5,
+#else
+ NULL,
+#endif
+#if USE_SHA1
+ &_gcry_digest_spec_sha1,
+#else
+ NULL,
+#endif
+#if USE_RMD160
+ &_gcry_digest_spec_rmd160,
+#else
+ NULL,
+#endif
+ NULL, /* Unused index 4 */
+#if USE_MD2
+ &_gcry_digest_spec_md2,
+#else
+ NULL,
+#endif
+#if USE_TIGER
+ &_gcry_digest_spec_tiger,
+#else
+ NULL,
+#endif
+ NULL, /* GCRY_MD_HAVAL */
+#if USE_SHA256
+ &_gcry_digest_spec_sha256,
+#else
+ NULL,
+#endif
+#if USE_SHA512
+ &_gcry_digest_spec_sha384,
+ &_gcry_digest_spec_sha512,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_SHA256
+ &_gcry_digest_spec_sha224
+#else
+ NULL
+#endif
+ };
+
+/* Digest implementations starting with index 301 (enum gcry_md_algos) */
+static gcry_md_spec_t * const digest_list_algo301[] =
+ {
+#if USE_MD4
+ &_gcry_digest_spec_md4,
+#else
+ NULL,
+#endif
+#if USE_CRC
+ &_gcry_digest_spec_crc32,
+ &_gcry_digest_spec_crc32_rfc1510,
+ &_gcry_digest_spec_crc24_rfc2440,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_WHIRLPOOL
+ &_gcry_digest_spec_whirlpool,
+#else
+ NULL,
+#endif
+#if USE_TIGER
+ &_gcry_digest_spec_tiger1,
+ &_gcry_digest_spec_tiger2,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_GOST_R_3411_94
+ &_gcry_digest_spec_gost3411_94,
+#else
+ NULL,
+#endif
+#if USE_GOST_R_3411_12
+ &_gcry_digest_spec_stribog_256,
+ &_gcry_digest_spec_stribog_512,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_GOST_R_3411_94
+ &_gcry_digest_spec_gost3411_cp,
+#else
+ NULL,
+#endif
+#if USE_SHA3
+ &_gcry_digest_spec_sha3_224,
+ &_gcry_digest_spec_sha3_256,
+ &_gcry_digest_spec_sha3_384,
+ &_gcry_digest_spec_sha3_512,
+ &_gcry_digest_spec_shake128,
+ &_gcry_digest_spec_shake256,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_BLAKE2
+ &_gcry_digest_spec_blake2b_512,
+ &_gcry_digest_spec_blake2b_384,
+ &_gcry_digest_spec_blake2b_256,
+ &_gcry_digest_spec_blake2b_160,
+ &_gcry_digest_spec_blake2s_256,
+ &_gcry_digest_spec_blake2s_224,
+ &_gcry_digest_spec_blake2s_160,
+ &_gcry_digest_spec_blake2s_128,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_SM3
+ &_gcry_digest_spec_sm3,
+#else
+ NULL,
+#endif
+#if USE_SHA512
+ &_gcry_digest_spec_sha512_256,
+ &_gcry_digest_spec_sha512_224,
+#else
+ NULL,
+ NULL,
+#endif
+ };
+
+
+typedef struct gcry_md_list
+{
+ gcry_md_spec_t *spec;
+ struct gcry_md_list *next;
+ size_t actual_struct_size; /* Allocated size of this structure. */
+ PROPERLY_ALIGNED_TYPE context[1];
+} GcryDigestEntry;
+
+/* This structure is put right after the gcry_md_hd_t buffer, so that
+ * only one memory block is needed. */
+struct gcry_md_context
+{
+ int magic;
+ size_t actual_handle_size; /* Allocated size of this handle. */
+ FILE *debug;
+ struct {
+ unsigned int secure:1;
+ unsigned int finalized:1;
+ unsigned int bugemu1:1;
+ unsigned int hmac:1;
+ } flags;
+ GcryDigestEntry *list;
+};
+
+
+#define CTX_MAGIC_NORMAL 0x11071961
+#define CTX_MAGIC_SECURE 0x16917011
+
+static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
+static void md_close (gcry_md_hd_t a);
+static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
+static byte *md_read( gcry_md_hd_t a, int algo );
+static int md_get_algo( gcry_md_hd_t a );
+static int md_digest_length( int algo );
+static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
+static void md_stop_debug ( gcry_md_hd_t a );
+
+
+
+static int
+map_algo (int algo)
+{
+ return algo;
+}
+
+
+/* Return the spec structure for the hash algorithm ALGO. For an
+ unknown algorithm NULL is returned. */
+static gcry_md_spec_t *
+spec_from_algo (int algo)
+{
+ gcry_md_spec_t *spec = NULL;
+
+ algo = map_algo (algo);
+
+ if (algo >= 0 && algo < DIM(digest_list_algo0))
+ spec = digest_list_algo0[algo];
+ else if (algo >= 301 && algo < 301 + DIM(digest_list_algo301))
+ spec = digest_list_algo301[algo - 301];
+
+ if (spec)
+ gcry_assert (spec->algo == algo);
+
+ return spec;
+}
+
+
+/* Lookup a hash's spec by its name. */
+static gcry_md_spec_t *
+spec_from_name (const char *name)
+{
+ gcry_md_spec_t *spec;
+ int idx;
+
+ for (idx=0; (spec = digest_list[idx]); idx++)
+ {
+ if (!stricmp (name, spec->name))
+ return spec;
+ }
+
+ return NULL;
+}
+
+
+/* Lookup a hash's spec by its OID. */
+static gcry_md_spec_t *
+spec_from_oid (const char *oid)
+{
+ gcry_md_spec_t *spec;
+ gcry_md_oid_spec_t *oid_specs;
+ int idx, j;
+
+ for (idx=0; (spec = digest_list[idx]); idx++)
+ {
+ oid_specs = spec->oids;
+ if (oid_specs)
+ {
+ for (j = 0; oid_specs[j].oidstring; j++)
+ if (!stricmp (oid, oid_specs[j].oidstring))
+ return spec;
+ }
+ }
+
+ return NULL;
+}
+
+
+static gcry_md_spec_t *
+search_oid (const char *oid, gcry_md_oid_spec_t *oid_spec)
+{
+ gcry_md_spec_t *spec;
+ int i;
+
+ if (!oid)
+ return NULL;
+
+ if (!strncmp (oid, "oid.", 4) || !strncmp (oid, "OID.", 4))
+ oid += 4;
+
+ spec = spec_from_oid (oid);
+ if (spec && spec->oids)
+ {
+ for (i = 0; spec->oids[i].oidstring; i++)
+ if (!stricmp (oid, spec->oids[i].oidstring))
+ {
+ if (oid_spec)
+ *oid_spec = spec->oids[i];
+ return spec;
+ }
+ }
+
+ return NULL;
+}
+
+
+/****************
+ * Map a string to the digest algo
+ */
+int
+_gcry_md_map_name (const char *string)
+{
+ gcry_md_spec_t *spec;
+
+ if (!string)
+ return 0;
+
+ /* If the string starts with a digit (optionally prefixed with
+ either "OID." or "oid."), we first look into our table of ASN.1
+ object identifiers to figure out the algorithm */
+ spec = search_oid (string, NULL);
+ if (spec)
+ return spec->algo;
+
+ /* Not found, search a matching digest name. */
+ spec = spec_from_name (string);
+ if (spec)
+ return spec->algo;
+
+ return 0;
+}
+
+
+/****************
+ * This function simply returns the name of the algorithm or some constant
+ * string when there is no algo. It will never return NULL.
+ * Use the macro gcry_md_test_algo() to check whether the algorithm
+ * is valid.
+ */
+const char *
+_gcry_md_algo_name (int algorithm)
+{
+ gcry_md_spec_t *spec;
+
+ spec = spec_from_algo (algorithm);
+ return spec ? spec->name : "?";
+}
+
+
+static gcry_err_code_t
+check_digest_algo (int algorithm)
+{
+ gcry_md_spec_t *spec;
+
+ spec = spec_from_algo (algorithm);
+ if (spec && !spec->flags.disabled)
+ return 0;
+
+ return GPG_ERR_DIGEST_ALGO;
+
+}
+
+
+/****************
+ * Open a message digest handle for use with algorithm ALGO.
+ * More algorithms may be added by md_enable(). The initial algorithm
+ * may be 0.
+ */
+static gcry_err_code_t
+md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
+{
+ gcry_err_code_t err = 0;
+ int secure = !!(flags & GCRY_MD_FLAG_SECURE);
+ int hmac = !!(flags & GCRY_MD_FLAG_HMAC);
+ int bufsize = secure ? 512 : 1024;
+ struct gcry_md_context *ctx;
+ gcry_md_hd_t hd;
+ size_t n;
+
+ /* Allocate a memory area to hold the caller visible buffer with it's
+ * control information and the data required by this module. Set the
+ * context pointer at the beginning to this area.
+ * We have to use this strange scheme because we want to hide the
+ * internal data but have a variable sized buffer.
+ *
+ * +---+------+---........------+-------------+
+ * !ctx! bctl ! buffer ! private !
+ * +---+------+---........------+-------------+
+ * ! ^
+ * !---------------------------!
+ *
+ * We have to make sure that private is well aligned.
+ */
+ n = sizeof (struct gcry_md_handle) + bufsize;
+ n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
+ / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
+
+ /* Allocate and set the Context pointer to the private data */
+ if (secure)
+ hd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
+ else
+ hd = xtrymalloc (n + sizeof (struct gcry_md_context));
+
+ if (! hd)
+ err = gpg_err_code_from_errno (errno);
+
+ if (! err)
+ {
+ hd->ctx = ctx = (void *) ((char *) hd + n);
+ /* Setup the globally visible data (bctl in the diagram).*/
+ hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
+ hd->bufpos = 0;
+
+ /* Initialize the private data. */
+ memset (hd->ctx, 0, sizeof *hd->ctx);
+ ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
+ ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
+ ctx->flags.secure = secure;
+ ctx->flags.hmac = hmac;
+ ctx->flags.bugemu1 = !!(flags & GCRY_MD_FLAG_BUGEMU1);
+ }
+
+ if (! err)
+ {
+ /* Hmmm, should we really do that? - yes [-wk] */
+ _gcry_fast_random_poll ();
+
+ if (algo)
+ {
+ err = md_enable (hd, algo);
+ if (err)
+ md_close (hd);
+ }
+ }
+
+ if (! err)
+ *h = hd;
+
+ return err;
+}
+
+/* Create a message digest object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of the gcry_md_flags values. ALGO may be
+ given as 0 if the algorithms to be used are later set using
+ gcry_md_enable. H is guaranteed to be a valid handle or NULL on
+ error. */
+gcry_err_code_t
+_gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
+{
+ gcry_err_code_t rc;
+ gcry_md_hd_t hd;
+
+ if ((flags & ~(GCRY_MD_FLAG_SECURE
+ | GCRY_MD_FLAG_HMAC
+ | GCRY_MD_FLAG_BUGEMU1)))
+ rc = GPG_ERR_INV_ARG;
+ else
+ rc = md_open (&hd, algo, flags);
+
+ *h = rc? NULL : hd;
+ return rc;
+}
+
+
+
+static gcry_err_code_t
+md_enable (gcry_md_hd_t hd, int algorithm)
+{
+ struct gcry_md_context *h = hd->ctx;
+ gcry_md_spec_t *spec;
+ GcryDigestEntry *entry;
+ gcry_err_code_t err = 0;
+
+ for (entry = h->list; entry; entry = entry->next)
+ if (entry->spec->algo == algorithm)
+ return 0; /* Already enabled */
+
+ spec = spec_from_algo (algorithm);
+ if (!spec)
+ {
+ log_debug ("md_enable: algorithm %d not available\n", algorithm);
+ err = GPG_ERR_DIGEST_ALGO;
+ }
+
+
+ if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
+ {
+ _gcry_inactivate_fips_mode ("MD5 used");
+ if (_gcry_enforced_fips_mode () )
+ {
+ /* We should never get to here because we do not register
+ MD5 in enforced fips mode. But better throw an error. */
+ err = GPG_ERR_DIGEST_ALGO;
+ }
+ }
+
+ if (!err && h->flags.hmac && spec->read == NULL)
+ {
+ /* Expandable output function cannot act as part of HMAC. */
+ err = GPG_ERR_DIGEST_ALGO;
+ }
+
+ if (!err)
+ {
+ size_t size = (sizeof (*entry)
+ + spec->contextsize * (h->flags.hmac? 3 : 1)
+ - sizeof (entry->context));
+
+ /* And allocate a new list entry. */
+ if (h->flags.secure)
+ entry = xtrymalloc_secure (size);
+ else
+ entry = xtrymalloc (size);
+
+ if (! entry)
+ err = gpg_err_code_from_errno (errno);
+ else
+ {
+ entry->spec = spec;
+ entry->next = h->list;
+ entry->actual_struct_size = size;
+ h->list = entry;
+
+ /* And init this instance. */
+ entry->spec->init (entry->context,
+ h->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
+ }
+ }
+
+ return err;
+}
+
+
+gcry_err_code_t
+_gcry_md_enable (gcry_md_hd_t hd, int algorithm)
+{
+ return md_enable (hd, algorithm);
+}
+
+
+static gcry_err_code_t
+md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
+{
+ gcry_err_code_t err = 0;
+ struct gcry_md_context *a = ahd->ctx;
+ struct gcry_md_context *b;
+ GcryDigestEntry *ar, *br;
+ gcry_md_hd_t bhd;
+ size_t n;
+
+ if (ahd->bufpos)
+ md_write (ahd, NULL, 0);
+
+ n = (char *) ahd->ctx - (char *) ahd;
+ if (a->flags.secure)
+ bhd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
+ else
+ bhd = xtrymalloc (n + sizeof (struct gcry_md_context));
+
+ if (!bhd)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ bhd->ctx = b = (void *) ((char *) bhd + n);
+ /* No need to copy the buffer due to the write above. */
+ gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
+ bhd->bufsize = ahd->bufsize;
+ bhd->bufpos = 0;
+ gcry_assert (! ahd->bufpos);
+ memcpy (b, a, sizeof *a);
+ b->list = NULL;
+ b->debug = NULL;
+
+ /* Copy the complete list of algorithms. The copied list is
+ reversed, but that doesn't matter. */
+ for (ar = a->list; ar; ar = ar->next)
+ {
+ if (a->flags.secure)
+ br = xtrymalloc_secure (ar->actual_struct_size);
+ else
+ br = xtrymalloc (ar->actual_struct_size);
+ if (!br)
+ {
+ err = gpg_err_code_from_syserror ();
+ md_close (bhd);
+ goto leave;
+ }
+
+ memcpy (br, ar, ar->actual_struct_size);
+ br->next = b->list;
+ b->list = br;
+ }
+
+ if (a->debug)
+ md_start_debug (bhd, "unknown");
+
+ *b_hd = bhd;
+
+ leave:
+ return err;
+}
+
+
+gcry_err_code_t
+_gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
+{
+ gcry_err_code_t rc;
+
+ rc = md_copy (hd, handle);
+ if (rc)
+ *handle = NULL;
+ return rc;
+}
+
+
+/*
+ * Reset all contexts and discard any buffered stuff. This may be used
+ * instead of a md_close(); md_open().
+ */
+void
+_gcry_md_reset (gcry_md_hd_t a)
+{
+ GcryDigestEntry *r;
+
+ /* Note: We allow this even in fips non operational mode. */
+
+ a->bufpos = a->ctx->flags.finalized = 0;
+
+ if (a->ctx->flags.hmac)
+ for (r = a->ctx->list; r; r = r->next)
+ {
+ memcpy (r->context, (char *)r->context + r->spec->contextsize,
+ r->spec->contextsize);
+ }
+ else
+ for (r = a->ctx->list; r; r = r->next)
+ {
+ memset (r->context, 0, r->spec->contextsize);
+ (*r->spec->init) (r->context,
+ a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
+ }
+}
+
+
+static void
+md_close (gcry_md_hd_t a)
+{
+ GcryDigestEntry *r, *r2;
+
+ if (! a)
+ return;
+ if (a->ctx->debug)
+ md_stop_debug (a);
+ for (r = a->ctx->list; r; r = r2)
+ {
+ r2 = r->next;
+ wipememory (r, r->actual_struct_size);
+ xfree (r);
+ }
+
+ wipememory (a, a->ctx->actual_handle_size);
+ xfree(a);
+}
+
+
+void
+_gcry_md_close (gcry_md_hd_t hd)
+{
+ /* Note: We allow this even in fips non operational mode. */
+ md_close (hd);
+}
+
+
+static void
+md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
+{
+ GcryDigestEntry *r;
+
+ if (a->ctx->debug)
+ {
+ if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
+ BUG();
+ if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
+ BUG();
+ }
+
+ for (r = a->ctx->list; r; r = r->next)
+ {
+ if (a->bufpos)
+ (*r->spec->write) (r->context, a->buf, a->bufpos);
+ (*r->spec->write) (r->context, inbuf, inlen);
+ }
+ a->bufpos = 0;
+}
+
+
+/* Note that this function may be used after finalize and read to keep
+ on writing to the transform function so to mitigate timing
+ attacks. */
+void
+_gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
+{
+ md_write (hd, inbuf, inlen);
+}
+
+
+static void
+md_final (gcry_md_hd_t a)
+{
+ GcryDigestEntry *r;
+
+ if (a->ctx->flags.finalized)
+ return;
+
+ if (a->bufpos)
+ md_write (a, NULL, 0);
+
+ for (r = a->ctx->list; r; r = r->next)
+ (*r->spec->final) (r->context);
+
+ a->ctx->flags.finalized = 1;
+
+ if (!a->ctx->flags.hmac)
+ return;
+
+ for (r = a->ctx->list; r; r = r->next)
+ {
+ byte *p;
+ size_t dlen = r->spec->mdlen;
+ byte *hash;
+ gcry_err_code_t err;
+
+ if (r->spec->read == NULL)
+ continue;
+
+ p = r->spec->read (r->context);
+
+ if (a->ctx->flags.secure)
+ hash = xtrymalloc_secure (dlen);
+ else
+ hash = xtrymalloc (dlen);
+ if (!hash)
+ {
+ err = gpg_err_code_from_errno (errno);
+ _gcry_fatal_error (err, NULL);
+ }
+
+ memcpy (hash, p, dlen);
+ memcpy (r->context, (char *)r->context + r->spec->contextsize * 2,
+ r->spec->contextsize);
+ (*r->spec->write) (r->context, hash, dlen);
+ (*r->spec->final) (r->context);
+ xfree (hash);
+ }
+}
+
+
+static gcry_err_code_t
+md_setkey (gcry_md_hd_t h, const unsigned char *key, size_t keylen)
+{
+ gcry_err_code_t rc = 0;
+ GcryDigestEntry *r;
+ int algo_had_setkey = 0;
+
+ if (!h->ctx->list)
+ return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */
+
+ if (h->ctx->flags.hmac)
+ return GPG_ERR_DIGEST_ALGO; /* Tried md_setkey for HMAC md. */
+
+ for (r = h->ctx->list; r; r = r->next)
+ {
+ switch (r->spec->algo)
+ {
+#if USE_BLAKE2
+ /* TODO? add spec->init_with_key? */
+ case GCRY_MD_BLAKE2B_512:
+ case GCRY_MD_BLAKE2B_384:
+ case GCRY_MD_BLAKE2B_256:
+ case GCRY_MD_BLAKE2B_160:
+ case GCRY_MD_BLAKE2S_256:
+ case GCRY_MD_BLAKE2S_224:
+ case GCRY_MD_BLAKE2S_160:
+ case GCRY_MD_BLAKE2S_128:
+ algo_had_setkey = 1;
+ memset (r->context, 0, r->spec->contextsize);
+ rc = _gcry_blake2_init_with_key (r->context,
+ h->ctx->flags.bugemu1
+ ? GCRY_MD_FLAG_BUGEMU1:0,
+ key, keylen, r->spec->algo);
+ break;
+#endif
+ default:
+ rc = GPG_ERR_DIGEST_ALGO;
+ break;
+ }
+
+ if (rc)
+ break;
+ }
+
+ if (rc && !algo_had_setkey)
+ {
+ /* None of algorithms had setkey implementation, so contexts were not
+ * modified. Just return error. */
+ return rc;
+ }
+ else if (rc && algo_had_setkey)
+ {
+ /* Some of the contexts have been modified, but got error. Reset
+ * all contexts. */
+ _gcry_md_reset (h);
+ return rc;
+ }
+
+ /* Successful md_setkey implies reset. */
+ h->bufpos = h->ctx->flags.finalized = 0;
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+prepare_macpads (gcry_md_hd_t a, const unsigned char *key, size_t keylen)
+{
+ GcryDigestEntry *r;
+
+ if (!a->ctx->list)
+ return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */
+
+ if (!a->ctx->flags.hmac)
+ return GPG_ERR_DIGEST_ALGO; /* Tried prepare_macpads for non-HMAC md. */
+
+ for (r = a->ctx->list; r; r = r->next)
+ {
+ const unsigned char *k;
+ size_t k_len;
+ unsigned char *key_allocated = NULL;
+ int macpad_Bsize;
+ int i;
+
+ switch (r->spec->algo)
+ {
+ /* TODO: add spec->blocksize */
+ case GCRY_MD_SHA3_224:
+ macpad_Bsize = 1152 / 8;
+ break;
+ case GCRY_MD_SHA3_256:
+ macpad_Bsize = 1088 / 8;
+ break;
+ case GCRY_MD_SHA3_384:
+ macpad_Bsize = 832 / 8;
+ break;
+ case GCRY_MD_SHA3_512:
+ macpad_Bsize = 576 / 8;
+ break;
+ case GCRY_MD_SHA384:
+ case GCRY_MD_SHA512:
+ case GCRY_MD_SHA512_256:
+ case GCRY_MD_SHA512_224:
+ case GCRY_MD_BLAKE2B_512:
+ case GCRY_MD_BLAKE2B_384:
+ case GCRY_MD_BLAKE2B_256:
+ case GCRY_MD_BLAKE2B_160:
+ macpad_Bsize = 128;
+ break;
+ case GCRY_MD_GOSTR3411_94:
+ case GCRY_MD_GOSTR3411_CP:
+ macpad_Bsize = 32;
+ break;
+ default:
+ macpad_Bsize = 64;
+ break;
+ }
+
+ if ( keylen > macpad_Bsize )
+ {
+ k = key_allocated = xtrymalloc_secure (r->spec->mdlen);
+ if (!k)
+ return gpg_err_code_from_errno (errno);
+ _gcry_md_hash_buffer (r->spec->algo, key_allocated, key, keylen);
+ k_len = r->spec->mdlen;
+ gcry_assert ( k_len <= macpad_Bsize );
+ }
+ else
+ {
+ k = key;
+ k_len = keylen;
+ }
+
+ (*r->spec->init) (r->context,
+ a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
+ a->bufpos = 0;
+ for (i=0; i < k_len; i++ )
+ _gcry_md_putc (a, k[i] ^ 0x36);
+ for (; i < macpad_Bsize; i++ )
+ _gcry_md_putc (a, 0x36);
+ (*r->spec->write) (r->context, a->buf, a->bufpos);
+ memcpy ((char *)r->context + r->spec->contextsize, r->context,
+ r->spec->contextsize);
+
+ (*r->spec->init) (r->context,
+ a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
+ a->bufpos = 0;
+ for (i=0; i < k_len; i++ )
+ _gcry_md_putc (a, k[i] ^ 0x5c);
+ for (; i < macpad_Bsize; i++ )
+ _gcry_md_putc (a, 0x5c);
+ (*r->spec->write) (r->context, a->buf, a->bufpos);
+ memcpy ((char *)r->context + r->spec->contextsize*2, r->context,
+ r->spec->contextsize);
+
+ xfree (key_allocated);
+ }
+
+ a->bufpos = 0;
+ return 0;
+}
+
+
+gcry_err_code_t
+_gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
+{
+ gcry_err_code_t rc = 0;
+
+ (void)buflen; /* Currently not used. */
+
+ switch (cmd)
+ {
+ case GCRYCTL_FINALIZE:
+ md_final (hd);
+ break;
+ case GCRYCTL_START_DUMP:
+ md_start_debug (hd, buffer);
+ break;
+ case GCRYCTL_STOP_DUMP:
+ md_stop_debug ( hd );
+ break;
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+ return rc;
+}
+
+
+gcry_err_code_t
+_gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
+{
+ gcry_err_code_t rc;
+
+ if (hd->ctx->flags.hmac)
+ {
+ rc = prepare_macpads (hd, key, keylen);
+ if (!rc)
+ _gcry_md_reset (hd);
+ }
+ else
+ {
+ rc = md_setkey (hd, key, keylen);
+ }
+
+ return rc;
+}
+
+
+/* The new debug interface. If SUFFIX is a string it creates an debug
+ file for the context HD. IF suffix is NULL, the file is closed and
+ debugging is stopped. */
+void
+_gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
+{
+ if (suffix)
+ md_start_debug (hd, suffix);
+ else
+ md_stop_debug (hd);
+}
+
+
+/****************
+ * If ALGO is null get the digest for the used algo (which should be
+ * only one)
+ */
+static byte *
+md_read( gcry_md_hd_t a, int algo )
+{
+ GcryDigestEntry *r = a->ctx->list;
+
+ if (! algo)
+ {
+ /* Return the first algorithm */
+ if (r)
+ {
+ if (r->next)
+ log_debug ("more than one algorithm in md_read(0)\n");
+ if (r->spec->read)
+ return r->spec->read (r->context);
+ }
+ }
+ else
+ {
+ for (r = a->ctx->list; r; r = r->next)
+ if (r->spec->algo == algo)
+ {
+ if (r->spec->read)
+ return r->spec->read (r->context);
+ break;
+ }
+ }
+
+ if (r && !r->spec->read)
+ _gcry_fatal_error (GPG_ERR_DIGEST_ALGO,
+ "requested algo has no fixed digest length");
+ else
+ _gcry_fatal_error (GPG_ERR_DIGEST_ALGO, "requested algo not in md context");
+ return NULL;
+}
+
+
+/*
+ * Read out the complete digest, this function implictly finalizes
+ * the hash.
+ */
+byte *
+_gcry_md_read (gcry_md_hd_t hd, int algo)
+{
+ /* This function is expected to always return a digest, thus we
+ can't return an error which we actually should do in
+ non-operational state. */
+ _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+ return md_read (hd, algo);
+}
+
+
+/****************
+ * If ALGO is null get the digest for the used algo (which should be
+ * only one)
+ */
+static gcry_err_code_t
+md_extract(gcry_md_hd_t a, int algo, void *out, size_t outlen)
+{
+ GcryDigestEntry *r = a->ctx->list;
+
+ if (!algo)
+ {
+ /* Return the first algorithm */
+ if (r && r->spec->extract)
+ {
+ if (r->next)
+ log_debug ("more than one algorithm in md_extract(0)\n");
+ r->spec->extract (r->context, out, outlen);
+ return 0;
+ }
+ }
+ else
+ {
+ for (r = a->ctx->list; r; r = r->next)
+ if (r->spec->algo == algo && r->spec->extract)
+ {
+ r->spec->extract (r->context, out, outlen);
+ return 0;
+ }
+ }
+
+ return GPG_ERR_DIGEST_ALGO;
+}
+
+
+/*
+ * Expand the output from XOF class digest, this function implictly finalizes
+ * the hash.
+ */
+gcry_err_code_t
+_gcry_md_extract (gcry_md_hd_t hd, int algo, void *out, size_t outlen)
+{
+ _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+ return md_extract (hd, algo, out, outlen);
+}
+
+
+/*
+ * Read out an intermediate digest. Not yet functional.
+ */
+gcry_err_code_t
+_gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
+{
+ (void)hd;
+ (void)algo;
+ (void)buffer;
+ (void)buflen;
+
+ /*md_digest ... */
+ fips_signal_error ("unimplemented function called");
+ return GPG_ERR_INTERNAL;
+}
+
+
+/*
+ * Shortcut function to hash a buffer with a given algo. The only
+ * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
+ * supplied digest buffer must be large enough to store the resulting
+ * hash. No error is returned, the function will abort on an invalid
+ * algo. DISABLED_ALGOS are ignored here. */
+void
+_gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length)
+{
+ gcry_md_spec_t *spec;
+
+ spec = spec_from_algo (algo);
+ if (!spec)
+ {
+ log_debug ("md_hash_buffer: algorithm %d not available\n", algo);
+ return;
+ }
+
+ if (algo == GCRY_MD_MD5 && fips_mode ())
+ {
+ _gcry_inactivate_fips_mode ("MD5 used");
+ if (_gcry_enforced_fips_mode () )
+ {
+ /* We should never get to here because we do not register
+ MD5 in enforced fips mode. */
+ _gcry_fips_noreturn ();
+ }
+ }
+
+ if (spec->hash_buffer != NULL)
+ {
+ spec->hash_buffer (digest, buffer, length);
+ }
+ else if (spec->hash_buffers != NULL)
+ {
+ gcry_buffer_t iov;
+
+ iov.size = 0;
+ iov.data = (void *)buffer;
+ iov.off = 0;
+ iov.len = length;
+
+ spec->hash_buffers (digest, &iov, 1);
+ }
+ else
+ {
+ /* For the others we do not have a fast function, so we use the
+ normal functions. */
+ gcry_md_hd_t h;
+ gpg_err_code_t err;
+
+ err = md_open (&h, algo, 0);
+ if (err)
+ log_bug ("gcry_md_open failed for algo %d: %s",
+ algo, gpg_strerror (gcry_error(err)));
+ md_write (h, (byte *) buffer, length);
+ md_final (h);
+ memcpy (digest, md_read (h, algo), md_digest_length (algo));
+ md_close (h);
+ }
+}
+
+
+/* Shortcut function to hash multiple buffers with a given algo. In
+ contrast to gcry_md_hash_buffer, this function returns an error on
+ invalid arguments or on other problems; disabled algorithms are
+ _not_ ignored but flagged as an error.
+
+ The data to sign is taken from the array IOV which has IOVCNT items.
+
+ The only supported flag in FLAGS is GCRY_MD_FLAG_HMAC which turns
+ this function into a HMAC function; the first item in IOV is then
+ used as the key.
+
+ On success 0 is returned and resulting hash or HMAC is stored at
+ DIGEST which must have been provided by the caller with an
+ appropriate length. */
+gpg_err_code_t
+_gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
+ const gcry_buffer_t *iov, int iovcnt)
+{
+ gcry_md_spec_t *spec;
+ int hmac;
+
+ if (!iov || iovcnt < 0)
+ return GPG_ERR_INV_ARG;
+ if (flags & ~(GCRY_MD_FLAG_HMAC))
+ return GPG_ERR_INV_ARG;
+
+ hmac = !!(flags & GCRY_MD_FLAG_HMAC);
+ if (hmac && iovcnt < 1)
+ return GPG_ERR_INV_ARG;
+
+ spec = spec_from_algo (algo);
+ if (!spec)
+ {
+ log_debug ("md_hash_buffers: algorithm %d not available\n", algo);
+ return GPG_ERR_DIGEST_ALGO;
+ }
+
+ if (algo == GCRY_MD_MD5 && fips_mode ())
+ {
+ _gcry_inactivate_fips_mode ("MD5 used");
+ if (_gcry_enforced_fips_mode () )
+ {
+ /* We should never get to here because we do not register
+ MD5 in enforced fips mode. */
+ _gcry_fips_noreturn ();
+ }
+ }
+
+ if (!hmac && spec->hash_buffers)
+ {
+ spec->hash_buffers (digest, iov, iovcnt);
+ }
+ else
+ {
+ /* For the others we do not have a fast function, so we use the
+ normal functions. */
+ gcry_md_hd_t h;
+ gpg_err_code_t rc;
+ int dlen;
+
+ /* Detect SHAKE128 like algorithms which we can't use because
+ * our API does not allow for a variable length digest. */
+ dlen = md_digest_length (algo);
+ if (!dlen)
+ return GPG_ERR_DIGEST_ALGO;
+
+ rc = md_open (&h, algo, (hmac? GCRY_MD_FLAG_HMAC:0));
+ if (rc)
+ return rc;
+
+ if (hmac)
+ {
+ rc = _gcry_md_setkey (h,
+ (const char*)iov[0].data + iov[0].off,
+ iov[0].len);
+ if (rc)
+ {
+ md_close (h);
+ return rc;
+ }
+ iov++; iovcnt--;
+ }
+ for (;iovcnt; iov++, iovcnt--)
+ md_write (h, (const char*)iov[0].data + iov[0].off, iov[0].len);
+ md_final (h);
+ memcpy (digest, md_read (h, algo), dlen);
+ md_close (h);
+ }
+
+ return 0;
+}
+
+
+static int
+md_get_algo (gcry_md_hd_t a)
+{
+ GcryDigestEntry *r = a->ctx->list;
+
+ if (r && r->next)
+ {
+ fips_signal_error ("possible usage error");
+ log_error ("WARNING: more than one algorithm in md_get_algo()\n");
+ }
+ return r ? r->spec->algo : 0;
+}
+
+
+int
+_gcry_md_get_algo (gcry_md_hd_t hd)
+{
+ return md_get_algo (hd);
+}
+
+
+/****************
+ * Return the length of the digest
+ */
+static int
+md_digest_length (int algorithm)
+{
+ gcry_md_spec_t *spec;
+
+ spec = spec_from_algo (algorithm);
+ return spec? spec->mdlen : 0;
+}
+
+
+/****************
+ * Return the length of the digest in bytes.
+ * This function will return 0 in case of errors.
+ */
+unsigned int
+_gcry_md_get_algo_dlen (int algorithm)
+{
+ return md_digest_length (algorithm);
+}
+
+
+/* Hmmm: add a mode to enumerate the OIDs
+ * to make g10/sig-check.c more portable */
+static const byte *
+md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
+{
+ gcry_md_spec_t *spec;
+ const byte *asnoid = NULL;
+
+ spec = spec_from_algo (algorithm);
+ if (spec)
+ {
+ if (asnlen)
+ *asnlen = spec->asnlen;
+ if (mdlen)
+ *mdlen = spec->mdlen;
+ asnoid = spec->asnoid;
+ }
+ else
+ log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
+
+ return asnoid;
+}
+
+
+/****************
+ * Return information about the given cipher algorithm
+ * WHAT select the kind of information returned:
+ * GCRYCTL_TEST_ALGO:
+ * Returns 0 when the specified algorithm is available for use.
+ * buffer and nbytes must be zero.
+ * GCRYCTL_GET_ASNOID:
+ * Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
+ * the required length is returned.
+ * GCRYCTL_SELFTEST
+ * Helper for the regression tests - shall not be used by applications.
+ *
+ * Note: Because this function is in most cases used to return an
+ * integer value, we can make it easier for the caller to just look at
+ * the return value. The caller will in all cases consult the value
+ * and thereby detecting whether a error occurred or not (i.e. while checking
+ * the block size)
+ */
+gcry_err_code_t
+_gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t rc;
+
+ switch (what)
+ {
+ case GCRYCTL_TEST_ALGO:
+ if (buffer || nbytes)
+ rc = GPG_ERR_INV_ARG;
+ else
+ rc = check_digest_algo (algo);
+ break;
+
+ case GCRYCTL_GET_ASNOID:
+ /* We need to check that the algo is available because
+ md_asn_oid would otherwise raise an assertion. */
+ rc = check_digest_algo (algo);
+ if (!rc)
+ {
+ const char unsigned *asn;
+ size_t asnlen;
+
+ asn = md_asn_oid (algo, &asnlen, NULL);
+ if (buffer && (*nbytes >= asnlen))
+ {
+ memcpy (buffer, asn, asnlen);
+ *nbytes = asnlen;
+ }
+ else if (!buffer && nbytes)
+ *nbytes = asnlen;
+ else
+ {
+ if (buffer)
+ rc = GPG_ERR_TOO_SHORT;
+ else
+ rc = GPG_ERR_INV_ARG;
+ }
+ }
+ break;
+
+ case GCRYCTL_SELFTEST:
+ /* Helper function for the regression tests. */
+ rc = gpg_err_code (_gcry_md_selftest (algo, nbytes? (int)*nbytes : 0,
+ NULL));
+ break;
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ break;
+ }
+
+ return rc;
+}
+
+
+static void
+md_start_debug ( gcry_md_hd_t md, const char *suffix )
+{
+ static int idx=0;
+ char buf[50];
+
+ if (fips_mode ())
+ return;
+
+ if ( md->ctx->debug )
+ {
+ log_debug("Oops: md debug already started\n");
+ return;
+ }
+ idx++;
+ snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
+ md->ctx->debug = fopen(buf, "w");
+ if ( !md->ctx->debug )
+ log_debug("md debug: can't open %s\n", buf );
+}
+
+
+static void
+md_stop_debug( gcry_md_hd_t md )
+{
+ if ( md->ctx->debug )
+ {
+ if ( md->bufpos )
+ md_write ( md, NULL, 0 );
+ fclose (md->ctx->debug);
+ md->ctx->debug = NULL;
+ }
+
+ { /* a kludge to pull in the __muldi3 for Solaris */
+ volatile u32 a = (u32)(uintptr_t)md;
+ volatile u64 b = 42;
+ volatile u64 c;
+ c = a * b;
+ (void)c;
+ }
+}
+
+
+
+/*
+ * Return information about the digest handle.
+ * GCRYCTL_IS_SECURE:
+ * Returns 1 when the handle works on secured memory
+ * otherwise 0 is returned. There is no error return.
+ * GCRYCTL_IS_ALGO_ENABLED:
+ * Returns 1 if the algo is enabled for that handle.
+ * The algo must be passed as the address of an int.
+ */
+gcry_err_code_t
+_gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t rc = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_IS_SECURE:
+ *nbytes = h->ctx->flags.secure;
+ break;
+
+ case GCRYCTL_IS_ALGO_ENABLED:
+ {
+ GcryDigestEntry *r;
+ int algo;
+
+ if ( !buffer || !nbytes || *nbytes != sizeof (int))
+ rc = GPG_ERR_INV_ARG;
+ else
+ {
+ algo = *(int*)buffer;
+
+ *nbytes = 0;
+ for(r=h->ctx->list; r; r = r->next ) {
+ if (r->spec->algo == algo)
+ {
+ *nbytes = 1;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return rc;
+}
+
+
+/* Explicitly initialize this module. */
+gcry_err_code_t
+_gcry_md_init (void)
+{
+ if (fips_mode())
+ {
+ /* disable algorithms that are disallowed in fips */
+ int idx;
+ gcry_md_spec_t *spec;
+
+ for (idx = 0; (spec = digest_list[idx]); idx++)
+ if (!spec->flags.fips)
+ spec->flags.disabled = 1;
+ }
+
+ return 0;
+}
+
+
+int
+_gcry_md_is_secure (gcry_md_hd_t a)
+{
+ size_t value;
+
+ if (_gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
+ value = 1; /* It seems to be better to assume secure memory on
+ error. */
+ return value;
+}
+
+
+int
+_gcry_md_is_enabled (gcry_md_hd_t a, int algo)
+{
+ size_t value;
+
+ value = sizeof algo;
+ if (_gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
+ value = 0;
+ return value;
+}
+
+
+/* Run the selftests for digest algorithm ALGO with optional reporting
+ function REPORT. */
+gpg_error_t
+_gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_err_code_t ec = 0;
+ gcry_md_spec_t *spec;
+
+ spec = spec_from_algo (algo);
+ if (spec && !spec->flags.disabled && spec->selftest)
+ ec = spec->selftest (algo, extended, report);
+ else
+ {
+ ec = (spec && spec->selftest) ? GPG_ERR_DIGEST_ALGO
+ /* */ : GPG_ERR_NOT_IMPLEMENTED;
+ if (report)
+ report ("digest", algo, "module",
+ (spec && !spec->flags.disabled)?
+ "no selftest available" :
+ spec? "algorithm disabled" : "algorithm not found");
+ }
+
+ return gpg_error (ec);
+}
diff --git a/comm/third_party/libgcrypt/cipher/md4.c b/comm/third_party/libgcrypt/cipher/md4.c
new file mode 100644
index 0000000000..b55443a8aa
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/md4.c
@@ -0,0 +1,296 @@
+/* md4.c - MD4 Message-Digest Algorithm
+ * Copyright (C) 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
+ *
+ * Based on md5.c in libgcrypt, but rewritten to compute md4 checksums
+ * using a public domain md4 implementation with the following comments:
+ *
+ * Modified by Wei Dai from Andrew M. Kuchling's md4.c
+ * The original code and all modifications are in the public domain.
+ *
+ * This is the original introductory comment:
+ *
+ * md4.c : MD4 hash algorithm.
+ *
+ * Part of the Python Cryptography Toolkit, version 1.1
+ *
+ * Distribute and use freely; there are no restrictions on further
+ * dissemination and usage except those imposed by the laws of your
+ * country of residence.
+ *
+ */
+
+/* MD4 test suite:
+ * MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
+ * MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
+ * MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
+ * MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
+ * MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
+ * MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
+ * 043f8582f241db351ce627e153e7f0e4
+ * MD4 ("123456789012345678901234567890123456789012345678901234567890123456
+ * 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "hash-common.h"
+
+
+typedef struct {
+ gcry_md_block_ctx_t bctx;
+ u32 A,B,C,D; /* chaining variables */
+} MD4_CONTEXT;
+
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks );
+
+static void
+md4_init (void *context, unsigned int flags)
+{
+ MD4_CONTEXT *ctx = context;
+
+ (void)flags;
+
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+
+ ctx->bctx.nblocks = 0;
+ ctx->bctx.nblocks_high = 0;
+ ctx->bctx.count = 0;
+ ctx->bctx.blocksize_shift = _gcry_ctz(64);
+ ctx->bctx.bwrite = transform;
+}
+
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+
+/****************
+ * transform 64 bytes
+ */
+static unsigned int
+transform_blk ( void *c, const unsigned char *data )
+{
+ MD4_CONTEXT *ctx = c;
+ u32 in[16];
+ register u32 A = ctx->A;
+ register u32 B = ctx->B;
+ register u32 C = ctx->C;
+ register u32 D = ctx->D;
+ int i;
+
+ for ( i = 0; i < 16; i++ )
+ in[i] = buf_get_le32(data + i * 4);
+
+ /* Round 1. */
+#define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
+ function(A,B,C,D, 0, 3);
+ function(D,A,B,C, 1, 7);
+ function(C,D,A,B, 2,11);
+ function(B,C,D,A, 3,19);
+ function(A,B,C,D, 4, 3);
+ function(D,A,B,C, 5, 7);
+ function(C,D,A,B, 6,11);
+ function(B,C,D,A, 7,19);
+ function(A,B,C,D, 8, 3);
+ function(D,A,B,C, 9, 7);
+ function(C,D,A,B,10,11);
+ function(B,C,D,A,11,19);
+ function(A,B,C,D,12, 3);
+ function(D,A,B,C,13, 7);
+ function(C,D,A,B,14,11);
+ function(B,C,D,A,15,19);
+
+#undef function
+
+ /* Round 2. */
+#define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s);
+
+ function(A,B,C,D, 0, 3);
+ function(D,A,B,C, 4, 5);
+ function(C,D,A,B, 8, 9);
+ function(B,C,D,A,12,13);
+ function(A,B,C,D, 1, 3);
+ function(D,A,B,C, 5, 5);
+ function(C,D,A,B, 9, 9);
+ function(B,C,D,A,13,13);
+ function(A,B,C,D, 2, 3);
+ function(D,A,B,C, 6, 5);
+ function(C,D,A,B,10, 9);
+ function(B,C,D,A,14,13);
+ function(A,B,C,D, 3, 3);
+ function(D,A,B,C, 7, 5);
+ function(C,D,A,B,11, 9);
+ function(B,C,D,A,15,13);
+
+#undef function
+
+ /* Round 3. */
+#define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s);
+
+ function(A,B,C,D, 0, 3);
+ function(D,A,B,C, 8, 9);
+ function(C,D,A,B, 4,11);
+ function(B,C,D,A,12,15);
+ function(A,B,C,D, 2, 3);
+ function(D,A,B,C,10, 9);
+ function(C,D,A,B, 6,11);
+ function(B,C,D,A,14,15);
+ function(A,B,C,D, 1, 3);
+ function(D,A,B,C, 9, 9);
+ function(C,D,A,B, 5,11);
+ function(B,C,D,A,13,15);
+ function(A,B,C,D, 3, 3);
+ function(D,A,B,C,11, 9);
+ function(C,D,A,B, 7,11);
+ function(B,C,D,A,15,15);
+
+
+ /* Put checksum in context given as argument. */
+ ctx->A += A;
+ ctx->B += B;
+ ctx->C += C;
+ ctx->D += D;
+
+ return /*burn_stack*/ 80+6*sizeof(void*);
+}
+
+
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+ unsigned int burn;
+
+ do
+ {
+ burn = transform_blk (c, data);
+ data += 64;
+ }
+ while (--nblks);
+
+ return burn;
+}
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD4 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+static void
+md4_final( void *context )
+{
+ MD4_CONTEXT *hd = context;
+ u32 t, th, msb, lsb;
+ byte *p;
+ unsigned int burn;
+
+ t = hd->bctx.nblocks;
+ if (sizeof t == sizeof hd->bctx.nblocks)
+ th = hd->bctx.nblocks_high;
+ else
+ th = hd->bctx.nblocks >> 32;
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = (th << 6) | (t >> 26);
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->bctx.count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->bctx.count < 56) /* enough room */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ if (hd->bctx.count < 56)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+
+ /* append the 64 bit count */
+ buf_put_le32(hd->bctx.buf + 56, lsb);
+ buf_put_le32(hd->bctx.buf + 60, msb);
+ burn = transform (hd, hd->bctx.buf, 1);
+ }
+ else /* need one extra block */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ /* fill pad and next block with zeroes */
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+
+ /* append the 64 bit count */
+ buf_put_le32(hd->bctx.buf + 64 + 56, lsb);
+ buf_put_le32(hd->bctx.buf + 64 + 60, msb);
+ burn = transform (hd, hd->bctx.buf, 2);
+ }
+
+ p = hd->bctx.buf;
+#define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0)
+ X(A);
+ X(B);
+ X(C);
+ X(D);
+#undef X
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (burn);
+}
+
+static byte *
+md4_read (void *context)
+{
+ MD4_CONTEXT *hd = context;
+ return hd->bctx.buf;
+}
+
+static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
+ { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+ 0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
+
+static gcry_md_oid_spec_t oid_spec_md4[] =
+ {
+ /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
+ { "1.2.840.113549.2.4" },
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_md4 =
+ {
+ GCRY_MD_MD4, {0, 0},
+ "MD4", asn, DIM (asn), oid_spec_md4,16,
+ md4_init, _gcry_md_block_write, md4_final, md4_read, NULL,
+ NULL, NULL,
+ sizeof (MD4_CONTEXT)
+ };
diff --git a/comm/third_party/libgcrypt/cipher/md5.c b/comm/third_party/libgcrypt/cipher/md5.c
new file mode 100644
index 0000000000..32cb535aaa
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/md5.c
@@ -0,0 +1,322 @@
+/* md5.c - MD5 Message-Digest Algorithm
+ * Copyright (C) 1995,1996,1998,1999,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
+ *
+ * According to the definition of MD5 in RFC 1321 from April 1992.
+ * NOTE: This is *not* the same file as the one from glibc.
+ * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ * heavily modified for GnuPG by Werner Koch <wk@gnupg.org>
+ */
+
+/* Test values:
+ * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
+ * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
+ * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
+ * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "hash-common.h"
+
+
+typedef struct {
+ gcry_md_block_ctx_t bctx;
+ u32 A,B,C,D; /* chaining variables */
+} MD5_CONTEXT;
+
+static unsigned int
+transform ( void *ctx, const unsigned char *data, size_t datalen );
+
+static void
+md5_init( void *context, unsigned int flags)
+{
+ MD5_CONTEXT *ctx = context;
+
+ (void)flags;
+
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+
+ ctx->bctx.nblocks = 0;
+ ctx->bctx.nblocks_high = 0;
+ ctx->bctx.count = 0;
+ ctx->bctx.blocksize_shift = _gcry_ctz(64);
+ ctx->bctx.bwrite = transform;
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+ and defined in the RFC 1321. The first function is a little bit optimized
+ (as found in Colin Plumbs public domain implementation). */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+
+/****************
+ * transform 64 bytes
+ */
+static unsigned int
+transform_blk ( void *c, const unsigned char *data )
+{
+ MD5_CONTEXT *ctx = c;
+ u32 correct_words[16];
+ register u32 A = ctx->A;
+ register u32 B = ctx->B;
+ register u32 C = ctx->C;
+ register u32 D = ctx->D;
+ u32 *cwp = correct_words;
+ int i;
+
+ for ( i = 0; i < 16; i++ )
+ correct_words[i] = buf_get_le32(data + i * 4);
+
+#define OP(a, b, c, d, s, T) \
+ do \
+ { \
+ a += FF (b, c, d) + (*cwp++) + T; \
+ a = rol(a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* Before we start, one word about the strange constants.
+ They are defined in RFC 1321 as
+
+ T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+ */
+
+ /* Round 1. */
+ OP (A, B, C, D, 7, 0xd76aa478);
+ OP (D, A, B, C, 12, 0xe8c7b756);
+ OP (C, D, A, B, 17, 0x242070db);
+ OP (B, C, D, A, 22, 0xc1bdceee);
+ OP (A, B, C, D, 7, 0xf57c0faf);
+ OP (D, A, B, C, 12, 0x4787c62a);
+ OP (C, D, A, B, 17, 0xa8304613);
+ OP (B, C, D, A, 22, 0xfd469501);
+ OP (A, B, C, D, 7, 0x698098d8);
+ OP (D, A, B, C, 12, 0x8b44f7af);
+ OP (C, D, A, B, 17, 0xffff5bb1);
+ OP (B, C, D, A, 22, 0x895cd7be);
+ OP (A, B, C, D, 7, 0x6b901122);
+ OP (D, A, B, C, 12, 0xfd987193);
+ OP (C, D, A, B, 17, 0xa679438e);
+ OP (B, C, D, A, 22, 0x49b40821);
+
+#undef OP
+#define OP(f, a, b, c, d, k, s, T) \
+ do \
+ { \
+ a += f (b, c, d) + correct_words[k] + T; \
+ a = rol(a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* Round 2. */
+ OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
+ OP (FG, D, A, B, C, 6, 9, 0xc040b340);
+ OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+ OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+ OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
+ OP (FG, D, A, B, C, 10, 9, 0x02441453);
+ OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+ OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+ OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
+ OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
+ OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
+ OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
+ OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
+ OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+ OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
+ OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
+ OP (FH, D, A, B, C, 8, 11, 0x8771f681);
+ OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+ OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+ OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
+ OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+ OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+ OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+ OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
+ OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
+ OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
+ OP (FH, B, C, D, A, 6, 23, 0x04881d05);
+ OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
+ OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+ OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+ OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+ /* Round 4. */
+ OP (FI, A, B, C, D, 0, 6, 0xf4292244);
+ OP (FI, D, A, B, C, 7, 10, 0x432aff97);
+ OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+ OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
+ OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
+ OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+ OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+ OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
+ OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+ OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+ OP (FI, C, D, A, B, 6, 15, 0xa3014314);
+ OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+ OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
+ OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+ OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+ OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+ /* Put checksum in context given as argument. */
+ ctx->A += A;
+ ctx->B += B;
+ ctx->C += C;
+ ctx->D += D;
+
+ return /*burn_stack*/ 80+6*sizeof(void*);
+}
+
+
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+ unsigned int burn;
+
+ do
+ {
+ burn = transform_blk (c, data);
+ data += 64;
+ }
+ while (--nblks);
+
+ return burn;
+}
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD5 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+static void
+md5_final( void *context)
+{
+ MD5_CONTEXT *hd = context;
+ u32 t, th, msb, lsb;
+ byte *p;
+ unsigned int burn;
+
+ t = hd->bctx.nblocks;
+ if (sizeof t == sizeof hd->bctx.nblocks)
+ th = hd->bctx.nblocks_high;
+ else
+ th = hd->bctx.nblocks >> 32;
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = (th << 6) | (t >> 26);
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->bctx.count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->bctx.count < 56) /* enough room */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ if (hd->bctx.count < 56)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+
+ /* append the 64 bit count */
+ buf_put_le32(hd->bctx.buf + 56, lsb);
+ buf_put_le32(hd->bctx.buf + 60, msb);
+ burn = transform (hd, hd->bctx.buf, 1);
+ }
+ else /* need one extra block */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ /* fill pad and next block with zeroes */
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+
+ /* append the 64 bit count */
+ buf_put_le32(hd->bctx.buf + 64 + 56, lsb);
+ buf_put_le32(hd->bctx.buf + 64 + 60, msb);
+ burn = transform (hd, hd->bctx.buf, 2);
+ }
+
+ p = hd->bctx.buf;
+#define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0)
+ X(A);
+ X(B);
+ X(C);
+ X(D);
+#undef X
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (burn);
+}
+
+static byte *
+md5_read( void *context )
+{
+ MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
+ return hd->bctx.buf;
+}
+
+static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
+ { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+ 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
+
+static gcry_md_oid_spec_t oid_spec_md5[] =
+ {
+ /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */
+ { "1.2.840.113549.1.1.4" },
+ /* RSADSI digestAlgorithm MD5 */
+ { "1.2.840.113549.2.5" },
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_md5 =
+ {
+ GCRY_MD_MD5, {0, 0},
+ "MD5", asn, DIM (asn), oid_spec_md5, 16,
+ md5_init, _gcry_md_block_write, md5_final, md5_read, NULL,
+ NULL, NULL,
+ sizeof (MD5_CONTEXT)
+ };
diff --git a/comm/third_party/libgcrypt/cipher/poly1305-internal.h b/comm/third_party/libgcrypt/cipher/poly1305-internal.h
new file mode 100644
index 0000000000..19cee5f6f3
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/poly1305-internal.h
@@ -0,0 +1,64 @@
+/* poly1305-internal.h - Poly1305 internals
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G10_POLY1305_INTERNAL_H
+#define G10_POLY1305_INTERNAL_H
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+
+#define POLY1305_TAGLEN 16
+#define POLY1305_KEYLEN 32
+#define POLY1305_BLOCKSIZE 16
+
+
+typedef struct
+{
+ u32 k[4];
+ u32 r[4];
+ u32 h[5];
+} POLY1305_STATE;
+
+typedef struct poly1305_context_s
+{
+ POLY1305_STATE state;
+ byte buffer[POLY1305_BLOCKSIZE];
+ unsigned int leftover;
+} poly1305_context_t;
+
+
+gcry_err_code_t _gcry_poly1305_init (poly1305_context_t *ctx, const byte *key,
+ size_t keylen);
+
+void _gcry_poly1305_finish (poly1305_context_t *ctx,
+ byte mac[POLY1305_TAGLEN]);
+
+void _gcry_poly1305_update (poly1305_context_t *ctx, const byte *buf,
+ size_t buflen);
+
+unsigned int _gcry_poly1305_update_burn (poly1305_context_t *ctx,
+ const byte *m, size_t bytes);
+
+#endif /* G10_POLY1305_INTERNAL_H */
diff --git a/comm/third_party/libgcrypt/cipher/poly1305-s390x.S b/comm/third_party/libgcrypt/cipher/poly1305-s390x.S
new file mode 100644
index 0000000000..844245f6ad
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/poly1305-s390x.S
@@ -0,0 +1,87 @@
+/* poly1305-s390x.S - zSeries implementation of Poly1305
+ *
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9
+#include <config.h>
+#if defined(HAVE_GCC_INLINE_ASM_S390X)
+
+#include "asm-poly1305-s390x.h"
+
+.text
+
+.balign 8
+.globl _gcry_poly1305_s390x_blocks1
+ELF(.type _gcry_poly1305_s390x_blocks1,@function;)
+
+_gcry_poly1305_s390x_blocks1:
+ /* input:
+ * %r2: poly1305-state
+ * %r3: src
+ * %r4: len
+ * %r5: high_pad
+ */
+ CFI_STARTPROC();
+
+ stmg %r6, %r14, 6 * 8(%r15);
+
+ lgr POLY_RSTATE, %r2;
+ lgr POLY_RSRC, %r3;
+ srlg %r0, %r4, 4;
+
+ cgije %r5, 0, .Lpoly_high0;
+
+ POLY1305_LOAD_STATE();
+
+.balign 4
+.Lpoly_loop_high1:
+ POLY1305_BLOCK_PART1(0 * 16);
+ INC_POLY1305_SRC(1 * 16);
+.Lpoly_block_part2:
+ POLY1305_BLOCK_PART2();
+ POLY1305_BLOCK_PART3();
+ POLY1305_BLOCK_PART4();
+ POLY1305_BLOCK_PART5();
+ POLY1305_BLOCK_PART6();
+ POLY1305_BLOCK_PART7();
+ POLY1305_BLOCK_PART8();
+
+ brctg %r0, .Lpoly_loop_high1;
+
+.balign 4
+.Lpoly_done:
+ POLY1305_STORE_STATE();
+
+ lmg %r6, %r14, 6 * 8(%r15);
+ xgr %r2, %r2;
+ br %r14;
+
+.balign 4
+.Lpoly_high0:
+ lghi %r0, 1;
+ POLY1305_LOAD_STATE();
+ POLY1305_BLOCK_PART1_HB(0 * 16, 0);
+ j .Lpoly_block_part2;
+
+ CFI_ENDPROC();
+ELF(.size _gcry_poly1305_s390x_blocks1,
+ .-_gcry_poly1305_s390x_blocks1;)
+
+#endif /*HAVE_GCC_INLINE_ASM_S390X*/
+#endif /*__s390x__*/
diff --git a/comm/third_party/libgcrypt/cipher/poly1305.c b/comm/third_party/libgcrypt/cipher/poly1305.c
new file mode 100644
index 0000000000..6cb4d2b72d
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/poly1305.c
@@ -0,0 +1,740 @@
+/* poly1305.c - Poly1305 internals and generic implementation
+ * Copyright (C) 2014,2017,2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "poly1305-internal.h"
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+static const char *selftest (void);
+
+
+#undef HAVE_ASM_POLY1305_BLOCKS
+
+
+#undef USE_MPI_64BIT
+#undef USE_MPI_32BIT
+#if BYTES_PER_MPI_LIMB == 8 && defined(HAVE_TYPE_U64)
+# define USE_MPI_64BIT 1
+#elif BYTES_PER_MPI_LIMB == 4
+# define USE_MPI_32BIT 1
+#else
+# error please implement for this limb size.
+#endif
+
+
+/* USE_S390X_ASM indicates whether to enable zSeries code. */
+#undef USE_S390X_ASM
+#if BYTES_PER_MPI_LIMB == 8
+# if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9
+# if defined(HAVE_GCC_INLINE_ASM_S390X)
+# define USE_S390X_ASM 1
+# endif /* USE_S390X_ASM */
+# endif
+#endif
+
+
+#ifdef USE_S390X_ASM
+
+#define HAVE_ASM_POLY1305_BLOCKS 1
+
+extern unsigned int _gcry_poly1305_s390x_blocks1(void *state,
+ const byte *buf, size_t len,
+ byte high_pad);
+
+static unsigned int
+poly1305_blocks (poly1305_context_t *ctx, const byte *buf, size_t len,
+ byte high_pad)
+{
+ return _gcry_poly1305_s390x_blocks1(&ctx->state, buf, len, high_pad);
+}
+
+#endif /* USE_S390X_ASM */
+
+
+static void poly1305_init (poly1305_context_t *ctx,
+ const byte key[POLY1305_KEYLEN])
+{
+ POLY1305_STATE *st = &ctx->state;
+
+ ctx->leftover = 0;
+
+ st->h[0] = 0;
+ st->h[1] = 0;
+ st->h[2] = 0;
+ st->h[3] = 0;
+ st->h[4] = 0;
+
+ st->r[0] = buf_get_le32(key + 0) & 0x0fffffff;
+ st->r[1] = buf_get_le32(key + 4) & 0x0ffffffc;
+ st->r[2] = buf_get_le32(key + 8) & 0x0ffffffc;
+ st->r[3] = buf_get_le32(key + 12) & 0x0ffffffc;
+
+ st->k[0] = buf_get_le32(key + 16);
+ st->k[1] = buf_get_le32(key + 20);
+ st->k[2] = buf_get_le32(key + 24);
+ st->k[3] = buf_get_le32(key + 28);
+}
+
+
+#ifdef USE_MPI_64BIT
+
+#if defined (__aarch64__) && __GNUC__ >= 4
+
+/* A += B (armv8/aarch64) */
+#define ADD_1305_64(A2, A1, A0, B2, B1, B0) \
+ __asm__ ("adds %0, %3, %0\n" \
+ "adcs %1, %4, %1\n" \
+ "adc %2, %5, %2\n" \
+ : "+r" (A0), "+r" (A1), "+r" (A2) \
+ : "r" (B0), "r" (B1), "r" (B2) \
+ : "cc" )
+
+#endif /* __aarch64__ */
+
+#if defined (__x86_64__) && __GNUC__ >= 4
+
+/* A += B (x86-64) */
+#define ADD_1305_64(A2, A1, A0, B2, B1, B0) \
+ __asm__ ("addq %3, %0\n" \
+ "adcq %4, %1\n" \
+ "adcq %5, %2\n" \
+ : "+r" (A0), "+r" (A1), "+r" (A2) \
+ : "g" (B0), "g" (B1), "g" (B2) \
+ : "cc" )
+
+#endif /* __x86_64__ */
+
+#if defined (__powerpc__) && __GNUC__ >= 4
+
+/* A += B (ppc64) */
+#define ADD_1305_64(A2, A1, A0, B2, B1, B0) \
+ __asm__ ("addc %0, %3, %0\n" \
+ "adde %1, %4, %1\n" \
+ "adde %2, %5, %2\n" \
+ : "+r" (A0), "+r" (A1), "+r" (A2) \
+ : "r" (B0), "r" (B1), "r" (B2) \
+ : "cc" )
+
+#endif /* __powerpc__ */
+
+#ifndef ADD_1305_64
+/* A += B (generic, mpi) */
+# define ADD_1305_64(A2, A1, A0, B2, B1, B0) do { \
+ u64 carry; \
+ add_ssaaaa(carry, A0, 0, A0, 0, B0); \
+ add_ssaaaa(A2, A1, A2, A1, B2, B1); \
+ add_ssaaaa(A2, A1, A2, A1, 0, carry); \
+ } while (0)
+#endif
+
+/* H = H * R mod 2¹³â°-5 */
+#define MUL_MOD_1305_64(H2, H1, H0, R1, R0, R1_MULT5) do { \
+ u64 x0_lo, x0_hi, x1_lo, x1_hi; \
+ u64 t0_lo, t0_hi, t1_lo, t1_hi; \
+ \
+ /* x = a * r (partial mod 2^130-5) */ \
+ umul_ppmm(x0_hi, x0_lo, H0, R0); /* h0 * r0 */ \
+ umul_ppmm(x1_hi, x1_lo, H0, R1); /* h0 * r1 */ \
+ \
+ umul_ppmm(t0_hi, t0_lo, H1, R1_MULT5); /* h1 * r1 mod 2^130-5 */ \
+ add_ssaaaa(x0_hi, x0_lo, x0_hi, x0_lo, t0_hi, t0_lo); \
+ umul_ppmm(t1_hi, t1_lo, H1, R0); /* h1 * r0 */ \
+ add_ssaaaa(x1_hi, x1_lo, x1_hi, x1_lo, t1_hi, t1_lo); \
+ \
+ t1_lo = H2 * R1_MULT5; /* h2 * r1 mod 2^130-5 */ \
+ t1_hi = H2 * R0; /* h2 * r0 */ \
+ add_ssaaaa(H0, H1, x1_hi, x1_lo, t1_hi, t1_lo); \
+ \
+ /* carry propagation */ \
+ H2 = H0 & 3; \
+ H0 = (H0 >> 2) * 5; /* msb mod 2^130-5 */ \
+ ADD_1305_64(H2, H1, H0, (u64)0, x0_hi, x0_lo); \
+ } while (0)
+
+#ifndef HAVE_ASM_POLY1305_BLOCKS
+
+static unsigned int
+poly1305_blocks (poly1305_context_t *ctx, const byte *buf, size_t len,
+ byte high_pad)
+{
+ POLY1305_STATE *st = &ctx->state;
+ u64 r0, r1, r1_mult5;
+ u64 h0, h1, h2;
+ u64 m0, m1, m2;
+
+ m2 = high_pad;
+
+ h0 = st->h[0] + ((u64)st->h[1] << 32);
+ h1 = st->h[2] + ((u64)st->h[3] << 32);
+ h2 = st->h[4];
+
+ r0 = st->r[0] + ((u64)st->r[1] << 32);
+ r1 = st->r[2] + ((u64)st->r[3] << 32);
+
+ r1_mult5 = (r1 >> 2) + r1;
+
+ m0 = buf_get_le64(buf + 0);
+ m1 = buf_get_le64(buf + 8);
+ buf += POLY1305_BLOCKSIZE;
+ len -= POLY1305_BLOCKSIZE;
+
+ while (len >= POLY1305_BLOCKSIZE)
+ {
+ /* a = h + m */
+ ADD_1305_64(h2, h1, h0, m2, m1, m0);
+
+ m0 = buf_get_le64(buf + 0);
+ m1 = buf_get_le64(buf + 8);
+
+ /* h = a * r (partial mod 2^130-5) */
+ MUL_MOD_1305_64(h2, h1, h0, r1, r0, r1_mult5);
+
+ buf += POLY1305_BLOCKSIZE;
+ len -= POLY1305_BLOCKSIZE;
+ }
+
+ /* a = h + m */
+ ADD_1305_64(h2, h1, h0, m2, m1, m0);
+
+ /* h = a * r (partial mod 2^130-5) */
+ MUL_MOD_1305_64(h2, h1, h0, r1, r0, r1_mult5);
+
+ st->h[0] = h0;
+ st->h[1] = h0 >> 32;
+ st->h[2] = h1;
+ st->h[3] = h1 >> 32;
+ st->h[4] = h2;
+
+ return 6 * sizeof (void *) + 18 * sizeof (u64);
+}
+
+#endif /* !HAVE_ASM_POLY1305_BLOCKS */
+
+static unsigned int poly1305_final (poly1305_context_t *ctx,
+ byte mac[POLY1305_TAGLEN])
+{
+ POLY1305_STATE *st = &ctx->state;
+ unsigned int burn = 0;
+ u64 u, carry;
+ u64 k0, k1;
+ u64 h0, h1;
+ u64 h2;
+
+ /* process the remaining block */
+ if (ctx->leftover)
+ {
+ ctx->buffer[ctx->leftover++] = 1;
+ if (ctx->leftover < POLY1305_BLOCKSIZE)
+ {
+ memset (&ctx->buffer[ctx->leftover], 0,
+ POLY1305_BLOCKSIZE - ctx->leftover);
+ ctx->leftover = POLY1305_BLOCKSIZE;
+ }
+ burn = poly1305_blocks (ctx, ctx->buffer, POLY1305_BLOCKSIZE, 0);
+ }
+
+ h0 = st->h[0] + ((u64)st->h[1] << 32);
+ h1 = st->h[2] + ((u64)st->h[3] << 32);
+ h2 = st->h[4];
+
+ k0 = st->k[0] + ((u64)st->k[1] << 32);
+ k1 = st->k[2] + ((u64)st->k[3] << 32);
+
+ /* check if h is more than 2^130-5, by adding 5. */
+ add_ssaaaa(carry, u, 0, h0, 0, 5);
+ add_ssaaaa(carry, u, 0, carry, 0, h1);
+ u = (carry + h2) >> 2; /* u == 0 or 1 */
+
+ /* minus 2^130-5 ... (+5) */
+ u = (-u) & 5;
+ add_ssaaaa(h1, h0, h1, h0, 0, u);
+
+ /* add high part of key + h */
+ add_ssaaaa(h1, h0, h1, h0, k1, k0);
+ buf_put_le64(mac + 0, h0);
+ buf_put_le64(mac + 8, h1);
+
+ /* burn_stack */
+ return 4 * sizeof (void *) + 7 * sizeof (u64) + burn;
+}
+
+#endif /* USE_MPI_64BIT */
+
+#ifdef USE_MPI_32BIT
+
+#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+/* HI:LO += A * B (arm) */
+#define UMUL_ADD_32(HI, LO, A, B) \
+ __asm__ ("umlal %1, %0, %4, %5" \
+ : "=r" (HI), "=r" (LO) \
+ : "0" (HI), "1" (LO), "r" (A), "r" (B) )
+
+/* A += B (arm) */
+#define ADD_1305_32(A4, A3, A2, A1, A0, B4, B3, B2, B1, B0) \
+ __asm__ ("adds %0, %0, %5\n" \
+ "adcs %1, %1, %6\n" \
+ "adcs %2, %2, %7\n" \
+ "adcs %3, %3, %8\n" \
+ "adc %4, %4, %9\n" \
+ : "+r" (A0), "+r" (A1), "+r" (A2), "+r" (A3), "+r" (A4) \
+ : "r" (B0), "r" (B1), "r" (B2), "r" (B3), "r" (B4) \
+ : "cc" )
+
+#endif /* HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS */
+
+#if defined (__i386__) && __GNUC__ >= 4
+
+/* A += B (i386) */
+#define ADD_1305_32(A4, A3, A2, A1, A0, B4, B3, B2, B1, B0) \
+ __asm__ ("addl %5, %0\n" \
+ "adcl %6, %1\n" \
+ "adcl %7, %2\n" \
+ "adcl %8, %3\n" \
+ "adcl %9, %4\n" \
+ : "+r" (A0), "+r" (A1), "+r" (A2), "+r" (A3), "+r" (A4) \
+ : "g" (B0), "g" (B1), "g" (B2), "g" (B3), "g" (B4) \
+ : "cc" )
+
+#endif /* __i386__ */
+
+#ifndef UMUL_ADD_32
+/* HI:LO += A * B (generic, mpi) */
+# define UMUL_ADD_32(HI, LO, A, B) do { \
+ u32 t_lo, t_hi; \
+ umul_ppmm(t_hi, t_lo, A, B); \
+ add_ssaaaa(HI, LO, HI, LO, t_hi, t_lo); \
+ } while (0)
+#endif
+
+#ifndef ADD_1305_32
+/* A += B (generic, mpi) */
+# define ADD_1305_32(A4, A3, A2, A1, A0, B4, B3, B2, B1, B0) do { \
+ u32 carry0, carry1, carry2; \
+ add_ssaaaa(carry0, A0, 0, A0, 0, B0); \
+ add_ssaaaa(carry1, A1, 0, A1, 0, B1); \
+ add_ssaaaa(carry1, A1, carry1, A1, 0, carry0); \
+ add_ssaaaa(carry2, A2, 0, A2, 0, B2); \
+ add_ssaaaa(carry2, A2, carry2, A2, 0, carry1); \
+ add_ssaaaa(A4, A3, A4, A3, B4, B3); \
+ add_ssaaaa(A4, A3, A4, A3, 0, carry2); \
+ } while (0)
+#endif
+
+/* H = H * R mod 2¹³â°-5 */
+#define MUL_MOD_1305_32(H4, H3, H2, H1, H0, R3, R2, R1, R0, \
+ R3_MULT5, R2_MULT5, R1_MULT5) do { \
+ u32 x0_lo, x0_hi, x1_lo, x1_hi, x2_lo, x2_hi, x3_lo, x3_hi; \
+ u32 t0_lo, t0_hi; \
+ \
+ /* x = a * r (partial mod 2^130-5) */ \
+ umul_ppmm(x0_hi, x0_lo, H0, R0); /* h0 * r0 */ \
+ umul_ppmm(x1_hi, x1_lo, H0, R1); /* h0 * r1 */ \
+ umul_ppmm(x2_hi, x2_lo, H0, R2); /* h0 * r2 */ \
+ umul_ppmm(x3_hi, x3_lo, H0, R3); /* h0 * r3 */ \
+ \
+ UMUL_ADD_32(x0_hi, x0_lo, H1, R3_MULT5); /* h1 * r3 mod 2^130-5 */ \
+ UMUL_ADD_32(x1_hi, x1_lo, H1, R0); /* h1 * r0 */ \
+ UMUL_ADD_32(x2_hi, x2_lo, H1, R1); /* h1 * r1 */ \
+ UMUL_ADD_32(x3_hi, x3_lo, H1, R2); /* h1 * r2 */ \
+ \
+ UMUL_ADD_32(x0_hi, x0_lo, H2, R2_MULT5); /* h2 * r2 mod 2^130-5 */ \
+ UMUL_ADD_32(x1_hi, x1_lo, H2, R3_MULT5); /* h2 * r3 mod 2^130-5 */ \
+ UMUL_ADD_32(x2_hi, x2_lo, H2, R0); /* h2 * r0 */ \
+ UMUL_ADD_32(x3_hi, x3_lo, H2, R1); /* h2 * r1 */ \
+ \
+ UMUL_ADD_32(x0_hi, x0_lo, H3, R1_MULT5); /* h3 * r1 mod 2^130-5 */ \
+ H1 = x0_hi; \
+ UMUL_ADD_32(x1_hi, x1_lo, H3, R2_MULT5); /* h3 * r2 mod 2^130-5 */ \
+ UMUL_ADD_32(x2_hi, x2_lo, H3, R3_MULT5); /* h3 * r3 mod 2^130-5 */ \
+ UMUL_ADD_32(x3_hi, x3_lo, H3, R0); /* h3 * r0 */ \
+ \
+ t0_lo = H4 * R1_MULT5; /* h4 * r1 mod 2^130-5 */ \
+ t0_hi = H4 * R2_MULT5; /* h4 * r2 mod 2^130-5 */ \
+ add_ssaaaa(H2, x1_lo, x1_hi, x1_lo, 0, t0_lo); \
+ add_ssaaaa(H3, x2_lo, x2_hi, x2_lo, 0, t0_hi); \
+ t0_lo = H4 * R3_MULT5; /* h4 * r3 mod 2^130-5 */ \
+ t0_hi = H4 * R0; /* h4 * r0 */ \
+ add_ssaaaa(H4, x3_lo, x3_hi, x3_lo, t0_hi, t0_lo); \
+ \
+ /* carry propagation */ \
+ H0 = (H4 >> 2) * 5; /* msb mod 2^130-5 */ \
+ H4 = H4 & 3; \
+ ADD_1305_32(H4, H3, H2, H1, H0, 0, x3_lo, x2_lo, x1_lo, x0_lo); \
+ } while (0)
+
+#ifndef HAVE_ASM_POLY1305_BLOCKS
+
+static unsigned int
+poly1305_blocks (poly1305_context_t *ctx, const byte *buf, size_t len,
+ byte high_pad)
+{
+ POLY1305_STATE *st = &ctx->state;
+ u32 r1_mult5, r2_mult5, r3_mult5;
+ u32 h0, h1, h2, h3, h4;
+ u32 m0, m1, m2, m3, m4;
+
+ m4 = high_pad;
+
+ h0 = st->h[0];
+ h1 = st->h[1];
+ h2 = st->h[2];
+ h3 = st->h[3];
+ h4 = st->h[4];
+
+ r1_mult5 = (st->r[1] >> 2) + st->r[1];
+ r2_mult5 = (st->r[2] >> 2) + st->r[2];
+ r3_mult5 = (st->r[3] >> 2) + st->r[3];
+
+ while (len >= POLY1305_BLOCKSIZE)
+ {
+ m0 = buf_get_le32(buf + 0);
+ m1 = buf_get_le32(buf + 4);
+ m2 = buf_get_le32(buf + 8);
+ m3 = buf_get_le32(buf + 12);
+
+ /* a = h + m */
+ ADD_1305_32(h4, h3, h2, h1, h0, m4, m3, m2, m1, m0);
+
+ /* h = a * r (partial mod 2^130-5) */
+ MUL_MOD_1305_32(h4, h3, h2, h1, h0,
+ st->r[3], st->r[2], st->r[1], st->r[0],
+ r3_mult5, r2_mult5, r1_mult5);
+
+ buf += POLY1305_BLOCKSIZE;
+ len -= POLY1305_BLOCKSIZE;
+ }
+
+ st->h[0] = h0;
+ st->h[1] = h1;
+ st->h[2] = h2;
+ st->h[3] = h3;
+ st->h[4] = h4;
+
+ return 6 * sizeof (void *) + 28 * sizeof (u32);
+}
+
+#endif /* !HAVE_ASM_POLY1305_BLOCKS */
+
+static unsigned int poly1305_final (poly1305_context_t *ctx,
+ byte mac[POLY1305_TAGLEN])
+{
+ POLY1305_STATE *st = &ctx->state;
+ unsigned int burn = 0;
+ u32 carry, tmp0, tmp1, tmp2, u;
+ u32 h4, h3, h2, h1, h0;
+
+ /* process the remaining block */
+ if (ctx->leftover)
+ {
+ ctx->buffer[ctx->leftover++] = 1;
+ if (ctx->leftover < POLY1305_BLOCKSIZE)
+ {
+ memset (&ctx->buffer[ctx->leftover], 0,
+ POLY1305_BLOCKSIZE - ctx->leftover);
+ ctx->leftover = POLY1305_BLOCKSIZE;
+ }
+ burn = poly1305_blocks (ctx, ctx->buffer, POLY1305_BLOCKSIZE, 0);
+ }
+
+ h0 = st->h[0];
+ h1 = st->h[1];
+ h2 = st->h[2];
+ h3 = st->h[3];
+ h4 = st->h[4];
+
+ /* check if h is more than 2^130-5, by adding 5. */
+ add_ssaaaa(carry, tmp0, 0, h0, 0, 5);
+ add_ssaaaa(carry, tmp0, 0, carry, 0, h1);
+ add_ssaaaa(carry, tmp0, 0, carry, 0, h2);
+ add_ssaaaa(carry, tmp0, 0, carry, 0, h3);
+ u = (carry + h4) >> 2; /* u == 0 or 1 */
+
+ /* minus 2^130-5 ... (+5) */
+ u = (-u) & 5;
+ add_ssaaaa(carry, h0, 0, h0, 0, u);
+ add_ssaaaa(carry, h1, 0, h1, 0, carry);
+ add_ssaaaa(carry, h2, 0, h2, 0, carry);
+ add_ssaaaa(carry, h3, 0, h3, 0, carry);
+
+ /* add high part of key + h */
+ add_ssaaaa(tmp0, h0, 0, h0, 0, st->k[0]);
+ add_ssaaaa(tmp1, h1, 0, h1, 0, st->k[1]);
+ add_ssaaaa(tmp1, h1, tmp1, h1, 0, tmp0);
+ add_ssaaaa(tmp2, h2, 0, h2, 0, st->k[2]);
+ add_ssaaaa(tmp2, h2, tmp2, h2, 0, tmp1);
+ add_ssaaaa(carry, h3, 0, h3, 0, st->k[3]);
+ h3 += tmp2;
+
+ buf_put_le32(mac + 0, h0);
+ buf_put_le32(mac + 4, h1);
+ buf_put_le32(mac + 8, h2);
+ buf_put_le32(mac + 12, h3);
+
+ /* burn_stack */
+ return 4 * sizeof (void *) + 10 * sizeof (u32) + burn;
+}
+
+#endif /* USE_MPI_32BIT */
+
+
+unsigned int
+_gcry_poly1305_update_burn (poly1305_context_t *ctx, const byte *m,
+ size_t bytes)
+{
+ unsigned int burn = 0;
+
+ /* handle leftover */
+ if (ctx->leftover)
+ {
+ size_t want = (POLY1305_BLOCKSIZE - ctx->leftover);
+ if (want > bytes)
+ want = bytes;
+ buf_cpy (ctx->buffer + ctx->leftover, m, want);
+ bytes -= want;
+ m += want;
+ ctx->leftover += want;
+ if (ctx->leftover < POLY1305_BLOCKSIZE)
+ return 0;
+ burn = poly1305_blocks (ctx, ctx->buffer, POLY1305_BLOCKSIZE, 1);
+ ctx->leftover = 0;
+ }
+
+ /* process full blocks */
+ if (bytes >= POLY1305_BLOCKSIZE)
+ {
+ size_t nblks = bytes / POLY1305_BLOCKSIZE;
+ burn = poly1305_blocks (ctx, m, nblks * POLY1305_BLOCKSIZE, 1);
+ m += nblks * POLY1305_BLOCKSIZE;
+ bytes -= nblks * POLY1305_BLOCKSIZE;
+ }
+
+ /* store leftover */
+ if (bytes)
+ {
+ buf_cpy (ctx->buffer + ctx->leftover, m, bytes);
+ ctx->leftover += bytes;
+ }
+
+ return burn;
+}
+
+
+void
+_gcry_poly1305_update (poly1305_context_t *ctx, const byte *m, size_t bytes)
+{
+ unsigned int burn;
+
+ burn = _gcry_poly1305_update_burn (ctx, m, bytes);
+
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+
+void
+_gcry_poly1305_finish (poly1305_context_t *ctx, byte mac[POLY1305_TAGLEN])
+{
+ unsigned int burn;
+
+ burn = poly1305_final (ctx, mac);
+
+ _gcry_burn_stack (burn);
+}
+
+
+gcry_err_code_t
+_gcry_poly1305_init (poly1305_context_t * ctx, const byte * key,
+ size_t keylen)
+{
+ static int initialized;
+ static const char *selftest_failed;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if (selftest_failed)
+ log_error ("Poly1305 selftest failed (%s)\n", selftest_failed);
+ }
+
+ if (keylen != POLY1305_KEYLEN)
+ return GPG_ERR_INV_KEYLEN;
+
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ poly1305_init (ctx, key);
+
+ return 0;
+}
+
+
+static void
+poly1305_auth (byte mac[POLY1305_TAGLEN], const byte * m, size_t bytes,
+ const byte * key)
+{
+ poly1305_context_t ctx;
+
+ memset (&ctx, 0, sizeof (ctx));
+
+ _gcry_poly1305_init (&ctx, key, POLY1305_KEYLEN);
+ _gcry_poly1305_update (&ctx, m, bytes);
+ _gcry_poly1305_finish (&ctx, mac);
+
+ wipememory (&ctx, sizeof (ctx));
+}
+
+
+static const char *
+selftest (void)
+{
+ /* example from nacl */
+ static const byte nacl_key[POLY1305_KEYLEN] = {
+ 0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91,
+ 0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25,
+ 0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65,
+ 0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80,
+ };
+
+ static const byte nacl_msg[131] = {
+ 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
+ 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
+ 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
+ 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
+ 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
+ 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
+ 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
+ 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
+ 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
+ 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
+ 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
+ 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
+ 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
+ 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
+ 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
+ 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
+ 0xe3, 0x55, 0xa5
+ };
+
+ static const byte nacl_mac[16] = {
+ 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
+ 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9
+ };
+
+ /* generates a final value of (2^130 - 2) == 3 */
+ static const byte wrap_key[POLY1305_KEYLEN] = {
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+
+ static const byte wrap_msg[16] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+
+ static const byte wrap_mac[16] = {
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+
+ /* mac of the macs of messages of length 0 to 256, where the key and messages
+ * have all their values set to the length
+ */
+ static const byte total_key[POLY1305_KEYLEN] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+
+ static const byte total_mac[16] = {
+ 0x64, 0xaf, 0xe2, 0xe8, 0xd6, 0xad, 0x7b, 0xbd,
+ 0xd2, 0x87, 0xf9, 0x7c, 0x44, 0x62, 0x3d, 0x39
+ };
+
+ poly1305_context_t ctx;
+ poly1305_context_t total_ctx;
+ byte all_key[POLY1305_KEYLEN];
+ byte all_msg[256];
+ byte mac[16];
+ size_t i, j;
+
+ memset (&ctx, 0, sizeof (ctx));
+ memset (&total_ctx, 0, sizeof (total_ctx));
+
+ memset (mac, 0, sizeof (mac));
+ poly1305_auth (mac, nacl_msg, sizeof (nacl_msg), nacl_key);
+ if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
+ return "Poly1305 test 1 failed.";
+
+ /* SSE2/AVX have a 32 byte block size, but also support 64 byte blocks, so
+ * make sure everything still works varying between them */
+ memset (mac, 0, sizeof (mac));
+ _gcry_poly1305_init (&ctx, nacl_key, POLY1305_KEYLEN);
+ _gcry_poly1305_update (&ctx, nacl_msg + 0, 32);
+ _gcry_poly1305_update (&ctx, nacl_msg + 32, 64);
+ _gcry_poly1305_update (&ctx, nacl_msg + 96, 16);
+ _gcry_poly1305_update (&ctx, nacl_msg + 112, 8);
+ _gcry_poly1305_update (&ctx, nacl_msg + 120, 4);
+ _gcry_poly1305_update (&ctx, nacl_msg + 124, 2);
+ _gcry_poly1305_update (&ctx, nacl_msg + 126, 1);
+ _gcry_poly1305_update (&ctx, nacl_msg + 127, 1);
+ _gcry_poly1305_update (&ctx, nacl_msg + 128, 1);
+ _gcry_poly1305_update (&ctx, nacl_msg + 129, 1);
+ _gcry_poly1305_update (&ctx, nacl_msg + 130, 1);
+ _gcry_poly1305_finish (&ctx, mac);
+ if (memcmp (nacl_mac, mac, sizeof (nacl_mac)) != 0)
+ return "Poly1305 test 2 failed.";
+
+ memset (mac, 0, sizeof (mac));
+ poly1305_auth (mac, wrap_msg, sizeof (wrap_msg), wrap_key);
+ if (memcmp (wrap_mac, mac, sizeof (nacl_mac)) != 0)
+ return "Poly1305 test 3 failed.";
+
+ _gcry_poly1305_init (&total_ctx, total_key, POLY1305_KEYLEN);
+ for (i = 0; i < 256; i++)
+ {
+ /* set key and message to 'i,i,i..' */
+ for (j = 0; j < sizeof (all_key); j++)
+ all_key[j] = i;
+ for (j = 0; j < i; j++)
+ all_msg[j] = i;
+ poly1305_auth (mac, all_msg, i, all_key);
+ _gcry_poly1305_update (&total_ctx, mac, 16);
+ }
+ _gcry_poly1305_finish (&total_ctx, mac);
+ if (memcmp (total_mac, mac, sizeof (total_mac)) != 0)
+ return "Poly1305 test 4 failed.";
+
+ return NULL;
+}
diff --git a/comm/third_party/libgcrypt/cipher/primegen.c b/comm/third_party/libgcrypt/cipher/primegen.c
new file mode 100644
index 0000000000..e24de4dc7c
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/primegen.c
@@ -0,0 +1,1878 @@
+/* primegen.c - prime number generator
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003
+ * 2004, 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
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel,
+ int (*extra_check)(void *, gcry_mpi_t),
+ void *extra_check_arg);
+static int check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
+ gcry_prime_check_func_t cb_func, void *cb_arg );
+static int is_prime (gcry_mpi_t n, int steps, unsigned int *count);
+static void m_out_of_n( char *array, int m, int n );
+
+static void (*progress_cb) (void *,const char*,int,int, int );
+static void *progress_cb_data;
+
+/* Note: 2 is not included because it can be tested more easily by
+ looking at bit 0. The last entry in this list is marked by a zero */
+static ushort small_prime_numbers[] = {
+ 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
+ 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
+ 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
+ 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
+ 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
+ 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
+ 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
+ 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
+ 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
+ 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
+ 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
+ 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
+ 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
+ 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
+ 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
+ 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
+ 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
+ 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
+ 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
+ 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
+ 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
+ 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
+ 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
+ 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
+ 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
+ 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
+ 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
+ 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
+ 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
+ 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
+ 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
+ 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
+ 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
+ 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
+ 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
+ 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
+ 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
+ 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
+ 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
+ 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
+ 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
+ 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
+ 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
+ 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
+ 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
+ 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
+ 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
+ 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
+ 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
+ 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
+ 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
+ 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
+ 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
+ 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
+ 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
+ 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
+ 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
+ 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
+ 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
+ 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
+ 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
+ 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
+ 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
+ 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
+ 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
+ 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
+ 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
+ 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
+ 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
+ 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
+ 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
+ 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
+ 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
+ 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
+ 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
+ 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
+ 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
+ 4957, 4967, 4969, 4973, 4987, 4993, 4999,
+ 0
+};
+static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
+
+
+
+/* An object and a list to build up a global pool of primes. See
+ save_pool_prime and get_pool_prime. */
+struct primepool_s
+{
+ struct primepool_s *next;
+ gcry_mpi_t prime; /* If this is NULL the entry is not used. */
+ unsigned int nbits;
+ gcry_random_level_t randomlevel;
+};
+struct primepool_s *primepool;
+/* Mutex used to protect access to the primepool. */
+GPGRT_LOCK_DEFINE (primepool_lock);
+
+
+gcry_err_code_t
+_gcry_primegen_init (void)
+{
+ /* This function was formerly used to initialize the primepool
+ Mutex. This has been replace by a static initialization. */
+ return 0;
+}
+
+
+/* Save PRIME which has been generated at RANDOMLEVEL for later
+ use. Needs to be called while primepool_lock is being hold. Note
+ that PRIME should be considered released after calling this
+ function. */
+static void
+save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
+{
+ struct primepool_s *item, *item2;
+ size_t n;
+
+ for (n=0, item = primepool; item; item = item->next, n++)
+ if (!item->prime)
+ break;
+ if (!item && n > 100)
+ {
+ /* Remove some of the entries. Our strategy is removing
+ the last third from the list. */
+ int i;
+
+ for (i=0, item2 = primepool; item2; item2 = item2->next)
+ {
+ if (i >= n/3*2)
+ {
+ _gcry_mpi_release (item2->prime);
+ item2->prime = NULL;
+ if (!item)
+ item = item2;
+ }
+ }
+ }
+ if (!item)
+ {
+ item = xtrycalloc (1, sizeof *item);
+ if (!item)
+ {
+ /* Out of memory. Silently giving up. */
+ _gcry_mpi_release (prime);
+ return;
+ }
+ item->next = primepool;
+ primepool = item;
+ }
+ item->prime = prime;
+ item->nbits = mpi_get_nbits (prime);
+ item->randomlevel = randomlevel;
+}
+
+
+/* Return a prime for the prime pool or NULL if none has been found.
+ The prime needs to match NBITS and randomlevel. This function needs
+ to be called with the primepool_look is being hold. */
+static gcry_mpi_t
+get_pool_prime (unsigned int nbits, gcry_random_level_t randomlevel)
+{
+ struct primepool_s *item;
+
+ for (item = primepool; item; item = item->next)
+ if (item->prime
+ && item->nbits == nbits && item->randomlevel == randomlevel)
+ {
+ gcry_mpi_t prime = item->prime;
+ item->prime = NULL;
+ gcry_assert (nbits == mpi_get_nbits (prime));
+ return prime;
+ }
+ return NULL;
+}
+
+
+
+
+
+
+void
+_gcry_register_primegen_progress ( void (*cb)(void *,const char*,int,int,int),
+ void *cb_data )
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+
+static void
+progress( int c )
+{
+ if ( progress_cb )
+ progress_cb ( progress_cb_data, "primegen", c, 0, 0 );
+}
+
+
+/****************
+ * Generate a prime number (stored in secure memory)
+ */
+gcry_mpi_t
+_gcry_generate_secret_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg)
+{
+ gcry_mpi_t prime;
+
+ prime = gen_prime (nbits, 1, random_level, extra_check, extra_check_arg);
+ progress('\n');
+ return prime;
+}
+
+
+/* Generate a prime number which may be public, i.e. not allocated in
+ secure memory. */
+gcry_mpi_t
+_gcry_generate_public_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg)
+{
+ gcry_mpi_t prime;
+
+ prime = gen_prime (nbits, 0, random_level, extra_check, extra_check_arg);
+ progress('\n');
+ return prime;
+}
+
+
+/* Core prime generation function. The algorithm used to generate
+ practically save primes is due to Lim and Lee as described in the
+ CRYPTO '97 proceedings (ISBN3540633847) page 260.
+
+ NEED_Q_FACTOR: If true make sure that at least one factor is of
+ size qbits. This is for example required for DSA.
+ PRIME_GENERATED: Adresss of a variable where the resulting prime
+ number will be stored.
+ PBITS: Requested size of the prime number. At least 48.
+ QBITS: One factor of the prime needs to be of this size. Maybe 0
+ if this is not required. See also MODE.
+ G: If not NULL an MPI which will receive a generator for the prime
+ for use with Elgamal.
+ RET_FACTORS: if not NULL, an array with all factors are stored at
+ that address.
+ ALL_FACTORS: If set to true all factors of prime-1 are returned.
+ RANDOMLEVEL: How strong should the random numers be.
+ FLAGS: Prime generation bit flags. Currently supported:
+ GCRY_PRIME_FLAG_SECRET - The prime needs to be kept secret.
+ CB_FUNC, CB_ARG: Callback to be used for extra checks.
+
+ */
+static gcry_err_code_t
+prime_generate_internal (int need_q_factor,
+ gcry_mpi_t *prime_generated, unsigned int pbits,
+ unsigned int qbits, gcry_mpi_t g,
+ gcry_mpi_t **ret_factors,
+ gcry_random_level_t randomlevel, unsigned int flags,
+ int all_factors,
+ gcry_prime_check_func_t cb_func, void *cb_arg)
+{
+ gcry_err_code_t err = 0;
+ gcry_mpi_t *factors_new = NULL; /* Factors to return to the
+ caller. */
+ gcry_mpi_t *factors = NULL; /* Current factors. */
+ gcry_random_level_t poolrandomlevel; /* Random level used for pool primes. */
+ gcry_mpi_t *pool = NULL; /* Pool of primes. */
+ int *pool_in_use = NULL; /* Array with currently used POOL elements. */
+ unsigned char *perms = NULL; /* Permutations of POOL. */
+ gcry_mpi_t q_factor = NULL; /* Used if QBITS is non-zero. */
+ unsigned int fbits = 0; /* Length of prime factors. */
+ unsigned int n = 0; /* Number of factors. */
+ unsigned int m = 0; /* Number of primes in pool. */
+ gcry_mpi_t q = NULL; /* First prime factor. */
+ gcry_mpi_t prime = NULL; /* Prime candidate. */
+ unsigned int nprime = 0; /* Bits of PRIME. */
+ unsigned int req_qbits; /* The original QBITS value. */
+ gcry_mpi_t val_2; /* For check_prime(). */
+ int is_locked = 0; /* Flag to help unlocking the primepool. */
+ unsigned int is_secret = (flags & GCRY_PRIME_FLAG_SECRET);
+ unsigned int count1 = 0, count2 = 0;
+ unsigned int i = 0, j = 0;
+
+ if (pbits < 48)
+ return GPG_ERR_INV_ARG;
+
+ /* We won't use a too strong random elvel for the pooled subprimes. */
+ poolrandomlevel = (randomlevel > GCRY_STRONG_RANDOM?
+ GCRY_STRONG_RANDOM : randomlevel);
+
+
+ /* If QBITS is not given, assume a reasonable value. */
+ if (!qbits)
+ qbits = pbits / 3;
+
+ req_qbits = qbits;
+
+ /* Find number of needed prime factors N. */
+ for (n = 1; (pbits - qbits - 1) / n >= qbits; n++)
+ ;
+ n--;
+
+ val_2 = mpi_alloc_set_ui (2);
+
+ if ((! n) || ((need_q_factor) && (n < 2)))
+ {
+ err = GPG_ERR_INV_ARG;
+ goto leave;
+ }
+
+ if (need_q_factor)
+ {
+ n--; /* Need one factor less because we want a specific Q-FACTOR. */
+ fbits = (pbits - 2 * req_qbits -1) / n;
+ qbits = pbits - req_qbits - n * fbits;
+ }
+ else
+ {
+ fbits = (pbits - req_qbits -1) / n;
+ qbits = pbits - n * fbits;
+ }
+
+ if (DBG_CIPHER)
+ log_debug ("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
+ pbits, req_qbits, qbits, fbits, n);
+
+ /* Allocate an integer to old the new prime. */
+ prime = mpi_new (pbits);
+
+ /* Generate first prime factor. */
+ q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+
+ /* Generate a specific Q-Factor if requested. */
+ if (need_q_factor)
+ q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
+
+ /* Allocate an array to hold all factors + 2 for later usage. */
+ factors = xtrycalloc (n + 2, sizeof (*factors));
+ if (!factors)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+
+ /* Allocate an array to track pool usage. */
+ pool_in_use = xtrymalloc (n * sizeof *pool_in_use);
+ if (!pool_in_use)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ for (i=0; i < n; i++)
+ pool_in_use[i] = -1;
+
+ /* Make a pool of 3n+5 primes (this is an arbitrary value). We
+ require at least 30 primes for are useful selection process.
+
+ Fixme: We need to research the best formula for sizing the pool.
+ */
+ m = n * 3 + 5;
+ if (need_q_factor) /* Need some more in this case. */
+ m += 5;
+ if (m < 30)
+ m = 30;
+ pool = xtrycalloc (m , sizeof (*pool));
+ if (! pool)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+
+ /* Permutate over the pool of primes until we find a prime of the
+ requested length. */
+ do
+ {
+ next_try:
+ for (i=0; i < n; i++)
+ pool_in_use[i] = -1;
+
+ if (!perms)
+ {
+ /* Allocate new primes. This is done right at the beginning
+ of the loop and if we have later run out of primes. */
+ for (i = 0; i < m; i++)
+ {
+ mpi_free (pool[i]);
+ pool[i] = NULL;
+ }
+
+ /* Init m_out_of_n(). */
+ perms = xtrycalloc (1, m);
+ if (!perms)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+
+ err = gpgrt_lock_lock (&primepool_lock);
+ if (err)
+ goto leave;
+ is_locked = 1;
+
+ for (i = 0; i < n; i++)
+ {
+ perms[i] = 1;
+ /* At a maximum we use strong random for the factors.
+ This saves us a lot of entropy. Given that Q and
+ possible Q-factor are also used in the final prime
+ this should be acceptable. We also don't allocate in
+ secure memory to save on that scare resource too. If
+ Q has been allocated in secure memory, the final
+ prime will be saved there anyway. This is because
+ our MPI routines take care of that. GnuPG has worked
+ this way ever since. */
+ pool[i] = NULL;
+ if (is_locked)
+ {
+ pool[i] = get_pool_prime (fbits, poolrandomlevel);
+ if (!pool[i])
+ {
+ err = gpgrt_lock_unlock (&primepool_lock);
+ if (err)
+ goto leave;
+ is_locked = 0;
+ }
+ }
+ if (!pool[i])
+ pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
+ pool_in_use[i] = i;
+ factors[i] = pool[i];
+ }
+
+ if (is_locked && (err = gpgrt_lock_unlock (&primepool_lock)))
+ goto leave;
+ is_locked = 0;
+ }
+ else
+ {
+ /* Get next permutation. */
+ m_out_of_n ( (char*)perms, n, m);
+
+ if ((err = gpgrt_lock_lock (&primepool_lock)))
+ goto leave;
+ is_locked = 1;
+
+ for (i = j = 0; (i < m) && (j < n); i++)
+ if (perms[i])
+ {
+ /* If the subprime has not yet beed generated do it now. */
+ if (!pool[i] && is_locked)
+ {
+ pool[i] = get_pool_prime (fbits, poolrandomlevel);
+ if (!pool[i])
+ {
+ if ((err = gpgrt_lock_unlock (&primepool_lock)))
+ goto leave;
+ is_locked = 0;
+ }
+ }
+ if (!pool[i])
+ pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
+ pool_in_use[j] = i;
+ factors[j++] = pool[i];
+ }
+
+ if (is_locked && (err = gpgrt_lock_unlock (&primepool_lock)))
+ goto leave;
+ is_locked = 0;
+
+ if (i == n)
+ {
+ /* Ran out of permutations: Allocate new primes. */
+ xfree (perms);
+ perms = NULL;
+ progress ('!');
+ goto next_try;
+ }
+ }
+
+ /* Generate next prime candidate:
+ p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1.
+ */
+ mpi_set (prime, q);
+ mpi_mul_ui (prime, prime, 2);
+ if (need_q_factor)
+ mpi_mul (prime, prime, q_factor);
+ for(i = 0; i < n; i++)
+ mpi_mul (prime, prime, factors[i]);
+ mpi_add_ui (prime, prime, 1);
+ nprime = mpi_get_nbits (prime);
+
+ if (nprime < pbits)
+ {
+ if (++count1 > 20)
+ {
+ count1 = 0;
+ qbits++;
+ progress('>');
+ mpi_free (q);
+ q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+ goto next_try;
+ }
+ }
+ else
+ count1 = 0;
+
+ if (nprime > pbits)
+ {
+ if (++count2 > 20)
+ {
+ count2 = 0;
+ qbits--;
+ progress('<');
+ mpi_free (q);
+ q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+ goto next_try;
+ }
+ }
+ else
+ count2 = 0;
+ }
+ while (! ((nprime == pbits) && check_prime (prime, val_2, 5,
+ cb_func, cb_arg)));
+
+ if (DBG_CIPHER)
+ {
+ progress ('\n');
+ log_mpidump ("prime ", prime);
+ log_mpidump ("factor q", q);
+ if (need_q_factor)
+ log_mpidump ("factor q0", q_factor);
+ for (i = 0; i < n; i++)
+ log_mpidump ("factor pi", factors[i]);
+ log_debug ("bit sizes: prime=%u, q=%u",
+ mpi_get_nbits (prime), mpi_get_nbits (q));
+ if (need_q_factor)
+ log_printf (", q0=%u", mpi_get_nbits (q_factor));
+ for (i = 0; i < n; i++)
+ log_printf (", p%d=%u", i, mpi_get_nbits (factors[i]));
+ log_printf ("\n");
+ }
+
+ if (ret_factors)
+ {
+ /* Caller wants the factors. */
+ factors_new = xtrycalloc (n + 4, sizeof (*factors_new));
+ if (! factors_new)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+
+ if (all_factors)
+ {
+ i = 0;
+ factors_new[i++] = mpi_set_ui (NULL, 2);
+ factors_new[i++] = mpi_copy (q);
+ if (need_q_factor)
+ factors_new[i++] = mpi_copy (q_factor);
+ for(j=0; j < n; j++)
+ factors_new[i++] = mpi_copy (factors[j]);
+ }
+ else
+ {
+ i = 0;
+ if (need_q_factor)
+ {
+ factors_new[i++] = mpi_copy (q_factor);
+ for (; i <= n; i++)
+ factors_new[i] = mpi_copy (factors[i]);
+ }
+ else
+ for (; i < n; i++ )
+ factors_new[i] = mpi_copy (factors[i]);
+ }
+ }
+
+ if (g && need_q_factor)
+ err = GPG_ERR_NOT_IMPLEMENTED;
+ else if (g)
+ {
+ /* Create a generator (start with 3). */
+ gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime));
+ gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
+ gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
+
+ factors[n] = q;
+ factors[n + 1] = mpi_alloc_set_ui (2);
+ mpi_sub_ui (pmin1, prime, 1);
+ mpi_set_ui (g, 2);
+ do
+ {
+ mpi_add_ui (g, g, 1);
+ if (DBG_CIPHER)
+ log_printmpi ("checking g", g);
+ else
+ progress('^');
+ for (i = 0; i < n + 2; i++)
+ {
+ mpi_fdiv_q (tmp, pmin1, factors[i]);
+ /* No mpi_pow(), but it is okay to use this with mod
+ prime. */
+ mpi_powm (b, g, tmp, prime);
+ if (! mpi_cmp_ui (b, 1))
+ break;
+ }
+ if (DBG_CIPHER)
+ progress('\n');
+ }
+ while (i < n + 2);
+
+ mpi_free (factors[n+1]);
+ mpi_free (tmp);
+ mpi_free (b);
+ mpi_free (pmin1);
+ }
+
+ if (! DBG_CIPHER)
+ progress ('\n');
+
+
+ leave:
+ if (pool)
+ {
+ is_locked = !gpgrt_lock_lock (&primepool_lock);
+ for(i = 0; i < m; i++)
+ {
+ if (pool[i])
+ {
+ for (j=0; j < n; j++)
+ if (pool_in_use[j] == i)
+ break;
+ if (j == n && is_locked)
+ {
+ /* This pooled subprime has not been used. */
+ save_pool_prime (pool[i], poolrandomlevel);
+ }
+ else
+ mpi_free (pool[i]);
+ }
+ }
+ if (is_locked)
+ err = gpgrt_lock_unlock (&primepool_lock);
+ is_locked = 0;
+ xfree (pool);
+ }
+ xfree (pool_in_use);
+ if (factors)
+ xfree (factors); /* Factors are shallow copies. */
+ if (perms)
+ xfree (perms);
+
+ mpi_free (val_2);
+ mpi_free (q);
+ mpi_free (q_factor);
+
+ if (! err)
+ {
+ *prime_generated = prime;
+ if (ret_factors)
+ *ret_factors = factors_new;
+ }
+ else
+ {
+ if (factors_new)
+ {
+ for (i = 0; factors_new[i]; i++)
+ mpi_free (factors_new[i]);
+ xfree (factors_new);
+ }
+ mpi_free (prime);
+ }
+
+ return err;
+}
+
+
+/* Generate a prime used for discrete logarithm algorithms; i.e. this
+ prime will be public and no strong random is required. On success
+ R_PRIME receives a new MPI with the prime. On error R_PRIME is set
+ to NULL and an error code is returned. If RET_FACTORS is not NULL
+ it is set to an allocated array of factors on success or to NULL on
+ error. */
+gcry_err_code_t
+_gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
+ gcry_mpi_t g,
+ gcry_mpi_t *r_prime, gcry_mpi_t **ret_factors)
+{
+ *r_prime = NULL;
+ if (ret_factors)
+ *ret_factors = NULL;
+ return prime_generate_internal ((mode == 1), r_prime, pbits, qbits, g,
+ ret_factors, GCRY_WEAK_RANDOM, 0, 0,
+ NULL, NULL);
+}
+
+
+static gcry_mpi_t
+gen_prime (unsigned int nbits, int secret, int randomlevel,
+ int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg)
+{
+ gcry_mpi_t prime, ptest, pminus1, val_2, val_3, result;
+ int i;
+ unsigned int x, step;
+ unsigned int count1, count2;
+ int *mods;
+
+/* if ( DBG_CIPHER ) */
+/* log_debug ("generate a prime of %u bits ", nbits ); */
+
+ if (nbits < 16)
+ log_fatal ("can't generate a prime with less than %d bits\n", 16);
+
+ mods = (secret? xmalloc_secure (no_of_small_prime_numbers * sizeof *mods)
+ /* */ : xmalloc (no_of_small_prime_numbers * sizeof *mods));
+ /* Make nbits fit into gcry_mpi_t implementation. */
+ val_2 = mpi_alloc_set_ui( 2 );
+ val_3 = mpi_alloc_set_ui( 3);
+ prime = secret? mpi_snew (nbits): mpi_new (nbits);
+ result = mpi_alloc_like( prime );
+ pminus1= mpi_alloc_like( prime );
+ ptest = mpi_alloc_like( prime );
+ count1 = count2 = 0;
+ for (;;)
+ { /* try forvever */
+ int dotcount=0;
+
+ /* generate a random number */
+ _gcry_mpi_randomize( prime, nbits, randomlevel );
+
+ /* Set high order bit to 1, set low order bit to 1. If we are
+ generating a secret prime we are most probably doing that
+ for RSA, to make sure that the modulus does have the
+ requested key size we set the 2 high order bits. */
+ mpi_set_highbit (prime, nbits-1);
+ if (secret)
+ mpi_set_bit (prime, nbits-2);
+ mpi_set_bit(prime, 0);
+
+ /* Calculate all remainders. */
+ for (i=0; (x = small_prime_numbers[i]); i++ )
+ mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
+
+ /* Now try some primes starting with prime. */
+ for(step=0; step < 20000; step += 2 )
+ {
+ /* Check against all the small primes we have in mods. */
+ count1++;
+ for (i=0; (x = small_prime_numbers[i]); i++ )
+ {
+ while ( mods[i] + step >= x )
+ mods[i] -= x;
+ if ( !(mods[i] + step) )
+ break;
+ }
+ if ( x )
+ continue; /* Found a multiple of an already known prime. */
+
+ mpi_add_ui( ptest, prime, step );
+
+ /* Do a fast Fermat test now. */
+ count2++;
+ mpi_sub_ui( pminus1, ptest, 1);
+ mpi_powm( result, val_2, pminus1, ptest );
+ if ( !mpi_cmp_ui( result, 1 ) )
+ {
+ /* Not composite, perform stronger tests */
+ if (is_prime(ptest, 5, &count2 ))
+ {
+ if (!mpi_test_bit( ptest, nbits-1-secret ))
+ {
+ progress('\n');
+ log_debug ("overflow in prime generation\n");
+ break; /* Stop loop, continue with a new prime. */
+ }
+
+ if (extra_check && extra_check (extra_check_arg, ptest))
+ {
+ /* The extra check told us that this prime is
+ not of the caller's taste. */
+ progress ('/');
+ }
+ else
+ {
+ /* Got it. */
+ mpi_free(val_2);
+ mpi_free(val_3);
+ mpi_free(result);
+ mpi_free(pminus1);
+ mpi_free(prime);
+ xfree(mods);
+ return ptest;
+ }
+ }
+ }
+ if (++dotcount == 10 )
+ {
+ progress('.');
+ dotcount = 0;
+ }
+ }
+ progress(':'); /* restart with a new random value */
+ }
+}
+
+/****************
+ * Returns: true if this may be a prime
+ * RM_ROUNDS gives the number of Rabin-Miller tests to run.
+ */
+static int
+check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
+ gcry_prime_check_func_t cb_func, void *cb_arg)
+{
+ int i;
+ unsigned int x;
+ unsigned int count=0;
+
+ /* Check against small primes. */
+ for (i=0; (x = small_prime_numbers[i]); i++ )
+ {
+ if ( mpi_divisible_ui( prime, x ) )
+ return !mpi_cmp_ui (prime, x);
+ }
+
+ /* A quick Fermat test. */
+ {
+ gcry_mpi_t result = mpi_alloc_like( prime );
+ gcry_mpi_t pminus1 = mpi_alloc_like( prime );
+ mpi_sub_ui( pminus1, prime, 1);
+ mpi_powm( result, val_2, pminus1, prime );
+ mpi_free( pminus1 );
+ if ( mpi_cmp_ui( result, 1 ) )
+ {
+ /* Is composite. */
+ mpi_free( result );
+ progress('.');
+ return 0;
+ }
+ mpi_free( result );
+ }
+
+ if (!cb_func || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_MAYBE_PRIME, prime))
+ {
+ /* Perform stronger tests. */
+ if ( is_prime( prime, rm_rounds, &count ) )
+ {
+ if (!cb_func
+ || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_GOT_PRIME, prime))
+ return 1; /* Probably a prime. */
+ }
+ }
+ progress('.');
+ return 0;
+}
+
+
+/*
+ * Return true if n is probably a prime
+ */
+static int
+is_prime (gcry_mpi_t n, int steps, unsigned int *count)
+{
+ gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs( n ) );
+ gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs( n ) );
+ gcry_mpi_t z = mpi_alloc( mpi_get_nlimbs( n ) );
+ gcry_mpi_t nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
+ gcry_mpi_t a2 = mpi_alloc_set_ui( 2 );
+ gcry_mpi_t q;
+ unsigned i, j, k;
+ int rc = 0;
+ unsigned nbits = mpi_get_nbits( n );
+
+ if (steps < 5) /* Make sure that we do at least 5 rounds. */
+ steps = 5;
+
+ mpi_sub_ui( nminus1, n, 1 );
+
+ /* Find q and k, so that n = 1 + 2^k * q . */
+ q = mpi_copy ( nminus1 );
+ k = mpi_trailing_zeros ( q );
+ mpi_tdiv_q_2exp (q, q, k);
+
+ for (i=0 ; i < steps; i++ )
+ {
+ ++*count;
+ if( !i )
+ {
+ mpi_set_ui( x, 2 );
+ }
+ else
+ {
+ /* We need to loop to avoid an X with value 0 or 1. */
+ do
+ {
+ _gcry_mpi_randomize (x, nbits, GCRY_WEAK_RANDOM);
+
+ /* Make sure that the number is smaller than the prime
+ * and keep the randomness of the high bit. */
+ if (mpi_test_bit (x, nbits-2))
+ {
+ mpi_set_highbit (x, nbits-2); /* Clear all higher bits. */
+ }
+ else
+ {
+ mpi_set_highbit (x, nbits-2);
+ mpi_clear_bit (x, nbits-2);
+ }
+ }
+ while (mpi_cmp_ui (x, 1) <= 0);
+ gcry_assert (mpi_cmp (x, nminus1) < 0);
+ }
+ mpi_powm ( y, x, q, n);
+ if ( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) )
+ {
+ for ( j=1; j < k && mpi_cmp( y, nminus1 ); j++ )
+ {
+ mpi_powm(y, y, a2, n);
+ if( !mpi_cmp_ui( y, 1 ) )
+ goto leave; /* Not a prime. */
+ }
+ if (mpi_cmp( y, nminus1 ) )
+ goto leave; /* Not a prime. */
+ }
+ progress('+');
+ }
+ rc = 1; /* May be a prime. */
+
+ leave:
+ mpi_free( x );
+ mpi_free( y );
+ mpi_free( z );
+ mpi_free( nminus1 );
+ mpi_free( q );
+ mpi_free( a2 );
+
+ return rc;
+}
+
+
+/* Given ARRAY of size N with M elements set to true produce a
+ modified array with the next permutation of M elements. Note, that
+ ARRAY is used in a one-bit-per-byte approach. To detected the last
+ permutation it is useful to initialize the array with the first M
+ element set to true and use this test:
+ m_out_of_n (array, m, n);
+ for (i = j = 0; i < n && j < m; i++)
+ if (array[i])
+ j++;
+ if (j == m)
+ goto ready;
+
+ This code is based on the algorithm 452 from the "Collected
+ Algorithms From ACM, Volume II" by C. N. Liu and D. T. Tang.
+*/
+static void
+m_out_of_n ( char *array, int m, int n )
+{
+ int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
+
+ if( !m || m >= n )
+ return;
+
+ /* Need to handle this simple case separately. */
+ if( m == 1 )
+ {
+ for (i=0; i < n; i++ )
+ {
+ if ( array[i] )
+ {
+ array[i++] = 0;
+ if( i >= n )
+ i = 0;
+ array[i] = 1;
+ return;
+ }
+ }
+ BUG();
+ }
+
+
+ for (j=1; j < n; j++ )
+ {
+ if ( array[n-1] == array[n-j-1])
+ continue;
+ j1 = j;
+ break;
+ }
+
+ if ( (m & 1) )
+ {
+ /* M is odd. */
+ if( array[n-1] )
+ {
+ if( j1 & 1 )
+ {
+ k1 = n - j1;
+ k2 = k1+2;
+ if( k2 > n )
+ k2 = n;
+ goto leave;
+ }
+ goto scan;
+ }
+ k2 = n - j1 - 1;
+ if( k2 == 0 )
+ {
+ k1 = i;
+ k2 = n - j1;
+ }
+ else if( array[k2] && array[k2-1] )
+ k1 = n;
+ else
+ k1 = k2 + 1;
+ }
+ else
+ {
+ /* M is even. */
+ if( !array[n-1] )
+ {
+ k1 = n - j1;
+ k2 = k1 + 1;
+ goto leave;
+ }
+
+ if( !(j1 & 1) )
+ {
+ k1 = n - j1;
+ k2 = k1+2;
+ if( k2 > n )
+ k2 = n;
+ goto leave;
+ }
+ scan:
+ jp = n - j1 - 1;
+ for (i=1; i <= jp; i++ )
+ {
+ i1 = jp + 2 - i;
+ if( array[i1-1] )
+ {
+ if( array[i1-2] )
+ {
+ k1 = i1 - 1;
+ k2 = n - j1;
+ }
+ else
+ {
+ k1 = i1 - 1;
+ k2 = n + 1 - j1;
+ }
+ goto leave;
+ }
+ }
+ k1 = 1;
+ k2 = n + 1 - m;
+ }
+ leave:
+ /* Now complement the two selected bits. */
+ array[k1-1] = !array[k1-1];
+ array[k2-1] = !array[k2-1];
+}
+
+
+/* Generate a new prime number of PRIME_BITS bits and store it in
+ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of
+ (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is
+ non-zero, allocate a new, NULL-terminated array holding the prime
+ factors and store it in FACTORS. FLAGS might be used to influence
+ the prime number generation process. */
+gcry_err_code_t
+_gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
+ unsigned int factor_bits, gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func, void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags)
+{
+ gcry_err_code_t rc = 0;
+ gcry_mpi_t *factors_generated = NULL;
+ gcry_mpi_t prime_generated = NULL;
+ unsigned int mode = 0;
+
+ if (!prime)
+ return GPG_ERR_INV_ARG;
+ *prime = NULL;
+
+ if (flags & GCRY_PRIME_FLAG_SPECIAL_FACTOR)
+ mode = 1;
+
+ /* Generate. */
+ rc = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
+ factor_bits, NULL,
+ factors? &factors_generated : NULL,
+ random_level, flags, 1,
+ cb_func, cb_arg);
+
+ if (!rc && cb_func)
+ {
+ /* Additional check. */
+ if ( !cb_func (cb_arg, GCRY_PRIME_CHECK_AT_FINISH, prime_generated))
+ {
+ /* Failed, deallocate resources. */
+ unsigned int i;
+
+ mpi_free (prime_generated);
+ if (factors)
+ {
+ for (i = 0; factors_generated[i]; i++)
+ mpi_free (factors_generated[i]);
+ xfree (factors_generated);
+ }
+ rc = GPG_ERR_GENERAL;
+ }
+ }
+
+ if (!rc)
+ {
+ if (factors)
+ *factors = factors_generated;
+ *prime = prime_generated;
+ }
+
+ return rc;
+}
+
+/* Check whether the number X is prime. */
+gcry_err_code_t
+_gcry_prime_check (gcry_mpi_t x, unsigned int flags)
+{
+ (void)flags;
+
+ switch (mpi_cmp_ui (x, 2))
+ {
+ case 0: return 0; /* 2 is a prime */
+ case -1: return GPG_ERR_NO_PRIME; /* Only numbers > 1 are primes. */
+ }
+
+ /* We use 64 rounds because the prime we are going to test is not
+ guaranteed to be a random one. */
+ if (check_prime (x, mpi_const (MPI_C_TWO), 64, NULL, NULL))
+ return 0;
+
+ return GPG_ERR_NO_PRIME;
+}
+
+
+/* Check whether the number X is prime according to FIPS 186-4 table C.2. */
+gcry_err_code_t
+_gcry_fips186_4_prime_check (gcry_mpi_t x, unsigned int bits)
+{
+ gcry_err_code_t ec = GPG_ERR_NO_ERROR;
+
+ switch (mpi_cmp_ui (x, 2))
+ {
+ case 0: return ec; /* 2 is a prime */
+ case -1: return GPG_ERR_NO_PRIME; /* Only numbers > 1 are primes. */
+ }
+
+ /* We use 5 or 4 rounds as specified in table C.2 */
+ if (! check_prime (x, mpi_const (MPI_C_TWO), bits > 1024 ? 4 : 5, NULL, NULL))
+ ec = GPG_ERR_NO_PRIME;
+
+ return ec;
+}
+
+
+/* Find a generator for PRIME where the factorization of (prime-1) is
+ in the NULL terminated array FACTORS. Return the generator as a
+ newly allocated MPI in R_G. If START_G is not NULL, use this as s
+ atart for the search. Returns 0 on success.*/
+gcry_err_code_t
+_gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime, gcry_mpi_t *factors,
+ gcry_mpi_t start_g)
+{
+ gcry_mpi_t tmp, b, pmin1, g;
+ int first, i, n;
+
+ if (!r_g)
+ return GPG_ERR_INV_ARG;
+ *r_g = NULL;
+ if (!factors || !prime)
+ return GPG_ERR_INV_ARG;
+
+ for (n=0; factors[n]; n++)
+ ;
+ if (n < 2)
+ return GPG_ERR_INV_ARG;
+
+ tmp = mpi_new (0);
+ b = mpi_new (0);
+ pmin1 = mpi_new (0);
+ g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3);
+
+ /* Extra sanity check - usually disabled. */
+/* mpi_set (tmp, factors[0]); */
+/* for(i = 1; i < n; i++) */
+/* mpi_mul (tmp, tmp, factors[i]); */
+/* mpi_add_ui (tmp, tmp, 1); */
+/* if (mpi_cmp (prime, tmp)) */
+/* return gpg_error (GPG_ERR_INV_ARG); */
+
+ mpi_sub_ui (pmin1, prime, 1);
+ first = 1;
+ do
+ {
+ if (first)
+ first = 0;
+ else
+ mpi_add_ui (g, g, 1);
+
+ if (DBG_CIPHER)
+ log_printmpi ("checking g", g);
+ else
+ progress('^');
+
+ for (i = 0; i < n; i++)
+ {
+ mpi_fdiv_q (tmp, pmin1, factors[i]);
+ mpi_powm (b, g, tmp, prime);
+ if (! mpi_cmp_ui (b, 1))
+ break;
+ }
+ if (DBG_CIPHER)
+ progress('\n');
+ }
+ while (i < n);
+
+ _gcry_mpi_release (tmp);
+ _gcry_mpi_release (b);
+ _gcry_mpi_release (pmin1);
+ *r_g = g;
+
+ return 0;
+}
+
+/* Convenience function to release the factors array. */
+void
+_gcry_prime_release_factors (gcry_mpi_t *factors)
+{
+ if (factors)
+ {
+ int i;
+
+ for (i=0; factors[i]; i++)
+ mpi_free (factors[i]);
+ xfree (factors);
+ }
+}
+
+
+
+/* Helper for _gcry_derive_x931_prime. */
+static gcry_mpi_t
+find_x931_prime (const gcry_mpi_t pfirst)
+{
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
+ gcry_mpi_t prime;
+
+ prime = mpi_copy (pfirst);
+ /* If P is even add 1. */
+ mpi_set_bit (prime, 0);
+
+ /* We use 64 Rabin-Miller rounds which is better and thus
+ sufficient. We do not have a Lucas test implementation thus we
+ can't do it in the X9.31 preferred way of running a few
+ Rabin-Miller followed by one Lucas test. */
+ while ( !check_prime (prime, val_2, 64, NULL, NULL) )
+ mpi_add_ui (prime, prime, 2);
+
+ mpi_free (val_2);
+
+ return prime;
+}
+
+
+/* Generate a prime using the algorithm from X9.31 appendix B.4.
+
+ This function requires that the provided public exponent E is odd.
+ XP, XP1 and XP2 are the seed values. All values are mandatory.
+
+ On success the prime is returned. If R_P1 or R_P2 are given the
+ internal values P1 and P2 are saved at these addresses. On error
+ NULL is returned. */
+gcry_mpi_t
+_gcry_derive_x931_prime (const gcry_mpi_t xp,
+ const gcry_mpi_t xp1, const gcry_mpi_t xp2,
+ const gcry_mpi_t e,
+ gcry_mpi_t *r_p1, gcry_mpi_t *r_p2)
+{
+ gcry_mpi_t p1, p2, p1p2, yp0;
+
+ if (!xp || !xp1 || !xp2)
+ return NULL;
+ if (!e || !mpi_test_bit (e, 0))
+ return NULL; /* We support only odd values for E. */
+
+ p1 = find_x931_prime (xp1);
+ p2 = find_x931_prime (xp2);
+ p1p2 = mpi_alloc_like (xp);
+ mpi_mul (p1p2, p1, p2);
+
+ {
+ gcry_mpi_t r1, tmp;
+
+ /* r1 = (p2^{-1} mod p1)p2 - (p1^{-1} mod p2) */
+ tmp = mpi_alloc_like (p1);
+ mpi_invm (tmp, p2, p1);
+ mpi_mul (tmp, tmp, p2);
+ r1 = tmp;
+
+ tmp = mpi_alloc_like (p2);
+ mpi_invm (tmp, p1, p2);
+ mpi_mul (tmp, tmp, p1);
+ mpi_sub (r1, r1, tmp);
+
+ /* Fixup a negative value. */
+ if (mpi_has_sign (r1))
+ mpi_add (r1, r1, p1p2);
+
+ /* yp0 = xp + (r1 - xp mod p1*p2) */
+ yp0 = tmp; tmp = NULL;
+ mpi_subm (yp0, r1, xp, p1p2);
+ mpi_add (yp0, yp0, xp);
+ mpi_free (r1);
+
+ /* Fixup a negative value. */
+ if (mpi_cmp (yp0, xp) < 0 )
+ mpi_add (yp0, yp0, p1p2);
+ }
+
+ /* yp0 is now the first integer greater than xp with p1 being a
+ large prime factor of yp0-1 and p2 a large prime factor of yp0+1. */
+
+ /* Note that the first example from X9.31 (D.1.1) which uses
+ (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
+ (Xq2 #134E4CAA16D2350A21D775C404#)
+ (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
+ 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
+ 321DE34A#))))
+ returns an yp0 of
+ #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC4E3
+ BF20CB896EE37E098A906313271422162CB6C642
+ 75C1201F#
+ and not
+ #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC2E6
+ C88FE299D52D78BE405A97E01FD71DD7819ECB91
+ FA85A076#
+ as stated in the standard. This seems to be a bug in X9.31.
+ */
+
+ {
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
+ gcry_mpi_t gcdtmp = mpi_alloc_like (yp0);
+ int gcdres;
+
+ mpi_sub_ui (p1p2, p1p2, 1); /* Adjust for loop body. */
+ mpi_sub_ui (yp0, yp0, 1); /* Ditto. */
+ for (;;)
+ {
+ gcdres = mpi_gcd (gcdtmp, e, yp0);
+ mpi_add_ui (yp0, yp0, 1);
+ if (!gcdres)
+ progress ('/'); /* gcd (e, yp0-1) != 1 */
+ else if (check_prime (yp0, val_2, 64, NULL, NULL))
+ break; /* Found. */
+ /* We add p1p2-1 because yp0 is incremented after the gcd test. */
+ mpi_add (yp0, yp0, p1p2);
+ }
+ mpi_free (gcdtmp);
+ mpi_free (val_2);
+ }
+
+ mpi_free (p1p2);
+
+ progress('\n');
+ if (r_p1)
+ *r_p1 = p1;
+ else
+ mpi_free (p1);
+ if (r_p2)
+ *r_p2 = p2;
+ else
+ mpi_free (p2);
+ return yp0;
+}
+
+
+
+/* Generate the two prime used for DSA using the algorithm specified
+ in FIPS 186-2. PBITS is the desired length of the prime P and a
+ QBITS the length of the prime Q. If SEED is not supplied and
+ SEEDLEN is 0 the function generates an appropriate SEED. On
+ success the generated primes are stored at R_Q and R_P, the counter
+ value is stored at R_COUNTER and the seed actually used for
+ generation is stored at R_SEED and R_SEEDVALUE. */
+gpg_err_code_t
+_gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen)
+{
+ gpg_err_code_t ec;
+ unsigned char seed_help_buffer[160/8]; /* Used to hold a generated SEED. */
+ unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */
+ unsigned char digest[160/8]; /* Helper buffer for SHA-1 digest. */
+ gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */
+ gcry_mpi_t tmpval = NULL; /* Helper variable. */
+ int i;
+
+ unsigned char value_u[160/8];
+ int value_n, value_b, value_k;
+ int counter;
+ gcry_mpi_t value_w = NULL;
+ gcry_mpi_t value_x = NULL;
+ gcry_mpi_t prime_q = NULL;
+ gcry_mpi_t prime_p = NULL;
+
+ /* FIPS 186-2 allows only for 1024/160 bit. */
+ if (pbits != 1024 || qbits != 160)
+ return GPG_ERR_INV_KEYLEN;
+
+ if (!seed && !seedlen)
+ ; /* No seed value given: We are asked to generate it. */
+ else if (!seed || seedlen < qbits/8)
+ return GPG_ERR_INV_ARG;
+
+ /* Allocate a buffer to later compute SEED+some_increment. */
+ seed_plus = xtrymalloc (seedlen < 20? 20:seedlen);
+ if (!seed_plus)
+ {
+ ec = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ val_2 = mpi_alloc_set_ui (2);
+ value_n = (pbits - 1) / qbits;
+ value_b = (pbits - 1) - value_n * qbits;
+ value_w = mpi_new (pbits);
+ value_x = mpi_new (pbits);
+
+ restart:
+ /* Generate Q. */
+ for (;;)
+ {
+ /* Step 1: Generate a (new) seed unless one has been supplied. */
+ if (!seed)
+ {
+ seedlen = sizeof seed_help_buffer;
+ _gcry_create_nonce (seed_help_buffer, seedlen);
+ seed = seed_help_buffer;
+ }
+
+ /* Step 2: U = sha1(seed) ^ sha1((seed+1) mod 2^{qbits}) */
+ memcpy (seed_plus, seed, seedlen);
+ for (i=seedlen-1; i >= 0; i--)
+ {
+ seed_plus[i]++;
+ if (seed_plus[i])
+ break;
+ }
+ _gcry_md_hash_buffer (GCRY_MD_SHA1, value_u, seed, seedlen);
+ _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+ for (i=0; i < sizeof value_u; i++)
+ value_u[i] ^= digest[i];
+
+ /* Step 3: Form q from U */
+ _gcry_mpi_release (prime_q); prime_q = NULL;
+ ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+ value_u, sizeof value_u, NULL);
+ if (ec)
+ goto leave;
+ mpi_set_highbit (prime_q, qbits-1 );
+ mpi_set_bit (prime_q, 0);
+
+ /* Step 4: Test whether Q is prime using 64 round of Rabin-Miller. */
+ if (check_prime (prime_q, val_2, 64, NULL, NULL))
+ break; /* Yes, Q is prime. */
+
+ /* Step 5. */
+ seed = NULL; /* Force a new seed at Step 1. */
+ }
+
+ /* Step 6. Note that we do no use an explicit offset but increment
+ SEED_PLUS accordingly. SEED_PLUS is currently SEED+1. */
+ counter = 0;
+
+ /* Generate P. */
+ prime_p = mpi_new (pbits);
+ for (;;)
+ {
+ /* Step 7: For k = 0,...n let
+ V_k = sha1(seed+offset+k) mod 2^{qbits}
+ Step 8: W = V_0 + V_1*2^160 +
+ ...
+ + V_{n-1}*2^{(n-1)*160}
+ + (V_{n} mod 2^b)*2^{n*160}
+ */
+ mpi_set_ui (value_w, 0);
+ for (value_k=0; value_k <= value_n; value_k++)
+ {
+ /* There is no need to have an explicit offset variable: In
+ the first round we shall have an offset of 2, this is
+ achieved by using SEED_PLUS which is already at SEED+1,
+ thus we just need to increment it once again. The
+ requirement for the next round is to update offset by N,
+ which we implictly did at the end of this loop, and then
+ to add one; this one is the same as in the first round. */
+ for (i=seedlen-1; i >= 0; i--)
+ {
+ seed_plus[i]++;
+ if (seed_plus[i])
+ break;
+ }
+ _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+
+ _gcry_mpi_release (tmpval); tmpval = NULL;
+ ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+ digest, sizeof digest, NULL);
+ if (ec)
+ goto leave;
+ if (value_k == value_n)
+ mpi_clear_highbit (tmpval, value_b); /* (V_n mod 2^b) */
+ mpi_lshift (tmpval, tmpval, value_k*qbits);
+ mpi_add (value_w, value_w, tmpval);
+ }
+
+ /* Step 8 continued: X = W + 2^{L-1} */
+ mpi_set_ui (value_x, 0);
+ mpi_set_highbit (value_x, pbits-1);
+ mpi_add (value_x, value_x, value_w);
+
+ /* Step 9: c = X mod 2q, p = X - (c - 1) */
+ mpi_mul_2exp (tmpval, prime_q, 1);
+ mpi_mod (tmpval, value_x, tmpval);
+ mpi_sub_ui (tmpval, tmpval, 1);
+ mpi_sub (prime_p, value_x, tmpval);
+
+ /* Step 10: If p < 2^{L-1} skip the primality test. */
+ /* Step 11 and 12: Primality test. */
+ if (mpi_get_nbits (prime_p) >= pbits-1
+ && check_prime (prime_p, val_2, 64, NULL, NULL) )
+ break; /* Yes, P is prime, continue with Step 15. */
+
+ /* Step 13: counter = counter + 1, offset = offset + n + 1. */
+ counter++;
+
+ /* Step 14: If counter >= 2^12 goto Step 1. */
+ if (counter >= 4096)
+ goto restart;
+ }
+
+ /* Step 15: Save p, q, counter and seed. */
+/* log_debug ("fips186-2 pbits p=%u q=%u counter=%d\n", */
+/* mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); */
+/* log_printhex("fips186-2 seed:", seed, seedlen); */
+/* log_mpidump ("fips186-2 prime p", prime_p); */
+/* log_mpidump ("fips186-2 prime q", prime_q); */
+ if (r_q)
+ {
+ *r_q = prime_q;
+ prime_q = NULL;
+ }
+ if (r_p)
+ {
+ *r_p = prime_p;
+ prime_p = NULL;
+ }
+ if (r_counter)
+ *r_counter = counter;
+ if (r_seed && r_seedlen)
+ {
+ memcpy (seed_plus, seed, seedlen);
+ *r_seed = seed_plus;
+ seed_plus = NULL;
+ *r_seedlen = seedlen;
+ }
+
+
+ leave:
+ _gcry_mpi_release (tmpval);
+ _gcry_mpi_release (value_x);
+ _gcry_mpi_release (value_w);
+ _gcry_mpi_release (prime_p);
+ _gcry_mpi_release (prime_q);
+ xfree (seed_plus);
+ _gcry_mpi_release (val_2);
+ return ec;
+}
+
+
+
+/* WARNING: The code below has not yet been tested!
+ *
+ * Generate the two prime used for DSA using the algorithm specified
+ * in FIPS 186-3, A.1.1.2. PBITS is the desired length of the prime P
+ * and a QBITS the length of the prime Q. If SEED is not supplied and
+ * SEEDLEN is 0 the function generates an appropriate SEED. On
+ * success the generated primes are stored at R_Q and R_P, the counter
+ * value is stored at R_COUNTER and the seed actually used for
+ * generation is stored at R_SEED and R_SEEDVALUE. The hash algorithm
+ * used is stored at R_HASHALGO.
+ *
+ * Note that this function is very similar to the fips186_2 code. Due
+ * to the minor differences, other buffer sizes and for documentarion,
+ * we use a separate function.
+ */
+gpg_err_code_t
+_gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen,
+ int *r_hashalgo)
+{
+ gpg_err_code_t ec;
+ unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */
+ unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */
+ unsigned char digest[256/8]; /* Helper buffer for SHA-2 digest. */
+ gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */
+ gcry_mpi_t tmpval = NULL; /* Helper variable. */
+ int hashalgo; /* The id of the Approved Hash Function. */
+ int i;
+
+ unsigned char value_u[256/8];
+ int value_n, value_b, value_j;
+ int counter;
+ gcry_mpi_t value_w = NULL;
+ gcry_mpi_t value_x = NULL;
+ gcry_mpi_t prime_q = NULL;
+ gcry_mpi_t prime_p = NULL;
+
+ gcry_assert (sizeof seed_help_buffer == sizeof digest
+ && sizeof seed_help_buffer == sizeof value_u);
+
+ /* Step 1: Check the requested prime lengths. */
+ /* Note that due to the size of our buffers QBITS is limited to 256. */
+ if (pbits == 2048 && qbits == 224)
+ hashalgo = GCRY_MD_SHA224;
+ else if (pbits == 2048 && qbits == 256)
+ hashalgo = GCRY_MD_SHA256;
+ else if (pbits == 3072 && qbits == 256)
+ hashalgo = GCRY_MD_SHA256;
+ else
+ return GPG_ERR_INV_KEYLEN;
+
+ /* Also check that the hash algorithm is available. */
+ ec = _gcry_md_test_algo (hashalgo);
+ if (ec)
+ return ec;
+ gcry_assert (qbits/8 <= sizeof digest);
+ gcry_assert (_gcry_md_get_algo_dlen (hashalgo) == qbits/8);
+
+
+ /* Step 2: Check seedlen. */
+ if (!seed && !seedlen)
+ ; /* No seed value given: We are asked to generate it. */
+ else if (!seed || seedlen < qbits/8)
+ return GPG_ERR_INV_ARG;
+
+ /* Allocate a buffer to later compute SEED+some_increment and a few
+ helper variables. */
+ seed_plus = xtrymalloc (seedlen < sizeof seed_help_buffer?
+ sizeof seed_help_buffer : seedlen);
+ if (!seed_plus)
+ {
+ ec = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ val_2 = mpi_alloc_set_ui (2);
+ value_w = mpi_new (pbits);
+ value_x = mpi_new (pbits);
+
+ /* Step 3: n = \lceil L / outlen \rceil - 1 */
+ value_n = (pbits + qbits - 1) / qbits - 1;
+ /* Step 4: b = L - 1 - (n * outlen) */
+ value_b = pbits - 1 - (value_n * qbits);
+
+ restart:
+ /* Generate Q. */
+ for (;;)
+ {
+ /* Step 5: Generate a (new) seed unless one has been supplied. */
+ if (!seed)
+ {
+ seedlen = qbits/8;
+ gcry_assert (seedlen <= sizeof seed_help_buffer);
+ _gcry_create_nonce (seed_help_buffer, seedlen);
+ seed = seed_help_buffer;
+ }
+
+ /* Step 6: U = hash(seed) */
+ _gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
+
+ /* Step 7: q = 2^{N-1} + U + 1 - (U mod 2) */
+ if ( !(value_u[qbits/8-1] & 0x01) )
+ {
+ for (i=qbits/8-1; i >= 0; i--)
+ {
+ value_u[i]++;
+ if (value_u[i])
+ break;
+ }
+ }
+ _gcry_mpi_release (prime_q); prime_q = NULL;
+ ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+ value_u, qbits/8, NULL);
+ if (ec)
+ goto leave;
+ mpi_set_highbit (prime_q, qbits-1 );
+
+ /* Step 8: Test whether Q is prime using 64 round of Rabin-Miller.
+ According to table C.1 this is sufficient for all
+ supported prime sizes (i.e. up 3072/256). */
+ if (check_prime (prime_q, val_2, 64, NULL, NULL))
+ break; /* Yes, Q is prime. */
+
+ /* Step 8. */
+ seed = NULL; /* Force a new seed at Step 5. */
+ }
+
+ /* Step 11. Note that we do no use an explicit offset but increment
+ SEED_PLUS accordingly. */
+ memcpy (seed_plus, seed, seedlen);
+ counter = 0;
+
+ /* Generate P. */
+ prime_p = mpi_new (pbits);
+ for (;;)
+ {
+ /* Step 11.1: For j = 0,...n let
+ V_j = hash(seed+offset+j)
+ Step 11.2: W = V_0 + V_1*2^outlen +
+ ...
+ + V_{n-1}*2^{(n-1)*outlen}
+ + (V_{n} mod 2^b)*2^{n*outlen}
+ */
+ mpi_set_ui (value_w, 0);
+ for (value_j=0; value_j <= value_n; value_j++)
+ {
+ /* There is no need to have an explicit offset variable: In
+ the first round we shall have an offset of 1 and a j of
+ 0. This is achieved by incrementing SEED_PLUS here. For
+ the next round offset is implicitly updated by using
+ SEED_PLUS again. */
+ for (i=seedlen-1; i >= 0; i--)
+ {
+ seed_plus[i]++;
+ if (seed_plus[i])
+ break;
+ }
+ _gcry_md_hash_buffer (hashalgo, digest, seed_plus, seedlen);
+
+ _gcry_mpi_release (tmpval); tmpval = NULL;
+ ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+ digest, qbits/8, NULL);
+ if (ec)
+ goto leave;
+ if (value_j == value_n)
+ mpi_clear_highbit (tmpval, value_b); /* (V_n mod 2^b) */
+ mpi_lshift (tmpval, tmpval, value_j*qbits);
+ mpi_add (value_w, value_w, tmpval);
+ }
+
+ /* Step 11.3: X = W + 2^{L-1} */
+ mpi_set_ui (value_x, 0);
+ mpi_set_highbit (value_x, pbits-1);
+ mpi_add (value_x, value_x, value_w);
+
+ /* Step 11.4: c = X mod 2q */
+ mpi_mul_2exp (tmpval, prime_q, 1);
+ mpi_mod (tmpval, value_x, tmpval);
+
+ /* Step 11.5: p = X - (c - 1) */
+ mpi_sub_ui (tmpval, tmpval, 1);
+ mpi_sub (prime_p, value_x, tmpval);
+
+ /* Step 11.6: If p < 2^{L-1} skip the primality test. */
+ /* Step 11.7 and 11.8: Primality test. */
+ if (mpi_get_nbits (prime_p) >= pbits-1
+ && check_prime (prime_p, val_2, 64, NULL, NULL) )
+ break; /* Yes, P is prime, continue with Step 15. */
+
+ /* Step 11.9: counter = counter + 1, offset = offset + n + 1.
+ If counter >= 4L goto Step 5. */
+ counter++;
+ if (counter >= 4*pbits)
+ goto restart;
+ }
+
+ /* Step 12: Save p, q, counter and seed. */
+ /* log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", */
+ /* mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); */
+ /* log_printhex ("fips186-3 seed", seed, seedlen); */
+ /* log_printmpi ("fips186-3 p", prime_p); */
+ /* log_printmpi ("fips186-3 q", prime_q); */
+
+ if (r_q)
+ {
+ *r_q = prime_q;
+ prime_q = NULL;
+ }
+ if (r_p)
+ {
+ *r_p = prime_p;
+ prime_p = NULL;
+ }
+ if (r_counter)
+ *r_counter = counter;
+ if (r_seed && r_seedlen)
+ {
+ memcpy (seed_plus, seed, seedlen);
+ *r_seed = seed_plus;
+ seed_plus = NULL;
+ *r_seedlen = seedlen;
+ }
+ if (r_hashalgo)
+ *r_hashalgo = hashalgo;
+
+ leave:
+ _gcry_mpi_release (tmpval);
+ _gcry_mpi_release (value_x);
+ _gcry_mpi_release (value_w);
+ _gcry_mpi_release (prime_p);
+ _gcry_mpi_release (prime_q);
+ xfree (seed_plus);
+ _gcry_mpi_release (val_2);
+ return ec;
+}
diff --git a/comm/third_party/libgcrypt/cipher/pubkey-internal.h b/comm/third_party/libgcrypt/cipher/pubkey-internal.h
new file mode 100644
index 0000000000..d31e26f392
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/pubkey-internal.h
@@ -0,0 +1,105 @@
+/* pubkey-internal.h - Internal defs for pubkey.c
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_PUBKEY_INTERNAL_H
+#define GCRY_PUBKEY_INTERNAL_H
+
+/*-- pubkey-util.c --*/
+gpg_err_code_t _gcry_pk_util_parse_flaglist (gcry_sexp_t list,
+ int *r_flags,
+ enum pk_encoding *r_encoding);
+gpg_err_code_t _gcry_pk_util_get_nbits (gcry_sexp_t list,
+ unsigned int *r_nbits);
+gpg_err_code_t _gcry_pk_util_get_rsa_use_e (gcry_sexp_t list,
+ unsigned long *r_e);
+gpg_err_code_t _gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig,
+ const char **algo_names,
+ gcry_sexp_t *r_parms,
+ int *r_eccflags);
+gpg_err_code_t _gcry_pk_util_preparse_encval (gcry_sexp_t sexp,
+ const char **algo_names,
+ gcry_sexp_t *r_parms,
+ struct pk_encoding_ctx *ctx);
+void _gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
+ enum pk_operation op,
+ unsigned int nbits);
+void _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx);
+gcry_err_code_t _gcry_pk_util_data_to_mpi (gcry_sexp_t input,
+ gcry_mpi_t *ret_mpi,
+ struct pk_encoding_ctx *ctx);
+
+
+
+/*-- rsa-common.c --*/
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_for_enc (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen,
+ const unsigned char *random_override,
+ size_t random_override_len);
+gpg_err_code_t
+_gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen,
+ unsigned int nbits, gcry_mpi_t value);
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen);
+
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen,
+ int algo);
+gpg_err_code_t
+_gcry_rsa_oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+ const unsigned char *value, size_t valuelen,
+ const unsigned char *label, size_t labellen,
+ const void *random_override, size_t random_override_len);
+gpg_err_code_t
+_gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen,
+ unsigned int nbits, int algo,
+ gcry_mpi_t value,
+ const unsigned char *label, size_t labellen);
+gpg_err_code_t
+_gcry_rsa_pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+ const unsigned char *value, size_t valuelen, int saltlen,
+ const void *random_override, size_t random_override_len);
+gpg_err_code_t
+_gcry_rsa_pss_verify (gcry_mpi_t value, gcry_mpi_t encoded,
+ unsigned int nbits, int algo, size_t saltlen);
+
+
+
+/*-- dsa-common.c --*/
+void _gcry_dsa_modify_k (gcry_mpi_t k, gcry_mpi_t q, int qbits);
+gcry_mpi_t _gcry_dsa_gen_k (gcry_mpi_t q, int security_level);
+gpg_err_code_t _gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k,
+ gcry_mpi_t dsa_q, gcry_mpi_t dsa_x,
+ const unsigned char *h1,
+ unsigned int h1len,
+ int halgo,
+ unsigned int extraloops);
+
+gpg_err_code_t _gcry_dsa_normalize_hash (gcry_mpi_t input,
+ gcry_mpi_t *out,
+ unsigned int qbits);
+
+/*-- ecc.c --*/
+gpg_err_code_t _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode,
+ mpi_ec_t ec);
+
+
+#endif /*GCRY_PUBKEY_INTERNAL_H*/
diff --git a/comm/third_party/libgcrypt/cipher/pubkey-util.c b/comm/third_party/libgcrypt/cipher/pubkey-util.c
new file mode 100644
index 0000000000..7ddef7dc31
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/pubkey-util.c
@@ -0,0 +1,1160 @@
+/* pubkey-util.c - Supporting functions for all pubkey modules.
+ * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
+ * 2007, 2008, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2015 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+/* Callback for the pubkey algorithm code to verify PSS signatures.
+ OPAQUE is the data provided by the actual caller. The meaning of
+ TMP depends on the actual algorithm (but there is only RSA); now
+ for RSA it is the output of running the public key function on the
+ input. */
+static int
+pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
+{
+ struct pk_encoding_ctx *ctx = opaque;
+ gcry_mpi_t hash = ctx->verify_arg;
+
+ return _gcry_rsa_pss_verify (hash, tmp, ctx->nbits - 1,
+ ctx->hash_algo, ctx->saltlen);
+}
+
+
+/* Parser for a flag list. On return the encoding is stored at
+ R_ENCODING and the flags are stored at R_FLAGS. If any of them is
+ not needed, NULL may be passed. The function returns 0 on success
+ or an error code. */
+gpg_err_code_t
+_gcry_pk_util_parse_flaglist (gcry_sexp_t list,
+ int *r_flags, enum pk_encoding *r_encoding)
+{
+ gpg_err_code_t rc = 0;
+ const char *s;
+ size_t n;
+ int i;
+ int encoding = PUBKEY_ENC_UNKNOWN;
+ int flags = 0;
+ int igninvflag = 0;
+
+ for (i = list ? sexp_length (list)-1 : 0; i > 0; i--)
+ {
+ s = sexp_nth_data (list, i, &n);
+ if (!s)
+ continue; /* Not a data element. */
+
+ switch (n)
+ {
+ case 3:
+ if (!memcmp (s, "pss", 3) && encoding == PUBKEY_ENC_UNKNOWN)
+ {
+ encoding = PUBKEY_ENC_PSS;
+ flags |= PUBKEY_FLAG_FIXEDLEN;
+ }
+ else if (!memcmp (s, "raw", 3) && encoding == PUBKEY_ENC_UNKNOWN)
+ {
+ encoding = PUBKEY_ENC_RAW;
+ flags |= PUBKEY_FLAG_RAW_FLAG; /* Explicitly given. */
+ }
+ else if (!memcmp (s, "sm2", 3))
+ {
+ encoding = PUBKEY_ENC_RAW;
+ flags |= PUBKEY_FLAG_SM2 | PUBKEY_FLAG_RAW_FLAG;
+ }
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 4:
+ if (!memcmp (s, "comp", 4))
+ flags |= PUBKEY_FLAG_COMP;
+ else if (!memcmp (s, "oaep", 4) && encoding == PUBKEY_ENC_UNKNOWN)
+ {
+ encoding = PUBKEY_ENC_OAEP;
+ flags |= PUBKEY_FLAG_FIXEDLEN;
+ }
+ else if (!memcmp (s, "gost", 4))
+ {
+ encoding = PUBKEY_ENC_RAW;
+ flags |= PUBKEY_FLAG_GOST;
+ }
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 5:
+ if (!memcmp (s, "eddsa", 5))
+ {
+ encoding = PUBKEY_ENC_RAW;
+ flags |= PUBKEY_FLAG_EDDSA;
+ flags |= PUBKEY_FLAG_DJB_TWEAK;
+ }
+ else if (!memcmp (s, "pkcs1", 5) && encoding == PUBKEY_ENC_UNKNOWN)
+ {
+ encoding = PUBKEY_ENC_PKCS1;
+ flags |= PUBKEY_FLAG_FIXEDLEN;
+ }
+ else if (!memcmp (s, "param", 5))
+ flags |= PUBKEY_FLAG_PARAM;
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 6:
+ if (!memcmp (s, "nocomp", 6))
+ flags |= PUBKEY_FLAG_NOCOMP;
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 7:
+ if (!memcmp (s, "rfc6979", 7))
+ flags |= PUBKEY_FLAG_RFC6979;
+ else if (!memcmp (s, "noparam", 7))
+ ; /* Ignore - it is the default. */
+ else if (!memcmp (s, "prehash", 7))
+ flags |= PUBKEY_FLAG_PREHASH;
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 8:
+ if (!memcmp (s, "use-x931", 8))
+ flags |= PUBKEY_FLAG_USE_X931;
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 9:
+ if (!memcmp (s, "pkcs1-raw", 9) && encoding == PUBKEY_ENC_UNKNOWN)
+ {
+ encoding = PUBKEY_ENC_PKCS1_RAW;
+ flags |= PUBKEY_FLAG_FIXEDLEN;
+ }
+ else if (!memcmp (s, "djb-tweak", 9))
+ {
+ encoding = PUBKEY_ENC_RAW;
+ flags |= PUBKEY_FLAG_DJB_TWEAK;
+ }
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 10:
+ if (!memcmp (s, "igninvflag", 10))
+ igninvflag = 1;
+ else if (!memcmp (s, "no-keytest", 10))
+ flags |= PUBKEY_FLAG_NO_KEYTEST;
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 11:
+ if (!memcmp (s, "no-blinding", 11))
+ flags |= PUBKEY_FLAG_NO_BLINDING;
+ else if (!memcmp (s, "use-fips186", 11))
+ flags |= PUBKEY_FLAG_USE_FIPS186;
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ case 13:
+ if (!memcmp (s, "use-fips186-2", 13))
+ flags |= PUBKEY_FLAG_USE_FIPS186_2;
+ else if (!memcmp (s, "transient-key", 13))
+ flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+
+ default:
+ if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
+ break;
+ }
+ }
+
+ if (r_flags)
+ *r_flags = flags;
+ if (r_encoding)
+ *r_encoding = encoding;
+
+ return rc;
+}
+
+
+static int
+get_hash_algo (const char *s, size_t n)
+{
+ static const struct { const char *name; int algo; } hashnames[] = {
+ { "sha1", GCRY_MD_SHA1 },
+ { "md5", GCRY_MD_MD5 },
+ { "sha256", GCRY_MD_SHA256 },
+ { "ripemd160", GCRY_MD_RMD160 },
+ { "rmd160", GCRY_MD_RMD160 },
+ { "sha384", GCRY_MD_SHA384 },
+ { "sha512", GCRY_MD_SHA512 },
+ { "sha224", GCRY_MD_SHA224 },
+ { "md2", GCRY_MD_MD2 },
+ { "md4", GCRY_MD_MD4 },
+ { "tiger", GCRY_MD_TIGER },
+ { "haval", GCRY_MD_HAVAL },
+ { "sha3-224", GCRY_MD_SHA3_224 },
+ { "sha3-256", GCRY_MD_SHA3_256 },
+ { "sha3-384", GCRY_MD_SHA3_384 },
+ { "sha3-512", GCRY_MD_SHA3_512 },
+ { "sm3", GCRY_MD_SM3 },
+ { "shake128", GCRY_MD_SHAKE128 },
+ { "shake256", GCRY_MD_SHAKE256 },
+ { NULL, 0 }
+ };
+ int algo;
+ int i;
+
+ for (i=0; hashnames[i].name; i++)
+ {
+ if ( strlen (hashnames[i].name) == n
+ && !memcmp (hashnames[i].name, s, n))
+ break;
+ }
+ if (hashnames[i].name)
+ algo = hashnames[i].algo;
+ else
+ {
+ /* In case of not listed or dynamically allocated hash
+ algorithm we fall back to this somewhat slower
+ method. Further, it also allows to use OIDs as
+ algorithm names. */
+ char *tmpname;
+
+ tmpname = xtrymalloc (n+1);
+ if (!tmpname)
+ algo = 0; /* Out of core - silently give up. */
+ else
+ {
+ memcpy (tmpname, s, n);
+ tmpname[n] = 0;
+ algo = _gcry_md_map_name (tmpname);
+ xfree (tmpname);
+ }
+ }
+ return algo;
+}
+
+
+/* Get the "nbits" parameter from an s-expression of the format:
+ *
+ * (algo
+ * (parameter_name_1 ....)
+ * ....
+ * (parameter_name_n ....))
+ *
+ * Example:
+ *
+ * (rsa
+ * (nbits 4:2048))
+ *
+ * On success the value for nbits is stored at R_NBITS. If no nbits
+ * parameter is found, the function returns success and stores 0 at
+ * R_NBITS. For parsing errors the function returns an error code and
+ * stores 0 at R_NBITS.
+ */
+gpg_err_code_t
+_gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
+{
+ char buf[50];
+ const char *s;
+ size_t n;
+
+ *r_nbits = 0;
+
+ list = sexp_find_token (list, "nbits", 0);
+ if (!list)
+ return 0; /* No NBITS found. */
+
+ s = sexp_nth_data (list, 1, &n);
+ if (!s || n >= DIM (buf) - 1 )
+ {
+ /* NBITS given without a cdr. */
+ sexp_release (list);
+ return GPG_ERR_INV_OBJ;
+ }
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
+ sexp_release (list);
+ return 0;
+}
+
+
+/* Get the optional "rsa-use-e" parameter from an s-expression of the
+ * format:
+ *
+ * (algo
+ * (parameter_name_1 ....)
+ * ....
+ * (parameter_name_n ....))
+ *
+ * Example:
+ *
+ * (rsa
+ * (nbits 4:2048)
+ * (rsa-use-e 2:41))
+ *
+ * On success the value for nbits is stored at R_E. If no rsa-use-e
+ * parameter is found, the function returns success and stores 65537 at
+ * R_E. For parsing errors the function returns an error code and
+ * stores 0 at R_E.
+ */
+gpg_err_code_t
+_gcry_pk_util_get_rsa_use_e (gcry_sexp_t list, unsigned long *r_e)
+{
+ char buf[50];
+ const char *s;
+ size_t n;
+
+ *r_e = 0;
+
+ list = sexp_find_token (list, "rsa-use-e", 0);
+ if (!list)
+ {
+ *r_e = 65537; /* Not given, use the value generated by old versions. */
+ return 0;
+ }
+
+ s = sexp_nth_data (list, 1, &n);
+ if (!s || n >= DIM (buf) - 1 )
+ {
+ /* No value or value too large. */
+ sexp_release (list);
+ return GPG_ERR_INV_OBJ;
+ }
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ *r_e = strtoul (buf, NULL, 0);
+ sexp_release (list);
+ return 0;
+}
+
+
+/* Parse a "sig-val" s-expression and store the inner parameter list at
+ R_PARMS. ALGO_NAMES is used to verify that the algorithm in
+ "sig-val" is valid. Returns 0 on success and stores a new list at
+ R_PARMS which must be freed by the caller. On error R_PARMS is set
+ to NULL and an error code returned. If R_ECCFLAGS is not NULL flag
+ values are set into it; as of now they are only used with ecc
+ algorithms. */
+gpg_err_code_t
+_gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig, const char **algo_names,
+ gcry_sexp_t *r_parms, int *r_eccflags)
+{
+ gpg_err_code_t rc;
+ gcry_sexp_t l1 = NULL;
+ gcry_sexp_t l2 = NULL;
+ char *name = NULL;
+ int i;
+
+ *r_parms = NULL;
+ if (r_eccflags)
+ *r_eccflags = 0;
+
+ /* Extract the signature value. */
+ l1 = sexp_find_token (s_sig, "sig-val", 0);
+ if (!l1)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Does not contain a signature value object. */
+ goto leave;
+ }
+
+ l2 = sexp_nth (l1, 1);
+ if (!l2)
+ {
+ rc = GPG_ERR_NO_OBJ; /* No cadr for the sig object. */
+ goto leave;
+ }
+ name = sexp_nth_string (l2, 0);
+ if (!name)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ goto leave;
+ }
+ else if (!strcmp (name, "flags"))
+ {
+ /* Skip a "flags" parameter and look again for the algorithm
+ name. This is not used but here just for the sake of
+ consistent S-expressions we need to handle it. */
+ sexp_release (l2);
+ l2 = sexp_nth (l1, 2);
+ if (!l2)
+ {
+ rc = GPG_ERR_INV_OBJ;
+ goto leave;
+ }
+ xfree (name);
+ name = sexp_nth_string (l2, 0);
+ if (!name)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ goto leave;
+ }
+ }
+
+ for (i=0; algo_names[i]; i++)
+ if (!stricmp (name, algo_names[i]))
+ break;
+ if (!algo_names[i])
+ {
+ rc = GPG_ERR_CONFLICT; /* "sig-val" uses an unexpected algo. */
+ goto leave;
+ }
+ if (r_eccflags)
+ {
+ if (!strcmp (name, "eddsa"))
+ *r_eccflags = PUBKEY_FLAG_EDDSA;
+ if (!strcmp (name, "gost"))
+ *r_eccflags = PUBKEY_FLAG_GOST;
+ if (!strcmp (name, "sm2"))
+ *r_eccflags = PUBKEY_FLAG_SM2;
+ }
+
+ *r_parms = l2;
+ l2 = NULL;
+ rc = 0;
+
+ leave:
+ xfree (name);
+ sexp_release (l2);
+ sexp_release (l1);
+ return rc;
+}
+
+
+/* Parse a "enc-val" s-expression and store the inner parameter list
+ at R_PARMS. ALGO_NAMES is used to verify that the algorithm in
+ "enc-val" is valid. Returns 0 on success and stores a new list at
+ R_PARMS which must be freed by the caller. On error R_PARMS is set
+ to NULL and an error code returned. If R_ECCFLAGS is not NULL flag
+ values are set into it; as of now they are only used with ecc
+ algorithms.
+
+ (enc-val
+ [(flags [raw, pkcs1, oaep, no-blinding])]
+ [(hash-algo <algo>)]
+ [(label <label>)]
+ (<algo>
+ (<param_name1> <mpi>)
+ ...
+ (<param_namen> <mpi>)))
+
+ HASH-ALGO and LABEL are specific to OAEP. CTX will be updated with
+ encoding information. */
+gpg_err_code_t
+_gcry_pk_util_preparse_encval (gcry_sexp_t sexp, const char **algo_names,
+ gcry_sexp_t *r_parms,
+ struct pk_encoding_ctx *ctx)
+{
+ gcry_err_code_t rc = 0;
+ gcry_sexp_t l1 = NULL;
+ gcry_sexp_t l2 = NULL;
+ char *name = NULL;
+ size_t n;
+ int parsed_flags = 0;
+ int i;
+
+ *r_parms = NULL;
+
+ /* Check that the first element is valid. */
+ l1 = sexp_find_token (sexp, "enc-val" , 0);
+ if (!l1)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object. */
+ goto leave;
+ }
+
+ l2 = sexp_nth (l1, 1);
+ if (!l2)
+ {
+ rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
+ goto leave;
+ }
+
+ /* Extract identifier of sublist. */
+ name = sexp_nth_string (l2, 0);
+ if (!name)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ goto leave;
+ }
+
+ if (!strcmp (name, "flags"))
+ {
+ const char *s;
+
+ /* There is a flags element - process it. */
+ rc = _gcry_pk_util_parse_flaglist (l2, &parsed_flags, &ctx->encoding);
+ if (rc)
+ goto leave;
+ if (ctx->encoding == PUBKEY_ENC_PSS)
+ {
+ rc = GPG_ERR_CONFLICT;
+ goto leave;
+ }
+
+ /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
+ if (ctx->encoding == PUBKEY_ENC_OAEP)
+ {
+ /* Get HASH-ALGO. */
+ sexp_release (l2);
+ l2 = sexp_find_token (l1, "hash-algo", 0);
+ if (l2)
+ {
+ s = sexp_nth_data (l2, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ }
+ if (rc)
+ goto leave;
+ }
+
+ /* Get LABEL. */
+ sexp_release (l2);
+ l2 = sexp_find_token (l1, "label", 0);
+ if (l2)
+ {
+ s = sexp_nth_data (l2, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ ctx->label = xtrymalloc (n);
+ if (!ctx->label)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (ctx->label, s, n);
+ ctx->labellen = n;
+ }
+ }
+ if (rc)
+ goto leave;
+ }
+ }
+
+ /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
+ for (i = 2; (sexp_release (l2), l2 = sexp_nth (l1, i)); i++)
+ {
+ s = sexp_nth_data (l2, 0, &n);
+ if (!(n == 9 && !memcmp (s, "hash-algo", 9))
+ && !(n == 5 && !memcmp (s, "label", 5))
+ && !(n == 15 && !memcmp (s, "random-override", 15)))
+ break;
+ }
+ if (!l2)
+ {
+ rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
+ goto leave;
+ }
+
+ /* Extract sublist identifier. */
+ xfree (name);
+ name = sexp_nth_string (l2, 0);
+ if (!name)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ goto leave;
+ }
+ }
+ else /* No flags - flag as legacy structure. */
+ parsed_flags |= PUBKEY_FLAG_LEGACYRESULT;
+
+ for (i=0; algo_names[i]; i++)
+ if (!stricmp (name, algo_names[i]))
+ break;
+ if (!algo_names[i])
+ {
+ rc = GPG_ERR_CONFLICT; /* "enc-val" uses an unexpected algo. */
+ goto leave;
+ }
+
+ *r_parms = l2;
+ l2 = NULL;
+ ctx->flags |= parsed_flags;
+ rc = 0;
+
+ leave:
+ xfree (name);
+ sexp_release (l2);
+ sexp_release (l1);
+ return rc;
+}
+
+
+/* Initialize an encoding context. */
+void
+_gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
+ enum pk_operation op,
+ unsigned int nbits)
+{
+ ctx->op = op;
+ ctx->nbits = nbits;
+ ctx->encoding = PUBKEY_ENC_UNKNOWN;
+ ctx->flags = 0;
+ if (fips_mode ())
+ {
+ ctx->hash_algo = GCRY_MD_SHA256;
+ }
+ else
+ {
+ ctx->hash_algo = GCRY_MD_SHA1;
+ }
+ ctx->label = NULL;
+ ctx->labellen = 0;
+ ctx->saltlen = 20;
+ ctx->verify_cmp = NULL;
+ ctx->verify_arg = NULL;
+}
+
+/* Free a context initialzied by _gcry_pk_util_init_encoding_ctx. */
+void
+_gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
+{
+ xfree (ctx->label);
+}
+
+
+/* Take the hash value and convert into an MPI, suitable for
+ passing to the low level functions. We currently support the
+ old style way of passing just a MPI and the modern interface which
+ allows to pass flags so that we can choose between raw and pkcs1
+ padding - may be more padding options later.
+
+ (<mpi>)
+ or
+ (data
+ [(flags [raw, direct, pkcs1, oaep, pss,
+ no-blinding, rfc6979, eddsa, prehash])]
+ [(hash <algo> <value>)]
+ [(value <text>)]
+ [(hash-algo <algo>)]
+ [(label <label>)]
+ [(salt-length <length>)]
+ [(random-override <data>)]
+ )
+
+ Either the VALUE or the HASH element must be present for use
+ with signatures. VALUE is used for encryption.
+
+ HASH-ALGO is specific to OAEP and EDDSA.
+
+ LABEL is specific to OAEP.
+
+ SALT-LENGTH is for PSS it is limited to 16384 bytes.
+
+ RANDOM-OVERRIDE is used to replace random nonces for regression
+ testing. */
+gcry_err_code_t
+_gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
+ struct pk_encoding_ctx *ctx)
+{
+ gcry_err_code_t rc = 0;
+ gcry_sexp_t ldata, lhash, lvalue;
+ size_t n;
+ const char *s;
+ int unknown_flag = 0;
+ int parsed_flags = 0;
+
+ *ret_mpi = NULL;
+ ldata = sexp_find_token (input, "data", 0);
+ if (!ldata)
+ { /* assume old style */
+ int mpifmt = (ctx->flags & PUBKEY_FLAG_RAW_FLAG) ?
+ GCRYMPI_FMT_OPAQUE : GCRYMPI_FMT_STD;
+
+ *ret_mpi = sexp_nth_mpi (input, 0, mpifmt);
+ return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
+ }
+
+ /* See whether there is a flags list. */
+ {
+ gcry_sexp_t lflags = sexp_find_token (ldata, "flags", 0);
+ if (lflags)
+ {
+ if (_gcry_pk_util_parse_flaglist (lflags,
+ &parsed_flags, &ctx->encoding))
+ unknown_flag = 1;
+ sexp_release (lflags);
+ }
+ }
+
+ if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
+
+ /* Get HASH or MPI */
+ lhash = sexp_find_token (ldata, "hash", 0);
+ lvalue = lhash? NULL : sexp_find_token (ldata, "value", 0);
+
+ if (!(!lhash ^ !lvalue))
+ rc = GPG_ERR_INV_OBJ; /* none or both given */
+ else if (unknown_flag)
+ rc = GPG_ERR_INV_FLAG;
+ else if (ctx->encoding == PUBKEY_ENC_RAW
+ && ((parsed_flags & PUBKEY_FLAG_EDDSA)
+ || (ctx->flags & PUBKEY_FLAG_EDDSA)))
+ {
+ /* Prepare for EdDSA. */
+ gcry_sexp_t list;
+ void *value;
+ size_t valuelen;
+
+ if (!lvalue)
+ {
+ rc = GPG_ERR_INV_OBJ;
+ goto leave;
+ }
+ /* Hash algo is determined by curve. No hash-algo is OK. */
+ /* Get HASH-ALGO. */
+ list = sexp_find_token (ldata, "hash-algo", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ }
+ sexp_release (list);
+ }
+ if (rc)
+ goto leave;
+
+ /* Get LABEL. */
+ list = sexp_find_token (ldata, "label", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ ctx->label = xtrymalloc (n);
+ if (!ctx->label)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (ctx->label, s, n);
+ ctx->labellen = n;
+ }
+ }
+ sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ /* Get VALUE. */
+ value = sexp_nth_buffer (lvalue, 1, &valuelen);
+ if (!value)
+ {
+ /* We assume that a zero length message is meant by
+ "(value)". This is commonly used by test vectors. Note
+ that S-expression do not allow zero length items. */
+ valuelen = 0;
+ value = xtrymalloc (1);
+ if (!value)
+ rc = gpg_err_code_from_syserror ();
+ }
+ else if ((valuelen * 8) < valuelen)
+ {
+ xfree (value);
+ rc = GPG_ERR_TOO_LARGE;
+ }
+ if (rc)
+ goto leave;
+
+ /* Note that mpi_set_opaque takes ownership of VALUE. */
+ *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
+ }
+ else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
+ && ((parsed_flags & PUBKEY_FLAG_RAW_FLAG)
+ || (parsed_flags & PUBKEY_FLAG_RFC6979)))
+ {
+ /* Raw encoding along with a hash element. This is commonly
+ used for DSA. For better backward error compatibility we
+ allow this only if either the rfc6979 flag has been given or
+ the raw flags was explicitly given. */
+ if (sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ void *value;
+ size_t valuelen;
+
+ ctx->hash_algo = get_hash_algo (s, n);
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else if (!(value=sexp_nth_buffer (lhash, 2, &valuelen)))
+ rc = GPG_ERR_INV_OBJ;
+ else if ((valuelen * 8) < valuelen)
+ {
+ xfree (value);
+ rc = GPG_ERR_TOO_LARGE;
+ }
+ else
+ *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
+ {
+ /* RFC6969 may only be used with the a hash value and not the
+ MPI based value. */
+ if (parsed_flags & PUBKEY_FLAG_RFC6979)
+ {
+ rc = GPG_ERR_CONFLICT;
+ goto leave;
+ }
+
+ /* Get the value */
+ *ret_mpi = sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
+ if (!*ret_mpi)
+ rc = GPG_ERR_INV_OBJ;
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
+ && ctx->op == PUBKEY_OP_ENCRYPT)
+ {
+ const void * value;
+ size_t valuelen;
+ gcry_sexp_t list;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
+
+ if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ /* Get optional RANDOM-OVERRIDE. */
+ list = sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = xtrymalloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
+ value, valuelen,
+ random_override,
+ random_override_len);
+ xfree (random_override);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
+ && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
+ {
+ if (sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ const void * value;
+ size_t valuelen;
+
+ ctx->hash_algo = get_hash_algo (s, n);
+
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
+ || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
+ value, valuelen,
+ ctx->hash_algo);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PKCS1_RAW && lvalue
+ && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
+ {
+ const void * value;
+ size_t valuelen;
+
+ if (sexp_length (lvalue) != 2)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(value=sexp_nth_data (lvalue, 1, &valuelen))
+ || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ rc = _gcry_rsa_pkcs1_encode_raw_for_sig (ret_mpi, ctx->nbits,
+ value, valuelen);
+ }
+ else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
+ && ctx->op == PUBKEY_OP_ENCRYPT)
+ {
+ const void * value;
+ size_t valuelen;
+
+ if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ gcry_sexp_t list;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
+
+ /* Get HASH-ALGO. */
+ list = sexp_find_token (ldata, "hash-algo", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ }
+ sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ /* Get LABEL. */
+ list = sexp_find_token (ldata, "label", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ ctx->label = xtrymalloc (n);
+ if (!ctx->label)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (ctx->label, s, n);
+ ctx->labellen = n;
+ }
+ }
+ sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+ /* Get optional RANDOM-OVERRIDE. */
+ list = sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = xtrymalloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
+ value, valuelen,
+ ctx->label, ctx->labellen,
+ random_override, random_override_len);
+
+ xfree (random_override);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
+ && ctx->op == PUBKEY_OP_SIGN)
+ {
+ if (sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ const void * value;
+ size_t valuelen;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
+
+ ctx->hash_algo = get_hash_algo (s, n);
+
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
+ || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ gcry_sexp_t list;
+
+ /* Get SALT-LENGTH. */
+ list = sexp_find_token (ldata, "salt-length", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+ ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
+ sexp_release (list);
+ }
+
+ /* Get optional RANDOM-OVERRIDE. */
+ list = sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = xtrymalloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ /* Encode the data. (NBITS-1 is due to 8.1.1, step 1.) */
+ rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
+ ctx->hash_algo,
+ value, valuelen, ctx->saltlen,
+ random_override, random_override_len);
+
+ xfree (random_override);
+ }
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
+ && ctx->op == PUBKEY_OP_VERIFY)
+ {
+ if (sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else
+ {
+ gcry_sexp_t list;
+ /* Get SALT-LENGTH. */
+ list = sexp_find_token (ldata, "salt-length", 0);
+ if (list)
+ {
+ unsigned long ul;
+
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ sexp_release (list);
+ goto leave;
+ }
+ ul = strtoul (s, NULL, 10);
+ if (ul > 16384)
+ {
+ rc = GPG_ERR_TOO_LARGE;
+ sexp_release (list);
+ goto leave;
+ }
+ ctx->saltlen = ul;
+ sexp_release (list);
+ }
+
+ *ret_mpi = sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
+ if (!*ret_mpi)
+ rc = GPG_ERR_INV_OBJ;
+ ctx->verify_cmp = pss_verify_cmp;
+ ctx->verify_arg = *ret_mpi;
+ }
+ }
+ }
+ else
+ rc = GPG_ERR_CONFLICT;
+
+ leave:
+ sexp_release (ldata);
+ sexp_release (lhash);
+ sexp_release (lvalue);
+
+ if (!rc)
+ ctx->flags |= parsed_flags;
+ else
+ {
+ xfree (ctx->label);
+ ctx->label = NULL;
+ }
+
+ return rc;
+}
diff --git a/comm/third_party/libgcrypt/cipher/pubkey.c b/comm/third_party/libgcrypt/cipher/pubkey.c
new file mode 100644
index 0000000000..4c07e33bfc
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/pubkey.c
@@ -0,0 +1,970 @@
+/* pubkey.c - pubkey dispatcher
+ * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
+ * 2007, 2008, 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "pubkey-internal.h"
+
+
+/* This is the list of the public-key algorithms included in
+ Libgcrypt. */
+static gcry_pk_spec_t * const pubkey_list[] =
+ {
+#if USE_ECC
+ &_gcry_pubkey_spec_ecc,
+#endif
+#if USE_RSA
+ &_gcry_pubkey_spec_rsa,
+#endif
+#if USE_DSA
+ &_gcry_pubkey_spec_dsa,
+#endif
+#if USE_ELGAMAL
+ &_gcry_pubkey_spec_elg,
+#endif
+ NULL
+ };
+
+
+static int
+map_algo (int algo)
+{
+ switch (algo)
+ {
+ case GCRY_PK_RSA_E: return GCRY_PK_RSA;
+ case GCRY_PK_RSA_S: return GCRY_PK_RSA;
+ case GCRY_PK_ELG_E: return GCRY_PK_ELG;
+ case GCRY_PK_ECDSA: return GCRY_PK_ECC;
+ case GCRY_PK_ECDH: return GCRY_PK_ECC;
+ default: return algo;
+ }
+}
+
+
+/* Return the spec structure for the public key algorithm ALGO. For
+ an unknown algorithm NULL is returned. */
+static gcry_pk_spec_t *
+spec_from_algo (int algo)
+{
+ int idx;
+ gcry_pk_spec_t *spec;
+
+ algo = map_algo (algo);
+
+ for (idx = 0; (spec = pubkey_list[idx]); idx++)
+ if (algo == spec->algo)
+ return spec;
+ return NULL;
+}
+
+
+/* Return the spec structure for the public key algorithm with NAME.
+ For an unknown name NULL is returned. */
+static gcry_pk_spec_t *
+spec_from_name (const char *name)
+{
+ gcry_pk_spec_t *spec;
+ int idx;
+ const char **aliases;
+
+ for (idx=0; (spec = pubkey_list[idx]); idx++)
+ {
+ if (!stricmp (name, spec->name))
+ return spec;
+ for (aliases = spec->aliases; *aliases; aliases++)
+ if (!stricmp (name, *aliases))
+ return spec;
+ }
+
+ return NULL;
+}
+
+
+
+/* Given the s-expression SEXP with the first element be either
+ * "private-key" or "public-key" return the spec structure for it. We
+ * look through the list to find a list beginning with "private-key"
+ * or "public-key" - the first one found is used. If WANT_PRIVATE is
+ * set the function will only succeed if a private key has been given.
+ * On success the spec is stored at R_SPEC. On error NULL is stored
+ * at R_SPEC and an error code returned. If R_PARMS is not NULL and
+ * the function returns success, the parameter list below
+ * "private-key" or "public-key" is stored there and the caller must
+ * call gcry_sexp_release on it.
+ */
+static gcry_err_code_t
+spec_from_sexp (gcry_sexp_t sexp, int want_private,
+ gcry_pk_spec_t **r_spec, gcry_sexp_t *r_parms)
+{
+ gcry_sexp_t list, l2;
+ char *name;
+ gcry_pk_spec_t *spec;
+
+ *r_spec = NULL;
+ if (r_parms)
+ *r_parms = NULL;
+
+ /* Check that the first element is valid. If we are looking for a
+ public key but a private key was supplied, we allow the use of
+ the private key anyway. The rationale for this is that the
+ private key is a superset of the public key. */
+ list = sexp_find_token (sexp, want_private? "private-key":"public-key", 0);
+ if (!list && !want_private)
+ list = sexp_find_token (sexp, "private-key", 0);
+ if (!list)
+ return GPG_ERR_INV_OBJ; /* Does not contain a key object. */
+
+ l2 = sexp_cadr (list);
+ sexp_release (list);
+ list = l2;
+ name = sexp_nth_string (list, 0);
+ if (!name)
+ {
+ sexp_release ( list );
+ return GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ }
+ spec = spec_from_name (name);
+ xfree (name);
+ if (!spec)
+ {
+ sexp_release (list);
+ return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+ }
+ *r_spec = spec;
+ if (r_parms)
+ *r_parms = list;
+ else
+ sexp_release (list);
+ return 0;
+}
+
+
+
+/* Disable the use of the algorithm ALGO. This is not thread safe and
+ should thus be called early. */
+static void
+disable_pubkey_algo (int algo)
+{
+ gcry_pk_spec_t *spec = spec_from_algo (algo);
+
+ if (spec)
+ spec->flags.disabled = 1;
+}
+
+
+
+/*
+ * Map a string to the pubkey algo
+ */
+int
+_gcry_pk_map_name (const char *string)
+{
+ gcry_pk_spec_t *spec;
+
+ if (!string)
+ return 0;
+ spec = spec_from_name (string);
+ if (!spec)
+ return 0;
+ if (spec->flags.disabled)
+ return 0;
+ return spec->algo;
+}
+
+
+/* Map the public key algorithm whose ID is contained in ALGORITHM to
+ a string representation of the algorithm name. For unknown
+ algorithm IDs this functions returns "?". */
+const char *
+_gcry_pk_algo_name (int algo)
+{
+ gcry_pk_spec_t *spec;
+
+ spec = spec_from_algo (algo);
+ if (spec)
+ return spec->name;
+ return "?";
+}
+
+
+/****************
+ * A USE of 0 means: don't care.
+ */
+static gcry_err_code_t
+check_pubkey_algo (int algo, unsigned use)
+{
+ gcry_err_code_t err = 0;
+ gcry_pk_spec_t *spec;
+
+ spec = spec_from_algo (algo);
+ if (spec)
+ {
+ if (((use & GCRY_PK_USAGE_SIGN)
+ && (! (spec->use & GCRY_PK_USAGE_SIGN)))
+ || ((use & GCRY_PK_USAGE_ENCR)
+ && (! (spec->use & GCRY_PK_USAGE_ENCR))))
+ err = GPG_ERR_WRONG_PUBKEY_ALGO;
+ }
+ else
+ err = GPG_ERR_PUBKEY_ALGO;
+
+ return err;
+}
+
+
+/****************
+ * Return the number of public key material numbers
+ */
+static int
+pubkey_get_npkey (int algo)
+{
+ gcry_pk_spec_t *spec = spec_from_algo (algo);
+
+ return spec? strlen (spec->elements_pkey) : 0;
+}
+
+
+/****************
+ * Return the number of secret key material numbers
+ */
+static int
+pubkey_get_nskey (int algo)
+{
+ gcry_pk_spec_t *spec = spec_from_algo (algo);
+
+ return spec? strlen (spec->elements_skey) : 0;
+}
+
+
+/****************
+ * Return the number of signature material numbers
+ */
+static int
+pubkey_get_nsig (int algo)
+{
+ gcry_pk_spec_t *spec = spec_from_algo (algo);
+
+ return spec? strlen (spec->elements_sig) : 0;
+}
+
+/****************
+ * Return the number of encryption material numbers
+ */
+static int
+pubkey_get_nenc (int algo)
+{
+ gcry_pk_spec_t *spec = spec_from_algo (algo);
+
+ return spec? strlen (spec->elements_enc) : 0;
+}
+
+
+
+/*
+ Do a PK encrypt operation
+
+ Caller has to provide a public key as the SEXP pkey and data as a
+ SEXP with just one MPI in it. Alternatively S_DATA might be a
+ complex S-Expression, similar to the one used for signature
+ verification. This provides a flag which allows to handle PKCS#1
+ block type 2 padding. The function returns a sexp which may be
+ passed to to pk_decrypt.
+
+ Returns: 0 or an errorcode.
+
+ s_data = See comment for _gcry_pk_util_data_to_mpi
+ s_pkey = <key-as-defined-in-sexp_to_key>
+ r_ciph = (enc-val
+ (<algo>
+ (<param_name1> <mpi>)
+ ...
+ (<param_namen> <mpi>)
+ ))
+
+*/
+gcry_err_code_t
+_gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
+{
+ gcry_err_code_t rc;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms;
+
+ *r_ciph = NULL;
+
+ rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
+ if (rc)
+ goto leave;
+
+ if (spec->encrypt)
+ rc = spec->encrypt (r_ciph, s_data, keyparms);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+ sexp_release (keyparms);
+ return rc;
+}
+
+
+/*
+ Do a PK decrypt operation
+
+ Caller has to provide a secret key as the SEXP skey and data in a
+ format as created by gcry_pk_encrypt. For historic reasons the
+ function returns simply an MPI as an S-expression part; this is
+ deprecated and the new method should be used which returns a real
+ S-expressionl this is selected by adding at least an empty flags
+ list to S_DATA.
+
+ Returns: 0 or an errorcode.
+
+ s_data = (enc-val
+ [(flags [raw, pkcs1, oaep])]
+ (<algo>
+ (<param_name1> <mpi>)
+ ...
+ (<param_namen> <mpi>)
+ ))
+ s_skey = <key-as-defined-in-sexp_to_key>
+ r_plain= Either an incomplete S-expression without the parentheses
+ or if the flags list is used (even if empty) a real S-expression:
+ (value PLAIN). In raw mode (or no flags given) the returned value
+ is to be interpreted as a signed MPI, thus it may have an extra
+ leading zero octet even if not included in the original data.
+ With pkcs1 or oaep decoding enabled the returned value is a
+ verbatim octet string.
+ */
+gcry_err_code_t
+_gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
+{
+ gcry_err_code_t rc;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms;
+
+ *r_plain = NULL;
+
+ rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
+ if (rc)
+ goto leave;
+
+ if (spec->decrypt)
+ rc = spec->decrypt (r_plain, s_data, keyparms);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+ sexp_release (keyparms);
+ return rc;
+}
+
+
+
+/*
+ Create a signature.
+
+ Caller has to provide a secret key as the SEXP skey and data
+ expressed as a SEXP list hash with only one element which should
+ instantly be available as a MPI. Alternatively the structure given
+ below may be used for S_HASH, it provides the abiliy to pass flags
+ to the operation; the flags defined by now are "pkcs1" which does
+ PKCS#1 block type 1 style padding and "pss" for PSS encoding.
+
+ Returns: 0 or an errorcode.
+ In case of 0 the function returns a new SEXP with the
+ signature value; the structure of this signature depends on the
+ other arguments but is always suitable to be passed to
+ gcry_pk_verify
+
+ s_hash = See comment for _gcry-pk_util_data_to_mpi
+
+ s_skey = <key-as-defined-in-sexp_to_key>
+ r_sig = (sig-val
+ (<algo>
+ (<param_name1> <mpi>)
+ ...
+ (<param_namen> <mpi>))
+ [(hash algo)])
+
+ Note that (hash algo) in R_SIG is not used.
+*/
+gcry_err_code_t
+_gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
+{
+ gcry_err_code_t rc;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms;
+
+ *r_sig = NULL;
+
+ rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
+ if (rc)
+ goto leave;
+
+ if (spec->sign)
+ rc = spec->sign (r_sig, s_hash, keyparms);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+ sexp_release (keyparms);
+ return rc;
+}
+
+
+/*
+ Verify a signature.
+
+ Caller has to supply the public key pkey, the signature sig and his
+ hashvalue data. Public key has to be a standard public key given
+ as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
+ must be an S-Exp like the one in sign too. */
+gcry_err_code_t
+_gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
+{
+ gcry_err_code_t rc;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms;
+
+ rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
+ if (rc)
+ goto leave;
+
+ if (spec->verify)
+ rc = spec->verify (s_sig, s_hash, keyparms);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+ sexp_release (keyparms);
+ return rc;
+}
+
+
+/*
+ Test a key.
+
+ This may be used either for a public or a secret key to see whether
+ the internal structure is okay.
+
+ Returns: 0 or an errorcode.
+
+ NOTE: We currently support only secret key checking. */
+gcry_err_code_t
+_gcry_pk_testkey (gcry_sexp_t s_key)
+{
+ gcry_err_code_t rc;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms;
+
+ rc = spec_from_sexp (s_key, 1, &spec, &keyparms);
+ if (rc)
+ goto leave;
+
+ if (spec->check_secret_key)
+ rc = spec->check_secret_key (keyparms);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+ sexp_release (keyparms);
+ return rc;
+}
+
+
+/*
+ Create a public key pair and return it in r_key.
+ How the key is created depends on s_parms:
+ (genkey
+ (algo
+ (parameter_name_1 ....)
+ ....
+ (parameter_name_n ....)
+ ))
+ The key is returned in a format depending on the
+ algorithm. Both, private and secret keys are returned
+ and optionally some additional informatin.
+ For elgamal we return this structure:
+ (key-data
+ (public-key
+ (elg
+ (p <mpi>)
+ (g <mpi>)
+ (y <mpi>)
+ )
+ )
+ (private-key
+ (elg
+ (p <mpi>)
+ (g <mpi>)
+ (y <mpi>)
+ (x <mpi>)
+ )
+ )
+ (misc-key-info
+ (pm1-factors n1 n2 ... nn)
+ ))
+ */
+gcry_err_code_t
+_gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
+{
+ gcry_pk_spec_t *spec = NULL;
+ gcry_sexp_t list = NULL;
+ gcry_sexp_t l2 = NULL;
+ char *name = NULL;
+ gcry_err_code_t rc;
+
+ *r_key = NULL;
+
+ list = sexp_find_token (s_parms, "genkey", 0);
+ if (!list)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
+ goto leave;
+ }
+
+ l2 = sexp_cadr (list);
+ sexp_release (list);
+ list = l2;
+ l2 = NULL;
+ if (! list)
+ {
+ rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
+ goto leave;
+ }
+
+ name = _gcry_sexp_nth_string (list, 0);
+ if (!name)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Algo string missing. */
+ goto leave;
+ }
+
+ spec = spec_from_name (name);
+ xfree (name);
+ name = NULL;
+ if (!spec)
+ {
+ rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+ goto leave;
+ }
+
+ if (spec->generate)
+ rc = spec->generate (list, r_key);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+ sexp_release (list);
+ xfree (name);
+ sexp_release (l2);
+
+ return rc;
+}
+
+
+/*
+ Get the number of nbits from the public key.
+
+ Hmmm: Should we have really this function or is it better to have a
+ more general function to retrieve different properties of the key? */
+unsigned int
+_gcry_pk_get_nbits (gcry_sexp_t key)
+{
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t parms;
+ unsigned int nbits;
+
+ /* Parsing KEY might be considered too much overhead. For example
+ for RSA we would only need to look at P and stop parsing right
+ away. However, with ECC things are more complicate in that only
+ a curve name might be specified. Thus we need to tear the sexp
+ apart. */
+
+ if (spec_from_sexp (key, 0, &spec, &parms))
+ return 0; /* Error - 0 is a suitable indication for that. */
+
+ nbits = spec->get_nbits (parms);
+ sexp_release (parms);
+ return nbits;
+}
+
+
+/* Return the so called KEYGRIP which is the SHA-1 hash of the public
+ key parameters expressed in a way depending on the algorithm.
+
+ ARRAY must either be 20 bytes long or NULL; in the latter case a
+ newly allocated array of that size is returned, otherwise ARRAY or
+ NULL is returned to indicate an error which is most likely an
+ unknown algorithm. The function accepts public or secret keys. */
+unsigned char *
+_gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
+{
+ gcry_sexp_t list = NULL;
+ gcry_sexp_t l2 = NULL;
+ gcry_pk_spec_t *spec = NULL;
+ const char *s;
+ char *name = NULL;
+ int idx;
+ const char *elems;
+ gcry_md_hd_t md = NULL;
+ int okay = 0;
+
+ /* Check that the first element is valid. */
+ list = sexp_find_token (key, "public-key", 0);
+ if (! list)
+ list = sexp_find_token (key, "private-key", 0);
+ if (! list)
+ list = sexp_find_token (key, "protected-private-key", 0);
+ if (! list)
+ list = sexp_find_token (key, "shadowed-private-key", 0);
+ if (! list)
+ return NULL; /* No public- or private-key object. */
+
+ l2 = sexp_cadr (list);
+ sexp_release (list);
+ list = l2;
+ l2 = NULL;
+
+ name = _gcry_sexp_nth_string (list, 0);
+ if (!name)
+ goto fail; /* Invalid structure of object. */
+
+ spec = spec_from_name (name);
+ if (!spec)
+ goto fail; /* Unknown algorithm. */
+
+ elems = spec->elements_grip;
+ if (!elems)
+ goto fail; /* No grip parameter. */
+
+ if (_gcry_md_open (&md, GCRY_MD_SHA1, 0))
+ goto fail;
+
+ if (spec->comp_keygrip)
+ {
+ /* Module specific method to compute a keygrip. */
+ if (spec->comp_keygrip (md, list))
+ goto fail;
+ }
+ else
+ {
+ /* Generic method to compute a keygrip. */
+ for (idx = 0, s = elems; *s; s++, idx++)
+ {
+ const char *data;
+ size_t datalen;
+ char buf[30];
+
+ l2 = sexp_find_token (list, s, 1);
+ if (! l2)
+ goto fail;
+ data = sexp_nth_data (l2, 1, &datalen);
+ if (! data)
+ goto fail;
+
+ snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
+ _gcry_md_write (md, buf, strlen (buf));
+ _gcry_md_write (md, data, datalen);
+ sexp_release (l2);
+ l2 = NULL;
+ _gcry_md_write (md, ")", 1);
+ }
+ }
+
+ if (!array)
+ {
+ array = xtrymalloc (20);
+ if (! array)
+ goto fail;
+ }
+
+ memcpy (array, _gcry_md_read (md, GCRY_MD_SHA1), 20);
+ okay = 1;
+
+ fail:
+ xfree (name);
+ sexp_release (l2);
+ _gcry_md_close (md);
+ sexp_release (list);
+ return okay? array : NULL;
+}
+
+
+
+const char *
+_gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
+{
+ const char *result = NULL;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms = NULL;
+
+ if (r_nbits)
+ *r_nbits = 0;
+
+ if (key)
+ {
+ iterator = 0;
+
+ if (spec_from_sexp (key, 0, &spec, &keyparms))
+ return NULL;
+ }
+ else
+ {
+ spec = spec_from_name ("ecc");
+ if (!spec)
+ return NULL;
+ }
+
+ if (spec->get_curve)
+ result = spec->get_curve (keyparms, iterator, r_nbits);
+
+ sexp_release (keyparms);
+ return result;
+}
+
+
+
+gcry_sexp_t
+_gcry_pk_get_param (int algo, const char *name)
+{
+ gcry_sexp_t result = NULL;
+ gcry_pk_spec_t *spec = NULL;
+
+ algo = map_algo (algo);
+
+ if (algo != GCRY_PK_ECC)
+ return NULL;
+
+ spec = spec_from_name ("ecc");
+ if (spec)
+ {
+ if (spec && spec->get_curve_param)
+ result = spec->get_curve_param (name);
+ }
+ return result;
+}
+
+
+
+gcry_err_code_t
+_gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
+{
+ gcry_err_code_t rc = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_DISABLE_ALGO:
+ /* This one expects a buffer pointing to an integer with the
+ algo number. */
+ if ((! buffer) || (buflen != sizeof (int)))
+ rc = GPG_ERR_INV_ARG;
+ else
+ disable_pubkey_algo (*((int *) buffer));
+ break;
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return rc;
+}
+
+
+/* Return information about the given algorithm
+
+ WHAT selects the kind of information returned:
+
+ GCRYCTL_TEST_ALGO:
+ Returns 0 when the specified algorithm is available for use.
+ Buffer must be NULL, nbytes may have the address of a variable
+ with the required usage of the algorithm. It may be 0 for don't
+ care or a combination of the GCRY_PK_USAGE_xxx flags;
+
+ GCRYCTL_GET_ALGO_USAGE:
+ Return the usage flags for the given algo. An invalid algo
+ returns 0. Disabled algos are ignored here because we
+ only want to know whether the algo is at all capable of
+ the usage.
+
+ Note: Because this function is in most cases used to return an
+ integer value, we can make it easier for the caller to just look at
+ the return value. The caller will in all cases consult the value
+ and thereby detecting whether a error occurred or not (i.e. while
+ checking the block size) */
+gcry_err_code_t
+_gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t rc = 0;
+
+ switch (what)
+ {
+ case GCRYCTL_TEST_ALGO:
+ {
+ int use = nbytes ? *nbytes : 0;
+ if (buffer)
+ rc = GPG_ERR_INV_ARG;
+ else if (check_pubkey_algo (algorithm, use))
+ rc = GPG_ERR_PUBKEY_ALGO;
+ break;
+ }
+
+ case GCRYCTL_GET_ALGO_USAGE:
+ {
+ gcry_pk_spec_t *spec;
+
+ spec = spec_from_algo (algorithm);
+ *nbytes = spec? spec->use : 0;
+ break;
+ }
+
+ case GCRYCTL_GET_ALGO_NPKEY:
+ {
+ /* FIXME? */
+ int npkey = pubkey_get_npkey (algorithm);
+ *nbytes = npkey;
+ break;
+ }
+ case GCRYCTL_GET_ALGO_NSKEY:
+ {
+ /* FIXME? */
+ int nskey = pubkey_get_nskey (algorithm);
+ *nbytes = nskey;
+ break;
+ }
+ case GCRYCTL_GET_ALGO_NSIGN:
+ {
+ /* FIXME? */
+ int nsign = pubkey_get_nsig (algorithm);
+ *nbytes = nsign;
+ break;
+ }
+ case GCRYCTL_GET_ALGO_NENCR:
+ {
+ /* FIXME? */
+ int nencr = pubkey_get_nenc (algorithm);
+ *nbytes = nencr;
+ break;
+ }
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return rc;
+}
+
+
+/* Return an S-expression representing the context CTX. Depending on
+ the state of that context, the S-expression may either be a public
+ key, a private key or any other object used with public key
+ operations. On success a new S-expression is stored at R_SEXP and
+ 0 is returned, on error NULL is store there and an error code is
+ returned. MODE is either 0 or one of the GCRY_PK_GET_xxx values.
+
+ As of now it only support certain ECC operations because a context
+ object is right now only defined for ECC. Over time this function
+ will be extended to cover more algorithms. Note also that the name
+ of the function is gcry_pubkey_xxx and not gcry_pk_xxx. The idea
+ is that we will eventually provide variants of the existing
+ gcry_pk_xxx functions which will take a context parameter. */
+gcry_err_code_t
+_gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
+{
+ mpi_ec_t ec;
+
+ if (!r_sexp)
+ return GPG_ERR_INV_VALUE;
+ *r_sexp = NULL;
+ switch (mode)
+ {
+ case 0:
+ case GCRY_PK_GET_PUBKEY:
+ case GCRY_PK_GET_SECKEY:
+ break;
+ default:
+ return GPG_ERR_INV_VALUE;
+ }
+ if (!ctx)
+ return GPG_ERR_NO_CRYPT_CTX;
+
+ ec = _gcry_ctx_find_pointer (ctx, CONTEXT_TYPE_EC);
+ if (ec)
+ return _gcry_pk_ecc_get_sexp (r_sexp, mode, ec);
+
+ return GPG_ERR_WRONG_CRYPT_CTX;
+}
+
+
+
+/* Explicitly initialize this module. */
+gcry_err_code_t
+_gcry_pk_init (void)
+{
+ if (fips_mode())
+ {
+ /* disable algorithms that are disallowed in fips */
+ int idx;
+ gcry_pk_spec_t *spec;
+
+ for (idx = 0; (spec = pubkey_list[idx]); idx++)
+ if (!spec->flags.fips)
+ spec->flags.disabled = 1;
+ }
+
+ return 0;
+}
+
+
+/* Run the selftests for pubkey algorithm ALGO with optional reporting
+ function REPORT. */
+gpg_error_t
+_gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_err_code_t ec;
+ gcry_pk_spec_t *spec;
+
+ algo = map_algo (algo);
+ spec = spec_from_algo (algo);
+ if (spec && !spec->flags.disabled && spec->selftest)
+ ec = spec->selftest (algo, extended, report);
+ else
+ {
+ ec = GPG_ERR_PUBKEY_ALGO;
+ /* Fixme: We need to change the report function to allow passing
+ of an encryption mode (e.g. pkcs1, ecdsa, or ecdh). */
+ if (report)
+ report ("pubkey", algo, "module",
+ spec && !spec->flags.disabled?
+ "no selftest available" :
+ spec? "algorithm disabled" :
+ "algorithm not found");
+ }
+
+ return gpg_error (ec);
+}
diff --git a/comm/third_party/libgcrypt/cipher/rfc2268.c b/comm/third_party/libgcrypt/cipher/rfc2268.c
new file mode 100644
index 0000000000..f018b64038
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rfc2268.c
@@ -0,0 +1,378 @@
+/* rfc2268.c - The cipher described in rfc2268; aka Ron's Cipher 2.
+ * Copyright (C) 2003 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 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
+ */
+
+/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
+ * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
+ * direct use by Libgcrypt by Werner Koch. This implementation is
+ * only useful for pkcs#12 decryption.
+ *
+ * The implementation here is based on Peter Gutmann's RRC.2 paper.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "types.h"
+#include "cipher.h"
+#include "cipher-internal.h"
+
+#define RFC2268_BLOCKSIZE 8
+
+typedef struct
+{
+ u16 S[64];
+} RFC2268_context;
+
+static const unsigned char rfc2268_sbox[] = {
+ 217, 120, 249, 196, 25, 221, 181, 237,
+ 40, 233, 253, 121, 74, 160, 216, 157,
+ 198, 126, 55, 131, 43, 118, 83, 142,
+ 98, 76, 100, 136, 68, 139, 251, 162,
+ 23, 154, 89, 245, 135, 179, 79, 19,
+ 97, 69, 109, 141, 9, 129, 125, 50,
+ 189, 143, 64, 235, 134, 183, 123, 11,
+ 240, 149, 33, 34, 92, 107, 78, 130,
+ 84, 214, 101, 147, 206, 96, 178, 28,
+ 115, 86, 192, 20, 167, 140, 241, 220,
+ 18, 117, 202, 31, 59, 190, 228, 209,
+ 66, 61, 212, 48, 163, 60, 182, 38,
+ 111, 191, 14, 218, 70, 105, 7, 87,
+ 39, 242, 29, 155, 188, 148, 67, 3,
+ 248, 17, 199, 246, 144, 239, 62, 231,
+ 6, 195, 213, 47, 200, 102, 30, 215,
+ 8, 232, 234, 222, 128, 82, 238, 247,
+ 132, 170, 114, 172, 53, 77, 106, 42,
+ 150, 26, 210, 113, 90, 21, 73, 116,
+ 75, 159, 208, 94, 4, 24, 164, 236,
+ 194, 224, 65, 110, 15, 81, 203, 204,
+ 36, 145, 175, 80, 161, 244, 112, 57,
+ 153, 124, 58, 133, 35, 184, 180, 122,
+ 252, 2, 54, 91, 37, 85, 151, 49,
+ 45, 93, 250, 152, 227, 138, 146, 174,
+ 5, 223, 41, 16, 103, 108, 186, 201,
+ 211, 0, 230, 207, 225, 158, 168, 44,
+ 99, 22, 1, 63, 88, 226, 137, 169,
+ 13, 56, 52, 27, 171, 51, 255, 176,
+ 187, 72, 12, 95, 185, 177, 205, 46,
+ 197, 243, 219, 71, 229, 165, 156, 119,
+ 10, 166, 32, 104, 254, 127, 193, 173
+};
+
+#define rotl16(x,n) (((x) << ((u16)(n))) | ((x) >> (16 - (u16)(n))))
+#define rotr16(x,n) (((x) >> ((u16)(n))) | ((x) << (16 - (u16)(n))))
+
+static const char *selftest (void);
+
+
+static void
+do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ RFC2268_context *ctx = context;
+ register int i, j;
+ u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
+
+ word0 = (word0 << 8) | inbuf[1];
+ word0 = (word0 << 8) | inbuf[0];
+ word1 = (word1 << 8) | inbuf[3];
+ word1 = (word1 << 8) | inbuf[2];
+ word2 = (word2 << 8) | inbuf[5];
+ word2 = (word2 << 8) | inbuf[4];
+ word3 = (word3 << 8) | inbuf[7];
+ word3 = (word3 << 8) | inbuf[6];
+
+ for (i = 0; i < 16; i++)
+ {
+ j = i * 4;
+ /* For some reason I cannot combine those steps. */
+ word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
+ word0 = rotl16(word0, 1);
+
+ word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
+ word1 = rotl16(word1, 2);
+
+ word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
+ word2 = rotl16(word2, 3);
+
+ word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
+ word3 = rotl16(word3, 5);
+
+ if (i == 4 || i == 10)
+ {
+ word0 += ctx->S[word3 & 63];
+ word1 += ctx->S[word0 & 63];
+ word2 += ctx->S[word1 & 63];
+ word3 += ctx->S[word2 & 63];
+ }
+
+ }
+
+ outbuf[0] = word0 & 255;
+ outbuf[1] = word0 >> 8;
+ outbuf[2] = word1 & 255;
+ outbuf[3] = word1 >> 8;
+ outbuf[4] = word2 & 255;
+ outbuf[5] = word2 >> 8;
+ outbuf[6] = word3 & 255;
+ outbuf[7] = word3 >> 8;
+}
+
+static unsigned int
+encrypt_block (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ do_encrypt (context, outbuf, inbuf);
+ return /*burn_stack*/ (4 * sizeof(void *) + sizeof(void *) + sizeof(u32) * 4);
+}
+
+static void
+do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ RFC2268_context *ctx = context;
+ register int i, j;
+ u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
+
+ word0 = (word0 << 8) | inbuf[1];
+ word0 = (word0 << 8) | inbuf[0];
+ word1 = (word1 << 8) | inbuf[3];
+ word1 = (word1 << 8) | inbuf[2];
+ word2 = (word2 << 8) | inbuf[5];
+ word2 = (word2 << 8) | inbuf[4];
+ word3 = (word3 << 8) | inbuf[7];
+ word3 = (word3 << 8) | inbuf[6];
+
+ for (i = 15; i >= 0; i--)
+ {
+ j = i * 4;
+
+ word3 = rotr16(word3, 5);
+ word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
+
+ word2 = rotr16(word2, 3);
+ word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
+
+ word1 = rotr16(word1, 2);
+ word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
+
+ word0 = rotr16(word0, 1);
+ word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
+
+ if (i == 5 || i == 11)
+ {
+ word3 = word3 - ctx->S[word2 & 63];
+ word2 = word2 - ctx->S[word1 & 63];
+ word1 = word1 - ctx->S[word0 & 63];
+ word0 = word0 - ctx->S[word3 & 63];
+ }
+
+ }
+
+ outbuf[0] = word0 & 255;
+ outbuf[1] = word0 >> 8;
+ outbuf[2] = word1 & 255;
+ outbuf[3] = word1 >> 8;
+ outbuf[4] = word2 & 255;
+ outbuf[5] = word2 >> 8;
+ outbuf[6] = word3 & 255;
+ outbuf[7] = word3 >> 8;
+}
+
+static unsigned int
+decrypt_block (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ do_decrypt (context, outbuf, inbuf);
+ return /*burn_stack*/ (4 * sizeof(void *) + sizeof(void *) + sizeof(u32) * 4);
+}
+
+
+static gpg_err_code_t
+setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
+{
+ static int initialized;
+ static const char *selftest_failed;
+ RFC2268_context *ctx = context;
+ unsigned int i;
+ unsigned char *S, x;
+ int len;
+ int bits = keylen * 8;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if (selftest_failed)
+ log_error ("RFC2268 selftest failed (%s).\n", selftest_failed);
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if (keylen < 40 / 8) /* We want at least 40 bits. */
+ return GPG_ERR_INV_KEYLEN;
+
+ S = (unsigned char *) ctx->S;
+
+ for (i = 0; i < keylen; i++)
+ S[i] = key[i];
+
+ for (i = keylen; i < 128; i++)
+ S[i] = rfc2268_sbox[(S[i - keylen] + S[i - 1]) & 255];
+
+ S[0] = rfc2268_sbox[S[0]];
+
+ /* Phase 2 - reduce effective key size to "bits". This was not
+ * discussed in Gutmann's paper. I've copied that from the public
+ * domain code posted in sci.crypt. */
+ if (with_phase2)
+ {
+ len = (bits + 7) >> 3;
+ i = 128 - len;
+ x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
+ S[i] = x;
+
+ while (i--)
+ {
+ x = rfc2268_sbox[x ^ S[i + len]];
+ S[i] = x;
+ }
+ }
+
+ /* Make the expanded key, endian independent. */
+ for (i = 0; i < 64; i++)
+ ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
+
+ return 0;
+}
+
+static gpg_err_code_t
+do_setkey (void *context, const unsigned char *key, unsigned int keylen,
+ cipher_bulk_ops_t *bulk_ops)
+{
+ (void)bulk_ops;
+ return setkey_core (context, key, keylen, 1);
+}
+
+static const char *
+selftest (void)
+{
+ RFC2268_context ctx;
+ unsigned char scratch[16];
+
+ /* Test vectors from Peter Gutmann's paper. */
+ static unsigned char key_1[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static unsigned char plaintext_1[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const unsigned char ciphertext_1[] =
+ { 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 };
+
+ static unsigned char key_2[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+ };
+ static unsigned char plaintext_2[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static unsigned char ciphertext_2[] =
+ { 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 };
+
+ /* This one was checked against libmcrypt's RFC2268. */
+ static unsigned char key_3[] =
+ { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static unsigned char plaintext_3[] =
+ { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static unsigned char ciphertext_3[] =
+ { 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e };
+
+
+ /* First test. */
+ setkey_core (&ctx, key_1, sizeof(key_1), 0);
+ do_encrypt (&ctx, scratch, plaintext_1);
+
+ if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1)))
+ return "RFC2268 encryption test 1 failed.";
+
+ setkey_core (&ctx, key_1, sizeof(key_1), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
+ return "RFC2268 decryption test 1 failed.";
+
+ /* Second test. */
+ setkey_core (&ctx, key_2, sizeof(key_2), 0);
+ do_encrypt (&ctx, scratch, plaintext_2);
+ if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2)))
+ return "RFC2268 encryption test 2 failed.";
+
+ setkey_core (&ctx, key_2, sizeof(key_2), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
+ return "RFC2268 decryption test 2 failed.";
+
+ /* Third test. */
+ setkey_core(&ctx, key_3, sizeof(key_3), 0);
+ do_encrypt(&ctx, scratch, plaintext_3);
+
+ if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3)))
+ return "RFC2268 encryption test 3 failed.";
+
+ setkey_core (&ctx, key_3, sizeof(key_3), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
+ return "RFC2268 decryption test 3 failed.";
+
+ return NULL;
+}
+
+
+
+static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
+ {
+ /*{ "1.2.840.113549.3.2", GCRY_CIPHER_MODE_CBC },*/
+ /* pbeWithSHAAnd40BitRC2_CBC */
+ { "1.2.840.113549.1.12.1.6", GCRY_CIPHER_MODE_CBC },
+ { NULL }
+ };
+
+static gcry_cipher_oid_spec_t oids_rfc2268_128[] =
+ {
+ /* pbeWithSHAAnd128BitRC2_CBC */
+ { "1.2.840.113549.1.12.1.5", GCRY_CIPHER_MODE_CBC },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 =
+ {
+ GCRY_CIPHER_RFC2268_40, {0, 0},
+ "RFC2268_40", NULL, oids_rfc2268_40,
+ RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
+ do_setkey, encrypt_block, decrypt_block
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_128 =
+ {
+ GCRY_CIPHER_RFC2268_128, {0, 0},
+ "RFC2268_128", NULL, oids_rfc2268_128,
+ RFC2268_BLOCKSIZE, 128, sizeof(RFC2268_context),
+ do_setkey, encrypt_block, decrypt_block
+ };
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-aarch64.S b/comm/third_party/libgcrypt/cipher/rijndael-aarch64.S
new file mode 100644
index 0000000000..e77dd4e0b8
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-aarch64.S
@@ -0,0 +1,514 @@
+/* rijndael-aarch64.S - ARMv8/AArch64 assembly implementation of AES cipher
+ *
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__)
+#ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS
+
+.text
+
+/* register macros */
+#define CTX x0
+#define RDST x1
+#define RSRC x2
+#define NROUNDS w3
+#define RTAB x4
+#define RMASK w5
+
+#define RA w8
+#define RB w9
+#define RC w10
+#define RD w11
+
+#define RNA w12
+#define RNB w13
+#define RNC w14
+#define RND w15
+
+#define RT0 w6
+#define RT1 w7
+#define RT2 w16
+#define xRT0 x6
+#define xRT1 x7
+#define xRT2 x16
+
+#define xw8 x8
+#define xw9 x9
+#define xw10 x10
+#define xw11 x11
+
+#define xw12 x12
+#define xw13 x13
+#define xw14 x14
+#define xw15 x15
+
+/***********************************************************************
+ * ARMv8/AArch64 assembly implementation of the AES cipher
+ ***********************************************************************/
+#define preload_first_key(round, ra) \
+ ldr ra, [CTX, #(((round) * 16) + 0 * 4)];
+
+#define dummy(round, ra) /* nothing */
+
+#define addroundkey(ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ ldp rna, rnb, [CTX]; \
+ ldp rnc, rnd, [CTX, #8]; \
+ eor ra, ra, rna; \
+ eor rb, rb, rnb; \
+ eor rc, rc, rnc; \
+ preload_key(1, rna); \
+ eor rd, rd, rnd;
+
+#define do_encround(next_r, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ ldr rnb, [CTX, #(((next_r) * 16) + 1 * 4)]; \
+ \
+ and RT0, RMASK, ra, lsl#2; \
+ ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \
+ and RT1, RMASK, ra, lsr#(8 - 2); \
+ ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \
+ and RT2, RMASK, ra, lsr#(16 - 2); \
+ ldr RT0, [RTAB, xRT0]; \
+ and ra, RMASK, ra, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, xRT1]; \
+ eor rna, rna, RT0; \
+ ldr RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rd, lsl#2; \
+ ldr ra, [RTAB, x##ra]; \
+ \
+ eor rnd, rnd, RT1, ror #24; \
+ and RT1, RMASK, rd, lsr#(8 - 2); \
+ eor rnc, rnc, RT2, ror #16; \
+ and RT2, RMASK, rd, lsr#(16 - 2); \
+ eor rnb, rnb, ra, ror #8; \
+ ldr RT0, [RTAB, xRT0]; \
+ and rd, RMASK, rd, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, xRT1]; \
+ eor rnd, rnd, RT0; \
+ ldr RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rc, lsl#2; \
+ ldr rd, [RTAB, x##rd]; \
+ \
+ eor rnc, rnc, RT1, ror #24; \
+ and RT1, RMASK, rc, lsr#(8 - 2); \
+ eor rnb, rnb, RT2, ror #16; \
+ and RT2, RMASK, rc, lsr#(16 - 2); \
+ eor rna, rna, rd, ror #8; \
+ ldr RT0, [RTAB, xRT0]; \
+ and rc, RMASK, rc, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, xRT1]; \
+ eor rnc, rnc, RT0; \
+ ldr RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rb, lsl#2; \
+ ldr rc, [RTAB, x##rc]; \
+ \
+ eor rnb, rnb, RT1, ror #24; \
+ and RT1, RMASK, rb, lsr#(8 - 2); \
+ eor rna, rna, RT2, ror #16; \
+ and RT2, RMASK, rb, lsr#(16 - 2); \
+ eor rnd, rnd, rc, ror #8; \
+ ldr RT0, [RTAB, xRT0]; \
+ and rb, RMASK, rb, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, xRT1]; \
+ eor rnb, rnb, RT0; \
+ ldr RT2, [RTAB, xRT2]; \
+ eor rna, rna, RT1, ror #24; \
+ ldr rb, [RTAB, x##rb]; \
+ \
+ eor rnd, rnd, RT2, ror #16; \
+ preload_key((next_r) + 1, ra); \
+ eor rnc, rnc, rb, ror #8;
+
+#define do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ and RT0, RMASK, ra, lsl#2; \
+ and RT1, RMASK, ra, lsr#(8 - 2); \
+ and RT2, RMASK, ra, lsr#(16 - 2); \
+ ldrb rna, [RTAB, xRT0]; \
+ and ra, RMASK, ra, lsr#(24 - 2); \
+ ldrb rnd, [RTAB, xRT1]; \
+ and RT0, RMASK, rd, lsl#2; \
+ ldrb rnc, [RTAB, xRT2]; \
+ ror rnd, rnd, #24; \
+ ldrb rnb, [RTAB, x##ra]; \
+ and RT1, RMASK, rd, lsr#(8 - 2); \
+ ror rnc, rnc, #16; \
+ and RT2, RMASK, rd, lsr#(16 - 2); \
+ ror rnb, rnb, #8; \
+ ldrb RT0, [RTAB, xRT0]; \
+ and rd, RMASK, rd, lsr#(24 - 2); \
+ ldrb RT1, [RTAB, xRT1]; \
+ \
+ orr rnd, rnd, RT0; \
+ ldrb RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rc, lsl#2; \
+ ldrb rd, [RTAB, x##rd]; \
+ orr rnc, rnc, RT1, ror #24; \
+ and RT1, RMASK, rc, lsr#(8 - 2); \
+ orr rnb, rnb, RT2, ror #16; \
+ and RT2, RMASK, rc, lsr#(16 - 2); \
+ orr rna, rna, rd, ror #8; \
+ ldrb RT0, [RTAB, xRT0]; \
+ and rc, RMASK, rc, lsr#(24 - 2); \
+ ldrb RT1, [RTAB, xRT1]; \
+ \
+ orr rnc, rnc, RT0; \
+ ldrb RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rb, lsl#2; \
+ ldrb rc, [RTAB, x##rc]; \
+ orr rnb, rnb, RT1, ror #24; \
+ and RT1, RMASK, rb, lsr#(8 - 2); \
+ orr rna, rna, RT2, ror #16; \
+ ldrb RT0, [RTAB, xRT0]; \
+ and RT2, RMASK, rb, lsr#(16 - 2); \
+ ldrb RT1, [RTAB, xRT1]; \
+ orr rnd, rnd, rc, ror #8; \
+ ldrb RT2, [RTAB, xRT2]; \
+ and rb, RMASK, rb, lsr#(24 - 2); \
+ ldrb rb, [RTAB, x##rb]; \
+ \
+ orr rnb, rnb, RT0; \
+ orr rna, rna, RT1, ror #24; \
+ orr rnd, rnd, RT2, ror #16; \
+ orr rnc, rnc, rb, ror #8;
+
+#define firstencround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ addroundkey(ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key); \
+ do_encround((round) + 1, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key);
+
+#define encround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ do_encround((round) + 1, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key);
+
+#define lastencround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ add CTX, CTX, #(((round) + 1) * 16); \
+ add RTAB, RTAB, #1; \
+ do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+ addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy);
+
+.globl _gcry_aes_arm_encrypt_block
+ELF(.type _gcry_aes_arm_encrypt_block,%function;)
+
+_gcry_aes_arm_encrypt_block:
+ /* input:
+ * %x0: keysched, CTX
+ * %x1: dst
+ * %x2: src
+ * %w3: number of rounds.. 10, 12 or 14
+ * %x4: encryption table
+ */
+ CFI_STARTPROC();
+
+ /* read input block */
+
+ /* aligned load */
+ ldp RA, RB, [RSRC];
+ ldp RC, RD, [RSRC, #8];
+#ifndef __AARCH64EL__
+ rev RA, RA;
+ rev RB, RB;
+ rev RC, RC;
+ rev RD, RD;
+#endif
+
+ mov RMASK, #(0xff<<2);
+
+ firstencround(0, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+ encround(1, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(2, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(3, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(4, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(5, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(6, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(7, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+
+ cmp NROUNDS, #12;
+ bge .Lenc_not_128;
+
+ encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+ lastencround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+.Lenc_done:
+
+ /* store output block */
+
+ /* aligned store */
+#ifndef __AARCH64EL__
+ rev RA, RA;
+ rev RB, RB;
+ rev RC, RC;
+ rev RD, RD;
+#endif
+ /* write output block */
+ stp RA, RB, [RDST];
+ stp RC, RD, [RDST, #8];
+
+ mov x0, #(0);
+ ret;
+
+.ltorg
+.Lenc_not_128:
+ beq .Lenc_192
+
+ encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(10, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(11, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(12, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+ lastencround(13, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+ b .Lenc_done;
+
+.ltorg
+.Lenc_192:
+ encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(10, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+ lastencround(11, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+ b .Lenc_done;
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block;)
+
+#define addroundkey_dec(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ ldr rna, [CTX, #(((round) * 16) + 0 * 4)]; \
+ ldr rnb, [CTX, #(((round) * 16) + 1 * 4)]; \
+ eor ra, ra, rna; \
+ ldr rnc, [CTX, #(((round) * 16) + 2 * 4)]; \
+ eor rb, rb, rnb; \
+ ldr rnd, [CTX, #(((round) * 16) + 3 * 4)]; \
+ eor rc, rc, rnc; \
+ preload_first_key((round) - 1, rna); \
+ eor rd, rd, rnd;
+
+#define do_decround(next_r, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ ldr rnb, [CTX, #(((next_r) * 16) + 1 * 4)]; \
+ \
+ and RT0, RMASK, ra, lsl#2; \
+ ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \
+ and RT1, RMASK, ra, lsr#(8 - 2); \
+ ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \
+ and RT2, RMASK, ra, lsr#(16 - 2); \
+ ldr RT0, [RTAB, xRT0]; \
+ and ra, RMASK, ra, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, xRT1]; \
+ eor rna, rna, RT0; \
+ ldr RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rb, lsl#2; \
+ ldr ra, [RTAB, x##ra]; \
+ \
+ eor rnb, rnb, RT1, ror #24; \
+ and RT1, RMASK, rb, lsr#(8 - 2); \
+ eor rnc, rnc, RT2, ror #16; \
+ and RT2, RMASK, rb, lsr#(16 - 2); \
+ eor rnd, rnd, ra, ror #8; \
+ ldr RT0, [RTAB, xRT0]; \
+ and rb, RMASK, rb, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, xRT1]; \
+ eor rnb, rnb, RT0; \
+ ldr RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rc, lsl#2; \
+ ldr rb, [RTAB, x##rb]; \
+ \
+ eor rnc, rnc, RT1, ror #24; \
+ and RT1, RMASK, rc, lsr#(8 - 2); \
+ eor rnd, rnd, RT2, ror #16; \
+ and RT2, RMASK, rc, lsr#(16 - 2); \
+ eor rna, rna, rb, ror #8; \
+ ldr RT0, [RTAB, xRT0]; \
+ and rc, RMASK, rc, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, xRT1]; \
+ eor rnc, rnc, RT0; \
+ ldr RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rd, lsl#2; \
+ ldr rc, [RTAB, x##rc]; \
+ \
+ eor rnd, rnd, RT1, ror #24; \
+ and RT1, RMASK, rd, lsr#(8 - 2); \
+ eor rna, rna, RT2, ror #16; \
+ and RT2, RMASK, rd, lsr#(16 - 2); \
+ eor rnb, rnb, rc, ror #8; \
+ ldr RT0, [RTAB, xRT0]; \
+ and rd, RMASK, rd, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, xRT1]; \
+ eor rnd, rnd, RT0; \
+ ldr RT2, [RTAB, xRT2]; \
+ eor rna, rna, RT1, ror #24; \
+ ldr rd, [RTAB, x##rd]; \
+ \
+ eor rnb, rnb, RT2, ror #16; \
+ preload_key((next_r) - 1, ra); \
+ eor rnc, rnc, rd, ror #8;
+
+#define do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ and RT0, RMASK, ra; \
+ and RT1, RMASK, ra, lsr#8; \
+ and RT2, RMASK, ra, lsr#16; \
+ ldrb rna, [RTAB, xRT0]; \
+ lsr ra, ra, #24; \
+ ldrb rnb, [RTAB, xRT1]; \
+ and RT0, RMASK, rb; \
+ ldrb rnc, [RTAB, xRT2]; \
+ ror rnb, rnb, #24; \
+ ldrb rnd, [RTAB, x##ra]; \
+ and RT1, RMASK, rb, lsr#8; \
+ ror rnc, rnc, #16; \
+ and RT2, RMASK, rb, lsr#16; \
+ ror rnd, rnd, #8; \
+ ldrb RT0, [RTAB, xRT0]; \
+ lsr rb, rb, #24; \
+ ldrb RT1, [RTAB, xRT1]; \
+ \
+ orr rnb, rnb, RT0; \
+ ldrb RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rc; \
+ ldrb rb, [RTAB, x##rb]; \
+ orr rnc, rnc, RT1, ror #24; \
+ and RT1, RMASK, rc, lsr#8; \
+ orr rnd, rnd, RT2, ror #16; \
+ and RT2, RMASK, rc, lsr#16; \
+ orr rna, rna, rb, ror #8; \
+ ldrb RT0, [RTAB, xRT0]; \
+ lsr rc, rc, #24; \
+ ldrb RT1, [RTAB, xRT1]; \
+ \
+ orr rnc, rnc, RT0; \
+ ldrb RT2, [RTAB, xRT2]; \
+ and RT0, RMASK, rd; \
+ ldrb rc, [RTAB, x##rc]; \
+ orr rnd, rnd, RT1, ror #24; \
+ and RT1, RMASK, rd, lsr#8; \
+ orr rna, rna, RT2, ror #16; \
+ ldrb RT0, [RTAB, xRT0]; \
+ and RT2, RMASK, rd, lsr#16; \
+ ldrb RT1, [RTAB, xRT1]; \
+ orr rnb, rnb, rc, ror #8; \
+ ldrb RT2, [RTAB, xRT2]; \
+ lsr rd, rd, #24; \
+ ldrb rd, [RTAB, x##rd]; \
+ \
+ orr rnd, rnd, RT0; \
+ orr rna, rna, RT1, ror #24; \
+ orr rnb, rnb, RT2, ror #16; \
+ orr rnc, rnc, rd, ror #8;
+
+#define firstdecround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ addroundkey_dec(((round) + 1), ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+ do_decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key);
+
+#define decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ do_decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key);
+
+#define set_last_round_rmask(_, __) \
+ mov RMASK, #0xff;
+
+#define lastdecround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ add RTAB, RTAB, #(4 * 256); \
+ do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+ addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy);
+
+.globl _gcry_aes_arm_decrypt_block
+ELF(.type _gcry_aes_arm_decrypt_block,%function;)
+
+_gcry_aes_arm_decrypt_block:
+ /* input:
+ * %x0: keysched, CTX
+ * %x1: dst
+ * %x2: src
+ * %w3: number of rounds.. 10, 12 or 14
+ * %x4: decryption table
+ */
+ CFI_STARTPROC();
+
+ /* read input block */
+
+ /* aligned load */
+ ldp RA, RB, [RSRC];
+ ldp RC, RD, [RSRC, #8];
+#ifndef __AARCH64EL__
+ rev RA, RA;
+ rev RB, RB;
+ rev RC, RC;
+ rev RD, RD;
+#endif
+
+ mov RMASK, #(0xff << 2);
+
+ cmp NROUNDS, #12;
+ bge .Ldec_256;
+
+ firstdecround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+.Ldec_tail:
+ decround(8, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(7, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ decround(6, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(5, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ decround(4, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(3, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ decround(2, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(1, RA, RB, RC, RD, RNA, RNB, RNC, RND, set_last_round_rmask);
+ lastdecround(0, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+ /* store output block */
+
+ /* aligned store */
+#ifndef __AARCH64EL__
+ rev RA, RA;
+ rev RB, RB;
+ rev RC, RC;
+ rev RD, RD;
+#endif
+ /* write output block */
+ stp RA, RB, [RDST];
+ stp RC, RD, [RDST, #8];
+
+ mov x0, #(0);
+ ret;
+
+.ltorg
+.Ldec_256:
+ beq .Ldec_192;
+
+ firstdecround(13, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+ decround(12, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(11, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ decround(10, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+
+ b .Ldec_tail;
+
+.ltorg
+.Ldec_192:
+ firstdecround(11, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+ decround(10, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+
+ b .Ldec_tail;
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_arm_decrypt_block,.-_gcry_aes_arm_decrypt_block;)
+
+#endif /*HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS*/
+#endif /*__AARCH64EL__ */
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-aesni.c b/comm/third_party/libgcrypt/cipher/rijndael-aesni.c
new file mode 100644
index 0000000000..95ec4c2bb7
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-aesni.c
@@ -0,0 +1,3965 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* 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)
+{
+ aesni_prepare ();
+
+ asm volatile ("movdqu %[iv], %%xmm0\n\t"
+ : /* No output */
+ : [iv] "m" (*iv)
+ : "memory" );
+
+ for ( ;nblocks; nblocks-- )
+ {
+ do_aesni_enc (ctx);
+
+ asm volatile ("movdqu %[inbuf], %%xmm1\n\t"
+ "pxor %%xmm1, %%xmm0\n\t"
+ "movdqu %%xmm0, %[outbuf]\n\t"
+ : [outbuf] "=m" (*outbuf)
+ : [inbuf] "m" (*inbuf)
+ : "memory" );
+
+ outbuf += BLOCKSIZE;
+ inbuf += BLOCKSIZE;
+ }
+
+ asm volatile ("movdqu %%xmm0, %[iv]\n\t"
+ : [iv] "=m" (*iv)
+ :
+ : "memory" );
+
+ aesni_cleanup ();
+}
+
+
+void 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)
+{
+ aesni_prepare_2_7_variable;
+
+ aesni_prepare ();
+ aesni_prepare_2_7();
+
+ asm volatile ("movdqu %[iv], %%xmm5\n\t"
+ : /* No output */
+ : [iv] "m" (*iv)
+ : "memory" );
+
+ for ( ;nblocks; nblocks-- )
+ {
+ asm volatile ("movdqu %[inbuf], %%xmm0\n\t"
+ "pxor %%xmm5, %%xmm0\n\t"
+ : /* No output */
+ : [inbuf] "m" (*inbuf)
+ : "memory" );
+
+ do_aesni_enc (ctx);
+
+ asm volatile ("movdqa %%xmm0, %%xmm5\n\t"
+ "movdqu %%xmm0, %[outbuf]\n\t"
+ : [outbuf] "=m" (*outbuf)
+ :
+ : "memory" );
+
+ inbuf += BLOCKSIZE;
+ if (!cbc_mac)
+ outbuf += BLOCKSIZE;
+ }
+
+ asm volatile ("movdqu %%xmm5, %[iv]\n\t"
+ : [iv] "=m" (*iv)
+ :
+ : "memory" );
+
+ aesni_cleanup ();
+ aesni_cleanup_2_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 ();
+}
+
+
+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[16] __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" );
+
+ 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" );
+
+ 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/comm/third_party/libgcrypt/cipher/rijndael-amd64.S b/comm/third_party/libgcrypt/cipher/rijndael-amd64.S
new file mode 100644
index 0000000000..3dcaa856b7
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-amd64.S
@@ -0,0 +1,477 @@
+/* rinjdael-amd64.S - AMD64 assembly implementation of AES cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_AES)
+
+#include "asm-common-amd64.h"
+
+.text
+
+/* table macros */
+#define E0 (0)
+#define Es0 (1)
+#define Esize 4
+#define Essize 4
+
+#define D0 (0)
+#define Ds0 (4 * 256)
+#define Dsize 4
+#define Dssize 1
+
+/* register macros */
+#define CTX %rdi
+#define RTAB %r12
+
+#define RA %rax
+#define RB %rbx
+#define RC %rcx
+#define RD %rdx
+
+#define RAd %eax
+#define RBd %ebx
+#define RCd %ecx
+#define RDd %edx
+
+#define RAbl %al
+#define RBbl %bl
+#define RCbl %cl
+#define RDbl %dl
+
+#define RAbh %ah
+#define RBbh %bh
+#define RCbh %ch
+#define RDbh %dh
+
+#define RNA %r8
+#define RNB %r9
+#define RNC %r10
+#define RND %r11
+
+#define RNAd %r8d
+#define RNBd %r9d
+#define RNCd %r10d
+#define RNDd %r11d
+
+#define RT0 %rbp
+#define RT1 %rsi
+
+#define RT0d %ebp
+#define RT1d %esi
+
+/* helper macros */
+#define do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
+ movzbl source ## bl, t0 ## d; \
+ movzbl source ## bh, t1 ## d; \
+ op ## l table1(RTAB,t0,tablemul), dest1 ## d; \
+ op ## l table2(RTAB,t1,tablemul), dest2 ## d;
+
+#define do16bit_shr(shf, op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
+ movzbl source ## bl, t0 ## d; \
+ movzbl source ## bh, t1 ## d; \
+ shrl $(shf), source ## d; \
+ op ## l table1(RTAB,t0,tablemul), dest1 ## d; \
+ op ## l table2(RTAB,t1,tablemul), dest2 ## d;
+
+#define last_do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
+ movzbl source ## bl, t0 ## d; \
+ movzbl source ## bh, t1 ## d; \
+ movzbl table1(RTAB,t0,tablemul), t0 ## d; \
+ movzbl table2(RTAB,t1,tablemul), t1 ## d; \
+ op ## l t0 ## d, dest1 ## d; \
+ op ## l t1 ## d, dest2 ## d;
+
+#define last_do16bit_shr(shf, op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
+ movzbl source ## bl, t0 ## d; \
+ movzbl source ## bh, t1 ## d; \
+ shrl $(shf), source ## d; \
+ movzbl table1(RTAB,t0,tablemul), t0 ## d; \
+ movzbl table2(RTAB,t1,tablemul), t1 ## d; \
+ op ## l t0 ## d, dest1 ## d; \
+ op ## l t1 ## d, dest2 ## d;
+
+/***********************************************************************
+ * AMD64 assembly implementation of the AES cipher
+ ***********************************************************************/
+#define addroundkey(round, ra, rb, rc, rd) \
+ xorl (((round) * 16) + 0 * 4)(CTX), ra ## d; \
+ xorl (((round) * 16) + 1 * 4)(CTX), rb ## d; \
+ xorl (((round) * 16) + 2 * 4)(CTX), rc ## d; \
+ xorl (((round) * 16) + 3 * 4)(CTX), rd ## d;
+
+#define do_encround(next_r) \
+ do16bit_shr(16, mov, RA, Esize, E0, RNA, E0, RND, RT0, RT1); \
+ do16bit( mov, RA, Esize, E0, RNC, E0, RNB, RT0, RT1); \
+ movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+ roll $8, RNDd; \
+ xorl RNAd, RAd; \
+ roll $8, RNCd; \
+ roll $8, RNBd; \
+ roll $8, RAd; \
+ \
+ do16bit_shr(16, xor, RD, Esize, E0, RND, E0, RNC, RT0, RT1); \
+ do16bit( xor, RD, Esize, E0, RNB, E0, RA, RT0, RT1); \
+ movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+ roll $8, RNCd; \
+ xorl RNDd, RDd; \
+ roll $8, RNBd; \
+ roll $8, RAd; \
+ roll $8, RDd; \
+ \
+ do16bit_shr(16, xor, RC, Esize, E0, RNC, E0, RNB, RT0, RT1); \
+ do16bit( xor, RC, Esize, E0, RA, E0, RD, RT0, RT1); \
+ movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+ roll $8, RNBd; \
+ xorl RNCd, RCd; \
+ roll $8, RAd; \
+ roll $8, RDd; \
+ roll $8, RCd; \
+ \
+ do16bit_shr(16, xor, RB, Esize, E0, RNB, E0, RA, RT0, RT1); \
+ do16bit( xor, RB, Esize, E0, RD, E0, RC, RT0, RT1); \
+ movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+ roll $8, RAd; \
+ xorl RNBd, RBd; \
+ roll $16, RDd; \
+ roll $24, RCd;
+
+#define do_lastencround(next_r) \
+ do16bit_shr(16, movzb, RA, Essize, Es0, RNA, Es0, RND, RT0, RT1); \
+ do16bit( movzb, RA, Essize, Es0, RNC, Es0, RNB, RT0, RT1); \
+ movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+ roll $8, RNDd; \
+ xorl RNAd, RAd; \
+ roll $8, RNCd; \
+ roll $8, RNBd; \
+ roll $8, RAd; \
+ \
+ last_do16bit_shr(16, xor, RD, Essize, Es0, RND, Es0, RNC, RT0, RT1); \
+ last_do16bit( xor, RD, Essize, Es0, RNB, Es0, RA, RT0, RT1); \
+ movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+ roll $8, RNCd; \
+ xorl RNDd, RDd; \
+ roll $8, RNBd; \
+ roll $8, RAd; \
+ roll $8, RDd; \
+ \
+ last_do16bit_shr(16, xor, RC, Essize, Es0, RNC, Es0, RNB, RT0, RT1); \
+ last_do16bit( xor, RC, Essize, Es0, RA, Es0, RD, RT0, RT1); \
+ movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+ roll $8, RNBd; \
+ xorl RNCd, RCd; \
+ roll $8, RAd; \
+ roll $8, RDd; \
+ roll $8, RCd; \
+ \
+ last_do16bit_shr(16, xor, RB, Essize, Es0, RNB, Es0, RA, RT0, RT1); \
+ last_do16bit( xor, RB, Essize, Es0, RD, Es0, RC, RT0, RT1); \
+ movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+ roll $8, RAd; \
+ xorl RNBd, RBd; \
+ roll $16, RDd; \
+ roll $24, RCd;
+
+#define firstencround(round) \
+ addroundkey(round, RA, RB, RC, RD); \
+ do_encround((round) + 1);
+
+#define encround(round) \
+ do_encround((round) + 1);
+
+#define lastencround(round) \
+ do_lastencround((round) + 1);
+
+.align 8
+.globl _gcry_aes_amd64_encrypt_block
+ELF(.type _gcry_aes_amd64_encrypt_block,@function;)
+
+_gcry_aes_amd64_encrypt_block:
+ /* input:
+ * %rdi: keysched, CTX
+ * %rsi: dst
+ * %rdx: src
+ * %ecx: number of rounds.. 10, 12 or 14
+ * %r8: encryption tables
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_5
+
+ subq $(5 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(5 * 8);
+ movq %rsi, (0 * 8)(%rsp);
+ movl %ecx, (1 * 8)(%rsp);
+ movq %rbp, (2 * 8)(%rsp);
+ movq %rbx, (3 * 8)(%rsp);
+ movq %r12, (4 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 2 * 8);
+ CFI_REL_OFFSET(%rbx, 3 * 8);
+ CFI_REL_OFFSET(%r12, 4 * 8);
+
+ leaq (%r8), RTAB;
+
+ /* read input block */
+ movl 0 * 4(%rdx), RAd;
+ movl 1 * 4(%rdx), RBd;
+ movl 2 * 4(%rdx), RCd;
+ movl 3 * 4(%rdx), RDd;
+
+ firstencround(0);
+ encround(1);
+ encround(2);
+ encround(3);
+ encround(4);
+ encround(5);
+ encround(6);
+ encround(7);
+ encround(8);
+ cmpl $12, (1 * 8)(%rsp);
+ jnb .Lenc_not_128;
+ lastencround(9);
+
+.align 4
+.Lenc_done:
+ /* write output block */
+ movq (0 * 8)(%rsp), %rsi;
+ movl RAd, 0 * 4(%rsi);
+ movl RBd, 1 * 4(%rsi);
+ movl RCd, 2 * 4(%rsi);
+ movl RDd, 3 * 4(%rsi);
+
+ CFI_REMEMBER_STATE();
+
+ movq (4 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %rbp;
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%rbp);
+ addq $(5 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-5 * 8);
+
+ movl $(6 * 8), %eax;
+
+ EXIT_SYSV_FUNC
+ ret;
+
+ CFI_RESTORE_STATE();
+.align 4
+.Lenc_not_128:
+ je .Lenc_192
+
+ encround(9);
+ encround(10);
+ encround(11);
+ encround(12);
+ lastencround(13);
+
+ jmp .Lenc_done;
+
+.align 4
+.Lenc_192:
+ encround(9);
+ encround(10);
+ lastencround(11);
+
+ jmp .Lenc_done;
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block;)
+
+#define do_decround(next_r) \
+ do16bit_shr(16, mov, RA, Dsize, D0, RNA, D0, RNB, RT0, RT1); \
+ do16bit( mov, RA, Dsize, D0, RNC, D0, RND, RT0, RT1); \
+ movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+ roll $8, RNBd; \
+ xorl RNAd, RAd; \
+ roll $8, RNCd; \
+ roll $8, RNDd; \
+ roll $8, RAd; \
+ \
+ do16bit_shr(16, xor, RB, Dsize, D0, RNB, D0, RNC, RT0, RT1); \
+ do16bit( xor, RB, Dsize, D0, RND, D0, RA, RT0, RT1); \
+ movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+ roll $8, RNCd; \
+ xorl RNBd, RBd; \
+ roll $8, RNDd; \
+ roll $8, RAd; \
+ roll $8, RBd; \
+ \
+ do16bit_shr(16, xor, RC, Dsize, D0, RNC, D0, RND, RT0, RT1); \
+ do16bit( xor, RC, Dsize, D0, RA, D0, RB, RT0, RT1); \
+ movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+ roll $8, RNDd; \
+ xorl RNCd, RCd; \
+ roll $8, RAd; \
+ roll $8, RBd; \
+ roll $8, RCd; \
+ \
+ do16bit_shr(16, xor, RD, Dsize, D0, RND, D0, RA, RT0, RT1); \
+ do16bit( xor, RD, Dsize, D0, RB, D0, RC, RT0, RT1); \
+ movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+ roll $8, RAd; \
+ xorl RNDd, RDd; \
+ roll $16, RBd; \
+ roll $24, RCd;
+
+#define do_lastdecround(next_r) \
+ do16bit_shr(16, movzb, RA, Dssize, Ds0, RNA, Ds0, RNB, RT0, RT1); \
+ do16bit( movzb, RA, Dssize, Ds0, RNC, Ds0, RND, RT0, RT1); \
+ movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+ roll $8, RNBd; \
+ xorl RNAd, RAd; \
+ roll $8, RNCd; \
+ roll $8, RNDd; \
+ roll $8, RAd; \
+ \
+ last_do16bit_shr(16, xor, RB, Dssize, Ds0, RNB, Ds0, RNC, RT0, RT1); \
+ last_do16bit( xor, RB, Dssize, Ds0, RND, Ds0, RA, RT0, RT1); \
+ movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+ roll $8, RNCd; \
+ xorl RNBd, RBd; \
+ roll $8, RNDd; \
+ roll $8, RAd; \
+ roll $8, RBd; \
+ \
+ last_do16bit_shr(16, xor, RC, Dssize, Ds0, RNC, Ds0, RND, RT0, RT1); \
+ last_do16bit( xor, RC, Dssize, Ds0, RA, Ds0, RB, RT0, RT1); \
+ movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+ roll $8, RNDd; \
+ xorl RNCd, RCd; \
+ roll $8, RAd; \
+ roll $8, RBd; \
+ roll $8, RCd; \
+ \
+ last_do16bit_shr(16, xor, RD, Dssize, Ds0, RND, Ds0, RA, RT0, RT1); \
+ last_do16bit( xor, RD, Dssize, Ds0, RB, Ds0, RC, RT0, RT1); \
+ movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+ roll $8, RAd; \
+ xorl RNDd, RDd; \
+ roll $16, RBd; \
+ roll $24, RCd;
+
+#define firstdecround(round) \
+ addroundkey((round + 1), RA, RB, RC, RD); \
+ do_decround(round);
+
+#define decround(round) \
+ do_decround(round);
+
+#define lastdecround(round) \
+ do_lastdecround(round);
+
+.align 8
+.globl _gcry_aes_amd64_decrypt_block
+ELF(.type _gcry_aes_amd64_decrypt_block,@function;)
+
+_gcry_aes_amd64_decrypt_block:
+ /* input:
+ * %rdi: keysched, CTX
+ * %rsi: dst
+ * %rdx: src
+ * %ecx: number of rounds.. 10, 12 or 14
+ * %r8: decryption tables
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_5
+
+ subq $(5 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(5 * 8);
+ movq %rsi, (0 * 8)(%rsp);
+ movl %ecx, (1 * 8)(%rsp);
+ movq %rbp, (2 * 8)(%rsp);
+ movq %rbx, (3 * 8)(%rsp);
+ movq %r12, (4 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 2 * 8);
+ CFI_REL_OFFSET(%rbx, 3 * 8);
+ CFI_REL_OFFSET(%r12, 4 * 8);
+
+ leaq (%r8), RTAB;
+
+ /* read input block */
+ movl 0 * 4(%rdx), RAd;
+ movl 1 * 4(%rdx), RBd;
+ movl 2 * 4(%rdx), RCd;
+ movl 3 * 4(%rdx), RDd;
+
+ cmpl $12, (1 * 8)(%rsp);
+ jnb .Ldec_256;
+
+ firstdecround(9);
+.align 4
+.Ldec_tail:
+ decround(8);
+ decround(7);
+ decround(6);
+ decround(5);
+ decround(4);
+ decround(3);
+ decround(2);
+ decround(1);
+ lastdecround(0);
+
+ /* write output block */
+ movq (0 * 8)(%rsp), %rsi;
+ movl RAd, 0 * 4(%rsi);
+ movl RBd, 1 * 4(%rsi);
+ movl RCd, 2 * 4(%rsi);
+ movl RDd, 3 * 4(%rsi);
+
+ CFI_REMEMBER_STATE();
+
+ movq (4 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %rbp;
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%rbp);
+ addq $(5 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-5 * 8);
+
+ movl $(6 * 8), %eax;
+
+ EXIT_SYSV_FUNC
+ ret;
+
+ CFI_RESTORE_STATE();
+.align 4
+.Ldec_256:
+ je .Ldec_192;
+
+ firstdecround(13);
+ decround(12);
+ decround(11);
+ decround(10);
+ decround(9);
+
+ jmp .Ldec_tail;
+
+.align 4
+.Ldec_192:
+ firstdecround(11);
+ decround(10);
+ decround(9);
+
+ jmp .Ldec_tail;
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block;)
+
+#endif /*USE_AES*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-arm.S b/comm/third_party/libgcrypt/cipher/rijndael-arm.S
new file mode 100644
index 0000000000..e680c817b2
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-arm.S
@@ -0,0 +1,581 @@
+/* rijndael-arm.S - ARM assembly implementation of AES cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(__ARMEL__)
+#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+.text
+
+.syntax unified
+.arm
+
+/* register macros */
+#define CTX %r0
+#define RTAB %lr
+#define RMASK %ip
+
+#define RA %r4
+#define RB %r5
+#define RC %r6
+#define RD %r7
+
+#define RNA %r8
+#define RNB %r9
+#define RNC %r10
+#define RND %r11
+
+#define RT0 %r1
+#define RT1 %r2
+#define RT2 %r3
+
+/* helper macros */
+#define ldr_unaligned_le(rout, rsrc, offs, rtmp) \
+ ldrb rout, [rsrc, #((offs) + 0)]; \
+ ldrb rtmp, [rsrc, #((offs) + 1)]; \
+ orr rout, rout, rtmp, lsl #8; \
+ ldrb rtmp, [rsrc, #((offs) + 2)]; \
+ orr rout, rout, rtmp, lsl #16; \
+ ldrb rtmp, [rsrc, #((offs) + 3)]; \
+ orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_le(rin, rdst, offs, rtmp0, rtmp1) \
+ mov rtmp0, rin, lsr #8; \
+ strb rin, [rdst, #((offs) + 0)]; \
+ mov rtmp1, rin, lsr #16; \
+ strb rtmp0, [rdst, #((offs) + 1)]; \
+ mov rtmp0, rin, lsr #24; \
+ strb rtmp1, [rdst, #((offs) + 2)]; \
+ strb rtmp0, [rdst, #((offs) + 3)];
+
+/***********************************************************************
+ * ARM assembly implementation of the AES cipher
+ ***********************************************************************/
+#define preload_first_key(round, ra) \
+ ldr ra, [CTX, #(((round) * 16) + 0 * 4)];
+
+#define dummy(round, ra) /* nothing */
+
+#define addroundkey(ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ ldm CTX, {rna, rnb, rnc, rnd}; \
+ eor ra, rna; \
+ eor rb, rnb; \
+ eor rc, rnc; \
+ preload_key(1, rna); \
+ eor rd, rnd;
+
+#define do_encround(next_r, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ ldr rnb, [CTX, #(((next_r) * 16) + 1 * 4)]; \
+ \
+ and RT0, RMASK, ra, lsl#2; \
+ ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \
+ and RT1, RMASK, ra, lsr#(8 - 2); \
+ ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \
+ and RT2, RMASK, ra, lsr#(16 - 2); \
+ ldr RT0, [RTAB, RT0]; \
+ and ra, RMASK, ra, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, RT1]; \
+ eor rna, rna, RT0; \
+ ldr RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rd, lsl#2; \
+ ldr ra, [RTAB, ra]; \
+ \
+ eor rnd, rnd, RT1, ror #24; \
+ and RT1, RMASK, rd, lsr#(8 - 2); \
+ eor rnc, rnc, RT2, ror #16; \
+ and RT2, RMASK, rd, lsr#(16 - 2); \
+ eor rnb, rnb, ra, ror #8; \
+ ldr RT0, [RTAB, RT0]; \
+ and rd, RMASK, rd, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, RT1]; \
+ eor rnd, rnd, RT0; \
+ ldr RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rc, lsl#2; \
+ ldr rd, [RTAB, rd]; \
+ \
+ eor rnc, rnc, RT1, ror #24; \
+ and RT1, RMASK, rc, lsr#(8 - 2); \
+ eor rnb, rnb, RT2, ror #16; \
+ and RT2, RMASK, rc, lsr#(16 - 2); \
+ eor rna, rna, rd, ror #8; \
+ ldr RT0, [RTAB, RT0]; \
+ and rc, RMASK, rc, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, RT1]; \
+ eor rnc, rnc, RT0; \
+ ldr RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rb, lsl#2; \
+ ldr rc, [RTAB, rc]; \
+ \
+ eor rnb, rnb, RT1, ror #24; \
+ and RT1, RMASK, rb, lsr#(8 - 2); \
+ eor rna, rna, RT2, ror #16; \
+ and RT2, RMASK, rb, lsr#(16 - 2); \
+ eor rnd, rnd, rc, ror #8; \
+ ldr RT0, [RTAB, RT0]; \
+ and rb, RMASK, rb, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, RT1]; \
+ eor rnb, rnb, RT0; \
+ ldr RT2, [RTAB, RT2]; \
+ eor rna, rna, RT1, ror #24; \
+ ldr rb, [RTAB, rb]; \
+ \
+ eor rnd, rnd, RT2, ror #16; \
+ preload_key((next_r) + 1, ra); \
+ eor rnc, rnc, rb, ror #8;
+
+#define do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ and RT0, RMASK, ra, lsl#2; \
+ and RT1, RMASK, ra, lsr#(8 - 2); \
+ and RT2, RMASK, ra, lsr#(16 - 2); \
+ ldrb rna, [RTAB, RT0]; \
+ and ra, RMASK, ra, lsr#(24 - 2); \
+ ldrb rnd, [RTAB, RT1]; \
+ and RT0, RMASK, rd, lsl#2; \
+ ldrb rnc, [RTAB, RT2]; \
+ mov rnd, rnd, ror #24; \
+ ldrb rnb, [RTAB, ra]; \
+ and RT1, RMASK, rd, lsr#(8 - 2); \
+ mov rnc, rnc, ror #16; \
+ and RT2, RMASK, rd, lsr#(16 - 2); \
+ mov rnb, rnb, ror #8; \
+ ldrb RT0, [RTAB, RT0]; \
+ and rd, RMASK, rd, lsr#(24 - 2); \
+ ldrb RT1, [RTAB, RT1]; \
+ \
+ orr rnd, rnd, RT0; \
+ ldrb RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rc, lsl#2; \
+ ldrb rd, [RTAB, rd]; \
+ orr rnc, rnc, RT1, ror #24; \
+ and RT1, RMASK, rc, lsr#(8 - 2); \
+ orr rnb, rnb, RT2, ror #16; \
+ and RT2, RMASK, rc, lsr#(16 - 2); \
+ orr rna, rna, rd, ror #8; \
+ ldrb RT0, [RTAB, RT0]; \
+ and rc, RMASK, rc, lsr#(24 - 2); \
+ ldrb RT1, [RTAB, RT1]; \
+ \
+ orr rnc, rnc, RT0; \
+ ldrb RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rb, lsl#2; \
+ ldrb rc, [RTAB, rc]; \
+ orr rnb, rnb, RT1, ror #24; \
+ and RT1, RMASK, rb, lsr#(8 - 2); \
+ orr rna, rna, RT2, ror #16; \
+ ldrb RT0, [RTAB, RT0]; \
+ and RT2, RMASK, rb, lsr#(16 - 2); \
+ ldrb RT1, [RTAB, RT1]; \
+ orr rnd, rnd, rc, ror #8; \
+ ldrb RT2, [RTAB, RT2]; \
+ and rb, RMASK, rb, lsr#(24 - 2); \
+ ldrb rb, [RTAB, rb]; \
+ \
+ orr rnb, rnb, RT0; \
+ orr rna, rna, RT1, ror #24; \
+ orr rnd, rnd, RT2, ror #16; \
+ orr rnc, rnc, rb, ror #8;
+
+#define firstencround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ addroundkey(ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key); \
+ do_encround((round) + 1, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key);
+
+#define encround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ do_encround((round) + 1, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key);
+
+#define lastencround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ add CTX, #(((round) + 1) * 16); \
+ add RTAB, #1; \
+ do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+ addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy);
+
+.align 3
+.globl _gcry_aes_arm_encrypt_block
+.type _gcry_aes_arm_encrypt_block,%function;
+
+_gcry_aes_arm_encrypt_block:
+ /* input:
+ * %r0: keysched, CTX
+ * %r1: dst
+ * %r2: src
+ * %r3: number of rounds.. 10, 12 or 14
+ * %st+0: encryption table
+ */
+ push {%r4-%r11, %ip, %lr};
+
+ /* read input block */
+
+ /* test if src is unaligned */
+ tst %r2, #3;
+ beq 1f;
+
+ /* unaligned load */
+ ldr_unaligned_le(RA, %r2, 0, RNA);
+ ldr_unaligned_le(RB, %r2, 4, RNB);
+ ldr_unaligned_le(RC, %r2, 8, RNA);
+ ldr_unaligned_le(RD, %r2, 12, RNB);
+ b 2f;
+.ltorg
+1:
+ /* aligned load */
+ ldm %r2, {RA, RB, RC, RD};
+#ifndef __ARMEL__
+ rev RA, RA;
+ rev RB, RB;
+ rev RC, RC;
+ rev RD, RD;
+#endif
+2:
+ ldr RTAB, [%sp, #40];
+ sub %sp, #16;
+
+ str %r1, [%sp, #4]; /* dst */
+ mov RMASK, #0xff;
+ str %r3, [%sp, #8]; /* nrounds */
+ mov RMASK, RMASK, lsl#2; /* byte mask */
+
+ firstencround(0, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+ encround(1, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(2, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(3, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(4, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(5, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(6, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(7, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+
+ ldr RT0, [%sp, #8]; /* nrounds */
+ cmp RT0, #12;
+ bge .Lenc_not_128;
+
+ encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+ lastencround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+.Lenc_done:
+ ldr RT0, [%sp, #4]; /* dst */
+ add %sp, #16;
+
+ /* store output block */
+
+ /* test if dst is unaligned */
+ tst RT0, #3;
+ beq 1f;
+
+ /* unaligned store */
+ str_unaligned_le(RA, RT0, 0, RNA, RNB);
+ str_unaligned_le(RB, RT0, 4, RNA, RNB);
+ str_unaligned_le(RC, RT0, 8, RNA, RNB);
+ str_unaligned_le(RD, RT0, 12, RNA, RNB);
+ b 2f;
+.ltorg
+1:
+ /* aligned store */
+#ifndef __ARMEL__
+ rev RA, RA;
+ rev RB, RB;
+ rev RC, RC;
+ rev RD, RD;
+#endif
+ /* write output block */
+ stm RT0, {RA, RB, RC, RD};
+2:
+
+ mov r0, #(10 * 4);
+ pop {%r4-%r11, %ip, %pc};
+
+.ltorg
+.Lenc_not_128:
+ beq .Lenc_192
+
+ encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(10, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(11, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(12, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+ lastencround(13, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+ b .Lenc_done;
+
+.ltorg
+.Lenc_192:
+ encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ encround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ encround(10, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+ lastencround(11, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+ b .Lenc_done;
+.size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block;
+
+#define addroundkey_dec(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ ldr rna, [CTX, #(((round) * 16) + 0 * 4)]; \
+ ldr rnb, [CTX, #(((round) * 16) + 1 * 4)]; \
+ eor ra, rna; \
+ ldr rnc, [CTX, #(((round) * 16) + 2 * 4)]; \
+ eor rb, rnb; \
+ ldr rnd, [CTX, #(((round) * 16) + 3 * 4)]; \
+ eor rc, rnc; \
+ preload_first_key((round) - 1, rna); \
+ eor rd, rnd;
+
+#define do_decround(next_r, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ ldr rnb, [CTX, #(((next_r) * 16) + 1 * 4)]; \
+ \
+ and RT0, RMASK, ra, lsl#2; \
+ ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \
+ and RT1, RMASK, ra, lsr#(8 - 2); \
+ ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \
+ and RT2, RMASK, ra, lsr#(16 - 2); \
+ ldr RT0, [RTAB, RT0]; \
+ and ra, RMASK, ra, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, RT1]; \
+ eor rna, rna, RT0; \
+ ldr RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rb, lsl#2; \
+ ldr ra, [RTAB, ra]; \
+ \
+ eor rnb, rnb, RT1, ror #24; \
+ and RT1, RMASK, rb, lsr#(8 - 2); \
+ eor rnc, rnc, RT2, ror #16; \
+ and RT2, RMASK, rb, lsr#(16 - 2); \
+ eor rnd, rnd, ra, ror #8; \
+ ldr RT0, [RTAB, RT0]; \
+ and rb, RMASK, rb, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, RT1]; \
+ eor rnb, rnb, RT0; \
+ ldr RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rc, lsl#2; \
+ ldr rb, [RTAB, rb]; \
+ \
+ eor rnc, rnc, RT1, ror #24; \
+ and RT1, RMASK, rc, lsr#(8 - 2); \
+ eor rnd, rnd, RT2, ror #16; \
+ and RT2, RMASK, rc, lsr#(16 - 2); \
+ eor rna, rna, rb, ror #8; \
+ ldr RT0, [RTAB, RT0]; \
+ and rc, RMASK, rc, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, RT1]; \
+ eor rnc, rnc, RT0; \
+ ldr RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rd, lsl#2; \
+ ldr rc, [RTAB, rc]; \
+ \
+ eor rnd, rnd, RT1, ror #24; \
+ and RT1, RMASK, rd, lsr#(8 - 2); \
+ eor rna, rna, RT2, ror #16; \
+ and RT2, RMASK, rd, lsr#(16 - 2); \
+ eor rnb, rnb, rc, ror #8; \
+ ldr RT0, [RTAB, RT0]; \
+ and rd, RMASK, rd, lsr#(24 - 2); \
+ \
+ ldr RT1, [RTAB, RT1]; \
+ eor rnd, rnd, RT0; \
+ ldr RT2, [RTAB, RT2]; \
+ eor rna, rna, RT1, ror #24; \
+ ldr rd, [RTAB, rd]; \
+ \
+ eor rnb, rnb, RT2, ror #16; \
+ preload_key((next_r) - 1, ra); \
+ eor rnc, rnc, rd, ror #8;
+
+#define do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ and RT0, RMASK, ra; \
+ and RT1, RMASK, ra, lsr#8; \
+ and RT2, RMASK, ra, lsr#16; \
+ ldrb rna, [RTAB, RT0]; \
+ mov ra, ra, lsr#24; \
+ ldrb rnb, [RTAB, RT1]; \
+ and RT0, RMASK, rb; \
+ ldrb rnc, [RTAB, RT2]; \
+ mov rnb, rnb, ror #24; \
+ ldrb rnd, [RTAB, ra]; \
+ and RT1, RMASK, rb, lsr#8; \
+ mov rnc, rnc, ror #16; \
+ and RT2, RMASK, rb, lsr#16; \
+ mov rnd, rnd, ror #8; \
+ ldrb RT0, [RTAB, RT0]; \
+ mov rb, rb, lsr#24; \
+ ldrb RT1, [RTAB, RT1]; \
+ \
+ orr rnb, rnb, RT0; \
+ ldrb RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rc; \
+ ldrb rb, [RTAB, rb]; \
+ orr rnc, rnc, RT1, ror #24; \
+ and RT1, RMASK, rc, lsr#8; \
+ orr rnd, rnd, RT2, ror #16; \
+ and RT2, RMASK, rc, lsr#16; \
+ orr rna, rna, rb, ror #8; \
+ ldrb RT0, [RTAB, RT0]; \
+ mov rc, rc, lsr#24; \
+ ldrb RT1, [RTAB, RT1]; \
+ \
+ orr rnc, rnc, RT0; \
+ ldrb RT2, [RTAB, RT2]; \
+ and RT0, RMASK, rd; \
+ ldrb rc, [RTAB, rc]; \
+ orr rnd, rnd, RT1, ror #24; \
+ and RT1, RMASK, rd, lsr#8; \
+ orr rna, rna, RT2, ror #16; \
+ ldrb RT0, [RTAB, RT0]; \
+ and RT2, RMASK, rd, lsr#16; \
+ ldrb RT1, [RTAB, RT1]; \
+ orr rnb, rnb, rc, ror #8; \
+ ldrb RT2, [RTAB, RT2]; \
+ mov rd, rd, lsr#24; \
+ ldrb rd, [RTAB, rd]; \
+ \
+ orr rnd, rnd, RT0; \
+ orr rna, rna, RT1, ror #24; \
+ orr rnb, rnb, RT2, ror #16; \
+ orr rnc, rnc, rd, ror #8;
+
+#define firstdecround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ addroundkey_dec(((round) + 1), ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+ do_decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key);
+
+#define decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+ do_decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key);
+
+#define set_last_round_rmask(_, __) \
+ mov RMASK, #0xff;
+
+#define lastdecround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+ add RTAB, #(4 * 256); \
+ do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+ addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy);
+
+.align 3
+.globl _gcry_aes_arm_decrypt_block
+.type _gcry_aes_arm_decrypt_block,%function;
+
+_gcry_aes_arm_decrypt_block:
+ /* input:
+ * %r0: keysched, CTX
+ * %r1: dst
+ * %r2: src
+ * %r3: number of rounds.. 10, 12 or 14
+ * %st+0: decryption table
+ */
+ push {%r4-%r11, %ip, %lr};
+
+ /* read input block */
+
+ /* test if src is unaligned */
+ tst %r2, #3;
+ beq 1f;
+
+ /* unaligned load */
+ ldr_unaligned_le(RA, %r2, 0, RNA);
+ ldr_unaligned_le(RB, %r2, 4, RNB);
+ ldr_unaligned_le(RC, %r2, 8, RNA);
+ ldr_unaligned_le(RD, %r2, 12, RNB);
+ b 2f;
+.ltorg
+1:
+ /* aligned load */
+ ldm %r2, {RA, RB, RC, RD};
+#ifndef __ARMEL__
+ rev RA, RA;
+ rev RB, RB;
+ rev RC, RC;
+ rev RD, RD;
+#endif
+2:
+ ldr RTAB, [%sp, #40];
+ sub %sp, #16;
+
+ mov RMASK, #0xff;
+ str %r1, [%sp, #4]; /* dst */
+ mov RMASK, RMASK, lsl#2; /* byte mask */
+
+ cmp %r3, #12;
+ bge .Ldec_256;
+
+ firstdecround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+.Ldec_tail:
+ decround(8, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(7, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ decround(6, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(5, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ decround(4, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(3, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ decround(2, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(1, RA, RB, RC, RD, RNA, RNB, RNC, RND, set_last_round_rmask);
+ lastdecround(0, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+ ldr RT0, [%sp, #4]; /* dst */
+ add %sp, #16;
+
+ /* store output block */
+
+ /* test if dst is unaligned */
+ tst RT0, #3;
+ beq 1f;
+
+ /* unaligned store */
+ str_unaligned_le(RA, RT0, 0, RNA, RNB);
+ str_unaligned_le(RB, RT0, 4, RNA, RNB);
+ str_unaligned_le(RC, RT0, 8, RNA, RNB);
+ str_unaligned_le(RD, RT0, 12, RNA, RNB);
+ b 2f;
+.ltorg
+1:
+ /* aligned store */
+#ifndef __ARMEL__
+ rev RA, RA;
+ rev RB, RB;
+ rev RC, RC;
+ rev RD, RD;
+#endif
+ /* write output block */
+ stm RT0, {RA, RB, RC, RD};
+2:
+ mov r0, #(10 * 4);
+ pop {%r4-%r11, %ip, %pc};
+
+.ltorg
+.Ldec_256:
+ beq .Ldec_192;
+
+ firstdecround(13, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+ decround(12, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(11, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+ decround(10, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+
+ b .Ldec_tail;
+
+.ltorg
+.Ldec_192:
+ firstdecround(11, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+ decround(10, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+ decround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+
+ b .Ldec_tail;
+.size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block;
+
+#endif /*HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS*/
+#endif /*__ARMEL__ */
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-armv8-aarch32-ce.S b/comm/third_party/libgcrypt/cipher/rijndael-armv8-aarch32-ce.S
new file mode 100644
index 0000000000..66440bd4eb
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-armv8-aarch32-ce.S
@@ -0,0 +1,1867 @@
+/* rijndael-armv8-aarch32-ce.S - ARMv8/CE accelerated AES
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO)
+
+.syntax unified
+.arch armv8-a
+.fpu crypto-neon-fp-armv8
+.arm
+
+.text
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+
+/* AES macros */
+
+#define aes_preload_keys(keysched, rekeysched) \
+ vldmia keysched!, {q5-q7}; \
+ mov rekeysched, keysched; \
+ vldmialo keysched!, {q8-q15}; /* 128-bit */ \
+ addeq keysched, #(2*16); \
+ vldmiaeq keysched!, {q10-q15}; /* 192-bit */ \
+ addhi keysched, #(4*16); \
+ vldmiahi keysched!, {q12-q15}; /* 256-bit */ \
+
+#define do_aes_one128(ed, mcimc, qo, qb) \
+ aes##ed.8 qb, q5; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q6; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q7; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q8; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q9; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q10; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q11; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q12; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q13; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q14; \
+ veor qo, qb, q15;
+
+#define do_aes_one128re(ed, mcimc, qo, qb, keysched, rekeysched) \
+ vldm rekeysched, {q8-q9}; \
+ do_aes_one128(ed, mcimc, qo, qb);
+
+#define do_aes_one192(ed, mcimc, qo, qb, keysched, rekeysched) \
+ vldm rekeysched!, {q8}; \
+ aes##ed.8 qb, q5; \
+ aes##mcimc.8 qb, qb; \
+ vldm rekeysched, {q9}; \
+ aes##ed.8 qb, q6; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q7; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q8; \
+ aes##mcimc.8 qb, qb; \
+ vldmia keysched!, {q8}; \
+ aes##ed.8 qb, q9; \
+ aes##mcimc.8 qb, qb; \
+ sub rekeysched, #(1*16); \
+ aes##ed.8 qb, q10; \
+ aes##mcimc.8 qb, qb; \
+ vldm keysched, {q9}; \
+ aes##ed.8 qb, q11; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q12; \
+ aes##mcimc.8 qb, qb; \
+ sub keysched, #16; \
+ aes##ed.8 qb, q13; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q14; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q15; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q8; \
+ veor qo, qb, q9; \
+
+#define do_aes_one256(ed, mcimc, qo, qb, keysched, rekeysched) \
+ vldmia rekeysched!, {q8}; \
+ aes##ed.8 qb, q5; \
+ aes##mcimc.8 qb, qb; \
+ vldmia rekeysched!, {q9}; \
+ aes##ed.8 qb, q6; \
+ aes##mcimc.8 qb, qb; \
+ vldmia rekeysched!, {q10}; \
+ aes##ed.8 qb, q7; \
+ aes##mcimc.8 qb, qb; \
+ vldm rekeysched, {q11}; \
+ aes##ed.8 qb, q8; \
+ aes##mcimc.8 qb, qb; \
+ vldmia keysched!, {q8}; \
+ aes##ed.8 qb, q9; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q10; \
+ aes##mcimc.8 qb, qb; \
+ vldmia keysched!, {q9}; \
+ aes##ed.8 qb, q11; \
+ aes##mcimc.8 qb, qb; \
+ sub rekeysched, #(3*16); \
+ aes##ed.8 qb, q12; \
+ aes##mcimc.8 qb, qb; \
+ vldmia keysched!, {q10}; \
+ aes##ed.8 qb, q13; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q14; \
+ aes##mcimc.8 qb, qb; \
+ vldm keysched, {q11}; \
+ aes##ed.8 qb, q15; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q8; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q9; \
+ aes##mcimc.8 qb, qb; \
+ aes##ed.8 qb, q10; \
+ veor qo, qb, q11; \
+ sub keysched, #(3*16); \
+
+#define aes_round_4(ed, mcimc, b0, b1, b2, b3, key) \
+ aes##ed.8 b0, key; \
+ aes##mcimc.8 b0, b0; \
+ aes##ed.8 b1, key; \
+ aes##mcimc.8 b1, b1; \
+ aes##ed.8 b2, key; \
+ aes##mcimc.8 b2, b2; \
+ aes##ed.8 b3, key; \
+ aes##mcimc.8 b3, b3;
+
+#define do_aes_4_128(ed, mcimc, b0, b1, b2, b3) \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q5); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q6); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q7); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q8); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q9); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q10); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q11); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q12); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q13); \
+ aes##ed.8 b0, q14; \
+ veor b0, b0, q15; \
+ aes##ed.8 b1, q14; \
+ veor b1, b1, q15; \
+ aes##ed.8 b2, q14; \
+ veor b2, b2, q15; \
+ aes##ed.8 b3, q14; \
+ veor b3, b3, q15;
+
+#define do_aes_4_128re(ed, mcimc, b0, b1, b2, b3, keysched, rekeysched) \
+ vldm rekeysched, {q8-q9}; \
+ do_aes_4_128(ed, mcimc, b0, b1, b2, b3);
+
+#define do_aes_4_192(ed, mcimc, b0, b1, b2, b3, keysched, rekeysched) \
+ vldm rekeysched!, {q8}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q5); \
+ vldm rekeysched, {q9}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q6); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q7); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q8); \
+ vldmia keysched!, {q8}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q9); \
+ sub rekeysched, #(1*16); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q10); \
+ vldm keysched, {q9}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q11); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q12); \
+ sub keysched, #16; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q13); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q14); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q15); \
+ aes##ed.8 b0, q8; \
+ veor b0, b0, q9; \
+ aes##ed.8 b1, q8; \
+ veor b1, b1, q9; \
+ aes##ed.8 b2, q8; \
+ veor b2, b2, q9; \
+ aes##ed.8 b3, q8; \
+ veor b3, b3, q9;
+
+#define do_aes_4_256(ed, mcimc, b0, b1, b2, b3, keysched, rekeysched) \
+ vldmia rekeysched!, {q8}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q5); \
+ vldmia rekeysched!, {q9}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q6); \
+ vldmia rekeysched!, {q10}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q7); \
+ vldm rekeysched, {q11}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q8); \
+ vldmia keysched!, {q8}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q9); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q10); \
+ vldmia keysched!, {q9}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q11); \
+ sub rekeysched, #(3*16); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q12); \
+ vldmia keysched!, {q10}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q13); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q14); \
+ vldm keysched, {q11}; \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q15); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q8); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, q9); \
+ sub keysched, #(3*16); \
+ aes##ed.8 b0, q10; \
+ veor b0, b0, q11; \
+ aes##ed.8 b1, q10; \
+ veor b1, b1, q11; \
+ aes##ed.8 b2, q10; \
+ veor b2, b2, q11; \
+ aes##ed.8 b3, q10; \
+ veor b3, b3, q11;
+
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) veor reg, reg;
+
+
+/*
+ * unsigned int _gcry_aes_enc_armv8_ce(void *keysched, byte *dst,
+ * const byte *src,
+ * unsigned int nrounds);
+ */
+.align 3
+.globl _gcry_aes_enc_armv8_ce
+.type _gcry_aes_enc_armv8_ce,%function;
+_gcry_aes_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: dst
+ * r2: src
+ * r3: nrounds
+ */
+
+ vldmia r0!, {q1-q3} /* load 3 round keys */
+
+ cmp r3, #12
+
+ vld1.8 {q0}, [r2]
+
+ bhi .Lenc1_256
+ beq .Lenc1_192
+
+.Lenc1_128:
+
+.Lenc1_tail:
+ vldmia r0, {q8-q15} /* load 8 round keys */
+
+ aese.8 q0, q1
+ aesmc.8 q0, q0
+ CLEAR_REG(q1)
+
+ aese.8 q0, q2
+ aesmc.8 q0, q0
+ CLEAR_REG(q2)
+
+ aese.8 q0, q3
+ aesmc.8 q0, q0
+ CLEAR_REG(q3)
+
+ aese.8 q0, q8
+ aesmc.8 q0, q0
+ CLEAR_REG(q8)
+
+ aese.8 q0, q9
+ aesmc.8 q0, q0
+ CLEAR_REG(q9)
+
+ aese.8 q0, q10
+ aesmc.8 q0, q0
+ CLEAR_REG(q10)
+
+ aese.8 q0, q11
+ aesmc.8 q0, q0
+ CLEAR_REG(q11)
+
+ aese.8 q0, q12
+ aesmc.8 q0, q0
+ CLEAR_REG(q12)
+
+ aese.8 q0, q13
+ aesmc.8 q0, q0
+ CLEAR_REG(q13)
+
+ aese.8 q0, q14
+ veor q0, q15
+ CLEAR_REG(q14)
+ CLEAR_REG(q15)
+
+ vst1.8 {q0}, [r1]
+ CLEAR_REG(q0)
+
+ mov r0, #0
+ bx lr
+
+.Lenc1_192:
+ aese.8 q0, q1
+ aesmc.8 q0, q0
+ vmov q1, q3
+
+ aese.8 q0, q2
+ aesmc.8 q0, q0
+ vldm r0!, {q2-q3} /* load 3 round keys */
+
+ b .Lenc1_tail
+
+.Lenc1_256:
+ vldm r0!, {q15} /* load 1 round key */
+ aese.8 q0, q1
+ aesmc.8 q0, q0
+
+ aese.8 q0, q2
+ aesmc.8 q0, q0
+
+ aese.8 q0, q3
+ aesmc.8 q0, q0
+ vldm r0!, {q1-q3} /* load 3 round keys */
+
+ aese.8 q0, q15
+ aesmc.8 q0, q0
+
+ b .Lenc1_tail
+.size _gcry_aes_enc_armv8_ce,.-_gcry_aes_enc_armv8_ce;
+
+
+/*
+ * unsigned int _gcry_aes_dec_armv8_ce(void *keysched, byte *dst,
+ * const byte *src,
+ * unsigned int nrounds);
+ */
+.align 3
+.globl _gcry_aes_dec_armv8_ce
+.type _gcry_aes_dec_armv8_ce,%function;
+_gcry_aes_dec_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: dst
+ * r2: src
+ * r3: nrounds
+ */
+
+ vldmia r0!, {q1-q3} /* load 3 round keys */
+
+ cmp r3, #12
+
+ vld1.8 {q0}, [r2]
+
+ bhi .Ldec1_256
+ beq .Ldec1_192
+
+.Ldec1_128:
+
+.Ldec1_tail:
+ vldmia r0, {q8-q15} /* load 8 round keys */
+
+ aesd.8 q0, q1
+ aesimc.8 q0, q0
+ CLEAR_REG(q1)
+
+ aesd.8 q0, q2
+ aesimc.8 q0, q0
+ CLEAR_REG(q2)
+
+ aesd.8 q0, q3
+ aesimc.8 q0, q0
+ CLEAR_REG(q3)
+
+ aesd.8 q0, q8
+ aesimc.8 q0, q0
+ CLEAR_REG(q8)
+
+ aesd.8 q0, q9
+ aesimc.8 q0, q0
+ CLEAR_REG(q9)
+
+ aesd.8 q0, q10
+ aesimc.8 q0, q0
+ CLEAR_REG(q10)
+
+ aesd.8 q0, q11
+ aesimc.8 q0, q0
+ CLEAR_REG(q11)
+
+ aesd.8 q0, q12
+ aesimc.8 q0, q0
+ CLEAR_REG(q12)
+
+ aesd.8 q0, q13
+ aesimc.8 q0, q0
+ CLEAR_REG(q13)
+
+ aesd.8 q0, q14
+ veor q0, q15
+ CLEAR_REG(q14)
+ CLEAR_REG(q15)
+
+ vst1.8 {q0}, [r1]
+ CLEAR_REG(q0)
+
+ mov r0, #0
+ bx lr
+
+.Ldec1_192:
+ aesd.8 q0, q1
+ aesimc.8 q0, q0
+ vmov q1, q3
+
+ aesd.8 q0, q2
+ aesimc.8 q0, q0
+ vldm r0!, {q2-q3} /* load 3 round keys */
+
+ b .Ldec1_tail
+
+.Ldec1_256:
+ vldm r0!, {q15} /* load 1 round key */
+ aesd.8 q0, q1
+ aesimc.8 q0, q0
+
+ aesd.8 q0, q2
+ aesimc.8 q0, q0
+
+ aesd.8 q0, q3
+ aesimc.8 q0, q0
+ vldm r0!, {q1-q3} /* load 3 round keys */
+
+ aesd.8 q0, q15
+ aesimc.8 q0, q0
+
+ b .Ldec1_tail
+.size _gcry_aes_dec_armv8_ce,.-_gcry_aes_dec_armv8_ce;
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_cbc_enc_armv8_ce
+.type _gcry_aes_cbc_enc_armv8_ce,%function;
+_gcry_aes_cbc_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * %st+0: nblocks => r4
+ * %st+4: cbc_mac => r5
+ * %st+8: nrounds => r6
+ */
+
+ push {r4-r6,lr} /* 4*4 = 16b */
+ ldr r4, [sp, #(16+0)]
+ ldr r5, [sp, #(16+4)]
+ cmp r4, #0
+ ldr r6, [sp, #(16+8)]
+ beq .Lcbc_enc_skip
+ cmp r5, #0
+ vpush {q4-q7}
+ moveq r5, #16
+ movne r5, #0
+
+ cmp r6, #12
+ vld1.8 {q1}, [r3] /* load IV */
+
+ aes_preload_keys(r0, lr);
+
+ beq .Lcbc_enc_loop192
+ bhi .Lcbc_enc_loop256
+
+#define CBC_ENC(bits, ...) \
+ .Lcbc_enc_loop##bits: \
+ vld1.8 {q0}, [r2]!; /* load plaintext */ \
+ veor q1, q0, q1; \
+ subs r4, r4, #1; \
+ \
+ do_aes_one##bits(e, mc, q1, q1, ##__VA_ARGS__); \
+ \
+ vst1.8 {q1}, [r1], r5; /* store ciphertext */ \
+ \
+ bne .Lcbc_enc_loop##bits; \
+ b .Lcbc_enc_done;
+
+ CBC_ENC(128)
+ CBC_ENC(192, r0, lr)
+ CBC_ENC(256, r0, lr)
+
+#undef CBC_ENC
+
+.Lcbc_enc_done:
+ vst1.8 {q1}, [r3] /* store IV */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ vpop {q4-q7}
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+.Lcbc_enc_skip:
+ pop {r4-r6,pc}
+.size _gcry_aes_cbc_enc_armv8_ce,.-_gcry_aes_cbc_enc_armv8_ce;
+
+
+/*
+ * void _gcry_aes_cbc_dec_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_cbc_dec_armv8_ce
+.type _gcry_aes_cbc_dec_armv8_ce,%function;
+_gcry_aes_cbc_dec_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * %st+0: nblocks => r4
+ * %st+4: nrounds => r5
+ */
+
+ push {r4-r6,lr} /* 4*4 = 16b */
+ ldr r4, [sp, #(16+0)]
+ ldr r5, [sp, #(16+4)]
+ cmp r4, #0
+ beq .Lcbc_dec_skip
+ vpush {q4-q7}
+
+ cmp r5, #12
+ vld1.8 {q0}, [r3] /* load IV */
+
+ aes_preload_keys(r0, r6);
+
+ beq .Lcbc_dec_entry_192
+ bhi .Lcbc_dec_entry_256
+
+#define CBC_DEC(bits, ...) \
+ .Lcbc_dec_entry_##bits: \
+ cmp r4, #4; \
+ blo .Lcbc_dec_loop_##bits; \
+ \
+ .Lcbc_dec_loop4_##bits: \
+ \
+ vld1.8 {q1-q2}, [r2]!; /* load ciphertext */ \
+ sub r4, r4, #4; \
+ vld1.8 {q3-q4}, [r2]; /* load ciphertext */ \
+ cmp r4, #4; \
+ sub r2, #32; \
+ \
+ do_aes_4_##bits(d, imc, q1, q2, q3, q4, ##__VA_ARGS__); \
+ \
+ veor q1, q1, q0; \
+ vld1.8 {q0}, [r2]!; /* load next IV */ \
+ veor q2, q2, q0; \
+ vld1.8 {q0}, [r2]!; /* load next IV */ \
+ vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \
+ veor q3, q3, q0; \
+ vld1.8 {q0}, [r2]!; /* load next IV */ \
+ veor q4, q4, q0; \
+ vld1.8 {q0}, [r2]!; /* load next IV */ \
+ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \
+ \
+ bhs .Lcbc_dec_loop4_##bits; \
+ cmp r4, #0; \
+ beq .Lcbc_dec_done; \
+ \
+ .Lcbc_dec_loop_##bits: \
+ vld1.8 {q1}, [r2]!; /* load ciphertext */ \
+ subs r4, r4, #1; \
+ vmov q2, q1; \
+ \
+ do_aes_one##bits(d, imc, q1, q1, ##__VA_ARGS__); \
+ \
+ veor q1, q1, q0; \
+ vmov q0, q2; \
+ vst1.8 {q1}, [r1]!; /* store plaintext */ \
+ \
+ bne .Lcbc_dec_loop_##bits; \
+ b .Lcbc_dec_done;
+
+ CBC_DEC(128)
+ CBC_DEC(192, r0, r6)
+ CBC_DEC(256, r0, r6)
+
+#undef CBC_DEC
+
+.Lcbc_dec_done:
+ vst1.8 {q0}, [r3] /* store IV */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ vpop {q4-q7}
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+.Lcbc_dec_skip:
+ pop {r4-r6,pc}
+.size _gcry_aes_cbc_dec_armv8_ce,.-_gcry_aes_cbc_dec_armv8_ce;
+
+
+/*
+ * void _gcry_aes_cfb_enc_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_cfb_enc_armv8_ce
+.type _gcry_aes_cfb_enc_armv8_ce,%function;
+_gcry_aes_cfb_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * %st+0: nblocks => r4
+ * %st+4: nrounds => r5
+ */
+
+ push {r4-r6,lr} /* 4*4 = 16b */
+ ldr r4, [sp, #(16+0)]
+ ldr r5, [sp, #(16+4)]
+ cmp r4, #0
+ beq .Lcfb_enc_skip
+ vpush {q4-q7}
+
+ cmp r5, #12
+ vld1.8 {q0}, [r3] /* load IV */
+
+ aes_preload_keys(r0, r6);
+
+ beq .Lcfb_enc_entry_192
+ bhi .Lcfb_enc_entry_256
+
+#define CFB_ENC(bits, ...) \
+ .Lcfb_enc_entry_##bits: \
+ .Lcfb_enc_loop_##bits: \
+ vld1.8 {q1}, [r2]!; /* load plaintext */ \
+ subs r4, r4, #1; \
+ \
+ do_aes_one##bits(e, mc, q0, q0, ##__VA_ARGS__); \
+ \
+ veor q0, q1, q0; \
+ vst1.8 {q0}, [r1]!; /* store ciphertext */ \
+ \
+ bne .Lcfb_enc_loop_##bits; \
+ b .Lcfb_enc_done;
+
+ CFB_ENC(128)
+ CFB_ENC(192, r0, r6)
+ CFB_ENC(256, r0, r6)
+
+#undef CFB_ENC
+
+.Lcfb_enc_done:
+ vst1.8 {q0}, [r3] /* store IV */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ vpop {q4-q7}
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+.Lcfb_enc_skip:
+ pop {r4-r6,pc}
+.size _gcry_aes_cfb_enc_armv8_ce,.-_gcry_aes_cfb_enc_armv8_ce;
+
+
+/*
+ * void _gcry_aes_cfb_dec_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_cfb_dec_armv8_ce
+.type _gcry_aes_cfb_dec_armv8_ce,%function;
+_gcry_aes_cfb_dec_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * %st+0: nblocks => r4
+ * %st+4: nrounds => r5
+ */
+
+ push {r4-r6,lr} /* 4*4 = 16b */
+ ldr r4, [sp, #(16+0)]
+ ldr r5, [sp, #(16+4)]
+ cmp r4, #0
+ beq .Lcfb_dec_skip
+ vpush {q4-q7}
+
+ cmp r5, #12
+ vld1.8 {q0}, [r3] /* load IV */
+
+ aes_preload_keys(r0, r6);
+
+ beq .Lcfb_dec_entry_192
+ bhi .Lcfb_dec_entry_256
+
+#define CFB_DEC(bits, ...) \
+ .Lcfb_dec_entry_##bits: \
+ cmp r4, #4; \
+ blo .Lcfb_dec_loop_##bits; \
+ \
+ .Lcfb_dec_loop4_##bits: \
+ \
+ vld1.8 {q2-q3}, [r2]!; /* load ciphertext */ \
+ vmov q1, q0; \
+ sub r4, r4, #4; \
+ vld1.8 {q4}, [r2]; /* load ciphertext */ \
+ sub r2, #32; \
+ cmp r4, #4; \
+ \
+ do_aes_4_##bits(e, mc, q1, q2, q3, q4, ##__VA_ARGS__); \
+ \
+ vld1.8 {q0}, [r2]!; /* load ciphertext */ \
+ veor q1, q1, q0; \
+ vld1.8 {q0}, [r2]!; /* load ciphertext */ \
+ veor q2, q2, q0; \
+ vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \
+ vld1.8 {q0}, [r2]!; \
+ veor q3, q3, q0; \
+ vld1.8 {q0}, [r2]!; /* load next IV / ciphertext */ \
+ veor q4, q4, q0; \
+ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \
+ \
+ bhs .Lcfb_dec_loop4_##bits; \
+ cmp r4, #0; \
+ beq .Lcfb_dec_done; \
+ \
+ .Lcfb_dec_loop_##bits: \
+ \
+ vld1.8 {q1}, [r2]!; /* load ciphertext */ \
+ \
+ subs r4, r4, #1; \
+ \
+ do_aes_one##bits(e, mc, q0, q0, ##__VA_ARGS__); \
+ \
+ veor q2, q1, q0; \
+ vmov q0, q1; \
+ vst1.8 {q2}, [r1]!; /* store plaintext */ \
+ \
+ bne .Lcfb_dec_loop_##bits; \
+ b .Lcfb_dec_done;
+
+ CFB_DEC(128)
+ CFB_DEC(192, r0, r6)
+ CFB_DEC(256, r0, r6)
+
+#undef CFB_DEC
+
+.Lcfb_dec_done:
+ vst1.8 {q0}, [r3] /* store IV */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ vpop {q4-q7}
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+.Lcfb_dec_skip:
+ pop {r4-r6,pc}
+.size _gcry_aes_cfb_dec_armv8_ce,.-_gcry_aes_cfb_dec_armv8_ce;
+
+
+/*
+ * void _gcry_aes_ctr_enc_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_ctr_enc_armv8_ce
+.type _gcry_aes_ctr_enc_armv8_ce,%function;
+_gcry_aes_ctr_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * %st+0: nblocks => r4
+ * %st+4: nrounds => r5
+ */
+
+ vpush {q4-q7}
+ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */
+ ldr r4, [sp, #(104+0)]
+ ldr r5, [sp, #(104+4)]
+ cmp r4, #0
+ beq .Lctr_enc_skip
+
+ cmp r5, #12
+ ldm r3, {r7-r10}
+ vld1.8 {q0}, [r3] /* load IV */
+ rev r7, r7
+ rev r8, r8
+ rev r9, r9
+ rev r10, r10
+
+ aes_preload_keys(r0, r6);
+
+ beq .Lctr_enc_entry_192
+ bhi .Lctr_enc_entry_256
+
+#define CTR_ENC(bits, ...) \
+ .Lctr_enc_entry_##bits: \
+ cmp r4, #4; \
+ blo .Lctr_enc_loop_##bits; \
+ \
+ .Lctr_enc_loop4_##bits: \
+ cmp r10, #0xfffffffc; \
+ sub r4, r4, #4; \
+ blo .Lctr_enc_loop4_##bits##_nocarry; \
+ cmp r9, #0xffffffff; \
+ bne .Lctr_enc_loop4_##bits##_nocarry; \
+ \
+ adds r10, #1; \
+ vmov q1, q0; \
+ blcs .Lctr_overflow_one; \
+ rev r11, r10; \
+ vmov.32 d1[1], r11; \
+ \
+ adds r10, #1; \
+ vmov q2, q0; \
+ blcs .Lctr_overflow_one; \
+ rev r11, r10; \
+ vmov.32 d1[1], r11; \
+ \
+ adds r10, #1; \
+ vmov q3, q0; \
+ blcs .Lctr_overflow_one; \
+ rev r11, r10; \
+ vmov.32 d1[1], r11; \
+ \
+ adds r10, #1; \
+ vmov q4, q0; \
+ blcs .Lctr_overflow_one; \
+ rev r11, r10; \
+ vmov.32 d1[1], r11; \
+ \
+ b .Lctr_enc_loop4_##bits##_store_ctr; \
+ \
+ .Lctr_enc_loop4_##bits##_nocarry: \
+ \
+ veor q2, q2; \
+ vrev64.8 q1, q0; \
+ vceq.u32 d5, d5; \
+ vadd.u64 q3, q2, q2; \
+ vadd.u64 q4, q3, q2; \
+ vadd.u64 q0, q3, q3; \
+ vsub.u64 q2, q1, q2; \
+ vsub.u64 q3, q1, q3; \
+ vsub.u64 q4, q1, q4; \
+ vsub.u64 q0, q1, q0; \
+ vrev64.8 q1, q1; \
+ vrev64.8 q2, q2; \
+ vrev64.8 q3, q3; \
+ vrev64.8 q0, q0; \
+ vrev64.8 q4, q4; \
+ add r10, #4; \
+ \
+ .Lctr_enc_loop4_##bits##_store_ctr: \
+ \
+ vst1.8 {q0}, [r3]; \
+ cmp r4, #4; \
+ vld1.8 {q0}, [r2]!; /* load ciphertext */ \
+ \
+ do_aes_4_##bits(e, mc, q1, q2, q3, q4, ##__VA_ARGS__); \
+ \
+ veor q1, q1, q0; \
+ vld1.8 {q0}, [r2]!; /* load ciphertext */ \
+ vst1.8 {q1}, [r1]!; /* store plaintext */ \
+ vld1.8 {q1}, [r2]!; /* load ciphertext */ \
+ veor q2, q2, q0; \
+ veor q3, q3, q1; \
+ vld1.8 {q0}, [r2]!; /* load ciphertext */ \
+ vst1.8 {q2}, [r1]!; /* store plaintext */ \
+ veor q4, q4, q0; \
+ vld1.8 {q0}, [r3]; /* reload IV */ \
+ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \
+ \
+ bhs .Lctr_enc_loop4_##bits; \
+ cmp r4, #0; \
+ beq .Lctr_enc_done; \
+ \
+ .Lctr_enc_loop_##bits: \
+ \
+ adds r10, #1; \
+ vmov q1, q0; \
+ blcs .Lctr_overflow_one; \
+ rev r11, r10; \
+ subs r4, r4, #1; \
+ vld1.8 {q2}, [r2]!; /* load ciphertext */ \
+ vmov.32 d1[1], r11; \
+ \
+ do_aes_one##bits(e, mc, q1, q1, ##__VA_ARGS__); \
+ \
+ veor q1, q2, q1; \
+ vst1.8 {q1}, [r1]!; /* store plaintext */ \
+ \
+ bne .Lctr_enc_loop_##bits; \
+ b .Lctr_enc_done;
+
+ CTR_ENC(128)
+ CTR_ENC(192, r0, r6)
+ CTR_ENC(256, r0, r6)
+
+#undef CTR_ENC
+
+.Lctr_enc_done:
+ vst1.8 {q0}, [r3] /* store IV */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+.Lctr_enc_skip:
+ pop {r4-r12,lr}
+ vpop {q4-q7}
+ bx lr
+
+.Lctr_overflow_one:
+ adcs r9, #0
+ adcs r8, #0
+ adc r7, #0
+ rev r11, r9
+ rev r12, r8
+ vmov.32 d1[0], r11
+ rev r11, r7
+ vmov.32 d0[1], r12
+ vmov.32 d0[0], r11
+ bx lr
+.size _gcry_aes_ctr_enc_armv8_ce,.-_gcry_aes_ctr_enc_armv8_ce;
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_ocb_enc_armv8_ce
+.type _gcry_aes_ocb_enc_armv8_ce,%function;
+_gcry_aes_ocb_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: offset
+ * %st+0: checksum => r4
+ * %st+4: Ls => r5
+ * %st+8: nblocks => r6 (0 < nblocks <= 32)
+ * %st+12: nrounds => r7
+ * %st+16: blkn => lr
+ */
+
+ vpush {q4-q7}
+ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */
+ ldr r7, [sp, #(104+12)]
+ ldr r4, [sp, #(104+0)]
+ ldr r5, [sp, #(104+4)]
+ ldr r6, [sp, #(104+8)]
+ ldr lr, [sp, #(104+16)]
+
+ cmp r7, #12
+ vld1.8 {q0}, [r3] /* load offset */
+
+ aes_preload_keys(r0, r12);
+
+ beq .Locb_enc_entry_192
+ bhi .Locb_enc_entry_256
+
+#define OCB_ENC(bits, ...) \
+ .Locb_enc_entry_##bits: \
+ cmp r6, #4; \
+ add lr, #1; \
+ blo .Locb_enc_loop_##bits; \
+ \
+ .Locb_enc_loop4_##bits: \
+ \
+ /* 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) */ \
+ \
+ add r9, lr, #1; \
+ add r10, lr, #2; \
+ add r11, lr, #3; \
+ rbit r8, lr; \
+ add lr, lr, #4; \
+ rbit r9, r9; \
+ rbit r10, r10; \
+ rbit r11, r11; \
+ clz r8, r8; /* ntz(i+0) */ \
+ clz r9, r9; /* ntz(i+1) */ \
+ clz r10, r10; /* ntz(i+2) */ \
+ clz r11, r11; /* ntz(i+3) */ \
+ add r8, r5, r8, lsl #4; \
+ add r9, r5, r9, lsl #4; \
+ add r10, r5, r10, lsl #4; \
+ add r11, r5, r11, lsl #4; \
+ \
+ sub r6, #4; \
+ \
+ vld1.8 {q9}, [r8]; /* load L_{ntz(i+0)} */ \
+ vld1.8 {q1-q2}, [r2]!; /* load P_i+<0-1> */ \
+ vld1.8 {q8}, [r4]; /* load Checksum_{i-1} */ \
+ veor q0, q0, q9; /* Offset_i+0 */ \
+ vld1.8 {q9}, [r9]; /* load L_{ntz(i+1)} */ \
+ veor q8, q8, q1; /* Checksum_i+0 */ \
+ veor q1, q1, q0; /* P_i+0 xor Offset_i+0 */\
+ vld1.8 {q3-q4}, [r2]!; /* load P_i+<2-3> */ \
+ vst1.8 {q0}, [r1]!; /* store Offset_i+0 */\
+ veor q0, q0, q9; /* Offset_i+1 */ \
+ vld1.8 {q9}, [r10]; /* load L_{ntz(i+2)} */ \
+ veor q8, q8, q2; /* Checksum_i+1 */ \
+ veor q2, q2, q0; /* P_i+1 xor Offset_i+1 */\
+ vst1.8 {q0}, [r1]!; /* store Offset_i+1 */\
+ veor q0, q0, q9; /* Offset_i+2 */ \
+ vld1.8 {q9}, [r11]; /* load L_{ntz(i+3)} */ \
+ veor q8, q8, q3; /* Checksum_i+2 */ \
+ veor q3, q3, q0; /* P_i+2 xor Offset_i+2 */\
+ vst1.8 {q0}, [r1]!; /* store Offset_i+2 */\
+ veor q0, q0, q9; /* Offset_i+3 */ \
+ veor q8, q8, q4; /* Checksum_i+3 */ \
+ veor q4, q4, q0; /* P_i+3 xor Offset_i+3 */\
+ vst1.8 {q0}, [r1]; /* store Offset_i+3 */\
+ sub r1, #(3*16); \
+ vst1.8 {q8}, [r4]; /* store Checksum_i+3 */\
+ \
+ cmp r6, #4; \
+ \
+ do_aes_4_##bits(e, mc, q1, q2, q3, q4, ##__VA_ARGS__); \
+ \
+ mov r8, r1; \
+ vld1.8 {q8-q9}, [r1]!; \
+ veor q1, q1, q8; \
+ veor q2, q2, q9; \
+ vld1.8 {q8-q9}, [r1]!; \
+ vst1.8 {q1-q2}, [r8]!; \
+ veor q3, q3, q8; \
+ veor q4, q4, q9; \
+ vst1.8 {q3-q4}, [r8]; \
+ \
+ bhs .Locb_enc_loop4_##bits; \
+ cmp r6, #0; \
+ beq .Locb_enc_done; \
+ \
+ .Locb_enc_loop_##bits: \
+ \
+ /* 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) */ \
+ \
+ rbit r8, lr; \
+ add lr, #1; \
+ clz r8, r8; /* ntz(i) */ \
+ add r8, r5, r8, lsl #4; \
+ \
+ vld1.8 {q1}, [r2]!; /* load plaintext */ \
+ vld1.8 {q2}, [r8]; /* load L_{ntz(i)} */ \
+ vld1.8 {q3}, [r4]; /* load checksum */ \
+ subs r6, #1; \
+ veor q0, q0, q2; \
+ veor q3, q3, q1; \
+ veor q1, q1, q0; \
+ vst1.8 {q3}, [r4]; /* store checksum */ \
+ \
+ do_aes_one##bits(e, mc, q1, q1, ##__VA_ARGS__); \
+ \
+ veor q1, q1, q0; \
+ vst1.8 {q1}, [r1]!; /* store ciphertext */ \
+ \
+ bne .Locb_enc_loop_##bits; \
+ b .Locb_enc_done;
+
+ OCB_ENC(128re, r0, r12)
+ OCB_ENC(192, r0, r12)
+ OCB_ENC(256, r0, r12)
+
+#undef OCB_ENC
+
+.Locb_enc_done:
+ vst1.8 {q0}, [r3] /* store offset */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+ pop {r4-r12,lr}
+ vpop {q4-q7}
+ bx lr
+.size _gcry_aes_ocb_enc_armv8_ce,.-_gcry_aes_ocb_enc_armv8_ce;
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_ocb_dec_armv8_ce
+.type _gcry_aes_ocb_dec_armv8_ce,%function;
+_gcry_aes_ocb_dec_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: offset
+ * %st+0: checksum => r4
+ * %st+4: Ls => r5
+ * %st+8: nblocks => r6 (0 < nblocks <= 32)
+ * %st+12: nrounds => r7
+ * %st+16: blkn => lr
+ */
+
+ vpush {q4-q7}
+ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */
+ ldr r7, [sp, #(104+12)]
+ ldr r4, [sp, #(104+0)]
+ ldr r5, [sp, #(104+4)]
+ ldr r6, [sp, #(104+8)]
+ ldr lr, [sp, #(104+16)]
+
+ cmp r7, #12
+ vld1.8 {q0}, [r3] /* load offset */
+
+ aes_preload_keys(r0, r12);
+
+ beq .Locb_dec_entry_192
+ bhi .Locb_dec_entry_256
+
+#define OCB_DEC(bits, ...) \
+ .Locb_dec_entry_##bits: \
+ cmp r6, #4; \
+ add lr, #1; \
+ blo .Locb_dec_loop_##bits; \
+ \
+ .Locb_dec_loop4_##bits: \
+ \
+ /* 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 */ \
+ \
+ add r9, lr, #1; \
+ add r10, lr, #2; \
+ add r11, lr, #3; \
+ rbit r8, lr; \
+ add lr, lr, #4; \
+ rbit r9, r9; \
+ rbit r10, r10; \
+ rbit r11, r11; \
+ clz r8, r8; /* ntz(i+0) */ \
+ clz r9, r9; /* ntz(i+1) */ \
+ clz r10, r10; /* ntz(i+2) */ \
+ clz r11, r11; /* ntz(i+3) */ \
+ add r8, r5, r8, lsl #4; \
+ add r9, r5, r9, lsl #4; \
+ add r10, r5, r10, lsl #4; \
+ add r11, r5, r11, lsl #4; \
+ \
+ sub r6, #4; \
+ \
+ vld1.8 {q9}, [r8]; /* load L_{ntz(i+0)} */ \
+ vld1.8 {q1-q2}, [r2]!; /* load P_i+<0-1> */ \
+ veor q0, q0, q9; /* Offset_i+0 */ \
+ vld1.8 {q9}, [r9]; /* load L_{ntz(i+1)} */ \
+ veor q1, q1, q0; /* P_i+0 xor Offset_i+0 */\
+ vld1.8 {q3-q4}, [r2]!; /* load P_i+<2-3> */ \
+ vst1.8 {q0}, [r1]!; /* store Offset_i+0 */\
+ veor q0, q0, q9; /* Offset_i+1 */ \
+ vld1.8 {q9}, [r10]; /* load L_{ntz(i+2)} */ \
+ veor q2, q2, q0; /* P_i+1 xor Offset_i+1 */\
+ vst1.8 {q0}, [r1]!; /* store Offset_i+1 */\
+ veor q0, q0, q9; /* Offset_i+2 */ \
+ vld1.8 {q9}, [r11]; /* load L_{ntz(i+3)} */ \
+ veor q3, q3, q0; /* P_i+2 xor Offset_i+2 */\
+ vst1.8 {q0}, [r1]!; /* store Offset_i+2 */\
+ veor q0, q0, q9; /* Offset_i+3 */ \
+ veor q4, q4, q0; /* P_i+3 xor Offset_i+3 */\
+ vst1.8 {q0}, [r1]; /* store Offset_i+3 */\
+ sub r1, #(3*16); \
+ \
+ cmp r6, #4; \
+ \
+ do_aes_4_##bits(d, imc, q1, q2, q3, q4, ##__VA_ARGS__); \
+ \
+ mov r8, r1; \
+ vld1.8 {q8-q9}, [r1]!; \
+ veor q1, q1, q8; \
+ veor q2, q2, q9; \
+ vld1.8 {q8-q9}, [r1]!; \
+ vst1.8 {q1-q2}, [r8]!; \
+ veor q1, q1, q2; \
+ vld1.8 {q2}, [r4]; /* load Checksum_{i-1} */ \
+ veor q3, q3, q8; \
+ veor q1, q1, q3; \
+ veor q4, q4, q9; \
+ veor q1, q1, q4; \
+ vst1.8 {q3-q4}, [r8]; \
+ veor q2, q2, q1; \
+ vst1.8 {q2}, [r4]; /* store Checksum_i+3 */ \
+ \
+ bhs .Locb_dec_loop4_##bits; \
+ cmp r6, #0; \
+ beq .Locb_dec_done; \
+ \
+ .Locb_dec_loop_##bits: \
+ \
+ /* 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 */ \
+ \
+ rbit r8, lr; \
+ add lr, #1; \
+ clz r8, r8; /* ntz(i) */ \
+ add r8, r5, r8, lsl #4; \
+ \
+ vld1.8 {q2}, [r8]; /* load L_{ntz(i)} */ \
+ vld1.8 {q1}, [r2]!; /* load ciphertext */ \
+ subs r6, #1; \
+ veor q0, q0, q2; \
+ veor q1, q1, q0; \
+ \
+ do_aes_one##bits(d, imc, q1, q1, ##__VA_ARGS__) \
+ \
+ vld1.8 {q2}, [r4]; /* load checksum */ \
+ veor q1, q1, q0; \
+ vst1.8 {q1}, [r1]!; /* store plaintext */ \
+ veor q2, q2, q1; \
+ vst1.8 {q2}, [r4]; /* store checksum */ \
+ \
+ bne .Locb_dec_loop_##bits; \
+ b .Locb_dec_done;
+
+ OCB_DEC(128re, r0, r12)
+ OCB_DEC(192, r0, r12)
+ OCB_DEC(256, r0, r12)
+
+#undef OCB_DEC
+
+.Locb_dec_done:
+ vst1.8 {q0}, [r3] /* store offset */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+ pop {r4-r12,lr}
+ vpop {q4-q7}
+ bx lr
+.size _gcry_aes_ocb_dec_armv8_ce,.-_gcry_aes_ocb_dec_armv8_ce;
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_ocb_auth_armv8_ce
+.type _gcry_aes_ocb_auth_armv8_ce,%function;
+_gcry_aes_ocb_auth_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: abuf
+ * r2: offset
+ * r3: checksum
+ * %st+0: Ls => r5
+ * %st+4: nblocks => r6 (0 < nblocks <= 32)
+ * %st+8: nrounds => r7
+ * %st+12: blkn => lr
+ */
+
+ vpush {q4-q7}
+ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */
+ ldr r7, [sp, #(104+8)]
+ ldr r5, [sp, #(104+0)]
+ ldr r6, [sp, #(104+4)]
+ ldr lr, [sp, #(104+12)]
+
+ cmp r7, #12
+ vld1.8 {q0}, [r2] /* load offset */
+
+ aes_preload_keys(r0, r12);
+
+ beq .Locb_auth_entry_192
+ bhi .Locb_auth_entry_256
+
+#define OCB_AUTH(bits, ...) \
+ .Locb_auth_entry_##bits: \
+ cmp r6, #4; \
+ add lr, #1; \
+ blo .Locb_auth_loop_##bits; \
+ \
+ .Locb_auth_loop4_##bits: \
+ \
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ \
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ \
+ \
+ add r9, lr, #1; \
+ add r10, lr, #2; \
+ add r11, lr, #3; \
+ rbit r8, lr; \
+ add lr, lr, #4; \
+ rbit r9, r9; \
+ rbit r10, r10; \
+ rbit r11, r11; \
+ clz r8, r8; /* ntz(i+0) */ \
+ clz r9, r9; /* ntz(i+1) */ \
+ clz r10, r10; /* ntz(i+2) */ \
+ clz r11, r11; /* ntz(i+3) */ \
+ add r8, r5, r8, lsl #4; \
+ add r9, r5, r9, lsl #4; \
+ add r10, r5, r10, lsl #4; \
+ add r11, r5, r11, lsl #4; \
+ \
+ sub r6, #4; \
+ \
+ vld1.8 {q9}, [r8]; /* load L_{ntz(i+0)} */ \
+ vld1.8 {q1-q2}, [r1]!; /* load A_i+<0-1> */ \
+ veor q0, q0, q9; /* Offset_i+0 */ \
+ vld1.8 {q9}, [r9]; /* load L_{ntz(i+1)} */ \
+ veor q1, q1, q0; /* A_i+0 xor Offset_i+0 */\
+ vld1.8 {q3-q4}, [r1]!; /* load A_i+<2-3> */ \
+ veor q0, q0, q9; /* Offset_i+1 */ \
+ vld1.8 {q9}, [r10]; /* load L_{ntz(i+2)} */ \
+ veor q2, q2, q0; /* A_i+1 xor Offset_i+1 */\
+ veor q0, q0, q9; /* Offset_i+2 */ \
+ vld1.8 {q9}, [r11]; /* load L_{ntz(i+3)} */ \
+ veor q3, q3, q0; /* A_i+2 xor Offset_i+2 */\
+ veor q0, q0, q9; /* Offset_i+3 */ \
+ veor q4, q4, q0; /* A_i+3 xor Offset_i+3 */\
+ \
+ cmp r6, #4; \
+ \
+ do_aes_4_##bits(e, mc, q1, q2, q3, q4, ##__VA_ARGS__); \
+ \
+ veor q1, q1, q2; \
+ veor q3, q3, q4; \
+ vld1.8 {q2}, [r3]; \
+ veor q1, q1, q3; \
+ veor q2, q2, q1; \
+ vst1.8 {q2}, [r3]; \
+ \
+ bhs .Locb_auth_loop4_##bits; \
+ cmp r6, #0; \
+ beq .Locb_auth_done; \
+ \
+ .Locb_auth_loop_##bits: \
+ \
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ \
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ \
+ \
+ rbit r8, lr; \
+ add lr, #1; \
+ clz r8, r8; /* ntz(i) */ \
+ add r8, r5, r8, lsl #4; \
+ \
+ vld1.8 {q2}, [r8]; /* load L_{ntz(i)} */ \
+ vld1.8 {q1}, [r1]!; /* load aadtext */ \
+ subs r6, #1; \
+ veor q0, q0, q2; \
+ vld1.8 {q2}, [r3]; /* load checksum */ \
+ veor q1, q1, q0; \
+ \
+ do_aes_one##bits(e, mc, q1, q1, ##__VA_ARGS__) \
+ \
+ veor q2, q2, q1; \
+ vst1.8 {q2}, [r3]; /* store checksum */ \
+ \
+ bne .Locb_auth_loop_##bits; \
+ b .Locb_auth_done;
+
+ OCB_AUTH(128re, r0, r12)
+ OCB_AUTH(192, r0, r12)
+ OCB_AUTH(256, r0, r12)
+
+#undef OCB_AUTH
+
+.Locb_auth_done:
+ vst1.8 {q0}, [r2] /* store offset */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+ pop {r4-r12,lr}
+ vpop {q4-q7}
+ bx lr
+.size _gcry_aes_ocb_auth_armv8_ce,.-_gcry_aes_ocb_auth_armv8_ce;
+
+
+
+/*
+ * void _gcry_aes_xts_enc_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_xts_enc_armv8_ce
+.type _gcry_aes_xts_enc_armv8_ce,%function;
+_gcry_aes_xts_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * %st+0: nblocks => r4
+ * %st+4: nrounds => r5
+ */
+
+ vpush {q4-q7}
+ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */
+ ldr r4, [sp, #(104+0)]
+ ldr r5, [sp, #(104+4)]
+ cmp r4, #0
+ beq .Lxts_enc_skip
+
+ cmp r5, #12
+
+ vld1.8 {q0}, [r3] /* load tweak */
+ mov r7, #0x87;
+
+ aes_preload_keys(r0, r6);
+
+ beq .Lxts_enc_entry_192
+ bhi .Lxts_enc_entry_256
+
+#define CTR_XTS(bits, ...) \
+ .Lxts_enc_entry_##bits: \
+ cmp r4, #4; \
+ blo .Lxts_enc_loop_##bits; \
+ \
+ .Lxts_enc_loop4_##bits: \
+ sub r4, r4, #4; \
+ veor q9, q9, q9; \
+ \
+ vld1.8 {q1-q2}, [r2]!; /* load plaintext */ \
+ veor q1, q1, q0; \
+ cmp r4, #4; \
+ vmov.u32 d18[0], r7; \
+ vst1.8 {q0}, [r1]!; /* store tweak0 to temp */ \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ \
+ vld1.8 {q3-q4}, [r2]!; /* load plaintext */ \
+ veor q2, q2, q0; \
+ vst1.8 {q0}, [r1]!; /* store tweak1 to temp */ \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ \
+ veor q3, q3, q0; \
+ vst1.8 {q0}, [r1]!; /* store tweak2 to temp */ \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ \
+ veor q4, q4, q0; \
+ vst1.8 {q0}, [r1]; /* store tweak3 to temp */ \
+ sub r1, r1, #48; \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ \
+ do_aes_4_##bits(e, mc, q1, q2, q3, q4, ##__VA_ARGS__); \
+ \
+ vld1.8 {q8-q9}, [r1]!; /* load tweak from temp */ \
+ veor q1, q1, q8; \
+ veor q2, q2, q9; \
+ vld1.8 {q8-q9}, [r1]; /* load tweak from temp */ \
+ sub r1, r1, #32; \
+ veor q3, q3, q8; \
+ veor q4, q4, q9; \
+ vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \
+ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \
+ \
+ bhs .Lxts_enc_loop4_##bits; \
+ cmp r4, #0; \
+ beq .Lxts_enc_done; \
+ \
+ .Lxts_enc_loop_##bits: \
+ \
+ vld1.8 {q1}, [r2]!; /* load ciphertext */ \
+ \
+ veor q9, q9, q9; \
+ veor q1, q1, q0; \
+ vmov.u32 d18[0], r7; \
+ vmov q2, q0; \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ subs r4, r4, #1; \
+ \
+ do_aes_one##bits(e, mc, q1, q1, ##__VA_ARGS__); \
+ \
+ veor q1, q1, q2; \
+ vst1.8 {q1}, [r1]!; /* store plaintext */ \
+ \
+ bne .Lxts_enc_loop_##bits; \
+ b .Lxts_enc_done;
+
+ CTR_XTS(128re, r0, r6)
+ CTR_XTS(192, r0, r6)
+ CTR_XTS(256, r0, r6)
+
+#undef CTR_XTS
+
+.Lxts_enc_done:
+ vst1.8 {q0}, [r3] /* store tweak */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+.Lxts_enc_skip:
+ pop {r4-r12,lr}
+ vpop {q4-q7}
+ bx lr
+.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce;
+
+
+/*
+ * void _gcry_aes_xts_dec_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_xts_dec_armv8_ce
+.type _gcry_aes_xts_dec_armv8_ce,%function;
+_gcry_aes_xts_dec_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * %st+0: nblocks => r4
+ * %st+4: nrounds => r5
+ */
+
+ vpush {q4-q7}
+ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */
+ ldr r4, [sp, #(104+0)]
+ ldr r5, [sp, #(104+4)]
+ cmp r4, #0
+ beq .Lxts_dec_skip
+
+ cmp r5, #12
+
+ vld1.8 {q0}, [r3] /* load tweak */
+ mov r7, #0x87;
+
+ aes_preload_keys(r0, r6);
+
+ beq .Lxts_dec_entry_192
+ bhi .Lxts_dec_entry_256
+
+#define CTR_XTS(bits, ...) \
+ .Lxts_dec_entry_##bits: \
+ cmp r4, #4; \
+ blo .Lxts_dec_loop_##bits; \
+ \
+ .Lxts_dec_loop4_##bits: \
+ sub r4, r4, #4; \
+ veor q9, q9, q9; \
+ \
+ vld1.8 {q1-q2}, [r2]!; /* load plaintext */ \
+ veor q1, q1, q0; \
+ cmp r4, #4; \
+ vmov.u32 d18[0], r7; \
+ vst1.8 {q0}, [r1]!; /* store tweak0 to temp */ \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ \
+ vld1.8 {q3-q4}, [r2]!; /* load plaintext */ \
+ veor q2, q2, q0; \
+ vst1.8 {q0}, [r1]!; /* store tweak1 to temp */ \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ \
+ veor q3, q3, q0; \
+ vst1.8 {q0}, [r1]!; /* store tweak2 to temp */ \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ \
+ veor q4, q4, q0; \
+ vst1.8 {q0}, [r1]; /* store tweak3 to temp */ \
+ sub r1, r1, #48; \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ \
+ do_aes_4_##bits(d, imc, q1, q2, q3, q4, ##__VA_ARGS__); \
+ \
+ vld1.8 {q8-q9}, [r1]!; /* load tweak from temp */ \
+ veor q1, q1, q8; \
+ veor q2, q2, q9; \
+ vld1.8 {q8-q9}, [r1]; /* load tweak from temp */ \
+ sub r1, r1, #32; \
+ veor q3, q3, q8; \
+ veor q4, q4, q9; \
+ vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \
+ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \
+ \
+ bhs .Lxts_dec_loop4_##bits; \
+ cmp r4, #0; \
+ beq .Lxts_dec_done; \
+ \
+ .Lxts_dec_loop_##bits: \
+ \
+ vld1.8 {q1}, [r2]!; /* load ciphertext */ \
+ \
+ veor q9, q9, q9; \
+ veor q1, q1, q0; \
+ vmov.u32 d18[0], r7; \
+ vmov q2, q0; \
+ \
+ vshr.s64 d16, d1, #63; \
+ vshr.u64 d17, d0, #63; \
+ vadd.u64 q0, q0, q0; \
+ vand d16, d16, d18; \
+ veor q0, q0, q8; \
+ subs r4, r4, #1; \
+ \
+ do_aes_one##bits(d, imc, q1, q1, ##__VA_ARGS__); \
+ \
+ veor q1, q1, q2; \
+ vst1.8 {q1}, [r1]!; /* store plaintext */ \
+ \
+ bne .Lxts_dec_loop_##bits; \
+ b .Lxts_dec_done;
+
+ CTR_XTS(128re, r0, r6)
+ CTR_XTS(192, r0, r6)
+ CTR_XTS(256, r0, r6)
+
+#undef CTR_XTS
+
+.Lxts_dec_done:
+ vst1.8 {q0}, [r3] /* store tweak */
+
+ CLEAR_REG(q0)
+ CLEAR_REG(q1)
+ CLEAR_REG(q2)
+ CLEAR_REG(q3)
+ CLEAR_REG(q8)
+ CLEAR_REG(q9)
+ CLEAR_REG(q10)
+ CLEAR_REG(q11)
+ CLEAR_REG(q12)
+ CLEAR_REG(q13)
+ CLEAR_REG(q14)
+
+.Lxts_dec_skip:
+ pop {r4-r12,lr}
+ vpop {q4-q7}
+ bx lr
+.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce;
+
+
+/*
+ * u32 _gcry_aes_sbox4_armv8_ce(u32 in4b);
+ */
+.align 3
+.globl _gcry_aes_sbox4_armv8_ce
+.type _gcry_aes_sbox4_armv8_ce,%function;
+_gcry_aes_sbox4_armv8_ce:
+ /* See "Gouvêa, C. P. L. & López, J. Implementing GCM on ARMv8. Topics in
+ * Cryptology — CT-RSA 2015" for details.
+ */
+ vmov.i8 q0, #0x52
+ vmov.i8 q1, #0
+ vmov s0, r0
+ aese.8 q0, q1
+ veor d0, d1
+ vpadd.i32 d0, d0, d1
+ vmov r0, s0
+ CLEAR_REG(q0)
+ bx lr
+.size _gcry_aes_sbox4_armv8_ce,.-_gcry_aes_sbox4_armv8_ce;
+
+
+/*
+ * void _gcry_aes_invmixcol_armv8_ce(void *dst, const void *src);
+ */
+.align 3
+.globl _gcry_aes_invmixcol_armv8_ce
+.type _gcry_aes_invmixcol_armv8_ce,%function;
+_gcry_aes_invmixcol_armv8_ce:
+ vld1.8 {q0}, [r1]
+ aesimc.8 q0, q0
+ vst1.8 {q0}, [r0]
+ CLEAR_REG(q0)
+ bx lr
+.size _gcry_aes_invmixcol_armv8_ce,.-_gcry_aes_invmixcol_armv8_ce;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-armv8-aarch64-ce.S b/comm/third_party/libgcrypt/cipher/rijndael-armv8-aarch64-ce.S
new file mode 100644
index 0000000000..3af29e0d0c
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-armv8-aarch64-ce.S
@@ -0,0 +1,1613 @@
+/* rijndael-armv8-aarch64-ce.S - ARMv8/CE accelerated AES
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+
+.cpu generic+simd+crypto
+
+.text
+
+
+/* Register macros */
+
+#define vk0 v17
+#define vk1 v18
+#define vk2 v19
+#define vk3 v20
+#define vk4 v21
+#define vk5 v22
+#define vk6 v23
+#define vk7 v24
+#define vk8 v25
+#define vk9 v26
+#define vk10 v27
+#define vk11 v28
+#define vk12 v29
+#define vk13 v30
+#define vk14 v31
+
+
+/* AES macros */
+
+#define aes_preload_keys(keysched, nrounds) \
+ cmp nrounds, #12; \
+ ld1 {vk0.16b-vk3.16b}, [keysched], #64; \
+ ld1 {vk4.16b-vk7.16b}, [keysched], #64; \
+ ld1 {vk8.16b-vk10.16b}, [keysched], #48; \
+ b.lo 1f; \
+ ld1 {vk11.16b-vk12.16b}, [keysched], #32; \
+ b.eq 1f; \
+ ld1 {vk13.16b-vk14.16b}, [keysched]; \
+1: ;
+
+#define do_aes_one128(ed, mcimc, vo, vb) \
+ aes##ed vb.16b, vk0.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk1.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk2.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk3.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk4.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk5.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk6.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk7.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk8.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk9.16b; \
+ eor vo.16b, vb.16b, vk10.16b;
+
+#define do_aes_one192(ed, mcimc, vo, vb) \
+ aes##ed vb.16b, vk0.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk1.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk2.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk3.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk4.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk5.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk6.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk7.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk8.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk9.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk10.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk11.16b; \
+ eor vo.16b, vb.16b, vk12.16b;
+
+#define do_aes_one256(ed, mcimc, vo, vb) \
+ aes##ed vb.16b, vk0.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk1.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk2.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk3.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk4.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk5.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk6.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk7.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk8.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk9.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk10.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk11.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk12.16b; \
+ aes##mcimc vb.16b, vb.16b; \
+ aes##ed vb.16b, vk13.16b; \
+ eor vo.16b, vb.16b, vk14.16b;
+
+#define aes_round_4(ed, mcimc, b0, b1, b2, b3, key) \
+ aes##ed b0.16b, key.16b; \
+ aes##mcimc b0.16b, b0.16b; \
+ aes##ed b1.16b, key.16b; \
+ aes##mcimc b1.16b, b1.16b; \
+ aes##ed b2.16b, key.16b; \
+ aes##mcimc b2.16b, b2.16b; \
+ aes##ed b3.16b, key.16b; \
+ aes##mcimc b3.16b, b3.16b;
+
+#define aes_lastround_4(ed, b0, b1, b2, b3, key1, key2) \
+ aes##ed b0.16b, key1.16b; \
+ eor b0.16b, b0.16b, key2.16b; \
+ aes##ed b1.16b, key1.16b; \
+ eor b1.16b, b1.16b, key2.16b; \
+ aes##ed b2.16b, key1.16b; \
+ eor b2.16b, b2.16b, key2.16b; \
+ aes##ed b3.16b, key1.16b; \
+ eor b3.16b, b3.16b, key2.16b;
+
+#define do_aes_4_128(ed, mcimc, b0, b1, b2, b3) \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk0); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk1); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk2); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk3); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk4); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk5); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk6); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk7); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk8); \
+ aes_lastround_4(ed, b0, b1, b2, b3, vk9, vk10);
+
+#define do_aes_4_192(ed, mcimc, b0, b1, b2, b3) \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk0); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk1); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk2); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk3); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk4); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk5); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk6); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk7); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk8); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk9); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk10); \
+ aes_lastround_4(ed, b0, b1, b2, b3, vk11, vk12);
+
+#define do_aes_4_256(ed, mcimc, b0, b1, b2, b3) \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk0); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk1); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk2); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk3); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk4); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk5); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk6); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk7); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk8); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk9); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk10); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk11); \
+ aes_round_4(ed, mcimc, b0, b1, b2, b3, vk12); \
+ aes_lastround_4(ed, b0, b1, b2, b3, vk13, vk14);
+
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) eor reg.16b, reg.16b, reg.16b;
+
+#define aes_clear_keys(nrounds) \
+ cmp nrounds, #12; \
+ CLEAR_REG(vk0); \
+ CLEAR_REG(vk1); \
+ CLEAR_REG(vk2); \
+ CLEAR_REG(vk3); \
+ CLEAR_REG(vk4); \
+ CLEAR_REG(vk5); \
+ CLEAR_REG(vk6); \
+ CLEAR_REG(vk7); \
+ CLEAR_REG(vk9); \
+ CLEAR_REG(vk8); \
+ CLEAR_REG(vk10); \
+ b.lo 1f; \
+ CLEAR_REG(vk11); \
+ CLEAR_REG(vk12); \
+ b.eq 1f; \
+ CLEAR_REG(vk13); \
+ CLEAR_REG(vk14); \
+1: ;
+
+
+/*
+ * unsigned int _gcry_aes_enc_armv8_ce(void *keysched, byte *dst,
+ * const byte *src,
+ * unsigned int nrounds);
+ */
+.align 3
+.globl _gcry_aes_enc_armv8_ce
+ELF(.type _gcry_aes_enc_armv8_ce,%function;)
+_gcry_aes_enc_armv8_ce:
+ /* input:
+ * x0: keysched
+ * x1: dst
+ * x2: src
+ * w3: nrounds
+ */
+ CFI_STARTPROC();
+
+ aes_preload_keys(x0, w3);
+
+ ld1 {v0.16b}, [x2]
+
+ b.hi .Lenc1_256
+ b.eq .Lenc1_192
+
+.Lenc1_128:
+ do_aes_one128(e, mc, v0, v0);
+
+.Lenc1_tail:
+ CLEAR_REG(vk0)
+ CLEAR_REG(vk1)
+ CLEAR_REG(vk2)
+ CLEAR_REG(vk3)
+ CLEAR_REG(vk4)
+ CLEAR_REG(vk5)
+ CLEAR_REG(vk6)
+ CLEAR_REG(vk7)
+ CLEAR_REG(vk8)
+ CLEAR_REG(vk9)
+ CLEAR_REG(vk10)
+ st1 {v0.16b}, [x1]
+ CLEAR_REG(v0)
+
+ mov x0, #0
+ ret
+
+.Lenc1_192:
+ do_aes_one192(e, mc, v0, v0);
+
+ CLEAR_REG(vk11)
+ CLEAR_REG(vk12)
+ b .Lenc1_tail
+
+.Lenc1_256:
+ do_aes_one256(e, mc, v0, v0);
+
+ CLEAR_REG(vk11)
+ CLEAR_REG(vk12)
+ CLEAR_REG(vk13)
+ CLEAR_REG(vk14)
+ b .Lenc1_tail
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_enc_armv8_ce,.-_gcry_aes_enc_armv8_ce;)
+
+
+/*
+ * unsigned int _gcry_aes_dec_armv8_ce(void *keysched, byte *dst,
+ * const byte *src,
+ * unsigned int nrounds);
+ */
+.align 3
+.globl _gcry_aes_dec_armv8_ce
+ELF(.type _gcry_aes_dec_armv8_ce,%function;)
+_gcry_aes_dec_armv8_ce:
+ /* input:
+ * x0: keysched
+ * x1: dst
+ * x2: src
+ * w3: nrounds
+ */
+ CFI_STARTPROC();
+
+ aes_preload_keys(x0, w3);
+
+ ld1 {v0.16b}, [x2]
+
+ b.hi .Ldec1_256
+ b.eq .Ldec1_192
+
+.Ldec1_128:
+ do_aes_one128(d, imc, v0, v0);
+
+.Ldec1_tail:
+ CLEAR_REG(vk0)
+ CLEAR_REG(vk1)
+ CLEAR_REG(vk2)
+ CLEAR_REG(vk3)
+ CLEAR_REG(vk4)
+ CLEAR_REG(vk5)
+ CLEAR_REG(vk6)
+ CLEAR_REG(vk7)
+ CLEAR_REG(vk8)
+ CLEAR_REG(vk9)
+ CLEAR_REG(vk10)
+ st1 {v0.16b}, [x1]
+ CLEAR_REG(v0)
+
+ mov x0, #0
+ ret
+
+.Ldec1_192:
+ do_aes_one192(d, imc, v0, v0);
+
+ CLEAR_REG(vk11)
+ CLEAR_REG(vk12)
+ b .Ldec1_tail
+
+.Ldec1_256:
+ do_aes_one256(d, imc, v0, v0);
+
+ CLEAR_REG(vk11)
+ CLEAR_REG(vk12)
+ CLEAR_REG(vk13)
+ CLEAR_REG(vk14)
+ b .Ldec1_tail
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_dec_armv8_ce,.-_gcry_aes_dec_armv8_ce;)
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_cbc_enc_armv8_ce
+ELF(.type _gcry_aes_cbc_enc_armv8_ce,%function;)
+_gcry_aes_cbc_enc_armv8_ce:
+ /* input:
+ * x0: keysched
+ * x1: outbuf
+ * x2: inbuf
+ * x3: iv
+ * x4: nblocks
+ * w5: cbc_mac
+ * w6: nrounds
+ */
+ CFI_STARTPROC();
+
+ cbz x4, .Lcbc_enc_skip
+
+ cmp w5, #0
+ ld1 {v1.16b}, [x3] /* load IV */
+ cset x5, eq
+
+ aes_preload_keys(x0, w6);
+ lsl x5, x5, #4
+
+ b.eq .Lcbc_enc_loop192
+ b.hi .Lcbc_enc_loop256
+
+#define CBC_ENC(bits) \
+ .Lcbc_enc_loop##bits: \
+ ld1 {v0.16b}, [x2], #16; /* load plaintext */ \
+ eor v1.16b, v0.16b, v1.16b; \
+ sub x4, x4, #1; \
+ \
+ do_aes_one##bits(e, mc, v1, v1); \
+ \
+ st1 {v1.16b}, [x1], x5; /* store ciphertext */ \
+ \
+ cbnz x4, .Lcbc_enc_loop##bits; \
+ b .Lcbc_enc_done;
+
+ CBC_ENC(128)
+ CBC_ENC(192)
+ CBC_ENC(256)
+
+#undef CBC_ENC
+
+.Lcbc_enc_done:
+ aes_clear_keys(w6)
+
+ st1 {v1.16b}, [x3] /* store IV */
+
+ CLEAR_REG(v1)
+ CLEAR_REG(v0)
+
+.Lcbc_enc_skip:
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_cbc_enc_armv8_ce,.-_gcry_aes_cbc_enc_armv8_ce;)
+
+/*
+ * void _gcry_aes_cbc_dec_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_cbc_dec_armv8_ce
+ELF(.type _gcry_aes_cbc_dec_armv8_ce,%function;)
+_gcry_aes_cbc_dec_armv8_ce:
+ /* input:
+ * x0: keysched
+ * x1: outbuf
+ * x2: inbuf
+ * x3: iv
+ * x4: nblocks
+ * w5: nrounds
+ */
+ CFI_STARTPROC();
+
+ cbz x4, .Lcbc_dec_skip
+
+ ld1 {v0.16b}, [x3] /* load IV */
+
+ aes_preload_keys(x0, w5);
+
+ b.eq .Lcbc_dec_entry_192
+ b.hi .Lcbc_dec_entry_256
+
+#define CBC_DEC(bits) \
+ .Lcbc_dec_entry_##bits: \
+ cmp x4, #4; \
+ b.lo .Lcbc_dec_loop_##bits; \
+ \
+ .Lcbc_dec_loop4_##bits: \
+ \
+ ld1 {v1.16b-v4.16b}, [x2], #64; /* load ciphertext */ \
+ sub x4, x4, #4; \
+ mov v5.16b, v1.16b; \
+ mov v6.16b, v2.16b; \
+ mov v7.16b, v3.16b; \
+ mov v16.16b, v4.16b; \
+ cmp x4, #4; \
+ \
+ do_aes_4_##bits(d, imc, v1, v2, v3, v4); \
+ \
+ eor v1.16b, v1.16b, v0.16b; \
+ eor v2.16b, v2.16b, v5.16b; \
+ st1 {v1.16b-v2.16b}, [x1], #32; /* store plaintext */ \
+ eor v3.16b, v3.16b, v6.16b; \
+ eor v4.16b, v4.16b, v7.16b; \
+ mov v0.16b, v16.16b; /* next IV */ \
+ st1 {v3.16b-v4.16b}, [x1], #32; /* store plaintext */ \
+ \
+ b.hs .Lcbc_dec_loop4_##bits; \
+ CLEAR_REG(v3); \
+ CLEAR_REG(v4); \
+ CLEAR_REG(v5); \
+ CLEAR_REG(v6); \
+ CLEAR_REG(v7); \
+ CLEAR_REG(v16); \
+ cbz x4, .Lcbc_dec_done; \
+ \
+ .Lcbc_dec_loop_##bits: \
+ ld1 {v1.16b}, [x2], #16; /* load ciphertext */ \
+ sub x4, x4, #1; \
+ mov v2.16b, v1.16b; \
+ \
+ do_aes_one##bits(d, imc, v1, v1); \
+ \
+ eor v1.16b, v1.16b, v0.16b; \
+ mov v0.16b, v2.16b; \
+ st1 {v1.16b}, [x1], #16; /* store plaintext */ \
+ \
+ cbnz x4, .Lcbc_dec_loop_##bits; \
+ b .Lcbc_dec_done;
+
+ CBC_DEC(128)
+ CBC_DEC(192)
+ CBC_DEC(256)
+
+#undef CBC_DEC
+
+.Lcbc_dec_done:
+ aes_clear_keys(w5)
+
+ st1 {v0.16b}, [x3] /* store IV */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+ CLEAR_REG(v2)
+
+.Lcbc_dec_skip:
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_cbc_dec_armv8_ce,.-_gcry_aes_cbc_dec_armv8_ce;)
+
+
+/*
+ * void _gcry_aes_ctr_enc_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_ctr_enc_armv8_ce
+ELF(.type _gcry_aes_ctr_enc_armv8_ce,%function;)
+_gcry_aes_ctr_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * x4: nblocks
+ * w5: nrounds
+ */
+ CFI_STARTPROC();
+
+ cbz x4, .Lctr_enc_skip
+
+ mov x6, #1
+ movi v16.16b, #0
+ mov v16.D[1], x6
+
+ /* load IV */
+ ldp x9, x10, [x3]
+ ld1 {v0.16b}, [x3]
+ rev x9, x9
+ rev x10, x10
+
+ aes_preload_keys(x0, w5);
+
+ b.eq .Lctr_enc_entry_192
+ b.hi .Lctr_enc_entry_256
+
+#define CTR_ENC(bits) \
+ .Lctr_enc_entry_##bits: \
+ cmp x4, #4; \
+ b.lo .Lctr_enc_loop_##bits; \
+ \
+ .Lctr_enc_loop4_##bits: \
+ cmp x10, #0xfffffffffffffffc; \
+ sub x4, x4, #4; \
+ b.lo .Lctr_enc_loop4_##bits##_nocarry; \
+ \
+ adds x10, x10, #1; \
+ mov v1.16b, v0.16b; \
+ adc x9, x9, xzr; \
+ mov v2.D[1], x10; \
+ mov v2.D[0], x9; \
+ \
+ adds x10, x10, #1; \
+ rev64 v2.16b, v2.16b; \
+ adc x9, x9, xzr; \
+ mov v3.D[1], x10; \
+ mov v3.D[0], x9; \
+ \
+ adds x10, x10, #1; \
+ rev64 v3.16b, v3.16b; \
+ adc x9, x9, xzr; \
+ mov v4.D[1], x10; \
+ mov v4.D[0], x9; \
+ \
+ adds x10, x10, #1; \
+ rev64 v4.16b, v4.16b; \
+ adc x9, x9, xzr; \
+ mov v0.D[1], x10; \
+ mov v0.D[0], x9; \
+ rev64 v0.16b, v0.16b; \
+ \
+ b .Lctr_enc_loop4_##bits##_store_ctr; \
+ \
+ .Lctr_enc_loop4_##bits##_nocarry: \
+ \
+ add v3.2d, v16.2d, v16.2d; /* 2 */ \
+ rev64 v6.16b, v0.16b; \
+ add x10, x10, #4; \
+ add v4.2d, v3.2d, v16.2d; /* 3 */ \
+ add v0.2d, v3.2d, v3.2d; /* 4 */ \
+ rev64 v1.16b, v6.16b; \
+ add v2.2d, v6.2d, v16.2d; \
+ add v3.2d, v6.2d, v3.2d; \
+ add v4.2d, v6.2d, v4.2d; \
+ add v0.2d, v6.2d, v0.2d; \
+ rev64 v2.16b, v2.16b; \
+ rev64 v3.16b, v3.16b; \
+ rev64 v0.16b, v0.16b; \
+ rev64 v4.16b, v4.16b; \
+ \
+ .Lctr_enc_loop4_##bits##_store_ctr: \
+ \
+ st1 {v0.16b}, [x3]; \
+ cmp x4, #4; \
+ ld1 {v5.16b-v7.16b}, [x2], #48; /* preload ciphertext */ \
+ \
+ do_aes_4_##bits(e, mc, v1, v2, v3, v4); \
+ \
+ eor v1.16b, v1.16b, v5.16b; \
+ ld1 {v5.16b}, [x2], #16; /* load ciphertext */ \
+ eor v2.16b, v2.16b, v6.16b; \
+ eor v3.16b, v3.16b, v7.16b; \
+ eor v4.16b, v4.16b, v5.16b; \
+ st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \
+ \
+ b.hs .Lctr_enc_loop4_##bits; \
+ CLEAR_REG(v3); \
+ CLEAR_REG(v4); \
+ CLEAR_REG(v5); \
+ CLEAR_REG(v6); \
+ CLEAR_REG(v7); \
+ cbz x4, .Lctr_enc_done; \
+ \
+ .Lctr_enc_loop_##bits: \
+ \
+ adds x10, x10, #1; \
+ mov v1.16b, v0.16b; \
+ adc x9, x9, xzr; \
+ mov v0.D[1], x10; \
+ mov v0.D[0], x9; \
+ sub x4, x4, #1; \
+ ld1 {v2.16b}, [x2], #16; /* load ciphertext */ \
+ rev64 v0.16b, v0.16b; \
+ \
+ do_aes_one##bits(e, mc, v1, v1); \
+ \
+ eor v1.16b, v2.16b, v1.16b; \
+ st1 {v1.16b}, [x1], #16; /* store plaintext */ \
+ \
+ cbnz x4, .Lctr_enc_loop_##bits; \
+ b .Lctr_enc_done;
+
+ CTR_ENC(128)
+ CTR_ENC(192)
+ CTR_ENC(256)
+
+#undef CTR_ENC
+
+.Lctr_enc_done:
+ aes_clear_keys(w5)
+
+ st1 {v0.16b}, [x3] /* store IV */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+ CLEAR_REG(v2)
+
+.Lctr_enc_skip:
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_ctr_enc_armv8_ce,.-_gcry_aes_ctr_enc_armv8_ce;)
+
+
+/*
+ * void _gcry_aes_cfb_enc_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_cfb_enc_armv8_ce
+ELF(.type _gcry_aes_cfb_enc_armv8_ce,%function;)
+_gcry_aes_cfb_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * x4: nblocks
+ * w5: nrounds
+ */
+ CFI_STARTPROC();
+
+ cbz x4, .Lcfb_enc_skip
+
+ /* load IV */
+ ld1 {v0.16b}, [x3]
+
+ aes_preload_keys(x0, w5);
+
+ b.eq .Lcfb_enc_entry_192
+ b.hi .Lcfb_enc_entry_256
+
+#define CFB_ENC(bits) \
+ .Lcfb_enc_entry_##bits: \
+ .Lcfb_enc_loop_##bits: \
+ ld1 {v1.16b}, [x2], #16; /* load plaintext */ \
+ sub x4, x4, #1; \
+ \
+ do_aes_one##bits(e, mc, v0, v0); \
+ \
+ eor v0.16b, v1.16b, v0.16b; \
+ st1 {v0.16b}, [x1], #16; /* store ciphertext */ \
+ \
+ cbnz x4, .Lcfb_enc_loop_##bits; \
+ b .Lcfb_enc_done;
+
+ CFB_ENC(128)
+ CFB_ENC(192)
+ CFB_ENC(256)
+
+#undef CFB_ENC
+
+.Lcfb_enc_done:
+ aes_clear_keys(w5)
+
+ st1 {v0.16b}, [x3] /* store IV */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+
+.Lcfb_enc_skip:
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_cfb_enc_armv8_ce,.-_gcry_aes_cfb_enc_armv8_ce;)
+
+
+/*
+ * void _gcry_aes_cfb_dec_armv8_ce (const void *keysched,
+ * unsigned char *outbuf,
+ * const unsigned char *inbuf,
+ * unsigned char *iv, unsigned int nrounds);
+ */
+
+.align 3
+.globl _gcry_aes_cfb_dec_armv8_ce
+ELF(.type _gcry_aes_cfb_dec_armv8_ce,%function;)
+_gcry_aes_cfb_dec_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: iv
+ * x4: nblocks
+ * w5: nrounds
+ */
+ CFI_STARTPROC();
+
+ cbz x4, .Lcfb_dec_skip
+
+ /* load IV */
+ ld1 {v0.16b}, [x3]
+
+ aes_preload_keys(x0, w5);
+
+ b.eq .Lcfb_dec_entry_192
+ b.hi .Lcfb_dec_entry_256
+
+#define CFB_DEC(bits) \
+ .Lcfb_dec_entry_##bits: \
+ cmp x4, #4; \
+ b.lo .Lcfb_dec_loop_##bits; \
+ \
+ .Lcfb_dec_loop4_##bits: \
+ \
+ ld1 {v2.16b-v4.16b}, [x2], #48; /* load ciphertext */ \
+ mov v1.16b, v0.16b; \
+ sub x4, x4, #4; \
+ cmp x4, #4; \
+ mov v5.16b, v2.16b; \
+ mov v6.16b, v3.16b; \
+ mov v7.16b, v4.16b; \
+ ld1 {v0.16b}, [x2], #16; /* load next IV / ciphertext */ \
+ \
+ do_aes_4_##bits(e, mc, v1, v2, v3, v4); \
+ \
+ eor v1.16b, v1.16b, v5.16b; \
+ eor v2.16b, v2.16b, v6.16b; \
+ eor v3.16b, v3.16b, v7.16b; \
+ eor v4.16b, v4.16b, v0.16b; \
+ st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \
+ \
+ b.hs .Lcfb_dec_loop4_##bits; \
+ CLEAR_REG(v3); \
+ CLEAR_REG(v4); \
+ CLEAR_REG(v5); \
+ CLEAR_REG(v6); \
+ CLEAR_REG(v7); \
+ cbz x4, .Lcfb_dec_done; \
+ \
+ .Lcfb_dec_loop_##bits: \
+ \
+ ld1 {v1.16b}, [x2], #16; /* load ciphertext */ \
+ \
+ sub x4, x4, #1; \
+ \
+ do_aes_one##bits(e, mc, v0, v0); \
+ \
+ eor v2.16b, v1.16b, v0.16b; \
+ mov v0.16b, v1.16b; \
+ st1 {v2.16b}, [x1], #16; /* store plaintext */ \
+ \
+ cbnz x4, .Lcfb_dec_loop_##bits; \
+ b .Lcfb_dec_done;
+
+ CFB_DEC(128)
+ CFB_DEC(192)
+ CFB_DEC(256)
+
+#undef CFB_DEC
+
+.Lcfb_dec_done:
+ aes_clear_keys(w5)
+
+ st1 {v0.16b}, [x3] /* store IV */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+ CLEAR_REG(v2)
+
+.Lcfb_dec_skip:
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_cfb_dec_armv8_ce,.-_gcry_aes_cfb_dec_armv8_ce;)
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_ocb_enc_armv8_ce
+ELF(.type _gcry_aes_ocb_enc_armv8_ce,%function;)
+_gcry_aes_ocb_enc_armv8_ce:
+ /* input:
+ * x0: keysched
+ * x1: outbuf
+ * x2: inbuf
+ * x3: offset
+ * x4: checksum
+ * x5: Ltable
+ * x6: nblocks (0 < nblocks <= 32)
+ * w7: nrounds
+ * %st+0: blkn => w12
+ */
+ CFI_STARTPROC();
+
+ ldr w12, [sp]
+ ld1 {v0.16b}, [x3] /* load offset */
+ ld1 {v16.16b}, [x4] /* load checksum */
+
+ aes_preload_keys(x0, w7);
+
+ b.eq .Locb_enc_entry_192
+ b.hi .Locb_enc_entry_256
+
+#define OCB_ENC(bits, ...) \
+ .Locb_enc_entry_##bits: \
+ cmp x6, #4; \
+ add x12, x12, #1; \
+ b.lo .Locb_enc_loop_##bits; \
+ \
+ .Locb_enc_loop4_##bits: \
+ \
+ /* 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) */ \
+ \
+ add w9, w12, #1; \
+ add w10, w12, #2; \
+ add w11, w12, #3; \
+ rbit w8, w12; \
+ add w12, w12, #4; \
+ rbit w9, w9; \
+ rbit w10, w10; \
+ rbit w11, w11; \
+ clz w8, w8; /* ntz(i+0) */ \
+ clz w9, w9; /* ntz(i+1) */ \
+ clz w10, w10; /* ntz(i+2) */ \
+ clz w11, w11; /* ntz(i+3) */ \
+ add x8, x5, x8, lsl #4; \
+ ld1 {v1.16b-v4.16b}, [x2], #64; /* load P_i+<0-3> */ \
+ add x9, x5, x9, lsl #4; \
+ add x10, x5, x10, lsl #4; \
+ add x11, x5, x11, lsl #4; \
+ \
+ sub x6, x6, #4; \
+ \
+ ld1 {v5.16b}, [x8]; /* load L_{ntz(i+0)} */ \
+ eor v16.16b, v16.16b, v1.16b; /* Checksum_i+0 */ \
+ ld1 {v6.16b}, [x9]; /* load L_{ntz(i+1)} */ \
+ eor v16.16b, v16.16b, v2.16b; /* Checksum_i+1 */ \
+ ld1 {v7.16b}, [x10]; /* load L_{ntz(i+2)} */ \
+ eor v16.16b, v16.16b, v3.16b; /* Checksum_i+2 */ \
+ eor v5.16b, v5.16b, v0.16b; /* Offset_i+0 */ \
+ ld1 {v0.16b}, [x11]; /* load L_{ntz(i+3)} */ \
+ eor v16.16b, v16.16b, v4.16b; /* Checksum_i+3 */ \
+ eor v6.16b, v6.16b, v5.16b; /* Offset_i+1 */ \
+ eor v1.16b, v1.16b, v5.16b; /* P_i+0 xor Offset_i+0 */ \
+ eor v7.16b, v7.16b, v6.16b; /* Offset_i+2 */ \
+ eor v2.16b, v2.16b, v6.16b; /* P_i+1 xor Offset_i+1 */ \
+ eor v0.16b, v0.16b, v7.16b; /* Offset_i+3 */ \
+ cmp x6, #4; \
+ eor v3.16b, v3.16b, v7.16b; /* P_i+2 xor Offset_i+2 */ \
+ eor v4.16b, v4.16b, v0.16b; /* P_i+3 xor Offset_i+3 */ \
+ \
+ do_aes_4_##bits(e, mc, v1, v2, v3, v4); \
+ \
+ eor v1.16b, v1.16b, v5.16b; /* xor Offset_i+0 */ \
+ eor v2.16b, v2.16b, v6.16b; /* xor Offset_i+1 */ \
+ eor v3.16b, v3.16b, v7.16b; /* xor Offset_i+2 */ \
+ eor v4.16b, v4.16b, v0.16b; /* xor Offset_i+3 */ \
+ st1 {v1.16b-v4.16b}, [x1], #64; \
+ \
+ b.hs .Locb_enc_loop4_##bits; \
+ CLEAR_REG(v3); \
+ CLEAR_REG(v4); \
+ CLEAR_REG(v5); \
+ CLEAR_REG(v6); \
+ CLEAR_REG(v7); \
+ cbz x6, .Locb_enc_done; \
+ \
+ .Locb_enc_loop_##bits: \
+ \
+ /* 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) */ \
+ \
+ rbit x8, x12; \
+ add x12, x12, #1; \
+ clz x8, x8; /* ntz(i) */ \
+ add x8, x5, x8, lsl #4; \
+ \
+ ld1 {v1.16b}, [x2], #16; /* load plaintext */ \
+ ld1 {v2.16b}, [x8]; /* load L_{ntz(i)} */ \
+ sub x6, x6, #1; \
+ eor v0.16b, v0.16b, v2.16b; \
+ eor v16.16b, v16.16b, v1.16b; \
+ eor v1.16b, v1.16b, v0.16b; \
+ \
+ do_aes_one##bits(e, mc, v1, v1); \
+ \
+ eor v1.16b, v1.16b, v0.16b; \
+ st1 {v1.16b}, [x1], #16; /* store ciphertext */ \
+ \
+ cbnz x6, .Locb_enc_loop_##bits; \
+ b .Locb_enc_done;
+
+ OCB_ENC(128)
+ OCB_ENC(192)
+ OCB_ENC(256)
+
+#undef OCB_ENC
+
+.Locb_enc_done:
+ aes_clear_keys(w7)
+
+ st1 {v16.16b}, [x4] /* store checksum */
+ st1 {v0.16b}, [x3] /* store offset */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+ CLEAR_REG(v2)
+ CLEAR_REG(v16)
+
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_ocb_enc_armv8_ce,.-_gcry_aes_ocb_enc_armv8_ce;)
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_ocb_dec_armv8_ce
+ELF(.type _gcry_aes_ocb_dec_armv8_ce,%function;)
+_gcry_aes_ocb_dec_armv8_ce:
+ /* input:
+ * x0: keysched
+ * x1: outbuf
+ * x2: inbuf
+ * x3: offset
+ * x4: checksum
+ * x5: Ltable
+ * x6: nblocks (0 < nblocks <= 32)
+ * w7: nrounds
+ * %st+0: blkn => w12
+ */
+ CFI_STARTPROC();
+
+ ldr w12, [sp]
+ ld1 {v0.16b}, [x3] /* load offset */
+ ld1 {v16.16b}, [x4] /* load checksum */
+
+ aes_preload_keys(x0, w7);
+
+ b.eq .Locb_dec_entry_192
+ b.hi .Locb_dec_entry_256
+
+#define OCB_DEC(bits) \
+ .Locb_dec_entry_##bits: \
+ cmp x6, #4; \
+ add w12, w12, #1; \
+ b.lo .Locb_dec_loop_##bits; \
+ \
+ .Locb_dec_loop4_##bits: \
+ \
+ /* 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 */ \
+ \
+ add w9, w12, #1; \
+ add w10, w12, #2; \
+ add w11, w12, #3; \
+ rbit w8, w12; \
+ add w12, w12, #4; \
+ rbit w9, w9; \
+ rbit w10, w10; \
+ rbit w11, w11; \
+ clz w8, w8; /* ntz(i+0) */ \
+ clz w9, w9; /* ntz(i+1) */ \
+ clz w10, w10; /* ntz(i+2) */ \
+ clz w11, w11; /* ntz(i+3) */ \
+ add x8, x5, x8, lsl #4; \
+ ld1 {v1.16b-v4.16b}, [x2], #64; /* load C_i+<0-3> */ \
+ add x9, x5, x9, lsl #4; \
+ add x10, x5, x10, lsl #4; \
+ add x11, x5, x11, lsl #4; \
+ \
+ sub x6, x6, #4; \
+ \
+ ld1 {v5.16b}, [x8]; /* load L_{ntz(i+0)} */ \
+ ld1 {v6.16b}, [x9]; /* load L_{ntz(i+1)} */ \
+ ld1 {v7.16b}, [x10]; /* load L_{ntz(i+2)} */ \
+ eor v5.16b, v5.16b, v0.16b; /* Offset_i+0 */ \
+ ld1 {v0.16b}, [x11]; /* load L_{ntz(i+3)} */ \
+ eor v6.16b, v6.16b, v5.16b; /* Offset_i+1 */ \
+ eor v1.16b, v1.16b, v5.16b; /* C_i+0 xor Offset_i+0 */ \
+ eor v7.16b, v7.16b, v6.16b; /* Offset_i+2 */ \
+ eor v2.16b, v2.16b, v6.16b; /* C_i+1 xor Offset_i+1 */ \
+ eor v0.16b, v0.16b, v7.16b; /* Offset_i+3 */ \
+ cmp x6, #4; \
+ eor v3.16b, v3.16b, v7.16b; /* C_i+2 xor Offset_i+2 */ \
+ eor v4.16b, v4.16b, v0.16b; /* C_i+3 xor Offset_i+3 */ \
+ \
+ do_aes_4_##bits(d, imc, v1, v2, v3, v4); \
+ \
+ eor v1.16b, v1.16b, v5.16b; /* xor Offset_i+0 */ \
+ eor v2.16b, v2.16b, v6.16b; /* xor Offset_i+1 */ \
+ eor v16.16b, v16.16b, v1.16b; /* Checksum_i+0 */ \
+ eor v3.16b, v3.16b, v7.16b; /* xor Offset_i+2 */ \
+ eor v16.16b, v16.16b, v2.16b; /* Checksum_i+1 */ \
+ eor v4.16b, v4.16b, v0.16b; /* xor Offset_i+3 */ \
+ eor v16.16b, v16.16b, v3.16b; /* Checksum_i+2 */ \
+ eor v16.16b, v16.16b, v4.16b; /* Checksum_i+3 */ \
+ st1 {v1.16b-v4.16b}, [x1], #64; \
+ \
+ b.hs .Locb_dec_loop4_##bits; \
+ CLEAR_REG(v3); \
+ CLEAR_REG(v4); \
+ CLEAR_REG(v5); \
+ CLEAR_REG(v6); \
+ CLEAR_REG(v7); \
+ cbz x6, .Locb_dec_done; \
+ \
+ .Locb_dec_loop_##bits: \
+ \
+ /* 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 */ \
+ \
+ rbit w8, w12; \
+ add w12, w12, #1; \
+ clz w8, w8; /* ntz(i) */ \
+ add x8, x5, x8, lsl #4; \
+ \
+ ld1 {v1.16b}, [x2], #16; /* load ciphertext */ \
+ ld1 {v2.16b}, [x8]; /* load L_{ntz(i)} */ \
+ sub x6, x6, #1; \
+ eor v0.16b, v0.16b, v2.16b; \
+ eor v1.16b, v1.16b, v0.16b; \
+ \
+ do_aes_one##bits(d, imc, v1, v1) \
+ \
+ eor v1.16b, v1.16b, v0.16b; \
+ st1 {v1.16b}, [x1], #16; /* store plaintext */ \
+ eor v16.16b, v16.16b, v1.16b; \
+ \
+ cbnz x6, .Locb_dec_loop_##bits; \
+ b .Locb_dec_done;
+
+ OCB_DEC(128)
+ OCB_DEC(192)
+ OCB_DEC(256)
+
+#undef OCB_DEC
+
+.Locb_dec_done:
+ aes_clear_keys(w7)
+
+ st1 {v16.16b}, [x4] /* store checksum */
+ st1 {v0.16b}, [x3] /* store offset */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+ CLEAR_REG(v2)
+ CLEAR_REG(v16)
+
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_ocb_dec_armv8_ce,.-_gcry_aes_ocb_dec_armv8_ce;)
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_ocb_auth_armv8_ce
+ELF(.type _gcry_aes_ocb_auth_armv8_ce,%function;)
+_gcry_aes_ocb_auth_armv8_ce:
+ /* input:
+ * x0: keysched
+ * x1: abuf
+ * x2: offset => x3
+ * x3: checksum => x4
+ * x4: Ltable => x5
+ * x5: nblocks => x6 (0 < nblocks <= 32)
+ * w6: nrounds => w7
+ * w7: blkn => w12
+ */
+ CFI_STARTPROC();
+
+ mov w12, w7
+ mov w7, w6
+ mov x6, x5
+ mov x5, x4
+ mov x4, x3
+ mov x3, x2
+
+ aes_preload_keys(x0, w7);
+
+ ld1 {v0.16b}, [x3] /* load offset */
+ ld1 {v16.16b}, [x4] /* load checksum */
+
+ beq .Locb_auth_entry_192
+ bhi .Locb_auth_entry_256
+
+#define OCB_AUTH(bits) \
+ .Locb_auth_entry_##bits: \
+ cmp x6, #4; \
+ add w12, w12, #1; \
+ b.lo .Locb_auth_loop_##bits; \
+ \
+ .Locb_auth_loop4_##bits: \
+ \
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ \
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ \
+ \
+ add w9, w12, #1; \
+ add w10, w12, #2; \
+ add w11, w12, #3; \
+ rbit w8, w12; \
+ add w12, w12, #4; \
+ rbit w9, w9; \
+ rbit w10, w10; \
+ rbit w11, w11; \
+ clz w8, w8; /* ntz(i+0) */ \
+ clz w9, w9; /* ntz(i+1) */ \
+ clz w10, w10; /* ntz(i+2) */ \
+ clz w11, w11; /* ntz(i+3) */ \
+ add x8, x5, x8, lsl #4; \
+ ld1 {v1.16b-v4.16b}, [x1], #64; /* load A_i+<0-3> */ \
+ add x9, x5, x9, lsl #4; \
+ add x10, x5, x10, lsl #4; \
+ add x11, x5, x11, lsl #4; \
+ \
+ sub x6, x6, #4; \
+ \
+ ld1 {v5.16b}, [x8]; /* load L_{ntz(i+0)} */ \
+ ld1 {v6.16b}, [x9]; /* load L_{ntz(i+1)} */ \
+ ld1 {v7.16b}, [x10]; /* load L_{ntz(i+2)} */ \
+ eor v5.16b, v5.16b, v0.16b; /* Offset_i+0 */ \
+ ld1 {v0.16b}, [x11]; /* load L_{ntz(i+3)} */ \
+ eor v6.16b, v6.16b, v5.16b; /* Offset_i+1 */ \
+ eor v1.16b, v1.16b, v5.16b; /* A_i+0 xor Offset_i+0 */ \
+ eor v7.16b, v7.16b, v6.16b; /* Offset_i+2 */ \
+ eor v2.16b, v2.16b, v6.16b; /* A_i+1 xor Offset_i+1 */ \
+ eor v0.16b, v0.16b, v7.16b; /* Offset_i+3 */ \
+ cmp x6, #4; \
+ eor v3.16b, v3.16b, v7.16b; /* A_i+2 xor Offset_i+2 */ \
+ eor v4.16b, v4.16b, v0.16b; /* A_i+3 xor Offset_i+3 */ \
+ \
+ do_aes_4_##bits(e, mc, v1, v2, v3, v4); \
+ \
+ eor v1.16b, v1.16b, v2.16b; \
+ eor v16.16b, v16.16b, v3.16b; \
+ eor v1.16b, v1.16b, v4.16b; \
+ eor v16.16b, v16.16b, v1.16b; \
+ \
+ b.hs .Locb_auth_loop4_##bits; \
+ CLEAR_REG(v3); \
+ CLEAR_REG(v4); \
+ CLEAR_REG(v5); \
+ CLEAR_REG(v6); \
+ CLEAR_REG(v7); \
+ cbz x6, .Locb_auth_done; \
+ \
+ .Locb_auth_loop_##bits: \
+ \
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ \
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ \
+ \
+ rbit w8, w12; \
+ add w12, w12, #1; \
+ clz w8, w8; /* ntz(i) */ \
+ add x8, x5, x8, lsl #4; \
+ \
+ ld1 {v1.16b}, [x1], #16; /* load aadtext */ \
+ ld1 {v2.16b}, [x8]; /* load L_{ntz(i)} */ \
+ sub x6, x6, #1; \
+ eor v0.16b, v0.16b, v2.16b; \
+ eor v1.16b, v1.16b, v0.16b; \
+ \
+ do_aes_one##bits(e, mc, v1, v1) \
+ \
+ eor v16.16b, v16.16b, v1.16b; \
+ \
+ cbnz x6, .Locb_auth_loop_##bits; \
+ b .Locb_auth_done;
+
+ OCB_AUTH(128)
+ OCB_AUTH(192)
+ OCB_AUTH(256)
+
+#undef OCB_AUTH
+
+.Locb_auth_done:
+ aes_clear_keys(w7)
+
+ st1 {v16.16b}, [x4] /* store checksum */
+ st1 {v0.16b}, [x3] /* store offset */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+ CLEAR_REG(v2)
+ CLEAR_REG(v16)
+
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_ocb_auth_armv8_ce,.-_gcry_aes_ocb_auth_armv8_ce;)
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_xts_enc_armv8_ce
+ELF(.type _gcry_aes_xts_enc_armv8_ce,%function;)
+_gcry_aes_xts_enc_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: tweak
+ * x4: nblocks
+ * w5: nrounds
+ */
+ CFI_STARTPROC();
+
+ cbz x4, .Lxts_enc_skip
+
+ /* load tweak */
+ ld1 {v0.16b}, [x3]
+
+ /* load gfmul mask */
+ mov x6, #0x87
+ mov x7, #0x01
+ mov v16.D[0], x6
+ mov v16.D[1], x7
+
+ aes_preload_keys(x0, w5);
+
+ b.eq .Lxts_enc_entry_192
+ b.hi .Lxts_enc_entry_256
+
+#define XTS_ENC(bits) \
+ .Lxts_enc_entry_##bits: \
+ cmp x4, #4; \
+ b.lo .Lxts_enc_loop_##bits; \
+ \
+ .Lxts_enc_loop4_##bits: \
+ \
+ ext v4.16b, v0.16b, v0.16b, #8; \
+ \
+ sshr v2.2d, v4.2d, #63; \
+ add v5.2d, v0.2d, v0.2d; \
+ and v2.16b, v2.16b, v16.16b; \
+ add v4.2d, v4.2d, v4.2d; \
+ eor v5.16b, v5.16b, v2.16b; \
+ \
+ sshr v2.2d, v4.2d, #63; \
+ add v6.2d, v5.2d, v5.2d; \
+ and v2.16b, v2.16b, v16.16b; \
+ add v4.2d, v4.2d, v4.2d; \
+ eor v6.16b, v6.16b, v2.16b; \
+ \
+ sshr v2.2d, v4.2d, #63; \
+ add v7.2d, v6.2d, v6.2d; \
+ and v2.16b, v2.16b, v16.16b; \
+ add v4.2d, v4.2d, v4.2d; \
+ eor v7.16b, v7.16b, v2.16b; \
+ \
+ sshr v2.2d, v4.2d, #63; \
+ add v3.2d, v7.2d, v7.2d; \
+ and v2.16b, v2.16b, v16.16b; \
+ add v4.2d, v4.2d, v4.2d; \
+ eor v3.16b, v3.16b, v2.16b; \
+ ld1 {v1.16b-v2.16b}, [x2], #32; /* load plaintext */ \
+ st1 {v3.16b}, [x3]; \
+ sub x4, x4, #4; \
+ eor v1.16b, v1.16b, v0.16b; \
+ \
+ ld1 {v3.16b-v4.16b}, [x2], #32; /* load plaintext */ \
+ cmp x4, #4; \
+ eor v2.16b, v2.16b, v5.16b; \
+ eor v3.16b, v3.16b, v6.16b; \
+ eor v4.16b, v4.16b, v7.16b; \
+ \
+ do_aes_4_##bits(e, mc, v1, v2, v3, v4); \
+ \
+ eor v1.16b, v1.16b, v0.16b; \
+ ld1 {v0.16b}, [x3]; \
+ eor v2.16b, v2.16b, v5.16b; \
+ eor v3.16b, v3.16b, v6.16b; \
+ eor v4.16b, v4.16b, v7.16b; \
+ st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \
+ \
+ b.hs .Lxts_enc_loop4_##bits; \
+ CLEAR_REG(v3); \
+ CLEAR_REG(v4); \
+ CLEAR_REG(v5); \
+ CLEAR_REG(v6); \
+ CLEAR_REG(v7); \
+ cbz x4, .Lxts_enc_done; \
+ \
+ .Lxts_enc_loop_##bits: \
+ \
+ ld1 {v1.16b}, [x2], #16; /* load plaintext */ \
+ ext v3.16b, v0.16b, v0.16b, #8; \
+ mov v2.16b, v0.16b; \
+ sshr v3.2d, v3.2d, #63; \
+ add v0.2d, v0.2d, v0.2d; \
+ and v3.16b, v3.16b, v16.16b; \
+ eor v1.16b, v1.16b, v2.16b; \
+ eor v0.16b, v0.16b, v3.16b; \
+ sub x4, x4, #1; \
+ \
+ do_aes_one##bits(e, mc, v1, v1); \
+ \
+ eor v1.16b, v1.16b, v2.16b; \
+ st1 {v1.16b}, [x1], #16; /* store ciphertext */ \
+ \
+ cbnz x4, .Lxts_enc_loop_##bits; \
+ b .Lxts_enc_done;
+
+ XTS_ENC(128)
+ XTS_ENC(192)
+ XTS_ENC(256)
+
+#undef XTS_ENC
+
+.Lxts_enc_done:
+ aes_clear_keys(w5)
+
+ st1 {v0.16b}, [x3] /* store tweak */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+ CLEAR_REG(v2)
+
+.Lxts_enc_skip:
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce;)
+
+
+/*
+ * 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);
+ */
+
+.align 3
+.globl _gcry_aes_xts_dec_armv8_ce
+ELF(.type _gcry_aes_xts_dec_armv8_ce,%function;)
+_gcry_aes_xts_dec_armv8_ce:
+ /* input:
+ * r0: keysched
+ * r1: outbuf
+ * r2: inbuf
+ * r3: tweak
+ * x4: nblocks
+ * w5: nrounds
+ */
+ CFI_STARTPROC();
+
+ cbz x4, .Lxts_dec_skip
+
+ /* load tweak */
+ ld1 {v0.16b}, [x3]
+
+ /* load gfmul mask */
+ mov x6, #0x87
+ mov x7, #0x01
+ mov v16.D[0], x6
+ mov v16.D[1], x7
+
+ aes_preload_keys(x0, w5);
+
+ b.eq .Lxts_dec_entry_192
+ b.hi .Lxts_dec_entry_256
+
+#define XTS_DEC(bits) \
+ .Lxts_dec_entry_##bits: \
+ cmp x4, #4; \
+ b.lo .Lxts_dec_loop_##bits; \
+ \
+ .Lxts_dec_loop4_##bits: \
+ \
+ ext v4.16b, v0.16b, v0.16b, #8; \
+ \
+ sshr v2.2d, v4.2d, #63; \
+ add v5.2d, v0.2d, v0.2d; \
+ and v2.16b, v2.16b, v16.16b; \
+ add v4.2d, v4.2d, v4.2d; \
+ eor v5.16b, v5.16b, v2.16b; \
+ \
+ sshr v2.2d, v4.2d, #63; \
+ add v6.2d, v5.2d, v5.2d; \
+ and v2.16b, v2.16b, v16.16b; \
+ add v4.2d, v4.2d, v4.2d; \
+ eor v6.16b, v6.16b, v2.16b; \
+ \
+ sshr v2.2d, v4.2d, #63; \
+ add v7.2d, v6.2d, v6.2d; \
+ and v2.16b, v2.16b, v16.16b; \
+ add v4.2d, v4.2d, v4.2d; \
+ eor v7.16b, v7.16b, v2.16b; \
+ \
+ sshr v2.2d, v4.2d, #63; \
+ add v3.2d, v7.2d, v7.2d; \
+ and v2.16b, v2.16b, v16.16b; \
+ add v4.2d, v4.2d, v4.2d; \
+ eor v3.16b, v3.16b, v2.16b; \
+ ld1 {v1.16b-v2.16b}, [x2], #32; /* load plaintext */ \
+ st1 {v3.16b}, [x3]; \
+ sub x4, x4, #4; \
+ eor v1.16b, v1.16b, v0.16b; \
+ \
+ ld1 {v3.16b-v4.16b}, [x2], #32; /* load plaintext */ \
+ cmp x4, #4; \
+ eor v2.16b, v2.16b, v5.16b; \
+ eor v3.16b, v3.16b, v6.16b; \
+ eor v4.16b, v4.16b, v7.16b; \
+ \
+ do_aes_4_##bits(d, imc, v1, v2, v3, v4); \
+ \
+ eor v1.16b, v1.16b, v0.16b; \
+ ld1 {v0.16b}, [x3]; \
+ eor v2.16b, v2.16b, v5.16b; \
+ eor v3.16b, v3.16b, v6.16b; \
+ eor v4.16b, v4.16b, v7.16b; \
+ st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \
+ \
+ b.hs .Lxts_dec_loop4_##bits; \
+ CLEAR_REG(v3); \
+ CLEAR_REG(v4); \
+ CLEAR_REG(v5); \
+ CLEAR_REG(v6); \
+ CLEAR_REG(v7); \
+ cbz x4, .Lxts_dec_done; \
+ \
+ .Lxts_dec_loop_##bits: \
+ \
+ ld1 {v1.16b}, [x2], #16; /* load plaintext */ \
+ ext v3.16b, v0.16b, v0.16b, #8; \
+ mov v2.16b, v0.16b; \
+ sshr v3.2d, v3.2d, #63; \
+ add v0.2d, v0.2d, v0.2d; \
+ and v3.16b, v3.16b, v16.16b; \
+ eor v1.16b, v1.16b, v2.16b; \
+ eor v0.16b, v0.16b, v3.16b; \
+ sub x4, x4, #1; \
+ \
+ do_aes_one##bits(d, imc, v1, v1); \
+ \
+ eor v1.16b, v1.16b, v2.16b; \
+ st1 {v1.16b}, [x1], #16; /* store ciphertext */ \
+ \
+ cbnz x4, .Lxts_dec_loop_##bits; \
+ b .Lxts_dec_done;
+
+ XTS_DEC(128)
+ XTS_DEC(192)
+ XTS_DEC(256)
+
+#undef XTS_DEC
+
+.Lxts_dec_done:
+ aes_clear_keys(w5)
+
+ st1 {v0.16b}, [x3] /* store tweak */
+
+ CLEAR_REG(v0)
+ CLEAR_REG(v1)
+ CLEAR_REG(v2)
+
+.Lxts_dec_skip:
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce;)
+
+
+/*
+ * u32 _gcry_aes_sbox4_armv8_ce(u32 in4b);
+ */
+.align 3
+.globl _gcry_aes_sbox4_armv8_ce
+ELF(.type _gcry_aes_sbox4_armv8_ce,%function;)
+_gcry_aes_sbox4_armv8_ce:
+ /* See "Gouvêa, C. P. L. & López, J. Implementing GCM on ARMv8. Topics in
+ * Cryptology — CT-RSA 2015" for details.
+ */
+ CFI_STARTPROC();
+ movi v0.16b, #0x52
+ movi v1.16b, #0
+ mov v0.S[0], w0
+ aese v0.16b, v1.16b
+ addv s0, v0.4s
+ mov w0, v0.S[0]
+ CLEAR_REG(v0)
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_sbox4_armv8_ce,.-_gcry_aes_sbox4_armv8_ce;)
+
+
+/*
+ * void _gcry_aes_invmixcol_armv8_ce(void *dst, const void *src);
+ */
+.align 3
+.globl _gcry_aes_invmixcol_armv8_ce
+ELF(.type _gcry_aes_invmixcol_armv8_ce,%function;)
+_gcry_aes_invmixcol_armv8_ce:
+ CFI_STARTPROC();
+ ld1 {v0.16b}, [x1]
+ aesimc v0.16b, v0.16b
+ st1 {v0.16b}, [x0]
+ CLEAR_REG(v0)
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_invmixcol_armv8_ce,.-_gcry_aes_invmixcol_armv8_ce;)
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-armv8-ce.c b/comm/third_party/libgcrypt/cipher/rijndael-armv8-ce.c
new file mode 100644
index 0000000000..6e46830ee4
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-armv8-ce.c
@@ -0,0 +1,414 @@
+/* ARMv8 Crypto Extension AES for Libgcrypt
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* 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_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);
+}
+
+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/comm/third_party/libgcrypt/cipher/rijndael-internal.h b/comm/third_party/libgcrypt/cipher/rijndael-internal.h
new file mode 100644
index 0000000000..7e01f6b057
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-internal.h
@@ -0,0 +1,194 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G10_RIJNDAEL_INTERNAL_H
+#define G10_RIJNDAEL_INTERNAL_H
+
+#include "types.h" /* for byte and u32 typedefs */
+
+
+#define MAXKC (256/32)
+#define MAXROUNDS 14
+#define BLOCKSIZE (128/8)
+
+
+/* Helper macro to force alignment to 16 or 64 bytes. */
+#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# define ATTR_ALIGNED_16 __attribute__ ((aligned (16)))
+# define ATTR_ALIGNED_64 __attribute__ ((aligned (64)))
+#else
+# define ATTR_ALIGNED_16
+# define ATTR_ALIGNED_64
+#endif
+
+
+/* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */
+#undef USE_AMD64_ASM
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AMD64_ASM 1
+#endif
+
+/* USE_SSSE3 indicates whether to use SSSE3 code. */
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_SSSE3 1
+#endif
+
+/* USE_ARM_ASM indicates whether to use ARM assembly code. */
+#undef USE_ARM_ASM
+#if defined(__ARMEL__)
+# ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+# define USE_ARM_ASM 1
+# endif
+#endif
+#if defined(__AARCH64EL__)
+# ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS
+# define USE_ARM_ASM 1
+# endif
+#endif
+
+/* USE_PADLOCK indicates whether to compile the padlock specific
+ code. */
+#undef USE_PADLOCK
+#ifdef ENABLE_PADLOCK_SUPPORT
+# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)
+# define USE_PADLOCK 1
+# endif
+# endif
+#endif /* ENABLE_PADLOCK_SUPPORT */
+
+/* USE_AESNI inidicates whether to compile with Intel AES-NI code. We
+ need the vector-size attribute which seems to be available since
+ gcc 3. However, to be on the safe side we require at least gcc 4. */
+#undef USE_AESNI
+#ifdef ENABLE_AESNI_SUPPORT
+# if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
+# if __GNUC__ >= 4
+# define USE_AESNI 1
+# endif
+# endif
+#endif /* ENABLE_AESNI_SUPPORT */
+
+/* USE_ARM_CE indicates whether to enable ARMv8 Crypto Extension assembly
+ * code. */
+#undef USE_ARM_CE
+#ifdef ENABLE_ARM_CRYPTO_SUPPORT
+# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
+ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
+ && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO)
+# define USE_ARM_CE 1
+# elif defined(__AARCH64EL__) \
+ && defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) \
+ && defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+# define USE_ARM_CE 1
+# endif
+#endif /* ENABLE_ARM_CRYPTO_SUPPORT */
+
+/* USE_PPC_CRYPTO indicates whether to enable PowerPC vector crypto
+ * accelerated code. USE_PPC_CRYPTO_WITH_PPC9LE indicates whether to
+ * enable POWER9 optimized variant. */
+#undef USE_PPC_CRYPTO
+#undef USE_PPC_CRYPTO_WITH_PPC9LE
+#ifdef ENABLE_PPC_CRYPTO_SUPPORT
+# if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC)
+# if __GNUC__ >= 4
+# define USE_PPC_CRYPTO 1
+# if !defined(WORDS_BIGENDIAN) && defined(HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00)
+# define USE_PPC_CRYPTO_WITH_PPC9LE 1
+# endif
+# endif
+# endif
+#endif /* ENABLE_PPC_CRYPTO_SUPPORT */
+
+/* USE_S390X_CRYPTO indicates whether to enable zSeries code. */
+#undef USE_S390X_CRYPTO
+#if defined(HAVE_GCC_INLINE_ASM_S390X)
+# define USE_S390X_CRYPTO 1
+#endif /* USE_S390X_CRYPTO */
+
+struct RIJNDAEL_context_s;
+
+typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx,
+ unsigned char *bx,
+ const unsigned char *ax);
+typedef void (*rijndael_prefetchfn_t)(void);
+typedef void (*rijndael_prepare_decfn_t)(struct RIJNDAEL_context_s *ctx);
+
+/* Our context object. */
+typedef struct RIJNDAEL_context_s
+{
+ /* The first fields are the keyschedule arrays. This is so that
+ they are aligned on a 16 byte boundary if using gcc. This
+ alignment is required for the AES-NI code and a good idea in any
+ case. The alignment is guaranteed due to the way cipher.c
+ allocates the space for the context. The PROPERLY_ALIGNED_TYPE
+ hack is used to force a minimal alignment if not using gcc of if
+ the alignment requirement is higher that 16 bytes. */
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ byte keyschedule[MAXROUNDS+1][4][4];
+ u32 keyschedule32[MAXROUNDS+1][4];
+#ifdef USE_PADLOCK
+ /* The key as passed to the padlock engine. It is only used if
+ the padlock engine is used (USE_PADLOCK, below). */
+ unsigned char padlock_key[16] __attribute__ ((aligned (16)));
+#endif /*USE_PADLOCK*/
+ } u1;
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ byte keyschedule[MAXROUNDS+1][4][4];
+ u32 keyschedule32[MAXROUNDS+1][4];
+ } u2;
+ int rounds; /* Key-length-dependent number of rounds. */
+ unsigned int decryption_prepared:1; /* The decryption key schedule is available. */
+#ifdef USE_AESNI
+ unsigned int use_avx:1; /* AVX shall be used by AES-NI implementation. */
+ unsigned int use_avx2:1; /* AVX2 shall be used by AES-NI implementation. */
+#endif /*USE_AESNI*/
+#ifdef USE_S390X_CRYPTO
+ byte km_func;
+ byte km_func_xts;
+ byte kmc_func;
+ byte kmac_func;
+ byte kmf_func;
+ byte kmo_func;
+ byte kma_func;
+#endif /*USE_S390X_CRYPTO*/
+ rijndael_cryptfn_t encrypt_fn;
+ rijndael_cryptfn_t decrypt_fn;
+ rijndael_prefetchfn_t prefetch_enc_fn;
+ rijndael_prefetchfn_t prefetch_dec_fn;
+ rijndael_prepare_decfn_t prepare_decryption;
+} RIJNDAEL_context ATTR_ALIGNED_16;
+
+/* Macros defining alias for the keyschedules. */
+#define keyschenc u1.keyschedule
+#define keyschenc32 u1.keyschedule32
+#define keyschdec u2.keyschedule
+#define keyschdec32 u2.keyschedule32
+#define padlockkey u1.padlock_key
+
+#endif /* G10_RIJNDAEL_INTERNAL_H */
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-padlock.c b/comm/third_party/libgcrypt/cipher/rijndael-padlock.c
new file mode 100644
index 0000000000..3af214d74e
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-padlock.c
@@ -0,0 +1,110 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* 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/comm/third_party/libgcrypt/cipher/rijndael-ppc-common.h b/comm/third_party/libgcrypt/cipher/rijndael-ppc-common.h
new file mode 100644
index 0000000000..bbbeaac035
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-ppc-common.h
@@ -0,0 +1,342 @@
+/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation
+ * Copyright (C) 2019 Shawn Landden <shawn@git.icu>
+ * Copyright (C) 2019-2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project,
+ * and Cryptogams by Andy Polyakov, and if made part of a release of either
+ * or both projects, is thereafter dual-licensed under the license said project
+ * is released under.
+ */
+
+#ifndef G10_RIJNDAEL_PPC_COMMON_H
+#define G10_RIJNDAEL_PPC_COMMON_H
+
+#include <altivec.h>
+
+
+typedef vector unsigned char block;
+
+typedef union
+{
+ u32 data32[4];
+} __attribute__((packed, aligned(1), may_alias)) u128_t;
+
+
+#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
+
+
+#define ALIGNED_LOAD(in_ptr, offs) \
+ (asm_aligned_ld ((offs) * 16, (const void *)(in_ptr)))
+
+#define ALIGNED_STORE(out_ptr, offs, vec) \
+ (asm_aligned_st ((vec), (offs) * 16, (void *)(out_ptr)))
+
+#define VEC_BE_SWAP(vec, bige_const) (asm_be_swap ((vec), (bige_const)))
+
+#define VEC_LOAD_BE(in_ptr, offs, bige_const) \
+ (asm_be_swap (asm_load_be_noswap ((offs) * 16, (const void *)(in_ptr)), \
+ bige_const))
+
+#define VEC_LOAD_BE_NOSWAP(in_ptr, offs) \
+ (asm_load_be_noswap ((offs) * 16, (const unsigned char *)(in_ptr)))
+
+#define VEC_STORE_BE(out_ptr, offs, vec, bige_const) \
+ (asm_store_be_noswap (asm_be_swap ((vec), (bige_const)), (offs) * 16, \
+ (void *)(out_ptr)))
+
+#define VEC_STORE_BE_NOSWAP(out_ptr, offs, vec) \
+ (asm_store_be_noswap ((vec), (offs) * 16, (void *)(out_ptr)))
+
+
+#define ROUND_KEY_VARIABLES \
+ block rkey0, rkeylast
+
+#define PRELOAD_ROUND_KEYS(nrounds) \
+ do { \
+ rkey0 = ALIGNED_LOAD (rk, 0); \
+ rkeylast = ALIGNED_LOAD (rk, nrounds); \
+ } while (0)
+
+#define AES_ENCRYPT(blk, nrounds) \
+ do { \
+ blk ^= rkey0; \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 1)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 2)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 3)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 4)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 5)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 6)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 7)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 8)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 9)); \
+ if (nrounds >= 12) \
+ { \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 10)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 11)); \
+ if (rounds > 12) \
+ { \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 12)); \
+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 13)); \
+ } \
+ } \
+ blk = asm_cipherlast_be (blk, rkeylast); \
+ } while (0)
+
+#define AES_DECRYPT(blk, nrounds) \
+ do { \
+ blk ^= rkey0; \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 1)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 2)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 3)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 4)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 5)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 6)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 7)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 8)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 9)); \
+ if (nrounds >= 12) \
+ { \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 10)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 11)); \
+ if (rounds > 12) \
+ { \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 12)); \
+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 13)); \
+ } \
+ } \
+ blk = asm_ncipherlast_be (blk, rkeylast); \
+ } while (0)
+
+
+#define ROUND_KEY_VARIABLES_ALL \
+ block rkey0, rkey1, rkey2, rkey3, rkey4, rkey5, rkey6, rkey7, rkey8, \
+ rkey9, rkey10, rkey11, rkey12, rkey13, rkeylast
+
+#define PRELOAD_ROUND_KEYS_ALL(nrounds) \
+ do { \
+ rkey0 = ALIGNED_LOAD (rk, 0); \
+ rkey1 = ALIGNED_LOAD (rk, 1); \
+ rkey2 = ALIGNED_LOAD (rk, 2); \
+ rkey3 = ALIGNED_LOAD (rk, 3); \
+ rkey4 = ALIGNED_LOAD (rk, 4); \
+ rkey5 = ALIGNED_LOAD (rk, 5); \
+ rkey6 = ALIGNED_LOAD (rk, 6); \
+ rkey7 = ALIGNED_LOAD (rk, 7); \
+ rkey8 = ALIGNED_LOAD (rk, 8); \
+ rkey9 = ALIGNED_LOAD (rk, 9); \
+ if (nrounds >= 12) \
+ { \
+ rkey10 = ALIGNED_LOAD (rk, 10); \
+ rkey11 = ALIGNED_LOAD (rk, 11); \
+ if (rounds > 12) \
+ { \
+ rkey12 = ALIGNED_LOAD (rk, 12); \
+ rkey13 = ALIGNED_LOAD (rk, 13); \
+ } \
+ } \
+ rkeylast = ALIGNED_LOAD (rk, nrounds); \
+ } while (0)
+
+#define AES_ENCRYPT_ALL(blk, nrounds) \
+ do { \
+ blk ^= rkey0; \
+ blk = asm_cipher_be (blk, rkey1); \
+ blk = asm_cipher_be (blk, rkey2); \
+ blk = asm_cipher_be (blk, rkey3); \
+ blk = asm_cipher_be (blk, rkey4); \
+ blk = asm_cipher_be (blk, rkey5); \
+ blk = asm_cipher_be (blk, rkey6); \
+ blk = asm_cipher_be (blk, rkey7); \
+ blk = asm_cipher_be (blk, rkey8); \
+ blk = asm_cipher_be (blk, rkey9); \
+ if (nrounds >= 12) \
+ { \
+ blk = asm_cipher_be (blk, rkey10); \
+ blk = asm_cipher_be (blk, rkey11); \
+ if (rounds > 12) \
+ { \
+ blk = asm_cipher_be (blk, rkey12); \
+ blk = asm_cipher_be (blk, rkey13); \
+ } \
+ } \
+ blk = asm_cipherlast_be (blk, rkeylast); \
+ } while (0)
+
+
+static ASM_FUNC_ATTR_INLINE block
+asm_aligned_ld(unsigned long offset, const void *ptr)
+{
+ block vec;
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ volatile ("lvx %0,0,%1\n\t"
+ : "=v" (vec)
+ : "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ volatile ("lvx %0,%1,%2\n\t"
+ : "=v" (vec)
+ : "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+ return vec;
+}
+
+static ASM_FUNC_ATTR_INLINE void
+asm_aligned_st(block vec, unsigned long offset, void *ptr)
+{
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ volatile ("stvx %0,0,%1\n\t"
+ :
+ : "v" (vec), "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ volatile ("stvx %0,%1,%2\n\t"
+ :
+ : "v" (vec), "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_vperm1(block vec, block mask)
+{
+ block o;
+ __asm__ volatile ("vperm %0,%1,%1,%2\n\t"
+ : "=v" (o)
+ : "v" (vec), "v" (mask));
+ return o;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_add_uint128(block a, block b)
+{
+ block res;
+ __asm__ volatile ("vadduqm %0,%1,%2\n\t"
+ : "=v" (res)
+ : "v" (a), "v" (b));
+ return res;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_add_uint64(block a, block b)
+{
+ block res;
+ __asm__ volatile ("vaddudm %0,%1,%2\n\t"
+ : "=v" (res)
+ : "v" (a), "v" (b));
+ return res;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_sra_int64(block a, block b)
+{
+ block res;
+ __asm__ volatile ("vsrad %0,%1,%2\n\t"
+ : "=v" (res)
+ : "v" (a), "v" (b));
+ return res;
+}
+
+static block
+asm_swap_uint64_halfs(block a)
+{
+ block res;
+ __asm__ volatile ("xxswapd %x0, %x1"
+ : "=wa" (res)
+ : "wa" (a));
+ return res;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_xor(block a, block b)
+{
+ block res;
+ __asm__ volatile ("vxor %0,%1,%2\n\t"
+ : "=v" (res)
+ : "v" (a), "v" (b));
+ return res;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_cipher_be(block b, block rk)
+{
+ block o;
+ __asm__ volatile ("vcipher %0, %1, %2\n\t"
+ : "=v" (o)
+ : "v" (b), "v" (rk));
+ return o;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_cipherlast_be(block b, block rk)
+{
+ block o;
+ __asm__ volatile ("vcipherlast %0, %1, %2\n\t"
+ : "=v" (o)
+ : "v" (b), "v" (rk));
+ return o;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_ncipher_be(block b, block rk)
+{
+ block o;
+ __asm__ volatile ("vncipher %0, %1, %2\n\t"
+ : "=v" (o)
+ : "v" (b), "v" (rk));
+ return o;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_ncipherlast_be(block b, block rk)
+{
+ block o;
+ __asm__ volatile ("vncipherlast %0, %1, %2\n\t"
+ : "=v" (o)
+ : "v" (b), "v" (rk));
+ return o;
+}
+
+
+/* Make a decryption key from an encryption key. */
+static ASM_FUNC_ATTR_INLINE void
+internal_aes_ppc_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;
+
+ r = 0;
+ rr = rounds;
+ for (r = 0, rr = rounds; r <= rounds; r++, rr--)
+ {
+ ALIGNED_STORE (dkey, r, ALIGNED_LOAD (ekey, rr));
+ }
+}
+
+#endif /* G10_RIJNDAEL_PPC_COMMON_H */
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-ppc-functions.h b/comm/third_party/libgcrypt/cipher/rijndael-ppc-functions.h
new file mode 100644
index 0000000000..72f31852b4
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-ppc-functions.h
@@ -0,0 +1,2020 @@
+/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation
+ * Copyright (C) 2019 Shawn Landden <shawn@git.icu>
+ * Copyright (C) 2019-2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project,
+ * and Cryptogams by Andy Polyakov, and if made part of a release of either
+ * or both projects, is thereafter dual-licensed under the license said project
+ * is released under.
+ */
+
+unsigned int ENCRYPT_BLOCK_FUNC (const RIJNDAEL_context *ctx,
+ unsigned char *out,
+ const unsigned char *in)
+{
+ const block bige_const = asm_load_be_const();
+ const u128_t *rk = (u128_t *)&ctx->keyschenc;
+ int rounds = ctx->rounds;
+ ROUND_KEY_VARIABLES;
+ block b;
+
+ b = VEC_LOAD_BE (in, 0, bige_const);
+
+ PRELOAD_ROUND_KEYS (rounds);
+
+ AES_ENCRYPT (b, rounds);
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ return 0; /* does not use stack */
+}
+
+
+unsigned int DECRYPT_BLOCK_FUNC (const RIJNDAEL_context *ctx,
+ unsigned char *out,
+ const unsigned char *in)
+{
+ const block bige_const = asm_load_be_const();
+ const u128_t *rk = (u128_t *)&ctx->keyschdec;
+ int rounds = ctx->rounds;
+ ROUND_KEY_VARIABLES;
+ block b;
+
+ b = VEC_LOAD_BE (in, 0, bige_const);
+
+ PRELOAD_ROUND_KEYS (rounds);
+
+ AES_DECRYPT (b, rounds);
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ return 0; /* does not use stack */
+}
+
+
+void CFB_ENC_FUNC (void *context, unsigned char *iv_arg,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ const block bige_const = asm_load_be_const();
+ RIJNDAEL_context *ctx = context;
+ const u128_t *rk = (u128_t *)&ctx->keyschenc;
+ const u128_t *in = (const u128_t *)inbuf_arg;
+ u128_t *out = (u128_t *)outbuf_arg;
+ int rounds = ctx->rounds;
+ ROUND_KEY_VARIABLES_ALL;
+ block rkeylast_orig;
+ block iv;
+
+ iv = VEC_LOAD_BE (iv_arg, 0, bige_const);
+
+ PRELOAD_ROUND_KEYS_ALL (rounds);
+ rkeylast_orig = rkeylast;
+
+ for (; nblocks >= 2; nblocks -= 2)
+ {
+ block in2, iv1;
+
+ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in, 0, bige_const);
+ in2 = VEC_LOAD_BE (in + 1, 0, bige_const);
+ in += 2;
+
+ AES_ENCRYPT_ALL (iv, rounds);
+
+ iv1 = iv;
+ rkeylast = rkeylast_orig ^ in2;
+
+ AES_ENCRYPT_ALL (iv, rounds);
+
+ VEC_STORE_BE (out++, 0, iv1, bige_const);
+ VEC_STORE_BE (out++, 0, iv, bige_const);
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in++, 0, bige_const);
+
+ AES_ENCRYPT_ALL (iv, rounds);
+
+ VEC_STORE_BE (out++, 0, iv, bige_const);
+ }
+
+ VEC_STORE_BE (iv_arg, 0, iv, bige_const);
+}
+
+void CFB_DEC_FUNC (void *context, unsigned char *iv_arg,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ const block bige_const = asm_load_be_const();
+ RIJNDAEL_context *ctx = context;
+ const u128_t *rk = (u128_t *)&ctx->keyschenc;
+ const u128_t *in = (const u128_t *)inbuf_arg;
+ u128_t *out = (u128_t *)outbuf_arg;
+ int rounds = ctx->rounds;
+ ROUND_KEY_VARIABLES;
+ block rkeylast_orig;
+ block iv, b, bin;
+ block in0, in1, in2, in3, in4, in5, in6, in7;
+ block b0, b1, b2, b3, b4, b5, b6, b7;
+ block rkey;
+
+ iv = VEC_LOAD_BE (iv_arg, 0, bige_const);
+
+ PRELOAD_ROUND_KEYS (rounds);
+ rkeylast_orig = rkeylast;
+
+ for (; nblocks >= 8; nblocks -= 8)
+ {
+ in0 = iv;
+ in1 = VEC_LOAD_BE_NOSWAP (in, 0);
+ in2 = VEC_LOAD_BE_NOSWAP (in, 1);
+ in3 = VEC_LOAD_BE_NOSWAP (in, 2);
+ in4 = VEC_LOAD_BE_NOSWAP (in, 3);
+ in1 = VEC_BE_SWAP (in1, bige_const);
+ in2 = VEC_BE_SWAP (in2, bige_const);
+ in5 = VEC_LOAD_BE_NOSWAP (in, 4);
+ in6 = VEC_LOAD_BE_NOSWAP (in, 5);
+ in3 = VEC_BE_SWAP (in3, bige_const);
+ in4 = VEC_BE_SWAP (in4, bige_const);
+ in7 = VEC_LOAD_BE_NOSWAP (in, 6);
+ iv = VEC_LOAD_BE_NOSWAP (in, 7);
+ in += 8;
+ in5 = VEC_BE_SWAP (in5, bige_const);
+ in6 = VEC_BE_SWAP (in6, bige_const);
+ b0 = asm_xor (rkey0, in0);
+ b1 = asm_xor (rkey0, in1);
+ in7 = VEC_BE_SWAP (in7, bige_const);
+ iv = VEC_BE_SWAP (iv, bige_const);
+ b2 = asm_xor (rkey0, in2);
+ b3 = asm_xor (rkey0, in3);
+ b4 = asm_xor (rkey0, in4);
+ b5 = asm_xor (rkey0, in5);
+ b6 = asm_xor (rkey0, in6);
+ b7 = asm_xor (rkey0, in7);
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey); \
+ b4 = asm_cipher_be (b4, rkey); \
+ b5 = asm_cipher_be (b5, rkey); \
+ b6 = asm_cipher_be (b6, rkey); \
+ b7 = asm_cipher_be (b7, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ in1 = asm_xor (rkeylast, in1);
+ in2 = asm_xor (rkeylast, in2);
+ in3 = asm_xor (rkeylast, in3);
+ in4 = asm_xor (rkeylast, in4);
+ b0 = asm_cipherlast_be (b0, in1);
+ b1 = asm_cipherlast_be (b1, in2);
+ in5 = asm_xor (rkeylast, in5);
+ in6 = asm_xor (rkeylast, in6);
+ b2 = asm_cipherlast_be (b2, in3);
+ b3 = asm_cipherlast_be (b3, in4);
+ in7 = asm_xor (rkeylast, in7);
+ in0 = asm_xor (rkeylast, iv);
+ b0 = VEC_BE_SWAP (b0, bige_const);
+ b1 = VEC_BE_SWAP (b1, bige_const);
+ b4 = asm_cipherlast_be (b4, in5);
+ b5 = asm_cipherlast_be (b5, in6);
+ b2 = VEC_BE_SWAP (b2, bige_const);
+ b3 = VEC_BE_SWAP (b3, bige_const);
+ b6 = asm_cipherlast_be (b6, in7);
+ b7 = asm_cipherlast_be (b7, in0);
+ b4 = VEC_BE_SWAP (b4, bige_const);
+ b5 = VEC_BE_SWAP (b5, bige_const);
+ b6 = VEC_BE_SWAP (b6, bige_const);
+ b7 = VEC_BE_SWAP (b7, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 0, b0);
+ VEC_STORE_BE_NOSWAP (out, 1, b1);
+ VEC_STORE_BE_NOSWAP (out, 2, b2);
+ VEC_STORE_BE_NOSWAP (out, 3, b3);
+ VEC_STORE_BE_NOSWAP (out, 4, b4);
+ VEC_STORE_BE_NOSWAP (out, 5, b5);
+ VEC_STORE_BE_NOSWAP (out, 6, b6);
+ VEC_STORE_BE_NOSWAP (out, 7, b7);
+ out += 8;
+ }
+
+ if (nblocks >= 4)
+ {
+ in0 = iv;
+ in1 = VEC_LOAD_BE (in, 0, bige_const);
+ in2 = VEC_LOAD_BE (in, 1, bige_const);
+ in3 = VEC_LOAD_BE (in, 2, bige_const);
+ iv = VEC_LOAD_BE (in, 3, bige_const);
+
+ b0 = asm_xor (rkey0, in0);
+ b1 = asm_xor (rkey0, in1);
+ b2 = asm_xor (rkey0, in2);
+ b3 = asm_xor (rkey0, in3);
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ in1 = asm_xor (rkeylast, in1);
+ in2 = asm_xor (rkeylast, in2);
+ in3 = asm_xor (rkeylast, in3);
+ in0 = asm_xor (rkeylast, iv);
+ b0 = asm_cipherlast_be (b0, in1);
+ b1 = asm_cipherlast_be (b1, in2);
+ b2 = asm_cipherlast_be (b2, in3);
+ b3 = asm_cipherlast_be (b3, in0);
+ VEC_STORE_BE (out, 0, b0, bige_const);
+ VEC_STORE_BE (out, 1, b1, bige_const);
+ VEC_STORE_BE (out, 2, b2, bige_const);
+ VEC_STORE_BE (out, 3, b3, bige_const);
+
+ in += 4;
+ out += 4;
+ nblocks -= 4;
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ bin = VEC_LOAD_BE (in, 0, bige_const);
+ rkeylast = rkeylast_orig ^ bin;
+ b = iv;
+ iv = bin;
+
+ AES_ENCRYPT (b, rounds);
+
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ out++;
+ in++;
+ }
+
+ VEC_STORE_BE (iv_arg, 0, iv, bige_const);
+}
+
+
+void CBC_ENC_FUNC (void *context, unsigned char *iv_arg,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks, int cbc_mac)
+{
+ const block bige_const = asm_load_be_const();
+ RIJNDAEL_context *ctx = context;
+ const u128_t *rk = (u128_t *)&ctx->keyschenc;
+ const u128_t *in = (const u128_t *)inbuf_arg;
+ byte *out = (byte *)outbuf_arg;
+ int rounds = ctx->rounds;
+ ROUND_KEY_VARIABLES_ALL;
+ block lastiv, b;
+ unsigned int outadd = -(!cbc_mac) & 16;
+
+ lastiv = VEC_LOAD_BE (iv_arg, 0, bige_const);
+
+ PRELOAD_ROUND_KEYS_ALL (rounds);
+
+ for (; nblocks >= 2; nblocks -= 2)
+ {
+ block in2, lastiv1;
+
+ b = lastiv ^ VEC_LOAD_BE (in, 0, bige_const);
+ in2 = VEC_LOAD_BE (in + 1, 0, bige_const);
+ in += 2;
+
+ AES_ENCRYPT_ALL (b, rounds);
+
+ lastiv1 = b;
+ b = lastiv1 ^ in2;
+
+ AES_ENCRYPT_ALL (b, rounds);
+
+ lastiv = b;
+ VEC_STORE_BE ((u128_t *)out, 0, lastiv1, bige_const);
+ out += outadd;
+ VEC_STORE_BE ((u128_t *)out, 0, lastiv, bige_const);
+ out += outadd;
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ b = lastiv ^ VEC_LOAD_BE (in++, 0, bige_const);
+
+ AES_ENCRYPT_ALL (b, rounds);
+
+ lastiv = b;
+ VEC_STORE_BE ((u128_t *)out, 0, b, bige_const);
+ out += outadd;
+ }
+
+ VEC_STORE_BE (iv_arg, 0, lastiv, bige_const);
+}
+
+void CBC_DEC_FUNC (void *context, unsigned char *iv_arg,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ const block bige_const = asm_load_be_const();
+ RIJNDAEL_context *ctx = context;
+ const u128_t *rk = (u128_t *)&ctx->keyschdec;
+ const u128_t *in = (const u128_t *)inbuf_arg;
+ u128_t *out = (u128_t *)outbuf_arg;
+ int rounds = ctx->rounds;
+ ROUND_KEY_VARIABLES;
+ block rkeylast_orig;
+ block in0, in1, in2, in3, in4, in5, in6, in7;
+ block b0, b1, b2, b3, b4, b5, b6, b7;
+ block rkey;
+ block iv, b;
+
+ if (!ctx->decryption_prepared)
+ {
+ internal_aes_ppc_prepare_decryption (ctx);
+ ctx->decryption_prepared = 1;
+ }
+
+ iv = VEC_LOAD_BE (iv_arg, 0, bige_const);
+
+ PRELOAD_ROUND_KEYS (rounds);
+ rkeylast_orig = rkeylast;
+
+ for (; nblocks >= 8; nblocks -= 8)
+ {
+ in0 = VEC_LOAD_BE_NOSWAP (in, 0);
+ in1 = VEC_LOAD_BE_NOSWAP (in, 1);
+ in2 = VEC_LOAD_BE_NOSWAP (in, 2);
+ in3 = VEC_LOAD_BE_NOSWAP (in, 3);
+ in0 = VEC_BE_SWAP (in0, bige_const);
+ in1 = VEC_BE_SWAP (in1, bige_const);
+ in4 = VEC_LOAD_BE_NOSWAP (in, 4);
+ in5 = VEC_LOAD_BE_NOSWAP (in, 5);
+ in2 = VEC_BE_SWAP (in2, bige_const);
+ in3 = VEC_BE_SWAP (in3, bige_const);
+ in6 = VEC_LOAD_BE_NOSWAP (in, 6);
+ in7 = VEC_LOAD_BE_NOSWAP (in, 7);
+ in += 8;
+ b0 = asm_xor (rkey0, in0);
+ b1 = asm_xor (rkey0, in1);
+ in4 = VEC_BE_SWAP (in4, bige_const);
+ in5 = VEC_BE_SWAP (in5, bige_const);
+ b2 = asm_xor (rkey0, in2);
+ b3 = asm_xor (rkey0, in3);
+ in6 = VEC_BE_SWAP (in6, bige_const);
+ in7 = VEC_BE_SWAP (in7, bige_const);
+ b4 = asm_xor (rkey0, in4);
+ b5 = asm_xor (rkey0, in5);
+ b6 = asm_xor (rkey0, in6);
+ b7 = asm_xor (rkey0, in7);
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_ncipher_be (b0, rkey); \
+ b1 = asm_ncipher_be (b1, rkey); \
+ b2 = asm_ncipher_be (b2, rkey); \
+ b3 = asm_ncipher_be (b3, rkey); \
+ b4 = asm_ncipher_be (b4, rkey); \
+ b5 = asm_ncipher_be (b5, rkey); \
+ b6 = asm_ncipher_be (b6, rkey); \
+ b7 = asm_ncipher_be (b7, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ iv = asm_xor (rkeylast, iv);
+ in0 = asm_xor (rkeylast, in0);
+ in1 = asm_xor (rkeylast, in1);
+ in2 = asm_xor (rkeylast, in2);
+ b0 = asm_ncipherlast_be (b0, iv);
+ iv = in7;
+ b1 = asm_ncipherlast_be (b1, in0);
+ in3 = asm_xor (rkeylast, in3);
+ in4 = asm_xor (rkeylast, in4);
+ b2 = asm_ncipherlast_be (b2, in1);
+ b3 = asm_ncipherlast_be (b3, in2);
+ in5 = asm_xor (rkeylast, in5);
+ in6 = asm_xor (rkeylast, in6);
+ b0 = VEC_BE_SWAP (b0, bige_const);
+ b1 = VEC_BE_SWAP (b1, bige_const);
+ b4 = asm_ncipherlast_be (b4, in3);
+ b5 = asm_ncipherlast_be (b5, in4);
+ b2 = VEC_BE_SWAP (b2, bige_const);
+ b3 = VEC_BE_SWAP (b3, bige_const);
+ b6 = asm_ncipherlast_be (b6, in5);
+ b7 = asm_ncipherlast_be (b7, in6);
+ b4 = VEC_BE_SWAP (b4, bige_const);
+ b5 = VEC_BE_SWAP (b5, bige_const);
+ b6 = VEC_BE_SWAP (b6, bige_const);
+ b7 = VEC_BE_SWAP (b7, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 0, b0);
+ VEC_STORE_BE_NOSWAP (out, 1, b1);
+ VEC_STORE_BE_NOSWAP (out, 2, b2);
+ VEC_STORE_BE_NOSWAP (out, 3, b3);
+ VEC_STORE_BE_NOSWAP (out, 4, b4);
+ VEC_STORE_BE_NOSWAP (out, 5, b5);
+ VEC_STORE_BE_NOSWAP (out, 6, b6);
+ VEC_STORE_BE_NOSWAP (out, 7, b7);
+ out += 8;
+ }
+
+ if (nblocks >= 4)
+ {
+ in0 = VEC_LOAD_BE (in, 0, bige_const);
+ in1 = VEC_LOAD_BE (in, 1, bige_const);
+ in2 = VEC_LOAD_BE (in, 2, bige_const);
+ in3 = VEC_LOAD_BE (in, 3, bige_const);
+
+ b0 = asm_xor (rkey0, in0);
+ b1 = asm_xor (rkey0, in1);
+ b2 = asm_xor (rkey0, in2);
+ b3 = asm_xor (rkey0, in3);
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_ncipher_be (b0, rkey); \
+ b1 = asm_ncipher_be (b1, rkey); \
+ b2 = asm_ncipher_be (b2, rkey); \
+ b3 = asm_ncipher_be (b3, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ iv = asm_xor (rkeylast, iv);
+ in0 = asm_xor (rkeylast, in0);
+ in1 = asm_xor (rkeylast, in1);
+ in2 = asm_xor (rkeylast, in2);
+
+ b0 = asm_ncipherlast_be (b0, iv);
+ iv = in3;
+ b1 = asm_ncipherlast_be (b1, in0);
+ b2 = asm_ncipherlast_be (b2, in1);
+ b3 = asm_ncipherlast_be (b3, in2);
+
+ VEC_STORE_BE (out, 0, b0, bige_const);
+ VEC_STORE_BE (out, 1, b1, bige_const);
+ VEC_STORE_BE (out, 2, b2, bige_const);
+ VEC_STORE_BE (out, 3, b3, bige_const);
+
+ in += 4;
+ out += 4;
+ nblocks -= 4;
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ rkeylast = rkeylast_orig ^ iv;
+
+ iv = VEC_LOAD_BE (in, 0, bige_const);
+ b = iv;
+ AES_DECRYPT (b, rounds);
+
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ in++;
+ out++;
+ }
+
+ VEC_STORE_BE (iv_arg, 0, iv, bige_const);
+}
+
+
+void CTR_ENC_FUNC (void *context, unsigned char *ctr_arg,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ static const unsigned char vec_one_const[16] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+ const block bige_const = asm_load_be_const();
+ RIJNDAEL_context *ctx = context;
+ const u128_t *rk = (u128_t *)&ctx->keyschenc;
+ const u128_t *in = (const u128_t *)inbuf_arg;
+ u128_t *out = (u128_t *)outbuf_arg;
+ int rounds = ctx->rounds;
+ ROUND_KEY_VARIABLES;
+ block rkeylast_orig;
+ block ctr, b, one;
+
+ ctr = VEC_LOAD_BE (ctr_arg, 0, bige_const);
+ one = VEC_LOAD_BE (&vec_one_const, 0, bige_const);
+
+ PRELOAD_ROUND_KEYS (rounds);
+ rkeylast_orig = rkeylast;
+
+ if (nblocks >= 4)
+ {
+ block in0, in1, in2, in3, in4, in5, in6, in7;
+ block b0, b1, b2, b3, b4, b5, b6, b7;
+ block two, three, four;
+ block rkey;
+
+ two = asm_add_uint128 (one, one);
+ three = asm_add_uint128 (two, one);
+ four = asm_add_uint128 (two, two);
+
+ for (; nblocks >= 8; nblocks -= 8)
+ {
+ b1 = asm_add_uint128 (ctr, one);
+ b2 = asm_add_uint128 (ctr, two);
+ b3 = asm_add_uint128 (ctr, three);
+ b4 = asm_add_uint128 (ctr, four);
+ b5 = asm_add_uint128 (b1, four);
+ b6 = asm_add_uint128 (b2, four);
+ b7 = asm_add_uint128 (b3, four);
+ b0 = asm_xor (rkey0, ctr);
+ rkey = ALIGNED_LOAD (rk, 1);
+ ctr = asm_add_uint128 (b4, four);
+ b1 = asm_xor (rkey0, b1);
+ b2 = asm_xor (rkey0, b2);
+ b3 = asm_xor (rkey0, b3);
+ b0 = asm_cipher_be (b0, rkey);
+ b1 = asm_cipher_be (b1, rkey);
+ b2 = asm_cipher_be (b2, rkey);
+ b3 = asm_cipher_be (b3, rkey);
+ b4 = asm_xor (rkey0, b4);
+ b5 = asm_xor (rkey0, b5);
+ b6 = asm_xor (rkey0, b6);
+ b7 = asm_xor (rkey0, b7);
+ b4 = asm_cipher_be (b4, rkey);
+ b5 = asm_cipher_be (b5, rkey);
+ b6 = asm_cipher_be (b6, rkey);
+ b7 = asm_cipher_be (b7, rkey);
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey); \
+ b4 = asm_cipher_be (b4, rkey); \
+ b5 = asm_cipher_be (b5, rkey); \
+ b6 = asm_cipher_be (b6, rkey); \
+ b7 = asm_cipher_be (b7, rkey);
+
+ in0 = VEC_LOAD_BE_NOSWAP (in, 0);
+ DO_ROUND(2);
+ in1 = VEC_LOAD_BE_NOSWAP (in, 1);
+ DO_ROUND(3);
+ in2 = VEC_LOAD_BE_NOSWAP (in, 2);
+ DO_ROUND(4);
+ in3 = VEC_LOAD_BE_NOSWAP (in, 3);
+ DO_ROUND(5);
+ in4 = VEC_LOAD_BE_NOSWAP (in, 4);
+ DO_ROUND(6);
+ in5 = VEC_LOAD_BE_NOSWAP (in, 5);
+ DO_ROUND(7);
+ in6 = VEC_LOAD_BE_NOSWAP (in, 6);
+ DO_ROUND(8);
+ in7 = VEC_LOAD_BE_NOSWAP (in, 7);
+ in += 8;
+ DO_ROUND(9);
+
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ in0 = VEC_BE_SWAP (in0, bige_const);
+ in1 = VEC_BE_SWAP (in1, bige_const);
+ in2 = VEC_BE_SWAP (in2, bige_const);
+ in3 = VEC_BE_SWAP (in3, bige_const);
+ in4 = VEC_BE_SWAP (in4, bige_const);
+ in5 = VEC_BE_SWAP (in5, bige_const);
+ in6 = VEC_BE_SWAP (in6, bige_const);
+ in7 = VEC_BE_SWAP (in7, bige_const);
+
+ in0 = asm_xor (rkeylast, in0);
+ in1 = asm_xor (rkeylast, in1);
+ in2 = asm_xor (rkeylast, in2);
+ in3 = asm_xor (rkeylast, in3);
+ b0 = asm_cipherlast_be (b0, in0);
+ b1 = asm_cipherlast_be (b1, in1);
+ in4 = asm_xor (rkeylast, in4);
+ in5 = asm_xor (rkeylast, in5);
+ b2 = asm_cipherlast_be (b2, in2);
+ b3 = asm_cipherlast_be (b3, in3);
+ in6 = asm_xor (rkeylast, in6);
+ in7 = asm_xor (rkeylast, in7);
+ b4 = asm_cipherlast_be (b4, in4);
+ b5 = asm_cipherlast_be (b5, in5);
+ b6 = asm_cipherlast_be (b6, in6);
+ b7 = asm_cipherlast_be (b7, in7);
+
+ b0 = VEC_BE_SWAP (b0, bige_const);
+ b1 = VEC_BE_SWAP (b1, bige_const);
+ b2 = VEC_BE_SWAP (b2, bige_const);
+ b3 = VEC_BE_SWAP (b3, bige_const);
+ b4 = VEC_BE_SWAP (b4, bige_const);
+ b5 = VEC_BE_SWAP (b5, bige_const);
+ b6 = VEC_BE_SWAP (b6, bige_const);
+ b7 = VEC_BE_SWAP (b7, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 0, b0);
+ VEC_STORE_BE_NOSWAP (out, 1, b1);
+ VEC_STORE_BE_NOSWAP (out, 2, b2);
+ VEC_STORE_BE_NOSWAP (out, 3, b3);
+ VEC_STORE_BE_NOSWAP (out, 4, b4);
+ VEC_STORE_BE_NOSWAP (out, 5, b5);
+ VEC_STORE_BE_NOSWAP (out, 6, b6);
+ VEC_STORE_BE_NOSWAP (out, 7, b7);
+ out += 8;
+ }
+
+ if (nblocks >= 4)
+ {
+ b1 = asm_add_uint128 (ctr, one);
+ b2 = asm_add_uint128 (ctr, two);
+ b3 = asm_add_uint128 (ctr, three);
+ b0 = asm_xor (rkey0, ctr);
+ ctr = asm_add_uint128 (ctr, four);
+ b1 = asm_xor (rkey0, b1);
+ b2 = asm_xor (rkey0, b2);
+ b3 = asm_xor (rkey0, b3);
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+
+ in0 = VEC_LOAD_BE (in, 0, bige_const);
+ in1 = VEC_LOAD_BE (in, 1, bige_const);
+ in2 = VEC_LOAD_BE (in, 2, bige_const);
+ in3 = VEC_LOAD_BE (in, 3, bige_const);
+
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ in0 = asm_xor (rkeylast, in0);
+ in1 = asm_xor (rkeylast, in1);
+ in2 = asm_xor (rkeylast, in2);
+ in3 = asm_xor (rkeylast, in3);
+
+ b0 = asm_cipherlast_be (b0, in0);
+ b1 = asm_cipherlast_be (b1, in1);
+ b2 = asm_cipherlast_be (b2, in2);
+ b3 = asm_cipherlast_be (b3, in3);
+
+ VEC_STORE_BE (out, 0, b0, bige_const);
+ VEC_STORE_BE (out, 1, b1, bige_const);
+ VEC_STORE_BE (out, 2, b2, bige_const);
+ VEC_STORE_BE (out, 3, b3, bige_const);
+
+ in += 4;
+ out += 4;
+ nblocks -= 4;
+ }
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ b = ctr;
+ ctr = asm_add_uint128 (ctr, one);
+ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in, 0, bige_const);
+
+ AES_ENCRYPT (b, rounds);
+
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ out++;
+ in++;
+ }
+
+ VEC_STORE_BE (ctr_arg, 0, ctr, bige_const);
+}
+
+
+size_t OCB_CRYPT_FUNC (gcry_cipher_hd_t c, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks,
+ int encrypt)
+{
+ const block bige_const = asm_load_be_const();
+ RIJNDAEL_context *ctx = (void *)&c->context.c;
+ const u128_t *in = (const u128_t *)inbuf_arg;
+ u128_t *out = (u128_t *)outbuf_arg;
+ int rounds = ctx->rounds;
+ u64 data_nblocks = c->u_mode.ocb.data_nblocks;
+ block l0, l1, l2, l;
+ block b0, b1, b2, b3, b4, b5, b6, b7, b;
+ block iv0, iv1, iv2, iv3, iv4, iv5, iv6, iv7;
+ block rkey, rkeylf;
+ block ctr, iv;
+ ROUND_KEY_VARIABLES;
+
+ iv = VEC_LOAD_BE (c->u_iv.iv, 0, bige_const);
+ ctr = VEC_LOAD_BE (c->u_ctr.ctr, 0, bige_const);
+
+ l0 = VEC_LOAD_BE (c->u_mode.ocb.L[0], 0, bige_const);
+ l1 = VEC_LOAD_BE (c->u_mode.ocb.L[1], 0, bige_const);
+ l2 = VEC_LOAD_BE (c->u_mode.ocb.L[2], 0, bige_const);
+
+ if (encrypt)
+ {
+ const u128_t *rk = (u128_t *)&ctx->keyschenc;
+
+ PRELOAD_ROUND_KEYS (rounds);
+
+ for (; nblocks >= 8 && data_nblocks % 8; nblocks--)
+ {
+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const);
+ b = VEC_LOAD_BE (in, 0, bige_const);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ iv ^= l;
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ctr ^= b;
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+ b ^= iv;
+ AES_ENCRYPT (b, rounds);
+ b ^= iv;
+
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ in += 1;
+ out += 1;
+ }
+
+ for (; nblocks >= 8; nblocks -= 8)
+ {
+ b0 = VEC_LOAD_BE_NOSWAP (in, 0);
+ b1 = VEC_LOAD_BE_NOSWAP (in, 1);
+ b2 = VEC_LOAD_BE_NOSWAP (in, 2);
+ b3 = VEC_LOAD_BE_NOSWAP (in, 3);
+ b4 = VEC_LOAD_BE_NOSWAP (in, 4);
+ b5 = VEC_LOAD_BE_NOSWAP (in, 5);
+ b6 = VEC_LOAD_BE_NOSWAP (in, 6);
+ b7 = VEC_LOAD_BE_NOSWAP (in, 7);
+ in += 8;
+ l = VEC_LOAD_BE_NOSWAP (ocb_get_l (c, data_nblocks += 8), 0);
+ b0 = VEC_BE_SWAP(b0, bige_const);
+ b1 = VEC_BE_SWAP(b1, bige_const);
+ b2 = VEC_BE_SWAP(b2, bige_const);
+ b3 = VEC_BE_SWAP(b3, bige_const);
+ b4 = VEC_BE_SWAP(b4, bige_const);
+ b5 = VEC_BE_SWAP(b5, bige_const);
+ b6 = VEC_BE_SWAP(b6, bige_const);
+ b7 = VEC_BE_SWAP(b7, bige_const);
+ l = VEC_BE_SWAP(l, bige_const);
+
+ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7;
+
+ iv ^= rkey0;
+
+ iv0 = iv ^ l0;
+ iv1 = iv ^ l0 ^ l1;
+ iv2 = iv ^ l1;
+ iv3 = iv ^ l1 ^ l2;
+ iv4 = iv ^ l1 ^ l2 ^ l0;
+ iv5 = iv ^ l2 ^ l0;
+ iv6 = iv ^ l2;
+ iv7 = iv ^ l2 ^ l;
+
+ b0 ^= iv0;
+ b1 ^= iv1;
+ b2 ^= iv2;
+ b3 ^= iv3;
+ b4 ^= iv4;
+ b5 ^= iv5;
+ b6 ^= iv6;
+ b7 ^= iv7;
+ iv = iv7 ^ rkey0;
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey); \
+ b4 = asm_cipher_be (b4, rkey); \
+ b5 = asm_cipher_be (b5, rkey); \
+ b6 = asm_cipher_be (b6, rkey); \
+ b7 = asm_cipher_be (b7, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+
+ rkeylf = asm_xor (rkeylast, rkey0);
+
+ DO_ROUND(8);
+
+ iv0 = asm_xor (rkeylf, iv0);
+ iv1 = asm_xor (rkeylf, iv1);
+ iv2 = asm_xor (rkeylf, iv2);
+ iv3 = asm_xor (rkeylf, iv3);
+ iv4 = asm_xor (rkeylf, iv4);
+ iv5 = asm_xor (rkeylf, iv5);
+ iv6 = asm_xor (rkeylf, iv6);
+ iv7 = asm_xor (rkeylf, iv7);
+
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ b0 = asm_cipherlast_be (b0, iv0);
+ b1 = asm_cipherlast_be (b1, iv1);
+ b2 = asm_cipherlast_be (b2, iv2);
+ b3 = asm_cipherlast_be (b3, iv3);
+ b4 = asm_cipherlast_be (b4, iv4);
+ b5 = asm_cipherlast_be (b5, iv5);
+ b6 = asm_cipherlast_be (b6, iv6);
+ b7 = asm_cipherlast_be (b7, iv7);
+
+ b0 = VEC_BE_SWAP (b0, bige_const);
+ b1 = VEC_BE_SWAP (b1, bige_const);
+ b2 = VEC_BE_SWAP (b2, bige_const);
+ b3 = VEC_BE_SWAP (b3, bige_const);
+ b4 = VEC_BE_SWAP (b4, bige_const);
+ b5 = VEC_BE_SWAP (b5, bige_const);
+ b6 = VEC_BE_SWAP (b6, bige_const);
+ b7 = VEC_BE_SWAP (b7, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 0, b0);
+ VEC_STORE_BE_NOSWAP (out, 1, b1);
+ VEC_STORE_BE_NOSWAP (out, 2, b2);
+ VEC_STORE_BE_NOSWAP (out, 3, b3);
+ VEC_STORE_BE_NOSWAP (out, 4, b4);
+ VEC_STORE_BE_NOSWAP (out, 5, b5);
+ VEC_STORE_BE_NOSWAP (out, 6, b6);
+ VEC_STORE_BE_NOSWAP (out, 7, b7);
+ out += 8;
+ }
+
+ if (nblocks >= 4 && (data_nblocks % 4) == 0)
+ {
+ b0 = VEC_LOAD_BE (in, 0, bige_const);
+ b1 = VEC_LOAD_BE (in, 1, bige_const);
+ b2 = VEC_LOAD_BE (in, 2, bige_const);
+ b3 = VEC_LOAD_BE (in, 3, bige_const);
+
+ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const);
+
+ ctr ^= b0 ^ b1 ^ b2 ^ b3;
+
+ iv ^= rkey0;
+
+ iv0 = iv ^ l0;
+ iv1 = iv ^ l0 ^ l1;
+ iv2 = iv ^ l1;
+ iv3 = iv ^ l1 ^ l;
+
+ b0 ^= iv0;
+ b1 ^= iv1;
+ b2 ^= iv2;
+ b3 ^= iv3;
+ iv = iv3 ^ rkey0;
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ rkey = rkeylast ^ rkey0;
+ b0 = asm_cipherlast_be (b0, rkey ^ iv0);
+ b1 = asm_cipherlast_be (b1, rkey ^ iv1);
+ b2 = asm_cipherlast_be (b2, rkey ^ iv2);
+ b3 = asm_cipherlast_be (b3, rkey ^ iv3);
+
+ VEC_STORE_BE (out, 0, b0, bige_const);
+ VEC_STORE_BE (out, 1, b1, bige_const);
+ VEC_STORE_BE (out, 2, b2, bige_const);
+ VEC_STORE_BE (out, 3, b3, bige_const);
+
+ in += 4;
+ out += 4;
+ nblocks -= 4;
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const);
+ b = VEC_LOAD_BE (in, 0, bige_const);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ iv ^= l;
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ctr ^= b;
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+ b ^= iv;
+ AES_ENCRYPT (b, rounds);
+ b ^= iv;
+
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ in += 1;
+ out += 1;
+ }
+ }
+ else
+ {
+ const u128_t *rk = (u128_t *)&ctx->keyschdec;
+
+ if (!ctx->decryption_prepared)
+ {
+ internal_aes_ppc_prepare_decryption (ctx);
+ ctx->decryption_prepared = 1;
+ }
+
+ PRELOAD_ROUND_KEYS (rounds);
+
+ for (; nblocks >= 8 && data_nblocks % 8; nblocks--)
+ {
+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const);
+ b = VEC_LOAD_BE (in, 0, bige_const);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ iv ^= l;
+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
+ b ^= iv;
+ AES_DECRYPT (b, rounds);
+ b ^= iv;
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ctr ^= b;
+
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ in += 1;
+ out += 1;
+ }
+
+ for (; nblocks >= 8; nblocks -= 8)
+ {
+ b0 = VEC_LOAD_BE_NOSWAP (in, 0);
+ b1 = VEC_LOAD_BE_NOSWAP (in, 1);
+ b2 = VEC_LOAD_BE_NOSWAP (in, 2);
+ b3 = VEC_LOAD_BE_NOSWAP (in, 3);
+ b4 = VEC_LOAD_BE_NOSWAP (in, 4);
+ b5 = VEC_LOAD_BE_NOSWAP (in, 5);
+ b6 = VEC_LOAD_BE_NOSWAP (in, 6);
+ b7 = VEC_LOAD_BE_NOSWAP (in, 7);
+ in += 8;
+ l = VEC_LOAD_BE_NOSWAP (ocb_get_l (c, data_nblocks += 8), 0);
+ b0 = VEC_BE_SWAP(b0, bige_const);
+ b1 = VEC_BE_SWAP(b1, bige_const);
+ b2 = VEC_BE_SWAP(b2, bige_const);
+ b3 = VEC_BE_SWAP(b3, bige_const);
+ b4 = VEC_BE_SWAP(b4, bige_const);
+ b5 = VEC_BE_SWAP(b5, bige_const);
+ b6 = VEC_BE_SWAP(b6, bige_const);
+ b7 = VEC_BE_SWAP(b7, bige_const);
+ l = VEC_BE_SWAP(l, bige_const);
+
+ iv ^= rkey0;
+
+ iv0 = iv ^ l0;
+ iv1 = iv ^ l0 ^ l1;
+ iv2 = iv ^ l1;
+ iv3 = iv ^ l1 ^ l2;
+ iv4 = iv ^ l1 ^ l2 ^ l0;
+ iv5 = iv ^ l2 ^ l0;
+ iv6 = iv ^ l2;
+ iv7 = iv ^ l2 ^ l;
+
+ b0 ^= iv0;
+ b1 ^= iv1;
+ b2 ^= iv2;
+ b3 ^= iv3;
+ b4 ^= iv4;
+ b5 ^= iv5;
+ b6 ^= iv6;
+ b7 ^= iv7;
+ iv = iv7 ^ rkey0;
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_ncipher_be (b0, rkey); \
+ b1 = asm_ncipher_be (b1, rkey); \
+ b2 = asm_ncipher_be (b2, rkey); \
+ b3 = asm_ncipher_be (b3, rkey); \
+ b4 = asm_ncipher_be (b4, rkey); \
+ b5 = asm_ncipher_be (b5, rkey); \
+ b6 = asm_ncipher_be (b6, rkey); \
+ b7 = asm_ncipher_be (b7, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+
+ rkeylf = asm_xor (rkeylast, rkey0);
+
+ DO_ROUND(8);
+
+ iv0 = asm_xor (rkeylf, iv0);
+ iv1 = asm_xor (rkeylf, iv1);
+ iv2 = asm_xor (rkeylf, iv2);
+ iv3 = asm_xor (rkeylf, iv3);
+ iv4 = asm_xor (rkeylf, iv4);
+ iv5 = asm_xor (rkeylf, iv5);
+ iv6 = asm_xor (rkeylf, iv6);
+ iv7 = asm_xor (rkeylf, iv7);
+
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ b0 = asm_ncipherlast_be (b0, iv0);
+ b1 = asm_ncipherlast_be (b1, iv1);
+ b2 = asm_ncipherlast_be (b2, iv2);
+ b3 = asm_ncipherlast_be (b3, iv3);
+ b4 = asm_ncipherlast_be (b4, iv4);
+ b5 = asm_ncipherlast_be (b5, iv5);
+ b6 = asm_ncipherlast_be (b6, iv6);
+ b7 = asm_ncipherlast_be (b7, iv7);
+
+ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7;
+
+ b0 = VEC_BE_SWAP (b0, bige_const);
+ b1 = VEC_BE_SWAP (b1, bige_const);
+ b2 = VEC_BE_SWAP (b2, bige_const);
+ b3 = VEC_BE_SWAP (b3, bige_const);
+ b4 = VEC_BE_SWAP (b4, bige_const);
+ b5 = VEC_BE_SWAP (b5, bige_const);
+ b6 = VEC_BE_SWAP (b6, bige_const);
+ b7 = VEC_BE_SWAP (b7, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 0, b0);
+ VEC_STORE_BE_NOSWAP (out, 1, b1);
+ VEC_STORE_BE_NOSWAP (out, 2, b2);
+ VEC_STORE_BE_NOSWAP (out, 3, b3);
+ VEC_STORE_BE_NOSWAP (out, 4, b4);
+ VEC_STORE_BE_NOSWAP (out, 5, b5);
+ VEC_STORE_BE_NOSWAP (out, 6, b6);
+ VEC_STORE_BE_NOSWAP (out, 7, b7);
+ out += 8;
+ }
+
+ if (nblocks >= 4 && (data_nblocks % 4) == 0)
+ {
+ b0 = VEC_LOAD_BE (in, 0, bige_const);
+ b1 = VEC_LOAD_BE (in, 1, bige_const);
+ b2 = VEC_LOAD_BE (in, 2, bige_const);
+ b3 = VEC_LOAD_BE (in, 3, bige_const);
+
+ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const);
+
+ iv ^= rkey0;
+
+ iv0 = iv ^ l0;
+ iv1 = iv ^ l0 ^ l1;
+ iv2 = iv ^ l1;
+ iv3 = iv ^ l1 ^ l;
+
+ b0 ^= iv0;
+ b1 ^= iv1;
+ b2 ^= iv2;
+ b3 ^= iv3;
+ iv = iv3 ^ rkey0;
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_ncipher_be (b0, rkey); \
+ b1 = asm_ncipher_be (b1, rkey); \
+ b2 = asm_ncipher_be (b2, rkey); \
+ b3 = asm_ncipher_be (b3, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ rkey = rkeylast ^ rkey0;
+ b0 = asm_ncipherlast_be (b0, rkey ^ iv0);
+ b1 = asm_ncipherlast_be (b1, rkey ^ iv1);
+ b2 = asm_ncipherlast_be (b2, rkey ^ iv2);
+ b3 = asm_ncipherlast_be (b3, rkey ^ iv3);
+
+ VEC_STORE_BE (out, 0, b0, bige_const);
+ VEC_STORE_BE (out, 1, b1, bige_const);
+ VEC_STORE_BE (out, 2, b2, bige_const);
+ VEC_STORE_BE (out, 3, b3, bige_const);
+
+ ctr ^= b0 ^ b1 ^ b2 ^ b3;
+
+ in += 4;
+ out += 4;
+ nblocks -= 4;
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const);
+ b = VEC_LOAD_BE (in, 0, bige_const);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ iv ^= l;
+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
+ b ^= iv;
+ AES_DECRYPT (b, rounds);
+ b ^= iv;
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ ctr ^= b;
+
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ in += 1;
+ out += 1;
+ }
+ }
+
+ VEC_STORE_BE (c->u_iv.iv, 0, iv, bige_const);
+ VEC_STORE_BE (c->u_ctr.ctr, 0, ctr, bige_const);
+ c->u_mode.ocb.data_nblocks = data_nblocks;
+
+ return 0;
+}
+
+size_t OCB_AUTH_FUNC (gcry_cipher_hd_t c, void *abuf_arg, size_t nblocks)
+{
+ const block bige_const = asm_load_be_const();
+ RIJNDAEL_context *ctx = (void *)&c->context.c;
+ const u128_t *rk = (u128_t *)&ctx->keyschenc;
+ const u128_t *abuf = (const u128_t *)abuf_arg;
+ int rounds = ctx->rounds;
+ u64 data_nblocks = c->u_mode.ocb.aad_nblocks;
+ block l0, l1, l2, l;
+ block b0, b1, b2, b3, b4, b5, b6, b7, b;
+ block iv0, iv1, iv2, iv3, iv4, iv5, iv6, iv7;
+ block rkey, frkey;
+ block ctr, iv;
+ ROUND_KEY_VARIABLES;
+
+ iv = VEC_LOAD_BE (c->u_mode.ocb.aad_offset, 0, bige_const);
+ ctr = VEC_LOAD_BE (c->u_mode.ocb.aad_sum, 0, bige_const);
+
+ l0 = VEC_LOAD_BE (c->u_mode.ocb.L[0], 0, bige_const);
+ l1 = VEC_LOAD_BE (c->u_mode.ocb.L[1], 0, bige_const);
+ l2 = VEC_LOAD_BE (c->u_mode.ocb.L[2], 0, bige_const);
+
+ PRELOAD_ROUND_KEYS (rounds);
+
+ for (; nblocks >= 8 && data_nblocks % 8; nblocks--)
+ {
+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const);
+ b = VEC_LOAD_BE (abuf, 0, bige_const);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ iv ^= l;
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+ b ^= iv;
+ AES_ENCRYPT (b, rounds);
+ ctr ^= b;
+
+ abuf += 1;
+ }
+
+ for (; nblocks >= 8; nblocks -= 8)
+ {
+ b0 = VEC_LOAD_BE (abuf, 0, bige_const);
+ b1 = VEC_LOAD_BE (abuf, 1, bige_const);
+ b2 = VEC_LOAD_BE (abuf, 2, bige_const);
+ b3 = VEC_LOAD_BE (abuf, 3, bige_const);
+ b4 = VEC_LOAD_BE (abuf, 4, bige_const);
+ b5 = VEC_LOAD_BE (abuf, 5, bige_const);
+ b6 = VEC_LOAD_BE (abuf, 6, bige_const);
+ b7 = VEC_LOAD_BE (abuf, 7, bige_const);
+
+ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 8), 0, bige_const);
+
+ frkey = rkey0;
+ iv ^= frkey;
+
+ iv0 = iv ^ l0;
+ iv1 = iv ^ l0 ^ l1;
+ iv2 = iv ^ l1;
+ iv3 = iv ^ l1 ^ l2;
+ iv4 = iv ^ l1 ^ l2 ^ l0;
+ iv5 = iv ^ l2 ^ l0;
+ iv6 = iv ^ l2;
+ iv7 = iv ^ l2 ^ l;
+
+ b0 ^= iv0;
+ b1 ^= iv1;
+ b2 ^= iv2;
+ b3 ^= iv3;
+ b4 ^= iv4;
+ b5 ^= iv5;
+ b6 ^= iv6;
+ b7 ^= iv7;
+ iv = iv7 ^ frkey;
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey); \
+ b4 = asm_cipher_be (b4, rkey); \
+ b5 = asm_cipher_be (b5, rkey); \
+ b6 = asm_cipher_be (b6, rkey); \
+ b7 = asm_cipher_be (b7, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ rkey = rkeylast;
+ b0 = asm_cipherlast_be (b0, rkey);
+ b1 = asm_cipherlast_be (b1, rkey);
+ b2 = asm_cipherlast_be (b2, rkey);
+ b3 = asm_cipherlast_be (b3, rkey);
+ b4 = asm_cipherlast_be (b4, rkey);
+ b5 = asm_cipherlast_be (b5, rkey);
+ b6 = asm_cipherlast_be (b6, rkey);
+ b7 = asm_cipherlast_be (b7, rkey);
+
+ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7;
+
+ abuf += 8;
+ }
+
+ if (nblocks >= 4 && (data_nblocks % 4) == 0)
+ {
+ b0 = VEC_LOAD_BE (abuf, 0, bige_const);
+ b1 = VEC_LOAD_BE (abuf, 1, bige_const);
+ b2 = VEC_LOAD_BE (abuf, 2, bige_const);
+ b3 = VEC_LOAD_BE (abuf, 3, bige_const);
+
+ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const);
+
+ frkey = rkey0;
+ iv ^= frkey;
+
+ iv0 = iv ^ l0;
+ iv1 = iv ^ l0 ^ l1;
+ iv2 = iv ^ l1;
+ iv3 = iv ^ l1 ^ l;
+
+ b0 ^= iv0;
+ b1 ^= iv1;
+ b2 ^= iv2;
+ b3 ^= iv3;
+ iv = iv3 ^ frkey;
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ rkey = rkeylast;
+ b0 = asm_cipherlast_be (b0, rkey);
+ b1 = asm_cipherlast_be (b1, rkey);
+ b2 = asm_cipherlast_be (b2, rkey);
+ b3 = asm_cipherlast_be (b3, rkey);
+
+ ctr ^= b0 ^ b1 ^ b2 ^ b3;
+
+ abuf += 4;
+ nblocks -= 4;
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const);
+ b = VEC_LOAD_BE (abuf, 0, bige_const);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ iv ^= l;
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+ b ^= iv;
+ AES_ENCRYPT (b, rounds);
+ ctr ^= b;
+
+ abuf += 1;
+ }
+
+ VEC_STORE_BE (c->u_mode.ocb.aad_offset, 0, iv, bige_const);
+ VEC_STORE_BE (c->u_mode.ocb.aad_sum, 0, ctr, bige_const);
+ c->u_mode.ocb.aad_nblocks = data_nblocks;
+
+ return 0;
+}
+
+
+void XTS_CRYPT_FUNC (void *context, unsigned char *tweak_arg,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks, int encrypt)
+{
+#ifdef WORDS_BIGENDIAN
+ static const block vec_bswap128_const =
+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+#else
+ static const block vec_bswap128_const =
+ { ~15, ~14, ~13, ~12, ~11, ~10, ~9, ~8, ~7, ~6, ~5, ~4, ~3, ~2, ~1, ~0 };
+#endif
+ static const unsigned char vec_tweak_const[16] =
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x87 };
+ static const vector unsigned long long vec_shift63_const =
+ { 63, 63 };
+ const block bige_const = asm_load_be_const();
+ RIJNDAEL_context *ctx = context;
+ const u128_t *in = (const u128_t *)inbuf_arg;
+ u128_t *out = (u128_t *)outbuf_arg;
+ int rounds = ctx->rounds;
+ block tweak;
+ block b0, b1, b2, b3, b4, b5, b6, b7, b, rkey, rkeylf;
+ block tweak0, tweak1, tweak2, tweak3, tweak4, tweak5, tweak6, tweak7;
+ block tweak_const, bswap128_const, shift63_const;
+ ROUND_KEY_VARIABLES;
+
+ tweak_const = VEC_LOAD_BE (&vec_tweak_const, 0, bige_const);
+ bswap128_const = ALIGNED_LOAD (&vec_bswap128_const, 0);
+ shift63_const = ALIGNED_LOAD (&vec_shift63_const, 0);
+
+ tweak = VEC_LOAD_BE (tweak_arg, 0, bige_const);
+ tweak = asm_vperm1 (tweak, bswap128_const);
+
+#define GEN_TWEAK(tout, tin) /* Generate next tweak. */ \
+ do { \
+ block tmp1, tmp2; \
+ tmp1 = asm_swap_uint64_halfs(tin); \
+ tmp2 = asm_add_uint64(tin, tin); \
+ tmp1 = asm_sra_int64(tmp1, shift63_const) & tweak_const; \
+ tout = asm_xor(tmp1, tmp2); \
+ } while (0)
+
+ if (encrypt)
+ {
+ const u128_t *rk = (u128_t *)&ctx->keyschenc;
+
+ PRELOAD_ROUND_KEYS (rounds);
+
+ for (; nblocks >= 8; nblocks -= 8)
+ {
+ b0 = VEC_LOAD_BE_NOSWAP (in, 0);
+ b1 = VEC_LOAD_BE_NOSWAP (in, 1);
+ b2 = VEC_LOAD_BE_NOSWAP (in, 2);
+ b3 = VEC_LOAD_BE_NOSWAP (in, 3);
+ tweak0 = tweak;
+ GEN_TWEAK (tweak1, tweak0);
+ tweak0 = asm_vperm1 (tweak0, bswap128_const);
+ b4 = VEC_LOAD_BE_NOSWAP (in, 4);
+ b5 = VEC_LOAD_BE_NOSWAP (in, 5);
+ GEN_TWEAK (tweak2, tweak1);
+ tweak1 = asm_vperm1 (tweak1, bswap128_const);
+ b6 = VEC_LOAD_BE_NOSWAP (in, 6);
+ b7 = VEC_LOAD_BE_NOSWAP (in, 7);
+ in += 8;
+
+ b0 = VEC_BE_SWAP(b0, bige_const);
+ b1 = VEC_BE_SWAP(b1, bige_const);
+ GEN_TWEAK (tweak3, tweak2);
+ tweak2 = asm_vperm1 (tweak2, bswap128_const);
+ GEN_TWEAK (tweak4, tweak3);
+ tweak3 = asm_vperm1 (tweak3, bswap128_const);
+ b2 = VEC_BE_SWAP(b2, bige_const);
+ b3 = VEC_BE_SWAP(b3, bige_const);
+ GEN_TWEAK (tweak5, tweak4);
+ tweak4 = asm_vperm1 (tweak4, bswap128_const);
+ GEN_TWEAK (tweak6, tweak5);
+ tweak5 = asm_vperm1 (tweak5, bswap128_const);
+ b4 = VEC_BE_SWAP(b4, bige_const);
+ b5 = VEC_BE_SWAP(b5, bige_const);
+ GEN_TWEAK (tweak7, tweak6);
+ tweak6 = asm_vperm1 (tweak6, bswap128_const);
+ GEN_TWEAK (tweak, tweak7);
+ tweak7 = asm_vperm1 (tweak7, bswap128_const);
+ b6 = VEC_BE_SWAP(b6, bige_const);
+ b7 = VEC_BE_SWAP(b7, bige_const);
+
+ tweak0 = asm_xor (tweak0, rkey0);
+ tweak1 = asm_xor (tweak1, rkey0);
+ tweak2 = asm_xor (tweak2, rkey0);
+ tweak3 = asm_xor (tweak3, rkey0);
+ tweak4 = asm_xor (tweak4, rkey0);
+ tweak5 = asm_xor (tweak5, rkey0);
+ tweak6 = asm_xor (tweak6, rkey0);
+ tweak7 = asm_xor (tweak7, rkey0);
+
+ b0 = asm_xor (b0, tweak0);
+ b1 = asm_xor (b1, tweak1);
+ b2 = asm_xor (b2, tweak2);
+ b3 = asm_xor (b3, tweak3);
+ b4 = asm_xor (b4, tweak4);
+ b5 = asm_xor (b5, tweak5);
+ b6 = asm_xor (b6, tweak6);
+ b7 = asm_xor (b7, tweak7);
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey); \
+ b4 = asm_cipher_be (b4, rkey); \
+ b5 = asm_cipher_be (b5, rkey); \
+ b6 = asm_cipher_be (b6, rkey); \
+ b7 = asm_cipher_be (b7, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+
+ rkeylf = asm_xor (rkeylast, rkey0);
+
+ DO_ROUND(8);
+
+ tweak0 = asm_xor (tweak0, rkeylf);
+ tweak1 = asm_xor (tweak1, rkeylf);
+ tweak2 = asm_xor (tweak2, rkeylf);
+ tweak3 = asm_xor (tweak3, rkeylf);
+ tweak4 = asm_xor (tweak4, rkeylf);
+ tweak5 = asm_xor (tweak5, rkeylf);
+ tweak6 = asm_xor (tweak6, rkeylf);
+ tweak7 = asm_xor (tweak7, rkeylf);
+
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ b0 = asm_cipherlast_be (b0, tweak0);
+ b1 = asm_cipherlast_be (b1, tweak1);
+ b2 = asm_cipherlast_be (b2, tweak2);
+ b3 = asm_cipherlast_be (b3, tweak3);
+ b0 = VEC_BE_SWAP (b0, bige_const);
+ b1 = VEC_BE_SWAP (b1, bige_const);
+ b4 = asm_cipherlast_be (b4, tweak4);
+ b5 = asm_cipherlast_be (b5, tweak5);
+ b2 = VEC_BE_SWAP (b2, bige_const);
+ b3 = VEC_BE_SWAP (b3, bige_const);
+ b6 = asm_cipherlast_be (b6, tweak6);
+ b7 = asm_cipherlast_be (b7, tweak7);
+ VEC_STORE_BE_NOSWAP (out, 0, b0);
+ VEC_STORE_BE_NOSWAP (out, 1, b1);
+ b4 = VEC_BE_SWAP (b4, bige_const);
+ b5 = VEC_BE_SWAP (b5, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 2, b2);
+ VEC_STORE_BE_NOSWAP (out, 3, b3);
+ b6 = VEC_BE_SWAP (b6, bige_const);
+ b7 = VEC_BE_SWAP (b7, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 4, b4);
+ VEC_STORE_BE_NOSWAP (out, 5, b5);
+ VEC_STORE_BE_NOSWAP (out, 6, b6);
+ VEC_STORE_BE_NOSWAP (out, 7, b7);
+ out += 8;
+ }
+
+ if (nblocks >= 4)
+ {
+ tweak0 = tweak;
+ GEN_TWEAK (tweak1, tweak0);
+ GEN_TWEAK (tweak2, tweak1);
+ GEN_TWEAK (tweak3, tweak2);
+ GEN_TWEAK (tweak, tweak3);
+
+ b0 = VEC_LOAD_BE (in, 0, bige_const);
+ b1 = VEC_LOAD_BE (in, 1, bige_const);
+ b2 = VEC_LOAD_BE (in, 2, bige_const);
+ b3 = VEC_LOAD_BE (in, 3, bige_const);
+
+ tweak0 = asm_vperm1 (tweak0, bswap128_const);
+ tweak1 = asm_vperm1 (tweak1, bswap128_const);
+ tweak2 = asm_vperm1 (tweak2, bswap128_const);
+ tweak3 = asm_vperm1 (tweak3, bswap128_const);
+
+ b0 ^= tweak0 ^ rkey0;
+ b1 ^= tweak1 ^ rkey0;
+ b2 ^= tweak2 ^ rkey0;
+ b3 ^= tweak3 ^ rkey0;
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_cipher_be (b0, rkey); \
+ b1 = asm_cipher_be (b1, rkey); \
+ b2 = asm_cipher_be (b2, rkey); \
+ b3 = asm_cipher_be (b3, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ rkey = rkeylast;
+ b0 = asm_cipherlast_be (b0, rkey ^ tweak0);
+ b1 = asm_cipherlast_be (b1, rkey ^ tweak1);
+ b2 = asm_cipherlast_be (b2, rkey ^ tweak2);
+ b3 = asm_cipherlast_be (b3, rkey ^ tweak3);
+
+ VEC_STORE_BE (out, 0, b0, bige_const);
+ VEC_STORE_BE (out, 1, b1, bige_const);
+ VEC_STORE_BE (out, 2, b2, bige_const);
+ VEC_STORE_BE (out, 3, b3, bige_const);
+
+ in += 4;
+ out += 4;
+ nblocks -= 4;
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ tweak0 = asm_vperm1 (tweak, bswap128_const);
+
+ /* Xor-Encrypt/Decrypt-Xor block. */
+ b = VEC_LOAD_BE (in, 0, bige_const) ^ tweak0;
+
+ /* Generate next tweak. */
+ GEN_TWEAK (tweak, tweak);
+
+ AES_ENCRYPT (b, rounds);
+
+ b ^= tweak0;
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ in++;
+ out++;
+ }
+ }
+ else
+ {
+ const u128_t *rk = (u128_t *)&ctx->keyschdec;
+
+ if (!ctx->decryption_prepared)
+ {
+ internal_aes_ppc_prepare_decryption (ctx);
+ ctx->decryption_prepared = 1;
+ }
+
+ PRELOAD_ROUND_KEYS (rounds);
+
+ for (; nblocks >= 8; nblocks -= 8)
+ {
+ b0 = VEC_LOAD_BE_NOSWAP (in, 0);
+ b1 = VEC_LOAD_BE_NOSWAP (in, 1);
+ b2 = VEC_LOAD_BE_NOSWAP (in, 2);
+ b3 = VEC_LOAD_BE_NOSWAP (in, 3);
+ tweak0 = tweak;
+ GEN_TWEAK (tweak1, tweak0);
+ tweak0 = asm_vperm1 (tweak0, bswap128_const);
+ b4 = VEC_LOAD_BE_NOSWAP (in, 4);
+ b5 = VEC_LOAD_BE_NOSWAP (in, 5);
+ GEN_TWEAK (tweak2, tweak1);
+ tweak1 = asm_vperm1 (tweak1, bswap128_const);
+ b6 = VEC_LOAD_BE_NOSWAP (in, 6);
+ b7 = VEC_LOAD_BE_NOSWAP (in, 7);
+ in += 8;
+
+ b0 = VEC_BE_SWAP(b0, bige_const);
+ b1 = VEC_BE_SWAP(b1, bige_const);
+ GEN_TWEAK (tweak3, tweak2);
+ tweak2 = asm_vperm1 (tweak2, bswap128_const);
+ GEN_TWEAK (tweak4, tweak3);
+ tweak3 = asm_vperm1 (tweak3, bswap128_const);
+ b2 = VEC_BE_SWAP(b2, bige_const);
+ b3 = VEC_BE_SWAP(b3, bige_const);
+ GEN_TWEAK (tweak5, tweak4);
+ tweak4 = asm_vperm1 (tweak4, bswap128_const);
+ GEN_TWEAK (tweak6, tweak5);
+ tweak5 = asm_vperm1 (tweak5, bswap128_const);
+ b4 = VEC_BE_SWAP(b4, bige_const);
+ b5 = VEC_BE_SWAP(b5, bige_const);
+ GEN_TWEAK (tweak7, tweak6);
+ tweak6 = asm_vperm1 (tweak6, bswap128_const);
+ GEN_TWEAK (tweak, tweak7);
+ tweak7 = asm_vperm1 (tweak7, bswap128_const);
+ b6 = VEC_BE_SWAP(b6, bige_const);
+ b7 = VEC_BE_SWAP(b7, bige_const);
+
+ tweak0 = asm_xor (tweak0, rkey0);
+ tweak1 = asm_xor (tweak1, rkey0);
+ tweak2 = asm_xor (tweak2, rkey0);
+ tweak3 = asm_xor (tweak3, rkey0);
+ tweak4 = asm_xor (tweak4, rkey0);
+ tweak5 = asm_xor (tweak5, rkey0);
+ tweak6 = asm_xor (tweak6, rkey0);
+ tweak7 = asm_xor (tweak7, rkey0);
+
+ b0 = asm_xor (b0, tweak0);
+ b1 = asm_xor (b1, tweak1);
+ b2 = asm_xor (b2, tweak2);
+ b3 = asm_xor (b3, tweak3);
+ b4 = asm_xor (b4, tweak4);
+ b5 = asm_xor (b5, tweak5);
+ b6 = asm_xor (b6, tweak6);
+ b7 = asm_xor (b7, tweak7);
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_ncipher_be (b0, rkey); \
+ b1 = asm_ncipher_be (b1, rkey); \
+ b2 = asm_ncipher_be (b2, rkey); \
+ b3 = asm_ncipher_be (b3, rkey); \
+ b4 = asm_ncipher_be (b4, rkey); \
+ b5 = asm_ncipher_be (b5, rkey); \
+ b6 = asm_ncipher_be (b6, rkey); \
+ b7 = asm_ncipher_be (b7, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+
+ rkeylf = asm_xor (rkeylast, rkey0);
+
+ DO_ROUND(8);
+
+ tweak0 = asm_xor (tweak0, rkeylf);
+ tweak1 = asm_xor (tweak1, rkeylf);
+ tweak2 = asm_xor (tweak2, rkeylf);
+ tweak3 = asm_xor (tweak3, rkeylf);
+ tweak4 = asm_xor (tweak4, rkeylf);
+ tweak5 = asm_xor (tweak5, rkeylf);
+ tweak6 = asm_xor (tweak6, rkeylf);
+ tweak7 = asm_xor (tweak7, rkeylf);
+
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ b0 = asm_ncipherlast_be (b0, tweak0);
+ b1 = asm_ncipherlast_be (b1, tweak1);
+ b2 = asm_ncipherlast_be (b2, tweak2);
+ b3 = asm_ncipherlast_be (b3, tweak3);
+ b0 = VEC_BE_SWAP (b0, bige_const);
+ b1 = VEC_BE_SWAP (b1, bige_const);
+ b4 = asm_ncipherlast_be (b4, tweak4);
+ b5 = asm_ncipherlast_be (b5, tweak5);
+ b2 = VEC_BE_SWAP (b2, bige_const);
+ b3 = VEC_BE_SWAP (b3, bige_const);
+ b6 = asm_ncipherlast_be (b6, tweak6);
+ b7 = asm_ncipherlast_be (b7, tweak7);
+ VEC_STORE_BE_NOSWAP (out, 0, b0);
+ VEC_STORE_BE_NOSWAP (out, 1, b1);
+ b4 = VEC_BE_SWAP (b4, bige_const);
+ b5 = VEC_BE_SWAP (b5, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 2, b2);
+ VEC_STORE_BE_NOSWAP (out, 3, b3);
+ b6 = VEC_BE_SWAP (b6, bige_const);
+ b7 = VEC_BE_SWAP (b7, bige_const);
+ VEC_STORE_BE_NOSWAP (out, 4, b4);
+ VEC_STORE_BE_NOSWAP (out, 5, b5);
+ VEC_STORE_BE_NOSWAP (out, 6, b6);
+ VEC_STORE_BE_NOSWAP (out, 7, b7);
+ out += 8;
+ }
+
+ if (nblocks >= 4)
+ {
+ tweak0 = tweak;
+ GEN_TWEAK (tweak1, tweak0);
+ GEN_TWEAK (tweak2, tweak1);
+ GEN_TWEAK (tweak3, tweak2);
+ GEN_TWEAK (tweak, tweak3);
+
+ b0 = VEC_LOAD_BE (in, 0, bige_const);
+ b1 = VEC_LOAD_BE (in, 1, bige_const);
+ b2 = VEC_LOAD_BE (in, 2, bige_const);
+ b3 = VEC_LOAD_BE (in, 3, bige_const);
+
+ tweak0 = asm_vperm1 (tweak0, bswap128_const);
+ tweak1 = asm_vperm1 (tweak1, bswap128_const);
+ tweak2 = asm_vperm1 (tweak2, bswap128_const);
+ tweak3 = asm_vperm1 (tweak3, bswap128_const);
+
+ b0 ^= tweak0 ^ rkey0;
+ b1 ^= tweak1 ^ rkey0;
+ b2 ^= tweak2 ^ rkey0;
+ b3 ^= tweak3 ^ rkey0;
+
+#define DO_ROUND(r) \
+ rkey = ALIGNED_LOAD (rk, r); \
+ b0 = asm_ncipher_be (b0, rkey); \
+ b1 = asm_ncipher_be (b1, rkey); \
+ b2 = asm_ncipher_be (b2, rkey); \
+ b3 = asm_ncipher_be (b3, rkey);
+
+ DO_ROUND(1);
+ DO_ROUND(2);
+ DO_ROUND(3);
+ DO_ROUND(4);
+ DO_ROUND(5);
+ DO_ROUND(6);
+ DO_ROUND(7);
+ DO_ROUND(8);
+ DO_ROUND(9);
+ if (rounds >= 12)
+ {
+ DO_ROUND(10);
+ DO_ROUND(11);
+ if (rounds > 12)
+ {
+ DO_ROUND(12);
+ DO_ROUND(13);
+ }
+ }
+
+#undef DO_ROUND
+
+ rkey = rkeylast;
+ b0 = asm_ncipherlast_be (b0, rkey ^ tweak0);
+ b1 = asm_ncipherlast_be (b1, rkey ^ tweak1);
+ b2 = asm_ncipherlast_be (b2, rkey ^ tweak2);
+ b3 = asm_ncipherlast_be (b3, rkey ^ tweak3);
+
+ VEC_STORE_BE (out, 0, b0, bige_const);
+ VEC_STORE_BE (out, 1, b1, bige_const);
+ VEC_STORE_BE (out, 2, b2, bige_const);
+ VEC_STORE_BE (out, 3, b3, bige_const);
+
+ in += 4;
+ out += 4;
+ nblocks -= 4;
+ }
+
+ for (; nblocks; nblocks--)
+ {
+ tweak0 = asm_vperm1 (tweak, bswap128_const);
+
+ /* Xor-Encrypt/Decrypt-Xor block. */
+ b = VEC_LOAD_BE (in, 0, bige_const) ^ tweak0;
+
+ /* Generate next tweak. */
+ GEN_TWEAK (tweak, tweak);
+
+ AES_DECRYPT (b, rounds);
+
+ b ^= tweak0;
+ VEC_STORE_BE (out, 0, b, bige_const);
+
+ in++;
+ out++;
+ }
+ }
+
+ tweak = asm_vperm1 (tweak, bswap128_const);
+ VEC_STORE_BE (tweak_arg, 0, tweak, bige_const);
+
+#undef GEN_TWEAK
+}
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-ppc.c b/comm/third_party/libgcrypt/cipher/rijndael-ppc.c
new file mode 100644
index 0000000000..f5c3236111
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-ppc.c
@@ -0,0 +1,259 @@
+/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation
+ * Copyright (C) 2019 Shawn Landden <shawn@git.icu>
+ * Copyright (C) 2019-2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project,
+ * and Cryptogams by Andy Polyakov, and if made part of a release of either
+ * or both projects, is thereafter dual-licensed under the license said project
+ * is released under.
+ */
+
+#include <config.h>
+
+#include "rijndael-internal.h"
+#include "cipher-internal.h"
+#include "bufhelp.h"
+
+#ifdef USE_PPC_CRYPTO
+
+#include "rijndael-ppc-common.h"
+
+
+#ifdef WORDS_BIGENDIAN
+static const block vec_bswap32_const =
+ { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 };
+#else
+static const block vec_bswap32_const_neg =
+ { ~3, ~2, ~1, ~0, ~7, ~6, ~5, ~4, ~11, ~10, ~9, ~8, ~15, ~14, ~13, ~12 };
+#endif
+
+
+static ASM_FUNC_ATTR_INLINE block
+asm_load_be_const(void)
+{
+#ifndef WORDS_BIGENDIAN
+ return ALIGNED_LOAD (&vec_bswap32_const_neg, 0);
+#else
+ static const block vec_dummy = { 0 };
+ return vec_dummy;
+#endif
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_be_swap(block vec, block be_bswap_const)
+{
+ (void)be_bswap_const;
+#ifndef WORDS_BIGENDIAN
+ return asm_vperm1 (vec, be_bswap_const);
+#else
+ return vec;
+#endif
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_load_be_noswap(unsigned long offset, const void *ptr)
+{
+ block vec;
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ volatile ("lxvw4x %x0,0,%1\n\t"
+ : "=wa" (vec)
+ : "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ volatile ("lxvw4x %x0,%1,%2\n\t"
+ : "=wa" (vec)
+ : "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+ /* NOTE: vec needs to be be-swapped using 'asm_be_swap' by caller */
+ return vec;
+}
+
+static ASM_FUNC_ATTR_INLINE void
+asm_store_be_noswap(block vec, unsigned long offset, void *ptr)
+{
+ /* NOTE: vec be-swapped using 'asm_be_swap' by caller */
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ volatile ("stxvw4x %x0,0,%1\n\t"
+ :
+ : "wa" (vec), "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ volatile ("stxvw4x %x0,%1,%2\n\t"
+ :
+ : "wa" (vec), "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+}
+
+
+static ASM_FUNC_ATTR_INLINE u32
+_gcry_aes_sbox4_ppc8(u32 fourbytes)
+{
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ block data_vec;
+ u32 data32[4];
+ } u;
+
+ u.data32[0] = fourbytes;
+ u.data_vec = vec_sbox_be(u.data_vec);
+ return u.data32[0];
+}
+
+void
+_gcry_aes_ppc8_setkey (RIJNDAEL_context *ctx, const byte *key)
+{
+ const block bige_const = asm_load_be_const();
+ 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;
+ u128_t *ekey = (u128_t *)(void *)ctx->keyschenc;
+ 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] ^=
+ le_bswap32(
+ _gcry_aes_sbox4_ppc8(rol(le_bswap32(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] ^=
+ le_bswap32(_gcry_aes_sbox4_ppc8(le_bswap32(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);
+ }
+
+ /* Store in big-endian order. */
+ for (r = 0; r <= rounds; r++)
+ {
+#ifndef WORDS_BIGENDIAN
+ VEC_STORE_BE(ekey, r, ALIGNED_LOAD (ekey, r), bige_const);
+#else
+ block rvec = ALIGNED_LOAD (ekey, r);
+ ALIGNED_STORE (ekey, r,
+ vec_perm(rvec, rvec, vec_bswap32_const));
+ (void)bige_const;
+#endif
+ }
+
+#undef W
+#undef tk
+#undef k
+#undef W_u32
+#undef tk_u32
+#undef k_u32
+ wipememory(&tkk, sizeof(tkk));
+}
+
+void
+_gcry_aes_ppc8_prepare_decryption (RIJNDAEL_context *ctx)
+{
+ internal_aes_ppc_prepare_decryption (ctx);
+}
+
+
+#define GCRY_AES_PPC8 1
+#define ENCRYPT_BLOCK_FUNC _gcry_aes_ppc8_encrypt
+#define DECRYPT_BLOCK_FUNC _gcry_aes_ppc8_decrypt
+#define CFB_ENC_FUNC _gcry_aes_ppc8_cfb_enc
+#define CFB_DEC_FUNC _gcry_aes_ppc8_cfb_dec
+#define CBC_ENC_FUNC _gcry_aes_ppc8_cbc_enc
+#define CBC_DEC_FUNC _gcry_aes_ppc8_cbc_dec
+#define CTR_ENC_FUNC _gcry_aes_ppc8_ctr_enc
+#define OCB_CRYPT_FUNC _gcry_aes_ppc8_ocb_crypt
+#define OCB_AUTH_FUNC _gcry_aes_ppc8_ocb_auth
+#define XTS_CRYPT_FUNC _gcry_aes_ppc8_xts_crypt
+
+#include <rijndael-ppc-functions.h>
+
+#endif /* USE_PPC_CRYPTO */
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-ppc9le.c b/comm/third_party/libgcrypt/cipher/rijndael-ppc9le.c
new file mode 100644
index 0000000000..facdedd4f2
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-ppc9le.c
@@ -0,0 +1,102 @@
+/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation
+ * Copyright (C) 2019 Shawn Landden <shawn@git.icu>
+ * Copyright (C) 2019-2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project,
+ * and Cryptogams by Andy Polyakov, and if made part of a release of either
+ * or both projects, is thereafter dual-licensed under the license said project
+ * is released under.
+ */
+
+#include <config.h>
+
+#include "rijndael-internal.h"
+#include "cipher-internal.h"
+#include "bufhelp.h"
+
+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE
+
+#include "rijndael-ppc-common.h"
+
+
+static ASM_FUNC_ATTR_INLINE block
+asm_load_be_const(void)
+{
+ static const block vec_dummy = { 0 };
+ return vec_dummy;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_be_swap(block vec, block be_bswap_const)
+{
+ (void)be_bswap_const;
+ return vec;
+}
+
+static ASM_FUNC_ATTR_INLINE block
+asm_load_be_noswap(unsigned long offset, const void *ptr)
+{
+ block vec;
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ volatile ("lxvb16x %x0,0,%1\n\t"
+ : "=wa" (vec)
+ : "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ volatile ("lxvb16x %x0,%1,%2\n\t"
+ : "=wa" (vec)
+ : "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+ return vec;
+}
+
+static ASM_FUNC_ATTR_INLINE void
+asm_store_be_noswap(block vec, unsigned long offset, void *ptr)
+{
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ volatile ("stxvb16x %x0,0,%1\n\t"
+ :
+ : "wa" (vec), "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ volatile ("stxvb16x %x0,%1,%2\n\t"
+ :
+ : "wa" (vec), "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+}
+
+
+#define GCRY_AES_PPC9LE 1
+#define ENCRYPT_BLOCK_FUNC _gcry_aes_ppc9le_encrypt
+#define DECRYPT_BLOCK_FUNC _gcry_aes_ppc9le_decrypt
+#define CFB_ENC_FUNC _gcry_aes_ppc9le_cfb_enc
+#define CFB_DEC_FUNC _gcry_aes_ppc9le_cfb_dec
+#define CBC_ENC_FUNC _gcry_aes_ppc9le_cbc_enc
+#define CBC_DEC_FUNC _gcry_aes_ppc9le_cbc_dec
+#define CTR_ENC_FUNC _gcry_aes_ppc9le_ctr_enc
+#define OCB_CRYPT_FUNC _gcry_aes_ppc9le_ocb_crypt
+#define OCB_AUTH_FUNC _gcry_aes_ppc9le_ocb_auth
+#define XTS_CRYPT_FUNC _gcry_aes_ppc9le_xts_crypt
+
+#include <rijndael-ppc-functions.h>
+
+#endif /* USE_PPC_CRYPTO */
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-s390x.c b/comm/third_party/libgcrypt/cipher/rijndael-s390x.c
new file mode 100644
index 0000000000..aea65c5a3d
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-s390x.c
@@ -0,0 +1,1155 @@
+/* Rijndael (AES) for GnuPG - s390x/zSeries AES implementation
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "rijndael-internal.h"
+#include "cipher-internal.h"
+#include "bufhelp.h"
+
+#ifdef USE_S390X_CRYPTO
+
+#include "asm-inline-s390x.h"
+
+#define NO_INLINE __attribute__((noinline))
+
+struct aes_s390x_gcm_params_s
+{
+ u32 reserved[3];
+ u32 counter_value;
+ u64 tag[2];
+ u64 hash_subkey[2];
+ u64 total_aad_length;
+ u64 total_cipher_length;
+ u32 initial_counter_value[4];
+ u64 key[4];
+};
+
+#define DECL_QUERY_FUNC(instruction, opcode) \
+ static u128_t instruction ##_query(void) \
+ { \
+ static u128_t function_codes = 0; \
+ static int initialized = 0; \
+ register unsigned long reg0 asm("0") = 0; \
+ register void *reg1 asm("1") = &function_codes; \
+ u128_t r1, r2; \
+ \
+ if (initialized) \
+ return function_codes; \
+ \
+ asm volatile ("0: .insn rre," #opcode " << 16, %[r1], %[r2]\n\t" \
+ " brc 1,0b\n\t" \
+ : [r1] "=a" (r1), [r2] "=a" (r2) \
+ : [reg0] "r" (reg0), [reg1] "r" (reg1) \
+ : "cc", "memory"); \
+ \
+ initialized = 1; \
+ return function_codes; \
+ }
+
+#define DECL_EXECUTE_FUNC(instruction, opcode, param_const) \
+ static ALWAYS_INLINE size_t \
+ instruction ##_execute(unsigned int func, param_const void *param_block, \
+ void *dst, const void *src, size_t src_len) \
+ { \
+ register unsigned long reg0 asm("0") = func; \
+ register param_const byte *reg1 asm("1") = param_block; \
+ u128_t r1 = ((u128_t)(uintptr_t)dst << 64); \
+ u128_t r2 = ((u128_t)(uintptr_t)src << 64) | (u64)src_len; \
+ \
+ asm volatile ("0: .insn rre," #opcode " << 16, %[r1], %[r2]\n\t" \
+ " brc 1,0b\n\t" \
+ : [r1] "+a" (r1), [r2] "+a" (r2) \
+ : [func] "r" (reg0), [param_ptr] "r" (reg1) \
+ : "cc", "memory"); \
+ \
+ return (u64)r2; \
+ }
+
+DECL_QUERY_FUNC(km, 0xb92e);
+DECL_QUERY_FUNC(kmc, 0xb92f);
+DECL_QUERY_FUNC(kmac, 0xb91e);
+DECL_QUERY_FUNC(kmf, 0xb92a);
+DECL_QUERY_FUNC(kmo, 0xb92b);
+
+DECL_EXECUTE_FUNC(km, 0xb92e, const);
+DECL_EXECUTE_FUNC(kmc, 0xb92f, );
+DECL_EXECUTE_FUNC(kmac, 0xb91e, );
+DECL_EXECUTE_FUNC(kmf, 0xb92a, );
+DECL_EXECUTE_FUNC(kmo, 0xb92b, );
+
+static u128_t kma_query(void)
+{
+ static u128_t function_codes = 0;
+ static int initialized = 0;
+ register unsigned long reg0 asm("0") = 0;
+ register void *reg1 asm("1") = &function_codes;
+ u128_t r1, r2, r3;
+
+ if (initialized)
+ return function_codes;
+
+ asm volatile ("0: .insn rrf,0xb929 << 16, %[r1], %[r2], %[r3], 0\n\t"
+ " brc 1,0b\n\t"
+ : [r1] "=a" (r1), [r2] "=a" (r2), [r3] "=a" (r3)
+ : [reg0] "r" (reg0), [reg1] "r" (reg1)
+ : "cc", "memory");
+
+ initialized = 1;
+ return function_codes;
+}
+
+static ALWAYS_INLINE void
+kma_execute(unsigned int func, void *param_block, byte *dst, const byte *src,
+ size_t src_len, const byte *aad, size_t aad_len)
+{
+ register unsigned long reg0 asm("0") = func;
+ register byte *reg1 asm("1") = param_block;
+ u128_t r1 = ((u128_t)(uintptr_t)dst << 64);
+ u128_t r2 = ((u128_t)(uintptr_t)src << 64) | (u64)src_len;
+ u128_t r3 = ((u128_t)(uintptr_t)aad << 64) | (u64)aad_len;
+
+ asm volatile ("0: .insn rrf,0xb929 << 16, %[r1], %[r2], %[r3], 0\n\t"
+ " brc 1,0b\n\t"
+ : [r1] "+a" (r1), [r2] "+a" (r2), [r3] "+a" (r3),
+ [func] "+r" (reg0)
+ : [param_ptr] "r" (reg1)
+ : "cc", "memory");
+}
+
+unsigned int _gcry_aes_s390x_encrypt(const RIJNDAEL_context *ctx,
+ unsigned char *dst,
+ const unsigned char *src)
+{
+ km_execute (ctx->km_func | KM_ENCRYPT, ctx->keyschenc, dst, src,
+ BLOCKSIZE);
+ return 0;
+}
+
+unsigned int _gcry_aes_s390x_decrypt(const RIJNDAEL_context *ctx,
+ unsigned char *dst,
+ const unsigned char *src)
+{
+ km_execute (ctx->km_func | KM_DECRYPT, ctx->keyschenc, dst, src,
+ BLOCKSIZE);
+ return 0;
+}
+
+static void aes_s390x_cbc_enc(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks, int cbc_mac)
+{
+ RIJNDAEL_context *ctx = context;
+ byte *out = outbuf_arg;
+ const byte *in = inbuf_arg;
+ u128_t params[3];
+
+ /* Prepare parameter block. */
+ memcpy (&params[0], iv, BLOCKSIZE);
+ memcpy (&params[1], ctx->keyschenc, 32);
+
+ if (cbc_mac)
+ {
+ kmac_execute (ctx->kmac_func | KM_ENCRYPT, &params, NULL, in,
+ nblocks * BLOCKSIZE);
+ memcpy (out, &params[0], BLOCKSIZE);
+ }
+ else
+ {
+ kmc_execute (ctx->kmc_func | KM_ENCRYPT, &params, out, in,
+ nblocks * BLOCKSIZE);
+ }
+
+ /* Update IV with OCV. */
+ memcpy (iv, &params[0], BLOCKSIZE);
+
+ wipememory (&params, sizeof(params));
+}
+
+static void aes_s390x_cbc_dec(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ byte *out = outbuf_arg;
+ const byte *in = inbuf_arg;
+ u128_t params[3];
+
+ /* Prepare parameter block (ICV & key). */
+ memcpy (&params[0], iv, BLOCKSIZE);
+ memcpy (&params[1], ctx->keyschenc, 32);
+
+ kmc_execute (ctx->kmc_func | KM_DECRYPT, &params, out, in,
+ nblocks * BLOCKSIZE);
+
+ /* Update IV with OCV. */
+ memcpy (iv, &params[0], BLOCKSIZE);
+
+ wipememory (&params, sizeof(params));
+}
+
+static void aes_s390x_cfb128_enc(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ byte *out = outbuf_arg;
+ const byte *in = inbuf_arg;
+ unsigned int function;
+ u128_t params[3];
+
+ /* Prepare parameter block. */
+ memcpy (&params[0], iv, BLOCKSIZE);
+ memcpy (&params[1], ctx->keyschenc, 32);
+
+ function = ctx->kmf_func | KM_ENCRYPT | KMF_LCFB_16;
+ kmf_execute (function, &params, out, in, nblocks * BLOCKSIZE);
+
+ /* Update IV with OCV. */
+ memcpy (iv, &params[0], BLOCKSIZE);
+
+ wipememory (&params, sizeof(params));
+}
+
+static void aes_s390x_cfb128_dec(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ u128_t blocks[64];
+ byte *out = outbuf_arg;
+ const byte *in = inbuf_arg;
+ size_t max_blocks_used = 0;
+
+ /* AES128-CFB128 decryption speed using KMF was observed to be the same as
+ * the KMF encryption, ~1.03 cpb. Expection was to see similar performance
+ * as for AES128-CBC decryption as decryption for both modes should be
+ * parallalizeble (CBC shows ~0.22 cpb). Therefore there is quite a bit
+ * of room for improvement and implementation below using KM instruction
+ * shows ~0.70 cpb speed, ~30% improvement over KMF instruction.
+ */
+
+ while (nblocks >= 64)
+ {
+ /* Copy IV to encrypt buffer, copy (nblocks - 1) input blocks to
+ * encrypt buffer and update IV. */
+ asm volatile ("mvc 0(16, %[blocks]), 0(%[iv])\n\t"
+ "mvc 16(240, %[blocks]), 0(%[in])\n\t"
+ "mvc 256(256, %[blocks]), 240(%[in])\n\t"
+ "mvc 512(256, %[blocks]), 496(%[in])\n\t"
+ "mvc 768(256, %[blocks]), 752(%[in])\n\t"
+ "mvc 0(16, %[iv]), 1008(%[in])\n\t"
+ :
+ : [in] "a" (in), [out] "a" (out), [blocks] "a" (blocks),
+ [iv] "a" (iv)
+ : "memory");
+
+ /* Perform encryption of temporary buffer. */
+ km_execute (ctx->km_func | KM_ENCRYPT, ctx->keyschenc, blocks, blocks,
+ 64 * BLOCKSIZE);
+
+ /* Xor encrypt buffer with input blocks and store to output blocks. */
+ asm volatile ("xc 0(256, %[blocks]), 0(%[in])\n\t"
+ "xc 256(256, %[blocks]), 256(%[in])\n\t"
+ "xc 512(256, %[blocks]), 512(%[in])\n\t"
+ "xc 768(256, %[blocks]), 768(%[in])\n\t"
+ "mvc 0(256, %[out]), 0(%[blocks])\n\t"
+ "mvc 256(256, %[out]), 256(%[blocks])\n\t"
+ "mvc 512(256, %[out]), 512(%[blocks])\n\t"
+ "mvc 768(256, %[out]), 768(%[blocks])\n\t"
+ :
+ : [in] "a" (in), [out] "a" (out), [blocks] "a" (blocks)
+ : "memory");
+
+ max_blocks_used = 64;
+ in += 64 * BLOCKSIZE;
+ out += 64 * BLOCKSIZE;
+ nblocks -= 64;
+ }
+
+ if (nblocks)
+ {
+ unsigned int pos = 0;
+ size_t in_nblocks = nblocks;
+ size_t num_in = 0;
+
+ max_blocks_used = max_blocks_used < nblocks ? nblocks : max_blocks_used;
+
+ /* Copy IV to encrypt buffer. */
+ asm volatile ("mvc 0(16, %[blocks]), 0(%[iv])\n\t"
+ :
+ : [blocks] "a" (blocks), [iv] "a" (iv)
+ : "memory");
+ pos += 1;
+
+#define CFB_MOVE_BLOCKS(block_oper, move_nbytes) \
+ block_oper (in_nblocks - 1 >= move_nbytes / BLOCKSIZE) \
+ { \
+ unsigned int move_nblocks = move_nbytes / BLOCKSIZE; \
+ asm volatile ("mvc 0(" #move_nbytes ", %[blocks_x]), 0(%[in])\n\t" \
+ : \
+ : [blocks_x] "a" (&blocks[pos]), [in] "a" (in) \
+ : "memory"); \
+ num_in += move_nblocks; \
+ in += move_nblocks * BLOCKSIZE; \
+ pos += move_nblocks; \
+ in_nblocks -= move_nblocks; \
+ }
+
+ /* Copy (nblocks - 1) input blocks to encrypt buffer. */
+ CFB_MOVE_BLOCKS(while, 256);
+ CFB_MOVE_BLOCKS(if, 128);
+ CFB_MOVE_BLOCKS(if, 64);
+ CFB_MOVE_BLOCKS(if, 32);
+ CFB_MOVE_BLOCKS(if, 16);
+
+#undef CFB_MOVE_BLOCKS
+
+ /* Update IV. */
+ asm volatile ("mvc 0(16, %[iv]), 0(%[in])\n\t"
+ :
+ : [iv] "a" (iv), [in] "a" (in)
+ : "memory");
+ num_in += 1;
+ in += BLOCKSIZE;
+
+ /* Perform encryption of temporary buffer. */
+ km_execute (ctx->km_func | KM_ENCRYPT, ctx->keyschenc, blocks, blocks,
+ nblocks * BLOCKSIZE);
+
+ /* Xor encrypt buffer with input blocks and store to output blocks. */
+ pos = 0;
+ in -= nblocks * BLOCKSIZE;
+
+#define CFB_XOR_BLOCKS(block_oper, xor_nbytes) \
+ block_oper (nblocks >= xor_nbytes / BLOCKSIZE) \
+ { \
+ unsigned int xor_nblocks = xor_nbytes / BLOCKSIZE; \
+ asm volatile ("xc 0(" #xor_nbytes ", %[blocks_x]), 0(%[in])\n\t" \
+ "mvc 0(" #xor_nbytes ", %[out]), 0(%[blocks_x])\n\t" \
+ : \
+ : [blocks_x] "a" (&blocks[pos]), [out] "a" (out), \
+ [in] "a" (in) \
+ : "memory"); \
+ out += xor_nblocks * BLOCKSIZE; \
+ in += xor_nblocks * BLOCKSIZE; \
+ nblocks -= xor_nblocks; \
+ pos += xor_nblocks; \
+ }
+
+ CFB_XOR_BLOCKS(while, 256);
+ CFB_XOR_BLOCKS(if, 128);
+ CFB_XOR_BLOCKS(if, 64);
+ CFB_XOR_BLOCKS(if, 32);
+ CFB_XOR_BLOCKS(if, 16);
+
+#undef CFB_XOR_BLOCKS
+ }
+
+ if (max_blocks_used)
+ wipememory (&blocks, max_blocks_used * BLOCKSIZE);
+}
+
+static void aes_s390x_ofb_enc(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ byte *out = outbuf_arg;
+ const byte *in = inbuf_arg;
+ unsigned int function;
+ u128_t params[3];
+
+ /* Prepare parameter block. */
+ memcpy (&params[0], iv, BLOCKSIZE);
+ memcpy (&params[1], ctx->keyschenc, 32);
+
+ function = ctx->kmo_func | KM_ENCRYPT;
+ kmo_execute (function, &params, out, in, nblocks * BLOCKSIZE);
+
+ /* Update IV with OCV. */
+ memcpy (iv, &params[0], BLOCKSIZE);
+
+ wipememory (&params, sizeof(params));
+}
+
+static void aes_s390x_ctr128_enc(void *context, unsigned char *ctr,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ byte *out = outbuf_arg;
+ const byte *in = inbuf_arg;
+ unsigned int function;
+ struct aes_s390x_gcm_params_s params;
+
+ memset (&params.hash_subkey, 0, sizeof(params.hash_subkey));
+ memcpy (&params.key, ctx->keyschenc, 32);
+
+ function = ctx->kma_func | KM_DECRYPT | KMA_HS | KMA_LAAD;
+
+ while (nblocks)
+ {
+ u64 to_overflow = (u64)0xFFFFFFFFU + 1 - buf_get_be32 (ctr + 12);
+ u64 ncurr = nblocks > to_overflow ? to_overflow : nblocks;
+
+ /* Prepare parameter block. */
+ memset (&params.reserved, 0, sizeof(params.reserved));
+ buf_put_be32 (&params.counter_value, buf_get_be32(ctr + 12) - 1);
+ memcpy (&params.initial_counter_value, ctr, 16);
+ params.initial_counter_value[3] = params.counter_value;
+ memset (&params.tag, 0, sizeof(params.tag));
+ params.total_aad_length = 0;
+ params.total_cipher_length = 0;
+
+ /* Update counter. */
+ cipher_block_add (ctr, ncurr, BLOCKSIZE);
+ if (ncurr == (u64)0xFFFFFFFFU + 1)
+ cipher_block_add (ctr, 1, BLOCKSIZE);
+
+ /* Perform CTR using KMA-GCM. */
+ kma_execute (function, &params, out, in, ncurr * BLOCKSIZE, NULL, 0);
+
+ out += ncurr * BLOCKSIZE;
+ in += ncurr * BLOCKSIZE;
+ nblocks -= ncurr;
+ }
+
+ wipememory (&params, sizeof(params));
+}
+
+static size_t aes_s390x_gcm_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;
+ byte *out = outbuf_arg;
+ const byte *in = inbuf_arg;
+ byte *ctr = c->u_ctr.ctr;
+ unsigned int function;
+ struct aes_s390x_gcm_params_s params;
+
+ function = ctx->kma_func | (encrypt ? KM_ENCRYPT : KM_DECRYPT)
+ | KMA_HS | KMA_LAAD;
+
+ /* Prepare parameter block. */
+ memset (&params.reserved, 0, sizeof(params.reserved));
+ buf_put_be32 (&params.counter_value, buf_get_be32(ctr + 12) - 1);
+ memcpy (&params.tag, c->u_mode.gcm.u_tag.tag, 16);
+ memcpy (&params.hash_subkey, c->u_mode.gcm.u_ghash_key.key, 16);
+ params.total_aad_length = 0;
+ params.total_cipher_length = 0;
+ memcpy (&params.initial_counter_value, ctr, 12);
+ params.initial_counter_value[3] = params.counter_value;
+ memcpy (&params.key, ctx->keyschenc, 32);
+
+ /* Update counter (CTR32). */
+ buf_put_be32(ctr + 12, buf_get_be32(ctr + 12) + nblocks);
+
+ /* Perform KMA-GCM. */
+ kma_execute (function, &params, out, in, nblocks * BLOCKSIZE, NULL, 0);
+
+ /* Update tag. */
+ memcpy (c->u_mode.gcm.u_tag.tag, &params.tag, 16);
+
+ wipememory (&params, sizeof(params));
+
+ return 0;
+}
+
+static void aes_s390x_xts_crypt(void *context, unsigned char *tweak,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks, int encrypt)
+{
+ RIJNDAEL_context *ctx = context;
+ byte *out = outbuf_arg;
+ const byte *in = inbuf_arg;
+ unsigned int function;
+ u128_t params[3];
+ u128_t *params_tweak;
+
+ if (ctx->rounds < 12)
+ {
+ memcpy (&params[0], ctx->keyschenc, 16);
+ params_tweak = &params[1];
+ memcpy (params_tweak, tweak, BLOCKSIZE);
+ }
+ else if (ctx->rounds == 12)
+ {
+ BUG(); /* KM-XTS-AES-192 not defined. */
+ }
+ else
+ {
+ memcpy (&params[0], ctx->keyschenc, 32);
+ params_tweak = &params[2];
+ memcpy (params_tweak, tweak, BLOCKSIZE);
+ }
+
+ function = ctx->km_func_xts | (encrypt ? KM_ENCRYPT : KM_DECRYPT);
+ km_execute (function, &params, out, in, nblocks * BLOCKSIZE);
+
+ /* Update tweak with XTSP. */
+ memcpy (tweak, params_tweak, BLOCKSIZE);
+
+ wipememory (&params, sizeof(params));
+}
+
+static NO_INLINE void
+aes_s390x_ocb_prepare_Ls (gcry_cipher_hd_t c, u64 blkn, const void *Ls[64],
+ const void ***pl)
+{
+ unsigned int n = 64 - (blkn % 64);
+ int i;
+
+ /* Prepare L pointers. */
+ *pl = &Ls[(63 + n) % 64];
+ for (i = 0; i < 64; i += 8, n = (n + 8) % 64)
+ {
+ static const int lastL[8] = { 3, 4, 3, 5, 3, 4, 3, 0 };
+
+ Ls[(0 + n) % 64] = c->u_mode.ocb.L[0];
+ Ls[(1 + n) % 64] = c->u_mode.ocb.L[1];
+ Ls[(2 + n) % 64] = c->u_mode.ocb.L[0];
+ Ls[(3 + n) % 64] = c->u_mode.ocb.L[2];
+ Ls[(4 + n) % 64] = c->u_mode.ocb.L[0];
+ Ls[(5 + n) % 64] = c->u_mode.ocb.L[1];
+ Ls[(6 + n) % 64] = c->u_mode.ocb.L[0];
+ Ls[(7 + n) % 64] = c->u_mode.ocb.L[lastL[i / 8]];
+ }
+}
+
+static NO_INLINE void
+aes_s390x_ocb_checksum (unsigned char *checksum, const void *plainbuf_arg,
+ size_t nblks)
+{
+ const char *plainbuf = plainbuf_arg;
+ u64 tmp0[2];
+ u64 tmp1[2] = { 0, 0 };
+ u64 tmp2[2] = { 0, 0 };
+ u64 tmp3[2] = { 0, 0 };
+
+ cipher_block_cpy (tmp0, checksum, BLOCKSIZE);
+
+ if (nblks >= 4)
+ {
+ while (nblks >= 4)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ cipher_block_xor_1 (tmp0, plainbuf + 0 * BLOCKSIZE, BLOCKSIZE);
+ cipher_block_xor_1 (tmp1, plainbuf + 1 * BLOCKSIZE, BLOCKSIZE);
+ cipher_block_xor_1 (tmp2, plainbuf + 2 * BLOCKSIZE, BLOCKSIZE);
+ cipher_block_xor_1 (tmp3, plainbuf + 3 * BLOCKSIZE, BLOCKSIZE);
+
+ plainbuf += 4 * BLOCKSIZE;
+ nblks -= 4;
+ }
+
+ cipher_block_xor_1 (tmp0, tmp1, BLOCKSIZE);
+ cipher_block_xor_1 (tmp2, tmp3, BLOCKSIZE);
+ cipher_block_xor_1 (tmp0, tmp2, BLOCKSIZE);
+
+ wipememory (tmp1, sizeof(tmp1));
+ wipememory (tmp2, sizeof(tmp2));
+ wipememory (tmp3, sizeof(tmp3));
+ }
+
+ while (nblks > 0)
+ {
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ cipher_block_xor_1 (tmp0, plainbuf, BLOCKSIZE);
+
+ plainbuf += BLOCKSIZE;
+ nblks--;
+ }
+
+ cipher_block_cpy (checksum, tmp0, BLOCKSIZE);
+
+ wipememory (tmp0, sizeof(tmp0));
+}
+
+static NO_INLINE size_t
+aes_s390x_ocb_enc (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;
+ size_t nblocks = nblocks_arg;
+ u128_t blocks[64];
+ u128_t offset;
+ size_t max_blocks_used = 0;
+ u64 blkn = c->u_mode.ocb.data_nblocks;
+ unsigned int function = ctx->km_func | KM_ENCRYPT;
+ const void *Ls[64];
+ const void **pl;
+
+ aes_s390x_ocb_prepare_Ls (c, blkn, Ls, &pl);
+
+ /* Checksumming could be done inline in OCB_INPUT macros, but register
+ * pressure becomes too heavy and performance would end up being worse.
+ * For decryption, checksumming is part of OCB_OUTPUT macros as
+ * output handling is less demanding and can handle the additional
+ * computation. */
+ aes_s390x_ocb_checksum (c->u_ctr.ctr, inbuf_arg, nblocks_arg);
+
+ cipher_block_cpy (&offset, &c->u_iv.iv, BLOCKSIZE);
+
+#define OCB_INPUT(n) \
+ cipher_block_xor_2dst (&blocks[n], &offset, Ls[n], BLOCKSIZE); \
+ cipher_block_xor (outbuf + (n) * BLOCKSIZE, inbuf + (n) * BLOCKSIZE, \
+ &offset, BLOCKSIZE)
+
+#define OCB_INPUT_4(n) \
+ OCB_INPUT((n) + 0); OCB_INPUT((n) + 1); OCB_INPUT((n) + 2); \
+ OCB_INPUT((n) + 3)
+
+#define OCB_INPUT_16(n) \
+ OCB_INPUT_4((n) + 0); OCB_INPUT_4((n) + 4); OCB_INPUT_4((n) + 8); \
+ OCB_INPUT_4((n) + 12);
+
+#define OCB_OUTPUT(n) \
+ cipher_block_xor_1 (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE)
+
+#define OCB_OUTPUT_4(n) \
+ OCB_OUTPUT((n) + 0); OCB_OUTPUT((n) + 1); OCB_OUTPUT((n) + 2); \
+ OCB_OUTPUT((n) + 3)
+
+#define OCB_OUTPUT_16(n) \
+ OCB_OUTPUT_4((n) + 0); OCB_OUTPUT_4((n) + 4); OCB_OUTPUT_4((n) + 8); \
+ OCB_OUTPUT_4((n) + 12);
+
+ while (nblocks >= 64)
+ {
+ blkn += 64;
+ *pl = ocb_get_l(c, blkn - blkn % 64);
+
+ OCB_INPUT_16(0);
+ OCB_INPUT_16(16);
+ OCB_INPUT_16(32);
+ OCB_INPUT_16(48);
+
+ km_execute (function, ctx->keyschenc, outbuf, outbuf, 64 * BLOCKSIZE);
+
+ asm volatile ("xc 0(256, %[out]), 0(%[blocks])\n\t"
+ "xc 256(256, %[out]), 256(%[blocks])\n\t"
+ "xc 512(256, %[out]), 512(%[blocks])\n\t"
+ "xc 768(256, %[out]), 768(%[blocks])\n\t"
+ :
+ : [out] "a" (outbuf), [blocks] "a" (blocks)
+ : "memory");
+
+ max_blocks_used = 64;
+ inbuf += 64 * BLOCKSIZE;
+ outbuf += 64 * BLOCKSIZE;
+ nblocks -= 64;
+ }
+
+ if (nblocks)
+ {
+ unsigned int pos = 0;
+
+ max_blocks_used = max_blocks_used < nblocks ? nblocks : max_blocks_used;
+
+ blkn += nblocks;
+ *pl = ocb_get_l(c, blkn - blkn % 64);
+
+ while (nblocks >= 16)
+ {
+ OCB_INPUT_16(pos + 0);
+ pos += 16;
+ nblocks -= 16;
+ }
+ while (nblocks >= 4)
+ {
+ OCB_INPUT_4(pos + 0);
+ pos += 4;
+ nblocks -= 4;
+ }
+ if (nblocks >= 2)
+ {
+ OCB_INPUT(pos + 0);
+ OCB_INPUT(pos + 1);
+ pos += 2;
+ nblocks -= 2;
+ }
+ if (nblocks >= 1)
+ {
+ OCB_INPUT(pos + 0);
+ pos += 1;
+ nblocks -= 1;
+ }
+
+ nblocks = pos;
+ pos = 0;
+ km_execute (function, ctx->keyschenc, outbuf, outbuf,
+ nblocks * BLOCKSIZE);
+
+ while (nblocks >= 16)
+ {
+ OCB_OUTPUT_16(pos + 0);
+ pos += 16;
+ nblocks -= 16;
+ }
+ while (nblocks >= 4)
+ {
+ OCB_OUTPUT_4(pos + 0);
+ pos += 4;
+ nblocks -= 4;
+ }
+ if (nblocks >= 2)
+ {
+ OCB_OUTPUT(pos + 0);
+ OCB_OUTPUT(pos + 1);
+ pos += 2;
+ nblocks -= 2;
+ }
+ if (nblocks >= 1)
+ {
+ OCB_OUTPUT(pos + 0);
+ pos += 1;
+ nblocks -= 1;
+ }
+ }
+
+#undef OCB_INPUT
+#undef OCB_INPUT_4
+#undef OCB_INPUT_16
+#undef OCB_OUTPUT
+#undef OCB_OUTPUT_4
+#undef OCB_OUTPUT_16
+
+ c->u_mode.ocb.data_nblocks = blkn;
+ cipher_block_cpy (&c->u_iv.iv, &offset, BLOCKSIZE);
+
+ if (max_blocks_used)
+ wipememory (&blocks, max_blocks_used * BLOCKSIZE);
+
+ return 0;
+}
+
+static NO_INLINE size_t
+aes_s390x_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;
+ size_t nblocks = nblocks_arg;
+ u128_t blocks[64];
+ u128_t offset;
+ size_t max_blocks_used = 0;
+ u64 blkn = c->u_mode.ocb.data_nblocks;
+ unsigned int function = ctx->km_func | KM_DECRYPT;
+ const void *Ls[64];
+ const void **pl;
+
+ aes_s390x_ocb_prepare_Ls (c, blkn, Ls, &pl);
+
+ cipher_block_cpy (&offset, &c->u_iv.iv, BLOCKSIZE);
+
+#define OCB_INPUT(n) \
+ cipher_block_xor_2dst (&blocks[n], &offset, Ls[n], BLOCKSIZE); \
+ cipher_block_xor (outbuf + (n) * BLOCKSIZE, inbuf + (n) * BLOCKSIZE, \
+ &offset, BLOCKSIZE)
+
+#define OCB_INPUT_4(n) \
+ OCB_INPUT((n) + 0); OCB_INPUT((n) + 1); OCB_INPUT((n) + 2); \
+ OCB_INPUT((n) + 3)
+
+#define OCB_INPUT_16(n) \
+ OCB_INPUT_4((n) + 0); OCB_INPUT_4((n) + 4); OCB_INPUT_4((n) + 8); \
+ OCB_INPUT_4((n) + 12);
+
+#define OCB_OUTPUT(n) \
+ cipher_block_xor_1 (&blocks[n], outbuf + (n) * BLOCKSIZE, BLOCKSIZE); \
+ cipher_block_xor_1 (c->u_ctr.ctr, &blocks[n], BLOCKSIZE); \
+ cipher_block_cpy (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE);
+
+#define OCB_OUTPUT_4(n) \
+ OCB_OUTPUT((n) + 0); OCB_OUTPUT((n) + 1); OCB_OUTPUT((n) + 2); \
+ OCB_OUTPUT((n) + 3)
+
+#define OCB_OUTPUT_16(n) \
+ OCB_OUTPUT_4((n) + 0); OCB_OUTPUT_4((n) + 4); OCB_OUTPUT_4((n) + 8); \
+ OCB_OUTPUT_4((n) + 12);
+
+ while (nblocks >= 64)
+ {
+ blkn += 64;
+ *pl = ocb_get_l(c, blkn - blkn % 64);
+
+ OCB_INPUT_16(0);
+ OCB_INPUT_16(16);
+ OCB_INPUT_16(32);
+ OCB_INPUT_16(48);
+
+ km_execute (function, ctx->keyschenc, outbuf, outbuf, 64 * BLOCKSIZE);
+
+ asm volatile ("xc 0(256, %[out]), 0(%[blocks])\n\t"
+ "xc 256(256, %[out]), 256(%[blocks])\n\t"
+ "xc 512(256, %[out]), 512(%[blocks])\n\t"
+ "xc 768(256, %[out]), 768(%[blocks])\n\t"
+ :
+ : [out] "a" (outbuf), [blocks] "a" (blocks)
+ : "memory");
+
+ max_blocks_used = 64;
+ inbuf += 64 * BLOCKSIZE;
+ outbuf += 64 * BLOCKSIZE;
+ nblocks -= 64;
+ }
+
+ if (nblocks)
+ {
+ unsigned int pos = 0;
+
+ max_blocks_used = max_blocks_used < nblocks ? nblocks : max_blocks_used;
+
+ blkn += nblocks;
+ *pl = ocb_get_l(c, blkn - blkn % 64);
+
+ while (nblocks >= 16)
+ {
+ OCB_INPUT_16(pos + 0);
+ pos += 16;
+ nblocks -= 16;
+ }
+ while (nblocks >= 4)
+ {
+ OCB_INPUT_4(pos + 0);
+ pos += 4;
+ nblocks -= 4;
+ }
+ if (nblocks >= 2)
+ {
+ OCB_INPUT(pos + 0);
+ OCB_INPUT(pos + 1);
+ pos += 2;
+ nblocks -= 2;
+ }
+ if (nblocks >= 1)
+ {
+ OCB_INPUT(pos + 0);
+ pos += 1;
+ nblocks -= 1;
+ }
+
+ nblocks = pos;
+ pos = 0;
+ km_execute (function, ctx->keyschenc, outbuf, outbuf,
+ nblocks * BLOCKSIZE);
+
+ while (nblocks >= 16)
+ {
+ OCB_OUTPUT_16(pos + 0);
+ pos += 16;
+ nblocks -= 16;
+ }
+ while (nblocks >= 4)
+ {
+ OCB_OUTPUT_4(pos + 0);
+ pos += 4;
+ nblocks -= 4;
+ }
+ if (nblocks >= 2)
+ {
+ OCB_OUTPUT(pos + 0);
+ OCB_OUTPUT(pos + 1);
+ pos += 2;
+ nblocks -= 2;
+ }
+ if (nblocks >= 1)
+ {
+ OCB_OUTPUT(pos + 0);
+ pos += 1;
+ nblocks -= 1;
+ }
+ }
+
+#undef OCB_INPUT
+#undef OCB_INPUT_4
+#undef OCB_INPUT_16
+#undef OCB_OUTPUT
+#undef OCB_OUTPUT_4
+#undef OCB_OUTPUT_16
+
+ c->u_mode.ocb.data_nblocks = blkn;
+ cipher_block_cpy (&c->u_iv.iv, &offset, BLOCKSIZE);
+
+ if (max_blocks_used)
+ wipememory (&blocks, max_blocks_used * BLOCKSIZE);
+
+ return 0;
+}
+
+static size_t
+aes_s390x_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks_arg, int encrypt)
+{
+ if (encrypt)
+ return aes_s390x_ocb_enc (c, outbuf_arg, inbuf_arg, nblocks_arg);
+ else
+ return aes_s390x_ocb_dec (c, outbuf_arg, inbuf_arg, nblocks_arg);
+}
+
+static size_t
+aes_s390x_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+ size_t nblocks_arg)
+{
+ RIJNDAEL_context *ctx = (void *)&c->context.c;
+ const unsigned char *abuf = abuf_arg;
+ u128_t blocks[64];
+ u128_t offset;
+ size_t max_blocks_used = 0;
+ u64 blkn = c->u_mode.ocb.aad_nblocks;
+ unsigned int function = ctx->km_func | KM_ENCRYPT;
+ const void *Ls[64];
+ const void **pl;
+
+ aes_s390x_ocb_prepare_Ls (c, blkn, Ls, &pl);
+
+ cipher_block_cpy (&offset, c->u_mode.ocb.aad_offset, BLOCKSIZE);
+
+#define OCB_INPUT(n) \
+ cipher_block_xor_2dst (&blocks[n], &offset, Ls[n], BLOCKSIZE); \
+ cipher_block_xor_1 (&blocks[n], abuf + (n) * BLOCKSIZE, BLOCKSIZE)
+
+#define OCB_INPUT_4(n) \
+ OCB_INPUT((n) + 0); OCB_INPUT((n) + 1); OCB_INPUT((n) + 2); \
+ OCB_INPUT((n) + 3)
+
+#define OCB_INPUT_16(n) \
+ OCB_INPUT_4((n) + 0); OCB_INPUT_4((n) + 4); OCB_INPUT_4((n) + 8); \
+ OCB_INPUT_4((n) + 12);
+
+ while (nblocks_arg >= 64)
+ {
+ blkn += 64;
+ *pl = ocb_get_l(c, blkn - blkn % 64);
+
+ OCB_INPUT_16(0);
+ OCB_INPUT_16(16);
+ OCB_INPUT_16(32);
+ OCB_INPUT_16(48);
+
+ km_execute (function, ctx->keyschenc, blocks, blocks, 64 * BLOCKSIZE);
+
+ aes_s390x_ocb_checksum (c->u_mode.ocb.aad_sum, blocks, 64);
+
+ max_blocks_used = 64;
+ abuf += 64 * BLOCKSIZE;
+ nblocks_arg -= 64;
+ }
+
+ if (nblocks_arg > 0)
+ {
+ size_t nblocks = nblocks_arg;
+ unsigned int pos = 0;
+
+ max_blocks_used = max_blocks_used < nblocks ? nblocks : max_blocks_used;
+
+ blkn += nblocks;
+ *pl = ocb_get_l(c, blkn - blkn % 64);
+
+ while (nblocks >= 16)
+ {
+ OCB_INPUT_16(pos + 0);
+ pos += 16;
+ nblocks -= 16;
+ }
+ while (nblocks >= 4)
+ {
+ OCB_INPUT_4(pos + 0);
+ pos += 4;
+ nblocks -= 4;
+ }
+ if (nblocks >= 2)
+ {
+ OCB_INPUT(pos + 0);
+ OCB_INPUT(pos + 1);
+ pos += 2;
+ nblocks -= 2;
+ }
+ if (nblocks >= 1)
+ {
+ OCB_INPUT(pos + 0);
+ pos += 1;
+ nblocks -= 1;
+ }
+
+ nblocks = pos;
+ nblocks_arg -= pos;
+ pos = 0;
+ km_execute (function, ctx->keyschenc, blocks, blocks,
+ nblocks * BLOCKSIZE);
+
+ aes_s390x_ocb_checksum (c->u_mode.ocb.aad_sum, blocks, nblocks);
+ }
+
+#undef OCB_INPUT
+#undef OCB_INPUT_4
+#undef OCB_INPUT_16
+
+ c->u_mode.ocb.aad_nblocks = blkn;
+ cipher_block_cpy (c->u_mode.ocb.aad_offset, &offset, BLOCKSIZE);
+
+ if (max_blocks_used)
+ wipememory (&blocks, max_blocks_used * BLOCKSIZE);
+
+ return 0;
+}
+
+int _gcry_aes_s390x_setup_acceleration(RIJNDAEL_context *ctx,
+ unsigned int keylen,
+ unsigned int hwfeatures,
+ cipher_bulk_ops_t *bulk_ops)
+{
+ unsigned int func;
+ unsigned int func_xts;
+ u128_t func_mask;
+ u128_t func_xts_mask;
+
+ if (!(hwfeatures & HWF_S390X_MSA))
+ return 0;
+
+ switch (keylen)
+ {
+ default:
+ case 16:
+ func = KM_FUNCTION_AES_128;
+ func_xts = KM_FUNCTION_XTS_AES_128;
+ func_mask = km_function_to_mask(KM_FUNCTION_AES_128);
+ func_xts_mask = km_function_to_mask(KM_FUNCTION_XTS_AES_128);
+ break;
+ case 24:
+ func = KM_FUNCTION_AES_192;
+ func_xts = 0;
+ func_mask = km_function_to_mask(KM_FUNCTION_AES_192);
+ func_xts_mask = 0; /* XTS-AES192 not available. */
+ break;
+ case 32:
+ func = KM_FUNCTION_AES_256;
+ func_xts = KM_FUNCTION_XTS_AES_256;
+ func_mask = km_function_to_mask(KM_FUNCTION_AES_256);
+ func_xts_mask = km_function_to_mask(KM_FUNCTION_AES_256);
+ break;
+ }
+
+ /* Query KM for supported algorithms and check if acceleration for
+ * requested key-length is available. */
+ if (!(km_query () & func_mask))
+ return 0;
+
+ ctx->km_func = func;
+
+ /* Query KM for supported XTS algorithms. */
+ if (km_query () & func_xts_mask)
+ ctx->km_func_xts = func_xts;
+
+ /* Query KMC for supported algorithms. */
+ if (kmc_query () & func_mask)
+ ctx->kmc_func = func;
+
+ /* Query KMAC for supported algorithms. */
+ if (kmac_query () & func_mask)
+ ctx->kmac_func = func;
+
+ if (hwfeatures & HWF_S390X_MSA_4)
+ {
+ /* Query KMF for supported algorithms. */
+ if (kmf_query () & func_mask)
+ ctx->kmf_func = func;
+
+ /* Query KMO for supported algorithms. */
+ if (kmo_query () & func_mask)
+ ctx->kmo_func = func;
+ }
+
+ if (hwfeatures & HWF_S390X_MSA_8)
+ {
+ /* Query KMA for supported algorithms. */
+ if (kma_query () & func_mask)
+ ctx->kma_func = func;
+ }
+
+ /* Setup zSeries bulk encryption/decryption routines. */
+
+ if (ctx->km_func)
+ {
+ bulk_ops->ocb_crypt = aes_s390x_ocb_crypt;
+ bulk_ops->ocb_auth = aes_s390x_ocb_auth;
+
+ /* CFB128 decryption uses KM instruction, instead of KMF. */
+ bulk_ops->cfb_dec = aes_s390x_cfb128_dec;
+ }
+
+ if (ctx->km_func_xts)
+ {
+ bulk_ops->xts_crypt = aes_s390x_xts_crypt;
+ }
+
+ if (ctx->kmc_func)
+ {
+ if(ctx->kmac_func)
+ {
+ /* Either KMC or KMAC used depending on 'cbc_mac' parameter. */
+ bulk_ops->cbc_enc = aes_s390x_cbc_enc;
+ }
+
+ bulk_ops->cbc_dec = aes_s390x_cbc_dec;
+ }
+
+ if (ctx->kmf_func)
+ {
+ bulk_ops->cfb_enc = aes_s390x_cfb128_enc;
+ }
+
+ if (ctx->kmo_func)
+ {
+ bulk_ops->ofb_enc = aes_s390x_ofb_enc;
+ }
+
+ if (ctx->kma_func)
+ {
+ bulk_ops->ctr_enc = aes_s390x_ctr128_enc;
+
+ if (kimd_query () & km_function_to_mask (KMID_FUNCTION_GHASH))
+ {
+ /* KIMD based GHASH implementation is required with AES-GCM
+ * acceleration. */
+ bulk_ops->gcm_crypt = aes_s390x_gcm_crypt;
+ }
+ }
+
+ return 1;
+}
+
+void _gcry_aes_s390x_setkey(RIJNDAEL_context *ctx, const byte *key)
+{
+ unsigned int keylen = 16 + (ctx->rounds - 10) * 4;
+ memcpy (ctx->keyschenc, key, keylen);
+}
+
+void _gcry_aes_s390x_prepare_decryption(RIJNDAEL_context *ctx)
+{
+ /* Do nothing. */
+ (void)ctx;
+}
+
+#endif /* USE_S390X_CRYPTO */
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-ssse3-amd64-asm.S b/comm/third_party/libgcrypt/cipher/rijndael-ssse3-amd64-asm.S
new file mode 100644
index 0000000000..8124eb2198
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-ssse3-amd64-asm.S
@@ -0,0 +1,874 @@
+/* SSSE3 vector permutation AES for Libgcrypt
+ * Copyright (C) 2014-2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ *
+ * 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/
+ */
+
+#if defined(__x86_64__)
+#include <config.h>
+#if defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+
+#include "asm-common-amd64.h"
+
+.text
+
+##
+## _gcry_aes_ssse3_enc_preload
+##
+ELF(.type _gcry_aes_ssse3_enc_preload,@function)
+.globl _gcry_aes_ssse3_enc_preload
+_gcry_aes_ssse3_enc_preload:
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+ lea .Laes_consts(%rip), %rax
+ movdqa (%rax), %xmm9 # 0F
+ movdqa .Lk_inv (%rax), %xmm10 # inv
+ movdqa .Lk_inv+16(%rax), %xmm11 # inva
+ movdqa .Lk_sb1 (%rax), %xmm13 # sb1u
+ movdqa .Lk_sb1+16(%rax), %xmm12 # sb1t
+ movdqa .Lk_sb2 (%rax), %xmm15 # sb2u
+ movdqa .Lk_sb2+16(%rax), %xmm14 # sb2t
+ EXIT_SYSV_FUNC
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_ssse3_enc_preload,.-_gcry_aes_ssse3_enc_preload)
+
+##
+## _gcry_aes_ssse3_dec_preload
+##
+ELF(.type _gcry_aes_ssse3_dec_preload,@function)
+.globl _gcry_aes_ssse3_dec_preload
+_gcry_aes_ssse3_dec_preload:
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+ lea .Laes_consts(%rip), %rax
+ movdqa (%rax), %xmm9 # 0F
+ movdqa .Lk_inv (%rax), %xmm10 # inv
+ movdqa .Lk_inv+16(%rax), %xmm11 # inva
+ movdqa .Lk_dsb9 (%rax), %xmm13 # sb9u
+ movdqa .Lk_dsb9+16(%rax), %xmm12 # sb9t
+ movdqa .Lk_dsbd (%rax), %xmm15 # sbdu
+ movdqa .Lk_dsbb (%rax), %xmm14 # sbbu
+ movdqa .Lk_dsbe (%rax), %xmm8 # sbeu
+ EXIT_SYSV_FUNC
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_ssse3_dec_preload,.-_gcry_aes_ssse3_dec_preload)
+
+##
+## Constant-time SSSE3 AES core implementation.
+##
+## By Mike Hamburg (Stanford University), 2009
+## Public domain.
+##
+
+##
+## _aes_encrypt_core
+##
+## AES-encrypt %xmm0.
+##
+## Inputs:
+## %xmm0 = input
+## %xmm9-%xmm15 as in .Laes_preheat
+## (%rdi) = scheduled keys
+## %rsi = nrounds
+##
+## Output in %xmm0
+## Clobbers %xmm1-%xmm4, %r9, %r11, %rax, %rcx, %rdx
+## Preserves %xmm6 - %xmm7 so you get some local vectors
+##
+##
+.align 16
+ELF(.type _gcry_aes_ssse3_encrypt_core,@function)
+.globl _gcry_aes_ssse3_encrypt_core
+_gcry_aes_ssse3_encrypt_core:
+_aes_encrypt_core:
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+ mov %rdi, %rdx
+ leaq -1(%rsi), %rax
+ lea .Laes_consts(%rip), %rcx
+ leaq .Lk_mc_backward(%rcx), %rdi
+ mov $16, %rsi
+ movdqa .Lk_ipt (%rcx), %xmm2 # iptlo
+ movdqa %xmm9, %xmm1
+ pandn %xmm0, %xmm1
+ psrld $4, %xmm1
+ pand %xmm9, %xmm0
+ pshufb %xmm0, %xmm2
+ movdqa .Lk_ipt+16(%rcx), %xmm0 # ipthi
+ pshufb %xmm1, %xmm0
+ pxor (%rdx),%xmm2
+ pxor %xmm2, %xmm0
+ add $16, %rdx
+ jmp .Laes_entry
+
+.align 8
+.Laes_loop:
+ # middle of middle round
+ movdqa %xmm13, %xmm4 # 4 : sb1u
+ pshufb %xmm2, %xmm4 # 4 = sb1u
+ pxor (%rdx), %xmm4 # 4 = sb1u + k
+ movdqa %xmm12, %xmm0 # 0 : sb1t
+ pshufb %xmm3, %xmm0 # 0 = sb1t
+ pxor %xmm4, %xmm0 # 0 = A
+ movdqa %xmm15, %xmm4 # 4 : sb2u
+ pshufb %xmm2, %xmm4 # 4 = sb2u
+ movdqa .Lk_mc_forward-.Lk_mc_backward(%rsi,%rdi), %xmm1
+ movdqa %xmm14, %xmm2 # 2 : sb2t
+ pshufb %xmm3, %xmm2 # 2 = sb2t
+ pxor %xmm4, %xmm2 # 2 = 2A
+ movdqa %xmm0, %xmm3 # 3 = A
+ pshufb %xmm1, %xmm0 # 0 = B
+ pxor %xmm2, %xmm0 # 0 = 2A+B
+ pshufb (%rsi,%rdi), %xmm3 # 3 = D
+ lea 16(%esi),%esi # next mc
+ pxor %xmm0, %xmm3 # 3 = 2A+B+D
+ lea 16(%rdx),%rdx # next key
+ pshufb %xmm1, %xmm0 # 0 = 2B+C
+ pxor %xmm3, %xmm0 # 0 = 2A+3B+C+D
+ and $48, %rsi # ... mod 4
+ dec %rax # nr--
+
+.Laes_entry:
+ # top of round
+ movdqa %xmm9, %xmm1 # 1 : i
+ pandn %xmm0, %xmm1 # 1 = i<<4
+ psrld $4, %xmm1 # 1 = i
+ pand %xmm9, %xmm0 # 0 = k
+ movdqa %xmm11, %xmm2 # 2 : a/k
+ pshufb %xmm0, %xmm2 # 2 = a/k
+ pxor %xmm1, %xmm0 # 0 = j
+ movdqa %xmm10, %xmm3 # 3 : 1/i
+ pshufb %xmm1, %xmm3 # 3 = 1/i
+ pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k
+ movdqa %xmm10, %xmm4 # 4 : 1/j
+ pshufb %xmm0, %xmm4 # 4 = 1/j
+ pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k
+ movdqa %xmm10, %xmm2 # 2 : 1/iak
+ pshufb %xmm3, %xmm2 # 2 = 1/iak
+ pxor %xmm0, %xmm2 # 2 = io
+ movdqa %xmm10, %xmm3 # 3 : 1/jak
+ pshufb %xmm4, %xmm3 # 3 = 1/jak
+ pxor %xmm1, %xmm3 # 3 = jo
+ jnz .Laes_loop
+
+ # middle of last round
+ movdqa .Lk_sbo(%rcx), %xmm4 # 3 : sbou
+ pshufb %xmm2, %xmm4 # 4 = sbou
+ pxor (%rdx), %xmm4 # 4 = sb1u + k
+ movdqa .Lk_sbo+16(%rcx), %xmm0 # 0 : sbot
+ pshufb %xmm3, %xmm0 # 0 = sb1t
+ pxor %xmm4, %xmm0 # 0 = A
+ pshufb .Lk_sr(%rsi,%rcx), %xmm0
+ EXIT_SYSV_FUNC
+ ret
+ CFI_ENDPROC();
+ELF(.size _aes_encrypt_core,.-_aes_encrypt_core)
+
+##
+## Decryption core
+##
+## Same API as encryption core.
+##
+.align 16
+.globl _gcry_aes_ssse3_decrypt_core
+ELF(.type _gcry_aes_ssse3_decrypt_core,@function)
+_gcry_aes_ssse3_decrypt_core:
+_aes_decrypt_core:
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+ mov %rdi, %rdx
+ lea .Laes_consts(%rip), %rcx
+ subl $1, %esi
+ movl %esi, %eax
+ shll $4, %esi
+ xorl $48, %esi
+ andl $48, %esi
+ movdqa .Lk_dipt (%rcx), %xmm2 # iptlo
+ movdqa %xmm9, %xmm1
+ pandn %xmm0, %xmm1
+ psrld $4, %xmm1
+ pand %xmm9, %xmm0
+ pshufb %xmm0, %xmm2
+ movdqa .Lk_dipt+16(%rcx), %xmm0 # ipthi
+ pshufb %xmm1, %xmm0
+ pxor (%rdx), %xmm2
+ pxor %xmm2, %xmm0
+ movdqa .Lk_mc_forward+48(%rcx), %xmm5
+ lea 16(%rdx), %rdx
+ neg %rax
+ jmp .Laes_dec_entry
+
+.align 16
+.Laes_dec_loop:
+##
+## Inverse mix columns
+##
+ movdqa %xmm13, %xmm4 # 4 : sb9u
+ pshufb %xmm2, %xmm4 # 4 = sb9u
+ pxor (%rdx), %xmm4
+ movdqa %xmm12, %xmm0 # 0 : sb9t
+ pshufb %xmm3, %xmm0 # 0 = sb9t
+ movdqa .Lk_dsbd+16(%rcx),%xmm1 # 1 : sbdt
+ pxor %xmm4, %xmm0 # 0 = ch
+ lea 16(%rdx), %rdx # next round key
+
+ pshufb %xmm5, %xmm0 # MC ch
+ movdqa %xmm15, %xmm4 # 4 : sbdu
+ pshufb %xmm2, %xmm4 # 4 = sbdu
+ pxor %xmm0, %xmm4 # 4 = ch
+ pshufb %xmm3, %xmm1 # 1 = sbdt
+ pxor %xmm4, %xmm1 # 1 = ch
+
+ pshufb %xmm5, %xmm1 # MC ch
+ movdqa %xmm14, %xmm4 # 4 : sbbu
+ pshufb %xmm2, %xmm4 # 4 = sbbu
+ inc %rax # nr--
+ pxor %xmm1, %xmm4 # 4 = ch
+ movdqa .Lk_dsbb+16(%rcx),%xmm0 # 0 : sbbt
+ pshufb %xmm3, %xmm0 # 0 = sbbt
+ pxor %xmm4, %xmm0 # 0 = ch
+
+ pshufb %xmm5, %xmm0 # MC ch
+ movdqa %xmm8, %xmm4 # 4 : sbeu
+ pshufb %xmm2, %xmm4 # 4 = sbeu
+ pshufd $0x93, %xmm5, %xmm5
+ pxor %xmm0, %xmm4 # 4 = ch
+ movdqa .Lk_dsbe+16(%rcx),%xmm0 # 0 : sbet
+ pshufb %xmm3, %xmm0 # 0 = sbet
+ pxor %xmm4, %xmm0 # 0 = ch
+
+.Laes_dec_entry:
+ # top of round
+ movdqa %xmm9, %xmm1 # 1 : i
+ pandn %xmm0, %xmm1 # 1 = i<<4
+ psrld $4, %xmm1 # 1 = i
+ pand %xmm9, %xmm0 # 0 = k
+ movdqa %xmm11, %xmm2 # 2 : a/k
+ pshufb %xmm0, %xmm2 # 2 = a/k
+ pxor %xmm1, %xmm0 # 0 = j
+ movdqa %xmm10, %xmm3 # 3 : 1/i
+ pshufb %xmm1, %xmm3 # 3 = 1/i
+ pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k
+ movdqa %xmm10, %xmm4 # 4 : 1/j
+ pshufb %xmm0, %xmm4 # 4 = 1/j
+ pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k
+ movdqa %xmm10, %xmm2 # 2 : 1/iak
+ pshufb %xmm3, %xmm2 # 2 = 1/iak
+ pxor %xmm0, %xmm2 # 2 = io
+ movdqa %xmm10, %xmm3 # 3 : 1/jak
+ pshufb %xmm4, %xmm3 # 3 = 1/jak
+ pxor %xmm1, %xmm3 # 3 = jo
+ jnz .Laes_dec_loop
+
+ # middle of last round
+ movdqa .Lk_dsbo(%rcx), %xmm4 # 3 : sbou
+ pshufb %xmm2, %xmm4 # 4 = sbou
+ pxor (%rdx), %xmm4 # 4 = sb1u + k
+ movdqa .Lk_dsbo+16(%rcx), %xmm0 # 0 : sbot
+ pshufb %xmm3, %xmm0 # 0 = sb1t
+ pxor %xmm4, %xmm0 # 0 = A
+ pshufb .Lk_sr(%rsi,%rcx), %xmm0
+ EXIT_SYSV_FUNC
+ ret
+ CFI_ENDPROC();
+ELF(.size _aes_decrypt_core,.-_aes_decrypt_core)
+
+########################################################
+## ##
+## AES key schedule ##
+## ##
+########################################################
+
+.align 16
+.globl _gcry_aes_ssse3_schedule_core
+ELF(.type _gcry_aes_ssse3_schedule_core,@function)
+_gcry_aes_ssse3_schedule_core:
+_aes_schedule_core:
+ # rdi = key
+ # rsi = size in bits
+ # rdx = buffer
+ # rcx = direction. 0=encrypt, 1=decrypt
+ # r8 = rotoffs
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_5
+
+ # load the tables
+ lea .Laes_consts(%rip), %r10
+ movdqa (%r10), %xmm9 # 0F
+ movdqa .Lk_inv (%r10), %xmm10 # inv
+ movdqa .Lk_inv+16(%r10), %xmm11 # inva
+ movdqa .Lk_sb1 (%r10), %xmm13 # sb1u
+ movdqa .Lk_sb1+16(%r10), %xmm12 # sb1t
+ movdqa .Lk_sb2 (%r10), %xmm15 # sb2u
+ movdqa .Lk_sb2+16(%r10), %xmm14 # sb2t
+
+ movdqa .Lk_rcon(%r10), %xmm8 # load rcon
+ movdqu (%rdi), %xmm0 # load key (unaligned)
+
+ # input transform
+ movdqu %xmm0, %xmm3
+ lea .Lk_ipt(%r10), %r11
+ call .Laes_schedule_transform
+ movdqu %xmm0, %xmm7
+
+ test %rcx, %rcx
+ jnz .Laes_schedule_am_decrypting
+
+ # encrypting, output zeroth round key after transform
+ movdqa %xmm0, (%rdx)
+ jmp .Laes_schedule_go
+
+.Laes_schedule_am_decrypting:
+ # decrypting, output zeroth round key after shiftrows
+ pshufb .Lk_sr(%r8,%r10),%xmm3
+ movdqa %xmm3, (%rdx)
+ xor $48, %r8
+
+.Laes_schedule_go:
+ cmp $192, %rsi
+ je .Laes_schedule_192
+ cmp $256, %rsi
+ je .Laes_schedule_256
+ # 128: fall though
+
+##
+## .Laes_schedule_128
+##
+## 128-bit specific part of key schedule.
+##
+## This schedule is really simple, because all its parts
+## are accomplished by the subroutines.
+##
+.Laes_schedule_128:
+ mov $10, %rsi
+
+.Laes_schedule_128_L:
+ call .Laes_schedule_round
+ dec %rsi
+ jz .Laes_schedule_mangle_last
+ call .Laes_schedule_mangle # write output
+ jmp .Laes_schedule_128_L
+
+##
+## .Laes_schedule_192
+##
+## 192-bit specific part of key schedule.
+##
+## The main body of this schedule is the same as the 128-bit
+## schedule, but with more smearing. The long, high side is
+## stored in %xmm7 as before, and the short, low side is in
+## the high bits of %xmm6.
+##
+## This schedule is somewhat nastier, however, because each
+## round produces 192 bits of key material, or 1.5 round keys.
+## Therefore, on each cycle we do 2 rounds and produce 3 round
+## keys.
+##
+.Laes_schedule_192:
+ movdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned)
+ call .Laes_schedule_transform # input transform
+ pshufd $0x0E, %xmm0, %xmm6
+ pslldq $8, %xmm6 # clobber low side with zeros
+ mov $4, %rsi
+
+.Laes_schedule_192_L:
+ call .Laes_schedule_round
+ palignr $8,%xmm6,%xmm0
+ call .Laes_schedule_mangle # save key n
+ call .Laes_schedule_192_smear
+ call .Laes_schedule_mangle # save key n+1
+ call .Laes_schedule_round
+ dec %rsi
+ jz .Laes_schedule_mangle_last
+ call .Laes_schedule_mangle # save key n+2
+ call .Laes_schedule_192_smear
+ jmp .Laes_schedule_192_L
+
+##
+## .Laes_schedule_192_smear
+##
+## Smear the short, low side in the 192-bit key schedule.
+##
+## Inputs:
+## %xmm7: high side, b a x y
+## %xmm6: low side, d c 0 0
+## %xmm13: 0
+##
+## Outputs:
+## %xmm6: b+c+d b+c 0 0
+## %xmm0: b+c+d b+c b a
+##
+.Laes_schedule_192_smear:
+ pshufd $0x80, %xmm6, %xmm0 # d c 0 0 -> c 0 0 0
+ pxor %xmm0, %xmm6 # -> c+d c 0 0
+ pshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a
+ pxor %xmm6, %xmm0 # -> b+c+d b+c b a
+ pshufd $0x0E, %xmm0, %xmm6
+ pslldq $8, %xmm6 # clobber low side with zeros
+ ret
+
+##
+## .Laes_schedule_256
+##
+## 256-bit specific part of key schedule.
+##
+## The structure here is very similar to the 128-bit
+## schedule, but with an additional 'low side' in
+## %xmm6. The low side's rounds are the same as the
+## high side's, except no rcon and no rotation.
+##
+.Laes_schedule_256:
+ movdqu 16(%rdi),%xmm0 # load key part 2 (unaligned)
+ call .Laes_schedule_transform # input transform
+ mov $7, %rsi
+
+.Laes_schedule_256_L:
+ call .Laes_schedule_mangle # output low result
+ movdqa %xmm0, %xmm6 # save cur_lo in xmm6
+
+ # high round
+ call .Laes_schedule_round
+ dec %rsi
+ jz .Laes_schedule_mangle_last
+ call .Laes_schedule_mangle
+
+ # low round. swap xmm7 and xmm6
+ pshufd $0xFF, %xmm0, %xmm0
+ movdqa %xmm7, %xmm5
+ movdqa %xmm6, %xmm7
+ call .Laes_schedule_low_round
+ movdqa %xmm5, %xmm7
+
+ jmp .Laes_schedule_256_L
+
+##
+## .Laes_schedule_round
+##
+## Runs one main round of the key schedule on %xmm0, %xmm7
+##
+## Specifically, runs subbytes on the high dword of %xmm0
+## then rotates it by one byte and xors into the low dword of
+## %xmm7.
+##
+## Adds rcon from low byte of %xmm8, then rotates %xmm8 for
+## next rcon.
+##
+## Smears the dwords of %xmm7 by xoring the low into the
+## second low, result into third, result into highest.
+##
+## Returns results in %xmm7 = %xmm0.
+## Clobbers %xmm1-%xmm4, %r11.
+##
+.Laes_schedule_round:
+ # extract rcon from xmm8
+ pxor %xmm1, %xmm1
+ palignr $15, %xmm8, %xmm1
+ palignr $15, %xmm8, %xmm8
+ pxor %xmm1, %xmm7
+
+ # rotate
+ pshufd $0xFF, %xmm0, %xmm0
+ palignr $1, %xmm0, %xmm0
+
+ # fall through...
+
+ # low round: same as high round, but no rotation and no rcon.
+.Laes_schedule_low_round:
+ # smear xmm7
+ movdqa %xmm7, %xmm1
+ pslldq $4, %xmm7
+ pxor %xmm1, %xmm7
+ movdqa %xmm7, %xmm1
+ pslldq $8, %xmm7
+ pxor %xmm1, %xmm7
+ pxor .Lk_s63(%r10), %xmm7
+
+ # subbytes
+ movdqa %xmm9, %xmm1
+ pandn %xmm0, %xmm1
+ psrld $4, %xmm1 # 1 = i
+ pand %xmm9, %xmm0 # 0 = k
+ movdqa %xmm11, %xmm2 # 2 : a/k
+ pshufb %xmm0, %xmm2 # 2 = a/k
+ pxor %xmm1, %xmm0 # 0 = j
+ movdqa %xmm10, %xmm3 # 3 : 1/i
+ pshufb %xmm1, %xmm3 # 3 = 1/i
+ pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k
+ movdqa %xmm10, %xmm4 # 4 : 1/j
+ pshufb %xmm0, %xmm4 # 4 = 1/j
+ pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k
+ movdqa %xmm10, %xmm2 # 2 : 1/iak
+ pshufb %xmm3, %xmm2 # 2 = 1/iak
+ pxor %xmm0, %xmm2 # 2 = io
+ movdqa %xmm10, %xmm3 # 3 : 1/jak
+ pshufb %xmm4, %xmm3 # 3 = 1/jak
+ pxor %xmm1, %xmm3 # 3 = jo
+ movdqa .Lk_sb1(%r10), %xmm4 # 4 : sbou
+ pshufb %xmm2, %xmm4 # 4 = sbou
+ movdqa .Lk_sb1+16(%r10), %xmm0 # 0 : sbot
+ pshufb %xmm3, %xmm0 # 0 = sb1t
+ pxor %xmm4, %xmm0 # 0 = sbox output
+
+ # add in smeared stuff
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, %xmm7
+ ret
+
+##
+## .Laes_schedule_transform
+##
+## Linear-transform %xmm0 according to tables at (%r11)
+##
+## Requires that %xmm9 = 0x0F0F... as in preheat
+## Output in %xmm0
+## Clobbers %xmm1, %xmm2
+##
+.Laes_schedule_transform:
+ movdqa %xmm9, %xmm1
+ pandn %xmm0, %xmm1
+ psrld $4, %xmm1
+ pand %xmm9, %xmm0
+ movdqa (%r11), %xmm2 # lo
+ pshufb %xmm0, %xmm2
+ movdqa 16(%r11), %xmm0 # hi
+ pshufb %xmm1, %xmm0
+ pxor %xmm2, %xmm0
+ ret
+
+##
+## .Laes_schedule_mangle
+##
+## Mangle xmm0 from (basis-transformed) standard version
+## to our version.
+##
+## On encrypt,
+## xor with 0x63
+## multiply by circulant 0,1,1,1
+## apply shiftrows transform
+##
+## On decrypt,
+## xor with 0x63
+## multiply by 'inverse mixcolumns' circulant E,B,D,9
+## deskew
+## apply shiftrows transform
+##
+##
+## Writes out to (%rdx), and increments or decrements it
+## Keeps track of round number mod 4 in %r8
+## Preserves xmm0
+## Clobbers xmm1-xmm5
+##
+.Laes_schedule_mangle:
+ movdqa %xmm0, %xmm4 # save xmm0 for later
+ movdqa .Lk_mc_forward(%r10),%xmm5
+ test %rcx, %rcx
+ jnz .Laes_schedule_mangle_dec
+
+ # encrypting
+ add $16, %rdx
+ pxor .Lk_s63(%r10),%xmm4
+ pshufb %xmm5, %xmm4
+ movdqa %xmm4, %xmm3
+ pshufb %xmm5, %xmm4
+ pxor %xmm4, %xmm3
+ pshufb %xmm5, %xmm4
+ pxor %xmm4, %xmm3
+
+ jmp .Laes_schedule_mangle_both
+
+.Laes_schedule_mangle_dec:
+ lea .Lk_dks_1(%r10), %r11 # first table: *9
+ call .Laes_schedule_transform
+ movdqa %xmm0, %xmm3
+ pshufb %xmm5, %xmm3
+
+ add $32, %r11 # next table: *B
+ call .Laes_schedule_transform
+ pxor %xmm0, %xmm3
+ pshufb %xmm5, %xmm3
+
+ add $32, %r11 # next table: *D
+ call .Laes_schedule_transform
+ pxor %xmm0, %xmm3
+ pshufb %xmm5, %xmm3
+
+ add $32, %r11 # next table: *E
+ call .Laes_schedule_transform
+ pxor %xmm0, %xmm3
+ pshufb %xmm5, %xmm3
+
+ movdqa %xmm4, %xmm0 # restore %xmm0
+ add $-16, %rdx
+
+.Laes_schedule_mangle_both:
+ pshufb .Lk_sr(%r8,%r10),%xmm3
+ add $-16, %r8
+ and $48, %r8
+ movdqa %xmm3, (%rdx)
+ ret
+
+##
+## .Laes_schedule_mangle_last
+##
+## Mangler for last round of key schedule
+## Mangles %xmm0
+## when encrypting, outputs out(%xmm0) ^ 63
+## when decrypting, outputs unskew(%xmm0)
+##
+## Always called right before return... jumps to cleanup and exits
+##
+.Laes_schedule_mangle_last:
+ # schedule last round key from xmm0
+ lea .Lk_deskew(%r10),%r11 # prepare to deskew
+ test %rcx, %rcx
+ jnz .Laes_schedule_mangle_last_dec
+
+ # encrypting
+ pshufb .Lk_sr(%r8,%r10),%xmm0 # output permute
+ lea .Lk_opt(%r10), %r11 # prepare to output transform
+ add $32, %rdx
+
+.Laes_schedule_mangle_last_dec:
+ add $-16, %rdx
+ pxor .Lk_s63(%r10), %xmm0
+ call .Laes_schedule_transform # output transform
+ movdqa %xmm0, (%rdx) # save last key
+
+ #_aes_cleanup
+ pxor %xmm0, %xmm0
+ pxor %xmm1, %xmm1
+ pxor %xmm2, %xmm2
+ pxor %xmm3, %xmm3
+ pxor %xmm4, %xmm4
+ pxor %xmm5, %xmm5
+ pxor %xmm6, %xmm6
+ pxor %xmm7, %xmm7
+ pxor %xmm8, %xmm8
+ EXIT_SYSV_FUNC
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_aes_ssse3_schedule_core,.-_gcry_aes_ssse3_schedule_core)
+
+########################################################
+## ##
+## Constants ##
+## ##
+########################################################
+
+.align 16
+ELF(.type _aes_consts,@object)
+.Laes_consts:
+_aes_consts:
+ # s0F
+ .Lk_s0F = .-.Laes_consts
+ .quad 0x0F0F0F0F0F0F0F0F
+ .quad 0x0F0F0F0F0F0F0F0F
+
+ # input transform (lo, hi)
+ .Lk_ipt = .-.Laes_consts
+ .quad 0xC2B2E8985A2A7000
+ .quad 0xCABAE09052227808
+ .quad 0x4C01307D317C4D00
+ .quad 0xCD80B1FCB0FDCC81
+
+ # inv, inva
+ .Lk_inv = .-.Laes_consts
+ .quad 0x0E05060F0D080180
+ .quad 0x040703090A0B0C02
+ .quad 0x01040A060F0B0780
+ .quad 0x030D0E0C02050809
+
+ # sb1u, sb1t
+ .Lk_sb1 = .-.Laes_consts
+ .quad 0xB19BE18FCB503E00
+ .quad 0xA5DF7A6E142AF544
+ .quad 0x3618D415FAE22300
+ .quad 0x3BF7CCC10D2ED9EF
+
+
+ # sb2u, sb2t
+ .Lk_sb2 = .-.Laes_consts
+ .quad 0xE27A93C60B712400
+ .quad 0x5EB7E955BC982FCD
+ .quad 0x69EB88400AE12900
+ .quad 0xC2A163C8AB82234A
+
+ # sbou, sbot
+ .Lk_sbo = .-.Laes_consts
+ .quad 0xD0D26D176FBDC700
+ .quad 0x15AABF7AC502A878
+ .quad 0xCFE474A55FBB6A00
+ .quad 0x8E1E90D1412B35FA
+
+ # mc_forward
+ .Lk_mc_forward = .-.Laes_consts
+ .quad 0x0407060500030201
+ .quad 0x0C0F0E0D080B0A09
+ .quad 0x080B0A0904070605
+ .quad 0x000302010C0F0E0D
+ .quad 0x0C0F0E0D080B0A09
+ .quad 0x0407060500030201
+ .quad 0x000302010C0F0E0D
+ .quad 0x080B0A0904070605
+
+ # mc_backward
+ .Lk_mc_backward = .-.Laes_consts
+ .quad 0x0605040702010003
+ .quad 0x0E0D0C0F0A09080B
+ .quad 0x020100030E0D0C0F
+ .quad 0x0A09080B06050407
+ .quad 0x0E0D0C0F0A09080B
+ .quad 0x0605040702010003
+ .quad 0x0A09080B06050407
+ .quad 0x020100030E0D0C0F
+
+ # sr
+ .Lk_sr = .-.Laes_consts
+ .quad 0x0706050403020100
+ .quad 0x0F0E0D0C0B0A0908
+ .quad 0x030E09040F0A0500
+ .quad 0x0B06010C07020D08
+ .quad 0x0F060D040B020900
+ .quad 0x070E050C030A0108
+ .quad 0x0B0E0104070A0D00
+ .quad 0x0306090C0F020508
+
+ # rcon
+ .Lk_rcon = .-.Laes_consts
+ .quad 0x1F8391B9AF9DEEB6
+ .quad 0x702A98084D7C7D81
+
+ # s63: all equal to 0x63 transformed
+ .Lk_s63 = .-.Laes_consts
+ .quad 0x5B5B5B5B5B5B5B5B
+ .quad 0x5B5B5B5B5B5B5B5B
+
+ # output transform
+ .Lk_opt = .-.Laes_consts
+ .quad 0xFF9F4929D6B66000
+ .quad 0xF7974121DEBE6808
+ .quad 0x01EDBD5150BCEC00
+ .quad 0xE10D5DB1B05C0CE0
+
+ # deskew tables: inverts the sbox's 'skew'
+ .Lk_deskew = .-.Laes_consts
+ .quad 0x07E4A34047A4E300
+ .quad 0x1DFEB95A5DBEF91A
+ .quad 0x5F36B5DC83EA6900
+ .quad 0x2841C2ABF49D1E77
+
+##
+## Decryption stuff
+## Key schedule constants
+##
+ # decryption key schedule: x -> invskew x*9
+ .Lk_dks_1 = .-.Laes_consts
+ .quad 0xB6116FC87ED9A700
+ .quad 0x4AED933482255BFC
+ .quad 0x4576516227143300
+ .quad 0x8BB89FACE9DAFDCE
+
+ # decryption key schedule: invskew x*9 -> invskew x*D
+ .Lk_dks_2 = .-.Laes_consts
+ .quad 0x27438FEBCCA86400
+ .quad 0x4622EE8AADC90561
+ .quad 0x815C13CE4F92DD00
+ .quad 0x73AEE13CBD602FF2
+
+ # decryption key schedule: invskew x*D -> invskew x*B
+ .Lk_dks_3 = .-.Laes_consts
+ .quad 0x03C4C50201C6C700
+ .quad 0xF83F3EF9FA3D3CFB
+ .quad 0xEE1921D638CFF700
+ .quad 0xA5526A9D7384BC4B
+
+ # decryption key schedule: invskew x*B -> invskew x*E + 0x63
+ .Lk_dks_4 = .-.Laes_consts
+ .quad 0xE3C390B053732000
+ .quad 0xA080D3F310306343
+ .quad 0xA0CA214B036982E8
+ .quad 0x2F45AEC48CE60D67
+
+##
+## Decryption stuff
+## Round function constants
+##
+ # decryption input transform
+ .Lk_dipt = .-.Laes_consts
+ .quad 0x0F505B040B545F00
+ .quad 0x154A411E114E451A
+ .quad 0x86E383E660056500
+ .quad 0x12771772F491F194
+
+ # decryption sbox output *9*u, *9*t
+ .Lk_dsb9 = .-.Laes_consts
+ .quad 0x851C03539A86D600
+ .quad 0xCAD51F504F994CC9
+ .quad 0xC03B1789ECD74900
+ .quad 0x725E2C9EB2FBA565
+
+ # decryption sbox output *D*u, *D*t
+ .Lk_dsbd = .-.Laes_consts
+ .quad 0x7D57CCDFE6B1A200
+ .quad 0xF56E9B13882A4439
+ .quad 0x3CE2FAF724C6CB00
+ .quad 0x2931180D15DEEFD3
+
+ # decryption sbox output *B*u, *B*t
+ .Lk_dsbb = .-.Laes_consts
+ .quad 0xD022649296B44200
+ .quad 0x602646F6B0F2D404
+ .quad 0xC19498A6CD596700
+ .quad 0xF3FF0C3E3255AA6B
+
+ # decryption sbox output *E*u, *E*t
+ .Lk_dsbe = .-.Laes_consts
+ .quad 0x46F2929626D4D000
+ .quad 0x2242600464B4F6B0
+ .quad 0x0C55A6CDFFAAC100
+ .quad 0x9467F36B98593E32
+
+ # decryption sbox final output
+ .Lk_dsbo = .-.Laes_consts
+ .quad 0x1387EA537EF94000
+ .quad 0xC7AA6DB9D4943E2D
+ .quad 0x12D7560F93441D00
+ .quad 0xCA4B8159D8C58E9C
+ELF(.size _aes_consts,.-_aes_consts)
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/rijndael-ssse3-amd64.c b/comm/third_party/libgcrypt/cipher/rijndael-ssse3-amd64.c
new file mode 100644
index 0000000000..b07238531c
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-ssse3-amd64.c
@@ -0,0 +1,743 @@
+/* SSSE3 vector permutation AES for Libgcrypt
+ * Copyright (C) 2014-2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ *
+ * 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* 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/comm/third_party/libgcrypt/cipher/rijndael-tables.h b/comm/third_party/libgcrypt/cipher/rijndael-tables.h
new file mode 100644
index 0000000000..b54d959393
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael-tables.h
@@ -0,0 +1,227 @@
+/* rijndael-tables.h - Rijndael (AES) for GnuPG,
+ * Copyright (C) 2000, 2001, 2002, 2003, 2007,
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* To keep the actual implementation at a readable size we use this
+ include file to define the tables. */
+
+static struct
+{
+ volatile u32 counter_head;
+ u32 cacheline_align[64 / 4 - 1];
+ u32 T[256];
+ volatile u32 counter_tail;
+} enc_tables ATTR_ALIGNED_64 =
+ {
+ 0,
+ { 0, },
+ {
+ 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
+ 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
+ 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
+ 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
+ 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
+ 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
+ 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,
+ 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
+ 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
+ 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
+ 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9,
+ 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
+ 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d,
+ 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
+ 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
+ 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
+ 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,
+ 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
+ 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d,
+ 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
+ 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
+ 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
+ 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972,
+ 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
+ 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
+ 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
+ 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
+ 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
+ 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05,
+ 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
+ 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142,
+ 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
+ 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
+ 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
+ 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
+ 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
+ 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,
+ 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
+ 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
+ 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
+ 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14,
+ 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
+ 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4,
+ 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
+ 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
+ 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
+ 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,
+ 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
+ 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c,
+ 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
+ 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
+ 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
+ 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc,
+ 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
+ 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
+ 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
+ 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
+ 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
+ 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9,
+ 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
+ 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a,
+ 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
+ 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
+ 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
+ },
+ 0
+ };
+
+#define encT enc_tables.T
+
+static struct
+{
+ volatile u32 counter_head;
+ u32 cacheline_align[64 / 4 - 1];
+ u32 T[256];
+ byte inv_sbox[256];
+ volatile u32 counter_tail;
+} dec_tables ATTR_ALIGNED_64 =
+ {
+ 0,
+ { 0, },
+ {
+ 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a,
+ 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
+ 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5,
+ 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
+ 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d,
+ 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
+ 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295,
+ 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
+ 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927,
+ 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
+ 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362,
+ 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
+ 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52,
+ 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
+ 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
+ 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
+ 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e,
+ 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
+ 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4,
+ 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
+ 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d,
+ 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060,
+ 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967,
+ 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
+ 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000,
+ 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
+ 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36,
+ 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
+ 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b,
+ 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
+ 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12,
+ 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
+ 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,
+ 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
+ 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8,
+ 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
+ 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7,
+ 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
+ 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947,
+ 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
+ 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498,
+ 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
+ 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54,
+ 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
+ 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
+ 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
+ 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83,
+ 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
+ 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029,
+ 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
+ 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733,
+ 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117,
+ 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4,
+ 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
+ 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb,
+ 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
+ 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb,
+ 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
+ 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773,
+ 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
+ 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2,
+ 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff,
+ 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,
+ 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0
+ },
+ {
+ 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
+ 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
+ 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
+ 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
+ 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
+ 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
+ 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
+ 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
+ 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
+ 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
+ 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
+ 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
+ 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
+ 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
+ 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
+ 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
+ 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
+ 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
+ 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
+ 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
+ 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
+ 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
+ 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
+ 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
+ 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
+ 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
+ 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
+ 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
+ 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
+ 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
+ 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
+ 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+ },
+ 0
+ };
+
+#define decT dec_tables.T
+#define inv_sbox dec_tables.inv_sbox
+
+static const u32 rcon[30] =
+ {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
+ 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
+ 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
+ };
diff --git a/comm/third_party/libgcrypt/cipher/rijndael.c b/comm/third_party/libgcrypt/cipher/rijndael.c
new file mode 100644
index 0000000000..fe137327e7
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rijndael.c
@@ -0,0 +1,2032 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ *******************************************************************
+ * 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcmp() */
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-selftest.h"
+#include "rijndael-internal.h"
+#include "./cipher-internal.h"
+
+
+#ifdef USE_AMD64_ASM
+/* AMD64 assembly implementations of AES */
+extern unsigned int _gcry_aes_amd64_encrypt_block(const void *keysched_enc,
+ unsigned char *out,
+ const unsigned char *in,
+ int rounds,
+ const void *encT);
+
+extern unsigned int _gcry_aes_amd64_decrypt_block(const void *keysched_dec,
+ unsigned char *out,
+ const unsigned char *in,
+ int rounds,
+ const void *decT);
+#endif /*USE_AMD64_ASM*/
+
+#ifdef USE_AESNI
+/* AES-NI (AMD64 & i386) accelerated implementations of AES */
+extern void _gcry_aes_aesni_do_setkey(RIJNDAEL_context *ctx, const byte *key);
+extern void _gcry_aes_aesni_prepare_decryption(RIJNDAEL_context *ctx);
+
+extern unsigned int _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx,
+ unsigned char *dst,
+ const unsigned char *src);
+extern unsigned int _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx,
+ unsigned char *dst,
+ const unsigned char *src);
+extern void _gcry_aes_aesni_cfb_enc (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
+extern void _gcry_aes_aesni_cbc_enc (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks, int cbc_mac);
+extern void _gcry_aes_aesni_ctr_enc (void *context, unsigned char *ctr,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
+extern void _gcry_aes_aesni_cfb_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
+extern void _gcry_aes_aesni_cbc_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
+extern size_t _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks,
+ int encrypt);
+extern size_t _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+ size_t nblocks);
+extern void _gcry_aes_aesni_xts_crypt (void *context, unsigned char *tweak,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks, int encrypt);
+#endif
+
+#ifdef USE_SSSE3
+/* SSSE3 (AMD64) vector permutation implementation of AES */
+extern void _gcry_aes_ssse3_do_setkey(RIJNDAEL_context *ctx, const byte *key);
+extern void _gcry_aes_ssse3_prepare_decryption(RIJNDAEL_context *ctx);
+
+extern unsigned int _gcry_aes_ssse3_encrypt (const RIJNDAEL_context *ctx,
+ unsigned char *dst,
+ const unsigned char *src);
+extern unsigned int _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx,
+ unsigned char *dst,
+ const unsigned char *src);
+extern void _gcry_aes_ssse3_cfb_enc (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
+extern void _gcry_aes_ssse3_cbc_enc (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks,
+ int cbc_mac);
+extern void _gcry_aes_ssse3_ctr_enc (void *context, unsigned char *ctr,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
+extern void _gcry_aes_ssse3_cfb_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
+extern void _gcry_aes_ssse3_cbc_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ size_t nblocks);
+extern size_t _gcry_aes_ssse3_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
+ const void *inbuf_arg, size_t nblocks,
+ int encrypt);
+extern size_t _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
+ size_t nblocks);
+#endif
+
+#ifdef USE_PADLOCK
+extern unsigned int _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx,
+ unsigned char *bx,
+ const unsigned char *ax);
+extern unsigned int _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx,
+ unsigned char *bx,
+ const unsigned char *ax);
+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_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);
+#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->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;
+ }
+#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->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;
+ }
+#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 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";
+
+ 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 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";
+ 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 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";
+ 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)
+{
+ const int nblocks = 8+1;
+ const int blocksize = BLOCKSIZE;
+ const int context_size = sizeof(RIJNDAEL_context);
+
+ return _gcry_selftest_helper_ctr("AES", &rijndael_setkey,
+ &rijndael_encrypt, nblocks, blocksize, context_size);
+}
+
+
+/* Run the self-tests for AES-CBC-128, tests bulk CBC decryption.
+ Returns NULL on success. */
+static const char*
+selftest_cbc_128 (void)
+{
+ const int nblocks = 8+2;
+ const int blocksize = BLOCKSIZE;
+ const int context_size = sizeof(RIJNDAEL_context);
+
+ return _gcry_selftest_helper_cbc("AES", &rijndael_setkey,
+ &rijndael_encrypt, nblocks, blocksize, context_size);
+}
+
+
+/* Run the self-tests for AES-CFB-128, tests bulk CFB decryption.
+ Returns NULL on success. */
+static const char*
+selftest_cfb_128 (void)
+{
+ const int nblocks = 8+2;
+ const int blocksize = BLOCKSIZE;
+ const int context_size = sizeof(RIJNDAEL_context);
+
+ return _gcry_selftest_helper_cfb("AES", &rijndael_setkey,
+ &rijndael_encrypt, nblocks, blocksize, context_size);
+}
+
+
+/* Run all the self-tests and return NULL on success. This function
+ is used for the on-the-fly self-tests. */
+static const char *
+selftest (void)
+{
+ const char *r;
+
+ if ( (r = selftest_basic_128 ())
+ || (r = selftest_basic_192 ())
+ || (r = selftest_basic_256 ()) )
+ return r;
+
+ if ( (r = selftest_ctr_128 ()) )
+ return r;
+
+ if ( (r = selftest_cbc_128 ()) )
+ return r;
+
+ if ( (r = selftest_cfb_128 ()) )
+ return r;
+
+ return r;
+}
+
+
+/* SP800-38a.pdf for AES-128. */
+static const char *
+selftest_fips_128_38a (int requested_mode)
+{
+ static const struct tv
+ {
+ int mode;
+ const unsigned char key[16];
+ const unsigned char iv[16];
+ struct
+ {
+ const unsigned char input[16];
+ const unsigned char output[16];
+ } data[4];
+ } tv[2] =
+ {
+ {
+ GCRY_CIPHER_MODE_CFB, /* F.3.13, CFB128-AES128 */
+ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ {
+ { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
+ { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+ 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
+
+ { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
+ { 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f,
+ 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b } },
+
+ { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
+ { 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40,
+ 0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf } },
+
+ { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ { 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e,
+ 0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6 } }
+ }
+ },
+ {
+ GCRY_CIPHER_MODE_OFB,
+ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ {
+ { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
+ { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+ 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
+
+ { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
+ { 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
+ 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25 } },
+
+ { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
+ { 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
+ 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc } },
+
+ { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ { 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
+ 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e } },
+ }
+ }
+ };
+ unsigned char scratch[16];
+ gpg_error_t err;
+ int tvi, idx;
+ gcry_cipher_hd_t hdenc = NULL;
+ gcry_cipher_hd_t hddec = NULL;
+
+#define Fail(a) do { \
+ _gcry_cipher_close (hdenc); \
+ _gcry_cipher_close (hddec); \
+ return a; \
+ } while (0)
+
+ gcry_assert (sizeof tv[0].data[0].input == sizeof scratch);
+ gcry_assert (sizeof tv[0].data[0].output == sizeof scratch);
+
+ for (tvi=0; tvi < DIM (tv); tvi++)
+ if (tv[tvi].mode == requested_mode)
+ break;
+ if (tvi == DIM (tv))
+ Fail ("no test data for this mode");
+
+ err = _gcry_cipher_open (&hdenc, GCRY_CIPHER_AES, tv[tvi].mode, 0);
+ if (err)
+ Fail ("open");
+ err = _gcry_cipher_open (&hddec, GCRY_CIPHER_AES, tv[tvi].mode, 0);
+ if (err)
+ Fail ("open");
+ err = _gcry_cipher_setkey (hdenc, tv[tvi].key, sizeof tv[tvi].key);
+ if (!err)
+ err = _gcry_cipher_setkey (hddec, tv[tvi].key, sizeof tv[tvi].key);
+ if (err)
+ Fail ("set key");
+ err = _gcry_cipher_setiv (hdenc, tv[tvi].iv, sizeof tv[tvi].iv);
+ if (!err)
+ err = _gcry_cipher_setiv (hddec, tv[tvi].iv, sizeof tv[tvi].iv);
+ if (err)
+ Fail ("set IV");
+ for (idx=0; idx < DIM (tv[tvi].data); idx++)
+ {
+ err = _gcry_cipher_encrypt (hdenc, scratch, sizeof scratch,
+ tv[tvi].data[idx].input,
+ sizeof tv[tvi].data[idx].input);
+ if (err)
+ Fail ("encrypt command");
+ if (memcmp (scratch, tv[tvi].data[idx].output, sizeof scratch))
+ Fail ("encrypt mismatch");
+ err = _gcry_cipher_decrypt (hddec, scratch, sizeof scratch,
+ tv[tvi].data[idx].output,
+ sizeof tv[tvi].data[idx].output);
+ if (err)
+ Fail ("decrypt command");
+ if (memcmp (scratch, tv[tvi].data[idx].input, sizeof scratch))
+ Fail ("decrypt mismatch");
+ }
+
+#undef Fail
+ _gcry_cipher_close (hdenc);
+ _gcry_cipher_close (hddec);
+ return NULL;
+}
+
+
+/* Complete selftest for AES-128 with all modes and driver code. */
+static gpg_err_code_t
+selftest_fips_128 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "low-level";
+ errtxt = selftest_basic_128 ();
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "cfb";
+ errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB);
+ if (errtxt)
+ goto failed;
+
+ what = "ofb";
+ errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cipher", GCRY_CIPHER_AES128, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+/* Complete selftest for AES-192. */
+static gpg_err_code_t
+selftest_fips_192 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ (void)extended; /* No extended tests available. */
+
+ what = "low-level";
+ errtxt = selftest_basic_192 ();
+ if (errtxt)
+ goto failed;
+
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cipher", GCRY_CIPHER_AES192, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Complete selftest for AES-256. */
+static gpg_err_code_t
+selftest_fips_256 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ (void)extended; /* No extended tests available. */
+
+ what = "low-level";
+ errtxt = selftest_basic_256 ();
+ if (errtxt)
+ goto failed;
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cipher", GCRY_CIPHER_AES256, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_CIPHER_AES128:
+ ec = selftest_fips_128 (extended, report);
+ break;
+ case GCRY_CIPHER_AES192:
+ ec = selftest_fips_192 (extended, report);
+ break;
+ case GCRY_CIPHER_AES256:
+ ec = selftest_fips_256 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_CIPHER_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+
+static const char *rijndael_names[] =
+ {
+ "RIJNDAEL",
+ "AES128",
+ "AES-128",
+ NULL
+ };
+
+static gcry_cipher_oid_spec_t rijndael_oids[] =
+ {
+ { "2.16.840.1.101.3.4.1.1", GCRY_CIPHER_MODE_ECB },
+ { "2.16.840.1.101.3.4.1.2", GCRY_CIPHER_MODE_CBC },
+ { "2.16.840.1.101.3.4.1.3", GCRY_CIPHER_MODE_OFB },
+ { "2.16.840.1.101.3.4.1.4", GCRY_CIPHER_MODE_CFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes =
+ {
+ GCRY_CIPHER_AES, {0, 1},
+ "AES", rijndael_names, rijndael_oids, 16, 128,
+ sizeof (RIJNDAEL_context),
+ rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+ NULL, NULL,
+ run_selftests
+ };
+
+
+static const char *rijndael192_names[] =
+ {
+ "RIJNDAEL192",
+ "AES-192",
+ NULL
+ };
+
+static gcry_cipher_oid_spec_t rijndael192_oids[] =
+ {
+ { "2.16.840.1.101.3.4.1.21", GCRY_CIPHER_MODE_ECB },
+ { "2.16.840.1.101.3.4.1.22", GCRY_CIPHER_MODE_CBC },
+ { "2.16.840.1.101.3.4.1.23", GCRY_CIPHER_MODE_OFB },
+ { "2.16.840.1.101.3.4.1.24", GCRY_CIPHER_MODE_CFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes192 =
+ {
+ GCRY_CIPHER_AES192, {0, 1},
+ "AES192", rijndael192_names, rijndael192_oids, 16, 192,
+ sizeof (RIJNDAEL_context),
+ rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+ NULL, NULL,
+ run_selftests
+ };
+
+
+static const char *rijndael256_names[] =
+ {
+ "RIJNDAEL256",
+ "AES-256",
+ NULL
+ };
+
+static gcry_cipher_oid_spec_t rijndael256_oids[] =
+ {
+ { "2.16.840.1.101.3.4.1.41", GCRY_CIPHER_MODE_ECB },
+ { "2.16.840.1.101.3.4.1.42", GCRY_CIPHER_MODE_CBC },
+ { "2.16.840.1.101.3.4.1.43", GCRY_CIPHER_MODE_OFB },
+ { "2.16.840.1.101.3.4.1.44", GCRY_CIPHER_MODE_CFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes256 =
+ {
+ GCRY_CIPHER_AES256, {0, 1},
+ "AES256", rijndael256_names, rijndael256_oids, 16, 256,
+ sizeof (RIJNDAEL_context),
+ rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+ NULL, NULL,
+ run_selftests
+ };
diff --git a/comm/third_party/libgcrypt/cipher/rmd160.c b/comm/third_party/libgcrypt/cipher/rmd160.c
new file mode 100644
index 0000000000..e12ff0176f
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rmd160.c
@@ -0,0 +1,529 @@
+/* rmd160.c - RIPE-MD160
+ * 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
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "hash-common.h"
+#include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
+
+#include "bithelp.h"
+#include "bufhelp.h"
+
+/*********************************
+ * RIPEMD-160 is not patented, see (as of 25.10.97)
+ * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
+ * Note that the code uses Little Endian byteorder, which is good for
+ * 386 etc, but we must add some conversion when used on a big endian box.
+ *
+ *
+ * Pseudo-code for RIPEMD-160
+ *
+ * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
+ * The round function takes as input a 5-word chaining variable and a 16-word
+ * message block and maps this to a new chaining variable. All operations are
+ * defined on 32-bit words. Padding is identical to that of MD4.
+ *
+ *
+ * RIPEMD-160: definitions
+ *
+ *
+ * nonlinear functions at bit level: exor, mux, -, mux, -
+ *
+ * f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15)
+ * f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31)
+ * f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47)
+ * f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63)
+ * f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79)
+ *
+ *
+ * added constants (hexadecimal)
+ *
+ * K(j) = 0x00000000 (0 <= j <= 15)
+ * K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2))
+ * K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3))
+ * K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5))
+ * K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7))
+ * K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2))
+ * K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3))
+ * K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5))
+ * K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7))
+ * K'(j) = 0x00000000 (64 <= j <= 79)
+ *
+ *
+ * selection of message word
+ *
+ * r(j) = j (0 <= j <= 15)
+ * r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
+ * r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
+ * r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
+ * r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
+ * r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
+ * r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
+ * r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
+ * r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
+ * r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
+ *
+ *
+ * amount for rotate left (rol)
+ *
+ * s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
+ * s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
+ * s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
+ * s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
+ * s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
+ * s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
+ * s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
+ * s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
+ * s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
+ * s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
+ *
+ *
+ * initial value (hexadecimal)
+ *
+ * h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
+ * h4 = 0xC3D2E1F0;
+ *
+ *
+ * RIPEMD-160: pseudo-code
+ *
+ * It is assumed that the message after padding consists of t 16-word blocks
+ * that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
+ * The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
+ * shift (rotate) over s positions.
+ *
+ *
+ * for i := 0 to t-1 {
+ * A := h0; B := h1; C := h2; D = h3; E = h4;
+ * A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
+ * for j := 0 to 79 {
+ * T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
+ * A := E; E := D; D := rol_10(C); C := B; B := T;
+ * T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
+ [+] K'(j)) [+] E';
+ * A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
+ * }
+ * T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
+ * h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
+ * }
+ */
+
+/* Some examples:
+ * "" 9c1185a5c5e9fc54612808977ee8f548b2258d31
+ * "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
+ * "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
+ * "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36
+ * "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc
+ * "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b
+ * "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189
+ * 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb
+ * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
+ */
+
+typedef struct
+{
+ gcry_md_block_ctx_t bctx;
+ u32 h0,h1,h2,h3,h4;
+} RMD160_CONTEXT;
+
+
+static unsigned int
+transform ( void *ctx, const unsigned char *data, size_t nblks );
+
+static void
+rmd160_init (void *context, unsigned int flags)
+{
+ RMD160_CONTEXT *hd = context;
+
+ (void)flags;
+
+ hd->h0 = 0x67452301;
+ hd->h1 = 0xEFCDAB89;
+ hd->h2 = 0x98BADCFE;
+ hd->h3 = 0x10325476;
+ hd->h4 = 0xC3D2E1F0;
+
+ hd->bctx.nblocks = 0;
+ hd->bctx.nblocks_high = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize_shift = _gcry_ctz(64);
+ hd->bctx.bwrite = transform;
+}
+
+
+/****************
+ * Transform the message X which consists of 16 32-bit-words
+ */
+static unsigned int
+transform_blk ( void *ctx, const unsigned char *data )
+{
+ RMD160_CONTEXT *hd = ctx;
+ register u32 al, ar, bl, br, cl, cr, dl, dr, el, er;
+ u32 x[16];
+ int i;
+
+ for ( i = 0; i < 16; i++ )
+ x[i] = buf_get_le32(data + i * 4);
+
+#define K0 0x00000000
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xA953FD4E
+#define KK0 0x50A28BE6
+#define KK1 0x5C4DD124
+#define KK2 0x6D703EF3
+#define KK3 0x7A6D76E9
+#define KK4 0x00000000
+#define F0(x,y,z) ( (x) ^ (y) ^ (z) )
+#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
+#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
+#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
+#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
+#define R(a,b,c,d,e,f,k,r,s) do { a += f(b,c,d) + k + x[r]; \
+ a = rol(a,s) + e; \
+ c = rol(c,10); \
+ } while(0)
+
+ /* left lane and right lanes interleaved */
+ al = ar = hd->h0;
+ bl = br = hd->h1;
+ cl = cr = hd->h2;
+ dl = dr = hd->h3;
+ el = er = hd->h4;
+ R( al, bl, cl, dl, el, F0, K0, 0, 11 );
+ R( ar, br, cr, dr, er, F4, KK0, 5, 8);
+ R( el, al, bl, cl, dl, F0, K0, 1, 14 );
+ R( er, ar, br, cr, dr, F4, KK0, 14, 9);
+ R( dl, el, al, bl, cl, F0, K0, 2, 15 );
+ R( dr, er, ar, br, cr, F4, KK0, 7, 9);
+ R( cl, dl, el, al, bl, F0, K0, 3, 12 );
+ R( cr, dr, er, ar, br, F4, KK0, 0, 11);
+ R( bl, cl, dl, el, al, F0, K0, 4, 5 );
+ R( br, cr, dr, er, ar, F4, KK0, 9, 13);
+ R( al, bl, cl, dl, el, F0, K0, 5, 8 );
+ R( ar, br, cr, dr, er, F4, KK0, 2, 15);
+ R( el, al, bl, cl, dl, F0, K0, 6, 7 );
+ R( er, ar, br, cr, dr, F4, KK0, 11, 15);
+ R( dl, el, al, bl, cl, F0, K0, 7, 9 );
+ R( dr, er, ar, br, cr, F4, KK0, 4, 5);
+ R( cl, dl, el, al, bl, F0, K0, 8, 11 );
+ R( cr, dr, er, ar, br, F4, KK0, 13, 7);
+ R( bl, cl, dl, el, al, F0, K0, 9, 13 );
+ R( br, cr, dr, er, ar, F4, KK0, 6, 7);
+ R( al, bl, cl, dl, el, F0, K0, 10, 14 );
+ R( ar, br, cr, dr, er, F4, KK0, 15, 8);
+ R( el, al, bl, cl, dl, F0, K0, 11, 15 );
+ R( er, ar, br, cr, dr, F4, KK0, 8, 11);
+ R( dl, el, al, bl, cl, F0, K0, 12, 6 );
+ R( dr, er, ar, br, cr, F4, KK0, 1, 14);
+ R( cl, dl, el, al, bl, F0, K0, 13, 7 );
+ R( cr, dr, er, ar, br, F4, KK0, 10, 14);
+ R( bl, cl, dl, el, al, F0, K0, 14, 9 );
+ R( br, cr, dr, er, ar, F4, KK0, 3, 12);
+ R( al, bl, cl, dl, el, F0, K0, 15, 8 );
+ R( ar, br, cr, dr, er, F4, KK0, 12, 6);
+ R( el, al, bl, cl, dl, F1, K1, 7, 7 );
+ R( er, ar, br, cr, dr, F3, KK1, 6, 9);
+ R( dl, el, al, bl, cl, F1, K1, 4, 6 );
+ R( dr, er, ar, br, cr, F3, KK1, 11, 13);
+ R( cl, dl, el, al, bl, F1, K1, 13, 8 );
+ R( cr, dr, er, ar, br, F3, KK1, 3, 15);
+ R( bl, cl, dl, el, al, F1, K1, 1, 13 );
+ R( br, cr, dr, er, ar, F3, KK1, 7, 7);
+ R( al, bl, cl, dl, el, F1, K1, 10, 11 );
+ R( ar, br, cr, dr, er, F3, KK1, 0, 12);
+ R( el, al, bl, cl, dl, F1, K1, 6, 9 );
+ R( er, ar, br, cr, dr, F3, KK1, 13, 8);
+ R( dl, el, al, bl, cl, F1, K1, 15, 7 );
+ R( dr, er, ar, br, cr, F3, KK1, 5, 9);
+ R( cl, dl, el, al, bl, F1, K1, 3, 15 );
+ R( cr, dr, er, ar, br, F3, KK1, 10, 11);
+ R( bl, cl, dl, el, al, F1, K1, 12, 7 );
+ R( br, cr, dr, er, ar, F3, KK1, 14, 7);
+ R( al, bl, cl, dl, el, F1, K1, 0, 12 );
+ R( ar, br, cr, dr, er, F3, KK1, 15, 7);
+ R( el, al, bl, cl, dl, F1, K1, 9, 15 );
+ R( er, ar, br, cr, dr, F3, KK1, 8, 12);
+ R( dl, el, al, bl, cl, F1, K1, 5, 9 );
+ R( dr, er, ar, br, cr, F3, KK1, 12, 7);
+ R( cl, dl, el, al, bl, F1, K1, 2, 11 );
+ R( cr, dr, er, ar, br, F3, KK1, 4, 6);
+ R( bl, cl, dl, el, al, F1, K1, 14, 7 );
+ R( br, cr, dr, er, ar, F3, KK1, 9, 15);
+ R( al, bl, cl, dl, el, F1, K1, 11, 13 );
+ R( ar, br, cr, dr, er, F3, KK1, 1, 13);
+ R( el, al, bl, cl, dl, F1, K1, 8, 12 );
+ R( er, ar, br, cr, dr, F3, KK1, 2, 11);
+ R( dl, el, al, bl, cl, F2, K2, 3, 11 );
+ R( dr, er, ar, br, cr, F2, KK2, 15, 9);
+ R( cl, dl, el, al, bl, F2, K2, 10, 13 );
+ R( cr, dr, er, ar, br, F2, KK2, 5, 7);
+ R( bl, cl, dl, el, al, F2, K2, 14, 6 );
+ R( br, cr, dr, er, ar, F2, KK2, 1, 15);
+ R( al, bl, cl, dl, el, F2, K2, 4, 7 );
+ R( ar, br, cr, dr, er, F2, KK2, 3, 11);
+ R( el, al, bl, cl, dl, F2, K2, 9, 14 );
+ R( er, ar, br, cr, dr, F2, KK2, 7, 8);
+ R( dl, el, al, bl, cl, F2, K2, 15, 9 );
+ R( dr, er, ar, br, cr, F2, KK2, 14, 6);
+ R( cl, dl, el, al, bl, F2, K2, 8, 13 );
+ R( cr, dr, er, ar, br, F2, KK2, 6, 6);
+ R( bl, cl, dl, el, al, F2, K2, 1, 15 );
+ R( br, cr, dr, er, ar, F2, KK2, 9, 14);
+ R( al, bl, cl, dl, el, F2, K2, 2, 14 );
+ R( ar, br, cr, dr, er, F2, KK2, 11, 12);
+ R( el, al, bl, cl, dl, F2, K2, 7, 8 );
+ R( er, ar, br, cr, dr, F2, KK2, 8, 13);
+ R( dl, el, al, bl, cl, F2, K2, 0, 13 );
+ R( dr, er, ar, br, cr, F2, KK2, 12, 5);
+ R( cl, dl, el, al, bl, F2, K2, 6, 6 );
+ R( cr, dr, er, ar, br, F2, KK2, 2, 14);
+ R( bl, cl, dl, el, al, F2, K2, 13, 5 );
+ R( br, cr, dr, er, ar, F2, KK2, 10, 13);
+ R( al, bl, cl, dl, el, F2, K2, 11, 12 );
+ R( ar, br, cr, dr, er, F2, KK2, 0, 13);
+ R( el, al, bl, cl, dl, F2, K2, 5, 7 );
+ R( er, ar, br, cr, dr, F2, KK2, 4, 7);
+ R( dl, el, al, bl, cl, F2, K2, 12, 5 );
+ R( dr, er, ar, br, cr, F2, KK2, 13, 5);
+ R( cl, dl, el, al, bl, F3, K3, 1, 11 );
+ R( cr, dr, er, ar, br, F1, KK3, 8, 15);
+ R( bl, cl, dl, el, al, F3, K3, 9, 12 );
+ R( br, cr, dr, er, ar, F1, KK3, 6, 5);
+ R( al, bl, cl, dl, el, F3, K3, 11, 14 );
+ R( ar, br, cr, dr, er, F1, KK3, 4, 8);
+ R( el, al, bl, cl, dl, F3, K3, 10, 15 );
+ R( er, ar, br, cr, dr, F1, KK3, 1, 11);
+ R( dl, el, al, bl, cl, F3, K3, 0, 14 );
+ R( dr, er, ar, br, cr, F1, KK3, 3, 14);
+ R( cl, dl, el, al, bl, F3, K3, 8, 15 );
+ R( cr, dr, er, ar, br, F1, KK3, 11, 14);
+ R( bl, cl, dl, el, al, F3, K3, 12, 9 );
+ R( br, cr, dr, er, ar, F1, KK3, 15, 6);
+ R( al, bl, cl, dl, el, F3, K3, 4, 8 );
+ R( ar, br, cr, dr, er, F1, KK3, 0, 14);
+ R( el, al, bl, cl, dl, F3, K3, 13, 9 );
+ R( er, ar, br, cr, dr, F1, KK3, 5, 6);
+ R( dl, el, al, bl, cl, F3, K3, 3, 14 );
+ R( dr, er, ar, br, cr, F1, KK3, 12, 9);
+ R( cl, dl, el, al, bl, F3, K3, 7, 5 );
+ R( cr, dr, er, ar, br, F1, KK3, 2, 12);
+ R( bl, cl, dl, el, al, F3, K3, 15, 6 );
+ R( br, cr, dr, er, ar, F1, KK3, 13, 9);
+ R( al, bl, cl, dl, el, F3, K3, 14, 8 );
+ R( ar, br, cr, dr, er, F1, KK3, 9, 12);
+ R( el, al, bl, cl, dl, F3, K3, 5, 6 );
+ R( er, ar, br, cr, dr, F1, KK3, 7, 5);
+ R( dl, el, al, bl, cl, F3, K3, 6, 5 );
+ R( dr, er, ar, br, cr, F1, KK3, 10, 15);
+ R( cl, dl, el, al, bl, F3, K3, 2, 12 );
+ R( cr, dr, er, ar, br, F1, KK3, 14, 8);
+ R( bl, cl, dl, el, al, F4, K4, 4, 9 );
+ R( br, cr, dr, er, ar, F0, KK4, 12, 8);
+ R( al, bl, cl, dl, el, F4, K4, 0, 15 );
+ R( ar, br, cr, dr, er, F0, KK4, 15, 5);
+ R( el, al, bl, cl, dl, F4, K4, 5, 5 );
+ R( er, ar, br, cr, dr, F0, KK4, 10, 12);
+ R( dl, el, al, bl, cl, F4, K4, 9, 11 );
+ R( dr, er, ar, br, cr, F0, KK4, 4, 9);
+ R( cl, dl, el, al, bl, F4, K4, 7, 6 );
+ R( cr, dr, er, ar, br, F0, KK4, 1, 12);
+ R( bl, cl, dl, el, al, F4, K4, 12, 8 );
+ R( br, cr, dr, er, ar, F0, KK4, 5, 5);
+ R( al, bl, cl, dl, el, F4, K4, 2, 13 );
+ R( ar, br, cr, dr, er, F0, KK4, 8, 14);
+ R( el, al, bl, cl, dl, F4, K4, 10, 12 );
+ R( er, ar, br, cr, dr, F0, KK4, 7, 6);
+ R( dl, el, al, bl, cl, F4, K4, 14, 5 );
+ R( dr, er, ar, br, cr, F0, KK4, 6, 8);
+ R( cl, dl, el, al, bl, F4, K4, 1, 12 );
+ R( cr, dr, er, ar, br, F0, KK4, 2, 13);
+ R( bl, cl, dl, el, al, F4, K4, 3, 13 );
+ R( br, cr, dr, er, ar, F0, KK4, 13, 6);
+ R( al, bl, cl, dl, el, F4, K4, 8, 14 );
+ R( ar, br, cr, dr, er, F0, KK4, 14, 5);
+ R( el, al, bl, cl, dl, F4, K4, 11, 11 );
+ R( er, ar, br, cr, dr, F0, KK4, 0, 15);
+ R( dl, el, al, bl, cl, F4, K4, 6, 8 );
+ R( dr, er, ar, br, cr, F0, KK4, 3, 13);
+ R( cl, dl, el, al, bl, F4, K4, 15, 5 );
+ R( cr, dr, er, ar, br, F0, KK4, 9, 11);
+ R( bl, cl, dl, el, al, F4, K4, 13, 6 );
+ R( br, cr, dr, er, ar, F0, KK4, 11, 11);
+
+ dr += cl + hd->h1;
+ hd->h1 = hd->h2 + dl + er;
+ hd->h2 = hd->h3 + el + ar;
+ hd->h3 = hd->h4 + al + br;
+ hd->h4 = hd->h0 + bl + cr;
+ hd->h0 = dr;
+
+ return /*burn_stack*/ 104+5*sizeof(void*);
+}
+
+
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+ unsigned int burn;
+
+ do
+ {
+ burn = transform_blk (c, data);
+ data += 64;
+ }
+ while (--nblks);
+
+ return burn;
+}
+
+
+/*
+ * The routine terminates the computation
+ */
+static void
+rmd160_final( void *context )
+{
+ RMD160_CONTEXT *hd = context;
+ u32 t, th, msb, lsb;
+ byte *p;
+ unsigned int burn;
+
+ t = hd->bctx.nblocks;
+ if (sizeof t == sizeof hd->bctx.nblocks)
+ th = hd->bctx.nblocks_high;
+ else
+ th = hd->bctx.nblocks >> 32;
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = (th << 6) | (t >> 26);
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->bctx.count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->bctx.count < 56) /* enough room */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ if (hd->bctx.count < 56)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+
+ /* append the 64 bit count */
+ buf_put_le32(hd->bctx.buf + 56, lsb);
+ buf_put_le32(hd->bctx.buf + 60, msb);
+ burn = transform (hd, hd->bctx.buf, 1);
+ }
+ else /* need one extra block */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ /* fill pad and next block with zeroes */
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+
+ /* append the 64 bit count */
+ buf_put_le32(hd->bctx.buf + 64 + 56, lsb);
+ buf_put_le32(hd->bctx.buf + 64 + 60, msb);
+ burn = transform (hd, hd->bctx.buf, 2);
+ }
+
+ p = hd->bctx.buf;
+#define X(a) do { buf_put_le32(p, hd->h##a); p += 4; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+#undef X
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (burn);
+}
+
+static byte *
+rmd160_read( void *context )
+{
+ RMD160_CONTEXT *hd = context;
+
+ return hd->bctx.buf;
+}
+
+
+
+/****************
+ * Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 20 bytes.
+ */
+void
+_gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
+{
+ RMD160_CONTEXT hd;
+
+ rmd160_init (&hd, 0);
+ _gcry_md_block_write ( &hd, buffer, length );
+ rmd160_final ( &hd );
+ memcpy ( outbuf, hd.bctx.buf, 20 );
+}
+
+/* Variant of the above shortcut function using a multiple buffers. */
+static void
+_gcry_rmd160_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+ RMD160_CONTEXT hd;
+
+ rmd160_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ rmd160_final ( &hd );
+ memcpy ( outbuf, hd.bctx.buf, 20 );
+}
+
+
+static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
+ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
+ 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
+
+static gcry_md_oid_spec_t oid_spec_rmd160[] =
+ {
+ /* rsaSignatureWithripemd160 */
+ { "1.3.36.3.3.1.2" },
+ /* TeleTrust hash algorithm. */
+ { "1.3.36.3.2.1" },
+ { NULL }
+ };
+
+gcry_md_spec_t _gcry_digest_spec_rmd160 =
+ {
+ GCRY_MD_RMD160, {0, 0},
+ "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
+ rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read, NULL,
+ _gcry_rmd160_hash_buffer, _gcry_rmd160_hash_buffers,
+ sizeof (RMD160_CONTEXT)
+ };
diff --git a/comm/third_party/libgcrypt/cipher/rsa-common.c b/comm/third_party/libgcrypt/cipher/rsa-common.c
new file mode 100644
index 0000000000..29b7bc8148
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rsa-common.c
@@ -0,0 +1,1038 @@
+/* rsa-common.c - Supporting functions for RSA
+ * Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+/* Turn VALUE into an octet string and store it in an allocated buffer
+ at R_FRAME or - if R_RAME is NULL - copy it into the caller
+ provided buffer SPACE; either SPACE or R_FRAME may be used. If
+ SPACE if not NULL, the caller must provide a buffer of at least
+ NBYTES. If the resulting octet string is shorter than NBYTES pad
+ it to the left with zeroes. If VALUE does not fit into NBYTES
+ return an error code. */
+static gpg_err_code_t
+octet_string_from_mpi (unsigned char **r_frame, void *space,
+ gcry_mpi_t value, size_t nbytes)
+{
+ return _gcry_mpi_to_octet_string (r_frame, space, value, nbytes);
+}
+
+
+
+/* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
+ type 2 padding. On success the result is stored as a new MPI at
+ R_RESULT. On error the value at R_RESULT is undefined.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the seed instead of using a random string for it. This feature is
+ only useful for regression tests. Note that this value may not
+ contain zero bytes.
+
+ We encode the value in this way:
+
+ 0 2 RND(n bytes) 0 VALUE
+
+ 0 is a marker we unfortunately can't encode because we return an
+ MPI which strips all leading zeroes.
+ 2 is the block type.
+ RND are non-zero random bytes.
+
+ (Note that OpenPGP includes the cipher algorithm and a checksum in
+ VALUE; the caller needs to prepare the value accordingly.)
+ */
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_for_enc (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen,
+ const unsigned char *random_override,
+ size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ int i;
+ size_t n;
+ unsigned char *p;
+
+ if (valuelen + 7 > nframe || !nframe)
+ {
+ /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
+ return GPG_ERR_TOO_SHORT; /* The key is too short. */
+ }
+
+ if ( !(frame = xtrymalloc_secure (nframe)))
+ return gpg_err_code_from_syserror ();
+
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 2; /* block type */
+ i = nframe - 3 - valuelen;
+ gcry_assert (i > 0);
+
+ if (random_override)
+ {
+ int j;
+
+ if (random_override_len != i)
+ {
+ xfree (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ /* Check that random does not include a zero byte. */
+ for (j=0; j < random_override_len; j++)
+ if (!random_override[j])
+ {
+ xfree (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ memcpy (frame + n, random_override, random_override_len);
+ n += random_override_len;
+ }
+ else
+ {
+ p = _gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
+ /* Replace zero bytes by new values. */
+ for (;;)
+ {
+ int j, k;
+ unsigned char *pp;
+
+ /* Count the zero bytes. */
+ for (j=k=0; j < i; j++)
+ {
+ if (!p[j])
+ k++;
+ }
+ if (!k)
+ break; /* Okay: no (more) zero bytes. */
+
+ k += k/128 + 3; /* Better get some more. */
+ pp = _gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
+ for (j=0; j < i && k; )
+ {
+ if (!p[j])
+ p[j] = pp[--k];
+ if (p[j])
+ j++;
+ }
+ xfree (pp);
+ }
+ memcpy (frame+n, p, i);
+ n += i;
+ xfree (p);
+ }
+
+ frame[n++] = 0;
+ memcpy (frame+n, value, valuelen);
+ n += valuelen;
+ gcry_assert (n == nframe);
+
+ rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+ if (!rc &&DBG_CIPHER)
+ log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
+ xfree (frame);
+
+ return rc;
+}
+
+
+/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
+ NBITS is the size of the secret key. On success the result is
+ stored as a newly allocated buffer at R_RESULT and its valid length at
+ R_RESULTLEN. On error NULL is stored at R_RESULT. */
+gpg_err_code_t
+_gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen,
+ unsigned int nbits, gcry_mpi_t value)
+{
+ gcry_error_t err;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ size_t n;
+
+ *r_result = NULL;
+
+ if ( !(frame = xtrymalloc_secure (nframe)))
+ return gpg_err_code_from_syserror ();
+
+ err = _gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
+ if (err)
+ {
+ xfree (frame);
+ return gcry_err_code (err);
+ }
+
+ nframe = n; /* Set NFRAME to the actual length. */
+
+ /* FRAME = 0x00 || 0x02 || PS || 0x00 || M
+
+ pkcs#1 requires that the first byte is zero. Our MPIs usually
+ strip leading zero bytes; thus we are not able to detect them.
+ However due to the way gcry_mpi_print is implemented we may see
+ leading zero bytes nevertheless. We handle this by making the
+ first zero byte optional. */
+ if (nframe < 4)
+ {
+ xfree (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* Too short. */
+ }
+ n = 0;
+ if (!frame[0])
+ n++;
+ if (frame[n++] != 0x02)
+ {
+ xfree (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* Wrong block type. */
+ }
+
+ /* Skip the non-zero random bytes and the terminating zero byte. */
+ for (; n < nframe && frame[n] != 0x00; n++)
+ ;
+ if (n+1 >= nframe)
+ {
+ xfree (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* No zero byte. */
+ }
+ n++; /* Skip the zero byte. */
+
+ /* To avoid an extra allocation we reuse the frame buffer. The only
+ caller of this function will anyway free the result soon. */
+ memmove (frame, frame + n, nframe - n);
+ *r_result = frame;
+ *r_resultlen = nframe - n;
+
+ if (DBG_CIPHER)
+ log_printhex ("value extracted from PKCS#1 block type 2 encoded data",
+ *r_result, *r_resultlen);
+
+ return 0;
+}
+
+
+/* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorithm ALGO
+ using the pkcs#1 block type 1 padding. On success the result is
+ stored as a new MPI at R_RESULT. On error the value at R_RESULT is
+ undefined.
+
+ We encode the value in this way:
+
+ 0 1 PAD(n bytes) 0 ASN(asnlen bytes) VALUE(valuelen bytes)
+
+ 0 is a marker we unfortunately can't encode because we return an
+ MPI which strips all leading zeroes.
+ 1 is the block type.
+ PAD consists of 0xff bytes.
+ 0 marks the end of the padding.
+ ASN is the DER encoding of the hash algorithm; along with the VALUE
+ it yields a valid DER encoding.
+
+ (Note that PGP prior to version 2.3 encoded the message digest as:
+ 0 1 MD(16 bytes) 0 PAD(n bytes) 1
+ The MD is always 16 bytes here because it's always MD5. GnuPG
+ does not not support pre-v2.3 signatures, but I'm including this
+ comment so the information is easily found if needed.)
+*/
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen,
+ int algo)
+{
+ gcry_err_code_t rc = 0;
+ byte asn[100];
+ byte *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ int i;
+ size_t n;
+ size_t asnlen, dlen;
+
+ asnlen = DIM(asn);
+ dlen = _gcry_md_get_algo_dlen (algo);
+
+ if (_gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
+ {
+ /* We don't have yet all of the above algorithms. */
+ return GPG_ERR_NOT_IMPLEMENTED;
+ }
+
+ if ( valuelen != dlen )
+ {
+ /* Hash value does not match the length of digest for
+ the given algorithm. */
+ return GPG_ERR_CONFLICT;
+ }
+
+ if ( !dlen || dlen + asnlen + 4 > nframe)
+ {
+ /* Can't encode an DLEN byte digest MD into an NFRAME byte
+ frame. */
+ return GPG_ERR_TOO_SHORT;
+ }
+
+ if ( !(frame = xtrymalloc (nframe)) )
+ return gpg_err_code_from_syserror ();
+
+ /* Assemble the pkcs#1 block type 1. */
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 1; /* block type */
+ i = nframe - valuelen - asnlen - 3 ;
+ gcry_assert (i > 1);
+ memset (frame+n, 0xff, i );
+ n += i;
+ frame[n++] = 0;
+ memcpy (frame+n, asn, asnlen);
+ n += asnlen;
+ memcpy (frame+n, value, valuelen );
+ n += valuelen;
+ gcry_assert (n == nframe);
+
+ /* Convert it into an MPI. */
+ rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+ if (!rc && DBG_CIPHER)
+ log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
+ xfree (frame);
+
+ return rc;
+}
+
+/* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
+ type 1 padding. On success the result is stored as a new MPI at
+ R_RESULT. On error the value at R_RESULT is undefined.
+
+ We encode the value in this way:
+
+ 0 1 PAD(n bytes) 0 VALUE(valuelen bytes)
+
+ 0 is a marker we unfortunately can't encode because we return an
+ MPI which strips all leading zeroes.
+ 1 is the block type.
+ PAD consists of 0xff bytes.
+ 0 marks the end of the padding.
+
+ (Note that PGP prior to version 2.3 encoded the message digest as:
+ 0 1 MD(16 bytes) 0 PAD(n bytes) 1
+ The MD is always 16 bytes here because it's always MD5. GnuPG
+ does not not support pre-v2.3 signatures, but I'm including this
+ comment so the information is easily found if needed.)
+*/
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ byte *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ int i;
+ size_t n;
+
+ if ( !valuelen || valuelen + 4 > nframe)
+ {
+ /* Can't encode an DLEN byte digest MD into an NFRAME byte
+ frame. */
+ return GPG_ERR_TOO_SHORT;
+ }
+
+ if ( !(frame = xtrymalloc (nframe)) )
+ return gpg_err_code_from_syserror ();
+
+ /* Assemble the pkcs#1 block type 1. */
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 1; /* block type */
+ i = nframe - valuelen - 3 ;
+ gcry_assert (i > 1);
+ memset (frame+n, 0xff, i );
+ n += i;
+ frame[n++] = 0;
+ memcpy (frame+n, value, valuelen );
+ n += valuelen;
+ gcry_assert (n == nframe);
+
+ /* Convert it into an MPI. */
+ err = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
+ xfree (frame);
+
+ return rc;
+}
+
+
+/* Mask generation function for OAEP. See RFC-3447 B.2.1. */
+static gcry_err_code_t
+mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
+ int algo)
+{
+ size_t dlen, nbytes, n;
+ int idx;
+ gcry_md_hd_t hd;
+ gcry_err_code_t err;
+
+ err = _gcry_md_open (&hd, algo, 0);
+ if (err)
+ return err;
+
+ dlen = _gcry_md_get_algo_dlen (algo);
+
+ /* We skip step 1 which would be assert(OUTLEN <= 2^32). The loop
+ in step 3 is merged with step 4 by concatenating no more octets
+ than what would fit into OUTPUT. The ceiling for the counter IDX
+ is implemented indirectly. */
+ nbytes = 0; /* Step 2. */
+ idx = 0;
+ while ( nbytes < outlen )
+ {
+ unsigned char c[4], *digest;
+
+ if (idx)
+ _gcry_md_reset (hd);
+
+ c[0] = (idx >> 24) & 0xFF;
+ c[1] = (idx >> 16) & 0xFF;
+ c[2] = (idx >> 8) & 0xFF;
+ c[3] = idx & 0xFF;
+ idx++;
+
+ _gcry_md_write (hd, seed, seedlen);
+ _gcry_md_write (hd, c, 4);
+ digest = _gcry_md_read (hd, 0);
+
+ n = (outlen - nbytes < dlen)? (outlen - nbytes) : dlen;
+ memcpy (output+nbytes, digest, n);
+ nbytes += n;
+ }
+
+ _gcry_md_close (hd);
+ return GPG_ERR_NO_ERROR;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) OAEP encoding. NBITS is the length of the
+ key measured in bits. ALGO is the hash function; it must be a
+ valid and usable algorithm. {VALUE,VALUELEN} is the message to
+ encrypt. {LABEL,LABELLEN} is the optional label to be associated
+ with the message, if LABEL is NULL the default is to use the empty
+ string as label. On success the encoded ciphertext is returned at
+ R_RESULT.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the seed instead of using a random string for it. This feature is
+ only useful for regression tests.
+
+ Here is figure 1 from the RFC depicting the process:
+
+ +----------+---------+-------+
+ DB = | lHash | PS | M |
+ +----------+---------+-------+
+ |
+ +----------+ V
+ | seed |--> MGF ---> xor
+ +----------+ |
+ | |
+ +--+ V |
+ |00| xor <----- MGF <-----|
+ +--+ | |
+ | | |
+ V V V
+ +--+----------+----------------------------+
+ EM = |00|maskedSeed| maskedDB |
+ +--+----------+----------------------------+
+ */
+gpg_err_code_t
+_gcry_rsa_oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+ const unsigned char *value, size_t valuelen,
+ const unsigned char *label, size_t labellen,
+ const void *random_override, size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ unsigned char *p;
+ size_t hlen;
+ size_t n;
+
+ *r_result = NULL;
+
+ /* Set defaults for LABEL. */
+ if (!label || !labellen)
+ {
+ label = (const unsigned char*)"";
+ labellen = 0;
+ }
+
+ hlen = _gcry_md_get_algo_dlen (algo);
+
+ /* We skip step 1a which would be to check that LABELLEN is not
+ greater than 2^61-1. See rfc-3447 7.1.1. */
+
+ /* Step 1b. Note that the obsolete rfc-2437 uses the check:
+ valuelen > nframe - 2 * hlen - 1 . */
+ if (valuelen > nframe - 2 * hlen - 2 || !nframe)
+ {
+ /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
+ return GPG_ERR_TOO_SHORT; /* The key is too short. */
+ }
+
+ /* Allocate the frame. */
+ frame = xtrycalloc_secure (1, nframe);
+ if (!frame)
+ return gpg_err_code_from_syserror ();
+
+ /* Step 2a: Compute the hash of the label. We store it in the frame
+ where later the maskedDB will commence. */
+ _gcry_md_hash_buffer (algo, frame + 1 + hlen, label, labellen);
+
+ /* Step 2b: Set octet string to zero. */
+ /* This has already been done while allocating FRAME. */
+
+ /* Step 2c: Create DB by concatenating lHash, PS, 0x01 and M. */
+ n = nframe - valuelen - 1;
+ frame[n] = 0x01;
+ memcpy (frame + n + 1, value, valuelen);
+
+ /* Step 3d: Generate seed. We store it where the maskedSeed will go
+ later. */
+ if (random_override)
+ {
+ if (random_override_len != hlen)
+ {
+ xfree (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ memcpy (frame + 1, random_override, hlen);
+ }
+ else
+ _gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
+
+ /* Step 2e and 2f: Create maskedDB. */
+ {
+ unsigned char *dmask;
+
+ dmask = xtrymalloc_secure (nframe - hlen - 1);
+ if (!dmask)
+ {
+ rc = gpg_err_code_from_syserror ();
+ xfree (frame);
+ return rc;
+ }
+ rc = mgf1 (dmask, nframe - hlen - 1, frame+1, hlen, algo);
+ if (rc)
+ {
+ xfree (dmask);
+ xfree (frame);
+ return rc;
+ }
+ for (n = 1 + hlen, p = dmask; n < nframe; n++)
+ frame[n] ^= *p++;
+ xfree (dmask);
+ }
+
+ /* Step 2g and 2h: Create maskedSeed. */
+ {
+ unsigned char *smask;
+
+ smask = xtrymalloc_secure (hlen);
+ if (!smask)
+ {
+ rc = gpg_err_code_from_syserror ();
+ xfree (frame);
+ return rc;
+ }
+ rc = mgf1 (smask, hlen, frame + 1 + hlen, nframe - hlen - 1, algo);
+ if (rc)
+ {
+ xfree (smask);
+ xfree (frame);
+ return rc;
+ }
+ for (n = 1, p = smask; n < 1 + hlen; n++)
+ frame[n] ^= *p++;
+ xfree (smask);
+ }
+
+ /* Step 2i: Concatenate 0x00, maskedSeed and maskedDB. */
+ /* This has already been done by using in-place operations. */
+
+ /* Convert the stuff into an MPI as expected by the caller. */
+ rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL);
+ if (!rc && DBG_CIPHER)
+ log_mpidump ("OAEP encoded data", *r_result);
+ xfree (frame);
+
+ return rc;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) OAEP decoding. NBITS is the length of the
+ key measured in bits. ALGO is the hash function; it must be a
+ valid and usable algorithm. VALUE is the raw decrypted message
+ {LABEL,LABELLEN} is the optional label to be associated with the
+ message, if LABEL is NULL the default is to use the empty string as
+ label. On success the plaintext is returned as a newly allocated
+ buffer at R_RESULT; its valid length is stored at R_RESULTLEN. On
+ error NULL is stored at R_RESULT. */
+gpg_err_code_t
+_gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen,
+ unsigned int nbits, int algo,
+ gcry_mpi_t value,
+ const unsigned char *label, size_t labellen)
+{
+ gcry_err_code_t rc;
+ unsigned char *frame = NULL; /* Encoded messages (EM). */
+ unsigned char *masked_seed; /* Points into FRAME. */
+ unsigned char *masked_db; /* Points into FRAME. */
+ unsigned char *seed = NULL; /* Allocated space for the seed and DB. */
+ unsigned char *db; /* Points into SEED. */
+ unsigned char *lhash = NULL; /* Hash of the label. */
+ size_t nframe; /* Length of the ciphertext (EM). */
+ size_t hlen; /* Length of the hash digest. */
+ size_t db_len; /* Length of DB and masked_db. */
+ size_t nkey = (nbits+7)/8; /* Length of the key in bytes. */
+ int failed = 0; /* Error indicator. */
+ size_t n;
+
+ *r_result = NULL;
+
+ /* This code is implemented as described by rfc-3447 7.1.2. */
+
+ /* Set defaults for LABEL. */
+ if (!label || !labellen)
+ {
+ label = (const unsigned char*)"";
+ labellen = 0;
+ }
+
+ /* Get the length of the digest. */
+ hlen = _gcry_md_get_algo_dlen (algo);
+
+ /* Hash the label right away. */
+ lhash = xtrymalloc (hlen);
+ if (!lhash)
+ return gpg_err_code_from_syserror ();
+ _gcry_md_hash_buffer (algo, lhash, label, labellen);
+
+ /* Turn the MPI into an octet string. If the octet string is
+ shorter than the key we pad it to the left with zeroes. This may
+ happen due to the leading zero in OAEP frames and due to the
+ following random octets (seed^mask) which may have leading zero
+ bytes. This all is needed to cope with our leading zeroes
+ suppressing MPI implementation. The code implictly implements
+ Step 1b (bail out if NFRAME != N). */
+ rc = octet_string_from_mpi (&frame, NULL, value, nkey);
+ if (rc)
+ {
+ xfree (lhash);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+ nframe = nkey;
+
+ /* Step 1c: Check that the key is long enough. */
+ if ( nframe < 2 * hlen + 2 )
+ {
+ xfree (frame);
+ xfree (lhash);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+
+ /* Step 2 has already been done by the caller and the
+ gcry_mpi_aprint above. */
+
+ /* Allocate space for SEED and DB. */
+ seed = xtrymalloc_secure (nframe - 1);
+ if (!seed)
+ {
+ rc = gpg_err_code_from_syserror ();
+ xfree (frame);
+ xfree (lhash);
+ return rc;
+ }
+ db = seed + hlen;
+
+ /* To avoid chosen ciphertext attacks from now on we make sure to
+ run all code even in the error case; this avoids possible timing
+ attacks as described by Manger. */
+
+ /* Step 3a: Hash the label. */
+ /* This has already been done. */
+
+ /* Step 3b: Separate the encoded message. */
+ masked_seed = frame + 1;
+ masked_db = frame + 1 + hlen;
+ db_len = nframe - 1 - hlen;
+
+ /* Step 3c and 3d: seed = maskedSeed ^ mgf(maskedDB, hlen). */
+ if (mgf1 (seed, hlen, masked_db, db_len, algo))
+ failed = 1;
+ for (n = 0; n < hlen; n++)
+ seed[n] ^= masked_seed[n];
+
+ /* Step 3e and 3f: db = maskedDB ^ mgf(seed, db_len). */
+ if (mgf1 (db, db_len, seed, hlen, algo))
+ failed = 1;
+ for (n = 0; n < db_len; n++)
+ db[n] ^= masked_db[n];
+
+ /* Step 3g: Check lhash, an possible empty padding string terminated
+ by 0x01 and the first byte of EM being 0. */
+ if (memcmp (lhash, db, hlen))
+ failed = 1;
+ for (n = hlen; n < db_len; n++)
+ if (db[n] == 0x01)
+ break;
+ if (n == db_len)
+ failed = 1;
+ if (frame[0])
+ failed = 1;
+
+ xfree (lhash);
+ xfree (frame);
+ if (failed)
+ {
+ xfree (seed);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+
+ /* Step 4: Output M. */
+ /* To avoid an extra allocation we reuse the seed buffer. The only
+ caller of this function will anyway free the result soon. */
+ n++;
+ memmove (seed, db + n, db_len - n);
+ *r_result = seed;
+ *r_resultlen = db_len - n;
+ seed = NULL;
+
+ if (DBG_CIPHER)
+ log_printhex ("value extracted from OAEP encoded data",
+ *r_result, *r_resultlen);
+
+ return 0;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) PSS encoding. Encode {VALUE,VALUELEN} for
+ an NBITS key. Note that VALUE is already the mHash from the
+ picture below. ALGO is a valid hash algorithm and SALTLEN is the
+ length of salt to be used. On success the result is stored as a
+ new MPI at R_RESULT. On error the value at R_RESULT is undefined.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the salt instead of using a random string for the salt. This
+ feature is only useful for regression tests.
+
+ Here is figure 2 from the RFC (errata 595 applied) depicting the
+ process:
+
+ +-----------+
+ | M |
+ +-----------+
+ |
+ V
+ Hash
+ |
+ V
+ +--------+----------+----------+
+ M' = |Padding1| mHash | salt |
+ +--------+----------+----------+
+ |
+ +--------+----------+ V
+ DB = |Padding2| salt | Hash
+ +--------+----------+ |
+ | |
+ V | +----+
+ xor <--- MGF <---| |0xbc|
+ | | +----+
+ | | |
+ V V V
+ +-------------------+----------+----+
+ EM = | maskedDB | H |0xbc|
+ +-------------------+----------+----+
+
+ */
+gpg_err_code_t
+_gcry_rsa_pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+ const unsigned char *value, size_t valuelen, int saltlen,
+ const void *random_override, size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ size_t hlen; /* Length of the hash digest. */
+ unsigned char *em = NULL; /* Encoded message. */
+ size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */
+ unsigned char *h; /* Points into EM. */
+ unsigned char *buf = NULL; /* Help buffer. */
+ size_t buflen; /* Length of BUF. */
+ unsigned char *mhash; /* Points into BUF. */
+ unsigned char *salt; /* Points into BUF. */
+ unsigned char *dbmask; /* Points into BUF. */
+ unsigned char *p;
+ size_t n;
+
+ /* This code is implemented as described by rfc-3447 9.1.1. */
+
+ /* Get the length of the digest. */
+ hlen = _gcry_md_get_algo_dlen (algo);
+ gcry_assert (hlen); /* We expect a valid ALGO here. */
+
+ /* Allocate a help buffer and setup some pointers. */
+ buflen = 8 + hlen + saltlen + (emlen - hlen - 1);
+ buf = xtrymalloc (buflen);
+ if (!buf)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ mhash = buf + 8;
+ salt = mhash + hlen;
+ dbmask= salt + saltlen;
+
+ /* Step 2: That would be: mHash = Hash(M) but our input is already
+ mHash thus we do only a consistency check and copy to MHASH. */
+ if (valuelen != hlen)
+ {
+ rc = GPG_ERR_INV_LENGTH;
+ goto leave;
+ }
+ memcpy (mhash, value, hlen);
+
+ /* Step 3: Check length constraints. */
+ if (emlen < hlen + saltlen + 2)
+ {
+ rc = GPG_ERR_TOO_SHORT;
+ goto leave;
+ }
+
+ /* Allocate space for EM. */
+ em = xtrymalloc (emlen);
+ if (!em)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ h = em + emlen - 1 - hlen;
+
+ /* Step 4: Create a salt. */
+ if (saltlen)
+ {
+ if (random_override)
+ {
+ if (random_override_len != saltlen)
+ {
+ rc = GPG_ERR_INV_ARG;
+ goto leave;
+ }
+ memcpy (salt, random_override, saltlen);
+ }
+ else
+ _gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
+ }
+
+ /* Step 5 and 6: M' = Hash(Padding1 || mHash || salt). */
+ memset (buf, 0, 8); /* Padding. */
+ _gcry_md_hash_buffer (algo, h, buf, 8 + hlen + saltlen);
+
+ /* Step 7 and 8: DB = PS || 0x01 || salt. */
+ /* Note that we use EM to store DB and later Xor in-place. */
+ p = em + emlen - 1 - hlen - saltlen - 1;
+ memset (em, 0, p - em);
+ *p++ = 0x01;
+ memcpy (p, salt, saltlen);
+
+ /* Step 9: dbmask = MGF(H, emlen - hlen - 1). */
+ mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
+
+ /* Step 10: maskedDB = DB ^ dbMask */
+ for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
+ em[n] ^= *p;
+
+ /* Step 11: Set the leftmost bits to zero. */
+ em[0] &= 0xFF >> (8 * emlen - nbits);
+
+ /* Step 12: EM = maskedDB || H || 0xbc. */
+ em[emlen-1] = 0xbc;
+
+ /* Convert EM into an MPI. */
+ rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, em, emlen, NULL);
+ if (!rc && DBG_CIPHER)
+ log_mpidump ("PSS encoded data", *r_result);
+
+ leave:
+ if (em)
+ {
+ wipememory (em, emlen);
+ xfree (em);
+ }
+ if (buf)
+ {
+ wipememory (buf, buflen);
+ xfree (buf);
+ }
+ return rc;
+}
+
+
+/* Verify a signature assuming PSS padding. VALUE is the hash of the
+ message (mHash) encoded as an MPI; its length must match the digest
+ length of ALGO. ENCODED is the output of the RSA public key
+ function (EM). NBITS is the size of the public key. ALGO is the
+ hash algorithm and SALTLEN is the length of the used salt. The
+ function returns 0 on success or on error code. */
+gpg_err_code_t
+_gcry_rsa_pss_verify (gcry_mpi_t value, gcry_mpi_t encoded,
+ unsigned int nbits, int algo, size_t saltlen)
+{
+ gcry_err_code_t rc = 0;
+ size_t hlen; /* Length of the hash digest. */
+ unsigned char *em = NULL; /* Encoded message. */
+ size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */
+ unsigned char *salt; /* Points into EM. */
+ unsigned char *h; /* Points into EM. */
+ unsigned char *buf = NULL; /* Help buffer. */
+ size_t buflen; /* Length of BUF. */
+ unsigned char *dbmask; /* Points into BUF. */
+ unsigned char *mhash; /* Points into BUF. */
+ unsigned char *p;
+ size_t n;
+
+ /* This code is implemented as described by rfc-3447 9.1.2. */
+
+ /* Get the length of the digest. */
+ hlen = _gcry_md_get_algo_dlen (algo);
+ gcry_assert (hlen); /* We expect a valid ALGO here. */
+
+ /* Allocate a help buffer and setup some pointers.
+ This buffer is used for two purposes:
+ +------------------------------+-------+
+ 1. | dbmask | mHash |
+ +------------------------------+-------+
+ emlen - hlen - 1 hlen
+
+ +----------+-------+---------+-+-------+
+ 2. | padding1 | mHash | salt | | mHash |
+ +----------+-------+---------+-+-------+
+ 8 hlen saltlen hlen
+ */
+ buflen = 8 + hlen + saltlen;
+ if (buflen < emlen - hlen - 1)
+ buflen = emlen - hlen - 1;
+ buflen += hlen;
+ buf = xtrymalloc (buflen);
+ if (!buf)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ dbmask = buf;
+ mhash = buf + buflen - hlen;
+
+ /* Step 2: That would be: mHash = Hash(M) but our input is already
+ mHash thus we only need to convert VALUE into MHASH. */
+ rc = octet_string_from_mpi (NULL, mhash, value, hlen);
+ if (rc)
+ goto leave;
+
+ /* Convert the signature into an octet string. */
+ rc = octet_string_from_mpi (&em, NULL, encoded, emlen);
+ if (rc)
+ goto leave;
+
+ /* Step 3: Check length of EM. Because we internally use MPI
+ functions we can't do this properly; EMLEN is always the length
+ of the key because octet_string_from_mpi needs to left pad the
+ result with zero to cope with the fact that our MPIs suppress all
+ leading zeroes. Thus what we test here are merely the digest and
+ salt lengths to the key. */
+ if (emlen < hlen + saltlen + 2)
+ {
+ rc = GPG_ERR_TOO_SHORT; /* For the hash and saltlen. */
+ goto leave;
+ }
+
+ /* Step 4: Check last octet. */
+ if (em[emlen - 1] != 0xbc)
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 5: Split EM. */
+ h = em + emlen - 1 - hlen;
+
+ /* Step 6: Check the leftmost bits. */
+ if ((em[0] & ~(0xFF >> (8 * emlen - nbits))))
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 7: dbmask = MGF(H, emlen - hlen - 1). */
+ mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
+
+ /* Step 8: maskedDB = DB ^ dbMask. */
+ for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
+ em[n] ^= *p;
+
+ /* Step 9: Set leftmost bits in DB to zero. */
+ em[0] &= 0xFF >> (8 * emlen - nbits);
+
+ /* Step 10: Check the padding of DB. */
+ for (n = 0; n < emlen - hlen - saltlen - 2 && !em[n]; n++)
+ ;
+ if (n != emlen - hlen - saltlen - 2 || em[n++] != 1)
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 11: Extract salt from DB. */
+ salt = em + n;
+
+ /* Step 12: M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
+ memset (buf, 0, 8);
+ memcpy (buf+8, mhash, hlen);
+ memcpy (buf+8+hlen, salt, saltlen);
+
+ /* Step 13: H' = Hash(M'). */
+ _gcry_md_hash_buffer (algo, buf, buf, 8 + hlen + saltlen);
+
+ /* Step 14: Check H == H'. */
+ rc = memcmp (h, buf, hlen) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
+
+ leave:
+ if (em)
+ {
+ wipememory (em, emlen);
+ xfree (em);
+ }
+ if (buf)
+ {
+ wipememory (buf, buflen);
+ xfree (buf);
+ }
+ return rc;
+}
diff --git a/comm/third_party/libgcrypt/cipher/rsa.c b/comm/third_party/libgcrypt/cipher/rsa.c
new file mode 100644
index 0000000000..575ea94924
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/rsa.c
@@ -0,0 +1,2035 @@
+/* rsa.c - RSA implementation
+ * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
+ * Copyright (C) 2000, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This code uses an algorithm protected by U.S. Patent #4,405,829
+ which expired on September 20, 2000. The patent holder placed that
+ patent into the public domain on Sep 6th, 2000.
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+typedef struct
+{
+ gcry_mpi_t n; /* modulus */
+ gcry_mpi_t e; /* exponent */
+} RSA_public_key;
+
+
+typedef struct
+{
+ gcry_mpi_t n; /* public modulus */
+ gcry_mpi_t e; /* public exponent */
+ gcry_mpi_t d; /* exponent */
+ gcry_mpi_t p; /* prime p. */
+ gcry_mpi_t q; /* prime q. */
+ gcry_mpi_t u; /* inverse of p mod q. */
+} RSA_secret_key;
+
+
+static const char *rsa_names[] =
+ {
+ "rsa",
+ "openpgp-rsa",
+ "oid.1.2.840.113549.1.1.1",
+ NULL,
+ };
+
+
+/* A sample 2048 bit RSA key used for the selftests. */
+static const char sample_secret_key[] =
+" (private-key"
+" (rsa"
+" (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC"
+" 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8"
+" 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C"
+" 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917"
+" DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613"
+" 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C"
+" 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918"
+" 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6CB#)"
+" (e #010001#)"
+" (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19"
+" 8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93"
+" 7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12"
+" 771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F"
+" 5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48"
+" EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD"
+" 69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84"
+" 3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401#)"
+" (p #00C29D438F115825779631CD665A5739367F3E128ADC29766483A46CA80897E0"
+" 79B32881860B8F9A6A04C2614A904F6F2578DAE13EA67CD60AE3D0AA00A1FF9B"
+" 441485E44B2DC3D0B60260FBFE073B5AC72FAF67964DE15C8212C389D20DB9CF"
+" 54AF6AEF5C4196EAA56495DD30CF709F499D5AB30CA35E086C2A1589D6283F1783#)"
+" (q #00D1984135231CB243FE959C0CBEF551EDD986AD7BEDF71EDF447BE3DA27AF46"
+" 79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77"
+" 88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E"
+" 8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B919#)"
+" (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04"
+" 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4"
+" A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9"
+" AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7#)))";
+
+/* A sample 2048 bit RSA key used for the selftests (public only). */
+static const char sample_public_key[] =
+" (public-key"
+" (rsa"
+" (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC"
+" 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8"
+" 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C"
+" 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917"
+" DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613"
+" 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C"
+" 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918"
+" 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6CB#)"
+" (e #010001#)))";
+
+
+static int test_keys (RSA_secret_key *sk, unsigned nbits);
+static int check_secret_key (RSA_secret_key *sk);
+static void public (gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *skey);
+static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey);
+static unsigned int rsa_get_nbits (gcry_sexp_t parms);
+
+
+/* Check that a freshly generated key actually works. Returns 0 on success. */
+static int
+test_keys (RSA_secret_key *sk, unsigned int nbits)
+{
+ int result = -1; /* Default to failure. */
+ RSA_public_key pk;
+ gcry_mpi_t plaintext = mpi_new (nbits);
+ gcry_mpi_t ciphertext = mpi_new (nbits);
+ gcry_mpi_t decr_plaintext = mpi_new (nbits);
+ gcry_mpi_t signature = mpi_new (nbits);
+
+ /* Put the relevant parameters into a public key structure. */
+ pk.n = sk->n;
+ pk.e = sk->e;
+
+ /* Create a random plaintext. */
+ _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+ /* Encrypt using the public key. */
+ public (ciphertext, plaintext, &pk);
+
+ /* Check that the cipher text does not match the plaintext. */
+ if (!mpi_cmp (ciphertext, plaintext))
+ goto leave; /* Ciphertext is identical to the plaintext. */
+
+ /* Decrypt using the secret key. */
+ secret (decr_plaintext, ciphertext, sk);
+
+ /* Check that the decrypted plaintext matches the original plaintext. */
+ if (mpi_cmp (decr_plaintext, plaintext))
+ goto leave; /* Plaintext does not match. */
+
+ /* Create another random plaintext as data for signature checking. */
+ _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+ /* Use the RSA secret function to create a signature of the plaintext. */
+ secret (signature, plaintext, sk);
+
+ /* Use the RSA public function to verify this signature. */
+ public (decr_plaintext, signature, &pk);
+ if (mpi_cmp (decr_plaintext, plaintext))
+ goto leave; /* Signature does not match. */
+
+ /* Modify the signature and check that the signing fails. */
+ mpi_add_ui (signature, signature, 1);
+ public (decr_plaintext, signature, &pk);
+ if (!mpi_cmp (decr_plaintext, plaintext))
+ goto leave; /* Signature matches but should not. */
+
+ result = 0; /* All tests succeeded. */
+
+ leave:
+ _gcry_mpi_release (signature);
+ _gcry_mpi_release (decr_plaintext);
+ _gcry_mpi_release (ciphertext);
+ _gcry_mpi_release (plaintext);
+ return result;
+}
+
+
+/* Callback used by the prime generation to test whether the exponent
+ is suitable. Returns 0 if the test has been passed. */
+static int
+check_exponent (void *arg, gcry_mpi_t a)
+{
+ gcry_mpi_t e = arg;
+ gcry_mpi_t tmp;
+ int result;
+
+ mpi_sub_ui (a, a, 1);
+ tmp = _gcry_mpi_alloc_like (a);
+ result = !mpi_gcd(tmp, e, a); /* GCD is not 1. */
+ _gcry_mpi_release (tmp);
+ mpi_add_ui (a, a, 1);
+ return result;
+}
+
+/****************
+ * Generate a key pair with a key of size NBITS.
+ * USE_E = 0 let Libcgrypt decide what exponent to use.
+ * = 1 request the use of a "secure" exponent; this is required by some
+ * specification to be 65537.
+ * > 2 Use this public exponent. If the given exponent
+ * is not odd one is internally added to it.
+ * TRANSIENT_KEY: If true, generate the primes using the standard RNG.
+ * Returns: 2 structures filled with all needed values
+ */
+static gpg_err_code_t
+generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
+ int transient_key)
+{
+ gcry_mpi_t p, q; /* the two primes */
+ gcry_mpi_t d; /* the private key */
+ gcry_mpi_t u;
+ gcry_mpi_t t1, t2;
+ gcry_mpi_t n; /* the public key */
+ gcry_mpi_t e; /* the exponent */
+ gcry_mpi_t phi; /* helper: (p-1)(q-1) */
+ gcry_mpi_t g;
+ gcry_mpi_t f;
+ gcry_random_level_t random_level;
+
+ if (fips_mode ())
+ {
+ if (nbits < 1024)
+ return GPG_ERR_INV_VALUE;
+ if (transient_key)
+ return GPG_ERR_INV_VALUE;
+ }
+
+ /* The random quality depends on the transient_key flag. */
+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+
+ /* Make sure that nbits is even so that we generate p, q of equal size. */
+ if ( (nbits&1) )
+ nbits++;
+
+ if (use_e == 1) /* Alias for a secure value */
+ use_e = 65537; /* as demanded by Sphinx. */
+
+ /* Public exponent:
+ In general we use 41 as this is quite fast and more secure than the
+ commonly used 17. Benchmarking the RSA verify function
+ with a 1024 bit key yields (2001-11-08):
+ e=17 0.54 ms
+ e=41 0.75 ms
+ e=257 0.95 ms
+ e=65537 1.80 ms
+ */
+ e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
+ if (!use_e)
+ mpi_set_ui (e, 41); /* This is a reasonable secure and fast value */
+ else
+ {
+ use_e |= 1; /* make sure this is odd */
+ mpi_set_ui (e, use_e);
+ }
+
+ n = mpi_new (nbits);
+
+ p = q = NULL;
+ do
+ {
+ /* select two (very secret) primes */
+ if (p)
+ _gcry_mpi_release (p);
+ if (q)
+ _gcry_mpi_release (q);
+ if (use_e)
+ { /* Do an extra test to ensure that the given exponent is
+ suitable. */
+ p = _gcry_generate_secret_prime (nbits/2, random_level,
+ check_exponent, e);
+ q = _gcry_generate_secret_prime (nbits/2, random_level,
+ check_exponent, e);
+ }
+ else
+ { /* We check the exponent later. */
+ p = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
+ q = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
+ }
+ if (mpi_cmp (p, q) > 0 ) /* p shall be smaller than q (for calc of u)*/
+ mpi_swap(p,q);
+ /* calculate the modulus */
+ mpi_mul( n, p, q );
+ }
+ while ( mpi_get_nbits(n) != nbits );
+
+ /* calculate Euler totient: phi = (p-1)(q-1) */
+ t1 = mpi_alloc_secure( mpi_get_nlimbs(p) );
+ t2 = mpi_alloc_secure( mpi_get_nlimbs(p) );
+ phi = mpi_snew ( nbits );
+ g = mpi_snew ( nbits );
+ f = mpi_snew ( nbits );
+ mpi_sub_ui( t1, p, 1 );
+ mpi_sub_ui( t2, q, 1 );
+ mpi_mul( phi, t1, t2 );
+ mpi_gcd (g, t1, t2);
+ mpi_fdiv_q(f, phi, g);
+
+ while (!mpi_gcd(t1, e, phi)) /* (while gcd is not 1) */
+ {
+ if (use_e)
+ BUG (); /* The prime generator already made sure that we
+ never can get to here. */
+ mpi_add_ui (e, e, 2);
+ }
+
+ /* calculate the secret key d = e^-1 mod phi */
+ d = mpi_snew ( nbits );
+ mpi_invm (d, e, f );
+ /* calculate the inverse of p and q (used for chinese remainder theorem)*/
+ u = mpi_snew ( nbits );
+ mpi_invm(u, p, q );
+
+ if( DBG_CIPHER )
+ {
+ log_mpidump(" p= ", p );
+ log_mpidump(" q= ", q );
+ log_mpidump("phi= ", phi );
+ log_mpidump(" g= ", g );
+ log_mpidump(" f= ", f );
+ log_mpidump(" n= ", n );
+ log_mpidump(" e= ", e );
+ log_mpidump(" d= ", d );
+ log_mpidump(" u= ", u );
+ }
+
+ _gcry_mpi_release (t1);
+ _gcry_mpi_release (t2);
+ _gcry_mpi_release (phi);
+ _gcry_mpi_release (f);
+ _gcry_mpi_release (g);
+
+ sk->n = n;
+ sk->e = e;
+ sk->p = p;
+ sk->q = q;
+ sk->d = d;
+ sk->u = u;
+
+ /* Now we can test our keys. */
+ if (test_keys (sk, nbits - 64))
+ {
+ _gcry_mpi_release (sk->n); sk->n = NULL;
+ _gcry_mpi_release (sk->e); sk->e = NULL;
+ _gcry_mpi_release (sk->p); sk->p = NULL;
+ _gcry_mpi_release (sk->q); sk->q = NULL;
+ _gcry_mpi_release (sk->d); sk->d = NULL;
+ _gcry_mpi_release (sk->u); sk->u = NULL;
+ fips_signal_error ("self-test after key generation failed");
+ return GPG_ERR_SELFTEST_FAILED;
+ }
+
+ return 0;
+}
+
+
+/****************
+ * Generate a key pair with a key of size NBITS.
+ * USE_E = 0 let Libcgrypt decide what exponent to use.
+ * = 1 request the use of a "secure" exponent; this is required by some
+ * specification to be 65537.
+ * > 2 Use this public exponent. If the given exponent
+ * is not odd one is internally added to it.
+ * TESTPARMS: If set, do not generate but test whether the p,q is probably prime
+ * Returns key with zeroes to not break code calling this function.
+ * TRANSIENT_KEY: If true, generate the primes using the standard RNG.
+ * Returns: 2 structures filled with all needed values
+ */
+static gpg_err_code_t
+generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
+ gcry_sexp_t testparms, int transient_key)
+{
+ gcry_mpi_t p, q; /* the two primes */
+ gcry_mpi_t d; /* the private key */
+ gcry_mpi_t u;
+ gcry_mpi_t p1, q1;
+ gcry_mpi_t n; /* the public key */
+ gcry_mpi_t e; /* the exponent */
+ gcry_mpi_t g;
+ gcry_mpi_t minp;
+ gcry_mpi_t diff, mindiff;
+ gcry_random_level_t random_level;
+ unsigned int pbits = nbits/2;
+ unsigned int i;
+ int pqswitch;
+ gpg_err_code_t ec = GPG_ERR_NO_PRIME;
+
+ if (nbits < 1024 || (nbits & 0x1FF))
+ return GPG_ERR_INV_VALUE;
+ if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072)
+ return GPG_ERR_INV_VALUE;
+
+ /* The random quality depends on the transient_key flag. */
+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+
+ if (testparms)
+ {
+ /* Parameters to derive the key are given. */
+ /* Note that we explicitly need to setup the values of tbl
+ because some compilers (e.g. OpenWatcom, IRIX) don't allow to
+ initialize a structure with automatic variables. */
+ struct { const char *name; gcry_mpi_t *value; } tbl[] = {
+ { "e" },
+ { "p" },
+ { "q" },
+ { NULL }
+ };
+ int idx;
+ gcry_sexp_t oneparm;
+
+ tbl[0].value = &e;
+ tbl[1].value = &p;
+ tbl[2].value = &q;
+
+ for (idx=0; tbl[idx].name; idx++)
+ {
+ oneparm = sexp_find_token (testparms, tbl[idx].name, 0);
+ if (oneparm)
+ {
+ *tbl[idx].value = sexp_nth_mpi (oneparm, 1, GCRYMPI_FMT_USG);
+ sexp_release (oneparm);
+ }
+ }
+ for (idx=0; tbl[idx].name; idx++)
+ if (!*tbl[idx].value)
+ break;
+ if (tbl[idx].name)
+ {
+ /* At least one parameter is missing. */
+ for (idx=0; tbl[idx].name; idx++)
+ _gcry_mpi_release (*tbl[idx].value);
+ return GPG_ERR_MISSING_VALUE;
+ }
+ }
+ else
+ {
+ if (use_e < 65537)
+ use_e = 65537; /* This is the smallest value allowed by FIPS */
+
+ e = mpi_alloc ((32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB);
+
+ use_e |= 1; /* make sure this is odd */
+ mpi_set_ui (e, use_e);
+
+ p = mpi_snew (pbits);
+ q = mpi_snew (pbits);
+ }
+
+ n = mpi_new (nbits);
+ d = mpi_snew (nbits);
+ u = mpi_snew (nbits);
+
+ /* prepare approximate minimum p and q */
+ minp = mpi_new (pbits);
+ mpi_set_ui (minp, 0xB504F334);
+ mpi_lshift (minp, minp, pbits - 32);
+
+ /* prepare minimum p and q difference */
+ diff = mpi_new (pbits);
+ mindiff = mpi_new (pbits - 99);
+ mpi_set_ui (mindiff, 1);
+ mpi_lshift (mindiff, mindiff, pbits - 100);
+
+ p1 = mpi_snew (pbits);
+ q1 = mpi_snew (pbits);
+ g = mpi_snew (pbits);
+
+ retry:
+ /* generate p and q */
+ for (i = 0; i < 5 * pbits; i++)
+ {
+ ploop:
+ if (!testparms)
+ {
+ _gcry_mpi_randomize (p, pbits, random_level);
+ }
+ if (mpi_cmp (p, minp) < 0)
+ {
+ if (testparms)
+ goto err;
+ goto ploop;
+ }
+
+ mpi_sub_ui (p1, p, 1);
+ if (mpi_gcd (g, p1, e))
+ {
+ if (_gcry_fips186_4_prime_check (p, pbits) != GPG_ERR_NO_ERROR)
+ {
+ /* not a prime */
+ if (testparms)
+ goto err;
+ }
+ else
+ break;
+ }
+ else if (testparms)
+ goto err;
+ }
+ if (i >= 5 * pbits)
+ goto err;
+
+ for (i = 0; i < 5 * pbits; i++)
+ {
+ qloop:
+ if (!testparms)
+ {
+ _gcry_mpi_randomize (q, pbits, random_level);
+ }
+ if (mpi_cmp (q, minp) < 0)
+ {
+ if (testparms)
+ goto err;
+ goto qloop;
+ }
+ if (mpi_cmp (p, q) > 0)
+ {
+ pqswitch = 1;
+ mpi_sub (diff, p, q);
+ }
+ else
+ {
+ pqswitch = 0;
+ mpi_sub (diff, q, p);
+ }
+ if (mpi_cmp (diff, mindiff) < 0)
+ {
+ if (testparms)
+ goto err;
+ goto qloop;
+ }
+
+ mpi_sub_ui (q1, q, 1);
+ if (mpi_gcd (g, q1, e))
+ {
+ if (_gcry_fips186_4_prime_check (q, pbits) != GPG_ERR_NO_ERROR)
+ {
+ /* not a prime */
+ if (testparms)
+ goto err;
+ }
+ else
+ break;
+ }
+ else if (testparms)
+ goto err;
+ }
+ if (i >= 5 * pbits)
+ goto err;
+
+ if (testparms)
+ {
+ mpi_clear (p);
+ mpi_clear (q);
+ }
+ else
+ {
+ gcry_mpi_t f;
+
+ if (pqswitch)
+ {
+ gcry_mpi_t tmp;
+
+ tmp = p;
+ p = q;
+ q = tmp;
+ }
+
+ f = mpi_snew (nbits);
+
+ /* calculate the modulus */
+ mpi_mul (n, p, q);
+
+ /* calculate the secret key d = e^1 mod phi */
+ mpi_gcd (g, p1, q1);
+ mpi_fdiv_q (f, p1, g);
+ mpi_mul (f, f, q1);
+
+ mpi_invm (d, e, f);
+
+ _gcry_mpi_release (f);
+
+ if (mpi_get_nbits (d) < pbits)
+ goto retry;
+
+ /* calculate the inverse of p and q (used for chinese remainder theorem)*/
+ mpi_invm (u, p, q );
+ }
+
+ ec = 0;
+
+ if (DBG_CIPHER)
+ {
+ log_mpidump(" p= ", p );
+ log_mpidump(" q= ", q );
+ log_mpidump(" n= ", n );
+ log_mpidump(" e= ", e );
+ log_mpidump(" d= ", d );
+ log_mpidump(" u= ", u );
+ }
+
+ err:
+
+ _gcry_mpi_release (p1);
+ _gcry_mpi_release (q1);
+ _gcry_mpi_release (g);
+ _gcry_mpi_release (minp);
+ _gcry_mpi_release (mindiff);
+ _gcry_mpi_release (diff);
+
+ sk->n = n;
+ sk->e = e;
+ sk->p = p;
+ sk->q = q;
+ sk->d = d;
+ sk->u = u;
+
+ /* Now we can test our keys. */
+ if (ec || (!testparms && test_keys (sk, nbits - 64)))
+ {
+ _gcry_mpi_release (sk->n); sk->n = NULL;
+ _gcry_mpi_release (sk->e); sk->e = NULL;
+ _gcry_mpi_release (sk->p); sk->p = NULL;
+ _gcry_mpi_release (sk->q); sk->q = NULL;
+ _gcry_mpi_release (sk->d); sk->d = NULL;
+ _gcry_mpi_release (sk->u); sk->u = NULL;
+ if (!ec)
+ {
+ fips_signal_error ("self-test after key generation failed");
+ return GPG_ERR_SELFTEST_FAILED;
+ }
+ }
+
+ return ec;
+}
+
+
+/* Helper for generate_x931. */
+static gcry_mpi_t
+gen_x931_parm_xp (unsigned int nbits)
+{
+ gcry_mpi_t xp;
+
+ xp = mpi_snew (nbits);
+ _gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM);
+
+ /* The requirement for Xp is:
+
+ sqrt{2}*2^{nbits-1} <= xp <= 2^{nbits} - 1
+
+ We set the two high order bits to 1 to satisfy the lower bound.
+ By using mpi_set_highbit we make sure that the upper bound is
+ satisfied as well. */
+ mpi_set_highbit (xp, nbits-1);
+ mpi_set_bit (xp, nbits-2);
+ gcry_assert ( mpi_get_nbits (xp) == nbits );
+
+ return xp;
+}
+
+
+/* Helper for generate_x931. */
+static gcry_mpi_t
+gen_x931_parm_xi (void)
+{
+ gcry_mpi_t xi;
+
+ xi = mpi_snew (101);
+ _gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM);
+ mpi_set_highbit (xi, 100);
+ gcry_assert ( mpi_get_nbits (xi) == 101 );
+
+ return xi;
+}
+
+
+
+/* Variant of the standard key generation code using the algorithm
+ from X9.31. Using this algorithm has the advantage that the
+ generation can be made deterministic which is required for CAVS
+ testing. */
+static gpg_err_code_t
+generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
+ gcry_sexp_t deriveparms, int *swapped)
+{
+ gcry_mpi_t p, q; /* The two primes. */
+ gcry_mpi_t e; /* The public exponent. */
+ gcry_mpi_t n; /* The public key. */
+ gcry_mpi_t d; /* The private key */
+ gcry_mpi_t u; /* The inverse of p and q. */
+ gcry_mpi_t pm1; /* p - 1 */
+ gcry_mpi_t qm1; /* q - 1 */
+ gcry_mpi_t phi; /* Euler totient. */
+ gcry_mpi_t f, g; /* Helper. */
+
+ *swapped = 0;
+
+ if (e_value == 1) /* Alias for a secure value. */
+ e_value = 65537;
+
+ /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */
+ if (nbits < 1024 || (nbits % 256))
+ return GPG_ERR_INV_VALUE;
+
+ /* Point 2: 2 <= bitlength(e) < 2^{k-2}
+ Note that we do not need to check the upper bound because we use
+ an unsigned long for E and thus there is no way for E to reach
+ that limit. */
+ if (e_value < 3)
+ return GPG_ERR_INV_VALUE;
+
+ /* Our implementation requires E to be odd. */
+ if (!(e_value & 1))
+ return GPG_ERR_INV_VALUE;
+
+ /* Point 3: e > 0 or e 0 if it is to be randomly generated.
+ We support only a fixed E and thus there is no need for an extra test. */
+
+
+ /* Compute or extract the derive parameters. */
+ {
+ gcry_mpi_t xp1 = NULL;
+ gcry_mpi_t xp2 = NULL;
+ gcry_mpi_t xp = NULL;
+ gcry_mpi_t xq1 = NULL;
+ gcry_mpi_t xq2 = NULL;
+ gcry_mpi_t xq = NULL;
+ gcry_mpi_t tmpval;
+
+ if (!deriveparms)
+ {
+ /* Not given: Generate them. */
+ xp = gen_x931_parm_xp (nbits/2);
+ /* Make sure that |xp - xq| > 2^{nbits - 100} holds. */
+ tmpval = mpi_snew (nbits/2);
+ do
+ {
+ _gcry_mpi_release (xq);
+ xq = gen_x931_parm_xp (nbits/2);
+ mpi_sub (tmpval, xp, xq);
+ }
+ while (mpi_get_nbits (tmpval) <= (nbits/2 - 100));
+ _gcry_mpi_release (tmpval);
+
+ xp1 = gen_x931_parm_xi ();
+ xp2 = gen_x931_parm_xi ();
+ xq1 = gen_x931_parm_xi ();
+ xq2 = gen_x931_parm_xi ();
+
+ }
+ else
+ {
+ /* Parameters to derive the key are given. */
+ /* Note that we explicitly need to setup the values of tbl
+ because some compilers (e.g. OpenWatcom, IRIX) don't allow
+ to initialize a structure with automatic variables. */
+ struct { const char *name; gcry_mpi_t *value; } tbl[] = {
+ { "Xp1" },
+ { "Xp2" },
+ { "Xp" },
+ { "Xq1" },
+ { "Xq2" },
+ { "Xq" },
+ { NULL }
+ };
+ int idx;
+ gcry_sexp_t oneparm;
+
+ tbl[0].value = &xp1;
+ tbl[1].value = &xp2;
+ tbl[2].value = &xp;
+ tbl[3].value = &xq1;
+ tbl[4].value = &xq2;
+ tbl[5].value = &xq;
+
+ for (idx=0; tbl[idx].name; idx++)
+ {
+ oneparm = sexp_find_token (deriveparms, tbl[idx].name, 0);
+ if (oneparm)
+ {
+ *tbl[idx].value = sexp_nth_mpi (oneparm, 1, GCRYMPI_FMT_USG);
+ sexp_release (oneparm);
+ }
+ }
+ for (idx=0; tbl[idx].name; idx++)
+ if (!*tbl[idx].value)
+ break;
+ if (tbl[idx].name)
+ {
+ /* At least one parameter is missing. */
+ for (idx=0; tbl[idx].name; idx++)
+ _gcry_mpi_release (*tbl[idx].value);
+ return GPG_ERR_MISSING_VALUE;
+ }
+ }
+
+ e = mpi_alloc_set_ui (e_value);
+
+ /* Find two prime numbers. */
+ p = _gcry_derive_x931_prime (xp, xp1, xp2, e, NULL, NULL);
+ q = _gcry_derive_x931_prime (xq, xq1, xq2, e, NULL, NULL);
+ _gcry_mpi_release (xp); xp = NULL;
+ _gcry_mpi_release (xp1); xp1 = NULL;
+ _gcry_mpi_release (xp2); xp2 = NULL;
+ _gcry_mpi_release (xq); xq = NULL;
+ _gcry_mpi_release (xq1); xq1 = NULL;
+ _gcry_mpi_release (xq2); xq2 = NULL;
+ if (!p || !q)
+ {
+ _gcry_mpi_release (p);
+ _gcry_mpi_release (q);
+ _gcry_mpi_release (e);
+ return GPG_ERR_NO_PRIME;
+ }
+ }
+
+
+ /* Compute the public modulus. We make sure that p is smaller than
+ q to allow the use of the CRT. */
+ if (mpi_cmp (p, q) > 0 )
+ {
+ mpi_swap (p, q);
+ *swapped = 1;
+ }
+ n = mpi_new (nbits);
+ mpi_mul (n, p, q);
+
+ /* Compute the Euler totient: phi = (p-1)(q-1) */
+ pm1 = mpi_snew (nbits/2);
+ qm1 = mpi_snew (nbits/2);
+ phi = mpi_snew (nbits);
+ mpi_sub_ui (pm1, p, 1);
+ mpi_sub_ui (qm1, q, 1);
+ mpi_mul (phi, pm1, qm1);
+
+ g = mpi_snew (nbits);
+ gcry_assert (mpi_gcd (g, e, phi));
+
+ /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
+ mpi_gcd (g, pm1, qm1);
+ f = pm1; pm1 = NULL;
+ _gcry_mpi_release (qm1); qm1 = NULL;
+ mpi_fdiv_q (f, phi, g);
+ _gcry_mpi_release (phi); phi = NULL;
+ d = g; g = NULL;
+ /* Compute the secret key: d = e^{-1} mod lcm(p-1,q-1) */
+ mpi_invm (d, e, f);
+
+ /* Compute the inverse of p and q. */
+ u = f; f = NULL;
+ mpi_invm (u, p, q );
+
+ if( DBG_CIPHER )
+ {
+ if (*swapped)
+ log_debug ("p and q are swapped\n");
+ log_mpidump(" p", p );
+ log_mpidump(" q", q );
+ log_mpidump(" n", n );
+ log_mpidump(" e", e );
+ log_mpidump(" d", d );
+ log_mpidump(" u", u );
+ }
+
+
+ sk->n = n;
+ sk->e = e;
+ sk->p = p;
+ sk->q = q;
+ sk->d = d;
+ sk->u = u;
+
+ /* Now we can test our keys. */
+ if (test_keys (sk, nbits - 64))
+ {
+ _gcry_mpi_release (sk->n); sk->n = NULL;
+ _gcry_mpi_release (sk->e); sk->e = NULL;
+ _gcry_mpi_release (sk->p); sk->p = NULL;
+ _gcry_mpi_release (sk->q); sk->q = NULL;
+ _gcry_mpi_release (sk->d); sk->d = NULL;
+ _gcry_mpi_release (sk->u); sk->u = NULL;
+ fips_signal_error ("self-test after key generation failed");
+ return GPG_ERR_SELFTEST_FAILED;
+ }
+
+ return 0;
+}
+
+
+/****************
+ * Test whether the secret key is valid.
+ * Returns: true if this is a valid key.
+ */
+static int
+check_secret_key( RSA_secret_key *sk )
+{
+ int rc;
+ gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 );
+
+ mpi_mul(temp, sk->p, sk->q );
+ rc = mpi_cmp( temp, sk->n );
+ mpi_free(temp);
+ return !rc;
+}
+
+
+
+/****************
+ * Public key operation. Encrypt INPUT with PKEY and put result into OUTPUT.
+ *
+ * c = m^e mod n
+ *
+ * Where c is OUTPUT, m is INPUT and e,n are elements of PKEY.
+ */
+static void
+public(gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *pkey )
+{
+ if( output == input ) /* powm doesn't like output and input the same */
+ {
+ gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs(input)*2 );
+ mpi_powm( x, input, pkey->e, pkey->n );
+ mpi_set(output, x);
+ mpi_free(x);
+ }
+ else
+ mpi_powm( output, input, pkey->e, pkey->n );
+}
+
+#if 0
+static void
+stronger_key_check ( RSA_secret_key *skey )
+{
+ gcry_mpi_t t = mpi_alloc_secure ( 0 );
+ gcry_mpi_t t1 = mpi_alloc_secure ( 0 );
+ gcry_mpi_t t2 = mpi_alloc_secure ( 0 );
+ gcry_mpi_t phi = mpi_alloc_secure ( 0 );
+
+ /* check that n == p * q */
+ mpi_mul( t, skey->p, skey->q);
+ if (mpi_cmp( t, skey->n) )
+ log_info ( "RSA Oops: n != p * q\n" );
+
+ /* check that p is less than q */
+ if( mpi_cmp( skey->p, skey->q ) > 0 )
+ {
+ log_info ("RSA Oops: p >= q - fixed\n");
+ _gcry_mpi_swap ( skey->p, skey->q);
+ }
+
+ /* check that e divides neither p-1 nor q-1 */
+ mpi_sub_ui(t, skey->p, 1 );
+ mpi_fdiv_r(t, t, skey->e );
+ if ( !mpi_cmp_ui( t, 0) )
+ log_info ( "RSA Oops: e divides p-1\n" );
+ mpi_sub_ui(t, skey->q, 1 );
+ mpi_fdiv_r(t, t, skey->e );
+ if ( !mpi_cmp_ui( t, 0) )
+ log_info ( "RSA Oops: e divides q-1\n" );
+
+ /* check that d is correct */
+ mpi_sub_ui( t1, skey->p, 1 );
+ mpi_sub_ui( t2, skey->q, 1 );
+ mpi_mul( phi, t1, t2 );
+ gcry_mpi_gcd(t, t1, t2);
+ mpi_fdiv_q(t, phi, t);
+ mpi_invm(t, skey->e, t );
+ if ( mpi_cmp(t, skey->d ) )
+ {
+ log_info ( "RSA Oops: d is wrong - fixed\n");
+ mpi_set (skey->d, t);
+ log_printmpi (" fixed d", skey->d);
+ }
+
+ /* check for correctness of u */
+ mpi_invm(t, skey->p, skey->q );
+ if ( mpi_cmp(t, skey->u ) )
+ {
+ log_info ( "RSA Oops: u is wrong - fixed\n");
+ mpi_set (skey->u, t);
+ log_printmpi (" fixed u", skey->u);
+ }
+
+ log_info ( "RSA secret key check finished\n");
+
+ mpi_free (t);
+ mpi_free (t1);
+ mpi_free (t2);
+ mpi_free (phi);
+}
+#endif
+
+
+
+/* Secret key operation - standard version.
+ *
+ * m = c^d mod n
+ */
+static void
+secret_core_std (gcry_mpi_t M, gcry_mpi_t C,
+ gcry_mpi_t D, gcry_mpi_t N)
+{
+ mpi_powm (M, C, D, N);
+}
+
+
+/* Secret key operation - using the CRT.
+ *
+ * m1 = c ^ (d mod (p-1)) mod p
+ * m2 = c ^ (d mod (q-1)) mod q
+ * h = u * (m2 - m1) mod q
+ * m = m1 + h * p
+ */
+static void
+secret_core_crt (gcry_mpi_t M, gcry_mpi_t C,
+ gcry_mpi_t D, unsigned int Nlimbs,
+ gcry_mpi_t P, gcry_mpi_t Q, gcry_mpi_t U)
+{
+ gcry_mpi_t m1 = mpi_alloc_secure ( Nlimbs + 1 );
+ gcry_mpi_t m2 = mpi_alloc_secure ( Nlimbs + 1 );
+ gcry_mpi_t h = mpi_alloc_secure ( Nlimbs + 1 );
+ gcry_mpi_t D_blind = mpi_alloc_secure ( Nlimbs + 1 );
+ gcry_mpi_t r;
+ unsigned int r_nbits;
+
+ r_nbits = mpi_get_nbits (P) / 4;
+ if (r_nbits < 96)
+ r_nbits = 96;
+ r = mpi_secure_new (r_nbits);
+
+ /* d_blind = (d mod (p-1)) + (p-1) * r */
+ /* m1 = c ^ d_blind mod p */
+ _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM);
+ mpi_set_highbit (r, r_nbits - 1);
+ mpi_sub_ui ( h, P, 1 );
+ mpi_mul ( D_blind, h, r );
+ mpi_fdiv_r ( h, D, h );
+ mpi_add ( D_blind, D_blind, h );
+ mpi_powm ( m1, C, D_blind, P );
+
+ /* d_blind = (d mod (q-1)) + (q-1) * r */
+ /* m2 = c ^ d_blind mod q */
+ _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM);
+ mpi_set_highbit (r, r_nbits - 1);
+ mpi_sub_ui ( h, Q, 1 );
+ mpi_mul ( D_blind, h, r );
+ mpi_fdiv_r ( h, D, h );
+ mpi_add ( D_blind, D_blind, h );
+ mpi_powm ( m2, C, D_blind, Q );
+
+ mpi_free ( r );
+ mpi_free ( D_blind );
+
+ /* h = u * ( m2 - m1 ) mod q */
+ mpi_sub ( h, m2, m1 );
+ if ( mpi_has_sign ( h ) )
+ mpi_add ( h, h, Q );
+ mpi_mulm ( h, U, h, Q );
+
+ /* m = m1 + h * p */
+ mpi_mul ( h, h, P );
+ mpi_add ( M, m1, h );
+
+ mpi_free ( h );
+ mpi_free ( m1 );
+ mpi_free ( m2 );
+}
+
+
+/* Secret key operation.
+ * Encrypt INPUT with SKEY and put result into
+ * OUTPUT. SKEY has the secret key parameters.
+ */
+static void
+secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
+{
+ /* Remove superfluous leading zeroes from INPUT. */
+ mpi_normalize (input);
+
+ if (!skey->p || !skey->q || !skey->u)
+ {
+ secret_core_std (output, input, skey->d, skey->n);
+ }
+ else
+ {
+ secret_core_crt (output, input, skey->d, mpi_get_nlimbs (skey->n),
+ skey->p, skey->q, skey->u);
+ }
+}
+
+
+static void
+secret_blinded (gcry_mpi_t output, gcry_mpi_t input,
+ RSA_secret_key *sk, unsigned int nbits)
+{
+ gcry_mpi_t r; /* Random number needed for blinding. */
+ gcry_mpi_t ri; /* Modular multiplicative inverse of r. */
+ gcry_mpi_t bldata; /* Blinded data to decrypt. */
+
+ /* First, we need a random number r between 0 and n - 1, which is
+ * relatively prime to n (i.e. it is neither p nor q). The random
+ * number needs to be only unpredictable, thus we employ the
+ * gcry_create_nonce function by using GCRY_WEAK_RANDOM with
+ * gcry_mpi_randomize. */
+ r = mpi_snew (nbits);
+ ri = mpi_snew (nbits);
+ bldata = mpi_snew (nbits);
+
+ do
+ {
+ _gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM);
+ mpi_mod (r, r, sk->n);
+ }
+ while (!mpi_invm (ri, r, sk->n));
+
+ /* Do blinding. We calculate: y = (x * r^e) mod n, where r is the
+ * random number, e is the public exponent, x is the non-blinded
+ * input data and n is the RSA modulus. */
+ mpi_powm (bldata, r, sk->e, sk->n);
+ mpi_mulm (bldata, bldata, input, sk->n);
+
+ /* Perform decryption. */
+ secret (output, bldata, sk);
+ _gcry_mpi_release (bldata);
+
+ /* Undo blinding. Here we calculate: y = (x * r^-1) mod n, where x
+ * is the blinded decrypted data, ri is the modular multiplicative
+ * inverse of r and n is the RSA modulus. */
+ mpi_mulm (output, output, ri, sk->n);
+
+ _gcry_mpi_release (r);
+ _gcry_mpi_release (ri);
+}
+
+
+/*********************************************
+ ************** interface ******************
+ *********************************************/
+
+static gcry_err_code_t
+rsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+{
+ gpg_err_code_t ec;
+ unsigned int nbits;
+ unsigned long evalue;
+ RSA_secret_key sk;
+ gcry_sexp_t deriveparms;
+ int flags = 0;
+ gcry_sexp_t l1;
+ gcry_sexp_t swap_info = NULL;
+
+ memset (&sk, 0, sizeof sk);
+
+ ec = _gcry_pk_util_get_nbits (genparms, &nbits);
+ if (ec)
+ return ec;
+
+ ec = _gcry_pk_util_get_rsa_use_e (genparms, &evalue);
+ if (ec)
+ return ec;
+
+ /* Parse the optional flags list. */
+ l1 = sexp_find_token (genparms, "flags", 0);
+ if (l1)
+ {
+ ec = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+ sexp_release (l1);
+ if (ec)
+ return ec;
+ }
+
+ deriveparms = (genparms?
+ sexp_find_token (genparms, "derive-parms", 0) : NULL);
+ if (!deriveparms)
+ {
+ /* Parse the optional "use-x931" flag. */
+ l1 = sexp_find_token (genparms, "use-x931", 0);
+ if (l1)
+ {
+ flags |= PUBKEY_FLAG_USE_X931;
+ sexp_release (l1);
+ }
+ }
+
+ if (deriveparms || (flags & PUBKEY_FLAG_USE_X931))
+ {
+ int swapped;
+ ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped);
+ sexp_release (deriveparms);
+ if (!ec && swapped)
+ ec = sexp_new (&swap_info, "(misc-key-info(p-q-swapped))", 0, 1);
+ }
+ else
+ {
+ /* Parse the optional "transient-key" flag. */
+ if (!(flags & PUBKEY_FLAG_TRANSIENT_KEY))
+ {
+ l1 = sexp_find_token (genparms, "transient-key", 0);
+ if (l1)
+ {
+ flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+ sexp_release (l1);
+ }
+ }
+ deriveparms = (genparms? sexp_find_token (genparms, "test-parms", 0)
+ /**/ : NULL);
+
+ /* Generate. */
+ if (deriveparms || fips_mode())
+ {
+ ec = generate_fips (&sk, nbits, evalue, deriveparms,
+ !!(flags & PUBKEY_FLAG_TRANSIENT_KEY));
+ }
+ else
+ {
+ ec = generate_std (&sk, nbits, evalue,
+ !!(flags & PUBKEY_FLAG_TRANSIENT_KEY));
+ }
+ sexp_release (deriveparms);
+ }
+
+ if (!ec)
+ {
+ ec = sexp_build (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (rsa(n%m)(e%m)))"
+ " (private-key"
+ " (rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))"
+ " %S)",
+ sk.n, sk.e,
+ sk.n, sk.e, sk.d, sk.p, sk.q, sk.u,
+ swap_info);
+ }
+
+ mpi_free (sk.n);
+ mpi_free (sk.e);
+ mpi_free (sk.p);
+ mpi_free (sk.q);
+ mpi_free (sk.d);
+ mpi_free (sk.u);
+ sexp_release (swap_info);
+
+ return ec;
+}
+
+
+static gcry_err_code_t
+rsa_check_secret_key (gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
+
+ /* To check the key we need the optional parameters. */
+ rc = sexp_extract_param (keyparms, NULL, "nedpqu",
+ &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u,
+ NULL);
+ if (rc)
+ goto leave;
+
+ if (!check_secret_key (&sk))
+ rc = GPG_ERR_BAD_SECKEY;
+
+ leave:
+ _gcry_mpi_release (sk.n);
+ _gcry_mpi_release (sk.e);
+ _gcry_mpi_release (sk.d);
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.u);
+ if (DBG_CIPHER)
+ log_debug ("rsa_testkey => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+rsa_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t data = NULL;
+ RSA_public_key pk = {NULL, NULL};
+ gcry_mpi_t ciph = NULL;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+ rsa_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("rsa_encrypt data", data);
+ if (!data || mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the key. */
+ rc = sexp_extract_param (keyparms, NULL, "ne", &pk.n, &pk.e, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("rsa_encrypt n", pk.n);
+ log_mpidump ("rsa_encrypt e", pk.e);
+ }
+
+ /* Do RSA computation and build result. */
+ ciph = mpi_new (0);
+ public (ciph, data, &pk);
+ if (DBG_CIPHER)
+ log_mpidump ("rsa_encrypt res", ciph);
+ if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN))
+ {
+ /* We need to make sure to return the correct length to avoid
+ problems with missing leading zeroes. */
+ unsigned char *em;
+ size_t emlen = (mpi_get_nbits (pk.n)+7)/8;
+
+ rc = _gcry_mpi_to_octet_string (&em, NULL, ciph, emlen);
+ if (!rc)
+ {
+ rc = sexp_build (r_ciph, NULL, "(enc-val(rsa(a%b)))", (int)emlen, em);
+ xfree (em);
+ }
+ }
+ else
+ rc = sexp_build (r_ciph, NULL, "(enc-val(rsa(a%m)))", ciph);
+
+ leave:
+ _gcry_mpi_release (ciph);
+ _gcry_mpi_release (pk.n);
+ _gcry_mpi_release (pk.e);
+ _gcry_mpi_release (data);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("rsa_encrypt => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+
+{
+ gpg_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ gcry_mpi_t data = NULL;
+ RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
+ gcry_mpi_t plain = NULL;
+ unsigned char *unpad = NULL;
+ size_t unpadlen = 0;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
+ rsa_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_preparse_encval (s_data, rsa_names, &l1, &ctx);
+ if (rc)
+ goto leave;
+ rc = sexp_extract_param (l1, NULL, "a", &data, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_printmpi ("rsa_decrypt data", data);
+ if (mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the key. */
+ rc = sexp_extract_param (keyparms, NULL, "nedp?q?u?",
+ &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u,
+ NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_printmpi ("rsa_decrypt n", sk.n);
+ log_printmpi ("rsa_decrypt e", sk.e);
+ if (!fips_mode ())
+ {
+ log_printmpi ("rsa_decrypt d", sk.d);
+ log_printmpi ("rsa_decrypt p", sk.p);
+ log_printmpi ("rsa_decrypt q", sk.q);
+ log_printmpi ("rsa_decrypt u", sk.u);
+ }
+ }
+
+ /* Better make sure that there are no superfluous leading zeroes in
+ the input and it has not been "padded" using multiples of N.
+ This mitigates side-channel attacks (CVE-2013-4576). */
+ mpi_normalize (data);
+ mpi_fdiv_r (data, data, sk.n);
+
+ /* Allocate MPI for the plaintext. */
+ plain = mpi_snew (ctx.nbits);
+
+ /* We use blinding by default to mitigate timing attacks which can
+ be practically mounted over the network as shown by Brumley and
+ Boney in 2003. */
+ if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING))
+ secret (plain, data, &sk);
+ else
+ secret_blinded (plain, data, &sk, ctx.nbits);
+
+ if (DBG_CIPHER)
+ log_printmpi ("rsa_decrypt res", plain);
+
+ /* Reverse the encoding and build the s-expression. */
+ switch (ctx.encoding)
+ {
+ case PUBKEY_ENC_PKCS1:
+ rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, ctx.nbits, plain);
+ mpi_free (plain);
+ plain = NULL;
+ if (!rc)
+ rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad);
+ break;
+
+ case PUBKEY_ENC_OAEP:
+ rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen,
+ ctx.nbits, ctx.hash_algo,
+ plain, ctx.label, ctx.labellen);
+ mpi_free (plain);
+ plain = NULL;
+ if (!rc)
+ rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad);
+ break;
+
+ default:
+ /* Raw format. For backward compatibility we need to assume a
+ signed mpi by using the sexp format string "%m". */
+ rc = sexp_build (r_plain, NULL,
+ (ctx.flags & PUBKEY_FLAG_LEGACYRESULT)
+ ? "%m":"(value %m)", plain);
+ break;
+ }
+
+ leave:
+ xfree (unpad);
+ _gcry_mpi_release (plain);
+ _gcry_mpi_release (sk.n);
+ _gcry_mpi_release (sk.e);
+ _gcry_mpi_release (sk.d);
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.u);
+ _gcry_mpi_release (data);
+ sexp_release (l1);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("rsa_decrypt => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ gpg_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t data = NULL;
+ RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
+ RSA_public_key pk;
+ gcry_mpi_t sig = NULL;
+ gcry_mpi_t result = NULL;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
+ rsa_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_printmpi ("rsa_sign data", data);
+ if (mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the key. */
+ rc = sexp_extract_param (keyparms, NULL, "nedp?q?u?",
+ &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u,
+ NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_printmpi ("rsa_sign n", sk.n);
+ log_printmpi ("rsa_sign e", sk.e);
+ if (!fips_mode ())
+ {
+ log_printmpi ("rsa_sign d", sk.d);
+ log_printmpi ("rsa_sign p", sk.p);
+ log_printmpi ("rsa_sign q", sk.q);
+ log_printmpi ("rsa_sign u", sk.u);
+ }
+ }
+
+ /* Do RSA computation. */
+ sig = mpi_new (0);
+ if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING))
+ secret (sig, data, &sk);
+ else
+ secret_blinded (sig, data, &sk, ctx.nbits);
+ if (DBG_CIPHER)
+ log_printmpi ("rsa_sign res", sig);
+
+ /* Check that the created signature is good. This detects a failure
+ of the CRT algorithm (Lenstra's attack on RSA's use of the CRT). */
+ result = mpi_new (0);
+ pk.n = sk.n;
+ pk.e = sk.e;
+ public (result, sig, &pk);
+ if (mpi_cmp (result, data))
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Convert the result. */
+ if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN))
+ {
+ /* We need to make sure to return the correct length to avoid
+ problems with missing leading zeroes. */
+ unsigned char *em;
+ size_t emlen = (mpi_get_nbits (sk.n)+7)/8;
+
+ rc = _gcry_mpi_to_octet_string (&em, NULL, sig, emlen);
+ if (!rc)
+ {
+ rc = sexp_build (r_sig, NULL, "(sig-val(rsa(s%b)))", (int)emlen, em);
+ xfree (em);
+ }
+ }
+ else
+ rc = sexp_build (r_sig, NULL, "(sig-val(rsa(s%M)))", sig);
+
+
+ leave:
+ _gcry_mpi_release (result);
+ _gcry_mpi_release (sig);
+ _gcry_mpi_release (sk.n);
+ _gcry_mpi_release (sk.e);
+ _gcry_mpi_release (sk.d);
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.u);
+ _gcry_mpi_release (data);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("rsa_sign => %s\n", gpg_strerror (rc));
+ return rc;
+}
+
+
+static gcry_err_code_t
+rsa_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ gcry_mpi_t sig = NULL;
+ gcry_mpi_t data = NULL;
+ RSA_public_key pk = { NULL, NULL };
+ gcry_mpi_t result = NULL;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+ rsa_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_printmpi ("rsa_verify data", data);
+ if (mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the signature value. */
+ rc = _gcry_pk_util_preparse_sigval (s_sig, rsa_names, &l1, NULL);
+ if (rc)
+ goto leave;
+ rc = sexp_extract_param (l1, NULL, "s", &sig, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_printmpi ("rsa_verify sig", sig);
+
+ /* Extract the key. */
+ rc = sexp_extract_param (keyparms, NULL, "ne", &pk.n, &pk.e, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_printmpi ("rsa_verify n", pk.n);
+ log_printmpi ("rsa_verify e", pk.e);
+ }
+
+ /* Do RSA computation and compare. */
+ result = mpi_new (0);
+ public (result, sig, &pk);
+ if (DBG_CIPHER)
+ log_printmpi ("rsa_verify cmp", result);
+ if (ctx.verify_cmp)
+ rc = ctx.verify_cmp (&ctx, result);
+ else
+ rc = mpi_cmp (result, data) ? GPG_ERR_BAD_SIGNATURE : 0;
+
+ leave:
+ _gcry_mpi_release (result);
+ _gcry_mpi_release (pk.n);
+ _gcry_mpi_release (pk.e);
+ _gcry_mpi_release (data);
+ _gcry_mpi_release (sig);
+ sexp_release (l1);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("rsa_verify => %s\n", rc?gpg_strerror (rc):"Good");
+ return rc;
+}
+
+
+
+/* Return the number of bits for the key described by PARMS. On error
+ * 0 is returned. The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ * (rsa
+ * (n <mpi>)
+ * (e <mpi>))
+ *
+ * More parameters may be given but we only need N here.
+ */
+static unsigned int
+rsa_get_nbits (gcry_sexp_t parms)
+{
+ gcry_sexp_t l1;
+ gcry_mpi_t n;
+ unsigned int nbits;
+
+ l1 = sexp_find_token (parms, "n", 1);
+ if (!l1)
+ return 0; /* Parameter N not found. */
+
+ n = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ nbits = n? mpi_get_nbits (n) : 0;
+ _gcry_mpi_release (n);
+ return nbits;
+}
+
+
+/* Compute a keygrip. MD is the hash context which we are going to
+ update. KEYPARAM is an S-expression with the key parameters, this
+ is usually a public key but may also be a secret key. An example
+ of such an S-expression is:
+
+ (rsa
+ (n #00B...#)
+ (e #010001#))
+
+ PKCS-15 says that for RSA only the modulus should be hashed -
+ however, it is not clear whether this is meant to use the raw bytes
+ (assuming this is an unsigned integer) or whether the DER required
+ 0 should be prefixed. We hash the raw bytes. */
+static gpg_err_code_t
+compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
+{
+ gcry_sexp_t l1;
+ const char *data;
+ size_t datalen;
+
+ l1 = sexp_find_token (keyparam, "n", 1);
+ if (!l1)
+ return GPG_ERR_NO_OBJ;
+
+ data = sexp_nth_data (l1, 1, &datalen);
+ if (!data)
+ {
+ sexp_release (l1);
+ return GPG_ERR_NO_OBJ;
+ }
+
+ _gcry_md_write (md, data, datalen);
+ sexp_release (l1);
+
+ return 0;
+}
+
+
+
+
+/*
+ Self-test section.
+ */
+
+static const char *
+selftest_sign_2048 (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+ static const char sample_data[] =
+ "(data (flags pkcs1)"
+ " (hash sha256 #11223344556677889900aabbccddeeff"
+ /**/ "102030405060708090a0b0c0d0f01121#))";
+ static const char sample_data_bad[] =
+ "(data (flags pkcs1)"
+ " (hash sha256 #11223344556677889900aabbccddeeff"
+ /**/ "802030405060708090a0b0c0d0f01121#))";
+
+ const char *errtxt = NULL;
+ gcry_error_t err;
+ gcry_sexp_t data = NULL;
+ gcry_sexp_t data_bad = NULL;
+ gcry_sexp_t sig = NULL;
+ /* raw signature data reference */
+ const char ref_data[] =
+ "6252a19a11e1d5155ed9376036277193d644fa239397fff03e9b92d6f86415d6"
+ "d30da9273775f290e580d038295ff8ff89522becccfa6ae870bf76b76df402a8"
+ "54f69347e3db3de8e1e7d4dada281ec556810c7a8ecd0b5f51f9b1c0e7aa7557"
+ "61aa2b8ba5f811304acc6af0eca41fe49baf33bf34eddaf44e21e036ac7f0b68"
+ "03cdef1c60021fb7b5b97ebacdd88ab755ce29af568dbc5728cc6e6eff42618d"
+ "62a0386ca8beed46402bdeeef29b6a3feded906bace411a06a39192bf516ae10"
+ "67e4320fa8ea113968525f4574d022a3ceeaafdc41079efe1f22cc94bf59d8d3"
+ "328085da9674857db56de5978a62394aab48aa3b72e23a1b16260cfd9daafe65";
+ gcry_mpi_t ref_mpi = NULL;
+ gcry_mpi_t sig_mpi = NULL;
+
+ err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
+ if (!err)
+ err = sexp_sscan (&data_bad, NULL,
+ sample_data_bad, strlen (sample_data_bad));
+ if (err)
+ {
+ errtxt = "converting data failed";
+ goto leave;
+ }
+
+ err = _gcry_pk_sign (&sig, data, skey);
+ if (err)
+ {
+ errtxt = "signing failed";
+ goto leave;
+ }
+
+ err = _gcry_mpi_scan(&ref_mpi, GCRYMPI_FMT_HEX, ref_data, 0, NULL);
+ if (err)
+ {
+ errtxt = "converting ref_data to mpi failed";
+ goto leave;
+ }
+
+ err = _gcry_sexp_extract_param(sig, "sig-val!rsa", "s", &sig_mpi, NULL);
+ if (err)
+ {
+ errtxt = "extracting signature data failed";
+ goto leave;
+ }
+
+ if (mpi_cmp (sig_mpi, ref_mpi))
+ {
+ errtxt = "signature does not match reference data";
+ goto leave;
+ }
+
+ err = _gcry_pk_verify (sig, data, pkey);
+ if (err)
+ {
+ errtxt = "verify failed";
+ goto leave;
+ }
+ err = _gcry_pk_verify (sig, data_bad, pkey);
+ if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
+ {
+ errtxt = "bad signature not detected";
+ goto leave;
+ }
+
+
+ leave:
+ sexp_release (sig);
+ sexp_release (data_bad);
+ sexp_release (data);
+ _gcry_mpi_release (ref_mpi);
+ _gcry_mpi_release (sig_mpi);
+ return errtxt;
+}
+
+
+
+/* Given an S-expression ENCR_DATA of the form:
+
+ (enc-val
+ (rsa
+ (a a-value)))
+
+ as returned by gcry_pk_decrypt, return the the A-VALUE. On error,
+ return NULL. */
+static gcry_mpi_t
+extract_a_from_sexp (gcry_sexp_t encr_data)
+{
+ gcry_sexp_t l1, l2, l3;
+ gcry_mpi_t a_value;
+
+ l1 = sexp_find_token (encr_data, "enc-val", 0);
+ if (!l1)
+ return NULL;
+ l2 = sexp_find_token (l1, "rsa", 0);
+ sexp_release (l1);
+ if (!l2)
+ return NULL;
+ l3 = sexp_find_token (l2, "a", 0);
+ sexp_release (l2);
+ if (!l3)
+ return NULL;
+ a_value = sexp_nth_mpi (l3, 1, 0);
+ sexp_release (l3);
+
+ return a_value;
+}
+
+
+static const char *
+selftest_encr_2048 (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+ const char *errtxt = NULL;
+ gcry_error_t err;
+ static const char plaintext[] =
+ "Jim quickly realized that the beautiful gowns are expensive.";
+ gcry_sexp_t plain = NULL;
+ gcry_sexp_t encr = NULL;
+ gcry_mpi_t ciphertext = NULL;
+ gcry_sexp_t decr = NULL;
+ char *decr_plaintext = NULL;
+ gcry_sexp_t tmplist = NULL;
+ /* expected result of encrypting the plaintext with sample_secret_key */
+ static const char ref_data[] =
+ "18022e2593a402a737caaa93b4c7e750e20ca265452980e1d6b7710fbd3e"
+ "7dce72be5c2110fb47691cb38f42170ee3b4a37f2498d4a51567d762585e"
+ "4cb81d04fbc7df4144f8e5eac2d4b8688521b64011f11d7ad53f4c874004"
+ "819856f2e2a6f83d1c9c4e73ac26089789c14482b0b8d44139133c88c4a5"
+ "2dba9dd6d6ffc622666b7d129168333d999706af30a2d7d272db7734e5ed"
+ "fb8c64ea3018af3ad20f4a013a5060cb0f5e72753967bebe294280a6ed0d"
+ "dbd3c4f11d0a8696e9d32a0dc03deb0b5e49b2cbd1503392642d4e1211f3"
+ "e8e2ee38abaa3671ccd57fcde8ca76e85fd2cb77c35706a970a213a27352"
+ "cec92a9604d543ddb5fc478ff50e0622";
+ gcry_mpi_t ref_mpi = NULL;
+
+ /* Put the plaintext into an S-expression. */
+ err = sexp_build (&plain, NULL, "(data (flags raw) (value %s))", plaintext);
+ if (err)
+ {
+ errtxt = "converting data failed";
+ goto leave;
+ }
+
+ /* Encrypt. */
+ err = _gcry_pk_encrypt (&encr, plain, pkey);
+ if (err)
+ {
+ errtxt = "encrypt failed";
+ goto leave;
+ }
+
+ err = _gcry_mpi_scan(&ref_mpi, GCRYMPI_FMT_HEX, ref_data, 0, NULL);
+ if (err)
+ {
+ errtxt = "converting encrydata to mpi failed";
+ goto leave;
+ }
+
+ /* Extraxt the ciphertext from the returned S-expression. */
+ /*sexp_dump (encr);*/
+ ciphertext = extract_a_from_sexp (encr);
+ if (!ciphertext)
+ {
+ errtxt = "gcry_pk_decrypt returned garbage";
+ goto leave;
+ }
+
+ /* Check that the ciphertext does no match the plaintext. */
+ /* _gcry_log_printmpi ("plaintext", plaintext); */
+ /* _gcry_log_printmpi ("ciphertxt", ciphertext); */
+ if (mpi_cmp (ref_mpi, ciphertext))
+ {
+ errtxt = "ciphertext doesn't match reference data";
+ goto leave;
+ }
+
+ /* Decrypt. */
+ err = _gcry_pk_decrypt (&decr, encr, skey);
+ if (err)
+ {
+ errtxt = "decrypt failed";
+ goto leave;
+ }
+
+ /* Extract the decrypted data from the S-expression. Note that the
+ output of gcry_pk_decrypt depends on whether a flags lists occurs
+ in its input data. Because we passed the output of
+ gcry_pk_encrypt directly to gcry_pk_decrypt, such a flag value
+ won't be there as of today. To be prepared for future changes we
+ take care of it anyway. */
+ tmplist = sexp_find_token (decr, "value", 0);
+ if (tmplist)
+ decr_plaintext = sexp_nth_string (tmplist, 1);
+ else
+ decr_plaintext = sexp_nth_string (decr, 0);
+ if (!decr_plaintext)
+ {
+ errtxt = "decrypt returned no plaintext";
+ goto leave;
+ }
+
+ /* Check that the decrypted plaintext matches the original plaintext. */
+ if (strcmp (plaintext, decr_plaintext))
+ {
+ errtxt = "mismatch";
+ goto leave;
+ }
+
+ leave:
+ sexp_release (tmplist);
+ xfree (decr_plaintext);
+ sexp_release (decr);
+ _gcry_mpi_release (ciphertext);
+ _gcry_mpi_release (ref_mpi);
+ sexp_release (encr);
+ sexp_release (plain);
+ return errtxt;
+}
+
+
+static gpg_err_code_t
+selftests_rsa (selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+ gcry_error_t err;
+ gcry_sexp_t skey = NULL;
+ gcry_sexp_t pkey = NULL;
+
+ /* Convert the S-expressions into the internal representation. */
+ what = "convert";
+ err = sexp_sscan (&skey, NULL, sample_secret_key, strlen (sample_secret_key));
+ if (!err)
+ err = sexp_sscan (&pkey, NULL,
+ sample_public_key, strlen (sample_public_key));
+ if (err)
+ {
+ errtxt = _gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "key consistency";
+ err = _gcry_pk_testkey (skey);
+ if (err)
+ {
+ errtxt = _gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "sign";
+ errtxt = selftest_sign_2048 (pkey, skey);
+ if (errtxt)
+ goto failed;
+
+ what = "encrypt";
+ errtxt = selftest_encr_2048 (pkey, skey);
+ if (errtxt)
+ goto failed;
+
+ sexp_release (pkey);
+ sexp_release (skey);
+ return 0; /* Succeeded. */
+
+ failed:
+ sexp_release (pkey);
+ sexp_release (skey);
+ if (report)
+ report ("pubkey", GCRY_PK_RSA, 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;
+
+ (void)extended;
+
+ switch (algo)
+ {
+ case GCRY_PK_RSA:
+ ec = selftests_rsa (report);
+ break;
+ default:
+ ec = GPG_ERR_PUBKEY_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+
+gcry_pk_spec_t _gcry_pubkey_spec_rsa =
+ {
+ GCRY_PK_RSA, { 0, 1 },
+ (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
+ "RSA", rsa_names,
+ "ne", "nedpqu", "a", "s", "n",
+ rsa_generate,
+ rsa_check_secret_key,
+ rsa_encrypt,
+ rsa_decrypt,
+ rsa_sign,
+ rsa_verify,
+ rsa_get_nbits,
+ run_selftests,
+ compute_keygrip
+ };
diff --git a/comm/third_party/libgcrypt/cipher/salsa20-amd64.S b/comm/third_party/libgcrypt/cipher/salsa20-amd64.S
new file mode 100644
index 0000000000..ae8f27155a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/salsa20-amd64.S
@@ -0,0 +1,940 @@
+/* salsa20-amd64.S - AMD64 implementation of Salsa20
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Based on public domain implementation by D. J. Bernstein at
+ * http://cr.yp.to/snuffle.html
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_SALSA20)
+
+#include "asm-common-amd64.h"
+
+.text
+
+.align 8
+.globl _gcry_salsa20_amd64_keysetup
+ELF(.type _gcry_salsa20_amd64_keysetup,@function;)
+_gcry_salsa20_amd64_keysetup:
+ CFI_STARTPROC();
+ movl 0(%rsi),%r8d
+ movl 4(%rsi),%r9d
+ movl 8(%rsi),%eax
+ movl 12(%rsi),%r10d
+ movl %r8d,20(%rdi)
+ movl %r9d,40(%rdi)
+ movl %eax,60(%rdi)
+ movl %r10d,48(%rdi)
+ cmp $256,%rdx
+ jb .L_kbits128
+.L_kbits256:
+ movl 16(%rsi),%edx
+ movl 20(%rsi),%ecx
+ movl 24(%rsi),%r8d
+ movl 28(%rsi),%esi
+ movl %edx,28(%rdi)
+ movl %ecx,16(%rdi)
+ movl %r8d,36(%rdi)
+ movl %esi,56(%rdi)
+ mov $1634760805,%rsi
+ mov $857760878,%rdx
+ mov $2036477234,%rcx
+ mov $1797285236,%r8
+ movl %esi,0(%rdi)
+ movl %edx,4(%rdi)
+ movl %ecx,8(%rdi)
+ movl %r8d,12(%rdi)
+ jmp .L_keysetupdone
+.L_kbits128:
+ movl 0(%rsi),%edx
+ movl 4(%rsi),%ecx
+ movl 8(%rsi),%r8d
+ movl 12(%rsi),%esi
+ movl %edx,28(%rdi)
+ movl %ecx,16(%rdi)
+ movl %r8d,36(%rdi)
+ movl %esi,56(%rdi)
+ mov $1634760805,%rsi
+ mov $824206446,%rdx
+ mov $2036477238,%rcx
+ mov $1797285236,%r8
+ movl %esi,0(%rdi)
+ movl %edx,4(%rdi)
+ movl %ecx,8(%rdi)
+ movl %r8d,12(%rdi)
+.L_keysetupdone:
+ ret
+ CFI_ENDPROC();
+
+.align 8
+.globl _gcry_salsa20_amd64_ivsetup
+ELF(.type _gcry_salsa20_amd64_ivsetup,@function;)
+_gcry_salsa20_amd64_ivsetup:
+ CFI_STARTPROC();
+ movl 0(%rsi),%r8d
+ movl 4(%rsi),%esi
+ mov $0,%r9
+ mov $0,%rax
+ movl %r8d,24(%rdi)
+ movl %esi,44(%rdi)
+ movl %r9d,32(%rdi)
+ movl %eax,52(%rdi)
+ ret
+ CFI_ENDPROC();
+
+.align 8
+.globl _gcry_salsa20_amd64_encrypt_blocks
+ELF(.type _gcry_salsa20_amd64_encrypt_blocks,@function;)
+_gcry_salsa20_amd64_encrypt_blocks:
+ /*
+ * Modifications to original implementation:
+ * - Number of rounds passing in register %r8 (for Salsa20/12).
+ * - Length is input as number of blocks, so don't handle tail bytes
+ * (this is done in salsa20.c).
+ */
+ CFI_STARTPROC();
+ push %rbx
+ CFI_PUSH(%rbx);
+ shlq $6, %rcx /* blocks to bytes */
+ mov %r8, %rbx
+ mov %rsp,%r11
+ CFI_DEF_CFA_REGISTER(%r11);
+ sub $384,%rsp
+ and $~31,%rsp
+ mov %rdi,%r8
+ mov %rsi,%rsi
+ mov %rdx,%rdi
+ mov %rcx,%rdx
+ cmp $0,%rdx
+ jbe .L_done
+.L_start:
+ cmp $256,%rdx
+ jb .L_bytes_are_64_128_or_192
+ movdqa 0(%r8),%xmm0
+ pshufd $0x55,%xmm0,%xmm1
+ pshufd $0xaa,%xmm0,%xmm2
+ pshufd $0xff,%xmm0,%xmm3
+ pshufd $0x00,%xmm0,%xmm0
+ movdqa %xmm1,0(%rsp)
+ movdqa %xmm2,16(%rsp)
+ movdqa %xmm3,32(%rsp)
+ movdqa %xmm0,48(%rsp)
+ movdqa 16(%r8),%xmm0
+ pshufd $0xaa,%xmm0,%xmm1
+ pshufd $0xff,%xmm0,%xmm2
+ pshufd $0x00,%xmm0,%xmm3
+ pshufd $0x55,%xmm0,%xmm0
+ movdqa %xmm1,64(%rsp)
+ movdqa %xmm2,80(%rsp)
+ movdqa %xmm3,96(%rsp)
+ movdqa %xmm0,112(%rsp)
+ movdqa 32(%r8),%xmm0
+ pshufd $0xff,%xmm0,%xmm1
+ pshufd $0x55,%xmm0,%xmm2
+ pshufd $0xaa,%xmm0,%xmm0
+ movdqa %xmm1,128(%rsp)
+ movdqa %xmm2,144(%rsp)
+ movdqa %xmm0,160(%rsp)
+ movdqa 48(%r8),%xmm0
+ pshufd $0x00,%xmm0,%xmm1
+ pshufd $0xaa,%xmm0,%xmm2
+ pshufd $0xff,%xmm0,%xmm0
+ movdqa %xmm1,176(%rsp)
+ movdqa %xmm2,192(%rsp)
+ movdqa %xmm0,208(%rsp)
+.L_bytesatleast256:
+ movl 32(%r8),%ecx
+ movl 52(%r8),%r9d
+ movl %ecx,224(%rsp)
+ movl %r9d,240(%rsp)
+ add $1,%ecx
+ adc $0,%r9d
+ movl %ecx,4+224(%rsp)
+ movl %r9d,4+240(%rsp)
+ add $1,%ecx
+ adc $0,%r9d
+ movl %ecx,8+224(%rsp)
+ movl %r9d,8+240(%rsp)
+ add $1,%ecx
+ adc $0,%r9d
+ movl %ecx,12+224(%rsp)
+ movl %r9d,12+240(%rsp)
+ add $1,%ecx
+ adc $0,%r9d
+ movl %ecx,32(%r8)
+ movl %r9d,52(%r8)
+ movq %rdx,288(%rsp)
+ mov %rbx,%rdx
+ movdqa 0(%rsp),%xmm0
+ movdqa 16(%rsp),%xmm1
+ movdqa 32(%rsp),%xmm2
+ movdqa 192(%rsp),%xmm3
+ movdqa 208(%rsp),%xmm4
+ movdqa 64(%rsp),%xmm5
+ movdqa 80(%rsp),%xmm6
+ movdqa 112(%rsp),%xmm7
+ movdqa 128(%rsp),%xmm8
+ movdqa 144(%rsp),%xmm9
+ movdqa 160(%rsp),%xmm10
+ movdqa 240(%rsp),%xmm11
+ movdqa 48(%rsp),%xmm12
+ movdqa 96(%rsp),%xmm13
+ movdqa 176(%rsp),%xmm14
+ movdqa 224(%rsp),%xmm15
+.L_mainloop1:
+ movdqa %xmm1,256(%rsp)
+ movdqa %xmm2,272(%rsp)
+ movdqa %xmm13,%xmm1
+ paddd %xmm12,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $7,%xmm1
+ pxor %xmm1,%xmm14
+ psrld $25,%xmm2
+ pxor %xmm2,%xmm14
+ movdqa %xmm7,%xmm1
+ paddd %xmm0,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $7,%xmm1
+ pxor %xmm1,%xmm11
+ psrld $25,%xmm2
+ pxor %xmm2,%xmm11
+ movdqa %xmm12,%xmm1
+ paddd %xmm14,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $9,%xmm1
+ pxor %xmm1,%xmm15
+ psrld $23,%xmm2
+ pxor %xmm2,%xmm15
+ movdqa %xmm0,%xmm1
+ paddd %xmm11,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $9,%xmm1
+ pxor %xmm1,%xmm9
+ psrld $23,%xmm2
+ pxor %xmm2,%xmm9
+ movdqa %xmm14,%xmm1
+ paddd %xmm15,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $13,%xmm1
+ pxor %xmm1,%xmm13
+ psrld $19,%xmm2
+ pxor %xmm2,%xmm13
+ movdqa %xmm11,%xmm1
+ paddd %xmm9,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $13,%xmm1
+ pxor %xmm1,%xmm7
+ psrld $19,%xmm2
+ pxor %xmm2,%xmm7
+ movdqa %xmm15,%xmm1
+ paddd %xmm13,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $18,%xmm1
+ pxor %xmm1,%xmm12
+ psrld $14,%xmm2
+ pxor %xmm2,%xmm12
+ movdqa 256(%rsp),%xmm1
+ movdqa %xmm12,256(%rsp)
+ movdqa %xmm9,%xmm2
+ paddd %xmm7,%xmm2
+ movdqa %xmm2,%xmm12
+ pslld $18,%xmm2
+ pxor %xmm2,%xmm0
+ psrld $14,%xmm12
+ pxor %xmm12,%xmm0
+ movdqa %xmm5,%xmm2
+ paddd %xmm1,%xmm2
+ movdqa %xmm2,%xmm12
+ pslld $7,%xmm2
+ pxor %xmm2,%xmm3
+ psrld $25,%xmm12
+ pxor %xmm12,%xmm3
+ movdqa 272(%rsp),%xmm2
+ movdqa %xmm0,272(%rsp)
+ movdqa %xmm6,%xmm0
+ paddd %xmm2,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $7,%xmm0
+ pxor %xmm0,%xmm4
+ psrld $25,%xmm12
+ pxor %xmm12,%xmm4
+ movdqa %xmm1,%xmm0
+ paddd %xmm3,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $9,%xmm0
+ pxor %xmm0,%xmm10
+ psrld $23,%xmm12
+ pxor %xmm12,%xmm10
+ movdqa %xmm2,%xmm0
+ paddd %xmm4,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $9,%xmm0
+ pxor %xmm0,%xmm8
+ psrld $23,%xmm12
+ pxor %xmm12,%xmm8
+ movdqa %xmm3,%xmm0
+ paddd %xmm10,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $13,%xmm0
+ pxor %xmm0,%xmm5
+ psrld $19,%xmm12
+ pxor %xmm12,%xmm5
+ movdqa %xmm4,%xmm0
+ paddd %xmm8,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $13,%xmm0
+ pxor %xmm0,%xmm6
+ psrld $19,%xmm12
+ pxor %xmm12,%xmm6
+ movdqa %xmm10,%xmm0
+ paddd %xmm5,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $18,%xmm0
+ pxor %xmm0,%xmm1
+ psrld $14,%xmm12
+ pxor %xmm12,%xmm1
+ movdqa 256(%rsp),%xmm0
+ movdqa %xmm1,256(%rsp)
+ movdqa %xmm4,%xmm1
+ paddd %xmm0,%xmm1
+ movdqa %xmm1,%xmm12
+ pslld $7,%xmm1
+ pxor %xmm1,%xmm7
+ psrld $25,%xmm12
+ pxor %xmm12,%xmm7
+ movdqa %xmm8,%xmm1
+ paddd %xmm6,%xmm1
+ movdqa %xmm1,%xmm12
+ pslld $18,%xmm1
+ pxor %xmm1,%xmm2
+ psrld $14,%xmm12
+ pxor %xmm12,%xmm2
+ movdqa 272(%rsp),%xmm12
+ movdqa %xmm2,272(%rsp)
+ movdqa %xmm14,%xmm1
+ paddd %xmm12,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $7,%xmm1
+ pxor %xmm1,%xmm5
+ psrld $25,%xmm2
+ pxor %xmm2,%xmm5
+ movdqa %xmm0,%xmm1
+ paddd %xmm7,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $9,%xmm1
+ pxor %xmm1,%xmm10
+ psrld $23,%xmm2
+ pxor %xmm2,%xmm10
+ movdqa %xmm12,%xmm1
+ paddd %xmm5,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $9,%xmm1
+ pxor %xmm1,%xmm8
+ psrld $23,%xmm2
+ pxor %xmm2,%xmm8
+ movdqa %xmm7,%xmm1
+ paddd %xmm10,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $13,%xmm1
+ pxor %xmm1,%xmm4
+ psrld $19,%xmm2
+ pxor %xmm2,%xmm4
+ movdqa %xmm5,%xmm1
+ paddd %xmm8,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $13,%xmm1
+ pxor %xmm1,%xmm14
+ psrld $19,%xmm2
+ pxor %xmm2,%xmm14
+ movdqa %xmm10,%xmm1
+ paddd %xmm4,%xmm1
+ movdqa %xmm1,%xmm2
+ pslld $18,%xmm1
+ pxor %xmm1,%xmm0
+ psrld $14,%xmm2
+ pxor %xmm2,%xmm0
+ movdqa 256(%rsp),%xmm1
+ movdqa %xmm0,256(%rsp)
+ movdqa %xmm8,%xmm0
+ paddd %xmm14,%xmm0
+ movdqa %xmm0,%xmm2
+ pslld $18,%xmm0
+ pxor %xmm0,%xmm12
+ psrld $14,%xmm2
+ pxor %xmm2,%xmm12
+ movdqa %xmm11,%xmm0
+ paddd %xmm1,%xmm0
+ movdqa %xmm0,%xmm2
+ pslld $7,%xmm0
+ pxor %xmm0,%xmm6
+ psrld $25,%xmm2
+ pxor %xmm2,%xmm6
+ movdqa 272(%rsp),%xmm2
+ movdqa %xmm12,272(%rsp)
+ movdqa %xmm3,%xmm0
+ paddd %xmm2,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $7,%xmm0
+ pxor %xmm0,%xmm13
+ psrld $25,%xmm12
+ pxor %xmm12,%xmm13
+ movdqa %xmm1,%xmm0
+ paddd %xmm6,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $9,%xmm0
+ pxor %xmm0,%xmm15
+ psrld $23,%xmm12
+ pxor %xmm12,%xmm15
+ movdqa %xmm2,%xmm0
+ paddd %xmm13,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $9,%xmm0
+ pxor %xmm0,%xmm9
+ psrld $23,%xmm12
+ pxor %xmm12,%xmm9
+ movdqa %xmm6,%xmm0
+ paddd %xmm15,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $13,%xmm0
+ pxor %xmm0,%xmm11
+ psrld $19,%xmm12
+ pxor %xmm12,%xmm11
+ movdqa %xmm13,%xmm0
+ paddd %xmm9,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $13,%xmm0
+ pxor %xmm0,%xmm3
+ psrld $19,%xmm12
+ pxor %xmm12,%xmm3
+ movdqa %xmm15,%xmm0
+ paddd %xmm11,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $18,%xmm0
+ pxor %xmm0,%xmm1
+ psrld $14,%xmm12
+ pxor %xmm12,%xmm1
+ movdqa %xmm9,%xmm0
+ paddd %xmm3,%xmm0
+ movdqa %xmm0,%xmm12
+ pslld $18,%xmm0
+ pxor %xmm0,%xmm2
+ psrld $14,%xmm12
+ pxor %xmm12,%xmm2
+ movdqa 256(%rsp),%xmm12
+ movdqa 272(%rsp),%xmm0
+ sub $2,%rdx
+ ja .L_mainloop1
+ paddd 48(%rsp),%xmm12
+ paddd 112(%rsp),%xmm7
+ paddd 160(%rsp),%xmm10
+ paddd 208(%rsp),%xmm4
+ movd %xmm12,%rdx
+ movd %xmm7,%rcx
+ movd %xmm10,%r9
+ movd %xmm4,%rax
+ pshufd $0x39,%xmm12,%xmm12
+ pshufd $0x39,%xmm7,%xmm7
+ pshufd $0x39,%xmm10,%xmm10
+ pshufd $0x39,%xmm4,%xmm4
+ xorl 0(%rsi),%edx
+ xorl 4(%rsi),%ecx
+ xorl 8(%rsi),%r9d
+ xorl 12(%rsi),%eax
+ movl %edx,0(%rdi)
+ movl %ecx,4(%rdi)
+ movl %r9d,8(%rdi)
+ movl %eax,12(%rdi)
+ movd %xmm12,%rdx
+ movd %xmm7,%rcx
+ movd %xmm10,%r9
+ movd %xmm4,%rax
+ pshufd $0x39,%xmm12,%xmm12
+ pshufd $0x39,%xmm7,%xmm7
+ pshufd $0x39,%xmm10,%xmm10
+ pshufd $0x39,%xmm4,%xmm4
+ xorl 64(%rsi),%edx
+ xorl 68(%rsi),%ecx
+ xorl 72(%rsi),%r9d
+ xorl 76(%rsi),%eax
+ movl %edx,64(%rdi)
+ movl %ecx,68(%rdi)
+ movl %r9d,72(%rdi)
+ movl %eax,76(%rdi)
+ movd %xmm12,%rdx
+ movd %xmm7,%rcx
+ movd %xmm10,%r9
+ movd %xmm4,%rax
+ pshufd $0x39,%xmm12,%xmm12
+ pshufd $0x39,%xmm7,%xmm7
+ pshufd $0x39,%xmm10,%xmm10
+ pshufd $0x39,%xmm4,%xmm4
+ xorl 128(%rsi),%edx
+ xorl 132(%rsi),%ecx
+ xorl 136(%rsi),%r9d
+ xorl 140(%rsi),%eax
+ movl %edx,128(%rdi)
+ movl %ecx,132(%rdi)
+ movl %r9d,136(%rdi)
+ movl %eax,140(%rdi)
+ movd %xmm12,%rdx
+ movd %xmm7,%rcx
+ movd %xmm10,%r9
+ movd %xmm4,%rax
+ xorl 192(%rsi),%edx
+ xorl 196(%rsi),%ecx
+ xorl 200(%rsi),%r9d
+ xorl 204(%rsi),%eax
+ movl %edx,192(%rdi)
+ movl %ecx,196(%rdi)
+ movl %r9d,200(%rdi)
+ movl %eax,204(%rdi)
+ paddd 176(%rsp),%xmm14
+ paddd 0(%rsp),%xmm0
+ paddd 64(%rsp),%xmm5
+ paddd 128(%rsp),%xmm8
+ movd %xmm14,%rdx
+ movd %xmm0,%rcx
+ movd %xmm5,%r9
+ movd %xmm8,%rax
+ pshufd $0x39,%xmm14,%xmm14
+ pshufd $0x39,%xmm0,%xmm0
+ pshufd $0x39,%xmm5,%xmm5
+ pshufd $0x39,%xmm8,%xmm8
+ xorl 16(%rsi),%edx
+ xorl 20(%rsi),%ecx
+ xorl 24(%rsi),%r9d
+ xorl 28(%rsi),%eax
+ movl %edx,16(%rdi)
+ movl %ecx,20(%rdi)
+ movl %r9d,24(%rdi)
+ movl %eax,28(%rdi)
+ movd %xmm14,%rdx
+ movd %xmm0,%rcx
+ movd %xmm5,%r9
+ movd %xmm8,%rax
+ pshufd $0x39,%xmm14,%xmm14
+ pshufd $0x39,%xmm0,%xmm0
+ pshufd $0x39,%xmm5,%xmm5
+ pshufd $0x39,%xmm8,%xmm8
+ xorl 80(%rsi),%edx
+ xorl 84(%rsi),%ecx
+ xorl 88(%rsi),%r9d
+ xorl 92(%rsi),%eax
+ movl %edx,80(%rdi)
+ movl %ecx,84(%rdi)
+ movl %r9d,88(%rdi)
+ movl %eax,92(%rdi)
+ movd %xmm14,%rdx
+ movd %xmm0,%rcx
+ movd %xmm5,%r9
+ movd %xmm8,%rax
+ pshufd $0x39,%xmm14,%xmm14
+ pshufd $0x39,%xmm0,%xmm0
+ pshufd $0x39,%xmm5,%xmm5
+ pshufd $0x39,%xmm8,%xmm8
+ xorl 144(%rsi),%edx
+ xorl 148(%rsi),%ecx
+ xorl 152(%rsi),%r9d
+ xorl 156(%rsi),%eax
+ movl %edx,144(%rdi)
+ movl %ecx,148(%rdi)
+ movl %r9d,152(%rdi)
+ movl %eax,156(%rdi)
+ movd %xmm14,%rdx
+ movd %xmm0,%rcx
+ movd %xmm5,%r9
+ movd %xmm8,%rax
+ xorl 208(%rsi),%edx
+ xorl 212(%rsi),%ecx
+ xorl 216(%rsi),%r9d
+ xorl 220(%rsi),%eax
+ movl %edx,208(%rdi)
+ movl %ecx,212(%rdi)
+ movl %r9d,216(%rdi)
+ movl %eax,220(%rdi)
+ paddd 224(%rsp),%xmm15
+ paddd 240(%rsp),%xmm11
+ paddd 16(%rsp),%xmm1
+ paddd 80(%rsp),%xmm6
+ movd %xmm15,%rdx
+ movd %xmm11,%rcx
+ movd %xmm1,%r9
+ movd %xmm6,%rax
+ pshufd $0x39,%xmm15,%xmm15
+ pshufd $0x39,%xmm11,%xmm11
+ pshufd $0x39,%xmm1,%xmm1
+ pshufd $0x39,%xmm6,%xmm6
+ xorl 32(%rsi),%edx
+ xorl 36(%rsi),%ecx
+ xorl 40(%rsi),%r9d
+ xorl 44(%rsi),%eax
+ movl %edx,32(%rdi)
+ movl %ecx,36(%rdi)
+ movl %r9d,40(%rdi)
+ movl %eax,44(%rdi)
+ movd %xmm15,%rdx
+ movd %xmm11,%rcx
+ movd %xmm1,%r9
+ movd %xmm6,%rax
+ pshufd $0x39,%xmm15,%xmm15
+ pshufd $0x39,%xmm11,%xmm11
+ pshufd $0x39,%xmm1,%xmm1
+ pshufd $0x39,%xmm6,%xmm6
+ xorl 96(%rsi),%edx
+ xorl 100(%rsi),%ecx
+ xorl 104(%rsi),%r9d
+ xorl 108(%rsi),%eax
+ movl %edx,96(%rdi)
+ movl %ecx,100(%rdi)
+ movl %r9d,104(%rdi)
+ movl %eax,108(%rdi)
+ movd %xmm15,%rdx
+ movd %xmm11,%rcx
+ movd %xmm1,%r9
+ movd %xmm6,%rax
+ pshufd $0x39,%xmm15,%xmm15
+ pshufd $0x39,%xmm11,%xmm11
+ pshufd $0x39,%xmm1,%xmm1
+ pshufd $0x39,%xmm6,%xmm6
+ xorl 160(%rsi),%edx
+ xorl 164(%rsi),%ecx
+ xorl 168(%rsi),%r9d
+ xorl 172(%rsi),%eax
+ movl %edx,160(%rdi)
+ movl %ecx,164(%rdi)
+ movl %r9d,168(%rdi)
+ movl %eax,172(%rdi)
+ movd %xmm15,%rdx
+ movd %xmm11,%rcx
+ movd %xmm1,%r9
+ movd %xmm6,%rax
+ xorl 224(%rsi),%edx
+ xorl 228(%rsi),%ecx
+ xorl 232(%rsi),%r9d
+ xorl 236(%rsi),%eax
+ movl %edx,224(%rdi)
+ movl %ecx,228(%rdi)
+ movl %r9d,232(%rdi)
+ movl %eax,236(%rdi)
+ paddd 96(%rsp),%xmm13
+ paddd 144(%rsp),%xmm9
+ paddd 192(%rsp),%xmm3
+ paddd 32(%rsp),%xmm2
+ movd %xmm13,%rdx
+ movd %xmm9,%rcx
+ movd %xmm3,%r9
+ movd %xmm2,%rax
+ pshufd $0x39,%xmm13,%xmm13
+ pshufd $0x39,%xmm9,%xmm9
+ pshufd $0x39,%xmm3,%xmm3
+ pshufd $0x39,%xmm2,%xmm2
+ xorl 48(%rsi),%edx
+ xorl 52(%rsi),%ecx
+ xorl 56(%rsi),%r9d
+ xorl 60(%rsi),%eax
+ movl %edx,48(%rdi)
+ movl %ecx,52(%rdi)
+ movl %r9d,56(%rdi)
+ movl %eax,60(%rdi)
+ movd %xmm13,%rdx
+ movd %xmm9,%rcx
+ movd %xmm3,%r9
+ movd %xmm2,%rax
+ pshufd $0x39,%xmm13,%xmm13
+ pshufd $0x39,%xmm9,%xmm9
+ pshufd $0x39,%xmm3,%xmm3
+ pshufd $0x39,%xmm2,%xmm2
+ xorl 112(%rsi),%edx
+ xorl 116(%rsi),%ecx
+ xorl 120(%rsi),%r9d
+ xorl 124(%rsi),%eax
+ movl %edx,112(%rdi)
+ movl %ecx,116(%rdi)
+ movl %r9d,120(%rdi)
+ movl %eax,124(%rdi)
+ movd %xmm13,%rdx
+ movd %xmm9,%rcx
+ movd %xmm3,%r9
+ movd %xmm2,%rax
+ pshufd $0x39,%xmm13,%xmm13
+ pshufd $0x39,%xmm9,%xmm9
+ pshufd $0x39,%xmm3,%xmm3
+ pshufd $0x39,%xmm2,%xmm2
+ xorl 176(%rsi),%edx
+ xorl 180(%rsi),%ecx
+ xorl 184(%rsi),%r9d
+ xorl 188(%rsi),%eax
+ movl %edx,176(%rdi)
+ movl %ecx,180(%rdi)
+ movl %r9d,184(%rdi)
+ movl %eax,188(%rdi)
+ movd %xmm13,%rdx
+ movd %xmm9,%rcx
+ movd %xmm3,%r9
+ movd %xmm2,%rax
+ xorl 240(%rsi),%edx
+ xorl 244(%rsi),%ecx
+ xorl 248(%rsi),%r9d
+ xorl 252(%rsi),%eax
+ movl %edx,240(%rdi)
+ movl %ecx,244(%rdi)
+ movl %r9d,248(%rdi)
+ movl %eax,252(%rdi)
+ movq 288(%rsp),%rdx
+ sub $256,%rdx
+ add $256,%rsi
+ add $256,%rdi
+ cmp $256,%rdx
+ jae .L_bytesatleast256
+ cmp $0,%rdx
+ jbe .L_done
+.L_bytes_are_64_128_or_192:
+ movq %rdx,288(%rsp)
+ movdqa 0(%r8),%xmm0
+ movdqa 16(%r8),%xmm1
+ movdqa 32(%r8),%xmm2
+ movdqa 48(%r8),%xmm3
+ movdqa %xmm1,%xmm4
+ mov %rbx,%rdx
+.L_mainloop2:
+ paddd %xmm0,%xmm4
+ movdqa %xmm0,%xmm5
+ movdqa %xmm4,%xmm6
+ pslld $7,%xmm4
+ psrld $25,%xmm6
+ pxor %xmm4,%xmm3
+ pxor %xmm6,%xmm3
+ paddd %xmm3,%xmm5
+ movdqa %xmm3,%xmm4
+ movdqa %xmm5,%xmm6
+ pslld $9,%xmm5
+ psrld $23,%xmm6
+ pxor %xmm5,%xmm2
+ pshufd $0x93,%xmm3,%xmm3
+ pxor %xmm6,%xmm2
+ paddd %xmm2,%xmm4
+ movdqa %xmm2,%xmm5
+ movdqa %xmm4,%xmm6
+ pslld $13,%xmm4
+ psrld $19,%xmm6
+ pxor %xmm4,%xmm1
+ pshufd $0x4e,%xmm2,%xmm2
+ pxor %xmm6,%xmm1
+ paddd %xmm1,%xmm5
+ movdqa %xmm3,%xmm4
+ movdqa %xmm5,%xmm6
+ pslld $18,%xmm5
+ psrld $14,%xmm6
+ pxor %xmm5,%xmm0
+ pshufd $0x39,%xmm1,%xmm1
+ pxor %xmm6,%xmm0
+ paddd %xmm0,%xmm4
+ movdqa %xmm0,%xmm5
+ movdqa %xmm4,%xmm6
+ pslld $7,%xmm4
+ psrld $25,%xmm6
+ pxor %xmm4,%xmm1
+ pxor %xmm6,%xmm1
+ paddd %xmm1,%xmm5
+ movdqa %xmm1,%xmm4
+ movdqa %xmm5,%xmm6
+ pslld $9,%xmm5
+ psrld $23,%xmm6
+ pxor %xmm5,%xmm2
+ pshufd $0x93,%xmm1,%xmm1
+ pxor %xmm6,%xmm2
+ paddd %xmm2,%xmm4
+ movdqa %xmm2,%xmm5
+ movdqa %xmm4,%xmm6
+ pslld $13,%xmm4
+ psrld $19,%xmm6
+ pxor %xmm4,%xmm3
+ pshufd $0x4e,%xmm2,%xmm2
+ pxor %xmm6,%xmm3
+ paddd %xmm3,%xmm5
+ movdqa %xmm1,%xmm4
+ movdqa %xmm5,%xmm6
+ pslld $18,%xmm5
+ psrld $14,%xmm6
+ pxor %xmm5,%xmm0
+ pshufd $0x39,%xmm3,%xmm3
+ pxor %xmm6,%xmm0
+ paddd %xmm0,%xmm4
+ movdqa %xmm0,%xmm5
+ movdqa %xmm4,%xmm6
+ pslld $7,%xmm4
+ psrld $25,%xmm6
+ pxor %xmm4,%xmm3
+ pxor %xmm6,%xmm3
+ paddd %xmm3,%xmm5
+ movdqa %xmm3,%xmm4
+ movdqa %xmm5,%xmm6
+ pslld $9,%xmm5
+ psrld $23,%xmm6
+ pxor %xmm5,%xmm2
+ pshufd $0x93,%xmm3,%xmm3
+ pxor %xmm6,%xmm2
+ paddd %xmm2,%xmm4
+ movdqa %xmm2,%xmm5
+ movdqa %xmm4,%xmm6
+ pslld $13,%xmm4
+ psrld $19,%xmm6
+ pxor %xmm4,%xmm1
+ pshufd $0x4e,%xmm2,%xmm2
+ pxor %xmm6,%xmm1
+ paddd %xmm1,%xmm5
+ movdqa %xmm3,%xmm4
+ movdqa %xmm5,%xmm6
+ pslld $18,%xmm5
+ psrld $14,%xmm6
+ pxor %xmm5,%xmm0
+ pshufd $0x39,%xmm1,%xmm1
+ pxor %xmm6,%xmm0
+ paddd %xmm0,%xmm4
+ movdqa %xmm0,%xmm5
+ movdqa %xmm4,%xmm6
+ pslld $7,%xmm4
+ psrld $25,%xmm6
+ pxor %xmm4,%xmm1
+ pxor %xmm6,%xmm1
+ paddd %xmm1,%xmm5
+ movdqa %xmm1,%xmm4
+ movdqa %xmm5,%xmm6
+ pslld $9,%xmm5
+ psrld $23,%xmm6
+ pxor %xmm5,%xmm2
+ pshufd $0x93,%xmm1,%xmm1
+ pxor %xmm6,%xmm2
+ paddd %xmm2,%xmm4
+ movdqa %xmm2,%xmm5
+ movdqa %xmm4,%xmm6
+ pslld $13,%xmm4
+ psrld $19,%xmm6
+ pxor %xmm4,%xmm3
+ pshufd $0x4e,%xmm2,%xmm2
+ pxor %xmm6,%xmm3
+ sub $4,%rdx
+ paddd %xmm3,%xmm5
+ movdqa %xmm1,%xmm4
+ movdqa %xmm5,%xmm6
+ pslld $18,%xmm5
+ pxor %xmm7,%xmm7
+ psrld $14,%xmm6
+ pxor %xmm5,%xmm0
+ pshufd $0x39,%xmm3,%xmm3
+ pxor %xmm6,%xmm0
+ ja .L_mainloop2
+ paddd 0(%r8),%xmm0
+ paddd 16(%r8),%xmm1
+ paddd 32(%r8),%xmm2
+ paddd 48(%r8),%xmm3
+ movd %xmm0,%rdx
+ movd %xmm1,%rcx
+ movd %xmm2,%rax
+ movd %xmm3,%r10
+ pshufd $0x39,%xmm0,%xmm0
+ pshufd $0x39,%xmm1,%xmm1
+ pshufd $0x39,%xmm2,%xmm2
+ pshufd $0x39,%xmm3,%xmm3
+ xorl 0(%rsi),%edx
+ xorl 48(%rsi),%ecx
+ xorl 32(%rsi),%eax
+ xorl 16(%rsi),%r10d
+ movl %edx,0(%rdi)
+ movl %ecx,48(%rdi)
+ movl %eax,32(%rdi)
+ movl %r10d,16(%rdi)
+ movd %xmm0,%rdx
+ movd %xmm1,%rcx
+ movd %xmm2,%rax
+ movd %xmm3,%r10
+ pshufd $0x39,%xmm0,%xmm0
+ pshufd $0x39,%xmm1,%xmm1
+ pshufd $0x39,%xmm2,%xmm2
+ pshufd $0x39,%xmm3,%xmm3
+ xorl 20(%rsi),%edx
+ xorl 4(%rsi),%ecx
+ xorl 52(%rsi),%eax
+ xorl 36(%rsi),%r10d
+ movl %edx,20(%rdi)
+ movl %ecx,4(%rdi)
+ movl %eax,52(%rdi)
+ movl %r10d,36(%rdi)
+ movd %xmm0,%rdx
+ movd %xmm1,%rcx
+ movd %xmm2,%rax
+ movd %xmm3,%r10
+ pshufd $0x39,%xmm0,%xmm0
+ pshufd $0x39,%xmm1,%xmm1
+ pshufd $0x39,%xmm2,%xmm2
+ pshufd $0x39,%xmm3,%xmm3
+ xorl 40(%rsi),%edx
+ xorl 24(%rsi),%ecx
+ xorl 8(%rsi),%eax
+ xorl 56(%rsi),%r10d
+ movl %edx,40(%rdi)
+ movl %ecx,24(%rdi)
+ movl %eax,8(%rdi)
+ movl %r10d,56(%rdi)
+ movd %xmm0,%rdx
+ movd %xmm1,%rcx
+ movd %xmm2,%rax
+ movd %xmm3,%r10
+ xorl 60(%rsi),%edx
+ xorl 44(%rsi),%ecx
+ xorl 28(%rsi),%eax
+ xorl 12(%rsi),%r10d
+ movl %edx,60(%rdi)
+ movl %ecx,44(%rdi)
+ movl %eax,28(%rdi)
+ movl %r10d,12(%rdi)
+ movq 288(%rsp),%rdx
+ movl 32(%r8),%ecx
+ movl 52(%r8),%eax
+ add $1,%ecx
+ adc $0,%eax
+ movl %ecx,32(%r8)
+ movl %eax,52(%r8)
+ cmp $64,%rdx
+ ja .L_bytes_are_128_or_192
+.L_done:
+ CFI_REMEMBER_STATE();
+ mov %r11,%rax
+ sub %rsp,%rax
+ mov %r11,%rsp
+ CFI_REGISTER(%r11, %rsp)
+ CFI_DEF_CFA_REGISTER(%rsp)
+ pop %rbx
+ CFI_POP(%rbx)
+ ret
+ CFI_RESTORE_STATE();
+.L_bytes_are_128_or_192:
+ sub $64,%rdx
+ add $64,%rdi
+ add $64,%rsi
+ jmp .L_bytes_are_64_128_or_192
+ CFI_ENDPROC();
+ELF(.size _gcry_salsa20_amd64_encrypt_blocks,.-_gcry_salsa20_amd64_encrypt_blocks;)
+
+#endif /*defined(USE_SALSA20)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/salsa20-armv7-neon.S b/comm/third_party/libgcrypt/cipher/salsa20-armv7-neon.S
new file mode 100644
index 0000000000..3686e3fa6f
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/salsa20-armv7-neon.S
@@ -0,0 +1,899 @@
+/* salsa-armv7-neon.S - ARM NEON implementation of Salsa20 cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_NEON) && defined(USE_SALSA20)
+
+/*
+ * Based on public domain implementation from SUPERCOP benchmarking framework
+ * by Peter Schwabe and D. J. Bernstein. Paper about the implementation at:
+ * http://cryptojedi.org/papers/#neoncrypto
+ */
+
+.syntax unified
+.arm
+.fpu neon
+.text
+
+.align 2
+.globl _gcry_arm_neon_salsa20_encrypt
+.type _gcry_arm_neon_salsa20_encrypt,%function;
+_gcry_arm_neon_salsa20_encrypt:
+ /* Modifications:
+ * - arguments changed to (void *c, const void *m, unsigned int nblks,
+ * void *ctx, unsigned int rounds) from (void *c, const void *m,
+ * unsigned long long mlen, const void *n, const void *k)
+ * - nonce and key read from 'ctx' as well as sigma and counter.
+ * - read in counter from 'ctx' at the start.
+ * - update counter in 'ctx' at the end.
+ * - length is input as number of blocks, so don't handle tail bytes
+ * (this is done in salsa20.c).
+ */
+ lsl r2,r2,#6
+ vpush {q4,q5,q6,q7}
+ mov r12,sp
+ sub sp,sp,#352
+ and sp,sp,#0xffffffe0
+ strd r4,[sp,#0]
+ strd r6,[sp,#8]
+ strd r8,[sp,#16]
+ strd r10,[sp,#24]
+ str r14,[sp,#224]
+ str r12,[sp,#228]
+ str r0,[sp,#232]
+ str r1,[sp,#236]
+ str r2,[sp,#240]
+ ldr r4,[r12,#64]
+ str r4,[sp,#244]
+ mov r2,r3
+ add r3,r2,#48
+ vld1.8 {q3},[r2]
+ add r0,r2,#32
+ add r14,r2,#40
+ vmov.i64 q3,#0xff
+ str r14,[sp,#160]
+ ldrd r8,[r2,#4]
+ vld1.8 {d0},[r0]
+ ldrd r4,[r2,#20]
+ vld1.8 {d8-d9},[r2]!
+ ldrd r6,[r0,#0]
+ vmov d4,d9
+ ldr r0,[r14]
+ vrev64.i32 d0,d0
+ ldr r1,[r14,#4]
+ vld1.8 {d10-d11},[r2]
+ strd r6,[sp,#32]
+ sub r2,r2,#16
+ strd r0,[sp,#40]
+ vmov d5,d11
+ strd r8,[sp,#48]
+ vext.32 d1,d0,d10,#1
+ strd r4,[sp,#56]
+ ldr r1,[r2,#0]
+ vshr.u32 q3,q3,#7
+ ldr r4,[r2,#12]
+ vext.32 d3,d11,d9,#1
+ ldr r11,[r2,#16]
+ vext.32 d2,d8,d0,#1
+ ldr r8,[r2,#28]
+ vext.32 d0,d10,d8,#1
+ ldr r0,[r3,#0]
+ add r2,r2,#44
+ vmov q4,q3
+ vld1.8 {d6-d7},[r14]
+ vadd.i64 q3,q3,q4
+ ldr r5,[r3,#4]
+ add r12,sp,#256
+ vst1.8 {d4-d5},[r12,: 128]
+ ldr r10,[r3,#8]
+ add r14,sp,#272
+ vst1.8 {d2-d3},[r14,: 128]
+ ldr r9,[r3,#12]
+ vld1.8 {d2-d3},[r3]
+ strd r0,[sp,#64]
+ ldr r0,[sp,#240]
+ strd r4,[sp,#72]
+ strd r10,[sp,#80]
+ strd r8,[sp,#88]
+ nop
+ cmp r0,#192
+ blo .L_mlenlowbelow192
+.L_mlenatleast192:
+ ldrd r2,[sp,#48]
+ vext.32 d7,d6,d6,#1
+ vmov q8,q1
+ ldrd r6,[sp,#32]
+ vld1.8 {d18-d19},[r12,: 128]
+ vmov q10,q0
+ str r0,[sp,#240]
+ vext.32 d4,d7,d19,#1
+ vmov q11,q8
+ vext.32 d10,d18,d7,#1
+ vadd.i64 q3,q3,q4
+ ldrd r0,[sp,#64]
+ vld1.8 {d24-d25},[r14,: 128]
+ vmov d5,d24
+ add r8,sp,#288
+ ldrd r4,[sp,#72]
+ vmov d11,d25
+ add r9,sp,#304
+ ldrd r10,[sp,#80]
+ vst1.8 {d4-d5},[r8,: 128]
+ strd r2,[sp,#96]
+ vext.32 d7,d6,d6,#1
+ vmov q13,q10
+ strd r6,[sp,#104]
+ vmov d13,d24
+ vst1.8 {d10-d11},[r9,: 128]
+ add r2,sp,#320
+ vext.32 d12,d7,d19,#1
+ vmov d15,d25
+ add r6,sp,#336
+ ldr r12,[sp,#244]
+ vext.32 d14,d18,d7,#1
+ vadd.i64 q3,q3,q4
+ ldrd r8,[sp,#88]
+ vst1.8 {d12-d13},[r2,: 128]
+ ldrd r2,[sp,#56]
+ vst1.8 {d14-d15},[r6,: 128]
+ ldrd r6,[sp,#40]
+.L_mainloop2:
+ str r12,[sp,#248]
+ vadd.i32 q4,q10,q8
+ vadd.i32 q9,q13,q11
+ add r12,r0,r2
+ add r14,r5,r1
+ vshl.i32 q12,q4,#7
+ vshl.i32 q14,q9,#7
+ vshr.u32 q4,q4,#25
+ vshr.u32 q9,q9,#25
+ eor r4,r4,r12,ROR #25
+ eor r7,r7,r14,ROR #25
+ add r12,r4,r0
+ add r14,r7,r5
+ veor q5,q5,q12
+ veor q7,q7,q14
+ veor q4,q5,q4
+ veor q5,q7,q9
+ eor r6,r6,r12,ROR #23
+ eor r3,r3,r14,ROR #23
+ add r12,r6,r4
+ str r7,[sp,#116]
+ add r7,r3,r7
+ ldr r14,[sp,#108]
+ vadd.i32 q7,q8,q4
+ vadd.i32 q9,q11,q5
+ vshl.i32 q12,q7,#9
+ vshl.i32 q14,q9,#9
+ vshr.u32 q7,q7,#23
+ vshr.u32 q9,q9,#23
+ veor q2,q2,q12
+ veor q6,q6,q14
+ veor q2,q2,q7
+ veor q6,q6,q9
+ eor r2,r2,r12,ROR #19
+ str r2,[sp,#120]
+ eor r1,r1,r7,ROR #19
+ ldr r7,[sp,#96]
+ add r2,r2,r6
+ str r6,[sp,#112]
+ add r6,r1,r3
+ ldr r12,[sp,#104]
+ vadd.i32 q7,q4,q2
+ vext.32 q4,q4,q4,#3
+ vadd.i32 q9,q5,q6
+ vshl.i32 q12,q7,#13
+ vext.32 q5,q5,q5,#3
+ vshl.i32 q14,q9,#13
+ eor r0,r0,r2,ROR #14
+ eor r2,r5,r6,ROR #14
+ str r3,[sp,#124]
+ add r3,r10,r12
+ ldr r5,[sp,#100]
+ add r6,r9,r11
+ vshr.u32 q7,q7,#19
+ vshr.u32 q9,q9,#19
+ veor q10,q10,q12
+ veor q12,q13,q14
+ eor r8,r8,r3,ROR #25
+ eor r3,r5,r6,ROR #25
+ add r5,r8,r10
+ add r6,r3,r9
+ veor q7,q10,q7
+ veor q9,q12,q9
+ eor r5,r7,r5,ROR #23
+ eor r6,r14,r6,ROR #23
+ add r7,r5,r8
+ add r14,r6,r3
+ vadd.i32 q10,q2,q7
+ vswp d4,d5
+ vadd.i32 q12,q6,q9
+ vshl.i32 q13,q10,#18
+ vswp d12,d13
+ vshl.i32 q14,q12,#18
+ eor r7,r12,r7,ROR #19
+ eor r11,r11,r14,ROR #19
+ add r12,r7,r5
+ add r14,r11,r6
+ vshr.u32 q10,q10,#14
+ vext.32 q7,q7,q7,#1
+ vshr.u32 q12,q12,#14
+ veor q8,q8,q13
+ vext.32 q9,q9,q9,#1
+ veor q11,q11,q14
+ eor r10,r10,r12,ROR #14
+ eor r9,r9,r14,ROR #14
+ add r12,r0,r3
+ add r14,r2,r4
+ veor q8,q8,q10
+ veor q10,q11,q12
+ eor r1,r1,r12,ROR #25
+ eor r7,r7,r14,ROR #25
+ add r12,r1,r0
+ add r14,r7,r2
+ vadd.i32 q11,q4,q8
+ vadd.i32 q12,q5,q10
+ vshl.i32 q13,q11,#7
+ vshl.i32 q14,q12,#7
+ eor r5,r5,r12,ROR #23
+ eor r6,r6,r14,ROR #23
+ vshr.u32 q11,q11,#25
+ vshr.u32 q12,q12,#25
+ add r12,r5,r1
+ add r14,r6,r7
+ veor q7,q7,q13
+ veor q9,q9,q14
+ veor q7,q7,q11
+ veor q9,q9,q12
+ vadd.i32 q11,q8,q7
+ vadd.i32 q12,q10,q9
+ vshl.i32 q13,q11,#9
+ vshl.i32 q14,q12,#9
+ eor r3,r3,r12,ROR #19
+ str r7,[sp,#104]
+ eor r4,r4,r14,ROR #19
+ ldr r7,[sp,#112]
+ add r12,r3,r5
+ str r6,[sp,#108]
+ add r6,r4,r6
+ ldr r14,[sp,#116]
+ eor r0,r0,r12,ROR #14
+ str r5,[sp,#96]
+ eor r5,r2,r6,ROR #14
+ ldr r2,[sp,#120]
+ vshr.u32 q11,q11,#23
+ vshr.u32 q12,q12,#23
+ veor q2,q2,q13
+ veor q6,q6,q14
+ veor q2,q2,q11
+ veor q6,q6,q12
+ add r6,r10,r14
+ add r12,r9,r8
+ vadd.i32 q11,q7,q2
+ vext.32 q7,q7,q7,#3
+ vadd.i32 q12,q9,q6
+ vshl.i32 q13,q11,#13
+ vext.32 q9,q9,q9,#3
+ vshl.i32 q14,q12,#13
+ vshr.u32 q11,q11,#19
+ vshr.u32 q12,q12,#19
+ eor r11,r11,r6,ROR #25
+ eor r2,r2,r12,ROR #25
+ add r6,r11,r10
+ str r3,[sp,#100]
+ add r3,r2,r9
+ ldr r12,[sp,#124]
+ veor q4,q4,q13
+ veor q5,q5,q14
+ veor q4,q4,q11
+ veor q5,q5,q12
+ eor r6,r7,r6,ROR #23
+ eor r3,r12,r3,ROR #23
+ add r7,r6,r11
+ add r12,r3,r2
+ vadd.i32 q11,q2,q4
+ vswp d4,d5
+ vadd.i32 q12,q6,q5
+ vshl.i32 q13,q11,#18
+ vswp d12,d13
+ vshl.i32 q14,q12,#18
+ eor r7,r14,r7,ROR #19
+ eor r8,r8,r12,ROR #19
+ add r12,r7,r6
+ add r14,r8,r3
+ vshr.u32 q11,q11,#14
+ vext.32 q4,q4,q4,#1
+ vshr.u32 q12,q12,#14
+ veor q8,q8,q13
+ vext.32 q5,q5,q5,#1
+ veor q10,q10,q14
+ eor r10,r10,r12,ROR #14
+ veor q8,q8,q11
+ eor r9,r9,r14,ROR #14
+ veor q10,q10,q12
+ vadd.i32 q11,q7,q8
+ vadd.i32 q12,q9,q10
+ add r12,r0,r2
+ add r14,r5,r1
+ vshl.i32 q13,q11,#7
+ vshl.i32 q14,q12,#7
+ vshr.u32 q11,q11,#25
+ vshr.u32 q12,q12,#25
+ eor r4,r4,r12,ROR #25
+ eor r7,r7,r14,ROR #25
+ add r12,r4,r0
+ add r14,r7,r5
+ veor q4,q4,q13
+ veor q5,q5,q14
+ veor q4,q4,q11
+ veor q5,q5,q12
+ eor r6,r6,r12,ROR #23
+ eor r3,r3,r14,ROR #23
+ add r12,r6,r4
+ str r7,[sp,#116]
+ add r7,r3,r7
+ ldr r14,[sp,#108]
+ vadd.i32 q11,q8,q4
+ vadd.i32 q12,q10,q5
+ vshl.i32 q13,q11,#9
+ vshl.i32 q14,q12,#9
+ vshr.u32 q11,q11,#23
+ vshr.u32 q12,q12,#23
+ veor q2,q2,q13
+ veor q6,q6,q14
+ veor q2,q2,q11
+ veor q6,q6,q12
+ eor r2,r2,r12,ROR #19
+ str r2,[sp,#120]
+ eor r1,r1,r7,ROR #19
+ ldr r7,[sp,#96]
+ add r2,r2,r6
+ str r6,[sp,#112]
+ add r6,r1,r3
+ ldr r12,[sp,#104]
+ vadd.i32 q11,q4,q2
+ vext.32 q4,q4,q4,#3
+ vadd.i32 q12,q5,q6
+ vshl.i32 q13,q11,#13
+ vext.32 q5,q5,q5,#3
+ vshl.i32 q14,q12,#13
+ eor r0,r0,r2,ROR #14
+ eor r2,r5,r6,ROR #14
+ str r3,[sp,#124]
+ add r3,r10,r12
+ ldr r5,[sp,#100]
+ add r6,r9,r11
+ vshr.u32 q11,q11,#19
+ vshr.u32 q12,q12,#19
+ veor q7,q7,q13
+ veor q9,q9,q14
+ eor r8,r8,r3,ROR #25
+ eor r3,r5,r6,ROR #25
+ add r5,r8,r10
+ add r6,r3,r9
+ veor q7,q7,q11
+ veor q9,q9,q12
+ eor r5,r7,r5,ROR #23
+ eor r6,r14,r6,ROR #23
+ add r7,r5,r8
+ add r14,r6,r3
+ vadd.i32 q11,q2,q7
+ vswp d4,d5
+ vadd.i32 q12,q6,q9
+ vshl.i32 q13,q11,#18
+ vswp d12,d13
+ vshl.i32 q14,q12,#18
+ eor r7,r12,r7,ROR #19
+ eor r11,r11,r14,ROR #19
+ add r12,r7,r5
+ add r14,r11,r6
+ vshr.u32 q11,q11,#14
+ vext.32 q7,q7,q7,#1
+ vshr.u32 q12,q12,#14
+ veor q8,q8,q13
+ vext.32 q9,q9,q9,#1
+ veor q10,q10,q14
+ eor r10,r10,r12,ROR #14
+ eor r9,r9,r14,ROR #14
+ add r12,r0,r3
+ add r14,r2,r4
+ veor q8,q8,q11
+ veor q11,q10,q12
+ eor r1,r1,r12,ROR #25
+ eor r7,r7,r14,ROR #25
+ add r12,r1,r0
+ add r14,r7,r2
+ vadd.i32 q10,q4,q8
+ vadd.i32 q12,q5,q11
+ vshl.i32 q13,q10,#7
+ vshl.i32 q14,q12,#7
+ eor r5,r5,r12,ROR #23
+ eor r6,r6,r14,ROR #23
+ vshr.u32 q10,q10,#25
+ vshr.u32 q12,q12,#25
+ add r12,r5,r1
+ add r14,r6,r7
+ veor q7,q7,q13
+ veor q9,q9,q14
+ veor q7,q7,q10
+ veor q9,q9,q12
+ vadd.i32 q10,q8,q7
+ vadd.i32 q12,q11,q9
+ vshl.i32 q13,q10,#9
+ vshl.i32 q14,q12,#9
+ eor r3,r3,r12,ROR #19
+ str r7,[sp,#104]
+ eor r4,r4,r14,ROR #19
+ ldr r7,[sp,#112]
+ add r12,r3,r5
+ str r6,[sp,#108]
+ add r6,r4,r6
+ ldr r14,[sp,#116]
+ eor r0,r0,r12,ROR #14
+ str r5,[sp,#96]
+ eor r5,r2,r6,ROR #14
+ ldr r2,[sp,#120]
+ vshr.u32 q10,q10,#23
+ vshr.u32 q12,q12,#23
+ veor q2,q2,q13
+ veor q6,q6,q14
+ veor q2,q2,q10
+ veor q6,q6,q12
+ add r6,r10,r14
+ add r12,r9,r8
+ vadd.i32 q12,q7,q2
+ vext.32 q10,q7,q7,#3
+ vadd.i32 q7,q9,q6
+ vshl.i32 q14,q12,#13
+ vext.32 q13,q9,q9,#3
+ vshl.i32 q9,q7,#13
+ vshr.u32 q12,q12,#19
+ vshr.u32 q7,q7,#19
+ eor r11,r11,r6,ROR #25
+ eor r2,r2,r12,ROR #25
+ add r6,r11,r10
+ str r3,[sp,#100]
+ add r3,r2,r9
+ ldr r12,[sp,#124]
+ veor q4,q4,q14
+ veor q5,q5,q9
+ veor q4,q4,q12
+ veor q7,q5,q7
+ eor r6,r7,r6,ROR #23
+ eor r3,r12,r3,ROR #23
+ add r7,r6,r11
+ add r12,r3,r2
+ vadd.i32 q5,q2,q4
+ vswp d4,d5
+ vadd.i32 q9,q6,q7
+ vshl.i32 q12,q5,#18
+ vswp d12,d13
+ vshl.i32 q14,q9,#18
+ eor r7,r14,r7,ROR #19
+ eor r8,r8,r12,ROR #19
+ add r12,r7,r6
+ add r14,r8,r3
+ vshr.u32 q15,q5,#14
+ vext.32 q5,q4,q4,#1
+ vshr.u32 q4,q9,#14
+ veor q8,q8,q12
+ vext.32 q7,q7,q7,#1
+ veor q9,q11,q14
+ eor r10,r10,r12,ROR #14
+ ldr r12,[sp,#248]
+ veor q8,q8,q15
+ eor r9,r9,r14,ROR #14
+ veor q11,q9,q4
+ subs r12,r12,#4
+ bhi .L_mainloop2
+ strd r8,[sp,#112]
+ ldrd r8,[sp,#64]
+ strd r2,[sp,#120]
+ ldrd r2,[sp,#96]
+ add r0,r0,r8
+ strd r10,[sp,#96]
+ add r1,r1,r9
+ ldrd r10,[sp,#48]
+ ldrd r8,[sp,#72]
+ add r2,r2,r10
+ strd r6,[sp,#128]
+ add r3,r3,r11
+ ldrd r6,[sp,#104]
+ ldrd r10,[sp,#32]
+ ldr r12,[sp,#236]
+ add r4,r4,r8
+ add r5,r5,r9
+ add r6,r6,r10
+ add r7,r7,r11
+ cmp r12,#0
+ beq .L_nomessage1
+ ldr r8,[r12,#0]
+ ldr r9,[r12,#4]
+ ldr r10,[r12,#8]
+ ldr r11,[r12,#12]
+ eor r0,r0,r8
+ ldr r8,[r12,#16]
+ eor r1,r1,r9
+ ldr r9,[r12,#20]
+ eor r2,r2,r10
+ ldr r10,[r12,#24]
+ eor r3,r3,r11
+ ldr r11,[r12,#28]
+ eor r4,r4,r8
+ eor r5,r5,r9
+ eor r6,r6,r10
+ eor r7,r7,r11
+.L_nomessage1:
+ ldr r14,[sp,#232]
+ vadd.i32 q4,q8,q1
+ str r0,[r14,#0]
+ add r0,sp,#304
+ str r1,[r14,#4]
+ vld1.8 {d16-d17},[r0,: 128]
+ str r2,[r14,#8]
+ vadd.i32 q5,q8,q5
+ str r3,[r14,#12]
+ add r0,sp,#288
+ str r4,[r14,#16]
+ vld1.8 {d16-d17},[r0,: 128]
+ str r5,[r14,#20]
+ vadd.i32 q9,q10,q0
+ str r6,[r14,#24]
+ vadd.i32 q2,q8,q2
+ str r7,[r14,#28]
+ vmov.i64 q8,#0xffffffff
+ ldrd r6,[sp,#128]
+ vext.32 d20,d8,d10,#1
+ ldrd r0,[sp,#40]
+ vext.32 d25,d9,d11,#1
+ ldrd r2,[sp,#120]
+ vbif q4,q9,q8
+ ldrd r4,[sp,#56]
+ vext.32 d21,d5,d19,#1
+ add r6,r6,r0
+ vext.32 d24,d4,d18,#1
+ add r7,r7,r1
+ vbif q2,q5,q8
+ add r2,r2,r4
+ vrev64.i32 q5,q10
+ add r3,r3,r5
+ vrev64.i32 q9,q12
+ adds r0,r0,#3
+ vswp d5,d9
+ adc r1,r1,#0
+ strd r0,[sp,#40]
+ ldrd r8,[sp,#112]
+ ldrd r0,[sp,#88]
+ ldrd r10,[sp,#96]
+ ldrd r4,[sp,#80]
+ add r0,r8,r0
+ add r1,r9,r1
+ add r4,r10,r4
+ add r5,r11,r5
+ add r8,r14,#64
+ cmp r12,#0
+ beq .L_nomessage2
+ ldr r9,[r12,#32]
+ ldr r10,[r12,#36]
+ ldr r11,[r12,#40]
+ ldr r14,[r12,#44]
+ eor r6,r6,r9
+ ldr r9,[r12,#48]
+ eor r7,r7,r10
+ ldr r10,[r12,#52]
+ eor r4,r4,r11
+ ldr r11,[r12,#56]
+ eor r5,r5,r14
+ ldr r14,[r12,#60]
+ add r12,r12,#64
+ eor r2,r2,r9
+ vld1.8 {d20-d21},[r12]!
+ veor q4,q4,q10
+ eor r3,r3,r10
+ vld1.8 {d20-d21},[r12]!
+ veor q5,q5,q10
+ eor r0,r0,r11
+ vld1.8 {d20-d21},[r12]!
+ veor q2,q2,q10
+ eor r1,r1,r14
+ vld1.8 {d20-d21},[r12]!
+ veor q9,q9,q10
+.L_nomessage2:
+ vst1.8 {d8-d9},[r8]!
+ vst1.8 {d10-d11},[r8]!
+ vmov.i64 q4,#0xff
+ vst1.8 {d4-d5},[r8]!
+ vst1.8 {d18-d19},[r8]!
+ str r6,[r8,#-96]
+ add r6,sp,#336
+ str r7,[r8,#-92]
+ add r7,sp,#320
+ str r4,[r8,#-88]
+ vadd.i32 q2,q11,q1
+ vld1.8 {d10-d11},[r6,: 128]
+ vadd.i32 q5,q5,q7
+ vld1.8 {d14-d15},[r7,: 128]
+ vadd.i32 q9,q13,q0
+ vadd.i32 q6,q7,q6
+ str r5,[r8,#-84]
+ vext.32 d14,d4,d10,#1
+ str r2,[r8,#-80]
+ vext.32 d21,d5,d11,#1
+ str r3,[r8,#-76]
+ vbif q2,q9,q8
+ str r0,[r8,#-72]
+ vext.32 d15,d13,d19,#1
+ vshr.u32 q4,q4,#7
+ str r1,[r8,#-68]
+ vext.32 d20,d12,d18,#1
+ vbif q6,q5,q8
+ ldr r0,[sp,#240]
+ vrev64.i32 q5,q7
+ vrev64.i32 q7,q10
+ vswp d13,d5
+ vadd.i64 q3,q3,q4
+ sub r0,r0,#192
+ cmp r12,#0
+ beq .L_nomessage21
+ vld1.8 {d16-d17},[r12]!
+ veor q2,q2,q8
+ vld1.8 {d16-d17},[r12]!
+ veor q5,q5,q8
+ vld1.8 {d16-d17},[r12]!
+ veor q6,q6,q8
+ vld1.8 {d16-d17},[r12]!
+ veor q7,q7,q8
+.L_nomessage21:
+ vst1.8 {d4-d5},[r8]!
+ vst1.8 {d10-d11},[r8]!
+ vst1.8 {d12-d13},[r8]!
+ vst1.8 {d14-d15},[r8]!
+ str r12,[sp,#236]
+ add r14,sp,#272
+ add r12,sp,#256
+ str r8,[sp,#232]
+ cmp r0,#192
+ bhs .L_mlenatleast192
+.L_mlenlowbelow192:
+ cmp r0,#0
+ beq .L_done
+ b .L_mlenatleast1
+.L_nextblock:
+ sub r0,r0,#64
+.L_mlenatleast1:
+.L_handleblock:
+ str r0,[sp,#248]
+ ldrd r2,[sp,#48]
+ ldrd r6,[sp,#32]
+ ldrd r0,[sp,#64]
+ ldrd r4,[sp,#72]
+ ldrd r10,[sp,#80]
+ ldrd r8,[sp,#88]
+ strd r2,[sp,#96]
+ strd r6,[sp,#104]
+ ldrd r2,[sp,#56]
+ ldrd r6,[sp,#40]
+ ldr r12,[sp,#244]
+.L_mainloop1:
+ str r12,[sp,#252]
+ add r12,r0,r2
+ add r14,r5,r1
+ eor r4,r4,r12,ROR #25
+ eor r7,r7,r14,ROR #25
+ add r12,r4,r0
+ add r14,r7,r5
+ eor r6,r6,r12,ROR #23
+ eor r3,r3,r14,ROR #23
+ add r12,r6,r4
+ str r7,[sp,#132]
+ add r7,r3,r7
+ ldr r14,[sp,#104]
+ eor r2,r2,r12,ROR #19
+ str r6,[sp,#128]
+ eor r1,r1,r7,ROR #19
+ ldr r7,[sp,#100]
+ add r6,r2,r6
+ str r2,[sp,#120]
+ add r2,r1,r3
+ ldr r12,[sp,#96]
+ eor r0,r0,r6,ROR #14
+ str r3,[sp,#124]
+ eor r2,r5,r2,ROR #14
+ ldr r3,[sp,#108]
+ add r5,r10,r14
+ add r6,r9,r11
+ eor r8,r8,r5,ROR #25
+ eor r5,r7,r6,ROR #25
+ add r6,r8,r10
+ add r7,r5,r9
+ eor r6,r12,r6,ROR #23
+ eor r3,r3,r7,ROR #23
+ add r7,r6,r8
+ add r12,r3,r5
+ eor r7,r14,r7,ROR #19
+ eor r11,r11,r12,ROR #19
+ add r12,r7,r6
+ add r14,r11,r3
+ eor r10,r10,r12,ROR #14
+ eor r9,r9,r14,ROR #14
+ add r12,r0,r5
+ add r14,r2,r4
+ eor r1,r1,r12,ROR #25
+ eor r7,r7,r14,ROR #25
+ add r12,r1,r0
+ add r14,r7,r2
+ eor r6,r6,r12,ROR #23
+ eor r3,r3,r14,ROR #23
+ add r12,r6,r1
+ str r7,[sp,#104]
+ add r7,r3,r7
+ ldr r14,[sp,#128]
+ eor r5,r5,r12,ROR #19
+ str r3,[sp,#108]
+ eor r4,r4,r7,ROR #19
+ ldr r7,[sp,#132]
+ add r12,r5,r6
+ str r6,[sp,#96]
+ add r3,r4,r3
+ ldr r6,[sp,#120]
+ eor r0,r0,r12,ROR #14
+ str r5,[sp,#100]
+ eor r5,r2,r3,ROR #14
+ ldr r3,[sp,#124]
+ add r2,r10,r7
+ add r12,r9,r8
+ eor r11,r11,r2,ROR #25
+ eor r2,r6,r12,ROR #25
+ add r6,r11,r10
+ add r12,r2,r9
+ eor r6,r14,r6,ROR #23
+ eor r3,r3,r12,ROR #23
+ add r12,r6,r11
+ add r14,r3,r2
+ eor r7,r7,r12,ROR #19
+ eor r8,r8,r14,ROR #19
+ add r12,r7,r6
+ add r14,r8,r3
+ eor r10,r10,r12,ROR #14
+ eor r9,r9,r14,ROR #14
+ ldr r12,[sp,#252]
+ subs r12,r12,#2
+ bhi .L_mainloop1
+ strd r6,[sp,#128]
+ strd r2,[sp,#120]
+ strd r10,[sp,#112]
+ strd r8,[sp,#136]
+ ldrd r2,[sp,#96]
+ ldrd r6,[sp,#104]
+ ldrd r8,[sp,#64]
+ ldrd r10,[sp,#48]
+ add r0,r0,r8
+ add r1,r1,r9
+ add r2,r2,r10
+ add r3,r3,r11
+ ldrd r8,[sp,#72]
+ ldrd r10,[sp,#32]
+ add r4,r4,r8
+ add r5,r5,r9
+ add r6,r6,r10
+ add r7,r7,r11
+ ldr r12,[sp,#236]
+ cmp r12,#0
+ beq .L_nomessage10
+ ldr r8,[r12,#0]
+ ldr r9,[r12,#4]
+ ldr r10,[r12,#8]
+ ldr r11,[r12,#12]
+ eor r0,r0,r8
+ ldr r8,[r12,#16]
+ eor r1,r1,r9
+ ldr r9,[r12,#20]
+ eor r2,r2,r10
+ ldr r10,[r12,#24]
+ eor r3,r3,r11
+ ldr r11,[r12,#28]
+ eor r4,r4,r8
+ eor r5,r5,r9
+ eor r6,r6,r10
+ eor r7,r7,r11
+.L_nomessage10:
+ ldr r14,[sp,#232]
+ str r0,[r14,#0]
+ str r1,[r14,#4]
+ str r2,[r14,#8]
+ str r3,[r14,#12]
+ str r4,[r14,#16]
+ str r5,[r14,#20]
+ str r6,[r14,#24]
+ str r7,[r14,#28]
+ ldrd r6,[sp,#128]
+ ldrd r10,[sp,#112]
+ ldrd r0,[sp,#40]
+ ldrd r4,[sp,#80]
+ add r6,r6,r0
+ add r7,r7,r1
+ add r10,r10,r4
+ add r11,r11,r5
+ adds r0,r0,#1
+ adc r1,r1,#0
+ strd r0,[sp,#40]
+ ldrd r2,[sp,#120]
+ ldrd r8,[sp,#136]
+ ldrd r4,[sp,#56]
+ ldrd r0,[sp,#88]
+ add r2,r2,r4
+ add r3,r3,r5
+ add r0,r8,r0
+ add r1,r9,r1
+ cmp r12,#0
+ beq .L_nomessage11
+ ldr r4,[r12,#32]
+ ldr r5,[r12,#36]
+ ldr r8,[r12,#40]
+ ldr r9,[r12,#44]
+ eor r6,r6,r4
+ ldr r4,[r12,#48]
+ eor r7,r7,r5
+ ldr r5,[r12,#52]
+ eor r10,r10,r8
+ ldr r8,[r12,#56]
+ eor r11,r11,r9
+ ldr r9,[r12,#60]
+ eor r2,r2,r4
+ eor r3,r3,r5
+ eor r0,r0,r8
+ eor r1,r1,r9
+ add r4,r12,#64
+ str r4,[sp,#236]
+.L_nomessage11:
+ str r6,[r14,#32]
+ str r7,[r14,#36]
+ str r10,[r14,#40]
+ str r11,[r14,#44]
+ str r2,[r14,#48]
+ str r3,[r14,#52]
+ str r0,[r14,#56]
+ str r1,[r14,#60]
+ add r0,r14,#64
+ str r0,[sp,#232]
+ ldr r0,[sp,#248]
+ cmp r0,#64
+ bhi .L_nextblock
+.L_done:
+ ldr r2,[sp,#160]
+ ldrd r4,[sp,#0]
+ ldrd r6,[sp,#8]
+ ldrd r8,[sp,#16]
+ ldrd r10,[sp,#24]
+ ldr r12,[sp,#228]
+ ldr r14,[sp,#224]
+ ldrd r0,[sp,#40]
+ strd r0,[r2]
+ sub r0,r12,sp
+ mov sp,r12
+ vpop {q4,q5,q6,q7}
+ add r0,r0,#64
+ bx lr
+.size _gcry_arm_neon_salsa20_encrypt,.-_gcry_arm_neon_salsa20_encrypt;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/salsa20.c b/comm/third_party/libgcrypt/cipher/salsa20.c
new file mode 100644
index 0000000000..d8c5c81f30
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/salsa20.c
@@ -0,0 +1,600 @@
+/* salsa20.c - Bernstein's Salsa20 cipher
+ * Copyright (C) 2012 Simon Josefsson, Niels Möller
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * For a description of the algorithm, see:
+ * http://cr.yp.to/snuffle/spec.pdf
+ * http://cr.yp.to/snuffle/design.pdf
+ */
+
+/* The code is based on the code in Nettle
+ (git commit id 9d2d8ddaee35b91a4e1a32ae77cba04bea3480e7)
+ which in turn is based on
+ salsa20-ref.c version 20051118
+ D. J. Bernstein
+ Public domain.
+*/
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-internal.h"
+
+
+/* USE_AMD64 indicates whether to compile with AMD64 code. */
+#undef USE_AMD64
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AMD64 1
+#endif
+
+/* USE_ARM_NEON_ASM indicates whether to enable ARM NEON assembly code. */
+#undef USE_ARM_NEON_ASM
+#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_ARM_NEON_ASM 1
+# endif
+#endif /*ENABLE_NEON_SUPPORT*/
+
+
+#define SALSA20_MIN_KEY_SIZE 16 /* Bytes. */
+#define SALSA20_MAX_KEY_SIZE 32 /* Bytes. */
+#define SALSA20_BLOCK_SIZE 64 /* Bytes. */
+#define SALSA20_IV_SIZE 8 /* Bytes. */
+#define SALSA20_INPUT_LENGTH 16 /* Bytes. */
+
+/* Number of rounds. The standard uses 20 rounds. In any case the
+ number of rounds must be even. */
+#define SALSA20_ROUNDS 20
+#define SALSA20R12_ROUNDS 12
+
+
+struct SALSA20_context_s;
+
+typedef unsigned int (*salsa20_core_t) (u32 *dst, struct SALSA20_context_s *ctx,
+ unsigned int rounds);
+typedef void (* salsa20_keysetup_t)(struct SALSA20_context_s *ctx,
+ const byte *key, int keylen);
+typedef void (* salsa20_ivsetup_t)(struct SALSA20_context_s *ctx,
+ const byte *iv);
+
+typedef struct SALSA20_context_s
+{
+ /* Indices 1-4 and 11-14 holds the key (two identical copies for the
+ shorter key size), indices 0, 5, 10, 15 are constant, indices 6, 7
+ are the IV, and indices 8, 9 are the block counter:
+
+ C K K K
+ K C I I
+ B B C K
+ K K K C
+ */
+ u32 input[SALSA20_INPUT_LENGTH];
+ u32 pad[SALSA20_INPUT_LENGTH];
+ unsigned int unused; /* bytes in the pad. */
+#ifdef USE_ARM_NEON_ASM
+ int use_neon;
+#endif
+ salsa20_keysetup_t keysetup;
+ salsa20_ivsetup_t ivsetup;
+ salsa20_core_t core;
+} SALSA20_context_t;
+
+
+/* The masking of the right shift is needed to allow n == 0 (using
+ just 32 - n and 64 - n results in undefined behaviour). Most uses
+ of these macros use a constant and non-zero rotation count. */
+#define ROTL32(n,x) (((x)<<(n)) | ((x)>>((-(n)&31))))
+
+
+#define LE_SWAP32(v) le_bswap32(v)
+
+#define LE_READ_UINT32(p) buf_get_le32(p)
+
+
+static void salsa20_setiv (void *context, const byte *iv, size_t ivlen);
+static const char *selftest (void);
+
+
+#ifdef USE_AMD64
+
+/* Assembly implementations use SystemV ABI, ABI conversion and additional
+ * stack to store XMM6-XMM15 needed on Win64. */
+#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
+
+/* AMD64 assembly implementations of Salsa20. */
+void _gcry_salsa20_amd64_keysetup(u32 *ctxinput, const void *key, int keybits)
+ ASM_FUNC_ABI;
+void _gcry_salsa20_amd64_ivsetup(u32 *ctxinput, const void *iv)
+ ASM_FUNC_ABI;
+unsigned int
+_gcry_salsa20_amd64_encrypt_blocks(u32 *ctxinput, const void *src, void *dst,
+ size_t len, int rounds) ASM_FUNC_ABI;
+
+static void
+salsa20_keysetup(SALSA20_context_t *ctx, const byte *key, int keylen)
+{
+ _gcry_salsa20_amd64_keysetup(ctx->input, key, keylen * 8);
+}
+
+static void
+salsa20_ivsetup(SALSA20_context_t *ctx, const byte *iv)
+{
+ _gcry_salsa20_amd64_ivsetup(ctx->input, iv);
+}
+
+static unsigned int
+salsa20_core (u32 *dst, SALSA20_context_t *ctx, unsigned int rounds)
+{
+ memset(dst, 0, SALSA20_BLOCK_SIZE);
+ return _gcry_salsa20_amd64_encrypt_blocks(ctx->input, dst, dst, 1, rounds)
+ + ASM_EXTRA_STACK;
+}
+
+#else /* USE_AMD64 */
+
+
+
+#if 0
+# define SALSA20_CORE_DEBUG(i) do { \
+ unsigned debug_j; \
+ for (debug_j = 0; debug_j < 16; debug_j++) \
+ { \
+ if (debug_j == 0) \
+ fprintf(stderr, "%2d:", (i)); \
+ else if (debug_j % 4 == 0) \
+ fprintf(stderr, "\n "); \
+ fprintf(stderr, " %8x", pad[debug_j]); \
+ } \
+ fprintf(stderr, "\n"); \
+ } while (0)
+#else
+# define SALSA20_CORE_DEBUG(i)
+#endif
+
+#define QROUND(x0, x1, x2, x3) \
+ do { \
+ x1 ^= ROTL32 ( 7, x0 + x3); \
+ x2 ^= ROTL32 ( 9, x1 + x0); \
+ x3 ^= ROTL32 (13, x2 + x1); \
+ x0 ^= ROTL32 (18, x3 + x2); \
+ } while(0)
+
+static unsigned int
+salsa20_core (u32 *dst, SALSA20_context_t *ctx, unsigned rounds)
+{
+ u32 pad[SALSA20_INPUT_LENGTH], *src = ctx->input;
+ unsigned int i;
+
+ memcpy (pad, src, sizeof(pad));
+ for (i = 0; i < rounds; i += 2)
+ {
+ SALSA20_CORE_DEBUG (i);
+ QROUND (pad[0], pad[4], pad[8], pad[12]);
+ QROUND (pad[5], pad[9], pad[13], pad[1] );
+ QROUND (pad[10], pad[14], pad[2], pad[6] );
+ QROUND (pad[15], pad[3], pad[7], pad[11]);
+
+ SALSA20_CORE_DEBUG (i+1);
+ QROUND (pad[0], pad[1], pad[2], pad[3] );
+ QROUND (pad[5], pad[6], pad[7], pad[4] );
+ QROUND (pad[10], pad[11], pad[8], pad[9] );
+ QROUND (pad[15], pad[12], pad[13], pad[14]);
+ }
+ SALSA20_CORE_DEBUG (i);
+
+ for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
+ {
+ u32 t = pad[i] + src[i];
+ dst[i] = LE_SWAP32 (t);
+ }
+
+ /* Update counter. */
+ if (!++src[8])
+ src[9]++;
+
+ /* burn_stack */
+ return ( 3*sizeof (void*) \
+ + 2*sizeof (void*) \
+ + 64 \
+ + sizeof (unsigned int) \
+ + sizeof (u32) );
+}
+#undef QROUND
+#undef SALSA20_CORE_DEBUG
+
+static void
+salsa20_keysetup(SALSA20_context_t *ctx, const byte *key, int keylen)
+{
+ /* These constants are the little endian encoding of the string
+ "expand 32-byte k". For the 128 bit variant, the "32" in that
+ string will be fixed up to "16". */
+ ctx->input[0] = 0x61707865; /* "apxe" */
+ ctx->input[5] = 0x3320646e; /* "3 dn" */
+ ctx->input[10] = 0x79622d32; /* "yb-2" */
+ ctx->input[15] = 0x6b206574; /* "k et" */
+
+ ctx->input[1] = LE_READ_UINT32(key + 0);
+ ctx->input[2] = LE_READ_UINT32(key + 4);
+ ctx->input[3] = LE_READ_UINT32(key + 8);
+ ctx->input[4] = LE_READ_UINT32(key + 12);
+ if (keylen == SALSA20_MAX_KEY_SIZE) /* 256 bits */
+ {
+ ctx->input[11] = LE_READ_UINT32(key + 16);
+ ctx->input[12] = LE_READ_UINT32(key + 20);
+ ctx->input[13] = LE_READ_UINT32(key + 24);
+ ctx->input[14] = LE_READ_UINT32(key + 28);
+ }
+ else /* 128 bits */
+ {
+ ctx->input[11] = ctx->input[1];
+ ctx->input[12] = ctx->input[2];
+ ctx->input[13] = ctx->input[3];
+ ctx->input[14] = ctx->input[4];
+
+ ctx->input[5] -= 0x02000000; /* Change to "1 dn". */
+ ctx->input[10] += 0x00000004; /* Change to "yb-6". */
+ }
+}
+
+static void salsa20_ivsetup(SALSA20_context_t *ctx, const byte *iv)
+{
+ ctx->input[6] = LE_READ_UINT32(iv + 0);
+ ctx->input[7] = LE_READ_UINT32(iv + 4);
+ /* Reset the block counter. */
+ ctx->input[8] = 0;
+ ctx->input[9] = 0;
+}
+
+#endif /*!USE_AMD64*/
+
+#ifdef USE_ARM_NEON_ASM
+
+/* ARM NEON implementation of Salsa20. */
+unsigned int
+_gcry_arm_neon_salsa20_encrypt(void *c, const void *m, unsigned int nblks,
+ void *k, unsigned int rounds);
+
+static unsigned int
+salsa20_core_neon (u32 *dst, SALSA20_context_t *ctx, unsigned int rounds)
+{
+ return _gcry_arm_neon_salsa20_encrypt(dst, NULL, 1, ctx->input, rounds);
+}
+
+static void salsa20_ivsetup_neon(SALSA20_context_t *ctx, const byte *iv)
+{
+ memcpy(ctx->input + 8, iv, 8);
+ /* Reset the block counter. */
+ memset(ctx->input + 10, 0, 8);
+}
+
+static void
+salsa20_keysetup_neon(SALSA20_context_t *ctx, const byte *key, int klen)
+{
+ static const unsigned char sigma32[16] = "expand 32-byte k";
+ static const unsigned char sigma16[16] = "expand 16-byte k";
+
+ if (klen == 16)
+ {
+ memcpy (ctx->input, key, 16);
+ memcpy (ctx->input + 4, key, 16); /* Duplicate 128-bit key. */
+ memcpy (ctx->input + 12, sigma16, 16);
+ }
+ else
+ {
+ /* 32-byte key */
+ memcpy (ctx->input, key, 32);
+ memcpy (ctx->input + 12, sigma32, 16);
+ }
+}
+
+#endif /*USE_ARM_NEON_ASM*/
+
+
+static gcry_err_code_t
+salsa20_do_setkey (SALSA20_context_t *ctx,
+ const byte *key, unsigned int keylen)
+{
+ static int initialized;
+ static const char *selftest_failed;
+
+ if (!initialized )
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if (selftest_failed)
+ log_error ("SALSA20 selftest failed (%s)\n", selftest_failed );
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if (keylen != SALSA20_MIN_KEY_SIZE
+ && keylen != SALSA20_MAX_KEY_SIZE)
+ return GPG_ERR_INV_KEYLEN;
+
+ /* Default ops. */
+ ctx->keysetup = salsa20_keysetup;
+ ctx->ivsetup = salsa20_ivsetup;
+ ctx->core = salsa20_core;
+
+#ifdef USE_ARM_NEON_ASM
+ ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0;
+ if (ctx->use_neon)
+ {
+ /* Use ARM NEON ops instead. */
+ ctx->keysetup = salsa20_keysetup_neon;
+ ctx->ivsetup = salsa20_ivsetup_neon;
+ ctx->core = salsa20_core_neon;
+ }
+#endif
+
+ ctx->keysetup (ctx, key, keylen);
+
+ /* We default to a zero nonce. */
+ salsa20_setiv (ctx, NULL, 0);
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+salsa20_setkey (void *context, const byte *key, unsigned int keylen,
+ cipher_bulk_ops_t *bulk_ops)
+{
+ SALSA20_context_t *ctx = (SALSA20_context_t *)context;
+ gcry_err_code_t rc = salsa20_do_setkey (ctx, key, keylen);
+ (void)bulk_ops;
+ _gcry_burn_stack (4 + sizeof (void *) + 4 * sizeof (void *));
+ return rc;
+}
+
+
+static void
+salsa20_setiv (void *context, const byte *iv, size_t ivlen)
+{
+ SALSA20_context_t *ctx = (SALSA20_context_t *)context;
+ byte tmp[SALSA20_IV_SIZE];
+
+ if (iv && ivlen != SALSA20_IV_SIZE)
+ log_info ("WARNING: salsa20_setiv: bad ivlen=%u\n", (u32)ivlen);
+
+ if (!iv || ivlen != SALSA20_IV_SIZE)
+ memset (tmp, 0, sizeof(tmp));
+ else
+ memcpy (tmp, iv, SALSA20_IV_SIZE);
+
+ ctx->ivsetup (ctx, tmp);
+
+ /* Reset the unused pad bytes counter. */
+ ctx->unused = 0;
+
+ wipememory (tmp, sizeof(tmp));
+}
+
+
+
+/* Note: This function requires LENGTH > 0. */
+static void
+salsa20_do_encrypt_stream (SALSA20_context_t *ctx,
+ byte *outbuf, const byte *inbuf,
+ size_t length, unsigned rounds)
+{
+ unsigned int nburn, burn = 0;
+
+ if (ctx->unused)
+ {
+ unsigned char *p = (void*)ctx->pad;
+ size_t n;
+
+ gcry_assert (ctx->unused < SALSA20_BLOCK_SIZE);
+
+ n = ctx->unused;
+ if (n > length)
+ n = length;
+ buf_xor (outbuf, inbuf, p + SALSA20_BLOCK_SIZE - ctx->unused, n);
+ length -= n;
+ outbuf += n;
+ inbuf += n;
+ ctx->unused -= n;
+ if (!length)
+ return;
+ gcry_assert (!ctx->unused);
+ }
+
+#ifdef USE_AMD64
+ if (length >= SALSA20_BLOCK_SIZE)
+ {
+ size_t nblocks = length / SALSA20_BLOCK_SIZE;
+ burn = _gcry_salsa20_amd64_encrypt_blocks(ctx->input, inbuf, outbuf,
+ nblocks, rounds);
+ burn += ASM_EXTRA_STACK;
+ length -= SALSA20_BLOCK_SIZE * nblocks;
+ outbuf += SALSA20_BLOCK_SIZE * nblocks;
+ inbuf += SALSA20_BLOCK_SIZE * nblocks;
+ }
+#endif
+
+#ifdef USE_ARM_NEON_ASM
+ if (ctx->use_neon && length >= SALSA20_BLOCK_SIZE)
+ {
+ unsigned int nblocks = length / SALSA20_BLOCK_SIZE;
+ _gcry_arm_neon_salsa20_encrypt (outbuf, inbuf, nblocks, ctx->input,
+ rounds);
+ length -= SALSA20_BLOCK_SIZE * nblocks;
+ outbuf += SALSA20_BLOCK_SIZE * nblocks;
+ inbuf += SALSA20_BLOCK_SIZE * nblocks;
+ }
+#endif
+
+ while (length > 0)
+ {
+ /* Create the next pad and bump the block counter. Note that it
+ is the user's duty to change to another nonce not later than
+ after 2^70 processed bytes. */
+ nburn = ctx->core (ctx->pad, ctx, rounds);
+ burn = nburn > burn ? nburn : burn;
+
+ if (length <= SALSA20_BLOCK_SIZE)
+ {
+ buf_xor (outbuf, inbuf, ctx->pad, length);
+ ctx->unused = SALSA20_BLOCK_SIZE - length;
+ break;
+ }
+ buf_xor (outbuf, inbuf, ctx->pad, SALSA20_BLOCK_SIZE);
+ length -= SALSA20_BLOCK_SIZE;
+ outbuf += SALSA20_BLOCK_SIZE;
+ inbuf += SALSA20_BLOCK_SIZE;
+ }
+
+ _gcry_burn_stack (burn);
+}
+
+
+static void
+salsa20_encrypt_stream (void *context,
+ byte *outbuf, const byte *inbuf, size_t length)
+{
+ SALSA20_context_t *ctx = (SALSA20_context_t *)context;
+
+ if (length)
+ salsa20_do_encrypt_stream (ctx, outbuf, inbuf, length, SALSA20_ROUNDS);
+}
+
+
+static void
+salsa20r12_encrypt_stream (void *context,
+ byte *outbuf, const byte *inbuf, size_t length)
+{
+ SALSA20_context_t *ctx = (SALSA20_context_t *)context;
+
+ if (length)
+ salsa20_do_encrypt_stream (ctx, outbuf, inbuf, length, SALSA20R12_ROUNDS);
+}
+
+
+static const char*
+selftest (void)
+{
+ byte ctxbuf[sizeof(SALSA20_context_t) + 15];
+ SALSA20_context_t *ctx;
+ byte scratch[8+1];
+ byte buf[256+64+4];
+ int i;
+
+ static byte key_1[] =
+ { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const byte nonce_1[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const byte plaintext_1[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const byte ciphertext_1[] =
+ { 0xE3, 0xBE, 0x8F, 0xDD, 0x8B, 0xEC, 0xA2, 0xE3};
+
+ /* 16-byte alignment required for amd64 implementation. */
+ ctx = (SALSA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15);
+
+ salsa20_setkey (ctx, key_1, sizeof key_1, NULL);
+ salsa20_setiv (ctx, nonce_1, sizeof nonce_1);
+ scratch[8] = 0;
+ salsa20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1);
+ if (memcmp (scratch, ciphertext_1, sizeof ciphertext_1))
+ return "Salsa20 encryption test 1 failed.";
+ if (scratch[8])
+ return "Salsa20 wrote too much.";
+ salsa20_setkey( ctx, key_1, sizeof(key_1), NULL);
+ salsa20_setiv (ctx, nonce_1, sizeof nonce_1);
+ salsa20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1);
+ if (memcmp (scratch, plaintext_1, sizeof plaintext_1))
+ return "Salsa20 decryption test 1 failed.";
+
+ for (i = 0; i < sizeof buf; i++)
+ buf[i] = i;
+ salsa20_setkey (ctx, key_1, sizeof key_1, NULL);
+ salsa20_setiv (ctx, nonce_1, sizeof nonce_1);
+ /*encrypt*/
+ salsa20_encrypt_stream (ctx, buf, buf, sizeof buf);
+ /*decrypt*/
+ salsa20_setkey (ctx, key_1, sizeof key_1, NULL);
+ salsa20_setiv (ctx, nonce_1, sizeof nonce_1);
+ salsa20_encrypt_stream (ctx, buf, buf, 1);
+ salsa20_encrypt_stream (ctx, buf+1, buf+1, (sizeof buf)-1-1);
+ salsa20_encrypt_stream (ctx, buf+(sizeof buf)-1, buf+(sizeof buf)-1, 1);
+ for (i = 0; i < sizeof buf; i++)
+ if (buf[i] != (byte)i)
+ return "Salsa20 encryption test 2 failed.";
+
+ return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_salsa20 =
+ {
+ GCRY_CIPHER_SALSA20,
+ {0, 0}, /* flags */
+ "SALSA20", /* name */
+ NULL, /* aliases */
+ NULL, /* oids */
+ 1, /* blocksize in bytes. */
+ SALSA20_MAX_KEY_SIZE*8, /* standard key length in bits. */
+ sizeof (SALSA20_context_t),
+ salsa20_setkey,
+ NULL,
+ NULL,
+ salsa20_encrypt_stream,
+ salsa20_encrypt_stream,
+ NULL,
+ NULL,
+ salsa20_setiv
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_salsa20r12 =
+ {
+ GCRY_CIPHER_SALSA20R12,
+ {0, 0}, /* flags */
+ "SALSA20R12", /* name */
+ NULL, /* aliases */
+ NULL, /* oids */
+ 1, /* blocksize in bytes. */
+ SALSA20_MAX_KEY_SIZE*8, /* standard key length in bits. */
+ sizeof (SALSA20_context_t),
+ salsa20_setkey,
+ NULL,
+ NULL,
+ salsa20r12_encrypt_stream,
+ salsa20r12_encrypt_stream,
+ NULL,
+ NULL,
+ salsa20_setiv
+ };
diff --git a/comm/third_party/libgcrypt/cipher/scrypt.c b/comm/third_party/libgcrypt/cipher/scrypt.c
new file mode 100644
index 0000000000..13fd1cf06c
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/scrypt.c
@@ -0,0 +1,322 @@
+/* scrypt.c - Scrypt password-based key derivation function.
+ * Copyright (C) 2012 Simon Josefsson
+ * Copyright (C) 2013 Christian Grothoff
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* Adapted from the nettle, low-level cryptographics library for
+ * libgcrypt by Christian Grothoff; original license:
+ *
+ * Copyright (C) 2012 Simon Josefsson
+ *
+ * The nettle library 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.
+ *
+ * The nettle library 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 the nettle library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#include <config.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "kdf-internal.h"
+#include "bufhelp.h"
+
+/* We really need a 64 bit type for this code. */
+#define SALSA20_INPUT_LENGTH 16
+
+#define ROTL32(n,x) (((x)<<(n)) | ((x)>>(32-(n))))
+
+
+/* Reads a 64-bit integer, in network, big-endian, byte order */
+#define READ_UINT64(p) buf_get_be64(p)
+
+
+/* And the other, little-endian, byteorder */
+#define LE_READ_UINT64(p) buf_get_le64(p)
+
+#define LE_SWAP32(v) le_bswap32(v)
+
+
+#define QROUND(x0, x1, x2, x3) do { \
+ x1 ^= ROTL32(7, x0 + x3); \
+ x2 ^= ROTL32(9, x1 + x0); \
+ x3 ^= ROTL32(13, x2 + x1); \
+ x0 ^= ROTL32(18, x3 + x2); \
+ } while(0)
+
+
+static void
+salsa20_core (u32 *dst, const u32 *src, unsigned int rounds)
+{
+ u32 x[SALSA20_INPUT_LENGTH];
+ unsigned i;
+
+ assert ( (rounds & 1) == 0);
+
+ for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
+ x[i] = LE_SWAP32(src[i]);
+
+ for (i = 0; i < rounds;i += 2)
+ {
+ QROUND(x[0], x[4], x[8], x[12]);
+ QROUND(x[5], x[9], x[13], x[1]);
+ QROUND(x[10], x[14], x[2], x[6]);
+ QROUND(x[15], x[3], x[7], x[11]);
+
+ QROUND(x[0], x[1], x[2], x[3]);
+ QROUND(x[5], x[6], x[7], x[4]);
+ QROUND(x[10], x[11], x[8], x[9]);
+ QROUND(x[15], x[12], x[13], x[14]);
+ }
+
+ for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
+ {
+ u32 t = x[i] + LE_SWAP32(src[i]);
+ dst[i] = LE_SWAP32(t);
+ }
+}
+
+
+static void
+scrypt_block_mix (u32 r, unsigned char *B, unsigned char *tmp2)
+{
+ u64 i;
+ unsigned char *X = tmp2;
+ unsigned char *Y = tmp2 + 64;
+
+#if 0
+ if (r == 1)
+ {
+ for (i = 0; i < 2 * r; i++)
+ {
+ size_t j;
+ printf ("B[%d] = ", (int)i);
+ for (j = 0; j < 64; j++)
+ {
+ if (j && !(j % 16))
+ printf ("\n ");
+ printf (" %02x", B[i * 64 + j]);
+ }
+ putchar ('\n');
+ }
+ }
+#endif
+
+ /* X = B[2 * r - 1] */
+ memcpy (X, &B[(2 * r - 1) * 64], 64);
+
+ /* for i = 0 to 2 * r - 1 do */
+ for (i = 0; i <= 2 * r - 1; i++)
+ {
+ /* T = X xor B[i] */
+ buf_xor(X, X, &B[i * 64], 64);
+
+ /* X = Salsa (T) */
+ salsa20_core ((u32*)(void*)X, (u32*)(void*)X, 8);
+
+ /* Y[i] = X */
+ memcpy (&Y[i * 64], X, 64);
+ }
+
+ for (i = 0; i < r; i++)
+ {
+ memcpy (&B[i * 64], &Y[2 * i * 64], 64);
+ memcpy (&B[(r + i) * 64], &Y[(2 * i + 1) * 64], 64);
+ }
+
+#if 0
+ if (r==1)
+ {
+ for (i = 0; i < 2 * r; i++)
+ {
+ size_t j;
+ printf ("B'[%d] =", (int)i);
+ for (j = 0; j < 64; j++)
+ {
+ if (j && !(j % 16))
+ printf ("\n ");
+ printf (" %02x", B[i * 64 + j]);
+ }
+ putchar ('\n');
+ }
+ }
+#endif
+}
+
+
+static void
+scrypt_ro_mix (u32 r, unsigned char *B, u64 N,
+ unsigned char *tmp1, unsigned char *tmp2)
+{
+ unsigned char *X = B, *T = B;
+ u64 i;
+
+#if 0
+ if (r == 1)
+ {
+ printf ("B = ");
+ for (i = 0; i < 128 * r; i++)
+ {
+ if (i && !(i % 16))
+ printf ("\n ");
+ printf (" %02x", B[i]);
+ }
+ putchar ('\n');
+ }
+#endif
+
+ /* for i = 0 to N - 1 do */
+ for (i = 0; i <= N - 1; i++)
+ {
+ /* V[i] = X */
+ memcpy (&tmp1[i * 128 * r], X, 128 * r);
+
+ /* X = ScryptBlockMix (X) */
+ scrypt_block_mix (r, X, tmp2);
+ }
+
+ /* for i = 0 to N - 1 do */
+ for (i = 0; i <= N - 1; i++)
+ {
+ u64 j;
+
+ /* j = Integerify (X) mod N */
+ j = LE_READ_UINT64 (&X[128 * r - 64]) % N;
+
+ /* T = X xor V[j] */
+ buf_xor (T, T, &tmp1[j * 128 * r], 128 * r);
+
+ /* X = scryptBlockMix (T) */
+ scrypt_block_mix (r, T, tmp2);
+ }
+
+#if 0
+ if (r == 1)
+ {
+ printf ("B' =");
+ for (i = 0; i < 128 * r; i++)
+ {
+ if (i && !(i % 16))
+ printf ("\n ");
+ printf (" %02x", B[i]);
+ }
+ putchar ('\n');
+ }
+#endif
+}
+
+
+/*
+ *
+ */
+gcry_err_code_t
+_gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
+ int algo, int subalgo,
+ const unsigned char *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t dkLen, unsigned char *DK)
+{
+ u64 N = subalgo; /* CPU/memory cost parameter. */
+ u32 r; /* Block size. */
+ u32 p = iterations; /* Parallelization parameter. */
+
+ gpg_err_code_t ec;
+ u32 i;
+ unsigned char *B = NULL;
+ unsigned char *tmp1 = NULL;
+ unsigned char *tmp2 = NULL;
+ size_t r128;
+ size_t nbytes;
+
+ if (subalgo < 1 || !iterations)
+ return GPG_ERR_INV_VALUE;
+
+ if (algo == GCRY_KDF_SCRYPT)
+ r = 8;
+ else if (algo == 41) /* Hack to allow the use of all test vectors. */
+ r = 1;
+ else
+ return GPG_ERR_UNKNOWN_ALGORITHM;
+
+ r128 = r * 128;
+ if (r128 / 128 != r)
+ return GPG_ERR_ENOMEM;
+
+ nbytes = p * r128;
+ if (r128 && nbytes / r128 != p)
+ return GPG_ERR_ENOMEM;
+
+ nbytes = N * r128;
+ if (r128 && nbytes / r128 != N)
+ return GPG_ERR_ENOMEM;
+
+ nbytes = 64 + r128;
+ if (nbytes < r128)
+ return GPG_ERR_ENOMEM;
+
+ B = xtrymalloc (p * r128);
+ if (!B)
+ {
+ ec = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ tmp1 = xtrymalloc (N * r128);
+ if (!tmp1)
+ {
+ ec = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ tmp2 = xtrymalloc (64 + r128);
+ if (!tmp2)
+ {
+ ec = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ ec = _gcry_kdf_pkdf2 (passwd, passwdlen, GCRY_MD_SHA256, salt, saltlen,
+ 1 /* iterations */, p * r128, B);
+
+ for (i = 0; !ec && i < p; i++)
+ scrypt_ro_mix (r, &B[i * r128], N, tmp1, tmp2);
+
+ for (i = 0; !ec && i < p; i++)
+ ec = _gcry_kdf_pkdf2 (passwd, passwdlen, GCRY_MD_SHA256, B, p * r128,
+ 1 /* iterations */, dkLen, DK);
+
+ leave:
+ xfree (tmp2);
+ xfree (tmp1);
+ xfree (B);
+
+ return ec;
+}
diff --git a/comm/third_party/libgcrypt/cipher/seed.c b/comm/third_party/libgcrypt/cipher/seed.c
new file mode 100644
index 0000000000..2c8958fa82
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/seed.c
@@ -0,0 +1,478 @@
+/* SEED for libgcrypt
+ * Copyright (C) 2006 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
+ *
+ * --
+ * This implementation was provided for libgcrypt in public domain
+ * by Hye-Shik Chang <perky@FreeBSD.org>, July 2006.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-internal.h"
+
+#define NUMKC 16
+
+#define GETU32(pt) buf_get_be32(pt)
+#define PUTU32(ct, st) buf_put_be32(ct, st)
+
+union wordbuf
+{
+ u32 w;
+ byte b[4];
+};
+
+#ifdef WORDS_BIGENDIAN
+#define b0 b[3]
+#define b1 b[2]
+#define b2 b[1]
+#define b3 b[0]
+#else
+#define b0 b[0]
+#define b1 b[1]
+#define b2 b[2]
+#define b3 b[3]
+#endif
+
+static const char *selftest(void);
+
+typedef struct
+{
+ u32 keyschedule[32];
+} SEED_context;
+
+static const u32 SS0[256] = {
+ 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c,
+ 0x2c8ca0ac, 0x25052124, 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
+ 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, 0x28082028, 0x04444044,
+ 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
+ 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310,
+ 0x12c2d2d0, 0x2ecee2ec, 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
+ 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, 0x2ccce0ec, 0x15859194,
+ 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
+ 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc,
+ 0x32c2f2f0, 0x19c9d1d8, 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
+ 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, 0x20406060, 0x10405050,
+ 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
+ 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210,
+ 0x2f8fa3ac, 0x15c5d1d4, 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
+ 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, 0x1f0f131c, 0x19899198,
+ 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
+ 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388,
+ 0x0e0e020c, 0x2b8ba3a8, 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
+ 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, 0x3f8fb3bc, 0x2fcfe3ec,
+ 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
+ 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120,
+ 0x2b4b6368, 0x26466264, 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
+ 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, 0x3a4a7278, 0x07474344,
+ 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
+ 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114,
+ 0x22022220, 0x38083038, 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
+ 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, 0x35053134, 0x0bcbc3c8,
+ 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
+ 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158,
+ 0x02828280, 0x04c4c0c4, 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
+ 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, 0x0f0f030c, 0x0e8e828c,
+ 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
+ 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c,
+ 0x2d0d212c, 0x00404040, 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
+ 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, 0x3b0b3338, 0x1cccd0dc,
+ 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
+ 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328,
+ 0x25456164, 0x3acaf2f8, 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
+ 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, 0x31013130, 0x2acae2e8,
+ 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
+ 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128,
+ 0x07070304, 0x33033330, 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
+ 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298,
+};
+
+static const u32 SS1[256] = {
+ 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2,
+ 0xb03383b3, 0xb83888b0, 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
+ 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, 0xc003c3c3, 0x60224262,
+ 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
+ 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0,
+ 0x34360632, 0x480b4b43, 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
+ 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, 0xc002c2c2, 0x44054541,
+ 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
+ 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1,
+ 0x0c0d0d01, 0xdc1fcfd3, 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
+ 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, 0x40024242, 0xd414c4d0,
+ 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
+ 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20,
+ 0xa82a8aa2, 0x34340430, 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
+ 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, 0x54174753, 0xac2e8ea2,
+ 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
+ 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82,
+ 0x682a4a62, 0xb03181b1, 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
+ 0x20220222, 0x04040400, 0x68284860, 0x70314171, 0x04070703, 0xd81bcbd3,
+ 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
+ 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3,
+ 0xa82b8ba3, 0xd010c0d0, 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
+ 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, 0x94168692, 0x783b4b73,
+ 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
+ 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22,
+ 0xb83a8ab2, 0x6c2e4e62, 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
+ 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, 0x14150511, 0xf83bcbf3,
+ 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
+ 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0,
+ 0xe82acae2, 0x08090901, 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
+ 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, 0xf83acaf2, 0x00010101,
+ 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
+ 0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1,
+ 0x48084840, 0x78394971, 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
+ 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, 0x74374773, 0x54144450,
+ 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
+ 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2,
+ 0xc809c9c1, 0xfc3dcdf1, 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
+ 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, 0x0c0e0e02, 0x50104050,
+ 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
+ 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353,
+ 0x080a0a02, 0x84078783, 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
+ 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3,
+};
+
+static const u32 SS2[256] = {
+ 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d,
+ 0xa0ac2c8c, 0x21242505, 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
+ 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, 0x20282808, 0x40440444,
+ 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
+ 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303,
+ 0xd2d012c2, 0xe2ec2ece, 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
+ 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, 0xe0ec2ccc, 0x91941585,
+ 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
+ 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc,
+ 0xf2f032c2, 0xd1d819c9, 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
+ 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, 0x60602040, 0x50501040,
+ 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
+ 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202,
+ 0xa3ac2f8f, 0xd1d415c5, 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
+ 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, 0x131c1f0f, 0x91981989,
+ 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
+ 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b,
+ 0x020c0e0e, 0xa3a82b8b, 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
+ 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, 0xb3bc3f8f, 0xe3ec2fcf,
+ 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
+ 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101,
+ 0x63682b4b, 0x62642646, 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
+ 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, 0x72783a4a, 0x43440747,
+ 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
+ 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505,
+ 0x22202202, 0x30383808, 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
+ 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, 0x31343505, 0xc3c80bcb,
+ 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
+ 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949,
+ 0x82800282, 0xc0c404c4, 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
+ 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, 0x030c0f0f, 0x828c0e8e,
+ 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
+ 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d,
+ 0x212c2d0d, 0x40400040, 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
+ 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, 0x33383b0b, 0xd0dc1ccc,
+ 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
+ 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b,
+ 0x61642545, 0xf2f83aca, 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
+ 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, 0x31303101, 0xe2e82aca,
+ 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
+ 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909,
+ 0x03040707, 0x33303303, 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
+ 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a,
+};
+
+static const u32 SS3[256] = {
+ 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e,
+ 0x83b3b033, 0x88b0b838, 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
+ 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, 0xc3c3c003, 0x42626022,
+ 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
+ 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c,
+ 0x06323436, 0x4b43480b, 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
+ 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, 0xc2c2c002, 0x45414405,
+ 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
+ 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839,
+ 0x0d010c0d, 0xcfd3dc1f, 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
+ 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, 0x42424002, 0xc4d0d414,
+ 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
+ 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c,
+ 0x8aa2a82a, 0x04303434, 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
+ 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, 0x47535417, 0x8ea2ac2e,
+ 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
+ 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a,
+ 0x4a62682a, 0x81b1b031, 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
+ 0x02222022, 0x04000404, 0x48606828, 0x41717031, 0x07030407, 0xcbd3d81b,
+ 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
+ 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023,
+ 0x8ba3a82b, 0xc0d0d010, 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
+ 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, 0x86929416, 0x4b73783b,
+ 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
+ 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e,
+ 0x8ab2b83a, 0x4e626c2e, 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
+ 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, 0x05111415, 0xcbf3f83b,
+ 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
+ 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434,
+ 0xcae2e82a, 0x09010809, 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
+ 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, 0xcaf2f83a, 0x01010001,
+ 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
+ 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425,
+ 0x48404808, 0x49717839, 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
+ 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, 0x47737437, 0x44505414,
+ 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
+ 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a,
+ 0xc9c1c809, 0xcdf1fc3d, 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
+ 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, 0x0e020c0e, 0x40505010,
+ 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
+ 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013,
+ 0x0a02080a, 0x87838407, 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
+ 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437,
+};
+
+static const u32 KC[NUMKC] = {
+ 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc,
+ 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
+ 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1,
+ 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b,
+};
+
+
+
+/* Perform the key setup.
+ */
+static gcry_err_code_t
+do_setkey (SEED_context *ctx, const byte *key, const unsigned keylen)
+{
+ static int initialized = 0;
+ static const char *selftest_failed=0;
+ u32 x1, x2, x3, x4;
+ union wordbuf t0, t1;
+ u32 *keyout = ctx->keyschedule;
+ int i;
+
+ 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 != 16)
+ return GPG_ERR_INV_KEYLEN;
+
+ x1 = GETU32 (key);
+ x2 = GETU32 (key+4);
+ x3 = GETU32 (key+8);
+ x4 = GETU32 (key+12);
+
+ for (i = 0; i < NUMKC; i++)
+ {
+ t0.w = x1 + x3 - KC[i];
+ t1.w = x2 + KC[i] - x4;
+ *(keyout++) = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3];
+ *(keyout++) = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];
+
+ if (i % 2 == 0)
+ {
+ t0.w = x1;
+ x1 = (x1>>8) ^ (x2<<24);
+ x2 = (x2>>8) ^ (t0.w<<24);
+ }
+ else
+ {
+ t0.w = x3;
+ x3 = (x3<<8) ^ (x4>>24);
+ x4 = (x4<<8) ^ (t0.w>>24);
+ }
+ }
+
+ return 0;
+}
+
+static gcry_err_code_t
+seed_setkey (void *context, const byte *key, const unsigned keylen,
+ cipher_bulk_ops_t *bulk_ops)
+{
+ SEED_context *ctx = context;
+ int rc = do_setkey (ctx, key, keylen);
+ (void)bulk_ops;
+ _gcry_burn_stack (4*6 + sizeof(void*)*2 + sizeof(int)*2);
+ return rc;
+}
+
+
+
+#define OP(X1, X2, X3, X4, rbase) \
+ t0.w = X3 ^ ctx->keyschedule[rbase]; \
+ t1.w = X4 ^ ctx->keyschedule[rbase+1]; \
+ t1.w ^= t0.w; \
+ t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3]; \
+ t0.w += t1.w; \
+ t0.w = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3]; \
+ t1.w += t0.w; \
+ t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3]; \
+ t0.w += t1.w; \
+ X1 ^= t0.w; \
+ X2 ^= t1.w;
+
+/* Encrypt one block. inbuf and outbuf may be the same. */
+static void
+do_encrypt (const SEED_context *ctx, byte *outbuf, const byte *inbuf)
+{
+ u32 x1, x2, x3, x4;
+ union wordbuf t0, t1;
+
+ x1 = GETU32 (inbuf);
+ x2 = GETU32 (inbuf+4);
+ x3 = GETU32 (inbuf+8);
+ x4 = GETU32 (inbuf+12);
+
+ OP (x1, x2, x3, x4, 0);
+ OP (x3, x4, x1, x2, 2);
+ OP (x1, x2, x3, x4, 4);
+ OP (x3, x4, x1, x2, 6);
+ OP (x1, x2, x3, x4, 8);
+ OP (x3, x4, x1, x2, 10);
+ OP (x1, x2, x3, x4, 12);
+ OP (x3, x4, x1, x2, 14);
+ OP (x1, x2, x3, x4, 16);
+ OP (x3, x4, x1, x2, 18);
+ OP (x1, x2, x3, x4, 20);
+ OP (x3, x4, x1, x2, 22);
+ OP (x1, x2, x3, x4, 24);
+ OP (x3, x4, x1, x2, 26);
+ OP (x1, x2, x3, x4, 28);
+ OP (x3, x4, x1, x2, 30);
+
+ PUTU32 (outbuf, x3);
+ PUTU32 (outbuf+4, x4);
+ PUTU32 (outbuf+8, x1);
+ PUTU32 (outbuf+12, x2);
+}
+
+static unsigned int
+seed_encrypt (void *context, byte *outbuf, const byte *inbuf)
+{
+ SEED_context *ctx = context;
+
+ do_encrypt (ctx, outbuf, inbuf);
+ return /*burn_stack*/ (4*6);
+}
+
+
+
+/* Decrypt one block. inbuf and outbuf may be the same. */
+static void
+do_decrypt (SEED_context *ctx, byte *outbuf, const byte *inbuf)
+{
+ u32 x1, x2, x3, x4;
+ union wordbuf t0, t1;
+
+ x1 = GETU32 (inbuf);
+ x2 = GETU32 (inbuf+4);
+ x3 = GETU32 (inbuf+8);
+ x4 = GETU32 (inbuf+12);
+
+ OP (x1, x2, x3, x4, 30);
+ OP (x3, x4, x1, x2, 28);
+ OP (x1, x2, x3, x4, 26);
+ OP (x3, x4, x1, x2, 24);
+ OP (x1, x2, x3, x4, 22);
+ OP (x3, x4, x1, x2, 20);
+ OP (x1, x2, x3, x4, 18);
+ OP (x3, x4, x1, x2, 16);
+ OP (x1, x2, x3, x4, 14);
+ OP (x3, x4, x1, x2, 12);
+ OP (x1, x2, x3, x4, 10);
+ OP (x3, x4, x1, x2, 8);
+ OP (x1, x2, x3, x4, 6);
+ OP (x3, x4, x1, x2, 4);
+ OP (x1, x2, x3, x4, 2);
+ OP (x3, x4, x1, x2, 0);
+
+ PUTU32 (outbuf, x3);
+ PUTU32 (outbuf+4, x4);
+ PUTU32 (outbuf+8, x1);
+ PUTU32 (outbuf+12, x2);
+}
+
+static unsigned int
+seed_decrypt (void *context, byte *outbuf, const byte *inbuf)
+{
+ SEED_context *ctx = context;
+
+ do_decrypt (ctx, outbuf, inbuf);
+ return /*burn_stack*/ (4*6);
+}
+
+
+/* Test a single encryption and decryption with each key size. */
+static const char*
+selftest (void)
+{
+ SEED_context ctx;
+ byte scratch[16];
+
+ /* The test vector is taken from the appendix section B.3 of RFC4269.
+ */
+ static const byte plaintext[16] = {
+ 0x83, 0xA2, 0xF8, 0xA2, 0x88, 0x64, 0x1F, 0xB9,
+ 0xA4, 0xE9, 0xA5, 0xCC, 0x2F, 0x13, 0x1C, 0x7D
+ };
+ static const byte key[16] = {
+ 0x47, 0x06, 0x48, 0x08, 0x51, 0xE6, 0x1B, 0xE8,
+ 0x5D, 0x74, 0xBF, 0xB3, 0xFD, 0x95, 0x61, 0x85
+ };
+ static const byte ciphertext[16] = {
+ 0xEE, 0x54, 0xD1, 0x3E, 0xBC, 0xAE, 0x70, 0x6D,
+ 0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A,
+ };
+
+ seed_setkey (&ctx, key, sizeof(key), NULL);
+ seed_encrypt (&ctx, scratch, plaintext);
+ if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
+ return "SEED test encryption failed.";
+ seed_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext, sizeof (plaintext)))
+ return "SEED test decryption failed.";
+
+ return NULL;
+}
+
+
+
+static gcry_cipher_oid_spec_t seed_oids[] =
+ {
+ { "1.2.410.200004.1.3", GCRY_CIPHER_MODE_ECB },
+ { "1.2.410.200004.1.4", GCRY_CIPHER_MODE_CBC },
+ { "1.2.410.200004.1.5", GCRY_CIPHER_MODE_CFB },
+ { "1.2.410.200004.1.6", GCRY_CIPHER_MODE_OFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_seed =
+ {
+ GCRY_CIPHER_SEED, {0, 0},
+ "SEED", NULL, seed_oids, 16, 128, sizeof (SEED_context),
+ seed_setkey, seed_encrypt, seed_decrypt,
+ };
diff --git a/comm/third_party/libgcrypt/cipher/serpent-armv7-neon.S b/comm/third_party/libgcrypt/cipher/serpent-armv7-neon.S
new file mode 100644
index 0000000000..adff639463
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/serpent-armv7-neon.S
@@ -0,0 +1,1124 @@
+/* serpent-armv7-neon.S - ARM/NEON assembly implementation of Serpent cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_NEON)
+
+.text
+
+.syntax unified
+.fpu neon
+.arm
+
+/* ARM registers */
+#define RROUND r0
+
+/* NEON vector registers */
+#define RA0 q0
+#define RA1 q1
+#define RA2 q2
+#define RA3 q3
+#define RA4 q4
+#define RB0 q5
+#define RB1 q6
+#define RB2 q7
+#define RB3 q8
+#define RB4 q9
+
+#define RT0 q10
+#define RT1 q11
+#define RT2 q12
+#define RT3 q13
+
+#define RA0d0 d0
+#define RA0d1 d1
+#define RA1d0 d2
+#define RA1d1 d3
+#define RA2d0 d4
+#define RA2d1 d5
+#define RA3d0 d6
+#define RA3d1 d7
+#define RA4d0 d8
+#define RA4d1 d9
+#define RB0d0 d10
+#define RB0d1 d11
+#define RB1d0 d12
+#define RB1d1 d13
+#define RB2d0 d14
+#define RB2d1 d15
+#define RB3d0 d16
+#define RB3d1 d17
+#define RB4d0 d18
+#define RB4d1 d19
+#define RT0d0 d20
+#define RT0d1 d21
+#define RT1d0 d22
+#define RT1d1 d23
+#define RT2d0 d24
+#define RT2d1 d25
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+#define transpose_4x4(_q0, _q1, _q2, _q3) \
+ vtrn.32 _q0, _q1; \
+ vtrn.32 _q2, _q3; \
+ vswp _q0##d1, _q2##d0; \
+ vswp _q1##d1, _q3##d0;
+
+/**********************************************************************
+ 8-way serpent
+ **********************************************************************/
+
+/*
+ * 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(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ veor a3, a3, a0; veor b3, b3, b0; vmov a4, a1; vmov b4, b1; \
+ vand a1, a1, a3; vand b1, b1, b3; veor a4, a4, a2; veor b4, b4, b2; \
+ veor a1, a1, a0; veor b1, b1, b0; vorr a0, a0, a3; vorr b0, b0, b3; \
+ veor a0, a0, a4; veor b0, b0, b4; veor a4, a4, a3; veor b4, b4, b3; \
+ veor a3, a3, a2; veor b3, b3, b2; vorr a2, a2, a1; vorr b2, b2, b1; \
+ veor a2, a2, a4; veor b2, b2, b4; vmvn a4, a4; vmvn b4, b4; \
+ vorr a4, a4, a1; vorr b4, b4, b1; veor a1, a1, a3; veor b1, b1, b3; \
+ veor a1, a1, a4; veor b1, b1, b4; vorr a3, a3, a0; vorr b3, b3, b0; \
+ veor a1, a1, a3; veor b1, b1, b3; veor a4, a3; veor b4, b3;
+
+#define SBOX0_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmvn a2, a2; vmvn b2, b2; vmov a4, a1; vmov b4, b1; \
+ vorr a1, a1, a0; vorr b1, b1, b0; vmvn a4, a4; vmvn b4, b4; \
+ veor a1, a1, a2; veor b1, b1, b2; vorr a2, a2, a4; vorr b2, b2, b4; \
+ veor a1, a1, a3; veor b1, b1, b3; veor a0, a0, a4; veor b0, b0, b4; \
+ veor a2, a2, a0; veor b2, b2, b0; vand a0, a0, a3; vand b0, b0, b3; \
+ veor a4, a4, a0; veor b4, b4, b0; vorr a0, a0, a1; vorr b0, b0, b1; \
+ veor a0, a0, a2; veor b0, b0, b2; veor a3, a3, a4; veor b3, b3, b4; \
+ veor a2, a2, a1; veor b2, b2, b1; veor a3, a3, a0; veor b3, b3, b0; \
+ veor a3, a3, a1; veor b3, b3, b1;\
+ vand a2, a2, a3; vand b2, b2, b3;\
+ veor a4, a2; veor b4, b2;
+
+#define SBOX1(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmvn a0, a0; vmvn b0, b0; vmvn a2, a2; vmvn b2, b2; \
+ vmov a4, a0; vmov b4, b0; vand a0, a0, a1; vand b0, b0, b1; \
+ veor a2, a2, a0; veor b2, b2, b0; vorr a0, a0, a3; vorr b0, b0, b3; \
+ veor a3, a3, a2; veor b3, b3, b2; veor a1, a1, a0; veor b1, b1, b0; \
+ veor a0, a0, a4; veor b0, b0, b4; vorr a4, a4, a1; vorr b4, b4, b1; \
+ veor a1, a1, a3; veor b1, b1, b3; vorr a2, a2, a0; vorr b2, b2, b0; \
+ vand a2, a2, a4; vand b2, b2, b4; veor a0, a0, a1; veor b0, b0, b1; \
+ vand a1, a1, a2; vand b1, b1, b2;\
+ veor a1, a1, a0; veor b1, b1, b0; vand a0, a0, a2; vand b0, b0, b2; \
+ veor a0, a4; veor b0, b4;
+
+#define SBOX1_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmov a4, a1; vmov b4, b1; veor a1, a1, a3; veor b1, b1, b3; \
+ vand a3, a3, a1; vand b3, b3, b1; veor a4, a4, a2; veor b4, b4, b2; \
+ veor a3, a3, a0; veor b3, b3, b0; vorr a0, a0, a1; vorr b0, b0, b1; \
+ veor a2, a2, a3; veor b2, b2, b3; veor a0, a0, a4; veor b0, b0, b4; \
+ vorr a0, a0, a2; vorr b0, b0, b2; veor a1, a1, a3; veor b1, b1, b3; \
+ veor a0, a0, a1; veor b0, b0, b1; vorr a1, a1, a3; vorr b1, b1, b3; \
+ veor a1, a1, a0; veor b1, b1, b0; vmvn a4, a4; vmvn b4, b4; \
+ veor a4, a4, a1; veor b4, b4, b1; vorr a1, a1, a0; vorr b1, b1, b0; \
+ veor a1, a1, a0; veor b1, b1, b0;\
+ vorr a1, a1, a4; vorr b1, b1, b4;\
+ veor a3, a1; veor b3, b1;
+
+#define SBOX2(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmov a4, a0; vmov b4, b0; vand a0, a0, a2; vand b0, b0, b2; \
+ veor a0, a0, a3; veor b0, b0, b3; veor a2, a2, a1; veor b2, b2, b1; \
+ veor a2, a2, a0; veor b2, b2, b0; vorr a3, a3, a4; vorr b3, b3, b4; \
+ veor a3, a3, a1; veor b3, b3, b1; veor a4, a4, a2; veor b4, b4, b2; \
+ vmov a1, a3; vmov b1, b3; vorr a3, a3, a4; vorr b3, b3, b4; \
+ veor a3, a3, a0; veor b3, b3, b0; vand a0, a0, a1; vand b0, b0, b1; \
+ veor a4, a4, a0; veor b4, b4, b0; veor a1, a1, a3; veor b1, b1, b3; \
+ veor a1, a1, a4; veor b1, b1, b4; vmvn a4, a4; vmvn b4, b4;
+
+#define SBOX2_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ veor a2, a2, a3; veor b2, b2, b3; veor a3, a3, a0; veor b3, b3, b0; \
+ vmov a4, a3; vmov b4, b3; vand a3, a3, a2; vand b3, b3, b2; \
+ veor a3, a3, a1; veor b3, b3, b1; vorr a1, a1, a2; vorr b1, b1, b2; \
+ veor a1, a1, a4; veor b1, b1, b4; vand a4, a4, a3; vand b4, b4, b3; \
+ veor a2, a2, a3; veor b2, b2, b3; vand a4, a4, a0; vand b4, b4, b0; \
+ veor a4, a4, a2; veor b4, b4, b2; vand a2, a2, a1; vand b2, b2, b1; \
+ vorr a2, a2, a0; vorr b2, b2, b0; vmvn a3, a3; vmvn b3, b3; \
+ veor a2, a2, a3; veor b2, b2, b3; veor a0, a0, a3; veor b0, b0, b3; \
+ vand a0, a0, a1; vand b0, b0, b1; veor a3, a3, a4; veor b3, b3, b4; \
+ veor a3, a0; veor b3, b0;
+
+#define SBOX3(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmov a4, a0; vmov b4, b0; vorr a0, a0, a3; vorr b0, b0, b3; \
+ veor a3, a3, a1; veor b3, b3, b1; vand a1, a1, a4; vand b1, b1, b4; \
+ veor a4, a4, a2; veor b4, b4, b2; veor a2, a2, a3; veor b2, b2, b3; \
+ vand a3, a3, a0; vand b3, b3, b0; vorr a4, a4, a1; vorr b4, b4, b1; \
+ veor a3, a3, a4; veor b3, b3, b4; veor a0, a0, a1; veor b0, b0, b1; \
+ vand a4, a4, a0; vand b4, b4, b0; veor a1, a1, a3; veor b1, b1, b3; \
+ veor a4, a4, a2; veor b4, b4, b2; vorr a1, a1, a0; vorr b1, b1, b0; \
+ veor a1, a1, a2; veor b1, b1, b2; veor a0, a0, a3; veor b0, b0, b3; \
+ vmov a2, a1; vmov b2, b1; vorr a1, a1, a3; vorr b1, b1, b3; \
+ veor a1, a0; veor b1, b0;
+
+#define SBOX3_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmov a4, a2; vmov b4, b2; veor a2, a2, a1; veor b2, b2, b1; \
+ veor a0, a0, a2; veor b0, b0, b2; vand a4, a4, a2; vand b4, b4, b2; \
+ veor a4, a4, a0; veor b4, b4, b0; vand a0, a0, a1; vand b0, b0, b1; \
+ veor a1, a1, a3; veor b1, b1, b3; vorr a3, a3, a4; vorr b3, b3, b4; \
+ veor a2, a2, a3; veor b2, b2, b3; veor a0, a0, a3; veor b0, b0, b3; \
+ veor a1, a1, a4; veor b1, b1, b4; vand a3, a3, a2; vand b3, b3, b2; \
+ veor a3, a3, a1; veor b3, b3, b1; veor a1, a1, a0; veor b1, b1, b0; \
+ vorr a1, a1, a2; vorr b1, b1, b2; veor a0, a0, a3; veor b0, b0, b3; \
+ veor a1, a1, a4; veor b1, b1, b4;\
+ veor a0, a1; veor b0, b1;
+
+#define SBOX4(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ veor a1, a1, a3; veor b1, b1, b3; vmvn a3, a3; vmvn b3, b3; \
+ veor a2, a2, a3; veor b2, b2, b3; veor a3, a3, a0; veor b3, b3, b0; \
+ vmov a4, a1; vmov b4, b1; vand a1, a1, a3; vand b1, b1, b3; \
+ veor a1, a1, a2; veor b1, b1, b2; veor a4, a4, a3; veor b4, b4, b3; \
+ veor a0, a0, a4; veor b0, b0, b4; vand a2, a2, a4; vand b2, b2, b4; \
+ veor a2, a2, a0; veor b2, b2, b0; vand a0, a0, a1; vand b0, b0, b1; \
+ veor a3, a3, a0; veor b3, b3, b0; vorr a4, a4, a1; vorr b4, b4, b1; \
+ veor a4, a4, a0; veor b4, b4, b0; vorr a0, a0, a3; vorr b0, b0, b3; \
+ veor a0, a0, a2; veor b0, b0, b2; vand a2, a2, a3; vand b2, b2, b3; \
+ vmvn a0, a0; vmvn b0, b0; veor a4, a2; veor b4, b2;
+
+#define SBOX4_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmov a4, a2; vmov b4, b2; vand a2, a2, a3; vand b2, b2, b3; \
+ veor a2, a2, a1; veor b2, b2, b1; vorr a1, a1, a3; vorr b1, b1, b3; \
+ vand a1, a1, a0; vand b1, b1, b0; veor a4, a4, a2; veor b4, b4, b2; \
+ veor a4, a4, a1; veor b4, b4, b1; vand a1, a1, a2; vand b1, b1, b2; \
+ vmvn a0, a0; vmvn b0, b0; veor a3, a3, a4; veor b3, b3, b4; \
+ veor a1, a1, a3; veor b1, b1, b3; vand a3, a3, a0; vand b3, b3, b0; \
+ veor a3, a3, a2; veor b3, b3, b2; veor a0, a0, a1; veor b0, b0, b1; \
+ vand a2, a2, a0; vand b2, b2, b0; veor a3, a3, a0; veor b3, b3, b0; \
+ veor a2, a2, a4; veor b2, b2, b4;\
+ vorr a2, a2, a3; vorr b2, b2, b3; veor a3, a3, a0; veor b3, b3, b0; \
+ veor a2, a1; veor b2, b1;
+
+#define SBOX5(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ veor a0, a0, a1; veor b0, b0, b1; veor a1, a1, a3; veor b1, b1, b3; \
+ vmvn a3, a3; vmvn b3, b3; vmov a4, a1; vmov b4, b1; \
+ vand a1, a1, a0; vand b1, b1, b0; veor a2, a2, a3; veor b2, b2, b3; \
+ veor a1, a1, a2; veor b1, b1, b2; vorr a2, a2, a4; vorr b2, b2, b4; \
+ veor a4, a4, a3; veor b4, b4, b3; vand a3, a3, a1; vand b3, b3, b1; \
+ veor a3, a3, a0; veor b3, b3, b0; veor a4, a4, a1; veor b4, b4, b1; \
+ veor a4, a4, a2; veor b4, b4, b2; veor a2, a2, a0; veor b2, b2, b0; \
+ vand a0, a0, a3; vand b0, b0, b3; vmvn a2, a2; vmvn b2, b2; \
+ veor a0, a0, a4; veor b0, b0, b4; vorr a4, a4, a3; vorr b4, b4, b3; \
+ veor a2, a4; veor b2, b4;
+
+#define SBOX5_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmvn a1, a1; vmvn b1, b1; vmov a4, a3; vmov b4, b3; \
+ veor a2, a2, a1; veor b2, b2, b1; vorr a3, a3, a0; vorr b3, b3, b0; \
+ veor a3, a3, a2; veor b3, b3, b2; vorr a2, a2, a1; vorr b2, b2, b1; \
+ vand a2, a2, a0; vand b2, b2, b0; veor a4, a4, a3; veor b4, b4, b3; \
+ veor a2, a2, a4; veor b2, b2, b4; vorr a4, a4, a0; vorr b4, b4, b0; \
+ veor a4, a4, a1; veor b4, b4, b1; vand a1, a1, a2; vand b1, b1, b2; \
+ veor a1, a1, a3; veor b1, b1, b3; veor a4, a4, a2; veor b4, b4, b2; \
+ vand a3, a3, a4; vand b3, b3, b4; veor a4, a4, a1; veor b4, b4, b1; \
+ veor a3, a3, a4; veor b3, b3, b4; vmvn a4, a4; vmvn b4, b4; \
+ veor a3, a0; veor b3, b0;
+
+#define SBOX6(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmvn a2, a2; vmvn b2, b2; vmov a4, a3; vmov b4, b3; \
+ vand a3, a3, a0; vand b3, b3, b0; veor a0, a0, a4; veor b0, b0, b4; \
+ veor a3, a3, a2; veor b3, b3, b2; vorr a2, a2, a4; vorr b2, b2, b4; \
+ veor a1, a1, a3; veor b1, b1, b3; veor a2, a2, a0; veor b2, b2, b0; \
+ vorr a0, a0, a1; vorr b0, b0, b1; veor a2, a2, a1; veor b2, b2, b1; \
+ veor a4, a4, a0; veor b4, b4, b0; vorr a0, a0, a3; vorr b0, b0, b3; \
+ veor a0, a0, a2; veor b0, b0, b2; veor a4, a4, a3; veor b4, b4, b3; \
+ veor a4, a4, a0; veor b4, b4, b0; vmvn a3, a3; vmvn b3, b3; \
+ vand a2, a2, a4; vand b2, b2, b4;\
+ veor a2, a3; veor b2, b3;
+
+#define SBOX6_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ veor a0, a0, a2; veor b0, b0, b2; vmov a4, a2; vmov b4, b2; \
+ vand a2, a2, a0; vand b2, b2, b0; veor a4, a4, a3; veor b4, b4, b3; \
+ vmvn a2, a2; vmvn b2, b2; veor a3, a3, a1; veor b3, b3, b1; \
+ veor a2, a2, a3; veor b2, b2, b3; vorr a4, a4, a0; vorr b4, b4, b0; \
+ veor a0, a0, a2; veor b0, b0, b2; veor a3, a3, a4; veor b3, b3, b4; \
+ veor a4, a4, a1; veor b4, b4, b1; vand a1, a1, a3; vand b1, b1, b3; \
+ veor a1, a1, a0; veor b1, b1, b0; veor a0, a0, a3; veor b0, b0, b3; \
+ vorr a0, a0, a2; vorr b0, b0, b2; veor a3, a3, a1; veor b3, b3, b1; \
+ veor a4, a0; veor b4, b0;
+
+#define SBOX7(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmov a4, a1; vmov b4, b1; vorr a1, a1, a2; vorr b1, b1, b2; \
+ veor a1, a1, a3; veor b1, b1, b3; veor a4, a4, a2; veor b4, b4, b2; \
+ veor a2, a2, a1; veor b2, b2, b1; vorr a3, a3, a4; vorr b3, b3, b4; \
+ vand a3, a3, a0; vand b3, b3, b0; veor a4, a4, a2; veor b4, b4, b2; \
+ veor a3, a3, a1; veor b3, b3, b1; vorr a1, a1, a4; vorr b1, b1, b4; \
+ veor a1, a1, a0; veor b1, b1, b0; vorr a0, a0, a4; vorr b0, b0, b4; \
+ veor a0, a0, a2; veor b0, b0, b2; veor a1, a1, a4; veor b1, b1, b4; \
+ veor a2, a2, a1; veor b2, b2, b1; vand a1, a1, a0; vand b1, b1, b0; \
+ veor a1, a1, a4; veor b1, b1, b4; vmvn a2, a2; vmvn b2, b2; \
+ vorr a2, a2, a0; vorr b2, b2, b0;\
+ veor a4, a2; veor b4, b2;
+
+#define SBOX7_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vmov a4, a2; vmov b4, b2; veor a2, a2, a0; veor b2, b2, b0; \
+ vand a0, a0, a3; vand b0, b0, b3; vorr a4, a4, a3; vorr b4, b4, b3; \
+ vmvn a2, a2; vmvn b2, b2; veor a3, a3, a1; veor b3, b3, b1; \
+ vorr a1, a1, a0; vorr b1, b1, b0; veor a0, a0, a2; veor b0, b0, b2; \
+ vand a2, a2, a4; vand b2, b2, b4; vand a3, a3, a4; vand b3, b3, b4; \
+ veor a1, a1, a2; veor b1, b1, b2; veor a2, a2, a0; veor b2, b2, b0; \
+ vorr a0, a0, a2; vorr b0, b0, b2; veor a4, a4, a1; veor b4, b4, b1; \
+ veor a0, a0, a3; veor b0, b0, b3; veor a3, a3, a4; veor b3, b3, b4; \
+ vorr a4, a4, a0; vorr b4, b4, b0; veor a3, a3, a2; veor b3, b3, b2; \
+ veor a4, a2; veor b4, b2;
+
+/* Apply SBOX number WHICH to to the block. */
+#define SBOX(which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ SBOX##which (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4)
+
+/* Apply inverse SBOX number WHICH to to the block. */
+#define SBOX_INVERSE(which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ SBOX##which##_INVERSE (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4)
+
+/* XOR round key into block state in a0,a1,a2,a3. a4 used as temporary. */
+#define BLOCK_XOR_KEY(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vdup.32 RT3, RT0d0[0]; \
+ vdup.32 RT1, RT0d0[1]; \
+ vdup.32 RT2, RT0d1[0]; \
+ vdup.32 RT0, RT0d1[1]; \
+ veor a0, a0, RT3; veor b0, b0, RT3; \
+ veor a1, a1, RT1; veor b1, b1, RT1; \
+ veor a2, a2, RT2; veor b2, b2, RT2; \
+ veor a3, a3, RT0; veor b3, b3, RT0;
+
+#define BLOCK_LOAD_KEY_ENC() \
+ vld1.8 {RT0d0, RT0d1}, [RROUND]!;
+
+#define BLOCK_LOAD_KEY_DEC() \
+ vld1.8 {RT0d0, RT0d1}, [RROUND]; \
+ sub RROUND, RROUND, #16
+
+/* Apply the linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vshl.u32 a4, a0, #13; vshl.u32 b4, b0, #13; \
+ vshr.u32 a0, a0, #(32-13); vshr.u32 b0, b0, #(32-13); \
+ veor a0, a0, a4; veor b0, b0, b4; \
+ vshl.u32 a4, a2, #3; vshl.u32 b4, b2, #3; \
+ vshr.u32 a2, a2, #(32-3); vshr.u32 b2, b2, #(32-3); \
+ veor a2, a2, a4; veor b2, b2, b4; \
+ veor a1, a0, a1; veor b1, b0, b1; \
+ veor a1, a2, a1; veor b1, b2, b1; \
+ vshl.u32 a4, a0, #3; vshl.u32 b4, b0, #3; \
+ veor a3, a2, a3; veor b3, b2, b3; \
+ veor a3, a4, a3; veor b3, b4, b3; \
+ vshl.u32 a4, a1, #1; vshl.u32 b4, b1, #1; \
+ vshr.u32 a1, a1, #(32-1); vshr.u32 b1, b1, #(32-1); \
+ veor a1, a1, a4; veor b1, b1, b4; \
+ vshl.u32 a4, a3, #7; vshl.u32 b4, b3, #7; \
+ vshr.u32 a3, a3, #(32-7); vshr.u32 b3, b3, #(32-7); \
+ veor a3, a3, a4; veor b3, b3, b4; \
+ veor a0, a1, a0; veor b0, b1, b0; \
+ veor a0, a3, a0; veor b0, b3, b0; \
+ vshl.u32 a4, a1, #7; vshl.u32 b4, b1, #7; \
+ veor a2, a3, a2; veor b2, b3, b2; \
+ veor a2, a4, a2; veor b2, b4, b2; \
+ vshl.u32 a4, a0, #5; vshl.u32 b4, b0, #5; \
+ vshr.u32 a0, a0, #(32-5); vshr.u32 b0, b0, #(32-5); \
+ veor a0, a0, a4; veor b0, b0, b4; \
+ vshl.u32 a4, a2, #22; vshl.u32 b4, b2, #22; \
+ vshr.u32 a2, a2, #(32-22); vshr.u32 b2, b2, #(32-22); \
+ veor a2, a2, a4; veor b2, b2, b4;
+
+/* Apply the inverse linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+ vshr.u32 a4, a2, #22; vshr.u32 b4, b2, #22; \
+ vshl.u32 a2, a2, #(32-22); vshl.u32 b2, b2, #(32-22); \
+ veor a2, a2, a4; veor b2, b2, b4; \
+ vshr.u32 a4, a0, #5; vshr.u32 b4, b0, #5; \
+ vshl.u32 a0, a0, #(32-5); vshl.u32 b0, b0, #(32-5); \
+ veor a0, a0, a4; veor b0, b0, b4; \
+ vshl.u32 a4, a1, #7; vshl.u32 b4, b1, #7; \
+ veor a2, a3, a2; veor b2, b3, b2; \
+ veor a2, a4, a2; veor b2, b4, b2; \
+ veor a0, a1, a0; veor b0, b1, b0; \
+ veor a0, a3, a0; veor b0, b3, b0; \
+ vshr.u32 a4, a3, #7; vshr.u32 b4, b3, #7; \
+ vshl.u32 a3, a3, #(32-7); vshl.u32 b3, b3, #(32-7); \
+ veor a3, a3, a4; veor b3, b3, b4; \
+ vshr.u32 a4, a1, #1; vshr.u32 b4, b1, #1; \
+ vshl.u32 a1, a1, #(32-1); vshl.u32 b1, b1, #(32-1); \
+ veor a1, a1, a4; veor b1, b1, b4; \
+ vshl.u32 a4, a0, #3; vshl.u32 b4, b0, #3; \
+ veor a3, a2, a3; veor b3, b2, b3; \
+ veor a3, a4, a3; veor b3, b4, b3; \
+ veor a1, a0, a1; veor b1, b0, b1; \
+ veor a1, a2, a1; veor b1, b2, b1; \
+ vshr.u32 a4, a2, #3; vshr.u32 b4, b2, #3; \
+ vshl.u32 a2, a2, #(32-3); vshl.u32 b2, b2, #(32-3); \
+ veor a2, a2, a4; veor b2, b2, b4; \
+ vshr.u32 a4, a0, #13; vshr.u32 b4, b0, #13; \
+ vshl.u32 a0, a0, #(32-13); vshl.u32 b0, b0, #(32-13); \
+ veor a0, a0, a4; veor b0, b0, b4;
+
+/* Apply a Serpent round to eight parallel blocks. This macro increments
+ `round'. */
+#define ROUND(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+ BLOCK_LOAD_KEY_ENC (); \
+ SBOX (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+ LINEAR_TRANSFORMATION (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);
+
+/* Apply the last Serpent round to eight parallel blocks. This macro increments
+ `round'. */
+#define ROUND_LAST(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+ BLOCK_LOAD_KEY_ENC (); \
+ SBOX (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);
+
+/* Apply an inverse Serpent round to eight parallel blocks. This macro
+ increments `round'. */
+#define ROUND_INVERSE(round, which, a0, a1, a2, a3, a4, \
+ na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, \
+ nb0, nb1, nb2, nb3, nb4) \
+ LINEAR_TRANSFORMATION_INVERSE (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+ SBOX_INVERSE (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4); \
+ BLOCK_LOAD_KEY_DEC ();
+
+/* Apply the first inverse Serpent round to eight parallel blocks. This macro
+ increments `round'. */
+#define ROUND_FIRST_INVERSE(round, which, a0, a1, a2, a3, a4, \
+ na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, \
+ nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+ BLOCK_LOAD_KEY_DEC (); \
+ SBOX_INVERSE (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4); \
+ BLOCK_LOAD_KEY_DEC ();
+
+.align 3
+.type __serpent_enc_blk8,%function;
+__serpent_enc_blk8:
+ /* input:
+ * r0: round key pointer
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+ * blocks
+ * output:
+ * RA4, RA1, RA2, RA0, RB4, RB1, RB2, RB0: eight parallel
+ * ciphertext blocks
+ */
+
+ transpose_4x4(RA0, RA1, RA2, RA3);
+ BLOCK_LOAD_KEY_ENC ();
+ transpose_4x4(RB0, RB1, RB2, RB3);
+
+ ROUND (0, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+ RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+ ROUND (1, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+ RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+ ROUND (2, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+ RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+ ROUND (3, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+ RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+ ROUND (4, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+ RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+ ROUND (5, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+ RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+ ROUND (6, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+ ROUND (7, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+ RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+ ROUND (8, 0, RA4, RA1, RA2, RA0, RA3, RA1, RA3, RA2, RA4, RA0,
+ RB4, RB1, RB2, RB0, RB3, RB1, RB3, RB2, RB4, RB0);
+ ROUND (9, 1, RA1, RA3, RA2, RA4, RA0, RA2, RA1, RA4, RA3, RA0,
+ RB1, RB3, RB2, RB4, RB0, RB2, RB1, RB4, RB3, RB0);
+ ROUND (10, 2, RA2, RA1, RA4, RA3, RA0, RA4, RA3, RA1, RA0, RA2,
+ RB2, RB1, RB4, RB3, RB0, RB4, RB3, RB1, RB0, RB2);
+ ROUND (11, 3, RA4, RA3, RA1, RA0, RA2, RA3, RA1, RA0, RA2, RA4,
+ RB4, RB3, RB1, RB0, RB2, RB3, RB1, RB0, RB2, RB4);
+ ROUND (12, 4, RA3, RA1, RA0, RA2, RA4, RA1, RA4, RA3, RA2, RA0,
+ RB3, RB1, RB0, RB2, RB4, RB1, RB4, RB3, RB2, RB0);
+ ROUND (13, 5, RA1, RA4, RA3, RA2, RA0, RA4, RA2, RA1, RA3, RA0,
+ RB1, RB4, RB3, RB2, RB0, RB4, RB2, RB1, RB3, RB0);
+ ROUND (14, 6, RA4, RA2, RA1, RA3, RA0, RA4, RA2, RA0, RA1, RA3,
+ RB4, RB2, RB1, RB3, RB0, RB4, RB2, RB0, RB1, RB3);
+ ROUND (15, 7, RA4, RA2, RA0, RA1, RA3, RA3, RA1, RA2, RA4, RA0,
+ RB4, RB2, RB0, RB1, RB3, RB3, RB1, RB2, RB4, RB0);
+ ROUND (16, 0, RA3, RA1, RA2, RA4, RA0, RA1, RA0, RA2, RA3, RA4,
+ RB3, RB1, RB2, RB4, RB0, RB1, RB0, RB2, RB3, RB4);
+ ROUND (17, 1, RA1, RA0, RA2, RA3, RA4, RA2, RA1, RA3, RA0, RA4,
+ RB1, RB0, RB2, RB3, RB4, RB2, RB1, RB3, RB0, RB4);
+ ROUND (18, 2, RA2, RA1, RA3, RA0, RA4, RA3, RA0, RA1, RA4, RA2,
+ RB2, RB1, RB3, RB0, RB4, RB3, RB0, RB1, RB4, RB2);
+ ROUND (19, 3, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA4, RA2, RA3,
+ RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB4, RB2, RB3);
+ ROUND (20, 4, RA0, RA1, RA4, RA2, RA3, RA1, RA3, RA0, RA2, RA4,
+ RB0, RB1, RB4, RB2, RB3, RB1, RB3, RB0, RB2, RB4);
+ ROUND (21, 5, RA1, RA3, RA0, RA2, RA4, RA3, RA2, RA1, RA0, RA4,
+ RB1, RB3, RB0, RB2, RB4, RB3, RB2, RB1, RB0, RB4);
+ ROUND (22, 6, RA3, RA2, RA1, RA0, RA4, RA3, RA2, RA4, RA1, RA0,
+ RB3, RB2, RB1, RB0, RB4, RB3, RB2, RB4, RB1, RB0);
+ ROUND (23, 7, RA3, RA2, RA4, RA1, RA0, RA0, RA1, RA2, RA3, RA4,
+ RB3, RB2, RB4, RB1, RB0, RB0, RB1, RB2, RB3, RB4);
+ ROUND (24, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+ RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+ ROUND (25, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+ RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+ ROUND (26, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+ RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+ ROUND (27, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+ RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+ ROUND (28, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+ RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+ ROUND (29, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+ RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+ ROUND (30, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+ ROUND_LAST (31, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+ RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+
+ transpose_4x4(RA4, RA1, RA2, RA0);
+ transpose_4x4(RB4, RB1, RB2, RB0);
+
+ bx lr;
+.size __serpent_enc_blk8,.-__serpent_enc_blk8;
+
+.align 3
+.type __serpent_dec_blk8,%function;
+__serpent_dec_blk8:
+ /* input:
+ * r0: round key pointer
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel
+ * ciphertext blocks
+ * output:
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+ * blocks
+ */
+
+ add RROUND, RROUND, #(32*16);
+
+ transpose_4x4(RA0, RA1, RA2, RA3);
+ BLOCK_LOAD_KEY_DEC ();
+ transpose_4x4(RB0, RB1, RB2, RB3);
+
+ ROUND_FIRST_INVERSE (31, 7, RA0, RA1, RA2, RA3, RA4,
+ RA3, RA0, RA1, RA4, RA2,
+ RB0, RB1, RB2, RB3, RB4,
+ RB3, RB0, RB1, RB4, RB2);
+ ROUND_INVERSE (30, 6, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA2, RA4, RA3,
+ RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB2, RB4, RB3);
+ ROUND_INVERSE (29, 5, RA0, RA1, RA2, RA4, RA3, RA1, RA3, RA4, RA2, RA0,
+ RB0, RB1, RB2, RB4, RB3, RB1, RB3, RB4, RB2, RB0);
+ ROUND_INVERSE (28, 4, RA1, RA3, RA4, RA2, RA0, RA1, RA2, RA4, RA0, RA3,
+ RB1, RB3, RB4, RB2, RB0, RB1, RB2, RB4, RB0, RB3);
+ ROUND_INVERSE (27, 3, RA1, RA2, RA4, RA0, RA3, RA4, RA2, RA0, RA1, RA3,
+ RB1, RB2, RB4, RB0, RB3, RB4, RB2, RB0, RB1, RB3);
+ ROUND_INVERSE (26, 2, RA4, RA2, RA0, RA1, RA3, RA2, RA3, RA0, RA1, RA4,
+ RB4, RB2, RB0, RB1, RB3, RB2, RB3, RB0, RB1, RB4);
+ ROUND_INVERSE (25, 1, RA2, RA3, RA0, RA1, RA4, RA4, RA2, RA1, RA0, RA3,
+ RB2, RB3, RB0, RB1, RB4, RB4, RB2, RB1, RB0, RB3);
+ ROUND_INVERSE (24, 0, RA4, RA2, RA1, RA0, RA3, RA4, RA3, RA2, RA0, RA1,
+ RB4, RB2, RB1, RB0, RB3, RB4, RB3, RB2, RB0, RB1);
+ ROUND_INVERSE (23, 7, RA4, RA3, RA2, RA0, RA1, RA0, RA4, RA3, RA1, RA2,
+ RB4, RB3, RB2, RB0, RB1, RB0, RB4, RB3, RB1, RB2);
+ ROUND_INVERSE (22, 6, RA0, RA4, RA3, RA1, RA2, RA4, RA3, RA2, RA1, RA0,
+ RB0, RB4, RB3, RB1, RB2, RB4, RB3, RB2, RB1, RB0);
+ ROUND_INVERSE (21, 5, RA4, RA3, RA2, RA1, RA0, RA3, RA0, RA1, RA2, RA4,
+ RB4, RB3, RB2, RB1, RB0, RB3, RB0, RB1, RB2, RB4);
+ ROUND_INVERSE (20, 4, RA3, RA0, RA1, RA2, RA4, RA3, RA2, RA1, RA4, RA0,
+ RB3, RB0, RB1, RB2, RB4, RB3, RB2, RB1, RB4, RB0);
+ ROUND_INVERSE (19, 3, RA3, RA2, RA1, RA4, RA0, RA1, RA2, RA4, RA3, RA0,
+ RB3, RB2, RB1, RB4, RB0, RB1, RB2, RB4, RB3, RB0);
+ ROUND_INVERSE (18, 2, RA1, RA2, RA4, RA3, RA0, RA2, RA0, RA4, RA3, RA1,
+ RB1, RB2, RB4, RB3, RB0, RB2, RB0, RB4, RB3, RB1);
+ ROUND_INVERSE (17, 1, RA2, RA0, RA4, RA3, RA1, RA1, RA2, RA3, RA4, RA0,
+ RB2, RB0, RB4, RB3, RB1, RB1, RB2, RB3, RB4, RB0);
+ ROUND_INVERSE (16, 0, RA1, RA2, RA3, RA4, RA0, RA1, RA0, RA2, RA4, RA3,
+ RB1, RB2, RB3, RB4, RB0, RB1, RB0, RB2, RB4, RB3);
+ ROUND_INVERSE (15, 7, RA1, RA0, RA2, RA4, RA3, RA4, RA1, RA0, RA3, RA2,
+ RB1, RB0, RB2, RB4, RB3, RB4, RB1, RB0, RB3, RB2);
+ ROUND_INVERSE (14, 6, RA4, RA1, RA0, RA3, RA2, RA1, RA0, RA2, RA3, RA4,
+ RB4, RB1, RB0, RB3, RB2, RB1, RB0, RB2, RB3, RB4);
+ ROUND_INVERSE (13, 5, RA1, RA0, RA2, RA3, RA4, RA0, RA4, RA3, RA2, RA1,
+ RB1, RB0, RB2, RB3, RB4, RB0, RB4, RB3, RB2, RB1);
+ ROUND_INVERSE (12, 4, RA0, RA4, RA3, RA2, RA1, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB4, RB3, RB2, RB1, RB0, RB2, RB3, RB1, RB4);
+ ROUND_INVERSE (11, 3, RA0, RA2, RA3, RA1, RA4, RA3, RA2, RA1, RA0, RA4,
+ RB0, RB2, RB3, RB1, RB4, RB3, RB2, RB1, RB0, RB4);
+ ROUND_INVERSE (10, 2, RA3, RA2, RA1, RA0, RA4, RA2, RA4, RA1, RA0, RA3,
+ RB3, RB2, RB1, RB0, RB4, RB2, RB4, RB1, RB0, RB3);
+ ROUND_INVERSE (9, 1, RA2, RA4, RA1, RA0, RA3, RA3, RA2, RA0, RA1, RA4,
+ RB2, RB4, RB1, RB0, RB3, RB3, RB2, RB0, RB1, RB4);
+ ROUND_INVERSE (8, 0, RA3, RA2, RA0, RA1, RA4, RA3, RA4, RA2, RA1, RA0,
+ RB3, RB2, RB0, RB1, RB4, RB3, RB4, RB2, RB1, RB0);
+ ROUND_INVERSE (7, 7, RA3, RA4, RA2, RA1, RA0, RA1, RA3, RA4, RA0, RA2,
+ RB3, RB4, RB2, RB1, RB0, RB1, RB3, RB4, RB0, RB2);
+ ROUND_INVERSE (6, 6, RA1, RA3, RA4, RA0, RA2, RA3, RA4, RA2, RA0, RA1,
+ RB1, RB3, RB4, RB0, RB2, RB3, RB4, RB2, RB0, RB1);
+ ROUND_INVERSE (5, 5, RA3, RA4, RA2, RA0, RA1, RA4, RA1, RA0, RA2, RA3,
+ RB3, RB4, RB2, RB0, RB1, RB4, RB1, RB0, RB2, RB3);
+ ROUND_INVERSE (4, 4, RA4, RA1, RA0, RA2, RA3, RA4, RA2, RA0, RA3, RA1,
+ RB4, RB1, RB0, RB2, RB3, RB4, RB2, RB0, RB3, RB1);
+ ROUND_INVERSE (3, 3, RA4, RA2, RA0, RA3, RA1, RA0, RA2, RA3, RA4, RA1,
+ RB4, RB2, RB0, RB3, RB1, RB0, RB2, RB3, RB4, RB1);
+ ROUND_INVERSE (2, 2, RA0, RA2, RA3, RA4, RA1, RA2, RA1, RA3, RA4, RA0,
+ RB0, RB2, RB3, RB4, RB1, RB2, RB1, RB3, RB4, RB0);
+ ROUND_INVERSE (1, 1, RA2, RA1, RA3, RA4, RA0, RA0, RA2, RA4, RA3, RA1,
+ RB2, RB1, RB3, RB4, RB0, RB0, RB2, RB4, RB3, RB1);
+ ROUND_INVERSE (0, 0, RA0, RA2, RA4, RA3, RA1, RA0, RA1, RA2, RA3, RA4,
+ RB0, RB2, RB4, RB3, RB1, RB0, RB1, RB2, RB3, RB4);
+
+ transpose_4x4(RA0, RA1, RA2, RA3);
+ transpose_4x4(RB0, RB1, RB2, RB3);
+
+ bx lr;
+.size __serpent_dec_blk8,.-__serpent_dec_blk8;
+
+.align 3
+.globl _gcry_serpent_neon_ctr_enc
+.type _gcry_serpent_neon_ctr_enc,%function;
+_gcry_serpent_neon_ctr_enc:
+ /* input:
+ * r0: ctx, CTX
+ * r1: dst (8 blocks)
+ * r2: src (8 blocks)
+ * r3: iv
+ */
+
+ vmov.u8 RT1d0, #0xff; /* u64: -1 */
+ push {r4,lr};
+ vadd.u64 RT2d0, RT1d0, RT1d0; /* u64: -2 */
+ vpush {RA4-RB2};
+
+ /* load IV and byteswap */
+ vld1.8 {RA0}, [r3];
+ vrev64.u8 RT0, RA0; /* be => le */
+ ldr r4, [r3, #8];
+
+ /* construct IVs */
+ vsub.u64 RA2d1, RT0d1, RT2d0; /* +2 */
+ vsub.u64 RA1d1, RT0d1, RT1d0; /* +1 */
+ cmp r4, #-1;
+
+ vsub.u64 RB0d1, RA2d1, RT2d0; /* +4 */
+ vsub.u64 RA3d1, RA2d1, RT1d0; /* +3 */
+ ldr r4, [r3, #12];
+
+ vsub.u64 RB2d1, RB0d1, RT2d0; /* +6 */
+ vsub.u64 RB1d1, RB0d1, RT1d0; /* +5 */
+
+ vsub.u64 RT2d1, RB2d1, RT2d0; /* +8 */
+ vsub.u64 RB3d1, RB2d1, RT1d0; /* +7 */
+
+ vmov RA1d0, RT0d0;
+ vmov RA2d0, RT0d0;
+ vmov RA3d0, RT0d0;
+ vmov RB0d0, RT0d0;
+ rev r4, r4;
+ vmov RB1d0, RT0d0;
+ vmov RB2d0, RT0d0;
+ vmov RB3d0, RT0d0;
+ vmov RT2d0, RT0d0;
+
+ /* check need for handling 64-bit overflow and carry */
+ beq .Ldo_ctr_carry;
+
+.Lctr_carry_done:
+ /* le => be */
+ vrev64.u8 RA1, RA1;
+ vrev64.u8 RA2, RA2;
+ vrev64.u8 RA3, RA3;
+ vrev64.u8 RB0, RB0;
+ vrev64.u8 RT2, RT2;
+ vrev64.u8 RB1, RB1;
+ vrev64.u8 RB2, RB2;
+ vrev64.u8 RB3, RB3;
+ /* store new IV */
+ vst1.8 {RT2}, [r3];
+
+ bl __serpent_enc_blk8;
+
+ vld1.8 {RT0, RT1}, [r2]!;
+ vld1.8 {RT2, RT3}, [r2]!;
+ veor RA4, RA4, RT0;
+ veor RA1, RA1, RT1;
+ vld1.8 {RT0, RT1}, [r2]!;
+ veor RA2, RA2, RT2;
+ veor RA0, RA0, RT3;
+ vld1.8 {RT2, RT3}, [r2]!;
+ veor RB4, RB4, RT0;
+ veor RT0, RT0;
+ veor RB1, RB1, RT1;
+ veor RT1, RT1;
+ veor RB2, RB2, RT2;
+ veor RT2, RT2;
+ veor RB0, RB0, RT3;
+ veor RT3, RT3;
+
+ vst1.8 {RA4}, [r1]!;
+ vst1.8 {RA1}, [r1]!;
+ veor RA1, RA1;
+ vst1.8 {RA2}, [r1]!;
+ veor RA2, RA2;
+ vst1.8 {RA0}, [r1]!;
+ veor RA0, RA0;
+ vst1.8 {RB4}, [r1]!;
+ veor RB4, RB4;
+ vst1.8 {RB1}, [r1]!;
+ vst1.8 {RB2}, [r1]!;
+ vst1.8 {RB0}, [r1]!;
+
+ vpop {RA4-RB2};
+
+ /* clear the used registers */
+ veor RA3, RA3;
+ veor RB3, RB3;
+
+ pop {r4,pc};
+
+.Ldo_ctr_carry:
+ cmp r4, #-8;
+ blo .Lctr_carry_done;
+ beq .Lcarry_RT2;
+
+ cmp r4, #-6;
+ blo .Lcarry_RB3;
+ beq .Lcarry_RB2;
+
+ cmp r4, #-4;
+ blo .Lcarry_RB1;
+ beq .Lcarry_RB0;
+
+ cmp r4, #-2;
+ blo .Lcarry_RA3;
+ beq .Lcarry_RA2;
+
+ vsub.u64 RA1d0, RT1d0;
+.Lcarry_RA2:
+ vsub.u64 RA2d0, RT1d0;
+.Lcarry_RA3:
+ vsub.u64 RA3d0, RT1d0;
+.Lcarry_RB0:
+ vsub.u64 RB0d0, RT1d0;
+.Lcarry_RB1:
+ vsub.u64 RB1d0, RT1d0;
+.Lcarry_RB2:
+ vsub.u64 RB2d0, RT1d0;
+.Lcarry_RB3:
+ vsub.u64 RB3d0, RT1d0;
+.Lcarry_RT2:
+ vsub.u64 RT2d0, RT1d0;
+
+ b .Lctr_carry_done;
+.size _gcry_serpent_neon_ctr_enc,.-_gcry_serpent_neon_ctr_enc;
+
+.align 3
+.globl _gcry_serpent_neon_cfb_dec
+.type _gcry_serpent_neon_cfb_dec,%function;
+_gcry_serpent_neon_cfb_dec:
+ /* input:
+ * r0: ctx, CTX
+ * r1: dst (8 blocks)
+ * r2: src (8 blocks)
+ * r3: iv
+ */
+
+ push {lr};
+ vpush {RA4-RB2};
+
+ /* Load input */
+ vld1.8 {RA0}, [r3];
+ vld1.8 {RA1, RA2}, [r2]!;
+ vld1.8 {RA3}, [r2]!;
+ vld1.8 {RB0}, [r2]!;
+ vld1.8 {RB1, RB2}, [r2]!;
+ vld1.8 {RB3}, [r2]!;
+
+ /* Update IV */
+ vld1.8 {RT0}, [r2]!;
+ vst1.8 {RT0}, [r3];
+ mov r3, lr;
+ sub r2, r2, #(8*16);
+
+ bl __serpent_enc_blk8;
+
+ vld1.8 {RT0, RT1}, [r2]!;
+ vld1.8 {RT2, RT3}, [r2]!;
+ veor RA4, RA4, RT0;
+ veor RA1, RA1, RT1;
+ vld1.8 {RT0, RT1}, [r2]!;
+ veor RA2, RA2, RT2;
+ veor RA0, RA0, RT3;
+ vld1.8 {RT2, RT3}, [r2]!;
+ veor RB4, RB4, RT0;
+ veor RT0, RT0;
+ veor RB1, RB1, RT1;
+ veor RT1, RT1;
+ veor RB2, RB2, RT2;
+ veor RT2, RT2;
+ veor RB0, RB0, RT3;
+ veor RT3, RT3;
+
+ vst1.8 {RA4}, [r1]!;
+ vst1.8 {RA1}, [r1]!;
+ veor RA1, RA1;
+ vst1.8 {RA2}, [r1]!;
+ veor RA2, RA2;
+ vst1.8 {RA0}, [r1]!;
+ veor RA0, RA0;
+ vst1.8 {RB4}, [r1]!;
+ veor RB4, RB4;
+ vst1.8 {RB1}, [r1]!;
+ vst1.8 {RB2}, [r1]!;
+ vst1.8 {RB0}, [r1]!;
+
+ vpop {RA4-RB2};
+
+ /* clear the used registers */
+ veor RA3, RA3;
+ veor RB3, RB3;
+
+ pop {pc};
+.size _gcry_serpent_neon_cfb_dec,.-_gcry_serpent_neon_cfb_dec;
+
+.align 3
+.globl _gcry_serpent_neon_cbc_dec
+.type _gcry_serpent_neon_cbc_dec,%function;
+_gcry_serpent_neon_cbc_dec:
+ /* input:
+ * r0: ctx, CTX
+ * r1: dst (8 blocks)
+ * r2: src (8 blocks)
+ * r3: iv
+ */
+
+ push {lr};
+ vpush {RA4-RB2};
+
+ vld1.8 {RA0, RA1}, [r2]!;
+ vld1.8 {RA2, RA3}, [r2]!;
+ vld1.8 {RB0, RB1}, [r2]!;
+ vld1.8 {RB2, RB3}, [r2]!;
+ sub r2, r2, #(8*16);
+
+ bl __serpent_dec_blk8;
+
+ vld1.8 {RB4}, [r3];
+ vld1.8 {RT0, RT1}, [r2]!;
+ vld1.8 {RT2, RT3}, [r2]!;
+ veor RA0, RA0, RB4;
+ veor RA1, RA1, RT0;
+ veor RA2, RA2, RT1;
+ vld1.8 {RT0, RT1}, [r2]!;
+ veor RA3, RA3, RT2;
+ veor RB0, RB0, RT3;
+ vld1.8 {RT2, RT3}, [r2]!;
+ veor RB1, RB1, RT0;
+ veor RT0, RT0;
+ veor RB2, RB2, RT1;
+ veor RT1, RT1;
+ veor RB3, RB3, RT2;
+ veor RT2, RT2;
+ vst1.8 {RT3}, [r3]; /* store new IV */
+ veor RT3, RT3;
+
+ vst1.8 {RA0, RA1}, [r1]!;
+ veor RA0, RA0;
+ veor RA1, RA1;
+ vst1.8 {RA2, RA3}, [r1]!;
+ veor RA2, RA2;
+ vst1.8 {RB0, RB1}, [r1]!;
+ veor RA3, RA3;
+ vst1.8 {RB2, RB3}, [r1]!;
+ veor RB3, RB3;
+
+ vpop {RA4-RB2};
+
+ /* clear the used registers */
+ veor RB4, RB4;
+
+ pop {pc};
+.size _gcry_serpent_neon_cbc_dec,.-_gcry_serpent_neon_cbc_dec;
+
+.align 3
+.globl _gcry_serpent_neon_ocb_enc
+.type _gcry_serpent_neon_ocb_enc,%function;
+_gcry_serpent_neon_ocb_enc:
+ /* input:
+ * r0 : ctx, CTX
+ * r1 : dst (8 blocks)
+ * r2 : src (8 blocks)
+ * r3 : offset
+ * sp+0: checksum
+ * sp+4: L pointers (void *L[8])
+ */
+
+ push {r4-r11, ip, lr};
+ add ip, sp, #(10*4);
+
+ vpush {RA4-RB2};
+
+ ldm ip, {r4, lr};
+
+ vld1.8 {RT0}, [r3];
+ vld1.8 {RT1}, [r4];
+
+ /* Load L pointers */
+ ldm lr!, {r5, r6, r7, r8};
+ ldm lr, {r9, r10, r11, ip};
+
+ /* 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) */
+
+ vld1.8 {RA0, RA1}, [r2]!;
+ vld1.8 {RA2, RA3}, [r2]!;
+ vld1.8 {RB0, RB1}, [r2]!;
+ vld1.8 {RB2, RB3}, [r2];
+
+#define OCB_INPUT(lreg, vreg) \
+ vld1.8 {RT3}, [lreg]; \
+ veor RT0, RT3; \
+ veor RT1, vreg; \
+ veor vreg, RT0; \
+ vst1.8 {RT0}, [r1]!;
+
+ OCB_INPUT(r5, RA0);
+ OCB_INPUT(r6, RA1);
+ OCB_INPUT(r7, RA2);
+ OCB_INPUT(r8, RA3);
+ OCB_INPUT(r9, RB0);
+ OCB_INPUT(r10, RB1);
+ OCB_INPUT(r11, RB2);
+ OCB_INPUT(ip, RB3);
+#undef OCB_INPUT
+
+ sub r1, r1, #(8*16);
+ vst1.8 {RT0}, [r3];
+ vst1.8 {RT1}, [r4];
+ mov r2, r1;
+
+ bl __serpent_enc_blk8;
+
+ vld1.8 {RT0, RT1}, [r1]!;
+ veor RT0, RA4, RT0;
+ veor RT1, RA1, RT1;
+ vld1.8 {RT2, RT3}, [r1]!;
+ vst1.8 {RT0, RT1}, [r2]!;
+ veor RT2, RA2, RT2;
+ veor RT3, RA0, RT3;
+ vld1.8 {RT0, RT1}, [r1]!;
+ vst1.8 {RT2, RT3}, [r2]!;
+ veor RT0, RB4, RT0;
+ veor RT1, RB1, RT1;
+ vld1.8 {RT2, RT3}, [r1]!;
+ vst1.8 {RT0, RT1}, [r2]!;
+ veor RT2, RB2, RT2;
+ veor RT3, RB0, RT3;
+ vst1.8 {RT2, RT3}, [r2]!;
+
+ vpop {RA4-RB2};
+
+ /* clear the used registers */
+ veor RA3, RA3;
+ veor RB3, RB3;
+
+ pop {r4-r11, ip, pc};
+.size _gcry_serpent_neon_ocb_enc,.-_gcry_serpent_neon_ocb_enc;
+
+.align 3
+.globl _gcry_serpent_neon_ocb_dec
+.type _gcry_serpent_neon_ocb_dec,%function;
+_gcry_serpent_neon_ocb_dec:
+ /* input:
+ * r0 : ctx, CTX
+ * r1 : dst (8 blocks)
+ * r2 : src (8 blocks)
+ * r3 : offset
+ * sp+0: checksum
+ * sp+4: L pointers (void *L[8])
+ */
+
+ push {r4-r11, ip, lr};
+ add ip, sp, #(10*4);
+
+ vpush {RA4-RB2};
+
+ ldm ip, {r4, lr};
+
+ vld1.8 {RT0}, [r3];
+
+ /* Load L pointers */
+ ldm lr!, {r5, r6, r7, r8};
+ ldm lr, {r9, r10, r11, ip};
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
+
+ vld1.8 {RA0, RA1}, [r2]!;
+ vld1.8 {RA2, RA3}, [r2]!;
+ vld1.8 {RB0, RB1}, [r2]!;
+ vld1.8 {RB2, RB3}, [r2];
+
+#define OCB_INPUT(lreg, vreg) \
+ vld1.8 {RT3}, [lreg]; \
+ veor RT0, RT3; \
+ veor vreg, RT0; \
+ vst1.8 {RT0}, [r1]!;
+
+ OCB_INPUT(r5, RA0);
+ OCB_INPUT(r6, RA1);
+ OCB_INPUT(r7, RA2);
+ OCB_INPUT(r8, RA3);
+ OCB_INPUT(r9, RB0);
+ OCB_INPUT(r10, RB1);
+ OCB_INPUT(r11, RB2);
+ OCB_INPUT(ip, RB3);
+#undef OCB_INPUT
+
+ sub r1, r1, #(8*16);
+ vst1.8 {RT0}, [r3];
+ mov r2, r1;
+
+ bl __serpent_dec_blk8;
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ vld1.8 {RA4}, [r4];
+
+ vld1.8 {RT0, RT1}, [r1]!;
+ veor RA0, RA0, RT0;
+ veor RA1, RA1, RT1;
+ vld1.8 {RT2, RT3}, [r1]!;
+ veor RA4, RA4, RA0;
+ vst1.8 {RA0, RA1}, [r2]!;
+ veor RA4, RA4, RA1;
+ veor RA2, RA2, RT2;
+ veor RA3, RA3, RT3;
+ vld1.8 {RT0, RT1}, [r1]!;
+ veor RA4, RA4, RA2;
+ vst1.8 {RA2, RA3}, [r2]!;
+ veor RA4, RA4, RA3;
+ veor RB0, RB0, RT0;
+ veor RB1, RB1, RT1;
+ vld1.8 {RT2, RT3}, [r1]!;
+ veor RA4, RA4, RB0;
+ vst1.8 {RB0, RB1}, [r2]!;
+ veor RA4, RA4, RB1;
+ veor RB2, RB2, RT2;
+ veor RB3, RB3, RT3;
+ veor RA4, RA4, RB2;
+ vst1.8 {RB2, RB3}, [r2]!;
+
+ veor RA4, RA4, RB3;
+ vst1.8 {RA4}, [r4];
+
+ vpop {RA4-RB2};
+
+ /* clear the used registers */
+ veor RB4, RB4;
+
+ pop {r4-r11, ip, pc};
+.size _gcry_serpent_neon_ocb_dec,.-_gcry_serpent_neon_ocb_dec;
+
+.align 3
+.globl _gcry_serpent_neon_ocb_auth
+.type _gcry_serpent_neon_ocb_auth,%function;
+_gcry_serpent_neon_ocb_auth:
+ /* input:
+ * r0 : ctx, CTX
+ * r1 : abuf (8 blocks)
+ * r2 : offset
+ * r3 : checksum
+ * sp+0: L pointers (void *L[8])
+ */
+
+ push {r5-r11, ip, lr};
+ ldr lr, [sp, #(9*4)];
+
+ vpush {RA4-RB2};
+
+ vld1.8 {RT0}, [r2];
+
+ /* Load L pointers */
+ ldm lr!, {r5, r6, r7, r8};
+ ldm lr, {r9, r10, r11, ip};
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+
+ vld1.8 {RA0, RA1}, [r1]!;
+ vld1.8 {RA2, RA3}, [r1]!;
+ vld1.8 {RB0, RB1}, [r1]!;
+ vld1.8 {RB2, RB3}, [r1];
+
+#define OCB_INPUT(lreg, vreg) \
+ vld1.8 {RT3}, [lreg]; \
+ veor RT0, RT3; \
+ veor vreg, RT0;
+
+ OCB_INPUT(r5, RA0);
+ OCB_INPUT(r6, RA1);
+ OCB_INPUT(r7, RA2);
+ OCB_INPUT(r8, RA3);
+ OCB_INPUT(r9, RB0);
+ OCB_INPUT(r10, RB1);
+ OCB_INPUT(r11, RB2);
+ OCB_INPUT(ip, RB3);
+#undef OCB_INPUT
+
+ vst1.8 {RT0}, [r2];
+
+ bl __serpent_enc_blk8;
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ vld1.8 {RT0}, [r3];
+
+ veor RA4, RB4;
+ veor RA1, RB1;
+ veor RA2, RB2;
+ veor RA0, RB0;
+
+ veor RA2, RT0;
+ veor RA1, RA4;
+ veor RA0, RA2;
+
+ veor RA0, RA1;
+
+ vst1.8 {RA0}, [r3];
+
+ vpop {RA4-RB2};
+
+ /* clear the used registers */
+ veor RA3, RA3;
+ veor RB3, RB3;
+
+ pop {r5-r11, ip, pc};
+.size _gcry_serpent_neon_ocb_auth,.-_gcry_serpent_neon_ocb_auth;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/serpent-avx2-amd64.S b/comm/third_party/libgcrypt/cipher/serpent-avx2-amd64.S
new file mode 100644
index 0000000000..dcee9b62a5
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/serpent-avx2-amd64.S
@@ -0,0 +1,1160 @@
+/* serpent-avx2-amd64.S - AVX2 implementation of Serpent cipher
+ *
+ * Copyright (C) 2013-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#ifdef __x86_64
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_SERPENT) && \
+ defined(ENABLE_AVX2_SUPPORT)
+
+#include "asm-common-amd64.h"
+
+/* struct serpent_context: */
+#define ctx_keys 0
+
+/* register macros */
+#define CTX %rdi
+
+/* vector registers */
+#define RA0 %ymm0
+#define RA1 %ymm1
+#define RA2 %ymm2
+#define RA3 %ymm3
+#define RA4 %ymm4
+
+#define RB0 %ymm5
+#define RB1 %ymm6
+#define RB2 %ymm7
+#define RB3 %ymm8
+#define RB4 %ymm9
+
+#define RNOT %ymm10
+#define RTMP0 %ymm11
+#define RTMP1 %ymm12
+#define RTMP2 %ymm13
+#define RTMP3 %ymm14
+#define RTMP4 %ymm15
+
+#define RNOTx %xmm10
+#define RTMP0x %xmm11
+#define RTMP1x %xmm12
+#define RTMP2x %xmm13
+#define RTMP3x %xmm14
+#define RTMP4x %xmm15
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+/* vector 32-bit rotation to left */
+#define vec_rol(reg, nleft, tmp) \
+ vpslld $(nleft), reg, tmp; \
+ vpsrld $(32 - (nleft)), reg, reg; \
+ vpor tmp, reg, reg;
+
+/* vector 32-bit rotation to right */
+#define vec_ror(reg, nright, tmp) \
+ vec_rol(reg, 32 - nright, tmp)
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
+ vpunpckhdq x1, x0, t2; \
+ vpunpckldq x1, x0, x0; \
+ \
+ vpunpckldq x3, x2, t1; \
+ vpunpckhdq x3, x2, x2; \
+ \
+ vpunpckhqdq t1, x0, x1; \
+ vpunpcklqdq t1, x0, x0; \
+ \
+ vpunpckhqdq x2, t2, x3; \
+ vpunpcklqdq x2, t2, x2;
+
+/**********************************************************************
+ 16-way serpent
+ **********************************************************************/
+
+/*
+ * 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, r4) \
+ vpxor r0, r3, r3; vmovdqa r1, r4; \
+ vpand r3, r1, r1; vpxor r2, r4, r4; \
+ vpxor r0, r1, r1; vpor r3, r0, r0; \
+ vpxor r4, r0, r0; vpxor r3, r4, r4; \
+ vpxor r2, r3, r3; vpor r1, r2, r2; \
+ vpxor r4, r2, r2; vpxor RNOT, r4, r4; \
+ vpor r1, r4, r4; vpxor r3, r1, r1; \
+ vpxor r4, r1, r1; vpor r0, r3, r3; \
+ vpxor r3, r1, r1; vpxor r3, r4, r4;
+
+#define SBOX0_INVERSE(r0, r1, r2, r3, r4) \
+ vpxor RNOT, r2, r2; vmovdqa r1, r4; \
+ vpor r0, r1, r1; vpxor RNOT, r4, r4; \
+ vpxor r2, r1, r1; vpor r4, r2, r2; \
+ vpxor r3, r1, r1; vpxor r4, r0, r0; \
+ vpxor r0, r2, r2; vpand r3, r0, r0; \
+ vpxor r0, r4, r4; vpor r1, r0, r0; \
+ vpxor r2, r0, r0; vpxor r4, r3, r3; \
+ vpxor r1, r2, r2; vpxor r0, r3, r3; \
+ vpxor r1, r3, r3; \
+ vpand r3, r2, r2; \
+ vpxor r2, r4, r4;
+
+#define SBOX1(r0, r1, r2, r3, r4) \
+ vpxor RNOT, r0, r0; vpxor RNOT, r2, r2; \
+ vmovdqa r0, r4; vpand r1, r0, r0; \
+ vpxor r0, r2, r2; vpor r3, r0, r0; \
+ vpxor r2, r3, r3; vpxor r0, r1, r1; \
+ vpxor r4, r0, r0; vpor r1, r4, r4; \
+ vpxor r3, r1, r1; vpor r0, r2, r2; \
+ vpand r4, r2, r2; vpxor r1, r0, r0; \
+ vpand r2, r1, r1; \
+ vpxor r0, r1, r1; vpand r2, r0, r0; \
+ vpxor r4, r0, r0;
+
+#define SBOX1_INVERSE(r0, r1, r2, r3, r4) \
+ vmovdqa r1, r4; vpxor r3, r1, r1; \
+ vpand r1, r3, r3; vpxor r2, r4, r4; \
+ vpxor r0, r3, r3; vpor r1, r0, r0; \
+ vpxor r3, r2, r2; vpxor r4, r0, r0; \
+ vpor r2, r0, r0; vpxor r3, r1, r1; \
+ vpxor r1, r0, r0; vpor r3, r1, r1; \
+ vpxor r0, r1, r1; vpxor RNOT, r4, r4; \
+ vpxor r1, r4, r4; vpor r0, r1, r1; \
+ vpxor r0, r1, r1; \
+ vpor r4, r1, r1; \
+ vpxor r1, r3, r3;
+
+#define SBOX2(r0, r1, r2, r3, r4) \
+ vmovdqa r0, r4; vpand r2, r0, r0; \
+ vpxor r3, r0, r0; vpxor r1, r2, r2; \
+ vpxor r0, r2, r2; vpor r4, r3, r3; \
+ vpxor r1, r3, r3; vpxor r2, r4, r4; \
+ vmovdqa r3, r1; vpor r4, r3, r3; \
+ vpxor r0, r3, r3; vpand r1, r0, r0; \
+ vpxor r0, r4, r4; vpxor r3, r1, r1; \
+ vpxor r4, r1, r1; vpxor RNOT, r4, r4;
+
+#define SBOX2_INVERSE(r0, r1, r2, r3, r4) \
+ vpxor r3, r2, r2; vpxor r0, r3, r3; \
+ vmovdqa r3, r4; vpand r2, r3, r3; \
+ vpxor r1, r3, r3; vpor r2, r1, r1; \
+ vpxor r4, r1, r1; vpand r3, r4, r4; \
+ vpxor r3, r2, r2; vpand r0, r4, r4; \
+ vpxor r2, r4, r4; vpand r1, r2, r2; \
+ vpor r0, r2, r2; vpxor RNOT, r3, r3; \
+ vpxor r3, r2, r2; vpxor r3, r0, r0; \
+ vpand r1, r0, r0; vpxor r4, r3, r3; \
+ vpxor r0, r3, r3;
+
+#define SBOX3(r0, r1, r2, r3, r4) \
+ vmovdqa r0, r4; vpor r3, r0, r0; \
+ vpxor r1, r3, r3; vpand r4, r1, r1; \
+ vpxor r2, r4, r4; vpxor r3, r2, r2; \
+ vpand r0, r3, r3; vpor r1, r4, r4; \
+ vpxor r4, r3, r3; vpxor r1, r0, r0; \
+ vpand r0, r4, r4; vpxor r3, r1, r1; \
+ vpxor r2, r4, r4; vpor r0, r1, r1; \
+ vpxor r2, r1, r1; vpxor r3, r0, r0; \
+ vmovdqa r1, r2; vpor r3, r1, r1; \
+ vpxor r0, r1, r1;
+
+#define SBOX3_INVERSE(r0, r1, r2, r3, r4) \
+ vmovdqa r2, r4; vpxor r1, r2, r2; \
+ vpxor r2, r0, r0; vpand r2, r4, r4; \
+ vpxor r0, r4, r4; vpand r1, r0, r0; \
+ vpxor r3, r1, r1; vpor r4, r3, r3; \
+ vpxor r3, r2, r2; vpxor r3, r0, r0; \
+ vpxor r4, r1, r1; vpand r2, r3, r3; \
+ vpxor r1, r3, r3; vpxor r0, r1, r1; \
+ vpor r2, r1, r1; vpxor r3, r0, r0; \
+ vpxor r4, r1, r1; \
+ vpxor r1, r0, r0;
+
+#define SBOX4(r0, r1, r2, r3, r4) \
+ vpxor r3, r1, r1; vpxor RNOT, r3, r3; \
+ vpxor r3, r2, r2; vpxor r0, r3, r3; \
+ vmovdqa r1, r4; vpand r3, r1, r1; \
+ vpxor r2, r1, r1; vpxor r3, r4, r4; \
+ vpxor r4, r0, r0; vpand r4, r2, r2; \
+ vpxor r0, r2, r2; vpand r1, r0, r0; \
+ vpxor r0, r3, r3; vpor r1, r4, r4; \
+ vpxor r0, r4, r4; vpor r3, r0, r0; \
+ vpxor r2, r0, r0; vpand r3, r2, r2; \
+ vpxor RNOT, r0, r0; vpxor r2, r4, r4;
+
+#define SBOX4_INVERSE(r0, r1, r2, r3, r4) \
+ vmovdqa r2, r4; vpand r3, r2, r2; \
+ vpxor r1, r2, r2; vpor r3, r1, r1; \
+ vpand r0, r1, r1; vpxor r2, r4, r4; \
+ vpxor r1, r4, r4; vpand r2, r1, r1; \
+ vpxor RNOT, r0, r0; vpxor r4, r3, r3; \
+ vpxor r3, r1, r1; vpand r0, r3, r3; \
+ vpxor r2, r3, r3; vpxor r1, r0, r0; \
+ vpand r0, r2, r2; vpxor r0, r3, r3; \
+ vpxor r4, r2, r2; \
+ vpor r3, r2, r2; vpxor r0, r3, r3; \
+ vpxor r1, r2, r2;
+
+#define SBOX5(r0, r1, r2, r3, r4) \
+ vpxor r1, r0, r0; vpxor r3, r1, r1; \
+ vpxor RNOT, r3, r3; vmovdqa r1, r4; \
+ vpand r0, r1, r1; vpxor r3, r2, r2; \
+ vpxor r2, r1, r1; vpor r4, r2, r2; \
+ vpxor r3, r4, r4; vpand r1, r3, r3; \
+ vpxor r0, r3, r3; vpxor r1, r4, r4; \
+ vpxor r2, r4, r4; vpxor r0, r2, r2; \
+ vpand r3, r0, r0; vpxor RNOT, r2, r2; \
+ vpxor r4, r0, r0; vpor r3, r4, r4; \
+ vpxor r4, r2, r2;
+
+#define SBOX5_INVERSE(r0, r1, r2, r3, r4) \
+ vpxor RNOT, r1, r1; vmovdqa r3, r4; \
+ vpxor r1, r2, r2; vpor r0, r3, r3; \
+ vpxor r2, r3, r3; vpor r1, r2, r2; \
+ vpand r0, r2, r2; vpxor r3, r4, r4; \
+ vpxor r4, r2, r2; vpor r0, r4, r4; \
+ vpxor r1, r4, r4; vpand r2, r1, r1; \
+ vpxor r3, r1, r1; vpxor r2, r4, r4; \
+ vpand r4, r3, r3; vpxor r1, r4, r4; \
+ vpxor r4, r3, r3; vpxor RNOT, r4, r4; \
+ vpxor r0, r3, r3;
+
+#define SBOX6(r0, r1, r2, r3, r4) \
+ vpxor RNOT, r2, r2; vmovdqa r3, r4; \
+ vpand r0, r3, r3; vpxor r4, r0, r0; \
+ vpxor r2, r3, r3; vpor r4, r2, r2; \
+ vpxor r3, r1, r1; vpxor r0, r2, r2; \
+ vpor r1, r0, r0; vpxor r1, r2, r2; \
+ vpxor r0, r4, r4; vpor r3, r0, r0; \
+ vpxor r2, r0, r0; vpxor r3, r4, r4; \
+ vpxor r0, r4, r4; vpxor RNOT, r3, r3; \
+ vpand r4, r2, r2; \
+ vpxor r3, r2, r2;
+
+#define SBOX6_INVERSE(r0, r1, r2, r3, r4) \
+ vpxor r2, r0, r0; vmovdqa r2, r4; \
+ vpand r0, r2, r2; vpxor r3, r4, r4; \
+ vpxor RNOT, r2, r2; vpxor r1, r3, r3; \
+ vpxor r3, r2, r2; vpor r0, r4, r4; \
+ vpxor r2, r0, r0; vpxor r4, r3, r3; \
+ vpxor r1, r4, r4; vpand r3, r1, r1; \
+ vpxor r0, r1, r1; vpxor r3, r0, r0; \
+ vpor r2, r0, r0; vpxor r1, r3, r3; \
+ vpxor r0, r4, r4;
+
+#define SBOX7(r0, r1, r2, r3, r4) \
+ vmovdqa r1, r4; vpor r2, r1, r1; \
+ vpxor r3, r1, r1; vpxor r2, r4, r4; \
+ vpxor r1, r2, r2; vpor r4, r3, r3; \
+ vpand r0, r3, r3; vpxor r2, r4, r4; \
+ vpxor r1, r3, r3; vpor r4, r1, r1; \
+ vpxor r0, r1, r1; vpor r4, r0, r0; \
+ vpxor r2, r0, r0; vpxor r4, r1, r1; \
+ vpxor r1, r2, r2; vpand r0, r1, r1; \
+ vpxor r4, r1, r1; vpxor RNOT, r2, r2; \
+ vpor r0, r2, r2; \
+ vpxor r2, r4, r4;
+
+#define SBOX7_INVERSE(r0, r1, r2, r3, r4) \
+ vmovdqa r2, r4; vpxor r0, r2, r2; \
+ vpand r3, r0, r0; vpor r3, r4, r4; \
+ vpxor RNOT, r2, r2; vpxor r1, r3, r3; \
+ vpor r0, r1, r1; vpxor r2, r0, r0; \
+ vpand r4, r2, r2; vpand r4, r3, r3; \
+ vpxor r2, r1, r1; vpxor r0, r2, r2; \
+ vpor r2, r0, r0; vpxor r1, r4, r4; \
+ vpxor r3, r0, r0; vpxor r4, r3, r3; \
+ vpor r0, r4, r4; vpxor r2, r3, r3; \
+ vpxor r2, r4, r4;
+
+/* Apply SBOX number WHICH to to the block. */
+#define SBOX(which, r0, r1, r2, r3, r4) \
+ SBOX##which (r0, r1, r2, r3, r4)
+
+/* Apply inverse SBOX number WHICH to to the block. */
+#define SBOX_INVERSE(which, r0, r1, r2, r3, r4) \
+ SBOX##which##_INVERSE (r0, r1, r2, r3, r4)
+
+/* XOR round key into block state in r0,r1,r2,r3. r4 used as temporary. */
+#define BLOCK_XOR_KEY(r0, r1, r2, r3, r4, round) \
+ vpbroadcastd (ctx_keys + (round) * 16 + 0 * 4)(CTX), r4; \
+ vpxor r4, r0, r0; \
+ vpbroadcastd (ctx_keys + (round) * 16 + 1 * 4)(CTX), r4; \
+ vpxor r4, r1, r1; \
+ vpbroadcastd (ctx_keys + (round) * 16 + 2 * 4)(CTX), r4; \
+ vpxor r4, r2, r2; \
+ vpbroadcastd (ctx_keys + (round) * 16 + 3 * 4)(CTX), r4; \
+ vpxor r4, r3, r3;
+
+/* Apply the linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION(r0, r1, r2, r3, r4) \
+ vec_rol(r0, 13, r4); \
+ vec_rol(r2, 3, r4); \
+ vpxor r0, r1, r1; \
+ vpxor r2, r1, r1; \
+ vpslld $3, r0, r4; \
+ vpxor r2, r3, r3; \
+ vpxor r4, r3, r3; \
+ vec_rol(r1, 1, r4); \
+ vec_rol(r3, 7, r4); \
+ vpxor r1, r0, r0; \
+ vpxor r3, r0, r0; \
+ vpslld $7, r1, r4; \
+ vpxor r3, r2, r2; \
+ vpxor r4, r2, r2; \
+ vec_rol(r0, 5, r4); \
+ vec_rol(r2, 22, r4);
+
+/* Apply the inverse linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION_INVERSE(r0, r1, r2, r3, r4) \
+ vec_ror(r2, 22, r4); \
+ vec_ror(r0, 5, r4); \
+ vpslld $7, r1, r4; \
+ vpxor r3, r2, r2; \
+ vpxor r4, r2, r2; \
+ vpxor r1, r0, r0; \
+ vpxor r3, r0, r0; \
+ vec_ror(r3, 7, r4); \
+ vec_ror(r1, 1, r4); \
+ vpslld $3, r0, r4; \
+ vpxor r2, r3, r3; \
+ vpxor r4, r3, r3; \
+ vpxor r0, r1, r1; \
+ vpxor r2, r1, r1; \
+ vec_ror(r2, 3, r4); \
+ vec_ror(r0, 13, r4);
+
+/* Apply a Serpent round to sixteen parallel blocks. This macro increments
+ `round'. */
+#define ROUND(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round); \
+ SBOX (which, a0, a1, a2, a3, a4); \
+ BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round); \
+ SBOX (which, b0, b1, b2, b3, b4); \
+ LINEAR_TRANSFORMATION (na0, na1, na2, na3, na4); \
+ LINEAR_TRANSFORMATION (nb0, nb1, nb2, nb3, nb4);
+
+/* Apply the last Serpent round to sixteen parallel blocks. This macro
+ increments `round'. */
+#define ROUND_LAST(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round); \
+ SBOX (which, a0, a1, a2, a3, a4); \
+ BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round); \
+ SBOX (which, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, ((round) + 1)); \
+ BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, ((round) + 1));
+
+/* Apply an inverse Serpent round to sixteen parallel blocks. This macro
+ increments `round'. */
+#define ROUND_INVERSE(round, which, a0, a1, a2, a3, a4, \
+ na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, \
+ nb0, nb1, nb2, nb3, nb4) \
+ LINEAR_TRANSFORMATION_INVERSE (a0, a1, a2, a3, a4); \
+ LINEAR_TRANSFORMATION_INVERSE (b0, b1, b2, b3, b4); \
+ SBOX_INVERSE (which, a0, a1, a2, a3, a4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round); \
+ SBOX_INVERSE (which, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
+
+/* Apply the first inverse Serpent round to sixteen parallel blocks. This macro
+ increments `round'. */
+#define ROUND_FIRST_INVERSE(round, which, a0, a1, a2, a3, a4, \
+ na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, \
+ nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, ((round) + 1)); \
+ BLOCK_XOR_KEY (b0, b1, b2, b3, b4, ((round) + 1)); \
+ SBOX_INVERSE (which, a0, a1, a2, a3, a4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round); \
+ SBOX_INVERSE (which, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
+
+.text
+
+.align 8
+ELF(.type __serpent_enc_blk16,@function;)
+__serpent_enc_blk16:
+ /* input:
+ * %rdi: ctx, CTX
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: sixteen parallel
+ * plaintext blocks
+ * output:
+ * RA4, RA1, RA2, RA0, RB4, RB1, RB2, RB0: sixteen parallel
+ * ciphertext blocks
+ */
+ CFI_STARTPROC();
+
+ vpcmpeqd RNOT, RNOT, RNOT;
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+ ROUND (0, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+ RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+ ROUND (1, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+ RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+ ROUND (2, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+ RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+ ROUND (3, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+ RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+ ROUND (4, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+ RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+ ROUND (5, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+ RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+ ROUND (6, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+ ROUND (7, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+ RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+ ROUND (8, 0, RA4, RA1, RA2, RA0, RA3, RA1, RA3, RA2, RA4, RA0,
+ RB4, RB1, RB2, RB0, RB3, RB1, RB3, RB2, RB4, RB0);
+ ROUND (9, 1, RA1, RA3, RA2, RA4, RA0, RA2, RA1, RA4, RA3, RA0,
+ RB1, RB3, RB2, RB4, RB0, RB2, RB1, RB4, RB3, RB0);
+ ROUND (10, 2, RA2, RA1, RA4, RA3, RA0, RA4, RA3, RA1, RA0, RA2,
+ RB2, RB1, RB4, RB3, RB0, RB4, RB3, RB1, RB0, RB2);
+ ROUND (11, 3, RA4, RA3, RA1, RA0, RA2, RA3, RA1, RA0, RA2, RA4,
+ RB4, RB3, RB1, RB0, RB2, RB3, RB1, RB0, RB2, RB4);
+ ROUND (12, 4, RA3, RA1, RA0, RA2, RA4, RA1, RA4, RA3, RA2, RA0,
+ RB3, RB1, RB0, RB2, RB4, RB1, RB4, RB3, RB2, RB0);
+ ROUND (13, 5, RA1, RA4, RA3, RA2, RA0, RA4, RA2, RA1, RA3, RA0,
+ RB1, RB4, RB3, RB2, RB0, RB4, RB2, RB1, RB3, RB0);
+ ROUND (14, 6, RA4, RA2, RA1, RA3, RA0, RA4, RA2, RA0, RA1, RA3,
+ RB4, RB2, RB1, RB3, RB0, RB4, RB2, RB0, RB1, RB3);
+ ROUND (15, 7, RA4, RA2, RA0, RA1, RA3, RA3, RA1, RA2, RA4, RA0,
+ RB4, RB2, RB0, RB1, RB3, RB3, RB1, RB2, RB4, RB0);
+ ROUND (16, 0, RA3, RA1, RA2, RA4, RA0, RA1, RA0, RA2, RA3, RA4,
+ RB3, RB1, RB2, RB4, RB0, RB1, RB0, RB2, RB3, RB4);
+ ROUND (17, 1, RA1, RA0, RA2, RA3, RA4, RA2, RA1, RA3, RA0, RA4,
+ RB1, RB0, RB2, RB3, RB4, RB2, RB1, RB3, RB0, RB4);
+ ROUND (18, 2, RA2, RA1, RA3, RA0, RA4, RA3, RA0, RA1, RA4, RA2,
+ RB2, RB1, RB3, RB0, RB4, RB3, RB0, RB1, RB4, RB2);
+ ROUND (19, 3, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA4, RA2, RA3,
+ RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB4, RB2, RB3);
+ ROUND (20, 4, RA0, RA1, RA4, RA2, RA3, RA1, RA3, RA0, RA2, RA4,
+ RB0, RB1, RB4, RB2, RB3, RB1, RB3, RB0, RB2, RB4);
+ ROUND (21, 5, RA1, RA3, RA0, RA2, RA4, RA3, RA2, RA1, RA0, RA4,
+ RB1, RB3, RB0, RB2, RB4, RB3, RB2, RB1, RB0, RB4);
+ ROUND (22, 6, RA3, RA2, RA1, RA0, RA4, RA3, RA2, RA4, RA1, RA0,
+ RB3, RB2, RB1, RB0, RB4, RB3, RB2, RB4, RB1, RB0);
+ ROUND (23, 7, RA3, RA2, RA4, RA1, RA0, RA0, RA1, RA2, RA3, RA4,
+ RB3, RB2, RB4, RB1, RB0, RB0, RB1, RB2, RB3, RB4);
+ ROUND (24, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+ RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+ ROUND (25, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+ RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+ ROUND (26, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+ RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+ ROUND (27, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+ RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+ ROUND (28, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+ RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+ ROUND (29, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+ RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+ ROUND (30, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+ ROUND_LAST (31, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+ RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+
+ transpose_4x4(RA4, RA1, RA2, RA0, RA3, RTMP0, RTMP1);
+ transpose_4x4(RB4, RB1, RB2, RB0, RB3, RTMP0, RTMP1);
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __serpent_enc_blk16,.-__serpent_enc_blk16;)
+
+.align 8
+ELF(.type __serpent_dec_blk16,@function;)
+__serpent_dec_blk16:
+ /* input:
+ * %rdi: ctx, CTX
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: sixteen parallel
+ * ciphertext blocks
+ * output:
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: sixteen parallel
+ * plaintext blocks
+ */
+ CFI_STARTPROC();
+
+ vpcmpeqd RNOT, RNOT, RNOT;
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+ ROUND_FIRST_INVERSE (31, 7, RA0, RA1, RA2, RA3, RA4,
+ RA3, RA0, RA1, RA4, RA2,
+ RB0, RB1, RB2, RB3, RB4,
+ RB3, RB0, RB1, RB4, RB2);
+ ROUND_INVERSE (30, 6, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA2, RA4, RA3,
+ RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB2, RB4, RB3);
+ ROUND_INVERSE (29, 5, RA0, RA1, RA2, RA4, RA3, RA1, RA3, RA4, RA2, RA0,
+ RB0, RB1, RB2, RB4, RB3, RB1, RB3, RB4, RB2, RB0);
+ ROUND_INVERSE (28, 4, RA1, RA3, RA4, RA2, RA0, RA1, RA2, RA4, RA0, RA3,
+ RB1, RB3, RB4, RB2, RB0, RB1, RB2, RB4, RB0, RB3);
+ ROUND_INVERSE (27, 3, RA1, RA2, RA4, RA0, RA3, RA4, RA2, RA0, RA1, RA3,
+ RB1, RB2, RB4, RB0, RB3, RB4, RB2, RB0, RB1, RB3);
+ ROUND_INVERSE (26, 2, RA4, RA2, RA0, RA1, RA3, RA2, RA3, RA0, RA1, RA4,
+ RB4, RB2, RB0, RB1, RB3, RB2, RB3, RB0, RB1, RB4);
+ ROUND_INVERSE (25, 1, RA2, RA3, RA0, RA1, RA4, RA4, RA2, RA1, RA0, RA3,
+ RB2, RB3, RB0, RB1, RB4, RB4, RB2, RB1, RB0, RB3);
+ ROUND_INVERSE (24, 0, RA4, RA2, RA1, RA0, RA3, RA4, RA3, RA2, RA0, RA1,
+ RB4, RB2, RB1, RB0, RB3, RB4, RB3, RB2, RB0, RB1);
+ ROUND_INVERSE (23, 7, RA4, RA3, RA2, RA0, RA1, RA0, RA4, RA3, RA1, RA2,
+ RB4, RB3, RB2, RB0, RB1, RB0, RB4, RB3, RB1, RB2);
+ ROUND_INVERSE (22, 6, RA0, RA4, RA3, RA1, RA2, RA4, RA3, RA2, RA1, RA0,
+ RB0, RB4, RB3, RB1, RB2, RB4, RB3, RB2, RB1, RB0);
+ ROUND_INVERSE (21, 5, RA4, RA3, RA2, RA1, RA0, RA3, RA0, RA1, RA2, RA4,
+ RB4, RB3, RB2, RB1, RB0, RB3, RB0, RB1, RB2, RB4);
+ ROUND_INVERSE (20, 4, RA3, RA0, RA1, RA2, RA4, RA3, RA2, RA1, RA4, RA0,
+ RB3, RB0, RB1, RB2, RB4, RB3, RB2, RB1, RB4, RB0);
+ ROUND_INVERSE (19, 3, RA3, RA2, RA1, RA4, RA0, RA1, RA2, RA4, RA3, RA0,
+ RB3, RB2, RB1, RB4, RB0, RB1, RB2, RB4, RB3, RB0);
+ ROUND_INVERSE (18, 2, RA1, RA2, RA4, RA3, RA0, RA2, RA0, RA4, RA3, RA1,
+ RB1, RB2, RB4, RB3, RB0, RB2, RB0, RB4, RB3, RB1);
+ ROUND_INVERSE (17, 1, RA2, RA0, RA4, RA3, RA1, RA1, RA2, RA3, RA4, RA0,
+ RB2, RB0, RB4, RB3, RB1, RB1, RB2, RB3, RB4, RB0);
+ ROUND_INVERSE (16, 0, RA1, RA2, RA3, RA4, RA0, RA1, RA0, RA2, RA4, RA3,
+ RB1, RB2, RB3, RB4, RB0, RB1, RB0, RB2, RB4, RB3);
+ ROUND_INVERSE (15, 7, RA1, RA0, RA2, RA4, RA3, RA4, RA1, RA0, RA3, RA2,
+ RB1, RB0, RB2, RB4, RB3, RB4, RB1, RB0, RB3, RB2);
+ ROUND_INVERSE (14, 6, RA4, RA1, RA0, RA3, RA2, RA1, RA0, RA2, RA3, RA4,
+ RB4, RB1, RB0, RB3, RB2, RB1, RB0, RB2, RB3, RB4);
+ ROUND_INVERSE (13, 5, RA1, RA0, RA2, RA3, RA4, RA0, RA4, RA3, RA2, RA1,
+ RB1, RB0, RB2, RB3, RB4, RB0, RB4, RB3, RB2, RB1);
+ ROUND_INVERSE (12, 4, RA0, RA4, RA3, RA2, RA1, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB4, RB3, RB2, RB1, RB0, RB2, RB3, RB1, RB4);
+ ROUND_INVERSE (11, 3, RA0, RA2, RA3, RA1, RA4, RA3, RA2, RA1, RA0, RA4,
+ RB0, RB2, RB3, RB1, RB4, RB3, RB2, RB1, RB0, RB4);
+ ROUND_INVERSE (10, 2, RA3, RA2, RA1, RA0, RA4, RA2, RA4, RA1, RA0, RA3,
+ RB3, RB2, RB1, RB0, RB4, RB2, RB4, RB1, RB0, RB3);
+ ROUND_INVERSE (9, 1, RA2, RA4, RA1, RA0, RA3, RA3, RA2, RA0, RA1, RA4,
+ RB2, RB4, RB1, RB0, RB3, RB3, RB2, RB0, RB1, RB4);
+ ROUND_INVERSE (8, 0, RA3, RA2, RA0, RA1, RA4, RA3, RA4, RA2, RA1, RA0,
+ RB3, RB2, RB0, RB1, RB4, RB3, RB4, RB2, RB1, RB0);
+ ROUND_INVERSE (7, 7, RA3, RA4, RA2, RA1, RA0, RA1, RA3, RA4, RA0, RA2,
+ RB3, RB4, RB2, RB1, RB0, RB1, RB3, RB4, RB0, RB2);
+ ROUND_INVERSE (6, 6, RA1, RA3, RA4, RA0, RA2, RA3, RA4, RA2, RA0, RA1,
+ RB1, RB3, RB4, RB0, RB2, RB3, RB4, RB2, RB0, RB1);
+ ROUND_INVERSE (5, 5, RA3, RA4, RA2, RA0, RA1, RA4, RA1, RA0, RA2, RA3,
+ RB3, RB4, RB2, RB0, RB1, RB4, RB1, RB0, RB2, RB3);
+ ROUND_INVERSE (4, 4, RA4, RA1, RA0, RA2, RA3, RA4, RA2, RA0, RA3, RA1,
+ RB4, RB1, RB0, RB2, RB3, RB4, RB2, RB0, RB3, RB1);
+ ROUND_INVERSE (3, 3, RA4, RA2, RA0, RA3, RA1, RA0, RA2, RA3, RA4, RA1,
+ RB4, RB2, RB0, RB3, RB1, RB0, RB2, RB3, RB4, RB1);
+ ROUND_INVERSE (2, 2, RA0, RA2, RA3, RA4, RA1, RA2, RA1, RA3, RA4, RA0,
+ RB0, RB2, RB3, RB4, RB1, RB2, RB1, RB3, RB4, RB0);
+ ROUND_INVERSE (1, 1, RA2, RA1, RA3, RA4, RA0, RA0, RA2, RA4, RA3, RA1,
+ RB2, RB1, RB3, RB4, RB0, RB0, RB2, RB4, RB3, RB1);
+ ROUND_INVERSE (0, 0, RA0, RA2, RA4, RA3, RA1, RA0, RA1, RA2, RA3, RA4,
+ RB0, RB2, RB4, RB3, RB1, RB0, RB1, RB2, RB3, RB4);
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __serpent_dec_blk16,.-__serpent_dec_blk16;)
+
+#define inc_le128(x, minus_one, tmp) \
+ vpcmpeqq minus_one, x, tmp; \
+ vpsubq minus_one, x, x; \
+ vpslldq $8, tmp, tmp; \
+ vpsubq tmp, x, x;
+
+.align 8
+.globl _gcry_serpent_avx2_ctr_enc
+ELF(.type _gcry_serpent_avx2_ctr_enc,@function;)
+_gcry_serpent_avx2_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv (big endian, 128bit)
+ */
+ CFI_STARTPROC();
+
+ movq 8(%rcx), %rax;
+ bswapq %rax;
+
+ vzeroupper;
+
+ vbroadcasti128 .Lbswap128_mask rRIP, RTMP3;
+ vpcmpeqd RNOT, RNOT, RNOT;
+ vpsrldq $8, RNOT, RNOT; /* ab: -1:0 ; cd: -1:0 */
+ vpaddq RNOT, RNOT, RTMP2; /* ab: -2:0 ; cd: -2:0 */
+
+ /* load IV and byteswap */
+ vmovdqu (%rcx), RTMP4x;
+ vpshufb RTMP3x, RTMP4x, RTMP4x;
+ vmovdqa RTMP4x, RTMP0x;
+ inc_le128(RTMP4x, RNOTx, RTMP1x);
+ vinserti128 $1, RTMP4x, RTMP0, RTMP0;
+ vpshufb RTMP3, RTMP0, RA0; /* +1 ; +0 */
+
+ /* check need for handling 64-bit overflow and carry */
+ cmpq $(0xffffffffffffffff - 16), %rax;
+ ja .Lhandle_ctr_carry;
+
+ /* construct IVs */
+ vpsubq RTMP2, RTMP0, RTMP0; /* +3 ; +2 */
+ vpshufb RTMP3, RTMP0, RA1;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +5 ; +4 */
+ vpshufb RTMP3, RTMP0, RA2;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +7 ; +6 */
+ vpshufb RTMP3, RTMP0, RA3;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +9 ; +8 */
+ vpshufb RTMP3, RTMP0, RB0;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +11 ; +10 */
+ vpshufb RTMP3, RTMP0, RB1;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +13 ; +12 */
+ vpshufb RTMP3, RTMP0, RB2;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +15 ; +14 */
+ vpshufb RTMP3, RTMP0, RB3;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +16 */
+ vpshufb RTMP3x, RTMP0x, RTMP0x;
+
+ jmp .Lctr_carry_done;
+
+.Lhandle_ctr_carry:
+ /* construct IVs */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RA1; /* +3 ; +2 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RA2; /* +5 ; +4 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RA3; /* +7 ; +6 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB0; /* +9 ; +8 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB1; /* +11 ; +10 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB2; /* +13 ; +12 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB3; /* +15 ; +14 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vextracti128 $1, RTMP0, RTMP0x;
+ vpshufb RTMP3x, RTMP0x, RTMP0x; /* +16 */
+
+.align 4
+.Lctr_carry_done:
+ /* store new IV */
+ vmovdqu RTMP0x, (%rcx);
+
+ call __serpent_enc_blk16;
+
+ vpxor (0 * 32)(%rdx), RA4, RA4;
+ vpxor (1 * 32)(%rdx), RA1, RA1;
+ vpxor (2 * 32)(%rdx), RA2, RA2;
+ vpxor (3 * 32)(%rdx), RA0, RA0;
+ vpxor (4 * 32)(%rdx), RB4, RB4;
+ vpxor (5 * 32)(%rdx), RB1, RB1;
+ vpxor (6 * 32)(%rdx), RB2, RB2;
+ vpxor (7 * 32)(%rdx), RB0, RB0;
+
+ vmovdqu RA4, (0 * 32)(%rsi);
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vmovdqu RA0, (3 * 32)(%rsi);
+ vmovdqu RB4, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vmovdqu RB0, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_avx2_ctr_enc,.-_gcry_serpent_avx2_ctr_enc;)
+
+.align 8
+.globl _gcry_serpent_avx2_cbc_dec
+ELF(.type _gcry_serpent_avx2_cbc_dec,@function;)
+_gcry_serpent_avx2_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ vmovdqu (0 * 32)(%rdx), RA0;
+ vmovdqu (1 * 32)(%rdx), RA1;
+ vmovdqu (2 * 32)(%rdx), RA2;
+ vmovdqu (3 * 32)(%rdx), RA3;
+ vmovdqu (4 * 32)(%rdx), RB0;
+ vmovdqu (5 * 32)(%rdx), RB1;
+ vmovdqu (6 * 32)(%rdx), RB2;
+ vmovdqu (7 * 32)(%rdx), RB3;
+
+ call __serpent_dec_blk16;
+
+ vmovdqu (%rcx), RNOTx;
+ vinserti128 $1, (%rdx), RNOT, RNOT;
+ vpxor RNOT, RA0, RA0;
+ vpxor (0 * 32 + 16)(%rdx), RA1, RA1;
+ vpxor (1 * 32 + 16)(%rdx), RA2, RA2;
+ vpxor (2 * 32 + 16)(%rdx), RA3, RA3;
+ vpxor (3 * 32 + 16)(%rdx), RB0, RB0;
+ vpxor (4 * 32 + 16)(%rdx), RB1, RB1;
+ vpxor (5 * 32 + 16)(%rdx), RB2, RB2;
+ vpxor (6 * 32 + 16)(%rdx), RB3, RB3;
+ vmovdqu (7 * 32 + 16)(%rdx), RNOTx;
+ vmovdqu RNOTx, (%rcx); /* store new IV */
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vmovdqu RA3, (3 * 32)(%rsi);
+ vmovdqu RB0, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vmovdqu RB3, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_avx2_cbc_dec,.-_gcry_serpent_avx2_cbc_dec;)
+
+.align 8
+.globl _gcry_serpent_avx2_cfb_dec
+ELF(.type _gcry_serpent_avx2_cfb_dec,@function;)
+_gcry_serpent_avx2_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ /* Load input */
+ vmovdqu (%rcx), RNOTx;
+ vinserti128 $1, (%rdx), RNOT, RA0;
+ vmovdqu (0 * 32 + 16)(%rdx), RA1;
+ vmovdqu (1 * 32 + 16)(%rdx), RA2;
+ vmovdqu (2 * 32 + 16)(%rdx), RA3;
+ vmovdqu (3 * 32 + 16)(%rdx), RB0;
+ vmovdqu (4 * 32 + 16)(%rdx), RB1;
+ vmovdqu (5 * 32 + 16)(%rdx), RB2;
+ vmovdqu (6 * 32 + 16)(%rdx), RB3;
+
+ /* Update IV */
+ vmovdqu (7 * 32 + 16)(%rdx), RNOTx;
+ vmovdqu RNOTx, (%rcx);
+
+ call __serpent_enc_blk16;
+
+ vpxor (0 * 32)(%rdx), RA4, RA4;
+ vpxor (1 * 32)(%rdx), RA1, RA1;
+ vpxor (2 * 32)(%rdx), RA2, RA2;
+ vpxor (3 * 32)(%rdx), RA0, RA0;
+ vpxor (4 * 32)(%rdx), RB4, RB4;
+ vpxor (5 * 32)(%rdx), RB1, RB1;
+ vpxor (6 * 32)(%rdx), RB2, RB2;
+ vpxor (7 * 32)(%rdx), RB0, RB0;
+
+ vmovdqu RA4, (0 * 32)(%rsi);
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vmovdqu RA0, (3 * 32)(%rsi);
+ vmovdqu RB4, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vmovdqu RB0, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_avx2_cfb_dec,.-_gcry_serpent_avx2_cfb_dec;)
+
+.align 8
+.globl _gcry_serpent_avx2_ocb_enc
+ELF(.type _gcry_serpent_avx2_ocb_enc,@function;)
+
+_gcry_serpent_avx2_ocb_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rcx), RTMP0x;
+ vmovdqu (%r8), RTMP1x;
+
+ /* 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) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rdx), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RTMP1, RTMP1; \
+ vpxor yreg, RNOT, yreg; \
+ vmovdqu RNOT, (n * 32)(%rsi);
+
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RA1);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(2, %r10, %r11, RA2);
+ OCB_INPUT(3, %r12, %r13, RA3);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %r11, RB0);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(6, %r10, %r11, RB2);
+ OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vmovdqu RTMP0x, (%rcx);
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%r8);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __serpent_enc_blk16;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vpxor (0 * 32)(%rsi), RA4, RA4;
+ vpxor (1 * 32)(%rsi), RA1, RA1;
+ vpxor (2 * 32)(%rsi), RA2, RA2;
+ vpxor (3 * 32)(%rsi), RA0, RA0;
+ vpxor (4 * 32)(%rsi), RB4, RB4;
+ vpxor (5 * 32)(%rsi), RB1, RB1;
+ vpxor (6 * 32)(%rsi), RB2, RB2;
+ vpxor (7 * 32)(%rsi), RB0, RB0;
+
+ vmovdqu RA4, (0 * 32)(%rsi);
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vmovdqu RA0, (3 * 32)(%rsi);
+ vmovdqu RB4, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vmovdqu RB0, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_avx2_ocb_enc,.-_gcry_serpent_avx2_ocb_enc;)
+
+.align 8
+.globl _gcry_serpent_avx2_ocb_dec
+ELF(.type _gcry_serpent_avx2_ocb_dec,@function;)
+
+_gcry_serpent_avx2_ocb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rcx), RTMP0x;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rdx), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RNOT, yreg; \
+ vmovdqu RNOT, (n * 32)(%rsi);
+
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RA1);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(2, %r10, %r11, RA2);
+ OCB_INPUT(3, %r12, %r13, RA3);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %r11, RB0);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(6, %r10, %r11, RB2);
+ OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0x, (%rcx);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __serpent_dec_blk16;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vmovdqu (%r8), RTMP1x;
+
+ vpxor (0 * 32)(%rsi), RA0, RA0;
+ vpxor (1 * 32)(%rsi), RA1, RA1;
+ vpxor (2 * 32)(%rsi), RA2, RA2;
+ vpxor (3 * 32)(%rsi), RA3, RA3;
+ vpxor (4 * 32)(%rsi), RB0, RB0;
+ vpxor (5 * 32)(%rsi), RB1, RB1;
+ vpxor (6 * 32)(%rsi), RB2, RB2;
+ vpxor (7 * 32)(%rsi), RB3, RB3;
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vpxor RA0, RTMP1, RTMP1;
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vpxor RA1, RTMP1, RTMP1;
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vpxor RA2, RTMP1, RTMP1;
+ vmovdqu RA3, (3 * 32)(%rsi);
+ vpxor RA3, RTMP1, RTMP1;
+ vmovdqu RB0, (4 * 32)(%rsi);
+ vpxor RB0, RTMP1, RTMP1;
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vpxor RB1, RTMP1, RTMP1;
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vpxor RB2, RTMP1, RTMP1;
+ vmovdqu RB3, (7 * 32)(%rsi);
+ vpxor RB3, RTMP1, RTMP1;
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%r8);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_avx2_ocb_dec,.-_gcry_serpent_avx2_ocb_dec;)
+
+.align 8
+.globl _gcry_serpent_avx2_ocb_auth
+ELF(.type _gcry_serpent_avx2_ocb_auth,@function;)
+
+_gcry_serpent_avx2_ocb_auth:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: abuf (16 blocks)
+ * %rdx: offset
+ * %rcx: checksum
+ * %r8 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rdx), RTMP0x;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rsi), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RNOT, yreg;
+
+ movq (0 * 8)(%r8), %r10;
+ movq (1 * 8)(%r8), %r11;
+ movq (2 * 8)(%r8), %r12;
+ movq (3 * 8)(%r8), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RA1);
+ movq (4 * 8)(%r8), %r10;
+ movq (5 * 8)(%r8), %r11;
+ movq (6 * 8)(%r8), %r12;
+ movq (7 * 8)(%r8), %r13;
+ OCB_INPUT(2, %r10, %r11, RA2);
+ OCB_INPUT(3, %r12, %r13, RA3);
+ movq (8 * 8)(%r8), %r10;
+ movq (9 * 8)(%r8), %r11;
+ movq (10 * 8)(%r8), %r12;
+ movq (11 * 8)(%r8), %r13;
+ OCB_INPUT(4, %r10, %r11, RB0);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r8), %r10;
+ movq (13 * 8)(%r8), %r11;
+ movq (14 * 8)(%r8), %r12;
+ movq (15 * 8)(%r8), %r13;
+ OCB_INPUT(6, %r10, %r11, RB2);
+ OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0x, (%rdx);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __serpent_enc_blk16;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vpxor RA4, RB4, RA4;
+ vpxor RA1, RB1, RA1;
+ vpxor RA2, RB2, RA2;
+ vpxor RA0, RB0, RA0;
+
+ vpxor RA4, RA1, RA1;
+ vpxor RA2, RA0, RA0;
+
+ vpxor RA1, RA0, RTMP1;
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vpxor (%rcx), RTMP1x, RTMP1x;
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%rcx);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_avx2_ocb_auth,.-_gcry_serpent_avx2_ocb_auth;)
+
+.align 16
+
+/* For CTR-mode IV byteswap */
+.Lbswap128_mask:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+#endif /*defined(USE_SERPENT) && defined(ENABLE_AVX2_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/serpent-sse2-amd64.S b/comm/third_party/libgcrypt/cipher/serpent-sse2-amd64.S
new file mode 100644
index 0000000000..39cba00297
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/serpent-sse2-amd64.S
@@ -0,0 +1,1211 @@
+/* serpent-sse2-amd64.S - SSE2 implementation of Serpent cipher
+ *
+ * Copyright (C) 2013-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_SERPENT)
+
+#include "asm-common-amd64.h"
+
+/* struct serpent_context: */
+#define ctx_keys 0
+
+/* register macros */
+#define CTX %rdi
+
+/* vector registers */
+#define RA0 %xmm0
+#define RA1 %xmm1
+#define RA2 %xmm2
+#define RA3 %xmm3
+#define RA4 %xmm4
+
+#define RB0 %xmm5
+#define RB1 %xmm6
+#define RB2 %xmm7
+#define RB3 %xmm8
+#define RB4 %xmm9
+
+#define RNOT %xmm10
+#define RTMP0 %xmm11
+#define RTMP1 %xmm12
+#define RTMP2 %xmm13
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+/* vector 32-bit rotation to left */
+#define vec_rol(reg, nleft, tmp) \
+ movdqa reg, tmp; \
+ pslld $(nleft), tmp; \
+ psrld $(32 - (nleft)), reg; \
+ por tmp, reg;
+
+/* vector 32-bit rotation to right */
+#define vec_ror(reg, nright, tmp) \
+ vec_rol(reg, 32 - nright, tmp)
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
+ movdqa x0, t2; \
+ punpckhdq x1, t2; \
+ punpckldq x1, x0; \
+ \
+ movdqa x2, t1; \
+ punpckldq x3, t1; \
+ punpckhdq x3, x2; \
+ \
+ movdqa x0, x1; \
+ punpckhqdq t1, x1; \
+ punpcklqdq t1, x0; \
+ \
+ movdqa t2, x3; \
+ punpckhqdq x2, x3; \
+ punpcklqdq x2, t2; \
+ movdqa t2, x2;
+
+/* fill xmm register with 32-bit value from memory */
+#define pbroadcastd(mem32, xreg) \
+ movd mem32, xreg; \
+ pshufd $0, xreg, xreg;
+
+/* xor with unaligned memory operand */
+#define pxor_u(umem128, xreg, t) \
+ movdqu umem128, t; \
+ pxor t, xreg;
+
+/* 128-bit wide byte swap */
+#define pbswap(xreg, t0) \
+ /* reorder 32-bit words, [a,b,c,d] => [d,c,b,a] */ \
+ pshufd $0x1b, xreg, xreg; \
+ /* reorder high&low 16-bit words, [d0,d1,c0,c1] => [d1,d0,c1,c0] */ \
+ pshuflw $0xb1, xreg, xreg; \
+ pshufhw $0xb1, xreg, xreg; \
+ /* reorder bytes in 16-bit words */ \
+ movdqa xreg, t0; \
+ psrlw $8, t0; \
+ psllw $8, xreg; \
+ por t0, xreg;
+
+/**********************************************************************
+ 8-way serpent
+ **********************************************************************/
+
+/*
+ * 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, r4) \
+ pxor r0, r3; movdqa r1, r4; \
+ pand r3, r1; pxor r2, r4; \
+ pxor r0, r1; por r3, r0; \
+ pxor r4, r0; pxor r3, r4; \
+ pxor r2, r3; por r1, r2; \
+ pxor r4, r2; pxor RNOT, r4; \
+ por r1, r4; pxor r3, r1; \
+ pxor r4, r1; por r0, r3; \
+ pxor r3, r1; pxor r3, r4;
+
+#define SBOX0_INVERSE(r0, r1, r2, r3, r4) \
+ pxor RNOT, r2; movdqa r1, r4; \
+ por r0, r1; pxor RNOT, r4; \
+ pxor r2, r1; por r4, r2; \
+ pxor r3, r1; pxor r4, r0; \
+ pxor r0, r2; pand r3, r0; \
+ pxor r0, r4; por r1, r0; \
+ pxor r2, r0; pxor r4, r3; \
+ pxor r1, r2; pxor r0, r3; \
+ pxor r1, r3; \
+ pand r3, r2; \
+ pxor r2, r4;
+
+#define SBOX1(r0, r1, r2, r3, r4) \
+ pxor RNOT, r0; pxor RNOT, r2; \
+ movdqa r0, r4; pand r1, r0; \
+ pxor r0, r2; por r3, r0; \
+ pxor r2, r3; pxor r0, r1; \
+ pxor r4, r0; por r1, r4; \
+ pxor r3, r1; por r0, r2; \
+ pand r4, r2; pxor r1, r0; \
+ pand r2, r1; \
+ pxor r0, r1; pand r2, r0; \
+ pxor r4, r0;
+
+#define SBOX1_INVERSE(r0, r1, r2, r3, r4) \
+ movdqa r1, r4; pxor r3, r1; \
+ pand r1, r3; pxor r2, r4; \
+ pxor r0, r3; por r1, r0; \
+ pxor r3, r2; pxor r4, r0; \
+ por r2, r0; pxor r3, r1; \
+ pxor r1, r0; por r3, r1; \
+ pxor r0, r1; pxor RNOT, r4; \
+ pxor r1, r4; por r0, r1; \
+ pxor r0, r1; \
+ por r4, r1; \
+ pxor r1, r3;
+
+#define SBOX2(r0, r1, r2, r3, r4) \
+ movdqa r0, r4; pand r2, r0; \
+ pxor r3, r0; pxor r1, r2; \
+ pxor r0, r2; por r4, r3; \
+ pxor r1, r3; pxor r2, r4; \
+ movdqa r3, r1; por r4, r3; \
+ pxor r0, r3; pand r1, r0; \
+ pxor r0, r4; pxor r3, r1; \
+ pxor r4, r1; pxor RNOT, r4;
+
+#define SBOX2_INVERSE(r0, r1, r2, r3, r4) \
+ pxor r3, r2; pxor r0, r3; \
+ movdqa r3, r4; pand r2, r3; \
+ pxor r1, r3; por r2, r1; \
+ pxor r4, r1; pand r3, r4; \
+ pxor r3, r2; pand r0, r4; \
+ pxor r2, r4; pand r1, r2; \
+ por r0, r2; pxor RNOT, r3; \
+ pxor r3, r2; pxor r3, r0; \
+ pand r1, r0; pxor r4, r3; \
+ pxor r0, r3;
+
+#define SBOX3(r0, r1, r2, r3, r4) \
+ movdqa r0, r4; por r3, r0; \
+ pxor r1, r3; pand r4, r1; \
+ pxor r2, r4; pxor r3, r2; \
+ pand r0, r3; por r1, r4; \
+ pxor r4, r3; pxor r1, r0; \
+ pand r0, r4; pxor r3, r1; \
+ pxor r2, r4; por r0, r1; \
+ pxor r2, r1; pxor r3, r0; \
+ movdqa r1, r2; por r3, r1; \
+ pxor r0, r1;
+
+#define SBOX3_INVERSE(r0, r1, r2, r3, r4) \
+ movdqa r2, r4; pxor r1, r2; \
+ pxor r2, r0; pand r2, r4; \
+ pxor r0, r4; pand r1, r0; \
+ pxor r3, r1; por r4, r3; \
+ pxor r3, r2; pxor r3, r0; \
+ pxor r4, r1; pand r2, r3; \
+ pxor r1, r3; pxor r0, r1; \
+ por r2, r1; pxor r3, r0; \
+ pxor r4, r1; \
+ pxor r1, r0;
+
+#define SBOX4(r0, r1, r2, r3, r4) \
+ pxor r3, r1; pxor RNOT, r3; \
+ pxor r3, r2; pxor r0, r3; \
+ movdqa r1, r4; pand r3, r1; \
+ pxor r2, r1; pxor r3, r4; \
+ pxor r4, r0; pand r4, r2; \
+ pxor r0, r2; pand r1, r0; \
+ pxor r0, r3; por r1, r4; \
+ pxor r0, r4; por r3, r0; \
+ pxor r2, r0; pand r3, r2; \
+ pxor RNOT, r0; pxor r2, r4;
+
+#define SBOX4_INVERSE(r0, r1, r2, r3, r4) \
+ movdqa r2, r4; pand r3, r2; \
+ pxor r1, r2; por r3, r1; \
+ pand r0, r1; pxor r2, r4; \
+ pxor r1, r4; pand r2, r1; \
+ pxor RNOT, r0; pxor r4, r3; \
+ pxor r3, r1; pand r0, r3; \
+ pxor r2, r3; pxor r1, r0; \
+ pand r0, r2; pxor r0, r3; \
+ pxor r4, r2; \
+ por r3, r2; pxor r0, r3; \
+ pxor r1, r2;
+
+#define SBOX5(r0, r1, r2, r3, r4) \
+ pxor r1, r0; pxor r3, r1; \
+ pxor RNOT, r3; movdqa r1, r4; \
+ pand r0, r1; pxor r3, r2; \
+ pxor r2, r1; por r4, r2; \
+ pxor r3, r4; pand r1, r3; \
+ pxor r0, r3; pxor r1, r4; \
+ pxor r2, r4; pxor r0, r2; \
+ pand r3, r0; pxor RNOT, r2; \
+ pxor r4, r0; por r3, r4; \
+ pxor r4, r2;
+
+#define SBOX5_INVERSE(r0, r1, r2, r3, r4) \
+ pxor RNOT, r1; movdqa r3, r4; \
+ pxor r1, r2; por r0, r3; \
+ pxor r2, r3; por r1, r2; \
+ pand r0, r2; pxor r3, r4; \
+ pxor r4, r2; por r0, r4; \
+ pxor r1, r4; pand r2, r1; \
+ pxor r3, r1; pxor r2, r4; \
+ pand r4, r3; pxor r1, r4; \
+ pxor r4, r3; pxor RNOT, r4; \
+ pxor r0, r3;
+
+#define SBOX6(r0, r1, r2, r3, r4) \
+ pxor RNOT, r2; movdqa r3, r4; \
+ pand r0, r3; pxor r4, r0; \
+ pxor r2, r3; por r4, r2; \
+ pxor r3, r1; pxor r0, r2; \
+ por r1, r0; pxor r1, r2; \
+ pxor r0, r4; por r3, r0; \
+ pxor r2, r0; pxor r3, r4; \
+ pxor r0, r4; pxor RNOT, r3; \
+ pand r4, r2; \
+ pxor r3, r2;
+
+#define SBOX6_INVERSE(r0, r1, r2, r3, r4) \
+ pxor r2, r0; movdqa r2, r4; \
+ pand r0, r2; pxor r3, r4; \
+ pxor RNOT, r2; pxor r1, r3; \
+ pxor r3, r2; por r0, r4; \
+ pxor r2, r0; pxor r4, r3; \
+ pxor r1, r4; pand r3, r1; \
+ pxor r0, r1; pxor r3, r0; \
+ por r2, r0; pxor r1, r3; \
+ pxor r0, r4;
+
+#define SBOX7(r0, r1, r2, r3, r4) \
+ movdqa r1, r4; por r2, r1; \
+ pxor r3, r1; pxor r2, r4; \
+ pxor r1, r2; por r4, r3; \
+ pand r0, r3; pxor r2, r4; \
+ pxor r1, r3; por r4, r1; \
+ pxor r0, r1; por r4, r0; \
+ pxor r2, r0; pxor r4, r1; \
+ pxor r1, r2; pand r0, r1; \
+ pxor r4, r1; pxor RNOT, r2; \
+ por r0, r2; \
+ pxor r2, r4;
+
+#define SBOX7_INVERSE(r0, r1, r2, r3, r4) \
+ movdqa r2, r4; pxor r0, r2; \
+ pand r3, r0; por r3, r4; \
+ pxor RNOT, r2; pxor r1, r3; \
+ por r0, r1; pxor r2, r0; \
+ pand r4, r2; pand r4, r3; \
+ pxor r2, r1; pxor r0, r2; \
+ por r2, r0; pxor r1, r4; \
+ pxor r3, r0; pxor r4, r3; \
+ por r0, r4; pxor r2, r3; \
+ pxor r2, r4;
+
+/* Apply SBOX number WHICH to to the block. */
+#define SBOX(which, r0, r1, r2, r3, r4) \
+ SBOX##which (r0, r1, r2, r3, r4)
+
+/* Apply inverse SBOX number WHICH to to the block. */
+#define SBOX_INVERSE(which, r0, r1, r2, r3, r4) \
+ SBOX##which##_INVERSE (r0, r1, r2, r3, r4)
+
+/* XOR round key into block state in r0,r1,r2,r3. r4 used as temporary. */
+#define BLOCK_XOR_KEY(r0, r1, r2, r3, r4, round) \
+ pbroadcastd ((ctx_keys + (round) * 16 + 0 * 4)(CTX), r4); \
+ pxor r4, r0; \
+ pbroadcastd ((ctx_keys + (round) * 16 + 1 * 4)(CTX), r4); \
+ pxor r4, r1; \
+ pbroadcastd ((ctx_keys + (round) * 16 + 2 * 4)(CTX), r4); \
+ pxor r4, r2; \
+ pbroadcastd ((ctx_keys + (round) * 16 + 3 * 4)(CTX), r4); \
+ pxor r4, r3;
+
+/* Apply the linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION(r0, r1, r2, r3, r4) \
+ vec_rol(r0, 13, r4); \
+ vec_rol(r2, 3, r4); \
+ pxor r0, r1; \
+ pxor r2, r1; \
+ movdqa r0, r4; \
+ pslld $3, r4; \
+ pxor r2, r3; \
+ pxor r4, r3; \
+ vec_rol(r1, 1, r4); \
+ vec_rol(r3, 7, r4); \
+ pxor r1, r0; \
+ pxor r3, r0; \
+ movdqa r1, r4; \
+ pslld $7, r4; \
+ pxor r3, r2; \
+ pxor r4, r2; \
+ vec_rol(r0, 5, r4); \
+ vec_rol(r2, 22, r4);
+
+/* Apply the inverse linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION_INVERSE(r0, r1, r2, r3, r4) \
+ vec_ror(r2, 22, r4); \
+ vec_ror(r0, 5, r4); \
+ movdqa r1, r4; \
+ pslld $7, r4; \
+ pxor r3, r2; \
+ pxor r4, r2; \
+ pxor r1, r0; \
+ pxor r3, r0; \
+ vec_ror(r3, 7, r4); \
+ vec_ror(r1, 1, r4); \
+ movdqa r0, r4; \
+ pslld $3, r4; \
+ pxor r2, r3; \
+ pxor r4, r3; \
+ pxor r0, r1; \
+ pxor r2, r1; \
+ vec_ror(r2, 3, r4); \
+ vec_ror(r0, 13, r4);
+
+/* Apply a Serpent round to eight parallel blocks. This macro increments
+ `round'. */
+#define ROUND(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round); \
+ SBOX (which, a0, a1, a2, a3, a4); \
+ BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round); \
+ SBOX (which, b0, b1, b2, b3, b4); \
+ LINEAR_TRANSFORMATION (na0, na1, na2, na3, na4); \
+ LINEAR_TRANSFORMATION (nb0, nb1, nb2, nb3, nb4);
+
+/* Apply the last Serpent round to eight parallel blocks. This macro increments
+ `round'. */
+#define ROUND_LAST(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round); \
+ SBOX (which, a0, a1, a2, a3, a4); \
+ BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round); \
+ SBOX (which, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, ((round) + 1)); \
+ BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, ((round) + 1));
+
+/* Apply an inverse Serpent round to eight parallel blocks. This macro
+ increments `round'. */
+#define ROUND_INVERSE(round, which, a0, a1, a2, a3, a4, \
+ na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, \
+ nb0, nb1, nb2, nb3, nb4) \
+ LINEAR_TRANSFORMATION_INVERSE (a0, a1, a2, a3, a4); \
+ LINEAR_TRANSFORMATION_INVERSE (b0, b1, b2, b3, b4); \
+ SBOX_INVERSE (which, a0, a1, a2, a3, a4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round); \
+ SBOX_INVERSE (which, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
+
+/* Apply the first inverse Serpent round to eight parallel blocks. This macro
+ increments `round'. */
+#define ROUND_FIRST_INVERSE(round, which, a0, a1, a2, a3, a4, \
+ na0, na1, na2, na3, na4, \
+ b0, b1, b2, b3, b4, \
+ nb0, nb1, nb2, nb3, nb4) \
+ BLOCK_XOR_KEY (a0, a1, a2, a3, a4, ((round) + 1)); \
+ BLOCK_XOR_KEY (b0, b1, b2, b3, b4, ((round) + 1)); \
+ SBOX_INVERSE (which, a0, a1, a2, a3, a4); \
+ BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round); \
+ SBOX_INVERSE (which, b0, b1, b2, b3, b4); \
+ BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
+
+.text
+
+.align 8
+ELF(.type __serpent_enc_blk8,@function;)
+__serpent_enc_blk8:
+ /* input:
+ * %rdi: ctx, CTX
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+ * blocks
+ * output:
+ * RA4, RA1, RA2, RA0, RB4, RB1, RB2, RB0: eight parallel
+ * ciphertext blocks
+ */
+ CFI_STARTPROC();
+
+ pcmpeqd RNOT, RNOT;
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+ ROUND (0, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+ RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+ ROUND (1, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+ RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+ ROUND (2, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+ RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+ ROUND (3, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+ RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+ ROUND (4, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+ RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+ ROUND (5, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+ RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+ ROUND (6, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+ ROUND (7, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+ RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+ ROUND (8, 0, RA4, RA1, RA2, RA0, RA3, RA1, RA3, RA2, RA4, RA0,
+ RB4, RB1, RB2, RB0, RB3, RB1, RB3, RB2, RB4, RB0);
+ ROUND (9, 1, RA1, RA3, RA2, RA4, RA0, RA2, RA1, RA4, RA3, RA0,
+ RB1, RB3, RB2, RB4, RB0, RB2, RB1, RB4, RB3, RB0);
+ ROUND (10, 2, RA2, RA1, RA4, RA3, RA0, RA4, RA3, RA1, RA0, RA2,
+ RB2, RB1, RB4, RB3, RB0, RB4, RB3, RB1, RB0, RB2);
+ ROUND (11, 3, RA4, RA3, RA1, RA0, RA2, RA3, RA1, RA0, RA2, RA4,
+ RB4, RB3, RB1, RB0, RB2, RB3, RB1, RB0, RB2, RB4);
+ ROUND (12, 4, RA3, RA1, RA0, RA2, RA4, RA1, RA4, RA3, RA2, RA0,
+ RB3, RB1, RB0, RB2, RB4, RB1, RB4, RB3, RB2, RB0);
+ ROUND (13, 5, RA1, RA4, RA3, RA2, RA0, RA4, RA2, RA1, RA3, RA0,
+ RB1, RB4, RB3, RB2, RB0, RB4, RB2, RB1, RB3, RB0);
+ ROUND (14, 6, RA4, RA2, RA1, RA3, RA0, RA4, RA2, RA0, RA1, RA3,
+ RB4, RB2, RB1, RB3, RB0, RB4, RB2, RB0, RB1, RB3);
+ ROUND (15, 7, RA4, RA2, RA0, RA1, RA3, RA3, RA1, RA2, RA4, RA0,
+ RB4, RB2, RB0, RB1, RB3, RB3, RB1, RB2, RB4, RB0);
+ ROUND (16, 0, RA3, RA1, RA2, RA4, RA0, RA1, RA0, RA2, RA3, RA4,
+ RB3, RB1, RB2, RB4, RB0, RB1, RB0, RB2, RB3, RB4);
+ ROUND (17, 1, RA1, RA0, RA2, RA3, RA4, RA2, RA1, RA3, RA0, RA4,
+ RB1, RB0, RB2, RB3, RB4, RB2, RB1, RB3, RB0, RB4);
+ ROUND (18, 2, RA2, RA1, RA3, RA0, RA4, RA3, RA0, RA1, RA4, RA2,
+ RB2, RB1, RB3, RB0, RB4, RB3, RB0, RB1, RB4, RB2);
+ ROUND (19, 3, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA4, RA2, RA3,
+ RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB4, RB2, RB3);
+ ROUND (20, 4, RA0, RA1, RA4, RA2, RA3, RA1, RA3, RA0, RA2, RA4,
+ RB0, RB1, RB4, RB2, RB3, RB1, RB3, RB0, RB2, RB4);
+ ROUND (21, 5, RA1, RA3, RA0, RA2, RA4, RA3, RA2, RA1, RA0, RA4,
+ RB1, RB3, RB0, RB2, RB4, RB3, RB2, RB1, RB0, RB4);
+ ROUND (22, 6, RA3, RA2, RA1, RA0, RA4, RA3, RA2, RA4, RA1, RA0,
+ RB3, RB2, RB1, RB0, RB4, RB3, RB2, RB4, RB1, RB0);
+ ROUND (23, 7, RA3, RA2, RA4, RA1, RA0, RA0, RA1, RA2, RA3, RA4,
+ RB3, RB2, RB4, RB1, RB0, RB0, RB1, RB2, RB3, RB4);
+ ROUND (24, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+ RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+ ROUND (25, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+ RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+ ROUND (26, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+ RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+ ROUND (27, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+ RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+ ROUND (28, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+ RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+ ROUND (29, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+ RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+ ROUND (30, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+ ROUND_LAST (31, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+ RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+
+ transpose_4x4(RA4, RA1, RA2, RA0, RA3, RTMP0, RTMP1);
+ transpose_4x4(RB4, RB1, RB2, RB0, RB3, RTMP0, RTMP1);
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __serpent_enc_blk8,.-__serpent_enc_blk8;)
+
+.align 8
+ELF(.type __serpent_dec_blk8,@function;)
+__serpent_dec_blk8:
+ /* input:
+ * %rdi: ctx, CTX
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel
+ * ciphertext blocks
+ * output:
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+ * blocks
+ */
+ CFI_STARTPROC();
+
+ pcmpeqd RNOT, RNOT;
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+ ROUND_FIRST_INVERSE (31, 7, RA0, RA1, RA2, RA3, RA4,
+ RA3, RA0, RA1, RA4, RA2,
+ RB0, RB1, RB2, RB3, RB4,
+ RB3, RB0, RB1, RB4, RB2);
+ ROUND_INVERSE (30, 6, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA2, RA4, RA3,
+ RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB2, RB4, RB3);
+ ROUND_INVERSE (29, 5, RA0, RA1, RA2, RA4, RA3, RA1, RA3, RA4, RA2, RA0,
+ RB0, RB1, RB2, RB4, RB3, RB1, RB3, RB4, RB2, RB0);
+ ROUND_INVERSE (28, 4, RA1, RA3, RA4, RA2, RA0, RA1, RA2, RA4, RA0, RA3,
+ RB1, RB3, RB4, RB2, RB0, RB1, RB2, RB4, RB0, RB3);
+ ROUND_INVERSE (27, 3, RA1, RA2, RA4, RA0, RA3, RA4, RA2, RA0, RA1, RA3,
+ RB1, RB2, RB4, RB0, RB3, RB4, RB2, RB0, RB1, RB3);
+ ROUND_INVERSE (26, 2, RA4, RA2, RA0, RA1, RA3, RA2, RA3, RA0, RA1, RA4,
+ RB4, RB2, RB0, RB1, RB3, RB2, RB3, RB0, RB1, RB4);
+ ROUND_INVERSE (25, 1, RA2, RA3, RA0, RA1, RA4, RA4, RA2, RA1, RA0, RA3,
+ RB2, RB3, RB0, RB1, RB4, RB4, RB2, RB1, RB0, RB3);
+ ROUND_INVERSE (24, 0, RA4, RA2, RA1, RA0, RA3, RA4, RA3, RA2, RA0, RA1,
+ RB4, RB2, RB1, RB0, RB3, RB4, RB3, RB2, RB0, RB1);
+ ROUND_INVERSE (23, 7, RA4, RA3, RA2, RA0, RA1, RA0, RA4, RA3, RA1, RA2,
+ RB4, RB3, RB2, RB0, RB1, RB0, RB4, RB3, RB1, RB2);
+ ROUND_INVERSE (22, 6, RA0, RA4, RA3, RA1, RA2, RA4, RA3, RA2, RA1, RA0,
+ RB0, RB4, RB3, RB1, RB2, RB4, RB3, RB2, RB1, RB0);
+ ROUND_INVERSE (21, 5, RA4, RA3, RA2, RA1, RA0, RA3, RA0, RA1, RA2, RA4,
+ RB4, RB3, RB2, RB1, RB0, RB3, RB0, RB1, RB2, RB4);
+ ROUND_INVERSE (20, 4, RA3, RA0, RA1, RA2, RA4, RA3, RA2, RA1, RA4, RA0,
+ RB3, RB0, RB1, RB2, RB4, RB3, RB2, RB1, RB4, RB0);
+ ROUND_INVERSE (19, 3, RA3, RA2, RA1, RA4, RA0, RA1, RA2, RA4, RA3, RA0,
+ RB3, RB2, RB1, RB4, RB0, RB1, RB2, RB4, RB3, RB0);
+ ROUND_INVERSE (18, 2, RA1, RA2, RA4, RA3, RA0, RA2, RA0, RA4, RA3, RA1,
+ RB1, RB2, RB4, RB3, RB0, RB2, RB0, RB4, RB3, RB1);
+ ROUND_INVERSE (17, 1, RA2, RA0, RA4, RA3, RA1, RA1, RA2, RA3, RA4, RA0,
+ RB2, RB0, RB4, RB3, RB1, RB1, RB2, RB3, RB4, RB0);
+ ROUND_INVERSE (16, 0, RA1, RA2, RA3, RA4, RA0, RA1, RA0, RA2, RA4, RA3,
+ RB1, RB2, RB3, RB4, RB0, RB1, RB0, RB2, RB4, RB3);
+ ROUND_INVERSE (15, 7, RA1, RA0, RA2, RA4, RA3, RA4, RA1, RA0, RA3, RA2,
+ RB1, RB0, RB2, RB4, RB3, RB4, RB1, RB0, RB3, RB2);
+ ROUND_INVERSE (14, 6, RA4, RA1, RA0, RA3, RA2, RA1, RA0, RA2, RA3, RA4,
+ RB4, RB1, RB0, RB3, RB2, RB1, RB0, RB2, RB3, RB4);
+ ROUND_INVERSE (13, 5, RA1, RA0, RA2, RA3, RA4, RA0, RA4, RA3, RA2, RA1,
+ RB1, RB0, RB2, RB3, RB4, RB0, RB4, RB3, RB2, RB1);
+ ROUND_INVERSE (12, 4, RA0, RA4, RA3, RA2, RA1, RA0, RA2, RA3, RA1, RA4,
+ RB0, RB4, RB3, RB2, RB1, RB0, RB2, RB3, RB1, RB4);
+ ROUND_INVERSE (11, 3, RA0, RA2, RA3, RA1, RA4, RA3, RA2, RA1, RA0, RA4,
+ RB0, RB2, RB3, RB1, RB4, RB3, RB2, RB1, RB0, RB4);
+ ROUND_INVERSE (10, 2, RA3, RA2, RA1, RA0, RA4, RA2, RA4, RA1, RA0, RA3,
+ RB3, RB2, RB1, RB0, RB4, RB2, RB4, RB1, RB0, RB3);
+ ROUND_INVERSE (9, 1, RA2, RA4, RA1, RA0, RA3, RA3, RA2, RA0, RA1, RA4,
+ RB2, RB4, RB1, RB0, RB3, RB3, RB2, RB0, RB1, RB4);
+ ROUND_INVERSE (8, 0, RA3, RA2, RA0, RA1, RA4, RA3, RA4, RA2, RA1, RA0,
+ RB3, RB2, RB0, RB1, RB4, RB3, RB4, RB2, RB1, RB0);
+ ROUND_INVERSE (7, 7, RA3, RA4, RA2, RA1, RA0, RA1, RA3, RA4, RA0, RA2,
+ RB3, RB4, RB2, RB1, RB0, RB1, RB3, RB4, RB0, RB2);
+ ROUND_INVERSE (6, 6, RA1, RA3, RA4, RA0, RA2, RA3, RA4, RA2, RA0, RA1,
+ RB1, RB3, RB4, RB0, RB2, RB3, RB4, RB2, RB0, RB1);
+ ROUND_INVERSE (5, 5, RA3, RA4, RA2, RA0, RA1, RA4, RA1, RA0, RA2, RA3,
+ RB3, RB4, RB2, RB0, RB1, RB4, RB1, RB0, RB2, RB3);
+ ROUND_INVERSE (4, 4, RA4, RA1, RA0, RA2, RA3, RA4, RA2, RA0, RA3, RA1,
+ RB4, RB1, RB0, RB2, RB3, RB4, RB2, RB0, RB3, RB1);
+ ROUND_INVERSE (3, 3, RA4, RA2, RA0, RA3, RA1, RA0, RA2, RA3, RA4, RA1,
+ RB4, RB2, RB0, RB3, RB1, RB0, RB2, RB3, RB4, RB1);
+ ROUND_INVERSE (2, 2, RA0, RA2, RA3, RA4, RA1, RA2, RA1, RA3, RA4, RA0,
+ RB0, RB2, RB3, RB4, RB1, RB2, RB1, RB3, RB4, RB0);
+ ROUND_INVERSE (1, 1, RA2, RA1, RA3, RA4, RA0, RA0, RA2, RA4, RA3, RA1,
+ RB2, RB1, RB3, RB4, RB0, RB0, RB2, RB4, RB3, RB1);
+ ROUND_INVERSE (0, 0, RA0, RA2, RA4, RA3, RA1, RA0, RA1, RA2, RA3, RA4,
+ RB0, RB2, RB4, RB3, RB1, RB0, RB1, RB2, RB3, RB4);
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __serpent_dec_blk8,.-__serpent_dec_blk8;)
+
+.align 8
+.globl _gcry_serpent_sse2_ctr_enc
+ELF(.type _gcry_serpent_sse2_ctr_enc,@function;)
+_gcry_serpent_sse2_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: iv (big endian, 128bit)
+ */
+ CFI_STARTPROC();
+
+ /* load IV and byteswap */
+ movdqu (%rcx), RA0;
+ movdqa RA0, RTMP0;
+ pbswap(RTMP0, RTMP1); /* be => le */
+
+ pcmpeqd RNOT, RNOT;
+ psrldq $8, RNOT; /* low: -1, high: 0 */
+ movdqa RNOT, RTMP2;
+ paddq RTMP2, RTMP2; /* low: -2, high: 0 */
+
+ /* construct IVs */
+ movdqa RTMP0, RTMP1;
+ psubq RNOT, RTMP0; /* +1 */
+ movdqa RTMP0, RA1;
+ psubq RTMP2, RTMP1; /* +2 */
+ movdqa RTMP1, RA2;
+ psubq RTMP2, RTMP0; /* +3 */
+ movdqa RTMP0, RA3;
+ psubq RTMP2, RTMP1; /* +4 */
+ movdqa RTMP1, RB0;
+ psubq RTMP2, RTMP0; /* +5 */
+ movdqa RTMP0, RB1;
+ psubq RTMP2, RTMP1; /* +6 */
+ movdqa RTMP1, RB2;
+ psubq RTMP2, RTMP0; /* +7 */
+ movdqa RTMP0, RB3;
+ psubq RTMP2, RTMP1; /* +8 */
+
+ /* check need for handling 64-bit overflow and carry */
+ cmpl $0xffffffff, 8(%rcx);
+ jne .Lno_ctr_carry;
+
+ movl 12(%rcx), %eax;
+ bswapl %eax;
+ cmpl $-8, %eax;
+ jb .Lno_ctr_carry;
+ pslldq $8, RNOT; /* low: 0, high: -1 */
+ je .Lcarry_RTMP0;
+
+ cmpl $-6, %eax;
+ jb .Lcarry_RB3;
+ je .Lcarry_RB2;
+
+ cmpl $-4, %eax;
+ jb .Lcarry_RB1;
+ je .Lcarry_RB0;
+
+ cmpl $-2, %eax;
+ jb .Lcarry_RA3;
+ je .Lcarry_RA2;
+
+ psubq RNOT, RA1;
+.Lcarry_RA2:
+ psubq RNOT, RA2;
+.Lcarry_RA3:
+ psubq RNOT, RA3;
+.Lcarry_RB0:
+ psubq RNOT, RB0;
+.Lcarry_RB1:
+ psubq RNOT, RB1;
+.Lcarry_RB2:
+ psubq RNOT, RB2;
+.Lcarry_RB3:
+ psubq RNOT, RB3;
+.Lcarry_RTMP0:
+ psubq RNOT, RTMP1;
+
+.Lno_ctr_carry:
+ /* le => be */
+ pbswap(RA1, RTMP0);
+ pbswap(RA2, RTMP0);
+ pbswap(RA3, RTMP0);
+ pbswap(RB0, RTMP0);
+ pbswap(RB1, RTMP0);
+ pbswap(RB2, RTMP0);
+ pbswap(RB3, RTMP0);
+ pbswap(RTMP1, RTMP0);
+ /* store new IV */
+ movdqu RTMP1, (%rcx);
+
+ call __serpent_enc_blk8;
+
+ pxor_u((0 * 16)(%rdx), RA4, RTMP0);
+ pxor_u((1 * 16)(%rdx), RA1, RTMP0);
+ pxor_u((2 * 16)(%rdx), RA2, RTMP0);
+ pxor_u((3 * 16)(%rdx), RA0, RTMP0);
+ pxor_u((4 * 16)(%rdx), RB4, RTMP0);
+ pxor_u((5 * 16)(%rdx), RB1, RTMP0);
+ pxor_u((6 * 16)(%rdx), RB2, RTMP0);
+ pxor_u((7 * 16)(%rdx), RB0, RTMP0);
+
+ movdqu RA4, (0 * 16)(%rsi);
+ movdqu RA1, (1 * 16)(%rsi);
+ movdqu RA2, (2 * 16)(%rsi);
+ movdqu RA0, (3 * 16)(%rsi);
+ movdqu RB4, (4 * 16)(%rsi);
+ movdqu RB1, (5 * 16)(%rsi);
+ movdqu RB2, (6 * 16)(%rsi);
+ movdqu RB0, (7 * 16)(%rsi);
+
+ /* clear the used registers */
+ pxor RA0, RA0;
+ pxor RA1, RA1;
+ pxor RA2, RA2;
+ pxor RA3, RA3;
+ pxor RA4, RA4;
+ pxor RB0, RB0;
+ pxor RB1, RB1;
+ pxor RB2, RB2;
+ pxor RB3, RB3;
+ pxor RB4, RB4;
+ pxor RTMP0, RTMP0;
+ pxor RTMP1, RTMP1;
+ pxor RTMP2, RTMP2;
+ pxor RNOT, RNOT;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_sse2_ctr_enc,.-_gcry_serpent_sse2_ctr_enc;)
+
+.align 8
+.globl _gcry_serpent_sse2_cbc_dec
+ELF(.type _gcry_serpent_sse2_cbc_dec,@function;)
+_gcry_serpent_sse2_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ movdqu (0 * 16)(%rdx), RA0;
+ movdqu (1 * 16)(%rdx), RA1;
+ movdqu (2 * 16)(%rdx), RA2;
+ movdqu (3 * 16)(%rdx), RA3;
+ movdqu (4 * 16)(%rdx), RB0;
+ movdqu (5 * 16)(%rdx), RB1;
+ movdqu (6 * 16)(%rdx), RB2;
+ movdqu (7 * 16)(%rdx), RB3;
+
+ call __serpent_dec_blk8;
+
+ movdqu (7 * 16)(%rdx), RNOT;
+ pxor_u((%rcx), RA0, RTMP0);
+ pxor_u((0 * 16)(%rdx), RA1, RTMP0);
+ pxor_u((1 * 16)(%rdx), RA2, RTMP0);
+ pxor_u((2 * 16)(%rdx), RA3, RTMP0);
+ pxor_u((3 * 16)(%rdx), RB0, RTMP0);
+ pxor_u((4 * 16)(%rdx), RB1, RTMP0);
+ pxor_u((5 * 16)(%rdx), RB2, RTMP0);
+ pxor_u((6 * 16)(%rdx), RB3, RTMP0);
+ movdqu RNOT, (%rcx); /* store new IV */
+
+ movdqu RA0, (0 * 16)(%rsi);
+ movdqu RA1, (1 * 16)(%rsi);
+ movdqu RA2, (2 * 16)(%rsi);
+ movdqu RA3, (3 * 16)(%rsi);
+ movdqu RB0, (4 * 16)(%rsi);
+ movdqu RB1, (5 * 16)(%rsi);
+ movdqu RB2, (6 * 16)(%rsi);
+ movdqu RB3, (7 * 16)(%rsi);
+
+ /* clear the used registers */
+ pxor RA0, RA0;
+ pxor RA1, RA1;
+ pxor RA2, RA2;
+ pxor RA3, RA3;
+ pxor RA4, RA4;
+ pxor RB0, RB0;
+ pxor RB1, RB1;
+ pxor RB2, RB2;
+ pxor RB3, RB3;
+ pxor RB4, RB4;
+ pxor RTMP0, RTMP0;
+ pxor RTMP1, RTMP1;
+ pxor RTMP2, RTMP2;
+ pxor RNOT, RNOT;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_sse2_cbc_dec,.-_gcry_serpent_sse2_cbc_dec;)
+
+.align 8
+.globl _gcry_serpent_sse2_cfb_dec
+ELF(.type _gcry_serpent_sse2_cfb_dec,@function;)
+_gcry_serpent_sse2_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ /* Load input */
+ movdqu (%rcx), RA0;
+ movdqu 0 * 16(%rdx), RA1;
+ movdqu 1 * 16(%rdx), RA2;
+ movdqu 2 * 16(%rdx), RA3;
+ movdqu 3 * 16(%rdx), RB0;
+ movdqu 4 * 16(%rdx), RB1;
+ movdqu 5 * 16(%rdx), RB2;
+ movdqu 6 * 16(%rdx), RB3;
+
+ /* Update IV */
+ movdqu 7 * 16(%rdx), RNOT;
+ movdqu RNOT, (%rcx);
+
+ call __serpent_enc_blk8;
+
+ pxor_u((0 * 16)(%rdx), RA4, RTMP0);
+ pxor_u((1 * 16)(%rdx), RA1, RTMP0);
+ pxor_u((2 * 16)(%rdx), RA2, RTMP0);
+ pxor_u((3 * 16)(%rdx), RA0, RTMP0);
+ pxor_u((4 * 16)(%rdx), RB4, RTMP0);
+ pxor_u((5 * 16)(%rdx), RB1, RTMP0);
+ pxor_u((6 * 16)(%rdx), RB2, RTMP0);
+ pxor_u((7 * 16)(%rdx), RB0, RTMP0);
+
+ movdqu RA4, (0 * 16)(%rsi);
+ movdqu RA1, (1 * 16)(%rsi);
+ movdqu RA2, (2 * 16)(%rsi);
+ movdqu RA0, (3 * 16)(%rsi);
+ movdqu RB4, (4 * 16)(%rsi);
+ movdqu RB1, (5 * 16)(%rsi);
+ movdqu RB2, (6 * 16)(%rsi);
+ movdqu RB0, (7 * 16)(%rsi);
+
+ /* clear the used registers */
+ pxor RA0, RA0;
+ pxor RA1, RA1;
+ pxor RA2, RA2;
+ pxor RA3, RA3;
+ pxor RA4, RA4;
+ pxor RB0, RB0;
+ pxor RB1, RB1;
+ pxor RB2, RB2;
+ pxor RB3, RB3;
+ pxor RB4, RB4;
+ pxor RTMP0, RTMP0;
+ pxor RTMP1, RTMP1;
+ pxor RTMP2, RTMP2;
+ pxor RNOT, RNOT;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_sse2_cfb_dec,.-_gcry_serpent_sse2_cfb_dec;)
+
+.align 8
+.globl _gcry_serpent_sse2_ocb_enc
+ELF(.type _gcry_serpent_sse2_ocb_enc,@function;)
+
+_gcry_serpent_sse2_ocb_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[8])
+ */
+ CFI_STARTPROC();
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ movdqu (%rcx), RTMP0;
+ movdqu (%r8), RTMP1;
+
+ /* 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) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ movdqu (n * 16)(%rdx), xreg; \
+ movdqu (lreg), RNOT; \
+ pxor RNOT, RTMP0; \
+ pxor xreg, RTMP1; \
+ pxor RTMP0, xreg; \
+ movdqu RTMP0, (n * 16)(%rsi);
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, RA0);
+ OCB_INPUT(1, %r11, RA1);
+ OCB_INPUT(2, %r12, RA2);
+ OCB_INPUT(3, %r13, RA3);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, RB0);
+ OCB_INPUT(5, %r11, RB1);
+ OCB_INPUT(6, %r12, RB2);
+ OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+ movdqu RTMP0, (%rcx);
+ movdqu RTMP1, (%r8);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __serpent_enc_blk8;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ pxor_u((0 * 16)(%rsi), RA4, RTMP0);
+ pxor_u((1 * 16)(%rsi), RA1, RTMP0);
+ pxor_u((2 * 16)(%rsi), RA2, RTMP0);
+ pxor_u((3 * 16)(%rsi), RA0, RTMP0);
+ pxor_u((4 * 16)(%rsi), RB4, RTMP0);
+ pxor_u((5 * 16)(%rsi), RB1, RTMP0);
+ pxor_u((6 * 16)(%rsi), RB2, RTMP0);
+ pxor_u((7 * 16)(%rsi), RB0, RTMP0);
+
+ movdqu RA4, (0 * 16)(%rsi);
+ movdqu RA1, (1 * 16)(%rsi);
+ movdqu RA2, (2 * 16)(%rsi);
+ movdqu RA0, (3 * 16)(%rsi);
+ movdqu RB4, (4 * 16)(%rsi);
+ movdqu RB1, (5 * 16)(%rsi);
+ movdqu RB2, (6 * 16)(%rsi);
+ movdqu RB0, (7 * 16)(%rsi);
+
+ /* clear the used registers */
+ pxor RA0, RA0;
+ pxor RA1, RA1;
+ pxor RA2, RA2;
+ pxor RA3, RA3;
+ pxor RA4, RA4;
+ pxor RB0, RB0;
+ pxor RB1, RB1;
+ pxor RB2, RB2;
+ pxor RB3, RB3;
+ pxor RB4, RB4;
+ pxor RTMP0, RTMP0;
+ pxor RTMP1, RTMP1;
+ pxor RTMP2, RTMP2;
+ pxor RNOT, RNOT;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_sse2_ocb_enc,.-_gcry_serpent_sse2_ocb_enc;)
+
+.align 8
+.globl _gcry_serpent_sse2_ocb_dec
+ELF(.type _gcry_serpent_sse2_ocb_dec,@function;)
+
+_gcry_serpent_sse2_ocb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[8])
+ */
+ CFI_STARTPROC();
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ movdqu (%rcx), RTMP0;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ movdqu (n * 16)(%rdx), xreg; \
+ movdqu (lreg), RNOT; \
+ pxor RNOT, RTMP0; \
+ pxor RTMP0, xreg; \
+ movdqu RTMP0, (n * 16)(%rsi);
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, RA0);
+ OCB_INPUT(1, %r11, RA1);
+ OCB_INPUT(2, %r12, RA2);
+ OCB_INPUT(3, %r13, RA3);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, RB0);
+ OCB_INPUT(5, %r11, RB1);
+ OCB_INPUT(6, %r12, RB2);
+ OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+ movdqu RTMP0, (%rcx);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __serpent_dec_blk8;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ movdqu (%r8), RTMP0;
+
+ pxor_u((0 * 16)(%rsi), RA0, RTMP1);
+ pxor_u((1 * 16)(%rsi), RA1, RTMP1);
+ pxor_u((2 * 16)(%rsi), RA2, RTMP1);
+ pxor_u((3 * 16)(%rsi), RA3, RTMP1);
+ pxor_u((4 * 16)(%rsi), RB0, RTMP1);
+ pxor_u((5 * 16)(%rsi), RB1, RTMP1);
+ pxor_u((6 * 16)(%rsi), RB2, RTMP1);
+ pxor_u((7 * 16)(%rsi), RB3, RTMP1);
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+
+ movdqu RA0, (0 * 16)(%rsi);
+ pxor RA0, RTMP0;
+ movdqu RA1, (1 * 16)(%rsi);
+ pxor RA1, RTMP0;
+ movdqu RA2, (2 * 16)(%rsi);
+ pxor RA2, RTMP0;
+ movdqu RA3, (3 * 16)(%rsi);
+ pxor RA3, RTMP0;
+ movdqu RB0, (4 * 16)(%rsi);
+ pxor RB0, RTMP0;
+ movdqu RB1, (5 * 16)(%rsi);
+ pxor RB1, RTMP0;
+ movdqu RB2, (6 * 16)(%rsi);
+ pxor RB2, RTMP0;
+ movdqu RB3, (7 * 16)(%rsi);
+ pxor RB3, RTMP0;
+
+ movdqu RTMP0, (%r8);
+
+ /* clear the used registers */
+ pxor RA0, RA0;
+ pxor RA1, RA1;
+ pxor RA2, RA2;
+ pxor RA3, RA3;
+ pxor RA4, RA4;
+ pxor RB0, RB0;
+ pxor RB1, RB1;
+ pxor RB2, RB2;
+ pxor RB3, RB3;
+ pxor RB4, RB4;
+ pxor RTMP0, RTMP0;
+ pxor RTMP1, RTMP1;
+ pxor RTMP2, RTMP2;
+ pxor RNOT, RNOT;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_sse2_ocb_dec,.-_gcry_serpent_sse2_ocb_dec;)
+
+.align 8
+.globl _gcry_serpent_sse2_ocb_auth
+ELF(.type _gcry_serpent_sse2_ocb_auth,@function;)
+
+_gcry_serpent_sse2_ocb_auth:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: abuf (8 blocks)
+ * %rdx: offset
+ * %rcx: checksum
+ * %r8 : L pointers (void *L[8])
+ */
+ CFI_STARTPROC();
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ movdqu (%rdx), RTMP0;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ movdqu (n * 16)(%rsi), xreg; \
+ movdqu (lreg), RNOT; \
+ pxor RNOT, RTMP0; \
+ pxor RTMP0, xreg;
+ movq (0 * 8)(%r8), %r10;
+ movq (1 * 8)(%r8), %r11;
+ movq (2 * 8)(%r8), %r12;
+ movq (3 * 8)(%r8), %r13;
+ OCB_INPUT(0, %r10, RA0);
+ OCB_INPUT(1, %r11, RA1);
+ OCB_INPUT(2, %r12, RA2);
+ OCB_INPUT(3, %r13, RA3);
+ movq (4 * 8)(%r8), %r10;
+ movq (5 * 8)(%r8), %r11;
+ movq (6 * 8)(%r8), %r12;
+ movq (7 * 8)(%r8), %r13;
+ OCB_INPUT(4, %r10, RB0);
+ OCB_INPUT(5, %r11, RB1);
+ OCB_INPUT(6, %r12, RB2);
+ OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+ movdqu RTMP0, (%rdx);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __serpent_enc_blk8;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ movdqu (%rcx), RTMP0;
+ pxor RB4, RA4;
+ pxor RB1, RA1;
+ pxor RB2, RA2;
+ pxor RB0, RA0;
+
+ pxor RTMP0, RA2;
+ pxor RA4, RA1;
+ pxor RA2, RA0;
+
+ pxor RA1, RA0;
+ movdqu RA0, (%rcx);
+
+ /* clear the used registers */
+ pxor RA0, RA0;
+ pxor RA1, RA1;
+ pxor RA2, RA2;
+ pxor RA3, RA3;
+ pxor RA4, RA4;
+ pxor RB0, RB0;
+ pxor RB1, RB1;
+ pxor RB2, RB2;
+ pxor RB3, RB3;
+ pxor RB4, RB4;
+ pxor RTMP0, RTMP0;
+ pxor RTMP1, RTMP1;
+ pxor RTMP2, RTMP2;
+ pxor RNOT, RNOT;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_serpent_sse2_ocb_auth,.-_gcry_serpent_sse2_ocb_auth;)
+
+#endif /*defined(USE_SERPENT)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/serpent.c b/comm/third_party/libgcrypt/cipher/serpent.c
new file mode 100644
index 0000000000..3c5eed2c03
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/serpent.c
@@ -0,0 +1,1807 @@
+/* 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 <config.h>
+
+#include <string.h>
+#include <stdio.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher-internal.h"
+#include "cipher-selftest.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 void
+serpent_setkey_internal (serpent_context_t *context,
+ const byte *key, unsigned int key_length)
+{
+ serpent_key_t key_prepared;
+
+ 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));
+}
+
+/* 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
+ 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];
+ unsigned int n = 16 - (blkn % 16);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 16)
+ {
+ for (i = 0; i < 16; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(15 + n) % 16];
+
+ /* 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];
+ unsigned int n = 8 - (blkn % 8);
+ u64 *l;
+
+ if (nblocks >= 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(0 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(1 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(2 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(3 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(4 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(5 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(6 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ l = &Ls[(7 + n) % 8];
+
+ /* 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;
+ const void *Ls[8];
+ unsigned int n = 8 - (blkn % 8);
+ const void **l;
+
+ if (nblocks >= 8)
+ {
+ Ls[(0 + n) % 8] = c->u_mode.ocb.L[0];
+ Ls[(1 + n) % 8] = c->u_mode.ocb.L[1];
+ Ls[(2 + n) % 8] = c->u_mode.ocb.L[0];
+ Ls[(3 + n) % 8] = c->u_mode.ocb.L[2];
+ Ls[(4 + n) % 8] = c->u_mode.ocb.L[0];
+ Ls[(5 + n) % 8] = c->u_mode.ocb.L[1];
+ Ls[(6 + n) % 8] = c->u_mode.ocb.L[0];
+ l = &Ls[(7 + n) % 8];
+
+ /* Process data in 8 block chunks. */
+ while (nblocks >= 8)
+ {
+ blkn += 8;
+ *l = 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, Ls);
+ else
+ _gcry_serpent_neon_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_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];
+ unsigned int n = 16 - (blkn % 16);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 16)
+ {
+ for (i = 0; i < 16; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(15 + n) % 16];
+
+ /* 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];
+ unsigned int n = 8 - (blkn % 8);
+ u64 *l;
+
+ if (nblocks >= 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(0 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(1 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(2 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(3 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(4 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(5 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(6 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ l = &Ls[(7 + n) % 8];
+
+ /* 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;
+ const void *Ls[8];
+ unsigned int n = 8 - (blkn % 8);
+ const void **l;
+
+ if (nblocks >= 8)
+ {
+ Ls[(0 + n) % 8] = c->u_mode.ocb.L[0];
+ Ls[(1 + n) % 8] = c->u_mode.ocb.L[1];
+ Ls[(2 + n) % 8] = c->u_mode.ocb.L[0];
+ Ls[(3 + n) % 8] = c->u_mode.ocb.L[2];
+ Ls[(4 + n) % 8] = c->u_mode.ocb.L[0];
+ Ls[(5 + n) % 8] = c->u_mode.ocb.L[1];
+ Ls[(6 + n) % 8] = c->u_mode.ocb.L[0];
+ l = &Ls[(7 + n) % 8];
+
+ /* Process data in 8 block chunks. */
+ while (nblocks >= 8)
+ {
+ blkn += 8;
+ *l = 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, 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 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 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 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/comm/third_party/libgcrypt/cipher/sha1-armv7-neon.S b/comm/third_party/libgcrypt/cipher/sha1-armv7-neon.S
new file mode 100644
index 0000000000..61cc541c68
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1-armv7-neon.S
@@ -0,0 +1,526 @@
+/* sha1-armv7-neon.S - ARM/NEON accelerated SHA-1 transform function
+ * Copyright (C) 2013-2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on sha1.c:
+ * Copyright (C) 1998, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_NEON) && defined(USE_SHA1)
+
+.syntax unified
+.fpu neon
+.arm
+
+.text
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xCA62C1D6
+.align 4
+gcry_sha1_armv7_neon_K_VEC:
+.LK_VEC:
+.LK1: .long K1, K1, K1, K1
+.LK2: .long K2, K2, K2, K2
+.LK3: .long K3, K3, K3, K3
+.LK4: .long K4, K4, K4, K4
+
+
+/* Register macros */
+
+#define RSTATE r0
+#define RDATA r1
+#define RNBLKS r2
+#define ROLDSTACK r3
+#define RWK lr
+
+#define _a r4
+#define _b r5
+#define _c r6
+#define _d r7
+#define _e r8
+
+#define RT0 r9
+#define RT1 r10
+#define RT2 r11
+#define RT3 r12
+
+#define W0 q0
+#define W1 q1
+#define W2 q2
+#define W3 q3
+#define W4 q4
+#define W5 q5
+#define W6 q6
+#define W7 q7
+
+#define tmp0 q8
+#define tmp1 q9
+#define tmp2 q10
+#define tmp3 q11
+
+#define qK1 q12
+#define qK2 q13
+#define qK3 q14
+#define qK4 q15
+
+
+/* Round function macros. */
+
+#define WK_offs(i) (((i) & 15) * 4)
+
+#define _R_F1(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ldr RT3, [sp, WK_offs(i)]; \
+ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ bic RT0, d, b; \
+ add e, e, a, ror #(32 - 5); \
+ and RT1, c, b; \
+ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add RT0, RT0, RT3; \
+ add e, e, RT1; \
+ ror b, #(32 - 30); \
+ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add e, e, RT0;
+
+#define _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ldr RT3, [sp, WK_offs(i)]; \
+ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ eor RT0, d, b; \
+ add e, e, a, ror #(32 - 5); \
+ eor RT0, RT0, c; \
+ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add e, e, RT3; \
+ ror b, #(32 - 30); \
+ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add e, e, RT0; \
+
+#define _R_F3(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ ldr RT3, [sp, WK_offs(i)]; \
+ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ eor RT0, b, c; \
+ and RT1, b, c; \
+ add e, e, a, ror #(32 - 5); \
+ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ and RT0, RT0, d; \
+ add RT1, RT1, RT3; \
+ add e, e, RT0; \
+ ror b, #(32 - 30); \
+ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \
+ add e, e, RT1;
+
+#define _R_F4(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define _R(a,b,c,d,e,f,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \
+ _R_##f(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define R(a,b,c,d,e,f,i) \
+ _R_##f(a,b,c,d,e,i,dummy,dummy,dummy,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28)
+
+#define dummy(...)
+
+
+/* Input expansion macros. */
+
+/********* Precalc macros for rounds 0-15 *************************************/
+
+#define W_PRECALC_00_15() \
+ add RWK, sp, #(WK_offs(0)); \
+ \
+ vld1.32 {tmp0, tmp1}, [RDATA]!; \
+ vrev32.8 W0, tmp0; /* big => little */ \
+ vld1.32 {tmp2, tmp3}, [RDATA]!; \
+ vadd.u32 tmp0, W0, curK; \
+ vrev32.8 W7, tmp1; /* big => little */ \
+ vrev32.8 W6, tmp2; /* big => little */ \
+ vadd.u32 tmp1, W7, curK; \
+ vrev32.8 W5, tmp3; /* big => little */ \
+ vadd.u32 tmp2, W6, curK; \
+ vst1.32 {tmp0, tmp1}, [RWK]!; \
+ vadd.u32 tmp3, W5, curK; \
+ vst1.32 {tmp2, tmp3}, [RWK]; \
+
+#define WPRECALC_00_15_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vld1.32 {tmp0, tmp1}, [RDATA]!; \
+
+#define WPRECALC_00_15_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ add RWK, sp, #(WK_offs(0)); \
+
+#define WPRECALC_00_15_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vrev32.8 W0, tmp0; /* big => little */ \
+
+#define WPRECALC_00_15_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vld1.32 {tmp2, tmp3}, [RDATA]!; \
+
+#define WPRECALC_00_15_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vadd.u32 tmp0, W0, curK; \
+
+#define WPRECALC_00_15_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vrev32.8 W7, tmp1; /* big => little */ \
+
+#define WPRECALC_00_15_6(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vrev32.8 W6, tmp2; /* big => little */ \
+
+#define WPRECALC_00_15_7(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vadd.u32 tmp1, W7, curK; \
+
+#define WPRECALC_00_15_8(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vrev32.8 W5, tmp3; /* big => little */ \
+
+#define WPRECALC_00_15_9(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vadd.u32 tmp2, W6, curK; \
+
+#define WPRECALC_00_15_10(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vst1.32 {tmp0, tmp1}, [RWK]!; \
+
+#define WPRECALC_00_15_11(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vadd.u32 tmp3, W5, curK; \
+
+#define WPRECALC_00_15_12(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vst1.32 {tmp2, tmp3}, [RWK]; \
+
+
+/********* Precalc macros for rounds 16-31 ************************************/
+
+#define WPRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ veor tmp0, tmp0; \
+ vext.8 W, W_m16, W_m12, #8; \
+
+#define WPRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ add RWK, sp, #(WK_offs(i)); \
+ vext.8 tmp0, W_m04, tmp0, #4; \
+
+#define WPRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ veor tmp0, tmp0, W_m16; \
+ veor.32 W, W, W_m08; \
+
+#define WPRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ veor tmp1, tmp1; \
+ veor W, W, tmp0; \
+
+#define WPRECALC_16_31_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vshl.u32 tmp0, W, #1; \
+
+#define WPRECALC_16_31_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vext.8 tmp1, tmp1, W, #(16-12); \
+ vshr.u32 W, W, #31; \
+
+#define WPRECALC_16_31_6(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vorr tmp0, tmp0, W; \
+ vshr.u32 W, tmp1, #30; \
+
+#define WPRECALC_16_31_7(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vshl.u32 tmp1, tmp1, #2; \
+
+#define WPRECALC_16_31_8(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ veor tmp0, tmp0, W; \
+
+#define WPRECALC_16_31_9(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ veor W, tmp0, tmp1; \
+
+#define WPRECALC_16_31_10(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vadd.u32 tmp0, W, curK; \
+
+#define WPRECALC_16_31_11(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vst1.32 {tmp0}, [RWK];
+
+
+/********* Precalc macros for rounds 32-79 ************************************/
+
+#define WPRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ veor W, W_m28; \
+
+#define WPRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vext.8 tmp0, W_m08, W_m04, #8; \
+
+#define WPRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ veor W, W_m16; \
+
+#define WPRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ veor W, tmp0; \
+
+#define WPRECALC_32_79_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ add RWK, sp, #(WK_offs(i&~3)); \
+
+#define WPRECALC_32_79_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vshl.u32 tmp1, W, #2; \
+
+#define WPRECALC_32_79_6(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vshr.u32 tmp0, W, #30; \
+
+#define WPRECALC_32_79_7(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vorr W, tmp0, tmp1; \
+
+#define WPRECALC_32_79_8(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vadd.u32 tmp0, W, curK; \
+
+#define WPRECALC_32_79_9(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \
+ vst1.32 {tmp0}, [RWK];
+
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) veor reg, reg;
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_armv7_neon (void *ctx, const unsigned char *data,
+ * size_t nblks)
+ */
+.align 3
+.globl _gcry_sha1_transform_armv7_neon
+.type _gcry_sha1_transform_armv7_neon,%function;
+_gcry_sha1_transform_armv7_neon:
+ /* input:
+ * r0: ctx, CTX
+ * r1: data (64*nblks bytes)
+ * r2: nblks
+ */
+
+ cmp RNBLKS, #0;
+ beq .Ldo_nothing;
+
+ push {r4-r12, lr};
+
+ GET_DATA_POINTER(RT3, .LK_VEC, _a);
+ vpush {q4-q7};
+
+ mov ROLDSTACK, sp;
+
+ /* Align stack. */
+ sub sp, #(16*4);
+ and sp, #(~(16-1));
+
+ vld1.32 {qK1-qK2}, [RT3]!; /* Load K1,K2 */
+
+ /* Get the values of the chaining variables. */
+ ldm RSTATE, {_a-_e};
+
+ vld1.32 {qK3-qK4}, [RT3]; /* Load K3,K4 */
+
+#undef curK
+#define curK qK1
+ /* Precalc 0-15. */
+ W_PRECALC_00_15();
+
+ b .Loop;
+
+.ltorg
+.Loop:
+ /* Transform 0-15 + Precalc 16-31. */
+ _R( _a, _b, _c, _d, _e, F1, 0, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 16, W4, W5, W6, W7, W0, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F1, 1, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 16, W4, W5, W6, W7, W0, _, _, _ );
+ _R( _d, _e, _a, _b, _c, F1, 2, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 16, W4, W5, W6, W7, W0, _, _, _ );
+ _R( _c, _d, _e, _a, _b, F1, 3, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,16, W4, W5, W6, W7, W0, _, _, _ );
+
+#undef curK
+#define curK qK2
+ _R( _b, _c, _d, _e, _a, F1, 4, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 20, W3, W4, W5, W6, W7, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F1, 5, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 20, W3, W4, W5, W6, W7, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F1, 6, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 20, W3, W4, W5, W6, W7, _, _, _ );
+ _R( _d, _e, _a, _b, _c, F1, 7, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,20, W3, W4, W5, W6, W7, _, _, _ );
+
+ _R( _c, _d, _e, _a, _b, F1, 8, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 24, W2, W3, W4, W5, W6, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F1, 9, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 24, W2, W3, W4, W5, W6, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F1, 10, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 24, W2, W3, W4, W5, W6, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F1, 11, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,24, W2, W3, W4, W5, W6, _, _, _ );
+
+ _R( _d, _e, _a, _b, _c, F1, 12, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 28, W1, W2, W3, W4, W5, _, _, _ );
+ _R( _c, _d, _e, _a, _b, F1, 13, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 28, W1, W2, W3, W4, W5, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F1, 14, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 28, W1, W2, W3, W4, W5, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F1, 15, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,28, W1, W2, W3, W4, W5, _, _, _ );
+
+ /* Transform 16-63 + Precalc 32-79. */
+ _R( _e, _a, _b, _c, _d, F1, 16, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 32, W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _d, _e, _a, _b, _c, F1, 17, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 32, W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _c, _d, _e, _a, _b, F1, 18, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 32, W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _b, _c, _d, _e, _a, F1, 19, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 32, W0, W1, W2, W3, W4, W5, W6, W7);
+
+ _R( _a, _b, _c, _d, _e, F2, 20, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 36, W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _e, _a, _b, _c, _d, F2, 21, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 36, W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _d, _e, _a, _b, _c, F2, 22, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 36, W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _c, _d, _e, _a, _b, F2, 23, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 36, W7, W0, W1, W2, W3, W4, W5, W6);
+
+#undef curK
+#define curK qK3
+ _R( _b, _c, _d, _e, _a, F2, 24, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 40, W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _a, _b, _c, _d, _e, F2, 25, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 40, W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _e, _a, _b, _c, _d, F2, 26, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 40, W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _d, _e, _a, _b, _c, F2, 27, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 40, W6, W7, W0, W1, W2, W3, W4, W5);
+
+ _R( _c, _d, _e, _a, _b, F2, 28, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 44, W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _b, _c, _d, _e, _a, F2, 29, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 44, W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _a, _b, _c, _d, _e, F2, 30, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 44, W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _e, _a, _b, _c, _d, F2, 31, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 44, W5, W6, W7, W0, W1, W2, W3, W4);
+
+ _R( _d, _e, _a, _b, _c, F2, 32, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 48, W4, W5, W6, W7, W0, W1, W2, W3);
+ _R( _c, _d, _e, _a, _b, F2, 33, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 48, W4, W5, W6, W7, W0, W1, W2, W3);
+ _R( _b, _c, _d, _e, _a, F2, 34, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 48, W4, W5, W6, W7, W0, W1, W2, W3);
+ _R( _a, _b, _c, _d, _e, F2, 35, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 48, W4, W5, W6, W7, W0, W1, W2, W3);
+
+ _R( _e, _a, _b, _c, _d, F2, 36, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 52, W3, W4, W5, W6, W7, W0, W1, W2);
+ _R( _d, _e, _a, _b, _c, F2, 37, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 52, W3, W4, W5, W6, W7, W0, W1, W2);
+ _R( _c, _d, _e, _a, _b, F2, 38, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 52, W3, W4, W5, W6, W7, W0, W1, W2);
+ _R( _b, _c, _d, _e, _a, F2, 39, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 52, W3, W4, W5, W6, W7, W0, W1, W2);
+
+ _R( _a, _b, _c, _d, _e, F3, 40, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 56, W2, W3, W4, W5, W6, W7, W0, W1);
+ _R( _e, _a, _b, _c, _d, F3, 41, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 56, W2, W3, W4, W5, W6, W7, W0, W1);
+ _R( _d, _e, _a, _b, _c, F3, 42, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 56, W2, W3, W4, W5, W6, W7, W0, W1);
+ _R( _c, _d, _e, _a, _b, F3, 43, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 56, W2, W3, W4, W5, W6, W7, W0, W1);
+
+#undef curK
+#define curK qK4
+ _R( _b, _c, _d, _e, _a, F3, 44, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 60, W1, W2, W3, W4, W5, W6, W7, W0);
+ _R( _a, _b, _c, _d, _e, F3, 45, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 60, W1, W2, W3, W4, W5, W6, W7, W0);
+ _R( _e, _a, _b, _c, _d, F3, 46, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 60, W1, W2, W3, W4, W5, W6, W7, W0);
+ _R( _d, _e, _a, _b, _c, F3, 47, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 60, W1, W2, W3, W4, W5, W6, W7, W0);
+
+ _R( _c, _d, _e, _a, _b, F3, 48, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 64, W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _b, _c, _d, _e, _a, F3, 49, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 64, W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _a, _b, _c, _d, _e, F3, 50, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 64, W0, W1, W2, W3, W4, W5, W6, W7);
+ _R( _e, _a, _b, _c, _d, F3, 51, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 64, W0, W1, W2, W3, W4, W5, W6, W7);
+
+ _R( _d, _e, _a, _b, _c, F3, 52, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 68, W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _c, _d, _e, _a, _b, F3, 53, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 68, W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _b, _c, _d, _e, _a, F3, 54, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 68, W7, W0, W1, W2, W3, W4, W5, W6);
+ _R( _a, _b, _c, _d, _e, F3, 55, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 68, W7, W0, W1, W2, W3, W4, W5, W6);
+
+ _R( _e, _a, _b, _c, _d, F3, 56, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 72, W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _d, _e, _a, _b, _c, F3, 57, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 72, W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _c, _d, _e, _a, _b, F3, 58, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 72, W6, W7, W0, W1, W2, W3, W4, W5);
+ _R( _b, _c, _d, _e, _a, F3, 59, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 72, W6, W7, W0, W1, W2, W3, W4, W5);
+
+ subs RNBLKS, #1;
+
+ _R( _a, _b, _c, _d, _e, F4, 60, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 76, W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _e, _a, _b, _c, _d, F4, 61, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 76, W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _d, _e, _a, _b, _c, F4, 62, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 76, W5, W6, W7, W0, W1, W2, W3, W4);
+ _R( _c, _d, _e, _a, _b, F4, 63, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 76, W5, W6, W7, W0, W1, W2, W3, W4);
+
+ beq .Lend;
+
+ /* Transform 64-79 + Precalc 0-15 of next block. */
+#undef curK
+#define curK qK1
+ _R( _b, _c, _d, _e, _a, F4, 64, WPRECALC_00_15_0, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F4, 65, WPRECALC_00_15_1, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F4, 66, WPRECALC_00_15_2, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _d, _e, _a, _b, _c, F4, 67, WPRECALC_00_15_3, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+ _R( _c, _d, _e, _a, _b, F4, 68, dummy, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F4, 69, dummy, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F4, 70, WPRECALC_00_15_4, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _e, _a, _b, _c, _d, F4, 71, WPRECALC_00_15_5, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+ _R( _d, _e, _a, _b, _c, F4, 72, dummy, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _c, _d, _e, _a, _b, F4, 73, dummy, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F4, 74, WPRECALC_00_15_6, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _a, _b, _c, _d, _e, F4, 75, WPRECALC_00_15_7, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+
+ _R( _e, _a, _b, _c, _d, F4, 76, WPRECALC_00_15_8, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _d, _e, _a, _b, _c, F4, 77, WPRECALC_00_15_9, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _c, _d, _e, _a, _b, F4, 78, WPRECALC_00_15_10, dummy, dummy, _, _, _, _, _, _, _, _, _ );
+ _R( _b, _c, _d, _e, _a, F4, 79, WPRECALC_00_15_11, dummy, WPRECALC_00_15_12, _, _, _, _, _, _, _, _, _ );
+
+ /* Update the chaining variables. */
+ ldm RSTATE, {RT0-RT3};
+ add _a, RT0;
+ ldr RT0, [RSTATE, #state_h4];
+ add _b, RT1;
+ add _c, RT2;
+ add _d, RT3;
+ add _e, RT0;
+ stm RSTATE, {_a-_e};
+
+ b .Loop;
+
+.ltorg
+.Lend:
+ /* Transform 64-79 + Clear XMM registers. */
+ R( _b, _c, _d, _e, _a, F4, 64 );
+ R( _a, _b, _c, _d, _e, F4, 65 ); CLEAR_REG(tmp0);
+ R( _e, _a, _b, _c, _d, F4, 66 ); CLEAR_REG(tmp1);
+ R( _d, _e, _a, _b, _c, F4, 67 ); CLEAR_REG(W0);
+ R( _c, _d, _e, _a, _b, F4, 68 ); CLEAR_REG(W1);
+ R( _b, _c, _d, _e, _a, F4, 69 ); CLEAR_REG(W2);
+ R( _a, _b, _c, _d, _e, F4, 70 ); CLEAR_REG(W3);
+ R( _e, _a, _b, _c, _d, F4, 71 ); CLEAR_REG(W4);
+ R( _d, _e, _a, _b, _c, F4, 72 ); CLEAR_REG(W5);
+ R( _c, _d, _e, _a, _b, F4, 73 ); CLEAR_REG(W6);
+ R( _b, _c, _d, _e, _a, F4, 74 ); CLEAR_REG(W7);
+ R( _a, _b, _c, _d, _e, F4, 75 );
+ R( _e, _a, _b, _c, _d, F4, 76 );
+ R( _d, _e, _a, _b, _c, F4, 77 );
+ R( _c, _d, _e, _a, _b, F4, 78 );
+ R( _b, _c, _d, _e, _a, F4, 79 );
+
+ mov sp, ROLDSTACK;
+
+ /* Update the chaining variables. */
+ ldm RSTATE, {RT0-RT3};
+ add _a, RT0;
+ ldr RT0, [RSTATE, #state_h4];
+ add _b, RT1;
+ add _c, RT2;
+ add _d, RT3;
+ vpop {q4-q7};
+ add _e, RT0;
+ stm RSTATE, {_a-_e};
+
+ /* burn_stack */
+ mov r0, #(16*4 + 16*4 + 15);
+
+ pop {r4-r12, pc};
+
+.Ldo_nothing:
+ mov r0, #0;
+ bx lr
+.size _gcry_sha1_transform_armv7_neon,.-_gcry_sha1_transform_armv7_neon;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha1-armv8-aarch32-ce.S b/comm/third_party/libgcrypt/cipher/sha1-armv8-aarch32-ce.S
new file mode 100644
index 0000000000..bf2b233b01
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1-armv8-aarch32-ce.S
@@ -0,0 +1,220 @@
+/* sha1-armv8-aarch32-ce.S - ARM/CE accelerated SHA-1 transform function
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO) && defined(USE_SHA1)
+
+.syntax unified
+.arch armv8-a
+.fpu crypto-neon-fp-armv8
+.arm
+
+.text
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+
+/* Constants */
+
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xCA62C1D6
+.align 4
+gcry_sha1_aarch32_ce_K_VEC:
+.LK_VEC:
+.LK1: .long K1, K1, K1, K1
+.LK2: .long K2, K2, K2, K2
+.LK3: .long K3, K3, K3, K3
+.LK4: .long K4, K4, K4, K4
+
+
+/* Register macros */
+
+#define qH4 q0
+#define sH4 s0
+#define qH0123 q1
+
+#define qABCD q2
+#define qE0 q3
+#define qE1 q4
+
+#define qT0 q5
+#define qT1 q6
+
+#define qW0 q8
+#define qW1 q9
+#define qW2 q10
+#define qW3 q11
+
+#define qK1 q12
+#define qK2 q13
+#define qK3 q14
+#define qK4 q15
+
+
+/* Round macros */
+
+#define _(...) /*_*/
+#define do_add(dst, src0, src1) vadd.u32 dst, src0, src1;
+#define do_sha1su0(w0,w1,w2) sha1su0.32 w0,w1,w2;
+#define do_sha1su1(w0,w3) sha1su1.32 w0,w3;
+
+#define do_rounds(f, e0, e1, t, k, w0, w1, w2, w3, add_fn, sha1su0_fn, sha1su1_fn) \
+ sha1su1_fn( w3, w2 ); \
+ sha1h.32 e0, qABCD; \
+ sha1##f.32 qABCD, e1, t; \
+ add_fn( t, w2, k ); \
+ sha1su0_fn( w0, w1, w2 );
+
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) veor reg, reg;
+
+
+/*
+ * unsigned int
+ * _gcry_sha1_transform_armv8_ce (void *ctx, const unsigned char *data,
+ * size_t nblks)
+ */
+.align 3
+.globl _gcry_sha1_transform_armv8_ce
+.type _gcry_sha1_transform_armv8_ce,%function;
+_gcry_sha1_transform_armv8_ce:
+ /* input:
+ * r0: ctx, CTX
+ * r1: data (64*nblks bytes)
+ * r2: nblks
+ */
+
+ cmp r2, #0;
+ push {r4,lr};
+ beq .Ldo_nothing;
+
+ vpush {q4-q7};
+
+ GET_DATA_POINTER(r4, .LK_VEC, lr);
+
+ veor qH4, qH4
+ vld1.32 {qH0123}, [r0] /* load h0,h1,h2,h3 */
+
+ vld1.32 {qK1-qK2}, [r4]! /* load K1,K2 */
+ vldr sH4, [r0, #16] /* load h4 */
+ vld1.32 {qK3-qK4}, [r4] /* load K3,K4 */
+
+ vld1.8 {qW0-qW1}, [r1]!
+ vmov qABCD, qH0123
+ vld1.8 {qW2-qW3}, [r1]!
+
+ vrev32.8 qW0, qW0
+ vrev32.8 qW1, qW1
+ vrev32.8 qW2, qW2
+ do_add(qT0, qW0, qK1)
+ vrev32.8 qW3, qW3
+ do_add(qT1, qW1, qK1)
+
+.Loop:
+ do_rounds(c, qE1, qH4, qT0, qK1, qW0, qW1, qW2, qW3, do_add, do_sha1su0, _)
+ subs r2, r2, #1
+ do_rounds(c, qE0, qE1, qT1, qK1, qW1, qW2, qW3, qW0, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(c, qE1, qE0, qT0, qK1, qW2, qW3, qW0, qW1, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(c, qE0, qE1, qT1, qK2, qW3, qW0, qW1, qW2, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(c, qE1, qE0, qT0, qK2, qW0, qW1, qW2, qW3, do_add, do_sha1su0, do_sha1su1)
+
+ do_rounds(p, qE0, qE1, qT1, qK2, qW1, qW2, qW3, qW0, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(p, qE1, qE0, qT0, qK2, qW2, qW3, qW0, qW1, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(p, qE0, qE1, qT1, qK2, qW3, qW0, qW1, qW2, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(p, qE1, qE0, qT0, qK3, qW0, qW1, qW2, qW3, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(p, qE0, qE1, qT1, qK3, qW1, qW2, qW3, qW0, do_add, do_sha1su0, do_sha1su1)
+
+ do_rounds(m, qE1, qE0, qT0, qK3, qW2, qW3, qW0, qW1, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(m, qE0, qE1, qT1, qK3, qW3, qW0, qW1, qW2, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(m, qE1, qE0, qT0, qK3, qW0, qW1, qW2, qW3, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(m, qE0, qE1, qT1, qK4, qW1, qW2, qW3, qW0, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(m, qE1, qE0, qT0, qK4, qW2, qW3, qW0, qW1, do_add, do_sha1su0, do_sha1su1)
+
+ do_rounds(p, qE0, qE1, qT1, qK4, qW3, qW0, qW1, qW2, do_add, do_sha1su0, do_sha1su1)
+ beq .Lend
+
+ vld1.8 {qW0-qW1}, [r1]! /* preload */
+ do_rounds(p, qE1, qE0, qT0, qK4, _ , _ , qW2, qW3, do_add, _, do_sha1su1)
+ vrev32.8 qW0, qW0
+ vld1.8 {qW2}, [r1]!
+ vrev32.8 qW1, qW1
+ do_rounds(p, qE0, qE1, qT1, qK4, _ , _ , qW3, _ , do_add, _, _)
+ vld1.8 {qW3}, [r1]!
+ vrev32.8 qW2, qW2
+ do_rounds(p, qE1, qE0, qT0, _, _, _, _, _, _, _, _)
+ vrev32.8 qW3, qW3
+ do_rounds(p, qE0, qE1, qT1, _, _, _, _, _, _, _, _)
+
+ do_add(qT0, qW0, qK1)
+ vadd.u32 qH4, qE0
+ vadd.u32 qABCD, qH0123
+ do_add(qT1, qW1, qK1)
+
+ vmov qH0123, qABCD
+
+ b .Loop
+
+.Lend:
+ do_rounds(p, qE1, qE0, qT0, qK4, _ , _ , qW2, qW3, do_add, _, do_sha1su1)
+ do_rounds(p, qE0, qE1, qT1, qK4, _ , _ , qW3, _ , do_add, _, _)
+ do_rounds(p, qE1, qE0, qT0, _, _, _, _, _, _, _, _)
+ do_rounds(p, qE0, qE1, qT1, _, _, _, _, _, _, _, _)
+
+ vadd.u32 qH4, qE0
+ vadd.u32 qH0123, qABCD
+
+ CLEAR_REG(qW0)
+ CLEAR_REG(qW1)
+ CLEAR_REG(qW2)
+ CLEAR_REG(qW3)
+ CLEAR_REG(qABCD)
+ CLEAR_REG(qE1)
+ CLEAR_REG(qE0)
+
+ vstr sH4, [r0, #16] /* store h4 */
+ vst1.32 {qH0123}, [r0] /* store h0,h1,h2,h3 */
+
+ CLEAR_REG(qH0123)
+ CLEAR_REG(qH4)
+ vpop {q4-q7}
+
+.Ldo_nothing:
+ mov r0, #0
+ pop {r4,pc}
+.size _gcry_sha1_transform_armv8_ce,.-_gcry_sha1_transform_armv8_ce;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha1-armv8-aarch64-ce.S b/comm/third_party/libgcrypt/cipher/sha1-armv8-aarch64-ce.S
new file mode 100644
index 0000000000..223268cad2
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1-armv8-aarch64-ce.S
@@ -0,0 +1,201 @@
+/* sha1-armv8-aarch64-ce.S - ARM/CE accelerated SHA-1 transform function
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO) && defined(USE_SHA1)
+
+.cpu generic+simd+crypto
+
+.text
+
+
+/* Constants */
+
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xCA62C1D6
+.align 4
+gcry_sha1_aarch64_ce_K_VEC:
+.LK_VEC:
+.LK1: .long K1, K1, K1, K1
+.LK2: .long K2, K2, K2, K2
+.LK3: .long K3, K3, K3, K3
+.LK4: .long K4, K4, K4, K4
+
+
+/* Register macros */
+
+#define sH4 s0
+#define vH4 v0
+#define vH0123 v1
+
+#define qABCD q2
+#define sABCD s2
+#define vABCD v2
+#define sE0 s3
+#define vE0 v3
+#define sE1 s4
+#define vE1 v4
+
+#define vT0 v5
+#define vT1 v6
+
+#define vW0 v16
+#define vW1 v17
+#define vW2 v18
+#define vW3 v19
+
+#define vK1 v20
+#define vK2 v21
+#define vK3 v22
+#define vK4 v23
+
+
+/* Round macros */
+
+#define _(...) /*_*/
+#define do_add(dst, src0, src1) add dst.4s, src0.4s, src1.4s;
+#define do_sha1su0(w0,w1,w2) sha1su0 w0.4s,w1.4s,w2.4s;
+#define do_sha1su1(w0,w3) sha1su1 w0.4s,w3.4s;
+
+#define do_rounds(f, e0, e1, t, k, w0, w1, w2, w3, add_fn, sha1su0_fn, sha1su1_fn) \
+ sha1su1_fn( v##w3, v##w2 ); \
+ sha1h e0, sABCD; \
+ sha1##f qABCD, e1, v##t.4s; \
+ add_fn( v##t, v##w2, v##k ); \
+ sha1su0_fn( v##w0, v##w1, v##w2 );
+
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) eor reg.16b, reg.16b, reg.16b;
+
+
+/*
+ * unsigned int
+ * _gcry_sha1_transform_armv8_ce (void *ctx, const unsigned char *data,
+ * size_t nblks)
+ */
+.align 3
+.globl _gcry_sha1_transform_armv8_ce
+ELF(.type _gcry_sha1_transform_armv8_ce,%function;)
+_gcry_sha1_transform_armv8_ce:
+ /* input:
+ * x0: ctx, CTX
+ * x1: data (64*nblks bytes)
+ * x2: nblks
+ */
+ CFI_STARTPROC();
+
+ cbz x2, .Ldo_nothing;
+
+ GET_DATA_POINTER(x4, .LK_VEC);
+
+ ld1 {vH0123.4s}, [x0] /* load h0,h1,h2,h3 */
+ ld1 {vK1.4s-vK4.4s}, [x4] /* load K1,K2,K3,K4 */
+ ldr sH4, [x0, #16] /* load h4 */
+
+ ld1 {vW0.16b-vW3.16b}, [x1], #64
+ mov vABCD.16b, vH0123.16b
+
+ rev32 vW0.16b, vW0.16b
+ rev32 vW1.16b, vW1.16b
+ rev32 vW2.16b, vW2.16b
+ do_add(vT0, vW0, vK1)
+ rev32 vW3.16b, vW3.16b
+ do_add(vT1, vW1, vK1)
+
+.Loop:
+ do_rounds(c, sE1, sH4, T0, K1, W0, W1, W2, W3, do_add, do_sha1su0, _)
+ sub x2, x2, #1
+ do_rounds(c, sE0, sE1, T1, K1, W1, W2, W3, W0, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(c, sE1, sE0, T0, K1, W2, W3, W0, W1, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(c, sE0, sE1, T1, K2, W3, W0, W1, W2, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(c, sE1, sE0, T0, K2, W0, W1, W2, W3, do_add, do_sha1su0, do_sha1su1)
+
+ do_rounds(p, sE0, sE1, T1, K2, W1, W2, W3, W0, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(p, sE1, sE0, T0, K2, W2, W3, W0, W1, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(p, sE0, sE1, T1, K2, W3, W0, W1, W2, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(p, sE1, sE0, T0, K3, W0, W1, W2, W3, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(p, sE0, sE1, T1, K3, W1, W2, W3, W0, do_add, do_sha1su0, do_sha1su1)
+
+ do_rounds(m, sE1, sE0, T0, K3, W2, W3, W0, W1, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(m, sE0, sE1, T1, K3, W3, W0, W1, W2, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(m, sE1, sE0, T0, K3, W0, W1, W2, W3, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(m, sE0, sE1, T1, K4, W1, W2, W3, W0, do_add, do_sha1su0, do_sha1su1)
+ do_rounds(m, sE1, sE0, T0, K4, W2, W3, W0, W1, do_add, do_sha1su0, do_sha1su1)
+
+ do_rounds(p, sE0, sE1, T1, K4, W3, W0, W1, W2, do_add, do_sha1su0, do_sha1su1)
+ cbz x2, .Lend
+
+ ld1 {vW0.16b-vW1.16b}, [x1], #32 /* preload */
+ do_rounds(p, sE1, sE0, T0, K4, _ , _ , W2, W3, do_add, _, do_sha1su1)
+ rev32 vW0.16b, vW0.16b
+ ld1 {vW2.16b}, [x1], #16
+ rev32 vW1.16b, vW1.16b
+ do_rounds(p, sE0, sE1, T1, K4, _ , _ , W3, _ , do_add, _, _)
+ ld1 {vW3.16b}, [x1], #16
+ rev32 vW2.16b, vW2.16b
+ do_rounds(p, sE1, sE0, T0, _, _, _, _, _, _, _, _)
+ rev32 vW3.16b, vW3.16b
+ do_rounds(p, sE0, sE1, T1, _, _, _, _, _, _, _, _)
+
+ do_add(vT0, vW0, vK1)
+ add vH4.2s, vH4.2s, vE0.2s
+ add vABCD.4s, vABCD.4s, vH0123.4s
+ do_add(vT1, vW1, vK1)
+
+ mov vH0123.16b, vABCD.16b
+
+ b .Loop
+
+.Lend:
+ do_rounds(p, sE1, sE0, T0, K4, _ , _ , W2, W3, do_add, _, do_sha1su1)
+ do_rounds(p, sE0, sE1, T1, K4, _ , _ , W3, _ , do_add, _, _)
+ do_rounds(p, sE1, sE0, T0, _, _, _, _, _, _, _, _)
+ do_rounds(p, sE0, sE1, T1, _, _, _, _, _, _, _, _)
+
+ add vH4.2s, vH4.2s, vE0.2s
+ add vH0123.4s, vH0123.4s, vABCD.4s
+
+ CLEAR_REG(vW0)
+ CLEAR_REG(vW1)
+ CLEAR_REG(vW2)
+ CLEAR_REG(vW3)
+ CLEAR_REG(vABCD)
+ CLEAR_REG(vE1)
+ CLEAR_REG(vE0)
+
+ str sH4, [x0, #16] /* store h4 */
+ st1 {vH0123.4s}, [x0] /* store h0,h1,h2,h3 */
+
+ CLEAR_REG(vH0123)
+ CLEAR_REG(vH4)
+
+.Ldo_nothing:
+ mov x0, #0
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_sha1_transform_armv8_ce,.-_gcry_sha1_transform_armv8_ce;)
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha1-avx-amd64.S b/comm/third_party/libgcrypt/cipher/sha1-avx-amd64.S
new file mode 100644
index 0000000000..85876ad418
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1-avx-amd64.S
@@ -0,0 +1,429 @@
+/* sha1-avx-amd64.S - Intel AVX accelerated SHA-1 transform function
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on sha1.c:
+ * Copyright (C) 1998, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Intel SSSE3 accelerated SHA-1 implementation based on white paper:
+ * "Improving the Performance of the Secure Hash Algorithm (SHA-1)"
+ * http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA1)
+
+#include "asm-common-amd64.h"
+
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+.text
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xCA62C1D6
+.align 16
+.LK_XMM:
+.LK1: .long K1, K1, K1, K1
+.LK2: .long K2, K2, K2, K2
+.LK3: .long K3, K3, K3, K3
+.LK4: .long K4, K4, K4, K4
+
+.Lbswap_shufb_ctl:
+ .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
+
+
+/* Register macros */
+
+#define RSTATE %r8
+#define RDATA %r9
+#define ROLDSTACK %r10
+#define RNBLKS %r11
+
+#define a %eax
+#define b %ebx
+#define c %ecx
+#define d %edx
+#define e %edi
+
+#define RT0 %esi
+#define RT1 %ebp
+
+#define Wtmp0 %xmm0
+#define Wtmp1 %xmm1
+
+#define W0 %xmm2
+#define W1 %xmm3
+#define W2 %xmm4
+#define W3 %xmm5
+#define W4 %xmm6
+#define W5 %xmm7
+#define W6 %xmm8
+#define W7 %xmm9
+
+#define BSWAP_REG %xmm10
+
+
+/* Round function macros. */
+
+#define WK(i) (((i) & 15) * 4)(%rsp)
+
+#define R_F1(a,b,c,d,e,i) \
+ movl c, RT0; \
+ addl WK(i), e; \
+ xorl d, RT0; \
+ movl a, RT1; \
+ andl b, RT0; \
+ shldl $30, b, b; \
+ xorl d, RT0; \
+ leal (RT0,e), e; \
+ shldl $5, RT1, RT1; \
+ addl RT1, e;
+
+#define R_F2(a,b,c,d,e,i) \
+ movl c, RT0; \
+ addl WK(i), e; \
+ xorl b, RT0; \
+ shldl $30, b, b; \
+ xorl d, RT0; \
+ movl a, RT1; \
+ leal (RT0,e), e; \
+ shldl $5, RT1, RT1; \
+ addl RT1, e;
+
+#define R_F3(a,b,c,d,e,i) \
+ movl c, RT0; \
+ movl b, RT1; \
+ xorl b, RT0; \
+ andl c, RT1; \
+ andl d, RT0; \
+ addl RT1, e; \
+ addl WK(i), e; \
+ shldl $30, b, b; \
+ movl a, RT1; \
+ leal (RT0,e), e; \
+ shldl $5, RT1, RT1; \
+ addl RT1, e;
+
+#define R_F4(a,b,c,d,e,i) R_F2(a,b,c,d,e,i)
+
+#define R(a,b,c,d,e,f,i) \
+ R_##f(a,b,c,d,e,i)
+
+
+/* Input expansion macros. */
+
+#define W_PRECALC_00_15_0(i, W, tmp0) \
+ vmovdqu (4*(i))(RDATA), tmp0;
+
+#define W_PRECALC_00_15_1(i, W, tmp0) \
+ vpshufb BSWAP_REG, tmp0, W;
+
+#define W_PRECALC_00_15_2(i, W, tmp0) \
+ vpaddd (.LK_XMM + ((i)/20)*16) rRIP, W, tmp0;
+
+#define W_PRECALC_00_15_3(i, W, tmp0) \
+ vmovdqa tmp0, WK(i&~3);
+
+#define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpalignr $8, W_m16, W_m12, W; \
+ vpsrldq $4, W_m04, tmp0; \
+ vpxor W_m08, W, W;
+
+#define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpxor W_m16, tmp0, tmp0; \
+ vpxor tmp0, W, W; \
+ vpslld $1, W, tmp0; \
+ vpslldq $12, W, tmp1; \
+ vpsrld $31, W, W;
+
+#define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpor W, tmp0, tmp0; \
+ vpsrld $30, tmp1, W; \
+ vpslld $2, tmp1, tmp1;
+
+#define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpxor W, tmp0, tmp0; \
+ vpxor tmp1, tmp0, W; \
+ vpaddd (.LK_XMM + ((i)/20)*16) rRIP, W, tmp0; \
+ vmovdqa tmp0, WK((i)&~3);
+
+#define W_PRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpxor W_m28, W, W; \
+ vpalignr $8, W_m08, W_m04, tmp0;
+
+#define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpxor W_m16, W, W; \
+ vpxor tmp0, W, W;
+
+#define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpsrld $30, W, tmp0; \
+ vpslld $2, W, W;
+
+#define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpor W, tmp0, W; \
+ vpaddd (.LK_XMM + ((i)/20)*16) rRIP, W, tmp0; \
+ vmovdqa tmp0, WK((i)&~3);
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_amd64_avx (void *ctx, const unsigned char *data,
+ * size_t nblks)
+ */
+.globl _gcry_sha1_transform_amd64_avx
+ELF(.type _gcry_sha1_transform_amd64_avx,@function)
+.align 16
+_gcry_sha1_transform_amd64_avx:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: data (64*nblks bytes)
+ * %rdx: nblks
+ */
+ CFI_STARTPROC();
+
+ xorl %eax, %eax;
+ cmpq $0, %rdx;
+ jz .Lret;
+
+ vzeroupper;
+
+ movq %rdx, RNBLKS;
+ movq %rdi, RSTATE;
+ movq %rsi, RDATA;
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+
+ movq %rsp, ROLDSTACK;
+ CFI_DEF_CFA_REGISTER(ROLDSTACK);
+
+ subq $(16*4), %rsp;
+ andq $(~31), %rsp;
+
+ /* Get the values of the chaining variables. */
+ movl state_h0(RSTATE), a;
+ movl state_h1(RSTATE), b;
+ movl state_h2(RSTATE), c;
+ movl state_h3(RSTATE), d;
+ movl state_h4(RSTATE), e;
+
+ vmovdqa .Lbswap_shufb_ctl rRIP, BSWAP_REG;
+
+ /* Precalc 0-15. */
+ W_PRECALC_00_15_0(0, W0, Wtmp0);
+ W_PRECALC_00_15_1(1, W0, Wtmp0);
+ W_PRECALC_00_15_2(2, W0, Wtmp0);
+ W_PRECALC_00_15_3(3, W0, Wtmp0);
+ W_PRECALC_00_15_0(4, W7, Wtmp0);
+ W_PRECALC_00_15_1(5, W7, Wtmp0);
+ W_PRECALC_00_15_2(6, W7, Wtmp0);
+ W_PRECALC_00_15_3(7, W7, Wtmp0);
+ W_PRECALC_00_15_0(8, W6, Wtmp0);
+ W_PRECALC_00_15_1(9, W6, Wtmp0);
+ W_PRECALC_00_15_2(10, W6, Wtmp0);
+ W_PRECALC_00_15_3(11, W6, Wtmp0);
+ W_PRECALC_00_15_0(12, W5, Wtmp0);
+ W_PRECALC_00_15_1(13, W5, Wtmp0);
+ W_PRECALC_00_15_2(14, W5, Wtmp0);
+ W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+.align 8
+.Loop:
+ addq $64, RDATA;
+
+ /* Transform 0-15 + Precalc 16-31. */
+ R( a, b, c, d, e, F1, 0 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F1, 2 ); W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F1, 3 ); W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F1, 4 ); W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 5 ); W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 6 ); W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F1, 7 ); W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F1, 8 ); W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F1, 9 ); W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 10 ); W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 11 ); W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F1, 12 ); W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F1, 13 ); W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F1, 14 ); W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 15 ); W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+
+ /* Transform 16-63 + Precalc 32-79. */
+ R( e, a, b, c, d, F1, 16 ); W_PRECALC_32_79_0(32, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( d, e, a, b, c, F1, 17 ); W_PRECALC_32_79_1(33, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( c, d, e, a, b, F1, 18 ); W_PRECALC_32_79_2(34, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( b, c, d, e, a, F1, 19 ); W_PRECALC_32_79_3(35, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( a, b, c, d, e, F2, 20 ); W_PRECALC_32_79_0(36, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( e, a, b, c, d, F2, 21 ); W_PRECALC_32_79_1(37, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( d, e, a, b, c, F2, 22 ); W_PRECALC_32_79_2(38, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( c, d, e, a, b, F2, 23 ); W_PRECALC_32_79_3(39, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( b, c, d, e, a, F2, 24 ); W_PRECALC_32_79_0(40, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( a, b, c, d, e, F2, 25 ); W_PRECALC_32_79_1(41, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( e, a, b, c, d, F2, 26 ); W_PRECALC_32_79_2(42, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( d, e, a, b, c, F2, 27 ); W_PRECALC_32_79_3(43, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( c, d, e, a, b, F2, 28 ); W_PRECALC_32_79_0(44, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( b, c, d, e, a, F2, 29 ); W_PRECALC_32_79_1(45, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( a, b, c, d, e, F2, 30 ); W_PRECALC_32_79_2(46, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( e, a, b, c, d, F2, 31 ); W_PRECALC_32_79_3(47, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( d, e, a, b, c, F2, 32 ); W_PRECALC_32_79_0(48, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( c, d, e, a, b, F2, 33 ); W_PRECALC_32_79_1(49, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( b, c, d, e, a, F2, 34 ); W_PRECALC_32_79_2(50, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( a, b, c, d, e, F2, 35 ); W_PRECALC_32_79_3(51, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( e, a, b, c, d, F2, 36 ); W_PRECALC_32_79_0(52, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( d, e, a, b, c, F2, 37 ); W_PRECALC_32_79_1(53, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( c, d, e, a, b, F2, 38 ); W_PRECALC_32_79_2(54, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( b, c, d, e, a, F2, 39 ); W_PRECALC_32_79_3(55, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( a, b, c, d, e, F3, 40 ); W_PRECALC_32_79_0(56, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( e, a, b, c, d, F3, 41 ); W_PRECALC_32_79_1(57, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( d, e, a, b, c, F3, 42 ); W_PRECALC_32_79_2(58, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( c, d, e, a, b, F3, 43 ); W_PRECALC_32_79_3(59, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( b, c, d, e, a, F3, 44 ); W_PRECALC_32_79_0(60, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( a, b, c, d, e, F3, 45 ); W_PRECALC_32_79_1(61, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( e, a, b, c, d, F3, 46 ); W_PRECALC_32_79_2(62, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( d, e, a, b, c, F3, 47 ); W_PRECALC_32_79_3(63, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( c, d, e, a, b, F3, 48 ); W_PRECALC_32_79_0(64, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( b, c, d, e, a, F3, 49 ); W_PRECALC_32_79_1(65, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( a, b, c, d, e, F3, 50 ); W_PRECALC_32_79_2(66, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( e, a, b, c, d, F3, 51 ); W_PRECALC_32_79_3(67, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( d, e, a, b, c, F3, 52 ); W_PRECALC_32_79_0(68, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( c, d, e, a, b, F3, 53 ); W_PRECALC_32_79_1(69, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( b, c, d, e, a, F3, 54 ); W_PRECALC_32_79_2(70, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( a, b, c, d, e, F3, 55 ); W_PRECALC_32_79_3(71, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( e, a, b, c, d, F3, 56 ); W_PRECALC_32_79_0(72, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( d, e, a, b, c, F3, 57 ); W_PRECALC_32_79_1(73, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( c, d, e, a, b, F3, 58 ); W_PRECALC_32_79_2(74, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( b, c, d, e, a, F3, 59 ); W_PRECALC_32_79_3(75, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( a, b, c, d, e, F4, 60 ); W_PRECALC_32_79_0(76, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( e, a, b, c, d, F4, 61 ); W_PRECALC_32_79_1(77, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( d, e, a, b, c, F4, 62 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( c, d, e, a, b, F4, 63 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+
+ decq RNBLKS;
+ jz .Lend;
+
+ /* Transform 64-79 + Precalc 0-15 of next block. */
+ R( b, c, d, e, a, F4, 64 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
+ R( a, b, c, d, e, F4, 65 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
+ R( e, a, b, c, d, F4, 66 ); W_PRECALC_00_15_2(2, W0, Wtmp0);
+ R( d, e, a, b, c, F4, 67 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
+ R( c, d, e, a, b, F4, 68 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
+ R( b, c, d, e, a, F4, 69 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
+ R( a, b, c, d, e, F4, 70 ); W_PRECALC_00_15_2(6, W7, Wtmp0);
+ R( e, a, b, c, d, F4, 71 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
+ R( d, e, a, b, c, F4, 72 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
+ R( c, d, e, a, b, F4, 73 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
+ R( b, c, d, e, a, F4, 74 ); W_PRECALC_00_15_2(10, W6, Wtmp0);
+ R( a, b, c, d, e, F4, 75 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
+ R( e, a, b, c, d, F4, 76 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
+ R( d, e, a, b, c, F4, 77 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
+ R( c, d, e, a, b, F4, 78 );
+ addl state_h0(RSTATE), a; W_PRECALC_00_15_2(14, W5, Wtmp0);
+ R( b, c, d, e, a, F4, 79 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ jmp .Loop;
+
+.align 16
+.Lend:
+ vzeroall;
+
+ /* Transform 64-79 + burn stack */
+ R( b, c, d, e, a, F4, 64 );
+ R( a, b, c, d, e, F4, 65 );
+ R( e, a, b, c, d, F4, 66 );
+ R( d, e, a, b, c, F4, 67 );
+ R( c, d, e, a, b, F4, 68 );
+ R( b, c, d, e, a, F4, 69 );
+ R( a, b, c, d, e, F4, 70 );
+ R( e, a, b, c, d, F4, 71 );
+ R( d, e, a, b, c, F4, 72 );
+ R( c, d, e, a, b, F4, 73 );
+ R( b, c, d, e, a, F4, 74 );
+ R( a, b, c, d, e, F4, 75 );
+ R( e, a, b, c, d, F4, 76 ); vmovdqa %xmm0, (0*16)(%rsp);
+ R( d, e, a, b, c, F4, 77 ); vmovdqa %xmm0, (1*16)(%rsp);
+ R( c, d, e, a, b, F4, 78 ); vmovdqa %xmm0, (2*16)(%rsp);
+ addl state_h0(RSTATE), a;
+ R( b, c, d, e, a, F4, 79 );
+
+ /* 16*4/16-1 = 3 */
+ vmovdqa %xmm0, (3*16)(%rsp);
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ movq ROLDSTACK, %rsp;
+ CFI_REGISTER(ROLDSTACK, %rsp);
+ CFI_DEF_CFA_REGISTER(%rsp);
+
+ popq %rbp;
+ CFI_POP(%rbp);
+ popq %rbx;
+ CFI_POP(%rbx);
+
+ /* stack already burned */
+ xorl %eax, %eax;
+
+.Lret:
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sha1_transform_amd64_avx,
+ .-_gcry_sha1_transform_amd64_avx;)
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha1-avx-bmi2-amd64.S b/comm/third_party/libgcrypt/cipher/sha1-avx-bmi2-amd64.S
new file mode 100644
index 0000000000..5dfcdca979
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1-avx-bmi2-amd64.S
@@ -0,0 +1,441 @@
+/* sha1-avx-bmi2-amd64.S - Intel AVX/BMI2 accelerated SHA-1 transform function
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on sha1.c:
+ * Copyright (C) 1998, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Intel SSSE3 accelerated SHA-1 implementation based on white paper:
+ * "Improving the Performance of the Secure Hash Algorithm (SHA-1)"
+ * http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+ defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA1)
+
+#include "asm-common-amd64.h"
+
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+.text
+.align 16
+.Lbswap_shufb_ctl:
+ .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
+
+.LK1: .long 0x5A827999
+.LK2: .long 0x6ED9EBA1
+.LK3: .long 0x8F1BBCDC
+.LK4: .long 0xCA62C1D6
+
+
+/* Register macros */
+
+#define RSTATE %r8
+#define RDATA %r9
+#define ROLDSTACK %r10
+#define RNBLKS %r11
+
+#define a %esi
+#define b %edi
+#define c %ebp
+#define d %edx
+#define e %ecx
+#define ne %ebx
+
+#define RT0 %eax
+#define RT1 %r12d
+
+#define Wtmp0 %xmm0
+#define Wtmp1 %xmm1
+
+#define W0 %xmm2
+#define W1 %xmm3
+#define W2 %xmm4
+#define W3 %xmm5
+#define W4 %xmm6
+#define W5 %xmm7
+#define W6 %xmm8
+#define W7 %xmm9
+
+#define BSWAP_REG %xmm10
+
+#define K1 %xmm11
+#define K2 %xmm12
+#define K3 %xmm13
+#define K4 %xmm14
+
+
+/* Round function macros. */
+
+#define WK(i) (((i) & 15) * 4)(%rsp)
+
+#define R_F1(a,b,c,d,e,i) \
+ movl c, RT0; \
+ andn d, b, RT1; \
+ addl WK(i), e; \
+ andl b, RT0; \
+ rorxl $2, b, b; \
+ addl RT1, e; \
+ addl ne, a; \
+ leal (RT0,e), ne; \
+ rorxl $27, a, e;
+
+#define R_F2(a,b,c,d,e,i) \
+ movl c, RT0; \
+ addl WK(i), e; \
+ xorl b, RT0; \
+ rorxl $2, b, b; \
+ xorl d, RT0; \
+ addl ne, a; \
+ leal (RT0,e), ne; \
+ rorxl $27, a, e;
+
+#define R_F3(a,b,c,d,e,i) \
+ movl c, RT0; \
+ movl b, RT1; \
+ addl WK(i), e; \
+ xorl b, RT0; \
+ andl c, RT1; \
+ andl d, RT0; \
+ addl RT1, e; \
+ rorxl $2, b, b; \
+ addl ne, a; \
+ leal (RT0,e), ne; \
+ rorxl $27, a, e;
+
+#define R_F4(a,b,c,d,e,i) R_F2(a,b,c,d,e,i)
+
+#define R(a,b,c,d,e,f,i) \
+ R_##f(a,b,c,d,e,i)
+
+
+/* Input expansion macros. */
+
+#define W_PRECALC_00_15_0(i, W, tmp0) \
+ vmovdqu (4*(i))(RDATA), tmp0;
+
+#define W_PRECALC_00_15_1(i, W, tmp0) \
+ vpshufb BSWAP_REG, tmp0, W;
+
+#define W_PRECALC_00_15_2(i, W, tmp0, K) \
+ vpaddd K, W, tmp0;
+
+#define W_PRECALC_00_15_3(i, W, tmp0) \
+ vmovdqa tmp0, WK(i&~3);
+
+#define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpalignr $8, W_m16, W_m12, W; \
+ vpsrldq $4, W_m04, tmp0; \
+ vpxor W_m08, W, W;
+
+#define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpxor W_m16, tmp0, tmp0; \
+ vpxor tmp0, W, W; \
+ vpslld $1, W, tmp0; \
+ vpslldq $12, W, tmp1; \
+ vpsrld $31, W, W;
+
+#define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpor W, tmp0, tmp0; \
+ vpsrld $30, tmp1, W; \
+ vpslld $2, tmp1, tmp1;
+
+#define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1, K) \
+ vpxor W, tmp0, tmp0; \
+ vpxor tmp1, tmp0, W; \
+ vpaddd K, W, tmp0; \
+ vmovdqa tmp0, WK((i)&~3);
+
+#define W_PRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpxor W_m28, W, W; \
+ vpalignr $8, W_m08, W_m04, tmp0;
+
+#define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpxor W_m16, W, W; \
+ vpxor tmp0, W, W;
+
+#define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpsrld $30, W, tmp0; \
+ vpslld $2, W, W;
+
+#define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0, K) \
+ vpor W, tmp0, W; \
+ vpaddd K, W, tmp0; \
+ vmovdqa tmp0, WK((i)&~3);
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_amd64_avx_bmi2 (void *ctx, const unsigned char *data,
+ * size_t nblks)
+ */
+.globl _gcry_sha1_transform_amd64_avx_bmi2
+ELF(.type _gcry_sha1_transform_amd64_avx_bmi2,@function)
+.align 16
+_gcry_sha1_transform_amd64_avx_bmi2:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: data (64*nblks bytes)
+ * %rdx: nblks
+ */
+ CFI_STARTPROC();
+
+ xorl %eax, %eax;
+ cmpq $0, %rdx;
+ jz .Lret;
+
+ vzeroupper;
+
+ movq %rdx, RNBLKS;
+ movq %rdi, RSTATE;
+ movq %rsi, RDATA;
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %r12;
+ CFI_PUSH(%r12);
+
+ movq %rsp, ROLDSTACK;
+ CFI_DEF_CFA_REGISTER(ROLDSTACK);
+
+ subq $(16*4), %rsp;
+ andq $(~31), %rsp;
+
+ /* Get the values of the chaining variables. */
+ movl state_h0(RSTATE), a;
+ movl state_h1(RSTATE), b;
+ movl state_h2(RSTATE), c;
+ movl state_h3(RSTATE), d;
+ movl state_h4(RSTATE), e;
+ xorl ne, ne;
+
+ vmovdqa .Lbswap_shufb_ctl rRIP, BSWAP_REG;
+ vpbroadcastd .LK1 rRIP, K1;
+ vpbroadcastd .LK2 rRIP, K2;
+ vpbroadcastd .LK3 rRIP, K3;
+ vpbroadcastd .LK4 rRIP, K4;
+
+ /* Precalc 0-15. */
+ W_PRECALC_00_15_0(0, W0, Wtmp0);
+ W_PRECALC_00_15_1(1, W0, Wtmp0);
+ W_PRECALC_00_15_2(2, W0, Wtmp0, K1);
+ W_PRECALC_00_15_3(3, W0, Wtmp0);
+ W_PRECALC_00_15_0(4, W7, Wtmp0);
+ W_PRECALC_00_15_1(5, W7, Wtmp0);
+ W_PRECALC_00_15_2(6, W7, Wtmp0, K1);
+ W_PRECALC_00_15_3(7, W7, Wtmp0);
+ W_PRECALC_00_15_0(8, W6, Wtmp0);
+ W_PRECALC_00_15_1(9, W6, Wtmp0);
+ W_PRECALC_00_15_2(10, W6, Wtmp0, K1);
+ W_PRECALC_00_15_3(11, W6, Wtmp0);
+ W_PRECALC_00_15_0(12, W5, Wtmp0);
+ W_PRECALC_00_15_1(13, W5, Wtmp0);
+ W_PRECALC_00_15_2(14, W5, Wtmp0, K1);
+ W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+.align 8
+.Loop:
+ addq $64, RDATA;
+
+ /* Transform 0-15 + Precalc 16-31. */
+ R( a, b, c, d, e, F1, 0 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F1, 2 ); W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F1, 3 ); W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1, K1);
+ R( b, c, d, e, a, F1, 4 ); W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 5 ); W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 6 ); W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F1, 7 ); W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1, K2);
+ R( c, d, e, a, b, F1, 8 ); W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F1, 9 ); W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 10 ); W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 11 ); W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1, K2);
+ R( d, e, a, b, c, F1, 12 ); W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F1, 13 ); W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F1, 14 ); W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 15 ); W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1, K2);
+
+ /* Transform 16-63 + Precalc 32-79. */
+ R( e, a, b, c, d, F1, 16 ); W_PRECALC_32_79_0(32, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( d, e, a, b, c, F1, 17 ); W_PRECALC_32_79_1(33, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( c, d, e, a, b, F1, 18 ); W_PRECALC_32_79_2(34, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( b, c, d, e, a, F1, 19 ); W_PRECALC_32_79_3(35, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0, K2);
+ R( a, b, c, d, e, F2, 20 ); W_PRECALC_32_79_0(36, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( e, a, b, c, d, F2, 21 ); W_PRECALC_32_79_1(37, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( d, e, a, b, c, F2, 22 ); W_PRECALC_32_79_2(38, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( c, d, e, a, b, F2, 23 ); W_PRECALC_32_79_3(39, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0, K2);
+ R( b, c, d, e, a, F2, 24 ); W_PRECALC_32_79_0(40, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( a, b, c, d, e, F2, 25 ); W_PRECALC_32_79_1(41, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( e, a, b, c, d, F2, 26 ); W_PRECALC_32_79_2(42, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( d, e, a, b, c, F2, 27 ); W_PRECALC_32_79_3(43, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0, K3);
+ R( c, d, e, a, b, F2, 28 ); W_PRECALC_32_79_0(44, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( b, c, d, e, a, F2, 29 ); W_PRECALC_32_79_1(45, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( a, b, c, d, e, F2, 30 ); W_PRECALC_32_79_2(46, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( e, a, b, c, d, F2, 31 ); W_PRECALC_32_79_3(47, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0, K3);
+ R( d, e, a, b, c, F2, 32 ); W_PRECALC_32_79_0(48, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( c, d, e, a, b, F2, 33 ); W_PRECALC_32_79_1(49, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( b, c, d, e, a, F2, 34 ); W_PRECALC_32_79_2(50, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( a, b, c, d, e, F2, 35 ); W_PRECALC_32_79_3(51, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0, K3);
+ R( e, a, b, c, d, F2, 36 ); W_PRECALC_32_79_0(52, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( d, e, a, b, c, F2, 37 ); W_PRECALC_32_79_1(53, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( c, d, e, a, b, F2, 38 ); W_PRECALC_32_79_2(54, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( b, c, d, e, a, F2, 39 ); W_PRECALC_32_79_3(55, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0, K3);
+ R( a, b, c, d, e, F3, 40 ); W_PRECALC_32_79_0(56, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( e, a, b, c, d, F3, 41 ); W_PRECALC_32_79_1(57, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( d, e, a, b, c, F3, 42 ); W_PRECALC_32_79_2(58, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( c, d, e, a, b, F3, 43 ); W_PRECALC_32_79_3(59, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0, K3);
+ R( b, c, d, e, a, F3, 44 ); W_PRECALC_32_79_0(60, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( a, b, c, d, e, F3, 45 ); W_PRECALC_32_79_1(61, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( e, a, b, c, d, F3, 46 ); W_PRECALC_32_79_2(62, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( d, e, a, b, c, F3, 47 ); W_PRECALC_32_79_3(63, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0, K4);
+ R( c, d, e, a, b, F3, 48 ); W_PRECALC_32_79_0(64, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( b, c, d, e, a, F3, 49 ); W_PRECALC_32_79_1(65, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( a, b, c, d, e, F3, 50 ); W_PRECALC_32_79_2(66, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( e, a, b, c, d, F3, 51 ); W_PRECALC_32_79_3(67, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0, K4);
+ R( d, e, a, b, c, F3, 52 ); W_PRECALC_32_79_0(68, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( c, d, e, a, b, F3, 53 ); W_PRECALC_32_79_1(69, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( b, c, d, e, a, F3, 54 ); W_PRECALC_32_79_2(70, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( a, b, c, d, e, F3, 55 ); W_PRECALC_32_79_3(71, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0, K4);
+ R( e, a, b, c, d, F3, 56 ); W_PRECALC_32_79_0(72, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( d, e, a, b, c, F3, 57 ); W_PRECALC_32_79_1(73, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( c, d, e, a, b, F3, 58 ); W_PRECALC_32_79_2(74, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( b, c, d, e, a, F3, 59 ); W_PRECALC_32_79_3(75, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0, K4);
+ R( a, b, c, d, e, F4, 60 ); W_PRECALC_32_79_0(76, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( e, a, b, c, d, F4, 61 ); W_PRECALC_32_79_1(77, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( d, e, a, b, c, F4, 62 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( c, d, e, a, b, F4, 63 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0, K4);
+
+ decq RNBLKS;
+ jz .Lend;
+
+ /* Transform 64-79 + Precalc 0-15 of next block. */
+ R( b, c, d, e, a, F4, 64 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
+ R( a, b, c, d, e, F4, 65 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
+ R( e, a, b, c, d, F4, 66 ); W_PRECALC_00_15_2(2, W0, Wtmp0, K1);
+ R( d, e, a, b, c, F4, 67 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
+ R( c, d, e, a, b, F4, 68 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
+ R( b, c, d, e, a, F4, 69 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
+ R( a, b, c, d, e, F4, 70 ); W_PRECALC_00_15_2(6, W7, Wtmp0, K1);
+ R( e, a, b, c, d, F4, 71 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
+ R( d, e, a, b, c, F4, 72 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
+ R( c, d, e, a, b, F4, 73 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
+ R( b, c, d, e, a, F4, 74 ); W_PRECALC_00_15_2(10, W6, Wtmp0, K1);
+ R( a, b, c, d, e, F4, 75 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
+ R( e, a, b, c, d, F4, 76 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
+ R( d, e, a, b, c, F4, 77 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
+ R( c, d, e, a, b, F4, 78 );
+ addl state_h0(RSTATE), a; W_PRECALC_00_15_2(14, W5, Wtmp0, K1);
+ R( b, c, d, e, a, F4, 79 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
+ addl ne, a;
+ xorl ne, ne;
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ jmp .Loop;
+
+.align 16
+.Lend:
+ vzeroall;
+
+ /* Transform 64-79 + burn stack */
+ R( b, c, d, e, a, F4, 64 );
+ R( a, b, c, d, e, F4, 65 );
+ R( e, a, b, c, d, F4, 66 );
+ R( d, e, a, b, c, F4, 67 );
+ R( c, d, e, a, b, F4, 68 );
+ R( b, c, d, e, a, F4, 69 );
+ R( a, b, c, d, e, F4, 70 );
+ R( e, a, b, c, d, F4, 71 );
+ R( d, e, a, b, c, F4, 72 );
+ R( c, d, e, a, b, F4, 73 );
+ R( b, c, d, e, a, F4, 74 );
+ R( a, b, c, d, e, F4, 75 );
+ R( e, a, b, c, d, F4, 76 ); vmovdqa %xmm0, (0*16)(%rsp);
+ R( d, e, a, b, c, F4, 77 ); vmovdqa %xmm0, (1*16)(%rsp);
+ R( c, d, e, a, b, F4, 78 ); vmovdqa %xmm0, (2*16)(%rsp);
+ addl state_h0(RSTATE), a;
+ R( b, c, d, e, a, F4, 79 );
+ addl ne, a;
+ xorl ne, ne;
+
+ /* 16*4/16-1 = 3 */
+ vmovdqa %xmm0, (3*16)(%rsp);
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ movq ROLDSTACK, %rsp;
+ CFI_REGISTER(ROLDSTACK, %rsp);
+ CFI_DEF_CFA_REGISTER(%rsp);
+
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbp;
+ CFI_POP(%rbp);
+ popq %rbx;
+ CFI_POP(%rbx);
+
+ /* stack already burned */
+ xorl %eax, %eax;
+
+.Lret:
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sha1_transform_amd64_avx_bmi2,
+ .-_gcry_sha1_transform_amd64_avx_bmi2;)
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha1-avx2-bmi2-amd64.S b/comm/third_party/libgcrypt/cipher/sha1-avx2-bmi2-amd64.S
new file mode 100644
index 0000000000..938632305a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1-avx2-bmi2-amd64.S
@@ -0,0 +1,573 @@
+/* sha1-avx2-bmi2-amd64.S - Intel AVX2/BMI2 accelerated SHA-1 transform function
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on sha1.c:
+ * Copyright (C) 1998, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Intel SSSE3 accelerated SHA-1 implementation based on white paper:
+ * "Improving the Performance of the Secure Hash Algorithm (SHA-1)"
+ * http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_GCC_INLINE_ASM_BMI2) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+ defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(USE_SHA1)
+
+#include "asm-common-amd64.h"
+
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+#define WK_STACK_WORDS (80 * 2)
+
+.text
+.align 16
+.Lbswap_shufb_ctl:
+ .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
+
+.LK1: .long 0x5A827999
+.LK2: .long 0x6ED9EBA1
+.LK3: .long 0x8F1BBCDC
+.LK4: .long 0xCA62C1D6
+
+
+/* Register macros */
+
+#define RSTATE %r8
+#define RDATA %r9
+#define ROLDSTACK %r10
+#define RNBLKS %r11
+
+#define a %eax
+#define b %ebx
+#define c %ecx
+#define d %edx
+#define e %edi
+#define ne %r12d
+
+#define RT0 %esi
+#define RT1 %ebp
+
+#define Wtmp0 %ymm0
+#define Wtmp1 %ymm1
+#define Wtmp0x %xmm0
+#define Wtmp1x %xmm1
+
+#define W0 %ymm2
+#define W1 %ymm3
+#define W2 %ymm4
+#define W3 %ymm5
+#define W4 %ymm6
+#define W5 %ymm7
+#define W6 %ymm8
+#define W7 %ymm9
+
+#define BSWAP_REG %ymm10
+
+#define K1 %ymm11
+#define K2 %ymm12
+#define K3 %ymm13
+#define K4 %ymm14
+
+
+/* Round function macros. */
+
+#define WK(i,block) ((block) * 16 + ((i) / 4) * 32 + ((i) % 4) * 4)(%rsp)
+#define PRE_WK(i) ((i) * 4 * 2)(%rsp)
+
+#define R_F1(a,b,c,d,e,i,block) \
+ movl c, RT0; \
+ andn d, b, RT1; \
+ addl WK(i,block), e; \
+ andl b, RT0; \
+ leal (a,ne), a; \
+ rorxl $2, b, b; \
+ addl RT1, e; \
+ rorxl $27, a, ne; \
+ addl RT0, e;
+
+#define R_F2(a,b,c,d,e,i,block) \
+ addl WK(i,block), e; \
+ movl c, RT0; \
+ xorl b, RT0; \
+ leal (a,ne), a; \
+ rorxl $2, b, b; \
+ xorl d, RT0; \
+ addl RT0, e; \
+ rorxl $27, a, ne;
+
+#define R_F3(a,b,c,d,e,i,block) \
+ movl c, RT0; \
+ addl WK(i,block), e; \
+ movl b, RT1; \
+ xorl b, RT0; \
+ leal (a,ne), a; \
+ rorxl $2, b, b; \
+ andl c, RT1; \
+ addl RT1, e; \
+ andl d, RT0; \
+ rorxl $27, a, ne; \
+ addl RT0, e;
+
+#define R_F4(a,b,c,d,e,i,block) R_F2(a,b,c,d,e,i,block)
+
+#define R(a,b,c,d,e,f,i,block) \
+ R_##f(a,b,c,d,e,i,block)
+
+
+/* Input expansion macros. */
+
+#define W_PRECALC_00_15_0(i, W, tmp0) \
+ vmovdqu (4*(i))(RDATA), tmp0##x; \
+ vinserti128 $1, (4*(i) + 64)(RDATA), tmp0, tmp0;
+
+#define W_PRECALC_00_15_1(i, W, tmp0) \
+ vpshufb BSWAP_REG, tmp0, W;
+
+#define W_PRECALC_00_15_2(i, W, tmp0, K) \
+ vpaddd K, W, tmp0;
+
+#define W_PRECALC_00_15_3(i, W, tmp0) \
+ vmovdqa tmp0, PRE_WK((i)&~3);
+
+#define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpalignr $8, W_m16, W_m12, W; \
+ vpsrldq $4, W_m04, tmp0; \
+ vpxor W_m08, W, W;
+
+#define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpxor W_m16, tmp0, tmp0; \
+ vpxor tmp0, W, W; \
+ vpslld $1, W, tmp0; \
+ vpslldq $12, W, tmp1; \
+ vpsrld $31, W, W;
+
+#define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ vpor W, tmp0, tmp0; \
+ vpsrld $30, tmp1, W; \
+ vpslld $2, tmp1, tmp1;
+
+#define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1, K) \
+ vpxor W, tmp0, tmp0; \
+ vpxor tmp1, tmp0, W; \
+ vpaddd K, W, tmp0; \
+ vmovdqa tmp0, PRE_WK((i)&~3);
+
+#define W_PRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpxor W_m28, W, W; \
+ vpalignr $8, W_m08, W_m04, tmp0;
+
+#define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpxor W_m16, W, W; \
+ vpxor tmp0, W, W;
+
+#define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ vpsrld $30, W, tmp0; \
+ vpslld $2, W, W;
+
+#define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0, K) \
+ vpor W, tmp0, W; \
+ vpaddd K, W, tmp0; \
+ vmovdqa tmp0, PRE_WK((i)&~3);
+
+
+/*
+ * Transform 2*nblks*64 bytes (2*nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_amd64_avx2_bmi2 (void *ctx, const unsigned char *data,
+ * size_t nblks)
+ */
+.globl _gcry_sha1_transform_amd64_avx2_bmi2
+ELF(.type _gcry_sha1_transform_amd64_avx2_bmi2,@function)
+.align 16
+_gcry_sha1_transform_amd64_avx2_bmi2:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: data (64*nblks bytes)
+ * %rdx: nblks (multiple of 2, larger than 0)
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ movq %rdx, RNBLKS;
+ movq %rdi, RSTATE;
+ movq %rsi, RDATA;
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+ pushq %r12;
+ CFI_PUSH(%r12);
+
+ movq %rsp, ROLDSTACK;
+ CFI_DEF_CFA_REGISTER(ROLDSTACK);
+
+ subq $(WK_STACK_WORDS*4), %rsp;
+ andq $(~63), %rsp;
+
+ /* Get the values of the chaining variables. */
+ movl state_h0(RSTATE), a;
+ movl state_h1(RSTATE), b;
+ movl state_h2(RSTATE), c;
+ movl state_h3(RSTATE), d;
+ movl state_h4(RSTATE), e;
+ xorl ne, ne;
+
+ vbroadcasti128 .Lbswap_shufb_ctl rRIP, BSWAP_REG;
+ vpbroadcastd .LK1 rRIP, K1;
+ vpbroadcastd .LK2 rRIP, K2;
+ vpbroadcastd .LK3 rRIP, K3;
+ vpbroadcastd .LK4 rRIP, K4;
+
+ /* Precalc 0-31 for block 1 & 2. */
+ W_PRECALC_00_15_0(0, W0, Wtmp0);
+ W_PRECALC_00_15_1(1, W0, Wtmp0);
+ W_PRECALC_00_15_2(2, W0, Wtmp0, K1);
+ W_PRECALC_00_15_3(3, W0, Wtmp0);
+ W_PRECALC_00_15_0(4, W7, Wtmp0);
+ W_PRECALC_00_15_1(5, W7, Wtmp0);
+ W_PRECALC_00_15_2(6, W7, Wtmp0, K1);
+ W_PRECALC_00_15_3(7, W7, Wtmp0);
+ W_PRECALC_00_15_0(8, W6, Wtmp0);
+ W_PRECALC_00_15_1(9, W6, Wtmp0);
+ W_PRECALC_00_15_2(10, W6, Wtmp0, K1);
+ W_PRECALC_00_15_3(11, W6, Wtmp0);
+ W_PRECALC_00_15_0(12, W5, Wtmp0);
+ W_PRECALC_00_15_1(13, W5, Wtmp0);
+ W_PRECALC_00_15_2(14, W5, Wtmp0, K1);
+ W_PRECALC_00_15_3(15, W5, Wtmp0);
+ W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1, K1);
+ W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1, K2);
+ W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1, K2);
+ W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1, K2);
+
+.align 8
+.Loop:
+ addq $(2 * 64), RDATA;
+
+ /* Transform 0-15 for block 1 + Precalc 32-47 for block 1 & 2. */
+ R( a, b, c, d, e, F1, 0, 0 ); W_PRECALC_32_79_0(32, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( e, a, b, c, d, F1, 1, 0 ); W_PRECALC_32_79_1(33, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( d, e, a, b, c, F1, 2, 0 ); W_PRECALC_32_79_2(34, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( c, d, e, a, b, F1, 3, 0 ); W_PRECALC_32_79_3(35, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0, K2);
+ R( b, c, d, e, a, F1, 4, 0 ); W_PRECALC_32_79_0(36, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( a, b, c, d, e, F1, 5, 0 ); W_PRECALC_32_79_1(37, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( e, a, b, c, d, F1, 6, 0 ); W_PRECALC_32_79_2(38, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( d, e, a, b, c, F1, 7, 0 ); W_PRECALC_32_79_3(39, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0, K2);
+ R( c, d, e, a, b, F1, 8, 0 ); W_PRECALC_32_79_0(40, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( b, c, d, e, a, F1, 9, 0 ); W_PRECALC_32_79_1(41, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( a, b, c, d, e, F1, 10, 0 ); W_PRECALC_32_79_2(42, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( e, a, b, c, d, F1, 11, 0 ); W_PRECALC_32_79_3(43, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0, K3);
+ R( d, e, a, b, c, F1, 12, 0 ); W_PRECALC_32_79_0(44, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( c, d, e, a, b, F1, 13, 0 ); W_PRECALC_32_79_1(45, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( b, c, d, e, a, F1, 14, 0 ); W_PRECALC_32_79_2(46, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( a, b, c, d, e, F1, 15, 0 ); W_PRECALC_32_79_3(47, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0, K3);
+
+ /* Transform 16-47 for block 1 + Precalc 48-79 for block 1 & 2. */
+ R( e, a, b, c, d, F1, 16, 0 ); W_PRECALC_32_79_0(48, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( d, e, a, b, c, F1, 17, 0 ); W_PRECALC_32_79_1(49, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( c, d, e, a, b, F1, 18, 0 ); W_PRECALC_32_79_2(50, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( b, c, d, e, a, F1, 19, 0 ); W_PRECALC_32_79_3(51, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0, K3);
+ R( a, b, c, d, e, F2, 20, 0 ); W_PRECALC_32_79_0(52, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( e, a, b, c, d, F2, 21, 0 ); W_PRECALC_32_79_1(53, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( d, e, a, b, c, F2, 22, 0 ); W_PRECALC_32_79_2(54, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( c, d, e, a, b, F2, 23, 0 ); W_PRECALC_32_79_3(55, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0, K3);
+ R( b, c, d, e, a, F2, 24, 0 ); W_PRECALC_32_79_0(56, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( a, b, c, d, e, F2, 25, 0 ); W_PRECALC_32_79_1(57, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( e, a, b, c, d, F2, 26, 0 ); W_PRECALC_32_79_2(58, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( d, e, a, b, c, F2, 27, 0 ); W_PRECALC_32_79_3(59, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0, K3);
+ R( c, d, e, a, b, F2, 28, 0 ); W_PRECALC_32_79_0(60, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( b, c, d, e, a, F2, 29, 0 ); W_PRECALC_32_79_1(61, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( a, b, c, d, e, F2, 30, 0 ); W_PRECALC_32_79_2(62, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( e, a, b, c, d, F2, 31, 0 ); W_PRECALC_32_79_3(63, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0, K4);
+ R( d, e, a, b, c, F2, 32, 0 ); W_PRECALC_32_79_0(64, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( c, d, e, a, b, F2, 33, 0 ); W_PRECALC_32_79_1(65, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( b, c, d, e, a, F2, 34, 0 ); W_PRECALC_32_79_2(66, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( a, b, c, d, e, F2, 35, 0 ); W_PRECALC_32_79_3(67, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0, K4);
+ R( e, a, b, c, d, F2, 36, 0 ); W_PRECALC_32_79_0(68, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( d, e, a, b, c, F2, 37, 0 ); W_PRECALC_32_79_1(69, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( c, d, e, a, b, F2, 38, 0 ); W_PRECALC_32_79_2(70, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( b, c, d, e, a, F2, 39, 0 ); W_PRECALC_32_79_3(71, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0, K4);
+ R( a, b, c, d, e, F3, 40, 0 ); W_PRECALC_32_79_0(72, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( e, a, b, c, d, F3, 41, 0 ); W_PRECALC_32_79_1(73, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( d, e, a, b, c, F3, 42, 0 ); W_PRECALC_32_79_2(74, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( c, d, e, a, b, F3, 43, 0 ); W_PRECALC_32_79_3(75, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0, K4);
+ R( b, c, d, e, a, F3, 44, 0 ); W_PRECALC_32_79_0(76, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( a, b, c, d, e, F3, 45, 0 ); W_PRECALC_32_79_1(77, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( e, a, b, c, d, F3, 46, 0 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( d, e, a, b, c, F3, 47, 0 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0, K4);
+
+ /* Transform 48-79 for block 1. */
+ R( c, d, e, a, b, F3, 48, 0 );
+ R( b, c, d, e, a, F3, 49, 0 );
+ R( a, b, c, d, e, F3, 50, 0 );
+ R( e, a, b, c, d, F3, 51, 0 );
+ R( d, e, a, b, c, F3, 52, 0 );
+ R( c, d, e, a, b, F3, 53, 0 );
+ R( b, c, d, e, a, F3, 54, 0 );
+ R( a, b, c, d, e, F3, 55, 0 );
+ R( e, a, b, c, d, F3, 56, 0 );
+ R( d, e, a, b, c, F3, 57, 0 );
+ R( c, d, e, a, b, F3, 58, 0 );
+ R( b, c, d, e, a, F3, 59, 0 );
+ R( a, b, c, d, e, F4, 60, 0 );
+ R( e, a, b, c, d, F4, 61, 0 );
+ R( d, e, a, b, c, F4, 62, 0 );
+ R( c, d, e, a, b, F4, 63, 0 );
+ R( b, c, d, e, a, F4, 64, 0 );
+ R( a, b, c, d, e, F4, 65, 0 );
+ R( e, a, b, c, d, F4, 66, 0 );
+ R( d, e, a, b, c, F4, 67, 0 );
+ R( c, d, e, a, b, F4, 68, 0 );
+ R( b, c, d, e, a, F4, 69, 0 );
+ R( a, b, c, d, e, F4, 70, 0 );
+ R( e, a, b, c, d, F4, 71, 0 );
+ R( d, e, a, b, c, F4, 72, 0 );
+ R( c, d, e, a, b, F4, 73, 0 );
+ R( b, c, d, e, a, F4, 74, 0 );
+ R( a, b, c, d, e, F4, 75, 0 );
+ R( e, a, b, c, d, F4, 76, 0 );
+ R( d, e, a, b, c, F4, 77, 0 );
+ R( c, d, e, a, b, F4, 78, 0 );
+ addl state_h0(RSTATE), a;
+ R( b, c, d, e, a, F4, 79, 0 );
+ addl ne, a;
+ xorl ne, ne;
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ /* Transform 0-47 for block 2. */
+ R( a, b, c, d, e, F1, 0, 1 );
+ R( e, a, b, c, d, F1, 1, 1 );
+ R( d, e, a, b, c, F1, 2, 1 );
+ R( c, d, e, a, b, F1, 3, 1 );
+ R( b, c, d, e, a, F1, 4, 1 );
+ R( a, b, c, d, e, F1, 5, 1 );
+ R( e, a, b, c, d, F1, 6, 1 );
+ R( d, e, a, b, c, F1, 7, 1 );
+ R( c, d, e, a, b, F1, 8, 1 );
+ R( b, c, d, e, a, F1, 9, 1 );
+ R( a, b, c, d, e, F1, 10, 1 );
+ R( e, a, b, c, d, F1, 11, 1 );
+ R( d, e, a, b, c, F1, 12, 1 );
+ R( c, d, e, a, b, F1, 13, 1 );
+ R( b, c, d, e, a, F1, 14, 1 );
+ R( a, b, c, d, e, F1, 15, 1 );
+ R( e, a, b, c, d, F1, 16, 1 );
+ R( d, e, a, b, c, F1, 17, 1 );
+ R( c, d, e, a, b, F1, 18, 1 );
+ R( b, c, d, e, a, F1, 19, 1 );
+ R( a, b, c, d, e, F2, 20, 1 );
+ R( e, a, b, c, d, F2, 21, 1 );
+ R( d, e, a, b, c, F2, 22, 1 );
+ R( c, d, e, a, b, F2, 23, 1 );
+ R( b, c, d, e, a, F2, 24, 1 );
+ R( a, b, c, d, e, F2, 25, 1 );
+ R( e, a, b, c, d, F2, 26, 1 );
+ R( d, e, a, b, c, F2, 27, 1 );
+ R( c, d, e, a, b, F2, 28, 1 );
+ R( b, c, d, e, a, F2, 29, 1 );
+ R( a, b, c, d, e, F2, 30, 1 );
+ R( e, a, b, c, d, F2, 31, 1 );
+ R( d, e, a, b, c, F2, 32, 1 );
+ R( c, d, e, a, b, F2, 33, 1 );
+ R( b, c, d, e, a, F2, 34, 1 );
+ R( a, b, c, d, e, F2, 35, 1 );
+ R( e, a, b, c, d, F2, 36, 1 );
+ R( d, e, a, b, c, F2, 37, 1 );
+ R( c, d, e, a, b, F2, 38, 1 );
+ R( b, c, d, e, a, F2, 39, 1 );
+ R( a, b, c, d, e, F3, 40, 1 );
+ R( e, a, b, c, d, F3, 41, 1 );
+ R( d, e, a, b, c, F3, 42, 1 );
+ R( c, d, e, a, b, F3, 43, 1 );
+ R( b, c, d, e, a, F3, 44, 1 );
+ R( a, b, c, d, e, F3, 45, 1 );
+ R( e, a, b, c, d, F3, 46, 1 );
+ R( d, e, a, b, c, F3, 47, 1 );
+
+ addq $-2, RNBLKS;
+ jz .Lend;
+
+ /* Transform 48-79 for block 2 + Precalc 0-31 for next two blocks. */
+ R( c, d, e, a, b, F3, 48, 1 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
+ R( b, c, d, e, a, F3, 49, 1 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
+ R( a, b, c, d, e, F3, 50, 1 ); W_PRECALC_00_15_2(2, W0, Wtmp0, K1);
+ R( e, a, b, c, d, F3, 51, 1 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
+ R( d, e, a, b, c, F3, 52, 1 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
+ R( c, d, e, a, b, F3, 53, 1 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
+ R( b, c, d, e, a, F3, 54, 1 ); W_PRECALC_00_15_2(6, W7, Wtmp0, K1);
+ R( a, b, c, d, e, F3, 55, 1 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
+ R( e, a, b, c, d, F3, 56, 1 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
+ R( d, e, a, b, c, F3, 57, 1 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
+ R( c, d, e, a, b, F3, 58, 1 ); W_PRECALC_00_15_2(10, W6, Wtmp0, K1);
+ R( b, c, d, e, a, F3, 59, 1 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
+ R( a, b, c, d, e, F4, 60, 1 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
+ R( e, a, b, c, d, F4, 61, 1 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
+ R( d, e, a, b, c, F4, 62, 1 ); W_PRECALC_00_15_2(14, W5, Wtmp0, K1);
+ R( c, d, e, a, b, F4, 63, 1 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
+ R( b, c, d, e, a, F4, 64, 1 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F4, 65, 1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F4, 66, 1 ); W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F4, 67, 1 ); W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1, K1);
+ R( c, d, e, a, b, F4, 68, 1 ); W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F4, 69, 1 ); W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F4, 70, 1 ); W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F4, 71, 1 ); W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1, K2);
+ R( d, e, a, b, c, F4, 72, 1 ); W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F4, 73, 1 ); W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F4, 74, 1 ); W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F4, 75, 1 ); W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1, K2);
+ R( e, a, b, c, d, F4, 76, 1 ); W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F4, 77, 1 ); W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F4, 78, 1 ); W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ addl state_h0(RSTATE), a; W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1, K2);
+ R( b, c, d, e, a, F4, 79, 1 );
+ addl ne, a;
+ xorl ne, ne;
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ jmp .Loop;
+
+.align 16
+.Lend:
+ vzeroall;
+
+ /* Transform 48-79 for block 2 + burn stack */
+ R( c, d, e, a, b, F3, 48, 1 );
+ R( b, c, d, e, a, F3, 49, 1 );
+ R( a, b, c, d, e, F3, 50, 1 );
+ R( e, a, b, c, d, F3, 51, 1 );
+ R( d, e, a, b, c, F3, 52, 1 );
+ R( c, d, e, a, b, F3, 53, 1 );
+ R( b, c, d, e, a, F3, 54, 1 );
+ R( a, b, c, d, e, F3, 55, 1 );
+ R( e, a, b, c, d, F3, 56, 1 );
+ R( d, e, a, b, c, F3, 57, 1 );
+ R( c, d, e, a, b, F3, 58, 1 );
+ R( b, c, d, e, a, F3, 59, 1 );
+ R( a, b, c, d, e, F4, 60, 1 ); vmovdqa %ymm0, (0*32)(%rsp);
+ R( e, a, b, c, d, F4, 61, 1 ); vmovdqa %ymm0, (1*32)(%rsp);
+ R( d, e, a, b, c, F4, 62, 1 ); vmovdqa %ymm0, (2*32)(%rsp);
+ R( c, d, e, a, b, F4, 63, 1 ); vmovdqa %ymm0, (3*32)(%rsp);
+ R( b, c, d, e, a, F4, 64, 1 ); vmovdqa %ymm0, (4*32)(%rsp);
+ R( a, b, c, d, e, F4, 65, 1 ); vmovdqa %ymm0, (5*32)(%rsp);
+ R( e, a, b, c, d, F4, 66, 1 ); vmovdqa %ymm0, (6*32)(%rsp);
+ R( d, e, a, b, c, F4, 67, 1 ); vmovdqa %ymm0, (7*32)(%rsp);
+ R( c, d, e, a, b, F4, 68, 1 ); vmovdqa %ymm0, (8*32)(%rsp);
+ R( b, c, d, e, a, F4, 69, 1 ); vmovdqa %ymm0, (9*32)(%rsp);
+ R( a, b, c, d, e, F4, 70, 1 ); vmovdqa %ymm0, (10*32)(%rsp);
+ R( e, a, b, c, d, F4, 71, 1 ); vmovdqa %ymm0, (11*32)(%rsp);
+ R( d, e, a, b, c, F4, 72, 1 ); vmovdqa %ymm0, (12*32)(%rsp);
+ R( c, d, e, a, b, F4, 73, 1 ); vmovdqa %ymm0, (13*32)(%rsp);
+ R( b, c, d, e, a, F4, 74, 1 ); vmovdqa %ymm0, (14*32)(%rsp);
+ R( a, b, c, d, e, F4, 75, 1 ); vmovdqa %ymm0, (15*32)(%rsp);
+ R( e, a, b, c, d, F4, 76, 1 ); vmovdqa %ymm0, (16*32)(%rsp);
+ R( d, e, a, b, c, F4, 77, 1 ); vmovdqa %ymm0, (17*32)(%rsp);
+ R( c, d, e, a, b, F4, 78, 1 ); vmovdqa %ymm0, (18*32)(%rsp);
+ addl state_h0(RSTATE), a;
+ R( b, c, d, e, a, F4, 79, 1 );
+ addl ne, a;
+ xorl ne, ne;
+
+ /* WK_STACK_WORDS*4/32-1 = 19 */
+ vmovdqa %ymm0, (19*32)(%rsp);
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ movq ROLDSTACK, %rsp;
+ CFI_REGISTER(ROLDSTACK, %rsp);
+ CFI_DEF_CFA_REGISTER(%rsp);
+
+ popq %r12;
+ CFI_POP(%r12);
+ popq %rbp;
+ CFI_POP(%rbp);
+ popq %rbx;
+ CFI_POP(%rbx);
+
+ /* stack already burned */
+ xorl %eax, %eax;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sha1_transform_amd64_avx2_bmi2,
+ .-_gcry_sha1_transform_amd64_avx2_bmi2;)
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha1-intel-shaext.c b/comm/third_party/libgcrypt/cipher/sha1-intel-shaext.c
new file mode 100644
index 0000000000..ddf2be2aa1
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1-intel-shaext.c
@@ -0,0 +1,292 @@
+/* sha1-intel-shaext.S - SHAEXT accelerated SHA-1 transform function
+ * Copyright (C) 2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "types.h"
+
+#if defined(HAVE_GCC_INLINE_ASM_SHAEXT) && \
+ defined(HAVE_GCC_INLINE_ASM_SSE41) && defined(USE_SHA1) && \
+ defined(ENABLE_SHAEXT_SUPPORT)
+
+#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 NO_INSTRUMENT_FUNCTION __attribute__((no_instrument_function))
+
+#define ASM_FUNC_ATTR NO_INSTRUMENT_FUNCTION
+
+/* Two macros to be called prior and after the use of SHA-EXT
+ 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 shaext_prepare_variable char win64tmp[2*16]
+# define shaext_prepare_variable_size sizeof(win64tmp)
+# define shaext_prepare() \
+ do { asm volatile ("movdqu %%xmm6, (%0)\n" \
+ "movdqu %%xmm7, (%1)\n" \
+ : \
+ : "r" (&win64tmp[0]), "r" (&win64tmp[16]) \
+ : "memory"); \
+ } while (0)
+# define shaext_cleanup(tmp0,tmp1) \
+ do { asm volatile ("movdqu (%0), %%xmm6\n" \
+ "movdqu (%1), %%xmm7\n" \
+ "pxor %%xmm0, %%xmm0\n" \
+ "pxor %%xmm1, %%xmm1\n" \
+ "pxor %%xmm2, %%xmm2\n" \
+ "pxor %%xmm3, %%xmm3\n" \
+ "pxor %%xmm4, %%xmm4\n" \
+ "pxor %%xmm5, %%xmm5\n" \
+ "movdqa %%xmm0, (%2)\n\t" \
+ "movdqa %%xmm0, (%3)\n\t" \
+ : \
+ : "r" (&win64tmp[0]), "r" (&win64tmp[16]), \
+ "r" (tmp0), "r" (tmp1) \
+ : "memory"); \
+ } while (0)
+#else
+# define shaext_prepare_variable
+# define shaext_prepare_variable_size 0
+# define shaext_prepare() do { } while (0)
+# define shaext_cleanup(tmp0,tmp1) \
+ do { asm volatile ("pxor %%xmm0, %%xmm0\n" \
+ "pxor %%xmm1, %%xmm1\n" \
+ "pxor %%xmm2, %%xmm2\n" \
+ "pxor %%xmm3, %%xmm3\n" \
+ "pxor %%xmm4, %%xmm4\n" \
+ "pxor %%xmm5, %%xmm5\n" \
+ "pxor %%xmm6, %%xmm6\n" \
+ "pxor %%xmm7, %%xmm7\n" \
+ "movdqa %%xmm0, (%0)\n\t" \
+ "movdqa %%xmm0, (%1)\n\t" \
+ : \
+ : "r" (tmp0), "r" (tmp1) \
+ : "memory"); \
+ } while (0)
+#endif
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ */
+unsigned int ASM_FUNC_ATTR
+_gcry_sha1_transform_intel_shaext(void *state, const unsigned char *data,
+ size_t nblks)
+{
+ 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 };
+ char save_buf[2 * 16 + 15];
+ char *abcd_save;
+ char *e_save;
+ shaext_prepare_variable;
+
+ if (nblks == 0)
+ return 0;
+
+ shaext_prepare ();
+
+ asm volatile ("" : "=r" (abcd_save) : "0" (save_buf) : "memory");
+ abcd_save = abcd_save + (-(uintptr_t)abcd_save & 15);
+ e_save = abcd_save + 16;
+
+ /* byteswap mask => XMM7 */
+ asm volatile ("movdqa %[mask], %%xmm7\n\t" /* Preload mask */
+ :
+ : [mask] "m" (*be_mask)
+ : "memory");
+
+ /* Load state.. ABCD => XMM4, E => XMM5 */
+ asm volatile ("movd 16(%[state]), %%xmm5\n\t"
+ "movdqu (%[state]), %%xmm4\n\t"
+ "pslldq $12, %%xmm5\n\t"
+ "pshufd $0x1b, %%xmm4, %%xmm4\n\t"
+ "movdqa %%xmm5, (%[e_save])\n\t"
+ "movdqa %%xmm4, (%[abcd_save])\n\t"
+ :
+ : [state] "r" (state), [abcd_save] "r" (abcd_save),
+ [e_save] "r" (e_save)
+ : "memory" );
+
+ /* DATA => XMM[0..4] */
+ asm volatile ("movdqu 0(%[data]), %%xmm0\n\t"
+ "movdqu 16(%[data]), %%xmm1\n\t"
+ "movdqu 32(%[data]), %%xmm2\n\t"
+ "movdqu 48(%[data]), %%xmm3\n\t"
+ "pshufb %%xmm7, %%xmm0\n\t"
+ "pshufb %%xmm7, %%xmm1\n\t"
+ "pshufb %%xmm7, %%xmm2\n\t"
+ "pshufb %%xmm7, %%xmm3\n\t"
+ :
+ : [data] "r" (data)
+ : "memory" );
+ data += 64;
+
+ while (1)
+ {
+ /* Round 0..3 */
+ asm volatile ("paddd %%xmm0, %%xmm5\n\t"
+ "movdqa %%xmm4, %%xmm6\n\t" /* ABCD => E1 */
+ "sha1rnds4 $0, %%xmm5, %%xmm4\n\t"
+ ::: "memory" );
+
+ /* Round 4..7 */
+ asm volatile ("sha1nexte %%xmm1, %%xmm6\n\t"
+ "movdqa %%xmm4, %%xmm5\n\t"
+ "sha1rnds4 $0, %%xmm6, %%xmm4\n\t"
+ "sha1msg1 %%xmm1, %%xmm0\n\t"
+ ::: "memory" );
+
+ /* Round 8..11 */
+ asm volatile ("sha1nexte %%xmm2, %%xmm5\n\t"
+ "movdqa %%xmm4, %%xmm6\n\t"
+ "sha1rnds4 $0, %%xmm5, %%xmm4\n\t"
+ "sha1msg1 %%xmm2, %%xmm1\n\t"
+ "pxor %%xmm2, %%xmm0\n\t"
+ ::: "memory" );
+
+#define ROUND(imm, E0, E1, MSG0, MSG1, MSG2, MSG3) \
+ asm volatile ("sha1nexte %%"MSG0", %%"E0"\n\t" \
+ "movdqa %%xmm4, %%"E1"\n\t" \
+ "sha1msg2 %%"MSG0", %%"MSG1"\n\t" \
+ "sha1rnds4 $"imm", %%"E0", %%xmm4\n\t" \
+ "sha1msg1 %%"MSG0", %%"MSG3"\n\t" \
+ "pxor %%"MSG0", %%"MSG2"\n\t" \
+ ::: "memory" )
+
+ /* Rounds 12..15 to 64..67 */
+ ROUND("0", "xmm6", "xmm5", "xmm3", "xmm0", "xmm1", "xmm2");
+ ROUND("0", "xmm5", "xmm6", "xmm0", "xmm1", "xmm2", "xmm3");
+ ROUND("1", "xmm6", "xmm5", "xmm1", "xmm2", "xmm3", "xmm0");
+ ROUND("1", "xmm5", "xmm6", "xmm2", "xmm3", "xmm0", "xmm1");
+ ROUND("1", "xmm6", "xmm5", "xmm3", "xmm0", "xmm1", "xmm2");
+ ROUND("1", "xmm5", "xmm6", "xmm0", "xmm1", "xmm2", "xmm3");
+ ROUND("1", "xmm6", "xmm5", "xmm1", "xmm2", "xmm3", "xmm0");
+ ROUND("2", "xmm5", "xmm6", "xmm2", "xmm3", "xmm0", "xmm1");
+ ROUND("2", "xmm6", "xmm5", "xmm3", "xmm0", "xmm1", "xmm2");
+ ROUND("2", "xmm5", "xmm6", "xmm0", "xmm1", "xmm2", "xmm3");
+ ROUND("2", "xmm6", "xmm5", "xmm1", "xmm2", "xmm3", "xmm0");
+ ROUND("2", "xmm5", "xmm6", "xmm2", "xmm3", "xmm0", "xmm1");
+ ROUND("3", "xmm6", "xmm5", "xmm3", "xmm0", "xmm1", "xmm2");
+ ROUND("3", "xmm5", "xmm6", "xmm0", "xmm1", "xmm2", "xmm3");
+
+ if (--nblks == 0)
+ break;
+
+ /* Round 68..71 */
+ asm volatile ("movdqu 0(%[data]), %%xmm0\n\t"
+ "sha1nexte %%xmm1, %%xmm6\n\t"
+ "movdqa %%xmm4, %%xmm5\n\t"
+ "sha1msg2 %%xmm1, %%xmm2\n\t"
+ "sha1rnds4 $3, %%xmm6, %%xmm4\n\t"
+ "pxor %%xmm1, %%xmm3\n\t"
+ "pshufb %%xmm7, %%xmm0\n\t"
+ :
+ : [data] "r" (data)
+ : "memory" );
+
+ /* Round 72..75 */
+ asm volatile ("movdqu 16(%[data]), %%xmm1\n\t"
+ "sha1nexte %%xmm2, %%xmm5\n\t"
+ "movdqa %%xmm4, %%xmm6\n\t"
+ "sha1msg2 %%xmm2, %%xmm3\n\t"
+ "sha1rnds4 $3, %%xmm5, %%xmm4\n\t"
+ "pshufb %%xmm7, %%xmm1\n\t"
+ :
+ : [data] "r" (data)
+ : "memory" );
+
+ /* Round 76..79 */
+ asm volatile ("movdqu 32(%[data]), %%xmm2\n\t"
+ "sha1nexte %%xmm3, %%xmm6\n\t"
+ "movdqa %%xmm4, %%xmm5\n\t"
+ "sha1rnds4 $3, %%xmm6, %%xmm4\n\t"
+ "pshufb %%xmm7, %%xmm2\n\t"
+ :
+ : [data] "r" (data)
+ : "memory" );
+
+ /* Merge states, store current. */
+ asm volatile ("movdqu 48(%[data]), %%xmm3\n\t"
+ "sha1nexte (%[e_save]), %%xmm5\n\t"
+ "paddd (%[abcd_save]), %%xmm4\n\t"
+ "pshufb %%xmm7, %%xmm3\n\t"
+ "movdqa %%xmm5, (%[e_save])\n\t"
+ "movdqa %%xmm4, (%[abcd_save])\n\t"
+ :
+ : [abcd_save] "r" (abcd_save), [e_save] "r" (e_save),
+ [data] "r" (data)
+ : "memory" );
+
+ data += 64;
+ }
+
+ /* Round 68..71 */
+ asm volatile ("sha1nexte %%xmm1, %%xmm6\n\t"
+ "movdqa %%xmm4, %%xmm5\n\t"
+ "sha1msg2 %%xmm1, %%xmm2\n\t"
+ "sha1rnds4 $3, %%xmm6, %%xmm4\n\t"
+ "pxor %%xmm1, %%xmm3\n\t"
+ ::: "memory" );
+
+ /* Round 72..75 */
+ asm volatile ("sha1nexte %%xmm2, %%xmm5\n\t"
+ "movdqa %%xmm4, %%xmm6\n\t"
+ "sha1msg2 %%xmm2, %%xmm3\n\t"
+ "sha1rnds4 $3, %%xmm5, %%xmm4\n\t"
+ ::: "memory" );
+
+ /* Round 76..79 */
+ asm volatile ("sha1nexte %%xmm3, %%xmm6\n\t"
+ "movdqa %%xmm4, %%xmm5\n\t"
+ "sha1rnds4 $3, %%xmm6, %%xmm4\n\t"
+ ::: "memory" );
+
+ /* Merge states. */
+ asm volatile ("sha1nexte (%[e_save]), %%xmm5\n\t"
+ "paddd (%[abcd_save]), %%xmm4\n\t"
+ :
+ : [abcd_save] "r" (abcd_save), [e_save] "r" (e_save)
+ : "memory" );
+
+ /* Save state */
+ asm volatile ("pshufd $0x1b, %%xmm4, %%xmm4\n\t"
+ "psrldq $12, %%xmm5\n\t"
+ "movdqu %%xmm4, (%[state])\n\t"
+ "movd %%xmm5, 16(%[state])\n\t"
+ :
+ : [state] "r" (state)
+ : "memory" );
+
+ shaext_cleanup (abcd_save, e_save);
+ return 0;
+}
+
+#if __clang__
+# pragma clang attribute pop
+#endif
+
+#endif /* HAVE_GCC_INLINE_ASM_SHA_EXT */
diff --git a/comm/third_party/libgcrypt/cipher/sha1-ssse3-amd64.S b/comm/third_party/libgcrypt/cipher/sha1-ssse3-amd64.S
new file mode 100644
index 0000000000..db62928ad3
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1-ssse3-amd64.S
@@ -0,0 +1,437 @@
+/* sha1-ssse3-amd64.S - Intel SSSE3 accelerated SHA-1 transform function
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on sha1.c:
+ * Copyright (C) 1998, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Intel SSSE3 accelerated SHA-1 implementation based on white paper:
+ * "Improving the Performance of the Secure Hash Algorithm (SHA-1)"
+ * http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1
+ */
+
+#ifdef __x86_64__
+#include <config.h>
+
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA1)
+
+#include "asm-common-amd64.h"
+
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+
+
+/* Constants */
+
+.text
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xCA62C1D6
+.align 16
+.LK_XMM:
+.LK1: .long K1, K1, K1, K1
+.LK2: .long K2, K2, K2, K2
+.LK3: .long K3, K3, K3, K3
+.LK4: .long K4, K4, K4, K4
+
+.Lbswap_shufb_ctl:
+ .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
+
+
+/* Register macros */
+
+#define RSTATE %r8
+#define RDATA %r9
+#define ROLDSTACK %r10
+#define RNBLKS %r11
+
+#define a %eax
+#define b %ebx
+#define c %ecx
+#define d %edx
+#define e %edi
+
+#define RT0 %esi
+#define RT1 %ebp
+
+#define Wtmp0 %xmm0
+#define Wtmp1 %xmm1
+
+#define W0 %xmm2
+#define W1 %xmm3
+#define W2 %xmm4
+#define W3 %xmm5
+#define W4 %xmm6
+#define W5 %xmm7
+#define W6 %xmm8
+#define W7 %xmm9
+
+#define BSWAP_REG %xmm10
+
+
+/* Round function macros. */
+
+#define WK(i) (((i) & 15) * 4)(%rsp)
+
+#define R_F1(a,b,c,d,e,i) \
+ movl c, RT0; \
+ addl WK(i), e; \
+ xorl d, RT0; \
+ movl a, RT1; \
+ andl b, RT0; \
+ roll $30, b; \
+ xorl d, RT0; \
+ leal (RT0,e), e; \
+ roll $5, RT1; \
+ addl RT1, e;
+
+#define R_F2(a,b,c,d,e,i) \
+ movl c, RT0; \
+ addl WK(i), e; \
+ xorl b, RT0; \
+ roll $30, b; \
+ xorl d, RT0; \
+ movl a, RT1; \
+ leal (RT0,e), e; \
+ roll $5, RT1; \
+ addl RT1, e;
+
+#define R_F3(a,b,c,d,e,i) \
+ movl c, RT0; \
+ movl b, RT1; \
+ xorl b, RT0; \
+ andl c, RT1; \
+ andl d, RT0; \
+ addl RT1, e; \
+ addl WK(i), e; \
+ roll $30, b; \
+ movl a, RT1; \
+ leal (RT0,e), e; \
+ roll $5, RT1; \
+ addl RT1, e;
+
+#define R_F4(a,b,c,d,e,i) R_F2(a,b,c,d,e,i)
+
+#define R(a,b,c,d,e,f,i) \
+ R_##f(a,b,c,d,e,i)
+
+
+/* Input expansion macros. */
+
+#define W_PRECALC_00_15_0(i, W, tmp0) \
+ movdqu (4*(i))(RDATA), tmp0;
+
+#define W_PRECALC_00_15_1(i, W, tmp0) \
+ pshufb BSWAP_REG, tmp0; \
+ movdqa tmp0, W;
+
+#define W_PRECALC_00_15_2(i, W, tmp0) \
+ paddd (.LK_XMM + ((i)/20)*16) rRIP, tmp0;
+
+#define W_PRECALC_00_15_3(i, W, tmp0) \
+ movdqa tmp0, WK(i&~3);
+
+#define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ movdqa W_m12, W; \
+ palignr $8, W_m16, W; \
+ movdqa W_m04, tmp0; \
+ psrldq $4, tmp0; \
+ pxor W_m08, W;
+
+#define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ pxor W_m16, tmp0; \
+ pxor tmp0, W; \
+ movdqa W, tmp1; \
+ movdqa W, tmp0; \
+ pslldq $12, tmp1;
+
+#define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ psrld $31, W; \
+ pslld $1, tmp0; \
+ por W, tmp0; \
+ movdqa tmp1, W; \
+ psrld $30, tmp1; \
+ pslld $2, W;
+
+#define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+ pxor W, tmp0; \
+ pxor tmp1, tmp0; \
+ movdqa tmp0, W; \
+ paddd (.LK_XMM + ((i)/20)*16) rRIP, tmp0; \
+ movdqa tmp0, WK((i)&~3);
+
+#define W_PRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ movdqa W_m04, tmp0; \
+ pxor W_m28, W; \
+ palignr $8, W_m08, tmp0;
+
+#define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ pxor W_m16, W; \
+ pxor tmp0, W; \
+ movdqa W, tmp0;
+
+#define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ psrld $30, W; \
+ pslld $2, tmp0; \
+ por W, tmp0;
+
+#define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+ movdqa tmp0, W; \
+ paddd (.LK_XMM + ((i)/20)*16) rRIP, tmp0; \
+ movdqa tmp0, WK((i)&~3);
+
+#define CLEAR_REG(reg) pxor reg, reg;
+
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_amd64_ssse3 (void *ctx, const unsigned char *data,
+ * size_t nblks)
+ */
+.globl _gcry_sha1_transform_amd64_ssse3
+ELF(.type _gcry_sha1_transform_amd64_ssse3,@function)
+.align 16
+_gcry_sha1_transform_amd64_ssse3:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: data (64*nblks bytes)
+ * %rdx: nblks
+ */
+ CFI_STARTPROC();
+
+ xorl %eax, %eax;
+ cmpq $0, %rdx;
+ jz .Lret;
+
+ movq %rdx, RNBLKS;
+ movq %rdi, RSTATE;
+ movq %rsi, RDATA;
+ pushq %rbx;
+ CFI_PUSH(%rbx);
+ pushq %rbp;
+ CFI_PUSH(%rbp);
+
+ movq %rsp, ROLDSTACK;
+ CFI_DEF_CFA_REGISTER(ROLDSTACK);
+
+ subq $(16*4), %rsp;
+ andq $(~31), %rsp;
+
+ /* Get the values of the chaining variables. */
+ movl state_h0(RSTATE), a;
+ movl state_h1(RSTATE), b;
+ movl state_h2(RSTATE), c;
+ movl state_h3(RSTATE), d;
+ movl state_h4(RSTATE), e;
+
+ movdqa .Lbswap_shufb_ctl rRIP, BSWAP_REG;
+
+ /* Precalc 0-15. */
+ W_PRECALC_00_15_0(0, W0, Wtmp0);
+ W_PRECALC_00_15_1(1, W0, Wtmp0);
+ W_PRECALC_00_15_2(2, W0, Wtmp0);
+ W_PRECALC_00_15_3(3, W0, Wtmp0);
+ W_PRECALC_00_15_0(4, W7, Wtmp0);
+ W_PRECALC_00_15_1(5, W7, Wtmp0);
+ W_PRECALC_00_15_2(6, W7, Wtmp0);
+ W_PRECALC_00_15_3(7, W7, Wtmp0);
+ W_PRECALC_00_15_0(8, W6, Wtmp0);
+ W_PRECALC_00_15_1(9, W6, Wtmp0);
+ W_PRECALC_00_15_2(10, W6, Wtmp0);
+ W_PRECALC_00_15_3(11, W6, Wtmp0);
+ W_PRECALC_00_15_0(12, W5, Wtmp0);
+ W_PRECALC_00_15_1(13, W5, Wtmp0);
+ W_PRECALC_00_15_2(14, W5, Wtmp0);
+ W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+.align 8
+.Loop:
+ addq $64, RDATA;
+
+ /* Transform 0-15 + Precalc 16-31. */
+ R( a, b, c, d, e, F1, 0 ); W_PRECALC_16_31_0(16, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 1 ); W_PRECALC_16_31_1(17, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F1, 2 ); W_PRECALC_16_31_2(18, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F1, 3 ); W_PRECALC_16_31_3(19, W4, W5, W6, W7, W0, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F1, 4 ); W_PRECALC_16_31_0(20, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 5 ); W_PRECALC_16_31_1(21, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 6 ); W_PRECALC_16_31_2(22, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F1, 7 ); W_PRECALC_16_31_3(23, W3, W4, W5, W6, W7, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F1, 8 ); W_PRECALC_16_31_0(24, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F1, 9 ); W_PRECALC_16_31_1(25, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 10 ); W_PRECALC_16_31_2(26, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( e, a, b, c, d, F1, 11 ); W_PRECALC_16_31_3(27, W2, W3, W4, W5, W6, Wtmp0, Wtmp1);
+ R( d, e, a, b, c, F1, 12 ); W_PRECALC_16_31_0(28, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( c, d, e, a, b, F1, 13 ); W_PRECALC_16_31_1(29, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( b, c, d, e, a, F1, 14 ); W_PRECALC_16_31_2(30, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+ R( a, b, c, d, e, F1, 15 ); W_PRECALC_16_31_3(31, W1, W2, W3, W4, W5, Wtmp0, Wtmp1);
+
+ /* Transform 16-63 + Precalc 32-79. */
+ R( e, a, b, c, d, F1, 16 ); W_PRECALC_32_79_0(32, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( d, e, a, b, c, F1, 17 ); W_PRECALC_32_79_1(33, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( c, d, e, a, b, F1, 18 ); W_PRECALC_32_79_2(34, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( b, c, d, e, a, F1, 19 ); W_PRECALC_32_79_3(35, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( a, b, c, d, e, F2, 20 ); W_PRECALC_32_79_0(36, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( e, a, b, c, d, F2, 21 ); W_PRECALC_32_79_1(37, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( d, e, a, b, c, F2, 22 ); W_PRECALC_32_79_2(38, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( c, d, e, a, b, F2, 23 ); W_PRECALC_32_79_3(39, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( b, c, d, e, a, F2, 24 ); W_PRECALC_32_79_0(40, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( a, b, c, d, e, F2, 25 ); W_PRECALC_32_79_1(41, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( e, a, b, c, d, F2, 26 ); W_PRECALC_32_79_2(42, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( d, e, a, b, c, F2, 27 ); W_PRECALC_32_79_3(43, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( c, d, e, a, b, F2, 28 ); W_PRECALC_32_79_0(44, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( b, c, d, e, a, F2, 29 ); W_PRECALC_32_79_1(45, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( a, b, c, d, e, F2, 30 ); W_PRECALC_32_79_2(46, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( e, a, b, c, d, F2, 31 ); W_PRECALC_32_79_3(47, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( d, e, a, b, c, F2, 32 ); W_PRECALC_32_79_0(48, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( c, d, e, a, b, F2, 33 ); W_PRECALC_32_79_1(49, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( b, c, d, e, a, F2, 34 ); W_PRECALC_32_79_2(50, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( a, b, c, d, e, F2, 35 ); W_PRECALC_32_79_3(51, W4, W5, W6, W7, W0, W1, W2, W3, Wtmp0);
+ R( e, a, b, c, d, F2, 36 ); W_PRECALC_32_79_0(52, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( d, e, a, b, c, F2, 37 ); W_PRECALC_32_79_1(53, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( c, d, e, a, b, F2, 38 ); W_PRECALC_32_79_2(54, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( b, c, d, e, a, F2, 39 ); W_PRECALC_32_79_3(55, W3, W4, W5, W6, W7, W0, W1, W2, Wtmp0);
+ R( a, b, c, d, e, F3, 40 ); W_PRECALC_32_79_0(56, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( e, a, b, c, d, F3, 41 ); W_PRECALC_32_79_1(57, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( d, e, a, b, c, F3, 42 ); W_PRECALC_32_79_2(58, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( c, d, e, a, b, F3, 43 ); W_PRECALC_32_79_3(59, W2, W3, W4, W5, W6, W7, W0, W1, Wtmp0);
+ R( b, c, d, e, a, F3, 44 ); W_PRECALC_32_79_0(60, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( a, b, c, d, e, F3, 45 ); W_PRECALC_32_79_1(61, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( e, a, b, c, d, F3, 46 ); W_PRECALC_32_79_2(62, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( d, e, a, b, c, F3, 47 ); W_PRECALC_32_79_3(63, W1, W2, W3, W4, W5, W6, W7, W0, Wtmp0);
+ R( c, d, e, a, b, F3, 48 ); W_PRECALC_32_79_0(64, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( b, c, d, e, a, F3, 49 ); W_PRECALC_32_79_1(65, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( a, b, c, d, e, F3, 50 ); W_PRECALC_32_79_2(66, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( e, a, b, c, d, F3, 51 ); W_PRECALC_32_79_3(67, W0, W1, W2, W3, W4, W5, W6, W7, Wtmp0);
+ R( d, e, a, b, c, F3, 52 ); W_PRECALC_32_79_0(68, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( c, d, e, a, b, F3, 53 ); W_PRECALC_32_79_1(69, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( b, c, d, e, a, F3, 54 ); W_PRECALC_32_79_2(70, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( a, b, c, d, e, F3, 55 ); W_PRECALC_32_79_3(71, W7, W0, W1, W2, W3, W4, W5, W6, Wtmp0);
+ R( e, a, b, c, d, F3, 56 ); W_PRECALC_32_79_0(72, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( d, e, a, b, c, F3, 57 ); W_PRECALC_32_79_1(73, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( c, d, e, a, b, F3, 58 ); W_PRECALC_32_79_2(74, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( b, c, d, e, a, F3, 59 ); W_PRECALC_32_79_3(75, W6, W7, W0, W1, W2, W3, W4, W5, Wtmp0);
+ R( a, b, c, d, e, F4, 60 ); W_PRECALC_32_79_0(76, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( e, a, b, c, d, F4, 61 ); W_PRECALC_32_79_1(77, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( d, e, a, b, c, F4, 62 ); W_PRECALC_32_79_2(78, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+ R( c, d, e, a, b, F4, 63 ); W_PRECALC_32_79_3(79, W5, W6, W7, W0, W1, W2, W3, W4, Wtmp0);
+
+ decq RNBLKS;
+ jz .Lend;
+
+ /* Transform 64-79 + Precalc 0-15 of next block. */
+ R( b, c, d, e, a, F4, 64 ); W_PRECALC_00_15_0(0, W0, Wtmp0);
+ R( a, b, c, d, e, F4, 65 ); W_PRECALC_00_15_1(1, W0, Wtmp0);
+ R( e, a, b, c, d, F4, 66 ); W_PRECALC_00_15_2(2, W0, Wtmp0);
+ R( d, e, a, b, c, F4, 67 ); W_PRECALC_00_15_3(3, W0, Wtmp0);
+ R( c, d, e, a, b, F4, 68 ); W_PRECALC_00_15_0(4, W7, Wtmp0);
+ R( b, c, d, e, a, F4, 69 ); W_PRECALC_00_15_1(5, W7, Wtmp0);
+ R( a, b, c, d, e, F4, 70 ); W_PRECALC_00_15_2(6, W7, Wtmp0);
+ R( e, a, b, c, d, F4, 71 ); W_PRECALC_00_15_3(7, W7, Wtmp0);
+ R( d, e, a, b, c, F4, 72 ); W_PRECALC_00_15_0(8, W6, Wtmp0);
+ R( c, d, e, a, b, F4, 73 ); W_PRECALC_00_15_1(9, W6, Wtmp0);
+ R( b, c, d, e, a, F4, 74 ); W_PRECALC_00_15_2(10, W6, Wtmp0);
+ R( a, b, c, d, e, F4, 75 ); W_PRECALC_00_15_3(11, W6, Wtmp0);
+ R( e, a, b, c, d, F4, 76 ); W_PRECALC_00_15_0(12, W5, Wtmp0);
+ R( d, e, a, b, c, F4, 77 ); W_PRECALC_00_15_1(13, W5, Wtmp0);
+ R( c, d, e, a, b, F4, 78 );
+ addl state_h0(RSTATE), a; W_PRECALC_00_15_2(14, W5, Wtmp0);
+ R( b, c, d, e, a, F4, 79 ); W_PRECALC_00_15_3(15, W5, Wtmp0);
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ jmp .Loop;
+
+.align 16
+.Lend:
+ /* Transform 64-79 + Clear XMM registers + Burn stack. */
+ R( b, c, d, e, a, F4, 64 ); CLEAR_REG(BSWAP_REG);
+ R( a, b, c, d, e, F4, 65 ); CLEAR_REG(Wtmp0);
+ R( e, a, b, c, d, F4, 66 ); CLEAR_REG(Wtmp1);
+ R( d, e, a, b, c, F4, 67 ); CLEAR_REG(W0);
+ R( c, d, e, a, b, F4, 68 ); CLEAR_REG(W1);
+ R( b, c, d, e, a, F4, 69 ); CLEAR_REG(W2);
+ R( a, b, c, d, e, F4, 70 ); CLEAR_REG(W3);
+ R( e, a, b, c, d, F4, 71 ); CLEAR_REG(W4);
+ R( d, e, a, b, c, F4, 72 ); CLEAR_REG(W5);
+ R( c, d, e, a, b, F4, 73 ); CLEAR_REG(W6);
+ R( b, c, d, e, a, F4, 74 ); CLEAR_REG(W7);
+ R( a, b, c, d, e, F4, 75 );
+ R( e, a, b, c, d, F4, 76 ); movdqa Wtmp0, (0*16)(%rsp);
+ R( d, e, a, b, c, F4, 77 ); movdqa Wtmp0, (1*16)(%rsp);
+ R( c, d, e, a, b, F4, 78 ); movdqa Wtmp0, (2*16)(%rsp);
+ addl state_h0(RSTATE), a;
+ R( b, c, d, e, a, F4, 79 );
+
+ /* 16*4/16-1 = 3 */
+ movdqa Wtmp0, (3*16)(%rsp);
+
+ /* Update the chaining variables. */
+ addl state_h3(RSTATE), d;
+ addl state_h2(RSTATE), c;
+ addl state_h1(RSTATE), b;
+ addl state_h4(RSTATE), e;
+
+ movl d, state_h3(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl a, state_h0(RSTATE);
+ movl e, state_h4(RSTATE);
+
+ movq ROLDSTACK, %rsp;
+ CFI_REGISTER(ROLDSTACK, %rsp);
+ CFI_DEF_CFA_REGISTER(%rsp);
+
+ popq %rbp;
+ CFI_POP(%rbp);
+ popq %rbx;
+ CFI_POP(%rbx);
+
+ /* stack already burned */
+ xorl %eax, %eax;
+
+.Lret:
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sha1_transform_amd64_ssse3,
+ .-_gcry_sha1_transform_amd64_ssse3;)
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha1.c b/comm/third_party/libgcrypt/cipher/sha1.c
new file mode 100644
index 0000000000..35f7376c19
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1.c
@@ -0,0 +1,765 @@
+/* sha1.c - SHA1 hash function
+ * Copyright (C) 1998, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Test vectors:
+ *
+ * "abc"
+ * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D
+ *
+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "sha1.h"
+
+
+/* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
+#undef USE_SSSE3
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_SSSE3 1
+#endif
+
+/* USE_AVX indicates whether to compile with Intel AVX code. */
+#undef USE_AVX
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX 1
+#endif
+
+/* USE_BMI2 indicates whether to compile with Intel AVX/BMI2 code. */
+#undef USE_BMI2
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+ defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_BMI2 1
+#endif
+
+/* USE_AVX2 indicates whether to compile with Intel AVX2/BMI2 code. */
+#undef USE_AVX2
+#if defined(USE_BMI2) && defined(HAVE_GCC_INLINE_ASM_AVX2)
+# define USE_AVX2 1
+#endif
+
+/* USE_SHAEXT indicates whether to compile with Intel SHA Extension code. */
+#undef USE_SHAEXT
+#if defined(HAVE_GCC_INLINE_ASM_SHAEXT) && \
+ defined(HAVE_GCC_INLINE_ASM_SSE41) && \
+ defined(ENABLE_SHAEXT_SUPPORT)
+# define USE_SHAEXT 1
+#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
+
+/* USE_ARM_CE indicates whether to enable ARMv8 Crypto Extension assembly
+ * code. */
+#undef USE_ARM_CE
+#ifdef ENABLE_ARM_CRYPTO_SUPPORT
+# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
+ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
+ && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO)
+# define USE_ARM_CE 1
+# elif defined(__AARCH64EL__) \
+ && defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) \
+ && defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+# define USE_ARM_CE 1
+# endif
+#endif
+
+
+/* A macro to test whether P is properly aligned for an u32 type.
+ Note that config.h provides a suitable replacement for uintptr_t if
+ it does not exist in stdint.h. */
+/* #if __GNUC__ >= 2 */
+/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % __alignof__ (u32))) */
+/* #else */
+/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */
+/* #endif */
+
+
+
+/* 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_SSSE3) || defined(USE_AVX) || defined(USE_BMI2) || \
+ defined(USE_SHAEXT)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# define ASM_EXTRA_STACK (10 * 16 + sizeof(void *) * 4)
+# else
+# define ASM_FUNC_ABI
+# define ASM_EXTRA_STACK 0
+# endif
+#endif
+
+
+#ifdef USE_SSSE3
+unsigned int
+_gcry_sha1_transform_amd64_ssse3 (void *state, const unsigned char *data,
+ size_t nblks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha1_transform_amd64_ssse3 (void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+ return _gcry_sha1_transform_amd64_ssse3 (&hd->h0, data, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif
+
+#ifdef USE_AVX
+unsigned int
+_gcry_sha1_transform_amd64_avx (void *state, const unsigned char *data,
+ size_t nblks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha1_transform_amd64_avx (void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+ return _gcry_sha1_transform_amd64_avx (&hd->h0, data, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif
+
+#ifdef USE_BMI2
+unsigned int
+_gcry_sha1_transform_amd64_avx_bmi2 (void *state, const unsigned char *data,
+ size_t nblks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha1_transform_amd64_avx_bmi2 (void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+ return _gcry_sha1_transform_amd64_avx_bmi2 (&hd->h0, data, nblks)
+ + ASM_EXTRA_STACK;
+}
+
+#ifdef USE_AVX2
+unsigned int
+_gcry_sha1_transform_amd64_avx2_bmi2 (void *state, const unsigned char *data,
+ size_t nblks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha1_transform_amd64_avx2_bmi2 (void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+
+ /* AVX2/BMI2 function only handles pair of blocks so nblks needs to be
+ * multiple of 2 and function does not handle zero nblks. Use AVX/BMI2
+ * code to handle these cases. */
+
+ if (nblks <= 1)
+ return do_sha1_transform_amd64_avx_bmi2 (ctx, data, nblks);
+
+ if (nblks & 1)
+ {
+ (void)_gcry_sha1_transform_amd64_avx_bmi2 (&hd->h0, data, 1);
+ nblks--;
+ data += 64;
+ }
+
+ return _gcry_sha1_transform_amd64_avx2_bmi2 (&hd->h0, data, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif /* USE_AVX2 */
+#endif /* USE_BMI2 */
+
+#ifdef USE_SHAEXT
+/* Does not need ASM_FUNC_ABI */
+unsigned int
+_gcry_sha1_transform_intel_shaext (void *state, const unsigned char *data,
+ size_t nblks);
+
+static unsigned int
+do_sha1_transform_intel_shaext (void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+ return _gcry_sha1_transform_intel_shaext (&hd->h0, data, nblks);
+}
+#endif
+
+#ifdef USE_NEON
+unsigned int
+_gcry_sha1_transform_armv7_neon (void *state, const unsigned char *data,
+ size_t nblks);
+
+static unsigned int
+do_sha1_transform_armv7_neon (void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+ return _gcry_sha1_transform_armv7_neon (&hd->h0, data, nblks);
+}
+#endif
+
+#ifdef USE_ARM_CE
+unsigned int
+_gcry_sha1_transform_armv8_ce (void *state, const unsigned char *data,
+ size_t nblks);
+
+static unsigned int
+do_sha1_transform_armv8_ce (void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+ return _gcry_sha1_transform_armv8_ce (&hd->h0, data, nblks);
+}
+#endif
+
+#ifdef SHA1_USE_S390X_CRYPTO
+#include "asm-inline-s390x.h"
+
+static unsigned int
+do_sha1_transform_s390x (void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+
+ kimd_execute (KMID_FUNCTION_SHA1, &hd->h0, data, nblks * 64);
+ return 0;
+}
+
+static unsigned int
+do_sha1_final_s390x (void *ctx, const unsigned char *data, size_t datalen,
+ u32 len_msb, u32 len_lsb)
+{
+ SHA1_CONTEXT *hd = ctx;
+
+ /* Make sure that 'final_len' is positioned at correct offset relative
+ * to 'h0'. This is because we are passing 'h0' pointer as start of
+ * parameter block to 'klmd' instruction. */
+
+ gcry_assert (offsetof (SHA1_CONTEXT, final_len_msb)
+ - offsetof (SHA1_CONTEXT, h0) == 5 * sizeof(u32));
+ gcry_assert (offsetof (SHA1_CONTEXT, final_len_lsb)
+ - offsetof (SHA1_CONTEXT, final_len_msb) == 1 * sizeof(u32));
+
+ hd->final_len_msb = len_msb;
+ hd->final_len_lsb = len_lsb;
+
+ klmd_execute (KMID_FUNCTION_SHA1, &hd->h0, data, datalen);
+ return 0;
+}
+#endif
+
+
+static unsigned int
+do_transform_generic (void *c, const unsigned char *data, size_t nblks);
+
+
+static void
+sha1_init (void *context, unsigned int flags)
+{
+ SHA1_CONTEXT *hd = context;
+ unsigned int features = _gcry_get_hw_features ();
+
+ (void)flags;
+
+ hd->h0 = 0x67452301;
+ hd->h1 = 0xefcdab89;
+ hd->h2 = 0x98badcfe;
+ hd->h3 = 0x10325476;
+ hd->h4 = 0xc3d2e1f0;
+
+ hd->bctx.nblocks = 0;
+ hd->bctx.nblocks_high = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize_shift = _gcry_ctz(64);
+
+ /* Order of feature checks is important here; last match will be
+ * selected. Keep slower implementations at the top and faster at
+ * the bottom. */
+ hd->bctx.bwrite = do_transform_generic;
+#ifdef USE_SSSE3
+ if ((features & HWF_INTEL_SSSE3) != 0)
+ hd->bctx.bwrite = do_sha1_transform_amd64_ssse3;
+#endif
+#ifdef USE_AVX
+ /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs.
+ * Therefore use this implementation on Intel CPUs only. */
+ if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD))
+ hd->bctx.bwrite = do_sha1_transform_amd64_avx;
+#endif
+#ifdef USE_BMI2
+ if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_BMI2))
+ hd->bctx.bwrite = do_sha1_transform_amd64_avx_bmi2;
+#endif
+#ifdef USE_AVX2
+ if ((features & HWF_INTEL_AVX2) && (features & HWF_INTEL_AVX) &&
+ (features & HWF_INTEL_BMI2))
+ hd->bctx.bwrite = do_sha1_transform_amd64_avx2_bmi2;
+#endif
+#ifdef USE_SHAEXT
+ if ((features & HWF_INTEL_SHAEXT) && (features & HWF_INTEL_SSE4_1))
+ hd->bctx.bwrite = do_sha1_transform_intel_shaext;
+#endif
+#ifdef USE_NEON
+ if ((features & HWF_ARM_NEON) != 0)
+ hd->bctx.bwrite = do_sha1_transform_armv7_neon;
+#endif
+#ifdef USE_ARM_CE
+ if ((features & HWF_ARM_SHA1) != 0)
+ hd->bctx.bwrite = do_sha1_transform_armv8_ce;
+#endif
+#ifdef SHA1_USE_S390X_CRYPTO
+ hd->use_s390x_crypto = 0;
+ if ((features & HWF_S390X_MSA) != 0)
+ {
+ if ((kimd_query () & km_function_to_mask (KMID_FUNCTION_SHA1)) &&
+ (klmd_query () & km_function_to_mask (KMID_FUNCTION_SHA1)))
+ {
+ hd->bctx.bwrite = do_sha1_transform_s390x;
+ hd->use_s390x_crypto = 1;
+ }
+ }
+#endif
+
+ (void)features;
+}
+
+/*
+ * Initialize the context HD. This is used to prepare the use of
+ * _gcry_sha1_mixblock. WARNING: This is a special purpose function
+ * for exclusive use by random-csprng.c.
+ */
+void
+_gcry_sha1_mixblock_init (SHA1_CONTEXT *hd)
+{
+ sha1_init (hd, 0);
+}
+
+
+/* Round function macros. */
+#define K1 0x5A827999L
+#define K2 0x6ED9EBA1L
+#define K3 0x8F1BBCDCL
+#define K4 0xCA62C1D6L
+#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
+#define F2(x,y,z) ( x ^ y ^ z )
+#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
+#define F4(x,y,z) ( x ^ y ^ z )
+#define M(i) ( tm = x[ i &0x0f] \
+ ^ x[(i-14)&0x0f] \
+ ^ x[(i-8) &0x0f] \
+ ^ x[(i-3) &0x0f], \
+ (x[i&0x0f] = rol(tm, 1)))
+#define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \
+ + f( b, c, d ) \
+ + k \
+ + m; \
+ b = rol( b, 30 ); \
+ } while(0)
+
+/*
+ * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
+ */
+static unsigned int
+do_transform_generic (void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+
+ do
+ {
+ const u32 *idata = (const void *)data;
+ u32 a, b, c, d, e; /* Local copies of the chaining variables. */
+ u32 tm; /* Helper. */
+ u32 x[16]; /* The array we work on. */
+
+#define I(i) (x[i] = buf_get_be32(idata + i))
+
+ /* Get the values of the chaining variables. */
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+
+ /* Transform. */
+ R( a, b, c, d, e, F1, K1, I( 0) );
+ R( e, a, b, c, d, F1, K1, I( 1) );
+ R( d, e, a, b, c, F1, K1, I( 2) );
+ R( c, d, e, a, b, F1, K1, I( 3) );
+ R( b, c, d, e, a, F1, K1, I( 4) );
+ R( a, b, c, d, e, F1, K1, I( 5) );
+ R( e, a, b, c, d, F1, K1, I( 6) );
+ R( d, e, a, b, c, F1, K1, I( 7) );
+ R( c, d, e, a, b, F1, K1, I( 8) );
+ R( b, c, d, e, a, F1, K1, I( 9) );
+ R( a, b, c, d, e, F1, K1, I(10) );
+ R( e, a, b, c, d, F1, K1, I(11) );
+ R( d, e, a, b, c, F1, K1, I(12) );
+ R( c, d, e, a, b, F1, K1, I(13) );
+ R( b, c, d, e, a, F1, K1, I(14) );
+ R( a, b, c, d, e, F1, K1, I(15) );
+ R( e, a, b, c, d, F1, K1, M(16) );
+ R( d, e, a, b, c, F1, K1, M(17) );
+ R( c, d, e, a, b, F1, K1, M(18) );
+ R( b, c, d, e, a, F1, K1, M(19) );
+ R( a, b, c, d, e, F2, K2, M(20) );
+ R( e, a, b, c, d, F2, K2, M(21) );
+ R( d, e, a, b, c, F2, K2, M(22) );
+ R( c, d, e, a, b, F2, K2, M(23) );
+ R( b, c, d, e, a, F2, K2, M(24) );
+ R( a, b, c, d, e, F2, K2, M(25) );
+ R( e, a, b, c, d, F2, K2, M(26) );
+ R( d, e, a, b, c, F2, K2, M(27) );
+ R( c, d, e, a, b, F2, K2, M(28) );
+ R( b, c, d, e, a, F2, K2, M(29) );
+ R( a, b, c, d, e, F2, K2, M(30) );
+ R( e, a, b, c, d, F2, K2, M(31) );
+ R( d, e, a, b, c, F2, K2, M(32) );
+ R( c, d, e, a, b, F2, K2, M(33) );
+ R( b, c, d, e, a, F2, K2, M(34) );
+ R( a, b, c, d, e, F2, K2, M(35) );
+ R( e, a, b, c, d, F2, K2, M(36) );
+ R( d, e, a, b, c, F2, K2, M(37) );
+ R( c, d, e, a, b, F2, K2, M(38) );
+ R( b, c, d, e, a, F2, K2, M(39) );
+ R( a, b, c, d, e, F3, K3, M(40) );
+ R( e, a, b, c, d, F3, K3, M(41) );
+ R( d, e, a, b, c, F3, K3, M(42) );
+ R( c, d, e, a, b, F3, K3, M(43) );
+ R( b, c, d, e, a, F3, K3, M(44) );
+ R( a, b, c, d, e, F3, K3, M(45) );
+ R( e, a, b, c, d, F3, K3, M(46) );
+ R( d, e, a, b, c, F3, K3, M(47) );
+ R( c, d, e, a, b, F3, K3, M(48) );
+ R( b, c, d, e, a, F3, K3, M(49) );
+ R( a, b, c, d, e, F3, K3, M(50) );
+ R( e, a, b, c, d, F3, K3, M(51) );
+ R( d, e, a, b, c, F3, K3, M(52) );
+ R( c, d, e, a, b, F3, K3, M(53) );
+ R( b, c, d, e, a, F3, K3, M(54) );
+ R( a, b, c, d, e, F3, K3, M(55) );
+ R( e, a, b, c, d, F3, K3, M(56) );
+ R( d, e, a, b, c, F3, K3, M(57) );
+ R( c, d, e, a, b, F3, K3, M(58) );
+ R( b, c, d, e, a, F3, K3, M(59) );
+ R( a, b, c, d, e, F4, K4, M(60) );
+ R( e, a, b, c, d, F4, K4, M(61) );
+ R( d, e, a, b, c, F4, K4, M(62) );
+ R( c, d, e, a, b, F4, K4, M(63) );
+ R( b, c, d, e, a, F4, K4, M(64) );
+ R( a, b, c, d, e, F4, K4, M(65) );
+ R( e, a, b, c, d, F4, K4, M(66) );
+ R( d, e, a, b, c, F4, K4, M(67) );
+ R( c, d, e, a, b, F4, K4, M(68) );
+ R( b, c, d, e, a, F4, K4, M(69) );
+ R( a, b, c, d, e, F4, K4, M(70) );
+ R( e, a, b, c, d, F4, K4, M(71) );
+ R( d, e, a, b, c, F4, K4, M(72) );
+ R( c, d, e, a, b, F4, K4, M(73) );
+ R( b, c, d, e, a, F4, K4, M(74) );
+ R( a, b, c, d, e, F4, K4, M(75) );
+ R( e, a, b, c, d, F4, K4, M(76) );
+ R( d, e, a, b, c, F4, K4, M(77) );
+ R( c, d, e, a, b, F4, K4, M(78) );
+ R( b, c, d, e, a, F4, K4, M(79) );
+
+ /* Update the chaining variables. */
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+
+ data += 64;
+ }
+ while (--nblks);
+
+ return 88+4*sizeof(void*);
+}
+
+
+/*
+ * Apply the SHA-1 transform function on the buffer BLOCKOF64BYTE
+ * which must have a length 64 bytes. BLOCKOF64BYTE must be 32-bit
+ * aligned. Updates the 20 bytes in BLOCKOF64BYTE with its mixed
+ * content. Returns the number of bytes which should be burned on the
+ * stack. You need to use _gcry_sha1_mixblock_init to initialize the
+ * context.
+ * WARNING: This is a special purpose function for exclusive use by
+ * random-csprng.c.
+ */
+unsigned int
+_gcry_sha1_mixblock (SHA1_CONTEXT *hd, void *blockof64byte)
+{
+ u32 *p = blockof64byte;
+ unsigned int nburn;
+
+ nburn = (*hd->bctx.bwrite) (hd, blockof64byte, 1);
+ p[0] = hd->h0;
+ p[1] = hd->h1;
+ p[2] = hd->h2;
+ p[3] = hd->h3;
+ p[4] = hd->h4;
+
+ return nburn;
+}
+
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 20 bytes representing the digest.
+ */
+
+static void
+sha1_final(void *context)
+{
+ SHA1_CONTEXT *hd = context;
+ u32 t, th, msb, lsb;
+ unsigned char *p;
+ unsigned int burn;
+
+ t = hd->bctx.nblocks;
+ if (sizeof t == sizeof hd->bctx.nblocks)
+ th = hd->bctx.nblocks_high;
+ else
+ th = hd->bctx.nblocks >> 32;
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = (th << 6) | (t >> 26);
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->bctx.count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (0)
+ { }
+#ifdef SHA1_USE_S390X_CRYPTO
+ else if (hd->use_s390x_crypto)
+ {
+ burn = do_sha1_final_s390x (hd, hd->bctx.buf, hd->bctx.count, msb, lsb);
+ }
+#endif
+ else if (hd->bctx.count < 56) /* enough room */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ if (hd->bctx.count < 56)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+
+ /* append the 64 bit count */
+ buf_put_be32(hd->bctx.buf + 56, msb);
+ buf_put_be32(hd->bctx.buf + 60, lsb);
+ burn = (*hd->bctx.bwrite) ( hd, hd->bctx.buf, 1 );
+ }
+ else /* need one extra block */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ /* fill pad and next block with zeroes */
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+
+ /* append the 64 bit count */
+ buf_put_be32(hd->bctx.buf + 64 + 56, msb);
+ buf_put_be32(hd->bctx.buf + 64 + 60, lsb);
+ burn = (*hd->bctx.bwrite) ( hd, hd->bctx.buf, 2 );
+ }
+
+ p = hd->bctx.buf;
+#define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+#undef X
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (burn);
+}
+
+static unsigned char *
+sha1_read( void *context )
+{
+ SHA1_CONTEXT *hd = context;
+
+ return hd->bctx.buf;
+}
+
+/****************
+ * Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 20 bytes.
+ */
+void
+_gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SHA1_CONTEXT hd;
+
+ sha1_init (&hd, 0);
+ _gcry_md_block_write (&hd, buffer, length);
+ sha1_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 20);
+}
+
+
+/* Variant of the above shortcut function using a multiple buffers. */
+void
+_gcry_sha1_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+ SHA1_CONTEXT hd;
+
+ sha1_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ sha1_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 20);
+}
+
+
+
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha1 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA1, 0,
+ "abc", 3,
+ "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
+ "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA1, 0,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+ "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
+ "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA1, 1,
+ NULL, 0,
+ "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
+ "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", 20);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA1, 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_MD_SHA1:
+ ec = selftests_sha1 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+
+static unsigned char asn[15] = /* Object ID is 1.3.14.3.2.26 */
+ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+ 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
+
+static gcry_md_oid_spec_t oid_spec_sha1[] =
+ {
+ /* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 (sha1WithRSAEncryption) */
+ { "1.2.840.113549.1.1.5" },
+ /* iso.member-body.us.x9-57.x9cm.3 (dsaWithSha1)*/
+ { "1.2.840.10040.4.3" },
+ /* from NIST's OIW (sha1) */
+ { "1.3.14.3.2.26" },
+ /* from NIST OIW (sha-1WithRSAEncryption) */
+ { "1.3.14.3.2.29" },
+ /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
+ { "1.2.840.10045.4.1" },
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha1 =
+ {
+ GCRY_MD_SHA1, {0, 1},
+ "SHA1", asn, DIM (asn), oid_spec_sha1, 20,
+ sha1_init, _gcry_md_block_write, sha1_final, sha1_read, NULL,
+ _gcry_sha1_hash_buffer, _gcry_sha1_hash_buffers,
+ sizeof (SHA1_CONTEXT),
+ run_selftests
+ };
diff --git a/comm/third_party/libgcrypt/cipher/sha1.h b/comm/third_party/libgcrypt/cipher/sha1.h
new file mode 100644
index 0000000000..a359765847
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha1.h
@@ -0,0 +1,47 @@
+/* sha1.h - SHA-1 context definition
+ * Copyright (C) 1998, 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GCRY_SHA1_H
+#define GCRY_SHA1_H
+
+#include "hash-common.h"
+
+
+/* SHA1_USE_S390X_CRYPTO indicates whether to enable zSeries code. */
+#undef SHA1_USE_S390X_CRYPTO
+#if defined(HAVE_GCC_INLINE_ASM_S390X)
+# define SHA1_USE_S390X_CRYPTO 1
+#endif /* SHA1_USE_S390X_CRYPTO */
+
+
+/* We need this here for direct use by random-csprng.c. */
+typedef struct
+{
+ gcry_md_block_ctx_t bctx;
+ u32 h0,h1,h2,h3,h4;
+#ifdef SHA1_USE_S390X_CRYPTO
+ u32 final_len_msb, final_len_lsb; /* needs to be right after h4. */
+ int use_s390x_crypto;
+#endif
+} SHA1_CONTEXT;
+
+
+void _gcry_sha1_mixblock_init (SHA1_CONTEXT *hd);
+unsigned int _gcry_sha1_mixblock (SHA1_CONTEXT *hd, void *blockof64byte);
+
+#endif /*GCRY_SHA1_H*/
diff --git a/comm/third_party/libgcrypt/cipher/sha256-armv8-aarch32-ce.S b/comm/third_party/libgcrypt/cipher/sha256-armv8-aarch32-ce.S
new file mode 100644
index 0000000000..2b17ab1b17
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha256-armv8-aarch32-ce.S
@@ -0,0 +1,231 @@
+/* sha256-armv8-aarch32-ce.S - ARM/CE accelerated SHA-256 transform function
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO) && defined(USE_SHA256)
+
+.syntax unified
+.arch armv8-a
+.fpu crypto-neon-fp-armv8
+.arm
+
+.text
+
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
+
+/* Constants */
+
+.align 4
+gcry_sha256_aarch32_ce_K:
+.LK:
+ .long 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
+ .long 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
+ .long 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
+ .long 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
+ .long 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
+ .long 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
+ .long 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
+ .long 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
+ .long 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
+ .long 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
+ .long 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
+ .long 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
+ .long 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
+ .long 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
+ .long 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
+ .long 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+
+
+/* Register macros */
+
+#define qH0123 q0
+#define qH4567 q1
+
+#define qABCD0 q2
+#define qABCD1 q3
+#define qEFGH q4
+
+#define qT0 q5
+#define qT1 q6
+
+#define qW0 q8
+#define qW1 q9
+#define qW2 q10
+#define qW3 q11
+
+#define qK0 q12
+#define qK1 q13
+#define qK2 q14
+#define qK3 q15
+
+
+/* Round macros */
+
+#define _(...) /*_*/
+
+#define do_loadk(nk0, nk1) vld1.32 {nk0-nk1},[lr]!;
+#define do_add(a, b) vadd.u32 a, a, b;
+#define do_sha256su0(w0, w1) sha256su0.32 w0, w1;
+#define do_sha256su1(w0, w2, w3) sha256su1.32 w0, w2, w3;
+
+#define do_rounds(k, nk0, nk1, w0, w1, w2, w3, loadk_fn, add_fn, su0_fn, su1_fn) \
+ loadk_fn( nk0, nk1 ); \
+ su0_fn( w0, w1 ); \
+ vmov qABCD1, qABCD0; \
+ sha256h.32 qABCD0, qEFGH, k; \
+ sha256h2.32 qEFGH, qABCD1, k; \
+ add_fn( nk0, w2 ); \
+ su1_fn( w0, w2, w3 );
+
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) veor reg, reg;
+
+
+/*
+ * unsigned int
+ * _gcry_sha256_transform_armv8_ce (u32 state[8], const void *input_data,
+ * size_t num_blks)
+ */
+.align 3
+.globl _gcry_sha256_transform_armv8_ce
+.type _gcry_sha256_transform_armv8_ce,%function;
+_gcry_sha256_transform_armv8_ce:
+ /* input:
+ * r0: ctx, CTX
+ * r1: data (64*nblks bytes)
+ * r2: nblks
+ */
+
+ cmp r2, #0;
+ push {r4,lr};
+ beq .Ldo_nothing;
+
+ vpush {q4-q7};
+
+ GET_DATA_POINTER(r4, .LK, lr);
+ mov lr, r4
+
+ vld1.32 {qH0123-qH4567}, [r0] /* load state */
+
+ vld1.8 {qW0-qW1}, [r1]!
+ do_loadk(qK0, qK1)
+ vld1.8 {qW2-qW3}, [r1]!
+ vmov qABCD0, qH0123
+ vmov qEFGH, qH4567
+
+ vrev32.8 qW0, qW0
+ vrev32.8 qW1, qW1
+ vrev32.8 qW2, qW2
+ do_add(qK0, qW0)
+ vrev32.8 qW3, qW3
+ do_add(qK1, qW1)
+
+.Loop:
+ do_rounds(qK0, qK2, qK3, qW0, qW1, qW2, qW3, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ subs r2,r2,#1
+ do_rounds(qK1, qK3, _ , qW1, qW2, qW3, qW0, _ , do_add, do_sha256su0, do_sha256su1)
+ do_rounds(qK2, qK0, qK1, qW2, qW3, qW0, qW1, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(qK3, qK1, _ , qW3, qW0, qW1, qW2, _ , do_add, do_sha256su0, do_sha256su1)
+
+ do_rounds(qK0, qK2, qK3, qW0, qW1, qW2, qW3, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(qK1, qK3, _ , qW1, qW2, qW3, qW0, _ , do_add, do_sha256su0, do_sha256su1)
+ do_rounds(qK2, qK0, qK1, qW2, qW3, qW0, qW1, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(qK3, qK1, _ , qW3, qW0, qW1, qW2, _ , do_add, do_sha256su0, do_sha256su1)
+
+ do_rounds(qK0, qK2, qK3, qW0, qW1, qW2, qW3, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(qK1, qK3, _ , qW1, qW2, qW3, qW0, _ , do_add, do_sha256su0, do_sha256su1)
+ do_rounds(qK2, qK0, qK1, qW2, qW3, qW0, qW1, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(qK3, qK1, _ , qW3, qW0, qW1, qW2, _ , do_add, do_sha256su0, do_sha256su1)
+
+ beq .Lend
+
+ do_rounds(qK0, qK2, qK3, qW0, _ , qW2, qW3, do_loadk, do_add, _, _)
+ vld1.8 {qW0}, [r1]!
+ mov lr, r4
+ do_rounds(qK1, qK3, _ , qW1, _ , qW3, _ , _ , do_add, _, _)
+ vld1.8 {qW1}, [r1]!
+ vrev32.8 qW0, qW0
+ do_rounds(qK2, qK0, qK1, qW2, _ , qW0, _ , do_loadk, do_add, _, _)
+ vrev32.8 qW1, qW1
+ vld1.8 {qW2}, [r1]!
+ do_rounds(qK3, qK1, _ , qW3, _ , qW1, _ , _ , do_add, _, _)
+ vld1.8 {qW3}, [r1]!
+
+ vadd.u32 qH0123, qABCD0
+ vadd.u32 qH4567, qEFGH
+
+ vrev32.8 qW2, qW2
+ vmov qABCD0, qH0123
+ vrev32.8 qW3, qW3
+ vmov qEFGH, qH4567
+
+ b .Loop
+
+.Lend:
+
+ do_rounds(qK0, qK2, qK3, qW0, _ , qW2, qW3, do_loadk, do_add, _, _)
+ do_rounds(qK1, qK3, _ , qW1, _ , qW3, _ , _ , do_add, _, _)
+ do_rounds(qK2, _ , _ , qW2, _ , _ , _ , _ , _, _, _)
+ do_rounds(qK3, _ , _ , qW3, _ , _ , _ , _ , _, _, _)
+
+ CLEAR_REG(qW0)
+ CLEAR_REG(qW1)
+ CLEAR_REG(qW2)
+ CLEAR_REG(qW3)
+ CLEAR_REG(qK0)
+ CLEAR_REG(qK1)
+ CLEAR_REG(qK2)
+ CLEAR_REG(qK3)
+
+ vadd.u32 qH0123, qABCD0
+ vadd.u32 qH4567, qEFGH
+
+ CLEAR_REG(qABCD0)
+ CLEAR_REG(qABCD1)
+ CLEAR_REG(qEFGH)
+
+ vst1.32 {qH0123-qH4567}, [r0] /* store state */
+
+ CLEAR_REG(qH0123)
+ CLEAR_REG(qH4567)
+ vpop {q4-q7}
+
+.Ldo_nothing:
+ mov r0, #0
+ pop {r4,pc}
+.size _gcry_sha256_transform_armv8_ce,.-_gcry_sha256_transform_armv8_ce;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha256-armv8-aarch64-ce.S b/comm/third_party/libgcrypt/cipher/sha256-armv8-aarch64-ce.S
new file mode 100644
index 0000000000..f57cae290b
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha256-armv8-aarch64-ce.S
@@ -0,0 +1,215 @@
+/* sha256-armv8-aarch64-ce.S - ARM/CE accelerated SHA-256 transform function
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__) && \
+ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO) && defined(USE_SHA256)
+
+.cpu generic+simd+crypto
+
+.text
+
+
+/* Constants */
+
+.align 4
+gcry_sha256_aarch64_ce_K:
+.LK:
+ .long 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
+ .long 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
+ .long 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
+ .long 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
+ .long 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
+ .long 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
+ .long 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
+ .long 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
+ .long 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
+ .long 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
+ .long 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
+ .long 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
+ .long 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
+ .long 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
+ .long 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
+ .long 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+
+
+/* Register macros */
+
+#define vH0123 v0
+#define vH4567 v1
+
+#define vABCD0 v2
+#define qABCD0 q2
+#define vABCD1 v3
+#define qABCD1 q3
+#define vEFGH v4
+#define qEFGH q4
+
+#define vT0 v5
+#define vT1 v6
+
+#define vW0 v16
+#define vW1 v17
+#define vW2 v18
+#define vW3 v19
+
+#define vK0 v20
+#define vK1 v21
+#define vK2 v22
+#define vK3 v23
+
+
+/* Round macros */
+
+#define _(...) /*_*/
+
+#define do_loadk(nk0, nk1) ld1 {nk0.16b-nk1.16b},[x3],#32;
+#define do_add(a, b) add a.4s, a.4s, b.4s;
+#define do_sha256su0(w0, w1) sha256su0 w0.4s, w1.4s;
+#define do_sha256su1(w0, w2, w3) sha256su1 w0.4s, w2.4s, w3.4s;
+
+#define do_rounds(k, nk0, nk1, w0, w1, w2, w3, loadk_fn, add_fn, su0_fn, su1_fn) \
+ loadk_fn( v##nk0, v##nk1 ); \
+ su0_fn( v##w0, v##w1 ); \
+ mov vABCD1.16b, vABCD0.16b; \
+ sha256h qABCD0, qEFGH, v##k.4s; \
+ sha256h2 qEFGH, qABCD1, v##k.4s; \
+ add_fn( v##nk0, v##w2 ); \
+ su1_fn( v##w0, v##w2, v##w3 );
+
+
+/* Other functional macros */
+
+#define CLEAR_REG(reg) eor reg.16b, reg.16b, reg.16b;
+
+
+/*
+ * unsigned int
+ * _gcry_sha256_transform_armv8_ce (u32 state[8], const void *input_data,
+ * size_t num_blks)
+ */
+.align 3
+.globl _gcry_sha256_transform_armv8_ce
+ELF(.type _gcry_sha256_transform_armv8_ce,%function;)
+_gcry_sha256_transform_armv8_ce:
+ /* input:
+ * r0: ctx, CTX
+ * r1: data (64*nblks bytes)
+ * r2: nblks
+ */
+ CFI_STARTPROC();
+
+ cbz x2, .Ldo_nothing;
+
+ GET_DATA_POINTER(x3, .LK);
+ mov x4, x3
+
+ ld1 {vH0123.4s-vH4567.4s}, [x0] /* load state */
+
+ ld1 {vW0.16b-vW1.16b}, [x1], #32
+ do_loadk(vK0, vK1)
+ ld1 {vW2.16b-vW3.16b}, [x1], #32
+ mov vABCD0.16b, vH0123.16b
+ mov vEFGH.16b, vH4567.16b
+
+ rev32 vW0.16b, vW0.16b
+ rev32 vW1.16b, vW1.16b
+ rev32 vW2.16b, vW2.16b
+ do_add(vK0, vW0)
+ rev32 vW3.16b, vW3.16b
+ do_add(vK1, vW1)
+
+.Loop:
+ do_rounds(K0, K2, K3, W0, W1, W2, W3, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ sub x2,x2,#1
+ do_rounds(K1, K3, _ , W1, W2, W3, W0, _ , do_add, do_sha256su0, do_sha256su1)
+ do_rounds(K2, K0, K1, W2, W3, W0, W1, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(K3, K1, _ , W3, W0, W1, W2, _ , do_add, do_sha256su0, do_sha256su1)
+
+ do_rounds(K0, K2, K3, W0, W1, W2, W3, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(K1, K3, _ , W1, W2, W3, W0, _ , do_add, do_sha256su0, do_sha256su1)
+ do_rounds(K2, K0, K1, W2, W3, W0, W1, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(K3, K1, _ , W3, W0, W1, W2, _ , do_add, do_sha256su0, do_sha256su1)
+
+ do_rounds(K0, K2, K3, W0, W1, W2, W3, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(K1, K3, _ , W1, W2, W3, W0, _ , do_add, do_sha256su0, do_sha256su1)
+ do_rounds(K2, K0, K1, W2, W3, W0, W1, do_loadk, do_add, do_sha256su0, do_sha256su1)
+ do_rounds(K3, K1, _ , W3, W0, W1, W2, _ , do_add, do_sha256su0, do_sha256su1)
+
+ cbz x2, .Lend
+
+ do_rounds(K0, K2, K3, W0, _ , W2, W3, do_loadk, do_add, _, _)
+ ld1 {vW0.16b}, [x1], #16
+ mov x3, x4
+ do_rounds(K1, K3, _ , W1, _ , W3, _ , _ , do_add, _, _)
+ ld1 {vW1.16b}, [x1], #16
+ rev32 vW0.16b, vW0.16b
+ do_rounds(K2, K0, K1, W2, _ , W0, _ , do_loadk, do_add, _, _)
+ rev32 vW1.16b, vW1.16b
+ ld1 {vW2.16b}, [x1], #16
+ do_rounds(K3, K1, _ , W3, _ , W1, _ , _ , do_add, _, _)
+ ld1 {vW3.16b}, [x1], #16
+
+ do_add(vH0123, vABCD0)
+ do_add(vH4567, vEFGH)
+
+ rev32 vW2.16b, vW2.16b
+ mov vABCD0.16b, vH0123.16b
+ rev32 vW3.16b, vW3.16b
+ mov vEFGH.16b, vH4567.16b
+
+ b .Loop
+
+.Lend:
+
+ do_rounds(K0, K2, K3, W0, _ , W2, W3, do_loadk, do_add, _, _)
+ do_rounds(K1, K3, _ , W1, _ , W3, _ , _ , do_add, _, _)
+ do_rounds(K2, _ , _ , W2, _ , _ , _ , _ , _, _, _)
+ do_rounds(K3, _ , _ , W3, _ , _ , _ , _ , _, _, _)
+
+ CLEAR_REG(vW0)
+ CLEAR_REG(vW1)
+ CLEAR_REG(vW2)
+ CLEAR_REG(vW3)
+ CLEAR_REG(vK0)
+ CLEAR_REG(vK1)
+ CLEAR_REG(vK2)
+ CLEAR_REG(vK3)
+
+ do_add(vH0123, vABCD0)
+ do_add(vH4567, vEFGH)
+
+ CLEAR_REG(vABCD0)
+ CLEAR_REG(vABCD1)
+ CLEAR_REG(vEFGH)
+
+ st1 {vH0123.4s-vH4567.4s}, [x0] /* store state */
+
+ CLEAR_REG(vH0123)
+ CLEAR_REG(vH4567)
+
+.Ldo_nothing:
+ mov x0, #0
+ ret
+ CFI_ENDPROC();
+ELF(.size _gcry_sha256_transform_armv8_ce,.-_gcry_sha256_transform_armv8_ce;)
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha256-avx-amd64.S b/comm/third_party/libgcrypt/cipher/sha256-avx-amd64.S
new file mode 100644
index 0000000000..ec945f8473
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha256-avx-amd64.S
@@ -0,0 +1,506 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Copyright (c) 2012, Intel Corporation
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are
+; met:
+;
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the
+; distribution.
+;
+; * Neither the name of the Intel Corporation nor the names of its
+; contributors may be used to endorse or promote products derived from
+; this software without specific prior written permission.
+;
+;
+; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; This code is described in an Intel White-Paper:
+; "Fast SHA-256 Implementations on Intel Architecture Processors"
+;
+; To find it, surf to http://www.intel.com/p/en_US/embedded
+; and search for that title.
+; The paper is expected to be released roughly at the end of April, 2012
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; This code schedules 1 blocks at a time, with 4 lanes per block
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ * by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Note: Based on the SSSE3 implementation.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA256)
+
+#include "asm-common-amd64.h"
+
+.intel_syntax noprefix
+
+#define VMOVDQ vmovdqu /* assume buffers not aligned */
+
+#define ROR(p1, p2) \
+ /* shld is faster than ror on Intel Sandybridge */ \
+ shld p1, p1, (32 - p2);
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros*/
+
+/* addm [mem], reg
+ * Add reg to mem using reg-mem add and store */
+#define addm(p1, p2) \
+ add p2, p1; \
+ mov p1, p2;
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
+
+/* COPY_XMM_AND_BSWAP xmm, [mem], byte_flip_mask
+ * Load xmm with mem and byte swap each dword */
+#define COPY_XMM_AND_BSWAP(p1, p2, p3) \
+ VMOVDQ p1, p2; \
+ vpshufb p1, p1, p3;
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
+
+#define X0 xmm4
+#define X1 xmm5
+#define X2 xmm6
+#define X3 xmm7
+
+#define XTMP0 xmm0
+#define XTMP1 xmm1
+#define XTMP2 xmm2
+#define XTMP3 xmm3
+#define XTMP4 xmm8
+#define XFER xmm9
+
+#define SHUF_00BA xmm10 /* shuffle xBxA -> 00BA */
+#define SHUF_DC00 xmm11 /* shuffle xDxC -> DC00 */
+#define BYTE_FLIP_MASK xmm12
+
+#define NUM_BLKS rdx /* 3rd arg */
+#define CTX rsi /* 2nd arg */
+#define INP rdi /* 1st arg */
+
+#define SRND rdi /* clobbers INP */
+#define c ecx
+#define d r8d
+#define e edx
+
+#define TBL rbp
+#define a eax
+#define b ebx
+
+#define f r9d
+#define g r10d
+#define h r11d
+
+#define y0 r13d
+#define y1 r14d
+#define y2 r15d
+
+
+
+#define _INP_END_SIZE 8
+#define _INP_SIZE 8
+#define _XFER_SIZE 8
+#define _XMM_SAVE_SIZE 0
+/* STACK_SIZE plus pushes must be an odd multiple of 8 */
+#define _ALIGN_SIZE 8
+
+#define _INP_END 0
+#define _INP (_INP_END + _INP_END_SIZE)
+#define _XFER (_INP + _INP_SIZE)
+#define _XMM_SAVE (_XFER + _XFER_SIZE + _ALIGN_SIZE)
+#define STACK_SIZE (_XMM_SAVE + _XMM_SAVE_SIZE)
+
+
+#define FOUR_ROUNDS_AND_SCHED_0(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ /* compute s0 four at a time and s1 two at a time */; \
+ /* compute W[-16] + W[-7] 4 at a time */; \
+ mov y0, e /* y0 = e */; \
+ ROR( y0, (25-11)) /* y0 = e >> (25-11) */; \
+ mov y1, a /* y1 = a */; \
+ vpalignr XTMP0, X3, X2, 4 /* XTMP0 = W[-7] */; \
+ ROR( y1, (22-13)) /* y1 = a >> (22-13) */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ mov y2, f /* y2 = f */; \
+ ROR( y0, (11-6)) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ xor y2, g /* y2 = f^g */; \
+ vpaddd XTMP0, XTMP0, X0 /* XTMP0 = W[-7] + W[-16] */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ ROR( y1, (13-2)) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ /* compute s0 */; \
+ vpalignr XTMP1, X1, X0, 4 /* XTMP1 = W[-15] */; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ ROR( y0, 6) /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ ROR( y1, 2) /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ add y2, [rsp + _XFER + 0*4] /* y2 = k + w + S1 + CH */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ vpslld XTMP2, XTMP1, (32-7); \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ vpsrld XTMP3, XTMP1, 7; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ vpor XTMP3, XTMP3, XTMP2 /* XTMP1 = W[-15] ror 7 */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+#define FOUR_ROUNDS_AND_SCHED_1(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ mov y0, e /* y0 = e */; \
+ mov y1, a /* y1 = a */; \
+ ROR( y0, (25-11)) /* y0 = e >> (25-11) */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ mov y2, f /* y2 = f */; \
+ ROR( y1, (22-13)) /* y1 = a >> (22-13) */; \
+ vpslld XTMP2, XTMP1, (32-18); \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ ROR( y0, (11-6)) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ xor y2, g /* y2 = f^g */; \
+ vpsrld XTMP4, XTMP1, 18; \
+ ROR( y1, (13-2)) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ ROR( y0, 6) /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ vpxor XTMP4, XTMP4, XTMP3; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ vpsrld XTMP1, XTMP1, 3 /* XTMP4 = W[-15] >> 3 */; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ add y2, [rsp + _XFER + 1*4] /* y2 = k + w + S1 + CH */; \
+ ROR( y1, 2) /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ vpxor XTMP1, XTMP1, XTMP2 /* XTMP1 = W[-15] ror 7 ^ W[-15] ror 18 */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ vpxor XTMP1, XTMP1, XTMP4 /* XTMP1 = s0 */; \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ /* compute low s1 */; \
+ vpshufd XTMP2, X3, 0b11111010 /* XTMP2 = W[-2] {BBAA} */; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ vpaddd XTMP0, XTMP0, XTMP1 /* XTMP0 = W[-16] + W[-7] + s0 */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+#define FOUR_ROUNDS_AND_SCHED_2(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ mov y0, e /* y0 = e */; \
+ mov y1, a /* y1 = a */; \
+ ROR( y0, (25-11)) /* y0 = e >> (25-11) */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ ROR( y1, (22-13)) /* y1 = a >> (22-13) */; \
+ mov y2, f /* y2 = f */; \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ ROR( y0, (11-6)) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ vpsrlq XTMP3, XTMP2, 17 /* XTMP2 = W[-2] ror 17 {xBxA} */; \
+ xor y2, g /* y2 = f^g */; \
+ vpsrlq XTMP4, XTMP2, 19 /* XTMP3 = W[-2] ror 19 {xBxA} */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ vpsrld XTMP2, XTMP2, 10 /* XTMP4 = W[-2] >> 10 {BBAA} */; \
+ ROR( y1, (13-2)) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ ROR( y0, 6) /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ vpxor XTMP2, XTMP2, XTMP3; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ ROR( y1, 2) /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ add y2, [rsp + _XFER + 2*4] /* y2 = k + w + S1 + CH */; \
+ vpxor XTMP4, XTMP4, XTMP2 /* XTMP4 = s1 {xBxA} */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ vpshufb XTMP4, XTMP4, SHUF_00BA /* XTMP4 = s1 {00BA} */; \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ vpaddd XTMP0, XTMP0, XTMP4 /* XTMP0 = {..., ..., W[1], W[0]} */; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ /* compute high s1 */; \
+ vpshufd XTMP2, XTMP0, 0b01010000 /* XTMP2 = W[-2] {DDCC} */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+#define FOUR_ROUNDS_AND_SCHED_3(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ mov y0, e /* y0 = e */; \
+ ROR( y0, (25-11)) /* y0 = e >> (25-11) */; \
+ mov y1, a /* y1 = a */; \
+ ROR( y1, (22-13)) /* y1 = a >> (22-13) */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ mov y2, f /* y2 = f */; \
+ ROR( y0, (11-6)) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ vpsrlq XTMP3, XTMP2, 17 /* XTMP2 = W[-2] ror 17 {xDxC} */; \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ xor y2, g /* y2 = f^g */; \
+ vpsrlq X0, XTMP2, 19 /* XTMP3 = W[-2] ror 19 {xDxC} */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ ROR( y1, (13-2)) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ vpsrld XTMP2, XTMP2, 10 /* X0 = W[-2] >> 10 {DDCC} */; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ ROR( y0, 6) /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ vpxor XTMP2, XTMP2, XTMP3; \
+ ROR( y1, 2) /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ add y2, [rsp + _XFER + 3*4] /* y2 = k + w + S1 + CH */; \
+ vpxor X0, X0, XTMP2 /* X0 = s1 {xDxC} */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ vpshufb X0, X0, SHUF_DC00 /* X0 = s1 {DC00} */; \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ vpaddd X0, X0, XTMP0 /* X0 = {W[3], W[2], W[1], W[0]} */; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+#define FOUR_ROUNDS_AND_SCHED(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ FOUR_ROUNDS_AND_SCHED_0(X0, X1, X2, X3, a, b, c, d, e, f, g, h); \
+ FOUR_ROUNDS_AND_SCHED_1(X0, X1, X2, X3, h, a, b, c, d, e, f, g); \
+ FOUR_ROUNDS_AND_SCHED_2(X0, X1, X2, X3, g, h, a, b, c, d, e, f); \
+ FOUR_ROUNDS_AND_SCHED_3(X0, X1, X2, X3, f, g, h, a, b, c, d, e);
+
+/* input is [rsp + _XFER + %1 * 4] */
+#define DO_ROUND(i1, a, b, c, d, e, f, g, h) \
+ mov y0, e /* y0 = e */; \
+ ROR( y0, (25-11)) /* y0 = e >> (25-11) */; \
+ mov y1, a /* y1 = a */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ ROR( y1, (22-13)) /* y1 = a >> (22-13) */; \
+ mov y2, f /* y2 = f */; \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ ROR( y0, (11-6)) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ xor y2, g /* y2 = f^g */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ ROR( y1, (13-2)) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ ROR( y0, 6) /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ ROR( y1, 2) /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ add y2, [rsp + _XFER + i1 * 4] /* y2 = k + w + S1 + CH */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; void sha256_avx(void *input_data, UINT32 digest[8], UINT64 num_blks)
+;; arg 1 : pointer to input data
+;; arg 2 : pointer to digest
+;; arg 3 : Num blocks
+*/
+.text
+.globl _gcry_sha256_transform_amd64_avx
+ELF(.type _gcry_sha256_transform_amd64_avx,@function;)
+.align 16
+_gcry_sha256_transform_amd64_avx:
+ CFI_STARTPROC()
+ vzeroupper
+
+ push rbx
+ CFI_PUSH(rbx)
+ push rbp
+ CFI_PUSH(rbp)
+ push r13
+ CFI_PUSH(r13)
+ push r14
+ CFI_PUSH(r14)
+ push r15
+ CFI_PUSH(r15)
+
+ sub rsp, STACK_SIZE
+ CFI_ADJUST_CFA_OFFSET(STACK_SIZE);
+
+ shl NUM_BLKS, 6 /* convert to bytes */
+ jz .Ldone_hash
+ add NUM_BLKS, INP /* pointer to end of data */
+ mov [rsp + _INP_END], NUM_BLKS
+
+ /* load initial digest */
+ mov a,[4*0 + CTX]
+ mov b,[4*1 + CTX]
+ mov c,[4*2 + CTX]
+ mov d,[4*3 + CTX]
+ mov e,[4*4 + CTX]
+ mov f,[4*5 + CTX]
+ mov g,[4*6 + CTX]
+ mov h,[4*7 + CTX]
+
+ vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+ vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
+ vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
+
+.Loop0:
+ lea TBL, [.LK256 ADD_RIP]
+
+ /* byte swap first 16 dwords */
+ COPY_XMM_AND_BSWAP(X0, [INP + 0*16], BYTE_FLIP_MASK)
+ COPY_XMM_AND_BSWAP(X1, [INP + 1*16], BYTE_FLIP_MASK)
+ COPY_XMM_AND_BSWAP(X2, [INP + 2*16], BYTE_FLIP_MASK)
+ COPY_XMM_AND_BSWAP(X3, [INP + 3*16], BYTE_FLIP_MASK)
+
+ mov [rsp + _INP], INP
+
+ /* schedule 48 input dwords, by doing 3 rounds of 16 each */
+ mov SRND, 3
+.align 16
+.Loop1:
+ vpaddd XFER, X0, [TBL + 0*16]
+ vmovdqa [rsp + _XFER], XFER
+ FOUR_ROUNDS_AND_SCHED(X0, X1, X2, X3, a, b, c, d, e, f, g, h)
+
+ vpaddd XFER, X1, [TBL + 1*16]
+ vmovdqa [rsp + _XFER], XFER
+ FOUR_ROUNDS_AND_SCHED(X1, X2, X3, X0, e, f, g, h, a, b, c, d)
+
+ vpaddd XFER, X2, [TBL + 2*16]
+ vmovdqa [rsp + _XFER], XFER
+ FOUR_ROUNDS_AND_SCHED(X2, X3, X0, X1, a, b, c, d, e, f, g, h)
+
+ vpaddd XFER, X3, [TBL + 3*16]
+ vmovdqa [rsp + _XFER], XFER
+ add TBL, 4*16
+ FOUR_ROUNDS_AND_SCHED(X3, X0, X1, X2, e, f, g, h, a, b, c, d)
+
+ sub SRND, 1
+ jne .Loop1
+
+ mov SRND, 2
+.Loop2:
+ vpaddd X0, X0, [TBL + 0*16]
+ vmovdqa [rsp + _XFER], X0
+ DO_ROUND(0, a, b, c, d, e, f, g, h)
+ DO_ROUND(1, h, a, b, c, d, e, f, g)
+ DO_ROUND(2, g, h, a, b, c, d, e, f)
+ DO_ROUND(3, f, g, h, a, b, c, d, e)
+ vpaddd X1, X1, [TBL + 1*16]
+ vmovdqa [rsp + _XFER], X1
+ add TBL, 2*16
+ DO_ROUND(0, e, f, g, h, a, b, c, d)
+ DO_ROUND(1, d, e, f, g, h, a, b, c)
+ DO_ROUND(2, c, d, e, f, g, h, a, b)
+ DO_ROUND(3, b, c, d, e, f, g, h, a)
+
+ vmovdqa X0, X2
+ vmovdqa X1, X3
+
+ sub SRND, 1
+ jne .Loop2
+
+ addm([4*0 + CTX],a)
+ addm([4*1 + CTX],b)
+ addm([4*2 + CTX],c)
+ addm([4*3 + CTX],d)
+ addm([4*4 + CTX],e)
+ addm([4*5 + CTX],f)
+ addm([4*6 + CTX],g)
+ addm([4*7 + CTX],h)
+
+ mov INP, [rsp + _INP]
+ add INP, 64
+ cmp INP, [rsp + _INP_END]
+ jne .Loop0
+
+.Ldone_hash:
+ vzeroall
+
+ vmovdqa [rsp + _XFER], XFER
+ xor eax, eax
+
+ add rsp, STACK_SIZE
+ CFI_ADJUST_CFA_OFFSET(-STACK_SIZE);
+
+ pop r15
+ CFI_POP(r15)
+ pop r14
+ CFI_POP(r14)
+ pop r13
+ CFI_POP(r13)
+ pop rbp
+ CFI_POP(rbp)
+ pop rbx
+ CFI_POP(rbx)
+
+ ret
+ CFI_ENDPROC()
+
+
+.align 16
+.LK256:
+ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+
+.LPSHUFFLE_BYTE_FLIP_MASK: .octa 0x0c0d0e0f08090a0b0405060700010203
+
+/* shuffle xBxA -> 00BA */
+.L_SHUF_00BA: .octa 0xFFFFFFFFFFFFFFFF0b0a090803020100
+
+/* shuffle xDxC -> DC00 */
+.L_SHUF_DC00: .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha256-avx2-bmi2-amd64.S b/comm/third_party/libgcrypt/cipher/sha256-avx2-bmi2-amd64.S
new file mode 100644
index 0000000000..d130dd4a61
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha256-avx2-bmi2-amd64.S
@@ -0,0 +1,527 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Copyright (c) 2012, Intel Corporation
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are
+; met:
+;
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the
+; distribution.
+;
+; * Neither the name of the Intel Corporation nor the names of its
+; contributors may be used to endorse or promote products derived from
+; this software without specific prior written permission.
+;
+;
+; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; This code is described in an Intel White-Paper:
+; "Fast SHA-256 Implementations on Intel Architecture Processors"
+;
+; To find it, surf to http://www.intel.com/p/en_US/embedded
+; and search for that title.
+; The paper is expected to be released roughly at the end of April, 2012
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; This code schedules 2 blocks at a time, with 4 lanes per block
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ * by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+ defined(USE_SHA256)
+
+#include "asm-common-amd64.h"
+
+.intel_syntax noprefix
+
+#define VMOVDQ vmovdqu /* ; assume buffers not aligned */
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros */
+
+/* addm [mem], reg */
+/* Add reg to mem using reg-mem add and store */
+#define addm(p1, p2) \
+ add p2, p1; \
+ mov p1, p2;
+
+/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+#define X0 ymm4
+#define X1 ymm5
+#define X2 ymm6
+#define X3 ymm7
+
+/* XMM versions of above */
+#define XWORD0 xmm4
+#define XWORD1 xmm5
+#define XWORD2 xmm6
+#define XWORD3 xmm7
+
+#define XTMP0 ymm0
+#define XTMP1 ymm1
+#define XTMP2 ymm2
+#define XTMP3 ymm3
+#define XTMP4 ymm8
+#define XFER ymm9
+#define XTMP5 ymm11
+
+#define SHUF_00BA ymm10 /* shuffle xBxA -> 00BA */
+#define SHUF_DC00 ymm12 /* shuffle xDxC -> DC00 */
+#define BYTE_FLIP_MASK ymm13
+
+#define X_BYTE_FLIP_MASK xmm13 /* XMM version of BYTE_FLIP_MASK */
+
+#define NUM_BLKS rdx /* 3rd arg */
+#define CTX rsi /* 2nd arg */
+#define INP rdi /* 1st arg */
+#define c ecx
+#define d r8d
+#define e edx /* clobbers NUM_BLKS */
+#define y3 edi /* clobbers INP */
+
+#define TBL rbp
+#define SRND CTX /* SRND is same register as CTX */
+
+#define a eax
+#define b ebx
+#define f r9d
+#define g r10d
+#define h r11d
+#define old_h r11d
+
+#define T1 r12d
+#define y0 r13d
+#define y1 r14d
+#define y2 r15d
+
+
+#define _XFER_SIZE 2*64*4 /* 2 blocks, 64 rounds, 4 bytes/round */
+#define _XMM_SAVE_SIZE 0
+#define _INP_END_SIZE 8
+#define _INP_SIZE 8
+#define _CTX_SIZE 8
+#define _RSP_SIZE 8
+
+#define _XFER 0
+#define _XMM_SAVE _XFER + _XFER_SIZE
+#define _INP_END _XMM_SAVE + _XMM_SAVE_SIZE
+#define _INP _INP_END + _INP_END_SIZE
+#define _CTX _INP + _INP_SIZE
+#define _RSP _CTX + _CTX_SIZE
+#define STACK_SIZE _RSP + _RSP_SIZE
+
+#define ONE_ROUND_PART1(XFERIN, a, b, c, d, e, f, g, h) \
+ /* h += Sum1 (e) + Ch (e, f, g) + (k[t] + w[0]); */ \
+ /* d += h; */ \
+ /* h += Sum0 (a) + Maj (a, b, c); */ \
+ \
+ /* Ch(x, y, z) => ((x & y) + (~x & z)) */ \
+ /* Maj(x, y, z) => ((x & y) + (z & (x ^ y))) */ \
+ \
+ mov y3, e; \
+ add h, [XFERIN]; \
+ and y3, f; \
+ rorx y0, e, 25; \
+ rorx y1, e, 11; \
+ lea h, [h + y3]; \
+ andn y3, e, g; \
+ rorx T1, a, 13; \
+ xor y0, y1; \
+ lea h, [h + y3]
+
+#define ONE_ROUND_PART2(a, b, c, d, e, f, g, h) \
+ rorx y2, a, 22; \
+ rorx y1, e, 6; \
+ mov y3, a; \
+ xor T1, y2; \
+ xor y0, y1; \
+ xor y3, b; \
+ lea h, [h + y0]; \
+ mov y0, a; \
+ rorx y2, a, 2; \
+ add d, h; \
+ and y3, c; \
+ xor T1, y2; \
+ lea h, [h + y3]; \
+ lea h, [h + T1]; \
+ and y0, b; \
+ lea h, [h + y0]
+
+#define ONE_ROUND(XFER, a, b, c, d, e, f, g, h) \
+ ONE_ROUND_PART1(XFER, a, b, c, d, e, f, g, h); \
+ ONE_ROUND_PART2(a, b, c, d, e, f, g, h)
+
+#define FOUR_ROUNDS_AND_SCHED(XFERIN, XFEROUT, X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */; \
+ vpalignr XTMP0, X3, X2, 4 /* XTMP0 = W[-7] */; \
+ vpaddd XTMP0, XTMP0, X0 /* XTMP0 = W[-7] + W[-16]; y1 = (e >> 6); S1 */; \
+ vpalignr XTMP1, X1, X0, 4 /* XTMP1 = W[-15] */; \
+ vpsrld XTMP2, XTMP1, 7; \
+ vpslld XTMP3, XTMP1, (32-7); \
+ vpor XTMP3, XTMP3, XTMP2 /* XTMP3 = W[-15] ror 7 */; \
+ vpsrld XTMP2, XTMP1,18; \
+ \
+ ONE_ROUND(0*4+XFERIN, a, b, c, d, e, f, g, h); \
+ \
+ /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */; \
+ vpsrld XTMP4, XTMP1, 3 /* XTMP4 = W[-15] >> 3 */; \
+ vpslld XTMP1, XTMP1, (32-18); \
+ vpxor XTMP3, XTMP3, XTMP1; \
+ vpxor XTMP3, XTMP3, XTMP2 /* XTMP3 = W[-15] ror 7 ^ W[-15] ror 18 */; \
+ vpxor XTMP1, XTMP3, XTMP4 /* XTMP1 = s0 */; \
+ vpshufd XTMP2, X3, 0b11111010 /* XTMP2 = W[-2] {BBAA} */; \
+ vpaddd XTMP0, XTMP0, XTMP1 /* XTMP0 = W[-16] + W[-7] + s0 */; \
+ vpsrld XTMP4, XTMP2, 10 /* XTMP4 = W[-2] >> 10 {BBAA} */; \
+ \
+ ONE_ROUND(1*4+XFERIN, h, a, b, c, d, e, f, g); \
+ \
+ /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */; \
+ vpsrlq XTMP3, XTMP2, 19 /* XTMP3 = W[-2] ror 19 {xBxA} */; \
+ vpsrlq XTMP2, XTMP2, 17 /* XTMP2 = W[-2] ror 17 {xBxA} */; \
+ vpxor XTMP2, XTMP2, XTMP3; \
+ vpxor XTMP4, XTMP4, XTMP2 /* XTMP4 = s1 {xBxA} */; \
+ vpshufb XTMP4, XTMP4, SHUF_00BA /* XTMP4 = s1 {00BA} */; \
+ vpaddd XTMP0, XTMP0, XTMP4 /* XTMP0 = {..., ..., W[1], W[0]} */; \
+ vpshufd XTMP2, XTMP0, 0b1010000 /* XTMP2 = W[-2] {DDCC} */; \
+ \
+ ONE_ROUND(2*4+XFERIN, g, h, a, b, c, d, e, f); \
+ \
+ /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; */; \
+ vpsrld XTMP5, XTMP2, 10 /* XTMP5 = W[-2] >> 10 {DDCC} */; \
+ vpsrlq XTMP3, XTMP2, 19 /* XTMP3 = W[-2] ror 19 {xDxC} */; \
+ vpsrlq XTMP2, XTMP2, 17 /* XTMP2 = W[-2] ror 17 {xDxC} */; \
+ vpxor XTMP2, XTMP2, XTMP3; \
+ vpxor XTMP5, XTMP5, XTMP2 /* XTMP5 = s1 {xDxC} */; \
+ vpshufb XTMP5, XTMP5, SHUF_DC00 /* XTMP5 = s1 {DC00} */; \
+ vpaddd X0, XTMP5, XTMP0 /* X0 = {W[3], W[2], W[1], W[0]} */; \
+ vpaddd XFER, X0, [TBL + XFEROUT]; \
+ \
+ ONE_ROUND_PART1(3*4+XFERIN, f, g, h, a, b, c, d, e); \
+ vmovdqa [rsp + _XFER + XFEROUT], XFER; \
+ ONE_ROUND_PART2(f, g, h, a, b, c, d, e);
+
+#define DO_4ROUNDS(XFERIN, a, b, c, d, e, f, g, h) \
+ ONE_ROUND(0*4+XFERIN, a, b, c, d, e, f, g, h); \
+ ONE_ROUND(1*4+XFERIN, h, a, b, c, d, e, f, g); \
+ ONE_ROUND(2*4+XFERIN, g, h, a, b, c, d, e, f); \
+ ONE_ROUND(3*4+XFERIN, f, g, h, a, b, c, d, e)
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; void sha256_rorx(void *input_data, UINT32 digest[8], UINT64 num_blks)
+;; arg 1 : pointer to input data
+;; arg 2 : pointer to digest
+;; arg 3 : Num blocks
+*/
+.text
+.globl _gcry_sha256_transform_amd64_avx2
+ELF(.type _gcry_sha256_transform_amd64_avx2,@function)
+.align 32
+_gcry_sha256_transform_amd64_avx2:
+ CFI_STARTPROC()
+ xor eax, eax
+
+ cmp rdx, 0
+ je .Lnowork
+
+ push rbx
+ CFI_PUSH(rbx)
+ push rbp
+ CFI_PUSH(rbp)
+ push r12
+ CFI_PUSH(r12)
+ push r13
+ CFI_PUSH(r13)
+ push r14
+ CFI_PUSH(r14)
+ push r15
+ CFI_PUSH(r15)
+
+ vzeroupper
+
+ vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+ vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
+ vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
+
+ mov rax, rsp
+ CFI_DEF_CFA_REGISTER(rax);
+ sub rsp, STACK_SIZE
+ and rsp, ~63
+ mov [rsp + _RSP], rax
+ CFI_CFA_ON_STACK(_RSP, 6 * 8)
+
+ shl NUM_BLKS, 6 /* convert to bytes */
+ lea NUM_BLKS, [NUM_BLKS + INP - 64] /* pointer to last block */
+ mov [rsp + _INP_END], NUM_BLKS
+
+ /* Check if only one block of input. Note: Loading initial digest
+ * only uses 'mov' instruction and does not change condition
+ * flags. */
+ cmp NUM_BLKS, INP
+
+ /* ; load initial digest */
+ mov a,[4*0 + CTX]
+ mov b,[4*1 + CTX]
+ mov c,[4*2 + CTX]
+ mov d,[4*3 + CTX]
+ mov e,[4*4 + CTX]
+ mov f,[4*5 + CTX]
+ mov g,[4*6 + CTX]
+ mov h,[4*7 + CTX]
+
+ mov [rsp + _CTX], CTX
+
+ je .Ldo_last_block
+
+.Loop0:
+ lea TBL, [.LK256 ADD_RIP]
+
+ /* ; Load first 16 dwords from two blocks */
+ VMOVDQ XTMP0, [INP + 0*32]
+ VMOVDQ XTMP1, [INP + 1*32]
+ VMOVDQ XTMP2, [INP + 2*32]
+ VMOVDQ XTMP3, [INP + 3*32]
+
+ /* ; byte swap data */
+ vpshufb XTMP0, XTMP0, BYTE_FLIP_MASK
+ vpshufb XTMP1, XTMP1, BYTE_FLIP_MASK
+ vpshufb XTMP2, XTMP2, BYTE_FLIP_MASK
+ vpshufb XTMP3, XTMP3, BYTE_FLIP_MASK
+
+ /* ; transpose data into high/low halves */
+ vperm2i128 X0, XTMP0, XTMP2, 0x20
+ vperm2i128 X1, XTMP0, XTMP2, 0x31
+ vperm2i128 X2, XTMP1, XTMP3, 0x20
+ vperm2i128 X3, XTMP1, XTMP3, 0x31
+
+.Last_block_enter:
+ add INP, 64
+ mov [rsp + _INP], INP
+
+ /* ; schedule 48 input dwords, by doing 3 rounds of 12 each */
+ xor SRND, SRND
+
+ vpaddd XFER, X0, [TBL + 0*32]
+ vmovdqa [rsp + _XFER + 0*32], XFER
+ vpaddd XFER, X1, [TBL + 1*32]
+ vmovdqa [rsp + _XFER + 1*32], XFER
+ vpaddd XFER, X2, [TBL + 2*32]
+ vmovdqa [rsp + _XFER + 2*32], XFER
+ vpaddd XFER, X3, [TBL + 3*32]
+ vmovdqa [rsp + _XFER + 3*32], XFER
+
+.align 16
+.Loop1:
+ FOUR_ROUNDS_AND_SCHED(rsp + _XFER + SRND + 0*32, SRND + 4*32, X0, X1, X2, X3, a, b, c, d, e, f, g, h)
+ FOUR_ROUNDS_AND_SCHED(rsp + _XFER + SRND + 1*32, SRND + 5*32, X1, X2, X3, X0, e, f, g, h, a, b, c, d)
+ FOUR_ROUNDS_AND_SCHED(rsp + _XFER + SRND + 2*32, SRND + 6*32, X2, X3, X0, X1, a, b, c, d, e, f, g, h)
+ FOUR_ROUNDS_AND_SCHED(rsp + _XFER + SRND + 3*32, SRND + 7*32, X3, X0, X1, X2, e, f, g, h, a, b, c, d)
+
+ add SRND, 4*32
+ cmp SRND, 3 * 4*32
+ jb .Loop1
+
+ /* ; Do last 16 rounds with no scheduling */
+ DO_4ROUNDS(rsp + _XFER + (3*4*32 + 0*32), a, b, c, d, e, f, g, h)
+ DO_4ROUNDS(rsp + _XFER + (3*4*32 + 1*32), e, f, g, h, a, b, c, d)
+ DO_4ROUNDS(rsp + _XFER + (3*4*32 + 2*32), a, b, c, d, e, f, g, h)
+ DO_4ROUNDS(rsp + _XFER + (3*4*32 + 3*32), e, f, g, h, a, b, c, d)
+
+ mov CTX, [rsp + _CTX]
+ mov INP, [rsp + _INP]
+
+ addm([4*0 + CTX],a)
+ addm([4*1 + CTX],b)
+ addm([4*2 + CTX],c)
+ addm([4*3 + CTX],d)
+ addm([4*4 + CTX],e)
+ addm([4*5 + CTX],f)
+ addm([4*6 + CTX],g)
+ addm([4*7 + CTX],h)
+
+ cmp INP, [rsp + _INP_END]
+ ja .Ldone_hash
+
+ /* ;;; Do second block using previously scheduled results */
+ xor SRND, SRND
+.align 16
+.Loop3:
+ DO_4ROUNDS(rsp + _XFER + SRND + 0*32 + 16, a, b, c, d, e, f, g, h)
+ DO_4ROUNDS(rsp + _XFER + SRND + 1*32 + 16, e, f, g, h, a, b, c, d)
+ add SRND, 2*32
+ cmp SRND, 4 * 4*32
+ jb .Loop3
+
+ mov CTX, [rsp + _CTX]
+ mov INP, [rsp + _INP]
+ add INP, 64
+
+ addm([4*0 + CTX],a)
+ addm([4*1 + CTX],b)
+ addm([4*2 + CTX],c)
+ addm([4*3 + CTX],d)
+ addm([4*4 + CTX],e)
+ addm([4*5 + CTX],f)
+ addm([4*6 + CTX],g)
+ addm([4*7 + CTX],h)
+
+ cmp INP, [rsp + _INP_END]
+ jb .Loop0
+ ja .Ldone_hash
+
+.Ldo_last_block:
+ /* ;;; do last block */
+ lea TBL, [.LK256 ADD_RIP]
+
+ VMOVDQ XWORD0, [INP + 0*16]
+ VMOVDQ XWORD1, [INP + 1*16]
+ VMOVDQ XWORD2, [INP + 2*16]
+ VMOVDQ XWORD3, [INP + 3*16]
+
+ vpshufb XWORD0, XWORD0, X_BYTE_FLIP_MASK
+ vpshufb XWORD1, XWORD1, X_BYTE_FLIP_MASK
+ vpshufb XWORD2, XWORD2, X_BYTE_FLIP_MASK
+ vpshufb XWORD3, XWORD3, X_BYTE_FLIP_MASK
+
+ jmp .Last_block_enter
+
+.Lonly_one_block:
+
+ /* ; load initial digest */
+ mov a,[4*0 + CTX]
+ mov b,[4*1 + CTX]
+ mov c,[4*2 + CTX]
+ mov d,[4*3 + CTX]
+ mov e,[4*4 + CTX]
+ mov f,[4*5 + CTX]
+ mov g,[4*6 + CTX]
+ mov h,[4*7 + CTX]
+
+ vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+ vmovdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
+ vmovdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
+
+ mov [rsp + _CTX], CTX
+ jmp .Ldo_last_block
+
+.Ldone_hash:
+ vzeroall
+
+ /* burn stack */
+ vmovdqa [rsp + _XFER + 0 * 32], ymm0
+ vmovdqa [rsp + _XFER + 1 * 32], ymm0
+ vmovdqa [rsp + _XFER + 2 * 32], ymm0
+ vmovdqa [rsp + _XFER + 3 * 32], ymm0
+ vmovdqa [rsp + _XFER + 4 * 32], ymm0
+ vmovdqa [rsp + _XFER + 5 * 32], ymm0
+ vmovdqa [rsp + _XFER + 6 * 32], ymm0
+ vmovdqa [rsp + _XFER + 7 * 32], ymm0
+ vmovdqa [rsp + _XFER + 8 * 32], ymm0
+ vmovdqa [rsp + _XFER + 9 * 32], ymm0
+ vmovdqa [rsp + _XFER + 10 * 32], ymm0
+ vmovdqa [rsp + _XFER + 11 * 32], ymm0
+ vmovdqa [rsp + _XFER + 12 * 32], ymm0
+ vmovdqa [rsp + _XFER + 13 * 32], ymm0
+ vmovdqa [rsp + _XFER + 14 * 32], ymm0
+ vmovdqa [rsp + _XFER + 15 * 32], ymm0
+ xor eax, eax
+
+ mov rsp, [rsp + _RSP]
+ CFI_DEF_CFA_REGISTER(rsp)
+
+ pop r15
+ CFI_POP(r15)
+ pop r14
+ CFI_POP(r14)
+ pop r13
+ CFI_POP(r13)
+ pop r12
+ CFI_POP(r12)
+ pop rbp
+ CFI_POP(rbp)
+ pop rbx
+ CFI_POP(rbx)
+
+.Lnowork:
+ ret
+ CFI_ENDPROC()
+
+.align 64
+.LK256:
+ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+
+.LPSHUFFLE_BYTE_FLIP_MASK:
+ .octa 0x0c0d0e0f08090a0b0405060700010203,0x0c0d0e0f08090a0b0405060700010203
+
+/* shuffle xBxA -> 00BA */
+.L_SHUF_00BA:
+ .octa 0xFFFFFFFFFFFFFFFF0b0a090803020100,0xFFFFFFFFFFFFFFFF0b0a090803020100
+
+/* shuffle xDxC -> DC00 */
+.L_SHUF_DC00:
+ .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF,0x0b0a090803020100FFFFFFFFFFFFFFFF
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha256-intel-shaext.c b/comm/third_party/libgcrypt/cipher/sha256-intel-shaext.c
new file mode 100644
index 0000000000..48c09eefe1
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha256-intel-shaext.c
@@ -0,0 +1,363 @@
+/* sha256-intel-shaext.S - SHAEXT accelerated SHA-256 transform function
+ * Copyright (C) 2018 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "types.h"
+
+#if defined(HAVE_GCC_INLINE_ASM_SHAEXT) && \
+ defined(HAVE_GCC_INLINE_ASM_SSE41) && defined(USE_SHA256) && \
+ defined(ENABLE_SHAEXT_SUPPORT)
+
+#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 NO_INSTRUMENT_FUNCTION __attribute__((no_instrument_function))
+
+#define ASM_FUNC_ATTR NO_INSTRUMENT_FUNCTION
+
+/* Two macros to be called prior and after the use of SHA-EXT
+ 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 shaext_prepare_variable char win64tmp[2*16]
+# define shaext_prepare_variable_size sizeof(win64tmp)
+# define shaext_prepare() \
+ do { asm volatile ("movdqu %%xmm6, (%0)\n" \
+ "movdqu %%xmm7, (%1)\n" \
+ : \
+ : "r" (&win64tmp[0]), "r" (&win64tmp[16]) \
+ : "memory"); \
+ } while (0)
+# define shaext_cleanup(tmp0,tmp1) \
+ do { asm volatile ("movdqu (%0), %%xmm6\n" \
+ "movdqu (%1), %%xmm7\n" \
+ "pxor %%xmm0, %%xmm0\n" \
+ "pxor %%xmm1, %%xmm1\n" \
+ "pxor %%xmm2, %%xmm2\n" \
+ "pxor %%xmm3, %%xmm3\n" \
+ "pxor %%xmm4, %%xmm4\n" \
+ "pxor %%xmm5, %%xmm5\n" \
+ "movdqa %%xmm0, (%2)\n\t" \
+ "movdqa %%xmm0, (%3)\n\t" \
+ : \
+ : "r" (&win64tmp[0]), "r" (&win64tmp[16]), \
+ "r" (tmp0), "r" (tmp1) \
+ : "memory"); \
+ } while (0)
+#else
+# define shaext_prepare_variable
+# define shaext_prepare_variable_size 0
+# define shaext_prepare() do { } while (0)
+# define shaext_cleanup(tmp0,tmp1) \
+ do { asm volatile ("pxor %%xmm0, %%xmm0\n" \
+ "pxor %%xmm1, %%xmm1\n" \
+ "pxor %%xmm2, %%xmm2\n" \
+ "pxor %%xmm3, %%xmm3\n" \
+ "pxor %%xmm4, %%xmm4\n" \
+ "pxor %%xmm5, %%xmm5\n" \
+ "pxor %%xmm6, %%xmm6\n" \
+ "pxor %%xmm7, %%xmm7\n" \
+ "movdqa %%xmm0, (%0)\n\t" \
+ "movdqa %%xmm0, (%1)\n\t" \
+ : \
+ : "r" (tmp0), "r" (tmp1) \
+ : "memory"); \
+ } while (0)
+#endif
+
+typedef struct u128_s
+{
+ u32 a, b, c, d;
+} u128_t;
+
+/*
+ * Transform nblks*64 bytes (nblks*16 32-bit words) at DATA.
+ */
+unsigned int ASM_FUNC_ATTR
+_gcry_sha256_transform_intel_shaext(u32 state[8], const unsigned char *data,
+ size_t nblks)
+{
+ static const unsigned char bshuf_mask[16] __attribute__ ((aligned (16))) =
+ { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 };
+ static const u128_t K[16] __attribute__ ((aligned (16))) =
+ {
+ { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5 },
+ { 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5 },
+ { 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3 },
+ { 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174 },
+ { 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc },
+ { 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da },
+ { 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7 },
+ { 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967 },
+ { 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13 },
+ { 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85 },
+ { 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3 },
+ { 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070 },
+ { 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5 },
+ { 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3 },
+ { 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208 },
+ { 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }
+ };
+ char save_buf[2 * 16 + 15];
+ char *abef_save;
+ char *cdgh_save;
+ shaext_prepare_variable;
+
+ if (nblks == 0)
+ return 0;
+
+ shaext_prepare ();
+
+ asm volatile ("" : "=r" (abef_save) : "0" (save_buf) : "memory");
+ abef_save = abef_save + (-(uintptr_t)abef_save & 15);
+ cdgh_save = abef_save + 16;
+
+ /* byteswap mask => XMM7 */
+ asm volatile ("movdqa %[mask], %%xmm7\n\t" /* Preload mask */
+ :
+ : [mask] "m" (*bshuf_mask)
+ : "memory");
+
+ /* Load state.. ABEF_SAVE => STATE0 XMM1, CDGH_STATE => STATE1 XMM2 */
+ asm volatile ("movups 16(%[state]), %%xmm1\n\t" /* HGFE (xmm=EFGH) */
+ "movups 0(%[state]), %%xmm0\n\t" /* DCBA (xmm=ABCD) */
+ "movaps %%xmm1, %%xmm2\n\t"
+ "shufps $0x11, %%xmm0, %%xmm1\n\t" /* ABEF (xmm=FEBA) */
+ "shufps $0xbb, %%xmm0, %%xmm2\n\t" /* CDGH (xmm=HGDC) */
+ :
+ : [state] "r" (state)
+ : "memory" );
+
+ /* Load message */
+ asm volatile ("movdqu 0*16(%[data]), %%xmm3\n\t"
+ "movdqu 1*16(%[data]), %%xmm4\n\t"
+ "movdqu 2*16(%[data]), %%xmm5\n\t"
+ "movdqu 3*16(%[data]), %%xmm6\n\t"
+ "pshufb %%xmm7, %%xmm3\n\t"
+ "pshufb %%xmm7, %%xmm4\n\t"
+ "pshufb %%xmm7, %%xmm5\n\t"
+ "pshufb %%xmm7, %%xmm6\n\t"
+ :
+ : [data] "r" (data)
+ : "memory" );
+ data += 64;
+
+ do
+ {
+ /* Save state */
+ asm volatile ("movdqa %%xmm1, (%[abef_save])\n\t"
+ "movdqa %%xmm2, (%[cdgh_save])\n\t"
+ :
+ : [abef_save] "r" (abef_save), [cdgh_save] "r" (cdgh_save)
+ : "memory" );
+
+ /* Round 0..3 */
+ asm volatile ("movdqa %%xmm3, %%xmm0\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ :
+ : [constants] "m" (K[0].a)
+ : "memory" );
+
+ /* Round 4..7 */
+ asm volatile ("movdqa %%xmm4, %%xmm0\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ "sha256msg1 %%xmm4, %%xmm3\n\t"
+ :
+ : [constants] "m" (K[1].a)
+ : "memory" );
+
+ /* Round 8..11 */
+ asm volatile ("movdqa %%xmm5, %%xmm0\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ "sha256msg1 %%xmm5, %%xmm4\n\t"
+ :
+ : [constants] "m" (K[2].a)
+ : "memory" );
+
+#define ROUND(k, MSG0, MSG1, MSG2, MSG3) \
+ asm volatile ("movdqa %%"MSG0", %%xmm0\n\t" \
+ "paddd %[constants], %%xmm0\n\t" \
+ "sha256rnds2 %%xmm1, %%xmm2\n\t" \
+ "movdqa %%"MSG0", %%xmm7\n\t" \
+ "palignr $4, %%"MSG3", %%xmm7\n\t" \
+ "paddd %%xmm7, %%"MSG1"\n\t" \
+ "sha256msg2 %%"MSG0", %%"MSG1"\n\t" \
+ "psrldq $8, %%xmm0\n\t" \
+ "sha256rnds2 %%xmm2, %%xmm1\n\t" \
+ "sha256msg1 %%"MSG0", %%"MSG3"\n\t" \
+ : \
+ : [constants] "m" (K[k].a) \
+ : "memory" )
+
+ /* Rounds 12..15 to 48..51 */
+ ROUND(3, "xmm6", "xmm3", "xmm4", "xmm5");
+ ROUND(4, "xmm3", "xmm4", "xmm5", "xmm6");
+ ROUND(5, "xmm4", "xmm5", "xmm6", "xmm3");
+ ROUND(6, "xmm5", "xmm6", "xmm3", "xmm4");
+ ROUND(7, "xmm6", "xmm3", "xmm4", "xmm5");
+ ROUND(8, "xmm3", "xmm4", "xmm5", "xmm6");
+ ROUND(9, "xmm4", "xmm5", "xmm6", "xmm3");
+ ROUND(10, "xmm5", "xmm6", "xmm3", "xmm4");
+ ROUND(11, "xmm6", "xmm3", "xmm4", "xmm5");
+ ROUND(12, "xmm3", "xmm4", "xmm5", "xmm6");
+
+ if (--nblks == 0)
+ break;
+
+ /* Round 52..55 */
+ asm volatile ("movdqa %%xmm4, %%xmm0\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "movdqa %%xmm4, %%xmm7\n\t"
+ "palignr $4, %%xmm3, %%xmm7\n\t"
+ "movdqu 0*16(%[data]), %%xmm3\n\t"
+ "paddd %%xmm7, %%xmm5\n\t"
+ "sha256msg2 %%xmm4, %%xmm5\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ :
+ : [constants] "m" (K[13].a), [data] "r" (data)
+ : "memory" );
+
+ /* Round 56..59 */
+ asm volatile ("movdqa %%xmm5, %%xmm0\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "movdqa %%xmm5, %%xmm7\n\t"
+ "palignr $4, %%xmm4, %%xmm7\n\t"
+ "movdqu 1*16(%[data]), %%xmm4\n\t"
+ "paddd %%xmm7, %%xmm6\n\t"
+ "movdqa %[mask], %%xmm7\n\t" /* Reload mask */
+ "sha256msg2 %%xmm5, %%xmm6\n\t"
+ "movdqu 2*16(%[data]), %%xmm5\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ :
+ : [constants] "m" (K[14].a), [mask] "m" (*bshuf_mask),
+ [data] "r" (data)
+ : "memory" );
+
+ /* Round 60..63 */
+ asm volatile ("movdqa %%xmm6, %%xmm0\n\t"
+ "pshufb %%xmm7, %%xmm3\n\t"
+ "movdqu 3*16(%[data]), %%xmm6\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "pshufb %%xmm7, %%xmm4\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "pshufb %%xmm7, %%xmm5\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ :
+ : [constants] "m" (K[15].a), [data] "r" (data)
+ : "memory" );
+ data += 64;
+
+ /* Merge states */
+ asm volatile ("paddd (%[abef_save]), %%xmm1\n\t"
+ "paddd (%[cdgh_save]), %%xmm2\n\t"
+ "pshufb %%xmm7, %%xmm6\n\t"
+ :
+ : [abef_save] "r" (abef_save), [cdgh_save] "r" (cdgh_save)
+ : "memory" );
+ }
+ while (1);
+
+ /* Round 52..55 */
+ asm volatile ("movdqa %%xmm4, %%xmm0\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "movdqa %%xmm4, %%xmm7\n\t"
+ "palignr $4, %%xmm3, %%xmm7\n\t"
+ "paddd %%xmm7, %%xmm5\n\t"
+ "sha256msg2 %%xmm4, %%xmm5\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ :
+ : [constants] "m" (K[13].a)
+ : "memory" );
+
+ /* Round 56..59 */
+ asm volatile ("movdqa %%xmm5, %%xmm0\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "movdqa %%xmm5, %%xmm7\n\t"
+ "palignr $4, %%xmm4, %%xmm7\n\t"
+ "paddd %%xmm7, %%xmm6\n\t"
+ "movdqa %[mask], %%xmm7\n\t" /* Reload mask */
+ "sha256msg2 %%xmm5, %%xmm6\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ :
+ : [constants] "m" (K[14].a), [mask] "m" (*bshuf_mask)
+ : "memory" );
+
+ /* Round 60..63 */
+ asm volatile ("movdqa %%xmm6, %%xmm0\n\t"
+ "paddd %[constants], %%xmm0\n\t"
+ "sha256rnds2 %%xmm1, %%xmm2\n\t"
+ "psrldq $8, %%xmm0\n\t"
+ "sha256rnds2 %%xmm2, %%xmm1\n\t"
+ :
+ : [constants] "m" (K[15].a)
+ : "memory" );
+
+ /* Merge states */
+ asm volatile ("paddd (%[abef_save]), %%xmm1\n\t"
+ "paddd (%[cdgh_save]), %%xmm2\n\t"
+ :
+ : [abef_save] "r" (abef_save), [cdgh_save] "r" (cdgh_save)
+ : "memory" );
+
+ /* Save state (XMM1=FEBA, XMM2=HGDC) */
+ asm volatile ("movaps %%xmm1, %%xmm0\n\t"
+ "shufps $0x11, %%xmm2, %%xmm1\n\t" /* xmm=ABCD */
+ "shufps $0xbb, %%xmm2, %%xmm0\n\t" /* xmm=EFGH */
+ "movups %%xmm1, 16(%[state])\n\t"
+ "movups %%xmm0, 0(%[state])\n\t"
+ :
+ : [state] "r" (state)
+ : "memory" );
+
+ shaext_cleanup (abef_save, cdgh_save);
+ return 0;
+}
+
+#if __clang__
+# pragma clang attribute pop
+#endif
+
+#endif /* HAVE_GCC_INLINE_ASM_SHA_EXT */
diff --git a/comm/third_party/libgcrypt/cipher/sha256-ppc.c b/comm/third_party/libgcrypt/cipher/sha256-ppc.c
new file mode 100644
index 0000000000..a9b59714d2
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha256-ppc.c
@@ -0,0 +1,795 @@
+/* sha256-ppc.c - PowerPC vcrypto implementation of SHA-256 transform
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(ENABLE_PPC_CRYPTO_SUPPORT) && \
+ defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) && \
+ defined(USE_SHA256) && \
+ __GNUC__ >= 4
+
+#include <altivec.h>
+#include "bufhelp.h"
+
+
+typedef vector unsigned char vector16x_u8;
+typedef vector unsigned int vector4x_u32;
+typedef vector unsigned long long vector2x_u64;
+
+
+#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
+
+
+static const u32 K[64] =
+ {
+#define TBL(v) v
+ TBL(0x428a2f98), TBL(0x71374491), TBL(0xb5c0fbcf), TBL(0xe9b5dba5),
+ TBL(0x3956c25b), TBL(0x59f111f1), TBL(0x923f82a4), TBL(0xab1c5ed5),
+ TBL(0xd807aa98), TBL(0x12835b01), TBL(0x243185be), TBL(0x550c7dc3),
+ TBL(0x72be5d74), TBL(0x80deb1fe), TBL(0x9bdc06a7), TBL(0xc19bf174),
+ TBL(0xe49b69c1), TBL(0xefbe4786), TBL(0x0fc19dc6), TBL(0x240ca1cc),
+ TBL(0x2de92c6f), TBL(0x4a7484aa), TBL(0x5cb0a9dc), TBL(0x76f988da),
+ TBL(0x983e5152), TBL(0xa831c66d), TBL(0xb00327c8), TBL(0xbf597fc7),
+ TBL(0xc6e00bf3), TBL(0xd5a79147), TBL(0x06ca6351), TBL(0x14292967),
+ TBL(0x27b70a85), TBL(0x2e1b2138), TBL(0x4d2c6dfc), TBL(0x53380d13),
+ TBL(0x650a7354), TBL(0x766a0abb), TBL(0x81c2c92e), TBL(0x92722c85),
+ TBL(0xa2bfe8a1), TBL(0xa81a664b), TBL(0xc24b8b70), TBL(0xc76c51a3),
+ TBL(0xd192e819), TBL(0xd6990624), TBL(0xf40e3585), TBL(0x106aa070),
+ TBL(0x19a4c116), TBL(0x1e376c08), TBL(0x2748774c), TBL(0x34b0bcb5),
+ TBL(0x391c0cb3), TBL(0x4ed8aa4a), TBL(0x5b9cca4f), TBL(0x682e6ff3),
+ TBL(0x748f82ee), TBL(0x78a5636f), TBL(0x84c87814), TBL(0x8cc70208),
+ TBL(0x90befffa), TBL(0xa4506ceb), TBL(0xbef9a3f7), TBL(0xc67178f2)
+#undef TBL
+ };
+
+
+static ASM_FUNC_ATTR_INLINE vector4x_u32
+vec_rol_elems(vector4x_u32 v, unsigned int idx)
+{
+#ifndef WORDS_BIGENDIAN
+ return vec_sld (v, v, (16 - (4 * idx)) & 15);
+#else
+ return vec_sld (v, v, (4 * idx) & 15);
+#endif
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector4x_u32
+vec_merge_idx0_elems(vector4x_u32 v0, vector4x_u32 v1,
+ vector4x_u32 v2, vector4x_u32 v3)
+{
+ return (vector4x_u32)vec_mergeh ((vector2x_u64) vec_mergeh(v0, v1),
+ (vector2x_u64) vec_mergeh(v2, v3));
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector4x_u32
+vec_ror_u32(vector4x_u32 v, unsigned int shift)
+{
+ return (v >> (shift & 31)) ^ (v << ((32 - shift) & 31));
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector4x_u32
+vec_vshasigma_u32(vector4x_u32 v, unsigned int a, unsigned int b)
+{
+ asm ("vshasigmaw %0,%1,%2,%3"
+ : "=v" (v)
+ : "v" (v), "g" (a), "g" (b)
+ : "memory");
+ return v;
+}
+
+
+/* SHA2 round in vector registers */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h); \
+ t1 += ((k) + (w)); \
+ t1 += Cho((e),(f),(g)); \
+ t1 += Sum1((e)); \
+ t2 = Sum0((a)); \
+ t2 += Maj((a),(b),(c)); \
+ d += t1; \
+ h = t1 + t2; \
+ } while (0)
+
+#define Cho(b, c, d) (vec_sel(d, c, b))
+
+#define Maj(c, d, b) (vec_sel(c, b, c ^ d))
+
+#define Sum0(x) (vec_vshasigma_u32(x, 1, 0))
+
+#define Sum1(x) (vec_vshasigma_u32(x, 1, 15))
+
+
+/* Message expansion on general purpose registers */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))
+
+#define I(i) ( w[i] = buf_get_be32(data + i * 4) )
+#define W(i) ({ w[i&0x0f] += w[(i-7) &0x0f]; \
+ w[i&0x0f] += S0(w[(i-15)&0x0f]); \
+ w[i&0x0f] += S1(w[(i-2) &0x0f]); \
+ w[i&0x0f]; })
+
+#define I2(i) ( w2[i] = buf_get_be32(64 + data + i * 4), I(i) )
+#define W2(i) ({ w2[i] = w2[i-7]; \
+ w2[i] += S1(w2[i-2]); \
+ w2[i] += S0(w2[i-15]); \
+ w2[i] += w2[i-16]; \
+ W(i); })
+#define R2(i) ( w2[i] )
+
+
+unsigned int ASM_FUNC_ATTR
+_gcry_sha256_transform_ppc8(u32 state[8], const unsigned char *data,
+ size_t nblks)
+{
+ /* GPRs used for message expansion as vector intrinsics based generates
+ * slower code. */
+ vector4x_u32 h0, h1, h2, h3, h4, h5, h6, h7;
+ vector4x_u32 h0_h3, h4_h7;
+ vector4x_u32 a, b, c, d, e, f, g, h, t1, t2;
+ u32 w[16];
+ u32 w2[64];
+
+ h0_h3 = vec_vsx_ld (4 * 0, state);
+ h4_h7 = vec_vsx_ld (4 * 4, state);
+
+ h0 = h0_h3;
+ h1 = vec_rol_elems (h0_h3, 1);
+ h2 = vec_rol_elems (h0_h3, 2);
+ h3 = vec_rol_elems (h0_h3, 3);
+ h4 = h4_h7;
+ h5 = vec_rol_elems (h4_h7, 1);
+ h6 = vec_rol_elems (h4_h7, 2);
+ h7 = vec_rol_elems (h4_h7, 3);
+
+ while (nblks >= 2)
+ {
+ a = h0;
+ b = h1;
+ c = h2;
+ d = h3;
+ e = h4;
+ f = h5;
+ g = h6;
+ h = h7;
+
+ R(a, b, c, d, e, f, g, h, K[0], I2(0));
+ R(h, a, b, c, d, e, f, g, K[1], I2(1));
+ R(g, h, a, b, c, d, e, f, K[2], I2(2));
+ R(f, g, h, a, b, c, d, e, K[3], I2(3));
+ R(e, f, g, h, a, b, c, d, K[4], I2(4));
+ R(d, e, f, g, h, a, b, c, K[5], I2(5));
+ R(c, d, e, f, g, h, a, b, K[6], I2(6));
+ R(b, c, d, e, f, g, h, a, K[7], I2(7));
+ R(a, b, c, d, e, f, g, h, K[8], I2(8));
+ R(h, a, b, c, d, e, f, g, K[9], I2(9));
+ R(g, h, a, b, c, d, e, f, K[10], I2(10));
+ R(f, g, h, a, b, c, d, e, K[11], I2(11));
+ R(e, f, g, h, a, b, c, d, K[12], I2(12));
+ R(d, e, f, g, h, a, b, c, K[13], I2(13));
+ R(c, d, e, f, g, h, a, b, K[14], I2(14));
+ R(b, c, d, e, f, g, h, a, K[15], I2(15));
+ data += 64 * 2;
+
+ R(a, b, c, d, e, f, g, h, K[16], W2(16));
+ R(h, a, b, c, d, e, f, g, K[17], W2(17));
+ R(g, h, a, b, c, d, e, f, K[18], W2(18));
+ R(f, g, h, a, b, c, d, e, K[19], W2(19));
+ R(e, f, g, h, a, b, c, d, K[20], W2(20));
+ R(d, e, f, g, h, a, b, c, K[21], W2(21));
+ R(c, d, e, f, g, h, a, b, K[22], W2(22));
+ R(b, c, d, e, f, g, h, a, K[23], W2(23));
+ R(a, b, c, d, e, f, g, h, K[24], W2(24));
+ R(h, a, b, c, d, e, f, g, K[25], W2(25));
+ R(g, h, a, b, c, d, e, f, K[26], W2(26));
+ R(f, g, h, a, b, c, d, e, K[27], W2(27));
+ R(e, f, g, h, a, b, c, d, K[28], W2(28));
+ R(d, e, f, g, h, a, b, c, K[29], W2(29));
+ R(c, d, e, f, g, h, a, b, K[30], W2(30));
+ R(b, c, d, e, f, g, h, a, K[31], W2(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W2(32));
+ R(h, a, b, c, d, e, f, g, K[33], W2(33));
+ R(g, h, a, b, c, d, e, f, K[34], W2(34));
+ R(f, g, h, a, b, c, d, e, K[35], W2(35));
+ R(e, f, g, h, a, b, c, d, K[36], W2(36));
+ R(d, e, f, g, h, a, b, c, K[37], W2(37));
+ R(c, d, e, f, g, h, a, b, K[38], W2(38));
+ R(b, c, d, e, f, g, h, a, K[39], W2(39));
+ R(a, b, c, d, e, f, g, h, K[40], W2(40));
+ R(h, a, b, c, d, e, f, g, K[41], W2(41));
+ R(g, h, a, b, c, d, e, f, K[42], W2(42));
+ R(f, g, h, a, b, c, d, e, K[43], W2(43));
+ R(e, f, g, h, a, b, c, d, K[44], W2(44));
+ R(d, e, f, g, h, a, b, c, K[45], W2(45));
+ R(c, d, e, f, g, h, a, b, K[46], W2(46));
+ R(b, c, d, e, f, g, h, a, K[47], W2(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W2(48));
+ R(h, a, b, c, d, e, f, g, K[49], W2(49));
+ R(g, h, a, b, c, d, e, f, K[50], W2(50));
+ R(f, g, h, a, b, c, d, e, K[51], W2(51));
+ R(e, f, g, h, a, b, c, d, K[52], W2(52));
+ R(d, e, f, g, h, a, b, c, K[53], W2(53));
+ R(c, d, e, f, g, h, a, b, K[54], W2(54));
+ R(b, c, d, e, f, g, h, a, K[55], W2(55));
+ R(a, b, c, d, e, f, g, h, K[56], W2(56));
+ R(h, a, b, c, d, e, f, g, K[57], W2(57));
+ R(g, h, a, b, c, d, e, f, K[58], W2(58));
+ R(f, g, h, a, b, c, d, e, K[59], W2(59));
+ R(e, f, g, h, a, b, c, d, K[60], W2(60));
+ R(d, e, f, g, h, a, b, c, K[61], W2(61));
+ R(c, d, e, f, g, h, a, b, K[62], W2(62));
+ R(b, c, d, e, f, g, h, a, K[63], W2(63));
+
+ h0 += a;
+ h1 += b;
+ h2 += c;
+ h3 += d;
+ h4 += e;
+ h5 += f;
+ h6 += g;
+ h7 += h;
+
+ a = h0;
+ b = h1;
+ c = h2;
+ d = h3;
+ e = h4;
+ f = h5;
+ g = h6;
+ h = h7;
+
+ R(a, b, c, d, e, f, g, h, K[0], R2(0));
+ R(h, a, b, c, d, e, f, g, K[1], R2(1));
+ R(g, h, a, b, c, d, e, f, K[2], R2(2));
+ R(f, g, h, a, b, c, d, e, K[3], R2(3));
+ R(e, f, g, h, a, b, c, d, K[4], R2(4));
+ R(d, e, f, g, h, a, b, c, K[5], R2(5));
+ R(c, d, e, f, g, h, a, b, K[6], R2(6));
+ R(b, c, d, e, f, g, h, a, K[7], R2(7));
+ R(a, b, c, d, e, f, g, h, K[8], R2(8));
+ R(h, a, b, c, d, e, f, g, K[9], R2(9));
+ R(g, h, a, b, c, d, e, f, K[10], R2(10));
+ R(f, g, h, a, b, c, d, e, K[11], R2(11));
+ R(e, f, g, h, a, b, c, d, K[12], R2(12));
+ R(d, e, f, g, h, a, b, c, K[13], R2(13));
+ R(c, d, e, f, g, h, a, b, K[14], R2(14));
+ R(b, c, d, e, f, g, h, a, K[15], R2(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], R2(16));
+ R(h, a, b, c, d, e, f, g, K[17], R2(17));
+ R(g, h, a, b, c, d, e, f, K[18], R2(18));
+ R(f, g, h, a, b, c, d, e, K[19], R2(19));
+ R(e, f, g, h, a, b, c, d, K[20], R2(20));
+ R(d, e, f, g, h, a, b, c, K[21], R2(21));
+ R(c, d, e, f, g, h, a, b, K[22], R2(22));
+ R(b, c, d, e, f, g, h, a, K[23], R2(23));
+ R(a, b, c, d, e, f, g, h, K[24], R2(24));
+ R(h, a, b, c, d, e, f, g, K[25], R2(25));
+ R(g, h, a, b, c, d, e, f, K[26], R2(26));
+ R(f, g, h, a, b, c, d, e, K[27], R2(27));
+ R(e, f, g, h, a, b, c, d, K[28], R2(28));
+ R(d, e, f, g, h, a, b, c, K[29], R2(29));
+ R(c, d, e, f, g, h, a, b, K[30], R2(30));
+ R(b, c, d, e, f, g, h, a, K[31], R2(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], R2(32));
+ R(h, a, b, c, d, e, f, g, K[33], R2(33));
+ R(g, h, a, b, c, d, e, f, K[34], R2(34));
+ R(f, g, h, a, b, c, d, e, K[35], R2(35));
+ R(e, f, g, h, a, b, c, d, K[36], R2(36));
+ R(d, e, f, g, h, a, b, c, K[37], R2(37));
+ R(c, d, e, f, g, h, a, b, K[38], R2(38));
+ R(b, c, d, e, f, g, h, a, K[39], R2(39));
+ R(a, b, c, d, e, f, g, h, K[40], R2(40));
+ R(h, a, b, c, d, e, f, g, K[41], R2(41));
+ R(g, h, a, b, c, d, e, f, K[42], R2(42));
+ R(f, g, h, a, b, c, d, e, K[43], R2(43));
+ R(e, f, g, h, a, b, c, d, K[44], R2(44));
+ R(d, e, f, g, h, a, b, c, K[45], R2(45));
+ R(c, d, e, f, g, h, a, b, K[46], R2(46));
+ R(b, c, d, e, f, g, h, a, K[47], R2(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], R2(48));
+ R(h, a, b, c, d, e, f, g, K[49], R2(49));
+ R(g, h, a, b, c, d, e, f, K[50], R2(50));
+ R(f, g, h, a, b, c, d, e, K[51], R2(51));
+ R(e, f, g, h, a, b, c, d, K[52], R2(52));
+ R(d, e, f, g, h, a, b, c, K[53], R2(53));
+ R(c, d, e, f, g, h, a, b, K[54], R2(54));
+ R(b, c, d, e, f, g, h, a, K[55], R2(55));
+ R(a, b, c, d, e, f, g, h, K[56], R2(56));
+ R(h, a, b, c, d, e, f, g, K[57], R2(57));
+ R(g, h, a, b, c, d, e, f, K[58], R2(58));
+ R(f, g, h, a, b, c, d, e, K[59], R2(59));
+ R(e, f, g, h, a, b, c, d, K[60], R2(60));
+ R(d, e, f, g, h, a, b, c, K[61], R2(61));
+ R(c, d, e, f, g, h, a, b, K[62], R2(62));
+ R(b, c, d, e, f, g, h, a, K[63], R2(63));
+
+ h0 += a;
+ h1 += b;
+ h2 += c;
+ h3 += d;
+ h4 += e;
+ h5 += f;
+ h6 += g;
+ h7 += h;
+
+ nblks -= 2;
+ }
+
+ while (nblks)
+ {
+ a = h0;
+ b = h1;
+ c = h2;
+ d = h3;
+ e = h4;
+ f = h5;
+ g = h6;
+ h = h7;
+
+ R(a, b, c, d, e, f, g, h, K[0], I(0));
+ R(h, a, b, c, d, e, f, g, K[1], I(1));
+ R(g, h, a, b, c, d, e, f, K[2], I(2));
+ R(f, g, h, a, b, c, d, e, K[3], I(3));
+ R(e, f, g, h, a, b, c, d, K[4], I(4));
+ R(d, e, f, g, h, a, b, c, K[5], I(5));
+ R(c, d, e, f, g, h, a, b, K[6], I(6));
+ R(b, c, d, e, f, g, h, a, K[7], I(7));
+ R(a, b, c, d, e, f, g, h, K[8], I(8));
+ R(h, a, b, c, d, e, f, g, K[9], I(9));
+ R(g, h, a, b, c, d, e, f, K[10], I(10));
+ R(f, g, h, a, b, c, d, e, K[11], I(11));
+ R(e, f, g, h, a, b, c, d, K[12], I(12));
+ R(d, e, f, g, h, a, b, c, K[13], I(13));
+ R(c, d, e, f, g, h, a, b, K[14], I(14));
+ R(b, c, d, e, f, g, h, a, K[15], I(15));
+ data += 64;
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W(48));
+ R(h, a, b, c, d, e, f, g, K[49], W(49));
+ R(g, h, a, b, c, d, e, f, K[50], W(50));
+ R(f, g, h, a, b, c, d, e, K[51], W(51));
+ R(e, f, g, h, a, b, c, d, K[52], W(52));
+ R(d, e, f, g, h, a, b, c, K[53], W(53));
+ R(c, d, e, f, g, h, a, b, K[54], W(54));
+ R(b, c, d, e, f, g, h, a, K[55], W(55));
+ R(a, b, c, d, e, f, g, h, K[56], W(56));
+ R(h, a, b, c, d, e, f, g, K[57], W(57));
+ R(g, h, a, b, c, d, e, f, K[58], W(58));
+ R(f, g, h, a, b, c, d, e, K[59], W(59));
+ R(e, f, g, h, a, b, c, d, K[60], W(60));
+ R(d, e, f, g, h, a, b, c, K[61], W(61));
+ R(c, d, e, f, g, h, a, b, K[62], W(62));
+ R(b, c, d, e, f, g, h, a, K[63], W(63));
+
+ h0 += a;
+ h1 += b;
+ h2 += c;
+ h3 += d;
+ h4 += e;
+ h5 += f;
+ h6 += g;
+ h7 += h;
+
+ nblks--;
+ }
+
+ h0_h3 = vec_merge_idx0_elems (h0, h1, h2, h3);
+ h4_h7 = vec_merge_idx0_elems (h4, h5, h6, h7);
+ vec_vsx_st (h0_h3, 4 * 0, state);
+ vec_vsx_st (h4_h7, 4 * 4, state);
+
+ return sizeof(w2) + sizeof(w);
+}
+#undef R
+#undef Cho
+#undef Maj
+#undef Sum0
+#undef Sum1
+#undef S0
+#undef S1
+#undef I
+#undef W
+#undef I2
+#undef W2
+#undef R2
+
+
+/* SHA2 round in general purpose registers */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + ((k) + (w));\
+ t2 = Sum0((a)) + Maj((a),(b),(c)); \
+ d += t1; \
+ h = t1 + t2; \
+ } while (0)
+
+#define Cho(x, y, z) ((x & y) + (~x & z))
+
+#define Maj(z, x, y) ((x & y) + (z & (x ^ y)))
+
+#define Sum0(x) (ror (x, 2) ^ ror (x ^ ror (x, 22-13), 13))
+
+#define Sum1(x) (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25))
+
+
+/* Message expansion on general purpose registers */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))
+
+#define I(i) ( w[i] = buf_get_be32(data + i * 4) )
+#define WN(i) ({ w[i&0x0f] += w[(i-7) &0x0f]; \
+ w[i&0x0f] += S0(w[(i-15)&0x0f]); \
+ w[i&0x0f] += S1(w[(i-2) &0x0f]); \
+ w[i&0x0f]; })
+#define W(i) ({ u32 r = w[i&0x0f]; WN(i); r; })
+#define L(i) w[i&0x0f]
+
+
+unsigned int ASM_FUNC_ATTR
+_gcry_sha256_transform_ppc9(u32 state[8], const unsigned char *data,
+ size_t nblks)
+{
+ /* GPRs used for round function and message expansion as vector intrinsics
+ * based generates slower code for POWER9. */
+ u32 a, b, c, d, e, f, g, h, t1, t2;
+ u32 w[16];
+
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+
+ while (nblks >= 2)
+ {
+ I(0); I(1); I(2); I(3);
+ I(4); I(5); I(6); I(7);
+ I(8); I(9); I(10); I(11);
+ I(12); I(13); I(14); I(15);
+ data += 64;
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], L(48));
+ R(h, a, b, c, d, e, f, g, K[49], L(49));
+ R(g, h, a, b, c, d, e, f, K[50], L(50));
+ R(f, g, h, a, b, c, d, e, K[51], L(51));
+ I(0); I(1); I(2); I(3);
+ R(e, f, g, h, a, b, c, d, K[52], L(52));
+ R(d, e, f, g, h, a, b, c, K[53], L(53));
+ R(c, d, e, f, g, h, a, b, K[54], L(54));
+ R(b, c, d, e, f, g, h, a, K[55], L(55));
+ I(4); I(5); I(6); I(7);
+ R(a, b, c, d, e, f, g, h, K[56], L(56));
+ R(h, a, b, c, d, e, f, g, K[57], L(57));
+ R(g, h, a, b, c, d, e, f, K[58], L(58));
+ R(f, g, h, a, b, c, d, e, K[59], L(59));
+ I(8); I(9); I(10); I(11);
+ R(e, f, g, h, a, b, c, d, K[60], L(60));
+ R(d, e, f, g, h, a, b, c, K[61], L(61));
+ R(c, d, e, f, g, h, a, b, K[62], L(62));
+ R(b, c, d, e, f, g, h, a, K[63], L(63));
+ I(12); I(13); I(14); I(15);
+ data += 64;
+
+ a += state[0];
+ b += state[1];
+ c += state[2];
+ d += state[3];
+ e += state[4];
+ f += state[5];
+ g += state[6];
+ h += state[7];
+ state[0] = a;
+ state[1] = b;
+ state[2] = c;
+ state[3] = d;
+ state[4] = e;
+ state[5] = f;
+ state[6] = g;
+ state[7] = h;
+
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], L(48));
+ R(h, a, b, c, d, e, f, g, K[49], L(49));
+ R(g, h, a, b, c, d, e, f, K[50], L(50));
+ R(f, g, h, a, b, c, d, e, K[51], L(51));
+ R(e, f, g, h, a, b, c, d, K[52], L(52));
+ R(d, e, f, g, h, a, b, c, K[53], L(53));
+ R(c, d, e, f, g, h, a, b, K[54], L(54));
+ R(b, c, d, e, f, g, h, a, K[55], L(55));
+ R(a, b, c, d, e, f, g, h, K[56], L(56));
+ R(h, a, b, c, d, e, f, g, K[57], L(57));
+ R(g, h, a, b, c, d, e, f, K[58], L(58));
+ R(f, g, h, a, b, c, d, e, K[59], L(59));
+ R(e, f, g, h, a, b, c, d, K[60], L(60));
+ R(d, e, f, g, h, a, b, c, K[61], L(61));
+ R(c, d, e, f, g, h, a, b, K[62], L(62));
+ R(b, c, d, e, f, g, h, a, K[63], L(63));
+
+ a += state[0];
+ b += state[1];
+ c += state[2];
+ d += state[3];
+ e += state[4];
+ f += state[5];
+ g += state[6];
+ h += state[7];
+ state[0] = a;
+ state[1] = b;
+ state[2] = c;
+ state[3] = d;
+ state[4] = e;
+ state[5] = f;
+ state[6] = g;
+ state[7] = h;
+
+ nblks -= 2;
+ }
+
+ while (nblks)
+ {
+ I(0); I(1); I(2); I(3);
+ I(4); I(5); I(6); I(7);
+ I(8); I(9); I(10); I(11);
+ I(12); I(13); I(14); I(15);
+ data += 64;
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], L(48));
+ R(h, a, b, c, d, e, f, g, K[49], L(49));
+ R(g, h, a, b, c, d, e, f, K[50], L(50));
+ R(f, g, h, a, b, c, d, e, K[51], L(51));
+ R(e, f, g, h, a, b, c, d, K[52], L(52));
+ R(d, e, f, g, h, a, b, c, K[53], L(53));
+ R(c, d, e, f, g, h, a, b, K[54], L(54));
+ R(b, c, d, e, f, g, h, a, K[55], L(55));
+ R(a, b, c, d, e, f, g, h, K[56], L(56));
+ R(h, a, b, c, d, e, f, g, K[57], L(57));
+ R(g, h, a, b, c, d, e, f, K[58], L(58));
+ R(f, g, h, a, b, c, d, e, K[59], L(59));
+ R(e, f, g, h, a, b, c, d, K[60], L(60));
+ R(d, e, f, g, h, a, b, c, K[61], L(61));
+ R(c, d, e, f, g, h, a, b, K[62], L(62));
+ R(b, c, d, e, f, g, h, a, K[63], L(63));
+
+ a += state[0];
+ b += state[1];
+ c += state[2];
+ d += state[3];
+ e += state[4];
+ f += state[5];
+ g += state[6];
+ h += state[7];
+ state[0] = a;
+ state[1] = b;
+ state[2] = c;
+ state[3] = d;
+ state[4] = e;
+ state[5] = f;
+ state[6] = g;
+ state[7] = h;
+
+ nblks--;
+ }
+
+ return sizeof(w);
+}
+
+#endif /* ENABLE_PPC_CRYPTO_SUPPORT */
diff --git a/comm/third_party/libgcrypt/cipher/sha256-ssse3-amd64.S b/comm/third_party/libgcrypt/cipher/sha256-ssse3-amd64.S
new file mode 100644
index 0000000000..098b0eb641
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha256-ssse3-amd64.S
@@ -0,0 +1,528 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Copyright (c) 2012, Intel Corporation
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are
+; met:
+;
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the
+; distribution.
+;
+; * Neither the name of the Intel Corporation nor the names of its
+; contributors may be used to endorse or promote products derived from
+; this software without specific prior written permission.
+;
+;
+; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; This code is described in an Intel White-Paper:
+; "Fast SHA-256 Implementations on Intel Architecture Processors"
+;
+; To find it, surf to http://www.intel.com/p/en_US/embedded
+; and search for that title.
+; The paper is expected to be released roughly at the end of April, 2012
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; This code schedules 1 blocks at a time, with 4 lanes per block
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ * by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Note: original implementation was named as SHA256-SSE4. However, only SSSE3
+ * is required.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA256)
+
+#include "asm-common-amd64.h"
+
+.intel_syntax noprefix
+
+#define MOVDQ movdqu /* assume buffers not aligned */
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros*/
+
+/* addm [mem], reg
+ * Add reg to mem using reg-mem add and store */
+#define addm(p1, p2) \
+ add p2, p1; \
+ mov p1, p2;
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
+
+/* COPY_XMM_AND_BSWAP xmm, [mem], byte_flip_mask
+ * Load xmm with mem and byte swap each dword */
+#define COPY_XMM_AND_BSWAP(p1, p2, p3) \
+ MOVDQ p1, p2; \
+ pshufb p1, p3;
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
+
+#define X0 xmm4
+#define X1 xmm5
+#define X2 xmm6
+#define X3 xmm7
+
+#define XTMP0 xmm0
+#define XTMP1 xmm1
+#define XTMP2 xmm2
+#define XTMP3 xmm3
+#define XTMP4 xmm8
+#define XFER xmm9
+
+#define SHUF_00BA xmm10 /* shuffle xBxA -> 00BA */
+#define SHUF_DC00 xmm11 /* shuffle xDxC -> DC00 */
+#define BYTE_FLIP_MASK xmm12
+
+#define NUM_BLKS rdx /* 3rd arg */
+#define CTX rsi /* 2nd arg */
+#define INP rdi /* 1st arg */
+
+#define SRND rdi /* clobbers INP */
+#define c ecx
+#define d r8d
+#define e edx
+
+#define TBL rbp
+#define a eax
+#define b ebx
+
+#define f r9d
+#define g r10d
+#define h r11d
+
+#define y0 r13d
+#define y1 r14d
+#define y2 r15d
+
+
+
+#define _INP_END_SIZE 8
+#define _INP_SIZE 8
+#define _XFER_SIZE 8
+#define _XMM_SAVE_SIZE 0
+/* STACK_SIZE plus pushes must be an odd multiple of 8 */
+#define _ALIGN_SIZE 8
+
+#define _INP_END 0
+#define _INP (_INP_END + _INP_END_SIZE)
+#define _XFER (_INP + _INP_SIZE)
+#define _XMM_SAVE (_XFER + _XFER_SIZE + _ALIGN_SIZE)
+#define STACK_SIZE (_XMM_SAVE + _XMM_SAVE_SIZE)
+
+
+#define FOUR_ROUNDS_AND_SCHED_0(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ /* compute s0 four at a time and s1 two at a time */; \
+ /* compute W[-16] + W[-7] 4 at a time */; \
+ movdqa XTMP0, X3; \
+ mov y0, e /* y0 = e */; \
+ ror y0, (25-11) /* y0 = e >> (25-11) */; \
+ mov y1, a /* y1 = a */; \
+ palignr XTMP0, X2, 4 /* XTMP0 = W[-7] */; \
+ ror y1, (22-13) /* y1 = a >> (22-13) */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ mov y2, f /* y2 = f */; \
+ ror y0, (11-6) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ movdqa XTMP1, X1; \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ xor y2, g /* y2 = f^g */; \
+ paddd XTMP0, X0 /* XTMP0 = W[-7] + W[-16] */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ ror y1, (13-2) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ /* compute s0 */; \
+ palignr XTMP1, X0, 4 /* XTMP1 = W[-15] */; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ ror y0, 6 /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ movdqa XTMP2, XTMP1 /* XTMP2 = W[-15] */; \
+ ror y1, 2 /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ add y2, [rsp + _XFER + 0*4] /* y2 = k + w + S1 + CH */; \
+ movdqa XTMP3, XTMP1 /* XTMP3 = W[-15] */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ pslld XTMP1, (32-7); \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ psrld XTMP2, 7; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ por XTMP1, XTMP2 /* XTMP1 = W[-15] ror 7 */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+#define FOUR_ROUNDS_AND_SCHED_1(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ movdqa XTMP2, XTMP3 /* XTMP2 = W[-15] */; \
+ mov y0, e /* y0 = e */; \
+ mov y1, a /* y1 = a */; \
+ movdqa XTMP4, XTMP3 /* XTMP4 = W[-15] */; \
+ ror y0, (25-11) /* y0 = e >> (25-11) */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ mov y2, f /* y2 = f */; \
+ ror y1, (22-13) /* y1 = a >> (22-13) */; \
+ pslld XTMP3, (32-18); \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ ror y0, (11-6) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ xor y2, g /* y2 = f^g */; \
+ psrld XTMP2, 18; \
+ ror y1, (13-2) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ ror y0, 6 /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ pxor XTMP1, XTMP3; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ psrld XTMP4, 3 /* XTMP4 = W[-15] >> 3 */; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ add y2, [rsp + _XFER + 1*4] /* y2 = k + w + S1 + CH */; \
+ ror y1, 2 /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ pxor XTMP1, XTMP2 /* XTMP1 = W[-15] ror 7 ^ W[-15] ror 18 */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ pxor XTMP1, XTMP4 /* XTMP1 = s0 */; \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ /* compute low s1 */; \
+ pshufd XTMP2, X3, 0b11111010 /* XTMP2 = W[-2] {BBAA} */; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ paddd XTMP0, XTMP1 /* XTMP0 = W[-16] + W[-7] + s0 */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+#define FOUR_ROUNDS_AND_SCHED_2(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ movdqa XTMP3, XTMP2 /* XTMP3 = W[-2] {BBAA} */; \
+ mov y0, e /* y0 = e */; \
+ mov y1, a /* y1 = a */; \
+ ror y0, (25-11) /* y0 = e >> (25-11) */; \
+ movdqa XTMP4, XTMP2 /* XTMP4 = W[-2] {BBAA} */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ ror y1, (22-13) /* y1 = a >> (22-13) */; \
+ mov y2, f /* y2 = f */; \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ ror y0, (11-6) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ psrlq XTMP2, 17 /* XTMP2 = W[-2] ror 17 {xBxA} */; \
+ xor y2, g /* y2 = f^g */; \
+ psrlq XTMP3, 19 /* XTMP3 = W[-2] ror 19 {xBxA} */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ psrld XTMP4, 10 /* XTMP4 = W[-2] >> 10 {BBAA} */; \
+ ror y1, (13-2) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ ror y0, 6 /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ pxor XTMP2, XTMP3; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ ror y1, 2 /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ add y2, [rsp + _XFER + 2*4] /* y2 = k + w + S1 + CH */; \
+ pxor XTMP4, XTMP2 /* XTMP4 = s1 {xBxA} */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ pshufb XTMP4, SHUF_00BA /* XTMP4 = s1 {00BA} */; \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ paddd XTMP0, XTMP4 /* XTMP0 = {..., ..., W[1], W[0]} */; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ /* compute high s1 */; \
+ pshufd XTMP2, XTMP0, 0b01010000 /* XTMP2 = W[-2] {DDCC} */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+#define FOUR_ROUNDS_AND_SCHED_3(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ movdqa XTMP3, XTMP2 /* XTMP3 = W[-2] {DDCC} */; \
+ mov y0, e /* y0 = e */; \
+ ror y0, (25-11) /* y0 = e >> (25-11) */; \
+ mov y1, a /* y1 = a */; \
+ movdqa X0, XTMP2 /* X0 = W[-2] {DDCC} */; \
+ ror y1, (22-13) /* y1 = a >> (22-13) */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ mov y2, f /* y2 = f */; \
+ ror y0, (11-6) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ psrlq XTMP2, 17 /* XTMP2 = W[-2] ror 17 {xDxC} */; \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ xor y2, g /* y2 = f^g */; \
+ psrlq XTMP3, 19 /* XTMP3 = W[-2] ror 19 {xDxC} */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ ror y1, (13-2) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ psrld X0, 10 /* X0 = W[-2] >> 10 {DDCC} */; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ ror y0, 6 /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ pxor XTMP2, XTMP3; \
+ ror y1, 2 /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ add y2, [rsp + _XFER + 3*4] /* y2 = k + w + S1 + CH */; \
+ pxor X0, XTMP2 /* X0 = s1 {xDxC} */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ pshufb X0, SHUF_DC00 /* X0 = s1 {DC00} */; \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ paddd X0, XTMP0 /* X0 = {W[3], W[2], W[1], W[0]} */; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+#define FOUR_ROUNDS_AND_SCHED(X0, X1, X2, X3, a, b, c, d, e, f, g, h) \
+ FOUR_ROUNDS_AND_SCHED_0(X0, X1, X2, X3, a, b, c, d, e, f, g, h); \
+ FOUR_ROUNDS_AND_SCHED_1(X0, X1, X2, X3, h, a, b, c, d, e, f, g); \
+ FOUR_ROUNDS_AND_SCHED_2(X0, X1, X2, X3, g, h, a, b, c, d, e, f); \
+ FOUR_ROUNDS_AND_SCHED_3(X0, X1, X2, X3, f, g, h, a, b, c, d, e);
+
+/* input is [rsp + _XFER + %1 * 4] */
+#define DO_ROUND(i1, a, b, c, d, e, f, g, h) \
+ mov y0, e /* y0 = e */; \
+ ror y0, (25-11) /* y0 = e >> (25-11) */; \
+ mov y1, a /* y1 = a */; \
+ xor y0, e /* y0 = e ^ (e >> (25-11)) */; \
+ ror y1, (22-13) /* y1 = a >> (22-13) */; \
+ mov y2, f /* y2 = f */; \
+ xor y1, a /* y1 = a ^ (a >> (22-13) */; \
+ ror y0, (11-6) /* y0 = (e >> (11-6)) ^ (e >> (25-6)) */; \
+ xor y2, g /* y2 = f^g */; \
+ xor y0, e /* y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) */; \
+ ror y1, (13-2) /* y1 = (a >> (13-2)) ^ (a >> (22-2)) */; \
+ and y2, e /* y2 = (f^g)&e */; \
+ xor y1, a /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */; \
+ ror y0, 6 /* y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) */; \
+ xor y2, g /* y2 = CH = ((f^g)&e)^g */; \
+ add y2, y0 /* y2 = S1 + CH */; \
+ ror y1, 2 /* y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) */; \
+ add y2, [rsp + _XFER + i1 * 4] /* y2 = k + w + S1 + CH */; \
+ mov y0, a /* y0 = a */; \
+ add h, y2 /* h = h + S1 + CH + k + w */; \
+ mov y2, a /* y2 = a */; \
+ or y0, c /* y0 = a|c */; \
+ add d, h /* d = d + h + S1 + CH + k + w */; \
+ and y2, c /* y2 = a&c */; \
+ and y0, b /* y0 = (a|c)&b */; \
+ add h, y1 /* h = h + S1 + CH + k + w + S0 */; \
+ or y0, y2 /* y0 = MAJ = (a|c)&b)|(a&c) */; \
+ lea h, [h + y0] /* h = h + S1 + CH + k + w + S0 + MAJ */
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; void sha256_sse4(void *input_data, UINT32 digest[8], UINT64 num_blks)
+;; arg 1 : pointer to input data
+;; arg 2 : pointer to digest
+;; arg 3 : Num blocks
+*/
+.text
+.globl _gcry_sha256_transform_amd64_ssse3
+ELF(.type _gcry_sha256_transform_amd64_ssse3,@function;)
+.align 16
+_gcry_sha256_transform_amd64_ssse3:
+ CFI_STARTPROC()
+ push rbx
+ CFI_PUSH(rbx)
+ push rbp
+ CFI_PUSH(rbp)
+ push r13
+ CFI_PUSH(r13)
+ push r14
+ CFI_PUSH(r14)
+ push r15
+ CFI_PUSH(r15)
+
+ sub rsp, STACK_SIZE
+ CFI_ADJUST_CFA_OFFSET(STACK_SIZE);
+
+ shl NUM_BLKS, 6 /* convert to bytes */
+ jz .Ldone_hash
+ add NUM_BLKS, INP /* pointer to end of data */
+ mov [rsp + _INP_END], NUM_BLKS
+
+ /* load initial digest */
+ mov a,[4*0 + CTX]
+ mov b,[4*1 + CTX]
+ mov c,[4*2 + CTX]
+ mov d,[4*3 + CTX]
+ mov e,[4*4 + CTX]
+ mov f,[4*5 + CTX]
+ mov g,[4*6 + CTX]
+ mov h,[4*7 + CTX]
+
+ movdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+ movdqa SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
+ movdqa SHUF_DC00, [.L_SHUF_DC00 ADD_RIP]
+
+.Loop0:
+ lea TBL, [.LK256 ADD_RIP]
+
+ /* byte swap first 16 dwords */
+ COPY_XMM_AND_BSWAP(X0, [INP + 0*16], BYTE_FLIP_MASK)
+ COPY_XMM_AND_BSWAP(X1, [INP + 1*16], BYTE_FLIP_MASK)
+ COPY_XMM_AND_BSWAP(X2, [INP + 2*16], BYTE_FLIP_MASK)
+ COPY_XMM_AND_BSWAP(X3, [INP + 3*16], BYTE_FLIP_MASK)
+
+ mov [rsp + _INP], INP
+
+ /* schedule 48 input dwords, by doing 3 rounds of 16 each */
+ mov SRND, 3
+.align 16
+.Loop1:
+ movdqa XFER, [TBL + 0*16]
+ paddd XFER, X0
+ movdqa [rsp + _XFER], XFER
+ FOUR_ROUNDS_AND_SCHED(X0, X1, X2, X3, a, b, c, d, e, f, g, h)
+
+ movdqa XFER, [TBL + 1*16]
+ paddd XFER, X1
+ movdqa [rsp + _XFER], XFER
+ FOUR_ROUNDS_AND_SCHED(X1, X2, X3, X0, e, f, g, h, a, b, c, d)
+
+ movdqa XFER, [TBL + 2*16]
+ paddd XFER, X2
+ movdqa [rsp + _XFER], XFER
+ FOUR_ROUNDS_AND_SCHED(X2, X3, X0, X1, a, b, c, d, e, f, g, h)
+
+ movdqa XFER, [TBL + 3*16]
+ paddd XFER, X3
+ movdqa [rsp + _XFER], XFER
+ add TBL, 4*16
+ FOUR_ROUNDS_AND_SCHED(X3, X0, X1, X2, e, f, g, h, a, b, c, d)
+
+ sub SRND, 1
+ jne .Loop1
+
+ mov SRND, 2
+.Loop2:
+ paddd X0, [TBL + 0*16]
+ movdqa [rsp + _XFER], X0
+ DO_ROUND(0, a, b, c, d, e, f, g, h)
+ DO_ROUND(1, h, a, b, c, d, e, f, g)
+ DO_ROUND(2, g, h, a, b, c, d, e, f)
+ DO_ROUND(3, f, g, h, a, b, c, d, e)
+ paddd X1, [TBL + 1*16]
+ movdqa [rsp + _XFER], X1
+ add TBL, 2*16
+ DO_ROUND(0, e, f, g, h, a, b, c, d)
+ DO_ROUND(1, d, e, f, g, h, a, b, c)
+ DO_ROUND(2, c, d, e, f, g, h, a, b)
+ DO_ROUND(3, b, c, d, e, f, g, h, a)
+
+ movdqa X0, X2
+ movdqa X1, X3
+
+ sub SRND, 1
+ jne .Loop2
+
+ addm([4*0 + CTX],a)
+ addm([4*1 + CTX],b)
+ addm([4*2 + CTX],c)
+ addm([4*3 + CTX],d)
+ addm([4*4 + CTX],e)
+ addm([4*5 + CTX],f)
+ addm([4*6 + CTX],g)
+ addm([4*7 + CTX],h)
+
+ mov INP, [rsp + _INP]
+ add INP, 64
+ cmp INP, [rsp + _INP_END]
+ jne .Loop0
+
+ pxor xmm0, xmm0
+ pxor xmm1, xmm1
+ pxor xmm2, xmm2
+ pxor xmm3, xmm3
+ pxor xmm4, xmm4
+ pxor xmm5, xmm5
+ pxor xmm6, xmm6
+ pxor xmm7, xmm7
+ pxor xmm8, xmm8
+ pxor xmm9, xmm9
+ pxor xmm10, xmm10
+ pxor xmm11, xmm11
+ pxor xmm12, xmm12
+
+.Ldone_hash:
+ pxor XFER, XFER
+ movdqa [rsp + _XFER], XFER
+ xor eax, eax
+
+ add rsp, STACK_SIZE
+ CFI_ADJUST_CFA_OFFSET(-STACK_SIZE);
+
+ pop r15
+ CFI_POP(r15)
+ pop r14
+ CFI_POP(r14)
+ pop r13
+ CFI_POP(r13)
+ pop rbp
+ CFI_POP(rbp)
+ pop rbx
+ CFI_POP(rbx)
+
+ ret
+ CFI_ENDPROC()
+
+
+.align 16
+.LK256:
+ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+
+.LPSHUFFLE_BYTE_FLIP_MASK: .octa 0x0c0d0e0f08090a0b0405060700010203
+
+/* shuffle xBxA -> 00BA */
+.L_SHUF_00BA: .octa 0xFFFFFFFFFFFFFFFF0b0a090803020100
+
+/* shuffle xDxC -> DC00 */
+.L_SHUF_DC00: .octa 0x0b0a090803020100FFFFFFFFFFFFFFFF
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha256.c b/comm/third_party/libgcrypt/cipher/sha256.c
new file mode 100644
index 0000000000..9350589110
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha256.c
@@ -0,0 +1,857 @@
+/* sha256.c - SHA256 hash function
+ * Copyright (C) 2003, 2006, 2008, 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Test vectors:
+
+ "abc"
+ SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
+ SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
+
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
+ SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
+
+ "a" one million times
+ SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
+ SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
+
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+/* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
+#undef USE_SSSE3
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_SSSE3 1
+#endif
+
+/* USE_AVX indicates whether to compile with Intel AVX code. */
+#undef USE_AVX
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX 1
+#endif
+
+/* USE_AVX2 indicates whether to compile with Intel AVX2/BMI2 code. */
+#undef USE_AVX2
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+ defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX2 1
+#endif
+
+/* USE_SHAEXT indicates whether to compile with Intel SHA Extension code. */
+#undef USE_SHAEXT
+#if defined(HAVE_GCC_INLINE_ASM_SHAEXT) && \
+ defined(HAVE_GCC_INLINE_ASM_SSE41) && \
+ defined(ENABLE_SHAEXT_SUPPORT)
+# define USE_SHAEXT 1
+#endif
+
+/* USE_ARM_CE indicates whether to enable ARMv8 Crypto Extension assembly
+ * code. */
+#undef USE_ARM_CE
+#ifdef ENABLE_ARM_CRYPTO_SUPPORT
+# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
+ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
+ && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO)
+# define USE_ARM_CE 1
+# elif defined(__AARCH64EL__) \
+ && defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) \
+ && defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
+# define USE_ARM_CE 1
+# endif
+#endif
+
+/* USE_PPC_CRYPTO indicates whether to enable PowerPC vector crypto
+ * accelerated code. */
+#undef USE_PPC_CRYPTO
+#ifdef ENABLE_PPC_CRYPTO_SUPPORT
+# if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC)
+# if __GNUC__ >= 4
+# define USE_PPC_CRYPTO 1
+# endif
+# endif
+#endif
+
+/* USE_S390X_CRYPTO indicates whether to enable zSeries code. */
+#undef USE_S390X_CRYPTO
+#if defined(HAVE_GCC_INLINE_ASM_S390X)
+# define USE_S390X_CRYPTO 1
+#endif /* USE_S390X_CRYPTO */
+
+
+typedef struct {
+ gcry_md_block_ctx_t bctx;
+ u32 h0,h1,h2,h3,h4,h5,h6,h7;
+#ifdef USE_S390X_CRYPTO
+ u32 final_len_msb, final_len_lsb; /* needs to be right after h7. */
+ int use_s390x_crypto;
+#endif
+} SHA256_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_SSSE3) || defined(USE_AVX) || defined(USE_AVX2) || \
+ defined(USE_SHAEXT)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# define ASM_EXTRA_STACK (10 * 16 + sizeof(void *) * 4)
+# else
+# define ASM_FUNC_ABI
+# define ASM_EXTRA_STACK 0
+# endif
+#endif
+
+
+#ifdef USE_SSSE3
+unsigned int _gcry_sha256_transform_amd64_ssse3(const void *input_data,
+ u32 state[8],
+ size_t num_blks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha256_transform_amd64_ssse3(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+ return _gcry_sha256_transform_amd64_ssse3 (data, &hd->h0, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif
+
+#ifdef USE_AVX
+unsigned int _gcry_sha256_transform_amd64_avx(const void *input_data,
+ u32 state[8],
+ size_t num_blks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha256_transform_amd64_avx(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+ return _gcry_sha256_transform_amd64_avx (data, &hd->h0, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif
+
+#ifdef USE_AVX2
+unsigned int _gcry_sha256_transform_amd64_avx2(const void *input_data,
+ u32 state[8],
+ size_t num_blks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha256_transform_amd64_avx2(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+ return _gcry_sha256_transform_amd64_avx2 (data, &hd->h0, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif
+
+#ifdef USE_SHAEXT
+/* Does not need ASM_FUNC_ABI */
+unsigned int
+_gcry_sha256_transform_intel_shaext(u32 state[8],
+ const unsigned char *input_data,
+ size_t num_blks);
+
+static unsigned int
+do_sha256_transform_intel_shaext(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+ return _gcry_sha256_transform_intel_shaext (&hd->h0, data, nblks);
+}
+#endif
+
+#ifdef USE_ARM_CE
+unsigned int _gcry_sha256_transform_armv8_ce(u32 state[8],
+ const void *input_data,
+ size_t num_blks);
+
+static unsigned int
+do_sha256_transform_armv8_ce(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+ return _gcry_sha256_transform_armv8_ce (&hd->h0, data, nblks);
+}
+#endif
+
+#ifdef USE_PPC_CRYPTO
+unsigned int _gcry_sha256_transform_ppc8(u32 state[8],
+ const unsigned char *input_data,
+ size_t num_blks);
+
+unsigned int _gcry_sha256_transform_ppc9(u32 state[8],
+ const unsigned char *input_data,
+ size_t num_blks);
+
+static unsigned int
+do_sha256_transform_ppc8(void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+ return _gcry_sha256_transform_ppc8 (&hd->h0, data, nblks);
+}
+
+static unsigned int
+do_sha256_transform_ppc9(void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+ return _gcry_sha256_transform_ppc9 (&hd->h0, data, nblks);
+}
+#endif
+
+#ifdef USE_S390X_CRYPTO
+#include "asm-inline-s390x.h"
+
+static unsigned int
+do_sha256_transform_s390x (void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+
+ kimd_execute (KMID_FUNCTION_SHA256, &hd->h0, data, nblks * 64);
+ return 0;
+}
+
+static unsigned int
+do_sha256_final_s390x (void *ctx, const unsigned char *data, size_t datalen,
+ u32 len_msb, u32 len_lsb)
+{
+ SHA256_CONTEXT *hd = ctx;
+
+ /* Make sure that 'final_len' is positioned at correct offset relative
+ * to 'h0'. This is because we are passing 'h0' pointer as start of
+ * parameter block to 'klmd' instruction. */
+
+ gcry_assert (offsetof (SHA256_CONTEXT, final_len_msb)
+ - offsetof (SHA256_CONTEXT, h0) == 8 * sizeof(u32));
+ gcry_assert (offsetof (SHA256_CONTEXT, final_len_lsb)
+ - offsetof (SHA256_CONTEXT, final_len_msb) == 1 * sizeof(u32));
+
+ hd->final_len_msb = len_msb;
+ hd->final_len_lsb = len_lsb;
+
+ klmd_execute (KMID_FUNCTION_SHA256, &hd->h0, data, datalen);
+ return 0;
+}
+#endif
+
+
+static unsigned int
+do_transform_generic (void *ctx, const unsigned char *data, size_t nblks);
+
+
+static void
+sha256_common_init (SHA256_CONTEXT *hd)
+{
+ unsigned int features = _gcry_get_hw_features ();
+
+ hd->bctx.nblocks = 0;
+ hd->bctx.nblocks_high = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize_shift = _gcry_ctz(64);
+
+ /* Order of feature checks is important here; last match will be
+ * selected. Keep slower implementations at the top and faster at
+ * the bottom. */
+ hd->bctx.bwrite = do_transform_generic;
+#ifdef USE_SSSE3
+ if ((features & HWF_INTEL_SSSE3) != 0)
+ hd->bctx.bwrite = do_sha256_transform_amd64_ssse3;
+#endif
+#ifdef USE_AVX
+ /* AVX implementation uses SHLD which is known to be slow on non-Intel CPUs.
+ * Therefore use this implementation on Intel CPUs only. */
+ if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD))
+ hd->bctx.bwrite = do_sha256_transform_amd64_avx;
+#endif
+#ifdef USE_AVX2
+ if ((features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2))
+ hd->bctx.bwrite = do_sha256_transform_amd64_avx2;
+#endif
+#ifdef USE_SHAEXT
+ if ((features & HWF_INTEL_SHAEXT) && (features & HWF_INTEL_SSE4_1))
+ hd->bctx.bwrite = do_sha256_transform_intel_shaext;
+#endif
+#ifdef USE_ARM_CE
+ if ((features & HWF_ARM_SHA2) != 0)
+ hd->bctx.bwrite = do_sha256_transform_armv8_ce;
+#endif
+#ifdef USE_PPC_CRYPTO
+ if ((features & HWF_PPC_VCRYPTO) != 0)
+ hd->bctx.bwrite = do_sha256_transform_ppc8;
+ if ((features & HWF_PPC_VCRYPTO) != 0 && (features & HWF_PPC_ARCH_3_00) != 0)
+ hd->bctx.bwrite = do_sha256_transform_ppc9;
+#endif
+#ifdef USE_S390X_CRYPTO
+ hd->use_s390x_crypto = 0;
+ if ((features & HWF_S390X_MSA) != 0)
+ {
+ if ((kimd_query () & km_function_to_mask (KMID_FUNCTION_SHA256)) &&
+ (klmd_query () & km_function_to_mask (KMID_FUNCTION_SHA256)))
+ {
+ hd->bctx.bwrite = do_sha256_transform_s390x;
+ hd->use_s390x_crypto = 1;
+ }
+ }
+#endif
+ (void)features;
+}
+
+
+static void
+sha256_init (void *context, unsigned int flags)
+{
+ SHA256_CONTEXT *hd = context;
+
+ (void)flags;
+
+ hd->h0 = 0x6a09e667;
+ hd->h1 = 0xbb67ae85;
+ hd->h2 = 0x3c6ef372;
+ hd->h3 = 0xa54ff53a;
+ hd->h4 = 0x510e527f;
+ hd->h5 = 0x9b05688c;
+ hd->h6 = 0x1f83d9ab;
+ hd->h7 = 0x5be0cd19;
+
+ sha256_common_init (hd);
+}
+
+
+static void
+sha224_init (void *context, unsigned int flags)
+{
+ SHA256_CONTEXT *hd = context;
+
+ (void)flags;
+
+ hd->h0 = 0xc1059ed8;
+ hd->h1 = 0x367cd507;
+ hd->h2 = 0x3070dd17;
+ hd->h3 = 0xf70e5939;
+ hd->h4 = 0xffc00b31;
+ hd->h5 = 0x68581511;
+ hd->h6 = 0x64f98fa7;
+ hd->h7 = 0xbefa4fa4;
+
+ sha256_common_init (hd);
+}
+
+
+/*
+ Transform the message X which consists of 16 32-bit-words. See FIPS
+ 180-2 for details. */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
+ t2 = Sum0((a)) + Maj((a),(b),(c)); \
+ d += t1; \
+ h = t1 + t2; \
+ } while (0)
+
+/* (4.2) same as SHA-1's F1. */
+#define Cho(x, y, z) (z ^ (x & (y ^ z)))
+
+/* (4.3) same as SHA-1's F3 */
+#define Maj(x, y, z) ((x & y) + (z & (x ^ y)))
+
+/* (4.4) */
+#define Sum0(x) (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22))
+
+/* (4.5) */
+#define Sum1(x) (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25))
+
+/* Message expansion */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
+#define I(i) ( w[i] = buf_get_be32(data + i * 4) )
+#define W(i) ( w[i&0x0f] = S1(w[(i-2) &0x0f]) \
+ + w[(i-7) &0x0f] \
+ + S0(w[(i-15)&0x0f]) \
+ + w[(i-16)&0x0f] )
+
+static unsigned int
+do_transform_generic (void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA256_CONTEXT *hd = ctx;
+ static const u32 K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ do
+ {
+
+ u32 a,b,c,d,e,f,g,h,t1,t2;
+ u32 w[16];
+
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+ R(a, b, c, d, e, f, g, h, K[0], I(0));
+ R(h, a, b, c, d, e, f, g, K[1], I(1));
+ R(g, h, a, b, c, d, e, f, K[2], I(2));
+ R(f, g, h, a, b, c, d, e, K[3], I(3));
+ R(e, f, g, h, a, b, c, d, K[4], I(4));
+ R(d, e, f, g, h, a, b, c, K[5], I(5));
+ R(c, d, e, f, g, h, a, b, K[6], I(6));
+ R(b, c, d, e, f, g, h, a, K[7], I(7));
+ R(a, b, c, d, e, f, g, h, K[8], I(8));
+ R(h, a, b, c, d, e, f, g, K[9], I(9));
+ R(g, h, a, b, c, d, e, f, K[10], I(10));
+ R(f, g, h, a, b, c, d, e, K[11], I(11));
+ R(e, f, g, h, a, b, c, d, K[12], I(12));
+ R(d, e, f, g, h, a, b, c, K[13], I(13));
+ R(c, d, e, f, g, h, a, b, K[14], I(14));
+ R(b, c, d, e, f, g, h, a, K[15], I(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W(48));
+ R(h, a, b, c, d, e, f, g, K[49], W(49));
+ R(g, h, a, b, c, d, e, f, K[50], W(50));
+ R(f, g, h, a, b, c, d, e, K[51], W(51));
+ R(e, f, g, h, a, b, c, d, K[52], W(52));
+ R(d, e, f, g, h, a, b, c, K[53], W(53));
+ R(c, d, e, f, g, h, a, b, K[54], W(54));
+ R(b, c, d, e, f, g, h, a, K[55], W(55));
+ R(a, b, c, d, e, f, g, h, K[56], W(56));
+ R(h, a, b, c, d, e, f, g, K[57], W(57));
+ R(g, h, a, b, c, d, e, f, K[58], W(58));
+ R(f, g, h, a, b, c, d, e, K[59], W(59));
+ R(e, f, g, h, a, b, c, d, K[60], W(60));
+ R(d, e, f, g, h, a, b, c, K[61], W(61));
+ R(c, d, e, f, g, h, a, b, K[62], W(62));
+ R(b, c, d, e, f, g, h, a, K[63], W(63));
+
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+
+ data += 64;
+ }
+ while (--nblks);
+
+ return 26*4 + 32 + 3 * sizeof(void*);
+}
+
+#undef S0
+#undef S1
+#undef R
+
+
+/*
+ The routine finally terminates the computation and returns the
+ digest. The handle is prepared for a new cycle, but adding bytes
+ to the handle will the destroy the returned buffer. Returns: 32
+ bytes with the message the digest. */
+static void
+sha256_final(void *context)
+{
+ SHA256_CONTEXT *hd = context;
+ u32 t, th, msb, lsb;
+ byte *p;
+ unsigned int burn;
+
+ t = hd->bctx.nblocks;
+ if (sizeof t == sizeof hd->bctx.nblocks)
+ th = hd->bctx.nblocks_high;
+ else
+ th = hd->bctx.nblocks >> 32;
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = (th << 6) | (t >> 26);
+ /* add the count */
+ t = lsb;
+ if ((lsb += hd->bctx.count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (0)
+ { }
+#ifdef USE_S390X_CRYPTO
+ else if (hd->use_s390x_crypto)
+ {
+ burn = do_sha256_final_s390x (hd, hd->bctx.buf, hd->bctx.count, msb, lsb);
+ }
+#endif
+ else if (hd->bctx.count < 56) /* enough room */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ if (hd->bctx.count < 56)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+
+ /* append the 64 bit count */
+ buf_put_be32(hd->bctx.buf + 56, msb);
+ buf_put_be32(hd->bctx.buf + 60, lsb);
+ burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 1);
+ }
+ else /* need one extra block */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ /* fill pad and next block with zeroes */
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+
+ /* append the 64 bit count */
+ buf_put_be32(hd->bctx.buf + 64 + 56, msb);
+ buf_put_be32(hd->bctx.buf + 64 + 60, lsb);
+ burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 2);
+ }
+
+ p = hd->bctx.buf;
+#define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+ X(5);
+ X(6);
+ X(7);
+#undef X
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (burn);
+}
+
+static byte *
+sha256_read (void *context)
+{
+ SHA256_CONTEXT *hd = context;
+
+ return hd->bctx.buf;
+}
+
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 32 bytes. */
+void
+_gcry_sha256_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SHA256_CONTEXT hd;
+
+ sha256_init (&hd, 0);
+ _gcry_md_block_write (&hd, buffer, length);
+ sha256_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 32);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers. */
+void
+_gcry_sha256_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+ SHA256_CONTEXT hd;
+
+ sha256_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ sha256_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 32);
+}
+
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 28 bytes. */
+static void
+_gcry_sha224_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SHA256_CONTEXT hd;
+
+ sha224_init (&hd, 0);
+ _gcry_md_block_write (&hd, buffer, length);
+ sha256_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 28);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers. */
+static void
+_gcry_sha224_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+ SHA256_CONTEXT hd;
+
+ sha224_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ sha256_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 28);
+}
+
+
+
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha224 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA224, 0,
+ "abc", 3,
+ "\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", 28);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA224, 0,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+ "\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", 28);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA224, 1,
+ NULL, 0,
+ "\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", 28);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA224, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_sha256 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA256, 0,
+ "abc", 3,
+ "\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", 32);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA256, 0,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+ "\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",
+ 32);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA256, 1,
+ NULL, 0,
+ "\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",
+ 32);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA256, 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_MD_SHA224:
+ ec = selftests_sha224 (extended, report);
+ break;
+ case GCRY_MD_SHA256:
+ ec = selftests_sha256 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+
+static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
+ { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
+ 0x1C
+ };
+
+static gcry_md_oid_spec_t oid_spec_sha224[] =
+ {
+ /* From RFC3874, Section 4 */
+ { "2.16.840.1.101.3.4.2.4" },
+ { NULL },
+ };
+
+static byte asn256[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
+ { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+ 0x00, 0x04, 0x20 };
+
+static gcry_md_oid_spec_t oid_spec_sha256[] =
+ {
+ /* According to the OpenPGP draft rfc2440-bis06 */
+ { "2.16.840.1.101.3.4.2.1" },
+ /* PKCS#1 sha256WithRSAEncryption */
+ { "1.2.840.113549.1.1.11" },
+
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha224 =
+ {
+ GCRY_MD_SHA224, {0, 1},
+ "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
+ sha224_init, _gcry_md_block_write, sha256_final, sha256_read, NULL,
+ _gcry_sha224_hash_buffer, _gcry_sha224_hash_buffers,
+ sizeof (SHA256_CONTEXT),
+ run_selftests
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha256 =
+ {
+ GCRY_MD_SHA256, {0, 1},
+ "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
+ sha256_init, _gcry_md_block_write, sha256_final, sha256_read, NULL,
+ _gcry_sha256_hash_buffer, _gcry_sha256_hash_buffers,
+ sizeof (SHA256_CONTEXT),
+ run_selftests
+ };
diff --git a/comm/third_party/libgcrypt/cipher/sha512-arm.S b/comm/third_party/libgcrypt/cipher/sha512-arm.S
new file mode 100644
index 0000000000..94ec0141e7
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha512-arm.S
@@ -0,0 +1,464 @@
+/* sha512-arm.S - ARM assembly implementation of SHA-512 transform
+ *
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#include <config.h>
+
+#if defined(__ARMEL__)
+#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+.text
+
+.syntax unified
+.arm
+
+/* structure of SHA512_CONTEXT */
+#define hd_a 0
+#define hd_b ((hd_a) + 8)
+#define hd_c ((hd_b) + 8)
+#define hd_d ((hd_c) + 8)
+#define hd_e ((hd_d) + 8)
+#define hd_f ((hd_e) + 8)
+#define hd_g ((hd_f) + 8)
+#define hd_h ((hd_g) + 8)
+
+/* register macros */
+#define RK %r2
+
+#define RElo %r0
+#define REhi %r1
+
+#define RT1lo %r3
+#define RT1hi %r4
+#define RT2lo %r5
+#define RT2hi %r6
+#define RWlo %r7
+#define RWhi %r8
+#define RT3lo %r9
+#define RT3hi %r10
+#define RT4lo %r11
+#define RT4hi %ip
+
+#define RRND %lr
+
+/* variable offsets in stack */
+#define ctx (0)
+#define data ((ctx) + 4)
+#define nblks ((data) + 4)
+#define _a ((nblks) + 4)
+#define _b ((_a) + 8)
+#define _c ((_b) + 8)
+#define _d ((_c) + 8)
+#define _e ((_d) + 8)
+#define _f ((_e) + 8)
+#define _g ((_f) + 8)
+#define _h ((_g) + 8)
+
+#define w(i) ((_h) + 8 + ((i) % 16) * 8)
+
+#define STACK_MAX (w(15) + 8)
+
+/* helper macros */
+#define ldr_unaligned_be(rout, rsrc, offs, rtmp) \
+ ldrb rout, [rsrc, #((offs) + 3)]; \
+ ldrb rtmp, [rsrc, #((offs) + 2)]; \
+ orr rout, rout, rtmp, lsl #8; \
+ ldrb rtmp, [rsrc, #((offs) + 1)]; \
+ orr rout, rout, rtmp, lsl #16; \
+ ldrb rtmp, [rsrc, #((offs) + 0)]; \
+ orr rout, rout, rtmp, lsl #24;
+
+#ifdef __ARMEL__
+ /* bswap on little-endian */
+#ifdef HAVE_ARM_ARCH_V6
+ #define be_to_host(reg, rtmp) \
+ rev reg, reg;
+#else
+ #define be_to_host(reg, rtmp) \
+ eor rtmp, reg, reg, ror #16; \
+ mov rtmp, rtmp, lsr #8; \
+ bic rtmp, rtmp, #65280; \
+ eor reg, rtmp, reg, ror #8;
+#endif
+#else
+ /* nop on big-endian */
+ #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define host_to_host(x, y) /*_*/
+
+#define read_u64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, convert, rtmp) \
+ ldr lo0, [rin, #((offs) + 0 * 8 + 4)]; \
+ ldr hi0, [rin, #((offs) + 0 * 8 + 0)]; \
+ ldr lo1, [rin, #((offs) + 1 * 8 + 4)]; \
+ ldr hi1, [rin, #((offs) + 1 * 8 + 0)]; \
+ ldr lo2, [rin, #((offs) + 2 * 8 + 4)]; \
+ convert(lo0, rtmp); \
+ ldr hi2, [rin, #((offs) + 2 * 8 + 0)]; \
+ convert(hi0, rtmp); \
+ ldr lo3, [rin, #((offs) + 3 * 8 + 4)]; \
+ convert(lo1, rtmp); \
+ ldr hi3, [rin, #((offs) + 3 * 8 + 0)]; \
+ convert(hi1, rtmp); \
+ convert(lo2, rtmp); \
+ convert(hi2, rtmp); \
+ convert(lo3, rtmp); \
+ convert(hi3, rtmp);
+
+#define read_be64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, rtmp0) \
+ read_u64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, be_to_host, rtmp0)
+
+/* need to handle unaligned reads by byte reads */
+#define read_be64_unaligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, rtmp0) \
+ ldr_unaligned_be(lo0, rin, (offs) + 0 * 8 + 4, rtmp0); \
+ ldr_unaligned_be(hi0, rin, (offs) + 0 * 8 + 0, rtmp0); \
+ ldr_unaligned_be(lo1, rin, (offs) + 1 * 8 + 4, rtmp0); \
+ ldr_unaligned_be(hi1, rin, (offs) + 1 * 8 + 0, rtmp0); \
+ ldr_unaligned_be(lo2, rin, (offs) + 2 * 8 + 4, rtmp0); \
+ ldr_unaligned_be(hi2, rin, (offs) + 2 * 8 + 0, rtmp0); \
+ ldr_unaligned_be(lo3, rin, (offs) + 3 * 8 + 4, rtmp0); \
+ ldr_unaligned_be(hi3, rin, (offs) + 3 * 8 + 0, rtmp0);
+
+/***********************************************************************
+ * ARM assembly implementation of sha512 transform
+ ***********************************************************************/
+
+/* Round function */
+
+#define R(_a,_b,_c,_d,_e,_f,_g,_h,W,wi) \
+ /* Message expansion, t1 = _h + w[i] */ \
+ W(_a,_h,wi); \
+ \
+ /* w = Sum1(_e) */ \
+ mov RWlo, RElo, lsr#14; \
+ ldm RK!, {RT2lo-RT2hi}; \
+ mov RWhi, REhi, lsr#14; \
+ eor RWlo, RWlo, RElo, lsr#18; \
+ eor RWhi, RWhi, REhi, lsr#18; \
+ ldr RT3lo, [%sp, #(_f)]; \
+ adds RT1lo, RT2lo; /* t1 += K */ \
+ ldr RT3hi, [%sp, #(_f) + 4]; \
+ adc RT1hi, RT2hi; \
+ ldr RT4lo, [%sp, #(_g)]; \
+ eor RWlo, RWlo, RElo, lsl#23; \
+ ldr RT4hi, [%sp, #(_g) + 4]; \
+ eor RWhi, RWhi, REhi, lsl#23; \
+ eor RWlo, RWlo, REhi, lsl#18; \
+ eor RWhi, RWhi, RElo, lsl#18; \
+ eor RWlo, RWlo, REhi, lsl#14; \
+ eor RWhi, RWhi, RElo, lsl#14; \
+ eor RWlo, RWlo, REhi, lsr#9; \
+ eor RWhi, RWhi, RElo, lsr#9; \
+ \
+ /* Cho(_e,_f,_g) => (_e & _f) ^ (~_e & _g) */ \
+ adds RT1lo, RWlo; /* t1 += Sum1(_e) */ \
+ and RT3lo, RT3lo, RElo; \
+ adc RT1hi, RWhi; \
+ and RT3hi, RT3hi, REhi; \
+ bic RT4lo, RT4lo, RElo; \
+ bic RT4hi, RT4hi, REhi; \
+ eor RT3lo, RT3lo, RT4lo; \
+ eor RT3hi, RT3hi, RT4hi; \
+ \
+ /* Load D */ \
+ /* t1 += Cho(_e,_f,_g) */ \
+ ldr RElo, [%sp, #(_d)]; \
+ adds RT1lo, RT3lo; \
+ ldr REhi, [%sp, #(_d) + 4]; \
+ adc RT1hi, RT3hi; \
+ \
+ /* Load A */ \
+ ldr RT3lo, [%sp, #(_a)]; \
+ \
+ /* _d += t1 */ \
+ adds RElo, RT1lo; \
+ ldr RT3hi, [%sp, #(_a) + 4]; \
+ adc REhi, RT1hi; \
+ \
+ /* Store D */ \
+ str RElo, [%sp, #(_d)]; \
+ \
+ /* t2 = Sum0(_a) */ \
+ mov RT2lo, RT3lo, lsr#28; \
+ str REhi, [%sp, #(_d) + 4]; \
+ mov RT2hi, RT3hi, lsr#28; \
+ ldr RWlo, [%sp, #(_b)]; \
+ eor RT2lo, RT2lo, RT3lo, lsl#30; \
+ ldr RWhi, [%sp, #(_b) + 4]; \
+ eor RT2hi, RT2hi, RT3hi, lsl#30; \
+ eor RT2lo, RT2lo, RT3lo, lsl#25; \
+ eor RT2hi, RT2hi, RT3hi, lsl#25; \
+ eor RT2lo, RT2lo, RT3hi, lsl#4; \
+ eor RT2hi, RT2hi, RT3lo, lsl#4; \
+ eor RT2lo, RT2lo, RT3hi, lsr#2; \
+ eor RT2hi, RT2hi, RT3lo, lsr#2; \
+ eor RT2lo, RT2lo, RT3hi, lsr#7; \
+ eor RT2hi, RT2hi, RT3lo, lsr#7; \
+ \
+ /* t2 += t1 */ \
+ adds RT2lo, RT1lo; \
+ ldr RT1lo, [%sp, #(_c)]; \
+ adc RT2hi, RT1hi; \
+ \
+ /* Maj(_a,_b,_c) => ((_a & _b) ^ (_c & (_a ^ _b))) */ \
+ ldr RT1hi, [%sp, #(_c) + 4]; \
+ and RT4lo, RWlo, RT3lo; \
+ and RT4hi, RWhi, RT3hi; \
+ eor RWlo, RWlo, RT3lo; \
+ eor RWhi, RWhi, RT3hi; \
+ and RWlo, RWlo, RT1lo; \
+ and RWhi, RWhi, RT1hi; \
+ eor RWlo, RWlo, RT4lo; \
+ eor RWhi, RWhi, RT4hi; \
+
+/* Message expansion */
+
+#define W_0_63(_a,_h,i) \
+ ldr RT3lo, [%sp, #(w(i-2))]; \
+ adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */ \
+ ldr RT3hi, [%sp, #(w(i-2)) + 4]; \
+ adc RT2hi, RWhi; \
+ /* nw = S1(w[i-2]) */ \
+ ldr RT1lo, [%sp, #(_h)]; /* Load H */ \
+ mov RWlo, RT3lo, lsr#19; \
+ str RT2lo, [%sp, #(_a)]; \
+ eor RWlo, RWlo, RT3lo, lsl#3; \
+ ldr RT1hi, [%sp, #(_h) + 4]; \
+ mov RWhi, RT3hi, lsr#19; \
+ ldr RT2lo, [%sp, #(w(i-7))]; \
+ eor RWhi, RWhi, RT3hi, lsl#3; \
+ str RT2hi, [%sp, #(_a) + 4]; \
+ eor RWlo, RWlo, RT3lo, lsr#6; \
+ ldr RT2hi, [%sp, #(w(i-7)) + 4]; \
+ eor RWhi, RWhi, RT3hi, lsr#6; \
+ eor RWlo, RWlo, RT3hi, lsl#13; \
+ eor RWhi, RWhi, RT3lo, lsl#13; \
+ eor RWlo, RWlo, RT3hi, lsr#29; \
+ eor RWhi, RWhi, RT3lo, lsr#29; \
+ ldr RT3lo, [%sp, #(w(i-15))]; \
+ eor RWlo, RWlo, RT3hi, lsl#26; \
+ ldr RT3hi, [%sp, #(w(i-15)) + 4]; \
+ \
+ adds RT2lo, RWlo; /* nw += w[i-7] */ \
+ ldr RWlo, [%sp, #(w(i-16))]; \
+ adc RT2hi, RWhi; \
+ mov RT4lo, RT3lo, lsr#1; /* S0(w[i-15]) */ \
+ ldr RWhi, [%sp, #(w(i-16)) + 4]; \
+ mov RT4hi, RT3hi, lsr#1; \
+ adds RT2lo, RWlo; /* nw += w[i-16] */ \
+ eor RT4lo, RT4lo, RT3lo, lsr#8; \
+ eor RT4hi, RT4hi, RT3hi, lsr#8; \
+ eor RT4lo, RT4lo, RT3lo, lsr#7; \
+ eor RT4hi, RT4hi, RT3hi, lsr#7; \
+ eor RT4lo, RT4lo, RT3hi, lsl#31; \
+ eor RT4hi, RT4hi, RT3lo, lsl#31; \
+ eor RT4lo, RT4lo, RT3hi, lsl#24; \
+ eor RT4hi, RT4hi, RT3lo, lsl#24; \
+ eor RT4lo, RT4lo, RT3hi, lsl#25; \
+ adc RT2hi, RWhi; \
+ \
+ /* nw += S0(w[i-15]) */ \
+ adds RT2lo, RT4lo; \
+ adc RT2hi, RT4hi; \
+ \
+ /* w[0] = nw */ \
+ str RT2lo, [%sp, #(w(i))]; \
+ adds RT1lo, RWlo; \
+ str RT2hi, [%sp, #(w(i)) + 4]; \
+ adc RT1hi, RWhi;
+
+#define W_64_79(_a,_h,i) \
+ adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */ \
+ ldr RWlo, [%sp, #(w(i-16))]; \
+ adc RT2hi, RWhi; \
+ ldr RWhi, [%sp, #(w(i-16)) + 4]; \
+ ldr RT1lo, [%sp, #(_h)]; /* Load H */ \
+ ldr RT1hi, [%sp, #(_h) + 4]; \
+ str RT2lo, [%sp, #(_a)]; \
+ str RT2hi, [%sp, #(_a) + 4]; \
+ adds RT1lo, RWlo; \
+ adc RT1hi, RWhi;
+
+.align 3
+.globl _gcry_sha512_transform_arm
+.type _gcry_sha512_transform_arm,%function;
+
+_gcry_sha512_transform_arm:
+ /* Input:
+ * %r0: SHA512_CONTEXT
+ * %r1: data
+ * %r2: u64 k[] constants
+ * %r3: nblks
+ */
+ push {%r4-%r11, %ip, %lr};
+ sub %sp, %sp, #STACK_MAX;
+ movs RWlo, %r3;
+ str %r0, [%sp, #(ctx)];
+
+ beq .Ldone;
+
+.Loop_blocks:
+ str RWlo, [%sp, #nblks];
+
+ /* Load context to stack */
+ add RWhi, %sp, #(_a);
+ ldm %r0!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+ stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+ ldm %r0, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+ stm RWhi, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+ /* Load input to w[16] */
+
+ /* test if data is unaligned */
+ tst %r1, #3;
+ beq 1f;
+
+ /* unaligned load */
+ add RWhi, %sp, #(w(0));
+ read_be64_unaligned_4(%r1, 0 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+ stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+ read_be64_unaligned_4(%r1, 4 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+ stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+ read_be64_unaligned_4(%r1, 8 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+ stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+ read_be64_unaligned_4(%r1, 12 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+ b 2f;
+1:
+ /* aligned load */
+ add RWhi, %sp, #(w(0));
+ read_be64_aligned_4(%r1, 0 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+ stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+ read_be64_aligned_4(%r1, 4 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+ stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+ read_be64_aligned_4(%r1, 8 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+ stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+ read_be64_aligned_4(%r1, 12 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo);
+2:
+ add %r1, #(16 * 8);
+ stm RWhi, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi}
+ str %r1, [%sp, #(data)];
+
+ /* preload E & A */
+ ldr RElo, [%sp, #(_e)];
+ ldr REhi, [%sp, #(_e) + 4];
+ mov RWlo, #0;
+ ldr RT2lo, [%sp, #(_a)];
+ mov RRND, #(80-16);
+ ldr RT2hi, [%sp, #(_a) + 4];
+ mov RWhi, #0;
+
+.Loop_rounds:
+ R(_a, _b, _c, _d, _e, _f, _g, _h, W_0_63, 16);
+ R(_h, _a, _b, _c, _d, _e, _f, _g, W_0_63, 17);
+ R(_g, _h, _a, _b, _c, _d, _e, _f, W_0_63, 18);
+ R(_f, _g, _h, _a, _b, _c, _d, _e, W_0_63, 19);
+ R(_e, _f, _g, _h, _a, _b, _c, _d, W_0_63, 20);
+ R(_d, _e, _f, _g, _h, _a, _b, _c, W_0_63, 21);
+ R(_c, _d, _e, _f, _g, _h, _a, _b, W_0_63, 22);
+ R(_b, _c, _d, _e, _f, _g, _h, _a, W_0_63, 23);
+ R(_a, _b, _c, _d, _e, _f, _g, _h, W_0_63, 24);
+ R(_h, _a, _b, _c, _d, _e, _f, _g, W_0_63, 25);
+ R(_g, _h, _a, _b, _c, _d, _e, _f, W_0_63, 26);
+ R(_f, _g, _h, _a, _b, _c, _d, _e, W_0_63, 27);
+ R(_e, _f, _g, _h, _a, _b, _c, _d, W_0_63, 28);
+ R(_d, _e, _f, _g, _h, _a, _b, _c, W_0_63, 29);
+ R(_c, _d, _e, _f, _g, _h, _a, _b, W_0_63, 30);
+ R(_b, _c, _d, _e, _f, _g, _h, _a, W_0_63, 31);
+
+ subs RRND, #16;
+ bne .Loop_rounds;
+
+ R(_a, _b, _c, _d, _e, _f, _g, _h, W_64_79, 16);
+ R(_h, _a, _b, _c, _d, _e, _f, _g, W_64_79, 17);
+ R(_g, _h, _a, _b, _c, _d, _e, _f, W_64_79, 18);
+ R(_f, _g, _h, _a, _b, _c, _d, _e, W_64_79, 19);
+ R(_e, _f, _g, _h, _a, _b, _c, _d, W_64_79, 20);
+ R(_d, _e, _f, _g, _h, _a, _b, _c, W_64_79, 21);
+ R(_c, _d, _e, _f, _g, _h, _a, _b, W_64_79, 22);
+ R(_b, _c, _d, _e, _f, _g, _h, _a, W_64_79, 23);
+ R(_a, _b, _c, _d, _e, _f, _g, _h, W_64_79, 24);
+ R(_h, _a, _b, _c, _d, _e, _f, _g, W_64_79, 25);
+ R(_g, _h, _a, _b, _c, _d, _e, _f, W_64_79, 26);
+ R(_f, _g, _h, _a, _b, _c, _d, _e, W_64_79, 27);
+ R(_e, _f, _g, _h, _a, _b, _c, _d, W_64_79, 28);
+ R(_d, _e, _f, _g, _h, _a, _b, _c, W_64_79, 29);
+ R(_c, _d, _e, _f, _g, _h, _a, _b, W_64_79, 30);
+ R(_b, _c, _d, _e, _f, _g, _h, _a, W_64_79, 31);
+
+ ldr %r0, [%sp, #(ctx)];
+ adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */
+ ldr %r1, [%sp, #(data)];
+ adc RT2hi, RWhi;
+
+ ldm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi}
+ adds RT1lo, RT2lo;
+ ldr RT2lo, [%sp, #(_b + 0)];
+ adc RT1hi, RT2hi;
+ ldr RT2hi, [%sp, #(_b + 4)];
+ adds RWlo, RT2lo;
+ ldr RT2lo, [%sp, #(_c + 0)];
+ adc RWhi, RT2hi;
+ ldr RT2hi, [%sp, #(_c + 4)];
+ adds RT3lo, RT2lo;
+ ldr RT2lo, [%sp, #(_d + 0)];
+ adc RT3hi, RT2hi;
+ ldr RT2hi, [%sp, #(_d + 4)];
+ adds RT4lo, RT2lo;
+ ldr RT2lo, [%sp, #(_e + 0)];
+ adc RT4hi, RT2hi;
+ stm %r0!, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi}
+
+ ldr RT2hi, [%sp, #(_e + 4)];
+ ldm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi}
+ adds RT1lo, RT2lo;
+ ldr RT2lo, [%sp, #(_f + 0)];
+ adc RT1hi, RT2hi;
+ ldr RT2hi, [%sp, #(_f + 4)];
+ adds RWlo, RT2lo;
+ ldr RT2lo, [%sp, #(_g + 0)];
+ adc RWhi, RT2hi;
+ ldr RT2hi, [%sp, #(_g + 4)];
+ adds RT3lo, RT2lo;
+ ldr RT2lo, [%sp, #(_h + 0)];
+ adc RT3hi, RT2hi;
+ ldr RT2hi, [%sp, #(_h + 4)];
+ adds RT4lo, RT2lo;
+ adc RT4hi, RT2hi;
+ stm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi}
+ sub %r0, %r0, #(4 * 8);
+ ldr RWlo, [%sp, #nblks];
+
+ sub RK, #(80 * 8);
+ subs RWlo, #1;
+ bne .Loop_blocks;
+
+.Ldone:
+ mov %r0, #STACK_MAX;
+__out:
+ add %sp, %sp, #STACK_MAX;
+ pop {%r4-%r11, %ip, %pc};
+.size _gcry_sha512_transform_arm,.-_gcry_sha512_transform_arm;
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha512-armv7-neon.S b/comm/third_party/libgcrypt/cipher/sha512-armv7-neon.S
new file mode 100644
index 0000000000..6596f2cdb2
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha512-armv7-neon.S
@@ -0,0 +1,450 @@
+/* sha512-armv7-neon.S - ARM/NEON assembly implementation of SHA-512 transform
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
+ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_NEON)
+
+.text
+
+.syntax unified
+.fpu neon
+.arm
+
+/* structure of SHA512_CONTEXT */
+#define hd_a 0
+#define hd_b ((hd_a) + 8)
+#define hd_c ((hd_b) + 8)
+#define hd_d ((hd_c) + 8)
+#define hd_e ((hd_d) + 8)
+#define hd_f ((hd_e) + 8)
+#define hd_g ((hd_f) + 8)
+
+/* register macros */
+#define RK %r2
+
+#define RA d0
+#define RB d1
+#define RC d2
+#define RD d3
+#define RE d4
+#define RF d5
+#define RG d6
+#define RH d7
+
+#define RT0 d8
+#define RT1 d9
+#define RT2 d10
+#define RT3 d11
+#define RT4 d12
+#define RT5 d13
+#define RT6 d14
+#define RT7 d15
+
+#define RT01q q4
+#define RT23q q5
+#define RT45q q6
+#define RT67q q7
+
+#define RW0 d16
+#define RW1 d17
+#define RW2 d18
+#define RW3 d19
+#define RW4 d20
+#define RW5 d21
+#define RW6 d22
+#define RW7 d23
+#define RW8 d24
+#define RW9 d25
+#define RW10 d26
+#define RW11 d27
+#define RW12 d28
+#define RW13 d29
+#define RW14 d30
+#define RW15 d31
+
+#define RW01q q8
+#define RW23q q9
+#define RW45q q10
+#define RW67q q11
+#define RW89q q12
+#define RW1011q q13
+#define RW1213q q14
+#define RW1415q q15
+
+/***********************************************************************
+ * ARM assembly implementation of sha512 transform
+ ***********************************************************************/
+#define rounds2_0_63(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw1, rw01q, rw2, rw23q, rw1415q, rw9, rw10, interleave_op, arg1) \
+ /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
+ vshr.u64 RT2, re, #14; \
+ vshl.u64 RT3, re, #64 - 14; \
+ interleave_op(arg1); \
+ vshr.u64 RT4, re, #18; \
+ vshl.u64 RT5, re, #64 - 18; \
+ vld1.64 {RT0}, [RK]!; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, re, #41; \
+ vshl.u64 RT5, re, #64 - 41; \
+ vadd.u64 RT0, RT0, rw0; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vmov.64 RT7, re; \
+ veor.64 RT1, RT2, RT3; \
+ vbsl.64 RT7, rf, rg; \
+ \
+ vadd.u64 RT1, RT1, rh; \
+ vshr.u64 RT2, ra, #28; \
+ vshl.u64 RT3, ra, #64 - 28; \
+ vadd.u64 RT1, RT1, RT0; \
+ vshr.u64 RT4, ra, #34; \
+ vshl.u64 RT5, ra, #64 - 34; \
+ vadd.u64 RT1, RT1, RT7; \
+ \
+ /* h = Sum0 (a) + Maj (a, b, c); */ \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, ra, #39; \
+ vshl.u64 RT5, ra, #64 - 39; \
+ veor.64 RT0, ra, rb; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vbsl.64 RT0, rc, rb; \
+ vadd.u64 rd, rd, RT1; /* d+=t1; */ \
+ veor.64 rh, RT2, RT3; \
+ \
+ /* t1 = g + Sum1 (d) + Ch (d, e, f) + k[t] + w[t]; */ \
+ vshr.u64 RT2, rd, #14; \
+ vshl.u64 RT3, rd, #64 - 14; \
+ vadd.u64 rh, rh, RT0; \
+ vshr.u64 RT4, rd, #18; \
+ vshl.u64 RT5, rd, #64 - 18; \
+ vadd.u64 rh, rh, RT1; /* h+=t1; */ \
+ vld1.64 {RT0}, [RK]!; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, rd, #41; \
+ vshl.u64 RT5, rd, #64 - 41; \
+ vadd.u64 RT0, RT0, rw1; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vmov.64 RT7, rd; \
+ veor.64 RT1, RT2, RT3; \
+ vbsl.64 RT7, re, rf; \
+ \
+ vadd.u64 RT1, RT1, rg; \
+ vshr.u64 RT2, rh, #28; \
+ vshl.u64 RT3, rh, #64 - 28; \
+ vadd.u64 RT1, RT1, RT0; \
+ vshr.u64 RT4, rh, #34; \
+ vshl.u64 RT5, rh, #64 - 34; \
+ vadd.u64 RT1, RT1, RT7; \
+ \
+ /* g = Sum0 (h) + Maj (h, a, b); */ \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, rh, #39; \
+ vshl.u64 RT5, rh, #64 - 39; \
+ veor.64 RT0, rh, ra; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vbsl.64 RT0, rb, ra; \
+ vadd.u64 rc, rc, RT1; /* c+=t1; */ \
+ veor.64 rg, RT2, RT3; \
+ \
+ /* w[0] += S1 (w[14]) + w[9] + S0 (w[1]); */ \
+ /* w[1] += S1 (w[15]) + w[10] + S0 (w[2]); */ \
+ \
+ /**** S0(w[1:2]) */ \
+ \
+ /* w[0:1] += w[9:10] */ \
+ /* RT23q = rw1:rw2 */ \
+ vext.u64 RT23q, rw01q, rw23q, #1; \
+ vadd.u64 rw0, rw9; \
+ vadd.u64 rg, rg, RT0; \
+ vadd.u64 rw1, rw10;\
+ vadd.u64 rg, rg, RT1; /* g+=t1; */ \
+ \
+ vshr.u64 RT45q, RT23q, #1; \
+ vshl.u64 RT67q, RT23q, #64 - 1; \
+ vshr.u64 RT01q, RT23q, #8; \
+ veor.u64 RT45q, RT45q, RT67q; \
+ vshl.u64 RT67q, RT23q, #64 - 8; \
+ veor.u64 RT45q, RT45q, RT01q; \
+ vshr.u64 RT01q, RT23q, #7; \
+ veor.u64 RT45q, RT45q, RT67q; \
+ \
+ /**** S1(w[14:15]) */ \
+ vshr.u64 RT23q, rw1415q, #6; \
+ veor.u64 RT01q, RT01q, RT45q; \
+ vshr.u64 RT45q, rw1415q, #19; \
+ vshl.u64 RT67q, rw1415q, #64 - 19; \
+ veor.u64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT45q, rw1415q, #61; \
+ veor.u64 RT23q, RT23q, RT67q; \
+ vshl.u64 RT67q, rw1415q, #64 - 61; \
+ veor.u64 RT23q, RT23q, RT45q; \
+ vadd.u64 rw01q, RT01q; /* w[0:1] += S(w[1:2]) */ \
+ veor.u64 RT01q, RT23q, RT67q;
+#define vadd_RT01q(rw01q) \
+ /* w[0:1] += S(w[14:15]) */ \
+ vadd.u64 rw01q, RT01q;
+
+#define dummy(_) /*_*/
+
+#define rounds2_64_79(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw1, interleave_op1, arg1, interleave_op2, arg2) \
+ /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
+ vshr.u64 RT2, re, #14; \
+ vshl.u64 RT3, re, #64 - 14; \
+ interleave_op1(arg1); \
+ vshr.u64 RT4, re, #18; \
+ vshl.u64 RT5, re, #64 - 18; \
+ interleave_op2(arg2); \
+ vld1.64 {RT0}, [RK]!; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, re, #41; \
+ vshl.u64 RT5, re, #64 - 41; \
+ vadd.u64 RT0, RT0, rw0; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vmov.64 RT7, re; \
+ veor.64 RT1, RT2, RT3; \
+ vbsl.64 RT7, rf, rg; \
+ \
+ vadd.u64 RT1, RT1, rh; \
+ vshr.u64 RT2, ra, #28; \
+ vshl.u64 RT3, ra, #64 - 28; \
+ vadd.u64 RT1, RT1, RT0; \
+ vshr.u64 RT4, ra, #34; \
+ vshl.u64 RT5, ra, #64 - 34; \
+ vadd.u64 RT1, RT1, RT7; \
+ \
+ /* h = Sum0 (a) + Maj (a, b, c); */ \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, ra, #39; \
+ vshl.u64 RT5, ra, #64 - 39; \
+ veor.64 RT0, ra, rb; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vbsl.64 RT0, rc, rb; \
+ vadd.u64 rd, rd, RT1; /* d+=t1; */ \
+ veor.64 rh, RT2, RT3; \
+ \
+ /* t1 = g + Sum1 (d) + Ch (d, e, f) + k[t] + w[t]; */ \
+ vshr.u64 RT2, rd, #14; \
+ vshl.u64 RT3, rd, #64 - 14; \
+ vadd.u64 rh, rh, RT0; \
+ vshr.u64 RT4, rd, #18; \
+ vshl.u64 RT5, rd, #64 - 18; \
+ vadd.u64 rh, rh, RT1; /* h+=t1; */ \
+ vld1.64 {RT0}, [RK]!; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, rd, #41; \
+ vshl.u64 RT5, rd, #64 - 41; \
+ vadd.u64 RT0, RT0, rw1; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vmov.64 RT7, rd; \
+ veor.64 RT1, RT2, RT3; \
+ vbsl.64 RT7, re, rf; \
+ \
+ vadd.u64 RT1, RT1, rg; \
+ vshr.u64 RT2, rh, #28; \
+ vshl.u64 RT3, rh, #64 - 28; \
+ vadd.u64 RT1, RT1, RT0; \
+ vshr.u64 RT4, rh, #34; \
+ vshl.u64 RT5, rh, #64 - 34; \
+ vadd.u64 RT1, RT1, RT7; \
+ \
+ /* g = Sum0 (h) + Maj (h, a, b); */ \
+ veor.64 RT23q, RT23q, RT45q; \
+ vshr.u64 RT4, rh, #39; \
+ vshl.u64 RT5, rh, #64 - 39; \
+ veor.64 RT0, rh, ra; \
+ veor.64 RT23q, RT23q, RT45q; \
+ vbsl.64 RT0, rb, ra; \
+ vadd.u64 rc, rc, RT1; /* c+=t1; */ \
+ veor.64 rg, RT2, RT3;
+#define vadd_rg_RT0(rg) \
+ vadd.u64 rg, rg, RT0;
+#define vadd_rg_RT1(rg) \
+ vadd.u64 rg, rg, RT1; /* g+=t1; */
+
+.align 3
+.globl _gcry_sha512_transform_armv7_neon
+.type _gcry_sha512_transform_armv7_neon,%function;
+
+_gcry_sha512_transform_armv7_neon:
+ /* Input:
+ * %r0: SHA512_CONTEXT
+ * %r1: data
+ * %r2: u64 k[] constants
+ * %r3: nblks
+ */
+ push {%lr};
+
+ mov %lr, #0;
+
+ /* Load context to d0-d7 */
+ vld1.64 {RA-RD}, [%r0]!;
+ vld1.64 {RE-RH}, [%r0];
+ sub %r0, #(4*8);
+
+ /* Load input to w[16], d16-d31 */
+ /* NOTE: Assumes that on ARMv7 unaligned accesses are always allowed. */
+ vld1.64 {RW0-RW3}, [%r1]!;
+ vld1.64 {RW4-RW7}, [%r1]!;
+ vld1.64 {RW8-RW11}, [%r1]!;
+ vld1.64 {RW12-RW15}, [%r1]!;
+#ifdef __ARMEL__
+ /* byteswap */
+ vrev64.8 RW01q, RW01q;
+ vrev64.8 RW23q, RW23q;
+ vrev64.8 RW45q, RW45q;
+ vrev64.8 RW67q, RW67q;
+ vrev64.8 RW89q, RW89q;
+ vrev64.8 RW1011q, RW1011q;
+ vrev64.8 RW1213q, RW1213q;
+ vrev64.8 RW1415q, RW1415q;
+#endif
+
+ /* EABI says that d8-d15 must be preserved by callee. */
+ vpush {RT0-RT7};
+
+.Loop:
+ rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, RW01q, RW2, RW23q, RW1415q, RW9, RW10, dummy, _);
+ b .Lenter_rounds;
+
+.Loop_rounds:
+ rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, RW01q, RW2, RW23q, RW1415q, RW9, RW10, vadd_RT01q, RW1415q);
+.Lenter_rounds:
+ rounds2_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW3, RW23q, RW4, RW45q, RW01q, RW11, RW12, vadd_RT01q, RW01q);
+ rounds2_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5, RW45q, RW6, RW67q, RW23q, RW13, RW14, vadd_RT01q, RW23q);
+ rounds2_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7, RW67q, RW8, RW89q, RW45q, RW15, RW0, vadd_RT01q, RW45q);
+ rounds2_0_63(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9, RW89q, RW10, RW1011q, RW67q, RW1, RW2, vadd_RT01q, RW67q);
+ rounds2_0_63(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11, RW1011q, RW12, RW1213q, RW89q, RW3, RW4, vadd_RT01q, RW89q);
+ add %lr, #16;
+ rounds2_0_63(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13, RW1213q, RW14, RW1415q, RW1011q, RW5, RW6, vadd_RT01q, RW1011q);
+ cmp %lr, #64;
+ rounds2_0_63(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15, RW1415q, RW0, RW01q, RW1213q, RW7, RW8, vadd_RT01q, RW1213q);
+ bne .Loop_rounds;
+
+ subs %r3, #1;
+
+ rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW0, RW1, vadd_RT01q, RW1415q, dummy, _);
+ rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW2, RW3, vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+ beq .Lhandle_tail;
+ vld1.64 {RW0-RW3}, [%r1]!;
+ rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5, vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+ rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7, vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+#ifdef __ARMEL__
+ vrev64.8 RW01q, RW01q;
+ vrev64.8 RW23q, RW23q;
+#endif
+ vld1.64 {RW4-RW7}, [%r1]!;
+ rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9, vadd_rg_RT0, RA, vadd_rg_RT1, RA);
+ rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11, vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+#ifdef __ARMEL__
+ vrev64.8 RW45q, RW45q;
+ vrev64.8 RW67q, RW67q;
+#endif
+ vld1.64 {RW8-RW11}, [%r1]!;
+ rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13, vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+ rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15, vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+#ifdef __ARMEL__
+ vrev64.8 RW89q, RW89q;
+ vrev64.8 RW1011q, RW1011q;
+#endif
+ vld1.64 {RW12-RW15}, [%r1]!;
+ vadd_rg_RT0(RA);
+ vadd_rg_RT1(RA);
+
+ /* Load context */
+ vld1.64 {RT0-RT3}, [%r0]!;
+ vld1.64 {RT4-RT7}, [%r0];
+ sub %r0, #(4*8);
+
+#ifdef __ARMEL__
+ vrev64.8 RW1213q, RW1213q;
+ vrev64.8 RW1415q, RW1415q;
+#endif
+
+ vadd.u64 RA, RT0;
+ vadd.u64 RB, RT1;
+ vadd.u64 RC, RT2;
+ vadd.u64 RD, RT3;
+ vadd.u64 RE, RT4;
+ vadd.u64 RF, RT5;
+ vadd.u64 RG, RT6;
+ vadd.u64 RH, RT7;
+
+ /* Store the first half of context */
+ vst1.64 {RA-RD}, [%r0]!;
+ sub RK, $(8*80);
+ vst1.64 {RE-RH}, [%r0]; /* Store the last half of context */
+ mov %lr, #0;
+ sub %r0, #(4*8);
+
+ b .Loop;
+.ltorg
+
+.Lhandle_tail:
+ rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW4, RW5, vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+ rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW6, RW7, vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+ rounds2_64_79(RA, RB, RC, RD, RE, RF, RG, RH, RW8, RW9, vadd_rg_RT0, RA, vadd_rg_RT1, RA);
+ rounds2_64_79(RG, RH, RA, RB, RC, RD, RE, RF, RW10, RW11, vadd_rg_RT0, RG, vadd_rg_RT1, RG);
+ rounds2_64_79(RE, RF, RG, RH, RA, RB, RC, RD, RW12, RW13, vadd_rg_RT0, RE, vadd_rg_RT1, RE);
+ rounds2_64_79(RC, RD, RE, RF, RG, RH, RA, RB, RW14, RW15, vadd_rg_RT0, RC, vadd_rg_RT1, RC);
+
+ /* Load context to d16-d23 */
+ vld1.64 {RW0-RW3}, [%r0]!;
+ vadd_rg_RT0(RA);
+ vld1.64 {RW4-RW7}, [%r0];
+ vadd_rg_RT1(RA);
+ sub %r0, #(4*8);
+
+ vadd.u64 RA, RW0;
+ vadd.u64 RB, RW1;
+ vadd.u64 RC, RW2;
+ vadd.u64 RD, RW3;
+ vadd.u64 RE, RW4;
+ vadd.u64 RF, RW5;
+ vadd.u64 RG, RW6;
+ vadd.u64 RH, RW7;
+
+ /* Store the first half of context */
+ vst1.64 {RA-RD}, [%r0]!;
+
+ /* Clear used registers */
+ /* d16-d31 */
+ veor.u64 RW01q, RW01q;
+ veor.u64 RW23q, RW23q;
+ veor.u64 RW45q, RW45q;
+ veor.u64 RW67q, RW67q;
+ vst1.64 {RE-RH}, [%r0]; /* Store the last half of context */
+ veor.u64 RW89q, RW89q;
+ veor.u64 RW1011q, RW1011q;
+ veor.u64 RW1213q, RW1213q;
+ veor.u64 RW1415q, RW1415q;
+ /* d8-d15 */
+ vpop {RT0-RT7};
+ /* d0-d7 (q0-q3) */
+ veor.u64 %q0, %q0;
+ veor.u64 %q1, %q1;
+ veor.u64 %q2, %q2;
+ veor.u64 %q3, %q3;
+
+ eor %r0, %r0;
+ pop {%pc};
+.size _gcry_sha512_transform_armv7_neon,.-_gcry_sha512_transform_armv7_neon;
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha512-avx-amd64.S b/comm/third_party/libgcrypt/cipher/sha512-avx-amd64.S
new file mode 100644
index 0000000000..75f7b07059
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha512-avx-amd64.S
@@ -0,0 +1,461 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Copyright (c) 2012, Intel Corporation
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are
+; met:
+;
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the
+; distribution.
+;
+; * Neither the name of the Intel Corporation nor the names of its
+; contributors may be used to endorse or promote products derived from
+; this software without specific prior written permission.
+;
+;
+; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ * by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA512)
+
+#include "asm-common-amd64.h"
+
+.intel_syntax noprefix
+
+.text
+
+/* Virtual Registers */
+#define msg rdi /* ARG1 */
+#define digest rsi /* ARG2 */
+#define msglen rdx /* ARG3 */
+#define T1 rcx
+#define T2 r8
+#define a_64 r9
+#define b_64 r10
+#define c_64 r11
+#define d_64 r12
+#define e_64 r13
+#define f_64 r14
+#define g_64 r15
+#define h_64 rbx
+#define tmp0 rax
+
+/*
+; Local variables (stack frame)
+; Note: frame_size must be an odd multiple of 8 bytes to XMM align RSP
+*/
+#define frame_W 0 /* Message Schedule */
+#define frame_W_size (80 * 8)
+#define frame_WK ((frame_W) + (frame_W_size)) /* W[t] + K[t] | W[t+1] + K[t+1] */
+#define frame_WK_size (2 * 8)
+#define frame_GPRSAVE ((frame_WK) + (frame_WK_size))
+#define frame_GPRSAVE_size (5 * 8)
+#define frame_size ((frame_GPRSAVE) + (frame_GPRSAVE_size))
+
+
+/* Useful QWORD "arrays" for simpler memory references */
+#define MSG(i) msg + 8*(i) /* Input message (arg1) */
+#define DIGEST(i) digest + 8*(i) /* Output Digest (arg2) */
+#define K_t(i) .LK512 + 8*(i) ADD_RIP /* SHA Constants (static mem) */
+#define W_t(i) rsp + frame_W + 8*(i) /* Message Schedule (stack frame) */
+#define WK_2(i) rsp + frame_WK + 8*((i) % 2) /* W[t]+K[t] (stack frame) */
+/* MSG, DIGEST, K_t, W_t are arrays */
+/* WK_2(t) points to 1 of 2 qwords at frame.WK depdending on t being odd/even */
+
+#define RORQ(p1, p2) \
+ /* shld is faster than ror on Intel Sandybridge */ \
+ shld p1, p1, (64 - p2)
+
+#define SHA512_Round(t, a, b, c, d, e, f, g, h) \
+ /* Compute Round %%t */; \
+ mov T1, f /* T1 = f */; \
+ mov tmp0, e /* tmp = e */; \
+ xor T1, g /* T1 = f ^ g */; \
+ RORQ( tmp0, 23) /* 41 ; tmp = e ror 23 */; \
+ and T1, e /* T1 = (f ^ g) & e */; \
+ xor tmp0, e /* tmp = (e ror 23) ^ e */; \
+ xor T1, g /* T1 = ((f ^ g) & e) ^ g = CH(e,f,g) */; \
+ add T1, [WK_2(t)] /* W[t] + K[t] from message scheduler */; \
+ RORQ( tmp0, 4) /* 18 ; tmp = ((e ror 23) ^ e) ror 4 */; \
+ xor tmp0, e /* tmp = (((e ror 23) ^ e) ror 4) ^ e */; \
+ mov T2, a /* T2 = a */; \
+ add T1, h /* T1 = CH(e,f,g) + W[t] + K[t] + h */; \
+ RORQ( tmp0, 14) /* 14 ; tmp = ((((e ror23)^e)ror4)^e)ror14 = S1(e) */; \
+ add T1, tmp0 /* T1 = CH(e,f,g) + W[t] + K[t] + S1(e) */; \
+ mov tmp0, a /* tmp = a */; \
+ xor T2, c /* T2 = a ^ c */; \
+ and tmp0, c /* tmp = a & c */; \
+ and T2, b /* T2 = (a ^ c) & b */; \
+ xor T2, tmp0 /* T2 = ((a ^ c) & b) ^ (a & c) = Maj(a,b,c) */; \
+ mov tmp0, a /* tmp = a */; \
+ RORQ( tmp0, 5) /* 39 ; tmp = a ror 5 */; \
+ xor tmp0, a /* tmp = (a ror 5) ^ a */; \
+ add d, T1 /* e(next_state) = d + T1 */; \
+ RORQ( tmp0, 6) /* 34 ; tmp = ((a ror 5) ^ a) ror 6 */; \
+ xor tmp0, a /* tmp = (((a ror 5) ^ a) ror 6) ^ a */; \
+ lea h, [T1 + T2] /* a(next_state) = T1 + Maj(a,b,c) */; \
+ RORQ( tmp0, 28) /* 28 ; tmp = ((((a ror5)^a)ror6)^a)ror28 = S0(a) */; \
+ add h, tmp0 /* a(next_state) = T1 + Maj(a,b,c) S0(a) */
+
+#define SHA512_2Sched_2Round_avx_PART1(t, a, b, c, d, e, f, g, h) \
+ /* \
+ ; Compute rounds %%t-2 and %%t-1 \
+ ; Compute message schedule QWORDS %%t and %%t+1 \
+ ; \
+ ; Two rounds are computed based on the values for K[t-2]+W[t-2] and \
+ ; K[t-1]+W[t-1] which were previously stored at WK_2 by the message \
+ ; scheduler. \
+ ; The two new schedule QWORDS are stored at [W_t(%%t)] and [W_t(%%t+1)]. \
+ ; They are then added to their respective SHA512 constants at \
+ ; [K_t(%%t)] and [K_t(%%t+1)] and stored at dqword [WK_2(%%t)] \
+ ; For brievity, the comments following vectored instructions only refer to \
+ ; the first of a pair of QWORDS. \
+ ; Eg. XMM4=W[t-2] really means XMM4={W[t-2]|W[t-1]} \
+ ; The computation of the message schedule and the rounds are tightly \
+ ; stitched to take advantage of instruction-level parallelism. \
+ ; For clarity, integer instructions (for the rounds calculation) are indented \
+ ; by one tab. Vectored instructions (for the message scheduler) are indented \
+ ; by two tabs. \
+ */ \
+ \
+ vmovdqa xmm4, [W_t(t-2)] /* XMM4 = W[t-2] */; \
+ vmovdqu xmm5, [W_t(t-15)] /* XMM5 = W[t-15] */; \
+ mov T1, f; \
+ vpsrlq xmm0, xmm4, 61 /* XMM0 = W[t-2]>>61 */; \
+ mov tmp0, e; \
+ vpsrlq xmm6, xmm5, 1 /* XMM6 = W[t-15]>>1 */; \
+ xor T1, g; \
+ RORQ( tmp0, 23) /* 41 */; \
+ vpsrlq xmm1, xmm4, 19 /* XMM1 = W[t-2]>>19 */; \
+ and T1, e; \
+ xor tmp0, e; \
+ vpxor xmm0, xmm0, xmm1 /* XMM0 = W[t-2]>>61 ^ W[t-2]>>19 */; \
+ xor T1, g; \
+ add T1, [WK_2(t)]; \
+ vpsrlq xmm7, xmm5, 8 /* XMM7 = W[t-15]>>8 */; \
+ RORQ( tmp0, 4) /* 18 */; \
+ vpsrlq xmm2, xmm4, 6 /* XMM2 = W[t-2]>>6 */; \
+ xor tmp0, e; \
+ mov T2, a; \
+ add T1, h; \
+ vpxor xmm6, xmm6, xmm7 /* XMM6 = W[t-15]>>1 ^ W[t-15]>>8 */; \
+ RORQ( tmp0, 14) /* 14 */; \
+ add T1, tmp0; \
+ vpsrlq xmm8, xmm5, 7 /* XMM8 = W[t-15]>>7 */; \
+ mov tmp0, a; \
+ xor T2, c; \
+ vpsllq xmm3, xmm4, (64-61) /* XMM3 = W[t-2]<<3 */; \
+ and tmp0, c; \
+ and T2, b; \
+ vpxor xmm2, xmm2, xmm3 /* XMM2 = W[t-2]>>6 ^ W[t-2]<<3 */; \
+ xor T2, tmp0; \
+ mov tmp0, a; \
+ vpsllq xmm9, xmm5, (64-1) /* XMM9 = W[t-15]<<63 */; \
+ RORQ( tmp0, 5) /* 39 */; \
+ vpxor xmm8, xmm8, xmm9 /* XMM8 = W[t-15]>>7 ^ W[t-15]<<63 */; \
+ xor tmp0, a; \
+ add d, T1; \
+ RORQ( tmp0, 6) /* 34 */; \
+ xor tmp0, a; \
+ vpxor xmm6, xmm6, xmm8 /* XMM6 = W[t-15]>>1 ^ W[t-15]>>8 ^ W[t-15]>>7 ^ W[t-15]<<63 */; \
+ lea h, [T1 + T2]; \
+ RORQ( tmp0, 28) /* 28 */; \
+ vpsllq xmm4, xmm4, (64-19) /* XMM4 = W[t-2]<<25 */; \
+ add h, tmp0
+
+#define SHA512_2Sched_2Round_avx_PART2(t, a, b, c, d, e, f, g, h) \
+ vpxor xmm0, xmm0, xmm4 /* XMM0 = W[t-2]>>61 ^ W[t-2]>>19 ^ W[t-2]<<25 */; \
+ mov T1, f; \
+ vpxor xmm0, xmm0, xmm2 /* XMM0 = s1(W[t-2]) */; \
+ mov tmp0, e; \
+ xor T1, g; \
+ vpaddq xmm0, xmm0, [W_t(t-16)] /* XMM0 = s1(W[t-2]) + W[t-16] */; \
+ vmovdqu xmm1, [W_t(t- 7)] /* XMM1 = W[t-7] */; \
+ RORQ( tmp0, 23) /* 41 */; \
+ and T1, e; \
+ xor tmp0, e; \
+ xor T1, g; \
+ vpsllq xmm5, xmm5, (64-8) /* XMM5 = W[t-15]<<56 */; \
+ add T1, [WK_2(t+1)]; \
+ vpxor xmm6, xmm6, xmm5 /* XMM6 = s0(W[t-15]) */; \
+ RORQ( tmp0, 4) /* 18 */; \
+ vpaddq xmm0, xmm0, xmm6 /* XMM0 = s1(W[t-2]) + W[t-16] + s0(W[t-15]) */; \
+ xor tmp0, e; \
+ vpaddq xmm0, xmm0, xmm1 /* XMM0 = W[t] = s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16] */; \
+ mov T2, a; \
+ add T1, h; \
+ RORQ( tmp0, 14) /* 14 */; \
+ add T1, tmp0; \
+ vmovdqa [W_t(t)], xmm0 /* Store W[t] */; \
+ vpaddq xmm0, xmm0, [K_t(t)] /* Compute W[t]+K[t] */; \
+ vmovdqa [WK_2(t)], xmm0 /* Store W[t]+K[t] for next rounds */; \
+ mov tmp0, a; \
+ xor T2, c; \
+ and tmp0, c; \
+ and T2, b; \
+ xor T2, tmp0; \
+ mov tmp0, a; \
+ RORQ( tmp0, 5) /* 39 */; \
+ xor tmp0, a; \
+ add d, T1; \
+ RORQ( tmp0, 6) /* 34 */; \
+ xor tmp0, a; \
+ lea h, [T1 + T2]; \
+ RORQ( tmp0, 28) /* 28 */; \
+ add h, tmp0
+
+#define SHA512_2Sched_2Round_avx(t, a, b, c, d, e, f, g, h) \
+ SHA512_2Sched_2Round_avx_PART1(t, a, b, c, d, e, f, g, h); \
+ SHA512_2Sched_2Round_avx_PART2(t, h, a, b, c, d, e, f, g)
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void sha512_avx(const void* M, void* D, uint64_t L);
+; Purpose: Updates the SHA512 digest stored at D with the message stored in M.
+; The size of the message pointed to by M must be an integer multiple of SHA512
+; message blocks.
+; L is the message length in SHA512 blocks
+*/
+.globl _gcry_sha512_transform_amd64_avx
+ELF(.type _gcry_sha512_transform_amd64_avx,@function;)
+.align 16
+_gcry_sha512_transform_amd64_avx:
+ CFI_STARTPROC()
+ xor eax, eax
+
+ cmp msglen, 0
+ je .Lnowork
+
+ vzeroupper
+
+ /* Allocate Stack Space */
+ sub rsp, frame_size
+ CFI_ADJUST_CFA_OFFSET(frame_size);
+
+ /* Save GPRs */
+ mov [rsp + frame_GPRSAVE + 8 * 0], rbx
+ mov [rsp + frame_GPRSAVE + 8 * 1], r12
+ mov [rsp + frame_GPRSAVE + 8 * 2], r13
+ mov [rsp + frame_GPRSAVE + 8 * 3], r14
+ mov [rsp + frame_GPRSAVE + 8 * 4], r15
+ CFI_REL_OFFSET(rbx, frame_GPRSAVE + 8 * 0);
+ CFI_REL_OFFSET(r12, frame_GPRSAVE + 8 * 1);
+ CFI_REL_OFFSET(r13, frame_GPRSAVE + 8 * 2);
+ CFI_REL_OFFSET(r14, frame_GPRSAVE + 8 * 3);
+ CFI_REL_OFFSET(r15, frame_GPRSAVE + 8 * 4);
+
+.Lupdateblock:
+
+ /* Load state variables */
+ mov a_64, [DIGEST(0)]
+ mov b_64, [DIGEST(1)]
+ mov c_64, [DIGEST(2)]
+ mov d_64, [DIGEST(3)]
+ mov e_64, [DIGEST(4)]
+ mov f_64, [DIGEST(5)]
+ mov g_64, [DIGEST(6)]
+ mov h_64, [DIGEST(7)]
+
+ /* BSWAP 2 QWORDS */
+ vmovdqa xmm1, [.LXMM_QWORD_BSWAP ADD_RIP]
+ vmovdqu xmm0, [MSG(0)]
+ vpshufb xmm0, xmm0, xmm1 /* BSWAP */
+ vmovdqa [W_t(0)], xmm0 /* Store Scheduled Pair */
+ vpaddq xmm0, xmm0, [K_t(0)] /* Compute W[t]+K[t] */
+ vmovdqa [WK_2(0)], xmm0 /* Store into WK for rounds */
+
+ #define T_2_14(t, a, b, c, d, e, f, g, h) \
+ /* BSWAP 2 QWORDS, Compute 2 Rounds */; \
+ vmovdqu xmm0, [MSG(t)]; \
+ vpshufb xmm0, xmm0, xmm1 /* BSWAP */; \
+ SHA512_Round(((t) - 2), a##_64, b##_64, c##_64, d##_64, \
+ e##_64, f##_64, g##_64, h##_64); \
+ vmovdqa [W_t(t)], xmm0 /* Store Scheduled Pair */; \
+ vpaddq xmm0, xmm0, [K_t(t)] /* Compute W[t]+K[t] */; \
+ SHA512_Round(((t) - 1), h##_64, a##_64, b##_64, c##_64, \
+ d##_64, e##_64, f##_64, g##_64); \
+ vmovdqa [WK_2(t)], xmm0 /* W[t]+K[t] into WK */
+
+ #define T_16_78(t, a, b, c, d, e, f, g, h) \
+ SHA512_2Sched_2Round_avx((t), a##_64, b##_64, c##_64, d##_64, \
+ e##_64, f##_64, g##_64, h##_64)
+
+ #define T_80(t, a, b, c, d, e, f, g, h) \
+ /* Compute 2 Rounds */; \
+ SHA512_Round((t - 2), a##_64, b##_64, c##_64, d##_64, \
+ e##_64, f##_64, g##_64, h##_64); \
+ SHA512_Round((t - 1), h##_64, a##_64, b##_64, c##_64, \
+ d##_64, e##_64, f##_64, g##_64)
+
+ T_2_14(2, a, b, c, d, e, f, g, h)
+ T_2_14(4, g, h, a, b, c, d, e, f)
+ T_2_14(6, e, f, g, h, a, b, c, d)
+ T_2_14(8, c, d, e, f, g, h, a, b)
+ T_2_14(10, a, b, c, d, e, f, g, h)
+ T_2_14(12, g, h, a, b, c, d, e, f)
+ T_2_14(14, e, f, g, h, a, b, c, d)
+ T_16_78(16, c, d, e, f, g, h, a, b)
+ T_16_78(18, a, b, c, d, e, f, g, h)
+ T_16_78(20, g, h, a, b, c, d, e, f)
+ T_16_78(22, e, f, g, h, a, b, c, d)
+ T_16_78(24, c, d, e, f, g, h, a, b)
+ T_16_78(26, a, b, c, d, e, f, g, h)
+ T_16_78(28, g, h, a, b, c, d, e, f)
+ T_16_78(30, e, f, g, h, a, b, c, d)
+ T_16_78(32, c, d, e, f, g, h, a, b)
+ T_16_78(34, a, b, c, d, e, f, g, h)
+ T_16_78(36, g, h, a, b, c, d, e, f)
+ T_16_78(38, e, f, g, h, a, b, c, d)
+ T_16_78(40, c, d, e, f, g, h, a, b)
+ T_16_78(42, a, b, c, d, e, f, g, h)
+ T_16_78(44, g, h, a, b, c, d, e, f)
+ T_16_78(46, e, f, g, h, a, b, c, d)
+ T_16_78(48, c, d, e, f, g, h, a, b)
+ T_16_78(50, a, b, c, d, e, f, g, h)
+ T_16_78(52, g, h, a, b, c, d, e, f)
+ T_16_78(54, e, f, g, h, a, b, c, d)
+ T_16_78(56, c, d, e, f, g, h, a, b)
+ T_16_78(58, a, b, c, d, e, f, g, h)
+ T_16_78(60, g, h, a, b, c, d, e, f)
+ T_16_78(62, e, f, g, h, a, b, c, d)
+ T_16_78(64, c, d, e, f, g, h, a, b)
+ T_16_78(66, a, b, c, d, e, f, g, h)
+ T_16_78(68, g, h, a, b, c, d, e, f)
+ T_16_78(70, e, f, g, h, a, b, c, d)
+ T_16_78(72, c, d, e, f, g, h, a, b)
+ T_16_78(74, a, b, c, d, e, f, g, h)
+ T_16_78(76, g, h, a, b, c, d, e, f)
+ T_16_78(78, e, f, g, h, a, b, c, d)
+ T_80(80, c, d, e, f, g, h, a, b)
+
+ /* Update digest */
+ add [DIGEST(0)], a_64
+ add [DIGEST(1)], b_64
+ add [DIGEST(2)], c_64
+ add [DIGEST(3)], d_64
+ add [DIGEST(4)], e_64
+ add [DIGEST(5)], f_64
+ add [DIGEST(6)], g_64
+ add [DIGEST(7)], h_64
+
+ /* Advance to next message block */
+ add msg, 16*8
+ dec msglen
+ jnz .Lupdateblock
+
+ /* Restore GPRs */
+ mov rbx, [rsp + frame_GPRSAVE + 8 * 0]
+ mov r12, [rsp + frame_GPRSAVE + 8 * 1]
+ mov r13, [rsp + frame_GPRSAVE + 8 * 2]
+ mov r14, [rsp + frame_GPRSAVE + 8 * 3]
+ mov r15, [rsp + frame_GPRSAVE + 8 * 4]
+ CFI_RESTORE(rbx)
+ CFI_RESTORE(r12)
+ CFI_RESTORE(r13)
+ CFI_RESTORE(r14)
+ CFI_RESTORE(r15)
+
+ vzeroall
+
+ /* Burn stack */
+ mov eax, 0
+.Lerase_stack:
+ vmovdqu [rsp + rax], ymm0
+ add eax, 32
+ cmp eax, frame_W_size
+ jne .Lerase_stack
+ vmovdqu [rsp + frame_WK], xmm0
+ xor eax, eax
+
+ /* Restore Stack Pointer */
+ add rsp, frame_size
+ CFI_ADJUST_CFA_OFFSET(-frame_size);
+
+.Lnowork:
+ ret
+ CFI_ENDPROC()
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Binary Data
+*/
+
+.align 16
+
+/* Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. */
+.LXMM_QWORD_BSWAP:
+ .octa 0x08090a0b0c0d0e0f0001020304050607
+
+/* K[t] used in SHA512 hashing */
+.LK512:
+ .quad 0x428a2f98d728ae22,0x7137449123ef65cd
+ .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+ .quad 0x3956c25bf348b538,0x59f111f1b605d019
+ .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
+ .quad 0xd807aa98a3030242,0x12835b0145706fbe
+ .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+ .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
+ .quad 0x9bdc06a725c71235,0xc19bf174cf692694
+ .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
+ .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+ .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
+ .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+ .quad 0x983e5152ee66dfab,0xa831c66d2db43210
+ .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
+ .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
+ .quad 0x06ca6351e003826f,0x142929670a0e6e70
+ .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
+ .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+ .quad 0x650a73548baf63de,0x766a0abb3c77b2a8
+ .quad 0x81c2c92e47edaee6,0x92722c851482353b
+ .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
+ .quad 0xc24b8b70d0f89791,0xc76c51a30654be30
+ .quad 0xd192e819d6ef5218,0xd69906245565a910
+ .quad 0xf40e35855771202a,0x106aa07032bbd1b8
+ .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
+ .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+ .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+ .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+ .quad 0x748f82ee5defb2fc,0x78a5636f43172f60
+ .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
+ .quad 0x90befffa23631e28,0xa4506cebde82bde9
+ .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
+ .quad 0xca273eceea26619c,0xd186b8c721c0c207
+ .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+ .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
+ .quad 0x113f9804bef90dae,0x1b710b35131c471b
+ .quad 0x28db77f523047d84,0x32caab7b40c72493
+ .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+ .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+ .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha512-avx2-bmi2-amd64.S b/comm/third_party/libgcrypt/cipher/sha512-avx2-bmi2-amd64.S
new file mode 100644
index 0000000000..7f119e6c10
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha512-avx2-bmi2-amd64.S
@@ -0,0 +1,502 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Copyright (c) 2012, Intel Corporation
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are
+; met:
+;
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the
+; distribution.
+;
+; * Neither the name of the Intel Corporation nor the names of its
+; contributors may be used to endorse or promote products derived from
+; this software without specific prior written permission.
+;
+;
+; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; This code schedules 1 blocks at a time, with 4 lanes per block
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ * by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+ defined(USE_SHA512)
+
+#include "asm-common-amd64.h"
+
+.intel_syntax noprefix
+
+.text
+
+/* Virtual Registers */
+#define Y_0 ymm4
+#define Y_1 ymm5
+#define Y_2 ymm6
+#define Y_3 ymm7
+
+#define YTMP0 ymm0
+#define YTMP1 ymm1
+#define YTMP2 ymm2
+#define YTMP3 ymm3
+#define YTMP4 ymm8
+#define XFER YTMP0
+
+#define BYTE_FLIP_MASK ymm9
+#define MASK_YMM_LO ymm10
+#define MASK_YMM_LOx xmm10
+
+#define INP rdi /* 1st arg */
+#define CTX rsi /* 2nd arg */
+#define NUM_BLKS rdx /* 3rd arg */
+#define c rcx
+#define d r8
+#define e rdx
+#define y3 rdi
+
+#define TBL rbp
+
+#define a rax
+#define b rbx
+
+#define f r9
+#define g r10
+#define h r11
+
+#define T1 r12
+#define y0 r13
+#define y1 r14
+#define y2 r15
+
+#define y4 r12
+
+/* Local variables (stack frame) */
+#define frame_XFER 0
+#define frame_XFER_size (4*4*8)
+#define frame_SRND (frame_XFER + frame_XFER_size)
+#define frame_SRND_size (1*8)
+#define frame_INP (frame_SRND + frame_SRND_size)
+#define frame_INP_size (1*8)
+#define frame_NBLKS (frame_INP + frame_INP_size)
+#define frame_NBLKS_size (1*8)
+#define frame_RSPSAVE (frame_NBLKS + frame_NBLKS_size)
+#define frame_RSPSAVE_size (1*8)
+#define frame_GPRSAVE (frame_RSPSAVE + frame_RSPSAVE_size)
+#define frame_GPRSAVE_size (6*8)
+#define frame_size (frame_GPRSAVE + frame_GPRSAVE_size)
+
+#define VMOVDQ vmovdqu /*; assume buffers not aligned */
+
+/* addm [mem], reg */
+/* Add reg to mem using reg-mem add and store */
+#define addm(p1, p2) \
+ add p2, p1; \
+ mov p1, p2;
+
+
+/* COPY_YMM_AND_BSWAP ymm, [mem], byte_flip_mask */
+/* Load ymm with mem and byte swap each dword */
+#define COPY_YMM_AND_BSWAP(p1, p2, p3) \
+ VMOVDQ p1, p2; \
+ vpshufb p1, p1, p3
+
+/* %macro MY_VPALIGNR YDST, YSRC1, YSRC2, RVAL */
+/* YDST = {YSRC1, YSRC2} >> RVAL*8 */
+#define MY_VPALIGNR(YDST, YSRC1, YSRC2, RVAL) \
+ vperm2i128 YDST, YSRC1, YSRC2, 0x3 /* YDST = {YS1_LO, YS2_HI} */; \
+ vpalignr YDST, YDST, YSRC2, RVAL /* YDST = {YDS1, YS2} >> RVAL*8 */
+
+#define ONE_ROUND_PART1(XFERIN, a, b, c, d, e, f, g, h) \
+ /* h += Sum1 (e) + Ch (e, f, g) + (k[t] + w[0]); \
+ * d += h; \
+ * h += Sum0 (a) + Maj (a, b, c); \
+ * \
+ * Ch(x, y, z) => ((x & y) + (~x & z)) \
+ * Maj(x, y, z) => ((x & y) + (z & (x ^ y))) \
+ */ \
+ \
+ mov y3, e; \
+ add h, [XFERIN]; \
+ and y3, f; \
+ rorx y0, e, 41; \
+ rorx y1, e, 18; \
+ lea h, [h + y3]; \
+ andn y3, e, g; \
+ rorx T1, a, 34; \
+ xor y0, y1; \
+ lea h, [h + y3]
+
+#define ONE_ROUND_PART2(a, b, c, d, e, f, g, h) \
+ rorx y2, a, 39; \
+ rorx y1, e, 14; \
+ mov y3, a; \
+ xor T1, y2; \
+ xor y0, y1; \
+ xor y3, b; \
+ lea h, [h + y0]; \
+ mov y0, a; \
+ rorx y2, a, 28; \
+ add d, h; \
+ and y3, c; \
+ xor T1, y2; \
+ lea h, [h + y3]; \
+ lea h, [h + T1]; \
+ and y0, b; \
+ lea h, [h + y0]
+
+#define ONE_ROUND(XFERIN, a, b, c, d, e, f, g, h) \
+ ONE_ROUND_PART1(XFERIN, a, b, c, d, e, f, g, h); \
+ ONE_ROUND_PART2(a, b, c, d, e, f, g, h)
+
+#define FOUR_ROUNDS_AND_SCHED(X, Y_0, Y_1, Y_2, Y_3, a, b, c, d, e, f, g, h) \
+ /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */; \
+ /* Extract w[t-7] */; \
+ MY_VPALIGNR( YTMP0, Y_3, Y_2, 8) /* YTMP0 = W[-7] */; \
+ /* Calculate w[t-16] + w[t-7] */; \
+ vpaddq YTMP0, YTMP0, Y_0 /* YTMP0 = W[-7] + W[-16] */; \
+ /* Extract w[t-15] */; \
+ MY_VPALIGNR( YTMP1, Y_1, Y_0, 8) /* YTMP1 = W[-15] */; \
+ \
+ /* Calculate sigma0 */; \
+ \
+ /* Calculate w[t-15] ror 1 */; \
+ vpsrlq YTMP2, YTMP1, 1; \
+ vpsllq YTMP3, YTMP1, (64-1); \
+ vpor YTMP3, YTMP3, YTMP2 /* YTMP3 = W[-15] ror 1 */; \
+ /* Calculate w[t-15] shr 7 */; \
+ vpsrlq YTMP4, YTMP1, 7 /* YTMP4 = W[-15] >> 7 */; \
+ \
+ ONE_ROUND(rsp+frame_XFER+0*8+X*32, a, b, c, d, e, f, g, h); \
+ \
+ /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */; \
+ /* Calculate w[t-15] ror 8 */; \
+ vpsrlq YTMP2, YTMP1, 8; \
+ vpsllq YTMP1, YTMP1, (64-8); \
+ vpor YTMP1, YTMP1, YTMP2 /* YTMP1 = W[-15] ror 8 */; \
+ /* XOR the three components */; \
+ vpxor YTMP3, YTMP3, YTMP4 /* YTMP3 = W[-15] ror 1 ^ W[-15] >> 7 */; \
+ vpxor YTMP1, YTMP3, YTMP1 /* YTMP1 = s0 */; \
+ \
+ /* Add three components, w[t-16], w[t-7] and sigma0 */; \
+ vpaddq YTMP0, YTMP0, YTMP1 /* YTMP0 = W[-16] + W[-7] + s0 */; \
+ /* Move to appropriate lanes for calculating w[16] and w[17] */; \
+ vperm2i128 Y_0, YTMP0, YTMP0, 0x0 /* Y_0 = W[-16] + W[-7] + s0 {BABA} */; \
+ /* Move to appropriate lanes for calculating w[18] and w[19] */; \
+ vpand YTMP0, YTMP0, MASK_YMM_LO /* YTMP0 = W[-16] + W[-7] + s0 {DC00} */; \
+ \
+ /* Calculate w[16] and w[17] in both 128 bit lanes */; \
+ \
+ /* Calculate sigma1 for w[16] and w[17] on both 128 bit lanes */; \
+ vperm2i128 YTMP2, Y_3, Y_3, 0x11 /* YTMP2 = W[-2] {BABA} */; \
+ vpsrlq YTMP4, YTMP2, 6 /* YTMP4 = W[-2] >> 6 {BABA} */; \
+ \
+ ONE_ROUND(rsp+frame_XFER+1*8+X*32, h, a, b, c, d, e, f, g); \
+ \
+ /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */; \
+ vpsrlq YTMP3, YTMP2, 19 /* YTMP3 = W[-2] >> 19 {BABA} */; \
+ vpsllq YTMP1, YTMP2, (64-19) /* YTMP1 = W[-2] << 19 {BABA} */; \
+ vpor YTMP3, YTMP3, YTMP1 /* YTMP3 = W[-2] ror 19 {BABA} */; \
+ vpxor YTMP4, YTMP4, YTMP3 /* YTMP4 = W[-2] ror 19 ^ W[-2] >> 6 {BABA} */; \
+ vpsrlq YTMP3, YTMP2, 61 /* YTMP3 = W[-2] >> 61 {BABA} */; \
+ vpsllq YTMP1, YTMP2, (64-61) /* YTMP1 = W[-2] << 61 {BABA} */; \
+ vpor YTMP3, YTMP3, YTMP1 /* YTMP3 = W[-2] ror 61 {BABA} */; \
+ vpxor YTMP4, YTMP4, YTMP3 /* YTMP4 = s1 = (W[-2] ror 19) ^ (W[-2] ror 61) ^ (W[-2] >> 6) {BABA} */; \
+ \
+ /* Add sigma1 to the other compunents to get w[16] and w[17] */; \
+ vpaddq Y_0, Y_0, YTMP4 /* Y_0 = {W[1], W[0], W[1], W[0]} */; \
+ \
+ /* Calculate sigma1 for w[18] and w[19] for upper 128 bit lane */; \
+ vpsrlq YTMP4, Y_0, 6 /* YTMP4 = W[-2] >> 6 {DC--} */; \
+ \
+ ONE_ROUND(rsp+frame_XFER+2*8+X*32, g, h, a, b, c, d, e, f); \
+ \
+ /*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */; \
+ vpsrlq YTMP3, Y_0, 19 /* YTMP3 = W[-2] >> 19 {DC--} */; \
+ vpsllq YTMP1, Y_0, (64-19) /* YTMP1 = W[-2] << 19 {DC--} */; \
+ vpor YTMP3, YTMP3, YTMP1 /* YTMP3 = W[-2] ror 19 {DC--} */; \
+ vpxor YTMP4, YTMP4, YTMP3 /* YTMP4 = W[-2] ror 19 ^ W[-2] >> 6 {DC--} */; \
+ vpsrlq YTMP3, Y_0, 61 /* YTMP3 = W[-2] >> 61 {DC--} */; \
+ vpsllq YTMP1, Y_0, (64-61) /* YTMP1 = W[-2] << 61 {DC--} */; \
+ vpor YTMP3, YTMP3, YTMP1 /* YTMP3 = W[-2] ror 61 {DC--} */; \
+ vpxor YTMP4, YTMP4, YTMP3 /* YTMP4 = s1 = (W[-2] ror 19) ^ (W[-2] ror 61) ^ (W[-2] >> 6) {DC--} */; \
+ \
+ /* Add the sigma0 + w[t-7] + w[t-16] for w[18] and w[19] to newly calculated sigma1 to get w[18] and w[19] */; \
+ vpaddq YTMP2, YTMP0, YTMP4 /* YTMP2 = {W[3], W[2], --, --} */; \
+ \
+ /* Form w[19, w[18], w17], w[16] */; \
+ vpblendd Y_0, Y_0, YTMP2, 0xF0 /* Y_0 = {W[3], W[2], W[1], W[0]} */; \
+ \
+ ONE_ROUND_PART1(rsp+frame_XFER+3*8+X*32, f, g, h, a, b, c, d, e); \
+ vpaddq XFER, Y_0, [TBL + (4+X)*32]; \
+ vmovdqa [rsp + frame_XFER + X*32], XFER; \
+ ONE_ROUND_PART2(f, g, h, a, b, c, d, e)
+
+#define DO_4ROUNDS(X, a, b, c, d, e, f, g, h) \
+ ONE_ROUND(rsp+frame_XFER+0*8+X*32, a, b, c, d, e, f, g, h); \
+ ONE_ROUND(rsp+frame_XFER+1*8+X*32, h, a, b, c, d, e, f, g); \
+ ONE_ROUND(rsp+frame_XFER+2*8+X*32, g, h, a, b, c, d, e, f); \
+ ONE_ROUND(rsp+frame_XFER+3*8+X*32, f, g, h, a, b, c, d, e)
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void sha512_rorx(const void* M, void* D, uint64_t L);
+; Purpose: Updates the SHA512 digest stored at D with the message stored in M.
+; The size of the message pointed to by M must be an integer multiple of SHA512
+; message blocks.
+; L is the message length in SHA512 blocks
+*/
+.globl _gcry_sha512_transform_amd64_avx2
+ELF(.type _gcry_sha512_transform_amd64_avx2,@function;)
+.align 16
+_gcry_sha512_transform_amd64_avx2:
+ CFI_STARTPROC()
+ xor eax, eax
+
+ cmp rdx, 0
+ je .Lnowork
+
+ vzeroupper
+
+ /* Allocate Stack Space */
+ mov rax, rsp
+ CFI_DEF_CFA_REGISTER(rax);
+ sub rsp, frame_size
+ and rsp, ~(0x40 - 1)
+ mov [rsp + frame_RSPSAVE], rax
+ CFI_CFA_ON_STACK(frame_RSPSAVE, 0)
+
+ /* Save GPRs */
+ mov [rsp + frame_GPRSAVE + 8 * 0], rbp
+ mov [rsp + frame_GPRSAVE + 8 * 1], rbx
+ mov [rsp + frame_GPRSAVE + 8 * 2], r12
+ mov [rsp + frame_GPRSAVE + 8 * 3], r13
+ mov [rsp + frame_GPRSAVE + 8 * 4], r14
+ mov [rsp + frame_GPRSAVE + 8 * 5], r15
+ CFI_REG_ON_STACK(rbp, frame_GPRSAVE + 8 * 0)
+ CFI_REG_ON_STACK(rbx, frame_GPRSAVE + 8 * 1)
+ CFI_REG_ON_STACK(r12, frame_GPRSAVE + 8 * 2)
+ CFI_REG_ON_STACK(r13, frame_GPRSAVE + 8 * 3)
+ CFI_REG_ON_STACK(r14, frame_GPRSAVE + 8 * 4)
+ CFI_REG_ON_STACK(r15, frame_GPRSAVE + 8 * 5)
+
+ mov [rsp + frame_NBLKS], NUM_BLKS
+
+ /*; load initial digest */
+ mov a,[8*0 + CTX]
+ mov b,[8*1 + CTX]
+ mov c,[8*2 + CTX]
+ mov d,[8*3 + CTX]
+ mov e,[8*4 + CTX]
+ mov f,[8*5 + CTX]
+ mov g,[8*6 + CTX]
+ mov h,[8*7 + CTX]
+
+ vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+ vmovdqa MASK_YMM_LO, [.LMASK_YMM_LO ADD_RIP]
+
+ lea TBL,[.LK512 ADD_RIP]
+
+ /*; byte swap first 16 dwords */
+ COPY_YMM_AND_BSWAP(Y_0, [INP + 0*32], BYTE_FLIP_MASK)
+ COPY_YMM_AND_BSWAP(Y_1, [INP + 1*32], BYTE_FLIP_MASK)
+ COPY_YMM_AND_BSWAP(Y_2, [INP + 2*32], BYTE_FLIP_MASK)
+ COPY_YMM_AND_BSWAP(Y_3, [INP + 3*32], BYTE_FLIP_MASK)
+
+ add INP, 128
+ mov [rsp + frame_INP], INP
+
+ vpaddq XFER, Y_0, [TBL + 0*32]
+ vmovdqa [rsp + frame_XFER + 0*32], XFER
+ vpaddq XFER, Y_1, [TBL + 1*32]
+ vmovdqa [rsp + frame_XFER + 1*32], XFER
+ vpaddq XFER, Y_2, [TBL + 2*32]
+ vmovdqa [rsp + frame_XFER + 2*32], XFER
+ vpaddq XFER, Y_3, [TBL + 3*32]
+ vmovdqa [rsp + frame_XFER + 3*32], XFER
+
+ /*; schedule 64 input dwords, by doing 12 rounds of 4 each */
+ mov qword ptr [rsp + frame_SRND], 4
+
+.align 16
+.Loop0:
+ FOUR_ROUNDS_AND_SCHED(0, Y_0, Y_1, Y_2, Y_3, a, b, c, d, e, f, g, h)
+ FOUR_ROUNDS_AND_SCHED(1, Y_1, Y_2, Y_3, Y_0, e, f, g, h, a, b, c, d)
+ FOUR_ROUNDS_AND_SCHED(2, Y_2, Y_3, Y_0, Y_1, a, b, c, d, e, f, g, h)
+ FOUR_ROUNDS_AND_SCHED(3, Y_3, Y_0, Y_1, Y_2, e, f, g, h, a, b, c, d)
+ add TBL, 4*32
+
+ sub qword ptr [rsp + frame_SRND], 1
+ jne .Loop0
+
+ sub qword ptr [rsp + frame_NBLKS], 1
+ je .Ldone_hash
+
+ mov INP, [rsp + frame_INP]
+
+ lea TBL,[.LK512 ADD_RIP]
+
+ /* load next block and byte swap */
+ COPY_YMM_AND_BSWAP(Y_0, [INP + 0*32], BYTE_FLIP_MASK)
+ COPY_YMM_AND_BSWAP(Y_1, [INP + 1*32], BYTE_FLIP_MASK)
+ COPY_YMM_AND_BSWAP(Y_2, [INP + 2*32], BYTE_FLIP_MASK)
+ COPY_YMM_AND_BSWAP(Y_3, [INP + 3*32], BYTE_FLIP_MASK)
+
+ add INP, 128
+ mov [rsp + frame_INP], INP
+
+ DO_4ROUNDS(0, a, b, c, d, e, f, g, h)
+ vpaddq XFER, Y_0, [TBL + 0*32]
+ vmovdqa [rsp + frame_XFER + 0*32], XFER
+ DO_4ROUNDS(1, e, f, g, h, a, b, c, d)
+ vpaddq XFER, Y_1, [TBL + 1*32]
+ vmovdqa [rsp + frame_XFER + 1*32], XFER
+ DO_4ROUNDS(2, a, b, c, d, e, f, g, h)
+ vpaddq XFER, Y_2, [TBL + 2*32]
+ vmovdqa [rsp + frame_XFER + 2*32], XFER
+ DO_4ROUNDS(3, e, f, g, h, a, b, c, d)
+ vpaddq XFER, Y_3, [TBL + 3*32]
+ vmovdqa [rsp + frame_XFER + 3*32], XFER
+
+ addm([8*0 + CTX],a)
+ addm([8*1 + CTX],b)
+ addm([8*2 + CTX],c)
+ addm([8*3 + CTX],d)
+ addm([8*4 + CTX],e)
+ addm([8*5 + CTX],f)
+ addm([8*6 + CTX],g)
+ addm([8*7 + CTX],h)
+
+ /*; schedule 64 input dwords, by doing 12 rounds of 4 each */
+ mov qword ptr [rsp + frame_SRND],4
+
+ jmp .Loop0
+
+.Ldone_hash:
+ vzeroall
+
+ DO_4ROUNDS(0, a, b, c, d, e, f, g, h)
+ vmovdqa [rsp + frame_XFER + 0*32], ymm0 /* burn stack */
+ DO_4ROUNDS(1, e, f, g, h, a, b, c, d)
+ vmovdqa [rsp + frame_XFER + 1*32], ymm0 /* burn stack */
+ DO_4ROUNDS(2, a, b, c, d, e, f, g, h)
+ vmovdqa [rsp + frame_XFER + 2*32], ymm0 /* burn stack */
+ DO_4ROUNDS(3, e, f, g, h, a, b, c, d)
+ vmovdqa [rsp + frame_XFER + 3*32], ymm0 /* burn stack */
+
+ addm([8*0 + CTX],a)
+ xor eax, eax /* burn stack */
+ addm([8*1 + CTX],b)
+ addm([8*2 + CTX],c)
+ addm([8*3 + CTX],d)
+ addm([8*4 + CTX],e)
+ addm([8*5 + CTX],f)
+ addm([8*6 + CTX],g)
+ addm([8*7 + CTX],h)
+
+ /* Restore GPRs */
+ mov rbp, [rsp + frame_GPRSAVE + 8 * 0]
+ mov rbx, [rsp + frame_GPRSAVE + 8 * 1]
+ mov r12, [rsp + frame_GPRSAVE + 8 * 2]
+ mov r13, [rsp + frame_GPRSAVE + 8 * 3]
+ mov r14, [rsp + frame_GPRSAVE + 8 * 4]
+ mov r15, [rsp + frame_GPRSAVE + 8 * 5]
+ CFI_RESTORE(rbp)
+ CFI_RESTORE(rbx)
+ CFI_RESTORE(r12)
+ CFI_RESTORE(r13)
+ CFI_RESTORE(r14)
+ CFI_RESTORE(r15)
+
+ /* Restore Stack Pointer */
+ mov rsp, [rsp + frame_RSPSAVE]
+ CFI_DEF_CFA_REGISTER(rsp)
+
+.Lnowork:
+ ret
+ CFI_ENDPROC()
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+/*;; Binary Data */
+
+.align 64
+/* K[t] used in SHA512 hashing */
+.LK512:
+ .quad 0x428a2f98d728ae22,0x7137449123ef65cd
+ .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+ .quad 0x3956c25bf348b538,0x59f111f1b605d019
+ .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
+ .quad 0xd807aa98a3030242,0x12835b0145706fbe
+ .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+ .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
+ .quad 0x9bdc06a725c71235,0xc19bf174cf692694
+ .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
+ .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+ .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
+ .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+ .quad 0x983e5152ee66dfab,0xa831c66d2db43210
+ .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
+ .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
+ .quad 0x06ca6351e003826f,0x142929670a0e6e70
+ .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
+ .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+ .quad 0x650a73548baf63de,0x766a0abb3c77b2a8
+ .quad 0x81c2c92e47edaee6,0x92722c851482353b
+ .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
+ .quad 0xc24b8b70d0f89791,0xc76c51a30654be30
+ .quad 0xd192e819d6ef5218,0xd69906245565a910
+ .quad 0xf40e35855771202a,0x106aa07032bbd1b8
+ .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
+ .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+ .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+ .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+ .quad 0x748f82ee5defb2fc,0x78a5636f43172f60
+ .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
+ .quad 0x90befffa23631e28,0xa4506cebde82bde9
+ .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
+ .quad 0xca273eceea26619c,0xd186b8c721c0c207
+ .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+ .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
+ .quad 0x113f9804bef90dae,0x1b710b35131c471b
+ .quad 0x28db77f523047d84,0x32caab7b40c72493
+ .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+ .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+ .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
+
+.align 32
+
+/* Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. */
+.LPSHUFFLE_BYTE_FLIP_MASK: .octa 0x08090a0b0c0d0e0f0001020304050607
+ .octa 0x18191a1b1c1d1e1f1011121314151617
+
+.LMASK_YMM_LO: .octa 0x00000000000000000000000000000000
+ .octa 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha512-ppc.c b/comm/third_party/libgcrypt/cipher/sha512-ppc.c
new file mode 100644
index 0000000000..31ea25bf9a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha512-ppc.c
@@ -0,0 +1,969 @@
+/* sha512-ppc.c - PowerPC vcrypto implementation of SHA-512 transform
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(ENABLE_PPC_CRYPTO_SUPPORT) && \
+ defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) && \
+ defined(USE_SHA512) && \
+ __GNUC__ >= 4
+
+#include <altivec.h>
+#include "bufhelp.h"
+
+
+typedef vector unsigned char vector16x_u8;
+typedef vector unsigned long long vector2x_u64;
+
+
+#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
+
+
+static const u64 K[80] =
+ {
+ U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
+ U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
+ U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
+ U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
+ U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
+ U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
+ U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
+ U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
+ U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
+ U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
+ U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
+ U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
+ U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
+ U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
+ U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
+ U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
+ U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
+ U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
+ U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
+ U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
+ U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
+ U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
+ U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
+ U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
+ U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
+ U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
+ U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
+ U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
+ U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
+ U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
+ U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
+ U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
+ U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
+ U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
+ U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
+ U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
+ U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
+ U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
+ U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
+ U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
+ };
+
+
+static ASM_FUNC_ATTR_INLINE u64
+ror64 (u64 v, u64 shift)
+{
+ return (v >> (shift & 63)) ^ (v << ((64 - shift) & 63));
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+vec_rol_elems(vector2x_u64 v, unsigned int idx)
+{
+#ifndef WORDS_BIGENDIAN
+ return vec_sld (v, v, (16 - (8 * idx)) & 15);
+#else
+ return vec_sld (v, v, (8 * idx) & 15);
+#endif
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+vec_merge_idx0_elems(vector2x_u64 v0, vector2x_u64 v1)
+{
+ return vec_mergeh (v0, v1);
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+vec_vshasigma_u64(vector2x_u64 v, unsigned int a, unsigned int b)
+{
+ __asm__ ("vshasigmad %0,%1,%2,%3"
+ : "=v" (v)
+ : "v" (v), "g" (a), "g" (b)
+ : "memory");
+ return v;
+}
+
+
+static ASM_FUNC_ATTR_INLINE vector2x_u64
+vec_u64_load(unsigned long offset, const void *ptr)
+{
+ vector2x_u64 vecu64;
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ ("lxvd2x %x0,0,%1\n\t"
+ : "=wa" (vecu64)
+ : "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ ("lxvd2x %x0,%1,%2\n\t"
+ : "=wa" (vecu64)
+ : "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+#ifndef WORDS_BIGENDIAN
+ __asm__ ("xxswapd %x0, %x1"
+ : "=wa" (vecu64)
+ : "wa" (vecu64));
+#endif
+ return vecu64;
+}
+
+
+static ASM_FUNC_ATTR_INLINE void
+vec_u64_store(vector2x_u64 vecu64, unsigned long offset, void *ptr)
+{
+#ifndef WORDS_BIGENDIAN
+ __asm__ ("xxswapd %x0, %x1"
+ : "=wa" (vecu64)
+ : "wa" (vecu64));
+#endif
+#if __GNUC__ >= 4
+ if (__builtin_constant_p (offset) && offset == 0)
+ __asm__ ("stxvd2x %x0,0,%1\n\t"
+ :
+ : "wa" (vecu64), "r" ((uintptr_t)ptr)
+ : "memory");
+ else
+#endif
+ __asm__ ("stxvd2x %x0,%1,%2\n\t"
+ :
+ : "wa" (vecu64), "r" (offset), "r" ((uintptr_t)ptr)
+ : "memory", "r0");
+}
+
+
+/* SHA2 round in vector registers */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h); \
+ t1 += ((k) + (w)); \
+ t1 += Cho((e),(f),(g)); \
+ t1 += Sum1((e)); \
+ t2 = Sum0((a)); \
+ t2 += Maj((a),(b),(c)); \
+ d += t1; \
+ h = t1 + t2; \
+ } while (0)
+
+#define Cho(b, c, d) (vec_sel(d, c, b))
+
+#define Maj(c, d, b) (vec_sel(c, b, c ^ d))
+
+#define Sum0(x) (vec_vshasigma_u64(x, 1, 0))
+
+#define Sum1(x) (vec_vshasigma_u64(x, 1, 15))
+
+
+/* Message expansion on general purpose registers */
+#define S0(x) (ror64 ((x), 1) ^ ror64 ((x), 8) ^ ((x) >> 7))
+#define S1(x) (ror64 ((x), 19) ^ ror64 ((x), 61) ^ ((x) >> 6))
+
+#define I(i) ( w[i] = buf_get_be64(data + i * 8) )
+#define WN(i) ({ w[i&0x0f] += w[(i-7) &0x0f]; \
+ w[i&0x0f] += S0(w[(i-15)&0x0f]); \
+ w[i&0x0f] += S1(w[(i-2) &0x0f]); \
+ w[i&0x0f]; })
+#define W(i) ({ u64 r = w[i&0x0f]; WN(i); r; })
+#define L(i) w[i&0x0f]
+
+
+unsigned int ASM_FUNC_ATTR
+_gcry_sha512_transform_ppc8(u64 state[8],
+ const unsigned char *data, size_t nblks)
+{
+ /* GPRs used for message expansion as vector intrinsics based generates
+ * slower code. */
+ vector2x_u64 h0, h1, h2, h3, h4, h5, h6, h7;
+ vector2x_u64 a, b, c, d, e, f, g, h, t1, t2;
+ u64 w[16];
+
+ h0 = vec_u64_load (8 * 0, (unsigned long long *)state);
+ h1 = vec_rol_elems (h0, 1);
+ h2 = vec_u64_load (8 * 2, (unsigned long long *)state);
+ h3 = vec_rol_elems (h2, 1);
+ h4 = vec_u64_load (8 * 4, (unsigned long long *)state);
+ h5 = vec_rol_elems (h4, 1);
+ h6 = vec_u64_load (8 * 6, (unsigned long long *)state);
+ h7 = vec_rol_elems (h6, 1);
+
+ while (nblks >= 2)
+ {
+ a = h0;
+ b = h1;
+ c = h2;
+ d = h3;
+ e = h4;
+ f = h5;
+ g = h6;
+ h = h7;
+
+ I(0); I(1); I(2); I(3);
+ I(4); I(5); I(6); I(7);
+ I(8); I(9); I(10); I(11);
+ I(12); I(13); I(14); I(15);
+ data += 128;
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W(48));
+ R(h, a, b, c, d, e, f, g, K[49], W(49));
+ R(g, h, a, b, c, d, e, f, K[50], W(50));
+ R(f, g, h, a, b, c, d, e, K[51], W(51));
+ R(e, f, g, h, a, b, c, d, K[52], W(52));
+ R(d, e, f, g, h, a, b, c, K[53], W(53));
+ R(c, d, e, f, g, h, a, b, K[54], W(54));
+ R(b, c, d, e, f, g, h, a, K[55], W(55));
+ R(a, b, c, d, e, f, g, h, K[56], W(56));
+ R(h, a, b, c, d, e, f, g, K[57], W(57));
+ R(g, h, a, b, c, d, e, f, K[58], W(58));
+ R(f, g, h, a, b, c, d, e, K[59], W(59));
+ R(e, f, g, h, a, b, c, d, K[60], W(60));
+ R(d, e, f, g, h, a, b, c, K[61], W(61));
+ R(c, d, e, f, g, h, a, b, K[62], W(62));
+ R(b, c, d, e, f, g, h, a, K[63], W(63));
+
+ R(a, b, c, d, e, f, g, h, K[64], L(64));
+ R(h, a, b, c, d, e, f, g, K[65], L(65));
+ R(g, h, a, b, c, d, e, f, K[66], L(66));
+ R(f, g, h, a, b, c, d, e, K[67], L(67));
+ I(0); I(1); I(2); I(3);
+ R(e, f, g, h, a, b, c, d, K[68], L(68));
+ R(d, e, f, g, h, a, b, c, K[69], L(69));
+ R(c, d, e, f, g, h, a, b, K[70], L(70));
+ R(b, c, d, e, f, g, h, a, K[71], L(71));
+ I(4); I(5); I(6); I(7);
+ R(a, b, c, d, e, f, g, h, K[72], L(72));
+ R(h, a, b, c, d, e, f, g, K[73], L(73));
+ R(g, h, a, b, c, d, e, f, K[74], L(74));
+ R(f, g, h, a, b, c, d, e, K[75], L(75));
+ I(8); I(9); I(10); I(11);
+ R(e, f, g, h, a, b, c, d, K[76], L(76));
+ R(d, e, f, g, h, a, b, c, K[77], L(77));
+ R(c, d, e, f, g, h, a, b, K[78], L(78));
+ R(b, c, d, e, f, g, h, a, K[79], L(79));
+ I(12); I(13); I(14); I(15);
+ data += 128;
+
+ h0 += a;
+ h1 += b;
+ h2 += c;
+ h3 += d;
+ h4 += e;
+ h5 += f;
+ h6 += g;
+ h7 += h;
+ a = h0;
+ b = h1;
+ c = h2;
+ d = h3;
+ e = h4;
+ f = h5;
+ g = h6;
+ h = h7;
+
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W(48));
+ R(h, a, b, c, d, e, f, g, K[49], W(49));
+ R(g, h, a, b, c, d, e, f, K[50], W(50));
+ R(f, g, h, a, b, c, d, e, K[51], W(51));
+ R(e, f, g, h, a, b, c, d, K[52], W(52));
+ R(d, e, f, g, h, a, b, c, K[53], W(53));
+ R(c, d, e, f, g, h, a, b, K[54], W(54));
+ R(b, c, d, e, f, g, h, a, K[55], W(55));
+ R(a, b, c, d, e, f, g, h, K[56], W(56));
+ R(h, a, b, c, d, e, f, g, K[57], W(57));
+ R(g, h, a, b, c, d, e, f, K[58], W(58));
+ R(f, g, h, a, b, c, d, e, K[59], W(59));
+ R(e, f, g, h, a, b, c, d, K[60], W(60));
+ R(d, e, f, g, h, a, b, c, K[61], W(61));
+ R(c, d, e, f, g, h, a, b, K[62], W(62));
+ R(b, c, d, e, f, g, h, a, K[63], W(63));
+
+ R(a, b, c, d, e, f, g, h, K[64], L(64));
+ R(h, a, b, c, d, e, f, g, K[65], L(65));
+ R(g, h, a, b, c, d, e, f, K[66], L(66));
+ R(f, g, h, a, b, c, d, e, K[67], L(67));
+ R(e, f, g, h, a, b, c, d, K[68], L(68));
+ R(d, e, f, g, h, a, b, c, K[69], L(69));
+ R(c, d, e, f, g, h, a, b, K[70], L(70));
+ R(b, c, d, e, f, g, h, a, K[71], L(71));
+ R(a, b, c, d, e, f, g, h, K[72], L(72));
+ R(h, a, b, c, d, e, f, g, K[73], L(73));
+ R(g, h, a, b, c, d, e, f, K[74], L(74));
+ R(f, g, h, a, b, c, d, e, K[75], L(75));
+ R(e, f, g, h, a, b, c, d, K[76], L(76));
+ R(d, e, f, g, h, a, b, c, K[77], L(77));
+ R(c, d, e, f, g, h, a, b, K[78], L(78));
+ R(b, c, d, e, f, g, h, a, K[79], L(79));
+
+ h0 += a;
+ h1 += b;
+ h2 += c;
+ h3 += d;
+ h4 += e;
+ h5 += f;
+ h6 += g;
+ h7 += h;
+
+ nblks -= 2;
+ }
+
+ while (nblks)
+ {
+ a = h0;
+ b = h1;
+ c = h2;
+ d = h3;
+ e = h4;
+ f = h5;
+ g = h6;
+ h = h7;
+
+ I(0); I(1); I(2); I(3);
+ I(4); I(5); I(6); I(7);
+ I(8); I(9); I(10); I(11);
+ I(12); I(13); I(14); I(15);
+ data += 128;
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W(48));
+ R(h, a, b, c, d, e, f, g, K[49], W(49));
+ R(g, h, a, b, c, d, e, f, K[50], W(50));
+ R(f, g, h, a, b, c, d, e, K[51], W(51));
+ R(e, f, g, h, a, b, c, d, K[52], W(52));
+ R(d, e, f, g, h, a, b, c, K[53], W(53));
+ R(c, d, e, f, g, h, a, b, K[54], W(54));
+ R(b, c, d, e, f, g, h, a, K[55], W(55));
+ R(a, b, c, d, e, f, g, h, K[56], W(56));
+ R(h, a, b, c, d, e, f, g, K[57], W(57));
+ R(g, h, a, b, c, d, e, f, K[58], W(58));
+ R(f, g, h, a, b, c, d, e, K[59], W(59));
+ R(e, f, g, h, a, b, c, d, K[60], W(60));
+ R(d, e, f, g, h, a, b, c, K[61], W(61));
+ R(c, d, e, f, g, h, a, b, K[62], W(62));
+ R(b, c, d, e, f, g, h, a, K[63], W(63));
+
+ R(a, b, c, d, e, f, g, h, K[64], L(64));
+ R(h, a, b, c, d, e, f, g, K[65], L(65));
+ R(g, h, a, b, c, d, e, f, K[66], L(66));
+ R(f, g, h, a, b, c, d, e, K[67], L(67));
+ R(e, f, g, h, a, b, c, d, K[68], L(68));
+ R(d, e, f, g, h, a, b, c, K[69], L(69));
+ R(c, d, e, f, g, h, a, b, K[70], L(70));
+ R(b, c, d, e, f, g, h, a, K[71], L(71));
+ R(a, b, c, d, e, f, g, h, K[72], L(72));
+ R(h, a, b, c, d, e, f, g, K[73], L(73));
+ R(g, h, a, b, c, d, e, f, K[74], L(74));
+ R(f, g, h, a, b, c, d, e, K[75], L(75));
+ R(e, f, g, h, a, b, c, d, K[76], L(76));
+ R(d, e, f, g, h, a, b, c, K[77], L(77));
+ R(c, d, e, f, g, h, a, b, K[78], L(78));
+ R(b, c, d, e, f, g, h, a, K[79], L(79));
+
+ h0 += a;
+ h1 += b;
+ h2 += c;
+ h3 += d;
+ h4 += e;
+ h5 += f;
+ h6 += g;
+ h7 += h;
+
+ nblks--;
+ }
+
+ h0 = vec_merge_idx0_elems (h0, h1);
+ h2 = vec_merge_idx0_elems (h2, h3);
+ h4 = vec_merge_idx0_elems (h4, h5);
+ h6 = vec_merge_idx0_elems (h6, h7);
+ vec_u64_store (h0, 8 * 0, (unsigned long long *)state);
+ vec_u64_store (h2, 8 * 2, (unsigned long long *)state);
+ vec_u64_store (h4, 8 * 4, (unsigned long long *)state);
+ vec_u64_store (h6, 8 * 6, (unsigned long long *)state);
+
+ return sizeof(w);
+}
+#undef R
+#undef Cho
+#undef Maj
+#undef Sum0
+#undef Sum1
+#undef S0
+#undef S1
+#undef I
+#undef W
+#undef I2
+#undef W2
+#undef R2
+
+
+/* SHA2 round in general purpose registers */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + ((k) + (w));\
+ t2 = Sum0((a)) + Maj((a),(b),(c)); \
+ d += t1; \
+ h = t1 + t2; \
+ } while (0)
+
+#define Cho(x, y, z) ((x & y) + (~x & z))
+
+#define Maj(z, x, y) ((x & y) + (z & (x ^ y)))
+
+#define Sum0(x) (ror64(x, 28) ^ ror64(x ^ ror64(x, 39-34), 34))
+
+#define Sum1(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41))
+
+
+/* Message expansion on general purpose registers */
+#define S0(x) (ror64 ((x), 1) ^ ror64 ((x), 8) ^ ((x) >> 7))
+#define S1(x) (ror64 ((x), 19) ^ ror64 ((x), 61) ^ ((x) >> 6))
+
+#define I(i) ( w[i] = buf_get_be64(data + i * 8) )
+#define WN(i) ({ w[i&0x0f] += w[(i-7) &0x0f]; \
+ w[i&0x0f] += S0(w[(i-15)&0x0f]); \
+ w[i&0x0f] += S1(w[(i-2) &0x0f]); \
+ w[i&0x0f]; })
+#define W(i) ({ u64 r = w[i&0x0f]; WN(i); r; })
+#define L(i) w[i&0x0f]
+
+
+unsigned int ASM_FUNC_ATTR
+_gcry_sha512_transform_ppc9(u64 state[8], const unsigned char *data,
+ size_t nblks)
+{
+ /* GPRs used for round function and message expansion as vector intrinsics
+ * based generates slower code for POWER9. */
+ u64 a, b, c, d, e, f, g, h, t1, t2;
+ u64 w[16];
+
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+
+ while (nblks >= 2)
+ {
+ I(0); I(1); I(2); I(3);
+ I(4); I(5); I(6); I(7);
+ I(8); I(9); I(10); I(11);
+ I(12); I(13); I(14); I(15);
+ data += 128;
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W(48));
+ R(h, a, b, c, d, e, f, g, K[49], W(49));
+ R(g, h, a, b, c, d, e, f, K[50], W(50));
+ R(f, g, h, a, b, c, d, e, K[51], W(51));
+ R(e, f, g, h, a, b, c, d, K[52], W(52));
+ R(d, e, f, g, h, a, b, c, K[53], W(53));
+ R(c, d, e, f, g, h, a, b, K[54], W(54));
+ R(b, c, d, e, f, g, h, a, K[55], W(55));
+ R(a, b, c, d, e, f, g, h, K[56], W(56));
+ R(h, a, b, c, d, e, f, g, K[57], W(57));
+ R(g, h, a, b, c, d, e, f, K[58], W(58));
+ R(f, g, h, a, b, c, d, e, K[59], W(59));
+ R(e, f, g, h, a, b, c, d, K[60], W(60));
+ R(d, e, f, g, h, a, b, c, K[61], W(61));
+ R(c, d, e, f, g, h, a, b, K[62], W(62));
+ R(b, c, d, e, f, g, h, a, K[63], W(63));
+
+ R(a, b, c, d, e, f, g, h, K[64], L(64));
+ R(h, a, b, c, d, e, f, g, K[65], L(65));
+ R(g, h, a, b, c, d, e, f, K[66], L(66));
+ R(f, g, h, a, b, c, d, e, K[67], L(67));
+ I(0); I(1); I(2); I(3);
+ R(e, f, g, h, a, b, c, d, K[68], L(68));
+ R(d, e, f, g, h, a, b, c, K[69], L(69));
+ R(c, d, e, f, g, h, a, b, K[70], L(70));
+ R(b, c, d, e, f, g, h, a, K[71], L(71));
+ I(4); I(5); I(6); I(7);
+ R(a, b, c, d, e, f, g, h, K[72], L(72));
+ R(h, a, b, c, d, e, f, g, K[73], L(73));
+ R(g, h, a, b, c, d, e, f, K[74], L(74));
+ R(f, g, h, a, b, c, d, e, K[75], L(75));
+ I(8); I(9); I(10); I(11);
+ R(e, f, g, h, a, b, c, d, K[76], L(76));
+ R(d, e, f, g, h, a, b, c, K[77], L(77));
+ R(c, d, e, f, g, h, a, b, K[78], L(78));
+ R(b, c, d, e, f, g, h, a, K[79], L(79));
+ I(12); I(13); I(14); I(15);
+ data += 128;
+
+ a += state[0];
+ b += state[1];
+ c += state[2];
+ d += state[3];
+ e += state[4];
+ f += state[5];
+ g += state[6];
+ h += state[7];
+ state[0] = a;
+ state[1] = b;
+ state[2] = c;
+ state[3] = d;
+ state[4] = e;
+ state[5] = f;
+ state[6] = g;
+ state[7] = h;
+
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W(48));
+ R(h, a, b, c, d, e, f, g, K[49], W(49));
+ R(g, h, a, b, c, d, e, f, K[50], W(50));
+ R(f, g, h, a, b, c, d, e, K[51], W(51));
+ R(e, f, g, h, a, b, c, d, K[52], W(52));
+ R(d, e, f, g, h, a, b, c, K[53], W(53));
+ R(c, d, e, f, g, h, a, b, K[54], W(54));
+ R(b, c, d, e, f, g, h, a, K[55], W(55));
+ R(a, b, c, d, e, f, g, h, K[56], W(56));
+ R(h, a, b, c, d, e, f, g, K[57], W(57));
+ R(g, h, a, b, c, d, e, f, K[58], W(58));
+ R(f, g, h, a, b, c, d, e, K[59], W(59));
+ R(e, f, g, h, a, b, c, d, K[60], W(60));
+ R(d, e, f, g, h, a, b, c, K[61], W(61));
+ R(c, d, e, f, g, h, a, b, K[62], W(62));
+ R(b, c, d, e, f, g, h, a, K[63], W(63));
+
+ R(a, b, c, d, e, f, g, h, K[64], L(64));
+ R(h, a, b, c, d, e, f, g, K[65], L(65));
+ R(g, h, a, b, c, d, e, f, K[66], L(66));
+ R(f, g, h, a, b, c, d, e, K[67], L(67));
+ R(e, f, g, h, a, b, c, d, K[68], L(68));
+ R(d, e, f, g, h, a, b, c, K[69], L(69));
+ R(c, d, e, f, g, h, a, b, K[70], L(70));
+ R(b, c, d, e, f, g, h, a, K[71], L(71));
+ R(a, b, c, d, e, f, g, h, K[72], L(72));
+ R(h, a, b, c, d, e, f, g, K[73], L(73));
+ R(g, h, a, b, c, d, e, f, K[74], L(74));
+ R(f, g, h, a, b, c, d, e, K[75], L(75));
+ R(e, f, g, h, a, b, c, d, K[76], L(76));
+ R(d, e, f, g, h, a, b, c, K[77], L(77));
+ R(c, d, e, f, g, h, a, b, K[78], L(78));
+ R(b, c, d, e, f, g, h, a, K[79], L(79));
+
+ a += state[0];
+ b += state[1];
+ c += state[2];
+ d += state[3];
+ e += state[4];
+ f += state[5];
+ g += state[6];
+ h += state[7];
+ state[0] = a;
+ state[1] = b;
+ state[2] = c;
+ state[3] = d;
+ state[4] = e;
+ state[5] = f;
+ state[6] = g;
+ state[7] = h;
+
+ nblks -= 2;
+ }
+
+ while (nblks)
+ {
+ I(0); I(1); I(2); I(3);
+ I(4); I(5); I(6); I(7);
+ I(8); I(9); I(10); I(11);
+ I(12); I(13); I(14); I(15);
+ data += 128;
+ R(a, b, c, d, e, f, g, h, K[0], W(0));
+ R(h, a, b, c, d, e, f, g, K[1], W(1));
+ R(g, h, a, b, c, d, e, f, K[2], W(2));
+ R(f, g, h, a, b, c, d, e, K[3], W(3));
+ R(e, f, g, h, a, b, c, d, K[4], W(4));
+ R(d, e, f, g, h, a, b, c, K[5], W(5));
+ R(c, d, e, f, g, h, a, b, K[6], W(6));
+ R(b, c, d, e, f, g, h, a, K[7], W(7));
+ R(a, b, c, d, e, f, g, h, K[8], W(8));
+ R(h, a, b, c, d, e, f, g, K[9], W(9));
+ R(g, h, a, b, c, d, e, f, K[10], W(10));
+ R(f, g, h, a, b, c, d, e, K[11], W(11));
+ R(e, f, g, h, a, b, c, d, K[12], W(12));
+ R(d, e, f, g, h, a, b, c, K[13], W(13));
+ R(c, d, e, f, g, h, a, b, K[14], W(14));
+ R(b, c, d, e, f, g, h, a, K[15], W(15));
+
+ R(a, b, c, d, e, f, g, h, K[16], W(16));
+ R(h, a, b, c, d, e, f, g, K[17], W(17));
+ R(g, h, a, b, c, d, e, f, K[18], W(18));
+ R(f, g, h, a, b, c, d, e, K[19], W(19));
+ R(e, f, g, h, a, b, c, d, K[20], W(20));
+ R(d, e, f, g, h, a, b, c, K[21], W(21));
+ R(c, d, e, f, g, h, a, b, K[22], W(22));
+ R(b, c, d, e, f, g, h, a, K[23], W(23));
+ R(a, b, c, d, e, f, g, h, K[24], W(24));
+ R(h, a, b, c, d, e, f, g, K[25], W(25));
+ R(g, h, a, b, c, d, e, f, K[26], W(26));
+ R(f, g, h, a, b, c, d, e, K[27], W(27));
+ R(e, f, g, h, a, b, c, d, K[28], W(28));
+ R(d, e, f, g, h, a, b, c, K[29], W(29));
+ R(c, d, e, f, g, h, a, b, K[30], W(30));
+ R(b, c, d, e, f, g, h, a, K[31], W(31));
+
+ R(a, b, c, d, e, f, g, h, K[32], W(32));
+ R(h, a, b, c, d, e, f, g, K[33], W(33));
+ R(g, h, a, b, c, d, e, f, K[34], W(34));
+ R(f, g, h, a, b, c, d, e, K[35], W(35));
+ R(e, f, g, h, a, b, c, d, K[36], W(36));
+ R(d, e, f, g, h, a, b, c, K[37], W(37));
+ R(c, d, e, f, g, h, a, b, K[38], W(38));
+ R(b, c, d, e, f, g, h, a, K[39], W(39));
+ R(a, b, c, d, e, f, g, h, K[40], W(40));
+ R(h, a, b, c, d, e, f, g, K[41], W(41));
+ R(g, h, a, b, c, d, e, f, K[42], W(42));
+ R(f, g, h, a, b, c, d, e, K[43], W(43));
+ R(e, f, g, h, a, b, c, d, K[44], W(44));
+ R(d, e, f, g, h, a, b, c, K[45], W(45));
+ R(c, d, e, f, g, h, a, b, K[46], W(46));
+ R(b, c, d, e, f, g, h, a, K[47], W(47));
+
+ R(a, b, c, d, e, f, g, h, K[48], W(48));
+ R(h, a, b, c, d, e, f, g, K[49], W(49));
+ R(g, h, a, b, c, d, e, f, K[50], W(50));
+ R(f, g, h, a, b, c, d, e, K[51], W(51));
+ R(e, f, g, h, a, b, c, d, K[52], W(52));
+ R(d, e, f, g, h, a, b, c, K[53], W(53));
+ R(c, d, e, f, g, h, a, b, K[54], W(54));
+ R(b, c, d, e, f, g, h, a, K[55], W(55));
+ R(a, b, c, d, e, f, g, h, K[56], W(56));
+ R(h, a, b, c, d, e, f, g, K[57], W(57));
+ R(g, h, a, b, c, d, e, f, K[58], W(58));
+ R(f, g, h, a, b, c, d, e, K[59], W(59));
+ R(e, f, g, h, a, b, c, d, K[60], W(60));
+ R(d, e, f, g, h, a, b, c, K[61], W(61));
+ R(c, d, e, f, g, h, a, b, K[62], W(62));
+ R(b, c, d, e, f, g, h, a, K[63], W(63));
+
+ R(a, b, c, d, e, f, g, h, K[64], L(64));
+ R(h, a, b, c, d, e, f, g, K[65], L(65));
+ R(g, h, a, b, c, d, e, f, K[66], L(66));
+ R(f, g, h, a, b, c, d, e, K[67], L(67));
+ R(e, f, g, h, a, b, c, d, K[68], L(68));
+ R(d, e, f, g, h, a, b, c, K[69], L(69));
+ R(c, d, e, f, g, h, a, b, K[70], L(70));
+ R(b, c, d, e, f, g, h, a, K[71], L(71));
+ R(a, b, c, d, e, f, g, h, K[72], L(72));
+ R(h, a, b, c, d, e, f, g, K[73], L(73));
+ R(g, h, a, b, c, d, e, f, K[74], L(74));
+ R(f, g, h, a, b, c, d, e, K[75], L(75));
+ R(e, f, g, h, a, b, c, d, K[76], L(76));
+ R(d, e, f, g, h, a, b, c, K[77], L(77));
+ R(c, d, e, f, g, h, a, b, K[78], L(78));
+ R(b, c, d, e, f, g, h, a, K[79], L(79));
+
+ a += state[0];
+ b += state[1];
+ c += state[2];
+ d += state[3];
+ e += state[4];
+ f += state[5];
+ g += state[6];
+ h += state[7];
+ state[0] = a;
+ state[1] = b;
+ state[2] = c;
+ state[3] = d;
+ state[4] = e;
+ state[5] = f;
+ state[6] = g;
+ state[7] = h;
+
+ nblks--;
+ }
+
+ return sizeof(w);
+}
+
+#endif /* ENABLE_PPC_CRYPTO_SUPPORT */
diff --git a/comm/third_party/libgcrypt/cipher/sha512-ssse3-amd64.S b/comm/third_party/libgcrypt/cipher/sha512-ssse3-amd64.S
new file mode 100644
index 0000000000..6a1328a690
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha512-ssse3-amd64.S
@@ -0,0 +1,467 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Copyright (c) 2012, Intel Corporation
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are
+; met:
+;
+; * Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the
+; distribution.
+;
+; * Neither the name of the Intel Corporation nor the names of its
+; contributors may be used to endorse or promote products derived from
+; this software without specific prior written permission.
+;
+;
+; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ * by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Note: original implementation was named as SHA512-SSE4. However, only SSSE3
+ * is required.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA512)
+
+#include "asm-common-amd64.h"
+
+.intel_syntax noprefix
+
+.text
+
+/* Virtual Registers */
+#define msg rdi /* ARG1 */
+#define digest rsi /* ARG2 */
+#define msglen rdx /* ARG3 */
+#define T1 rcx
+#define T2 r8
+#define a_64 r9
+#define b_64 r10
+#define c_64 r11
+#define d_64 r12
+#define e_64 r13
+#define f_64 r14
+#define g_64 r15
+#define h_64 rbx
+#define tmp0 rax
+
+/*
+; Local variables (stack frame)
+; Note: frame_size must be an odd multiple of 8 bytes to XMM align RSP
+*/
+#define frame_W 0 /* Message Schedule */
+#define frame_W_size (80 * 8)
+#define frame_WK ((frame_W) + (frame_W_size)) /* W[t] + K[t] | W[t+1] + K[t+1] */
+#define frame_WK_size (2 * 8)
+#define frame_GPRSAVE ((frame_WK) + (frame_WK_size))
+#define frame_GPRSAVE_size (5 * 8)
+#define frame_size ((frame_GPRSAVE) + (frame_GPRSAVE_size))
+
+
+/* Useful QWORD "arrays" for simpler memory references */
+#define MSG(i) msg + 8*(i) /* Input message (arg1) */
+#define DIGEST(i) digest + 8*(i) /* Output Digest (arg2) */
+#define K_t(i) .LK512 + 8*(i) ADD_RIP /* SHA Constants (static mem) */
+#define W_t(i) rsp + frame_W + 8*(i) /* Message Schedule (stack frame) */
+#define WK_2(i) rsp + frame_WK + 8*((i) % 2) /* W[t]+K[t] (stack frame) */
+/* MSG, DIGEST, K_t, W_t are arrays */
+/* WK_2(t) points to 1 of 2 qwords at frame.WK depdending on t being odd/even */
+
+#define SHA512_Round(t, a, b, c, d, e, f, g, h) \
+ /* Compute Round %%t */; \
+ mov T1, f /* T1 = f */; \
+ mov tmp0, e /* tmp = e */; \
+ xor T1, g /* T1 = f ^ g */; \
+ ror tmp0, 23 /* 41 ; tmp = e ror 23 */; \
+ and T1, e /* T1 = (f ^ g) & e */; \
+ xor tmp0, e /* tmp = (e ror 23) ^ e */; \
+ xor T1, g /* T1 = ((f ^ g) & e) ^ g = CH(e,f,g) */; \
+ add T1, [WK_2(t)] /* W[t] + K[t] from message scheduler */; \
+ ror tmp0, 4 /* 18 ; tmp = ((e ror 23) ^ e) ror 4 */; \
+ xor tmp0, e /* tmp = (((e ror 23) ^ e) ror 4) ^ e */; \
+ mov T2, a /* T2 = a */; \
+ add T1, h /* T1 = CH(e,f,g) + W[t] + K[t] + h */; \
+ ror tmp0, 14 /* 14 ; tmp = ((((e ror23)^e)ror4)^e)ror14 = S1(e) */; \
+ add T1, tmp0 /* T1 = CH(e,f,g) + W[t] + K[t] + S1(e) */; \
+ mov tmp0, a /* tmp = a */; \
+ xor T2, c /* T2 = a ^ c */; \
+ and tmp0, c /* tmp = a & c */; \
+ and T2, b /* T2 = (a ^ c) & b */; \
+ xor T2, tmp0 /* T2 = ((a ^ c) & b) ^ (a & c) = Maj(a,b,c) */; \
+ mov tmp0, a /* tmp = a */; \
+ ror tmp0, 5 /* 39 ; tmp = a ror 5 */; \
+ xor tmp0, a /* tmp = (a ror 5) ^ a */; \
+ add d, T1 /* e(next_state) = d + T1 */; \
+ ror tmp0, 6 /* 34 ; tmp = ((a ror 5) ^ a) ror 6 */; \
+ xor tmp0, a /* tmp = (((a ror 5) ^ a) ror 6) ^ a */; \
+ lea h, [T1 + T2] /* a(next_state) = T1 + Maj(a,b,c) */; \
+ ror tmp0, 28 /* 28 ; tmp = ((((a ror5)^a)ror6)^a)ror28 = S0(a) */; \
+ add h, tmp0 /* a(next_state) = T1 + Maj(a,b,c) S0(a) */
+
+#define SHA512_2Sched_2Round_sse_PART1(t, a, b, c, d, e, f, g, h) \
+ /* \
+ ; Compute rounds %%t-2 and %%t-1 \
+ ; Compute message schedule QWORDS %%t and %%t+1 \
+ ; \
+ ; Two rounds are computed based on the values for K[t-2]+W[t-2] and \
+ ; K[t-1]+W[t-1] which were previously stored at WK_2 by the message \
+ ; scheduler. \
+ ; The two new schedule QWORDS are stored at [W_t(%%t)] and [W_t(%%t+1)]. \
+ ; They are then added to their respective SHA512 constants at \
+ ; [K_t(%%t)] and [K_t(%%t+1)] and stored at dqword [WK_2(%%t)] \
+ ; For brievity, the comments following vectored instructions only refer to \
+ ; the first of a pair of QWORDS. \
+ ; Eg. XMM2=W[t-2] really means XMM2={W[t-2]|W[t-1]} \
+ ; The computation of the message schedule and the rounds are tightly \
+ ; stitched to take advantage of instruction-level parallelism. \
+ ; For clarity, integer instructions (for the rounds calculation) are indented \
+ ; by one tab. Vectored instructions (for the message scheduler) are indented \
+ ; by two tabs. \
+ */ \
+ \
+ mov T1, f; \
+ movdqa xmm2, [W_t(t-2)] /* XMM2 = W[t-2] */; \
+ xor T1, g; \
+ and T1, e; \
+ movdqa xmm0, xmm2 /* XMM0 = W[t-2] */; \
+ xor T1, g; \
+ add T1, [WK_2(t)]; \
+ movdqu xmm5, [W_t(t-15)] /* XMM5 = W[t-15] */; \
+ mov tmp0, e; \
+ ror tmp0, 23 /* 41 */; \
+ movdqa xmm3, xmm5 /* XMM3 = W[t-15] */; \
+ xor tmp0, e; \
+ ror tmp0, 4 /* 18 */; \
+ psrlq xmm0, 61 - 19 /* XMM0 = W[t-2] >> 42 */; \
+ xor tmp0, e; \
+ ror tmp0, 14 /* 14 */; \
+ psrlq xmm3, (8 - 7) /* XMM3 = W[t-15] >> 1 */; \
+ add T1, tmp0; \
+ add T1, h; \
+ pxor xmm0, xmm2 /* XMM0 = (W[t-2] >> 42) ^ W[t-2] */; \
+ mov T2, a; \
+ xor T2, c; \
+ pxor xmm3, xmm5 /* XMM3 = (W[t-15] >> 1) ^ W[t-15] */; \
+ and T2, b; \
+ mov tmp0, a; \
+ psrlq xmm0, 19 - 6 /* XMM0 = ((W[t-2]>>42)^W[t-2])>>13 */; \
+ and tmp0, c; \
+ xor T2, tmp0; \
+ psrlq xmm3, (7 - 1) /* XMM3 = ((W[t-15]>>1)^W[t-15])>>6 */; \
+ mov tmp0, a; \
+ ror tmp0, 5 /* 39 */; \
+ pxor xmm0, xmm2 /* XMM0 = (((W[t-2]>>42)^W[t-2])>>13)^W[t-2] */; \
+ xor tmp0, a; \
+ ror tmp0, 6 /* 34 */; \
+ pxor xmm3, xmm5 /* XMM3 = (((W[t-15]>>1)^W[t-15])>>6)^W[t-15] */; \
+ xor tmp0, a; \
+ ror tmp0, 28 /* 28 */; \
+ psrlq xmm0, 6 /* XMM0 = ((((W[t-2]>>42)^W[t-2])>>13)^W[t-2])>>6 */; \
+ add T2, tmp0; \
+ add d, T1; \
+ psrlq xmm3, 1 /* XMM3 = (((W[t-15]>>1)^W[t-15])>>6)^W[t-15]>>1 */; \
+ lea h, [T1 + T2]
+
+#define SHA512_2Sched_2Round_sse_PART2(t, a, b, c, d, e, f, g, h) \
+ movdqa xmm1, xmm2 /* XMM1 = W[t-2] */; \
+ mov T1, f; \
+ xor T1, g; \
+ movdqa xmm4, xmm5 /* XMM4 = W[t-15] */; \
+ and T1, e; \
+ xor T1, g; \
+ psllq xmm1, (64 - 19) - (64 - 61) /* XMM1 = W[t-2] << 42 */; \
+ add T1, [WK_2(t+1)]; \
+ mov tmp0, e; \
+ psllq xmm4, (64 - 1) - (64 - 8) /* XMM4 = W[t-15] << 7 */; \
+ ror tmp0, 23 /* 41 */; \
+ xor tmp0, e; \
+ pxor xmm1, xmm2 /* XMM1 = (W[t-2] << 42)^W[t-2] */; \
+ ror tmp0, 4 /* 18 */; \
+ xor tmp0, e; \
+ pxor xmm4, xmm5 /* XMM4 = (W[t-15]<<7)^W[t-15] */; \
+ ror tmp0, 14 /* 14 */; \
+ add T1, tmp0; \
+ psllq xmm1, (64 - 61) /* XMM1 = ((W[t-2] << 42)^W[t-2])<<3 */; \
+ add T1, h; \
+ mov T2, a; \
+ psllq xmm4, (64 - 8) /* XMM4 = ((W[t-15]<<7)^W[t-15])<<56 */; \
+ xor T2, c; \
+ and T2, b; \
+ pxor xmm0, xmm1 /* XMM0 = s1(W[t-2]) */; \
+ mov tmp0, a; \
+ and tmp0, c; \
+ movdqu xmm1, [W_t(t- 7)] /* XMM1 = W[t-7] */; \
+ xor T2, tmp0; \
+ pxor xmm3, xmm4 /* XMM3 = s0(W[t-15]) */; \
+ mov tmp0, a; \
+ paddq xmm0, xmm3 /* XMM0 = s1(W[t-2]) + s0(W[t-15]) */; \
+ ror tmp0, 5 /* 39 */; \
+ paddq xmm0, [W_t(t-16)] /* XMM0 = s1(W[t-2]) + s0(W[t-15]) + W[t-16] */; \
+ xor tmp0, a; \
+ paddq xmm0, xmm1 /* XMM0 = s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16] */; \
+ ror tmp0, 6 /* 34 */; \
+ movdqa [W_t(t)], xmm0 /* Store scheduled qwords */; \
+ xor tmp0, a; \
+ paddq xmm0, [K_t(t)] /* Compute W[t]+K[t] */; \
+ ror tmp0, 28 /* 28 */; \
+ movdqa [WK_2(t)], xmm0 /* Store W[t]+K[t] for next rounds */; \
+ add T2, tmp0; \
+ add d, T1; \
+ lea h, [T1 + T2]
+
+#define SHA512_2Sched_2Round_sse(t, a, b, c, d, e, f, g, h) \
+ SHA512_2Sched_2Round_sse_PART1(t, a, b, c, d, e, f, g, h); \
+ SHA512_2Sched_2Round_sse_PART2(t, h, a, b, c, d, e, f, g)
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void sha512_sse4(const void* M, void* D, uint64_t L);
+; Purpose: Updates the SHA512 digest stored at D with the message stored in M.
+; The size of the message pointed to by M must be an integer multiple of SHA512
+; message blocks.
+; L is the message length in SHA512 blocks.
+*/
+.globl _gcry_sha512_transform_amd64_ssse3
+ELF(.type _gcry_sha512_transform_amd64_ssse3,@function;)
+.align 16
+_gcry_sha512_transform_amd64_ssse3:
+ CFI_STARTPROC()
+ xor eax, eax
+
+ cmp msglen, 0
+ je .Lnowork
+
+ /* Allocate Stack Space */
+ sub rsp, frame_size
+ CFI_ADJUST_CFA_OFFSET(frame_size);
+
+ /* Save GPRs */
+ mov [rsp + frame_GPRSAVE + 8 * 0], rbx
+ mov [rsp + frame_GPRSAVE + 8 * 1], r12
+ mov [rsp + frame_GPRSAVE + 8 * 2], r13
+ mov [rsp + frame_GPRSAVE + 8 * 3], r14
+ mov [rsp + frame_GPRSAVE + 8 * 4], r15
+ CFI_REL_OFFSET(rbx, frame_GPRSAVE + 8 * 0);
+ CFI_REL_OFFSET(r12, frame_GPRSAVE + 8 * 1);
+ CFI_REL_OFFSET(r13, frame_GPRSAVE + 8 * 2);
+ CFI_REL_OFFSET(r14, frame_GPRSAVE + 8 * 3);
+ CFI_REL_OFFSET(r15, frame_GPRSAVE + 8 * 4);
+
+.Lupdateblock:
+
+ /* Load state variables */
+ mov a_64, [DIGEST(0)]
+ mov b_64, [DIGEST(1)]
+ mov c_64, [DIGEST(2)]
+ mov d_64, [DIGEST(3)]
+ mov e_64, [DIGEST(4)]
+ mov f_64, [DIGEST(5)]
+ mov g_64, [DIGEST(6)]
+ mov h_64, [DIGEST(7)]
+
+ /* BSWAP 2 QWORDS */
+ movdqa xmm1, [.LXMM_QWORD_BSWAP ADD_RIP]
+ movdqu xmm0, [MSG(0)]
+ pshufb xmm0, xmm1 /* BSWAP */
+ movdqa [W_t(0)], xmm0 /* Store Scheduled Pair */
+ paddq xmm0, [K_t(0)] /* Compute W[t]+K[t] */
+ movdqa [WK_2(0)], xmm0 /* Store into WK for rounds */
+
+ #define T_2_14(t, a, b, c, d, e, f, g, h) \
+ /* BSWAP 2 QWORDS; Compute 2 Rounds */; \
+ movdqu xmm0, [MSG(t)]; \
+ pshufb xmm0, xmm1 /* BSWAP */; \
+ SHA512_Round(((t) - 2), a##_64, b##_64, c##_64, d##_64, \
+ e##_64, f##_64, g##_64, h##_64); \
+ movdqa [W_t(t)], xmm0 /* Store Scheduled Pair */; \
+ paddq xmm0, [K_t(t)] /* Compute W[t]+K[t] */; \
+ SHA512_Round(((t) - 1), h##_64, a##_64, b##_64, c##_64, \
+ d##_64, e##_64, f##_64, g##_64); \
+ movdqa [WK_2(t)], xmm0 /* Store W[t]+K[t] into WK */
+
+ #define T_16_78(t, a, b, c, d, e, f, g, h) \
+ SHA512_2Sched_2Round_sse((t), a##_64, b##_64, c##_64, d##_64, \
+ e##_64, f##_64, g##_64, h##_64)
+
+ #define T_80(t, a, b, c, d, e, f, g, h) \
+ /* Compute 2 Rounds */; \
+ SHA512_Round((t - 2), a##_64, b##_64, c##_64, d##_64, \
+ e##_64, f##_64, g##_64, h##_64); \
+ SHA512_Round((t - 1), h##_64, a##_64, b##_64, c##_64, \
+ d##_64, e##_64, f##_64, g##_64)
+
+ T_2_14(2, a, b, c, d, e, f, g, h)
+ T_2_14(4, g, h, a, b, c, d, e, f)
+ T_2_14(6, e, f, g, h, a, b, c, d)
+ T_2_14(8, c, d, e, f, g, h, a, b)
+ T_2_14(10, a, b, c, d, e, f, g, h)
+ T_2_14(12, g, h, a, b, c, d, e, f)
+ T_2_14(14, e, f, g, h, a, b, c, d)
+ T_16_78(16, c, d, e, f, g, h, a, b)
+ T_16_78(18, a, b, c, d, e, f, g, h)
+ T_16_78(20, g, h, a, b, c, d, e, f)
+ T_16_78(22, e, f, g, h, a, b, c, d)
+ T_16_78(24, c, d, e, f, g, h, a, b)
+ T_16_78(26, a, b, c, d, e, f, g, h)
+ T_16_78(28, g, h, a, b, c, d, e, f)
+ T_16_78(30, e, f, g, h, a, b, c, d)
+ T_16_78(32, c, d, e, f, g, h, a, b)
+ T_16_78(34, a, b, c, d, e, f, g, h)
+ T_16_78(36, g, h, a, b, c, d, e, f)
+ T_16_78(38, e, f, g, h, a, b, c, d)
+ T_16_78(40, c, d, e, f, g, h, a, b)
+ T_16_78(42, a, b, c, d, e, f, g, h)
+ T_16_78(44, g, h, a, b, c, d, e, f)
+ T_16_78(46, e, f, g, h, a, b, c, d)
+ T_16_78(48, c, d, e, f, g, h, a, b)
+ T_16_78(50, a, b, c, d, e, f, g, h)
+ T_16_78(52, g, h, a, b, c, d, e, f)
+ T_16_78(54, e, f, g, h, a, b, c, d)
+ T_16_78(56, c, d, e, f, g, h, a, b)
+ T_16_78(58, a, b, c, d, e, f, g, h)
+ T_16_78(60, g, h, a, b, c, d, e, f)
+ T_16_78(62, e, f, g, h, a, b, c, d)
+ T_16_78(64, c, d, e, f, g, h, a, b)
+ T_16_78(66, a, b, c, d, e, f, g, h)
+ T_16_78(68, g, h, a, b, c, d, e, f)
+ T_16_78(70, e, f, g, h, a, b, c, d)
+ T_16_78(72, c, d, e, f, g, h, a, b)
+ T_16_78(74, a, b, c, d, e, f, g, h)
+ T_16_78(76, g, h, a, b, c, d, e, f)
+ T_16_78(78, e, f, g, h, a, b, c, d)
+ T_80(80, c, d, e, f, g, h, a, b)
+
+ /* Update digest */
+ add [DIGEST(0)], a_64
+ add [DIGEST(1)], b_64
+ add [DIGEST(2)], c_64
+ add [DIGEST(3)], d_64
+ add [DIGEST(4)], e_64
+ add [DIGEST(5)], f_64
+ add [DIGEST(6)], g_64
+ add [DIGEST(7)], h_64
+
+ /* Advance to next message block */
+ add msg, 16*8
+ dec msglen
+ jnz .Lupdateblock
+
+ /* Restore GPRs */
+ mov rbx, [rsp + frame_GPRSAVE + 8 * 0]
+ mov r12, [rsp + frame_GPRSAVE + 8 * 1]
+ mov r13, [rsp + frame_GPRSAVE + 8 * 2]
+ mov r14, [rsp + frame_GPRSAVE + 8 * 3]
+ mov r15, [rsp + frame_GPRSAVE + 8 * 4]
+ CFI_RESTORE(rbx)
+ CFI_RESTORE(r12)
+ CFI_RESTORE(r13)
+ CFI_RESTORE(r14)
+ CFI_RESTORE(r15)
+
+ pxor xmm0, xmm0
+ pxor xmm1, xmm1
+ pxor xmm2, xmm2
+ pxor xmm3, xmm3
+ pxor xmm4, xmm4
+ pxor xmm5, xmm5
+
+ /* Burn stack */
+ mov eax, 0
+.Lerase_stack:
+ movdqu [rsp + rax], xmm0
+ add eax, 16
+ cmp eax, frame_W_size
+ jne .Lerase_stack
+ movdqu [rsp + frame_WK], xmm0
+ xor eax, eax
+
+ /* Restore Stack Pointer */
+ add rsp, frame_size
+ CFI_ADJUST_CFA_OFFSET(-frame_size);
+
+.Lnowork:
+ ret
+ CFI_ENDPROC()
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Binary Data
+*/
+
+.align 16
+
+/* Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. */
+.LXMM_QWORD_BSWAP:
+ .octa 0x08090a0b0c0d0e0f0001020304050607
+
+/* K[t] used in SHA512 hashing */
+.LK512:
+ .quad 0x428a2f98d728ae22,0x7137449123ef65cd
+ .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+ .quad 0x3956c25bf348b538,0x59f111f1b605d019
+ .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
+ .quad 0xd807aa98a3030242,0x12835b0145706fbe
+ .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+ .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
+ .quad 0x9bdc06a725c71235,0xc19bf174cf692694
+ .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
+ .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+ .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
+ .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+ .quad 0x983e5152ee66dfab,0xa831c66d2db43210
+ .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
+ .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
+ .quad 0x06ca6351e003826f,0x142929670a0e6e70
+ .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
+ .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+ .quad 0x650a73548baf63de,0x766a0abb3c77b2a8
+ .quad 0x81c2c92e47edaee6,0x92722c851482353b
+ .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
+ .quad 0xc24b8b70d0f89791,0xc76c51a30654be30
+ .quad 0xd192e819d6ef5218,0xd69906245565a910
+ .quad 0xf40e35855771202a,0x106aa07032bbd1b8
+ .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
+ .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+ .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+ .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+ .quad 0x748f82ee5defb2fc,0x78a5636f43172f60
+ .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
+ .quad 0x90befffa23631e28,0xa4506cebde82bde9
+ .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
+ .quad 0xca273eceea26619c,0xd186b8c721c0c207
+ .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+ .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
+ .quad 0x113f9804bef90dae,0x1b710b35131c471b
+ .quad 0x28db77f523047d84,0x32caab7b40c72493
+ .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+ .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+ .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha512-ssse3-i386.c b/comm/third_party/libgcrypt/cipher/sha512-ssse3-i386.c
new file mode 100644
index 0000000000..0fc98d8ed2
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha512-ssse3-i386.c
@@ -0,0 +1,404 @@
+/* sha512-ssse3-i386.c - i386/SSSE3 implementation of SHA-512 transform
+ * Copyright (C) 2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * SHA512 Message Expansion (I2 and W2 macros) based on implementation
+ * from file "sha512-ssse3-amd64.s":
+ ************************************************************************
+ * Copyright (c) 2012, Intel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ************************************************************************
+ */
+
+#include <config.h>
+
+#if defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 && \
+ defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA512)
+
+#include "bufhelp.h"
+
+
+#if _GCRY_GCC_VERSION >= 40400 /* 4.4 */
+/* Prevent compiler from issuing SSE/MMX instructions between asm blocks. */
+# pragma GCC target("no-sse")
+# pragma GCC target("no-mmx")
+#endif
+#if __clang__
+# pragma clang attribute push (__attribute__((target("no-sse"))), apply_to = function)
+# pragma clang attribute push (__attribute__((target("no-mmx"))), 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
+
+
+static const u64 K[80] __attribute__ ((aligned (16))) =
+ {
+ U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
+ U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
+ U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
+ U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
+ U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
+ U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
+ U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
+ U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
+ U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
+ U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
+ U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
+ U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
+ U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
+ U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
+ U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
+ U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
+ U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
+ U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
+ U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
+ U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
+ U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
+ U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
+ U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
+ U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
+ U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
+ U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
+ U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
+ U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
+ U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
+ U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
+ U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
+ U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
+ U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
+ U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
+ U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
+ U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
+ U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
+ U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
+ U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
+ U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
+ };
+
+static const unsigned char bshuf_mask[16] __attribute__ ((aligned (16))) =
+ { 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 };
+
+
+/* SHA2 round */
+#define RA "%%mm0"
+#define RB "%%mm1"
+#define RC "%%mm2"
+#define RD "%%mm3"
+#define RE "%%mm4"
+#define RF "%%mm5"
+#define RG "%%mm6"
+#define RH "%%mm7"
+
+#define Rx(a,b,c,d,e,f,g,h,wk) \
+ asm volatile (/* Cho + Sum1 */ \
+ "movq2dq "a", %%xmm2;\n\t" \
+ "movq "e", "a";\n\t" \
+ "movq2dq "c", %%xmm3;\n\t" \
+ "movq "e", "c";\n\t" \
+ "movq2dq "b", %%xmm4;\n\t" \
+ "movq "e", "b";\n\t" \
+ "psrlq $(41-18), "c";\n\t" \
+ "pandn "g", "a";\n\t" \
+ "pxor "e", "c";\n\t" \
+ "pand "f", "b";\n\t" \
+ "psrlq $(18-14), "c";\n\t" \
+ "paddq "a", "h";\n\t" \
+ wk(a) \
+ "pxor "e", "c";\n\t" \
+ "paddq "b", "h";\n\t" \
+ "psrlq $(14), "c";\n\t" \
+ "movq "e", "b";\n\t" \
+ "psllq $(50-46), "b";\n\t" \
+ "paddq "a", "h";\n\t" \
+ "movdq2q %%xmm2, "a";\n\t" \
+ "pxor "e", "b";\n\t" \
+ "psllq $(46-23), "b";\n\t" \
+ "pxor "e", "b";\n\t" \
+ "psllq $(23), "b";\n\t" \
+ "pxor "b", "c";\n\t" \
+ "movdq2q %%xmm4, "b";\n\t" \
+ "paddq "c", "h";\n\t" \
+ "movdq2q %%xmm3, "c";\n\t" \
+ \
+ /* Maj + Sum0 */ \
+ "movq2dq "e", %%xmm2;\n\t" \
+ "movq "a", "e";\n\t" \
+ "movq2dq "g", %%xmm3;\n\t" \
+ "movq "a", "g";\n\t" \
+ "movq2dq "f", %%xmm4;\n\t" \
+ "movq "a", "f";\n\t" \
+ "psrlq $(39-34), "g";\n\t" \
+ "pxor "b", "e";\n\t" \
+ "pxor "a", "g";\n\t" \
+ "pand "b", "f";\n\t" \
+ "psrlq $(34-28), "g";\n\t" \
+ "pand "c", "e";\n\t" \
+ "pxor "a", "g";\n\t" \
+ "paddq "h", "d";\n\t" \
+ "paddq "f", "h";\n\t" \
+ "movdq2q %%xmm4, "f";\n\t" \
+ "psrlq $28, "g";\n\t" \
+ "paddq "e", "h";\n\t" \
+ "movq "a", "e";\n\t" \
+ "psllq $(36-30), "e";\n\t" \
+ "pxor "a", "e";\n\t" \
+ "psllq $(30-25), "e";\n\t" \
+ "pxor "a", "e";\n\t" \
+ "psllq $(25), "e";\n\t" \
+ "pxor "e", "g";\n\t" \
+ "movdq2q %%xmm2, "e";\n\t" \
+ "paddq "g", "h";\n\t" \
+ "movdq2q %%xmm3, "g";\n\t" \
+ \
+ : \
+ : \
+ : "memory" )
+
+#define WK0(tmp) "movdq2q %%xmm0, "tmp";\n\t" \
+ "pshufd $0xee, %%xmm0, %%xmm0;\n\t"
+
+#define WK1(tmp) "movdq2q %%xmm0, "tmp";\n\t"
+
+/* Message expansion */
+#define I2(i) \
+ asm volatile ("movdqu %[inbuf], %%xmm0;\n\t" \
+ "pshufb %%xmm6, %%xmm0;\n\t" \
+ "movdqu %%xmm0, %[w];\n\t" \
+ "paddq %[k], %%xmm0;\n\t" \
+ : \
+ : [k] "m" (K[i]), \
+ [w] "m" (w[i]), \
+ [inbuf] "m" (data[(i)*8]) \
+ : "memory" )
+
+#define W2(i) \
+ asm volatile ("movdqu %[w_t_m_2], %%xmm2;\n\t" \
+ "movdqa %%xmm2, %%xmm0;\n\t" \
+ "movdqu %[w_t_m_15], %%xmm5;\n\t" \
+ : \
+ : [w_t_m_2] "m" (w[(i)-2]), \
+ [w_t_m_15] "m" (w[(i)-15]) \
+ : "memory" ); \
+ asm volatile ("movdqa %%xmm5, %%xmm3;\n\t" \
+ "psrlq $(61-19), %%xmm0;\n\t" \
+ "psrlq $(8-7), %%xmm3;\n\t" \
+ "pxor %%xmm2, %%xmm0;\n\t" \
+ "pxor %%xmm5, %%xmm3;\n\t" \
+ "psrlq $(19-6), %%xmm0;\n\t" \
+ "psrlq $(7-1), %%xmm3;\n\t" \
+ "pxor %%xmm2, %%xmm0;\n\t" \
+ "pxor %%xmm5, %%xmm3;\n\t" \
+ "psrlq $6, %%xmm0;\n\t" \
+ "psrlq $1, %%xmm3;\n\t" \
+ "movdqa %%xmm2, %%xmm1;\n\t" \
+ "movdqa %%xmm5, %%xmm4;\n\t" \
+ "psllq $(61-19), %%xmm1;\n\t" \
+ "psllq $(8-1), %%xmm4;\n\t" \
+ "pxor %%xmm2, %%xmm1;\n\t" \
+ "pxor %%xmm5, %%xmm4;\n\t" \
+ "psllq $(64-61), %%xmm1;\n\t" \
+ "psllq $(64-8), %%xmm4;\n\t" \
+ "pxor %%xmm1, %%xmm0;\n\t" \
+ "movdqu %[w_t_m_16], %%xmm2;\n\t" \
+ "pxor %%xmm4, %%xmm3;\n\t" \
+ "movdqu %[w_t_m_7], %%xmm1;\n\t" \
+ : \
+ : [w_t_m_7] "m" (w[(i)-7]), \
+ [w_t_m_16] "m" (w[(i)-16]) \
+ : "memory" ); \
+ asm volatile ("paddq %%xmm3, %%xmm0;\n\t" \
+ "paddq %%xmm2, %%xmm0;\n\t" \
+ "paddq %%xmm1, %%xmm0;\n\t" \
+ "movdqu %%xmm0, %[w_t_m_0];\n\t" \
+ "paddq %[k], %%xmm0;\n\t" \
+ : [w_t_m_0] "=m" (w[(i)-0]) \
+ : [k] "m" (K[i]) \
+ : "memory" )
+
+unsigned int ASM_FUNC_ATTR
+_gcry_sha512_transform_i386_ssse3(u64 state[8], const unsigned char *data,
+ size_t nblks)
+{
+ unsigned int t;
+ u64 w[80];
+
+ /* Load state to MMX registers. */
+ asm volatile ("movq 8*0(%[state]), "RA";\n\t"
+ "movq 8*1(%[state]), "RB";\n\t"
+ "movq 8*2(%[state]), "RC";\n\t"
+ "movq 8*3(%[state]), "RD";\n\t"
+ "movq 8*4(%[state]), "RE";\n\t"
+ "movq 8*5(%[state]), "RF";\n\t"
+ "movq 8*6(%[state]), "RG";\n\t"
+ "movq 8*7(%[state]), "RH";\n\t"
+ :
+ : [state] "r" (state)
+ : "memory" );
+
+ asm volatile ("movdqa %[bshuf_mask], %%xmm6;\n\t"
+ :
+ : [bshuf_mask] "m" (*bshuf_mask)
+ : "memory" );
+
+ while (nblks)
+ {
+ I2(0);
+ Rx(RA, RB, RC, RD, RE, RF, RG, RH, WK0);
+ Rx(RH, RA, RB, RC, RD, RE, RF, RG, WK1);
+ I2(2);
+ Rx(RG, RH, RA, RB, RC, RD, RE, RF, WK0);
+ Rx(RF, RG, RH, RA, RB, RC, RD, RE, WK1);
+ I2(4);
+ Rx(RE, RF, RG, RH, RA, RB, RC, RD, WK0);
+ Rx(RD, RE, RF, RG, RH, RA, RB, RC, WK1);
+ I2(6);
+ Rx(RC, RD, RE, RF, RG, RH, RA, RB, WK0);
+ Rx(RB, RC, RD, RE, RF, RG, RH, RA, WK1);
+ I2(8);
+ Rx(RA, RB, RC, RD, RE, RF, RG, RH, WK0);
+ Rx(RH, RA, RB, RC, RD, RE, RF, RG, WK1);
+ I2(10);
+ Rx(RG, RH, RA, RB, RC, RD, RE, RF, WK0);
+ Rx(RF, RG, RH, RA, RB, RC, RD, RE, WK1);
+ I2(12);
+ Rx(RE, RF, RG, RH, RA, RB, RC, RD, WK0);
+ Rx(RD, RE, RF, RG, RH, RA, RB, RC, WK1);
+ I2(14);
+ Rx(RC, RD, RE, RF, RG, RH, RA, RB, WK0);
+ Rx(RB, RC, RD, RE, RF, RG, RH, RA, WK1);
+ data += 128;
+
+ for (t = 16; t < 80; t += 16)
+ {
+ W2(t + 0);
+ Rx(RA, RB, RC, RD, RE, RF, RG, RH, WK0);
+ Rx(RH, RA, RB, RC, RD, RE, RF, RG, WK1);
+ W2(t + 2);
+ Rx(RG, RH, RA, RB, RC, RD, RE, RF, WK0);
+ Rx(RF, RG, RH, RA, RB, RC, RD, RE, WK1);
+ W2(t + 4);
+ Rx(RE, RF, RG, RH, RA, RB, RC, RD, WK0);
+ Rx(RD, RE, RF, RG, RH, RA, RB, RC, WK1);
+ W2(t + 6);
+ Rx(RC, RD, RE, RF, RG, RH, RA, RB, WK0);
+ Rx(RB, RC, RD, RE, RF, RG, RH, RA, WK1);
+ W2(t + 8);
+ Rx(RA, RB, RC, RD, RE, RF, RG, RH, WK0);
+ Rx(RH, RA, RB, RC, RD, RE, RF, RG, WK1);
+ W2(t + 10);
+ Rx(RG, RH, RA, RB, RC, RD, RE, RF, WK0);
+ Rx(RF, RG, RH, RA, RB, RC, RD, RE, WK1);
+ W2(t + 12);
+ Rx(RE, RF, RG, RH, RA, RB, RC, RD, WK0);
+ Rx(RD, RE, RF, RG, RH, RA, RB, RC, WK1);
+ W2(t + 14);
+ Rx(RC, RD, RE, RF, RG, RH, RA, RB, WK0);
+ Rx(RB, RC, RD, RE, RF, RG, RH, RA, WK1);
+ }
+
+ asm volatile ("paddq 8*0(%[state]), "RA";\n\t"
+ "paddq 8*1(%[state]), "RB";\n\t"
+ "paddq 8*2(%[state]), "RC";\n\t"
+ "paddq 8*3(%[state]), "RD";\n\t"
+ "paddq 8*4(%[state]), "RE";\n\t"
+ "paddq 8*5(%[state]), "RF";\n\t"
+ "paddq 8*6(%[state]), "RG";\n\t"
+ "paddq 8*7(%[state]), "RH";\n\t"
+ "movq "RA", 8*0(%[state]);\n\t"
+ "movq "RB", 8*1(%[state]);\n\t"
+ "movq "RC", 8*2(%[state]);\n\t"
+ "movq "RD", 8*3(%[state]);\n\t"
+ "movq "RE", 8*4(%[state]);\n\t"
+ "movq "RF", 8*5(%[state]);\n\t"
+ "movq "RG", 8*6(%[state]);\n\t"
+ "movq "RH", 8*7(%[state]);\n\t"
+ :
+ : [state] "r" (state)
+ : "memory" );
+
+ nblks--;
+ }
+
+ /* Clear registers */
+ 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 %%mm0, %%mm0;\n\t"
+ "pxor %%mm1, %%mm1;\n\t"
+ "pxor %%mm2, %%mm2;\n\t"
+ "pxor %%mm3, %%mm3;\n\t"
+ "pxor %%mm4, %%mm4;\n\t"
+ "pxor %%mm5, %%mm5;\n\t"
+ "pxor %%mm6, %%mm6;\n\t"
+ "pxor %%mm7, %%mm7;\n\t"
+ "emms;\n\t"
+ :
+ :
+ : "memory" );
+
+ return sizeof(w);
+}
+
+#if __clang__
+# pragma clang attribute pop
+# pragma clang attribute pop
+#endif
+
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/sha512.c b/comm/third_party/libgcrypt/cipher/sha512.c
new file mode 100644
index 0000000000..bc4657a8b9
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sha512.c
@@ -0,0 +1,1316 @@
+/* sha512.c - SHA384 and SHA512 hash functions
+ * Copyright (C) 2003, 2008, 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Test vectors from FIPS-180-2:
+ *
+ * "abc"
+ * 384:
+ * CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163
+ * 1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7
+ * 512:
+ * DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
+ * 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
+ *
+ * "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
+ * 384:
+ * 09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2
+ * 2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039
+ * 512:
+ * 8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018
+ * 501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909
+ *
+ * "a" x 1000000
+ * 384:
+ * 9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852
+ * 7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985
+ * 512:
+ * E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB
+ * DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B
+ */
+
+
+#include <config.h>
+#include <string.h>
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+/* USE_ARM_NEON_ASM indicates whether to enable ARM NEON assembly code. */
+#undef USE_ARM_NEON_ASM
+#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_ARM_NEON_ASM 1
+# endif
+#endif /*ENABLE_NEON_SUPPORT*/
+
+
+/* USE_ARM_ASM indicates whether to enable ARM assembly code. */
+#undef USE_ARM_ASM
+#if defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS)
+# define USE_ARM_ASM 1
+#endif
+
+
+/* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
+#undef USE_SSSE3
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_SSSE3 1
+#endif
+
+
+/* USE_AVX indicates whether to compile with Intel AVX code. */
+#undef USE_AVX
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX 1
+#endif
+
+
+/* USE_AVX2 indicates whether to compile with Intel AVX2/rorx code. */
+#undef USE_AVX2
+#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
+ defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+ defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
+# define USE_AVX2 1
+#endif
+
+
+/* USE_SSSE3_I386 indicates whether to compile with Intel SSSE3/i386 code. */
+#undef USE_SSSE3_I386
+#if defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 && \
+ defined(HAVE_GCC_INLINE_ASM_SSSE3)
+# define USE_SSSE3_I386 1
+#endif
+
+
+/* USE_PPC_CRYPTO indicates whether to enable PowerPC vector crypto
+ * accelerated code. */
+#undef USE_PPC_CRYPTO
+#ifdef ENABLE_PPC_CRYPTO_SUPPORT
+# if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC)
+# if __GNUC__ >= 4
+# define USE_PPC_CRYPTO 1
+# endif
+# endif
+#endif
+
+
+/* USE_S390X_CRYPTO indicates whether to enable zSeries code. */
+#undef USE_S390X_CRYPTO
+#if defined(HAVE_GCC_INLINE_ASM_S390X)
+# define USE_S390X_CRYPTO 1
+#endif /* USE_S390X_CRYPTO */
+
+
+typedef struct
+{
+ u64 h0, h1, h2, h3, h4, h5, h6, h7;
+} SHA512_STATE;
+
+typedef struct
+{
+ gcry_md_block_ctx_t bctx;
+ SHA512_STATE state;
+#ifdef USE_S390X_CRYPTO
+ u64 final_len_msb, final_len_lsb; /* needs to be right after state.h7. */
+ int use_s390x_crypto;
+#endif
+} SHA512_CONTEXT;
+
+
+static const u64 k[] =
+ {
+ U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
+ U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
+ U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
+ U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
+ U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
+ U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
+ U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
+ U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
+ U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
+ U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
+ U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
+ U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
+ U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
+ U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
+ U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
+ U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
+ U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
+ U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
+ U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
+ U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
+ U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
+ U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
+ U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
+ U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
+ U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
+ U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
+ U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
+ U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
+ U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
+ U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
+ U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
+ U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
+ U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
+ U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
+ U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
+ U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
+ U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
+ U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
+ U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
+ U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
+ };
+
+
+/* AMD64 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_SSSE3) || defined(USE_AVX) || defined(USE_AVX2)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# define ASM_EXTRA_STACK (10 * 16 + 4 * sizeof(void *))
+# else
+# define ASM_FUNC_ABI
+# define ASM_EXTRA_STACK 0
+# endif
+#endif
+
+
+#ifdef USE_ARM_NEON_ASM
+unsigned int _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd,
+ const unsigned char *data,
+ const u64 k[], size_t num_blks);
+
+static unsigned int
+do_sha512_transform_armv7_neon(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA512_CONTEXT *hd = ctx;
+ return _gcry_sha512_transform_armv7_neon (&hd->state, data, k, nblks);
+}
+#endif
+
+#ifdef USE_SSSE3
+unsigned int _gcry_sha512_transform_amd64_ssse3(const void *input_data,
+ void *state,
+ size_t num_blks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha512_transform_amd64_ssse3(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA512_CONTEXT *hd = ctx;
+ return _gcry_sha512_transform_amd64_ssse3 (data, &hd->state, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif
+
+#ifdef USE_AVX
+unsigned int _gcry_sha512_transform_amd64_avx(const void *input_data,
+ void *state,
+ size_t num_blks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha512_transform_amd64_avx(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA512_CONTEXT *hd = ctx;
+ return _gcry_sha512_transform_amd64_avx (data, &hd->state, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif
+
+#ifdef USE_AVX2
+unsigned int _gcry_sha512_transform_amd64_avx2(const void *input_data,
+ void *state,
+ size_t num_blks) ASM_FUNC_ABI;
+
+static unsigned int
+do_sha512_transform_amd64_avx2(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA512_CONTEXT *hd = ctx;
+ return _gcry_sha512_transform_amd64_avx2 (data, &hd->state, nblks)
+ + ASM_EXTRA_STACK;
+}
+#endif
+
+#ifdef USE_SSSE3_I386
+unsigned int _gcry_sha512_transform_i386_ssse3(u64 state[8],
+ const unsigned char *input_data,
+ size_t num_blks);
+
+static unsigned int
+do_sha512_transform_i386_ssse3(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA512_CONTEXT *hd = ctx;
+ return _gcry_sha512_transform_i386_ssse3 (&hd->state.h0, data, nblks);
+}
+#endif
+
+
+#ifdef USE_ARM_ASM
+unsigned int _gcry_sha512_transform_arm (SHA512_STATE *hd,
+ const unsigned char *data,
+ const u64 k[], size_t num_blks);
+
+static unsigned int
+do_transform_generic (void *context, const unsigned char *data, size_t nblks)
+{
+ SHA512_CONTEXT *hd = context;
+ return _gcry_sha512_transform_arm (&hd->state, data, k, nblks);
+}
+#else
+static unsigned int
+do_transform_generic (void *context, const unsigned char *data, size_t nblks);
+#endif
+
+
+#ifdef USE_PPC_CRYPTO
+unsigned int _gcry_sha512_transform_ppc8(u64 state[8],
+ const unsigned char *input_data,
+ size_t num_blks);
+
+unsigned int _gcry_sha512_transform_ppc9(u64 state[8],
+ const unsigned char *input_data,
+ size_t num_blks);
+
+static unsigned int
+do_sha512_transform_ppc8(void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA512_CONTEXT *hd = ctx;
+ return _gcry_sha512_transform_ppc8 (&hd->state.h0, data, nblks);
+}
+
+static unsigned int
+do_sha512_transform_ppc9(void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA512_CONTEXT *hd = ctx;
+ return _gcry_sha512_transform_ppc9 (&hd->state.h0, data, nblks);
+}
+#endif
+
+
+#ifdef USE_S390X_CRYPTO
+#include "asm-inline-s390x.h"
+
+static unsigned int
+do_sha512_transform_s390x (void *ctx, const unsigned char *data, size_t nblks)
+{
+ SHA512_CONTEXT *hd = ctx;
+
+ kimd_execute (KMID_FUNCTION_SHA512, &hd->state.h0, data, nblks * 128);
+ return 0;
+}
+
+static unsigned int
+do_sha512_final_s390x (void *ctx, const unsigned char *data, size_t datalen,
+ u64 len_msb, u64 len_lsb)
+{
+ SHA512_CONTEXT *hd = ctx;
+
+ /* Make sure that 'final_len' is positioned at correct offset relative
+ * to 'state.h0'. This is because we are passing 'state.h0' pointer as start of
+ * parameter block to 'klmd' instruction. */
+
+ gcry_assert (offsetof (SHA512_CONTEXT, final_len_msb)
+ - offsetof (SHA512_CONTEXT, state.h0) == 8 * sizeof(u64));
+ gcry_assert (offsetof (SHA512_CONTEXT, final_len_lsb)
+ - offsetof (SHA512_CONTEXT, final_len_msb) == 1 * sizeof(u64));
+
+ hd->final_len_msb = len_msb;
+ hd->final_len_lsb = len_lsb;
+
+ klmd_execute (KMID_FUNCTION_SHA512, &hd->state.h0, data, datalen);
+ return 0;
+}
+#endif
+
+
+static void
+sha512_init_common (SHA512_CONTEXT *ctx, unsigned int flags)
+{
+ unsigned int features = _gcry_get_hw_features ();
+
+ (void)flags;
+ (void)k;
+
+ ctx->bctx.nblocks = 0;
+ ctx->bctx.nblocks_high = 0;
+ ctx->bctx.count = 0;
+ ctx->bctx.blocksize_shift = _gcry_ctz(128);
+
+ /* Order of feature checks is important here; last match will be
+ * selected. Keep slower implementations at the top and faster at
+ * the bottom. */
+ ctx->bctx.bwrite = do_transform_generic;
+#ifdef USE_ARM_NEON_ASM
+ if ((features & HWF_ARM_NEON) != 0)
+ ctx->bctx.bwrite = do_sha512_transform_armv7_neon;
+#endif
+#ifdef USE_SSSE3
+ if ((features & HWF_INTEL_SSSE3) != 0)
+ ctx->bctx.bwrite = do_sha512_transform_amd64_ssse3;
+#endif
+#ifdef USE_AVX
+ if ((features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD))
+ ctx->bctx.bwrite = do_sha512_transform_amd64_avx;
+#endif
+#ifdef USE_AVX2
+ if ((features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2))
+ ctx->bctx.bwrite = do_sha512_transform_amd64_avx2;
+#endif
+#ifdef USE_PPC_CRYPTO
+ if ((features & HWF_PPC_VCRYPTO) != 0)
+ ctx->bctx.bwrite = do_sha512_transform_ppc8;
+ if ((features & HWF_PPC_VCRYPTO) != 0 && (features & HWF_PPC_ARCH_3_00) != 0)
+ ctx->bctx.bwrite = do_sha512_transform_ppc9;
+#endif
+#ifdef USE_SSSE3_I386
+ if ((features & HWF_INTEL_SSSE3) != 0)
+ ctx->bctx.bwrite = do_sha512_transform_i386_ssse3;
+#endif
+#ifdef USE_S390X_CRYPTO
+ ctx->use_s390x_crypto = 0;
+ if ((features & HWF_S390X_MSA) != 0)
+ {
+ if ((kimd_query () & km_function_to_mask (KMID_FUNCTION_SHA512)) &&
+ (klmd_query () & km_function_to_mask (KMID_FUNCTION_SHA512)))
+ {
+ ctx->bctx.bwrite = do_sha512_transform_s390x;
+ ctx->use_s390x_crypto = 1;
+ }
+ }
+#endif
+ (void)features;
+}
+
+
+static void
+sha512_init (void *context, unsigned int flags)
+{
+ SHA512_CONTEXT *ctx = context;
+ SHA512_STATE *hd = &ctx->state;
+
+ hd->h0 = U64_C(0x6a09e667f3bcc908);
+ hd->h1 = U64_C(0xbb67ae8584caa73b);
+ hd->h2 = U64_C(0x3c6ef372fe94f82b);
+ hd->h3 = U64_C(0xa54ff53a5f1d36f1);
+ hd->h4 = U64_C(0x510e527fade682d1);
+ hd->h5 = U64_C(0x9b05688c2b3e6c1f);
+ hd->h6 = U64_C(0x1f83d9abfb41bd6b);
+ hd->h7 = U64_C(0x5be0cd19137e2179);
+
+ sha512_init_common (ctx, flags);
+}
+
+static void
+sha384_init (void *context, unsigned int flags)
+{
+ SHA512_CONTEXT *ctx = context;
+ SHA512_STATE *hd = &ctx->state;
+
+ hd->h0 = U64_C(0xcbbb9d5dc1059ed8);
+ hd->h1 = U64_C(0x629a292a367cd507);
+ hd->h2 = U64_C(0x9159015a3070dd17);
+ hd->h3 = U64_C(0x152fecd8f70e5939);
+ hd->h4 = U64_C(0x67332667ffc00b31);
+ hd->h5 = U64_C(0x8eb44a8768581511);
+ hd->h6 = U64_C(0xdb0c2e0d64f98fa7);
+ hd->h7 = U64_C(0x47b5481dbefa4fa4);
+
+ sha512_init_common (ctx, flags);
+}
+
+
+static void
+sha512_256_init (void *context, unsigned int flags)
+{
+ SHA512_CONTEXT *ctx = context;
+ SHA512_STATE *hd = &ctx->state;
+
+ hd->h0 = U64_C(0x22312194fc2bf72c);
+ hd->h1 = U64_C(0x9f555fa3c84c64c2);
+ hd->h2 = U64_C(0x2393b86b6f53b151);
+ hd->h3 = U64_C(0x963877195940eabd);
+ hd->h4 = U64_C(0x96283ee2a88effe3);
+ hd->h5 = U64_C(0xbe5e1e2553863992);
+ hd->h6 = U64_C(0x2b0199fc2c85b8aa);
+ hd->h7 = U64_C(0x0eb72ddc81c52ca2);
+
+ sha512_init_common (ctx, flags);
+}
+
+
+static void
+sha512_224_init (void *context, unsigned int flags)
+{
+ SHA512_CONTEXT *ctx = context;
+ SHA512_STATE *hd = &ctx->state;
+
+ hd->h0 = U64_C(0x8c3d37c819544da2);
+ hd->h1 = U64_C(0x73e1996689dcd4d6);
+ hd->h2 = U64_C(0x1dfab7ae32ff9c82);
+ hd->h3 = U64_C(0x679dd514582f9fcf);
+ hd->h4 = U64_C(0x0f6d2b697bd44da8);
+ hd->h5 = U64_C(0x77e36f7304c48942);
+ hd->h6 = U64_C(0x3f9d85a86a1d36c8);
+ hd->h7 = U64_C(0x1112e6ad91d692a1);
+
+ sha512_init_common (ctx, flags);
+}
+
+
+
+#ifndef USE_ARM_ASM
+
+static inline u64
+ROTR (u64 x, u64 n)
+{
+ return ((x >> n) | (x << (64 - n)));
+}
+
+static inline u64
+Ch (u64 x, u64 y, u64 z)
+{
+ return ((x & y) ^ ( ~x & z));
+}
+
+static inline u64
+Maj (u64 x, u64 y, u64 z)
+{
+ return ((x & y) ^ (x & z) ^ (y & z));
+}
+
+static inline u64
+Sum0 (u64 x)
+{
+ return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39));
+}
+
+static inline u64
+Sum1 (u64 x)
+{
+ return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
+}
+
+/****************
+ * Transform the message W which consists of 16 64-bit-words
+ */
+static unsigned int
+do_transform_generic (void *context, const unsigned char *data, size_t nblks)
+{
+ SHA512_CONTEXT *ctx = context;
+ SHA512_STATE *hd = &ctx->state;
+
+ do
+ {
+ u64 a, b, c, d, e, f, g, h;
+ u64 w[16];
+ int t;
+
+ /* get values from the chaining vars */
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+ for ( t = 0; t < 16; t++ )
+ w[t] = buf_get_be64(data + t * 8);
+
+#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
+#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+
+ for (t = 0; t < 80 - 16; )
+ {
+ u64 t1, t2;
+
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0];
+ w[0] += S1 (w[14]) + w[9] + S0 (w[1]);
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1];
+ w[1] += S1 (w[15]) + w[10] + S0 (w[2]);
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2];
+ w[2] += S1 (w[0]) + w[11] + S0 (w[3]);
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3];
+ w[3] += S1 (w[1]) + w[12] + S0 (w[4]);
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4];
+ w[4] += S1 (w[2]) + w[13] + S0 (w[5]);
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5];
+ w[5] += S1 (w[3]) + w[14] + S0 (w[6]);
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6];
+ w[6] += S1 (w[4]) + w[15] + S0 (w[7]);
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7];
+ w[7] += S1 (w[5]) + w[0] + S0 (w[8]);
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8];
+ w[8] += S1 (w[6]) + w[1] + S0 (w[9]);
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9];
+ w[9] += S1 (w[7]) + w[2] + S0 (w[10]);
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10];
+ w[10] += S1 (w[8]) + w[3] + S0 (w[11]);
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11];
+ w[11] += S1 (w[9]) + w[4] + S0 (w[12]);
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12];
+ w[12] += S1 (w[10]) + w[5] + S0 (w[13]);
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13];
+ w[13] += S1 (w[11]) + w[6] + S0 (w[14]);
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14];
+ w[14] += S1 (w[12]) + w[7] + S0 (w[15]);
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15];
+ w[15] += S1 (w[13]) + w[8] + S0 (w[0]);
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t += 16;
+ }
+
+ for (; t < 80; )
+ {
+ u64 t1, t2;
+
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t += 16;
+ }
+
+ /* Update chaining vars. */
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+
+ data += 128;
+ }
+ while (--nblks);
+
+ return (8 + 16) * sizeof(u64) + sizeof(u32) + 3 * sizeof(void*);
+}
+#endif /*!USE_ARM_ASM*/
+
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 64 bytes representing the digest. When used for sha384,
+ * we take the leftmost 48 of those bytes.
+ */
+
+static void
+sha512_final (void *context)
+{
+ SHA512_CONTEXT *hd = context;
+ unsigned int burn;
+ u64 t, th, msb, lsb;
+ byte *p;
+
+ t = hd->bctx.nblocks;
+ /* if (sizeof t == sizeof hd->bctx.nblocks) */
+ th = hd->bctx.nblocks_high;
+ /* else */
+ /* th = hd->bctx.nblocks >> 64; In case we ever use u128 */
+
+ /* multiply by 128 to make a byte count */
+ lsb = t << 7;
+ msb = (th << 7) | (t >> 57);
+ /* add the count */
+ t = lsb;
+ if ((lsb += hd->bctx.count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 61;
+
+ if (0)
+ { }
+#ifdef USE_S390X_CRYPTO
+ else if (hd->use_s390x_crypto)
+ {
+ burn = do_sha512_final_s390x (hd, hd->bctx.buf, hd->bctx.count, msb, lsb);
+ }
+#endif
+ else
+ {
+ if (hd->bctx.count < 112)
+ {
+ /* enough room */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ if (hd->bctx.count < 112)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 112 - hd->bctx.count);
+ }
+ else
+ {
+ /* need one extra block */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ if (hd->bctx.count < 128)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 128 - hd->bctx.count);
+ hd->bctx.count = 128;
+ _gcry_md_block_write (context, NULL, 0); /* flush */
+ memset (hd->bctx.buf, 0, 112); /* fill next block with zeroes */
+ }
+ /* append the 128 bit count */
+ buf_put_be64(hd->bctx.buf + 112, msb);
+ buf_put_be64(hd->bctx.buf + 120, lsb);
+ burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 1);
+ }
+
+ p = hd->bctx.buf;
+#define X(a) do { buf_put_be64(p, hd->state.h##a); p += 8; } while (0)
+ X (0);
+ X (1);
+ X (2);
+ X (3);
+ X (4);
+ X (5);
+ /* Note that these last two chunks are included even for SHA384.
+ We just ignore them. */
+ X (6);
+ X (7);
+#undef X
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (burn);
+}
+
+static byte *
+sha512_read (void *context)
+{
+ SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
+ return hd->bctx.buf;
+}
+
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 64 bytes. */
+void
+_gcry_sha512_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SHA512_CONTEXT hd;
+
+ sha512_init (&hd, 0);
+ _gcry_md_block_write (&hd, buffer, length);
+ sha512_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 64);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers. */
+void
+_gcry_sha512_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+ SHA512_CONTEXT hd;
+
+ sha512_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ sha512_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 64);
+}
+
+
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 48 bytes. */
+static void
+_gcry_sha384_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SHA512_CONTEXT hd;
+
+ sha384_init (&hd, 0);
+ _gcry_md_block_write (&hd, buffer, length);
+ sha512_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 48);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers. */
+static void
+_gcry_sha384_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+ SHA512_CONTEXT hd;
+
+ sha384_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ sha512_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 48);
+}
+
+
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 32 bytes. */
+static void
+_gcry_sha512_256_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SHA512_CONTEXT hd;
+
+ sha512_256_init (&hd, 0);
+ _gcry_md_block_write (&hd, buffer, length);
+ sha512_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 32);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers. */
+static void
+_gcry_sha512_256_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+ int iovcnt)
+{
+ SHA512_CONTEXT hd;
+
+ sha512_256_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ sha512_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 32);
+}
+
+
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 28 bytes. */
+static void
+_gcry_sha512_224_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SHA512_CONTEXT hd;
+
+ sha512_224_init (&hd, 0);
+ _gcry_md_block_write (&hd, buffer, length);
+ sha512_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 28);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers. */
+static void
+_gcry_sha512_224_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+ int iovcnt)
+{
+ SHA512_CONTEXT hd;
+
+ sha512_224_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ sha512_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 28);
+}
+
+
+
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha384 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA384, 0,
+ "abc", 3,
+ "\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", 48);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA384, 0,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47"
+ "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12"
+ "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39",
+ 48);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA384, 1,
+ NULL, 0,
+ "\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",
+ 48);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA384, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_sha512 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512, 0,
+ "abc", 3,
+ "\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", 64);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512, 0,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F"
+ "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18"
+ "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A"
+ "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09",
+ 64);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512, 1,
+ NULL, 0,
+ "\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",
+ 64);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA512, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_sha512_224 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512_224, 0,
+ "abc", 3,
+ "\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",
+ 28);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512_224, 0,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ "\x23\xFE\xC5\xBB\x94\xD6\x0B\x23\x30\x81\x92\x64\x0B\x0C\x45\x33"
+ "\x35\xD6\x64\x73\x4F\xE4\x0E\x72\x68\x67\x4A\xF9",
+ 28);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512_224, 1,
+ NULL, 0,
+ "\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",
+ 28);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA512_224, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_sha512_256 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512_256, 0,
+ "abc", 3,
+ "\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",
+ 32);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512_256, 0,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ "\x39\x28\xE1\x84\xFB\x86\x90\xF8\x40\xDA\x39\x88\x12\x1D\x31\xBE"
+ "\x65\xCB\x9D\x3E\xF8\x3E\xE6\x14\x6F\xEA\xC8\x61\xE1\x9B\x56\x3A",
+ 32);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512_256, 1,
+ NULL, 0,
+ "\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",
+ 32);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA512_256, 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_MD_SHA384:
+ ec = selftests_sha384 (extended, report);
+ break;
+ case GCRY_MD_SHA512:
+ ec = selftests_sha512 (extended, report);
+ break;
+ case GCRY_MD_SHA512_224:
+ ec = selftests_sha512_224 (extended, report);
+ break;
+ case GCRY_MD_SHA512_256:
+ ec = selftests_sha512_256 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+
+static byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */
+ {
+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
+ 0x00, 0x04, 0x40
+ };
+
+static gcry_md_oid_spec_t oid_spec_sha512[] =
+ {
+ { "2.16.840.1.101.3.4.2.3" },
+
+ /* PKCS#1 sha512WithRSAEncryption */
+ { "1.2.840.113549.1.1.13" },
+
+ { NULL }
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha512 =
+ {
+ GCRY_MD_SHA512, {0, 1},
+ "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
+ sha512_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
+ _gcry_sha512_hash_buffer, _gcry_sha512_hash_buffers,
+ sizeof (SHA512_CONTEXT),
+ run_selftests
+ };
+
+static byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */
+ {
+ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
+ 0x00, 0x04, 0x30
+ };
+
+static gcry_md_oid_spec_t oid_spec_sha384[] =
+ {
+ { "2.16.840.1.101.3.4.2.2" },
+
+ /* PKCS#1 sha384WithRSAEncryption */
+ { "1.2.840.113549.1.1.12" },
+
+ /* SHA384WithECDSA: RFC 7427 (A.3.3.) */
+ { "1.2.840.10045.4.3.3" },
+
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha384 =
+ {
+ GCRY_MD_SHA384, {0, 1},
+ "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
+ sha384_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
+ _gcry_sha384_hash_buffer, _gcry_sha384_hash_buffers,
+ sizeof (SHA512_CONTEXT),
+ run_selftests
+ };
+
+static byte sha512_256_asn[] = { 0x30 };
+
+static gcry_md_oid_spec_t oid_spec_sha512_256[] =
+ {
+ { "2.16.840.1.101.3.4.2.6" },
+
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha512_256 =
+ {
+ GCRY_MD_SHA512_256, {0, 1},
+ "SHA512_256", sha512_256_asn, DIM (sha512_256_asn), oid_spec_sha512_256, 32,
+ sha512_256_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
+ _gcry_sha512_256_hash_buffer, _gcry_sha512_256_hash_buffers,
+ sizeof (SHA512_CONTEXT),
+ run_selftests
+ };
+
+static byte sha512_224_asn[] = { 0x30 };
+
+static gcry_md_oid_spec_t oid_spec_sha512_224[] =
+ {
+ { "2.16.840.1.101.3.4.2.5" },
+
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha512_224 =
+ {
+ GCRY_MD_SHA512_224, {0, 1},
+ "SHA512_224", sha512_224_asn, DIM (sha512_224_asn), oid_spec_sha512_224, 28,
+ sha512_224_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
+ _gcry_sha512_224_hash_buffer, _gcry_sha512_224_hash_buffers,
+ sizeof (SHA512_CONTEXT),
+ run_selftests
+ };
diff --git a/comm/third_party/libgcrypt/cipher/sm3.c b/comm/third_party/libgcrypt/cipher/sm3.c
new file mode 100644
index 0000000000..0f9bae3bf5
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sm3.c
@@ -0,0 +1,473 @@
+/* sm3.c - SM3 hash function
+ * Copyright (C) 2017 Jia Zhang
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Test vectors:
+
+ "abc"
+ SM3: 66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0
+
+ "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"
+ SM3: debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732
+
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ SM3: 639b6cc5 e64d9e37 a390b192 df4fa1ea 0720ab74 7ff692b9 f38c4e66 ad7b8c05
+
+ "a" one million times
+ SM3: c8aaf894 29554029 e231941a 2acc0ad6 1ff2a5ac d8fadd25 847a3a73 2b3b02c3
+
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+typedef struct {
+ gcry_md_block_ctx_t bctx;
+ u32 h0,h1,h2,h3,h4,h5,h6,h7;
+} SM3_CONTEXT;
+
+
+static unsigned int
+transform (void *c, const unsigned char *data, size_t nblks);
+
+
+static void
+sm3_init (void *context, unsigned int flags)
+{
+ SM3_CONTEXT *hd = context;
+ unsigned int features = _gcry_get_hw_features ();
+
+ (void)flags;
+
+ hd->h0 = 0x7380166f;
+ hd->h1 = 0x4914b2b9;
+ hd->h2 = 0x172442d7;
+ hd->h3 = 0xda8a0600;
+ hd->h4 = 0xa96f30bc;
+ hd->h5 = 0x163138aa;
+ hd->h6 = 0xe38dee4d;
+ hd->h7 = 0xb0fb0e4e;
+
+ hd->bctx.nblocks = 0;
+ hd->bctx.nblocks_high = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize_shift = _gcry_ctz(64);
+ hd->bctx.bwrite = transform;
+
+ (void)features;
+}
+
+
+/*
+ Transform the message X which consists of 16 32-bit-words. See
+ GM/T 004-2012 for details. */
+#define R(i,a,b,c,d,e,f,g,h,t,w1,w2) do \
+ { \
+ ss1 = rol ((rol ((a), 12) + (e) + (t)), 7); \
+ ss2 = ss1 ^ rol ((a), 12); \
+ d += FF##i(a,b,c) + ss2 + ((w1) ^ (w2)); \
+ h += GG##i(e,f,g) + ss1 + (w1); \
+ b = rol ((b), 9); \
+ f = rol ((f), 19); \
+ h = P0 ((h)); \
+ } while (0)
+
+#define R1(a,b,c,d,e,f,g,h,t,w1,w2) R(1,a,b,c,d,e,f,g,h,t,w1,w2)
+#define R2(a,b,c,d,e,f,g,h,t,w1,w2) R(2,a,b,c,d,e,f,g,h,t,w1,w2)
+
+#define FF1(x, y, z) (x ^ y ^ z)
+
+#define FF2(x, y, z) ((x & y) | (x & z) | (y & z))
+
+#define GG1(x, y, z) (x ^ y ^ z)
+
+#define GG2(x, y, z) ((x & y) | ( ~x & z))
+
+/* Message expansion */
+#define P0(x) ((x) ^ rol ((x), 9) ^ rol ((x), 17))
+#define P1(x) ((x) ^ rol ((x), 15) ^ rol ((x), 23))
+#define I(i) ( w[i] = buf_get_be32(data + i * 4) )
+#define W1(i) ( w[i&0x0f] )
+#define W2(i) ( w[i&0x0f] = P1(w[i &0x0f] \
+ ^ w[(i-9)&0x0f] \
+ ^ rol (w[(i-3)&0x0f], 15)) \
+ ^ rol (w[(i-13)&0x0f], 7) \
+ ^ w[(i-6)&0x0f] )
+
+static unsigned int
+transform_blk (void *ctx, const unsigned char *data)
+{
+ SM3_CONTEXT *hd = ctx;
+ static const u32 K[64] = {
+ 0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb,
+ 0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc,
+ 0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce,
+ 0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6,
+ 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
+ 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
+ 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
+ 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
+ 0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53,
+ 0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d,
+ 0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4,
+ 0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43,
+ 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
+ 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
+ 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
+ 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5
+ };
+
+ u32 a,b,c,d,e,f,g,h,ss1,ss2;
+ u32 w[16];
+
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+ R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4));
+ R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5));
+ R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6));
+ R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7));
+ R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8));
+ R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9));
+ R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10));
+ R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11));
+ R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12));
+ R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13));
+ R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14));
+ R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15));
+ R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16));
+ R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17));
+ R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18));
+ R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19));
+
+ R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20));
+ R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21));
+ R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22));
+ R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23));
+ R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24));
+ R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25));
+ R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26));
+ R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27));
+ R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28));
+ R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29));
+ R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30));
+ R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31));
+ R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32));
+ R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33));
+ R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34));
+ R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35));
+
+ R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36));
+ R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37));
+ R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38));
+ R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39));
+ R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40));
+ R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41));
+ R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42));
+ R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43));
+ R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44));
+ R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45));
+ R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46));
+ R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47));
+ R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48));
+ R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49));
+ R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50));
+ R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51));
+
+ R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52));
+ R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53));
+ R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54));
+ R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55));
+ R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56));
+ R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57));
+ R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58));
+ R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59));
+ R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60));
+ R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61));
+ R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62));
+ R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63));
+ R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64));
+ R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65));
+ R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66));
+ R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67));
+
+ hd->h0 ^= a;
+ hd->h1 ^= b;
+ hd->h2 ^= c;
+ hd->h3 ^= d;
+ hd->h4 ^= e;
+ hd->h5 ^= f;
+ hd->h6 ^= g;
+ hd->h7 ^= h;
+
+ return /*burn_stack*/ 26*4+32;
+}
+#undef P0
+#undef P1
+#undef R
+#undef R1
+#undef R2
+
+static unsigned int
+transform (void *ctx, const unsigned char *data, size_t nblks)
+{
+ SM3_CONTEXT *hd = ctx;
+ unsigned int burn;
+
+ do
+ {
+ burn = transform_blk (hd, data);
+ data += 64;
+ }
+ while (--nblks);
+
+ return burn;
+}
+
+
+/*
+ The routine finally terminates the computation and returns the
+ digest. The handle is prepared for a new cycle, but adding bytes
+ to the handle will the destroy the returned buffer. Returns: 32
+ bytes with the message the digest. */
+static void
+sm3_final(void *context)
+{
+ SM3_CONTEXT *hd = context;
+ u32 t, th, msb, lsb;
+ byte *p;
+ unsigned int burn;
+
+ t = hd->bctx.nblocks;
+ if (sizeof t == sizeof hd->bctx.nblocks)
+ th = hd->bctx.nblocks_high;
+ else
+ th = hd->bctx.nblocks >> 32;
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = (th << 6) | (t >> 26);
+ /* add the count */
+ t = lsb;
+ if ((lsb += hd->bctx.count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->bctx.count < 56) /* enough room */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ if (hd->bctx.count < 56)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+
+ /* append the 64 bit count */
+ buf_put_be32(hd->bctx.buf + 56, msb);
+ buf_put_be32(hd->bctx.buf + 60, lsb);
+ burn = (*hd->bctx.bwrite) ( hd, hd->bctx.buf, 1 );
+ }
+ else /* need one extra block */
+ {
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ /* fill pad and next block with zeroes */
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+
+ /* append the 64 bit count */
+ buf_put_be32(hd->bctx.buf + 64 + 56, msb);
+ buf_put_be32(hd->bctx.buf + 64 + 60, lsb);
+ burn = (*hd->bctx.bwrite) ( hd, hd->bctx.buf, 2 );
+ }
+
+ p = hd->bctx.buf;
+#define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+ X(5);
+ X(6);
+ X(7);
+#undef X
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (burn);
+}
+
+static byte *
+sm3_read (void *context)
+{
+ SM3_CONTEXT *hd = context;
+
+ return hd->bctx.buf;
+}
+
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 32 bytes. */
+void
+_gcry_sm3_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SM3_CONTEXT hd;
+
+ sm3_init (&hd, 0);
+ _gcry_md_block_write (&hd, buffer, length);
+ sm3_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 32);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers. */
+void
+_gcry_sm3_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+ SM3_CONTEXT hd;
+
+ sm3_init (&hd, 0);
+ for (;iovcnt > 0; iov++, iovcnt--)
+ _gcry_md_block_write (&hd,
+ (const char*)iov[0].data + iov[0].off, iov[0].len);
+ sm3_final (&hd);
+ memcpy (outbuf, hd.bctx.buf, 32);
+}
+
+
+
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sm3 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string (spec example 1)";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SM3, 0,
+ "abc", 3,
+ "\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", 32);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string (spec example 2)";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SM3, 0,
+ "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", 64,
+ "\xde\xbe\x9f\xf9\x22\x75\xb8\xa1\x38\x60\x48\x89\xc1\x8e\x5a\x4d"
+ "\x6f\xdb\x70\xe5\x38\x7e\x57\x65\x29\x3d\xcb\xa3\x9c\x0c\x57\x32",
+ 32);
+ if (errtxt)
+ goto failed;
+
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SM3, 0,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+ "\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",
+ 32);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SM3, 1,
+ NULL, 0,
+ "\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",
+ 32);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SM3, 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_MD_SM3:
+ ec = selftests_sm3 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+static byte asn_sm3[] = /* Object ID is 1.2.156.10197.401 */
+ { 0x30, 0x2F, 0x30, 0x0B, 0x06, 0x07, 0x2A, 0x81,
+ 0x1C, 0xCF, 0x55, 0x83, 0x11, 0x05, 0x00, 0x04,
+ 0x20 };
+
+static gcry_md_oid_spec_t oid_spec_sm3[] =
+ {
+ /* China Electronics Standardization Instutute,
+ OID White paper (2015), Table 6 */
+ { "1.2.156.10197.401" },
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sm3 =
+ {
+ GCRY_MD_SM3, {0, 0},
+ "SM3", asn_sm3, DIM (asn_sm3), oid_spec_sm3, 32,
+ sm3_init, _gcry_md_block_write, sm3_final, sm3_read, NULL,
+ _gcry_sm3_hash_buffer, _gcry_sm3_hash_buffers,
+ sizeof (SM3_CONTEXT),
+ run_selftests
+ };
diff --git a/comm/third_party/libgcrypt/cipher/sm4-aesni-avx-amd64.S b/comm/third_party/libgcrypt/cipher/sm4-aesni-avx-amd64.S
new file mode 100644
index 0000000000..3610b98c67
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sm4-aesni-avx-amd64.S
@@ -0,0 +1,987 @@
+/* sm4-avx-aesni-amd64.S - AES-NI/AVX implementation of SM4 cipher
+ *
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on SM4 AES-NI work by Markku-Juhani O. Saarinen at:
+ * https://github.com/mjosaarinen/sm4ni
+ */
+
+#include <config.h>
+
+#ifdef __x86_64
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
+
+#include "asm-common-amd64.h"
+
+/* vector registers */
+#define RX0 %xmm0
+#define RX1 %xmm1
+#define MASK_4BIT %xmm2
+#define RTMP0 %xmm3
+#define RTMP1 %xmm4
+#define RTMP2 %xmm5
+#define RTMP3 %xmm6
+#define RTMP4 %xmm7
+
+#define RA0 %xmm8
+#define RA1 %xmm9
+#define RA2 %xmm10
+#define RA3 %xmm11
+
+#define RB0 %xmm12
+#define RB1 %xmm13
+#define RB2 %xmm14
+#define RB3 %xmm15
+
+#define RNOT %xmm0
+#define RBSWAP %xmm1
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+/* Transpose four 32-bit words between 128-bit vectors. */
+#define transpose_4x4(x0, x1, x2, x3, t1, t2) \
+ vpunpckhdq x1, x0, t2; \
+ vpunpckldq x1, x0, x0; \
+ \
+ vpunpckldq x3, x2, t1; \
+ vpunpckhdq x3, x2, x2; \
+ \
+ vpunpckhqdq t1, x0, x1; \
+ vpunpcklqdq t1, x0, x0; \
+ \
+ vpunpckhqdq x2, t2, x3; \
+ vpunpcklqdq x2, t2, x2;
+
+/* post-SubByte transform. */
+#define transform_pre(x, lo_t, hi_t, mask4bit, tmp0) \
+ vpand x, mask4bit, tmp0; \
+ vpandn x, mask4bit, x; \
+ vpsrld $4, x, x; \
+ \
+ vpshufb tmp0, lo_t, tmp0; \
+ vpshufb x, hi_t, x; \
+ vpxor tmp0, x, x;
+
+/* post-SubByte transform. Note: x has been XOR'ed with mask4bit by
+ * 'vaeslastenc' instruction. */
+#define transform_post(x, lo_t, hi_t, mask4bit, tmp0) \
+ vpandn mask4bit, x, tmp0; \
+ vpsrld $4, x, x; \
+ vpand x, mask4bit, x; \
+ \
+ vpshufb tmp0, lo_t, tmp0; \
+ vpshufb x, hi_t, x; \
+ vpxor tmp0, x, x;
+
+/**********************************************************************
+ 4-way && 8-way SM4 with AES-NI and AVX
+ **********************************************************************/
+
+.text
+.align 16
+
+/*
+ * Following four affine transform look-up tables are from work by
+ * Markku-Juhani O. Saarinen, at https://github.com/mjosaarinen/sm4ni
+ *
+ * These allow exposing SM4 S-Box from AES SubByte.
+ */
+
+/* pre-SubByte affine transform, from SM4 field to AES field. */
+.Lpre_tf_lo_s:
+ .quad 0x9197E2E474720701, 0xC7C1B4B222245157
+.Lpre_tf_hi_s:
+ .quad 0xE240AB09EB49A200, 0xF052B91BF95BB012
+
+/* post-SubByte affine transform, from AES field to SM4 field. */
+.Lpost_tf_lo_s:
+ .quad 0x5B67F2CEA19D0834, 0xEDD14478172BBE82
+.Lpost_tf_hi_s:
+ .quad 0xAE7201DD73AFDC00, 0x11CDBE62CC1063BF
+
+/* For isolating SubBytes from AESENCLAST, inverse shift row */
+.Linv_shift_row:
+ .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
+ .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
+
+/* Inverse shift row + Rotate left by 8 bits on 32-bit words with vpshufb */
+.Linv_shift_row_rol_8:
+ .byte 0x07, 0x00, 0x0d, 0x0a, 0x0b, 0x04, 0x01, 0x0e
+ .byte 0x0f, 0x08, 0x05, 0x02, 0x03, 0x0c, 0x09, 0x06
+
+/* Inverse shift row + Rotate left by 16 bits on 32-bit words with vpshufb */
+.Linv_shift_row_rol_16:
+ .byte 0x0a, 0x07, 0x00, 0x0d, 0x0e, 0x0b, 0x04, 0x01
+ .byte 0x02, 0x0f, 0x08, 0x05, 0x06, 0x03, 0x0c, 0x09
+
+/* Inverse shift row + Rotate left by 24 bits on 32-bit words with vpshufb */
+.Linv_shift_row_rol_24:
+ .byte 0x0d, 0x0a, 0x07, 0x00, 0x01, 0x0e, 0x0b, 0x04
+ .byte 0x05, 0x02, 0x0f, 0x08, 0x09, 0x06, 0x03, 0x0c
+
+/* For CTR-mode IV byteswap */
+.Lbswap128_mask:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+/* For input word byte-swap */
+.Lbswap32_mask:
+ .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
+
+.align 4
+/* 4-bit mask */
+.L0f0f0f0f:
+ .long 0x0f0f0f0f
+
+.align 8
+.globl _gcry_sm4_aesni_avx_expand_key
+ELF(.type _gcry_sm4_aesni_avx_expand_key,@function;)
+_gcry_sm4_aesni_avx_expand_key:
+ /* input:
+ * %rdi: 128-bit key
+ * %rsi: rkey_enc
+ * %rdx: rkey_dec
+ * %rcx: fk array
+ * %r8: ck array
+ */
+ CFI_STARTPROC();
+
+ vmovd 0*4(%rdi), RA0;
+ vmovd 1*4(%rdi), RA1;
+ vmovd 2*4(%rdi), RA2;
+ vmovd 3*4(%rdi), RA3;
+
+ vmovdqa .Lbswap32_mask rRIP, RTMP2;
+ vpshufb RTMP2, RA0, RA0;
+ vpshufb RTMP2, RA1, RA1;
+ vpshufb RTMP2, RA2, RA2;
+ vpshufb RTMP2, RA3, RA3;
+
+ vmovd 0*4(%rcx), RB0;
+ vmovd 1*4(%rcx), RB1;
+ vmovd 2*4(%rcx), RB2;
+ vmovd 3*4(%rcx), RB3;
+ vpxor RB0, RA0, RA0;
+ vpxor RB1, RA1, RA1;
+ vpxor RB2, RA2, RA2;
+ vpxor RB3, RA3, RA3;
+
+ vbroadcastss .L0f0f0f0f rRIP, MASK_4BIT;
+ vmovdqa .Lpre_tf_lo_s rRIP, RTMP4;
+ vmovdqa .Lpre_tf_hi_s rRIP, RB0;
+ vmovdqa .Lpost_tf_lo_s rRIP, RB1;
+ vmovdqa .Lpost_tf_hi_s rRIP, RB2;
+ vmovdqa .Linv_shift_row rRIP, RB3;
+
+#define ROUND(round, s0, s1, s2, s3) \
+ vbroadcastss (4*(round))(%r8), RX0; \
+ vpxor s1, RX0, RX0; \
+ vpxor s2, RX0, RX0; \
+ vpxor s3, RX0, RX0; /* s1 ^ s2 ^ s3 ^ rk */ \
+ \
+ /* sbox, non-linear part */ \
+ transform_pre(RX0, RTMP4, RB0, MASK_4BIT, RTMP0); \
+ vaesenclast MASK_4BIT, RX0, RX0; \
+ transform_post(RX0, RB1, RB2, MASK_4BIT, RTMP0); \
+ \
+ /* linear part */ \
+ vpshufb RB3, RX0, RX0; \
+ vpxor RX0, s0, s0; /* s0 ^ x */ \
+ vpslld $13, RX0, RTMP0; \
+ vpsrld $19, RX0, RTMP1; \
+ vpslld $23, RX0, RTMP2; \
+ vpsrld $9, RX0, RTMP3; \
+ vpxor RTMP0, RTMP1, RTMP1; \
+ vpxor RTMP2, RTMP3, RTMP3; \
+ vpxor RTMP1, s0, s0; /* s0 ^ x ^ rol(x,13) */ \
+ vpxor RTMP3, s0, s0; /* s0 ^ x ^ rol(x,13) ^ rol(x,23) */
+
+ leaq (32*4)(%r8), %rax;
+ leaq (32*4)(%rdx), %rdx;
+.align 16
+.Lroundloop_expand_key:
+ leaq (-4*4)(%rdx), %rdx;
+ ROUND(0, RA0, RA1, RA2, RA3);
+ ROUND(1, RA1, RA2, RA3, RA0);
+ ROUND(2, RA2, RA3, RA0, RA1);
+ ROUND(3, RA3, RA0, RA1, RA2);
+ leaq (4*4)(%r8), %r8;
+ vmovd RA0, (0*4)(%rsi);
+ vmovd RA1, (1*4)(%rsi);
+ vmovd RA2, (2*4)(%rsi);
+ vmovd RA3, (3*4)(%rsi);
+ vmovd RA0, (3*4)(%rdx);
+ vmovd RA1, (2*4)(%rdx);
+ vmovd RA2, (1*4)(%rdx);
+ vmovd RA3, (0*4)(%rdx);
+ leaq (4*4)(%rsi), %rsi;
+ cmpq %rax, %r8;
+ jne .Lroundloop_expand_key;
+
+#undef ROUND
+
+ vzeroall;
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx_expand_key,.-_gcry_sm4_aesni_avx_expand_key;)
+
+.align 8
+ELF(.type sm4_aesni_avx_crypt_blk1_4,@function;)
+sm4_aesni_avx_crypt_blk1_4:
+ /* input:
+ * %rdi: round key array, CTX
+ * %rsi: dst (1..4 blocks)
+ * %rdx: src (1..4 blocks)
+ * %rcx: num blocks (1..4)
+ */
+ CFI_STARTPROC();
+
+ vmovdqu 0*16(%rdx), RA0;
+ vmovdqa RA0, RA1;
+ vmovdqa RA0, RA2;
+ vmovdqa RA0, RA3;
+ cmpq $2, %rcx;
+ jb .Lblk4_load_input_done;
+ vmovdqu 1*16(%rdx), RA1;
+ je .Lblk4_load_input_done;
+ vmovdqu 2*16(%rdx), RA2;
+ cmpq $3, %rcx;
+ je .Lblk4_load_input_done;
+ vmovdqu 3*16(%rdx), RA3;
+
+.Lblk4_load_input_done:
+
+ vmovdqa .Lbswap32_mask rRIP, RTMP2;
+ vpshufb RTMP2, RA0, RA0;
+ vpshufb RTMP2, RA1, RA1;
+ vpshufb RTMP2, RA2, RA2;
+ vpshufb RTMP2, RA3, RA3;
+
+ vbroadcastss .L0f0f0f0f rRIP, MASK_4BIT;
+ vmovdqa .Lpre_tf_lo_s rRIP, RTMP4;
+ vmovdqa .Lpre_tf_hi_s rRIP, RB0;
+ vmovdqa .Lpost_tf_lo_s rRIP, RB1;
+ vmovdqa .Lpost_tf_hi_s rRIP, RB2;
+ vmovdqa .Linv_shift_row rRIP, RB3;
+ vmovdqa .Linv_shift_row_rol_8 rRIP, RTMP2;
+ vmovdqa .Linv_shift_row_rol_16 rRIP, RTMP3;
+ transpose_4x4(RA0, RA1, RA2, RA3, RTMP0, RTMP1);
+
+#define ROUND(round, s0, s1, s2, s3) \
+ vbroadcastss (4*(round))(%rdi), RX0; \
+ vpxor s1, RX0, RX0; \
+ vpxor s2, RX0, RX0; \
+ vpxor s3, RX0, RX0; /* s1 ^ s2 ^ s3 ^ rk */ \
+ \
+ /* sbox, non-linear part */ \
+ transform_pre(RX0, RTMP4, RB0, MASK_4BIT, RTMP0); \
+ vaesenclast MASK_4BIT, RX0, RX0; \
+ transform_post(RX0, RB1, RB2, MASK_4BIT, RTMP0); \
+ \
+ /* linear part */ \
+ vpshufb RB3, RX0, RTMP0; \
+ vpxor RTMP0, s0, s0; /* s0 ^ x */ \
+ vpshufb RTMP2, RX0, RTMP1; \
+ vpxor RTMP1, RTMP0, RTMP0; /* x ^ rol(x,8) */ \
+ vpshufb RTMP3, RX0, RTMP1; \
+ vpxor RTMP1, RTMP0, RTMP0; /* x ^ rol(x,8) ^ rol(x,16) */ \
+ vpshufb .Linv_shift_row_rol_24 rRIP, RX0, RTMP1; \
+ vpxor RTMP1, s0, s0; /* s0 ^ x ^ rol(x,24) */ \
+ vpslld $2, RTMP0, RTMP1; \
+ vpsrld $30, RTMP0, RTMP0; \
+ vpxor RTMP0, s0, s0; \
+ vpxor RTMP1, s0, s0; /* s0 ^ x ^ rol(x,2) ^ rol(x,10) ^ rol(x,18) ^ rol(x,24) */
+
+ leaq (32*4)(%rdi), %rax;
+.align 16
+.Lroundloop_blk4:
+ ROUND(0, RA0, RA1, RA2, RA3);
+ ROUND(1, RA1, RA2, RA3, RA0);
+ ROUND(2, RA2, RA3, RA0, RA1);
+ ROUND(3, RA3, RA0, RA1, RA2);
+ leaq (4*4)(%rdi), %rdi;
+ cmpq %rax, %rdi;
+ jne .Lroundloop_blk4;
+
+#undef ROUND
+
+ vmovdqa .Lbswap128_mask rRIP, RTMP2;
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RTMP0, RTMP1);
+ vpshufb RTMP2, RA0, RA0;
+ vpshufb RTMP2, RA1, RA1;
+ vpshufb RTMP2, RA2, RA2;
+ vpshufb RTMP2, RA3, RA3;
+
+ vmovdqu RA0, 0*16(%rsi);
+ cmpq $2, %rcx;
+ jb .Lblk4_store_output_done;
+ vmovdqu RA1, 1*16(%rsi);
+ je .Lblk4_store_output_done;
+ vmovdqu RA2, 2*16(%rsi);
+ cmpq $3, %rcx;
+ je .Lblk4_store_output_done;
+ vmovdqu RA3, 3*16(%rsi);
+
+.Lblk4_store_output_done:
+ vzeroall;
+ xorl %eax, %eax;
+ ret;
+ CFI_ENDPROC();
+ELF(.size sm4_aesni_avx_crypt_blk1_4,.-sm4_aesni_avx_crypt_blk1_4;)
+
+.align 8
+ELF(.type __sm4_crypt_blk8,@function;)
+__sm4_crypt_blk8:
+ /* input:
+ * %rdi: round key array, CTX
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel
+ * ciphertext blocks
+ * output:
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+ * blocks
+ */
+ CFI_STARTPROC();
+
+ vmovdqa .Lbswap32_mask rRIP, RTMP2;
+ vpshufb RTMP2, RA0, RA0;
+ vpshufb RTMP2, RA1, RA1;
+ vpshufb RTMP2, RA2, RA2;
+ vpshufb RTMP2, RA3, RA3;
+ vpshufb RTMP2, RB0, RB0;
+ vpshufb RTMP2, RB1, RB1;
+ vpshufb RTMP2, RB2, RB2;
+ vpshufb RTMP2, RB3, RB3;
+
+ vbroadcastss .L0f0f0f0f rRIP, MASK_4BIT;
+ transpose_4x4(RA0, RA1, RA2, RA3, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RTMP0, RTMP1);
+
+#define ROUND(round, s0, s1, s2, s3, r0, r1, r2, r3) \
+ vbroadcastss (4*(round))(%rdi), RX0; \
+ vmovdqa .Lpre_tf_lo_s rRIP, RTMP4; \
+ vmovdqa .Lpre_tf_hi_s rRIP, RTMP1; \
+ vmovdqa RX0, RX1; \
+ vpxor s1, RX0, RX0; \
+ vpxor s2, RX0, RX0; \
+ vpxor s3, RX0, RX0; /* s1 ^ s2 ^ s3 ^ rk */ \
+ vmovdqa .Lpost_tf_lo_s rRIP, RTMP2; \
+ vmovdqa .Lpost_tf_hi_s rRIP, RTMP3; \
+ vpxor r1, RX1, RX1; \
+ vpxor r2, RX1, RX1; \
+ vpxor r3, RX1, RX1; /* r1 ^ r2 ^ r3 ^ rk */ \
+ \
+ /* sbox, non-linear part */ \
+ transform_pre(RX0, RTMP4, RTMP1, MASK_4BIT, RTMP0); \
+ transform_pre(RX1, RTMP4, RTMP1, MASK_4BIT, RTMP0); \
+ vmovdqa .Linv_shift_row rRIP, RTMP4; \
+ vaesenclast MASK_4BIT, RX0, RX0; \
+ vaesenclast MASK_4BIT, RX1, RX1; \
+ transform_post(RX0, RTMP2, RTMP3, MASK_4BIT, RTMP0); \
+ transform_post(RX1, RTMP2, RTMP3, MASK_4BIT, RTMP0); \
+ \
+ /* linear part */ \
+ vpshufb RTMP4, RX0, RTMP0; \
+ vpxor RTMP0, s0, s0; /* s0 ^ x */ \
+ vpshufb RTMP4, RX1, RTMP2; \
+ vmovdqa .Linv_shift_row_rol_8 rRIP, RTMP4; \
+ vpxor RTMP2, r0, r0; /* r0 ^ x */ \
+ vpshufb RTMP4, RX0, RTMP1; \
+ vpxor RTMP1, RTMP0, RTMP0; /* x ^ rol(x,8) */ \
+ vpshufb RTMP4, RX1, RTMP3; \
+ vmovdqa .Linv_shift_row_rol_16 rRIP, RTMP4; \
+ vpxor RTMP3, RTMP2, RTMP2; /* x ^ rol(x,8) */ \
+ vpshufb RTMP4, RX0, RTMP1; \
+ vpxor RTMP1, RTMP0, RTMP0; /* x ^ rol(x,8) ^ rol(x,16) */ \
+ vpshufb RTMP4, RX1, RTMP3; \
+ vmovdqa .Linv_shift_row_rol_24 rRIP, RTMP4; \
+ vpxor RTMP3, RTMP2, RTMP2; /* x ^ rol(x,8) ^ rol(x,16) */ \
+ vpshufb RTMP4, RX0, RTMP1; \
+ vpxor RTMP1, s0, s0; /* s0 ^ x ^ rol(x,24) */ \
+ vpslld $2, RTMP0, RTMP1; \
+ vpsrld $30, RTMP0, RTMP0; \
+ vpxor RTMP0, s0, s0; \
+ vpxor RTMP1, s0, s0; /* s0 ^ x ^ rol(x,2) ^ rol(x,10) ^ rol(x,18) ^ rol(x,24) */ \
+ vpshufb RTMP4, RX1, RTMP3; \
+ vpxor RTMP3, r0, r0; /* r0 ^ x ^ rol(x,24) */ \
+ vpslld $2, RTMP2, RTMP3; \
+ vpsrld $30, RTMP2, RTMP2; \
+ vpxor RTMP2, r0, r0; \
+ vpxor RTMP3, r0, r0; /* r0 ^ x ^ rol(x,2) ^ rol(x,10) ^ rol(x,18) ^ rol(x,24) */
+
+ leaq (32*4)(%rdi), %rax;
+.align 16
+.Lroundloop_blk8:
+ ROUND(0, RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3);
+ ROUND(1, RA1, RA2, RA3, RA0, RB1, RB2, RB3, RB0);
+ ROUND(2, RA2, RA3, RA0, RA1, RB2, RB3, RB0, RB1);
+ ROUND(3, RA3, RA0, RA1, RA2, RB3, RB0, RB1, RB2);
+ leaq (4*4)(%rdi), %rdi;
+ cmpq %rax, %rdi;
+ jne .Lroundloop_blk8;
+
+#undef ROUND
+
+ vmovdqa .Lbswap128_mask rRIP, RTMP2;
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RTMP0, RTMP1);
+ vpshufb RTMP2, RA0, RA0;
+ vpshufb RTMP2, RA1, RA1;
+ vpshufb RTMP2, RA2, RA2;
+ vpshufb RTMP2, RA3, RA3;
+ vpshufb RTMP2, RB0, RB0;
+ vpshufb RTMP2, RB1, RB1;
+ vpshufb RTMP2, RB2, RB2;
+ vpshufb RTMP2, RB3, RB3;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __sm4_crypt_blk8,.-__sm4_crypt_blk8;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx_crypt_blk1_8
+ELF(.type _gcry_sm4_aesni_avx_crypt_blk1_8,@function;)
+_gcry_sm4_aesni_avx_crypt_blk1_8:
+ /* input:
+ * %rdi: round key array, CTX
+ * %rsi: dst (1..8 blocks)
+ * %rdx: src (1..8 blocks)
+ * %rcx: num blocks (1..8)
+ */
+ CFI_STARTPROC();
+
+ cmpq $5, %rcx;
+ jb sm4_aesni_avx_crypt_blk1_4;
+ vmovdqu (0 * 16)(%rdx), RA0;
+ vmovdqu (1 * 16)(%rdx), RA1;
+ vmovdqu (2 * 16)(%rdx), RA2;
+ vmovdqu (3 * 16)(%rdx), RA3;
+ vmovdqu (4 * 16)(%rdx), RB0;
+ vmovdqa RB0, RB1;
+ vmovdqa RB0, RB2;
+ vmovdqa RB0, RB3;
+ je .Lblk8_load_input_done;
+ vmovdqu (5 * 16)(%rdx), RB1;
+ cmpq $7, %rcx;
+ jb .Lblk8_load_input_done;
+ vmovdqu (6 * 16)(%rdx), RB2;
+ je .Lblk8_load_input_done;
+ vmovdqu (7 * 16)(%rdx), RB3;
+
+.Lblk8_load_input_done:
+ call __sm4_crypt_blk8;
+
+ cmpq $6, %rcx;
+ vmovdqu RA0, (0 * 16)(%rsi);
+ vmovdqu RA1, (1 * 16)(%rsi);
+ vmovdqu RA2, (2 * 16)(%rsi);
+ vmovdqu RA3, (3 * 16)(%rsi);
+ vmovdqu RB0, (4 * 16)(%rsi);
+ jb .Lblk8_store_output_done;
+ vmovdqu RB1, (5 * 16)(%rsi);
+ je .Lblk8_store_output_done;
+ vmovdqu RB2, (6 * 16)(%rsi);
+ cmpq $7, %rcx;
+ je .Lblk8_store_output_done;
+ vmovdqu RB3, (7 * 16)(%rsi);
+
+.Lblk8_store_output_done:
+ vzeroall;
+ xorl %eax, %eax;
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx_crypt_blk1_8,.-_gcry_sm4_aesni_avx_crypt_blk1_8;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx_ctr_enc
+ELF(.type _gcry_sm4_aesni_avx_ctr_enc,@function;)
+_gcry_sm4_aesni_avx_ctr_enc:
+ /* input:
+ * %rdi: round key array, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: iv (big endian, 128bit)
+ */
+ CFI_STARTPROC();
+
+ /* load IV and byteswap */
+ vmovdqu (%rcx), RA0;
+
+ vmovdqa .Lbswap128_mask rRIP, RBSWAP;
+ vpshufb RBSWAP, RA0, RTMP0; /* be => le */
+
+ vpcmpeqd RNOT, RNOT, RNOT;
+ vpsrldq $8, RNOT, RNOT; /* low: -1, high: 0 */
+
+#define inc_le128(x, minus_one, tmp) \
+ vpcmpeqq minus_one, x, tmp; \
+ vpsubq minus_one, x, x; \
+ vpslldq $8, tmp, tmp; \
+ vpsubq tmp, x, x;
+
+ /* construct IVs */
+ inc_le128(RTMP0, RNOT, RTMP2); /* +1 */
+ vpshufb RBSWAP, RTMP0, RA1;
+ inc_le128(RTMP0, RNOT, RTMP2); /* +2 */
+ vpshufb RBSWAP, RTMP0, RA2;
+ inc_le128(RTMP0, RNOT, RTMP2); /* +3 */
+ vpshufb RBSWAP, RTMP0, RA3;
+ inc_le128(RTMP0, RNOT, RTMP2); /* +4 */
+ vpshufb RBSWAP, RTMP0, RB0;
+ inc_le128(RTMP0, RNOT, RTMP2); /* +5 */
+ vpshufb RBSWAP, RTMP0, RB1;
+ inc_le128(RTMP0, RNOT, RTMP2); /* +6 */
+ vpshufb RBSWAP, RTMP0, RB2;
+ inc_le128(RTMP0, RNOT, RTMP2); /* +7 */
+ vpshufb RBSWAP, RTMP0, RB3;
+ inc_le128(RTMP0, RNOT, RTMP2); /* +8 */
+ vpshufb RBSWAP, RTMP0, RTMP1;
+
+ /* store new IV */
+ vmovdqu RTMP1, (%rcx);
+
+ call __sm4_crypt_blk8;
+
+ vpxor (0 * 16)(%rdx), RA0, RA0;
+ vpxor (1 * 16)(%rdx), RA1, RA1;
+ vpxor (2 * 16)(%rdx), RA2, RA2;
+ vpxor (3 * 16)(%rdx), RA3, RA3;
+ vpxor (4 * 16)(%rdx), RB0, RB0;
+ vpxor (5 * 16)(%rdx), RB1, RB1;
+ vpxor (6 * 16)(%rdx), RB2, RB2;
+ vpxor (7 * 16)(%rdx), RB3, RB3;
+
+ vmovdqu RA0, (0 * 16)(%rsi);
+ vmovdqu RA1, (1 * 16)(%rsi);
+ vmovdqu RA2, (2 * 16)(%rsi);
+ vmovdqu RA3, (3 * 16)(%rsi);
+ vmovdqu RB0, (4 * 16)(%rsi);
+ vmovdqu RB1, (5 * 16)(%rsi);
+ vmovdqu RB2, (6 * 16)(%rsi);
+ vmovdqu RB3, (7 * 16)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx_ctr_enc,.-_gcry_sm4_aesni_avx_ctr_enc;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx_cbc_dec
+ELF(.type _gcry_sm4_aesni_avx_cbc_dec,@function;)
+_gcry_sm4_aesni_avx_cbc_dec:
+ /* input:
+ * %rdi: round key array, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ vmovdqu (0 * 16)(%rdx), RA0;
+ vmovdqu (1 * 16)(%rdx), RA1;
+ vmovdqu (2 * 16)(%rdx), RA2;
+ vmovdqu (3 * 16)(%rdx), RA3;
+ vmovdqu (4 * 16)(%rdx), RB0;
+ vmovdqu (5 * 16)(%rdx), RB1;
+ vmovdqu (6 * 16)(%rdx), RB2;
+ vmovdqu (7 * 16)(%rdx), RB3;
+
+ call __sm4_crypt_blk8;
+
+ vmovdqu (7 * 16)(%rdx), RNOT;
+ vpxor (%rcx), RA0, RA0;
+ vpxor (0 * 16)(%rdx), RA1, RA1;
+ vpxor (1 * 16)(%rdx), RA2, RA2;
+ vpxor (2 * 16)(%rdx), RA3, RA3;
+ vpxor (3 * 16)(%rdx), RB0, RB0;
+ vpxor (4 * 16)(%rdx), RB1, RB1;
+ vpxor (5 * 16)(%rdx), RB2, RB2;
+ vpxor (6 * 16)(%rdx), RB3, RB3;
+ vmovdqu RNOT, (%rcx); /* store new IV */
+
+ vmovdqu RA0, (0 * 16)(%rsi);
+ vmovdqu RA1, (1 * 16)(%rsi);
+ vmovdqu RA2, (2 * 16)(%rsi);
+ vmovdqu RA3, (3 * 16)(%rsi);
+ vmovdqu RB0, (4 * 16)(%rsi);
+ vmovdqu RB1, (5 * 16)(%rsi);
+ vmovdqu RB2, (6 * 16)(%rsi);
+ vmovdqu RB3, (7 * 16)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx_cbc_dec,.-_gcry_sm4_aesni_avx_cbc_dec;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx_cfb_dec
+ELF(.type _gcry_sm4_aesni_avx_cfb_dec,@function;)
+_gcry_sm4_aesni_avx_cfb_dec:
+ /* input:
+ * %rdi: round key array, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ /* Load input */
+ vmovdqu (%rcx), RA0;
+ vmovdqu 0 * 16(%rdx), RA1;
+ vmovdqu 1 * 16(%rdx), RA2;
+ vmovdqu 2 * 16(%rdx), RA3;
+ vmovdqu 3 * 16(%rdx), RB0;
+ vmovdqu 4 * 16(%rdx), RB1;
+ vmovdqu 5 * 16(%rdx), RB2;
+ vmovdqu 6 * 16(%rdx), RB3;
+
+ /* Update IV */
+ vmovdqu 7 * 16(%rdx), RNOT;
+ vmovdqu RNOT, (%rcx);
+
+ call __sm4_crypt_blk8;
+
+ vpxor (0 * 16)(%rdx), RA0, RA0;
+ vpxor (1 * 16)(%rdx), RA1, RA1;
+ vpxor (2 * 16)(%rdx), RA2, RA2;
+ vpxor (3 * 16)(%rdx), RA3, RA3;
+ vpxor (4 * 16)(%rdx), RB0, RB0;
+ vpxor (5 * 16)(%rdx), RB1, RB1;
+ vpxor (6 * 16)(%rdx), RB2, RB2;
+ vpxor (7 * 16)(%rdx), RB3, RB3;
+
+ vmovdqu RA0, (0 * 16)(%rsi);
+ vmovdqu RA1, (1 * 16)(%rsi);
+ vmovdqu RA2, (2 * 16)(%rsi);
+ vmovdqu RA3, (3 * 16)(%rsi);
+ vmovdqu RB0, (4 * 16)(%rsi);
+ vmovdqu RB1, (5 * 16)(%rsi);
+ vmovdqu RB2, (6 * 16)(%rsi);
+ vmovdqu RB3, (7 * 16)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx_cfb_dec,.-_gcry_sm4_aesni_avx_cfb_dec;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx_ocb_enc
+ELF(.type _gcry_sm4_aesni_avx_ocb_enc,@function;)
+
+_gcry_sm4_aesni_avx_ocb_enc:
+ /* input:
+ * %rdi: round key array, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[8])
+ */
+ CFI_STARTPROC();
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rcx), RTMP0;
+ vmovdqu (%r8), RTMP1;
+
+ /* 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) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ vmovdqu (n * 16)(%rdx), xreg; \
+ vpxor (lreg), RTMP0, RTMP0; \
+ vpxor xreg, RTMP1, RTMP1; \
+ vpxor RTMP0, xreg, xreg; \
+ vmovdqu RTMP0, (n * 16)(%rsi);
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, RA0);
+ OCB_INPUT(1, %r11, RA1);
+ OCB_INPUT(2, %r12, RA2);
+ OCB_INPUT(3, %r13, RA3);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, RB0);
+ OCB_INPUT(5, %r11, RB1);
+ OCB_INPUT(6, %r12, RB2);
+ OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0, (%rcx);
+ vmovdqu RTMP1, (%r8);
+
+ movq (0 * 8)(%rsp), %r10;
+ CFI_RESTORE(%r10);
+ movq (1 * 8)(%rsp), %r11;
+ CFI_RESTORE(%r11);
+ movq (2 * 8)(%rsp), %r12;
+ CFI_RESTORE(%r12);
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r13);
+
+ call __sm4_crypt_blk8;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vpxor (0 * 16)(%rsi), RA0, RA0;
+ vpxor (1 * 16)(%rsi), RA1, RA1;
+ vpxor (2 * 16)(%rsi), RA2, RA2;
+ vpxor (3 * 16)(%rsi), RA3, RA3;
+ vpxor (4 * 16)(%rsi), RB0, RB0;
+ vpxor (5 * 16)(%rsi), RB1, RB1;
+ vpxor (6 * 16)(%rsi), RB2, RB2;
+ vpxor (7 * 16)(%rsi), RB3, RB3;
+
+ vmovdqu RA0, (0 * 16)(%rsi);
+ vmovdqu RA1, (1 * 16)(%rsi);
+ vmovdqu RA2, (2 * 16)(%rsi);
+ vmovdqu RA3, (3 * 16)(%rsi);
+ vmovdqu RB0, (4 * 16)(%rsi);
+ vmovdqu RB1, (5 * 16)(%rsi);
+ vmovdqu RB2, (6 * 16)(%rsi);
+ vmovdqu RB3, (7 * 16)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx_ocb_enc,.-_gcry_sm4_aesni_avx_ocb_enc;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx_ocb_dec
+ELF(.type _gcry_sm4_aesni_avx_ocb_dec,@function;)
+
+_gcry_sm4_aesni_avx_ocb_dec:
+ /* input:
+ * %rdi: round key array, CTX
+ * %rsi: dst (8 blocks)
+ * %rdx: src (8 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[8])
+ */
+ CFI_STARTPROC();
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ movdqu (%rcx), RTMP0;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ vmovdqu (n * 16)(%rdx), xreg; \
+ vpxor (lreg), RTMP0, RTMP0; \
+ vpxor RTMP0, xreg, xreg; \
+ vmovdqu RTMP0, (n * 16)(%rsi);
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, RA0);
+ OCB_INPUT(1, %r11, RA1);
+ OCB_INPUT(2, %r12, RA2);
+ OCB_INPUT(3, %r13, RA3);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, RB0);
+ OCB_INPUT(5, %r11, RB1);
+ OCB_INPUT(6, %r12, RB2);
+ OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0, (%rcx);
+
+ movq (0 * 8)(%rsp), %r10;
+ CFI_RESTORE(%r10);
+ movq (1 * 8)(%rsp), %r11;
+ CFI_RESTORE(%r11);
+ movq (2 * 8)(%rsp), %r12;
+ CFI_RESTORE(%r12);
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r13);
+
+ call __sm4_crypt_blk8;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vmovdqu (%r8), RTMP0;
+
+ vpxor (0 * 16)(%rsi), RA0, RA0;
+ vpxor (1 * 16)(%rsi), RA1, RA1;
+ vpxor (2 * 16)(%rsi), RA2, RA2;
+ vpxor (3 * 16)(%rsi), RA3, RA3;
+ vpxor (4 * 16)(%rsi), RB0, RB0;
+ vpxor (5 * 16)(%rsi), RB1, RB1;
+ vpxor (6 * 16)(%rsi), RB2, RB2;
+ vpxor (7 * 16)(%rsi), RB3, RB3;
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+
+ vmovdqu RA0, (0 * 16)(%rsi);
+ vpxor RA0, RTMP0, RTMP0;
+ vmovdqu RA1, (1 * 16)(%rsi);
+ vpxor RA1, RTMP0, RTMP0;
+ vmovdqu RA2, (2 * 16)(%rsi);
+ vpxor RA2, RTMP0, RTMP0;
+ vmovdqu RA3, (3 * 16)(%rsi);
+ vpxor RA3, RTMP0, RTMP0;
+ vmovdqu RB0, (4 * 16)(%rsi);
+ vpxor RB0, RTMP0, RTMP0;
+ vmovdqu RB1, (5 * 16)(%rsi);
+ vpxor RB1, RTMP0, RTMP0;
+ vmovdqu RB2, (6 * 16)(%rsi);
+ vpxor RB2, RTMP0, RTMP0;
+ vmovdqu RB3, (7 * 16)(%rsi);
+ vpxor RB3, RTMP0, RTMP0;
+
+ vmovdqu RTMP0, (%r8);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx_ocb_dec,.-_gcry_sm4_aesni_avx_ocb_dec;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx_ocb_auth
+ELF(.type _gcry_sm4_aesni_avx_ocb_auth,@function;)
+
+_gcry_sm4_aesni_avx_ocb_auth:
+ /* input:
+ * %rdi: round key array, CTX
+ * %rsi: abuf (8 blocks)
+ * %rdx: offset
+ * %rcx: checksum
+ * %r8 : L pointers (void *L[8])
+ */
+ CFI_STARTPROC();
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rdx), RTMP0;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+
+#define OCB_INPUT(n, lreg, xreg) \
+ vmovdqu (n * 16)(%rsi), xreg; \
+ vpxor (lreg), RTMP0, RTMP0; \
+ vpxor RTMP0, xreg, xreg;
+ movq (0 * 8)(%r8), %r10;
+ movq (1 * 8)(%r8), %r11;
+ movq (2 * 8)(%r8), %r12;
+ movq (3 * 8)(%r8), %r13;
+ OCB_INPUT(0, %r10, RA0);
+ OCB_INPUT(1, %r11, RA1);
+ OCB_INPUT(2, %r12, RA2);
+ OCB_INPUT(3, %r13, RA3);
+ movq (4 * 8)(%r8), %r10;
+ movq (5 * 8)(%r8), %r11;
+ movq (6 * 8)(%r8), %r12;
+ movq (7 * 8)(%r8), %r13;
+ OCB_INPUT(4, %r10, RB0);
+ OCB_INPUT(5, %r11, RB1);
+ OCB_INPUT(6, %r12, RB2);
+ OCB_INPUT(7, %r13, RB3);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0, (%rdx);
+
+ movq (0 * 8)(%rsp), %r10;
+ CFI_RESTORE(%r10);
+ movq (1 * 8)(%rsp), %r11;
+ CFI_RESTORE(%r11);
+ movq (2 * 8)(%rsp), %r12;
+ CFI_RESTORE(%r12);
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r13);
+
+ call __sm4_crypt_blk8;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vmovdqu (%rcx), RTMP0;
+ vpxor RB0, RA0, RA0;
+ vpxor RB1, RA1, RA1;
+ vpxor RB2, RA2, RA2;
+ vpxor RB3, RA3, RA3;
+
+ vpxor RTMP0, RA3, RA3;
+ vpxor RA2, RA0, RA0;
+ vpxor RA3, RA1, RA1;
+
+ vpxor RA1, RA0, RA0;
+ vmovdqu RA0, (%rcx);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx_ocb_auth,.-_gcry_sm4_aesni_avx_ocb_auth;)
+
+#endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/sm4-aesni-avx2-amd64.S b/comm/third_party/libgcrypt/cipher/sm4-aesni-avx2-amd64.S
new file mode 100644
index 0000000000..6e46c0dca8
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sm4-aesni-avx2-amd64.S
@@ -0,0 +1,851 @@
+/* sm4-avx2-amd64.S - AVX2 implementation of SM4 cipher
+ *
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on SM4 AES-NI work by Markku-Juhani O. Saarinen at:
+ * https://github.com/mjosaarinen/sm4ni
+ */
+
+#include <config.h>
+
+#ifdef __x86_64
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
+ defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
+
+#include "asm-common-amd64.h"
+
+/* vector registers */
+#define RX0 %ymm0
+#define RX1 %ymm1
+#define MASK_4BIT %ymm2
+#define RTMP0 %ymm3
+#define RTMP1 %ymm4
+#define RTMP2 %ymm5
+#define RTMP3 %ymm6
+#define RTMP4 %ymm7
+
+#define RA0 %ymm8
+#define RA1 %ymm9
+#define RA2 %ymm10
+#define RA3 %ymm11
+
+#define RB0 %ymm12
+#define RB1 %ymm13
+#define RB2 %ymm14
+#define RB3 %ymm15
+
+#define RNOT %ymm0
+#define RBSWAP %ymm1
+
+#define RX0x %xmm0
+#define RX1x %xmm1
+#define MASK_4BITx %xmm2
+
+#define RNOTx %xmm0
+#define RBSWAPx %xmm1
+
+#define RTMP0x %xmm3
+#define RTMP1x %xmm4
+#define RTMP2x %xmm5
+#define RTMP3x %xmm6
+#define RTMP4x %xmm7
+
+/**********************************************************************
+ helper macros
+ **********************************************************************/
+
+/* Transpose four 32-bit words between 128-bit vector lanes. */
+#define transpose_4x4(x0, x1, x2, x3, t1, t2) \
+ vpunpckhdq x1, x0, t2; \
+ vpunpckldq x1, x0, x0; \
+ \
+ vpunpckldq x3, x2, t1; \
+ vpunpckhdq x3, x2, x2; \
+ \
+ vpunpckhqdq t1, x0, x1; \
+ vpunpcklqdq t1, x0, x0; \
+ \
+ vpunpckhqdq x2, t2, x3; \
+ vpunpcklqdq x2, t2, x2;
+
+/* post-SubByte transform. */
+#define transform_pre(x, lo_t, hi_t, mask4bit, tmp0) \
+ vpand x, mask4bit, tmp0; \
+ vpandn x, mask4bit, x; \
+ vpsrld $4, x, x; \
+ \
+ vpshufb tmp0, lo_t, tmp0; \
+ vpshufb x, hi_t, x; \
+ vpxor tmp0, x, x;
+
+/* post-SubByte transform. Note: x has been XOR'ed with mask4bit by
+ * 'vaeslastenc' instruction. */
+#define transform_post(x, lo_t, hi_t, mask4bit, tmp0) \
+ vpandn mask4bit, x, tmp0; \
+ vpsrld $4, x, x; \
+ vpand x, mask4bit, x; \
+ \
+ vpshufb tmp0, lo_t, tmp0; \
+ vpshufb x, hi_t, x; \
+ vpxor tmp0, x, x;
+
+/**********************************************************************
+ 16-way SM4 with AES-NI and AVX
+ **********************************************************************/
+
+.text
+.align 16
+
+/*
+ * Following four affine transform look-up tables are from work by
+ * Markku-Juhani O. Saarinen, at https://github.com/mjosaarinen/sm4ni
+ *
+ * These allow exposing SM4 S-Box from AES SubByte.
+ */
+
+/* pre-SubByte affine transform, from SM4 field to AES field. */
+.Lpre_tf_lo_s:
+ .quad 0x9197E2E474720701, 0xC7C1B4B222245157
+.Lpre_tf_hi_s:
+ .quad 0xE240AB09EB49A200, 0xF052B91BF95BB012
+
+/* post-SubByte affine transform, from AES field to SM4 field. */
+.Lpost_tf_lo_s:
+ .quad 0x5B67F2CEA19D0834, 0xEDD14478172BBE82
+.Lpost_tf_hi_s:
+ .quad 0xAE7201DD73AFDC00, 0x11CDBE62CC1063BF
+
+/* For isolating SubBytes from AESENCLAST, inverse shift row */
+.Linv_shift_row:
+ .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
+ .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
+
+/* Inverse shift row + Rotate left by 8 bits on 32-bit words with vpshufb */
+.Linv_shift_row_rol_8:
+ .byte 0x07, 0x00, 0x0d, 0x0a, 0x0b, 0x04, 0x01, 0x0e
+ .byte 0x0f, 0x08, 0x05, 0x02, 0x03, 0x0c, 0x09, 0x06
+
+/* Inverse shift row + Rotate left by 16 bits on 32-bit words with vpshufb */
+.Linv_shift_row_rol_16:
+ .byte 0x0a, 0x07, 0x00, 0x0d, 0x0e, 0x0b, 0x04, 0x01
+ .byte 0x02, 0x0f, 0x08, 0x05, 0x06, 0x03, 0x0c, 0x09
+
+/* Inverse shift row + Rotate left by 24 bits on 32-bit words with vpshufb */
+.Linv_shift_row_rol_24:
+ .byte 0x0d, 0x0a, 0x07, 0x00, 0x01, 0x0e, 0x0b, 0x04
+ .byte 0x05, 0x02, 0x0f, 0x08, 0x09, 0x06, 0x03, 0x0c
+
+/* For CTR-mode IV byteswap */
+.Lbswap128_mask:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+/* For input word byte-swap */
+.Lbswap32_mask:
+ .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
+
+.align 4
+/* 4-bit mask */
+.L0f0f0f0f:
+ .long 0x0f0f0f0f
+
+.align 8
+ELF(.type __sm4_crypt_blk16,@function;)
+__sm4_crypt_blk16:
+ /* input:
+ * %rdi: ctx, CTX
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: sixteen parallel
+ * plaintext blocks
+ * output:
+ * RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: sixteen parallel
+ * ciphertext blocks
+ */
+ CFI_STARTPROC();
+
+ vbroadcasti128 .Lbswap32_mask rRIP, RTMP2;
+ vpshufb RTMP2, RA0, RA0;
+ vpshufb RTMP2, RA1, RA1;
+ vpshufb RTMP2, RA2, RA2;
+ vpshufb RTMP2, RA3, RA3;
+ vpshufb RTMP2, RB0, RB0;
+ vpshufb RTMP2, RB1, RB1;
+ vpshufb RTMP2, RB2, RB2;
+ vpshufb RTMP2, RB3, RB3;
+
+ vpbroadcastd .L0f0f0f0f rRIP, MASK_4BIT;
+ transpose_4x4(RA0, RA1, RA2, RA3, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RTMP0, RTMP1);
+
+#define ROUND(round, s0, s1, s2, s3, r0, r1, r2, r3) \
+ vpbroadcastd (4*(round))(%rdi), RX0; \
+ vbroadcasti128 .Lpre_tf_lo_s rRIP, RTMP4; \
+ vbroadcasti128 .Lpre_tf_hi_s rRIP, RTMP1; \
+ vmovdqa RX0, RX1; \
+ vpxor s1, RX0, RX0; \
+ vpxor s2, RX0, RX0; \
+ vpxor s3, RX0, RX0; /* s1 ^ s2 ^ s3 ^ rk */ \
+ vbroadcasti128 .Lpost_tf_lo_s rRIP, RTMP2; \
+ vbroadcasti128 .Lpost_tf_hi_s rRIP, RTMP3; \
+ vpxor r1, RX1, RX1; \
+ vpxor r2, RX1, RX1; \
+ vpxor r3, RX1, RX1; /* r1 ^ r2 ^ r3 ^ rk */ \
+ \
+ /* sbox, non-linear part */ \
+ transform_pre(RX0, RTMP4, RTMP1, MASK_4BIT, RTMP0); \
+ transform_pre(RX1, RTMP4, RTMP1, MASK_4BIT, RTMP0); \
+ vextracti128 $1, RX0, RTMP4x; \
+ vextracti128 $1, RX1, RTMP0x; \
+ vaesenclast MASK_4BITx, RX0x, RX0x; \
+ vaesenclast MASK_4BITx, RTMP4x, RTMP4x; \
+ vaesenclast MASK_4BITx, RX1x, RX1x; \
+ vaesenclast MASK_4BITx, RTMP0x, RTMP0x; \
+ vinserti128 $1, RTMP4x, RX0, RX0; \
+ vbroadcasti128 .Linv_shift_row rRIP, RTMP4; \
+ vinserti128 $1, RTMP0x, RX1, RX1; \
+ transform_post(RX0, RTMP2, RTMP3, MASK_4BIT, RTMP0); \
+ transform_post(RX1, RTMP2, RTMP3, MASK_4BIT, RTMP0); \
+ \
+ /* linear part */ \
+ vpshufb RTMP4, RX0, RTMP0; \
+ vpxor RTMP0, s0, s0; /* s0 ^ x */ \
+ vpshufb RTMP4, RX1, RTMP2; \
+ vbroadcasti128 .Linv_shift_row_rol_8 rRIP, RTMP4; \
+ vpxor RTMP2, r0, r0; /* r0 ^ x */ \
+ vpshufb RTMP4, RX0, RTMP1; \
+ vpxor RTMP1, RTMP0, RTMP0; /* x ^ rol(x,8) */ \
+ vpshufb RTMP4, RX1, RTMP3; \
+ vbroadcasti128 .Linv_shift_row_rol_16 rRIP, RTMP4; \
+ vpxor RTMP3, RTMP2, RTMP2; /* x ^ rol(x,8) */ \
+ vpshufb RTMP4, RX0, RTMP1; \
+ vpxor RTMP1, RTMP0, RTMP0; /* x ^ rol(x,8) ^ rol(x,16) */ \
+ vpshufb RTMP4, RX1, RTMP3; \
+ vbroadcasti128 .Linv_shift_row_rol_24 rRIP, RTMP4; \
+ vpxor RTMP3, RTMP2, RTMP2; /* x ^ rol(x,8) ^ rol(x,16) */ \
+ vpshufb RTMP4, RX0, RTMP1; \
+ vpxor RTMP1, s0, s0; /* s0 ^ x ^ rol(x,24) */ \
+ vpslld $2, RTMP0, RTMP1; \
+ vpsrld $30, RTMP0, RTMP0; \
+ vpxor RTMP0, s0, s0; \
+ vpxor RTMP1, s0, s0; /* s0 ^ x ^ rol(x,2) ^ rol(x,10) ^ rol(x,18) ^ rol(x,24) */ \
+ vpshufb RTMP4, RX1, RTMP3; \
+ vpxor RTMP3, r0, r0; /* r0 ^ x ^ rol(x,24) */ \
+ vpslld $2, RTMP2, RTMP3; \
+ vpsrld $30, RTMP2, RTMP2; \
+ vpxor RTMP2, r0, r0; \
+ vpxor RTMP3, r0, r0; /* r0 ^ x ^ rol(x,2) ^ rol(x,10) ^ rol(x,18) ^ rol(x,24) */
+
+ leaq (32*4)(%rdi), %rax;
+.align 16
+.Lroundloop_blk8:
+ ROUND(0, RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3);
+ ROUND(1, RA1, RA2, RA3, RA0, RB1, RB2, RB3, RB0);
+ ROUND(2, RA2, RA3, RA0, RA1, RB2, RB3, RB0, RB1);
+ ROUND(3, RA3, RA0, RA1, RA2, RB3, RB0, RB1, RB2);
+ leaq (4*4)(%rdi), %rdi;
+ cmpq %rax, %rdi;
+ jne .Lroundloop_blk8;
+
+#undef ROUND
+
+ vbroadcasti128 .Lbswap128_mask rRIP, RTMP2;
+
+ transpose_4x4(RA0, RA1, RA2, RA3, RTMP0, RTMP1);
+ transpose_4x4(RB0, RB1, RB2, RB3, RTMP0, RTMP1);
+ vpshufb RTMP2, RA0, RA0;
+ vpshufb RTMP2, RA1, RA1;
+ vpshufb RTMP2, RA2, RA2;
+ vpshufb RTMP2, RA3, RA3;
+ vpshufb RTMP2, RB0, RB0;
+ vpshufb RTMP2, RB1, RB1;
+ vpshufb RTMP2, RB2, RB2;
+ vpshufb RTMP2, RB3, RB3;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __sm4_crypt_blk16,.-__sm4_crypt_blk16;)
+
+#define inc_le128(x, minus_one, tmp) \
+ vpcmpeqq minus_one, x, tmp; \
+ vpsubq minus_one, x, x; \
+ vpslldq $8, tmp, tmp; \
+ vpsubq tmp, x, x;
+
+.align 8
+.globl _gcry_sm4_aesni_avx2_ctr_enc
+ELF(.type _gcry_sm4_aesni_avx2_ctr_enc,@function;)
+_gcry_sm4_aesni_avx2_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv (big endian, 128bit)
+ */
+ CFI_STARTPROC();
+
+ movq 8(%rcx), %rax;
+ bswapq %rax;
+
+ vzeroupper;
+
+ vbroadcasti128 .Lbswap128_mask rRIP, RTMP3;
+ vpcmpeqd RNOT, RNOT, RNOT;
+ vpsrldq $8, RNOT, RNOT; /* ab: -1:0 ; cd: -1:0 */
+ vpaddq RNOT, RNOT, RTMP2; /* ab: -2:0 ; cd: -2:0 */
+
+ /* load IV and byteswap */
+ vmovdqu (%rcx), RTMP4x;
+ vpshufb RTMP3x, RTMP4x, RTMP4x;
+ vmovdqa RTMP4x, RTMP0x;
+ inc_le128(RTMP4x, RNOTx, RTMP1x);
+ vinserti128 $1, RTMP4x, RTMP0, RTMP0;
+ vpshufb RTMP3, RTMP0, RA0; /* +1 ; +0 */
+
+ /* check need for handling 64-bit overflow and carry */
+ cmpq $(0xffffffffffffffff - 16), %rax;
+ ja .Lhandle_ctr_carry;
+
+ /* construct IVs */
+ vpsubq RTMP2, RTMP0, RTMP0; /* +3 ; +2 */
+ vpshufb RTMP3, RTMP0, RA1;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +5 ; +4 */
+ vpshufb RTMP3, RTMP0, RA2;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +7 ; +6 */
+ vpshufb RTMP3, RTMP0, RA3;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +9 ; +8 */
+ vpshufb RTMP3, RTMP0, RB0;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +11 ; +10 */
+ vpshufb RTMP3, RTMP0, RB1;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +13 ; +12 */
+ vpshufb RTMP3, RTMP0, RB2;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +15 ; +14 */
+ vpshufb RTMP3, RTMP0, RB3;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +16 */
+ vpshufb RTMP3x, RTMP0x, RTMP0x;
+
+ jmp .Lctr_carry_done;
+
+.Lhandle_ctr_carry:
+ /* construct IVs */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RA1; /* +3 ; +2 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RA2; /* +5 ; +4 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RA3; /* +7 ; +6 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB0; /* +9 ; +8 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB1; /* +11 ; +10 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB2; /* +13 ; +12 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB3; /* +15 ; +14 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vextracti128 $1, RTMP0, RTMP0x;
+ vpshufb RTMP3x, RTMP0x, RTMP0x; /* +16 */
+
+.align 4
+.Lctr_carry_done:
+ /* store new IV */
+ vmovdqu RTMP0x, (%rcx);
+
+ call __sm4_crypt_blk16;
+
+ vpxor (0 * 32)(%rdx), RA0, RA0;
+ vpxor (1 * 32)(%rdx), RA1, RA1;
+ vpxor (2 * 32)(%rdx), RA2, RA2;
+ vpxor (3 * 32)(%rdx), RA3, RA3;
+ vpxor (4 * 32)(%rdx), RB0, RB0;
+ vpxor (5 * 32)(%rdx), RB1, RB1;
+ vpxor (6 * 32)(%rdx), RB2, RB2;
+ vpxor (7 * 32)(%rdx), RB3, RB3;
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vmovdqu RA3, (3 * 32)(%rsi);
+ vmovdqu RB0, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vmovdqu RB3, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx2_ctr_enc,.-_gcry_sm4_aesni_avx2_ctr_enc;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx2_cbc_dec
+ELF(.type _gcry_sm4_aesni_avx2_cbc_dec,@function;)
+_gcry_sm4_aesni_avx2_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ vmovdqu (0 * 32)(%rdx), RA0;
+ vmovdqu (1 * 32)(%rdx), RA1;
+ vmovdqu (2 * 32)(%rdx), RA2;
+ vmovdqu (3 * 32)(%rdx), RA3;
+ vmovdqu (4 * 32)(%rdx), RB0;
+ vmovdqu (5 * 32)(%rdx), RB1;
+ vmovdqu (6 * 32)(%rdx), RB2;
+ vmovdqu (7 * 32)(%rdx), RB3;
+
+ call __sm4_crypt_blk16;
+
+ vmovdqu (%rcx), RNOTx;
+ vinserti128 $1, (%rdx), RNOT, RNOT;
+ vpxor RNOT, RA0, RA0;
+ vpxor (0 * 32 + 16)(%rdx), RA1, RA1;
+ vpxor (1 * 32 + 16)(%rdx), RA2, RA2;
+ vpxor (2 * 32 + 16)(%rdx), RA3, RA3;
+ vpxor (3 * 32 + 16)(%rdx), RB0, RB0;
+ vpxor (4 * 32 + 16)(%rdx), RB1, RB1;
+ vpxor (5 * 32 + 16)(%rdx), RB2, RB2;
+ vpxor (6 * 32 + 16)(%rdx), RB3, RB3;
+ vmovdqu (7 * 32 + 16)(%rdx), RNOTx;
+ vmovdqu RNOTx, (%rcx); /* store new IV */
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vmovdqu RA3, (3 * 32)(%rsi);
+ vmovdqu RB0, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vmovdqu RB3, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx2_cbc_dec,.-_gcry_sm4_aesni_avx2_cbc_dec;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx2_cfb_dec
+ELF(.type _gcry_sm4_aesni_avx2_cfb_dec,@function;)
+_gcry_sm4_aesni_avx2_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ /* Load input */
+ vmovdqu (%rcx), RNOTx;
+ vinserti128 $1, (%rdx), RNOT, RA0;
+ vmovdqu (0 * 32 + 16)(%rdx), RA1;
+ vmovdqu (1 * 32 + 16)(%rdx), RA2;
+ vmovdqu (2 * 32 + 16)(%rdx), RA3;
+ vmovdqu (3 * 32 + 16)(%rdx), RB0;
+ vmovdqu (4 * 32 + 16)(%rdx), RB1;
+ vmovdqu (5 * 32 + 16)(%rdx), RB2;
+ vmovdqu (6 * 32 + 16)(%rdx), RB3;
+
+ /* Update IV */
+ vmovdqu (7 * 32 + 16)(%rdx), RNOTx;
+ vmovdqu RNOTx, (%rcx);
+
+ call __sm4_crypt_blk16;
+
+ vpxor (0 * 32)(%rdx), RA0, RA0;
+ vpxor (1 * 32)(%rdx), RA1, RA1;
+ vpxor (2 * 32)(%rdx), RA2, RA2;
+ vpxor (3 * 32)(%rdx), RA3, RA3;
+ vpxor (4 * 32)(%rdx), RB0, RB0;
+ vpxor (5 * 32)(%rdx), RB1, RB1;
+ vpxor (6 * 32)(%rdx), RB2, RB2;
+ vpxor (7 * 32)(%rdx), RB3, RB3;
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vmovdqu RA3, (3 * 32)(%rsi);
+ vmovdqu RB0, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vmovdqu RB3, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx2_cfb_dec,.-_gcry_sm4_aesni_avx2_cfb_dec;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx2_ocb_enc
+ELF(.type _gcry_sm4_aesni_avx2_ocb_enc,@function;)
+
+_gcry_sm4_aesni_avx2_ocb_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rcx), RTMP0x;
+ vmovdqu (%r8), RTMP1x;
+
+ /* 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) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rdx), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RTMP1, RTMP1; \
+ vpxor yreg, RNOT, yreg; \
+ vmovdqu RNOT, (n * 32)(%rsi);
+
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RA1);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(2, %r10, %r11, RA2);
+ OCB_INPUT(3, %r12, %r13, RA3);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %r11, RB0);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(6, %r10, %r11, RB2);
+ OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vmovdqu RTMP0x, (%rcx);
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%r8);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __sm4_crypt_blk16;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vpxor (0 * 32)(%rsi), RA0, RA0;
+ vpxor (1 * 32)(%rsi), RA1, RA1;
+ vpxor (2 * 32)(%rsi), RA2, RA2;
+ vpxor (3 * 32)(%rsi), RA3, RA3;
+ vpxor (4 * 32)(%rsi), RB0, RB0;
+ vpxor (5 * 32)(%rsi), RB1, RB1;
+ vpxor (6 * 32)(%rsi), RB2, RB2;
+ vpxor (7 * 32)(%rsi), RB3, RB3;
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vmovdqu RA3, (3 * 32)(%rsi);
+ vmovdqu RB0, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vmovdqu RB3, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx2_ocb_enc,.-_gcry_sm4_aesni_avx2_ocb_enc;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx2_ocb_dec
+ELF(.type _gcry_sm4_aesni_avx2_ocb_dec,@function;)
+
+_gcry_sm4_aesni_avx2_ocb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rcx), RTMP0x;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rdx), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RNOT, yreg; \
+ vmovdqu RNOT, (n * 32)(%rsi);
+
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RA1);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(2, %r10, %r11, RA2);
+ OCB_INPUT(3, %r12, %r13, RA3);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %r11, RB0);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(6, %r10, %r11, RB2);
+ OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0x, (%rcx);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __sm4_crypt_blk16;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vmovdqu (%r8), RTMP1x;
+
+ vpxor (0 * 32)(%rsi), RA0, RA0;
+ vpxor (1 * 32)(%rsi), RA1, RA1;
+ vpxor (2 * 32)(%rsi), RA2, RA2;
+ vpxor (3 * 32)(%rsi), RA3, RA3;
+ vpxor (4 * 32)(%rsi), RB0, RB0;
+ vpxor (5 * 32)(%rsi), RB1, RB1;
+ vpxor (6 * 32)(%rsi), RB2, RB2;
+ vpxor (7 * 32)(%rsi), RB3, RB3;
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vpxor RA0, RTMP1, RTMP1;
+ vmovdqu RA1, (1 * 32)(%rsi);
+ vpxor RA1, RTMP1, RTMP1;
+ vmovdqu RA2, (2 * 32)(%rsi);
+ vpxor RA2, RTMP1, RTMP1;
+ vmovdqu RA3, (3 * 32)(%rsi);
+ vpxor RA3, RTMP1, RTMP1;
+ vmovdqu RB0, (4 * 32)(%rsi);
+ vpxor RB0, RTMP1, RTMP1;
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vpxor RB1, RTMP1, RTMP1;
+ vmovdqu RB2, (6 * 32)(%rsi);
+ vpxor RB2, RTMP1, RTMP1;
+ vmovdqu RB3, (7 * 32)(%rsi);
+ vpxor RB3, RTMP1, RTMP1;
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%r8);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx2_ocb_dec,.-_gcry_sm4_aesni_avx2_ocb_dec;)
+
+.align 8
+.globl _gcry_sm4_aesni_avx2_ocb_auth
+ELF(.type _gcry_sm4_aesni_avx2_ocb_auth,@function;)
+
+_gcry_sm4_aesni_avx2_ocb_auth:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: abuf (16 blocks)
+ * %rdx: offset
+ * %rcx: checksum
+ * %r8 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rdx), RTMP0x;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rsi), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RNOT, yreg;
+
+ movq (0 * 8)(%r8), %r10;
+ movq (1 * 8)(%r8), %r11;
+ movq (2 * 8)(%r8), %r12;
+ movq (3 * 8)(%r8), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RA1);
+ movq (4 * 8)(%r8), %r10;
+ movq (5 * 8)(%r8), %r11;
+ movq (6 * 8)(%r8), %r12;
+ movq (7 * 8)(%r8), %r13;
+ OCB_INPUT(2, %r10, %r11, RA2);
+ OCB_INPUT(3, %r12, %r13, RA3);
+ movq (8 * 8)(%r8), %r10;
+ movq (9 * 8)(%r8), %r11;
+ movq (10 * 8)(%r8), %r12;
+ movq (11 * 8)(%r8), %r13;
+ OCB_INPUT(4, %r10, %r11, RB0);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r8), %r10;
+ movq (13 * 8)(%r8), %r11;
+ movq (14 * 8)(%r8), %r12;
+ movq (15 * 8)(%r8), %r13;
+ OCB_INPUT(6, %r10, %r11, RB2);
+ OCB_INPUT(7, %r12, %r13, RB3);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0x, (%rdx);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __sm4_crypt_blk16;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vpxor RA0, RB0, RA0;
+ vpxor RA1, RB1, RA1;
+ vpxor RA2, RB2, RA2;
+ vpxor RA3, RB3, RA3;
+
+ vpxor RA1, RA0, RA0;
+ vpxor RA3, RA2, RA2;
+
+ vpxor RA2, RA0, RTMP1;
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vpxor (%rcx), RTMP1x, RTMP1x;
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%rcx);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_sm4_aesni_avx2_ocb_auth,.-_gcry_sm4_aesni_avx2_ocb_auth;)
+
+#endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/sm4.c b/comm/third_party/libgcrypt/cipher/sm4.c
new file mode 100644
index 0000000000..c8dd0406e1
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/sm4.c
@@ -0,0 +1,1251 @@
+/* sm4.c - SM4 Cipher Algorithm
+ * Copyright (C) 2020 Alibaba Group.
+ * Copyright (C) 2020 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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"
+
+/* 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_AVX 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
+
+/* 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)
+# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ASM_FUNC_ABI __attribute__((sysv_abi))
+# else
+# define ASM_FUNC_ABI
+# 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 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
+} SM4_context;
+
+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_8(const u32 *rk, byte *out, const byte *in,
+ unsigned int num_blks)
+{
+ 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;
+#endif /* USE_AESNI_AVX2 */
+
+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_AESNI_AVX
+ if (ctx->use_aesni_avx)
+ {
+ _gcry_sm4_aesni_avx_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
+
+ /* 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->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;
+
+ 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;
+
+ 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 u32 *rk, byte *out, const byte *in,
+ unsigned int num_blks)
+{
+ 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;
+}
+
+/* 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_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
+
+ /* Process remaining blocks. */
+ if (nblocks)
+ {
+ unsigned int (*crypt_blk1_8)(const u32 *rk, byte *out, const byte *in,
+ unsigned int num_blks);
+ byte tmpbuf[16 * 8];
+ unsigned int tmp_used = 16;
+
+ if (0)
+ ;
+#ifdef USE_AESNI_AVX
+ else if (ctx->use_aesni_avx)
+ {
+ crypt_blk1_8 = sm4_aesni_avx_crypt_blk1_8;
+ }
+#endif
+ else
+ {
+ prefetch_sbox_table ();
+ crypt_blk1_8 = sm4_crypt_blocks;
+ }
+
+ /* Process remaining blocks. */
+ while (nblocks)
+ {
+ size_t curr_blks = nblocks > 8 ? 8 : nblocks;
+ size_t i;
+
+ if (curr_blks * 16 > tmp_used)
+ tmp_used = curr_blks * 16;
+
+ cipher_block_cpy (tmpbuf + 0 * 16, ctr, 16);
+ for (i = 1; i < curr_blks; i++)
+ {
+ cipher_block_cpy (&tmpbuf[i * 16], ctr, 16);
+ cipher_block_add (&tmpbuf[i * 16], i, 16);
+ }
+ cipher_block_add (ctr, curr_blks, 16);
+
+ burn_stack_depth = crypt_blk1_8 (ctx->rkey_enc, tmpbuf, tmpbuf,
+ curr_blks);
+
+ for (i = 0; i < curr_blks; i++)
+ {
+ cipher_block_xor (outbuf, &tmpbuf[i * 16], inbuf, 16);
+ outbuf += 16;
+ inbuf += 16;
+ }
+
+ nblocks -= curr_blks;
+ }
+
+ 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_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
+
+ /* Process remaining blocks. */
+ if (nblocks)
+ {
+ unsigned int (*crypt_blk1_8)(const u32 *rk, byte *out, const byte *in,
+ unsigned int num_blks);
+ unsigned char savebuf[16 * 8];
+ unsigned int tmp_used = 16;
+
+ if (0)
+ ;
+#ifdef USE_AESNI_AVX
+ else if (ctx->use_aesni_avx)
+ {
+ crypt_blk1_8 = sm4_aesni_avx_crypt_blk1_8;
+ }
+#endif
+ else
+ {
+ prefetch_sbox_table ();
+ crypt_blk1_8 = sm4_crypt_blocks;
+ }
+
+ /* Process remaining blocks. */
+ while (nblocks)
+ {
+ size_t curr_blks = nblocks > 8 ? 8 : nblocks;
+ size_t i;
+
+ if (curr_blks * 16 > tmp_used)
+ tmp_used = curr_blks * 16;
+
+ burn_stack_depth = crypt_blk1_8 (ctx->rkey_dec, savebuf, inbuf,
+ curr_blks);
+
+ for (i = 0; i < curr_blks; i++)
+ {
+ cipher_block_xor_n_copy_2(outbuf, &savebuf[i * 16], iv, inbuf,
+ 16);
+ outbuf += 16;
+ inbuf += 16;
+ }
+
+ nblocks -= curr_blks;
+ }
+
+ wipememory(savebuf, 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_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
+
+ /* Process remaining blocks. */
+ if (nblocks)
+ {
+ unsigned int (*crypt_blk1_8)(const u32 *rk, byte *out, const byte *in,
+ unsigned int num_blks);
+ unsigned char ivbuf[16 * 8];
+ unsigned int tmp_used = 16;
+
+ if (0)
+ ;
+#ifdef USE_AESNI_AVX
+ else if (ctx->use_aesni_avx)
+ {
+ crypt_blk1_8 = sm4_aesni_avx_crypt_blk1_8;
+ }
+#endif
+ else
+ {
+ prefetch_sbox_table ();
+ crypt_blk1_8 = sm4_crypt_blocks;
+ }
+
+ /* Process remaining blocks. */
+ while (nblocks)
+ {
+ size_t curr_blks = nblocks > 8 ? 8 : nblocks;
+ size_t i;
+
+ if (curr_blks * 16 > tmp_used)
+ tmp_used = curr_blks * 16;
+
+ cipher_block_cpy (&ivbuf[0 * 16], iv, 16);
+ for (i = 1; i < curr_blks; i++)
+ cipher_block_cpy (&ivbuf[i * 16], &inbuf[(i - 1) * 16], 16);
+ cipher_block_cpy (iv, &inbuf[(i - 1) * 16], 16);
+
+ burn_stack_depth = crypt_blk1_8 (ctx->rkey_enc, ivbuf, ivbuf,
+ curr_blks);
+
+ for (i = 0; i < curr_blks; i++)
+ {
+ cipher_block_xor (outbuf, inbuf, &ivbuf[i * 16], 16);
+ outbuf += 16;
+ inbuf += 16;
+ }
+
+ nblocks -= curr_blks;
+ }
+
+ wipememory(ivbuf, 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_AESNI_AVX2
+ if (ctx->use_aesni_avx2)
+ {
+ u64 Ls[16];
+ unsigned int n = 16 - (blkn % 16);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 16)
+ {
+ for (i = 0; i < 16; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(15 + n) % 16];
+
+ /* 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];
+ unsigned int n = 8 - (blkn % 8);
+ u64 *l;
+
+ if (nblocks >= 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(0 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(1 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(2 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(3 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(4 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(5 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(6 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(7 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(7 + n) % 8];
+
+ /* 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
+
+ if (nblocks)
+ {
+ unsigned int (*crypt_blk1_8)(const u32 *rk, byte *out, const byte *in,
+ unsigned int num_blks);
+ const u32 *rk = encrypt ? ctx->rkey_enc : ctx->rkey_dec;
+ unsigned char tmpbuf[16 * 8];
+ unsigned int tmp_used = 16;
+
+ if (0)
+ ;
+#ifdef USE_AESNI_AVX
+ else if (ctx->use_aesni_avx)
+ {
+ crypt_blk1_8 = sm4_aesni_avx_crypt_blk1_8;
+ }
+#endif
+ else
+ {
+ prefetch_sbox_table ();
+ crypt_blk1_8 = sm4_crypt_blocks;
+ }
+
+ while (nblocks)
+ {
+ size_t curr_blks = nblocks > 8 ? 8 : nblocks;
+ size_t i;
+
+ if (curr_blks * 16 > tmp_used)
+ tmp_used = curr_blks * 16;
+
+ for (i = 0; i < curr_blks; i++)
+ {
+ const unsigned char *l = ocb_get_l(c, ++blkn);
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ if (encrypt)
+ cipher_block_xor_1(c->u_ctr.ctr, &inbuf[i * 16], 16);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ cipher_block_xor_2dst (&tmpbuf[i * 16], c->u_iv.iv, l, 16);
+ cipher_block_xor (&outbuf[i * 16], &inbuf[i * 16],
+ c->u_iv.iv, 16);
+ }
+
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+ crypt_blk1_8 (rk, outbuf, outbuf, curr_blks);
+
+ for (i = 0; i < curr_blks; i++)
+ {
+ cipher_block_xor_1 (&outbuf[i * 16], &tmpbuf[i * 16], 16);
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ if (!encrypt)
+ cipher_block_xor_1(c->u_ctr.ctr, &outbuf[i * 16], 16);
+ }
+
+ outbuf += curr_blks * 16;
+ inbuf += curr_blks * 16;
+ nblocks -= curr_blks;
+ }
+
+ 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;
+
+#ifdef USE_AESNI_AVX2
+ if (ctx->use_aesni_avx2)
+ {
+ u64 Ls[16];
+ unsigned int n = 16 - (blkn % 16);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 16)
+ {
+ for (i = 0; i < 16; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(15 + n) % 16];
+
+ /* 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];
+ unsigned int n = 8 - (blkn % 8);
+ u64 *l;
+
+ if (nblocks >= 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(0 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(1 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(2 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(3 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(4 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(5 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(6 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(7 + n) % 8] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(7 + n) % 8];
+
+ /* 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
+
+ if (nblocks)
+ {
+ unsigned int (*crypt_blk1_8)(const u32 *rk, byte *out, const byte *in,
+ unsigned int num_blks);
+ unsigned char tmpbuf[16 * 8];
+ unsigned int tmp_used = 16;
+
+ if (0)
+ ;
+#ifdef USE_AESNI_AVX
+ else if (ctx->use_aesni_avx)
+ {
+ crypt_blk1_8 = sm4_aesni_avx_crypt_blk1_8;
+ }
+#endif
+ else
+ {
+ prefetch_sbox_table ();
+ crypt_blk1_8 = sm4_crypt_blocks;
+ }
+
+ while (nblocks)
+ {
+ size_t curr_blks = nblocks > 8 ? 8 : nblocks;
+ size_t i;
+
+ if (curr_blks * 16 > tmp_used)
+ tmp_used = curr_blks * 16;
+
+ for (i = 0; i < curr_blks; i++)
+ {
+ const unsigned char *l = ocb_get_l(c, ++blkn);
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ cipher_block_xor_2dst (&tmpbuf[i * 16],
+ c->u_mode.ocb.aad_offset, l, 16);
+ cipher_block_xor_1 (&tmpbuf[i * 16], &abuf[i * 16], 16);
+ }
+
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+ crypt_blk1_8 (ctx->rkey_enc, tmpbuf, tmpbuf, curr_blks);
+
+ for (i = 0; i < curr_blks; i++)
+ {
+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, &tmpbuf[i * 16], 16);
+ }
+
+ abuf += curr_blks * 16;
+ nblocks -= curr_blks;
+ }
+
+ wipememory(tmpbuf, tmp_used);
+ }
+
+ c->u_mode.ocb.aad_nblocks = blkn;
+
+ 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 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/comm/third_party/libgcrypt/cipher/stribog.c b/comm/third_party/libgcrypt/cipher/stribog.c
new file mode 100644
index 0000000000..f8776a3e8f
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/stribog.c
@@ -0,0 +1,1362 @@
+/* stribog.c - GOST R 34.11-2012 (Stribog) hash function
+ * Copyright (C) 2013 Dmitry Eremin-Solenikov
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+typedef struct
+{
+ gcry_md_block_ctx_t bctx;
+ union
+ {
+ u64 h[8];
+ unsigned char result[64];
+ };
+ u64 N[8];
+ u64 Sigma[8];
+} STRIBOG_CONTEXT;
+
+
+/* Pre-computed results of multiplication of bytes on A and reordered with
+ Pi[]. */
+static const u64 stribog_table[8][256] =
+{
+ /* 0 */
+ { U64_C(0xd01f715b5c7ef8e6), U64_C(0x16fa240980778325),
+ U64_C(0xa8a42e857ee049c8), U64_C(0x6ac1068fa186465b),
+ U64_C(0x6e417bd7a2e9320b), U64_C(0x665c8167a437daab),
+ U64_C(0x7666681aa89617f6), U64_C(0x4b959163700bdcf5),
+ U64_C(0xf14be6b78df36248), U64_C(0xc585bd689a625cff),
+ U64_C(0x9557d7fca67d82cb), U64_C(0x89f0b969af6dd366),
+ U64_C(0xb0833d48749f6c35), U64_C(0xa1998c23b1ecbc7c),
+ U64_C(0x8d70c431ac02a736), U64_C(0xd6dfbc2fd0a8b69e),
+ U64_C(0x37aeb3e551fa198b), U64_C(0x0b7d128a40b5cf9c),
+ U64_C(0x5a8f2008b5780cbc), U64_C(0xedec882284e333e5),
+ U64_C(0xd25fc177d3c7c2ce), U64_C(0x5e0f5d50b61778ec),
+ U64_C(0x1d873683c0c24cb9), U64_C(0xad040bcbb45d208c),
+ U64_C(0x2f89a0285b853c76), U64_C(0x5732fff6791b8d58),
+ U64_C(0x3e9311439ef6ec3f), U64_C(0xc9183a809fd3c00f),
+ U64_C(0x83adf3f5260a01ee), U64_C(0xa6791941f4e8ef10),
+ U64_C(0x103ae97d0ca1cd5d), U64_C(0x2ce948121dee1b4a),
+ U64_C(0x39738421dbf2bf53), U64_C(0x093da2a6cf0cf5b4),
+ U64_C(0xcd9847d89cbcb45f), U64_C(0xf9561c078b2d8ae8),
+ U64_C(0x9c6a755a6971777f), U64_C(0xbc1ebaa0712ef0c5),
+ U64_C(0x72e61542abf963a6), U64_C(0x78bb5fde229eb12e),
+ U64_C(0x14ba94250fceb90d), U64_C(0x844d6697630e5282),
+ U64_C(0x98ea08026a1e032f), U64_C(0xf06bbea144217f5c),
+ U64_C(0xdb6263d11ccb377a), U64_C(0x641c314b2b8ee083),
+ U64_C(0x320e96ab9b4770cf), U64_C(0x1ee7deb986a96b85),
+ U64_C(0xe96cf57a878c47b5), U64_C(0xfdd6615f8842feb8),
+ U64_C(0xc83862965601dd1b), U64_C(0x2ea9f83e92572162),
+ U64_C(0xf876441142ff97fc), U64_C(0xeb2c455608357d9d),
+ U64_C(0x5612a7e0b0c9904c), U64_C(0x6c01cbfb2d500823),
+ U64_C(0x4548a6a7fa037a2d), U64_C(0xabc4c6bf388b6ef4),
+ U64_C(0xbade77d4fdf8bebd), U64_C(0x799b07c8eb4cac3a),
+ U64_C(0x0c9d87e805b19cf0), U64_C(0xcb588aac106afa27),
+ U64_C(0xea0c1d40c1e76089), U64_C(0x2869354a1e816f1a),
+ U64_C(0xff96d17307fbc490), U64_C(0x9f0a9d602f1a5043),
+ U64_C(0x96373fc6e016a5f7), U64_C(0x5292dab8b3a6e41c),
+ U64_C(0x9b8ae0382c752413), U64_C(0x4f15ec3b7364a8a5),
+ U64_C(0x3fb349555724f12b), U64_C(0xc7c50d4415db66d7),
+ U64_C(0x92b7429ee379d1a7), U64_C(0xd37f99611a15dfda),
+ U64_C(0x231427c05e34a086), U64_C(0xa439a96d7b51d538),
+ U64_C(0xb403401077f01865), U64_C(0xdda2aea5901d7902),
+ U64_C(0x0a5d4a9c8967d288), U64_C(0xc265280adf660f93),
+ U64_C(0x8bb0094520d4e94e), U64_C(0x2a29856691385532),
+ U64_C(0x42a833c5bf072941), U64_C(0x73c64d54622b7eb2),
+ U64_C(0x07e095624504536c), U64_C(0x8a905153e906f45a),
+ U64_C(0x6f6123c16b3b2f1f), U64_C(0xc6e55552dc097bc3),
+ U64_C(0x4468feb133d16739), U64_C(0xe211e7f0c7398829),
+ U64_C(0xa2f96419f7879b40), U64_C(0x19074bdbc3ad38e9),
+ U64_C(0xf4ebc3f9474e0b0c), U64_C(0x43886bd376d53455),
+ U64_C(0xd8028beb5aa01046), U64_C(0x51f23282f5cdc320),
+ U64_C(0xe7b1c2be0d84e16d), U64_C(0x081dfab006dee8a0),
+ U64_C(0x3b33340d544b857b), U64_C(0x7f5bcabc679ae242),
+ U64_C(0x0edd37c48a08a6d8), U64_C(0x81ed43d9a9b33bc6),
+ U64_C(0xb1a3655ebd4d7121), U64_C(0x69a1eeb5e7ed6167),
+ U64_C(0xf6ab73d5c8f73124), U64_C(0x1a67a3e185c61fd5),
+ U64_C(0x2dc91004d43c065e), U64_C(0x0240b02c8fb93a28),
+ U64_C(0x90f7f2b26cc0eb8f), U64_C(0x3cd3a16f114fd617),
+ U64_C(0xaae49ea9f15973e0), U64_C(0x06c0cd748cd64e78),
+ U64_C(0xda423bc7d5192a6e), U64_C(0xc345701c16b41287),
+ U64_C(0x6d2193ede4821537), U64_C(0xfcf639494190e3ac),
+ U64_C(0x7c3b228621f1c57e), U64_C(0xfb16ac2b0494b0c0),
+ U64_C(0xbf7e529a3745d7f9), U64_C(0x6881b6a32e3f7c73),
+ U64_C(0xca78d2bad9b8e733), U64_C(0xbbfe2fc2342aa3a9),
+ U64_C(0x0dbddffecc6381e4), U64_C(0x70a6a56e2440598e),
+ U64_C(0xe4d12a844befc651), U64_C(0x8c509c2765d0ba22),
+ U64_C(0xee8c6018c28814d9), U64_C(0x17da7c1f49a59e31),
+ U64_C(0x609c4c1328e194d3), U64_C(0xb3e3d57232f44b09),
+ U64_C(0x91d7aaa4a512f69b), U64_C(0x0ffd6fd243dabbcc),
+ U64_C(0x50d26a943c1fde34), U64_C(0x6be15e9968545b4f),
+ U64_C(0x94778fea6faf9fdf), U64_C(0x2b09dd7058ea4826),
+ U64_C(0x677cd9716de5c7bf), U64_C(0x49d5214fffb2e6dd),
+ U64_C(0x0360e83a466b273c), U64_C(0x1fc786af4f7b7691),
+ U64_C(0xa0b9d435783ea168), U64_C(0xd49f0c035f118cb6),
+ U64_C(0x01205816c9d21d14), U64_C(0xac2453dd7d8f3d98),
+ U64_C(0x545217cc3f70aa64), U64_C(0x26b4028e9489c9c2),
+ U64_C(0xdec2469fd6765e3e), U64_C(0x04807d58036f7450),
+ U64_C(0xe5f17292823ddb45), U64_C(0xf30b569b024a5860),
+ U64_C(0x62dcfc3fa758aefb), U64_C(0xe84cad6c4e5e5aa1),
+ U64_C(0xccb81fce556ea94b), U64_C(0x53b282ae7a74f908),
+ U64_C(0x1b47fbf74c1402c1), U64_C(0x368eebf39828049f),
+ U64_C(0x7afbeff2ad278b06), U64_C(0xbe5e0a8cfe97caed),
+ U64_C(0xcfd8f7f413058e77), U64_C(0xf78b2bc301252c30),
+ U64_C(0x4d555c17fcdd928d), U64_C(0x5f2f05467fc565f8),
+ U64_C(0x24f4b2a21b30f3ea), U64_C(0x860dd6bbecb768aa),
+ U64_C(0x4c750401350f8f99), U64_C(0x0000000000000000),
+ U64_C(0xecccd0344d312ef1), U64_C(0xb5231806be220571),
+ U64_C(0xc105c030990d28af), U64_C(0x653c695de25cfd97),
+ U64_C(0x159acc33c61ca419), U64_C(0xb89ec7f872418495),
+ U64_C(0xa9847693b73254dc), U64_C(0x58cf90243ac13694),
+ U64_C(0x59efc832f3132b80), U64_C(0x5c4fed7c39ae42c4),
+ U64_C(0x828dabe3efd81cfa), U64_C(0xd13f294d95ace5f2),
+ U64_C(0x7d1b7a90e823d86a), U64_C(0xb643f03cf849224d),
+ U64_C(0x3df3f979d89dcb03), U64_C(0x7426d836272f2dde),
+ U64_C(0xdfe21e891fa4432a), U64_C(0x3a136c1b9d99986f),
+ U64_C(0xfa36f43dcd46add4), U64_C(0xc025982650df35bb),
+ U64_C(0x856d3e81aadc4f96), U64_C(0xc4a5e57e53b041eb),
+ U64_C(0x4708168b75ba4005), U64_C(0xaf44bbe73be41aa4),
+ U64_C(0x971767d029c4b8e3), U64_C(0xb9be9feebb939981),
+ U64_C(0x215497ecd18d9aae), U64_C(0x316e7e91dd2c57f3),
+ U64_C(0xcef8afe2dad79363), U64_C(0x3853dc371220a247),
+ U64_C(0x35ee03c9de4323a3), U64_C(0xe6919aa8c456fc79),
+ U64_C(0xe05157dc4880b201), U64_C(0x7bdbb7e464f59612),
+ U64_C(0x127a59518318f775), U64_C(0x332ecebd52956ddb),
+ U64_C(0x8f30741d23bb9d1e), U64_C(0xd922d3fd93720d52),
+ U64_C(0x7746300c61440ae2), U64_C(0x25d4eab4d2e2eefe),
+ U64_C(0x75068020eefd30ca), U64_C(0x135a01474acaea61),
+ U64_C(0x304e268714fe4ae7), U64_C(0xa519f17bb283c82c),
+ U64_C(0xdc82f6b359cf6416), U64_C(0x5baf781e7caa11a8),
+ U64_C(0xb2c38d64fb26561d), U64_C(0x34ce5bdf17913eb7),
+ U64_C(0x5d6fb56af07c5fd0), U64_C(0x182713cd0a7f25fd),
+ U64_C(0x9e2ac576e6c84d57), U64_C(0x9aaab82ee5a73907),
+ U64_C(0xa3d93c0f3e558654), U64_C(0x7e7b92aaae48ff56),
+ U64_C(0x872d8ead256575be), U64_C(0x41c8dbfff96c0e7d),
+ U64_C(0x99ca5014a3cc1e3b), U64_C(0x40e883e930be1369),
+ U64_C(0x1ca76e95091051ad), U64_C(0x4e35b42dbab6b5b1),
+ U64_C(0x05a0254ecabd6944), U64_C(0xe1710fca8152af15),
+ U64_C(0xf22b0e8dcb984574), U64_C(0xb763a82a319b3f59),
+ U64_C(0x63fca4296e8ab3ef), U64_C(0x9d4a2d4ca0a36a6b),
+ U64_C(0xe331bfe60eeb953d), U64_C(0xd5bf541596c391a2),
+ U64_C(0xf5cb9bef8e9c1618), U64_C(0x46284e9dbc685d11),
+ U64_C(0x2074cffa185f87ba), U64_C(0xbd3ee2b6b8fcedd1),
+ U64_C(0xae64e3f1f23607b0), U64_C(0xfeb68965ce29d984),
+ U64_C(0x55724fdaf6a2b770), U64_C(0x29496d5cd753720e),
+ U64_C(0xa75941573d3af204), U64_C(0x8e102c0bea69800a),
+ U64_C(0x111ab16bc573d049), U64_C(0xd7ffe439197aab8a),
+ U64_C(0xefac380e0b5a09cd), U64_C(0x48f579593660fbc9),
+ U64_C(0x22347fd697e6bd92), U64_C(0x61bc1405e13389c7),
+ U64_C(0x4ab5c975b9d9c1e1), U64_C(0x80cd1bcf606126d2),
+ U64_C(0x7186fd78ed92449a), U64_C(0x93971a882aabccb3),
+ U64_C(0x88d0e17f66bfce72), U64_C(0x27945a985d5bd4d6) },
+ /* 1 */
+ { U64_C(0xde553f8c05a811c8), U64_C(0x1906b59631b4f565),
+ U64_C(0x436e70d6b1964ff7), U64_C(0x36d343cb8b1e9d85),
+ U64_C(0x843dfacc858aab5a), U64_C(0xfdfc95c299bfc7f9),
+ U64_C(0x0f634bdea1d51fa2), U64_C(0x6d458b3b76efb3cd),
+ U64_C(0x85c3f77cf8593f80), U64_C(0x3c91315fbe737cb2),
+ U64_C(0x2148b03366ace398), U64_C(0x18f8b8264c6761bf),
+ U64_C(0xc830c1c495c9fb0f), U64_C(0x981a76102086a0aa),
+ U64_C(0xaa16012142f35760), U64_C(0x35cc54060c763cf6),
+ U64_C(0x42907d66cc45db2d), U64_C(0x8203d44b965af4bc),
+ U64_C(0x3d6f3cefc3a0e868), U64_C(0xbc73ff69d292bda7),
+ U64_C(0x8722ed0102e20a29), U64_C(0x8f8185e8cd34deb7),
+ U64_C(0x9b0561dda7ee01d9), U64_C(0x5335a0193227fad6),
+ U64_C(0xc9cecc74e81a6fd5), U64_C(0x54f5832e5c2431ea),
+ U64_C(0x99e47ba05d553470), U64_C(0xf7bee756acd226ce),
+ U64_C(0x384e05a5571816fd), U64_C(0xd1367452a47d0e6a),
+ U64_C(0xf29fde1c386ad85b), U64_C(0x320c77316275f7ca),
+ U64_C(0xd0c879e2d9ae9ab0), U64_C(0xdb7406c69110ef5d),
+ U64_C(0x45505e51a2461011), U64_C(0xfc029872e46c5323),
+ U64_C(0xfa3cb6f5f7bc0cc5), U64_C(0x031f17cd8768a173),
+ U64_C(0xbd8df2d9af41297d), U64_C(0x9d3b4f5ab43e5e3f),
+ U64_C(0x4071671b36feee84), U64_C(0x716207e7d3e3b83d),
+ U64_C(0x48d20ff2f9283a1a), U64_C(0x27769eb4757cbc7e),
+ U64_C(0x5c56ebc793f2e574), U64_C(0xa48b474f9ef5dc18),
+ U64_C(0x52cbada94ff46e0c), U64_C(0x60c7da982d8199c6),
+ U64_C(0x0e9d466edc068b78), U64_C(0x4eec2175eaf865fc),
+ U64_C(0x550b8e9e21f7a530), U64_C(0x6b7ba5bc653fec2b),
+ U64_C(0x5eb7f1ba6949d0dd), U64_C(0x57ea94e3db4c9099),
+ U64_C(0xf640eae6d101b214), U64_C(0xdd4a284182c0b0bb),
+ U64_C(0xff1d8fbf6304f250), U64_C(0xb8accb933bf9d7e8),
+ U64_C(0xe8867c478eb68c4d), U64_C(0x3f8e2692391bddc1),
+ U64_C(0xcb2fd60912a15a7c), U64_C(0xaec935dbab983d2f),
+ U64_C(0xf55ffd2b56691367), U64_C(0x80e2ce366ce1c115),
+ U64_C(0x179bf3f8edb27e1d), U64_C(0x01fe0db07dd394da),
+ U64_C(0xda8a0b76ecc37b87), U64_C(0x44ae53e1df9584cb),
+ U64_C(0xb310b4b77347a205), U64_C(0xdfab323c787b8512),
+ U64_C(0x3b511268d070b78e), U64_C(0x65e6e3d2b9396753),
+ U64_C(0x6864b271e2574d58), U64_C(0x259784c98fc789d7),
+ U64_C(0x02e11a7dfabb35a9), U64_C(0x8841a6dfa337158b),
+ U64_C(0x7ade78c39b5dcdd0), U64_C(0xb7cf804d9a2cc84a),
+ U64_C(0x20b6bd831b7f7742), U64_C(0x75bd331d3a88d272),
+ U64_C(0x418f6aab4b2d7a5e), U64_C(0xd9951cbb6babdaf4),
+ U64_C(0xb6318dfde7ff5c90), U64_C(0x1f389b112264aa83),
+ U64_C(0x492c024284fbaec0), U64_C(0xe33a0363c608f9a0),
+ U64_C(0x2688930408af28a4), U64_C(0xc7538a1a341ce4ad),
+ U64_C(0x5da8e677ee2171ae), U64_C(0x8c9e92254a5c7fc4),
+ U64_C(0x63d8cd55aae938b5), U64_C(0x29ebd8daa97a3706),
+ U64_C(0x959827b37be88aa1), U64_C(0x1484e4356adadf6e),
+ U64_C(0xa7945082199d7d6b), U64_C(0xbf6ce8a455fa1cd4),
+ U64_C(0x9cc542eac9edcae5), U64_C(0x79c16f0e1c356ca3),
+ U64_C(0x89bfab6fdee48151), U64_C(0xd4174d1830c5f0ff),
+ U64_C(0x9258048415eb419d), U64_C(0x6139d72850520d1c),
+ U64_C(0x6a85a80c18ec78f1), U64_C(0xcd11f88e0171059a),
+ U64_C(0xcceff53e7ca29140), U64_C(0xd229639f2315af19),
+ U64_C(0x90b91ef9ef507434), U64_C(0x5977d28d074a1be1),
+ U64_C(0x311360fce51d56b9), U64_C(0xc093a92d5a1f2f91),
+ U64_C(0x1a19a25bb6dc5416), U64_C(0xeb996b8a09de2d3e),
+ U64_C(0xfee3820f1ed7668a), U64_C(0xd7085ad5b7ad518c),
+ U64_C(0x7fff41890fe53345), U64_C(0xec5948bd67dde602),
+ U64_C(0x2fd5f65dbaaa68e0), U64_C(0xa5754affe32648c2),
+ U64_C(0xf8ddac880d07396c), U64_C(0x6fa491468c548664),
+ U64_C(0x0c7c5c1326bdbed1), U64_C(0x4a33158f03930fb3),
+ U64_C(0x699abfc19f84d982), U64_C(0xe4fa2054a80b329c),
+ U64_C(0x6707f9af438252fa), U64_C(0x08a368e9cfd6d49e),
+ U64_C(0x47b1442c58fd25b8), U64_C(0xbbb3dc5ebc91769b),
+ U64_C(0x1665fe489061eac7), U64_C(0x33f27a811fa66310),
+ U64_C(0x93a609346838d547), U64_C(0x30ed6d4c98cec263),
+ U64_C(0x1dd9816cd8df9f2a), U64_C(0x94662a03063b1e7b),
+ U64_C(0x83fdd9fbeb896066), U64_C(0x7b207573e68e590a),
+ U64_C(0x5f49fc0a149a4407), U64_C(0x343259b671a5a82c),
+ U64_C(0xfbc2bb458a6f981f), U64_C(0xc272b350a0a41a38),
+ U64_C(0x3aaf1fd8ada32354), U64_C(0x6cbb868b0b3c2717),
+ U64_C(0xa2b569c88d2583fe), U64_C(0xf180c9d1bf027928),
+ U64_C(0xaf37386bd64ba9f5), U64_C(0x12bacab2790a8088),
+ U64_C(0x4c0d3b0810435055), U64_C(0xb2eeb9070e9436df),
+ U64_C(0xc5b29067cea7d104), U64_C(0xdcb425f1ff132461),
+ U64_C(0x4f122cc5972bf126), U64_C(0xac282fa651230886),
+ U64_C(0xe7e537992f6393ef), U64_C(0xe61b3a2952b00735),
+ U64_C(0x709c0a57ae302ce7), U64_C(0xe02514ae416058d3),
+ U64_C(0xc44c9dd7b37445de), U64_C(0x5a68c5408022ba92),
+ U64_C(0x1c278cdca50c0bf0), U64_C(0x6e5a9cf6f18712be),
+ U64_C(0x86dce0b17f319ef3), U64_C(0x2d34ec2040115d49),
+ U64_C(0x4bcd183f7e409b69), U64_C(0x2815d56ad4a9a3dc),
+ U64_C(0x24698979f2141d0d), U64_C(0x0000000000000000),
+ U64_C(0x1ec696a15fb73e59), U64_C(0xd86b110b16784e2e),
+ U64_C(0x8e7f8858b0e74a6d), U64_C(0x063e2e8713d05fe6),
+ U64_C(0xe2c40ed3bbdb6d7a), U64_C(0xb1f1aeca89fc97ac),
+ U64_C(0xe1db191e3cb3cc09), U64_C(0x6418ee62c4eaf389),
+ U64_C(0xc6ad87aa49cf7077), U64_C(0xd6f65765ca7ec556),
+ U64_C(0x9afb6c6dda3d9503), U64_C(0x7ce05644888d9236),
+ U64_C(0x8d609f95378feb1e), U64_C(0x23a9aa4e9c17d631),
+ U64_C(0x6226c0e5d73aac6f), U64_C(0x56149953a69f0443),
+ U64_C(0xeeb852c09d66d3ab), U64_C(0x2b0ac2a753c102af),
+ U64_C(0x07c023376e03cb3c), U64_C(0x2ccae1903dc2c993),
+ U64_C(0xd3d76e2f5ec63bc3), U64_C(0x9e2458973356ff4c),
+ U64_C(0xa66a5d32644ee9b1), U64_C(0x0a427294356de137),
+ U64_C(0x783f62be61e6f879), U64_C(0x1344c70204d91452),
+ U64_C(0x5b96c8f0fdf12e48), U64_C(0xa90916ecc59bf613),
+ U64_C(0xbe92e5142829880e), U64_C(0x727d102a548b194e),
+ U64_C(0x1be7afebcb0fc0cc), U64_C(0x3e702b2244c8491b),
+ U64_C(0xd5e940a84d166425), U64_C(0x66f9f41f3e51c620),
+ U64_C(0xabe80c913f20c3ba), U64_C(0xf07ec461c2d1edf2),
+ U64_C(0xf361d3ac45b94c81), U64_C(0x0521394a94b8fe95),
+ U64_C(0xadd622162cf09c5c), U64_C(0xe97871f7f3651897),
+ U64_C(0xf4a1f09b2bba87bd), U64_C(0x095d6559b2054044),
+ U64_C(0x0bbc7f2448be75ed), U64_C(0x2af4cf172e129675),
+ U64_C(0x157ae98517094bb4), U64_C(0x9fda55274e856b96),
+ U64_C(0x914713499283e0ee), U64_C(0xb952c623462a4332),
+ U64_C(0x74433ead475b46a8), U64_C(0x8b5eb112245fb4f8),
+ U64_C(0xa34b6478f0f61724), U64_C(0x11a5dd7ffe6221fb),
+ U64_C(0xc16da49d27ccbb4b), U64_C(0x76a224d0bde07301),
+ U64_C(0x8aa0bca2598c2022), U64_C(0x4df336b86d90c48f),
+ U64_C(0xea67663a740db9e4), U64_C(0xef465f70e0b54771),
+ U64_C(0x39b008152acb8227), U64_C(0x7d1e5bf4f55e06ec),
+ U64_C(0x105bd0cf83b1b521), U64_C(0x775c2960c033e7db),
+ U64_C(0x7e014c397236a79f), U64_C(0x811cc386113255cf),
+ U64_C(0xeda7450d1a0e72d8), U64_C(0x5889df3d7a998f3b),
+ U64_C(0x2e2bfbedc779fc3a), U64_C(0xce0eef438619a4e9),
+ U64_C(0x372d4e7bf6cd095f), U64_C(0x04df34fae96b6a4f),
+ U64_C(0xf923a13870d4adb6), U64_C(0xa1aa7e050a4d228d),
+ U64_C(0xa8f71b5cb84862c9), U64_C(0xb52e9a306097fde3),
+ U64_C(0x0d8251a35b6e2a0b), U64_C(0x2257a7fee1c442eb),
+ U64_C(0x73831d9a29588d94), U64_C(0x51d4ba64c89ccf7f),
+ U64_C(0x502ab7d4b54f5ba5), U64_C(0x97793dce8153bf08),
+ U64_C(0xe5042de4d5d8a646), U64_C(0x9687307efc802bd2),
+ U64_C(0xa05473b5779eb657), U64_C(0xb4d097801d446939),
+ U64_C(0xcff0e2f3fbca3033), U64_C(0xc38cbee0dd778ee2),
+ U64_C(0x464f499c252eb162), U64_C(0xcad1dbb96f72cea6),
+ U64_C(0xba4dd1eec142e241), U64_C(0xb00fa37af42f0376) },
+ /* 2 */
+ { U64_C(0xcce4cd3aa968b245), U64_C(0x089d5484e80b7faf),
+ U64_C(0x638246c1b3548304), U64_C(0xd2fe0ec8c2355492),
+ U64_C(0xa7fbdf7ff2374eee), U64_C(0x4df1600c92337a16),
+ U64_C(0x84e503ea523b12fb), U64_C(0x0790bbfd53ab0c4a),
+ U64_C(0x198a780f38f6ea9d), U64_C(0x2ab30c8f55ec48cb),
+ U64_C(0xe0f7fed6b2c49db5), U64_C(0xb6ecf3f422cadbdc),
+ U64_C(0x409c9a541358df11), U64_C(0xd3ce8a56dfde3fe3),
+ U64_C(0xc3e9224312c8c1a0), U64_C(0x0d6dfa58816ba507),
+ U64_C(0xddf3e1b179952777), U64_C(0x04c02a42748bb1d9),
+ U64_C(0x94c2abff9f2decb8), U64_C(0x4f91752da8f8acf4),
+ U64_C(0x78682befb169bf7b), U64_C(0xe1c77a48af2ff6c4),
+ U64_C(0x0c5d7ec69c80ce76), U64_C(0x4cc1e4928fd81167),
+ U64_C(0xfeed3d24d9997b62), U64_C(0x518bb6dfc3a54a23),
+ U64_C(0x6dbf2d26151f9b90), U64_C(0xb5bc624b05ea664f),
+ U64_C(0xe86aaa525acfe21a), U64_C(0x4801ced0fb53a0be),
+ U64_C(0xc91463e6c00868ed), U64_C(0x1027a815cd16fe43),
+ U64_C(0xf67069a0319204cd), U64_C(0xb04ccc976c8abce7),
+ U64_C(0xc0b9b3fc35e87c33), U64_C(0xf380c77c58f2de65),
+ U64_C(0x50bb3241de4e2152), U64_C(0xdf93f490435ef195),
+ U64_C(0xf1e0d25d62390887), U64_C(0xaf668bfb1a3c3141),
+ U64_C(0xbc11b251f00a7291), U64_C(0x73a5eed47e427d47),
+ U64_C(0x25bee3f6ee4c3b2e), U64_C(0x43cc0beb34786282),
+ U64_C(0xc824e778dde3039c), U64_C(0xf97d86d98a327728),
+ U64_C(0xf2b043e24519b514), U64_C(0xe297ebf7880f4b57),
+ U64_C(0x3a94a49a98fab688), U64_C(0x868516cb68f0c419),
+ U64_C(0xeffa11af0964ee50), U64_C(0xa4ab4ec0d517f37d),
+ U64_C(0xa9c6b498547c567a), U64_C(0x8e18424f80fbbbb6),
+ U64_C(0x0bcdc53bcf2bc23c), U64_C(0x137739aaea3643d0),
+ U64_C(0x2c1333ec1bac2ff0), U64_C(0x8d48d3f0a7db0625),
+ U64_C(0x1e1ac3f26b5de6d7), U64_C(0xf520f81f16b2b95e),
+ U64_C(0x9f0f6ec450062e84), U64_C(0x0130849e1deb6b71),
+ U64_C(0xd45e31ab8c7533a9), U64_C(0x652279a2fd14e43f),
+ U64_C(0x3209f01e70f1c927), U64_C(0xbe71a770cac1a473),
+ U64_C(0x0e3d6be7a64b1894), U64_C(0x7ec8148cff29d840),
+ U64_C(0xcb7476c7fac3be0f), U64_C(0x72956a4a63a91636),
+ U64_C(0x37f95ec21991138f), U64_C(0x9e3fea5a4ded45f5),
+ U64_C(0x7b38ba50964902e8), U64_C(0x222e580bbde73764),
+ U64_C(0x61e253e0899f55e6), U64_C(0xfc8d2805e352ad80),
+ U64_C(0x35994be3235ac56d), U64_C(0x09add01af5e014de),
+ U64_C(0x5e8659a6780539c6), U64_C(0xb17c48097161d796),
+ U64_C(0x026015213acbd6e2), U64_C(0xd1ae9f77e515e901),
+ U64_C(0xb7dc776a3f21b0ad), U64_C(0xaba6a1b96eb78098),
+ U64_C(0x9bcf4486248d9f5d), U64_C(0x582666c536455efd),
+ U64_C(0xfdbdac9bfeb9c6f1), U64_C(0xc47999be4163cdea),
+ U64_C(0x765540081722a7ef), U64_C(0x3e548ed8ec710751),
+ U64_C(0x3d041f67cb51bac2), U64_C(0x7958af71ac82d40a),
+ U64_C(0x36c9da5c047a78fe), U64_C(0xed9a048e33af38b2),
+ U64_C(0x26ee7249c96c86bd), U64_C(0x900281bdeba65d61),
+ U64_C(0x11172c8bd0fd9532), U64_C(0xea0abf73600434f8),
+ U64_C(0x42fc8f75299309f3), U64_C(0x34a9cf7d3eb1ae1c),
+ U64_C(0x2b838811480723ba), U64_C(0x5ce64c8742ceef24),
+ U64_C(0x1adae9b01fd6570e), U64_C(0x3c349bf9d6bad1b3),
+ U64_C(0x82453c891c7b75c0), U64_C(0x97923a40b80d512b),
+ U64_C(0x4a61dbf1c198765c), U64_C(0xb48ce6d518010d3e),
+ U64_C(0xcfb45c858e480fd6), U64_C(0xd933cbf30d1e96ae),
+ U64_C(0xd70ea014ab558e3a), U64_C(0xc189376228031742),
+ U64_C(0x9262949cd16d8b83), U64_C(0xeb3a3bed7def5f89),
+ U64_C(0x49314a4ee6b8cbcf), U64_C(0xdcc3652f647e4c06),
+ U64_C(0xda635a4c2a3e2b3d), U64_C(0x470c21a940f3d35b),
+ U64_C(0x315961a157d174b4), U64_C(0x6672e81dda3459ac),
+ U64_C(0x5b76f77a1165e36e), U64_C(0x445cb01667d36ec8),
+ U64_C(0xc5491d205c88a69b), U64_C(0x456c34887a3805b9),
+ U64_C(0xffddb9bac4721013), U64_C(0x99af51a71e4649bf),
+ U64_C(0xa15be01cbc7729d5), U64_C(0x52db2760e485f7b0),
+ U64_C(0x8c78576eba306d54), U64_C(0xae560f6507d75a30),
+ U64_C(0x95f22f6182c687c9), U64_C(0x71c5fbf54489aba5),
+ U64_C(0xca44f259e728d57e), U64_C(0x88b87d2ccebbdc8d),
+ U64_C(0xbab18d32be4a15aa), U64_C(0x8be8ec93e99b611e),
+ U64_C(0x17b713e89ebdf209), U64_C(0xb31c5d284baa0174),
+ U64_C(0xeeca9531148f8521), U64_C(0xb8d198138481c348),
+ U64_C(0x8988f9b2d350b7fc), U64_C(0xb9e11c8d996aa839),
+ U64_C(0x5a4673e40c8e881f), U64_C(0x1687977683569978),
+ U64_C(0xbf4123eed72acf02), U64_C(0x4ea1f1b3b513c785),
+ U64_C(0xe767452be16f91ff), U64_C(0x7505d1b730021a7c),
+ U64_C(0xa59bca5ec8fc980c), U64_C(0xad069eda20f7e7a3),
+ U64_C(0x38f4b1bba231606a), U64_C(0x60d2d77e94743e97),
+ U64_C(0x9affc0183966f42c), U64_C(0x248e6768f3a7505f),
+ U64_C(0xcdd449a4b483d934), U64_C(0x87b59255751baf68),
+ U64_C(0x1bea6d2e023d3c7f), U64_C(0x6b1f12455b5ffcab),
+ U64_C(0x743555292de9710d), U64_C(0xd8034f6d10f5fddf),
+ U64_C(0xc6198c9f7ba81b08), U64_C(0xbb8109aca3a17edb),
+ U64_C(0xfa2d1766ad12cabb), U64_C(0xc729080166437079),
+ U64_C(0x9c5fff7b77269317), U64_C(0x0000000000000000),
+ U64_C(0x15d706c9a47624eb), U64_C(0x6fdf38072fd44d72),
+ U64_C(0x5fb6dd3865ee52b7), U64_C(0xa33bf53d86bcff37),
+ U64_C(0xe657c1b5fc84fa8e), U64_C(0xaa962527735cebe9),
+ U64_C(0x39c43525bfda0b1b), U64_C(0x204e4d2a872ce186),
+ U64_C(0x7a083ece8ba26999), U64_C(0x554b9c9db72efbfa),
+ U64_C(0xb22cd9b656416a05), U64_C(0x96a2bedea5e63a5a),
+ U64_C(0x802529a826b0a322), U64_C(0x8115ad363b5bc853),
+ U64_C(0x8375b81701901eb1), U64_C(0x3069e53f4a3a1fc5),
+ U64_C(0xbd2136cfede119e0), U64_C(0x18bafc91251d81ec),
+ U64_C(0x1d4a524d4c7d5b44), U64_C(0x05f0aedc6960daa8),
+ U64_C(0x29e39d3072ccf558), U64_C(0x70f57f6b5962c0d4),
+ U64_C(0x989fd53903ad22ce), U64_C(0xf84d024797d91c59),
+ U64_C(0x547b1803aac5908b), U64_C(0xf0d056c37fd263f6),
+ U64_C(0xd56eb535919e58d8), U64_C(0x1c7ad6d351963035),
+ U64_C(0x2e7326cd2167f912), U64_C(0xac361a443d1c8cd2),
+ U64_C(0x697f076461942a49), U64_C(0x4b515f6fdc731d2d),
+ U64_C(0x8ad8680df4700a6f), U64_C(0x41ac1eca0eb3b460),
+ U64_C(0x7d988533d80965d3), U64_C(0xa8f6300649973d0b),
+ U64_C(0x7765c4960ac9cc9e), U64_C(0x7ca801adc5e20ea2),
+ U64_C(0xdea3700e5eb59ae4), U64_C(0xa06b6482a19c42a4),
+ U64_C(0x6a2f96db46b497da), U64_C(0x27def6d7d487edcc),
+ U64_C(0x463ca5375d18b82a), U64_C(0xa6cb5be1efdc259f),
+ U64_C(0x53eba3fef96e9cc1), U64_C(0xce84d81b93a364a7),
+ U64_C(0xf4107c810b59d22f), U64_C(0x333974806d1aa256),
+ U64_C(0x0f0def79bba073e5), U64_C(0x231edc95a00c5c15),
+ U64_C(0xe437d494c64f2c6c), U64_C(0x91320523f64d3610),
+ U64_C(0x67426c83c7df32dd), U64_C(0x6eefbc99323f2603),
+ U64_C(0x9d6f7be56acdf866), U64_C(0x5916e25b2bae358c),
+ U64_C(0x7ff89012e2c2b331), U64_C(0x035091bf2720bd93),
+ U64_C(0x561b0d22900e4669), U64_C(0x28d319ae6f279e29),
+ U64_C(0x2f43a2533c8c9263), U64_C(0xd09e1be9f8fe8270),
+ U64_C(0xf740ed3e2c796fbc), U64_C(0xdb53ded237d5404c),
+ U64_C(0x62b2c25faebfe875), U64_C(0x0afd41a5d2c0a94d),
+ U64_C(0x6412fd3ce0ff8f4e), U64_C(0xe3a76f6995e42026),
+ U64_C(0x6c8fa9b808f4f0e1), U64_C(0xc2d9a6dd0f23aad1),
+ U64_C(0x8f28c6d19d10d0c7), U64_C(0x85d587744fd0798a),
+ U64_C(0xa20b71a39b579446), U64_C(0x684f83fa7c7f4138),
+ U64_C(0xe507500adba4471d), U64_C(0x3f640a46f19a6c20),
+ U64_C(0x1247bd34f7dd28a1), U64_C(0x2d23b77206474481),
+ U64_C(0x93521002cc86e0f2), U64_C(0x572b89bc8de52d18),
+ U64_C(0xfb1d93f8b0f9a1ca), U64_C(0xe95a2ecc4724896b),
+ U64_C(0x3ba420048511ddf9), U64_C(0xd63e248ab6bee54b),
+ U64_C(0x5dd6c8195f258455), U64_C(0x06a03f634e40673b),
+ U64_C(0x1f2a476c76b68da6), U64_C(0x217ec9b49ac78af7),
+ U64_C(0xecaa80102e4453c3), U64_C(0x14e78257b99d4f9a) },
+ /* 3 */
+ { U64_C(0x20329b2cc87bba05), U64_C(0x4f5eb6f86546a531),
+ U64_C(0xd4f44775f751b6b1), U64_C(0x8266a47b850dfa8b),
+ U64_C(0xbb986aa15a6ca985), U64_C(0xc979eb08f9ae0f99),
+ U64_C(0x2da6f447a2375ea1), U64_C(0x1e74275dcd7d8576),
+ U64_C(0xbc20180a800bc5f8), U64_C(0xb4a2f701b2dc65be),
+ U64_C(0xe726946f981b6d66), U64_C(0x48e6c453bf21c94c),
+ U64_C(0x42cad9930f0a4195), U64_C(0xefa47b64aacccd20),
+ U64_C(0x71180a8960409a42), U64_C(0x8bb3329bf6a44e0c),
+ U64_C(0xd34c35de2d36dacc), U64_C(0xa92f5b7cbc23dc96),
+ U64_C(0xb31a85aa68bb09c3), U64_C(0x13e04836a73161d2),
+ U64_C(0xb24dfc4129c51d02), U64_C(0x8ae44b70b7da5acd),
+ U64_C(0xe671ed84d96579a7), U64_C(0xa4bb3417d66f3832),
+ U64_C(0x4572ab38d56d2de8), U64_C(0xb1b47761ea47215c),
+ U64_C(0xe81c09cf70aba15d), U64_C(0xffbdb872ce7f90ac),
+ U64_C(0xa8782297fd5dc857), U64_C(0x0d946f6b6a4ce4a4),
+ U64_C(0xe4df1f4f5b995138), U64_C(0x9ebc71edca8c5762),
+ U64_C(0x0a2c1dc0b02b88d9), U64_C(0x3b503c115d9d7b91),
+ U64_C(0xc64376a8111ec3a2), U64_C(0xcec199a323c963e4),
+ U64_C(0xdc76a87ec58616f7), U64_C(0x09d596e073a9b487),
+ U64_C(0x14583a9d7d560daf), U64_C(0xf4c6dc593f2a0cb4),
+ U64_C(0xdd21d19584f80236), U64_C(0x4a4836983ddde1d3),
+ U64_C(0xe58866a41ae745f9), U64_C(0xf591a5b27e541875),
+ U64_C(0x891dc05074586693), U64_C(0x5b068c651810a89e),
+ U64_C(0xa30346bc0c08544f), U64_C(0x3dbf3751c684032d),
+ U64_C(0x2a1e86ec785032dc), U64_C(0xf73f5779fca830ea),
+ U64_C(0xb60c05ca30204d21), U64_C(0x0cc316802b32f065),
+ U64_C(0x8770241bdd96be69), U64_C(0xb861e18199ee95db),
+ U64_C(0xf805cad91418fcd1), U64_C(0x29e70dccbbd20e82),
+ U64_C(0xc7140f435060d763), U64_C(0x0f3a9da0e8b0cc3b),
+ U64_C(0xa2543f574d76408e), U64_C(0xbd7761e1c175d139),
+ U64_C(0x4b1f4f737ca3f512), U64_C(0x6dc2df1f2fc137ab),
+ U64_C(0xf1d05c3967b14856), U64_C(0xa742bf3715ed046c),
+ U64_C(0x654030141d1697ed), U64_C(0x07b872abda676c7d),
+ U64_C(0x3ce84eba87fa17ec), U64_C(0xc1fb0403cb79afdf),
+ U64_C(0x3e46bc7105063f73), U64_C(0x278ae987121cd678),
+ U64_C(0xa1adb4778ef47cd0), U64_C(0x26dd906c5362c2b9),
+ U64_C(0x05168060589b44e2), U64_C(0xfbfc41f9d79ac08f),
+ U64_C(0x0e6de44ba9ced8fa), U64_C(0x9feb08068bf243a3),
+ U64_C(0x7b341749d06b129b), U64_C(0x229c69e74a87929a),
+ U64_C(0xe09ee6c4427c011b), U64_C(0x5692e30e725c4c3a),
+ U64_C(0xda99a33e5e9f6e4b), U64_C(0x353dd85af453a36b),
+ U64_C(0x25241b4c90e0fee7), U64_C(0x5de987258309d022),
+ U64_C(0xe230140fc0802984), U64_C(0x93281e86a0c0b3c6),
+ U64_C(0xf229d719a4337408), U64_C(0x6f6c2dd4ad3d1f34),
+ U64_C(0x8ea5b2fbae3f0aee), U64_C(0x8331dd90c473ee4a),
+ U64_C(0x346aa1b1b52db7aa), U64_C(0xdf8f235e06042aa9),
+ U64_C(0xcc6f6b68a1354b7b), U64_C(0x6c95a6f46ebf236a),
+ U64_C(0x52d31a856bb91c19), U64_C(0x1a35ded6d498d555),
+ U64_C(0xf37eaef2e54d60c9), U64_C(0x72e181a9a3c2a61c),
+ U64_C(0x98537aad51952fde), U64_C(0x16f6c856ffaa2530),
+ U64_C(0xd960281e9d1d5215), U64_C(0x3a0745fa1ce36f50),
+ U64_C(0x0b7b642bf1559c18), U64_C(0x59a87eae9aec8001),
+ U64_C(0x5e100c05408bec7c), U64_C(0x0441f98b19e55023),
+ U64_C(0xd70dcc5534d38aef), U64_C(0x927f676de1bea707),
+ U64_C(0x9769e70db925e3e5), U64_C(0x7a636ea29115065a),
+ U64_C(0x468b201816ef11b6), U64_C(0xab81a9b73edff409),
+ U64_C(0xc0ac7de88a07bb1e), U64_C(0x1f235eb68c0391b7),
+ U64_C(0x6056b074458dd30f), U64_C(0xbe8eeac102f7ed67),
+ U64_C(0xcd381283e04b5fba), U64_C(0x5cbefecec277c4e3),
+ U64_C(0xd21b4c356c48ce0d), U64_C(0x1019c31664b35d8c),
+ U64_C(0x247362a7d19eea26), U64_C(0xebe582efb3299d03),
+ U64_C(0x02aef2cb82fc289f), U64_C(0x86275df09ce8aaa8),
+ U64_C(0x28b07427faac1a43), U64_C(0x38a9b7319e1f47cf),
+ U64_C(0xc82e92e3b8d01b58), U64_C(0x06ef0b409b1978bc),
+ U64_C(0x62f842bfc771fb90), U64_C(0x9904034610eb3b1f),
+ U64_C(0xded85ab5477a3e68), U64_C(0x90d195a663428f98),
+ U64_C(0x5384636e2ac708d8), U64_C(0xcbd719c37b522706),
+ U64_C(0xae9729d76644b0eb), U64_C(0x7c8c65e20a0c7ee6),
+ U64_C(0x80c856b007f1d214), U64_C(0x8c0b40302cc32271),
+ U64_C(0xdbcedad51fe17a8a), U64_C(0x740e8ae938dbdea0),
+ U64_C(0xa615c6dc549310ad), U64_C(0x19cc55f6171ae90b),
+ U64_C(0x49b1bdb8fe5fdd8d), U64_C(0xed0a89af2830e5bf),
+ U64_C(0x6a7aadb4f5a65bd6), U64_C(0x7e22972988f05679),
+ U64_C(0xf952b3325566e810), U64_C(0x39fecedadf61530e),
+ U64_C(0x6101c99f04f3c7ce), U64_C(0x2e5f7f6761b562ff),
+ U64_C(0xf08725d226cf5c97), U64_C(0x63af3b54860fef51),
+ U64_C(0x8ff2cb10ef411e2f), U64_C(0x884ab9bb35267252),
+ U64_C(0x4df04433e7ba8dae), U64_C(0x9afd8866d3690741),
+ U64_C(0x66b9bb34de94abb3), U64_C(0x9baaf18d92171380),
+ U64_C(0x543c11c5f0a064a5), U64_C(0x17a1b1bdbed431f1),
+ U64_C(0xb5f58eeaf3a2717f), U64_C(0xc355f6c849858740),
+ U64_C(0xec5df044694ef17e), U64_C(0xd83751f5dc6346d4),
+ U64_C(0xfc4433520dfdacf2), U64_C(0x0000000000000000),
+ U64_C(0x5a51f58e596ebc5f), U64_C(0x3285aaf12e34cf16),
+ U64_C(0x8d5c39db6dbd36b0), U64_C(0x12b731dde64f7513),
+ U64_C(0x94906c2d7aa7dfbb), U64_C(0x302b583aacc8e789),
+ U64_C(0x9d45facd090e6b3c), U64_C(0x2165e2c78905aec4),
+ U64_C(0x68d45f7f775a7349), U64_C(0x189b2c1d5664fdca),
+ U64_C(0xe1c99f2f030215da), U64_C(0x6983269436246788),
+ U64_C(0x8489af3b1e148237), U64_C(0xe94b702431d5b59c),
+ U64_C(0x33d2d31a6f4adbd7), U64_C(0xbfd9932a4389f9a6),
+ U64_C(0xb0e30e8aab39359d), U64_C(0xd1e2c715afcaf253),
+ U64_C(0x150f43763c28196e), U64_C(0xc4ed846393e2eb3d),
+ U64_C(0x03f98b20c3823c5e), U64_C(0xfd134ab94c83b833),
+ U64_C(0x556b682eb1de7064), U64_C(0x36c4537a37d19f35),
+ U64_C(0x7559f30279a5ca61), U64_C(0x799ae58252973a04),
+ U64_C(0x9c12832648707ffd), U64_C(0x78cd9c6913e92ec5),
+ U64_C(0x1d8dac7d0effb928), U64_C(0x439da0784e745554),
+ U64_C(0x413352b3cc887dcb), U64_C(0xbacf134a1b12bd44),
+ U64_C(0x114ebafd25cd494d), U64_C(0x2f08068c20cb763e),
+ U64_C(0x76a07822ba27f63f), U64_C(0xeab2fb04f25789c2),
+ U64_C(0xe3676de481fe3d45), U64_C(0x1b62a73d95e6c194),
+ U64_C(0x641749ff5c68832c), U64_C(0xa5ec4dfc97112cf3),
+ U64_C(0xf6682e92bdd6242b), U64_C(0x3f11c59a44782bb2),
+ U64_C(0x317c21d1edb6f348), U64_C(0xd65ab5be75ad9e2e),
+ U64_C(0x6b2dd45fb4d84f17), U64_C(0xfaab381296e4d44e),
+ U64_C(0xd0b5befeeeb4e692), U64_C(0x0882ef0b32d7a046),
+ U64_C(0x512a91a5a83b2047), U64_C(0x963e9ee6f85bf724),
+ U64_C(0x4e09cf132438b1f0), U64_C(0x77f701c9fb59e2fe),
+ U64_C(0x7ddb1c094b726a27), U64_C(0x5f4775ee01f5f8bd),
+ U64_C(0x9186ec4d223c9b59), U64_C(0xfeeac1998f01846d),
+ U64_C(0xac39db1ce4b89874), U64_C(0xb75b7c21715e59e0),
+ U64_C(0xafc0503c273aa42a), U64_C(0x6e3b543fec430bf5),
+ U64_C(0x704f7362213e8e83), U64_C(0x58ff0745db9294c0),
+ U64_C(0x67eec2df9feabf72), U64_C(0xa0facd9ccf8a6811),
+ U64_C(0xb936986ad890811a), U64_C(0x95c715c63bd9cb7a),
+ U64_C(0xca8060283a2c33c7), U64_C(0x507de84ee9453486),
+ U64_C(0x85ded6d05f6a96f6), U64_C(0x1cdad5964f81ade9),
+ U64_C(0xd5a33e9eb62fa270), U64_C(0x40642b588df6690a),
+ U64_C(0x7f75eec2c98e42b8), U64_C(0x2cf18dace3494a60),
+ U64_C(0x23cb100c0bf9865b), U64_C(0xeef3028febb2d9e1),
+ U64_C(0x4425d2d394133929), U64_C(0xaad6d05c7fa1e0c8),
+ U64_C(0xad6ea2f7a5c68cb5), U64_C(0xc2028f2308fb9381),
+ U64_C(0x819f2f5b468fc6d5), U64_C(0xc5bafd88d29cfffc),
+ U64_C(0x47dc59f357910577), U64_C(0x2b49ff07392e261d),
+ U64_C(0x57c59ae5332258fb), U64_C(0x73b6f842e2bcb2dd),
+ U64_C(0xcf96e04862b77725), U64_C(0x4ca73dd8a6c4996f),
+ U64_C(0x015779eb417e14c1), U64_C(0x37932a9176af8bf4) },
+ /* 4 */
+ { U64_C(0x190a2c9b249df23e), U64_C(0x2f62f8b62263e1e9),
+ U64_C(0x7a7f754740993655), U64_C(0x330b7ba4d5564d9f),
+ U64_C(0x4c17a16a46672582), U64_C(0xb22f08eb7d05f5b8),
+ U64_C(0x535f47f40bc148cc), U64_C(0x3aec5d27d4883037),
+ U64_C(0x10ed0a1825438f96), U64_C(0x516101f72c233d17),
+ U64_C(0x13cc6f949fd04eae), U64_C(0x739853c441474bfd),
+ U64_C(0x653793d90d3f5b1b), U64_C(0x5240647b96b0fc2f),
+ U64_C(0x0c84890ad27623e0), U64_C(0xd7189b32703aaea3),
+ U64_C(0x2685de3523bd9c41), U64_C(0x99317c5b11bffefa),
+ U64_C(0x0d9baa854f079703), U64_C(0x70b93648fbd48ac5),
+ U64_C(0xa80441fce30bc6be), U64_C(0x7287704bdc36ff1e),
+ U64_C(0xb65384ed33dc1f13), U64_C(0xd36417343ee34408),
+ U64_C(0x39cd38ab6e1bf10f), U64_C(0x5ab861770a1f3564),
+ U64_C(0x0ebacf09f594563b), U64_C(0xd04572b884708530),
+ U64_C(0x3cae9722bdb3af47), U64_C(0x4a556b6f2f5cbaf2),
+ U64_C(0xe1704f1f76c4bd74), U64_C(0x5ec4ed7144c6dfcf),
+ U64_C(0x16afc01d4c7810e6), U64_C(0x283f113cd629ca7a),
+ U64_C(0xaf59a8761741ed2d), U64_C(0xeed5a3991e215fac),
+ U64_C(0x3bf37ea849f984d4), U64_C(0xe413e096a56ce33c),
+ U64_C(0x2c439d3a98f020d1), U64_C(0x637559dc6404c46b),
+ U64_C(0x9e6c95d1e5f5d569), U64_C(0x24bb9836045fe99a),
+ U64_C(0x44efa466dac8ecc9), U64_C(0xc6eab2a5c80895d6),
+ U64_C(0x803b50c035220cc4), U64_C(0x0321658cba93c138),
+ U64_C(0x8f9ebc465dc7ee1c), U64_C(0xd15a5137190131d3),
+ U64_C(0x0fa5ec8668e5e2d8), U64_C(0x91c979578d1037b1),
+ U64_C(0x0642ca05693b9f70), U64_C(0xefca80168350eb4f),
+ U64_C(0x38d21b24f36a45ec), U64_C(0xbeab81e1af73d658),
+ U64_C(0x8cbfd9cae7542f24), U64_C(0xfd19cc0d81f11102),
+ U64_C(0x0ac6430fbb4dbc90), U64_C(0x1d76a09d6a441895),
+ U64_C(0x2a01573ff1cbbfa1), U64_C(0xb572e161894fde2b),
+ U64_C(0x8124734fa853b827), U64_C(0x614b1fdf43e6b1b0),
+ U64_C(0x68ac395c4238cc18), U64_C(0x21d837bfd7f7b7d2),
+ U64_C(0x20c714304a860331), U64_C(0x5cfaab726324aa14),
+ U64_C(0x74c5ba4eb50d606e), U64_C(0xf3a3030474654739),
+ U64_C(0x23e671bcf015c209), U64_C(0x45f087e947b9582a),
+ U64_C(0xd8bd77b418df4c7b), U64_C(0xe06f6c90ebb50997),
+ U64_C(0x0bd96080263c0873), U64_C(0x7e03f9410e40dcfe),
+ U64_C(0xb8e94be4c6484928), U64_C(0xfb5b0608e8ca8e72),
+ U64_C(0x1a2b49179e0e3306), U64_C(0x4e29e76961855059),
+ U64_C(0x4f36c4e6fcf4e4ba), U64_C(0x49740ee395cf7bca),
+ U64_C(0xc2963ea386d17f7d), U64_C(0x90d65ad810618352),
+ U64_C(0x12d34c1b02a1fa4d), U64_C(0xfa44258775bb3a91),
+ U64_C(0x18150f14b9ec46dd), U64_C(0x1491861e6b9a653d),
+ U64_C(0x9a1019d7ab2c3fc2), U64_C(0x3668d42d06fe13d7),
+ U64_C(0xdcc1fbb25606a6d0), U64_C(0x969490dd795a1c22),
+ U64_C(0x3549b1a1bc6dd2ef), U64_C(0xc94f5e23a0ed770e),
+ U64_C(0xb9f6686b5b39fdcb), U64_C(0xc4d4f4a6efeae00d),
+ U64_C(0xe732851a1fff2204), U64_C(0x94aad6de5eb869f9),
+ U64_C(0x3f8ff2ae07206e7f), U64_C(0xfe38a9813b62d03a),
+ U64_C(0xa7a1ad7a8bee2466), U64_C(0x7b6056c8dde882b6),
+ U64_C(0x302a1e286fc58ca7), U64_C(0x8da0fa457a259bc7),
+ U64_C(0xb3302b64e074415b), U64_C(0x5402ae7eff8b635f),
+ U64_C(0x08f8050c9cafc94b), U64_C(0xae468bf98a3059ce),
+ U64_C(0x88c355cca98dc58f), U64_C(0xb10e6d67c7963480),
+ U64_C(0xbad70de7e1aa3cf3), U64_C(0xbfb4a26e320262bb),
+ U64_C(0xcb711820870f02d5), U64_C(0xce12b7a954a75c9d),
+ U64_C(0x563ce87dd8691684), U64_C(0x9f73b65e7884618a),
+ U64_C(0x2b1e74b06cba0b42), U64_C(0x47cec1ea605b2df1),
+ U64_C(0x1c698312f735ac76), U64_C(0x5fdbcefed9b76b2c),
+ U64_C(0x831a354c8fb1cdfc), U64_C(0x820516c312c0791f),
+ U64_C(0xb74ca762aeadabf0), U64_C(0xfc06ef821c80a5e1),
+ U64_C(0x5723cbf24518a267), U64_C(0x9d4df05d5f661451),
+ U64_C(0x588627742dfd40bf), U64_C(0xda8331b73f3d39a0),
+ U64_C(0x17b0e392d109a405), U64_C(0xf965400bcf28fba9),
+ U64_C(0x7c3dbf4229a2a925), U64_C(0x023e460327e275db),
+ U64_C(0x6cd0b55a0ce126b3), U64_C(0xe62da695828e96e7),
+ U64_C(0x42ad6e63b3f373b9), U64_C(0xe50cc319381d57df),
+ U64_C(0xc5cbd729729b54ee), U64_C(0x46d1e265fd2a9912),
+ U64_C(0x6428b056904eeff8), U64_C(0x8be23040131e04b7),
+ U64_C(0x6709d5da2add2ec0), U64_C(0x075de98af44a2b93),
+ U64_C(0x8447dcc67bfbe66f), U64_C(0x6616f655b7ac9a23),
+ U64_C(0xd607b8bded4b1a40), U64_C(0x0563af89d3a85e48),
+ U64_C(0x3db1b4ad20c21ba4), U64_C(0x11f22997b8323b75),
+ U64_C(0x292032b34b587e99), U64_C(0x7f1cdace9331681d),
+ U64_C(0x8e819fc9c0b65aff), U64_C(0xa1e3677fe2d5bb16),
+ U64_C(0xcd33d225ee349da5), U64_C(0xd9a2543b85aef898),
+ U64_C(0x795e10cbfa0af76d), U64_C(0x25a4bbb9992e5d79),
+ U64_C(0x78413344677b438e), U64_C(0xf0826688cef68601),
+ U64_C(0xd27b34bba392f0eb), U64_C(0x551d8df162fad7bc),
+ U64_C(0x1e57c511d0d7d9ad), U64_C(0xdeffbdb171e4d30b),
+ U64_C(0xf4feea8e802f6caa), U64_C(0xa480c8f6317de55e),
+ U64_C(0xa0fc44f07fa40ff5), U64_C(0x95b5f551c3c9dd1a),
+ U64_C(0x22f952336d6476ea), U64_C(0x0000000000000000),
+ U64_C(0xa6be8ef5169f9085), U64_C(0xcc2cf1aa73452946),
+ U64_C(0x2e7ddb39bf12550a), U64_C(0xd526dd3157d8db78),
+ U64_C(0x486b2d6c08becf29), U64_C(0x9b0f3a58365d8b21),
+ U64_C(0xac78cdfaadd22c15), U64_C(0xbc95c7e28891a383),
+ U64_C(0x6a927f5f65dab9c3), U64_C(0xc3891d2c1ba0cb9e),
+ U64_C(0xeaa92f9f50f8b507), U64_C(0xcf0d9426c9d6e87e),
+ U64_C(0xca6e3baf1a7eb636), U64_C(0xab25247059980786),
+ U64_C(0x69b31ad3df4978fb), U64_C(0xe2512a93cc577c4c),
+ U64_C(0xff278a0ea61364d9), U64_C(0x71a615c766a53e26),
+ U64_C(0x89dc764334fc716c), U64_C(0xf87a638452594f4a),
+ U64_C(0xf2bc208be914f3da), U64_C(0x8766b94ac1682757),
+ U64_C(0xbbc82e687cdb8810), U64_C(0x626a7a53f9757088),
+ U64_C(0xa2c202f358467a2e), U64_C(0x4d0882e5db169161),
+ U64_C(0x09e7268301de7da8), U64_C(0xe897699c771ac0dc),
+ U64_C(0xc8507dac3d9cc3ed), U64_C(0xc0a878a0a1330aa6),
+ U64_C(0x978bb352e42ba8c1), U64_C(0xe9884a13ea6b743f),
+ U64_C(0x279afdbabecc28a2), U64_C(0x047c8c064ed9eaab),
+ U64_C(0x507e2278b15289f4), U64_C(0x599904fbb08cf45c),
+ U64_C(0xbd8ae46d15e01760), U64_C(0x31353da7f2b43844),
+ U64_C(0x8558ff49e68a528c), U64_C(0x76fbfc4d92ef15b5),
+ U64_C(0x3456922e211c660c), U64_C(0x86799ac55c1993b4),
+ U64_C(0x3e90d1219a51da9c), U64_C(0x2d5cbeb505819432),
+ U64_C(0x982e5fd48cce4a19), U64_C(0xdb9c1238a24c8d43),
+ U64_C(0xd439febecaa96f9b), U64_C(0x418c0bef0960b281),
+ U64_C(0x158ea591f6ebd1de), U64_C(0x1f48e69e4da66d4e),
+ U64_C(0x8afd13cf8e6fb054), U64_C(0xf5e1c9011d5ed849),
+ U64_C(0xe34e091c5126c8af), U64_C(0xad67ee7530a398f6),
+ U64_C(0x43b24dec2e82c75a), U64_C(0x75da99c1287cd48d),
+ U64_C(0x92e81cdb3783f689), U64_C(0xa3dd217cc537cecd),
+ U64_C(0x60543c50de970553), U64_C(0x93f73f54aaf2426a),
+ U64_C(0xa91b62737e7a725d), U64_C(0xf19d4507538732e2),
+ U64_C(0x77e4dfc20f9ea156), U64_C(0x7d229ccdb4d31dc6),
+ U64_C(0x1b346a98037f87e5), U64_C(0xedf4c615a4b29e94),
+ U64_C(0x4093286094110662), U64_C(0xb0114ee85ae78063),
+ U64_C(0x6ff1d0d6b672e78b), U64_C(0x6dcf96d591909250),
+ U64_C(0xdfe09e3eec9567e8), U64_C(0x3214582b4827f97c),
+ U64_C(0xb46dc2ee143e6ac8), U64_C(0xf6c0ac8da7cd1971),
+ U64_C(0xebb60c10cd8901e4), U64_C(0xf7df8f023abcad92),
+ U64_C(0x9c52d3d2c217a0b2), U64_C(0x6b8d5cd0f8ab0d20),
+ U64_C(0x3777f7a29b8fa734), U64_C(0x011f238f9d71b4e3),
+ U64_C(0xc1b75b2f3c42be45), U64_C(0x5de588fdfe551ef7),
+ U64_C(0x6eeef3592b035368), U64_C(0xaa3a07ffc4e9b365),
+ U64_C(0xecebe59a39c32a77), U64_C(0x5ba742f8976e8187),
+ U64_C(0x4b4a48e0b22d0e11), U64_C(0xddded83dcb771233),
+ U64_C(0xa59feb79ac0c51bd), U64_C(0xc7f5912a55792135) },
+ /* 5 */
+ { U64_C(0x6d6ae04668a9b08a), U64_C(0x3ab3f04b0be8c743),
+ U64_C(0xe51e166b54b3c908), U64_C(0xbe90a9eb35c2f139),
+ U64_C(0xb2c7066637f2bec1), U64_C(0xaa6945613392202c),
+ U64_C(0x9a28c36f3b5201eb), U64_C(0xddce5a93ab536994),
+ U64_C(0x0e34133ef6382827), U64_C(0x52a02ba1ec55048b),
+ U64_C(0xa2f88f97c4b2a177), U64_C(0x8640e513ca2251a5),
+ U64_C(0xcdf1d36258137622), U64_C(0xfe6cb708dedf8ddb),
+ U64_C(0x8a174a9ec8121e5d), U64_C(0x679896036b81560e),
+ U64_C(0x59ed033395795fee), U64_C(0x1dd778ab8b74edaf),
+ U64_C(0xee533ef92d9f926d), U64_C(0x2a8c79baf8a8d8f5),
+ U64_C(0x6bcf398e69b119f6), U64_C(0xe20491742fafdd95),
+ U64_C(0x276488e0809c2aec), U64_C(0xea955b82d88f5cce),
+ U64_C(0x7102c63a99d9e0c4), U64_C(0xf9763017a5c39946),
+ U64_C(0x429fa2501f151b3d), U64_C(0x4659c72bea05d59e),
+ U64_C(0x984b7fdccf5a6634), U64_C(0xf742232953fbb161),
+ U64_C(0x3041860e08c021c7), U64_C(0x747bfd9616cd9386),
+ U64_C(0x4bb1367192312787), U64_C(0x1b72a1638a6c44d3),
+ U64_C(0x4a0e68a6e8359a66), U64_C(0x169a5039f258b6ca),
+ U64_C(0xb98a2ef44edee5a4), U64_C(0xd9083fe85e43a737),
+ U64_C(0x967f6ce239624e13), U64_C(0x8874f62d3c1a7982),
+ U64_C(0x3c1629830af06e3f), U64_C(0x9165ebfd427e5a8e),
+ U64_C(0xb5dd81794ceeaa5c), U64_C(0x0de8f15a7834f219),
+ U64_C(0x70bd98ede3dd5d25), U64_C(0xaccc9ca9328a8950),
+ U64_C(0x56664eda1945ca28), U64_C(0x221db34c0f8859ae),
+ U64_C(0x26dbd637fa98970d), U64_C(0x1acdffb4f068f932),
+ U64_C(0x4585254f64090fa0), U64_C(0x72de245e17d53afa),
+ U64_C(0x1546b25d7c546cf4), U64_C(0x207e0ffffb803e71),
+ U64_C(0xfaaad2732bcf4378), U64_C(0xb462dfae36ea17bd),
+ U64_C(0xcf926fd1ac1b11fd), U64_C(0xe0672dc7dba7ba4a),
+ U64_C(0xd3fa49ad5d6b41b3), U64_C(0x8ba81449b216a3bc),
+ U64_C(0x14f9ec8a0650d115), U64_C(0x40fc1ee3eb1d7ce2),
+ U64_C(0x23a2ed9b758ce44f), U64_C(0x782c521b14fddc7e),
+ U64_C(0x1c68267cf170504e), U64_C(0xbcf31558c1ca96e6),
+ U64_C(0xa781b43b4ba6d235), U64_C(0xf6fd7dfe29ff0c80),
+ U64_C(0xb0a4bad5c3fad91e), U64_C(0xd199f51ea963266c),
+ U64_C(0x414340349119c103), U64_C(0x5405f269ed4dadf7),
+ U64_C(0xabd61bb649969dcd), U64_C(0x6813dbeae7bdc3c8),
+ U64_C(0x65fb2ab09f8931d1), U64_C(0xf1e7fae152e3181d),
+ U64_C(0xc1a67cef5a2339da), U64_C(0x7a4feea8e0f5bba1),
+ U64_C(0x1e0b9acf05783791), U64_C(0x5b8ebf8061713831),
+ U64_C(0x80e53cdbcb3af8d9), U64_C(0x7e898bd315e57502),
+ U64_C(0xc6bcfbf0213f2d47), U64_C(0x95a38e86b76e942d),
+ U64_C(0x092e94218d243cba), U64_C(0x8339debf453622e7),
+ U64_C(0xb11be402b9fe64ff), U64_C(0x57d9100d634177c9),
+ U64_C(0xcc4e8db52217cbc3), U64_C(0x3b0cae9c71ec7aa2),
+ U64_C(0xfb158ca451cbfe99), U64_C(0x2b33276d82ac6514),
+ U64_C(0x01bf5ed77a04bde1), U64_C(0xc5601994af33f779),
+ U64_C(0x75c4a3416cc92e67), U64_C(0xf3844652a6eb7fc2),
+ U64_C(0x3487e375fdd0ef64), U64_C(0x18ae430704609eed),
+ U64_C(0x4d14efb993298efb), U64_C(0x815a620cb13e4538),
+ U64_C(0x125c354207487869), U64_C(0x9eeea614ce42cf48),
+ U64_C(0xce2d3106d61fac1c), U64_C(0xbbe99247bad6827b),
+ U64_C(0x071a871f7b1c149d), U64_C(0x2e4a1cc10db81656),
+ U64_C(0x77a71ff298c149b8), U64_C(0x06a5d9c80118a97c),
+ U64_C(0xad73c27e488e34b1), U64_C(0x443a7b981e0db241),
+ U64_C(0xe3bbcfa355ab6074), U64_C(0x0af276450328e684),
+ U64_C(0x73617a896dd1871b), U64_C(0x58525de4ef7de20f),
+ U64_C(0xb7be3dcab8e6cd83), U64_C(0x19111dd07e64230c),
+ U64_C(0x842359a03e2a367a), U64_C(0x103f89f1f3401fb6),
+ U64_C(0xdc710444d157d475), U64_C(0xb835702334da5845),
+ U64_C(0x4320fc876511a6dc), U64_C(0xd026abc9d3679b8d),
+ U64_C(0x17250eee885c0b2b), U64_C(0x90dab52a387ae76f),
+ U64_C(0x31fed8d972c49c26), U64_C(0x89cba8fa461ec463),
+ U64_C(0x2ff5421677bcabb7), U64_C(0x396f122f85e41d7d),
+ U64_C(0xa09b332430bac6a8), U64_C(0xc888e8ced7070560),
+ U64_C(0xaeaf201ac682ee8f), U64_C(0x1180d7268944a257),
+ U64_C(0xf058a43628e7a5fc), U64_C(0xbd4c4b8fbbce2b07),
+ U64_C(0xa1246df34abe7b49), U64_C(0x7d5569b79be9af3c),
+ U64_C(0xa9b5a705bd9efa12), U64_C(0xdb6b835baa4bc0e8),
+ U64_C(0x05793bac8f147342), U64_C(0x21c1512881848390),
+ U64_C(0xfdb0556c50d357e5), U64_C(0x613d4fcb6a99ff72),
+ U64_C(0x03dce2648e0cda3e), U64_C(0xe949b9e6568386f0),
+ U64_C(0xfc0f0bbb2ad7ea04), U64_C(0x6a70675913b5a417),
+ U64_C(0x7f36d5046fe1c8e3), U64_C(0x0c57af8d02304ff8),
+ U64_C(0x32223abdfcc84618), U64_C(0x0891caf6f720815b),
+ U64_C(0xa63eeaec31a26fd4), U64_C(0x2507345374944d33),
+ U64_C(0x49d28ac266394058), U64_C(0xf5219f9aa7f3d6be),
+ U64_C(0x2d96fea583b4cc68), U64_C(0x5a31e1571b7585d0),
+ U64_C(0x8ed12fe53d02d0fe), U64_C(0xdfade6205f5b0e4b),
+ U64_C(0x4cabb16ee92d331a), U64_C(0x04c6657bf510cea3),
+ U64_C(0xd73c2cd6a87b8f10), U64_C(0xe1d87310a1a307ab),
+ U64_C(0x6cd5be9112ad0d6b), U64_C(0x97c032354366f3f2),
+ U64_C(0xd4e0ceb22677552e), U64_C(0x0000000000000000),
+ U64_C(0x29509bde76a402cb), U64_C(0xc27a9e8bd42fe3e4),
+ U64_C(0x5ef7842cee654b73), U64_C(0xaf107ecdbc86536e),
+ U64_C(0x3fcacbe784fcb401), U64_C(0xd55f90655c73e8cf),
+ U64_C(0xe6c2f40fdabf1336), U64_C(0xe8f6e7312c873b11),
+ U64_C(0xeb2a0555a28be12f), U64_C(0xe4a148bc2eb774e9),
+ U64_C(0x9b979db84156bc0a), U64_C(0x6eb60222e6a56ab4),
+ U64_C(0x87ffbbc4b026ec44), U64_C(0xc703a5275b3b90a6),
+ U64_C(0x47e699fc9001687f), U64_C(0x9c8d1aa73a4aa897),
+ U64_C(0x7cea3760e1ed12dd), U64_C(0x4ec80ddd1d2554c5),
+ U64_C(0x13e36b957d4cc588), U64_C(0x5d2b66486069914d),
+ U64_C(0x92b90999cc7280b0), U64_C(0x517cc9c56259deb5),
+ U64_C(0xc937b619ad03b881), U64_C(0xec30824ad997f5b2),
+ U64_C(0xa45d565fc5aa080b), U64_C(0xd6837201d27f32f1),
+ U64_C(0x635ef3789e9198ad), U64_C(0x531f75769651b96a),
+ U64_C(0x4f77530a6721e924), U64_C(0x486dd4151c3dfdb9),
+ U64_C(0x5f48dafb9461f692), U64_C(0x375b011173dc355a),
+ U64_C(0x3da9775470f4d3de), U64_C(0x8d0dcd81b30e0ac0),
+ U64_C(0x36e45fc609d888bb), U64_C(0x55baacbe97491016),
+ U64_C(0x8cb29356c90ab721), U64_C(0x76184125e2c5f459),
+ U64_C(0x99f4210bb55edbd5), U64_C(0x6f095cf59ca1d755),
+ U64_C(0x9f51f8c3b44672a9), U64_C(0x3538bda287d45285),
+ U64_C(0x50c39712185d6354), U64_C(0xf23b1885dcefc223),
+ U64_C(0x79930ccc6ef9619f), U64_C(0xed8fdc9da3934853),
+ U64_C(0xcb540aaa590bdf5e), U64_C(0x5c94389f1a6d2cac),
+ U64_C(0xe77daad8a0bbaed7), U64_C(0x28efc5090ca0bf2a),
+ U64_C(0xbf2ff73c4fc64cd8), U64_C(0xb37858b14df60320),
+ U64_C(0xf8c96ec0dfc724a7), U64_C(0x828680683f329f06),
+ U64_C(0x941cd051cd6a29cc), U64_C(0xc3c5c05cae2b5e05),
+ U64_C(0xb601631dc2e27062), U64_C(0xc01922382027843b),
+ U64_C(0x24b86a840e90f0d2), U64_C(0xd245177a276ffc52),
+ U64_C(0x0f8b4de98c3c95c6), U64_C(0x3e759530fef809e0),
+ U64_C(0x0b4d2892792c5b65), U64_C(0xc4df4743d5374a98),
+ U64_C(0xa5e20888bfaeb5ea), U64_C(0xba56cc90c0d23f9a),
+ U64_C(0x38d04cf8ffe0a09c), U64_C(0x62e1adafe495254c),
+ U64_C(0x0263bcb3f40867df), U64_C(0xcaeb547d230f62bf),
+ U64_C(0x6082111c109d4293), U64_C(0xdad4dd8cd04f7d09),
+ U64_C(0xefec602e579b2f8c), U64_C(0x1fb4c4187f7c8a70),
+ U64_C(0xffd3e9dfa4db303a), U64_C(0x7bf0b07f9af10640),
+ U64_C(0xf49ec14dddf76b5f), U64_C(0x8f6e713247066d1f),
+ U64_C(0x339d646a86ccfbf9), U64_C(0x64447467e58d8c30),
+ U64_C(0x2c29a072f9b07189), U64_C(0xd8b7613f24471ad6),
+ U64_C(0x6627c8d41185ebef), U64_C(0xa347d140beb61c96),
+ U64_C(0xde12b8f7255fb3aa), U64_C(0x9d324470404e1576),
+ U64_C(0x9306574eb6763d51), U64_C(0xa80af9d2c79a47f3),
+ U64_C(0x859c0777442e8b9b), U64_C(0x69ac853d9db97e29) },
+ /* 6 */
+ { U64_C(0xc3407dfc2de6377e), U64_C(0x5b9e93eea4256f77),
+ U64_C(0xadb58fdd50c845e0), U64_C(0x5219ff11a75bed86),
+ U64_C(0x356b61cfd90b1de9), U64_C(0xfb8f406e25abe037),
+ U64_C(0x7a5a0231c0f60796), U64_C(0x9d3cd216e1f5020b),
+ U64_C(0x0c6550fb6b48d8f3), U64_C(0xf57508c427ff1c62),
+ U64_C(0x4ad35ffa71cb407d), U64_C(0x6290a2da1666aa6d),
+ U64_C(0xe284ec2349355f9f), U64_C(0xb3c307c53d7c84ec),
+ U64_C(0x05e23c0468365a02), U64_C(0x190bac4d6c9ebfa8),
+ U64_C(0x94bbbee9e28b80fa), U64_C(0xa34fc777529cb9b5),
+ U64_C(0xcc7b39f095bcd978), U64_C(0x2426addb0ce532e3),
+ U64_C(0x7e79329312ce4fc7), U64_C(0xab09a72eebec2917),
+ U64_C(0xf8d15499f6b9d6c2), U64_C(0x1a55b8babf8c895d),
+ U64_C(0xdb8add17fb769a85), U64_C(0xb57f2f368658e81b),
+ U64_C(0x8acd36f18f3f41f6), U64_C(0x5ce3b7bba50f11d3),
+ U64_C(0x114dcc14d5ee2f0a), U64_C(0xb91a7fcded1030e8),
+ U64_C(0x81d5425fe55de7a1), U64_C(0xb6213bc1554adeee),
+ U64_C(0x80144ef95f53f5f2), U64_C(0x1e7688186db4c10c),
+ U64_C(0x3b912965db5fe1bc), U64_C(0xc281715a97e8252d),
+ U64_C(0x54a5d7e21c7f8171), U64_C(0x4b12535ccbc5522e),
+ U64_C(0x1d289cefbea6f7f9), U64_C(0x6ef5f2217d2e729e),
+ U64_C(0xe6a7dc819b0d17ce), U64_C(0x1b94b41c05829b0e),
+ U64_C(0x33d7493c622f711e), U64_C(0xdcf7f942fa5ce421),
+ U64_C(0x600fba8b7f7a8ecb), U64_C(0x46b60f011a83988e),
+ U64_C(0x235b898e0dcf4c47), U64_C(0x957ab24f588592a9),
+ U64_C(0x4354330572b5c28c), U64_C(0xa5f3ef84e9b8d542),
+ U64_C(0x8c711e02341b2d01), U64_C(0x0b1874ae6a62a657),
+ U64_C(0x1213d8e306fc19ff), U64_C(0xfe6d7c6a4d9dba35),
+ U64_C(0x65ed868f174cd4c9), U64_C(0x88522ea0e6236550),
+ U64_C(0x899322065c2d7703), U64_C(0xc01e690bfef4018b),
+ U64_C(0x915982ed8abddaf8), U64_C(0xbe675b98ec3a4e4c),
+ U64_C(0xa996bf7f82f00db1), U64_C(0xe1daf8d49a27696a),
+ U64_C(0x2effd5d3dc8986e7), U64_C(0xd153a51f2b1a2e81),
+ U64_C(0x18caa0ebd690adfb), U64_C(0x390e3134b243c51a),
+ U64_C(0x2778b92cdff70416), U64_C(0x029f1851691c24a6),
+ U64_C(0x5e7cafeacc133575), U64_C(0xfa4e4cc89fa5f264),
+ U64_C(0x5a5f9f481e2b7d24), U64_C(0x484c47ab18d764db),
+ U64_C(0x400a27f2a1a7f479), U64_C(0xaeeb9b2a83da7315),
+ U64_C(0x721c626879869734), U64_C(0x042330a2d2384851),
+ U64_C(0x85f672fd3765aff0), U64_C(0xba446b3a3e02061d),
+ U64_C(0x73dd6ecec3888567), U64_C(0xffac70ccf793a866),
+ U64_C(0xdfa9edb5294ed2d4), U64_C(0x6c6aea7014325638),
+ U64_C(0x834a5a0e8c41c307), U64_C(0xcdba35562fb2cb2b),
+ U64_C(0x0ad97808d06cb404), U64_C(0x0f3b440cb85aee06),
+ U64_C(0xe5f9c876481f213b), U64_C(0x98deee1289c35809),
+ U64_C(0x59018bbfcd394bd1), U64_C(0xe01bf47220297b39),
+ U64_C(0xde68e1139340c087), U64_C(0x9fa3ca4788e926ad),
+ U64_C(0xbb85679c840c144e), U64_C(0x53d8f3b71d55ffd5),
+ U64_C(0x0da45c5dd146caa0), U64_C(0x6f34fe87c72060cd),
+ U64_C(0x57fbc315cf6db784), U64_C(0xcee421a1fca0fdde),
+ U64_C(0x3d2d0196607b8d4b), U64_C(0x642c8a29ad42c69a),
+ U64_C(0x14aff010bdd87508), U64_C(0xac74837beac657b3),
+ U64_C(0x3216459ad821634d), U64_C(0x3fb219c70967a9ed),
+ U64_C(0x06bc28f3bb246cf7), U64_C(0xf2082c9126d562c6),
+ U64_C(0x66b39278c45ee23c), U64_C(0xbd394f6f3f2878b9),
+ U64_C(0xfd33689d9e8f8cc0), U64_C(0x37f4799eb017394f),
+ U64_C(0x108cc0b26fe03d59), U64_C(0xda4bd1b1417888d6),
+ U64_C(0xb09d1332ee6eb219), U64_C(0x2f3ed975668794b4),
+ U64_C(0x58c0871977375982), U64_C(0x7561463d78ace990),
+ U64_C(0x09876cff037e82f1), U64_C(0x7fb83e35a8c05d94),
+ U64_C(0x26b9b58a65f91645), U64_C(0xef20b07e9873953f),
+ U64_C(0x3148516d0b3355b8), U64_C(0x41cb2b541ba9e62a),
+ U64_C(0x790416c613e43163), U64_C(0xa011d380818e8f40),
+ U64_C(0x3a5025c36151f3ef), U64_C(0xd57095bdf92266d0),
+ U64_C(0x498d4b0da2d97688), U64_C(0x8b0c3a57353153a5),
+ U64_C(0x21c491df64d368e1), U64_C(0x8f2f0af5e7091bf4),
+ U64_C(0x2da1c1240f9bb012), U64_C(0xc43d59a92ccc49da),
+ U64_C(0xbfa6573e56345c1f), U64_C(0x828b56a8364fd154),
+ U64_C(0x9a41f643e0df7caf), U64_C(0xbcf843c985266aea),
+ U64_C(0x2b1de9d7b4bfdce5), U64_C(0x20059d79dedd7ab2),
+ U64_C(0x6dabe6d6ae3c446b), U64_C(0x45e81bf6c991ae7b),
+ U64_C(0x6351ae7cac68b83e), U64_C(0xa432e32253b6c711),
+ U64_C(0xd092a9b991143cd2), U64_C(0xcac711032e98b58f),
+ U64_C(0xd8d4c9e02864ac70), U64_C(0xc5fc550f96c25b89),
+ U64_C(0xd7ef8dec903e4276), U64_C(0x67729ede7e50f06f),
+ U64_C(0xeac28c7af045cf3d), U64_C(0xb15c1f945460a04a),
+ U64_C(0x9cfddeb05bfb1058), U64_C(0x93c69abce3a1fe5e),
+ U64_C(0xeb0380dc4a4bdd6e), U64_C(0xd20db1e8f8081874),
+ U64_C(0x229a8528b7c15e14), U64_C(0x44291750739fbc28),
+ U64_C(0xd3ccbd4e42060a27), U64_C(0xf62b1c33f4ed2a97),
+ U64_C(0x86a8660ae4779905), U64_C(0xd62e814a2a305025),
+ U64_C(0x477703a7a08d8add), U64_C(0x7b9b0e977af815c5),
+ U64_C(0x78c51a60a9ea2330), U64_C(0xa6adfb733aaae3b7),
+ U64_C(0x97e5aa1e3199b60f), U64_C(0x0000000000000000),
+ U64_C(0xf4b404629df10e31), U64_C(0x5564db44a6719322),
+ U64_C(0x9207961a59afec0d), U64_C(0x9624a6b88b97a45c),
+ U64_C(0x363575380a192b1c), U64_C(0x2c60cd82b595a241),
+ U64_C(0x7d272664c1dc7932), U64_C(0x7142769faa94a1c1),
+ U64_C(0xa1d0df263b809d13), U64_C(0x1630e841d4c451ae),
+ U64_C(0xc1df65ad44fa13d8), U64_C(0x13d2d445bcf20bac),
+ U64_C(0xd915c546926abe23), U64_C(0x38cf3d92084dd749),
+ U64_C(0xe766d0272103059d), U64_C(0xc7634d5effde7f2f),
+ U64_C(0x077d2455012a7ea4), U64_C(0xedbfa82ff16fb199),
+ U64_C(0xaf2a978c39d46146), U64_C(0x42953fa3c8bbd0df),
+ U64_C(0xcb061da59496a7dc), U64_C(0x25e7a17db6eb20b0),
+ U64_C(0x34aa6d6963050fba), U64_C(0xa76cf7d580a4f1e4),
+ U64_C(0xf7ea10954ee338c4), U64_C(0xfcf2643b24819e93),
+ U64_C(0xcf252d0746aeef8d), U64_C(0x4ef06f58a3f3082c),
+ U64_C(0x563acfb37563a5d7), U64_C(0x5086e740ce47c920),
+ U64_C(0x2982f186dda3f843), U64_C(0x87696aac5e798b56),
+ U64_C(0x5d22bb1d1f010380), U64_C(0x035e14f7d31236f5),
+ U64_C(0x3cec0d30da759f18), U64_C(0xf3c920379cdb7095),
+ U64_C(0xb8db736b571e22bb), U64_C(0xdd36f5e44052f672),
+ U64_C(0xaac8ab8851e23b44), U64_C(0xa857b3d938fe1fe2),
+ U64_C(0x17f1e4e76eca43fd), U64_C(0xec7ea4894b61a3ca),
+ U64_C(0x9e62c6e132e734fe), U64_C(0xd4b1991b432c7483),
+ U64_C(0x6ad6c283af163acf), U64_C(0x1ce9904904a8e5aa),
+ U64_C(0x5fbda34c761d2726), U64_C(0xf910583f4cb7c491),
+ U64_C(0xc6a241f845d06d7c), U64_C(0x4f3163fe19fd1a7f),
+ U64_C(0xe99c988d2357f9c8), U64_C(0x8eee06535d0709a7),
+ U64_C(0x0efa48aa0254fc55), U64_C(0xb4be23903c56fa48),
+ U64_C(0x763f52caabbedf65), U64_C(0xeee1bcd8227d876c),
+ U64_C(0xe345e085f33b4dcc), U64_C(0x3e731561b369bbbe),
+ U64_C(0x2843fd2067adea10), U64_C(0x2adce5710eb1ceb6),
+ U64_C(0xb7e03767ef44ccbd), U64_C(0x8db012a48e153f52),
+ U64_C(0x61ceb62dc5749c98), U64_C(0xe85d942b9959eb9b),
+ U64_C(0x4c6f7709caef2c8a), U64_C(0x84377e5b8d6bbda3),
+ U64_C(0x30895dcbb13d47eb), U64_C(0x74a04a9bc2a2fbc3),
+ U64_C(0x6b17ce251518289c), U64_C(0xe438c4d0f2113368),
+ U64_C(0x1fb784bed7bad35f), U64_C(0x9b80fae55ad16efc),
+ U64_C(0x77fe5e6c11b0cd36), U64_C(0xc858095247849129),
+ U64_C(0x08466059b97090a2), U64_C(0x01c10ca6ba0e1253),
+ U64_C(0x6988d6747c040c3a), U64_C(0x6849dad2c60a1e69),
+ U64_C(0x5147ebe67449db73), U64_C(0xc99905f4fd8a837a),
+ U64_C(0x991fe2b433cd4a5a), U64_C(0xf09734c04fc94660),
+ U64_C(0xa28ecbd1e892abe6), U64_C(0xf1563866f5c75433),
+ U64_C(0x4dae7baf70e13ed9), U64_C(0x7ce62ac27bd26b61),
+ U64_C(0x70837a39109ab392), U64_C(0x90988e4b30b3c8ab),
+ U64_C(0xb2020b63877296bf), U64_C(0x156efcb607d6675b) },
+ /* 7 */
+ { U64_C(0xe63f55ce97c331d0), U64_C(0x25b506b0015bba16),
+ U64_C(0xc8706e29e6ad9ba8), U64_C(0x5b43d3775d521f6a),
+ U64_C(0x0bfa3d577035106e), U64_C(0xab95fc172afb0e66),
+ U64_C(0xf64b63979e7a3276), U64_C(0xf58b4562649dad4b),
+ U64_C(0x48f7c3dbae0c83f1), U64_C(0xff31916642f5c8c5),
+ U64_C(0xcbb048dc1c4a0495), U64_C(0x66b8f83cdf622989),
+ U64_C(0x35c130e908e2b9b0), U64_C(0x7c761a61f0b34fa1),
+ U64_C(0x3601161cf205268d), U64_C(0x9e54ccfe2219b7d6),
+ U64_C(0x8b7d90a538940837), U64_C(0x9cd403588ea35d0b),
+ U64_C(0xbc3c6fea9ccc5b5a), U64_C(0xe5ff733b6d24aeed),
+ U64_C(0xceed22de0f7eb8d2), U64_C(0xec8581cab1ab545e),
+ U64_C(0xb96105e88ff8e71d), U64_C(0x8ca03501871a5ead),
+ U64_C(0x76ccce65d6db2a2f), U64_C(0x5883f582a7b58057),
+ U64_C(0x3f7be4ed2e8adc3e), U64_C(0x0fe7be06355cd9c9),
+ U64_C(0xee054e6c1d11be83), U64_C(0x1074365909b903a6),
+ U64_C(0x5dde9f80b4813c10), U64_C(0x4a770c7d02b6692c),
+ U64_C(0x5379c8d5d7809039), U64_C(0xb4067448161ed409),
+ U64_C(0x5f5e5026183bd6cd), U64_C(0xe898029bf4c29df9),
+ U64_C(0x7fb63c940a54d09c), U64_C(0xc5171f897f4ba8bc),
+ U64_C(0xa6f28db7b31d3d72), U64_C(0x2e4f3be7716eaa78),
+ U64_C(0x0d6771a099e63314), U64_C(0x82076254e41bf284),
+ U64_C(0x2f0fd2b42733df98), U64_C(0x5c9e76d3e2dc49f0),
+ U64_C(0x7aeb569619606cdb), U64_C(0x83478b07b2468764),
+ U64_C(0xcfadcb8d5923cd32), U64_C(0x85dac7f05b95a41e),
+ U64_C(0xb5469d1b4043a1e9), U64_C(0xb821ecbbd9a592fd),
+ U64_C(0x1b8e0b0e798c13c8), U64_C(0x62a57b6d9a0be02e),
+ U64_C(0xfcf1b793b81257f8), U64_C(0x9d94ea0bd8fe28eb),
+ U64_C(0x4cea408aeb654a56), U64_C(0x23284a47e888996c),
+ U64_C(0x2d8f1d128b893545), U64_C(0xf4cbac3132c0d8ab),
+ U64_C(0xbd7c86b9ca912eba), U64_C(0x3a268eef3dbe6079),
+ U64_C(0xf0d62f6077a9110c), U64_C(0x2735c916ade150cb),
+ U64_C(0x89fd5f03942ee2ea), U64_C(0x1acee25d2fd16628),
+ U64_C(0x90f39bab41181bff), U64_C(0x430dfe8cde39939f),
+ U64_C(0xf70b8ac4c8274796), U64_C(0x1c53aeaac6024552),
+ U64_C(0x13b410acf35e9c9b), U64_C(0xa532ab4249faa24f),
+ U64_C(0x2b1251e5625a163f), U64_C(0xd7e3e676da4841c7),
+ U64_C(0xa7b264e4e5404892), U64_C(0xda8497d643ae72d3),
+ U64_C(0x861ae105a1723b23), U64_C(0x38a6414991048aa4),
+ U64_C(0x6578dec92585b6b4), U64_C(0x0280cfa6acbaeadd),
+ U64_C(0x88bdb650c273970a), U64_C(0x9333bd5ebbff84c2),
+ U64_C(0x4e6a8f2c47dfa08b), U64_C(0x321c954db76cef2a),
+ U64_C(0x418d312a72837942), U64_C(0xb29b38bfffcdf773),
+ U64_C(0x6c022c38f90a4c07), U64_C(0x5a033a240b0f6a8a),
+ U64_C(0x1f93885f3ce5da6f), U64_C(0xc38a537e96988bc6),
+ U64_C(0x39e6a81ac759ff44), U64_C(0x29929e43cee0fce2),
+ U64_C(0x40cdd87924de0ca2), U64_C(0xe9d8ebc8a29fe819),
+ U64_C(0x0c2798f3cfbb46f4), U64_C(0x55e484223e53b343),
+ U64_C(0x4650948ecd0d2fd8), U64_C(0x20e86cb2126f0651),
+ U64_C(0x6d42c56baf5739e7), U64_C(0xa06fc1405ace1e08),
+ U64_C(0x7babbfc54f3d193b), U64_C(0x424d17df8864e67f),
+ U64_C(0xd8045870ef14980e), U64_C(0xc6d7397c85ac3781),
+ U64_C(0x21a885e1443273b1), U64_C(0x67f8116f893f5c69),
+ U64_C(0x24f5efe35706cff6), U64_C(0xd56329d076f2ab1a),
+ U64_C(0x5e1eb9754e66a32d), U64_C(0x28d2771098bd8902),
+ U64_C(0x8f6013f47dfdc190), U64_C(0x17a993fdb637553c),
+ U64_C(0xe0a219397e1012aa), U64_C(0x786b9930b5da8606),
+ U64_C(0x6e82e39e55b0a6da), U64_C(0x875a0856f72f4ec3),
+ U64_C(0x3741ff4fa458536d), U64_C(0xac4859b3957558fc),
+ U64_C(0x7ef6d5c75c09a57c), U64_C(0xc04a758b6c7f14fb),
+ U64_C(0xf9acdd91ab26ebbf), U64_C(0x7391a467c5ef9668),
+ U64_C(0x335c7c1ee1319aca), U64_C(0xa91533b18641e4bb),
+ U64_C(0xe4bf9a683b79db0d), U64_C(0x8e20faa72ba0b470),
+ U64_C(0x51f907737b3a7ae4), U64_C(0x2268a314bed5ec8c),
+ U64_C(0xd944b123b949edee), U64_C(0x31dcb3b84d8b7017),
+ U64_C(0xd3fe65279f218860), U64_C(0x097af2f1dc8ffab3),
+ U64_C(0x9b09a6fc312d0b91), U64_C(0xcc6ded78a3c4520f),
+ U64_C(0x3481d9ba5ebfcc50), U64_C(0x4f2a667f1182d56b),
+ U64_C(0xdfd9fdd4509ace94), U64_C(0x26752045fbbc252b),
+ U64_C(0xbffc491f662bc467), U64_C(0xdd593272fc202449),
+ U64_C(0x3cbbc218d46d4303), U64_C(0x91b372f817456e1f),
+ U64_C(0x681faf69bc6385a0), U64_C(0xb686bbeebaa43ed4),
+ U64_C(0x1469b5084cd0ca01), U64_C(0x98c98009cbca94ac),
+ U64_C(0x6438379a73d8c354), U64_C(0xc2caba2dc0c5fe26),
+ U64_C(0x3e3b0dbe78d7a9de), U64_C(0x50b9ee202d670f04),
+ U64_C(0x4590b27b37eab0e5), U64_C(0x6025b4cb36b10af3),
+ U64_C(0xfb2c1237079c0162), U64_C(0xa12f28130c936be8),
+ U64_C(0x4b37e52e54eb1ccc), U64_C(0x083a1ba28ad28f53),
+ U64_C(0xc10a9cd83a22611b), U64_C(0x9f1425ad7444c236),
+ U64_C(0x069d4cf7e9d3237a), U64_C(0xedc56899e7f621be),
+ U64_C(0x778c273680865fcf), U64_C(0x309c5aeb1bd605f7),
+ U64_C(0x8de0dc52d1472b4d), U64_C(0xf8ec34c2fd7b9e5f),
+ U64_C(0xea18cd3d58787724), U64_C(0xaad515447ca67b86),
+ U64_C(0x9989695a9d97e14c), U64_C(0x0000000000000000),
+ U64_C(0xf196c63321f464ec), U64_C(0x71116bc169557cb5),
+ U64_C(0xaf887f466f92c7c1), U64_C(0x972e3e0ffe964d65),
+ U64_C(0x190ec4a8d536f915), U64_C(0x95aef1a9522ca7b8),
+ U64_C(0xdc19db21aa7d51a9), U64_C(0x94ee18fa0471d258),
+ U64_C(0x8087adf248a11859), U64_C(0xc457f6da2916dd5c),
+ U64_C(0xfa6cfb6451c17482), U64_C(0xf256e0c6db13fbd1),
+ U64_C(0x6a9f60cf10d96f7d), U64_C(0x4daaa9d9bd383fb6),
+ U64_C(0x03c026f5fae79f3d), U64_C(0xde99148706c7bb74),
+ U64_C(0x2a52b8b6340763df), U64_C(0x6fc20acd03edd33a),
+ U64_C(0xd423c08320afdefa), U64_C(0xbbe1ca4e23420dc0),
+ U64_C(0x966ed75ca8cb3885), U64_C(0xeb58246e0e2502c4),
+ U64_C(0x055d6a021334bc47), U64_C(0xa47242111fa7d7af),
+ U64_C(0xe3623fcc84f78d97), U64_C(0x81c744a11efc6db9),
+ U64_C(0xaec8961539cfb221), U64_C(0xf31609958d4e8e31),
+ U64_C(0x63e5923ecc5695ce), U64_C(0x47107ddd9b505a38),
+ U64_C(0xa3afe7b5a0298135), U64_C(0x792b7063e387f3e6),
+ U64_C(0x0140e953565d75e0), U64_C(0x12f4f9ffa503e97b),
+ U64_C(0x750ce8902c3cb512), U64_C(0xdbc47e8515f30733),
+ U64_C(0x1ed3610c6ab8af8f), U64_C(0x5239218681dde5d9),
+ U64_C(0xe222d69fd2aaf877), U64_C(0xfe71783514a8bd25),
+ U64_C(0xcaf0a18f4a177175), U64_C(0x61655d9860ec7f13),
+ U64_C(0xe77fbc9dc19e4430), U64_C(0x2ccff441ddd440a5),
+ U64_C(0x16e97aaee06a20dc), U64_C(0xa855dae2d01c915b),
+ U64_C(0x1d1347f9905f30b2), U64_C(0xb7c652bdecf94b34),
+ U64_C(0xd03e43d265c6175d), U64_C(0xfdb15ec0ee4f2218),
+ U64_C(0x57644b8492e9599e), U64_C(0x07dda5a4bf8e569a),
+ U64_C(0x54a46d71680ec6a3), U64_C(0x5624a2d7c4b42c7e),
+ U64_C(0xbebca04c3076b187), U64_C(0x7d36f332a6ee3a41),
+ U64_C(0x3b6667bc6be31599), U64_C(0x695f463aea3ef040),
+ U64_C(0xad08b0e0c3282d1c), U64_C(0xb15b1e4a052a684e),
+ U64_C(0x44d05b2861b7c505), U64_C(0x15295c5b1a8dbfe1),
+ U64_C(0x744c01c37a61c0f2), U64_C(0x59c31cd1f1e8f5b7),
+ U64_C(0xef45a73f4b4ccb63), U64_C(0x6bdf899c46841a9d),
+ U64_C(0x3dfb2b4b823036e3), U64_C(0xa2ef0ee6f674f4d5),
+ U64_C(0x184e2dfb836b8cf5), U64_C(0x1134df0a5fe47646),
+ U64_C(0xbaa1231d751f7820), U64_C(0xd17eaa81339b62bd),
+ U64_C(0xb01bf71953771dae), U64_C(0x849a2ea30dc8d1fe),
+ U64_C(0x705182923f080955), U64_C(0x0ea757556301ac29),
+ U64_C(0x041d83514569c9a7), U64_C(0x0abad4042668658e),
+ U64_C(0x49b72a88f851f611), U64_C(0x8a3d79f66ec97dd7),
+ U64_C(0xcd2d042bf59927ef), U64_C(0xc930877ab0f0ee48),
+ U64_C(0x9273540deda2f122), U64_C(0xc797d02fd3f14261),
+ U64_C(0xe1e2f06a284d674a), U64_C(0xd2be8c74c97cfd80),
+ U64_C(0x9a494faf67707e71), U64_C(0xb3dbd1eca9908293),
+ U64_C(0x72d14d3493b2e388), U64_C(0xd6a30f258c153427) },
+};
+
+static const u64 C16[12][8] =
+{
+ { U64_C(0xdd806559f2a64507), U64_C(0x05767436cc744d23),
+ U64_C(0xa2422a08a460d315), U64_C(0x4b7ce09192676901),
+ U64_C(0x714eb88d7585c4fc), U64_C(0x2f6a76432e45d016),
+ U64_C(0xebcb2f81c0657c1f), U64_C(0xb1085bda1ecadae9) },
+ { U64_C(0xe679047021b19bb7), U64_C(0x55dda21bd7cbcd56),
+ U64_C(0x5cb561c2db0aa7ca), U64_C(0x9ab5176b12d69958),
+ U64_C(0x61d55e0f16b50131), U64_C(0xf3feea720a232b98),
+ U64_C(0x4fe39d460f70b5d7), U64_C(0x6fa3b58aa99d2f1a) },
+ { U64_C(0x991e96f50aba0ab2), U64_C(0xc2b6f443867adb31),
+ U64_C(0xc1c93a376062db09), U64_C(0xd3e20fe490359eb1),
+ U64_C(0xf2ea7514b1297b7b), U64_C(0x06f15e5f529c1f8b),
+ U64_C(0x0a39fc286a3d8435), U64_C(0xf574dcac2bce2fc7) },
+ { U64_C(0x220cbebc84e3d12e), U64_C(0x3453eaa193e837f1),
+ U64_C(0xd8b71333935203be), U64_C(0xa9d72c82ed03d675),
+ U64_C(0x9d721cad685e353f), U64_C(0x488e857e335c3c7d),
+ U64_C(0xf948e1a05d71e4dd), U64_C(0xef1fdfb3e81566d2) },
+ { U64_C(0x601758fd7c6cfe57), U64_C(0x7a56a27ea9ea63f5),
+ U64_C(0xdfff00b723271a16), U64_C(0xbfcd1747253af5a3),
+ U64_C(0x359e35d7800fffbd), U64_C(0x7f151c1f1686104a),
+ U64_C(0x9a3f410c6ca92363), U64_C(0x4bea6bacad474799) },
+ { U64_C(0xfa68407a46647d6e), U64_C(0xbf71c57236904f35),
+ U64_C(0x0af21f66c2bec6b6), U64_C(0xcffaa6b71c9ab7b4),
+ U64_C(0x187f9ab49af08ec6), U64_C(0x2d66c4f95142a46c),
+ U64_C(0x6fa4c33b7a3039c0), U64_C(0xae4faeae1d3ad3d9) },
+ { U64_C(0x8886564d3a14d493), U64_C(0x3517454ca23c4af3),
+ U64_C(0x06476983284a0504), U64_C(0x0992abc52d822c37),
+ U64_C(0xd3473e33197a93c9), U64_C(0x399ec6c7e6bf87c9),
+ U64_C(0x51ac86febf240954), U64_C(0xf4c70e16eeaac5ec) },
+ { U64_C(0xa47f0dd4bf02e71e), U64_C(0x36acc2355951a8d9),
+ U64_C(0x69d18d2bd1a5c42f), U64_C(0xf4892bcb929b0690),
+ U64_C(0x89b4443b4ddbc49a), U64_C(0x4eb7f8719c36de1e),
+ U64_C(0x03e7aa020c6e4141), U64_C(0x9b1f5b424d93c9a7) },
+ { U64_C(0x7261445183235adb), U64_C(0x0e38dc92cb1f2a60),
+ U64_C(0x7b2b8a9aa6079c54), U64_C(0x800a440bdbb2ceb1),
+ U64_C(0x3cd955b7e00d0984), U64_C(0x3a7d3a1b25894224),
+ U64_C(0x944c9ad8ec165fde), U64_C(0x378f5a541631229b) },
+ { U64_C(0x74b4c7fb98459ced), U64_C(0x3698fad1153bb6c3),
+ U64_C(0x7a1e6c303b7652f4), U64_C(0x9fe76702af69334b),
+ U64_C(0x1fffe18a1b336103), U64_C(0x8941e71cff8a78db),
+ U64_C(0x382ae548b2e4f3f3), U64_C(0xabbedea680056f52) },
+ { U64_C(0x6bcaa4cd81f32d1b), U64_C(0xdea2594ac06fd85d),
+ U64_C(0xefbacd1d7d476e98), U64_C(0x8a1d71efea48b9ca),
+ U64_C(0x2001802114846679), U64_C(0xd8fa6bbbebab0761),
+ U64_C(0x3002c6cd635afe94), U64_C(0x7bcd9ed0efc889fb) },
+ { U64_C(0x48bc924af11bd720), U64_C(0xfaf417d5d9b21b99),
+ U64_C(0xe71da4aa88e12852), U64_C(0x5d80ef9d1891cc86),
+ U64_C(0xf82012d430219f9b), U64_C(0xcda43c32bcdf1d77),
+ U64_C(0xd21380b00449b17a), U64_C(0x378ee767f11631ba) },
+};
+
+
+#define strido(out, temp, i) do { \
+ u64 t; \
+ t = stribog_table[0][(temp[0] >> (i * 8)) & 0xff]; \
+ t ^= stribog_table[1][(temp[1] >> (i * 8)) & 0xff]; \
+ t ^= stribog_table[2][(temp[2] >> (i * 8)) & 0xff]; \
+ t ^= stribog_table[3][(temp[3] >> (i * 8)) & 0xff]; \
+ t ^= stribog_table[4][(temp[4] >> (i * 8)) & 0xff]; \
+ t ^= stribog_table[5][(temp[5] >> (i * 8)) & 0xff]; \
+ t ^= stribog_table[6][(temp[6] >> (i * 8)) & 0xff]; \
+ t ^= stribog_table[7][(temp[7] >> (i * 8)) & 0xff]; \
+ out[i] = t; } while(0)
+
+static void LPSX (u64 *out, const u64 *a, const u64 *b)
+{
+ u64 temp[8];
+ temp[0] = a[0] ^ b[0];
+ temp[1] = a[1] ^ b[1];
+ temp[2] = a[2] ^ b[2];
+ temp[3] = a[3] ^ b[3];
+ temp[4] = a[4] ^ b[4];
+ temp[5] = a[5] ^ b[5];
+ temp[6] = a[6] ^ b[6];
+ temp[7] = a[7] ^ b[7];
+ strido (out, temp, 0);
+ strido (out, temp, 1);
+ strido (out, temp, 2);
+ strido (out, temp, 3);
+ strido (out, temp, 4);
+ strido (out, temp, 5);
+ strido (out, temp, 6);
+ strido (out, temp, 7);
+}
+
+static inline void g (u64 *h, u64 *m, u64 *N)
+{
+ u64 K[8];
+ u64 T[8];
+ int i;
+
+ LPSX (K, h, N);
+
+ LPSX (T, K, m);
+ LPSX (K, K, C16[0]);
+ for (i = 1; i < 12; i++)
+ {
+ LPSX (T, K, T);
+ LPSX (K, K, C16[i]);
+ }
+
+ h[0] ^= T[0] ^ K[0] ^ m[0];
+ h[1] ^= T[1] ^ K[1] ^ m[1];
+ h[2] ^= T[2] ^ K[2] ^ m[2];
+ h[3] ^= T[3] ^ K[3] ^ m[3];
+ h[4] ^= T[4] ^ K[4] ^ m[4];
+ h[5] ^= T[5] ^ K[5] ^ m[5];
+ h[6] ^= T[6] ^ K[6] ^ m[6];
+ h[7] ^= T[7] ^ K[7] ^ m[7];
+}
+
+
+static unsigned int
+transform (void *context, const unsigned char *inbuf_arg, size_t datalen);
+
+
+static void
+stribog_init_512 (void *context, unsigned int flags)
+{
+ STRIBOG_CONTEXT *hd = context;
+
+ (void)flags;
+
+ memset (hd, 0, sizeof (*hd));
+
+ hd->bctx.blocksize_shift = _gcry_ctz(64);
+ hd->bctx.bwrite = transform;
+}
+
+static void
+stribog_init_256 (void *context, unsigned int flags)
+{
+ STRIBOG_CONTEXT *hd = context;
+
+ stribog_init_512 (context, flags);
+ memset (hd->h, 1, 64);
+}
+
+static void
+transform_bits (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count)
+{
+ u64 M[8];
+ u64 l, cf;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ M[i] = buf_get_le64(data + i * 8);
+
+ g (hd->h, M, hd->N);
+ l = hd->N[0];
+ hd->N[0] += count;
+ if (hd->N[0] < l)
+ { /* overflow */
+ for (i = 1; i < 8; i++)
+ {
+ hd->N[i]++;
+ if (hd->N[i] != 0)
+ break;
+ }
+ }
+
+ hd->Sigma[0] += M[0];
+ cf = 0;
+ for (i = 1; i < 8; i++)
+ {
+ if (hd->Sigma[i-1] != M[i-1])
+ cf = (hd->Sigma[i-1] < M[i-1]);
+ hd->Sigma[i] += M[i] + cf;
+ }
+}
+
+static unsigned int
+transform_blk (void *context, const unsigned char *inbuf_arg)
+{
+ STRIBOG_CONTEXT *hd = context;
+
+ transform_bits (hd, inbuf_arg, 64 * 8);
+
+ return /* burn_stack */ 768;
+}
+
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+ unsigned int burn;
+
+ do
+ {
+ burn = transform_blk (c, data);
+ data += 64;
+ }
+ while (--nblks);
+
+ return burn;
+}
+
+/*
+ The routine finally terminates the computation and returns the
+ digest. The handle is prepared for a new cycle, but adding bytes
+ to the handle will the destroy the returned buffer. Returns: 32
+ bytes with the message the digest. */
+static void
+stribog_final (void *context)
+{
+ STRIBOG_CONTEXT *hd = context;
+ u64 Z[8] = {};
+ int i;
+
+ /* PAD. It does not count towards message length */
+ i = hd->bctx.count;
+ /* After flush we have at least one byte free) */
+ hd->bctx.buf[i++] = 1;
+ if (i < 64)
+ memset (&hd->bctx.buf[i], 0, 64 - i);
+ i = 64;
+ transform_bits (hd, hd->bctx.buf, hd->bctx.count * 8);
+
+ g (hd->h, hd->N, Z);
+ g (hd->h, hd->Sigma, Z);
+
+ for (i = 0; i < 8; i++)
+ hd->h[i] = le_bswap64(hd->h[i]);
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (768);
+}
+
+static byte *
+stribog_read_512 (void *context)
+{
+ STRIBOG_CONTEXT *hd = context;
+
+ return hd->result;
+}
+
+static byte *
+stribog_read_256 (void *context)
+{
+ STRIBOG_CONTEXT *hd = context;
+
+ return hd->result + 32;
+}
+
+static gcry_md_oid_spec_t oid_spec_stribog256[] =
+ {
+ /* id-tc26-signwithdigest-gost3410-12-256 */
+ { "1.2.643.7.1.1.3.2" },
+ /* id-tc26-gost3411-12-256 */
+ { "1.2.643.7.1.1.2.2" },
+ { NULL },
+ };
+
+static gcry_md_oid_spec_t oid_spec_stribog512[] =
+ {
+ /* id-tc26-signwithdigest-gost3410-12-512 */
+ { "1.2.643.7.1.1.3.3" },
+ /* id-tc26-gost3411-12-512 */
+ { "1.2.643.7.1.1.2.3" },
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_stribog_256 =
+ {
+ GCRY_MD_STRIBOG256, {0, 0},
+ "STRIBOG256", NULL, 0, oid_spec_stribog256, 32,
+ stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read_256,
+ NULL, NULL, NULL,
+ sizeof (STRIBOG_CONTEXT)
+ };
+
+gcry_md_spec_t _gcry_digest_spec_stribog_512 =
+ {
+ GCRY_MD_STRIBOG512, {0, 0},
+ "STRIBOG512", NULL, 0, oid_spec_stribog512, 64,
+ stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read_512,
+ NULL, NULL, NULL,
+ sizeof (STRIBOG_CONTEXT)
+ };
diff --git a/comm/third_party/libgcrypt/cipher/tiger.c b/comm/third_party/libgcrypt/cipher/tiger.c
new file mode 100644
index 0000000000..4039b22b1c
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/tiger.c
@@ -0,0 +1,860 @@
+/* tiger.c - The TIGER hash function
+ * Copyright (C) 1998, 2001, 2002, 2003, 2010 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
+ */
+
+/* See http://www.cs.technion.ac.il/~biham/Reports/Tiger/ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "hash-common.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+
+typedef struct
+{
+ gcry_md_block_ctx_t bctx;
+ u64 a, b, c;
+ int variant; /* 0 = old code, 1 = fixed code, 2 - TIGER2. */
+} TIGER_CONTEXT;
+
+
+/*********************************
+ * Okay, okay, this is not the fastest code - improvements are welcome.
+ *
+ */
+
+/* Some test vectors:
+ * "" 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
+ * "abc" F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
+ * "Tiger" 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
+ * 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789"
+ * 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham"
+ * 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
+ * "eedings of Fast Software Encryption 3, Cambridge."
+ * EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
+ * "eedings of Fast Software Encryption 3, Cambridge, 1996."
+ * 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEF"
+ * "GHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
+ * 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
+ */
+
+static u64 sbox1[256] = {
+ U64_C(0x02aab17cf7e90c5e) /* 0 */, U64_C(0xac424b03e243a8ec) /* 1 */,
+ U64_C(0x72cd5be30dd5fcd3) /* 2 */, U64_C(0x6d019b93f6f97f3a) /* 3 */,
+ U64_C(0xcd9978ffd21f9193) /* 4 */, U64_C(0x7573a1c9708029e2) /* 5 */,
+ U64_C(0xb164326b922a83c3) /* 6 */, U64_C(0x46883eee04915870) /* 7 */,
+ U64_C(0xeaace3057103ece6) /* 8 */, U64_C(0xc54169b808a3535c) /* 9 */,
+ U64_C(0x4ce754918ddec47c) /* 10 */, U64_C(0x0aa2f4dfdc0df40c) /* 11 */,
+ U64_C(0x10b76f18a74dbefa) /* 12 */, U64_C(0xc6ccb6235ad1ab6a) /* 13 */,
+ U64_C(0x13726121572fe2ff) /* 14 */, U64_C(0x1a488c6f199d921e) /* 15 */,
+ U64_C(0x4bc9f9f4da0007ca) /* 16 */, U64_C(0x26f5e6f6e85241c7) /* 17 */,
+ U64_C(0x859079dbea5947b6) /* 18 */, U64_C(0x4f1885c5c99e8c92) /* 19 */,
+ U64_C(0xd78e761ea96f864b) /* 20 */, U64_C(0x8e36428c52b5c17d) /* 21 */,
+ U64_C(0x69cf6827373063c1) /* 22 */, U64_C(0xb607c93d9bb4c56e) /* 23 */,
+ U64_C(0x7d820e760e76b5ea) /* 24 */, U64_C(0x645c9cc6f07fdc42) /* 25 */,
+ U64_C(0xbf38a078243342e0) /* 26 */, U64_C(0x5f6b343c9d2e7d04) /* 27 */,
+ U64_C(0xf2c28aeb600b0ec6) /* 28 */, U64_C(0x6c0ed85f7254bcac) /* 29 */,
+ U64_C(0x71592281a4db4fe5) /* 30 */, U64_C(0x1967fa69ce0fed9f) /* 31 */,
+ U64_C(0xfd5293f8b96545db) /* 32 */, U64_C(0xc879e9d7f2a7600b) /* 33 */,
+ U64_C(0x860248920193194e) /* 34 */, U64_C(0xa4f9533b2d9cc0b3) /* 35 */,
+ U64_C(0x9053836c15957613) /* 36 */, U64_C(0xdb6dcf8afc357bf1) /* 37 */,
+ U64_C(0x18beea7a7a370f57) /* 38 */, U64_C(0x037117ca50b99066) /* 39 */,
+ U64_C(0x6ab30a9774424a35) /* 40 */, U64_C(0xf4e92f02e325249b) /* 41 */,
+ U64_C(0x7739db07061ccae1) /* 42 */, U64_C(0xd8f3b49ceca42a05) /* 43 */,
+ U64_C(0xbd56be3f51382f73) /* 44 */, U64_C(0x45faed5843b0bb28) /* 45 */,
+ U64_C(0x1c813d5c11bf1f83) /* 46 */, U64_C(0x8af0e4b6d75fa169) /* 47 */,
+ U64_C(0x33ee18a487ad9999) /* 48 */, U64_C(0x3c26e8eab1c94410) /* 49 */,
+ U64_C(0xb510102bc0a822f9) /* 50 */, U64_C(0x141eef310ce6123b) /* 51 */,
+ U64_C(0xfc65b90059ddb154) /* 52 */, U64_C(0xe0158640c5e0e607) /* 53 */,
+ U64_C(0x884e079826c3a3cf) /* 54 */, U64_C(0x930d0d9523c535fd) /* 55 */,
+ U64_C(0x35638d754e9a2b00) /* 56 */, U64_C(0x4085fccf40469dd5) /* 57 */,
+ U64_C(0xc4b17ad28be23a4c) /* 58 */, U64_C(0xcab2f0fc6a3e6a2e) /* 59 */,
+ U64_C(0x2860971a6b943fcd) /* 60 */, U64_C(0x3dde6ee212e30446) /* 61 */,
+ U64_C(0x6222f32ae01765ae) /* 62 */, U64_C(0x5d550bb5478308fe) /* 63 */,
+ U64_C(0xa9efa98da0eda22a) /* 64 */, U64_C(0xc351a71686c40da7) /* 65 */,
+ U64_C(0x1105586d9c867c84) /* 66 */, U64_C(0xdcffee85fda22853) /* 67 */,
+ U64_C(0xccfbd0262c5eef76) /* 68 */, U64_C(0xbaf294cb8990d201) /* 69 */,
+ U64_C(0xe69464f52afad975) /* 70 */, U64_C(0x94b013afdf133e14) /* 71 */,
+ U64_C(0x06a7d1a32823c958) /* 72 */, U64_C(0x6f95fe5130f61119) /* 73 */,
+ U64_C(0xd92ab34e462c06c0) /* 74 */, U64_C(0xed7bde33887c71d2) /* 75 */,
+ U64_C(0x79746d6e6518393e) /* 76 */, U64_C(0x5ba419385d713329) /* 77 */,
+ U64_C(0x7c1ba6b948a97564) /* 78 */, U64_C(0x31987c197bfdac67) /* 79 */,
+ U64_C(0xde6c23c44b053d02) /* 80 */, U64_C(0x581c49fed002d64d) /* 81 */,
+ U64_C(0xdd474d6338261571) /* 82 */, U64_C(0xaa4546c3e473d062) /* 83 */,
+ U64_C(0x928fce349455f860) /* 84 */, U64_C(0x48161bbacaab94d9) /* 85 */,
+ U64_C(0x63912430770e6f68) /* 86 */, U64_C(0x6ec8a5e602c6641c) /* 87 */,
+ U64_C(0x87282515337ddd2b) /* 88 */, U64_C(0x2cda6b42034b701b) /* 89 */,
+ U64_C(0xb03d37c181cb096d) /* 90 */, U64_C(0xe108438266c71c6f) /* 91 */,
+ U64_C(0x2b3180c7eb51b255) /* 92 */, U64_C(0xdf92b82f96c08bbc) /* 93 */,
+ U64_C(0x5c68c8c0a632f3ba) /* 94 */, U64_C(0x5504cc861c3d0556) /* 95 */,
+ U64_C(0xabbfa4e55fb26b8f) /* 96 */, U64_C(0x41848b0ab3baceb4) /* 97 */,
+ U64_C(0xb334a273aa445d32) /* 98 */, U64_C(0xbca696f0a85ad881) /* 99 */,
+ U64_C(0x24f6ec65b528d56c) /* 100 */, U64_C(0x0ce1512e90f4524a) /* 101 */,
+ U64_C(0x4e9dd79d5506d35a) /* 102 */, U64_C(0x258905fac6ce9779) /* 103 */,
+ U64_C(0x2019295b3e109b33) /* 104 */, U64_C(0xf8a9478b73a054cc) /* 105 */,
+ U64_C(0x2924f2f934417eb0) /* 106 */, U64_C(0x3993357d536d1bc4) /* 107 */,
+ U64_C(0x38a81ac21db6ff8b) /* 108 */, U64_C(0x47c4fbf17d6016bf) /* 109 */,
+ U64_C(0x1e0faadd7667e3f5) /* 110 */, U64_C(0x7abcff62938beb96) /* 111 */,
+ U64_C(0xa78dad948fc179c9) /* 112 */, U64_C(0x8f1f98b72911e50d) /* 113 */,
+ U64_C(0x61e48eae27121a91) /* 114 */, U64_C(0x4d62f7ad31859808) /* 115 */,
+ U64_C(0xeceba345ef5ceaeb) /* 116 */, U64_C(0xf5ceb25ebc9684ce) /* 117 */,
+ U64_C(0xf633e20cb7f76221) /* 118 */, U64_C(0xa32cdf06ab8293e4) /* 119 */,
+ U64_C(0x985a202ca5ee2ca4) /* 120 */, U64_C(0xcf0b8447cc8a8fb1) /* 121 */,
+ U64_C(0x9f765244979859a3) /* 122 */, U64_C(0xa8d516b1a1240017) /* 123 */,
+ U64_C(0x0bd7ba3ebb5dc726) /* 124 */, U64_C(0xe54bca55b86adb39) /* 125 */,
+ U64_C(0x1d7a3afd6c478063) /* 126 */, U64_C(0x519ec608e7669edd) /* 127 */,
+ U64_C(0x0e5715a2d149aa23) /* 128 */, U64_C(0x177d4571848ff194) /* 129 */,
+ U64_C(0xeeb55f3241014c22) /* 130 */, U64_C(0x0f5e5ca13a6e2ec2) /* 131 */,
+ U64_C(0x8029927b75f5c361) /* 132 */, U64_C(0xad139fabc3d6e436) /* 133 */,
+ U64_C(0x0d5df1a94ccf402f) /* 134 */, U64_C(0x3e8bd948bea5dfc8) /* 135 */,
+ U64_C(0xa5a0d357bd3ff77e) /* 136 */, U64_C(0xa2d12e251f74f645) /* 137 */,
+ U64_C(0x66fd9e525e81a082) /* 138 */, U64_C(0x2e0c90ce7f687a49) /* 139 */,
+ U64_C(0xc2e8bcbeba973bc5) /* 140 */, U64_C(0x000001bce509745f) /* 141 */,
+ U64_C(0x423777bbe6dab3d6) /* 142 */, U64_C(0xd1661c7eaef06eb5) /* 143 */,
+ U64_C(0xa1781f354daacfd8) /* 144 */, U64_C(0x2d11284a2b16affc) /* 145 */,
+ U64_C(0xf1fc4f67fa891d1f) /* 146 */, U64_C(0x73ecc25dcb920ada) /* 147 */,
+ U64_C(0xae610c22c2a12651) /* 148 */, U64_C(0x96e0a810d356b78a) /* 149 */,
+ U64_C(0x5a9a381f2fe7870f) /* 150 */, U64_C(0xd5ad62ede94e5530) /* 151 */,
+ U64_C(0xd225e5e8368d1427) /* 152 */, U64_C(0x65977b70c7af4631) /* 153 */,
+ U64_C(0x99f889b2de39d74f) /* 154 */, U64_C(0x233f30bf54e1d143) /* 155 */,
+ U64_C(0x9a9675d3d9a63c97) /* 156 */, U64_C(0x5470554ff334f9a8) /* 157 */,
+ U64_C(0x166acb744a4f5688) /* 158 */, U64_C(0x70c74caab2e4aead) /* 159 */,
+ U64_C(0xf0d091646f294d12) /* 160 */, U64_C(0x57b82a89684031d1) /* 161 */,
+ U64_C(0xefd95a5a61be0b6b) /* 162 */, U64_C(0x2fbd12e969f2f29a) /* 163 */,
+ U64_C(0x9bd37013feff9fe8) /* 164 */, U64_C(0x3f9b0404d6085a06) /* 165 */,
+ U64_C(0x4940c1f3166cfe15) /* 166 */, U64_C(0x09542c4dcdf3defb) /* 167 */,
+ U64_C(0xb4c5218385cd5ce3) /* 168 */, U64_C(0xc935b7dc4462a641) /* 169 */,
+ U64_C(0x3417f8a68ed3b63f) /* 170 */, U64_C(0xb80959295b215b40) /* 171 */,
+ U64_C(0xf99cdaef3b8c8572) /* 172 */, U64_C(0x018c0614f8fcb95d) /* 173 */,
+ U64_C(0x1b14accd1a3acdf3) /* 174 */, U64_C(0x84d471f200bb732d) /* 175 */,
+ U64_C(0xc1a3110e95e8da16) /* 176 */, U64_C(0x430a7220bf1a82b8) /* 177 */,
+ U64_C(0xb77e090d39df210e) /* 178 */, U64_C(0x5ef4bd9f3cd05e9d) /* 179 */,
+ U64_C(0x9d4ff6da7e57a444) /* 180 */, U64_C(0xda1d60e183d4a5f8) /* 181 */,
+ U64_C(0xb287c38417998e47) /* 182 */, U64_C(0xfe3edc121bb31886) /* 183 */,
+ U64_C(0xc7fe3ccc980ccbef) /* 184 */, U64_C(0xe46fb590189bfd03) /* 185 */,
+ U64_C(0x3732fd469a4c57dc) /* 186 */, U64_C(0x7ef700a07cf1ad65) /* 187 */,
+ U64_C(0x59c64468a31d8859) /* 188 */, U64_C(0x762fb0b4d45b61f6) /* 189 */,
+ U64_C(0x155baed099047718) /* 190 */, U64_C(0x68755e4c3d50baa6) /* 191 */,
+ U64_C(0xe9214e7f22d8b4df) /* 192 */, U64_C(0x2addbf532eac95f4) /* 193 */,
+ U64_C(0x32ae3909b4bd0109) /* 194 */, U64_C(0x834df537b08e3450) /* 195 */,
+ U64_C(0xfa209da84220728d) /* 196 */, U64_C(0x9e691d9b9efe23f7) /* 197 */,
+ U64_C(0x0446d288c4ae8d7f) /* 198 */, U64_C(0x7b4cc524e169785b) /* 199 */,
+ U64_C(0x21d87f0135ca1385) /* 200 */, U64_C(0xcebb400f137b8aa5) /* 201 */,
+ U64_C(0x272e2b66580796be) /* 202 */, U64_C(0x3612264125c2b0de) /* 203 */,
+ U64_C(0x057702bdad1efbb2) /* 204 */, U64_C(0xd4babb8eacf84be9) /* 205 */,
+ U64_C(0x91583139641bc67b) /* 206 */, U64_C(0x8bdc2de08036e024) /* 207 */,
+ U64_C(0x603c8156f49f68ed) /* 208 */, U64_C(0xf7d236f7dbef5111) /* 209 */,
+ U64_C(0x9727c4598ad21e80) /* 210 */, U64_C(0xa08a0896670a5fd7) /* 211 */,
+ U64_C(0xcb4a8f4309eba9cb) /* 212 */, U64_C(0x81af564b0f7036a1) /* 213 */,
+ U64_C(0xc0b99aa778199abd) /* 214 */, U64_C(0x959f1ec83fc8e952) /* 215 */,
+ U64_C(0x8c505077794a81b9) /* 216 */, U64_C(0x3acaaf8f056338f0) /* 217 */,
+ U64_C(0x07b43f50627a6778) /* 218 */, U64_C(0x4a44ab49f5eccc77) /* 219 */,
+ U64_C(0x3bc3d6e4b679ee98) /* 220 */, U64_C(0x9cc0d4d1cf14108c) /* 221 */,
+ U64_C(0x4406c00b206bc8a0) /* 222 */, U64_C(0x82a18854c8d72d89) /* 223 */,
+ U64_C(0x67e366b35c3c432c) /* 224 */, U64_C(0xb923dd61102b37f2) /* 225 */,
+ U64_C(0x56ab2779d884271d) /* 226 */, U64_C(0xbe83e1b0ff1525af) /* 227 */,
+ U64_C(0xfb7c65d4217e49a9) /* 228 */, U64_C(0x6bdbe0e76d48e7d4) /* 229 */,
+ U64_C(0x08df828745d9179e) /* 230 */, U64_C(0x22ea6a9add53bd34) /* 231 */,
+ U64_C(0xe36e141c5622200a) /* 232 */, U64_C(0x7f805d1b8cb750ee) /* 233 */,
+ U64_C(0xafe5c7a59f58e837) /* 234 */, U64_C(0xe27f996a4fb1c23c) /* 235 */,
+ U64_C(0xd3867dfb0775f0d0) /* 236 */, U64_C(0xd0e673de6e88891a) /* 237 */,
+ U64_C(0x123aeb9eafb86c25) /* 238 */, U64_C(0x30f1d5d5c145b895) /* 239 */,
+ U64_C(0xbb434a2dee7269e7) /* 240 */, U64_C(0x78cb67ecf931fa38) /* 241 */,
+ U64_C(0xf33b0372323bbf9c) /* 242 */, U64_C(0x52d66336fb279c74) /* 243 */,
+ U64_C(0x505f33ac0afb4eaa) /* 244 */, U64_C(0xe8a5cd99a2cce187) /* 245 */,
+ U64_C(0x534974801e2d30bb) /* 246 */, U64_C(0x8d2d5711d5876d90) /* 247 */,
+ U64_C(0x1f1a412891bc038e) /* 248 */, U64_C(0xd6e2e71d82e56648) /* 249 */,
+ U64_C(0x74036c3a497732b7) /* 250 */, U64_C(0x89b67ed96361f5ab) /* 251 */,
+ U64_C(0xffed95d8f1ea02a2) /* 252 */, U64_C(0xe72b3bd61464d43d) /* 253 */,
+ U64_C(0xa6300f170bdc4820) /* 254 */, U64_C(0xebc18760ed78a77a) /* 255 */
+};
+static u64 sbox2[256] = {
+ U64_C(0xe6a6be5a05a12138) /* 256 */, U64_C(0xb5a122a5b4f87c98) /* 257 */,
+ U64_C(0x563c6089140b6990) /* 258 */, U64_C(0x4c46cb2e391f5dd5) /* 259 */,
+ U64_C(0xd932addbc9b79434) /* 260 */, U64_C(0x08ea70e42015aff5) /* 261 */,
+ U64_C(0xd765a6673e478cf1) /* 262 */, U64_C(0xc4fb757eab278d99) /* 263 */,
+ U64_C(0xdf11c6862d6e0692) /* 264 */, U64_C(0xddeb84f10d7f3b16) /* 265 */,
+ U64_C(0x6f2ef604a665ea04) /* 266 */, U64_C(0x4a8e0f0ff0e0dfb3) /* 267 */,
+ U64_C(0xa5edeef83dbcba51) /* 268 */, U64_C(0xfc4f0a2a0ea4371e) /* 269 */,
+ U64_C(0xe83e1da85cb38429) /* 270 */, U64_C(0xdc8ff882ba1b1ce2) /* 271 */,
+ U64_C(0xcd45505e8353e80d) /* 272 */, U64_C(0x18d19a00d4db0717) /* 273 */,
+ U64_C(0x34a0cfeda5f38101) /* 274 */, U64_C(0x0be77e518887caf2) /* 275 */,
+ U64_C(0x1e341438b3c45136) /* 276 */, U64_C(0xe05797f49089ccf9) /* 277 */,
+ U64_C(0xffd23f9df2591d14) /* 278 */, U64_C(0x543dda228595c5cd) /* 279 */,
+ U64_C(0x661f81fd99052a33) /* 280 */, U64_C(0x8736e641db0f7b76) /* 281 */,
+ U64_C(0x15227725418e5307) /* 282 */, U64_C(0xe25f7f46162eb2fa) /* 283 */,
+ U64_C(0x48a8b2126c13d9fe) /* 284 */, U64_C(0xafdc541792e76eea) /* 285 */,
+ U64_C(0x03d912bfc6d1898f) /* 286 */, U64_C(0x31b1aafa1b83f51b) /* 287 */,
+ U64_C(0xf1ac2796e42ab7d9) /* 288 */, U64_C(0x40a3a7d7fcd2ebac) /* 289 */,
+ U64_C(0x1056136d0afbbcc5) /* 290 */, U64_C(0x7889e1dd9a6d0c85) /* 291 */,
+ U64_C(0xd33525782a7974aa) /* 292 */, U64_C(0xa7e25d09078ac09b) /* 293 */,
+ U64_C(0xbd4138b3eac6edd0) /* 294 */, U64_C(0x920abfbe71eb9e70) /* 295 */,
+ U64_C(0xa2a5d0f54fc2625c) /* 296 */, U64_C(0xc054e36b0b1290a3) /* 297 */,
+ U64_C(0xf6dd59ff62fe932b) /* 298 */, U64_C(0x3537354511a8ac7d) /* 299 */,
+ U64_C(0xca845e9172fadcd4) /* 300 */, U64_C(0x84f82b60329d20dc) /* 301 */,
+ U64_C(0x79c62ce1cd672f18) /* 302 */, U64_C(0x8b09a2add124642c) /* 303 */,
+ U64_C(0xd0c1e96a19d9e726) /* 304 */, U64_C(0x5a786a9b4ba9500c) /* 305 */,
+ U64_C(0x0e020336634c43f3) /* 306 */, U64_C(0xc17b474aeb66d822) /* 307 */,
+ U64_C(0x6a731ae3ec9baac2) /* 308 */, U64_C(0x8226667ae0840258) /* 309 */,
+ U64_C(0x67d4567691caeca5) /* 310 */, U64_C(0x1d94155c4875adb5) /* 311 */,
+ U64_C(0x6d00fd985b813fdf) /* 312 */, U64_C(0x51286efcb774cd06) /* 313 */,
+ U64_C(0x5e8834471fa744af) /* 314 */, U64_C(0xf72ca0aee761ae2e) /* 315 */,
+ U64_C(0xbe40e4cdaee8e09a) /* 316 */, U64_C(0xe9970bbb5118f665) /* 317 */,
+ U64_C(0x726e4beb33df1964) /* 318 */, U64_C(0x703b000729199762) /* 319 */,
+ U64_C(0x4631d816f5ef30a7) /* 320 */, U64_C(0xb880b5b51504a6be) /* 321 */,
+ U64_C(0x641793c37ed84b6c) /* 322 */, U64_C(0x7b21ed77f6e97d96) /* 323 */,
+ U64_C(0x776306312ef96b73) /* 324 */, U64_C(0xae528948e86ff3f4) /* 325 */,
+ U64_C(0x53dbd7f286a3f8f8) /* 326 */, U64_C(0x16cadce74cfc1063) /* 327 */,
+ U64_C(0x005c19bdfa52c6dd) /* 328 */, U64_C(0x68868f5d64d46ad3) /* 329 */,
+ U64_C(0x3a9d512ccf1e186a) /* 330 */, U64_C(0x367e62c2385660ae) /* 331 */,
+ U64_C(0xe359e7ea77dcb1d7) /* 332 */, U64_C(0x526c0773749abe6e) /* 333 */,
+ U64_C(0x735ae5f9d09f734b) /* 334 */, U64_C(0x493fc7cc8a558ba8) /* 335 */,
+ U64_C(0xb0b9c1533041ab45) /* 336 */, U64_C(0x321958ba470a59bd) /* 337 */,
+ U64_C(0x852db00b5f46c393) /* 338 */, U64_C(0x91209b2bd336b0e5) /* 339 */,
+ U64_C(0x6e604f7d659ef19f) /* 340 */, U64_C(0xb99a8ae2782ccb24) /* 341 */,
+ U64_C(0xccf52ab6c814c4c7) /* 342 */, U64_C(0x4727d9afbe11727b) /* 343 */,
+ U64_C(0x7e950d0c0121b34d) /* 344 */, U64_C(0x756f435670ad471f) /* 345 */,
+ U64_C(0xf5add442615a6849) /* 346 */, U64_C(0x4e87e09980b9957a) /* 347 */,
+ U64_C(0x2acfa1df50aee355) /* 348 */, U64_C(0xd898263afd2fd556) /* 349 */,
+ U64_C(0xc8f4924dd80c8fd6) /* 350 */, U64_C(0xcf99ca3d754a173a) /* 351 */,
+ U64_C(0xfe477bacaf91bf3c) /* 352 */, U64_C(0xed5371f6d690c12d) /* 353 */,
+ U64_C(0x831a5c285e687094) /* 354 */, U64_C(0xc5d3c90a3708a0a4) /* 355 */,
+ U64_C(0x0f7f903717d06580) /* 356 */, U64_C(0x19f9bb13b8fdf27f) /* 357 */,
+ U64_C(0xb1bd6f1b4d502843) /* 358 */, U64_C(0x1c761ba38fff4012) /* 359 */,
+ U64_C(0x0d1530c4e2e21f3b) /* 360 */, U64_C(0x8943ce69a7372c8a) /* 361 */,
+ U64_C(0xe5184e11feb5ce66) /* 362 */, U64_C(0x618bdb80bd736621) /* 363 */,
+ U64_C(0x7d29bad68b574d0b) /* 364 */, U64_C(0x81bb613e25e6fe5b) /* 365 */,
+ U64_C(0x071c9c10bc07913f) /* 366 */, U64_C(0xc7beeb7909ac2d97) /* 367 */,
+ U64_C(0xc3e58d353bc5d757) /* 368 */, U64_C(0xeb017892f38f61e8) /* 369 */,
+ U64_C(0xd4effb9c9b1cc21a) /* 370 */, U64_C(0x99727d26f494f7ab) /* 371 */,
+ U64_C(0xa3e063a2956b3e03) /* 372 */, U64_C(0x9d4a8b9a4aa09c30) /* 373 */,
+ U64_C(0x3f6ab7d500090fb4) /* 374 */, U64_C(0x9cc0f2a057268ac0) /* 375 */,
+ U64_C(0x3dee9d2dedbf42d1) /* 376 */, U64_C(0x330f49c87960a972) /* 377 */,
+ U64_C(0xc6b2720287421b41) /* 378 */, U64_C(0x0ac59ec07c00369c) /* 379 */,
+ U64_C(0xef4eac49cb353425) /* 380 */, U64_C(0xf450244eef0129d8) /* 381 */,
+ U64_C(0x8acc46e5caf4deb6) /* 382 */, U64_C(0x2ffeab63989263f7) /* 383 */,
+ U64_C(0x8f7cb9fe5d7a4578) /* 384 */, U64_C(0x5bd8f7644e634635) /* 385 */,
+ U64_C(0x427a7315bf2dc900) /* 386 */, U64_C(0x17d0c4aa2125261c) /* 387 */,
+ U64_C(0x3992486c93518e50) /* 388 */, U64_C(0xb4cbfee0a2d7d4c3) /* 389 */,
+ U64_C(0x7c75d6202c5ddd8d) /* 390 */, U64_C(0xdbc295d8e35b6c61) /* 391 */,
+ U64_C(0x60b369d302032b19) /* 392 */, U64_C(0xce42685fdce44132) /* 393 */,
+ U64_C(0x06f3ddb9ddf65610) /* 394 */, U64_C(0x8ea4d21db5e148f0) /* 395 */,
+ U64_C(0x20b0fce62fcd496f) /* 396 */, U64_C(0x2c1b912358b0ee31) /* 397 */,
+ U64_C(0xb28317b818f5a308) /* 398 */, U64_C(0xa89c1e189ca6d2cf) /* 399 */,
+ U64_C(0x0c6b18576aaadbc8) /* 400 */, U64_C(0xb65deaa91299fae3) /* 401 */,
+ U64_C(0xfb2b794b7f1027e7) /* 402 */, U64_C(0x04e4317f443b5beb) /* 403 */,
+ U64_C(0x4b852d325939d0a6) /* 404 */, U64_C(0xd5ae6beefb207ffc) /* 405 */,
+ U64_C(0x309682b281c7d374) /* 406 */, U64_C(0xbae309a194c3b475) /* 407 */,
+ U64_C(0x8cc3f97b13b49f05) /* 408 */, U64_C(0x98a9422ff8293967) /* 409 */,
+ U64_C(0x244b16b01076ff7c) /* 410 */, U64_C(0xf8bf571c663d67ee) /* 411 */,
+ U64_C(0x1f0d6758eee30da1) /* 412 */, U64_C(0xc9b611d97adeb9b7) /* 413 */,
+ U64_C(0xb7afd5887b6c57a2) /* 414 */, U64_C(0x6290ae846b984fe1) /* 415 */,
+ U64_C(0x94df4cdeacc1a5fd) /* 416 */, U64_C(0x058a5bd1c5483aff) /* 417 */,
+ U64_C(0x63166cc142ba3c37) /* 418 */, U64_C(0x8db8526eb2f76f40) /* 419 */,
+ U64_C(0xe10880036f0d6d4e) /* 420 */, U64_C(0x9e0523c9971d311d) /* 421 */,
+ U64_C(0x45ec2824cc7cd691) /* 422 */, U64_C(0x575b8359e62382c9) /* 423 */,
+ U64_C(0xfa9e400dc4889995) /* 424 */, U64_C(0xd1823ecb45721568) /* 425 */,
+ U64_C(0xdafd983b8206082f) /* 426 */, U64_C(0xaa7d29082386a8cb) /* 427 */,
+ U64_C(0x269fcd4403b87588) /* 428 */, U64_C(0x1b91f5f728bdd1e0) /* 429 */,
+ U64_C(0xe4669f39040201f6) /* 430 */, U64_C(0x7a1d7c218cf04ade) /* 431 */,
+ U64_C(0x65623c29d79ce5ce) /* 432 */, U64_C(0x2368449096c00bb1) /* 433 */,
+ U64_C(0xab9bf1879da503ba) /* 434 */, U64_C(0xbc23ecb1a458058e) /* 435 */,
+ U64_C(0x9a58df01bb401ecc) /* 436 */, U64_C(0xa070e868a85f143d) /* 437 */,
+ U64_C(0x4ff188307df2239e) /* 438 */, U64_C(0x14d565b41a641183) /* 439 */,
+ U64_C(0xee13337452701602) /* 440 */, U64_C(0x950e3dcf3f285e09) /* 441 */,
+ U64_C(0x59930254b9c80953) /* 442 */, U64_C(0x3bf299408930da6d) /* 443 */,
+ U64_C(0xa955943f53691387) /* 444 */, U64_C(0xa15edecaa9cb8784) /* 445 */,
+ U64_C(0x29142127352be9a0) /* 446 */, U64_C(0x76f0371fff4e7afb) /* 447 */,
+ U64_C(0x0239f450274f2228) /* 448 */, U64_C(0xbb073af01d5e868b) /* 449 */,
+ U64_C(0xbfc80571c10e96c1) /* 450 */, U64_C(0xd267088568222e23) /* 451 */,
+ U64_C(0x9671a3d48e80b5b0) /* 452 */, U64_C(0x55b5d38ae193bb81) /* 453 */,
+ U64_C(0x693ae2d0a18b04b8) /* 454 */, U64_C(0x5c48b4ecadd5335f) /* 455 */,
+ U64_C(0xfd743b194916a1ca) /* 456 */, U64_C(0x2577018134be98c4) /* 457 */,
+ U64_C(0xe77987e83c54a4ad) /* 458 */, U64_C(0x28e11014da33e1b9) /* 459 */,
+ U64_C(0x270cc59e226aa213) /* 460 */, U64_C(0x71495f756d1a5f60) /* 461 */,
+ U64_C(0x9be853fb60afef77) /* 462 */, U64_C(0xadc786a7f7443dbf) /* 463 */,
+ U64_C(0x0904456173b29a82) /* 464 */, U64_C(0x58bc7a66c232bd5e) /* 465 */,
+ U64_C(0xf306558c673ac8b2) /* 466 */, U64_C(0x41f639c6b6c9772a) /* 467 */,
+ U64_C(0x216defe99fda35da) /* 468 */, U64_C(0x11640cc71c7be615) /* 469 */,
+ U64_C(0x93c43694565c5527) /* 470 */, U64_C(0xea038e6246777839) /* 471 */,
+ U64_C(0xf9abf3ce5a3e2469) /* 472 */, U64_C(0x741e768d0fd312d2) /* 473 */,
+ U64_C(0x0144b883ced652c6) /* 474 */, U64_C(0xc20b5a5ba33f8552) /* 475 */,
+ U64_C(0x1ae69633c3435a9d) /* 476 */, U64_C(0x97a28ca4088cfdec) /* 477 */,
+ U64_C(0x8824a43c1e96f420) /* 478 */, U64_C(0x37612fa66eeea746) /* 479 */,
+ U64_C(0x6b4cb165f9cf0e5a) /* 480 */, U64_C(0x43aa1c06a0abfb4a) /* 481 */,
+ U64_C(0x7f4dc26ff162796b) /* 482 */, U64_C(0x6cbacc8e54ed9b0f) /* 483 */,
+ U64_C(0xa6b7ffefd2bb253e) /* 484 */, U64_C(0x2e25bc95b0a29d4f) /* 485 */,
+ U64_C(0x86d6a58bdef1388c) /* 486 */, U64_C(0xded74ac576b6f054) /* 487 */,
+ U64_C(0x8030bdbc2b45805d) /* 488 */, U64_C(0x3c81af70e94d9289) /* 489 */,
+ U64_C(0x3eff6dda9e3100db) /* 490 */, U64_C(0xb38dc39fdfcc8847) /* 491 */,
+ U64_C(0x123885528d17b87e) /* 492 */, U64_C(0xf2da0ed240b1b642) /* 493 */,
+ U64_C(0x44cefadcd54bf9a9) /* 494 */, U64_C(0x1312200e433c7ee6) /* 495 */,
+ U64_C(0x9ffcc84f3a78c748) /* 496 */, U64_C(0xf0cd1f72248576bb) /* 497 */,
+ U64_C(0xec6974053638cfe4) /* 498 */, U64_C(0x2ba7b67c0cec4e4c) /* 499 */,
+ U64_C(0xac2f4df3e5ce32ed) /* 500 */, U64_C(0xcb33d14326ea4c11) /* 501 */,
+ U64_C(0xa4e9044cc77e58bc) /* 502 */, U64_C(0x5f513293d934fcef) /* 503 */,
+ U64_C(0x5dc9645506e55444) /* 504 */, U64_C(0x50de418f317de40a) /* 505 */,
+ U64_C(0x388cb31a69dde259) /* 506 */, U64_C(0x2db4a83455820a86) /* 507 */,
+ U64_C(0x9010a91e84711ae9) /* 508 */, U64_C(0x4df7f0b7b1498371) /* 509 */,
+ U64_C(0xd62a2eabc0977179) /* 510 */, U64_C(0x22fac097aa8d5c0e) /* 511 */
+};
+static u64 sbox3[256] = {
+ U64_C(0xf49fcc2ff1daf39b) /* 512 */, U64_C(0x487fd5c66ff29281) /* 513 */,
+ U64_C(0xe8a30667fcdca83f) /* 514 */, U64_C(0x2c9b4be3d2fcce63) /* 515 */,
+ U64_C(0xda3ff74b93fbbbc2) /* 516 */, U64_C(0x2fa165d2fe70ba66) /* 517 */,
+ U64_C(0xa103e279970e93d4) /* 518 */, U64_C(0xbecdec77b0e45e71) /* 519 */,
+ U64_C(0xcfb41e723985e497) /* 520 */, U64_C(0xb70aaa025ef75017) /* 521 */,
+ U64_C(0xd42309f03840b8e0) /* 522 */, U64_C(0x8efc1ad035898579) /* 523 */,
+ U64_C(0x96c6920be2b2abc5) /* 524 */, U64_C(0x66af4163375a9172) /* 525 */,
+ U64_C(0x2174abdcca7127fb) /* 526 */, U64_C(0xb33ccea64a72ff41) /* 527 */,
+ U64_C(0xf04a4933083066a5) /* 528 */, U64_C(0x8d970acdd7289af5) /* 529 */,
+ U64_C(0x8f96e8e031c8c25e) /* 530 */, U64_C(0xf3fec02276875d47) /* 531 */,
+ U64_C(0xec7bf310056190dd) /* 532 */, U64_C(0xf5adb0aebb0f1491) /* 533 */,
+ U64_C(0x9b50f8850fd58892) /* 534 */, U64_C(0x4975488358b74de8) /* 535 */,
+ U64_C(0xa3354ff691531c61) /* 536 */, U64_C(0x0702bbe481d2c6ee) /* 537 */,
+ U64_C(0x89fb24057deded98) /* 538 */, U64_C(0xac3075138596e902) /* 539 */,
+ U64_C(0x1d2d3580172772ed) /* 540 */, U64_C(0xeb738fc28e6bc30d) /* 541 */,
+ U64_C(0x5854ef8f63044326) /* 542 */, U64_C(0x9e5c52325add3bbe) /* 543 */,
+ U64_C(0x90aa53cf325c4623) /* 544 */, U64_C(0xc1d24d51349dd067) /* 545 */,
+ U64_C(0x2051cfeea69ea624) /* 546 */, U64_C(0x13220f0a862e7e4f) /* 547 */,
+ U64_C(0xce39399404e04864) /* 548 */, U64_C(0xd9c42ca47086fcb7) /* 549 */,
+ U64_C(0x685ad2238a03e7cc) /* 550 */, U64_C(0x066484b2ab2ff1db) /* 551 */,
+ U64_C(0xfe9d5d70efbf79ec) /* 552 */, U64_C(0x5b13b9dd9c481854) /* 553 */,
+ U64_C(0x15f0d475ed1509ad) /* 554 */, U64_C(0x0bebcd060ec79851) /* 555 */,
+ U64_C(0xd58c6791183ab7f8) /* 556 */, U64_C(0xd1187c5052f3eee4) /* 557 */,
+ U64_C(0xc95d1192e54e82ff) /* 558 */, U64_C(0x86eea14cb9ac6ca2) /* 559 */,
+ U64_C(0x3485beb153677d5d) /* 560 */, U64_C(0xdd191d781f8c492a) /* 561 */,
+ U64_C(0xf60866baa784ebf9) /* 562 */, U64_C(0x518f643ba2d08c74) /* 563 */,
+ U64_C(0x8852e956e1087c22) /* 564 */, U64_C(0xa768cb8dc410ae8d) /* 565 */,
+ U64_C(0x38047726bfec8e1a) /* 566 */, U64_C(0xa67738b4cd3b45aa) /* 567 */,
+ U64_C(0xad16691cec0dde19) /* 568 */, U64_C(0xc6d4319380462e07) /* 569 */,
+ U64_C(0xc5a5876d0ba61938) /* 570 */, U64_C(0x16b9fa1fa58fd840) /* 571 */,
+ U64_C(0x188ab1173ca74f18) /* 572 */, U64_C(0xabda2f98c99c021f) /* 573 */,
+ U64_C(0x3e0580ab134ae816) /* 574 */, U64_C(0x5f3b05b773645abb) /* 575 */,
+ U64_C(0x2501a2be5575f2f6) /* 576 */, U64_C(0x1b2f74004e7e8ba9) /* 577 */,
+ U64_C(0x1cd7580371e8d953) /* 578 */, U64_C(0x7f6ed89562764e30) /* 579 */,
+ U64_C(0xb15926ff596f003d) /* 580 */, U64_C(0x9f65293da8c5d6b9) /* 581 */,
+ U64_C(0x6ecef04dd690f84c) /* 582 */, U64_C(0x4782275fff33af88) /* 583 */,
+ U64_C(0xe41433083f820801) /* 584 */, U64_C(0xfd0dfe409a1af9b5) /* 585 */,
+ U64_C(0x4325a3342cdb396b) /* 586 */, U64_C(0x8ae77e62b301b252) /* 587 */,
+ U64_C(0xc36f9e9f6655615a) /* 588 */, U64_C(0x85455a2d92d32c09) /* 589 */,
+ U64_C(0xf2c7dea949477485) /* 590 */, U64_C(0x63cfb4c133a39eba) /* 591 */,
+ U64_C(0x83b040cc6ebc5462) /* 592 */, U64_C(0x3b9454c8fdb326b0) /* 593 */,
+ U64_C(0x56f56a9e87ffd78c) /* 594 */, U64_C(0x2dc2940d99f42bc6) /* 595 */,
+ U64_C(0x98f7df096b096e2d) /* 596 */, U64_C(0x19a6e01e3ad852bf) /* 597 */,
+ U64_C(0x42a99ccbdbd4b40b) /* 598 */, U64_C(0xa59998af45e9c559) /* 599 */,
+ U64_C(0x366295e807d93186) /* 600 */, U64_C(0x6b48181bfaa1f773) /* 601 */,
+ U64_C(0x1fec57e2157a0a1d) /* 602 */, U64_C(0x4667446af6201ad5) /* 603 */,
+ U64_C(0xe615ebcacfb0f075) /* 604 */, U64_C(0xb8f31f4f68290778) /* 605 */,
+ U64_C(0x22713ed6ce22d11e) /* 606 */, U64_C(0x3057c1a72ec3c93b) /* 607 */,
+ U64_C(0xcb46acc37c3f1f2f) /* 608 */, U64_C(0xdbb893fd02aaf50e) /* 609 */,
+ U64_C(0x331fd92e600b9fcf) /* 610 */, U64_C(0xa498f96148ea3ad6) /* 611 */,
+ U64_C(0xa8d8426e8b6a83ea) /* 612 */, U64_C(0xa089b274b7735cdc) /* 613 */,
+ U64_C(0x87f6b3731e524a11) /* 614 */, U64_C(0x118808e5cbc96749) /* 615 */,
+ U64_C(0x9906e4c7b19bd394) /* 616 */, U64_C(0xafed7f7e9b24a20c) /* 617 */,
+ U64_C(0x6509eadeeb3644a7) /* 618 */, U64_C(0x6c1ef1d3e8ef0ede) /* 619 */,
+ U64_C(0xb9c97d43e9798fb4) /* 620 */, U64_C(0xa2f2d784740c28a3) /* 621 */,
+ U64_C(0x7b8496476197566f) /* 622 */, U64_C(0x7a5be3e6b65f069d) /* 623 */,
+ U64_C(0xf96330ed78be6f10) /* 624 */, U64_C(0xeee60de77a076a15) /* 625 */,
+ U64_C(0x2b4bee4aa08b9bd0) /* 626 */, U64_C(0x6a56a63ec7b8894e) /* 627 */,
+ U64_C(0x02121359ba34fef4) /* 628 */, U64_C(0x4cbf99f8283703fc) /* 629 */,
+ U64_C(0x398071350caf30c8) /* 630 */, U64_C(0xd0a77a89f017687a) /* 631 */,
+ U64_C(0xf1c1a9eb9e423569) /* 632 */, U64_C(0x8c7976282dee8199) /* 633 */,
+ U64_C(0x5d1737a5dd1f7abd) /* 634 */, U64_C(0x4f53433c09a9fa80) /* 635 */,
+ U64_C(0xfa8b0c53df7ca1d9) /* 636 */, U64_C(0x3fd9dcbc886ccb77) /* 637 */,
+ U64_C(0xc040917ca91b4720) /* 638 */, U64_C(0x7dd00142f9d1dcdf) /* 639 */,
+ U64_C(0x8476fc1d4f387b58) /* 640 */, U64_C(0x23f8e7c5f3316503) /* 641 */,
+ U64_C(0x032a2244e7e37339) /* 642 */, U64_C(0x5c87a5d750f5a74b) /* 643 */,
+ U64_C(0x082b4cc43698992e) /* 644 */, U64_C(0xdf917becb858f63c) /* 645 */,
+ U64_C(0x3270b8fc5bf86dda) /* 646 */, U64_C(0x10ae72bb29b5dd76) /* 647 */,
+ U64_C(0x576ac94e7700362b) /* 648 */, U64_C(0x1ad112dac61efb8f) /* 649 */,
+ U64_C(0x691bc30ec5faa427) /* 650 */, U64_C(0xff246311cc327143) /* 651 */,
+ U64_C(0x3142368e30e53206) /* 652 */, U64_C(0x71380e31e02ca396) /* 653 */,
+ U64_C(0x958d5c960aad76f1) /* 654 */, U64_C(0xf8d6f430c16da536) /* 655 */,
+ U64_C(0xc8ffd13f1be7e1d2) /* 656 */, U64_C(0x7578ae66004ddbe1) /* 657 */,
+ U64_C(0x05833f01067be646) /* 658 */, U64_C(0xbb34b5ad3bfe586d) /* 659 */,
+ U64_C(0x095f34c9a12b97f0) /* 660 */, U64_C(0x247ab64525d60ca8) /* 661 */,
+ U64_C(0xdcdbc6f3017477d1) /* 662 */, U64_C(0x4a2e14d4decad24d) /* 663 */,
+ U64_C(0xbdb5e6d9be0a1eeb) /* 664 */, U64_C(0x2a7e70f7794301ab) /* 665 */,
+ U64_C(0xdef42d8a270540fd) /* 666 */, U64_C(0x01078ec0a34c22c1) /* 667 */,
+ U64_C(0xe5de511af4c16387) /* 668 */, U64_C(0x7ebb3a52bd9a330a) /* 669 */,
+ U64_C(0x77697857aa7d6435) /* 670 */, U64_C(0x004e831603ae4c32) /* 671 */,
+ U64_C(0xe7a21020ad78e312) /* 672 */, U64_C(0x9d41a70c6ab420f2) /* 673 */,
+ U64_C(0x28e06c18ea1141e6) /* 674 */, U64_C(0xd2b28cbd984f6b28) /* 675 */,
+ U64_C(0x26b75f6c446e9d83) /* 676 */, U64_C(0xba47568c4d418d7f) /* 677 */,
+ U64_C(0xd80badbfe6183d8e) /* 678 */, U64_C(0x0e206d7f5f166044) /* 679 */,
+ U64_C(0xe258a43911cbca3e) /* 680 */, U64_C(0x723a1746b21dc0bc) /* 681 */,
+ U64_C(0xc7caa854f5d7cdd3) /* 682 */, U64_C(0x7cac32883d261d9c) /* 683 */,
+ U64_C(0x7690c26423ba942c) /* 684 */, U64_C(0x17e55524478042b8) /* 685 */,
+ U64_C(0xe0be477656a2389f) /* 686 */, U64_C(0x4d289b5e67ab2da0) /* 687 */,
+ U64_C(0x44862b9c8fbbfd31) /* 688 */, U64_C(0xb47cc8049d141365) /* 689 */,
+ U64_C(0x822c1b362b91c793) /* 690 */, U64_C(0x4eb14655fb13dfd8) /* 691 */,
+ U64_C(0x1ecbba0714e2a97b) /* 692 */, U64_C(0x6143459d5cde5f14) /* 693 */,
+ U64_C(0x53a8fbf1d5f0ac89) /* 694 */, U64_C(0x97ea04d81c5e5b00) /* 695 */,
+ U64_C(0x622181a8d4fdb3f3) /* 696 */, U64_C(0xe9bcd341572a1208) /* 697 */,
+ U64_C(0x1411258643cce58a) /* 698 */, U64_C(0x9144c5fea4c6e0a4) /* 699 */,
+ U64_C(0x0d33d06565cf620f) /* 700 */, U64_C(0x54a48d489f219ca1) /* 701 */,
+ U64_C(0xc43e5eac6d63c821) /* 702 */, U64_C(0xa9728b3a72770daf) /* 703 */,
+ U64_C(0xd7934e7b20df87ef) /* 704 */, U64_C(0xe35503b61a3e86e5) /* 705 */,
+ U64_C(0xcae321fbc819d504) /* 706 */, U64_C(0x129a50b3ac60bfa6) /* 707 */,
+ U64_C(0xcd5e68ea7e9fb6c3) /* 708 */, U64_C(0xb01c90199483b1c7) /* 709 */,
+ U64_C(0x3de93cd5c295376c) /* 710 */, U64_C(0xaed52edf2ab9ad13) /* 711 */,
+ U64_C(0x2e60f512c0a07884) /* 712 */, U64_C(0xbc3d86a3e36210c9) /* 713 */,
+ U64_C(0x35269d9b163951ce) /* 714 */, U64_C(0x0c7d6e2ad0cdb5fa) /* 715 */,
+ U64_C(0x59e86297d87f5733) /* 716 */, U64_C(0x298ef221898db0e7) /* 717 */,
+ U64_C(0x55000029d1a5aa7e) /* 718 */, U64_C(0x8bc08ae1b5061b45) /* 719 */,
+ U64_C(0xc2c31c2b6c92703a) /* 720 */, U64_C(0x94cc596baf25ef42) /* 721 */,
+ U64_C(0x0a1d73db22540456) /* 722 */, U64_C(0x04b6a0f9d9c4179a) /* 723 */,
+ U64_C(0xeffdafa2ae3d3c60) /* 724 */, U64_C(0xf7c8075bb49496c4) /* 725 */,
+ U64_C(0x9cc5c7141d1cd4e3) /* 726 */, U64_C(0x78bd1638218e5534) /* 727 */,
+ U64_C(0xb2f11568f850246a) /* 728 */, U64_C(0xedfabcfa9502bc29) /* 729 */,
+ U64_C(0x796ce5f2da23051b) /* 730 */, U64_C(0xaae128b0dc93537c) /* 731 */,
+ U64_C(0x3a493da0ee4b29ae) /* 732 */, U64_C(0xb5df6b2c416895d7) /* 733 */,
+ U64_C(0xfcabbd25122d7f37) /* 734 */, U64_C(0x70810b58105dc4b1) /* 735 */,
+ U64_C(0xe10fdd37f7882a90) /* 736 */, U64_C(0x524dcab5518a3f5c) /* 737 */,
+ U64_C(0x3c9e85878451255b) /* 738 */, U64_C(0x4029828119bd34e2) /* 739 */,
+ U64_C(0x74a05b6f5d3ceccb) /* 740 */, U64_C(0xb610021542e13eca) /* 741 */,
+ U64_C(0x0ff979d12f59e2ac) /* 742 */, U64_C(0x6037da27e4f9cc50) /* 743 */,
+ U64_C(0x5e92975a0df1847d) /* 744 */, U64_C(0xd66de190d3e623fe) /* 745 */,
+ U64_C(0x5032d6b87b568048) /* 746 */, U64_C(0x9a36b7ce8235216e) /* 747 */,
+ U64_C(0x80272a7a24f64b4a) /* 748 */, U64_C(0x93efed8b8c6916f7) /* 749 */,
+ U64_C(0x37ddbff44cce1555) /* 750 */, U64_C(0x4b95db5d4b99bd25) /* 751 */,
+ U64_C(0x92d3fda169812fc0) /* 752 */, U64_C(0xfb1a4a9a90660bb6) /* 753 */,
+ U64_C(0x730c196946a4b9b2) /* 754 */, U64_C(0x81e289aa7f49da68) /* 755 */,
+ U64_C(0x64669a0f83b1a05f) /* 756 */, U64_C(0x27b3ff7d9644f48b) /* 757 */,
+ U64_C(0xcc6b615c8db675b3) /* 758 */, U64_C(0x674f20b9bcebbe95) /* 759 */,
+ U64_C(0x6f31238275655982) /* 760 */, U64_C(0x5ae488713e45cf05) /* 761 */,
+ U64_C(0xbf619f9954c21157) /* 762 */, U64_C(0xeabac46040a8eae9) /* 763 */,
+ U64_C(0x454c6fe9f2c0c1cd) /* 764 */, U64_C(0x419cf6496412691c) /* 765 */,
+ U64_C(0xd3dc3bef265b0f70) /* 766 */, U64_C(0x6d0e60f5c3578a9e) /* 767 */
+};
+static u64 sbox4[256] = {
+ U64_C(0x5b0e608526323c55) /* 768 */, U64_C(0x1a46c1a9fa1b59f5) /* 769 */,
+ U64_C(0xa9e245a17c4c8ffa) /* 770 */, U64_C(0x65ca5159db2955d7) /* 771 */,
+ U64_C(0x05db0a76ce35afc2) /* 772 */, U64_C(0x81eac77ea9113d45) /* 773 */,
+ U64_C(0x528ef88ab6ac0a0d) /* 774 */, U64_C(0xa09ea253597be3ff) /* 775 */,
+ U64_C(0x430ddfb3ac48cd56) /* 776 */, U64_C(0xc4b3a67af45ce46f) /* 777 */,
+ U64_C(0x4ececfd8fbe2d05e) /* 778 */, U64_C(0x3ef56f10b39935f0) /* 779 */,
+ U64_C(0x0b22d6829cd619c6) /* 780 */, U64_C(0x17fd460a74df2069) /* 781 */,
+ U64_C(0x6cf8cc8e8510ed40) /* 782 */, U64_C(0xd6c824bf3a6ecaa7) /* 783 */,
+ U64_C(0x61243d581a817049) /* 784 */, U64_C(0x048bacb6bbc163a2) /* 785 */,
+ U64_C(0xd9a38ac27d44cc32) /* 786 */, U64_C(0x7fddff5baaf410ab) /* 787 */,
+ U64_C(0xad6d495aa804824b) /* 788 */, U64_C(0xe1a6a74f2d8c9f94) /* 789 */,
+ U64_C(0xd4f7851235dee8e3) /* 790 */, U64_C(0xfd4b7f886540d893) /* 791 */,
+ U64_C(0x247c20042aa4bfda) /* 792 */, U64_C(0x096ea1c517d1327c) /* 793 */,
+ U64_C(0xd56966b4361a6685) /* 794 */, U64_C(0x277da5c31221057d) /* 795 */,
+ U64_C(0x94d59893a43acff7) /* 796 */, U64_C(0x64f0c51ccdc02281) /* 797 */,
+ U64_C(0x3d33bcc4ff6189db) /* 798 */, U64_C(0xe005cb184ce66af1) /* 799 */,
+ U64_C(0xff5ccd1d1db99bea) /* 800 */, U64_C(0xb0b854a7fe42980f) /* 801 */,
+ U64_C(0x7bd46a6a718d4b9f) /* 802 */, U64_C(0xd10fa8cc22a5fd8c) /* 803 */,
+ U64_C(0xd31484952be4bd31) /* 804 */, U64_C(0xc7fa975fcb243847) /* 805 */,
+ U64_C(0x4886ed1e5846c407) /* 806 */, U64_C(0x28cddb791eb70b04) /* 807 */,
+ U64_C(0xc2b00be2f573417f) /* 808 */, U64_C(0x5c9590452180f877) /* 809 */,
+ U64_C(0x7a6bddfff370eb00) /* 810 */, U64_C(0xce509e38d6d9d6a4) /* 811 */,
+ U64_C(0xebeb0f00647fa702) /* 812 */, U64_C(0x1dcc06cf76606f06) /* 813 */,
+ U64_C(0xe4d9f28ba286ff0a) /* 814 */, U64_C(0xd85a305dc918c262) /* 815 */,
+ U64_C(0x475b1d8732225f54) /* 816 */, U64_C(0x2d4fb51668ccb5fe) /* 817 */,
+ U64_C(0xa679b9d9d72bba20) /* 818 */, U64_C(0x53841c0d912d43a5) /* 819 */,
+ U64_C(0x3b7eaa48bf12a4e8) /* 820 */, U64_C(0x781e0e47f22f1ddf) /* 821 */,
+ U64_C(0xeff20ce60ab50973) /* 822 */, U64_C(0x20d261d19dffb742) /* 823 */,
+ U64_C(0x16a12b03062a2e39) /* 824 */, U64_C(0x1960eb2239650495) /* 825 */,
+ U64_C(0x251c16fed50eb8b8) /* 826 */, U64_C(0x9ac0c330f826016e) /* 827 */,
+ U64_C(0xed152665953e7671) /* 828 */, U64_C(0x02d63194a6369570) /* 829 */,
+ U64_C(0x5074f08394b1c987) /* 830 */, U64_C(0x70ba598c90b25ce1) /* 831 */,
+ U64_C(0x794a15810b9742f6) /* 832 */, U64_C(0x0d5925e9fcaf8c6c) /* 833 */,
+ U64_C(0x3067716cd868744e) /* 834 */, U64_C(0x910ab077e8d7731b) /* 835 */,
+ U64_C(0x6a61bbdb5ac42f61) /* 836 */, U64_C(0x93513efbf0851567) /* 837 */,
+ U64_C(0xf494724b9e83e9d5) /* 838 */, U64_C(0xe887e1985c09648d) /* 839 */,
+ U64_C(0x34b1d3c675370cfd) /* 840 */, U64_C(0xdc35e433bc0d255d) /* 841 */,
+ U64_C(0xd0aab84234131be0) /* 842 */, U64_C(0x08042a50b48b7eaf) /* 843 */,
+ U64_C(0x9997c4ee44a3ab35) /* 844 */, U64_C(0x829a7b49201799d0) /* 845 */,
+ U64_C(0x263b8307b7c54441) /* 846 */, U64_C(0x752f95f4fd6a6ca6) /* 847 */,
+ U64_C(0x927217402c08c6e5) /* 848 */, U64_C(0x2a8ab754a795d9ee) /* 849 */,
+ U64_C(0xa442f7552f72943d) /* 850 */, U64_C(0x2c31334e19781208) /* 851 */,
+ U64_C(0x4fa98d7ceaee6291) /* 852 */, U64_C(0x55c3862f665db309) /* 853 */,
+ U64_C(0xbd0610175d53b1f3) /* 854 */, U64_C(0x46fe6cb840413f27) /* 855 */,
+ U64_C(0x3fe03792df0cfa59) /* 856 */, U64_C(0xcfe700372eb85e8f) /* 857 */,
+ U64_C(0xa7be29e7adbce118) /* 858 */, U64_C(0xe544ee5cde8431dd) /* 859 */,
+ U64_C(0x8a781b1b41f1873e) /* 860 */, U64_C(0xa5c94c78a0d2f0e7) /* 861 */,
+ U64_C(0x39412e2877b60728) /* 862 */, U64_C(0xa1265ef3afc9a62c) /* 863 */,
+ U64_C(0xbcc2770c6a2506c5) /* 864 */, U64_C(0x3ab66dd5dce1ce12) /* 865 */,
+ U64_C(0xe65499d04a675b37) /* 866 */, U64_C(0x7d8f523481bfd216) /* 867 */,
+ U64_C(0x0f6f64fcec15f389) /* 868 */, U64_C(0x74efbe618b5b13c8) /* 869 */,
+ U64_C(0xacdc82b714273e1d) /* 870 */, U64_C(0xdd40bfe003199d17) /* 871 */,
+ U64_C(0x37e99257e7e061f8) /* 872 */, U64_C(0xfa52626904775aaa) /* 873 */,
+ U64_C(0x8bbbf63a463d56f9) /* 874 */, U64_C(0xf0013f1543a26e64) /* 875 */,
+ U64_C(0xa8307e9f879ec898) /* 876 */, U64_C(0xcc4c27a4150177cc) /* 877 */,
+ U64_C(0x1b432f2cca1d3348) /* 878 */, U64_C(0xde1d1f8f9f6fa013) /* 879 */,
+ U64_C(0x606602a047a7ddd6) /* 880 */, U64_C(0xd237ab64cc1cb2c7) /* 881 */,
+ U64_C(0x9b938e7225fcd1d3) /* 882 */, U64_C(0xec4e03708e0ff476) /* 883 */,
+ U64_C(0xfeb2fbda3d03c12d) /* 884 */, U64_C(0xae0bced2ee43889a) /* 885 */,
+ U64_C(0x22cb8923ebfb4f43) /* 886 */, U64_C(0x69360d013cf7396d) /* 887 */,
+ U64_C(0x855e3602d2d4e022) /* 888 */, U64_C(0x073805bad01f784c) /* 889 */,
+ U64_C(0x33e17a133852f546) /* 890 */, U64_C(0xdf4874058ac7b638) /* 891 */,
+ U64_C(0xba92b29c678aa14a) /* 892 */, U64_C(0x0ce89fc76cfaadcd) /* 893 */,
+ U64_C(0x5f9d4e0908339e34) /* 894 */, U64_C(0xf1afe9291f5923b9) /* 895 */,
+ U64_C(0x6e3480f60f4a265f) /* 896 */, U64_C(0xeebf3a2ab29b841c) /* 897 */,
+ U64_C(0xe21938a88f91b4ad) /* 898 */, U64_C(0x57dfeff845c6d3c3) /* 899 */,
+ U64_C(0x2f006b0bf62caaf2) /* 900 */, U64_C(0x62f479ef6f75ee78) /* 901 */,
+ U64_C(0x11a55ad41c8916a9) /* 902 */, U64_C(0xf229d29084fed453) /* 903 */,
+ U64_C(0x42f1c27b16b000e6) /* 904 */, U64_C(0x2b1f76749823c074) /* 905 */,
+ U64_C(0x4b76eca3c2745360) /* 906 */, U64_C(0x8c98f463b91691bd) /* 907 */,
+ U64_C(0x14bcc93cf1ade66a) /* 908 */, U64_C(0x8885213e6d458397) /* 909 */,
+ U64_C(0x8e177df0274d4711) /* 910 */, U64_C(0xb49b73b5503f2951) /* 911 */,
+ U64_C(0x10168168c3f96b6b) /* 912 */, U64_C(0x0e3d963b63cab0ae) /* 913 */,
+ U64_C(0x8dfc4b5655a1db14) /* 914 */, U64_C(0xf789f1356e14de5c) /* 915 */,
+ U64_C(0x683e68af4e51dac1) /* 916 */, U64_C(0xc9a84f9d8d4b0fd9) /* 917 */,
+ U64_C(0x3691e03f52a0f9d1) /* 918 */, U64_C(0x5ed86e46e1878e80) /* 919 */,
+ U64_C(0x3c711a0e99d07150) /* 920 */, U64_C(0x5a0865b20c4e9310) /* 921 */,
+ U64_C(0x56fbfc1fe4f0682e) /* 922 */, U64_C(0xea8d5de3105edf9b) /* 923 */,
+ U64_C(0x71abfdb12379187a) /* 924 */, U64_C(0x2eb99de1bee77b9c) /* 925 */,
+ U64_C(0x21ecc0ea33cf4523) /* 926 */, U64_C(0x59a4d7521805c7a1) /* 927 */,
+ U64_C(0x3896f5eb56ae7c72) /* 928 */, U64_C(0xaa638f3db18f75dc) /* 929 */,
+ U64_C(0x9f39358dabe9808e) /* 930 */, U64_C(0xb7defa91c00b72ac) /* 931 */,
+ U64_C(0x6b5541fd62492d92) /* 932 */, U64_C(0x6dc6dee8f92e4d5b) /* 933 */,
+ U64_C(0x353f57abc4beea7e) /* 934 */, U64_C(0x735769d6da5690ce) /* 935 */,
+ U64_C(0x0a234aa642391484) /* 936 */, U64_C(0xf6f9508028f80d9d) /* 937 */,
+ U64_C(0xb8e319a27ab3f215) /* 938 */, U64_C(0x31ad9c1151341a4d) /* 939 */,
+ U64_C(0x773c22a57bef5805) /* 940 */, U64_C(0x45c7561a07968633) /* 941 */,
+ U64_C(0xf913da9e249dbe36) /* 942 */, U64_C(0xda652d9b78a64c68) /* 943 */,
+ U64_C(0x4c27a97f3bc334ef) /* 944 */, U64_C(0x76621220e66b17f4) /* 945 */,
+ U64_C(0x967743899acd7d0b) /* 946 */, U64_C(0xf3ee5bcae0ed6782) /* 947 */,
+ U64_C(0x409f753600c879fc) /* 948 */, U64_C(0x06d09a39b5926db6) /* 949 */,
+ U64_C(0x6f83aeb0317ac588) /* 950 */, U64_C(0x01e6ca4a86381f21) /* 951 */,
+ U64_C(0x66ff3462d19f3025) /* 952 */, U64_C(0x72207c24ddfd3bfb) /* 953 */,
+ U64_C(0x4af6b6d3e2ece2eb) /* 954 */, U64_C(0x9c994dbec7ea08de) /* 955 */,
+ U64_C(0x49ace597b09a8bc4) /* 956 */, U64_C(0xb38c4766cf0797ba) /* 957 */,
+ U64_C(0x131b9373c57c2a75) /* 958 */, U64_C(0xb1822cce61931e58) /* 959 */,
+ U64_C(0x9d7555b909ba1c0c) /* 960 */, U64_C(0x127fafdd937d11d2) /* 961 */,
+ U64_C(0x29da3badc66d92e4) /* 962 */, U64_C(0xa2c1d57154c2ecbc) /* 963 */,
+ U64_C(0x58c5134d82f6fe24) /* 964 */, U64_C(0x1c3ae3515b62274f) /* 965 */,
+ U64_C(0xe907c82e01cb8126) /* 966 */, U64_C(0xf8ed091913e37fcb) /* 967 */,
+ U64_C(0x3249d8f9c80046c9) /* 968 */, U64_C(0x80cf9bede388fb63) /* 969 */,
+ U64_C(0x1881539a116cf19e) /* 970 */, U64_C(0x5103f3f76bd52457) /* 971 */,
+ U64_C(0x15b7e6f5ae47f7a8) /* 972 */, U64_C(0xdbd7c6ded47e9ccf) /* 973 */,
+ U64_C(0x44e55c410228bb1a) /* 974 */, U64_C(0xb647d4255edb4e99) /* 975 */,
+ U64_C(0x5d11882bb8aafc30) /* 976 */, U64_C(0xf5098bbb29d3212a) /* 977 */,
+ U64_C(0x8fb5ea14e90296b3) /* 978 */, U64_C(0x677b942157dd025a) /* 979 */,
+ U64_C(0xfb58e7c0a390acb5) /* 980 */, U64_C(0x89d3674c83bd4a01) /* 981 */,
+ U64_C(0x9e2da4df4bf3b93b) /* 982 */, U64_C(0xfcc41e328cab4829) /* 983 */,
+ U64_C(0x03f38c96ba582c52) /* 984 */, U64_C(0xcad1bdbd7fd85db2) /* 985 */,
+ U64_C(0xbbb442c16082ae83) /* 986 */, U64_C(0xb95fe86ba5da9ab0) /* 987 */,
+ U64_C(0xb22e04673771a93f) /* 988 */, U64_C(0x845358c9493152d8) /* 989 */,
+ U64_C(0xbe2a488697b4541e) /* 990 */, U64_C(0x95a2dc2dd38e6966) /* 991 */,
+ U64_C(0xc02c11ac923c852b) /* 992 */, U64_C(0x2388b1990df2a87b) /* 993 */,
+ U64_C(0x7c8008fa1b4f37be) /* 994 */, U64_C(0x1f70d0c84d54e503) /* 995 */,
+ U64_C(0x5490adec7ece57d4) /* 996 */, U64_C(0x002b3c27d9063a3a) /* 997 */,
+ U64_C(0x7eaea3848030a2bf) /* 998 */, U64_C(0xc602326ded2003c0) /* 999 */,
+ U64_C(0x83a7287d69a94086) /* 1000 */, U64_C(0xc57a5fcb30f57a8a) /* 1001 */,
+ U64_C(0xb56844e479ebe779) /* 1002 */, U64_C(0xa373b40f05dcbce9) /* 1003 */,
+ U64_C(0xd71a786e88570ee2) /* 1004 */, U64_C(0x879cbacdbde8f6a0) /* 1005 */,
+ U64_C(0x976ad1bcc164a32f) /* 1006 */, U64_C(0xab21e25e9666d78b) /* 1007 */,
+ U64_C(0x901063aae5e5c33c) /* 1008 */, U64_C(0x9818b34448698d90) /* 1009 */,
+ U64_C(0xe36487ae3e1e8abb) /* 1010 */, U64_C(0xafbdf931893bdcb4) /* 1011 */,
+ U64_C(0x6345a0dc5fbbd519) /* 1012 */, U64_C(0x8628fe269b9465ca) /* 1013 */,
+ U64_C(0x1e5d01603f9c51ec) /* 1014 */, U64_C(0x4de44006a15049b7) /* 1015 */,
+ U64_C(0xbf6c70e5f776cbb1) /* 1016 */, U64_C(0x411218f2ef552bed) /* 1017 */,
+ U64_C(0xcb0c0708705a36a3) /* 1018 */, U64_C(0xe74d14754f986044) /* 1019 */,
+ U64_C(0xcd56d9430ea8280e) /* 1020 */, U64_C(0xc12591d7535f5065) /* 1021 */,
+ U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */
+};
+
+static unsigned int
+transform ( void *ctx, const unsigned char *data, size_t nblks );
+
+static void
+do_init (void *context, int variant)
+{
+ TIGER_CONTEXT *hd = context;
+
+ hd->a = 0x0123456789abcdefLL;
+ hd->b = 0xfedcba9876543210LL;
+ hd->c = 0xf096a5b4c3b2e187LL;
+
+ hd->bctx.nblocks = 0;
+ hd->bctx.nblocks_high = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize_shift = _gcry_ctz(64);
+ hd->bctx.bwrite = transform;
+ hd->variant = variant;
+}
+
+static void
+tiger_init (void *context, unsigned int flags)
+{
+ (void)flags;
+
+ do_init (context, 0);
+}
+
+static void
+tiger1_init (void *context, unsigned int flags)
+{
+ (void)flags;
+
+ do_init (context, 1);
+}
+
+static void
+tiger2_init (void *context, unsigned int flags)
+{
+ (void)flags;
+
+ do_init (context, 2);
+}
+
+
+#define tiger_round(xa, xb, xc, xx, xmul) { \
+ xc ^= xx; \
+ xa -= ( sbox1[ (xc) & 0xff ] ^ sbox2[ ((xc) >> 16) & 0xff ] \
+ ^ sbox3[ ((xc) >> 32) & 0xff ] ^ sbox4[ ((xc) >> 48) & 0xff ]); \
+ xb += ( sbox4[ ((xc) >> 8) & 0xff ] ^ sbox3[ ((xc) >> 24) & 0xff ] \
+ ^ sbox2[ ((xc) >> 40) & 0xff ] ^ sbox1[ ((xc) >> 56) & 0xff ]); \
+ xb *= xmul; }
+
+
+#define pass(ya, yb, yc, yx, ymul) { \
+ tiger_round( ya, yb, yc, yx[0], ymul ); \
+ tiger_round( yb, yc, ya, yx[1], ymul ); \
+ tiger_round( yc, ya, yb, yx[2], ymul ); \
+ tiger_round( ya, yb, yc, yx[3], ymul ); \
+ tiger_round( yb, yc, ya, yx[4], ymul ); \
+ tiger_round( yc, ya, yb, yx[5], ymul ); \
+ tiger_round( ya, yb, yc, yx[6], ymul ); \
+ tiger_round( yb, yc, ya, yx[7], ymul ); }
+
+
+#define key_schedule(x) { \
+ x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL; \
+ x[1] ^= x[0]; \
+ x[2] += x[1]; \
+ x[3] -= x[2] ^ ((~x[1]) << 19 ); \
+ x[4] ^= x[3]; \
+ x[5] += x[4]; \
+ x[6] -= x[5] ^ ((~x[4]) >> 23 ); \
+ x[7] ^= x[6]; \
+ x[0] += x[7]; \
+ x[1] -= x[0] ^ ((~x[7]) << 19 ); \
+ x[2] ^= x[1]; \
+ x[3] += x[2]; \
+ x[4] -= x[3] ^ ((~x[2]) >> 23 ); \
+ x[5] ^= x[4]; \
+ x[6] += x[5]; \
+ x[7] -= x[6] ^ 0x0123456789abcdefLL; }
+
+
+/****************
+ * Transform the message DATA which consists of 512 bytes (8 words)
+ */
+static unsigned int
+transform_blk ( void *ctx, const unsigned char *data )
+{
+ TIGER_CONTEXT *hd = ctx;
+ u64 a,b,c,aa,bb,cc;
+ u64 x[8];
+ int i;
+
+ for ( i = 0; i < 8; i++ )
+ x[i] = buf_get_le64(data + i * 8);
+
+ /* save */
+ a = aa = hd->a;
+ b = bb = hd->b;
+ c = cc = hd->c;
+
+ pass( a, b, c, x, 5);
+ key_schedule( x );
+ pass( c, a, b, x, 7);
+ key_schedule( x );
+ pass( b, c, a, x, 9);
+
+ /* feedforward */
+ a ^= aa;
+ b -= bb;
+ c += cc;
+ /* store */
+ hd->a = a;
+ hd->b = b;
+ hd->c = c;
+
+ return /*burn_stack*/ 21*8+11*sizeof(void*);
+}
+
+
+static unsigned int
+transform ( void *c, const unsigned char *data, size_t nblks )
+{
+ unsigned int burn;
+
+ do
+ {
+ burn = transform_blk (c, data);
+ data += 64;
+ }
+ while (--nblks);
+
+ return burn;
+}
+
+
+
+/* The routine terminates the computation
+ */
+static void
+tiger_final( void *context )
+{
+ TIGER_CONTEXT *hd = context;
+ u32 t, th, msb, lsb;
+ byte *p;
+ unsigned int burn;
+ byte pad = hd->variant == 2? 0x80 : 0x01;
+
+ t = hd->bctx.nblocks;
+ if (sizeof t == sizeof hd->bctx.nblocks)
+ th = hd->bctx.nblocks_high;
+ else
+ th = hd->bctx.nblocks >> 32;
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = (th << 6) | (t >> 26);
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->bctx.count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if( hd->bctx.count < 56 ) /* enough room */
+ {
+ hd->bctx.buf[hd->bctx.count++] = pad;
+ if (hd->bctx.count < 56)
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+
+ /* append the 64 bit count */
+ buf_put_le32(hd->bctx.buf + 56, lsb);
+ buf_put_le32(hd->bctx.buf + 60, msb);
+ burn = transform( hd, hd->bctx.buf, 1 );
+ }
+ else /* need one extra block */
+ {
+ hd->bctx.buf[hd->bctx.count++] = pad; /* pad character */
+ /* fill pad and next block with zeroes */
+ memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+
+ /* append the 64 bit count */
+ buf_put_le32(hd->bctx.buf + 64 + 56, lsb);
+ buf_put_le32(hd->bctx.buf + 64 + 60, msb);
+ burn = transform( hd, hd->bctx.buf, 2 );
+ }
+
+ p = hd->bctx.buf;
+#define X(a) do { buf_put_be64(p, hd->a); p += 8; } while(0)
+#define Y(a) do { buf_put_le64(p, hd->a); p += 8; } while(0)
+ if (hd->variant == 0)
+ {
+ X(a);
+ X(b);
+ X(c);
+ }
+ else
+ {
+ Y(a);
+ Y(b);
+ Y(c);
+ }
+#undef X
+#undef Y
+
+ hd->bctx.count = 0;
+
+ _gcry_burn_stack (burn);
+}
+
+static byte *
+tiger_read( void *context )
+{
+ TIGER_CONTEXT *hd = context;
+
+ return hd->bctx.buf;
+}
+
+
+
+/* This is the old TIGER variant based on the unfixed reference
+ implementation. IT was used in GnupG up to 1.3.2. We don't provide
+ an OID anymore because that would not be correct. */
+gcry_md_spec_t _gcry_digest_spec_tiger =
+ {
+ GCRY_MD_TIGER, {0, 0},
+ "TIGER192", NULL, 0, NULL, 24,
+ tiger_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
+ NULL, NULL,
+ sizeof (TIGER_CONTEXT)
+ };
+
+
+
+/* This is the fixed TIGER implementation. */
+static byte asn1[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
+ { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
+ 0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
+ 0x05, 0x00, 0x04, 0x18 };
+
+static gcry_md_oid_spec_t oid_spec_tiger1[] =
+ {
+ /* GNU.digestAlgorithm TIGER */
+ { "1.3.6.1.4.1.11591.12.2" },
+ { NULL }
+ };
+
+gcry_md_spec_t _gcry_digest_spec_tiger1 =
+ {
+ GCRY_MD_TIGER1, {0, 0},
+ "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
+ tiger1_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
+ NULL, NULL,
+ sizeof (TIGER_CONTEXT)
+ };
+
+
+
+/* This is TIGER2 which usues a changed padding algorithm. */
+gcry_md_spec_t _gcry_digest_spec_tiger2 =
+ {
+ GCRY_MD_TIGER2, {0, 0},
+ "TIGER2", NULL, 0, NULL, 24,
+ tiger2_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
+ NULL, NULL,
+ sizeof (TIGER_CONTEXT)
+ };
diff --git a/comm/third_party/libgcrypt/cipher/twofish-aarch64.S b/comm/third_party/libgcrypt/cipher/twofish-aarch64.S
new file mode 100644
index 0000000000..9f35b5cdeb
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/twofish-aarch64.S
@@ -0,0 +1,321 @@
+/* twofish-aarch64.S - ARMv8/AArch64 assembly implementation of Twofish cipher
+ *
+ * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "asm-common-aarch64.h"
+
+#if defined(__AARCH64EL__)
+#ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS
+
+.text
+
+/* structure of TWOFISH_context: */
+#define s0 0
+#define s1 ((s0) + 4 * 256)
+#define s2 ((s1) + 4 * 256)
+#define s3 ((s2) + 4 * 256)
+#define w ((s3) + 4 * 256)
+#define k ((w) + 4 * 8)
+
+/* register macros */
+#define CTX x0
+#define RDST x1
+#define RSRC x2
+#define CTXs0 CTX
+#define CTXs1 x3
+#define CTXs2 x4
+#define CTXs3 x5
+#define CTXw x17
+
+#define RA w6
+#define RB w7
+#define RC w8
+#define RD w9
+
+#define RX w10
+#define RY w11
+
+#define xRX x10
+#define xRY x11
+
+#define RMASK w12
+
+#define RT0 w13
+#define RT1 w14
+#define RT2 w15
+#define RT3 w16
+
+#define xRT0 x13
+#define xRT1 x14
+#define xRT2 x15
+#define xRT3 x16
+
+/* helper macros */
+#ifndef __AARCH64EL__
+ /* bswap on big-endian */
+ #define host_to_le(reg) \
+ rev reg, reg;
+ #define le_to_host(reg) \
+ rev reg, reg;
+#else
+ /* nop on little-endian */
+ #define host_to_le(reg) /*_*/
+ #define le_to_host(reg) /*_*/
+#endif
+
+#define ldr_input_aligned_le(rin, a, b, c, d) \
+ ldr a, [rin, #0]; \
+ ldr b, [rin, #4]; \
+ le_to_host(a); \
+ ldr c, [rin, #8]; \
+ le_to_host(b); \
+ ldr d, [rin, #12]; \
+ le_to_host(c); \
+ le_to_host(d);
+
+#define str_output_aligned_le(rout, a, b, c, d) \
+ le_to_host(a); \
+ le_to_host(b); \
+ str a, [rout, #0]; \
+ le_to_host(c); \
+ str b, [rout, #4]; \
+ le_to_host(d); \
+ str c, [rout, #8]; \
+ str d, [rout, #12];
+
+/* unaligned word reads/writes allowed */
+#define ldr_input_le(rin, ra, rb, rc, rd, rtmp) \
+ ldr_input_aligned_le(rin, ra, rb, rc, rd)
+
+#define str_output_le(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+ str_output_aligned_le(rout, ra, rb, rc, rd)
+
+/**********************************************************************
+ 1-way twofish
+ **********************************************************************/
+#define encrypt_round(a, b, rc, rd, n, ror_a, adj_a) \
+ and RT0, RMASK, b, lsr#(8 - 2); \
+ and RY, RMASK, b, lsr#(16 - 2); \
+ and RT1, RMASK, b, lsr#(24 - 2); \
+ ldr RY, [CTXs3, xRY]; \
+ and RT2, RMASK, b, lsl#(2); \
+ ldr RT0, [CTXs2, xRT0]; \
+ and RT3, RMASK, a, lsr#(16 - 2 + (adj_a)); \
+ ldr RT1, [CTXs0, xRT1]; \
+ and RX, RMASK, a, lsr#(8 - 2 + (adj_a)); \
+ ldr RT2, [CTXs1, xRT2]; \
+ ldr RX, [CTXs1, xRX]; \
+ ror_a(a); \
+ \
+ eor RY, RY, RT0; \
+ ldr RT3, [CTXs2, xRT3]; \
+ and RT0, RMASK, a, lsl#(2); \
+ eor RY, RY, RT1; \
+ and RT1, RMASK, a, lsr#(24 - 2); \
+ eor RY, RY, RT2; \
+ ldr RT0, [CTXs0, xRT0]; \
+ eor RX, RX, RT3; \
+ ldr RT1, [CTXs3, xRT1]; \
+ eor RX, RX, RT0; \
+ \
+ ldr RT3, [CTXs3, #(k - s3 + 8 * (n) + 4)]; \
+ eor RX, RX, RT1; \
+ ldr RT2, [CTXs3, #(k - s3 + 8 * (n))]; \
+ \
+ add RT0, RX, RY, lsl #1; \
+ add RX, RX, RY; \
+ add RT0, RT0, RT3; \
+ add RX, RX, RT2; \
+ eor rd, RT0, rd, ror #31; \
+ eor rc, rc, RX;
+
+#define dummy(x) /*_*/
+
+#define ror1(r) \
+ ror r, r, #1;
+
+#define decrypt_round(a, b, rc, rd, n, ror_b, adj_b) \
+ and RT3, RMASK, b, lsl#(2 - (adj_b)); \
+ and RT1, RMASK, b, lsr#(8 - 2 + (adj_b)); \
+ ror_b(b); \
+ and RT2, RMASK, a, lsl#(2); \
+ and RT0, RMASK, a, lsr#(8 - 2); \
+ \
+ ldr RY, [CTXs1, xRT3]; \
+ ldr RX, [CTXs0, xRT2]; \
+ and RT3, RMASK, b, lsr#(16 - 2); \
+ ldr RT1, [CTXs2, xRT1]; \
+ and RT2, RMASK, a, lsr#(16 - 2); \
+ ldr RT0, [CTXs1, xRT0]; \
+ \
+ ldr RT3, [CTXs3, xRT3]; \
+ eor RY, RY, RT1; \
+ \
+ and RT1, RMASK, b, lsr#(24 - 2); \
+ eor RX, RX, RT0; \
+ ldr RT2, [CTXs2, xRT2]; \
+ and RT0, RMASK, a, lsr#(24 - 2); \
+ \
+ ldr RT1, [CTXs0, xRT1]; \
+ \
+ eor RY, RY, RT3; \
+ ldr RT0, [CTXs3, xRT0]; \
+ eor RX, RX, RT2; \
+ eor RY, RY, RT1; \
+ \
+ ldr RT1, [CTXs3, #(k - s3 + 8 * (n) + 4)]; \
+ eor RX, RX, RT0; \
+ ldr RT2, [CTXs3, #(k - s3 + 8 * (n))]; \
+ \
+ add RT0, RX, RY, lsl #1; \
+ add RX, RX, RY; \
+ add RT0, RT0, RT1; \
+ add RX, RX, RT2; \
+ eor rd, rd, RT0; \
+ eor rc, RX, rc, ror #31;
+
+#define first_encrypt_cycle(nc) \
+ encrypt_round(RA, RB, RC, RD, (nc) * 2, dummy, 0); \
+ encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1);
+
+#define encrypt_cycle(nc) \
+ encrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+ encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1);
+
+#define last_encrypt_cycle(nc) \
+ encrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+ encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+ ror1(RA);
+
+#define first_decrypt_cycle(nc) \
+ decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, dummy, 0); \
+ decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1);
+
+#define decrypt_cycle(nc) \
+ decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+ decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1);
+
+#define last_decrypt_cycle(nc) \
+ decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+ decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+ ror1(RD);
+
+.globl _gcry_twofish_arm_encrypt_block
+ELF(.type _gcry_twofish_arm_encrypt_block,%function;)
+
+_gcry_twofish_arm_encrypt_block:
+ /* input:
+ * x0: ctx
+ * x1: dst
+ * x2: src
+ */
+ CFI_STARTPROC();
+
+ add CTXw, CTX, #(w);
+
+ ldr_input_le(RSRC, RA, RB, RC, RD, RT0);
+
+ /* Input whitening */
+ ldp RT0, RT1, [CTXw, #(0*8)];
+ ldp RT2, RT3, [CTXw, #(1*8)];
+ add CTXs3, CTX, #(s3);
+ add CTXs2, CTX, #(s2);
+ add CTXs1, CTX, #(s1);
+ mov RMASK, #(0xff << 2);
+ eor RA, RA, RT0;
+ eor RB, RB, RT1;
+ eor RC, RC, RT2;
+ eor RD, RD, RT3;
+
+ first_encrypt_cycle(0);
+ encrypt_cycle(1);
+ encrypt_cycle(2);
+ encrypt_cycle(3);
+ encrypt_cycle(4);
+ encrypt_cycle(5);
+ encrypt_cycle(6);
+ last_encrypt_cycle(7);
+
+ /* Output whitening */
+ ldp RT0, RT1, [CTXw, #(2*8)];
+ ldp RT2, RT3, [CTXw, #(3*8)];
+ eor RC, RC, RT0;
+ eor RD, RD, RT1;
+ eor RA, RA, RT2;
+ eor RB, RB, RT3;
+
+ str_output_le(RDST, RC, RD, RA, RB, RT0, RT1);
+
+ ret;
+ CFI_ENDPROC();
+.ltorg
+ELF(.size _gcry_twofish_arm_encrypt_block,.-_gcry_twofish_arm_encrypt_block;)
+
+.globl _gcry_twofish_arm_decrypt_block
+ELF(.type _gcry_twofish_arm_decrypt_block,%function;)
+
+_gcry_twofish_arm_decrypt_block:
+ /* input:
+ * %r0: ctx
+ * %r1: dst
+ * %r2: src
+ */
+ CFI_STARTPROC();
+
+ add CTXw, CTX, #(w);
+
+ ldr_input_le(RSRC, RC, RD, RA, RB, RT0);
+
+ /* Input whitening */
+ ldp RT0, RT1, [CTXw, #(2*8)];
+ ldp RT2, RT3, [CTXw, #(3*8)];
+ add CTXs3, CTX, #(s3);
+ add CTXs2, CTX, #(s2);
+ add CTXs1, CTX, #(s1);
+ mov RMASK, #(0xff << 2);
+ eor RC, RC, RT0;
+ eor RD, RD, RT1;
+ eor RA, RA, RT2;
+ eor RB, RB, RT3;
+
+ first_decrypt_cycle(7);
+ decrypt_cycle(6);
+ decrypt_cycle(5);
+ decrypt_cycle(4);
+ decrypt_cycle(3);
+ decrypt_cycle(2);
+ decrypt_cycle(1);
+ last_decrypt_cycle(0);
+
+ /* Output whitening */
+ ldp RT0, RT1, [CTXw, #(0*8)];
+ ldp RT2, RT3, [CTXw, #(1*8)];
+ eor RA, RA, RT0;
+ eor RB, RB, RT1;
+ eor RC, RC, RT2;
+ eor RD, RD, RT3;
+
+ str_output_le(RDST, RA, RB, RC, RD, RT0, RT1);
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_arm_decrypt_block,.-_gcry_twofish_arm_decrypt_block;)
+
+#endif /*HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS*/
+#endif /*__AARCH64EL__*/
diff --git a/comm/third_party/libgcrypt/cipher/twofish-amd64.S b/comm/third_party/libgcrypt/cipher/twofish-amd64.S
new file mode 100644
index 0000000000..3cb734317d
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/twofish-amd64.S
@@ -0,0 +1,1184 @@
+/* twofish-amd64.S - AMD64 assembly implementation of Twofish cipher
+ *
+ * Copyright (C) 2013-2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_TWOFISH)
+
+#include "asm-common-amd64.h"
+
+.text
+
+/* structure of TWOFISH_context: */
+#define s0 0
+#define s1 ((s0) + 4 * 256)
+#define s2 ((s1) + 4 * 256)
+#define s3 ((s2) + 4 * 256)
+#define w ((s3) + 4 * 256)
+#define k ((w) + 4 * 8)
+
+/* register macros */
+#define CTX %rdi
+
+#define RA %rax
+#define RB %rbx
+#define RC %rcx
+#define RD %rdx
+
+#define RAd %eax
+#define RBd %ebx
+#define RCd %ecx
+#define RDd %edx
+
+#define RAbl %al
+#define RBbl %bl
+#define RCbl %cl
+#define RDbl %dl
+
+#define RAbh %ah
+#define RBbh %bh
+#define RCbh %ch
+#define RDbh %dh
+
+#define RX %r8
+#define RY %r9
+
+#define RXd %r8d
+#define RYd %r9d
+
+#define RT0 %rsi
+#define RT1 %rbp
+#define RT2 %r10
+#define RT3 %r11
+
+#define RT0d %esi
+#define RT1d %ebp
+#define RT2d %r10d
+#define RT3d %r11d
+
+/***********************************************************************
+ * AMD64 assembly implementation of the Twofish cipher
+ ***********************************************************************/
+#define enc_g1_2(a, b, x, y) \
+ movzbl b ## bl, RT3d; \
+ movzbl b ## bh, RT1d; \
+ movzbl a ## bl, RT2d; \
+ movzbl a ## bh, RT0d; \
+ rorl $16, b ## d; \
+ rorl $16, a ## d; \
+ movl s1(CTX, RT3, 4), RYd; \
+ movzbl b ## bl, RT3d; \
+ movl s0(CTX, RT2, 4), RXd; \
+ movzbl a ## bl, RT2d; \
+ xorl s2(CTX, RT1, 4), RYd; \
+ movzbl b ## bh, RT1d; \
+ xorl s1(CTX, RT0, 4), RXd; \
+ movzbl a ## bh, RT0d; \
+ rorl $16, b ## d; \
+ rorl $16, a ## d; \
+ xorl s3(CTX, RT3, 4), RYd; \
+ xorl s2(CTX, RT2, 4), RXd; \
+ xorl s0(CTX, RT1, 4), RYd; \
+ xorl s3(CTX, RT0, 4), RXd;
+
+#define dec_g1_2(a, b, x, y) \
+ movzbl a ## bl, RT2d; \
+ movzbl a ## bh, RT0d; \
+ movzbl b ## bl, RT3d; \
+ movzbl b ## bh, RT1d; \
+ rorl $16, a ## d; \
+ rorl $16, b ## d; \
+ movl s0(CTX, RT2, 4), RXd; \
+ movzbl a ## bl, RT2d; \
+ movl s1(CTX, RT3, 4), RYd; \
+ movzbl b ## bl, RT3d; \
+ xorl s1(CTX, RT0, 4), RXd; \
+ movzbl a ## bh, RT0d; \
+ xorl s2(CTX, RT1, 4), RYd; \
+ movzbl b ## bh, RT1d; \
+ rorl $16, a ## d; \
+ rorl $16, b ## d; \
+ xorl s2(CTX, RT2, 4), RXd; \
+ xorl s3(CTX, RT3, 4), RYd; \
+ xorl s3(CTX, RT0, 4), RXd; \
+ xorl s0(CTX, RT1, 4), RYd;
+
+#define encrypt_round(ra, rb, rc, rd, n) \
+ enc_g1_2(##ra, ##rb, RX, RY); \
+ \
+ leal (RXd, RYd, 2), RT0d; \
+ addl RYd, RXd; \
+ addl (k + 8 * (n) + 4)(CTX), RT0d; \
+ roll $1, rd ## d; \
+ addl (k + 8 * (n))(CTX), RXd; \
+ xorl RT0d, rd ## d; \
+ xorl RXd, rc ## d; \
+ rorl $1, rc ## d;
+
+#define decrypt_round(ra, rb, rc, rd, n) \
+ dec_g1_2(##ra, ##rb, RX, RY); \
+ \
+ leal (RXd, RYd, 2), RT0d; \
+ addl RYd, RXd; \
+ addl (k + 8 * (n) + 4)(CTX), RT0d; \
+ roll $1, rc ## d; \
+ addl (k + 8 * (n))(CTX), RXd; \
+ xorl RXd, rc ## d; \
+ xorl RT0d, rd ## d; \
+ rorl $1, rd ## d;
+
+#define encrypt_cycle(a, b, c, d, nc) \
+ encrypt_round(##a, ##b, ##c, ##d, (nc) * 2); \
+ encrypt_round(##c, ##d, ##a, ##b, (nc) * 2 + 1);
+
+#define decrypt_cycle(a, b, c, d, nc) \
+ decrypt_round(##c, ##d, ##a, ##b, (nc) * 2 + 1); \
+ decrypt_round(##a, ##b, ##c, ##d, (nc) * 2);
+
+#define inpack(in, n, x, m) \
+ movl (4 * (n))(in), x; \
+ xorl (w + 4 * (m))(CTX), x;
+
+#define outunpack(out, n, x, m) \
+ xorl (w + 4 * (m))(CTX), x; \
+ movl x, (4 * (n))(out);
+
+.align 8
+.globl _gcry_twofish_amd64_encrypt_block
+ELF(.type _gcry_twofish_amd64_encrypt_block,@function;)
+
+_gcry_twofish_amd64_encrypt_block:
+ /* input:
+ * %rdi: context, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ subq $(3 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(3 * 8);
+ movq %rsi, (0 * 8)(%rsp);
+ movq %rbp, (1 * 8)(%rsp);
+ movq %rbx, (2 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 1 * 8);
+ CFI_REL_OFFSET(%rbx, 2 * 8);
+
+ movq %rdx, RX;
+ inpack(RX, 0, RAd, 0);
+ inpack(RX, 1, RBd, 1);
+ inpack(RX, 2, RCd, 2);
+ inpack(RX, 3, RDd, 3);
+
+ encrypt_cycle(RA, RB, RC, RD, 0);
+ encrypt_cycle(RA, RB, RC, RD, 1);
+ encrypt_cycle(RA, RB, RC, RD, 2);
+ encrypt_cycle(RA, RB, RC, RD, 3);
+ encrypt_cycle(RA, RB, RC, RD, 4);
+ encrypt_cycle(RA, RB, RC, RD, 5);
+ encrypt_cycle(RA, RB, RC, RD, 6);
+ encrypt_cycle(RA, RB, RC, RD, 7);
+
+ movq (0 * 8)(%rsp), RX; /*dst*/
+ outunpack(RX, 0, RCd, 4);
+ outunpack(RX, 1, RDd, 5);
+ outunpack(RX, 2, RAd, 6);
+ outunpack(RX, 3, RBd, 7);
+
+ movq (2 * 8)(%rsp), %rbx;
+ movq (1 * 8)(%rsp), %rbp;
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%rbp);
+ addq $(3 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-3 * 8);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;)
+
+.align 8
+.globl _gcry_twofish_amd64_decrypt_block
+ELF(.type _gcry_twofish_amd64_decrypt_block,@function;)
+
+_gcry_twofish_amd64_decrypt_block:
+ /* input:
+ * %rdi: context, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ subq $(3 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(3 * 8);
+ movq %rsi, (0 * 8)(%rsp);
+ movq %rbp, (1 * 8)(%rsp);
+ movq %rbx, (2 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 1 * 8);
+ CFI_REL_OFFSET(%rbx, 2 * 8);
+
+ movq %rdx, RX;
+ inpack(RX, 0, RCd, 4);
+ inpack(RX, 1, RDd, 5);
+ inpack(RX, 2, RAd, 6);
+ inpack(RX, 3, RBd, 7);
+
+ decrypt_cycle(RA, RB, RC, RD, 7);
+ decrypt_cycle(RA, RB, RC, RD, 6);
+ decrypt_cycle(RA, RB, RC, RD, 5);
+ decrypt_cycle(RA, RB, RC, RD, 4);
+ decrypt_cycle(RA, RB, RC, RD, 3);
+ decrypt_cycle(RA, RB, RC, RD, 2);
+ decrypt_cycle(RA, RB, RC, RD, 1);
+ decrypt_cycle(RA, RB, RC, RD, 0);
+
+ movq (0 * 8)(%rsp), RX; /*dst*/
+ outunpack(RX, 0, RAd, 0);
+ outunpack(RX, 1, RBd, 1);
+ outunpack(RX, 2, RCd, 2);
+ outunpack(RX, 3, RDd, 3);
+
+ movq (2 * 8)(%rsp), %rbx;
+ movq (1 * 8)(%rsp), %rbp;
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%rbp);
+ addq $(3 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-3 * 8);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;)
+
+#undef CTX
+
+#undef RA
+#undef RB
+#undef RC
+#undef RD
+
+#undef RAd
+#undef RBd
+#undef RCd
+#undef RDd
+
+#undef RAbl
+#undef RBbl
+#undef RCbl
+#undef RDbl
+
+#undef RAbh
+#undef RBbh
+#undef RCbh
+#undef RDbh
+
+#undef RX
+#undef RY
+
+#undef RXd
+#undef RYd
+
+#undef RT0
+#undef RT1
+#undef RT2
+#undef RT3
+
+#undef RT0d
+#undef RT1d
+#undef RT2d
+#undef RT3d
+
+/***********************************************************************
+ * AMD64 assembly implementation of the Twofish cipher, 3-way parallel
+ ***********************************************************************/
+#define CTX %rdi
+#define RIO %rdx
+
+#define RAB0 %rax
+#define RAB1 %rbx
+#define RAB2 %rcx
+
+#define RAB0d %eax
+#define RAB1d %ebx
+#define RAB2d %ecx
+
+#define RAB0bh %ah
+#define RAB1bh %bh
+#define RAB2bh %ch
+
+#define RAB0bl %al
+#define RAB1bl %bl
+#define RAB2bl %cl
+
+#define RCD0 %r8
+#define RCD1 %r9
+#define RCD2 %r10
+
+#define RCD0d %r8d
+#define RCD1d %r9d
+#define RCD2d %r10d
+
+#define RX0 %rbp
+#define RX1 %r11
+#define RX2 %r12
+
+#define RX0d %ebp
+#define RX1d %r11d
+#define RX2d %r12d
+
+#define RY0 %r13
+#define RY1 %r14
+#define RY2 %r15
+
+#define RY0d %r13d
+#define RY1d %r14d
+#define RY2d %r15d
+
+#define RT0 %rdx
+#define RT1 %rsi
+
+#define RT0d %edx
+#define RT1d %esi
+
+#define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \
+ movzbl ab ## bl, tmp2 ## d; \
+ movzbl ab ## bh, tmp1 ## d; \
+ rorq $(rot), ab; \
+ op1##l T0(CTX, tmp2, 4), dst ## d; \
+ op2##l T1(CTX, tmp1, 4), dst ## d;
+
+/*
+ * Combined G1 & G2 function. Reordered with help of rotates to have moves
+ * at beginning.
+ */
+#define g1g2_3(ab, cd, Tx0, Tx1, Tx2, Tx3, Ty0, Ty1, Ty2, Ty3, x, y) \
+ /* G1,1 && G2,1 */ \
+ do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 0, ab ## 0, x ## 0); \
+ do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 0, ab ## 0, y ## 0); \
+ \
+ do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 1, ab ## 1, x ## 1); \
+ do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 1, ab ## 1, y ## 1); \
+ \
+ do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 2, ab ## 2, x ## 2); \
+ do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 2, ab ## 2, y ## 2); \
+ \
+ /* G1,2 && G2,2 */ \
+ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \
+ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \
+ movq ab ## 0, RT0; \
+ movq cd ## 0, ab ## 0; \
+ movq RT0, cd ## 0; \
+ \
+ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \
+ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \
+ movq ab ## 1, RT0; \
+ movq cd ## 1, ab ## 1; \
+ movq RT0, cd ## 1; \
+ \
+ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \
+ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \
+ movq ab ## 2, RT0; \
+ movq cd ## 2, ab ## 2; \
+ movq RT0, cd ## 2;
+
+#define enc_round_end(ab, x, y, n) \
+ addl y ## d, x ## d; \
+ addl x ## d, y ## d; \
+ addl k+4*(2*(n))(CTX), x ## d; \
+ xorl ab ## d, x ## d; \
+ addl k+4*(2*(n)+1)(CTX), y ## d; \
+ shrq $32, ab; \
+ roll $1, ab ## d; \
+ xorl y ## d, ab ## d; \
+ shlq $32, ab; \
+ rorl $1, x ## d; \
+ orq x, ab;
+
+#define dec_round_end(ba, x, y, n) \
+ addl y ## d, x ## d; \
+ addl x ## d, y ## d; \
+ addl k+4*(2*(n))(CTX), x ## d; \
+ addl k+4*(2*(n)+1)(CTX), y ## d; \
+ xorl ba ## d, y ## d; \
+ shrq $32, ba; \
+ roll $1, ba ## d; \
+ xorl x ## d, ba ## d; \
+ shlq $32, ba; \
+ rorl $1, y ## d; \
+ orq y, ba;
+
+#define encrypt_round3(ab, cd, n) \
+ g1g2_3(ab, cd, s0, s1, s2, s3, s0, s1, s2, s3, RX, RY); \
+ \
+ enc_round_end(ab ## 0, RX0, RY0, n); \
+ enc_round_end(ab ## 1, RX1, RY1, n); \
+ enc_round_end(ab ## 2, RX2, RY2, n);
+
+#define decrypt_round3(ba, dc, n) \
+ g1g2_3(ba, dc, s1, s2, s3, s0, s3, s0, s1, s2, RY, RX); \
+ \
+ dec_round_end(ba ## 0, RX0, RY0, n); \
+ dec_round_end(ba ## 1, RX1, RY1, n); \
+ dec_round_end(ba ## 2, RX2, RY2, n);
+
+#define encrypt_cycle3(ab, cd, n) \
+ encrypt_round3(ab, cd, n*2); \
+ encrypt_round3(ab, cd, (n*2)+1);
+
+#define decrypt_cycle3(ba, dc, n) \
+ decrypt_round3(ba, dc, (n*2)+1); \
+ decrypt_round3(ba, dc, (n*2));
+
+#define inpack3(xy, m) \
+ xorq w+4*m(CTX), xy ## 0; \
+ xorq w+4*m(CTX), xy ## 1; \
+ xorq w+4*m(CTX), xy ## 2;
+
+#define outunpack3(xy, m) \
+ xorq w+4*m(CTX), xy ## 0; \
+ xorq w+4*m(CTX), xy ## 1; \
+ xorq w+4*m(CTX), xy ## 2;
+
+#define inpack_enc3() \
+ inpack3(RAB, 0); \
+ inpack3(RCD, 2);
+
+#define outunpack_enc3() \
+ outunpack3(RAB, 6); \
+ outunpack3(RCD, 4);
+
+#define inpack_dec3() \
+ inpack3(RAB, 4); \
+ rorq $32, RAB0; \
+ rorq $32, RAB1; \
+ rorq $32, RAB2; \
+ inpack3(RCD, 6); \
+ rorq $32, RCD0; \
+ rorq $32, RCD1; \
+ rorq $32, RCD2;
+
+#define outunpack_dec3() \
+ rorq $32, RCD0; \
+ rorq $32, RCD1; \
+ rorq $32, RCD2; \
+ outunpack3(RCD, 0); \
+ rorq $32, RAB0; \
+ rorq $32, RAB1; \
+ rorq $32, RAB2; \
+ outunpack3(RAB, 2);
+
+.align 8
+ELF(.type __twofish_enc_blk3,@function;)
+
+__twofish_enc_blk3:
+ /* input:
+ * %rdi: ctx, CTX
+ * RAB0,RCD0,RAB1,RCD1,RAB2,RCD2: three plaintext blocks
+ * output:
+ * RCD0,RAB0,RCD1,RAB1,RCD2,RAB2: three ciphertext blocks
+ */
+ CFI_STARTPROC();
+
+ inpack_enc3();
+
+ encrypt_cycle3(RAB, RCD, 0);
+ encrypt_cycle3(RAB, RCD, 1);
+ encrypt_cycle3(RAB, RCD, 2);
+ encrypt_cycle3(RAB, RCD, 3);
+ encrypt_cycle3(RAB, RCD, 4);
+ encrypt_cycle3(RAB, RCD, 5);
+ encrypt_cycle3(RAB, RCD, 6);
+ encrypt_cycle3(RAB, RCD, 7);
+
+ outunpack_enc3();
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __twofish_enc_blk3,.-__twofish_enc_blk3;)
+
+.align 8
+ELF(.type __twofish_dec_blk3,@function;)
+
+__twofish_dec_blk3:
+ /* input:
+ * %rdi: ctx, CTX
+ * RAB0,RCD0,RAB1,RCD1,RAB2,RCD2: three ciphertext blocks
+ * output:
+ * RCD0,RAB0,RCD1,RAB1,RCD2,RAB2: three plaintext blocks
+ */
+ CFI_STARTPROC();
+
+ inpack_dec3();
+
+ decrypt_cycle3(RAB, RCD, 7);
+ decrypt_cycle3(RAB, RCD, 6);
+ decrypt_cycle3(RAB, RCD, 5);
+ decrypt_cycle3(RAB, RCD, 4);
+ decrypt_cycle3(RAB, RCD, 3);
+ decrypt_cycle3(RAB, RCD, 2);
+ decrypt_cycle3(RAB, RCD, 1);
+ decrypt_cycle3(RAB, RCD, 0);
+
+ outunpack_dec3();
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __twofish_dec_blk3,.-__twofish_dec_blk3;)
+
+.align 8
+.globl _gcry_twofish_amd64_ctr_enc
+ELF(.type _gcry_twofish_amd64_ctr_enc,@function;)
+_gcry_twofish_amd64_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (3 blocks)
+ * %rdx: src (3 blocks)
+ * %rcx: iv (big endian, 128bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ subq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(8 * 8);
+ movq %rbp, (0 * 8)(%rsp);
+ movq %rbx, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ movq %r14, (4 * 8)(%rsp);
+ movq %r15, (5 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 0 * 8);
+ CFI_REL_OFFSET(%rbx, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+ CFI_REL_OFFSET(%r14, 4 * 8);
+ CFI_REL_OFFSET(%r15, 5 * 8);
+
+ movq %rsi, (6 * 8)(%rsp);
+ movq %rdx, (7 * 8)(%rsp);
+ movq %rcx, RX0;
+
+ /* load IV and byteswap */
+ movq 8(RX0), RT0;
+ movq 0(RX0), RT1;
+ movq RT0, RCD0;
+ movq RT1, RAB0;
+ bswapq RT0;
+ bswapq RT1;
+
+ /* construct IVs */
+ movq RT0, RCD1;
+ movq RT1, RAB1;
+ movq RT0, RCD2;
+ movq RT1, RAB2;
+ addq $1, RCD1;
+ adcq $0, RAB1;
+ bswapq RCD1;
+ bswapq RAB1;
+ addq $2, RCD2;
+ adcq $0, RAB2;
+ bswapq RCD2;
+ bswapq RAB2;
+ addq $3, RT0;
+ adcq $0, RT1;
+ bswapq RT0;
+ bswapq RT1;
+
+ /* store new IV */
+ movq RT0, 8(RX0);
+ movq RT1, 0(RX0);
+
+ call __twofish_enc_blk3;
+
+ movq (7 * 8)(%rsp), RX0; /*src*/
+ movq (6 * 8)(%rsp), RX1; /*dst*/
+
+ /* XOR key-stream with plaintext */
+ xorq (0 * 8)(RX0), RCD0;
+ xorq (1 * 8)(RX0), RAB0;
+ xorq (2 * 8)(RX0), RCD1;
+ xorq (3 * 8)(RX0), RAB1;
+ xorq (4 * 8)(RX0), RCD2;
+ xorq (5 * 8)(RX0), RAB2;
+ movq RCD0, (0 * 8)(RX1);
+ movq RAB0, (1 * 8)(RX1);
+ movq RCD1, (2 * 8)(RX1);
+ movq RAB1, (3 * 8)(RX1);
+ movq RCD2, (4 * 8)(RX1);
+ movq RAB2, (5 * 8)(RX1);
+
+ movq (0 * 8)(%rsp), %rbp;
+ movq (1 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ movq (4 * 8)(%rsp), %r14;
+ movq (5 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbp);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+ addq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-8 * 8);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_amd64_ctr_enc,.-_gcry_twofish_amd64_ctr_enc;)
+
+.align 8
+.globl _gcry_twofish_amd64_cbc_dec
+ELF(.type _gcry_twofish_amd64_cbc_dec,@function;)
+_gcry_twofish_amd64_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (3 blocks)
+ * %rdx: src (3 blocks)
+ * %rcx: iv (128bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ subq $(9 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(9 * 8);
+ movq %rbp, (0 * 8)(%rsp);
+ movq %rbx, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ movq %r14, (4 * 8)(%rsp);
+ movq %r15, (5 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 0 * 8);
+ CFI_REL_OFFSET(%rbx, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+ CFI_REL_OFFSET(%r14, 4 * 8);
+ CFI_REL_OFFSET(%r15, 5 * 8);
+
+ movq %rsi, (6 * 8)(%rsp);
+ movq %rdx, (7 * 8)(%rsp);
+ movq %rcx, (8 * 8)(%rsp);
+ movq %rdx, RX0;
+
+ /* load input */
+ movq (0 * 8)(RX0), RAB0;
+ movq (1 * 8)(RX0), RCD0;
+ movq (2 * 8)(RX0), RAB1;
+ movq (3 * 8)(RX0), RCD1;
+ movq (4 * 8)(RX0), RAB2;
+ movq (5 * 8)(RX0), RCD2;
+
+ call __twofish_dec_blk3;
+
+ movq (8 * 8)(%rsp), RT0; /*iv*/
+ movq (7 * 8)(%rsp), RX0; /*src*/
+ movq (6 * 8)(%rsp), RX1; /*dst*/
+
+ movq (4 * 8)(RX0), RY0;
+ movq (5 * 8)(RX0), RY1;
+ xorq (0 * 8)(RT0), RCD0;
+ xorq (1 * 8)(RT0), RAB0;
+ xorq (0 * 8)(RX0), RCD1;
+ xorq (1 * 8)(RX0), RAB1;
+ xorq (2 * 8)(RX0), RCD2;
+ xorq (3 * 8)(RX0), RAB2;
+ movq RY0, (0 * 8)(RT0);
+ movq RY1, (1 * 8)(RT0);
+
+ movq RCD0, (0 * 8)(RX1);
+ movq RAB0, (1 * 8)(RX1);
+ movq RCD1, (2 * 8)(RX1);
+ movq RAB1, (3 * 8)(RX1);
+ movq RCD2, (4 * 8)(RX1);
+ movq RAB2, (5 * 8)(RX1);
+
+ movq (0 * 8)(%rsp), %rbp;
+ movq (1 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ movq (4 * 8)(%rsp), %r14;
+ movq (5 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbp);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+ addq $(9 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-9 * 8);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_amd64_cbc_dec,.-_gcry_twofish_amd64_cbc_dec;)
+
+.align 8
+.globl _gcry_twofish_amd64_cfb_dec
+ELF(.type _gcry_twofish_amd64_cfb_dec,@function;)
+_gcry_twofish_amd64_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (3 blocks)
+ * %rdx: src (3 blocks)
+ * %rcx: iv (128bit)
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
+ subq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(8 * 8);
+ movq %rbp, (0 * 8)(%rsp);
+ movq %rbx, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ movq %r14, (4 * 8)(%rsp);
+ movq %r15, (5 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 0 * 8);
+ CFI_REL_OFFSET(%rbx, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+ CFI_REL_OFFSET(%r14, 4 * 8);
+ CFI_REL_OFFSET(%r15, 5 * 8);
+
+ movq %rsi, (6 * 8)(%rsp);
+ movq %rdx, (7 * 8)(%rsp);
+ movq %rdx, RX0;
+ movq %rcx, RX1;
+
+ /* load input */
+ movq (0 * 8)(RX1), RAB0;
+ movq (1 * 8)(RX1), RCD0;
+ movq (0 * 8)(RX0), RAB1;
+ movq (1 * 8)(RX0), RCD1;
+ movq (2 * 8)(RX0), RAB2;
+ movq (3 * 8)(RX0), RCD2;
+
+ /* Update IV */
+ movq (4 * 8)(RX0), RY0;
+ movq (5 * 8)(RX0), RY1;
+ movq RY0, (0 * 8)(RX1);
+ movq RY1, (1 * 8)(RX1);
+
+ call __twofish_enc_blk3;
+
+ movq (7 * 8)(%rsp), RX0; /*src*/
+ movq (6 * 8)(%rsp), RX1; /*dst*/
+
+ xorq (0 * 8)(RX0), RCD0;
+ xorq (1 * 8)(RX0), RAB0;
+ xorq (2 * 8)(RX0), RCD1;
+ xorq (3 * 8)(RX0), RAB1;
+ xorq (4 * 8)(RX0), RCD2;
+ xorq (5 * 8)(RX0), RAB2;
+ movq RCD0, (0 * 8)(RX1);
+ movq RAB0, (1 * 8)(RX1);
+ movq RCD1, (2 * 8)(RX1);
+ movq RAB1, (3 * 8)(RX1);
+ movq RCD2, (4 * 8)(RX1);
+ movq RAB2, (5 * 8)(RX1);
+
+ movq (0 * 8)(%rsp), %rbp;
+ movq (1 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ movq (4 * 8)(%rsp), %r14;
+ movq (5 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbp);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+ addq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-8 * 8);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_amd64_cfb_dec,.-_gcry_twofish_amd64_cfb_dec;)
+
+.align 8
+.globl _gcry_twofish_amd64_ocb_enc
+ELF(.type _gcry_twofish_amd64_ocb_enc,@function;)
+_gcry_twofish_amd64_ocb_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (3 blocks)
+ * %rdx: src (3 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[3])
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_6
+
+ subq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(8 * 8);
+ movq %rbp, (0 * 8)(%rsp);
+ movq %rbx, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ movq %r14, (4 * 8)(%rsp);
+ movq %r15, (5 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 0 * 8);
+ CFI_REL_OFFSET(%rbx, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+ CFI_REL_OFFSET(%r14, 4 * 8);
+ CFI_REL_OFFSET(%r15, 5 * 8);
+
+ movq %rsi, (6 * 8)(%rsp);
+ movq %rdx, RX0;
+ movq %rcx, RX1;
+ movq %r8, RX2;
+ movq %r9, RY0;
+ movq %rsi, RY1;
+
+ /* Load offset */
+ movq (0 * 8)(RX1), RT0;
+ movq (1 * 8)(RX1), RT1;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq (RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (0 * 8)(RX0), RAB0;
+ movq (1 * 8)(RX0), RCD0;
+ /* Store Offset_i */
+ movq RT0, (0 * 8)(RY1);
+ movq RT1, (1 * 8)(RY1);
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ xor RAB0, (0 * 8)(RX2);
+ xor RCD0, (1 * 8)(RX2);
+ /* PX_i = P_i xor Offset_i */
+ xorq RT0, RAB0;
+ xorq RT1, RCD0;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq 8(RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (2 * 8)(RX0), RAB1;
+ movq (3 * 8)(RX0), RCD1;
+ /* Store Offset_i */
+ movq RT0, (2 * 8)(RY1);
+ movq RT1, (3 * 8)(RY1);
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ xor RAB1, (0 * 8)(RX2);
+ xor RCD1, (1 * 8)(RX2);
+ /* PX_i = P_i xor Offset_i */
+ xorq RT0, RAB1;
+ xorq RT1, RCD1;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq 16(RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (4 * 8)(RX0), RAB2;
+ movq (5 * 8)(RX0), RCD2;
+ /* Store Offset_i */
+ movq RT0, (4 * 8)(RY1);
+ movq RT1, (5 * 8)(RY1);
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ xor RAB2, (0 * 8)(RX2);
+ xor RCD2, (1 * 8)(RX2);
+ /* PX_i = P_i xor Offset_i */
+ xorq RT0, RAB2;
+ xorq RT1, RCD2;
+
+ /* Store offset */
+ movq RT0, (0 * 8)(RX1);
+ movq RT1, (1 * 8)(RX1);
+
+ /* CX_i = ENCIPHER(K, PX_i) */
+ call __twofish_enc_blk3;
+
+ movq (6 * 8)(%rsp), RX1; /*dst*/
+
+ /* C_i = CX_i xor Offset_i */
+ xorq RCD0, (0 * 8)(RX1);
+ xorq RAB0, (1 * 8)(RX1);
+ xorq RCD1, (2 * 8)(RX1);
+ xorq RAB1, (3 * 8)(RX1);
+ xorq RCD2, (4 * 8)(RX1);
+ xorq RAB2, (5 * 8)(RX1);
+
+ movq (0 * 8)(%rsp), %rbp;
+ movq (1 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ movq (4 * 8)(%rsp), %r14;
+ movq (5 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbp);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+ addq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-8 * 8);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_amd64_ocb_enc,.-_gcry_twofish_amd64_ocb_enc;)
+
+.align 8
+.globl _gcry_twofish_amd64_ocb_dec
+ELF(.type _gcry_twofish_amd64_ocb_dec,@function;)
+_gcry_twofish_amd64_ocb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (3 blocks)
+ * %rdx: src (3 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[3])
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_6
+
+ subq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(8 * 8);
+ movq %rbp, (0 * 8)(%rsp);
+ movq %rbx, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ movq %r14, (4 * 8)(%rsp);
+ movq %r15, (5 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 0 * 8);
+ CFI_REL_OFFSET(%rbx, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+ CFI_REL_OFFSET(%r14, 4 * 8);
+ CFI_REL_OFFSET(%r15, 5 * 8);
+
+ movq %rsi, (6 * 8)(%rsp);
+ movq %r8, (7 * 8)(%rsp);
+ movq %rdx, RX0;
+ movq %rcx, RX1;
+ movq %r9, RY0;
+ movq %rsi, RY1;
+
+ /* Load offset */
+ movq (0 * 8)(RX1), RT0;
+ movq (1 * 8)(RX1), RT1;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq (RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (0 * 8)(RX0), RAB0;
+ movq (1 * 8)(RX0), RCD0;
+ /* Store Offset_i */
+ movq RT0, (0 * 8)(RY1);
+ movq RT1, (1 * 8)(RY1);
+ /* CX_i = C_i xor Offset_i */
+ xorq RT0, RAB0;
+ xorq RT1, RCD0;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq 8(RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (2 * 8)(RX0), RAB1;
+ movq (3 * 8)(RX0), RCD1;
+ /* Store Offset_i */
+ movq RT0, (2 * 8)(RY1);
+ movq RT1, (3 * 8)(RY1);
+ /* PX_i = P_i xor Offset_i */
+ xorq RT0, RAB1;
+ xorq RT1, RCD1;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq 16(RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (4 * 8)(RX0), RAB2;
+ movq (5 * 8)(RX0), RCD2;
+ /* Store Offset_i */
+ movq RT0, (4 * 8)(RY1);
+ movq RT1, (5 * 8)(RY1);
+ /* PX_i = P_i xor Offset_i */
+ xorq RT0, RAB2;
+ xorq RT1, RCD2;
+
+ /* Store offset */
+ movq RT0, (0 * 8)(RX1);
+ movq RT1, (1 * 8)(RX1);
+
+ /* PX_i = DECIPHER(K, CX_i) */
+ call __twofish_dec_blk3;
+
+ movq (7 * 8)(%rsp), RX2; /*checksum*/
+ movq (6 * 8)(%rsp), RX1; /*dst*/
+
+ /* Load checksum */
+ movq (0 * 8)(RX2), RT0;
+ movq (1 * 8)(RX2), RT1;
+
+ /* P_i = PX_i xor Offset_i */
+ xorq RCD0, (0 * 8)(RX1);
+ xorq RAB0, (1 * 8)(RX1);
+ xorq RCD1, (2 * 8)(RX1);
+ xorq RAB1, (3 * 8)(RX1);
+ xorq RCD2, (4 * 8)(RX1);
+ xorq RAB2, (5 * 8)(RX1);
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+ xorq (0 * 8)(RX1), RT0;
+ xorq (1 * 8)(RX1), RT1;
+ xorq (2 * 8)(RX1), RT0;
+ xorq (3 * 8)(RX1), RT1;
+ xorq (4 * 8)(RX1), RT0;
+ xorq (5 * 8)(RX1), RT1;
+
+ /* Store checksum */
+ movq RT0, (0 * 8)(RX2);
+ movq RT1, (1 * 8)(RX2);
+
+ movq (0 * 8)(%rsp), %rbp;
+ movq (1 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ movq (4 * 8)(%rsp), %r14;
+ movq (5 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbp);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+ addq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-8 * 8);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_amd64_ocb_dec,.-_gcry_twofish_amd64_ocb_dec;)
+
+.align 8
+.globl _gcry_twofish_amd64_ocb_auth
+ELF(.type _gcry_twofish_amd64_ocb_auth,@function;)
+_gcry_twofish_amd64_ocb_auth:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: abuf (3 blocks)
+ * %rdx: offset
+ * %rcx: checksum
+ * %r8 : L pointers (void *L[3])
+ */
+ CFI_STARTPROC();
+ ENTER_SYSV_FUNC_PARAMS_5
+
+ subq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(8 * 8);
+ movq %rbp, (0 * 8)(%rsp);
+ movq %rbx, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ movq %r14, (4 * 8)(%rsp);
+ movq %r15, (5 * 8)(%rsp);
+ CFI_REL_OFFSET(%rbp, 0 * 8);
+ CFI_REL_OFFSET(%rbx, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+ CFI_REL_OFFSET(%r14, 4 * 8);
+ CFI_REL_OFFSET(%r15, 5 * 8);
+
+ movq %rcx, (6 * 8)(%rsp);
+ movq %rsi, RX0;
+ movq %rdx, RX1;
+ movq %r8, RY0;
+
+ /* Load offset */
+ movq (0 * 8)(RX1), RT0;
+ movq (1 * 8)(RX1), RT1;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq (RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (0 * 8)(RX0), RAB0;
+ movq (1 * 8)(RX0), RCD0;
+ /* PX_i = P_i xor Offset_i */
+ xorq RT0, RAB0;
+ xorq RT1, RCD0;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq 8(RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (2 * 8)(RX0), RAB1;
+ movq (3 * 8)(RX0), RCD1;
+ /* PX_i = P_i xor Offset_i */
+ xorq RT0, RAB1;
+ xorq RT1, RCD1;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ movq 16(RY0), RY2;
+ xorq (0 * 8)(RY2), RT0;
+ xorq (1 * 8)(RY2), RT1;
+ movq (4 * 8)(RX0), RAB2;
+ movq (5 * 8)(RX0), RCD2;
+ /* PX_i = P_i xor Offset_i */
+ xorq RT0, RAB2;
+ xorq RT1, RCD2;
+
+ /* Store offset */
+ movq RT0, (0 * 8)(RX1);
+ movq RT1, (1 * 8)(RX1);
+
+ /* C_i = ENCIPHER(K, PX_i) */
+ call __twofish_enc_blk3;
+
+ movq (6 * 8)(%rsp), RX1; /*checksum*/
+
+ /* Checksum_i = C_i xor Checksum_i */
+ xorq RCD0, RCD1;
+ xorq RAB0, RAB1;
+ xorq RCD1, RCD2;
+ xorq RAB1, RAB2;
+ xorq RCD2, (0 * 8)(RX1);
+ xorq RAB2, (1 * 8)(RX1);
+
+ movq (0 * 8)(%rsp), %rbp;
+ movq (1 * 8)(%rsp), %rbx;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ movq (4 * 8)(%rsp), %r14;
+ movq (5 * 8)(%rsp), %r15;
+ CFI_RESTORE(%rbp);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+ addq $(8 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-8 * 8);
+
+ EXIT_SYSV_FUNC
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_amd64_ocb_auth,.-_gcry_twofish_amd64_ocb_auth;)
+
+#endif /*USE_TWOFISH*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/twofish-arm.S b/comm/third_party/libgcrypt/cipher/twofish-arm.S
new file mode 100644
index 0000000000..2e1da6cd15
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/twofish-arm.S
@@ -0,0 +1,363 @@
+/* twofish-arm.S - ARM assembly implementation of Twofish cipher
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(__ARMEL__)
+#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+.text
+
+.syntax unified
+.arm
+
+/* structure of TWOFISH_context: */
+#define s0 0
+#define s1 ((s0) + 4 * 256)
+#define s2 ((s1) + 4 * 256)
+#define s3 ((s2) + 4 * 256)
+#define w ((s3) + 4 * 256)
+#define k ((w) + 4 * 8)
+
+/* register macros */
+#define CTX %r0
+#define CTXs0 %r0
+#define CTXs1 %r1
+#define CTXs3 %r7
+
+#define RA %r3
+#define RB %r4
+#define RC %r5
+#define RD %r6
+
+#define RX %r2
+#define RY %ip
+
+#define RMASK %lr
+
+#define RT0 %r8
+#define RT1 %r9
+#define RT2 %r10
+#define RT3 %r11
+
+/* helper macros */
+#define ldr_unaligned_le(rout, rsrc, offs, rtmp) \
+ ldrb rout, [rsrc, #((offs) + 0)]; \
+ ldrb rtmp, [rsrc, #((offs) + 1)]; \
+ orr rout, rout, rtmp, lsl #8; \
+ ldrb rtmp, [rsrc, #((offs) + 2)]; \
+ orr rout, rout, rtmp, lsl #16; \
+ ldrb rtmp, [rsrc, #((offs) + 3)]; \
+ orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_le(rin, rdst, offs, rtmp0, rtmp1) \
+ mov rtmp0, rin, lsr #8; \
+ strb rin, [rdst, #((offs) + 0)]; \
+ mov rtmp1, rin, lsr #16; \
+ strb rtmp0, [rdst, #((offs) + 1)]; \
+ mov rtmp0, rin, lsr #24; \
+ strb rtmp1, [rdst, #((offs) + 2)]; \
+ strb rtmp0, [rdst, #((offs) + 3)];
+
+#ifndef __ARMEL__
+ /* bswap on big-endian */
+ #define host_to_le(reg) \
+ rev reg, reg;
+ #define le_to_host(reg) \
+ rev reg, reg;
+#else
+ /* nop on little-endian */
+ #define host_to_le(reg) /*_*/
+ #define le_to_host(reg) /*_*/
+#endif
+
+#define ldr_input_aligned_le(rin, a, b, c, d) \
+ ldr a, [rin, #0]; \
+ ldr b, [rin, #4]; \
+ le_to_host(a); \
+ ldr c, [rin, #8]; \
+ le_to_host(b); \
+ ldr d, [rin, #12]; \
+ le_to_host(c); \
+ le_to_host(d);
+
+#define str_output_aligned_le(rout, a, b, c, d) \
+ le_to_host(a); \
+ le_to_host(b); \
+ str a, [rout, #0]; \
+ le_to_host(c); \
+ str b, [rout, #4]; \
+ le_to_host(d); \
+ str c, [rout, #8]; \
+ str d, [rout, #12];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+ /* unaligned word reads/writes allowed */
+ #define ldr_input_le(rin, ra, rb, rc, rd, rtmp) \
+ ldr_input_aligned_le(rin, ra, rb, rc, rd)
+
+ #define str_output_le(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+ str_output_aligned_le(rout, ra, rb, rc, rd)
+#else
+ /* need to handle unaligned reads/writes by byte reads */
+ #define ldr_input_le(rin, ra, rb, rc, rd, rtmp0) \
+ tst rin, #3; \
+ beq 1f; \
+ ldr_unaligned_le(ra, rin, 0, rtmp0); \
+ ldr_unaligned_le(rb, rin, 4, rtmp0); \
+ ldr_unaligned_le(rc, rin, 8, rtmp0); \
+ ldr_unaligned_le(rd, rin, 12, rtmp0); \
+ b 2f; \
+ 1:;\
+ ldr_input_aligned_le(rin, ra, rb, rc, rd); \
+ 2:;
+
+ #define str_output_le(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+ tst rout, #3; \
+ beq 1f; \
+ str_unaligned_le(ra, rout, 0, rtmp0, rtmp1); \
+ str_unaligned_le(rb, rout, 4, rtmp0, rtmp1); \
+ str_unaligned_le(rc, rout, 8, rtmp0, rtmp1); \
+ str_unaligned_le(rd, rout, 12, rtmp0, rtmp1); \
+ b 2f; \
+ 1:;\
+ str_output_aligned_le(rout, ra, rb, rc, rd); \
+ 2:;
+#endif
+
+/**********************************************************************
+ 1-way twofish
+ **********************************************************************/
+#define encrypt_round(a, b, rc, rd, n, ror_a, adj_a) \
+ and RT0, RMASK, b, lsr#(8 - 2); \
+ and RY, RMASK, b, lsr#(16 - 2); \
+ add RT0, RT0, #(s2 - s1); \
+ and RT1, RMASK, b, lsr#(24 - 2); \
+ ldr RY, [CTXs3, RY]; \
+ and RT2, RMASK, b, lsl#(2); \
+ ldr RT0, [CTXs1, RT0]; \
+ and RT3, RMASK, a, lsr#(16 - 2 + (adj_a)); \
+ ldr RT1, [CTXs0, RT1]; \
+ and RX, RMASK, a, lsr#(8 - 2 + (adj_a)); \
+ ldr RT2, [CTXs1, RT2]; \
+ add RT3, RT3, #(s2 - s1); \
+ ldr RX, [CTXs1, RX]; \
+ ror_a(a); \
+ \
+ eor RY, RY, RT0; \
+ ldr RT3, [CTXs1, RT3]; \
+ and RT0, RMASK, a, lsl#(2); \
+ eor RY, RY, RT1; \
+ and RT1, RMASK, a, lsr#(24 - 2); \
+ eor RY, RY, RT2; \
+ ldr RT0, [CTXs0, RT0]; \
+ eor RX, RX, RT3; \
+ ldr RT1, [CTXs3, RT1]; \
+ eor RX, RX, RT0; \
+ \
+ ldr RT3, [CTXs3, #(k - s3 + 8 * (n) + 4)]; \
+ eor RX, RX, RT1; \
+ ldr RT2, [CTXs3, #(k - s3 + 8 * (n))]; \
+ \
+ add RT0, RX, RY, lsl #1; \
+ add RX, RX, RY; \
+ add RT0, RT0, RT3; \
+ add RX, RX, RT2; \
+ eor rd, RT0, rd, ror #31; \
+ eor rc, rc, RX;
+
+#define dummy(x) /*_*/
+
+#define ror1(r) \
+ ror r, r, #1;
+
+#define decrypt_round(a, b, rc, rd, n, ror_b, adj_b) \
+ and RT3, RMASK, b, lsl#(2 - (adj_b)); \
+ and RT1, RMASK, b, lsr#(8 - 2 + (adj_b)); \
+ ror_b(b); \
+ and RT2, RMASK, a, lsl#(2); \
+ and RT0, RMASK, a, lsr#(8 - 2); \
+ \
+ ldr RY, [CTXs1, RT3]; \
+ add RT1, RT1, #(s2 - s1); \
+ ldr RX, [CTXs0, RT2]; \
+ and RT3, RMASK, b, lsr#(16 - 2); \
+ ldr RT1, [CTXs1, RT1]; \
+ and RT2, RMASK, a, lsr#(16 - 2); \
+ ldr RT0, [CTXs1, RT0]; \
+ \
+ add RT2, RT2, #(s2 - s1); \
+ ldr RT3, [CTXs3, RT3]; \
+ eor RY, RY, RT1; \
+ \
+ and RT1, RMASK, b, lsr#(24 - 2); \
+ eor RX, RX, RT0; \
+ ldr RT2, [CTXs1, RT2]; \
+ and RT0, RMASK, a, lsr#(24 - 2); \
+ \
+ ldr RT1, [CTXs0, RT1]; \
+ \
+ eor RY, RY, RT3; \
+ ldr RT0, [CTXs3, RT0]; \
+ eor RX, RX, RT2; \
+ eor RY, RY, RT1; \
+ \
+ ldr RT1, [CTXs3, #(k - s3 + 8 * (n) + 4)]; \
+ eor RX, RX, RT0; \
+ ldr RT2, [CTXs3, #(k - s3 + 8 * (n))]; \
+ \
+ add RT0, RX, RY, lsl #1; \
+ add RX, RX, RY; \
+ add RT0, RT0, RT1; \
+ add RX, RX, RT2; \
+ eor rd, rd, RT0; \
+ eor rc, RX, rc, ror #31;
+
+#define first_encrypt_cycle(nc) \
+ encrypt_round(RA, RB, RC, RD, (nc) * 2, dummy, 0); \
+ encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1);
+
+#define encrypt_cycle(nc) \
+ encrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+ encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1);
+
+#define last_encrypt_cycle(nc) \
+ encrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+ encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+ ror1(RA);
+
+#define first_decrypt_cycle(nc) \
+ decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, dummy, 0); \
+ decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1);
+
+#define decrypt_cycle(nc) \
+ decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+ decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1);
+
+#define last_decrypt_cycle(nc) \
+ decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+ decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+ ror1(RD);
+
+.align 3
+.globl _gcry_twofish_arm_encrypt_block
+.type _gcry_twofish_arm_encrypt_block,%function;
+
+_gcry_twofish_arm_encrypt_block:
+ /* input:
+ * %r0: ctx
+ * %r1: dst
+ * %r2: src
+ */
+ push {%r1, %r4-%r11, %ip, %lr};
+
+ add RY, CTXs0, #w;
+
+ ldr_input_le(%r2, RA, RB, RC, RD, RT0);
+
+ /* Input whitening */
+ ldm RY, {RT0, RT1, RT2, RT3};
+ add CTXs3, CTXs0, #(s3 - s0);
+ add CTXs1, CTXs0, #(s1 - s0);
+ mov RMASK, #(0xff << 2);
+ eor RA, RA, RT0;
+ eor RB, RB, RT1;
+ eor RC, RC, RT2;
+ eor RD, RD, RT3;
+
+ first_encrypt_cycle(0);
+ encrypt_cycle(1);
+ encrypt_cycle(2);
+ encrypt_cycle(3);
+ encrypt_cycle(4);
+ encrypt_cycle(5);
+ encrypt_cycle(6);
+ last_encrypt_cycle(7);
+
+ add RY, CTXs3, #(w + 4*4 - s3);
+ pop {%r1}; /* dst */
+
+ /* Output whitening */
+ ldm RY, {RT0, RT1, RT2, RT3};
+ eor RC, RC, RT0;
+ eor RD, RD, RT1;
+ eor RA, RA, RT2;
+ eor RB, RB, RT3;
+
+ str_output_le(%r1, RC, RD, RA, RB, RT0, RT1);
+
+ pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_twofish_arm_encrypt_block,.-_gcry_twofish_arm_encrypt_block;
+
+.align 3
+.globl _gcry_twofish_arm_decrypt_block
+.type _gcry_twofish_arm_decrypt_block,%function;
+
+_gcry_twofish_arm_decrypt_block:
+ /* input:
+ * %r0: ctx
+ * %r1: dst
+ * %r2: src
+ */
+ push {%r1, %r4-%r11, %ip, %lr};
+
+ add CTXs3, CTXs0, #(s3 - s0);
+
+ ldr_input_le(%r2, RC, RD, RA, RB, RT0);
+
+ add RY, CTXs3, #(w + 4*4 - s3);
+ add CTXs3, CTXs0, #(s3 - s0);
+
+ /* Input whitening */
+ ldm RY, {RT0, RT1, RT2, RT3};
+ add CTXs1, CTXs0, #(s1 - s0);
+ mov RMASK, #(0xff << 2);
+ eor RC, RC, RT0;
+ eor RD, RD, RT1;
+ eor RA, RA, RT2;
+ eor RB, RB, RT3;
+
+ first_decrypt_cycle(7);
+ decrypt_cycle(6);
+ decrypt_cycle(5);
+ decrypt_cycle(4);
+ decrypt_cycle(3);
+ decrypt_cycle(2);
+ decrypt_cycle(1);
+ last_decrypt_cycle(0);
+
+ add RY, CTXs0, #w;
+ pop {%r1}; /* dst */
+
+ /* Output whitening */
+ ldm RY, {RT0, RT1, RT2, RT3};
+ eor RA, RA, RT0;
+ eor RB, RB, RT1;
+ eor RC, RC, RT2;
+ eor RD, RD, RT3;
+
+ str_output_le(%r1, RA, RB, RC, RD, RT0, RT1);
+
+ pop {%r4-%r11, %ip, %pc};
+.size _gcry_twofish_arm_decrypt_block,.-_gcry_twofish_arm_decrypt_block;
+
+#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
+#endif /*__ARMEL__*/
diff --git a/comm/third_party/libgcrypt/cipher/twofish-avx2-amd64.S b/comm/third_party/libgcrypt/cipher/twofish-avx2-amd64.S
new file mode 100644
index 0000000000..74cad35589
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/twofish-avx2-amd64.S
@@ -0,0 +1,1048 @@
+/* twofish-avx2-amd64.S - AMD64/AVX2 assembly implementation of Twofish cipher
+ *
+ * Copyright (C) 2013-2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_TWOFISH) && \
+ defined(ENABLE_AVX2_SUPPORT)
+
+#include "asm-common-amd64.h"
+
+.text
+
+/* structure of TWOFISH_context: */
+#define s0 0
+#define s1 ((s0) + 4 * 256)
+#define s2 ((s1) + 4 * 256)
+#define s3 ((s2) + 4 * 256)
+#define w ((s3) + 4 * 256)
+#define k ((w) + 4 * 8)
+
+/* register macros */
+#define CTX %rdi
+
+#define RROUND %rbp
+#define RROUNDd %ebp
+#define RS0 CTX
+#define RS1 %r8
+#define RS2 %r9
+#define RS3 %r10
+#define RK %r11
+#define RW %rax
+
+#define RA0 %ymm8
+#define RB0 %ymm9
+#define RC0 %ymm10
+#define RD0 %ymm11
+#define RA1 %ymm12
+#define RB1 %ymm13
+#define RC1 %ymm14
+#define RD1 %ymm15
+
+/* temp regs */
+#define RX0 %ymm0
+#define RY0 %ymm1
+#define RX1 %ymm2
+#define RY1 %ymm3
+#define RT0 %ymm4
+#define RIDX %ymm5
+
+#define RX0x %xmm0
+#define RY0x %xmm1
+#define RX1x %xmm2
+#define RY1x %xmm3
+#define RT0x %xmm4
+#define RIDXx %xmm5
+
+#define RTMP0 RX0
+#define RTMP0x RX0x
+#define RTMP1 RX1
+#define RTMP1x RX1x
+#define RTMP2 RY0
+#define RTMP2x RY0x
+#define RTMP3 RY1
+#define RTMP3x RY1x
+#define RTMP4 RIDX
+#define RTMP4x RIDXx
+
+/* vpgatherdd mask and '-1' */
+#define RNOT %ymm6
+#define RNOTx %xmm6
+
+/* byte mask, (-1 >> 24) */
+#define RBYTE %ymm7
+
+/**********************************************************************
+ 16-way AVX2 twofish
+ **********************************************************************/
+#define init_round_constants() \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ leaq k(CTX), RK; \
+ leaq w(CTX), RW; \
+ vpsrld $24, RNOT, RBYTE; \
+ leaq s1(CTX), RS1; \
+ leaq s2(CTX), RS2; \
+ leaq s3(CTX), RS3; \
+
+#define g16(ab, rs0, rs1, rs2, rs3, xy) \
+ vpand RBYTE, ab ## 0, RIDX; \
+ vpgatherdd RNOT, (rs0, RIDX, 4), xy ## 0; \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ \
+ vpand RBYTE, ab ## 1, RIDX; \
+ vpgatherdd RNOT, (rs0, RIDX, 4), xy ## 1; \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ \
+ vpsrld $8, ab ## 0, RIDX; \
+ vpand RBYTE, RIDX, RIDX; \
+ vpgatherdd RNOT, (rs1, RIDX, 4), RT0; \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ vpxor RT0, xy ## 0, xy ## 0; \
+ \
+ vpsrld $8, ab ## 1, RIDX; \
+ vpand RBYTE, RIDX, RIDX; \
+ vpgatherdd RNOT, (rs1, RIDX, 4), RT0; \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ vpxor RT0, xy ## 1, xy ## 1; \
+ \
+ vpsrld $16, ab ## 0, RIDX; \
+ vpand RBYTE, RIDX, RIDX; \
+ vpgatherdd RNOT, (rs2, RIDX, 4), RT0; \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ vpxor RT0, xy ## 0, xy ## 0; \
+ \
+ vpsrld $16, ab ## 1, RIDX; \
+ vpand RBYTE, RIDX, RIDX; \
+ vpgatherdd RNOT, (rs2, RIDX, 4), RT0; \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ vpxor RT0, xy ## 1, xy ## 1; \
+ \
+ vpsrld $24, ab ## 0, RIDX; \
+ vpgatherdd RNOT, (rs3, RIDX, 4), RT0; \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ vpxor RT0, xy ## 0, xy ## 0; \
+ \
+ vpsrld $24, ab ## 1, RIDX; \
+ vpgatherdd RNOT, (rs3, RIDX, 4), RT0; \
+ vpcmpeqd RNOT, RNOT, RNOT; \
+ vpxor RT0, xy ## 1, xy ## 1;
+
+#define g1_16(a, x) \
+ g16(a, RS0, RS1, RS2, RS3, x);
+
+#define g2_16(b, y) \
+ g16(b, RS1, RS2, RS3, RS0, y);
+
+#define encrypt_round_end16(a, b, c, d, nk, r) \
+ vpaddd RY0, RX0, RX0; \
+ vpaddd RX0, RY0, RY0; \
+ vpbroadcastd ((nk)+((r)*8))(RK), RT0; \
+ vpaddd RT0, RX0, RX0; \
+ vpbroadcastd 4+((nk)+((r)*8))(RK), RT0; \
+ vpaddd RT0, RY0, RY0; \
+ \
+ vpxor RY0, d ## 0, d ## 0; \
+ \
+ vpxor RX0, c ## 0, c ## 0; \
+ vpsrld $1, c ## 0, RT0; \
+ vpslld $31, c ## 0, c ## 0; \
+ vpor RT0, c ## 0, c ## 0; \
+ \
+ vpaddd RY1, RX1, RX1; \
+ vpaddd RX1, RY1, RY1; \
+ vpbroadcastd ((nk)+((r)*8))(RK), RT0; \
+ vpaddd RT0, RX1, RX1; \
+ vpbroadcastd 4+((nk)+((r)*8))(RK), RT0; \
+ vpaddd RT0, RY1, RY1; \
+ \
+ vpxor RY1, d ## 1, d ## 1; \
+ \
+ vpxor RX1, c ## 1, c ## 1; \
+ vpsrld $1, c ## 1, RT0; \
+ vpslld $31, c ## 1, c ## 1; \
+ vpor RT0, c ## 1, c ## 1; \
+
+#define encrypt_round16(a, b, c, d, nk, r) \
+ g2_16(b, RY); \
+ \
+ vpslld $1, b ## 0, RT0; \
+ vpsrld $31, b ## 0, b ## 0; \
+ vpor RT0, b ## 0, b ## 0; \
+ \
+ vpslld $1, b ## 1, RT0; \
+ vpsrld $31, b ## 1, b ## 1; \
+ vpor RT0, b ## 1, b ## 1; \
+ \
+ g1_16(a, RX); \
+ \
+ encrypt_round_end16(a, b, c, d, nk, r);
+
+#define encrypt_round_first16(a, b, c, d, nk, r) \
+ vpslld $1, d ## 0, RT0; \
+ vpsrld $31, d ## 0, d ## 0; \
+ vpor RT0, d ## 0, d ## 0; \
+ \
+ vpslld $1, d ## 1, RT0; \
+ vpsrld $31, d ## 1, d ## 1; \
+ vpor RT0, d ## 1, d ## 1; \
+ \
+ encrypt_round16(a, b, c, d, nk, r);
+
+#define encrypt_round_last16(a, b, c, d, nk, r) \
+ g2_16(b, RY); \
+ \
+ g1_16(a, RX); \
+ \
+ encrypt_round_end16(a, b, c, d, nk, r);
+
+#define decrypt_round_end16(a, b, c, d, nk, r) \
+ vpaddd RY0, RX0, RX0; \
+ vpaddd RX0, RY0, RY0; \
+ vpbroadcastd ((nk)+((r)*8))(RK), RT0; \
+ vpaddd RT0, RX0, RX0; \
+ vpbroadcastd 4+((nk)+((r)*8))(RK), RT0; \
+ vpaddd RT0, RY0, RY0; \
+ \
+ vpxor RX0, c ## 0, c ## 0; \
+ \
+ vpxor RY0, d ## 0, d ## 0; \
+ vpsrld $1, d ## 0, RT0; \
+ vpslld $31, d ## 0, d ## 0; \
+ vpor RT0, d ## 0, d ## 0; \
+ \
+ vpaddd RY1, RX1, RX1; \
+ vpaddd RX1, RY1, RY1; \
+ vpbroadcastd ((nk)+((r)*8))(RK), RT0; \
+ vpaddd RT0, RX1, RX1; \
+ vpbroadcastd 4+((nk)+((r)*8))(RK), RT0; \
+ vpaddd RT0, RY1, RY1; \
+ \
+ vpxor RX1, c ## 1, c ## 1; \
+ \
+ vpxor RY1, d ## 1, d ## 1; \
+ vpsrld $1, d ## 1, RT0; \
+ vpslld $31, d ## 1, d ## 1; \
+ vpor RT0, d ## 1, d ## 1;
+
+#define decrypt_round16(a, b, c, d, nk, r) \
+ g1_16(a, RX); \
+ \
+ vpslld $1, a ## 0, RT0; \
+ vpsrld $31, a ## 0, a ## 0; \
+ vpor RT0, a ## 0, a ## 0; \
+ \
+ vpslld $1, a ## 1, RT0; \
+ vpsrld $31, a ## 1, a ## 1; \
+ vpor RT0, a ## 1, a ## 1; \
+ \
+ g2_16(b, RY); \
+ \
+ decrypt_round_end16(a, b, c, d, nk, r);
+
+#define decrypt_round_first16(a, b, c, d, nk, r) \
+ vpslld $1, c ## 0, RT0; \
+ vpsrld $31, c ## 0, c ## 0; \
+ vpor RT0, c ## 0, c ## 0; \
+ \
+ vpslld $1, c ## 1, RT0; \
+ vpsrld $31, c ## 1, c ## 1; \
+ vpor RT0, c ## 1, c ## 1; \
+ \
+ decrypt_round16(a, b, c, d, nk, r)
+
+#define decrypt_round_last16(a, b, c, d, nk, r) \
+ g1_16(a, RX); \
+ \
+ g2_16(b, RY); \
+ \
+ decrypt_round_end16(a, b, c, d, nk, r);
+
+#define encrypt_cycle16(r) \
+ encrypt_round16(RA, RB, RC, RD, 0, r); \
+ encrypt_round16(RC, RD, RA, RB, 8, r);
+
+#define encrypt_cycle_first16(r) \
+ encrypt_round_first16(RA, RB, RC, RD, 0, r); \
+ encrypt_round16(RC, RD, RA, RB, 8, r);
+
+#define encrypt_cycle_last16(r) \
+ encrypt_round16(RA, RB, RC, RD, 0, r); \
+ encrypt_round_last16(RC, RD, RA, RB, 8, r);
+
+#define decrypt_cycle16(r) \
+ decrypt_round16(RC, RD, RA, RB, 8, r); \
+ decrypt_round16(RA, RB, RC, RD, 0, r);
+
+#define decrypt_cycle_first16(r) \
+ decrypt_round_first16(RC, RD, RA, RB, 8, r); \
+ decrypt_round16(RA, RB, RC, RD, 0, r);
+
+#define decrypt_cycle_last16(r) \
+ decrypt_round16(RC, RD, RA, RB, 8, r); \
+ decrypt_round_last16(RA, RB, RC, RD, 0, r);
+
+#define transpose_4x4(x0,x1,x2,x3,t1,t2) \
+ vpunpckhdq x1, x0, t2; \
+ vpunpckldq x1, x0, x0; \
+ \
+ vpunpckldq x3, x2, t1; \
+ vpunpckhdq x3, x2, x2; \
+ \
+ vpunpckhqdq t1, x0, x1; \
+ vpunpcklqdq t1, x0, x0; \
+ \
+ vpunpckhqdq x2, t2, x3; \
+ vpunpcklqdq x2, t2, x2;
+
+#define read_blocks8(offs,a,b,c,d) \
+ vmovdqu 16*offs(RIO), a; \
+ vmovdqu 16*offs+32(RIO), b; \
+ vmovdqu 16*offs+64(RIO), c; \
+ vmovdqu 16*offs+96(RIO), d; \
+ \
+ transpose_4x4(a, b, c, d, RX0, RY0);
+
+#define write_blocks8(offs,a,b,c,d) \
+ transpose_4x4(a, b, c, d, RX0, RY0); \
+ \
+ vmovdqu a, 16*offs(RIO); \
+ vmovdqu b, 16*offs+32(RIO); \
+ vmovdqu c, 16*offs+64(RIO); \
+ vmovdqu d, 16*offs+96(RIO);
+
+#define inpack_enc8(a,b,c,d) \
+ vpbroadcastd 4*0(RW), RT0; \
+ vpxor RT0, a, a; \
+ \
+ vpbroadcastd 4*1(RW), RT0; \
+ vpxor RT0, b, b; \
+ \
+ vpbroadcastd 4*2(RW), RT0; \
+ vpxor RT0, c, c; \
+ \
+ vpbroadcastd 4*3(RW), RT0; \
+ vpxor RT0, d, d;
+
+#define outunpack_enc8(a,b,c,d) \
+ vpbroadcastd 4*4(RW), RX0; \
+ vpbroadcastd 4*5(RW), RY0; \
+ vpxor RX0, c, RX0; \
+ vpxor RY0, d, RY0; \
+ \
+ vpbroadcastd 4*6(RW), RT0; \
+ vpxor RT0, a, c; \
+ vpbroadcastd 4*7(RW), RT0; \
+ vpxor RT0, b, d; \
+ \
+ vmovdqa RX0, a; \
+ vmovdqa RY0, b;
+
+#define inpack_dec8(a,b,c,d) \
+ vpbroadcastd 4*4(RW), RX0; \
+ vpbroadcastd 4*5(RW), RY0; \
+ vpxor RX0, a, RX0; \
+ vpxor RY0, b, RY0; \
+ \
+ vpbroadcastd 4*6(RW), RT0; \
+ vpxor RT0, c, a; \
+ vpbroadcastd 4*7(RW), RT0; \
+ vpxor RT0, d, b; \
+ \
+ vmovdqa RX0, c; \
+ vmovdqa RY0, d;
+
+#define outunpack_dec8(a,b,c,d) \
+ vpbroadcastd 4*0(RW), RT0; \
+ vpxor RT0, a, a; \
+ \
+ vpbroadcastd 4*1(RW), RT0; \
+ vpxor RT0, b, b; \
+ \
+ vpbroadcastd 4*2(RW), RT0; \
+ vpxor RT0, c, c; \
+ \
+ vpbroadcastd 4*3(RW), RT0; \
+ vpxor RT0, d, d;
+
+#define transpose4x4_16(a,b,c,d) \
+ transpose_4x4(a ## 0, b ## 0, c ## 0, d ## 0, RX0, RY0); \
+ transpose_4x4(a ## 1, b ## 1, c ## 1, d ## 1, RX0, RY0);
+
+#define inpack_enc16(a,b,c,d) \
+ inpack_enc8(a ## 0, b ## 0, c ## 0, d ## 0); \
+ inpack_enc8(a ## 1, b ## 1, c ## 1, d ## 1);
+
+#define outunpack_enc16(a,b,c,d) \
+ outunpack_enc8(a ## 0, b ## 0, c ## 0, d ## 0); \
+ outunpack_enc8(a ## 1, b ## 1, c ## 1, d ## 1);
+
+#define inpack_dec16(a,b,c,d) \
+ inpack_dec8(a ## 0, b ## 0, c ## 0, d ## 0); \
+ inpack_dec8(a ## 1, b ## 1, c ## 1, d ## 1);
+
+#define outunpack_dec16(a,b,c,d) \
+ outunpack_dec8(a ## 0, b ## 0, c ## 0, d ## 0); \
+ outunpack_dec8(a ## 1, b ## 1, c ## 1, d ## 1);
+
+.align 8
+ELF(.type __twofish_enc_blk16,@function;)
+__twofish_enc_blk16:
+ /* input:
+ * %rdi: ctx, CTX
+ * RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1: sixteen parallel
+ * plaintext blocks
+ * output:
+ * RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1: sixteen parallel
+ * ciphertext blocks
+ */
+ CFI_STARTPROC();
+ init_round_constants();
+
+ transpose4x4_16(RA, RB, RC, RD);
+ inpack_enc16(RA, RB, RC, RD);
+
+ encrypt_cycle_first16(0);
+ encrypt_cycle16(2);
+ encrypt_cycle16(4);
+ encrypt_cycle16(6);
+ encrypt_cycle16(8);
+ encrypt_cycle16(10);
+ encrypt_cycle16(12);
+ encrypt_cycle_last16(14);
+
+ outunpack_enc16(RA, RB, RC, RD);
+ transpose4x4_16(RA, RB, RC, RD);
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __twofish_enc_blk16,.-__twofish_enc_blk16;)
+
+.align 8
+ELF(.type __twofish_dec_blk16,@function;)
+__twofish_dec_blk16:
+ /* input:
+ * %rdi: ctx, CTX
+ * RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1: sixteen parallel
+ * plaintext blocks
+ * output:
+ * RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1: sixteen parallel
+ * ciphertext blocks
+ */
+ CFI_STARTPROC();
+ init_round_constants();
+
+ transpose4x4_16(RA, RB, RC, RD);
+ inpack_dec16(RA, RB, RC, RD);
+
+ decrypt_cycle_first16(14);
+ decrypt_cycle16(12);
+ decrypt_cycle16(10);
+ decrypt_cycle16(8);
+ decrypt_cycle16(6);
+ decrypt_cycle16(4);
+ decrypt_cycle16(2);
+ decrypt_cycle_last16(0);
+
+ outunpack_dec16(RA, RB, RC, RD);
+ transpose4x4_16(RA, RB, RC, RD);
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size __twofish_dec_blk16,.-__twofish_dec_blk16;)
+
+#define inc_le128(x, minus_one, tmp) \
+ vpcmpeqq minus_one, x, tmp; \
+ vpsubq minus_one, x, x; \
+ vpslldq $8, tmp, tmp; \
+ vpsubq tmp, x, x;
+
+.align 8
+.globl _gcry_twofish_avx2_ctr_enc
+ELF(.type _gcry_twofish_avx2_ctr_enc,@function;)
+_gcry_twofish_avx2_ctr_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv (big endian, 128bit)
+ */
+ CFI_STARTPROC();
+
+ movq 8(%rcx), %rax;
+ bswapq %rax;
+
+ vzeroupper;
+
+ vbroadcasti128 .Lbswap128_mask rRIP, RTMP3;
+ vpcmpeqd RNOT, RNOT, RNOT;
+ vpsrldq $8, RNOT, RNOT; /* ab: -1:0 ; cd: -1:0 */
+ vpaddq RNOT, RNOT, RTMP2; /* ab: -2:0 ; cd: -2:0 */
+
+ /* load IV and byteswap */
+ vmovdqu (%rcx), RTMP4x;
+ vpshufb RTMP3x, RTMP4x, RTMP4x;
+ vmovdqa RTMP4x, RTMP0x;
+ inc_le128(RTMP4x, RNOTx, RTMP1x);
+ vinserti128 $1, RTMP4x, RTMP0, RTMP0;
+ vpshufb RTMP3, RTMP0, RA0; /* +1 ; +0 */
+
+ /* check need for handling 64-bit overflow and carry */
+ cmpq $(0xffffffffffffffff - 16), %rax;
+ ja .Lhandle_ctr_carry;
+
+ /* construct IVs */
+ vpsubq RTMP2, RTMP0, RTMP0; /* +3 ; +2 */
+ vpshufb RTMP3, RTMP0, RB0;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +5 ; +4 */
+ vpshufb RTMP3, RTMP0, RC0;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +7 ; +6 */
+ vpshufb RTMP3, RTMP0, RD0;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +9 ; +8 */
+ vpshufb RTMP3, RTMP0, RA1;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +11 ; +10 */
+ vpshufb RTMP3, RTMP0, RB1;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +13 ; +12 */
+ vpshufb RTMP3, RTMP0, RC1;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +15 ; +14 */
+ vpshufb RTMP3, RTMP0, RD1;
+ vpsubq RTMP2, RTMP0, RTMP0; /* +16 */
+ vpshufb RTMP3x, RTMP0x, RTMP0x;
+
+ jmp .Lctr_carry_done;
+
+.Lhandle_ctr_carry:
+ /* construct IVs */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB0; /* +3 ; +2 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RC0; /* +5 ; +4 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RD0; /* +7 ; +6 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RA1; /* +9 ; +8 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RB1; /* +11 ; +10 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RC1; /* +13 ; +12 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vpshufb RTMP3, RTMP0, RD1; /* +15 ; +14 */
+ inc_le128(RTMP0, RNOT, RTMP1);
+ vextracti128 $1, RTMP0, RTMP0x;
+ vpshufb RTMP3x, RTMP0x, RTMP0x; /* +16 */
+
+.align 4
+.Lctr_carry_done:
+ /* store new IV */
+ vmovdqu RTMP0x, (%rcx);
+
+ call __twofish_enc_blk16;
+
+ vpxor (0 * 32)(%rdx), RA0, RA0;
+ vpxor (1 * 32)(%rdx), RB0, RB0;
+ vpxor (2 * 32)(%rdx), RC0, RC0;
+ vpxor (3 * 32)(%rdx), RD0, RD0;
+ vpxor (4 * 32)(%rdx), RA1, RA1;
+ vpxor (5 * 32)(%rdx), RB1, RB1;
+ vpxor (6 * 32)(%rdx), RC1, RC1;
+ vpxor (7 * 32)(%rdx), RD1, RD1;
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RB0, (1 * 32)(%rsi);
+ vmovdqu RC0, (2 * 32)(%rsi);
+ vmovdqu RD0, (3 * 32)(%rsi);
+ vmovdqu RA1, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RC1, (6 * 32)(%rsi);
+ vmovdqu RD1, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_avx2_ctr_enc,.-_gcry_twofish_avx2_ctr_enc;)
+
+.align 8
+.globl _gcry_twofish_avx2_cbc_dec
+ELF(.type _gcry_twofish_avx2_cbc_dec,@function;)
+_gcry_twofish_avx2_cbc_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ vmovdqu (0 * 32)(%rdx), RA0;
+ vmovdqu (1 * 32)(%rdx), RB0;
+ vmovdqu (2 * 32)(%rdx), RC0;
+ vmovdqu (3 * 32)(%rdx), RD0;
+ vmovdqu (4 * 32)(%rdx), RA1;
+ vmovdqu (5 * 32)(%rdx), RB1;
+ vmovdqu (6 * 32)(%rdx), RC1;
+ vmovdqu (7 * 32)(%rdx), RD1;
+
+ call __twofish_dec_blk16;
+
+ vmovdqu (%rcx), RNOTx;
+ vinserti128 $1, (%rdx), RNOT, RNOT;
+ vpxor RNOT, RA0, RA0;
+ vpxor (0 * 32 + 16)(%rdx), RB0, RB0;
+ vpxor (1 * 32 + 16)(%rdx), RC0, RC0;
+ vpxor (2 * 32 + 16)(%rdx), RD0, RD0;
+ vpxor (3 * 32 + 16)(%rdx), RA1, RA1;
+ vpxor (4 * 32 + 16)(%rdx), RB1, RB1;
+ vpxor (5 * 32 + 16)(%rdx), RC1, RC1;
+ vpxor (6 * 32 + 16)(%rdx), RD1, RD1;
+ vmovdqu (7 * 32 + 16)(%rdx), RNOTx;
+ vmovdqu RNOTx, (%rcx); /* store new IV */
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RB0, (1 * 32)(%rsi);
+ vmovdqu RC0, (2 * 32)(%rsi);
+ vmovdqu RD0, (3 * 32)(%rsi);
+ vmovdqu RA1, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RC1, (6 * 32)(%rsi);
+ vmovdqu RD1, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_avx2_cbc_dec,.-_gcry_twofish_avx2_cbc_dec;)
+
+.align 8
+.globl _gcry_twofish_avx2_cfb_dec
+ELF(.type _gcry_twofish_avx2_cfb_dec,@function;)
+_gcry_twofish_avx2_cfb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: iv
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ /* Load input */
+ vmovdqu (%rcx), RNOTx;
+ vinserti128 $1, (%rdx), RNOT, RA0;
+ vmovdqu (0 * 32 + 16)(%rdx), RB0;
+ vmovdqu (1 * 32 + 16)(%rdx), RC0;
+ vmovdqu (2 * 32 + 16)(%rdx), RD0;
+ vmovdqu (3 * 32 + 16)(%rdx), RA1;
+ vmovdqu (4 * 32 + 16)(%rdx), RB1;
+ vmovdqu (5 * 32 + 16)(%rdx), RC1;
+ vmovdqu (6 * 32 + 16)(%rdx), RD1;
+
+ /* Update IV */
+ vmovdqu (7 * 32 + 16)(%rdx), RNOTx;
+ vmovdqu RNOTx, (%rcx);
+
+ call __twofish_enc_blk16;
+
+ vpxor (0 * 32)(%rdx), RA0, RA0;
+ vpxor (1 * 32)(%rdx), RB0, RB0;
+ vpxor (2 * 32)(%rdx), RC0, RC0;
+ vpxor (3 * 32)(%rdx), RD0, RD0;
+ vpxor (4 * 32)(%rdx), RA1, RA1;
+ vpxor (5 * 32)(%rdx), RB1, RB1;
+ vpxor (6 * 32)(%rdx), RC1, RC1;
+ vpxor (7 * 32)(%rdx), RD1, RD1;
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RB0, (1 * 32)(%rsi);
+ vmovdqu RC0, (2 * 32)(%rsi);
+ vmovdqu RD0, (3 * 32)(%rsi);
+ vmovdqu RA1, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RC1, (6 * 32)(%rsi);
+ vmovdqu RD1, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_avx2_cfb_dec,.-_gcry_twofish_avx2_cfb_dec;)
+
+.align 8
+.globl _gcry_twofish_avx2_ocb_enc
+ELF(.type _gcry_twofish_avx2_ocb_enc,@function;)
+
+_gcry_twofish_avx2_ocb_enc:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rcx), RTMP0x;
+ vmovdqu (%r8), RTMP1x;
+
+ /* 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) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rdx), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RTMP1, RTMP1; \
+ vpxor yreg, RNOT, yreg; \
+ vmovdqu RNOT, (n * 32)(%rsi);
+
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RB0);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(2, %r10, %r11, RC0);
+ OCB_INPUT(3, %r12, %r13, RD0);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %r11, RA1);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(6, %r10, %r11, RC1);
+ OCB_INPUT(7, %r12, %r13, RD1);
+#undef OCB_INPUT
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vmovdqu RTMP0x, (%rcx);
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%r8);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __twofish_enc_blk16;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vpxor (0 * 32)(%rsi), RA0, RA0;
+ vpxor (1 * 32)(%rsi), RB0, RB0;
+ vpxor (2 * 32)(%rsi), RC0, RC0;
+ vpxor (3 * 32)(%rsi), RD0, RD0;
+ vpxor (4 * 32)(%rsi), RA1, RA1;
+ vpxor (5 * 32)(%rsi), RB1, RB1;
+ vpxor (6 * 32)(%rsi), RC1, RC1;
+ vpxor (7 * 32)(%rsi), RD1, RD1;
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vmovdqu RB0, (1 * 32)(%rsi);
+ vmovdqu RC0, (2 * 32)(%rsi);
+ vmovdqu RD0, (3 * 32)(%rsi);
+ vmovdqu RA1, (4 * 32)(%rsi);
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vmovdqu RC1, (6 * 32)(%rsi);
+ vmovdqu RD1, (7 * 32)(%rsi);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_avx2_ocb_enc,.-_gcry_twofish_avx2_ocb_enc;)
+
+.align 8
+.globl _gcry_twofish_avx2_ocb_dec
+ELF(.type _gcry_twofish_avx2_ocb_dec,@function;)
+
+_gcry_twofish_avx2_ocb_dec:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+ * %rdx: src (16 blocks)
+ * %rcx: offset
+ * %r8 : checksum
+ * %r9 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rcx), RTMP0x;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rdx), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RNOT, yreg; \
+ vmovdqu RNOT, (n * 32)(%rsi);
+
+ movq (0 * 8)(%r9), %r10;
+ movq (1 * 8)(%r9), %r11;
+ movq (2 * 8)(%r9), %r12;
+ movq (3 * 8)(%r9), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RB0);
+ movq (4 * 8)(%r9), %r10;
+ movq (5 * 8)(%r9), %r11;
+ movq (6 * 8)(%r9), %r12;
+ movq (7 * 8)(%r9), %r13;
+ OCB_INPUT(2, %r10, %r11, RC0);
+ OCB_INPUT(3, %r12, %r13, RD0);
+ movq (8 * 8)(%r9), %r10;
+ movq (9 * 8)(%r9), %r11;
+ movq (10 * 8)(%r9), %r12;
+ movq (11 * 8)(%r9), %r13;
+ OCB_INPUT(4, %r10, %r11, RA1);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r9), %r10;
+ movq (13 * 8)(%r9), %r11;
+ movq (14 * 8)(%r9), %r12;
+ movq (15 * 8)(%r9), %r13;
+ OCB_INPUT(6, %r10, %r11, RC1);
+ OCB_INPUT(7, %r12, %r13, RD1);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0x, (%rcx);
+ mov %r8, %rcx
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __twofish_dec_blk16;
+
+ vmovdqu (%rcx), RTMP1x;
+
+ vpxor (0 * 32)(%rsi), RA0, RA0;
+ vpxor (1 * 32)(%rsi), RB0, RB0;
+ vpxor (2 * 32)(%rsi), RC0, RC0;
+ vpxor (3 * 32)(%rsi), RD0, RD0;
+ vpxor (4 * 32)(%rsi), RA1, RA1;
+ vpxor (5 * 32)(%rsi), RB1, RB1;
+ vpxor (6 * 32)(%rsi), RC1, RC1;
+ vpxor (7 * 32)(%rsi), RD1, RD1;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ /* Checksum_i = Checksum_{i-1} xor P_i */
+
+ vmovdqu RA0, (0 * 32)(%rsi);
+ vpxor RA0, RTMP1, RTMP1;
+ vmovdqu RB0, (1 * 32)(%rsi);
+ vpxor RB0, RTMP1, RTMP1;
+ vmovdqu RC0, (2 * 32)(%rsi);
+ vpxor RC0, RTMP1, RTMP1;
+ vmovdqu RD0, (3 * 32)(%rsi);
+ vpxor RD0, RTMP1, RTMP1;
+ vmovdqu RA1, (4 * 32)(%rsi);
+ vpxor RA1, RTMP1, RTMP1;
+ vmovdqu RB1, (5 * 32)(%rsi);
+ vpxor RB1, RTMP1, RTMP1;
+ vmovdqu RC1, (6 * 32)(%rsi);
+ vpxor RC1, RTMP1, RTMP1;
+ vmovdqu RD1, (7 * 32)(%rsi);
+ vpxor RD1, RTMP1, RTMP1;
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%rcx);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_avx2_ocb_dec,.-_gcry_twofish_avx2_ocb_dec;)
+
+.align 8
+.globl _gcry_twofish_avx2_ocb_auth
+ELF(.type _gcry_twofish_avx2_ocb_auth,@function;)
+
+_gcry_twofish_avx2_ocb_auth:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: abuf (16 blocks)
+ * %rdx: offset
+ * %rcx: checksum
+ * %r8 : L pointers (void *L[16])
+ */
+ CFI_STARTPROC();
+
+ vzeroupper;
+
+ subq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(4 * 8);
+
+ movq %r10, (0 * 8)(%rsp);
+ movq %r11, (1 * 8)(%rsp);
+ movq %r12, (2 * 8)(%rsp);
+ movq %r13, (3 * 8)(%rsp);
+ CFI_REL_OFFSET(%r10, 0 * 8);
+ CFI_REL_OFFSET(%r11, 1 * 8);
+ CFI_REL_OFFSET(%r12, 2 * 8);
+ CFI_REL_OFFSET(%r13, 3 * 8);
+
+ vmovdqu (%rdx), RTMP0x;
+
+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+
+#define OCB_INPUT(n, l0reg, l1reg, yreg) \
+ vmovdqu (n * 32)(%rsi), yreg; \
+ vpxor (l0reg), RTMP0x, RNOTx; \
+ vpxor (l1reg), RNOTx, RTMP0x; \
+ vinserti128 $1, RTMP0x, RNOT, RNOT; \
+ vpxor yreg, RNOT, yreg;
+
+ movq (0 * 8)(%r8), %r10;
+ movq (1 * 8)(%r8), %r11;
+ movq (2 * 8)(%r8), %r12;
+ movq (3 * 8)(%r8), %r13;
+ OCB_INPUT(0, %r10, %r11, RA0);
+ OCB_INPUT(1, %r12, %r13, RB0);
+ movq (4 * 8)(%r8), %r10;
+ movq (5 * 8)(%r8), %r11;
+ movq (6 * 8)(%r8), %r12;
+ movq (7 * 8)(%r8), %r13;
+ OCB_INPUT(2, %r10, %r11, RC0);
+ OCB_INPUT(3, %r12, %r13, RD0);
+ movq (8 * 8)(%r8), %r10;
+ movq (9 * 8)(%r8), %r11;
+ movq (10 * 8)(%r8), %r12;
+ movq (11 * 8)(%r8), %r13;
+ OCB_INPUT(4, %r10, %r11, RA1);
+ OCB_INPUT(5, %r12, %r13, RB1);
+ movq (12 * 8)(%r8), %r10;
+ movq (13 * 8)(%r8), %r11;
+ movq (14 * 8)(%r8), %r12;
+ movq (15 * 8)(%r8), %r13;
+ OCB_INPUT(6, %r10, %r11, RC1);
+ OCB_INPUT(7, %r12, %r13, RD1);
+#undef OCB_INPUT
+
+ vmovdqu RTMP0x, (%rdx);
+
+ movq (0 * 8)(%rsp), %r10;
+ movq (1 * 8)(%rsp), %r11;
+ movq (2 * 8)(%rsp), %r12;
+ movq (3 * 8)(%rsp), %r13;
+ CFI_RESTORE(%r10);
+ CFI_RESTORE(%r11);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+
+ call __twofish_enc_blk16;
+
+ vpxor RA0, RB0, RA0;
+ vpxor RC0, RD0, RC0;
+ vpxor RA1, RB1, RA1;
+ vpxor RC1, RD1, RC1;
+
+ vpxor RA0, RC0, RA0;
+ vpxor RA1, RC1, RA1;
+
+ addq $(4 * 8), %rsp;
+ CFI_ADJUST_CFA_OFFSET(-4 * 8);
+
+ vpxor RA1, RA0, RTMP1;
+
+ vextracti128 $1, RTMP1, RNOTx;
+ vpxor (%rcx), RTMP1x, RTMP1x;
+ vpxor RNOTx, RTMP1x, RTMP1x;
+ vmovdqu RTMP1x, (%rcx);
+
+ vzeroall;
+
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_twofish_avx2_ocb_auth,.-_gcry_twofish_avx2_ocb_auth;)
+
+.align 16
+
+/* For CTR-mode IV byteswap */
+ _gcry_twofish_bswap128_mask:
+.Lbswap128_mask:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+ELF(.size _gcry_twofish_bswap128_mask,.-_gcry_twofish_bswap128_mask;)
+
+#endif /*defined(USE_TWOFISH) && defined(ENABLE_AVX2_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/comm/third_party/libgcrypt/cipher/twofish.c b/comm/third_party/libgcrypt/cipher/twofish.c
new file mode 100644
index 0000000000..d19e079046
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/twofish.c
@@ -0,0 +1,1793 @@
+/* Twofish for GPG
+ * Copyright (C) 1998, 2002, 2003 Free Software Foundation, Inc.
+ * Written by Matthew Skala <mskala@ansuz.sooke.bc.ca>, 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* 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"
+
+
+#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];
+ unsigned int n = 16 - (blkn % 16);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 16)
+ {
+ for (i = 0; i < 16; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(15 + n) % 16];
+
+ /* 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];
+ unsigned int n = 16 - (blkn % 16);
+ u64 *l;
+ int i;
+
+ if (nblocks >= 16)
+ {
+ for (i = 0; i < 16; i += 8)
+ {
+ /* Use u64 to store pointers for x32 support (assembly function
+ * assumes 64-bit pointers). */
+ Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
+ Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
+ Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
+ }
+
+ Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
+ l = &Ls[(15 + n) % 16];
+
+ /* 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 <stdio.h>
+#include <string.h>
+#include <time.h>
+
+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/comm/third_party/libgcrypt/cipher/whirlpool-sse2-amd64.S b/comm/third_party/libgcrypt/cipher/whirlpool-sse2-amd64.S
new file mode 100644
index 0000000000..5631dc567a
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/whirlpool-sse2-amd64.S
@@ -0,0 +1,348 @@
+/* whirlpool-sse2-amd64.S - AMD64 assembly implementation of Whirlpool
+ *
+ * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_WHIRLPOOL)
+
+#include "asm-common-amd64.h"
+
+.text
+
+/* look-up table offsets on RTAB */
+#define RC (0)
+#define C0 (RC + (8 * 10))
+#define C1 (C0 + (8 * 256))
+#define C2 (C1 + (8 * 256))
+#define C3 (C2 + (8 * 256))
+#define C4 (C3 + (8 * 256))
+#define C5 (C4 + (8 * 256))
+#define C6 (C5 + (8 * 256))
+#define C7 (C6 + (8 * 256))
+
+/* stack variables */
+#define STACK_DATAP (0)
+#define STACK_STATEP (STACK_DATAP + 8)
+#define STACK_ROUNDS (STACK_STATEP + 8)
+#define STACK_NBLKS (STACK_ROUNDS + 8)
+#define STACK_RBP (STACK_NBLKS + 8)
+#define STACK_RBX (STACK_RBP + 8)
+#define STACK_R12 (STACK_RBX + 8)
+#define STACK_R13 (STACK_R12 + 8)
+#define STACK_R14 (STACK_R13 + 8)
+#define STACK_R15 (STACK_R14 + 8)
+#define STACK_MAX (STACK_R15 + 8)
+
+/* register macros */
+#define RTAB %rbp
+
+#define RI1 %rax
+#define RI2 %rbx
+#define RI3 %rcx
+#define RI4 %rdx
+
+#define RI1d %eax
+#define RI2d %ebx
+#define RI3d %ecx
+#define RI4d %edx
+
+#define RI1bl %al
+#define RI2bl %bl
+#define RI3bl %cl
+#define RI4bl %dl
+
+#define RI1bh %ah
+#define RI2bh %bh
+#define RI3bh %ch
+#define RI4bh %dh
+
+#define RB0 %r8
+#define RB1 %r9
+#define RB2 %r10
+#define RB3 %r11
+#define RB4 %r12
+#define RB5 %r13
+#define RB6 %r14
+#define RB7 %r15
+
+#define RT0 %rsi
+#define RT1 %rdi
+
+#define RT0d %esi
+#define RT1d %edi
+
+#define XKEY0 %xmm0
+#define XKEY1 %xmm1
+#define XKEY2 %xmm2
+#define XKEY3 %xmm3
+#define XKEY4 %xmm4
+#define XKEY5 %xmm5
+#define XKEY6 %xmm6
+#define XKEY7 %xmm7
+
+#define XSTATE0 %xmm8
+#define XSTATE1 %xmm9
+#define XSTATE2 %xmm10
+#define XSTATE3 %xmm11
+#define XSTATE4 %xmm12
+#define XSTATE5 %xmm13
+#define XSTATE6 %xmm14
+#define XSTATE7 %xmm15
+
+/***********************************************************************
+ * AMD64 assembly implementation of Whirlpool.
+ * - Using table-lookups
+ * - Store state in XMM registers
+ ***********************************************************************/
+#define __do_whirl(op, ri, \
+ b0, b1, b2, b3, b4, b5, b6, b7, \
+ load_ri, load_arg) \
+ movzbl ri ## bl, RT0d; \
+ movzbl ri ## bh, RT1d; \
+ shrq $16, ri; \
+ op ## q C7(RTAB,RT0,8), b7; \
+ op ## q C6(RTAB,RT1,8), b6; \
+ movzbl ri ## bl, RT0d; \
+ movzbl ri ## bh, RT1d; \
+ shrq $16, ri; \
+ op ## q C5(RTAB,RT0,8), b5; \
+ op ## q C4(RTAB,RT1,8), b4; \
+ movzbl ri ## bl, RT0d; \
+ movzbl ri ## bh, RT1d; \
+ shrl $16, ri ## d; \
+ op ## q C3(RTAB,RT0,8), b3; \
+ op ## q C2(RTAB,RT1,8), b2; \
+ movzbl ri ## bl, RT0d; \
+ movzbl ri ## bh, RT1d; \
+ load_ri( load_arg, ri); \
+ op ## q C1(RTAB,RT0,8), b1; \
+ op ## q C0(RTAB,RT1,8), b0;
+
+#define do_whirl(op, ri, rb_add, load_ri, load_arg) \
+ __do_whirl(op, ##ri, rb_add, load_ri, load_arg)
+
+#define dummy(...) /*_*/
+
+#define do_movq(src, dst) movq src, dst;
+
+#define RB_ADD0 RB0, RB1, RB2, RB3, RB4, RB5, RB6, RB7
+#define RB_ADD1 RB1, RB2, RB3, RB4, RB5, RB6, RB7, RB0
+#define RB_ADD2 RB2, RB3, RB4, RB5, RB6, RB7, RB0, RB1
+#define RB_ADD3 RB3, RB4, RB5, RB6, RB7, RB0, RB1, RB2
+#define RB_ADD4 RB4, RB5, RB6, RB7, RB0, RB1, RB2, RB3
+#define RB_ADD5 RB5, RB6, RB7, RB0, RB1, RB2, RB3, RB4
+#define RB_ADD6 RB6, RB7, RB0, RB1, RB2, RB3, RB4, RB5
+#define RB_ADD7 RB7, RB0, RB1, RB2, RB3, RB4, RB5, RB6
+
+.align 8
+.globl _gcry_whirlpool_transform_amd64
+ELF(.type _gcry_whirlpool_transform_amd64,@function;)
+
+_gcry_whirlpool_transform_amd64:
+ /* input:
+ * %rdi: state
+ * %rsi: inblk
+ * %rdx: nblks
+ * %rcx: look-up tables
+ */
+ CFI_STARTPROC();
+ cmp $0, %rdx;
+ je .Lskip;
+
+ subq $STACK_MAX, %rsp;
+ CFI_ADJUST_CFA_OFFSET(STACK_MAX);
+ movq %rbp, STACK_RBP(%rsp);
+ movq %rbx, STACK_RBX(%rsp);
+ movq %r12, STACK_R12(%rsp);
+ movq %r13, STACK_R13(%rsp);
+ movq %r14, STACK_R14(%rsp);
+ movq %r15, STACK_R15(%rsp);
+ CFI_REL_OFFSET(%rbp, STACK_RBP);
+ CFI_REL_OFFSET(%rbx, STACK_RBX);
+ CFI_REL_OFFSET(%r12, STACK_R12);
+ CFI_REL_OFFSET(%r13, STACK_R13);
+ CFI_REL_OFFSET(%r14, STACK_R14);
+ CFI_REL_OFFSET(%r15, STACK_R15);
+
+ movq %rdx, STACK_NBLKS(%rsp);
+ movq %rdi, STACK_STATEP(%rsp);
+ movq %rsi, STACK_DATAP(%rsp);
+
+ movq %rcx, RTAB;
+
+ jmp .Lfirst_block;
+
+.align 8
+.Lblock_loop:
+ movq STACK_DATAP(%rsp), %rsi;
+ movq RI1, %rdi;
+
+.Lfirst_block:
+ /* load data_block */
+ movq 0*8(%rsi), RB0;
+ movq 1*8(%rsi), RB1;
+ bswapq RB0;
+ movq 2*8(%rsi), RB2;
+ bswapq RB1;
+ movq 3*8(%rsi), RB3;
+ bswapq RB2;
+ movq 4*8(%rsi), RB4;
+ bswapq RB3;
+ movq 5*8(%rsi), RB5;
+ bswapq RB4;
+ movq RB0, XSTATE0;
+ movq 6*8(%rsi), RB6;
+ bswapq RB5;
+ movq RB1, XSTATE1;
+ movq 7*8(%rsi), RB7;
+ bswapq RB6;
+ movq RB2, XSTATE2;
+ bswapq RB7;
+ movq RB3, XSTATE3;
+ movq RB4, XSTATE4;
+ movq RB5, XSTATE5;
+ movq RB6, XSTATE6;
+ movq RB7, XSTATE7;
+
+ /* load key */
+ movq 0*8(%rdi), XKEY0;
+ movq 1*8(%rdi), XKEY1;
+ movq 2*8(%rdi), XKEY2;
+ movq 3*8(%rdi), XKEY3;
+ movq 4*8(%rdi), XKEY4;
+ movq 5*8(%rdi), XKEY5;
+ movq 6*8(%rdi), XKEY6;
+ movq 7*8(%rdi), XKEY7;
+
+ movq XKEY0, RI1;
+ movq XKEY1, RI2;
+ movq XKEY2, RI3;
+ movq XKEY3, RI4;
+
+ /* prepare and store state */
+ pxor XKEY0, XSTATE0;
+ pxor XKEY1, XSTATE1;
+ pxor XKEY2, XSTATE2;
+ pxor XKEY3, XSTATE3;
+ pxor XKEY4, XSTATE4;
+ pxor XKEY5, XSTATE5;
+ pxor XKEY6, XSTATE6;
+ pxor XKEY7, XSTATE7;
+
+ movq XSTATE0, 0*8(%rdi);
+ movq XSTATE1, 1*8(%rdi);
+ movq XSTATE2, 2*8(%rdi);
+ movq XSTATE3, 3*8(%rdi);
+ movq XSTATE4, 4*8(%rdi);
+ movq XSTATE5, 5*8(%rdi);
+ movq XSTATE6, 6*8(%rdi);
+ movq XSTATE7, 7*8(%rdi);
+
+ addq $64, STACK_DATAP(%rsp);
+ movl $(0), STACK_ROUNDS(%rsp);
+.align 8
+.Lround_loop:
+ do_whirl(mov, RI1 /*XKEY0*/, RB_ADD0, do_movq, XKEY4);
+ do_whirl(xor, RI2 /*XKEY1*/, RB_ADD1, do_movq, XKEY5);
+ do_whirl(xor, RI3 /*XKEY2*/, RB_ADD2, do_movq, XKEY6);
+ do_whirl(xor, RI4 /*XKEY3*/, RB_ADD3, do_movq, XKEY7);
+ do_whirl(xor, RI1 /*XKEY0*/, RB_ADD4, do_movq, XSTATE0);
+ do_whirl(xor, RI2 /*XKEY1*/, RB_ADD5, do_movq, XSTATE1);
+ do_whirl(xor, RI3 /*XKEY2*/, RB_ADD6, do_movq, XSTATE2);
+ do_whirl(xor, RI4 /*XKEY3*/, RB_ADD7, do_movq, XSTATE3);
+
+ movl STACK_ROUNDS(%rsp), RT0d;
+ movq RB1, XKEY1;
+ addl $1, STACK_ROUNDS(%rsp);
+ movq RB2, XKEY2;
+ movq RB3, XKEY3;
+ xorq RC(RTAB,RT0,8), RB0; /* Add round constant */
+ movq RB4, XKEY4;
+ movq RB5, XKEY5;
+ movq RB0, XKEY0;
+ movq RB6, XKEY6;
+ movq RB7, XKEY7;
+
+ do_whirl(xor, RI1 /*XSTATE0*/, RB_ADD0, do_movq, XSTATE4);
+ do_whirl(xor, RI2 /*XSTATE1*/, RB_ADD1, do_movq, XSTATE5);
+ do_whirl(xor, RI3 /*XSTATE2*/, RB_ADD2, do_movq, XSTATE6);
+ do_whirl(xor, RI4 /*XSTATE3*/, RB_ADD3, do_movq, XSTATE7);
+
+ cmpl $10, STACK_ROUNDS(%rsp);
+ je .Lis_last_round;
+
+ do_whirl(xor, RI1 /*XSTATE4*/, RB_ADD4, do_movq, XKEY0);
+ do_whirl(xor, RI2 /*XSTATE5*/, RB_ADD5, do_movq, XKEY1);
+ do_whirl(xor, RI3 /*XSTATE6*/, RB_ADD6, do_movq, XKEY2);
+ do_whirl(xor, RI4 /*XSTATE7*/, RB_ADD7, do_movq, XKEY3);
+ movq RB0, XSTATE0;
+ movq RB1, XSTATE1;
+ movq RB2, XSTATE2;
+ movq RB3, XSTATE3;
+ movq RB4, XSTATE4;
+ movq RB5, XSTATE5;
+ movq RB6, XSTATE6;
+ movq RB7, XSTATE7;
+
+ jmp .Lround_loop;
+.align 8
+.Lis_last_round:
+ do_whirl(xor, RI1 /*XSTATE4*/, RB_ADD4, dummy, _);
+ movq STACK_STATEP(%rsp), RI1;
+ do_whirl(xor, RI2 /*XSTATE5*/, RB_ADD5, dummy, _);
+ do_whirl(xor, RI3 /*XSTATE6*/, RB_ADD6, dummy, _);
+ do_whirl(xor, RI4 /*XSTATE7*/, RB_ADD7, dummy, _);
+
+ /* store state */
+ xorq RB0, 0*8(RI1);
+ xorq RB1, 1*8(RI1);
+ xorq RB2, 2*8(RI1);
+ xorq RB3, 3*8(RI1);
+ xorq RB4, 4*8(RI1);
+ xorq RB5, 5*8(RI1);
+ xorq RB6, 6*8(RI1);
+ xorq RB7, 7*8(RI1);
+
+ subq $1, STACK_NBLKS(%rsp);
+ jnz .Lblock_loop;
+
+ movq STACK_RBP(%rsp), %rbp;
+ movq STACK_RBX(%rsp), %rbx;
+ movq STACK_R12(%rsp), %r12;
+ movq STACK_R13(%rsp), %r13;
+ movq STACK_R14(%rsp), %r14;
+ movq STACK_R15(%rsp), %r15;
+ CFI_RESTORE(%rbp);
+ CFI_RESTORE(%rbx);
+ CFI_RESTORE(%r12);
+ CFI_RESTORE(%r13);
+ CFI_RESTORE(%r14);
+ CFI_RESTORE(%r15);
+ addq $STACK_MAX, %rsp;
+ CFI_ADJUST_CFA_OFFSET(-STACK_MAX);
+.Lskip:
+ movl $(STACK_MAX + 8), %eax;
+ ret;
+ CFI_ENDPROC();
+ELF(.size _gcry_whirlpool_transform_amd64,.-_gcry_whirlpool_transform_amd64;)
+
+#endif
+#endif
diff --git a/comm/third_party/libgcrypt/cipher/whirlpool.c b/comm/third_party/libgcrypt/cipher/whirlpool.c
new file mode 100644
index 0000000000..79b2026b57
--- /dev/null
+++ b/comm/third_party/libgcrypt/cipher/whirlpool.c
@@ -0,0 +1,1535 @@
+/* whirlpool.c - Whirlpool hashing algorithm
+ * Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This is an implementation of the Whirlpool hashing algorithm, which
+ has been developed by Vincent Rijmen and Paulo S. L. M. Barreto;
+ it's homepage is located at:
+ http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html
+
+ The S-Boxes and the structure of the main transformation function,
+ which implements an optimized version of the algorithm, is taken
+ from the reference implementation available from
+ http://www.larc.usp.br/~pbarreto/whirlpool.zip
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+
+#include "bufhelp.h"
+#include "hash-common.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
+
+
+
+/* Size of a whirlpool block (in bytes). */
+#define BLOCK_SIZE 64
+
+/* Number of rounds. */
+#define R 10
+
+
+
+/* Types. */
+typedef u64 whirlpool_block_t[BLOCK_SIZE / 8];
+
+typedef struct {
+ gcry_md_block_ctx_t bctx;
+ whirlpool_block_t hash_state;
+ int use_bugemu;
+ struct {
+ size_t count;
+ unsigned char length[32];
+ } bugemu;
+} whirlpool_context_t;
+
+
+
+/* Macros. */
+
+/* Convert the the buffer BUFFER into a block BLOCK, using I as
+ counter. */
+#define buffer_to_block(buffer, block, i) \
+ for (i = 0; i < 8; i++) \
+ (block)[i] = buf_get_be64((buffer) + i * 8);
+
+/* Convert the block BLOCK into a buffer BUFFER, using I as
+ counter. */
+#define block_to_buffer(buffer, block, i) \
+ for (i = 0; i < 8; i++) \
+ buf_put_be64((buffer) + i * 8, (block)[i]);
+
+/* Copy the block BLOCK_SRC to BLOCK_DST, using I as counter. */
+#define block_copy(block_dst, block_src, i) \
+ for (i = 0; i < 8; i++) \
+ block_dst[i] = block_src[i];
+
+/* XOR the block BLOCK_SRC into BLOCK_DST, using I as counter. */
+#define block_xor(block_dst, block_src, i) \
+ for (i = 0; i < 8; i++) \
+ block_dst[i] ^= block_src[i];
+
+
+
+
+struct whirlpool_tables_s {
+ u64 RC[R];
+ u64 C[8][256];
+};
+
+static const struct whirlpool_tables_s tab =
+{
+/* Round constants. */
+ {
+ U64_C (0x1823c6e887b8014f),
+ U64_C (0x36a6d2f5796f9152),
+ U64_C (0x60bc9b8ea30c7b35),
+ U64_C (0x1de0d7c22e4bfe57),
+ U64_C (0x157737e59ff04ada),
+ U64_C (0x58c9290ab1a06b85),
+ U64_C (0xbd5d10f4cb3e0567),
+ U64_C (0xe427418ba77d95d8),
+ U64_C (0xfbee7c66dd17479e),
+ U64_C (0xca2dbf07ad5a8333),
+ },
+/* Main lookup boxes. */
+ { {
+ U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626),
+ U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb),
+ U64_C (0x878726874ca113cb), U64_C (0xb8b8dab8a9626d11),
+ U64_C (0x0101040108050209), U64_C (0x4f4f214f426e9e0d),
+ U64_C (0x3636d836adee6c9b), U64_C (0xa6a6a2a6590451ff),
+ U64_C (0xd2d26fd2debdb90c), U64_C (0xf5f5f3f5fb06f70e),
+ U64_C (0x7979f979ef80f296), U64_C (0x6f6fa16f5fcede30),
+ U64_C (0x91917e91fcef3f6d), U64_C (0x52525552aa07a4f8),
+ U64_C (0x60609d6027fdc047), U64_C (0xbcbccabc89766535),
+ U64_C (0x9b9b569baccd2b37), U64_C (0x8e8e028e048c018a),
+ U64_C (0xa3a3b6a371155bd2), U64_C (0x0c0c300c603c186c),
+ U64_C (0x7b7bf17bff8af684), U64_C (0x3535d435b5e16a80),
+ U64_C (0x1d1d741de8693af5), U64_C (0xe0e0a7e05347ddb3),
+ U64_C (0xd7d77bd7f6acb321), U64_C (0xc2c22fc25eed999c),
+ U64_C (0x2e2eb82e6d965c43), U64_C (0x4b4b314b627a9629),
+ U64_C (0xfefedffea321e15d), U64_C (0x575741578216aed5),
+ U64_C (0x15155415a8412abd), U64_C (0x7777c1779fb6eee8),
+ U64_C (0x3737dc37a5eb6e92), U64_C (0xe5e5b3e57b56d79e),
+ U64_C (0x9f9f469f8cd92313), U64_C (0xf0f0e7f0d317fd23),
+ U64_C (0x4a4a354a6a7f9420), U64_C (0xdada4fda9e95a944),
+ U64_C (0x58587d58fa25b0a2), U64_C (0xc9c903c906ca8fcf),
+ U64_C (0x2929a429558d527c), U64_C (0x0a0a280a5022145a),
+ U64_C (0xb1b1feb1e14f7f50), U64_C (0xa0a0baa0691a5dc9),
+ U64_C (0x6b6bb16b7fdad614), U64_C (0x85852e855cab17d9),
+ U64_C (0xbdbdcebd8173673c), U64_C (0x5d5d695dd234ba8f),
+ U64_C (0x1010401080502090), U64_C (0xf4f4f7f4f303f507),
+ U64_C (0xcbcb0bcb16c08bdd), U64_C (0x3e3ef83eedc67cd3),
+ U64_C (0x0505140528110a2d), U64_C (0x676781671fe6ce78),
+ U64_C (0xe4e4b7e47353d597), U64_C (0x27279c2725bb4e02),
+ U64_C (0x4141194132588273), U64_C (0x8b8b168b2c9d0ba7),
+ U64_C (0xa7a7a6a7510153f6), U64_C (0x7d7de97dcf94fab2),
+ U64_C (0x95956e95dcfb3749), U64_C (0xd8d847d88e9fad56),
+ U64_C (0xfbfbcbfb8b30eb70), U64_C (0xeeee9fee2371c1cd),
+ U64_C (0x7c7ced7cc791f8bb), U64_C (0x6666856617e3cc71),
+ U64_C (0xdddd53dda68ea77b), U64_C (0x17175c17b84b2eaf),
+ U64_C (0x4747014702468e45), U64_C (0x9e9e429e84dc211a),
+ U64_C (0xcaca0fca1ec589d4), U64_C (0x2d2db42d75995a58),
+ U64_C (0xbfbfc6bf9179632e), U64_C (0x07071c07381b0e3f),
+ U64_C (0xadad8ead012347ac), U64_C (0x5a5a755aea2fb4b0),
+ U64_C (0x838336836cb51bef), U64_C (0x3333cc3385ff66b6),
+ U64_C (0x636391633ff2c65c), U64_C (0x02020802100a0412),
+ U64_C (0xaaaa92aa39384993), U64_C (0x7171d971afa8e2de),
+ U64_C (0xc8c807c80ecf8dc6), U64_C (0x19196419c87d32d1),
+ U64_C (0x494939497270923b), U64_C (0xd9d943d9869aaf5f),
+ U64_C (0xf2f2eff2c31df931), U64_C (0xe3e3abe34b48dba8),
+ U64_C (0x5b5b715be22ab6b9), U64_C (0x88881a8834920dbc),
+ U64_C (0x9a9a529aa4c8293e), U64_C (0x262698262dbe4c0b),
+ U64_C (0x3232c8328dfa64bf), U64_C (0xb0b0fab0e94a7d59),
+ U64_C (0xe9e983e91b6acff2), U64_C (0x0f0f3c0f78331e77),
+ U64_C (0xd5d573d5e6a6b733), U64_C (0x80803a8074ba1df4),
+ U64_C (0xbebec2be997c6127), U64_C (0xcdcd13cd26de87eb),
+ U64_C (0x3434d034bde46889), U64_C (0x48483d487a759032),
+ U64_C (0xffffdbffab24e354), U64_C (0x7a7af57af78ff48d),
+ U64_C (0x90907a90f4ea3d64), U64_C (0x5f5f615fc23ebe9d),
+ U64_C (0x202080201da0403d), U64_C (0x6868bd6867d5d00f),
+ U64_C (0x1a1a681ad07234ca), U64_C (0xaeae82ae192c41b7),
+ U64_C (0xb4b4eab4c95e757d), U64_C (0x54544d549a19a8ce),
+ U64_C (0x93937693ece53b7f), U64_C (0x222288220daa442f),
+ U64_C (0x64648d6407e9c863), U64_C (0xf1f1e3f1db12ff2a),
+ U64_C (0x7373d173bfa2e6cc), U64_C (0x12124812905a2482),
+ U64_C (0x40401d403a5d807a), U64_C (0x0808200840281048),
+ U64_C (0xc3c32bc356e89b95), U64_C (0xecec97ec337bc5df),
+ U64_C (0xdbdb4bdb9690ab4d), U64_C (0xa1a1bea1611f5fc0),
+ U64_C (0x8d8d0e8d1c830791), U64_C (0x3d3df43df5c97ac8),
+ U64_C (0x97976697ccf1335b), U64_C (0x0000000000000000),
+ U64_C (0xcfcf1bcf36d483f9), U64_C (0x2b2bac2b4587566e),
+ U64_C (0x7676c57697b3ece1), U64_C (0x8282328264b019e6),
+ U64_C (0xd6d67fd6fea9b128), U64_C (0x1b1b6c1bd87736c3),
+ U64_C (0xb5b5eeb5c15b7774), U64_C (0xafaf86af112943be),
+ U64_C (0x6a6ab56a77dfd41d), U64_C (0x50505d50ba0da0ea),
+ U64_C (0x45450945124c8a57), U64_C (0xf3f3ebf3cb18fb38),
+ U64_C (0x3030c0309df060ad), U64_C (0xefef9bef2b74c3c4),
+ U64_C (0x3f3ffc3fe5c37eda), U64_C (0x55554955921caac7),
+ U64_C (0xa2a2b2a2791059db), U64_C (0xeaea8fea0365c9e9),
+ U64_C (0x656589650fecca6a), U64_C (0xbabad2bab9686903),
+ U64_C (0x2f2fbc2f65935e4a), U64_C (0xc0c027c04ee79d8e),
+ U64_C (0xdede5fdebe81a160), U64_C (0x1c1c701ce06c38fc),
+ U64_C (0xfdfdd3fdbb2ee746), U64_C (0x4d4d294d52649a1f),
+ U64_C (0x92927292e4e03976), U64_C (0x7575c9758fbceafa),
+ U64_C (0x06061806301e0c36), U64_C (0x8a8a128a249809ae),
+ U64_C (0xb2b2f2b2f940794b), U64_C (0xe6e6bfe66359d185),
+ U64_C (0x0e0e380e70361c7e), U64_C (0x1f1f7c1ff8633ee7),
+ U64_C (0x6262956237f7c455), U64_C (0xd4d477d4eea3b53a),
+ U64_C (0xa8a89aa829324d81), U64_C (0x96966296c4f43152),
+ U64_C (0xf9f9c3f99b3aef62), U64_C (0xc5c533c566f697a3),
+ U64_C (0x2525942535b14a10), U64_C (0x59597959f220b2ab),
+ U64_C (0x84842a8454ae15d0), U64_C (0x7272d572b7a7e4c5),
+ U64_C (0x3939e439d5dd72ec), U64_C (0x4c4c2d4c5a619816),
+ U64_C (0x5e5e655eca3bbc94), U64_C (0x7878fd78e785f09f),
+ U64_C (0x3838e038ddd870e5), U64_C (0x8c8c0a8c14860598),
+ U64_C (0xd1d163d1c6b2bf17), U64_C (0xa5a5aea5410b57e4),
+ U64_C (0xe2e2afe2434dd9a1), U64_C (0x616199612ff8c24e),
+ U64_C (0xb3b3f6b3f1457b42), U64_C (0x2121842115a54234),
+ U64_C (0x9c9c4a9c94d62508), U64_C (0x1e1e781ef0663cee),
+ U64_C (0x4343114322528661), U64_C (0xc7c73bc776fc93b1),
+ U64_C (0xfcfcd7fcb32be54f), U64_C (0x0404100420140824),
+ U64_C (0x51515951b208a2e3), U64_C (0x99995e99bcc72f25),
+ U64_C (0x6d6da96d4fc4da22), U64_C (0x0d0d340d68391a65),
+ U64_C (0xfafacffa8335e979), U64_C (0xdfdf5bdfb684a369),
+ U64_C (0x7e7ee57ed79bfca9), U64_C (0x242490243db44819),
+ U64_C (0x3b3bec3bc5d776fe), U64_C (0xabab96ab313d4b9a),
+ U64_C (0xcece1fce3ed181f0), U64_C (0x1111441188552299),
+ U64_C (0x8f8f068f0c890383), U64_C (0x4e4e254e4a6b9c04),
+ U64_C (0xb7b7e6b7d1517366), U64_C (0xebeb8beb0b60cbe0),
+ U64_C (0x3c3cf03cfdcc78c1), U64_C (0x81813e817cbf1ffd),
+ U64_C (0x94946a94d4fe3540), U64_C (0xf7f7fbf7eb0cf31c),
+ U64_C (0xb9b9deb9a1676f18), U64_C (0x13134c13985f268b),
+ U64_C (0x2c2cb02c7d9c5851), U64_C (0xd3d36bd3d6b8bb05),
+ U64_C (0xe7e7bbe76b5cd38c), U64_C (0x6e6ea56e57cbdc39),
+ U64_C (0xc4c437c46ef395aa), U64_C (0x03030c03180f061b),
+ U64_C (0x565645568a13acdc), U64_C (0x44440d441a49885e),
+ U64_C (0x7f7fe17fdf9efea0), U64_C (0xa9a99ea921374f88),
+ U64_C (0x2a2aa82a4d825467), U64_C (0xbbbbd6bbb16d6b0a),
+ U64_C (0xc1c123c146e29f87), U64_C (0x53535153a202a6f1),
+ U64_C (0xdcdc57dcae8ba572), U64_C (0x0b0b2c0b58271653),
+ U64_C (0x9d9d4e9d9cd32701), U64_C (0x6c6cad6c47c1d82b),
+ U64_C (0x3131c43195f562a4), U64_C (0x7474cd7487b9e8f3),
+ U64_C (0xf6f6fff6e309f115), U64_C (0x464605460a438c4c),
+ U64_C (0xacac8aac092645a5), U64_C (0x89891e893c970fb5),
+ U64_C (0x14145014a04428b4), U64_C (0xe1e1a3e15b42dfba),
+ U64_C (0x16165816b04e2ca6), U64_C (0x3a3ae83acdd274f7),
+ U64_C (0x6969b9696fd0d206), U64_C (0x09092409482d1241),
+ U64_C (0x7070dd70a7ade0d7), U64_C (0xb6b6e2b6d954716f),
+ U64_C (0xd0d067d0ceb7bd1e), U64_C (0xeded93ed3b7ec7d6),
+ U64_C (0xcccc17cc2edb85e2), U64_C (0x424215422a578468),
+ U64_C (0x98985a98b4c22d2c), U64_C (0xa4a4aaa4490e55ed),
+ U64_C (0x2828a0285d885075), U64_C (0x5c5c6d5cda31b886),
+ U64_C (0xf8f8c7f8933fed6b), U64_C (0x8686228644a411c2),
+ }, {
+ U64_C (0xd818186018c07830), U64_C (0x2623238c2305af46),
+ U64_C (0xb8c6c63fc67ef991), U64_C (0xfbe8e887e8136fcd),
+ U64_C (0xcb878726874ca113), U64_C (0x11b8b8dab8a9626d),
+ U64_C (0x0901010401080502), U64_C (0x0d4f4f214f426e9e),
+ U64_C (0x9b3636d836adee6c), U64_C (0xffa6a6a2a6590451),
+ U64_C (0x0cd2d26fd2debdb9), U64_C (0x0ef5f5f3f5fb06f7),
+ U64_C (0x967979f979ef80f2), U64_C (0x306f6fa16f5fcede),
+ U64_C (0x6d91917e91fcef3f), U64_C (0xf852525552aa07a4),
+ U64_C (0x4760609d6027fdc0), U64_C (0x35bcbccabc897665),
+ U64_C (0x379b9b569baccd2b), U64_C (0x8a8e8e028e048c01),
+ U64_C (0xd2a3a3b6a371155b), U64_C (0x6c0c0c300c603c18),
+ U64_C (0x847b7bf17bff8af6), U64_C (0x803535d435b5e16a),
+ U64_C (0xf51d1d741de8693a), U64_C (0xb3e0e0a7e05347dd),
+ U64_C (0x21d7d77bd7f6acb3), U64_C (0x9cc2c22fc25eed99),
+ U64_C (0x432e2eb82e6d965c), U64_C (0x294b4b314b627a96),
+ U64_C (0x5dfefedffea321e1), U64_C (0xd5575741578216ae),
+ U64_C (0xbd15155415a8412a), U64_C (0xe87777c1779fb6ee),
+ U64_C (0x923737dc37a5eb6e), U64_C (0x9ee5e5b3e57b56d7),
+ U64_C (0x139f9f469f8cd923), U64_C (0x23f0f0e7f0d317fd),
+ U64_C (0x204a4a354a6a7f94), U64_C (0x44dada4fda9e95a9),
+ U64_C (0xa258587d58fa25b0), U64_C (0xcfc9c903c906ca8f),
+ U64_C (0x7c2929a429558d52), U64_C (0x5a0a0a280a502214),
+ U64_C (0x50b1b1feb1e14f7f), U64_C (0xc9a0a0baa0691a5d),
+ U64_C (0x146b6bb16b7fdad6), U64_C (0xd985852e855cab17),
+ U64_C (0x3cbdbdcebd817367), U64_C (0x8f5d5d695dd234ba),
+ U64_C (0x9010104010805020), U64_C (0x07f4f4f7f4f303f5),
+ U64_C (0xddcbcb0bcb16c08b), U64_C (0xd33e3ef83eedc67c),
+ U64_C (0x2d0505140528110a), U64_C (0x78676781671fe6ce),
+ U64_C (0x97e4e4b7e47353d5), U64_C (0x0227279c2725bb4e),
+ U64_C (0x7341411941325882), U64_C (0xa78b8b168b2c9d0b),
+ U64_C (0xf6a7a7a6a7510153), U64_C (0xb27d7de97dcf94fa),
+ U64_C (0x4995956e95dcfb37), U64_C (0x56d8d847d88e9fad),
+ U64_C (0x70fbfbcbfb8b30eb), U64_C (0xcdeeee9fee2371c1),
+ U64_C (0xbb7c7ced7cc791f8), U64_C (0x716666856617e3cc),
+ U64_C (0x7bdddd53dda68ea7), U64_C (0xaf17175c17b84b2e),
+ U64_C (0x454747014702468e), U64_C (0x1a9e9e429e84dc21),
+ U64_C (0xd4caca0fca1ec589), U64_C (0x582d2db42d75995a),
+ U64_C (0x2ebfbfc6bf917963), U64_C (0x3f07071c07381b0e),
+ U64_C (0xacadad8ead012347), U64_C (0xb05a5a755aea2fb4),
+ U64_C (0xef838336836cb51b), U64_C (0xb63333cc3385ff66),
+ U64_C (0x5c636391633ff2c6), U64_C (0x1202020802100a04),
+ U64_C (0x93aaaa92aa393849), U64_C (0xde7171d971afa8e2),
+ U64_C (0xc6c8c807c80ecf8d), U64_C (0xd119196419c87d32),
+ U64_C (0x3b49493949727092), U64_C (0x5fd9d943d9869aaf),
+ U64_C (0x31f2f2eff2c31df9), U64_C (0xa8e3e3abe34b48db),
+ U64_C (0xb95b5b715be22ab6), U64_C (0xbc88881a8834920d),
+ U64_C (0x3e9a9a529aa4c829), U64_C (0x0b262698262dbe4c),
+ U64_C (0xbf3232c8328dfa64), U64_C (0x59b0b0fab0e94a7d),
+ U64_C (0xf2e9e983e91b6acf), U64_C (0x770f0f3c0f78331e),
+ U64_C (0x33d5d573d5e6a6b7), U64_C (0xf480803a8074ba1d),
+ U64_C (0x27bebec2be997c61), U64_C (0xebcdcd13cd26de87),
+ U64_C (0x893434d034bde468), U64_C (0x3248483d487a7590),
+ U64_C (0x54ffffdbffab24e3), U64_C (0x8d7a7af57af78ff4),
+ U64_C (0x6490907a90f4ea3d), U64_C (0x9d5f5f615fc23ebe),
+ U64_C (0x3d202080201da040), U64_C (0x0f6868bd6867d5d0),
+ U64_C (0xca1a1a681ad07234), U64_C (0xb7aeae82ae192c41),
+ U64_C (0x7db4b4eab4c95e75), U64_C (0xce54544d549a19a8),
+ U64_C (0x7f93937693ece53b), U64_C (0x2f222288220daa44),
+ U64_C (0x6364648d6407e9c8), U64_C (0x2af1f1e3f1db12ff),
+ U64_C (0xcc7373d173bfa2e6), U64_C (0x8212124812905a24),
+ U64_C (0x7a40401d403a5d80), U64_C (0x4808082008402810),
+ U64_C (0x95c3c32bc356e89b), U64_C (0xdfecec97ec337bc5),
+ U64_C (0x4ddbdb4bdb9690ab), U64_C (0xc0a1a1bea1611f5f),
+ U64_C (0x918d8d0e8d1c8307), U64_C (0xc83d3df43df5c97a),
+ U64_C (0x5b97976697ccf133), U64_C (0x0000000000000000),
+ U64_C (0xf9cfcf1bcf36d483), U64_C (0x6e2b2bac2b458756),
+ U64_C (0xe17676c57697b3ec), U64_C (0xe68282328264b019),
+ U64_C (0x28d6d67fd6fea9b1), U64_C (0xc31b1b6c1bd87736),
+ U64_C (0x74b5b5eeb5c15b77), U64_C (0xbeafaf86af112943),
+ U64_C (0x1d6a6ab56a77dfd4), U64_C (0xea50505d50ba0da0),
+ U64_C (0x5745450945124c8a), U64_C (0x38f3f3ebf3cb18fb),
+ U64_C (0xad3030c0309df060), U64_C (0xc4efef9bef2b74c3),
+ U64_C (0xda3f3ffc3fe5c37e), U64_C (0xc755554955921caa),
+ U64_C (0xdba2a2b2a2791059), U64_C (0xe9eaea8fea0365c9),
+ U64_C (0x6a656589650fecca), U64_C (0x03babad2bab96869),
+ U64_C (0x4a2f2fbc2f65935e), U64_C (0x8ec0c027c04ee79d),
+ U64_C (0x60dede5fdebe81a1), U64_C (0xfc1c1c701ce06c38),
+ U64_C (0x46fdfdd3fdbb2ee7), U64_C (0x1f4d4d294d52649a),
+ U64_C (0x7692927292e4e039), U64_C (0xfa7575c9758fbcea),
+ U64_C (0x3606061806301e0c), U64_C (0xae8a8a128a249809),
+ U64_C (0x4bb2b2f2b2f94079), U64_C (0x85e6e6bfe66359d1),
+ U64_C (0x7e0e0e380e70361c), U64_C (0xe71f1f7c1ff8633e),
+ U64_C (0x556262956237f7c4), U64_C (0x3ad4d477d4eea3b5),
+ U64_C (0x81a8a89aa829324d), U64_C (0x5296966296c4f431),
+ U64_C (0x62f9f9c3f99b3aef), U64_C (0xa3c5c533c566f697),
+ U64_C (0x102525942535b14a), U64_C (0xab59597959f220b2),
+ U64_C (0xd084842a8454ae15), U64_C (0xc57272d572b7a7e4),
+ U64_C (0xec3939e439d5dd72), U64_C (0x164c4c2d4c5a6198),
+ U64_C (0x945e5e655eca3bbc), U64_C (0x9f7878fd78e785f0),
+ U64_C (0xe53838e038ddd870), U64_C (0x988c8c0a8c148605),
+ U64_C (0x17d1d163d1c6b2bf), U64_C (0xe4a5a5aea5410b57),
+ U64_C (0xa1e2e2afe2434dd9), U64_C (0x4e616199612ff8c2),
+ U64_C (0x42b3b3f6b3f1457b), U64_C (0x342121842115a542),
+ U64_C (0x089c9c4a9c94d625), U64_C (0xee1e1e781ef0663c),
+ U64_C (0x6143431143225286), U64_C (0xb1c7c73bc776fc93),
+ U64_C (0x4ffcfcd7fcb32be5), U64_C (0x2404041004201408),
+ U64_C (0xe351515951b208a2), U64_C (0x2599995e99bcc72f),
+ U64_C (0x226d6da96d4fc4da), U64_C (0x650d0d340d68391a),
+ U64_C (0x79fafacffa8335e9), U64_C (0x69dfdf5bdfb684a3),
+ U64_C (0xa97e7ee57ed79bfc), U64_C (0x19242490243db448),
+ U64_C (0xfe3b3bec3bc5d776), U64_C (0x9aabab96ab313d4b),
+ U64_C (0xf0cece1fce3ed181), U64_C (0x9911114411885522),
+ U64_C (0x838f8f068f0c8903), U64_C (0x044e4e254e4a6b9c),
+ U64_C (0x66b7b7e6b7d15173), U64_C (0xe0ebeb8beb0b60cb),
+ U64_C (0xc13c3cf03cfdcc78), U64_C (0xfd81813e817cbf1f),
+ U64_C (0x4094946a94d4fe35), U64_C (0x1cf7f7fbf7eb0cf3),
+ U64_C (0x18b9b9deb9a1676f), U64_C (0x8b13134c13985f26),
+ U64_C (0x512c2cb02c7d9c58), U64_C (0x05d3d36bd3d6b8bb),
+ U64_C (0x8ce7e7bbe76b5cd3), U64_C (0x396e6ea56e57cbdc),
+ U64_C (0xaac4c437c46ef395), U64_C (0x1b03030c03180f06),
+ U64_C (0xdc565645568a13ac), U64_C (0x5e44440d441a4988),
+ U64_C (0xa07f7fe17fdf9efe), U64_C (0x88a9a99ea921374f),
+ U64_C (0x672a2aa82a4d8254), U64_C (0x0abbbbd6bbb16d6b),
+ U64_C (0x87c1c123c146e29f), U64_C (0xf153535153a202a6),
+ U64_C (0x72dcdc57dcae8ba5), U64_C (0x530b0b2c0b582716),
+ U64_C (0x019d9d4e9d9cd327), U64_C (0x2b6c6cad6c47c1d8),
+ U64_C (0xa43131c43195f562), U64_C (0xf37474cd7487b9e8),
+ U64_C (0x15f6f6fff6e309f1), U64_C (0x4c464605460a438c),
+ U64_C (0xa5acac8aac092645), U64_C (0xb589891e893c970f),
+ U64_C (0xb414145014a04428), U64_C (0xbae1e1a3e15b42df),
+ U64_C (0xa616165816b04e2c), U64_C (0xf73a3ae83acdd274),
+ U64_C (0x066969b9696fd0d2), U64_C (0x4109092409482d12),
+ U64_C (0xd77070dd70a7ade0), U64_C (0x6fb6b6e2b6d95471),
+ U64_C (0x1ed0d067d0ceb7bd), U64_C (0xd6eded93ed3b7ec7),
+ U64_C (0xe2cccc17cc2edb85), U64_C (0x68424215422a5784),
+ U64_C (0x2c98985a98b4c22d), U64_C (0xeda4a4aaa4490e55),
+ U64_C (0x752828a0285d8850), U64_C (0x865c5c6d5cda31b8),
+ U64_C (0x6bf8f8c7f8933fed), U64_C (0xc28686228644a411),
+ }, {
+ U64_C (0x30d818186018c078), U64_C (0x462623238c2305af),
+ U64_C (0x91b8c6c63fc67ef9), U64_C (0xcdfbe8e887e8136f),
+ U64_C (0x13cb878726874ca1), U64_C (0x6d11b8b8dab8a962),
+ U64_C (0x0209010104010805), U64_C (0x9e0d4f4f214f426e),
+ U64_C (0x6c9b3636d836adee), U64_C (0x51ffa6a6a2a65904),
+ U64_C (0xb90cd2d26fd2debd), U64_C (0xf70ef5f5f3f5fb06),
+ U64_C (0xf2967979f979ef80), U64_C (0xde306f6fa16f5fce),
+ U64_C (0x3f6d91917e91fcef), U64_C (0xa4f852525552aa07),
+ U64_C (0xc04760609d6027fd), U64_C (0x6535bcbccabc8976),
+ U64_C (0x2b379b9b569baccd), U64_C (0x018a8e8e028e048c),
+ U64_C (0x5bd2a3a3b6a37115), U64_C (0x186c0c0c300c603c),
+ U64_C (0xf6847b7bf17bff8a), U64_C (0x6a803535d435b5e1),
+ U64_C (0x3af51d1d741de869), U64_C (0xddb3e0e0a7e05347),
+ U64_C (0xb321d7d77bd7f6ac), U64_C (0x999cc2c22fc25eed),
+ U64_C (0x5c432e2eb82e6d96), U64_C (0x96294b4b314b627a),
+ U64_C (0xe15dfefedffea321), U64_C (0xaed5575741578216),
+ U64_C (0x2abd15155415a841), U64_C (0xeee87777c1779fb6),
+ U64_C (0x6e923737dc37a5eb), U64_C (0xd79ee5e5b3e57b56),
+ U64_C (0x23139f9f469f8cd9), U64_C (0xfd23f0f0e7f0d317),
+ U64_C (0x94204a4a354a6a7f), U64_C (0xa944dada4fda9e95),
+ U64_C (0xb0a258587d58fa25), U64_C (0x8fcfc9c903c906ca),
+ U64_C (0x527c2929a429558d), U64_C (0x145a0a0a280a5022),
+ U64_C (0x7f50b1b1feb1e14f), U64_C (0x5dc9a0a0baa0691a),
+ U64_C (0xd6146b6bb16b7fda), U64_C (0x17d985852e855cab),
+ U64_C (0x673cbdbdcebd8173), U64_C (0xba8f5d5d695dd234),
+ U64_C (0x2090101040108050), U64_C (0xf507f4f4f7f4f303),
+ U64_C (0x8bddcbcb0bcb16c0), U64_C (0x7cd33e3ef83eedc6),
+ U64_C (0x0a2d050514052811), U64_C (0xce78676781671fe6),
+ U64_C (0xd597e4e4b7e47353), U64_C (0x4e0227279c2725bb),
+ U64_C (0x8273414119413258), U64_C (0x0ba78b8b168b2c9d),
+ U64_C (0x53f6a7a7a6a75101), U64_C (0xfab27d7de97dcf94),
+ U64_C (0x374995956e95dcfb), U64_C (0xad56d8d847d88e9f),
+ U64_C (0xeb70fbfbcbfb8b30), U64_C (0xc1cdeeee9fee2371),
+ U64_C (0xf8bb7c7ced7cc791), U64_C (0xcc716666856617e3),
+ U64_C (0xa77bdddd53dda68e), U64_C (0x2eaf17175c17b84b),
+ U64_C (0x8e45474701470246), U64_C (0x211a9e9e429e84dc),
+ U64_C (0x89d4caca0fca1ec5), U64_C (0x5a582d2db42d7599),
+ U64_C (0x632ebfbfc6bf9179), U64_C (0x0e3f07071c07381b),
+ U64_C (0x47acadad8ead0123), U64_C (0xb4b05a5a755aea2f),
+ U64_C (0x1bef838336836cb5), U64_C (0x66b63333cc3385ff),
+ U64_C (0xc65c636391633ff2), U64_C (0x041202020802100a),
+ U64_C (0x4993aaaa92aa3938), U64_C (0xe2de7171d971afa8),
+ U64_C (0x8dc6c8c807c80ecf), U64_C (0x32d119196419c87d),
+ U64_C (0x923b494939497270), U64_C (0xaf5fd9d943d9869a),
+ U64_C (0xf931f2f2eff2c31d), U64_C (0xdba8e3e3abe34b48),
+ U64_C (0xb6b95b5b715be22a), U64_C (0x0dbc88881a883492),
+ U64_C (0x293e9a9a529aa4c8), U64_C (0x4c0b262698262dbe),
+ U64_C (0x64bf3232c8328dfa), U64_C (0x7d59b0b0fab0e94a),
+ U64_C (0xcff2e9e983e91b6a), U64_C (0x1e770f0f3c0f7833),
+ U64_C (0xb733d5d573d5e6a6), U64_C (0x1df480803a8074ba),
+ U64_C (0x6127bebec2be997c), U64_C (0x87ebcdcd13cd26de),
+ U64_C (0x68893434d034bde4), U64_C (0x903248483d487a75),
+ U64_C (0xe354ffffdbffab24), U64_C (0xf48d7a7af57af78f),
+ U64_C (0x3d6490907a90f4ea), U64_C (0xbe9d5f5f615fc23e),
+ U64_C (0x403d202080201da0), U64_C (0xd00f6868bd6867d5),
+ U64_C (0x34ca1a1a681ad072), U64_C (0x41b7aeae82ae192c),
+ U64_C (0x757db4b4eab4c95e), U64_C (0xa8ce54544d549a19),
+ U64_C (0x3b7f93937693ece5), U64_C (0x442f222288220daa),
+ U64_C (0xc86364648d6407e9), U64_C (0xff2af1f1e3f1db12),
+ U64_C (0xe6cc7373d173bfa2), U64_C (0x248212124812905a),
+ U64_C (0x807a40401d403a5d), U64_C (0x1048080820084028),
+ U64_C (0x9b95c3c32bc356e8), U64_C (0xc5dfecec97ec337b),
+ U64_C (0xab4ddbdb4bdb9690), U64_C (0x5fc0a1a1bea1611f),
+ U64_C (0x07918d8d0e8d1c83), U64_C (0x7ac83d3df43df5c9),
+ U64_C (0x335b97976697ccf1), U64_C (0x0000000000000000),
+ U64_C (0x83f9cfcf1bcf36d4), U64_C (0x566e2b2bac2b4587),
+ U64_C (0xece17676c57697b3), U64_C (0x19e68282328264b0),
+ U64_C (0xb128d6d67fd6fea9), U64_C (0x36c31b1b6c1bd877),
+ U64_C (0x7774b5b5eeb5c15b), U64_C (0x43beafaf86af1129),
+ U64_C (0xd41d6a6ab56a77df), U64_C (0xa0ea50505d50ba0d),
+ U64_C (0x8a5745450945124c), U64_C (0xfb38f3f3ebf3cb18),
+ U64_C (0x60ad3030c0309df0), U64_C (0xc3c4efef9bef2b74),
+ U64_C (0x7eda3f3ffc3fe5c3), U64_C (0xaac755554955921c),
+ U64_C (0x59dba2a2b2a27910), U64_C (0xc9e9eaea8fea0365),
+ U64_C (0xca6a656589650fec), U64_C (0x6903babad2bab968),
+ U64_C (0x5e4a2f2fbc2f6593), U64_C (0x9d8ec0c027c04ee7),
+ U64_C (0xa160dede5fdebe81), U64_C (0x38fc1c1c701ce06c),
+ U64_C (0xe746fdfdd3fdbb2e), U64_C (0x9a1f4d4d294d5264),
+ U64_C (0x397692927292e4e0), U64_C (0xeafa7575c9758fbc),
+ U64_C (0x0c3606061806301e), U64_C (0x09ae8a8a128a2498),
+ U64_C (0x794bb2b2f2b2f940), U64_C (0xd185e6e6bfe66359),
+ U64_C (0x1c7e0e0e380e7036), U64_C (0x3ee71f1f7c1ff863),
+ U64_C (0xc4556262956237f7), U64_C (0xb53ad4d477d4eea3),
+ U64_C (0x4d81a8a89aa82932), U64_C (0x315296966296c4f4),
+ U64_C (0xef62f9f9c3f99b3a), U64_C (0x97a3c5c533c566f6),
+ U64_C (0x4a102525942535b1), U64_C (0xb2ab59597959f220),
+ U64_C (0x15d084842a8454ae), U64_C (0xe4c57272d572b7a7),
+ U64_C (0x72ec3939e439d5dd), U64_C (0x98164c4c2d4c5a61),
+ U64_C (0xbc945e5e655eca3b), U64_C (0xf09f7878fd78e785),
+ U64_C (0x70e53838e038ddd8), U64_C (0x05988c8c0a8c1486),
+ U64_C (0xbf17d1d163d1c6b2), U64_C (0x57e4a5a5aea5410b),
+ U64_C (0xd9a1e2e2afe2434d), U64_C (0xc24e616199612ff8),
+ U64_C (0x7b42b3b3f6b3f145), U64_C (0x42342121842115a5),
+ U64_C (0x25089c9c4a9c94d6), U64_C (0x3cee1e1e781ef066),
+ U64_C (0x8661434311432252), U64_C (0x93b1c7c73bc776fc),
+ U64_C (0xe54ffcfcd7fcb32b), U64_C (0x0824040410042014),
+ U64_C (0xa2e351515951b208), U64_C (0x2f2599995e99bcc7),
+ U64_C (0xda226d6da96d4fc4), U64_C (0x1a650d0d340d6839),
+ U64_C (0xe979fafacffa8335), U64_C (0xa369dfdf5bdfb684),
+ U64_C (0xfca97e7ee57ed79b), U64_C (0x4819242490243db4),
+ U64_C (0x76fe3b3bec3bc5d7), U64_C (0x4b9aabab96ab313d),
+ U64_C (0x81f0cece1fce3ed1), U64_C (0x2299111144118855),
+ U64_C (0x03838f8f068f0c89), U64_C (0x9c044e4e254e4a6b),
+ U64_C (0x7366b7b7e6b7d151), U64_C (0xcbe0ebeb8beb0b60),
+ U64_C (0x78c13c3cf03cfdcc), U64_C (0x1ffd81813e817cbf),
+ U64_C (0x354094946a94d4fe), U64_C (0xf31cf7f7fbf7eb0c),
+ U64_C (0x6f18b9b9deb9a167), U64_C (0x268b13134c13985f),
+ U64_C (0x58512c2cb02c7d9c), U64_C (0xbb05d3d36bd3d6b8),
+ U64_C (0xd38ce7e7bbe76b5c), U64_C (0xdc396e6ea56e57cb),
+ U64_C (0x95aac4c437c46ef3), U64_C (0x061b03030c03180f),
+ U64_C (0xacdc565645568a13), U64_C (0x885e44440d441a49),
+ U64_C (0xfea07f7fe17fdf9e), U64_C (0x4f88a9a99ea92137),
+ U64_C (0x54672a2aa82a4d82), U64_C (0x6b0abbbbd6bbb16d),
+ U64_C (0x9f87c1c123c146e2), U64_C (0xa6f153535153a202),
+ U64_C (0xa572dcdc57dcae8b), U64_C (0x16530b0b2c0b5827),
+ U64_C (0x27019d9d4e9d9cd3), U64_C (0xd82b6c6cad6c47c1),
+ U64_C (0x62a43131c43195f5), U64_C (0xe8f37474cd7487b9),
+ U64_C (0xf115f6f6fff6e309), U64_C (0x8c4c464605460a43),
+ U64_C (0x45a5acac8aac0926), U64_C (0x0fb589891e893c97),
+ U64_C (0x28b414145014a044), U64_C (0xdfbae1e1a3e15b42),
+ U64_C (0x2ca616165816b04e), U64_C (0x74f73a3ae83acdd2),
+ U64_C (0xd2066969b9696fd0), U64_C (0x124109092409482d),
+ U64_C (0xe0d77070dd70a7ad), U64_C (0x716fb6b6e2b6d954),
+ U64_C (0xbd1ed0d067d0ceb7), U64_C (0xc7d6eded93ed3b7e),
+ U64_C (0x85e2cccc17cc2edb), U64_C (0x8468424215422a57),
+ U64_C (0x2d2c98985a98b4c2), U64_C (0x55eda4a4aaa4490e),
+ U64_C (0x50752828a0285d88), U64_C (0xb8865c5c6d5cda31),
+ U64_C (0xed6bf8f8c7f8933f), U64_C (0x11c28686228644a4),
+ }, {
+ U64_C (0x7830d818186018c0), U64_C (0xaf462623238c2305),
+ U64_C (0xf991b8c6c63fc67e), U64_C (0x6fcdfbe8e887e813),
+ U64_C (0xa113cb878726874c), U64_C (0x626d11b8b8dab8a9),
+ U64_C (0x0502090101040108), U64_C (0x6e9e0d4f4f214f42),
+ U64_C (0xee6c9b3636d836ad), U64_C (0x0451ffa6a6a2a659),
+ U64_C (0xbdb90cd2d26fd2de), U64_C (0x06f70ef5f5f3f5fb),
+ U64_C (0x80f2967979f979ef), U64_C (0xcede306f6fa16f5f),
+ U64_C (0xef3f6d91917e91fc), U64_C (0x07a4f852525552aa),
+ U64_C (0xfdc04760609d6027), U64_C (0x766535bcbccabc89),
+ U64_C (0xcd2b379b9b569bac), U64_C (0x8c018a8e8e028e04),
+ U64_C (0x155bd2a3a3b6a371), U64_C (0x3c186c0c0c300c60),
+ U64_C (0x8af6847b7bf17bff), U64_C (0xe16a803535d435b5),
+ U64_C (0x693af51d1d741de8), U64_C (0x47ddb3e0e0a7e053),
+ U64_C (0xacb321d7d77bd7f6), U64_C (0xed999cc2c22fc25e),
+ U64_C (0x965c432e2eb82e6d), U64_C (0x7a96294b4b314b62),
+ U64_C (0x21e15dfefedffea3), U64_C (0x16aed55757415782),
+ U64_C (0x412abd15155415a8), U64_C (0xb6eee87777c1779f),
+ U64_C (0xeb6e923737dc37a5), U64_C (0x56d79ee5e5b3e57b),
+ U64_C (0xd923139f9f469f8c), U64_C (0x17fd23f0f0e7f0d3),
+ U64_C (0x7f94204a4a354a6a), U64_C (0x95a944dada4fda9e),
+ U64_C (0x25b0a258587d58fa), U64_C (0xca8fcfc9c903c906),
+ U64_C (0x8d527c2929a42955), U64_C (0x22145a0a0a280a50),
+ U64_C (0x4f7f50b1b1feb1e1), U64_C (0x1a5dc9a0a0baa069),
+ U64_C (0xdad6146b6bb16b7f), U64_C (0xab17d985852e855c),
+ U64_C (0x73673cbdbdcebd81), U64_C (0x34ba8f5d5d695dd2),
+ U64_C (0x5020901010401080), U64_C (0x03f507f4f4f7f4f3),
+ U64_C (0xc08bddcbcb0bcb16), U64_C (0xc67cd33e3ef83eed),
+ U64_C (0x110a2d0505140528), U64_C (0xe6ce78676781671f),
+ U64_C (0x53d597e4e4b7e473), U64_C (0xbb4e0227279c2725),
+ U64_C (0x5882734141194132), U64_C (0x9d0ba78b8b168b2c),
+ U64_C (0x0153f6a7a7a6a751), U64_C (0x94fab27d7de97dcf),
+ U64_C (0xfb374995956e95dc), U64_C (0x9fad56d8d847d88e),
+ U64_C (0x30eb70fbfbcbfb8b), U64_C (0x71c1cdeeee9fee23),
+ U64_C (0x91f8bb7c7ced7cc7), U64_C (0xe3cc716666856617),
+ U64_C (0x8ea77bdddd53dda6), U64_C (0x4b2eaf17175c17b8),
+ U64_C (0x468e454747014702), U64_C (0xdc211a9e9e429e84),
+ U64_C (0xc589d4caca0fca1e), U64_C (0x995a582d2db42d75),
+ U64_C (0x79632ebfbfc6bf91), U64_C (0x1b0e3f07071c0738),
+ U64_C (0x2347acadad8ead01), U64_C (0x2fb4b05a5a755aea),
+ U64_C (0xb51bef838336836c), U64_C (0xff66b63333cc3385),
+ U64_C (0xf2c65c636391633f), U64_C (0x0a04120202080210),
+ U64_C (0x384993aaaa92aa39), U64_C (0xa8e2de7171d971af),
+ U64_C (0xcf8dc6c8c807c80e), U64_C (0x7d32d119196419c8),
+ U64_C (0x70923b4949394972), U64_C (0x9aaf5fd9d943d986),
+ U64_C (0x1df931f2f2eff2c3), U64_C (0x48dba8e3e3abe34b),
+ U64_C (0x2ab6b95b5b715be2), U64_C (0x920dbc88881a8834),
+ U64_C (0xc8293e9a9a529aa4), U64_C (0xbe4c0b262698262d),
+ U64_C (0xfa64bf3232c8328d), U64_C (0x4a7d59b0b0fab0e9),
+ U64_C (0x6acff2e9e983e91b), U64_C (0x331e770f0f3c0f78),
+ U64_C (0xa6b733d5d573d5e6), U64_C (0xba1df480803a8074),
+ U64_C (0x7c6127bebec2be99), U64_C (0xde87ebcdcd13cd26),
+ U64_C (0xe468893434d034bd), U64_C (0x75903248483d487a),
+ U64_C (0x24e354ffffdbffab), U64_C (0x8ff48d7a7af57af7),
+ U64_C (0xea3d6490907a90f4), U64_C (0x3ebe9d5f5f615fc2),
+ U64_C (0xa0403d202080201d), U64_C (0xd5d00f6868bd6867),
+ U64_C (0x7234ca1a1a681ad0), U64_C (0x2c41b7aeae82ae19),
+ U64_C (0x5e757db4b4eab4c9), U64_C (0x19a8ce54544d549a),
+ U64_C (0xe53b7f93937693ec), U64_C (0xaa442f222288220d),
+ U64_C (0xe9c86364648d6407), U64_C (0x12ff2af1f1e3f1db),
+ U64_C (0xa2e6cc7373d173bf), U64_C (0x5a24821212481290),
+ U64_C (0x5d807a40401d403a), U64_C (0x2810480808200840),
+ U64_C (0xe89b95c3c32bc356), U64_C (0x7bc5dfecec97ec33),
+ U64_C (0x90ab4ddbdb4bdb96), U64_C (0x1f5fc0a1a1bea161),
+ U64_C (0x8307918d8d0e8d1c), U64_C (0xc97ac83d3df43df5),
+ U64_C (0xf1335b97976697cc), U64_C (0x0000000000000000),
+ U64_C (0xd483f9cfcf1bcf36), U64_C (0x87566e2b2bac2b45),
+ U64_C (0xb3ece17676c57697), U64_C (0xb019e68282328264),
+ U64_C (0xa9b128d6d67fd6fe), U64_C (0x7736c31b1b6c1bd8),
+ U64_C (0x5b7774b5b5eeb5c1), U64_C (0x2943beafaf86af11),
+ U64_C (0xdfd41d6a6ab56a77), U64_C (0x0da0ea50505d50ba),
+ U64_C (0x4c8a574545094512), U64_C (0x18fb38f3f3ebf3cb),
+ U64_C (0xf060ad3030c0309d), U64_C (0x74c3c4efef9bef2b),
+ U64_C (0xc37eda3f3ffc3fe5), U64_C (0x1caac75555495592),
+ U64_C (0x1059dba2a2b2a279), U64_C (0x65c9e9eaea8fea03),
+ U64_C (0xecca6a656589650f), U64_C (0x686903babad2bab9),
+ U64_C (0x935e4a2f2fbc2f65), U64_C (0xe79d8ec0c027c04e),
+ U64_C (0x81a160dede5fdebe), U64_C (0x6c38fc1c1c701ce0),
+ U64_C (0x2ee746fdfdd3fdbb), U64_C (0x649a1f4d4d294d52),
+ U64_C (0xe0397692927292e4), U64_C (0xbceafa7575c9758f),
+ U64_C (0x1e0c360606180630), U64_C (0x9809ae8a8a128a24),
+ U64_C (0x40794bb2b2f2b2f9), U64_C (0x59d185e6e6bfe663),
+ U64_C (0x361c7e0e0e380e70), U64_C (0x633ee71f1f7c1ff8),
+ U64_C (0xf7c4556262956237), U64_C (0xa3b53ad4d477d4ee),
+ U64_C (0x324d81a8a89aa829), U64_C (0xf4315296966296c4),
+ U64_C (0x3aef62f9f9c3f99b), U64_C (0xf697a3c5c533c566),
+ U64_C (0xb14a102525942535), U64_C (0x20b2ab59597959f2),
+ U64_C (0xae15d084842a8454), U64_C (0xa7e4c57272d572b7),
+ U64_C (0xdd72ec3939e439d5), U64_C (0x6198164c4c2d4c5a),
+ U64_C (0x3bbc945e5e655eca), U64_C (0x85f09f7878fd78e7),
+ U64_C (0xd870e53838e038dd), U64_C (0x8605988c8c0a8c14),
+ U64_C (0xb2bf17d1d163d1c6), U64_C (0x0b57e4a5a5aea541),
+ U64_C (0x4dd9a1e2e2afe243), U64_C (0xf8c24e616199612f),
+ U64_C (0x457b42b3b3f6b3f1), U64_C (0xa542342121842115),
+ U64_C (0xd625089c9c4a9c94), U64_C (0x663cee1e1e781ef0),
+ U64_C (0x5286614343114322), U64_C (0xfc93b1c7c73bc776),
+ U64_C (0x2be54ffcfcd7fcb3), U64_C (0x1408240404100420),
+ U64_C (0x08a2e351515951b2), U64_C (0xc72f2599995e99bc),
+ U64_C (0xc4da226d6da96d4f), U64_C (0x391a650d0d340d68),
+ U64_C (0x35e979fafacffa83), U64_C (0x84a369dfdf5bdfb6),
+ U64_C (0x9bfca97e7ee57ed7), U64_C (0xb44819242490243d),
+ U64_C (0xd776fe3b3bec3bc5), U64_C (0x3d4b9aabab96ab31),
+ U64_C (0xd181f0cece1fce3e), U64_C (0x5522991111441188),
+ U64_C (0x8903838f8f068f0c), U64_C (0x6b9c044e4e254e4a),
+ U64_C (0x517366b7b7e6b7d1), U64_C (0x60cbe0ebeb8beb0b),
+ U64_C (0xcc78c13c3cf03cfd), U64_C (0xbf1ffd81813e817c),
+ U64_C (0xfe354094946a94d4), U64_C (0x0cf31cf7f7fbf7eb),
+ U64_C (0x676f18b9b9deb9a1), U64_C (0x5f268b13134c1398),
+ U64_C (0x9c58512c2cb02c7d), U64_C (0xb8bb05d3d36bd3d6),
+ U64_C (0x5cd38ce7e7bbe76b), U64_C (0xcbdc396e6ea56e57),
+ U64_C (0xf395aac4c437c46e), U64_C (0x0f061b03030c0318),
+ U64_C (0x13acdc565645568a), U64_C (0x49885e44440d441a),
+ U64_C (0x9efea07f7fe17fdf), U64_C (0x374f88a9a99ea921),
+ U64_C (0x8254672a2aa82a4d), U64_C (0x6d6b0abbbbd6bbb1),
+ U64_C (0xe29f87c1c123c146), U64_C (0x02a6f153535153a2),
+ U64_C (0x8ba572dcdc57dcae), U64_C (0x2716530b0b2c0b58),
+ U64_C (0xd327019d9d4e9d9c), U64_C (0xc1d82b6c6cad6c47),
+ U64_C (0xf562a43131c43195), U64_C (0xb9e8f37474cd7487),
+ U64_C (0x09f115f6f6fff6e3), U64_C (0x438c4c464605460a),
+ U64_C (0x2645a5acac8aac09), U64_C (0x970fb589891e893c),
+ U64_C (0x4428b414145014a0), U64_C (0x42dfbae1e1a3e15b),
+ U64_C (0x4e2ca616165816b0), U64_C (0xd274f73a3ae83acd),
+ U64_C (0xd0d2066969b9696f), U64_C (0x2d12410909240948),
+ U64_C (0xade0d77070dd70a7), U64_C (0x54716fb6b6e2b6d9),
+ U64_C (0xb7bd1ed0d067d0ce), U64_C (0x7ec7d6eded93ed3b),
+ U64_C (0xdb85e2cccc17cc2e), U64_C (0x578468424215422a),
+ U64_C (0xc22d2c98985a98b4), U64_C (0x0e55eda4a4aaa449),
+ U64_C (0x8850752828a0285d), U64_C (0x31b8865c5c6d5cda),
+ U64_C (0x3fed6bf8f8c7f893), U64_C (0xa411c28686228644),
+ }, {
+ U64_C (0xc07830d818186018), U64_C (0x05af462623238c23),
+ U64_C (0x7ef991b8c6c63fc6), U64_C (0x136fcdfbe8e887e8),
+ U64_C (0x4ca113cb87872687), U64_C (0xa9626d11b8b8dab8),
+ U64_C (0x0805020901010401), U64_C (0x426e9e0d4f4f214f),
+ U64_C (0xadee6c9b3636d836), U64_C (0x590451ffa6a6a2a6),
+ U64_C (0xdebdb90cd2d26fd2), U64_C (0xfb06f70ef5f5f3f5),
+ U64_C (0xef80f2967979f979), U64_C (0x5fcede306f6fa16f),
+ U64_C (0xfcef3f6d91917e91), U64_C (0xaa07a4f852525552),
+ U64_C (0x27fdc04760609d60), U64_C (0x89766535bcbccabc),
+ U64_C (0xaccd2b379b9b569b), U64_C (0x048c018a8e8e028e),
+ U64_C (0x71155bd2a3a3b6a3), U64_C (0x603c186c0c0c300c),
+ U64_C (0xff8af6847b7bf17b), U64_C (0xb5e16a803535d435),
+ U64_C (0xe8693af51d1d741d), U64_C (0x5347ddb3e0e0a7e0),
+ U64_C (0xf6acb321d7d77bd7), U64_C (0x5eed999cc2c22fc2),
+ U64_C (0x6d965c432e2eb82e), U64_C (0x627a96294b4b314b),
+ U64_C (0xa321e15dfefedffe), U64_C (0x8216aed557574157),
+ U64_C (0xa8412abd15155415), U64_C (0x9fb6eee87777c177),
+ U64_C (0xa5eb6e923737dc37), U64_C (0x7b56d79ee5e5b3e5),
+ U64_C (0x8cd923139f9f469f), U64_C (0xd317fd23f0f0e7f0),
+ U64_C (0x6a7f94204a4a354a), U64_C (0x9e95a944dada4fda),
+ U64_C (0xfa25b0a258587d58), U64_C (0x06ca8fcfc9c903c9),
+ U64_C (0x558d527c2929a429), U64_C (0x5022145a0a0a280a),
+ U64_C (0xe14f7f50b1b1feb1), U64_C (0x691a5dc9a0a0baa0),
+ U64_C (0x7fdad6146b6bb16b), U64_C (0x5cab17d985852e85),
+ U64_C (0x8173673cbdbdcebd), U64_C (0xd234ba8f5d5d695d),
+ U64_C (0x8050209010104010), U64_C (0xf303f507f4f4f7f4),
+ U64_C (0x16c08bddcbcb0bcb), U64_C (0xedc67cd33e3ef83e),
+ U64_C (0x28110a2d05051405), U64_C (0x1fe6ce7867678167),
+ U64_C (0x7353d597e4e4b7e4), U64_C (0x25bb4e0227279c27),
+ U64_C (0x3258827341411941), U64_C (0x2c9d0ba78b8b168b),
+ U64_C (0x510153f6a7a7a6a7), U64_C (0xcf94fab27d7de97d),
+ U64_C (0xdcfb374995956e95), U64_C (0x8e9fad56d8d847d8),
+ U64_C (0x8b30eb70fbfbcbfb), U64_C (0x2371c1cdeeee9fee),
+ U64_C (0xc791f8bb7c7ced7c), U64_C (0x17e3cc7166668566),
+ U64_C (0xa68ea77bdddd53dd), U64_C (0xb84b2eaf17175c17),
+ U64_C (0x02468e4547470147), U64_C (0x84dc211a9e9e429e),
+ U64_C (0x1ec589d4caca0fca), U64_C (0x75995a582d2db42d),
+ U64_C (0x9179632ebfbfc6bf), U64_C (0x381b0e3f07071c07),
+ U64_C (0x012347acadad8ead), U64_C (0xea2fb4b05a5a755a),
+ U64_C (0x6cb51bef83833683), U64_C (0x85ff66b63333cc33),
+ U64_C (0x3ff2c65c63639163), U64_C (0x100a041202020802),
+ U64_C (0x39384993aaaa92aa), U64_C (0xafa8e2de7171d971),
+ U64_C (0x0ecf8dc6c8c807c8), U64_C (0xc87d32d119196419),
+ U64_C (0x7270923b49493949), U64_C (0x869aaf5fd9d943d9),
+ U64_C (0xc31df931f2f2eff2), U64_C (0x4b48dba8e3e3abe3),
+ U64_C (0xe22ab6b95b5b715b), U64_C (0x34920dbc88881a88),
+ U64_C (0xa4c8293e9a9a529a), U64_C (0x2dbe4c0b26269826),
+ U64_C (0x8dfa64bf3232c832), U64_C (0xe94a7d59b0b0fab0),
+ U64_C (0x1b6acff2e9e983e9), U64_C (0x78331e770f0f3c0f),
+ U64_C (0xe6a6b733d5d573d5), U64_C (0x74ba1df480803a80),
+ U64_C (0x997c6127bebec2be), U64_C (0x26de87ebcdcd13cd),
+ U64_C (0xbde468893434d034), U64_C (0x7a75903248483d48),
+ U64_C (0xab24e354ffffdbff), U64_C (0xf78ff48d7a7af57a),
+ U64_C (0xf4ea3d6490907a90), U64_C (0xc23ebe9d5f5f615f),
+ U64_C (0x1da0403d20208020), U64_C (0x67d5d00f6868bd68),
+ U64_C (0xd07234ca1a1a681a), U64_C (0x192c41b7aeae82ae),
+ U64_C (0xc95e757db4b4eab4), U64_C (0x9a19a8ce54544d54),
+ U64_C (0xece53b7f93937693), U64_C (0x0daa442f22228822),
+ U64_C (0x07e9c86364648d64), U64_C (0xdb12ff2af1f1e3f1),
+ U64_C (0xbfa2e6cc7373d173), U64_C (0x905a248212124812),
+ U64_C (0x3a5d807a40401d40), U64_C (0x4028104808082008),
+ U64_C (0x56e89b95c3c32bc3), U64_C (0x337bc5dfecec97ec),
+ U64_C (0x9690ab4ddbdb4bdb), U64_C (0x611f5fc0a1a1bea1),
+ U64_C (0x1c8307918d8d0e8d), U64_C (0xf5c97ac83d3df43d),
+ U64_C (0xccf1335b97976697), U64_C (0x0000000000000000),
+ U64_C (0x36d483f9cfcf1bcf), U64_C (0x4587566e2b2bac2b),
+ U64_C (0x97b3ece17676c576), U64_C (0x64b019e682823282),
+ U64_C (0xfea9b128d6d67fd6), U64_C (0xd87736c31b1b6c1b),
+ U64_C (0xc15b7774b5b5eeb5), U64_C (0x112943beafaf86af),
+ U64_C (0x77dfd41d6a6ab56a), U64_C (0xba0da0ea50505d50),
+ U64_C (0x124c8a5745450945), U64_C (0xcb18fb38f3f3ebf3),
+ U64_C (0x9df060ad3030c030), U64_C (0x2b74c3c4efef9bef),
+ U64_C (0xe5c37eda3f3ffc3f), U64_C (0x921caac755554955),
+ U64_C (0x791059dba2a2b2a2), U64_C (0x0365c9e9eaea8fea),
+ U64_C (0x0fecca6a65658965), U64_C (0xb9686903babad2ba),
+ U64_C (0x65935e4a2f2fbc2f), U64_C (0x4ee79d8ec0c027c0),
+ U64_C (0xbe81a160dede5fde), U64_C (0xe06c38fc1c1c701c),
+ U64_C (0xbb2ee746fdfdd3fd), U64_C (0x52649a1f4d4d294d),
+ U64_C (0xe4e0397692927292), U64_C (0x8fbceafa7575c975),
+ U64_C (0x301e0c3606061806), U64_C (0x249809ae8a8a128a),
+ U64_C (0xf940794bb2b2f2b2), U64_C (0x6359d185e6e6bfe6),
+ U64_C (0x70361c7e0e0e380e), U64_C (0xf8633ee71f1f7c1f),
+ U64_C (0x37f7c45562629562), U64_C (0xeea3b53ad4d477d4),
+ U64_C (0x29324d81a8a89aa8), U64_C (0xc4f4315296966296),
+ U64_C (0x9b3aef62f9f9c3f9), U64_C (0x66f697a3c5c533c5),
+ U64_C (0x35b14a1025259425), U64_C (0xf220b2ab59597959),
+ U64_C (0x54ae15d084842a84), U64_C (0xb7a7e4c57272d572),
+ U64_C (0xd5dd72ec3939e439), U64_C (0x5a6198164c4c2d4c),
+ U64_C (0xca3bbc945e5e655e), U64_C (0xe785f09f7878fd78),
+ U64_C (0xddd870e53838e038), U64_C (0x148605988c8c0a8c),
+ U64_C (0xc6b2bf17d1d163d1), U64_C (0x410b57e4a5a5aea5),
+ U64_C (0x434dd9a1e2e2afe2), U64_C (0x2ff8c24e61619961),
+ U64_C (0xf1457b42b3b3f6b3), U64_C (0x15a5423421218421),
+ U64_C (0x94d625089c9c4a9c), U64_C (0xf0663cee1e1e781e),
+ U64_C (0x2252866143431143), U64_C (0x76fc93b1c7c73bc7),
+ U64_C (0xb32be54ffcfcd7fc), U64_C (0x2014082404041004),
+ U64_C (0xb208a2e351515951), U64_C (0xbcc72f2599995e99),
+ U64_C (0x4fc4da226d6da96d), U64_C (0x68391a650d0d340d),
+ U64_C (0x8335e979fafacffa), U64_C (0xb684a369dfdf5bdf),
+ U64_C (0xd79bfca97e7ee57e), U64_C (0x3db4481924249024),
+ U64_C (0xc5d776fe3b3bec3b), U64_C (0x313d4b9aabab96ab),
+ U64_C (0x3ed181f0cece1fce), U64_C (0x8855229911114411),
+ U64_C (0x0c8903838f8f068f), U64_C (0x4a6b9c044e4e254e),
+ U64_C (0xd1517366b7b7e6b7), U64_C (0x0b60cbe0ebeb8beb),
+ U64_C (0xfdcc78c13c3cf03c), U64_C (0x7cbf1ffd81813e81),
+ U64_C (0xd4fe354094946a94), U64_C (0xeb0cf31cf7f7fbf7),
+ U64_C (0xa1676f18b9b9deb9), U64_C (0x985f268b13134c13),
+ U64_C (0x7d9c58512c2cb02c), U64_C (0xd6b8bb05d3d36bd3),
+ U64_C (0x6b5cd38ce7e7bbe7), U64_C (0x57cbdc396e6ea56e),
+ U64_C (0x6ef395aac4c437c4), U64_C (0x180f061b03030c03),
+ U64_C (0x8a13acdc56564556), U64_C (0x1a49885e44440d44),
+ U64_C (0xdf9efea07f7fe17f), U64_C (0x21374f88a9a99ea9),
+ U64_C (0x4d8254672a2aa82a), U64_C (0xb16d6b0abbbbd6bb),
+ U64_C (0x46e29f87c1c123c1), U64_C (0xa202a6f153535153),
+ U64_C (0xae8ba572dcdc57dc), U64_C (0x582716530b0b2c0b),
+ U64_C (0x9cd327019d9d4e9d), U64_C (0x47c1d82b6c6cad6c),
+ U64_C (0x95f562a43131c431), U64_C (0x87b9e8f37474cd74),
+ U64_C (0xe309f115f6f6fff6), U64_C (0x0a438c4c46460546),
+ U64_C (0x092645a5acac8aac), U64_C (0x3c970fb589891e89),
+ U64_C (0xa04428b414145014), U64_C (0x5b42dfbae1e1a3e1),
+ U64_C (0xb04e2ca616165816), U64_C (0xcdd274f73a3ae83a),
+ U64_C (0x6fd0d2066969b969), U64_C (0x482d124109092409),
+ U64_C (0xa7ade0d77070dd70), U64_C (0xd954716fb6b6e2b6),
+ U64_C (0xceb7bd1ed0d067d0), U64_C (0x3b7ec7d6eded93ed),
+ U64_C (0x2edb85e2cccc17cc), U64_C (0x2a57846842421542),
+ U64_C (0xb4c22d2c98985a98), U64_C (0x490e55eda4a4aaa4),
+ U64_C (0x5d8850752828a028), U64_C (0xda31b8865c5c6d5c),
+ U64_C (0x933fed6bf8f8c7f8), U64_C (0x44a411c286862286),
+ }, {
+ U64_C (0x18c07830d8181860), U64_C (0x2305af462623238c),
+ U64_C (0xc67ef991b8c6c63f), U64_C (0xe8136fcdfbe8e887),
+ U64_C (0x874ca113cb878726), U64_C (0xb8a9626d11b8b8da),
+ U64_C (0x0108050209010104), U64_C (0x4f426e9e0d4f4f21),
+ U64_C (0x36adee6c9b3636d8), U64_C (0xa6590451ffa6a6a2),
+ U64_C (0xd2debdb90cd2d26f), U64_C (0xf5fb06f70ef5f5f3),
+ U64_C (0x79ef80f2967979f9), U64_C (0x6f5fcede306f6fa1),
+ U64_C (0x91fcef3f6d91917e), U64_C (0x52aa07a4f8525255),
+ U64_C (0x6027fdc04760609d), U64_C (0xbc89766535bcbcca),
+ U64_C (0x9baccd2b379b9b56), U64_C (0x8e048c018a8e8e02),
+ U64_C (0xa371155bd2a3a3b6), U64_C (0x0c603c186c0c0c30),
+ U64_C (0x7bff8af6847b7bf1), U64_C (0x35b5e16a803535d4),
+ U64_C (0x1de8693af51d1d74), U64_C (0xe05347ddb3e0e0a7),
+ U64_C (0xd7f6acb321d7d77b), U64_C (0xc25eed999cc2c22f),
+ U64_C (0x2e6d965c432e2eb8), U64_C (0x4b627a96294b4b31),
+ U64_C (0xfea321e15dfefedf), U64_C (0x578216aed5575741),
+ U64_C (0x15a8412abd151554), U64_C (0x779fb6eee87777c1),
+ U64_C (0x37a5eb6e923737dc), U64_C (0xe57b56d79ee5e5b3),
+ U64_C (0x9f8cd923139f9f46), U64_C (0xf0d317fd23f0f0e7),
+ U64_C (0x4a6a7f94204a4a35), U64_C (0xda9e95a944dada4f),
+ U64_C (0x58fa25b0a258587d), U64_C (0xc906ca8fcfc9c903),
+ U64_C (0x29558d527c2929a4), U64_C (0x0a5022145a0a0a28),
+ U64_C (0xb1e14f7f50b1b1fe), U64_C (0xa0691a5dc9a0a0ba),
+ U64_C (0x6b7fdad6146b6bb1), U64_C (0x855cab17d985852e),
+ U64_C (0xbd8173673cbdbdce), U64_C (0x5dd234ba8f5d5d69),
+ U64_C (0x1080502090101040), U64_C (0xf4f303f507f4f4f7),
+ U64_C (0xcb16c08bddcbcb0b), U64_C (0x3eedc67cd33e3ef8),
+ U64_C (0x0528110a2d050514), U64_C (0x671fe6ce78676781),
+ U64_C (0xe47353d597e4e4b7), U64_C (0x2725bb4e0227279c),
+ U64_C (0x4132588273414119), U64_C (0x8b2c9d0ba78b8b16),
+ U64_C (0xa7510153f6a7a7a6), U64_C (0x7dcf94fab27d7de9),
+ U64_C (0x95dcfb374995956e), U64_C (0xd88e9fad56d8d847),
+ U64_C (0xfb8b30eb70fbfbcb), U64_C (0xee2371c1cdeeee9f),
+ U64_C (0x7cc791f8bb7c7ced), U64_C (0x6617e3cc71666685),
+ U64_C (0xdda68ea77bdddd53), U64_C (0x17b84b2eaf17175c),
+ U64_C (0x4702468e45474701), U64_C (0x9e84dc211a9e9e42),
+ U64_C (0xca1ec589d4caca0f), U64_C (0x2d75995a582d2db4),
+ U64_C (0xbf9179632ebfbfc6), U64_C (0x07381b0e3f07071c),
+ U64_C (0xad012347acadad8e), U64_C (0x5aea2fb4b05a5a75),
+ U64_C (0x836cb51bef838336), U64_C (0x3385ff66b63333cc),
+ U64_C (0x633ff2c65c636391), U64_C (0x02100a0412020208),
+ U64_C (0xaa39384993aaaa92), U64_C (0x71afa8e2de7171d9),
+ U64_C (0xc80ecf8dc6c8c807), U64_C (0x19c87d32d1191964),
+ U64_C (0x497270923b494939), U64_C (0xd9869aaf5fd9d943),
+ U64_C (0xf2c31df931f2f2ef), U64_C (0xe34b48dba8e3e3ab),
+ U64_C (0x5be22ab6b95b5b71), U64_C (0x8834920dbc88881a),
+ U64_C (0x9aa4c8293e9a9a52), U64_C (0x262dbe4c0b262698),
+ U64_C (0x328dfa64bf3232c8), U64_C (0xb0e94a7d59b0b0fa),
+ U64_C (0xe91b6acff2e9e983), U64_C (0x0f78331e770f0f3c),
+ U64_C (0xd5e6a6b733d5d573), U64_C (0x8074ba1df480803a),
+ U64_C (0xbe997c6127bebec2), U64_C (0xcd26de87ebcdcd13),
+ U64_C (0x34bde468893434d0), U64_C (0x487a75903248483d),
+ U64_C (0xffab24e354ffffdb), U64_C (0x7af78ff48d7a7af5),
+ U64_C (0x90f4ea3d6490907a), U64_C (0x5fc23ebe9d5f5f61),
+ U64_C (0x201da0403d202080), U64_C (0x6867d5d00f6868bd),
+ U64_C (0x1ad07234ca1a1a68), U64_C (0xae192c41b7aeae82),
+ U64_C (0xb4c95e757db4b4ea), U64_C (0x549a19a8ce54544d),
+ U64_C (0x93ece53b7f939376), U64_C (0x220daa442f222288),
+ U64_C (0x6407e9c86364648d), U64_C (0xf1db12ff2af1f1e3),
+ U64_C (0x73bfa2e6cc7373d1), U64_C (0x12905a2482121248),
+ U64_C (0x403a5d807a40401d), U64_C (0x0840281048080820),
+ U64_C (0xc356e89b95c3c32b), U64_C (0xec337bc5dfecec97),
+ U64_C (0xdb9690ab4ddbdb4b), U64_C (0xa1611f5fc0a1a1be),
+ U64_C (0x8d1c8307918d8d0e), U64_C (0x3df5c97ac83d3df4),
+ U64_C (0x97ccf1335b979766), U64_C (0x0000000000000000),
+ U64_C (0xcf36d483f9cfcf1b), U64_C (0x2b4587566e2b2bac),
+ U64_C (0x7697b3ece17676c5), U64_C (0x8264b019e6828232),
+ U64_C (0xd6fea9b128d6d67f), U64_C (0x1bd87736c31b1b6c),
+ U64_C (0xb5c15b7774b5b5ee), U64_C (0xaf112943beafaf86),
+ U64_C (0x6a77dfd41d6a6ab5), U64_C (0x50ba0da0ea50505d),
+ U64_C (0x45124c8a57454509), U64_C (0xf3cb18fb38f3f3eb),
+ U64_C (0x309df060ad3030c0), U64_C (0xef2b74c3c4efef9b),
+ U64_C (0x3fe5c37eda3f3ffc), U64_C (0x55921caac7555549),
+ U64_C (0xa2791059dba2a2b2), U64_C (0xea0365c9e9eaea8f),
+ U64_C (0x650fecca6a656589), U64_C (0xbab9686903babad2),
+ U64_C (0x2f65935e4a2f2fbc), U64_C (0xc04ee79d8ec0c027),
+ U64_C (0xdebe81a160dede5f), U64_C (0x1ce06c38fc1c1c70),
+ U64_C (0xfdbb2ee746fdfdd3), U64_C (0x4d52649a1f4d4d29),
+ U64_C (0x92e4e03976929272), U64_C (0x758fbceafa7575c9),
+ U64_C (0x06301e0c36060618), U64_C (0x8a249809ae8a8a12),
+ U64_C (0xb2f940794bb2b2f2), U64_C (0xe66359d185e6e6bf),
+ U64_C (0x0e70361c7e0e0e38), U64_C (0x1ff8633ee71f1f7c),
+ U64_C (0x6237f7c455626295), U64_C (0xd4eea3b53ad4d477),
+ U64_C (0xa829324d81a8a89a), U64_C (0x96c4f43152969662),
+ U64_C (0xf99b3aef62f9f9c3), U64_C (0xc566f697a3c5c533),
+ U64_C (0x2535b14a10252594), U64_C (0x59f220b2ab595979),
+ U64_C (0x8454ae15d084842a), U64_C (0x72b7a7e4c57272d5),
+ U64_C (0x39d5dd72ec3939e4), U64_C (0x4c5a6198164c4c2d),
+ U64_C (0x5eca3bbc945e5e65), U64_C (0x78e785f09f7878fd),
+ U64_C (0x38ddd870e53838e0), U64_C (0x8c148605988c8c0a),
+ U64_C (0xd1c6b2bf17d1d163), U64_C (0xa5410b57e4a5a5ae),
+ U64_C (0xe2434dd9a1e2e2af), U64_C (0x612ff8c24e616199),
+ U64_C (0xb3f1457b42b3b3f6), U64_C (0x2115a54234212184),
+ U64_C (0x9c94d625089c9c4a), U64_C (0x1ef0663cee1e1e78),
+ U64_C (0x4322528661434311), U64_C (0xc776fc93b1c7c73b),
+ U64_C (0xfcb32be54ffcfcd7), U64_C (0x0420140824040410),
+ U64_C (0x51b208a2e3515159), U64_C (0x99bcc72f2599995e),
+ U64_C (0x6d4fc4da226d6da9), U64_C (0x0d68391a650d0d34),
+ U64_C (0xfa8335e979fafacf), U64_C (0xdfb684a369dfdf5b),
+ U64_C (0x7ed79bfca97e7ee5), U64_C (0x243db44819242490),
+ U64_C (0x3bc5d776fe3b3bec), U64_C (0xab313d4b9aabab96),
+ U64_C (0xce3ed181f0cece1f), U64_C (0x1188552299111144),
+ U64_C (0x8f0c8903838f8f06), U64_C (0x4e4a6b9c044e4e25),
+ U64_C (0xb7d1517366b7b7e6), U64_C (0xeb0b60cbe0ebeb8b),
+ U64_C (0x3cfdcc78c13c3cf0), U64_C (0x817cbf1ffd81813e),
+ U64_C (0x94d4fe354094946a), U64_C (0xf7eb0cf31cf7f7fb),
+ U64_C (0xb9a1676f18b9b9de), U64_C (0x13985f268b13134c),
+ U64_C (0x2c7d9c58512c2cb0), U64_C (0xd3d6b8bb05d3d36b),
+ U64_C (0xe76b5cd38ce7e7bb), U64_C (0x6e57cbdc396e6ea5),
+ U64_C (0xc46ef395aac4c437), U64_C (0x03180f061b03030c),
+ U64_C (0x568a13acdc565645), U64_C (0x441a49885e44440d),
+ U64_C (0x7fdf9efea07f7fe1), U64_C (0xa921374f88a9a99e),
+ U64_C (0x2a4d8254672a2aa8), U64_C (0xbbb16d6b0abbbbd6),
+ U64_C (0xc146e29f87c1c123), U64_C (0x53a202a6f1535351),
+ U64_C (0xdcae8ba572dcdc57), U64_C (0x0b582716530b0b2c),
+ U64_C (0x9d9cd327019d9d4e), U64_C (0x6c47c1d82b6c6cad),
+ U64_C (0x3195f562a43131c4), U64_C (0x7487b9e8f37474cd),
+ U64_C (0xf6e309f115f6f6ff), U64_C (0x460a438c4c464605),
+ U64_C (0xac092645a5acac8a), U64_C (0x893c970fb589891e),
+ U64_C (0x14a04428b4141450), U64_C (0xe15b42dfbae1e1a3),
+ U64_C (0x16b04e2ca6161658), U64_C (0x3acdd274f73a3ae8),
+ U64_C (0x696fd0d2066969b9), U64_C (0x09482d1241090924),
+ U64_C (0x70a7ade0d77070dd), U64_C (0xb6d954716fb6b6e2),
+ U64_C (0xd0ceb7bd1ed0d067), U64_C (0xed3b7ec7d6eded93),
+ U64_C (0xcc2edb85e2cccc17), U64_C (0x422a578468424215),
+ U64_C (0x98b4c22d2c98985a), U64_C (0xa4490e55eda4a4aa),
+ U64_C (0x285d8850752828a0), U64_C (0x5cda31b8865c5c6d),
+ U64_C (0xf8933fed6bf8f8c7), U64_C (0x8644a411c2868622),
+ }, {
+ U64_C (0x6018c07830d81818), U64_C (0x8c2305af46262323),
+ U64_C (0x3fc67ef991b8c6c6), U64_C (0x87e8136fcdfbe8e8),
+ U64_C (0x26874ca113cb8787), U64_C (0xdab8a9626d11b8b8),
+ U64_C (0x0401080502090101), U64_C (0x214f426e9e0d4f4f),
+ U64_C (0xd836adee6c9b3636), U64_C (0xa2a6590451ffa6a6),
+ U64_C (0x6fd2debdb90cd2d2), U64_C (0xf3f5fb06f70ef5f5),
+ U64_C (0xf979ef80f2967979), U64_C (0xa16f5fcede306f6f),
+ U64_C (0x7e91fcef3f6d9191), U64_C (0x5552aa07a4f85252),
+ U64_C (0x9d6027fdc0476060), U64_C (0xcabc89766535bcbc),
+ U64_C (0x569baccd2b379b9b), U64_C (0x028e048c018a8e8e),
+ U64_C (0xb6a371155bd2a3a3), U64_C (0x300c603c186c0c0c),
+ U64_C (0xf17bff8af6847b7b), U64_C (0xd435b5e16a803535),
+ U64_C (0x741de8693af51d1d), U64_C (0xa7e05347ddb3e0e0),
+ U64_C (0x7bd7f6acb321d7d7), U64_C (0x2fc25eed999cc2c2),
+ U64_C (0xb82e6d965c432e2e), U64_C (0x314b627a96294b4b),
+ U64_C (0xdffea321e15dfefe), U64_C (0x41578216aed55757),
+ U64_C (0x5415a8412abd1515), U64_C (0xc1779fb6eee87777),
+ U64_C (0xdc37a5eb6e923737), U64_C (0xb3e57b56d79ee5e5),
+ U64_C (0x469f8cd923139f9f), U64_C (0xe7f0d317fd23f0f0),
+ U64_C (0x354a6a7f94204a4a), U64_C (0x4fda9e95a944dada),
+ U64_C (0x7d58fa25b0a25858), U64_C (0x03c906ca8fcfc9c9),
+ U64_C (0xa429558d527c2929), U64_C (0x280a5022145a0a0a),
+ U64_C (0xfeb1e14f7f50b1b1), U64_C (0xbaa0691a5dc9a0a0),
+ U64_C (0xb16b7fdad6146b6b), U64_C (0x2e855cab17d98585),
+ U64_C (0xcebd8173673cbdbd), U64_C (0x695dd234ba8f5d5d),
+ U64_C (0x4010805020901010), U64_C (0xf7f4f303f507f4f4),
+ U64_C (0x0bcb16c08bddcbcb), U64_C (0xf83eedc67cd33e3e),
+ U64_C (0x140528110a2d0505), U64_C (0x81671fe6ce786767),
+ U64_C (0xb7e47353d597e4e4), U64_C (0x9c2725bb4e022727),
+ U64_C (0x1941325882734141), U64_C (0x168b2c9d0ba78b8b),
+ U64_C (0xa6a7510153f6a7a7), U64_C (0xe97dcf94fab27d7d),
+ U64_C (0x6e95dcfb37499595), U64_C (0x47d88e9fad56d8d8),
+ U64_C (0xcbfb8b30eb70fbfb), U64_C (0x9fee2371c1cdeeee),
+ U64_C (0xed7cc791f8bb7c7c), U64_C (0x856617e3cc716666),
+ U64_C (0x53dda68ea77bdddd), U64_C (0x5c17b84b2eaf1717),
+ U64_C (0x014702468e454747), U64_C (0x429e84dc211a9e9e),
+ U64_C (0x0fca1ec589d4caca), U64_C (0xb42d75995a582d2d),
+ U64_C (0xc6bf9179632ebfbf), U64_C (0x1c07381b0e3f0707),
+ U64_C (0x8ead012347acadad), U64_C (0x755aea2fb4b05a5a),
+ U64_C (0x36836cb51bef8383), U64_C (0xcc3385ff66b63333),
+ U64_C (0x91633ff2c65c6363), U64_C (0x0802100a04120202),
+ U64_C (0x92aa39384993aaaa), U64_C (0xd971afa8e2de7171),
+ U64_C (0x07c80ecf8dc6c8c8), U64_C (0x6419c87d32d11919),
+ U64_C (0x39497270923b4949), U64_C (0x43d9869aaf5fd9d9),
+ U64_C (0xeff2c31df931f2f2), U64_C (0xabe34b48dba8e3e3),
+ U64_C (0x715be22ab6b95b5b), U64_C (0x1a8834920dbc8888),
+ U64_C (0x529aa4c8293e9a9a), U64_C (0x98262dbe4c0b2626),
+ U64_C (0xc8328dfa64bf3232), U64_C (0xfab0e94a7d59b0b0),
+ U64_C (0x83e91b6acff2e9e9), U64_C (0x3c0f78331e770f0f),
+ U64_C (0x73d5e6a6b733d5d5), U64_C (0x3a8074ba1df48080),
+ U64_C (0xc2be997c6127bebe), U64_C (0x13cd26de87ebcdcd),
+ U64_C (0xd034bde468893434), U64_C (0x3d487a7590324848),
+ U64_C (0xdbffab24e354ffff), U64_C (0xf57af78ff48d7a7a),
+ U64_C (0x7a90f4ea3d649090), U64_C (0x615fc23ebe9d5f5f),
+ U64_C (0x80201da0403d2020), U64_C (0xbd6867d5d00f6868),
+ U64_C (0x681ad07234ca1a1a), U64_C (0x82ae192c41b7aeae),
+ U64_C (0xeab4c95e757db4b4), U64_C (0x4d549a19a8ce5454),
+ U64_C (0x7693ece53b7f9393), U64_C (0x88220daa442f2222),
+ U64_C (0x8d6407e9c8636464), U64_C (0xe3f1db12ff2af1f1),
+ U64_C (0xd173bfa2e6cc7373), U64_C (0x4812905a24821212),
+ U64_C (0x1d403a5d807a4040), U64_C (0x2008402810480808),
+ U64_C (0x2bc356e89b95c3c3), U64_C (0x97ec337bc5dfecec),
+ U64_C (0x4bdb9690ab4ddbdb), U64_C (0xbea1611f5fc0a1a1),
+ U64_C (0x0e8d1c8307918d8d), U64_C (0xf43df5c97ac83d3d),
+ U64_C (0x6697ccf1335b9797), U64_C (0x0000000000000000),
+ U64_C (0x1bcf36d483f9cfcf), U64_C (0xac2b4587566e2b2b),
+ U64_C (0xc57697b3ece17676), U64_C (0x328264b019e68282),
+ U64_C (0x7fd6fea9b128d6d6), U64_C (0x6c1bd87736c31b1b),
+ U64_C (0xeeb5c15b7774b5b5), U64_C (0x86af112943beafaf),
+ U64_C (0xb56a77dfd41d6a6a), U64_C (0x5d50ba0da0ea5050),
+ U64_C (0x0945124c8a574545), U64_C (0xebf3cb18fb38f3f3),
+ U64_C (0xc0309df060ad3030), U64_C (0x9bef2b74c3c4efef),
+ U64_C (0xfc3fe5c37eda3f3f), U64_C (0x4955921caac75555),
+ U64_C (0xb2a2791059dba2a2), U64_C (0x8fea0365c9e9eaea),
+ U64_C (0x89650fecca6a6565), U64_C (0xd2bab9686903baba),
+ U64_C (0xbc2f65935e4a2f2f), U64_C (0x27c04ee79d8ec0c0),
+ U64_C (0x5fdebe81a160dede), U64_C (0x701ce06c38fc1c1c),
+ U64_C (0xd3fdbb2ee746fdfd), U64_C (0x294d52649a1f4d4d),
+ U64_C (0x7292e4e039769292), U64_C (0xc9758fbceafa7575),
+ U64_C (0x1806301e0c360606), U64_C (0x128a249809ae8a8a),
+ U64_C (0xf2b2f940794bb2b2), U64_C (0xbfe66359d185e6e6),
+ U64_C (0x380e70361c7e0e0e), U64_C (0x7c1ff8633ee71f1f),
+ U64_C (0x956237f7c4556262), U64_C (0x77d4eea3b53ad4d4),
+ U64_C (0x9aa829324d81a8a8), U64_C (0x6296c4f431529696),
+ U64_C (0xc3f99b3aef62f9f9), U64_C (0x33c566f697a3c5c5),
+ U64_C (0x942535b14a102525), U64_C (0x7959f220b2ab5959),
+ U64_C (0x2a8454ae15d08484), U64_C (0xd572b7a7e4c57272),
+ U64_C (0xe439d5dd72ec3939), U64_C (0x2d4c5a6198164c4c),
+ U64_C (0x655eca3bbc945e5e), U64_C (0xfd78e785f09f7878),
+ U64_C (0xe038ddd870e53838), U64_C (0x0a8c148605988c8c),
+ U64_C (0x63d1c6b2bf17d1d1), U64_C (0xaea5410b57e4a5a5),
+ U64_C (0xafe2434dd9a1e2e2), U64_C (0x99612ff8c24e6161),
+ U64_C (0xf6b3f1457b42b3b3), U64_C (0x842115a542342121),
+ U64_C (0x4a9c94d625089c9c), U64_C (0x781ef0663cee1e1e),
+ U64_C (0x1143225286614343), U64_C (0x3bc776fc93b1c7c7),
+ U64_C (0xd7fcb32be54ffcfc), U64_C (0x1004201408240404),
+ U64_C (0x5951b208a2e35151), U64_C (0x5e99bcc72f259999),
+ U64_C (0xa96d4fc4da226d6d), U64_C (0x340d68391a650d0d),
+ U64_C (0xcffa8335e979fafa), U64_C (0x5bdfb684a369dfdf),
+ U64_C (0xe57ed79bfca97e7e), U64_C (0x90243db448192424),
+ U64_C (0xec3bc5d776fe3b3b), U64_C (0x96ab313d4b9aabab),
+ U64_C (0x1fce3ed181f0cece), U64_C (0x4411885522991111),
+ U64_C (0x068f0c8903838f8f), U64_C (0x254e4a6b9c044e4e),
+ U64_C (0xe6b7d1517366b7b7), U64_C (0x8beb0b60cbe0ebeb),
+ U64_C (0xf03cfdcc78c13c3c), U64_C (0x3e817cbf1ffd8181),
+ U64_C (0x6a94d4fe35409494), U64_C (0xfbf7eb0cf31cf7f7),
+ U64_C (0xdeb9a1676f18b9b9), U64_C (0x4c13985f268b1313),
+ U64_C (0xb02c7d9c58512c2c), U64_C (0x6bd3d6b8bb05d3d3),
+ U64_C (0xbbe76b5cd38ce7e7), U64_C (0xa56e57cbdc396e6e),
+ U64_C (0x37c46ef395aac4c4), U64_C (0x0c03180f061b0303),
+ U64_C (0x45568a13acdc5656), U64_C (0x0d441a49885e4444),
+ U64_C (0xe17fdf9efea07f7f), U64_C (0x9ea921374f88a9a9),
+ U64_C (0xa82a4d8254672a2a), U64_C (0xd6bbb16d6b0abbbb),
+ U64_C (0x23c146e29f87c1c1), U64_C (0x5153a202a6f15353),
+ U64_C (0x57dcae8ba572dcdc), U64_C (0x2c0b582716530b0b),
+ U64_C (0x4e9d9cd327019d9d), U64_C (0xad6c47c1d82b6c6c),
+ U64_C (0xc43195f562a43131), U64_C (0xcd7487b9e8f37474),
+ U64_C (0xfff6e309f115f6f6), U64_C (0x05460a438c4c4646),
+ U64_C (0x8aac092645a5acac), U64_C (0x1e893c970fb58989),
+ U64_C (0x5014a04428b41414), U64_C (0xa3e15b42dfbae1e1),
+ U64_C (0x5816b04e2ca61616), U64_C (0xe83acdd274f73a3a),
+ U64_C (0xb9696fd0d2066969), U64_C (0x2409482d12410909),
+ U64_C (0xdd70a7ade0d77070), U64_C (0xe2b6d954716fb6b6),
+ U64_C (0x67d0ceb7bd1ed0d0), U64_C (0x93ed3b7ec7d6eded),
+ U64_C (0x17cc2edb85e2cccc), U64_C (0x15422a5784684242),
+ U64_C (0x5a98b4c22d2c9898), U64_C (0xaaa4490e55eda4a4),
+ U64_C (0xa0285d8850752828), U64_C (0x6d5cda31b8865c5c),
+ U64_C (0xc7f8933fed6bf8f8), U64_C (0x228644a411c28686),
+ }, {
+ U64_C (0x186018c07830d818), U64_C (0x238c2305af462623),
+ U64_C (0xc63fc67ef991b8c6), U64_C (0xe887e8136fcdfbe8),
+ U64_C (0x8726874ca113cb87), U64_C (0xb8dab8a9626d11b8),
+ U64_C (0x0104010805020901), U64_C (0x4f214f426e9e0d4f),
+ U64_C (0x36d836adee6c9b36), U64_C (0xa6a2a6590451ffa6),
+ U64_C (0xd26fd2debdb90cd2), U64_C (0xf5f3f5fb06f70ef5),
+ U64_C (0x79f979ef80f29679), U64_C (0x6fa16f5fcede306f),
+ U64_C (0x917e91fcef3f6d91), U64_C (0x525552aa07a4f852),
+ U64_C (0x609d6027fdc04760), U64_C (0xbccabc89766535bc),
+ U64_C (0x9b569baccd2b379b), U64_C (0x8e028e048c018a8e),
+ U64_C (0xa3b6a371155bd2a3), U64_C (0x0c300c603c186c0c),
+ U64_C (0x7bf17bff8af6847b), U64_C (0x35d435b5e16a8035),
+ U64_C (0x1d741de8693af51d), U64_C (0xe0a7e05347ddb3e0),
+ U64_C (0xd77bd7f6acb321d7), U64_C (0xc22fc25eed999cc2),
+ U64_C (0x2eb82e6d965c432e), U64_C (0x4b314b627a96294b),
+ U64_C (0xfedffea321e15dfe), U64_C (0x5741578216aed557),
+ U64_C (0x155415a8412abd15), U64_C (0x77c1779fb6eee877),
+ U64_C (0x37dc37a5eb6e9237), U64_C (0xe5b3e57b56d79ee5),
+ U64_C (0x9f469f8cd923139f), U64_C (0xf0e7f0d317fd23f0),
+ U64_C (0x4a354a6a7f94204a), U64_C (0xda4fda9e95a944da),
+ U64_C (0x587d58fa25b0a258), U64_C (0xc903c906ca8fcfc9),
+ U64_C (0x29a429558d527c29), U64_C (0x0a280a5022145a0a),
+ U64_C (0xb1feb1e14f7f50b1), U64_C (0xa0baa0691a5dc9a0),
+ U64_C (0x6bb16b7fdad6146b), U64_C (0x852e855cab17d985),
+ U64_C (0xbdcebd8173673cbd), U64_C (0x5d695dd234ba8f5d),
+ U64_C (0x1040108050209010), U64_C (0xf4f7f4f303f507f4),
+ U64_C (0xcb0bcb16c08bddcb), U64_C (0x3ef83eedc67cd33e),
+ U64_C (0x05140528110a2d05), U64_C (0x6781671fe6ce7867),
+ U64_C (0xe4b7e47353d597e4), U64_C (0x279c2725bb4e0227),
+ U64_C (0x4119413258827341), U64_C (0x8b168b2c9d0ba78b),
+ U64_C (0xa7a6a7510153f6a7), U64_C (0x7de97dcf94fab27d),
+ U64_C (0x956e95dcfb374995), U64_C (0xd847d88e9fad56d8),
+ U64_C (0xfbcbfb8b30eb70fb), U64_C (0xee9fee2371c1cdee),
+ U64_C (0x7ced7cc791f8bb7c), U64_C (0x66856617e3cc7166),
+ U64_C (0xdd53dda68ea77bdd), U64_C (0x175c17b84b2eaf17),
+ U64_C (0x47014702468e4547), U64_C (0x9e429e84dc211a9e),
+ U64_C (0xca0fca1ec589d4ca), U64_C (0x2db42d75995a582d),
+ U64_C (0xbfc6bf9179632ebf), U64_C (0x071c07381b0e3f07),
+ U64_C (0xad8ead012347acad), U64_C (0x5a755aea2fb4b05a),
+ U64_C (0x8336836cb51bef83), U64_C (0x33cc3385ff66b633),
+ U64_C (0x6391633ff2c65c63), U64_C (0x020802100a041202),
+ U64_C (0xaa92aa39384993aa), U64_C (0x71d971afa8e2de71),
+ U64_C (0xc807c80ecf8dc6c8), U64_C (0x196419c87d32d119),
+ U64_C (0x4939497270923b49), U64_C (0xd943d9869aaf5fd9),
+ U64_C (0xf2eff2c31df931f2), U64_C (0xe3abe34b48dba8e3),
+ U64_C (0x5b715be22ab6b95b), U64_C (0x881a8834920dbc88),
+ U64_C (0x9a529aa4c8293e9a), U64_C (0x2698262dbe4c0b26),
+ U64_C (0x32c8328dfa64bf32), U64_C (0xb0fab0e94a7d59b0),
+ U64_C (0xe983e91b6acff2e9), U64_C (0x0f3c0f78331e770f),
+ U64_C (0xd573d5e6a6b733d5), U64_C (0x803a8074ba1df480),
+ U64_C (0xbec2be997c6127be), U64_C (0xcd13cd26de87ebcd),
+ U64_C (0x34d034bde4688934), U64_C (0x483d487a75903248),
+ U64_C (0xffdbffab24e354ff), U64_C (0x7af57af78ff48d7a),
+ U64_C (0x907a90f4ea3d6490), U64_C (0x5f615fc23ebe9d5f),
+ U64_C (0x2080201da0403d20), U64_C (0x68bd6867d5d00f68),
+ U64_C (0x1a681ad07234ca1a), U64_C (0xae82ae192c41b7ae),
+ U64_C (0xb4eab4c95e757db4), U64_C (0x544d549a19a8ce54),
+ U64_C (0x937693ece53b7f93), U64_C (0x2288220daa442f22),
+ U64_C (0x648d6407e9c86364), U64_C (0xf1e3f1db12ff2af1),
+ U64_C (0x73d173bfa2e6cc73), U64_C (0x124812905a248212),
+ U64_C (0x401d403a5d807a40), U64_C (0x0820084028104808),
+ U64_C (0xc32bc356e89b95c3), U64_C (0xec97ec337bc5dfec),
+ U64_C (0xdb4bdb9690ab4ddb), U64_C (0xa1bea1611f5fc0a1),
+ U64_C (0x8d0e8d1c8307918d), U64_C (0x3df43df5c97ac83d),
+ U64_C (0x976697ccf1335b97), U64_C (0x0000000000000000),
+ U64_C (0xcf1bcf36d483f9cf), U64_C (0x2bac2b4587566e2b),
+ U64_C (0x76c57697b3ece176), U64_C (0x82328264b019e682),
+ U64_C (0xd67fd6fea9b128d6), U64_C (0x1b6c1bd87736c31b),
+ U64_C (0xb5eeb5c15b7774b5), U64_C (0xaf86af112943beaf),
+ U64_C (0x6ab56a77dfd41d6a), U64_C (0x505d50ba0da0ea50),
+ U64_C (0x450945124c8a5745), U64_C (0xf3ebf3cb18fb38f3),
+ U64_C (0x30c0309df060ad30), U64_C (0xef9bef2b74c3c4ef),
+ U64_C (0x3ffc3fe5c37eda3f), U64_C (0x554955921caac755),
+ U64_C (0xa2b2a2791059dba2), U64_C (0xea8fea0365c9e9ea),
+ U64_C (0x6589650fecca6a65), U64_C (0xbad2bab9686903ba),
+ U64_C (0x2fbc2f65935e4a2f), U64_C (0xc027c04ee79d8ec0),
+ U64_C (0xde5fdebe81a160de), U64_C (0x1c701ce06c38fc1c),
+ U64_C (0xfdd3fdbb2ee746fd), U64_C (0x4d294d52649a1f4d),
+ U64_C (0x927292e4e0397692), U64_C (0x75c9758fbceafa75),
+ U64_C (0x061806301e0c3606), U64_C (0x8a128a249809ae8a),
+ U64_C (0xb2f2b2f940794bb2), U64_C (0xe6bfe66359d185e6),
+ U64_C (0x0e380e70361c7e0e), U64_C (0x1f7c1ff8633ee71f),
+ U64_C (0x62956237f7c45562), U64_C (0xd477d4eea3b53ad4),
+ U64_C (0xa89aa829324d81a8), U64_C (0x966296c4f4315296),
+ U64_C (0xf9c3f99b3aef62f9), U64_C (0xc533c566f697a3c5),
+ U64_C (0x25942535b14a1025), U64_C (0x597959f220b2ab59),
+ U64_C (0x842a8454ae15d084), U64_C (0x72d572b7a7e4c572),
+ U64_C (0x39e439d5dd72ec39), U64_C (0x4c2d4c5a6198164c),
+ U64_C (0x5e655eca3bbc945e), U64_C (0x78fd78e785f09f78),
+ U64_C (0x38e038ddd870e538), U64_C (0x8c0a8c148605988c),
+ U64_C (0xd163d1c6b2bf17d1), U64_C (0xa5aea5410b57e4a5),
+ U64_C (0xe2afe2434dd9a1e2), U64_C (0x6199612ff8c24e61),
+ U64_C (0xb3f6b3f1457b42b3), U64_C (0x21842115a5423421),
+ U64_C (0x9c4a9c94d625089c), U64_C (0x1e781ef0663cee1e),
+ U64_C (0x4311432252866143), U64_C (0xc73bc776fc93b1c7),
+ U64_C (0xfcd7fcb32be54ffc), U64_C (0x0410042014082404),
+ U64_C (0x515951b208a2e351), U64_C (0x995e99bcc72f2599),
+ U64_C (0x6da96d4fc4da226d), U64_C (0x0d340d68391a650d),
+ U64_C (0xfacffa8335e979fa), U64_C (0xdf5bdfb684a369df),
+ U64_C (0x7ee57ed79bfca97e), U64_C (0x2490243db4481924),
+ U64_C (0x3bec3bc5d776fe3b), U64_C (0xab96ab313d4b9aab),
+ U64_C (0xce1fce3ed181f0ce), U64_C (0x1144118855229911),
+ U64_C (0x8f068f0c8903838f), U64_C (0x4e254e4a6b9c044e),
+ U64_C (0xb7e6b7d1517366b7), U64_C (0xeb8beb0b60cbe0eb),
+ U64_C (0x3cf03cfdcc78c13c), U64_C (0x813e817cbf1ffd81),
+ U64_C (0x946a94d4fe354094), U64_C (0xf7fbf7eb0cf31cf7),
+ U64_C (0xb9deb9a1676f18b9), U64_C (0x134c13985f268b13),
+ U64_C (0x2cb02c7d9c58512c), U64_C (0xd36bd3d6b8bb05d3),
+ U64_C (0xe7bbe76b5cd38ce7), U64_C (0x6ea56e57cbdc396e),
+ U64_C (0xc437c46ef395aac4), U64_C (0x030c03180f061b03),
+ U64_C (0x5645568a13acdc56), U64_C (0x440d441a49885e44),
+ U64_C (0x7fe17fdf9efea07f), U64_C (0xa99ea921374f88a9),
+ U64_C (0x2aa82a4d8254672a), U64_C (0xbbd6bbb16d6b0abb),
+ U64_C (0xc123c146e29f87c1), U64_C (0x535153a202a6f153),
+ U64_C (0xdc57dcae8ba572dc), U64_C (0x0b2c0b582716530b),
+ U64_C (0x9d4e9d9cd327019d), U64_C (0x6cad6c47c1d82b6c),
+ U64_C (0x31c43195f562a431), U64_C (0x74cd7487b9e8f374),
+ U64_C (0xf6fff6e309f115f6), U64_C (0x4605460a438c4c46),
+ U64_C (0xac8aac092645a5ac), U64_C (0x891e893c970fb589),
+ U64_C (0x145014a04428b414), U64_C (0xe1a3e15b42dfbae1),
+ U64_C (0x165816b04e2ca616), U64_C (0x3ae83acdd274f73a),
+ U64_C (0x69b9696fd0d20669), U64_C (0x092409482d124109),
+ U64_C (0x70dd70a7ade0d770), U64_C (0xb6e2b6d954716fb6),
+ U64_C (0xd067d0ceb7bd1ed0), U64_C (0xed93ed3b7ec7d6ed),
+ U64_C (0xcc17cc2edb85e2cc), U64_C (0x4215422a57846842),
+ U64_C (0x985a98b4c22d2c98), U64_C (0xa4aaa4490e55eda4),
+ U64_C (0x28a0285d88507528), U64_C (0x5c6d5cda31b8865c),
+ U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286),
+ } }
+};
+#define C tab.C
+#define C0 C[0]
+#define C1 C[1]
+#define C2 C[2]
+#define C3 C[3]
+#define C4 C[4]
+#define C5 C[5]
+#define C6 C[6]
+#define C7 C[7]
+#define rc tab.RC
+
+
+
+static unsigned int
+whirlpool_transform (void *ctx, const unsigned char *data, size_t nblks);
+
+
+
+static void
+whirlpool_init (void *ctx, unsigned int flags)
+{
+ whirlpool_context_t *context = ctx;
+
+ memset (context, 0, sizeof (*context));
+
+ context->bctx.blocksize_shift = _gcry_ctz(BLOCK_SIZE);
+ context->bctx.bwrite = whirlpool_transform;
+ if ((flags & GCRY_MD_FLAG_BUGEMU1))
+ {
+ memset (&context->bugemu, 0, sizeof context->bugemu);
+ context->use_bugemu = 1;
+ }
+ else
+ context->use_bugemu = 0;
+}
+
+
+#ifdef USE_AMD64_ASM
+
+#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
+
+extern unsigned int
+_gcry_whirlpool_transform_amd64(u64 *state, const unsigned char *data,
+ size_t nblks, const struct whirlpool_tables_s *tables) ASM_FUNC_ABI;
+
+static unsigned int
+whirlpool_transform (void *ctx, const unsigned char *data, size_t nblks)
+{
+ whirlpool_context_t *context = ctx;
+
+ return _gcry_whirlpool_transform_amd64(
+ context->hash_state, data, nblks, &tab) + ASM_EXTRA_STACK;
+}
+
+#else /* USE_AMD64_ASM */
+
+/*
+ * Transform block.
+ */
+static unsigned int
+whirlpool_transform_blk (void *ctx, const unsigned char *data)
+{
+ whirlpool_context_t *context = ctx;
+ whirlpool_block_t data_block;
+ whirlpool_block_t key;
+ whirlpool_block_t state;
+ whirlpool_block_t block;
+ unsigned int r;
+ unsigned int i;
+
+ buffer_to_block (data, data_block, i);
+ block_copy (key, context->hash_state, i);
+ block_copy (state, context->hash_state, i);
+ block_xor (state, data_block, i);
+
+ for (r = 0; r < R; r++)
+ {
+ /* Compute round key K^r. */
+
+ block[0] = (C0[(key[0] >> 56) & 0xFF] ^ C1[(key[7] >> 48) & 0xFF] ^
+ C2[(key[6] >> 40) & 0xFF] ^ C3[(key[5] >> 32) & 0xFF] ^
+ C4[(key[4] >> 24) & 0xFF] ^ C5[(key[3] >> 16) & 0xFF] ^
+ C6[(key[2] >> 8) & 0xFF] ^ C7[(key[1] >> 0) & 0xFF] ^ rc[r]);
+ block[1] = (C0[(key[1] >> 56) & 0xFF] ^ C1[(key[0] >> 48) & 0xFF] ^
+ C2[(key[7] >> 40) & 0xFF] ^ C3[(key[6] >> 32) & 0xFF] ^
+ C4[(key[5] >> 24) & 0xFF] ^ C5[(key[4] >> 16) & 0xFF] ^
+ C6[(key[3] >> 8) & 0xFF] ^ C7[(key[2] >> 0) & 0xFF]);
+ block[2] = (C0[(key[2] >> 56) & 0xFF] ^ C1[(key[1] >> 48) & 0xFF] ^
+ C2[(key[0] >> 40) & 0xFF] ^ C3[(key[7] >> 32) & 0xFF] ^
+ C4[(key[6] >> 24) & 0xFF] ^ C5[(key[5] >> 16) & 0xFF] ^
+ C6[(key[4] >> 8) & 0xFF] ^ C7[(key[3] >> 0) & 0xFF]);
+ block[3] = (C0[(key[3] >> 56) & 0xFF] ^ C1[(key[2] >> 48) & 0xFF] ^
+ C2[(key[1] >> 40) & 0xFF] ^ C3[(key[0] >> 32) & 0xFF] ^
+ C4[(key[7] >> 24) & 0xFF] ^ C5[(key[6] >> 16) & 0xFF] ^
+ C6[(key[5] >> 8) & 0xFF] ^ C7[(key[4] >> 0) & 0xFF]);
+ block[4] = (C0[(key[4] >> 56) & 0xFF] ^ C1[(key[3] >> 48) & 0xFF] ^
+ C2[(key[2] >> 40) & 0xFF] ^ C3[(key[1] >> 32) & 0xFF] ^
+ C4[(key[0] >> 24) & 0xFF] ^ C5[(key[7] >> 16) & 0xFF] ^
+ C6[(key[6] >> 8) & 0xFF] ^ C7[(key[5] >> 0) & 0xFF]);
+ block[5] = (C0[(key[5] >> 56) & 0xFF] ^ C1[(key[4] >> 48) & 0xFF] ^
+ C2[(key[3] >> 40) & 0xFF] ^ C3[(key[2] >> 32) & 0xFF] ^
+ C4[(key[1] >> 24) & 0xFF] ^ C5[(key[0] >> 16) & 0xFF] ^
+ C6[(key[7] >> 8) & 0xFF] ^ C7[(key[6] >> 0) & 0xFF]);
+ block[6] = (C0[(key[6] >> 56) & 0xFF] ^ C1[(key[5] >> 48) & 0xFF] ^
+ C2[(key[4] >> 40) & 0xFF] ^ C3[(key[3] >> 32) & 0xFF] ^
+ C4[(key[2] >> 24) & 0xFF] ^ C5[(key[1] >> 16) & 0xFF] ^
+ C6[(key[0] >> 8) & 0xFF] ^ C7[(key[7] >> 0) & 0xFF]);
+ block[7] = (C0[(key[7] >> 56) & 0xFF] ^ C1[(key[6] >> 48) & 0xFF] ^
+ C2[(key[5] >> 40) & 0xFF] ^ C3[(key[4] >> 32) & 0xFF] ^
+ C4[(key[3] >> 24) & 0xFF] ^ C5[(key[2] >> 16) & 0xFF] ^
+ C6[(key[1] >> 8) & 0xFF] ^ C7[(key[0] >> 0) & 0xFF]);
+ block_copy (key, block, i);
+
+ /* Apply r-th round transformation. */
+
+ block[0] = (C0[(state[0] >> 56) & 0xFF] ^ C1[(state[7] >> 48) & 0xFF] ^
+ C2[(state[6] >> 40) & 0xFF] ^ C3[(state[5] >> 32) & 0xFF] ^
+ C4[(state[4] >> 24) & 0xFF] ^ C5[(state[3] >> 16) & 0xFF] ^
+ C6[(state[2] >> 8) & 0xFF] ^ C7[(state[1] >> 0) & 0xFF] ^ key[0]);
+ block[1] = (C0[(state[1] >> 56) & 0xFF] ^ C1[(state[0] >> 48) & 0xFF] ^
+ C2[(state[7] >> 40) & 0xFF] ^ C3[(state[6] >> 32) & 0xFF] ^
+ C4[(state[5] >> 24) & 0xFF] ^ C5[(state[4] >> 16) & 0xFF] ^
+ C6[(state[3] >> 8) & 0xFF] ^ C7[(state[2] >> 0) & 0xFF] ^ key[1]);
+ block[2] = (C0[(state[2] >> 56) & 0xFF] ^ C1[(state[1] >> 48) & 0xFF] ^
+ C2[(state[0] >> 40) & 0xFF] ^ C3[(state[7] >> 32) & 0xFF] ^
+ C4[(state[6] >> 24) & 0xFF] ^ C5[(state[5] >> 16) & 0xFF] ^
+ C6[(state[4] >> 8) & 0xFF] ^ C7[(state[3] >> 0) & 0xFF] ^ key[2]);
+ block[3] = (C0[(state[3] >> 56) & 0xFF] ^ C1[(state[2] >> 48) & 0xFF] ^
+ C2[(state[1] >> 40) & 0xFF] ^ C3[(state[0] >> 32) & 0xFF] ^
+ C4[(state[7] >> 24) & 0xFF] ^ C5[(state[6] >> 16) & 0xFF] ^
+ C6[(state[5] >> 8) & 0xFF] ^ C7[(state[4] >> 0) & 0xFF] ^ key[3]);
+ block[4] = (C0[(state[4] >> 56) & 0xFF] ^ C1[(state[3] >> 48) & 0xFF] ^
+ C2[(state[2] >> 40) & 0xFF] ^ C3[(state[1] >> 32) & 0xFF] ^
+ C4[(state[0] >> 24) & 0xFF] ^ C5[(state[7] >> 16) & 0xFF] ^
+ C6[(state[6] >> 8) & 0xFF] ^ C7[(state[5] >> 0) & 0xFF] ^ key[4]);
+ block[5] = (C0[(state[5] >> 56) & 0xFF] ^ C1[(state[4] >> 48) & 0xFF] ^
+ C2[(state[3] >> 40) & 0xFF] ^ C3[(state[2] >> 32) & 0xFF] ^
+ C4[(state[1] >> 24) & 0xFF] ^ C5[(state[0] >> 16) & 0xFF] ^
+ C6[(state[7] >> 8) & 0xFF] ^ C7[(state[6] >> 0) & 0xFF] ^ key[5]);
+ block[6] = (C0[(state[6] >> 56) & 0xFF] ^ C1[(state[5] >> 48) & 0xFF] ^
+ C2[(state[4] >> 40) & 0xFF] ^ C3[(state[3] >> 32) & 0xFF] ^
+ C4[(state[2] >> 24) & 0xFF] ^ C5[(state[1] >> 16) & 0xFF] ^
+ C6[(state[0] >> 8) & 0xFF] ^ C7[(state[7] >> 0) & 0xFF] ^ key[6]);
+ block[7] = (C0[(state[7] >> 56) & 0xFF] ^ C1[(state[6] >> 48) & 0xFF] ^
+ C2[(state[5] >> 40) & 0xFF] ^ C3[(state[4] >> 32) & 0xFF] ^
+ C4[(state[3] >> 24) & 0xFF] ^ C5[(state[2] >> 16) & 0xFF] ^
+ C6[(state[1] >> 8) & 0xFF] ^ C7[(state[0] >> 0) & 0xFF] ^ key[7]);
+ block_copy (state, block, i);
+ }
+
+ /* Compression. */
+
+ block_xor (context->hash_state, data_block, i);
+ block_xor (context->hash_state, state, i);
+
+ return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) +
+ 4 * sizeof(void*);
+}
+
+static unsigned int
+whirlpool_transform ( void *c, const unsigned char *data, size_t nblks )
+{
+ unsigned int burn;
+
+ do
+ {
+ burn = whirlpool_transform_blk (c, data);
+ data += BLOCK_SIZE;
+ }
+ while (--nblks);
+
+ return burn;
+}
+
+#endif /* !USE_AMD64_ASM */
+
+
+/* Bug compatibility Whirlpool version. */
+static void
+whirlpool_add_bugemu (whirlpool_context_t *context,
+ const void *buffer_arg, size_t buffer_n)
+{
+ const unsigned char *buffer = buffer_arg;
+ u64 buffer_size;
+ unsigned int carry;
+ unsigned int i;
+
+ buffer_size = buffer_n;
+
+ if (context->bugemu.count == BLOCK_SIZE)
+ {
+ /* Flush the buffer. */
+ whirlpool_transform (context, context->bctx.buf, 1);
+ context->bugemu.count = 0;
+ }
+ if (! buffer)
+ return; /* Nothing to add. */
+
+ if (context->bugemu.count)
+ {
+ while (buffer_n && (context->bugemu.count < BLOCK_SIZE))
+ {
+ context->bctx.buf[context->bugemu.count++] = *buffer++;
+ buffer_n--;
+ }
+ whirlpool_add_bugemu (context, NULL, 0);
+ if (!buffer_n)
+ return; /* Done. This is the bug we emulate. */
+ }
+
+ while (buffer_n >= BLOCK_SIZE)
+ {
+ whirlpool_transform (context, buffer, 1);
+ context->bugemu.count = 0;
+ buffer_n -= BLOCK_SIZE;
+ buffer += BLOCK_SIZE;
+ }
+ while (buffer_n && (context->bugemu.count < BLOCK_SIZE))
+ {
+ context->bctx.buf[context->bugemu.count++] = *buffer++;
+ buffer_n--;
+ }
+
+ /* Update bit counter. */
+ carry = 0;
+ buffer_size <<= 3;
+ for (i = 1; i <= 32; i++)
+ {
+ if (! (buffer_size || carry))
+ break;
+
+ carry += context->bugemu.length[32 - i] + (buffer_size & 0xFF);
+ context->bugemu.length[32 - i] = carry;
+ buffer_size >>= 8;
+ carry >>= 8;
+ }
+ gcry_assert (! (buffer_size || carry));
+}
+
+
+/* Bug compatibility Whirlpool version. */
+static void
+whirlpool_final_bugemu (void *ctx)
+{
+ whirlpool_context_t *context = ctx;
+ unsigned int i;
+
+ /* Flush. */
+ whirlpool_add_bugemu (context, NULL, 0);
+
+ /* Pad. */
+ context->bctx.buf[context->bugemu.count++] = 0x80;
+
+ if (context->bugemu.count > 32)
+ {
+ /* An extra block is necessary. */
+ while (context->bugemu.count < 64)
+ context->bctx.buf[context->bugemu.count++] = 0;
+ whirlpool_add_bugemu (context, NULL, 0);
+ }
+ while (context->bugemu.count < 32)
+ context->bctx.buf[context->bugemu.count++] = 0;
+
+ /* Add length of message. */
+ memcpy (context->bctx.buf + context->bugemu.count,
+ context->bugemu.length, 32);
+ context->bugemu.count += 32;
+ whirlpool_add_bugemu (context, NULL, 0);
+
+ block_to_buffer (context->bctx.buf, context->hash_state, i);
+}
+
+
+static void
+whirlpool_write (void *ctx, const void *buffer, size_t buffer_n)
+{
+ whirlpool_context_t *context = ctx;
+
+ if (context->use_bugemu)
+ {
+ whirlpool_add_bugemu (context, buffer, buffer_n);
+ }
+ else
+ {
+ u64 old_nblocks = context->bctx.nblocks;
+
+ _gcry_md_block_write (context, buffer, buffer_n);
+
+ gcry_assert (old_nblocks <= context->bctx.nblocks);
+ }
+}
+
+static void
+whirlpool_final (void *ctx)
+{
+ whirlpool_context_t *context = ctx;
+ unsigned int i;
+ u64 t, th, lsb, msb;
+ unsigned char *length;
+
+ if (context->use_bugemu)
+ {
+ whirlpool_final_bugemu (ctx);
+ return;
+ }
+
+ t = context->bctx.nblocks;
+ /* if (sizeof t == sizeof context->bctx.nblocks) */
+ th = context->bctx.nblocks_high;
+ /* else */
+ /* th = context->bctx.nblocks >> 64; In case we ever use u128 */
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = (th << 6) | (t >> 58);
+ /* add the count */
+ t = lsb;
+ if ((lsb += context->bctx.count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 61;
+
+ /* Flush. */
+ whirlpool_write (context, NULL, 0);
+
+ /* Pad. */
+ context->bctx.buf[context->bctx.count++] = 0x80;
+
+ if (context->bctx.count > 32)
+ {
+ /* An extra block is necessary. */
+ if (context->bctx.count < 64)
+ memset (&context->bctx.buf[context->bctx.count], 0,
+ 64 - context->bctx.count);
+ context->bctx.count = 64;
+ whirlpool_write (context, NULL, 0);
+ }
+ if (context->bctx.count < 32)
+ memset (&context->bctx.buf[context->bctx.count], 0,
+ 32 - context->bctx.count);
+ context->bctx.count = 32;
+
+ /* Add length of message. */
+ length = context->bctx.buf + context->bctx.count;
+ buf_put_be64(&length[0 * 8], 0);
+ buf_put_be64(&length[1 * 8], 0);
+ buf_put_be64(&length[2 * 8], msb);
+ buf_put_be64(&length[3 * 8], lsb);
+ context->bctx.count += 32;
+ whirlpool_write (context, NULL, 0);
+
+ block_to_buffer (context->bctx.buf, context->hash_state, i);
+}
+
+static byte *
+whirlpool_read (void *ctx)
+{
+ whirlpool_context_t *context = ctx;
+
+ return context->bctx.buf;
+}
+
+gcry_md_spec_t _gcry_digest_spec_whirlpool =
+ {
+ GCRY_MD_WHIRLPOOL, {0, 0},
+ "WHIRLPOOL", NULL, 0, NULL, 64,
+ whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read, NULL,
+ NULL, NULL,
+ sizeof (whirlpool_context_t)
+ };
diff --git a/comm/third_party/libgcrypt/compat/Makefile.am b/comm/third_party/libgcrypt/compat/Makefile.am
new file mode 100644
index 0000000000..f0ddf34dfd
--- /dev/null
+++ b/comm/third_party/libgcrypt/compat/Makefile.am
@@ -0,0 +1,48 @@
+# Makefile for compat directory
+# Copyright (C) 2010 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 <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+# We use this libcompat to work around problems with LIBOBJ stuff.
+# For example, we need some of the compat files also in tests/ but the
+# suggested way to do this (using the automake option subdir-objects)
+# leads to problems with "make distclean": The distclean target in
+# tests is run before the one src and it removes the deps files of the
+# libobj files which are in src. Now when it comes to run make in src
+# the icnluded files are gone - bummer. Instead of try to fix this
+# issue it seems better not to use subdir-objects but build them all
+# into a compat library and always link against that library. This
+# also avoids the problem that a dependency on LTLIBOBJ is not setup
+# if -- disable-static was used.
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src $(GPG_ERROR_CFLAGS)
+
+noinst_LTLIBRARIES = libcompat.la
+
+# We only need one file so that the library is guaranteed to have at
+# least one member.
+libcompat_la_SOURCES = compat.c libcompat.h
+libcompat_la_DEPENDENCIES = @LTLIBOBJS@
+libcompat_la_LIBADD = @LTLIBOBJS@
+
+# AC_LIBOBJ files are:
+# getpid.c
+# clock.c
+#
diff --git a/comm/third_party/libgcrypt/compat/Makefile.in b/comm/third_party/libgcrypt/compat/Makefile.in
new file mode 100644
index 0000000000..a413595098
--- /dev/null
+++ b/comm/third_party/libgcrypt/compat/Makefile.in
@@ -0,0 +1,697 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for compat directory
+# Copyright (C) 2010 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 <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+# We use this libcompat to work around problems with LIBOBJ stuff.
+# For example, we need some of the compat files also in tests/ but the
+# suggested way to do this (using the automake option subdir-objects)
+# leads to problems with "make distclean": The distclean target in
+# tests is run before the one src and it removes the deps files of the
+# libobj files which are in src. Now when it comes to run make in src
+# the icnluded files are gone - bummer. Instead of try to fix this
+# issue it seems better not to use subdir-objects but build them all
+# into a compat library and always link against that library. This
+# also avoids the problem that a dependency on LTLIBOBJ is not setup
+# if -- disable-static was used.
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = compat
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am_libcompat_la_OBJECTS = compat.lo
+libcompat_la_OBJECTS = $(am_libcompat_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = $(DEPDIR)/clock.Plo $(DEPDIR)/getpid.Plo \
+ ./$(DEPDIR)/compat.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libcompat_la_SOURCES)
+DIST_SOURCES = $(libcompat_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp clock.c getpid.c
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src $(GPG_ERROR_CFLAGS)
+noinst_LTLIBRARIES = libcompat.la
+
+# We only need one file so that the library is guaranteed to have at
+# least one member.
+libcompat_la_SOURCES = compat.c libcompat.h
+libcompat_la_DEPENDENCIES = @LTLIBOBJS@
+libcompat_la_LIBADD = @LTLIBOBJS@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu compat/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu compat/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libcompat.la: $(libcompat_la_OBJECTS) $(libcompat_la_DEPENDENCIES) $(EXTRA_libcompat_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libcompat_la_OBJECTS) $(libcompat_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/clock.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getpid.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(DEPDIR)/clock.Plo
+ -rm -f $(DEPDIR)/getpid.Plo
+ -rm -f ./$(DEPDIR)/compat.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(DEPDIR)/clock.Plo
+ -rm -f $(DEPDIR)/getpid.Plo
+ -rm -f ./$(DEPDIR)/compat.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# AC_LIBOBJ files are:
+# getpid.c
+# clock.c
+#
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/compat/clock.c b/comm/third_party/libgcrypt/compat/clock.c
new file mode 100644
index 0000000000..2a2c205f3e
--- /dev/null
+++ b/comm/third_party/libgcrypt/compat/clock.c
@@ -0,0 +1,36 @@
+/* clock.c - Replacement for WindowsCE
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_W32CE_SYSTEM
+#include <windows.h>
+#include <time.h>
+#include <assert.h>
+
+clock_t
+_gcry_clock (void)
+{
+ assert (CLOCKS_PER_SEC == 1000);
+#warning Replace by a correct implementation.
+ /* It seems that GetProcessTimes is available in the kernel but
+ without a declaration. If that fails we would need to walk over
+ all threads and tally up the GetThreadTimes. */
+
+ return GetTickCount ();
+}
+
+#else
+# error No replacement function for clock known
+#endif
diff --git a/comm/third_party/libgcrypt/compat/compat.c b/comm/third_party/libgcrypt/compat/compat.c
new file mode 100644
index 0000000000..88f20c13a5
--- /dev/null
+++ b/comm/third_party/libgcrypt/compat/compat.c
@@ -0,0 +1,40 @@
+/* compat.c - Dummy file to avoid an empty library.
+ * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "../src/g10lib.h"
+
+
+const char *
+_gcry_compat_identification (void)
+{
+ /* For complete list of copyright holders see the file AUTHORS in
+ the source distribution. */
+ static const char blurb[] =
+ "\n\n"
+ "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n"
+ "Copyright (C) 2000-2018 Free Software Foundation, Inc.\n"
+ "Copyright (C) 2012-2021 g10 Code GmbH\n"
+ "Copyright (C) 2013-2021 Jussi Kivilinna\n"
+ "\n"
+ "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n"
+ "\n\n";
+ return blurb;
+}
diff --git a/comm/third_party/libgcrypt/compat/getpid.c b/comm/third_party/libgcrypt/compat/getpid.c
new file mode 100644
index 0000000000..032387c367
--- /dev/null
+++ b/comm/third_party/libgcrypt/compat/getpid.c
@@ -0,0 +1,29 @@
+/* getpid.c - Replacement for WindowsCE
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_W32CE_SYSTEM
+#include <windows.h>
+#include <sys/types.h>
+
+pid_t
+_gcry_getpid (void)
+{
+ return GetCurrentProcessId ();
+}
+
+#else
+# error No replacement function for getpid known
+#endif
diff --git a/comm/third_party/libgcrypt/compat/libcompat.h b/comm/third_party/libgcrypt/compat/libcompat.h
new file mode 100644
index 0000000000..b5a7649129
--- /dev/null
+++ b/comm/third_party/libgcrypt/compat/libcompat.h
@@ -0,0 +1,37 @@
+/* libcomapt.h - Prototypes for AC_REPLACE_FUNCtions.
+ * Copyright (C) 2010 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_LIBCOMPAT_H
+#define GCRY_LIBCOMPAT_H
+
+const char *_gcry_compat_identification (void);
+
+
+#ifndef HAVE_GETPID
+pid_t _gcry_getpid (void);
+#define getpid() _gcry_getpid ()
+#endif
+
+#ifndef HAVE_CLOCK
+clock_t _gcry_clock (void);
+#define clock() _gcry_clock ()
+#endif
+
+
+#endif /*GCRY_LIBCOMPAT_H*/
diff --git a/comm/third_party/libgcrypt/config.h.in b/comm/third_party/libgcrypt/config.h.in
new file mode 100644
index 0000000000..7fa46b7dad
--- /dev/null
+++ b/comm/third_party/libgcrypt/config.h.in
@@ -0,0 +1,753 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+#define _GCRYPT_CONFIG_H_INCLUDED
+
+/* Enable gpg-error's strerror macro for W32CE. */
+#define GPG_ERR_ENABLE_ERRNO_MACROS 1
+
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* GIT commit id revision used to build this package */
+#undef BUILD_REVISION
+
+/* The time this package was configured for a build */
+#undef BUILD_TIMESTAMP
+
+/* configure did not test for endianness */
+#undef DISABLED_ENDIAN_CHECK
+
+/* Define if you don't want the default EGD socket name. For details see
+ cipher/rndegd.c */
+#undef EGD_SOCKET_NAME
+
+/* Enable support for Intel AES-NI instructions. */
+#undef ENABLE_AESNI_SUPPORT
+
+/* Enable support for ARMv8 Crypto Extension instructions. */
+#undef ENABLE_ARM_CRYPTO_SUPPORT
+
+/* Enable support for Intel AVX2 instructions. */
+#undef ENABLE_AVX2_SUPPORT
+
+/* Enable support for Intel AVX instructions. */
+#undef ENABLE_AVX_SUPPORT
+
+/* Enable support for Intel DRNG (RDRAND instruction). */
+#undef ENABLE_DRNG_SUPPORT
+
+/* Enable forcing 'soft' HW feature bits on (for testing). */
+#undef ENABLE_FORCE_SOFT_HWFEATURES
+
+/* Define to support an HMAC based integrity check */
+#undef ENABLE_HMAC_BINARY_CHECK
+
+/* Enable support for the jitter entropy collector. */
+#undef ENABLE_JENT_SUPPORT
+
+/* Enable support for ARM NEON instructions. */
+#undef ENABLE_NEON_SUPPORT
+
+/* Enable support for the PadLock engine. */
+#undef ENABLE_PADLOCK_SUPPORT
+
+/* Enable support for Intel PCLMUL instructions. */
+#undef ENABLE_PCLMUL_SUPPORT
+
+/* Enable support for POWER 8 (PowerISA 2.07) crypto extension. */
+#undef ENABLE_PPC_CRYPTO_SUPPORT
+
+/* Enable support for Intel SHAEXT instructions. */
+#undef ENABLE_SHAEXT_SUPPORT
+
+/* Enable support for Intel SSE4.1 instructions. */
+#undef ENABLE_SSE41_SUPPORT
+
+/* Define to use the GNU C visibility attribute. */
+#undef GCRY_USE_VISIBILITY
+
+/* The default error source for libgcrypt. */
+#undef GPG_ERR_SOURCE_DEFAULT
+
+/* Defined if ARM architecture is v6 or newer */
+#undef HAVE_ARM_ARCH_V6
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Defined if the mlock() call does not work */
+#undef HAVE_BROKEN_MLOCK
+
+/* Defined if compiler has '__builtin_bswap32' intrinsic */
+#undef HAVE_BUILTIN_BSWAP32
+
+/* Defined if compiler has '__builtin_bswap64' intrinsic */
+#undef HAVE_BUILTIN_BSWAP64
+
+/* Defined if compiler has '__builtin_clz' intrinsic */
+#undef HAVE_BUILTIN_CLZ
+
+/* Defined if compiler has '__builtin_clzl' intrinsic */
+#undef HAVE_BUILTIN_CLZL
+
+/* Defined if compiler has '__builtin_ctz' intrinsic */
+#undef HAVE_BUILTIN_CTZ
+
+/* Defined if compiler has '__builtin_ctzl' intrinsic */
+#undef HAVE_BUILTIN_CTZL
+
+/* Define to 1 if the system has the type `byte'. */
+#undef HAVE_BYTE
+
+/* Define to 1 if you have the `clock' function. */
+#undef HAVE_CLOCK
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
+/* Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto
+ intrinsics */
+#undef HAVE_COMPATIBLE_CC_PPC_ALTIVEC
+
+/* Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto
+ intrinsics with extra GCC flags */
+#undef HAVE_COMPATIBLE_CC_PPC_ALTIVEC_WITH_CFLAGS
+
+/* Defined if underlying assembler is compatible with ARMv8/Aarch64 assembly
+ implementations */
+#undef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS
+
+/* Defined if underlying assembler is compatible with amd64 assembly
+ implementations */
+#undef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+
+/* Defined if underlying assembler is compatible with ARM assembly
+ implementations */
+#undef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+/* Defined if underlying assembler is compatible with WIN64 assembly
+ implementations */
+#undef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+
+/* Defined for Alpha platforms */
+#undef HAVE_CPU_ARCH_ALPHA
+
+/* Defined for ARM AArch64 platforms */
+#undef HAVE_CPU_ARCH_ARM
+
+/* Defined for M68k platforms */
+#undef HAVE_CPU_ARCH_M68K
+
+/* Defined for MIPS platforms */
+#undef HAVE_CPU_ARCH_MIPS
+
+/* Defined for PPC platforms */
+#undef HAVE_CPU_ARCH_PPC
+
+/* Defined for s390x/zSeries platforms */
+#undef HAVE_CPU_ARCH_S390X
+
+/* Defined for SPARC platforms */
+#undef HAVE_CPU_ARCH_SPARC
+
+/* Defined for the x86 platforms */
+#undef HAVE_CPU_ARCH_X86
+
+/* defined if the system supports a random device */
+#undef HAVE_DEV_RANDOM
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2)
+ with special properties like no file modes */
+#undef HAVE_DOSISH_SYSTEM
+
+/* defined if we must run on a stupid file system */
+#undef HAVE_DRIVE_LETTERS
+
+/* Define to 1 if you have the `elf_aux_info' function. */
+#undef HAVE_ELF_AUX_INFO
+
+/* Define to 1 if you have the `explicit_bzero' function. */
+#undef HAVE_EXPLICIT_BZERO
+
+/* Define to 1 if you have the `explicit_memset' function. */
+#undef HAVE_EXPLICIT_MEMSET
+
+/* Define to 1 if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
+/* Define to 1 if you have the `flockfile' function. */
+#undef HAVE_FLOCKFILE
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Defined if underlying assembler supports for CFI directives */
+#undef HAVE_GCC_ASM_CFI_DIRECTIVES
+
+/* Defined if underlying assembler supports for ELF directives */
+#undef HAVE_GCC_ASM_ELF_DIRECTIVES
+
+/* Define if inline asm memory barrier is supported */
+#undef HAVE_GCC_ASM_VOLATILE_MEMORY
+
+/* Defined if a GCC style "__attribute__ ((aligned (n))" is supported */
+#undef HAVE_GCC_ATTRIBUTE_ALIGNED
+
+/* Defined if a GCC style "__attribute__ ((may_alias))" is supported */
+#undef HAVE_GCC_ATTRIBUTE_MAY_ALIAS
+
+/* Defined if compiler supports "__attribute__ ((ms_abi))" function attribute
+ */
+#undef HAVE_GCC_ATTRIBUTE_MS_ABI
+
+/* Defined if a GCC style "__attribute__ ((packed))" is supported */
+#undef HAVE_GCC_ATTRIBUTE_PACKED
+
+/* Defined if compiler supports "__attribute__ ((sysv_abi))" function
+ attribute */
+#undef HAVE_GCC_ATTRIBUTE_SYSV_ABI
+
+/* Defined if default calling convention is 'ms_abi' */
+#undef HAVE_GCC_DEFAULT_ABI_IS_MS_ABI
+
+/* Defined if default calling convention is 'sysv_abi' */
+#undef HAVE_GCC_DEFAULT_ABI_IS_SYSV_ABI
+
+/* Defined if inline assembler supports AArch32 Crypto Extension instructions
+ */
+#undef HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO
+
+/* Defined if inline assembler supports AArch64 Crypto Extension instructions
+ */
+#undef HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO
+
+/* Defined if inline assembler supports AArch64 NEON instructions */
+#undef HAVE_GCC_INLINE_ASM_AARCH64_NEON
+
+/* Defined if inline assembler supports AVX instructions */
+#undef HAVE_GCC_INLINE_ASM_AVX
+
+/* Defined if inline assembler supports AVX2 instructions */
+#undef HAVE_GCC_INLINE_ASM_AVX2
+
+/* Defined if inline assembler supports BMI2 instructions */
+#undef HAVE_GCC_INLINE_ASM_BMI2
+
+/* Defined if inline assembler supports NEON instructions */
+#undef HAVE_GCC_INLINE_ASM_NEON
+
+/* Defined if inline assembler supports PCLMUL instructions */
+#undef HAVE_GCC_INLINE_ASM_PCLMUL
+
+/* Defined if inline assembler supports PowerPC AltiVec/VSX/crypto
+ instructions */
+#undef HAVE_GCC_INLINE_ASM_PPC_ALTIVEC
+
+/* Defined if inline assembler supports PowerISA 3.00 instructions */
+#undef HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00
+
+/* Defined if inline assembler supports zSeries instructions */
+#undef HAVE_GCC_INLINE_ASM_S390X
+
+/* Defined if inline assembler supports zSeries vector instructions */
+#undef HAVE_GCC_INLINE_ASM_S390X_VX
+
+/* Defined if inline assembler supports SHA Extensions instructions */
+#undef HAVE_GCC_INLINE_ASM_SHAEXT
+
+/* Defined if inline assembler supports SSE4.1 instructions */
+#undef HAVE_GCC_INLINE_ASM_SSE41
+
+/* Defined if inline assembler supports SSSE3 instructions */
+#undef HAVE_GCC_INLINE_ASM_SSSE3
+
+/* Define to 1 if you have the `getauxval' function. */
+#undef HAVE_GETAUXVAL
+
+/* Define to 1 if you have the `getentropy' function. */
+#undef HAVE_GETENTROPY
+
+/* Define to 1 if you have the `gethrtime' function. */
+#undef HAVE_GETHRTIME
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getpid' function. */
+#undef HAVE_GETPID
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Defined if underlying assembler is compatible with Intel syntax assembly
+ implementations */
+#undef HAVE_INTEL_SYNTAX_PLATFORM_AS
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+#undef HAVE_LIBRT
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Defined if the system supports an mlock() call */
+#undef HAVE_MLOCK
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Defined if the GNU Pth is available */
+#undef HAVE_PTH
+
+/* Define if we have pthread. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the `raise' function. */
+#undef HAVE_RAISE
+
+/* Define to 1 if you have the `rand' function. */
+#undef HAVE_RAND
+
+/* Define to 1 if you have the <spawn.h> header file. */
+#undef HAVE_SPAWN_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `stpcpy' function. */
+#undef HAVE_STPCPY
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `stricmp' function. */
+#undef HAVE_STRICMP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtoul' function. */
+#undef HAVE_STRTOUL
+
+/* Defined if compiler has '__sync_synchronize' intrinsic */
+#undef HAVE_SYNC_SYNCHRONIZE
+
+/* Define to 1 if you have the `syscall' function. */
+#undef HAVE_SYSCALL
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the `syslog' function. */
+#undef HAVE_SYSLOG
+
+/* Define to 1 if you have the <sys/auxv.h> header file. */
+#undef HAVE_SYS_AUXV_H
+
+/* Define to 1 if you have the <sys/capability.h> header file. */
+#undef HAVE_SYS_CAPABILITY_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/msg.h> header file. */
+#undef HAVE_SYS_MSG_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if the system has the type `u16'. */
+#undef HAVE_U16
+
+/* Define to 1 if the system has the type `u32'. */
+#undef HAVE_U32
+
+/* Define to 1 if the system has the type `u64'. */
+#undef HAVE_U64
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#undef HAVE_UINTPTR_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if the system has the type `ushort'. */
+#undef HAVE_USHORT
+
+/* Defined if variable length arrays are supported */
+#undef HAVE_VLA
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Defined if we run on WindowsCE */
+#undef HAVE_W32CE_SYSTEM
+
+/* Defined if we run on a W32 API based system */
+#undef HAVE_W32_SYSTEM
+
+/* Define to 1 if you have the `wait4' function. */
+#undef HAVE_WAIT4
+
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define to 1 if you have the <ws2tcpip.h> header file. */
+#undef HAVE_WS2TCPIP_H
+
+/* Defined if this is not a regular release */
+#undef IS_DEVELOPMENT_VERSION
+
+/* List of available cipher algorithms */
+#undef LIBGCRYPT_CIPHERS
+
+/* List of available digest algorithms */
+#undef LIBGCRYPT_DIGESTS
+
+/* List of available KDF algorithms */
+#undef LIBGCRYPT_KDFS
+
+/* List of available public key cipher algorithms */
+#undef LIBGCRYPT_PUBKEY_CIPHERS
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Define to use the (obsolete) malloc guarding feature */
+#undef M_GUARD
+
+/* defined to the name of the strong random device */
+#undef NAME_OF_DEV_RANDOM
+
+/* defined to the name of the weaker random device */
+#undef NAME_OF_DEV_URANDOM
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* A human readable text with the name of the OS */
+#undef PRINTABLE_OS_NAME
+
+/* The size of `uint64_t', as computed by sizeof. */
+#undef SIZEOF_UINT64_T
+
+/* The size of `unsigned int', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The size of `unsigned long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The size of `unsigned long long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG_LONG
+
+/* The size of `unsigned short', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_SHORT
+
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Defined if this module should be included */
+#undef USE_AES
+
+/* Defined if this module should be included */
+#undef USE_ARCFOUR
+
+/* Defined if this module should be included */
+#undef USE_BLAKE2
+
+/* Defined if this module should be included */
+#undef USE_BLOWFISH
+
+/* Defined if this module should be included */
+#undef USE_CAMELLIA
+
+/* define if capabilities should be used */
+#undef USE_CAPABILITIES
+
+/* Defined if this module should be included */
+#undef USE_CAST5
+
+/* Defined if this module should be included */
+#undef USE_CHACHA20
+
+/* Defined if this module should be included */
+#undef USE_CRC
+
+/* Defined if this module should be included */
+#undef USE_DES
+
+/* Defined if this module should be included */
+#undef USE_DSA
+
+/* Defined if this module should be included */
+#undef USE_ECC
+
+/* Defined if this module should be included */
+#undef USE_ELGAMAL
+
+/* Defined if the GNU Portable Thread Library should be used */
+#undef USE_GNU_PTH
+
+/* Defined if this module should be included */
+#undef USE_GOST28147
+
+/* Defined if this module should be included */
+#undef USE_GOST_R_3411_12
+
+/* Defined if this module should be included */
+#undef USE_GOST_R_3411_94
+
+/* Defined if this module should be included */
+#undef USE_IDEA
+
+/* Defined if this module should be included */
+#undef USE_MD2
+
+/* Defined if this module should be included */
+#undef USE_MD4
+
+/* Defined if this module should be included */
+#undef USE_MD5
+
+/* set this to limit filenames to the 8.3 format */
+#undef USE_ONLY_8DOT3
+
+/* defined if we use posix_spawn in test program */
+#undef USE_POSIX_SPAWN_FOR_TESTS
+
+/* Define to support the experimental random daemon */
+#undef USE_RANDOM_DAEMON
+
+/* Defined if this module should be included */
+#undef USE_RFC2268
+
+/* Defined if this module should be included */
+#undef USE_RMD160
+
+/* Defined if the EGD based RNG should be used. */
+#undef USE_RNDEGD
+
+/* Defined if the /dev/random RNG should be used. */
+#undef USE_RNDLINUX
+
+/* Defined if the default Unix RNG should be used. */
+#undef USE_RNDUNIX
+
+/* Defined if the Windows specific RNG should be used. */
+#undef USE_RNDW32
+
+/* Defined if the WindowsCE specific RNG should be used. */
+#undef USE_RNDW32CE
+
+/* Defined if this module should be included */
+#undef USE_RSA
+
+/* Defined if this module should be included */
+#undef USE_SALSA20
+
+/* Defined if this module should be included */
+#undef USE_SCRYPT
+
+/* Defined if this module should be included */
+#undef USE_SEED
+
+/* Defined if this module should be included */
+#undef USE_SERPENT
+
+/* Defined if this module should be included */
+#undef USE_SHA1
+
+/* Defined if this module should be included */
+#undef USE_SHA256
+
+/* Defined if this module should be included */
+#undef USE_SHA3
+
+/* Defined if this module should be included */
+#undef USE_SHA512
+
+/* Defined if this module should be included */
+#undef USE_SM3
+
+/* Defined if this module should be included */
+#undef USE_SM4
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Defined if this module should be included */
+#undef USE_TIGER
+
+/* Defined if this module should be included */
+#undef USE_TWOFISH
+
+/* Defined if this module should be included */
+#undef USE_WHIRLPOOL
+
+/* Version number of package */
+#undef VERSION
+
+/* Defined if compiled symbols have a leading underscore */
+#undef WITH_SYMBOL_UNDERSCORE
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Expose all libc features (__DARWIN_C_FULL). */
+#undef _DARWIN_C_SOURCE
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* To allow the use of Libgcrypt in multithreaded programs we have to use
+ special features from the library. */
+#ifndef _REENTRANT
+# define _REENTRANT 1
+#endif
+
+
+/* Define to supported assembler block keyword, if plain 'asm' was not
+ supported */
+#undef asm
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* type to use in place of socklen_t if not defined */
+#undef socklen_t
+
+/* Define to the type of an unsigned integer type wide enough to hold a
+ pointer, if such a type exists, and if the system does not define it. */
+#undef uintptr_t
+
+
+#define _GCRYPT_IN_LIBGCRYPT 1
+
+/* Add .note.gnu.property section for Intel CET in assembler sources
+ when CET is enabled. */
+#if defined(__ASSEMBLER__) && defined(__CET__)
+# include <cet.h>
+#endif
+
+/* If the configure check for endianness has been disabled, get it from
+ OS macros. This is intended for making fat binary builds on OS X. */
+#ifdef DISABLED_ENDIAN_CHECK
+# if defined(__BIG_ENDIAN__)
+# define WORDS_BIGENDIAN 1
+# elif defined(__LITTLE_ENDIAN__)
+# undef WORDS_BIGENDIAN
+# else
+# error "No endianness found"
+# endif
+#endif /*DISABLED_ENDIAN_CHECK*/
+
+/* We basically use the original Camellia source. Make sure the symbols
+ properly prefixed. */
+#define CAMELLIA_EXT_SYM_PREFIX _gcry_
+
+#endif /*_GCRYPT_CONFIG_H_INCLUDED*/
+
diff --git a/comm/third_party/libgcrypt/configure b/comm/third_party/libgcrypt/configure
new file mode 100755
index 0000000000..e8909e2ecb
--- /dev/null
+++ b/comm/third_party/libgcrypt/configure
@@ -0,0 +1,22807 @@
+#! /bin/sh
+# From configure.ac Revision.
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for libgcrypt 1.9.2.
+#
+# Report bugs to <https://bugs.gnupg.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: https://bugs.gnupg.org about your system, including any
+$0: error possibly output before this message. Then install
+$0: a modern shell, or manually run the script under such a
+$0: shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='libgcrypt'
+PACKAGE_TARNAME='libgcrypt'
+PACKAGE_VERSION='1.9.2'
+PACKAGE_STRING='libgcrypt 1.9.2'
+PACKAGE_BUGREPORT='https://bugs.gnupg.org'
+PACKAGE_URL=''
+
+ac_unique_file="src/libgcrypt.vers"
+ac_config_libobj_dir=compat
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_header_list=
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+BUILD_TIMESTAMP
+BUILD_FILEVERSION
+BUILD_VERSION
+BUILD_REVISION
+BUILD_DOC_FALSE
+BUILD_DOC_TRUE
+GCRYPT_HWF_MODULES
+LIBGCRYPT_DIGESTS
+LIBGCRYPT_PUBKEY_CIPHERS
+LIBGCRYPT_CIPHERS
+GCRYPT_RANDOM
+GCRYPT_KDFS
+GCRYPT_DIGESTS
+GCRYPT_PUBKEY_CIPHERS
+GCRYPT_CIPHERS
+LIBGCRYPT_THREAD_MODULES
+LIBGCRYPT_CONFIG_HOST
+LIBGCRYPT_CONFIG_CFLAGS
+LIBGCRYPT_CONFIG_LIBS
+LIBGCRYPT_CONFIG_API_VERSION
+NOEXECSTACK_FLAGS
+CROSS_COMPILING_FALSE
+CROSS_COMPILING_TRUE
+DL_LIBS
+LIBOBJS
+ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_FALSE
+ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_TRUE
+MPI_MOD_C_UDIV_QRNND_FALSE
+MPI_MOD_C_UDIV_QRNND_TRUE
+MPI_MOD_C_UDIV_FALSE
+MPI_MOD_C_UDIV_TRUE
+MPI_MOD_C_MPIH_RSHIFT_FALSE
+MPI_MOD_C_MPIH_RSHIFT_TRUE
+MPI_MOD_C_MPIH_LSHIFT_FALSE
+MPI_MOD_C_MPIH_LSHIFT_TRUE
+MPI_MOD_C_MPIH_MUL3_FALSE
+MPI_MOD_C_MPIH_MUL3_TRUE
+MPI_MOD_C_MPIH_MUL2_FALSE
+MPI_MOD_C_MPIH_MUL2_TRUE
+MPI_MOD_C_MPIH_MUL1_FALSE
+MPI_MOD_C_MPIH_MUL1_TRUE
+MPI_MOD_C_MPIH_SUB1_FALSE
+MPI_MOD_C_MPIH_SUB1_TRUE
+MPI_MOD_C_MPIH_ADD1_FALSE
+MPI_MOD_C_MPIH_ADD1_TRUE
+MPI_MOD_ASM_UDIV_QRNND_FALSE
+MPI_MOD_ASM_UDIV_QRNND_TRUE
+MPI_MOD_ASM_UDIV_FALSE
+MPI_MOD_ASM_UDIV_TRUE
+MPI_MOD_ASM_MPIH_RSHIFT_FALSE
+MPI_MOD_ASM_MPIH_RSHIFT_TRUE
+MPI_MOD_ASM_MPIH_LSHIFT_FALSE
+MPI_MOD_ASM_MPIH_LSHIFT_TRUE
+MPI_MOD_ASM_MPIH_MUL3_FALSE
+MPI_MOD_ASM_MPIH_MUL3_TRUE
+MPI_MOD_ASM_MPIH_MUL2_FALSE
+MPI_MOD_ASM_MPIH_MUL2_TRUE
+MPI_MOD_ASM_MPIH_MUL1_FALSE
+MPI_MOD_ASM_MPIH_MUL1_TRUE
+MPI_MOD_ASM_MPIH_SUB1_FALSE
+MPI_MOD_ASM_MPIH_SUB1_TRUE
+MPI_MOD_ASM_MPIH_ADD1_FALSE
+MPI_MOD_ASM_MPIH_ADD1_TRUE
+MPI_SFLAGS
+FALLBACK_SOCKLEN_T
+INSERT_SYS_SELECT_H
+PTH_LIBS
+PTH_CFLAGS
+PTH_CONFIG
+GPG_ERROR_MT_LIBS
+GPG_ERROR_MT_CFLAGS
+GPG_ERROR_LIBS
+GPG_ERROR_CFLAGS
+GPGRT_CONFIG
+GPG_ERROR_CONFIG
+HAVE_LD_VERSION_SCRIPT_FALSE
+HAVE_LD_VERSION_SCRIPT_TRUE
+ENABLE_INSTRUMENTATION_MUNGING_FALSE
+ENABLE_INSTRUMENTATION_MUNGING_TRUE
+ENABLE_O_FLAG_MUNGING_FALSE
+ENABLE_O_FLAG_MUNGING_TRUE
+RUN_LARGE_DATA_TESTS
+USE_RANDOM_DAEMON_FALSE
+USE_RANDOM_DAEMON_TRUE
+emacs_local_vars_end
+emacs_local_vars_read_only
+emacs_local_vars_begin
+HAVE_W32CE_SYSTEM_FALSE
+HAVE_W32CE_SYSTEM_TRUE
+HAVE_W32_SYSTEM_FALSE
+HAVE_W32_SYSTEM_TRUE
+RC
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+LIBTOOL
+OBJDUMP
+DLLTOOL
+AS
+EXEEXT_FOR_BUILD
+CC_FOR_BUILD
+VERSION_NUMBER
+LDADD_FOR_TESTS_KLUDGE
+EGREP
+GREP
+am__fastdepCCAS_FALSE
+am__fastdepCCAS_TRUE
+CCASDEPMODE
+CCASFLAGS
+CCAS
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+SYSROOT
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+LIBGCRYPT_LT_REVISION
+LIBGCRYPT_LT_AGE
+LIBGCRYPT_LT_CURRENT
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL
+am__quote'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_maintainer_mode
+enable_dependency_tracking
+enable_static
+enable_shared
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_endian_check
+enable_ciphers
+enable_pubkey_ciphers
+enable_digests
+enable_kdfs
+enable_random
+enable_dev_random
+with_egd_socket
+enable_random_daemon
+enable_asm
+enable_m_guard
+enable_large_data_tests
+enable_force_soft_hwfeatures
+with_capabilities
+enable_hmac_binary_check
+enable_jent_support
+enable_padlock_support
+enable_aesni_support
+enable_shaext_support
+enable_pclmul_support
+enable_sse41_support
+enable_drng_support
+enable_avx_support
+enable_avx2_support
+enable_neon_support
+enable_arm_crypto_support
+enable_ppc_crypto_support
+enable_O_flag_munging
+enable_instrumentation_munging
+enable_amd64_as_feature_detection
+enable_ld_version_script
+with_libgpg_error_prefix
+with_gpg_error_prefix
+with_pth_prefix
+enable_mpi_path
+enable_optimization
+enable_noexecstack
+enable_doc
+enable_build_timestamp
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+SYSROOT
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CCAS
+CCASFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir runstatedir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures libgcrypt 1.9.2 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/libgcrypt]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of libgcrypt 1.9.2:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --enable-static[=PKGS] build static libraries [default=no]
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --disable-endian-check disable the endian check and trust the OS provided
+ macros
+ --enable-ciphers=ciphers
+ select the symmetric ciphers to include
+ --enable-pubkey-ciphers=ciphers
+ select the public-key ciphers to include
+ --enable-digests=digests
+ select the message digests to include
+ --enable-kfds=kdfs select the KDFs to include
+ --enable-random=name select which random number generator to use
+ --disable-dev-random disable the use of dev random
+ --enable-random-daemon Build and support the experimental gcryptrnd
+ --disable-asm Disable MPI and cipher assembler modules
+ --enable-m-guard Enable memory guard facility
+ --enable-large-data-tests
+ Enable the real long ruinning large data tests
+ --enable-force-soft-hwfeatures
+ Enable forcing 'soft' HW feature bits on
+ --enable-hmac-binary-check
+ Enable library integrity check
+ --disable-jent-support Disable support for the Jitter entropy collector
+ --disable-padlock-support
+ Disable support for the PadLock Engine of VIA
+ processors
+ --disable-aesni-support Disable support for the Intel AES-NI instructions
+ --disable-shaext-support
+ Disable support for the Intel SHAEXT instructions
+ --disable-pclmul-support
+ Disable support for the Intel PCLMUL instructions
+ --disable-sse41-support Disable support for the Intel SSE4.1 instructions
+ --disable-drng-support Disable support for the Intel DRNG (RDRAND
+ instruction)
+ --disable-avx-support Disable support for the Intel AVX instructions
+ --disable-avx2-support Disable support for the Intel AVX2 instructions
+ --disable-neon-support Disable support for the ARM NEON instructions
+ --disable-arm-crypto-support
+ Disable support for the ARMv8 Crypto Extension
+ instructions
+ --disable-ppc-crypto-support
+ Disable support for the PPC crypto instructions
+ introduced in POWER 8 (PowerISA 2.07)
+ --disable-O-flag-munging
+ Disable modification of the cc -O flag
+ --disable-instrumentation-munging
+ Disable modification of the cc instrumentation
+ options
+ --disable-amd64-as-feature-detection
+ Disable the auto-detection of AMD64 as(1) features
+ --enable-ld-version-script
+ enable/disable use of linker version script.
+ (default is system dependent)
+ --enable-mpi-path=EXTRA_PATH
+ prepend EXTRA_PATH to list of CPU specific
+ optimizations
+ --disable-optimization disable compiler optimization
+ --disable-noexecstack disable non executable stack support
+ --disable-doc do not build the documentation
+ --enable-build-timestamp
+ set an explicit build timestamp for reproducibility.
+ (default is the current time in ISO-8601 format)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot=DIR Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).
+ --with-egd-socket=NAME Use NAME for the EGD socket)
+ --with-capabilities Use linux capabilities [default=no]
+ --with-libgpg-error-prefix=PFX
+ prefix where GPG Error is installed (optional)
+
+ --with-pth-prefix=PFX prefix where GNU Pth is installed (optional)
+
+Some influential environment variables:
+ SYSROOT locate config scripts also below that directory
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ CCAS assembler compiler command (defaults to CC)
+ CCASFLAGS assembler compiler flags (defaults to CFLAGS)
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <https://bugs.gnupg.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+libgcrypt configure 1.9.2
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------- ##
+## Report this to https://bugs.gnupg.org ##
+## ------------------------------------- ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by libgcrypt $as_me 1.9.2, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+as_fn_append ac_header_list " sys/socket.h"
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# LT Version numbers, remember to change them just *before* a release.
+# (Code changed: REVISION++)
+# (Interfaces added/removed/changed: CURRENT++, REVISION=0)
+# (Interfaces added: AGE++)
+# (Interfaces removed: AGE=0)
+#
+# (Interfaces removed: CURRENT++, AGE=0, REVISION=0)
+# (Interfaces added: CURRENT++, AGE++, REVISION=0)
+# (No interfaces changed: REVISION++)
+LIBGCRYPT_LT_CURRENT=23
+LIBGCRYPT_LT_AGE=3
+LIBGCRYPT_LT_REVISION=2
+################################################
+
+
+
+
+
+# If the API is changed in an incompatible way: increment the next counter.
+#
+# 1.6: ABI and API change but the change is to most users irrelevant
+# and thus the API version number has not been incremented.
+LIBGCRYPT_CONFIG_API_VERSION=1
+
+# If you change the required gpg-error version, please remove
+# unnecessary error code defines in src/gcrypt-int.h.
+NEED_GPG_ERROR_VERSION=1.27
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+am__api_version='1.16'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='libgcrypt'
+ VERSION='1.9.2'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+
+
+
+
+
+
+
+
+
+
+######################
+## Basic checks. ### (we need some results later on (e.g. $GCC)
+######################
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+missing_dir=`cd $ac_aux_dir && pwd`
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+# AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+cat > confinc.mk << 'END'
+am__doit:
+ @echo this is the am__doit target >confinc.out
+.PHONY: am__doit
+END
+am__include="#"
+am__quote=
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+ { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
+ (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ case $?:`cat confinc.out 2>/dev/null` in #(
+ '0:this is the am__doit target') :
+ case $s in #(
+ BSD) :
+ am__include='.include' am__quote='"' ;; #(
+ *) :
+ am__include='include' am__quote='' ;;
+esac ;; #(
+ *) :
+ ;;
+esac
+ if test "$am__include" != "#"; then
+ _am_result="yes ($s style)"
+ break
+ fi
+done
+rm -f confinc.* confmf.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+$as_echo "${_am_result}" >&6; }
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# By default we simply use the C compiler to build assembly code.
+
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+
+
+
+depcc="$CCAS" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CCAS_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CCAS_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CCAS_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CCAS_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; }
+CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then
+ am__fastdepCCAS_TRUE=
+ am__fastdepCCAS_FALSE='#'
+else
+ am__fastdepCCAS_TRUE='#'
+ am__fastdepCCAS_FALSE=
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
+$as_echo_n "checking for library containing strerror... " >&6; }
+if ${ac_cv_search_strerror+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strerror ();
+int
+main ()
+{
+return strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' cposix; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_strerror=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_strerror+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_strerror+:} false; then :
+
+else
+ ac_cv_search_strerror=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5
+$as_echo "$ac_cv_search_strerror" >&6; }
+ac_res=$ac_cv_search_strerror
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+# Taken from mpfr-4.0.1, then modified for LDADD_FOR_TESTS_KLUDGE
+case $host in
+ *-*-linux*)
+ if test -n "$LD_LIBRARY_PATH"; then
+ saved_LDFLAGS="$LDFLAGS"
+ LDADD_FOR_TESTS_KLUDGE="-Wl,--disable-new-dtags"
+ LDFLAGS="$LDFLAGS $LDADD_FOR_TESTS_KLUDGE"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether --disable-new-dtags is supported by the linker" >&5
+$as_echo_n "checking whether --disable-new-dtags is supported by the linker... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int main (void) { return 0; }
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (use it since LD_LIBRARY_PATH is set)" >&5
+$as_echo "yes (use it since LD_LIBRARY_PATH is set)" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ LDADD_FOR_TESTS_KLUDGE=""
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$saved_LDFLAGS"
+ fi
+ ;;
+esac
+
+
+VERSION_NUMBER=0x010902
+
+
+# We need to compile and run a program on the build machine.
+# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test -z "$CC_FOR_BUILD"; then
+ if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+ else
+ CC_FOR_BUILD=gcc
+ fi
+fi
+
+# Also set EXEEXT_FOR_BUILD.
+if test "x$cross_compiling" = "xno"; then
+ EXEEXT_FOR_BUILD='$(EXEEXT)'
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5
+$as_echo_n "checking for build system executable suffix... " >&6; }
+if ${bfd_cv_build_exeext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.c
+ bfd_cv_build_exeext=
+ ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ rm -f conftest*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5
+$as_echo "$bfd_cv_build_exeext" >&6; }
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+
+
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AS="as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+ ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=no
+fi
+
+
+
+
+
+
+
+
+
+
+ enable_dlopen=no
+
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ link_all_deplibs=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ link_all_deplibs=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
+set dummy ${ac_tool_prefix}windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RC"; then
+ ac_cv_prog_RC="$RC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RC="${ac_tool_prefix}windres"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RC=$ac_cv_prog_RC
+if test -n "$RC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
+$as_echo "$RC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RC"; then
+ ac_ct_RC=$RC
+ # Extract the first word of "windres", so it can be a program name with args.
+set dummy windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RC"; then
+ ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RC="windres"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RC=$ac_cv_prog_ac_ct_RC
+if test -n "$ac_ct_RC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
+$as_echo "$ac_ct_RC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RC" = x; then
+ RC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RC=$ac_ct_RC
+ fi
+else
+ RC="$ac_cv_prog_RC"
+fi
+
+
+
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+objext_RC=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+compiler_RC=$CC
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+lt_cv_prog_compiler_c_o_RC=yes
+
+if test -n "$compiler"; then
+ :
+
+
+
+fi
+
+GCC=$lt_save_GCC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+
+
+
+##########################
+## General definitions. ##
+##########################
+
+# Used by libgcrypt-config
+LIBGCRYPT_CONFIG_LIBS="-lgcrypt"
+LIBGCRYPT_CONFIG_CFLAGS=""
+LIBGCRYPT_CONFIG_HOST="$host"
+
+# Definitions for symmetric ciphers.
+available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed"
+available_ciphers="$available_ciphers camellia idea salsa20 gost28147 chacha20"
+available_ciphers="$available_ciphers sm4"
+enabled_ciphers=""
+
+# Definitions for public-key ciphers.
+available_pubkey_ciphers="dsa elgamal rsa ecc"
+enabled_pubkey_ciphers=""
+
+# Definitions for message digests.
+available_digests="crc gostr3411-94 md2 md4 md5 rmd160 sha1 sha256 sha512"
+available_digests="$available_digests sha3 tiger whirlpool stribog blake2"
+available_digests="$available_digests sm3"
+enabled_digests=""
+
+# Definitions for kdfs (optional ones)
+available_kdfs="s2k pkdf2 scrypt"
+enabled_kdfs=""
+
+# Definitions for random modules.
+available_random_modules="linux egd unix"
+auto_random_modules="$available_random_modules"
+
+# Supported thread backends.
+LIBGCRYPT_THREAD_MODULES=""
+
+# Other definitions.
+have_w32_system=no
+have_w32ce_system=no
+have_pthread=no
+
+
+# Setup some stuff depending on host.
+case "${host}" in
+ *-*-mingw32*)
+ ac_cv_have_dev_random=no
+ have_w32_system=yes
+ case "${host}" in
+ *-mingw32ce*)
+ have_w32ce_system=yes
+ available_random_modules="w32ce"
+ ;;
+ *)
+ available_random_modules="w32"
+ ;;
+ esac
+
+$as_echo "#define USE_ONLY_8DOT3 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DOSISH_SYSTEM 1" >>confdefs.h
+
+ ;;
+
+ i?86-emx-os2 | i?86-*-os2*emx)
+ # OS/2 with the EMX environment
+ ac_cv_have_dev_random=no
+ $as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h
+
+ $as_echo "#define HAVE_DOSISH_SYSTEM 1" >>confdefs.h
+
+ ;;
+
+ i?86-*-msdosdjgpp*)
+ # DOS with the DJGPP environment
+ ac_cv_have_dev_random=no
+ $as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h
+
+ $as_echo "#define HAVE_DOSISH_SYSTEM 1" >>confdefs.h
+
+ ;;
+
+ *-*-hpux*)
+ if test -z "$GCC" ; then
+ CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
+ fi
+ ;;
+ *-dec-osf4*)
+ if test -z "$GCC" ; then
+ # Suppress all warnings
+ # to get rid of the unsigned/signed char mismatch warnings.
+ CFLAGS="$CFLAGS -w"
+ fi
+ ;;
+ m68k-atari-mint)
+ ;;
+ *-apple-darwin*)
+
+$as_echo "#define _DARWIN_C_SOURCE 900000L" >>confdefs.h
+
+
+$as_echo "#define USE_POSIX_SPAWN_FOR_TESTS 1" >>confdefs.h
+
+ for ac_header in spawn.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "spawn.h" "ac_cv_header_spawn_h" "$ac_includes_default"
+if test "x$ac_cv_header_spawn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SPAWN_H 1
+_ACEOF
+
+fi
+
+done
+
+ ;;
+ *)
+ ;;
+esac
+
+if test "$have_w32_system" = yes; then
+
+$as_echo "#define HAVE_W32_SYSTEM 1" >>confdefs.h
+
+ if test "$have_w32ce_system" = yes; then
+
+$as_echo "#define HAVE_W32CE_SYSTEM 1" >>confdefs.h
+
+ fi
+fi
+ if test "$have_w32_system" = yes; then
+ HAVE_W32_SYSTEM_TRUE=
+ HAVE_W32_SYSTEM_FALSE='#'
+else
+ HAVE_W32_SYSTEM_TRUE='#'
+ HAVE_W32_SYSTEM_FALSE=
+fi
+
+ if test "$have_w32ce_system" = yes; then
+ HAVE_W32CE_SYSTEM_TRUE=
+ HAVE_W32CE_SYSTEM_FALSE='#'
+else
+ HAVE_W32CE_SYSTEM_TRUE='#'
+ HAVE_W32CE_SYSTEM_FALSE=
+fi
+
+
+
+
+# A printable OS Name is sometimes useful.
+case "${host}" in
+ *-*-mingw32ce*)
+ PRINTABLE_OS_NAME="W32CE"
+ ;;
+
+ *-*-mingw32*)
+ PRINTABLE_OS_NAME="W32"
+ ;;
+
+ i?86-emx-os2 | i?86-*-os2*emx )
+ PRINTABLE_OS_NAME="OS/2"
+ ;;
+
+ i?86-*-msdosdjgpp*)
+ PRINTABLE_OS_NAME="MSDOS/DJGPP"
+ ;;
+
+ *-linux*)
+ PRINTABLE_OS_NAME="GNU/Linux"
+ ;;
+
+ *)
+ PRINTABLE_OS_NAME=`uname -s || echo "Unknown"`
+ ;;
+esac
+
+NAME_OF_DEV_RANDOM="/dev/random"
+NAME_OF_DEV_URANDOM="/dev/urandom"
+
+# Check whether --enable-endian-check was given.
+if test "${enable_endian_check+set}" = set; then :
+ enableval=$enable_endian_check; endiancheck=$enableval
+else
+ endiancheck=yes
+fi
+
+if test x"$endiancheck" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+else
+
+$as_echo "#define DISABLED_ENDIAN_CHECK 1" >>confdefs.h
+
+fi
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5
+$as_echo_n "checking size of unsigned short... " >&6; }
+if ${ac_cv_sizeof_unsigned_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5
+$as_echo "$ac_cv_sizeof_unsigned_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5
+$as_echo_n "checking size of unsigned int... " >&6; }
+if ${ac_cv_sizeof_unsigned_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned int)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5
+$as_echo "$ac_cv_sizeof_unsigned_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
+$as_echo_n "checking size of unsigned long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5
+$as_echo_n "checking size of unsigned long long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
+$as_echo_n "checking size of void *... " >&6; }
+if ${ac_cv_sizeof_void_p+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_void_p" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (void *)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_void_p=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
+$as_echo "$ac_cv_sizeof_void_p" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+
+
+
+ ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintptr_t" = xyes; then :
+
+$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h
+
+else
+ for ac_type in 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define uintptr_t $ac_type
+_ACEOF
+
+ ac_type=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test -z "$ac_type" && break
+ done
+fi
+
+
+
+if test "$ac_cv_sizeof_unsigned_short" = "0" \
+ || test "$ac_cv_sizeof_unsigned_int" = "0" \
+ || test "$ac_cv_sizeof_unsigned_long" = "0"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Hmmm, something is wrong with the sizes - using defaults" >&5
+$as_echo "$as_me: WARNING: Hmmm, something is wrong with the sizes - using defaults" >&2;};
+fi
+
+# Ensure that we have UINT64_C before we bother to check for uint64_t
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UINT64_C" >&5
+$as_echo_n "checking for UINT64_C... " >&6; }
+if ${gnupg_cv_uint64_c_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <inttypes.h>
+int
+main ()
+{
+uint64_t foo=UINT64_C(42);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gnupg_cv_uint64_c_works=yes
+else
+ gnupg_cv_uint64_c_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_uint64_c_works" >&5
+$as_echo "$gnupg_cv_uint64_c_works" >&6; }
+if test "$gnupg_cv_uint64_c_works" = "yes" ; then
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint64_t" >&5
+$as_echo_n "checking size of uint64_t... " >&6; }
+if ${ac_cv_sizeof_uint64_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint64_t))" "ac_cv_sizeof_uint64_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_uint64_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (uint64_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_uint64_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint64_t" >&5
+$as_echo "$ac_cv_sizeof_uint64_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UINT64_T $ac_cv_sizeof_uint64_t
+_ACEOF
+
+
+fi
+
+# Do we have any 64-bit data types?
+if test "$ac_cv_sizeof_unsigned_int" != "8" \
+ && test "$ac_cv_sizeof_unsigned_long" != "8" \
+ && test "$ac_cv_sizeof_unsigned_long_long" != "8" \
+ && test "$ac_cv_sizeof_uint64_t" != "8"; then
+ as_fn_error $? "
+***
+*** No 64-bit integer type available.
+*** It is not possible to build Libgcrypt on this platform.
+***" "$LINENO" 5
+fi
+
+
+# If not specified otherwise, all available algorithms will be
+# included.
+default_ciphers="$available_ciphers"
+default_pubkey_ciphers="$available_pubkey_ciphers"
+default_digests="$available_digests"
+default_kdfs="$available_kdfs"
+# Blacklist MD2 by default
+default_digests=`echo $default_digests | sed -e 's/md2//g'`
+
+# Substitutions to set generated files in a Emacs buffer to read-only.
+emacs_local_vars_begin='Local Variables:'
+
+emacs_local_vars_read_only='buffer-read-only: t'
+
+emacs_local_vars_end='End:'
+
+
+############################
+## Command line switches. ##
+############################
+
+# Implementation of the --enable-ciphers switch.
+# Check whether --enable-ciphers was given.
+if test "${enable_ciphers+set}" = set; then :
+ enableval=$enable_ciphers; enabled_ciphers=`echo $enableval | tr ',:' ' ' | tr 'A-Z' 'a-z'`
+else
+ enabled_ciphers=""
+fi
+
+if test "x$enabled_ciphers" = "x" \
+ -o "$enabled_ciphers" = "yes" \
+ -o "$enabled_ciphers" = "no"; then
+ enabled_ciphers=$default_ciphers
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which symmetric ciphers to include" >&5
+$as_echo_n "checking which symmetric ciphers to include... " >&6; }
+for cipher in $enabled_ciphers; do
+
+name=$cipher
+list=$available_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error $? "unsupported cipher \"$cipher\" specified" "$LINENO" 5
+ fi
+done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_ciphers" >&5
+$as_echo "$enabled_ciphers" >&6; }
+
+# Implementation of the --enable-pubkey-ciphers switch.
+# Check whether --enable-pubkey-ciphers was given.
+if test "${enable_pubkey_ciphers+set}" = set; then :
+ enableval=$enable_pubkey_ciphers; enabled_pubkey_ciphers=`echo $enableval | tr ',:' ' ' | tr 'A-Z' 'a-z'`
+else
+ enabled_pubkey_ciphers=""
+fi
+
+if test "x$enabled_pubkey_ciphers" = "x" \
+ -o "$enabled_pubkey_ciphers" = "yes" \
+ -o "$enabled_pubkey_ciphers" = "no"; then
+ enabled_pubkey_ciphers=$default_pubkey_ciphers
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which public-key ciphers to include" >&5
+$as_echo_n "checking which public-key ciphers to include... " >&6; }
+for cipher in $enabled_pubkey_ciphers; do
+
+name=$cipher
+list=$available_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error $? "unsupported public-key cipher specified" "$LINENO" 5
+ fi
+done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_pubkey_ciphers" >&5
+$as_echo "$enabled_pubkey_ciphers" >&6; }
+
+# Implementation of the --enable-digests switch.
+# Check whether --enable-digests was given.
+if test "${enable_digests+set}" = set; then :
+ enableval=$enable_digests; enabled_digests=`echo $enableval | tr ',:' ' ' | tr 'A-Z' 'a-z'`
+else
+ enabled_digests=""
+fi
+
+if test "x$enabled_digests" = "x" \
+ -o "$enabled_digests" = "yes" \
+ -o "$enabled_digests" = "no"; then
+ enabled_digests=$default_digests
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which message digests to include" >&5
+$as_echo_n "checking which message digests to include... " >&6; }
+for digest in $enabled_digests; do
+
+name=$digest
+list=$available_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error $? "unsupported message digest specified" "$LINENO" 5
+ fi
+done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_digests" >&5
+$as_echo "$enabled_digests" >&6; }
+
+# Implementation of the --enable-kdfs switch.
+# Check whether --enable-kdfs was given.
+if test "${enable_kdfs+set}" = set; then :
+ enableval=$enable_kdfs; enabled_kdfs=`echo $enableval | tr ',:' ' ' | tr 'A-Z' 'a-z'`
+else
+ enabled_kdfs=""
+fi
+
+if test "x$enabled_kdfs" = "x" \
+ -o "$enabled_kdfs" = "yes" \
+ -o "$enabled_kdfs" = "no"; then
+ enabled_kdfs=$default_kdfs
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which key derivation functions to include" >&5
+$as_echo_n "checking which key derivation functions to include... " >&6; }
+for kdf in $enabled_kdfs; do
+
+name=$kdf
+list=$available_kdfs
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error $? "unsupported key derivation function specified" "$LINENO" 5
+ fi
+done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_kdfs" >&5
+$as_echo "$enabled_kdfs" >&6; }
+
+# Implementation of the --enable-random switch.
+# Check whether --enable-random was given.
+if test "${enable_random+set}" = set; then :
+ enableval=$enable_random; random=`echo $enableval | tr 'A-Z' 'a-z'`
+fi
+
+if test "x$random" = "x" -o "$random" = "yes" -o "$random" = "no"; then
+ random=default
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which random module to use" >&5
+$as_echo_n "checking which random module to use... " >&6; }
+if test "$random" != "default" -a "$random" != "auto"; then
+
+name=$random
+list=$available_random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error $? "unsupported random module specified" "$LINENO" 5
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $random" >&5
+$as_echo "$random" >&6; }
+
+# Implementation of the --disable-dev-random switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether use of /dev/random is requested" >&5
+$as_echo_n "checking whether use of /dev/random is requested... " >&6; }
+# Check whether --enable-dev-random was given.
+if test "${enable_dev_random+set}" = set; then :
+ enableval=$enable_dev_random; try_dev_random=$enableval
+else
+ try_dev_random=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_dev_random" >&5
+$as_echo "$try_dev_random" >&6; }
+
+# Implementation of the --with-egd-socket switch.
+
+# Check whether --with-egd-socket was given.
+if test "${with_egd_socket+set}" = set; then :
+ withval=$with_egd_socket; egd_socket_name="$withval"
+else
+ egd_socket_name=""
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define EGD_SOCKET_NAME "$egd_socket_name"
+_ACEOF
+
+
+# Implementation of the --enable-random-daemon
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the experimental random daemon is requested" >&5
+$as_echo_n "checking whether the experimental random daemon is requested... " >&6; }
+# Check whether --enable-random-daemon was given.
+if test "${enable_random_daemon+set}" = set; then :
+ enableval=$enable_random_daemon; use_random_daemon=$enableval
+else
+ use_random_daemon=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_random_daemon" >&5
+$as_echo "$use_random_daemon" >&6; }
+if test x$use_random_daemon = xyes ; then
+
+$as_echo "#define USE_RANDOM_DAEMON 1" >>confdefs.h
+
+fi
+ if test x$use_random_daemon = xyes; then
+ USE_RANDOM_DAEMON_TRUE=
+ USE_RANDOM_DAEMON_FALSE='#'
+else
+ USE_RANDOM_DAEMON_TRUE='#'
+ USE_RANDOM_DAEMON_FALSE=
+fi
+
+
+
+# Implementation of --disable-asm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether MPI and cipher assembler modules are requested" >&5
+$as_echo_n "checking whether MPI and cipher assembler modules are requested... " >&6; }
+# Check whether --enable-asm was given.
+if test "${enable_asm+set}" = set; then :
+ enableval=$enable_asm; try_asm_modules=$enableval
+else
+ try_asm_modules=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_asm_modules" >&5
+$as_echo "$try_asm_modules" >&6; }
+
+# Implementation of the --enable-m-guard switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether memory guard is requested" >&5
+$as_echo_n "checking whether memory guard is requested... " >&6; }
+# Check whether --enable-m-guard was given.
+if test "${enable_m_guard+set}" = set; then :
+ enableval=$enable_m_guard; use_m_guard=$enableval
+else
+ use_m_guard=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_m_guard" >&5
+$as_echo "$use_m_guard" >&6; }
+if test "$use_m_guard" = yes ; then
+
+$as_echo "#define M_GUARD 1" >>confdefs.h
+
+fi
+
+# Implementation of the --enable-large-data-tests switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to run large data tests" >&5
+$as_echo_n "checking whether to run large data tests... " >&6; }
+# Check whether --enable-large-data-tests was given.
+if test "${enable_large_data_tests+set}" = set; then :
+ enableval=$enable_large_data_tests; large_data_tests=$enableval
+else
+ large_data_tests=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $large_data_tests" >&5
+$as_echo "$large_data_tests" >&6; }
+RUN_LARGE_DATA_TESTS=$large_data_tests
+
+
+# Implementation of --enable-force-soft-hwfeatures
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether 'soft' HW feature bits are forced on" >&5
+$as_echo_n "checking whether 'soft' HW feature bits are forced on... " >&6; }
+# Check whether --enable-force-soft-hwfeatures was given.
+if test "${enable_force_soft_hwfeatures+set}" = set; then :
+ enableval=$enable_force_soft_hwfeatures; force_soft_hwfeatures=$enableval
+else
+ force_soft_hwfeatures=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $force_soft_hwfeatures" >&5
+$as_echo "$force_soft_hwfeatures" >&6; }
+
+
+# Implementation of the --with-capabilities switch.
+# Check whether we want to use Linux capabilities
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether use of capabilities is requested" >&5
+$as_echo_n "checking whether use of capabilities is requested... " >&6; }
+
+# Check whether --with-capabilities was given.
+if test "${with_capabilities+set}" = set; then :
+ withval=$with_capabilities; use_capabilities="$withval"
+else
+ use_capabilities=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_capabilities" >&5
+$as_echo "$use_capabilities" >&6; }
+
+# Implementation of the --enable-hmac-binary-check.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a HMAC binary check is requested" >&5
+$as_echo_n "checking whether a HMAC binary check is requested... " >&6; }
+# Check whether --enable-hmac-binary-check was given.
+if test "${enable_hmac_binary_check+set}" = set; then :
+ enableval=$enable_hmac_binary_check; use_hmac_binary_check=$enableval
+else
+ use_hmac_binary_check=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_hmac_binary_check" >&5
+$as_echo "$use_hmac_binary_check" >&6; }
+if test "$use_hmac_binary_check" = yes ; then
+
+$as_echo "#define ENABLE_HMAC_BINARY_CHECK 1" >>confdefs.h
+
+fi
+
+
+# Implementation of the --disable-jent-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether jitter entropy support is requested" >&5
+$as_echo_n "checking whether jitter entropy support is requested... " >&6; }
+# Check whether --enable-jent-support was given.
+if test "${enable_jent_support+set}" = set; then :
+ enableval=$enable_jent_support; jentsupport=$enableval
+else
+ jentsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $jentsupport" >&5
+$as_echo "$jentsupport" >&6; }
+
+# Implementation of the --disable-padlock-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether padlock support is requested" >&5
+$as_echo_n "checking whether padlock support is requested... " >&6; }
+# Check whether --enable-padlock-support was given.
+if test "${enable_padlock_support+set}" = set; then :
+ enableval=$enable_padlock_support; padlocksupport=$enableval
+else
+ padlocksupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $padlocksupport" >&5
+$as_echo "$padlocksupport" >&6; }
+
+# Implementation of the --disable-aesni-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether AESNI support is requested" >&5
+$as_echo_n "checking whether AESNI support is requested... " >&6; }
+# Check whether --enable-aesni-support was given.
+if test "${enable_aesni_support+set}" = set; then :
+ enableval=$enable_aesni_support; aesnisupport=$enableval
+else
+ aesnisupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $aesnisupport" >&5
+$as_echo "$aesnisupport" >&6; }
+
+# Implementation of the --disable-shaext-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SHAEXT support is requested" >&5
+$as_echo_n "checking whether SHAEXT support is requested... " >&6; }
+# Check whether --enable-shaext-support was given.
+if test "${enable_shaext_support+set}" = set; then :
+ enableval=$enable_shaext_support; shaextsupport=$enableval
+else
+ shaextsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $shaextsupport" >&5
+$as_echo "$shaextsupport" >&6; }
+
+# Implementation of the --disable-pclmul-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PCLMUL support is requested" >&5
+$as_echo_n "checking whether PCLMUL support is requested... " >&6; }
+# Check whether --enable-pclmul-support was given.
+if test "${enable_pclmul_support+set}" = set; then :
+ enableval=$enable_pclmul_support; pclmulsupport=$enableval
+else
+ pclmulsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pclmulsupport" >&5
+$as_echo "$pclmulsupport" >&6; }
+
+# Implementation of the --disable-sse41-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SSE4.1 support is requested" >&5
+$as_echo_n "checking whether SSE4.1 support is requested... " >&6; }
+# Check whether --enable-sse41-support was given.
+if test "${enable_sse41_support+set}" = set; then :
+ enableval=$enable_sse41_support; sse41support=$enableval
+else
+ sse41support=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sse41support" >&5
+$as_echo "$sse41support" >&6; }
+
+# Implementation of the --disable-drng-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether DRNG support is requested" >&5
+$as_echo_n "checking whether DRNG support is requested... " >&6; }
+# Check whether --enable-drng-support was given.
+if test "${enable_drng_support+set}" = set; then :
+ enableval=$enable_drng_support; drngsupport=$enableval
+else
+ drngsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $drngsupport" >&5
+$as_echo "$drngsupport" >&6; }
+
+# Implementation of the --disable-avx-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether AVX support is requested" >&5
+$as_echo_n "checking whether AVX support is requested... " >&6; }
+# Check whether --enable-avx-support was given.
+if test "${enable_avx_support+set}" = set; then :
+ enableval=$enable_avx_support; avxsupport=$enableval
+else
+ avxsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $avxsupport" >&5
+$as_echo "$avxsupport" >&6; }
+
+# Implementation of the --disable-avx2-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether AVX2 support is requested" >&5
+$as_echo_n "checking whether AVX2 support is requested... " >&6; }
+# Check whether --enable-avx2-support was given.
+if test "${enable_avx2_support+set}" = set; then :
+ enableval=$enable_avx2_support; avx2support=$enableval
+else
+ avx2support=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $avx2support" >&5
+$as_echo "$avx2support" >&6; }
+
+# Implementation of the --disable-neon-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NEON support is requested" >&5
+$as_echo_n "checking whether NEON support is requested... " >&6; }
+# Check whether --enable-neon-support was given.
+if test "${enable_neon_support+set}" = set; then :
+ enableval=$enable_neon_support; neonsupport=$enableval
+else
+ neonsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $neonsupport" >&5
+$as_echo "$neonsupport" >&6; }
+
+# Implementation of the --disable-arm-crypto-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ARMv8 Crypto Extension support is requested" >&5
+$as_echo_n "checking whether ARMv8 Crypto Extension support is requested... " >&6; }
+# Check whether --enable-arm-crypto-support was given.
+if test "${enable_arm_crypto_support+set}" = set; then :
+ enableval=$enable_arm_crypto_support; armcryptosupport=$enableval
+else
+ armcryptosupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $armcryptosupport" >&5
+$as_echo "$armcryptosupport" >&6; }
+
+# Implementation of the --disable-ppc-crypto-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PPC crypto support is requested" >&5
+$as_echo_n "checking whether PPC crypto support is requested... " >&6; }
+# Check whether --enable-ppc-crypto-support was given.
+if test "${enable_ppc_crypto_support+set}" = set; then :
+ enableval=$enable_ppc_crypto_support; ppccryptosupport=$enableval
+else
+ ppccryptosupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ppccryptosupport" >&5
+$as_echo "$ppccryptosupport" >&6; }
+
+# Implementation of the --disable-O-flag-munging switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a -O flag munging is requested" >&5
+$as_echo_n "checking whether a -O flag munging is requested... " >&6; }
+# Check whether --enable-O-flag-munging was given.
+if test "${enable_O_flag_munging+set}" = set; then :
+ enableval=$enable_O_flag_munging; enable_o_flag_munging=$enableval
+else
+ enable_o_flag_munging=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_o_flag_munging" >&5
+$as_echo "$enable_o_flag_munging" >&6; }
+ if test "$enable_o_flag_munging" = "yes"; then
+ ENABLE_O_FLAG_MUNGING_TRUE=
+ ENABLE_O_FLAG_MUNGING_FALSE='#'
+else
+ ENABLE_O_FLAG_MUNGING_TRUE='#'
+ ENABLE_O_FLAG_MUNGING_FALSE=
+fi
+
+
+# Implementation of the --disable-instrumentation-munging switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a instrumentation (-fprofile, -fsanitize) munging is requested" >&5
+$as_echo_n "checking whether a instrumentation (-fprofile, -fsanitize) munging is requested... " >&6; }
+# Check whether --enable-instrumentation-munging was given.
+if test "${enable_instrumentation_munging+set}" = set; then :
+ enableval=$enable_instrumentation_munging; enable_instrumentation_munging=$enableval
+else
+ enable_instrumentation_munging=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_instrumentation_munging" >&5
+$as_echo "$enable_instrumentation_munging" >&6; }
+ if test "$enable_instrumentation_munging" = "yes"; then
+ ENABLE_INSTRUMENTATION_MUNGING_TRUE=
+ ENABLE_INSTRUMENTATION_MUNGING_FALSE='#'
+else
+ ENABLE_INSTRUMENTATION_MUNGING_TRUE='#'
+ ENABLE_INSTRUMENTATION_MUNGING_FALSE=
+fi
+
+
+# Implementation of the --disable-amd64-as-feature-detection switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable AMD64 as(1) feature detection" >&5
+$as_echo_n "checking whether to enable AMD64 as(1) feature detection... " >&6; }
+# Check whether --enable-amd64-as-feature-detection was given.
+if test "${enable_amd64_as_feature_detection+set}" = set; then :
+ enableval=$enable_amd64_as_feature_detection; amd64_as_feature_detection=$enableval
+else
+ amd64_as_feature_detection=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $amd64_as_feature_detection" >&5
+$as_echo "$amd64_as_feature_detection" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define PRINTABLE_OS_NAME "$PRINTABLE_OS_NAME"
+_ACEOF
+
+
+# For some systems we know that we have ld_version scripts.
+# Use it then as default.
+have_ld_version_script=no
+case "${host}" in
+ *-*-linux*)
+ have_ld_version_script=yes
+ ;;
+ *-*-gnu*)
+ have_ld_version_script=yes
+ ;;
+esac
+# Check whether --enable-ld-version-script was given.
+if test "${enable_ld_version_script+set}" = set; then :
+ enableval=$enable_ld_version_script; have_ld_version_script=$enableval
+else
+ :
+fi
+
+ if test "$have_ld_version_script" = "yes"; then
+ HAVE_LD_VERSION_SCRIPT_TRUE=
+ HAVE_LD_VERSION_SCRIPT_FALSE='#'
+else
+ HAVE_LD_VERSION_SCRIPT_TRUE='#'
+ HAVE_LD_VERSION_SCRIPT_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define NAME_OF_DEV_RANDOM "$NAME_OF_DEV_RANDOM"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define NAME_OF_DEV_URANDOM "$NAME_OF_DEV_URANDOM"
+_ACEOF
+
+
+
+###############################
+#### Checks for libraries. ####
+###############################
+
+#
+# gpg-error is required.
+#
+
+ gpg_error_config_prefix=""
+
+# Check whether --with-libgpg-error-prefix was given.
+if test "${with_libgpg_error_prefix+set}" = set; then :
+ withval=$with_libgpg_error_prefix; gpg_error_config_prefix="$withval"
+fi
+
+
+
+# Check whether --with-gpg-error-prefix was given.
+if test "${with_gpg_error_prefix+set}" = set; then :
+ withval=$with_gpg_error_prefix; gpg_error_config_prefix="$withval"
+fi
+
+
+ if test x"${GPG_ERROR_CONFIG}" = x ; then
+ if test x"${gpg_error_config_prefix}" != x ; then
+ GPG_ERROR_CONFIG="${gpg_error_config_prefix}/bin/gpg-error-config"
+ else
+ case "${SYSROOT}" in
+ /*)
+ if test -x "${SYSROOT}/bin/gpg-error-config" ; then
+ GPG_ERROR_CONFIG="${SYSROOT}/bin/gpg-error-config"
+ fi
+ ;;
+ '')
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring \$SYSROOT as it is not an absolute path." >&5
+$as_echo "$as_me: WARNING: Ignoring \$SYSROOT as it is not an absolute path." >&2;}
+ ;;
+ esac
+ fi
+ fi
+
+ # Extract the first word of "gpg-error-config", so it can be a program name with args.
+set dummy gpg-error-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GPG_ERROR_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GPG_ERROR_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GPG_ERROR_CONFIG="$GPG_ERROR_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GPG_ERROR_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_GPG_ERROR_CONFIG" && ac_cv_path_GPG_ERROR_CONFIG="no"
+ ;;
+esac
+fi
+GPG_ERROR_CONFIG=$ac_cv_path_GPG_ERROR_CONFIG
+if test -n "$GPG_ERROR_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPG_ERROR_CONFIG" >&5
+$as_echo "$GPG_ERROR_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ min_gpg_error_version="$NEED_GPG_ERROR_VERSION"
+ ok=no
+
+ if test "$prefix" = NONE ; then
+ prefix_option_expanded=/usr/local
+ else
+ prefix_option_expanded="$prefix"
+ fi
+ if test "$exec_prefix" = NONE ; then
+ exec_prefix_option_expanded=$prefix_option_expanded
+ else
+ exec_prefix_option_expanded=$(prefix=$prefix_option_expanded eval echo $exec_prefix)
+ fi
+ libdir_option_expanded=$(prefix=$prefix_option_expanded exec_prefix=$exec_prefix_option_expanded eval echo $libdir)
+
+ if test -f $libdir_option_expanded/pkgconfig/gpg-error.pc; then
+ gpgrt_libdir=$libdir_option_expanded
+ else
+ if crt1_path=$(${CC:-cc} -print-file-name=crt1.o 2>/dev/null); then
+ if possible_libdir=$(cd ${crt1_path%/*} && pwd 2>/dev/null); then
+ if test -f $possible_libdir/pkgconfig/gpg-error.pc; then
+ gpgrt_libdir=$possible_libdir
+ fi
+ fi
+ fi
+ fi
+
+ if test "$GPG_ERROR_CONFIG" = "no" -a -n "$gpgrt_libdir"; then
+ # Extract the first word of "gpgrt-config", so it can be a program name with args.
+set dummy gpgrt-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GPGRT_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GPGRT_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GPGRT_CONFIG="$GPGRT_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GPGRT_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_GPGRT_CONFIG" && ac_cv_path_GPGRT_CONFIG="no"
+ ;;
+esac
+fi
+GPGRT_CONFIG=$ac_cv_path_GPGRT_CONFIG
+if test -n "$GPGRT_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPGRT_CONFIG" >&5
+$as_echo "$GPGRT_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$GPGRT_CONFIG" = "no"; then
+ unset GPGRT_CONFIG
+ else
+ GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir"
+ if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then
+ GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Use gpgrt-config with $gpgrt_libdir as gpg-error-config" >&5
+$as_echo "$as_me: Use gpgrt-config with $gpgrt_libdir as gpg-error-config" >&6;}
+ gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion`
+ else
+ unset GPGRT_CONFIG
+ fi
+ fi
+ else
+ gpg_error_config_version=`$GPG_ERROR_CONFIG --version`
+ fi
+ if test "$GPG_ERROR_CONFIG" != "no"; then
+ req_major=`echo $min_gpg_error_version | \
+ sed 's/\([0-9]*\)\.\([0-9]*\)/\1/'`
+ req_minor=`echo $min_gpg_error_version | \
+ sed 's/\([0-9]*\)\.\([0-9]*\)/\2/'`
+ major=`echo $gpg_error_config_version | \
+ sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'`
+ minor=`echo $gpg_error_config_version | \
+ sed 's/\([0-9]*\)\.\([0-9]*\).*/\2/'`
+ if test "$major" -gt "$req_major"; then
+ ok=yes
+ else
+ if test "$major" -eq "$req_major"; then
+ if test "$minor" -ge "$req_minor"; then
+ ok=yes
+ fi
+ fi
+ fi
+ if test -z "$GPGRT_CONFIG" -a -n "$gpgrt_libdir"; then
+ if test "$major" -gt 1 -o "$major" -eq 1 -a "$minor" -ge 33; then
+ # Extract the first word of "gpgrt-config", so it can be a program name with args.
+set dummy gpgrt-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GPGRT_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GPGRT_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GPGRT_CONFIG="$GPGRT_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GPGRT_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_GPGRT_CONFIG" && ac_cv_path_GPGRT_CONFIG="no"
+ ;;
+esac
+fi
+GPGRT_CONFIG=$ac_cv_path_GPGRT_CONFIG
+if test -n "$GPGRT_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPGRT_CONFIG" >&5
+$as_echo "$GPGRT_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$GPGRT_CONFIG" = "no"; then
+ unset GPGRT_CONFIG
+ else
+ GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir"
+ if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then
+ GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Use gpgrt-config with $gpgrt_libdir as gpg-error-config" >&5
+$as_echo "$as_me: Use gpgrt-config with $gpgrt_libdir as gpg-error-config" >&6;}
+ else
+ unset GPGRT_CONFIG
+ fi
+ fi
+ fi
+ fi
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GPG Error - version >= $min_gpg_error_version" >&5
+$as_echo_n "checking for GPG Error - version >= $min_gpg_error_version... " >&6; }
+ if test $ok = yes; then
+ GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG --cflags`
+ GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG --libs`
+ if test -z "$GPGRT_CONFIG"; then
+ GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --mt --cflags 2>/dev/null`
+ GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --mt --libs 2>/dev/null`
+ else
+ GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --variable=mtcflags 2>/dev/null`
+ GPG_ERROR_MT_CFLAGS="$GPG_ERROR_CFLAGS${GPG_ERROR_CFLAGS:+ }$GPG_ERROR_MT_CFLAGS"
+ GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --variable=mtlibs 2>/dev/null`
+ GPG_ERROR_MT_LIBS="$GPG_ERROR_LIBS${GPG_ERROR_LIBS:+ }$GPG_ERROR_MT_LIBS"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($gpg_error_config_version)" >&5
+$as_echo "yes ($gpg_error_config_version)" >&6; }
+ :
+ if test -z "$GPGRT_CONFIG"; then
+ gpg_error_config_host=`$GPG_ERROR_CONFIG --host 2>/dev/null || echo none`
+ else
+ gpg_error_config_host=`$GPG_ERROR_CONFIG --variable=host 2>/dev/null || echo none`
+ fi
+ if test x"$gpg_error_config_host" != xnone ; then
+ if test x"$gpg_error_config_host" != x"$host" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+***
+*** The config script \"$GPG_ERROR_CONFIG\" was
+*** built for $gpg_error_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-libgpg-error-prefix
+*** to specify a matching config script or use \$SYSROOT.
+***" >&5
+$as_echo "$as_me: WARNING:
+***
+*** The config script \"$GPG_ERROR_CONFIG\" was
+*** built for $gpg_error_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-libgpg-error-prefix
+*** to specify a matching config script or use \$SYSROOT.
+***" >&2;}
+ gpg_config_script_warn="$gpg_config_script_warn libgpg-error"
+ fi
+ fi
+ else
+ GPG_ERROR_CFLAGS=""
+ GPG_ERROR_LIBS=""
+ GPG_ERROR_MT_CFLAGS=""
+ GPG_ERROR_MT_LIBS=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ :
+ fi
+
+
+
+
+
+if test "x$GPG_ERROR_LIBS" = "x"; then
+ as_fn_error $? "libgpg-error is needed.
+ See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ ." "$LINENO" 5
+fi
+
+
+$as_echo "#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT" >>confdefs.h
+
+
+#
+# Check whether the GNU Pth library is available. We require this
+# to build the optional gcryptrnd program.
+#
+
+# Check whether --with-pth-prefix was given.
+if test "${with_pth_prefix+set}" = set; then :
+ withval=$with_pth_prefix; pth_config_prefix="$withval"
+else
+ pth_config_prefix=""
+fi
+
+if test x$pth_config_prefix != x ; then
+ PTH_CONFIG="$pth_config_prefix/bin/pth-config"
+fi
+if test "$use_random_daemon" = "yes"; then
+ # Extract the first word of "pth-config", so it can be a program name with args.
+set dummy pth-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PTH_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PTH_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PTH_CONFIG="$PTH_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PTH_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PTH_CONFIG" && ac_cv_path_PTH_CONFIG="no"
+ ;;
+esac
+fi
+PTH_CONFIG=$ac_cv_path_PTH_CONFIG
+if test -n "$PTH_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTH_CONFIG" >&5
+$as_echo "$PTH_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$PTH_CONFIG" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+***
+*** To build the Libgcrypt's random number daemon
+*** we need the support of the GNU Portable Threads Library.
+*** Download it from ftp://ftp.gnu.org/gnu/pth/
+*** On a Debian GNU/Linux system you might want to try
+*** apt-get install libpth-dev
+***" >&5
+$as_echo "$as_me: WARNING:
+***
+*** To build the Libgcrypt's random number daemon
+*** we need the support of the GNU Portable Threads Library.
+*** Download it from ftp://ftp.gnu.org/gnu/pth/
+*** On a Debian GNU/Linux system you might want to try
+*** apt-get install libpth-dev
+***" >&2;}
+ else
+
+ _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print $3}'`
+ _req_version="1.3.7"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTH - version >= $_req_version" >&5
+$as_echo_n "checking for PTH - version >= $_req_version... " >&6; }
+ for _var in _pth_version _req_version; do
+ eval "_val=\"\$${_var}\""
+ _major=`echo $_val | sed 's/\([0-9]*\)\.\([0-9]*\)\([ab.]\)\([0-9]*\)/\1/'`
+ _minor=`echo $_val | sed 's/\([0-9]*\)\.\([0-9]*\)\([ab.]\)\([0-9]*\)/\2/'`
+ _rtype=`echo $_val | sed 's/\([0-9]*\)\.\([0-9]*\)\([ab.]\)\([0-9]*\)/\3/'`
+ _micro=`echo $_val | sed 's/\([0-9]*\)\.\([0-9]*\)\([ab.]\)\([0-9]*\)/\4/'`
+ case $_rtype in
+ "a" ) _rtype=0 ;;
+ "b" ) _rtype=1 ;;
+ "." ) _rtype=2 ;;
+ esac
+ _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \
+ "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"`
+ eval "${_var}_hex=\"\$_hex\""
+ done
+ have_pth=no
+ if test ".$_pth_version_hex" != .; then
+ if test ".$_req_version_hex" != .; then
+ if test $_pth_version_hex -ge $_req_version_hex; then
+ have_pth=yes
+ fi
+ fi
+ fi
+ if test $have_pth = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PTH installation is sane" >&5
+$as_echo_n "checking whether PTH installation is sane... " >&6; }
+ if ${gnupg_cv_pth_is_sane+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ _gnupg_pth_save_cflags=$CFLAGS
+ _gnupg_pth_save_ldflags=$LDFLAGS
+ _gnupg_pth_save_libs=$LIBS
+ CFLAGS="$CFLAGS `$PTH_CONFIG --cflags`"
+ LDFLAGS="$LDFLAGS `$PTH_CONFIG --ldflags`"
+ LIBS="$LIBS `$PTH_CONFIG --libs`"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pth.h>
+
+int
+main ()
+{
+ pth_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gnupg_cv_pth_is_sane=yes
+else
+ gnupg_cv_pth_is_sane=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS=$_gnupg_pth_save_cflags
+ LDFLAGS=$_gnupg_pth_save_ldflags
+ LIBS=$_gnupg_pth_save_libs
+
+fi
+
+ if test $gnupg_cv_pth_is_sane != yes; then
+ have_pth=no
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_pth_is_sane" >&5
+$as_echo "$gnupg_cv_pth_is_sane" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+ if test $have_pth = yes; then
+ PTH_CFLAGS=`$PTH_CONFIG --cflags`
+ PTH_LIBS=`$PTH_CONFIG --ldflags`
+ PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs --all`"
+
+$as_echo "#define USE_GNU_PTH 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PTH 1" >>confdefs.h
+
+ fi
+ fi
+fi
+
+
+
+#
+# Check whether pthreads is available
+#
+if test "$have_w32_system" != yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5
+$as_echo_n "checking for pthread_create in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_pthread_create+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_create ();
+int
+main ()
+{
+return pthread_create ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_create=yes
+else
+ ac_cv_lib_pthread_pthread_create=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then :
+ have_pthread=yes
+fi
+
+ if test "$have_pthread" = yes; then
+
+$as_echo "#define HAVE_PTHREAD 1 " >>confdefs.h
+
+ fi
+fi
+
+
+# Solaris needs -lsocket and -lnsl. Unisys system includes
+# gethostbyname in libsocket but needs libnsl for socket.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if ${ac_cv_search_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_setsockopt+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_setsockopt+:} false; then :
+
+else
+ ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if ${ac_cv_search_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib -lnsl $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_setsockopt+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_setsockopt+:} false; then :
+
+else
+ ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if ${ac_cv_search_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_setsockopt+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_setsockopt+:} false; then :
+
+else
+ ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+##################################
+#### Checks for header files. ####
+##################################
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+for ac_header in unistd.h sys/select.h sys/msg.h sys/auxv.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+INSERT_SYS_SELECT_H=
+if test x"$ac_cv_header_sys_select_h" = xyes; then
+ INSERT_SYS_SELECT_H=" include <sys/select.h>"
+fi
+
+
+
+##########################################
+#### Checks for typedefs, structures, ####
+#### and compiler characteristics. ####
+##########################################
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this sort of thing. */
+ typedef int charset[2];
+ const charset cs = { 0, 0 };
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+
+ac_fn_c_check_type "$LINENO" "byte" "ac_cv_type_byte" "$ac_includes_default"
+if test "x$ac_cv_type_byte" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_BYTE 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "ushort" "ac_cv_type_ushort" "$ac_includes_default"
+if test "x$ac_cv_type_ushort" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_USHORT 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "u16" "ac_cv_type_u16" "$ac_includes_default"
+if test "x$ac_cv_type_u16" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_U16 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "u32" "ac_cv_type_u32" "$ac_includes_default"
+if test "x$ac_cv_type_u32" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_U32 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "u64" "ac_cv_type_u64" "$ac_includes_default"
+if test "x$ac_cv_type_u64" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_U64 1
+_ACEOF
+
+
+fi
+
+
+
+
+
+ for ac_header in $ac_header_list
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+ if test $ac_cv_header_sys_socket_h = no; then
+ for ac_header in ws2tcpip.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "ws2tcpip.h" "ac_cv_header_ws2tcpip_h" "$ac_includes_default"
+if test "x$ac_cv_header_ws2tcpip_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_WS2TCPIP_H 1
+_ACEOF
+
+fi
+
+done
+
+ fi
+
+ ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "
+/* <sys/types.h> is not needed according to POSIX, but the
+ <sys/socket.h> in i386-unknown-freebsd4.10 and
+ powerpc-apple-darwin5.5 required it. */
+#include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#elif HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+#endif
+
+"
+if test "x$ac_cv_type_socklen_t" = xyes; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5
+$as_echo_n "checking for socklen_t equivalent... " >&6; }
+if ${gl_cv_socklen_t_equiv+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ gl_cv_socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t "unsigned int" "long int" "unsigned long int"; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+int
+main ()
+{
+$t len;
+ getpeername (0, 0, &len);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gl_cv_socklen_t_equiv="$t"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$gl_cv_socklen_t_equiv" != "" && break
+ done
+ test "$gl_cv_socklen_t_equiv" != "" && break
+ done
+ if test "$gl_cv_socklen_t_equiv" = ""; then
+ as_fn_error $? "Cannot find a type to use in place of socklen_t" "$LINENO" 5
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_socklen_t_equiv" >&5
+$as_echo "$gl_cv_socklen_t_equiv" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define socklen_t $gl_cv_socklen_t_equiv
+_ACEOF
+
+fi
+
+case "${host}" in
+ *-*-mingw32*)
+ # socklen_t may or may not be defined depending on what headers
+ # are included. To be safe we use int as this is the actual type.
+ FALLBACK_SOCKLEN_T="typedef int gcry_socklen_t;"
+ ;;
+ *)
+ if test ".$gl_cv_socklen_t_equiv" = "."; then
+ FALLBACK_SOCKLEN_T="typedef socklen_t gcry_socklen_t;"
+ else
+ FALLBACK_SOCKLEN_T="typedef ${gl_cv_socklen_t_equiv} gcry_socklen_t;"
+ fi
+esac
+
+
+
+#
+# Check for __builtin_bswap32 intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5
+$as_echo_n "checking for __builtin_bswap32... " >&6; }
+if ${gcry_cv_have_builtin_bswap32+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_builtin_bswap32=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+int x = 0; int y = __builtin_bswap32(x); return y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_have_builtin_bswap32=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_builtin_bswap32" >&5
+$as_echo "$gcry_cv_have_builtin_bswap32" >&6; }
+if test "$gcry_cv_have_builtin_bswap32" = "yes" ; then
+
+$as_echo "#define HAVE_BUILTIN_BSWAP32 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for __builtin_bswap64 intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap64" >&5
+$as_echo_n "checking for __builtin_bswap64... " >&6; }
+if ${gcry_cv_have_builtin_bswap64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_builtin_bswap64=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+long long x = 0; long long y = __builtin_bswap64(x); return y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_have_builtin_bswap64=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_builtin_bswap64" >&5
+$as_echo "$gcry_cv_have_builtin_bswap64" >&6; }
+if test "$gcry_cv_have_builtin_bswap64" = "yes" ; then
+
+$as_echo "#define HAVE_BUILTIN_BSWAP64 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for __builtin_ctz intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_ctz" >&5
+$as_echo_n "checking for __builtin_ctz... " >&6; }
+if ${gcry_cv_have_builtin_ctz+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_builtin_ctz=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+unsigned int x = 0; int y = __builtin_ctz(x); return y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_have_builtin_ctz=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_builtin_ctz" >&5
+$as_echo "$gcry_cv_have_builtin_ctz" >&6; }
+if test "$gcry_cv_have_builtin_ctz" = "yes" ; then
+
+$as_echo "#define HAVE_BUILTIN_CTZ 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for __builtin_ctzl intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_ctzl" >&5
+$as_echo_n "checking for __builtin_ctzl... " >&6; }
+if ${gcry_cv_have_builtin_ctzl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_builtin_ctzl=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+unsigned long x = 0; long y = __builtin_ctzl(x); return y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_have_builtin_ctzl=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_builtin_ctzl" >&5
+$as_echo "$gcry_cv_have_builtin_ctzl" >&6; }
+if test "$gcry_cv_have_builtin_ctzl" = "yes" ; then
+
+$as_echo "#define HAVE_BUILTIN_CTZL 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for __builtin_clz intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clz" >&5
+$as_echo_n "checking for __builtin_clz... " >&6; }
+if ${gcry_cv_have_builtin_clz+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_builtin_clz=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+unsigned int x = 0; int y = __builtin_clz(x); return y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_have_builtin_clz=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_builtin_clz" >&5
+$as_echo "$gcry_cv_have_builtin_clz" >&6; }
+if test "$gcry_cv_have_builtin_clz" = "yes" ; then
+
+$as_echo "#define HAVE_BUILTIN_CLZ 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for __builtin_clzl intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clzl" >&5
+$as_echo_n "checking for __builtin_clzl... " >&6; }
+if ${gcry_cv_have_builtin_clzl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_builtin_clzl=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+unsigned long x = 0; long y = __builtin_clzl(x); return y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_have_builtin_clzl=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_builtin_clzl" >&5
+$as_echo "$gcry_cv_have_builtin_clzl" >&6; }
+if test "$gcry_cv_have_builtin_clzl" = "yes" ; then
+
+$as_echo "#define HAVE_BUILTIN_CLZL 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for __sync_synchronize intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __sync_synchronize" >&5
+$as_echo_n "checking for __sync_synchronize... " >&6; }
+if ${gcry_cv_have_sync_synchronize+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_sync_synchronize=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+__sync_synchronize(); return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_have_sync_synchronize=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_sync_synchronize" >&5
+$as_echo "$gcry_cv_have_sync_synchronize" >&6; }
+if test "$gcry_cv_have_sync_synchronize" = "yes" ; then
+
+$as_echo "#define HAVE_SYNC_SYNCHRONIZE 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for VLA support (variable length arrays).
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the variable length arrays are supported" >&5
+$as_echo_n "checking whether the variable length arrays are supported... " >&6; }
+if ${gcry_cv_have_vla+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_vla=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void f1(char *, int);
+ char foo(int i) {
+ char b[(i < 0 ? 0 : i) + 1];
+ f1(b, sizeof b); return b[0];}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_have_vla=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_vla" >&5
+$as_echo "$gcry_cv_have_vla" >&6; }
+if test "$gcry_cv_have_vla" = "yes" ; then
+
+$as_echo "#define HAVE_VLA 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for ELF visibility support.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the visibility attribute is supported" >&5
+$as_echo_n "checking whether the visibility attribute is supported... " >&6; }
+if ${gcry_cv_visibility_attribute+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_visibility_attribute=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo __attribute__ ((visibility ("hidden"))) = 1;
+ int bar __attribute__ ((visibility ("protected"))) = 1;
+
+_ACEOF
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&5 2>&5 ; then
+ if grep '\.hidden.*foo' conftest.s >/dev/null 2>&1 ; then
+ if grep '\.protected.*bar' conftest.s >/dev/null 2>&1; then
+ gcry_cv_visibility_attribute=yes
+ fi
+ fi
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_visibility_attribute" >&5
+$as_echo "$gcry_cv_visibility_attribute" >&6; }
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken visibility attribute" >&5
+$as_echo_n "checking for broken visibility attribute... " >&6; }
+if ${gcry_cv_broken_visibility_attribute+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_broken_visibility_attribute=yes
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (int x);
+ int bar (int x) __asm__ ("foo")
+ __attribute__ ((visibility ("hidden")));
+ int bar (int x) { return x; }
+
+_ACEOF
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&5 2>&5 ; then
+ if grep '\.hidden[ _]foo' conftest.s >/dev/null 2>&1;
+ then
+ gcry_cv_broken_visibility_attribute=no
+ fi
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_broken_visibility_attribute" >&5
+$as_echo "$gcry_cv_broken_visibility_attribute" >&6; }
+fi
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken alias attribute" >&5
+$as_echo_n "checking for broken alias attribute... " >&6; }
+if ${gcry_cv_broken_alias_attribute+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_broken_alias_attribute=yes
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+extern int foo (int x) __asm ("xyzzy");
+ int bar (int x) { return x; }
+ extern __typeof (bar) foo __attribute ((weak, alias ("bar")));
+ extern int dfoo;
+ extern __typeof (dfoo) dfoo __asm ("abccb");
+ int dfoo = 1;
+
+_ACEOF
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&5 2>&5 ; then
+ if grep 'xyzzy' conftest.s >/dev/null 2>&1 && \
+ grep 'abccb' conftest.s >/dev/null 2>&1; then
+ gcry_cv_broken_alias_attribute=no
+ fi
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_broken_alias_attribute" >&5
+$as_echo "$gcry_cv_broken_alias_attribute" >&6; }
+fi
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -fvisibility=hidden" >&5
+$as_echo_n "checking if gcc supports -fvisibility=hidden... " >&6; }
+if ${gcry_cv_gcc_has_f_visibility+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_has_f_visibility=no
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-fvisibility=hidden"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_has_f_visibility=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$_gcc_cflags_save;
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_has_f_visibility" >&5
+$as_echo "$gcry_cv_gcc_has_f_visibility" >&6; }
+fi
+if test "$gcry_cv_visibility_attribute" = "yes" \
+ && test "$gcry_cv_broken_visibility_attribute" != "yes" \
+ && test "$gcry_cv_broken_alias_attribute" != "yes" \
+ && test "$gcry_cv_gcc_has_f_visibility" = "yes"
+ then
+
+$as_echo "#define GCRY_USE_VISIBILITY 1" >>confdefs.h
+
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+fi
+
+
+# Following attribute tests depend on warnings to cause compile to fail,
+# so set -Werror temporarily.
+_gcc_cflags_save=$CFLAGS
+CFLAGS="$CFLAGS -Werror"
+
+
+#
+# Check whether the compiler supports the GCC style aligned attribute
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the GCC style aligned attribute is supported" >&5
+$as_echo_n "checking whether the GCC style aligned attribute is supported... " >&6; }
+if ${gcry_cv_gcc_attribute_aligned+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_attribute_aligned=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+struct { int a; } foo __attribute__ ((aligned (16)));
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_attribute_aligned=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_aligned" >&5
+$as_echo "$gcry_cv_gcc_attribute_aligned" >&6; }
+if test "$gcry_cv_gcc_attribute_aligned" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ATTRIBUTE_ALIGNED 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether the compiler supports the GCC style packed attribute
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the GCC style packed attribute is supported" >&5
+$as_echo_n "checking whether the GCC style packed attribute is supported... " >&6; }
+if ${gcry_cv_gcc_attribute_packed+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_attribute_packed=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+struct foolong_s { long b; } __attribute__ ((packed));
+ struct foo_s { char a; struct foolong_s b; }
+ __attribute__ ((packed));
+ enum bar {
+ FOO = 1 / (sizeof(struct foo_s) == (sizeof(char) + sizeof(long))),
+ };
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_attribute_packed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_packed" >&5
+$as_echo "$gcry_cv_gcc_attribute_packed" >&6; }
+if test "$gcry_cv_gcc_attribute_packed" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ATTRIBUTE_PACKED 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether the compiler supports the GCC style may_alias attribute
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the GCC style may_alias attribute is supported" >&5
+$as_echo_n "checking whether the GCC style may_alias attribute is supported... " >&6; }
+if ${gcry_cv_gcc_attribute_may_alias+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_attribute_may_alias=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+typedef struct foo_s { int a; }
+ __attribute__ ((may_alias)) foo_t;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_attribute_may_alias=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_may_alias" >&5
+$as_echo "$gcry_cv_gcc_attribute_may_alias" >&6; }
+if test "$gcry_cv_gcc_attribute_may_alias" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ATTRIBUTE_MAY_ALIAS 1" >>confdefs.h
+
+fi
+
+
+# Restore flags.
+CFLAGS=$_gcc_cflags_save;
+
+
+#
+# Check whether the compiler supports 'asm' or '__asm__' keyword for
+# assembler blocks.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether 'asm' assembler keyword is supported" >&5
+$as_echo_n "checking whether 'asm' assembler keyword is supported... " >&6; }
+if ${gcry_cv_have_asm+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_asm=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(void) { asm("":::"memory"); }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_have_asm=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_asm" >&5
+$as_echo "$gcry_cv_have_asm" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether '__asm__' assembler keyword is supported" >&5
+$as_echo_n "checking whether '__asm__' assembler keyword is supported... " >&6; }
+if ${gcry_cv_have___asm__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have___asm__=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(void) { __asm__("":::"memory"); }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_have___asm__=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have___asm__" >&5
+$as_echo "$gcry_cv_have___asm__" >&6; }
+if test "$gcry_cv_have_asm" = "no" ; then
+ if test "$gcry_cv_have___asm__" = "yes" ; then
+
+$as_echo "#define asm __asm__" >>confdefs.h
+
+ fi
+fi
+
+
+#
+# Check whether the compiler supports inline assembly memory barrier.
+#
+if test "$gcry_cv_have_asm" = "no" ; then
+ if test "$gcry_cv_have___asm__" = "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inline assembly memory barrier is supported" >&5
+$as_echo_n "checking whether inline assembly memory barrier is supported... " >&6; }
+if ${gcry_cv_have_asm_volatile_memory+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_asm_volatile_memory=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(int x)
+ {
+ __asm__ volatile("":::"memory");
+ __asm__ volatile("":"+r"(x)::"memory");
+ }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_have_asm_volatile_memory=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_asm_volatile_memory" >&5
+$as_echo "$gcry_cv_have_asm_volatile_memory" >&6; }
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inline assembly memory barrier is supported" >&5
+$as_echo_n "checking whether inline assembly memory barrier is supported... " >&6; }
+if ${gcry_cv_have_asm_volatile_memory+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_have_asm_volatile_memory=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(int x)
+ {
+ asm volatile("":::"memory");
+ asm volatile("":"+r"(x)::"memory"); }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_have_asm_volatile_memory=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_asm_volatile_memory" >&5
+$as_echo "$gcry_cv_have_asm_volatile_memory" >&6; }
+fi
+if test "$gcry_cv_have_asm_volatile_memory" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ASM_VOLATILE_MEMORY 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for our ARM
+# implementations. This needs to be done before setting up the
+# assembler stuff.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for ARM assembly implementations" >&5
+$as_echo_n "checking whether GCC assembler is compatible for ARM assembly implementations... " >&6; }
+if ${gcry_cv_gcc_arm_platform_as_ok+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_arm_platform_as_ok="n/a"
+ else
+ gcry_cv_gcc_arm_platform_as_ok=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ /* Test if assembler supports UAL syntax. */
+ ".syntax unified\n\t"
+ ".arm\n\t" /* our assembly code is in ARM mode */
+ ".text\n\t"
+ /* Following causes error if assembler ignored '.syntax unified'. */
+ "asmfunc:\n\t"
+ "add %r0, %r0, %r4, ror #12;\n\t"
+
+ /* Test if '.type' and '.size' are supported. */
+ ".size asmfunc,.-asmfunc;\n\t"
+ ".type asmfunc,%function;\n\t"
+ );
+int
+main ()
+{
+ asmfunc();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_arm_platform_as_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_arm_platform_as_ok" >&5
+$as_echo "$gcry_cv_gcc_arm_platform_as_ok" >&6; }
+if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then
+
+$as_echo "#define HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for our ARMv8/Aarch64
+# implementations. This needs to be done before setting up the
+# assembler stuff.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for ARMv8/Aarch64 assembly implementations" >&5
+$as_echo_n "checking whether GCC assembler is compatible for ARMv8/Aarch64 assembly implementations... " >&6; }
+if ${gcry_cv_gcc_aarch64_platform_as_ok+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_aarch64_platform_as_ok="n/a"
+ else
+ gcry_cv_gcc_aarch64_platform_as_ok=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ ".text\n\t"
+ "asmfunc:\n\t"
+ "eor x0, x0, x30, ror #12;\n\t"
+ "add x0, x0, x30, asr #12;\n\t"
+ "eor v0.16b, v0.16b, v31.16b;\n\t"
+ );
+int
+main ()
+{
+ asmfunc();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_aarch64_platform_as_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_aarch64_platform_as_ok" >&5
+$as_echo "$gcry_cv_gcc_aarch64_platform_as_ok" >&6; }
+if test "$gcry_cv_gcc_aarch64_platform_as_ok" = "yes" ; then
+
+$as_echo "#define HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS 1" >>confdefs.h
+
+fi
+
+#
+# Check whether GCC assembler supports for CFI directives.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler supports for CFI directives" >&5
+$as_echo_n "checking whether GCC assembler supports for CFI directives... " >&6; }
+if ${gcry_cv_gcc_asm_cfi_directives+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_asm_cfi_directives=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ ".text\n\t"
+ "ac_test:\n\t"
+ ".cfi_startproc\n\t"
+ ".cfi_remember_state\n\t"
+ ".cfi_adjust_cfa_offset 8\n\t"
+ ".cfi_rel_offset 0, 8\n\t"
+ ".cfi_def_cfa_register 1\n\t"
+ ".cfi_register 2, 3\n\t"
+ ".cfi_restore 2\n\t"
+ ".cfi_escape 0x0f, 0x02, 0x11, 0x00\n\t"
+ ".cfi_restore_state\n\t"
+ ".long 0\n\t"
+ ".cfi_endproc\n\t"
+ );
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_asm_cfi_directives=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_asm_cfi_directives" >&5
+$as_echo "$gcry_cv_gcc_asm_cfi_directives" >&6; }
+if test "$gcry_cv_gcc_asm_cfi_directives" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ASM_CFI_DIRECTIVES 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC assembler supports for ELF directives.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler supports for ELF directives" >&5
+$as_echo_n "checking whether GCC assembler supports for ELF directives... " >&6; }
+if ${gcry_cv_gcc_asm_elf_directives+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_asm_elf_directives=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ /* Test if ELF directives '.type' and '.size' are supported. */
+ ".text\n\t"
+ "asmfunc:\n\t"
+ ".size asmfunc,.-asmfunc;\n\t"
+ ".type asmfunc,STT_FUNC;\n\t"
+ );
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_asm_elf_directives=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_asm_elf_directives" >&5
+$as_echo "$gcry_cv_gcc_asm_elf_directives" >&6; }
+if test "$gcry_cv_gcc_asm_elf_directives" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ASM_ELF_DIRECTIVES 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether underscores in symbols are required. This needs to be
+# done before setting up the assembler stuff.
+#
+
+tmp_do_check="no"
+case "${host}" in
+ i?86-mingw32* | i?86-*-mingw32*)
+ ac_cv_sys_symbol_underscore=yes
+ ;;
+ x86_64-*-mingw32*)
+ ac_cv_sys_symbol_underscore=no
+ ;;
+ i386-emx-os2 | i345686-pc-os2*emx | i386-pc-msdosdjgpp)
+ ac_cv_sys_symbol_underscore=yes
+ ;;
+ *)
+ if test "$cross_compiling" != yes; then
+ tmp_do_check="yes"
+ fi
+ ;;
+esac
+if test "$tmp_do_check" = "yes"; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
+$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
+ if ${ac_cv_sys_symbol_underscore+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_symbol_underscore=no
+ cat > conftest.$ac_ext <<EOF
+ void nm_test_func(){}
+ int main(){nm_test_func;return 0;}
+EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ fi
+ else
+ echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -rf conftest*
+
+fi
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
+$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
+ fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_symbol_underscore" >&5
+$as_echo "$ac_cv_sys_symbol_underscore" >&6; }
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+
+$as_echo "#define WITH_SYMBOL_UNDERSCORE 1" >>confdefs.h
+
+fi
+
+
+
+#################################
+#### ####
+#### Setup assembler stuff. ####
+#### Define mpi_cpu_arch. ####
+#### ####
+#################################
+# Check whether --enable-mpi-path was given.
+if test "${enable_mpi_path+set}" = set; then :
+ enableval=$enable_mpi_path; mpi_extra_path="$enableval"
+else
+ mpi_extra_path=""
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking architecture and mpi assembler functions" >&5
+$as_echo_n "checking architecture and mpi assembler functions... " >&6; }
+if test -f $srcdir/mpi/config.links ; then
+ . $srcdir/mpi/config.links
+ ac_config_links="$ac_config_links "$mpi_ln_list""
+
+ ac_cv_mpi_sflags="$mpi_sflags"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpi_cpu_arch" >&5
+$as_echo "$mpi_cpu_arch" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+ as_fn_error $? "mpi/config.links missing!" "$LINENO" 5
+fi
+MPI_SFLAGS="$ac_cv_mpi_sflags"
+
+
+ if test "$mpi_mod_asm_mpih_add1" = yes; then
+ MPI_MOD_ASM_MPIH_ADD1_TRUE=
+ MPI_MOD_ASM_MPIH_ADD1_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_ADD1_TRUE='#'
+ MPI_MOD_ASM_MPIH_ADD1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_sub1" = yes; then
+ MPI_MOD_ASM_MPIH_SUB1_TRUE=
+ MPI_MOD_ASM_MPIH_SUB1_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_SUB1_TRUE='#'
+ MPI_MOD_ASM_MPIH_SUB1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul1" = yes; then
+ MPI_MOD_ASM_MPIH_MUL1_TRUE=
+ MPI_MOD_ASM_MPIH_MUL1_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_MUL1_TRUE='#'
+ MPI_MOD_ASM_MPIH_MUL1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul2" = yes; then
+ MPI_MOD_ASM_MPIH_MUL2_TRUE=
+ MPI_MOD_ASM_MPIH_MUL2_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_MUL2_TRUE='#'
+ MPI_MOD_ASM_MPIH_MUL2_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul3" = yes; then
+ MPI_MOD_ASM_MPIH_MUL3_TRUE=
+ MPI_MOD_ASM_MPIH_MUL3_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_MUL3_TRUE='#'
+ MPI_MOD_ASM_MPIH_MUL3_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_lshift" = yes; then
+ MPI_MOD_ASM_MPIH_LSHIFT_TRUE=
+ MPI_MOD_ASM_MPIH_LSHIFT_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_LSHIFT_TRUE='#'
+ MPI_MOD_ASM_MPIH_LSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_rshift" = yes; then
+ MPI_MOD_ASM_MPIH_RSHIFT_TRUE=
+ MPI_MOD_ASM_MPIH_RSHIFT_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_RSHIFT_TRUE='#'
+ MPI_MOD_ASM_MPIH_RSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_asm_udiv" = yes; then
+ MPI_MOD_ASM_UDIV_TRUE=
+ MPI_MOD_ASM_UDIV_FALSE='#'
+else
+ MPI_MOD_ASM_UDIV_TRUE='#'
+ MPI_MOD_ASM_UDIV_FALSE=
+fi
+
+ if test "$mpi_mod_asm_udiv_qrnnd" = yes; then
+ MPI_MOD_ASM_UDIV_QRNND_TRUE=
+ MPI_MOD_ASM_UDIV_QRNND_FALSE='#'
+else
+ MPI_MOD_ASM_UDIV_QRNND_TRUE='#'
+ MPI_MOD_ASM_UDIV_QRNND_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_add1" = yes; then
+ MPI_MOD_C_MPIH_ADD1_TRUE=
+ MPI_MOD_C_MPIH_ADD1_FALSE='#'
+else
+ MPI_MOD_C_MPIH_ADD1_TRUE='#'
+ MPI_MOD_C_MPIH_ADD1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_sub1" = yes; then
+ MPI_MOD_C_MPIH_SUB1_TRUE=
+ MPI_MOD_C_MPIH_SUB1_FALSE='#'
+else
+ MPI_MOD_C_MPIH_SUB1_TRUE='#'
+ MPI_MOD_C_MPIH_SUB1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul1" = yes; then
+ MPI_MOD_C_MPIH_MUL1_TRUE=
+ MPI_MOD_C_MPIH_MUL1_FALSE='#'
+else
+ MPI_MOD_C_MPIH_MUL1_TRUE='#'
+ MPI_MOD_C_MPIH_MUL1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul2" = yes; then
+ MPI_MOD_C_MPIH_MUL2_TRUE=
+ MPI_MOD_C_MPIH_MUL2_FALSE='#'
+else
+ MPI_MOD_C_MPIH_MUL2_TRUE='#'
+ MPI_MOD_C_MPIH_MUL2_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul3" = yes; then
+ MPI_MOD_C_MPIH_MUL3_TRUE=
+ MPI_MOD_C_MPIH_MUL3_FALSE='#'
+else
+ MPI_MOD_C_MPIH_MUL3_TRUE='#'
+ MPI_MOD_C_MPIH_MUL3_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_lshift" = yes; then
+ MPI_MOD_C_MPIH_LSHIFT_TRUE=
+ MPI_MOD_C_MPIH_LSHIFT_FALSE='#'
+else
+ MPI_MOD_C_MPIH_LSHIFT_TRUE='#'
+ MPI_MOD_C_MPIH_LSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_rshift" = yes; then
+ MPI_MOD_C_MPIH_RSHIFT_TRUE=
+ MPI_MOD_C_MPIH_RSHIFT_FALSE='#'
+else
+ MPI_MOD_C_MPIH_RSHIFT_TRUE='#'
+ MPI_MOD_C_MPIH_RSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_c_udiv" = yes; then
+ MPI_MOD_C_UDIV_TRUE=
+ MPI_MOD_C_UDIV_FALSE='#'
+else
+ MPI_MOD_C_UDIV_TRUE='#'
+ MPI_MOD_C_UDIV_FALSE=
+fi
+
+ if test "$mpi_mod_c_udiv_qrnnd" = yes; then
+ MPI_MOD_C_UDIV_QRNND_TRUE=
+ MPI_MOD_C_UDIV_QRNND_FALSE='#'
+else
+ MPI_MOD_C_UDIV_QRNND_TRUE='#'
+ MPI_MOD_C_UDIV_QRNND_FALSE=
+fi
+
+
+# Reset non applicable feature flags.
+if test "$mpi_cpu_arch" != "x86" ; then
+ aesnisupport="n/a"
+ shaextsupport="n/a"
+ pclmulsupport="n/a"
+ sse41support="n/a"
+ avxsupport="n/a"
+ avx2support="n/a"
+ padlocksupport="n/a"
+ drngsupport="n/a"
+fi
+
+if test "$mpi_cpu_arch" != "arm" ; then
+ if test "$mpi_cpu_arch" != "aarch64" ; then
+ neonsupport="n/a"
+ armcryptosupport="n/a"
+ fi
+fi
+
+if test "$mpi_cpu_arch" != "ppc"; then
+ ppccryptosupport="n/a"
+fi
+
+#############################################
+#### ####
+#### Platform specific compiler checks. ####
+#### ####
+#############################################
+
+
+# Following tests depend on warnings to cause compile to fail, so set -Werror
+# temporarily.
+_gcc_cflags_save=$CFLAGS
+CFLAGS="$CFLAGS -Werror"
+
+
+#
+# Check whether compiler supports 'ms_abi' function attribute.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports 'ms_abi' function attribute" >&5
+$as_echo_n "checking whether compiler supports 'ms_abi' function attribute... " >&6; }
+if ${gcry_cv_gcc_attribute_ms_abi+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_attribute_ms_abi=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int __attribute__ ((ms_abi)) proto(int);
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_attribute_ms_abi=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_ms_abi" >&5
+$as_echo "$gcry_cv_gcc_attribute_ms_abi" >&6; }
+if test "$gcry_cv_gcc_attribute_ms_abi" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ATTRIBUTE_MS_ABI 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether compiler supports 'sysv_abi' function attribute.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports 'sysv_abi' function attribute" >&5
+$as_echo_n "checking whether compiler supports 'sysv_abi' function attribute... " >&6; }
+if ${gcry_cv_gcc_attribute_sysv_abi+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_attribute_sysv_abi=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int __attribute__ ((sysv_abi)) proto(int);
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_attribute_sysv_abi=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_sysv_abi" >&5
+$as_echo "$gcry_cv_gcc_attribute_sysv_abi" >&6; }
+if test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_ATTRIBUTE_SYSV_ABI 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether default calling convention is 'ms_abi'.
+#
+if test "$gcry_cv_gcc_attribute_ms_abi" = "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether default calling convention is 'ms_abi'" >&5
+$as_echo_n "checking whether default calling convention is 'ms_abi'... " >&6; }
+if ${gcry_cv_gcc_default_abi_is_ms_abi+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_default_abi_is_ms_abi=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void *test(void) {
+ void *(*def_func)(void) = test;
+ void *__attribute__((ms_abi))(*msabi_func)(void);
+ /* warning on SysV abi targets, passes on Windows based targets */
+ msabi_func = def_func;
+ return msabi_func;
+ }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_default_abi_is_ms_abi=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_default_abi_is_ms_abi" >&5
+$as_echo "$gcry_cv_gcc_default_abi_is_ms_abi" >&6; }
+ if test "$gcry_cv_gcc_default_abi_is_ms_abi" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_DEFAULT_ABI_IS_MS_ABI 1" >>confdefs.h
+
+ fi
+fi
+
+
+#
+# Check whether default calling convention is 'sysv_abi'.
+#
+if test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether default calling convention is 'sysv_abi'" >&5
+$as_echo_n "checking whether default calling convention is 'sysv_abi'... " >&6; }
+if ${gcry_cv_gcc_default_abi_is_sysv_abi+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_default_abi_is_sysv_abi=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void *test(void) {
+ void *(*def_func)(void) = test;
+ void *__attribute__((sysv_abi))(*sysvabi_func)(void);
+ /* warning on MS ABI targets, passes on SysV ABI targets */
+ sysvabi_func = def_func;
+ return sysvabi_func;
+ }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_default_abi_is_sysv_abi=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_default_abi_is_sysv_abi" >&5
+$as_echo "$gcry_cv_gcc_default_abi_is_sysv_abi" >&6; }
+ if test "$gcry_cv_gcc_default_abi_is_sysv_abi" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_DEFAULT_ABI_IS_SYSV_ABI 1" >>confdefs.h
+
+ fi
+fi
+
+
+# Restore flags.
+CFLAGS=$_gcc_cflags_save;
+
+
+#
+# Check whether GCC inline assembler supports SSSE3 instructions
+# This is required for the AES-NI instructions.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports SSSE3 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports SSSE3 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_ssse3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_ssse3="n/a"
+ else
+ gcry_cv_gcc_inline_asm_ssse3=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+ void a(void) {
+ __asm__("pshufb %[mask], %%xmm2\n\t"::[mask]"m"(*be_mask):);
+ }
+int
+main ()
+{
+ a();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_ssse3=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_ssse3" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_ssse3" >&6; }
+if test "$gcry_cv_gcc_inline_asm_ssse3" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_SSSE3 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports PCLMUL instructions.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports PCLMUL instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports PCLMUL instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_pclmul+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_pclmul="n/a"
+ else
+ gcry_cv_gcc_inline_asm_pclmul=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(void) {
+ __asm__("pclmulqdq \$0, %%xmm1, %%xmm3\n\t":::"cc");
+ }
+int
+main ()
+{
+ a();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_pclmul=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_pclmul" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_pclmul" >&6; }
+if test "$gcry_cv_gcc_inline_asm_pclmul" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_PCLMUL 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports SHA Extensions instructions.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports SHA Extensions instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports SHA Extensions instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_shaext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_shaext="n/a"
+ else
+ gcry_cv_gcc_inline_asm_shaext=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(void) {
+ __asm__("sha1rnds4 \$0, %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha1nexte %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha1msg1 %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha1msg2 %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha256rnds2 %%xmm0, %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha256msg1 %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha256msg2 %%xmm1, %%xmm3\n\t":::"cc");
+ }
+int
+main ()
+{
+ a();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_shaext=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_shaext" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_shaext" >&6; }
+if test "$gcry_cv_gcc_inline_asm_shaext" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_SHAEXT 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports SSE4.1 instructions.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports SSE4.1 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports SSE4.1 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_sse41+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_sse41="n/a"
+ else
+ gcry_cv_gcc_inline_asm_sse41=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(void) {
+ int i;
+ __asm__("pextrd \$2, %%xmm0, %[out]\n\t" : [out] "=m" (i));
+ }
+int
+main ()
+{
+ a();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_sse41=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_sse41" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_sse41" >&6; }
+if test "$gcry_cv_gcc_inline_asm_sse41" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_SSE41 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports AVX instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports AVX instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports AVX instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_avx+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_avx="n/a"
+ else
+ gcry_cv_gcc_inline_asm_avx=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(void) {
+ __asm__("xgetbv; vaesdeclast (%[mem]),%%xmm0,%%xmm7\n\t"::[mem]"r"(0):);
+ }
+int
+main ()
+{
+ a();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_avx=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_avx" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_avx" >&6; }
+if test "$gcry_cv_gcc_inline_asm_avx" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_AVX 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports AVX2 instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports AVX2 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports AVX2 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_avx2+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_avx2="n/a"
+ else
+ gcry_cv_gcc_inline_asm_avx2=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void a(void) {
+ __asm__("xgetbv; vpbroadcastb %%xmm7,%%ymm1\n\t":::"cc");
+ }
+int
+main ()
+{
+ a();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_avx2=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_avx2" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_avx2" >&6; }
+if test "$gcry_cv_gcc_inline_asm_avx2" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_AVX2 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports BMI2 instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports BMI2 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports BMI2 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_bmi2+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_bmi2="n/a"
+ else
+ gcry_cv_gcc_inline_asm_bmi2=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+unsigned int a(unsigned int x, unsigned int y) {
+ unsigned int tmp1, tmp2;
+ asm ("rorxl %2, %1, %0"
+ : "=r" (tmp1)
+ : "rm0" (x), "J" (32 - ((23) & 31)));
+ asm ("andnl %2, %1, %0"
+ : "=r" (tmp2)
+ : "r0" (x), "rm" (y));
+ return tmp1 + tmp2;
+ }
+int
+main ()
+{
+ a(1, 2);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_bmi2=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_bmi2" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_bmi2" >&6; }
+if test "$gcry_cv_gcc_inline_asm_bmi2" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_BMI2 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC assembler needs "-Wa,--divide" to correctly handle
+# constant division
+#
+if test $amd64_as_feature_detection = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler handles division correctly" >&5
+$as_echo_n "checking whether GCC assembler handles division correctly... " >&6; }
+if ${gcry_cv_gcc_as_const_division_ok+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_as_const_division_ok=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");
+int
+main ()
+{
+fn();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_as_const_division_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_as_const_division_ok" >&5
+$as_echo "$gcry_cv_gcc_as_const_division_ok" >&6; }
+ if test "$gcry_cv_gcc_as_const_division_ok" = "no" ; then
+ #
+ # Add '-Wa,--divide' to CPPFLAGS and try check again.
+ #
+ _gcc_cppflags_save="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -Wa,--divide"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler handles division correctly with \"-Wa,--divide\"" >&5
+$as_echo_n "checking whether GCC assembler handles division correctly with \"-Wa,--divide\"... " >&6; }
+if ${gcry_cv_gcc_as_const_division_with_wadivide_ok+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_as_const_division_with_wadivide_ok=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");
+int
+main ()
+{
+fn();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_as_const_division_with_wadivide_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_as_const_division_with_wadivide_ok" >&5
+$as_echo "$gcry_cv_gcc_as_const_division_with_wadivide_ok" >&6; }
+ if test "$gcry_cv_gcc_as_const_division_with_wadivide_ok" = "no" ; then
+ # '-Wa,--divide' did not work, restore old flags.
+ CPPFLAGS="$_gcc_cppflags_save"
+ fi
+ fi
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for our amd64
+# implementations
+#
+if test $amd64_as_feature_detection = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for amd64 assembly implementations" >&5
+$as_echo_n "checking whether GCC assembler is compatible for amd64 assembly implementations... " >&6; }
+if ${gcry_cv_gcc_amd64_platform_as_ok+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_amd64_platform_as_ok="n/a"
+ else
+ gcry_cv_gcc_amd64_platform_as_ok=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ /* Test if '.type' and '.size' are supported. */
+ /* These work only on ELF targets. */
+ ".text\n\t"
+ "asmfunc:\n\t"
+ ".size asmfunc,.-asmfunc;\n\t"
+ ".type asmfunc,@function;\n\t"
+ /* Test if assembler allows use of '/' for constant division
+ * (Solaris/x86 issue). If previous constant division check
+ * and "-Wa,--divide" workaround failed, this causes assembly
+ * to be disable on this machine. */
+ "xorl \$(123456789/12345678), %ebp;\n\t"
+ );
+int
+main ()
+{
+ asmfunc();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_amd64_platform_as_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_amd64_platform_as_ok" >&5
+$as_echo "$gcry_cv_gcc_amd64_platform_as_ok" >&6; }
+ if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then
+
+$as_echo "#define HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS 1" >>confdefs.h
+
+ fi
+ if test "$gcry_cv_gcc_amd64_platform_as_ok" = "no" &&
+ test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" &&
+ test "$gcry_cv_gcc_default_abi_is_ms_abi" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for WIN64 assembly implementations" >&5
+$as_echo_n "checking whether GCC assembler is compatible for WIN64 assembly implementations... " >&6; }
+if ${gcry_cv_gcc_win64_platform_as_ok+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_win64_platform_as_ok=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ ".text\n\t"
+ ".globl asmfunc\n\t"
+ "asmfunc:\n\t"
+ "xorq \$(1234), %rbp;\n\t"
+ );
+int
+main ()
+{
+ asmfunc();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_win64_platform_as_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_win64_platform_as_ok" >&5
+$as_echo "$gcry_cv_gcc_win64_platform_as_ok" >&6; }
+ if test "$gcry_cv_gcc_win64_platform_as_ok" = "yes" ; then
+
+$as_echo "#define HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS 1" >>confdefs.h
+
+ fi
+ fi
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for assembly
+# implementations that use Intel syntax
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for Intel syntax assembly implementations" >&5
+$as_echo_n "checking whether GCC assembler is compatible for Intel syntax assembly implementations... " >&6; }
+if ${gcry_cv_gcc_platform_as_ok_for_intel_syntax+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_platform_as_ok_for_intel_syntax="n/a"
+ else
+ gcry_cv_gcc_platform_as_ok_for_intel_syntax=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ ".intel_syntax noprefix\n\t"
+ ".text\n\t"
+ "actest:\n\t"
+ "pxor xmm1, xmm7;\n\t"
+ "vperm2i128 ymm2, ymm3, ymm0, 1;\n\t"
+ "add eax, ebp;\n\t"
+ "rorx eax, ebp, 1;\n\t"
+ "sub eax, [esp + 4];\n\t"
+ "add dword ptr [esp + eax], 0b10101;\n\t"
+ ".att_syntax prefix\n\t"
+ );
+int
+main ()
+{
+ actest();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_platform_as_ok_for_intel_syntax=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_platform_as_ok_for_intel_syntax" >&5
+$as_echo "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" >&6; }
+if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then
+
+$as_echo "#define HAVE_INTEL_SYNTAX_PLATFORM_AS 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether compiler is configured for ARMv6 or newer architecture
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler is configured for ARMv6 or newer architecture" >&5
+$as_echo_n "checking whether compiler is configured for ARMv6 or newer architecture... " >&6; }
+if ${gcry_cv_cc_arm_arch_is_v6+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "arm" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_cc_arm_arch_is_v6="n/a"
+ else
+ gcry_cv_cc_arm_arch_is_v6=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #if defined(__arm__) && \
+ ((defined(__ARM_ARCH) && __ARM_ARCH >= 6) \
+ || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) \
+ || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__))
+ /* empty */
+ #else
+ /* fail compile if not ARMv6. */
+ not_armv6 not_armv6 = (not_armv6)not_armv6;
+ #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_cc_arm_arch_is_v6=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_cc_arm_arch_is_v6" >&5
+$as_echo "$gcry_cv_cc_arm_arch_is_v6" >&6; }
+if test "$gcry_cv_cc_arm_arch_is_v6" = "yes" ; then
+
+$as_echo "#define HAVE_ARM_ARCH_V6 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports NEON instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports NEON instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports NEON instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_neon+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "arm" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_neon="n/a"
+ else
+ gcry_cv_gcc_inline_asm_neon=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ ".syntax unified\n\t"
+ ".arm\n\t"
+ ".fpu neon\n\t"
+ ".text\n\t"
+ "testfn:\n\t"
+ "vld1.64 {%q0-%q1}, [%r0]!;\n\t"
+ "vrev64.8 %q0, %q3;\n\t"
+ "vadd.u64 %q0, %q1;\n\t"
+ "vadd.s64 %d3, %d2, %d3;\n\t"
+ );
+
+int
+main ()
+{
+ testfn();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_neon=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_neon" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_neon" >&6; }
+if test "$gcry_cv_gcc_inline_asm_neon" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_NEON 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports AArch32 Crypto Extension instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports AArch32 Crypto Extension instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports AArch32 Crypto Extension instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_aarch32_crypto+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "arm" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_aarch32_crypto="n/a"
+ else
+ gcry_cv_gcc_inline_asm_aarch32_crypto=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ ".syntax unified\n\t"
+ ".arch armv8-a\n\t"
+ ".arm\n\t"
+ ".fpu crypto-neon-fp-armv8\n\t"
+ ".text\n\t"
+
+ "testfn:\n\t"
+ "sha1h.32 q0, q0;\n\t"
+ "sha1c.32 q0, q0, q0;\n\t"
+ "sha1p.32 q0, q0, q0;\n\t"
+ "sha1su0.32 q0, q0, q0;\n\t"
+ "sha1su1.32 q0, q0;\n\t"
+
+ "sha256h.32 q0, q0, q0;\n\t"
+ "sha256h2.32 q0, q0, q0;\n\t"
+ "sha1p.32 q0, q0, q0;\n\t"
+ "sha256su0.32 q0, q0;\n\t"
+ "sha256su1.32 q0, q0, q15;\n\t"
+
+ "aese.8 q0, q0;\n\t"
+ "aesd.8 q0, q0;\n\t"
+ "aesmc.8 q0, q0;\n\t"
+ "aesimc.8 q0, q0;\n\t"
+
+ "vmull.p64 q0, d0, d0;\n\t"
+ );
+
+int
+main ()
+{
+ testfn();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_aarch32_crypto=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_aarch32_crypto" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_aarch32_crypto" >&6; }
+if test "$gcry_cv_gcc_inline_asm_aarch32_crypto" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports AArch64 NEON instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports AArch64 NEON instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports AArch64 NEON instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_aarch64_neon+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "aarch64" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_aarch64_neon="n/a"
+ else
+ gcry_cv_gcc_inline_asm_aarch64_neon=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ ".cpu generic+simd\n\t"
+ ".text\n\t"
+ "testfn:\n\t"
+ "mov w0, \#42;\n\t"
+ "dup v0.8b, w0;\n\t"
+ "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t"
+ );
+
+int
+main ()
+{
+ testfn();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_aarch64_neon=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_aarch64_neon" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_aarch64_neon" >&6; }
+if test "$gcry_cv_gcc_inline_asm_aarch64_neon" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_AARCH64_NEON 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports AArch64 Crypto Extension instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports AArch64 Crypto Extension instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports AArch64 Crypto Extension instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_aarch64_crypto+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "aarch64" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_aarch64_crypto="n/a"
+ else
+ gcry_cv_gcc_inline_asm_aarch64_crypto=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(
+ ".cpu generic+simd+crypto\n\t"
+ ".text\n\t"
+ "testfn:\n\t"
+ "mov w0, \#42;\n\t"
+ "dup v0.8b, w0;\n\t"
+ "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t"
+
+ "sha1h s0, s0;\n\t"
+ "sha1c q0, s0, v0.4s;\n\t"
+ "sha1p q0, s0, v0.4s;\n\t"
+ "sha1su0 v0.4s, v0.4s, v0.4s;\n\t"
+ "sha1su1 v0.4s, v0.4s;\n\t"
+
+ "sha256h q0, q0, v0.4s;\n\t"
+ "sha256h2 q0, q0, v0.4s;\n\t"
+ "sha1p q0, s0, v0.4s;\n\t"
+ "sha256su0 v0.4s, v0.4s;\n\t"
+ "sha256su1 v0.4s, v0.4s, v31.4s;\n\t"
+
+ "aese v0.16b, v0.16b;\n\t"
+ "aesd v0.16b, v0.16b;\n\t"
+ "aesmc v0.16b, v0.16b;\n\t"
+ "aesimc v0.16b, v0.16b;\n\t"
+
+ "pmull v0.1q, v0.1d, v31.1d;\n\t"
+ "pmull2 v0.1q, v0.2d, v31.2d;\n\t"
+ );
+
+int
+main ()
+{
+ testfn();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_aarch64_crypto=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_aarch64_crypto" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_aarch64_crypto" >&6; }
+if test "$gcry_cv_gcc_inline_asm_aarch64_crypto" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether PowerPC AltiVec/VSX intrinsics
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports PowerPC AltiVec/VSX intrinsics" >&5
+$as_echo_n "checking whether compiler supports PowerPC AltiVec/VSX intrinsics... " >&6; }
+if ${gcry_cv_cc_ppc_altivec+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "ppc" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_cc_ppc_altivec="n/a"
+ else
+ gcry_cv_cc_ppc_altivec=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <altivec.h>
+ typedef vector unsigned char block;
+ typedef vector unsigned int vecu32;
+ block fn(block in)
+ {
+ block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0));
+ vecu32 y = vec_vsx_ld (0, (unsigned int*)0);
+ return vec_cipher_be (t, in) ^ (block)y;
+ }
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_cc_ppc_altivec=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_cc_ppc_altivec" >&5
+$as_echo "$gcry_cv_cc_ppc_altivec" >&6; }
+if test "$gcry_cv_cc_ppc_altivec" = "yes" ; then
+
+$as_echo "#define HAVE_COMPATIBLE_CC_PPC_ALTIVEC 1" >>confdefs.h
+
+fi
+
+_gcc_cflags_save=$CFLAGS
+CFLAGS="$CFLAGS -maltivec -mvsx -mcrypto"
+
+if test "$gcry_cv_cc_ppc_altivec" = "no" &&
+ test "$mpi_cpu_arch" = "ppc" &&
+ test "$try_asm_modules" == "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports PowerPC AltiVec/VSX/crypto intrinsics with extra GCC flags" >&5
+$as_echo_n "checking whether compiler supports PowerPC AltiVec/VSX/crypto intrinsics with extra GCC flags... " >&6; }
+if ${gcry_cv_cc_ppc_altivec_cflags+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_cc_ppc_altivec_cflags=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <altivec.h>
+ typedef vector unsigned char block;
+ typedef vector unsigned int vecu32;
+ block fn(block in)
+ {
+ block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0));
+ vecu32 y = vec_vsx_ld (0, (unsigned int*)0);
+ return vec_cipher_be (t, in) ^ (block)y;
+ }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_cc_ppc_altivec_cflags=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_cc_ppc_altivec_cflags" >&5
+$as_echo "$gcry_cv_cc_ppc_altivec_cflags" >&6; }
+ if test "$gcry_cv_cc_ppc_altivec_cflags" = "yes" ; then
+
+$as_echo "#define HAVE_COMPATIBLE_CC_PPC_ALTIVEC 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_COMPATIBLE_CC_PPC_ALTIVEC_WITH_CFLAGS 1" >>confdefs.h
+
+ fi
+fi
+
+ if test "$gcry_cv_cc_ppc_altivec_cflags" = "yes"; then
+ ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_TRUE=
+ ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_FALSE='#'
+else
+ ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_TRUE='#'
+ ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_FALSE=
+fi
+
+
+# Restore flags.
+CFLAGS=$_gcc_cflags_save;
+
+
+#
+# Check whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_ppc_altivec+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "ppc" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_ppc_altivec="n/a"
+ else
+ gcry_cv_gcc_inline_asm_ppc_altivec=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(".globl testfn;\n"
+ ".text\n\t"
+ "testfn:\n"
+ "stvx %v31,%r12,%r0;\n"
+ "lvx %v20,%r12,%r0;\n"
+ "vcipher %v0, %v1, %v22;\n"
+ "lxvw4x %vs32, %r0, %r1;\n"
+ "vadduwm %v0, %v1, %v22;\n"
+ "vshasigmaw %v0, %v1, 0, 15;\n"
+ "vshasigmad %v0, %v1, 0, 15;\n"
+ "vpmsumd %v11, %v11, %v11;\n"
+ );
+
+int
+main ()
+{
+ testfn();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_ppc_altivec=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_ppc_altivec" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_ppc_altivec" >&6; }
+if test "$gcry_cv_gcc_inline_asm_ppc_altivec" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_PPC_ALTIVEC 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports PowerISA 3.00 instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports PowerISA 3.00 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports PowerISA 3.00 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_ppc_arch_3_00+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "ppc" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_ppc_arch_3_00="n/a"
+ else
+ gcry_cv_gcc_inline_asm_ppc_arch_3_00=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__asm__(".text\n\t"
+ ".globl testfn;\n"
+ "testfn:\n"
+ "stxvb16x %r1,%v12,%v30;\n"
+ );
+
+int
+main ()
+{
+ testfn();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_ppc_arch_3_00=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_ppc_arch_3_00" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_ppc_arch_3_00" >&6; }
+if test "$gcry_cv_gcc_inline_asm_ppc_arch_3_00" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports zSeries instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports zSeries instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports zSeries instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_s390x+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "s390x" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_s390x="n/a"
+ else
+ gcry_cv_gcc_inline_asm_s390x=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+typedef unsigned int u128_t __attribute__ ((mode (TI)));
+ unsigned int testfunc(unsigned int x, void *y, unsigned int z)
+ {
+ unsigned long fac[8];
+ register unsigned long reg0 asm("0") = 0;
+ register unsigned long reg1 asm("1") = x;
+ u128_t r1 = ((u128_t)(unsigned long)y << 64) | (unsigned long)z;
+ u128_t r2 = 0;
+ u128_t r3 = 0;
+ asm volatile (".insn rre,0xb92e << 16, %[r1], %[r2]\n\t"
+ : [r1] "+a" (r1), [r2] "+a" (r2)
+ : "r" (reg0), "r" (reg1)
+ : "cc", "memory");
+ asm volatile (".insn rrf,0xb929 << 16, %[r1], %[r2], %[r3], 0\n\t"
+ : [r1] "+a" (r1), [r2] "+a" (r2), [r3] "+a" (r3)
+ : "r" (reg0), "r" (reg1)
+ : "cc", "memory");
+ reg0 = 8 - 1;
+ asm ("stfle %1\n\t"
+ : "+d" (reg0), "=Q" (fac[0])
+ :
+ : "cc", "memory");
+ asm volatile ("mvc 0(16, %0), 0(%1)\n\t"
+ :
+ : "a" (y), "a" (fac)
+ : "memory");
+ asm volatile ("xc 0(16, %0), 0(%0)\n\t"
+ :
+ : "a" (fac)
+ : "memory");
+ asm volatile ("risbgn %%r11, %%r11, 0, 129, 0\n\t"
+ :
+ :
+ : "memory", "r11");
+ asm volatile ("algrk %%r14, %%r14, %%r14\n\t"
+ :
+ :
+ : "memory", "r14");
+ return (unsigned int)r1 ^ reg0;
+ }
+
+int
+main ()
+{
+ testfunc(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_s390x=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_s390x" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_s390x" >&6; }
+if test "$gcry_cv_gcc_inline_asm_s390x" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_S390X 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports zSeries vector instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports zSeries vector instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports zSeries vector instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_s390x_vx+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$mpi_cpu_arch" != "s390x" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_s390x_vx="n/a"
+ else
+ gcry_cv_gcc_inline_asm_s390x_vx=no
+ if test "$gcry_cv_gcc_inline_asm_s390x" = "yes" ; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void testfunc(void)
+ {
+ asm volatile (".machine \"z13+vx\"\n\t"
+ "vx %%v0, %%v1, %%v31\n\t"
+ "verllf %%v11, %%v11, (16)(0)\n\t"
+ :
+ :
+ : "memory");
+ }
+
+int
+main ()
+{
+ testfunc();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gcry_cv_gcc_inline_asm_s390x_vx=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_inline_asm_s390x_vx" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_s390x_vx" >&6; }
+if test "$gcry_cv_gcc_inline_asm_s390x_vx" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_S390X_VX 1" >>confdefs.h
+
+fi
+
+
+#######################################
+#### Checks for library functions. ####
+#######################################
+
+for ac_func in vprintf
+do :
+ ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
+if test "x$ac_cv_func_vprintf" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF 1
+_ACEOF
+
+ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
+if test "x$ac_cv_func__doprnt" = xyes; then :
+
+$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
+
+fi
+
+fi
+done
+
+
+# We have replacements for these in src/missing-string.c
+for ac_func in stpcpy strcasecmp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# We have replacements for these in src/g10lib.h
+for ac_func in strtoul memmove stricmp atexit raise
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# Other checks
+for ac_func in strerror rand mmap getpagesize sysconf waitpid wait4
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in gettimeofday getrusage gethrtime clock_gettime syslog
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in syscall fcntl ftruncate flockfile getauxval elf_aux_info
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in explicit_bzero explicit_memset getentropy
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ for ac_func in mlock
+do :
+ ac_fn_c_check_func "$LINENO" "mlock" "ac_cv_func_mlock"
+if test "x$ac_cv_func_mlock" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MLOCK 1
+_ACEOF
+
+fi
+done
+
+ if test "$ac_cv_func_mlock" = "no"; then
+ for ac_header in sys/mman.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mman_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_MMAN_H 1
+_ACEOF
+
+fi
+
+done
+
+ if test "$ac_cv_header_sys_mman_h" = "yes"; then
+ # Add librt to LIBS:
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for memlk in -lrt" >&5
+$as_echo_n "checking for memlk in -lrt... " >&6; }
+if ${ac_cv_lib_rt_memlk+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char memlk ();
+int
+main ()
+{
+return memlk ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_memlk=yes
+else
+ ac_cv_lib_rt_memlk=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_memlk" >&5
+$as_echo "$ac_cv_lib_rt_memlk" >&6; }
+if test "x$ac_cv_lib_rt_memlk" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRT 1
+_ACEOF
+
+ LIBS="-lrt $LIBS"
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mlock is in sys/mman.h" >&5
+$as_echo_n "checking whether mlock is in sys/mman.h... " >&6; }
+if ${gnupg_cv_mlock_is_in_sys_mman+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <assert.h>
+ #ifdef HAVE_SYS_MMAN_H
+ #include <sys/mman.h>
+ #endif
+
+int
+main ()
+{
+
+int i;
+
+/* glibc defines this for functions which it implements
+ * to always fail with ENOSYS. Some functions are actually
+ * named something starting with __ and the normal name
+ * is an alias. */
+#if defined (__stub_mlock) || defined (__stub___mlock)
+choke me
+#else
+mlock(&i, 4);
+#endif
+; return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gnupg_cv_mlock_is_in_sys_mman=yes
+else
+ gnupg_cv_mlock_is_in_sys_mman=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_mlock_is_in_sys_mman" >&5
+$as_echo "$gnupg_cv_mlock_is_in_sys_mman" >&6; }
+ if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then
+
+$as_echo "#define HAVE_MLOCK 1" >>confdefs.h
+
+ fi
+ fi
+ fi
+ if test "$ac_cv_func_mlock" = "yes"; then
+ for ac_func in sysconf getpagesize
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mlock is broken" >&5
+$as_echo_n "checking whether mlock is broken... " >&6; }
+ if ${gnupg_cv_have_broken_mlock+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ gnupg_cv_have_broken_mlock="assume-no"
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+int main()
+{
+ char *pool;
+ int err;
+ long int pgsize;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pgsize = sysconf (_SC_PAGESIZE);
+#elif defined (HAVE_GETPAGESIZE)
+ pgsize = getpagesize();
+#else
+ pgsize = -1;
+#endif
+
+ if (pgsize == -1)
+ pgsize = 4096;
+
+ pool = malloc( 4096 + pgsize );
+ if( !pool )
+ return 2;
+ pool += (pgsize - ((long int)pool % pgsize));
+
+ err = mlock( pool, 4096 );
+ if( !err || errno == EPERM || errno == EAGAIN)
+ return 0; /* okay */
+
+ return 1; /* hmmm */
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gnupg_cv_have_broken_mlock="no"
+else
+ gnupg_cv_have_broken_mlock="yes"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+
+ if test "$gnupg_cv_have_broken_mlock" = "yes"; then
+
+$as_echo "#define HAVE_BROKEN_MLOCK 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ if test "$gnupg_cv_have_broken_mlock" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming no" >&5
+$as_echo "assuming no" >&6; }
+ fi
+ fi
+ fi
+
+
+#
+# Replacement functions.
+#
+ac_fn_c_check_func "$LINENO" "getpid" "ac_cv_func_getpid"
+if test "x$ac_cv_func_getpid" = xyes; then :
+ $as_echo "#define HAVE_GETPID 1" >>confdefs.h
+
+else
+ case " $LIBOBJS " in
+ *" getpid.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getpid.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "clock" "ac_cv_func_clock"
+if test "x$ac_cv_func_clock" = xyes; then :
+ $as_echo "#define HAVE_CLOCK 1" >>confdefs.h
+
+else
+ case " $LIBOBJS " in
+ *" clock.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS clock.$ac_objext"
+ ;;
+esac
+
+fi
+
+
+
+
+#
+# Check whether it is necessary to link against libdl.
+#
+DL_LIBS=""
+if test "$use_hmac_binary_check" = yes ; then
+ _gcry_save_libs="$LIBS"
+ LIBS=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
+$as_echo_n "checking for library containing dlopen... " >&6; }
+if ${ac_cv_search_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' c dl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_dlopen=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_dlopen+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_dlopen+:} false; then :
+
+else
+ ac_cv_search_dlopen=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
+$as_echo "$ac_cv_search_dlopen" >&6; }
+ac_res=$ac_cv_search_dlopen
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ DL_LIBS=$LIBS
+ LIBS="$_gcry_save_libs"
+fi
+
+
+
+#
+# Check whether we can use Linux capabilities as requested.
+#
+if test "$use_capabilities" = "yes" ; then
+use_capabilities=no
+for ac_header in sys/capability.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/capability.h" "ac_cv_header_sys_capability_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_capability_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_CAPABILITY_H 1
+_ACEOF
+
+fi
+
+done
+
+if test "$ac_cv_header_sys_capability_h" = "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_init in -lcap" >&5
+$as_echo_n "checking for cap_init in -lcap... " >&6; }
+if ${ac_cv_lib_cap_cap_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcap $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cap_init ();
+int
+main ()
+{
+return cap_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_cap_cap_init=yes
+else
+ ac_cv_lib_cap_cap_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_cap_init" >&5
+$as_echo "$ac_cv_lib_cap_cap_init" >&6; }
+if test "x$ac_cv_lib_cap_cap_init" = xyes; then :
+ ac_need_libcap=1
+fi
+
+ if test "$ac_cv_lib_cap_cap_init" = "yes"; then
+
+$as_echo "#define USE_CAPABILITIES 1" >>confdefs.h
+
+ LIBS="$LIBS -lcap"
+ use_capabilities=yes
+ fi
+fi
+if test "$use_capabilities" = "no" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+***
+*** The use of capabilities on this system is not possible.
+*** You need a recent Linux kernel and some patches:
+*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9)
+*** fcap-module-990613.tar.gz (kernel module)
+*** libcap-1.92.tar.gz (user mode library and utilities)
+*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN
+*** set (filesystems menu). Be warned: This code is *really* ALPHA.
+***" >&5
+$as_echo "$as_me: WARNING:
+***
+*** The use of capabilities on this system is not possible.
+*** You need a recent Linux kernel and some patches:
+*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9)
+*** fcap-module-990613.tar.gz (kernel module)
+*** libcap-1.92.tar.gz (user mode library and utilities)
+*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN
+*** set (filesystems menu). Be warned: This code is *really* ALPHA.
+***" >&2;}
+fi
+fi
+
+# Check whether a random device is available.
+if test "$try_dev_random" = yes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for random device" >&5
+$as_echo_n "checking for random device... " >&6; }
+if ${ac_cv_have_dev_random+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -r "$NAME_OF_DEV_RANDOM" && test -r "$NAME_OF_DEV_URANDOM" ; then
+ ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_dev_random" >&5
+$as_echo "$ac_cv_have_dev_random" >&6; }
+ if test "$ac_cv_have_dev_random" = yes; then
+
+$as_echo "#define HAVE_DEV_RANDOM 1" >>confdefs.h
+
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for random device" >&5
+$as_echo_n "checking for random device... " >&6; }
+ ac_cv_have_dev_random=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: has been disabled" >&5
+$as_echo "has been disabled" >&6; }
+fi
+
+# Figure out the random modules for this configuration.
+if test "$random" = "default"; then
+
+ # Select default value.
+ if test "$ac_cv_have_dev_random" = yes; then
+ # Try Linuxish random device.
+ random_modules="linux"
+ else
+ case "${host}" in
+ *-*-mingw32ce*)
+ # WindowsCE random device.
+ random_modules="w32ce"
+ ;;
+ *-*-mingw32*|*-*-cygwin*)
+ # Windows random device.
+ random_modules="w32"
+ ;;
+ *)
+ # Build everything, allow to select at runtime.
+ random_modules="$auto_random_modules"
+ ;;
+ esac
+ fi
+else
+ if test "$random" = "auto"; then
+ # Build everything, allow to select at runtime.
+ random_modules="$auto_random_modules"
+ else
+ random_modules="$random"
+ fi
+fi
+
+
+#
+# Other defines
+#
+if test mym4_isgit = "yes"; then
+
+$as_echo "#define IS_DEVELOPMENT_VERSION 1" >>confdefs.h
+
+fi
+
+
+ if test x$cross_compiling = xyes; then
+ CROSS_COMPILING_TRUE=
+ CROSS_COMPILING_FALSE='#'
+else
+ CROSS_COMPILING_TRUE='#'
+ CROSS_COMPILING_FALSE=
+fi
+
+
+
+# This is handy for debugging so the compiler doesn't rearrange
+# things and eliminate variables.
+# Check whether --enable-optimization was given.
+if test "${enable_optimization+set}" = set; then :
+ enableval=$enable_optimization; if test $enableval = no ; then
+ CFLAGS=`echo $CFLAGS | sed 's/-O[0-9]//'`
+ fi
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cc features" >&5
+$as_echo "$as_me: checking for cc features" >&6;}
+# CFLAGS mangling when using gcc.
+if test "$GCC" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -fno-delete-null-pointer-checks" >&5
+$as_echo_n "checking if gcc supports -fno-delete-null-pointer-checks... " >&6; }
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-fno-delete-null-pointer-checks"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ _gcc_wopt=yes
+else
+ _gcc_wopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_wopt" >&5
+$as_echo "$_gcc_wopt" >&6; }
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -fno-delete-null-pointer-checks"
+ fi
+
+ CFLAGS="$CFLAGS -Wall"
+ if test "$USE_MAINTAINER_MODE" = "yes"; then
+ CFLAGS="$CFLAGS -Wcast-align -Wshadow -Wstrict-prototypes"
+ CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security"
+
+ # If -Wno-missing-field-initializers is supported we can enable a
+ # a bunch of really useful warnings.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -Wno-missing-field-initializers" >&5
+$as_echo_n "checking if gcc supports -Wno-missing-field-initializers... " >&6; }
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-Wno-missing-field-initializers"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ _gcc_wopt=yes
+else
+ _gcc_wopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_wopt" >&5
+$as_echo "$_gcc_wopt" >&6; }
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -W -Wextra -Wbad-function-cast"
+ CFLAGS="$CFLAGS -Wwrite-strings"
+ CFLAGS="$CFLAGS -Wdeclaration-after-statement"
+ CFLAGS="$CFLAGS -Wno-missing-field-initializers"
+ CFLAGS="$CFLAGS -Wno-sign-compare"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -Wpointer-arith" >&5
+$as_echo_n "checking if gcc supports -Wpointer-arith... " >&6; }
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-Wpointer-arith"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ _gcc_wopt=yes
+else
+ _gcc_wopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_wopt" >&5
+$as_echo "$_gcc_wopt" >&6; }
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -Wpointer-arith"
+ fi
+ fi
+fi
+
+# Check whether as(1) supports a noeexecstack feature. This test
+# includes an override option.
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether non excutable stack support is requested" >&5
+$as_echo_n "checking whether non excutable stack support is requested... " >&6; }
+# Check whether --enable-noexecstack was given.
+if test "${enable_noexecstack+set}" = set; then :
+ enableval=$enable_noexecstack; noexecstack_support=$enableval
+else
+ noexecstack_support=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $noexecstack_support" >&5
+$as_echo "$noexecstack_support" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler supports --noexecstack option" >&5
+$as_echo_n "checking whether assembler supports --noexecstack option... " >&6; }
+if ${cl_cv_as_noexecstack+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<EOF
+void foo() {}
+EOF
+ if { ac_try='${CC} $CFLAGS $CPPFLAGS
+ -S -o conftest.s conftest.c >/dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } \
+ && grep .note.GNU-stack conftest.s >/dev/null \
+ && { ac_try='${CCAS} $CCASFLAGS $CPPFLAGS -Wa,--noexecstack
+ -c -o conftest.o conftest.s >/dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ cl_cv_as_noexecstack=yes
+ else
+ cl_cv_as_noexecstack=no
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cl_cv_as_noexecstack" >&5
+$as_echo "$cl_cv_as_noexecstack" >&6; }
+ if test "$noexecstack_support" = yes -a "$cl_cv_as_noexecstack" = yes; then
+ NOEXECSTACK_FLAGS="-Wa,--noexecstack"
+ else
+ NOEXECSTACK_FLAGS=
+ fi
+
+
+
+
+
+
+
+
+
+
+ac_config_commands="$ac_config_commands gcrypt-conf"
+
+
+#####################
+#### Conclusion. ####
+#####################
+
+# Check that requested feature can actually be used and define
+# ENABLE_foo_SUPPORT macros.
+
+if test x"$aesnisupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_ssse3" != "yes" ; then
+ aesnisupport="no (unsupported by compiler)"
+ fi
+fi
+if test x"$shaextsupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_shaext" != "yes" ; then
+ shaextsupport="no (unsupported by compiler)"
+ fi
+fi
+if test x"$pclmulsupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_pclmul" != "yes" ; then
+ pclmulsupport="no (unsupported by compiler)"
+ fi
+fi
+if test x"$sse41support" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_sse41" != "yes" ; then
+ sse41support="no (unsupported by compiler)"
+ fi
+fi
+if test x"$avxsupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_avx" != "yes" ; then
+ avxsupport="no (unsupported by compiler)"
+ fi
+fi
+if test x"$avx2support" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_avx2" != "yes" ; then
+ avx2support="no (unsupported by compiler)"
+ fi
+fi
+if test x"$neonsupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_neon" != "yes" ; then
+ if test "$gcry_cv_gcc_inline_asm_aarch64_neon" != "yes" ; then
+ neonsupport="no (unsupported by compiler)"
+ fi
+ fi
+fi
+if test x"$armcryptosupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_aarch32_crypto" != "yes" ; then
+ if test "$gcry_cv_gcc_inline_asm_aarch64_crypto" != "yes" ; then
+ neonsupport="no (unsupported by compiler)"
+ fi
+ fi
+fi
+
+if test x"$aesnisupport" = xyes ; then
+
+$as_echo "#define ENABLE_AESNI_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$shaextsupport" = xyes ; then
+
+$as_echo "#define ENABLE_SHAEXT_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$pclmulsupport" = xyes ; then
+
+$as_echo "#define ENABLE_PCLMUL_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$sse41support" = xyes ; then
+
+$as_echo "#define ENABLE_SSE41_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$avxsupport" = xyes ; then
+
+$as_echo "#define ENABLE_AVX_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$avx2support" = xyes ; then
+
+$as_echo "#define ENABLE_AVX2_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$neonsupport" = xyes ; then
+
+$as_echo "#define ENABLE_NEON_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$armcryptosupport" = xyes ; then
+
+$as_echo "#define ENABLE_ARM_CRYPTO_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$ppccryptosupport" = xyes ; then
+
+$as_echo "#define ENABLE_PPC_CRYPTO_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$jentsupport" = xyes ; then
+
+$as_echo "#define ENABLE_JENT_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$padlocksupport" = xyes ; then
+
+$as_echo "#define ENABLE_PADLOCK_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$drngsupport" = xyes ; then
+
+$as_echo "#define ENABLE_DRNG_SUPPORT 1" >>confdefs.h
+
+fi
+
+
+if test x"$force_soft_hwfeatures" = xyes ; then
+
+$as_echo "#define ENABLE_FORCE_SOFT_HWFEATURES 1" >>confdefs.h
+
+fi
+
+# Define conditional sources and config.h symbols depending on the
+# selected ciphers, pubkey-ciphers, digests, kdfs, and random modules.
+
+
+name=arcfour
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1"; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour.lo"
+
+$as_echo "#define USE_ARCFOUR 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour-amd64.lo"
+ ;;
+ esac
+fi
+
+
+name=blowfish
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish.lo"
+
+$as_echo "#define USE_BLOWFISH 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-amd64.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-arm.lo"
+ ;;
+ esac
+fi
+
+
+name=cast5
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5.lo"
+
+$as_echo "#define USE_CAST5 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-amd64.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-arm.lo"
+ ;;
+ esac
+fi
+
+
+name=des
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS des.lo"
+
+$as_echo "#define USE_DES 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS des-amd64.lo"
+ ;;
+ esac
+fi
+
+
+name=aes
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael.lo"
+
+$as_echo "#define USE_AES 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-amd64.lo"
+
+ # Build with the SSSE3 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ssse3-amd64.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ssse3-amd64-asm.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-arm.lo"
+
+ # Build with the ARMv8/AArch32 CE implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-ce.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-aarch32-ce.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-aarch64.lo"
+
+ # Build with the ARMv8/AArch64 CE implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-ce.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-aarch64-ce.lo"
+ ;;
+ powerpc64le-*-*)
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc9le.lo"
+ ;;
+ powerpc64-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo"
+ ;;
+ powerpc-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo"
+ ;;
+ s390x-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-s390x.lo"
+ ;;
+ esac
+
+ case "$mpi_cpu_arch" in
+ x86)
+ # Build with the AES-NI implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-aesni.lo"
+
+ # Build with the Padlock implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-padlock.lo"
+ ;;
+ esac
+fi
+
+
+name=twofish
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish.lo"
+
+$as_echo "#define USE_TWOFISH 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-amd64.lo"
+
+ if test x"$avx2support" = xyes ; then
+ # Build with the AVX2 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-avx2-amd64.lo"
+ fi
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-arm.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-aarch64.lo"
+ ;;
+ esac
+fi
+
+
+name=serpent
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent.lo"
+
+$as_echo "#define USE_SERPENT 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the SSE2 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-sse2-amd64.lo"
+ ;;
+ esac
+
+ if test x"$avx2support" = xyes ; then
+ # Build with the AVX2 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-avx2-amd64.lo"
+ fi
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-armv7-neon.lo"
+ fi
+fi
+
+
+name=rfc2268
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rfc2268.lo"
+
+$as_echo "#define USE_RFC2268 1" >>confdefs.h
+
+fi
+
+
+name=seed
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS seed.lo"
+
+$as_echo "#define USE_SEED 1" >>confdefs.h
+
+fi
+
+
+name=camellia
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia.lo camellia-glue.lo"
+
+$as_echo "#define USE_CAMELLIA 1" >>confdefs.h
+
+
+ case "${host}" in
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-arm.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aarch64.lo"
+ ;;
+ esac
+
+ if test x"$avxsupport" = xyes ; then
+ if test x"$aesnisupport" = xyes ; then
+ # Build with the AES-NI/AVX implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx-amd64.lo"
+ fi
+ fi
+
+ if test x"$avx2support" = xyes ; then
+ if test x"$aesnisupport" = xyes ; then
+ # Build with the AES-NI/AVX2 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx2-amd64.lo"
+ fi
+ fi
+fi
+
+
+name=idea
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS idea.lo"
+
+$as_echo "#define USE_IDEA 1" >>confdefs.h
+
+fi
+
+
+name=salsa20
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20.lo"
+
+$as_echo "#define USE_SALSA20 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20-amd64.lo"
+ ;;
+ esac
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20-armv7-neon.lo"
+ fi
+fi
+
+
+name=gost28147
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS gost28147.lo"
+
+$as_echo "#define USE_GOST28147 1" >>confdefs.h
+
+fi
+
+
+name=chacha20
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20.lo"
+
+$as_echo "#define USE_CHACHA20 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-amd64-ssse3.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-amd64-avx2.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-aarch64.lo"
+ ;;
+ powerpc64le-*-*)
+ # Build with the ppc8 vector implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-ppc.lo"
+ ;;
+ powerpc64-*-*)
+ # Build with the ppc8 vector implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-ppc.lo"
+ ;;
+ powerpc-*-*)
+ # Build with the ppc8 vector implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-ppc.lo"
+ ;;
+ s390x-*-*)
+ # Build with the s390x/zSeries vector implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-s390x.lo"
+ ;;
+ esac
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-armv7-neon.lo"
+ fi
+fi
+
+
+name=sm4
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sm4.lo"
+
+$as_echo "#define USE_SM4 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sm4-aesni-avx-amd64.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sm4-aesni-avx2-amd64.lo"
+ ;;
+ esac
+fi
+
+
+name=dsa
+list=$enabled_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS dsa.lo"
+
+$as_echo "#define USE_DSA 1" >>confdefs.h
+
+fi
+
+
+name=rsa
+list=$enabled_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS rsa.lo"
+
+$as_echo "#define USE_RSA 1" >>confdefs.h
+
+fi
+
+
+name=elgamal
+list=$enabled_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS elgamal.lo"
+
+$as_echo "#define USE_ELGAMAL 1" >>confdefs.h
+
+fi
+
+
+name=ecc
+list=$enabled_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS \
+ ecc.lo ecc-curves.lo ecc-misc.lo \
+ ecc-ecdh.lo ecc-ecdsa.lo ecc-eddsa.lo ecc-gost.lo \
+ ecc-sm2.lo"
+
+$as_echo "#define USE_ECC 1" >>confdefs.h
+
+fi
+
+
+name=crc
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc.lo"
+
+$as_echo "#define USE_CRC 1" >>confdefs.h
+
+
+ case "${host}" in
+ i?86-*-* | x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc-intel-pclmul.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-armv8-ce.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-armv8-aarch64-ce.lo"
+ ;;
+ powerpc64le-*-*)
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
+ ;;
+ powerpc64-*-*)
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
+ ;;
+ powerpc-*-*)
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
+ ;;
+ esac
+fi
+
+
+name=gostr3411-94
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ # GOST R 34.11-94 internally uses GOST 28147-89
+
+name=gost28147
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS gostr3411-94.lo"
+
+$as_echo "#define USE_GOST_R_3411_94 1" >>confdefs.h
+
+ fi
+fi
+
+
+name=stribog
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS stribog.lo"
+
+$as_echo "#define USE_GOST_R_3411_12 1" >>confdefs.h
+
+fi
+
+
+name=md2
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md2.lo"
+
+$as_echo "#define USE_MD2 1" >>confdefs.h
+
+fi
+
+
+name=md4
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo"
+
+$as_echo "#define USE_MD4 1" >>confdefs.h
+
+fi
+
+
+name=md5
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md5.lo"
+
+$as_echo "#define USE_MD5 1" >>confdefs.h
+
+fi
+
+
+name=rmd160
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo"
+
+$as_echo "#define USE_RMD160 1" >>confdefs.h
+
+fi
+
+
+name=sha256
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256.lo"
+
+$as_echo "#define USE_SHA256 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ssse3-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-avx-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-avx2-bmi2-amd64.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-armv8-aarch32-ce.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-armv8-aarch64-ce.lo"
+ ;;
+ powerpc64le-*-*)
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
+ ;;
+ powerpc64-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
+ ;;
+ powerpc-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
+ esac
+
+ case "$mpi_cpu_arch" in
+ x86)
+ # Build with the SHAEXT implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-intel-shaext.lo"
+ ;;
+ esac
+fi
+
+
+name=sha512
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512.lo"
+
+$as_echo "#define USE_SHA512 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ssse3-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx2-bmi2-amd64.lo"
+ ;;
+ i?86-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ssse3-i386.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-arm.lo"
+ ;;
+ powerpc64le-*-*)
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
+ ;;
+ powerpc64-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
+ ;;
+ powerpc-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
+ esac
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-armv7-neon.lo"
+ fi
+fi
+
+
+name=sha3
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS keccak.lo"
+
+$as_echo "#define USE_SHA3 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ :
+ ;;
+ esac
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS keccak-armv7-neon.lo"
+ fi
+fi
+
+
+name=tiger
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS tiger.lo"
+
+$as_echo "#define USE_TIGER 1" >>confdefs.h
+
+fi
+
+
+name=whirlpool
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool.lo"
+
+$as_echo "#define USE_WHIRLPOOL 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool-sse2-amd64.lo"
+ ;;
+ esac
+fi
+
+
+name=blake2
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS blake2.lo"
+
+$as_echo "#define USE_BLAKE2 1" >>confdefs.h
+
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS blake2b-amd64-avx2.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS blake2s-amd64-avx.lo"
+ ;;
+ esac
+fi
+
+# SHA-1 needs to be included always for example because it is used by
+# random-csprng.c.
+GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1.lo"
+
+$as_echo "#define USE_SHA1 1" >>confdefs.h
+
+
+case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-ssse3-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx-bmi2-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx2-bmi2-amd64.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-armv7-neon.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-armv8-aarch32-ce.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-armv8-aarch64-ce.lo"
+ ;;
+esac
+
+case "$mpi_cpu_arch" in
+ x86)
+ # Build with the SHAEXT implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-intel-shaext.lo"
+ ;;
+esac
+
+
+name=sm3
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sm3.lo"
+
+$as_echo "#define USE_SM3 1" >>confdefs.h
+
+fi
+
+
+name=scrypt
+list=$enabled_kdfs
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_KDFS="$GCRYPT_KDFS scrypt.lo"
+
+$as_echo "#define USE_SCRYPT 1" >>confdefs.h
+
+fi
+
+
+name=linux
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndlinux.lo"
+
+$as_echo "#define USE_RNDLINUX 1" >>confdefs.h
+
+fi
+
+
+name=unix
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndunix.lo"
+
+$as_echo "#define USE_RNDUNIX 1" >>confdefs.h
+
+fi
+
+
+name=egd
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndegd.lo"
+
+$as_echo "#define USE_RNDEGD 1" >>confdefs.h
+
+fi
+
+
+name=w32
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32.lo"
+
+$as_echo "#define USE_RNDW32 1" >>confdefs.h
+
+fi
+
+
+name=w32ce
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32ce.lo"
+
+$as_echo "#define USE_RNDW32CE 1" >>confdefs.h
+
+fi
+
+
+
+
+
+
+
+LIBGCRYPT_CIPHERS=$enabled_ciphers
+
+LIBGCRYPT_PUBKEY_CIPHERS=$enabled_pubkey_ciphers
+
+LIBGCRYPT_DIGESTS=$enabled_digests
+
+
+# For printing the configuration we need a colon separated list of
+# algorithm names.
+tmp=`echo "$enabled_ciphers" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_CIPHERS "$tmp"
+_ACEOF
+
+tmp=`echo "$enabled_pubkey_ciphers" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_PUBKEY_CIPHERS "$tmp"
+_ACEOF
+
+tmp=`echo "$enabled_digests" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_DIGESTS "$tmp"
+_ACEOF
+
+tmp=`echo "$enabled_kdfs" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_KDFS "$tmp"
+_ACEOF
+
+
+
+#
+# Define conditional sources depending on the used hardware platform.
+# Note that all possible modules must also be listed in
+# src/Makefile.am (EXTRA_libgcrypt_la_SOURCES).
+#
+GCRYPT_HWF_MODULES=
+case "$mpi_cpu_arch" in
+ x86)
+
+$as_echo "#define HAVE_CPU_ARCH_X86 1" >>confdefs.h
+
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-x86.lo"
+ ;;
+ alpha)
+
+$as_echo "#define HAVE_CPU_ARCH_ALPHA 1" >>confdefs.h
+
+ ;;
+ sparc)
+
+$as_echo "#define HAVE_CPU_ARCH_SPARC 1" >>confdefs.h
+
+ ;;
+ mips)
+
+$as_echo "#define HAVE_CPU_ARCH_MIPS 1" >>confdefs.h
+
+ ;;
+ m68k)
+
+$as_echo "#define HAVE_CPU_ARCH_M68K 1" >>confdefs.h
+
+ ;;
+ ppc)
+
+$as_echo "#define HAVE_CPU_ARCH_PPC 1" >>confdefs.h
+
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-ppc.lo"
+ ;;
+ arm)
+
+$as_echo "#define HAVE_CPU_ARCH_ARM 1" >>confdefs.h
+
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-arm.lo"
+ ;;
+ aarch64)
+
+$as_echo "#define HAVE_CPU_ARCH_ARM 1" >>confdefs.h
+
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-arm.lo"
+ ;;
+ s390x)
+
+$as_echo "#define HAVE_CPU_ARCH_S390X 1" >>confdefs.h
+
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-s390x.lo"
+ ;;
+esac
+
+
+
+#
+# Option to disable building of doc file
+#
+build_doc=yes
+# Check whether --enable-doc was given.
+if test "${enable_doc+set}" = set; then :
+ enableval=$enable_doc; build_doc=$enableval
+else
+ build_doc=yes
+fi
+
+ if test "x$build_doc" != xno; then
+ BUILD_DOC_TRUE=
+ BUILD_DOC_FALSE='#'
+else
+ BUILD_DOC_TRUE='#'
+ BUILD_DOC_FALSE=
+fi
+
+
+
+#
+# Provide information about the build.
+#
+BUILD_REVISION="24bd7e82"
+
+
+cat >>confdefs.h <<_ACEOF
+#define BUILD_REVISION "$BUILD_REVISION"
+_ACEOF
+
+
+BUILD_VERSION=`echo "$PACKAGE_VERSION" | sed 's/\([0-9.]*\).*/\1./'`
+BUILD_VERSION="${BUILD_VERSION}9405"
+BUILD_FILEVERSION=`echo "${BUILD_VERSION}" | tr . ,`
+
+
+
+# Check whether --enable-build-timestamp was given.
+if test "${enable_build_timestamp+set}" = set; then :
+ enableval=$enable_build_timestamp; if test "$enableval" = "yes"; then
+ BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
+ else
+ BUILD_TIMESTAMP="$enableval"
+ fi
+else
+ BUILD_TIMESTAMP="<none>"
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define BUILD_TIMESTAMP "$BUILD_TIMESTAMP"
+_ACEOF
+
+
+
+# And create the files.
+ac_config_files="$ac_config_files Makefile m4/Makefile compat/Makefile mpi/Makefile cipher/Makefile random/Makefile doc/Makefile src/Makefile src/gcrypt.h src/libgcrypt-config src/libgcrypt.pc src/versioninfo.rc tests/Makefile"
+
+ac_config_files="$ac_config_files tests/hashtest-256g"
+
+ac_config_files="$ac_config_files tests/basic-disable-all-hwf"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_W32_SYSTEM_TRUE}" && test -z "${HAVE_W32_SYSTEM_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_W32_SYSTEM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_W32CE_SYSTEM_TRUE}" && test -z "${HAVE_W32CE_SYSTEM_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_W32CE_SYSTEM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+if test -z "${USE_RANDOM_DAEMON_TRUE}" && test -z "${USE_RANDOM_DAEMON_FALSE}"; then
+ as_fn_error $? "conditional \"USE_RANDOM_DAEMON\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_O_FLAG_MUNGING_TRUE}" && test -z "${ENABLE_O_FLAG_MUNGING_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_O_FLAG_MUNGING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_INSTRUMENTATION_MUNGING_TRUE}" && test -z "${ENABLE_INSTRUMENTATION_MUNGING_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_INSTRUMENTATION_MUNGING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_LD_VERSION_SCRIPT_TRUE}" && test -z "${HAVE_LD_VERSION_SCRIPT_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_LD_VERSION_SCRIPT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_ADD1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_ADD1_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_ADD1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_SUB1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_SUB1_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_SUB1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_MUL1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL1_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_MUL1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_MUL2_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL2_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_MUL2\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_MUL3_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL3_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_MUL3\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_LSHIFT_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_LSHIFT_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_LSHIFT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_RSHIFT_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_RSHIFT_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_RSHIFT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_UDIV_TRUE}" && test -z "${MPI_MOD_ASM_UDIV_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_UDIV\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_UDIV_QRNND_TRUE}" && test -z "${MPI_MOD_ASM_UDIV_QRNND_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_ASM_UDIV_QRNND\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_ADD1_TRUE}" && test -z "${MPI_MOD_C_MPIH_ADD1_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_MPIH_ADD1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_SUB1_TRUE}" && test -z "${MPI_MOD_C_MPIH_SUB1_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_MPIH_SUB1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_MUL1_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL1_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_MPIH_MUL1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_MUL2_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL2_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_MPIH_MUL2\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_MUL3_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL3_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_MPIH_MUL3\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_LSHIFT_TRUE}" && test -z "${MPI_MOD_C_MPIH_LSHIFT_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_MPIH_LSHIFT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_RSHIFT_TRUE}" && test -z "${MPI_MOD_C_MPIH_RSHIFT_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_MPIH_RSHIFT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_UDIV_TRUE}" && test -z "${MPI_MOD_C_UDIV_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_UDIV\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_UDIV_QRNND_TRUE}" && test -z "${MPI_MOD_C_UDIV_QRNND_FALSE}"; then
+ as_fn_error $? "conditional \"MPI_MOD_C_UDIV_QRNND\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_TRUE}" && test -z "${ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then
+ as_fn_error $? "conditional \"CROSS_COMPILING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_DOC_TRUE}" && test -z "${BUILD_DOC_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_DOC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by libgcrypt $as_me 1.9.2, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_links="$ac_config_links"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Configuration commands:
+$config_commands
+
+Report bugs to <https://bugs.gnupg.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+libgcrypt config.status 1.9.2
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+LD_RC='`$ECHO "$LD_RC" | $SED "$delay_single_quote_subst"`'
+reload_flag_RC='`$ECHO "$reload_flag_RC" | $SED "$delay_single_quote_subst"`'
+reload_cmds_RC='`$ECHO "$reload_cmds_RC" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_RC='`$ECHO "$old_archive_cmds_RC" | $SED "$delay_single_quote_subst"`'
+compiler_RC='`$ECHO "$compiler_RC" | $SED "$delay_single_quote_subst"`'
+GCC_RC='`$ECHO "$GCC_RC" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_RC='`$ECHO "$lt_prog_compiler_no_builtin_flag_RC" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_RC='`$ECHO "$lt_prog_compiler_pic_RC" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_RC='`$ECHO "$lt_prog_compiler_wl_RC" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_RC='`$ECHO "$lt_prog_compiler_static_RC" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_RC='`$ECHO "$lt_cv_prog_compiler_c_o_RC" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_RC='`$ECHO "$archive_cmds_need_lc_RC" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_RC='`$ECHO "$enable_shared_with_static_runtimes_RC" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_RC='`$ECHO "$export_dynamic_flag_spec_RC" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_RC='`$ECHO "$whole_archive_flag_spec_RC" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_RC='`$ECHO "$compiler_needs_object_RC" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_RC='`$ECHO "$old_archive_from_new_cmds_RC" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_RC='`$ECHO "$old_archive_from_expsyms_cmds_RC" | $SED "$delay_single_quote_subst"`'
+archive_cmds_RC='`$ECHO "$archive_cmds_RC" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_RC='`$ECHO "$archive_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`'
+module_cmds_RC='`$ECHO "$module_cmds_RC" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_RC='`$ECHO "$module_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_RC='`$ECHO "$with_gnu_ld_RC" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_RC='`$ECHO "$allow_undefined_flag_RC" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_RC='`$ECHO "$no_undefined_flag_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_RC='`$ECHO "$hardcode_libdir_flag_spec_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_RC='`$ECHO "$hardcode_libdir_separator_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_RC='`$ECHO "$hardcode_direct_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_RC='`$ECHO "$hardcode_direct_absolute_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_RC='`$ECHO "$hardcode_minus_L_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_RC='`$ECHO "$hardcode_shlibpath_var_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_RC='`$ECHO "$hardcode_automatic_RC" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_RC='`$ECHO "$inherit_rpath_RC" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_RC='`$ECHO "$link_all_deplibs_RC" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_RC='`$ECHO "$always_export_symbols_RC" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_RC='`$ECHO "$export_symbols_cmds_RC" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_RC='`$ECHO "$exclude_expsyms_RC" | $SED "$delay_single_quote_subst"`'
+include_expsyms_RC='`$ECHO "$include_expsyms_RC" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_RC='`$ECHO "$prelink_cmds_RC" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_RC='`$ECHO "$postlink_cmds_RC" | $SED "$delay_single_quote_subst"`'
+file_list_spec_RC='`$ECHO "$file_list_spec_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_action_RC='`$ECHO "$hardcode_action_RC" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in AS \
+DLLTOOL \
+OBJDUMP \
+SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+LD_RC \
+reload_flag_RC \
+compiler_RC \
+lt_prog_compiler_no_builtin_flag_RC \
+lt_prog_compiler_pic_RC \
+lt_prog_compiler_wl_RC \
+lt_prog_compiler_static_RC \
+lt_cv_prog_compiler_c_o_RC \
+export_dynamic_flag_spec_RC \
+whole_archive_flag_spec_RC \
+compiler_needs_object_RC \
+with_gnu_ld_RC \
+allow_undefined_flag_RC \
+no_undefined_flag_RC \
+hardcode_libdir_flag_spec_RC \
+hardcode_libdir_separator_RC \
+exclude_expsyms_RC \
+include_expsyms_RC \
+file_list_spec_RC; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_RC \
+old_archive_cmds_RC \
+old_archive_from_new_cmds_RC \
+old_archive_from_expsyms_cmds_RC \
+archive_cmds_RC \
+archive_expsym_cmds_RC \
+module_cmds_RC \
+module_expsym_cmds_RC \
+export_symbols_cmds_RC \
+prelink_cmds_RC \
+postlink_cmds_RC; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+
+prefix=$prefix
+exec_prefix=$exec_prefix
+libdir=$libdir
+datadir=$datadir
+DATADIRNAME=$DATADIRNAME
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ ""$mpi_ln_list"") CONFIG_LINKS="$CONFIG_LINKS "$mpi_ln_list"" ;;
+ "gcrypt-conf") CONFIG_COMMANDS="$CONFIG_COMMANDS gcrypt-conf" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;;
+ "compat/Makefile") CONFIG_FILES="$CONFIG_FILES compat/Makefile" ;;
+ "mpi/Makefile") CONFIG_FILES="$CONFIG_FILES mpi/Makefile" ;;
+ "cipher/Makefile") CONFIG_FILES="$CONFIG_FILES cipher/Makefile" ;;
+ "random/Makefile") CONFIG_FILES="$CONFIG_FILES random/Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "src/gcrypt.h") CONFIG_FILES="$CONFIG_FILES src/gcrypt.h" ;;
+ "src/libgcrypt-config") CONFIG_FILES="$CONFIG_FILES src/libgcrypt-config" ;;
+ "src/libgcrypt.pc") CONFIG_FILES="$CONFIG_FILES src/libgcrypt.pc" ;;
+ "src/versioninfo.rc") CONFIG_FILES="$CONFIG_FILES src/versioninfo.rc" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+ "tests/hashtest-256g") CONFIG_FILES="$CONFIG_FILES tests/hashtest-256g" ;;
+ "tests/basic-disable-all-hwf") CONFIG_FILES="$CONFIG_FILES tests/basic-disable-all-hwf" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+ :L)
+ #
+ # CONFIG_LINK
+ #
+
+ if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then
+ :
+ else
+ # Prefer the file from the source tree if names are identical.
+ if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then
+ ac_source=$srcdir/$ac_source
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5
+$as_echo "$as_me: linking $ac_source to $ac_file" >&6;}
+
+ if test ! -r "$ac_source"; then
+ as_fn_error $? "$ac_source: file not found" "$LINENO" 5
+ fi
+ rm -f "$ac_file"
+
+ # Try a relative symlink, then a hard link, then a copy.
+ case $ac_source in
+ [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;;
+ *) ac_rel_source=$ac_top_build_prefix$ac_source ;;
+ esac
+ ln -s "$ac_rel_source" "$ac_file" 2>/dev/null ||
+ ln "$ac_source" "$ac_file" 2>/dev/null ||
+ cp -p "$ac_source" "$ac_file" ||
+ as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5
+ fi
+ ;;
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ # TODO: see whether this extra hack can be removed once we start
+ # requiring Autoconf 2.70 or later.
+ case $CONFIG_FILES in #(
+ *\'*) :
+ eval set x "$CONFIG_FILES" ;; #(
+ *) :
+ set x $CONFIG_FILES ;; #(
+ *) :
+ ;;
+esac
+ shift
+ # Used to flag and report bootstrapping failures.
+ am_rc=0
+ for am_mf
+ do
+ # Strip MF so we end up with the name of the file.
+ am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile which includes
+ # dependency-tracking related rules and includes.
+ # Grep'ing the whole file directly is not great: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+ || continue
+ am_dirpart=`$as_dirname -- "$am_mf" ||
+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$am_mf" : 'X\(//\)[^/]' \| \
+ X"$am_mf" : 'X\(//\)$' \| \
+ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$am_mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ am_filepart=`$as_basename -- "$am_mf" ||
+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$am_mf" : 'X\(//\)$' \| \
+ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$am_mf" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { echo "$as_me:$LINENO: cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles" >&5
+ (cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } || am_rc=$?
+ done
+ if test $am_rc -ne 0; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Something went wrong bootstrapping makefile fragments
+ for automatic dependency tracking. Try re-running configure with the
+ '--disable-dependency-tracking' option to at least be able to build
+ the package (albeit without support for automatic dependency tracking).
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ { am_dirpart=; unset am_dirpart;}
+ { am_filepart=; unset am_filepart;}
+ { am_mf=; unset am_mf;}
+ { am_rc=; unset am_rc;}
+ rm -f conftest-deps.mk
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from https://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="RC "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Assembler program.
+AS=$lt_AS
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$lt_OBJDUMP
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ if test x"$xsi_shell" = xyes; then
+ sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\ # positional parameters, so assign one to ordinary parameter first.\
+\ func_stripname_result=${3}\
+\ func_stripname_result=${func_stripname_result#"${1}"}\
+\ func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\ func_split_long_opt_name=${1%%=*}\
+\ func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\ func_split_short_opt_arg=${1#??}\
+\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\ case ${1} in\
+\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\ *) func_lo2o_result=${1} ;;\
+\ esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+ func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+ func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+ func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+ eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\ func_quote_for_eval "${2}"\
+\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: RC
+
+# The linker used to build libraries.
+LD=$lt_LD_RC
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_RC
+reload_cmds=$lt_reload_cmds_RC
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_RC
+
+# A language specific compiler.
+CC=$lt_compiler_RC
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_RC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_RC
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_RC
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_RC
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_RC
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_RC
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_RC
+archive_expsym_cmds=$lt_archive_expsym_cmds_RC
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_RC
+module_expsym_cmds=$lt_module_expsym_cmds_RC
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_RC
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_RC
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_RC
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_RC
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_RC
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_RC
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_RC
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_RC
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_RC
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_RC
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_RC
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_RC
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_RC
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_RC
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_RC
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_RC
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_RC
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_RC
+
+# ### END LIBTOOL TAG CONFIG: RC
+_LT_EOF
+
+ ;;
+ "gcrypt-conf":C)
+chmod +x src/libgcrypt-config
+ ;;
+ "tests/hashtest-256g":F) chmod +x tests/hashtest-256g ;;
+ "tests/basic-disable-all-hwf":F) chmod +x tests/basic-disable-all-hwf ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+
+detection_module="${GCRYPT_HWF_MODULES%.lo}"
+test -n "$detection_module" || detection_module="none"
+
+# Give some feedback
+
+ echo " " 1>&6
+
+
+ echo " Libgcrypt v${VERSION} has been configured as follows:" 1>&6
+
+
+ echo " " 1>&6
+
+
+ echo " Platform: $PRINTABLE_OS_NAME ($host)" 1>&6
+
+
+ echo " Hardware detection module: $detection_module" 1>&6
+
+
+ tmp=" Enabled cipher algorithms:"
+ tmpi="abc"
+ if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+ echo "$tmp $enabled_ciphers" 1>&6
+ else
+ tmpi=`echo "$tmp"| sed 's/./ /g'`
+ echo $enabled_ciphers EOF | tr ' ' '\n' | \
+ while read word; do
+ if test "${#tmp}" -gt 70 ; then
+ echo "$tmp" 1>&6
+ tmp="$tmpi"
+ fi
+ if test "$word" = "EOF" ; then
+ echo "$tmp" 1>&6
+ else
+ tmp="$tmp $word"
+ fi
+ done
+ fi
+
+
+ tmp=" Enabled digest algorithms:"
+ tmpi="abc"
+ if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+ echo "$tmp $enabled_digests" 1>&6
+ else
+ tmpi=`echo "$tmp"| sed 's/./ /g'`
+ echo $enabled_digests EOF | tr ' ' '\n' | \
+ while read word; do
+ if test "${#tmp}" -gt 70 ; then
+ echo "$tmp" 1>&6
+ tmp="$tmpi"
+ fi
+ if test "$word" = "EOF" ; then
+ echo "$tmp" 1>&6
+ else
+ tmp="$tmp $word"
+ fi
+ done
+ fi
+
+
+ tmp=" Enabled kdf algorithms: "
+ tmpi="abc"
+ if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+ echo "$tmp $enabled_kdfs" 1>&6
+ else
+ tmpi=`echo "$tmp"| sed 's/./ /g'`
+ echo $enabled_kdfs EOF | tr ' ' '\n' | \
+ while read word; do
+ if test "${#tmp}" -gt 70 ; then
+ echo "$tmp" 1>&6
+ tmp="$tmpi"
+ fi
+ if test "$word" = "EOF" ; then
+ echo "$tmp" 1>&6
+ else
+ tmp="$tmp $word"
+ fi
+ done
+ fi
+
+
+ tmp=" Enabled pubkey algorithms:"
+ tmpi="abc"
+ if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+ echo "$tmp $enabled_pubkey_ciphers" 1>&6
+ else
+ tmpi=`echo "$tmp"| sed 's/./ /g'`
+ echo $enabled_pubkey_ciphers EOF | tr ' ' '\n' | \
+ while read word; do
+ if test "${#tmp}" -gt 70 ; then
+ echo "$tmp" 1>&6
+ tmp="$tmpi"
+ fi
+ if test "$word" = "EOF" ; then
+ echo "$tmp" 1>&6
+ else
+ tmp="$tmp $word"
+ fi
+ done
+ fi
+
+
+ echo " Random number generator: $random" 1>&6
+
+
+ echo " Try using jitter entropy: $jentsupport" 1>&6
+
+
+ echo " Using linux capabilities: $use_capabilities" 1>&6
+
+
+ echo " Try using Padlock crypto: $padlocksupport" 1>&6
+
+
+ echo " Try using AES-NI crypto: $aesnisupport" 1>&6
+
+
+ echo " Try using Intel SHAEXT: $shaextsupport" 1>&6
+
+
+ echo " Try using Intel PCLMUL: $pclmulsupport" 1>&6
+
+
+ echo " Try using Intel SSE4.1: $sse41support" 1>&6
+
+
+ echo " Try using DRNG (RDRAND): $drngsupport" 1>&6
+
+
+ echo " Try using Intel AVX: $avxsupport" 1>&6
+
+
+ echo " Try using Intel AVX2: $avx2support" 1>&6
+
+
+ echo " Try using ARM NEON: $neonsupport" 1>&6
+
+
+ echo " Try using ARMv8 crypto: $armcryptosupport" 1>&6
+
+
+ echo " Try using PPC crypto: $ppccryptosupport" 1>&6
+
+
+ echo " " 1>&6
+
+
+if test "x${gpg_config_script_warn}" != x; then
+cat <<G10EOF
+ Mismatches between the target platform and the to
+ be used libraries have been been detected for:
+ ${gpg_config_script_warn}
+ Please check above for warning messages.
+
+G10EOF
+fi
+
+if test "$gcry_cv_gcc_attribute_aligned" != "yes" ; then
+cat <<G10EOF
+ Please not that your compiler does not support the GCC style
+ aligned attribute. Using this software may evoke bus errors.
+
+G10EOF
+fi
+
+if test -n "$gpl"; then
+ echo "Please note that you are building a version of Libgcrypt with"
+ echo " $gpl"
+ echo "included. These parts are licensed under the GPL and thus the"
+ echo "use of this library has to comply with the conditions of the GPL."
+ echo ""
+fi
diff --git a/comm/third_party/libgcrypt/configure.ac b/comm/third_party/libgcrypt/configure.ac
new file mode 100644
index 0000000000..e6104d5e0a
--- /dev/null
+++ b/comm/third_party/libgcrypt/configure.ac
@@ -0,0 +1,3257 @@
+# Configure.ac script for Libgcrypt
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
+# 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2012-2021 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 <http://www.gnu.org/licenses/>.
+
+# (Process this file with autoconf to produce a configure script.)
+AC_REVISION($Revision$)
+AC_PREREQ([2.60])
+min_automake_version="1.14"
+
+# To build a release you need to create a tag with the version number
+# (git tag -s libgcrypt-n.m.k) and run "./autogen.sh --force". Please
+# bump the version number immediately after the release and do another
+# commit and push so that the git magic is able to work. See below
+# for the LT versions.
+m4_define([mym4_package],[libgcrypt])
+m4_define([mym4_major], [1])
+m4_define([mym4_minor], [9])
+m4_define([mym4_micro], [2])
+
+# Below is m4 magic to extract and compute the git revision number,
+# the decimalized short revision number, a beta version string and a
+# flag indicating a development version (mym4_isbeta). Note that the
+# m4 processing is done by autoconf and not during the configure run.
+m4_define([mym4_verslist], m4_split(m4_esyscmd([./autogen.sh --find-version] \
+ mym4_package mym4_major mym4_minor mym4_micro),[:]))
+m4_define([mym4_isbeta], m4_argn(2, mym4_verslist))
+m4_define([mym4_version], m4_argn(4, mym4_verslist))
+m4_define([mym4_revision], m4_argn(7, mym4_verslist))
+m4_define([mym4_revision_dec], m4_argn(8, mym4_verslist))
+m4_esyscmd([echo ]mym4_version[>VERSION])
+AC_INIT([mym4_package],[mym4_version],[https://bugs.gnupg.org])
+
+# LT Version numbers, remember to change them just *before* a release.
+# (Code changed: REVISION++)
+# (Interfaces added/removed/changed: CURRENT++, REVISION=0)
+# (Interfaces added: AGE++)
+# (Interfaces removed: AGE=0)
+#
+# (Interfaces removed: CURRENT++, AGE=0, REVISION=0)
+# (Interfaces added: CURRENT++, AGE++, REVISION=0)
+# (No interfaces changed: REVISION++)
+LIBGCRYPT_LT_CURRENT=23
+LIBGCRYPT_LT_AGE=3
+LIBGCRYPT_LT_REVISION=2
+################################################
+
+AC_SUBST(LIBGCRYPT_LT_CURRENT)
+AC_SUBST(LIBGCRYPT_LT_AGE)
+AC_SUBST(LIBGCRYPT_LT_REVISION)
+
+# If the API is changed in an incompatible way: increment the next counter.
+#
+# 1.6: ABI and API change but the change is to most users irrelevant
+# and thus the API version number has not been incremented.
+LIBGCRYPT_CONFIG_API_VERSION=1
+
+# If you change the required gpg-error version, please remove
+# unnecessary error code defines in src/gcrypt-int.h.
+NEED_GPG_ERROR_VERSION=1.27
+
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_SRCDIR([src/libgcrypt.vers])
+AM_INIT_AUTOMAKE([serial-tests dist-bzip2])
+AC_CONFIG_HEADER(config.h)
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_LIBOBJ_DIR([compat])
+AC_CANONICAL_HOST
+AM_MAINTAINER_MODE
+AM_SILENT_RULES
+
+AC_ARG_VAR(SYSROOT,[locate config scripts also below that directory])
+
+AH_TOP([
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+#define _GCRYPT_CONFIG_H_INCLUDED
+
+/* Enable gpg-error's strerror macro for W32CE. */
+#define GPG_ERR_ENABLE_ERRNO_MACROS 1
+])
+
+AH_BOTTOM([
+#define _GCRYPT_IN_LIBGCRYPT 1
+
+/* Add .note.gnu.property section for Intel CET in assembler sources
+ when CET is enabled. */
+#if defined(__ASSEMBLER__) && defined(__CET__)
+# include <cet.h>
+#endif
+
+/* If the configure check for endianness has been disabled, get it from
+ OS macros. This is intended for making fat binary builds on OS X. */
+#ifdef DISABLED_ENDIAN_CHECK
+# if defined(__BIG_ENDIAN__)
+# define WORDS_BIGENDIAN 1
+# elif defined(__LITTLE_ENDIAN__)
+# undef WORDS_BIGENDIAN
+# else
+# error "No endianness found"
+# endif
+#endif /*DISABLED_ENDIAN_CHECK*/
+
+/* We basically use the original Camellia source. Make sure the symbols
+ properly prefixed. */
+#define CAMELLIA_EXT_SYM_PREFIX _gcry_
+
+#endif /*_GCRYPT_CONFIG_H_INCLUDED*/
+])
+
+AH_VERBATIM([_REENTRANT],
+[/* To allow the use of Libgcrypt in multithreaded programs we have to use
+ special features from the library. */
+#ifndef _REENTRANT
+# define _REENTRANT 1
+#endif
+])
+
+
+######################
+## Basic checks. ### (we need some results later on (e.g. $GCC)
+######################
+
+AC_PROG_MAKE_SET
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+# AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_PROG_CC
+AC_PROG_CPP
+AM_PROG_CC_C_O
+AM_PROG_AS
+AC_SEARCH_LIBS([strerror],[cposix])
+AC_PROG_INSTALL
+AC_PROG_AWK
+
+AC_USE_SYSTEM_EXTENSIONS
+
+# Taken from mpfr-4.0.1, then modified for LDADD_FOR_TESTS_KLUDGE
+dnl Under Linux, make sure that the old dtags are used if LD_LIBRARY_PATH
+dnl is defined. The issue is that with the new dtags, LD_LIBRARY_PATH has
+dnl the precedence over the run path, so that if a compatible MPFR library
+dnl is installed in some directory from $LD_LIBRARY_PATH, then the tested
+dnl MPFR library will be this library instead of the MPFR library from the
+dnl build tree. Other OS with the same issue might be added later.
+dnl
+dnl References:
+dnl https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=859732
+dnl http://lists.gnu.org/archive/html/libtool/2017-05/msg00000.html
+dnl
+dnl We need to check whether --disable-new-dtags is supported as alternate
+dnl linkers may be used (e.g., with tcc: CC=tcc LD=tcc).
+dnl
+case $host in
+ *-*-linux*)
+ if test -n "$LD_LIBRARY_PATH"; then
+ saved_LDFLAGS="$LDFLAGS"
+ LDADD_FOR_TESTS_KLUDGE="-Wl,--disable-new-dtags"
+ LDFLAGS="$LDFLAGS $LDADD_FOR_TESTS_KLUDGE"
+ AC_MSG_CHECKING(whether --disable-new-dtags is supported by the linker)
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+int main (void) { return 0; }
+ ]])],
+ [AC_MSG_RESULT(yes (use it since LD_LIBRARY_PATH is set))],
+ [AC_MSG_RESULT(no)
+ LDADD_FOR_TESTS_KLUDGE=""
+ ])
+ LDFLAGS="$saved_LDFLAGS"
+ fi
+ ;;
+esac
+AC_SUBST([LDADD_FOR_TESTS_KLUDGE])
+
+VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x%02x" mym4_major \
+ mym4_minor mym4_micro)
+AC_SUBST(VERSION_NUMBER)
+
+# We need to compile and run a program on the build machine.
+AX_CC_FOR_BUILD
+
+
+LT_PREREQ([2.2.6])
+LT_INIT([win32-dll disable-static])
+LT_LANG([Windows Resource])
+
+
+##########################
+## General definitions. ##
+##########################
+
+# Used by libgcrypt-config
+LIBGCRYPT_CONFIG_LIBS="-lgcrypt"
+LIBGCRYPT_CONFIG_CFLAGS=""
+LIBGCRYPT_CONFIG_HOST="$host"
+
+# Definitions for symmetric ciphers.
+available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed"
+available_ciphers="$available_ciphers camellia idea salsa20 gost28147 chacha20"
+available_ciphers="$available_ciphers sm4"
+enabled_ciphers=""
+
+# Definitions for public-key ciphers.
+available_pubkey_ciphers="dsa elgamal rsa ecc"
+enabled_pubkey_ciphers=""
+
+# Definitions for message digests.
+available_digests="crc gostr3411-94 md2 md4 md5 rmd160 sha1 sha256 sha512"
+available_digests="$available_digests sha3 tiger whirlpool stribog blake2"
+available_digests="$available_digests sm3"
+enabled_digests=""
+
+# Definitions for kdfs (optional ones)
+available_kdfs="s2k pkdf2 scrypt"
+enabled_kdfs=""
+
+# Definitions for random modules.
+available_random_modules="linux egd unix"
+auto_random_modules="$available_random_modules"
+
+# Supported thread backends.
+LIBGCRYPT_THREAD_MODULES=""
+
+# Other definitions.
+have_w32_system=no
+have_w32ce_system=no
+have_pthread=no
+
+
+# Setup some stuff depending on host.
+case "${host}" in
+ *-*-mingw32*)
+ ac_cv_have_dev_random=no
+ have_w32_system=yes
+ case "${host}" in
+ *-mingw32ce*)
+ have_w32ce_system=yes
+ available_random_modules="w32ce"
+ ;;
+ *)
+ available_random_modules="w32"
+ ;;
+ esac
+ AC_DEFINE(USE_ONLY_8DOT3,1,
+ [set this to limit filenames to the 8.3 format])
+ AC_DEFINE(HAVE_DRIVE_LETTERS,1,
+ [defined if we must run on a stupid file system])
+ AC_DEFINE(HAVE_DOSISH_SYSTEM,1,
+ [defined if we run on some of the PCDOS like systems
+ (DOS, Windoze. OS/2) with special properties like
+ no file modes])
+ ;;
+
+ i?86-emx-os2 | i?86-*-os2*emx)
+ # OS/2 with the EMX environment
+ ac_cv_have_dev_random=no
+ AC_DEFINE(HAVE_DRIVE_LETTERS)
+ AC_DEFINE(HAVE_DOSISH_SYSTEM)
+ ;;
+
+ i?86-*-msdosdjgpp*)
+ # DOS with the DJGPP environment
+ ac_cv_have_dev_random=no
+ AC_DEFINE(HAVE_DRIVE_LETTERS)
+ AC_DEFINE(HAVE_DOSISH_SYSTEM)
+ ;;
+
+ *-*-hpux*)
+ if test -z "$GCC" ; then
+ CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
+ fi
+ ;;
+ *-dec-osf4*)
+ if test -z "$GCC" ; then
+ # Suppress all warnings
+ # to get rid of the unsigned/signed char mismatch warnings.
+ CFLAGS="$CFLAGS -w"
+ fi
+ ;;
+ m68k-atari-mint)
+ ;;
+ *-apple-darwin*)
+ AC_DEFINE(_DARWIN_C_SOURCE, 900000L,
+ Expose all libc features (__DARWIN_C_FULL).)
+ AC_DEFINE(USE_POSIX_SPAWN_FOR_TESTS, 1,
+ [defined if we use posix_spawn in test program])
+ AC_CHECK_HEADERS(spawn.h)
+ ;;
+ *)
+ ;;
+esac
+
+if test "$have_w32_system" = yes; then
+ AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system])
+ if test "$have_w32ce_system" = yes; then
+ AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE])
+ fi
+fi
+AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes)
+AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes)
+
+
+
+# A printable OS Name is sometimes useful.
+case "${host}" in
+ *-*-mingw32ce*)
+ PRINTABLE_OS_NAME="W32CE"
+ ;;
+
+ *-*-mingw32*)
+ PRINTABLE_OS_NAME="W32"
+ ;;
+
+ i?86-emx-os2 | i?86-*-os2*emx )
+ PRINTABLE_OS_NAME="OS/2"
+ ;;
+
+ i?86-*-msdosdjgpp*)
+ PRINTABLE_OS_NAME="MSDOS/DJGPP"
+ ;;
+
+ *-linux*)
+ PRINTABLE_OS_NAME="GNU/Linux"
+ ;;
+
+ *)
+ PRINTABLE_OS_NAME=`uname -s || echo "Unknown"`
+ ;;
+esac
+
+NAME_OF_DEV_RANDOM="/dev/random"
+NAME_OF_DEV_URANDOM="/dev/urandom"
+
+AC_ARG_ENABLE(endian-check,
+ AS_HELP_STRING([--disable-endian-check],
+ [disable the endian check and trust the OS provided macros]),
+ endiancheck=$enableval,endiancheck=yes)
+if test x"$endiancheck" = xyes ; then
+ AC_C_BIGENDIAN
+else
+ AC_DEFINE(DISABLED_ENDIAN_CHECK,1,[configure did not test for endianness])
+fi
+
+AC_CHECK_SIZEOF(unsigned short, 2)
+AC_CHECK_SIZEOF(unsigned int, 4)
+AC_CHECK_SIZEOF(unsigned long, 4)
+AC_CHECK_SIZEOF(unsigned long long, 0)
+AC_CHECK_SIZEOF(void *, 0)
+
+AC_TYPE_UINTPTR_T
+
+if test "$ac_cv_sizeof_unsigned_short" = "0" \
+ || test "$ac_cv_sizeof_unsigned_int" = "0" \
+ || test "$ac_cv_sizeof_unsigned_long" = "0"; then
+ AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]);
+fi
+
+# Ensure that we have UINT64_C before we bother to check for uint64_t
+AC_CACHE_CHECK([for UINT64_C],[gnupg_cv_uint64_c_works],
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <inttypes.h>]],
+ [[uint64_t foo=UINT64_C(42);]])],
+ gnupg_cv_uint64_c_works=yes,gnupg_cv_uint64_c_works=no))
+if test "$gnupg_cv_uint64_c_works" = "yes" ; then
+ AC_CHECK_SIZEOF(uint64_t)
+fi
+
+# Do we have any 64-bit data types?
+if test "$ac_cv_sizeof_unsigned_int" != "8" \
+ && test "$ac_cv_sizeof_unsigned_long" != "8" \
+ && test "$ac_cv_sizeof_unsigned_long_long" != "8" \
+ && test "$ac_cv_sizeof_uint64_t" != "8"; then
+ AC_MSG_ERROR([[
+***
+*** No 64-bit integer type available.
+*** It is not possible to build Libgcrypt on this platform.
+***]])
+fi
+
+
+# If not specified otherwise, all available algorithms will be
+# included.
+default_ciphers="$available_ciphers"
+default_pubkey_ciphers="$available_pubkey_ciphers"
+default_digests="$available_digests"
+default_kdfs="$available_kdfs"
+# Blacklist MD2 by default
+default_digests=`echo $default_digests | sed -e 's/md2//g'`
+
+# Substitutions to set generated files in a Emacs buffer to read-only.
+AC_SUBST(emacs_local_vars_begin, ['Local Variables:'])
+AC_SUBST(emacs_local_vars_read_only, ['buffer-read-only: t'])
+AC_SUBST(emacs_local_vars_end, ['End:'])
+
+############################
+## Command line switches. ##
+############################
+
+# Implementation of the --enable-ciphers switch.
+AC_ARG_ENABLE(ciphers,
+ AS_HELP_STRING([--enable-ciphers=ciphers],
+ [select the symmetric ciphers to include]),
+ [enabled_ciphers=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`],
+ [enabled_ciphers=""])
+if test "x$enabled_ciphers" = "x" \
+ -o "$enabled_ciphers" = "yes" \
+ -o "$enabled_ciphers" = "no"; then
+ enabled_ciphers=$default_ciphers
+fi
+AC_MSG_CHECKING([which symmetric ciphers to include])
+for cipher in $enabled_ciphers; do
+ LIST_MEMBER($cipher, $available_ciphers)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported cipher "$cipher" specified])
+ fi
+done
+AC_MSG_RESULT([$enabled_ciphers])
+
+# Implementation of the --enable-pubkey-ciphers switch.
+AC_ARG_ENABLE(pubkey-ciphers,
+ AS_HELP_STRING([--enable-pubkey-ciphers=ciphers],
+ [select the public-key ciphers to include]),
+ [enabled_pubkey_ciphers=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`],
+ [enabled_pubkey_ciphers=""])
+if test "x$enabled_pubkey_ciphers" = "x" \
+ -o "$enabled_pubkey_ciphers" = "yes" \
+ -o "$enabled_pubkey_ciphers" = "no"; then
+ enabled_pubkey_ciphers=$default_pubkey_ciphers
+fi
+AC_MSG_CHECKING([which public-key ciphers to include])
+for cipher in $enabled_pubkey_ciphers; do
+ LIST_MEMBER($cipher, $available_pubkey_ciphers)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported public-key cipher specified])
+ fi
+done
+AC_MSG_RESULT([$enabled_pubkey_ciphers])
+
+# Implementation of the --enable-digests switch.
+AC_ARG_ENABLE(digests,
+ AS_HELP_STRING([--enable-digests=digests],
+ [select the message digests to include]),
+ [enabled_digests=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`],
+ [enabled_digests=""])
+if test "x$enabled_digests" = "x" \
+ -o "$enabled_digests" = "yes" \
+ -o "$enabled_digests" = "no"; then
+ enabled_digests=$default_digests
+fi
+AC_MSG_CHECKING([which message digests to include])
+for digest in $enabled_digests; do
+ LIST_MEMBER($digest, $available_digests)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported message digest specified])
+ fi
+done
+AC_MSG_RESULT([$enabled_digests])
+
+# Implementation of the --enable-kdfs switch.
+AC_ARG_ENABLE(kdfs,
+ AS_HELP_STRING([--enable-kfds=kdfs],
+ [select the KDFs to include]),
+ [enabled_kdfs=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`],
+ [enabled_kdfs=""])
+if test "x$enabled_kdfs" = "x" \
+ -o "$enabled_kdfs" = "yes" \
+ -o "$enabled_kdfs" = "no"; then
+ enabled_kdfs=$default_kdfs
+fi
+AC_MSG_CHECKING([which key derivation functions to include])
+for kdf in $enabled_kdfs; do
+ LIST_MEMBER($kdf, $available_kdfs)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported key derivation function specified])
+ fi
+done
+AC_MSG_RESULT([$enabled_kdfs])
+
+# Implementation of the --enable-random switch.
+AC_ARG_ENABLE(random,
+ AS_HELP_STRING([--enable-random=name],
+ [select which random number generator to use]),
+ [random=`echo $enableval | tr '[A-Z]' '[a-z]'`],
+ [])
+if test "x$random" = "x" -o "$random" = "yes" -o "$random" = "no"; then
+ random=default
+fi
+AC_MSG_CHECKING([which random module to use])
+if test "$random" != "default" -a "$random" != "auto"; then
+ LIST_MEMBER($random, $available_random_modules)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported random module specified])
+ fi
+fi
+AC_MSG_RESULT($random)
+
+# Implementation of the --disable-dev-random switch.
+AC_MSG_CHECKING([whether use of /dev/random is requested])
+AC_ARG_ENABLE(dev-random,
+[ --disable-dev-random disable the use of dev random],
+ try_dev_random=$enableval, try_dev_random=yes)
+AC_MSG_RESULT($try_dev_random)
+
+# Implementation of the --with-egd-socket switch.
+AC_ARG_WITH(egd-socket,
+ [ --with-egd-socket=NAME Use NAME for the EGD socket)],
+ egd_socket_name="$withval", egd_socket_name="" )
+AC_DEFINE_UNQUOTED(EGD_SOCKET_NAME, "$egd_socket_name",
+ [Define if you don't want the default EGD socket name.
+ For details see cipher/rndegd.c])
+
+# Implementation of the --enable-random-daemon
+AC_MSG_CHECKING([whether the experimental random daemon is requested])
+AC_ARG_ENABLE([random-daemon],
+ AS_HELP_STRING([--enable-random-daemon],
+ [Build and support the experimental gcryptrnd]),
+ [use_random_daemon=$enableval],
+ [use_random_daemon=no])
+AC_MSG_RESULT($use_random_daemon)
+if test x$use_random_daemon = xyes ; then
+ AC_DEFINE(USE_RANDOM_DAEMON,1,
+ [Define to support the experimental random daemon])
+fi
+AM_CONDITIONAL(USE_RANDOM_DAEMON, test x$use_random_daemon = xyes)
+
+
+# Implementation of --disable-asm.
+AC_MSG_CHECKING([whether MPI and cipher assembler modules are requested])
+AC_ARG_ENABLE([asm],
+ AS_HELP_STRING([--disable-asm],
+ [Disable MPI and cipher assembler modules]),
+ [try_asm_modules=$enableval],
+ [try_asm_modules=yes])
+AC_MSG_RESULT($try_asm_modules)
+
+# Implementation of the --enable-m-guard switch.
+AC_MSG_CHECKING([whether memory guard is requested])
+AC_ARG_ENABLE(m-guard,
+ AS_HELP_STRING([--enable-m-guard],
+ [Enable memory guard facility]),
+ [use_m_guard=$enableval], [use_m_guard=no])
+AC_MSG_RESULT($use_m_guard)
+if test "$use_m_guard" = yes ; then
+ AC_DEFINE(M_GUARD,1,[Define to use the (obsolete) malloc guarding feature])
+fi
+
+# Implementation of the --enable-large-data-tests switch.
+AC_MSG_CHECKING([whether to run large data tests])
+AC_ARG_ENABLE(large-data-tests,
+ AS_HELP_STRING([--enable-large-data-tests],
+ [Enable the real long ruinning large data tests]),
+ large_data_tests=$enableval,large_data_tests=no)
+AC_MSG_RESULT($large_data_tests)
+AC_SUBST(RUN_LARGE_DATA_TESTS, $large_data_tests)
+
+# Implementation of --enable-force-soft-hwfeatures
+AC_MSG_CHECKING([whether 'soft' HW feature bits are forced on])
+AC_ARG_ENABLE([force-soft-hwfeatures],
+ AS_HELP_STRING([--enable-force-soft-hwfeatures],
+ [Enable forcing 'soft' HW feature bits on]),
+ [force_soft_hwfeatures=$enableval],
+ [force_soft_hwfeatures=no])
+AC_MSG_RESULT($force_soft_hwfeatures)
+
+
+# Implementation of the --with-capabilities switch.
+# Check whether we want to use Linux capabilities
+AC_MSG_CHECKING([whether use of capabilities is requested])
+AC_ARG_WITH(capabilities,
+ AS_HELP_STRING([--with-capabilities],
+ [Use linux capabilities [default=no]]),
+ [use_capabilities="$withval"],[use_capabilities=no])
+AC_MSG_RESULT($use_capabilities)
+
+# Implementation of the --enable-hmac-binary-check.
+AC_MSG_CHECKING([whether a HMAC binary check is requested])
+AC_ARG_ENABLE(hmac-binary-check,
+ AS_HELP_STRING([--enable-hmac-binary-check],
+ [Enable library integrity check]),
+ [use_hmac_binary_check=$enableval],
+ [use_hmac_binary_check=no])
+AC_MSG_RESULT($use_hmac_binary_check)
+if test "$use_hmac_binary_check" = yes ; then
+ AC_DEFINE(ENABLE_HMAC_BINARY_CHECK,1,
+ [Define to support an HMAC based integrity check])
+fi
+
+
+# Implementation of the --disable-jent-support switch.
+AC_MSG_CHECKING([whether jitter entropy support is requested])
+AC_ARG_ENABLE(jent-support,
+ AS_HELP_STRING([--disable-jent-support],
+ [Disable support for the Jitter entropy collector]),
+ jentsupport=$enableval,jentsupport=yes)
+AC_MSG_RESULT($jentsupport)
+
+# Implementation of the --disable-padlock-support switch.
+AC_MSG_CHECKING([whether padlock support is requested])
+AC_ARG_ENABLE(padlock-support,
+ AS_HELP_STRING([--disable-padlock-support],
+ [Disable support for the PadLock Engine of VIA processors]),
+ padlocksupport=$enableval,padlocksupport=yes)
+AC_MSG_RESULT($padlocksupport)
+
+# Implementation of the --disable-aesni-support switch.
+AC_MSG_CHECKING([whether AESNI support is requested])
+AC_ARG_ENABLE(aesni-support,
+ AS_HELP_STRING([--disable-aesni-support],
+ [Disable support for the Intel AES-NI instructions]),
+ aesnisupport=$enableval,aesnisupport=yes)
+AC_MSG_RESULT($aesnisupport)
+
+# Implementation of the --disable-shaext-support switch.
+AC_MSG_CHECKING([whether SHAEXT support is requested])
+AC_ARG_ENABLE(shaext-support,
+ AS_HELP_STRING([--disable-shaext-support],
+ [Disable support for the Intel SHAEXT instructions]),
+ shaextsupport=$enableval,shaextsupport=yes)
+AC_MSG_RESULT($shaextsupport)
+
+# Implementation of the --disable-pclmul-support switch.
+AC_MSG_CHECKING([whether PCLMUL support is requested])
+AC_ARG_ENABLE(pclmul-support,
+ AS_HELP_STRING([--disable-pclmul-support],
+ [Disable support for the Intel PCLMUL instructions]),
+ pclmulsupport=$enableval,pclmulsupport=yes)
+AC_MSG_RESULT($pclmulsupport)
+
+# Implementation of the --disable-sse41-support switch.
+AC_MSG_CHECKING([whether SSE4.1 support is requested])
+AC_ARG_ENABLE(sse41-support,
+ AS_HELP_STRING([--disable-sse41-support],
+ [Disable support for the Intel SSE4.1 instructions]),
+ sse41support=$enableval,sse41support=yes)
+AC_MSG_RESULT($sse41support)
+
+# Implementation of the --disable-drng-support switch.
+AC_MSG_CHECKING([whether DRNG support is requested])
+AC_ARG_ENABLE(drng-support,
+ AS_HELP_STRING([--disable-drng-support],
+ [Disable support for the Intel DRNG (RDRAND instruction)]),
+ drngsupport=$enableval,drngsupport=yes)
+AC_MSG_RESULT($drngsupport)
+
+# Implementation of the --disable-avx-support switch.
+AC_MSG_CHECKING([whether AVX support is requested])
+AC_ARG_ENABLE(avx-support,
+ AS_HELP_STRING([--disable-avx-support],
+ [Disable support for the Intel AVX instructions]),
+ avxsupport=$enableval,avxsupport=yes)
+AC_MSG_RESULT($avxsupport)
+
+# Implementation of the --disable-avx2-support switch.
+AC_MSG_CHECKING([whether AVX2 support is requested])
+AC_ARG_ENABLE(avx2-support,
+ AS_HELP_STRING([--disable-avx2-support],
+ [Disable support for the Intel AVX2 instructions]),
+ avx2support=$enableval,avx2support=yes)
+AC_MSG_RESULT($avx2support)
+
+# Implementation of the --disable-neon-support switch.
+AC_MSG_CHECKING([whether NEON support is requested])
+AC_ARG_ENABLE(neon-support,
+ AS_HELP_STRING([--disable-neon-support],
+ [Disable support for the ARM NEON instructions]),
+ neonsupport=$enableval,neonsupport=yes)
+AC_MSG_RESULT($neonsupport)
+
+# Implementation of the --disable-arm-crypto-support switch.
+AC_MSG_CHECKING([whether ARMv8 Crypto Extension support is requested])
+AC_ARG_ENABLE(arm-crypto-support,
+ AS_HELP_STRING([--disable-arm-crypto-support],
+ [Disable support for the ARMv8 Crypto Extension instructions]),
+ armcryptosupport=$enableval,armcryptosupport=yes)
+AC_MSG_RESULT($armcryptosupport)
+
+# Implementation of the --disable-ppc-crypto-support switch.
+AC_MSG_CHECKING([whether PPC crypto support is requested])
+AC_ARG_ENABLE(ppc-crypto-support,
+ AS_HELP_STRING([--disable-ppc-crypto-support],
+ [Disable support for the PPC crypto instructions introduced in POWER 8 (PowerISA 2.07)]),
+ ppccryptosupport=$enableval,ppccryptosupport=yes)
+AC_MSG_RESULT($ppccryptosupport)
+
+# Implementation of the --disable-O-flag-munging switch.
+AC_MSG_CHECKING([whether a -O flag munging is requested])
+AC_ARG_ENABLE([O-flag-munging],
+ AS_HELP_STRING([--disable-O-flag-munging],
+ [Disable modification of the cc -O flag]),
+ [enable_o_flag_munging=$enableval],
+ [enable_o_flag_munging=yes])
+AC_MSG_RESULT($enable_o_flag_munging)
+AM_CONDITIONAL(ENABLE_O_FLAG_MUNGING, test "$enable_o_flag_munging" = "yes")
+
+# Implementation of the --disable-instrumentation-munging switch.
+AC_MSG_CHECKING([whether a instrumentation (-fprofile, -fsanitize) munging is requested])
+AC_ARG_ENABLE([instrumentation-munging],
+ AS_HELP_STRING([--disable-instrumentation-munging],
+ [Disable modification of the cc instrumentation options]),
+ [enable_instrumentation_munging=$enableval],
+ [enable_instrumentation_munging=yes])
+AC_MSG_RESULT($enable_instrumentation_munging)
+AM_CONDITIONAL(ENABLE_INSTRUMENTATION_MUNGING,
+ test "$enable_instrumentation_munging" = "yes")
+
+# Implementation of the --disable-amd64-as-feature-detection switch.
+AC_MSG_CHECKING([whether to enable AMD64 as(1) feature detection])
+AC_ARG_ENABLE(amd64-as-feature-detection,
+ AS_HELP_STRING([--disable-amd64-as-feature-detection],
+ [Disable the auto-detection of AMD64 as(1) features]),
+ amd64_as_feature_detection=$enableval,
+ amd64_as_feature_detection=yes)
+AC_MSG_RESULT($amd64_as_feature_detection)
+
+
+AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME",
+ [A human readable text with the name of the OS])
+
+# For some systems we know that we have ld_version scripts.
+# Use it then as default.
+have_ld_version_script=no
+case "${host}" in
+ *-*-linux*)
+ have_ld_version_script=yes
+ ;;
+ *-*-gnu*)
+ have_ld_version_script=yes
+ ;;
+esac
+AC_ARG_ENABLE([ld-version-script],
+ AS_HELP_STRING([--enable-ld-version-script],
+ [enable/disable use of linker version script.
+ (default is system dependent)]),
+ [have_ld_version_script=$enableval],
+ [ : ] )
+AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
+
+AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM",
+ [defined to the name of the strong random device])
+AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM",
+ [defined to the name of the weaker random device])
+
+
+###############################
+#### Checks for libraries. ####
+###############################
+
+#
+# gpg-error is required.
+#
+AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION")
+if test "x$GPG_ERROR_LIBS" = "x"; then
+ AC_MSG_ERROR([libgpg-error is needed.
+ See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ .])
+fi
+
+AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GCRYPT,
+ [The default error source for libgcrypt.])
+
+#
+# Check whether the GNU Pth library is available. We require this
+# to build the optional gcryptrnd program.
+#
+AC_ARG_WITH(pth-prefix,
+ AS_HELP_STRING([--with-pth-prefix=PFX],
+ [prefix where GNU Pth is installed (optional)]),
+ pth_config_prefix="$withval", pth_config_prefix="")
+if test x$pth_config_prefix != x ; then
+ PTH_CONFIG="$pth_config_prefix/bin/pth-config"
+fi
+if test "$use_random_daemon" = "yes"; then
+ AC_PATH_PROG(PTH_CONFIG, pth-config, no)
+ if test "$PTH_CONFIG" = "no"; then
+ AC_MSG_WARN([[
+***
+*** To build the Libgcrypt's random number daemon
+*** we need the support of the GNU Portable Threads Library.
+*** Download it from ftp://ftp.gnu.org/gnu/pth/
+*** On a Debian GNU/Linux system you might want to try
+*** apt-get install libpth-dev
+***]])
+ else
+ GNUPG_PTH_VERSION_CHECK([1.3.7])
+ if test $have_pth = yes; then
+ PTH_CFLAGS=`$PTH_CONFIG --cflags`
+ PTH_LIBS=`$PTH_CONFIG --ldflags`
+ PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs --all`"
+ AC_DEFINE(USE_GNU_PTH, 1,
+ [Defined if the GNU Portable Thread Library should be used])
+ AC_DEFINE(HAVE_PTH, 1,
+ [Defined if the GNU Pth is available])
+ fi
+ fi
+fi
+AC_SUBST(PTH_CFLAGS)
+AC_SUBST(PTH_LIBS)
+
+#
+# Check whether pthreads is available
+#
+if test "$have_w32_system" != yes; then
+ AC_CHECK_LIB(pthread,pthread_create,have_pthread=yes)
+ if test "$have_pthread" = yes; then
+ AC_DEFINE(HAVE_PTHREAD, 1 ,[Define if we have pthread.])
+ fi
+fi
+
+
+# Solaris needs -lsocket and -lnsl. Unisys system includes
+# gethostbyname in libsocket but needs libnsl for socket.
+AC_SEARCH_LIBS(setsockopt, [socket], ,
+ [AC_SEARCH_LIBS(setsockopt, [socket], , , [-lnsl])])
+AC_SEARCH_LIBS(setsockopt, [nsl])
+
+##################################
+#### Checks for header files. ####
+##################################
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(unistd.h sys/select.h sys/msg.h sys/auxv.h)
+INSERT_SYS_SELECT_H=
+if test x"$ac_cv_header_sys_select_h" = xyes; then
+ INSERT_SYS_SELECT_H=" include <sys/select.h>"
+fi
+AC_SUBST(INSERT_SYS_SELECT_H)
+
+
+##########################################
+#### Checks for typedefs, structures, ####
+#### and compiler characteristics. ####
+##########################################
+
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_TYPE_PID_T
+
+AC_CHECK_TYPES([byte, ushort, u16, u32, u64])
+
+gl_TYPE_SOCKLEN_T
+case "${host}" in
+ *-*-mingw32*)
+ # socklen_t may or may not be defined depending on what headers
+ # are included. To be safe we use int as this is the actual type.
+ FALLBACK_SOCKLEN_T="typedef int gcry_socklen_t;"
+ ;;
+ *)
+ if test ".$gl_cv_socklen_t_equiv" = "."; then
+ FALLBACK_SOCKLEN_T="typedef socklen_t gcry_socklen_t;"
+ else
+ FALLBACK_SOCKLEN_T="typedef ${gl_cv_socklen_t_equiv} gcry_socklen_t;"
+ fi
+esac
+AC_SUBST(FALLBACK_SOCKLEN_T)
+
+
+#
+# Check for __builtin_bswap32 intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_bswap32,
+ [gcry_cv_have_builtin_bswap32],
+ [gcry_cv_have_builtin_bswap32=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+ [int x = 0; int y = __builtin_bswap32(x); return y;])],
+ [gcry_cv_have_builtin_bswap32=yes])])
+if test "$gcry_cv_have_builtin_bswap32" = "yes" ; then
+ AC_DEFINE(HAVE_BUILTIN_BSWAP32,1,
+ [Defined if compiler has '__builtin_bswap32' intrinsic])
+fi
+
+
+#
+# Check for __builtin_bswap64 intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_bswap64,
+ [gcry_cv_have_builtin_bswap64],
+ [gcry_cv_have_builtin_bswap64=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+ [long long x = 0; long long y = __builtin_bswap64(x); return y;])],
+ [gcry_cv_have_builtin_bswap64=yes])])
+if test "$gcry_cv_have_builtin_bswap64" = "yes" ; then
+ AC_DEFINE(HAVE_BUILTIN_BSWAP64,1,
+ [Defined if compiler has '__builtin_bswap64' intrinsic])
+fi
+
+
+#
+# Check for __builtin_ctz intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_ctz,
+ [gcry_cv_have_builtin_ctz],
+ [gcry_cv_have_builtin_ctz=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+ [unsigned int x = 0; int y = __builtin_ctz(x); return y;])],
+ [gcry_cv_have_builtin_ctz=yes])])
+if test "$gcry_cv_have_builtin_ctz" = "yes" ; then
+ AC_DEFINE(HAVE_BUILTIN_CTZ, 1,
+ [Defined if compiler has '__builtin_ctz' intrinsic])
+fi
+
+
+#
+# Check for __builtin_ctzl intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_ctzl,
+ [gcry_cv_have_builtin_ctzl],
+ [gcry_cv_have_builtin_ctzl=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+ [unsigned long x = 0; long y = __builtin_ctzl(x); return y;])],
+ [gcry_cv_have_builtin_ctzl=yes])])
+if test "$gcry_cv_have_builtin_ctzl" = "yes" ; then
+ AC_DEFINE(HAVE_BUILTIN_CTZL, 1,
+ [Defined if compiler has '__builtin_ctzl' intrinsic])
+fi
+
+
+#
+# Check for __builtin_clz intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_clz,
+ [gcry_cv_have_builtin_clz],
+ [gcry_cv_have_builtin_clz=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+ [unsigned int x = 0; int y = __builtin_clz(x); return y;])],
+ [gcry_cv_have_builtin_clz=yes])])
+if test "$gcry_cv_have_builtin_clz" = "yes" ; then
+ AC_DEFINE(HAVE_BUILTIN_CLZ, 1,
+ [Defined if compiler has '__builtin_clz' intrinsic])
+fi
+
+
+#
+# Check for __builtin_clzl intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_clzl,
+ [gcry_cv_have_builtin_clzl],
+ [gcry_cv_have_builtin_clzl=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+ [unsigned long x = 0; long y = __builtin_clzl(x); return y;])],
+ [gcry_cv_have_builtin_clzl=yes])])
+if test "$gcry_cv_have_builtin_clzl" = "yes" ; then
+ AC_DEFINE(HAVE_BUILTIN_CLZL, 1,
+ [Defined if compiler has '__builtin_clzl' intrinsic])
+fi
+
+
+#
+# Check for __sync_synchronize intrinsic.
+#
+AC_CACHE_CHECK(for __sync_synchronize,
+ [gcry_cv_have_sync_synchronize],
+ [gcry_cv_have_sync_synchronize=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+ [__sync_synchronize(); return 0;])],
+ [gcry_cv_have_sync_synchronize=yes])])
+if test "$gcry_cv_have_sync_synchronize" = "yes" ; then
+ AC_DEFINE(HAVE_SYNC_SYNCHRONIZE, 1,
+ [Defined if compiler has '__sync_synchronize' intrinsic])
+fi
+
+
+#
+# Check for VLA support (variable length arrays).
+#
+AC_CACHE_CHECK(whether the variable length arrays are supported,
+ [gcry_cv_have_vla],
+ [gcry_cv_have_vla=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[void f1(char *, int);
+ char foo(int i) {
+ char b[(i < 0 ? 0 : i) + 1];
+ f1(b, sizeof b); return b[0];}]])],
+ [gcry_cv_have_vla=yes])])
+if test "$gcry_cv_have_vla" = "yes" ; then
+ AC_DEFINE(HAVE_VLA,1, [Defined if variable length arrays are supported])
+fi
+
+
+#
+# Check for ELF visibility support.
+#
+AC_CACHE_CHECK(whether the visibility attribute is supported,
+ gcry_cv_visibility_attribute,
+ [gcry_cv_visibility_attribute=no
+ AC_LANG_CONFTEST([AC_LANG_SOURCE(
+ [[int foo __attribute__ ((visibility ("hidden"))) = 1;
+ int bar __attribute__ ((visibility ("protected"))) = 1;
+ ]])])
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then
+ if grep '\.hidden.*foo' conftest.s >/dev/null 2>&1 ; then
+ if grep '\.protected.*bar' conftest.s >/dev/null 2>&1; then
+ gcry_cv_visibility_attribute=yes
+ fi
+ fi
+ fi
+ ])
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ AC_CACHE_CHECK(for broken visibility attribute,
+ gcry_cv_broken_visibility_attribute,
+ [gcry_cv_broken_visibility_attribute=yes
+ AC_LANG_CONFTEST([AC_LANG_SOURCE(
+ [[int foo (int x);
+ int bar (int x) __asm__ ("foo")
+ __attribute__ ((visibility ("hidden")));
+ int bar (int x) { return x; }
+ ]])])
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then
+ if grep '\.hidden@<:@ _@:>@foo' conftest.s >/dev/null 2>&1;
+ then
+ gcry_cv_broken_visibility_attribute=no
+ fi
+ fi
+ ])
+fi
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ AC_CACHE_CHECK(for broken alias attribute,
+ gcry_cv_broken_alias_attribute,
+ [gcry_cv_broken_alias_attribute=yes
+ AC_LANG_CONFTEST([AC_LANG_SOURCE(
+ [[extern int foo (int x) __asm ("xyzzy");
+ int bar (int x) { return x; }
+ extern __typeof (bar) foo __attribute ((weak, alias ("bar")));
+ extern int dfoo;
+ extern __typeof (dfoo) dfoo __asm ("abccb");
+ int dfoo = 1;
+ ]])])
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then
+ if grep 'xyzzy' conftest.s >/dev/null 2>&1 && \
+ grep 'abccb' conftest.s >/dev/null 2>&1; then
+ gcry_cv_broken_alias_attribute=no
+ fi
+ fi
+ ])
+fi
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ AC_CACHE_CHECK(if gcc supports -fvisibility=hidden,
+ gcry_cv_gcc_has_f_visibility,
+ [gcry_cv_gcc_has_f_visibility=no
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-fvisibility=hidden"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],
+ gcry_cv_gcc_has_f_visibility=yes)
+ CFLAGS=$_gcc_cflags_save;
+ ])
+fi
+if test "$gcry_cv_visibility_attribute" = "yes" \
+ && test "$gcry_cv_broken_visibility_attribute" != "yes" \
+ && test "$gcry_cv_broken_alias_attribute" != "yes" \
+ && test "$gcry_cv_gcc_has_f_visibility" = "yes"
+ then
+ AC_DEFINE(GCRY_USE_VISIBILITY, 1,
+ [Define to use the GNU C visibility attribute.])
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+fi
+
+
+# Following attribute tests depend on warnings to cause compile to fail,
+# so set -Werror temporarily.
+_gcc_cflags_save=$CFLAGS
+CFLAGS="$CFLAGS -Werror"
+
+
+#
+# Check whether the compiler supports the GCC style aligned attribute
+#
+AC_CACHE_CHECK([whether the GCC style aligned attribute is supported],
+ [gcry_cv_gcc_attribute_aligned],
+ [gcry_cv_gcc_attribute_aligned=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[struct { int a; } foo __attribute__ ((aligned (16)));]])],
+ [gcry_cv_gcc_attribute_aligned=yes])])
+if test "$gcry_cv_gcc_attribute_aligned" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_ATTRIBUTE_ALIGNED,1,
+ [Defined if a GCC style "__attribute__ ((aligned (n))" is supported])
+fi
+
+
+#
+# Check whether the compiler supports the GCC style packed attribute
+#
+AC_CACHE_CHECK([whether the GCC style packed attribute is supported],
+ [gcry_cv_gcc_attribute_packed],
+ [gcry_cv_gcc_attribute_packed=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[struct foolong_s { long b; } __attribute__ ((packed));
+ struct foo_s { char a; struct foolong_s b; }
+ __attribute__ ((packed));
+ enum bar {
+ FOO = 1 / (sizeof(struct foo_s) == (sizeof(char) + sizeof(long))),
+ };]])],
+ [gcry_cv_gcc_attribute_packed=yes])])
+if test "$gcry_cv_gcc_attribute_packed" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_ATTRIBUTE_PACKED,1,
+ [Defined if a GCC style "__attribute__ ((packed))" is supported])
+fi
+
+
+#
+# Check whether the compiler supports the GCC style may_alias attribute
+#
+AC_CACHE_CHECK([whether the GCC style may_alias attribute is supported],
+ [gcry_cv_gcc_attribute_may_alias],
+ [gcry_cv_gcc_attribute_may_alias=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[typedef struct foo_s { int a; }
+ __attribute__ ((may_alias)) foo_t;]])],
+ [gcry_cv_gcc_attribute_may_alias=yes])])
+if test "$gcry_cv_gcc_attribute_may_alias" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_ATTRIBUTE_MAY_ALIAS,1,
+ [Defined if a GCC style "__attribute__ ((may_alias))" is supported])
+fi
+
+
+# Restore flags.
+CFLAGS=$_gcc_cflags_save;
+
+
+#
+# Check whether the compiler supports 'asm' or '__asm__' keyword for
+# assembler blocks.
+#
+AC_CACHE_CHECK([whether 'asm' assembler keyword is supported],
+ [gcry_cv_have_asm],
+ [gcry_cv_have_asm=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[void a(void) { asm("":::"memory"); }]])],
+ [gcry_cv_have_asm=yes])])
+AC_CACHE_CHECK([whether '__asm__' assembler keyword is supported],
+ [gcry_cv_have___asm__],
+ [gcry_cv_have___asm__=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[void a(void) { __asm__("":::"memory"); }]])],
+ [gcry_cv_have___asm__=yes])])
+if test "$gcry_cv_have_asm" = "no" ; then
+ if test "$gcry_cv_have___asm__" = "yes" ; then
+ AC_DEFINE(asm,__asm__,
+ [Define to supported assembler block keyword, if plain 'asm' was not
+ supported])
+ fi
+fi
+
+
+#
+# Check whether the compiler supports inline assembly memory barrier.
+#
+if test "$gcry_cv_have_asm" = "no" ; then
+ if test "$gcry_cv_have___asm__" = "yes" ; then
+ AC_CACHE_CHECK([whether inline assembly memory barrier is supported],
+ [gcry_cv_have_asm_volatile_memory],
+ [gcry_cv_have_asm_volatile_memory=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[void a(int x)
+ {
+ __asm__ volatile("":::"memory");
+ __asm__ volatile("":"+r"(x)::"memory");
+ }]])],
+ [gcry_cv_have_asm_volatile_memory=yes])])
+ fi
+else
+ AC_CACHE_CHECK([whether inline assembly memory barrier is supported],
+ [gcry_cv_have_asm_volatile_memory],
+ [gcry_cv_have_asm_volatile_memory=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[void a(int x)
+ {
+ asm volatile("":::"memory");
+ asm volatile("":"+r"(x)::"memory"); }]])],
+ [gcry_cv_have_asm_volatile_memory=yes])])
+fi
+if test "$gcry_cv_have_asm_volatile_memory" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_ASM_VOLATILE_MEMORY,1,
+ [Define if inline asm memory barrier is supported])
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for our ARM
+# implementations. This needs to be done before setting up the
+# assembler stuff.
+#
+AC_CACHE_CHECK([whether GCC assembler is compatible for ARM assembly implementations],
+ [gcry_cv_gcc_arm_platform_as_ok],
+ [if test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_arm_platform_as_ok="n/a"
+ else
+ gcry_cv_gcc_arm_platform_as_ok=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ /* Test if assembler supports UAL syntax. */
+ ".syntax unified\n\t"
+ ".arm\n\t" /* our assembly code is in ARM mode */
+ ".text\n\t"
+ /* Following causes error if assembler ignored '.syntax unified'. */
+ "asmfunc:\n\t"
+ "add %r0, %r0, %r4, ror #12;\n\t"
+
+ /* Test if '.type' and '.size' are supported. */
+ ".size asmfunc,.-asmfunc;\n\t"
+ ".type asmfunc,%function;\n\t"
+ );]], [ asmfunc(); ] )],
+ [gcry_cv_gcc_arm_platform_as_ok=yes])
+ fi])
+if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then
+ AC_DEFINE(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS,1,
+ [Defined if underlying assembler is compatible with ARM assembly implementations])
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for our ARMv8/Aarch64
+# implementations. This needs to be done before setting up the
+# assembler stuff.
+#
+AC_CACHE_CHECK([whether GCC assembler is compatible for ARMv8/Aarch64 assembly implementations],
+ [gcry_cv_gcc_aarch64_platform_as_ok],
+ [if test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_aarch64_platform_as_ok="n/a"
+ else
+ gcry_cv_gcc_aarch64_platform_as_ok=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ ".text\n\t"
+ "asmfunc:\n\t"
+ "eor x0, x0, x30, ror #12;\n\t"
+ "add x0, x0, x30, asr #12;\n\t"
+ "eor v0.16b, v0.16b, v31.16b;\n\t"
+ );]], [ asmfunc(); ] )],
+ [gcry_cv_gcc_aarch64_platform_as_ok=yes])
+ fi])
+if test "$gcry_cv_gcc_aarch64_platform_as_ok" = "yes" ; then
+ AC_DEFINE(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS,1,
+ [Defined if underlying assembler is compatible with ARMv8/Aarch64 assembly implementations])
+fi
+
+#
+# Check whether GCC assembler supports for CFI directives.
+#
+AC_CACHE_CHECK([whether GCC assembler supports for CFI directives],
+ [gcry_cv_gcc_asm_cfi_directives],
+ [gcry_cv_gcc_asm_cfi_directives=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ ".text\n\t"
+ "ac_test:\n\t"
+ ".cfi_startproc\n\t"
+ ".cfi_remember_state\n\t"
+ ".cfi_adjust_cfa_offset 8\n\t"
+ ".cfi_rel_offset 0, 8\n\t"
+ ".cfi_def_cfa_register 1\n\t"
+ ".cfi_register 2, 3\n\t"
+ ".cfi_restore 2\n\t"
+ ".cfi_escape 0x0f, 0x02, 0x11, 0x00\n\t"
+ ".cfi_restore_state\n\t"
+ ".long 0\n\t"
+ ".cfi_endproc\n\t"
+ );]])],
+ [gcry_cv_gcc_asm_cfi_directives=yes])])
+if test "$gcry_cv_gcc_asm_cfi_directives" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_ASM_CFI_DIRECTIVES,1,
+ [Defined if underlying assembler supports for CFI directives])
+fi
+
+
+#
+# Check whether GCC assembler supports for ELF directives.
+#
+AC_CACHE_CHECK([whether GCC assembler supports for ELF directives],
+ [gcry_cv_gcc_asm_elf_directives],
+ [gcry_cv_gcc_asm_elf_directives=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ /* Test if ELF directives '.type' and '.size' are supported. */
+ ".text\n\t"
+ "asmfunc:\n\t"
+ ".size asmfunc,.-asmfunc;\n\t"
+ ".type asmfunc,STT_FUNC;\n\t"
+ );]])],
+ [gcry_cv_gcc_asm_elf_directives=yes])])
+if test "$gcry_cv_gcc_asm_elf_directives" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_ASM_ELF_DIRECTIVES,1,
+ [Defined if underlying assembler supports for ELF directives])
+fi
+
+
+#
+# Check whether underscores in symbols are required. This needs to be
+# done before setting up the assembler stuff.
+#
+GNUPG_SYS_SYMBOL_UNDERSCORE()
+
+
+#################################
+#### ####
+#### Setup assembler stuff. ####
+#### Define mpi_cpu_arch. ####
+#### ####
+#################################
+AC_ARG_ENABLE(mpi-path,
+ AS_HELP_STRING([--enable-mpi-path=EXTRA_PATH],
+ [prepend EXTRA_PATH to list of CPU specific optimizations]),
+ mpi_extra_path="$enableval",mpi_extra_path="")
+AC_MSG_CHECKING(architecture and mpi assembler functions)
+if test -f $srcdir/mpi/config.links ; then
+ . $srcdir/mpi/config.links
+ AC_CONFIG_LINKS("$mpi_ln_list")
+ ac_cv_mpi_sflags="$mpi_sflags"
+ AC_MSG_RESULT($mpi_cpu_arch)
+else
+ AC_MSG_RESULT(failed)
+ AC_MSG_ERROR([mpi/config.links missing!])
+fi
+MPI_SFLAGS="$ac_cv_mpi_sflags"
+AC_SUBST(MPI_SFLAGS)
+
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_ADD1, test "$mpi_mod_asm_mpih_add1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_SUB1, test "$mpi_mod_asm_mpih_sub1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL1, test "$mpi_mod_asm_mpih_mul1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL2, test "$mpi_mod_asm_mpih_mul2" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL3, test "$mpi_mod_asm_mpih_mul3" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_LSHIFT, test "$mpi_mod_asm_mpih_lshift" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_RSHIFT, test "$mpi_mod_asm_mpih_rshift" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_UDIV, test "$mpi_mod_asm_udiv" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_UDIV_QRNND, test "$mpi_mod_asm_udiv_qrnnd" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_ADD1, test "$mpi_mod_c_mpih_add1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_SUB1, test "$mpi_mod_c_mpih_sub1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL1, test "$mpi_mod_c_mpih_mul1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL2, test "$mpi_mod_c_mpih_mul2" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL3, test "$mpi_mod_c_mpih_mul3" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_LSHIFT, test "$mpi_mod_c_mpih_lshift" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_RSHIFT, test "$mpi_mod_c_mpih_rshift" = yes)
+AM_CONDITIONAL(MPI_MOD_C_UDIV, test "$mpi_mod_c_udiv" = yes)
+AM_CONDITIONAL(MPI_MOD_C_UDIV_QRNND, test "$mpi_mod_c_udiv_qrnnd" = yes)
+
+# Reset non applicable feature flags.
+if test "$mpi_cpu_arch" != "x86" ; then
+ aesnisupport="n/a"
+ shaextsupport="n/a"
+ pclmulsupport="n/a"
+ sse41support="n/a"
+ avxsupport="n/a"
+ avx2support="n/a"
+ padlocksupport="n/a"
+ drngsupport="n/a"
+fi
+
+if test "$mpi_cpu_arch" != "arm" ; then
+ if test "$mpi_cpu_arch" != "aarch64" ; then
+ neonsupport="n/a"
+ armcryptosupport="n/a"
+ fi
+fi
+
+if test "$mpi_cpu_arch" != "ppc"; then
+ ppccryptosupport="n/a"
+fi
+
+#############################################
+#### ####
+#### Platform specific compiler checks. ####
+#### ####
+#############################################
+
+
+# Following tests depend on warnings to cause compile to fail, so set -Werror
+# temporarily.
+_gcc_cflags_save=$CFLAGS
+CFLAGS="$CFLAGS -Werror"
+
+
+#
+# Check whether compiler supports 'ms_abi' function attribute.
+#
+AC_CACHE_CHECK([whether compiler supports 'ms_abi' function attribute],
+ [gcry_cv_gcc_attribute_ms_abi],
+ [gcry_cv_gcc_attribute_ms_abi=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[int __attribute__ ((ms_abi)) proto(int);]])],
+ [gcry_cv_gcc_attribute_ms_abi=yes])])
+if test "$gcry_cv_gcc_attribute_ms_abi" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_ATTRIBUTE_MS_ABI,1,
+ [Defined if compiler supports "__attribute__ ((ms_abi))" function attribute])
+fi
+
+
+#
+# Check whether compiler supports 'sysv_abi' function attribute.
+#
+AC_CACHE_CHECK([whether compiler supports 'sysv_abi' function attribute],
+ [gcry_cv_gcc_attribute_sysv_abi],
+ [gcry_cv_gcc_attribute_sysv_abi=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[int __attribute__ ((sysv_abi)) proto(int);]])],
+ [gcry_cv_gcc_attribute_sysv_abi=yes])])
+if test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_ATTRIBUTE_SYSV_ABI,1,
+ [Defined if compiler supports "__attribute__ ((sysv_abi))" function attribute])
+fi
+
+
+#
+# Check whether default calling convention is 'ms_abi'.
+#
+if test "$gcry_cv_gcc_attribute_ms_abi" = "yes" ; then
+ AC_CACHE_CHECK([whether default calling convention is 'ms_abi'],
+ [gcry_cv_gcc_default_abi_is_ms_abi],
+ [gcry_cv_gcc_default_abi_is_ms_abi=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[void *test(void) {
+ void *(*def_func)(void) = test;
+ void *__attribute__((ms_abi))(*msabi_func)(void);
+ /* warning on SysV abi targets, passes on Windows based targets */
+ msabi_func = def_func;
+ return msabi_func;
+ }]])],
+ [gcry_cv_gcc_default_abi_is_ms_abi=yes])])
+ if test "$gcry_cv_gcc_default_abi_is_ms_abi" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_DEFAULT_ABI_IS_MS_ABI,1,
+ [Defined if default calling convention is 'ms_abi'])
+ fi
+fi
+
+
+#
+# Check whether default calling convention is 'sysv_abi'.
+#
+if test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" ; then
+ AC_CACHE_CHECK([whether default calling convention is 'sysv_abi'],
+ [gcry_cv_gcc_default_abi_is_sysv_abi],
+ [gcry_cv_gcc_default_abi_is_sysv_abi=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[void *test(void) {
+ void *(*def_func)(void) = test;
+ void *__attribute__((sysv_abi))(*sysvabi_func)(void);
+ /* warning on MS ABI targets, passes on SysV ABI targets */
+ sysvabi_func = def_func;
+ return sysvabi_func;
+ }]])],
+ [gcry_cv_gcc_default_abi_is_sysv_abi=yes])])
+ if test "$gcry_cv_gcc_default_abi_is_sysv_abi" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_DEFAULT_ABI_IS_SYSV_ABI,1,
+ [Defined if default calling convention is 'sysv_abi'])
+ fi
+fi
+
+
+# Restore flags.
+CFLAGS=$_gcc_cflags_save;
+
+
+#
+# Check whether GCC inline assembler supports SSSE3 instructions
+# This is required for the AES-NI instructions.
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports SSSE3 instructions],
+ [gcry_cv_gcc_inline_asm_ssse3],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_ssse3="n/a"
+ else
+ gcry_cv_gcc_inline_asm_ssse3=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+ void a(void) {
+ __asm__("pshufb %[mask], %%xmm2\n\t"::[mask]"m"(*be_mask):);
+ }]], [ a(); ] )],
+ [gcry_cv_gcc_inline_asm_ssse3=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_ssse3" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_SSSE3,1,
+ [Defined if inline assembler supports SSSE3 instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports PCLMUL instructions.
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports PCLMUL instructions],
+ [gcry_cv_gcc_inline_asm_pclmul],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_pclmul="n/a"
+ else
+ gcry_cv_gcc_inline_asm_pclmul=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[void a(void) {
+ __asm__("pclmulqdq \$0, %%xmm1, %%xmm3\n\t":::"cc");
+ }]], [ a(); ] )],
+ [gcry_cv_gcc_inline_asm_pclmul=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_pclmul" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_PCLMUL,1,
+ [Defined if inline assembler supports PCLMUL instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports SHA Extensions instructions.
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports SHA Extensions instructions],
+ [gcry_cv_gcc_inline_asm_shaext],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_shaext="n/a"
+ else
+ gcry_cv_gcc_inline_asm_shaext=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[void a(void) {
+ __asm__("sha1rnds4 \$0, %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha1nexte %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha1msg1 %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha1msg2 %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha256rnds2 %%xmm0, %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha256msg1 %%xmm1, %%xmm3\n\t":::"cc");
+ __asm__("sha256msg2 %%xmm1, %%xmm3\n\t":::"cc");
+ }]], [ a(); ] )],
+ [gcry_cv_gcc_inline_asm_shaext=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_shaext" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_SHAEXT,1,
+ [Defined if inline assembler supports SHA Extensions instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports SSE4.1 instructions.
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports SSE4.1 instructions],
+ [gcry_cv_gcc_inline_asm_sse41],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_sse41="n/a"
+ else
+ gcry_cv_gcc_inline_asm_sse41=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[void a(void) {
+ int i;
+ __asm__("pextrd \$2, %%xmm0, %[out]\n\t" : [out] "=m" (i));
+ }]], [ a(); ] )],
+ [gcry_cv_gcc_inline_asm_sse41=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_sse41" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_SSE41,1,
+ [Defined if inline assembler supports SSE4.1 instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports AVX instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AVX instructions],
+ [gcry_cv_gcc_inline_asm_avx],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_avx="n/a"
+ else
+ gcry_cv_gcc_inline_asm_avx=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[void a(void) {
+ __asm__("xgetbv; vaesdeclast (%[mem]),%%xmm0,%%xmm7\n\t"::[mem]"r"(0):);
+ }]], [ a(); ] )],
+ [gcry_cv_gcc_inline_asm_avx=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_avx" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_AVX,1,
+ [Defined if inline assembler supports AVX instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports AVX2 instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AVX2 instructions],
+ [gcry_cv_gcc_inline_asm_avx2],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_avx2="n/a"
+ else
+ gcry_cv_gcc_inline_asm_avx2=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[void a(void) {
+ __asm__("xgetbv; vpbroadcastb %%xmm7,%%ymm1\n\t":::"cc");
+ }]], [ a(); ] )],
+ [gcry_cv_gcc_inline_asm_avx2=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_avx2" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_AVX2,1,
+ [Defined if inline assembler supports AVX2 instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports BMI2 instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports BMI2 instructions],
+ [gcry_cv_gcc_inline_asm_bmi2],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_bmi2="n/a"
+ else
+ gcry_cv_gcc_inline_asm_bmi2=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[unsigned int a(unsigned int x, unsigned int y) {
+ unsigned int tmp1, tmp2;
+ asm ("rorxl %2, %1, %0"
+ : "=r" (tmp1)
+ : "rm0" (x), "J" (32 - ((23) & 31)));
+ asm ("andnl %2, %1, %0"
+ : "=r" (tmp2)
+ : "r0" (x), "rm" (y));
+ return tmp1 + tmp2;
+ }]], [ a(1, 2); ] )],
+ [gcry_cv_gcc_inline_asm_bmi2=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_bmi2" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_BMI2,1,
+ [Defined if inline assembler supports BMI2 instructions])
+fi
+
+
+#
+# Check whether GCC assembler needs "-Wa,--divide" to correctly handle
+# constant division
+#
+if test $amd64_as_feature_detection = yes; then
+ AC_CACHE_CHECK([whether GCC assembler handles division correctly],
+ [gcry_cv_gcc_as_const_division_ok],
+ [gcry_cv_gcc_as_const_division_ok=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]],
+ [fn();])],
+ [gcry_cv_gcc_as_const_division_ok=yes])])
+ if test "$gcry_cv_gcc_as_const_division_ok" = "no" ; then
+ #
+ # Add '-Wa,--divide' to CPPFLAGS and try check again.
+ #
+ _gcc_cppflags_save="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -Wa,--divide"
+ AC_CACHE_CHECK([whether GCC assembler handles division correctly with "-Wa,--divide"],
+ [gcry_cv_gcc_as_const_division_with_wadivide_ok],
+ [gcry_cv_gcc_as_const_division_with_wadivide_ok=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]],
+ [fn();])],
+ [gcry_cv_gcc_as_const_division_with_wadivide_ok=yes])])
+ if test "$gcry_cv_gcc_as_const_division_with_wadivide_ok" = "no" ; then
+ # '-Wa,--divide' did not work, restore old flags.
+ CPPFLAGS="$_gcc_cppflags_save"
+ fi
+ fi
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for our amd64
+# implementations
+#
+if test $amd64_as_feature_detection = yes; then
+ AC_CACHE_CHECK([whether GCC assembler is compatible for amd64 assembly implementations],
+ [gcry_cv_gcc_amd64_platform_as_ok],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_amd64_platform_as_ok="n/a"
+ else
+ gcry_cv_gcc_amd64_platform_as_ok=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ /* Test if '.type' and '.size' are supported. */
+ /* These work only on ELF targets. */
+ ".text\n\t"
+ "asmfunc:\n\t"
+ ".size asmfunc,.-asmfunc;\n\t"
+ ".type asmfunc,@function;\n\t"
+ /* Test if assembler allows use of '/' for constant division
+ * (Solaris/x86 issue). If previous constant division check
+ * and "-Wa,--divide" workaround failed, this causes assembly
+ * to be disable on this machine. */
+ "xorl \$(123456789/12345678), %ebp;\n\t"
+ );]], [ asmfunc(); ])],
+ [gcry_cv_gcc_amd64_platform_as_ok=yes])
+ fi])
+ if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then
+ AC_DEFINE(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS,1,
+ [Defined if underlying assembler is compatible with amd64 assembly implementations])
+ fi
+ if test "$gcry_cv_gcc_amd64_platform_as_ok" = "no" &&
+ test "$gcry_cv_gcc_attribute_sysv_abi" = "yes" &&
+ test "$gcry_cv_gcc_default_abi_is_ms_abi" = "yes"; then
+ AC_CACHE_CHECK([whether GCC assembler is compatible for WIN64 assembly implementations],
+ [gcry_cv_gcc_win64_platform_as_ok],
+ [gcry_cv_gcc_win64_platform_as_ok=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ ".text\n\t"
+ ".globl asmfunc\n\t"
+ "asmfunc:\n\t"
+ "xorq \$(1234), %rbp;\n\t"
+ );]], [ asmfunc(); ])],
+ [gcry_cv_gcc_win64_platform_as_ok=yes])])
+ if test "$gcry_cv_gcc_win64_platform_as_ok" = "yes" ; then
+ AC_DEFINE(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS,1,
+ [Defined if underlying assembler is compatible with WIN64 assembly implementations])
+ fi
+ fi
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for assembly
+# implementations that use Intel syntax
+#
+AC_CACHE_CHECK([whether GCC assembler is compatible for Intel syntax assembly implementations],
+ [gcry_cv_gcc_platform_as_ok_for_intel_syntax],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_platform_as_ok_for_intel_syntax="n/a"
+ else
+ gcry_cv_gcc_platform_as_ok_for_intel_syntax=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ ".intel_syntax noprefix\n\t"
+ ".text\n\t"
+ "actest:\n\t"
+ "pxor xmm1, xmm7;\n\t"
+ "vperm2i128 ymm2, ymm3, ymm0, 1;\n\t"
+ "add eax, ebp;\n\t"
+ "rorx eax, ebp, 1;\n\t"
+ "sub eax, [esp + 4];\n\t"
+ "add dword ptr [esp + eax], 0b10101;\n\t"
+ ".att_syntax prefix\n\t"
+ );]], [ actest(); ])],
+ [gcry_cv_gcc_platform_as_ok_for_intel_syntax=yes])
+ fi])
+if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then
+ AC_DEFINE(HAVE_INTEL_SYNTAX_PLATFORM_AS,1,
+ [Defined if underlying assembler is compatible with Intel syntax assembly implementations])
+fi
+
+
+#
+# Check whether compiler is configured for ARMv6 or newer architecture
+#
+AC_CACHE_CHECK([whether compiler is configured for ARMv6 or newer architecture],
+ [gcry_cv_cc_arm_arch_is_v6],
+ [if test "$mpi_cpu_arch" != "arm" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_cc_arm_arch_is_v6="n/a"
+ else
+ gcry_cv_cc_arm_arch_is_v6=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[
+ #if defined(__arm__) && \
+ ((defined(__ARM_ARCH) && __ARM_ARCH >= 6) \
+ || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) \
+ || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__))
+ /* empty */
+ #else
+ /* fail compile if not ARMv6. */
+ not_armv6 not_armv6 = (not_armv6)not_armv6;
+ #endif
+ ]])],
+ [gcry_cv_cc_arm_arch_is_v6=yes])
+ fi])
+if test "$gcry_cv_cc_arm_arch_is_v6" = "yes" ; then
+ AC_DEFINE(HAVE_ARM_ARCH_V6,1,
+ [Defined if ARM architecture is v6 or newer])
+fi
+
+
+#
+# Check whether GCC inline assembler supports NEON instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports NEON instructions],
+ [gcry_cv_gcc_inline_asm_neon],
+ [if test "$mpi_cpu_arch" != "arm" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_neon="n/a"
+ else
+ gcry_cv_gcc_inline_asm_neon=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ ".syntax unified\n\t"
+ ".arm\n\t"
+ ".fpu neon\n\t"
+ ".text\n\t"
+ "testfn:\n\t"
+ "vld1.64 {%q0-%q1}, [%r0]!;\n\t"
+ "vrev64.8 %q0, %q3;\n\t"
+ "vadd.u64 %q0, %q1;\n\t"
+ "vadd.s64 %d3, %d2, %d3;\n\t"
+ );
+ ]], [ testfn(); ])],
+ [gcry_cv_gcc_inline_asm_neon=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_neon" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_NEON,1,
+ [Defined if inline assembler supports NEON instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports AArch32 Crypto Extension instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AArch32 Crypto Extension instructions],
+ [gcry_cv_gcc_inline_asm_aarch32_crypto],
+ [if test "$mpi_cpu_arch" != "arm" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_aarch32_crypto="n/a"
+ else
+ gcry_cv_gcc_inline_asm_aarch32_crypto=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ ".syntax unified\n\t"
+ ".arch armv8-a\n\t"
+ ".arm\n\t"
+ ".fpu crypto-neon-fp-armv8\n\t"
+ ".text\n\t"
+
+ "testfn:\n\t"
+ "sha1h.32 q0, q0;\n\t"
+ "sha1c.32 q0, q0, q0;\n\t"
+ "sha1p.32 q0, q0, q0;\n\t"
+ "sha1su0.32 q0, q0, q0;\n\t"
+ "sha1su1.32 q0, q0;\n\t"
+
+ "sha256h.32 q0, q0, q0;\n\t"
+ "sha256h2.32 q0, q0, q0;\n\t"
+ "sha1p.32 q0, q0, q0;\n\t"
+ "sha256su0.32 q0, q0;\n\t"
+ "sha256su1.32 q0, q0, q15;\n\t"
+
+ "aese.8 q0, q0;\n\t"
+ "aesd.8 q0, q0;\n\t"
+ "aesmc.8 q0, q0;\n\t"
+ "aesimc.8 q0, q0;\n\t"
+
+ "vmull.p64 q0, d0, d0;\n\t"
+ );
+ ]], [ testfn(); ])],
+ [gcry_cv_gcc_inline_asm_aarch32_crypto=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_aarch32_crypto" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO,1,
+ [Defined if inline assembler supports AArch32 Crypto Extension instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports AArch64 NEON instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 NEON instructions],
+ [gcry_cv_gcc_inline_asm_aarch64_neon],
+ [if test "$mpi_cpu_arch" != "aarch64" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_aarch64_neon="n/a"
+ else
+ gcry_cv_gcc_inline_asm_aarch64_neon=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ ".cpu generic+simd\n\t"
+ ".text\n\t"
+ "testfn:\n\t"
+ "mov w0, \#42;\n\t"
+ "dup v0.8b, w0;\n\t"
+ "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t"
+ );
+ ]], [ testfn(); ])],
+ [gcry_cv_gcc_inline_asm_aarch64_neon=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_aarch64_neon" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_AARCH64_NEON,1,
+ [Defined if inline assembler supports AArch64 NEON instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports AArch64 Crypto Extension instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 Crypto Extension instructions],
+ [gcry_cv_gcc_inline_asm_aarch64_crypto],
+ [if test "$mpi_cpu_arch" != "aarch64" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_aarch64_crypto="n/a"
+ else
+ gcry_cv_gcc_inline_asm_aarch64_crypto=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(
+ ".cpu generic+simd+crypto\n\t"
+ ".text\n\t"
+ "testfn:\n\t"
+ "mov w0, \#42;\n\t"
+ "dup v0.8b, w0;\n\t"
+ "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t"
+
+ "sha1h s0, s0;\n\t"
+ "sha1c q0, s0, v0.4s;\n\t"
+ "sha1p q0, s0, v0.4s;\n\t"
+ "sha1su0 v0.4s, v0.4s, v0.4s;\n\t"
+ "sha1su1 v0.4s, v0.4s;\n\t"
+
+ "sha256h q0, q0, v0.4s;\n\t"
+ "sha256h2 q0, q0, v0.4s;\n\t"
+ "sha1p q0, s0, v0.4s;\n\t"
+ "sha256su0 v0.4s, v0.4s;\n\t"
+ "sha256su1 v0.4s, v0.4s, v31.4s;\n\t"
+
+ "aese v0.16b, v0.16b;\n\t"
+ "aesd v0.16b, v0.16b;\n\t"
+ "aesmc v0.16b, v0.16b;\n\t"
+ "aesimc v0.16b, v0.16b;\n\t"
+
+ "pmull v0.1q, v0.1d, v31.1d;\n\t"
+ "pmull2 v0.1q, v0.2d, v31.2d;\n\t"
+ );
+ ]], [ testfn(); ])],
+ [gcry_cv_gcc_inline_asm_aarch64_crypto=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_aarch64_crypto" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO,1,
+ [Defined if inline assembler supports AArch64 Crypto Extension instructions])
+fi
+
+
+#
+# Check whether PowerPC AltiVec/VSX intrinsics
+#
+AC_CACHE_CHECK([whether compiler supports PowerPC AltiVec/VSX intrinsics],
+ [gcry_cv_cc_ppc_altivec],
+ [if test "$mpi_cpu_arch" != "ppc" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_cc_ppc_altivec="n/a"
+ else
+ gcry_cv_cc_ppc_altivec=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[#include <altivec.h>
+ typedef vector unsigned char block;
+ typedef vector unsigned int vecu32;
+ block fn(block in)
+ {
+ block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0));
+ vecu32 y = vec_vsx_ld (0, (unsigned int*)0);
+ return vec_cipher_be (t, in) ^ (block)y;
+ }
+ ]])],
+ [gcry_cv_cc_ppc_altivec=yes])
+ fi])
+if test "$gcry_cv_cc_ppc_altivec" = "yes" ; then
+ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC,1,
+ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics])
+fi
+
+_gcc_cflags_save=$CFLAGS
+CFLAGS="$CFLAGS -maltivec -mvsx -mcrypto"
+
+if test "$gcry_cv_cc_ppc_altivec" = "no" &&
+ test "$mpi_cpu_arch" = "ppc" &&
+ test "$try_asm_modules" == "yes" ; then
+ AC_CACHE_CHECK([whether compiler supports PowerPC AltiVec/VSX/crypto intrinsics with extra GCC flags],
+ [gcry_cv_cc_ppc_altivec_cflags],
+ [gcry_cv_cc_ppc_altivec_cflags=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[#include <altivec.h>
+ typedef vector unsigned char block;
+ typedef vector unsigned int vecu32;
+ block fn(block in)
+ {
+ block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0));
+ vecu32 y = vec_vsx_ld (0, (unsigned int*)0);
+ return vec_cipher_be (t, in) ^ (block)y;
+ }]])],
+ [gcry_cv_cc_ppc_altivec_cflags=yes])])
+ if test "$gcry_cv_cc_ppc_altivec_cflags" = "yes" ; then
+ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC,1,
+ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics])
+ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC_WITH_CFLAGS,1,
+ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics with extra GCC flags])
+ fi
+fi
+
+AM_CONDITIONAL(ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS,
+ test "$gcry_cv_cc_ppc_altivec_cflags" = "yes")
+
+# Restore flags.
+CFLAGS=$_gcc_cflags_save;
+
+
+#
+# Check whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions],
+ [gcry_cv_gcc_inline_asm_ppc_altivec],
+ [if test "$mpi_cpu_arch" != "ppc" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_ppc_altivec="n/a"
+ else
+ gcry_cv_gcc_inline_asm_ppc_altivec=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(".globl testfn;\n"
+ ".text\n\t"
+ "testfn:\n"
+ "stvx %v31,%r12,%r0;\n"
+ "lvx %v20,%r12,%r0;\n"
+ "vcipher %v0, %v1, %v22;\n"
+ "lxvw4x %vs32, %r0, %r1;\n"
+ "vadduwm %v0, %v1, %v22;\n"
+ "vshasigmaw %v0, %v1, 0, 15;\n"
+ "vshasigmad %v0, %v1, 0, 15;\n"
+ "vpmsumd %v11, %v11, %v11;\n"
+ );
+ ]], [ testfn(); ] )],
+ [gcry_cv_gcc_inline_asm_ppc_altivec=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_ppc_altivec" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC,1,
+ [Defined if inline assembler supports PowerPC AltiVec/VSX/crypto instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports PowerISA 3.00 instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports PowerISA 3.00 instructions],
+ [gcry_cv_gcc_inline_asm_ppc_arch_3_00],
+ [if test "$mpi_cpu_arch" != "ppc" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_ppc_arch_3_00="n/a"
+ else
+ gcry_cv_gcc_inline_asm_ppc_arch_3_00=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[__asm__(".text\n\t"
+ ".globl testfn;\n"
+ "testfn:\n"
+ "stxvb16x %r1,%v12,%v30;\n"
+ );
+ ]], [ testfn(); ])],
+ [gcry_cv_gcc_inline_asm_ppc_arch_3_00=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_ppc_arch_3_00" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00,1,
+ [Defined if inline assembler supports PowerISA 3.00 instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports zSeries instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports zSeries instructions],
+ [gcry_cv_gcc_inline_asm_s390x],
+ [if test "$mpi_cpu_arch" != "s390x" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_s390x="n/a"
+ else
+ gcry_cv_gcc_inline_asm_s390x=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[typedef unsigned int u128_t __attribute__ ((mode (TI)));
+ unsigned int testfunc(unsigned int x, void *y, unsigned int z)
+ {
+ unsigned long fac[8];
+ register unsigned long reg0 asm("0") = 0;
+ register unsigned long reg1 asm("1") = x;
+ u128_t r1 = ((u128_t)(unsigned long)y << 64) | (unsigned long)z;
+ u128_t r2 = 0;
+ u128_t r3 = 0;
+ asm volatile (".insn rre,0xb92e << 16, %[r1], %[r2]\n\t"
+ : [r1] "+a" (r1), [r2] "+a" (r2)
+ : "r" (reg0), "r" (reg1)
+ : "cc", "memory");
+ asm volatile (".insn rrf,0xb929 << 16, %[r1], %[r2], %[r3], 0\n\t"
+ : [r1] "+a" (r1), [r2] "+a" (r2), [r3] "+a" (r3)
+ : "r" (reg0), "r" (reg1)
+ : "cc", "memory");
+ reg0 = 8 - 1;
+ asm ("stfle %1\n\t"
+ : "+d" (reg0), "=Q" (fac[0])
+ :
+ : "cc", "memory");
+ asm volatile ("mvc 0(16, %0), 0(%1)\n\t"
+ :
+ : "a" (y), "a" (fac)
+ : "memory");
+ asm volatile ("xc 0(16, %0), 0(%0)\n\t"
+ :
+ : "a" (fac)
+ : "memory");
+ asm volatile ("risbgn %%r11, %%r11, 0, 129, 0\n\t"
+ :
+ :
+ : "memory", "r11");
+ asm volatile ("algrk %%r14, %%r14, %%r14\n\t"
+ :
+ :
+ : "memory", "r14");
+ return (unsigned int)r1 ^ reg0;
+ }
+ ]] , [ testfunc(0, 0, 0); ])],
+ [gcry_cv_gcc_inline_asm_s390x=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_s390x" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_S390X,1,
+ [Defined if inline assembler supports zSeries instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports zSeries vector instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports zSeries vector instructions],
+ [gcry_cv_gcc_inline_asm_s390x_vx],
+ [if test "$mpi_cpu_arch" != "s390x" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_s390x_vx="n/a"
+ else
+ gcry_cv_gcc_inline_asm_s390x_vx=no
+ if test "$gcry_cv_gcc_inline_asm_s390x" = "yes" ; then
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[void testfunc(void)
+ {
+ asm volatile (".machine \"z13+vx\"\n\t"
+ "vx %%v0, %%v1, %%v31\n\t"
+ "verllf %%v11, %%v11, (16)(0)\n\t"
+ :
+ :
+ : "memory");
+ }
+ ]], [ testfunc(); ])],
+ [gcry_cv_gcc_inline_asm_s390x_vx=yes])
+ fi
+ fi])
+if test "$gcry_cv_gcc_inline_asm_s390x_vx" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_S390X_VX,1,
+ [Defined if inline assembler supports zSeries vector instructions])
+fi
+
+
+#######################################
+#### Checks for library functions. ####
+#######################################
+
+AC_FUNC_VPRINTF
+# We have replacements for these in src/missing-string.c
+AC_CHECK_FUNCS(stpcpy strcasecmp)
+# We have replacements for these in src/g10lib.h
+AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise)
+# Other checks
+AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4)
+AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime syslog)
+AC_CHECK_FUNCS(syscall fcntl ftruncate flockfile getauxval elf_aux_info)
+AC_CHECK_FUNCS(explicit_bzero explicit_memset getentropy)
+
+GNUPG_CHECK_MLOCK
+
+#
+# Replacement functions.
+#
+AC_REPLACE_FUNCS([getpid clock])
+
+
+#
+# Check whether it is necessary to link against libdl.
+#
+DL_LIBS=""
+if test "$use_hmac_binary_check" = yes ; then
+ _gcry_save_libs="$LIBS"
+ LIBS=""
+ AC_SEARCH_LIBS(dlopen, c dl,,,)
+ DL_LIBS=$LIBS
+ LIBS="$_gcry_save_libs"
+fi
+AC_SUBST(DL_LIBS)
+
+
+#
+# Check whether we can use Linux capabilities as requested.
+#
+if test "$use_capabilities" = "yes" ; then
+use_capabilities=no
+AC_CHECK_HEADERS(sys/capability.h)
+if test "$ac_cv_header_sys_capability_h" = "yes" ; then
+ AC_CHECK_LIB(cap, cap_init, ac_need_libcap=1)
+ if test "$ac_cv_lib_cap_cap_init" = "yes"; then
+ AC_DEFINE(USE_CAPABILITIES,1,
+ [define if capabilities should be used])
+ LIBS="$LIBS -lcap"
+ use_capabilities=yes
+ fi
+fi
+if test "$use_capabilities" = "no" ; then
+ AC_MSG_WARN([[
+***
+*** The use of capabilities on this system is not possible.
+*** You need a recent Linux kernel and some patches:
+*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9)
+*** fcap-module-990613.tar.gz (kernel module)
+*** libcap-1.92.tar.gz (user mode library and utilities)
+*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN
+*** set (filesystems menu). Be warned: This code is *really* ALPHA.
+***]])
+fi
+fi
+
+# Check whether a random device is available.
+if test "$try_dev_random" = yes ; then
+ AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
+ [if test -r "$NAME_OF_DEV_RANDOM" && test -r "$NAME_OF_DEV_URANDOM" ; then
+ ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi])
+ if test "$ac_cv_have_dev_random" = yes; then
+ AC_DEFINE(HAVE_DEV_RANDOM,1,
+ [defined if the system supports a random device] )
+ fi
+else
+ AC_MSG_CHECKING(for random device)
+ ac_cv_have_dev_random=no
+ AC_MSG_RESULT(has been disabled)
+fi
+
+# Figure out the random modules for this configuration.
+if test "$random" = "default"; then
+
+ # Select default value.
+ if test "$ac_cv_have_dev_random" = yes; then
+ # Try Linuxish random device.
+ random_modules="linux"
+ else
+ case "${host}" in
+ *-*-mingw32ce*)
+ # WindowsCE random device.
+ random_modules="w32ce"
+ ;;
+ *-*-mingw32*|*-*-cygwin*)
+ # Windows random device.
+ random_modules="w32"
+ ;;
+ *)
+ # Build everything, allow to select at runtime.
+ random_modules="$auto_random_modules"
+ ;;
+ esac
+ fi
+else
+ if test "$random" = "auto"; then
+ # Build everything, allow to select at runtime.
+ random_modules="$auto_random_modules"
+ else
+ random_modules="$random"
+ fi
+fi
+
+
+#
+# Other defines
+#
+if test mym4_isgit = "yes"; then
+ AC_DEFINE(IS_DEVELOPMENT_VERSION,1,
+ [Defined if this is not a regular release])
+fi
+
+
+AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes)
+
+
+# This is handy for debugging so the compiler doesn't rearrange
+# things and eliminate variables.
+AC_ARG_ENABLE(optimization,
+ AS_HELP_STRING([--disable-optimization],
+ [disable compiler optimization]),
+ [if test $enableval = no ; then
+ CFLAGS=`echo $CFLAGS | sed 's/-O[[0-9]]//'`
+ fi])
+
+AC_MSG_NOTICE([checking for cc features])
+# CFLAGS mangling when using gcc.
+if test "$GCC" = yes; then
+ AC_MSG_CHECKING([if gcc supports -fno-delete-null-pointer-checks])
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-fno-delete-null-pointer-checks"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no)
+ AC_MSG_RESULT($_gcc_wopt)
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -fno-delete-null-pointer-checks"
+ fi
+
+ CFLAGS="$CFLAGS -Wall"
+ if test "$USE_MAINTAINER_MODE" = "yes"; then
+ CFLAGS="$CFLAGS -Wcast-align -Wshadow -Wstrict-prototypes"
+ CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security"
+
+ # If -Wno-missing-field-initializers is supported we can enable a
+ # a bunch of really useful warnings.
+ AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers])
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-Wno-missing-field-initializers"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no)
+ AC_MSG_RESULT($_gcc_wopt)
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -W -Wextra -Wbad-function-cast"
+ CFLAGS="$CFLAGS -Wwrite-strings"
+ CFLAGS="$CFLAGS -Wdeclaration-after-statement"
+ CFLAGS="$CFLAGS -Wno-missing-field-initializers"
+ CFLAGS="$CFLAGS -Wno-sign-compare"
+ fi
+
+ AC_MSG_CHECKING([if gcc supports -Wpointer-arith])
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-Wpointer-arith"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no)
+ AC_MSG_RESULT($_gcc_wopt)
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -Wpointer-arith"
+ fi
+ fi
+fi
+
+# Check whether as(1) supports a noeexecstack feature. This test
+# includes an override option.
+CL_AS_NOEXECSTACK
+
+
+AC_SUBST(LIBGCRYPT_CONFIG_API_VERSION)
+AC_SUBST(LIBGCRYPT_CONFIG_LIBS)
+AC_SUBST(LIBGCRYPT_CONFIG_CFLAGS)
+AC_SUBST(LIBGCRYPT_CONFIG_HOST)
+AC_SUBST(LIBGCRYPT_THREAD_MODULES)
+
+AC_CONFIG_COMMANDS([gcrypt-conf],[[
+chmod +x src/libgcrypt-config
+]],[[
+prefix=$prefix
+exec_prefix=$exec_prefix
+libdir=$libdir
+datadir=$datadir
+DATADIRNAME=$DATADIRNAME
+]])
+
+#####################
+#### Conclusion. ####
+#####################
+
+# Check that requested feature can actually be used and define
+# ENABLE_foo_SUPPORT macros.
+
+if test x"$aesnisupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_ssse3" != "yes" ; then
+ aesnisupport="no (unsupported by compiler)"
+ fi
+fi
+if test x"$shaextsupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_shaext" != "yes" ; then
+ shaextsupport="no (unsupported by compiler)"
+ fi
+fi
+if test x"$pclmulsupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_pclmul" != "yes" ; then
+ pclmulsupport="no (unsupported by compiler)"
+ fi
+fi
+if test x"$sse41support" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_sse41" != "yes" ; then
+ sse41support="no (unsupported by compiler)"
+ fi
+fi
+if test x"$avxsupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_avx" != "yes" ; then
+ avxsupport="no (unsupported by compiler)"
+ fi
+fi
+if test x"$avx2support" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_avx2" != "yes" ; then
+ avx2support="no (unsupported by compiler)"
+ fi
+fi
+if test x"$neonsupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_neon" != "yes" ; then
+ if test "$gcry_cv_gcc_inline_asm_aarch64_neon" != "yes" ; then
+ neonsupport="no (unsupported by compiler)"
+ fi
+ fi
+fi
+if test x"$armcryptosupport" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_aarch32_crypto" != "yes" ; then
+ if test "$gcry_cv_gcc_inline_asm_aarch64_crypto" != "yes" ; then
+ neonsupport="no (unsupported by compiler)"
+ fi
+ fi
+fi
+
+if test x"$aesnisupport" = xyes ; then
+ AC_DEFINE(ENABLE_AESNI_SUPPORT, 1,
+ [Enable support for Intel AES-NI instructions.])
+fi
+if test x"$shaextsupport" = xyes ; then
+ AC_DEFINE(ENABLE_SHAEXT_SUPPORT, 1,
+ [Enable support for Intel SHAEXT instructions.])
+fi
+if test x"$pclmulsupport" = xyes ; then
+ AC_DEFINE(ENABLE_PCLMUL_SUPPORT, 1,
+ [Enable support for Intel PCLMUL instructions.])
+fi
+if test x"$sse41support" = xyes ; then
+ AC_DEFINE(ENABLE_SSE41_SUPPORT, 1,
+ [Enable support for Intel SSE4.1 instructions.])
+fi
+if test x"$avxsupport" = xyes ; then
+ AC_DEFINE(ENABLE_AVX_SUPPORT,1,
+ [Enable support for Intel AVX instructions.])
+fi
+if test x"$avx2support" = xyes ; then
+ AC_DEFINE(ENABLE_AVX2_SUPPORT,1,
+ [Enable support for Intel AVX2 instructions.])
+fi
+if test x"$neonsupport" = xyes ; then
+ AC_DEFINE(ENABLE_NEON_SUPPORT,1,
+ [Enable support for ARM NEON instructions.])
+fi
+if test x"$armcryptosupport" = xyes ; then
+ AC_DEFINE(ENABLE_ARM_CRYPTO_SUPPORT,1,
+ [Enable support for ARMv8 Crypto Extension instructions.])
+fi
+if test x"$ppccryptosupport" = xyes ; then
+ AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1,
+ [Enable support for POWER 8 (PowerISA 2.07) crypto extension.])
+fi
+if test x"$jentsupport" = xyes ; then
+ AC_DEFINE(ENABLE_JENT_SUPPORT, 1,
+ [Enable support for the jitter entropy collector.])
+fi
+if test x"$padlocksupport" = xyes ; then
+ AC_DEFINE(ENABLE_PADLOCK_SUPPORT, 1,
+ [Enable support for the PadLock engine.])
+fi
+if test x"$drngsupport" = xyes ; then
+ AC_DEFINE(ENABLE_DRNG_SUPPORT, 1,
+ [Enable support for Intel DRNG (RDRAND instruction).])
+fi
+
+
+if test x"$force_soft_hwfeatures" = xyes ; then
+ AC_DEFINE(ENABLE_FORCE_SOFT_HWFEATURES, 1,
+ [Enable forcing 'soft' HW feature bits on (for testing).])
+fi
+
+# Define conditional sources and config.h symbols depending on the
+# selected ciphers, pubkey-ciphers, digests, kdfs, and random modules.
+
+LIST_MEMBER(arcfour, $enabled_ciphers)
+if test "$found" = "1"; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour.lo"
+ AC_DEFINE(USE_ARCFOUR, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour-amd64.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(blowfish, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish.lo"
+ AC_DEFINE(USE_BLOWFISH, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-amd64.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-arm.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(cast5, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5.lo"
+ AC_DEFINE(USE_CAST5, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-amd64.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-arm.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(des, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS des.lo"
+ AC_DEFINE(USE_DES, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS des-amd64.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(aes, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael.lo"
+ AC_DEFINE(USE_AES, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-amd64.lo"
+
+ # Build with the SSSE3 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ssse3-amd64.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ssse3-amd64-asm.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-arm.lo"
+
+ # Build with the ARMv8/AArch32 CE implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-ce.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-aarch32-ce.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-aarch64.lo"
+
+ # Build with the ARMv8/AArch64 CE implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-ce.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-aarch64-ce.lo"
+ ;;
+ powerpc64le-*-*)
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc9le.lo"
+ ;;
+ powerpc64-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo"
+ ;;
+ powerpc-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo"
+ ;;
+ s390x-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-s390x.lo"
+ ;;
+ esac
+
+ case "$mpi_cpu_arch" in
+ x86)
+ # Build with the AES-NI implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-aesni.lo"
+
+ # Build with the Padlock implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-padlock.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(twofish, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish.lo"
+ AC_DEFINE(USE_TWOFISH, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-amd64.lo"
+
+ if test x"$avx2support" = xyes ; then
+ # Build with the AVX2 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-avx2-amd64.lo"
+ fi
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-arm.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-aarch64.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(serpent, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent.lo"
+ AC_DEFINE(USE_SERPENT, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the SSE2 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-sse2-amd64.lo"
+ ;;
+ esac
+
+ if test x"$avx2support" = xyes ; then
+ # Build with the AVX2 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-avx2-amd64.lo"
+ fi
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-armv7-neon.lo"
+ fi
+fi
+
+LIST_MEMBER(rfc2268, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rfc2268.lo"
+ AC_DEFINE(USE_RFC2268, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(seed, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS seed.lo"
+ AC_DEFINE(USE_SEED, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(camellia, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia.lo camellia-glue.lo"
+ AC_DEFINE(USE_CAMELLIA, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-arm.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aarch64.lo"
+ ;;
+ esac
+
+ if test x"$avxsupport" = xyes ; then
+ if test x"$aesnisupport" = xyes ; then
+ # Build with the AES-NI/AVX implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx-amd64.lo"
+ fi
+ fi
+
+ if test x"$avx2support" = xyes ; then
+ if test x"$aesnisupport" = xyes ; then
+ # Build with the AES-NI/AVX2 implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx2-amd64.lo"
+ fi
+ fi
+fi
+
+LIST_MEMBER(idea, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS idea.lo"
+ AC_DEFINE(USE_IDEA, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(salsa20, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20.lo"
+ AC_DEFINE(USE_SALSA20, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20-amd64.lo"
+ ;;
+ esac
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20-armv7-neon.lo"
+ fi
+fi
+
+LIST_MEMBER(gost28147, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS gost28147.lo"
+ AC_DEFINE(USE_GOST28147, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(chacha20, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20.lo"
+ AC_DEFINE(USE_CHACHA20, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-amd64-ssse3.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-amd64-avx2.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-aarch64.lo"
+ ;;
+ powerpc64le-*-*)
+ # Build with the ppc8 vector implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-ppc.lo"
+ ;;
+ powerpc64-*-*)
+ # Build with the ppc8 vector implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-ppc.lo"
+ ;;
+ powerpc-*-*)
+ # Build with the ppc8 vector implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-ppc.lo"
+ ;;
+ s390x-*-*)
+ # Build with the s390x/zSeries vector implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-s390x.lo"
+ ;;
+ esac
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS chacha20-armv7-neon.lo"
+ fi
+fi
+
+LIST_MEMBER(sm4, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sm4.lo"
+ AC_DEFINE(USE_SM4, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sm4-aesni-avx-amd64.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sm4-aesni-avx2-amd64.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(dsa, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS dsa.lo"
+ AC_DEFINE(USE_DSA, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(rsa, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS rsa.lo"
+ AC_DEFINE(USE_RSA, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(elgamal, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS elgamal.lo"
+ AC_DEFINE(USE_ELGAMAL, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(ecc, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS \
+ ecc.lo ecc-curves.lo ecc-misc.lo \
+ ecc-ecdh.lo ecc-ecdsa.lo ecc-eddsa.lo ecc-gost.lo \
+ ecc-sm2.lo"
+ AC_DEFINE(USE_ECC, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(crc, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc.lo"
+ AC_DEFINE(USE_CRC, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ i?86-*-* | x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc-intel-pclmul.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-armv8-ce.lo"
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-armv8-aarch64-ce.lo"
+ ;;
+ powerpc64le-*-*)
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
+ ;;
+ powerpc64-*-*)
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
+ ;;
+ powerpc-*-*)
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(gostr3411-94, $enabled_digests)
+if test "$found" = "1" ; then
+ # GOST R 34.11-94 internally uses GOST 28147-89
+ LIST_MEMBER(gost28147, $enabled_ciphers)
+ if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS gostr3411-94.lo"
+ AC_DEFINE(USE_GOST_R_3411_94, 1, [Defined if this module should be included])
+ fi
+fi
+
+LIST_MEMBER(stribog, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS stribog.lo"
+ AC_DEFINE(USE_GOST_R_3411_12, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(md2, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md2.lo"
+ AC_DEFINE(USE_MD2, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(md4, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo"
+ AC_DEFINE(USE_MD4, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(md5, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md5.lo"
+ AC_DEFINE(USE_MD5, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(rmd160, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo"
+ AC_DEFINE(USE_RMD160, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(sha256, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256.lo"
+ AC_DEFINE(USE_SHA256, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ssse3-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-avx-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-avx2-bmi2-amd64.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-armv8-aarch32-ce.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-armv8-aarch64-ce.lo"
+ ;;
+ powerpc64le-*-*)
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
+ ;;
+ powerpc64-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
+ ;;
+ powerpc-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
+ esac
+
+ case "$mpi_cpu_arch" in
+ x86)
+ # Build with the SHAEXT implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-intel-shaext.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(sha512, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512.lo"
+ AC_DEFINE(USE_SHA512, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ssse3-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx2-bmi2-amd64.lo"
+ ;;
+ i?86-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ssse3-i386.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-arm.lo"
+ ;;
+ powerpc64le-*-*)
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
+ ;;
+ powerpc64-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
+ ;;
+ powerpc-*-*)
+ # Big-Endian.
+ # Build with the crypto extension implementation
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
+ esac
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-armv7-neon.lo"
+ fi
+fi
+
+LIST_MEMBER(sha3, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS keccak.lo"
+ AC_DEFINE(USE_SHA3, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ :
+ ;;
+ esac
+
+ if test x"$neonsupport" = xyes ; then
+ # Build with the NEON implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS keccak-armv7-neon.lo"
+ fi
+fi
+
+LIST_MEMBER(tiger, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS tiger.lo"
+ AC_DEFINE(USE_TIGER, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(whirlpool, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool.lo"
+ AC_DEFINE(USE_WHIRLPOOL, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool-sse2-amd64.lo"
+ ;;
+ esac
+fi
+
+LIST_MEMBER(blake2, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS blake2.lo"
+ AC_DEFINE(USE_BLAKE2, 1, [Defined if this module should be included])
+
+ case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS blake2b-amd64-avx2.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS blake2s-amd64-avx.lo"
+ ;;
+ esac
+fi
+
+# SHA-1 needs to be included always for example because it is used by
+# random-csprng.c.
+GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1.lo"
+AC_DEFINE(USE_SHA1, 1, [Defined if this module should be included])
+
+case "${host}" in
+ x86_64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-ssse3-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx-bmi2-amd64.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-avx2-bmi2-amd64.lo"
+ ;;
+ arm*-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-armv7-neon.lo"
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-armv8-aarch32-ce.lo"
+ ;;
+ aarch64-*-*)
+ # Build with the assembly implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-armv8-aarch64-ce.lo"
+ ;;
+esac
+
+case "$mpi_cpu_arch" in
+ x86)
+ # Build with the SHAEXT implementation
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-intel-shaext.lo"
+ ;;
+esac
+
+LIST_MEMBER(sm3, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sm3.lo"
+ AC_DEFINE(USE_SM3, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(scrypt, $enabled_kdfs)
+if test "$found" = "1" ; then
+ GCRYPT_KDFS="$GCRYPT_KDFS scrypt.lo"
+ AC_DEFINE(USE_SCRYPT, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(linux, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndlinux.lo"
+ AC_DEFINE(USE_RNDLINUX, 1, [Defined if the /dev/random RNG should be used.])
+fi
+
+LIST_MEMBER(unix, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndunix.lo"
+ AC_DEFINE(USE_RNDUNIX, 1, [Defined if the default Unix RNG should be used.])
+fi
+
+LIST_MEMBER(egd, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndegd.lo"
+ AC_DEFINE(USE_RNDEGD, 1, [Defined if the EGD based RNG should be used.])
+fi
+
+LIST_MEMBER(w32, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32.lo"
+ AC_DEFINE(USE_RNDW32, 1,
+ [Defined if the Windows specific RNG should be used.])
+fi
+
+LIST_MEMBER(w32ce, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32ce.lo"
+ AC_DEFINE(USE_RNDW32CE, 1,
+ [Defined if the WindowsCE specific RNG should be used.])
+fi
+
+AC_SUBST([GCRYPT_CIPHERS])
+AC_SUBST([GCRYPT_PUBKEY_CIPHERS])
+AC_SUBST([GCRYPT_DIGESTS])
+AC_SUBST([GCRYPT_KDFS])
+AC_SUBST([GCRYPT_RANDOM])
+
+AC_SUBST(LIBGCRYPT_CIPHERS, $enabled_ciphers)
+AC_SUBST(LIBGCRYPT_PUBKEY_CIPHERS, $enabled_pubkey_ciphers)
+AC_SUBST(LIBGCRYPT_DIGESTS, $enabled_digests)
+
+# For printing the configuration we need a colon separated list of
+# algorithm names.
+tmp=`echo "$enabled_ciphers" | tr ' ' : `
+AC_DEFINE_UNQUOTED(LIBGCRYPT_CIPHERS, "$tmp",
+ [List of available cipher algorithms])
+tmp=`echo "$enabled_pubkey_ciphers" | tr ' ' : `
+AC_DEFINE_UNQUOTED(LIBGCRYPT_PUBKEY_CIPHERS, "$tmp",
+ [List of available public key cipher algorithms])
+tmp=`echo "$enabled_digests" | tr ' ' : `
+AC_DEFINE_UNQUOTED(LIBGCRYPT_DIGESTS, "$tmp",
+ [List of available digest algorithms])
+tmp=`echo "$enabled_kdfs" | tr ' ' : `
+AC_DEFINE_UNQUOTED(LIBGCRYPT_KDFS, "$tmp",
+ [List of available KDF algorithms])
+
+
+#
+# Define conditional sources depending on the used hardware platform.
+# Note that all possible modules must also be listed in
+# src/Makefile.am (EXTRA_libgcrypt_la_SOURCES).
+#
+GCRYPT_HWF_MODULES=
+case "$mpi_cpu_arch" in
+ x86)
+ AC_DEFINE(HAVE_CPU_ARCH_X86, 1, [Defined for the x86 platforms])
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-x86.lo"
+ ;;
+ alpha)
+ AC_DEFINE(HAVE_CPU_ARCH_ALPHA, 1, [Defined for Alpha platforms])
+ ;;
+ sparc)
+ AC_DEFINE(HAVE_CPU_ARCH_SPARC, 1, [Defined for SPARC platforms])
+ ;;
+ mips)
+ AC_DEFINE(HAVE_CPU_ARCH_MIPS, 1, [Defined for MIPS platforms])
+ ;;
+ m68k)
+ AC_DEFINE(HAVE_CPU_ARCH_M68K, 1, [Defined for M68k platforms])
+ ;;
+ ppc)
+ AC_DEFINE(HAVE_CPU_ARCH_PPC, 1, [Defined for PPC platforms])
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-ppc.lo"
+ ;;
+ arm)
+ AC_DEFINE(HAVE_CPU_ARCH_ARM, 1, [Defined for ARM platforms])
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-arm.lo"
+ ;;
+ aarch64)
+ AC_DEFINE(HAVE_CPU_ARCH_ARM, 1, [Defined for ARM AArch64 platforms])
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-arm.lo"
+ ;;
+ s390x)
+ AC_DEFINE(HAVE_CPU_ARCH_S390X, 1, [Defined for s390x/zSeries platforms])
+ GCRYPT_HWF_MODULES="libgcrypt_la-hwf-s390x.lo"
+ ;;
+esac
+AC_SUBST([GCRYPT_HWF_MODULES])
+
+
+#
+# Option to disable building of doc file
+#
+build_doc=yes
+AC_ARG_ENABLE([doc], AS_HELP_STRING([--disable-doc],
+ [do not build the documentation]),
+ build_doc=$enableval, build_doc=yes)
+AM_CONDITIONAL([BUILD_DOC], [test "x$build_doc" != xno])
+
+
+#
+# Provide information about the build.
+#
+BUILD_REVISION="mym4_revision"
+AC_SUBST(BUILD_REVISION)
+AC_DEFINE_UNQUOTED(BUILD_REVISION, "$BUILD_REVISION",
+ [GIT commit id revision used to build this package])
+
+changequote(,)dnl
+BUILD_VERSION=`echo "$PACKAGE_VERSION" | sed 's/\([0-9.]*\).*/\1./'`
+changequote([,])dnl
+BUILD_VERSION="${BUILD_VERSION}mym4_revision_dec"
+BUILD_FILEVERSION=`echo "${BUILD_VERSION}" | tr . ,`
+AC_SUBST(BUILD_VERSION)
+AC_SUBST(BUILD_FILEVERSION)
+
+AC_ARG_ENABLE([build-timestamp],
+ AS_HELP_STRING([--enable-build-timestamp],
+ [set an explicit build timestamp for reproducibility.
+ (default is the current time in ISO-8601 format)]),
+ [if test "$enableval" = "yes"; then
+ BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
+ else
+ BUILD_TIMESTAMP="$enableval"
+ fi],
+ [BUILD_TIMESTAMP="<none>"])
+AC_SUBST(BUILD_TIMESTAMP)
+AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP",
+ [The time this package was configured for a build])
+
+
+# And create the files.
+AC_CONFIG_FILES([
+Makefile
+m4/Makefile
+compat/Makefile
+mpi/Makefile
+cipher/Makefile
+random/Makefile
+doc/Makefile
+src/Makefile
+src/gcrypt.h
+src/libgcrypt-config
+src/libgcrypt.pc
+src/versioninfo.rc
+tests/Makefile
+])
+AC_CONFIG_FILES([tests/hashtest-256g], [chmod +x tests/hashtest-256g])
+AC_CONFIG_FILES([tests/basic-disable-all-hwf], [chmod +x tests/basic-disable-all-hwf])
+AC_OUTPUT
+
+
+detection_module="${GCRYPT_HWF_MODULES%.lo}"
+test -n "$detection_module" || detection_module="none"
+
+# Give some feedback
+GCRY_MSG_SHOW([],[])
+GCRY_MSG_SHOW([Libgcrypt],[v${VERSION} has been configured as follows:])
+GCRY_MSG_SHOW([],[])
+GCRY_MSG_SHOW([Platform: ],[$PRINTABLE_OS_NAME ($host)])
+GCRY_MSG_SHOW([Hardware detection module:],[$detection_module])
+GCRY_MSG_WRAP([Enabled cipher algorithms:],[$enabled_ciphers])
+GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests])
+GCRY_MSG_WRAP([Enabled kdf algorithms: ],[$enabled_kdfs])
+GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers])
+GCRY_MSG_SHOW([Random number generator: ],[$random])
+GCRY_MSG_SHOW([Try using jitter entropy: ],[$jentsupport])
+GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities])
+GCRY_MSG_SHOW([Try using Padlock crypto: ],[$padlocksupport])
+GCRY_MSG_SHOW([Try using AES-NI crypto: ],[$aesnisupport])
+GCRY_MSG_SHOW([Try using Intel SHAEXT: ],[$shaextsupport])
+GCRY_MSG_SHOW([Try using Intel PCLMUL: ],[$pclmulsupport])
+GCRY_MSG_SHOW([Try using Intel SSE4.1: ],[$sse41support])
+GCRY_MSG_SHOW([Try using DRNG (RDRAND): ],[$drngsupport])
+GCRY_MSG_SHOW([Try using Intel AVX: ],[$avxsupport])
+GCRY_MSG_SHOW([Try using Intel AVX2: ],[$avx2support])
+GCRY_MSG_SHOW([Try using ARM NEON: ],[$neonsupport])
+GCRY_MSG_SHOW([Try using ARMv8 crypto: ],[$armcryptosupport])
+GCRY_MSG_SHOW([Try using PPC crypto: ],[$ppccryptosupport])
+GCRY_MSG_SHOW([],[])
+
+if test "x${gpg_config_script_warn}" != x; then
+cat <<G10EOF
+ Mismatches between the target platform and the to
+ be used libraries have been been detected for:
+ ${gpg_config_script_warn}
+ Please check above for warning messages.
+
+G10EOF
+fi
+
+if test "$gcry_cv_gcc_attribute_aligned" != "yes" ; then
+cat <<G10EOF
+ Please not that your compiler does not support the GCC style
+ aligned attribute. Using this software may evoke bus errors.
+
+G10EOF
+fi
+
+if test -n "$gpl"; then
+ echo "Please note that you are building a version of Libgcrypt with"
+ echo " $gpl"
+ echo "included. These parts are licensed under the GPL and thus the"
+ echo "use of this library has to comply with the conditions of the GPL."
+ echo ""
+fi
diff --git a/comm/third_party/libgcrypt/doc/ChangeLog-2011 b/comm/third_party/libgcrypt/doc/ChangeLog-2011
new file mode 100644
index 0000000000..de837a057a
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/ChangeLog-2011
@@ -0,0 +1,488 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Remove the gcry_ac interface
+
+2009-10-28 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Add code to build a man page for hmac256.
+ * yat2m.c: New. Taken from GnuPG.
+ * gcrypt.text (hmac256): New section.
+
+2009-10-28 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Multi-Threading): Add examples.
+
+2009-07-02 Daiki Ueno <ueno@unixuser.org>
+
+ * gcrypt.texi (Working with S-expressions): Describe format
+ character '%S'. Typo fixes. Fixes bug#1079.
+
+2009-05-10 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Working with cipher handles): Clarified that
+ keylengths are in bytes.
+
+2009-04-02 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Self-Tests): Fix register fucntion names.
+
+2009-02-22 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Memory allocation): Fix describion of gcry-calloc.
+ Reported by Sergi Blanch i Torné.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Cryptographic Functions): Explain the domain
+ parameter for key generation.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Updates for pubkey generation.
+
+2008-10-20 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Error handler): Fix description of
+ gcry_handler_no_mem_t. Reported by Patrick Strateman. desribe
+ what what the error handler is expected to do. Fixes bug #961.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (FIPS Mode): Add state transition Error to Error.
+ * fips-fsm.fig: Ditto.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Add a couple of index items.
+ (FIPS Mode): Reflect recent changes.
+ (Controlling the library): Describe gcry_fips_mode_active.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (FIPS Mode): Describe new transitions 18 and 19.
+ * fips-fsm.fig: Add new transitions.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Fold the two FIPS appendices into one.
+
+2008-09-11 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Public-Key Subsystem Architecture): Explain RSA
+ blinding.
+
+2008-09-08 Marcus Brinkmann <marcus@g10code.com>
+
+ * gcrypt.texi: Some typos fixed.
+
+2008-09-08 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Formatting cleanups.
+ * lgpl.texi (Library Copying): Replace @appendix by @unnumbered.
+ * gpl.texi (Copying): Ditto.
+
+2008-08-27 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (online): Take care of development versions.
+
+2008-08-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Top): Remove the detailmenu.
+ (Public Key Cryptographi (II)): Move into a section of the PK
+ interface description.
+ (Hashing): Move after the encryption chapters.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Controlling the library): Remove
+ GCRYCTL_DUMP_CONFIG because it is not implemented.
+ (Initializing the library): Describe initialization steps with
+ regard to secure memory.
+
+ * gcrypt.texi (Working with cipher handles): Adjust for
+ implementation changes of gcry_cipher_setkey, gcry_cipher_setiv and
+ gcry_cipher_setctr.
+
+2008-01-04 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Controlling the library): Add remark that the
+ theoritical attack on a seed file is not feasible under Linux.
+
+2007-12-11 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Various minor corrections as reported by Elie De
+ Brauer more than a year ago.
+
+2007-06-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Controlling the library): Clarified the use of
+ GCRYCTL_ENABLE_QUICK_RANDOM.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * HACKING: New. Two items by Marcus.
+ * README.apichanges: Move from .. to here.
+ * Makefile.am (EXTRA_DIST): Add new files.
+
+2007-04-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.texi: Fix some typos.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (General public-key related Functions): Typo.
+
+2006-09-19 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (online): New target.
+
+2006-08-29 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Available ciphers): Add missing ciphers.
+
+2006-03-10 Brad Hards <bradh@frogmouth.net> (wk, patch 2005-04-25)
+
+ * gcrypt.texi: Document SHA-224 and typo fixes.
+
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * gcrypt.texi (Available cipher modes): Typo fix, add a little
+ more detail on cipher modes vs cipher algorithms.
+
+2006-01-08 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Added documentation for more gcry_control commands.
+
+ * gcrypt.texi: Fixed several typos; thanks to Tommi Vainikainen.
+
+2005-12-16 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (MPI formats): Fix return types of functions:
+ gcry_mpi_scan, gcry_mpi_print, gcry_mpi_aprint.
+
+2005-11-26 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: New chapter: Prime numbers.
+
+2005-11-12 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (MPI formats): Document that for gcry_mpi_scan and
+ in the case of GCRYMPI_FMT_HEX, BUFLEN must be zero.
+
+2005-10-31 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Added more gcry_control related descriptions.
+
+2005-10-16 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Controlling the library): Start documenting the
+ existing control commands.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Available hash algorithms): Add entry for Whirlpool.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with IO objects): Document ac io objects;
+ adjust ac scheme functions, which do now use io objects.
+
+2005-03-19 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with cipher handles): Clarify CTS mode.
+
+2005-02-08 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Fixed direntry.
+
+2005-02-13 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Using cryptographic functions): Document new
+ encoding and scheme crypto functionality.
+
+2005-02-03 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Fixed several typos; thanks to Michele Baldessari.
+
+2005-01-04 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Updated to use @copying. Fixed list of copyright
+ years; we had real changes in 2004. Fixed some formatting issues.
+
+2004-08-24 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Miscellaneous): Document gcry_mpi_randomize.
+
+2004-08-18 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Multi Threading): Document
+ GCRY_THREAD_OPTION_PTH_IMPL, GCRY_THREAD_OPTION_PTHREAD_IMPL.
+
+2004-05-07 Moritz Schulte <moritz@g10code.de>
+
+ * gcrypt.texi: Merged several fixes reported by Umberto Salsi.
+
+2004-04-08 Moritz Schulte <moritz@g10code.de>
+
+ * gcrypt.texi (Multi Threading): Typo fix.
+
+2004-03-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.texi (Multi Threading): Partially document new thread
+ support.
+
+2004-02-24 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Calculations): Typo fix.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.texi (General cipher functions): Fixed descriptions of
+ the arguments for GCRYCTL_GET_KEYLEN, GCRYCTL_GET_BLKLEN; reported
+ by Randy.
+
+2004-01-14 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.texi (Public Key cryptography II): Adjusted to new
+ gcry_ac_* API; document flags.
+
+2003-12-04 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (gcrypt_TEXINFOS): Removed fdl.texi.
+
+2003-12-03 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi: Changed license from FDL to GPL because this is a
+ reference manual only useful along with actual code.
+ * fdl.texi: Removed.
+
+ * gcrypt.texi: Minor cleanups
+ (Working with keys): Clarified generation of RSA's E parameter.
+ (Multi Threading): Clarified.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Working with S-expressions): Added "%b".
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Retrieving random numbers): Add gcry_create_nonce.
+
+2003-08-30 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Working with hash algorithms): Clarified that HMAC
+ does not work with all algorithms.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Available asymmetric algorithms): Mention
+ GCRY_AC_ELG_E.
+
+2003-07-28 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with keys): Mention that gcry_pk_testkey
+ and gcry_ac_key_test only verify private keys.
+ (Working with keys): Fix typo.
+ (General public-key related Functions): Fixed some sentences,
+ thanks to Neil Spring.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi: Adjusted description of gcry_mpi_scan and
+ gcry_mpi_dump. Add gcry_mpi_dump.
+
+2003-07-22 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Added more documentation for the register
+ mechanism.
+
+2003-07-18 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Misc): Add a warning on the use of opaque values.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Overview): Mention the non-thread-safe-nature of
+ functions modifying context stored in handles.
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Available ciphers): Added: TWOFISH128.
+ (Error Handling): Merged a lot of documentation taken from GPGME.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with sets of data): Documented:
+ gcry_ac_data_copy.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Documented module system.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with cipher handles): Small fix by Simon
+ Josefsson <jas@extundo.com>.
+
+2003-07-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Documented ac interface.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Small fixes.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * cipher-ref.sgml: Removed file.
+ * digest-ref.sgml: Likewise.
+ * misc-ref.sgml: Likewise.
+ * pubkey-ref.sgml: Likewise.
+ * reference.sgml: Likewise.
+ * version.sgml.in: Likewise.
+
+2003-06-15 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Documented several parts of the library, merged
+ some documentation from GPGME's manual, re-structured the whole
+ manual, added more menus.
+
+2003-06-14 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Hash Functions): Adjusteded description of
+ gcry_md_copy.
+
+2003-06-12 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Public Key Functions): Fix example S-Exp, i.e.:
+ added the number of following digits as prefix to the number of
+ bits.
+ (Public Key Functions): Document the general usage of `flags',
+ including the no-blinding flag.
+
+2003-06-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Hash Functions): Document possible values of HD.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Version Check): Changed description of
+ gcry_check_version; the user now *must* call the function to
+ initialize the library.
+
+2003-06-08 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Change for libgpg-error.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Public Key Functions): Fixed typo.
+
+2003-05-17 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Public Key Functions): Mention that only the
+ checking of secret keys is supported currently.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.texi: Add CTR.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.texi: Add CBC-MAC.
+
+2003-03-04 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Cipher Functions): Added gcry_cipher_reset.
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (gcry_pk_decrypt): Described use of FLAGS
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.texi (Hash Functions): Add CRC.
+
+2003-01-19 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi: Most functions are now documented. Still need to
+ fine tune the menu structure, document some utility functions,
+ mark up indices and references and add examples.
+
+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi: Typo fixes.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ * lgpl.texi: New.
+ * gcrypt.texi: Included lgpl and commented not yet converted text.
+
+2002-04-16 Werner Koch <wk@gnupg.org>
+
+ * version.sgml.in, cipher-ref.sgml, digest-ref.sgml, misc-ref.sgml
+ * pubkey-ref.sgml, reference.sgml: Removed.
+ * gcrypt.texi: New. Based on the old sgml version.
+ * gpl.texi, fdl.texi: New.
+ * Makefile.am: Adjusted for use with texinfo.
+
+2000-12-21 Werner Koch <wk@gnupg.org>
+
+ Renamed the gcryptref.sgml files and removed the GnuPG stuff.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * Makefile.am (SUBDIRS): Removed gph from this development series
+
+Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am (SUBDIRS): New subdir gph for the manual.
+
+Thu Jul 22 20:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gpg.sgml (--always-trust): Added.
+
+Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Create a dummy man page if docbook-to-man is missing.
+
+Wed Jun 16 20:16:21 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gpg1.pod: Removed.
+ * gpg.sgml: New. Replaces the pod file
+ * Makefile.am: Add rule to make a man file from sgml
+
+Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.in.in: Use DESTDIR.
+
+Mon May 31 19:41:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gpg.1pod: Enhanced the Bugs section (Michael).
+
+Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gpg.1pod: Spelling and grammar corrections (John A. Martin)
+ * FAQ: Ditto.
+ * DETAILS: Ditto.
+
+ Copyright 1999, 2000, 2002, 2003, 2008 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/doc/DCO b/comm/third_party/libgcrypt/doc/DCO
new file mode 100644
index 0000000000..ee460f6b68
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/DCO
@@ -0,0 +1,29 @@
+Libgcrypt Developer's Certificate of Origin. Version 1.0
+=========================================================
+
+By making a contribution to the Libgcrypt project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the free software license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the
+ best of my knowledge, is covered under an appropriate free
+ software license and I have the right under that license to
+ submit that work with modifications, whether created in whole
+ or in part by me, under the same free software license
+ (unless I am permitted to submit under a different license),
+ as indicated in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including
+ all personal information I submit with it, including my
+ sign-off) is maintained indefinitely and may be redistributed
+ consistent with this project or the free software license(s)
+ involved.
+
+Signed-off-by: [Your name and mail address]
diff --git a/comm/third_party/libgcrypt/doc/HACKING b/comm/third_party/libgcrypt/doc/HACKING
new file mode 100644
index 0000000000..0cb8d56098
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/HACKING
@@ -0,0 +1,143 @@
+# HACKING -*- org -*-
+#+TITLE: Hacking notes for Libgcrypt
+#+STARTUP: showall
+
+* How to contribute
+
+ The following stuff explains some basic procedures you need to
+ follow if you want to contribute code or documentation.
+
+** No more ChangeLog files
+
+ Do not modify any of the ChangeLog files in Libgcrypt. Starting on
+ December 1st, 2011 we put change information only in the GIT commit
+ log, and generate a top-level ChangeLog file from logs at "make
+ dist" time. As such, there are strict requirements on the form of
+ the commit log messages. The old ChangeLog files have all be
+ renamed to ChangeLog-2011
+
+** Commit log requirements
+
+ Your commit log should always start with a one-line summary, the
+ second line should be blank, and the remaining lines are usually
+ ChangeLog-style entries for all affected files. However, it's fine
+ -- even recommended -- to write a few lines of prose describing the
+ change, when the summary and ChangeLog entries don't give enough of
+ the big picture. Omit the leading TABs that you're used to seeing
+ in a "real" ChangeLog file, but keep the maximum line length at 72
+ or smaller, so that the generated ChangeLog lines, each with its
+ leading TAB, will not exceed 80 columns.
+
+** License policy
+
+ Libgcrypt is currently licensed under the LGPLv2+ with tools and the
+ manual being under the GPLv2+. We may eventually update to a newer
+ version of the licenses or a combination of them. It is thus
+ important, that all contributed code allows for an update of the
+ license; for example we can't accept code under the LGPLv2(only).
+
+ Libgcrypt used to have a strict policy of requiring copyright
+ assignments to the FSF. To avoid this major organizational overhead
+ and to allow inclusion of code, not copyrighted by the FSF, this
+ policy has been relaxed. It is now also possible to contribute code
+ by asserting that the contribution is in accordance to the
+ "Libgcrypt Developer's Certificate of Origin" as found in the file
+ "DCO". (Except for a slight wording change, this DCO is identical
+ to the one used by the Linux kernel.)
+
+ If your want to contribute code or documentation to Libgcrypt and
+ you didn't signed a copyright assignment with the FSF in the past,
+ you need to take these simple steps:
+
+ - Decide which mail address you want to use. Please have your real
+ name in the address and not a pseudonym. Anonymous contributions
+ can only be done if you find a proxy who certifies for you.
+
+ - If your employer or school might claim ownership of code written
+ by you; you need to talk to them to make sure that you have the
+ right to contribute under the DCO.
+
+ - Send an OpenPGP signed mail to the gcrypt-devel@gnupg.org mailing
+ list from your mail address. Include a copy of the DCO as found
+ in the official master branch. Insert your name and email address
+ into the DCO in the same way you want to use it later. Example:
+
+ Signed-off-by: Joe R. Hacker <joe@example.org>
+
+ (If you really need it, you may perform simple transformations of
+ the mail address: Replacing "@" by " at " or "." by " dot ".)
+
+ - That's it. From now on you only need to add a "Signed-off-by:"
+ line with your name and mail address to the commit message. It is
+ recommended to send the patches using a PGP/MIME signed mail.
+
+** Coding standards
+
+ Please follow the GNU coding standards. If you are in doubt consult
+ the existing code as an example. Do no re-indent code without a
+ need. If you really need to do it, use a separate commit for such a
+ change.
+
+
+* Porting hints
+** Taking optimized MPI code out of GMP:
+
+ I generated the pentium4/* files by glueing the existing assembler
+ prologues to the GMP 4.2.1 assembler files generated with the m4
+ tool in GMP's build process, for example:
+
+ $ m4 -DHAVE_CONFIG_H -D__GMP_WITHIN_GMP -DOPERATION_rshift -DPIC \
+ rshift.asm >tmp-rshift.s
+
+ Then tmp-rshift will contain the assembler instructions for the
+ configured platform. Unfortunately, this way the comments are lost.
+ For most files I re-inserted some of the comments, but this is
+ tedious work.
+
+
+* Debug hints
+
+** Debugging math stuff:
+
+ While debugging the ECC code in libgcrypt, I was in need for some
+ computer algebra system which would allow me to verify the numbers
+ in the debugging easily. I found that PARI (pari-gp package in
+ Debian) has support for elliptic curves. The below commands shows
+ how they are set up and used with an example.
+
+ ===8<========
+ hextodec(s)=local(v=Vec(s),a=10,b=11,c=12,d=13,e=14,f=15,A=10,B=11,C=12,D=13,E=14,F=15,h);if(#setunion(Set(v),Vec("0123456789ABCDEFabcdef"))>22,error);for(i=1,#v,h=shift(h,4)+eval(v[i]));h
+
+ p = hextodec("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
+ a = hextodec("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")
+ b = hextodec("51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")
+
+ /* Set up y^2 = x^3 + ax + b mod (p). */
+ e = ellinit(Mod(1,p)*[0,0,0,a,b]);
+
+ gx = hextodec ("00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")
+ gy = hextodec ("011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650")
+ g = Mod(1,p)*[gx,gy]
+
+ n = hextodec ("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409")
+
+ /* Verify that G is on the curve, and that n is the order. */
+ ellisoncurve (e,g)
+ isprime (n)
+ ellpow (e,g,n)
+
+ d = hextodec ("018F9573F25059571BDF614529953DE2540497CEDABD04F3AF78813BED7BB163A2FD919EECF822848FCA39EF55E500F8CE861C7D53D371857F7774B79428E887F81B")
+
+ qx = hextodec ("00316AAAD3E905875938F588BD9E8A4785EF9BDB76D62A83A5340F82CB8E800B25619F5C3EA02B7A4FA43D7497C7702F7DFBEAC8E8F92C3CAABD9F84182FDA391B3B")
+ /* Note: WRONG! (It is apparent that this is the same as X shifted by
+ 8 bit). */
+ qy = hextodec ("0000316AAAD3E905875938F588BD9E8A4785EF9BDB76D62A83A5340F82CB8E800B25619F5C3EA02B7A4FA43D7497C7702F7DFBEAC8E8F92C3CAABD9F84182FDA391B")
+ q = Mod(1,p)*[qx,qy]
+
+ /* Calculate what Q should be given d. */
+ ellpow (e,g,d)
+
+ /* This is not 0 and thus shows that libgcrypt gave Q and d that do
+ not match. */
+ ellpow (e,g,d) - q
+ ====8<=====================
diff --git a/comm/third_party/libgcrypt/doc/Makefile.am b/comm/third_party/libgcrypt/doc/Makefile.am
new file mode 100644
index 0000000000..fd7aac2f45
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/Makefile.am
@@ -0,0 +1,106 @@
+## Process this file with automake to create Makefile.in
+# Copyright (C) 2002 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
+
+EXTRA_DIST = README.apichanges HACKING DCO \
+ libgcrypt-modules.eps fips-fsm.eps \
+ libgcrypt-modules.png fips-fsm.png \
+ libgcrypt-modules.pdf fips-fsm.pdf \
+ yat2m.c
+
+DISTCLEANFILES = gcrypt.cps yat2m-stamp.tmp yat2m-stamp $(myman_pages)
+CLEANFILES = yat2m
+
+BUILT_SOURCES = libgcrypt-modules.eps fips-fsm.eps \
+ libgcrypt-modules.png fips-fsm.png \
+ libgcrypt-modules.pdf fips-fsm.pdf
+
+info_TEXINFOS = gcrypt.texi
+gcrypt_TEXINFOS = lgpl.texi gpl.texi libgcrypt-modules.fig fips-fsm.fig
+
+YAT2M_OPTIONS = -I $(srcdir) \
+ --release "Libgcrypt @PACKAGE_VERSION@" --source "Libgcrypt"
+
+myman_sources = gcrypt.texi
+myman_pages = hmac256.1
+
+man_MANS = $(myman_pages)
+
+yat2m: yat2m.c
+ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) \
+ $(CPPFLAGS_FOR_BUILD)-o $@ $(srcdir)/yat2m.c
+
+.fig.png:
+ fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.jpg:
+ fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.eps:
+ fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.pdf:
+ fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+yat2m-stamp: $(myman_sources)
+ @rm -f yat2m-stamp.tmp
+ @touch yat2m-stamp.tmp
+ for file in $(myman_sources) ; do \
+ ./yat2m $(YAT2M_OPTIONS) --store \
+ `test -f '$$file' || echo '$(srcdir)/'`$$file ; done
+ @mv -f yat2m-stamp.tmp $@
+
+yat2m-stamp: yat2m
+
+$(myman_pages) : yat2m-stamp
+ @if test -f $@; then :; else \
+ trap 'rm -rf yat2m-stamp yat2m-lock' 1 2 13 15; \
+ if mkdir yat2m-lock 2>/dev/null; then \
+ rm -f yat2m-stamp; \
+ $(MAKE) $(AM_MAKEFLAGS) yat2m-stamp; \
+ rmdir yat2m-lock; \
+ else \
+ while test -d yat2m-lock; do sleep 1; done; \
+ test -f yat2m-stamp; exit $$?; \
+ fi; \
+ fi
+
+
+# Make sure that gcrypt.texi is touched if any other source file has
+# been modified. This is required so that the version.texi magic
+# updates the release date.
+gcrypt.texi : $(gcrypt_TEXINFOS)
+ touch $(srcdir)/gcrypt.texi
+
+online: gcrypt.html gcrypt.pdf gcrypt.info
+ set -e; \
+ echo "Uploading current manuals to www.gnupg.org ..."; \
+ cp libgcrypt-modules.png gcrypt.html/; \
+ cp fips-fsm.png gcrypt.html/; \
+ user=werner ; dashdevel="" ; \
+ if echo "@PACKAGE_VERSION@" | grep -- "-svn" >/dev/null; then \
+ dashdevel="-devel" ; \
+ cp gcrypt.pdf gcrypt.html/; \
+ cp gcrypt.info gcrypt.html/; \
+ else \
+ rsync -v gcrypt.pdf gcrypt.info \
+ $${user}@trithemius.gnupg.org:webspace/manuals/ ; \
+ fi ; \
+ cd gcrypt.html ; \
+ rsync -vr --exclude='.svn' . \
+ $${user}@trithemius.gnupg.org:webspace/manuals/gcrypt$${dashdevel}/
diff --git a/comm/third_party/libgcrypt/doc/Makefile.in b/comm/third_party/libgcrypt/doc/Makefile.in
new file mode 100644
index 0000000000..90d007d909
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/Makefile.in
@@ -0,0 +1,982 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2002 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
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/version.texi \
+ $(srcdir)/stamp-vti $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+AM_V_DVIPS = $(am__v_DVIPS_@AM_V@)
+am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@)
+am__v_DVIPS_0 = @echo " DVIPS " $@;
+am__v_DVIPS_1 =
+AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@)
+am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@)
+am__v_MAKEINFO_0 = @echo " MAKEINFO" $@;
+am__v_MAKEINFO_1 =
+AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@)
+am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@)
+am__v_INFOHTML_0 = @echo " INFOHTML" $@;
+am__v_INFOHTML_1 =
+AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@)
+am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@)
+am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@;
+am__v_TEXI2DVI_1 =
+AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@)
+am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@)
+am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@;
+am__v_TEXI2PDF_1 =
+AM_V_texinfo = $(am__v_texinfo_@AM_V@)
+am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@)
+am__v_texinfo_0 = -q
+am__v_texinfo_1 =
+AM_V_texidevnull = $(am__v_texidevnull_@AM_V@)
+am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@)
+am__v_texidevnull_0 = > /dev/null
+am__v_texidevnull_1 =
+INFO_DEPS = $(srcdir)/gcrypt.info
+TEXINFO_TEX = $(top_srcdir)/build-aux/texinfo.tex
+am__TEXINFO_TEX_DIR = $(top_srcdir)/build-aux
+DVIS = gcrypt.dvi
+PDFS = gcrypt.pdf
+PSS = gcrypt.ps
+HTMLS = gcrypt.html
+TEXINFOS = gcrypt.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(gcrypt_TEXINFOS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/mdate-sh \
+ $(top_srcdir)/build-aux/texinfo.tex
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = README.apichanges HACKING DCO \
+ libgcrypt-modules.eps fips-fsm.eps \
+ libgcrypt-modules.png fips-fsm.png \
+ libgcrypt-modules.pdf fips-fsm.pdf \
+ yat2m.c
+
+DISTCLEANFILES = gcrypt.cps yat2m-stamp.tmp yat2m-stamp $(myman_pages)
+CLEANFILES = yat2m
+BUILT_SOURCES = libgcrypt-modules.eps fips-fsm.eps \
+ libgcrypt-modules.png fips-fsm.png \
+ libgcrypt-modules.pdf fips-fsm.pdf
+
+info_TEXINFOS = gcrypt.texi
+gcrypt_TEXINFOS = lgpl.texi gpl.texi libgcrypt-modules.fig fips-fsm.fig
+YAT2M_OPTIONS = -I $(srcdir) \
+ --release "Libgcrypt @PACKAGE_VERSION@" --source "Libgcrypt"
+
+myman_sources = gcrypt.texi
+myman_pages = hmac256.1
+man_MANS = $(myman_pages)
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .eps .fig .html .info .jpg .pdf .png .ps .texi
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu doc/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+.texi.info:
+ $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && $(am__cd) $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ else :; fi && \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ $(am__cd) $(srcdir); \
+ else \
+ rc=$$?; \
+ $(am__cd) $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+ $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \
+ $<
+
+.texi.pdf:
+ $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \
+ $<
+
+.texi.html:
+ $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp)
+ $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@ && mv $(@:.html=.htp) $@; \
+ else \
+ rm -rf $(@:.html=.htp); exit 1; \
+ fi
+$(srcdir)/gcrypt.info: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
+gcrypt.dvi: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
+gcrypt.pdf: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
+gcrypt.html: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
+$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
+$(srcdir)/stamp-vti: gcrypt.texi $(top_srcdir)/configure
+ @(dir=.; test -f ./gcrypt.texi || dir=$(srcdir); \
+ set `$(SHELL) $(top_srcdir)/build-aux/mdate-sh $$dir/gcrypt.texi`; \
+ echo "@set UPDATED $$1 $$2 $$3"; \
+ echo "@set UPDATED-MONTH $$2 $$3"; \
+ echo "@set EDITION $(VERSION)"; \
+ echo "@set VERSION $(VERSION)") > vti.tmp$$$$ && \
+ (cmp -s vti.tmp$$$$ $(srcdir)/version.texi \
+ || (echo "Updating $(srcdir)/version.texi" && \
+ cp vti.tmp$$$$ $(srcdir)/version.texi.tmp$$$$ && \
+ mv $(srcdir)/version.texi.tmp$$$$ $(srcdir)/version.texi)) && \
+ rm -f vti.tmp$$$$ $(srcdir)/version.texi.$$$$
+ @cp $(srcdir)/version.texi $@
+
+mostlyclean-vti:
+ -rm -f vti.tmp* $(srcdir)/version.texi.tmp*
+
+maintainer-clean-vti:
+@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
+.dvi.ps:
+ $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) $(AM_V_texinfo) -o $@ $<
+
+uninstall-dvi-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+ rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+ done
+
+uninstall-html-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+uninstall-pdf-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
+uninstall-ps-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(psdir)/$$f"; \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+ if test -f $$file; then \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f "$(distdir)/$$relfile" || \
+ cp -p $$file "$(distdir)/$$relfile"; \
+ else :; fi; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf gcrypt.t2d gcrypt.t2p
+
+clean-aminfo:
+ -test -z "gcrypt.dvi gcrypt.pdf gcrypt.ps gcrypt.html" \
+ || rm -rf gcrypt.dvi gcrypt.pdf gcrypt.ps gcrypt.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+install-man1: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(INFO_DEPS) $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am: $(DVIS)
+ @$(NORMAL_INSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+ done
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am: $(HTMLS)
+ @$(NORMAL_INSTALL)
+ @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__strip_dir) \
+ d2=$$d$$p; \
+ if test -d "$$d2"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+ echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ else \
+ list2="$$list2 $$d2"; \
+ fi; \
+ done; \
+ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+ done; }
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
+ fi; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ echo "$$ifile"; \
+ else : ; fi; \
+ done; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+ @$(POST_INSTALL)
+ @if $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-pdf-am: $(PDFS)
+ @$(NORMAL_INSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-am
+
+install-ps-am: $(PSS)
+ @$(NORMAL_INSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic maintainer-clean-vti
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-vti
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-man uninstall-pdf-am uninstall-ps-am
+
+uninstall-man: uninstall-man1
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
+ clean-libtool cscopelist-am ctags-am dist-info distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man1 install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-aminfo maintainer-clean-generic \
+ maintainer-clean-vti mostlyclean mostlyclean-aminfo \
+ mostlyclean-generic mostlyclean-libtool mostlyclean-vti pdf \
+ pdf-am ps ps-am tags-am uninstall uninstall-am \
+ uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-man uninstall-man1 uninstall-pdf-am uninstall-ps-am
+
+.PRECIOUS: Makefile
+
+
+yat2m: yat2m.c
+ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) \
+ $(CPPFLAGS_FOR_BUILD)-o $@ $(srcdir)/yat2m.c
+
+.fig.png:
+ fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.jpg:
+ fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.eps:
+ fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.pdf:
+ fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+yat2m-stamp: $(myman_sources)
+ @rm -f yat2m-stamp.tmp
+ @touch yat2m-stamp.tmp
+ for file in $(myman_sources) ; do \
+ ./yat2m $(YAT2M_OPTIONS) --store \
+ `test -f '$$file' || echo '$(srcdir)/'`$$file ; done
+ @mv -f yat2m-stamp.tmp $@
+
+yat2m-stamp: yat2m
+
+$(myman_pages) : yat2m-stamp
+ @if test -f $@; then :; else \
+ trap 'rm -rf yat2m-stamp yat2m-lock' 1 2 13 15; \
+ if mkdir yat2m-lock 2>/dev/null; then \
+ rm -f yat2m-stamp; \
+ $(MAKE) $(AM_MAKEFLAGS) yat2m-stamp; \
+ rmdir yat2m-lock; \
+ else \
+ while test -d yat2m-lock; do sleep 1; done; \
+ test -f yat2m-stamp; exit $$?; \
+ fi; \
+ fi
+
+# Make sure that gcrypt.texi is touched if any other source file has
+# been modified. This is required so that the version.texi magic
+# updates the release date.
+gcrypt.texi : $(gcrypt_TEXINFOS)
+ touch $(srcdir)/gcrypt.texi
+
+online: gcrypt.html gcrypt.pdf gcrypt.info
+ set -e; \
+ echo "Uploading current manuals to www.gnupg.org ..."; \
+ cp libgcrypt-modules.png gcrypt.html/; \
+ cp fips-fsm.png gcrypt.html/; \
+ user=werner ; dashdevel="" ; \
+ if echo "@PACKAGE_VERSION@" | grep -- "-svn" >/dev/null; then \
+ dashdevel="-devel" ; \
+ cp gcrypt.pdf gcrypt.html/; \
+ cp gcrypt.info gcrypt.html/; \
+ else \
+ rsync -v gcrypt.pdf gcrypt.info \
+ $${user}@trithemius.gnupg.org:webspace/manuals/ ; \
+ fi ; \
+ cd gcrypt.html ; \
+ rsync -vr --exclude='.svn' . \
+ $${user}@trithemius.gnupg.org:webspace/manuals/gcrypt$${dashdevel}/
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/doc/README.apichanges b/comm/third_party/libgcrypt/doc/README.apichanges
new file mode 100644
index 0000000000..63b64da241
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/README.apichanges
@@ -0,0 +1,115 @@
+README.apichanges 2003-07-28
+
+ NOTE: THESE ARE API CHANGES DONE BEFORE THE FIRST STABLE RELEASE SO
+ THEY ARE NOT RELEVANT ANYMORE [stable is 1.2.4 right now]
+
+We decided to change a couple of annoying things in Libgcrypt and to
+cleanup the API. The new API better fits into a multi-threaded
+environment and is more consistent. One import change is that all
+functions return error codes from a set of error codes shared between
+GnuPG, GPGME and Libgcrypt.
+
+This file contains some hints on how to port your application from
+libgcrypt <= 1.1.12 to the current API as of 1.1.42. We hope that
+there won't be another need for such a major change.
+
+
+* Types
+
+ All types definitions changed to a foo_t scheme; for some time we
+ will support the old names but you better start to rename them:
+
+ s/GCRY_MPI/gcry_mpi_t/
+ s/GcryMPI/gcry_mpi_t/
+ s/GCRY_SEXP/gcry_sexp_t/
+ s/GcrySexp/gcry_sexp_t/
+ s/GCRY_CIPHER_HD/gcry_cipher_hd_t/
+ s/GcryCipherHd/gcry_cipher_hd_t/
+ s/GCRY_MD_HD/gcry_md_hd_t/
+ s/GcryMDHd/gcry_md_hd_t/
+
+* Initialization
+
+ For proper initialization of the library, you must call
+ gcry_check_version() before calling any other function except for
+ these gcry_control operations:
+ GCRYCTL_SUSPEND_SECMEM_WARN
+ GCRYCTL_DISABLE_INTERNAL_LOCKING
+ GCRYCTL_ANY_INITIALIZATION_P
+ GCRYCTL_INITIALIZATION_FINISHED_P
+
+
+* Handles
+
+ gcry_cipher_open and gcry_md_open do now return an error code
+ instead of a NULL handle; the handle is now returned by
+ asigning it to the first argument. Example on how to change your
+ code:
+
+ Old:
+
+ hd = gcry_md_open (algo, flags);
+ if (!hd)
+ {
+ fprintf (stderr, "md_open failed: %s\n", gcry_errno (-1));
+ ....
+
+ New:
+
+ rc = gcry_md_open (&hd, algo, flags);
+ if (rc)
+ {
+ fprintf (stderr, "md_open failed: %s\n", gcry_strerror (rc));
+ ....
+
+ If you are not interested in the error code, you can do it in a
+ simplified way:
+
+ gcry_md_open (&hd, algo, flags);
+ if (!hd)
+ abort ();
+
+ i.e. the function makes sure that HD points to NULL in case of an error.
+ The required change for gcry_cipher_open is similar.
+
+* Message Digests
+
+ The order of the arguments to gcry_md_copy has been changed in order
+ to be more consistent with other functions of this type. This means
+ that the new message digest handle will be a copy of the message
+ handle specified by the second argument and stored at the address
+ pointed to by the first argument.
+
+* Error codes
+
+ gcry_errno () has been removed because it is hard to use in
+ multi-threaded environment. You need to save the error code
+ returned by the functions and use it either numerical or passing it
+ to gcry_strerror (since gcry_strerror is a wrapper function for
+ gpg_strerror, the latter function can also be used).
+
+ Instead of using the error codes GCRYERR_*, you have to use the
+ GPG_ERR_* names.
+
+* S-expressions
+
+ gcry_sexp_canon_len used to return a `historical' error code in
+ `errcode', this is not the case anymore; the value returned in
+ `errcode' is now a standard Libgcrypt (i.e. gpg-error) error code.
+
+* MPI
+
+ gcry_mpi_scan and gcry_mpi_print need the size of a provided buffer
+ as input and return the number of bytes actually scanned/printed to
+ the user. The old API used a single size_t Pointer for both tasks,
+ the new API distinguishes between the input and the output values.
+
+* Public Key cryptography
+
+ gcry_pk_decrypt used to return a `simple S-expression part' that
+ contains a single MPI value. In case the `data' S-expression
+ contains a `flags' element, the result S-expression is filled with a
+ complete S-expression of the following format:
+
+ (value PLAINTEXT)
+
diff --git a/comm/third_party/libgcrypt/doc/fips-fsm.eps b/comm/third_party/libgcrypt/doc/fips-fsm.eps
new file mode 100644
index 0000000000..fbb3a90c3f
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/fips-fsm.eps
@@ -0,0 +1,514 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: /home/wk/s/libgcrypt/doc/fips-fsm.fig
+%%Creator: fig2dev Version 3.2.7a
+%%CreationDate: 2021-02-17 09:16:49
+%%BoundingBox: 0 0 497 579
+%%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col32 {0.612 0.000 0.000 srgb} bind def
+/col33 {0.549 0.549 0.549 srgb} bind def
+/col34 {0.549 0.549 0.549 srgb} bind def
+/col35 {0.259 0.259 0.259 srgb} bind def
+/col36 {0.549 0.549 0.549 srgb} bind def
+/col37 {0.259 0.259 0.259 srgb} bind def
+/col38 {0.549 0.549 0.549 srgb} bind def
+/col39 {0.259 0.259 0.259 srgb} bind def
+/col40 {0.549 0.549 0.549 srgb} bind def
+/col41 {0.259 0.259 0.259 srgb} bind def
+/col42 {0.549 0.549 0.549 srgb} bind def
+/col43 {0.259 0.259 0.259 srgb} bind def
+
+end
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/rl {rlineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/reencdict 12 dict def /ReEncode { reencdict begin
+/newcodesandnames exch def /newfontname exch def /basefontname exch def
+/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
+basefontdict { exch dup /FID ne { dup /Encoding eq
+{ exch dup length array copy newfont 3 1 roll put }
+{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
+newfont /FontName newfontname put newcodesandnames aload pop
+128 1 255 { newfont /Encoding get exch /.notdef put } for
+newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
+newfontname newfont definefont pop end } def
+/isovec [
+8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
+8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
+8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
+8#220 /dotlessi 8#230 /oe 8#231 /OE
+8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
+8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
+8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
+8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
+8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
+8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
+8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
+8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
+8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
+8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
+8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
+8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
+8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
+8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
+8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
+8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
+8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
+8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
+8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
+8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
+8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
+8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
+/Courier-Oblique /Courier-Oblique-iso isovec ReEncode
+/Times-Roman /Times-Roman-iso isovec ReEncode
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+sa
+n 0 579 m 0 0 l 497 0 l 497 579 l cp clip
+-56.9 596.0 tr
+1 -1 sc
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+% Ellipse
+7.500 slw
+n 3238 1735 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 2408 3749 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 1708 5809 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 5848 1685 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 6128 7899 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 7568 4889 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 6008 3879 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 5418 2659 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 4268 3715 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 3208 5865 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 4178 6765 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 4558 7355 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 5208 7365 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 3708 7715 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 3038 7925 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 6568 5895 142 142 0 360 DrawEllipse gs col0 s gr
+% Polyline
+0 slj
+0 slc
+n 3900 8370 m 3600 8370 3600 9150 300 arcto 4 {pop} repeat
+ 3600 9450 5670 9450 300 arcto 4 {pop} repeat
+ 5970 9450 5970 8670 300 arcto 4 {pop} repeat
+ 5970 8370 3900 8370 300 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 1215 4335 m 915 4335 915 5145 300 arcto 4 {pop} repeat
+ 915 5445 2640 5445 300 arcto 4 {pop} repeat
+ 2940 5445 2940 4635 300 arcto 4 {pop} repeat
+ 2940 4335 1215 4335 300 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 1230 6345 m 930 6345 930 7155 300 arcto 4 {pop} repeat
+ 930 7455 2655 7455 300 arcto 4 {pop} repeat
+ 2955 7455 2955 6645 300 arcto 4 {pop} repeat
+ 2955 6345 1230 6345 300 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 7050 6360 m 6750 6360 6750 7170 300 arcto 4 {pop} repeat
+ 6750 7470 8475 7470 300 arcto 4 {pop} repeat
+ 8775 7470 8775 6660 300 arcto 4 {pop} repeat
+ 8775 6360 7050 6360 300 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 4125 4335 m 3825 4335 3825 5145 300 arcto 4 {pop} repeat
+ 3825 5445 5550 5445 300 arcto 4 {pop} repeat
+ 5850 5445 5850 4635 300 arcto 4 {pop} repeat
+ 5850 4335 4125 4335 300 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 7050 2310 m 6750 2310 6750 3120 300 arcto 4 {pop} repeat
+ 6750 3420 8475 3420 300 arcto 4 {pop} repeat
+ 8775 3420 8775 2610 300 arcto 4 {pop} repeat
+ 8775 2310 7050 2310 300 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 2775 2295 m 2475 2295 2475 3105 300 arcto 4 {pop} repeat
+ 2475 3405 4200 3405 300 arcto 4 {pop} repeat
+ 4500 3405 4500 2595 300 arcto 4 {pop} repeat
+ 4500 2295 2775 2295 300 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 2775 285 m 2475 285 2475 1095 300 arcto 4 {pop} repeat
+ 2475 1395 4200 1395 300 arcto 4 {pop} repeat
+ 4500 1395 4500 585 300 arcto 4 {pop} repeat
+ 4500 285 2775 285 300 arcto 4 {pop} repeat
+ cp gs col0 s gr % Ellipse
+n 4192 6338 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 3202 4507 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 3181 5161 142 142 0 360 DrawEllipse gs col0 s gr
+% Ellipse
+n 7709 7996 142 142 0 360 DrawEllipse gs col0 s gr
+% Arc
+15.000 slw
+1 slc
+gs clippath
+2916 6717 m 2913 6696 l 3183 6599 l 3204 6717 l cp
+eoclip
+n 4837.5 16740.0 10215.6 -79.2098 -100.7902 arcn
+gs col0 s gr
+ gr
+% arrowhead
+0 slc
+n 3183 6599 m 2957 6699 l 3204 6717 l 3183 6599 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+1 slc
+gs clippath
+2914 7255 m 2915 7234 l 3199 7193 l 3195 7313 l cp
+eoclip
+n 3026.1 8399.8 1159.2 -1.4743 -95.0051 arcn
+gs col0 s gr
+ gr
+% arrowhead
+0 slc
+n 3199 7193 m 2957 7246 l 3195 7313 l 3199 7193 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+1 slc
+gs clippath
+6762 6561 m 6759 6582 l 6472 6596 l 6487 6477 l cp
+eoclip
+n 7663.1 -2028.8 8647.1 123.5832 96.0617 arcn
+gs col0 s gr
+ gr
+% arrowhead
+0 slc
+n 6472 6596 m 6718 6566 l 6487 6477 l 6472 6596 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+1 slc
+gs clippath
+8278 7455 m 8295 7468 l 8163 7723 l 8067 7650 l cp
+eoclip
+n 7717.5 7211.2 619.2 155.2976 24.7024 arcn
+gs col0 s gr
+ gr
+% arrowhead
+0 slc
+n 8163 7723 m 8260 7496 l 8067 7650 l 8163 7723 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+3431 2306 m 3410 2306 l 3360 2023 l 3480 2023 l cp
+eoclip
+n 3420 1395 m
+ 3420 2295 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 3360 2023 m 3420 2263 l 3480 2023 l 3360 2023 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+4830 4317 m 4818 4335 l 4555 4219 l 4622 4119 l cp
+eoclip
+n 3465 3420 m
+ 4815 4320 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 4555 4219 m 4788 4302 l 4622 4119 l 4555 4219 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+1901 6356 m 1880 6356 l 1830 6073 l 1950 6073 l cp
+eoclip
+n 1890 5445 m
+ 1890 6345 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 1830 6073 m 1890 6313 l 1950 6073 l 1830 6073 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+3750 8416 m 3734 8430 l 3511 8249 l 3602 8170 l cp
+eoclip
+n 2835 7380 m
+ 3735 8415 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 3511 8249 m 3714 8391 l 3602 8170 l 3511 8249 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+4715 5480 m 4736 5480 l 4785 5762 l 4665 5762 l cp
+eoclip
+n 4725 8370 m
+ 4725 5490 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 4785 5762 m 4725 5522 l 4665 5762 l 4785 5762 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+7330 3406 m 7349 3415 l 7271 3691 l 7163 3639 l cp
+eoclip
+n 4950 8370 m
+ 7335 3420 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 7271 3691 m 7321 3449 l 7163 3639 l 7271 3691 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+6761 6920 m 6761 6941 l 6478 6990 l 6478 6870 l cp
+eoclip
+n 2925 6930 m
+ 6750 6930 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 6478 6990 m 6718 6930 l 6478 6870 l 6478 6990 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+3914 5340 m 3930 5354 l 3775 5596 l 3686 5515 l cp
+eoclip
+n 2880 6480 m
+ 3915 5355 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 3775 5596 m 3893 5379 l 3686 5515 l 3775 5596 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+6761 2825 m 6761 2846 l 6478 2895 l 6478 2775 l cp
+eoclip
+n 4500 2835 m
+ 6750 2835 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 6478 2895 m 6718 2835 l 6478 2775 l 6478 2895 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+7730 3410 m 7751 3410 l 7800 3692 l 7680 3692 l cp
+eoclip
+n 7740 6345 m
+ 7740 3420 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 7800 3692 m 7740 3452 l 7680 3692 l 7800 3692 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+1886 4334 m 1876 4316 l 2092 4128 l 2154 4230 l cp
+eoclip
+n 3375 3420 m
+ 1890 4320 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 2092 4128 m 1918 4303 l 2154 4230 l 2092 4128 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+6840 3315 m 6855 3330 l 6690 3565 l 6605 3480 l cp
+eoclip
+n 5760 4410 m
+ 6840 3330 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 6690 3565 m 6817 3353 l 6605 3480 l 6690 3565 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+4486 860 m 4495 841 l 4773 911 l 4725 1020 l cp
+eoclip
+n 7740 2295 m
+ 4500 855 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 4773 911 m 4530 868 l 4725 1020 l 4773 911 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+5745 5355 m 5760 5340 l 5995 5505 l 5910 5590 l cp
+eoclip
+n 6840 6435 m
+ 5760 5355 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 5995 5505 m 5783 5378 l 5910 5590 l 5995 5505 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+6839 7365 m 6855 7379 l 6706 7624 l 6615 7545 l cp
+eoclip
+n 5895 8460 m
+ 6840 7380 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 6706 7624 m 6819 7404 l 6615 7545 l 6706 7624 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+3836 4670 m 3836 4691 l 3553 4740 l 3553 4620 l cp
+eoclip
+n 2925 4680 m
+ 3825 4680 l gs col0 s gr gr
+% arrowhead
+0 slc
+n 3553 4740 m 3793 4680 l 3553 4620 l 3553 4740 l cp gs 0.00 setgray ef gr col0 s
+/Courier-Oblique-iso ff 180.00 scf sf
+3157 1805 m
+gs 1 -1 sc (1) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+2327 3819 m
+gs 1 -1 sc (2) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+1627 5879 m
+gs 1 -1 sc (3) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+5767 1755 m
+gs 1 -1 sc (6) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+6047 7969 m
+gs 1 -1 sc (7) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+7487 4959 m
+gs 1 -1 sc (8) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+5882 3940 m
+gs 1 -1 sc (10) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+5292 2720 m
+gs 1 -1 sc (11) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+4142 3776 m
+gs 1 -1 sc (12) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+3082 5926 m
+gs 1 -1 sc (13) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+4052 6826 m
+gs 1 -1 sc (14) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+4432 7416 m
+gs 1 -1 sc (15) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+5127 7435 m
+gs 1 -1 sc (5) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+3582 7776 m
+gs 1 -1 sc (16) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+2957 7995 m
+gs 1 -1 sc (4) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+6487 5965 m
+gs 1 -1 sc (9) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+3870 9000 m
+gs 1 -1 sc (Operational) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+1620 4995 m
+gs 1 -1 sc (Init) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+1215 7020 m
+gs 1 -1 sc (Self-Test) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+7335 7020 m
+gs 1 -1 sc (Error) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+3915 4995 m
+gs 1 -1 sc (Fatal-Error) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+6930 2970 m
+gs 1 -1 sc (Shutdown) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+2655 2970 m
+gs 1 -1 sc (Power-On) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+2565 945 m
+gs 1 -1 sc (Power-Off) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+4066 6399 m
+gs 1 -1 sc (17) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+3076 4568 m
+gs 1 -1 sc (19) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+3055 5222 m
+gs 1 -1 sc (18) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+7612 8047 m
+gs 1 -1 sc (20) col0 sh gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+%EOF
diff --git a/comm/third_party/libgcrypt/doc/fips-fsm.fig b/comm/third_party/libgcrypt/doc/fips-fsm.fig
new file mode 100644
index 0000000000..a4f0aeceef
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/fips-fsm.fig
@@ -0,0 +1,199 @@
+#FIG 3.2
+Portrait
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+0 32 #9c0000
+0 33 #8c8c8c
+0 34 #8c8c8c
+0 35 #424242
+0 36 #8c8c8c
+0 37 #424242
+0 38 #8c8c8c
+0 39 #424242
+0 40 #8c8c8c
+0 41 #424242
+0 42 #8c8c8c
+0 43 #424242
+6 900 270 8775 9450
+5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 4837.500 16740.000 6750 6705 4725 6525 2925 6705
+ 1 1 2.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 3026.138 8399.825 4185 8370 3870 7605 2925 7245
+ 1 1 2.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 7663.125 -2028.750 2880 5175 4770 6120 6750 6570
+ 1 1 2.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 7717.500 7211.250 7155 7470 7740 7830 8280 7470
+ 1 1 2.00 120.00 240.00
+6 3096 1593 3380 1877
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3238 1735 142 142 3238 1735 3103 1690
+4 0 0 50 -1 13 12 0.0000 4 105 105 3157 1805 1\001
+-6
+6 2266 3607 2550 3891
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2408 3749 142 142 2408 3749 2273 3704
+4 0 0 50 -1 13 12 0.0000 4 105 105 2327 3819 2\001
+-6
+6 1566 5667 1850 5951
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 1708 5809 142 142 1708 5809 1573 5764
+4 0 0 50 -1 13 12 0.0000 4 105 105 1627 5879 3\001
+-6
+6 5706 1543 5990 1827
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5848 1685 142 142 5848 1685 5713 1640
+4 0 0 50 -1 13 12 0.0000 4 105 105 5767 1755 6\001
+-6
+6 5986 7757 6270 8041
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6128 7899 142 142 6128 7899 5993 7854
+4 0 0 50 -1 13 12 0.0000 4 105 105 6047 7969 7\001
+-6
+6 7426 4747 7710 5031
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 7568 4889 142 142 7568 4889 7433 4844
+4 0 0 50 -1 13 12 0.0000 4 105 105 7487 4959 8\001
+-6
+6 5866 3737 6150 4021
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6008 3879 142 142 6008 3879 5873 3834
+4 0 0 50 -1 13 12 0.0000 4 105 210 5882 3940 10\001
+-6
+6 5276 2517 5560 2801
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5418 2659 142 142 5418 2659 5283 2614
+4 0 0 50 -1 13 12 0.0000 4 105 210 5292 2720 11\001
+-6
+6 4126 3573 4410 3857
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4268 3715 142 142 4268 3715 4133 3670
+4 0 0 50 -1 13 12 0.0000 4 105 210 4142 3776 12\001
+-6
+6 3066 5723 3350 6007
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3208 5865 142 142 3208 5865 3073 5820
+4 0 0 50 -1 13 12 0.0000 4 105 210 3082 5926 13\001
+-6
+6 4036 6623 4320 6907
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4178 6765 142 142 4178 6765 4043 6720
+4 0 0 50 -1 13 12 0.0000 4 105 210 4052 6826 14\001
+-6
+6 4416 7213 4700 7497
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4558 7355 142 142 4558 7355 4423 7310
+4 0 0 50 -1 13 12 0.0000 4 105 210 4432 7416 15\001
+-6
+6 5066 7223 5350 7507
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5208 7365 142 142 5208 7365 5073 7320
+4 0 0 50 -1 13 12 0.0000 4 105 105 5127 7435 5\001
+-6
+6 3566 7573 3850 7857
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3708 7715 142 142 3708 7715 3573 7670
+4 0 0 50 -1 13 12 0.0000 4 105 210 3582 7776 16\001
+-6
+6 2896 7783 3180 8067
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3038 7925 142 142 3038 7925 2903 7880
+4 0 0 50 -1 13 12 0.0000 4 105 105 2957 7995 4\001
+-6
+6 6426 5753 6710 6037
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6568 5895 142 142 6568 5895 6433 5850
+4 0 0 50 -1 13 12 0.0000 4 105 105 6487 5965 9\001
+-6
+6 3600 8370 5985 9450
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 5970 9450 3600 9450 3600 8370 5970 8370 5970 9450
+4 0 0 50 -1 0 24 0.0000 4 330 1725 3870 9000 Operational\001
+-6
+6 900 4320 2970 5445
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 2940 5445 915 5445 915 4335 2940 4335 2940 5445
+4 0 0 50 -1 0 24 0.0000 4 240 510 1620 4995 Init\001
+-6
+6 900 6345 2970 7470
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 2955 7455 930 7455 930 6345 2955 6345 2955 7455
+4 0 0 50 -1 0 24 0.0000 4 255 1335 1215 7020 Self-Test\001
+-6
+6 6750 6345 8775 7470
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 8775 7470 6750 7470 6750 6360 8775 6360 8775 7470
+4 0 0 50 -1 0 24 0.0000 4 240 765 7335 7020 Error\001
+-6
+6 3825 4320 5850 5445
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 5850 5445 3825 5445 3825 4335 5850 4335 5850 5445
+4 0 0 50 -1 0 24 0.0000 4 255 1620 3915 4995 Fatal-Error\001
+-6
+6 6750 2295 8775 3420
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 8775 3420 6750 3420 6750 2310 8775 2310 8775 3420
+4 0 0 50 -1 0 24 0.0000 4 240 1455 6930 2970 Shutdown\001
+-6
+6 2475 2295 4500 3420
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 4500 3405 2475 3405 2475 2295 4500 2295 4500 3405
+4 0 0 50 -1 0 24 0.0000 4 240 1470 2655 2970 Power-On\001
+-6
+6 2475 270 4500 1395
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 4500 1395 2475 1395 2475 285 4500 285 4500 1395
+4 0 0 50 -1 0 24 0.0000 4 240 1530 2565 945 Power-Off\001
+-6
+6 4050 6196 4334 6480
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4192 6338 142 142 4192 6338 4057 6293
+4 0 0 50 -1 13 12 0.0000 4 105 210 4066 6399 17\001
+-6
+6 3053 4358 3351 4656
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3202 4507 142 142 3202 4507 3067 4462
+4 0 0 50 -1 13 12 0.0000 4 105 210 3076 4568 19\001
+-6
+6 3032 5012 3330 5310
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3181 5161 142 142 3181 5161 3046 5116
+4 0 0 50 -1 13 12 0.0000 4 105 210 3055 5222 18\001
+-6
+6 7560 7847 7858 8145
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 7709 7996 142 142 7709 7996 7574 7951
+4 0 0 50 -1 13 12 0.0000 4 105 210 7612 8047 20\001
+-6
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 3420 1395 3420 2295
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 3465 3420 4815 4320
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 1890 5445 1890 6345
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 2835 7380 3735 8415
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 4725 8370 4725 5490
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 4950 8370 7335 3420
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 2925 6930 6750 6930
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 2880 6480 3915 5355
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 4500 2835 6750 2835
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 7740 6345 7740 3420
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 3375 3420 1890 4320
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 5760 4410 6840 3330
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 7740 2295 4500 855
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 6840 6435 5760 5355
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 5895 8460 6840 7380
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 2925 4680 3825 4680
+-6
diff --git a/comm/third_party/libgcrypt/doc/fips-fsm.pdf b/comm/third_party/libgcrypt/doc/fips-fsm.pdf
new file mode 100644
index 0000000000..05e5e93f9a
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/fips-fsm.pdf
Binary files differ
diff --git a/comm/third_party/libgcrypt/doc/fips-fsm.png b/comm/third_party/libgcrypt/doc/fips-fsm.png
new file mode 100644
index 0000000000..e56aa750c1
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/fips-fsm.png
Binary files differ
diff --git a/comm/third_party/libgcrypt/doc/gcrypt.info b/comm/third_party/libgcrypt/doc/gcrypt.info
new file mode 100644
index 0000000000..8895c16684
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/gcrypt.info
@@ -0,0 +1,135 @@
+This is gcrypt.info, produced by makeinfo version 6.5 from gcrypt.texi.
+
+This manual is for Libgcrypt version 1.9.2 and was last updated 28
+January 2021. Libgcrypt is GNU's library of cryptographic building
+blocks.
+
+Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011, 2012
+Free Software Foundation, Inc.
+Copyright (C) 2012, 2013, 2016, 2017 g10 Code GmbH
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. The text of the
+ license can be found in the section entitled "GNU General Public
+ License".
+INFO-DIR-SECTION GNU Libraries
+START-INFO-DIR-ENTRY
+* libgcrypt: (gcrypt). Cryptographic function library.
+END-INFO-DIR-ENTRY
+
+
+Indirect:
+gcrypt.info-1: 861
+gcrypt.info-2: 310476
+
+Tag Table:
+(Indirect)
+Node: Top861
+Node: Introduction3413
+Node: Getting Started3785
+Node: Features4665
+Node: Overview5449
+Node: Preparation6072
+Node: Header6995
+Node: Building sources8066
+Node: Building sources using Automake9983
+Node: Initializing the library11911
+Ref: sample-use-suspend-secmem15303
+Ref: sample-use-resume-secmem16146
+Node: Multi-Threading17049
+Ref: Multi-Threading-Footnote-118228
+Node: Enabling FIPS mode18637
+Ref: enabling fips mode18818
+Node: Hardware features20630
+Ref: hardware features20797
+Ref: Hardware features-Footnote-121974
+Node: Generalities22135
+Node: Controlling the library22394
+Node: Error Handling41291
+Node: Error Values43830
+Node: Error Sources48770
+Node: Error Codes51038
+Node: Error Strings54514
+Node: Handler Functions55698
+Node: Progress handler56257
+Node: Allocation handler58406
+Node: Error handler59952
+Node: Logging handler61518
+Node: Symmetric cryptography62110
+Node: Available ciphers62850
+Node: Available cipher modes65997
+Node: Working with cipher handles70062
+Node: General cipher functions81591
+Node: Public Key cryptography85117
+Node: Available algorithms85956
+Node: Used S-expressions86256
+Node: RSA key parameters87381
+Node: DSA key parameters88656
+Node: ECC key parameters89310
+Ref: ecc_keyparam89461
+Node: Cryptographic Functions92467
+Node: Dedicated ECC Functions104442
+Node: General public-key related Functions105586
+Node: Hashing119256
+Node: Available hash algorithms119989
+Node: Working with hash algorithms126342
+Node: Message Authentication Codes140474
+Node: Available MAC algorithms141142
+Node: Working with MAC algorithms147903
+Node: Key Derivation153891
+Node: Random Numbers156293
+Node: Quality of random numbers156576
+Node: Retrieving random numbers157259
+Node: S-expressions158748
+Node: Data types for S-expressions159393
+Node: Working with S-expressions159719
+Node: MPI library174818
+Node: Data types175840
+Node: Basic functions176149
+Node: MPI formats179166
+Node: Calculations182690
+Node: Comparisons185078
+Node: Bit manipulations186081
+Node: EC functions187403
+Ref: gcry_mpi_ec_new190352
+Node: Miscellaneous195911
+Node: Prime numbers200055
+Node: Generation200325
+Node: Checking201612
+Node: Utilities202022
+Node: Memory allocation202399
+Node: Context management203755
+Ref: gcry_ctx_release204193
+Node: Buffer description204354
+Node: Config reporting205141
+Node: Tools206091
+Node: hmac256206258
+Node: Configuration207264
+Node: Architecture210317
+Ref: fig:subsystems211841
+Ref: Architecture-Footnote-1212927
+Ref: Architecture-Footnote-2212989
+Node: Public-Key Subsystem Architecture213073
+Node: Symmetric Encryption Subsystem Architecture215351
+Node: Hashing and MACing Subsystem Architecture216948
+Node: Multi-Precision-Integer Subsystem Architecture219022
+Node: Prime-Number-Generator Subsystem Architecture220460
+Ref: Prime-Number-Generator Subsystem Architecture-Footnote-1222391
+Node: Random-Number Subsystem Architecture222682
+Node: CSPRNG Description225631
+Ref: CSPRNG Description-Footnote-1227187
+Node: FIPS PRNG Description227310
+Node: Self-Tests229444
+Node: FIPS Mode240903
+Ref: fig:fips-fsm244729
+Ref: tbl:fips-states244832
+Ref: tbl:fips-state-transitions246084
+Node: Library Copying249705
+Node: Copying277811
+Node: Figures and Tables296987
+Node: Concept Index297412
+Node: Function and Data Index310476
+
+End Tag Table
diff --git a/comm/third_party/libgcrypt/doc/gcrypt.info-1 b/comm/third_party/libgcrypt/doc/gcrypt.info-1
new file mode 100644
index 0000000000..3bd16f486e
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/gcrypt.info-1
@@ -0,0 +1,7269 @@
+This is gcrypt.info, produced by makeinfo version 6.5 from gcrypt.texi.
+
+This manual is for Libgcrypt version 1.9.2 and was last updated 28
+January 2021. Libgcrypt is GNU's library of cryptographic building
+blocks.
+
+Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011, 2012
+Free Software Foundation, Inc.
+Copyright (C) 2012, 2013, 2016, 2017 g10 Code GmbH
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. The text of the
+ license can be found in the section entitled "GNU General Public
+ License".
+INFO-DIR-SECTION GNU Libraries
+START-INFO-DIR-ENTRY
+* libgcrypt: (gcrypt). Cryptographic function library.
+END-INFO-DIR-ENTRY
+
+
+File: gcrypt.info, Node: Top, Next: Introduction, Up: (dir)
+
+The Libgcrypt Library
+*********************
+
+This manual is for Libgcrypt version 1.9.2 and was last updated 28
+January 2021. Libgcrypt is GNU's library of cryptographic building
+blocks.
+
+Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011, 2012
+Free Software Foundation, Inc.
+Copyright (C) 2012, 2013, 2016, 2017 g10 Code GmbH
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. The text of the
+ license can be found in the section entitled "GNU General Public
+ License".
+
+* Menu:
+
+* Introduction:: What is Libgcrypt.
+* Preparation:: What you should do before using the library.
+* Generalities:: General library functions and data types.
+* Handler Functions:: Working with handler functions.
+* Symmetric cryptography:: How to use symmetric cryptography.
+* Public Key cryptography:: How to use public key cryptography.
+* Hashing:: How to use hash algorithms.
+* Message Authentication Codes:: How to use MAC algorithms.
+* Key Derivation:: How to derive keys from strings
+* Random Numbers:: How to work with random numbers.
+* S-expressions:: How to manage S-expressions.
+* MPI library:: How to work with multi-precision-integers.
+* Prime numbers:: How to use the Prime number related functions.
+* Utilities:: Utility functions.
+* Tools:: Utility tools.
+* Configuration:: Configuration files and environment variables.
+* Architecture:: How Libgcrypt works internally.
+
+Appendices
+
+* Self-Tests:: Description of the self-tests.
+* FIPS Mode:: Description of the FIPS mode.
+* Library Copying:: The GNU Lesser General Public License
+ says how you can copy and share Libgcrypt.
+* Copying:: The GNU General Public License says how you
+ can copy and share some parts of Libgcrypt.
+
+Indices
+
+* Figures and Tables:: Index of figures and tables.
+* Concept Index:: Index of concepts and programs.
+* Function and Data Index:: Index of functions, variables and data types.
+
+
+File: gcrypt.info, Node: Introduction, Next: Preparation, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+Libgcrypt is a library providing cryptographic building blocks.
+
+* Menu:
+
+* Getting Started:: How to use this manual.
+* Features:: A glance at Libgcrypt's features.
+* Overview:: Overview about the library.
+
+
+File: gcrypt.info, Node: Getting Started, Next: Features, Up: Introduction
+
+1.1 Getting Started
+===================
+
+This manual documents the Libgcrypt library application programming
+interface (API). All functions and data types provided by the library
+are explained.
+
+The reader is assumed to possess basic knowledge about applied
+cryptography.
+
+ This manual can be used in several ways. If read from the beginning
+to the end, it gives a good introduction into the library and how it can
+be used in an application. Forward references are included where
+necessary. Later on, the manual can be used as a reference manual to
+get just the information needed about any particular interface of the
+library. Experienced programmers might want to start looking at the
+examples at the end of the manual, and then only read up those parts of
+the interface which are unclear.
+
+
+File: gcrypt.info, Node: Features, Next: Overview, Prev: Getting Started, Up: Introduction
+
+1.2 Features
+============
+
+Libgcrypt might have a couple of advantages over other libraries doing a
+similar job.
+
+It's Free Software
+ Anybody can use, modify, and redistribute it under the terms of the
+ GNU Lesser General Public License (*note Library Copying::). Note,
+ that some parts (which are in general not needed by applications)
+ are subject to the terms of the GNU General Public License (*note
+ Copying::); please see the README file of the distribution for of
+ list of these parts.
+
+It encapsulates the low level cryptography
+ Libgcrypt provides a high level interface to cryptographic building
+ blocks using an extensible and flexible API.
+
+
+File: gcrypt.info, Node: Overview, Prev: Features, Up: Introduction
+
+1.3 Overview
+============
+
+The Libgcrypt library is fully thread-safe, where it makes sense to be
+thread-safe. Not thread-safe are some cryptographic functions that
+modify a certain context stored in handles. If the user really intents
+to use such functions from different threads on the same handle, he has
+to take care of the serialization of such functions himself. If not
+described otherwise, every function is thread-safe.
+
+ Libgcrypt depends on the library 'libgpg-error', which contains some
+common code used by other GnuPG components.
+
+
+File: gcrypt.info, Node: Preparation, Next: Generalities, Prev: Introduction, Up: Top
+
+2 Preparation
+*************
+
+To use Libgcrypt, you have to perform some changes to your sources and
+the build system. The necessary changes are small and explained in the
+following sections. At the end of this chapter, it is described how the
+library is initialized, and how the requirements of the library are
+verified.
+
+* Menu:
+
+* Header:: What header file you need to include.
+* Building sources:: How to build sources using the library.
+* Building sources using Automake:: How to build sources with the help of Automake.
+* Initializing the library:: How to initialize the library.
+* Multi-Threading:: How Libgcrypt can be used in a MT environment.
+* Enabling FIPS mode:: How to enable the FIPS mode.
+* Hardware features:: How to disable hardware features.
+
+
+File: gcrypt.info, Node: Header, Next: Building sources, Up: Preparation
+
+2.1 Header
+==========
+
+All interfaces (data types and functions) of the library are defined in
+the header file 'gcrypt.h'. You must include this in all source files
+using the library, either directly or through some other header file,
+like this:
+
+ #include <gcrypt.h>
+
+ The name space of Libgcrypt is 'gcry_*' for function and type names
+and 'GCRY*' for other symbols. In addition the same name prefixes with
+one prepended underscore are reserved for internal use and should never
+be used by an application. Note that Libgcrypt uses libgpg-error, which
+uses 'gpg_*' as name space for function and type names and 'GPG_*' for
+other symbols, including all the error codes.
+
+Certain parts of gcrypt.h may be excluded by defining these macros:
+
+'GCRYPT_NO_MPI_MACROS'
+ Do not define the shorthand macros 'mpi_*' for 'gcry_mpi_*'.
+
+'GCRYPT_NO_DEPRECATED'
+ Do not include definitions for deprecated features. This is useful
+ to make sure that no deprecated features are used.
+
+
+File: gcrypt.info, Node: Building sources, Next: Building sources using Automake, Prev: Header, Up: Preparation
+
+2.2 Building sources
+====================
+
+If you want to compile a source file including the 'gcrypt.h' header
+file, you must make sure that the compiler can find it in the directory
+hierarchy. This is accomplished by adding the path to the directory in
+which the header file is located to the compilers include file search
+path (via the '-I' option).
+
+ However, the path to the include file is determined at the time the
+source is configured. To solve this problem, Libgcrypt ships with a
+small helper program 'libgcrypt-config' that knows the path to the
+include file and other configuration options. The options that need to
+be added to the compiler invocation at compile time are output by the
+'--cflags' option to 'libgcrypt-config'. The following example shows
+how it can be used at the command line:
+
+ gcc -c foo.c `libgcrypt-config --cflags`
+
+ Adding the output of 'libgcrypt-config --cflags' to the compiler’s
+command line will ensure that the compiler can find the Libgcrypt header
+file.
+
+ A similar problem occurs when linking the program with the library.
+Again, the compiler has to find the library files. For this to work,
+the path to the library files has to be added to the library search path
+(via the '-L' option). For this, the option '--libs' to
+'libgcrypt-config' can be used. For convenience, this option also
+outputs all other options that are required to link the program with the
+Libgcrypt libraries (in particular, the '-lgcrypt' option). The example
+shows how to link 'foo.o' with the Libgcrypt library to a program 'foo'.
+
+ gcc -o foo foo.o `libgcrypt-config --libs`
+
+ Of course you can also combine both examples to a single command by
+specifying both options to 'libgcrypt-config':
+
+ gcc -o foo foo.c `libgcrypt-config --cflags --libs`
+
+
+File: gcrypt.info, Node: Building sources using Automake, Next: Initializing the library, Prev: Building sources, Up: Preparation
+
+2.3 Building sources using Automake
+===================================
+
+It is much easier if you use GNU Automake instead of writing your own
+Makefiles. If you do that, you do not have to worry about finding and
+invoking the 'libgcrypt-config' script at all. Libgcrypt provides an
+extension to Automake that does all the work for you.
+
+ -- Macro: AM_PATH_LIBGCRYPT ([MINIMUM-VERSION], [ACTION-IF-FOUND],
+ [ACTION-IF-NOT-FOUND])
+ Check whether Libgcrypt (at least version MINIMUM-VERSION, if
+ given) exists on the host system. If it is found, execute
+ ACTION-IF-FOUND, otherwise do ACTION-IF-NOT-FOUND, if given.
+
+ Additionally, the function defines 'LIBGCRYPT_CFLAGS' to the flags
+ needed for compilation of the program to find the 'gcrypt.h' header
+ file, and 'LIBGCRYPT_LIBS' to the linker flags needed to link the
+ program to the Libgcrypt library. If the used helper script does
+ not match the target type you are building for a warning is printed
+ and the string 'libgcrypt' is appended to the variable
+ 'gpg_config_script_warn'.
+
+ This macro searches for 'libgcrypt-config' along the PATH. If you
+ are cross-compiling, it is useful to set the environment variable
+ 'SYSROOT' to the top directory of your target. The macro will then
+ first look for the helper program in the 'bin' directory below that
+ top directory. An absolute directory name must be used for
+ 'SYSROOT'. Finally, if the configure command line option
+ '--with-libgcrypt-prefix' is used, only its value is used for the
+ top directory below which the helper script is expected.
+
+ You can use the defined Autoconf variables like this in your
+'Makefile.am':
+
+ AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS)
+ LDADD = $(LIBGCRYPT_LIBS)
+
+
+File: gcrypt.info, Node: Initializing the library, Next: Multi-Threading, Prev: Building sources using Automake, Up: Preparation
+
+2.4 Initializing the library
+============================
+
+Before the library can be used, it must initialize itself. This is
+achieved by invoking the function 'gcry_check_version' described below.
+
+ Also, it is often desirable to check that the version of Libgcrypt
+used is indeed one which fits all requirements. Even with binary
+compatibility, new features may have been introduced, but due to problem
+with the dynamic linker an old version may actually be used. So you may
+want to check that the version is okay right after program startup.
+
+ -- Function: const char * gcry_check_version (const char *REQ_VERSION)
+
+ The function 'gcry_check_version' initializes some subsystems used
+ by Libgcrypt and must be invoked before any other function in the
+ library. *Note Multi-Threading::.
+
+ Furthermore, this function returns the version number of the
+ library. It can also verify that the version number is higher than
+ a certain required version number REQ_VERSION, if this value is not
+ a null pointer.
+
+ Libgcrypt uses a concept known as secure memory, which is a region of
+memory set aside for storing sensitive data. Because such memory is a
+scarce resource, it needs to be setup in advanced to a fixed size.
+Further, most operating systems have special requirements on how that
+secure memory can be used. For example, it might be required to install
+an application as "setuid(root)" to allow allocating such memory.
+Libgcrypt requires a sequence of initialization steps to make sure that
+this works correctly. The following examples show the necessary steps.
+
+ If you don't have a need for secure memory, for example if your
+application does not use secret keys or other confidential data or it
+runs in a controlled environment where key material floating around in
+memory is not a problem, you should initialize Libgcrypt this way:
+
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are initialized.
+ #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
+ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
+ {
+ fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
+ NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
+ exit (2);
+ }
+
+ /* Disable secure memory. */
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ If you have to protect your keys or other information in memory
+against being swapped out to disk and to enable an automatic overwrite
+of used and freed memory, you need to initialize Libgcrypt this way:
+
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are initialized.
+ #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
+ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
+ {
+ fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
+ NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
+ exit (2);
+ }
+
+ /* We don't want to see any warnings, e.g. because we have not yet
+ parsed program options which might be used to suppress such
+ warnings. */
+ gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. Note that the
+ process might still be running with increased privileges and that
+ the secure memory has not been initialized. */
+
+ /* Allocate a pool of 16k secure memory. This makes the secure memory
+ available and also drops privileges where needed. Note that by
+ using functions like gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt
+ may expand the secure memory pool with memory which lacks the
+ property of not being swapped out to disk. */
+ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+ /* It is now okay to let Libgcrypt complain when there was/is
+ a problem with the secure memory. */
+ gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ It is important that these initialization steps are not done by a
+library but by the actual application. A library using Libgcrypt might
+want to check for finished initialization using:
+
+ if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P))
+ {
+ fputs ("libgcrypt has not been initialized\n", stderr);
+ abort ();
+ }
+
+ Instead of terminating the process, the library may instead print a
+warning and try to initialize Libgcrypt itself. See also the section on
+multi-threading below for more pitfalls.
+
+
+File: gcrypt.info, Node: Multi-Threading, Next: Enabling FIPS mode, Prev: Initializing the library, Up: Preparation
+
+2.5 Multi-Threading
+===================
+
+As mentioned earlier, the Libgcrypt library is thread-safe if you adhere
+to the following requirements:
+
+ * If you use pthread and your applications forks and does not
+ directly call exec (even calling stdio functions), all kind of
+ problems may occur. Future versions of Libgcrypt will try to
+ cleanup using pthread_atfork but even that may lead to problems.
+ This is a common problem with almost all applications using pthread
+ and fork.
+
+ * The function 'gcry_check_version' must be called before any other
+ function in the library. To achieve this in multi-threaded
+ programs, you must synchronize the memory with respect to other
+ threads that also want to use Libgcrypt. For this, it is
+ sufficient to call 'gcry_check_version' before creating the other
+ threads using Libgcrypt(1).
+
+ * Just like the function 'gpg_strerror', the function 'gcry_strerror'
+ is not thread safe. You have to use 'gpg_strerror_r' instead.
+
+ ---------- Footnotes ----------
+
+ (1) At least this is true for POSIX threads, as 'pthread_create' is a
+function that synchronizes memory with respects to other threads. There
+are many functions which have this property, a complete list can be
+found in POSIX, IEEE Std 1003.1-2003, Base Definitions, Issue 6, in the
+definition of the term "Memory Synchronization". For other thread
+packages, more relaxed or more strict rules may apply.
+
+
+File: gcrypt.info, Node: Enabling FIPS mode, Next: Hardware features, Prev: Multi-Threading, Up: Preparation
+
+2.6 How to enable the FIPS mode
+===============================
+
+Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not
+necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check
+the NIST database at <http://csrc.nist.gov/groups/STM/cmvp/> to see what
+versions of Libgcrypt are approved.
+
+ Because FIPS 140 has certain restrictions on the use of cryptography
+which are not always wanted, Libgcrypt needs to be put into FIPS mode
+explicitly. Three alternative mechanisms are provided to switch
+Libgcrypt into this mode:
+
+ * If the file '/proc/sys/crypto/fips_enabled' exists and contains a
+ numeric value other than '0', Libgcrypt is put into FIPS mode at
+ initialization time. Obviously this works only on systems with a
+ 'proc' file system (i.e. GNU/Linux).
+
+ * If the file '/etc/gcrypt/fips_enabled' exists, Libgcrypt is put
+ into FIPS mode at initialization time. Note that this filename is
+ hardwired and does not depend on any configuration options.
+
+ * If the application requests FIPS mode using the control command
+ 'GCRYCTL_FORCE_FIPS_MODE'. This must be done prior to any
+ initialization (i.e. before 'gcry_check_version').
+
+ In addition to the standard FIPS mode, Libgcrypt may also be put into
+an Enforced FIPS mode by writing a non-zero value into the file
+'/etc/gcrypt/fips_enabled' or by using the control command
+'GCRYCTL_SET_ENFORCED_FIPS_FLAG' before any other calls to libgcrypt.
+The Enforced FIPS mode helps to detect applications which don't fulfill
+all requirements for using Libgcrypt in FIPS mode (*note FIPS Mode::).
+
+ Once Libgcrypt has been put into FIPS mode, it is not possible to
+switch back to standard mode without terminating the process first. If
+the logging verbosity level of Libgcrypt has been set to at least 2, the
+state transitions and the self-tests are logged.
+
+
+File: gcrypt.info, Node: Hardware features, Prev: Enabling FIPS mode, Up: Preparation
+
+2.7 How to disable hardware features
+====================================
+
+Libgcrypt makes use of certain hardware features. If the use of a
+feature is not desired it may be either be disabled by a program or
+globally using a configuration file. The currently supported features
+are
+
+'padlock-rng'
+'padlock-aes'
+'padlock-sha'
+'padlock-mmul'
+'intel-cpu'
+'intel-fast-shld'
+'intel-bmi2'
+'intel-ssse3'
+'intel-sse4.1'
+'intel-pclmul'
+'intel-aesni'
+'intel-rdrand'
+'intel-avx'
+'intel-avx2'
+'intel-fast-vpgather'
+'intel-rdtsc'
+'intel-shaext'
+'arm-neon'
+'arm-aes'
+'arm-sha1'
+'arm-sha2'
+'arm-pmull'
+
+ To disable a feature for all processes using Libgcrypt 1.6 or newer,
+create the file '/etc/gcrypt/hwf.deny' and put each feature not to be
+used on a single line. Empty lines, white space, and lines prefixed
+with a hash mark are ignored. The file should be world readable.
+
+ To disable a feature specifically for a program that program must
+tell it Libgcrypt before before calling 'gcry_check_version'.
+Example:(1)
+
+ gcry_control (GCRYCTL_DISABLE_HWF, "intel-rdrand", NULL);
+
+To print the list of active features you may use this command:
+
+ mpicalc --print-config | grep ^hwflist: | tr : '\n' | tail -n +2
+
+ ---------- Footnotes ----------
+
+ (1) NB. Libgcrypt uses the RDRAND feature only as one source of
+entropy. A CPU with a broken RDRAND will thus not compromise of the
+random number generator
+
+
+File: gcrypt.info, Node: Generalities, Next: Handler Functions, Prev: Preparation, Up: Top
+
+3 Generalities
+**************
+
+* Menu:
+
+* Controlling the library:: Controlling Libgcrypt's behavior.
+* Error Handling:: Error codes and such.
+
+
+File: gcrypt.info, Node: Controlling the library, Next: Error Handling, Up: Generalities
+
+3.1 Controlling the library
+===========================
+
+ -- Function: gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...)
+
+ This function can be used to influence the general behavior of
+ Libgcrypt in several ways. Depending on CMD, more arguments can or
+ have to be provided.
+
+ 'GCRYCTL_ENABLE_M_GUARD; Arguments: none'
+ This command enables the built-in memory guard. It must not
+ be used to activate the memory guard after the memory
+ management has already been used; therefore it can ONLY be
+ used before 'gcry_check_version'. Note that the memory guard
+ is NOT used when the user of the library has set his own
+ memory management callbacks.
+
+ 'GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none'
+ This command inhibits the use the very secure random quality
+ level ('GCRY_VERY_STRONG_RANDOM') and degrades all request
+ down to 'GCRY_STRONG_RANDOM'. In general this is not
+ recommended. However, for some applications the extra quality
+ random Libgcrypt tries to create is not justified and this
+ option may help to get better performance. Please check with
+ a crypto expert whether this option can be used for your
+ application.
+
+ This option can only be used at initialization time.
+
+ 'GCRYCTL_DUMP_RANDOM_STATS; Arguments: none'
+ This command dumps random number generator related statistics
+ to the library's logging stream.
+
+ 'GCRYCTL_DUMP_MEMORY_STATS; Arguments: none'
+ This command dumps memory management related statistics to the
+ library's logging stream.
+
+ 'GCRYCTL_DUMP_SECMEM_STATS; Arguments: none'
+ This command dumps secure memory management related statistics
+ to the library's logging stream.
+
+ 'GCRYCTL_DROP_PRIVS; Arguments: none'
+ This command disables the use of secure memory and drops the
+ privileges of the current process. This command has not much
+ use; the suggested way to disable secure memory is to use
+ 'GCRYCTL_DISABLE_SECMEM' right after initialization.
+
+ 'GCRYCTL_DISABLE_SECMEM; Arguments: none'
+ This command disables the use of secure memory. If this
+ command is used in FIPS mode, FIPS mode will be disabled and
+ the function 'gcry_fips_mode_active' returns false. However,
+ in Enforced FIPS mode this command has no effect at all.
+
+ Many applications do not require secure memory, so they should
+ disable it right away. This command should be executed right
+ after 'gcry_check_version'.
+
+ 'GCRYCTL_DISABLE_LOCKED_SECMEM; Arguments: none'
+ This command disables the use of the mlock call for secure
+ memory. Disabling the use of mlock may for example be done if
+ an encrypted swap space is in use. This command should be
+ executed right after 'gcry_check_version'. Note that by using
+ functions like gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt
+ may expand the secure memory pool with memory which lacks the
+ property of not being swapped out to disk (but will still be
+ zeroed out on free).
+
+ 'GCRYCTL_DISABLE_PRIV_DROP; Arguments: none'
+ This command sets a global flag to tell the secure memory
+ subsystem that it shall not drop privileges after secure
+ memory has been allocated. This command is commonly used
+ right after 'gcry_check_version' but may also be used right
+ away at program startup. It won't have an effect after the
+ secure memory pool has been initialized. WARNING: A process
+ running setuid(root) is a severe security risk. Processes
+ making use of Libgcrypt or other complex code should drop
+ these extra privileges as soon as possible. If this command
+ has been used the caller is responsible for dropping the
+ privileges.
+
+ 'GCRYCTL_INIT_SECMEM; Arguments: unsigned int nbytes'
+ This command is used to allocate a pool of secure memory and
+ thus enabling the use of secure memory. It also drops all
+ extra privileges the process has (i.e. if it is run as setuid
+ (root)). If the argument NBYTES is 0, secure memory will be
+ disabled. The minimum amount of secure memory allocated is
+ currently 16384 bytes; you may thus use a value of 1 to
+ request that default size.
+
+ 'GCRYCTL_AUTO_EXPAND_SECMEM; Arguments: unsigned int chunksize'
+ This command enables on-the-fly expanding of the secure memory
+ area. Note that by using functions like 'gcry_xmalloc_secure'
+ and 'gcry_mpi_snew' will do this auto expanding anyway. The
+ argument to this option is the suggested size for new secure
+ memory areas. A larger size improves performance of all
+ memory allocation and releasing functions. The given
+ chunksize is rounded up to the next 32KiB. The drawback of
+ auto expanding is that memory might be swapped out to disk;
+ this can be fixed by configuring the system to use an
+ encrypted swap space.
+
+ 'GCRYCTL_TERM_SECMEM; Arguments: none'
+ This command zeroises the secure memory and destroys the
+ handler. The secure memory pool may not be used anymore after
+ running this command. If the secure memory pool as already
+ been destroyed, this command has no effect. Applications
+ might want to run this command from their exit handler to make
+ sure that the secure memory gets properly destroyed. This
+ command is not necessarily thread-safe but that should not be
+ needed in cleanup code. It may be called from a signal
+ handler.
+
+ 'GCRYCTL_DISABLE_SECMEM_WARN; Arguments: none'
+ Disable warning messages about problems with the secure memory
+ subsystem. This command should be run right after
+ 'gcry_check_version'.
+
+ 'GCRYCTL_SUSPEND_SECMEM_WARN; Arguments: none'
+ Postpone warning messages from the secure memory subsystem.
+ *Note the initialization example: sample-use-suspend-secmem,
+ on how to use it.
+
+ 'GCRYCTL_RESUME_SECMEM_WARN; Arguments: none'
+ Resume warning messages from the secure memory subsystem.
+ *Note the initialization example: sample-use-resume-secmem, on
+ how to use it.
+
+ 'GCRYCTL_USE_SECURE_RNDPOOL; Arguments: none'
+ This command tells the PRNG to store random numbers in secure
+ memory. This command should be run right after
+ 'gcry_check_version' and not later than the command
+ GCRYCTL_INIT_SECMEM. Note that in FIPS mode the secure memory
+ is always used.
+
+ 'GCRYCTL_SET_RANDOM_SEED_FILE; Arguments: const char *filename'
+ This command specifies the file, which is to be used as seed
+ file for the PRNG. If the seed file is registered prior to
+ initialization of the PRNG, the seed file's content (if it
+ exists and seems to be valid) is fed into the PRNG pool.
+ After the seed file has been registered, the PRNG can be
+ signalled to write out the PRNG pool's content into the seed
+ file with the following command.
+
+ 'GCRYCTL_UPDATE_RANDOM_SEED_FILE; Arguments: none'
+ Write out the PRNG pool's content into the registered seed
+ file.
+
+ Multiple instances of the applications sharing the same random
+ seed file can be started in parallel, in which case they will
+ read out the same pool and then race for updating it (the last
+ update overwrites earlier updates). They will differentiate
+ only by the weak entropy that is added in read_seed_file based
+ on the PID and clock, and up to 16 bytes of weak random
+ non-blockingly. The consequence is that the output of these
+ different instances is correlated to some extent. In a
+ perfect attack scenario, the attacker can control (or at least
+ guess) the PID and clock of the application, and drain the
+ system's entropy pool to reduce the "up to 16 bytes" above to
+ 0. Then the dependencies of the initial states of the pools
+ are completely known. Note that this is not an issue if
+ random of 'GCRY_VERY_STRONG_RANDOM' quality is requested as in
+ this case enough extra entropy gets mixed. It is also not an
+ issue when using Linux (rndlinux driver), because this one
+ guarantees to read full 16 bytes from /dev/urandom and thus
+ there is no way for an attacker without kernel access to
+ control these 16 bytes.
+
+ 'GCRYCTL_CLOSE_RANDOM_DEVICE; Arguments: none'
+ Try to close the random device. If on Unix system you call
+ fork(), the child process does no call exec(), and you do not
+ intend to use Libgcrypt in the child, it might be useful to
+ use this control code to close the inherited file descriptors
+ of the random device. If Libgcrypt is later used again by the
+ child, the device will be re-opened. On non-Unix systems this
+ control code is ignored.
+
+ 'GCRYCTL_SET_VERBOSITY; Arguments: int level'
+ This command sets the verbosity of the logging. A level of 0
+ disables all extra logging whereas positive numbers enable
+ more verbose logging. The level may be changed at any time
+ but be aware that no memory synchronization is done so the
+ effect of this command might not immediately show up in other
+ threads. This command may even be used prior to
+ 'gcry_check_version'.
+
+ 'GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags'
+ Set the debug flag bits as given by the argument. Be aware
+ that no memory synchronization is done so the effect of this
+ command might not immediately show up in other threads. The
+ debug flags are not considered part of the API and thus may
+ change without notice. As of now bit 0 enables debugging of
+ cipher functions and bit 1 debugging of
+ multi-precision-integers. This command may even be used prior
+ to 'gcry_check_version'.
+
+ 'GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags'
+ Set the debug flag bits as given by the argument. Be aware
+ that that no memory synchronization is done so the effect of
+ this command might not immediately show up in other threads.
+ This command may even be used prior to 'gcry_check_version'.
+
+ 'GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none'
+ This command does nothing. It exists only for backward
+ compatibility.
+
+ 'GCRYCTL_ANY_INITIALIZATION_P; Arguments: none'
+ This command returns true if the library has been basically
+ initialized. Such a basic initialization happens implicitly
+ with many commands to get certain internal subsystems running.
+ The common and suggested way to do this basic initialization
+ is by calling gcry_check_version.
+
+ 'GCRYCTL_INITIALIZATION_FINISHED; Arguments: none'
+ This command tells the library that the application has
+ finished the initialization.
+
+ 'GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none'
+ This command returns true if the command
+ GCRYCTL_INITIALIZATION_FINISHED has already been run.
+
+ 'GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops'
+ This command is obsolete since version 1.6.
+
+ 'GCRYCTL_FAST_POLL; Arguments: none'
+ Run a fast random poll.
+
+ 'GCRYCTL_SET_RNDEGD_SOCKET; Arguments: const char *filename'
+ This command may be used to override the default name of the
+ EGD socket to connect to. It may be used only during
+ initialization as it is not thread safe. Changing the socket
+ name again is not supported. The function may return an error
+ if the given filename is too long for a local socket name.
+
+ EGD is an alternative random gatherer, used only on systems
+ lacking a proper random device.
+
+ 'GCRYCTL_PRINT_CONFIG; Arguments: FILE *stream'
+ This command dumps information pertaining to the configuration
+ of the library to the given stream. If NULL is given for
+ STREAM, the log system is used. This command may be used
+ before the initialization has been finished but not before a
+ 'gcry_check_version'. Note that the macro 'estream_t' can be
+ used instead of 'gpgrt_stream_t'.
+
+ 'GCRYCTL_OPERATIONAL_P; Arguments: none'
+ This command returns true if the library is in an operational
+ state. This information makes only sense in FIPS mode. In
+ contrast to other functions, this is a pure test function and
+ won't put the library into FIPS mode or change the internal
+ state. This command may be used before the initialization has
+ been finished but not before a 'gcry_check_version'.
+
+ 'GCRYCTL_FIPS_MODE_P; Arguments: none'
+ This command returns true if the library is in FIPS mode.
+ Note, that this is no indication about the current state of
+ the library. This command may be used before the
+ initialization has been finished but not before a
+ 'gcry_check_version'. An application may use this command or
+ the convenience macro below to check whether FIPS mode is
+ actually active.
+
+ -- Function: int gcry_fips_mode_active (void)
+
+ Returns true if the FIPS mode is active. Note that this
+ is implemented as a macro.
+
+ 'GCRYCTL_FORCE_FIPS_MODE; Arguments: none'
+ Running this command puts the library into FIPS mode. If the
+ library is already in FIPS mode, a self-test is triggered and
+ thus the library will be put into operational state. This
+ command may be used before a call to 'gcry_check_version' and
+ that is actually the recommended way to let an application
+ switch the library into FIPS mode. Note that Libgcrypt will
+ reject an attempt to switch to fips mode during or after the
+ initialization.
+
+ 'GCRYCTL_SET_ENFORCED_FIPS_FLAG; Arguments: none'
+ Running this command sets the internal flag that puts the
+ library into the enforced FIPS mode during the FIPS mode
+ initialization. This command does not affect the library if
+ the library is not put into the FIPS mode and it must be used
+ before any other libgcrypt library calls that initialize the
+ library such as 'gcry_check_version'. Note that Libgcrypt
+ will reject an attempt to switch to the enforced fips mode
+ during or after the initialization.
+
+ 'GCRYCTL_SET_PREFERRED_RNG_TYPE; Arguments: int'
+ These are advisory commands to select a certain random number
+ generator. They are only advisory because libraries may not
+ know what an application actually wants or vice versa. Thus
+ Libgcrypt employs a priority check to select the actually used
+ RNG. If an applications selects a lower priority RNG but a
+ library requests a higher priority RNG Libgcrypt will switch
+ to the higher priority RNG. Applications and libraries should
+ use these control codes before 'gcry_check_version'. The
+ available generators are:
+ 'GCRY_RNG_TYPE_STANDARD'
+ A conservative standard generator based on the
+ "Continuously Seeded Pseudo Random Number Generator"
+ designed by Peter Gutmann.
+ 'GCRY_RNG_TYPE_FIPS'
+ A deterministic random number generator conforming to he
+ document "NIST-Recommended Random Number Generator Based
+ on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES
+ and AES Algorithms" (2005-01-31). This implementation
+ uses the AES variant.
+ 'GCRY_RNG_TYPE_SYSTEM'
+ A wrapper around the system's native RNG. On Unix system
+ these are usually the /dev/random and /dev/urandom
+ devices.
+ The default is 'GCRY_RNG_TYPE_STANDARD' unless FIPS mode as
+ been enabled; in which case 'GCRY_RNG_TYPE_FIPS' is used and
+ locked against further changes.
+
+ 'GCRYCTL_GET_CURRENT_RNG_TYPE; Arguments: int *'
+ This command stores the type of the currently used RNG as an
+ integer value at the provided address.
+
+ 'GCRYCTL_SELFTEST; Arguments: none'
+ This may be used at anytime to have the library run all
+ implemented self-tests. It works in standard and in FIPS
+ mode. Returns 0 on success or an error code on failure.
+
+ 'GCRYCTL_DISABLE_HWF; Arguments: const char *name'
+
+ Libgcrypt detects certain features of the CPU at startup time.
+ For performance tests it is sometimes required not to use such
+ a feature. This option may be used to disable a certain
+ feature; i.e. Libgcrypt behaves as if this feature has not
+ been detected. This call can be used several times to disable
+ a set of features, or features may be given as a colon or
+ comma delimited string. The special feature "all" can be used
+ to disable all available features.
+
+ Note that the detection code might be run if the feature has
+ been disabled. This command must be used at initialization
+ time; i.e. before calling 'gcry_check_version'.
+
+ 'GCRYCTL_REINIT_SYSCALL_CLAMP; Arguments: none'
+
+ Libgcrypt wraps blocking system calls with two functions calls
+ ("system call clamp") to give user land threading libraries a
+ hook for re-scheduling. This works by reading the system call
+ clamp from Libgpg-error at initialization time. However
+ sometimes Libgcrypt needs to be initialized before the user
+ land threading systems and at that point the system call clamp
+ has not been registered with Libgpg-error and in turn
+ Libgcrypt would not use them. The control code can be used to
+ tell Libgcrypt that a system call clamp has now been
+ registered with Libgpg-error and advise Libgcrypt to read the
+ clamp again. Obviously this control code may only be used
+ before a second thread is started in a process.
+
+
+File: gcrypt.info, Node: Error Handling, Prev: Controlling the library, Up: Generalities
+
+3.2 Error Handling
+==================
+
+Many functions in Libgcrypt can return an error if they fail. For this
+reason, the application should always catch the error condition and take
+appropriate measures, for example by releasing the resources and passing
+the error up to the caller, or by displaying a descriptive message to
+the user and cancelling the operation.
+
+ Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly. For
+example, if you try to decrypt a tempered message, the decryption will
+fail. Another error value actually means that the end of a data buffer
+or list has been reached. The following descriptions explain for many
+error codes what they mean usually. Some error values have specific
+meanings if returned by a certain functions. Such cases are described
+in the documentation of those functions.
+
+ Libgcrypt uses the 'libgpg-error' library. This allows to share the
+error codes with other components of the GnuPG system, and to pass error
+values transparently from the crypto engine, or some helper application
+of the crypto engine, to the user. This way no information is lost. As
+a consequence, Libgcrypt does not use its own identifiers for error
+codes, but uses those provided by 'libgpg-error'. They usually start
+with 'GPG_ERR_'.
+
+ However, Libgcrypt does provide aliases for the functions defined in
+libgpg-error, which might be preferred for name space consistency.
+
+ Most functions in Libgcrypt return an error code in the case of
+failure. For this reason, the application should always catch the error
+condition and take appropriate measures, for example by releasing the
+resources and passing the error up to the caller, or by displaying a
+descriptive message to the user and canceling the operation.
+
+ Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly.
+
+ GnuPG components, including Libgcrypt, use an extra library named
+libgpg-error to provide a common error handling scheme. For more
+information on libgpg-error, see the according manual.
+
+* Menu:
+
+* Error Values:: The error value and what it means.
+* Error Sources:: A list of important error sources.
+* Error Codes:: A list of important error codes.
+* Error Strings:: How to get a descriptive string from a value.
+
+
+File: gcrypt.info, Node: Error Values, Next: Error Sources, Up: Error Handling
+
+3.2.1 Error Values
+------------------
+
+ -- Data type: gcry_err_code_t
+ The 'gcry_err_code_t' type is an alias for the 'libgpg-error' type
+ 'gpg_err_code_t'. The error code indicates the type of an error,
+ or the reason why an operation failed.
+
+ A list of important error codes can be found in the next section.
+
+ -- Data type: gcry_err_source_t
+ The 'gcry_err_source_t' type is an alias for the 'libgpg-error'
+ type 'gpg_err_source_t'. The error source has not a precisely
+ defined meaning. Sometimes it is the place where the error
+ happened, sometimes it is the place where an error was encoded into
+ an error value. Usually the error source will give an indication
+ to where to look for the problem. This is not always true, but it
+ is attempted to achieve this goal.
+
+ A list of important error sources can be found in the next section.
+
+ -- Data type: gcry_error_t
+ The 'gcry_error_t' type is an alias for the 'libgpg-error' type
+ 'gpg_error_t'. An error value like this has always two components,
+ an error code and an error source. Both together form the error
+ value.
+
+ Thus, the error value can not be directly compared against an error
+ code, but the accessor functions described below must be used.
+ However, it is guaranteed that only 0 is used to indicate success
+ ('GPG_ERR_NO_ERROR'), and that in this case all other parts of the
+ error value are set to 0, too.
+
+ Note that in Libgcrypt, the error source is used purely for
+ diagnostic purposes. Only the error code should be checked to test
+ for a certain outcome of a function. The manual only documents the
+ error code part of an error value. The error source is left
+ unspecified and might be anything.
+
+ -- Function: gcry_err_code_t gcry_err_code (gcry_error_t ERR)
+ The static inline function 'gcry_err_code' returns the
+ 'gcry_err_code_t' component of the error value ERR. This function
+ must be used to extract the error code from an error value in order
+ to compare it with the 'GPG_ERR_*' error code macros.
+
+ -- Function: gcry_err_source_t gcry_err_source (gcry_error_t ERR)
+ The static inline function 'gcry_err_source' returns the
+ 'gcry_err_source_t' component of the error value ERR. This
+ function must be used to extract the error source from an error
+ value in order to compare it with the 'GPG_ERR_SOURCE_*' error
+ source macros.
+
+ -- Function: gcry_error_t gcry_err_make (gcry_err_source_t SOURCE,
+ gcry_err_code_t CODE)
+ The static inline function 'gcry_err_make' returns the error value
+ consisting of the error source SOURCE and the error code CODE.
+
+ This function can be used in callback functions to construct an
+ error value to return it to the library.
+
+ -- Function: gcry_error_t gcry_error (gcry_err_code_t CODE)
+ The static inline function 'gcry_error' returns the error value
+ consisting of the default error source and the error code CODE.
+
+ For GCRY applications, the default error source is
+ 'GPG_ERR_SOURCE_USER_1'. You can define 'GCRY_ERR_SOURCE_DEFAULT'
+ before including 'gcrypt.h' to change this default.
+
+ This function can be used in callback functions to construct an
+ error value to return it to the library.
+
+ The 'libgpg-error' library provides error codes for all system error
+numbers it knows about. If ERR is an unknown error number, the error
+code 'GPG_ERR_UNKNOWN_ERRNO' is used. The following functions can be
+used to construct error values from system errno numbers.
+
+ -- Function: gcry_error_t gcry_err_make_from_errno
+ (gcry_err_source_t SOURCE, int ERR)
+ The function 'gcry_err_make_from_errno' is like 'gcry_err_make',
+ but it takes a system error like 'errno' instead of a
+ 'gcry_err_code_t' error code.
+
+ -- Function: gcry_error_t gcry_error_from_errno (int ERR)
+ The function 'gcry_error_from_errno' is like 'gcry_error', but it
+ takes a system error like 'errno' instead of a 'gcry_err_code_t'
+ error code.
+
+ Sometimes you might want to map system error numbers to error codes
+directly, or map an error code representing a system error back to the
+system error number. The following functions can be used to do that.
+
+ -- Function: gcry_err_code_t gcry_err_code_from_errno (int ERR)
+ The function 'gcry_err_code_from_errno' returns the error code for
+ the system error ERR. If ERR is not a known system error, the
+ function returns 'GPG_ERR_UNKNOWN_ERRNO'.
+
+ -- Function: int gcry_err_code_to_errno (gcry_err_code_t ERR)
+ The function 'gcry_err_code_to_errno' returns the system error for
+ the error code ERR. If ERR is not an error code representing a
+ system error, or if this system error is not defined on this
+ system, the function returns '0'.
+
+
+File: gcrypt.info, Node: Error Sources, Next: Error Codes, Prev: Error Values, Up: Error Handling
+
+3.2.2 Error Sources
+-------------------
+
+The library 'libgpg-error' defines an error source for every component
+of the GnuPG system. The error source part of an error value is not
+well defined. As such it is mainly useful to improve the diagnostic
+error message for the user.
+
+ If the error code part of an error value is '0', the whole error
+value will be '0'. In this case the error source part is of course
+'GPG_ERR_SOURCE_UNKNOWN'.
+
+ The list of error sources that might occur in applications using
+Libgcrypt is:
+
+'GPG_ERR_SOURCE_UNKNOWN'
+ The error source is not known. The value of this error source is
+ '0'.
+
+'GPG_ERR_SOURCE_GPGME'
+ The error source is GPGME itself.
+
+'GPG_ERR_SOURCE_GPG'
+ The error source is GnuPG, which is the crypto engine used for the
+ OpenPGP protocol.
+
+'GPG_ERR_SOURCE_GPGSM'
+ The error source is GPGSM, which is the crypto engine used for the
+ OpenPGP protocol.
+
+'GPG_ERR_SOURCE_GCRYPT'
+ The error source is 'libgcrypt', which is used by crypto engines to
+ perform cryptographic operations.
+
+'GPG_ERR_SOURCE_GPGAGENT'
+ The error source is 'gpg-agent', which is used by crypto engines to
+ perform operations with the secret key.
+
+'GPG_ERR_SOURCE_PINENTRY'
+ The error source is 'pinentry', which is used by 'gpg-agent' to
+ query the passphrase to unlock a secret key.
+
+'GPG_ERR_SOURCE_SCD'
+ The error source is the SmartCard Daemon, which is used by
+ 'gpg-agent' to delegate operations with the secret key to a
+ SmartCard.
+
+'GPG_ERR_SOURCE_KEYBOX'
+ The error source is 'libkbx', a library used by the crypto engines
+ to manage local keyrings.
+
+'GPG_ERR_SOURCE_USER_1'
+'GPG_ERR_SOURCE_USER_2'
+'GPG_ERR_SOURCE_USER_3'
+'GPG_ERR_SOURCE_USER_4'
+ These error sources are not used by any GnuPG component and can be
+ used by other software. For example, applications using Libgcrypt
+ can use them to mark error values coming from callback handlers.
+ Thus 'GPG_ERR_SOURCE_USER_1' is the default for errors created with
+ 'gcry_error' and 'gcry_error_from_errno', unless you define
+ 'GCRY_ERR_SOURCE_DEFAULT' before including 'gcrypt.h'.
+
+
+File: gcrypt.info, Node: Error Codes, Next: Error Strings, Prev: Error Sources, Up: Error Handling
+
+3.2.3 Error Codes
+-----------------
+
+The library 'libgpg-error' defines many error values. The following
+list includes the most important error codes.
+
+'GPG_ERR_EOF'
+ This value indicates the end of a list, buffer or file.
+
+'GPG_ERR_NO_ERROR'
+ This value indicates success. The value of this error code is '0'.
+ Also, it is guaranteed that an error value made from the error code
+ '0' will be '0' itself (as a whole). This means that the error
+ source information is lost for this error code, however, as this
+ error code indicates that no error occurred, this is generally not
+ a problem.
+
+'GPG_ERR_GENERAL'
+ This value means that something went wrong, but either there is not
+ enough information about the problem to return a more useful error
+ value, or there is no separate error value for this type of
+ problem.
+
+'GPG_ERR_ENOMEM'
+ This value means that an out-of-memory condition occurred.
+
+'GPG_ERR_E...'
+ System errors are mapped to GPG_ERR_EFOO where FOO is the symbol
+ for the system error.
+
+'GPG_ERR_INV_VALUE'
+ This value means that some user provided data was out of range.
+
+'GPG_ERR_UNUSABLE_PUBKEY'
+ This value means that some recipients for a message were invalid.
+
+'GPG_ERR_UNUSABLE_SECKEY'
+ This value means that some signers were invalid.
+
+'GPG_ERR_NO_DATA'
+ This value means that data was expected where no data was found.
+
+'GPG_ERR_CONFLICT'
+ This value means that a conflict of some sort occurred.
+
+'GPG_ERR_NOT_IMPLEMENTED'
+ This value indicates that the specific function (or operation) is
+ not implemented. This error should never happen. It can only
+ occur if you use certain values or configuration options which do
+ not work, but for which we think that they should work at some
+ later time.
+
+'GPG_ERR_DECRYPT_FAILED'
+ This value indicates that a decryption operation was unsuccessful.
+
+'GPG_ERR_WRONG_KEY_USAGE'
+ This value indicates that a key is not used appropriately.
+
+'GPG_ERR_NO_SECKEY'
+ This value indicates that no secret key for the user ID is
+ available.
+
+'GPG_ERR_UNSUPPORTED_ALGORITHM'
+ This value means a verification failed because the cryptographic
+ algorithm is not supported by the crypto backend.
+
+'GPG_ERR_BAD_SIGNATURE'
+ This value means a verification failed because the signature is
+ bad.
+
+'GPG_ERR_NO_PUBKEY'
+ This value means a verification failed because the public key is
+ not available.
+
+'GPG_ERR_NOT_OPERATIONAL'
+ This value means that the library is not yet in state which allows
+ to use this function. This error code is in particular returned if
+ Libgcrypt is operated in FIPS mode and the internal state of the
+ library does not yet or not anymore allow the use of a service.
+
+ This error code is only available with newer libgpg-error versions,
+ thus you might see "invalid error code" when passing this to
+ 'gpg_strerror'. The numeric value of this error code is 176.
+
+'GPG_ERR_USER_1'
+'GPG_ERR_USER_2'
+'...'
+'GPG_ERR_USER_16'
+ These error codes are not used by any GnuPG component and can be
+ freely used by other software. Applications using Libgcrypt might
+ use them to mark specific errors returned by callback handlers if
+ no suitable error codes (including the system errors) for these
+ errors exist already.
+
+
+File: gcrypt.info, Node: Error Strings, Prev: Error Codes, Up: Error Handling
+
+3.2.4 Error Strings
+-------------------
+
+ -- Function: const char * gcry_strerror (gcry_error_t ERR)
+ The function 'gcry_strerror' returns a pointer to a statically
+ allocated string containing a description of the error code
+ contained in the error value ERR. This string can be used to
+ output a diagnostic message to the user.
+
+ -- Function: const char * gcry_strsource (gcry_error_t ERR)
+ The function 'gcry_strsource' returns a pointer to a statically
+ allocated string containing a description of the error source
+ contained in the error value ERR. This string can be used to
+ output a diagnostic message to the user.
+
+ The following example illustrates the use of the functions described
+above:
+
+ {
+ gcry_cipher_hd_t handle;
+ gcry_error_t err = 0;
+
+ err = gcry_cipher_open (&handle, GCRY_CIPHER_AES,
+ GCRY_CIPHER_MODE_CBC, 0);
+ if (err)
+ {
+ fprintf (stderr, "Failure: %s/%s\n",
+ gcry_strsource (err),
+ gcry_strerror (err));
+ }
+ }
+
+
+File: gcrypt.info, Node: Handler Functions, Next: Symmetric cryptography, Prev: Generalities, Up: Top
+
+4 Handler Functions
+*******************
+
+Libgcrypt makes it possible to install so called 'handler functions',
+which get called by Libgcrypt in case of certain events.
+
+* Menu:
+
+* Progress handler:: Using a progress handler function.
+* Allocation handler:: Using special memory allocation functions.
+* Error handler:: Using error handler functions.
+* Logging handler:: Using a special logging function.
+
+
+File: gcrypt.info, Node: Progress handler, Next: Allocation handler, Up: Handler Functions
+
+4.1 Progress handler
+====================
+
+It is often useful to retrieve some feedback while long running
+operations are performed.
+
+ -- Data type: gcry_handler_progress_t
+ Progress handler functions have to be of the type
+ 'gcry_handler_progress_t', which is defined as:
+
+ 'void (*gcry_handler_progress_t) (void *, const char *, int, int,
+ int)'
+
+ The following function may be used to register a handler function for
+this purpose.
+
+ -- Function: void gcry_set_progress_handler (gcry_handler_progress_t
+ CB, void *CB_DATA)
+
+ This function installs CB as the 'Progress handler' function. It
+ may be used only during initialization. CB must be defined as
+ follows:
+
+ void
+ my_progress_handler (void *CB_DATA, const char *WHAT,
+ int PRINTCHAR, int CURRENT, int TOTAL)
+ {
+ /* Do something. */
+ }
+
+ A description of the arguments of the progress handler function
+ follows.
+
+ CB_DATA
+ The argument provided in the call to
+ 'gcry_set_progress_handler'.
+ WHAT
+ A string identifying the type of the progress output. The
+ following values for WHAT are defined:
+
+ 'need_entropy'
+ Not enough entropy is available. TOTAL holds the number
+ of required bytes.
+
+ 'wait_dev_random'
+ Waiting to re-open a random device. TOTAL gives the
+ number of seconds until the next try.
+
+ 'primegen'
+ Values for PRINTCHAR:
+ '\n'
+ Prime generated.
+ '!'
+ Need to refresh the pool of prime numbers.
+ '<, >'
+ Number of bits adjusted.
+ '^'
+ Searching for a generator.
+ '.'
+ Fermat test on 10 candidates failed.
+ ':'
+ Restart with a new random value.
+ '+'
+ Rabin Miller test passed.
+
+
+File: gcrypt.info, Node: Allocation handler, Next: Error handler, Prev: Progress handler, Up: Handler Functions
+
+4.2 Allocation handler
+======================
+
+It is possible to make Libgcrypt use special memory allocation functions
+instead of the built-in ones.
+
+ Memory allocation functions are of the following types:
+ -- Data type: gcry_handler_alloc_t
+ This type is defined as: 'void *(*gcry_handler_alloc_t) (size_t
+ n)'.
+ -- Data type: gcry_handler_secure_check_t
+ This type is defined as: 'int *(*gcry_handler_secure_check_t)
+ (const void *)'.
+ -- Data type: gcry_handler_realloc_t
+ This type is defined as: 'void *(*gcry_handler_realloc_t) (void *p,
+ size_t n)'.
+ -- Data type: gcry_handler_free_t
+ This type is defined as: 'void *(*gcry_handler_free_t) (void *)'.
+
+ Special memory allocation functions can be installed with the
+following function:
+
+ -- Function: void gcry_set_allocation_handler (gcry_handler_alloc_t
+ FUNC_ALLOC, gcry_handler_alloc_t FUNC_ALLOC_SECURE,
+ gcry_handler_secure_check_t FUNC_SECURE_CHECK,
+ gcry_handler_realloc_t FUNC_REALLOC, gcry_handler_free_t
+ FUNC_FREE)
+ Install the provided functions and use them instead of the built-in
+ functions for doing memory allocation. Using this function is in
+ general not recommended because the standard Libgcrypt allocation
+ functions are guaranteed to zeroize memory if needed.
+
+ This function may be used only during initialization and may not be
+ used in fips mode.
+
+
+File: gcrypt.info, Node: Error handler, Next: Logging handler, Prev: Allocation handler, Up: Handler Functions
+
+4.3 Error handler
+=================
+
+The following functions may be used to register handler functions that
+are called by Libgcrypt in case certain error conditions occur. They
+may and should be registered prior to calling 'gcry_check_version'.
+
+ -- Data type: gcry_handler_no_mem_t
+ This type is defined as: 'int (*gcry_handler_no_mem_t) (void *,
+ size_t, unsigned int)'
+ -- Function: void gcry_set_outofcore_handler (gcry_handler_no_mem_t
+ FUNC_NO_MEM, void *CB_DATA)
+ This function registers FUNC_NO_MEM as 'out-of-core handler', which
+ means that it will be called in the case of not having enough
+ memory available. The handler is called with 3 arguments: The
+ first one is the pointer CB_DATA as set with this function, the
+ second is the requested memory size and the last being a flag. If
+ bit 0 of the flag is set, secure memory has been requested. The
+ handler should either return true to indicate that Libgcrypt should
+ try again allocating memory or return false to let Libgcrypt use
+ its default fatal error handler.
+
+ -- Data type: gcry_handler_error_t
+ This type is defined as: 'void (*gcry_handler_error_t) (void *,
+ int, const char *)'
+
+ -- Function: void gcry_set_fatalerror_handler (gcry_handler_error_t
+ FUNC_ERROR, void *CB_DATA)
+ This function registers FUNC_ERROR as 'error handler', which means
+ that it will be called in error conditions.
+
+
+File: gcrypt.info, Node: Logging handler, Prev: Error handler, Up: Handler Functions
+
+4.4 Logging handler
+===================
+
+ -- Data type: gcry_handler_log_t
+ This type is defined as: 'void (*gcry_handler_log_t) (void *, int,
+ const char *, va_list)'
+
+ -- Function: void gcry_set_log_handler (gcry_handler_log_t FUNC_LOG,
+ void *CB_DATA)
+ This function registers FUNC_LOG as 'logging handler', which means
+ that it will be called in case Libgcrypt wants to log a message.
+ This function may and should be used prior to calling
+ 'gcry_check_version'.
+
+
+File: gcrypt.info, Node: Symmetric cryptography, Next: Public Key cryptography, Prev: Handler Functions, Up: Top
+
+5 Symmetric cryptography
+************************
+
+The cipher functions are used for symmetrical cryptography, i.e.
+cryptography using a shared key. The programming model follows an
+open/process/close paradigm and is in that similar to other building
+blocks provided by Libgcrypt.
+
+* Menu:
+
+* Available ciphers:: List of ciphers supported by the library.
+* Available cipher modes:: List of cipher modes supported by the library.
+* Working with cipher handles:: How to perform operations related to cipher handles.
+* General cipher functions:: General cipher functions independent of cipher handles.
+
+
+File: gcrypt.info, Node: Available ciphers, Next: Available cipher modes, Up: Symmetric cryptography
+
+5.1 Available ciphers
+=====================
+
+'GCRY_CIPHER_NONE'
+ This is not a real algorithm but used by some functions as error
+ return. The value always evaluates to false.
+
+'GCRY_CIPHER_IDEA'
+ This is the IDEA algorithm.
+
+'GCRY_CIPHER_3DES'
+ Triple-DES with 3 Keys as EDE. The key size of this algorithm is
+ 168 bits but you have to pass 192 bits because the most significant
+ bits of each byte are ignored.
+
+'GCRY_CIPHER_CAST5'
+ CAST128-5 block cipher algorithm. The key size is 128 bits.
+
+'GCRY_CIPHER_BLOWFISH'
+ The blowfish algorithm. The supported key sizes are 8 to 576 bits
+ in 8 bit increments.
+
+'GCRY_CIPHER_SAFER_SK128'
+ Reserved and not currently implemented.
+
+'GCRY_CIPHER_DES_SK'
+ Reserved and not currently implemented.
+
+'GCRY_CIPHER_AES'
+'GCRY_CIPHER_AES128'
+'GCRY_CIPHER_RIJNDAEL'
+'GCRY_CIPHER_RIJNDAEL128'
+ AES (Rijndael) with a 128 bit key.
+
+'GCRY_CIPHER_AES192'
+'GCRY_CIPHER_RIJNDAEL192'
+ AES (Rijndael) with a 192 bit key.
+
+'GCRY_CIPHER_AES256'
+'GCRY_CIPHER_RIJNDAEL256'
+ AES (Rijndael) with a 256 bit key.
+
+'GCRY_CIPHER_TWOFISH'
+ The Twofish algorithm with a 256 bit key.
+
+'GCRY_CIPHER_TWOFISH128'
+ The Twofish algorithm with a 128 bit key.
+
+'GCRY_CIPHER_ARCFOUR'
+ An algorithm which is 100% compatible with RSA Inc.'s RC4
+ algorithm. Note that this is a stream cipher and must be used very
+ carefully to avoid a couple of weaknesses.
+
+'GCRY_CIPHER_DES'
+ Standard DES with a 56 bit key. You need to pass 64 bit but the
+ high bits of each byte are ignored. Note, that this is a weak
+ algorithm which can be broken in reasonable time using a brute
+ force approach.
+
+'GCRY_CIPHER_SERPENT128'
+'GCRY_CIPHER_SERPENT192'
+'GCRY_CIPHER_SERPENT256'
+ The Serpent cipher from the AES contest.
+
+'GCRY_CIPHER_RFC2268_40'
+'GCRY_CIPHER_RFC2268_128'
+ Ron's Cipher 2 in the 40 and 128 bit variants.
+
+'GCRY_CIPHER_SEED'
+ A 128 bit cipher as described by RFC4269.
+
+'GCRY_CIPHER_CAMELLIA128'
+'GCRY_CIPHER_CAMELLIA192'
+'GCRY_CIPHER_CAMELLIA256'
+ The Camellia cipher by NTT. See
+ <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html>.
+
+'GCRY_CIPHER_SALSA20'
+ This is the Salsa20 stream cipher.
+
+'GCRY_CIPHER_SALSA20R12'
+ This is the Salsa20/12 - reduced round version of Salsa20 stream
+ cipher.
+
+'GCRY_CIPHER_GOST28147'
+ The GOST 28147-89 cipher, defined in the respective GOST standard.
+ Translation of this GOST into English is provided in the RFC-5830.
+
+'GCRY_CIPHER_GOST28147_MESH'
+ The GOST 28147-89 cipher, defined in the respective GOST standard.
+ Translation of this GOST into English is provided in the RFC-5830.
+ This cipher will use CryptoPro keymeshing as defined in RFC 4357 if
+ it has to be used for the selected parameter set.
+
+'GCRY_CIPHER_CHACHA20'
+ This is the ChaCha20 stream cipher.
+
+'GCRY_CIPHER_SM4'
+ A 128 bit cipher by the State Cryptography Administration of China
+ (SCA). See <https://tools.ietf.org/html/draft-ribose-cfrg-sm4-10>.
+
+
+File: gcrypt.info, Node: Available cipher modes, Next: Working with cipher handles, Prev: Available ciphers, Up: Symmetric cryptography
+
+5.2 Available cipher modes
+==========================
+
+'GCRY_CIPHER_MODE_NONE'
+ No mode specified. This should not be used. The only exception is
+ that if Libgcrypt is not used in FIPS mode and if any debug flag
+ has been set, this mode may be used to bypass the actual
+ encryption.
+
+'GCRY_CIPHER_MODE_ECB'
+ Electronic Codebook mode.
+
+'GCRY_CIPHER_MODE_CFB'
+'GCRY_CIPHER_MODE_CFB8'
+ Cipher Feedback mode. For GCRY_CIPHER_MODE_CFB the shift size
+ equals the block size of the cipher (e.g. for AES it is CFB-128).
+ For GCRY_CIPHER_MODE_CFB8 the shift size is 8 bit but that variant
+ is not yet available.
+
+'GCRY_CIPHER_MODE_CBC'
+ Cipher Block Chaining mode.
+
+'GCRY_CIPHER_MODE_STREAM'
+ Stream mode, only to be used with stream cipher algorithms.
+
+'GCRY_CIPHER_MODE_OFB'
+ Output Feedback mode.
+
+'GCRY_CIPHER_MODE_CTR'
+ Counter mode.
+
+'GCRY_CIPHER_MODE_AESWRAP'
+ This mode is used to implement the AES-Wrap algorithm according to
+ RFC-3394. It may be used with any 128 bit block length algorithm,
+ however the specs require one of the 3 AES algorithms. These
+ special conditions apply: If 'gcry_cipher_setiv' has not been used
+ the standard IV is used; if it has been used the lower 64 bit of
+ the IV are used as the Alternative Initial Value. On encryption
+ the provided output buffer must be 64 bit (8 byte) larger than the
+ input buffer; in-place encryption is still allowed. On decryption
+ the output buffer may be specified 64 bit (8 byte) shorter than
+ then input buffer. As per specs the input length must be at least
+ 128 bits and the length must be a multiple of 64 bits.
+
+'GCRY_CIPHER_MODE_CCM'
+ Counter with CBC-MAC mode is an Authenticated Encryption with
+ Associated Data (AEAD) block cipher mode, which is specified in
+ 'NIST Special Publication 800-38C' and RFC 3610.
+
+'GCRY_CIPHER_MODE_GCM'
+ Galois/Counter Mode (GCM) is an Authenticated Encryption with
+ Associated Data (AEAD) block cipher mode, which is specified in
+ 'NIST Special Publication 800-38D'.
+
+'GCRY_CIPHER_MODE_POLY1305'
+ This mode implements the Poly1305 Authenticated Encryption with
+ Associated Data (AEAD) mode according to RFC-8439. This mode can
+ be used with ChaCha20 stream cipher.
+
+'GCRY_CIPHER_MODE_OCB'
+ OCB is an Authenticated Encryption with Associated Data (AEAD)
+ block cipher mode, which is specified in RFC-7253. Supported tag
+ lengths are 128, 96, and 64 bit with the default being 128 bit. To
+ switch to a different tag length 'gcry_cipher_ctl' using the
+ command 'GCRYCTL_SET_TAGLEN' and the address of an 'int' variable
+ set to 12 (for 96 bit) or 8 (for 64 bit) provided for the 'buffer'
+ argument and 'sizeof(int)' for 'buflen'.
+
+ Note that the use of 'gcry_cipher_final' is required.
+
+'GCRY_CIPHER_MODE_XTS'
+ XEX-based tweaked-codebook mode with ciphertext stealing (XTS) mode
+ is used to implement the AES-XTS as specified in IEEE 1619 Standard
+ Architecture for Encrypted Shared Storage Media and NIST SP800-38E.
+
+ The XTS mode requires doubling key-length, for example, using
+ 512-bit key with AES-256 ('GCRY_CIPHER_AES256'). The 128-bit tweak
+ value is feed to XTS mode as little-endian byte array using
+ 'gcry_cipher_setiv' function. When encrypting or decrypting,
+ full-sized data unit buffers needs to be passed to
+ 'gcry_cipher_encrypt' or 'gcry_cipher_decrypt'. The tweak value is
+ automatically incremented after each call of 'gcry_cipher_encrypt'
+ and 'gcry_cipher_decrypt'. Auto-increment allows avoiding need of
+ setting IV between processing of sequential data units.
+
+'GCRY_CIPHER_MODE_EAX'
+ EAX is an Authenticated Encryption with Associated Data (AEAD)
+ block cipher mode by Bellare, Rogaway, and Wagner (see
+ <http://web.cs.ucdavis.edu/~rogaway/papers/eax.html>).
+
+
+File: gcrypt.info, Node: Working with cipher handles, Next: General cipher functions, Prev: Available cipher modes, Up: Symmetric cryptography
+
+5.3 Working with cipher handles
+===============================
+
+To use a cipher algorithm, you must first allocate an according handle.
+This is to be done using the open function:
+
+ -- Function: gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *HD, int
+ ALGO, int MODE, unsigned int FLAGS)
+
+ This function creates the context handle required for most of the
+ other cipher functions and returns a handle to it in 'hd'. In case
+ of an error, an according error code is returned.
+
+ The ID of algorithm to use must be specified via ALGO. See *note
+ Available ciphers::, for a list of supported ciphers and the
+ according constants.
+
+ Besides using the constants directly, the function
+ 'gcry_cipher_map_name' may be used to convert the textual name of
+ an algorithm into the according numeric ID.
+
+ The cipher mode to use must be specified via MODE. See *note
+ Available cipher modes::, for a list of supported cipher modes and
+ the according constants. Note that some modes are incompatible
+ with some algorithms - in particular, stream mode
+ ('GCRY_CIPHER_MODE_STREAM') only works with stream ciphers.
+ Poly1305 AEAD mode ('GCRY_CIPHER_MODE_POLY1305') only works with
+ ChaCha20 stream cipher. The block cipher modes
+ ('GCRY_CIPHER_MODE_ECB', 'GCRY_CIPHER_MODE_CBC',
+ 'GCRY_CIPHER_MODE_CFB', 'GCRY_CIPHER_MODE_OFB',
+ 'GCRY_CIPHER_MODE_CTR' and 'GCRY_CIPHER_MODE_EAX') will work with
+ any block cipher algorithm. GCM mode ('GCRY_CIPHER_MODE_CCM'), CCM
+ mode ('GCRY_CIPHER_MODE_GCM'), OCB mode ('GCRY_CIPHER_MODE_OCB'),
+ and XTS mode ('GCRY_CIPHER_MODE_XTS') will only work with block
+ cipher algorithms which have the block size of 16 bytes.
+
+ The third argument FLAGS can either be passed as '0' or as the
+ bit-wise OR of the following constants.
+
+ 'GCRY_CIPHER_SECURE'
+ Make sure that all operations are allocated in secure memory.
+ This is useful when the key material is highly confidential.
+ 'GCRY_CIPHER_ENABLE_SYNC'
+ This flag enables the CFB sync mode, which is a special
+ feature of Libgcrypt's CFB mode implementation to allow for
+ OpenPGP's CFB variant. See 'gcry_cipher_sync'.
+ 'GCRY_CIPHER_CBC_CTS'
+ Enable cipher text stealing (CTS) for the CBC mode. Cannot be
+ used simultaneous as GCRY_CIPHER_CBC_MAC. CTS mode makes it
+ possible to transform data of almost arbitrary size (only
+ limitation is that it must be greater than the algorithm's
+ block size).
+ 'GCRY_CIPHER_CBC_MAC'
+ Compute CBC-MAC keyed checksums. This is the same as CBC
+ mode, but only output the last block. Cannot be used
+ simultaneous as GCRY_CIPHER_CBC_CTS.
+
+ Use the following function to release an existing handle:
+
+ -- Function: void gcry_cipher_close (gcry_cipher_hd_t H)
+
+ This function releases the context created by 'gcry_cipher_open'.
+ It also zeroises all sensitive information associated with this
+ cipher handle.
+
+ In order to use a handle for performing cryptographic operations, a
+'key' has to be set first:
+
+ -- Function: gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t H, const
+ void *K, size_t L)
+
+ Set the key K used for encryption or decryption in the context
+ denoted by the handle H. The length L (in bytes) of the key K must
+ match the required length of the algorithm set for this context or
+ be in the allowed range for algorithms with variable key size. The
+ function checks this and returns an error if there is a problem. A
+ caller should always check for an error.
+
+ Most crypto modes requires an initialization vector (IV), which
+usually is a non-secret random string acting as a kind of salt value.
+The CTR mode requires a counter, which is also similar to a salt value.
+To set the IV or CTR, use these functions:
+
+ -- Function: gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t H, const
+ void *K, size_t L)
+
+ Set the initialization vector used for encryption or decryption.
+ The vector is passed as the buffer K of length L bytes and copied
+ to internal data structures. The function checks that the IV
+ matches the requirement of the selected algorithm and mode.
+
+ This function is also used by AEAD modes and with Salsa20 and
+ ChaCha20 stream ciphers to set or update the required nonce. In
+ these cases it needs to be called after setting the key.
+
+ -- Function: gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t H, const
+ void *C, size_t L)
+
+ Set the counter vector used for encryption or decryption. The
+ counter is passed as the buffer C of length L bytes and copied to
+ internal data structures. The function checks that the counter
+ matches the requirement of the selected algorithm (i.e., it must be
+ the same size as the block size).
+
+ -- Function: gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t H)
+
+ Set the given handle's context back to the state it had after the
+ last call to gcry_cipher_setkey and clear the initialization
+ vector.
+
+ Note that gcry_cipher_reset is implemented as a macro.
+
+ Authenticated Encryption with Associated Data (AEAD) block cipher
+modes require the handling of the authentication tag and the additional
+authenticated data, which can be done by using the following functions:
+
+ -- Function: gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t H,
+ const void *ABUF, size_t ABUFLEN)
+
+ Process the buffer ABUF of length ABUFLEN as the additional
+ authenticated data (AAD) for AEAD cipher modes.
+
+ -- Function: gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t H,
+ void *TAG, size_t TAGLEN)
+
+ This function is used to read the authentication tag after
+ encryption. The function finalizes and outputs the authentication
+ tag to the buffer TAG of length TAGLEN bytes.
+
+ Depending on the used mode certain restrictions for TAGLEN are
+ enforced: For GCM TAGLEN must be at least 16 or one of the allowed
+ truncated lengths (4, 8, 12, 13, 14, or 15).
+
+ -- Function: gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t H,
+ const void *TAG, size_t TAGLEN)
+
+ Check the authentication tag after decryption. The authentication
+ tag is passed as the buffer TAG of length TAGLEN bytes and compared
+ to internal authentication tag computed during decryption. Error
+ code 'GPG_ERR_CHECKSUM' is returned if the authentication tag in
+ the buffer TAG does not match the authentication tag calculated
+ during decryption.
+
+ Depending on the used mode certain restrictions for TAGLEN are
+ enforced: For GCM TAGLEN must either be 16 or one of the allowed
+ truncated lengths (4, 8, 12, 13, 14, or 15).
+
+ The actual encryption and decryption is done by using one of the
+following functions. They may be used as often as required to process
+all the data.
+
+ -- Function: gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t H,
+ unsigned char *out, size_t OUTSIZE, const unsigned char *IN,
+ size_t INLEN)
+
+ 'gcry_cipher_encrypt' is used to encrypt the data. This function
+ can either work in place or with two buffers. It uses the cipher
+ context already setup and described by the handle H. There are 2
+ ways to use the function: If IN is passed as 'NULL' and INLEN is
+ '0', in-place encryption of the data in OUT of length OUTSIZE takes
+ place. With IN being not 'NULL', INLEN bytes are encrypted to the
+ buffer OUT which must have at least a size of INLEN. OUTSIZE must
+ be set to the allocated size of OUT, so that the function can check
+ that there is sufficient space. Note that overlapping buffers are
+ not allowed.
+
+ Depending on the selected algorithms and encryption mode, the
+ length of the buffers must be a multiple of the block size.
+
+ Some encryption modes require that 'gcry_cipher_final' is used
+ before the final data chunk is passed to this function.
+
+ The function returns '0' on success or an error code.
+
+ -- Function: gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t H,
+ unsigned char *out, size_t OUTSIZE, const unsigned char *IN,
+ size_t INLEN)
+
+ 'gcry_cipher_decrypt' is used to decrypt the data. This function
+ can either work in place or with two buffers. It uses the cipher
+ context already setup and described by the handle H. There are 2
+ ways to use the function: If IN is passed as 'NULL' and INLEN is
+ '0', in-place decryption of the data in OUT or length OUTSIZE takes
+ place. With IN being not 'NULL', INLEN bytes are decrypted to the
+ buffer OUT which must have at least a size of INLEN. OUTSIZE must
+ be set to the allocated size of OUT, so that the function can check
+ that there is sufficient space. Note that overlapping buffers are
+ not allowed.
+
+ Depending on the selected algorithms and encryption mode, the
+ length of the buffers must be a multiple of the block size.
+
+ Some encryption modes require that 'gcry_cipher_final' is used
+ before the final data chunk is passed to this function.
+
+ The function returns '0' on success or an error code.
+
+ The OCB mode features integrated padding and must thus be told about
+the end of the input data. This is done with:
+
+ -- Function: gcry_error_t gcry_cipher_final (gcry_cipher_hd_t H)
+
+ Set a flag in the context to tell the encrypt and decrypt functions
+ that their next call will provide the last chunk of data. Only the
+ first call to this function has an effect and only for modes which
+ support it. Checking the error is in general not necessary. This
+ is implemented as a macro.
+
+ OpenPGP (as defined in RFC-4880) requires a special sync operation in
+some places. The following function is used for this:
+
+ -- Function: gcry_error_t gcry_cipher_sync (gcry_cipher_hd_t H)
+
+ Perform the OpenPGP sync operation on context H. Note that this is
+ a no-op unless the context was created with the flag
+ 'GCRY_CIPHER_ENABLE_SYNC'
+
+ Some of the described functions are implemented as macros utilizing a
+catch-all control function. This control function is rarely used
+directly but there is nothing which would inhibit it:
+
+ -- Function: gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t H, int CMD,
+ void *BUFFER, size_t BUFLEN)
+
+ 'gcry_cipher_ctl' controls various aspects of the cipher module and
+ specific cipher contexts. Usually some more specialized functions
+ or macros are used for this purpose. The semantics of the function
+ and its parameters depends on the the command CMD and the passed
+ context handle H. Please see the comments in the source code
+ ('src/global.c') for details.
+
+ -- Function: gcry_error_t gcry_cipher_info (gcry_cipher_hd_t H, int
+ WHAT, void *BUFFER, size_t *NBYTES)
+
+ 'gcry_cipher_info' is used to retrieve various information about a
+ cipher context or the cipher module in general.
+
+ 'GCRYCTL_GET_TAGLEN:'
+ Return the length of the tag for an AE algorithm mode. An
+ error is returned for modes which do not support a tag.
+ BUFFER must be given as NULL. On success the result is stored
+ NBYTES. The taglen is returned in bytes.
+
+
+File: gcrypt.info, Node: General cipher functions, Prev: Working with cipher handles, Up: Symmetric cryptography
+
+5.4 General cipher functions
+============================
+
+To work with the algorithms, several functions are available to map
+algorithm names to the internal identifiers, as well as ways to retrieve
+information about an algorithm or the current cipher context.
+
+ -- Function: gcry_error_t gcry_cipher_algo_info (int ALGO, int WHAT,
+ void *BUFFER, size_t *NBYTES)
+
+ This function is used to retrieve information on a specific
+ algorithm. You pass the cipher algorithm ID as ALGO and the type
+ of information requested as WHAT. The result is either returned as
+ the return code of the function or copied to the provided BUFFER
+ whose allocated length must be available in an integer variable
+ with the address passed in NBYTES. This variable will also receive
+ the actual used length of the buffer.
+
+ Here is a list of supported codes for WHAT:
+
+ 'GCRYCTL_GET_KEYLEN:'
+ Return the length of the key. If the algorithm supports
+ multiple key lengths, the maximum supported value is returned.
+ The length is returned as number of octets (bytes) and not as
+ number of bits in NBYTES; BUFFER must be zero. Note that it
+ is usually better to use the convenience function
+ 'gcry_cipher_get_algo_keylen'.
+
+ 'GCRYCTL_GET_BLKLEN:'
+ Return the block length of the algorithm. The length is
+ returned as a number of octets in NBYTES; BUFFER must be zero.
+ Note that it is usually better to use the convenience function
+ 'gcry_cipher_get_algo_blklen'.
+
+ 'GCRYCTL_TEST_ALGO:'
+ Returns '0' when the specified algorithm is available for use.
+ BUFFER and NBYTES must be zero.
+
+ -- Function: size_t gcry_cipher_get_algo_keylen (ALGO)
+
+ This function returns length of the key for algorithm ALGO. If the
+ algorithm supports multiple key lengths, the maximum supported key
+ length is returned. On error '0' is returned. The key length is
+ returned as number of octets.
+
+ This is a convenience functions which should be preferred over
+ 'gcry_cipher_algo_info' because it allows for proper type checking.
+
+ -- Function: size_t gcry_cipher_get_algo_blklen (int ALGO)
+
+ This functions returns the block-length of the algorithm ALGO
+ counted in octets. On error '0' is returned.
+
+ This is a convenience functions which should be preferred over
+ 'gcry_cipher_algo_info' because it allows for proper type checking.
+
+ -- Function: const char * gcry_cipher_algo_name (int ALGO)
+
+ 'gcry_cipher_algo_name' returns a string with the name of the
+ cipher algorithm ALGO. If the algorithm is not known or another
+ error occurred, the string '"?"' is returned. This function should
+ not be used to test for the availability of an algorithm.
+
+ -- Function: int gcry_cipher_map_name (const char *NAME)
+
+ 'gcry_cipher_map_name' returns the algorithm identifier for the
+ cipher algorithm described by the string NAME. If this algorithm
+ is not available '0' is returned.
+
+ -- Function: int gcry_cipher_mode_from_oid (const char *STRING)
+
+ Return the cipher mode associated with an ASN.1 object identifier.
+ The object identifier is expected to be in the IETF-style dotted
+ decimal notation. The function returns '0' for an unknown object
+ identifier or when no mode is associated with it.
+
+
+File: gcrypt.info, Node: Public Key cryptography, Next: Hashing, Prev: Symmetric cryptography, Up: Top
+
+6 Public Key cryptography
+*************************
+
+Public key cryptography, also known as asymmetric cryptography, is an
+easy way for key management and to provide digital signatures.
+Libgcrypt provides two completely different interfaces to public key
+cryptography, this chapter explains the one based on S-expressions.
+
+* Menu:
+
+* Available algorithms:: Algorithms supported by the library.
+* Used S-expressions:: Introduction into the used S-expression.
+* Cryptographic Functions:: Functions for performing the cryptographic actions.
+* Dedicated ECC Functions:: Dedicated functions for elliptic curves.
+* General public-key related Functions:: General functions, not implementing any cryptography.
+
+
+File: gcrypt.info, Node: Available algorithms, Next: Used S-expressions, Up: Public Key cryptography
+
+6.1 Available algorithms
+========================
+
+Libgcrypt supports the RSA (Rivest-Shamir-Adleman) algorithms as well as
+DSA (Digital Signature Algorithm), Elgamal, ECDSA, ECDH, and EdDSA.
+
+
+File: gcrypt.info, Node: Used S-expressions, Next: Cryptographic Functions, Prev: Available algorithms, Up: Public Key cryptography
+
+6.2 Used S-expressions
+======================
+
+Libgcrypt's API for asymmetric cryptography is based on data structures
+called S-expressions (see
+<http://people.csail.mit.edu/rivest/sexp.html>) and does not work with
+contexts/handles as most of the other building blocks of Libgcrypt do.
+
+The following information are stored in S-expressions:
+
+ * keys
+
+ * plain text data
+
+ * encrypted data
+
+ * signatures
+
+To describe how Libgcrypt expect keys, we use examples. Note that words
+in uppercase indicate parameters whereas lowercase words are literals.
+
+ Note that all MPI (multi-precision-integers) values are expected to
+be in 'GCRYMPI_FMT_USG' format. An easy way to create S-expressions is
+by using 'gcry_sexp_build' which allows to pass a string with
+printf-like escapes to insert MPI values.
+
+* Menu:
+
+* RSA key parameters:: Parameters used with an RSA key.
+* DSA key parameters:: Parameters used with a DSA key.
+* ECC key parameters:: Parameters used with ECC keys.
+
+
+File: gcrypt.info, Node: RSA key parameters, Next: DSA key parameters, Up: Used S-expressions
+
+6.2.1 RSA key parameters
+------------------------
+
+An RSA private key is described by this S-expression:
+
+ (private-key
+ (rsa
+ (n N-MPI)
+ (e E-MPI)
+ (d D-MPI)
+ (p P-MPI)
+ (q Q-MPI)
+ (u U-MPI)))
+
+An RSA public key is described by this S-expression:
+
+ (public-key
+ (rsa
+ (n N-MPI)
+ (e E-MPI)))
+
+N-MPI
+ RSA public modulus n.
+E-MPI
+ RSA public exponent e.
+D-MPI
+ RSA secret exponent d = e^{-1} \bmod (p-1)(q-1).
+P-MPI
+ RSA secret prime p.
+Q-MPI
+ RSA secret prime q with p < q.
+U-MPI
+ Multiplicative inverse u = p^{-1} \bmod q.
+
+ For signing and decryption the parameters (p, q, u) are optional but
+greatly improve the performance. Either all of these optional
+parameters must be given or none of them. They are mandatory for
+gcry_pk_testkey.
+
+ Note that OpenSSL uses slighly different parameters: q < p and u =
+q^{-1} \bmod p. To use these parameters you will need to swap the
+values and recompute u. Here is example code to do this:
+
+ if (gcry_mpi_cmp (p, q) > 0)
+ {
+ gcry_mpi_swap (p, q);
+ gcry_mpi_invm (u, p, q);
+ }
+
+
+File: gcrypt.info, Node: DSA key parameters, Next: ECC key parameters, Prev: RSA key parameters, Up: Used S-expressions
+
+6.2.2 DSA key parameters
+------------------------
+
+A DSA private key is described by this S-expression:
+
+ (private-key
+ (dsa
+ (p P-MPI)
+ (q Q-MPI)
+ (g G-MPI)
+ (y Y-MPI)
+ (x X-MPI)))
+
+P-MPI
+ DSA prime p.
+Q-MPI
+ DSA group order q (which is a prime divisor of p-1).
+G-MPI
+ DSA group generator g.
+Y-MPI
+ DSA public key value y = g^x \bmod p.
+X-MPI
+ DSA secret exponent x.
+
+ The public key is similar with "private-key" replaced by "public-key"
+and no X-MPI.
+
+
+File: gcrypt.info, Node: ECC key parameters, Prev: DSA key parameters, Up: Used S-expressions
+
+6.2.3 ECC key parameters
+------------------------
+
+An ECC private key is described by this S-expression:
+
+ (private-key
+ (ecc
+ (p P-MPI)
+ (a A-MPI)
+ (b B-MPI)
+ (g G-POINT)
+ (n N-MPI)
+ (q Q-POINT)
+ (d D-MPI)))
+
+P-MPI
+ Prime specifying the field GF(p).
+A-MPI
+B-MPI
+ The two coefficients of the Weierstrass equation y^2 = x^3 + ax + b
+G-POINT
+ Base point g.
+N-MPI
+ Order of g
+Q-POINT
+ The point representing the public key Q = dG.
+D-MPI
+ The private key d
+
+ All point values are encoded in standard format; Libgcrypt does in
+general only support uncompressed points, thus the first byte needs to
+be '0x04'. However "EdDSA" describes its own compression scheme which
+is used by default; the non-standard first byte '0x40' may optionally be
+used to explicit flag the use of the algorithm’s native compression
+method.
+
+ The public key is similar with "private-key" replaced by "public-key"
+and no D-MPI.
+
+ If the domain parameters are well-known, the name of this curve may
+be used. For example
+
+ (private-key
+ (ecc
+ (curve "NIST P-192")
+ (q Q-POINT)
+ (d D-MPI)))
+
+ Note that Q-POINT is optional for a private key. The 'curve'
+parameter may be given in any case and is used to replace missing
+parameters.
+
+Currently implemented curves are:
+
+'Curve25519'
+'X25519'
+'1.3.6.1.4.1.3029.1.5.1'
+'1.3.101.110'
+ The RFC-8410 255 bit curve, its RFC name, OpenPGP and RFC OIDs.
+
+'X448'
+'1.3.101.111'
+ The RFC-8410 448 bit curve and its RFC OID.
+
+'Ed25519'
+'1.3.6.1.4.1.11591.15.1'
+'1.3.101.112'
+ The signing variant of the RFC-8410 255 bit curve, its OpenPGP and
+ RFC OIDs.
+
+'Ed448'
+'1.3.101.113'
+ The signing variant of the RFC-8410 448 bit curve and its RFC OID.
+
+'NIST P-192'
+'1.2.840.10045.3.1.1'
+'nistp192'
+'prime192v1'
+'secp192r1'
+ The NIST 192 bit curve, its OID and aliases.
+
+'NIST P-224'
+'1.3.132.0.33'
+'nistp224'
+'secp224r1'
+ The NIST 224 bit curve, its OID and aliases.
+
+'NIST P-256'
+'1.2.840.10045.3.1.7'
+'nistp256'
+'prime256v1'
+'secp256r1'
+ The NIST 256 bit curve, its OID and aliases.
+
+'NIST P-384'
+'1.3.132.0.34'
+'nistp384'
+'secp384r1'
+ The NIST 384 bit curve, its OID and aliases.
+
+'NIST P-521'
+'1.3.132.0.35'
+'nistp521'
+'secp521r1'
+ The NIST 521 bit curve, its OID and aliases.
+
+'brainpoolP160r1'
+'1.3.36.3.3.2.8.1.1.1'
+ The Brainpool 160 bit curve and its OID.
+
+'brainpoolP192r1'
+'1.3.36.3.3.2.8.1.1.3'
+ The Brainpool 192 bit curve and its OID.
+
+'brainpoolP224r1'
+'1.3.36.3.3.2.8.1.1.5'
+ The Brainpool 224 bit curve and its OID.
+
+'brainpoolP256r1'
+'1.3.36.3.3.2.8.1.1.7'
+ The Brainpool 256 bit curve and its OID.
+
+'brainpoolP320r1'
+'1.3.36.3.3.2.8.1.1.9'
+ The Brainpool 320 bit curve and its OID.
+
+'brainpoolP384r1'
+'1.3.36.3.3.2.8.1.1.11'
+ The Brainpool 384 bit curve and its OID.
+
+'brainpoolP512r1'
+'1.3.36.3.3.2.8.1.1.13'
+ The Brainpool 512 bit curve and its OID.
+
+ As usual the OIDs may optionally be prefixed with the string 'OID.'
+or 'oid.'.
+
+
+File: gcrypt.info, Node: Cryptographic Functions, Next: Dedicated ECC Functions, Prev: Used S-expressions, Up: Public Key cryptography
+
+6.3 Cryptographic Functions
+===========================
+
+Some functions operating on S-expressions support 'flags' to influence
+the operation. These flags have to be listed in a sub-S-expression
+named 'flags'. Flag names are case-sensitive. The following flags are
+known:
+
+'comp'
+'nocomp'
+ If supported by the algorithm and curve the 'comp' flag requests
+ that points are returned in compact (compressed) representation.
+ The 'nocomp' flag requests that points are returned with full
+ coordinates. The default depends on the the algorithm and curve.
+ The compact representation requires a small overhead before a point
+ can be used but halves the size of a to be conveyed public key. If
+ 'comp' is used with the "EdDSA" algorithm the key generation prefix
+ the public key with a '0x40' byte.
+
+'pkcs1'
+ Use PKCS#1 block type 2 padding for encryption, block type 1
+ padding for signing.
+
+'oaep'
+ Use RSA-OAEP padding for encryption.
+
+'pss'
+ Use RSA-PSS padding for signing.
+
+'eddsa'
+ Use the EdDSA scheme signing instead of the default ECDSA
+ algorithm. Note that the EdDSA uses a special form of the public
+ key.
+
+'rfc6979'
+ For DSA and ECDSA use a deterministic scheme for the k parameter.
+
+'no-blinding'
+ Do not use a technique called 'blinding', which is used by default
+ in order to prevent leaking of secret information. Blinding is
+ only implemented by RSA, but it might be implemented by other
+ algorithms in the future as well, when necessary.
+
+'param'
+ For ECC key generation also return the domain parameters. For ECC
+ signing and verification override default parameters by provided
+ domain parameters of the public or private key.
+
+'transient-key'
+ This flag is only meaningful for RSA, DSA, and ECC key generation.
+ If given the key is created using a faster and a somewhat less
+ secure random number generator. This flag may be used for keys
+ which are only used for a short time or per-message and do not
+ require full cryptographic strength.
+
+'no-keytest'
+ This flag skips internal failsafe tests to assert that a generated
+ key is properly working. It currently has an effect only for
+ standard ECC key generation. It is mostly useful along with
+ transient-key to achieve fastest ECC key generation.
+
+'use-x931'
+ Force the use of the ANSI X9.31 key generation algorithm instead of
+ the default algorithm. This flag is only meaningful for RSA key
+ generation and usually not required. Note that this algorithm is
+ implicitly used if either 'derive-parms' is given or Libgcrypt is
+ in FIPS mode.
+
+'use-fips186'
+ Force the use of the FIPS 186 key generation algorithm instead of
+ the default algorithm. This flag is only meaningful for DSA and
+ usually not required. Note that this algorithm is implicitly used
+ if either 'derive-parms' is given or Libgcrypt is in FIPS mode. As
+ of now FIPS 186-2 is implemented; after the approval of FIPS 186-3
+ the code will be changed to implement 186-3.
+
+'use-fips186-2'
+ Force the use of the FIPS 186-2 key generation algorithm instead of
+ the default algorithm. This algorithm is slightly different from
+ FIPS 186-3 and allows only 1024 bit keys. This flag is only
+ meaningful for DSA and only required for FIPS testing backward
+ compatibility.
+
+Now that we know the key basics, we can carry on and explain how to
+encrypt and decrypt data. In almost all cases the data is a random
+session key which is in turn used for the actual encryption of the real
+data. There are 2 functions to do this:
+
+ -- Function: gcry_error_t gcry_pk_encrypt (gcry_sexp_t *R_CIPH,
+ gcry_sexp_t DATA, gcry_sexp_t PKEY)
+
+ Obviously a public key must be provided for encryption. It is
+ expected as an appropriate S-expression (see above) in PKEY. The
+ data to be encrypted can either be in the simple old format, which
+ is a very simple S-expression consisting only of one MPI, or it may
+ be a more complex S-expression which also allows to specify flags
+ for operation, like e.g. padding rules.
+
+ If you don't want to let Libgcrypt handle the padding, you must
+ pass an appropriate MPI using this expression for DATA:
+
+ (data
+ (flags raw)
+ (value MPI))
+
+ This has the same semantics as the old style MPI only way. MPI is
+ the actual data, already padded appropriate for your protocol.
+ Most RSA based systems however use PKCS#1 padding and so you can
+ use this S-expression for DATA:
+
+ (data
+ (flags pkcs1)
+ (value BLOCK))
+
+ Here, the "flags" list has the "pkcs1" flag which let the function
+ know that it should provide PKCS#1 block type 2 padding. The
+ actual data to be encrypted is passed as a string of octets in
+ BLOCK. The function checks that this data actually can be used
+ with the given key, does the padding and encrypts it.
+
+ If the function could successfully perform the encryption, the
+ return value will be 0 and a new S-expression with the encrypted
+ result is allocated and assigned to the variable at the address of
+ R_CIPH. The caller is responsible to release this value using
+ 'gcry_sexp_release'. In case of an error, an error code is
+ returned and R_CIPH will be set to 'NULL'.
+
+ The returned S-expression has this format when used with RSA:
+
+ (enc-val
+ (rsa
+ (a A-MPI)))
+
+ Where A-MPI is an MPI with the result of the RSA operation. When
+ using the Elgamal algorithm, the return value will have this
+ format:
+
+ (enc-val
+ (elg
+ (a A-MPI)
+ (b B-MPI)))
+
+ Where A-MPI and B-MPI are MPIs with the result of the Elgamal
+ encryption operation.
+
+ -- Function: gcry_error_t gcry_pk_decrypt (gcry_sexp_t *R_PLAIN,
+ gcry_sexp_t DATA, gcry_sexp_t SKEY)
+
+ Obviously a private key must be provided for decryption. It is
+ expected as an appropriate S-expression (see above) in SKEY. The
+ data to be decrypted must match the format of the result as
+ returned by 'gcry_pk_encrypt', but should be enlarged with a
+ 'flags' element:
+
+ (enc-val
+ (flags)
+ (elg
+ (a A-MPI)
+ (b B-MPI)))
+
+ This function does not remove padding from the data by default. To
+ let Libgcrypt remove padding, give a hint in 'flags' telling which
+ padding method was used when encrypting:
+
+ (flags PADDING-METHOD)
+
+ Currently PADDING-METHOD is either 'pkcs1' for PKCS#1 block type 2
+ padding, or 'oaep' for RSA-OAEP padding.
+
+ The function returns 0 on success or an error code. The variable
+ at the address of R_PLAIN will be set to NULL on error or receive
+ the decrypted value on success. The format of R_PLAIN is a simple
+ S-expression part (i.e. not a valid one) with just one MPI if
+ there was no 'flags' element in DATA; if at least an empty 'flags'
+ is passed in DATA, the format is:
+
+ (value PLAINTEXT)
+
+ Another operation commonly performed using public key cryptography is
+signing data. In some sense this is even more important than encryption
+because digital signatures are an important instrument for key
+management. Libgcrypt supports digital signatures using 2 functions,
+similar to the encryption functions:
+
+ -- Function: gcry_error_t gcry_pk_sign (gcry_sexp_t *R_SIG,
+ gcry_sexp_t DATA, gcry_sexp_t SKEY)
+
+ This function creates a digital signature for DATA using the
+ private key SKEY and place it into the variable at the address of
+ R_SIG. DATA may either be the simple old style S-expression with
+ just one MPI or a modern and more versatile S-expression which
+ allows to let Libgcrypt handle padding:
+
+ (data
+ (flags pkcs1)
+ (hash HASH-ALGO BLOCK))
+
+ This example requests to sign the data in BLOCK after applying
+ PKCS#1 block type 1 style padding. HASH-ALGO is a string with the
+ hash algorithm to be encoded into the signature, this may be any
+ hash algorithm name as supported by Libgcrypt. Most likely, this
+ will be "sha256" or "sha1". It is obvious that the length of BLOCK
+ must match the size of that message digests; the function checks
+ that this and other constraints are valid.
+
+ If PKCS#1 padding is not required (because the caller does already
+ provide a padded value), either the old format or better the
+ following format should be used:
+
+ (data
+ (flags raw)
+ (value MPI))
+
+ Here, the data to be signed is directly given as an MPI.
+
+ For DSA the input data is expected in this format:
+
+ (data
+ (flags raw)
+ (value MPI))
+
+ Here, the data to be signed is directly given as an MPI. It is
+ expect that this MPI is the the hash value. For the standard DSA
+ using a MPI is not a problem in regard to leading zeroes because
+ the hash value is directly used as an MPI. For better standard
+ conformance it would be better to explicit use a memory string
+ (like with pkcs1) but that is currently not supported. However,
+ for deterministic DSA as specified in RFC6979 this can't be used.
+ Instead the following input is expected.
+
+ (data
+ (flags rfc6979)
+ (hash HASH-ALGO BLOCK))
+
+ Note that the provided hash-algo is used for the internal HMAC; it
+ should match the hash-algo used to create BLOCK.
+
+ The signature is returned as a newly allocated S-expression in
+ R_SIG using this format for RSA:
+
+ (sig-val
+ (rsa
+ (s S-MPI)))
+
+ Where S-MPI is the result of the RSA sign operation. For DSA the
+ S-expression returned is:
+
+ (sig-val
+ (dsa
+ (r R-MPI)
+ (s S-MPI)))
+
+ Where R-MPI and S-MPI are the result of the DSA sign operation.
+
+ For Elgamal signing (which is slow, yields large numbers and
+ probably is not as secure as the other algorithms), the same format
+ is used with "elg" replacing "dsa"; for ECDSA signing, the same
+ format is used with "ecdsa" replacing "dsa".
+
+ For the EdDSA algorithm (cf. Ed25515) the required input
+ parameters are:
+
+ (data
+ (flags eddsa)
+ (hash-algo sha512)
+ (value MESSAGE))
+
+ Note that the MESSAGE may be of any length; hashing is part of the
+ algorithm. Using a large data block for MESSAGE is in general not
+ suggested; in that case the used protocol should better require
+ that a hash of the message is used as input to the EdDSA algorithm.
+ Note that for X.509 certificates MESSAGE is the 'tbsCertificate'
+ part and in CMS MESSAGE is the 'signedAttrs' part; see RFC-8410 and
+ RFC-8419.
+
+The operation most commonly used is definitely the verification of a
+signature. Libgcrypt provides this function:
+
+ -- Function: gcry_error_t gcry_pk_verify (gcry_sexp_t SIG,
+ gcry_sexp_t DATA, gcry_sexp_t PKEY)
+
+ This is used to check whether the signature SIG matches the DATA.
+ The public key PKEY must be provided to perform this verification.
+ This function is similar in its parameters to 'gcry_pk_sign' with
+ the exceptions that the public key is used instead of the private
+ key and that no signature is created but a signature, in a format
+ as created by 'gcry_pk_sign', is passed to the function in SIG.
+
+ The result is 0 for success (i.e. the data matches the signature),
+ or an error code where the most relevant code is
+ 'GCRY_ERR_BAD_SIGNATURE' to indicate that the signature does not
+ match the provided data.
+
+
+File: gcrypt.info, Node: Dedicated ECC Functions, Next: General public-key related Functions, Prev: Cryptographic Functions, Up: Public Key cryptography
+
+6.4 Dedicated functions for elliptic curves.
+============================================
+
+The S-expression based interface is for certain operations on elliptic
+curves not optimal. Thus a few special functions are implemented to
+support common operations on curves with one of these assigned curve
+ids:
+
+'GCRY_ECC_CURVE25519'
+'GCRY_ECC_CURVE448'
+
+ -- Function: unsigned int gcry_ecc_get_algo_keylen (int CURVEID);
+
+ Returns the length in bytes of a point on the curve with the id
+ CURVEID. 0 is returned for curves which have no assigned id.
+
+ -- Function: gpg_error_t gcry_ecc_mul_point (int CURVEID,
+ unsigned char *RESULT, const unsigned char *SCALAR,
+ const unsigned char *POINT)
+
+ This function computes the scalar multiplication on the Montgomery
+ form of the curve with id CURVEID. If POINT is NULL the base point
+ of the curve is used. The caller needs to provide a large enough
+ buffer for RESULT and a valid SCALAR and POINT.
+
+
+File: gcrypt.info, Node: General public-key related Functions, Prev: Dedicated ECC Functions, Up: Public Key cryptography
+
+6.5 General public-key related Functions
+========================================
+
+A couple of utility functions are available to retrieve the length of
+the key, map algorithm identifiers and perform sanity checks:
+
+ -- Function: const char * gcry_pk_algo_name (int ALGO)
+
+ Map the public key algorithm id ALGO to a string representation of
+ the algorithm name. For unknown algorithms this functions returns
+ the string '"?"'. This function should not be used to test for the
+ availability of an algorithm.
+
+ -- Function: int gcry_pk_map_name (const char *NAME)
+
+ Map the algorithm NAME to a public key algorithm Id. Returns 0 if
+ the algorithm name is not known.
+
+ -- Function: int gcry_pk_test_algo (int ALGO)
+
+ Return 0 if the public key algorithm ALGO is available for use.
+ Note that this is implemented as a macro.
+
+ -- Function: unsigned int gcry_pk_get_nbits (gcry_sexp_t KEY)
+
+ Return what is commonly referred as the key length for the given
+ public or private in KEY.
+
+ -- Function: unsigned char * gcry_pk_get_keygrip (gcry_sexp_t KEY,
+ unsigned char *ARRAY)
+
+ Return the so called "keygrip" which is the SHA-1 hash of the
+ public key parameters expressed in a way depended on the algorithm.
+ ARRAY must either provide space for 20 bytes or be 'NULL'. In the
+ latter case a newly allocated array of that size is returned. On
+ success a pointer to the newly allocated space or to ARRAY is
+ returned. 'NULL' is returned to indicate an error which is most
+ likely an unknown algorithm or one where a "keygrip" has not yet
+ been defined. The function accepts public or secret keys in KEY.
+
+ -- Function: gcry_error_t gcry_pk_testkey (gcry_sexp_t KEY)
+
+ Return zero if the private key KEY is 'sane', an error code
+ otherwise. Note that it is not possible to check the 'saneness' of
+ a public key.
+
+ -- Function: gcry_error_t gcry_pk_algo_info (int ALGO, int WHAT,
+ void *BUFFER, size_t *NBYTES)
+
+ Depending on the value of WHAT return various information about the
+ public key algorithm with the id ALGO. Note that the function
+ returns '-1' on error and the actual error code must be retrieved
+ using the function 'gcry_errno'. The currently defined values for
+ WHAT are:
+
+ 'GCRYCTL_TEST_ALGO:'
+ Return 0 if the specified algorithm is available for use.
+ BUFFER must be 'NULL', NBYTES may be passed as 'NULL' or point
+ to a variable with the required usage of the algorithm. This
+ may be 0 for "don't care" or the bit-wise OR of these flags:
+
+ 'GCRY_PK_USAGE_SIGN'
+ Algorithm is usable for signing.
+ 'GCRY_PK_USAGE_ENCR'
+ Algorithm is usable for encryption.
+
+ Unless you need to test for the allowed usage, it is in
+ general better to use the macro gcry_pk_test_algo instead.
+
+ 'GCRYCTL_GET_ALGO_USAGE:'
+ Return the usage flags for the given algorithm. An invalid
+ algorithm return 0. Disabled algorithms are ignored here
+ because we want to know whether the algorithm is at all
+ capable of a certain usage.
+
+ 'GCRYCTL_GET_ALGO_NPKEY'
+ Return the number of elements the public key for algorithm
+ ALGO consist of. Return 0 for an unknown algorithm.
+
+ 'GCRYCTL_GET_ALGO_NSKEY'
+ Return the number of elements the private key for algorithm
+ ALGO consist of. Note that this value is always larger than
+ that of the public key. Return 0 for an unknown algorithm.
+
+ 'GCRYCTL_GET_ALGO_NSIGN'
+ Return the number of elements a signature created with the
+ algorithm ALGO consists of. Return 0 for an unknown algorithm
+ or for an algorithm not capable of creating signatures.
+
+ 'GCRYCTL_GET_ALGO_NENCR'
+ Return the number of elements a encrypted message created with
+ the algorithm ALGO consists of. Return 0 for an unknown
+ algorithm or for an algorithm not capable of encryption.
+
+ Please note that parameters not required should be passed as
+ 'NULL'.
+
+ -- Function: gcry_error_t gcry_pk_ctl (int CMD, void *BUFFER,
+ size_t BUFLEN)
+
+ This is a general purpose function to perform certain control
+ operations. CMD controls what is to be done. The return value is
+ 0 for success or an error code. Currently supported values for CMD
+ are:
+
+ 'GCRYCTL_DISABLE_ALGO'
+ Disable the algorithm given as an algorithm id in BUFFER.
+ BUFFER must point to an 'int' variable with the algorithm id
+ and BUFLEN must have the value 'sizeof (int)'. This function
+ is not thread safe and should thus be used before any other
+ threads are started.
+
+Libgcrypt also provides a function to generate public key pairs:
+
+ -- Function: gcry_error_t gcry_pk_genkey (gcry_sexp_t *R_KEY,
+ gcry_sexp_t PARMS)
+
+ This function create a new public key pair using information given
+ in the S-expression PARMS and stores the private and the public key
+ in one new S-expression at the address given by R_KEY. In case of
+ an error, R_KEY is set to 'NULL'. The return code is 0 for success
+ or an error code otherwise.
+
+ Here is an example for PARMS to create an 2048 bit RSA key:
+
+ (genkey
+ (rsa
+ (nbits 4:2048)))
+
+ To create an Elgamal key, substitute "elg" for "rsa" and to create
+ a DSA key use "dsa". Valid ranges for the key length depend on the
+ algorithms; all commonly used key lengths are supported. Currently
+ supported parameters are:
+
+ 'nbits'
+ This is always required to specify the length of the key. The
+ argument is a string with a number in C-notation. The value
+ should be a multiple of 8. Note that the S-expression syntax
+ requires that a number is prefixed with its string length;
+ thus the '4:' in the above example.
+
+ 'curve NAME'
+ For ECC a named curve may be used instead of giving the number
+ of requested bits. This allows to request a specific curve to
+ override a default selection Libgcrypt would have taken if
+ 'nbits' has been given. The available names are listed with
+ the description of the ECC public key parameters.
+
+ 'rsa-use-e VALUE'
+ This is only used with RSA to give a hint for the public
+ exponent. The VALUE will be used as a base to test for a
+ usable exponent. Some values are special:
+
+ '0'
+ Use a secure and fast value. This is currently the
+ number 41.
+ '1'
+ Use a value as required by some crypto policies. This is
+ currently the number 65537.
+ '2'
+ Reserved
+ '> 2'
+ Use the given value.
+
+ If this parameter is not used, Libgcrypt uses for historic
+ reasons 65537. Note that the value must fit into a 32 bit
+ unsigned variable and that the usual C prefixes are considered
+ (e.g. 017 gives 15).
+
+ 'qbits N'
+ This is only meanigful for DSA keys. If it is given the DSA
+ key is generated with a Q parameyer of size N bits. If it is
+ not given or zero Q is deduced from NBITS in this way:
+ '512 <= N <= 1024'
+ Q = 160
+ 'N = 2048'
+ Q = 224
+ 'N = 3072'
+ Q = 256
+ 'N = 7680'
+ Q = 384
+ 'N = 15360'
+ Q = 512
+ Note that in this case only the values for N, as given in the
+ table, are allowed. When specifying Q all values of N in the
+ range 512 to 15680 are valid as long as they are multiples of
+ 8.
+
+ 'domain LIST'
+ This is only meaningful for DLP algorithms. If specified keys
+ are generated with domain parameters taken from this list.
+ The exact format of this parameter depends on the actual
+ algorithm. It is currently only implemented for DSA using
+ this format:
+
+ (genkey
+ (dsa
+ (domain
+ (p P-MPI)
+ (q Q-MPI)
+ (g Q-MPI))))
+
+ 'nbits' and 'qbits' may not be specified because they are
+ derived from the domain parameters.
+
+ 'derive-parms LIST'
+ This is currently only implemented for RSA and DSA keys. It
+ is not allowed to use this together with a 'domain'
+ specification. If given, it is used to derive the keys using
+ the given parameters.
+
+ If given for an RSA key the X9.31 key generation algorithm is
+ used even if libgcrypt is not in FIPS mode. If given for a
+ DSA key, the FIPS 186 algorithm is used even if libgcrypt is
+ not in FIPS mode.
+
+ (genkey
+ (rsa
+ (nbits 4:1024)
+ (rsa-use-e 1:3)
+ (derive-parms
+ (Xp1 #1A1916DDB29B4EB7EB6732E128#)
+ (Xp2 #192E8AAC41C576C822D93EA433#)
+ (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D
+ 769D6D76646C7A792E16EBD89FE6FC5B605A6493
+ 39DFC925A86A4C6D150B71B9EEA02D68885F5009
+ B98BD984#)
+ (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
+ (Xq2 #134E4CAA16D2350A21D775C404#)
+ (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
+ 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
+ 321DE34A#))))
+
+ (genkey
+ (dsa
+ (nbits 4:1024)
+ (derive-parms
+ (seed SEED-MPI))))
+
+ 'flags FLAGLIST'
+ This is preferred way to define flags. FLAGLIST may contain
+ any number of flags. See above for a specification of these
+ flags.
+
+ Here is an example on how to create a key using curve Ed25519
+ with the ECDSA signature algorithm. Note that the use of
+ ECDSA with that curve is in general not recommended.
+ (genkey
+ (ecc
+ (flags transient-key)))
+
+ 'transient-key'
+ 'use-x931'
+ 'use-fips186'
+ 'use-fips186-2'
+ These are deprecated ways to set a flag with that name; see
+ above for a description of each flag.
+
+ The key pair is returned in a format depending on the algorithm.
+ Both private and public keys are returned in one container and may
+ be accompanied by some miscellaneous information.
+
+ Here are two examples; the first for Elgamal and the second for
+ elliptic curve key generation:
+
+ (key-data
+ (public-key
+ (elg
+ (p P-MPI)
+ (g G-MPI)
+ (y Y-MPI)))
+ (private-key
+ (elg
+ (p P-MPI)
+ (g G-MPI)
+ (y Y-MPI)
+ (x X-MPI)))
+ (misc-key-info
+ (pm1-factors N1 N2 ... NN))
+
+ (key-data
+ (public-key
+ (ecc
+ (curve Ed25519)
+ (flags eddsa)
+ (q Q-VALUE)))
+ (private-key
+ (ecc
+ (curve Ed25519)
+ (flags eddsa)
+ (q Q-VALUE)
+ (d D-VALUE))))
+
+ As you can see, some of the information is duplicated, but this
+ provides an easy way to extract either the public or the private
+ key. Note that the order of the elements is not defined, e.g. the
+ private key may be stored before the public key. N1 N2 ... NN is a
+ list of prime numbers used to composite P-MPI; this is in general
+ not a very useful information and only available if the key
+ generation algorithm provides them.
+
+Future versions of Libgcrypt will have extended versions of the public
+key interfaced which will take an additional context to allow for
+pre-computations, special operations, and other optimization. As a
+first step a new function is introduced to help using the ECC algorithms
+in new ways:
+
+ -- Function: gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *R_SEXP,
+ int MODE, gcry_ctx_t CTX)
+
+ Return an S-expression representing the context CTX. Depending on
+ the state of that context, the S-expression may either be a public
+ key, a private key or any other object used with public key
+ operations. On success 0 is returned and a new S-expression is
+ stored at R_SEXP; on error an error code is returned and NULL is
+ stored at R_SEXP. MODE must be one of:
+
+ '0'
+ Decide what to return depending on the context. For example
+ if the private key parameter is available a private key is
+ returned, if not a public key is returned.
+
+ 'GCRY_PK_GET_PUBKEY'
+ Return the public key even if the context has the private key
+ parameter.
+
+ 'GCRY_PK_GET_SECKEY'
+ Return the private key or the error 'GPG_ERR_NO_SECKEY' if it
+ is not possible.
+
+ As of now this function supports only certain ECC operations
+ because a context object is right now only defined for ECC. Over
+ time this function will be extended to cover more algorithms.
+
+
+File: gcrypt.info, Node: Hashing, Next: Message Authentication Codes, Prev: Public Key cryptography, Up: Top
+
+7 Hashing
+*********
+
+Libgcrypt provides an easy and consistent to use interface for hashing.
+Hashing is buffered and several hash algorithms can be updated at once.
+It is possible to compute a HMAC using the same routines. The
+programming model follows an open/process/close paradigm and is in that
+similar to other building blocks provided by Libgcrypt.
+
+ For convenience reasons, a few cyclic redundancy check value
+operations are also supported.
+
+* Menu:
+
+* Available hash algorithms:: List of hash algorithms supported by the library.
+* Working with hash algorithms:: List of functions related to hashing.
+
+
+File: gcrypt.info, Node: Available hash algorithms, Next: Working with hash algorithms, Up: Hashing
+
+7.1 Available hash algorithms
+=============================
+
+'GCRY_MD_NONE'
+ This is not a real algorithm but used by some functions as an error
+ return value. This constant is guaranteed to have the value '0'.
+
+'GCRY_MD_SHA1'
+ This is the SHA-1 algorithm which yields a message digest of 20
+ bytes. Note that SHA-1 begins to show some weaknesses and it is
+ suggested to fade out its use if strong cryptographic properties
+ are required.
+
+'GCRY_MD_RMD160'
+ This is the 160 bit version of the RIPE message digest
+ (RIPE-MD-160). Like SHA-1 it also yields a digest of 20 bytes.
+ This algorithm share a lot of design properties with SHA-1 and thus
+ it is advisable not to use it for new protocols.
+
+'GCRY_MD_MD5'
+ This is the well known MD5 algorithm, which yields a message digest
+ of 16 bytes. Note that the MD5 algorithm has severe weaknesses,
+ for example it is easy to compute two messages yielding the same
+ hash (collision attack). The use of this algorithm is only
+ justified for non-cryptographic application.
+
+'GCRY_MD_MD4'
+ This is the MD4 algorithm, which yields a message digest of 16
+ bytes. This algorithm has severe weaknesses and should not be
+ used.
+
+'GCRY_MD_MD2'
+ This is an reserved identifier for MD-2; there is no implementation
+ yet. This algorithm has severe weaknesses and should not be used.
+
+'GCRY_MD_TIGER'
+ This is the TIGER/192 algorithm which yields a message digest of 24
+ bytes. Actually this is a variant of TIGER with a different output
+ print order as used by GnuPG up to version 1.3.2.
+
+'GCRY_MD_TIGER1'
+ This is the TIGER variant as used by the NESSIE project. It uses
+ the most commonly used output print order.
+
+'GCRY_MD_TIGER2'
+ This is another variant of TIGER with a different padding scheme.
+
+'GCRY_MD_HAVAL'
+ This is an reserved value for the HAVAL algorithm with 5 passes and
+ 160 bit. It yields a message digest of 20 bytes. Note that there
+ is no implementation yet available.
+
+'GCRY_MD_SHA224'
+ This is the SHA-224 algorithm which yields a message digest of 28
+ bytes. See Change Notice 1 for FIPS 180-2 for the specification.
+
+'GCRY_MD_SHA256'
+ This is the SHA-256 algorithm which yields a message digest of 32
+ bytes. See FIPS 180-2 for the specification.
+
+'GCRY_MD_SHA384'
+ This is the SHA-384 algorithm which yields a message digest of 48
+ bytes. See FIPS 180-2 for the specification.
+
+'GCRY_MD_SHA512'
+ This is the SHA-512 algorithm which yields a message digest of 64
+ bytes. See FIPS 180-2 for the specification.
+
+'GCRY_MD_SHA512_224'
+ This is the SHA-512/224 algorithm which yields a message digest of
+ 28 bytes. See FIPS 180-4 for the specification.
+
+'GCRY_MD_SHA512_256'
+ This is the SHA-512/256 algorithm which yields a message digest of
+ 32 bytes. See FIPS 180-4 for the specification.
+
+'GCRY_MD_SHA3_224'
+ This is the SHA3-224 algorithm which yields a message digest of 28
+ bytes. See FIPS 202 for the specification.
+
+'GCRY_MD_SHA3_256'
+ This is the SHA3-256 algorithm which yields a message digest of 32
+ bytes. See FIPS 202 for the specification.
+
+'GCRY_MD_SHA3_384'
+ This is the SHA3-384 algorithm which yields a message digest of 48
+ bytes. See FIPS 202 for the specification.
+
+'GCRY_MD_SHA3_512'
+ This is the SHA3-512 algorithm which yields a message digest of 64
+ bytes. See FIPS 202 for the specification.
+
+'GCRY_MD_SHAKE128'
+ This is the SHAKE128 extendable-output function (XOF) algorithm
+ with 128 bit security strength. See FIPS 202 for the
+ specification.
+
+'GCRY_MD_SHAKE256'
+ This is the SHAKE256 extendable-output function (XOF) algorithm
+ with 256 bit security strength. See FIPS 202 for the
+ specification.
+
+'GCRY_MD_CRC32'
+ This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It
+ yields an output of 4 bytes. Note that this is not a hash
+ algorithm in the cryptographic sense.
+
+'GCRY_MD_CRC32_RFC1510'
+ This is the above cyclic redundancy check function, as modified by
+ RFC 1510. It yields an output of 4 bytes. Note that this is not a
+ hash algorithm in the cryptographic sense.
+
+'GCRY_MD_CRC24_RFC2440'
+ This is the OpenPGP cyclic redundancy check function. It yields an
+ output of 3 bytes. Note that this is not a hash algorithm in the
+ cryptographic sense.
+
+'GCRY_MD_WHIRLPOOL'
+ This is the Whirlpool algorithm which yields a message digest of 64
+ bytes.
+
+'GCRY_MD_GOSTR3411_94'
+ This is the hash algorithm described in GOST R 34.11-94 which
+ yields a message digest of 32 bytes.
+
+'GCRY_MD_STRIBOG256'
+ This is the 256-bit version of hash algorithm described in GOST R
+ 34.11-2012 which yields a message digest of 32 bytes.
+
+'GCRY_MD_STRIBOG512'
+ This is the 512-bit version of hash algorithm described in GOST R
+ 34.11-2012 which yields a message digest of 64 bytes.
+
+'GCRY_MD_BLAKE2B_512'
+ This is the BLAKE2b-512 algorithm which yields a message digest of
+ 64 bytes. See RFC 7693 for the specification.
+
+'GCRY_MD_BLAKE2B_384'
+ This is the BLAKE2b-384 algorithm which yields a message digest of
+ 48 bytes. See RFC 7693 for the specification.
+
+'GCRY_MD_BLAKE2B_256'
+ This is the BLAKE2b-256 algorithm which yields a message digest of
+ 32 bytes. See RFC 7693 for the specification.
+
+'GCRY_MD_BLAKE2B_160'
+ This is the BLAKE2b-160 algorithm which yields a message digest of
+ 20 bytes. See RFC 7693 for the specification.
+
+'GCRY_MD_BLAKE2S_256'
+ This is the BLAKE2s-256 algorithm which yields a message digest of
+ 32 bytes. See RFC 7693 for the specification.
+
+'GCRY_MD_BLAKE2S_224'
+ This is the BLAKE2s-224 algorithm which yields a message digest of
+ 28 bytes. See RFC 7693 for the specification.
+
+'GCRY_MD_BLAKE2S_160'
+ This is the BLAKE2s-160 algorithm which yields a message digest of
+ 20 bytes. See RFC 7693 for the specification.
+
+'GCRY_MD_BLAKE2S_128'
+ This is the BLAKE2s-128 algorithm which yields a message digest of
+ 16 bytes. See RFC 7693 for the specification.
+
+'GCRY_MD_SM3'
+ This is the SM3 algorithm which yields a message digest of 32
+ bytes.
+
+
+File: gcrypt.info, Node: Working with hash algorithms, Prev: Available hash algorithms, Up: Hashing
+
+7.2 Working with hash algorithms
+================================
+
+To use most of these function it is necessary to create a context; this
+is done using:
+
+ -- Function: gcry_error_t gcry_md_open (gcry_md_hd_t *HD, int ALGO,
+ unsigned int FLAGS)
+
+ Create a message digest object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of constants described below. ALGO may be
+ given as '0' if the algorithms to use are later set using
+ 'gcry_md_enable'. HD is guaranteed to either receive a valid
+ handle or NULL.
+
+ For a list of supported algorithms, see *note Available hash
+ algorithms::.
+
+ The flags allowed for MODE are:
+
+ 'GCRY_MD_FLAG_SECURE'
+ Allocate all buffers and the resulting digest in "secure
+ memory". Use this is the hashed data is highly confidential.
+
+ 'GCRY_MD_FLAG_HMAC'
+ Turn the algorithm into a HMAC message authentication
+ algorithm. This only works if just one algorithm is enabled
+ for the handle and that algorithm is not an extendable-output
+ function. Note that the function 'gcry_md_setkey' must be
+ used to set the MAC key. The size of the MAC is equal to the
+ message digest of the underlying hash algorithm. If you want
+ CBC message authentication codes based on a cipher, see *note
+ Working with cipher handles::.
+
+ 'GCRY_MD_FLAG_BUGEMU1'
+ Versions of Libgcrypt before 1.6.0 had a bug in the Whirlpool
+ code which led to a wrong result for certain input sizes and
+ write patterns. Using this flag emulates that bug. This may
+ for example be useful for applications which use Whirlpool as
+ part of their key generation. It is strongly suggested to use
+ this flag only if really needed and if possible to the data
+ should be re-processed using the regular Whirlpool algorithm.
+
+ Note that this flag works for the entire hash context. If
+ needed arises it may be used to enable bug emulation for other
+ hash algorithms. Thus you should not use this flag for a
+ multi-algorithm hash context.
+
+ You may use the function 'gcry_md_is_enabled' to later check
+ whether an algorithm has been enabled.
+
+ If you want to calculate several hash algorithms at the same time,
+you have to use the following function right after the 'gcry_md_open':
+
+ -- Function: gcry_error_t gcry_md_enable (gcry_md_hd_t H, int ALGO)
+
+ Add the message digest algorithm ALGO to the digest object
+ described by handle H. Duplicated enabling of algorithms is
+ detected and ignored.
+
+ If the flag 'GCRY_MD_FLAG_HMAC' was used, the key for the MAC must be
+set using the function:
+
+ -- Function: gcry_error_t gcry_md_setkey (gcry_md_hd_t H, const void
+ *KEY, size_t KEYLEN)
+
+ For use with the HMAC feature or BLAKE2 keyed hash, set the MAC key
+ to the value of KEY of length KEYLEN bytes. For HMAC, there is no
+ restriction on the length of the key. For keyed BLAKE2b hash,
+ length of the key must be 64 bytes or less. For keyed BLAKE2s
+ hash, length of the key must be 32 bytes or less.
+
+ After you are done with the hash calculation, you should release the
+resources by using:
+
+ -- Function: void gcry_md_close (gcry_md_hd_t H)
+
+ Release all resources of hash context H. H should not be used
+ after a call to this function. A 'NULL' passed as H is ignored.
+ The function also zeroises all sensitive information associated
+ with this handle.
+
+ Often you have to do several hash operations using the same
+algorithm. To avoid the overhead of creating and releasing context, a
+reset function is provided:
+
+ -- Function: void gcry_md_reset (gcry_md_hd_t H)
+
+ Reset the current context to its initial state. This is
+ effectively identical to a close followed by an open and enabling
+ all currently active algorithms.
+
+ Often it is necessary to start hashing some data and then continue to
+hash different data. To avoid hashing the same data several times
+(which might not even be possible if the data is received from a pipe),
+a snapshot of the current hash context can be taken and turned into a
+new context:
+
+ -- Function: gcry_error_t gcry_md_copy (gcry_md_hd_t *HANDLE_DST,
+ gcry_md_hd_t HANDLE_SRC)
+
+ Create a new digest object as an exact copy of the object described
+ by handle HANDLE_SRC and store it in HANDLE_DST. The context is
+ not reset and you can continue to hash data using this context and
+ independently using the original context.
+
+ Now that we have prepared everything to calculate hashes, it is time
+to see how it is actually done. There are two ways for this, one to
+update the hash with a block of memory and one macro to update the hash
+by just one character. Both methods can be used on the same hash
+context.
+
+ -- Function: void gcry_md_write (gcry_md_hd_t H, const void *BUFFER,
+ size_t LENGTH)
+
+ Pass LENGTH bytes of the data in BUFFER to the digest object with
+ handle H to update the digest values. This function should be used
+ for large blocks of data. If this function is used after the
+ context has been finalized, it will keep on pushing the data
+ through the algorithm specific transform function and change the
+ context; however the results are not meaningful and this feature is
+ only available to mitigate timing attacks.
+
+ -- Function: void gcry_md_putc (gcry_md_hd_t H, int C)
+
+ Pass the byte in C to the digest object with handle H to update the
+ digest value. This is an efficient function, implemented as a
+ macro to buffer the data before an actual update.
+
+ The semantics of the hash functions do not provide for reading out
+intermediate message digests because the calculation must be finalized
+first. This finalization may for example include the number of bytes
+hashed in the message digest or some padding.
+
+ -- Function: void gcry_md_final (gcry_md_hd_t H)
+
+ Finalize the message digest calculation. This is not really needed
+ because 'gcry_md_read' and 'gcry_md_extract' do this implicitly.
+ After this has been done no further updates (by means of
+ 'gcry_md_write' or 'gcry_md_putc' should be done; However, to
+ mitigate timing attacks it is sometimes useful to keep on updating
+ the context after having stored away the actual digest. Only the
+ first call to this function has an effect. It is implemented as a
+ macro.
+
+ The way to read out the calculated message digest is by using the
+function:
+
+ -- Function: unsigned char * gcry_md_read (gcry_md_hd_t H, int ALGO)
+
+ 'gcry_md_read' returns the message digest after finalizing the
+ calculation. This function may be used as often as required but it
+ will always return the same value for one handle. The returned
+ message digest is allocated within the message context and
+ therefore valid until the handle is released or reset-ed (using
+ 'gcry_md_close' or 'gcry_md_reset' or it has been updated as a
+ mitigation measure against timing attacks. ALGO may be given as 0
+ to return the only enabled message digest or it may specify one of
+ the enabled algorithms. The function does return 'NULL' if the
+ requested algorithm has not been enabled.
+
+ The way to read output of extendable-output function is by using the
+function:
+
+ -- Function: gpg_err_code_t gcry_md_extract (gcry_md_hd_t H, int ALGO,
+ void *BUFFER, size_t LENGTH)
+
+ 'gcry_mac_read' returns output from extendable-output function.
+ This function may be used as often as required to generate more
+ output byte stream from the algorithm. Function extracts the new
+ output bytes to BUFFER of the length LENGTH. Buffer will be fully
+ populated with new output. ALGO may be given as 0 to return the
+ only enabled message digest or it may specify one of the enabled
+ algorithms. The function does return non-zero value if the
+ requested algorithm has not been enabled.
+
+ Because it is often necessary to get the message digest of blocks of
+memory, two fast convenience function are available for this task:
+
+ -- Function: gpg_err_code_t gcry_md_hash_buffers ( int ALGO,
+ unsigned int FLAGS, void *DIGEST, const gcry_buffer_t *IOV,
+ int IOVCNT )
+
+ 'gcry_md_hash_buffers' is a shortcut function to calculate a
+ message digest from several buffers. This function does not
+ require a context and immediately returns the message digest of the
+ data described by IOV and IOVCNT. DIGEST must be allocated by the
+ caller, large enough to hold the message digest yielded by the the
+ specified algorithm ALGO. This required size may be obtained by
+ using the function 'gcry_md_get_algo_dlen'.
+
+ IOV is an array of buffer descriptions with IOVCNT items. The
+ caller should zero out the structures in this array and for each
+ array item set the fields '.data' to the address of the data to be
+ hashed, '.len' to number of bytes to be hashed. If .OFF is also
+ set, the data is taken starting at .OFF bytes from the begin of the
+ buffer. The field '.size' is not used.
+
+ The only supported flag value for FLAGS is GCRY_MD_FLAG_HMAC which
+ turns this function into a HMAC function; the first item in IOV is
+ then used as the key.
+
+ On success the function returns 0 and stores the resulting hash or
+ MAC at DIGEST.
+
+ -- Function: void gcry_md_hash_buffer (int ALGO, void *DIGEST, const
+ void *BUFFER, size_t LENGTH);
+
+ 'gcry_md_hash_buffer' is a shortcut function to calculate a message
+ digest of a buffer. This function does not require a context and
+ immediately returns the message digest of the LENGTH bytes at
+ BUFFER. DIGEST must be allocated by the caller, large enough to
+ hold the message digest yielded by the the specified algorithm
+ ALGO. This required size may be obtained by using the function
+ 'gcry_md_get_algo_dlen'.
+
+ Note that in contrast to 'gcry_md_hash_buffers' this function will
+ abort the process if an unavailable algorithm is used.
+
+ Hash algorithms are identified by internal algorithm numbers (see
+'gcry_md_open' for a list). However, in most applications they are used
+by names, so two functions are available to map between string
+representations and hash algorithm identifiers.
+
+ -- Function: const char * gcry_md_algo_name (int ALGO)
+
+ Map the digest algorithm id ALGO to a string representation of the
+ algorithm name. For unknown algorithms this function returns the
+ string '"?"'. This function should not be used to test for the
+ availability of an algorithm.
+
+ -- Function: int gcry_md_map_name (const char *NAME)
+
+ Map the algorithm with NAME to a digest algorithm identifier.
+ Returns 0 if the algorithm name is not known. Names representing
+ ASN.1 object identifiers are recognized if the IETF dotted format
+ is used and the OID is prefixed with either "'oid.'" or "'OID.'".
+ For a list of supported OIDs, see the source code at 'cipher/md.c'.
+ This function should not be used to test for the availability of an
+ algorithm.
+
+ -- Function: gcry_error_t gcry_md_get_asnoid (int ALGO, void *BUFFER,
+ size_t *LENGTH)
+
+ Return an DER encoded ASN.1 OID for the algorithm ALGO in the user
+ allocated BUFFER. LENGTH must point to variable with the available
+ size of BUFFER and receives after return the actual size of the
+ returned OID. The returned error code may be 'GPG_ERR_TOO_SHORT' if
+ the provided buffer is to short to receive the OID; it is possible
+ to call the function with 'NULL' for BUFFER to have it only return
+ the required size. The function returns 0 on success.
+
+ To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+ -- Function: gcry_error_t gcry_md_test_algo (int ALGO)
+
+ The macro returns 0 if the algorithm ALGO is available for use.
+
+ If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+ -- Function: unsigned int gcry_md_get_algo_dlen (int ALGO)
+
+ Retrieve the length in bytes of the digest yielded by algorithm
+ ALGO. This is often used prior to 'gcry_md_read' to allocate
+ sufficient memory for the digest.
+
+ In some situations it might be hard to remember the algorithm used
+for the ongoing hashing. The following function might be used to get
+that information:
+
+ -- Function: int gcry_md_get_algo (gcry_md_hd_t H)
+
+ Retrieve the algorithm used with the handle H. Note that this does
+ not work reliable if more than one algorithm is enabled in H.
+
+ The following macro might also be useful:
+
+ -- Function: int gcry_md_is_secure (gcry_md_hd_t H)
+
+ This function returns true when the digest object H is allocated in
+ "secure memory"; i.e. H was created with the
+ 'GCRY_MD_FLAG_SECURE'.
+
+ -- Function: int gcry_md_is_enabled (gcry_md_hd_t H, int ALGO)
+
+ This function returns true when the algorithm ALGO has been enabled
+ for the digest object H.
+
+ Tracking bugs related to hashing is often a cumbersome task which
+requires to add a lot of printf statements into the code. Libgcrypt
+provides an easy way to avoid this. The actual data hashed can be
+written to files on request.
+
+ -- Function: void gcry_md_debug (gcry_md_hd_t H, const char *SUFFIX)
+
+ Enable debugging for the digest object with handle H. This creates
+ files named 'dbgmd-<n>.<string>' while doing the actual hashing.
+ SUFFIX is the string part in the filename. The number is a counter
+ incremented for each new hashing. The data in the file is the raw
+ data as passed to 'gcry_md_write' or 'gcry_md_putc'. If 'NULL' is
+ used for SUFFIX, the debugging is stopped and the file closed.
+ This is only rarely required because 'gcry_md_close' implicitly
+ stops debugging.
+
+
+File: gcrypt.info, Node: Message Authentication Codes, Next: Key Derivation, Prev: Hashing, Up: Top
+
+8 Message Authentication Codes
+******************************
+
+Libgcrypt provides an easy and consistent to use interface for
+generating Message Authentication Codes (MAC). MAC generation is
+buffered and interface similar to the one used with hash algorithms.
+The programming model follows an open/process/close paradigm and is in
+that similar to other building blocks provided by Libgcrypt.
+
+* Menu:
+
+* Available MAC algorithms:: List of MAC algorithms supported by the library.
+* Working with MAC algorithms:: List of functions related to MAC algorithms.
+
+
+File: gcrypt.info, Node: Available MAC algorithms, Next: Working with MAC algorithms, Up: Message Authentication Codes
+
+8.1 Available MAC algorithms
+============================
+
+'GCRY_MAC_NONE'
+ This is not a real algorithm but used by some functions as an error
+ return value. This constant is guaranteed to have the value '0'.
+
+'GCRY_MAC_HMAC_SHA256'
+ This is keyed-hash message authentication code (HMAC) message
+ authentication algorithm based on the SHA-256 hash algorithm.
+
+'GCRY_MAC_HMAC_SHA224'
+ This is HMAC message authentication algorithm based on the SHA-224
+ hash algorithm.
+
+'GCRY_MAC_HMAC_SHA512'
+ This is HMAC message authentication algorithm based on the SHA-512
+ hash algorithm.
+
+'GCRY_MAC_HMAC_SHA384'
+ This is HMAC message authentication algorithm based on the SHA-384
+ hash algorithm.
+
+'GCRY_MAC_HMAC_SHA3_256'
+ This is HMAC message authentication algorithm based on the SHA3-256
+ hash algorithm.
+
+'GCRY_MAC_HMAC_SHA3_224'
+ This is HMAC message authentication algorithm based on the SHA3-224
+ hash algorithm.
+
+'GCRY_MAC_HMAC_SHA3_512'
+ This is HMAC message authentication algorithm based on the SHA3-512
+ hash algorithm.
+
+'GCRY_MAC_HMAC_SHA3_384'
+ This is HMAC message authentication algorithm based on the SHA3-384
+ hash algorithm.
+
+'GCRY_MAC_HMAC_SHA512_224'
+ This is HMAC message authentication algorithm based on the
+ SHA-512/224 hash algorithm.
+
+'GCRY_MAC_HMAC_SHA512_256'
+ This is HMAC message authentication algorithm based on the
+ SHA-512/256 hash algorithm.
+
+'GCRY_MAC_HMAC_SHA1'
+ This is HMAC message authentication algorithm based on the SHA-1
+ hash algorithm.
+
+'GCRY_MAC_HMAC_MD5'
+ This is HMAC message authentication algorithm based on the MD5 hash
+ algorithm.
+
+'GCRY_MAC_HMAC_MD4'
+ This is HMAC message authentication algorithm based on the MD4 hash
+ algorithm.
+
+'GCRY_MAC_HMAC_RMD160'
+ This is HMAC message authentication algorithm based on the
+ RIPE-MD-160 hash algorithm.
+
+'GCRY_MAC_HMAC_WHIRLPOOL'
+ This is HMAC message authentication algorithm based on the
+ WHIRLPOOL hash algorithm.
+
+'GCRY_MAC_HMAC_GOSTR3411_94'
+ This is HMAC message authentication algorithm based on the GOST R
+ 34.11-94 hash algorithm.
+
+'GCRY_MAC_HMAC_STRIBOG256'
+ This is HMAC message authentication algorithm based on the 256-bit
+ hash algorithm described in GOST R 34.11-2012.
+
+'GCRY_MAC_HMAC_STRIBOG512'
+ This is HMAC message authentication algorithm based on the 512-bit
+ hash algorithm described in GOST R 34.11-2012.
+
+'GCRY_MAC_HMAC_BLAKE2B_512'
+ This is HMAC message authentication algorithm based on the
+ BLAKE2b-512 hash algorithm.
+
+'GCRY_MAC_HMAC_BLAKE2B_384'
+ This is HMAC message authentication algorithm based on the
+ BLAKE2b-384 hash algorithm.
+
+'GCRY_MAC_HMAC_BLAKE2B_256'
+ This is HMAC message authentication algorithm based on the
+ BLAKE2b-256 hash algorithm.
+
+'GCRY_MAC_HMAC_BLAKE2B_160'
+ This is HMAC message authentication algorithm based on the
+ BLAKE2b-160 hash algorithm.
+
+'GCRY_MAC_HMAC_BLAKE2S_256'
+ This is HMAC message authentication algorithm based on the
+ BLAKE2s-256 hash algorithm.
+
+'GCRY_MAC_HMAC_BLAKE2S_224'
+ This is HMAC message authentication algorithm based on the
+ BLAKE2s-224 hash algorithm.
+
+'GCRY_MAC_HMAC_BLAKE2S_160'
+ This is HMAC message authentication algorithm based on the
+ BLAKE2s-160 hash algorithm.
+
+'GCRY_MAC_HMAC_BLAKE2S_128'
+ This is HMAC message authentication algorithm based on the
+ BLAKE2s-128 hash algorithm.
+
+'GCRY_MAC_HMAC_SM3'
+ This is HMAC message authentication algorithm based on the SM3 hash
+ algorithm.
+
+'GCRY_MAC_CMAC_AES'
+ This is CMAC (Cipher-based MAC) message authentication algorithm
+ based on the AES block cipher algorithm.
+
+'GCRY_MAC_CMAC_3DES'
+ This is CMAC message authentication algorithm based on the
+ three-key EDE Triple-DES block cipher algorithm.
+
+'GCRY_MAC_CMAC_CAMELLIA'
+ This is CMAC message authentication algorithm based on the Camellia
+ block cipher algorithm.
+
+'GCRY_MAC_CMAC_CAST5'
+ This is CMAC message authentication algorithm based on the
+ CAST128-5 block cipher algorithm.
+
+'GCRY_MAC_CMAC_BLOWFISH'
+ This is CMAC message authentication algorithm based on the Blowfish
+ block cipher algorithm.
+
+'GCRY_MAC_CMAC_TWOFISH'
+ This is CMAC message authentication algorithm based on the Twofish
+ block cipher algorithm.
+
+'GCRY_MAC_CMAC_SERPENT'
+ This is CMAC message authentication algorithm based on the Serpent
+ block cipher algorithm.
+
+'GCRY_MAC_CMAC_SEED'
+ This is CMAC message authentication algorithm based on the SEED
+ block cipher algorithm.
+
+'GCRY_MAC_CMAC_RFC2268'
+ This is CMAC message authentication algorithm based on the Ron's
+ Cipher 2 block cipher algorithm.
+
+'GCRY_MAC_CMAC_IDEA'
+ This is CMAC message authentication algorithm based on the IDEA
+ block cipher algorithm.
+
+'GCRY_MAC_CMAC_GOST28147'
+ This is CMAC message authentication algorithm based on the GOST
+ 28147-89 block cipher algorithm.
+
+'GCRY_MAC_CMAC_SM4'
+ This is CMAC message authentication algorithm based on the SM4
+ block cipher algorithm.
+
+'GCRY_MAC_GMAC_AES'
+ This is GMAC (GCM mode based MAC) message authentication algorithm
+ based on the AES block cipher algorithm.
+
+'GCRY_MAC_GMAC_CAMELLIA'
+ This is GMAC message authentication algorithm based on the Camellia
+ block cipher algorithm.
+
+'GCRY_MAC_GMAC_TWOFISH'
+ This is GMAC message authentication algorithm based on the Twofish
+ block cipher algorithm.
+
+'GCRY_MAC_GMAC_SERPENT'
+ This is GMAC message authentication algorithm based on the Serpent
+ block cipher algorithm.
+
+'GCRY_MAC_GMAC_SEED'
+ This is GMAC message authentication algorithm based on the SEED
+ block cipher algorithm.
+
+'GCRY_MAC_POLY1305'
+ This is plain Poly1305 message authentication algorithm, used with
+ one-time key.
+
+'GCRY_MAC_POLY1305_AES'
+ This is Poly1305-AES message authentication algorithm, used with
+ key and one-time nonce.
+
+'GCRY_MAC_POLY1305_CAMELLIA'
+ This is Poly1305-Camellia message authentication algorithm, used
+ with key and one-time nonce.
+
+'GCRY_MAC_POLY1305_TWOFISH'
+ This is Poly1305-Twofish message authentication algorithm, used
+ with key and one-time nonce.
+
+'GCRY_MAC_POLY1305_SERPENT'
+ This is Poly1305-Serpent message authentication algorithm, used
+ with key and one-time nonce.
+
+'GCRY_MAC_POLY1305_SEED'
+ This is Poly1305-SEED message authentication algorithm, used with
+ key and one-time nonce.
+
+'GCRY_MAC_GOST28147_IMIT'
+ This is MAC construction defined in GOST 28147-89 (see RFC 5830
+ Section 8).
+
+
+File: gcrypt.info, Node: Working with MAC algorithms, Prev: Available MAC algorithms, Up: Message Authentication Codes
+
+8.2 Working with MAC algorithms
+===============================
+
+To use most of these function it is necessary to create a context; this
+is done using:
+
+ -- Function: gcry_error_t gcry_mac_open (gcry_mac_hd_t *HD, int ALGO,
+ unsigned int FLAGS, gcry_ctx_t CTX)
+
+ Create a MAC object for algorithm ALGO. FLAGS may be given as an
+ bitwise OR of constants described below. HD is guaranteed to
+ either receive a valid handle or NULL. CTX is context object to
+ associate MAC object with. CTX maybe set to NULL.
+
+ For a list of supported algorithms, see *note Available MAC
+ algorithms::.
+
+ The flags allowed for MODE are:
+
+ 'GCRY_MAC_FLAG_SECURE'
+ Allocate all buffers and the resulting MAC in "secure memory".
+ Use this if the MAC data is highly confidential.
+
+ In order to use a handle for performing MAC algorithm operations, a
+'key' has to be set first:
+
+ -- Function: gcry_error_t gcry_mac_setkey (gcry_mac_hd_t H, const void
+ *KEY, size_t KEYLEN)
+
+ Set the MAC key to the value of KEY of length KEYLEN bytes. With
+ HMAC algorithms, there is no restriction on the length of the key.
+ With CMAC algorithms, the length of the key is restricted to those
+ supported by the underlying block cipher.
+
+ GMAC algorithms and Poly1305-with-cipher algorithms need
+initialization vector to be set, which can be performed with function:
+
+ -- Function: gcry_error_t gcry_mac_setiv (gcry_mac_hd_t H, const void
+ *IV, size_t IVLEN)
+
+ Set the IV to the value of IV of length IVLEN bytes.
+
+ After you are done with the MAC calculation, you should release the
+resources by using:
+
+ -- Function: void gcry_mac_close (gcry_mac_hd_t H)
+
+ Release all resources of MAC context H. H should not be used after
+ a call to this function. A 'NULL' passed as H is ignored. The
+ function also clears all sensitive information associated with this
+ handle.
+
+ Often you have to do several MAC operations using the same algorithm.
+To avoid the overhead of creating and releasing context, a reset
+function is provided:
+
+ -- Function: gcry_error_t gcry_mac_reset (gcry_mac_hd_t H)
+
+ Reset the current context to its initial state. This is
+ effectively identical to a close followed by an open and setting
+ same key.
+
+ Note that gcry_mac_reset is implemented as a macro.
+
+ Now that we have prepared everything to calculate MAC, it is time to
+see how it is actually done.
+
+ -- Function: gcry_error_t gcry_mac_write (gcry_mac_hd_t H, const void
+ *BUFFER, size_t LENGTH)
+
+ Pass LENGTH bytes of the data in BUFFER to the MAC object with
+ handle H to update the MAC values. If this function is used after
+ the context has been finalized, it will keep on pushing the data
+ through the algorithm specific transform function and thereby
+ change the context; however the results are not meaningful and this
+ feature is only available to mitigate timing attacks.
+
+ The way to read out the calculated MAC is by using the function:
+
+ -- Function: gcry_error_t gcry_mac_read (gcry_mac_hd_t H, void *BUFFER,
+ size_t *LENGTH)
+
+ 'gcry_mac_read' returns the MAC after finalizing the calculation.
+ Function copies the resulting MAC value to BUFFER of the length
+ LENGTH. If LENGTH is larger than length of resulting MAC value,
+ then length of MAC is returned through LENGTH.
+
+ To compare existing MAC value with recalculated MAC, one is to use
+the function:
+
+ -- Function: gcry_error_t gcry_mac_verify (gcry_mac_hd_t H, void
+ *BUFFER, size_t LENGTH)
+
+ 'gcry_mac_verify' finalizes MAC calculation and compares result
+ with LENGTH bytes of data in BUFFER. Error code 'GPG_ERR_CHECKSUM'
+ is returned if the MAC value in the buffer BUFFER does not match
+ the MAC calculated in object H.
+
+ In some situations it might be hard to remember the algorithm used
+for the MAC calculation. The following function might be used to get
+that information:
+
+ -- Function: int gcry_mac_get_algo (gcry_mac_hd_t H)
+
+ Retrieve the algorithm used with the handle H.
+
+ MAC algorithms are identified by internal algorithm numbers (see
+'gcry_mac_open' for a list). However, in most applications they are
+used by names, so two functions are available to map between string
+representations and MAC algorithm identifiers.
+
+ -- Function: const char * gcry_mac_algo_name (int ALGO)
+
+ Map the MAC algorithm id ALGO to a string representation of the
+ algorithm name. For unknown algorithms this function returns the
+ string '"?"'. This function should not be used to test for the
+ availability of an algorithm.
+
+ -- Function: int gcry_mac_map_name (const char *NAME)
+
+ Map the algorithm with NAME to a MAC algorithm identifier. Returns
+ 0 if the algorithm name is not known. This function should not be
+ used to test for the availability of an algorithm.
+
+ To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+ -- Function: gcry_error_t gcry_mac_test_algo (int ALGO)
+
+ The macro returns 0 if the MAC algorithm ALGO is available for use.
+
+ If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+ -- Function: unsigned int gcry_mac_get_algo_maclen (int ALGO)
+
+ Retrieve the length in bytes of the MAC yielded by algorithm ALGO.
+ This is often used prior to 'gcry_mac_read' to allocate sufficient
+ memory for the MAC value. On error '0' is returned.
+
+ -- Function: unsigned int gcry_mac_get_algo_keylen (ALGO)
+
+ This function returns length of the key for MAC algorithm ALGO. If
+ the algorithm supports multiple key lengths, the default supported
+ key length is returned. On error '0' is returned. The key length
+ is returned as number of octets.
+
+
+File: gcrypt.info, Node: Key Derivation, Next: Random Numbers, Prev: Message Authentication Codes, Up: Top
+
+9 Key Derivation
+****************
+
+Libgcypt provides a general purpose function to derive keys from
+strings.
+
+ -- Function: gpg_error_t gcry_kdf_derive ( const void *PASSPHRASE,
+ size_t PASSPHRASELEN, int ALGO, int SUBALGO, const void *SALT,
+ size_t SALTLEN, unsigned long ITERATIONS, size_t KEYSIZE,
+ void *KEYBUFFER )
+
+ Derive a key from a passphrase. KEYSIZE gives the requested size
+ of the keys in octets. KEYBUFFER is a caller provided buffer
+ filled on success with the derived key. The input passphrase is
+ taken from PASSPHRASE which is an arbitrary memory buffer of
+ PASSPHRASELEN octets. ALGO specifies the KDF algorithm to use; see
+ below. SUBALGO specifies an algorithm used internally by the KDF
+ algorithms; this is usually a hash algorithm but certain KDF
+ algorithms may use it differently. SALT is a salt of length
+ SALTLEN octets, as needed by most KDF algorithms. ITERATIONS is a
+ positive integer parameter to most KDFs.
+
+ On success 0 is returned; on failure an error code.
+
+ Currently supported KDFs (parameter ALGO):
+
+ 'GCRY_KDF_SIMPLE_S2K'
+ The OpenPGP simple S2K algorithm (cf. RFC4880). Its use is
+ strongly deprecated. SALT and ITERATIONS are not needed and
+ may be passed as 'NULL'/'0'.
+
+ 'GCRY_KDF_SALTED_S2K'
+ The OpenPGP salted S2K algorithm (cf. RFC4880). Usually not
+ used. ITERATIONS is not needed and may be passed as '0'.
+ SALTLEN must be given as 8.
+
+ 'GCRY_KDF_ITERSALTED_S2K'
+ The OpenPGP iterated+salted S2K algorithm (cf. RFC4880).
+ This is the default for most OpenPGP applications. SALTLEN
+ must be given as 8. Note that OpenPGP defines a special
+ encoding of the ITERATIONS; however this function takes the
+ plain decoded iteration count.
+
+ 'GCRY_KDF_PBKDF2'
+ The PKCS#5 Passphrase Based Key Derivation Function number 2.
+
+ 'GCRY_KDF_SCRYPT'
+ The SCRYPT Key Derivation Function. The subalgorithm is used
+ to specify the CPU/memory cost parameter N, and the number of
+ iterations is used for the parallelization parameter p. The
+ block size is fixed at 8 in the current implementation.
+
+
+File: gcrypt.info, Node: Random Numbers, Next: S-expressions, Prev: Key Derivation, Up: Top
+
+10 Random Numbers
+*****************
+
+* Menu:
+
+* Quality of random numbers:: Libgcrypt uses different quality levels.
+* Retrieving random numbers:: How to retrieve random numbers.
+
+
+File: gcrypt.info, Node: Quality of random numbers, Next: Retrieving random numbers, Up: Random Numbers
+
+10.1 Quality of random numbers
+==============================
+
+Libgcypt offers random numbers of different quality levels:
+
+ -- Data type: gcry_random_level_t
+ The constants for the random quality levels are of this enum type.
+
+'GCRY_WEAK_RANDOM'
+ For all functions, except for 'gcry_mpi_randomize', this level maps
+ to GCRY_STRONG_RANDOM. If you do not want this, consider using
+ 'gcry_create_nonce'.
+'GCRY_STRONG_RANDOM'
+ Use this level for session keys and similar purposes.
+'GCRY_VERY_STRONG_RANDOM'
+ Use this level for long term key material.
+
+
+File: gcrypt.info, Node: Retrieving random numbers, Prev: Quality of random numbers, Up: Random Numbers
+
+10.2 Retrieving random numbers
+==============================
+
+ -- Function: void gcry_randomize (unsigned char *BUFFER, size_t LENGTH,
+ enum gcry_random_level LEVEL)
+
+ Fill BUFFER with LENGTH random bytes using a random quality as
+ defined by LEVEL.
+
+ -- Function: void * gcry_random_bytes (size_t NBYTES, enum
+ gcry_random_level LEVEL)
+
+ Convenience function to allocate a memory block consisting of
+ NBYTES fresh random bytes using a random quality as defined by
+ LEVEL.
+
+ -- Function: void * gcry_random_bytes_secure (size_t NBYTES, enum
+ gcry_random_level LEVEL)
+
+ Convenience function to allocate a memory block consisting of
+ NBYTES fresh random bytes using a random quality as defined by
+ LEVEL. This function differs from 'gcry_random_bytes' in that the
+ returned buffer is allocated in a "secure" area of the memory.
+
+ -- Function: void gcry_create_nonce (unsigned char *BUFFER, size_t
+ LENGTH)
+
+ Fill BUFFER with LENGTH unpredictable bytes. This is commonly
+ called a nonce and may also be used for initialization vectors and
+ padding. This is an extra function nearly independent of the other
+ random function for 3 reasons: It better protects the regular
+ random generator's internal state, provides better performance and
+ does not drain the precious entropy pool.
+
+
+File: gcrypt.info, Node: S-expressions, Next: MPI library, Prev: Random Numbers, Up: Top
+
+11 S-expressions
+****************
+
+S-expressions are used by the public key functions to pass complex data
+structures around. These LISP like objects are used by some
+cryptographic protocols (cf. RFC-2692) and Libgcrypt provides functions
+to parse and construct them. For detailed information, see 'Ron Rivest,
+code and description of S-expressions,
+<http://theory.lcs.mit.edu/~rivest/sexp.html>'.
+
+* Menu:
+
+* Data types for S-expressions:: Data types related with S-expressions.
+* Working with S-expressions:: How to work with S-expressions.
+
+
+File: gcrypt.info, Node: Data types for S-expressions, Next: Working with S-expressions, Up: S-expressions
+
+11.1 Data types for S-expressions
+=================================
+
+ -- Data type: gcry_sexp_t
+ The 'gcry_sexp_t' type describes an object with the Libgcrypt
+ internal representation of an S-expression.
+
+
+File: gcrypt.info, Node: Working with S-expressions, Prev: Data types for S-expressions, Up: S-expressions
+
+11.2 Working with S-expressions
+===============================
+
+There are several functions to create an Libgcrypt S-expression object
+from its external representation or from a string template. There is
+also a function to convert the internal representation back into one of
+the external formats:
+
+ -- Function: gcry_error_t gcry_sexp_new (gcry_sexp_t *R_SEXP,
+ const void *BUFFER, size_t LENGTH, int AUTODETECT)
+
+ This is the generic function to create an new S-expression object
+ from its external representation in BUFFER of LENGTH bytes. On
+ success the result is stored at the address given by R_SEXP. With
+ AUTODETECT set to 0, the data in BUFFER is expected to be in
+ canonized format, with AUTODETECT set to 1 the parses any of the
+ defined external formats. If BUFFER does not hold a valid
+ S-expression an error code is returned and R_SEXP set to 'NULL'.
+ Note that the caller is responsible for releasing the newly
+ allocated S-expression using 'gcry_sexp_release'.
+
+ -- Function: gcry_error_t gcry_sexp_create (gcry_sexp_t *R_SEXP,
+ void *BUFFER, size_t LENGTH, int AUTODETECT,
+ void (*FREEFNC)(void*))
+
+ This function is identical to 'gcry_sexp_new' but has an extra
+ argument FREEFNC, which, when not set to 'NULL', is expected to be
+ a function to release the BUFFER; most likely the standard 'free'
+ function is used for this argument. This has the effect of
+ transferring the ownership of BUFFER to the created object in
+ R_SEXP. The advantage of using this function is that Libgcrypt
+ might decide to directly use the provided buffer and thus avoid
+ extra copying.
+
+ -- Function: gcry_error_t gcry_sexp_sscan (gcry_sexp_t *R_SEXP,
+ size_t *ERROFF, const char *BUFFER, size_t LENGTH)
+
+ This is another variant of the above functions. It behaves nearly
+ identical but provides an ERROFF argument which will receive the
+ offset into the buffer where the parsing stopped on error.
+
+ -- Function: gcry_error_t gcry_sexp_build (gcry_sexp_t *R_SEXP,
+ size_t *ERROFF, const char *FORMAT, ...)
+
+ This function creates an internal S-expression from the string
+ template FORMAT and stores it at the address of R_SEXP. If there
+ is a parsing error, the function returns an appropriate error code
+ and stores the offset into FORMAT where the parsing stopped in
+ ERROFF. The function supports a couple of printf-like formatting
+ characters and expects arguments for some of these escape sequences
+ right after FORMAT. The following format characters are defined:
+
+ '%m'
+ The next argument is expected to be of type 'gcry_mpi_t' and a
+ copy of its value is inserted into the resulting S-expression.
+ The MPI is stored as a signed integer.
+ '%M'
+ The next argument is expected to be of type 'gcry_mpi_t' and a
+ copy of its value is inserted into the resulting S-expression.
+ The MPI is stored as an unsigned integer.
+ '%s'
+ The next argument is expected to be of type 'char *' and that
+ string is inserted into the resulting S-expression.
+ '%d'
+ The next argument is expected to be of type 'int' and its
+ value is inserted into the resulting S-expression.
+ '%u'
+ The next argument is expected to be of type 'unsigned int' and
+ its value is inserted into the resulting S-expression.
+ '%b'
+ The next argument is expected to be of type 'int' directly
+ followed by an argument of type 'char *'. This represents a
+ buffer of given length to be inserted into the resulting
+ S-expression.
+ '%S'
+ The next argument is expected to be of type 'gcry_sexp_t' and
+ a copy of that S-expression is embedded in the resulting
+ S-expression. The argument needs to be a regular
+ S-expression, starting with a parenthesis.
+
+ No other format characters are defined and would return an error.
+ Note that the format character '%%' does not exists, because a
+ percent sign is not a valid character in an S-expression.
+
+ -- Function: void gcry_sexp_release (gcry_sexp_t SEXP)
+
+ Release the S-expression object SEXP. If the S-expression is
+ stored in secure memory it explicitly zeroises that memory; note
+ that this is done in addition to the zeroisation always done when
+ freeing secure memory.
+
+The next 2 functions are used to convert the internal representation
+back into a regular external S-expression format and to show the
+structure for debugging.
+
+ -- Function: size_t gcry_sexp_sprint (gcry_sexp_t SEXP, int MODE,
+ char *BUFFER, size_t MAXLENGTH)
+
+ Copies the S-expression object SEXP into BUFFER using the format
+ specified in MODE. MAXLENGTH must be set to the allocated length
+ of BUFFER. The function returns the actual length of valid bytes
+ put into BUFFER or 0 if the provided buffer is too short. Passing
+ 'NULL' for BUFFER returns the required length for BUFFER. For
+ convenience reasons an extra byte with value 0 is appended to the
+ buffer.
+
+ The following formats are supported:
+
+ 'GCRYSEXP_FMT_DEFAULT'
+ Returns a convenient external S-expression representation.
+
+ 'GCRYSEXP_FMT_CANON'
+ Return the S-expression in canonical format.
+
+ 'GCRYSEXP_FMT_BASE64'
+ Not currently supported.
+
+ 'GCRYSEXP_FMT_ADVANCED'
+ Returns the S-expression in advanced format.
+
+ -- Function: void gcry_sexp_dump (gcry_sexp_t SEXP)
+
+ Dumps SEXP in a format suitable for debugging to Libgcrypt's
+ logging stream.
+
+Often canonical encoding is used in the external representation. The
+following function can be used to check for valid encoding and to learn
+the length of the S-expression.
+
+ -- Function: size_t gcry_sexp_canon_len (const unsigned char *BUFFER,
+ size_t LENGTH, size_t *ERROFF, int *ERRCODE)
+
+ Scan the canonical encoded BUFFER with implicit length values and
+ return the actual length this S-expression uses. For a valid
+ S-expression it should never return 0. If LENGTH is not 0, the
+ maximum length to scan is given; this can be used for syntax checks
+ of data passed from outside. ERRCODE and ERROFF may both be passed
+ as 'NULL'.
+
+There are functions to parse S-expressions and retrieve elements:
+
+ -- Function: gcry_sexp_t gcry_sexp_find_token (const gcry_sexp_t LIST,
+ const char *TOKEN, size_t TOKLEN)
+
+ Scan the S-expression for a sublist with a type (the car of the
+ list) matching the string TOKEN. If TOKLEN is not 0, the token is
+ assumed to be raw memory of this length. The function returns a
+ newly allocated S-expression consisting of the found sublist or
+ 'NULL' when not found.
+
+ -- Function: int gcry_sexp_length (const gcry_sexp_t LIST)
+
+ Return the length of the LIST. For a valid S-expression this
+ should be at least 1.
+
+ -- Function: gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t LIST,
+ int NUMBER)
+
+ Create and return a new S-expression from the element with index
+ NUMBER in LIST. Note that the first element has the index 0. If
+ there is no such element, 'NULL' is returned.
+
+ -- Function: gcry_sexp_t gcry_sexp_car (const gcry_sexp_t LIST)
+
+ Create and return a new S-expression from the first element in
+ LIST; this is called the "type" and should always exist per
+ S-expression specification and in general be a string. 'NULL' is
+ returned in case of a problem.
+
+ -- Function: gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t LIST)
+
+ Create and return a new list form all elements except for the first
+ one. Note that this function may return an invalid S-expression
+ because it is not guaranteed, that the type exists and is a string.
+ However, for parsing a complex S-expression it might be useful for
+ intermediate lists. Returns 'NULL' on error.
+
+ -- Function: const char * gcry_sexp_nth_data (const gcry_sexp_t LIST,
+ int NUMBER, size_t *DATALEN)
+
+ This function is used to get data from a LIST. A pointer to the
+ actual data with index NUMBER is returned and the length of this
+ data will be stored to DATALEN. If there is no data at the given
+ index or the index represents another list, 'NULL' is returned.
+ *Caution:* The returned pointer is valid as long as LIST is not
+ modified or released.
+
+ Here is an example on how to extract and print the surname (Meier)
+ from the S-expression '(Name Otto Meier (address Burgplatz 3))':
+
+ size_t len;
+ const char *name;
+
+ name = gcry_sexp_nth_data (list, 2, &len);
+ printf ("my name is %.*s\n", (int)len, name);
+
+ -- Function: void * gcry_sexp_nth_buffer (const gcry_sexp_t LIST,
+ int NUMBER, size_t *RLENGTH)
+
+ This function is used to get data from a LIST. A malloced buffer
+ with the actual data at list index NUMBER is returned and the
+ length of this buffer will be stored to RLENGTH. If there is no
+ data at the given index or the index represents another list,
+ 'NULL' is returned. The caller must release the result using
+ 'gcry_free'.
+
+ Here is an example on how to extract and print the CRC value from
+ the S-expression '(hash crc32 #23ed00d7)':
+
+ size_t len;
+ char *value;
+
+ value = gcry_sexp_nth_buffer (list, 2, &len);
+ if (value)
+ fwrite (value, len, 1, stdout);
+ gcry_free (value);
+
+ -- Function: char * gcry_sexp_nth_string (gcry_sexp_t LIST, int NUMBER)
+
+ This function is used to get and convert data from a LIST. The
+ data is assumed to be a Nul terminated string. The caller must
+ release this returned value using 'gcry_free'. If there is no data
+ at the given index, the index represents a list or the value can't
+ be converted to a string, 'NULL' is returned.
+
+ -- Function: gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t LIST,
+ int NUMBER, int MPIFMT)
+
+ This function is used to get and convert data from a LIST. This
+ data is assumed to be an MPI stored in the format described by
+ MPIFMT and returned as a standard Libgcrypt MPI. The caller must
+ release this returned value using 'gcry_mpi_release'. If there is
+ no data at the given index, the index represents a list or the
+ value can't be converted to an MPI, 'NULL' is returned. If you use
+ this function to parse results of a public key function, you most
+ likely want to use 'GCRYMPI_FMT_USG'.
+
+ -- Function: gpg_error_t gcry_sexp_extract_param ( gcry_sexp_t SEXP,
+ const char *PATH, const char *LIST, ...)
+
+ Extract parameters from an S-expression using a list of parameter
+ names. The names of these parameters are specified in LIST. White
+ space between the parameter names are ignored. Some special
+ characters and character sequences may be given to control the
+ conversion:
+
+ '+'
+ Switch to unsigned integer format (GCRYMPI_FMT_USG). This is
+ the default mode.
+ '-'
+ Switch to standard signed format (GCRYMPI_FMT_STD).
+ '/'
+ Switch to opaque MPI format. The resulting MPIs may not be
+ used for computations; see 'gcry_mpi_get_opaque' for details.
+ '&'
+ Switch to buffer descriptor mode. See below for details.
+ '%s'
+ Switch to string mode. The expected argument is the address
+ of a 'char *' variable; the caller must release that value.
+ If the parameter was marked optional and is not found, NULL is
+ stored.
+ '%#s'
+ Switch to multi string mode. The expected argument is the
+ address of a 'char *' variable; the caller must release that
+ value. If the parameter was marked optional and is not found,
+ NULL is stored. A multi string takes all values, assumes they
+ are strings and concatenates them using a space as delimiter.
+ In case a value is actually another list this is not further
+ parsed but a '()' is inserted in place of that sublist.
+ '%u'
+ Switch to unsigned integer mode. The expected argument is
+ address of a 'unsigned int' variable.
+ '%lu'
+ Switch to unsigned long integer mode. The expected argument
+ is address of a 'unsigned long' variable.
+ '%d'
+ Switch to signed integer mode. The expected argument is
+ address of a 'int' variable.
+ '%ld'
+ Switch to signed long integer mode. The expected argument is
+ address of a 'long' variable.
+ '%zu'
+ Switch to size_t mode. The expected argument is address of a
+ 'size_t' variable.
+ '?'
+ If immediately following a parameter letter (no white space
+ allowed), that parameter is considered optional.
+
+ In general parameter names are single letters. To use a string for
+ a parameter name, enclose the name in single quotes.
+
+ Unless in buffer descriptor mode for each parameter name a pointer
+ to an 'gcry_mpi_t' variable is expected that must be set to 'NULL'
+ prior to invoking this function, and finally a 'NULL' is expected.
+ For example
+
+ gcry_sexp_extract_param (key, NULL, "n/x+e d-'foo'",
+ &mpi_n, &mpi_x, &mpi_e, &mpi_d, &mpi_foo, NULL)
+
+ stores the parameter 'n' from KEY as an unsigned MPI into MPI_N,
+ the parameter 'x' as an opaque MPI into MPI_X, the parameters 'e'
+ and 'd' again as an unsigned MPI into MPI_E and MPI_D and finally
+ the parameter 'foo' as a signed MPI into MPI_FOO.
+
+ PATH is an optional string used to locate a token. The exclamation
+ mark separated tokens are used via 'gcry_sexp_find_token' to find a
+ start point inside the S-expression.
+
+ In buffer descriptor mode a pointer to a 'gcry_buffer_t' descriptor
+ is expected instead of a pointer to an MPI. The caller may use two
+ different operation modes here: If the DATA field of the provided
+ descriptor is 'NULL', the function allocates a new buffer and
+ stores it at DATA; the other fields are set accordingly with OFF
+ set to 0. If DATA is not 'NULL', the function assumes that the
+ DATA, SIZE, and OFF fields specify a buffer where to but the value
+ of the respective parameter; on return the LEN field receives the
+ number of bytes copied to that buffer; in case the buffer is too
+ small, the function immediately returns with an error code (and LEN
+ is set to 0).
+
+ The function returns 0 on success. On error an error code is
+ returned, all passed MPIs that might have been allocated up to this
+ point are deallocated and set to 'NULL', and all passed buffers are
+ either truncated if the caller supplied the buffer, or deallocated
+ if the function allocated the buffer.
+
+
+File: gcrypt.info, Node: MPI library, Next: Prime numbers, Prev: S-expressions, Up: Top
+
+12 MPI library
+**************
+
+* Menu:
+
+* Data types:: MPI related data types.
+* Basic functions:: First steps with MPI numbers.
+* MPI formats:: External representation of MPIs.
+* Calculations:: Performing MPI calculations.
+* Comparisons:: How to compare MPI values.
+* Bit manipulations:: How to access single bits of MPI values.
+* EC functions:: Elliptic curve related functions.
+* Miscellaneous:: Miscellaneous MPI functions.
+
+Public key cryptography is based on mathematics with large numbers. To
+implement the public key functions, a library for handling these large
+numbers is required. Because of the general usefulness of such a
+library, its interface is exposed by Libgcrypt. In the context of
+Libgcrypt and in most other applications, these large numbers are called
+MPIs (multi-precision-integers).
+
+
+File: gcrypt.info, Node: Data types, Next: Basic functions, Up: MPI library
+
+12.1 Data types
+===============
+
+ -- Data type: gcry_mpi_t
+ This type represents an object to hold an MPI.
+
+ -- Data type: gcry_mpi_point_t
+ This type represents an object to hold a point for elliptic curve
+ math.
+
+
+File: gcrypt.info, Node: Basic functions, Next: MPI formats, Prev: Data types, Up: MPI library
+
+12.2 Basic functions
+====================
+
+To work with MPIs, storage must be allocated and released for the
+numbers. This can be done with one of these functions:
+
+ -- Function: gcry_mpi_t gcry_mpi_new (unsigned int NBITS)
+
+ Allocate a new MPI object, initialize it to 0 and initially
+ allocate enough memory for a number of at least NBITS. This
+ pre-allocation is only a small performance issue and not actually
+ necessary because Libgcrypt automatically re-allocates the required
+ memory.
+
+ -- Function: gcry_mpi_t gcry_mpi_snew (unsigned int NBITS)
+
+ This is identical to 'gcry_mpi_new' but allocates the MPI in the so
+ called "secure memory" which in turn will take care that all
+ derived values will also be stored in this "secure memory". Use
+ this for highly confidential data like private key parameters.
+
+ -- Function: gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t A)
+
+ Create a new MPI as the exact copy of A but with the constant and
+ immutable flags cleared.
+
+ -- Function: void gcry_mpi_release (gcry_mpi_t A)
+
+ Release the MPI A and free all associated resources. Passing
+ 'NULL' is allowed and ignored. When a MPI stored in the "secure
+ memory" is released, that memory gets wiped out immediately.
+
+The simplest operations are used to assign a new value to an MPI:
+
+ -- Function: gcry_mpi_t gcry_mpi_set (gcry_mpi_t W, const gcry_mpi_t U)
+
+ Assign the value of U to W and return W. If 'NULL' is passed for
+ W, a new MPI is allocated, set to the value of U and returned.
+
+ -- Function: gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t W, unsigned long U)
+
+ Assign the value of U to W and return W. If 'NULL' is passed for
+ W, a new MPI is allocated, set to the value of U and returned.
+ This function takes an 'unsigned int' as type for U and thus it is
+ only possible to set W to small values (usually up to the word size
+ of the CPU).
+
+ -- Function: gcry_error_t gcry_mpi_get_ui (unsigned int *W,
+ gcry_mpi_t U)
+
+ If U is not negative and small enough to be stored in an 'unsigned
+ int' variable, store its value at W. If the value does not fit or
+ is negative return GPG_ERR_ERANGE and do not change the value
+ stored at W. Note that this function returns an 'unsigned int' so
+ that this value can immediately be used with the bit test
+ functions. This is in contrast to the other "_ui" functions which
+ allow for values up to an 'unsigned long'.
+
+ -- Function: void gcry_mpi_swap (gcry_mpi_t A, gcry_mpi_t B)
+
+ Swap the values of A and B.
+
+ -- Function: void gcry_mpi_snatch (gcry_mpi_t W, const gcry_mpi_t U)
+
+ Set U into W and release U. If W is 'NULL' only U will be
+ released.
+
+ -- Function: void gcry_mpi_neg (gcry_mpi_t W, gcry_mpi_t U)
+
+ Set the sign of W to the negative of U.
+
+ -- Function: void gcry_mpi_abs (gcry_mpi_t W)
+
+ Clear the sign of W.
+
+
+File: gcrypt.info, Node: MPI formats, Next: Calculations, Prev: Basic functions, Up: MPI library
+
+12.3 MPI formats
+================
+
+The following functions are used to convert between an external
+representation of an MPI and the internal one of Libgcrypt.
+
+ -- Function: gcry_error_t gcry_mpi_scan (gcry_mpi_t *R_MPI,
+ enum gcry_mpi_format FORMAT, const unsigned char *BUFFER,
+ size_t BUFLEN, size_t *NSCANNED)
+
+ Convert the external representation of an integer stored in BUFFER
+ with a length of BUFLEN into a newly created MPI returned which
+ will be stored at the address of R_MPI. For certain formats the
+ length argument is not required and should be passed as '0'. A
+ BUFLEN larger than 16 MiByte will be rejected. After a successful
+ operation the variable NSCANNED receives the number of bytes
+ actually scanned unless NSCANNED was given as 'NULL'. FORMAT
+ describes the format of the MPI as stored in BUFFER:
+
+ 'GCRYMPI_FMT_STD'
+ 2-complement stored without a length header. Note that
+ 'gcry_mpi_print' stores a '0' as a string of zero length.
+
+ 'GCRYMPI_FMT_PGP'
+ As used by OpenPGP (only defined as unsigned). This is
+ basically 'GCRYMPI_FMT_STD' with a 2 byte big endian length
+ header. A length header indicating a length of more than
+ 16384 is not allowed.
+
+ 'GCRYMPI_FMT_SSH'
+ As used in the Secure Shell protocol. This is
+ 'GCRYMPI_FMT_STD' with a 4 byte big endian header.
+
+ 'GCRYMPI_FMT_HEX'
+ Stored as a string with each byte of the MPI encoded as 2 hex
+ digits. Negative numbers are prefix with a minus sign and in
+ addition the high bit is always zero to make clear that an
+ explicit sign ist used. When using this format, BUFLEN must
+ be zero.
+
+ 'GCRYMPI_FMT_USG'
+ Simple unsigned integer.
+
+ Note that all of the above formats store the integer in big-endian
+ format (MSB first).
+
+ -- Function: gcry_error_t gcry_mpi_print (enum gcry_mpi_format FORMAT,
+ unsigned char *BUFFER, size_t BUFLEN, size_t *NWRITTEN,
+ const gcry_mpi_t A)
+
+ Convert the MPI A into an external representation described by
+ FORMAT (see above) and store it in the provided BUFFER which has a
+ usable length of at least the BUFLEN bytes. If NWRITTEN is not
+ NULL, it will receive the number of bytes actually stored in BUFFER
+ after a successful operation.
+
+ -- Function: gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format FORMAT,
+ unsigned char **BUFFER, size_t *NBYTES, const gcry_mpi_t A)
+
+ Convert the MPI A into an external representation described by
+ FORMAT (see above) and store it in a newly allocated buffer which
+ address will be stored in the variable BUFFER points to. The
+ number of bytes stored in this buffer will be stored in the
+ variable NBYTES points to, unless NBYTES is 'NULL'.
+
+ Even if NBYTES is zero, the function allocates at least one byte
+ and store a zero there. Thus with formats 'GCRYMPI_FMT_STD' and
+ 'GCRYMPI_FMT_USG' the caller may safely set a returned length of 0
+ to 1 to represent a zero as a 1 byte string.
+
+ -- Function: void gcry_mpi_dump (const gcry_mpi_t A)
+
+ Dump the value of A in a format suitable for debugging to
+ Libgcrypt's logging stream. Note that one leading space but no
+ trailing space or linefeed will be printed. It is okay to pass
+ 'NULL' for A.
+
+
+File: gcrypt.info, Node: Calculations, Next: Comparisons, Prev: MPI formats, Up: MPI library
+
+12.4 Calculations
+=================
+
+Basic arithmetic operations:
+
+ -- Function: void gcry_mpi_add (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V)
+
+ W = U + V.
+
+ -- Function: void gcry_mpi_add_ui (gcry_mpi_t W, gcry_mpi_t U,
+ unsigned long V)
+
+ W = U + V. Note that V is an unsigned integer.
+
+ -- Function: void gcry_mpi_addm (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V, gcry_mpi_t M)
+
+ W = U + V \bmod M.
+
+ -- Function: void gcry_mpi_sub (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V)
+
+ W = U - V.
+
+ -- Function: void gcry_mpi_sub_ui (gcry_mpi_t W, gcry_mpi_t U,
+ unsigned long V)
+
+ W = U - V. V is an unsigned integer.
+
+ -- Function: void gcry_mpi_subm (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V, gcry_mpi_t M)
+
+ W = U - V \bmod M.
+
+ -- Function: void gcry_mpi_mul (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V)
+
+ W = U * V.
+
+ -- Function: void gcry_mpi_mul_ui (gcry_mpi_t W, gcry_mpi_t U,
+ unsigned long V)
+
+ W = U * V. V is an unsigned integer.
+
+ -- Function: void gcry_mpi_mulm (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V, gcry_mpi_t M)
+
+ W = U * V \bmod M.
+
+ -- Function: void gcry_mpi_mul_2exp (gcry_mpi_t W, gcry_mpi_t U,
+ unsigned long E)
+
+ W = U * 2^e.
+
+ -- Function: void gcry_mpi_div (gcry_mpi_t Q, gcry_mpi_t R,
+ gcry_mpi_t DIVIDEND, gcry_mpi_t DIVISOR, int ROUND)
+
+ Q = DIVIDEND / DIVISOR, R = DIVIDEND \bmod DIVISOR. Q and R may be
+ passed as 'NULL'. ROUND is either negative for floored division
+ (rounds towards the next lower integer) or zero for truncated
+ division (rounds towards zero).
+
+ -- Function: void gcry_mpi_mod (gcry_mpi_t R, gcry_mpi_t DIVIDEND,
+ gcry_mpi_t DIVISOR)
+
+ R = DIVIDEND \bmod DIVISOR.
+
+ -- Function: void gcry_mpi_powm (gcry_mpi_t W, const gcry_mpi_t B,
+ const gcry_mpi_t E, const gcry_mpi_t M)
+
+ W = B^e \bmod M.
+
+ -- Function: int gcry_mpi_gcd (gcry_mpi_t G, gcry_mpi_t A,
+ gcry_mpi_t B)
+
+ Set G to the greatest common divisor of A and B. Return true if
+ the G is 1.
+
+ -- Function: int gcry_mpi_invm (gcry_mpi_t X, gcry_mpi_t A,
+ gcry_mpi_t M)
+
+ Set X to the multiplicative inverse of A \bmod M. Return true if
+ the inverse exists.
+
+
+File: gcrypt.info, Node: Comparisons, Next: Bit manipulations, Prev: Calculations, Up: MPI library
+
+12.5 Comparisons
+================
+
+The next 2 functions are used to compare MPIs:
+
+ -- Function: int gcry_mpi_cmp (const gcry_mpi_t U, const gcry_mpi_t V)
+
+ Compare the multi-precision-integers number U and V returning 0 for
+ equality, a positive value for U > V and a negative for U < V. If
+ both numbers are opaque values (cf, gcry_mpi_set_opaque) the
+ comparison is done by checking the bit sizes using memcmp. If only
+ one number is an opaque value, the opaque value is less than the
+ other number.
+
+ -- Function: int gcry_mpi_cmp_ui (const gcry_mpi_t U, unsigned long V)
+
+ Compare the multi-precision-integers number U with the unsigned
+ integer V returning 0 for equality, a positive value for U > V and
+ a negative for U < V.
+
+ -- Function: int gcry_mpi_is_neg (const gcry_mpi_t A)
+
+ Return 1 if A is less than zero; return 0 if zero or positive.
+
+
+File: gcrypt.info, Node: Bit manipulations, Next: EC functions, Prev: Comparisons, Up: MPI library
+
+12.6 Bit manipulations
+======================
+
+There are a couple of functions to get information on arbitrary bits in
+an MPI and to set or clear them:
+
+ -- Function: unsigned int gcry_mpi_get_nbits (gcry_mpi_t A)
+
+ Return the number of bits required to represent A.
+
+ -- Function: int gcry_mpi_test_bit (gcry_mpi_t A, unsigned int N)
+
+ Return true if bit number N (counting from 0) is set in A.
+
+ -- Function: void gcry_mpi_set_bit (gcry_mpi_t A, unsigned int N)
+
+ Set bit number N in A.
+
+ -- Function: void gcry_mpi_clear_bit (gcry_mpi_t A, unsigned int N)
+
+ Clear bit number N in A.
+
+ -- Function: void gcry_mpi_set_highbit (gcry_mpi_t A, unsigned int N)
+
+ Set bit number N in A and clear all bits greater than N.
+
+ -- Function: void gcry_mpi_clear_highbit (gcry_mpi_t A, unsigned int N)
+
+ Clear bit number N in A and all bits greater than N.
+
+ -- Function: void gcry_mpi_rshift (gcry_mpi_t X, gcry_mpi_t A,
+ unsigned int N)
+
+ Shift the value of A by N bits to the right and store the result in
+ X.
+
+ -- Function: void gcry_mpi_lshift (gcry_mpi_t X, gcry_mpi_t A,
+ unsigned int N)
+
+ Shift the value of A by N bits to the left and store the result in
+ X.
+
+
+File: gcrypt.info, Node: EC functions, Next: Miscellaneous, Prev: Bit manipulations, Up: MPI library
+
+12.7 EC functions
+=================
+
+Libgcrypt provides an API to access low level functions used by its
+elliptic curve implementation. These functions allow to implement
+elliptic curve methods for which no explicit support is available.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_point_new (unsigned int NBITS)
+
+ Allocate a new point object, initialize it to 0, and allocate
+ enough memory for a points of at least NBITS. This pre-allocation
+ yields only a small performance win and is not really necessary
+ because Libgcrypt automatically re-allocates the required memory.
+ Using 0 for NBITS is usually the right thing to do.
+
+ -- Function: void gcry_mpi_point_release (gcry_mpi_point_t POINT)
+
+ Release POINT and free all associated resources. Passing 'NULL' is
+ allowed and ignored.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_point_copy
+ (gcry_mpi_point_t POINT)
+
+ Allocate and return a new point object and initialize it with
+ POINT. If POINT is NULL the function is identical to
+ 'gcry_mpi_point_new(0)'.
+
+ -- Function: void gcry_mpi_point_get (gcry_mpi_t X, gcry_mpi_t Y,
+ gcry_mpi_t Z, gcry_mpi_point_t POINT)
+
+ Store the projective coordinates from POINT into the MPIs X, Y, and
+ Z. If a coordinate is not required, 'NULL' may be used for X, Y,
+ or Z.
+
+ -- Function: void gcry_mpi_point_snatch_get (gcry_mpi_t X,
+ gcry_mpi_t Y, gcry_mpi_t Z, gcry_mpi_point_t POINT)
+
+ Store the projective coordinates from POINT into the MPIs X, Y, and
+ Z. If a coordinate is not required, 'NULL' may be used for X, Y,
+ or Z. The object POINT is then released. Using this function
+ instead of 'gcry_mpi_point_get' and 'gcry_mpi_point_release' has
+ the advantage of avoiding some extra memory allocations and copies.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_point_set (
+ gcry_mpi_point_t POINT, gcry_mpi_t X, gcry_mpi_t Y,
+ gcry_mpi_t Z)
+
+ Store the projective coordinates from X, Y, and Z into POINT. If a
+ coordinate is given as 'NULL', the value 0 is used. If 'NULL' is
+ used for POINT a new point object is allocated and returned.
+ Returns POINT or the newly allocated point object.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_point_snatch_set (
+ gcry_mpi_point_t POINT, gcry_mpi_t X, gcry_mpi_t Y,
+ gcry_mpi_t Z)
+
+ Store the projective coordinates from X, Y, and Z into POINT. If a
+ coordinate is given as 'NULL', the value 0 is used. If 'NULL' is
+ used for POINT a new point object is allocated and returned. The
+ MPIs X, Y, and Z are released. Using this function instead of
+ 'gcry_mpi_point_set' and 3 calls to 'gcry_mpi_release' has the
+ advantage of avoiding some extra memory allocations and copies.
+ Returns POINT or the newly allocated point object.
+
+ -- Function: gpg_error_t gcry_mpi_ec_new (gcry_ctx_t *R_CTX,
+ gcry_sexp_t KEYPARAM, const char *CURVENAME)
+
+ Allocate a new context for elliptic curve operations. If KEYPARAM
+ is given it specifies the parameters of the curve (*note
+ ecc_keyparam::). If CURVENAME is given in addition to KEYPARAM and
+ the key parameters do not include a named curve reference, the
+ string CURVENAME is used to fill in missing parameters. If only
+ CURVENAME is given, the context is initialized for this named
+ curve.
+
+ If a parameter specifying a point (e.g. 'g' or 'q') is not found,
+ the parser looks for a non-encoded point by appending '.x', '.y',
+ and '.z' to the parameter name and looking them all up to create a
+ point. A parameter with the suffix '.z' is optional and defaults
+ to 1.
+
+ On success the function returns 0 and stores the new context object
+ at R_CTX; this object eventually needs to be released (*note
+ gcry_ctx_release::). On error the function stores 'NULL' at R_CTX
+ and returns an error code.
+
+ -- Function: gcry_mpi_t gcry_mpi_ec_get_mpi ( const char *NAME,
+ gcry_ctx_t CTX, int COPY)
+
+ Return the MPI with NAME from the context CTX. If not found 'NULL'
+ is returned. If the returned MPI may later be modified, it is
+ suggested to pass '1' to COPY, so that the function guarantees that
+ a modifiable copy of the MPI is returned. If '0' is used for COPY,
+ this function may return a constant flagged MPI. In any case
+ 'gcry_mpi_release' needs to be called to release the result. For
+ valid names *note ecc_keyparam::. If the public key 'q' is
+ requested but only the private key 'd' is available, 'q' will be
+ recomputed on the fly. If a point parameter is requested it is
+ returned as an uncompressed encoded point unless these special
+ names are used:
+ Q@EDDSA
+ Return an EdDSA style compressed point. This is only
+ supported for Twisted Edwards curves.
+
+ -- Function: gcry_mpi_point_t gcry_mpi_ec_get_point ( const char *NAME,
+ gcry_ctx_t CTX, int COPY)
+
+ Return the point with NAME from the context CTX. If not found
+ 'NULL' is returned. If the returned MPI may later be modified, it
+ is suggested to pass '1' to COPY, so that the function guarantees
+ that a modifiable copy of the MPI is returned. If '0' is used for
+ COPY, this function may return a constant flagged point. In any
+ case 'gcry_mpi_point_release' needs to be called to release the
+ result. If the public key 'q' is requested but only the private
+ key 'd' is available, 'q' will be recomputed on the fly.
+
+ -- Function: gpg_error_t gcry_mpi_ec_set_mpi ( const char *NAME,
+ gcry_mpi_t NEWVALUE, gcry_ctx_t CTX)
+
+ Store the MPI NEWVALUE at NAME into the context CTX. On success
+ '0' is returned; on error an error code. Valid names are the MPI
+ parameters of an elliptic curve (*note ecc_keyparam::).
+
+ -- Function: gpg_error_t gcry_mpi_ec_set_point ( const char *NAME,
+ gcry_mpi_point_t NEWVALUE, gcry_ctx_t CTX)
+
+ Store the point NEWVALUE at NAME into the context CTX. On success
+ '0' is returned; on error an error code. Valid names are the point
+ parameters of an elliptic curve (*note ecc_keyparam::).
+
+ -- Function: gpg_err_code_t gcry_mpi_ec_decode_point (
+ mpi_point_t RESULT, gcry_mpi_t VALUE, gcry_ctx_t CTX)
+
+ Decode the point given as an MPI in VALUE and store at RESULT. To
+ decide which encoding is used the function takes a context CTX
+ which can be created with 'gcry_mpi_ec_new'. If 'NULL' is given
+ for the context the function assumes a 0x04 prefixed uncompressed
+ encoding. On error an error code is returned and RESULT might be
+ changed.
+
+ -- Function: int gcry_mpi_ec_get_affine ( gcry_mpi_t X, gcry_mpi_t Y,
+ gcry_mpi_point_t POINT, gcry_ctx_t CTX)
+
+ Compute the affine coordinates from the projective coordinates in
+ POINT and store them into X and Y. If one coordinate is not
+ required, 'NULL' may be passed to X or Y. CTX is the context
+ object which has been created using 'gcry_mpi_ec_new'. Returns 0
+ on success or not 0 if POINT is at infinity.
+
+ Note that you can use 'gcry_mpi_ec_set_point' with the value
+ 'GCRYMPI_CONST_ONE' for Z to convert affine coordinates back into
+ projective coordinates.
+
+ -- Function: void gcry_mpi_ec_dup ( gcry_mpi_point_t W,
+ gcry_mpi_point_t U, gcry_ctx_t CTX)
+
+ Double the point U of the elliptic curve described by CTX and store
+ the result into W.
+
+ -- Function: void gcry_mpi_ec_add ( gcry_mpi_point_t W,
+ gcry_mpi_point_t U, gcry_mpi_point_t V, gcry_ctx_t CTX)
+
+ Add the points U and V of the elliptic curve described by CTX and
+ store the result into W.
+
+ -- Function: void gcry_mpi_ec_sub ( gcry_mpi_point_t W,
+ gcry_mpi_point_t U, gcry_mpi_point_t V, gcry_ctx_t CTX)
+
+ Subtracts the point V from the point U of the elliptic curve
+ described by CTX and store the result into W. Only Twisted Edwards
+ curves are supported for now.
+
+ -- Function: void gcry_mpi_ec_mul ( gcry_mpi_point_t W, gcry_mpi_t N,
+ gcry_mpi_point_t U, gcry_ctx_t CTX)
+
+ Multiply the point U of the elliptic curve described by CTX by N
+ and store the result into W.
+
+ -- Function: int gcry_mpi_ec_curve_point ( gcry_mpi_point_t POINT,
+ gcry_ctx_t CTX)
+
+ Return true if POINT is on the elliptic curve described by CTX.
+
+
+File: gcrypt.info, Node: Miscellaneous, Prev: EC functions, Up: MPI library
+
+12.8 Miscellaneous
+==================
+
+An MPI data type is allowed to be "misused" to store an arbitrary value.
+Two functions implement this kludge:
+
+ -- Function: gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t A, void *P,
+ unsigned int NBITS)
+
+ Store NBITS of the value P points to in A and mark A as an opaque
+ value (i.e. an value that can't be used for any math calculation
+ and is only used to store an arbitrary bit pattern in A).
+ Ownership of P is taken by this function and thus the user may not
+ use dereference the passed value anymore. It is required that them
+ memory referenced by P has been allocated in a way that 'gcry_free'
+ is able to release it.
+
+ WARNING: Never use an opaque MPI for actual math operations. The
+ only valid functions are gcry_mpi_get_opaque and gcry_mpi_release.
+ Use gcry_mpi_scan to convert a string of arbitrary bytes into an
+ MPI.
+
+ -- Function: gcry_mpi_t gcry_mpi_set_opaque_copy (gcry_mpi_t A,
+ const void *P, unsigned int NBITS)
+
+ Same as 'gcry_mpi_set_opaque' but ownership of P is not taken
+ instead a copy of P is used.
+
+ -- Function: void * gcry_mpi_get_opaque (gcry_mpi_t A,
+ unsigned int *NBITS)
+
+ Return a pointer to an opaque value stored in A and return its size
+ in NBITS. Note that the returned pointer is still owned by A and
+ that the function should never be used for an non-opaque MPI.
+
+ Each MPI has an associated set of flags for special purposes. The
+currently defined flags are:
+
+'GCRYMPI_FLAG_SECURE'
+ Setting this flag converts A into an MPI stored in "secure memory".
+ Clearing this flag is not allowed.
+'GCRYMPI_FLAG_OPAQUE'
+ This is an internal flag, indicating the an opaque valuue and not
+ an integer is stored. This is an read-only flag; it may not be set
+ or cleared.
+'GCRYMPI_FLAG_IMMUTABLE'
+ If this flag is set, the MPI is marked as immutable. Setting or
+ changing the value of that MPI is ignored and an error message is
+ logged. The flag is sometimes useful for debugging.
+'GCRYMPI_FLAG_CONST'
+ If this flag is set, the MPI is marked as a constant and as
+ immutable Setting or changing the value of that MPI is ignored and
+ an error message is logged. Such an MPI will never be deallocated
+ and may thus be used without copying. Note that using
+ gcry_mpi_copy will return a copy of that constant with this and the
+ immutable flag cleared. A few commonly used constants are
+ pre-defined and accessible using the macros 'GCRYMPI_CONST_ONE',
+ 'GCRYMPI_CONST_TWO', 'GCRYMPI_CONST_THREE', 'GCRYMPI_CONST_FOUR',
+ and 'GCRYMPI_CONST_EIGHT'.
+'GCRYMPI_FLAG_USER1'
+'GCRYMPI_FLAG_USER2'
+'GCRYMPI_FLAG_USER3'
+'GCRYMPI_FLAG_USER4'
+ These flags are reserved for use by the application.
+
+ -- Function: void gcry_mpi_set_flag (gcry_mpi_t A,
+ enum gcry_mpi_flag FLAG)
+
+ Set the FLAG for the MPI A. The only allowed flags are
+ 'GCRYMPI_FLAG_SECURE', 'GCRYMPI_FLAG_IMMUTABLE', and
+ 'GCRYMPI_FLAG_CONST'.
+
+ -- Function: void gcry_mpi_clear_flag (gcry_mpi_t A,
+ enum gcry_mpi_flag FLAG)
+
+ Clear FLAG for the multi-precision-integers A. The only allowed
+ flag is 'GCRYMPI_FLAG_IMMUTABLE' but only if 'GCRYMPI_FLAG_CONST'
+ is not set. If 'GCRYMPI_FLAG_CONST' is set, clearing
+ 'GCRYMPI_FLAG_IMMUTABLE' will simply be ignored.
+ o
+ -- Function: int gcry_mpi_get_flag (gcry_mpi_t A,
+ enum gcry_mpi_flag FLAG)
+
+ Return true if FLAG is set for A.
+
+ To put a random value into an MPI, the following convenience function
+may be used:
+
+ -- Function: void gcry_mpi_randomize (gcry_mpi_t W, unsigned int NBITS,
+ enum gcry_random_level LEVEL)
+
+ Set the multi-precision-integers W to a random non-negative number
+ of NBITS, using random data quality of level LEVEL. In case NBITS
+ is not a multiple of a byte, NBITS is rounded up to the next byte
+ boundary. When using a LEVEL of 'GCRY_WEAK_RANDOM' this function
+ makes use of 'gcry_create_nonce'.
+
+
+File: gcrypt.info, Node: Prime numbers, Next: Utilities, Prev: MPI library, Up: Top
+
+13 Prime numbers
+****************
+
+* Menu:
+
+* Generation:: Generation of new prime numbers.
+* Checking:: Checking if a given number is prime.
+
+
+File: gcrypt.info, Node: Generation, Next: Checking, Up: Prime numbers
+
+13.1 Generation
+===============
+
+ -- Function: gcry_error_t gcry_prime_generate (gcry_mpi_t
+ *PRIME,unsigned int PRIME_BITS, unsigned int FACTOR_BITS,
+ gcry_mpi_t **FACTORS, gcry_prime_check_func_t CB_FUNC, void
+ *CB_ARG, gcry_random_level_t RANDOM_LEVEL, unsigned int FLAGS)
+
+ Generate a new prime number of PRIME_BITS bits and store it in
+ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of
+ (PRIME - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is
+ non-zero, allocate a new, 'NULL'-terminated array holding the prime
+ factors and store it in FACTORS. FLAGS might be used to influence
+ the prime number generation process.
+
+ -- Function: gcry_error_t gcry_prime_group_generator (gcry_mpi_t *R_G,
+ gcry_mpi_t PRIME, gcry_mpi_t *FACTORS, gcry_mpi_t START_G)
+
+ Find a generator for PRIME where the factorization of (PRIME-1) is
+ in the 'NULL' terminated array FACTORS. Return the generator as a
+ newly allocated MPI in R_G. If START_G is not NULL, use this as
+ the start for the search.
+
+ -- Function: void gcry_prime_release_factors (gcry_mpi_t *FACTORS)
+
+ Convenience function to release the FACTORS array.
+
+
+File: gcrypt.info, Node: Checking, Prev: Generation, Up: Prime numbers
+
+13.2 Checking
+=============
+
+ -- Function: gcry_error_t gcry_prime_check (gcry_mpi_t P, unsigned int
+ FLAGS)
+
+ Check whether the number P is prime. Returns zero in case P is
+ indeed a prime, returns 'GPG_ERR_NO_PRIME' in case P is not a prime
+ and a different error code in case something went horribly wrong.
+
+
+File: gcrypt.info, Node: Utilities, Next: Tools, Prev: Prime numbers, Up: Top
+
+14 Utilities
+************
+
+* Menu:
+
+* Memory allocation:: Functions related with memory allocation.
+* Context management:: Functions related with context management.
+* Buffer description:: A data type to describe buffers.
+* Config reporting:: How to return Libgcrypt's configuration.
+
+
+File: gcrypt.info, Node: Memory allocation, Next: Context management, Up: Utilities
+
+14.1 Memory allocation
+======================
+
+ -- Function: void * gcry_malloc (size_t N)
+
+ This function tries to allocate N bytes of memory. On success it
+ returns a pointer to the memory area, in an out-of-core condition,
+ it returns NULL.
+
+ -- Function: void * gcry_malloc_secure (size_t N)
+ Like 'gcry_malloc', but uses secure memory.
+
+ -- Function: void * gcry_calloc (size_t N, size_t M)
+
+ This function allocates a cleared block of memory (i.e.
+ initialized with zero bytes) long enough to contain a vector of N
+ elements, each of size M bytes. On success it returns a pointer to
+ the memory block; in an out-of-core condition, it returns NULL.
+
+ -- Function: void * gcry_calloc_secure (size_t N, size_t M)
+ Like 'gcry_calloc', but uses secure memory.
+
+ -- Function: void * gcry_realloc (void *P, size_t N)
+
+ This function tries to resize the memory area pointed to by P to N
+ bytes. On success it returns a pointer to the new memory area, in
+ an out-of-core condition, it returns NULL. Depending on whether the
+ memory pointed to by P is secure memory or not, gcry_realloc tries
+ to use secure memory as well.
+
+ -- Function: void gcry_free (void *P)
+ Release the memory area pointed to by P.
+
+
+File: gcrypt.info, Node: Context management, Next: Buffer description, Prev: Memory allocation, Up: Utilities
+
+14.2 Context management
+=======================
+
+Some function make use of a context object. As of now there are only a
+few math functions. However, future versions of Libgcrypt may make more
+use of this context object.
+
+ -- Data type: gcry_ctx_t
+ This type is used to refer to the general purpose context object.
+
+ -- Function: void gcry_ctx_release (gcry_ctx_t CTX)
+ Release the context object CTX and all associated resources. A
+ 'NULL' passed as CTX is ignored.
+
+
+File: gcrypt.info, Node: Buffer description, Next: Config reporting, Prev: Context management, Up: Utilities
+
+14.3 Buffer description
+=======================
+
+To help hashing non-contiguous areas of memory a general purpose data
+type is defined:
+
+ -- Data type: gcry_buffer_t
+ This type is a structure to describe a buffer. The user should
+ make sure that this structure is initialized to zero. The
+ available fields of this structure are:
+
+ '.size'
+ This is either 0 for no information available or indicates the
+ allocated length of the buffer.
+ '.off'
+ This is the offset into the buffer.
+ '.len'
+ This is the valid length of the buffer starting at '.off'.
+ '.data'
+ This is the address of the buffer.
+
+
+File: gcrypt.info, Node: Config reporting, Prev: Buffer description, Up: Utilities
+
+14.4 How to return Libgcrypt's configuration.
+=============================================
+
+Although 'GCRYCTL_PRINT_CONFIG' can be used to print configuration
+options, it is sometimes necessary to check them in a program. This can
+be accomplished by using this function:
+
+ -- Function: char * gcry_get_config (int MODE, const char *WHAT)
+
+ This function returns a malloced string with colon delimited
+ configure options. With a value of 0 for MODE this string
+ resembles the output of 'GCRYCTL_PRINT_CONFIG'. However, if WHAT
+ is not NULL, only the line where the first field (e.g. "cpu-arch")
+ matches WHAT is returned.
+
+ Other values than 0 for MODE are not defined. The caller shall
+ free the string using 'gcry_free'. On error NULL is returned and
+ ERRNO is set; if a value for WHAT is unknow ERRNO will be set to 0.
+
+
+File: gcrypt.info, Node: Tools, Next: Configuration, Prev: Utilities, Up: Top
+
+15 Tools
+********
+
+* Menu:
+
+* hmac256:: A standalone HMAC-SHA-256 implementation
+
+
+File: gcrypt.info, Node: hmac256, Up: Tools
+
+15.1 A HMAC-SHA-256 tool
+========================
+
+This is a standalone HMAC-SHA-256 implementation used to compute an
+HMAC-SHA-256 message authentication code. The tool has originally been
+developed as a second implementation for Libgcrypt to allow comparing
+against the primary implementation and to be used for internal
+consistency checks. It should not be used for sensitive data because no
+mechanisms to clear the stack etc are used.
+
+ The code has been written in a highly portable manner and requires
+only a few standard definitions to be provided in a config.h file.
+
+'hmac256' is commonly invoked as
+
+ hmac256 "This is my key" foo.txt
+
+This compute the MAC on the file 'foo.txt' using the key given on the
+command line.
+
+'hmac256' understands these options:
+
+'--binary'
+ Print the MAC as a binary string. The default is to print the MAC
+ encoded has lower case hex digits.
+
+'--version'
+ Print version of the program and exit.
+
+
+File: gcrypt.info, Node: Configuration, Next: Architecture, Prev: Tools, Up: Top
+
+16 Configuration files and environment variables
+************************************************
+
+This chapter describes which files and environment variables can be used
+to change the behaviour of Libgcrypt.
+
+The environment variables considered by Libgcrypt are:
+
+'GCRYPT_BARRETT'
+ By setting this variable to any value a different algorithm for
+ modular reduction is used for ECC.
+
+'GCRYPT_RNDUNIX_DBG'
+'GCRYPT_RNDUNIX_DBGALL'
+ These two environment variables are used to enable debug output for
+ the rndunix entropy gatherer, which is used on systems lacking a
+ /dev/random device. The value of 'GCRYPT_RNDUNIX_DBG' is a file
+ name or '-' for stdout. Debug output is the written to this file.
+ By setting 'GCRYPT_RNDUNIX_DBGALL' to any value the debug output
+ will be more verbose.
+
+'GCRYPT_RNDW32_NOPERF'
+ Setting this environment variable on Windows to any value disables
+ the use of performance data ('HKEY_PERFORMANCE_DATA') as source for
+ entropy. On some older Windows systems this could help to speed up
+ the creation of random numbers but also decreases the amount of
+ data used to init the random number generator.
+
+'GCRYPT_RNDW32_DBG'
+ Setting the value of this variable to a positive integer logs
+ information about the Windows entropy gatherer using the standard
+ log interface.
+
+'HOME'
+ This is used to locate the socket to connect to the EGD random
+ daemon. The EGD can be used on system without a /dev/random to
+ speed up the random number generator. It is not needed on the
+ majority of today's operating systems and support for EGD requires
+ the use of a configure option at build time.
+
+The files which Libgcrypt uses to retrieve system information and the
+files which can be created by the user to modify Libgcrypt's behavior
+are:
+
+'/etc/gcrypt/hwf.deny'
+ This file can be used to disable the use of hardware based
+ optimizations, *note hardware features::.
+
+'/etc/gcrypt/random.conf'
+ This file can be used to globally change parameters of the random
+ generator. The file is a simple text file where empty lines and
+ lines with the first non white-space character being '#' are
+ ignored. Supported options are
+
+ 'disable-jent'
+ Disable the use of the jitter based entropy generator.
+
+ 'only-urandom'
+ Always use the non-blocking /dev/urandom or the respective
+ system call instead of the blocking /dev/random. If Libgcrypt
+ is used early in the boot process of the system, this option
+ should only be used if the system also supports the getrandom
+ system call.
+
+'/etc/gcrypt/fips_enabled'
+'/proc/sys/crypto/fips_enabled'
+ On Linux these files are used to enable FIPS mode, *note enabling
+ fips mode::.
+
+'/proc/cpuinfo'
+'/proc/self/auxv'
+ On Linux running on the ARM architecture, these files are used to
+ read hardware capabilities of the CPU.
+
+
+File: gcrypt.info, Node: Architecture, Next: Self-Tests, Prev: Configuration, Up: Top
+
+17 Architecture
+***************
+
+This chapter describes the internal architecture of Libgcrypt.
+
+ Libgcrypt is a function library written in ISO C-90. Any compliant
+compiler should be able to build Libgcrypt as long as the target is
+either a POSIX platform or compatible to the API used by Windows NT.
+Provisions have been take so that the library can be directly used from
+C++ applications; however building with a C++ compiler is not supported.
+
+ Building Libgcrypt is done by using the common './configure && make'
+approach. The configure command is included in the source distribution
+and as a portable shell script it works on any Unix-alike system. The
+result of running the configure script are a C header file ('config.h'),
+customized Makefiles, the setup of symbolic links and a few other
+things. After that the make tool builds and optionally installs the
+library and the documentation. See the files 'INSTALL' and 'README' in
+the source distribution on how to do this.
+
+ Libgcrypt is developed using a Subversion(1) repository. Although
+all released versions are tagged in this repository, they should not be
+used to build production versions of Libgcrypt. Instead released
+tarballs should be used. These tarballs are available from several
+places with the master copy at 'ftp://ftp.gnupg.org/gcrypt/libgcrypt/'.
+Announcements of new releases are posted to the
+'gnupg-announce@gnupg.org' mailing list(2).
+
+
+
+Figure 17.1: Libgcrypt subsystems
+
+ Libgcrypt consists of several subsystems (*note Figure 17.1:
+fig:subsystems.) and all these subsystems provide a public API; this
+includes the helper subsystems like the one for S-expressions. The API
+style depends on the subsystem; in general an open-use-close approach is
+implemented. The open returns a handle to a context used for all
+further operations on this handle, several functions may then be used on
+this handle and a final close function releases all resources associated
+with the handle.
+
+* Menu:
+
+* Public-Key Subsystem Architecture:: About public keys.
+* Symmetric Encryption Subsystem Architecture:: About standard ciphers.
+* Hashing and MACing Subsystem Architecture:: About hashing.
+* Multi-Precision-Integer Subsystem Architecture:: About big integers.
+* Prime-Number-Generator Subsystem Architecture:: About prime numbers.
+* Random-Number Subsystem Architecture:: About random stuff.
+
+ ---------- Footnotes ----------
+
+ (1) A version control system available for many platforms
+
+ (2) See <http://www.gnupg.org/documentation/mailing-lists.en.html>
+for details.
+
+
+File: gcrypt.info, Node: Public-Key Subsystem Architecture, Next: Symmetric Encryption Subsystem Architecture, Up: Architecture
+
+17.1 Public-Key Architecture
+============================
+
+Because public key cryptography is almost always used to process small
+amounts of data (hash values or session keys), the interface is not
+implemented using the open-use-close paradigm, but with single
+self-contained functions. Due to the wide variety of parameters
+required by different algorithms S-expressions, as flexible way to
+convey these parameters, are used. There is a set of helper functions
+to work with these S-expressions.
+
+ Aside of functions to register new algorithms, map algorithms names
+to algorithms identifiers and to lookup properties of a key, the
+following main functions are available:
+
+'gcry_pk_encrypt'
+ Encrypt data using a public key.
+
+'gcry_pk_decrypt'
+ Decrypt data using a private key.
+
+'gcry_pk_sign'
+ Sign data using a private key.
+
+'gcry_pk_verify'
+ Verify that a signature matches the data.
+
+'gcry_pk_testkey'
+ Perform a consistency over a public or private key.
+
+'gcry_pk_genkey'
+ Create a new public/private key pair.
+
+ All these functions lookup the module implementing the algorithm and
+pass the actual work to that module. The parsing of the S-expression
+input and the construction of S-expression for the return values is done
+by the high level code ('cipher/pubkey.c'). Thus the internal interface
+between the algorithm modules and the high level functions passes data
+in a custom format.
+
+ By default Libgcrypt uses a blinding technique for RSA decryption to
+mitigate real world timing attacks over a network: Instead of using the
+RSA decryption directly, a blinded value y = x r^{e} \bmod n is
+decrypted and the unblinded value x' = y' r^{-1} \bmod n returned. The
+blinding value r is a random value with the size of the modulus n and
+generated with 'GCRY_WEAK_RANDOM' random level.
+
+ The algorithm used for RSA and DSA key generation depends on whether
+Libgcrypt is operated in standard or in FIPS mode. In standard mode an
+algorithm based on the Lim-Lee prime number generator is used. In FIPS
+mode RSA keys are generated as specified in ANSI X9.31 (1998) and DSA
+keys as specified in FIPS 186-2.
+
+
+File: gcrypt.info, Node: Symmetric Encryption Subsystem Architecture, Next: Hashing and MACing Subsystem Architecture, Prev: Public-Key Subsystem Architecture, Up: Architecture
+
+17.2 Symmetric Encryption Subsystem Architecture
+================================================
+
+The interface to work with symmetric encryption algorithms is made up of
+functions from the 'gcry_cipher_' name space. The implementation
+follows the open-use-close paradigm and uses registered algorithm
+modules for the actual work. Unless a module implements optimized
+cipher mode implementations, the high level code ('cipher/cipher.c')
+implements the modes and calls the core algorithm functions to process
+each block.
+
+ The most important functions are:
+
+'gcry_cipher_open'
+ Create a new instance to encrypt or decrypt using a specified
+ algorithm and mode.
+
+'gcry_cipher_close'
+ Release an instance.
+
+'gcry_cipher_setkey'
+ Set a key to be used for encryption or decryption.
+
+'gcry_cipher_setiv'
+ Set an initialization vector to be used for encryption or
+ decryption.
+
+'gcry_cipher_encrypt'
+'gcry_cipher_decrypt'
+ Encrypt or decrypt data. These functions may be called with
+ arbitrary amounts of data and as often as needed to encrypt or
+ decrypt all data.
+
+ There is no strict alignment requirements for data, but the best
+ performance can be archived if data is aligned to cacheline
+ boundary.
+
+ There are also functions to query properties of algorithms or
+context, like block length, key length, map names or to enable features
+like padding methods.
+
+
+File: gcrypt.info, Node: Hashing and MACing Subsystem Architecture, Next: Multi-Precision-Integer Subsystem Architecture, Prev: Symmetric Encryption Subsystem Architecture, Up: Architecture
+
+17.3 Hashing and MACing Subsystem Architecture
+==============================================
+
+The interface to work with message digests and CRC algorithms is made up
+of functions from the 'gcry_md_' name space. The implementation follows
+the open-use-close paradigm and uses registered algorithm modules for
+the actual work. Although CRC algorithms are not considered
+cryptographic hash algorithms, they share enough properties so that it
+makes sense to handle them in the same way. It is possible to use
+several algorithms at once with one context and thus compute them all on
+the same data.
+
+ The most important functions are:
+
+'gcry_md_open'
+ Create a new message digest instance and optionally enable one
+ algorithm. A flag may be used to turn the message digest algorithm
+ into a HMAC algorithm.
+
+'gcry_md_enable'
+ Enable an additional algorithm for the instance.
+
+'gcry_md_setkey'
+ Set the key for the MAC.
+
+'gcry_md_write'
+ Pass more data for computing the message digest to an instance.
+
+ There is no strict alignment requirements for data, but the best
+ performance can be archived if data is aligned to cacheline
+ boundary.
+
+'gcry_md_putc'
+ Buffered version of 'gcry_md_write' implemented as a macro.
+
+'gcry_md_read'
+ Finalize the computation of the message digest or HMAC and return
+ the result.
+
+'gcry_md_close'
+ Release an instance
+
+'gcry_md_hash_buffer'
+ Convenience function to directly compute a message digest over a
+ memory buffer without the need to create an instance first.
+
+ There are also functions to query properties of algorithms or the
+instance, like enabled algorithms, digest length, map algorithm names.
+it is also possible to reset an instance or to copy the current state of
+an instance at any time. Debug functions to write the hashed data to
+files are available as well.
+
+
+File: gcrypt.info, Node: Multi-Precision-Integer Subsystem Architecture, Next: Prime-Number-Generator Subsystem Architecture, Prev: Hashing and MACing Subsystem Architecture, Up: Architecture
+
+17.4 Multi-Precision-Integer Subsystem Architecture
+===================================================
+
+The implementation of Libgcrypt's big integer computation code is based
+on an old release of GNU Multi-Precision Library (GMP). The decision not
+to use the GMP library directly was due to stalled development at that
+time and due to security requirements which could not be provided by the
+code in GMP. As GMP does, Libgcrypt provides high performance assembler
+implementations of low level code for several CPUS to gain much better
+performance than with a generic C implementation.
+
+Major features of Libgcrypt's multi-precision-integer code compared to
+GMP are:
+
+ * Avoidance of stack based allocations to allow protection against
+ swapping out of sensitive data and for easy zeroing of sensitive
+ intermediate results.
+
+ * Optional use of secure memory and tracking of its use so that
+ results are also put into secure memory.
+
+ * MPIs are identified by a handle (implemented as a pointer) to give
+ better control over allocations and to augment them with extra
+ properties like opaque data.
+
+ * Removal of unnecessary code to reduce complexity.
+
+ * Functions specialized for public key cryptography.
+
+
+File: gcrypt.info, Node: Prime-Number-Generator Subsystem Architecture, Next: Random-Number Subsystem Architecture, Prev: Multi-Precision-Integer Subsystem Architecture, Up: Architecture
+
+17.5 Prime-Number-Generator Subsystem Architecture
+==================================================
+
+Libgcrypt provides an interface to its prime number generator. These
+functions make use of the internal prime number generator which is
+required for the generation for public key key pairs. The plain prime
+checking function is exported as well.
+
+ The generation of random prime numbers is based on the Lim and Lee
+algorithm to create practically save primes.(1) This algorithm creates
+a pool of smaller primes, select a few of them to create candidate
+primes of the form 2 * p_0 * p_1 * ... * p_n + 1, tests the candidate
+for primality and permutates the pool until a prime has been found. It
+is possible to clamp one of the small primes to a certain size to help
+DSA style algorithms. Because most of the small primes in the pool are
+not used for the resulting prime number, they are saved for later use
+(see 'save_pool_prime' and 'get_pool_prime' in 'cipher/primegen.c').
+The prime generator optionally supports the finding of an appropriate
+generator.
+
+The primality test works in three steps:
+
+ 1. The standard sieve algorithm using the primes up to 4999 is used as
+ a quick first check.
+
+ 2. A Fermat test filters out almost all non-primes.
+
+ 3. A 5 round Rabin-Miller test is finally used. The first round uses
+ a witness of 2, whereas the next rounds use a random witness.
+
+ To support the generation of RSA and DSA keys in FIPS mode according
+to X9.31 and FIPS 186-2, Libgcrypt implements two additional prime
+generation functions: '_gcry_derive_x931_prime' and
+'_gcry_generate_fips186_2_prime'. These functions are internal and not
+available through the public API.
+
+ ---------- Footnotes ----------
+
+ (1) Chae Hoon Lim and Pil Joong Lee. A key recovery attack on
+discrete log-based schemes using a prime order subgroup. In Burton S.
+Kaliski Jr., editor, Advances in Cryptology: Crypto '97, pages
+249­-263, Berlin / Heidelberg / New York, 1997. Springer-Verlag.
+Described on page 260.
+
+
+File: gcrypt.info, Node: Random-Number Subsystem Architecture, Prev: Prime-Number-Generator Subsystem Architecture, Up: Architecture
+
+17.6 Random-Number Subsystem Architecture
+=========================================
+
+Libgcrypt provides 3 levels or random quality: The level
+'GCRY_VERY_STRONG_RANDOM' usually used for key generation, the level
+'GCRY_STRONG_RANDOM' for all other strong random requirements and the
+function 'gcry_create_nonce' which is used for weaker usages like
+nonces. There is also a level 'GCRY_WEAK_RANDOM' which in general maps
+to 'GCRY_STRONG_RANDOM' except when used with the function
+'gcry_mpi_randomize', where it randomizes an multi-precision-integer
+using the 'gcry_create_nonce' function.
+
+There are two distinct random generators available:
+
+ * The Continuously Seeded Pseudo Random Number Generator (CSPRNG),
+ which is based on the classic GnuPG derived big pool
+ implementation. Implemented in 'random/random-csprng.c' and used
+ by default.
+ * A FIPS approved ANSI X9.31 PRNG using AES with a 128 bit key.
+ Implemented in 'random/random-fips.c' and used if Libgcrypt is in
+ FIPS mode.
+
+Both generators make use of so-called entropy gathering modules:
+
+rndlinux
+ Uses the operating system provided '/dev/random' and '/dev/urandom'
+ devices. The '/dev/gcrypt/random.conf' config option
+ 'only-urandom' can be used to inhibit the use of the blocking
+ '/dev/random' device.
+
+rndunix
+ Runs several operating system commands to collect entropy from
+ sources like virtual machine and process statistics. It is a kind
+ of poor-man's '/dev/random' implementation. It is not available in
+ FIPS mode.
+
+rndegd
+ Uses the operating system provided Entropy Gathering Daemon (EGD).
+ The EGD basically uses the same algorithms as rndunix does.
+ However as a system daemon it keeps on running and thus can serve
+ several processes requiring entropy input and does not waste
+ collected entropy if the application does not need all the
+ collected entropy. It is not available in FIPS mode.
+
+rndw32
+ Targeted for the Microsoft Windows OS. It uses certain properties
+ of that system and is the only gathering module available for that
+ OS.
+
+rndhw
+ Extra module to collect additional entropy by utilizing a hardware
+ random number generator. As of now the supported hardware RNG is
+ the Padlock engine of VIA (Centaur) CPUs and x86 CPUs with the
+ RDRAND instruction. It is not available in FIPS mode.
+
+rndjent
+ Extra module to collect additional entropy using a CPU jitter based
+ approach. This is only used on X86 hardware where the RDTSC opcode
+ is available. The '/dev/gcrypt/random.conf' config option
+ 'disable-jent' can be used to inhibit the use of this module.
+
+* Menu:
+
+* CSPRNG Description:: Description of the CSPRNG.
+* FIPS PRNG Description:: Description of the FIPS X9.31 PRNG.
+
+
+File: gcrypt.info, Node: CSPRNG Description, Next: FIPS PRNG Description, Up: Random-Number Subsystem Architecture
+
+17.6.1 Description of the CSPRNG
+--------------------------------
+
+This random number generator is loosely modelled after the one described
+in Peter Gutmann's paper: "Software Generation of Practically Strong
+Random Numbers".(1)
+
+ A pool of 600 bytes is used and mixed using the core SHA-1 hash
+transform function. Several extra features are used to make the robust
+against a wide variety of attacks and to protect against failures of
+subsystems. The state of the generator may be saved to a file and
+initially seed form a file.
+
+ Depending on how Libgcrypt was build the generator is able to select
+the best working entropy gathering module. It makes use of the slow and
+fast collection methods and requires the pool to initially seeded form
+the slow gatherer or a seed file. An entropy estimation is used to mix
+in enough data from the gather modules before returning the actual
+random output. Process fork detection and protection is implemented.
+
+ The implementation of the nonce generator (for 'gcry_create_nonce')
+is a straightforward repeated hash design: A 28 byte buffer is initially
+seeded with the PID and the time in seconds in the first 20 bytes and
+with 8 bytes of random taken from the 'GCRY_STRONG_RANDOM' generator.
+Random numbers are then created by hashing all the 28 bytes with SHA-1
+and saving that again in the first 20 bytes. The hash is also returned
+as result.
+
+ ---------- Footnotes ----------
+
+ (1) Also described in chapter 6 of his book "Cryptographic Security
+Architecture", New York, 2004, ISBN 0-387-95387-6.
+
+
+File: gcrypt.info, Node: FIPS PRNG Description, Prev: CSPRNG Description, Up: Random-Number Subsystem Architecture
+
+17.6.2 Description of the FIPS X9.31 PRNG
+-----------------------------------------
+
+The core of this deterministic random number generator is implemented
+according to the document "NIST-Recommended Random Number Generator
+Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES and AES
+Algorithms", dated 2005-01-31. This implementation uses the AES
+variant.
+
+ The generator is based on contexts to utilize the same core functions
+for all random levels as required by the high-level interface. All
+random generators return their data in 128 bit blocks. If the caller
+requests less bits, the extra bits are not used. The key for each
+generator is only set once at the first time a generator context is
+used. The seed value is set along with the key and again after 1000
+output blocks.
+
+ On Unix like systems the 'GCRY_VERY_STRONG_RANDOM' and
+'GCRY_STRONG_RANDOM' generators are keyed and seeded using the rndlinux
+module with the '/dev/random' device. Thus these generators may block
+until the OS kernel has collected enough entropy. When used with
+Microsoft Windows the rndw32 module is used instead.
+
+ The generator used for 'gcry_create_nonce' is keyed and seeded from
+the 'GCRY_STRONG_RANDOM' generator. Thus is may also block if the
+'GCRY_STRONG_RANDOM' generator has not yet been used before and thus
+gets initialized on the first use by 'gcry_create_nonce'. This special
+treatment is justified by the weaker requirements for a nonce generator
+and to save precious kernel entropy for use by the "real" random
+generators.
+
+ A self-test facility uses a separate context to check the
+functionality of the core X9.31 functions using a known answers test.
+During runtime each output block is compared to the previous one to
+detect a stuck generator.
+
+ The DT value for the generator is made up of the current time down to
+microseconds (if available) and a free running 64 bit counter. When
+used with the test context the DT value is taken from the context and
+incremented on each use.
+
+
+File: gcrypt.info, Node: Self-Tests, Next: FIPS Mode, Prev: Architecture, Up: Top
+
+Appendix A Description of the Self-Tests
+****************************************
+
+In addition to the build time regression test suite, Libgcrypt
+implements self-tests to be performed at runtime. Which self-tests are
+actually used depends on the mode Libgcrypt is used in. In standard
+mode a limited set of self-tests is run at the time an algorithm is
+first used. Note that not all algorithms feature a self-test in
+standard mode. The 'GCRYCTL_SELFTEST' control command may be used to
+run all implemented self-tests at any time; this will even run more
+tests than those run in FIPS mode.
+
+ If any of the self-tests fails, the library immediately returns an
+error code to the caller. If Libgcrypt is in FIPS mode the self-tests
+will be performed within the "Self-Test" state and any failure puts the
+library into the "Error" state.
+
+A.1 Power-Up Tests
+==================
+
+Power-up tests are only performed if Libgcrypt is in FIPS mode.
+
+A.1.1 Symmetric Cipher Algorithm Power-Up Tests
+-----------------------------------------------
+
+The following symmetric encryption algorithm tests are run during
+power-up:
+
+3DES
+ To test the 3DES 3-key EDE encryption in ECB mode these tests are
+ run:
+ 1. A known answer test is run on a 64 bit test vector processed
+ by 64 rounds of Single-DES block encryption and decryption
+ using a key changed with each round.
+ 2. A known answer test is run on a 64 bit test vector processed
+ by 16 rounds of 2-key and 3-key Triple-DES block encryption
+ and decryptions using a key changed with each round.
+ 3. 10 known answer tests using 3-key Triple-DES EDE encryption,
+ comparing the ciphertext to the known value, then running a
+ decryption and comparing it to the initial plaintext.
+ ('cipher/des.c:selftest')
+
+AES-128
+ A known answer tests is run using one test vector and one test key
+ with AES in ECB mode. ('cipher/rijndael.c:selftest_basic_128')
+
+AES-192
+ A known answer tests is run using one test vector and one test key
+ with AES in ECB mode. ('cipher/rijndael.c:selftest_basic_192')
+
+AES-256
+ A known answer tests is run using one test vector and one test key
+ with AES in ECB mode. ('cipher/rijndael.c:selftest_basic_256')
+
+A.1.2 Hash Algorithm Power-Up Tests
+-----------------------------------
+
+The following hash algorithm tests are run during power-up:
+
+SHA-1
+ A known answer test using the string '"abc"' is run.
+ ('cipher/sha1.c:selftests_sha1')
+SHA-224
+ A known answer test using the string '"abc"' is run.
+ ('cipher/sha256.c:selftests_sha224')
+SHA-256
+ A known answer test using the string '"abc"' is run.
+ ('cipher/sha256.c:selftests_sha256')
+SHA-384
+ A known answer test using the string '"abc"' is run.
+ ('cipher/sha512.c:selftests_sha384')
+SHA-512
+ A known answer test using the string '"abc"' is run.
+ ('cipher/sha512.c:selftests_sha512')
+
+A.1.3 MAC Algorithm Power-Up Tests
+----------------------------------
+
+The following MAC algorithm tests are run during power-up:
+
+HMAC SHA-1
+ A known answer test using 9 byte of data and a 64 byte key is run.
+ ('cipher/hmac-tests.c:selftests_sha1')
+HMAC SHA-224
+ A known answer test using 28 byte of data and a 4 byte key is run.
+ ('cipher/hmac-tests.c:selftests_sha224')
+HMAC SHA-256
+ A known answer test using 28 byte of data and a 4 byte key is run.
+ ('cipher/hmac-tests.c:selftests_sha256')
+HMAC SHA-384
+ A known answer test using 28 byte of data and a 4 byte key is run.
+ ('cipher/hmac-tests.c:selftests_sha384')
+HMAC SHA-512
+ A known answer test using 28 byte of data and a 4 byte key is run.
+ ('cipher/hmac-tests.c:selftests_sha512')
+
+A.1.4 Random Number Power-Up Test
+---------------------------------
+
+The DRNG is tested during power-up this way:
+
+ 1. Requesting one block of random using the public interface to check
+ general working and the duplicated block detection.
+ 2. 3 know answer tests using pre-defined keys, seed and initial DT
+ values. For each test 3 blocks of 16 bytes are requested and
+ compared to the expected result. The DT value is incremented for
+ each block.
+
+A.1.5 Public Key Algorithm Power-Up Tests
+-----------------------------------------
+
+The public key algorithms are tested during power-up:
+
+RSA
+ A pre-defined 1024 bit RSA key is used and these tests are run in
+ turn:
+ 1. Conversion of S-expression to internal format.
+ ('cipher/rsa.c:selftests_rsa')
+ 2. Private key consistency check. ('cipher/rsa.c:selftests_rsa')
+ 3. A pre-defined 20 byte value is signed with PKCS#1 padding for
+ SHA-1. The result is verified using the public key against
+ the original data and against modified data.
+ ('cipher/rsa.c:selftest_sign_1024')
+ 4. A 1000 bit random value is encrypted and checked that it does
+ not match the original random value. The encrypted result is
+ then decrypted and checked that it matches the original random
+ value. ('cipher/rsa.c:selftest_encr_1024')
+
+DSA
+ A pre-defined 1024 bit DSA key is used and these tests are run in
+ turn:
+ 1. Conversion of S-expression to internal format.
+ ('cipher/dsa.c:selftests_dsa')
+ 2. Private key consistency check. ('cipher/dsa.c:selftests_dsa')
+ 3. A pre-defined 20 byte value is signed with PKCS#1 padding for
+ SHA-1. The result is verified using the public key against
+ the original data and against modified data.
+ ('cipher/dsa.c:selftest_sign_1024')
+
+A.1.6 Integrity Power-Up Tests
+------------------------------
+
+The integrity of the Libgcrypt is tested during power-up but only if
+checking has been enabled at build time. The check works by computing a
+HMAC SHA-256 checksum over the file used to load Libgcrypt into memory.
+That checksum is compared against a checksum stored in a file of the
+same name but with a single dot as a prefix and a suffix of '.hmac'.
+
+A.1.7 Critical Functions Power-Up Tests
+---------------------------------------
+
+The 3DES weak key detection is tested during power-up by calling the
+detection function with keys taken from a table listening all weak keys.
+The table itself is protected using a SHA-1 hash.
+('cipher/des.c:selftest')
+
+A.2 Conditional Tests
+=====================
+
+The conditional tests are performed if a certain condition is met. This
+may occur at any time; the library does not necessary enter the
+"Self-Test" state to run these tests but will transit to the "Error"
+state if a test failed.
+
+A.2.1 Key-Pair Generation Tests
+-------------------------------
+
+After an asymmetric key-pair has been generated, Libgcrypt runs a
+pair-wise consistency tests on the generated key. On failure the
+generated key is not used, an error code is returned and, if in FIPS
+mode, the library is put into the "Error" state.
+
+RSA
+ The test uses a random number 64 bits less the size of the modulus
+ as plaintext and runs an encryption and decryption operation in
+ turn. The encrypted value is checked to not match the plaintext
+ and the result of the decryption is checked to match the plaintext.
+
+ A new random number of the same size is generated, signed and
+ verified to test the correctness of the signing operation. As a
+ second signing test, the signature is modified by incrementing its
+ value and then verified with the expected result that the
+ verification fails. ('cipher/rsa.c:test_keys')
+DSA
+ The test uses a random number of the size of the Q parameter to
+ create a signature and then checks that the signature verifies. As
+ a second signing test, the data is modified by incrementing its
+ value and then verified against the signature with the expected
+ result that the verification fails. ('cipher/dsa.c:test_keys')
+
+A.2.2 Software Load Tests
+-------------------------
+
+No code is loaded at runtime.
+
+A.2.3 Manual Key Entry Tests
+----------------------------
+
+A manual key entry feature is not implemented in Libgcrypt.
+
+A.2.4 Continuous RNG Tests
+--------------------------
+
+The continuous random number test is only used in FIPS mode. The RNG
+generates blocks of 128 bit size; the first block generated per context
+is saved in the context and another block is generated to be returned to
+the caller. Each block is compared against the saved block and then
+stored in the context. If a duplicated block is detected an error is
+signaled and the library is put into the "Fatal-Error" state.
+('random/random-fips.c:x931_aes_driver')
+
+A.3 Application Requested Tests
+===============================
+
+The application may requests tests at any time by means of the
+'GCRYCTL_SELFTEST' control command. Note that using these tests is not
+FIPS conform: Although Libgcrypt rejects all application requests for
+services while running self-tests, it does not ensure that no other
+operations of Libgcrypt are still being executed. Thus, in FIPS mode an
+application requesting self-tests needs to power-cycle Libgcrypt
+instead.
+
+ When self-tests are requested, Libgcrypt runs all the tests it does
+during power-up as well as a few extra checks as described below.
+
+A.3.1 Symmetric Cipher Algorithm Tests
+--------------------------------------
+
+The following symmetric encryption algorithm tests are run in addition
+to the power-up tests:
+
+AES-128
+ A known answer tests with test vectors taken from NIST SP800-38a
+ and using the high level functions is run for block modes CFB and
+ OFB.
+
+A.3.2 Hash Algorithm Tests
+--------------------------
+
+The following hash algorithm tests are run in addition to the power-up
+tests:
+
+SHA-1
+SHA-224
+SHA-256
+ 1. A known answer test using a 56 byte string is run.
+ 2. A known answer test using a string of one million letters "a"
+ is run.
+ ('cipher/sha1.c:selftests_sha1',
+ 'cipher/sha256.c:selftests_sha224',
+ 'cipher/sha256.c:selftests_sha256')
+SHA-384
+SHA-512
+ 1. A known answer test using a 112 byte string is run.
+ 2. A known answer test using a string of one million letters "a"
+ is run.
+ ('cipher/sha512.c:selftests_sha384',
+ 'cipher/sha512.c:selftests_sha512')
+
+A.3.3 MAC Algorithm Tests
+-------------------------
+
+The following MAC algorithm tests are run in addition to the power-up
+tests:
+
+HMAC SHA-1
+ 1. A known answer test using 9 byte of data and a 20 byte key is
+ run.
+ 2. A known answer test using 9 byte of data and a 100 byte key is
+ run.
+ 3. A known answer test using 9 byte of data and a 49 byte key is
+ run.
+ ('cipher/hmac-tests.c:selftests_sha1')
+HMAC SHA-224
+HMAC SHA-256
+HMAC SHA-384
+HMAC SHA-512
+ 1. A known answer test using 9 byte of data and a 20 byte key is
+ run.
+ 2. A known answer test using 50 byte of data and a 20 byte key is
+ run.
+ 3. A known answer test using 50 byte of data and a 26 byte key is
+ run.
+ 4. A known answer test using 54 byte of data and a 131 byte key
+ is run.
+ 5. A known answer test using 152 byte of data and a 131 byte key
+ is run.
+ ('cipher/hmac-tests.c:selftests_sha224',
+ 'cipher/hmac-tests.c:selftests_sha256',
+ 'cipher/hmac-tests.c:selftests_sha384',
+ 'cipher/hmac-tests.c:selftests_sha512')
+
+
+File: gcrypt.info, Node: FIPS Mode, Next: Library Copying, Prev: Self-Tests, Up: Top
+
+Appendix B Description of the FIPS Mode
+***************************************
+
+This appendix gives detailed information pertaining to the FIPS mode.
+In particular, the changes to the standard mode and the finite state
+machine are described. The self-tests required in this mode are
+described in the appendix on self-tests.
+
+B.1 Restrictions in FIPS Mode
+=============================
+
+If Libgcrypt is used in FIPS mode these restrictions are effective:
+
+ * The cryptographic algorithms are restricted to this list:
+
+ GCRY_CIPHER_3DES
+ 3 key EDE Triple-DES symmetric encryption.
+ GCRY_CIPHER_AES128
+ AES 128 bit symmetric encryption.
+ GCRY_CIPHER_AES192
+ AES 192 bit symmetric encryption.
+ GCRY_CIPHER_AES256
+ AES 256 bit symmetric encryption.
+ GCRY_MD_SHA1
+ SHA-1 message digest.
+ GCRY_MD_SHA224
+ SHA-224 message digest.
+ GCRY_MD_SHA256
+ SHA-256 message digest.
+ GCRY_MD_SHA384
+ SHA-384 message digest.
+ GCRY_MD_SHA512
+ SHA-512 message digest.
+ GCRY_MD_SHA1,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-1 message digest.
+ GCRY_MD_SHA224,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-224 message digest.
+ GCRY_MD_SHA256,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-256 message digest.
+ GCRY_MD_SHA384,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-384 message digest.
+ GCRY_MD_SHA512,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-512 message digest.
+ GCRY_PK_RSA
+ RSA encryption and signing.
+ GCRY_PK_DSA
+ DSA signing.
+
+ Note that the CRC algorithms are not considered cryptographic
+ algorithms and thus are in addition available.
+
+ * RSA key generation refuses to create a key with a keysize of less
+ than 1024 bits.
+
+ * DSA key generation refuses to create a key with a keysize other
+ than 1024 bits.
+
+ * The 'transient-key' flag for RSA and DSA key generation is ignored.
+
+ * Support for the VIA Padlock engine is disabled.
+
+ * FIPS mode may only be used on systems with a /dev/random device.
+ Switching into FIPS mode on other systems will fail at runtime.
+
+ * Saving and loading a random seed file is ignored.
+
+ * An X9.31 style random number generator is used in place of the
+ large-pool-CSPRNG generator.
+
+ * The command 'GCRYCTL_ENABLE_QUICK_RANDOM' is ignored.
+
+ * Message digest debugging is disabled.
+
+ * All debug output related to cryptographic data is suppressed.
+
+ * On-the-fly self-tests are not performed, instead self-tests are run
+ before entering operational state.
+
+ * The function 'gcry_set_allocation_handler' may not be used. If it
+ is used Libgcrypt disables FIPS mode unless Enforced FIPS mode is
+ enabled, in which case Libgcrypt will enter the error state.
+
+ * The digest algorithm MD5 may not be used. If it is used Libgcrypt
+ disables FIPS mode unless Enforced FIPS mode is enabled, in which
+ case Libgcrypt will enter the error state.
+
+ * In Enforced FIPS mode the command 'GCRYCTL_DISABLE_SECMEM' is
+ ignored. In standard FIPS mode it disables FIPS mode.
+
+ * A handler set by 'gcry_set_outofcore_handler' is ignored.
+ * A handler set by 'gcry_set_fatalerror_handler' is ignored.
+
+ Note that when we speak about disabling FIPS mode, it merely means
+that the function 'gcry_fips_mode_active' returns false; it does not
+mean that any non FIPS algorithms are allowed.
+
+B.2 FIPS Finite State Machine
+=============================
+
+The FIPS mode of libgcrypt implements a finite state machine (FSM) using
+8 states (*note Table B.1: tbl:fips-states.) and checks at runtime that
+only valid transitions (*note Table B.2: tbl:fips-state-transitions.)
+may happen.
+
+
+
+Figure B.1: FIPS mode state diagram
+
+States used by the FIPS FSM:
+
+Power-Off
+ Libgcrypt is not runtime linked to another application. This
+ usually means that the library is not loaded into main memory.
+ This state is documentation only.
+
+Power-On
+ Libgcrypt is loaded into memory and API calls may be made.
+ Compiler introduced constructor functions may be run. Note that
+ Libgcrypt does not implement any arbitrary constructor functions to
+ be called by the operating system
+
+Init
+ The Libgcrypt initialization functions are performed and the
+ library has not yet run any self-test.
+
+Self-Test
+ Libgcrypt is performing self-tests.
+
+Operational
+ Libgcrypt is in the operational state and all interfaces may be
+ used.
+
+Error
+ Libgrypt is in the error state. When calling any FIPS relevant
+ interfaces they either return an error ('GPG_ERR_NOT_OPERATIONAL')
+ or put Libgcrypt into the Fatal-Error state and won't return.
+
+Fatal-Error
+ Libgcrypt is in a non-recoverable error state and will
+ automatically transit into the Shutdown state.
+
+Shutdown
+ Libgcrypt is about to be terminated and removed from the memory.
+ The application may at this point still running cleanup handlers.
+
+Table B.1: FIPS mode states
+
+The valid state transitions (*note Figure B.1: fig:fips-fsm.) are:
+'1'
+ Power-Off to Power-On is implicitly done by the OS loading
+ Libgcrypt as a shared library and having it linked to an
+ application.
+
+'2'
+ Power-On to Init is triggered by the application calling the
+ Libgcrypt initialization function 'gcry_check_version'.
+
+'3'
+ Init to Self-Test is either triggered by a dedicated API call or
+ implicit by invoking a libgrypt service controlled by the FSM.
+
+'4'
+ Self-Test to Operational is triggered after all self-tests passed
+ successfully.
+
+'5'
+ Operational to Shutdown is an artificial state without any direct
+ action in Libgcrypt. When reaching the Shutdown state the library
+ is deinitialized and can't return to any other state again.
+
+'6'
+ Shutdown to Power-off is the process of removing Libgcrypt from the
+ computer's memory. For obvious reasons the Power-Off state can't
+ be represented within Libgcrypt and thus this transition is for
+ documentation only.
+
+'7'
+ Operational to Error is triggered if Libgcrypt detected an
+ application error which can't be returned to the caller but still
+ allows Libgcrypt to properly run. In the Error state all FIPS
+ relevant interfaces return an error code.
+
+'8'
+ Error to Shutdown is similar to the Operational to Shutdown
+ transition (5).
+
+'9'
+ Error to Fatal-Error is triggered if Libgrypt detects an fatal
+ error while already being in Error state.
+
+'10'
+ Fatal-Error to Shutdown is automatically entered by Libgcrypt after
+ having reported the error.
+
+'11'
+ Power-On to Shutdown is an artificial state to document that
+ Libgcrypt has not ye been initialized but the process is about to
+ terminate.
+
+'12'
+ Power-On to Fatal-Error will be triggered if certain Libgcrypt
+ functions are used without having reached the Init state.
+
+'13'
+ Self-Test to Fatal-Error is triggered by severe errors in Libgcrypt
+ while running self-tests.
+
+'14'
+ Self-Test to Error is triggered by a failed self-test.
+
+'15'
+ Operational to Fatal-Error is triggered if Libcrypt encountered a
+ non-recoverable error.
+
+'16'
+ Operational to Self-Test is triggered if the application requested
+ to run the self-tests again.
+
+'17'
+ Error to Self-Test is triggered if the application has requested to
+ run self-tests to get to get back into operational state after an
+ error.
+
+'18'
+ Init to Error is triggered by errors in the initialization code.
+
+'19'
+ Init to Fatal-Error is triggered by non-recoverable errors in the
+ initialization code.
+
+'20'
+ Error to Error is triggered by errors while already in the Error
+ state.
+
+Table B.2: FIPS mode state transitions
+
+B.3 FIPS Miscellaneous Information
+==================================
+
+Libgcrypt does not do any key management on itself; the application
+needs to care about it. Keys which are passed to Libgcrypt should be
+allocated in secure memory as available with the functions
+'gcry_malloc_secure' and 'gcry_calloc_secure'. By calling 'gcry_free'
+on this memory, the memory and thus the keys are overwritten with zero
+bytes before releasing the memory.
+
+ For use with the random number generator, Libgcrypt generates 3
+internal keys which are stored in the encryption contexts used by the
+RNG. These keys are stored in secure memory for the lifetime of the
+process. Application are required to use 'GCRYCTL_TERM_SECMEM' before
+process termination. This will zero out the entire secure memory and
+thus also the encryption contexts with these keys.
+
+
+File: gcrypt.info, Node: Library Copying, Next: Copying, Prev: FIPS Mode, Up: Top
+
+GNU Lesser General Public License
+*********************************
+
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ [This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence the
+ version number 2.1.]
+
+Preamble
+========
+
+The licenses for most software are designed to take away your freedom to
+share and change it. By contrast, the GNU General Public Licenses are
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software--typically libraries--of the Free Software
+Foundation and other authors who decide to use it. You can use it too,
+but we suggest you first think carefully about whether this license or
+the ordinary General Public License is the better strategy to use in any
+particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of it
+in new free programs; and that you are informed that you can do these
+things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling it.
+And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that there
+is no warranty for the free library. Also, if the library is modified
+by someone else and passed on, the recipients should know that what they
+have is not the original version, so that the original author's
+reputation will not be affected by problems that might be introduced by
+others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that any
+patent license obtained for a version of the library must be consistent
+with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and is
+quite different from the ordinary General Public License. We use this
+license for certain libraries in order to permit linking those libraries
+into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the entire
+combination fits its criteria of freedom. The Lesser General Public
+License permits more lax criteria for linking other code with the
+library.
+
+ We call this license the "Lesser" General Public License because it
+does _Less_ to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less of
+an advantage over competing non-free programs. These disadvantages are
+the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free library
+does the same job as widely used non-free libraries. In this case,
+there is little to gain by limiting the free library to free software
+only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of free
+software. For example, permission to use the GNU C Library in non-free
+programs enables many more people to use the whole GNU operating system,
+as well as its variant, the GNU/Linux operating system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is linked
+with the Library has the freedom and the wherewithal to run that program
+using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+ program which contains a notice placed by the copyright holder or
+ other authorized party saying it may be distributed under the terms
+ of this Lesser General Public License (also called "this License").
+ Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+ prepared so as to be conveniently linked with application programs
+ (which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+ which has been distributed under these terms. A "work based on the
+ Library" means either the Library or any derivative work under
+ copyright law: that is to say, a work containing the Library or a
+ portion of it, either verbatim or with modifications and/or
+ translated straightforwardly into another language. (Hereinafter,
+ translation is included without limitation in the term
+ "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+ making modifications to it. For a library, complete source code
+ means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to
+ control compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are
+ not covered by this License; they are outside its scope. The act
+ of running a program using the Library is not restricted, and
+ output from such a program is covered only if its contents
+ constitute a work based on the Library (independent of the use of
+ the Library in a tool for writing it). Whether that is true
+ depends on what the Library does and what the program that uses the
+ Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+ complete source code as you receive it, in any medium, provided
+ that you conspicuously and appropriately publish on each copy an
+ appropriate copyright notice and disclaimer of warranty; keep
+ intact all the notices that refer to this License and to the
+ absence of any warranty; and distribute a copy of this License
+ along with the Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+ and you may at your option offer warranty protection in exchange
+ for a fee.
+
+ 2. You may modify your copy or copies of the Library or any portion of
+ it, thus forming a work based on the Library, and copy and
+ distribute such modifications or work under the terms of Section 1
+ above, provided that you also meet all of these conditions:
+
+ a. The modified work must itself be a software library.
+
+ b. You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c. You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d. If a facility in the modified Library refers to a function or
+ a table of data to be supplied by an application program that
+ uses the facility, other than as an argument passed when the
+ facility is invoked, then you must make a good faith effort to
+ ensure that, in the event an application does not supply such
+ function or table, the facility still operates, and performs
+ whatever part of its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots
+ has a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function
+ must be optional: if the application does not supply it, the
+ square root function must still compute square roots.)
+
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the
+ Library, and can be reasonably considered independent and separate
+ works in themselves, then this License, and its terms, do not apply
+ to those sections when you distribute them as separate works. But
+ when you distribute the same sections as part of a whole which is a
+ work based on the Library, the distribution of the whole must be on
+ the terms of this License, whose permissions for other licensees
+ extend to the entire whole, and thus to each and every part
+ regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or
+ contest your rights to work written entirely by you; rather, the
+ intent is to exercise the right to control the distribution of
+ derivative or collective works based on the Library.
+
+ In addition, mere aggregation of another work not based on the
+ Library with the Library (or with a work based on the Library) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+ License instead of this License to a given copy of the Library. To
+ do this, you must alter all the notices that refer to this License,
+ so that they refer to the ordinary GNU General Public License,
+ version 2, instead of to this License. (If a newer version than
+ version 2 of the ordinary GNU General Public License has appeared,
+ then you can specify that version instead if you wish.) Do not
+ make any other change in these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+ that copy, so the ordinary GNU General Public License applies to
+ all subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or derivative
+ of it, under Section 2) in object code or executable form under the
+ terms of Sections 1 and 2 above provided that you accompany it with
+ the complete corresponding machine-readable source code, which must
+ be distributed under the terms of Sections 1 and 2 above on a
+ medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+ from a designated place, then offering equivalent access to copy
+ the source code from the same place satisfies the requirement to
+ distribute the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+ Library, but is designed to work with the Library by being compiled
+ or linked with it, is called a "work that uses the Library". Such
+ a work, in isolation, is not a derivative work of the Library, and
+ therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+ creates an executable that is a derivative of the Library (because
+ it contains portions of the Library), rather than a "work that uses
+ the library". The executable is therefore covered by this License.
+ Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header
+ file that is part of the Library, the object code for the work may
+ be a derivative work of the Library even though the source code is
+ not. Whether this is true is especially significant if the work
+ can be linked without the Library, or if the work is itself a
+ library. The threshold for this to be true is not precisely
+ defined by law.
+
+ If such an object file uses only numerical parameters, data
+ structure layouts and accessors, and small macros and small inline
+ functions (ten lines or less in length), then the use of the object
+ file is unrestricted, regardless of whether it is legally a
+ derivative work. (Executables containing this object code plus
+ portions of the Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+ distribute the object code for the work under the terms of Section
+ 6. Any executables containing that work also fall under Section 6,
+ whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or link
+ a "work that uses the Library" with the Library to produce a work
+ containing portions of the Library, and distribute that work under
+ terms of your choice, provided that the terms permit modification
+ of the work for the customer's own use and reverse engineering for
+ debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered
+ by this License. You must supply a copy of this License. If the
+ work during execution displays copyright notices, you must include
+ the copyright notice for the Library among them, as well as a
+ reference directing the user to the copy of this License. Also,
+ you must do one of these things:
+
+ a. Accompany the work with the complete corresponding
+ machine-readable source code for the Library including
+ whatever changes were used in the work (which must be
+ distributed under Sections 1 and 2 above); and, if the work is
+ an executable linked with the Library, with the complete
+ machine-readable "work that uses the Library", as object code
+ and/or source code, so that the user can modify the Library
+ and then relink to produce a modified executable containing
+ the modified Library. (It is understood that the user who
+ changes the contents of definitions files in the Library will
+ not necessarily be able to recompile the application to use
+ the modified definitions.)
+
+ b. Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run
+ time a copy of the library already present on the user's
+ computer system, rather than copying library functions into
+ the executable, and (2) will operate properly with a modified
+ version of the library, if the user installs one, as long as
+ the modified version is interface-compatible with the version
+ that the work was made with.
+
+ c. Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ d. If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the
+ above specified materials from the same place.
+
+ e. Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+ Library" must include any data and utility programs needed for
+ reproducing the executable from it. However, as a special
+ exception, the materials to be distributed need not include
+ anything that is normally distributed (in either source or binary
+ form) with the major components (compiler, kernel, and so on) of
+ the operating system on which the executable runs, unless that
+ component itself accompanies the executable.
+
+ It may happen that this requirement contradicts the license
+ restrictions of other proprietary libraries that do not normally
+ accompany the operating system. Such a contradiction means you
+ cannot use both them and the Library together in an executable that
+ you distribute.
+
+ 7. You may place library facilities that are a work based on the
+ Library side-by-side in a single library together with other
+ library facilities not covered by this License, and distribute such
+ a combined library, provided that the separate distribution of the
+ work based on the Library and of the other library facilities is
+ otherwise permitted, and provided that you do these two things:
+
+ a. Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b. Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same
+ work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute the
+ Library except as expressly provided under this License. Any
+ attempt otherwise to copy, modify, sublicense, link with, or
+ distribute the Library is void, and will automatically terminate
+ your rights under this License. However, parties who have received
+ copies, or rights, from you under this License will not have their
+ licenses terminated so long as such parties remain in full
+ compliance.
+
+ 9. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify
+ or distribute the Library or its derivative works. These actions
+ are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Library (or any work
+ based on the Library), you indicate your acceptance of this License
+ to do so, and all its terms and conditions for copying,
+ distributing or modifying the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+ Library), the recipient automatically receives a license from the
+ original licensor to copy, distribute, link with or modify the
+ Library subject to these terms and conditions. You may not impose
+ any further restrictions on the recipients' exercise of the rights
+ granted herein. You are not responsible for enforcing compliance
+ by third parties with this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent
+ issues), conditions are imposed on you (whether by court order,
+ agreement or otherwise) that contradict the conditions of this
+ License, they do not excuse you from the conditions of this
+ License. If you cannot distribute so as to satisfy simultaneously
+ your obligations under this License and any other pertinent
+ obligations, then as a consequence you may not distribute the
+ Library at all. For example, if a patent license would not permit
+ royalty-free redistribution of the Library by all those who receive
+ copies directly or indirectly through you, then the only way you
+ could satisfy both it and this License would be to refrain entirely
+ from distribution of the Library.
+
+ If any portion of this section is held invalid or unenforceable
+ under any particular circumstance, the balance of the section is
+ intended to apply, and the section as a whole is intended to apply
+ in other circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of
+ any such claims; this section has the sole purpose of protecting
+ the integrity of the free software distribution system which is
+ implemented by public license practices. Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is
+ willing to distribute software through any other system and a
+ licensee cannot impose that choice.
+
+ This section is intended to make thoroughly clear what is believed
+ to be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+ certain countries either by patents or by copyrighted interfaces,
+ the original copyright holder who places the Library under this
+ License may add an explicit geographical distribution limitation
+ excluding those countries, so that distribution is permitted only
+ in or among countries not thus excluded. In such case, this
+ License incorporates the limitation as if written in the body of
+ this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+ versions of the Lesser General Public License from time to time.
+ Such new versions will be similar in spirit to the present version,
+ but may differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+ Library specifies a version number of this License which applies to
+ it and "any later version", you have the option of following the
+ terms and conditions either of that version or of any later version
+ published by the Free Software Foundation. If the Library does not
+ specify a license version number, you may choose any version ever
+ published by the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+ programs whose distribution conditions are incompatible with these,
+ write to the author to ask for permission. For software which is
+ copyrighted by the Free Software Foundation, write to the Free
+ Software Foundation; we sometimes make exceptions for this. Our
+ decision will be guided by the two goals of preserving the free
+ status of all derivatives of our free software and of promoting the
+ sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+ WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
+ LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS
+ AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY
+ OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+ PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE
+ DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
+ OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
+ MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+ INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
+ OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY
+ OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+==============================================
+
+If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of
+the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should have
+at least the "copyright" line and a pointer to where the full notice is
+found.
+
+ ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES.
+ Copyright (C) YEAR NAME OF AUTHOR
+
+ This library 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.
+
+ This library 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 library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ USA.
+
+ Also add information on how to contact you by electronic and paper
+mail.
+
+ You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the library
+ `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ SIGNATURE OF TY COON, 1 April 1990
+ Ty Coon, President of Vice
+
+ That's all there is to it!
+
+
+File: gcrypt.info, Node: Copying, Next: Figures and Tables, Prev: Library Copying, Up: Top
+
+GNU General Public License
+**************************
+
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Preamble
+========
+
+The licenses for most software are designed to take away your freedom to
+share and change it. By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users. This General Public
+License applies to most of the Free Software Foundation's software and
+to any other program whose authors commit to using it. (Some other Free
+Software Foundation software is covered by the GNU Library General
+Public License instead.) You can apply it to your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it if
+you want it, that you can change the software or use pieces of it in new
+free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software,
+and (2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 1. This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The "Program",
+ below, refers to any such program or work, and a "work based on the
+ Program" means either the Program or any derivative work under
+ copyright law: that is to say, a work containing the Program or a
+ portion of it, either verbatim or with modifications and/or
+ translated into another language. (Hereinafter, translation is
+ included without limitation in the term "modification".) Each
+ licensee is addressed as "you".
+
+ Activities other than copying, distribution and modification are
+ not covered by this License; they are outside its scope. The act
+ of running the Program is not restricted, and the output from the
+ Program is covered only if its contents constitute a work based on
+ the Program (independent of having been made by running the
+ Program). Whether that is true depends on what the Program does.
+
+ 2. You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you
+ conspicuously and appropriately publish on each copy an appropriate
+ copyright notice and disclaimer of warranty; keep intact all the
+ notices that refer to this License and to the absence of any
+ warranty; and give any other recipients of the Program a copy of
+ this License along with the Program.
+
+ You may charge a fee for the physical act of transferring a copy,
+ and you may at your option offer warranty protection in exchange
+ for a fee.
+
+ 3. You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and
+ distribute such modifications or work under the terms of Section 1
+ above, provided that you also meet all of these conditions:
+
+ a. You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b. You must cause any work that you distribute or publish, that
+ in whole or in part contains or is derived from the Program or
+ any part thereof, to be licensed as a whole at no charge to
+ all third parties under the terms of this License.
+
+ c. If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display
+ an announcement including an appropriate copyright notice and
+ a notice that there is no warranty (or else, saying that you
+ provide a warranty) and that users may redistribute the
+ program under these conditions, and telling the user how to
+ view a copy of this License. (Exception: if the Program
+ itself is interactive but does not normally print such an
+ announcement, your work based on the Program is not required
+ to print an announcement.)
+
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the
+ Program, and can be reasonably considered independent and separate
+ works in themselves, then this License, and its terms, do not apply
+ to those sections when you distribute them as separate works. But
+ when you distribute the same sections as part of a whole which is a
+ work based on the Program, the distribution of the whole must be on
+ the terms of this License, whose permissions for other licensees
+ extend to the entire whole, and thus to each and every part
+ regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or
+ contest your rights to work written entirely by you; rather, the
+ intent is to exercise the right to control the distribution of
+ derivative or collective works based on the Program.
+
+ In addition, mere aggregation of another work not based on the
+ Program with the Program (or with a work based on the Program) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.
+
+ 4. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms
+ of Sections 1 and 2 above provided that you also do one of the
+ following:
+
+ a. Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Sections 1 and 2 above on a medium customarily used for
+ software interchange; or,
+
+ b. Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a
+ medium customarily used for software interchange; or,
+
+ c. Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with
+ such an offer, in accord with Subsection b above.)
+
+ The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete
+ source code means all the source code for all modules it contains,
+ plus any associated interface definition files, plus the scripts
+ used to control compilation and installation of the executable.
+ However, as a special exception, the source code distributed need
+ not include anything that is normally distributed (in either source
+ or binary form) with the major components (compiler, kernel, and so
+ on) of the operating system on which the executable runs, unless
+ that component itself accompanies the executable.
+
+ If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+
+ 5. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+ void, and will automatically terminate your rights under this
+ License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses terminated
+ so long as such parties remain in full compliance.
+
+ 6. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify
+ or distribute the Program or its derivative works. These actions
+ are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Program (or any work
+ based on the Program), you indicate your acceptance of this License
+ to do so, and all its terms and conditions for copying,
+ distributing or modifying the Program or works based on it.
+
+ 7. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject
+ to these terms and conditions. You may not impose any further
+ restrictions on the recipients' exercise of the rights granted
+ herein. You are not responsible for enforcing compliance by third
+ parties to this License.
+
+ 8. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent
+ issues), conditions are imposed on you (whether by court order,
+ agreement or otherwise) that contradict the conditions of this
+ License, they do not excuse you from the conditions of this
+ License. If you cannot distribute so as to satisfy simultaneously
+ your obligations under this License and any other pertinent
+ obligations, then as a consequence you may not distribute the
+ Program at all. For example, if a patent license would not permit
+ royalty-free redistribution of the Program by all those who receive
+ copies directly or indirectly through you, then the only way you
+ could satisfy both it and this License would be to refrain entirely
+ from distribution of the Program.
+
+ If any portion of this section is held invalid or unenforceable
+ under any particular circumstance, the balance of the section is
+ intended to apply and the section as a whole is intended to apply
+ in other circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of
+ any such claims; this section has the sole purpose of protecting
+ the integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is
+ willing to distribute software through any other system and a
+ licensee cannot impose that choice.
+
+ This section is intended to make thoroughly clear what is believed
+ to be a consequence of the rest of this License.
+
+ 9. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces,
+ the original copyright holder who places the Program under this
+ License may add an explicit geographical distribution limitation
+ excluding those countries, so that distribution is permitted only
+ in or among countries not thus excluded. In such case, this
+ License incorporates the limitation as if written in the body of
+ this License.
+
+ 10. The Free Software Foundation may publish revised and/or new
+ versions of the General Public License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+ Program specifies a version number of this License which applies to
+ it and "any later version", you have the option of following the
+ terms and conditions either of that version or of any later version
+ published by the Free Software Foundation. If the Program does not
+ specify a version number of this License, you may choose any
+ version ever published by the Free Software Foundation.
+
+ 11. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by
+ the Free Software Foundation, write to the Free Software
+ Foundation; we sometimes make exceptions for this. Our decision
+ will be guided by the two goals of preserving the free status of
+ all derivatives of our free software and of promoting the sharing
+ and reuse of software generally.
+
+ NO WARRANTY
+
+ 12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+ WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
+ LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS
+ AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+ OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+ PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
+ DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
+ OR CORRECTION.
+
+ 13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
+ MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+ INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
+ OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
+ OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+=============================================
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ ONE LINE TO GIVE THE PROGRAM'S NAME AND AN IDEA OF WHAT IT DOES.
+ Copyright (C) 19YY NAME OF AUTHOR
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program 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 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.
+
+ Also add information on how to contact you by electronic and paper
+mail.
+
+ If the program is interactive, make it output a short notice like
+this when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+ type `show w'. This is free software, and you are welcome
+ to redistribute it under certain conditions; type `show c'
+ for details.
+
+ The hypothetical commands 'show w' and 'show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than 'show w' and 'show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+ You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the program,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright
+ interest in the program `Gnomovision'
+ (which makes passes at compilers) written
+ by James Hacker.
+
+ SIGNATURE OF TY COON, 1 April 1989
+ Ty Coon, President of Vice
+
+ This General Public License does not permit incorporating your
+program into proprietary programs. If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use the
+GNU Library General Public License instead of this License.
+
+
+File: gcrypt.info, Node: Figures and Tables, Next: Concept Index, Prev: Copying, Up: Top
+
+List of Figures and Tables
+**************************
+
+* Menu:
+
+* Figure 17.1: fig:subsystems. Libgcrypt subsystems
+* Figure B.1: fig:fips-fsm. FIPS mode state diagram
+
+* Menu:
+
+* Table B.1: tbl:fips-states. FIPS mode states
+* Table B.2: tbl:fips-state-transitions. FIPS mode state transitions
+
+
+File: gcrypt.info, Node: Concept Index, Next: Function and Data Index, Prev: Figures and Tables, Up: Top
+
+Concept Index
+*************
+
+
+* Menu:
+
+* /etc/gcrypt/fips_enabled: Configuration. (line 69)
+* /etc/gcrypt/hwf.deny: Configuration. (line 48)
+* /etc/gcrypt/random.conf: Configuration. (line 52)
+* /proc/cpuinfo: Configuration. (line 74)
+* /proc/self/auxv: Configuration. (line 74)
+* 3DES: Available ciphers. (line 14)
+* Advanced Encryption Standard: Available ciphers. (line 35)
+* AES: Available ciphers. (line 35)
+* AES-Wrap mode: Available cipher modes.
+ (line 35)
+* Arcfour: Available ciphers. (line 52)
+* BLAKE2b-512, BLAKE2b-384, BLAKE2b-256, BLAKE2b-160: Available hash algorithms.
+ (line 6)
+* BLAKE2s-256, BLAKE2s-224, BLAKE2s-160, BLAKE2s-128: Available hash algorithms.
+ (line 6)
+* Blowfish: Available ciphers. (line 22)
+* bug emulation: Working with hash algorithms.
+ (line 38)
+* Camellia: Available ciphers. (line 77)
+* CAST5: Available ciphers. (line 19)
+* CBC, Cipher Block Chaining mode: Available cipher modes.
+ (line 23)
+* CBC-MAC: Working with cipher handles.
+ (line 56)
+* CCM, Counter with CBC-MAC mode: Available cipher modes.
+ (line 48)
+* CFB, Cipher Feedback mode: Available cipher modes.
+ (line 17)
+* ChaCha20: Available ciphers. (line 98)
+* cipher text stealing: Working with cipher handles.
+ (line 50)
+* comp: Cryptographic Functions.
+ (line 13)
+* CRC32: Available hash algorithms.
+ (line 6)
+* CTR, Counter mode: Available cipher modes.
+ (line 32)
+* DES: Available ciphers. (line 57)
+* DES-EDE: Available ciphers. (line 14)
+* Digital Encryption Standard: Available ciphers. (line 14)
+* disable-jent: Configuration. (line 58)
+* EAX, EAX mode: Available cipher modes.
+ (line 89)
+* ECB, Electronic Codebook mode: Available cipher modes.
+ (line 13)
+* EdDSA: Cryptographic Functions.
+ (line 33)
+* Enforced FIPS mode: Enabling FIPS mode. (line 29)
+* error codes: Error Values. (line 6)
+* error codes, list of: Error Sources. (line 6)
+* error codes, list of <1>: Error Codes. (line 6)
+* error codes, printing of: Error Strings. (line 6)
+* error sources: Error Values. (line 6)
+* error sources, printing of: Error Strings. (line 6)
+* error strings: Error Strings. (line 6)
+* error values: Error Values. (line 6)
+* error values, printing of: Error Strings. (line 6)
+* FIPS 140: Enabling FIPS mode. (line 6)
+* FIPS 186: Cryptographic Functions.
+ (line 72)
+* FIPS 186 <1>: Public-Key Subsystem Architecture.
+ (line 50)
+* FIPS 186-2: Cryptographic Functions.
+ (line 80)
+* FIPS mode: Enabling FIPS mode. (line 6)
+* fips_enabled: Configuration. (line 69)
+* GCM, Galois/Counter Mode: Available cipher modes.
+ (line 53)
+* GCRYPT_BARRETT: Configuration. (line 12)
+* GCRYPT_RNDUNIX_DBG: Configuration. (line 17)
+* GCRYPT_RNDUNIX_DBGALL: Configuration. (line 17)
+* GCRYPT_RNDW32_DBG: Configuration. (line 32)
+* GCRYPT_RNDW32_NOPERF: Configuration. (line 25)
+* GOST 28147-89: Available ciphers. (line 88)
+* GOST 28147-89 CryptoPro keymeshing: Available ciphers. (line 92)
+* GPL, GNU General Public License: Copying. (line 6)
+* hardware features: Hardware features. (line 6)
+* HAVAL: Available hash algorithms.
+ (line 6)
+* HMAC: Working with hash algorithms.
+ (line 28)
+* HMAC-BLAKE2s, HMAC-BLAKE2b: Available MAC algorithms.
+ (line 6)
+* HMAC-GOSTR-3411-94: Available MAC algorithms.
+ (line 6)
+* HMAC-MD2, HMAC-MD4, HMAC-MD5: Available MAC algorithms.
+ (line 6)
+* HMAC-RIPE-MD-160: Available MAC algorithms.
+ (line 6)
+* HMAC-SHA-1: Available MAC algorithms.
+ (line 6)
+* HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512: Available MAC algorithms.
+ (line 6)
+* HMAC-SHA-512/224, HMAC-SHA-512/256: Available MAC algorithms.
+ (line 6)
+* HMAC-SHA3-224, HMAC-SHA3-256, HMAC-SHA3-384, HMAC-SHA3-512: Available MAC algorithms.
+ (line 6)
+* HMAC-SM3: Available MAC algorithms.
+ (line 6)
+* HMAC-Stribog-256, HMAC-Stribog-512: Available MAC algorithms.
+ (line 6)
+* HMAC-TIGER1: Available MAC algorithms.
+ (line 6)
+* HMAC-Whirlpool: Available MAC algorithms.
+ (line 6)
+* HOME: Configuration. (line 37)
+* IDEA: Available ciphers. (line 11)
+* LGPL, GNU Lesser General Public License: Library Copying. (line 6)
+* MD2, MD4, MD5: Available hash algorithms.
+ (line 6)
+* no-blinding: Cryptographic Functions.
+ (line 41)
+* no-keytest: Cryptographic Functions.
+ (line 59)
+* nocomp: Cryptographic Functions.
+ (line 13)
+* OAEP: Cryptographic Functions.
+ (line 27)
+* OCB, OCB3: Available cipher modes.
+ (line 63)
+* OFB, Output Feedback mode: Available cipher modes.
+ (line 29)
+* only-urandom: Configuration. (line 61)
+* param: Cryptographic Functions.
+ (line 47)
+* PKCS1: Cryptographic Functions.
+ (line 23)
+* Poly1305 based AEAD mode with ChaCha20: Available cipher modes.
+ (line 58)
+* PSS: Cryptographic Functions.
+ (line 30)
+* RC2: Available ciphers. (line 69)
+* RC4: Available ciphers. (line 52)
+* rfc-2268: Available ciphers. (line 69)
+* RFC6979: Cryptographic Functions.
+ (line 38)
+* Rijndael: Available ciphers. (line 35)
+* RIPE-MD-160: Available hash algorithms.
+ (line 6)
+* Salsa20: Available ciphers. (line 81)
+* Salsa20/12: Available ciphers. (line 84)
+* Seed (cipher): Available ciphers. (line 72)
+* Serpent: Available ciphers. (line 65)
+* SHA-1: Available hash algorithms.
+ (line 6)
+* SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256: Available hash algorithms.
+ (line 6)
+* SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256: Available hash algorithms.
+ (line 6)
+* SM3: Available hash algorithms.
+ (line 6)
+* SM4 (cipher): Available ciphers. (line 101)
+* sync mode (OpenPGP): Working with cipher handles.
+ (line 46)
+* TIGER, TIGER1, TIGER2: Available hash algorithms.
+ (line 6)
+* transient-key: Cryptographic Functions.
+ (line 52)
+* Triple-DES: Available ciphers. (line 14)
+* Twofish: Available ciphers. (line 46)
+* Whirlpool: Available hash algorithms.
+ (line 6)
+* X9.31: Cryptographic Functions.
+ (line 65)
+* X9.31 <1>: Public-Key Subsystem Architecture.
+ (line 50)
+* XTS, XTS mode: Available cipher modes.
+ (line 74)
+
diff --git a/comm/third_party/libgcrypt/doc/gcrypt.info-2 b/comm/third_party/libgcrypt/doc/gcrypt.info-2
new file mode 100644
index 0000000000..67b75c96c9
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/gcrypt.info-2
Binary files differ
diff --git a/comm/third_party/libgcrypt/doc/gcrypt.texi b/comm/third_party/libgcrypt/doc/gcrypt.texi
new file mode 100644
index 0000000000..11c1549f4e
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/gcrypt.texi
@@ -0,0 +1,6944 @@
+\input texinfo @c -*- Texinfo -*-
+@c %**start of header
+@setfilename gcrypt.info
+@include version.texi
+@settitle The Libgcrypt Reference Manual
+@c Unify some of the indices.
+@syncodeindex tp fn
+@syncodeindex pg fn
+@c %**end of header
+@copying
+This manual is for Libgcrypt version @value{VERSION} and was last
+updated @value{UPDATED}. Libgcrypt is GNU's library of cryptographic
+building blocks.
+
+@noindent
+Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011, 2012 Free Software Foundation, Inc. @*
+Copyright @copyright{} 2012, 2013, 2016, 2017 g10 Code GmbH
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version. The text of the license can be found in the
+section entitled ``GNU General Public License''.
+@end quotation
+@end copying
+
+@dircategory GNU Libraries
+@direntry
+* libgcrypt: (gcrypt). Cryptographic function library.
+@end direntry
+
+@c A couple of macros with no effect on texinfo
+@c but used by the yat2m processor.
+@macro manpage {a}
+@end macro
+@macro mansect {a}
+@end macro
+@macro manpause
+@end macro
+@macro mancont
+@end macro
+
+@c
+@c Printing stuff taken from gcc.
+@c
+@macro gnupgtabopt{body}
+@code{\body\}
+@end macro
+
+
+@c
+@c Titlepage
+@c
+@setchapternewpage odd
+@titlepage
+@title The Libgcrypt Reference Manual
+@subtitle Version @value{VERSION}
+@subtitle @value{UPDATED}
+@author Werner Koch (@email{wk@@gnupg.org})
+@author Moritz Schulte (@email{mo@@g10code.com})
+
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@ifnothtml
+@summarycontents
+@contents
+@page
+@end ifnothtml
+
+
+@ifnottex
+@node Top
+@top The Libgcrypt Library
+@insertcopying
+@end ifnottex
+
+
+@menu
+* Introduction:: What is Libgcrypt.
+* Preparation:: What you should do before using the library.
+* Generalities:: General library functions and data types.
+* Handler Functions:: Working with handler functions.
+* Symmetric cryptography:: How to use symmetric cryptography.
+* Public Key cryptography:: How to use public key cryptography.
+* Hashing:: How to use hash algorithms.
+* Message Authentication Codes:: How to use MAC algorithms.
+* Key Derivation:: How to derive keys from strings
+* Random Numbers:: How to work with random numbers.
+* S-expressions:: How to manage S-expressions.
+* MPI library:: How to work with multi-precision-integers.
+* Prime numbers:: How to use the Prime number related functions.
+* Utilities:: Utility functions.
+* Tools:: Utility tools.
+* Configuration:: Configuration files and environment variables.
+* Architecture:: How Libgcrypt works internally.
+
+Appendices
+
+* Self-Tests:: Description of the self-tests.
+* FIPS Mode:: Description of the FIPS mode.
+* Library Copying:: The GNU Lesser General Public License
+ says how you can copy and share Libgcrypt.
+* Copying:: The GNU General Public License says how you
+ can copy and share some parts of Libgcrypt.
+
+Indices
+
+* Figures and Tables:: Index of figures and tables.
+* Concept Index:: Index of concepts and programs.
+* Function and Data Index:: Index of functions, variables and data types.
+
+@end menu
+
+@ifhtml
+@page
+@summarycontents
+@contents
+@end ifhtml
+
+
+@c **********************************************************
+@c ******************* Introduction ***********************
+@c **********************************************************
+@node Introduction
+@chapter Introduction
+
+Libgcrypt is a library providing cryptographic building blocks.
+
+@menu
+* Getting Started:: How to use this manual.
+* Features:: A glance at Libgcrypt's features.
+* Overview:: Overview about the library.
+@end menu
+
+@node Getting Started
+@section Getting Started
+
+This manual documents the Libgcrypt library application programming
+interface (API). All functions and data types provided by the library
+are explained.
+
+@noindent
+The reader is assumed to possess basic knowledge about applied
+cryptography.
+
+This manual can be used in several ways. If read from the beginning
+to the end, it gives a good introduction into the library and how it
+can be used in an application. Forward references are included where
+necessary. Later on, the manual can be used as a reference manual to
+get just the information needed about any particular interface of the
+library. Experienced programmers might want to start looking at the
+examples at the end of the manual, and then only read up those parts
+of the interface which are unclear.
+
+
+@node Features
+@section Features
+
+Libgcrypt might have a couple of advantages over other libraries doing
+a similar job.
+
+@table @asis
+@item It's Free Software
+Anybody can use, modify, and redistribute it under the terms of the GNU
+Lesser General Public License (@pxref{Library Copying}). Note, that
+some parts (which are in general not needed by applications) are subject
+to the terms of the GNU General Public License (@pxref{Copying}); please
+see the README file of the distribution for of list of these parts.
+
+@item It encapsulates the low level cryptography
+Libgcrypt provides a high level interface to cryptographic
+building blocks using an extensible and flexible API.
+
+@end table
+
+@node Overview
+@section Overview
+
+@noindent
+The Libgcrypt library is fully thread-safe, where it makes
+sense to be thread-safe. Not thread-safe are some cryptographic
+functions that modify a certain context stored in handles. If the
+user really intents to use such functions from different threads on
+the same handle, he has to take care of the serialization of such
+functions himself. If not described otherwise, every function is
+thread-safe.
+
+Libgcrypt depends on the library `libgpg-error', which contains some
+common code used by other GnuPG components.
+
+@c **********************************************************
+@c ******************* Preparation ************************
+@c **********************************************************
+@node Preparation
+@chapter Preparation
+
+To use Libgcrypt, you have to perform some changes to your
+sources and the build system. The necessary changes are small and
+explained in the following sections. At the end of this chapter, it
+is described how the library is initialized, and how the requirements
+of the library are verified.
+
+@menu
+* Header:: What header file you need to include.
+* Building sources:: How to build sources using the library.
+* Building sources using Automake:: How to build sources with the help of Automake.
+* Initializing the library:: How to initialize the library.
+* Multi-Threading:: How Libgcrypt can be used in a MT environment.
+* Enabling FIPS mode:: How to enable the FIPS mode.
+* Hardware features:: How to disable hardware features.
+@end menu
+
+
+@node Header
+@section Header
+
+All interfaces (data types and functions) of the library are defined
+in the header file @file{gcrypt.h}. You must include this in all source
+files using the library, either directly or through some other header
+file, like this:
+
+@example
+#include <gcrypt.h>
+@end example
+
+The name space of Libgcrypt is @code{gcry_*} for function
+and type names and @code{GCRY*} for other symbols. In addition the
+same name prefixes with one prepended underscore are reserved for
+internal use and should never be used by an application. Note that
+Libgcrypt uses libgpg-error, which uses @code{gpg_*} as
+name space for function and type names and @code{GPG_*} for other
+symbols, including all the error codes.
+
+@noindent
+Certain parts of gcrypt.h may be excluded by defining these macros:
+
+@table @code
+@item GCRYPT_NO_MPI_MACROS
+Do not define the shorthand macros @code{mpi_*} for @code{gcry_mpi_*}.
+
+@item GCRYPT_NO_DEPRECATED
+Do not include definitions for deprecated features. This is useful to
+make sure that no deprecated features are used.
+@end table
+
+@node Building sources
+@section Building sources
+
+If you want to compile a source file including the `gcrypt.h' header
+file, you must make sure that the compiler can find it in the
+directory hierarchy. This is accomplished by adding the path to the
+directory in which the header file is located to the compilers include
+file search path (via the @option{-I} option).
+
+However, the path to the include file is determined at the time the
+source is configured. To solve this problem, Libgcrypt ships with a small
+helper program @command{libgcrypt-config} that knows the path to the
+include file and other configuration options. The options that need
+to be added to the compiler invocation at compile time are output by
+the @option{--cflags} option to @command{libgcrypt-config}. The following
+example shows how it can be used at the command line:
+
+@example
+gcc -c foo.c `libgcrypt-config --cflags`
+@end example
+
+Adding the output of @samp{libgcrypt-config --cflags} to the
+compiler’s command line will ensure that the compiler can find the
+Libgcrypt header file.
+
+A similar problem occurs when linking the program with the library.
+Again, the compiler has to find the library files. For this to work,
+the path to the library files has to be added to the library search path
+(via the @option{-L} option). For this, the option @option{--libs} to
+@command{libgcrypt-config} can be used. For convenience, this option
+also outputs all other options that are required to link the program
+with the Libgcrypt libraries (in particular, the @samp{-lgcrypt}
+option). The example shows how to link @file{foo.o} with the Libgcrypt
+library to a program @command{foo}.
+
+@example
+gcc -o foo foo.o `libgcrypt-config --libs`
+@end example
+
+Of course you can also combine both examples to a single command by
+specifying both options to @command{libgcrypt-config}:
+
+@example
+gcc -o foo foo.c `libgcrypt-config --cflags --libs`
+@end example
+
+@node Building sources using Automake
+@section Building sources using Automake
+
+It is much easier if you use GNU Automake instead of writing your own
+Makefiles. If you do that, you do not have to worry about finding and
+invoking the @command{libgcrypt-config} script at all.
+Libgcrypt provides an extension to Automake that does all
+the work for you.
+
+@c A simple macro for optional variables.
+@macro ovar{varname}
+@r{[}@var{\varname\}@r{]}
+@end macro
+@defmac AM_PATH_LIBGCRYPT (@ovar{minimum-version}, @ovar{action-if-found}, @ovar{action-if-not-found})
+Check whether Libgcrypt (at least version
+@var{minimum-version}, if given) exists on the host system. If it is
+found, execute @var{action-if-found}, otherwise do
+@var{action-if-not-found}, if given.
+
+Additionally, the function defines @code{LIBGCRYPT_CFLAGS} to the
+flags needed for compilation of the program to find the
+@file{gcrypt.h} header file, and @code{LIBGCRYPT_LIBS} to the linker
+flags needed to link the program to the Libgcrypt library. If the
+used helper script does not match the target type you are building for
+a warning is printed and the string @code{libgcrypt} is appended to the
+variable @code{gpg_config_script_warn}.
+
+This macro searches for @command{libgcrypt-config} along the PATH. If
+you are cross-compiling, it is useful to set the environment variable
+@code{SYSROOT} to the top directory of your target. The macro will
+then first look for the helper program in the @file{bin} directory
+below that top directory. An absolute directory name must be used for
+@code{SYSROOT}. Finally, if the configure command line option
+@code{--with-libgcrypt-prefix} is used, only its value is used for the top
+directory below which the helper script is expected.
+
+@end defmac
+
+You can use the defined Autoconf variables like this in your
+@file{Makefile.am}:
+
+@example
+AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS)
+LDADD = $(LIBGCRYPT_LIBS)
+@end example
+
+@node Initializing the library
+@section Initializing the library
+
+Before the library can be used, it must initialize itself. This is
+achieved by invoking the function @code{gcry_check_version} described
+below.
+
+Also, it is often desirable to check that the version of
+Libgcrypt used is indeed one which fits all requirements.
+Even with binary compatibility, new features may have been introduced,
+but due to problem with the dynamic linker an old version may actually
+be used. So you may want to check that the version is okay right
+after program startup.
+
+@deftypefun {const char *} gcry_check_version (const char *@var{req_version})
+
+The function @code{gcry_check_version} initializes some subsystems used
+by Libgcrypt and must be invoked before any other function in the
+library.
+@xref{Multi-Threading}.
+
+Furthermore, this function returns the version number of the library.
+It can also verify that the version number is higher than a certain
+required version number @var{req_version}, if this value is not a null
+pointer.
+@end deftypefun
+
+Libgcrypt uses a concept known as secure memory, which is a region of
+memory set aside for storing sensitive data. Because such memory is a
+scarce resource, it needs to be setup in advanced to a fixed size.
+Further, most operating systems have special requirements on how that
+secure memory can be used. For example, it might be required to install
+an application as ``setuid(root)'' to allow allocating such memory.
+Libgcrypt requires a sequence of initialization steps to make sure that
+this works correctly. The following examples show the necessary steps.
+
+If you don't have a need for secure memory, for example if your
+application does not use secret keys or other confidential data or it
+runs in a controlled environment where key material floating around in
+memory is not a problem, you should initialize Libgcrypt this way:
+
+@example
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are initialized.
+ #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
+ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
+ @{
+ fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
+ NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
+ exit (2);
+ @}
+
+ /* Disable secure memory. */
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+@end example
+
+
+If you have to protect your keys or other information in memory against
+being swapped out to disk and to enable an automatic overwrite of used
+and freed memory, you need to initialize Libgcrypt this way:
+
+@example
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are initialized.
+ #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
+ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
+ @{
+ fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
+ NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
+ exit (2);
+ @}
+
+@anchor{sample-use-suspend-secmem}
+ /* We don't want to see any warnings, e.g. because we have not yet
+ parsed program options which might be used to suppress such
+ warnings. */
+ gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. Note that the
+ process might still be running with increased privileges and that
+ the secure memory has not been initialized. */
+
+ /* Allocate a pool of 16k secure memory. This makes the secure memory
+ available and also drops privileges where needed. Note that by
+ using functions like gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt
+ may expand the secure memory pool with memory which lacks the
+ property of not being swapped out to disk. */
+ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+@anchor{sample-use-resume-secmem}
+ /* It is now okay to let Libgcrypt complain when there was/is
+ a problem with the secure memory. */
+ gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+@end example
+
+It is important that these initialization steps are not done by a
+library but by the actual application. A library using Libgcrypt might
+want to check for finished initialization using:
+
+@example
+ if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P))
+ @{
+ fputs ("libgcrypt has not been initialized\n", stderr);
+ abort ();
+ @}
+@end example
+
+Instead of terminating the process, the library may instead print a
+warning and try to initialize Libgcrypt itself. See also the section on
+multi-threading below for more pitfalls.
+
+
+
+@node Multi-Threading
+@section Multi-Threading
+
+As mentioned earlier, the Libgcrypt library is
+thread-safe if you adhere to the following requirements:
+
+@itemize @bullet
+@item
+If you use pthread and your applications forks and does not directly
+call exec (even calling stdio functions), all kind of problems may
+occur. Future versions of Libgcrypt will try to cleanup using
+pthread_atfork but even that may lead to problems. This is a common
+problem with almost all applications using pthread and fork.
+
+
+@item
+The function @code{gcry_check_version} must be called before any other
+function in the library. To
+achieve this in multi-threaded programs, you must synchronize the
+memory with respect to other threads that also want to use
+Libgcrypt. For this, it is sufficient to call
+@code{gcry_check_version} before creating the other threads using
+Libgcrypt@footnote{At least this is true for POSIX threads,
+as @code{pthread_create} is a function that synchronizes memory with
+respects to other threads. There are many functions which have this
+property, a complete list can be found in POSIX, IEEE Std 1003.1-2003,
+Base Definitions, Issue 6, in the definition of the term ``Memory
+Synchronization''. For other thread packages, more relaxed or more
+strict rules may apply.}.
+
+@item
+Just like the function @code{gpg_strerror}, the function
+@code{gcry_strerror} is not thread safe. You have to use
+@code{gpg_strerror_r} instead.
+
+@end itemize
+
+
+@node Enabling FIPS mode
+@section How to enable the FIPS mode
+@cindex FIPS mode
+@cindex FIPS 140
+
+@anchor{enabling fips mode}
+Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not
+necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check the
+NIST database at @url{http://csrc.nist.gov/groups/STM/cmvp/} to see what
+versions of Libgcrypt are approved.
+
+Because FIPS 140 has certain restrictions on the use of cryptography
+which are not always wanted, Libgcrypt needs to be put into FIPS mode
+explicitly. Three alternative mechanisms are provided to switch
+Libgcrypt into this mode:
+
+@itemize
+@item
+If the file @file{/proc/sys/crypto/fips_enabled} exists and contains a
+numeric value other than @code{0}, Libgcrypt is put into FIPS mode at
+initialization time. Obviously this works only on systems with a
+@code{proc} file system (i.e. GNU/Linux).
+
+@item
+If the file @file{/etc/gcrypt/fips_enabled} exists, Libgcrypt is put
+into FIPS mode at initialization time. Note that this filename is
+hardwired and does not depend on any configuration options.
+
+@item
+If the application requests FIPS mode using the control command
+@code{GCRYCTL_FORCE_FIPS_MODE}. This must be done prior to any
+initialization (i.e. before @code{gcry_check_version}).
+
+@end itemize
+
+@cindex Enforced FIPS mode
+
+In addition to the standard FIPS mode, Libgcrypt may also be put into
+an Enforced FIPS mode by writing a non-zero value into the file
+@file{/etc/gcrypt/fips_enabled} or by using the control command
+@code{GCRYCTL_SET_ENFORCED_FIPS_FLAG} before any other calls to
+libgcrypt. The Enforced FIPS mode helps to detect applications
+which don't fulfill all requirements for using
+Libgcrypt in FIPS mode (@pxref{FIPS Mode}).
+
+Once Libgcrypt has been put into FIPS mode, it is not possible to
+switch back to standard mode without terminating the process first.
+If the logging verbosity level of Libgcrypt has been set to at least
+2, the state transitions and the self-tests are logged.
+
+@node Hardware features
+@section How to disable hardware features
+@cindex hardware features
+
+@anchor{hardware features}
+Libgcrypt makes use of certain hardware features. If the use of a
+feature is not desired it may be either be disabled by a program or
+globally using a configuration file. The currently supported features
+are
+
+@table @code
+@item padlock-rng
+@item padlock-aes
+@item padlock-sha
+@item padlock-mmul
+@item intel-cpu
+@item intel-fast-shld
+@item intel-bmi2
+@item intel-ssse3
+@item intel-sse4.1
+@item intel-pclmul
+@item intel-aesni
+@item intel-rdrand
+@item intel-avx
+@item intel-avx2
+@item intel-fast-vpgather
+@item intel-rdtsc
+@item intel-shaext
+@item arm-neon
+@item arm-aes
+@item arm-sha1
+@item arm-sha2
+@item arm-pmull
+@end table
+
+To disable a feature for all processes using Libgcrypt 1.6 or newer,
+create the file @file{/etc/gcrypt/hwf.deny} and put each feature not
+to be used on a single line. Empty lines, white space, and lines
+prefixed with a hash mark are ignored. The file should be world
+readable.
+
+To disable a feature specifically for a program that program must tell
+it Libgcrypt before before calling @code{gcry_check_version}.
+Example:@footnote{NB. Libgcrypt uses the RDRAND feature only as one
+source of entropy. A CPU with a broken RDRAND will thus not
+compromise of the random number generator}
+
+@example
+ gcry_control (GCRYCTL_DISABLE_HWF, "intel-rdrand", NULL);
+@end example
+
+@noindent
+To print the list of active features you may use this command:
+
+@example
+ mpicalc --print-config | grep ^hwflist: | tr : '\n' | tail -n +2
+@end example
+
+
+@c **********************************************************
+@c ******************* General ****************************
+@c **********************************************************
+@node Generalities
+@chapter Generalities
+
+@menu
+* Controlling the library:: Controlling Libgcrypt's behavior.
+* Error Handling:: Error codes and such.
+@end menu
+
+@node Controlling the library
+@section Controlling the library
+
+@deftypefun gcry_error_t gcry_control (enum gcry_ctl_cmds @var{cmd}, ...)
+
+This function can be used to influence the general behavior of
+Libgcrypt in several ways. Depending on @var{cmd}, more
+arguments can or have to be provided.
+
+@table @code
+@item GCRYCTL_ENABLE_M_GUARD; Arguments: none
+This command enables the built-in memory guard. It must not be used
+to activate the memory guard after the memory management has already
+been used; therefore it can ONLY be used before
+@code{gcry_check_version}. Note that the memory guard is NOT used
+when the user of the library has set his own memory management
+callbacks.
+
+@item GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none
+This command inhibits the use the very secure random quality level
+(@code{GCRY_VERY_STRONG_RANDOM}) and degrades all request down to
+@code{GCRY_STRONG_RANDOM}. In general this is not recommended. However,
+for some applications the extra quality random Libgcrypt tries to create
+is not justified and this option may help to get better performance.
+Please check with a crypto expert whether this option can be used for
+your application.
+
+This option can only be used at initialization time.
+
+
+@item GCRYCTL_DUMP_RANDOM_STATS; Arguments: none
+This command dumps random number generator related statistics to the
+library's logging stream.
+
+@item GCRYCTL_DUMP_MEMORY_STATS; Arguments: none
+This command dumps memory management related statistics to the library's
+logging stream.
+
+@item GCRYCTL_DUMP_SECMEM_STATS; Arguments: none
+This command dumps secure memory management related statistics to the
+library's logging stream.
+
+@item GCRYCTL_DROP_PRIVS; Arguments: none
+This command disables the use of secure memory and drops the privileges
+of the current process. This command has not much use; the suggested way
+to disable secure memory is to use @code{GCRYCTL_DISABLE_SECMEM} right
+after initialization.
+
+@item GCRYCTL_DISABLE_SECMEM; Arguments: none
+This command disables the use of secure memory. If this command is
+used in FIPS mode, FIPS mode will be disabled and the function
+@code{gcry_fips_mode_active} returns false. However, in Enforced FIPS
+mode this command has no effect at all.
+
+Many applications do not require secure memory, so they should disable
+it right away. This command should be executed right after
+@code{gcry_check_version}.
+
+@item GCRYCTL_DISABLE_LOCKED_SECMEM; Arguments: none
+This command disables the use of the mlock call for secure memory.
+Disabling the use of mlock may for example be done if an encrypted
+swap space is in use. This command should be executed right after
+@code{gcry_check_version}. Note that by using functions like
+gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt may expand the secure
+memory pool with memory which lacks the property of not being swapped
+out to disk (but will still be zeroed out on free).
+
+@item GCRYCTL_DISABLE_PRIV_DROP; Arguments: none
+This command sets a global flag to tell the secure memory subsystem
+that it shall not drop privileges after secure memory has been
+allocated. This command is commonly used right after
+@code{gcry_check_version} but may also be used right away at program
+startup. It won't have an effect after the secure memory pool has
+been initialized. WARNING: A process running setuid(root) is a severe
+security risk. Processes making use of Libgcrypt or other complex
+code should drop these extra privileges as soon as possible. If this
+command has been used the caller is responsible for dropping the
+privileges.
+
+@item GCRYCTL_INIT_SECMEM; Arguments: unsigned int nbytes
+This command is used to allocate a pool of secure memory and thus
+enabling the use of secure memory. It also drops all extra privileges
+the process has (i.e. if it is run as setuid (root)). If the argument
+@var{nbytes} is 0, secure memory will be disabled. The minimum amount
+of secure memory allocated is currently 16384 bytes; you may thus use a
+value of 1 to request that default size.
+
+@item GCRYCTL_AUTO_EXPAND_SECMEM; Arguments: unsigned int chunksize
+This command enables on-the-fly expanding of the secure memory area.
+Note that by using functions like @code{gcry_xmalloc_secure} and
+@code{gcry_mpi_snew} will do this auto expanding anyway. The argument
+to this option is the suggested size for new secure memory areas. A
+larger size improves performance of all memory allocation and
+releasing functions. The given chunksize is rounded up to the next
+32KiB. The drawback of auto expanding is that memory might be swapped
+out to disk; this can be fixed by configuring the system to use an
+encrypted swap space.
+
+@item GCRYCTL_TERM_SECMEM; Arguments: none
+This command zeroises the secure memory and destroys the handler. The
+secure memory pool may not be used anymore after running this command.
+If the secure memory pool as already been destroyed, this command has
+no effect. Applications might want to run this command from their
+exit handler to make sure that the secure memory gets properly
+destroyed. This command is not necessarily thread-safe but that
+should not be needed in cleanup code. It may be called from a signal
+handler.
+
+@item GCRYCTL_DISABLE_SECMEM_WARN; Arguments: none
+Disable warning messages about problems with the secure memory
+subsystem. This command should be run right after
+@code{gcry_check_version}.
+
+@item GCRYCTL_SUSPEND_SECMEM_WARN; Arguments: none
+Postpone warning messages from the secure memory subsystem.
+@xref{sample-use-suspend-secmem,,the initialization example}, on how to
+use it.
+
+@item GCRYCTL_RESUME_SECMEM_WARN; Arguments: none
+Resume warning messages from the secure memory subsystem.
+@xref{sample-use-resume-secmem,,the initialization example}, on how to
+use it.
+
+@item GCRYCTL_USE_SECURE_RNDPOOL; Arguments: none
+This command tells the PRNG to store random numbers in secure memory.
+This command should be run right after @code{gcry_check_version} and not
+later than the command GCRYCTL_INIT_SECMEM. Note that in FIPS mode the
+secure memory is always used.
+
+@item GCRYCTL_SET_RANDOM_SEED_FILE; Arguments: const char *filename
+This command specifies the file, which is to be used as seed file for
+the PRNG. If the seed file is registered prior to initialization of the
+PRNG, the seed file's content (if it exists and seems to be valid) is
+fed into the PRNG pool. After the seed file has been registered, the
+PRNG can be signalled to write out the PRNG pool's content into the seed
+file with the following command.
+
+
+@item GCRYCTL_UPDATE_RANDOM_SEED_FILE; Arguments: none
+Write out the PRNG pool's content into the registered seed file.
+
+Multiple instances of the applications sharing the same random seed file
+can be started in parallel, in which case they will read out the same
+pool and then race for updating it (the last update overwrites earlier
+updates). They will differentiate only by the weak entropy that is
+added in read_seed_file based on the PID and clock, and up to 16 bytes
+of weak random non-blockingly. The consequence is that the output of
+these different instances is correlated to some extent. In a perfect
+attack scenario, the attacker can control (or at least guess) the PID
+and clock of the application, and drain the system's entropy pool to
+reduce the "up to 16 bytes" above to 0. Then the dependencies of the
+initial states of the pools are completely known. Note that this is not
+an issue if random of @code{GCRY_VERY_STRONG_RANDOM} quality is
+requested as in this case enough extra entropy gets mixed. It is also
+not an issue when using Linux (rndlinux driver), because this one
+guarantees to read full 16 bytes from /dev/urandom and thus there is no
+way for an attacker without kernel access to control these 16 bytes.
+
+@item GCRYCTL_CLOSE_RANDOM_DEVICE; Arguments: none
+Try to close the random device. If on Unix system you call fork(),
+the child process does no call exec(), and you do not intend to use
+Libgcrypt in the child, it might be useful to use this control code to
+close the inherited file descriptors of the random device. If
+Libgcrypt is later used again by the child, the device will be
+re-opened. On non-Unix systems this control code is ignored.
+
+@item GCRYCTL_SET_VERBOSITY; Arguments: int level
+This command sets the verbosity of the logging. A level of 0 disables
+all extra logging whereas positive numbers enable more verbose logging.
+The level may be changed at any time but be aware that no memory
+synchronization is done so the effect of this command might not
+immediately show up in other threads. This command may even be used
+prior to @code{gcry_check_version}.
+
+@item GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags
+Set the debug flag bits as given by the argument. Be aware that no
+memory synchronization is done so the effect of this command might not
+immediately show up in other threads. The debug flags are not
+considered part of the API and thus may change without notice. As of
+now bit 0 enables debugging of cipher functions and bit 1 debugging of
+multi-precision-integers. This command may even be used prior to
+@code{gcry_check_version}.
+
+@item GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags
+Set the debug flag bits as given by the argument. Be aware that that no
+memory synchronization is done so the effect of this command might not
+immediately show up in other threads. This command may even be used
+prior to @code{gcry_check_version}.
+
+@item GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none
+This command does nothing. It exists only for backward compatibility.
+
+@item GCRYCTL_ANY_INITIALIZATION_P; Arguments: none
+This command returns true if the library has been basically initialized.
+Such a basic initialization happens implicitly with many commands to get
+certain internal subsystems running. The common and suggested way to
+do this basic initialization is by calling gcry_check_version.
+
+@item GCRYCTL_INITIALIZATION_FINISHED; Arguments: none
+This command tells the library that the application has finished the
+initialization.
+
+@item GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none
+This command returns true if the command@*
+GCRYCTL_INITIALIZATION_FINISHED has already been run.
+
+@item GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops
+This command is obsolete since version 1.6.
+
+@item GCRYCTL_FAST_POLL; Arguments: none
+Run a fast random poll.
+
+@item GCRYCTL_SET_RNDEGD_SOCKET; Arguments: const char *filename
+This command may be used to override the default name of the EGD socket
+to connect to. It may be used only during initialization as it is not
+thread safe. Changing the socket name again is not supported. The
+function may return an error if the given filename is too long for a
+local socket name.
+
+EGD is an alternative random gatherer, used only on systems lacking a
+proper random device.
+
+@item GCRYCTL_PRINT_CONFIG; Arguments: FILE *stream
+This command dumps information pertaining to the configuration of the
+library to the given stream. If NULL is given for @var{stream}, the log
+system is used. This command may be used before the initialization has
+been finished but not before a @code{gcry_check_version}. Note that
+the macro @code{estream_t} can be used instead of @code{gpgrt_stream_t}.
+
+@item GCRYCTL_OPERATIONAL_P; Arguments: none
+This command returns true if the library is in an operational state.
+This information makes only sense in FIPS mode. In contrast to other
+functions, this is a pure test function and won't put the library into
+FIPS mode or change the internal state. This command may be used before
+the initialization has been finished but not before a @code{gcry_check_version}.
+
+@item GCRYCTL_FIPS_MODE_P; Arguments: none
+This command returns true if the library is in FIPS mode. Note, that
+this is no indication about the current state of the library. This
+command may be used before the initialization has been finished but not
+before a @code{gcry_check_version}. An application may use this command or
+the convenience macro below to check whether FIPS mode is actually
+active.
+
+@deftypefun int gcry_fips_mode_active (void)
+
+Returns true if the FIPS mode is active. Note that this is
+implemented as a macro.
+@end deftypefun
+
+
+
+@item GCRYCTL_FORCE_FIPS_MODE; Arguments: none
+Running this command puts the library into FIPS mode. If the library is
+already in FIPS mode, a self-test is triggered and thus the library will
+be put into operational state. This command may be used before a call
+to @code{gcry_check_version} and that is actually the recommended way to let an
+application switch the library into FIPS mode. Note that Libgcrypt will
+reject an attempt to switch to fips mode during or after the initialization.
+
+@item GCRYCTL_SET_ENFORCED_FIPS_FLAG; Arguments: none
+Running this command sets the internal flag that puts the library into
+the enforced FIPS mode during the FIPS mode initialization. This command
+does not affect the library if the library is not put into the FIPS mode and
+it must be used before any other libgcrypt library calls that initialize
+the library such as @code{gcry_check_version}. Note that Libgcrypt will
+reject an attempt to switch to the enforced fips mode during or after
+the initialization.
+
+@item GCRYCTL_SET_PREFERRED_RNG_TYPE; Arguments: int
+These are advisory commands to select a certain random number
+generator. They are only advisory because libraries may not know what
+an application actually wants or vice versa. Thus Libgcrypt employs a
+priority check to select the actually used RNG. If an applications
+selects a lower priority RNG but a library requests a higher priority
+RNG Libgcrypt will switch to the higher priority RNG. Applications
+and libraries should use these control codes before
+@code{gcry_check_version}. The available generators are:
+@table @code
+@item GCRY_RNG_TYPE_STANDARD
+A conservative standard generator based on the ``Continuously Seeded
+Pseudo Random Number Generator'' designed by Peter Gutmann.
+@item GCRY_RNG_TYPE_FIPS
+A deterministic random number generator conforming to he document
+``NIST-Recommended Random Number Generator Based on ANSI X9.31
+Appendix A.2.4 Using the 3-Key Triple DES and AES Algorithms''
+(2005-01-31). This implementation uses the AES variant.
+@item GCRY_RNG_TYPE_SYSTEM
+A wrapper around the system's native RNG. On Unix system these are
+usually the /dev/random and /dev/urandom devices.
+@end table
+The default is @code{GCRY_RNG_TYPE_STANDARD} unless FIPS mode as been
+enabled; in which case @code{GCRY_RNG_TYPE_FIPS} is used and locked
+against further changes.
+
+@item GCRYCTL_GET_CURRENT_RNG_TYPE; Arguments: int *
+This command stores the type of the currently used RNG as an integer
+value at the provided address.
+
+
+@item GCRYCTL_SELFTEST; Arguments: none
+This may be used at anytime to have the library run all implemented
+self-tests. It works in standard and in FIPS mode. Returns 0 on
+success or an error code on failure.
+
+@item GCRYCTL_DISABLE_HWF; Arguments: const char *name
+
+Libgcrypt detects certain features of the CPU at startup time. For
+performance tests it is sometimes required not to use such a feature.
+This option may be used to disable a certain feature; i.e. Libgcrypt
+behaves as if this feature has not been detected. This call can be
+used several times to disable a set of features, or features may be
+given as a colon or comma delimited string. The special feature
+"all" can be used to disable all available features.
+
+Note that the detection code might be run if the feature has been
+disabled. This command must be used at initialization time;
+i.e. before calling @code{gcry_check_version}.
+
+@item GCRYCTL_REINIT_SYSCALL_CLAMP; Arguments: none
+
+Libgcrypt wraps blocking system calls with two functions calls
+(``system call clamp'') to give user land threading libraries a hook
+for re-scheduling. This works by reading the system call clamp from
+Libgpg-error at initialization time. However sometimes Libgcrypt
+needs to be initialized before the user land threading systems and at
+that point the system call clamp has not been registered with
+Libgpg-error and in turn Libgcrypt would not use them. The control
+code can be used to tell Libgcrypt that a system call clamp has now
+been registered with Libgpg-error and advise Libgcrypt to read the
+clamp again. Obviously this control code may only be used before a
+second thread is started in a process.
+
+
+@end table
+
+@end deftypefun
+
+@c **********************************************************
+@c ******************* Errors ****************************
+@c **********************************************************
+@node Error Handling
+@section Error Handling
+
+Many functions in Libgcrypt can return an error if they
+fail. For this reason, the application should always catch the error
+condition and take appropriate measures, for example by releasing the
+resources and passing the error up to the caller, or by displaying a
+descriptive message to the user and cancelling the operation.
+
+Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly. For
+example, if you try to decrypt a tempered message, the decryption will
+fail. Another error value actually means that the end of a data
+buffer or list has been reached. The following descriptions explain
+for many error codes what they mean usually. Some error values have
+specific meanings if returned by a certain functions. Such cases are
+described in the documentation of those functions.
+
+Libgcrypt uses the @code{libgpg-error} library. This allows to share
+the error codes with other components of the GnuPG system, and to pass
+error values transparently from the crypto engine, or some helper
+application of the crypto engine, to the user. This way no
+information is lost. As a consequence, Libgcrypt does not use its own
+identifiers for error codes, but uses those provided by
+@code{libgpg-error}. They usually start with @code{GPG_ERR_}.
+
+However, Libgcrypt does provide aliases for the functions
+defined in libgpg-error, which might be preferred for name space
+consistency.
+
+
+Most functions in Libgcrypt return an error code in the case
+of failure. For this reason, the application should always catch the
+error condition and take appropriate measures, for example by
+releasing the resources and passing the error up to the caller, or by
+displaying a descriptive message to the user and canceling the
+operation.
+
+Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly.
+
+GnuPG components, including Libgcrypt, use an extra library named
+libgpg-error to provide a common error handling scheme. For more
+information on libgpg-error, see the according manual.
+
+@menu
+* Error Values:: The error value and what it means.
+* Error Sources:: A list of important error sources.
+* Error Codes:: A list of important error codes.
+* Error Strings:: How to get a descriptive string from a value.
+@end menu
+
+
+@node Error Values
+@subsection Error Values
+@cindex error values
+@cindex error codes
+@cindex error sources
+
+@deftp {Data type} {gcry_err_code_t}
+The @code{gcry_err_code_t} type is an alias for the
+@code{libgpg-error} type @code{gpg_err_code_t}. The error code
+indicates the type of an error, or the reason why an operation failed.
+
+A list of important error codes can be found in the next section.
+@end deftp
+
+@deftp {Data type} {gcry_err_source_t}
+The @code{gcry_err_source_t} type is an alias for the
+@code{libgpg-error} type @code{gpg_err_source_t}. The error source
+has not a precisely defined meaning. Sometimes it is the place where
+the error happened, sometimes it is the place where an error was
+encoded into an error value. Usually the error source will give an
+indication to where to look for the problem. This is not always true,
+but it is attempted to achieve this goal.
+
+A list of important error sources can be found in the next section.
+@end deftp
+
+@deftp {Data type} {gcry_error_t}
+The @code{gcry_error_t} type is an alias for the @code{libgpg-error}
+type @code{gpg_error_t}. An error value like this has always two
+components, an error code and an error source. Both together form the
+error value.
+
+Thus, the error value can not be directly compared against an error
+code, but the accessor functions described below must be used.
+However, it is guaranteed that only 0 is used to indicate success
+(@code{GPG_ERR_NO_ERROR}), and that in this case all other parts of
+the error value are set to 0, too.
+
+Note that in Libgcrypt, the error source is used purely for
+diagnostic purposes. Only the error code should be checked to test
+for a certain outcome of a function. The manual only documents the
+error code part of an error value. The error source is left
+unspecified and might be anything.
+@end deftp
+
+@deftypefun {gcry_err_code_t} gcry_err_code (@w{gcry_error_t @var{err}})
+The static inline function @code{gcry_err_code} returns the
+@code{gcry_err_code_t} component of the error value @var{err}. This
+function must be used to extract the error code from an error value in
+order to compare it with the @code{GPG_ERR_*} error code macros.
+@end deftypefun
+
+@deftypefun {gcry_err_source_t} gcry_err_source (@w{gcry_error_t @var{err}})
+The static inline function @code{gcry_err_source} returns the
+@code{gcry_err_source_t} component of the error value @var{err}. This
+function must be used to extract the error source from an error value in
+order to compare it with the @code{GPG_ERR_SOURCE_*} error source macros.
+@end deftypefun
+
+@deftypefun {gcry_error_t} gcry_err_make (@w{gcry_err_source_t @var{source}}, @w{gcry_err_code_t @var{code}})
+The static inline function @code{gcry_err_make} returns the error
+value consisting of the error source @var{source} and the error code
+@var{code}.
+
+This function can be used in callback functions to construct an error
+value to return it to the library.
+@end deftypefun
+
+@deftypefun {gcry_error_t} gcry_error (@w{gcry_err_code_t @var{code}})
+The static inline function @code{gcry_error} returns the error value
+consisting of the default error source and the error code @var{code}.
+
+For @acronym{GCRY} applications, the default error source is
+@code{GPG_ERR_SOURCE_USER_1}. You can define
+@code{GCRY_ERR_SOURCE_DEFAULT} before including @file{gcrypt.h} to
+change this default.
+
+This function can be used in callback functions to construct an error
+value to return it to the library.
+@end deftypefun
+
+The @code{libgpg-error} library provides error codes for all system
+error numbers it knows about. If @var{err} is an unknown error
+number, the error code @code{GPG_ERR_UNKNOWN_ERRNO} is used. The
+following functions can be used to construct error values from system
+errno numbers.
+
+@deftypefun {gcry_error_t} gcry_err_make_from_errno (@w{gcry_err_source_t @var{source}}, @w{int @var{err}})
+The function @code{gcry_err_make_from_errno} is like
+@code{gcry_err_make}, but it takes a system error like @code{errno}
+instead of a @code{gcry_err_code_t} error code.
+@end deftypefun
+
+@deftypefun {gcry_error_t} gcry_error_from_errno (@w{int @var{err}})
+The function @code{gcry_error_from_errno} is like @code{gcry_error},
+but it takes a system error like @code{errno} instead of a
+@code{gcry_err_code_t} error code.
+@end deftypefun
+
+Sometimes you might want to map system error numbers to error codes
+directly, or map an error code representing a system error back to the
+system error number. The following functions can be used to do that.
+
+@deftypefun {gcry_err_code_t} gcry_err_code_from_errno (@w{int @var{err}})
+The function @code{gcry_err_code_from_errno} returns the error code
+for the system error @var{err}. If @var{err} is not a known system
+error, the function returns @code{GPG_ERR_UNKNOWN_ERRNO}.
+@end deftypefun
+
+@deftypefun {int} gcry_err_code_to_errno (@w{gcry_err_code_t @var{err}})
+The function @code{gcry_err_code_to_errno} returns the system error
+for the error code @var{err}. If @var{err} is not an error code
+representing a system error, or if this system error is not defined on
+this system, the function returns @code{0}.
+@end deftypefun
+
+
+@node Error Sources
+@subsection Error Sources
+@cindex error codes, list of
+
+The library @code{libgpg-error} defines an error source for every
+component of the GnuPG system. The error source part of an error
+value is not well defined. As such it is mainly useful to improve the
+diagnostic error message for the user.
+
+If the error code part of an error value is @code{0}, the whole error
+value will be @code{0}. In this case the error source part is of
+course @code{GPG_ERR_SOURCE_UNKNOWN}.
+
+The list of error sources that might occur in applications using
+@acronym{Libgcrypt} is:
+
+@table @code
+@item GPG_ERR_SOURCE_UNKNOWN
+The error source is not known. The value of this error source is
+@code{0}.
+
+@item GPG_ERR_SOURCE_GPGME
+The error source is @acronym{GPGME} itself.
+
+@item GPG_ERR_SOURCE_GPG
+The error source is GnuPG, which is the crypto engine used for the
+OpenPGP protocol.
+
+@item GPG_ERR_SOURCE_GPGSM
+The error source is GPGSM, which is the crypto engine used for the
+OpenPGP protocol.
+
+@item GPG_ERR_SOURCE_GCRYPT
+The error source is @code{libgcrypt}, which is used by crypto engines
+to perform cryptographic operations.
+
+@item GPG_ERR_SOURCE_GPGAGENT
+The error source is @command{gpg-agent}, which is used by crypto
+engines to perform operations with the secret key.
+
+@item GPG_ERR_SOURCE_PINENTRY
+The error source is @command{pinentry}, which is used by
+@command{gpg-agent} to query the passphrase to unlock a secret key.
+
+@item GPG_ERR_SOURCE_SCD
+The error source is the SmartCard Daemon, which is used by
+@command{gpg-agent} to delegate operations with the secret key to a
+SmartCard.
+
+@item GPG_ERR_SOURCE_KEYBOX
+The error source is @code{libkbx}, a library used by the crypto
+engines to manage local keyrings.
+
+@item GPG_ERR_SOURCE_USER_1
+@item GPG_ERR_SOURCE_USER_2
+@item GPG_ERR_SOURCE_USER_3
+@item GPG_ERR_SOURCE_USER_4
+These error sources are not used by any GnuPG component and can be
+used by other software. For example, applications using
+Libgcrypt can use them to mark error values coming from callback
+handlers. Thus @code{GPG_ERR_SOURCE_USER_1} is the default for errors
+created with @code{gcry_error} and @code{gcry_error_from_errno},
+unless you define @code{GCRY_ERR_SOURCE_DEFAULT} before including
+@file{gcrypt.h}.
+@end table
+
+
+@node Error Codes
+@subsection Error Codes
+@cindex error codes, list of
+
+The library @code{libgpg-error} defines many error values. The
+following list includes the most important error codes.
+
+@table @code
+@item GPG_ERR_EOF
+This value indicates the end of a list, buffer or file.
+
+@item GPG_ERR_NO_ERROR
+This value indicates success. The value of this error code is
+@code{0}. Also, it is guaranteed that an error value made from the
+error code @code{0} will be @code{0} itself (as a whole). This means
+that the error source information is lost for this error code,
+however, as this error code indicates that no error occurred, this is
+generally not a problem.
+
+@item GPG_ERR_GENERAL
+This value means that something went wrong, but either there is not
+enough information about the problem to return a more useful error
+value, or there is no separate error value for this type of problem.
+
+@item GPG_ERR_ENOMEM
+This value means that an out-of-memory condition occurred.
+
+@item GPG_ERR_E...
+System errors are mapped to GPG_ERR_EFOO where FOO is the symbol for
+the system error.
+
+@item GPG_ERR_INV_VALUE
+This value means that some user provided data was out of range.
+
+@item GPG_ERR_UNUSABLE_PUBKEY
+This value means that some recipients for a message were invalid.
+
+@item GPG_ERR_UNUSABLE_SECKEY
+This value means that some signers were invalid.
+
+@item GPG_ERR_NO_DATA
+This value means that data was expected where no data was found.
+
+@item GPG_ERR_CONFLICT
+This value means that a conflict of some sort occurred.
+
+@item GPG_ERR_NOT_IMPLEMENTED
+This value indicates that the specific function (or operation) is not
+implemented. This error should never happen. It can only occur if
+you use certain values or configuration options which do not work,
+but for which we think that they should work at some later time.
+
+@item GPG_ERR_DECRYPT_FAILED
+This value indicates that a decryption operation was unsuccessful.
+
+@item GPG_ERR_WRONG_KEY_USAGE
+This value indicates that a key is not used appropriately.
+
+@item GPG_ERR_NO_SECKEY
+This value indicates that no secret key for the user ID is available.
+
+@item GPG_ERR_UNSUPPORTED_ALGORITHM
+This value means a verification failed because the cryptographic
+algorithm is not supported by the crypto backend.
+
+@item GPG_ERR_BAD_SIGNATURE
+This value means a verification failed because the signature is bad.
+
+@item GPG_ERR_NO_PUBKEY
+This value means a verification failed because the public key is not
+available.
+
+@item GPG_ERR_NOT_OPERATIONAL
+This value means that the library is not yet in state which allows to
+use this function. This error code is in particular returned if
+Libgcrypt is operated in FIPS mode and the internal state of the
+library does not yet or not anymore allow the use of a service.
+
+This error code is only available with newer libgpg-error versions, thus
+you might see ``invalid error code'' when passing this to
+@code{gpg_strerror}. The numeric value of this error code is 176.
+
+@item GPG_ERR_USER_1
+@item GPG_ERR_USER_2
+@item ...
+@item GPG_ERR_USER_16
+These error codes are not used by any GnuPG component and can be
+freely used by other software. Applications using Libgcrypt
+might use them to mark specific errors returned by callback handlers
+if no suitable error codes (including the system errors) for these
+errors exist already.
+@end table
+
+
+@node Error Strings
+@subsection Error Strings
+@cindex error values, printing of
+@cindex error codes, printing of
+@cindex error sources, printing of
+@cindex error strings
+
+@deftypefun {const char *} gcry_strerror (@w{gcry_error_t @var{err}})
+The function @code{gcry_strerror} returns a pointer to a statically
+allocated string containing a description of the error code contained
+in the error value @var{err}. This string can be used to output a
+diagnostic message to the user.
+@end deftypefun
+
+
+@deftypefun {const char *} gcry_strsource (@w{gcry_error_t @var{err}})
+The function @code{gcry_strsource} returns a pointer to a statically
+allocated string containing a description of the error source
+contained in the error value @var{err}. This string can be used to
+output a diagnostic message to the user.
+@end deftypefun
+
+The following example illustrates the use of the functions described
+above:
+
+@example
+@{
+ gcry_cipher_hd_t handle;
+ gcry_error_t err = 0;
+
+ err = gcry_cipher_open (&handle, GCRY_CIPHER_AES,
+ GCRY_CIPHER_MODE_CBC, 0);
+ if (err)
+ @{
+ fprintf (stderr, "Failure: %s/%s\n",
+ gcry_strsource (err),
+ gcry_strerror (err));
+ @}
+@}
+@end example
+
+@c **********************************************************
+@c ******************* General ****************************
+@c **********************************************************
+@node Handler Functions
+@chapter Handler Functions
+
+Libgcrypt makes it possible to install so called `handler functions',
+which get called by Libgcrypt in case of certain events.
+
+@menu
+* Progress handler:: Using a progress handler function.
+* Allocation handler:: Using special memory allocation functions.
+* Error handler:: Using error handler functions.
+* Logging handler:: Using a special logging function.
+@end menu
+
+@node Progress handler
+@section Progress handler
+
+It is often useful to retrieve some feedback while long running
+operations are performed.
+
+@deftp {Data type} gcry_handler_progress_t
+Progress handler functions have to be of the type
+@code{gcry_handler_progress_t}, which is defined as:
+
+@code{void (*gcry_handler_progress_t) (void *, const char *, int, int, int)}
+@end deftp
+
+The following function may be used to register a handler function for
+this purpose.
+
+@deftypefun void gcry_set_progress_handler (gcry_handler_progress_t @var{cb}, void *@var{cb_data})
+
+This function installs @var{cb} as the `Progress handler' function.
+It may be used only during initialization. @var{cb} must be defined
+as follows:
+
+@example
+void
+my_progress_handler (void *@var{cb_data}, const char *@var{what},
+ int @var{printchar}, int @var{current}, int @var{total})
+@{
+ /* Do something. */
+@}
+@end example
+
+A description of the arguments of the progress handler function follows.
+
+@table @var
+@item cb_data
+The argument provided in the call to @code{gcry_set_progress_handler}.
+@item what
+A string identifying the type of the progress output. The following
+values for @var{what} are defined:
+
+@table @code
+@item need_entropy
+Not enough entropy is available. @var{total} holds the number of
+required bytes.
+
+@item wait_dev_random
+Waiting to re-open a random device. @var{total} gives the number of
+seconds until the next try.
+
+@item primegen
+Values for @var{printchar}:
+@table @code
+@item \n
+Prime generated.
+@item !
+Need to refresh the pool of prime numbers.
+@item <, >
+Number of bits adjusted.
+@item ^
+Searching for a generator.
+@item .
+Fermat test on 10 candidates failed.
+@item :
+Restart with a new random value.
+@item +
+Rabin Miller test passed.
+@end table
+
+@end table
+
+@end table
+@end deftypefun
+
+@node Allocation handler
+@section Allocation handler
+
+It is possible to make Libgcrypt use special memory
+allocation functions instead of the built-in ones.
+
+Memory allocation functions are of the following types:
+@deftp {Data type} gcry_handler_alloc_t
+This type is defined as: @code{void *(*gcry_handler_alloc_t) (size_t n)}.
+@end deftp
+@deftp {Data type} gcry_handler_secure_check_t
+This type is defined as: @code{int *(*gcry_handler_secure_check_t) (const void *)}.
+@end deftp
+@deftp {Data type} gcry_handler_realloc_t
+This type is defined as: @code{void *(*gcry_handler_realloc_t) (void *p, size_t n)}.
+@end deftp
+@deftp {Data type} gcry_handler_free_t
+This type is defined as: @code{void *(*gcry_handler_free_t) (void *)}.
+@end deftp
+
+Special memory allocation functions can be installed with the
+following function:
+
+@deftypefun void gcry_set_allocation_handler (gcry_handler_alloc_t @var{func_alloc}, gcry_handler_alloc_t @var{func_alloc_secure}, gcry_handler_secure_check_t @var{func_secure_check}, gcry_handler_realloc_t @var{func_realloc}, gcry_handler_free_t @var{func_free})
+Install the provided functions and use them instead of the built-in
+functions for doing memory allocation. Using this function is in
+general not recommended because the standard Libgcrypt allocation
+functions are guaranteed to zeroize memory if needed.
+
+This function may be used only during initialization and may not be
+used in fips mode.
+
+
+@end deftypefun
+
+@node Error handler
+@section Error handler
+
+The following functions may be used to register handler functions that
+are called by Libgcrypt in case certain error conditions occur. They
+may and should be registered prior to calling @code{gcry_check_version}.
+
+@deftp {Data type} gcry_handler_no_mem_t
+This type is defined as: @code{int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int)}
+@end deftp
+@deftypefun void gcry_set_outofcore_handler (gcry_handler_no_mem_t @var{func_no_mem}, void *@var{cb_data})
+This function registers @var{func_no_mem} as `out-of-core handler',
+which means that it will be called in the case of not having enough
+memory available. The handler is called with 3 arguments: The first
+one is the pointer @var{cb_data} as set with this function, the second
+is the requested memory size and the last being a flag. If bit 0 of
+the flag is set, secure memory has been requested. The handler should
+either return true to indicate that Libgcrypt should try again
+allocating memory or return false to let Libgcrypt use its default
+fatal error handler.
+@end deftypefun
+
+@deftp {Data type} gcry_handler_error_t
+This type is defined as: @code{void (*gcry_handler_error_t) (void *, int, const char *)}
+@end deftp
+
+@deftypefun void gcry_set_fatalerror_handler (gcry_handler_error_t @var{func_error}, void *@var{cb_data})
+This function registers @var{func_error} as `error handler',
+which means that it will be called in error conditions.
+@end deftypefun
+
+@node Logging handler
+@section Logging handler
+
+@deftp {Data type} gcry_handler_log_t
+This type is defined as: @code{void (*gcry_handler_log_t) (void *, int, const char *, va_list)}
+@end deftp
+
+@deftypefun void gcry_set_log_handler (gcry_handler_log_t @var{func_log}, void *@var{cb_data})
+This function registers @var{func_log} as `logging handler', which means
+that it will be called in case Libgcrypt wants to log a message. This
+function may and should be used prior to calling
+@code{gcry_check_version}.
+@end deftypefun
+
+@c **********************************************************
+@c ******************* Ciphers ****************************
+@c **********************************************************
+@c @include cipher-ref.texi
+@node Symmetric cryptography
+@chapter Symmetric cryptography
+
+The cipher functions are used for symmetrical cryptography,
+i.e. cryptography using a shared key. The programming model follows
+an open/process/close paradigm and is in that similar to other
+building blocks provided by Libgcrypt.
+
+@menu
+* Available ciphers:: List of ciphers supported by the library.
+* Available cipher modes:: List of cipher modes supported by the library.
+* Working with cipher handles:: How to perform operations related to cipher handles.
+* General cipher functions:: General cipher functions independent of cipher handles.
+@end menu
+
+@node Available ciphers
+@section Available ciphers
+
+@table @code
+@item GCRY_CIPHER_NONE
+This is not a real algorithm but used by some functions as error return.
+The value always evaluates to false.
+
+@item GCRY_CIPHER_IDEA
+@cindex IDEA
+This is the IDEA algorithm.
+
+@item GCRY_CIPHER_3DES
+@cindex 3DES
+@cindex Triple-DES
+@cindex DES-EDE
+@cindex Digital Encryption Standard
+Triple-DES with 3 Keys as EDE. The key size of this algorithm is 168 bits but
+you have to pass 192 bits because the most significant bits of each byte
+are ignored.
+
+@item GCRY_CIPHER_CAST5
+@cindex CAST5
+CAST128-5 block cipher algorithm. The key size is 128 bits.
+
+@item GCRY_CIPHER_BLOWFISH
+@cindex Blowfish
+The blowfish algorithm. The supported key sizes are 8 to 576 bits in
+8 bit increments.
+
+@item GCRY_CIPHER_SAFER_SK128
+Reserved and not currently implemented.
+
+@item GCRY_CIPHER_DES_SK
+Reserved and not currently implemented.
+
+@item GCRY_CIPHER_AES
+@itemx GCRY_CIPHER_AES128
+@itemx GCRY_CIPHER_RIJNDAEL
+@itemx GCRY_CIPHER_RIJNDAEL128
+@cindex Rijndael
+@cindex AES
+@cindex Advanced Encryption Standard
+AES (Rijndael) with a 128 bit key.
+
+@item GCRY_CIPHER_AES192
+@itemx GCRY_CIPHER_RIJNDAEL192
+AES (Rijndael) with a 192 bit key.
+
+@item GCRY_CIPHER_AES256
+@itemx GCRY_CIPHER_RIJNDAEL256
+AES (Rijndael) with a 256 bit key.
+
+@item GCRY_CIPHER_TWOFISH
+@cindex Twofish
+The Twofish algorithm with a 256 bit key.
+
+@item GCRY_CIPHER_TWOFISH128
+The Twofish algorithm with a 128 bit key.
+
+@item GCRY_CIPHER_ARCFOUR
+@cindex Arcfour
+@cindex RC4
+An algorithm which is 100% compatible with RSA Inc.'s RC4 algorithm.
+Note that this is a stream cipher and must be used very carefully to
+avoid a couple of weaknesses.
+
+@item GCRY_CIPHER_DES
+@cindex DES
+Standard DES with a 56 bit key. You need to pass 64 bit but the high
+bits of each byte are ignored. Note, that this is a weak algorithm
+which can be broken in reasonable time using a brute force approach.
+
+@item GCRY_CIPHER_SERPENT128
+@itemx GCRY_CIPHER_SERPENT192
+@itemx GCRY_CIPHER_SERPENT256
+@cindex Serpent
+The Serpent cipher from the AES contest.
+
+@item GCRY_CIPHER_RFC2268_40
+@itemx GCRY_CIPHER_RFC2268_128
+@cindex rfc-2268
+@cindex RC2
+Ron's Cipher 2 in the 40 and 128 bit variants.
+
+@item GCRY_CIPHER_SEED
+@cindex Seed (cipher)
+A 128 bit cipher as described by RFC4269.
+
+@item GCRY_CIPHER_CAMELLIA128
+@itemx GCRY_CIPHER_CAMELLIA192
+@itemx GCRY_CIPHER_CAMELLIA256
+@cindex Camellia
+The Camellia cipher by NTT. See
+@uref{http://info.isl.ntt.co.jp/@/crypt/@/eng/@/camellia/@/specifications.html}.
+
+@item GCRY_CIPHER_SALSA20
+@cindex Salsa20
+This is the Salsa20 stream cipher.
+
+@item GCRY_CIPHER_SALSA20R12
+@cindex Salsa20/12
+This is the Salsa20/12 - reduced round version of Salsa20 stream cipher.
+
+@item GCRY_CIPHER_GOST28147
+@cindex GOST 28147-89
+The GOST 28147-89 cipher, defined in the respective GOST standard.
+Translation of this GOST into English is provided in the RFC-5830.
+
+@item GCRY_CIPHER_GOST28147_MESH
+@cindex GOST 28147-89 CryptoPro keymeshing
+The GOST 28147-89 cipher, defined in the respective GOST standard.
+Translation of this GOST into English is provided in the RFC-5830.
+This cipher will use CryptoPro keymeshing as defined in RFC 4357
+if it has to be used for the selected parameter set.
+
+@item GCRY_CIPHER_CHACHA20
+@cindex ChaCha20
+This is the ChaCha20 stream cipher.
+
+@item GCRY_CIPHER_SM4
+@cindex SM4 (cipher)
+A 128 bit cipher by the State Cryptography Administration
+of China (SCA). See
+@uref{https://tools.ietf.org/html/draft-ribose-cfrg-sm4-10}.
+
+@end table
+
+@node Available cipher modes
+@section Available cipher modes
+
+@table @code
+@item GCRY_CIPHER_MODE_NONE
+No mode specified. This should not be used. The only exception is that
+if Libgcrypt is not used in FIPS mode and if any debug flag has been
+set, this mode may be used to bypass the actual encryption.
+
+@item GCRY_CIPHER_MODE_ECB
+@cindex ECB, Electronic Codebook mode
+Electronic Codebook mode.
+
+@item GCRY_CIPHER_MODE_CFB
+@item GCRY_CIPHER_MODE_CFB8
+@cindex CFB, Cipher Feedback mode
+Cipher Feedback mode. For GCRY_CIPHER_MODE_CFB the shift size equals
+the block size of the cipher (e.g. for AES it is CFB-128). For
+GCRY_CIPHER_MODE_CFB8 the shift size is 8 bit but that variant is not
+yet available.
+
+@item GCRY_CIPHER_MODE_CBC
+@cindex CBC, Cipher Block Chaining mode
+Cipher Block Chaining mode.
+
+@item GCRY_CIPHER_MODE_STREAM
+Stream mode, only to be used with stream cipher algorithms.
+
+@item GCRY_CIPHER_MODE_OFB
+@cindex OFB, Output Feedback mode
+Output Feedback mode.
+
+@item GCRY_CIPHER_MODE_CTR
+@cindex CTR, Counter mode
+Counter mode.
+
+@item GCRY_CIPHER_MODE_AESWRAP
+@cindex AES-Wrap mode
+This mode is used to implement the AES-Wrap algorithm according to
+RFC-3394. It may be used with any 128 bit block length algorithm,
+however the specs require one of the 3 AES algorithms. These special
+conditions apply: If @code{gcry_cipher_setiv} has not been used the
+standard IV is used; if it has been used the lower 64 bit of the IV
+are used as the Alternative Initial Value. On encryption the provided
+output buffer must be 64 bit (8 byte) larger than the input buffer;
+in-place encryption is still allowed. On decryption the output buffer
+may be specified 64 bit (8 byte) shorter than then input buffer. As
+per specs the input length must be at least 128 bits and the length
+must be a multiple of 64 bits.
+
+@item GCRY_CIPHER_MODE_CCM
+@cindex CCM, Counter with CBC-MAC mode
+Counter with CBC-MAC mode is an Authenticated Encryption with
+Associated Data (AEAD) block cipher mode, which is specified in
+'NIST Special Publication 800-38C' and RFC 3610.
+
+@item GCRY_CIPHER_MODE_GCM
+@cindex GCM, Galois/Counter Mode
+Galois/Counter Mode (GCM) is an Authenticated Encryption with
+Associated Data (AEAD) block cipher mode, which is specified in
+'NIST Special Publication 800-38D'.
+
+@item GCRY_CIPHER_MODE_POLY1305
+@cindex Poly1305 based AEAD mode with ChaCha20
+This mode implements the Poly1305 Authenticated Encryption with Associated
+Data (AEAD) mode according to RFC-8439. This mode can be used with ChaCha20
+stream cipher.
+
+@item GCRY_CIPHER_MODE_OCB
+@cindex OCB, OCB3
+OCB is an Authenticated Encryption with Associated Data (AEAD) block
+cipher mode, which is specified in RFC-7253. Supported tag lengths
+are 128, 96, and 64 bit with the default being 128 bit. To switch to
+a different tag length @code{gcry_cipher_ctl} using the command
+@code{GCRYCTL_SET_TAGLEN} and the address of an @code{int} variable
+set to 12 (for 96 bit) or 8 (for 64 bit) provided for the
+@code{buffer} argument and @code{sizeof(int)} for @code{buflen}.
+
+Note that the use of @code{gcry_cipher_final} is required.
+
+@item GCRY_CIPHER_MODE_XTS
+@cindex XTS, XTS mode
+XEX-based tweaked-codebook mode with ciphertext stealing (XTS) mode
+is used to implement the AES-XTS as specified in IEEE 1619 Standard
+Architecture for Encrypted Shared Storage Media and NIST SP800-38E.
+
+The XTS mode requires doubling key-length, for example, using 512-bit
+key with AES-256 (@code{GCRY_CIPHER_AES256}). The 128-bit tweak value
+is feed to XTS mode as little-endian byte array using
+@code{gcry_cipher_setiv} function. When encrypting or decrypting,
+full-sized data unit buffers needs to be passed to
+@code{gcry_cipher_encrypt} or @code{gcry_cipher_decrypt}. The tweak
+value is automatically incremented after each call of
+@code{gcry_cipher_encrypt} and @code{gcry_cipher_decrypt}.
+Auto-increment allows avoiding need of setting IV between processing
+of sequential data units.
+
+@item GCRY_CIPHER_MODE_EAX
+@cindex EAX, EAX mode
+EAX is an Authenticated Encryption with Associated Data (AEAD) block cipher
+mode by Bellare, Rogaway, and Wagner (see
+@uref{http://web.cs.ucdavis.edu/~rogaway/papers/eax.html}).
+
+@end table
+
+@node Working with cipher handles
+@section Working with cipher handles
+
+To use a cipher algorithm, you must first allocate an according
+handle. This is to be done using the open function:
+
+@deftypefun gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *@var{hd}, int @var{algo}, int @var{mode}, unsigned int @var{flags})
+
+This function creates the context handle required for most of the
+other cipher functions and returns a handle to it in `hd'. In case of
+an error, an according error code is returned.
+
+The ID of algorithm to use must be specified via @var{algo}. See
+@ref{Available ciphers}, for a list of supported ciphers and the
+according constants.
+
+Besides using the constants directly, the function
+@code{gcry_cipher_map_name} may be used to convert the textual name of
+an algorithm into the according numeric ID.
+
+The cipher mode to use must be specified via @var{mode}. See
+@ref{Available cipher modes}, for a list of supported cipher modes
+and the according constants. Note that some modes are incompatible
+with some algorithms - in particular, stream mode
+(@code{GCRY_CIPHER_MODE_STREAM}) only works with stream ciphers.
+Poly1305 AEAD mode (@code{GCRY_CIPHER_MODE_POLY1305}) only works with
+ChaCha20 stream cipher. The block cipher modes
+(@code{GCRY_CIPHER_MODE_ECB}, @code{GCRY_CIPHER_MODE_CBC},
+@code{GCRY_CIPHER_MODE_CFB}, @code{GCRY_CIPHER_MODE_OFB},
+@code{GCRY_CIPHER_MODE_CTR} and @code{GCRY_CIPHER_MODE_EAX}) will work
+with any block cipher algorithm. GCM mode
+(@code{GCRY_CIPHER_MODE_CCM}), CCM mode (@code{GCRY_CIPHER_MODE_GCM}),
+OCB mode (@code{GCRY_CIPHER_MODE_OCB}), and XTS mode
+(@code{GCRY_CIPHER_MODE_XTS}) will only work with block cipher
+algorithms which have the block size of 16 bytes.
+
+The third argument @var{flags} can either be passed as @code{0} or as
+the bit-wise OR of the following constants.
+
+@table @code
+@item GCRY_CIPHER_SECURE
+Make sure that all operations are allocated in secure memory. This is
+useful when the key material is highly confidential.
+@item GCRY_CIPHER_ENABLE_SYNC
+@cindex sync mode (OpenPGP)
+This flag enables the CFB sync mode, which is a special feature of
+Libgcrypt's CFB mode implementation to allow for OpenPGP's CFB variant.
+See @code{gcry_cipher_sync}.
+@item GCRY_CIPHER_CBC_CTS
+@cindex cipher text stealing
+Enable cipher text stealing (CTS) for the CBC mode. Cannot be used
+simultaneous as GCRY_CIPHER_CBC_MAC. CTS mode makes it possible to
+transform data of almost arbitrary size (only limitation is that it
+must be greater than the algorithm's block size).
+@item GCRY_CIPHER_CBC_MAC
+@cindex CBC-MAC
+Compute CBC-MAC keyed checksums. This is the same as CBC mode, but
+only output the last block. Cannot be used simultaneous as
+GCRY_CIPHER_CBC_CTS.
+@end table
+@end deftypefun
+
+Use the following function to release an existing handle:
+
+@deftypefun void gcry_cipher_close (gcry_cipher_hd_t @var{h})
+
+This function releases the context created by @code{gcry_cipher_open}.
+It also zeroises all sensitive information associated with this cipher
+handle.
+@end deftypefun
+
+In order to use a handle for performing cryptographic operations, a
+`key' has to be set first:
+
+@deftypefun gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t @var{h}, const void *@var{k}, size_t @var{l})
+
+Set the key @var{k} used for encryption or decryption in the context
+denoted by the handle @var{h}. The length @var{l} (in bytes) of the
+key @var{k} must match the required length of the algorithm set for
+this context or be in the allowed range for algorithms with variable
+key size. The function checks this and returns an error if there is a
+problem. A caller should always check for an error.
+
+@end deftypefun
+
+Most crypto modes requires an initialization vector (IV), which
+usually is a non-secret random string acting as a kind of salt value.
+The CTR mode requires a counter, which is also similar to a salt
+value. To set the IV or CTR, use these functions:
+
+@deftypefun gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t @var{h}, const void *@var{k}, size_t @var{l})
+
+Set the initialization vector used for encryption or decryption. The
+vector is passed as the buffer @var{K} of length @var{l} bytes and
+copied to internal data structures. The function checks that the IV
+matches the requirement of the selected algorithm and mode.
+
+This function is also used by AEAD modes and with Salsa20 and ChaCha20
+stream ciphers to set or update the required nonce. In these cases it
+needs to be called after setting the key.
+
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t @var{h}, const void *@var{c}, size_t @var{l})
+
+Set the counter vector used for encryption or decryption. The counter
+is passed as the buffer @var{c} of length @var{l} bytes and copied to
+internal data structures. The function checks that the counter
+matches the requirement of the selected algorithm (i.e., it must be
+the same size as the block size).
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t @var{h})
+
+Set the given handle's context back to the state it had after the last
+call to gcry_cipher_setkey and clear the initialization vector.
+
+Note that gcry_cipher_reset is implemented as a macro.
+@end deftypefun
+
+Authenticated Encryption with Associated Data (AEAD) block cipher
+modes require the handling of the authentication tag and the additional
+authenticated data, which can be done by using the following
+functions:
+
+@deftypefun gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t @var{h}, const void *@var{abuf}, size_t @var{abuflen})
+
+Process the buffer @var{abuf} of length @var{abuflen} as the additional
+authenticated data (AAD) for AEAD cipher modes.
+
+@end deftypefun
+
+@deftypefun {gcry_error_t} gcry_cipher_gettag @
+ (@w{gcry_cipher_hd_t @var{h}}, @
+ @w{void *@var{tag}}, @w{size_t @var{taglen}})
+
+This function is used to read the authentication tag after encryption.
+The function finalizes and outputs the authentication tag to the buffer
+@var{tag} of length @var{taglen} bytes.
+
+Depending on the used mode certain restrictions for @var{taglen} are
+enforced: For GCM @var{taglen} must be at least 16 or one of the
+allowed truncated lengths (4, 8, 12, 13, 14, or 15).
+
+@end deftypefun
+
+@deftypefun {gcry_error_t} gcry_cipher_checktag @
+ (@w{gcry_cipher_hd_t @var{h}}, @
+ @w{const void *@var{tag}}, @w{size_t @var{taglen}})
+
+Check the authentication tag after decryption. The authentication
+tag is passed as the buffer @var{tag} of length @var{taglen} bytes
+and compared to internal authentication tag computed during
+decryption. Error code @code{GPG_ERR_CHECKSUM} is returned if
+the authentication tag in the buffer @var{tag} does not match
+the authentication tag calculated during decryption.
+
+Depending on the used mode certain restrictions for @var{taglen} are
+enforced: For GCM @var{taglen} must either be 16 or one of the allowed
+truncated lengths (4, 8, 12, 13, 14, or 15).
+
+@end deftypefun
+
+The actual encryption and decryption is done by using one of the
+following functions. They may be used as often as required to process
+all the data.
+
+@deftypefun gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t @var{h}, unsigned char *{out}, size_t @var{outsize}, const unsigned char *@var{in}, size_t @var{inlen})
+
+@code{gcry_cipher_encrypt} is used to encrypt the data. This function
+can either work in place or with two buffers. It uses the cipher
+context already setup and described by the handle @var{h}. There are 2
+ways to use the function: If @var{in} is passed as @code{NULL} and
+@var{inlen} is @code{0}, in-place encryption of the data in @var{out} of
+length @var{outsize} takes place. With @var{in} being not @code{NULL},
+@var{inlen} bytes are encrypted to the buffer @var{out} which must have
+at least a size of @var{inlen}. @var{outsize} must be set to the
+allocated size of @var{out}, so that the function can check that there
+is sufficient space. Note that overlapping buffers are not allowed.
+
+Depending on the selected algorithms and encryption mode, the length of
+the buffers must be a multiple of the block size.
+
+Some encryption modes require that @code{gcry_cipher_final} is used
+before the final data chunk is passed to this function.
+
+The function returns @code{0} on success or an error code.
+@end deftypefun
+
+
+@deftypefun gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t @var{h}, unsigned char *{out}, size_t @var{outsize}, const unsigned char *@var{in}, size_t @var{inlen})
+
+@code{gcry_cipher_decrypt} is used to decrypt the data. This function
+can either work in place or with two buffers. It uses the cipher
+context already setup and described by the handle @var{h}. There are 2
+ways to use the function: If @var{in} is passed as @code{NULL} and
+@var{inlen} is @code{0}, in-place decryption of the data in @var{out} or
+length @var{outsize} takes place. With @var{in} being not @code{NULL},
+@var{inlen} bytes are decrypted to the buffer @var{out} which must have
+at least a size of @var{inlen}. @var{outsize} must be set to the
+allocated size of @var{out}, so that the function can check that there
+is sufficient space. Note that overlapping buffers are not allowed.
+
+Depending on the selected algorithms and encryption mode, the length of
+the buffers must be a multiple of the block size.
+
+Some encryption modes require that @code{gcry_cipher_final} is used
+before the final data chunk is passed to this function.
+
+The function returns @code{0} on success or an error code.
+@end deftypefun
+
+
+The OCB mode features integrated padding and must thus be told about
+the end of the input data. This is done with:
+
+@deftypefun gcry_error_t gcry_cipher_final (gcry_cipher_hd_t @var{h})
+
+Set a flag in the context to tell the encrypt and decrypt functions
+that their next call will provide the last chunk of data. Only the
+first call to this function has an effect and only for modes which
+support it. Checking the error is in general not necessary. This is
+implemented as a macro.
+@end deftypefun
+
+
+OpenPGP (as defined in RFC-4880) requires a special sync operation in
+some places. The following function is used for this:
+
+@deftypefun gcry_error_t gcry_cipher_sync (gcry_cipher_hd_t @var{h})
+
+Perform the OpenPGP sync operation on context @var{h}. Note that this
+is a no-op unless the context was created with the flag
+@code{GCRY_CIPHER_ENABLE_SYNC}
+@end deftypefun
+
+Some of the described functions are implemented as macros utilizing a
+catch-all control function. This control function is rarely used
+directly but there is nothing which would inhibit it:
+
+@deftypefun gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t @var{h}, int @var{cmd}, void *@var{buffer}, size_t @var{buflen})
+
+@code{gcry_cipher_ctl} controls various aspects of the cipher module and
+specific cipher contexts. Usually some more specialized functions or
+macros are used for this purpose. The semantics of the function and its
+parameters depends on the the command @var{cmd} and the passed context
+handle @var{h}. Please see the comments in the source code
+(@code{src/global.c}) for details.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_cipher_info (gcry_cipher_hd_t @var{h}, @
+ int @var{what}, void *@var{buffer}, size_t *@var{nbytes})
+
+@code{gcry_cipher_info} is used to retrieve various
+information about a cipher context or the cipher module in general.
+
+@c begin constants for gcry_cipher_info
+@table @code
+
+@item GCRYCTL_GET_TAGLEN:
+Return the length of the tag for an AE algorithm mode. An error is
+returned for modes which do not support a tag. @var{buffer} must be
+given as NULL. On success the result is stored @var{nbytes}. The
+taglen is returned in bytes.
+
+@end table
+@c end constants for gcry_cipher_info
+
+@end deftypefun
+
+@node General cipher functions
+@section General cipher functions
+
+To work with the algorithms, several functions are available to map
+algorithm names to the internal identifiers, as well as ways to
+retrieve information about an algorithm or the current cipher context.
+
+@deftypefun gcry_error_t gcry_cipher_algo_info (int @var{algo}, int @var{what}, void *@var{buffer}, size_t *@var{nbytes})
+
+This function is used to retrieve information on a specific algorithm.
+You pass the cipher algorithm ID as @var{algo} and the type of
+information requested as @var{what}. The result is either returned as
+the return code of the function or copied to the provided @var{buffer}
+whose allocated length must be available in an integer variable with the
+address passed in @var{nbytes}. This variable will also receive the
+actual used length of the buffer.
+
+Here is a list of supported codes for @var{what}:
+
+@c begin constants for gcry_cipher_algo_info
+@table @code
+@item GCRYCTL_GET_KEYLEN:
+Return the length of the key. If the algorithm supports multiple key
+lengths, the maximum supported value is returned. The length is
+returned as number of octets (bytes) and not as number of bits in
+@var{nbytes}; @var{buffer} must be zero. Note that it is usually
+better to use the convenience function
+@code{gcry_cipher_get_algo_keylen}.
+
+@item GCRYCTL_GET_BLKLEN:
+Return the block length of the algorithm. The length is returned as a
+number of octets in @var{nbytes}; @var{buffer} must be zero. Note
+that it is usually better to use the convenience function
+@code{gcry_cipher_get_algo_blklen}.
+
+@item GCRYCTL_TEST_ALGO:
+Returns @code{0} when the specified algorithm is available for use.
+@var{buffer} and @var{nbytes} must be zero.
+
+@end table
+@c end constants for gcry_cipher_algo_info
+
+@end deftypefun
+@c end gcry_cipher_algo_info
+
+@deftypefun size_t gcry_cipher_get_algo_keylen (@var{algo})
+
+This function returns length of the key for algorithm @var{algo}. If
+the algorithm supports multiple key lengths, the maximum supported key
+length is returned. On error @code{0} is returned. The key length is
+returned as number of octets.
+
+This is a convenience functions which should be preferred over
+@code{gcry_cipher_algo_info} because it allows for proper type
+checking.
+@end deftypefun
+@c end gcry_cipher_get_algo_keylen
+
+@deftypefun size_t gcry_cipher_get_algo_blklen (int @var{algo})
+
+This functions returns the block-length of the algorithm @var{algo}
+counted in octets. On error @code{0} is returned.
+
+This is a convenience functions which should be preferred over
+@code{gcry_cipher_algo_info} because it allows for proper type
+checking.
+@end deftypefun
+@c end gcry_cipher_get_algo_blklen
+
+
+@deftypefun {const char *} gcry_cipher_algo_name (int @var{algo})
+
+@code{gcry_cipher_algo_name} returns a string with the name of the
+cipher algorithm @var{algo}. If the algorithm is not known or another
+error occurred, the string @code{"?"} is returned. This function should
+not be used to test for the availability of an algorithm.
+@end deftypefun
+
+@deftypefun int gcry_cipher_map_name (const char *@var{name})
+
+@code{gcry_cipher_map_name} returns the algorithm identifier for the
+cipher algorithm described by the string @var{name}. If this algorithm
+is not available @code{0} is returned.
+@end deftypefun
+
+@deftypefun int gcry_cipher_mode_from_oid (const char *@var{string})
+
+Return the cipher mode associated with an @acronym{ASN.1} object
+identifier. The object identifier is expected to be in the
+@acronym{IETF}-style dotted decimal notation. The function returns
+@code{0} for an unknown object identifier or when no mode is associated
+with it.
+@end deftypefun
+
+
+@c **********************************************************
+@c ******************* Public Key *************************
+@c **********************************************************
+@node Public Key cryptography
+@chapter Public Key cryptography
+
+Public key cryptography, also known as asymmetric cryptography, is an
+easy way for key management and to provide digital signatures.
+Libgcrypt provides two completely different interfaces to
+public key cryptography, this chapter explains the one based on
+S-expressions.
+
+@menu
+* Available algorithms:: Algorithms supported by the library.
+* Used S-expressions:: Introduction into the used S-expression.
+* Cryptographic Functions:: Functions for performing the cryptographic actions.
+* Dedicated ECC Functions:: Dedicated functions for elliptic curves.
+* General public-key related Functions:: General functions, not implementing any cryptography.
+@end menu
+
+@node Available algorithms
+@section Available algorithms
+
+Libgcrypt supports the RSA (Rivest-Shamir-Adleman) algorithms as well
+as DSA (Digital Signature Algorithm), Elgamal, ECDSA, ECDH, and EdDSA.
+
+@node Used S-expressions
+@section Used S-expressions
+
+Libgcrypt's API for asymmetric cryptography is based on data structures
+called S-expressions (see
+@uref{http://people.csail.mit.edu/@/rivest/@/sexp.html}) and does not work
+with contexts/handles as most of the other building blocks of Libgcrypt do.
+
+@noindent
+The following information are stored in S-expressions:
+
+@itemize
+@item keys
+
+@item plain text data
+
+@item encrypted data
+
+@item signatures
+
+@end itemize
+
+@noindent
+To describe how Libgcrypt expect keys, we use examples. Note that
+words in
+@ifnottex
+uppercase
+@end ifnottex
+@iftex
+italics
+@end iftex
+indicate parameters whereas lowercase words are literals.
+
+Note that all MPI (multi-precision-integers) values are expected to be in
+@code{GCRYMPI_FMT_USG} format. An easy way to create S-expressions is
+by using @code{gcry_sexp_build} which allows to pass a string with
+printf-like escapes to insert MPI values.
+
+@menu
+* RSA key parameters:: Parameters used with an RSA key.
+* DSA key parameters:: Parameters used with a DSA key.
+* ECC key parameters:: Parameters used with ECC keys.
+@end menu
+
+@node RSA key parameters
+@subsection RSA key parameters
+
+@noindent
+An RSA private key is described by this S-expression:
+
+@example
+(private-key
+ (rsa
+ (n @var{n-mpi})
+ (e @var{e-mpi})
+ (d @var{d-mpi})
+ (p @var{p-mpi})
+ (q @var{q-mpi})
+ (u @var{u-mpi})))
+@end example
+
+@noindent
+An RSA public key is described by this S-expression:
+
+@example
+(public-key
+ (rsa
+ (n @var{n-mpi})
+ (e @var{e-mpi})))
+@end example
+
+
+@table @var
+@item n-mpi
+RSA public modulus @math{n}.
+@item e-mpi
+RSA public exponent @math{e}.
+@item d-mpi
+RSA secret exponent @math{d = e^{-1} \bmod (p-1)(q-1)}.
+@item p-mpi
+RSA secret prime @math{p}.
+@item q-mpi
+RSA secret prime @math{q} with @math{p < q}.
+@item u-mpi
+Multiplicative inverse @math{u = p^{-1} \bmod q}.
+@end table
+
+For signing and decryption the parameters @math{(p, q, u)} are optional
+but greatly improve the performance. Either all of these optional
+parameters must be given or none of them. They are mandatory for
+gcry_pk_testkey.
+
+Note that OpenSSL uses slighly different parameters: @math{q < p} and
+ @math{u = q^{-1} \bmod p}. To use these parameters you will need to
+swap the values and recompute @math{u}. Here is example code to do this:
+
+@example
+ if (gcry_mpi_cmp (p, q) > 0)
+ @{
+ gcry_mpi_swap (p, q);
+ gcry_mpi_invm (u, p, q);
+ @}
+@end example
+
+
+
+
+@node DSA key parameters
+@subsection DSA key parameters
+
+@noindent
+A DSA private key is described by this S-expression:
+
+@example
+(private-key
+ (dsa
+ (p @var{p-mpi})
+ (q @var{q-mpi})
+ (g @var{g-mpi})
+ (y @var{y-mpi})
+ (x @var{x-mpi})))
+@end example
+
+@table @var
+@item p-mpi
+DSA prime @math{p}.
+@item q-mpi
+DSA group order @math{q} (which is a prime divisor of @math{p-1}).
+@item g-mpi
+DSA group generator @math{g}.
+@item y-mpi
+DSA public key value @math{y = g^x \bmod p}.
+@item x-mpi
+DSA secret exponent x.
+@end table
+
+The public key is similar with "private-key" replaced by "public-key"
+and no @var{x-mpi}.
+
+
+@node ECC key parameters
+@subsection ECC key parameters
+
+@anchor{ecc_keyparam}
+@noindent
+An ECC private key is described by this S-expression:
+
+@example
+(private-key
+ (ecc
+ (p @var{p-mpi})
+ (a @var{a-mpi})
+ (b @var{b-mpi})
+ (g @var{g-point})
+ (n @var{n-mpi})
+ (q @var{q-point})
+ (d @var{d-mpi})))
+@end example
+
+@table @var
+@item p-mpi
+Prime specifying the field @math{GF(p)}.
+@item a-mpi
+@itemx b-mpi
+The two coefficients of the Weierstrass equation @math{y^2 = x^3 + ax + b}
+@item g-point
+Base point @math{g}.
+@item n-mpi
+Order of @math{g}
+@item q-point
+The point representing the public key @math{Q = dG}.
+@item d-mpi
+The private key @math{d}
+@end table
+
+All point values are encoded in standard format; Libgcrypt does in
+general only support uncompressed points, thus the first byte needs to
+be @code{0x04}. However ``EdDSA'' describes its own compression
+scheme which is used by default; the non-standard first byte
+@code{0x40} may optionally be used to explicit flag the use of the
+algorithm’s native compression method.
+
+The public key is similar with "private-key" replaced by "public-key"
+and no @var{d-mpi}.
+
+If the domain parameters are well-known, the name of this curve may be
+used. For example
+
+@example
+(private-key
+ (ecc
+ (curve "NIST P-192")
+ (q @var{q-point})
+ (d @var{d-mpi})))
+@end example
+
+Note that @var{q-point} is optional for a private key. The
+@code{curve} parameter may be given in any case and is used to replace
+missing parameters.
+
+@noindent
+Currently implemented curves are:
+
+@table @code
+@item Curve25519
+@itemx X25519
+@itemx 1.3.6.1.4.1.3029.1.5.1
+@itemx 1.3.101.110
+The RFC-8410 255 bit curve, its RFC name, OpenPGP and RFC OIDs.
+
+@item X448
+@itemx 1.3.101.111
+The RFC-8410 448 bit curve and its RFC OID.
+
+@item Ed25519
+@itemx 1.3.6.1.4.1.11591.15.1
+@itemx 1.3.101.112
+The signing variant of the RFC-8410 255 bit curve, its OpenPGP and RFC OIDs.
+
+@item Ed448
+@itemx 1.3.101.113
+The signing variant of the RFC-8410 448 bit curve and its RFC OID.
+
+@item NIST P-192
+@itemx 1.2.840.10045.3.1.1
+@itemx nistp192
+@itemx prime192v1
+@itemx secp192r1
+The NIST 192 bit curve, its OID and aliases.
+
+@item NIST P-224
+@itemx 1.3.132.0.33
+@itemx nistp224
+@itemx secp224r1
+The NIST 224 bit curve, its OID and aliases.
+
+@item NIST P-256
+@itemx 1.2.840.10045.3.1.7
+@itemx nistp256
+@itemx prime256v1
+@itemx secp256r1
+The NIST 256 bit curve, its OID and aliases.
+
+@item NIST P-384
+@itemx 1.3.132.0.34
+@itemx nistp384
+@itemx secp384r1
+The NIST 384 bit curve, its OID and aliases.
+
+@item NIST P-521
+@itemx 1.3.132.0.35
+@itemx nistp521
+@itemx secp521r1
+The NIST 521 bit curve, its OID and aliases.
+
+@item brainpoolP160r1
+@itemx 1.3.36.3.3.2.8.1.1.1
+The Brainpool 160 bit curve and its OID.
+
+@item brainpoolP192r1
+@itemx 1.3.36.3.3.2.8.1.1.3
+The Brainpool 192 bit curve and its OID.
+
+@item brainpoolP224r1
+@itemx 1.3.36.3.3.2.8.1.1.5
+The Brainpool 224 bit curve and its OID.
+
+@item brainpoolP256r1
+@itemx 1.3.36.3.3.2.8.1.1.7
+The Brainpool 256 bit curve and its OID.
+
+@item brainpoolP320r1
+@itemx 1.3.36.3.3.2.8.1.1.9
+The Brainpool 320 bit curve and its OID.
+
+@item brainpoolP384r1
+@itemx 1.3.36.3.3.2.8.1.1.11
+The Brainpool 384 bit curve and its OID.
+
+@item brainpoolP512r1
+@itemx 1.3.36.3.3.2.8.1.1.13
+The Brainpool 512 bit curve and its OID.
+
+@end table
+As usual the OIDs may optionally be prefixed with the string @code{OID.}
+or @code{oid.}.
+
+
+@node Cryptographic Functions
+@section Cryptographic Functions
+
+@noindent
+Some functions operating on S-expressions support `flags' to influence
+the operation. These flags have to be listed in a sub-S-expression
+named `flags'. Flag names are case-sensitive. The following flags
+are known:
+
+@table @code
+
+@item comp
+@itemx nocomp
+@cindex comp
+@cindex nocomp
+If supported by the algorithm and curve the @code{comp} flag requests
+that points are returned in compact (compressed) representation. The
+@code{nocomp} flag requests that points are returned with full
+coordinates. The default depends on the the algorithm and curve. The
+compact representation requires a small overhead before a point can be
+used but halves the size of a to be conveyed public key. If
+@code{comp} is used with the ``EdDSA'' algorithm the key generation
+prefix the public key with a @code{0x40} byte.
+
+@item pkcs1
+@cindex PKCS1
+Use PKCS#1 block type 2 padding for encryption, block type 1 padding
+for signing.
+
+@item oaep
+@cindex OAEP
+Use RSA-OAEP padding for encryption.
+
+@item pss
+@cindex PSS
+Use RSA-PSS padding for signing.
+
+@item eddsa
+@cindex EdDSA
+Use the EdDSA scheme signing instead of the default ECDSA algorithm.
+Note that the EdDSA uses a special form of the public key.
+
+@item rfc6979
+@cindex RFC6979
+For DSA and ECDSA use a deterministic scheme for the k parameter.
+
+@item no-blinding
+@cindex no-blinding
+Do not use a technique called `blinding', which is used by default in
+order to prevent leaking of secret information. Blinding is only
+implemented by RSA, but it might be implemented by other algorithms in
+the future as well, when necessary.
+
+@item param
+@cindex param
+For ECC key generation also return the domain parameters. For ECC
+signing and verification override default parameters by provided
+domain parameters of the public or private key.
+
+@item transient-key
+@cindex transient-key
+This flag is only meaningful for RSA, DSA, and ECC key generation. If
+given the key is created using a faster and a somewhat less secure
+random number generator. This flag may be used for keys which are
+only used for a short time or per-message and do not require full
+cryptographic strength.
+
+@item no-keytest
+@cindex no-keytest
+This flag skips internal failsafe tests to assert that a generated key
+is properly working. It currently has an effect only for standard ECC
+key generation. It is mostly useful along with transient-key to
+achieve fastest ECC key generation.
+
+@item use-x931
+@cindex X9.31
+Force the use of the ANSI X9.31 key generation algorithm instead of
+the default algorithm. This flag is only meaningful for RSA key
+generation and usually not required. Note that this algorithm is
+implicitly used if either @code{derive-parms} is given or Libgcrypt is
+in FIPS mode.
+
+@item use-fips186
+@cindex FIPS 186
+Force the use of the FIPS 186 key generation algorithm instead of the
+default algorithm. This flag is only meaningful for DSA and usually
+not required. Note that this algorithm is implicitly used if either
+@code{derive-parms} is given or Libgcrypt is in FIPS mode. As of now
+FIPS 186-2 is implemented; after the approval of FIPS 186-3 the code
+will be changed to implement 186-3.
+
+@item use-fips186-2
+@cindex FIPS 186-2
+Force the use of the FIPS 186-2 key generation algorithm instead of
+the default algorithm. This algorithm is slightly different from
+FIPS 186-3 and allows only 1024 bit keys. This flag is only meaningful
+for DSA and only required for FIPS testing backward compatibility.
+
+@end table
+
+@noindent
+Now that we know the key basics, we can carry on and explain how to
+encrypt and decrypt data. In almost all cases the data is a random
+session key which is in turn used for the actual encryption of the real
+data. There are 2 functions to do this:
+
+@deftypefun gcry_error_t gcry_pk_encrypt (@w{gcry_sexp_t *@var{r_ciph},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{pkey}})
+
+Obviously a public key must be provided for encryption. It is
+expected as an appropriate S-expression (see above) in @var{pkey}.
+The data to be encrypted can either be in the simple old format, which
+is a very simple S-expression consisting only of one MPI, or it may be
+a more complex S-expression which also allows to specify flags for
+operation, like e.g. padding rules.
+
+@noindent
+If you don't want to let Libgcrypt handle the padding, you must pass an
+appropriate MPI using this expression for @var{data}:
+
+@example
+(data
+ (flags raw)
+ (value @var{mpi}))
+@end example
+
+@noindent
+This has the same semantics as the old style MPI only way. @var{MPI}
+is the actual data, already padded appropriate for your protocol.
+Most RSA based systems however use PKCS#1 padding and so you can use
+this S-expression for @var{data}:
+
+@example
+(data
+ (flags pkcs1)
+ (value @var{block}))
+@end example
+
+@noindent
+Here, the "flags" list has the "pkcs1" flag which let the function know
+that it should provide PKCS#1 block type 2 padding. The actual data to
+be encrypted is passed as a string of octets in @var{block}. The
+function checks that this data actually can be used with the given key,
+does the padding and encrypts it.
+
+If the function could successfully perform the encryption, the return
+value will be 0 and a new S-expression with the encrypted result is
+allocated and assigned to the variable at the address of @var{r_ciph}.
+The caller is responsible to release this value using
+@code{gcry_sexp_release}. In case of an error, an error code is
+returned and @var{r_ciph} will be set to @code{NULL}.
+
+@noindent
+The returned S-expression has this format when used with RSA:
+
+@example
+(enc-val
+ (rsa
+ (a @var{a-mpi})))
+@end example
+
+@noindent
+Where @var{a-mpi} is an MPI with the result of the RSA operation. When
+using the Elgamal algorithm, the return value will have this format:
+
+@example
+(enc-val
+ (elg
+ (a @var{a-mpi})
+ (b @var{b-mpi})))
+@end example
+
+@noindent
+Where @var{a-mpi} and @var{b-mpi} are MPIs with the result of the
+Elgamal encryption operation.
+@end deftypefun
+@c end gcry_pk_encrypt
+
+@deftypefun gcry_error_t gcry_pk_decrypt (@w{gcry_sexp_t *@var{r_plain},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{skey}})
+
+Obviously a private key must be provided for decryption. It is expected
+as an appropriate S-expression (see above) in @var{skey}. The data to
+be decrypted must match the format of the result as returned by
+@code{gcry_pk_encrypt}, but should be enlarged with a @code{flags}
+element:
+
+@example
+(enc-val
+ (flags)
+ (elg
+ (a @var{a-mpi})
+ (b @var{b-mpi})))
+@end example
+
+@noindent
+This function does not remove padding from the data by default. To
+let Libgcrypt remove padding, give a hint in `flags' telling which
+padding method was used when encrypting:
+
+@example
+(flags @var{padding-method})
+@end example
+
+@noindent
+Currently @var{padding-method} is either @code{pkcs1} for PKCS#1 block
+type 2 padding, or @code{oaep} for RSA-OAEP padding.
+
+@noindent
+The function returns 0 on success or an error code. The variable at the
+address of @var{r_plain} will be set to NULL on error or receive the
+decrypted value on success. The format of @var{r_plain} is a
+simple S-expression part (i.e. not a valid one) with just one MPI if
+there was no @code{flags} element in @var{data}; if at least an empty
+@code{flags} is passed in @var{data}, the format is:
+
+@example
+(value @var{plaintext})
+@end example
+@end deftypefun
+@c end gcry_pk_decrypt
+
+
+Another operation commonly performed using public key cryptography is
+signing data. In some sense this is even more important than
+encryption because digital signatures are an important instrument for
+key management. Libgcrypt supports digital signatures using
+2 functions, similar to the encryption functions:
+
+@deftypefun gcry_error_t gcry_pk_sign (@w{gcry_sexp_t *@var{r_sig},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{skey}})
+
+This function creates a digital signature for @var{data} using the
+private key @var{skey} and place it into the variable at the address of
+@var{r_sig}. @var{data} may either be the simple old style S-expression
+with just one MPI or a modern and more versatile S-expression which
+allows to let Libgcrypt handle padding:
+
+@example
+ (data
+ (flags pkcs1)
+ (hash @var{hash-algo} @var{block}))
+@end example
+
+@noindent
+This example requests to sign the data in @var{block} after applying
+PKCS#1 block type 1 style padding. @var{hash-algo} is a string with the
+hash algorithm to be encoded into the signature, this may be any hash
+algorithm name as supported by Libgcrypt. Most likely, this will be
+"sha256" or "sha1". It is obvious that the length of @var{block} must
+match the size of that message digests; the function checks that this
+and other constraints are valid.
+
+@noindent
+If PKCS#1 padding is not required (because the caller does already
+provide a padded value), either the old format or better the following
+format should be used:
+
+@example
+(data
+ (flags raw)
+ (value @var{mpi}))
+@end example
+
+@noindent
+Here, the data to be signed is directly given as an @var{MPI}.
+
+@noindent
+For DSA the input data is expected in this format:
+
+@example
+(data
+ (flags raw)
+ (value @var{mpi}))
+@end example
+
+@noindent
+Here, the data to be signed is directly given as an @var{MPI}. It is
+expect that this MPI is the the hash value. For the standard DSA
+using a MPI is not a problem in regard to leading zeroes because the
+hash value is directly used as an MPI. For better standard
+conformance it would be better to explicit use a memory string (like
+with pkcs1) but that is currently not supported. However, for
+deterministic DSA as specified in RFC6979 this can't be used. Instead
+the following input is expected.
+
+@example
+(data
+ (flags rfc6979)
+ (hash @var{hash-algo} @var{block}))
+@end example
+
+Note that the provided hash-algo is used for the internal HMAC; it
+should match the hash-algo used to create @var{block}.
+
+
+@noindent
+The signature is returned as a newly allocated S-expression in
+@var{r_sig} using this format for RSA:
+
+@example
+(sig-val
+ (rsa
+ (s @var{s-mpi})))
+@end example
+
+Where @var{s-mpi} is the result of the RSA sign operation. For DSA the
+S-expression returned is:
+
+@example
+(sig-val
+ (dsa
+ (r @var{r-mpi})
+ (s @var{s-mpi})))
+@end example
+
+Where @var{r-mpi} and @var{s-mpi} are the result of the DSA sign
+operation.
+
+For Elgamal signing (which is slow, yields large numbers and probably
+is not as secure as the other algorithms), the same format is used
+with "elg" replacing "dsa"; for ECDSA signing, the same format is used
+with "ecdsa" replacing "dsa".
+
+For the EdDSA algorithm (cf. Ed25515) the required input parameters are:
+
+@example
+(data
+ (flags eddsa)
+ (hash-algo sha512)
+ (value @var{message}))
+@end example
+
+Note that the @var{message} may be of any length; hashing is part of
+the algorithm. Using a large data block for @var{message} is in
+general not suggested; in that case the used protocol should better
+require that a hash of the message is used as input to the EdDSA
+algorithm. Note that for X.509 certificates @var{message} is the
+@code{tbsCertificate} part and in CMS @var{message} is the
+@code{signedAttrs} part; see RFC-8410 and RFC-8419.
+
+
+@end deftypefun
+@c end gcry_pk_sign
+
+@noindent
+The operation most commonly used is definitely the verification of a
+signature. Libgcrypt provides this function:
+
+@deftypefun gcry_error_t gcry_pk_verify (@w{gcry_sexp_t @var{sig}}, @w{gcry_sexp_t @var{data}}, @w{gcry_sexp_t @var{pkey}})
+
+This is used to check whether the signature @var{sig} matches the
+@var{data}. The public key @var{pkey} must be provided to perform this
+verification. This function is similar in its parameters to
+@code{gcry_pk_sign} with the exceptions that the public key is used
+instead of the private key and that no signature is created but a
+signature, in a format as created by @code{gcry_pk_sign}, is passed to
+the function in @var{sig}.
+
+@noindent
+The result is 0 for success (i.e. the data matches the signature), or an
+error code where the most relevant code is @code{GCRY_ERR_BAD_SIGNATURE}
+to indicate that the signature does not match the provided data.
+
+@end deftypefun
+@c end gcry_pk_verify
+
+
+@node Dedicated ECC Functions
+@section Dedicated functions for elliptic curves.
+
+@noindent
+The S-expression based interface is for certain operations on elliptic
+curves not optimal. Thus a few special functions are implemented to
+support common operations on curves with one of these assigned curve
+ids:
+
+@table @code
+@item GCRY_ECC_CURVE25519
+@item GCRY_ECC_CURVE448
+@end table
+
+@deftypefun @w{unsigned int} gcry_ecc_get_algo_keylen (@w{int @var{curveid}});
+
+Returns the length in bytes of a point on the curve with the id
+@var{curveid}. 0 is returned for curves which have no assigned id.
+@end deftypefun
+
+
+@deftypefun gpg_error_t gcry_ecc_mul_point @
+ (@w{int @var{curveid}}, @
+ @w{unsigned char *@var{result}}, @
+ @w{const unsigned char *@var{scalar}}, @
+ @w{const unsigned char *@var{point}})
+
+This function computes the scalar multiplication on the Montgomery
+form of the curve with id @var{curveid}. If @var{point} is NULL the
+base point of the curve is used. The caller needs to provide a large
+enough buffer for @var{result} and a valid @var{scalar} and
+@var{point}.
+@end deftypefun
+
+
+@node General public-key related Functions
+@section General public-key related Functions
+
+@noindent
+A couple of utility functions are available to retrieve the length of
+the key, map algorithm identifiers and perform sanity checks:
+
+@deftypefun {const char *} gcry_pk_algo_name (int @var{algo})
+
+Map the public key algorithm id @var{algo} to a string representation of
+the algorithm name. For unknown algorithms this functions returns the
+string @code{"?"}. This function should not be used to test for the
+availability of an algorithm.
+@end deftypefun
+
+@deftypefun int gcry_pk_map_name (const char *@var{name})
+
+Map the algorithm @var{name} to a public key algorithm Id. Returns 0 if
+the algorithm name is not known.
+@end deftypefun
+
+@deftypefun int gcry_pk_test_algo (int @var{algo})
+
+Return 0 if the public key algorithm @var{algo} is available for use.
+Note that this is implemented as a macro.
+@end deftypefun
+
+
+@deftypefun {unsigned int} gcry_pk_get_nbits (gcry_sexp_t @var{key})
+
+Return what is commonly referred as the key length for the given
+public or private in @var{key}.
+@end deftypefun
+
+@deftypefun {unsigned char *} gcry_pk_get_keygrip (@w{gcry_sexp_t @var{key}}, @w{unsigned char *@var{array}})
+
+Return the so called "keygrip" which is the SHA-1 hash of the public key
+parameters expressed in a way depended on the algorithm. @var{array}
+must either provide space for 20 bytes or be @code{NULL}. In the latter
+case a newly allocated array of that size is returned. On success a
+pointer to the newly allocated space or to @var{array} is returned.
+@code{NULL} is returned to indicate an error which is most likely an
+unknown algorithm or one where a "keygrip" has not yet been defined.
+The function accepts public or secret keys in @var{key}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_pk_testkey (gcry_sexp_t @var{key})
+
+Return zero if the private key @var{key} is `sane', an error code otherwise.
+Note that it is not possible to check the `saneness' of a public key.
+
+@end deftypefun
+
+
+@deftypefun gcry_error_t gcry_pk_algo_info (@w{int @var{algo}}, @w{int @var{what}}, @w{void *@var{buffer}}, @w{size_t *@var{nbytes}})
+
+Depending on the value of @var{what} return various information about
+the public key algorithm with the id @var{algo}. Note that the
+function returns @code{-1} on error and the actual error code must be
+retrieved using the function @code{gcry_errno}. The currently defined
+values for @var{what} are:
+
+@table @code
+@item GCRYCTL_TEST_ALGO:
+Return 0 if the specified algorithm is available for use.
+@var{buffer} must be @code{NULL}, @var{nbytes} may be passed as
+@code{NULL} or point to a variable with the required usage of the
+algorithm. This may be 0 for "don't care" or the bit-wise OR of these
+flags:
+
+@table @code
+@item GCRY_PK_USAGE_SIGN
+Algorithm is usable for signing.
+@item GCRY_PK_USAGE_ENCR
+Algorithm is usable for encryption.
+@end table
+
+Unless you need to test for the allowed usage, it is in general better
+to use the macro gcry_pk_test_algo instead.
+
+@item GCRYCTL_GET_ALGO_USAGE:
+Return the usage flags for the given algorithm. An invalid algorithm
+return 0. Disabled algorithms are ignored here because we
+want to know whether the algorithm is at all capable of a certain usage.
+
+@item GCRYCTL_GET_ALGO_NPKEY
+Return the number of elements the public key for algorithm @var{algo}
+consist of. Return 0 for an unknown algorithm.
+
+@item GCRYCTL_GET_ALGO_NSKEY
+Return the number of elements the private key for algorithm @var{algo}
+consist of. Note that this value is always larger than that of the
+public key. Return 0 for an unknown algorithm.
+
+@item GCRYCTL_GET_ALGO_NSIGN
+Return the number of elements a signature created with the algorithm
+@var{algo} consists of. Return 0 for an unknown algorithm or for an
+algorithm not capable of creating signatures.
+
+@item GCRYCTL_GET_ALGO_NENCR
+Return the number of elements a encrypted message created with the algorithm
+@var{algo} consists of. Return 0 for an unknown algorithm or for an
+algorithm not capable of encryption.
+@end table
+
+@noindent
+Please note that parameters not required should be passed as @code{NULL}.
+@end deftypefun
+@c end gcry_pk_algo_info
+
+
+@deftypefun gcry_error_t gcry_pk_ctl (@w{int @var{cmd}}, @w{void *@var{buffer}}, @w{size_t @var{buflen}})
+
+This is a general purpose function to perform certain control
+operations. @var{cmd} controls what is to be done. The return value is
+0 for success or an error code. Currently supported values for
+@var{cmd} are:
+
+@table @code
+@item GCRYCTL_DISABLE_ALGO
+Disable the algorithm given as an algorithm id in @var{buffer}.
+@var{buffer} must point to an @code{int} variable with the algorithm
+id and @var{buflen} must have the value @code{sizeof (int)}. This
+function is not thread safe and should thus be used before any other
+threads are started.
+
+@end table
+@end deftypefun
+@c end gcry_pk_ctl
+
+@noindent
+Libgcrypt also provides a function to generate public key
+pairs:
+
+@deftypefun gcry_error_t gcry_pk_genkey (@w{gcry_sexp_t *@var{r_key}}, @w{gcry_sexp_t @var{parms}})
+
+This function create a new public key pair using information given in
+the S-expression @var{parms} and stores the private and the public key
+in one new S-expression at the address given by @var{r_key}. In case of
+an error, @var{r_key} is set to @code{NULL}. The return code is 0 for
+success or an error code otherwise.
+
+@noindent
+Here is an example for @var{parms} to create an 2048 bit RSA key:
+
+@example
+(genkey
+ (rsa
+ (nbits 4:2048)))
+@end example
+
+@noindent
+To create an Elgamal key, substitute "elg" for "rsa" and to create a DSA
+key use "dsa". Valid ranges for the key length depend on the
+algorithms; all commonly used key lengths are supported. Currently
+supported parameters are:
+
+@table @code
+@item nbits
+This is always required to specify the length of the key. The
+argument is a string with a number in C-notation. The value should be
+a multiple of 8. Note that the S-expression syntax requires that a
+number is prefixed with its string length; thus the @code{4:} in the
+above example.
+
+@item curve @var{name}
+For ECC a named curve may be used instead of giving the number of
+requested bits. This allows to request a specific curve to override a
+default selection Libgcrypt would have taken if @code{nbits} has been
+given. The available names are listed with the description of the ECC
+public key parameters.
+
+@item rsa-use-e @var{value}
+This is only used with RSA to give a hint for the public exponent. The
+@var{value} will be used as a base to test for a usable exponent. Some
+values are special:
+
+@table @samp
+@item 0
+Use a secure and fast value. This is currently the number 41.
+@item 1
+Use a value as required by some crypto policies. This is currently
+the number 65537.
+@item 2
+Reserved
+@item > 2
+Use the given value.
+@end table
+
+@noindent
+If this parameter is not used, Libgcrypt uses for historic reasons
+65537. Note that the value must fit into a 32 bit unsigned variable
+and that the usual C prefixes are considered (e.g. 017 gives 15).
+
+
+@item qbits @var{n}
+This is only meanigful for DSA keys. If it is given the DSA key is
+generated with a Q parameyer of size @var{n} bits. If it is not given
+or zero Q is deduced from NBITS in this way:
+@table @samp
+@item 512 <= N <= 1024
+Q = 160
+@item N = 2048
+Q = 224
+@item N = 3072
+Q = 256
+@item N = 7680
+Q = 384
+@item N = 15360
+Q = 512
+@end table
+Note that in this case only the values for N, as given in the table,
+are allowed. When specifying Q all values of N in the range 512 to
+15680 are valid as long as they are multiples of 8.
+
+@item domain @var{list}
+This is only meaningful for DLP algorithms. If specified keys are
+generated with domain parameters taken from this list. The exact
+format of this parameter depends on the actual algorithm. It is
+currently only implemented for DSA using this format:
+
+@example
+(genkey
+ (dsa
+ (domain
+ (p @var{p-mpi})
+ (q @var{q-mpi})
+ (g @var{q-mpi}))))
+@end example
+
+@code{nbits} and @code{qbits} may not be specified because they are
+derived from the domain parameters.
+
+@item derive-parms @var{list}
+This is currently only implemented for RSA and DSA keys. It is not
+allowed to use this together with a @code{domain} specification. If
+given, it is used to derive the keys using the given parameters.
+
+If given for an RSA key the X9.31 key generation algorithm is used
+even if libgcrypt is not in FIPS mode. If given for a DSA key, the
+FIPS 186 algorithm is used even if libgcrypt is not in FIPS mode.
+
+@example
+(genkey
+ (rsa
+ (nbits 4:1024)
+ (rsa-use-e 1:3)
+ (derive-parms
+ (Xp1 #1A1916DDB29B4EB7EB6732E128#)
+ (Xp2 #192E8AAC41C576C822D93EA433#)
+ (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D
+ 769D6D76646C7A792E16EBD89FE6FC5B605A6493
+ 39DFC925A86A4C6D150B71B9EEA02D68885F5009
+ B98BD984#)
+ (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
+ (Xq2 #134E4CAA16D2350A21D775C404#)
+ (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
+ 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
+ 321DE34A#))))
+@end example
+
+@example
+(genkey
+ (dsa
+ (nbits 4:1024)
+ (derive-parms
+ (seed @var{seed-mpi}))))
+@end example
+
+
+@item flags @var{flaglist}
+This is preferred way to define flags. @var{flaglist} may contain any
+number of flags. See above for a specification of these flags.
+
+Here is an example on how to create a key using curve Ed25519 with the
+ECDSA signature algorithm. Note that the use of ECDSA with that curve
+is in general not recommended.
+@example
+(genkey
+ (ecc
+ (flags transient-key)))
+@end example
+
+@item transient-key
+@itemx use-x931
+@itemx use-fips186
+@itemx use-fips186-2
+These are deprecated ways to set a flag with that name; see above for
+a description of each flag.
+
+
+@end table
+@c end table of parameters
+
+@noindent
+The key pair is returned in a format depending on the algorithm. Both
+private and public keys are returned in one container and may be
+accompanied by some miscellaneous information.
+
+@noindent
+Here are two examples; the first for Elgamal and the second for
+elliptic curve key generation:
+
+@example
+(key-data
+ (public-key
+ (elg
+ (p @var{p-mpi})
+ (g @var{g-mpi})
+ (y @var{y-mpi})))
+ (private-key
+ (elg
+ (p @var{p-mpi})
+ (g @var{g-mpi})
+ (y @var{y-mpi})
+ (x @var{x-mpi})))
+ (misc-key-info
+ (pm1-factors @var{n1 n2 ... nn}))
+@end example
+
+@example
+(key-data
+ (public-key
+ (ecc
+ (curve Ed25519)
+ (flags eddsa)
+ (q @var{q-value})))
+ (private-key
+ (ecc
+ (curve Ed25519)
+ (flags eddsa)
+ (q @var{q-value})
+ (d @var{d-value}))))
+@end example
+
+@noindent
+As you can see, some of the information is duplicated, but this
+provides an easy way to extract either the public or the private key.
+Note that the order of the elements is not defined, e.g. the private
+key may be stored before the public key. @var{n1 n2 ... nn} is a list
+of prime numbers used to composite @var{p-mpi}; this is in general not
+a very useful information and only available if the key generation
+algorithm provides them.
+@end deftypefun
+@c end gcry_pk_genkey
+
+
+@noindent
+Future versions of Libgcrypt will have extended versions of the public
+key interfaced which will take an additional context to allow for
+pre-computations, special operations, and other optimization. As a
+first step a new function is introduced to help using the ECC
+algorithms in new ways:
+
+@deftypefun gcry_error_t gcry_pubkey_get_sexp (@w{gcry_sexp_t *@var{r_sexp}}, @
+ @w{int @var{mode}}, @w{gcry_ctx_t @var{ctx}})
+
+Return an S-expression representing the context @var{ctx}. Depending
+on the state of that context, the S-expression may either be a public
+key, a private key or any other object used with public key
+operations. On success 0 is returned and a new S-expression is stored
+at @var{r_sexp}; on error an error code is returned and NULL is stored
+at @var{r_sexp}. @var{mode} must be one of:
+
+@table @code
+@item 0
+Decide what to return depending on the context. For example if the
+private key parameter is available a private key is returned, if not a
+public key is returned.
+
+@item GCRY_PK_GET_PUBKEY
+Return the public key even if the context has the private key
+parameter.
+
+@item GCRY_PK_GET_SECKEY
+Return the private key or the error @code{GPG_ERR_NO_SECKEY} if it is
+not possible.
+@end table
+
+As of now this function supports only certain ECC operations because a
+context object is right now only defined for ECC. Over time this
+function will be extended to cover more algorithms.
+
+@end deftypefun
+@c end gcry_pubkey_get_sexp
+
+
+
+
+
+@c **********************************************************
+@c ******************* Hash Functions *********************
+@c **********************************************************
+@node Hashing
+@chapter Hashing
+
+Libgcrypt provides an easy and consistent to use interface for hashing.
+Hashing is buffered and several hash algorithms can be updated at once.
+It is possible to compute a HMAC using the same routines. The
+programming model follows an open/process/close paradigm and is in that
+similar to other building blocks provided by Libgcrypt.
+
+For convenience reasons, a few cyclic redundancy check value operations
+are also supported.
+
+@menu
+* Available hash algorithms:: List of hash algorithms supported by the library.
+* Working with hash algorithms:: List of functions related to hashing.
+@end menu
+
+@node Available hash algorithms
+@section Available hash algorithms
+
+@c begin table of hash algorithms
+@cindex SHA-1
+@cindex SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256
+@cindex SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256
+@cindex RIPE-MD-160
+@cindex MD2, MD4, MD5
+@cindex TIGER, TIGER1, TIGER2
+@cindex HAVAL
+@cindex SM3
+@cindex Whirlpool
+@cindex BLAKE2b-512, BLAKE2b-384, BLAKE2b-256, BLAKE2b-160
+@cindex BLAKE2s-256, BLAKE2s-224, BLAKE2s-160, BLAKE2s-128
+@cindex CRC32
+@table @code
+@item GCRY_MD_NONE
+This is not a real algorithm but used by some functions as an error
+return value. This constant is guaranteed to have the value @code{0}.
+
+@item GCRY_MD_SHA1
+This is the SHA-1 algorithm which yields a message digest of 20 bytes.
+Note that SHA-1 begins to show some weaknesses and it is suggested to
+fade out its use if strong cryptographic properties are required.
+
+@item GCRY_MD_RMD160
+This is the 160 bit version of the RIPE message digest (RIPE-MD-160).
+Like SHA-1 it also yields a digest of 20 bytes. This algorithm share a
+lot of design properties with SHA-1 and thus it is advisable not to use
+it for new protocols.
+
+@item GCRY_MD_MD5
+This is the well known MD5 algorithm, which yields a message digest of
+16 bytes. Note that the MD5 algorithm has severe weaknesses, for
+example it is easy to compute two messages yielding the same hash
+(collision attack). The use of this algorithm is only justified for
+non-cryptographic application.
+
+
+@item GCRY_MD_MD4
+This is the MD4 algorithm, which yields a message digest of 16 bytes.
+This algorithm has severe weaknesses and should not be used.
+
+@item GCRY_MD_MD2
+This is an reserved identifier for MD-2; there is no implementation yet.
+This algorithm has severe weaknesses and should not be used.
+
+@item GCRY_MD_TIGER
+This is the TIGER/192 algorithm which yields a message digest of 24
+bytes. Actually this is a variant of TIGER with a different output
+print order as used by GnuPG up to version 1.3.2.
+
+@item GCRY_MD_TIGER1
+This is the TIGER variant as used by the NESSIE project. It uses the
+most commonly used output print order.
+
+@item GCRY_MD_TIGER2
+This is another variant of TIGER with a different padding scheme.
+
+
+@item GCRY_MD_HAVAL
+This is an reserved value for the HAVAL algorithm with 5 passes and 160
+bit. It yields a message digest of 20 bytes. Note that there is no
+implementation yet available.
+
+@item GCRY_MD_SHA224
+This is the SHA-224 algorithm which yields a message digest of 28 bytes.
+See Change Notice 1 for FIPS 180-2 for the specification.
+
+@item GCRY_MD_SHA256
+This is the SHA-256 algorithm which yields a message digest of 32 bytes.
+See FIPS 180-2 for the specification.
+
+@item GCRY_MD_SHA384
+This is the SHA-384 algorithm which yields a message digest of 48 bytes.
+See FIPS 180-2 for the specification.
+
+@item GCRY_MD_SHA512
+This is the SHA-512 algorithm which yields a message digest of 64 bytes.
+See FIPS 180-2 for the specification.
+
+@item GCRY_MD_SHA512_224
+This is the SHA-512/224 algorithm which yields a message digest of 28 bytes.
+See FIPS 180-4 for the specification.
+
+@item GCRY_MD_SHA512_256
+This is the SHA-512/256 algorithm which yields a message digest of 32 bytes.
+See FIPS 180-4 for the specification.
+
+@item GCRY_MD_SHA3_224
+This is the SHA3-224 algorithm which yields a message digest of 28 bytes.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHA3_256
+This is the SHA3-256 algorithm which yields a message digest of 32 bytes.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHA3_384
+This is the SHA3-384 algorithm which yields a message digest of 48 bytes.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHA3_512
+This is the SHA3-512 algorithm which yields a message digest of 64 bytes.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHAKE128
+This is the SHAKE128 extendable-output function (XOF) algorithm with 128 bit
+security strength.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_SHAKE256
+This is the SHAKE256 extendable-output function (XOF) algorithm with 256 bit
+security strength.
+See FIPS 202 for the specification.
+
+@item GCRY_MD_CRC32
+This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It yields
+an output of 4 bytes. Note that this is not a hash algorithm in the
+cryptographic sense.
+
+@item GCRY_MD_CRC32_RFC1510
+This is the above cyclic redundancy check function, as modified by RFC
+1510. It yields an output of 4 bytes. Note that this is not a hash
+algorithm in the cryptographic sense.
+
+@item GCRY_MD_CRC24_RFC2440
+This is the OpenPGP cyclic redundancy check function. It yields an
+output of 3 bytes. Note that this is not a hash algorithm in the
+cryptographic sense.
+
+@item GCRY_MD_WHIRLPOOL
+This is the Whirlpool algorithm which yields a message digest of 64
+bytes.
+
+@item GCRY_MD_GOSTR3411_94
+This is the hash algorithm described in GOST R 34.11-94 which yields a
+message digest of 32 bytes.
+
+@item GCRY_MD_STRIBOG256
+This is the 256-bit version of hash algorithm described in GOST R 34.11-2012
+which yields a message digest of 32 bytes.
+
+@item GCRY_MD_STRIBOG512
+This is the 512-bit version of hash algorithm described in GOST R 34.11-2012
+which yields a message digest of 64 bytes.
+
+@item GCRY_MD_BLAKE2B_512
+This is the BLAKE2b-512 algorithm which yields a message digest of 64 bytes.
+See RFC 7693 for the specification.
+
+@item GCRY_MD_BLAKE2B_384
+This is the BLAKE2b-384 algorithm which yields a message digest of 48 bytes.
+See RFC 7693 for the specification.
+
+@item GCRY_MD_BLAKE2B_256
+This is the BLAKE2b-256 algorithm which yields a message digest of 32 bytes.
+See RFC 7693 for the specification.
+
+@item GCRY_MD_BLAKE2B_160
+This is the BLAKE2b-160 algorithm which yields a message digest of 20 bytes.
+See RFC 7693 for the specification.
+
+@item GCRY_MD_BLAKE2S_256
+This is the BLAKE2s-256 algorithm which yields a message digest of 32 bytes.
+See RFC 7693 for the specification.
+
+@item GCRY_MD_BLAKE2S_224
+This is the BLAKE2s-224 algorithm which yields a message digest of 28 bytes.
+See RFC 7693 for the specification.
+
+@item GCRY_MD_BLAKE2S_160
+This is the BLAKE2s-160 algorithm which yields a message digest of 20 bytes.
+See RFC 7693 for the specification.
+
+@item GCRY_MD_BLAKE2S_128
+This is the BLAKE2s-128 algorithm which yields a message digest of 16 bytes.
+See RFC 7693 for the specification.
+
+@item GCRY_MD_SM3
+This is the SM3 algorithm which yields a message digest of 32 bytes.
+
+@end table
+@c end table of hash algorithms
+
+@node Working with hash algorithms
+@section Working with hash algorithms
+
+To use most of these function it is necessary to create a context;
+this is done using:
+
+@deftypefun gcry_error_t gcry_md_open (gcry_md_hd_t *@var{hd}, int @var{algo}, unsigned int @var{flags})
+
+Create a message digest object for algorithm @var{algo}. @var{flags}
+may be given as an bitwise OR of constants described below. @var{algo}
+may be given as @code{0} if the algorithms to use are later set using
+@code{gcry_md_enable}. @var{hd} is guaranteed to either receive a valid
+handle or NULL.
+
+For a list of supported algorithms, see @ref{Available hash
+algorithms}.
+
+The flags allowed for @var{mode} are:
+
+@c begin table of hash flags
+@table @code
+@item GCRY_MD_FLAG_SECURE
+Allocate all buffers and the resulting digest in "secure memory". Use
+this is the hashed data is highly confidential.
+
+@item GCRY_MD_FLAG_HMAC
+@cindex HMAC
+Turn the algorithm into a HMAC message authentication algorithm. This
+only works if just one algorithm is enabled for the handle and that
+algorithm is not an extendable-output function. Note that the function
+@code{gcry_md_setkey} must be used to set the MAC key. The size of the
+MAC is equal to the message digest of the underlying hash algorithm.
+If you want CBC message authentication codes based on a cipher,
+see @ref{Working with cipher handles}.
+
+@item GCRY_MD_FLAG_BUGEMU1
+@cindex bug emulation
+Versions of Libgcrypt before 1.6.0 had a bug in the Whirlpool code
+which led to a wrong result for certain input sizes and write
+patterns. Using this flag emulates that bug. This may for example be
+useful for applications which use Whirlpool as part of their key
+generation. It is strongly suggested to use this flag only if really
+needed and if possible to the data should be re-processed using the
+regular Whirlpool algorithm.
+
+Note that this flag works for the entire hash context. If needed
+arises it may be used to enable bug emulation for other hash
+algorithms. Thus you should not use this flag for a multi-algorithm
+hash context.
+
+
+@end table
+@c begin table of hash flags
+
+You may use the function @code{gcry_md_is_enabled} to later check
+whether an algorithm has been enabled.
+
+@end deftypefun
+@c end function gcry_md_open
+
+If you want to calculate several hash algorithms at the same time, you
+have to use the following function right after the @code{gcry_md_open}:
+
+@deftypefun gcry_error_t gcry_md_enable (gcry_md_hd_t @var{h}, int @var{algo})
+
+Add the message digest algorithm @var{algo} to the digest object
+described by handle @var{h}. Duplicated enabling of algorithms is
+detected and ignored.
+@end deftypefun
+
+If the flag @code{GCRY_MD_FLAG_HMAC} was used, the key for the MAC must
+be set using the function:
+
+@deftypefun gcry_error_t gcry_md_setkey (gcry_md_hd_t @var{h}, const void *@var{key}, size_t @var{keylen})
+
+For use with the HMAC feature or BLAKE2 keyed hash, set the MAC key to
+the value of @var{key} of length @var{keylen} bytes. For HMAC, there
+is no restriction on the length of the key. For keyed BLAKE2b hash,
+length of the key must be 64 bytes or less. For keyed BLAKE2s hash,
+length of the key must be 32 bytes or less.
+
+@end deftypefun
+
+
+After you are done with the hash calculation, you should release the
+resources by using:
+
+@deftypefun void gcry_md_close (gcry_md_hd_t @var{h})
+
+Release all resources of hash context @var{h}. @var{h} should not be
+used after a call to this function. A @code{NULL} passed as @var{h} is
+ignored. The function also zeroises all sensitive information
+associated with this handle.
+
+
+@end deftypefun
+
+Often you have to do several hash operations using the same algorithm.
+To avoid the overhead of creating and releasing context, a reset function
+is provided:
+
+@deftypefun void gcry_md_reset (gcry_md_hd_t @var{h})
+
+Reset the current context to its initial state. This is effectively
+identical to a close followed by an open and enabling all currently
+active algorithms.
+@end deftypefun
+
+
+Often it is necessary to start hashing some data and then continue to
+hash different data. To avoid hashing the same data several times (which
+might not even be possible if the data is received from a pipe), a
+snapshot of the current hash context can be taken and turned into a new
+context:
+
+@deftypefun gcry_error_t gcry_md_copy (gcry_md_hd_t *@var{handle_dst}, gcry_md_hd_t @var{handle_src})
+
+Create a new digest object as an exact copy of the object described by
+handle @var{handle_src} and store it in @var{handle_dst}. The context
+is not reset and you can continue to hash data using this context and
+independently using the original context.
+@end deftypefun
+
+
+Now that we have prepared everything to calculate hashes, it is time to
+see how it is actually done. There are two ways for this, one to
+update the hash with a block of memory and one macro to update the hash
+by just one character. Both methods can be used on the same hash context.
+
+@deftypefun void gcry_md_write (gcry_md_hd_t @var{h}, const void *@var{buffer}, size_t @var{length})
+
+Pass @var{length} bytes of the data in @var{buffer} to the digest object
+with handle @var{h} to update the digest values. This
+function should be used for large blocks of data. If this function is
+used after the context has been finalized, it will keep on pushing
+the data through the algorithm specific transform function and change
+the context; however the results are not meaningful and this feature
+is only available to mitigate timing attacks.
+@end deftypefun
+
+@deftypefun void gcry_md_putc (gcry_md_hd_t @var{h}, int @var{c})
+
+Pass the byte in @var{c} to the digest object with handle @var{h} to
+update the digest value. This is an efficient function, implemented as
+a macro to buffer the data before an actual update.
+@end deftypefun
+
+The semantics of the hash functions do not provide for reading out intermediate
+message digests because the calculation must be finalized first. This
+finalization may for example include the number of bytes hashed in the
+message digest or some padding.
+
+@deftypefun void gcry_md_final (gcry_md_hd_t @var{h})
+
+Finalize the message digest calculation. This is not really needed
+because @code{gcry_md_read} and @code{gcry_md_extract} do this implicitly.
+After this has been done no further updates (by means of @code{gcry_md_write}
+or @code{gcry_md_putc} should be done; However, to mitigate timing
+attacks it is sometimes useful to keep on updating the context after
+having stored away the actual digest. Only the first call to this function
+has an effect. It is implemented as a macro.
+@end deftypefun
+
+The way to read out the calculated message digest is by using the
+function:
+
+@deftypefun {unsigned char *} gcry_md_read (gcry_md_hd_t @var{h}, int @var{algo})
+
+@code{gcry_md_read} returns the message digest after finalizing the
+calculation. This function may be used as often as required but it will
+always return the same value for one handle. The returned message digest
+is allocated within the message context and therefore valid until the
+handle is released or reset-ed (using @code{gcry_md_close} or
+@code{gcry_md_reset} or it has been updated as a mitigation measure
+against timing attacks. @var{algo} may be given as 0 to return the only
+enabled message digest or it may specify one of the enabled algorithms.
+The function does return @code{NULL} if the requested algorithm has not
+been enabled.
+@end deftypefun
+
+The way to read output of extendable-output function is by using the
+function:
+
+@deftypefun gpg_err_code_t gcry_md_extract (gcry_md_hd_t @var{h}, @
+ int @var{algo}, void *@var{buffer}, size_t @var{length})
+
+@code{gcry_mac_read} returns output from extendable-output function.
+This function may be used as often as required to generate more output
+byte stream from the algorithm. Function extracts the new output bytes
+to @var{buffer} of the length @var{length}. Buffer will be fully
+populated with new output. @var{algo} may be given as 0 to return the only
+enabled message digest or it may specify one of the enabled algorithms.
+The function does return non-zero value if the requested algorithm has not
+been enabled.
+@end deftypefun
+
+Because it is often necessary to get the message digest of blocks of
+memory, two fast convenience function are available for this task:
+
+@deftypefun gpg_err_code_t gcry_md_hash_buffers ( @
+ @w{int @var{algo}}, @w{unsigned int @var{flags}}, @
+ @w{void *@var{digest}}, @
+ @w{const gcry_buffer_t *@var{iov}}, @w{int @var{iovcnt}} )
+
+@code{gcry_md_hash_buffers} is a shortcut function to calculate a
+message digest from several buffers. This function does not require a
+context and immediately returns the message digest of the data
+described by @var{iov} and @var{iovcnt}. @var{digest} must be
+allocated by the caller, large enough to hold the message digest
+yielded by the the specified algorithm @var{algo}. This required size
+may be obtained by using the function @code{gcry_md_get_algo_dlen}.
+
+@var{iov} is an array of buffer descriptions with @var{iovcnt} items.
+The caller should zero out the structures in this array and for each
+array item set the fields @code{.data} to the address of the data to
+be hashed, @code{.len} to number of bytes to be hashed. If @var{.off}
+is also set, the data is taken starting at @var{.off} bytes from the
+begin of the buffer. The field @code{.size} is not used.
+
+The only supported flag value for @var{flags} is
+@var{GCRY_MD_FLAG_HMAC} which turns this function into a HMAC
+function; the first item in @var{iov} is then used as the key.
+
+On success the function returns 0 and stores the resulting hash or MAC
+at @var{digest}.
+@end deftypefun
+
+@deftypefun void gcry_md_hash_buffer (int @var{algo}, void *@var{digest}, const void *@var{buffer}, size_t @var{length});
+
+@code{gcry_md_hash_buffer} is a shortcut function to calculate a message
+digest of a buffer. This function does not require a context and
+immediately returns the message digest of the @var{length} bytes at
+@var{buffer}. @var{digest} must be allocated by the caller, large
+enough to hold the message digest yielded by the the specified algorithm
+@var{algo}. This required size may be obtained by using the function
+@code{gcry_md_get_algo_dlen}.
+
+Note that in contrast to @code{gcry_md_hash_buffers} this function
+will abort the process if an unavailable algorithm is used.
+@end deftypefun
+
+@c ***********************************
+@c ***** MD info functions ***********
+@c ***********************************
+
+Hash algorithms are identified by internal algorithm numbers (see
+@code{gcry_md_open} for a list). However, in most applications they are
+used by names, so two functions are available to map between string
+representations and hash algorithm identifiers.
+
+@deftypefun {const char *} gcry_md_algo_name (int @var{algo})
+
+Map the digest algorithm id @var{algo} to a string representation of the
+algorithm name. For unknown algorithms this function returns the
+string @code{"?"}. This function should not be used to test for the
+availability of an algorithm.
+@end deftypefun
+
+@deftypefun int gcry_md_map_name (const char *@var{name})
+
+Map the algorithm with @var{name} to a digest algorithm identifier.
+Returns 0 if the algorithm name is not known. Names representing
+@acronym{ASN.1} object identifiers are recognized if the @acronym{IETF}
+dotted format is used and the OID is prefixed with either "@code{oid.}"
+or "@code{OID.}". For a list of supported OIDs, see the source code at
+@file{cipher/md.c}. This function should not be used to test for the
+availability of an algorithm.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_md_get_asnoid (int @var{algo}, void *@var{buffer}, size_t *@var{length})
+
+Return an DER encoded ASN.1 OID for the algorithm @var{algo} in the
+user allocated @var{buffer}. @var{length} must point to variable with
+the available size of @var{buffer} and receives after return the
+actual size of the returned OID. The returned error code may be
+@code{GPG_ERR_TOO_SHORT} if the provided buffer is to short to receive
+the OID; it is possible to call the function with @code{NULL} for
+@var{buffer} to have it only return the required size. The function
+returns 0 on success.
+
+@end deftypefun
+
+
+To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+@deftypefun gcry_error_t gcry_md_test_algo (int @var{algo})
+
+The macro returns 0 if the algorithm @var{algo} is available for use.
+@end deftypefun
+
+If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+@deftypefun {unsigned int} gcry_md_get_algo_dlen (int @var{algo})
+
+Retrieve the length in bytes of the digest yielded by algorithm
+@var{algo}. This is often used prior to @code{gcry_md_read} to allocate
+sufficient memory for the digest.
+@end deftypefun
+
+
+In some situations it might be hard to remember the algorithm used for
+the ongoing hashing. The following function might be used to get that
+information:
+
+@deftypefun int gcry_md_get_algo (gcry_md_hd_t @var{h})
+
+Retrieve the algorithm used with the handle @var{h}. Note that this
+does not work reliable if more than one algorithm is enabled in @var{h}.
+@end deftypefun
+
+The following macro might also be useful:
+
+@deftypefun int gcry_md_is_secure (gcry_md_hd_t @var{h})
+
+This function returns true when the digest object @var{h} is allocated
+in "secure memory"; i.e. @var{h} was created with the
+@code{GCRY_MD_FLAG_SECURE}.
+@end deftypefun
+
+@deftypefun int gcry_md_is_enabled (gcry_md_hd_t @var{h}, int @var{algo})
+
+This function returns true when the algorithm @var{algo} has been
+enabled for the digest object @var{h}.
+@end deftypefun
+
+
+
+Tracking bugs related to hashing is often a cumbersome task which
+requires to add a lot of printf statements into the code.
+Libgcrypt provides an easy way to avoid this. The actual data
+hashed can be written to files on request.
+
+@deftypefun void gcry_md_debug (gcry_md_hd_t @var{h}, const char *@var{suffix})
+
+Enable debugging for the digest object with handle @var{h}. This
+creates files named @file{dbgmd-<n>.<string>} while doing the
+actual hashing. @var{suffix} is the string part in the filename. The
+number is a counter incremented for each new hashing. The data in the
+file is the raw data as passed to @code{gcry_md_write} or
+@code{gcry_md_putc}. If @code{NULL} is used for @var{suffix}, the
+debugging is stopped and the file closed. This is only rarely required
+because @code{gcry_md_close} implicitly stops debugging.
+@end deftypefun
+
+
+
+@c **********************************************************
+@c ******************* MAC Functions **********************
+@c **********************************************************
+@node Message Authentication Codes
+@chapter Message Authentication Codes
+
+Libgcrypt provides an easy and consistent to use interface for generating
+Message Authentication Codes (MAC). MAC generation is buffered and interface
+similar to the one used with hash algorithms. The programming model follows
+an open/process/close paradigm and is in that similar to other building blocks
+provided by Libgcrypt.
+
+@menu
+* Available MAC algorithms:: List of MAC algorithms supported by the library.
+* Working with MAC algorithms:: List of functions related to MAC algorithms.
+@end menu
+
+@node Available MAC algorithms
+@section Available MAC algorithms
+
+@c begin table of MAC algorithms
+@cindex HMAC-SHA-1
+@cindex HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, HMAC-SHA-512
+@cindex HMAC-SHA-512/224, HMAC-SHA-512/256
+@cindex HMAC-SHA3-224, HMAC-SHA3-256, HMAC-SHA3-384, HMAC-SHA3-512
+@cindex HMAC-RIPE-MD-160
+@cindex HMAC-MD2, HMAC-MD4, HMAC-MD5
+@cindex HMAC-TIGER1
+@cindex HMAC-SM3
+@cindex HMAC-Whirlpool
+@cindex HMAC-Stribog-256, HMAC-Stribog-512
+@cindex HMAC-GOSTR-3411-94
+@cindex HMAC-BLAKE2s, HMAC-BLAKE2b
+@table @code
+@item GCRY_MAC_NONE
+This is not a real algorithm but used by some functions as an error
+return value. This constant is guaranteed to have the value @code{0}.
+
+@item GCRY_MAC_HMAC_SHA256
+This is keyed-hash message authentication code (HMAC) message authentication
+algorithm based on the SHA-256 hash algorithm.
+
+@item GCRY_MAC_HMAC_SHA224
+This is HMAC message authentication algorithm based on the SHA-224 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA512
+This is HMAC message authentication algorithm based on the SHA-512 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA384
+This is HMAC message authentication algorithm based on the SHA-384 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA3_256
+This is HMAC message authentication algorithm based on the SHA3-256 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA3_224
+This is HMAC message authentication algorithm based on the SHA3-224 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA3_512
+This is HMAC message authentication algorithm based on the SHA3-512 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA3_384
+This is HMAC message authentication algorithm based on the SHA3-384 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA512_224
+This is HMAC message authentication algorithm based on the SHA-512/224 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA512_256
+This is HMAC message authentication algorithm based on the SHA-512/256 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA1
+This is HMAC message authentication algorithm based on the SHA-1 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_MD5
+This is HMAC message authentication algorithm based on the MD5 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_MD4
+This is HMAC message authentication algorithm based on the MD4 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_RMD160
+This is HMAC message authentication algorithm based on the RIPE-MD-160 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_WHIRLPOOL
+This is HMAC message authentication algorithm based on the WHIRLPOOL hash
+algorithm.
+
+@item GCRY_MAC_HMAC_GOSTR3411_94
+This is HMAC message authentication algorithm based on the GOST R 34.11-94 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_STRIBOG256
+This is HMAC message authentication algorithm based on the 256-bit hash
+algorithm described in GOST R 34.11-2012.
+
+@item GCRY_MAC_HMAC_STRIBOG512
+This is HMAC message authentication algorithm based on the 512-bit hash
+algorithm described in GOST R 34.11-2012.
+
+@item GCRY_MAC_HMAC_BLAKE2B_512
+This is HMAC message authentication algorithm based on the BLAKE2b-512 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_BLAKE2B_384
+This is HMAC message authentication algorithm based on the BLAKE2b-384 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_BLAKE2B_256
+This is HMAC message authentication algorithm based on the BLAKE2b-256 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_BLAKE2B_160
+This is HMAC message authentication algorithm based on the BLAKE2b-160 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_BLAKE2S_256
+This is HMAC message authentication algorithm based on the BLAKE2s-256 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_BLAKE2S_224
+This is HMAC message authentication algorithm based on the BLAKE2s-224 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_BLAKE2S_160
+This is HMAC message authentication algorithm based on the BLAKE2s-160 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_BLAKE2S_128
+This is HMAC message authentication algorithm based on the BLAKE2s-128 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SM3
+This is HMAC message authentication algorithm based on the SM3 hash
+algorithm.
+
+@item GCRY_MAC_CMAC_AES
+This is CMAC (Cipher-based MAC) message authentication algorithm based on
+the AES block cipher algorithm.
+
+@item GCRY_MAC_CMAC_3DES
+This is CMAC message authentication algorithm based on the three-key EDE
+Triple-DES block cipher algorithm.
+
+@item GCRY_MAC_CMAC_CAMELLIA
+This is CMAC message authentication algorithm based on the Camellia block cipher
+algorithm.
+
+@item GCRY_MAC_CMAC_CAST5
+This is CMAC message authentication algorithm based on the CAST128-5
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_BLOWFISH
+This is CMAC message authentication algorithm based on the Blowfish
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_TWOFISH
+This is CMAC message authentication algorithm based on the Twofish
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_SERPENT
+This is CMAC message authentication algorithm based on the Serpent
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_SEED
+This is CMAC message authentication algorithm based on the SEED
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_RFC2268
+This is CMAC message authentication algorithm based on the Ron's Cipher 2
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_IDEA
+This is CMAC message authentication algorithm based on the IDEA
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_GOST28147
+This is CMAC message authentication algorithm based on the GOST 28147-89
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_SM4
+This is CMAC message authentication algorithm based on the SM4
+block cipher algorithm.
+
+@item GCRY_MAC_GMAC_AES
+This is GMAC (GCM mode based MAC) message authentication algorithm based on
+the AES block cipher algorithm.
+
+@item GCRY_MAC_GMAC_CAMELLIA
+This is GMAC message authentication algorithm based on the Camellia
+block cipher algorithm.
+
+@item GCRY_MAC_GMAC_TWOFISH
+This is GMAC message authentication algorithm based on the Twofish
+block cipher algorithm.
+
+@item GCRY_MAC_GMAC_SERPENT
+This is GMAC message authentication algorithm based on the Serpent
+block cipher algorithm.
+
+@item GCRY_MAC_GMAC_SEED
+This is GMAC message authentication algorithm based on the SEED
+block cipher algorithm.
+
+@item GCRY_MAC_POLY1305
+This is plain Poly1305 message authentication algorithm, used with
+one-time key.
+
+@item GCRY_MAC_POLY1305_AES
+This is Poly1305-AES message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_POLY1305_CAMELLIA
+This is Poly1305-Camellia message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_POLY1305_TWOFISH
+This is Poly1305-Twofish message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_POLY1305_SERPENT
+This is Poly1305-Serpent message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_POLY1305_SEED
+This is Poly1305-SEED message authentication algorithm, used with
+key and one-time nonce.
+
+@item GCRY_MAC_GOST28147_IMIT
+This is MAC construction defined in GOST 28147-89 (see RFC 5830 Section 8).
+
+@end table
+@c end table of MAC algorithms
+
+@node Working with MAC algorithms
+@section Working with MAC algorithms
+
+To use most of these function it is necessary to create a context;
+this is done using:
+
+@deftypefun gcry_error_t gcry_mac_open (gcry_mac_hd_t *@var{hd}, int @var{algo}, unsigned int @var{flags}, gcry_ctx_t @var{ctx})
+
+Create a MAC object for algorithm @var{algo}. @var{flags} may be given as an
+bitwise OR of constants described below. @var{hd} is guaranteed to either
+receive a valid handle or NULL. @var{ctx} is context object to associate MAC
+object with. @var{ctx} maybe set to NULL.
+
+For a list of supported algorithms, see @ref{Available MAC algorithms}.
+
+The flags allowed for @var{mode} are:
+
+@c begin table of MAC flags
+@table @code
+@item GCRY_MAC_FLAG_SECURE
+Allocate all buffers and the resulting MAC in "secure memory". Use this if the
+MAC data is highly confidential.
+
+@end table
+@c begin table of MAC flags
+
+@end deftypefun
+@c end function gcry_mac_open
+
+
+In order to use a handle for performing MAC algorithm operations, a
+`key' has to be set first:
+
+@deftypefun gcry_error_t gcry_mac_setkey (gcry_mac_hd_t @var{h}, const void *@var{key}, size_t @var{keylen})
+
+Set the MAC key to the value of @var{key} of length @var{keylen} bytes. With
+HMAC algorithms, there is no restriction on the length of the key. With CMAC
+algorithms, the length of the key is restricted to those supported by the
+underlying block cipher.
+@end deftypefun
+
+
+GMAC algorithms and Poly1305-with-cipher algorithms need initialization vector to be set,
+which can be performed with function:
+
+@deftypefun gcry_error_t gcry_mac_setiv (gcry_mac_hd_t @var{h}, const void *@var{iv}, size_t @var{ivlen})
+
+Set the IV to the value of @var{iv} of length @var{ivlen} bytes.
+@end deftypefun
+
+
+After you are done with the MAC calculation, you should release the resources
+by using:
+
+@deftypefun void gcry_mac_close (gcry_mac_hd_t @var{h})
+
+Release all resources of MAC context @var{h}. @var{h} should not be
+used after a call to this function. A @code{NULL} passed as @var{h} is
+ignored. The function also clears all sensitive information associated
+with this handle.
+@end deftypefun
+
+
+Often you have to do several MAC operations using the same algorithm.
+To avoid the overhead of creating and releasing context, a reset function
+is provided:
+
+@deftypefun gcry_error_t gcry_mac_reset (gcry_mac_hd_t @var{h})
+
+Reset the current context to its initial state. This is effectively identical
+to a close followed by an open and setting same key.
+
+Note that gcry_mac_reset is implemented as a macro.
+@end deftypefun
+
+
+Now that we have prepared everything to calculate MAC, it is time to
+see how it is actually done.
+
+@deftypefun gcry_error_t gcry_mac_write (gcry_mac_hd_t @var{h}, const void *@var{buffer}, size_t @var{length})
+
+Pass @var{length} bytes of the data in @var{buffer} to the MAC object
+with handle @var{h} to update the MAC values. If this function is
+used after the context has been finalized, it will keep on pushing the
+data through the algorithm specific transform function and thereby
+change the context; however the results are not meaningful and this
+feature is only available to mitigate timing attacks.
+@end deftypefun
+
+The way to read out the calculated MAC is by using the function:
+
+@deftypefun gcry_error_t gcry_mac_read (gcry_mac_hd_t @var{h}, void *@var{buffer}, size_t *@var{length})
+
+@code{gcry_mac_read} returns the MAC after finalizing the calculation.
+Function copies the resulting MAC value to @var{buffer} of the length
+@var{length}. If @var{length} is larger than length of resulting MAC value,
+then length of MAC is returned through @var{length}.
+@end deftypefun
+
+To compare existing MAC value with recalculated MAC, one is to use the function:
+
+@deftypefun gcry_error_t gcry_mac_verify (gcry_mac_hd_t @var{h}, void *@var{buffer}, size_t @var{length})
+
+@code{gcry_mac_verify} finalizes MAC calculation and compares result with
+@var{length} bytes of data in @var{buffer}. Error code @code{GPG_ERR_CHECKSUM}
+is returned if the MAC value in the buffer @var{buffer} does not match
+the MAC calculated in object @var{h}.
+@end deftypefun
+
+
+In some situations it might be hard to remember the algorithm used for
+the MAC calculation. The following function might be used to get that
+information:
+
+@deftypefun {int} gcry_mac_get_algo (gcry_mac_hd_t @var{h})
+
+Retrieve the algorithm used with the handle @var{h}.
+@end deftypefun
+
+
+@c ***********************************
+@c ***** MAC info functions **********
+@c ***********************************
+
+MAC algorithms are identified by internal algorithm numbers (see
+@code{gcry_mac_open} for a list). However, in most applications they are
+used by names, so two functions are available to map between string
+representations and MAC algorithm identifiers.
+
+@deftypefun {const char *} gcry_mac_algo_name (int @var{algo})
+
+Map the MAC algorithm id @var{algo} to a string representation of the
+algorithm name. For unknown algorithms this function returns the
+string @code{"?"}. This function should not be used to test for the
+availability of an algorithm.
+@end deftypefun
+
+@deftypefun int gcry_mac_map_name (const char *@var{name})
+
+Map the algorithm with @var{name} to a MAC algorithm identifier.
+Returns 0 if the algorithm name is not known. This function should not
+be used to test for the availability of an algorithm.
+@end deftypefun
+
+
+To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+@deftypefun gcry_error_t gcry_mac_test_algo (int @var{algo})
+
+The macro returns 0 if the MAC algorithm @var{algo} is available for use.
+@end deftypefun
+
+
+If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+@deftypefun {unsigned int} gcry_mac_get_algo_maclen (int @var{algo})
+
+Retrieve the length in bytes of the MAC yielded by algorithm @var{algo}.
+This is often used prior to @code{gcry_mac_read} to allocate sufficient memory
+for the MAC value. On error @code{0} is returned.
+@end deftypefun
+
+
+@deftypefun {unsigned int} gcry_mac_get_algo_keylen (@var{algo})
+
+This function returns length of the key for MAC algorithm @var{algo}. If
+the algorithm supports multiple key lengths, the default supported key
+length is returned. On error @code{0} is returned. The key length is
+returned as number of octets.
+@end deftypefun
+
+
+
+@c *******************************************************
+@c ******************* KDF *****************************
+@c *******************************************************
+@node Key Derivation
+@chapter Key Derivation
+
+@acronym{Libgcypt} provides a general purpose function to derive keys
+from strings.
+
+@deftypefun gpg_error_t gcry_kdf_derive ( @
+ @w{const void *@var{passphrase}}, @w{size_t @var{passphraselen}}, @
+ @w{int @var{algo}}, @w{int @var{subalgo}}, @
+ @w{const void *@var{salt}}, @w{size_t @var{saltlen}}, @
+ @w{unsigned long @var{iterations}}, @
+ @w{size_t @var{keysize}}, @w{void *@var{keybuffer}} )
+
+
+Derive a key from a passphrase. @var{keysize} gives the requested
+size of the keys in octets. @var{keybuffer} is a caller provided
+buffer filled on success with the derived key. The input passphrase
+is taken from @var{passphrase} which is an arbitrary memory buffer of
+@var{passphraselen} octets. @var{algo} specifies the KDF algorithm to
+use; see below. @var{subalgo} specifies an algorithm used internally
+by the KDF algorithms; this is usually a hash algorithm but certain
+KDF algorithms may use it differently. @var{salt} is a salt of length
+@var{saltlen} octets, as needed by most KDF algorithms.
+@var{iterations} is a positive integer parameter to most KDFs.
+
+@noindent
+On success 0 is returned; on failure an error code.
+
+@noindent
+Currently supported KDFs (parameter @var{algo}):
+
+@table @code
+@item GCRY_KDF_SIMPLE_S2K
+The OpenPGP simple S2K algorithm (cf. RFC4880). Its use is strongly
+deprecated. @var{salt} and @var{iterations} are not needed and may be
+passed as @code{NULL}/@code{0}.
+
+@item GCRY_KDF_SALTED_S2K
+The OpenPGP salted S2K algorithm (cf. RFC4880). Usually not used.
+@var{iterations} is not needed and may be passed as @code{0}. @var{saltlen}
+must be given as 8.
+
+@item GCRY_KDF_ITERSALTED_S2K
+The OpenPGP iterated+salted S2K algorithm (cf. RFC4880). This is the
+default for most OpenPGP applications. @var{saltlen} must be given as
+8. Note that OpenPGP defines a special encoding of the
+@var{iterations}; however this function takes the plain decoded
+iteration count.
+
+@item GCRY_KDF_PBKDF2
+The PKCS#5 Passphrase Based Key Derivation Function number 2.
+
+@item GCRY_KDF_SCRYPT
+The SCRYPT Key Derivation Function. The subalgorithm is used to specify
+the CPU/memory cost parameter N, and the number of iterations
+is used for the parallelization parameter p. The block size is fixed
+at 8 in the current implementation.
+
+@end table
+@end deftypefun
+
+
+@c **********************************************************
+@c ******************* Random *****************************
+@c **********************************************************
+@node Random Numbers
+@chapter Random Numbers
+
+@menu
+* Quality of random numbers:: Libgcrypt uses different quality levels.
+* Retrieving random numbers:: How to retrieve random numbers.
+@end menu
+
+@node Quality of random numbers
+@section Quality of random numbers
+
+@acronym{Libgcypt} offers random numbers of different quality levels:
+
+@deftp {Data type} gcry_random_level_t
+The constants for the random quality levels are of this enum type.
+@end deftp
+
+@table @code
+@item GCRY_WEAK_RANDOM
+For all functions, except for @code{gcry_mpi_randomize}, this level maps
+to GCRY_STRONG_RANDOM. If you do not want this, consider using
+@code{gcry_create_nonce}.
+@item GCRY_STRONG_RANDOM
+Use this level for session keys and similar purposes.
+@item GCRY_VERY_STRONG_RANDOM
+Use this level for long term key material.
+@end table
+
+@node Retrieving random numbers
+@section Retrieving random numbers
+
+@deftypefun void gcry_randomize (unsigned char *@var{buffer}, size_t @var{length}, enum gcry_random_level @var{level})
+
+Fill @var{buffer} with @var{length} random bytes using a random quality
+as defined by @var{level}.
+@end deftypefun
+
+@deftypefun {void *} gcry_random_bytes (size_t @var{nbytes}, enum gcry_random_level @var{level})
+
+Convenience function to allocate a memory block consisting of
+@var{nbytes} fresh random bytes using a random quality as defined by
+@var{level}.
+@end deftypefun
+
+@deftypefun {void *} gcry_random_bytes_secure (size_t @var{nbytes}, enum gcry_random_level @var{level})
+
+Convenience function to allocate a memory block consisting of
+@var{nbytes} fresh random bytes using a random quality as defined by
+@var{level}. This function differs from @code{gcry_random_bytes} in
+that the returned buffer is allocated in a ``secure'' area of the
+memory.
+@end deftypefun
+
+@deftypefun void gcry_create_nonce (unsigned char *@var{buffer}, size_t @var{length})
+
+Fill @var{buffer} with @var{length} unpredictable bytes. This is
+commonly called a nonce and may also be used for initialization
+vectors and padding. This is an extra function nearly independent of
+the other random function for 3 reasons: It better protects the
+regular random generator's internal state, provides better performance
+and does not drain the precious entropy pool.
+
+@end deftypefun
+
+
+
+@c **********************************************************
+@c ******************* S-Expressions ***********************
+@c **********************************************************
+@node S-expressions
+@chapter S-expressions
+
+S-expressions are used by the public key functions to pass complex data
+structures around. These LISP like objects are used by some
+cryptographic protocols (cf. RFC-2692) and Libgcrypt provides functions
+to parse and construct them. For detailed information, see
+@cite{Ron Rivest, code and description of S-expressions,
+@uref{http://theory.lcs.mit.edu/~rivest/sexp.html}}.
+
+@menu
+* Data types for S-expressions:: Data types related with S-expressions.
+* Working with S-expressions:: How to work with S-expressions.
+@end menu
+
+@node Data types for S-expressions
+@section Data types for S-expressions
+
+@deftp {Data type} gcry_sexp_t
+The @code{gcry_sexp_t} type describes an object with the Libgcrypt internal
+representation of an S-expression.
+@end deftp
+
+@node Working with S-expressions
+@section Working with S-expressions
+
+@noindent
+There are several functions to create an Libgcrypt S-expression object
+from its external representation or from a string template. There is
+also a function to convert the internal representation back into one of
+the external formats:
+
+
+@deftypefun gcry_error_t gcry_sexp_new (@w{gcry_sexp_t *@var{r_sexp}}, @w{const void *@var{buffer}}, @w{size_t @var{length}}, @w{int @var{autodetect}})
+
+This is the generic function to create an new S-expression object from
+its external representation in @var{buffer} of @var{length} bytes. On
+success the result is stored at the address given by @var{r_sexp}.
+With @var{autodetect} set to 0, the data in @var{buffer} is expected to
+be in canonized format, with @var{autodetect} set to 1 the parses any of
+the defined external formats. If @var{buffer} does not hold a valid
+S-expression an error code is returned and @var{r_sexp} set to
+@code{NULL}.
+Note that the caller is responsible for releasing the newly allocated
+S-expression using @code{gcry_sexp_release}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_sexp_create (@w{gcry_sexp_t *@var{r_sexp}}, @w{void *@var{buffer}}, @w{size_t @var{length}}, @w{int @var{autodetect}}, @w{void (*@var{freefnc})(void*)})
+
+This function is identical to @code{gcry_sexp_new} but has an extra
+argument @var{freefnc}, which, when not set to @code{NULL}, is expected
+to be a function to release the @var{buffer}; most likely the standard
+@code{free} function is used for this argument. This has the effect of
+transferring the ownership of @var{buffer} to the created object in
+@var{r_sexp}. The advantage of using this function is that Libgcrypt
+might decide to directly use the provided buffer and thus avoid extra
+copying.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_sexp_sscan (@w{gcry_sexp_t *@var{r_sexp}}, @w{size_t *@var{erroff}}, @w{const char *@var{buffer}}, @w{size_t @var{length}})
+
+This is another variant of the above functions. It behaves nearly
+identical but provides an @var{erroff} argument which will receive the
+offset into the buffer where the parsing stopped on error.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_sexp_build (@w{gcry_sexp_t *@var{r_sexp}}, @w{size_t *@var{erroff}}, @w{const char *@var{format}, ...})
+
+This function creates an internal S-expression from the string template
+@var{format} and stores it at the address of @var{r_sexp}. If there is a
+parsing error, the function returns an appropriate error code and stores
+the offset into @var{format} where the parsing stopped in @var{erroff}.
+The function supports a couple of printf-like formatting characters and
+expects arguments for some of these escape sequences right after
+@var{format}. The following format characters are defined:
+
+@table @samp
+@item %m
+The next argument is expected to be of type @code{gcry_mpi_t} and a copy of
+its value is inserted into the resulting S-expression. The MPI is
+stored as a signed integer.
+@item %M
+The next argument is expected to be of type @code{gcry_mpi_t} and a copy of
+its value is inserted into the resulting S-expression. The MPI is
+stored as an unsigned integer.
+@item %s
+The next argument is expected to be of type @code{char *} and that
+string is inserted into the resulting S-expression.
+@item %d
+The next argument is expected to be of type @code{int} and its value is
+inserted into the resulting S-expression.
+@item %u
+The next argument is expected to be of type @code{unsigned int} and
+its value is inserted into the resulting S-expression.
+@item %b
+The next argument is expected to be of type @code{int} directly
+followed by an argument of type @code{char *}. This represents a
+buffer of given length to be inserted into the resulting S-expression.
+@item %S
+The next argument is expected to be of type @code{gcry_sexp_t} and a
+copy of that S-expression is embedded in the resulting S-expression.
+The argument needs to be a regular S-expression, starting with a
+parenthesis.
+
+@end table
+
+@noindent
+No other format characters are defined and would return an error. Note
+that the format character @samp{%%} does not exists, because a percent
+sign is not a valid character in an S-expression.
+@end deftypefun
+
+@deftypefun void gcry_sexp_release (@w{gcry_sexp_t @var{sexp}})
+
+Release the S-expression object @var{sexp}. If the S-expression is
+stored in secure memory it explicitly zeroises that memory; note that
+this is done in addition to the zeroisation always done when freeing
+secure memory.
+@end deftypefun
+
+
+@noindent
+The next 2 functions are used to convert the internal representation
+back into a regular external S-expression format and to show the
+structure for debugging.
+
+@deftypefun size_t gcry_sexp_sprint (@w{gcry_sexp_t @var{sexp}}, @w{int @var{mode}}, @w{char *@var{buffer}}, @w{size_t @var{maxlength}})
+
+Copies the S-expression object @var{sexp} into @var{buffer} using the
+format specified in @var{mode}. @var{maxlength} must be set to the
+allocated length of @var{buffer}. The function returns the actual
+length of valid bytes put into @var{buffer} or 0 if the provided buffer
+is too short. Passing @code{NULL} for @var{buffer} returns the required
+length for @var{buffer}. For convenience reasons an extra byte with
+value 0 is appended to the buffer.
+
+@noindent
+The following formats are supported:
+
+@table @code
+@item GCRYSEXP_FMT_DEFAULT
+Returns a convenient external S-expression representation.
+
+@item GCRYSEXP_FMT_CANON
+Return the S-expression in canonical format.
+
+@item GCRYSEXP_FMT_BASE64
+Not currently supported.
+
+@item GCRYSEXP_FMT_ADVANCED
+Returns the S-expression in advanced format.
+@end table
+@end deftypefun
+
+@deftypefun void gcry_sexp_dump (@w{gcry_sexp_t @var{sexp}})
+
+Dumps @var{sexp} in a format suitable for debugging to Libgcrypt's
+logging stream.
+@end deftypefun
+
+@noindent
+Often canonical encoding is used in the external representation. The
+following function can be used to check for valid encoding and to learn
+the length of the S-expression.
+
+@deftypefun size_t gcry_sexp_canon_len (@w{const unsigned char *@var{buffer}}, @w{size_t @var{length}}, @w{size_t *@var{erroff}}, @w{int *@var{errcode}})
+
+Scan the canonical encoded @var{buffer} with implicit length values and
+return the actual length this S-expression uses. For a valid S-expression
+it should never return 0. If @var{length} is not 0, the maximum
+length to scan is given; this can be used for syntax checks of
+data passed from outside. @var{errcode} and @var{erroff} may both be
+passed as @code{NULL}.
+
+@end deftypefun
+
+
+@noindent
+There are functions to parse S-expressions and retrieve elements:
+
+@deftypefun gcry_sexp_t gcry_sexp_find_token (@w{const gcry_sexp_t @var{list}}, @w{const char *@var{token}}, @w{size_t @var{toklen}})
+
+Scan the S-expression for a sublist with a type (the car of the list)
+matching the string @var{token}. If @var{toklen} is not 0, the token is
+assumed to be raw memory of this length. The function returns a newly
+allocated S-expression consisting of the found sublist or @code{NULL}
+when not found.
+@end deftypefun
+
+
+@deftypefun int gcry_sexp_length (@w{const gcry_sexp_t @var{list}})
+
+Return the length of the @var{list}. For a valid S-expression this
+should be at least 1.
+@end deftypefun
+
+
+@deftypefun gcry_sexp_t gcry_sexp_nth (@w{const gcry_sexp_t @var{list}}, @w{int @var{number}})
+
+Create and return a new S-expression from the element with index @var{number} in
+@var{list}. Note that the first element has the index 0. If there is
+no such element, @code{NULL} is returned.
+@end deftypefun
+
+@deftypefun gcry_sexp_t gcry_sexp_car (@w{const gcry_sexp_t @var{list}})
+
+Create and return a new S-expression from the first element in
+@var{list}; this is called the "type" and should always exist per
+S-expression specification and in general be a string. @code{NULL} is
+returned in case of a problem.
+@end deftypefun
+
+@deftypefun gcry_sexp_t gcry_sexp_cdr (@w{const gcry_sexp_t @var{list}})
+
+Create and return a new list form all elements except for the first one.
+Note that this function may return an invalid S-expression because it
+is not guaranteed, that the type exists and is a string. However, for
+parsing a complex S-expression it might be useful for intermediate
+lists. Returns @code{NULL} on error.
+@end deftypefun
+
+
+@deftypefun {const char *} gcry_sexp_nth_data (@w{const gcry_sexp_t @var{list}}, @w{int @var{number}}, @w{size_t *@var{datalen}})
+
+This function is used to get data from a @var{list}. A pointer to the
+actual data with index @var{number} is returned and the length of this
+data will be stored to @var{datalen}. If there is no data at the given
+index or the index represents another list, @code{NULL} is returned.
+@strong{Caution:} The returned pointer is valid as long as @var{list} is
+not modified or released.
+
+@noindent
+Here is an example on how to extract and print the surname (Meier) from
+the S-expression @samp{(Name Otto Meier (address Burgplatz 3))}:
+
+@example
+size_t len;
+const char *name;
+
+name = gcry_sexp_nth_data (list, 2, &len);
+printf ("my name is %.*s\n", (int)len, name);
+@end example
+@end deftypefun
+
+@deftypefun {void *} gcry_sexp_nth_buffer (@w{const gcry_sexp_t @var{list}}, @w{int @var{number}}, @w{size_t *@var{rlength}})
+
+This function is used to get data from a @var{list}. A malloced
+buffer with the actual data at list index @var{number} is returned and
+the length of this buffer will be stored to @var{rlength}. If there
+is no data at the given index or the index represents another list,
+@code{NULL} is returned. The caller must release the result using
+@code{gcry_free}.
+
+@noindent
+Here is an example on how to extract and print the CRC value from the
+S-expression @samp{(hash crc32 #23ed00d7)}:
+
+@example
+size_t len;
+char *value;
+
+value = gcry_sexp_nth_buffer (list, 2, &len);
+if (value)
+ fwrite (value, len, 1, stdout);
+gcry_free (value);
+@end example
+@end deftypefun
+
+@deftypefun {char *} gcry_sexp_nth_string (@w{gcry_sexp_t @var{list}}, @w{int @var{number}})
+
+This function is used to get and convert data from a @var{list}. The
+data is assumed to be a Nul terminated string. The caller must
+release this returned value using @code{gcry_free}. If there is
+no data at the given index, the index represents a list or the value
+can't be converted to a string, @code{NULL} is returned.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_sexp_nth_mpi (@w{gcry_sexp_t @var{list}}, @w{int @var{number}}, @w{int @var{mpifmt}})
+
+This function is used to get and convert data from a @var{list}. This
+data is assumed to be an MPI stored in the format described by
+@var{mpifmt} and returned as a standard Libgcrypt MPI. The caller must
+release this returned value using @code{gcry_mpi_release}. If there is
+no data at the given index, the index represents a list or the value
+can't be converted to an MPI, @code{NULL} is returned. If you use
+this function to parse results of a public key function, you most
+likely want to use @code{GCRYMPI_FMT_USG}.
+@end deftypefun
+
+@deftypefun gpg_error_t gcry_sexp_extract_param ( @
+ @w{gcry_sexp_t @var{sexp}}, @
+ @w{const char *@var{path}}, @
+ @w{const char *@var{list}}, ...)
+
+Extract parameters from an S-expression using a list of parameter
+names. The names of these parameters are specified in LIST. White
+space between the parameter names are ignored. Some special characters
+and character sequences may be given to control the conversion:
+
+@table @samp
+@item +
+Switch to unsigned integer format (GCRYMPI_FMT_USG). This is the
+default mode.
+@item -
+Switch to standard signed format (GCRYMPI_FMT_STD).
+@item /
+Switch to opaque MPI format. The resulting MPIs may not be used for
+computations; see @code{gcry_mpi_get_opaque} for details.
+@item &
+Switch to buffer descriptor mode. See below for details.
+@item %s
+Switch to string mode. The expected argument is the address of a
+@code{char *} variable; the caller must release that value. If the
+parameter was marked optional and is not found, NULL is stored.
+@item %#s
+Switch to multi string mode. The expected argument is the address of a
+@code{char *} variable; the caller must release that value. If the
+parameter was marked optional and is not found, NULL is stored. A
+multi string takes all values, assumes they are strings and
+concatenates them using a space as delimiter. In case a value is
+actually another list this is not further parsed but a @code{()} is
+inserted in place of that sublist.
+@item %u
+Switch to unsigned integer mode. The expected argument is address of
+a @code{unsigned int} variable.
+@item %lu
+Switch to unsigned long integer mode. The expected argument is address of
+a @code{unsigned long} variable.
+@item %d
+Switch to signed integer mode. The expected argument is address of
+a @code{int} variable.
+@item %ld
+Switch to signed long integer mode. The expected argument is address of
+a @code{long} variable.
+@item %zu
+Switch to size_t mode. The expected argument is address of
+a @code{size_t} variable.
+@item ?
+If immediately following a parameter letter (no white space allowed),
+that parameter is considered optional.
+@end table
+
+In general parameter names are single letters. To use a string for a
+parameter name, enclose the name in single quotes.
+
+Unless in buffer descriptor mode for each parameter name a pointer to
+an @code{gcry_mpi_t} variable is expected that must be set to
+@code{NULL} prior to invoking this function, and finally a @code{NULL}
+is expected. For example
+
+@example
+ gcry_sexp_extract_param (key, NULL, "n/x+e d-'foo'",
+ &mpi_n, &mpi_x, &mpi_e, &mpi_d, &mpi_foo, NULL)
+@end example
+
+stores the parameter 'n' from @var{key} as an unsigned MPI into
+@var{mpi_n}, the parameter 'x' as an opaque MPI into @var{mpi_x}, the
+parameters 'e' and 'd' again as an unsigned MPI into @var{mpi_e} and
+@var{mpi_d} and finally the parameter 'foo' as a signed MPI into
+@var{mpi_foo}.
+
+@var{path} is an optional string used to locate a token. The
+exclamation mark separated tokens are used via
+@code{gcry_sexp_find_token} to find a start point inside the
+S-expression.
+
+In buffer descriptor mode a pointer to a @code{gcry_buffer_t}
+descriptor is expected instead of a pointer to an MPI. The caller may
+use two different operation modes here: If the @var{data} field of the
+provided descriptor is @code{NULL}, the function allocates a new
+buffer and stores it at @var{data}; the other fields are set
+accordingly with @var{off} set to 0. If @var{data} is not
+@code{NULL}, the function assumes that the @var{data}, @var{size}, and
+@var{off} fields specify a buffer where to but the value of the
+respective parameter; on return the @var{len} field receives the
+number of bytes copied to that buffer; in case the buffer is too
+small, the function immediately returns with an error code (and
+@var{len} is set to 0).
+
+The function returns 0 on success. On error an error code is
+returned, all passed MPIs that might have been allocated up to this
+point are deallocated and set to @code{NULL}, and all passed buffers
+are either truncated if the caller supplied the buffer, or deallocated
+if the function allocated the buffer.
+@end deftypefun
+
+
+@c **********************************************************
+@c ******************* MPIs ******** ***********************
+@c **********************************************************
+@node MPI library
+@chapter MPI library
+
+@menu
+* Data types:: MPI related data types.
+* Basic functions:: First steps with MPI numbers.
+* MPI formats:: External representation of MPIs.
+* Calculations:: Performing MPI calculations.
+* Comparisons:: How to compare MPI values.
+* Bit manipulations:: How to access single bits of MPI values.
+* EC functions:: Elliptic curve related functions.
+* Miscellaneous:: Miscellaneous MPI functions.
+@end menu
+
+Public key cryptography is based on mathematics with large numbers. To
+implement the public key functions, a library for handling these large
+numbers is required. Because of the general usefulness of such a
+library, its interface is exposed by Libgcrypt.
+In the context of Libgcrypt and in most other applications, these large
+numbers are called MPIs (multi-precision-integers).
+
+@node Data types
+@section Data types
+
+@deftp {Data type} {gcry_mpi_t}
+This type represents an object to hold an MPI.
+@end deftp
+
+@deftp {Data type} {gcry_mpi_point_t}
+This type represents an object to hold a point for elliptic curve math.
+@end deftp
+
+@node Basic functions
+@section Basic functions
+
+@noindent
+To work with MPIs, storage must be allocated and released for the
+numbers. This can be done with one of these functions:
+
+@deftypefun gcry_mpi_t gcry_mpi_new (@w{unsigned int @var{nbits}})
+
+Allocate a new MPI object, initialize it to 0 and initially allocate
+enough memory for a number of at least @var{nbits}. This pre-allocation is
+only a small performance issue and not actually necessary because
+Libgcrypt automatically re-allocates the required memory.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_snew (@w{unsigned int @var{nbits}})
+
+This is identical to @code{gcry_mpi_new} but allocates the MPI in the so
+called "secure memory" which in turn will take care that all derived
+values will also be stored in this "secure memory". Use this for highly
+confidential data like private key parameters.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_copy (@w{const gcry_mpi_t @var{a}})
+
+Create a new MPI as the exact copy of @var{a} but with the constant
+and immutable flags cleared.
+@end deftypefun
+
+
+@deftypefun void gcry_mpi_release (@w{gcry_mpi_t @var{a}})
+
+Release the MPI @var{a} and free all associated resources. Passing
+@code{NULL} is allowed and ignored. When a MPI stored in the "secure
+memory" is released, that memory gets wiped out immediately.
+@end deftypefun
+
+@noindent
+The simplest operations are used to assign a new value to an MPI:
+
+@deftypefun gcry_mpi_t gcry_mpi_set (@w{gcry_mpi_t @var{w}}, @w{const gcry_mpi_t @var{u}})
+
+Assign the value of @var{u} to @var{w} and return @var{w}. If
+@code{NULL} is passed for @var{w}, a new MPI is allocated, set to the
+value of @var{u} and returned.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_set_ui (@w{gcry_mpi_t @var{w}}, @w{unsigned long @var{u}})
+
+Assign the value of @var{u} to @var{w} and return @var{w}. If
+@code{NULL} is passed for @var{w}, a new MPI is allocated, set to the
+value of @var{u} and returned. This function takes an @code{unsigned
+int} as type for @var{u} and thus it is only possible to set @var{w} to
+small values (usually up to the word size of the CPU).
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_mpi_get_ui (@w{unsigned int *@var{w}}, @w{gcry_mpi_t @var{u}})
+
+If @var{u} is not negative and small enough to be stored in an
+@code{unsigned int} variable, store its value at @var{w}. If the
+value does not fit or is negative return GPG_ERR_ERANGE and do not
+change the value stored at @var{w}. Note that this function returns
+an @code{unsigned int} so that this value can immediately be used with
+the bit test functions. This is in contrast to the other "_ui"
+functions which allow for values up to an @code{unsigned long}.
+@end deftypefun
+
+
+@deftypefun void gcry_mpi_swap (@w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{b}})
+
+Swap the values of @var{a} and @var{b}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_snatch (@w{gcry_mpi_t @var{w}}, @
+ @w{const gcry_mpi_t @var{u}})
+
+Set @var{u} into @var{w} and release @var{u}. If @var{w} is
+@code{NULL} only @var{u} will be released.
+@end deftypefun
+
+@deftypefun void gcry_mpi_neg (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}})
+
+Set the sign of @var{w} to the negative of @var{u}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_abs (@w{gcry_mpi_t @var{w}})
+
+Clear the sign of @var{w}.
+@end deftypefun
+
+
+@node MPI formats
+@section MPI formats
+
+@noindent
+The following functions are used to convert between an external
+representation of an MPI and the internal one of Libgcrypt.
+
+@deftypefun gcry_error_t gcry_mpi_scan (@w{gcry_mpi_t *@var{r_mpi}}, @w{enum gcry_mpi_format @var{format}}, @w{const unsigned char *@var{buffer}}, @w{size_t @var{buflen}}, @w{size_t *@var{nscanned}})
+
+Convert the external representation of an integer stored in @var{buffer}
+with a length of @var{buflen} into a newly created MPI returned which
+will be stored at the address of @var{r_mpi}. For certain formats the
+length argument is not required and should be passed as @code{0}. A
+@var{buflen} larger than 16 MiByte will be rejected. After a
+successful operation the variable @var{nscanned} receives the number of
+bytes actually scanned unless @var{nscanned} was given as
+@code{NULL}. @var{format} describes the format of the MPI as stored in
+@var{buffer}:
+
+@table @code
+@item GCRYMPI_FMT_STD
+2-complement stored without a length header. Note that
+@code{gcry_mpi_print} stores a @code{0} as a string of zero length.
+
+@item GCRYMPI_FMT_PGP
+As used by OpenPGP (only defined as unsigned). This is basically
+@code{GCRYMPI_FMT_STD} with a 2 byte big endian length header.
+A length header indicating a length of more than 16384 is not allowed.
+
+@item GCRYMPI_FMT_SSH
+As used in the Secure Shell protocol. This is @code{GCRYMPI_FMT_STD}
+with a 4 byte big endian header.
+
+@item GCRYMPI_FMT_HEX
+Stored as a string with each byte of the MPI encoded as 2 hex digits.
+Negative numbers are prefix with a minus sign and in addition the
+high bit is always zero to make clear that an explicit sign ist used.
+When using this format, @var{buflen} must be zero.
+
+@item GCRYMPI_FMT_USG
+Simple unsigned integer.
+@end table
+
+@noindent
+Note that all of the above formats store the integer in big-endian
+format (MSB first).
+@end deftypefun
+
+
+@deftypefun gcry_error_t gcry_mpi_print (@w{enum gcry_mpi_format @var{format}}, @w{unsigned char *@var{buffer}}, @w{size_t @var{buflen}}, @w{size_t *@var{nwritten}}, @w{const gcry_mpi_t @var{a}})
+
+Convert the MPI @var{a} into an external representation described by
+@var{format} (see above) and store it in the provided @var{buffer}
+which has a usable length of at least the @var{buflen} bytes. If
+@var{nwritten} is not NULL, it will receive the number of bytes
+actually stored in @var{buffer} after a successful operation.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_mpi_aprint (@w{enum gcry_mpi_format @var{format}}, @w{unsigned char **@var{buffer}}, @w{size_t *@var{nbytes}}, @w{const gcry_mpi_t @var{a}})
+
+Convert the MPI @var{a} into an external representation described by
+@var{format} (see above) and store it in a newly allocated buffer which
+address will be stored in the variable @var{buffer} points to. The
+number of bytes stored in this buffer will be stored in the variable
+@var{nbytes} points to, unless @var{nbytes} is @code{NULL}.
+
+Even if @var{nbytes} is zero, the function allocates at least one byte
+and store a zero there. Thus with formats @code{GCRYMPI_FMT_STD} and
+@code{GCRYMPI_FMT_USG} the caller may safely set a returned length of
+0 to 1 to represent a zero as a 1 byte string.
+
+@end deftypefun
+
+@deftypefun void gcry_mpi_dump (@w{const gcry_mpi_t @var{a}})
+
+Dump the value of @var{a} in a format suitable for debugging to
+Libgcrypt's logging stream. Note that one leading space but no trailing
+space or linefeed will be printed. It is okay to pass @code{NULL} for
+@var{a}.
+@end deftypefun
+
+
+@node Calculations
+@section Calculations
+
+@noindent
+Basic arithmetic operations:
+
+@deftypefun void gcry_mpi_add (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
+
+@math{@var{w} = @var{u} + @var{v}}.
+@end deftypefun
+
+
+@deftypefun void gcry_mpi_add_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
+
+@math{@var{w} = @var{u} + @var{v}}. Note that @var{v} is an unsigned integer.
+@end deftypefun
+
+
+@deftypefun void gcry_mpi_addm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
+
+@math{@var{w} = @var{u} + @var{v} \bmod @var{m}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_sub (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
+
+@math{@var{w} = @var{u} - @var{v}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_sub_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
+
+@math{@var{w} = @var{u} - @var{v}}. @var{v} is an unsigned integer.
+@end deftypefun
+
+@deftypefun void gcry_mpi_subm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
+
+@math{@var{w} = @var{u} - @var{v} \bmod @var{m}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mul (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
+
+@math{@var{w} = @var{u} * @var{v}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mul_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
+
+@math{@var{w} = @var{u} * @var{v}}. @var{v} is an unsigned integer.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mulm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
+
+@math{@var{w} = @var{u} * @var{v} \bmod @var{m}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mul_2exp (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{e}})
+
+@c FIXME: I am in need for a real TeX{info} guru:
+@c I don't know why TeX can grok @var{e} here.
+@math{@var{w} = @var{u} * 2^e}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_div (@w{gcry_mpi_t @var{q}}, @w{gcry_mpi_t @var{r}}, @w{gcry_mpi_t @var{dividend}}, @w{gcry_mpi_t @var{divisor}}, @w{int @var{round}})
+
+@math{@var{q} = @var{dividend} / @var{divisor}}, @math{@var{r} =
+@var{dividend} \bmod @var{divisor}}. @var{q} and @var{r} may be passed
+as @code{NULL}. @var{round} is either negative for floored division
+(rounds towards the next lower integer) or zero for truncated division
+(rounds towards zero).
+@end deftypefun
+
+@deftypefun void gcry_mpi_mod (@w{gcry_mpi_t @var{r}}, @w{gcry_mpi_t @var{dividend}}, @w{gcry_mpi_t @var{divisor}})
+
+@math{@var{r} = @var{dividend} \bmod @var{divisor}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_powm (@w{gcry_mpi_t @var{w}}, @w{const gcry_mpi_t @var{b}}, @w{const gcry_mpi_t @var{e}}, @w{const gcry_mpi_t @var{m}})
+
+@c I don't know why TeX can grok @var{e} here.
+@math{@var{w} = @var{b}^e \bmod @var{m}}.
+@end deftypefun
+
+@deftypefun int gcry_mpi_gcd (@w{gcry_mpi_t @var{g}}, @w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{b}})
+
+Set @var{g} to the greatest common divisor of @var{a} and @var{b}.
+Return true if the @var{g} is 1.
+@end deftypefun
+
+@deftypefun int gcry_mpi_invm (@w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{m}})
+
+Set @var{x} to the multiplicative inverse of @math{@var{a} \bmod @var{m}}.
+Return true if the inverse exists.
+@end deftypefun
+
+
+@node Comparisons
+@section Comparisons
+
+@noindent
+The next 2 functions are used to compare MPIs:
+
+
+@deftypefun int gcry_mpi_cmp (@w{const gcry_mpi_t @var{u}}, @w{const gcry_mpi_t @var{v}})
+
+Compare the multi-precision-integers number @var{u} and @var{v}
+returning 0 for equality, a positive value for @var{u} > @var{v} and a
+negative for @var{u} < @var{v}. If both numbers are opaque values
+(cf, gcry_mpi_set_opaque) the comparison is done by checking the bit
+sizes using memcmp. If only one number is an opaque value, the opaque
+value is less than the other number.
+@end deftypefun
+
+@deftypefun int gcry_mpi_cmp_ui (@w{const gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
+
+Compare the multi-precision-integers number @var{u} with the unsigned
+integer @var{v} returning 0 for equality, a positive value for @var{u} >
+@var{v} and a negative for @var{u} < @var{v}.
+@end deftypefun
+
+@deftypefun int gcry_mpi_is_neg (@w{const gcry_mpi_t @var{a}})
+
+Return 1 if @var{a} is less than zero; return 0 if zero or positive.
+@end deftypefun
+
+
+@node Bit manipulations
+@section Bit manipulations
+
+@noindent
+There are a couple of functions to get information on arbitrary bits
+in an MPI and to set or clear them:
+
+@deftypefun {unsigned int} gcry_mpi_get_nbits (@w{gcry_mpi_t @var{a}})
+
+Return the number of bits required to represent @var{a}.
+@end deftypefun
+
+@deftypefun int gcry_mpi_test_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Return true if bit number @var{n} (counting from 0) is set in @var{a}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_set_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Set bit number @var{n} in @var{a}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_clear_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Clear bit number @var{n} in @var{a}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_set_highbit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Set bit number @var{n} in @var{a} and clear all bits greater than @var{n}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_clear_highbit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Clear bit number @var{n} in @var{a} and all bits greater than @var{n}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_rshift (@w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Shift the value of @var{a} by @var{n} bits to the right and store the
+result in @var{x}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_lshift (@w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Shift the value of @var{a} by @var{n} bits to the left and store the
+result in @var{x}.
+@end deftypefun
+
+@node EC functions
+@section EC functions
+
+@noindent
+Libgcrypt provides an API to access low level functions used by its
+elliptic curve implementation. These functions allow to implement
+elliptic curve methods for which no explicit support is available.
+
+@deftypefun gcry_mpi_point_t gcry_mpi_point_new (@w{unsigned int @var{nbits}})
+
+Allocate a new point object, initialize it to 0, and allocate enough
+memory for a points of at least @var{nbits}. This pre-allocation
+yields only a small performance win and is not really necessary
+because Libgcrypt automatically re-allocates the required memory.
+Using 0 for @var{nbits} is usually the right thing to do.
+@end deftypefun
+
+@deftypefun void gcry_mpi_point_release (@w{gcry_mpi_point_t @var{point}})
+
+Release @var{point} and free all associated resources. Passing
+@code{NULL} is allowed and ignored.
+@end deftypefun
+
+@deftypefun gcry_mpi_point_t gcry_mpi_point_copy (@w{gcry_mpi_point_t @var{point}})
+
+Allocate and return a new point object and initialize it with
+@var{point}. If @var{point} is NULL the function is identical to
+@code{gcry_mpi_point_new(0)}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_point_get (@w{gcry_mpi_t @var{x}}, @
+ @w{gcry_mpi_t @var{y}}, @w{gcry_mpi_t @var{z}}, @
+ @w{gcry_mpi_point_t @var{point}})
+
+Store the projective coordinates from @var{point} into the MPIs
+@var{x}, @var{y}, and @var{z}. If a coordinate is not required,
+@code{NULL} may be used for @var{x}, @var{y}, or @var{z}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_point_snatch_get (@w{gcry_mpi_t @var{x}}, @
+ @w{gcry_mpi_t @var{y}}, @w{gcry_mpi_t @var{z}}, @
+ @w{gcry_mpi_point_t @var{point}})
+
+Store the projective coordinates from @var{point} into the MPIs
+@var{x}, @var{y}, and @var{z}. If a coordinate is not required,
+@code{NULL} may be used for @var{x}, @var{y}, or @var{z}. The object
+@var{point} is then released. Using this function instead of
+@code{gcry_mpi_point_get} and @code{gcry_mpi_point_release} has the
+advantage of avoiding some extra memory allocations and copies.
+@end deftypefun
+
+@deftypefun gcry_mpi_point_t gcry_mpi_point_set ( @
+ @w{gcry_mpi_point_t @var{point}}, @
+ @w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{y}}, @w{gcry_mpi_t @var{z}})
+
+Store the projective coordinates from @var{x}, @var{y}, and @var{z}
+into @var{point}. If a coordinate is given as @code{NULL}, the value
+0 is used. If @code{NULL} is used for @var{point} a new point object
+is allocated and returned. Returns @var{point} or the newly allocated
+point object.
+@end deftypefun
+
+@deftypefun gcry_mpi_point_t gcry_mpi_point_snatch_set ( @
+ @w{gcry_mpi_point_t @var{point}}, @
+ @w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{y}}, @w{gcry_mpi_t @var{z}})
+
+Store the projective coordinates from @var{x}, @var{y}, and @var{z}
+into @var{point}. If a coordinate is given as @code{NULL}, the value
+0 is used. If @code{NULL} is used for @var{point} a new point object
+is allocated and returned. The MPIs @var{x}, @var{y}, and @var{z} are
+released. Using this function instead of @code{gcry_mpi_point_set}
+and 3 calls to @code{gcry_mpi_release} has the advantage of avoiding
+some extra memory allocations and copies. Returns @var{point} or the
+newly allocated point object.
+@end deftypefun
+
+@anchor{gcry_mpi_ec_new}
+@deftypefun gpg_error_t gcry_mpi_ec_new (@w{gcry_ctx_t *@var{r_ctx}}, @
+ @w{gcry_sexp_t @var{keyparam}}, @w{const char *@var{curvename}})
+
+Allocate a new context for elliptic curve operations. If
+@var{keyparam} is given it specifies the parameters of the curve
+(@pxref{ecc_keyparam}). If @var{curvename} is given in addition to
+@var{keyparam} and the key parameters do not include a named curve
+reference, the string @var{curvename} is used to fill in missing
+parameters. If only @var{curvename} is given, the context is
+initialized for this named curve.
+
+If a parameter specifying a point (e.g. @code{g} or @code{q}) is not
+found, the parser looks for a non-encoded point by appending
+@code{.x}, @code{.y}, and @code{.z} to the parameter name and looking
+them all up to create a point. A parameter with the suffix @code{.z}
+is optional and defaults to 1.
+
+On success the function returns 0 and stores the new context object at
+@var{r_ctx}; this object eventually needs to be released
+(@pxref{gcry_ctx_release}). On error the function stores @code{NULL} at
+@var{r_ctx} and returns an error code.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_ec_get_mpi ( @
+ @w{const char *@var{name}}, @w{gcry_ctx_t @var{ctx}}, @w{int @var{copy}})
+
+Return the MPI with @var{name} from the context @var{ctx}. If not
+found @code{NULL} is returned. If the returned MPI may later be
+modified, it is suggested to pass @code{1} to @var{copy}, so that the
+function guarantees that a modifiable copy of the MPI is returned. If
+@code{0} is used for @var{copy}, this function may return a constant
+flagged MPI. In any case @code{gcry_mpi_release} needs to be called
+to release the result. For valid names @ref{ecc_keyparam}. If the
+public key @code{q} is requested but only the private key @code{d} is
+available, @code{q} will be recomputed on the fly. If a point
+parameter is requested it is returned as an uncompressed
+encoded point unless these special names are used:
+@table @var
+@item q@@eddsa
+Return an EdDSA style compressed point. This is only supported for
+Twisted Edwards curves.
+@end table
+@end deftypefun
+
+@deftypefun gcry_mpi_point_t gcry_mpi_ec_get_point ( @
+ @w{const char *@var{name}}, @w{gcry_ctx_t @var{ctx}}, @w{int @var{copy}})
+
+Return the point with @var{name} from the context @var{ctx}. If not
+found @code{NULL} is returned. If the returned MPI may later be
+modified, it is suggested to pass @code{1} to @var{copy}, so that the
+function guarantees that a modifiable copy of the MPI is returned. If
+@code{0} is used for @var{copy}, this function may return a constant
+flagged point. In any case @code{gcry_mpi_point_release} needs to be
+called to release the result. If the public key @code{q} is requested
+but only the private key @code{d} is available, @code{q} will be
+recomputed on the fly.
+@end deftypefun
+
+@deftypefun gpg_error_t gcry_mpi_ec_set_mpi ( @
+ @w{const char *@var{name}}, @w{gcry_mpi_t @var{newvalue}}, @
+ @w{gcry_ctx_t @var{ctx}})
+
+Store the MPI @var{newvalue} at @var{name} into the context @var{ctx}.
+On success @code{0} is returned; on error an error code. Valid names
+are the MPI parameters of an elliptic curve (@pxref{ecc_keyparam}).
+@end deftypefun
+
+@deftypefun gpg_error_t gcry_mpi_ec_set_point ( @
+ @w{const char *@var{name}}, @w{gcry_mpi_point_t @var{newvalue}}, @
+ @w{gcry_ctx_t @var{ctx}})
+
+Store the point @var{newvalue} at @var{name} into the context
+@var{ctx}. On success @code{0} is returned; on error an error code.
+Valid names are the point parameters of an elliptic curve
+(@pxref{ecc_keyparam}).
+@end deftypefun
+
+@deftypefun gpg_err_code_t gcry_mpi_ec_decode_point ( @
+ @w{mpi_point_t @var{result}}, @w{gcry_mpi_t @var{value}}, @
+ @w{gcry_ctx_t @var{ctx}})
+
+Decode the point given as an MPI in @var{value} and store at
+@var{result}. To decide which encoding is used the function takes a
+context @var{ctx} which can be created with @code{gcry_mpi_ec_new}.
+If @code{NULL} is given for the context the function assumes a 0x04
+prefixed uncompressed encoding. On error an error code is returned
+and @var{result} might be changed.
+@end deftypefun
+
+
+@deftypefun int gcry_mpi_ec_get_affine ( @
+ @w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{y}}, @
+ @w{gcry_mpi_point_t @var{point}}, @w{gcry_ctx_t @var{ctx}})
+
+Compute the affine coordinates from the projective coordinates in
+@var{point} and store them into @var{x} and @var{y}. If one
+coordinate is not required, @code{NULL} may be passed to @var{x} or
+@var{y}. @var{ctx} is the context object which has been created using
+@code{gcry_mpi_ec_new}. Returns 0 on success or not 0 if @var{point}
+is at infinity.
+
+Note that you can use @code{gcry_mpi_ec_set_point} with the value
+@code{GCRYMPI_CONST_ONE} for @var{z} to convert affine coordinates
+back into projective coordinates.
+
+@end deftypefun
+
+@deftypefun void gcry_mpi_ec_dup ( @
+ @w{gcry_mpi_point_t @var{w}}, @w{gcry_mpi_point_t @var{u}}, @
+ @w{gcry_ctx_t @var{ctx}})
+
+Double the point @var{u} of the elliptic curve described by @var{ctx}
+and store the result into @var{w}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_ec_add ( @
+ @w{gcry_mpi_point_t @var{w}}, @w{gcry_mpi_point_t @var{u}}, @
+ @w{gcry_mpi_point_t @var{v}}, @w{gcry_ctx_t @var{ctx}})
+
+Add the points @var{u} and @var{v} of the elliptic curve described by
+@var{ctx} and store the result into @var{w}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_ec_sub ( @
+ @w{gcry_mpi_point_t @var{w}}, @w{gcry_mpi_point_t @var{u}}, @
+ @w{gcry_mpi_point_t @var{v}}, @w{gcry_ctx_t @var{ctx}})
+
+Subtracts the point @var{v} from the point @var{u} of the elliptic
+curve described by @var{ctx} and store the result into @var{w}. Only
+Twisted Edwards curves are supported for now.
+@end deftypefun
+
+@deftypefun void gcry_mpi_ec_mul ( @
+ @w{gcry_mpi_point_t @var{w}}, @w{gcry_mpi_t @var{n}}, @
+ @w{gcry_mpi_point_t @var{u}}, @w{gcry_ctx_t @var{ctx}})
+
+Multiply the point @var{u} of the elliptic curve described by
+@var{ctx} by @var{n} and store the result into @var{w}.
+@end deftypefun
+
+@deftypefun int gcry_mpi_ec_curve_point ( @
+ @w{gcry_mpi_point_t @var{point}}, @w{gcry_ctx_t @var{ctx}})
+
+Return true if @var{point} is on the elliptic curve described by
+@var{ctx}.
+@end deftypefun
+
+
+@node Miscellaneous
+@section Miscellaneous
+
+An MPI data type is allowed to be ``misused'' to store an arbitrary
+value. Two functions implement this kludge:
+
+@deftypefun gcry_mpi_t gcry_mpi_set_opaque (@w{gcry_mpi_t @var{a}}, @w{void *@var{p}}, @w{unsigned int @var{nbits}})
+
+Store @var{nbits} of the value @var{p} points to in @var{a} and mark
+@var{a} as an opaque value (i.e. an value that can't be used for any
+math calculation and is only used to store an arbitrary bit pattern in
+@var{a}). Ownership of @var{p} is taken by this function and thus the
+user may not use dereference the passed value anymore. It is required
+that them memory referenced by @var{p} has been allocated in a way
+that @code{gcry_free} is able to release it.
+
+WARNING: Never use an opaque MPI for actual math operations. The only
+valid functions are gcry_mpi_get_opaque and gcry_mpi_release. Use
+gcry_mpi_scan to convert a string of arbitrary bytes into an MPI.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_set_opaque_copy (@w{gcry_mpi_t @var{a}}, @w{const void *@var{p}}, @w{unsigned int @var{nbits}})
+
+Same as @code{gcry_mpi_set_opaque} but ownership of @var{p} is not
+taken instead a copy of @var{p} is used.
+@end deftypefun
+
+
+@deftypefun {void *} gcry_mpi_get_opaque (@w{gcry_mpi_t @var{a}}, @w{unsigned int *@var{nbits}})
+
+Return a pointer to an opaque value stored in @var{a} and return its
+size in @var{nbits}. Note that the returned pointer is still owned by
+@var{a} and that the function should never be used for an non-opaque
+MPI.
+@end deftypefun
+
+Each MPI has an associated set of flags for special purposes. The
+currently defined flags are:
+
+@table @code
+@item GCRYMPI_FLAG_SECURE
+Setting this flag converts @var{a} into an MPI stored in "secure
+memory". Clearing this flag is not allowed.
+@item GCRYMPI_FLAG_OPAQUE
+This is an internal flag, indicating the an opaque valuue and not an
+integer is stored. This is an read-only flag; it may not be set or
+cleared.
+@item GCRYMPI_FLAG_IMMUTABLE
+If this flag is set, the MPI is marked as immutable. Setting or
+changing the value of that MPI is ignored and an error message is
+logged. The flag is sometimes useful for debugging.
+@item GCRYMPI_FLAG_CONST
+If this flag is set, the MPI is marked as a constant and as immutable
+Setting or changing the value of that MPI is ignored and an error
+message is logged. Such an MPI will never be deallocated and may thus
+be used without copying. Note that using gcry_mpi_copy will return a
+copy of that constant with this and the immutable flag cleared. A few
+commonly used constants are pre-defined and accessible using the
+macros @code{GCRYMPI_CONST_ONE}, @code{GCRYMPI_CONST_TWO},
+@code{GCRYMPI_CONST_THREE}, @code{GCRYMPI_CONST_FOUR}, and
+@code{GCRYMPI_CONST_EIGHT}.
+@item GCRYMPI_FLAG_USER1
+@itemx GCRYMPI_FLAG_USER2
+@itemx GCRYMPI_FLAG_USER3
+@itemx GCRYMPI_FLAG_USER4
+These flags are reserved for use by the application.
+@end table
+
+@deftypefun void gcry_mpi_set_flag (@w{gcry_mpi_t @var{a}}, @
+ @w{enum gcry_mpi_flag @var{flag}})
+
+Set the @var{flag} for the MPI @var{a}. The only allowed flags are
+@code{GCRYMPI_FLAG_SECURE}, @code{GCRYMPI_FLAG_IMMUTABLE}, and
+@code{GCRYMPI_FLAG_CONST}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_clear_flag (@w{gcry_mpi_t @var{a}}, @
+ @w{enum gcry_mpi_flag @var{flag}})
+
+Clear @var{flag} for the multi-precision-integers @var{a}. The only
+allowed flag is @code{GCRYMPI_FLAG_IMMUTABLE} but only if
+@code{GCRYMPI_FLAG_CONST} is not set. If @code{GCRYMPI_FLAG_CONST} is
+set, clearing @code{GCRYMPI_FLAG_IMMUTABLE} will simply be ignored.
+@end deftypefun
+o
+@deftypefun int gcry_mpi_get_flag (@w{gcry_mpi_t @var{a}}, @
+ @w{enum gcry_mpi_flag @var{flag}})
+
+Return true if @var{flag} is set for @var{a}.
+@end deftypefun
+
+
+To put a random value into an MPI, the following convenience function
+may be used:
+
+@deftypefun void gcry_mpi_randomize (@w{gcry_mpi_t @var{w}}, @w{unsigned int @var{nbits}}, @w{enum gcry_random_level @var{level}})
+
+Set the multi-precision-integers @var{w} to a random non-negative number of
+@var{nbits}, using random data quality of level @var{level}. In case
+@var{nbits} is not a multiple of a byte, @var{nbits} is rounded up to
+the next byte boundary. When using a @var{level} of
+@code{GCRY_WEAK_RANDOM} this function makes use of
+@code{gcry_create_nonce}.
+@end deftypefun
+
+@c **********************************************************
+@c ******************** Prime numbers ***********************
+@c **********************************************************
+@node Prime numbers
+@chapter Prime numbers
+
+@menu
+* Generation:: Generation of new prime numbers.
+* Checking:: Checking if a given number is prime.
+@end menu
+
+@node Generation
+@section Generation
+
+@deftypefun gcry_error_t gcry_prime_generate (gcry_mpi_t *@var{prime},unsigned int @var{prime_bits}, unsigned int @var{factor_bits}, gcry_mpi_t **@var{factors}, gcry_prime_check_func_t @var{cb_func}, void *@var{cb_arg}, gcry_random_level_t @var{random_level}, unsigned int @var{flags})
+
+Generate a new prime number of @var{prime_bits} bits and store it in
+@var{prime}. If @var{factor_bits} is non-zero, one of the prime factors
+of (@var{prime} - 1) / 2 must be @var{factor_bits} bits long. If
+@var{factors} is non-zero, allocate a new, @code{NULL}-terminated array
+holding the prime factors and store it in @var{factors}. @var{flags}
+might be used to influence the prime number generation process.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_prime_group_generator (gcry_mpi_t *@var{r_g}, gcry_mpi_t @var{prime}, gcry_mpi_t *@var{factors}, gcry_mpi_t @var{start_g})
+
+Find a generator for @var{prime} where the factorization of
+(@var{prime}-1) is in the @code{NULL} terminated array @var{factors}.
+Return the generator as a newly allocated MPI in @var{r_g}. If
+@var{start_g} is not NULL, use this as the start for the search.
+@end deftypefun
+
+@deftypefun void gcry_prime_release_factors (gcry_mpi_t *@var{factors})
+
+Convenience function to release the @var{factors} array.
+@end deftypefun
+
+@node Checking
+@section Checking
+
+@deftypefun gcry_error_t gcry_prime_check (gcry_mpi_t @var{p}, unsigned int @var{flags})
+
+Check whether the number @var{p} is prime. Returns zero in case @var{p}
+is indeed a prime, returns @code{GPG_ERR_NO_PRIME} in case @var{p} is
+not a prime and a different error code in case something went horribly
+wrong.
+@end deftypefun
+
+@c **********************************************************
+@c ******************** Utilities ***************************
+@c **********************************************************
+@node Utilities
+@chapter Utilities
+
+@menu
+* Memory allocation:: Functions related with memory allocation.
+* Context management:: Functions related with context management.
+* Buffer description:: A data type to describe buffers.
+* Config reporting:: How to return Libgcrypt's configuration.
+@end menu
+
+
+@node Memory allocation
+@section Memory allocation
+
+@deftypefun {void *} gcry_malloc (size_t @var{n})
+
+This function tries to allocate @var{n} bytes of memory. On success
+it returns a pointer to the memory area, in an out-of-core condition,
+it returns NULL.
+@end deftypefun
+
+@deftypefun {void *} gcry_malloc_secure (size_t @var{n})
+Like @code{gcry_malloc}, but uses secure memory.
+@end deftypefun
+
+@deftypefun {void *} gcry_calloc (size_t @var{n}, size_t @var{m})
+
+This function allocates a cleared block of memory (i.e. initialized with
+zero bytes) long enough to contain a vector of @var{n} elements, each of
+size @var{m} bytes. On success it returns a pointer to the memory
+block; in an out-of-core condition, it returns NULL.
+@end deftypefun
+
+@deftypefun {void *} gcry_calloc_secure (size_t @var{n}, size_t @var{m})
+Like @code{gcry_calloc}, but uses secure memory.
+@end deftypefun
+
+@deftypefun {void *} gcry_realloc (void *@var{p}, size_t @var{n})
+
+This function tries to resize the memory area pointed to by @var{p} to
+@var{n} bytes. On success it returns a pointer to the new memory
+area, in an out-of-core condition, it returns NULL. Depending on
+whether the memory pointed to by @var{p} is secure memory or not,
+gcry_realloc tries to use secure memory as well.
+@end deftypefun
+
+@deftypefun void gcry_free (void *@var{p})
+Release the memory area pointed to by @var{p}.
+@end deftypefun
+
+
+@node Context management
+@section Context management
+
+Some function make use of a context object. As of now there are only
+a few math functions. However, future versions of Libgcrypt may make
+more use of this context object.
+
+@deftp {Data type} {gcry_ctx_t}
+This type is used to refer to the general purpose context object.
+@end deftp
+
+@anchor{gcry_ctx_release}
+@deftypefun void gcry_ctx_release (gcry_ctx_t @var{ctx})
+Release the context object @var{ctx} and all associated resources. A
+@code{NULL} passed as @var{ctx} is ignored.
+@end deftypefun
+
+@node Buffer description
+@section Buffer description
+
+To help hashing non-contiguous areas of memory a general purpose data
+type is defined:
+
+@deftp {Data type} {gcry_buffer_t}
+This type is a structure to describe a buffer. The user should make
+sure that this structure is initialized to zero. The available fields
+of this structure are:
+
+@table @code
+ @item .size
+ This is either 0 for no information available or indicates the
+ allocated length of the buffer.
+ @item .off
+ This is the offset into the buffer.
+ @item .len
+ This is the valid length of the buffer starting at @code{.off}.
+ @item .data
+ This is the address of the buffer.
+ @end table
+@end deftp
+
+@node Config reporting
+@section How to return Libgcrypt's configuration.
+
+Although @code{GCRYCTL_PRINT_CONFIG} can be used to print
+configuration options, it is sometimes necessary to check them in a
+program. This can be accomplished by using this function:
+
+@deftypefun {char *} gcry_get_config @
+ (@w{int @var{mode}}, @
+ @w{const char *@var{what}})
+
+This function returns a malloced string with colon delimited configure
+options. With a value of 0 for @var{mode} this string resembles the
+output of @code{GCRYCTL_PRINT_CONFIG}. However, if @var{what} is not
+NULL, only the line where the first field (e.g. "cpu-arch") matches
+@var{what} is returned.
+
+Other values than 0 for @var{mode} are not defined. The caller shall
+free the string using @code{gcry_free}. On error NULL is returned and
+ERRNO is set; if a value for WHAT is unknow ERRNO will be set to 0.
+@end deftypefun
+
+
+@c **********************************************************
+@c ********************* Tools ****************************
+@c **********************************************************
+@node Tools
+@chapter Tools
+
+@menu
+* hmac256:: A standalone HMAC-SHA-256 implementation
+@end menu
+
+@manpage hmac256.1
+@node hmac256
+@section A HMAC-SHA-256 tool
+@ifset manverb
+.B hmac256
+\- Compute an HMAC-SHA-256 MAC
+@end ifset
+
+@mansect synopsis
+@ifset manverb
+.B hmac256
+.RB [ \-\-binary ]
+.I key
+.I [FILENAME]
+@end ifset
+
+@mansect description
+This is a standalone HMAC-SHA-256 implementation used to compute an
+HMAC-SHA-256 message authentication code. The tool has originally
+been developed as a second implementation for Libgcrypt to allow
+comparing against the primary implementation and to be used for
+internal consistency checks. It should not be used for sensitive data
+because no mechanisms to clear the stack etc are used.
+
+The code has been written in a highly portable manner and requires
+only a few standard definitions to be provided in a config.h file.
+
+@noindent
+@command{hmac256} is commonly invoked as
+
+@example
+hmac256 "This is my key" foo.txt
+@end example
+
+@noindent
+This compute the MAC on the file @file{foo.txt} using the key given on
+the command line.
+
+@mansect options
+@noindent
+@command{hmac256} understands these options:
+
+@table @gnupgtabopt
+
+@item --binary
+Print the MAC as a binary string. The default is to print the MAC
+encoded has lower case hex digits.
+
+@item --version
+Print version of the program and exit.
+
+@end table
+
+@mansect see also
+@ifset isman
+@command{sha256sum}(1)
+@end ifset
+@manpause
+
+@c **********************************************************
+@c **************** Environment Variables *****************
+@c **********************************************************
+@node Configuration
+@chapter Configuration files and environment variables
+
+This chapter describes which files and environment variables can be
+used to change the behaviour of Libgcrypt.
+
+@noindent
+The environment variables considered by Libgcrypt are:
+
+@table @code
+
+@item GCRYPT_BARRETT
+@cindex GCRYPT_BARRETT
+By setting this variable to any value a different algorithm for
+modular reduction is used for ECC.
+
+@item GCRYPT_RNDUNIX_DBG
+@item GCRYPT_RNDUNIX_DBGALL
+@cindex GCRYPT_RNDUNIX_DBG
+@cindex GCRYPT_RNDUNIX_DBGALL
+These two environment variables are used to enable debug output for
+the rndunix entropy gatherer, which is used on systems lacking a
+/dev/random device. The value of @code{GCRYPT_RNDUNIX_DBG} is a file
+name or @code{-} for stdout. Debug output is the written to this
+file. By setting @code{GCRYPT_RNDUNIX_DBGALL} to any value the debug
+output will be more verbose.
+
+@item GCRYPT_RNDW32_NOPERF
+@cindex GCRYPT_RNDW32_NOPERF
+Setting this environment variable on Windows to any value disables
+the use of performance data (@code{HKEY_PERFORMANCE_DATA}) as source
+for entropy. On some older Windows systems this could help to speed
+up the creation of random numbers but also decreases the amount of
+data used to init the random number generator.
+
+@item GCRYPT_RNDW32_DBG
+@cindex GCRYPT_RNDW32_DBG
+Setting the value of this variable to a positive integer logs
+information about the Windows entropy gatherer using the standard log
+interface.
+
+
+@item HOME
+@cindex HOME
+This is used to locate the socket to connect to the EGD random
+daemon. The EGD can be used on system without a /dev/random to speed
+up the random number generator. It is not needed on the majority of
+today's operating systems and support for EGD requires the use of a
+configure option at build time.
+
+@end table
+
+@noindent
+The files which Libgcrypt uses to retrieve system information and the
+files which can be created by the user to modify Libgcrypt's behavior
+are:
+
+@table @file
+
+@item /etc/gcrypt/hwf.deny
+@cindex /etc/gcrypt/hwf.deny
+This file can be used to disable the use of hardware based
+optimizations, @pxref{hardware features}.
+
+
+@item /etc/gcrypt/random.conf
+@cindex /etc/gcrypt/random.conf
+This file can be used to globally change parameters of the random
+generator. The file is a simple text file where empty lines and
+lines with the first non white-space character being '#' are
+ignored. Supported options are
+
+@table @file
+@item disable-jent
+@cindex disable-jent
+Disable the use of the jitter based entropy generator.
+
+@item only-urandom
+@cindex only-urandom
+Always use the non-blocking /dev/urandom or the respective system call
+instead of the blocking /dev/random. If Libgcrypt is used early in
+the boot process of the system, this option should only be used if the
+system also supports the getrandom system call.
+
+@end table
+
+@item /etc/gcrypt/fips_enabled
+@itemx /proc/sys/crypto/fips_enabled
+@cindex /etc/gcrypt/fips_enabled
+@cindex fips_enabled
+On Linux these files are used to enable FIPS mode, @pxref{enabling fips mode}.
+
+@item /proc/cpuinfo
+@itemx /proc/self/auxv
+@cindex /proc/cpuinfo
+@cindex /proc/self/auxv
+On Linux running on the ARM architecture, these files are used to read
+hardware capabilities of the CPU.
+
+@end table
+
+
+@c **********************************************************
+@c ***************** Architecure Overview *****************
+@c **********************************************************
+@node Architecture
+@chapter Architecture
+
+This chapter describes the internal architecture of Libgcrypt.
+
+Libgcrypt is a function library written in ISO C-90. Any compliant
+compiler should be able to build Libgcrypt as long as the target is
+either a POSIX platform or compatible to the API used by Windows NT.
+Provisions have been take so that the library can be directly used from
+C++ applications; however building with a C++ compiler is not supported.
+
+Building Libgcrypt is done by using the common @code{./configure && make}
+approach. The configure command is included in the source distribution
+and as a portable shell script it works on any Unix-alike system. The
+result of running the configure script are a C header file
+(@file{config.h}), customized Makefiles, the setup of symbolic links and
+a few other things. After that the make tool builds and optionally
+installs the library and the documentation. See the files
+@file{INSTALL} and @file{README} in the source distribution on how to do
+this.
+
+Libgcrypt is developed using a Subversion@footnote{A version control
+system available for many platforms} repository. Although all released
+versions are tagged in this repository, they should not be used to build
+production versions of Libgcrypt. Instead released tarballs should be
+used. These tarballs are available from several places with the master
+copy at @indicateurl{ftp://ftp.gnupg.org/gcrypt/libgcrypt/}.
+Announcements of new releases are posted to the
+@indicateurl{gnupg-announce@@gnupg.org} mailing list@footnote{See
+@url{http://www.gnupg.org/documentation/mailing-lists.en.html} for
+details.}.
+
+
+@float Figure,fig:subsystems
+@caption{Libgcrypt subsystems}
+@center @image{libgcrypt-modules, 150mm,,Libgcrypt subsystems}
+@end float
+
+Libgcrypt consists of several subsystems (@pxref{fig:subsystems}) and
+all these subsystems provide a public API; this includes the helper
+subsystems like the one for S-expressions. The API style depends on the
+subsystem; in general an open-use-close approach is implemented. The
+open returns a handle to a context used for all further operations on
+this handle, several functions may then be used on this handle and a
+final close function releases all resources associated with the handle.
+
+@menu
+* Public-Key Subsystem Architecture:: About public keys.
+* Symmetric Encryption Subsystem Architecture:: About standard ciphers.
+* Hashing and MACing Subsystem Architecture:: About hashing.
+* Multi-Precision-Integer Subsystem Architecture:: About big integers.
+* Prime-Number-Generator Subsystem Architecture:: About prime numbers.
+* Random-Number Subsystem Architecture:: About random stuff.
+@c * Helper Subsystems Architecture:: About other stuff.
+@end menu
+
+
+
+@node Public-Key Subsystem Architecture
+@section Public-Key Architecture
+
+Because public key cryptography is almost always used to process small
+amounts of data (hash values or session keys), the interface is not
+implemented using the open-use-close paradigm, but with single
+self-contained functions. Due to the wide variety of parameters
+required by different algorithms S-expressions, as flexible way to
+convey these parameters, are used. There is a set of helper functions
+to work with these S-expressions.
+@c see @ref{S-expression Subsystem Architecture}.
+
+Aside of functions to register new algorithms, map algorithms names to
+algorithms identifiers and to lookup properties of a key, the
+following main functions are available:
+
+@table @code
+
+@item gcry_pk_encrypt
+Encrypt data using a public key.
+
+@item gcry_pk_decrypt
+Decrypt data using a private key.
+
+@item gcry_pk_sign
+Sign data using a private key.
+
+@item gcry_pk_verify
+Verify that a signature matches the data.
+
+@item gcry_pk_testkey
+Perform a consistency over a public or private key.
+
+@item gcry_pk_genkey
+Create a new public/private key pair.
+
+@end table
+
+All these functions
+lookup the module implementing the algorithm and pass the actual work
+to that module. The parsing of the S-expression input and the
+construction of S-expression for the return values is done by the high
+level code (@file{cipher/pubkey.c}). Thus the internal interface
+between the algorithm modules and the high level functions passes data
+in a custom format.
+
+By default Libgcrypt uses a blinding technique for RSA decryption to
+mitigate real world timing attacks over a network: Instead of using
+the RSA decryption directly, a blinded value @math{y = x r^{e} \bmod n}
+is decrypted and the unblinded value @math{x' = y' r^{-1} \bmod n}
+returned. The blinding value @math{r} is a random value with the size
+of the modulus @math{n} and generated with @code{GCRY_WEAK_RANDOM}
+random level.
+
+@cindex X9.31
+@cindex FIPS 186
+The algorithm used for RSA and DSA key generation depends on whether
+Libgcrypt is operated in standard or in FIPS mode. In standard mode
+an algorithm based on the Lim-Lee prime number generator is used. In
+FIPS mode RSA keys are generated as specified in ANSI X9.31 (1998) and
+DSA keys as specified in FIPS 186-2.
+
+
+
+@node Symmetric Encryption Subsystem Architecture
+@section Symmetric Encryption Subsystem Architecture
+
+The interface to work with symmetric encryption algorithms is made up
+of functions from the @code{gcry_cipher_} name space. The
+implementation follows the open-use-close paradigm and uses registered
+algorithm modules for the actual work. Unless a module implements
+optimized cipher mode implementations, the high level code
+(@file{cipher/cipher.c}) implements the modes and calls the core
+algorithm functions to process each block.
+
+The most important functions are:
+
+@table @code
+
+@item gcry_cipher_open
+Create a new instance to encrypt or decrypt using a specified
+algorithm and mode.
+
+@item gcry_cipher_close
+Release an instance.
+
+@item gcry_cipher_setkey
+Set a key to be used for encryption or decryption.
+
+@item gcry_cipher_setiv
+Set an initialization vector to be used for encryption or decryption.
+
+@item gcry_cipher_encrypt
+@itemx gcry_cipher_decrypt
+Encrypt or decrypt data. These functions may be called with arbitrary
+amounts of data and as often as needed to encrypt or decrypt all data.
+
+There is no strict alignment requirements for data, but the best
+performance can be archived if data is aligned to cacheline boundary.
+
+@end table
+
+There are also functions to query properties of algorithms or context,
+like block length, key length, map names or to enable features like
+padding methods.
+
+
+
+@node Hashing and MACing Subsystem Architecture
+@section Hashing and MACing Subsystem Architecture
+
+The interface to work with message digests and CRC algorithms is made
+up of functions from the @code{gcry_md_} name space. The
+implementation follows the open-use-close paradigm and uses registered
+algorithm modules for the actual work. Although CRC algorithms are
+not considered cryptographic hash algorithms, they share enough
+properties so that it makes sense to handle them in the same way.
+It is possible to use several algorithms at once with one context and
+thus compute them all on the same data.
+
+The most important functions are:
+
+@table @code
+@item gcry_md_open
+Create a new message digest instance and optionally enable one
+algorithm. A flag may be used to turn the message digest algorithm
+into a HMAC algorithm.
+
+@item gcry_md_enable
+Enable an additional algorithm for the instance.
+
+@item gcry_md_setkey
+Set the key for the MAC.
+
+@item gcry_md_write
+Pass more data for computing the message digest to an instance.
+
+There is no strict alignment requirements for data, but the best
+performance can be archived if data is aligned to cacheline boundary.
+
+@item gcry_md_putc
+Buffered version of @code{gcry_md_write} implemented as a macro.
+
+@item gcry_md_read
+Finalize the computation of the message digest or HMAC and return the
+result.
+
+@item gcry_md_close
+Release an instance
+
+@item gcry_md_hash_buffer
+Convenience function to directly compute a message digest over a
+memory buffer without the need to create an instance first.
+
+@end table
+
+There are also functions to query properties of algorithms or the
+instance, like enabled algorithms, digest length, map algorithm names.
+it is also possible to reset an instance or to copy the current state
+of an instance at any time. Debug functions to write the hashed data
+to files are available as well.
+
+
+
+@node Multi-Precision-Integer Subsystem Architecture
+@section Multi-Precision-Integer Subsystem Architecture
+
+The implementation of Libgcrypt's big integer computation code is
+based on an old release of GNU Multi-Precision Library (GMP). The
+decision not to use the GMP library directly was due to stalled
+development at that time and due to security requirements which could
+not be provided by the code in GMP. As GMP does, Libgcrypt provides
+high performance assembler implementations of low level code for
+several CPUS to gain much better performance than with a generic C
+implementation.
+
+@noindent
+Major features of Libgcrypt's multi-precision-integer code compared to
+GMP are:
+
+@itemize
+@item
+Avoidance of stack based allocations to allow protection against
+swapping out of sensitive data and for easy zeroing of sensitive
+intermediate results.
+
+@item
+Optional use of secure memory and tracking of its use so that results
+are also put into secure memory.
+
+@item
+MPIs are identified by a handle (implemented as a pointer) to give
+better control over allocations and to augment them with extra
+properties like opaque data.
+
+@item
+Removal of unnecessary code to reduce complexity.
+
+@item
+Functions specialized for public key cryptography.
+
+@end itemize
+
+
+
+@node Prime-Number-Generator Subsystem Architecture
+@section Prime-Number-Generator Subsystem Architecture
+
+Libgcrypt provides an interface to its prime number generator. These
+functions make use of the internal prime number generator which is
+required for the generation for public key key pairs. The plain prime
+checking function is exported as well.
+
+The generation of random prime numbers is based on the Lim and Lee
+algorithm to create practically save primes.@footnote{Chae Hoon Lim
+and Pil Joong Lee. A key recovery attack on discrete log-based schemes
+using a prime order subgroup. In Burton S. Kaliski Jr., editor,
+Advances in Cryptology: Crypto '97, pages 249­-263, Berlin /
+Heidelberg / New York, 1997. Springer-Verlag. Described on page 260.}
+This algorithm creates a pool of smaller primes, select a few of them
+to create candidate primes of the form @math{2 * p_0 * p_1 * ... * p_n
++ 1}, tests the candidate for primality and permutates the pool until
+a prime has been found. It is possible to clamp one of the small
+primes to a certain size to help DSA style algorithms. Because most
+of the small primes in the pool are not used for the resulting prime
+number, they are saved for later use (see @code{save_pool_prime} and
+@code{get_pool_prime} in @file{cipher/primegen.c}). The prime
+generator optionally supports the finding of an appropriate generator.
+
+@noindent
+The primality test works in three steps:
+
+@enumerate
+@item
+The standard sieve algorithm using the primes up to 4999 is used as a
+quick first check.
+
+@item
+A Fermat test filters out almost all non-primes.
+
+@item
+A 5 round Rabin-Miller test is finally used. The first round uses a
+witness of 2, whereas the next rounds use a random witness.
+
+@end enumerate
+
+To support the generation of RSA and DSA keys in FIPS mode according
+to X9.31 and FIPS 186-2, Libgcrypt implements two additional prime
+generation functions: @code{_gcry_derive_x931_prime} and
+@code{_gcry_generate_fips186_2_prime}. These functions are internal
+and not available through the public API.
+
+
+
+@node Random-Number Subsystem Architecture
+@section Random-Number Subsystem Architecture
+
+Libgcrypt provides 3 levels or random quality: The level
+@code{GCRY_VERY_STRONG_RANDOM} usually used for key generation, the
+level @code{GCRY_STRONG_RANDOM} for all other strong random
+requirements and the function @code{gcry_create_nonce} which is used
+for weaker usages like nonces. There is also a level
+@code{GCRY_WEAK_RANDOM} which in general maps to
+@code{GCRY_STRONG_RANDOM} except when used with the function
+@code{gcry_mpi_randomize}, where it randomizes an
+multi-precision-integer using the @code{gcry_create_nonce} function.
+
+@noindent
+There are two distinct random generators available:
+
+@itemize
+@item
+The Continuously Seeded Pseudo Random Number Generator (CSPRNG), which
+is based on the classic GnuPG derived big pool implementation.
+Implemented in @code{random/random-csprng.c} and used by default.
+@item
+A FIPS approved ANSI X9.31 PRNG using AES with a 128 bit key. Implemented in
+@code{random/random-fips.c} and used if Libgcrypt is in FIPS mode.
+@end itemize
+
+@noindent
+Both generators make use of so-called entropy gathering modules:
+
+@table @asis
+@item rndlinux
+Uses the operating system provided @file{/dev/random} and
+@file{/dev/urandom} devices. The @file{/dev/gcrypt/random.conf}
+config option @option{only-urandom} can be used to inhibit the use of
+the blocking @file{/dev/random} device.
+
+@item rndunix
+Runs several operating system commands to collect entropy from sources
+like virtual machine and process statistics. It is a kind of
+poor-man's @code{/dev/random} implementation. It is not available in
+FIPS mode.
+
+@item rndegd
+Uses the operating system provided Entropy Gathering Daemon (EGD).
+The EGD basically uses the same algorithms as rndunix does. However
+as a system daemon it keeps on running and thus can serve several
+processes requiring entropy input and does not waste collected entropy
+if the application does not need all the collected entropy. It is not
+available in FIPS mode.
+
+@item rndw32
+Targeted for the Microsoft Windows OS. It uses certain properties of
+that system and is the only gathering module available for that OS.
+
+@item rndhw
+Extra module to collect additional entropy by utilizing a hardware
+random number generator. As of now the supported hardware RNG is
+the Padlock engine of VIA (Centaur) CPUs and x86 CPUs with the RDRAND
+instruction. It is not available in FIPS mode.
+
+@item rndjent
+Extra module to collect additional entropy using a CPU jitter based
+approach. This is only used on X86 hardware where the RDTSC opcode is
+available. The @file{/dev/gcrypt/random.conf} config option
+@option{disable-jent} can be used to inhibit the use of this module.
+
+@end table
+
+
+@menu
+* CSPRNG Description:: Description of the CSPRNG.
+* FIPS PRNG Description:: Description of the FIPS X9.31 PRNG.
+@end menu
+
+
+@node CSPRNG Description
+@subsection Description of the CSPRNG
+
+This random number generator is loosely modelled after the one
+described in Peter Gutmann's paper: "Software Generation of
+Practically Strong Random Numbers".@footnote{Also described in chapter
+6 of his book "Cryptographic Security Architecture", New York, 2004,
+ISBN 0-387-95387-6.}
+
+A pool of 600 bytes is used and mixed using the core SHA-1 hash
+transform function. Several extra features are used to make the
+robust against a wide variety of attacks and to protect against
+failures of subsystems. The state of the generator may be saved to a
+file and initially seed form a file.
+
+Depending on how Libgcrypt was build the generator is able to select
+the best working entropy gathering module. It makes use of the slow
+and fast collection methods and requires the pool to initially seeded
+form the slow gatherer or a seed file. An entropy estimation is used
+to mix in enough data from the gather modules before returning the
+actual random output. Process fork detection and protection is
+implemented.
+
+@c FIXME: The design and implementation needs a more verbose description.
+
+The implementation of the nonce generator (for
+@code{gcry_create_nonce}) is a straightforward repeated hash design: A
+28 byte buffer is initially seeded with the PID and the time in
+seconds in the first 20 bytes and with 8 bytes of random taken from
+the @code{GCRY_STRONG_RANDOM} generator. Random numbers are then
+created by hashing all the 28 bytes with SHA-1 and saving that again
+in the first 20 bytes. The hash is also returned as result.
+
+
+@node FIPS PRNG Description
+@subsection Description of the FIPS X9.31 PRNG
+
+The core of this deterministic random number generator is implemented
+according to the document ``NIST-Recommended Random Number Generator
+Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES and AES
+Algorithms'', dated 2005-01-31. This implementation uses the AES
+variant.
+
+The generator is based on contexts to utilize the same core functions
+for all random levels as required by the high-level interface. All
+random generators return their data in 128 bit blocks. If the caller
+requests less bits, the extra bits are not used. The key for each
+generator is only set once at the first time a generator context is
+used. The seed value is set along with the key and again after 1000
+output blocks.
+
+On Unix like systems the @code{GCRY_VERY_STRONG_RANDOM} and
+@code{GCRY_STRONG_RANDOM} generators are keyed and seeded using the
+rndlinux module with the @file{/dev/random} device. Thus these
+generators may block until the OS kernel has collected enough entropy.
+When used with Microsoft Windows the rndw32 module is used instead.
+
+The generator used for @code{gcry_create_nonce} is keyed and seeded
+from the @code{GCRY_STRONG_RANDOM} generator. Thus is may also block
+if the @code{GCRY_STRONG_RANDOM} generator has not yet been used
+before and thus gets initialized on the first use by
+@code{gcry_create_nonce}. This special treatment is justified by the
+weaker requirements for a nonce generator and to save precious kernel
+entropy for use by the ``real'' random generators.
+
+A self-test facility uses a separate context to check the
+functionality of the core X9.31 functions using a known answers test.
+During runtime each output block is compared to the previous one to
+detect a stuck generator.
+
+The DT value for the generator is made up of the current time down to
+microseconds (if available) and a free running 64 bit counter. When
+used with the test context the DT value is taken from the context and
+incremented on each use.
+
+@c @node Helper Subsystems Architecture
+@c @section Helper Subsystems Architecture
+@c
+@c There are a few smaller subsystems which are mainly used internally by
+@c Libgcrypt but also available to applications.
+@c
+@c @menu
+@c * S-expression Subsystem Architecture:: Details about the S-expression architecture.
+@c * Memory Subsystem Architecture:: Details about the memory allocation architecture.
+@c * Miscellaneous Subsystems Architecture:: Details about other subsystems.
+@c @end menu
+@c
+@c @node S-expression Subsystem Architecture
+@c @subsection S-expression Subsystem Architecture
+@c
+@c Libgcrypt provides an interface to S-expression to create and parse
+@c them. To use an S-expression with Libgcrypt it needs first be
+@c converted into the internal representation used by Libgcrypt (the type
+@c @code{gcry_sexp_t}). The conversion functions support a large subset
+@c of the S-expression specification and further feature a printf like
+@c function to convert a list of big integers or other binary data into
+@c an S-expression.
+@c
+@c Libgcrypt currently implements S-expressions using a tagged linked
+@c list. However this is not exposed to an application and may be
+@c changed in future releases to reduce overhead when already working
+@c with canonically encoded S-expressions. Secure memory is supported by
+@c this S-expressions implementation.
+@c
+@c @node Memory Subsystem Architecture
+@c @subsection Memory Subsystem Architecture
+@c
+@c TBD.
+@c
+@c
+@c @node Miscellaneous Subsystems Architecture
+@c @subsection Miscellaneous Subsystems Architecture
+@c
+@c TBD.
+@c
+@c
+
+
+
+@c **********************************************************
+@c ******************* Appendices *************************
+@c **********************************************************
+
+@c ********************************************
+@node Self-Tests
+@appendix Description of the Self-Tests
+
+In addition to the build time regression test suite, Libgcrypt
+implements self-tests to be performed at runtime. Which self-tests
+are actually used depends on the mode Libgcrypt is used in. In
+standard mode a limited set of self-tests is run at the time an
+algorithm is first used. Note that not all algorithms feature a
+self-test in standard mode. The @code{GCRYCTL_SELFTEST} control
+command may be used to run all implemented self-tests at any time;
+this will even run more tests than those run in FIPS mode.
+
+If any of the self-tests fails, the library immediately returns an
+error code to the caller. If Libgcrypt is in FIPS mode the self-tests
+will be performed within the ``Self-Test'' state and any failure puts
+the library into the ``Error'' state.
+
+@c --------------------------------
+@section Power-Up Tests
+
+Power-up tests are only performed if Libgcrypt is in FIPS mode.
+
+@subsection Symmetric Cipher Algorithm Power-Up Tests
+
+The following symmetric encryption algorithm tests are run during
+power-up:
+
+@table @asis
+@item 3DES
+To test the 3DES 3-key EDE encryption in ECB mode these tests are
+run:
+@enumerate
+@item
+A known answer test is run on a 64 bit test vector processed by 64
+rounds of Single-DES block encryption and decryption using a key
+changed with each round.
+@item
+A known answer test is run on a 64 bit test vector processed by 16
+rounds of 2-key and 3-key Triple-DES block encryption and decryptions
+using a key changed with each round.
+@item
+10 known answer tests using 3-key Triple-DES EDE encryption, comparing
+the ciphertext to the known value, then running a decryption and
+comparing it to the initial plaintext.
+@end enumerate
+(@code{cipher/des.c:selftest})
+
+@item AES-128
+A known answer tests is run using one test vector and one test
+key with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_128})
+
+@item AES-192
+A known answer tests is run using one test vector and one test
+key with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_192})
+
+@item AES-256
+A known answer tests is run using one test vector and one test key
+with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_256})
+@end table
+
+@subsection Hash Algorithm Power-Up Tests
+
+The following hash algorithm tests are run during power-up:
+
+@table @asis
+@item SHA-1
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha1.c:@/selftests_sha1})
+@item SHA-224
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha256.c:@/selftests_sha224})
+@item SHA-256
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha256.c:@/selftests_sha256})
+@item SHA-384
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha512.c:@/selftests_sha384})
+@item SHA-512
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha512.c:@/selftests_sha512})
+@end table
+
+@subsection MAC Algorithm Power-Up Tests
+
+The following MAC algorithm tests are run during power-up:
+
+@table @asis
+@item HMAC SHA-1
+A known answer test using 9 byte of data and a 64 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha1})
+@item HMAC SHA-224
+A known answer test using 28 byte of data and a 4 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha224})
+@item HMAC SHA-256
+A known answer test using 28 byte of data and a 4 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha256})
+@item HMAC SHA-384
+A known answer test using 28 byte of data and a 4 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha384})
+@item HMAC SHA-512
+A known answer test using 28 byte of data and a 4 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha512})
+@end table
+
+@subsection Random Number Power-Up Test
+
+The DRNG is tested during power-up this way:
+
+@enumerate
+@item
+Requesting one block of random using the public interface to check
+general working and the duplicated block detection.
+@item
+3 know answer tests using pre-defined keys, seed and initial DT
+values. For each test 3 blocks of 16 bytes are requested and compared
+to the expected result. The DT value is incremented for each block.
+@end enumerate
+
+@subsection Public Key Algorithm Power-Up Tests
+
+The public key algorithms are tested during power-up:
+
+@table @asis
+@item RSA
+A pre-defined 1024 bit RSA key is used and these tests are run
+in turn:
+@enumerate
+@item
+Conversion of S-expression to internal format.
+(@code{cipher/@/rsa.c:@/selftests_rsa})
+@item
+Private key consistency check.
+(@code{cipher/@/rsa.c:@/selftests_rsa})
+@item
+A pre-defined 20 byte value is signed with PKCS#1 padding for SHA-1.
+The result is verified using the public key against the original data
+and against modified data. (@code{cipher/@/rsa.c:@/selftest_sign_1024})
+@item
+A 1000 bit random value is encrypted and checked that it does not
+match the original random value. The encrypted result is then
+decrypted and checked that it matches the original random value.
+(@code{cipher/@/rsa.c:@/selftest_encr_1024})
+@end enumerate
+
+@item DSA
+A pre-defined 1024 bit DSA key is used and these tests are run in turn:
+@enumerate
+@item
+Conversion of S-expression to internal format.
+(@code{cipher/@/dsa.c:@/selftests_dsa})
+@item
+Private key consistency check.
+(@code{cipher/@/dsa.c:@/selftests_dsa})
+@item
+A pre-defined 20 byte value is signed with PKCS#1 padding for
+SHA-1. The result is verified using the public key against the
+original data and against modified data.
+(@code{cipher/@/dsa.c:@/selftest_sign_1024})
+@end enumerate
+@end table
+
+@subsection Integrity Power-Up Tests
+
+The integrity of the Libgcrypt is tested during power-up but only if
+checking has been enabled at build time. The check works by computing
+a HMAC SHA-256 checksum over the file used to load Libgcrypt into
+memory. That checksum is compared against a checksum stored in a file
+of the same name but with a single dot as a prefix and a suffix of
+@file{.hmac}.
+
+
+@subsection Critical Functions Power-Up Tests
+
+The 3DES weak key detection is tested during power-up by calling the
+detection function with keys taken from a table listening all weak
+keys. The table itself is protected using a SHA-1 hash.
+(@code{cipher/@/des.c:@/selftest})
+
+
+
+@c --------------------------------
+@section Conditional Tests
+
+The conditional tests are performed if a certain condition is met.
+This may occur at any time; the library does not necessary enter the
+``Self-Test'' state to run these tests but will transit to the
+``Error'' state if a test failed.
+
+@subsection Key-Pair Generation Tests
+
+After an asymmetric key-pair has been generated, Libgcrypt runs a
+pair-wise consistency tests on the generated key. On failure the
+generated key is not used, an error code is returned and, if in FIPS
+mode, the library is put into the ``Error'' state.
+
+@table @asis
+@item RSA
+The test uses a random number 64 bits less the size of the modulus as
+plaintext and runs an encryption and decryption operation in turn. The
+encrypted value is checked to not match the plaintext and the result
+of the decryption is checked to match the plaintext.
+
+A new random number of the same size is generated, signed and verified
+to test the correctness of the signing operation. As a second signing
+test, the signature is modified by incrementing its value and then
+verified with the expected result that the verification fails.
+(@code{cipher/@/rsa.c:@/test_keys})
+@item DSA
+The test uses a random number of the size of the Q parameter to create
+a signature and then checks that the signature verifies. As a second
+signing test, the data is modified by incrementing its value and then
+verified against the signature with the expected result that the
+verification fails. (@code{cipher/@/dsa.c:@/test_keys})
+@end table
+
+
+@subsection Software Load Tests
+
+No code is loaded at runtime.
+
+@subsection Manual Key Entry Tests
+
+A manual key entry feature is not implemented in Libgcrypt.
+
+
+@subsection Continuous RNG Tests
+
+The continuous random number test is only used in FIPS mode. The RNG
+generates blocks of 128 bit size; the first block generated per
+context is saved in the context and another block is generated to be
+returned to the caller. Each block is compared against the saved
+block and then stored in the context. If a duplicated block is
+detected an error is signaled and the library is put into the
+``Fatal-Error'' state.
+(@code{random/@/random-fips.c:@/x931_aes_driver})
+
+
+
+@c --------------------------------
+@section Application Requested Tests
+
+The application may requests tests at any time by means of the
+@code{GCRYCTL_SELFTEST} control command. Note that using these tests
+is not FIPS conform: Although Libgcrypt rejects all application
+requests for services while running self-tests, it does not ensure
+that no other operations of Libgcrypt are still being executed. Thus,
+in FIPS mode an application requesting self-tests needs to power-cycle
+Libgcrypt instead.
+
+When self-tests are requested, Libgcrypt runs all the tests it does
+during power-up as well as a few extra checks as described below.
+
+@subsection Symmetric Cipher Algorithm Tests
+
+The following symmetric encryption algorithm tests are run in addition
+to the power-up tests:
+
+@table @asis
+@item AES-128
+A known answer tests with test vectors taken from NIST SP800-38a and
+using the high level functions is run for block modes CFB and OFB.
+
+@end table
+
+@subsection Hash Algorithm Tests
+
+The following hash algorithm tests are run in addition to the
+power-up tests:
+
+@table @asis
+@item SHA-1
+@itemx SHA-224
+@itemx SHA-256
+@enumerate
+@item
+A known answer test using a 56 byte string is run.
+@item
+A known answer test using a string of one million letters "a" is run.
+@end enumerate
+(@code{cipher/@/sha1.c:@/selftests_sha1},
+@code{cipher/@/sha256.c:@/selftests_sha224},
+@code{cipher/@/sha256.c:@/selftests_sha256})
+@item SHA-384
+@item SHA-512
+@enumerate
+@item
+A known answer test using a 112 byte string is run.
+@item
+A known answer test using a string of one million letters "a" is run.
+@end enumerate
+(@code{cipher/@/sha512.c:@/selftests_sha384},
+@code{cipher/@/sha512.c:@/selftests_sha512})
+@end table
+
+@subsection MAC Algorithm Tests
+
+The following MAC algorithm tests are run in addition to the power-up
+tests:
+
+@table @asis
+@item HMAC SHA-1
+@enumerate
+@item
+A known answer test using 9 byte of data and a 20 byte key is run.
+@item
+A known answer test using 9 byte of data and a 100 byte key is run.
+@item
+A known answer test using 9 byte of data and a 49 byte key is run.
+@end enumerate
+(@code{cipher/hmac-tests.c:selftests_sha1})
+@item HMAC SHA-224
+@itemx HMAC SHA-256
+@itemx HMAC SHA-384
+@itemx HMAC SHA-512
+@enumerate
+@item
+A known answer test using 9 byte of data and a 20 byte key is run.
+@item
+A known answer test using 50 byte of data and a 20 byte key is run.
+@item
+A known answer test using 50 byte of data and a 26 byte key is run.
+@item
+A known answer test using 54 byte of data and a 131 byte key is run.
+@item
+A known answer test using 152 byte of data and a 131 byte key is run.
+@end enumerate
+(@code{cipher/@/hmac-tests.c:@/selftests_sha224},
+@code{cipher/@/hmac-tests.c:@/selftests_sha256},
+@code{cipher/@/hmac-tests.c:@/selftests_sha384},
+@code{cipher/@/hmac-tests.c:@/selftests_sha512})
+@end table
+
+
+@c ********************************************
+@node FIPS Mode
+@appendix Description of the FIPS Mode
+
+This appendix gives detailed information pertaining to the FIPS mode.
+In particular, the changes to the standard mode and the finite state
+machine are described. The self-tests required in this mode are
+described in the appendix on self-tests.
+
+@c -------------------------------
+@section Restrictions in FIPS Mode
+
+@noindent
+If Libgcrypt is used in FIPS mode these restrictions are effective:
+
+@itemize
+@item
+The cryptographic algorithms are restricted to this list:
+
+@table @asis
+@item GCRY_CIPHER_3DES
+3 key EDE Triple-DES symmetric encryption.
+@item GCRY_CIPHER_AES128
+AES 128 bit symmetric encryption.
+@item GCRY_CIPHER_AES192
+AES 192 bit symmetric encryption.
+@item GCRY_CIPHER_AES256
+AES 256 bit symmetric encryption.
+@item GCRY_MD_SHA1
+SHA-1 message digest.
+@item GCRY_MD_SHA224
+SHA-224 message digest.
+@item GCRY_MD_SHA256
+SHA-256 message digest.
+@item GCRY_MD_SHA384
+SHA-384 message digest.
+@item GCRY_MD_SHA512
+SHA-512 message digest.
+@item GCRY_MD_SHA1,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-1 message digest.
+@item GCRY_MD_SHA224,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-224 message digest.
+@item GCRY_MD_SHA256,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-256 message digest.
+@item GCRY_MD_SHA384,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-384 message digest.
+@item GCRY_MD_SHA512,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-512 message digest.
+@item GCRY_PK_RSA
+RSA encryption and signing.
+@item GCRY_PK_DSA
+DSA signing.
+@end table
+
+Note that the CRC algorithms are not considered cryptographic algorithms
+and thus are in addition available.
+
+@item
+RSA key generation refuses to create a key with a keysize of
+less than 1024 bits.
+
+@item
+DSA key generation refuses to create a key with a keysize other
+than 1024 bits.
+
+@item
+The @code{transient-key} flag for RSA and DSA key generation is ignored.
+
+@item
+Support for the VIA Padlock engine is disabled.
+
+@item
+FIPS mode may only be used on systems with a /dev/random device.
+Switching into FIPS mode on other systems will fail at runtime.
+
+@item
+Saving and loading a random seed file is ignored.
+
+@item
+An X9.31 style random number generator is used in place of the
+large-pool-CSPRNG generator.
+
+@item
+The command @code{GCRYCTL_ENABLE_QUICK_RANDOM} is ignored.
+
+@item
+Message digest debugging is disabled.
+
+@item
+All debug output related to cryptographic data is suppressed.
+
+@item
+On-the-fly self-tests are not performed, instead self-tests are run
+before entering operational state.
+
+@item
+The function @code{gcry_set_allocation_handler} may not be used. If
+it is used Libgcrypt disables FIPS mode unless Enforced FIPS mode is
+enabled, in which case Libgcrypt will enter the error state.
+
+@item
+The digest algorithm MD5 may not be used. If it is used Libgcrypt
+disables FIPS mode unless Enforced FIPS mode is enabled, in which case
+Libgcrypt will enter the error state.
+
+@item
+In Enforced FIPS mode the command @code{GCRYCTL_DISABLE_SECMEM} is
+ignored. In standard FIPS mode it disables FIPS mode.
+
+@item
+A handler set by @code{gcry_set_outofcore_handler} is ignored.
+@item
+A handler set by @code{gcry_set_fatalerror_handler} is ignored.
+
+@end itemize
+
+Note that when we speak about disabling FIPS mode, it merely means
+that the function @code{gcry_fips_mode_active} returns false; it does
+not mean that any non FIPS algorithms are allowed.
+
+@c ********************************************
+@section FIPS Finite State Machine
+
+The FIPS mode of libgcrypt implements a finite state machine (FSM) using
+8 states (@pxref{tbl:fips-states}) and checks at runtime that only valid
+transitions (@pxref{tbl:fips-state-transitions}) may happen.
+
+@float Figure,fig:fips-fsm
+@caption{FIPS mode state diagram}
+@center @image{fips-fsm,150mm,,FIPS FSM Diagram}
+@end float
+
+@float Table,tbl:fips-states
+@caption{FIPS mode states}
+@noindent
+States used by the FIPS FSM:
+@table @asis
+
+@item Power-Off
+Libgcrypt is not runtime linked to another application. This usually
+means that the library is not loaded into main memory. This state is
+documentation only.
+
+@item Power-On
+Libgcrypt is loaded into memory and API calls may be made. Compiler
+introduced constructor functions may be run. Note that Libgcrypt does
+not implement any arbitrary constructor functions to be called by the
+operating system
+
+@item Init
+The Libgcrypt initialization functions are performed and the library has
+not yet run any self-test.
+
+@item Self-Test
+Libgcrypt is performing self-tests.
+
+@item Operational
+Libgcrypt is in the operational state and all interfaces may be used.
+
+@item Error
+Libgrypt is in the error state. When calling any FIPS relevant
+interfaces they either return an error (@code{GPG_ERR_NOT_OPERATIONAL})
+or put Libgcrypt into the Fatal-Error state and won't return.
+
+@item Fatal-Error
+Libgcrypt is in a non-recoverable error state and
+will automatically transit into the Shutdown state.
+
+@item Shutdown
+Libgcrypt is about to be terminated and removed from the memory. The
+application may at this point still running cleanup handlers.
+
+@end table
+@end float
+
+
+@float Table,tbl:fips-state-transitions
+@caption{FIPS mode state transitions}
+@noindent
+The valid state transitions (@pxref{fig:fips-fsm}) are:
+@table @code
+@item 1
+Power-Off to Power-On is implicitly done by the OS loading Libgcrypt as
+a shared library and having it linked to an application.
+
+@item 2
+Power-On to Init is triggered by the application calling the
+Libgcrypt initialization function @code{gcry_check_version}.
+
+@item 3
+Init to Self-Test is either triggered by a dedicated API call or implicit
+by invoking a libgrypt service controlled by the FSM.
+
+@item 4
+Self-Test to Operational is triggered after all self-tests passed
+successfully.
+
+@item 5
+Operational to Shutdown is an artificial state without any direct action
+in Libgcrypt. When reaching the Shutdown state the library is
+deinitialized and can't return to any other state again.
+
+@item 6
+Shutdown to Power-off is the process of removing Libgcrypt from the
+computer's memory. For obvious reasons the Power-Off state can't be
+represented within Libgcrypt and thus this transition is for
+documentation only.
+
+@item 7
+Operational to Error is triggered if Libgcrypt detected an application
+error which can't be returned to the caller but still allows Libgcrypt
+to properly run. In the Error state all FIPS relevant interfaces return
+an error code.
+
+@item 8
+Error to Shutdown is similar to the Operational to Shutdown transition
+(5).
+
+@item 9
+Error to Fatal-Error is triggered if Libgrypt detects an fatal error
+while already being in Error state.
+
+@item 10
+Fatal-Error to Shutdown is automatically entered by Libgcrypt
+after having reported the error.
+
+@item 11
+Power-On to Shutdown is an artificial state to document that Libgcrypt
+has not ye been initialized but the process is about to terminate.
+
+@item 12
+Power-On to Fatal-Error will be triggered if certain Libgcrypt functions
+are used without having reached the Init state.
+
+@item 13
+Self-Test to Fatal-Error is triggered by severe errors in Libgcrypt while
+running self-tests.
+
+@item 14
+Self-Test to Error is triggered by a failed self-test.
+
+@item 15
+Operational to Fatal-Error is triggered if Libcrypt encountered a
+non-recoverable error.
+
+@item 16
+Operational to Self-Test is triggered if the application requested to run
+the self-tests again.
+
+@item 17
+Error to Self-Test is triggered if the application has requested to run
+self-tests to get to get back into operational state after an error.
+
+@item 18
+Init to Error is triggered by errors in the initialization code.
+
+@item 19
+Init to Fatal-Error is triggered by non-recoverable errors in the
+initialization code.
+
+@item 20
+Error to Error is triggered by errors while already in the Error
+state.
+
+
+@end table
+@end float
+
+@c ********************************************
+@section FIPS Miscellaneous Information
+
+Libgcrypt does not do any key management on itself; the application
+needs to care about it. Keys which are passed to Libgcrypt should be
+allocated in secure memory as available with the functions
+@code{gcry_malloc_secure} and @code{gcry_calloc_secure}. By calling
+@code{gcry_free} on this memory, the memory and thus the keys are
+overwritten with zero bytes before releasing the memory.
+
+For use with the random number generator, Libgcrypt generates 3
+internal keys which are stored in the encryption contexts used by the
+RNG. These keys are stored in secure memory for the lifetime of the
+process. Application are required to use @code{GCRYCTL_TERM_SECMEM}
+before process termination. This will zero out the entire secure
+memory and thus also the encryption contexts with these keys.
+
+
+
+@c **********************************************************
+@c ************* Appendices (license etc.) ****************
+@c **********************************************************
+@include lgpl.texi
+
+@include gpl.texi
+
+@node Figures and Tables
+@unnumbered List of Figures and Tables
+
+@listoffloats Figure
+
+@listoffloats Table
+
+@node Concept Index
+@unnumbered Concept Index
+
+@printindex cp
+
+@node Function and Data Index
+@unnumbered Function and Data Index
+
+@printindex fn
+
+
+
+@bye
+
+GCRYCTL_SET_RANDOM_DAEMON_SOCKET
+GCRYCTL_USE_RANDOM_DAEMON
+The random daemon is still a bit experimental, thus we do not document
+them. Note that they should be used during initialization and that
+these functions are not really thread safe.
+
+
+
+
+@c LocalWords: int HD
diff --git a/comm/third_party/libgcrypt/doc/gpl.texi b/comm/third_party/libgcrypt/doc/gpl.texi
new file mode 100644
index 0000000000..6eb301e2b2
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/gpl.texi
@@ -0,0 +1,392 @@
+@node Copying
+@unnumbered GNU General Public License
+
+@cindex GPL, GNU General Public License
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@heading Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software---to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+@iftex
+@heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate
+@item
+This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The ``Program'', below,
+refers to any such program or work, and a ``work based on the Program''
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term ``modification''.) Each licensee is addressed as ``you''.
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+@item
+You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+@item
+You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+@item
+If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+@end enumerate
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+@enumerate a
+@item
+Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
+
+@item
+Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+@item
+Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+@end enumerate
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+@item
+Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+@item
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+@item
+If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+@item
+The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and ``any
+later version'', you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+@item
+If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+@center NO WARRANTY
+
+@item
+BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+@item
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+@end enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@heading How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the ``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the program's name and an idea of what it does.}
+Copyright (C) 19@var{yy} @var{name of author}
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program 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 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.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+@smallexample
+Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'. This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c'
+for details.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{show c}; they could even be mouse-clicks or menu items---whatever
+suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the program, if
+necessary. Here is a sample; alter the names:
+
+@smallexample
+@group
+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written
+by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end group
+@end smallexample
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/comm/third_party/libgcrypt/doc/lgpl.texi b/comm/third_party/libgcrypt/doc/lgpl.texi
new file mode 100644
index 0000000000..bbd18a006f
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/lgpl.texi
@@ -0,0 +1,560 @@
+@node Library Copying
+@unnumbered GNU Lesser General Public License
+
+@cindex LGPL, GNU Lesser General Public License
+@center Version 2.1, February 1999
+
+@display
+Copyright @copyright{} 1991, 1999 Free Software Foundation, Inc.
+59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+as the successor of the GNU Library Public License, version 2, hence the
+version number 2.1.]
+@end display
+
+@heading Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software---to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software---typically libraries---of the Free
+Software Foundation and other authors who decide to use it. You can use
+it too, but we suggest you first think carefully about whether this
+license or the ordinary General Public License is the better strategy to
+use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of it
+in new free programs; and that you are informed that you can do these
+things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the @dfn{Lesser} General Public License because it
+does @emph{Less} to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+``work based on the library'' and a ``work that uses the library''. The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+@iftex
+@heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center GNU LESSER GENERAL PUBLIC LICENSE
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate 0
+@item
+This License Agreement applies to any software library or other program
+which contains a notice placed by the copyright holder or other
+authorized party saying it may be distributed under the terms of this
+Lesser General Public License (also called ``this License''). Each
+licensee is addressed as ``you''.
+
+ A ``library'' means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The ``Library'', below, refers to any such software library or work
+which has been distributed under these terms. A ``work based on the
+Library'' means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term ``modification''.)
+
+ ``Source code'' for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+@item
+You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+@item
+You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate a
+@item
+The modified work must itself be a software library.
+
+@item
+You must cause the files modified to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause the whole of the work to be licensed at no
+charge to all third parties under the terms of this License.
+
+@item
+If a facility in the modified Library refers to a function or a
+table of data to be supplied by an application program that uses
+the facility, other than as an argument passed when the facility
+is invoked, then you must make a good faith effort to ensure that,
+in the event an application does not supply such function or
+table, the facility still operates, and performs whatever part of
+its purpose remains meaningful.
+
+(For example, a function in a library to compute square roots has
+a purpose that is entirely well-defined independent of the
+application. Therefore, Subsection 2d requires that any
+application-supplied function or table used by this function must
+be optional: if the application does not supply it, the square
+root function must still compute square roots.)
+@end enumerate
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+@item
+You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a ``work that uses the Library''. Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a ``work that uses the Library'' with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a ``work that uses the
+library''. The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a ``work that uses the Library'' uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+@item
+As an exception to the Sections above, you may also combine or
+link a ``work that uses the Library'' with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+@enumerate a
+@item
+Accompany the work with the complete corresponding
+machine-readable source code for the Library including whatever
+changes were used in the work (which must be distributed under
+Sections 1 and 2 above); and, if the work is an executable linked
+with the Library, with the complete machine-readable ``work that
+uses the Library'', as object code and/or source code, so that the
+user can modify the Library and then relink to produce a modified
+executable containing the modified Library. (It is understood
+that the user who changes the contents of definitions files in the
+Library will not necessarily be able to recompile the application
+to use the modified definitions.)
+
+@item
+Use a suitable shared library mechanism for linking with the Library. A
+suitable mechanism is one that (1) uses at run time a copy of the
+library already present on the user's computer system, rather than
+copying library functions into the executable, and (2) will operate
+properly with a modified version of the library, if the user installs
+one, as long as the modified version is interface-compatible with the
+version that the work was made with.
+
+@item
+Accompany the work with a written offer, valid for at
+least three years, to give the same user the materials
+specified in Subsection 6a, above, for a charge no more
+than the cost of performing this distribution.
+
+@item
+If distribution of the work is made by offering access to copy
+from a designated place, offer equivalent access to copy the above
+specified materials from the same place.
+
+@item
+Verify that the user has already received a copy of these
+materials or that you have already sent this user a copy.
+@end enumerate
+
+ For an executable, the required form of the ``work that uses the
+Library'' must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies the
+executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+@item
+You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+@enumerate a
+@item
+Accompany the combined library with a copy of the same work
+based on the Library, uncombined with any other library
+facilities. This must be distributed under the terms of the
+Sections above.
+
+@item
+Give prominent notice with the combined library of the fact
+that part of it is a work based on the Library, and explaining
+where to find the accompanying uncombined form of the same work.
+@end enumerate
+
+@item
+You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+@item
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+@item
+Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+@item
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+@item
+If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+@item
+The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+``any later version'', you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+@item
+If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+@center NO WARRANTY
+
+@item
+BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+@item
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+@end enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@heading How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the library's name and an idea of what it does.}
+Copyright (C) @var{year} @var{name of author}
+
+This library 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.
+
+This library 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 library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+USA.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the library, if
+necessary. Here is a sample; alter the names:
+
+@smallexample
+Yoyodyne, Inc., hereby disclaims all copyright interest in the library
+`Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+@var{signature of Ty Coon}, 1 April 1990
+Ty Coon, President of Vice
+@end smallexample
+
+That's all there is to it!
diff --git a/comm/third_party/libgcrypt/doc/libgcrypt-modules.eps b/comm/third_party/libgcrypt/doc/libgcrypt-modules.eps
new file mode 100644
index 0000000000..d015cb6b5f
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/libgcrypt-modules.eps
@@ -0,0 +1,322 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Title: /home/wk/s/libgcrypt/doc/libgcrypt-modules.fig
+%%Creator: fig2dev Version 3.2.7a
+%%CreationDate: 2021-02-17 09:16:49
+%%BoundingBox: 0 0 488 300
+%%Magnification: 1.0000
+%%EndComments
+%%BeginProlog
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col32 {0.557 0.557 0.557 srgb} bind def
+/col33 {0.255 0.271 0.255 srgb} bind def
+/col34 {0.753 0.753 0.753 srgb} bind def
+/col35 {0.502 0.502 0.502 srgb} bind def
+/col36 {0.388 0.388 0.388 srgb} bind def
+/col37 {0.804 0.804 0.804 srgb} bind def
+/col38 {0.424 0.424 0.424 srgb} bind def
+/col39 {0.776 0.718 0.592 srgb} bind def
+/col40 {0.937 0.973 1.000 srgb} bind def
+/col41 {0.863 0.796 0.651 srgb} bind def
+/col42 {0.251 0.251 0.251 srgb} bind def
+/col43 {0.878 0.878 0.878 srgb} bind def
+/col44 {0.557 0.561 0.557 srgb} bind def
+/col45 {0.667 0.667 0.667 srgb} bind def
+/col46 {0.333 0.333 0.333 srgb} bind def
+/col47 {0.843 0.843 0.843 srgb} bind def
+/col48 {0.682 0.682 0.682 srgb} bind def
+/col49 {0.745 0.745 0.745 srgb} bind def
+/col50 {0.318 0.318 0.318 srgb} bind def
+/col51 {0.906 0.890 0.906 srgb} bind def
+/col52 {0.000 0.000 0.286 srgb} bind def
+/col53 {0.475 0.475 0.475 srgb} bind def
+/col54 {0.188 0.204 0.188 srgb} bind def
+/col55 {0.255 0.255 0.255 srgb} bind def
+/col56 {0.780 0.714 0.588 srgb} bind def
+/col57 {0.867 0.616 0.576 srgb} bind def
+/col58 {0.945 0.925 0.878 srgb} bind def
+/col59 {0.765 0.765 0.765 srgb} bind def
+/col60 {0.886 0.784 0.659 srgb} bind def
+/col61 {0.882 0.882 0.882 srgb} bind def
+/col62 {0.824 0.824 0.824 srgb} bind def
+/col63 {0.929 0.929 0.929 srgb} bind def
+/col64 {0.855 0.478 0.102 srgb} bind def
+/col65 {0.945 0.894 0.102 srgb} bind def
+/col66 {0.533 0.490 0.761 srgb} bind def
+/col67 {0.839 0.839 0.839 srgb} bind def
+/col68 {0.549 0.549 0.647 srgb} bind def
+/col69 {0.290 0.290 0.290 srgb} bind def
+/col70 {0.549 0.420 0.420 srgb} bind def
+/col71 {0.353 0.353 0.353 srgb} bind def
+/col72 {0.718 0.608 0.451 srgb} bind def
+/col73 {0.255 0.576 1.000 srgb} bind def
+/col74 {0.749 0.439 0.231 srgb} bind def
+/col75 {0.859 0.467 0.000 srgb} bind def
+/col76 {0.855 0.722 0.000 srgb} bind def
+/col77 {0.000 0.392 0.000 srgb} bind def
+/col78 {0.353 0.420 0.231 srgb} bind def
+/col79 {0.827 0.827 0.827 srgb} bind def
+/col80 {0.557 0.557 0.643 srgb} bind def
+/col81 {0.953 0.725 0.365 srgb} bind def
+/col82 {0.537 0.600 0.420 srgb} bind def
+/col83 {0.392 0.392 0.392 srgb} bind def
+/col84 {0.718 0.902 1.000 srgb} bind def
+/col85 {0.525 0.753 0.925 srgb} bind def
+/col86 {0.741 0.741 0.741 srgb} bind def
+/col87 {0.827 0.584 0.322 srgb} bind def
+/col88 {0.596 0.824 0.996 srgb} bind def
+/col89 {0.549 0.612 0.420 srgb} bind def
+/col90 {0.969 0.420 0.000 srgb} bind def
+/col91 {0.353 0.420 0.224 srgb} bind def
+/col92 {0.549 0.612 0.420 srgb} bind def
+/col93 {0.549 0.612 0.482 srgb} bind def
+/col94 {0.094 0.290 0.094 srgb} bind def
+/col95 {0.678 0.678 0.678 srgb} bind def
+/col96 {0.969 0.741 0.353 srgb} bind def
+/col97 {0.388 0.420 0.612 srgb} bind def
+/col98 {0.969 0.969 0.969 srgb} bind def
+/col99 {0.871 0.000 0.000 srgb} bind def
+/col100 {0.678 0.678 0.678 srgb} bind def
+/col101 {0.969 0.741 0.353 srgb} bind def
+/col102 {0.678 0.678 0.678 srgb} bind def
+/col103 {0.969 0.741 0.353 srgb} bind def
+/col104 {0.388 0.420 0.612 srgb} bind def
+/col105 {0.322 0.420 0.161 srgb} bind def
+/col106 {0.580 0.580 0.580 srgb} bind def
+/col107 {0.000 0.388 0.000 srgb} bind def
+/col108 {0.000 0.388 0.290 srgb} bind def
+/col109 {0.482 0.518 0.290 srgb} bind def
+/col110 {0.906 0.741 0.482 srgb} bind def
+/col111 {0.647 0.710 0.776 srgb} bind def
+/col112 {0.420 0.420 0.580 srgb} bind def
+/col113 {0.518 0.420 0.420 srgb} bind def
+/col114 {0.322 0.612 0.290 srgb} bind def
+/col115 {0.839 0.906 0.906 srgb} bind def
+/col116 {0.322 0.388 0.388 srgb} bind def
+/col117 {0.094 0.420 0.290 srgb} bind def
+/col118 {0.612 0.647 0.710 srgb} bind def
+/col119 {1.000 0.580 0.000 srgb} bind def
+/col120 {1.000 0.580 0.000 srgb} bind def
+/col121 {0.000 0.388 0.290 srgb} bind def
+/col122 {0.482 0.518 0.290 srgb} bind def
+/col123 {0.388 0.451 0.482 srgb} bind def
+/col124 {0.906 0.741 0.482 srgb} bind def
+/col125 {0.871 0.871 0.871 srgb} bind def
+/col126 {0.953 0.933 0.827 srgb} bind def
+/col127 {0.961 0.682 0.365 srgb} bind def
+/col128 {0.584 0.808 0.600 srgb} bind def
+/col129 {0.710 0.082 0.490 srgb} bind def
+/col130 {0.933 0.933 0.933 srgb} bind def
+/col131 {0.518 0.518 0.518 srgb} bind def
+/col132 {0.482 0.482 0.482 srgb} bind def
+/col133 {0.000 0.353 0.000 srgb} bind def
+/col134 {0.906 0.451 0.451 srgb} bind def
+/col135 {1.000 0.796 0.192 srgb} bind def
+/col136 {0.161 0.475 0.290 srgb} bind def
+/col137 {0.871 0.157 0.129 srgb} bind def
+/col138 {0.129 0.349 0.776 srgb} bind def
+/col139 {0.973 0.973 0.973 srgb} bind def
+/col140 {0.902 0.902 0.902 srgb} bind def
+/col141 {0.129 0.518 0.353 srgb} bind def
+/col142 {0.788 0.788 0.788 srgb} bind def
+/col143 {0.875 0.847 0.875 srgb} bind def
+/col144 {0.969 0.953 0.969 srgb} bind def
+
+end
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/rl {rlineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/reencdict 12 dict def /ReEncode { reencdict begin
+/newcodesandnames exch def /newfontname exch def /basefontname exch def
+/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
+basefontdict { exch dup /FID ne { dup /Encoding eq
+{ exch dup length array copy newfont 3 1 roll put }
+{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
+newfont /FontName newfontname put newcodesandnames aload pop
+128 1 255 { newfont /Encoding get exch /.notdef put } for
+newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
+newfontname newfont definefont pop end } def
+/isovec [
+8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
+8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
+8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
+8#220 /dotlessi 8#230 /oe 8#231 /OE
+8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
+8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
+8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
+8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
+8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
+8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
+8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
+8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
+8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
+8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
+8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
+8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
+8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
+8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
+8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
+8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
+8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
+8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
+8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
+8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
+8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
+8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
+/Helvetica /Helvetica-iso isovec ReEncode
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+/pageheader {
+sa
+n 0 300 m 0 0 l 488 0 l 488 300 l cp clip
+-32.6 348.9 tr
+1 -1 sc
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+% Polyline
+0 slj
+0 slc
+15.000 slw
+n 645 810 m 540 810 540 2055 105 arcto 4 {pop} repeat
+ 540 2160 2685 2160 105 arcto 4 {pop} repeat
+ 2790 2160 2790 915 105 arcto 4 {pop} repeat
+ 2790 810 645 810 105 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 645 2790 m 540 2790 540 4035 105 arcto 4 {pop} repeat
+ 540 4140 2685 4140 105 arcto 4 {pop} repeat
+ 2790 4140 2790 2895 105 arcto 4 {pop} repeat
+ 2790 2790 645 2790 105 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 3345 2790 m 3240 2790 3240 4035 105 arcto 4 {pop} repeat
+ 3240 4140 5385 4140 105 arcto 4 {pop} repeat
+ 5490 4140 5490 2895 105 arcto 4 {pop} repeat
+ 5490 2790 3345 2790 105 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 6075 2805 m 5970 2805 5970 4050 105 arcto 4 {pop} repeat
+ 5970 4155 8115 4155 105 arcto 4 {pop} repeat
+ 8220 4155 8220 2910 105 arcto 4 {pop} repeat
+ 8220 2805 6075 2805 105 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 3345 810 m 3240 810 3240 2055 105 arcto 4 {pop} repeat
+ 3240 2160 5385 2160 105 arcto 4 {pop} repeat
+ 5490 2160 5490 915 105 arcto 4 {pop} repeat
+ 5490 810 3345 810 105 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 6090 810 m 5985 810 5985 2055 105 arcto 4 {pop} repeat
+ 5985 2160 8130 2160 105 arcto 4 {pop} repeat
+ 8235 2160 8235 915 105 arcto 4 {pop} repeat
+ 8235 810 6090 810 105 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 3513 4563 m 3438 4563 3438 5438 75 arcto 4 {pop} repeat
+ 3438 5513 4947 5513 75 arcto 4 {pop} repeat
+ 5022 5513 5022 4638 75 arcto 4 {pop} repeat
+ 5022 4563 3513 4563 75 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 5583 4563 m 5508 4563 5508 5438 75 arcto 4 {pop} repeat
+ 5508 5513 7017 5513 75 arcto 4 {pop} repeat
+ 7092 5513 7092 4638 75 arcto 4 {pop} repeat
+ 7092 4563 5583 4563 75 arcto 4 {pop} repeat
+ cp gs col0 s gr % Polyline
+n 1443 4567 m 1368 4567 1368 5442 75 arcto 4 {pop} repeat
+ 1368 5517 2877 5517 75 arcto 4 {pop} repeat
+ 2952 5517 2952 4642 75 arcto 4 {pop} repeat
+ 2952 4567 1443 4567 75 arcto 4 {pop} repeat
+ cp gs col0 s gr /Helvetica-iso ff 300.00 scf sf
+900 1440 m
+gs 1 -1 sc (Public-Key) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+900 1815 m
+gs 1 -1 sc (Encryption) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+630 3420 m
+gs 1 -1 sc (Multi-Precision-) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+900 3795 m
+gs 1 -1 sc (Integers) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3420 3420 m
+gs 1 -1 sc (Prime-Number) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3420 3795 m
+gs 1 -1 sc (Generator) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6420 3435 m
+gs 1 -1 sc (Random) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6420 3810 m
+gs 1 -1 sc (Numbers) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3600 1440 m
+gs 1 -1 sc (Symmetric) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3600 1815 m
+gs 1 -1 sc (Encryption) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6435 1440 m
+gs 1 -1 sc (Hashing) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6435 1815 m
+gs 1 -1 sc (MACing) col0 sh gr
+/Helvetica-iso ff 210.00 scf sf
+3825 5130 m
+gs 1 -1 sc (Memory) col0 sh gr
+/Helvetica-iso ff 210.00 scf sf
+5635 5133 m
+gs 1 -1 sc (Miscelleanous) col0 sh gr
+/Helvetica-iso ff 210.00 scf sf
+1495 5137 m
+gs 1 -1 sc (S-expressions) col0 sh gr
+% here ends figure;
+pagefooter
+showpage
+%%Trailer
+%EOF
diff --git a/comm/third_party/libgcrypt/doc/libgcrypt-modules.fig b/comm/third_party/libgcrypt/doc/libgcrypt-modules.fig
new file mode 100644
index 0000000000..ea3d05372a
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/libgcrypt-modules.fig
@@ -0,0 +1,193 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+0 32 #8e8e8e
+0 33 #414541
+0 34 #c0c0c0
+0 35 #808080
+0 36 #636363
+0 37 #cdcdcd
+0 38 #6c6c6c
+0 39 #c6b797
+0 40 #eff8ff
+0 41 #dccba6
+0 42 #404040
+0 43 #e0e0e0
+0 44 #8e8f8e
+0 45 #aaaaaa
+0 46 #555555
+0 47 #d7d7d7
+0 48 #aeaeae
+0 49 #bebebe
+0 50 #515151
+0 51 #e7e3e7
+0 52 #000049
+0 53 #797979
+0 54 #303430
+0 55 #414141
+0 56 #c7b696
+0 57 #dd9d93
+0 58 #f1ece0
+0 59 #c3c3c3
+0 60 #e2c8a8
+0 61 #e1e1e1
+0 62 #d2d2d2
+0 63 #ededed
+0 64 #da7a1a
+0 65 #f1e41a
+0 66 #887dc2
+0 67 #d6d6d6
+0 68 #8c8ca5
+0 69 #4a4a4a
+0 70 #8c6b6b
+0 71 #5a5a5a
+0 72 #b79b73
+0 73 #4193ff
+0 74 #bf703b
+0 75 #db7700
+0 76 #dab800
+0 77 #006400
+0 78 #5a6b3b
+0 79 #d3d3d3
+0 80 #8e8ea4
+0 81 #f3b95d
+0 82 #89996b
+0 83 #646464
+0 84 #b7e6ff
+0 85 #86c0ec
+0 86 #bdbdbd
+0 87 #d39552
+0 88 #98d2fe
+0 89 #8c9c6b
+0 90 #f76b00
+0 91 #5a6b39
+0 92 #8c9c6b
+0 93 #8c9c7b
+0 94 #184a18
+0 95 #adadad
+0 96 #f7bd5a
+0 97 #636b9c
+0 98 #f7f7f7
+0 99 #de0000
+0 100 #adadad
+0 101 #f7bd5a
+0 102 #adadad
+0 103 #f7bd5a
+0 104 #636b9c
+0 105 #526b29
+0 106 #949494
+0 107 #006300
+0 108 #00634a
+0 109 #7b844a
+0 110 #e7bd7b
+0 111 #a5b5c6
+0 112 #6b6b94
+0 113 #846b6b
+0 114 #529c4a
+0 115 #d6e7e7
+0 116 #526363
+0 117 #186b4a
+0 118 #9ca5b5
+0 119 #ff9400
+0 120 #ff9400
+0 121 #00634a
+0 122 #7b844a
+0 123 #63737b
+0 124 #e7bd7b
+0 125 #dedede
+0 126 #f3eed3
+0 127 #f5ae5d
+0 128 #95ce99
+0 129 #b5157d
+0 130 #eeeeee
+0 131 #848484
+0 132 #7b7b7b
+0 133 #005a00
+0 134 #e77373
+0 135 #ffcb31
+0 136 #29794a
+0 137 #de2821
+0 138 #2159c6
+0 139 #f8f8f8
+0 140 #e6e6e6
+0 141 #21845a
+0 142 #c9c9c9
+0 143 #dfd8df
+0 144 #f7f3f7
+6 450 720 8325 5580
+6 450 720 8325 4275
+6 450 720 2880 2250
+6 900 1170 2340 1890
+4 0 0 50 -1 16 20 0.0000 4 300 1410 900 1440 Public-Key\001
+4 0 0 50 -1 16 20 0.0000 4 300 1410 900 1815 Encryption\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2790 2160 2790 810 540 810 540 2160 2790 2160
+-6
+6 525 2775 2805 4155
+6 630 3150 2700 3870
+6 630 3150 2700 3870
+4 0 0 50 -1 16 20 0.0000 4 225 2055 630 3420 Multi-Precision-\001
+4 0 0 50 -1 16 20 0.0000 4 300 1095 900 3795 Integers\001
+-6
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2790 4140 2790 2790 540 2790 540 4140 2790 4140
+-6
+6 3150 2700 5580 4230
+6 3420 3150 5400 3870
+4 0 0 50 -1 16 20 0.0000 4 225 1965 3420 3420 Prime-Number\001
+4 0 0 50 -1 16 20 0.0000 4 225 1365 3420 3795 Generator\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5490 4140 5490 2790 3240 2790 3240 4140 5490 4140
+-6
+6 5880 2715 8310 4245
+6 6420 3165 7680 3885
+4 0 0 50 -1 16 20 0.0000 4 225 1140 6420 3435 Random\001
+4 0 0 50 -1 16 20 0.0000 4 225 1230 6420 3810 Numbers\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 8220 4155 8220 2805 5970 2805 5970 4155 8220 4155
+-6
+6 3150 720 5580 2250
+6 3600 1170 5040 1890
+4 0 0 50 -1 16 20 0.0000 4 300 1425 3600 1440 Symmetric\001
+4 0 0 50 -1 16 20 0.0000 4 300 1410 3600 1815 Encryption\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5490 2160 5490 810 3240 810 3240 2160 5490 2160
+-6
+6 5940 765 8280 2205
+6 6435 1215 7530 1890
+4 0 0 50 -1 16 20 0.0000 4 300 1095 6435 1440 Hashing\001
+4 0 0 50 -1 16 20 0.0000 4 300 1065 6435 1815 MACing\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 8235 2160 8235 810 5985 810 5985 2160 8235 2160
+-6
+-6
+6 1305 4500 7155 5580
+6 3375 4500 5085 5580
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 5 0 0 5
+ 5022 5513 5022 4563 3438 4563 3438 5513 5022 5513
+4 0 0 50 -1 16 14 0.0000 4 195 780 3825 5130 Memory\001
+-6
+6 5445 4500 7155 5576
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 5 0 0 5
+ 7092 5513 7092 4563 5508 4563 5508 5513 7092 5513
+4 0 0 50 -1 16 14 0.0000 4 150 1350 5635 5133 Miscelleanous\001
+-6
+6 1305 4504 3015 5580
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 5 0 0 5
+ 2952 5517 2952 4567 1368 4567 1368 5517 2952 5517
+4 0 0 50 -1 16 14 0.0000 4 195 1350 1495 5137 S-expressions\001
+-6
+-6
+-6
diff --git a/comm/third_party/libgcrypt/doc/libgcrypt-modules.pdf b/comm/third_party/libgcrypt/doc/libgcrypt-modules.pdf
new file mode 100644
index 0000000000..9722b22366
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/libgcrypt-modules.pdf
Binary files differ
diff --git a/comm/third_party/libgcrypt/doc/libgcrypt-modules.png b/comm/third_party/libgcrypt/doc/libgcrypt-modules.png
new file mode 100644
index 0000000000..c84ef1f6a7
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/libgcrypt-modules.png
Binary files differ
diff --git a/comm/third_party/libgcrypt/doc/stamp-vti b/comm/third_party/libgcrypt/doc/stamp-vti
new file mode 100644
index 0000000000..37de05924c
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/stamp-vti
@@ -0,0 +1,4 @@
+@set UPDATED 28 January 2021
+@set UPDATED-MONTH January 2021
+@set EDITION 1.9.2
+@set VERSION 1.9.2
diff --git a/comm/third_party/libgcrypt/doc/version.texi b/comm/third_party/libgcrypt/doc/version.texi
new file mode 100644
index 0000000000..37de05924c
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/version.texi
@@ -0,0 +1,4 @@
+@set UPDATED 28 January 2021
+@set UPDATED-MONTH January 2021
+@set EDITION 1.9.2
+@set VERSION 1.9.2
diff --git a/comm/third_party/libgcrypt/doc/yat2m.c b/comm/third_party/libgcrypt/doc/yat2m.c
new file mode 100644
index 0000000000..3c7b363558
--- /dev/null
+++ b/comm/third_party/libgcrypt/doc/yat2m.c
@@ -0,0 +1,1649 @@
+/* yat2m.c - Yet Another Texi 2 Man converter
+ * Copyright (C) 2005, 2013, 2015, 2016, 2017 g10 Code GmbH
+ * Copyright (C) 2006, 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*
+ This is a simple texinfo to man page converter. It needs some
+ special markup in th e texinfo and tries best to get a create man
+ page. It has been designed for the GnuPG man pages and thus only
+ a few texinfo commands are supported.
+
+ To use this you need to add the following macros into your texinfo
+ source:
+
+ @macro manpage {a}
+ @end macro
+ @macro mansect {a}
+ @end macro
+ @macro manpause
+ @end macro
+ @macro mancont
+ @end macro
+
+ They are used by yat2m to select parts of the Texinfo which should
+ go into the man page. These macros need to be used without leading
+ left space. Processing starts after a "manpage" macro has been
+ seen. "mansect" identifies the section and yat2m make sure to
+ emit the sections in the proper order. Note that @mansect skips
+ the next input line if that line begins with @section, @subsection or
+ @chapheading.
+
+ To insert verbatim troff markup, the following texinfo code may be
+ used:
+
+ @ifset manverb
+ .B whateever you want
+ @end ifset
+
+ alternativly a special comment may be used:
+
+ @c man:.B whatever you want
+
+ This is useful in case you need just one line. If you want to
+ include parts only in the man page but keep the texinfo
+ translation you may use:
+
+ @ifset isman
+ stuff to be rendered only on man pages
+ @end ifset
+
+ or to exclude stuff from man pages:
+
+ @ifclear isman
+ stuff not to be rendered on man pages
+ @end ifclear
+
+ the keyword @section is ignored, however @subsection gets rendered
+ as ".SS". @menu is completely skipped. Several man pages may be
+ extracted from one file, either using the --store or the --select
+ option.
+
+ If you want to indent tables in the source use this style:
+
+ @table foo
+ @item
+ @item
+ @table
+ @item
+ @end
+ @end
+
+ Don't change the indentation within a table and keep the same
+ number of white space at the start of the line. yat2m simply
+ detects the number of white spaces in front of an @item and remove
+ this number of spaces from all following lines until a new @item
+ is found or there are less spaces than for the last @item.
+
+ Note that @* does only work correctly if used at the end of an
+ input line.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <time.h>
+
+
+#if __GNUC__
+# define MY_GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+#else
+# define MY_GCC_VERSION 0
+#endif
+
+#if MY_GCC_VERSION >= 20500
+# define ATTR_PRINTF(f, a) __attribute__ ((format(printf,f,a)))
+# define ATTR_NR_PRINTF(f, a) __attribute__ ((noreturn, format(printf,f,a)))
+#else
+# define ATTR_PRINTF(f, a)
+# define ATTR_NR_PRINTF(f, a)
+#endif
+#if MY_GCC_VERSION >= 30200
+# define ATTR_MALLOC __attribute__ ((__malloc__))
+#else
+# define ATTR_MALLOC
+#endif
+
+
+
+#define PGM "yat2m"
+#ifdef PACKAGE_VERSION
+# define VERSION PACKAGE_VERSION
+#else
+# define VERSION "1.0"
+#endif
+
+/* The maximum length of a line including the linefeed and one extra
+ character. */
+#define LINESIZE 1024
+
+/* Number of allowed condition nestings. */
+#define MAX_CONDITION_NESTING 10
+
+/* Option flags. */
+static int verbose;
+static int quiet;
+static int debug;
+static const char *opt_source;
+static const char *opt_release;
+static const char *opt_date;
+static const char *opt_select;
+static const char *opt_include;
+static int opt_store;
+
+/* Flag to keep track whether any error occurred. */
+static int any_error;
+
+
+/* Object to keep macro definitions. */
+struct macro_s
+{
+ struct macro_s *next;
+ char *value; /* Malloced value. */
+ char name[1];
+};
+typedef struct macro_s *macro_t;
+
+/* List of all defined macros. */
+static macro_t macrolist;
+
+/* List of variables set by @set. */
+static macro_t variablelist;
+
+/* List of global macro names. The value part is not used. */
+static macro_t predefinedmacrolist;
+
+/* Object to keep track of @isset and @ifclear. */
+struct condition_s
+{
+ int manverb; /* "manverb" needs special treatment. */
+ int isset; /* This is an @isset condition. */
+ char name[1]; /* Name of the condition macro. */
+};
+typedef struct condition_s *condition_t;
+
+/* The stack used to evaluate conditions. And the current states. */
+static condition_t condition_stack[MAX_CONDITION_NESTING];
+static int condition_stack_idx;
+static int cond_is_active; /* State of ifset/ifclear */
+static int cond_in_verbatim; /* State of "manverb". */
+
+
+/* Object to store one line of content. */
+struct line_buffer_s
+{
+ struct line_buffer_s *next;
+ int verbatim; /* True if LINE contains verbatim data. The default
+ is Texinfo source. */
+ char *line;
+};
+typedef struct line_buffer_s *line_buffer_t;
+
+
+/* Object to collect the data of a section. */
+struct section_buffer_s
+{
+ char *name; /* Malloced name of the section. This may be
+ NULL to indicate this slot is not used. */
+ line_buffer_t lines; /* Linked list with the lines of the section. */
+ line_buffer_t *lines_tail; /* Helper for faster appending to the
+ linked list. */
+ line_buffer_t last_line; /* Points to the last line appended. */
+};
+typedef struct section_buffer_s *section_buffer_t;
+
+/* Variable to keep info about the current page together. */
+static struct
+{
+ /* Filename of the current page or NULL if no page is active. Malloced. */
+ char *name;
+
+ /* Number of allocated elements in SECTIONS below. */
+ size_t n_sections;
+ /* Array with the data of the sections. */
+ section_buffer_t sections;
+
+} thepage;
+
+
+/* The list of standard section names. COMMANDS and ASSUAN are GnuPG
+ specific. */
+static const char * const standard_sections[] =
+ { "NAME", "SYNOPSIS", "DESCRIPTION",
+ "RETURN VALUE", "EXIT STATUS", "ERROR HANDLING", "ERRORS",
+ "COMMANDS", "OPTIONS", "USAGE", "EXAMPLES", "FILES",
+ "ENVIRONMENT", "DIAGNOSTICS", "SECURITY", "CONFORMING TO",
+ "ASSUAN", "NOTES", "BUGS", "AUTHOR", "SEE ALSO", NULL };
+
+
+/*-- Local prototypes. --*/
+static void proc_texi_buffer (FILE *fp, const char *line, size_t len,
+ int *table_level, int *eol_action);
+
+static void die (const char *format, ...) ATTR_NR_PRINTF(1,2);
+static void err (const char *format, ...) ATTR_PRINTF(1,2);
+static void inf (const char *format, ...) ATTR_PRINTF(1,2);
+static void *xmalloc (size_t n) ATTR_MALLOC;
+static void *xcalloc (size_t n, size_t m) ATTR_MALLOC;
+
+
+
+/*-- Functions --*/
+
+/* Print diagnostic message and exit with failure. */
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fflush (stdout);
+ fprintf (stderr, "%s: ", PGM);
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ putc ('\n', stderr);
+
+ exit (1);
+}
+
+
+/* Print diagnostic message. */
+static void
+err (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fflush (stdout);
+ if (strncmp (format, "%s:%d:", 6))
+ fprintf (stderr, "%s: ", PGM);
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ putc ('\n', stderr);
+ any_error = 1;
+}
+
+/* Print diagnostic message. */
+static void
+inf (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fflush (stdout);
+ fprintf (stderr, "%s: ", PGM);
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ putc ('\n', stderr);
+}
+
+
+static void *
+xmalloc (size_t n)
+{
+ void *p = malloc (n);
+ if (!p)
+ die ("out of core: %s", strerror (errno));
+ return p;
+}
+
+static void *
+xcalloc (size_t n, size_t m)
+{
+ void *p = calloc (n, m);
+ if (!p)
+ die ("out of core: %s", strerror (errno));
+ return p;
+}
+
+static void *
+xrealloc (void *old, size_t n)
+{
+ void *p = realloc (old, n);
+ if (!p)
+ die ("out of core: %s", strerror (errno));
+ return p;
+}
+
+static char *
+xstrdup (const char *string)
+{
+ void *p = malloc (strlen (string)+1);
+ if (!p)
+ die ("out of core: %s", strerror (errno));
+ strcpy (p, string);
+ return p;
+}
+
+
+/* Uppercase the ascii characters in STRING. */
+static char *
+ascii_strupr (char *string)
+{
+ char *p;
+
+ for (p = string; *p; p++)
+ if (!(*p & 0x80))
+ *p = toupper (*p);
+ return string;
+}
+
+
+/* Return the current date as an ISO string. */
+const char *
+isodatestring (void)
+{
+ static char buffer[36];
+ struct tm *tp;
+ time_t atime;
+
+ if (opt_date && *opt_date)
+ atime = strtoul (opt_date, NULL, 10);
+ else
+ atime = time (NULL);
+ if (atime < 0)
+ strcpy (buffer, "????" "-??" "-??");
+ else
+ {
+ tp = gmtime (&atime);
+ sprintf (buffer,"%04d-%02d-%02d",
+ 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
+ }
+ return buffer;
+}
+
+
+/* Add NAME to the list of predefined macros which are global for all
+ files. */
+static void
+add_predefined_macro (const char *name)
+{
+ macro_t m;
+
+ for (m=predefinedmacrolist; m; m = m->next)
+ if (!strcmp (m->name, name))
+ break;
+ if (!m)
+ {
+ m = xcalloc (1, sizeof *m + strlen (name));
+ strcpy (m->name, name);
+ m->next = predefinedmacrolist;
+ predefinedmacrolist = m;
+ }
+}
+
+
+/* Create or update a macro with name MACRONAME and set its values TO
+ MACROVALUE. Note that ownership of the macro value is transferred
+ to this function. */
+static void
+set_macro (const char *macroname, char *macrovalue)
+{
+ macro_t m;
+
+ for (m=macrolist; m; m = m->next)
+ if (!strcmp (m->name, macroname))
+ break;
+ if (m)
+ free (m->value);
+ else
+ {
+ m = xcalloc (1, sizeof *m + strlen (macroname));
+ strcpy (m->name, macroname);
+ m->next = macrolist;
+ macrolist = m;
+ }
+ m->value = macrovalue;
+ macrovalue = NULL;
+}
+
+
+/* Create or update a variable with name and value given in NAMEANDVALUE. */
+static void
+set_variable (char *nameandvalue)
+{
+ macro_t m;
+ const char *value;
+ char *p;
+
+ for (p = nameandvalue; *p && *p != ' ' && *p != '\t'; p++)
+ ;
+ if (!*p)
+ value = "";
+ else
+ {
+ *p++ = 0;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ value = p;
+ }
+
+ for (m=variablelist; m; m = m->next)
+ if (!strcmp (m->name, nameandvalue))
+ break;
+ if (m)
+ free (m->value);
+ else
+ {
+ m = xcalloc (1, sizeof *m + strlen (nameandvalue));
+ strcpy (m->name, nameandvalue);
+ m->next = variablelist;
+ variablelist = m;
+ }
+ m->value = xstrdup (value);
+}
+
+
+/* Return true if the macro or variable NAME is set, i.e. not the
+ empty string and not evaluating to 0. */
+static int
+macro_set_p (const char *name)
+{
+ macro_t m;
+
+ for (m = macrolist; m ; m = m->next)
+ if (!strcmp (m->name, name))
+ break;
+ if (!m)
+ for (m = variablelist; m ; m = m->next)
+ if (!strcmp (m->name, name))
+ break;
+ if (!m || !m->value || !*m->value)
+ return 0;
+ if ((*m->value & 0x80) || !isdigit (*m->value))
+ return 1; /* Not a digit but some other string. */
+ return !!atoi (m->value);
+}
+
+
+/* Evaluate the current conditions. */
+static void
+evaluate_conditions (const char *fname, int lnr)
+{
+ int i;
+
+ (void)fname;
+ (void)lnr;
+
+ /* for (i=0; i < condition_stack_idx; i++) */
+ /* inf ("%s:%d: stack[%d] %s %s %c", */
+ /* fname, lnr, i, condition_stack[i]->isset? "set":"clr", */
+ /* condition_stack[i]->name, */
+ /* (macro_set_p (condition_stack[i]->name) */
+ /* ^ !condition_stack[i]->isset)? 't':'f'); */
+
+ cond_is_active = 1;
+ cond_in_verbatim = 0;
+ if (condition_stack_idx)
+ {
+ for (i=0; i < condition_stack_idx; i++)
+ {
+ if (condition_stack[i]->manverb)
+ cond_in_verbatim = (macro_set_p (condition_stack[i]->name)
+ ^ !condition_stack[i]->isset);
+ else if (!(macro_set_p (condition_stack[i]->name)
+ ^ !condition_stack[i]->isset))
+ {
+ cond_is_active = 0;
+ break;
+ }
+ }
+ }
+
+ /* inf ("%s:%d: active=%d verbatim=%d", */
+ /* fname, lnr, cond_is_active, cond_in_verbatim); */
+}
+
+
+/* Push a condition with condition macro NAME onto the stack. If
+ ISSET is true, a @isset condition is pushed. */
+static void
+push_condition (const char *name, int isset, const char *fname, int lnr)
+{
+ condition_t cond;
+ int manverb = 0;
+
+ if (condition_stack_idx >= MAX_CONDITION_NESTING)
+ {
+ err ("%s:%d: condition nested too deep", fname, lnr);
+ return;
+ }
+
+ if (!strcmp (name, "manverb"))
+ {
+ if (!isset)
+ {
+ err ("%s:%d: using \"@ifclear manverb\" is not allowed", fname, lnr);
+ return;
+ }
+ manverb = 1;
+ }
+
+ cond = xcalloc (1, sizeof *cond + strlen (name));
+ cond->manverb = manverb;
+ cond->isset = isset;
+ strcpy (cond->name, name);
+
+ condition_stack[condition_stack_idx++] = cond;
+ evaluate_conditions (fname, lnr);
+}
+
+
+/* Remove the last condition from the stack. ISSET is used for error
+ reporting. */
+static void
+pop_condition (int isset, const char *fname, int lnr)
+{
+ if (!condition_stack_idx)
+ {
+ err ("%s:%d: unbalanced \"@end %s\"",
+ fname, lnr, isset?"isset":"isclear");
+ return;
+ }
+ condition_stack_idx--;
+ free (condition_stack[condition_stack_idx]);
+ condition_stack[condition_stack_idx] = NULL;
+ evaluate_conditions (fname, lnr);
+}
+
+
+
+/* Return a section buffer for the section NAME. Allocate a new buffer
+ if this is a new section. Keep track of the sections in THEPAGE.
+ This function may reallocate the section array in THEPAGE. */
+static section_buffer_t
+get_section_buffer (const char *name)
+{
+ int i;
+ section_buffer_t sect;
+
+ /* If there is no section we put everything into the required NAME
+ section. Given that this is the first one listed it is likely
+ that error are easily visible. */
+ if (!name)
+ name = "NAME";
+
+ for (i=0; i < thepage.n_sections; i++)
+ {
+ sect = thepage.sections + i;
+ if (sect->name && !strcmp (name, sect->name))
+ return sect;
+ }
+ for (i=0; i < thepage.n_sections; i++)
+ if (!thepage.sections[i].name)
+ break;
+ if (thepage.n_sections && i < thepage.n_sections)
+ sect = thepage.sections + i;
+ else
+ {
+ /* We need to allocate or reallocate the section array. */
+ size_t old_n = thepage.n_sections;
+ size_t new_n = 20;
+
+ if (!old_n)
+ thepage.sections = xcalloc (new_n, sizeof *thepage.sections);
+ else
+ {
+ thepage.sections = xrealloc (thepage.sections,
+ ((old_n + new_n)
+ * sizeof *thepage.sections));
+ memset (thepage.sections + old_n, 0,
+ new_n * sizeof *thepage.sections);
+ }
+ thepage.n_sections += new_n;
+
+ /* Setup the tail pointers. */
+ for (i=old_n; i < thepage.n_sections; i++)
+ {
+ sect = thepage.sections + i;
+ sect->lines_tail = &sect->lines;
+ }
+ sect = thepage.sections + old_n;
+ }
+
+ /* Store the name. */
+ assert (!sect->name);
+ sect->name = xstrdup (name);
+ return sect;
+}
+
+
+
+/* Add the content of LINE to the section named SECTNAME. */
+static void
+add_content (const char *sectname, char *line, int verbatim)
+{
+ section_buffer_t sect;
+ line_buffer_t lb;
+
+ sect = get_section_buffer (sectname);
+ if (sect->last_line && !sect->last_line->verbatim == !verbatim)
+ {
+ /* Lets append that line to the last one. We do this to keep
+ all lines of the same kind (i.e.verbatim or not) together in
+ one large buffer. */
+ size_t n1, n;
+
+ lb = sect->last_line;
+ n1 = strlen (lb->line);
+ n = n1 + 1 + strlen (line) + 1;
+ lb->line = xrealloc (lb->line, n);
+ strcpy (lb->line+n1, "\n");
+ strcpy (lb->line+n1+1, line);
+ }
+ else
+ {
+ lb = xcalloc (1, sizeof *lb);
+ lb->verbatim = verbatim;
+ lb->line = xstrdup (line);
+ sect->last_line = lb;
+ *sect->lines_tail = lb;
+ sect->lines_tail = &lb->next;
+ }
+}
+
+
+/* Prepare for a new man page using the filename NAME. */
+static void
+start_page (char *name)
+{
+ if (verbose)
+ inf ("starting page '%s'", name);
+ assert (!thepage.name);
+ thepage.name = xstrdup (name);
+ thepage.n_sections = 0;
+}
+
+
+/* Write the .TH entry of the current page. Return -1 if there is a
+ problem with the page. */
+static int
+write_th (FILE *fp)
+{
+ char *name, *p;
+
+ fputs (".\\\" Created from Texinfo source by yat2m " VERSION "\n", fp);
+
+ name = ascii_strupr (xstrdup (thepage.name));
+ p = strrchr (name, '.');
+ if (!p || !p[1])
+ {
+ err ("no section name in man page '%s'", thepage.name);
+ free (name);
+ return -1;
+ }
+ *p++ = 0;
+ fprintf (fp, ".TH %s %s %s \"%s\" \"%s\"\n",
+ name, p, isodatestring (), opt_release, opt_source);
+ free (name);
+ return 0;
+}
+
+
+/* Process the texinfo command COMMAND (without the leading @) and
+ write output if needed to FP. REST is the remainer of the line
+ which should either point to an opening brace or to a white space.
+ The function returns the number of characters already processed
+ from REST. LEN is the usable length of REST. TABLE_LEVEL is used to
+ control the indentation of tables. */
+static size_t
+proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len,
+ int *table_level, int *eol_action)
+{
+ static struct {
+ const char *name; /* Name of the command. */
+ int what; /* What to do with this command. */
+ const char *lead_in; /* String to print with a opening brace. */
+ const char *lead_out;/* String to print with the closing brace. */
+ } cmdtbl[] = {
+ { "command", 0, "\\fB", "\\fR" },
+ { "code", 0, "\\fB", "\\fR" },
+ { "url", 0, "\\fB", "\\fR" },
+ { "sc", 0, "\\fB", "\\fR" },
+ { "var", 0, "\\fI", "\\fR" },
+ { "samp", 0, "\\(aq", "\\(aq" },
+ { "file", 0, "\\(oq\\fI","\\fR\\(cq" },
+ { "env", 0, "\\(oq\\fI","\\fR\\(cq" },
+ { "acronym", 0 },
+ { "dfn", 0 },
+ { "option", 0, "\\fB", "\\fR" },
+ { "example", 1, ".RS 2\n.nf\n" },
+ { "smallexample", 1, ".RS 2\n.nf\n" },
+ { "asis", 7 },
+ { "anchor", 7 },
+ { "cartouche", 1 },
+ { "ref", 0, "[", "]" },
+ { "xref", 0, "See: [", "]" },
+ { "pxref", 0, "see: [", "]" },
+ { "uref", 0, "(\\fB", "\\fR)" },
+ { "footnote",0, " ([", "])" },
+ { "emph", 0, "\\fI", "\\fR" },
+ { "w", 1 },
+ { "c", 5 },
+ { "efindex", 1 },
+ { "opindex", 1 },
+ { "cpindex", 1 },
+ { "cindex", 1 },
+ { "noindent", 0 },
+ { "section", 1 },
+ { "chapter", 1 },
+ { "subsection", 6, "\n.SS " },
+ { "chapheading", 0},
+ { "item", 2, ".TP\n.B " },
+ { "itemx", 2, ".TQ\n.B " },
+ { "table", 3 },
+ { "itemize", 3 },
+ { "bullet", 0, "* " },
+ { "*", 0, "\n.br"},
+ { "/", 0 },
+ { "end", 4 },
+ { "quotation",1, ".RS\n\\fB" },
+ { "value", 8 },
+ { NULL }
+ };
+ size_t n;
+ int i;
+ const char *s;
+ const char *lead_out = NULL;
+ int ignore_args = 0;
+
+ for (i=0; cmdtbl[i].name && strcmp (cmdtbl[i].name, command); i++)
+ ;
+ if (cmdtbl[i].name)
+ {
+ s = cmdtbl[i].lead_in;
+ if (s)
+ fputs (s, fp);
+ lead_out = cmdtbl[i].lead_out;
+ switch (cmdtbl[i].what)
+ {
+ case 1: /* Throw away the entire line. */
+ s = memchr (rest, '\n', len);
+ return s? (s-rest)+1 : len;
+ case 2: /* Handle @item. */
+ break;
+ case 3: /* Handle table. */
+ if (++(*table_level) > 1)
+ fputs (".RS\n", fp);
+ /* Now throw away the entire line. */
+ s = memchr (rest, '\n', len);
+ return s? (s-rest)+1 : len;
+ break;
+ case 4: /* Handle end. */
+ for (s=rest, n=len; n && (*s == ' ' || *s == '\t'); s++, n--)
+ ;
+ if (n >= 5 && !memcmp (s, "table", 5)
+ && (!n || s[5] == ' ' || s[5] == '\t' || s[5] == '\n'))
+ {
+ if ((*table_level)-- > 1)
+ fputs (".RE\n", fp);
+ else
+ fputs (".P\n", fp);
+ }
+ else if (n >= 7 && !memcmp (s, "example", 7)
+ && (!n || s[7] == ' ' || s[7] == '\t' || s[7] == '\n'))
+ {
+ fputs (".fi\n.RE\n", fp);
+ }
+ else if (n >= 12 && !memcmp (s, "smallexample", 12)
+ && (!n || s[12] == ' ' || s[12] == '\t' || s[12] == '\n'))
+ {
+ fputs (".fi\n.RE\n", fp);
+ }
+ else if (n >= 9 && !memcmp (s, "quotation", 9)
+ && (!n || s[9] == ' ' || s[9] == '\t' || s[9] == '\n'))
+ {
+ fputs ("\\fR\n.RE\n", fp);
+ }
+ /* Now throw away the entire line. */
+ s = memchr (rest, '\n', len);
+ return s? (s-rest)+1 : len;
+ case 5: /* Handle special comments. */
+ for (s=rest, n=len; n && (*s == ' ' || *s == '\t'); s++, n--)
+ ;
+ if (n >= 4 && !memcmp (s, "man:", 4))
+ {
+ for (s+=4, n-=4; n && *s != '\n'; n--, s++)
+ putc (*s, fp);
+ putc ('\n', fp);
+ }
+ /* Now throw away the entire line. */
+ s = memchr (rest, '\n', len);
+ return s? (s-rest)+1 : len;
+ case 6:
+ *eol_action = 1;
+ break;
+ case 7:
+ ignore_args = 1;
+ break;
+ case 8:
+ ignore_args = 1;
+ if (*rest != '{')
+ {
+ err ("opening brace for command '%s' missing", command);
+ return len;
+ }
+ else
+ {
+ /* Find closing brace. */
+ for (s=rest+1, n=1; *s && n < len; s++, n++)
+ if (*s == '}')
+ break;
+ if (*s != '}')
+ {
+ err ("closing brace for command '%s' not found", command);
+ return len;
+ }
+ else
+ {
+ size_t rlen = s - (rest + 1);
+ macro_t m;
+
+ for (m = variablelist; m; m = m->next)
+ {
+ if (strlen (m->name) == rlen
+ && !strncmp (m->name, rest+1, rlen))
+ break;
+ }
+ if (m)
+ fputs (m->value, fp);
+ else
+ inf ("texinfo variable '%.*s' is not set",
+ (int)rlen, rest+1);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else /* macro */
+ {
+ macro_t m;
+
+ for (m = macrolist; m ; m = m->next)
+ if (!strcmp (m->name, command))
+ break;
+ if (m)
+ {
+ proc_texi_buffer (fp, m->value, strlen (m->value),
+ table_level, eol_action);
+ ignore_args = 1; /* Parameterized macros are not yet supported. */
+ }
+ else
+ inf ("texinfo command '%s' not supported (%.*s)", command,
+ (int)((s = memchr (rest, '\n', len)), (s? (s-rest) : len)), rest);
+ }
+
+ if (*rest == '{')
+ {
+ /* Find matching closing brace. */
+ for (s=rest+1, n=1, i=1; i && *s && n < len; s++, n++)
+ if (*s == '{')
+ i++;
+ else if (*s == '}')
+ i--;
+ if (i)
+ {
+ err ("closing brace for command '%s' not found", command);
+ return len;
+ }
+ if (n > 2 && !ignore_args)
+ proc_texi_buffer (fp, rest+1, n-2, table_level, eol_action);
+ }
+ else
+ n = 0;
+
+ if (lead_out)
+ fputs (lead_out, fp);
+
+ return n;
+}
+
+
+
+/* Process the string LINE with LEN bytes of Texinfo content. */
+static void
+proc_texi_buffer (FILE *fp, const char *line, size_t len,
+ int *table_level, int *eol_action)
+{
+ const char *s;
+ char cmdbuf[256];
+ int cmdidx = 0;
+ int in_cmd = 0;
+ size_t n;
+
+ for (s=line; *s && len; s++, len--)
+ {
+ if (in_cmd)
+ {
+ if (in_cmd == 1)
+ {
+ switch (*s)
+ {
+ case '@': case '{': case '}':
+ putc (*s, fp); in_cmd = 0;
+ break;
+ case ':': /* Not ending a sentence flag. */
+ in_cmd = 0;
+ break;
+ case '.': case '!': case '?': /* Ending a sentence. */
+ putc (*s, fp); in_cmd = 0;
+ break;
+ case ' ': case '\t': case '\n': /* Non collapsing spaces. */
+ putc (*s, fp); in_cmd = 0;
+ break;
+ default:
+ cmdidx = 0;
+ cmdbuf[cmdidx++] = *s;
+ in_cmd++;
+ break;
+ }
+ }
+ else if (*s == '{' || *s == ' ' || *s == '\t' || *s == '\n')
+ {
+ cmdbuf[cmdidx] = 0;
+ n = proc_texi_cmd (fp, cmdbuf, s, len, table_level, eol_action);
+ assert (n <= len);
+ s += n; len -= n;
+ s--; len++;
+ in_cmd = 0;
+ }
+ else if (cmdidx < sizeof cmdbuf -1)
+ cmdbuf[cmdidx++] = *s;
+ else
+ {
+ err ("texinfo command too long - ignored");
+ in_cmd = 0;
+ }
+ }
+ else if (*s == '@')
+ in_cmd = 1;
+ else if (*s == '\n')
+ {
+ switch (*eol_action)
+ {
+ case 1: /* Create a dummy paragraph. */
+ fputs ("\n\\ \n", fp);
+ break;
+ default:
+ putc (*s, fp);
+ }
+ *eol_action = 0;
+ }
+ else if (*s == '\\')
+ fputs ("\\\\", fp);
+ else
+ putc (*s, fp);
+ }
+
+ if (in_cmd > 1)
+ {
+ cmdbuf[cmdidx] = 0;
+ n = proc_texi_cmd (fp, cmdbuf, s, len, table_level, eol_action);
+ assert (n <= len);
+ s += n; len -= n;
+ s--; len++;
+ /* in_cmd = 0; -- doc only */
+ }
+}
+
+
+/* Do something with the Texinfo line LINE. */
+static void
+parse_texi_line (FILE *fp, const char *line, int *table_level)
+{
+ int eol_action = 0;
+
+ /* A quick test whether there are any texinfo commands. */
+ if (!strchr (line, '@'))
+ {
+ fputs (line, fp);
+ putc ('\n', fp);
+ return;
+ }
+ proc_texi_buffer (fp, line, strlen (line), table_level, &eol_action);
+ putc ('\n', fp);
+}
+
+
+/* Write all the lines LINES to FP. */
+static void
+write_content (FILE *fp, line_buffer_t lines)
+{
+ line_buffer_t line;
+ int table_level = 0;
+
+ for (line = lines; line; line = line->next)
+ {
+ if (line->verbatim)
+ {
+ fputs (line->line, fp);
+ putc ('\n', fp);
+ }
+ else
+ {
+/* fputs ("TEXI---", fp); */
+/* fputs (line->line, fp); */
+/* fputs ("---\n", fp); */
+ parse_texi_line (fp, line->line, &table_level);
+ }
+ }
+}
+
+
+
+static int
+is_standard_section (const char *name)
+{
+ int i;
+ const char *s;
+
+ for (i=0; (s=standard_sections[i]); i++)
+ if (!strcmp (s, name))
+ return 1;
+ return 0;
+}
+
+
+/* Finish a page; that is sort the data and write it out to the file. */
+static void
+finish_page (void)
+{
+ FILE *fp;
+ section_buffer_t sect = NULL;
+ int idx;
+ const char *s;
+ int i;
+
+ if (!thepage.name)
+ return; /* No page active. */
+
+ if (verbose)
+ inf ("finishing page '%s'", thepage.name);
+
+ if (opt_select)
+ {
+ if (!strcmp (opt_select, thepage.name))
+ {
+ inf ("selected '%s'", thepage.name );
+ fp = stdout;
+ }
+ else
+ {
+ fp = fopen ( "/dev/null", "w" );
+ if (!fp)
+ die ("failed to open /dev/null: %s\n", strerror (errno));
+ }
+ }
+ else if (opt_store)
+ {
+ inf ("writing '%s'", thepage.name );
+ fp = fopen ( thepage.name, "w" );
+ if (!fp)
+ die ("failed to create '%s': %s\n", thepage.name, strerror (errno));
+ }
+ else
+ fp = stdout;
+
+ if (write_th (fp))
+ goto leave;
+
+ for (idx=0; (s=standard_sections[idx]); idx++)
+ {
+ for (i=0; i < thepage.n_sections; i++)
+ {
+ sect = thepage.sections + i;
+ if (sect->name && !strcmp (s, sect->name))
+ break;
+ }
+ if (i == thepage.n_sections)
+ sect = NULL;
+
+ if (sect)
+ {
+ fprintf (fp, ".SH %s\n", sect->name);
+ write_content (fp, sect->lines);
+ /* Now continue with all non standard sections directly
+ following this one. */
+ for (i++; i < thepage.n_sections; i++)
+ {
+ sect = thepage.sections + i;
+ if (sect->name && is_standard_section (sect->name))
+ break;
+ if (sect->name)
+ {
+ fprintf (fp, ".SH %s\n", sect->name);
+ write_content (fp, sect->lines);
+ }
+ }
+
+ }
+ }
+
+
+ leave:
+ if (fp != stdout)
+ fclose (fp);
+ free (thepage.name);
+ thepage.name = NULL;
+ /* FIXME: Cleanup the content. */
+}
+
+
+
+
+/* Parse one Texinfo file and create manpages according to the
+ embedded instructions. */
+static void
+parse_file (const char *fname, FILE *fp, char **section_name, int in_pause)
+{
+ char *line;
+ int lnr = 0;
+ /* Fixme: The following state variables don't carry over to include
+ files. */
+ int skip_to_end = 0; /* Used to skip over menu entries. */
+ int skip_sect_line = 0; /* Skip after @mansect. */
+ int item_indent = 0; /* How far is the current @item indented. */
+
+ /* Helper to define a macro. */
+ char *macroname = NULL;
+ char *macrovalue = NULL;
+ size_t macrovaluesize = 0;
+ size_t macrovalueused = 0;
+
+ line = xmalloc (LINESIZE);
+ while (fgets (line, LINESIZE, fp))
+ {
+ size_t n = strlen (line);
+ int got_line = 0;
+ char *p, *pend;
+
+ lnr++;
+ if (!n || line[n-1] != '\n')
+ {
+ err ("%s:%d: trailing linefeed missing, line too long or "
+ "embedded Nul character", fname, lnr);
+ break;
+ }
+ line[--n] = 0;
+
+ /* Kludge to allow indentation of tables. */
+ for (p=line; *p == ' ' || *p == '\t'; p++)
+ ;
+ if (*p)
+ {
+ if (*p == '@' && !strncmp (p+1, "item", 4))
+ item_indent = p - line; /* Set a new indent level. */
+ else if (p - line < item_indent)
+ item_indent = 0; /* Switch off indention. */
+
+ if (item_indent)
+ {
+ memmove (line, line+item_indent, n - item_indent + 1);
+ n -= item_indent;
+ }
+ }
+
+
+ if (*line == '@')
+ {
+ for (p=line+1, n=1; *p && *p != ' ' && *p != '\t'; p++)
+ n++;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ }
+ else
+ p = line;
+
+ /* Take action on macro. */
+ if (macroname)
+ {
+ if (n == 4 && !memcmp (line, "@end", 4)
+ && (line[4]==' '||line[4]=='\t'||!line[4])
+ && !strncmp (p, "macro", 5)
+ && (p[5]==' '||p[5]=='\t'||!p[5]))
+ {
+ if (macrovalueused)
+ macrovalue[--macrovalueused] = 0; /* Kill the last LF. */
+ macrovalue[macrovalueused] = 0; /* Terminate macro. */
+ macrovalue = xrealloc (macrovalue, macrovalueused+1);
+
+ set_macro (macroname, macrovalue);
+ macrovalue = NULL;
+ free (macroname);
+ macroname = NULL;
+ }
+ else
+ {
+ if (macrovalueused + strlen (line) + 2 >= macrovaluesize)
+ {
+ macrovaluesize += strlen (line) + 256;
+ macrovalue = xrealloc (macrovalue, macrovaluesize);
+ }
+ strcpy (macrovalue+macrovalueused, line);
+ macrovalueused += strlen (line);
+ macrovalue[macrovalueused++] = '\n';
+ }
+ continue;
+ }
+
+
+ if (n >= 5 && !memcmp (line, "@node", 5)
+ && (line[5]==' '||line[5]=='\t'||!line[5]))
+ {
+ /* Completey ignore @node lines. */
+ continue;
+ }
+
+
+ if (skip_sect_line)
+ {
+ skip_sect_line = 0;
+ if (!strncmp (line, "@section", 8)
+ || !strncmp (line, "@subsection", 11)
+ || !strncmp (line, "@chapheading", 12))
+ continue;
+ }
+
+ /* We only parse lines we need and ignore the rest. There are a
+ few macros used to control this as well as one @ifset
+ command. Parts we know about are saved away into containers
+ separate for each section. */
+
+ /* First process ifset/ifclear commands. */
+ if (*line == '@')
+ {
+ if (n == 6 && !memcmp (line, "@ifset", 6)
+ && (line[6]==' '||line[6]=='\t'))
+ {
+ for (p=line+7; *p == ' ' || *p == '\t'; p++)
+ ;
+ if (!*p)
+ {
+ err ("%s:%d: name missing after \"@ifset\"", fname, lnr);
+ continue;
+ }
+ for (pend=p; *pend && *pend != ' ' && *pend != '\t'; pend++)
+ ;
+ *pend = 0; /* Ignore rest of the line. */
+ push_condition (p, 1, fname, lnr);
+ continue;
+ }
+ else if (n == 8 && !memcmp (line, "@ifclear", 8)
+ && (line[8]==' '||line[8]=='\t'))
+ {
+ for (p=line+9; *p == ' ' || *p == '\t'; p++)
+ ;
+ if (!*p)
+ {
+ err ("%s:%d: name missing after \"@ifsclear\"", fname, lnr);
+ continue;
+ }
+ for (pend=p; *pend && *pend != ' ' && *pend != '\t'; pend++)
+ ;
+ *pend = 0; /* Ignore rest of the line. */
+ push_condition (p, 0, fname, lnr);
+ continue;
+ }
+ else if (n == 4 && !memcmp (line, "@end", 4)
+ && (line[4]==' '||line[4]=='\t')
+ && !strncmp (p, "ifset", 5)
+ && (p[5]==' '||p[5]=='\t'||!p[5]))
+ {
+ pop_condition (1, fname, lnr);
+ continue;
+ }
+ else if (n == 4 && !memcmp (line, "@end", 4)
+ && (line[4]==' '||line[4]=='\t')
+ && !strncmp (p, "ifclear", 7)
+ && (p[7]==' '||p[7]=='\t'||!p[7]))
+ {
+ pop_condition (0, fname, lnr);
+ continue;
+ }
+ }
+
+ /* Take action on ifset/ifclear. */
+ if (!cond_is_active)
+ continue;
+
+ /* Process commands. */
+ if (*line == '@')
+ {
+ if (skip_to_end
+ && n == 4 && !memcmp (line, "@end", 4)
+ && (line[4]==' '||line[4]=='\t'||!line[4]))
+ {
+ skip_to_end = 0;
+ }
+ else if (cond_in_verbatim)
+ {
+ got_line = 1;
+ }
+ else if (n == 6 && !memcmp (line, "@macro", 6))
+ {
+ macroname = xstrdup (p);
+ macrovalue = xmalloc ((macrovaluesize = 1024));
+ macrovalueused = 0;
+ }
+ else if (n == 4 && !memcmp (line, "@set", 4))
+ {
+ set_variable (p);
+ }
+ else if (n == 8 && !memcmp (line, "@manpage", 8))
+ {
+ free (*section_name);
+ *section_name = NULL;
+ finish_page ();
+ start_page (p);
+ in_pause = 0;
+ }
+ else if (n == 8 && !memcmp (line, "@mansect", 8))
+ {
+ if (!thepage.name)
+ err ("%s:%d: section outside of a man page", fname, lnr);
+ else
+ {
+ free (*section_name);
+ *section_name = ascii_strupr (xstrdup (p));
+ in_pause = 0;
+ skip_sect_line = 1;
+ }
+ }
+ else if (n == 9 && !memcmp (line, "@manpause", 9))
+ {
+ if (!*section_name)
+ err ("%s:%d: pausing outside of a man section", fname, lnr);
+ else if (in_pause)
+ err ("%s:%d: already pausing", fname, lnr);
+ else
+ in_pause = 1;
+ }
+ else if (n == 8 && !memcmp (line, "@mancont", 8))
+ {
+ if (!*section_name)
+ err ("%s:%d: continue outside of a man section", fname, lnr);
+ else if (!in_pause)
+ err ("%s:%d: continue while not pausing", fname, lnr);
+ else
+ in_pause = 0;
+ }
+ else if (n == 5 && !memcmp (line, "@menu", 5)
+ && (line[5]==' '||line[5]=='\t'||!line[5]))
+ {
+ skip_to_end = 1;
+ }
+ else if (n == 8 && !memcmp (line, "@include", 8)
+ && (line[8]==' '||line[8]=='\t'||!line[8]))
+ {
+ char *incname = xstrdup (p);
+ FILE *incfp = fopen (incname, "r");
+
+ if (!incfp && opt_include && *opt_include && *p != '/')
+ {
+ free (incname);
+ incname = xmalloc (strlen (opt_include) + 1
+ + strlen (p) + 1);
+ strcpy (incname, opt_include);
+ if ( incname[strlen (incname)-1] != '/' )
+ strcat (incname, "/");
+ strcat (incname, p);
+ incfp = fopen (incname, "r");
+ }
+
+ if (!incfp)
+ err ("can't open include file '%s': %s",
+ incname, strerror (errno));
+ else
+ {
+ parse_file (incname, incfp, section_name, in_pause);
+ fclose (incfp);
+ }
+ free (incname);
+ }
+ else if (n == 4 && !memcmp (line, "@bye", 4)
+ && (line[4]==' '||line[4]=='\t'||!line[4]))
+ {
+ break;
+ }
+ else if (!skip_to_end)
+ got_line = 1;
+ }
+ else if (!skip_to_end)
+ got_line = 1;
+
+ if (got_line && cond_in_verbatim)
+ add_content (*section_name, line, 1);
+ else if (got_line && thepage.name && *section_name && !in_pause)
+ add_content (*section_name, line, 0);
+
+ }
+ if (ferror (fp))
+ err ("%s:%d: read error: %s", fname, lnr, strerror (errno));
+ free (macroname);
+ free (macrovalue);
+ free (line);
+}
+
+
+static void
+top_parse_file (const char *fname, FILE *fp)
+{
+ char *section_name = NULL; /* Name of the current section or NULL
+ if not in a section. */
+ macro_t m;
+
+ while (macrolist)
+ {
+ macro_t next = macrolist->next;
+ free (macrolist->value);
+ free (macrolist);
+ macrolist = next;
+ }
+ while (variablelist)
+ {
+ macro_t next = variablelist->next;
+ free (variablelist->value);
+ free (variablelist);
+ variablelist = next;
+ }
+ for (m=predefinedmacrolist; m; m = m->next)
+ set_macro (m->name, xstrdup ("1"));
+ cond_is_active = 1;
+ cond_in_verbatim = 0;
+
+ parse_file (fname, fp, &section_name, 0);
+ free (section_name);
+ finish_page ();
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ const char *s;
+
+ opt_source = "GNU";
+ opt_release = "";
+
+ /* Define default macros. The trick is that these macros are not
+ defined when using the actual texinfo renderer. */
+ add_predefined_macro ("isman");
+ add_predefined_macro ("manverb");
+
+ /* Option parsing. */
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ puts (
+ "Usage: " PGM " [OPTION] [FILE]\n"
+ "Extract man pages from a Texinfo source.\n\n"
+ " --source NAME use NAME as source field\n"
+ " --release STRING use STRING as the release field\n"
+ " --date EPOCH use EPOCH as publication date\n"
+ " --store write output using @manpage name\n"
+ " --select NAME only output pages with @manpage NAME\n"
+ " --verbose enable extra informational output\n"
+ " --debug enable additional debug output\n"
+ " --help display this help and exit\n"
+ " -I DIR also search in include DIR\n"
+ " -D gpgone the only usable define\n\n"
+ "With no FILE, or when FILE is -, read standard input.\n\n"
+ "Report bugs to <https://bugs.gnupg.org>.");
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--version"))
+ {
+ puts (PGM " " VERSION "\n"
+ "Copyright (C) 2005, 2017 g10 Code GmbH\n"
+ "This program comes with ABSOLUTELY NO WARRANTY.\n"
+ "This is free software, and you are welcome to redistribute it\n"
+ "under certain conditions. See the file COPYING for details.");
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--quiet"))
+ {
+ quiet = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--source"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ opt_source = *argv;
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--release"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ opt_release = *argv;
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--date"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ opt_date = *argv;
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--store"))
+ {
+ opt_store = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--select"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ opt_select = strrchr (*argv, '/');
+ if (opt_select)
+ opt_select++;
+ else
+ opt_select = *argv;
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "-I"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ opt_include = *argv;
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "-D"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ add_predefined_macro (*argv);
+ argc--; argv++;
+ }
+ }
+ }
+
+ if (argc > 1)
+ die ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n");
+
+ /* Take care of supplied timestamp for reproducible builds. See
+ * https://reproducible-builds.org/specs/source-date-epoch/ */
+ if (!opt_date && (s = getenv ("SOURCE_DATE_EPOCH")) && *s)
+ opt_date = s;
+
+ /* Start processing. */
+ if (argc && strcmp (*argv, "-"))
+ {
+ FILE *fp = fopen (*argv, "rb");
+ if (!fp)
+ die ("%s:0: can't open file: %s", *argv, strerror (errno));
+ top_parse_file (*argv, fp);
+ fclose (fp);
+ }
+ else
+ top_parse_file ("-", stdin);
+
+ return !!any_error;
+}
+
+
+/*
+Local Variables:
+compile-command: "gcc -Wall -g -Wall -o yat2m yat2m.c"
+End:
+*/
diff --git a/comm/third_party/libgcrypt/m4/ChangeLog-2011 b/comm/third_party/libgcrypt/m4/ChangeLog-2011
new file mode 100644
index 0000000000..2b5100abd1
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/ChangeLog-2011
@@ -0,0 +1,50 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-02-23 Werner Koch <wk@g10code.com>
+
+ * gpg-error.m4: New. Take from current gpg-error master.
+ * Makefile.am (EXTRA_DIST): Add gpg-error.m4.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * noexecstack.m4: Replace non portable grep -q. Reported by
+ Albert Chin.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * noexecstack.m4: Change default to enable it.
+
+2007-02-20 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: New.
+
+ * noexecstack.m4: New. Taken from gnupg 1.4
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * fallback.m4: Removed again.
+
+2006-10-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * fallback.m4: New file from Pth.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * sys_socket_h.m4, socklen.m4, onceonly.m4: New files from gnulib.
+
+2004-04-06 Werner Koch <wk@gnupg.org>
+
+ * libtool.m4: Updated from 1.5.4
+
+2003-12-08 Werner Koch <wk@gnupg.org>
+
+ * libtool.m4: New.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/m4/Makefile.am b/comm/third_party/libgcrypt/m4/Makefile.am
new file mode 100644
index 0000000000..9b95317451
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST = libtool.m4 socklen.m4 sys_socket_h.m4 noexecstack.m4
+EXTRA_DIST += gpg-error.m4
diff --git a/comm/third_party/libgcrypt/m4/Makefile.in b/comm/third_party/libgcrypt/m4/Makefile.in
new file mode 100644
index 0000000000..5111b727bc
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/Makefile.in
@@ -0,0 +1,491 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = m4
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = libtool.m4 socklen.m4 sys_socket_h.m4 noexecstack.m4 \
+ gpg-error.m4
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu m4/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/m4/ax_cc_for_build.m4 b/comm/third_party/libgcrypt/m4/ax_cc_for_build.m4
new file mode 100644
index 0000000000..c62ffadbc0
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/ax_cc_for_build.m4
@@ -0,0 +1,77 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_cc_for_build.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CC_FOR_BUILD
+#
+# DESCRIPTION
+#
+# Find a build-time compiler. Sets CC_FOR_BUILD and EXEEXT_FOR_BUILD.
+#
+# LICENSE
+#
+# Copyright (c) 2010 Reuben Thomas <rrt@sc3d.org>
+# Copyright (c) 1999 Richard Henderson <rth@redhat.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program 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 General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 3
+
+dnl Get a default for CC_FOR_BUILD to put into Makefile.
+AC_DEFUN([AX_CC_FOR_BUILD],
+[# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test -z "$CC_FOR_BUILD"; then
+ if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+ else
+ CC_FOR_BUILD=gcc
+ fi
+fi
+AC_SUBST(CC_FOR_BUILD)
+# Also set EXEEXT_FOR_BUILD.
+if test "x$cross_compiling" = "xno"; then
+ EXEEXT_FOR_BUILD='$(EXEEXT)'
+else
+ AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext,
+ [rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.c
+ bfd_cv_build_exeext=
+ ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ rm -f conftest*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no])
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+AC_SUBST(EXEEXT_FOR_BUILD)])dnl
diff --git a/comm/third_party/libgcrypt/m4/gpg-error.m4 b/comm/third_party/libgcrypt/m4/gpg-error.m4
new file mode 100644
index 0000000000..c9b235f288
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/gpg-error.m4
@@ -0,0 +1,188 @@
+# gpg-error.m4 - autoconf macro to detect libgpg-error.
+# Copyright (C) 2002, 2003, 2004, 2011, 2014, 2018, 2020 g10 Code GmbH
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Last-changed: 2020-11-17
+
+
+dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION,
+dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl
+dnl Test for libgpg-error and define GPG_ERROR_CFLAGS, GPG_ERROR_LIBS,
+dnl GPG_ERROR_MT_CFLAGS, and GPG_ERROR_MT_LIBS. The _MT_ variants are
+dnl used for programs requireing real multi thread support.
+dnl
+dnl If a prefix option is not used, the config script is first
+dnl searched in $SYSROOT/bin and then along $PATH. If the used
+dnl config script does not match the host specification the script
+dnl is added to the gpg_config_script_warn variable.
+dnl
+AC_DEFUN([AM_PATH_GPG_ERROR],
+[ AC_REQUIRE([AC_CANONICAL_HOST])
+ gpg_error_config_prefix=""
+ dnl --with-libgpg-error-prefix=PFX is the preferred name for this option,
+ dnl since that is consistent with how our three siblings use the directory/
+ dnl package name in --with-$dir_name-prefix=PFX.
+ AC_ARG_WITH(libgpg-error-prefix,
+ AS_HELP_STRING([--with-libgpg-error-prefix=PFX],
+ [prefix where GPG Error is installed (optional)]),
+ [gpg_error_config_prefix="$withval"])
+
+ dnl Accept --with-gpg-error-prefix and make it work the same as
+ dnl --with-libgpg-error-prefix above, for backwards compatibility,
+ dnl but do not document this old, inconsistently-named option.
+ AC_ARG_WITH(gpg-error-prefix,,
+ [gpg_error_config_prefix="$withval"])
+
+ if test x"${GPG_ERROR_CONFIG}" = x ; then
+ if test x"${gpg_error_config_prefix}" != x ; then
+ GPG_ERROR_CONFIG="${gpg_error_config_prefix}/bin/gpg-error-config"
+ else
+ case "${SYSROOT}" in
+ /*)
+ if test -x "${SYSROOT}/bin/gpg-error-config" ; then
+ GPG_ERROR_CONFIG="${SYSROOT}/bin/gpg-error-config"
+ fi
+ ;;
+ '')
+ ;;
+ *)
+ AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.])
+ ;;
+ esac
+ fi
+ fi
+
+ AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no)
+ min_gpg_error_version=ifelse([$1], ,1.33,$1)
+ ok=no
+
+ if test "$prefix" = NONE ; then
+ prefix_option_expanded=/usr/local
+ else
+ prefix_option_expanded="$prefix"
+ fi
+ if test "$exec_prefix" = NONE ; then
+ exec_prefix_option_expanded=$prefix_option_expanded
+ else
+ exec_prefix_option_expanded=$(prefix=$prefix_option_expanded eval echo $exec_prefix)
+ fi
+ libdir_option_expanded=$(prefix=$prefix_option_expanded exec_prefix=$exec_prefix_option_expanded eval echo $libdir)
+
+ if test -f $libdir_option_expanded/pkgconfig/gpg-error.pc; then
+ gpgrt_libdir=$libdir_option_expanded
+ else
+ if crt1_path=$(${CC:-cc} -print-file-name=crt1.o 2>/dev/null); then
+ if possible_libdir=$(cd ${crt1_path%/*} && pwd 2>/dev/null); then
+ if test -f $possible_libdir/pkgconfig/gpg-error.pc; then
+ gpgrt_libdir=$possible_libdir
+ fi
+ fi
+ fi
+ fi
+
+ if test "$GPG_ERROR_CONFIG" = "no" -a -n "$gpgrt_libdir"; then
+ AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no)
+ if test "$GPGRT_CONFIG" = "no"; then
+ unset GPGRT_CONFIG
+ else
+ GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir"
+ if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then
+ GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error"
+ AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config])
+ gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion`
+ else
+ unset GPGRT_CONFIG
+ fi
+ fi
+ else
+ gpg_error_config_version=`$GPG_ERROR_CONFIG --version`
+ fi
+ if test "$GPG_ERROR_CONFIG" != "no"; then
+ req_major=`echo $min_gpg_error_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+ req_minor=`echo $min_gpg_error_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+ major=`echo $gpg_error_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+ minor=`echo $gpg_error_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+ if test "$major" -gt "$req_major"; then
+ ok=yes
+ else
+ if test "$major" -eq "$req_major"; then
+ if test "$minor" -ge "$req_minor"; then
+ ok=yes
+ fi
+ fi
+ fi
+ if test -z "$GPGRT_CONFIG" -a -n "$gpgrt_libdir"; then
+ if test "$major" -gt 1 -o "$major" -eq 1 -a "$minor" -ge 33; then
+ AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no)
+ if test "$GPGRT_CONFIG" = "no"; then
+ unset GPGRT_CONFIG
+ else
+ GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir"
+ if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then
+ GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error"
+ AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config])
+ else
+ unset GPGRT_CONFIG
+ fi
+ fi
+ fi
+ fi
+ fi
+ AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version)
+ if test $ok = yes; then
+ GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG --cflags`
+ GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG --libs`
+ if test -z "$GPGRT_CONFIG"; then
+ GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --mt --cflags 2>/dev/null`
+ GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --mt --libs 2>/dev/null`
+ else
+ GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --variable=mtcflags 2>/dev/null`
+ GPG_ERROR_MT_CFLAGS="$GPG_ERROR_CFLAGS${GPG_ERROR_CFLAGS:+ }$GPG_ERROR_MT_CFLAGS"
+ GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --variable=mtlibs 2>/dev/null`
+ GPG_ERROR_MT_LIBS="$GPG_ERROR_LIBS${GPG_ERROR_LIBS:+ }$GPG_ERROR_MT_LIBS"
+ fi
+ AC_MSG_RESULT([yes ($gpg_error_config_version)])
+ ifelse([$2], , :, [$2])
+ if test -z "$GPGRT_CONFIG"; then
+ gpg_error_config_host=`$GPG_ERROR_CONFIG --host 2>/dev/null || echo none`
+ else
+ gpg_error_config_host=`$GPG_ERROR_CONFIG --variable=host 2>/dev/null || echo none`
+ fi
+ if test x"$gpg_error_config_host" != xnone ; then
+ if test x"$gpg_error_config_host" != x"$host" ; then
+ AC_MSG_WARN([[
+***
+*** The config script "$GPG_ERROR_CONFIG" was
+*** built for $gpg_error_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-libgpg-error-prefix
+*** to specify a matching config script or use \$SYSROOT.
+***]])
+ gpg_config_script_warn="$gpg_config_script_warn libgpg-error"
+ fi
+ fi
+ else
+ GPG_ERROR_CFLAGS=""
+ GPG_ERROR_LIBS=""
+ GPG_ERROR_MT_CFLAGS=""
+ GPG_ERROR_MT_LIBS=""
+ AC_MSG_RESULT(no)
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(GPG_ERROR_CFLAGS)
+ AC_SUBST(GPG_ERROR_LIBS)
+ AC_SUBST(GPG_ERROR_MT_CFLAGS)
+ AC_SUBST(GPG_ERROR_MT_LIBS)
+])
diff --git a/comm/third_party/libgcrypt/m4/libtool.m4 b/comm/third_party/libgcrypt/m4/libtool.m4
new file mode 100644
index 0000000000..8795701e4c
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/libtool.m4
@@ -0,0 +1,8031 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from https://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_REPLACE_SHELLFNS
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case "$ECHO" in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[ --with-sysroot[=DIR] Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([${with_sysroot}])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS="$save_LDFLAGS"])
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case ${prev}${p} in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test "$pre_test_object_deps_done" = no; then
+ case ${prev} in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_PUSH([Java])
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_POP
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_PUSH([Go])
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_POP
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+
+dnl Here, something like AC_LANG_PUSH([RC]) is expected.
+dnl But Resource Compiler is not supported as a language by autoconf
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+dnl Here, AC_LANG_POP is expected.
+GCC=$lt_save_GCC
+dnl Back to C
+AC_LANG([C])
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+ func_split_long_opt_name=${1%%=*}
+ func_split_long_opt_arg=${1#*=}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
+
+ _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
+
+ _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+ func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+ eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/comm/third_party/libgcrypt/m4/ltoptions.m4 b/comm/third_party/libgcrypt/m4/ltoptions.m4
new file mode 100644
index 0000000000..5d9acd8e23
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/ltoptions.m4
@@ -0,0 +1,384 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/comm/third_party/libgcrypt/m4/ltsugar.m4 b/comm/third_party/libgcrypt/m4/ltsugar.m4
new file mode 100644
index 0000000000..9000a057d3
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/comm/third_party/libgcrypt/m4/ltversion.m4 b/comm/third_party/libgcrypt/m4/ltversion.m4
new file mode 100644
index 0000000000..07a8602d48
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/comm/third_party/libgcrypt/m4/lt~obsolete.m4 b/comm/third_party/libgcrypt/m4/lt~obsolete.m4
new file mode 100644
index 0000000000..c573da90c5
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/comm/third_party/libgcrypt/m4/noexecstack.m4 b/comm/third_party/libgcrypt/m4/noexecstack.m4
new file mode 100644
index 0000000000..ae0b26b842
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/noexecstack.m4
@@ -0,0 +1,55 @@
+# noexecstack.m4
+dnl Copyright (C) 1995-2006 Free Software Foundation, Inc.
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License, or (at your option) any later version.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+dnl Checks whether the stack can be marked nonexecutable by passing an
+dnl option to the C-compiler when acting on .s files. Returns that
+dnl option in NOEXECSTACK_FLAGS.
+dnl This macro is adapted from one found in GLIBC-2.3.5.
+AC_DEFUN([CL_AS_NOEXECSTACK],[
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AM_PROG_AS])
+
+AC_MSG_CHECKING([whether non excutable stack support is requested])
+AC_ARG_ENABLE(noexecstack,
+ AS_HELP_STRING([--disable-noexecstack],
+ [disable non executable stack support]),
+ noexecstack_support=$enableval, noexecstack_support=yes)
+AC_MSG_RESULT($noexecstack_support)
+
+AC_CACHE_CHECK([whether assembler supports --noexecstack option],
+cl_cv_as_noexecstack, [dnl
+ cat > conftest.c <<EOF
+void foo() {}
+EOF
+ if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS
+ -S -o conftest.s conftest.c >/dev/null]) \
+ && grep .note.GNU-stack conftest.s >/dev/null \
+ && AC_TRY_COMMAND([${CCAS} $CCASFLAGS $CPPFLAGS -Wa,--noexecstack
+ -c -o conftest.o conftest.s >/dev/null])
+ then
+ cl_cv_as_noexecstack=yes
+ else
+ cl_cv_as_noexecstack=no
+ fi
+ rm -f conftest*])
+ if test "$noexecstack_support" = yes -a "$cl_cv_as_noexecstack" = yes; then
+ NOEXECSTACK_FLAGS="-Wa,--noexecstack"
+ else
+ NOEXECSTACK_FLAGS=
+ fi
+ AC_SUBST(NOEXECSTACK_FLAGS)
+])
diff --git a/comm/third_party/libgcrypt/m4/socklen.m4 b/comm/third_party/libgcrypt/m4/socklen.m4
new file mode 100644
index 0000000000..251960b0ac
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/socklen.m4
@@ -0,0 +1,76 @@
+# socklen.m4 serial 11
+dnl Copyright (C) 2005-2007, 2009-2020 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Albert Chin, Windows fixes from Simon Josefsson.
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc.:
+dnl HP-UX 10.20, IRIX 6.5, OSF/1 4.0, Interix 3.5, BeOS.
+dnl So we have to test to find something that will work.
+
+AC_DEFUN([gl_TYPE_SOCKLEN_T],
+ [AC_REQUIRE([gl_CHECK_SOCKET_HEADERS])dnl
+ AC_CHECK_TYPE([socklen_t], ,
+ [AC_CACHE_CHECK([for socklen_t equivalent],
+ [gl_cv_socklen_t_equiv],
+ [# Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ gl_cv_socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t "unsigned int" "long int" "unsigned long int"; do
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+ [[#include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);]],
+ [[$t len;
+ getpeername (0, 0, &len);]])],
+ [gl_cv_socklen_t_equiv="$t"])
+ test "$gl_cv_socklen_t_equiv" != "" && break
+ done
+ test "$gl_cv_socklen_t_equiv" != "" && break
+ done
+ if test "$gl_cv_socklen_t_equiv" = ""; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_DEFINE_UNQUOTED([socklen_t], [$gl_cv_socklen_t_equiv],
+ [type to use in place of socklen_t if not defined])],
+ [gl_SOCKET_HEADERS])])
+
+dnl On mingw32, socklen_t is in ws2tcpip.h ('int'), so we try to find
+dnl it there too. But on Cygwin, wc2tcpip.h must not be included. Users
+dnl of this module should use the same include pattern as gl_SOCKET_HEADERS.
+dnl When you change this macro, keep also in sync:
+dnl - gl_CHECK_SOCKET_HEADERS,
+dnl - the Include section of modules/socklen.
+AC_DEFUN([gl_SOCKET_HEADERS],
+[
+/* <sys/types.h> is not needed according to POSIX, but the
+ <sys/socket.h> in i386-unknown-freebsd4.10 and
+ powerpc-apple-darwin5.5 required it. */
+#include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#elif HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+#endif
+])
+
+dnl Tests for the existence of the header for socket facilities.
+dnl Defines the C macros HAVE_SYS_SOCKET_H, HAVE_WS2TCPIP_H.
+dnl This macro must match gl_SOCKET_HEADERS.
+AC_DEFUN([gl_CHECK_SOCKET_HEADERS],
+ [AC_CHECK_HEADERS_ONCE([sys/socket.h])
+ if test $ac_cv_header_sys_socket_h = no; then
+ dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make
+ dnl the check for those headers unconditional; yet cygwin reports
+ dnl that the headers are present but cannot be compiled (since on
+ dnl cygwin, all socket information should come from sys/socket.h).
+ AC_CHECK_HEADERS([ws2tcpip.h])
+ fi
+ ])
diff --git a/comm/third_party/libgcrypt/m4/sys_socket_h.m4 b/comm/third_party/libgcrypt/m4/sys_socket_h.m4
new file mode 100644
index 0000000000..d3e45b48c1
--- /dev/null
+++ b/comm/third_party/libgcrypt/m4/sys_socket_h.m4
@@ -0,0 +1,23 @@
+# sys_socket_h.m4 serial 2
+dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson.
+
+AC_DEFUN([gl_HEADER_SYS_SOCKET],
+[
+ AC_CHECK_HEADERS_ONCE([sys/socket.h])
+ if test $ac_cv_header_sys_socket_h = yes; then
+ SYS_SOCKET_H=''
+ else
+ dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make
+ dnl the check for those headers unconditional; yet cygwin reports
+ dnl that the headers are present but cannot be compiled (since on
+ dnl cygwin, all socket information should come from sys/socket.h).
+ AC_CHECK_HEADERS([winsock2.h ws2tcpip.h])
+ SYS_SOCKET_H='sys/socket.h'
+ fi
+ AC_SUBST(SYS_SOCKET_H)
+])
diff --git a/comm/third_party/libgcrypt/mkinstalldirs b/comm/third_party/libgcrypt/mkinstalldirs
new file mode 100755
index 0000000000..ef7e16fdaf
--- /dev/null
+++ b/comm/third_party/libgcrypt/mkinstalldirs
@@ -0,0 +1,161 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2006-05-11.19
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+IFS=" "" $nl"
+errstatus=0
+dirmode=
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage"
+ exit $?
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --version)
+ echo "$0 $scriptversion"
+ exit $?
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error. This is a problem when calling mkinstalldirs
+# from a parallel make. We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+ '')
+ if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ test -d ./-p && rmdir ./-p
+ test -d ./--version && rmdir ./--version
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+ test ! -d ./--version; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ else
+ # Clean up after NextStep and OpenStep mkdir.
+ for d in ./-m ./-p ./--version "./$dirmode";
+ do
+ test -d $d && rmdir $d
+ done
+ fi
+ ;;
+esac
+
+for file
+do
+ case $file in
+ /*) pathcomp=/ ;;
+ *) pathcomp= ;;
+ esac
+ oIFS=$IFS
+ IFS=/
+ set fnord $file
+ shift
+ IFS=$oIFS
+
+ for d
+ do
+ test "x$d" = x && continue
+
+ pathcomp=$pathcomp$d
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp=$pathcomp/
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/comm/third_party/libgcrypt/mpi/ChangeLog-2011 b/comm/third_party/libgcrypt/mpi/ChangeLog-2011
new file mode 100644
index 0000000000..1e07872180
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/ChangeLog-2011
@@ -0,0 +1,831 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-07-04 Werner Koch <wk@g10code.com>
+
+ * longlong.h (add_ssaaaa) [__arm__]: Do no use asm if thumb code
+ generation is enabled. This is bug#1202. Reported for gpg 1.4.
+
+2011-03-28 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Remove unused var RSEC.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * mpi-cmp.c (gcry_mpi_cmp): Allow comparing of opaque MPIs.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-02-22 Aurelien Jarno <aurel32@debian.org> (wk)
+
+ * longlong.h (umul_ppmm) <mips> [__GNUC__ >= 4.4]: Patch according
+ to recommended gcc 4.4 changes.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * config.links: Remove asm modules for all sparc64. This is
+ debian#560028.
+
+2009-05-26 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (mpi_read_from_buffer): Allow zero-sized MPIs (i.e a
+ zero).
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * mpiutil.c: Remove memory.h.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (mpi_read_from_buffer): Do not bail out if the mpi is
+ larger than the buffer (potential problem). Do not print error
+ messages.
+ (mpi_fromstr): Return an error instead of hitting an assert.
+ (gcry_mpi_scan) <PGP>: Fix potential double free problem.
+ (gcry_mpi_scan) <HEX>: Fix potential memory leak.
+ (do_get_buffer): Return NULL on memory allocation failure.
+ (gcry_mpi_print): Check result of do_get_buffer.
+ (gcry_mpi_aprint): Return error on a memory allocation failure.
+
+ * mpicoder.c: Re-indent.
+
+2008-12-03 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Fix last change. Asserts are really
+ useful!
+
+2008-12-02 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Re-indent.
+ (gcry_mpi_powm): Simplified allocation of the result to fix a
+ double free bug. This is bug#977. Reported by Haakon Ringberg.
+
+2008-08-20 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_lshift): Actually implement.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_lshift): New.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * mpi-mod.c (gcry_mpi_mod): Remove
+ * mpi-inv.c (_gcry_mpi_invm): Remove _ prefix.
+ * mpiutil.c (_gcry_mpi_swap): Remove.
+ (_gcry_mpi_new): Remove.
+ (_gcry_mpi_snew): Remove.
+ (gcry_mpi_invm): Remove.
+ (gcry_mpi_copy): Remove and rename _version to this.
+ (gcry_mpi_set, gcry_mpi_set_ui): Merge with _ version.
+ * mpi-inv.c (gcry_mpi_invm): Remove _ prefix and return 1.
+ * mpi-mul.c (gcry_mpi_mul_2exp): Remove and rename _ version to this.
+
+2007-10-29 Werner Koch <wk@g10code.com>
+
+ * config.links: No Candadian Cross here, thus use $host instead of
+ $target.
+
+2007-10-26 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Special rules for Apple
+ Darwin on ia32 from Gregor Riepl.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * config.links: Rename assembler file links by suffixing "-asm".
+ * Makefile.am (CCASCOMPILE, LTCCASCOMPILE, CLEANFILES,
+ libmpi_la_LIBADD, libmpi_la_DEPENDENCIES, SUFFIXES, .S.o, .S.obj,
+ .S.lo): Removed variables and targets.
+ (mpih_add1, mpih_sub1, mpih_mul1, mpih_mul2, mpih_mul3,
+ mpih_lshift, mpih_rshift, mpih_udiv, mpih_udiv_qrnnd,
+ nodist_libmpi_la_SOURCES): New variables.
+ (DISTCLEANFILES): Rename assembler file links by suffixing "-asm".
+ Add variants for C file links.
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ * config.links (path): Allowthe sue of colons as delimiters.
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * pentium4/distfiles: Fixed.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * config.links: Create a file mod-source-info.h.
+ * Makefile.am (DISTCLEANFILES): Add that file.
+ * mpiutil.c (_gcry_mpi_get_hw_config): New.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * config.links: Add additional assembler search directories.
+
+2007-03-28 Werner Koch <wk@g10code.com>
+
+ * ec.c: New.
+
+2007-03-23 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (_gcry_mpi_lshift_limbs): Assign AP after the resize.
+
+ * mpi-div.c (gcry_mpi_mod, _gcry_mpi_mod): Moved to ..
+ * mpi-mod.c: .. new file.
+ (_gcry_mpi_barrett_init, _gcry_mpi_barrett_free): New.
+ (_gcry_mpi_mod_barrett): New.
+ (_gcry_mpi_mul_barrett): New.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * mpi-div.c (_gcry_mpi_mod): New.
+ * mpiutil.c (_gcry_mpi_new, _gcry_mpi_snew): New.
+
+2007-03-13 Werner Dittmann <Werner.Dittmann@t-online.de> (wk)
+
+ * amd64/mpih-add1.S, amd64/mpih-add1.S, amd64/mpih-lshift.S
+ * amd64/mpih-mul1.S, amd64/mpih-mul2.S, amd64/mpih-mul3.S
+ * amd64/mpih-rshift.S, amd64/mpih-sub1.S: New.
+ * config.links: Add case for x86_64.
+
+2007-02-23 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Remove unused var ESIGN.
+
+ * mpiutil.c (gcry_mpi_get_flag): Let it return a value to silent
+ MIPSpro cc warning.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (_gcry_mpi_set_buffer): Made BUFFER a void*.
+
+2006-11-15 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (.S.o): Check for srcdir also in in CPP pass.
+ (INCLUDES): Removed.
+ (AM_CPPFLAGS, AM_CFLAGS): New, modified. Merged with Moritz'
+ changes.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
+ new gcrypt.h is used, not the one installed in the system.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Make sure that powerpc64 is
+ matched before a generic powerpc. Reported by Andreas Metzler.
+ Should fix Debian bug 284609.
+
+2006-08-25 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_rshift): Don't shift if N == 0 but do a
+ plain copy.
+
+2006-08-04 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_rshift): Rewritten to remove the limitation
+ on N (which used to be less than BITS_PER_MPI_LIMB).
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit): Fixed
+ allocation. Reported by bpgcrypt at itaparica.org.
+ * mpiutil.c (_gcry_mpi_resize): Clear the new part of the resized
+ limb space.
+
+2006-07-26 Werner Koch <wk@g10code.com>
+
+ * mpiutil.c (gcry_mpi_randomize): Changed P to unsigned char*.
+
+ * mpicoder.c (gcry_mpi_scan): Changed arg BUFFER to void*.
+ (mpi_read_from_buffer): Made BUFFER arg const.
+ (gcry_mpi_scan): Removed now needless cast. Add cast for arg to
+ mpi_fromstr.
+ (gcry_mpi_print): Made TMP unsigned.
+
+ * Makefile.am (AM_CCASFLAGS): New.
+
+2005-10-09 Moritz Schulte <moritz@g10code.com>
+
+ * mpi-cmp.c (gcry_mpi_cmp_ui): Rewritten; correctly handle case of
+ zero limbs in U.
+
+2005-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (gcry_mpi_randomize): Store random data in secure
+ memory if the given MPI is secure - not the other way around (argl).
+
+2005-04-23 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Don't assume the compiler will pre-process the .S
+ files. Some compilers, like those from HP and IBM, don't do
+ this. So, we use the same solution gnupg-1.4.0 does. Preprocess
+ first and then compile.
+
+ * hppa1.1/mpih-mul3.S: Add "level 1.1" directive to disable
+ warning about using PA-RISC1.1 opcodes.
+ * hppa1.1/mpih-mul2.S: Likewise.
+ * hppa1.1/mpih-mul1.S: Likewise.
+ * hppa1.1/udiv-qrnnd.S: Likewise.
+
+2005-02-16 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Rewritten, fixed memory
+ corruption.
+
+2005-02-06 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_get_ui, gcry_mpi_get_ui): New functions.
+
+2005-01-05 Werner Koch <wk@g10code.com>
+
+ * hppa1.1/udiv-qrnnd.S: Reverted change of 2004-03-02 but kept the
+ .align directive.
+
+2004-12-16 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Move entry for powerpc64
+ before generic powerpc. Suggested by Rafael Ãvila de Espíndola.
+
+2004-03-02 Werner Koch <wk@gnupg.org>
+
+ * hppa1.1/udiv-qrnnd.S: Alignment fix from Lamont Jones for
+ Debian. Taken from gnupg-1.3.
+
+ * longlong.h: Added PowerPC 64 bit code from GPM-4.1.2 but didn't
+ enable it yet. Some whitespace changes in HPPA to fix assembler
+ problems on HP-UX. From gnupg 1.3
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Better allocate
+ something even if NLIMBS is passed as 0.
+
+ * config.links: Updated system list to match gnupg 1.3.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h [M_DEBUG]: Removed this unused code.
+ (struct karatsuba_ctx): Added TSPACE_NLIMBS and TP_NLIMBS.
+ * mpiutil.c (_gcry_mpi_free_limb_space): Add arg NLIMBS and wipe
+ out the memory. Changed all callers.
+ * mpih-mul.c (_gcry_mpih_mul_karatsuba_case): Keep track of
+ allocated limbs.
+ * mpi-div.c (_gcry_mpi_tdiv_qr): Keep track of allocated limbs.
+ * mpi-mul.c (gcry_mpi_mul): Ditto.
+ * mpi-pow.c (gcry_mpi_powm): Ditto.
+
+ * Manifest: Empty new file. Also add Manifest files to all CPU
+ specific directories.
+ * Makefile.am: Added.
+
+ * mpiutil.c (gcry_mpi_randomize): Use gcry_create_nonce if WEAK
+ random has been requested.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * i386/mpih-rshift.S, i386/mpih-lshift.S: Use %dl and not %edx for
+ testb; this avoids an assembler warning.
+
+ * mpi-pow.c (gcry_mpi_powm): s/exp/expo/ to avoid shadowing warning.
+
+2003-08-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (SUFFIXES): New variable.
+ (.S.o, .S.lo, .S.obj): Rewritten.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * longlong.h (__clz_tab): Renamed to _gcry_clz_tab.
+ * mpi-bit.c (__clz_tab): Likewise.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): New argument BUFLEN to replace the
+ use of the intial value of NBYTES. Changed BUFFER to unsigned.
+ (gcry_mpi_print): Likewise.
+ (gcry_mpi_dump): New.
+ (_gcry_log_mpidump): Make use of gcry_mpi_dump.
+ (mpi_print): Removed.
+ (gcry_mpi_scan): Allocated mpi in secure memory when required.
+ (gcry_mpi_aprint): Changed BUFFER to unsigned char*.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * mpicoder.c: Used gcry_err* wrappers for libgpg-error symbols.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * mpi-add.c: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * mpi-bit.c: Likewise.
+ * mpi-cmp.c: Likewise.
+ * mpi-div.c: Likewise.
+ * mpi-gcd.c: Likewise.
+ * mpi-internal.h: Likewise.
+ * mpi-inv.c: Likewise.
+ * mpi-mpow.c: Likewise.
+ * mpi-mul.c: Likewise.
+ * mpi-pow.c: Likewise.
+ * mpi-scan.c: Likewise.
+ * mpicoder.c: Likewise.
+ * mpiutil.c: Likewise.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * mpicoder.c (gcry_mpi_scan): Adjust for libgpg-error.
+ (gcry_mpi_print): Likewise.
+ (gcry_mpi_aprint): Likewise.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * longlong.h, mpi-add.c, mpi-bit.c, mpi-cmp.c, mpi-div.c,
+ mpi-gcd.c, mpi-inline.c, mpi-inline.h, mpi-internal.h, mpi-inv.c,
+ mpi-mpow.c, mpi-mul.c, mpi-pow.c, mpi-scan.c, mpicoder.c,
+ mpih-div.c, mpih-mul.c, mpiutil.c, generic/mpi-asm-defs.h,
+ generic/mpih-add1.c, generic/mpih-lshift.c, generic/mpih-mul1.c,
+ generic/mpih-mul2.c, generic/mpih-mul3.c, generic/mpih-rshift.c,
+ generic/mpih-sub1.c, generic/udiv-w-sdiv.c, i386/syntax.h,
+ m68k/syntax.h, mips3/mpi-asm-defs.h, powerpc32/syntax.h: Edited
+ all preprocessor instructions to remove whitespace before the '#'.
+ This is not required by C89, but there are some compilers out
+ there that don't like it. Replaced any occurence of the now
+ deprecated type names with the new ones.
+
+2003-05-21 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Only try to allocate
+ memory in case the amount of bytes to allocate is non-zero.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_resize): Allocate secure memory, in case
+ bit zero of `flags' is set.
+
+ * mpi-add.c (gcry_mpi_sub): Simplify function; always use a
+ temporary variable now.
+
+2003-04-15 Werner Koch <wk@gnupg.org>
+
+ * longlong.h (umul_ppmm): Support SH3 and SH4. Thanks to
+ kazuya.s@jp.yokogawa.com.
+
+2003-04-02 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_print): Fixed testing against possible
+ uninitialized LEN. Valgrinded by Nikos Mavroyanopoulos.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * longlong.h: Removed some spaces between backslashes and newlines.
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ * mpi-mul.c (gcry_mpi_mul_2exp): New. This was declared in
+ gcrypt.h but only implemented as internal function. Noted by Timo
+ but a few minutes to late for today's release.
+
+ * Makefile.am (DISTCLEANFILES): Include mpi-asm-defs.h
+
+2002-09-18 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (.S.lo): Pass -DPIC. i386, PPC and Sparc code
+ require it. It worked for me because I am using the i586 code.
+
+2002-08-23 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (.S.lo): Fixed for libtool build with --disable-shared.
+
+2002-07-24 Werner Koch <wk@gnupg.org>
+
+ * longlong.h: Replaced all K&R multiline strings by ISO ones for
+ the sake of modern compilers. Suggested by Marco Parrone.
+
+2002-06-24 Werner Koch <wk@gnupg.org>
+
+ * mpiutil.c (gcry_mpi_swap): New.
+
+ * mpi-div.c (gcry_mpi_div): New.
+ (gcry_mpi_mod): New.
+ * mpi-inv.c (gcry_mpi_invm): New.
+
+ * mpicoder.c (do_get_buffer): Make sure that we allocate at least
+ one byte.
+
+2002-06-12 Werner Koch <wk@gnupg.org>
+
+ * hppa1.1/udiv-qrnnd.S: Changes for PIC by Randolph Chung.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * config.links: Chnage the way the mpi modules are determined.
+ * Makefile.am: Revamped to better handle modules
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of all files to the LGPL.
+
+2002-04-18 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): Don't use normalize on a NULL MPI.
+
+2002-03-20 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (mpi_read_from_buffer): Bail out on a zero length
+ buffer because we can't eventually do an malloc of this size.
+ Reported by Timo.
+
+2002-01-14 Werner Koch <wk@gnupg.org>
+
+ * mpi-inv.c (_gcry_mpi_invm): Typo fixes, noted by Carlo Perassi.
+
+2001-11-01 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): Allow to pass a nbytes as NULL or
+ with value 0 for format GCRY_FMT_SSH, so that the length is not
+ used for any checks, only the length stored in the bufer is used.
+ This is a nice format becuase we can just pass a buffer around and
+ don't need to care about its length.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * config.links: Changed the way the list of files to be
+ symlinked is returned.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * mpih-cmp.c: Removed and moved mpihelp_cmp to ..
+ * mpi-inline.h: .. here.
+
+ Major function renaming. All global functions are now prefixed
+ with _gcry_ or gcry_. Renamed also all mpihelp_ to just mpih_ so
+ that functions names are not getting to long an unreadable and for
+ better matching with the filenames.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (mpi_fromstr): Made static and assume that all input
+ is in hexformat.
+
+ Updated all CPU specific code with the one from GnuPG-1.0.5. This
+ is just a change of text formatting and the use of .label
+ instead of labels for hppa and pa7100.
+
+ * longlong.h: Fixes for ARM by Phil Blundell.
+
+2001-03-29 Werner Koch <wk@gnupg.org>
+
+ * mpi-mul.c (mpi_mul): Make sure that secret temporary results are
+ not stored in w. Suggested by Florian Weimer.
+
+ * config.links: Use i386 code for i386. According to tests by
+ Kevin Ryde the i586 code runs slow on i386 CPUs. Ditto for i786.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am: Removed mpi.h.
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h: Put limb_t definition in an ifdef.
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h, mpi.h: Changed the way they are called and
+ introduced DID_MPI_LIMP_TYPEDEF hack. Very ugly, should all be
+ revamped.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-11 Werner Koch <wk@gnupg.org>
+
+ * generic/mpi-asm-defs.h: New.
+ * mips3/mpi-asm-defs.h: New.
+ * config.links: Create a link to one of the above files.
+
+Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
+
+ * mpicoder.c (gcry_mpi_scan): Normalize the returned MPI.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * config.links: Support for powerpc--netbsd by Gabriel Rosenkoetter.
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * power/: Add all files from GMP for this CPU. Converted comments to
+ CPP comments because some ASes complain about ' in comments.
+
+ * config.links: Support for BSDI 4.x; by Wayne Chapeskie. Add support
+ for FreeBSD 5 and made the case stmt looking nicer; by Jun Kuriyama.
+ Add support for NetBSD.
+ (sparc8): Made the search path the same as sparc9
+ (sparc64-unknown-linux-gnu): use udiv module; by Adam Mitchell.
+
+ * Makefile.am: c/SFLAGS/ASFLAGS/. This has only been used by the
+ powerpc and actually never passed the -Wa,foo to the cc.
+
+ * mpih-div.c (mpihelp_divrem): The MPN_COPY_DECR copied one element
+ too many. This is a gmp2.0.2p9.txt patch.
+
+ * longlong.h (umul_ppmm): Fixes for ARM-4. By Sean MacLennan.
+
+ * mpi-internal.h (karatsuba_ctx): New.
+ * mpih-mul.c (mpihelp_release_karatsuba_ctx): New.
+ (mpihelp_mul_karatsuba_case): New.
+ (mpihelp_mul): Splitted to make use of the new functions.
+ * mpi-pow.c (mpi_powm): Make use of the new splitted function to avoid
+ multiple allocation of temporary memory during the karatsuba operations.
+ * mpi_mpow.c: Removed the unused Barrett code.
+
+2000-03-21 16:17:30 Werner Koch (wk@habibti.openit.de)
+
+ * config.links: Add support for FreeBSD 5.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (gcry_mpi_aprint): Now really returns the length.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * mpiutil.c: Removed all memory debugging code.
+
+ * mpicoder.c (gcry_mpi_aprint): New.
+
+ * Replaced all m_ memory functions by g10_ ones.
+
+Fri Dec 31 14:06:56 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpi-bit.c (gcry_mpi_get_nbits): New.
+
+ * mpiutil.c (mpi_set_secure): made static.
+ (gcry_mpi_get_flag): New.
+ (gcry_mpi_set_flag): New.
+ (gcry_mpi_clear_flag): New.
+ (mpi_set_opaque): renamed to gcry_mpi_set_opaque.
+ (mpi_get_opaque): renamed to gcry_mpi_get_opaque.
+
+Fri Dec 31 12:48:31 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (mpi_read_from_buffer): Made static.
+ (gcry_mpi_print): A buffer of NULL is now allowed to get the required
+ length back.
+ (mpi_get_keyid): Removed.
+ (mpi_print): Made static - should be removed.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * Makefile.am (INCLUDES): Add ../gcrypt.
+
+ * g10m.c : Removed.
+
+ * mpicoder.c (mpi_write): Removed.
+ (mpi_read): Removed.
+ (gcry_mpi_scan): New. Taken from ../gcrypt/mpiapi.c.
+ (gcry_mpi_print): Ditto.
+
+ * mpi-pow.c (mpi_powm): Renamed to ...
+ (gcry_mpi_powm): ... this.
+
+ * mpiutil.c (gcry_mpi_new): New as a wrapper around the old function.
+ Taken from ../gcrypt/mpiapi.c.
+ (gcry_mpi_snew): Ditto.
+ (gcry_mpi_release): Ditto.
+ (gcry_mpi_copy): Ditto.
+ (gcry_mpi_set): Ditto.
+ (gcry_mpi_set_ui): Ditto.
+ (gcry_mpi_cmp): Ditto.
+ (gcry_mpi_cmp_ui): Ditto.
+ (gcry_mpi_randomize): Ditto.
+
+ * mpicoder.c (mpi_print): Removed the nbit_info kludge.
+ * mpi-bits.c (mpi_get_nbits): Replaced the is_protected stuff by
+ checking whether it is an opaque mpi and then returns it's length
+ in bits.
+ * mpiutil.c (mpi_set_opaque): Changed the interface to take a number
+ of bits for the length. Adjusted all users.
+ (mpi_get_opaque): Ditto.
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (g10_log_mpidump): Add a temporary workaround
+
+ * mpih-mul.c (mpihelp_mul_n): s/m_is_ecure/g10_is_secure/
+
+ * mpiutil.c (mpi_alloc): Remved the debug mode because it has turned
+ out, that this feature was not very useful in the past. Use the
+ new alloc functions.
+ (mpi_alloc_secure): Ditto.
+ (mpi_alloc_limb_space): Ditto.
+ (mpi_free_limb_space): Ditto.
+ (mpi_resize): Ditto.
+ (mpi_free): Ditto.
+ (mpi_set_secure): Removed the debug stuff.
+ (mpi_set_opaque): Ditto.
+ (mpi_copy): Ditto.
+ (mpi_alloc_set_ui): Ditto.
+ (mpi_m_check): Use g10_ wrapper.
+
+Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * config.links: Add case label for DJGPP
+
+Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * Makefile.am: Use .s files as temporaries, disabled other .S rules.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * mpicoder.c (g10_log_mpidump): New.
+
+ * Makefile.am: Support for libtool.
+
+Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * mpi-bit.c (mpi_lshift_limbs,mpi_rshift_limbs): New.
+ * mpi-mpow.c (barrett_mulm): New but diabled.
+
+Tue Jun 1 16:01:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links (i[56]86*-*-freebsdelf*): New.
+
+Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links (sysdep.h): Not any more conditionally created.
+
+Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpiutil.c (mpi_alloc_like): New.
+
+Mon Apr 26 17:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpih-add.c, mpih-sub.c: Removed
+ * mpi-inline.c: New.
+ * mpi-inline.h: Make it usable by mpi-inline.c.
+
+Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpih-mul.c (mpihelp_mul_n): Fixed use of memory region.
+ (mpihelp_mul): Ditto.
+
+Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Explicit rules to invoke cpp on *.S
+
+Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links: Take advantage of the with_symbol_underscore macro.
+ Add support for freebsd 4.
+
+Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mips3/mpih-sub1.S: Removed left over junk in last line. (Should I
+ blame me or my editor?).
+
+Sat Feb 13 12:04:43 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Removed the +=. Add MPI_OPT_FLAGS.
+
+Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpi-cmp.c (mpi_cmp_ui): Normalized the arg.
+
+Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpi-bit.c (mpi_normalize): New.
+ (mpi_get_nbits): Normalize the MPI.
+ * mpi-bit.c (mpi_cmp): Normalize the MPI before the compare.
+
+
+Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links: Moved the case for powerpc*linux
+ * powerpcp32/*.S: Removed some underscores.
+
+Thu Nov 26 07:27:52 1998 Werner Koch <werner.koch@guug.de>
+
+ * config.links: Support for ppc with ELF
+ * powerpc32/syntax.h: New.
+ * powerpc32/*.S: Applied ELF patches (glibc patches)
+
+Tue Nov 10 19:31:37 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * power*/ : Started with stuff for PPC
+ * config.links: Some stuff for PPC.
+ * generic/udiv-w-sdiv.c: New but disabled.
+
+Tue Oct 27 12:37:46 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (freebsd): Fixes for FreeBSD 3.0
+
+Wed Oct 14 09:59:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (freebsd): ELF patches from Jun Kuriyama.
+
+Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free).
+
+Thu Sep 17 18:08:50 1998 Werner Koch (wk@(none))
+
+ * hppa1.1/udiv-qrnnd.S: Fix from Steffen Zahn for HPUX 10.20
+
+Thu Aug 6 16:39:28 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * mpi-bit.c (mpi_set_bytes): Removed.
+
+Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none))
+
+ * mpicoder.c (mpi_read_from_buffer): New.
+
+ * mpiutil.c (mpi_set_opaque): New.
+ (mpi_get_opaque): New.
+ (mpi_copy): Changed to support opauqe flag
+ (mpi_free): Ditto.
+
+Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpiutil.c (mpi_clear): Reset flags.
+ (mpi_set): Ditto.
+ (mpi_alloc_secure): Set flag to 1 and not ored the 1 in, tsss..
+
+Fri Jun 26 11:19:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpiutil.c (mpi_alloc): set nbits to 0.
+ (mpi_alloc_secure): Ditto.
+ (mpi_clear): Ditto.
+
+Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mips3/*.S: New
+
+Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: split mpih-shift into mpih-[lr]shift and
+ changed all implementations.
+ * mpi/alpha: add some new assembler stuff.
+
+Wed May 13 11:04:29 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: Add support for MIPS
+
+Thu Apr 9 11:31:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpicoder.c (mpi_get_secure_buffer): New.
+
+Wed Apr 8 09:44:33 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: Applied small fix from Ulf Möller.
+
+Mon Apr 6 12:38:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpicoder.c (mpi_get_buffer): Removed returned leading zeroes
+ and changed all callers.
+
+Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi-bit.c (mpi_clear_highbit): New.
+
+Mon Mar 2 19:29:00 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (DISTCLEANFILES): New
+
+Thu Feb 26 06:48:54 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (X86_BROKEN_ALIGN): Added for some systems.
+
+Mon Feb 23 12:21:40 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi/m68k/mpih-shift.S (Lspecial): Changed duplicate symbol.
+
+Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links : Add detection of m68k cpus
+
+
+ Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/mpi/Makefile.am b/comm/third_party/libgcrypt/mpi/Makefile.am
new file mode 100644
index 0000000000..d06594e18a
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/Makefile.am
@@ -0,0 +1,179 @@
+## Process this file with automake to produce Makefile.in
+# Copyright (C) 1992, 1999, 2000, 2002 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
+
+# 1.5 leads to a combinatorial explosion due to all the conditionals
+# I was not able to build it with 64Megs - 1.6 fixes this.
+# not anymore required: AUTOMAKE_OPTIONS = 1.6
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+
+AM_ASFLAGS = $(MPI_SFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+
+EXTRA_DIST = config.links
+DISTCLEANFILES = mpi-asm-defs.h \
+ mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \
+ mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \
+ mpih-add1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c \
+ mpih-lshift.c mpih-rshift.c mpih-sub1.c \
+ sysdep.h mod-source-info.h
+
+# Beware: The following list is not a comment but grepped by
+# config.links to get the list of symlinked modules
+# Optional modules are marked with an O in the second column.
+#BEGIN_ASM_LIST
+# mpih-add1 C
+# mpih-sub1 C
+# mpih-mul1 C
+# mpih-mul2 C
+# mpih-mul3 C
+# mpih-lshift C
+# mpih-rshift C
+# udiv O
+# udiv-qrnnd O
+#END_ASM_LIST
+
+# Note: This function has not yet been implemented. There is only a dummy in
+# generic/
+# udiv-w-sdiv O
+
+# And we need to have conditionals for all modules because
+# we don't know whether they are .c or .S. Very ugly; I know.
+# Remember to define them all in configure.ac
+if MPI_MOD_ASM_MPIH_ADD1
+mpih_add1 = mpih-add1-asm.S
+else
+if MPI_MOD_C_MPIH_ADD1
+mpih_add1 = mpih-add1.c
+else
+mpih_add1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_SUB1
+mpih_sub1 = mpih-sub1-asm.S
+else
+if MPI_MOD_C_MPIH_SUB1
+mpih_sub1 = mpih-sub1.c
+else
+mpih_sub1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL1
+mpih_mul1 = mpih-mul1-asm.S
+else
+if MPI_MOD_C_MPIH_MUL1
+mpih_mul1 = mpih-mul1.c
+else
+mpih_mul1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL2
+mpih_mul2 = mpih-mul2-asm.S
+else
+if MPI_MOD_C_MPIH_MUL2
+mpih_mul2 = mpih-mul2.c
+else
+mpih_mul2 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL3
+mpih_mul3 = mpih-mul3-asm.S
+else
+if MPI_MOD_C_MPIH_MUL3
+mpih_mul3 = mpih-mul3.c
+else
+mpih_mul3 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_LSHIFT
+mpih_lshift = mpih-lshift-asm.S
+else
+if MPI_MOD_C_MPIH_LSHIFT
+mpih_lshift = mpih-lshift.c
+else
+mpih_lshift =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_RSHIFT
+mpih_rshift = mpih-rshift-asm.S
+else
+if MPI_MOD_C_MPIH_RSHIFT
+mpih_rshift = mpih-rshift.c
+else
+mpih_rshift =
+endif
+endif
+
+if MPI_MOD_ASM_UDIV
+udiv = udiv-asm.S
+else
+if MPI_MOD_C_UDIV
+udiv = udiv.c
+else
+udiv =
+endif
+endif
+
+if MPI_MOD_ASM_UDIV_QRNND
+udiv_qrnnd = udiv-qrnnd-asm.S
+else
+if MPI_MOD_C_UDIV_QRNND
+udiv_qrnnd = udiv-qrnnd.c
+else
+udiv_qrnnd =
+endif
+endif
+
+noinst_LTLIBRARIES = libmpi.la
+
+libmpi_la_LDFLAGS =
+nodist_libmpi_la_SOURCES = $(mpih_add1) $(mpih_sub1) $(mpih_mul1) \
+ $(mpih_mul2) $(mpih_mul3) $(mpih_lshift) $(mpih_rshift) \
+ $(udiv) $(udiv_qrnnd)
+libmpi_la_SOURCES = longlong.h \
+ mpi-add.c \
+ mpi-bit.c \
+ mpi-cmp.c \
+ mpi-div.c \
+ mpi-gcd.c \
+ mpi-internal.h \
+ mpi-inline.h \
+ mpi-inline.c \
+ mpi-inv.c \
+ mpi-mul.c \
+ mpi-mod.c \
+ mpi-pow.c \
+ mpi-mpow.c \
+ mpi-scan.c \
+ mpicoder.c \
+ mpih-div.c \
+ mpih-mul.c \
+ mpih-const-time.c \
+ mpiutil.c \
+ ec.c ec-internal.h ec-ed25519.c
+EXTRA_libmpi_la_SOURCES = asm-common-aarch64.h
diff --git a/comm/third_party/libgcrypt/mpi/Makefile.in b/comm/third_party/libgcrypt/mpi/Makefile.in
new file mode 100644
index 0000000000..156187ce75
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/Makefile.in
@@ -0,0 +1,947 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 1992, 1999, 2000, 2002 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
+
+# 1.5 leads to a combinatorial explosion due to all the conditionals
+# I was not able to build it with 64Megs - 1.6 fixes this.
+# not anymore required: AUTOMAKE_OPTIONS = 1.6
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = mpi
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libmpi_la_LIBADD =
+am_libmpi_la_OBJECTS = mpi-add.lo mpi-bit.lo mpi-cmp.lo mpi-div.lo \
+ mpi-gcd.lo mpi-inline.lo mpi-inv.lo mpi-mul.lo mpi-mod.lo \
+ mpi-pow.lo mpi-mpow.lo mpi-scan.lo mpicoder.lo mpih-div.lo \
+ mpih-mul.lo mpih-const-time.lo mpiutil.lo ec.lo ec-ed25519.lo
+@MPI_MOD_ASM_MPIH_ADD1_FALSE@@MPI_MOD_C_MPIH_ADD1_TRUE@am__objects_1 = mpih-add1.lo
+@MPI_MOD_ASM_MPIH_ADD1_TRUE@am__objects_1 = mpih-add1-asm.lo
+@MPI_MOD_ASM_MPIH_SUB1_FALSE@@MPI_MOD_C_MPIH_SUB1_TRUE@am__objects_2 = mpih-sub1.lo
+@MPI_MOD_ASM_MPIH_SUB1_TRUE@am__objects_2 = mpih-sub1-asm.lo
+@MPI_MOD_ASM_MPIH_MUL1_FALSE@@MPI_MOD_C_MPIH_MUL1_TRUE@am__objects_3 = mpih-mul1.lo
+@MPI_MOD_ASM_MPIH_MUL1_TRUE@am__objects_3 = mpih-mul1-asm.lo
+@MPI_MOD_ASM_MPIH_MUL2_FALSE@@MPI_MOD_C_MPIH_MUL2_TRUE@am__objects_4 = mpih-mul2.lo
+@MPI_MOD_ASM_MPIH_MUL2_TRUE@am__objects_4 = mpih-mul2-asm.lo
+@MPI_MOD_ASM_MPIH_MUL3_FALSE@@MPI_MOD_C_MPIH_MUL3_TRUE@am__objects_5 = mpih-mul3.lo
+@MPI_MOD_ASM_MPIH_MUL3_TRUE@am__objects_5 = mpih-mul3-asm.lo
+@MPI_MOD_ASM_MPIH_LSHIFT_FALSE@@MPI_MOD_C_MPIH_LSHIFT_TRUE@am__objects_6 = mpih-lshift.lo
+@MPI_MOD_ASM_MPIH_LSHIFT_TRUE@am__objects_6 = mpih-lshift-asm.lo
+@MPI_MOD_ASM_MPIH_RSHIFT_FALSE@@MPI_MOD_C_MPIH_RSHIFT_TRUE@am__objects_7 = mpih-rshift.lo
+@MPI_MOD_ASM_MPIH_RSHIFT_TRUE@am__objects_7 = mpih-rshift-asm.lo
+@MPI_MOD_ASM_UDIV_FALSE@@MPI_MOD_C_UDIV_TRUE@am__objects_8 = udiv.lo
+@MPI_MOD_ASM_UDIV_TRUE@am__objects_8 = udiv-asm.lo
+@MPI_MOD_ASM_UDIV_QRNND_FALSE@@MPI_MOD_C_UDIV_QRNND_TRUE@am__objects_9 = udiv-qrnnd.lo
+@MPI_MOD_ASM_UDIV_QRNND_TRUE@am__objects_9 = udiv-qrnnd-asm.lo
+nodist_libmpi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3) $(am__objects_4) $(am__objects_5) \
+ $(am__objects_6) $(am__objects_7) $(am__objects_8) \
+ $(am__objects_9)
+libmpi_la_OBJECTS = $(am_libmpi_la_OBJECTS) \
+ $(nodist_libmpi_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libmpi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libmpi_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/ec-ed25519.Plo ./$(DEPDIR)/ec.Plo \
+ ./$(DEPDIR)/mpi-add.Plo ./$(DEPDIR)/mpi-bit.Plo \
+ ./$(DEPDIR)/mpi-cmp.Plo ./$(DEPDIR)/mpi-div.Plo \
+ ./$(DEPDIR)/mpi-gcd.Plo ./$(DEPDIR)/mpi-inline.Plo \
+ ./$(DEPDIR)/mpi-inv.Plo ./$(DEPDIR)/mpi-mod.Plo \
+ ./$(DEPDIR)/mpi-mpow.Plo ./$(DEPDIR)/mpi-mul.Plo \
+ ./$(DEPDIR)/mpi-pow.Plo ./$(DEPDIR)/mpi-scan.Plo \
+ ./$(DEPDIR)/mpicoder.Plo ./$(DEPDIR)/mpih-add1-asm.Plo \
+ ./$(DEPDIR)/mpih-add1.Plo ./$(DEPDIR)/mpih-const-time.Plo \
+ ./$(DEPDIR)/mpih-div.Plo ./$(DEPDIR)/mpih-lshift-asm.Plo \
+ ./$(DEPDIR)/mpih-lshift.Plo ./$(DEPDIR)/mpih-mul.Plo \
+ ./$(DEPDIR)/mpih-mul1-asm.Plo ./$(DEPDIR)/mpih-mul1.Plo \
+ ./$(DEPDIR)/mpih-mul2-asm.Plo ./$(DEPDIR)/mpih-mul2.Plo \
+ ./$(DEPDIR)/mpih-mul3-asm.Plo ./$(DEPDIR)/mpih-mul3.Plo \
+ ./$(DEPDIR)/mpih-rshift-asm.Plo ./$(DEPDIR)/mpih-rshift.Plo \
+ ./$(DEPDIR)/mpih-sub1-asm.Plo ./$(DEPDIR)/mpih-sub1.Plo \
+ ./$(DEPDIR)/mpiutil.Plo ./$(DEPDIR)/udiv-asm.Plo \
+ ./$(DEPDIR)/udiv-qrnnd-asm.Plo ./$(DEPDIR)/udiv-qrnnd.Plo \
+ ./$(DEPDIR)/udiv.Plo
+am__mv = mv -f
+CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CCASFLAGS) $(CCASFLAGS)
+AM_V_CPPAS = $(am__v_CPPAS_@AM_V@)
+am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@)
+am__v_CPPAS_0 = @echo " CPPAS " $@;
+am__v_CPPAS_1 =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libmpi_la_SOURCES) $(EXTRA_libmpi_la_SOURCES) \
+ $(nodist_libmpi_la_SOURCES)
+DIST_SOURCES = $(libmpi_la_SOURCES) $(EXTRA_libmpi_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_ASFLAGS = $(MPI_SFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+EXTRA_DIST = config.links
+DISTCLEANFILES = mpi-asm-defs.h \
+ mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \
+ mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \
+ mpih-add1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c \
+ mpih-lshift.c mpih-rshift.c mpih-sub1.c \
+ sysdep.h mod-source-info.h
+
+@MPI_MOD_ASM_MPIH_ADD1_FALSE@@MPI_MOD_C_MPIH_ADD1_FALSE@mpih_add1 =
+@MPI_MOD_ASM_MPIH_ADD1_FALSE@@MPI_MOD_C_MPIH_ADD1_TRUE@mpih_add1 = mpih-add1.c
+
+# Beware: The following list is not a comment but grepped by
+# config.links to get the list of symlinked modules
+# Optional modules are marked with an O in the second column.
+#BEGIN_ASM_LIST
+# mpih-add1 C
+# mpih-sub1 C
+# mpih-mul1 C
+# mpih-mul2 C
+# mpih-mul3 C
+# mpih-lshift C
+# mpih-rshift C
+# udiv O
+# udiv-qrnnd O
+#END_ASM_LIST
+
+# Note: This function has not yet been implemented. There is only a dummy in
+# generic/
+# udiv-w-sdiv O
+
+# And we need to have conditionals for all modules because
+# we don't know whether they are .c or .S. Very ugly; I know.
+# Remember to define them all in configure.ac
+@MPI_MOD_ASM_MPIH_ADD1_TRUE@mpih_add1 = mpih-add1-asm.S
+@MPI_MOD_ASM_MPIH_SUB1_FALSE@@MPI_MOD_C_MPIH_SUB1_FALSE@mpih_sub1 =
+@MPI_MOD_ASM_MPIH_SUB1_FALSE@@MPI_MOD_C_MPIH_SUB1_TRUE@mpih_sub1 = mpih-sub1.c
+@MPI_MOD_ASM_MPIH_SUB1_TRUE@mpih_sub1 = mpih-sub1-asm.S
+@MPI_MOD_ASM_MPIH_MUL1_FALSE@@MPI_MOD_C_MPIH_MUL1_FALSE@mpih_mul1 =
+@MPI_MOD_ASM_MPIH_MUL1_FALSE@@MPI_MOD_C_MPIH_MUL1_TRUE@mpih_mul1 = mpih-mul1.c
+@MPI_MOD_ASM_MPIH_MUL1_TRUE@mpih_mul1 = mpih-mul1-asm.S
+@MPI_MOD_ASM_MPIH_MUL2_FALSE@@MPI_MOD_C_MPIH_MUL2_FALSE@mpih_mul2 =
+@MPI_MOD_ASM_MPIH_MUL2_FALSE@@MPI_MOD_C_MPIH_MUL2_TRUE@mpih_mul2 = mpih-mul2.c
+@MPI_MOD_ASM_MPIH_MUL2_TRUE@mpih_mul2 = mpih-mul2-asm.S
+@MPI_MOD_ASM_MPIH_MUL3_FALSE@@MPI_MOD_C_MPIH_MUL3_FALSE@mpih_mul3 =
+@MPI_MOD_ASM_MPIH_MUL3_FALSE@@MPI_MOD_C_MPIH_MUL3_TRUE@mpih_mul3 = mpih-mul3.c
+@MPI_MOD_ASM_MPIH_MUL3_TRUE@mpih_mul3 = mpih-mul3-asm.S
+@MPI_MOD_ASM_MPIH_LSHIFT_FALSE@@MPI_MOD_C_MPIH_LSHIFT_FALSE@mpih_lshift =
+@MPI_MOD_ASM_MPIH_LSHIFT_FALSE@@MPI_MOD_C_MPIH_LSHIFT_TRUE@mpih_lshift = mpih-lshift.c
+@MPI_MOD_ASM_MPIH_LSHIFT_TRUE@mpih_lshift = mpih-lshift-asm.S
+@MPI_MOD_ASM_MPIH_RSHIFT_FALSE@@MPI_MOD_C_MPIH_RSHIFT_FALSE@mpih_rshift =
+@MPI_MOD_ASM_MPIH_RSHIFT_FALSE@@MPI_MOD_C_MPIH_RSHIFT_TRUE@mpih_rshift = mpih-rshift.c
+@MPI_MOD_ASM_MPIH_RSHIFT_TRUE@mpih_rshift = mpih-rshift-asm.S
+@MPI_MOD_ASM_UDIV_FALSE@@MPI_MOD_C_UDIV_FALSE@udiv =
+@MPI_MOD_ASM_UDIV_FALSE@@MPI_MOD_C_UDIV_TRUE@udiv = udiv.c
+@MPI_MOD_ASM_UDIV_TRUE@udiv = udiv-asm.S
+@MPI_MOD_ASM_UDIV_QRNND_FALSE@@MPI_MOD_C_UDIV_QRNND_FALSE@udiv_qrnnd =
+@MPI_MOD_ASM_UDIV_QRNND_FALSE@@MPI_MOD_C_UDIV_QRNND_TRUE@udiv_qrnnd = udiv-qrnnd.c
+@MPI_MOD_ASM_UDIV_QRNND_TRUE@udiv_qrnnd = udiv-qrnnd-asm.S
+noinst_LTLIBRARIES = libmpi.la
+libmpi_la_LDFLAGS =
+nodist_libmpi_la_SOURCES = $(mpih_add1) $(mpih_sub1) $(mpih_mul1) \
+ $(mpih_mul2) $(mpih_mul3) $(mpih_lshift) $(mpih_rshift) \
+ $(udiv) $(udiv_qrnnd)
+
+libmpi_la_SOURCES = longlong.h \
+ mpi-add.c \
+ mpi-bit.c \
+ mpi-cmp.c \
+ mpi-div.c \
+ mpi-gcd.c \
+ mpi-internal.h \
+ mpi-inline.h \
+ mpi-inline.c \
+ mpi-inv.c \
+ mpi-mul.c \
+ mpi-mod.c \
+ mpi-pow.c \
+ mpi-mpow.c \
+ mpi-scan.c \
+ mpicoder.c \
+ mpih-div.c \
+ mpih-mul.c \
+ mpih-const-time.c \
+ mpiutil.c \
+ ec.c ec-internal.h ec-ed25519.c
+
+EXTRA_libmpi_la_SOURCES = asm-common-aarch64.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu mpi/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu mpi/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libmpi.la: $(libmpi_la_OBJECTS) $(libmpi_la_DEPENDENCIES) $(EXTRA_libmpi_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libmpi_la_LINK) $(libmpi_la_OBJECTS) $(libmpi_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-ed25519.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-add.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-bit.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-cmp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-div.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-gcd.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-inline.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-inv.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-mod.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-mpow.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-mul.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-pow.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-scan.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpicoder.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-add1-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-add1.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-const-time.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-div.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-lshift-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-lshift.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul1-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul1.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul2-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul3-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul3.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-rshift-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-rshift.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-sub1-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-sub1.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpiutil.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv-qrnnd-asm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv-qrnnd.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.S.o:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $<
+
+.S.obj:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.S.lo:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $<
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/ec-ed25519.Plo
+ -rm -f ./$(DEPDIR)/ec.Plo
+ -rm -f ./$(DEPDIR)/mpi-add.Plo
+ -rm -f ./$(DEPDIR)/mpi-bit.Plo
+ -rm -f ./$(DEPDIR)/mpi-cmp.Plo
+ -rm -f ./$(DEPDIR)/mpi-div.Plo
+ -rm -f ./$(DEPDIR)/mpi-gcd.Plo
+ -rm -f ./$(DEPDIR)/mpi-inline.Plo
+ -rm -f ./$(DEPDIR)/mpi-inv.Plo
+ -rm -f ./$(DEPDIR)/mpi-mod.Plo
+ -rm -f ./$(DEPDIR)/mpi-mpow.Plo
+ -rm -f ./$(DEPDIR)/mpi-mul.Plo
+ -rm -f ./$(DEPDIR)/mpi-pow.Plo
+ -rm -f ./$(DEPDIR)/mpi-scan.Plo
+ -rm -f ./$(DEPDIR)/mpicoder.Plo
+ -rm -f ./$(DEPDIR)/mpih-add1-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-add1.Plo
+ -rm -f ./$(DEPDIR)/mpih-const-time.Plo
+ -rm -f ./$(DEPDIR)/mpih-div.Plo
+ -rm -f ./$(DEPDIR)/mpih-lshift-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-lshift.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul1-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul1.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul2-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul2.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul3-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul3.Plo
+ -rm -f ./$(DEPDIR)/mpih-rshift-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-rshift.Plo
+ -rm -f ./$(DEPDIR)/mpih-sub1-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-sub1.Plo
+ -rm -f ./$(DEPDIR)/mpiutil.Plo
+ -rm -f ./$(DEPDIR)/udiv-asm.Plo
+ -rm -f ./$(DEPDIR)/udiv-qrnnd-asm.Plo
+ -rm -f ./$(DEPDIR)/udiv-qrnnd.Plo
+ -rm -f ./$(DEPDIR)/udiv.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/ec-ed25519.Plo
+ -rm -f ./$(DEPDIR)/ec.Plo
+ -rm -f ./$(DEPDIR)/mpi-add.Plo
+ -rm -f ./$(DEPDIR)/mpi-bit.Plo
+ -rm -f ./$(DEPDIR)/mpi-cmp.Plo
+ -rm -f ./$(DEPDIR)/mpi-div.Plo
+ -rm -f ./$(DEPDIR)/mpi-gcd.Plo
+ -rm -f ./$(DEPDIR)/mpi-inline.Plo
+ -rm -f ./$(DEPDIR)/mpi-inv.Plo
+ -rm -f ./$(DEPDIR)/mpi-mod.Plo
+ -rm -f ./$(DEPDIR)/mpi-mpow.Plo
+ -rm -f ./$(DEPDIR)/mpi-mul.Plo
+ -rm -f ./$(DEPDIR)/mpi-pow.Plo
+ -rm -f ./$(DEPDIR)/mpi-scan.Plo
+ -rm -f ./$(DEPDIR)/mpicoder.Plo
+ -rm -f ./$(DEPDIR)/mpih-add1-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-add1.Plo
+ -rm -f ./$(DEPDIR)/mpih-const-time.Plo
+ -rm -f ./$(DEPDIR)/mpih-div.Plo
+ -rm -f ./$(DEPDIR)/mpih-lshift-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-lshift.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul1-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul1.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul2-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul2.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul3-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-mul3.Plo
+ -rm -f ./$(DEPDIR)/mpih-rshift-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-rshift.Plo
+ -rm -f ./$(DEPDIR)/mpih-sub1-asm.Plo
+ -rm -f ./$(DEPDIR)/mpih-sub1.Plo
+ -rm -f ./$(DEPDIR)/mpiutil.Plo
+ -rm -f ./$(DEPDIR)/udiv-asm.Plo
+ -rm -f ./$(DEPDIR)/udiv-qrnnd-asm.Plo
+ -rm -f ./$(DEPDIR)/udiv-qrnnd.Plo
+ -rm -f ./$(DEPDIR)/udiv.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/mpi/aarch64/distfiles b/comm/third_party/libgcrypt/mpi/aarch64/distfiles
new file mode 100644
index 0000000000..1327bd4a71
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/aarch64/distfiles
@@ -0,0 +1,6 @@
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-sub1.S
+mpi-asm-defs.h
diff --git a/comm/third_party/libgcrypt/mpi/aarch64/mpi-asm-defs.h b/comm/third_party/libgcrypt/mpi/aarch64/mpi-asm-defs.h
new file mode 100644
index 0000000000..65190653bc
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/aarch64/mpi-asm-defs.h
@@ -0,0 +1,4 @@
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG_LONG)
diff --git a/comm/third_party/libgcrypt/mpi/aarch64/mpih-add1.S b/comm/third_party/libgcrypt/mpi/aarch64/mpih-add1.S
new file mode 100644
index 0000000000..bc62cf9873
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/aarch64/mpih-add1.S
@@ -0,0 +1,74 @@
+/* ARM64 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "asm-common-aarch64.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, x0
+ * mpi_ptr_t s1_ptr, x1
+ * mpi_ptr_t s2_ptr, x2
+ * mpi_size_t size) w3
+ */
+
+.text
+
+.globl _gcry_mpih_add_n
+ELF(.type _gcry_mpih_add_n,%function)
+_gcry_mpih_add_n:
+ CFI_STARTPROC()
+ and w5, w3, #3;
+ adds xzr, xzr, xzr; /* clear carry flag */
+
+ cbz w5, .Large_loop;
+
+.Loop:
+ ldr x4, [x1], #8;
+ sub w3, w3, #1;
+ ldr x11, [x2], #8;
+ and w5, w3, #3;
+ adcs x4, x4, x11;
+ str x4, [x0], #8;
+ cbz w3, .Lend;
+ cbnz w5, .Loop;
+
+.Large_loop:
+ ldp x4, x6, [x1], #16;
+ ldp x5, x7, [x2], #16;
+ ldp x8, x10, [x1], #16;
+ ldp x9, x11, [x2], #16;
+ sub w3, w3, #4;
+ adcs x4, x4, x5;
+ adcs x6, x6, x7;
+ adcs x8, x8, x9;
+ adcs x10, x10, x11;
+ stp x4, x6, [x0], #16;
+ stp x8, x10, [x0], #16;
+ cbnz w3, .Large_loop;
+
+.Lend:
+ adc x0, xzr, xzr;
+ ret;
+ CFI_ENDPROC()
+ELF(.size _gcry_mpih_add_n,.-_gcry_mpih_add_n;)
diff --git a/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul1.S
new file mode 100644
index 0000000000..92fcd141b1
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul1.S
@@ -0,0 +1,99 @@
+/* ARM64 mul_1 -- Multiply a limb vector with a limb and store the result in
+ * a second limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "asm-common-aarch64.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, x0
+ * mpi_ptr_t s1_ptr, x1
+ * mpi_size_t s1_size, w2
+ * mpi_limb_t s2_limb) x3
+ */
+
+.text
+
+.globl _gcry_mpih_mul_1
+ELF(.type _gcry_mpih_mul_1,%function)
+_gcry_mpih_mul_1:
+ CFI_STARTPROC()
+ and w5, w2, #3;
+ mov x4, xzr;
+
+ cbz w5, .Large_loop;
+
+.Loop:
+ ldr x5, [x1], #8;
+ sub w2, w2, #1;
+ mul x9, x5, x3;
+ umulh x10, x5, x3;
+ and w5, w2, #3;
+ adds x4, x4, x9;
+ str x4, [x0], #8;
+ adc x4, x10, xzr;
+
+ cbz w2, .Lend;
+ cbnz w5, .Loop;
+
+.Large_loop:
+ ldp x5, x6, [x1];
+ sub w2, w2, #4;
+
+ mul x9, x5, x3;
+ ldp x7, x8, [x1, #16];
+ umulh x10, x5, x3;
+ add x1, x1, #32;
+
+ adds x4, x4, x9;
+ str x4, [x0], #8;
+ mul x11, x6, x3;
+ adc x4, x10, xzr;
+
+ umulh x12, x6, x3;
+
+ adds x4, x4, x11;
+ str x4, [x0], #8;
+ mul x13, x7, x3;
+ adc x4, x12, xzr;
+
+ umulh x14, x7, x3;
+
+ adds x4, x4, x13;
+ str x4, [x0], #8;
+ mul x15, x8, x3;
+ adc x4, x14, xzr;
+
+ umulh x16, x8, x3;
+
+ adds x4, x4, x15;
+ str x4, [x0], #8;
+ adc x4, x16, xzr;
+
+ cbnz w2, .Large_loop;
+
+.Lend:
+ mov x0, x4;
+ ret;
+ CFI_ENDPROC()
+ELF(.size _gcry_mpih_mul_1,.-_gcry_mpih_mul_1;)
diff --git a/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul2.S
new file mode 100644
index 0000000000..aa0e5a2d5c
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul2.S
@@ -0,0 +1,111 @@
+/* ARM64 mul_2 -- Multiply a limb vector with a limb and add the result to
+ * a second limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "asm-common-aarch64.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, x0
+ * mpi_ptr_t s1_ptr, x1
+ * mpi_size_t s1_size, w2
+ * mpi_limb_t s2_limb) x3
+ */
+
+.text
+
+.globl _gcry_mpih_addmul_1
+ELF(.type _gcry_mpih_addmul_1,%function)
+_gcry_mpih_addmul_1:
+ CFI_STARTPROC()
+ and w5, w2, #3;
+ mov x6, xzr;
+ mov x7, xzr;
+
+ cbz w5, .Large_loop;
+
+.Loop:
+ ldr x5, [x1], #8;
+
+ mul x12, x5, x3;
+ ldr x4, [x0];
+ umulh x13, x5, x3;
+ sub w2, w2, #1;
+
+ adds x12, x12, x4;
+ and w5, w2, #3;
+ adc x13, x13, x7;
+ adds x12, x12, x6;
+ str x12, [x0], #8;
+ adc x6, x7, x13;
+
+ cbz w2, .Lend;
+ cbnz w5, .Loop;
+
+.Large_loop:
+ ldp x5, x9, [x1], #16;
+ sub w2, w2, #4;
+ ldp x4, x8, [x0];
+
+ mul x12, x5, x3;
+ umulh x13, x5, x3;
+
+ adds x12, x12, x4;
+ mul x14, x9, x3;
+ adc x13, x13, x7;
+ adds x12, x12, x6;
+ umulh x15, x9, x3;
+ str x12, [x0], #8;
+ adc x6, x7, x13;
+
+ adds x14, x14, x8;
+ ldp x5, x9, [x1], #16;
+ adc x15, x15, x7;
+ adds x14, x14, x6;
+ mul x12, x5, x3;
+ str x14, [x0], #8;
+ ldp x4, x8, [x0];
+ umulh x13, x5, x3;
+ adc x6, x7, x15;
+
+ adds x12, x12, x4;
+ mul x14, x9, x3;
+ adc x13, x13, x7;
+ adds x12, x12, x6;
+ umulh x15, x9, x3;
+ str x12, [x0], #8;
+ adc x6, x7, x13;
+
+ adds x14, x14, x8;
+ adc x15, x15, x7;
+ adds x14, x14, x6;
+ str x14, [x0], #8;
+ adc x6, x7, x15;
+
+ cbnz w2, .Large_loop;
+
+.Lend:
+ mov x0, x6;
+ ret;
+ CFI_ENDPROC()
+ELF(.size _gcry_mpih_addmul_1,.-_gcry_mpih_addmul_1;)
diff --git a/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul3.S
new file mode 100644
index 0000000000..5a40b354c2
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/aarch64/mpih-mul3.S
@@ -0,0 +1,124 @@
+/* ARM mul_3 -- Multiply a limb vector with a limb and subtract the result
+ * from a second limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "asm-common-aarch64.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, x0
+ * mpi_ptr_t s1_ptr, x1
+ * mpi_size_t s1_size, w2
+ * mpi_limb_t s2_limb) x3
+ */
+
+.text
+
+.globl _gcry_mpih_submul_1
+ELF(.type _gcry_mpih_submul_1,%function)
+_gcry_mpih_submul_1:
+ CFI_STARTPROC()
+ and w5, w2, #3;
+ mov x7, xzr;
+ cbz w5, .Large_loop;
+
+ subs xzr, xzr, xzr;
+
+.Loop:
+ ldr x4, [x1], #8;
+ cinc x7, x7, cc;
+ ldr x5, [x0];
+ sub w2, w2, #1;
+
+ mul x6, x4, x3;
+ subs x5, x5, x7;
+ umulh x4, x4, x3;
+ and w10, w2, #3;
+
+ cset x7, cc;
+ subs x5, x5, x6;
+ add x7, x7, x4;
+ str x5, [x0], #8;
+
+ cbz w2, .Loop_end;
+ cbnz w10, .Loop;
+
+ cinc x7, x7, cc;
+
+.Large_loop:
+ ldp x4, x8, [x1], #16;
+ sub w2, w2, #4;
+ ldp x5, x9, [x0];
+
+ mul x6, x4, x3;
+ subs x5, x5, x7;
+ umulh x4, x4, x3;
+
+ cset x7, cc;
+ subs x5, x5, x6;
+ mul x6, x8, x3;
+ add x7, x7, x4;
+ str x5, [x0], #8;
+ cinc x7, x7, cc;
+
+ umulh x8, x8, x3;
+
+ subs x9, x9, x7;
+ cset x7, cc;
+ subs x9, x9, x6;
+ ldp x4, x10, [x1], #16;
+ str x9, [x0], #8;
+ add x7, x7, x8;
+ ldp x5, x9, [x0];
+ cinc x7, x7, cc;
+
+ mul x6, x4, x3;
+ subs x5, x5, x7;
+ umulh x4, x4, x3;
+
+ cset x7, cc;
+ subs x5, x5, x6;
+ mul x6, x10, x3;
+ add x7, x7, x4;
+ str x5, [x0], #8;
+ cinc x7, x7, cc;
+
+ umulh x10, x10, x3;
+
+ subs x9, x9, x7;
+ cset x7, cc;
+ subs x9, x9, x6;
+ add x7, x7, x10;
+ str x9, [x0], #8;
+ cinc x7, x7, cc;
+
+ cbnz w2, .Large_loop;
+
+ mov x0, x7;
+ ret;
+
+.Loop_end:
+ cinc x0, x7, cc;
+ ret;
+ CFI_ENDPROC()
+ELF(.size _gcry_mpih_submul_1,.-_gcry_mpih_submul_1;)
diff --git a/comm/third_party/libgcrypt/mpi/aarch64/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/aarch64/mpih-sub1.S
new file mode 100644
index 0000000000..4f279a1230
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/aarch64/mpih-sub1.S
@@ -0,0 +1,74 @@
+/* ARM64 sub_n -- Subtract two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "asm-common-aarch64.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, x0
+ * mpi_ptr_t s1_ptr, x1
+ * mpi_ptr_t s2_ptr, x2
+ * mpi_size_t size) w3
+ */
+
+.text
+
+.globl _gcry_mpih_sub_n
+ELF(.type _gcry_mpih_sub_n,%function)
+_gcry_mpih_sub_n:
+ CFI_STARTPROC()
+ and w5, w3, #3;
+ subs xzr, xzr, xzr; /* prepare carry flag for sub */
+
+ cbz w5, .Large_loop;
+
+.Loop:
+ ldr x4, [x1], #8;
+ sub w3, w3, #1;
+ ldr x11, [x2], #8;
+ and w5, w3, #3;
+ sbcs x4, x4, x11;
+ str x4, [x0], #8;
+ cbz w3, .Lend;
+ cbnz w5, .Loop;
+
+.Large_loop:
+ ldp x4, x6, [x1], #16;
+ ldp x5, x7, [x2], #16;
+ ldp x8, x10, [x1], #16;
+ ldp x9, x11, [x2], #16;
+ sub w3, w3, #4;
+ sbcs x4, x4, x5;
+ sbcs x6, x6, x7;
+ sbcs x8, x8, x9;
+ sbcs x10, x10, x11;
+ stp x4, x6, [x0], #16;
+ stp x8, x10, [x0], #16;
+ cbnz w3, .Large_loop;
+
+.Lend:
+ cset x0, cc;
+ ret;
+ CFI_ENDPROC()
+ELF(.size _gcry_mpih_sub_n,.-_gcry_mpih_sub_n;)
diff --git a/comm/third_party/libgcrypt/mpi/alpha/README b/comm/third_party/libgcrypt/mpi/alpha/README
new file mode 100644
index 0000000000..00addfd396
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/README
@@ -0,0 +1,53 @@
+This directory contains mpn functions optimized for DEC Alpha processors.
+
+RELEVANT OPTIMIZATION ISSUES
+
+EV4
+
+1. This chip has very limited store bandwidth. The on-chip L1 cache is
+write-through, and a cache line is transferred from the store buffer to the
+off-chip L2 in as much 15 cycles on most systems. This delay hurts
+mpn_add_n, mpn_sub_n, mpn_lshift, and mpn_rshift.
+
+2. Pairing is possible between memory instructions and integer arithmetic
+instructions.
+
+3. mulq and umulh is documented to have a latency of 23 cycles, but 2 of
+these cycles are pipelined. Thus, multiply instructions can be issued at a
+rate of one each 21nd cycle.
+
+EV5
+
+1. The memory bandwidth of this chip seems excellent, both for loads and
+stores. Even when the working set is larger than the on-chip L1 and L2
+caches, the performance remain almost unaffected.
+
+2. mulq has a measured latency of 13 cycles and an issue rate of 1 each 8th
+cycle. umulh has a measured latency of 15 cycles and an issue rate of 1
+each 10th cycle. But the exact timing is somewhat confusing.
+
+3. mpn_add_n. With 4-fold unrolling, we need 37 instructions, whereof 12
+ are memory operations. This will take at least
+ ceil(37/2) [dual issue] + 1 [taken branch] = 20 cycles
+ We have 12 memory cycles, plus 4 after-store conflict cycles, or 16 data
+ cache cycles, which should be completely hidden in the 20 issue cycles.
+ The computation is inherently serial, with these dependencies:
+ addq
+ / \
+ addq cmpult
+ | |
+ cmpult |
+ \ /
+ or
+ I.e., there is a 4 cycle path for each limb, making 16 cycles the absolute
+ minimum. We could replace the `or' with a cmoveq/cmovne, which would save
+ a cycle on EV5, but that might waste a cycle on EV4. Also, cmov takes 2
+ cycles.
+ addq
+ / \
+ addq cmpult
+ | \
+ cmpult -> cmovne
+
+STATUS
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/distfiles b/comm/third_party/libgcrypt/mpi/alpha/distfiles
new file mode 100644
index 0000000000..f2ab9fc3c1
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/distfiles
@@ -0,0 +1,11 @@
+README
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+
+udiv-qrnnd.S
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/mpih-add1.S b/comm/third_party/libgcrypt/mpi/alpha/mpih-add1.S
new file mode 100644
index 0000000000..50dbb2b9d2
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/mpih-add1.S
@@ -0,0 +1,124 @@
+/* alpha add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ * Copyright (C) 1995, 1998, 2001, 2002 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
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($16)
+ * mpi_ptr_t s1_ptr, ($17)
+ * mpi_ptr_t s2_ptr, ($18)
+ * mpi_size_t size) ($19)
+ */
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_add_n
+ .ent _gcry_mpih_add_n
+_gcry_mpih_add_n:
+ .frame $30,0,$26,0
+
+ ldq $3,0($17)
+ ldq $4,0($18)
+
+ subq $19,1,$19
+ and $19,4-1,$2 # number of limbs in first loop
+ bis $31,$31,$0
+ beq $2,.L0 # if multiple of 4 limbs, skip first loop
+
+ subq $19,$2,$19
+
+.Loop0: subq $2,1,$2
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ addq $17,8,$17
+ addq $18,8,$18
+ bis $5,$5,$3
+ bis $6,$6,$4
+ addq $16,8,$16
+ bne $2,.Loop0
+
+.L0: beq $19,.Lend
+
+ .align 3
+.Loop: subq $19,4,$19
+
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ ldq $3,16($17)
+ addq $6,$0,$6
+ ldq $4,16($18)
+ cmpult $6,$0,$1
+ addq $5,$6,$6
+ cmpult $6,$5,$0
+ stq $6,8($16)
+ or $0,$1,$0
+
+ ldq $5,24($17)
+ addq $4,$0,$4
+ ldq $6,24($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,16($16)
+ or $0,$1,$0
+
+ ldq $3,32($17)
+ addq $6,$0,$6
+ ldq $4,32($18)
+ cmpult $6,$0,$1
+ addq $5,$6,$6
+ cmpult $6,$5,$0
+ stq $6,24($16)
+ or $0,$1,$0
+
+ addq $17,32,$17
+ addq $18,32,$18
+ addq $16,32,$16
+ bne $19,.Loop
+
+.Lend: addq $4,$0,$4
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_add_n
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/alpha/mpih-lshift.S
new file mode 100644
index 0000000000..ded4b15c00
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/mpih-lshift.S
@@ -0,0 +1,122 @@
+/* alpha - left shift
+ *
+ * Copyright (C) 1994, 1995, 1998, 2001,
+ * 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (r16)
+ * mpi_ptr_t up, (r17)
+ * mpi_size_t usize, (r18)
+ * unsigned cnt) (r19)
+ *
+ * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
+ * it would take 4 cycles/limb. It should be possible to get down to 3
+ * cycles/limb since both ldq and stq can be paired with the other used
+ * instructions. But there are many restrictions in the 21064 pipeline that
+ * makes it hard, if not impossible, to get down to 3 cycles/limb:
+ *
+ * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
+ * 2. Only aligned instruction pairs can be paired.
+ * 3. The store buffer or silo might not be able to deal with the bandwidth.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_lshift
+ .ent _gcry_mpih_lshift
+_gcry_mpih_lshift:
+ .frame $30,0,$26,0
+
+ s8addq $18,$17,$17 # make r17 point at end of s1
+ ldq $4,-8($17) # load first limb
+ subq $17,8,$17
+ subq $31,$19,$7
+ s8addq $18,$16,$16 # make r16 point at end of RES
+ subq $18,1,$18
+ and $18,4-1,$20 # number of limbs in first loop
+ srl $4,$7,$0 # compute function result
+
+ beq $20,.L0
+ subq $18,$20,$18
+
+ .align 3
+.Loop0:
+ ldq $3,-8($17)
+ subq $16,8,$16
+ subq $17,8,$17
+ subq $20,1,$20
+ sll $4,$19,$5
+ srl $3,$7,$6
+ bis $3,$3,$4
+ bis $5,$6,$8
+ stq $8,0($16)
+ bne $20,.Loop0
+
+.L0: beq $18,.Lend
+
+ .align 3
+.Loop: ldq $3,-8($17)
+ subq $16,32,$16
+ subq $18,4,$18
+ sll $4,$19,$5
+ srl $3,$7,$6
+
+ ldq $4,-16($17)
+ sll $3,$19,$1
+ bis $5,$6,$8
+ stq $8,24($16)
+ srl $4,$7,$2
+
+ ldq $3,-24($17)
+ sll $4,$19,$5
+ bis $1,$2,$8
+ stq $8,16($16)
+ srl $3,$7,$6
+
+ ldq $4,-32($17)
+ sll $3,$19,$1
+ bis $5,$6,$8
+ stq $8,8($16)
+ srl $4,$7,$2
+
+ subq $17,32,$17
+ bis $1,$2,$8
+ stq $8,0($16)
+
+ bgt $18,.Loop
+
+.Lend: sll $4,$19,$8
+ stq $8,-8($16)
+ ret $31,($26),1
+ .end _gcry_mpih_lshift
+
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/alpha/mpih-mul1.S
new file mode 100644
index 0000000000..cd91b10499
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/mpih-mul1.S
@@ -0,0 +1,90 @@
+/* Alpha 21064 mpih-mul1.S -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_size_t s1_size, (r18)
+ * mpi_limb_t s2_limb) (r19)
+ *
+ * This code runs at 42 cycles/limb on the EV4 and 18 cycles/limb on the EV5.
+ *
+ * To improve performance for long multiplications, we would use
+ * 'fetch' for S1 and 'fetch_m' for RES. It's not obvious how to use
+ * these instructions without slowing down the general code: 1. We can
+ * only have two prefetches in operation at any time in the Alpha
+ * architecture. 2. There will seldom be any special alignment
+ * between RES_PTR and S1_PTR. Maybe we can simply divide the current
+ * loop into an inner and outer loop, having the inner loop handle
+ * exactly one prefetch block?
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_mul_1
+ .ent _gcry_mpih_mul_1 2
+_gcry_mpih_mul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ bic $31,$31,$4 # clear cy_limb
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,Lend1 # jump if size was == 1
+ ldq $2,8($17) # $2 = s1_limb
+ subq $18,1,$18 # size--
+ stq $3,0($16)
+ beq $18,Lend2 # jump if size was == 2
+
+ .align 3
+Loop: mulq $2,$19,$3 # $3 = prod_low
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,16($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ stq $3,8($16)
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $16,8,$16 # res_ptr++
+ bne $18,Loop
+
+Lend2: mulq $2,$19,$3 # $3 = prod_low
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ stq $3,8($16)
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+Lend1: stq $3,0($16)
+ ret $31,($26),1
+
+ .end _gcry_mpih_mul_1
+
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/alpha/mpih-mul2.S
new file mode 100644
index 0000000000..5eb6b98be4
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/mpih-mul2.S
@@ -0,0 +1,97 @@
+/* Alpha 21064 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_size_t s1_size, (r18)
+ * mpi_limb_t s2_limb) (r19)
+ *
+ * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
+ */
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_addmul_1
+ .ent _gcry_mpih_addmul_1 2
+_gcry_mpih_addmul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,.Lend1 # jump if size was == 1
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ addq $5,$3,$3
+ cmpult $3,$5,$4
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ beq $18,.Lend2 # jump if size was == 2
+
+ .align 3
+.Loop: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ addq $5,$0,$0 # combine carries
+ bne $18,.Loop
+
+.Lend2: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $5,$0,$0 # combine carries
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+.Lend1: addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $0,$5,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_addmul_1
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/alpha/mpih-mul3.S
new file mode 100644
index 0000000000..7d5d2afe41
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/mpih-mul3.S
@@ -0,0 +1,95 @@
+/* Alpha 21064 submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r16 )
+ * mpi_ptr_t s1_ptr, (r17 )
+ * mpi_size_t s1_size, (r18 )
+ * mpi_limb_t s2_limb) (r19 )
+ *
+ * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_submul_1
+ .ent _gcry_mpih_submul_1 2
+_gcry_mpih_submul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,.Lend1 # jump if size was == 1
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ subq $5,$3,$3
+ cmpult $5,$3,$4
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ beq $18,.Lend2 # jump if size was == 2
+
+ .align 3
+.Loop: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ addq $5,$0,$0 # combine carries
+ bne $18,.Loop
+
+.Lend2: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $5,$0,$0 # combine carries
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+.Lend1: subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $0,$5,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_submul_1
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/alpha/mpih-rshift.S
new file mode 100644
index 0000000000..f0c9814388
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/mpih-rshift.S
@@ -0,0 +1,118 @@
+/* alpha rshift
+ * Copyright (C) 1994, 1995, 1998, 1999,
+ * 2000, 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (r16)
+ * mpi_ptr_t up, (r17)
+ * mpi_size_t usize, (r18)
+ * unsigned cnt) (r19)
+ *
+ * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
+ * it would take 4 cycles/limb. It should be possible to get down to 3
+ * cycles/limb since both ldq and stq can be paired with the other used
+ * instructions. But there are many restrictions in the 21064 pipeline that
+ * makes it hard, if not impossible, to get down to 3 cycles/limb:
+ *
+ * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
+ * 2. Only aligned instruction pairs can be paired.
+ * 3. The store buffer or silo might not be able to deal with the bandwidth.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_rshift
+ .ent _gcry_mpih_rshift
+_gcry_mpih_rshift:
+ .frame $30,0,$26,0
+
+ ldq $4,0($17) # load first limb
+ addq $17,8,$17
+ subq $31,$19,$7
+ subq $18,1,$18
+ and $18,4-1,$20 # number of limbs in first loop
+ sll $4,$7,$0 # compute function result
+
+ beq $20,.R0
+ subq $18,$20,$18
+
+ .align 3
+.Roop0:
+ ldq $3,0($17)
+ addq $16,8,$16
+ addq $17,8,$17
+ subq $20,1,$20
+ srl $4,$19,$5
+ sll $3,$7,$6
+ bis $3,$3,$4
+ bis $5,$6,$8
+ stq $8,-8($16)
+ bne $20,.Roop0
+
+.R0: beq $18,.Rend
+
+ .align 3
+.Roop: ldq $3,0($17)
+ addq $16,32,$16
+ subq $18,4,$18
+ srl $4,$19,$5
+ sll $3,$7,$6
+
+ ldq $4,8($17)
+ srl $3,$19,$1
+ bis $5,$6,$8
+ stq $8,-32($16)
+ sll $4,$7,$2
+
+ ldq $3,16($17)
+ srl $4,$19,$5
+ bis $1,$2,$8
+ stq $8,-24($16)
+ sll $3,$7,$6
+
+ ldq $4,24($17)
+ srl $3,$19,$1
+ bis $5,$6,$8
+ stq $8,-16($16)
+ sll $4,$7,$2
+
+ addq $17,32,$17
+ bis $1,$2,$8
+ stq $8,-8($16)
+
+ bgt $18,.Roop
+
+.Rend: srl $4,$19,$8
+ stq $8,0($16)
+ ret $31,($26),1
+ .end _gcry_mpih_rshift
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/alpha/mpih-sub1.S
new file mode 100644
index 0000000000..9a644468cd
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/mpih-sub1.S
@@ -0,0 +1,124 @@
+/* Alpha sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ * Copyright (C) 1995, 1998,
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_ptr_t s2_ptr, (r18)
+ * mpi_size_t size) (r19)
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_sub_n
+ .ent _gcry_mpih_sub_n
+_gcry_mpih_sub_n:
+ .frame $30,0,$26,0
+
+ ldq $3,0($17)
+ ldq $4,0($18)
+
+ subq $19,1,$19
+ and $19,4-1,$2 # number of limbs in first loop
+ bis $31,$31,$0
+ beq $2,.L0 # if multiple of 4 limbs, skip first loop
+
+ subq $19,$2,$19
+
+.Loop0: subq $2,1,$2
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ addq $17,8,$17
+ addq $18,8,$18
+ bis $5,$5,$3
+ bis $6,$6,$4
+ addq $16,8,$16
+ bne $2,.Loop0
+
+.L0: beq $19,.Lend
+
+ .align 3
+.Loop: subq $19,4,$19
+
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ ldq $3,16($17)
+ addq $6,$0,$6
+ ldq $4,16($18)
+ cmpult $6,$0,$1
+ subq $5,$6,$6
+ cmpult $5,$6,$0
+ stq $6,8($16)
+ or $0,$1,$0
+
+ ldq $5,24($17)
+ addq $4,$0,$4
+ ldq $6,24($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,16($16)
+ or $0,$1,$0
+
+ ldq $3,32($17)
+ addq $6,$0,$6
+ ldq $4,32($18)
+ cmpult $6,$0,$1
+ subq $5,$6,$6
+ cmpult $5,$6,$0
+ stq $6,24($16)
+ or $0,$1,$0
+
+ addq $17,32,$17
+ addq $18,32,$18
+ addq $16,32,$16
+ bne $19,.Loop
+
+.Lend: addq $4,$0,$4
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_sub_n
+
+
diff --git a/comm/third_party/libgcrypt/mpi/alpha/udiv-qrnnd.S b/comm/third_party/libgcrypt/mpi/alpha/udiv-qrnnd.S
new file mode 100644
index 0000000000..dd0c52d7de
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/alpha/udiv-qrnnd.S
@@ -0,0 +1,159 @@
+/* Alpha 21064 __udiv_qrnnd
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __udiv_qrnnd
+ .ent __udiv_qrnnd
+__udiv_qrnnd:
+ .frame $30,0,$26,0
+ .prologue 0
+#define cnt $2
+#define tmp $3
+#define rem_ptr $16
+#define n1 $17
+#define n0 $18
+#define d $19
+#define qb $20
+
+ ldiq cnt,16
+ blt d,.Largedivisor
+
+.Loop1: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,.Loop1
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+.Largedivisor:
+ and n0,1,$4
+
+ srl n0,1,n0
+ sll n1,63,tmp
+ or tmp,n0,n0
+ srl n1,1,n1
+
+ and d,1,$6
+ srl d,1,$5
+ addq $5,$6,$5
+
+.Loop2: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,.Loop2
+
+ addq n1,n1,n1
+ addq $4,n1,n1
+ bne $6,.LOdd
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+.LOdd:
+ /* q' in n0. r' in n1 */
+ addq n1,n0,n1
+ cmpult n1,n0,tmp # tmp := carry from addq
+ beq tmp,.LLp6
+ addq n0,1,n0
+ subq n1,d,n1
+.LLp6: cmpult n1,d,tmp
+ bne tmp,.LLp7
+ addq n0,1,n0
+ subq n1,d,n1
+.LLp7:
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+ .end __udiv_qrnnd
diff --git a/comm/third_party/libgcrypt/mpi/amd64/distfiles b/comm/third_party/libgcrypt/mpi/amd64/distfiles
new file mode 100644
index 0000000000..44aad5f829
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/distfiles
@@ -0,0 +1,9 @@
+func_abi.h
+mpih-add1.S
+mpih-lshift.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-rshift.S
+mpih-sub1.S
+mpi-asm-defs.h
diff --git a/comm/third_party/libgcrypt/mpi/amd64/func_abi.h b/comm/third_party/libgcrypt/mpi/amd64/func_abi.h
new file mode 100644
index 0000000000..a60363e4e4
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/func_abi.h
@@ -0,0 +1,56 @@
+#include <config.h>
+
+#ifdef __x86_64__
+#ifdef HAVE_GCC_ASM_CFI_DIRECTIVES
+# define CFI_STARTPROC() .cfi_startproc
+# define CFI_ENDPROC() .cfi_endproc
+# define CFI_ADJUST_CFA_OFFSET(off) .cfi_adjust_cfa_offset off
+# define CFI_REL_OFFSET(reg,off) .cfi_rel_offset reg, off
+# define CFI_RESTORE(reg) .cfi_restore reg
+
+# define CFI_PUSH(reg) \
+ CFI_ADJUST_CFA_OFFSET(8); CFI_REL_OFFSET(reg, 0)
+# define CFI_POP(reg) \
+ CFI_ADJUST_CFA_OFFSET(-8); CFI_RESTORE(reg)
+#else
+# define CFI_STARTPROC()
+# define CFI_ENDPROC()
+# define CFI_ADJUST_CFA_OFFSET(off)
+# define CFI_REL_OFFSET(reg,off)
+# define CFI_RESTORE(reg)
+
+# define CFI_PUSH(reg)
+# define CFI_POP(reg)
+#endif
+#endif
+
+#ifdef USE_MS_ABI
+ /* Store registers and move four first input arguments from MS ABI to
+ * SYSV ABI. */
+ #define FUNC_ENTRY() \
+ CFI_STARTPROC(); \
+ pushq %rsi; \
+ CFI_PUSH(%rsi); \
+ pushq %rdi; \
+ CFI_PUSH(%rdi); \
+ movq %rdx, %rsi; \
+ movq %rcx, %rdi; \
+ movq %r8, %rdx; \
+ movq %r9, %rcx;
+
+ /* Restore registers. */
+ #define FUNC_EXIT() \
+ popq %rdi; \
+ CFI_POP(%rdi); \
+ popq %rsi; \
+ CFI_POP(%rsi); \
+ ret; \
+ CFI_ENDPROC();
+#else
+ #define FUNC_ENTRY() \
+ CFI_STARTPROC();
+
+ #define FUNC_EXIT() \
+ ret; \
+ CFI_ENDPROC();
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/amd64/mpi-asm-defs.h b/comm/third_party/libgcrypt/mpi/amd64/mpi-asm-defs.h
new file mode 100644
index 0000000000..65190653bc
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/mpi-asm-defs.h
@@ -0,0 +1,4 @@
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG_LONG)
diff --git a/comm/third_party/libgcrypt/mpi/amd64/mpih-add1.S b/comm/third_party/libgcrypt/mpi/amd64/mpih-add1.S
new file mode 100644
index 0000000000..157e5f1e0d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/mpih-add1.S
@@ -0,0 +1,64 @@
+/* AMD64 (x86_64) add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, rdi
+ * mpi_ptr_t s1_ptr, rsi
+ * mpi_ptr_t s2_ptr, rdx
+ * mpi_size_t size) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ FUNC_ENTRY()
+ leaq (%rsi,%rcx,8), %rsi
+ leaq (%rdi,%rcx,8), %rdi
+ leaq (%rdx,%rcx,8), %rdx
+ negq %rcx
+ xorl %eax, %eax /* clear cy */
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rcx,8), %rax
+ movq (%rdx,%rcx,8), %r10
+ adcq %r10, %rax
+ movq %rax, (%rdi,%rcx,8)
+ incq %rcx
+ jne .Loop
+
+ movq %rcx, %rax /* zero %rax */
+ adcq %rax, %rax
+ FUNC_EXIT()
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/amd64/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/amd64/mpih-lshift.S
new file mode 100644
index 0000000000..76e9408fcd
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/mpih-lshift.S
@@ -0,0 +1,79 @@
+/* AMD64 (x86_64) lshift -- Left shift a limb vector and store
+ * result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, rdi
+ * mpi_ptr_t up, rsi
+ * mpi_size_t usize, rdx
+ * unsigned cnt) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+ FUNC_ENTRY()
+ /* Note: %xmm6 and %xmm7 not used for WIN64 ABI compatibility. */
+ movq -8(%rsi,%rdx,8), %xmm4
+ movd %ecx, %xmm1
+ movl $64, %eax
+ subl %ecx, %eax
+ movd %eax, %xmm0
+ movdqa %xmm4, %xmm3
+ psrlq %xmm0, %xmm4
+ movd %xmm4, %rax
+ subq $2, %rdx
+ jl .Lendo
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rdx,8), %xmm5
+ movdqa %xmm5, %xmm2
+ psrlq %xmm0, %xmm5
+ psllq %xmm1, %xmm3
+ por %xmm5, %xmm3
+ movq %xmm3, 8(%rdi,%rdx,8)
+ je .Lende
+ movq -8(%rsi,%rdx,8), %xmm4
+ movdqa %xmm4, %xmm3
+ psrlq %xmm0, %xmm4
+ psllq %xmm1, %xmm2
+ por %xmm4, %xmm2
+ movq %xmm2, (%rdi,%rdx,8)
+ subq $2, %rdx
+ jge .Loop
+
+.Lendo: movdqa %xmm3, %xmm2
+.Lende: psllq %xmm1, %xmm2
+ movq %xmm2, (%rdi)
+ FUNC_EXIT()
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/amd64/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/amd64/mpih-mul1.S
new file mode 100644
index 0000000000..67ab47eab6
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/mpih-mul1.S
@@ -0,0 +1,67 @@
+/* AMD64 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+
+
+ TEXT
+ ALIGN(5)
+ .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ FUNC_ENTRY()
+ movq %rdx, %r11
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+
+.Loop: movq (%rsi,%r11,8), %rax
+ mulq %rcx
+ addq %r8, %rax
+ movl $0, %r8d
+ adcq %rdx, %r8
+ movq %rax, (%rdi,%r11,8)
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ FUNC_EXIT()
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/amd64/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/amd64/mpih-mul2.S
new file mode 100644
index 0000000000..1aa4fa0ac8
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/mpih-mul2.S
@@ -0,0 +1,66 @@
+/* AMD64 addmul2 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+ TEXT
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+ FUNC_ENTRY()
+ movq %rdx, %r11
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+ xorl %r10d, %r10d
+
+ ALIGN(3) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%r11,8), %rax
+ mulq %rcx
+ addq (%rdi,%r11,8), %rax
+ adcq %r10, %rdx
+ addq %r8, %rax
+ movq %r10, %r8
+ movq %rax, (%rdi,%r11,8)
+ adcq %rdx, %r8
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ FUNC_EXIT()
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/amd64/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/amd64/mpih-mul3.S
new file mode 100644
index 0000000000..bc41c4eb97
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/mpih-mul3.S
@@ -0,0 +1,67 @@
+/* AMD64 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+ TEXT
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+ FUNC_ENTRY()
+ movq %rdx, %r11
+ leaq (%rsi,%r11,8), %rsi
+ leaq (%rdi,%r11,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+
+ ALIGN(3) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%r11,8), %rax
+ movq (%rdi,%r11,8), %r10
+ mulq %rcx
+ subq %r8, %r10
+ movl $0, %r8d
+ adcl %r8d, %r8d
+ subq %rax, %r10
+ adcq %rdx, %r8
+ movq %r10, (%rdi,%r11,8)
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ FUNC_EXIT()
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/amd64/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/amd64/mpih-rshift.S
new file mode 100644
index 0000000000..d5e27974ed
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/mpih-rshift.S
@@ -0,0 +1,82 @@
+/* AMD64 (x86_64) rshift -- Right shift a limb vector and store
+ * result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, rdi
+ * mpi_ptr_t up, rsi
+ * mpi_size_t usize, rdx
+ * unsigned cnt) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ FUNC_ENTRY()
+ /* Note: %xmm6 and %xmm7 not used for WIN64 ABI compatibility. */
+ movq (%rsi), %xmm4
+ movd %ecx, %xmm1
+ movl $64, %eax
+ subl %ecx, %eax
+ movd %eax, %xmm0
+ movdqa %xmm4, %xmm3
+ psllq %xmm0, %xmm4
+ movd %xmm4, %rax
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %rdx
+ addq $2, %rdx
+ jg .Lendo
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq -8(%rsi,%rdx,8), %xmm5
+ movdqa %xmm5, %xmm2
+ psllq %xmm0, %xmm5
+ psrlq %xmm1, %xmm3
+ por %xmm5, %xmm3
+ movq %xmm3, -16(%rdi,%rdx,8)
+ je .Lende
+ movq (%rsi,%rdx,8), %xmm4
+ movdqa %xmm4, %xmm3
+ psllq %xmm0, %xmm4
+ psrlq %xmm1, %xmm2
+ por %xmm4, %xmm2
+ movq %xmm2, -8(%rdi,%rdx,8)
+ addq $2, %rdx
+ jle .Loop
+
+.Lendo: movdqa %xmm3, %xmm2
+.Lende: psrlq %xmm1, %xmm2
+ movq %xmm2, -8(%rdi)
+ FUNC_EXIT()
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/amd64/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/amd64/mpih-sub1.S
new file mode 100644
index 0000000000..ccf6496315
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/amd64/mpih-sub1.S
@@ -0,0 +1,63 @@
+/* AMD64 (x86_64) sub_n -- Subtract two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, rdi
+ * mpi_ptr_t s1_ptr, rsi
+ * mpi_ptr_t s2_ptr, rdx
+ * mpi_size_t size) rcx
+ */
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+ FUNC_ENTRY()
+ leaq (%rsi,%rcx,8), %rsi
+ leaq (%rdi,%rcx,8), %rdi
+ leaq (%rdx,%rcx,8), %rdx
+ negq %rcx
+ xorl %eax, %eax /* clear cy */
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rcx,8), %rax
+ movq (%rdx,%rcx,8), %r10
+ sbbq %r10, %rax
+ movq %rax, (%rdi,%rcx,8)
+ incq %rcx
+ jne .Loop
+
+ movq %rcx, %rax /* zero %rax */
+ adcq %rax, %rax
+ FUNC_EXIT()
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/arm/distfiles b/comm/third_party/libgcrypt/mpi/arm/distfiles
new file mode 100644
index 0000000000..27a2ca5272
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/arm/distfiles
@@ -0,0 +1,6 @@
+mpi-asm-defs.h
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-sub1.S
diff --git a/comm/third_party/libgcrypt/mpi/arm/mpi-asm-defs.h b/comm/third_party/libgcrypt/mpi/arm/mpi-asm-defs.h
new file mode 100644
index 0000000000..047d1f5a72
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/arm/mpi-asm-defs.h
@@ -0,0 +1,4 @@
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
diff --git a/comm/third_party/libgcrypt/mpi/arm/mpih-add1.S b/comm/third_party/libgcrypt/mpi/arm/mpih-add1.S
new file mode 100644
index 0000000000..09e8b3b2bb
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/arm/mpih-add1.S
@@ -0,0 +1,76 @@
+/* ARM add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Note: This code is heavily based on the GNU MP Library (version 4.2.1).
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.syntax unified
+.arm
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, %r0
+ * mpi_ptr_t s1_ptr, %r1
+ * mpi_ptr_t s2_ptr, %r2
+ * mpi_size_t size) %r3
+ */
+
+.text
+
+.globl _gcry_mpih_add_n
+.type _gcry_mpih_add_n,%function
+_gcry_mpih_add_n:
+ push {%r4, %r5, %r6, %r7, %r8, %r9, %r10, %lr};
+ cmn %r0, #0; /* clear carry flag */
+
+ tst %r3, #3;
+ beq .Large_loop;
+
+.Loop:
+ ldr %r4, [%r1], #4;
+ sub %r3, #1;
+ ldr %lr, [%r2], #4;
+ adcs %r4, %lr;
+ tst %r3, #3;
+ str %r4, [%r0], #4;
+ bne .Loop;
+
+ teq %r3, #0;
+ beq .Lend;
+
+.Large_loop:
+ ldm %r1!, {%r4, %r6, %r8, %r10};
+ ldm %r2!, {%r5, %r7, %r9, %lr};
+ sub %r3, #4;
+ adcs %r4, %r5;
+ adcs %r6, %r7;
+ adcs %r8, %r9;
+ adcs %r10, %lr;
+ teq %r3, #0;
+ stm %r0!, {%r4, %r6, %r8, %r10};
+ bne .Large_loop;
+
+.Lend:
+ adc %r0, %r3, #0;
+ pop {%r4, %r5, %r6, %r7, %r8, %r9, %r10, %pc};
+.size _gcry_mpih_add_n,.-_gcry_mpih_add_n;
diff --git a/comm/third_party/libgcrypt/mpi/arm/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/arm/mpih-mul1.S
new file mode 100644
index 0000000000..c2e2854bf1
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/arm/mpih-mul1.S
@@ -0,0 +1,80 @@
+/* ARM mul_1 -- Multiply a limb vector with a limb and store the result in
+ * a second limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Note: This code is heavily based on the GNU MP Library (version 4.2.1).
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.syntax unified
+.arm
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, %r0
+ * mpi_ptr_t s1_ptr, %r1
+ * mpi_size_t s1_size, %r2
+ * mpi_limb_t s2_limb) %r3
+ */
+
+.text
+
+.globl _gcry_mpih_mul_1
+.type _gcry_mpih_mul_1,%function
+_gcry_mpih_mul_1:
+ push {%r4, %r5, %r6, %r7, %r8, %r9, %r10, %r11, %lr};
+ mov %r4, #0;
+
+ tst %r2, #3;
+ beq .Large_loop;
+
+.Loop:
+ ldr %r5, [%r1], #4;
+ mov %lr, #0;
+ umlal %r4, %lr, %r5, %r3;
+ sub %r2, #1;
+ str %r4, [%r0], #4;
+ tst %r2, #3;
+ mov %r4, %lr;
+ bne .Loop;
+
+ teq %r2, #0;
+ beq .Lend;
+
+.Large_loop:
+ ldm %r1!, {%r5, %r6, %r7, %r8};
+ mov %r9, #0;
+ mov %r10, #0;
+ umlal %r4, %r9, %r5, %r3;
+ mov %r11, #0;
+ umlal %r9, %r10, %r6, %r3;
+ str %r4, [%r0], #4;
+ mov %r4, #0;
+ umlal %r10, %r11, %r7, %r3;
+ subs %r2, #4;
+ umlal %r11, %r4, %r8, %r3;
+ stm %r0!, {%r9, %r10, %r11};
+ bne .Large_loop;
+
+.Lend:
+ mov %r0, %r4;
+ pop {%r4, %r5, %r6, %r7, %r8, %r9, %r10, %r11, %pc};
+.size _gcry_mpih_mul_1,.-_gcry_mpih_mul_1;
diff --git a/comm/third_party/libgcrypt/mpi/arm/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/arm/mpih-mul2.S
new file mode 100644
index 0000000000..bce932e9b0
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/arm/mpih-mul2.S
@@ -0,0 +1,94 @@
+/* ARM mul_2 -- Multiply a limb vector with a limb and add the result to
+ * a second limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Note: This code is heavily based on the GNU MP Library (version 4.2.1).
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.syntax unified
+.arm
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, %r0
+ * mpi_ptr_t s1_ptr, %r1
+ * mpi_size_t s1_size, %r2
+ * mpi_limb_t s2_limb) %r3
+ */
+
+.text
+
+.globl _gcry_mpih_addmul_1
+.type _gcry_mpih_addmul_1,%function
+_gcry_mpih_addmul_1:
+ push {%r4, %r5, %r6, %r8, %r10, %lr};
+ mov %lr, #0;
+ cmn %r0, #0; /* clear carry flag */
+
+ tst %r2, #3;
+ beq .Large_loop;
+.Loop:
+ ldr %r5, [%r1], #4;
+ ldr %r4, [%r0];
+ sub %r2, #1;
+ adcs %r4, %lr;
+ mov %lr, #0;
+ umlal %r4, %lr, %r5, %r3;
+ tst %r2, #3;
+ str %r4, [%r0], #4;
+ bne .Loop;
+
+ teq %r2, #0;
+ beq .Lend;
+
+.Large_loop:
+ ldr %r5, [%r1], #4;
+ ldm %r0, {%r4, %r6, %r8, %r10};
+
+ sub %r2, #4;
+ adcs %r4, %lr;
+ mov %lr, #0;
+ umlal %r4, %lr, %r5, %r3;
+
+ ldr %r5, [%r1], #4;
+ adcs %r6, %lr;
+ mov %lr, #0;
+ umlal %r6, %lr, %r5, %r3;
+
+ ldr %r5, [%r1], #4;
+ adcs %r8, %lr;
+ mov %lr, #0;
+ umlal %r8, %lr, %r5, %r3;
+
+ ldr %r5, [%r1], #4;
+ adcs %r10, %lr;
+ mov %lr, #0;
+ umlal %r10, %lr, %r5, %r3;
+
+ teq %r2, #0;
+ stm %r0!, {%r4, %r6, %r8, %r10};
+ bne .Large_loop;
+
+.Lend:
+ adc %r0, %lr, #0;
+ pop {%r4, %r5, %r6, %r8, %r10, %pc};
+.size _gcry_mpih_addmul_1,.-_gcry_mpih_addmul_1;
diff --git a/comm/third_party/libgcrypt/mpi/arm/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/arm/mpih-mul3.S
new file mode 100644
index 0000000000..33326c7873
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/arm/mpih-mul3.S
@@ -0,0 +1,100 @@
+/* ARM mul_3 -- Multiply a limb vector with a limb and subtract the result
+ * from a second limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Note: This code is heavily based on the GNU MP Library (version 4.2.1).
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.syntax unified
+.arm
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, %r0
+ * mpi_ptr_t s1_ptr, %r1
+ * mpi_size_t s1_size, %r2
+ * mpi_limb_t s2_limb) %r3
+ */
+
+.text
+
+.globl _gcry_mpih_submul_1
+.type _gcry_mpih_submul_1,%function
+_gcry_mpih_submul_1:
+ push {%r4, %r5, %r6, %r8, %r9, %r10, %lr};
+ mov %lr, #0;
+ cmp %r0, #0; /* prepare carry flag for sbc */
+
+ tst %r2, #3;
+ beq .Large_loop;
+.Loop:
+ ldr %r5, [%r1], #4;
+ mov %r4, %lr;
+ mov %lr, #0;
+ ldr %r6, [%r0];
+ umlal %r4, %lr, %r5, %r3;
+ sub %r2, #1;
+ sbcs %r4, %r6, %r4;
+ tst %r2, #3;
+ str %r4, [%r0], #4;
+ bne .Loop;
+
+ teq %r2, #0;
+ beq .Lend;
+
+.Large_loop:
+ ldr %r5, [%r1], #4;
+ mov %r9, #0;
+ ldr %r4, [%r0, #0];
+
+ umlal %lr, %r9, %r5, %r3;
+ ldr %r6, [%r0, #4];
+ ldr %r5, [%r1], #4;
+ sbcs %r4, %r4, %lr;
+
+ mov %lr, #0;
+ umlal %r9, %lr, %r5, %r3;
+ ldr %r8, [%r0, #8];
+ ldr %r5, [%r1], #4;
+ sbcs %r6, %r6, %r9;
+
+ mov %r9, #0;
+ umlal %lr, %r9, %r5, %r3;
+ ldr %r10, [%r0, #12];
+ ldr %r5, [%r1], #4;
+ sbcs %r8, %r8, %lr;
+
+ mov %lr, #0;
+ umlal %r9, %lr, %r5, %r3;
+ sub %r2, #4;
+ sbcs %r10, %r10, %r9;
+
+ teq %r2, #0;
+ stm %r0!, {%r4, %r6, %r8, %r10};
+ bne .Large_loop;
+
+.Lend:
+ it cc
+ movcc %r2, #1;
+ add %r0, %lr, %r2;
+ pop {%r4, %r5, %r6, %r8, %r9, %r10, %pc};
+.size _gcry_mpih_submul_1,.-_gcry_mpih_submul_1;
diff --git a/comm/third_party/libgcrypt/mpi/arm/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/arm/mpih-sub1.S
new file mode 100644
index 0000000000..593e3cded6
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/arm/mpih-sub1.S
@@ -0,0 +1,77 @@
+/* ARM sub_n -- Subtract two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Note: This code is heavily based on the GNU MP Library (version 4.2.1).
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.syntax unified
+.arm
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, %r0
+ * mpi_ptr_t s1_ptr, %r1
+ * mpi_ptr_t s2_ptr, %r2
+ * mpi_size_t size) %r3
+ */
+
+.text
+
+.globl _gcry_mpih_sub_n
+.type _gcry_mpih_sub_n,%function
+_gcry_mpih_sub_n:
+ push {%r4, %r5, %r6, %r7, %r8, %r9, %r10, %lr};
+ cmp %r0, #0; /* prepare carry flag for sub */
+
+ tst %r3, #3;
+ beq .Large_loop;
+
+.Loop:
+ ldr %r4, [%r1], #4;
+ sub %r3, #1;
+ ldr %lr, [%r2], #4;
+ sbcs %r4, %lr;
+ tst %r3, #3;
+ str %r4, [%r0], #4;
+ bne .Loop;
+
+ teq %r3, #0;
+ beq .Lend;
+
+.Large_loop:
+ ldm %r1!, {%r4, %r6, %r8, %r10};
+ sub %r3, #4;
+ ldm %r2!, {%r5, %r7, %r9, %lr};
+ sbcs %r4, %r5;
+ sbcs %r6, %r7;
+ sbcs %r8, %r9;
+ sbcs %r10, %lr;
+ teq %r3, #0;
+ stm %r0!, {%r4, %r6, %r8, %r10};
+ bne .Large_loop;
+
+.Lend:
+ sbc %r0, %r3, #0;
+ neg %r0, %r0;
+ pop {%r4, %r5, %r6, %r7, %r8, %r9, %r10, %pc};
+.size _gcry_mpih_sub_n,.-_gcry_mpih_sub_n;
diff --git a/comm/third_party/libgcrypt/mpi/asm-common-aarch64.h b/comm/third_party/libgcrypt/mpi/asm-common-aarch64.h
new file mode 100644
index 0000000000..cf4bdb8529
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/asm-common-aarch64.h
@@ -0,0 +1,26 @@
+/* asm-common-aarch64.h - Common macros for AArch64 assembly
+ *
+ * Copyright (C) 2018 Martin Storsjö <martin@martin.st>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MPI_ASM_COMMON_AARCH64_H
+#define MPI_ASM_COMMON_AARCH64_H
+
+#include "../cipher/asm-common-aarch64.h"
+
+#endif /* MPI_ASM_COMMON_AARCH64_H */
diff --git a/comm/third_party/libgcrypt/mpi/config.links b/comm/third_party/libgcrypt/mpi/config.links
new file mode 100644
index 0000000000..e4fc4fc4fd
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/config.links
@@ -0,0 +1,470 @@
+# config.links - helper for ../configure -*- mode: sh -*-
+# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright (C) 2012 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+# sourced by ../configure to get the list of files to link
+# this should set $mpi_ln_list.
+# Note: this is called from the above directory.
+#
+# Reguired variables:
+# $ac_cv_sys_symbol_underscore
+# $gcry_cv_gcc_arm_platform_as_ok
+
+mpi_sflags=
+mpi_extra_modules=
+mpi_cpu_arch=
+
+test -d ./mpi || mkdir ./mpi
+
+# We grep the list of modules from the Makefile so that
+# we don't need to maintain them here.
+mpi_standard_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
+ if( $3 != "O" ) print $2 }' $srcdir/mpi/Makefile.am`
+mpi_optional_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
+ if( $3 == "O" ) print $2 }' $srcdir/mpi/Makefile.am`
+
+
+echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
+echo "/* Host: ${host} */" >>./mpi/asm-syntax.h
+
+case "${host}" in
+ i[34567]86*-*-openbsd[12]* | \
+ i[34567]86*-*-openbsd3.[0123]*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ mpi_cpu_arch="x86"
+ ;;
+ i[3467]86*-*-openbsd* | \
+ i[3467]86*-*-freebsd*-elf | \
+ i[3467]86*-*-freebsd[3-9]* | \
+ i[3467]86*-*-freebsd[12][0-9]*| \
+ i[3467]86*-*-freebsdelf* | \
+ i[3467]86*-*-netbsd* | \
+ i[3467]86*-*-k*bsd*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ mpi_cpu_arch="x86"
+ ;;
+ i586*-*-openbsd* | \
+ i586*-*-freebsd*-elf | \
+ i586*-*-freebsd[3-9]* | \
+ i586*-*-freebsd[12][0-9]*| \
+ i586*-*-freebsdelf* | \
+ i586*-*-netbsd* | \
+ i586*-*-k*bsd* | \
+ pentium-*-netbsd* | \
+ pentiumpro-*-netbsd*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ mpi_cpu_arch="x86"
+ ;;
+ i[34]86*-*-bsdi4*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ mpi_cpu_arch="x86"
+ ;;
+ i[3467]86*-*-linuxaout* | \
+ i[3467]86*-*-linuxoldld* | \
+ i[3467]86*-*-*bsd*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ mpi_cpu_arch="x86"
+ ;;
+ i586*-*-linuxaout* | \
+ i586*-*-linuxoldld* | \
+ i586*-*-*bsd*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ mpi_cpu_arch="x86"
+ ;;
+ i[3467]86*-msdosdjgpp* | \
+ i[34]86*-apple-darwin*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ mpi_cpu_arch="x86"
+ ;;
+ i586*-msdosdjgpp* | \
+ i[567]86*-apple-darwin*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ mpi_cpu_arch="x86"
+ ;;
+ i[3467]86*-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ mpi_cpu_arch="x86"
+ ;;
+ i586*-*-* | \
+ pentium-*-* | \
+ pentiumpro-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ mpi_cpu_arch="x86"
+ ;;
+ x86_64-apple-darwin*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/amd64/func_abi.h >>./mpi/asm-syntax.h
+ path="amd64"
+ mpi_cpu_arch="x86"
+ ;;
+ x86_64-*mingw32*)
+ echo '#define USE_MS_ABI' >>./mpi/asm-syntax.h
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/amd64/func_abi.h >>./mpi/asm-syntax.h
+ path="amd64"
+ mpi_cpu_arch="x86"
+ ;;
+ x86_64-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/amd64/func_abi.h >>./mpi/asm-syntax.h
+ path="amd64"
+ mpi_cpu_arch="x86"
+ ;;
+ alpha*-*-*)
+ echo '/* configured for alpha */' >>./mpi/asm-syntax.h
+ path="alpha"
+ mpi_extra_modules="udiv-qrnnd"
+ mpi_cpu_arch="alpha"
+ ;;
+ aarch64-*-*)
+ echo '/* configured for aarch64 */' >>./mpi/asm-syntax.h
+ path="aarch64"
+ mpi_cpu_arch="aarch64"
+ ;;
+ arm*-*-*)
+ mpi_cpu_arch="arm"
+ if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then
+ echo '/* configured for arm */' >>./mpi/asm-syntax.h
+ path="arm"
+ else
+ echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
+ path=""
+ fi
+ ;;
+ hppa7000*-*-*)
+ echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h
+ path="hppa1.1 hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ mpi_cpu_arch="hppa"
+ ;;
+ hppa1.0*-*-*)
+ echo '/* configured for HPPA 1.0 */' >>./mpi/asm-syntax.h
+ path="hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ mpi_cpu_arch="hppa"
+ ;;
+ hppa*-*-*) # assume pa7100
+ echo '/* configured for HPPA (pa7100) */' >>./mpi/asm-syntax.h
+ path="pa7100 hppa1.1 hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ mpi_cpu_arch="hppa"
+ ;;
+ sparc64-*-linux-gnu)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ mpi_cpu_arch="sparc"
+ ;;
+ sparc64-sun-solaris2*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ mpi_cpu_arch="sparc"
+ ;;
+ sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*)
+ # There are no sparc64 assembler modules that work on the
+ # *BSDs, so use the generic C functions.
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ mpi_cpu_arch="sparc"
+ ;;
+ sparc64*-*-*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ mpi_cpu_arch="sparc"
+ ;;
+ sparc9*-*-* | \
+ ultrasparc*-*-* )
+ echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h
+ path="sparc32v8 sparc32"
+ mpi_cpu_arch="sparc"
+ ;;
+ sparc8*-*-* | \
+ microsparc*-*-*)
+ echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h
+ path="sparc32v8 sparc32"
+ mpi_cpu_arch="sparc"
+ ;;
+ supersparc*-*-*)
+ echo '/* configured for supersparc */' >>./mpi/asm-syntax.h
+ path="supersparc sparc32v8 sparc32"
+ mpi_extra_modules="udiv"
+ mpi_cpu_arch="sparc"
+ ;;
+ sparc*-*-*)
+ echo '/* configured for sparc */' >>./mpi/asm-syntax.h
+ path="sparc32"
+ mpi_extra_modules="udiv"
+ mpi_cpu_arch="sparc"
+ ;;
+ mips[34]*-*-* | \
+ mips*-*-irix6*)
+ echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h
+ path="mips3"
+ mpi_cpu_arch="mips"
+ ;;
+ mips*-*-*)
+ echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h
+ path="mips2"
+ mpi_cpu_arch="mips"
+ ;;
+ s390x*-*-*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ mpi_cpu_arch="s390x"
+ ;;
+
+ # Motorola 68k configurations. Let m68k mean 68020-68040.
+ # mc68000 or mc68060 configurations need to be specified explicitly
+ m680[234]0*-*-linuxaout* | \
+ m68k*-*-linuxaout*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68020 m68k"
+ mpi_cpu_arch="m68k"
+ ;;
+ m68060*-*-linuxaout*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k"
+ mpi_cpu_arch="m68k"
+ ;;
+ m680[234]0*-*-linux* | \
+ m68k*-*-linux*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ mpi_cpu_arch="m68k"
+ ;;
+ m68060*-*-linux*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k"
+ mpi_cpu_arch="m68k"
+ ;;
+ m68k-atari-mint)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k"
+ mpi_cpu_arch="m68k"
+ ;;
+ m68000*-*-* | \
+ m68060*-*-*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68000"
+ mpi_cpu_arch="m68k"
+ ;;
+ m680[234]0*-*-* | \
+ m68k*-*-*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68020 m68k"
+ mpi_cpu_arch="m68k"
+ ;;
+
+ powerpc-apple-darwin*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ mpi_cpu_arch="ppc"
+ ;;
+
+ powerpc*-*-netbsd* | powerpc*-*-openbsd*)
+ echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ mpi_cpu_arch="ppc"
+ ;;
+
+ ppc620-*-* | \
+ powerpc64*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc64"
+ mpi_cpu_arch="ppc"
+ ;;
+ powerpc*-*-linux*)
+ echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
+ path="powerpc32"
+ mpi_cpu_arch="ppc"
+ ;;
+
+ rs6000-*-aix[456789]* | \
+ rs6000-*-aix3.2.[456789])
+ mpi_sflags="-Wa,-mpwr"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ mpi_cpu_arch="ppc"
+ ;;
+ rs6000-*-* | \
+ power-*-* | \
+ power2-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ mpi_cpu_arch="ppc"
+ ;;
+ powerpc-ibm-aix4.2.* )
+ # I am not sure about this one but a machine identified by
+ # powerpc-ibm-aix4.2.1.0 cannot use the powerpc32 code.
+ mpi_sflags="-Wa,-mpwr"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ mpi_cpu_arch="ppc"
+ ;;
+ ppc601-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="power powerpc32"
+ mpi_cpu_arch="ppc"
+ ;;
+ ppc60[234]*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ mpi_cpu_arch="ppc"
+ ;;
+ powerpc*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ mpi_cpu_arch="ppc"
+ ;;
+ *)
+ echo '/* Platform not known */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+esac
+
+# If asm modules are disabled reset the found variables but keep
+# mpi_cpu_arch.
+if test "$try_asm_modules" != "yes" ; then
+ echo '/* Assembler modules disabled on request */' >./mpi/asm-syntax.h
+ path=""
+ mpi_sflags=""
+ mpi_extra_modules=""
+ mpi_cpu_arch="disabled"
+fi
+
+# Make sure that mpi_cpu_arch is not the empty string.
+if test x"$mpi_cpu_arch" = x ; then
+ mpi_cpu_arch="unknown"
+fi
+
+# Add .note.gnu.property section for Intel CET in assembler sources
+# when CET is enabled. */
+if test x"$mpi_cpu_arch" = xx86 ; then
+ cat <<EOF >> ./mpi/asm-syntax.h
+
+#if defined(__ASSEMBLER__) && defined(__CET__)
+# include <cet.h>
+#endif
+EOF
+fi
+
+# Make sysdep.h
+echo '/* created by config.links - do not edit */' >./mpi/sysdep.h
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+ cat <<EOF >>./mpi/sysdep.h
+#if __STDC__
+#define C_SYMBOL_NAME(name) _##name
+#else
+#define C_SYMBOL_NAME(name) _/**/name
+#endif
+EOF
+else
+ cat <<EOF >>./mpi/sysdep.h
+#define C_SYMBOL_NAME(name) name
+EOF
+fi
+
+
+# Figure the required modules out
+mpi_required_modules=$mpi_standard_modules
+if test "$mpi_extra_modules" != ""; then
+ for fn in $mpi_extra_modules; do
+ for i in $mpi_optional_modules; do
+ if test "$fn" = "$i" ; then
+ mpi_required_modules="$mpi_required_modules $fn"
+ fi
+ done
+ done
+fi
+
+# Try to get file to link from the assembler subdirectory and
+# if this fails get it from the generic subdirectory.
+mpi_ln_list=
+mpi_mod_list=
+path=`echo "$mpi_extra_path $path generic" | tr ':' ' '`
+echo '/* Created by config.links - do not edit */' >./mpi/mod-source-info.h
+echo "/* Host: ${host} */" >>./mpi/mod-source-info.h
+echo "static char mod_source_info[] =" >>./mpi/mod-source-info.h
+for fn in $mpi_required_modules ; do
+ fnu=`echo $fn | sed 's/-/_/g'`
+ eval mpi_mod_c_${fnu}=no
+ eval mpi_mod_asm_${fnu}=no
+ for dir in $path ; do
+ rm -f $srcdir/mpi/$fn.[Sc]
+ if test -f $srcdir/mpi/$dir/$fn.S ; then
+ echo " \":$dir/$fn.S\"" >>./mpi/mod-source-info.h
+ mpi_ln_list="$mpi_ln_list mpi/$fn-asm.S:mpi/$dir/$fn.S"
+ eval mpi_mod_asm_${fnu}=yes
+ mpi_mod_list="$mpi_mod_list $fn"
+ break;
+ elif test -f $srcdir/mpi/$dir/$fn.c ; then
+ echo " \":$dir/$fn.c\"" >>./mpi/mod-source-info.h
+ mpi_ln_list="$mpi_ln_list mpi/$fn.c:mpi/$dir/$fn.c"
+ eval mpi_mod_c_${fnu}=yes
+ mpi_mod_list="$mpi_mod_list $fn"
+ break;
+ fi
+ done
+done
+echo " ;" >>./mpi/mod-source-info.h
+
+# Same thing for the file which defines the limb size
+path=`echo "$path generic" | tr ':' ' '`
+for dir in $path ; do
+ rm -f $srcdir/mpi/mpi-asm-defs.h
+ if test -f $srcdir/mpi/$dir/mpi-asm-defs.h ; then
+ mpi_ln_list="$mpi_ln_list mpi/mpi-asm-defs.h:mpi/$dir/mpi-asm-defs.h"
+ break;
+ fi
+done
diff --git a/comm/third_party/libgcrypt/mpi/ec-ed25519.c b/comm/third_party/libgcrypt/mpi/ec-ed25519.c
new file mode 100644
index 0000000000..acfe2a69f5
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/ec-ed25519.c
@@ -0,0 +1,37 @@
+/* ec-ed25519.c - Ed25519 optimized elliptic curve functions
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+#include "context.h"
+#include "ec-context.h"
+
+
+void
+_gcry_mpi_ec_ed25519_mod (gcry_mpi_t a)
+{
+ (void)a;
+
+}
diff --git a/comm/third_party/libgcrypt/mpi/ec-internal.h b/comm/third_party/libgcrypt/mpi/ec-internal.h
new file mode 100644
index 0000000000..759335aad0
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/ec-internal.h
@@ -0,0 +1,25 @@
+/* ec-internal.h - Internal declarations of ec*.c
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_EC_INTERNAL_H
+#define GCRY_EC_INTERNAL_H
+
+void _gcry_mpi_ec_ed25519_mod (gcry_mpi_t a);
+
+#endif /*GCRY_EC_INTERNAL_H*/
diff --git a/comm/third_party/libgcrypt/mpi/ec.c b/comm/third_party/libgcrypt/mpi/ec.c
new file mode 100644
index 0000000000..659bb5caf1
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/ec.c
@@ -0,0 +1,2062 @@
+/* ec.c - Elliptic Curve functions
+ * Copyright (C) 2007 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ec-internal.h"
+
+extern void reverse_buffer (unsigned char *buffer, unsigned int length);
+
+#define point_init(a) _gcry_mpi_point_init ((a))
+#define point_free(a) _gcry_mpi_point_free_parts ((a))
+
+
+/* Print a point using the log functions. If CTX is not NULL affine
+ coordinates will be printed. */
+void
+_gcry_mpi_point_log (const char *name, mpi_point_t point, mpi_ec_t ctx)
+{
+ gcry_mpi_t x, y;
+ char buf[100];
+
+ if (!point)
+ {
+ snprintf (buf, sizeof buf - 1, "%s.*", name);
+ log_mpidump (buf, NULL);
+ return;
+ }
+ snprintf (buf, sizeof buf - 1, "%s.X", name);
+
+ if (ctx)
+ {
+ x = mpi_new (0);
+ y = mpi_new (0);
+ }
+ if (!ctx || _gcry_mpi_ec_get_affine (x, y, point, ctx))
+ {
+ log_mpidump (buf, point->x);
+ buf[strlen(buf)-1] = 'Y';
+ log_mpidump (buf, point->y);
+ buf[strlen(buf)-1] = 'Z';
+ log_mpidump (buf, point->z);
+ }
+ else
+ {
+ buf[strlen(buf)-1] = 'x';
+ log_mpidump (buf, x);
+ buf[strlen(buf)-1] = 'y';
+ log_mpidump (buf, y);
+
+ }
+ if (ctx)
+ {
+ _gcry_mpi_release (x);
+ _gcry_mpi_release (y);
+ }
+}
+
+
+/* Create a new point option. NBITS gives the size in bits of one
+ coordinate; it is only used to pre-allocate some resources and
+ might also be passed as 0 to use a default value. */
+mpi_point_t
+_gcry_mpi_point_new (unsigned int nbits)
+{
+ mpi_point_t p;
+
+ (void)nbits; /* Currently not used. */
+
+ p = xmalloc (sizeof *p);
+ _gcry_mpi_point_init (p);
+ return p;
+}
+
+
+/* Release the point object P. P may be NULL. */
+void
+_gcry_mpi_point_release (mpi_point_t p)
+{
+ if (p)
+ {
+ _gcry_mpi_point_free_parts (p);
+ xfree (p);
+ }
+}
+
+
+/* Initialize the fields of a point object. gcry_mpi_point_free_parts
+ may be used to release the fields. */
+void
+_gcry_mpi_point_init (mpi_point_t p)
+{
+ p->x = mpi_new (0);
+ p->y = mpi_new (0);
+ p->z = mpi_new (0);
+}
+
+
+/* Release the parts of a point object. */
+void
+_gcry_mpi_point_free_parts (mpi_point_t p)
+{
+ mpi_free (p->x); p->x = NULL;
+ mpi_free (p->y); p->y = NULL;
+ mpi_free (p->z); p->z = NULL;
+}
+
+
+/* Set the value from S into D. */
+static void
+point_set (mpi_point_t d, mpi_point_t s)
+{
+ mpi_set (d->x, s->x);
+ mpi_set (d->y, s->y);
+ mpi_set (d->z, s->z);
+}
+
+
+/* Return a copy of POINT. */
+gcry_mpi_point_t
+_gcry_mpi_point_copy (gcry_mpi_point_t point)
+{
+ mpi_point_t newpoint;
+
+ newpoint = _gcry_mpi_point_new (0);
+ if (point)
+ point_set (newpoint, point);
+
+ return newpoint;
+}
+
+
+static void
+point_resize (mpi_point_t p, mpi_ec_t ctx)
+{
+ size_t nlimbs = ctx->p->nlimbs;
+
+ mpi_resize (p->x, nlimbs);
+ p->x->nlimbs = nlimbs;
+ mpi_resize (p->z, nlimbs);
+ p->z->nlimbs = nlimbs;
+
+ if (ctx->model != MPI_EC_MONTGOMERY)
+ {
+ mpi_resize (p->y, nlimbs);
+ p->y->nlimbs = nlimbs;
+ }
+}
+
+
+static void
+point_swap_cond (mpi_point_t d, mpi_point_t s, unsigned long swap,
+ mpi_ec_t ctx)
+{
+ mpi_swap_cond (d->x, s->x, swap);
+ if (ctx->model != MPI_EC_MONTGOMERY)
+ mpi_swap_cond (d->y, s->y, swap);
+ mpi_swap_cond (d->z, s->z, swap);
+}
+
+
+/* Set the projective coordinates from POINT into X, Y, and Z. If a
+ coordinate is not required, X, Y, or Z may be passed as NULL. */
+void
+_gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ mpi_point_t point)
+{
+ if (x)
+ mpi_set (x, point->x);
+ if (y)
+ mpi_set (y, point->y);
+ if (z)
+ mpi_set (z, point->z);
+}
+
+
+/* Set the projective coordinates from POINT into X, Y, and Z and
+ release POINT. If a coordinate is not required, X, Y, or Z may be
+ passed as NULL. */
+void
+_gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ mpi_point_t point)
+{
+ mpi_snatch (x, point->x);
+ mpi_snatch (y, point->y);
+ mpi_snatch (z, point->z);
+ xfree (point);
+}
+
+
+/* Set the projective coordinates from X, Y, and Z into POINT. If a
+ coordinate is given as NULL, the value 0 is stored into point. If
+ POINT is given as NULL a new point object is allocated. Returns
+ POINT or the newly allocated point object. */
+mpi_point_t
+_gcry_mpi_point_set (mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
+{
+ if (!point)
+ point = mpi_point_new (0);
+
+ if (x)
+ mpi_set (point->x, x);
+ else
+ mpi_clear (point->x);
+ if (y)
+ mpi_set (point->y, y);
+ else
+ mpi_clear (point->y);
+ if (z)
+ mpi_set (point->z, z);
+ else
+ mpi_clear (point->z);
+
+ return point;
+}
+
+
+/* Set the projective coordinates from X, Y, and Z into POINT. If a
+ coordinate is given as NULL, the value 0 is stored into point. If
+ POINT is given as NULL a new point object is allocated. The
+ coordinates X, Y, and Z are released. Returns POINT or the newly
+ allocated point object. */
+mpi_point_t
+_gcry_mpi_point_snatch_set (mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
+{
+ if (!point)
+ point = mpi_point_new (0);
+
+ if (x)
+ mpi_snatch (point->x, x);
+ else
+ mpi_clear (point->x);
+ if (y)
+ mpi_snatch (point->y, y);
+ else
+ mpi_clear (point->y);
+ if (z)
+ mpi_snatch (point->z, z);
+ else
+ mpi_clear (point->z);
+
+ return point;
+}
+
+
+/* W = W mod P. */
+static void
+ec_mod (gcry_mpi_t w, mpi_ec_t ec)
+{
+ if (0 && ec->dialect == ECC_DIALECT_ED25519)
+ _gcry_mpi_ec_ed25519_mod (w);
+ else if (ec->t.p_barrett)
+ _gcry_mpi_mod_barrett (w, w, ec->t.p_barrett);
+ else
+ _gcry_mpi_mod (w, w, ec->p);
+}
+
+static void
+ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_add (w, u, v);
+ ec_mod (w, ctx);
+}
+
+static void
+ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec)
+{
+ mpi_sub (w, u, v);
+ while (w->sign)
+ mpi_add (w, w, ec->p);
+ /*ec_mod (w, ec);*/
+}
+
+static void
+ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_mul (w, u, v);
+ ec_mod (w, ctx);
+}
+
+/* W = 2 * U mod P. */
+static void
+ec_mul2 (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx)
+{
+ mpi_lshift (w, u, 1);
+ ec_mod (w, ctx);
+}
+
+static void
+ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
+ mpi_ec_t ctx)
+{
+ mpi_powm (w, b, e, ctx->p);
+ /* _gcry_mpi_abs (w); */
+}
+
+
+/* Shortcut for
+ ec_powm (B, B, mpi_const (MPI_C_TWO), ctx);
+ for easier optimization. */
+static void
+ec_pow2 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
+{
+ /* Using mpi_mul is slightly faster (at least on amd64). */
+ /* mpi_powm (w, b, mpi_const (MPI_C_TWO), ctx->p); */
+ ec_mulm (w, b, b, ctx);
+}
+
+
+/* Shortcut for
+ ec_powm (B, B, mpi_const (MPI_C_THREE), ctx);
+ for easier optimization. */
+static void
+ec_pow3 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
+{
+ mpi_powm (w, b, mpi_const (MPI_C_THREE), ctx->p);
+}
+
+
+static void
+ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx)
+{
+ if (!mpi_invm (x, a, ctx->p))
+ {
+ log_error ("ec_invm: inverse does not exist:\n");
+ log_mpidump (" a", a);
+ log_mpidump (" p", ctx->p);
+ }
+}
+
+/* Routines for 2^255 - 19. */
+
+#define LIMB_SIZE_25519 ((256+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB)
+
+static void
+ec_addm_25519 (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t wsize = LIMB_SIZE_25519;
+ mpi_limb_t n[LIMB_SIZE_25519];
+ mpi_limb_t borrow;
+
+ if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
+ log_bug ("addm_25519: different sizes\n");
+
+ memset (n, 0, sizeof n);
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ _gcry_mpih_add_n (wp, up, vp, wsize);
+ borrow = _gcry_mpih_sub_n (wp, wp, ctx->p->d, wsize);
+ mpih_set_cond (n, ctx->p->d, wsize, (borrow != 0UL));
+ _gcry_mpih_add_n (wp, wp, n, wsize);
+ wp[LIMB_SIZE_25519-1] &= ~((mpi_limb_t)1 << (255 % BITS_PER_MPI_LIMB));
+}
+
+static void
+ec_subm_25519 (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t wsize = LIMB_SIZE_25519;
+ mpi_limb_t n[LIMB_SIZE_25519];
+ mpi_limb_t borrow;
+
+ if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
+ log_bug ("subm_25519: different sizes\n");
+
+ memset (n, 0, sizeof n);
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ borrow = _gcry_mpih_sub_n (wp, up, vp, wsize);
+ mpih_set_cond (n, ctx->p->d, wsize, (borrow != 0UL));
+ _gcry_mpih_add_n (wp, wp, n, wsize);
+ wp[LIMB_SIZE_25519-1] &= ~((mpi_limb_t)1 << (255 % BITS_PER_MPI_LIMB));
+}
+
+static void
+ec_mulm_25519 (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t wsize = LIMB_SIZE_25519;
+ mpi_limb_t n[LIMB_SIZE_25519*2];
+ mpi_limb_t m[LIMB_SIZE_25519+1];
+ mpi_limb_t cy;
+ int msb;
+
+ (void)ctx;
+ if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
+ log_bug ("mulm_25519: different sizes\n");
+
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ _gcry_mpih_mul_n (n, up, vp, wsize);
+ memcpy (wp, n, wsize * BYTES_PER_MPI_LIMB);
+ wp[LIMB_SIZE_25519-1] &= ~((mpi_limb_t)1 << (255 % BITS_PER_MPI_LIMB));
+
+ memcpy (m, n+LIMB_SIZE_25519-1, (wsize+1) * BYTES_PER_MPI_LIMB);
+ _gcry_mpih_rshift (m, m, LIMB_SIZE_25519+1, (255 % BITS_PER_MPI_LIMB));
+
+ memcpy (n, m, wsize * BYTES_PER_MPI_LIMB);
+ cy = _gcry_mpih_lshift (m, m, LIMB_SIZE_25519, 4);
+ m[LIMB_SIZE_25519] = cy;
+ cy = _gcry_mpih_add_n (m, m, n, wsize);
+ m[LIMB_SIZE_25519] += cy;
+ cy = _gcry_mpih_add_n (m, m, n, wsize);
+ m[LIMB_SIZE_25519] += cy;
+ cy = _gcry_mpih_add_n (m, m, n, wsize);
+ m[LIMB_SIZE_25519] += cy;
+
+ cy = _gcry_mpih_add_n (wp, wp, m, wsize);
+ m[LIMB_SIZE_25519] += cy;
+
+ memset (m, 0, wsize * BYTES_PER_MPI_LIMB);
+ msb = (wp[LIMB_SIZE_25519-1] >> (255 % BITS_PER_MPI_LIMB));
+ m[0] = (m[LIMB_SIZE_25519] * 2 + msb) * 19;
+ wp[LIMB_SIZE_25519-1] &= ~((mpi_limb_t)1 << (255 % BITS_PER_MPI_LIMB));
+ _gcry_mpih_add_n (wp, wp, m, wsize);
+
+ m[0] = 0;
+ cy = _gcry_mpih_sub_n (wp, wp, ctx->p->d, wsize);
+ mpih_set_cond (m, ctx->p->d, wsize, (cy != 0UL));
+ _gcry_mpih_add_n (wp, wp, m, wsize);
+}
+
+static void
+ec_mul2_25519 (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx)
+{
+ ec_addm_25519 (w, u, u, ctx);
+}
+
+static void
+ec_pow2_25519 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
+{
+ ec_mulm_25519 (w, b, b, ctx);
+}
+
+/* Routines for 2^448 - 2^224 - 1. */
+
+#define LIMB_SIZE_448 ((448+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB)
+#define LIMB_SIZE_HALF_448 ((LIMB_SIZE_448+1)/2)
+
+static void
+ec_addm_448 (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t wsize = LIMB_SIZE_448;
+ mpi_limb_t n[LIMB_SIZE_448];
+ mpi_limb_t cy;
+
+ if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
+ log_bug ("addm_448: different sizes\n");
+
+ memset (n, 0, sizeof n);
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ cy = _gcry_mpih_add_n (wp, up, vp, wsize);
+ mpih_set_cond (n, ctx->p->d, wsize, (cy != 0UL));
+ _gcry_mpih_sub_n (wp, wp, n, wsize);
+}
+
+static void
+ec_subm_448 (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t wsize = LIMB_SIZE_448;
+ mpi_limb_t n[LIMB_SIZE_448];
+ mpi_limb_t borrow;
+
+ if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
+ log_bug ("subm_448: different sizes\n");
+
+ memset (n, 0, sizeof n);
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ borrow = _gcry_mpih_sub_n (wp, up, vp, wsize);
+ mpih_set_cond (n, ctx->p->d, wsize, (borrow != 0UL));
+ _gcry_mpih_add_n (wp, wp, n, wsize);
+}
+
+static void
+ec_mulm_448 (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t wsize = LIMB_SIZE_448;
+ mpi_limb_t n[LIMB_SIZE_448*2];
+ mpi_limb_t a2[LIMB_SIZE_HALF_448];
+ mpi_limb_t a3[LIMB_SIZE_HALF_448];
+ mpi_limb_t b0[LIMB_SIZE_HALF_448];
+ mpi_limb_t b1[LIMB_SIZE_HALF_448];
+ mpi_limb_t cy;
+ int i;
+#if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
+ mpi_limb_t b1_rest, a3_rest;
+#endif
+
+ if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
+ log_bug ("mulm_448: different sizes\n");
+
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ _gcry_mpih_mul_n (n, up, vp, wsize);
+
+ for (i = 0; i < (wsize + 1)/ 2; i++)
+ {
+ b0[i] = n[i];
+ b1[i] = n[i+wsize/2];
+ a2[i] = n[i+wsize];
+ a3[i] = n[i+wsize+wsize/2];
+ }
+
+#if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
+ b0[LIMB_SIZE_HALF_448-1] &= ((mpi_limb_t)1UL<<32)-1;
+ a2[LIMB_SIZE_HALF_448-1] &= ((mpi_limb_t)1UL<<32)-1;
+
+ b1_rest = 0;
+ a3_rest = 0;
+
+ for (i = (wsize + 1)/ 2 -1; i >= 0; i--)
+ {
+ mpi_limb_t b1v, a3v;
+ b1v = b1[i];
+ a3v = a3[i];
+ b1[i] = (b1_rest<<32) | (b1v >> 32);
+ a3[i] = (a3_rest<<32) | (a3v >> 32);
+ b1_rest = b1v & (((mpi_limb_t)1UL <<32)-1);
+ a3_rest = a3v & (((mpi_limb_t)1UL <<32)-1);
+ }
+#endif
+
+ cy = _gcry_mpih_add_n (b0, b0, a2, LIMB_SIZE_HALF_448);
+ cy += _gcry_mpih_add_n (b0, b0, a3, LIMB_SIZE_HALF_448);
+ for (i = 0; i < (wsize + 1)/ 2; i++)
+ wp[i] = b0[i];
+#if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
+ wp[LIMB_SIZE_HALF_448-1] &= (((mpi_limb_t)1UL <<32)-1);
+#endif
+
+#if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
+ cy = b0[LIMB_SIZE_HALF_448-1] >> 32;
+#endif
+
+ cy = _gcry_mpih_add_1 (b1, b1, LIMB_SIZE_HALF_448, cy);
+ cy += _gcry_mpih_add_n (b1, b1, a2, LIMB_SIZE_HALF_448);
+ cy += _gcry_mpih_add_n (b1, b1, a3, LIMB_SIZE_HALF_448);
+ cy += _gcry_mpih_add_n (b1, b1, a3, LIMB_SIZE_HALF_448);
+#if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
+ b1_rest = 0;
+ for (i = (wsize + 1)/ 2 -1; i >= 0; i--)
+ {
+ mpi_limb_t b1v = b1[i];
+ b1[i] = (b1_rest<<32) | (b1v >> 32);
+ b1_rest = b1v & (((mpi_limb_t)1UL <<32)-1);
+ }
+ wp[LIMB_SIZE_HALF_448-1] |= (b1_rest << 32);
+#endif
+ for (i = 0; i < wsize / 2; i++)
+ wp[i+(wsize + 1) / 2] = b1[i];
+
+#if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
+ cy = b1[LIMB_SIZE_HALF_448-1];
+#endif
+
+ memset (n, 0, wsize * BYTES_PER_MPI_LIMB);
+
+#if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
+ n[LIMB_SIZE_HALF_448-1] = cy << 32;
+#else
+ n[LIMB_SIZE_HALF_448] = cy;
+#endif
+ n[0] = cy;
+ _gcry_mpih_add_n (wp, wp, n, wsize);
+
+ memset (n, 0, wsize * BYTES_PER_MPI_LIMB);
+ cy = _gcry_mpih_sub_n (wp, wp, ctx->p->d, wsize);
+ mpih_set_cond (n, ctx->p->d, wsize, (cy != 0UL));
+ _gcry_mpih_add_n (wp, wp, n, wsize);
+}
+
+static void
+ec_mul2_448 (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx)
+{
+ ec_addm_448 (w, u, u, ctx);
+}
+
+static void
+ec_pow2_448 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
+{
+ ec_mulm_448 (w, b, b, ctx);
+}
+
+struct field_table {
+ const char *p;
+
+ /* computation routines for the field. */
+ void (* addm) (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx);
+ void (* subm) (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx);
+ void (* mulm) (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx);
+ void (* mul2) (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx);
+ void (* pow2) (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx);
+};
+
+static const struct field_table field_table[] = {
+ {
+ "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+ ec_addm_25519,
+ ec_subm_25519,
+ ec_mulm_25519,
+ ec_mul2_25519,
+ ec_pow2_25519
+ },
+ {
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ ec_addm_448,
+ ec_subm_448,
+ ec_mulm_448,
+ ec_mul2_448,
+ ec_pow2_448
+ },
+ { NULL, NULL, NULL, NULL, NULL, NULL },
+};
+
+/* Force recomputation of all helper variables. */
+void
+_gcry_mpi_ec_get_reset (mpi_ec_t ec)
+{
+ ec->t.valid.a_is_pminus3 = 0;
+ ec->t.valid.two_inv_p = 0;
+}
+
+
+/* Accessor for helper variable. */
+static int
+ec_get_a_is_pminus3 (mpi_ec_t ec)
+{
+ gcry_mpi_t tmp;
+
+ if (!ec->t.valid.a_is_pminus3)
+ {
+ ec->t.valid.a_is_pminus3 = 1;
+ tmp = mpi_alloc_like (ec->p);
+ mpi_sub_ui (tmp, ec->p, 3);
+ ec->t.a_is_pminus3 = !mpi_cmp (ec->a, tmp);
+ mpi_free (tmp);
+ }
+
+ return ec->t.a_is_pminus3;
+}
+
+
+/* Accessor for helper variable. */
+static gcry_mpi_t
+ec_get_two_inv_p (mpi_ec_t ec)
+{
+ if (!ec->t.valid.two_inv_p)
+ {
+ ec->t.valid.two_inv_p = 1;
+ if (!ec->t.two_inv_p)
+ ec->t.two_inv_p = mpi_alloc (0);
+ ec_invm (ec->t.two_inv_p, mpi_const (MPI_C_TWO), ec);
+ }
+ return ec->t.two_inv_p;
+}
+
+
+static const char *const curve25519_bad_points[] = {
+ "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed",
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x00b8495f16056286fdb1329ceb8d09da6ac49ff1fae35616aeb8413b7c7aebe0",
+ "0x57119fd0dd4e22d8868e1c58c45c44045bef839c55b1d0b1248c50a3bc959c5f",
+ "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec",
+ "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee",
+ NULL
+};
+
+
+static const char *const curve448_bad_points[] = {
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "0x00000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000",
+ "0x00000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000001",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "00000000000000000000000000000000000000000000000000000000",
+ NULL
+};
+
+static const char *const *bad_points_table[] = {
+ curve25519_bad_points,
+ curve448_bad_points,
+};
+
+static gcry_mpi_t
+scanval (const char *string)
+{
+ gpg_err_code_t rc;
+ gcry_mpi_t val;
+
+ rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (rc)
+ log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc));
+ return val;
+}
+
+
+/* This function initialized a context for elliptic curve based on the
+ field GF(p). P is the prime specifying this field, A is the first
+ coefficient. CTX is expected to be zeroized. */
+static void
+ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model,
+ enum ecc_dialects dialect,
+ int flags,
+ gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+ int i;
+ static int use_barrett;
+
+ if (!use_barrett)
+ {
+ if (getenv ("GCRYPT_BARRETT"))
+ use_barrett = 1;
+ else
+ use_barrett = -1;
+ }
+
+ /* Fixme: Do we want to check some constraints? e.g. a < p */
+
+ ctx->model = model;
+ ctx->dialect = dialect;
+ ctx->flags = flags;
+ ctx->nbits = mpi_get_nbits (p);
+ ctx->p = mpi_copy (p);
+ ctx->a = mpi_copy (a);
+ ctx->b = mpi_copy (b);
+
+ ctx->t.p_barrett = use_barrett > 0? _gcry_mpi_barrett_init (ctx->p, 0):NULL;
+
+ _gcry_mpi_ec_get_reset (ctx);
+
+ if (model == MPI_EC_MONTGOMERY)
+ {
+ for (i=0; i< DIM(bad_points_table); i++)
+ {
+ gcry_mpi_t p_candidate = scanval (bad_points_table[i][0]);
+ int match_p = !mpi_cmp (ctx->p, p_candidate);
+ int j;
+
+ mpi_free (p_candidate);
+ if (!match_p)
+ continue;
+
+ for (j=0; i< DIM(ctx->t.scratch) && bad_points_table[i][j]; j++)
+ ctx->t.scratch[j] = scanval (bad_points_table[i][j]);
+ }
+ }
+ else
+ {
+ /* Allocate scratch variables. */
+ for (i=0; i< DIM(ctx->t.scratch); i++)
+ ctx->t.scratch[i] = mpi_alloc_like (ctx->p);
+ }
+
+ ctx->addm = ec_addm;
+ ctx->subm = ec_subm;
+ ctx->mulm = ec_mulm;
+ ctx->mul2 = ec_mul2;
+ ctx->pow2 = ec_pow2;
+
+ for (i=0; field_table[i].p; i++)
+ {
+ gcry_mpi_t f_p;
+ gpg_err_code_t rc;
+
+ rc = _gcry_mpi_scan (&f_p, GCRYMPI_FMT_HEX, field_table[i].p, 0, NULL);
+ if (rc)
+ log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc));
+
+ if (!mpi_cmp (p, f_p))
+ {
+ ctx->addm = field_table[i].addm;
+ ctx->subm = field_table[i].subm;
+ ctx->mulm = field_table[i].mulm;
+ ctx->mul2 = field_table[i].mul2;
+ ctx->pow2 = field_table[i].pow2;
+ _gcry_mpi_release (f_p);
+
+ mpi_resize (ctx->a, ctx->p->nlimbs);
+ ctx->a->nlimbs = ctx->p->nlimbs;
+
+ mpi_resize (ctx->b, ctx->p->nlimbs);
+ ctx->b->nlimbs = ctx->p->nlimbs;
+
+ for (i=0; i< DIM(ctx->t.scratch) && ctx->t.scratch[i]; i++)
+ ctx->t.scratch[i]->nlimbs = ctx->p->nlimbs;
+
+ break;
+ }
+
+ _gcry_mpi_release (f_p);
+ }
+
+ /* Prepare for fast reduction. */
+ /* FIXME: need a test for NIST values. However it does not gain us
+ any real advantage, for 384 bits it is actually slower than using
+ mpi_mulm. */
+/* ctx->nist_nbits = mpi_get_nbits (ctx->p); */
+/* if (ctx->nist_nbits == 192) */
+/* { */
+/* for (i=0; i < 4; i++) */
+/* ctx->s[i] = mpi_new (192); */
+/* ctx->c = mpi_new (192*2); */
+/* } */
+/* else if (ctx->nist_nbits == 384) */
+/* { */
+/* for (i=0; i < 10; i++) */
+/* ctx->s[i] = mpi_new (384); */
+/* ctx->c = mpi_new (384*2); */
+/* } */
+}
+
+
+static void
+ec_deinit (void *opaque)
+{
+ mpi_ec_t ctx = opaque;
+ int i;
+
+ _gcry_mpi_barrett_free (ctx->t.p_barrett);
+
+ /* Domain parameter. */
+ mpi_free (ctx->p);
+ mpi_free (ctx->a);
+ mpi_free (ctx->b);
+ _gcry_mpi_point_release (ctx->G);
+ mpi_free (ctx->n);
+
+ /* The key. */
+ _gcry_mpi_point_release (ctx->Q);
+ mpi_free (ctx->d);
+
+ /* Private data of ec.c. */
+ mpi_free (ctx->t.two_inv_p);
+
+ for (i=0; i< DIM(ctx->t.scratch); i++)
+ mpi_free (ctx->t.scratch[i]);
+
+/* if (ctx->nist_nbits == 192) */
+/* { */
+/* for (i=0; i < 4; i++) */
+/* mpi_free (ctx->s[i]); */
+/* mpi_free (ctx->c); */
+/* } */
+/* else if (ctx->nist_nbits == 384) */
+/* { */
+/* for (i=0; i < 10; i++) */
+/* mpi_free (ctx->s[i]); */
+/* mpi_free (ctx->c); */
+/* } */
+}
+
+
+/* This function returns a new context for elliptic curve based on the
+ field GF(p). P is the prime specifying this field, A is the first
+ coefficient, B is the second coefficient, and MODEL is the model
+ for the curve. This function is only used within Libgcrypt and not
+ part of the public API.
+
+ This context needs to be released using _gcry_mpi_ec_free. */
+mpi_ec_t
+_gcry_mpi_ec_p_internal_new (enum gcry_mpi_ec_models model,
+ enum ecc_dialects dialect,
+ int flags,
+ gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+ mpi_ec_t ctx;
+
+ ctx = xcalloc (1, sizeof *ctx);
+ ec_p_init (ctx, model, dialect, flags, p, a, b);
+
+ return ctx;
+}
+
+
+/* This is a variant of _gcry_mpi_ec_p_internal_new which returns an
+ public context and does some error checking on the supplied
+ arguments. On success the new context is stored at R_CTX and 0 is
+ returned; on error NULL is stored at R_CTX and an error code is
+ returned.
+
+ The context needs to be released using gcry_ctx_release. */
+gpg_err_code_t
+_gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
+ enum gcry_mpi_ec_models model,
+ enum ecc_dialects dialect,
+ int flags,
+ gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+ gcry_ctx_t ctx;
+ mpi_ec_t ec;
+
+ *r_ctx = NULL;
+ if (!p || !a)
+ return GPG_ERR_EINVAL;
+
+ ctx = _gcry_ctx_alloc (CONTEXT_TYPE_EC, sizeof *ec, ec_deinit);
+ if (!ctx)
+ return gpg_err_code_from_syserror ();
+ ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+ ec_p_init (ec, model, dialect, flags, p, a, b);
+
+ *r_ctx = ctx;
+ return 0;
+}
+
+
+void
+_gcry_mpi_ec_free (mpi_ec_t ctx)
+{
+ if (ctx)
+ {
+ ec_deinit (ctx);
+ xfree (ctx);
+ }
+}
+
+
+gcry_mpi_t
+_gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy)
+{
+ mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+ return _gcry_ecc_get_mpi (name, ec, copy);
+}
+
+
+gcry_mpi_point_t
+_gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy)
+{
+ mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+ (void)copy; /* Not used. */
+
+ return _gcry_ecc_get_point (name, ec);
+}
+
+
+gpg_err_code_t
+_gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
+ gcry_ctx_t ctx)
+{
+ mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+ return _gcry_ecc_set_mpi (name, newvalue, ec);
+}
+
+
+gpg_err_code_t
+_gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
+ gcry_ctx_t ctx)
+{
+ mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+ return _gcry_ecc_set_point (name, newvalue, ec);
+}
+
+
+/* Given an encoded point in the MPI VALUE and a context EC, decode
+ * the point according to the context and store it in RESULT. On
+ * error an error code is return but RESULT might have been changed.
+ * If no context is given the function tries to decode VALUE by
+ * assuming a 0x04 prefixed uncompressed encoding. */
+gpg_err_code_t
+_gcry_mpi_ec_decode_point (mpi_point_t result, gcry_mpi_t value, mpi_ec_t ec)
+{
+ gpg_err_code_t rc;
+
+ if (ec
+ && (ec->dialect == ECC_DIALECT_ED25519
+ || (ec->model == MPI_EC_EDWARDS
+ && ec->dialect == ECC_DIALECT_SAFECURVE)))
+ rc = _gcry_ecc_eddsa_decodepoint (value, ec, result, NULL, NULL);
+ else if (ec && ec->model == MPI_EC_MONTGOMERY)
+ rc = _gcry_ecc_mont_decodepoint (value, ec, result);
+ else
+ rc = _gcry_ecc_sec_decodepoint (value, ec, result);
+
+ return rc;
+}
+
+
+/* Compute the affine coordinates from the projective coordinates in
+ POINT. Set them into X and Y. If one coordinate is not required,
+ X or Y may be passed as NULL. CTX is the usual context. Returns: 0
+ on success or !0 if POINT is at infinity. */
+int
+_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point,
+ mpi_ec_t ctx)
+{
+ if (!mpi_cmp_ui (point->z, 0))
+ return -1;
+
+ switch (ctx->model)
+ {
+ case MPI_EC_WEIERSTRASS: /* Using Jacobian coordinates. */
+ {
+ gcry_mpi_t z1, z2, z3;
+
+ z1 = mpi_new (0);
+ z2 = mpi_new (0);
+ ec_invm (z1, point->z, ctx); /* z1 = z^(-1) mod p */
+ ec_mulm (z2, z1, z1, ctx); /* z2 = z^(-2) mod p */
+
+ if (x)
+ ec_mulm (x, point->x, z2, ctx);
+
+ if (y)
+ {
+ z3 = mpi_new (0);
+ ec_mulm (z3, z2, z1, ctx); /* z3 = z^(-3) mod p */
+ ec_mulm (y, point->y, z3, ctx);
+ mpi_free (z3);
+ }
+
+ mpi_free (z2);
+ mpi_free (z1);
+ }
+ return 0;
+
+ case MPI_EC_MONTGOMERY:
+ {
+ if (x)
+ mpi_set (x, point->x);
+
+ if (y)
+ {
+ log_fatal ("%s: Getting Y-coordinate on %s is not supported\n",
+ "_gcry_mpi_ec_get_affine", "Montgomery");
+ return -1;
+ }
+ }
+ return 0;
+
+ case MPI_EC_EDWARDS:
+ {
+ gcry_mpi_t z;
+
+ z = mpi_new (0);
+ ec_invm (z, point->z, ctx);
+
+ mpi_resize (z, ctx->p->nlimbs);
+ z->nlimbs = ctx->p->nlimbs;
+
+ if (x)
+ {
+ mpi_resize (x, ctx->p->nlimbs);
+ x->nlimbs = ctx->p->nlimbs;
+ ctx->mulm (x, point->x, z, ctx);
+ }
+ if (y)
+ {
+ mpi_resize (y, ctx->p->nlimbs);
+ y->nlimbs = ctx->p->nlimbs;
+ ctx->mulm (y, point->y, z, ctx);
+ }
+
+ _gcry_mpi_release (z);
+ }
+ return 0;
+
+ default:
+ return -1;
+ }
+}
+
+
+
+/* RESULT = 2 * POINT (Weierstrass version). */
+static void
+dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+#define x3 (result->x)
+#define y3 (result->y)
+#define z3 (result->z)
+#define t1 (ctx->t.scratch[0])
+#define t2 (ctx->t.scratch[1])
+#define t3 (ctx->t.scratch[2])
+#define l1 (ctx->t.scratch[3])
+#define l2 (ctx->t.scratch[4])
+#define l3 (ctx->t.scratch[5])
+
+ if (!mpi_cmp_ui (point->y, 0) || !mpi_cmp_ui (point->z, 0))
+ {
+ /* P_y == 0 || P_z == 0 => [1:1:0] */
+ mpi_set_ui (x3, 1);
+ mpi_set_ui (y3, 1);
+ mpi_set_ui (z3, 0);
+ }
+ else
+ {
+ if (ec_get_a_is_pminus3 (ctx)) /* Use the faster case. */
+ {
+ /* L1 = 3(X - Z^2)(X + Z^2) */
+ /* T1: used for Z^2. */
+ /* T2: used for the right term. */
+ ec_pow2 (t1, point->z, ctx);
+ ec_subm (l1, point->x, t1, ctx);
+ ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx);
+ ec_addm (t2, point->x, t1, ctx);
+ ec_mulm (l1, l1, t2, ctx);
+ }
+ else /* Standard case. */
+ {
+ /* L1 = 3X^2 + aZ^4 */
+ /* T1: used for aZ^4. */
+ ec_pow2 (l1, point->x, ctx);
+ ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx);
+ ec_powm (t1, point->z, mpi_const (MPI_C_FOUR), ctx);
+ ec_mulm (t1, t1, ctx->a, ctx);
+ ec_addm (l1, l1, t1, ctx);
+ }
+ /* Z3 = 2YZ */
+ ec_mulm (z3, point->y, point->z, ctx);
+ ec_mul2 (z3, z3, ctx);
+
+ /* L2 = 4XY^2 */
+ /* T2: used for Y2; required later. */
+ ec_pow2 (t2, point->y, ctx);
+ ec_mulm (l2, t2, point->x, ctx);
+ ec_mulm (l2, l2, mpi_const (MPI_C_FOUR), ctx);
+
+ /* X3 = L1^2 - 2L2 */
+ /* T1: used for L2^2. */
+ ec_pow2 (x3, l1, ctx);
+ ec_mul2 (t1, l2, ctx);
+ ec_subm (x3, x3, t1, ctx);
+
+ /* L3 = 8Y^4 */
+ /* T2: taken from above. */
+ ec_pow2 (t2, t2, ctx);
+ ec_mulm (l3, t2, mpi_const (MPI_C_EIGHT), ctx);
+
+ /* Y3 = L1(L2 - X3) - L3 */
+ ec_subm (y3, l2, x3, ctx);
+ ec_mulm (y3, y3, l1, ctx);
+ ec_subm (y3, y3, l3, ctx);
+ }
+
+#undef x3
+#undef y3
+#undef z3
+#undef t1
+#undef t2
+#undef t3
+#undef l1
+#undef l2
+#undef l3
+}
+
+
+/* RESULT = 2 * POINT (Montgomery version). */
+static void
+dup_point_montgomery (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+ (void)result;
+ (void)point;
+ (void)ctx;
+ log_fatal ("%s: %s not yet supported\n",
+ "_gcry_mpi_ec_dup_point", "Montgomery");
+}
+
+
+/* RESULT = 2 * POINT (Twisted Edwards version). */
+static void
+dup_point_edwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+#define X1 (point->x)
+#define Y1 (point->y)
+#define Z1 (point->z)
+#define X3 (result->x)
+#define Y3 (result->y)
+#define Z3 (result->z)
+#define B (ctx->t.scratch[0])
+#define C (ctx->t.scratch[1])
+#define D (ctx->t.scratch[2])
+#define E (ctx->t.scratch[3])
+#define F (ctx->t.scratch[4])
+#define H (ctx->t.scratch[5])
+#define J (ctx->t.scratch[6])
+
+ /* Compute: (X_3 : Y_3 : Z_3) = 2( X_1 : Y_1 : Z_1 ) */
+
+ /* B = (X_1 + Y_1)^2 */
+ ctx->addm (B, X1, Y1, ctx);
+ ctx->pow2 (B, B, ctx);
+
+ /* C = X_1^2 */
+ /* D = Y_1^2 */
+ ctx->pow2 (C, X1, ctx);
+ ctx->pow2 (D, Y1, ctx);
+
+ /* E = aC */
+ if (ctx->dialect == ECC_DIALECT_ED25519)
+ ctx->subm (E, ctx->p, C, ctx);
+ else
+ ctx->mulm (E, ctx->a, C, ctx);
+
+ /* F = E + D */
+ ctx->addm (F, E, D, ctx);
+
+ /* H = Z_1^2 */
+ ctx->pow2 (H, Z1, ctx);
+
+ /* J = F - 2H */
+ ctx->mul2 (J, H, ctx);
+ ctx->subm (J, F, J, ctx);
+
+ /* X_3 = (B - C - D) · J */
+ ctx->subm (X3, B, C, ctx);
+ ctx->subm (X3, X3, D, ctx);
+ ctx->mulm (X3, X3, J, ctx);
+
+ /* Y_3 = F · (E - D) */
+ ctx->subm (Y3, E, D, ctx);
+ ctx->mulm (Y3, Y3, F, ctx);
+
+ /* Z_3 = F · J */
+ ctx->mulm (Z3, F, J, ctx);
+
+#undef X1
+#undef Y1
+#undef Z1
+#undef X3
+#undef Y3
+#undef Z3
+#undef B
+#undef C
+#undef D
+#undef E
+#undef F
+#undef H
+#undef J
+}
+
+
+/* RESULT = 2 * POINT */
+void
+_gcry_mpi_ec_dup_point (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+ switch (ctx->model)
+ {
+ case MPI_EC_WEIERSTRASS:
+ dup_point_weierstrass (result, point, ctx);
+ break;
+ case MPI_EC_MONTGOMERY:
+ dup_point_montgomery (result, point, ctx);
+ break;
+ case MPI_EC_EDWARDS:
+ dup_point_edwards (result, point, ctx);
+ break;
+ }
+}
+
+
+/* RESULT = P1 + P2 (Weierstrass version).*/
+static void
+add_points_weierstrass (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+#define x1 (p1->x )
+#define y1 (p1->y )
+#define z1 (p1->z )
+#define x2 (p2->x )
+#define y2 (p2->y )
+#define z2 (p2->z )
+#define x3 (result->x)
+#define y3 (result->y)
+#define z3 (result->z)
+#define l1 (ctx->t.scratch[0])
+#define l2 (ctx->t.scratch[1])
+#define l3 (ctx->t.scratch[2])
+#define l4 (ctx->t.scratch[3])
+#define l5 (ctx->t.scratch[4])
+#define l6 (ctx->t.scratch[5])
+#define l7 (ctx->t.scratch[6])
+#define l8 (ctx->t.scratch[7])
+#define l9 (ctx->t.scratch[8])
+#define t1 (ctx->t.scratch[9])
+#define t2 (ctx->t.scratch[10])
+
+ if ( (!mpi_cmp (x1, x2)) && (!mpi_cmp (y1, y2)) && (!mpi_cmp (z1, z2)) )
+ {
+ /* Same point; need to call the duplicate function. */
+ _gcry_mpi_ec_dup_point (result, p1, ctx);
+ }
+ else if (!mpi_cmp_ui (z1, 0))
+ {
+ /* P1 is at infinity. */
+ mpi_set (x3, p2->x);
+ mpi_set (y3, p2->y);
+ mpi_set (z3, p2->z);
+ }
+ else if (!mpi_cmp_ui (z2, 0))
+ {
+ /* P2 is at infinity. */
+ mpi_set (x3, p1->x);
+ mpi_set (y3, p1->y);
+ mpi_set (z3, p1->z);
+ }
+ else
+ {
+ int z1_is_one = !mpi_cmp_ui (z1, 1);
+ int z2_is_one = !mpi_cmp_ui (z2, 1);
+
+ /* l1 = x1 z2^2 */
+ /* l2 = x2 z1^2 */
+ if (z2_is_one)
+ mpi_set (l1, x1);
+ else
+ {
+ ec_pow2 (l1, z2, ctx);
+ ec_mulm (l1, l1, x1, ctx);
+ }
+ if (z1_is_one)
+ mpi_set (l2, x2);
+ else
+ {
+ ec_pow2 (l2, z1, ctx);
+ ec_mulm (l2, l2, x2, ctx);
+ }
+ /* l3 = l1 - l2 */
+ ec_subm (l3, l1, l2, ctx);
+ /* l4 = y1 z2^3 */
+ ec_powm (l4, z2, mpi_const (MPI_C_THREE), ctx);
+ ec_mulm (l4, l4, y1, ctx);
+ /* l5 = y2 z1^3 */
+ ec_powm (l5, z1, mpi_const (MPI_C_THREE), ctx);
+ ec_mulm (l5, l5, y2, ctx);
+ /* l6 = l4 - l5 */
+ ec_subm (l6, l4, l5, ctx);
+
+ if (!mpi_cmp_ui (l3, 0))
+ {
+ if (!mpi_cmp_ui (l6, 0))
+ {
+ /* P1 and P2 are the same - use duplicate function. */
+ _gcry_mpi_ec_dup_point (result, p1, ctx);
+ }
+ else
+ {
+ /* P1 is the inverse of P2. */
+ mpi_set_ui (x3, 1);
+ mpi_set_ui (y3, 1);
+ mpi_set_ui (z3, 0);
+ }
+ }
+ else
+ {
+ /* l7 = l1 + l2 */
+ ec_addm (l7, l1, l2, ctx);
+ /* l8 = l4 + l5 */
+ ec_addm (l8, l4, l5, ctx);
+ /* z3 = z1 z2 l3 */
+ ec_mulm (z3, z1, z2, ctx);
+ ec_mulm (z3, z3, l3, ctx);
+ /* x3 = l6^2 - l7 l3^2 */
+ ec_pow2 (t1, l6, ctx);
+ ec_pow2 (t2, l3, ctx);
+ ec_mulm (t2, t2, l7, ctx);
+ ec_subm (x3, t1, t2, ctx);
+ /* l9 = l7 l3^2 - 2 x3 */
+ ec_mul2 (t1, x3, ctx);
+ ec_subm (l9, t2, t1, ctx);
+ /* y3 = (l9 l6 - l8 l3^3)/2 */
+ ec_mulm (l9, l9, l6, ctx);
+ ec_powm (t1, l3, mpi_const (MPI_C_THREE), ctx); /* fixme: Use saved value*/
+ ec_mulm (t1, t1, l8, ctx);
+ ec_subm (y3, l9, t1, ctx);
+ ec_mulm (y3, y3, ec_get_two_inv_p (ctx), ctx);
+ }
+ }
+
+#undef x1
+#undef y1
+#undef z1
+#undef x2
+#undef y2
+#undef z2
+#undef x3
+#undef y3
+#undef z3
+#undef l1
+#undef l2
+#undef l3
+#undef l4
+#undef l5
+#undef l6
+#undef l7
+#undef l8
+#undef l9
+#undef t1
+#undef t2
+}
+
+
+/* RESULT = P1 + P2 (Montgomery version).*/
+static void
+add_points_montgomery (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+ (void)result;
+ (void)p1;
+ (void)p2;
+ (void)ctx;
+ log_fatal ("%s: %s not yet supported\n",
+ "_gcry_mpi_ec_add_points", "Montgomery");
+}
+
+
+/* RESULT = P1 + P2 (Twisted Edwards version).*/
+static void
+add_points_edwards (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+#define X1 (p1->x)
+#define Y1 (p1->y)
+#define Z1 (p1->z)
+#define X2 (p2->x)
+#define Y2 (p2->y)
+#define Z2 (p2->z)
+#define X3 (result->x)
+#define Y3 (result->y)
+#define Z3 (result->z)
+#define A (ctx->t.scratch[0])
+#define B (ctx->t.scratch[1])
+#define C (ctx->t.scratch[2])
+#define D (ctx->t.scratch[3])
+#define E (ctx->t.scratch[4])
+#define F (ctx->t.scratch[5])
+#define G (ctx->t.scratch[6])
+#define tmp (ctx->t.scratch[7])
+
+ point_resize (result, ctx);
+
+ /* Compute: (X_3 : Y_3 : Z_3) = (X_1 : Y_1 : Z_1) + (X_2 : Y_2 : Z_3) */
+
+ /* A = Z1 · Z2 */
+ ctx->mulm (A, Z1, Z2, ctx);
+
+ /* B = A^2 */
+ ctx->pow2 (B, A, ctx);
+
+ /* C = X1 · X2 */
+ ctx->mulm (C, X1, X2, ctx);
+
+ /* D = Y1 · Y2 */
+ ctx->mulm (D, Y1, Y2, ctx);
+
+ /* E = d · C · D */
+ ctx->mulm (E, ctx->b, C, ctx);
+ ctx->mulm (E, E, D, ctx);
+
+ /* F = B - E */
+ ctx->subm (F, B, E, ctx);
+
+ /* G = B + E */
+ ctx->addm (G, B, E, ctx);
+
+ /* X_3 = A · F · ((X_1 + Y_1) · (X_2 + Y_2) - C - D) */
+ ctx->addm (tmp, X1, Y1, ctx);
+ ctx->addm (X3, X2, Y2, ctx);
+ ctx->mulm (X3, X3, tmp, ctx);
+ ctx->subm (X3, X3, C, ctx);
+ ctx->subm (X3, X3, D, ctx);
+ ctx->mulm (X3, X3, F, ctx);
+ ctx->mulm (X3, X3, A, ctx);
+
+ /* Y_3 = A · G · (D - aC) */
+ if (ctx->dialect == ECC_DIALECT_ED25519)
+ {
+ ctx->addm (Y3, D, C, ctx);
+ }
+ else
+ {
+ ctx->mulm (Y3, ctx->a, C, ctx);
+ ctx->subm (Y3, D, Y3, ctx);
+ }
+ ctx->mulm (Y3, Y3, G, ctx);
+ ctx->mulm (Y3, Y3, A, ctx);
+
+ /* Z_3 = F · G */
+ ctx->mulm (Z3, F, G, ctx);
+
+
+#undef X1
+#undef Y1
+#undef Z1
+#undef X2
+#undef Y2
+#undef Z2
+#undef X3
+#undef Y3
+#undef Z3
+#undef A
+#undef B
+#undef C
+#undef D
+#undef E
+#undef F
+#undef G
+#undef tmp
+}
+
+
+/* Compute a step of Montgomery Ladder (only use X and Z in the point).
+ Inputs: P1, P2, and x-coordinate of DIF = P1 - P1.
+ Outputs: PRD = 2 * P1 and SUM = P1 + P2. */
+static void
+montgomery_ladder (mpi_point_t prd, mpi_point_t sum,
+ mpi_point_t p1, mpi_point_t p2, gcry_mpi_t dif_x,
+ mpi_ec_t ctx)
+{
+ ctx->addm (sum->x, p2->x, p2->z, ctx);
+ ctx->subm (p2->z, p2->x, p2->z, ctx);
+ ctx->addm (prd->x, p1->x, p1->z, ctx);
+ ctx->subm (p1->z, p1->x, p1->z, ctx);
+ ctx->mulm (p2->x, p1->z, sum->x, ctx);
+ ctx->mulm (p2->z, prd->x, p2->z, ctx);
+ ctx->pow2 (p1->x, prd->x, ctx);
+ ctx->pow2 (p1->z, p1->z, ctx);
+ ctx->addm (sum->x, p2->x, p2->z, ctx);
+ ctx->subm (p2->z, p2->x, p2->z, ctx);
+ ctx->mulm (prd->x, p1->x, p1->z, ctx);
+ ctx->subm (p1->z, p1->x, p1->z, ctx);
+ ctx->pow2 (sum->x, sum->x, ctx);
+ ctx->pow2 (sum->z, p2->z, ctx);
+ ctx->mulm (prd->z, p1->z, ctx->a, ctx); /* CTX->A: (a-2)/4 */
+ ctx->mulm (sum->z, sum->z, dif_x, ctx);
+ ctx->addm (prd->z, p1->x, prd->z, ctx);
+ ctx->mulm (prd->z, prd->z, p1->z, ctx);
+}
+
+
+/* RESULT = P1 + P2 */
+void
+_gcry_mpi_ec_add_points (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+ switch (ctx->model)
+ {
+ case MPI_EC_WEIERSTRASS:
+ add_points_weierstrass (result, p1, p2, ctx);
+ break;
+ case MPI_EC_MONTGOMERY:
+ add_points_montgomery (result, p1, p2, ctx);
+ break;
+ case MPI_EC_EDWARDS:
+ add_points_edwards (result, p1, p2, ctx);
+ break;
+ }
+}
+
+
+/* RESULT = P1 - P2 (Weierstrass version).*/
+static void
+sub_points_weierstrass (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+ (void)result;
+ (void)p1;
+ (void)p2;
+ (void)ctx;
+ log_fatal ("%s: %s not yet supported\n",
+ "_gcry_mpi_ec_sub_points", "Weierstrass");
+}
+
+
+/* RESULT = P1 - P2 (Montgomery version).*/
+static void
+sub_points_montgomery (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+ (void)result;
+ (void)p1;
+ (void)p2;
+ (void)ctx;
+ log_fatal ("%s: %s not yet supported\n",
+ "_gcry_mpi_ec_sub_points", "Montgomery");
+}
+
+
+/* RESULT = P1 - P2 (Twisted Edwards version).*/
+static void
+sub_points_edwards (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+ mpi_point_t p2i = _gcry_mpi_point_new (0);
+ point_set (p2i, p2);
+ ctx->subm (p2i->x, ctx->p, p2i->x, ctx);
+ add_points_edwards (result, p1, p2i, ctx);
+ _gcry_mpi_point_release (p2i);
+}
+
+
+/* RESULT = P1 - P2 */
+void
+_gcry_mpi_ec_sub_points (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+ switch (ctx->model)
+ {
+ case MPI_EC_WEIERSTRASS:
+ sub_points_weierstrass (result, p1, p2, ctx);
+ break;
+ case MPI_EC_MONTGOMERY:
+ sub_points_montgomery (result, p1, p2, ctx);
+ break;
+ case MPI_EC_EDWARDS:
+ sub_points_edwards (result, p1, p2, ctx);
+ break;
+ }
+}
+
+
+/* Scalar point multiplication - the main function for ECC. If takes
+ an integer SCALAR and a POINT as well as the usual context CTX.
+ RESULT will be set to the resulting point. */
+void
+_gcry_mpi_ec_mul_point (mpi_point_t result,
+ gcry_mpi_t scalar, mpi_point_t point,
+ mpi_ec_t ctx)
+{
+ gcry_mpi_t x1, y1, z1, k, h, yy;
+ unsigned int i, loops;
+ mpi_point_struct p1, p2, p1inv;
+
+ if (ctx->model == MPI_EC_EDWARDS
+ || (ctx->model == MPI_EC_WEIERSTRASS
+ && mpi_is_secure (scalar)))
+ {
+ /* Simple left to right binary method. Algorithm 3.27 from
+ * {author={Hankerson, Darrel and Menezes, Alfred J. and Vanstone, Scott},
+ * title = {Guide to Elliptic Curve Cryptography},
+ * year = {2003}, isbn = {038795273X},
+ * url = {http://www.cacr.math.uwaterloo.ca/ecc/},
+ * publisher = {Springer-Verlag New York, Inc.}} */
+ unsigned int nbits;
+ int j;
+
+ if (mpi_cmp (scalar, ctx->p) >= 0)
+ nbits = mpi_get_nbits (scalar);
+ else
+ nbits = mpi_get_nbits (ctx->p);
+
+ if (ctx->model == MPI_EC_WEIERSTRASS)
+ {
+ mpi_set_ui (result->x, 1);
+ mpi_set_ui (result->y, 1);
+ mpi_set_ui (result->z, 0);
+ }
+ else
+ {
+ mpi_set_ui (result->x, 0);
+ mpi_set_ui (result->y, 1);
+ mpi_set_ui (result->z, 1);
+ point_resize (point, ctx);
+ }
+
+ if (mpi_is_secure (scalar))
+ {
+ /* If SCALAR is in secure memory we assume that it is the
+ secret key we use constant time operation. */
+ mpi_point_struct tmppnt;
+
+ point_init (&tmppnt);
+ point_resize (result, ctx);
+ point_resize (&tmppnt, ctx);
+ for (j=nbits-1; j >= 0; j--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ _gcry_mpi_ec_add_points (&tmppnt, result, point, ctx);
+ point_swap_cond (result, &tmppnt, mpi_test_bit (scalar, j), ctx);
+ }
+ point_free (&tmppnt);
+ }
+ else
+ {
+ if (ctx->model == MPI_EC_EDWARDS)
+ {
+ point_resize (result, ctx);
+ point_resize (point, ctx);
+ }
+
+ for (j=nbits-1; j >= 0; j--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ if (mpi_test_bit (scalar, j))
+ _gcry_mpi_ec_add_points (result, result, point, ctx);
+ }
+ }
+ return;
+ }
+ else if (ctx->model == MPI_EC_MONTGOMERY)
+ {
+ unsigned int nbits;
+ int j;
+ mpi_point_struct p1_, p2_;
+ mpi_point_t q1, q2, prd, sum;
+ unsigned long sw;
+ mpi_size_t rsize;
+ int scalar_copied = 0;
+
+ /* Compute scalar point multiplication with Montgomery Ladder.
+ Note that we don't use Y-coordinate in the points at all.
+ RESULT->Y will be filled by zero. */
+
+ nbits = mpi_get_nbits (scalar);
+ point_init (&p1);
+ point_init (&p2);
+ point_init (&p1_);
+ point_init (&p2_);
+ mpi_set_ui (p1.x, 1);
+ mpi_free (p2.x);
+ p2.x = mpi_copy (point->x);
+ mpi_set_ui (p2.z, 1);
+
+ if (mpi_is_opaque (scalar))
+ {
+ const unsigned int pbits = ctx->nbits;
+ gcry_mpi_t a;
+ unsigned int n;
+ unsigned char *raw;
+
+ scalar_copied = 1;
+
+ raw = _gcry_mpi_get_opaque_copy (scalar, &n);
+ if ((n+7)/8 != (pbits+7)/8)
+ log_fatal ("scalar size (%d) != prime size (%d)\n",
+ (n+7)/8, (pbits+7)/8);
+
+ reverse_buffer (raw, (n+7)/8);
+ if ((pbits % 8))
+ raw[0] &= (1 << (pbits % 8)) - 1;
+ raw[0] |= (1 << ((pbits + 7) % 8));
+ raw[(pbits+7)/8 - 1] &= (256 - ctx->h);
+ a = mpi_is_secure (scalar) ? mpi_snew (pbits): mpi_new (pbits);
+ _gcry_mpi_set_buffer (a, raw, (n+7)/8, 0);
+ xfree (raw);
+
+ scalar = a;
+ }
+
+ point_resize (&p1, ctx);
+ point_resize (&p2, ctx);
+ point_resize (&p1_, ctx);
+ point_resize (&p2_, ctx);
+
+ mpi_resize (point->x, ctx->p->nlimbs);
+ point->x->nlimbs = ctx->p->nlimbs;
+
+ q1 = &p1;
+ q2 = &p2;
+ prd = &p1_;
+ sum = &p2_;
+
+ for (j=nbits-1; j >= 0; j--)
+ {
+ mpi_point_t t;
+
+ sw = mpi_test_bit (scalar, j);
+ point_swap_cond (q1, q2, sw, ctx);
+ montgomery_ladder (prd, sum, q1, q2, point->x, ctx);
+ point_swap_cond (prd, sum, sw, ctx);
+ t = q1; q1 = prd; prd = t;
+ t = q2; q2 = sum; sum = t;
+ }
+
+ mpi_clear (result->y);
+ sw = (nbits & 1);
+ point_swap_cond (&p1, &p1_, sw, ctx);
+
+ rsize = p1.z->nlimbs;
+ MPN_NORMALIZE (p1.z->d, rsize);
+ if (rsize == 0)
+ {
+ mpi_set_ui (result->x, 1);
+ mpi_set_ui (result->z, 0);
+ }
+ else
+ {
+ z1 = mpi_new (0);
+ ec_invm (z1, p1.z, ctx);
+ ec_mulm (result->x, p1.x, z1, ctx);
+ mpi_set_ui (result->z, 1);
+ mpi_free (z1);
+ }
+
+ point_free (&p1);
+ point_free (&p2);
+ point_free (&p1_);
+ point_free (&p2_);
+ if (scalar_copied)
+ _gcry_mpi_release (scalar);
+ return;
+ }
+
+ x1 = mpi_alloc_like (ctx->p);
+ y1 = mpi_alloc_like (ctx->p);
+ h = mpi_alloc_like (ctx->p);
+ k = mpi_copy (scalar);
+ yy = mpi_copy (point->y);
+
+ if ( mpi_has_sign (k) )
+ {
+ k->sign = 0;
+ ec_invm (yy, yy, ctx);
+ }
+
+ if (!mpi_cmp_ui (point->z, 1))
+ {
+ mpi_set (x1, point->x);
+ mpi_set (y1, yy);
+ }
+ else
+ {
+ gcry_mpi_t z2, z3;
+
+ z2 = mpi_alloc_like (ctx->p);
+ z3 = mpi_alloc_like (ctx->p);
+ ec_mulm (z2, point->z, point->z, ctx);
+ ec_mulm (z3, point->z, z2, ctx);
+ ec_invm (z2, z2, ctx);
+ ec_mulm (x1, point->x, z2, ctx);
+ ec_invm (z3, z3, ctx);
+ ec_mulm (y1, yy, z3, ctx);
+ mpi_free (z2);
+ mpi_free (z3);
+ }
+ z1 = mpi_copy (mpi_const (MPI_C_ONE));
+
+ mpi_mul (h, k, mpi_const (MPI_C_THREE)); /* h = 3k */
+ loops = mpi_get_nbits (h);
+ if (loops < 2)
+ {
+ /* If SCALAR is zero, the above mpi_mul sets H to zero and thus
+ LOOPs will be zero. To avoid an underflow of I in the main
+ loop we set LOOP to 2 and the result to (0,0,0). */
+ loops = 2;
+ mpi_clear (result->x);
+ mpi_clear (result->y);
+ mpi_clear (result->z);
+ }
+ else
+ {
+ mpi_set (result->x, point->x);
+ mpi_set (result->y, yy);
+ mpi_set (result->z, point->z);
+ }
+ mpi_free (yy); yy = NULL;
+
+ p1.x = x1; x1 = NULL;
+ p1.y = y1; y1 = NULL;
+ p1.z = z1; z1 = NULL;
+ point_init (&p2);
+ point_init (&p1inv);
+
+ /* Invert point: y = p - y mod p */
+ point_set (&p1inv, &p1);
+ ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
+
+ for (i=loops-2; i > 0; i--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0)
+ {
+ point_set (&p2, result);
+ _gcry_mpi_ec_add_points (result, &p2, &p1, ctx);
+ }
+ if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
+ {
+ point_set (&p2, result);
+ _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
+ }
+ }
+
+ point_free (&p1);
+ point_free (&p2);
+ point_free (&p1inv);
+ mpi_free (h);
+ mpi_free (k);
+}
+
+
+/* Return true if POINT is on the curve described by CTX. */
+int
+_gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx)
+{
+ int res = 0;
+ gcry_mpi_t x, y, w;
+
+ x = mpi_new (0);
+ y = mpi_new (0);
+ w = mpi_new (0);
+
+ /* Check that the point is in range. This needs to be done here and
+ * not after conversion to affine coordinates. */
+ if (mpi_cmpabs (point->x, ctx->p) >= 0)
+ goto leave;
+ if (mpi_cmpabs (point->y, ctx->p) >= 0)
+ goto leave;
+ if (mpi_cmpabs (point->z, ctx->p) >= 0)
+ goto leave;
+
+ switch (ctx->model)
+ {
+ case MPI_EC_WEIERSTRASS:
+ {
+ gcry_mpi_t xxx;
+
+ if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
+ goto leave;
+
+ xxx = mpi_new (0);
+
+ /* y^2 == x^3 + a·x + b */
+ ec_pow2 (y, y, ctx);
+
+ ec_pow3 (xxx, x, ctx);
+ ec_mulm (w, ctx->a, x, ctx);
+ ec_addm (w, w, ctx->b, ctx);
+ ec_addm (w, w, xxx, ctx);
+
+ if (!mpi_cmp (y, w))
+ res = 1;
+
+ _gcry_mpi_release (xxx);
+ }
+ break;
+ case MPI_EC_MONTGOMERY:
+ {
+#define xx y
+ /* With Montgomery curve, only X-coordinate is valid. */
+ if (_gcry_mpi_ec_get_affine (x, NULL, point, ctx))
+ goto leave;
+
+ /* The equation is: b * y^2 == x^3 + a · x^2 + x */
+ /* We check if right hand is quadratic residue or not by
+ Euler's criterion. */
+ /* CTX->A has (a-2)/4 and CTX->B has b^-1 */
+ ec_mulm (w, ctx->a, mpi_const (MPI_C_FOUR), ctx);
+ ec_addm (w, w, mpi_const (MPI_C_TWO), ctx);
+ ec_mulm (w, w, x, ctx);
+ ec_pow2 (xx, x, ctx);
+ ec_addm (w, w, xx, ctx);
+ ec_addm (w, w, mpi_const (MPI_C_ONE), ctx);
+ ec_mulm (w, w, x, ctx);
+ ec_mulm (w, w, ctx->b, ctx);
+#undef xx
+ /* Compute Euler's criterion: w^(p-1)/2 */
+#define p_minus1 y
+ ec_subm (p_minus1, ctx->p, mpi_const (MPI_C_ONE), ctx);
+ mpi_rshift (p_minus1, p_minus1, 1);
+ ec_powm (w, w, p_minus1, ctx);
+
+ res = !mpi_cmp_ui (w, 1);
+#undef p_minus1
+ }
+ break;
+ case MPI_EC_EDWARDS:
+ {
+ if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
+ goto leave;
+
+ mpi_resize (w, ctx->p->nlimbs);
+ w->nlimbs = ctx->p->nlimbs;
+
+ /* a · x^2 + y^2 - 1 - b · x^2 · y^2 == 0 */
+ ctx->pow2 (x, x, ctx);
+ ctx->pow2 (y, y, ctx);
+ if (ctx->dialect == ECC_DIALECT_ED25519)
+ ctx->subm (w, ctx->p, x, ctx);
+ else
+ ctx->mulm (w, ctx->a, x, ctx);
+ ctx->addm (w, w, y, ctx);
+ ctx->mulm (x, x, y, ctx);
+ ctx->mulm (x, x, ctx->b, ctx);
+ ctx->subm (w, w, x, ctx);
+ if (!mpi_cmp_ui (w, 1))
+ res = 1;
+ }
+ break;
+ }
+
+ leave:
+ _gcry_mpi_release (w);
+ _gcry_mpi_release (x);
+ _gcry_mpi_release (y);
+
+ return res;
+}
+
+
+int
+_gcry_mpi_ec_bad_point (gcry_mpi_point_t point, mpi_ec_t ctx)
+{
+ int i;
+ gcry_mpi_t x_bad;
+
+ for (i = 0; (x_bad = ctx->t.scratch[i]); i++)
+ if (!mpi_cmp (point->x, x_bad))
+ return 1;
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/mpi/generic/distfiles b/comm/third_party/libgcrypt/mpi/generic/distfiles
new file mode 100644
index 0000000000..649e829b7e
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/distfiles
@@ -0,0 +1,10 @@
+mpih-add1.c
+mpih-mul1.c
+mpih-mul2.c
+mpih-mul3.c
+mpih-lshift.c
+mpih-rshift.c
+mpih-sub1.c
+udiv-w-sdiv.c
+mpi-asm-defs.h
+
diff --git a/comm/third_party/libgcrypt/mpi/generic/mpi-asm-defs.h b/comm/third_party/libgcrypt/mpi/generic/mpi-asm-defs.h
new file mode 100644
index 0000000000..e607806e10
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/mpi-asm-defs.h
@@ -0,0 +1,8 @@
+/* This file defines some basic constants for the MPI machinery.
+ * AMD64 compiled for the x32 ABI is special and thus we can't use the
+ * standard values for this ABI. */
+#if __GNUC__ >= 3 && defined(__x86_64__) && defined(__ILP32__)
+#define BYTES_PER_MPI_LIMB 8
+#else
+#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/generic/mpih-add1.c b/comm/third_party/libgcrypt/mpi/generic/mpih-add1.c
new file mode 100644
index 0000000000..4a84df64d8
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/mpih-add1.c
@@ -0,0 +1,65 @@
+/* mpihelp-add_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998,
+ * 2000, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to one addend */
+ cy = y < cy; /* get out carry from that addition */
+ y += x; /* add other addend */
+ cy += y < x; /* get out carry from that add, combine */
+ res_ptr[j] = y;
+ }
+ while ( ++j );
+
+ return cy;
+}
+
diff --git a/comm/third_party/libgcrypt/mpi/generic/mpih-lshift.c b/comm/third_party/libgcrypt/mpi/generic/mpih-lshift.c
new file mode 100644
index 0000000000..f48c12cd02
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/mpih-lshift.c
@@ -0,0 +1,68 @@
+/* mpi-lshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
+ * and store the USIZE least significant digits of the result at WP.
+ * Return the bits shifted out from the most significant digit.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be >= UP.
+ */
+
+mpi_limb_t
+_gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned int cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp += 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ i = usize - 1;
+ low_limb = up[i];
+ retval = low_limb >> sh_2;
+ high_limb = low_limb;
+ while ( --i >= 0 )
+ {
+ low_limb = up[i];
+ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+ high_limb = low_limb;
+ }
+ wp[i] = high_limb << sh_1;
+
+ return retval;
+}
+
+
diff --git a/comm/third_party/libgcrypt/mpi/generic/mpih-mul1.c b/comm/third_party/libgcrypt/mpi/generic/mpih-mul1.c
new file mode 100644
index 0000000000..0e8197d88a
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/mpih-mul1.c
@@ -0,0 +1,62 @@
+/* mpihelp-mul_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+
+ /* The loop counter and index J goes from -S1_SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ res_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+ res_ptr[j] = prod_low;
+ }
+ while( ++j );
+
+ return cy_limb;
+}
+
diff --git a/comm/third_party/libgcrypt/mpi/generic/mpih-mul2.c b/comm/third_party/libgcrypt/mpi/generic/mpih-mul2.c
new file mode 100644
index 0000000000..3b7549605d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/mpih-mul2.c
@@ -0,0 +1,68 @@
+/* mpih-mul2.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+mpi_limb_t
+_gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+ mpi_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x + prod_low;
+ cy_limb += prod_low < x?1:0;
+ res_ptr[j] = prod_low;
+ }
+ while ( ++j );
+
+ return cy_limb;
+}
+
+
diff --git a/comm/third_party/libgcrypt/mpi/generic/mpih-mul3.c b/comm/third_party/libgcrypt/mpi/generic/mpih-mul3.c
new file mode 100644
index 0000000000..5e84f94f31
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/mpih-mul3.c
@@ -0,0 +1,68 @@
+/* mpih-mul3.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+mpi_limb_t
+_gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+ mpi_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x - prod_low;
+ cy_limb += prod_low > x?1:0;
+ res_ptr[j] = prod_low;
+ }
+ while( ++j );
+
+ return cy_limb;
+}
+
+
diff --git a/comm/third_party/libgcrypt/mpi/generic/mpih-rshift.c b/comm/third_party/libgcrypt/mpi/generic/mpih-rshift.c
new file mode 100644
index 0000000000..e40794fcf2
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/mpih-rshift.c
@@ -0,0 +1,67 @@
+/* mpih-rshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2000, 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+
+/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
+ * and store the USIZE least significant limbs of the result at WP.
+ * The bits shifted out to the right are returned.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be <= UP.
+ */
+
+mpi_limb_t
+_gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp -= 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ high_limb = up[0];
+ retval = high_limb << sh_2;
+ low_limb = high_limb;
+ for (i=1; i < usize; i++)
+ {
+ high_limb = up[i];
+ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
+ low_limb = high_limb;
+ }
+ wp[i] = low_limb >> sh_1;
+
+ return retval;
+}
+
diff --git a/comm/third_party/libgcrypt/mpi/generic/mpih-sub1.c b/comm/third_party/libgcrypt/mpi/generic/mpih-sub1.c
new file mode 100644
index 0000000000..e88821bfb4
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/mpih-sub1.c
@@ -0,0 +1,66 @@
+/* mpihelp-add_2.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to subtrahend */
+ cy = y < cy; /* get out carry from that addition */
+ y = x - y; /* main subtract */
+ cy += y > x; /* get out carry from the subtract, combine */
+ res_ptr[j] = y;
+ }
+ while( ++j );
+
+ return cy;
+}
+
+
diff --git a/comm/third_party/libgcrypt/mpi/generic/udiv-w-sdiv.c b/comm/third_party/libgcrypt/mpi/generic/udiv-w-sdiv.c
new file mode 100644
index 0000000000..e80d98bc54
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/generic/udiv-w-sdiv.c
@@ -0,0 +1,133 @@
+/* mpih-w-sdiv -- implement udiv_qrnnd on machines with only signed
+ * division.
+ * Copyright (C) 1992, 1994, 1996, 1998, 2002 Free Software Foundation, Inc.
+ * Contributed by Peter L. Montgomery.
+ *
+ * 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+#if 0 /* not yet ported to MPI */
+
+mpi_limb_t
+mpihelp_udiv_w_sdiv( mpi_limp_t *rp,
+ mpi_limp_t *a1,
+ mpi_limp_t *a0,
+ mpi_limp_t *d )
+{
+ mp_limb_t q, r;
+ mp_limb_t c0, c1, b1;
+
+ if ((mpi_limb_signed_t) d >= 0)
+ {
+ if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1)))
+ {
+ /* dividend, divisor, and quotient are nonnegative */
+ sdiv_qrnnd (q, r, a1, a0, d);
+ }
+ else
+ {
+ /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
+ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1));
+ /* Divide (c1*2^32 + c0) by d */
+ sdiv_qrnnd (q, r, c1, c0, d);
+ /* Add 2^31 to quotient */
+ q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
+ }
+ }
+ else
+ {
+ b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
+ c1 = a1 >> 1; /* A/2 */
+ c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1);
+
+ if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
+ {
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
+ {
+ c1 = (b1 - 1) - c1;
+ c0 = ~c0; /* logical NOT */
+
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ q = ~q; /* (A/2)/b1 */
+ r = (b1 - 1) - r;
+
+ r = 2*r + (a0 & 1); /* A/(2*b1) */
+
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else /* Implies c1 = b1 */
+ { /* Hence a1 = d - 1 = 2*b1 - 1 */
+ if (a0 >= -d)
+ {
+ q = -1;
+ r = a0 + d;
+ }
+ else
+ {
+ q = -2;
+ r = a0 + 2*d;
+ }
+ }
+ }
+
+ *rp = r;
+ return q;
+}
+
+#endif
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa/README b/comm/third_party/libgcrypt/mpi/hppa/README
new file mode 100644
index 0000000000..5a2d5fd970
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa/README
@@ -0,0 +1,84 @@
+This directory contains mpn functions for various HP PA-RISC chips. Code
+that runs faster on the PA7100 and later implementations, is in the pa7100
+directory.
+
+RELEVANT OPTIMIZATION ISSUES
+
+ Load and Store timing
+
+On the PA7000 no memory instructions can issue the two cycles after a store.
+For the PA7100, this is reduced to one cycle.
+
+The PA7100 has a lookup-free cache, so it helps to schedule loads and the
+dependent instruction really far from each other.
+
+STATUS
+
+1. mpn_mul_1 could be improved to 6.5 cycles/limb on the PA7100, using the
+ instructions bwlow (but some sw pipelining is needed to avoid the
+ xmpyu-fstds delay):
+
+ fldds s1_ptr
+
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+
+ addib Loop
+
+2. mpn_addmul_1 could be improved from the current 10 to 7.5 cycles/limb
+ (asymptotically) on the PA7100, using the instructions below. With proper
+ sw pipelining and the unrolling level below, the speed becomes 8
+ cycles/limb.
+
+ fldds s1_ptr
+ fldds s1_ptr
+
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ addc
+ addc
+ addc
+ addc
+ addc %r0,%r0,cy-limb
+
+ ldws res_ptr
+ ldws res_ptr
+ ldws res_ptr
+ ldws res_ptr
+ add
+ stws res_ptr
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+
+ addib
diff --git a/comm/third_party/libgcrypt/mpi/hppa/distfiles b/comm/third_party/libgcrypt/mpi/hppa/distfiles
new file mode 100644
index 0000000000..7f24205d34
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa/distfiles
@@ -0,0 +1,7 @@
+README
+udiv-qrnnd.S
+mpih-add1.S
+mpih-sub1.S
+mpih-lshift.S
+mpih-rshift.S
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa/mpih-add1.S b/comm/third_party/libgcrypt/mpi/hppa/mpih-add1.S
new file mode 100644
index 0000000000..3bc0e5e196
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa/mpih-add1.S
@@ -0,0 +1,70 @@
+/* hppa add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Fee 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (gr26)
+ * mpi_ptr_t s1_ptr, (gr25)
+ * mpi_ptr_t s2_ptr, (gr24)
+ * mpi_size_t size) (gr23)
+ *
+ * One might want to unroll this as for other processors, but it turns
+ * out that the data cache contention after a store makes such
+ * unrolling useless. We can't come under 5 cycles/limb anyway.
+ */
+
+ .code
+ .export _gcry_mpih_add_n
+ .label _gcry_mpih_add_n
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,= -1,%r23,L$end ; check for (SIZE == 1)
+ add %r20,%r19,%r28 ; add first limbs ignoring cy
+
+ .label L$loop
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,<> -1,%r23,L$loop
+ addc %r20,%r19,%r28
+
+ .label L$end
+ stws %r28,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r0,%r28
+
+ .exit
+ .procend
diff --git a/comm/third_party/libgcrypt/mpi/hppa/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/hppa/mpih-lshift.S
new file mode 100644
index 0000000000..91b29bb6e7
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa/mpih-lshift.S
@@ -0,0 +1,77 @@
+/* hppa lshift
+ *
+ * Copyright (C) 1992, 1994, 1998
+ * 2001, 2002 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
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_lshift
+ .label _gcry_mpih_lshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(0,%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L$0004
+ vshd %r0,%r22,%r28 ; compute carry out limb
+ ldws,mb -4(0,%r25),%r29
+ addib,= -1,%r24,L$0002
+ vshd %r22,%r29,%r20
+
+ .label L$loop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ addib,= -1,%r24,L$0003
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,<> -1,%r24,L$loop
+ vshd %r22,%r29,%r20
+
+ .label L$0002
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+ .label L$0003
+ stws,mb %r20,-4(0,%r26)
+ .label L$0004
+ vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+
+ .exit
+ .procend
+
+
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/hppa/mpih-rshift.S
new file mode 100644
index 0000000000..37a9d4ef92
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa/mpih-rshift.S
@@ -0,0 +1,73 @@
+/* hppa rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ */
+
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_rshift
+ .label _gcry_mpih_rshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L$r004
+ vshd %r22,%r0,%r28 ; compute carry out limb
+ ldws,ma 4(0,%r25),%r29
+ addib,= -1,%r24,L$r002
+ vshd %r29,%r22,%r20
+
+ .label L$roop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ addib,= -1,%r24,L$r003
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,<> -1,%r24,L$roop
+ vshd %r29,%r22,%r20
+
+ .label L$r002
+ stws,ma %r20,4(0,%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+ .label L$r003
+ stws,ma %r20,4(0,%r26)
+ .label L$r004
+ vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+
+ .exit
+ .procend
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/hppa/mpih-sub1.S
new file mode 100644
index 0000000000..8d197e412a
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa/mpih-sub1.S
@@ -0,0 +1,78 @@
+/* hppa sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (gr26)
+ * mpi_ptr_t s1_ptr, (gr25)
+ * mpi_ptr_t s2_ptr, (gr24)
+ * mpi_size_t size) (gr23)
+ *
+ * One might want to unroll this as for other processors, but it turns
+ * out that the data cache contention after a store makes such
+ * unrolling useless. We can't come under 5 cycles/limb anyway.
+ */
+
+
+ .code
+ .export _gcry_mpih_sub_n
+ .label _gcry_mpih_sub_n
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,= -1,%r23,L$end ; check for (SIZE == 1)
+ sub %r20,%r19,%r28 ; subtract first limbs ignoring cy
+
+ .label L$loop
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,<> -1,%r23,L$loop
+ subb %r20,%r19,%r28
+
+ .label L$end
+ stws %r28,0(0,%r26)
+ addc %r0,%r0,%r28
+ bv 0(%r2)
+ subi 1,%r28,%r28
+
+ .exit
+ .procend
+
+
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa/udiv-qrnnd.S b/comm/third_party/libgcrypt/mpi/hppa/udiv-qrnnd.S
new file mode 100644
index 0000000000..59ebf7a002
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa/udiv-qrnnd.S
@@ -0,0 +1,297 @@
+/* HP-PA __udiv_qrnnd division support, used from longlong.h.
+ * This version runs fast on pre-PA7000 CPUs.
+ *
+ * Copyright (C) 1993, 1994, 1998, 2001,
+ * 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/* INPUT PARAMETERS
+ * rem_ptr gr26
+ * n1 gr25
+ * n0 gr24
+ * d gr23
+ *
+ * The code size is a bit excessive. We could merge the last two ds;addc
+ * sequences by simply moving the "bb,< Odd" instruction down. The only
+ * trouble is the FFFFFFFF code that would need some hacking.
+ */
+
+ .code
+ .export __udiv_qrnnd
+ .label __udiv_qrnnd
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ comb,< %r23,0,L$largedivisor
+ sub %r0,%r23,%r1 ; clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r28
+ ds %r25,%r23,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r23,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r28,%r28,%r28
+
+ .label L$largedivisor
+ extru %r24,31,1,%r19 ; r19 = n0 & 1
+ bb,< %r23,31,L$odd
+ extru %r23,30,31,%r22 ; r22 = d >> 1
+ shd %r25,%r24,1,%r24 ; r24 = new n0
+ extru %r25,30,31,%r25 ; r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r19,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r24,%r24,%r28
+
+ .label L$odd
+ addib,sv,n 1,%r22,L$FF.. ; r22 = (d / 2 + 1)
+ shd %r25,%r24,1,%r24 ; r24 = new n0
+ extru %r25,30,31,%r25 ; r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r28
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r19,%r25
+; We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25
+ add,nuv %r28,%r25,%r25
+ addl %r25,%r1,%r25
+ addc %r0,%r28,%r28
+ sub,<< %r25,%r23,%r0
+ addl %r25,%r1,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r28,%r28
+
+; This is just a special case of the code above.
+; We come here when d == 0xFFFFFFFF
+ .label L$FF..
+ add,uv %r25,%r24,%r24
+ sub,<< %r24,%r23,%r0
+ ldo 1(%r24),%r24
+ stws %r24,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r25,%r28
+
+ .exit
+ .procend
diff --git a/comm/third_party/libgcrypt/mpi/hppa1.1/distfiles b/comm/third_party/libgcrypt/mpi/hppa1.1/distfiles
new file mode 100644
index 0000000000..d68227ac70
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa1.1/distfiles
@@ -0,0 +1,5 @@
+udiv-qrnnd.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul1.S
new file mode 100644
index 0000000000..45926dd7b5
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul1.S
@@ -0,0 +1,115 @@
+/* hppa1.1 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r26)
+ * mpi_ptr_t s1_ptr, (r25)
+ * mpi_size_t s1_size, (r24)
+ * mpi_limb_t s2_limb) (r23)
+ *
+ *
+ *
+ * This runs at 9 cycles/limb on a PA7000. With the used instructions, it can
+ * not become faster due to data cache contention after a store. On the
+ * PA7100 it runs at 7 cycles/limb, and that can not be improved either, since
+ * only the xmpyu does not need the integer pipeline, so the only dual-issue
+ * we will get are addc+xmpyu. Unrolling would not help either CPU.
+ *
+ * We could use fldds to read two limbs at a time from the S1 array, and that
+ * could bring down the times to 8.5 and 6.5 cycles/limb for the PA7000 and
+ * PA7100, respectively. We don't do that since it does not seem worth the
+ * (alignment) troubles...
+ *
+ * At least the PA7100 is rumored to be able to deal with cache-misses
+ * without stalling instruction issue. If this is true, and the cache is
+ * actually also lockup-free, we should use a deeper software pipeline, and
+ * load from S1 very early! (The loads and stores to -12(sp) will surely be
+ * in the cache.)
+ */
+
+ .level 1.1
+
+ .code
+ .export _gcry_mpih_mul_1
+ .label _gcry_mpih_mul_1
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ; move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ; ... into fr4
+ add %r0,%r0,%r0 ; clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 ; least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+; Main loop
+ .label L$loop
+ fldws,ma 4(%r25),%fr5
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+ .label L$end
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ stws,ma %r19,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .label L$just_one_limb
+ xmpyu %fr4,%fr5,%fr6
+ fstds %fr6,-16(%r30)
+ ldw -16(%r30),%r28
+ ldo -64(%r30),%r30
+ bv 0(%r2)
+ fstws %fr6R,0(%r26)
+
+ .exit
+ .procend
+
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul2.S
new file mode 100644
index 0000000000..1047ab5649
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul2.S
@@ -0,0 +1,117 @@
+/* hppa1.1 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r26)
+ * mpi_ptr_t s1_ptr, (r25)
+ * mpi_size_t s1_size, (r24)
+ * mpi_limb_t s2_limb) (r23)
+ *
+ * This runs at 11 cycles/limb on a PA7000. With the used instructions, it
+ * can not become faster due to data cache contention after a store. On the
+ * PA7100 it runs at 10 cycles/limb, and that can not be improved either,
+ * since only the xmpyu does not need the integer pipeline, so the only
+ * dual-issue we will get are addc+xmpyu. Unrolling could gain a cycle/limb
+ * on the PA7100.
+ *
+ * There are some ideas described in mul1.S that applies to this code too.
+ */
+
+ .level 1.1
+
+ .code
+ .export _gcry_mpih_addmul_1
+ .label _gcry_mpih_addmul_1
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ; move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ; ... into fr4
+ add %r0,%r0,%r0 ; clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 ; least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+; Main loop
+ .label L$loop
+ ldws 0(%r26),%r29
+ fldws,ma 4(%r25),%fr5
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addc %r0,%r28,%r28
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+ .label L$end
+ ldw 0(%r26),%r29
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ ldws 0(%r26),%r29
+ addc %r0,%r28,%r28
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .label L$just_one_limb
+ xmpyu %fr4,%fr5,%fr6
+ ldw 0(%r26),%r29
+ fstds %fr6,-16(%r30)
+ ldw -12(%r30),%r1
+ ldw -16(%r30),%r28
+ add %r29,%r1,%r19
+ stw %r19,0(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .exit
+ .procend
+
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul3.S
new file mode 100644
index 0000000000..632adf1eec
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa1.1/mpih-mul3.S
@@ -0,0 +1,126 @@
+/* hppa1.1 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r26)
+ * mpi_ptr_t s1_ptr, (r25)
+ * mpi_size_t s1_size, (r24)
+ * mpi_limb_t s2_limb) (r23)
+ *
+ *
+ * This runs at 12 cycles/limb on a PA7000. With the used instructions, it
+ * can not become faster due to data cache contention after a store. On the
+ * PA7100 it runs at 11 cycles/limb, and that can not be improved either,
+ * since only the xmpyu does not need the integer pipeline, so the only
+ * dual-issue we will get are addc+xmpyu. Unrolling could gain a cycle/limb
+ * on the PA7100.
+ *
+ * There are some ideas described in mul1.S that applies to this code too.
+ *
+ * It seems possible to make this run as fast as addmul_1, if we use
+ * sub,>>= %r29,%r19,%r22
+ * addi 1,%r28,%r28
+ * but that requires reworking the hairy software pipeline...
+ */
+
+ .level 1.1
+
+ .code
+ .export _gcry_mpih_submul_1
+ .label _gcry_mpih_submul_1
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ; move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ; ... into fr4
+ add %r0,%r0,%r0 ; clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 ; least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+; Main loop
+ .label L$loop
+ ldws 0(%r26),%r29
+ fldws,ma 4(%r25),%fr5
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addc %r0,%r28,%r28
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+ .label L$end
+ ldw 0(%r26),%r29
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ ldws 0(%r26),%r29
+ addc %r0,%r28,%r28
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .label L$just_one_limb
+ xmpyu %fr4,%fr5,%fr6
+ ldw 0(%r26),%r29
+ fstds %fr6,-16(%r30)
+ ldw -12(%r30),%r1
+ ldw -16(%r30),%r28
+ sub %r29,%r1,%r22
+ add %r22,%r1,%r0
+ stw %r22,0(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .exit
+ .procend
+
diff --git a/comm/third_party/libgcrypt/mpi/hppa1.1/udiv-qrnnd.S b/comm/third_party/libgcrypt/mpi/hppa1.1/udiv-qrnnd.S
new file mode 100644
index 0000000000..3f28b7b64d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/hppa1.1/udiv-qrnnd.S
@@ -0,0 +1,92 @@
+/* HP-PA __udiv_qrnnd division support, used from longlong.h.
+ * This version runs fast on PA 7000 and later.
+ *
+ * Copyright (C) 1993, 1994, 1998,
+ * 2001, 2002, 2004 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/* INPUT PARAMETERS
+ * rem_ptr gr26
+ * n1 gr25
+ * n0 gr24
+ * d gr23
+ */
+
+ .level 1.1
+
+ .data
+ .align 8
+ .label L$0000
+ .word 0x43f00000
+ .word 0x0
+ .code
+ .export __udiv_qrnnd
+ .label __udiv_qrnnd
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+ ldo 64(%r30),%r30
+
+ stws %r25,-16(0,%r30) ; n_hi
+ stws %r24,-12(0,%r30) ; n_lo
+ stw %r19,-32(%r30)
+ addil LT%L$0000,%r19
+ ldw RT%L$0000(%r1),%r1
+ fldds -16(0,%r30),%fr5
+ stws %r23,-12(0,%r30)
+ comib,<= 0,%r25,L$1
+ fcnvxf,dbl,dbl %fr5,%fr5
+ fldds 0(0,%r1),%fr4
+ fadd,dbl %fr4,%fr5,%fr5
+ .label L$1
+ fcpy,sgl %fr0,%fr6L
+ fldws -12(0,%r30),%fr6R
+ fcnvxf,dbl,dbl %fr6,%fr4
+
+ fdiv,dbl %fr5,%fr4,%fr5
+
+ fcnvfx,dbl,dbl %fr5,%fr4
+ fstws %fr4R,-16(%r30)
+ xmpyu %fr4R,%fr6R,%fr6
+ ldws -16(%r30),%r28
+ fstds %fr6,-16(0,%r30)
+ ldws -12(0,%r30),%r21
+ ldws -16(0,%r30),%r20
+ sub %r24,%r21,%r22
+ subb %r25,%r20,%r1
+ comib,= 0,%r1,L$2
+ ldo -64(%r30),%r30
+
+ add %r22,%r23,%r22
+ ldo -1(%r28),%r28
+ .label L$2
+ bv 0(%r2)
+ stws %r22,0(0,%r26)
+
+ .exit
+ .procend
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/distfiles b/comm/third_party/libgcrypt/mpi/i386/distfiles
new file mode 100644
index 0000000000..88d2a30c7d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/distfiles
@@ -0,0 +1,9 @@
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+syntax.h
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/mpih-add1.S b/comm/third_party/libgcrypt/mpi/i386/mpih-add1.S
new file mode 100644
index 0000000000..de78a0cb1d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/mpih-add1.S
@@ -0,0 +1,161 @@
+/* i80386 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ CFI_STARTPROC()
+ pushl %edi
+ CFI_PUSH(%edi)
+ pushl %esi
+ CFI_PUSH(%esi)
+
+ movl 12(%esp),%edi /* res_ptr */
+ movl 16(%esp),%esi /* s1_ptr */
+ movl 20(%esp),%edx /* s2_ptr */
+ movl 24(%esp),%ecx /* size */
+
+#if defined __CET__ && (__CET__ & 1) != 0
+ pushl %ebx
+ CFI_PUSH(%ebx)
+#endif
+
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz Loop /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#if defined __CET__ && (__CET__ & 1) != 0
+ leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */
+#endif
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L0
+ CFI_ADJUST_CFA_OFFSET(4)
+L0: leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(Loop-L0-3),%eax
+ addl $4,%esp
+ CFI_ADJUST_CFA_OFFSET(-4)
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (Loop - 3)(%eax,%eax,8),%eax
+#endif
+#if defined __CET__ && (__CET__ & 1) != 0
+ addl %ebx,%eax /* Adjust for endbr32 */
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+Loop: movl (%esi),%eax
+ adcl (%edx),%eax
+ movl %eax,(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 4(%esi),%eax
+ adcl 4(%edx),%eax
+ movl %eax,4(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 8(%esi),%eax
+ adcl 8(%edx),%eax
+ movl %eax,8(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 12(%esi),%eax
+ adcl 12(%edx),%eax
+ movl %eax,12(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 16(%esi),%eax
+ adcl 16(%edx),%eax
+ movl %eax,16(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 20(%esi),%eax
+ adcl 20(%edx),%eax
+ movl %eax,20(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 24(%esi),%eax
+ adcl 24(%edx),%eax
+ movl %eax,24(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 28(%esi),%eax
+ adcl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz Loop
+
+ sbbl %eax,%eax
+ negl %eax
+
+#if defined __CET__ && (__CET__ & 1) != 0
+ popl %ebx
+ CFI_POP(%ebx)
+#endif
+
+ popl %esi
+ CFI_POP(%esi)
+ popl %edi
+ CFI_POP(%edi)
+ ret
+ CFI_ENDPROC()
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/i386/mpih-lshift.S
new file mode 100644
index 0000000000..55da0678d0
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/mpih-lshift.S
@@ -0,0 +1,102 @@
+/* i80386 lshift
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+ CFI_STARTPROC()
+ pushl %edi
+ CFI_PUSH(%edi)
+ pushl %esi
+ CFI_PUSH(%esi)
+ pushl %ebx
+ CFI_PUSH(%ebx)
+
+ movl 16(%esp),%edi /* res_ptr */
+ movl 20(%esp),%esi /* s_ptr */
+ movl 24(%esp),%edx /* size */
+ movl 28(%esp),%ecx /* cnt */
+
+ subl $4,%esi /* adjust s_ptr */
+
+ movl (%esi,%edx,4),%ebx /* read most significant limb */
+ xorl %eax,%eax
+ shldl %cl,%ebx,%eax /* compute carry limb */
+ decl %edx
+ jz Lend
+ pushl %eax /* push carry limb onto stack */
+ testb $1,%dl
+ jnz L1 /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+Loop: movl (%esi,%edx,4),%ebx /* load next lower limb */
+ shldl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ decl %edx
+L1: movl (%esi,%edx,4),%eax
+ shldl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ decl %edx
+ jnz Loop
+
+ shll %cl,%eax /* compute least significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+Lend: shll %cl,%ebx /* compute least significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ CFI_POP(%ebx)
+ popl %esi
+ CFI_POP(%esi)
+ popl %edi
+ CFI_POP(%edi)
+ ret
+ CFI_ENDPROC()
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/i386/mpih-mul1.S
new file mode 100644
index 0000000000..9679ea6224
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/mpih-mul1.S
@@ -0,0 +1,94 @@
+/* i80386 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ CFI_STARTPROC()
+ INSN1(push,l ,R(edi))
+ CFI_PUSH(%edi)
+ INSN1(push,l ,R(esi))
+ CFI_PUSH(%esi)
+ INSN1(push,l ,R(ebx))
+ CFI_PUSH(%ebx)
+ INSN1(push,l ,R(ebp))
+ CFI_PUSH(%ebp)
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ CFI_POP(%ebp)
+ INSN1(pop,l ,R(ebx))
+ CFI_POP(%ebx)
+ INSN1(pop,l ,R(esi))
+ CFI_POP(%esi)
+ INSN1(pop,l ,R(edi))
+ CFI_POP(%edi)
+ ret
+ CFI_ENDPROC()
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/i386/mpih-mul2.S
new file mode 100644
index 0000000000..fe4129c435
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/mpih-mul2.S
@@ -0,0 +1,96 @@
+/* i80386 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ CFI_STARTPROC()
+ INSN1(push,l ,R(edi))
+ CFI_PUSH(%edi)
+ INSN1(push,l ,R(esi))
+ CFI_PUSH(%esi)
+ INSN1(push,l ,R(ebx))
+ CFI_PUSH(%ebx)
+ INSN1(push,l ,R(ebp))
+ CFI_PUSH(%ebp)
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(add,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ CFI_POP(%ebp)
+ INSN1(pop,l ,R(ebx))
+ CFI_POP(%ebx)
+ INSN1(pop,l ,R(esi))
+ CFI_POP(%esi)
+ INSN1(pop,l ,R(edi))
+ CFI_POP(%edi)
+ ret
+ CFI_ENDPROC()
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/i386/mpih-mul3.S
new file mode 100644
index 0000000000..87577d54ca
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/mpih-mul3.S
@@ -0,0 +1,96 @@
+/* i80386 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ CFI_STARTPROC()
+ INSN1(push,l ,R(edi))
+ CFI_PUSH(%edi)
+ INSN1(push,l ,R(esi))
+ CFI_PUSH(%esi)
+ INSN1(push,l ,R(ebx))
+ CFI_PUSH(%ebx)
+ INSN1(push,l ,R(ebp))
+ CFI_PUSH(%ebp)
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(sub,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ CFI_POP(%ebp)
+ INSN1(pop,l ,R(ebx))
+ CFI_POP(%ebx)
+ INSN1(pop,l ,R(esi))
+ CFI_POP(%esi)
+ INSN1(pop,l ,R(edi))
+ CFI_POP(%edi)
+ ret
+ CFI_ENDPROC()
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/i386/mpih-rshift.S
new file mode 100644
index 0000000000..35a8201f35
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/mpih-rshift.S
@@ -0,0 +1,105 @@
+/* i80386 rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ CFI_STARTPROC()
+ pushl %edi
+ CFI_PUSH(%edi)
+ pushl %esi
+ CFI_PUSH(%esi)
+ pushl %ebx
+ CFI_PUSH(%ebx)
+
+ movl 16(%esp),%edi /* wp */
+ movl 20(%esp),%esi /* up */
+ movl 24(%esp),%edx /* usize */
+ movl 28(%esp),%ecx /* cnt */
+
+ leal -4(%edi,%edx,4),%edi
+ leal (%esi,%edx,4),%esi
+ negl %edx
+
+ movl (%esi,%edx,4),%ebx /* read least significant limb */
+ xorl %eax,%eax
+ shrdl %cl,%ebx,%eax /* compute carry limb */
+ incl %edx
+ jz Lend2
+ pushl %eax /* push carry limb onto stack */
+ testb $1,%dl
+ jnz L2 /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+Loop2: movl (%esi,%edx,4),%ebx /* load next higher limb */
+ shrdl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ incl %edx
+L2: movl (%esi,%edx,4),%eax
+ shrdl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ incl %edx
+ jnz Loop2
+
+ shrl %cl,%eax /* compute most significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+Lend2: shrl %cl,%ebx /* compute most significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ CFI_POP(%ebx)
+ popl %esi
+ CFI_POP(%esi)
+ popl %edi
+ CFI_POP(%edi)
+ ret
+ CFI_ENDPROC()
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/i386/mpih-sub1.S
new file mode 100644
index 0000000000..2bdc143866
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/mpih-sub1.S
@@ -0,0 +1,162 @@
+/* i80386 sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+ CFI_STARTPROC()
+ pushl %edi
+ CFI_PUSH(%edi)
+ pushl %esi
+ CFI_PUSH(%esi)
+
+ movl 12(%esp),%edi /* res_ptr */
+ movl 16(%esp),%esi /* s1_ptr */
+ movl 20(%esp),%edx /* s2_ptr */
+ movl 24(%esp),%ecx /* size */
+
+#if defined __CET__ && (__CET__ & 1) != 0
+ pushl %ebx
+ CFI_PUSH(%ebx)
+#endif
+
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz Loop /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#if defined __CET__ && (__CET__ & 1) != 0
+ leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */
+#endif
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L0
+ CFI_ADJUST_CFA_OFFSET(4)
+L0: leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(Loop-L0-3),%eax
+ addl $4,%esp
+ CFI_ADJUST_CFA_OFFSET(-4)
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (Loop - 3)(%eax,%eax,8),%eax
+#endif
+#if defined __CET__ && (__CET__ & 1) != 0
+ addl %ebx,%eax /* Adjust for endbr32 */
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+Loop: movl (%esi),%eax
+ sbbl (%edx),%eax
+ movl %eax,(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 4(%esi),%eax
+ sbbl 4(%edx),%eax
+ movl %eax,4(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 8(%esi),%eax
+ sbbl 8(%edx),%eax
+ movl %eax,8(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 12(%esi),%eax
+ sbbl 12(%edx),%eax
+ movl %eax,12(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 16(%esi),%eax
+ sbbl 16(%edx),%eax
+ movl %eax,16(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 20(%esi),%eax
+ sbbl 20(%edx),%eax
+ movl %eax,20(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 24(%esi),%eax
+ sbbl 24(%edx),%eax
+ movl %eax,24(%edi)
+#ifdef _CET_ENDBR
+ _CET_ENDBR
+#endif
+ movl 28(%esi),%eax
+ sbbl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz Loop
+
+ sbbl %eax,%eax
+ negl %eax
+
+#if defined __CET__ && (__CET__ & 1) != 0
+ popl %ebx
+ CFI_POP(%ebx)
+#endif
+
+ popl %esi
+ CFI_POP(%esi)
+ popl %edi
+ CFI_POP(%edi)
+ ret
+ CFI_ENDPROC()
+
diff --git a/comm/third_party/libgcrypt/mpi/i386/syntax.h b/comm/third_party/libgcrypt/mpi/i386/syntax.h
new file mode 100644
index 0000000000..dd30031995
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i386/syntax.h
@@ -0,0 +1,94 @@
+/* syntax.h -- Definitions for x86 syntax variations.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+
+#ifdef __i386__
+#ifdef HAVE_GCC_ASM_CFI_DIRECTIVES
+# define CFI_STARTPROC() .cfi_startproc
+# define CFI_ENDPROC() .cfi_endproc
+# define CFI_ADJUST_CFA_OFFSET(off) .cfi_adjust_cfa_offset off
+# define CFI_REL_OFFSET(reg,off) .cfi_rel_offset reg, off
+# define CFI_RESTORE(reg) .cfi_restore reg
+
+# define CFI_PUSH(reg) \
+ CFI_ADJUST_CFA_OFFSET(4); CFI_REL_OFFSET(reg, 0)
+# define CFI_POP(reg) \
+ CFI_ADJUST_CFA_OFFSET(-4); CFI_RESTORE(reg)
+#else
+# define CFI_STARTPROC()
+# define CFI_ENDPROC()
+# define CFI_ADJUST_CFA_OFFSET(off)
+# define CFI_REL_OFFSET(reg,off)
+# define CFI_RESTORE(reg)
+
+# define CFI_PUSH(reg)
+# define CFI_POP(reg)
+#endif
+#endif
+
+#undef ALIGN
+
+#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX)
+#define R(r) %r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)displacement(R(base))
+#define MEM_INDEX(base,index,size)(R(base),R(index),size)
+#ifdef __STDC__
+#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst
+#else
+#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst
+#endif
+#define TEXT .text
+#if defined (BSD_SYNTAX)
+#define ALIGN(log) .align log
+#endif
+#if defined (ELF_SYNTAX)
+#define ALIGN(log) .align 1<<(log)
+#endif
+#define GLOBL .globl
+#endif
+
+#ifdef INTEL_SYNTAX
+#define R(r) r
+#define MEM(base)[base]
+#define MEM_DISP(base,displacement)[base+(displacement)]
+#define MEM_INDEX(base,index,size)[base+index*size]
+#define INSN1(mnemonic,size_suffix,dst)mnemonic dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src
+#define TEXT .text
+#define ALIGN(log) .align log
+#define GLOBL .globl
+#endif
+
+#ifdef X86_BROKEN_ALIGN
+#undef ALIGN
+#define ALIGN(log) .align log,0x90
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/i586/README b/comm/third_party/libgcrypt/mpi/i586/README
new file mode 100644
index 0000000000..d73b082684
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/README
@@ -0,0 +1,26 @@
+This directory contains mpn functions optimized for Intel Pentium
+processors.
+
+RELEVANT OPTIMIZATION ISSUES
+
+1. Pentium doesn't allocate cache lines on writes, unlike most other modern
+processors. Since the functions in the mpn class do array writes, we have to
+handle allocating the destination cache lines by reading a word from it in the
+loops, to achieve the best performance.
+
+2. Pairing of memory operations requires that the two issued operations refer
+to different cache banks. The simplest way to insure this is to read/write
+two words from the same object. If we make operations on different objects,
+they might or might not be to the same cache bank.
+
+STATUS
+
+1. mpn_lshift and mpn_rshift run at about 6 cycles/limb, but the Pentium
+documentation indicates that they should take only 43/8 = 5.375 cycles/limb,
+or 5 cycles/limb asymptotically.
+
+2. mpn_add_n and mpn_sub_n run at asymptotically 2 cycles/limb. Due to loop
+overhead and other delays (cache refill?), they run at or near 2.5 cycles/limb.
+
+3. mpn_mul_1, mpn_addmul_1, mpn_submul_1 all run 1 cycle faster than they
+should...
diff --git a/comm/third_party/libgcrypt/mpi/i586/distfiles b/comm/third_party/libgcrypt/mpi/i586/distfiles
new file mode 100644
index 0000000000..8f821fbfb4
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/distfiles
@@ -0,0 +1,9 @@
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+README
+
diff --git a/comm/third_party/libgcrypt/mpi/i586/mpih-add1.S b/comm/third_party/libgcrypt/mpi/i586/mpih-add1.S
new file mode 100644
index 0000000000..7436d59268
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/mpih-add1.S
@@ -0,0 +1,135 @@
+/* i80586 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1996, 1998,
+ * 2001, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s1_ptr */
+ movl 28(%esp),%ebp /* s2_ptr */
+ movl 32(%esp),%ecx /* size */
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz Lend
+ pushl %edx
+
+ ALIGN (3)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L1: movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %ebx,%eax
+ movl 4(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L2: movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ adcl %ebx,%eax
+ movl 12(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L3: movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ adcl %ebx,%eax
+ movl 20(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L4: movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %ebx,%eax
+ movl 28(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz Loop
+
+ popl %edx
+Lend:
+ decl %edx /* test %edx w/o clobbering carry */
+ js Lend2
+ incl %edx
+Loop2:
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ adcl %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz Loop2
+Lend2:
+ movl (%esi),%eax
+ adcl %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
diff --git a/comm/third_party/libgcrypt/mpi/i586/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/i586/mpih-lshift.S
new file mode 100644
index 0000000000..9d25fe9d7b
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/mpih-lshift.S
@@ -0,0 +1,229 @@
+/* i80586 lshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s_ptr */
+ movl 28(%esp),%ebp /* size */
+ movl 32(%esp),%ecx /* cnt */
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne Lnormal
+ leal 4(%esi),%eax
+ cmpl %edi,%eax
+ jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */
+ leal (%esi,%ebp,4),%eax
+ cmpl %eax,%edi
+ jnc Lspecial /* jump if res_ptr >= s_ptr + size */
+
+Lnormal:
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+ xorl %eax,%eax
+ shldl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz Lend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+Loop: movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ shldl %cl,%eax,%ebx
+ shldl %cl,%edx,%eax
+ movl %ebx,(%edi)
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ shldl %cl,%ebx,%edx
+ shldl %cl,%eax,%ebx
+ movl %edx,-8(%edi)
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ shldl %cl,%edx,%eax
+ shldl %cl,%ebx,%edx
+ movl %eax,-16(%edi)
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ shldl %cl,%eax,%ebx
+ shldl %cl,%edx,%eax
+ movl %ebx,-24(%edi)
+ movl %eax,-28(%edi)
+
+ subl $32,%esi
+ subl $32,%edi
+ decl %ebp
+ jnz Loop
+
+Lend: popl %ebp
+ andl $7,%ebp
+ jz Lend2
+Loop2: movl (%esi),%eax
+ shldl %cl,%eax,%edx
+ movl %edx,(%edi)
+ movl %eax,%edx
+ subl $4,%esi
+ subl $4,%edi
+ decl %ebp
+ jnz Loop2
+
+Lend2: shll %cl,%edx /* compute least significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+Lspecial:
+ movl (%esi),%edx
+ addl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ addl %edx,%edx
+ incl %ebp
+ decl %ebp
+ jz LLend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+LLoop: movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,(%edi)
+ adcl %edx,%edx
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ adcl %ebx,%ebx
+ movl %edx,8(%edi)
+ adcl %eax,%eax
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ adcl %edx,%edx
+ movl %eax,16(%edi)
+ adcl %ebx,%ebx
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,24(%edi)
+ adcl %edx,%edx
+ movl %eax,28(%edi)
+
+ leal 32(%esi),%esi /* use leal not to clobber carry */
+ leal 32(%edi),%edi
+ decl %ebp
+ jnz LLoop
+
+LLend: popl %ebp
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebp
+ jz LLend2
+ addl %eax,%eax /* restore carry from eax */
+LLoop2: movl %edx,%ebx
+ movl (%esi),%edx
+ adcl %edx,%edx
+ movl %ebx,(%edi)
+
+ leal 4(%esi),%esi /* use leal not to clobber carry */
+ leal 4(%edi),%edi
+ decl %ebp
+ jnz LLoop2
+
+ jmp LL1
+LLend2: addl %eax,%eax /* restore carry from eax */
+LL1: movl %edx,(%edi) /* store last limb */
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
diff --git a/comm/third_party/libgcrypt/mpi/i586/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/i586/mpih-mul1.S
new file mode 100644
index 0000000000..3601d968be
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/mpih-mul1.S
@@ -0,0 +1,89 @@
+/* i80586 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/comm/third_party/libgcrypt/mpi/i586/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/i586/mpih-mul2.S
new file mode 100644
index 0000000000..f32d363a7d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/mpih-mul2.S
@@ -0,0 +1,93 @@
+/* i80586 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
+
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(add,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/comm/third_party/libgcrypt/mpi/i586/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/i586/mpih-mul3.S
new file mode 100644
index 0000000000..fa27d4e1a5
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/mpih-mul3.S
@@ -0,0 +1,93 @@
+/* i80586 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
+
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(sub,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
diff --git a/comm/third_party/libgcrypt/mpi/i586/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/i586/mpih-rshift.S
new file mode 100644
index 0000000000..c661e3d3b9
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/mpih-rshift.S
@@ -0,0 +1,228 @@
+/* i80586 rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s_ptr */
+ movl 28(%esp),%ebp /* size */
+ movl 32(%esp),%ecx /* cnt */
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne Rnormal
+ leal 4(%edi),%eax
+ cmpl %esi,%eax
+ jnc Rspecial /* jump if res_ptr + 1 >= s_ptr */
+ leal (%edi,%ebp,4),%eax
+ cmpl %eax,%esi
+ jnc Rspecial /* jump if s_ptr >= res_ptr + size */
+
+Rnormal:
+ movl (%esi),%edx
+ addl $4,%esi
+ xorl %eax,%eax
+ shrdl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz Rend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+Roop: movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ shrdl %cl,%eax,%ebx
+ shrdl %cl,%edx,%eax
+ movl %ebx,(%edi)
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ shrdl %cl,%ebx,%edx
+ shrdl %cl,%eax,%ebx
+ movl %edx,8(%edi)
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ shrdl %cl,%edx,%eax
+ shrdl %cl,%ebx,%edx
+ movl %eax,16(%edi)
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ shrdl %cl,%eax,%ebx
+ shrdl %cl,%edx,%eax
+ movl %ebx,24(%edi)
+ movl %eax,28(%edi)
+
+ addl $32,%esi
+ addl $32,%edi
+ decl %ebp
+ jnz Roop
+
+Rend: popl %ebp
+ andl $7,%ebp
+ jz Rend2
+Roop2: movl (%esi),%eax
+ shrdl %cl,%eax,%edx /* compute result limb */
+ movl %edx,(%edi)
+ movl %eax,%edx
+ addl $4,%esi
+ addl $4,%edi
+ decl %ebp
+ jnz Roop2
+
+Rend2: shrl %cl,%edx /* compute most significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+Rspecial:
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ shrl $1,%edx
+ incl %ebp
+ decl %ebp
+ jz RLend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+RLoop: movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ rcrl $1,%eax
+ movl %ebx,(%edi)
+ rcrl $1,%edx
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ rcrl $1,%ebx
+ movl %edx,-8(%edi)
+ rcrl $1,%eax
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ rcrl $1,%edx
+ movl %eax,-16(%edi)
+ rcrl $1,%ebx
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ rcrl $1,%eax
+ movl %ebx,-24(%edi)
+ rcrl $1,%edx
+ movl %eax,-28(%edi)
+
+ leal -32(%esi),%esi /* use leal not to clobber carry */
+ leal -32(%edi),%edi
+ decl %ebp
+ jnz RLoop
+
+RLend: popl %ebp
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebp
+ jz RLend2
+ addl %eax,%eax /* restore carry from eax */
+RLoop2: movl %edx,%ebx
+ movl (%esi),%edx
+ rcrl $1,%edx
+ movl %ebx,(%edi)
+
+ leal -4(%esi),%esi /* use leal not to clobber carry */
+ leal -4(%edi),%edi
+ decl %ebp
+ jnz RLoop2
+
+ jmp RL1
+RLend2: addl %eax,%eax /* restore carry from eax */
+RL1: movl %edx,(%edi) /* store last limb */
+
+ movl $0,%eax
+ rcrl $1,%eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/comm/third_party/libgcrypt/mpi/i586/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/i586/mpih-sub1.S
new file mode 100644
index 0000000000..ef2d580743
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/i586/mpih-sub1.S
@@ -0,0 +1,142 @@
+/* i80586 sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s1_ptr */
+ movl 28(%esp),%ebp /* s2_ptr */
+ movl 32(%esp),%ecx /* size */
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz Lend
+ pushl %edx
+
+ ALIGN (3)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L1: movl (%esi),%eax
+ movl 4(%esi),%edx
+ sbbl %ebx,%eax
+ movl 4(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L2: movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ sbbl %ebx,%eax
+ movl 12(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L3: movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ sbbl %ebx,%eax
+ movl 20(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L4: movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ sbbl %ebx,%eax
+ movl 28(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz Loop
+
+ popl %edx
+Lend:
+ decl %edx /* test %edx w/o clobbering carry */
+ js Lend2
+ incl %edx
+Loop2:
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ sbbl %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz Loop2
+Lend2:
+ movl (%esi),%eax
+ sbbl %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/comm/third_party/libgcrypt/mpi/longlong.h b/comm/third_party/libgcrypt/mpi/longlong.h
new file mode 100644
index 0000000000..6bb6bedfb9
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/longlong.h
@@ -0,0 +1,1801 @@
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+ Note: This is the Libgcrypt version
+
+
+Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998,
+ 2000, 2001, 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+
+This file 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.
+
+This file 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 Library General Public License
+along with this file; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+/* You have to define the following before including this file:
+
+ UWtype -- An unsigned type, default type for operations (typically a "word")
+ UHWtype -- An unsigned type, at least half the size of UWtype.
+ UDWtype -- An unsigned type, at least twice as large a UWtype
+ W_TYPE_SIZE -- size in bits of UWtype
+
+ SItype, USItype -- Signed and unsigned 32 bit types.
+ DItype, UDItype -- Signed and unsigned 64 bit types.
+
+ On a 32 bit machine UWtype should typically be USItype;
+ on a 64 bit machine, UWtype should typically be UDItype.
+*/
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+/* This is used to make sure no undesirable sharing between different libraries
+ that use this file takes place. */
+#ifndef __MPN
+# define __MPN(x) __##x
+#endif
+
+/* Define auxiliary asm macros.
+
+ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
+ UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
+ word product in HIGH_PROD and LOW_PROD.
+
+ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
+ UDWtype product. This is just a variant of umul_ppmm.
+
+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator) divides a UDWtype, composed by the UWtype integers
+ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
+ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
+ than DENOMINATOR for correct operation. If, in addition, the most
+ significant bit of DENOMINATOR must be 1, then the pre-processor symbol
+ UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator). Like udiv_qrnnd but the numbers are signed. The quotient
+ is rounded towards 0.
+
+ 5) count_leading_zeros(count, x) counts the number of zero-bits from the
+ msb to the first non-zero bit in the UWtype X. This is the number of
+ steps X needs to be shifted left to set the msb. Undefined for X == 0,
+ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
+
+ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
+ from the least significant end.
+
+ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ high_addend_2, low_addend_2) adds two UWtype integers, composed by
+ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
+ (i.e. carry out) is not stored anywhere, and is lost.
+
+ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
+ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and is lost.
+
+ If any of these macros are left undefined for a particular CPU,
+ C macros are used. */
+
+/* The CPUs come in alphabetical order below.
+
+ Please add support for more CPUs here, or improve the current support
+ for the CPUs below! */
+
+#ifdef __riscos__
+#pragma continue_after_hash_error
+#else /* !__riscos__ */
+#if defined (__GNUC__) && !defined (NO_ASM)
+
+/* We sometimes need to clobber "cc" with gcc2, but that would not be
+ understood by gcc1. Use cpp to avoid major code duplication. */
+#if __GNUC__ < 2
+# define __CLOBBER_CC
+# define __AND_CLOBBER_CC
+#else /* __GNUC__ >= 2 */
+# define __CLOBBER_CC : "cc"
+# define __AND_CLOBBER_CC , "cc"
+#endif /* __GNUC__ < 2 */
+
+/***************************************
+ **** Begin CPU Specific Versions ****
+ ***************************************/
+
+/***************************************
+ ************** A29K *****************
+ ***************************************/
+#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %1,%4,%5\n" \
+ "addc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %1,%4,%5\n" \
+ "subc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+# define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("multiplu %0,%1,%2" \
+ : "=r" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ __asm__ ("multmu %0,%1,%2" \
+ : "=r" ((USItype)(xh)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ } while (0)
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("dividu %0,%3,%4" \
+ : "=r" ((USItype)(q)), \
+ "=q" ((USItype)(r)) \
+ : "1" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d)))
+# define count_leading_zeros(count, x) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+# define COUNT_LEADING_ZEROS_0 32
+#endif /* __a29k__ */
+
+
+#if defined (__alpha) && W_TYPE_SIZE == 64
+# define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh %r1,%2,%0" \
+ : "=r" ((UDItype) ph) \
+ : "%rJ" (__m0), \
+ "rI" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+# define UMUL_TIME 46
+# ifndef LONGLONG_STANDALONE
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UDItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UDItype __udiv_qrnnd ();
+# define UDIV_TIME 220
+# endif /* !LONGLONG_STANDALONE */
+#endif /* __alpha */
+
+/***************************************
+ ************** ARM ******************
+ ***************************************/
+#if defined (__arm__) && W_TYPE_SIZE == 32 && \
+ (!defined (__thumb__) || defined (__thumb2__))
+/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
+# ifndef __ARM_ARCH
+# ifdef __ARM_ARCH_2__
+# define __ARM_ARCH 2
+# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
+# define __ARM_ARCH 3
+# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__)
+# define __ARM_ARCH 4
+# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \
+ || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__)
+# define __ARM_ARCH 5
+# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+ || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
+# define __ARM_ARCH 6
+# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__)
+# define __ARM_ARCH 7
+# else
+ /* could not detect? */
+# endif
+# endif /* !__ARM_ARCH */
+
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5\n" \
+ "adc %0, %2, %3" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) __CLOBBER_CC)
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5\n" \
+ "sbc %0, %2, %3" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) __CLOBBER_CC)
+# if (defined __ARM_ARCH && __ARM_ARCH <= 3)
+# define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("@ Inlined umul_ppmm\n" \
+ "mov %|r0, %2, lsr #16 @ AAAA\n" \
+ "mov %|r2, %3, lsr #16 @ BBBB\n" \
+ "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \
+ "bic %0, %3, %|r2, lsl #16 @ bbbb\n" \
+ "mul %1, %|r1, %|r2 @ aaaa * BBBB\n" \
+ "mul %|r2, %|r0, %|r2 @ AAAA * BBBB\n" \
+ "mul %|r1, %0, %|r1 @ aaaa * bbbb\n" \
+ "mul %0, %|r0, %0 @ AAAA * bbbb\n" \
+ "adds %|r0, %1, %0 @ central sum\n" \
+ "addcs %|r2, %|r2, #65536\n" \
+ "adds %1, %|r1, %|r0, lsl #16\n" \
+ "adc %0, %|r2, %|r0, lsr #16" \
+ : "=&r" ((xh)), \
+ "=r" ((xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
+ : "r0", "r1", "r2" __AND_CLOBBER_CC)
+# else /* __ARM_ARCH >= 4 */
+# define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("@ Inlined umul_ppmm\n" \
+ "umull %1, %0, %2, %3" \
+ : "=&r" ((xh)), \
+ "=r" ((xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)))
+# endif /* __ARM_ARCH >= 4 */
+# define UMUL_TIME 20
+# define UDIV_TIME 100
+# if (defined __ARM_ARCH && __ARM_ARCH >= 5)
+# define count_leading_zeros(count, x) \
+ __asm__ ("clz %0, %1" \
+ : "=r" ((count)) \
+ : "r" ((USItype)(x)))
+# endif /* __ARM_ARCH >= 5 */
+#endif /* __arm__ */
+
+/***************************************
+ ********** ARM64 / Aarch64 **********
+ ***************************************/
+#if defined(__aarch64__) && W_TYPE_SIZE == 64
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5\n" \
+ "adc %0, %2, %3\n" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((UDItype)(ah)), \
+ "r" ((UDItype)(bh)), \
+ "r" ((UDItype)(al)), \
+ "r" ((UDItype)(bl)) __CLOBBER_CC)
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5\n" \
+ "sbc %0, %2, %3\n" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((UDItype)(ah)), \
+ "r" ((UDItype)(bh)), \
+ "r" ((UDItype)(al)), \
+ "r" ((UDItype)(bl)) __CLOBBER_CC)
+# define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1), __ph; \
+ (pl) = __m0 * __m1; \
+ __asm__ ("umulh %0,%1,%2" \
+ : "=r" (__ph) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ (ph) = __ph; \
+ } while (0)
+# define count_leading_zeros(count, x) \
+ do { \
+ UDItype __co; \
+ __asm__ ("clz %0, %1\n" \
+ : "=r" (__co) \
+ : "r" ((UDItype)(x))); \
+ (count) = __co; \
+ } while (0)
+#endif /* __aarch64__ */
+
+/***************************************
+ ************** CLIPPER **************
+ ***************************************/
+#if defined (__clipper__) && W_TYPE_SIZE == 32
+# define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+# define smul_ppmm(w1, w0, u, v) \
+ ({union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("mulwx %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((SItype)(u)), \
+ "r" ((SItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+# define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__w) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ __w; })
+#endif /* __clipper__ */
+
+
+/***************************************
+ ************** GMICRO ***************
+ ***************************************/
+#if defined (__gmicro__) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.w %5,%1\n" \
+ "addx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.w %5,%1\n" \
+ "subx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+# define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("mulx %3,%0,%1" \
+ : "=g" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%0" ((USItype)(m0)), \
+ "g" ((USItype)(m1)))
+# define udiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("divx %4,%0,%1" \
+ : "=g" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "1" ((USItype)(nh)), \
+ "0" ((USItype)(nl)), \
+ "g" ((USItype)(d)))
+# define count_leading_zeros(count, x) \
+ __asm__ ("bsch/1 %1,%0" \
+ : "=g" (count) \
+ : "g" ((USItype)(x)), \
+ "0" ((USItype)0))
+#endif
+
+
+/***************************************
+ ************** HPPA *****************
+ ***************************************/
+#if defined (__hppa) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ (" add %4,%5,%1\n" \
+ " addc %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "%rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ (" sub %4,%5,%1\n" \
+ " subb %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+# if defined (_PA_RISC1_1)
+# define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ (" xmpyu %1,%2,%0" \
+ : "=*f" (__xx.__ll) \
+ : "*f" ((USItype)(u)), \
+ "*f" ((USItype)(v))); \
+ (wh) = __xx.__i.__h; \
+ (wl) = __xx.__i.__l; \
+ } while (0)
+# define UMUL_TIME 8
+# define UDIV_TIME 60
+# else
+# define UMUL_TIME 40
+# define UDIV_TIME 80
+# endif
+# ifndef LONGLONG_STANDALONE
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ do { USItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern USItype __udiv_qrnnd ();
+# endif /* !LONGLONG_STANDALONE */
+# define count_leading_zeros(count, x) \
+ do { \
+ USItype __tmp; \
+ __asm__ ( \
+ " ldi 1,%0 \n" \
+ " extru,= %1,15,16,%%r0 ; Bits 31..16 zero? \n" \
+ " extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \
+ " ldo 16(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,23,8,%%r0 ; Bits 15..8 zero? \n" \
+ " extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \
+ " ldo 8(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,27,4,%%r0 ; Bits 7..4 zero? \n" \
+ " extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \
+ " ldo 4(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,29,2,%%r0 ; Bits 3..2 zero? \n" \
+ " extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \
+ " ldo 2(%0),%0 ; Yes. Perform add. \n" \
+ " extru %1,30,1,%1 ; Extract bit 1. \n" \
+ " sub %0,%1,%0 ; Subtract it. " \
+ : "=r" (count), "=r" (__tmp) : "1" (x)); \
+ } while (0)
+#endif /* hppa */
+
+
+/***************************************
+ ************** I370 *****************
+ ***************************************/
+#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
+# define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "r" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+# define smul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (m0), \
+ "r" (m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ } while (0)
+# define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("dr %0,%2" \
+ : "=r" (__xx.__ll) \
+ : "0" (__xx.__ll), "r" (d)); \
+ (q) = __xx.__i.__l; (r) = __xx.__i.__h; \
+ } while (0)
+#endif
+
+
+/***************************************
+ ************** I386 *****************
+ ***************************************/
+#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl %5,%1\n" \
+ "adcl %3,%0" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)) \
+ __CLOBBER_CC)
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl %5,%1\n" \
+ "sbbl %3,%0" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)) \
+ __CLOBBER_CC)
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mull %3" \
+ : "=a" ((w0)), \
+ "=d" ((w1)) \
+ : "%0" ((USItype)(u)), \
+ "rm" ((USItype)(v)) \
+ __CLOBBER_CC)
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divl %4" \
+ : "=a" ((q)), \
+ "=d" ((r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "rm" ((USItype)(d)) \
+ __CLOBBER_CC)
+# define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("bsrl %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((USItype)(x)) \
+ __CLOBBER_CC); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+# define count_trailing_zeros(count, x) \
+ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)) __CLOBBER_CC)
+# ifndef UMUL_TIME
+# define UMUL_TIME 40
+# endif
+# ifndef UDIV_TIME
+# define UDIV_TIME 40
+# endif
+#endif /* 80x86 */
+
+/***************************************
+ *********** AMD64 / x86-64 ************
+ ***************************************/
+#if defined(__x86_64) && W_TYPE_SIZE == 64
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addq %5,%1\n" \
+ "adcq %3,%0" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "0" ((UDItype)(ah)), \
+ "g" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), \
+ "g" ((UDItype)(bl)) \
+ __CLOBBER_CC)
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subq %5,%1\n" \
+ "sbbq %3,%0" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "0" ((UDItype)(ah)), \
+ "g" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), \
+ "g" ((UDItype)(bl)) \
+ __CLOBBER_CC)
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulq %3" \
+ : "=a" ((w0)), \
+ "=d" ((w1)) \
+ : "0" ((UDItype)(u)), \
+ "rm" ((UDItype)(v)) \
+ __CLOBBER_CC)
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divq %4" \
+ : "=a" ((q)), \
+ "=d" ((r)) \
+ : "0" ((UDItype)(n0)), \
+ "1" ((UDItype)(n1)), \
+ "rm" ((UDItype)(d)) \
+ __CLOBBER_CC)
+# define count_leading_zeros(count, x) \
+ do { \
+ UDItype __cbtmp; \
+ __asm__ ("bsrq %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((UDItype)(x)) \
+ __CLOBBER_CC); \
+ (count) = __cbtmp ^ 63; \
+ } while (0)
+# define count_trailing_zeros(count, x) \
+ do { \
+ UDItype __cbtmp; \
+ __asm__ ("bsfq %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((UDItype)(x)) \
+ __CLOBBER_CC); \
+ (count) = __cbtmp; \
+ } while (0)
+# ifndef UMUL_TIME
+# define UMUL_TIME 40
+# endif
+# ifndef UDIV_TIME
+# define UDIV_TIME 40
+# endif
+#endif /* __x86_64 */
+
+
+/***************************************
+ ************** I860 *****************
+ ***************************************/
+#if defined (__i860__) && W_TYPE_SIZE == 32
+# define rshift_rhlc(r,h,l,c) \
+ __asm__ ("shr %3,r0,r0\n" \
+ "shrd %1,%2,%0" \
+ "=r" (r) : "r" (h), "r" (l), "rn" (c))
+#endif /* i860 */
+
+/***************************************
+ ************** I960 *****************
+ ***************************************/
+#if defined (__i960__) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 1,0\n" \
+ "addc %5,%4,%1\n" \
+ "addc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "%dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 0,0\n" \
+ "subc %5,%4,%1\n" \
+ "subc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+# define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__xx.__ll) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+# define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__w) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ __w; })
+# define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (nh); __nn.__i.__l = (nl); \
+ __asm__ ("ediv %d,%n,%0" \
+ : "=d" (__rq.__ll) \
+ : "dI" (__nn.__ll), \
+ "dI" ((USItype)(d))); \
+ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
+ } while (0)
+# define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("scanbit %1,%0" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+# define COUNT_LEADING_ZEROS_0 (-32) /* sic */
+# if defined (__i960mx) /* what is the proper symbol to test??? */
+# define rshift_rhlc(r,h,l,c) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (h); __nn.__i.__l = (l); \
+ __asm__ ("shre %2,%1,%0" \
+ : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
+ }
+# endif /* i960mx */
+#endif /* i960 */
+
+
+/***************************************
+ ************** 68000 ****************
+ ***************************************/
+#if (defined (__mc68000__) || defined (__mc68020__) \
+ || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%.l %5,%1\n" \
+ "addx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%.l %5,%1\n" \
+ "subx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+# if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulu%.l %3,%1:%0" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "dmi" ((USItype)(v)))
+# define UMUL_TIME 45
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divu%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+# define UDIV_TIME 90
+# define sdiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divs%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+# define count_leading_zeros(count, x) \
+ __asm__ ("bfffo %1{%b2:%b2},%0" \
+ : "=d" ((USItype)(count)) \
+ : "od" ((USItype)(x)), "n" (0))
+# define COUNT_LEADING_ZEROS_0 32
+# else /* not mc68020 */
+# define umul_ppmm(xh, xl, a, b) \
+ do { USItype __umul_tmp1, __umul_tmp2; \
+ __asm__ ("| Inlined umul_ppmm \n" \
+ " move%.l %5,%3 \n" \
+ " move%.l %2,%0 \n" \
+ " move%.w %3,%1 \n" \
+ " swap %3 \n" \
+ " swap %0 \n" \
+ " mulu %2,%1 \n" \
+ " mulu %3,%0 \n" \
+ " mulu %2,%3 \n" \
+ " swap %2 \n" \
+ " mulu %5,%2 \n" \
+ " add%.l %3,%2 \n" \
+ " jcc 1f \n" \
+ " add%.l %#0x10000,%0 \n" \
+ "1: move%.l %2,%3 \n" \
+ " clr%.w %2 \n" \
+ " swap %2 \n" \
+ " swap %3 \n" \
+ " clr%.w %3 \n" \
+ " add%.l %3,%1 \n" \
+ " addx%.l %2,%0 \n" \
+ " | End inlined umul_ppmm" \
+ : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \
+ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
+ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
+ } while (0)
+# define UMUL_TIME 100
+# define UDIV_TIME 400
+# endif /* not mc68020 */
+#endif /* mc68000 */
+
+
+/***************************************
+ ************** 88000 ****************
+ ***************************************/
+#if defined (__m88000__) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addu.co %1,%r4,%r5\n" \
+ "addu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subu.co %1,%r4,%r5\n" \
+ "subu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+# define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("ff1 %0,%1" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+# define COUNT_LEADING_ZEROS_0 63 /* sic */
+# if defined (__m88110__)
+# define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
+ } while (0)
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x, __q; \
+ __x.__i.__h = (n1); __x.__i.__l = (n0); \
+ __asm__ ("divu.d %0,%1,%2" \
+ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
+ (r) = (n0) - __q.__l * (d); (q) = __q.__l; })
+# define UMUL_TIME 5
+# define UDIV_TIME 25
+# else
+# define UMUL_TIME 17
+# define UDIV_TIME 150
+# endif /* __m88110__ */
+#endif /* __m88000__ */
+
+/***************************************
+ ************** MIPS *****************
+ ***************************************/
+#if defined (__mips__) && W_TYPE_SIZE == 32
+# if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && \
+ __GNUC_MINOR__ >= 4)
+# define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UDItype _r; \
+ _r = (UDItype) u * v; \
+ (w1) = _r >> 32; \
+ (w0) = (USItype) _r; \
+ } while (0)
+# elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3" \
+ : "=l" ((USItype)(w0)), \
+ "=h" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+# else
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3 \n" \
+ "mflo %0 \n" \
+ "mfhi %1" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+# endif
+# define UMUL_TIME 10
+# define UDIV_TIME 100
+#endif /* __mips__ */
+
+/***************************************
+ ************** MIPS/64 **************
+ ***************************************/
+#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+# if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && \
+ __GNUC_MINOR__ >= 4)
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+# define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UTItype _r; \
+ _r = (UTItype) u * v; \
+ (w1) = _r >> 64; \
+ (w0) = (UDItype) _r; \
+ } while (0)
+# elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" \
+ : "=l" ((UDItype)(w0)), \
+ "=h" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+# else
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3 \n" \
+ "mflo %0 \n" \
+ "mfhi %1" \
+ : "=d" ((UDItype)(w0)), \
+ "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+# endif
+# define UMUL_TIME 20
+# define UDIV_TIME 140
+#endif /* __mips__ */
+
+
+/***************************************
+ ************** 32000 ****************
+ ***************************************/
+#if defined (__ns32000__) && W_TYPE_SIZE == 32
+# define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+# define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__w) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ __w; })
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
+ __asm__ ("deid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "0" (__xx.__ll), \
+ "g" ((USItype)(d))); \
+ (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
+# define count_trailing_zeros(count,x) \
+ do {
+ __asm__ ("ffsd %2,%0" \
+ : "=r" ((USItype) (count)) \
+ : "0" ((USItype) 0), \
+ "r" ((USItype) (x))); \
+ } while (0)
+#endif /* __ns32000__ */
+
+
+/***************************************
+ ************** PPC ******************
+ ***************************************/
+#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "%r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ } while (0)
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ } while (0)
+# define count_leading_zeros(count, x) \
+ __asm__ ("{cntlz|cntlzw} %0,%1" \
+ : "=r" ((count)) \
+ : "r" ((USItype)(x)))
+# define COUNT_LEADING_ZEROS_0 32
+# if defined (_ARCH_PPC)
+# define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhwu %0,%1,%2" \
+ : "=r" (ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+# define UMUL_TIME 15
+# define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ SItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhw %0,%1,%2" \
+ : "=r" ((SItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+# define SMUL_TIME 14
+# define UDIV_TIME 120
+# else
+# define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((xh)), \
+ "=q" ((xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+# define UMUL_TIME 8
+# define smul_ppmm(xh, xl, m0, m1) \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((SItype)(xh)), \
+ "=q" ((SItype)(xl)) \
+ : "r" (m0), \
+ "r" (m1))
+# define SMUL_TIME 4
+# define sdiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("div %0,%2,%4" \
+ : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \
+ : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d)))
+# define UDIV_TIME 100
+# endif
+#endif /* Power architecture variants. */
+
+/* Powerpc 64 bit support taken from gmp-4.1.2. */
+/* We should test _IBMR2 here when we add assembly support for the system
+ vendor compilers. */
+#if (defined (_ARCH_PPC) || defined (__powerpc__)) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 64
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ DItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14 /* ??? */
+#define UDIV_TIME 120 /* ??? */
+#endif /* 64-bit PowerPC. */
+
+/***************************************
+ ************** PYR ******************
+ ***************************************/
+#if defined (__pyr__) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addw %5,%1 \n" \
+ "addwc %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subw %5,%1 \n" \
+ "subwb %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
+# define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("movw %1,%R0 \n" \
+ "uemul %2,%0" \
+ : "=&r" (__xx.__ll) \
+ : "g" ((USItype) (u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#endif /* __pyr__ */
+
+
+/***************************************
+ ************** RT/ROMP **************
+ ***************************************/
+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("a %1,%5 \n" \
+ "ae %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("s %1,%5\n" \
+ "se %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+# define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ( \
+ "s r2,r2 \n" \
+ "mts r10,%2 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "cas %0,r2,r0 \n" \
+ "mfs r10,%1" \
+ : "=r" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%r" (__m0), \
+ "r" (__m1) \
+ : "r2"); \
+ (ph) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+# define UMUL_TIME 20
+# define UDIV_TIME 200
+# define count_leading_zeros(count, x) \
+ do { \
+ if ((x) >= 0x10000) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x) >> 16)); \
+ else \
+ { \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x))); \
+ (count) += 16; \
+ } \
+ } while (0)
+#endif /* RT/ROMP */
+
+
+/***************************************
+ ************** SH2 ******************
+ ***************************************/
+#if (defined (__sh2__) || defined(__sh3__) || defined(__SH4__) ) \
+ && W_TYPE_SIZE == 32
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ( \
+ "dmulu.l %2,%3\n" \
+ "sts macl,%1\n" \
+ "sts mach,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "macl", "mach")
+# define UMUL_TIME 5
+#endif
+
+/***************************************
+ ************** SPARC ****************
+ ***************************************/
+#if defined (__sparc__) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addcc %r4,%5,%1\n" \
+ "addx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subcc %r4,%5,%1\n" \
+ "subx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+# if defined (__sparc_v8__) || defined(__sparcv8)
+/* Don't match immediate range because, 1) it is not often useful,
+ 2) the 'I' flag thinks of the range as a 13 bit signed interval,
+ while we want to match a 13 bit interval, sign extended to 32 bits,
+ but INTERPRETED AS UNSIGNED. */
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+# define UMUL_TIME 5
+# ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" ((USItype)(__q)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d))); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+ } while (0)
+# define UDIV_TIME 25
+# endif /*!SUPERSPARC */
+# else /* ! __sparc_v8__ */
+# if defined (__sparclite__)
+/* This has hardware multiply but not divide. It also has two additional
+ instructions scan (ffs from high bit) and divscc. */
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+# define UMUL_TIME 5
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("! Inlined udiv_qrnnd \n" \
+ " wr %%g0,%2,%%y ! Not a delayed write for sparclite \n" \
+ " tst %%g0 \n" \
+ " divscc %3,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%0 \n" \
+ " rd %%y,%1 \n" \
+ " bl,a 1f \n" \
+ " add %1,%4,%1 \n" \
+ "1: ! End of inline udiv_qrnnd" \
+ : "=r" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "rI" ((USItype)(d)) \
+ : "%g1" __AND_CLOBBER_CC)
+# define UDIV_TIME 37
+# define count_leading_zeros(count, x) \
+ __asm__ ("scan %1,0,%0" \
+ : "=r" ((USItype)(x)) \
+ : "r" ((USItype)(count)))
+/* Early sparclites return 63 for an argument of 0, but they warn that future
+ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
+ undefined. */
+# endif /* !__sparclite__ */
+# endif /* !__sparc_v8__ */
+/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
+# ifndef umul_ppmm
+# define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("! Inlined umul_ppmm \n" \
+ " wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr \n" \
+ " sra %3,31,%%g2 ! Don't move this insn \n" \
+ " and %2,%%g2,%%g2 ! Don't move this insn \n" \
+ " andcc %%g0,0,%%g1 ! Don't move this insn \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,0,%%g1 \n" \
+ " add %%g1,%%g2,%0 \n" \
+ " rd %%y,%1" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "%rI" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "%g1", "%g2" __AND_CLOBBER_CC)
+# define UMUL_TIME 39 /* 39 instructions */
+# endif /* umul_ppmm */
+# ifndef udiv_qrnnd
+# ifndef LONGLONG_STANDALONE
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ do { USItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern USItype __udiv_qrnnd ();
+# define UDIV_TIME 140
+# endif /* LONGLONG_STANDALONE */
+# endif /* udiv_qrnnd */
+#endif /* __sparc__ */
+
+
+/***************************************
+ ************** VAX ******************
+ ***************************************/
+#if defined (__vax__) && W_TYPE_SIZE == 32
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl2 %5,%1\n" \
+ "adwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl2 %5,%1\n" \
+ "sbwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+# define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("emul %1,%2,$0,%0" \
+ : "=g" (__xx.__ll) \
+ : "g" (__m0), \
+ "g" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+# define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("ediv %3,%2,%0,%1" \
+ : "=g" (q), "=g" (r) \
+ : "g" (__xx.__ll), "g" (d)); \
+ } while (0)
+#endif /* __vax__ */
+
+
+/***************************************
+ ************** Z8000 ****************
+ ***************************************/
+#if defined (__z8000__) && W_TYPE_SIZE == 16
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "%0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "%1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+# define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {long int __ll; \
+ struct {unsigned int __h, __l;} __i; \
+ } __xx; \
+ unsigned int __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mult %S0,%H3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "rQR" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ + (((signed int) __m1 >> 15) & __m0)); \
+ } while (0)
+#endif /* __z8000__ */
+
+
+/***************************************
+ *********** s390x/zSeries ************
+ ***************************************/
+#if defined (__s390x__) && W_TYPE_SIZE == 64 && __GNUC__ >= 4
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("algr %1,%5\n" \
+ "alcgr %0,%3\n" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "0" ((UDItype)(ah)), \
+ "r" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), \
+ "r" ((UDItype)(bl)) \
+ __CLOBBER_CC)
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("slgr %1,%5\n" \
+ "slbgr %0,%3\n" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "0" ((UDItype)(ah)), \
+ "r" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), \
+ "r" ((UDItype)(bl)) \
+ __CLOBBER_CC)
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+# define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UTItype ___r; \
+ __asm__ ("mlgr %0,%2" \
+ : "=r" (___r) \
+ : "0" ((UDItype)(u)), \
+ "r" ((UDItype)(v))); \
+ (w1) = ___r >> 64; \
+ (w0) = (UDItype) ___r; \
+ } while (0)
+# define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ UTItype ___r = ((UTItype)n1 << 64) | n0; \
+ __asm__ ("dlgr %0,%2" \
+ : "=r" (___r) \
+ : "0" (___r), \
+ "r" ((UDItype)(d))); \
+ (r) = ___r >> 64; \
+ (q) = (UDItype) ___r; \
+ } while (0)
+#endif /* __s390x__ */
+
+
+/***************************************
+ ***** End CPU Specific Versions *****
+ ***************************************/
+
+#endif /* __GNUC__ */
+#endif /* !__riscos__ */
+
+
+/***************************************
+ *********** Generic Versions ********
+ ***************************************/
+#if !defined (umul_ppmm) && defined (__umulsidi3)
+# define umul_ppmm(ph, pl, m0, m1) \
+ { \
+ UDWtype __ll = __umulsidi3 (m0, m1); \
+ ph = (UWtype) (__ll >> W_TYPE_SIZE); \
+ pl = (UWtype) __ll; \
+ }
+#endif
+
+#if !defined (__umulsidi3)
+# define __umulsidi3(u, v) \
+ ({UWtype __hi, __lo; \
+ umul_ppmm (__hi, __lo, u, v); \
+ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
+#endif
+
+/* If this machine has no inline assembler, use C macros. */
+
+#if !defined (add_ssaaaa)
+# define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) + (bl); \
+ (sh) = (ah) + (bh) + (__x < (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (sub_ddmmss)
+# define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - (__x > (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (umul_ppmm)
+# define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ UWtype __u = (u), __v = (v); \
+ \
+ __ul = __ll_lowpart (__u); \
+ __uh = __ll_highpart (__u); \
+ __vl = __ll_lowpart (__v); \
+ __vh = __ll_highpart (__v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
+ } while (0)
+#endif
+
+#if !defined (umul_ppmm)
+# define smul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __w1; \
+ UWtype __m0 = (u), __m1 = (v); \
+ umul_ppmm (__w1, w0, __m0, __m1); \
+ (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
+ - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
+ } while (0)
+#endif
+
+/* Define this unconditionally, so it can be used for debugging. */
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
+ __d1 = __ll_highpart (d); \
+ __d0 = __ll_lowpart (d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (UWtype) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (UWtype) __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (UWtype) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+ __udiv_w_sdiv (defined in libgcc or elsewhere). */
+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
+# define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ UWtype __r; \
+ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
+ (r) = __r; \
+ } while (0)
+#endif
+
+/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
+#if !defined (udiv_qrnnd)
+# define UDIV_NEEDS_NORMALIZATION 1
+# define udiv_qrnnd __udiv_qrnnd_c
+#endif
+
+#if !defined (count_leading_zeros)
+# if defined (HAVE_BUILTIN_CLZL) && SIZEOF_UNSIGNED_LONG * 8 == W_TYPE_SIZE
+# define count_leading_zeros(count, x) (count = __builtin_clzl(x))
+# undef COUNT_LEADING_ZEROS_0 /* Input X=0 is undefined for the builtin. */
+# elif defined (HAVE_BUILTIN_CLZ) && SIZEOF_UNSIGNED_INT * 8 == W_TYPE_SIZE
+# define count_leading_zeros(count, x) (count = __builtin_clz(x))
+# undef COUNT_LEADING_ZEROS_0 /* Input X=0 is undefined for the builtin. */
+# endif
+#endif
+
+#if !defined (count_trailing_zeros)
+# if defined (HAVE_BUILTIN_CTZL) && SIZEOF_UNSIGNED_LONG * 8 == W_TYPE_SIZE
+# define count_trailing_zeros(count, x) (count = __builtin_ctzl(x))
+# undef COUNT_LEADING_ZEROS_0 /* Input X=0 is undefined for the builtin. */
+# elif defined (HAVE_BUILTIN_CTZ) && SIZEOF_UNSIGNED_INT * 8 == W_TYPE_SIZE
+# define count_trailing_zeros(count, x) (count = __builtin_ctz(x))
+# undef COUNT_LEADING_ZEROS_0 /* Input X=0 is undefined for the builtin. */
+# endif
+#endif
+
+#if !defined (count_leading_zeros)
+extern
+# ifdef __STDC__
+const
+# endif
+unsigned char _gcry_clz_tab[];
+# define MPI_INTERNAL_NEED_CLZ_TAB 1
+# define count_leading_zeros(count, x) \
+ do { \
+ UWtype __xr = (x); \
+ UWtype __a; \
+ \
+ if (W_TYPE_SIZE <= 32) \
+ { \
+ __a = __xr < ((UWtype) 1 << 2*__BITS4) \
+ ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
+ : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\
+ } \
+ else \
+ { \
+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ } \
+ \
+ (count) = W_TYPE_SIZE - (_gcry_clz_tab[__xr >> __a] + __a); \
+ } while (0)
+/* This version gives a well-defined value for zero. */
+# define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
+#endif /* !count_leading_zeros */
+
+#if !defined (count_trailing_zeros)
+/* Define count_trailing_zeros using count_leading_zeros. The latter might be
+ defined in asm, but if it is not, the C version above is good enough. */
+# define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ UWtype __ctz_c; \
+ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
+ (count) = W_TYPE_SIZE - 1 - __ctz_c; \
+ } while (0)
+#endif /* !count_trailing_zeros */
+
+#ifndef UDIV_NEEDS_NORMALIZATION
+# define UDIV_NEEDS_NORMALIZATION 0
+#endif
+
+/***************************************
+ ****** longlong.h ends here *********
+ ***************************************/
diff --git a/comm/third_party/libgcrypt/mpi/m68k/distfiles b/comm/third_party/libgcrypt/mpi/m68k/distfiles
new file mode 100644
index 0000000000..4c0967b840
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/distfiles
@@ -0,0 +1,8 @@
+syntax.h
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+mpih-sub1.S
+
+
+
diff --git a/comm/third_party/libgcrypt/mpi/m68k/mc68020/distfiles b/comm/third_party/libgcrypt/mpi/m68k/mc68020/distfiles
new file mode 100644
index 0000000000..fc7df9fa35
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/mc68020/distfiles
@@ -0,0 +1,3 @@
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
diff --git a/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S
new file mode 100644
index 0000000000..007c94c6db
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S
@@ -0,0 +1,104 @@
+/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+PROLOG(_gcry_mpih_mul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d4),MEM_PREDEC(sp)
+#if 0
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(d3),MEM_PREDEC(sp)
+ movel R(d4),MEM_PREDEC(sp)
+#endif
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,16),R(res_ptr)
+ movel MEM_DISP(sp,20),R(s1_ptr)
+ movel MEM_DISP(sp,24),R(s1_size)
+ movel MEM_DISP(sp,28),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ movel R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ movel R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ clrl R(d3)
+ addxl R(d3),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d4)
+#if 0
+ movel MEM_POSTINC(sp),R(d4)
+ movel MEM_POSTINC(sp),R(d3)
+ movel MEM_POSTINC(sp),R(d2)
+#endif
+ rts
+EPILOG(_gcry_mpih_mul_1)
+
+
diff --git a/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S
new file mode 100644
index 0000000000..44baa8d887
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S
@@ -0,0 +1,94 @@
+/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+PROLOG(_gcry_mpih_addmul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d5),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,20),R(res_ptr)
+ movel MEM_DISP(sp,24),R(s1_ptr)
+ movel MEM_DISP(sp,28),R(s1_size)
+ movel MEM_DISP(sp,32),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ clrl R(d5)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ addxl R(d5),R(d1)
+ addl R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ addxl R(d5),R(d0)
+ addl R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ addxl R(d5),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d5)
+
+ rts
+EPILOG(_gcry_mpih_addmul_1)
+
diff --git a/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S
new file mode 100644
index 0000000000..e958ef6117
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S
@@ -0,0 +1,97 @@
+/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+PROLOG(_gcry_mpih_submul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d5),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,20),R(res_ptr)
+ movel MEM_DISP(sp,24),R(s1_ptr)
+ movel MEM_DISP(sp,28),R(s1_size)
+ movel MEM_DISP(sp,32),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ clrl R(d5)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ addxl R(d5),R(d1)
+ subl R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ addxl R(d5),R(d0)
+ subl R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ addxl R(d5),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d5)
+
+ rts
+EPILOG(_gcry_mpih_submul_1)
+
+
diff --git a/comm/third_party/libgcrypt/mpi/m68k/mpih-add1.S b/comm/third_party/libgcrypt/mpi/m68k/mpih-add1.S
new file mode 100644
index 0000000000..8182d21a32
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/mpih-add1.S
@@ -0,0 +1,92 @@
+/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994,1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 16)
+ * mpi_size_t size) (sp + 12)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n)
+
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+PROLOG(_gcry_mpih_add_n)
+ /* Save used registers on the stack. */
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,12),R(a2)
+ movel MEM_DISP(sp,16),R(a0)
+ movel MEM_DISP(sp,20),R(a1)
+ movel MEM_DISP(sp,24),R(d2)
+
+ eorw #1,R(d2)
+ lsrl #1,R(d2)
+ bcc L(L1)
+ subql #1,R(d2) /* clears cy as side effect */
+
+L(Loop:)
+ movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ addxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+L(L1:) movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ addxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+
+ dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */
+ subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */
+ subl #0x10000,R(d2)
+ bcs L(L2)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(Loop)
+
+L(L2:)
+ negl R(d0)
+
+ /* Restore used registers from stack frame. */
+ movel MEM_POSTINC(sp),R(a2)
+ movel MEM_POSTINC(sp),R(d2)
+
+ rts
+EPILOG(_gcry_mpih_add_n)
+
+
diff --git a/comm/third_party/libgcrypt/mpi/m68k/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/m68k/mpih-lshift.S
new file mode 100644
index 0000000000..133d1aae3d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/mpih-lshift.S
@@ -0,0 +1,164 @@
+/* mc68020 lshift -- Shift left a low-level natural-number integer.
+ *
+ * Copyright (C) 1996, 1998, 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+#define res_ptr a1
+#define s_ptr a0
+#define s_size d6
+#define cnt d4
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_lshift)
+
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+PROLOG(_gcry_mpih_lshift)
+
+ /* Save used registers on the stack. */
+ moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. */
+ movel MEM_DISP(sp,28),R(res_ptr)
+ movel MEM_DISP(sp,32),R(s_ptr)
+ movel MEM_DISP(sp,36),R(s_size)
+ movel MEM_DISP(sp,40),R(cnt)
+
+ moveql #1,R(d5)
+ cmpl R(d5),R(cnt)
+ bne L(Lnormal)
+ cmpl R(s_ptr),R(res_ptr)
+ bls L(Lspecial) /* jump if s_ptr >= res_ptr */
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(a2)
+#else /* not mc68020 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ lea MEM_INDX(s_ptr,d0,l),R(a2)
+#endif
+ cmpl R(res_ptr),R(a2)
+ bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */
+
+L(Lnormal:)
+ moveql #32,R(d5)
+ subl R(cnt),R(d5)
+
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
+#else /* not mc68000 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ addl R(s_size),R(s_ptr)
+ addl R(s_size),R(res_ptr)
+#endif
+ movel MEM_PREDEC(s_ptr),R(d2)
+ movel R(d2),R(d0)
+ lsrl R(d5),R(d0) /* compute carry limb */
+
+ lsll R(cnt),R(d2)
+ movel R(d2),R(d1)
+ subql #1,R(s_size)
+ beq L(Lend)
+ lsrl #1,R(s_size)
+ bcs L(L1)
+ subql #1,R(s_size)
+
+L(Loop:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ movel R(d2),R(d3)
+ lsrl R(d5),R(d3)
+ orl R(d3),R(d1)
+ movel R(d1),MEM_PREDEC(res_ptr)
+ lsll R(cnt),R(d2)
+L(L1:)
+ movel MEM_PREDEC(s_ptr),R(d1)
+ movel R(d1),R(d3)
+ lsrl R(d5),R(d3)
+ orl R(d3),R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+ lsll R(cnt),R(d1)
+
+ dbf R(s_size),L(Loop)
+ subl #0x10000,R(s_size)
+ bcc L(Loop)
+
+L(Lend:)
+ movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination. */
+
+L(Lspecial:)
+ clrl R(d0) /* initialize carry */
+ eorw #1,R(s_size)
+ lsrl #1,R(s_size)
+ bcc L(LL1)
+ subql #1,R(s_size)
+
+L(LLoop:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ addxl R(d2),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+L(LL1:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ addxl R(d2),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+
+ dbf R(s_size),L(LLoop)
+ addxl R(d0),R(d0) /* save cy in lsb */
+ subl #0x10000,R(s_size)
+ bcs L(LLend)
+ lsrl #1,R(d0) /* restore cy */
+ bra L(LLoop)
+
+L(LLend:)
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+EPILOG(_gcry_mpih_lshift)
+
+
+
+
+
diff --git a/comm/third_party/libgcrypt/mpi/m68k/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/m68k/mpih-rshift.S
new file mode 100644
index 0000000000..be9f43502f
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/mpih-rshift.S
@@ -0,0 +1,162 @@
+/* mc68020 rshift -- Shift right a low-level natural-number integer.
+ *
+ * Copyright (C) 1996, 1998, 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+#define res_ptr a1
+#define s_ptr a0
+#define s_size d6
+#define cnt d4
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_rshift)
+
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+PROLOG(_gcry_mpih_rshift)
+ /* Save used registers on the stack. */
+ moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. */
+ movel MEM_DISP(sp,28),R(res_ptr)
+ movel MEM_DISP(sp,32),R(s_ptr)
+ movel MEM_DISP(sp,36),R(s_size)
+ movel MEM_DISP(sp,40),R(cnt)
+
+ moveql #1,R(d5)
+ cmpl R(d5),R(cnt)
+ bne L(Rnormal)
+ cmpl R(res_ptr),R(s_ptr)
+ bls L(Rspecial) /* jump if res_ptr >= s_ptr */
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(a2)
+#else /* not mc68020 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ lea MEM_INDX(res_ptr,d0,l),R(a2)
+#endif
+ cmpl R(s_ptr),R(a2)
+ bls L(Rspecial) /* jump if s_ptr >= res_ptr + s_size */
+
+L(Rnormal:)
+ moveql #32,R(d5)
+ subl R(cnt),R(d5)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ movel R(d2),R(d0)
+ lsll R(d5),R(d0) /* compute carry limb */
+
+ lsrl R(cnt),R(d2)
+ movel R(d2),R(d1)
+ subql #1,R(s_size)
+ beq L(Rend)
+ lsrl #1,R(s_size)
+ bcs L(R1)
+ subql #1,R(s_size)
+
+L(Roop:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ movel R(d2),R(d3)
+ lsll R(d5),R(d3)
+ orl R(d3),R(d1)
+ movel R(d1),MEM_POSTINC(res_ptr)
+ lsrl R(cnt),R(d2)
+L(R1:)
+ movel MEM_POSTINC(s_ptr),R(d1)
+ movel R(d1),R(d3)
+ lsll R(d5),R(d3)
+ orl R(d3),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+ lsrl R(cnt),R(d1)
+
+ dbf R(s_size),L(Roop)
+ subl #0x10000,R(s_size)
+ bcc L(Roop)
+
+L(Rend:)
+ movel R(d1),MEM(res_ptr) /* store most significant limb */
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+
+/* We loop from most significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination. */
+
+L(Rspecial:)
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
+#else /* not mc68000 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ addl R(s_size),R(s_ptr)
+ addl R(s_size),R(res_ptr)
+#endif
+
+ clrl R(d0) /* initialize carry */
+ eorw #1,R(s_size)
+ lsrl #1,R(s_size)
+ bcc L(LR1)
+ subql #1,R(s_size)
+
+L(LRoop:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ roxrl #1,R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+L(LR1:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ roxrl #1,R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+
+ dbf R(s_size),L(LRoop)
+ roxrl #1,R(d0) /* save cy in msb */
+ subl #0x10000,R(s_size)
+ bcs L(LRend)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(LRoop)
+
+L(LRend:)
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+EPILOG(_gcry_mpih_rshift)
+
+
+
+
diff --git a/comm/third_party/libgcrypt/mpi/m68k/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/m68k/mpih-sub1.S
new file mode 100644
index 0000000000..ee7555f897
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/mpih-sub1.S
@@ -0,0 +1,91 @@
+/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 16)
+ * mpi_size_t size) (sp + 12)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_sub_n)
+
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+PROLOG(_gcry_mpih_sub_n)
+/* Save used registers on the stack. */
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(a2),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,12),R(a2)
+ movel MEM_DISP(sp,16),R(a0)
+ movel MEM_DISP(sp,20),R(a1)
+ movel MEM_DISP(sp,24),R(d2)
+
+ eorw #1,R(d2)
+ lsrl #1,R(d2)
+ bcc L(L1)
+ subql #1,R(d2) /* clears cy as side effect */
+
+L(Loop:)
+ movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ subxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+L(L1:) movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ subxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+
+ dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */
+ subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */
+ subl #0x10000,R(d2)
+ bcs L(L2)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(Loop)
+
+L(L2:)
+ negl R(d0)
+
+/* Restore used registers from stack frame. */
+ movel MEM_POSTINC(sp),R(a2)
+ movel MEM_POSTINC(sp),R(d2)
+
+ rts
+EPILOG(_gcry_mpih_sub_n)
+
+
diff --git a/comm/third_party/libgcrypt/mpi/m68k/syntax.h b/comm/third_party/libgcrypt/mpi/m68k/syntax.h
new file mode 100644
index 0000000000..e27de98b4f
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/m68k/syntax.h
@@ -0,0 +1,185 @@
+/* asm.h -- Definitions for 68k syntax variations.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#undef ALIGN
+
+#ifdef MIT_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)base@
+#define MEM_DISP(base,displacement)base@(displacement)
+#define MEM_INDX(base,idx,size_suffix)base@(idx:size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)base@(idx:size_suffix:scale)
+#define MEM_PREDEC(memory_base)memory_base@-
+#define MEM_POSTINC(memory_base)memory_base@+
+#define L(label) label
+#define TEXT .text
+#define ALIGN .even
+#define GLOBL .globl
+#define moveql moveq
+/* Use variable sized opcodes. */
+#define bcc jcc
+#define bcs jcs
+#define bls jls
+#define beq jeq
+#define bne jne
+#define bra jra
+#endif
+
+#ifdef SONY_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)(displacement,base)
+#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale)
+#define MEM_PREDEC(memory_base)-(memory_base)
+#define MEM_POSTINC(memory_base)(memory_base)+
+#define L(label) label
+#define TEXT .text
+#define ALIGN .even
+#define GLOBL .globl
+#endif
+
+#ifdef MOTOROLA_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)(displacement,base)
+#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale)
+#define MEM_PREDEC(memory_base)-(memory_base)
+#define MEM_POSTINC(memory_base)(memory_base)+
+#define L(label) label
+#define TEXT
+#define ALIGN
+#define GLOBL XDEF
+#define lea LEA
+#define movel MOVE.L
+#define moveml MOVEM.L
+#define moveql MOVEQ.L
+#define cmpl CMP.L
+#define orl OR.L
+#define clrl CLR.L
+#define eorw EOR.W
+#define lsrl LSR.L
+#define lsll LSL.L
+#define roxrl ROXR.L
+#define roxll ROXL.L
+#define addl ADD.L
+#define addxl ADDX.L
+#define addql ADDQ.L
+#define subl SUB.L
+#define subxl SUBX.L
+#define subql SUBQ.L
+#define negl NEG.L
+#define mulul MULU.L
+#define bcc BCC
+#define bcs BCS
+#define bls BLS
+#define beq BEQ
+#define bne BNE
+#define bra BRA
+#define dbf DBF
+#define rts RTS
+#define d0 D0
+#define d1 D1
+#define d2 D2
+#define d3 D3
+#define d4 D4
+#define d5 D5
+#define d6 D6
+#define d7 D7
+#define a0 A0
+#define a1 A1
+#define a2 A2
+#define a3 A3
+#define a4 A4
+#define a5 A5
+#define a6 A6
+#define a7 A7
+#define sp SP
+#endif
+
+#ifdef ELF_SYNTAX
+#define PROLOG(name) .type name,@function
+#define EPILOG(name) .size name,.-name
+#define MEM(base)(R(base))
+#define MEM_DISP(base,displacement)(displacement,R(base))
+#define MEM_PREDEC(memory_base)-(R(memory_base))
+#define MEM_POSTINC(memory_base)(R(memory_base))+
+#ifdef __STDC__
+#define R_(r)%##r
+#define R(r)R_(r)
+#define MEM_INDX_(base,idx,size_suffix)(R(base),R(idx##.##size_suffix))
+#define MEM_INDX(base,idx,size_suffix)MEM_INDX_(base,idx,size_suffix)
+#define MEM_INDX1_(base,idx,size_suffix,scale)(R(base),R(idx##.##size_suffix*scale))
+#define MEM_INDX1(base,idx,size_suffix,scale)MEM_INDX1_(base,idx,size_suffix,scale)
+#define L(label) .##label
+#else
+#define R(r)%/**/r
+#define MEM_INDX(base,idx,size_suffix)(R(base),R(idx).size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(R(base),R(idx).size_suffix*scale)
+#define L(label) ./**/label
+#endif
+#define TEXT .text
+#define ALIGN .align 2
+#define GLOBL .globl
+#define bcc jbcc
+#define bcs jbcs
+#define bls jbls
+#define beq jbeq
+#define bne jbne
+#define bra jbra
+#endif
+
+#if defined (SONY_SYNTAX) || defined (ELF_SYNTAX)
+#define movel move.l
+#define moveml movem.l
+#define moveql moveq.l
+#define cmpl cmp.l
+#define orl or.l
+#define clrl clr.l
+#define eorw eor.w
+#define lsrl lsr.l
+#define lsll lsl.l
+#define roxrl roxr.l
+#define roxll roxl.l
+#define addl add.l
+#define addxl addx.l
+#define addql addq.l
+#define subl sub.l
+#define subxl subx.l
+#define subql subq.l
+#define negl neg.l
+#define mulul mulu.l
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/mips3/README b/comm/third_party/libgcrypt/mpi/mips3/README
new file mode 100644
index 0000000000..4ba4546d9f
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/README
@@ -0,0 +1,23 @@
+This directory contains mpn functions optimized for MIPS3. Example of
+processors that implement MIPS3 are R4000, R4400, R4600, R4700, and R8000.
+
+RELEVANT OPTIMIZATION ISSUES
+
+1. On the R4000 and R4400, branches, both the plain and the "likely" ones,
+ take 3 cycles to execute. (The fastest possible loop will take 4 cycles,
+ because of the delay insn.)
+
+ On the R4600, branches takes a single cycle
+
+ On the R8000, branches often take no noticeable cycles, as they are
+ executed in a separate function unit..
+
+2. The R4000 and R4400 have a load latency of 4 cycles.
+
+3. On the R4000 and R4400, multiplies take a data-dependent number of
+ cycles, contrary to the SGI documentation. There seem to be 3 or 4
+ possible latencies.
+
+STATUS
+
+Good...
diff --git a/comm/third_party/libgcrypt/mpi/mips3/distfiles b/comm/third_party/libgcrypt/mpi/mips3/distfiles
new file mode 100644
index 0000000000..85260fc8e7
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/distfiles
@@ -0,0 +1,10 @@
+README
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpi-asm-defs.h
+
diff --git a/comm/third_party/libgcrypt/mpi/mips3/mpi-asm-defs.h b/comm/third_party/libgcrypt/mpi/mips3/mpi-asm-defs.h
new file mode 100644
index 0000000000..2d9a9c1f2c
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/mpi-asm-defs.h
@@ -0,0 +1,10 @@
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB 8
+
+
+
+
+
+
diff --git a/comm/third_party/libgcrypt/mpi/mips3/mpih-add1.S b/comm/third_party/libgcrypt/mpi/mips3/mpih-add1.S
new file mode 100644
index 0000000000..f3db029de4
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/mpih-add1.S
@@ -0,0 +1,124 @@
+/* mips3 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2000
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($4)
+ * mpi_ptr_t s1_ptr, ($5)
+ * mpi_ptr_t s2_ptr, ($6)
+ * mpi_size_t size) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_add_n
+ .ent _gcry_mpih_add_n
+_gcry_mpih_add_n:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$2
+ ld $11,16($6)
+ sltu $8,$13,$2
+ daddu $13,$12,$13
+ sltu $2,$13,$12
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$2
+ ld $13,24($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$2
+ ld $11,32($6)
+ sltu $8,$13,$2
+ daddu $13,$12,$13
+ sltu $2,$13,$12
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+
+ .end _gcry_mpih_add_n
+
diff --git a/comm/third_party/libgcrypt/mpi/mips3/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/mips3/mpih-lshift.S
new file mode 100644
index 0000000000..084c109b24
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/mpih-lshift.S
@@ -0,0 +1,97 @@
+/* mips3 lshift
+ *
+ * Copyright (C) 1995, 1998, 2000,
+ * 2001, 2002 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
+ */
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, ($4)
+ * mpi_ptr_t up, ($5)
+ * mpi_size_t usize, ($6)
+ * unsigned cnt) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_lshift
+ .ent _gcry_mpih_lshift
+_gcry_mpih_lshift:
+ .set noreorder
+ .set nomacro
+
+ dsll $2,$6,3
+ daddu $5,$5,$2 # make r5 point at end of src
+ ld $10,-8($5) # load first limb
+ dsubu $13,$0,$7
+ daddu $4,$4,$2 # make r4 point at end of res
+ daddiu $6,$6,-1
+ and $9,$6,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ dsrl $2,$10,$13 # compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,-16($5)
+ daddiu $4,$4,-8
+ daddiu $5,$5,-8
+ daddiu $9,$9,-1
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,0($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,-16($5)
+ daddiu $4,$4,-32
+ daddiu $6,$6,-4
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+
+ ld $10,-24($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,24($4)
+ dsrl $9,$10,$13
+
+ ld $3,-32($5)
+ dsll $11,$10,$7
+ or $8,$14,$9
+ sd $8,16($4)
+ dsrl $12,$3,$13
+
+ ld $10,-40($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,8($4)
+ dsrl $9,$10,$13
+
+ daddiu $5,$5,-32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,0($4)
+
+.Lend: dsll $8,$10,$7
+ j $31
+ sd $8,-8($4)
+ .end _gcry_mpih_lshift
diff --git a/comm/third_party/libgcrypt/mpi/mips3/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/mips3/mpih-mul1.S
new file mode 100644
index 0000000000..6c0099de3f
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/mpih-mul1.S
@@ -0,0 +1,89 @@
+/* mips3 mpih-mul1.S -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_mul_1
+ .ent _gcry_mpih_mul_1
+_gcry_mpih_mul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: mflo $10
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $10,$10,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$10,$2 # carry from previous addition -> $2
+ sd $10,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ dmultu $8,$7
+ sd $10,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ sd $10,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_mul_1
+
diff --git a/comm/third_party/libgcrypt/mpi/mips3/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/mips3/mpih-mul2.S
new file mode 100644
index 0000000000..ca8276388f
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/mpih-mul2.S
@@ -0,0 +1,101 @@
+/* MIPS3 addmul_1 -- Multiply a limb vector with a single limb and
+ * add the product to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_addmul_1
+ .ent _gcry_mpih_addmul_1
+_gcry_mpih_addmul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$3,$2 # carry from previous addition -> $2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_addmul_1
+
diff --git a/comm/third_party/libgcrypt/mpi/mips3/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/mips3/mpih-mul3.S
new file mode 100644
index 0000000000..be421a68ee
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/mpih-mul3.S
@@ -0,0 +1,101 @@
+/* MIPS3 submul_1 -- Multiply a limb vector with a single limb and
+ * subtract the product from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_submul_1
+ .ent _gcry_mpih_submul_1
+_gcry_mpih_submul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$3,$2 # carry from previous addition -> $2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_submul_1
+
diff --git a/comm/third_party/libgcrypt/mpi/mips3/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/mips3/mpih-rshift.S
new file mode 100644
index 0000000000..e7e035a034
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/mpih-rshift.S
@@ -0,0 +1,95 @@
+/* mips3 rshift
+ *
+ * Copyright (C) 1995, 1998, 2000
+ * 2001, 2002 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
+ */
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, ($4)
+ * mpi_ptr_t up, ($5)
+ * mpi_size_t usize, ($6)
+ * unsigned cnt) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_rshift
+ .ent _gcry_mpih_rshift
+_gcry_mpih_rshift:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5) # load first limb
+ dsubu $13,$0,$7
+ daddiu $6,$6,-1
+ and $9,$6,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ dsll $2,$10,$13 # compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,8($5)
+ daddiu $4,$4,8
+ daddiu $5,$5,8
+ daddiu $9,$9,-1
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,-8($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,8($5)
+ daddiu $4,$4,32
+ daddiu $6,$6,-4
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+
+ ld $10,16($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-32($4)
+ dsll $9,$10,$13
+
+ ld $3,24($5)
+ dsrl $11,$10,$7
+ or $8,$14,$9
+ sd $8,-24($4)
+ dsll $12,$3,$13
+
+ ld $10,32($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-16($4)
+ dsll $9,$10,$13
+
+ daddiu $5,$5,32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,-8($4)
+
+.Lend: dsrl $8,$10,$7
+ j $31
+ sd $8,0($4)
+ .end _gcry_mpih_rshift
+
diff --git a/comm/third_party/libgcrypt/mpi/mips3/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/mips3/mpih-sub1.S
new file mode 100644
index 0000000000..9fac674399
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mips3/mpih-sub1.S
@@ -0,0 +1,125 @@
+/* mips3 sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ *
+ * Copyright (C) 1995, 1998, 1999, 2000,
+ * 2001, 2002 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
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_ptr_t s2_ptr, (r6)
+ * mpi_size_t size) (r7)
+ */
+
+
+ .text
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .ent _gcry_mpih_sub_n
+_gcry_mpih_sub_n:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$2
+ ld $11,16($6)
+ sltu $8,$13,$2
+ dsubu $13,$12,$13
+ sltu $2,$12,$13
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$2
+ ld $13,24($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$2
+ ld $11,32($6)
+ sltu $8,$13,$2
+ dsubu $13,$12,$13
+ sltu $2,$12,$13
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+
+ .end _gcry_mpih_sub_n
+
diff --git a/comm/third_party/libgcrypt/mpi/mpi-add.c b/comm/third_party/libgcrypt/mpi/mpi-add.c
new file mode 100644
index 0000000000..53f476e060
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-add.c
@@ -0,0 +1,235 @@
+/* mpi-add.c - MPI functions
+ * Copyright (C) 1994, 1996, 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+
+
+/****************
+ * Add the unsigned integer V to the mpi-integer U and store the
+ * result in W. U and V may be the same.
+ */
+void
+_gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize, wsize;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+ wsign = 0;
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = usize + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->d;
+ wp = w->d;
+
+ if( !usize ) { /* simple */
+ wp[0] = v;
+ wsize = v? 1:0;
+ }
+ else if( !usign ) { /* mpi is not negative */
+ mpi_limb_t cy;
+ cy = _gcry_mpih_add_1(wp, up, usize, v);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ }
+ else { /* The signs are different. Need exact comparison to determine
+ * which operand to subtract from which. */
+ if( usize == 1 && up[0] < v ) {
+ wp[0] = v - up[0];
+ wsize = 1;
+ }
+ else {
+ _gcry_mpih_sub_1(wp, up, usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = usize - (wp[usize-1]==0);
+ wsign = 1;
+ }
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+void
+_gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t usize, vsize, wsize;
+ int usign, vsign, wsign;
+
+ if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
+ usize = v->nlimbs;
+ usign = v->sign;
+ vsize = u->nlimbs;
+ vsign = u->sign;
+ wsize = usize + 1;
+ RESIZE_IF_NEEDED(w, wsize);
+ /* These must be after realloc (u or v may be the same as w). */
+ up = v->d;
+ vp = u->d;
+ }
+ else {
+ usize = u->nlimbs;
+ usign = u->sign;
+ vsize = v->nlimbs;
+ vsign = v->sign;
+ wsize = usize + 1;
+ RESIZE_IF_NEEDED(w, wsize);
+ /* These must be after realloc (u or v may be the same as w). */
+ up = u->d;
+ vp = v->d;
+ }
+ wp = w->d;
+ wsign = 0;
+
+ if( !vsize ) { /* simple */
+ MPN_COPY(wp, up, usize );
+ wsize = usize;
+ wsign = usign;
+ }
+ else if( usign != vsign ) { /* different sign */
+ /* This test is right since USIZE >= VSIZE */
+ if( usize != vsize ) {
+ _gcry_mpih_sub(wp, up, usize, vp, vsize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ wsign = usign;
+ }
+ else if( _gcry_mpih_cmp(up, vp, usize) < 0 ) {
+ _gcry_mpih_sub_n(wp, vp, up, usize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ if( !usign )
+ wsign = 1;
+ }
+ else {
+ _gcry_mpih_sub_n(wp, up, vp, usize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ if( usign )
+ wsign = 1;
+ }
+ }
+ else { /* U and V have same sign. Add them. */
+ mpi_limb_t cy = _gcry_mpih_add(wp, up, usize, vp, vsize);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ if( usign )
+ wsign = 1;
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+/****************
+ * Subtract the unsigned integer V from the mpi-integer U and store the
+ * result in W.
+ */
+void
+_gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize, wsize;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+ wsign = 0;
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = usize + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->d;
+ wp = w->d;
+
+ if( !usize ) { /* simple */
+ wp[0] = v;
+ wsize = v? 1:0;
+ wsign = 1;
+ }
+ else if( usign ) { /* mpi and v are negative */
+ mpi_limb_t cy;
+ cy = _gcry_mpih_add_1(wp, up, usize, v);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ }
+ else { /* The signs are different. Need exact comparison to determine
+ * which operand to subtract from which. */
+ if( usize == 1 && up[0] < v ) {
+ wp[0] = v - up[0];
+ wsize = 1;
+ wsign = 1;
+ }
+ else {
+ _gcry_mpih_sub_1(wp, up, usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = usize - (wp[usize-1]==0);
+ }
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+void
+_gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ gcry_mpi_t vv = mpi_copy (v);
+ vv->sign = ! vv->sign;
+ mpi_add (w, u, vv);
+ mpi_free (vv);
+}
+
+
+void
+_gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ mpi_add (w, u, v);
+ mpi_mod (w, w, m);
+}
+
+void
+_gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ mpi_sub (w, u, v);
+ mpi_mod (w, w, m);
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpi-bit.c b/comm/third_party/libgcrypt/mpi/mpi-bit.c
new file mode 100644
index 0000000000..e2170401e4
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-bit.c
@@ -0,0 +1,411 @@
+/* mpi-bit.c - MPI bit level functions
+ * Copyright (C) 1998, 1999, 2001, 2002, 2006 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+#ifdef MPI_INTERNAL_NEED_CLZ_TAB
+#ifdef __STDC__
+const
+#endif
+unsigned char
+_gcry_clz_tab[] =
+{
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+#endif
+
+
+#define A_LIMB_1 ((mpi_limb_t)1)
+
+
+/****************
+ * Sometimes we have MSL (most significant limbs) which are 0;
+ * this is for some reasons not good, so this function removes them.
+ */
+void
+_gcry_mpi_normalize( gcry_mpi_t a )
+{
+ if( mpi_is_opaque(a) )
+ return;
+
+ for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
+ ;
+}
+
+
+
+/****************
+ * Return the number of bits in A.
+ */
+unsigned int
+_gcry_mpi_get_nbits (gcry_mpi_t a)
+{
+ unsigned n;
+
+ if( mpi_is_opaque(a) ) {
+ return a->sign; /* which holds the number of bits */
+ }
+
+ _gcry_mpi_normalize( a );
+ if( a->nlimbs ) {
+ mpi_limb_t alimb = a->d[a->nlimbs-1];
+ if( alimb )
+ count_leading_zeros( n, alimb );
+ else
+ n = BITS_PER_MPI_LIMB;
+ n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
+ }
+ else
+ n = 0;
+ return n;
+}
+
+
+/****************
+ * Test whether bit N is set.
+ */
+int
+_gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+ mpi_limb_t limb;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return 0; /* too far left: this is a 0 */
+ limb = a->d[limbno];
+ return (limb & (A_LIMB_1 << bitno))? 1: 0;
+}
+
+
+/****************
+ * Set bit N of A.
+ */
+void
+_gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int i, limbno, bitno;
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if ( limbno >= a->nlimbs )
+ {
+ for (i=a->nlimbs; i < a->alloced; i++)
+ a->d[i] = 0;
+ mpi_resize (a, limbno+1 );
+ a->nlimbs = limbno+1;
+ }
+ a->d[limbno] |= (A_LIMB_1<<bitno);
+}
+
+/****************
+ * Set bit N of A. and clear all bits above
+ */
+void
+_gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int i, limbno, bitno;
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if ( limbno >= a->nlimbs )
+ {
+ for (i=a->nlimbs; i < a->alloced; i++)
+ a->d[i] = 0;
+ mpi_resize (a, limbno+1 );
+ a->nlimbs = limbno+1;
+ }
+ a->d[limbno] |= (A_LIMB_1<<bitno);
+ for ( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
+}
+
+/****************
+ * clear bit N of A and all bits above
+ */
+void
+_gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return; /* not allocated, therefore no need to clear bits :-) */
+
+ for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
+}
+
+/****************
+ * Clear bit N of A.
+ */
+void
+_gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if (limbno >= a->nlimbs)
+ return; /* Don't need to clear this bit, it's far too left. */
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+}
+
+
+/****************
+ * Shift A by COUNT limbs to the right
+ * This is used only within the MPI library
+ */
+void
+_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
+{
+ mpi_ptr_t ap = a->d;
+ mpi_size_t n = a->nlimbs;
+ unsigned int i;
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ if (count >= n)
+ {
+ a->nlimbs = 0;
+ return;
+ }
+
+ for( i = 0; i < n - count; i++ )
+ ap[i] = ap[i+count];
+ ap[i] = 0;
+ a->nlimbs -= count;
+}
+
+
+/*
+ * Shift A by N bits to the right.
+ */
+void
+_gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+{
+ mpi_size_t xsize;
+ unsigned int i;
+ unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
+ unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+
+ if (mpi_is_immutable (x))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ if ( x == a )
+ {
+ /* In-place operation. */
+ if ( nlimbs >= x->nlimbs )
+ {
+ x->nlimbs = 0;
+ return;
+ }
+
+ if (nlimbs)
+ {
+ for (i=0; i < x->nlimbs - nlimbs; i++ )
+ x->d[i] = x->d[i+nlimbs];
+ x->d[i] = 0;
+ x->nlimbs -= nlimbs;
+
+ }
+ if ( x->nlimbs && nbits )
+ _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits );
+ }
+ else if ( nlimbs )
+ {
+ /* Copy and shift by more or equal bits than in a limb. */
+ xsize = a->nlimbs;
+ x->sign = a->sign;
+ RESIZE_IF_NEEDED (x, xsize);
+ x->nlimbs = xsize;
+ for (i=0; i < a->nlimbs; i++ )
+ x->d[i] = a->d[i];
+ x->nlimbs = i;
+
+ if ( nlimbs >= x->nlimbs )
+ {
+ x->nlimbs = 0;
+ return;
+ }
+
+ if (nlimbs)
+ {
+ for (i=0; i < x->nlimbs - nlimbs; i++ )
+ x->d[i] = x->d[i+nlimbs];
+ x->d[i] = 0;
+ x->nlimbs -= nlimbs;
+ }
+
+ if ( x->nlimbs && nbits )
+ _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits );
+ }
+ else
+ {
+ /* Copy and shift by less than bits in a limb. */
+ xsize = a->nlimbs;
+ x->sign = a->sign;
+ RESIZE_IF_NEEDED (x, xsize);
+ x->nlimbs = xsize;
+
+ if ( xsize )
+ {
+ if (nbits )
+ _gcry_mpih_rshift (x->d, a->d, x->nlimbs, nbits );
+ else
+ {
+ /* The rshift helper function is not specified for
+ NBITS==0, thus we do a plain copy here. */
+ for (i=0; i < x->nlimbs; i++ )
+ x->d[i] = a->d[i];
+ }
+ }
+ }
+ MPN_NORMALIZE (x->d, x->nlimbs);
+}
+
+
+/****************
+ * Shift A by COUNT limbs to the left
+ * This is used only within the MPI library
+ */
+void
+_gcry_mpi_lshift_limbs (gcry_mpi_t a, unsigned int count)
+{
+ mpi_ptr_t ap;
+ int n = a->nlimbs;
+ int i;
+
+ if (!count || !n)
+ return;
+
+ RESIZE_IF_NEEDED (a, n+count);
+
+ ap = a->d;
+ for (i = n-1; i >= 0; i--)
+ ap[i+count] = ap[i];
+ for (i=0; i < count; i++ )
+ ap[i] = 0;
+ a->nlimbs += count;
+}
+
+
+/*
+ * Shift A by N bits to the left.
+ */
+void
+_gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+{
+ unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
+ unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+
+ if (mpi_is_immutable (x))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ if (x == a && !n)
+ return; /* In-place shift with an amount of zero. */
+
+ if ( x != a )
+ {
+ /* Copy A to X. */
+ unsigned int alimbs = a->nlimbs;
+ int asign = a->sign;
+ mpi_ptr_t xp, ap;
+
+ RESIZE_IF_NEEDED (x, alimbs+nlimbs+1);
+ xp = x->d;
+ ap = a->d;
+ MPN_COPY (xp, ap, alimbs);
+ x->nlimbs = alimbs;
+ x->flags = a->flags;
+ x->sign = asign;
+ }
+
+ if (nlimbs && !nbits)
+ {
+ /* Shift a full number of limbs. */
+ _gcry_mpi_lshift_limbs (x, nlimbs);
+ }
+ else if (n)
+ {
+ /* We use a very dump approach: Shift left by the number of
+ limbs plus one and than fix it up by an rshift. */
+ _gcry_mpi_lshift_limbs (x, nlimbs+1);
+ mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits);
+ }
+
+ MPN_NORMALIZE (x->d, x->nlimbs);
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpi-cmp.c b/comm/third_party/libgcrypt/mpi/mpi-cmp.c
new file mode 100644
index 0000000000..8927fa0ecb
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-cmp.c
@@ -0,0 +1,130 @@
+/* mpi-cmp.c - MPI functions
+ * Copyright (C) 1998, 1999, 2001, 2002, 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+int
+_gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
+{
+ mpi_limb_t limb = v;
+
+ _gcry_mpi_normalize (u);
+
+ /* Handle the case that U contains no limb. */
+ if (u->nlimbs == 0)
+ return -(limb != 0);
+
+ /* Handle the case that U is negative. */
+ if (u->sign)
+ return -1;
+
+ if (u->nlimbs == 1)
+ {
+ /* Handle the case that U contains exactly one limb. */
+
+ if (u->d[0] > limb)
+ return 1;
+ if (u->d[0] < limb)
+ return -1;
+ return 0;
+ }
+ else
+ /* Handle the case that U contains more than one limb. */
+ return 1;
+}
+
+
+/* Helper for _gcry_mpi_cmp and _gcry_mpi_cmpabs. */
+static int
+do_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v, int absmode)
+{
+ mpi_size_t usize;
+ mpi_size_t vsize;
+ int usign;
+ int vsign;
+ int cmp;
+
+ if (mpi_is_opaque (u) || mpi_is_opaque (v))
+ {
+ /* We have no signan and thus ABSMODE has no efeect here. */
+ if (mpi_is_opaque (u) && !mpi_is_opaque (v))
+ return -1;
+ if (!mpi_is_opaque (u) && mpi_is_opaque (v))
+ return 1;
+ if (!u->sign && !v->sign)
+ return 0; /* Empty buffers are identical. */
+ if (u->sign < v->sign)
+ return -1;
+ if (u->sign > v->sign)
+ return 1;
+ return memcmp (u->d, v->d, (u->sign+7)/8);
+ }
+ else
+ {
+ _gcry_mpi_normalize (u);
+ _gcry_mpi_normalize (v);
+
+ usize = u->nlimbs;
+ vsize = v->nlimbs;
+ usign = absmode? 0 : u->sign;
+ vsign = absmode? 0 : v->sign;
+
+ /* Special treatment for +0 == -0 */
+ if (!usize && !vsize)
+ return 0;
+
+ /* Compare sign bits. */
+ if (!usign && vsign)
+ return 1;
+ if (usign && !vsign)
+ return -1;
+
+ /* U and V are either both positive or both negative. */
+
+ if (usize != vsize && !usign && !vsign)
+ return usize - vsize;
+ if (usize != vsize && usign && vsign)
+ return vsize + usize;
+ if (!usize )
+ return 0;
+ if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize)))
+ return 0;
+ if ((cmp < 0?1:0) == (usign?1:0))
+ return 1;
+ }
+ return -1;
+}
+
+
+int
+_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
+{
+ return do_mpi_cmp (u, v, 0);
+}
+
+/* Compare only the absolute values. */
+int
+_gcry_mpi_cmpabs (gcry_mpi_t u, gcry_mpi_t v)
+{
+ return do_mpi_cmp (u, v, 1);
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpi-div.c b/comm/third_party/libgcrypt/mpi/mpi-div.c
new file mode 100644
index 0000000000..166ab87519
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-div.c
@@ -0,0 +1,360 @@
+/* mpi-div.c - MPI functions
+ * Copyright (C) 1994, 1996, 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+void
+_gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ int divisor_sign = divisor->sign;
+ gcry_mpi_t temp_divisor = NULL;
+
+ /* We need the original value of the divisor after the remainder has been
+ * preliminary calculated. We have to copy it to temporary space if it's
+ * the same variable as REM. */
+ if( rem == divisor ) {
+ temp_divisor = mpi_copy( divisor );
+ divisor = temp_divisor;
+ }
+
+ _gcry_mpi_tdiv_r( rem, dividend, divisor );
+
+ if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
+ mpi_add (rem, rem, divisor);
+
+ if( temp_divisor )
+ mpi_free(temp_divisor);
+}
+
+
+
+/****************
+ * Division rounding the quotient towards -infinity.
+ * The remainder gets the same sign as the denominator.
+ * rem is optional
+ */
+
+unsigned long
+_gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend,
+ unsigned long divisor )
+{
+ mpi_limb_t rlimb;
+
+ rlimb = _gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor );
+ if( rlimb && dividend->sign )
+ rlimb = divisor - rlimb;
+
+ if( rem ) {
+ rem->d[0] = rlimb;
+ rem->nlimbs = rlimb? 1:0;
+ }
+ return rlimb;
+}
+
+
+void
+_gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ gcry_mpi_t tmp = mpi_alloc( mpi_get_nlimbs(quot) );
+ _gcry_mpi_fdiv_qr( quot, tmp, dividend, divisor);
+ mpi_free(tmp);
+}
+
+void
+_gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ int divisor_sign = divisor->sign;
+ gcry_mpi_t temp_divisor = NULL;
+
+ if( quot == divisor || rem == divisor ) {
+ temp_divisor = mpi_copy( divisor );
+ divisor = temp_divisor;
+ }
+
+ _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor );
+
+ if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
+ mpi_sub_ui( quot, quot, 1 );
+ mpi_add( rem, rem, divisor);
+ }
+
+ if( temp_divisor )
+ mpi_free(temp_divisor);
+}
+
+
+/* If den == quot, den needs temporary storage.
+ * If den == rem, den needs temporary storage.
+ * If num == quot, num needs temporary storage.
+ * If den has temporary storage, it can be normalized while being copied,
+ * i.e no extra storage should be allocated.
+ */
+
+void
+_gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den)
+{
+ _gcry_mpi_tdiv_qr(NULL, rem, num, den );
+}
+
+void
+_gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den)
+{
+ mpi_ptr_t np, dp;
+ mpi_ptr_t qp, rp;
+ mpi_size_t nsize = num->nlimbs;
+ mpi_size_t dsize = den->nlimbs;
+ mpi_size_t qsize, rsize;
+ mpi_size_t sign_remainder = num->sign;
+ mpi_size_t sign_quotient = num->sign ^ den->sign;
+ unsigned normalization_steps;
+ mpi_limb_t q_limb;
+ mpi_ptr_t marker[5];
+ unsigned int marker_nlimbs[5];
+ int markidx=0;
+
+ /* Ensure space is enough for quotient and remainder.
+ * We need space for an extra limb in the remainder, because it's
+ * up-shifted (normalized) below. */
+ rsize = nsize + 1;
+ mpi_resize( rem, rsize);
+
+ qsize = rsize - dsize; /* qsize cannot be bigger than this. */
+ if( qsize <= 0 ) {
+ if( num != rem ) {
+ rem->nlimbs = num->nlimbs;
+ rem->sign = num->sign;
+ MPN_COPY(rem->d, num->d, nsize);
+ }
+ if( quot ) {
+ /* This needs to follow the assignment to rem, in case the
+ * numerator and quotient are the same. */
+ quot->nlimbs = 0;
+ quot->sign = 0;
+ }
+ return;
+ }
+
+ if( quot )
+ mpi_resize( quot, qsize);
+
+ if (!dsize)
+ _gcry_divide_by_zero();
+
+ /* Read pointers here, when reallocation is finished. */
+ np = num->d;
+ dp = den->d;
+ rp = rem->d;
+
+ /* Optimize division by a single-limb divisor. */
+ if( dsize == 1 ) {
+ mpi_limb_t rlimb;
+ if( quot ) {
+ qp = quot->d;
+ rlimb = _gcry_mpih_divmod_1( qp, np, nsize, dp[0] );
+ qsize -= qp[qsize - 1] == 0;
+ quot->nlimbs = qsize;
+ quot->sign = sign_quotient;
+ }
+ else
+ rlimb = _gcry_mpih_mod_1( np, nsize, dp[0] );
+ rp[0] = rlimb;
+ rsize = rlimb != 0?1:0;
+ rem->nlimbs = rsize;
+ rem->sign = sign_remainder;
+ return;
+ }
+
+
+ if( quot ) {
+ qp = quot->d;
+ /* Make sure QP and NP point to different objects. Otherwise the
+ * numerator would be gradually overwritten by the quotient limbs. */
+ if(qp == np) { /* Copy NP object to temporary space. */
+ marker_nlimbs[markidx] = nsize;
+ np = marker[markidx++] = mpi_alloc_limb_space(nsize,
+ mpi_is_secure(quot));
+ MPN_COPY(np, qp, nsize);
+ }
+ }
+ else /* Put quotient at top of remainder. */
+ qp = rp + dsize;
+
+ count_leading_zeros( normalization_steps, dp[dsize - 1] );
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ * shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ * numerator the same number of steps (to keep the quotient the same!).
+ */
+ if( normalization_steps ) {
+ mpi_ptr_t tp;
+ mpi_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ * the most significant word. Use temporary storage not to clobber
+ * the original contents of the denominator. */
+ marker_nlimbs[markidx] = dsize;
+ tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den));
+ _gcry_mpih_lshift( tp, dp, dsize, normalization_steps );
+ dp = tp;
+
+ /* Shift up the numerator, possibly introducing a new most
+ * significant word. Move the shifted numerator in the remainder
+ * meanwhile. */
+ nlimb = _gcry_mpih_lshift(rp, np, nsize, normalization_steps);
+ if( nlimb ) {
+ rp[nsize] = nlimb;
+ rsize = nsize + 1;
+ }
+ else
+ rsize = nsize;
+ }
+ else {
+ /* The denominator is already normalized, as required. Copy it to
+ * temporary space if it overlaps with the quotient or remainder. */
+ if( dp == rp || (quot && (dp == qp))) {
+ mpi_ptr_t tp;
+
+ marker_nlimbs[markidx] = dsize;
+ tp = marker[markidx++] = mpi_alloc_limb_space(dsize,
+ mpi_is_secure(den));
+ MPN_COPY( tp, dp, dsize );
+ dp = tp;
+ }
+
+ /* Move the numerator to the remainder. */
+ if( rp != np )
+ MPN_COPY(rp, np, nsize);
+
+ rsize = nsize;
+ }
+
+ q_limb = _gcry_mpih_divrem( qp, 0, rp, rsize, dp, dsize );
+
+ if( quot ) {
+ qsize = rsize - dsize;
+ if(q_limb) {
+ qp[qsize] = q_limb;
+ qsize += 1;
+ }
+
+ quot->nlimbs = qsize;
+ quot->sign = sign_quotient;
+ }
+
+ rsize = dsize;
+ MPN_NORMALIZE (rp, rsize);
+
+ if( normalization_steps && rsize ) {
+ _gcry_mpih_rshift(rp, rp, rsize, normalization_steps);
+ rsize -= rp[rsize - 1] == 0?1:0;
+ }
+
+ rem->nlimbs = rsize;
+ rem->sign = sign_remainder;
+ while( markidx )
+ {
+ markidx--;
+ _gcry_mpi_free_limb_space (marker[markidx], marker_nlimbs[markidx]);
+ }
+}
+
+void
+_gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned int count )
+{
+ mpi_size_t usize, wsize;
+ mpi_size_t limb_cnt;
+
+ usize = u->nlimbs;
+ limb_cnt = count / BITS_PER_MPI_LIMB;
+ wsize = usize - limb_cnt;
+ if( limb_cnt >= usize )
+ w->nlimbs = 0;
+ else {
+ mpi_ptr_t wp;
+ mpi_ptr_t up;
+
+ RESIZE_IF_NEEDED( w, wsize );
+ wp = w->d;
+ up = u->d;
+
+ count %= BITS_PER_MPI_LIMB;
+ if( count ) {
+ _gcry_mpih_rshift( wp, up + limb_cnt, wsize, count );
+ wsize -= !wp[wsize - 1];
+ }
+ else {
+ MPN_COPY_INCR( wp, up + limb_cnt, wsize);
+ }
+
+ w->nlimbs = wsize;
+ }
+}
+
+/****************
+ * Check whether dividend is divisible by divisor
+ * (note: divisor must fit into a limb)
+ */
+int
+_gcry_mpi_divisible_ui(gcry_mpi_t dividend, unsigned long divisor )
+{
+ return !_gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor );
+}
+
+
+void
+_gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend,
+ gcry_mpi_t divisor, int round)
+{
+ if (!round)
+ {
+ if (!rem)
+ {
+ gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs(quot));
+ _gcry_mpi_tdiv_qr (quot, tmp, dividend, divisor);
+ mpi_free (tmp);
+ }
+ else
+ _gcry_mpi_tdiv_qr (quot, rem, dividend, divisor);
+ }
+ else if (round < 0)
+ {
+ if (!rem)
+ _gcry_mpi_fdiv_q (quot, dividend, divisor);
+ else if (!quot)
+ _gcry_mpi_fdiv_r (rem, dividend, divisor);
+ else
+ _gcry_mpi_fdiv_qr (quot, rem, dividend, divisor);
+ }
+ else
+ log_bug ("mpi rounding to ceiling not yet implemented\n");
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpi-gcd.c b/comm/third_party/libgcrypt/mpi/mpi-gcd.c
new file mode 100644
index 0000000000..77ca05a6fc
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-gcd.c
@@ -0,0 +1,52 @@
+/* mpi-gcd.c - MPI functions
+ * 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
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+/****************
+ * Find the greatest common divisor G of A and B.
+ * Return: true if this 1, false in all other cases
+ */
+int
+_gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb)
+{
+ gcry_mpi_t a, b;
+
+ a = mpi_copy(xa);
+ b = mpi_copy(xb);
+
+ /* TAOCP Vol II, 4.5.2, Algorithm A */
+ a->sign = 0;
+ b->sign = 0;
+ while (mpi_cmp_ui (b, 0))
+ {
+ _gcry_mpi_fdiv_r( g, a, b ); /* G is used as temporary variable. */
+ mpi_set(a,b);
+ mpi_set(b,g);
+ }
+ mpi_set(g, a);
+
+ mpi_free(a);
+ mpi_free(b);
+ return !mpi_cmp_ui( g, 1);
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpi-inline.c b/comm/third_party/libgcrypt/mpi/mpi-inline.c
new file mode 100644
index 0000000000..39e2222479
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-inline.c
@@ -0,0 +1,35 @@
+/* mpi-inline.c
+ * Copyright (C) 1999, 2002 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* put the inline functions as real functions into the lib */
+#define G10_MPI_INLINE_DECL
+
+#include "mpi-internal.h"
+
+/* always include the header because it is only
+ * included by mpi-internal if __GCC__ is defined but we
+ * need it here in all cases and the above definition of
+ * of the macro allows us to do so
+ */
+#include "mpi-inline.h"
diff --git a/comm/third_party/libgcrypt/mpi/mpi-inline.h b/comm/third_party/libgcrypt/mpi/mpi-inline.h
new file mode 100644
index 0000000000..94e2aec8a1
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-inline.h
@@ -0,0 +1,161 @@
+/* mpi-inline.h - Internal to the Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_INLINE_H
+#define G10_MPI_INLINE_H
+
+/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the
+ c99 semantics. To keep the useful old semantics we use an
+ attribute. */
+#ifndef G10_MPI_INLINE_DECL
+# ifdef __GNUC_STDC_INLINE__
+# define G10_MPI_INLINE_DECL extern inline __attribute__ ((__gnu_inline__))
+# else
+# define G10_MPI_INLINE_DECL extern __inline__
+# endif
+#endif
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb += x;
+ *res_ptr++ = s2_limb;
+ if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
+ while( --s1_size ) {
+ x = *s1_ptr++ + 1; /* add carry */
+ *res_ptr++ = x; /* and store */
+ if( x ) /* not 0 (no overflow): we can stop */
+ goto leave;
+ }
+ return 1; /* return carry (size of s1 to small) */
+ }
+
+ leave:
+ if( res_ptr != s1_ptr ) { /* not the same variable */
+ mpi_size_t i; /* copy the rest */
+ for( i=0; i < s1_size-1; i++ )
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0; /* no carry */
+}
+
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size)
+{
+ mpi_limb_t cy = 0;
+
+ if( s2_size )
+ cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
+
+ if( s1_size - s2_size )
+ cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size,
+ s1_size - s2_size, cy);
+ return cy;
+}
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb )
+{
+ mpi_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb = x - s2_limb;
+ *res_ptr++ = s2_limb;
+ if( s2_limb > x ) {
+ while( --s1_size ) {
+ x = *s1_ptr++;
+ *res_ptr++ = x - 1;
+ if( x )
+ goto leave;
+ }
+ return 1;
+ }
+
+ leave:
+ if( res_ptr != s1_ptr ) {
+ mpi_size_t i;
+ for( i=0; i < s1_size-1; i++ )
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0;
+}
+
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size)
+{
+ mpi_limb_t cy = 0;
+
+ if( s2_size )
+ cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
+
+ if( s1_size - s2_size )
+ cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
+ s1_size - s2_size, cy);
+ return cy;
+}
+
+/****************
+ * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
+ * There are no restrictions on the relative sizes of
+ * the two arguments.
+ * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.
+ */
+G10_MPI_INLINE_DECL int
+_gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size )
+{
+ mpi_size_t i;
+ mpi_limb_t op1_word, op2_word;
+
+ for( i = size - 1; i >= 0 ; i--) {
+ op1_word = op1_ptr[i];
+ op2_word = op2_ptr[i];
+ if( op1_word != op2_word )
+ goto diff;
+ }
+ return 0;
+
+ diff:
+ /* This can *not* be simplified to
+ * op2_word - op2_word
+ * since that expression might give signed overflow. */
+ return (op1_word > op2_word) ? 1 : -1;
+}
+
+
+#endif /*G10_MPI_INLINE_H*/
diff --git a/comm/third_party/libgcrypt/mpi/mpi-internal.h b/comm/third_party/libgcrypt/mpi/mpi-internal.h
new file mode 100644
index 0000000000..8ccdeada55
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-internal.h
@@ -0,0 +1,300 @@
+/* mpi-internal.h - Internal to the Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 2000, 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_INTERNAL_H
+#define G10_MPI_INTERNAL_H
+
+#include "mpi-asm-defs.h"
+
+#ifndef BITS_PER_MPI_LIMB
+#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
+ typedef unsigned int mpi_limb_t;
+ typedef signed int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
+ typedef unsigned long int mpi_limb_t;
+ typedef signed long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
+ typedef unsigned long long int mpi_limb_t;
+ typedef signed long long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
+ typedef unsigned short int mpi_limb_t;
+ typedef signed short int mpi_limb_signed_t;
+#else
+#error BYTES_PER_MPI_LIMB does not match any C type
+#endif
+#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
+#endif /*BITS_PER_MPI_LIMB*/
+
+#include "mpi.h"
+
+/* If KARATSUBA_THRESHOLD is not already defined, define it to a
+ * value which is good on most machines. */
+
+/* tested 4, 16, 32 and 64, where 16 gave the best performance when
+ * checking a 768 and a 1024 bit ElGamal signature.
+ * (wk 22.12.97) */
+#ifndef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 16
+#endif
+
+/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
+#if KARATSUBA_THRESHOLD < 2
+#undef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 2
+#endif
+
+
+typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */
+typedef int mpi_size_t; /* (must be a signed type) */
+
+#define ABS(x) (x >= 0 ? x : -x)
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+#define RESIZE_IF_NEEDED(a,b) \
+ do { \
+ if( (a)->alloced < (b) ) \
+ mpi_resize((a), (b)); \
+ } while(0)
+
+/* Copy N limbs from S to D. */
+#define MPN_COPY( d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = (s)[_i]; \
+ } while(0)
+
+#define MPN_COPY_INCR( d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = (s)[_i]; \
+ } while (0)
+
+#define MPN_COPY_DECR( d, s, n ) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = (n)-1; _i >= 0; _i--) \
+ (d)[_i] = (s)[_i]; \
+ } while(0)
+
+/* Zero N limbs at D */
+#define MPN_ZERO(d, n) \
+ do { \
+ int _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = 0; \
+ } while (0)
+
+#define MPN_NORMALIZE(d, n) \
+ do { \
+ while( (n) > 0 ) { \
+ if( (d)[(n)-1] ) \
+ break; \
+ (n)--; \
+ } \
+ } while(0)
+
+#define MPN_NORMALIZE_NOT_ZERO(d, n) \
+ do { \
+ for(;;) { \
+ if( (d)[(n)-1] ) \
+ break; \
+ (n)--; \
+ } \
+ } while(0)
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if( (size) < KARATSUBA_THRESHOLD ) \
+ mul_n_basecase (prodp, up, vp, size); \
+ else \
+ mul_n (prodp, up, vp, size, tspace); \
+ } while (0);
+
+
+/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
+ * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
+ * If this would yield overflow, DI should be the largest possible number
+ * (i.e., only ones). For correct operation, the most significant bit of D
+ * has to be set. Put the quotient in Q and the remainder in R.
+ */
+#define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
+ do { \
+ mpi_limb_t _ql GCC_ATTR_UNUSED; \
+ mpi_limb_t _q, _r; \
+ mpi_limb_t _xh, _xl; \
+ umul_ppmm (_q, _ql, (nh), (di)); \
+ _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \
+ umul_ppmm (_xh, _xl, _q, (d)); \
+ sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
+ if( _xh ) { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q++; \
+ if( _xh) { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q++; \
+ } \
+ } \
+ if( _r >= (d) ) { \
+ _r -= (d); \
+ _q++; \
+ } \
+ (r) = _r; \
+ (q) = _q; \
+ } while (0)
+
+
+/*-- mpiutil.c --*/
+#define mpi_alloc_limb_space(n,f) _gcry_mpi_alloc_limb_space((n),(f))
+mpi_ptr_t _gcry_mpi_alloc_limb_space( unsigned nlimbs, int sec );
+void _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs );
+void _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned nlimbs );
+
+/*-- mpi-bit.c --*/
+#define mpi_rshift_limbs(a,n) _gcry_mpi_rshift_limbs ((a), (n))
+#define mpi_lshift_limbs(a,n) _gcry_mpi_lshift_limbs ((a), (n))
+
+void _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count );
+void _gcry_mpi_lshift_limbs( gcry_mpi_t a, unsigned int count );
+
+
+/*-- mpih-add.c --*/
+mpi_limb_t _gcry_mpih_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb );
+mpi_limb_t _gcry_mpih_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size);
+mpi_limb_t _gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size);
+
+/*-- mpih-sub.c --*/
+mpi_limb_t _gcry_mpih_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb );
+mpi_limb_t _gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size);
+mpi_limb_t _gcry_mpih_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size);
+
+/*-- mpih-cmp.c --*/
+int _gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size );
+
+/*-- mpih-mul.c --*/
+
+struct karatsuba_ctx {
+ struct karatsuba_ctx *next;
+ mpi_ptr_t tspace;
+ unsigned int tspace_nlimbs;
+ mpi_size_t tspace_size;
+ mpi_ptr_t tp;
+ unsigned int tp_nlimbs;
+ mpi_size_t tp_size;
+};
+
+void _gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx );
+
+mpi_limb_t _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+mpi_limb_t _gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+void _gcry_mpih_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t size);
+mpi_limb_t _gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize);
+void _gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size );
+void _gcry_mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
+ mpi_ptr_t tspace);
+
+void _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize,
+ struct karatsuba_ctx *ctx );
+
+
+/*-- mpih-mul_1.c (or xxx/cpu/ *.S) --*/
+mpi_limb_t _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+
+/*-- mpih-div.c --*/
+mpi_limb_t _gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb);
+mpi_limb_t _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
+ mpi_ptr_t np, mpi_size_t nsize,
+ mpi_ptr_t dp, mpi_size_t dsize);
+mpi_limb_t _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
+ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb);
+
+/*-- mpih-shift.c --*/
+mpi_limb_t _gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned cnt);
+mpi_limb_t _gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned cnt);
+
+/*-- mpih-const-time.c --*/
+#define mpih_set_cond(w,u,s,o) _gcry_mpih_set_cond ((w),(u),(s),(o))
+#define mpih_add_n_cond(w,u,v,s,o) _gcry_mpih_add_n_cond ((w),(u),(v),(s),(o))
+#define mpih_sub_n_cond(w,u,v,s,o) _gcry_mpih_sub_n_cond ((w),(u),(v),(s),(o))
+#define mpih_swap_cond(u,v,s,o) _gcry_mpih_swap_cond ((u),(v),(s),(o))
+#define mpih_abs_cond(w,u,s,o) _gcry_mpih_abs_cond ((w),(u),(s),(o))
+#define mpih_mod(v,vs,u,us) _gcry_mpih_mod ((v),(vs),(u),(us))
+
+void _gcry_mpih_set_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned long op_enable);
+mpi_limb_t _gcry_mpih_add_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t usize, unsigned long op_enable);
+mpi_limb_t _gcry_mpih_sub_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t usize, unsigned long op_enable);
+void _gcry_mpih_swap_cond (mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t usize,
+ unsigned long op_enable);
+void _gcry_mpih_abs_cond (mpi_ptr_t wp, mpi_ptr_t up,
+ mpi_size_t usize, unsigned long op_enable);
+mpi_ptr_t _gcry_mpih_mod (mpi_ptr_t vp, mpi_size_t vsize,
+ mpi_ptr_t up, mpi_size_t usize);
+int _gcry_mpih_cmp_ui (mpi_ptr_t up, mpi_size_t usize, unsigned long v);
+
+
+/* Define stuff for longlong.h. */
+#define W_TYPE_SIZE BITS_PER_MPI_LIMB
+ typedef mpi_limb_t UWtype;
+ typedef unsigned int UHWtype;
+#if defined (__GNUC__)
+ typedef unsigned int UQItype __attribute__ ((mode (QI)));
+ typedef int SItype __attribute__ ((mode (SI)));
+ typedef unsigned int USItype __attribute__ ((mode (SI)));
+ typedef int DItype __attribute__ ((mode (DI)));
+ typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#else
+ typedef unsigned char UQItype;
+ typedef long SItype;
+ typedef unsigned long USItype;
+#endif
+
+#ifdef __GNUC__
+#include "mpi-inline.h"
+#endif
+
+#endif /*G10_MPI_INTERNAL_H*/
diff --git a/comm/third_party/libgcrypt/mpi/mpi-inv.c b/comm/third_party/libgcrypt/mpi/mpi-inv.c
new file mode 100644
index 0000000000..7ce874666d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-inv.c
@@ -0,0 +1,565 @@
+/* mpi-inv.c - MPI functions
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "g10lib.h"
+
+/*
+ * This uses a modular inversion algorithm designed by Niels Möller
+ * which was implemented in Nettle. The same algorithm was later also
+ * adapted to GMP in mpn_sec_invert.
+ *
+ * For the description of the algorithm, see Algorithm 5 in Appendix A
+ * of "Fast Software Polynomial Multiplication on ARM Processors using
+ * the NEON Engine" by Danilo Câmara, Conrado P. L. Gouvêa, Julio
+ * López, and Ricardo Dahab:
+ * https://hal.inria.fr/hal-01506572/document
+ *
+ * Note that in the reference above, at the line 2 of Algorithm 5,
+ * initial value of V was described as V:=1 wrongly. It must be V:=0.
+ */
+static mpi_ptr_t
+mpih_invm_odd (mpi_ptr_t ap, mpi_ptr_t np, mpi_size_t nsize)
+{
+ int secure;
+ unsigned int iterations;
+ mpi_ptr_t n1hp;
+ mpi_ptr_t bp;
+ mpi_ptr_t up, vp;
+
+ secure = _gcry_is_secure (ap);
+ up = mpi_alloc_limb_space (nsize, secure);
+ MPN_ZERO (up, nsize);
+ up[0] = 1;
+
+ vp = mpi_alloc_limb_space (nsize, secure);
+ MPN_ZERO (vp, nsize);
+
+ secure = _gcry_is_secure (np);
+ bp = mpi_alloc_limb_space (nsize, secure);
+ MPN_COPY (bp, np, nsize);
+
+ n1hp = mpi_alloc_limb_space (nsize, secure);
+ MPN_COPY (n1hp, np, nsize);
+ _gcry_mpih_rshift (n1hp, n1hp, nsize, 1);
+ _gcry_mpih_add_1 (n1hp, n1hp, nsize, 1);
+
+ iterations = 2 * nsize * BITS_PER_MPI_LIMB;
+
+ while (iterations-- > 0)
+ {
+ mpi_limb_t odd_a, odd_u, underflow, borrow;
+
+ odd_a = ap[0] & 1;
+
+ underflow = mpih_sub_n_cond (ap, ap, bp, nsize, odd_a);
+ mpih_add_n_cond (bp, bp, ap, nsize, underflow);
+ mpih_abs_cond (ap, ap, nsize, underflow);
+ mpih_swap_cond (up, vp, nsize, underflow);
+
+ _gcry_mpih_rshift (ap, ap, nsize, 1);
+
+ borrow = mpih_sub_n_cond (up, up, vp, nsize, odd_a);
+ mpih_add_n_cond (up, up, np, nsize, borrow);
+
+ odd_u = _gcry_mpih_rshift (up, up, nsize, 1) != 0;
+ mpih_add_n_cond (up, up, n1hp, nsize, odd_u);
+ }
+
+ _gcry_mpi_free_limb_space (n1hp, nsize);
+ _gcry_mpi_free_limb_space (up, nsize);
+
+ if (_gcry_mpih_cmp_ui (bp, nsize, 1) == 0)
+ {
+ /* Inverse exists. */
+ _gcry_mpi_free_limb_space (bp, nsize);
+ return vp;
+ }
+ else
+ {
+ _gcry_mpi_free_limb_space (bp, nsize);
+ _gcry_mpi_free_limb_space (vp, nsize);
+ return NULL;
+ }
+}
+
+
+/*
+ * Calculate the multiplicative inverse X of A mod 2^K
+ * A must be positive.
+ *
+ * See section 7 in "A New Algorithm for Inversion mod p^k" by Çetin
+ * Kaya Koç: https://eprint.iacr.org/2017/411.pdf
+ */
+static mpi_ptr_t
+mpih_invm_pow2 (mpi_ptr_t ap, mpi_size_t asize, unsigned int k)
+{
+ int secure = _gcry_is_secure (ap);
+ mpi_size_t i;
+ unsigned int iterations;
+ mpi_ptr_t xp, wp, up, vp;
+ mpi_size_t usize;
+
+ if (!(ap[0] & 1))
+ return NULL;
+
+ iterations = ((k + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB)
+ * BITS_PER_MPI_LIMB;
+ usize = iterations / BITS_PER_MPI_LIMB;
+
+ up = mpi_alloc_limb_space (usize, secure);
+ MPN_ZERO (up, usize);
+ up[0] = 1;
+
+ vp = mpi_alloc_limb_space (usize, secure);
+ for (i = 0; i < (usize < asize ? usize : asize); i++)
+ vp[i] = ap[i];
+ for (; i < usize; i++)
+ vp[i] = 0;
+ if ((k % BITS_PER_MPI_LIMB))
+ for (i = k % BITS_PER_MPI_LIMB; i < BITS_PER_MPI_LIMB; i++)
+ vp[k/BITS_PER_MPI_LIMB] &= ~(((mpi_limb_t)1) << i);
+
+ wp = mpi_alloc_limb_space (usize, secure);
+ MPN_COPY (wp, up, usize);
+
+ xp = mpi_alloc_limb_space (usize, secure);
+ MPN_ZERO (xp, usize);
+
+ /*
+ * It can be considered that overflow at _gcry_mpih_sub_n results
+ * adding 2^(USIZE*BITS_PER_MPI_LIMB), which is no problem in modulo
+ * 2^K computation.
+ */
+ for (i = 0; i < iterations; i++)
+ {
+ int b0 = (up[0] & 1);
+
+ xp[i/BITS_PER_MPI_LIMB] |= ((mpi_limb_t)b0<<(i%BITS_PER_MPI_LIMB));
+ _gcry_mpih_sub_n (wp, up, vp, usize);
+ mpih_set_cond (up, wp, usize, b0);
+ _gcry_mpih_rshift (up, up, usize, 1);
+ }
+
+ if ((k % BITS_PER_MPI_LIMB))
+ for (i = k % BITS_PER_MPI_LIMB; i < BITS_PER_MPI_LIMB; i++)
+ xp[k/BITS_PER_MPI_LIMB] &= ~(((mpi_limb_t)1) << i);
+
+ _gcry_mpi_free_limb_space (up, usize);
+ _gcry_mpi_free_limb_space (vp, usize);
+ _gcry_mpi_free_limb_space (wp, usize);
+
+ return xp;
+}
+
+
+/****************
+ * Calculate the multiplicative inverse X of A mod N
+ * That is: Find the solution x for
+ * 1 = (a*x) mod n
+ */
+static int
+mpi_invm_generic (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n)
+{
+ int is_gcd_one;
+#if 0
+ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X) */
+ gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+ u1 = mpi_alloc_set_ui(1);
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_alloc_set_ui(0);
+ v2 = mpi_alloc_set_ui(1);
+ v3 = mpi_copy(v);
+ q = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t1 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t2 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t3 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ while( mpi_cmp_ui( v3, 0 ) ) {
+ mpi_fdiv_q( q, u3, v3 );
+ mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q);
+ mpi_sub(t1, u1, t1); mpi_sub(t2, u2, t2); mpi_sub(t3, u3, t3);
+ mpi_set(u1, v1); mpi_set(u2, v2); mpi_set(u3, v3);
+ mpi_set(v1, t1); mpi_set(v2, t2); mpi_set(v3, t3);
+ }
+ /* log_debug("result:\n");
+ log_mpidump("q =", q );
+ log_mpidump("u1=", u1);
+ log_mpidump("u2=", u2);
+ log_mpidump("u3=", u3);
+ log_mpidump("v1=", v1);
+ log_mpidump("v2=", v2); */
+ mpi_set(x, u1);
+
+ is_gcd_one = (mpi_cmp_ui (u3, 1) == 0);
+
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(u3);
+ mpi_free(v1);
+ mpi_free(v2);
+ mpi_free(v3);
+ mpi_free(q);
+ mpi_free(t1);
+ mpi_free(t2);
+ mpi_free(t3);
+ mpi_free(u);
+ mpi_free(v);
+#elif 0
+ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X)
+ * modified according to Michael Penk's solution for Exercise 35
+ * (in the first edition)
+ * In the third edition, it's Exercise 39, and it is described in
+ * page 646 of ANSWERS TO EXERCISES chapter.
+ */
+
+ /* FIXME: we can simplify this in most cases (see Knuth) */
+ gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, t1, t2, t3;
+ unsigned k;
+ int sign;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+ for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
+ mpi_rshift(u, u, 1);
+ mpi_rshift(v, v, 1);
+ }
+
+
+ u1 = mpi_alloc_set_ui(1);
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_copy(v); /* !-- used as const 1 */
+ v2 = mpi_alloc( mpi_get_nlimbs(u) ); mpi_sub( v2, u1, u );
+ v3 = mpi_copy(v);
+ if( mpi_test_bit(u, 0) ) { /* u is odd */
+ t1 = mpi_alloc_set_ui(0);
+ t2 = mpi_alloc_set_ui(1); t2->sign = 1;
+ t3 = mpi_copy(v); t3->sign = !t3->sign;
+ goto Y4;
+ }
+ else {
+ t1 = mpi_alloc_set_ui(1);
+ t2 = mpi_alloc_set_ui(0);
+ t3 = mpi_copy(u);
+ }
+ do {
+ do {
+ if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t2, t2, 1);
+ mpi_rshift(t3, t3, 1);
+ Y4:
+ ;
+ } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
+
+ if( !t3->sign ) {
+ mpi_set(u1, t1);
+ mpi_set(u2, t2);
+ mpi_set(u3, t3);
+ }
+ else {
+ mpi_sub(v1, v, t1);
+ sign = u->sign; u->sign = !u->sign;
+ mpi_sub(v2, u, t2);
+ u->sign = sign;
+ sign = t3->sign; t3->sign = !t3->sign;
+ mpi_set(v3, t3);
+ t3->sign = sign;
+ }
+ mpi_sub(t1, u1, v1);
+ mpi_sub(t2, u2, v2);
+ mpi_sub(t3, u3, v3);
+ if( t1->sign ) {
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
+ /* mpi_lshift( u3, u3, k ); */
+ is_gcd_one = (k == 0 && mpi_cmp_ui (u3, 1) == 0);
+ mpi_set(x, u1);
+
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(u3);
+ mpi_free(v1);
+ mpi_free(v2);
+ mpi_free(v3);
+ mpi_free(t1);
+ mpi_free(t2);
+ mpi_free(t3);
+#else
+ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X)
+ * modified according to Michael Penk's solution for Exercise 35
+ * with further enhancement */
+ /* The reference in the comment above is for the first edition.
+ * In the third edition, it's Exercise 39, and it is described in
+ * page 646 of ANSWERS TO EXERCISES chapter.
+ */
+ gcry_mpi_t u, v, u1, u2=NULL, u3, v1, v2=NULL, v3, t1, t2=NULL, t3;
+ unsigned k;
+ int sign;
+ int odd ;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+
+ for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
+ mpi_rshift(u, u, 1);
+ mpi_rshift(v, v, 1);
+ }
+ odd = mpi_test_bit(v,0);
+
+ u1 = mpi_alloc_set_ui(1);
+ if( !odd )
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_copy(v);
+ if( !odd ) {
+ v2 = mpi_alloc( mpi_get_nlimbs(u) );
+ mpi_sub( v2, u1, u ); /* U is used as const 1 */
+ }
+ v3 = mpi_copy(v);
+ if( mpi_test_bit(u, 0) ) { /* u is odd */
+ t1 = mpi_alloc_set_ui(0);
+ if( !odd ) {
+ t2 = mpi_alloc_set_ui(1); t2->sign = 1;
+ }
+ t3 = mpi_copy(v); t3->sign = !t3->sign;
+ goto Y4;
+ }
+ else {
+ t1 = mpi_alloc_set_ui(1);
+ if( !odd )
+ t2 = mpi_alloc_set_ui(0);
+ t3 = mpi_copy(u);
+ }
+ do {
+ do {
+ if( !odd ) {
+ if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t2, t2, 1);
+ mpi_rshift(t3, t3, 1);
+ }
+ else {
+ if( mpi_test_bit(t1, 0) )
+ mpi_add(t1, t1, v);
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t3, t3, 1);
+ }
+ Y4:
+ ;
+ } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
+
+ if( !t3->sign ) {
+ mpi_set(u1, t1);
+ if( !odd )
+ mpi_set(u2, t2);
+ mpi_set(u3, t3);
+ }
+ else {
+ mpi_sub(v1, v, t1);
+ sign = u->sign; u->sign = !u->sign;
+ if( !odd )
+ mpi_sub(v2, u, t2);
+ u->sign = sign;
+ sign = t3->sign; t3->sign = !t3->sign;
+ mpi_set(v3, t3);
+ t3->sign = sign;
+ }
+ mpi_sub(t1, u1, v1);
+ if( !odd )
+ mpi_sub(t2, u2, v2);
+ mpi_sub(t3, u3, v3);
+ if( t1->sign ) {
+ mpi_add(t1, t1, v);
+ if( !odd )
+ mpi_sub(t2, t2, u);
+ }
+ } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
+ /* mpi_lshift( u3, u3, k ); */
+ is_gcd_one = (k == 0 && mpi_cmp_ui (u3, 1) == 0);
+ mpi_set(x, u1);
+
+ mpi_free(u1);
+ mpi_free(v1);
+ mpi_free(t1);
+ if( !odd ) {
+ mpi_free(u2);
+ mpi_free(v2);
+ mpi_free(t2);
+ }
+ mpi_free(u3);
+ mpi_free(v3);
+ mpi_free(t3);
+
+ mpi_free(u);
+ mpi_free(v);
+#endif
+ return is_gcd_one;
+}
+
+
+/*
+ * Set X to the multiplicative inverse of A mod M. Return true if the
+ * inverse exists.
+ */
+int
+_gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n)
+{
+ mpi_ptr_t ap, xp;
+
+ if (!mpi_cmp_ui (a, 0))
+ return 0; /* Inverse does not exists. */
+ if (!mpi_cmp_ui (n, 1))
+ return 0; /* Inverse does not exists. */
+
+ if (mpi_test_bit (n, 0))
+ {
+ if (a->nlimbs <= n->nlimbs)
+ {
+ ap = mpi_alloc_limb_space (n->nlimbs, _gcry_is_secure (a->d));
+ MPN_ZERO (ap, n->nlimbs);
+ MPN_COPY (ap, a->d, a->nlimbs);
+ }
+ else
+ ap = _gcry_mpih_mod (a->d, a->nlimbs, n->d, n->nlimbs);
+
+ xp = mpih_invm_odd (ap, n->d, n->nlimbs);
+ _gcry_mpi_free_limb_space (ap, n->nlimbs);
+
+ if (xp)
+ {
+ _gcry_mpi_assign_limb_space (x, xp, n->nlimbs);
+ x->nlimbs = n->nlimbs;
+ return 1;
+ }
+ else
+ return 0; /* Inverse does not exists. */
+ }
+ else if (!a->sign && !n->sign)
+ {
+ unsigned int k = mpi_trailing_zeros (n);
+ mpi_size_t x1size = ((k + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB);
+ mpi_size_t hsize;
+ gcry_mpi_t q;
+ mpi_ptr_t x1p, x2p, q_invp, hp, diffp;
+ mpi_size_t i;
+
+ if (k == _gcry_mpi_get_nbits (n) - 1)
+ {
+ x1p = mpih_invm_pow2 (a->d, a->nlimbs, k);
+
+ if (x1p)
+ {
+ _gcry_mpi_assign_limb_space (x, x1p, x1size);
+ x->nlimbs = x1size;
+ return 1;
+ }
+ else
+ return 0; /* Inverse does not exists. */
+ }
+
+ /* N can be expressed as P * Q, where P = 2^K. P and Q are coprime. */
+ /*
+ * Compute X1 = invm (A, P) and X2 = invm (A, Q), and combine
+ * them by Garner's formula, to get X = invm (A, P*Q).
+ * A special case of Chinese Remainder Theorem.
+ */
+
+ /* X1 = invm (A, P) */
+ x1p = mpih_invm_pow2 (a->d, a->nlimbs, k);
+ if (!x1p)
+ return 0; /* Inverse does not exists. */
+
+ /* Q = N / P */
+ q = mpi_new (0);
+ mpi_rshift (q, n, k);
+
+ /* X2 = invm (A%Q, Q) */
+ ap = _gcry_mpih_mod (a->d, a->nlimbs, q->d, q->nlimbs);
+ x2p = mpih_invm_odd (ap, q->d, q->nlimbs);
+ _gcry_mpi_free_limb_space (ap, q->nlimbs);
+ if (!x2p)
+ {
+ _gcry_mpi_free_limb_space (x1p, x1size);
+ mpi_free (q);
+ return 0; /* Inverse does not exists. */
+ }
+
+ /* Q_inv = Q^(-1) = invm (Q, P) */
+ q_invp = mpih_invm_pow2 (q->d, q->nlimbs, k);
+
+ /* H = (X1 - X2) * Q_inv % P */
+ diffp = mpi_alloc_limb_space (x1size, _gcry_is_secure (a->d));
+ if (x1size >= q->nlimbs)
+ _gcry_mpih_sub (diffp, x1p, x1size, x2p, q->nlimbs);
+ else
+ _gcry_mpih_sub_n (diffp, x1p, x2p, x1size);
+ _gcry_mpi_free_limb_space (x1p, x1size);
+ if ((k % BITS_PER_MPI_LIMB))
+ for (i = k % BITS_PER_MPI_LIMB; i < BITS_PER_MPI_LIMB; i++)
+ diffp[k/BITS_PER_MPI_LIMB] &= ~(((mpi_limb_t)1) << i);
+
+ hsize = x1size * 2;
+ hp = mpi_alloc_limb_space (hsize, _gcry_is_secure (a->d));
+ _gcry_mpih_mul_n (hp, diffp, q_invp, x1size);
+ _gcry_mpi_free_limb_space (diffp, x1size);
+ _gcry_mpi_free_limb_space (q_invp, x1size);
+
+ for (i = x1size; i < hsize; i++)
+ hp[i] = 0;
+ if ((k % BITS_PER_MPI_LIMB))
+ for (i = k % BITS_PER_MPI_LIMB; i < BITS_PER_MPI_LIMB; i++)
+ hp[k/BITS_PER_MPI_LIMB] &= ~(((mpi_limb_t)1) << i);
+
+ xp = mpi_alloc_limb_space (x1size + q->nlimbs, _gcry_is_secure (a->d));
+ if (x1size >= q->nlimbs)
+ _gcry_mpih_mul (xp, hp, x1size, q->d, q->nlimbs);
+ else
+ _gcry_mpih_mul (xp, q->d, q->nlimbs, hp, x1size);
+
+ _gcry_mpi_free_limb_space (hp, hsize);
+
+ _gcry_mpih_add (xp, xp, x1size + q->nlimbs, x2p, q->nlimbs);
+ _gcry_mpi_free_limb_space (x2p, q->nlimbs);
+
+ _gcry_mpi_assign_limb_space (x, xp, x1size + q->nlimbs);
+ x->nlimbs = x1size + q->nlimbs;
+
+ mpi_free (q);
+
+ return 1;
+ }
+ else
+ return mpi_invm_generic (x, a, n);
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpi-mod.c b/comm/third_party/libgcrypt/mpi/mpi-mod.c
new file mode 100644
index 0000000000..88624720c2
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-mod.c
@@ -0,0 +1,188 @@
+/* mpi-mod.c - Modular reduction
+ Copyright (C) 1998, 1999, 2001, 2002, 2003,
+ 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+/* Context used with Barrett reduction. */
+struct barrett_ctx_s
+{
+ gcry_mpi_t m; /* The modulus - may not be modified. */
+ int m_copied; /* If true, M needs to be released. */
+ int k;
+ gcry_mpi_t y;
+ gcry_mpi_t r1; /* Helper MPI. */
+ gcry_mpi_t r2; /* Helper MPI. */
+ gcry_mpi_t r3; /* Helper MPI allocated on demand. */
+};
+
+
+
+void
+_gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor)
+{
+ _gcry_mpi_fdiv_r (rem, dividend, divisor);
+}
+
+
+/* This function returns a new context for Barrett based operations on
+ the modulus M. This context needs to be released using
+ _gcry_mpi_barrett_free. If COPY is true M will be transferred to
+ the context and the user may change M. If COPY is false, M may not
+ be changed until gcry_mpi_barrett_free has been called. */
+mpi_barrett_t
+_gcry_mpi_barrett_init (gcry_mpi_t m, int copy)
+{
+ mpi_barrett_t ctx;
+ gcry_mpi_t tmp;
+
+ mpi_normalize (m);
+ ctx = xcalloc (1, sizeof *ctx);
+
+ if (copy)
+ {
+ ctx->m = mpi_copy (m);
+ ctx->m_copied = 1;
+ }
+ else
+ ctx->m = m;
+
+ ctx->k = mpi_get_nlimbs (m);
+ tmp = mpi_alloc (ctx->k + 1);
+
+ /* Barrett precalculation: y = floor(b^(2k) / m). */
+ mpi_set_ui (tmp, 1);
+ mpi_lshift_limbs (tmp, 2 * ctx->k);
+ mpi_fdiv_q (tmp, tmp, m);
+
+ ctx->y = tmp;
+ ctx->r1 = mpi_alloc ( 2 * ctx->k + 1 );
+ ctx->r2 = mpi_alloc ( 2 * ctx->k + 1 );
+
+ return ctx;
+}
+
+void
+_gcry_mpi_barrett_free (mpi_barrett_t ctx)
+{
+ if (ctx)
+ {
+ mpi_free (ctx->y);
+ mpi_free (ctx->r1);
+ mpi_free (ctx->r2);
+ if (ctx->r3)
+ mpi_free (ctx->r3);
+ if (ctx->m_copied)
+ mpi_free (ctx->m);
+ xfree (ctx);
+ }
+}
+
+
+/* R = X mod M
+
+ Using Barrett reduction. Before using this function
+ _gcry_mpi_barrett_init must have been called to do the
+ precalculations. CTX is the context created by this precalculation
+ and also conveys M. If the Barret reduction could no be done a
+ straightforward reduction method is used.
+
+ We assume that these conditions are met:
+ Input: x =(x_2k-1 ...x_0)_b
+ m =(m_k-1 ....m_0)_b with m_k-1 != 0
+ Output: r = x mod m
+ */
+void
+_gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
+{
+ gcry_mpi_t m = ctx->m;
+ int k = ctx->k;
+ gcry_mpi_t y = ctx->y;
+ gcry_mpi_t r1 = ctx->r1;
+ gcry_mpi_t r2 = ctx->r2;
+ int sign;
+
+ mpi_normalize (x);
+ if (mpi_get_nlimbs (x) > 2*k )
+ {
+ mpi_mod (r, x, m);
+ return;
+ }
+
+ sign = x->sign;
+ x->sign = 0;
+
+ /* 1. q1 = floor( x / b^k-1)
+ * q2 = q1 * y
+ * q3 = floor( q2 / b^k+1 )
+ * Actually, we don't need qx, we can work direct on r2
+ */
+ mpi_set ( r2, x );
+ mpi_rshift_limbs ( r2, k-1 );
+ mpi_mul ( r2, r2, y );
+ mpi_rshift_limbs ( r2, k+1 );
+
+ /* 2. r1 = x mod b^k+1
+ * r2 = q3 * m mod b^k+1
+ * r = r1 - r2
+ * 3. if r < 0 then r = r + b^k+1
+ */
+ mpi_set ( r1, x );
+ if ( r1->nlimbs > k+1 ) /* Quick modulo operation. */
+ r1->nlimbs = k+1;
+ mpi_mul ( r2, r2, m );
+ if ( r2->nlimbs > k+1 ) /* Quick modulo operation. */
+ r2->nlimbs = k+1;
+ mpi_sub ( r, r1, r2 );
+
+ if ( mpi_has_sign ( r ) )
+ {
+ if (!ctx->r3)
+ {
+ ctx->r3 = mpi_alloc ( k + 2 );
+ mpi_set_ui (ctx->r3, 1);
+ mpi_lshift_limbs (ctx->r3, k + 1 );
+ }
+ mpi_add ( r, r, ctx->r3 );
+ }
+
+ /* 4. while r >= m do r = r - m */
+ while ( mpi_cmp( r, m ) >= 0 )
+ mpi_sub ( r, r, m );
+
+ x->sign = sign;
+}
+
+
+void
+_gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
+ mpi_barrett_t ctx)
+{
+ mpi_mul (w, u, v);
+ mpi_mod_barrett (w, w, ctx);
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpi-mpow.c b/comm/third_party/libgcrypt/mpi/mpi-mpow.c
new file mode 100644
index 0000000000..43bd641fb5
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-mpow.c
@@ -0,0 +1,223 @@
+/* mpi-mpow.c - MPI functions
+ * Copyright (C) 1998, 1999, 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
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+/* Barrett is slower than the classical way. It can be tweaked by
+ * using partial multiplications
+ */
+/*#define USE_BARRETT*/
+
+
+
+#ifdef USE_BARRETT
+static void barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
+static gcry_mpi_t init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 );
+static int calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
+#else
+#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) _gcry_mpi_mulm( (w), (u), (v), (m) )
+#endif
+
+
+static int
+build_index( gcry_mpi_t *exparray, int k, int i, int t )
+{
+ int j, bitno;
+ int idx = 0;
+
+ bitno = t-i;
+ for(j=k-1; j >= 0; j-- ) {
+ idx <<= 1;
+ if( mpi_test_bit( exparray[j], bitno ) )
+ idx |= 1;
+ }
+ /*log_debug("t=%d i=%d idx=%d\n", t, i, idx );*/
+ return idx;
+}
+
+/****************
+ * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
+ */
+void
+_gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t m)
+{
+ int k; /* number of elements */
+ int t; /* bit size of largest exponent */
+ int i, j, idx;
+ gcry_mpi_t *G; /* table with precomputed values of size 2^k */
+ gcry_mpi_t tmp;
+#ifdef USE_BARRETT
+ gcry_mpi_t barrett_y, barrett_r1, barrett_r2;
+ int barrett_k;
+#endif
+
+ for(k=0; basearray[k]; k++ )
+ ;
+ gcry_assert(k);
+ for(t=0, i=0; (tmp=exparray[i]); i++ ) {
+ /*log_mpidump("exp: ", tmp );*/
+ j = mpi_get_nbits(tmp);
+ if( j > t )
+ t = j;
+ }
+ /*log_mpidump("mod: ", m );*/
+ gcry_assert (i==k);
+ gcry_assert (t);
+ gcry_assert (k < 10);
+
+ G = xcalloc( (1<<k) , sizeof *G );
+#ifdef USE_BARRETT
+ barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
+#endif
+ /* and calculate */
+ tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
+ mpi_set_ui( res, 1 );
+ for(i = 1; i <= t; i++ ) {
+ barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
+ barrett_r1, barrett_r2 );
+ idx = build_index( exparray, k, i, t );
+ gcry_assert (idx >= 0 && idx < (1<<k));
+ if( !G[idx] ) {
+ if( !idx )
+ G[0] = mpi_alloc_set_ui( 1 );
+ else {
+ for(j=0; j < k; j++ ) {
+ if( (idx & (1<<j) ) ) {
+ if( !G[idx] )
+ G[idx] = mpi_copy( basearray[j] );
+ else
+ barrett_mulm( G[idx], G[idx], basearray[j],
+ m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
+ }
+ }
+ if( !G[idx] )
+ G[idx] = mpi_alloc(0);
+ }
+ }
+ barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
+ }
+
+ /* cleanup */
+ mpi_free(tmp);
+#ifdef USE_BARRETT
+ mpi_free(barrett_y);
+ mpi_free(barrett_r1);
+ mpi_free(barrett_r2);
+#endif
+ for(i=0; i < (1<<k); i++ )
+ mpi_free(G[i]);
+ xfree(G);
+}
+
+
+
+#ifdef USE_BARRETT
+static void
+barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 )
+{
+ mpi_mul(w, u, v);
+ if( calc_barrett( w, w, m, y, k, r1, r2 ) )
+ mpi_fdiv_r( w, w, m );
+}
+
+/****************
+ * Barrett precalculation: y = floor(b^(2k) / m)
+ */
+static gcry_mpi_t
+init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 )
+{
+ gcry_mpi_t tmp;
+
+ mpi_normalize( m );
+ *k = mpi_get_nlimbs( m );
+ tmp = mpi_alloc( *k + 1 );
+ mpi_set_ui( tmp, 1 );
+ mpi_lshift_limbs( tmp, 2 * *k );
+ mpi_fdiv_q( tmp, tmp, m );
+ *r1 = mpi_alloc( 2* *k + 1 );
+ *r2 = mpi_alloc( 2* *k + 1 );
+ return tmp;
+}
+
+/****************
+ * Barrett reduction: We assume that these conditions are met:
+ * Given x =(x_2k-1 ...x_0)_b
+ * m =(m_k-1 ....m_0)_b with m_k-1 != 0
+ * Output r = x mod m
+ * Before using this function init_barret must be used to calucalte y and k.
+ * Returns: false = no error
+ * true = can't perform barret reduction
+ */
+static int
+calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 )
+{
+ int xx = k > 3 ? k-3:0;
+
+ mpi_normalize( x );
+ if( mpi_get_nlimbs(x) > 2*k )
+ return 1; /* can't do it */
+
+ /* 1. q1 = floor( x / b^k-1)
+ * q2 = q1 * y
+ * q3 = floor( q2 / b^k+1 )
+ * Actually, we don't need qx, we can work direct on r2
+ */
+ mpi_set( r2, x );
+ mpi_rshift_limbs( r2, k-1 );
+ mpi_mul( r2, r2, y );
+ mpi_rshift_limbs( r2, k+1 );
+
+ /* 2. r1 = x mod b^k+1
+ * r2 = q3 * m mod b^k+1
+ * r = r1 - r2
+ * 3. if r < 0 then r = r + b^k+1
+ */
+ mpi_set( r1, x );
+ if( r1->nlimbs > k+1 ) /* quick modulo operation */
+ r1->nlimbs = k+1;
+ mpi_mul( r2, r2, m );
+ if( r2->nlimbs > k+1 ) /* quick modulo operation */
+ r2->nlimbs = k+1;
+ mpi_sub( r, r1, r2 );
+
+ if( mpi_has_sign (r) ) {
+ gcry_mpi_t tmp;
+
+ tmp = mpi_alloc( k + 2 );
+ mpi_set_ui( tmp, 1 );
+ mpi_lshift_limbs( tmp, k+1 );
+ mpi_add( r, r, tmp );
+ mpi_free(tmp);
+ }
+
+ /* 4. while r >= m do r = r - m */
+ while( mpi_cmp( r, m ) >= 0 )
+ mpi_sub( r, r, m );
+
+ return 0;
+}
+#endif /* USE_BARRETT */
diff --git a/comm/third_party/libgcrypt/mpi/mpi-mul.c b/comm/third_party/libgcrypt/mpi/mpi-mul.c
new file mode 100644
index 0000000000..4f4d7096a7
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-mul.c
@@ -0,0 +1,212 @@
+/* mpi-mul.c - MPI functions
+ * Copyright (C) 1994, 1996, 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+
+void
+_gcry_mpi_mul_ui (gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult)
+{
+ mpi_size_t size, prod_size;
+ mpi_ptr_t prod_ptr;
+ mpi_limb_t cy;
+ int sign;
+
+ size = mult->nlimbs;
+ sign = mult->sign;
+
+ if( !size || !small_mult ) {
+ prod->nlimbs = 0;
+ prod->sign = 0;
+ return;
+ }
+
+ prod_size = size + 1;
+ if( prod->alloced < prod_size )
+ mpi_resize( prod, prod_size );
+ prod_ptr = prod->d;
+
+ cy = _gcry_mpih_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
+ if( cy )
+ prod_ptr[size++] = cy;
+ prod->nlimbs = size;
+ prod->sign = sign;
+}
+
+
+void
+_gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
+{
+ mpi_size_t usize, wsize, limb_cnt;
+ mpi_ptr_t wp;
+ mpi_limb_t wlimb;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+
+ if( !usize ) {
+ w->nlimbs = 0;
+ w->sign = 0;
+ return;
+ }
+
+ limb_cnt = cnt / BITS_PER_MPI_LIMB;
+ wsize = usize + limb_cnt + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize );
+ wp = w->d;
+ wsize = usize + limb_cnt;
+ wsign = usign;
+
+ cnt %= BITS_PER_MPI_LIMB;
+ if( cnt ) {
+ wlimb = _gcry_mpih_lshift( wp + limb_cnt, u->d, usize, cnt );
+ if( wlimb ) {
+ wp[wsize] = wlimb;
+ wsize++;
+ }
+ }
+ else {
+ MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
+ }
+
+ /* Zero all whole limbs at low end. Do it here and not before calling
+ * mpn_lshift, not to lose for U == W. */
+ MPN_ZERO( wp, limb_cnt );
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+void
+_gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ mpi_size_t usize, vsize, wsize;
+ mpi_ptr_t up, vp, wp;
+ mpi_limb_t cy;
+ int usign, vsign, usecure, vsecure, sign_product;
+ int assign_wp=0;
+ mpi_ptr_t tmp_limb=NULL;
+ unsigned int tmp_limb_nlimbs = 0;
+
+ if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
+ usize = v->nlimbs;
+ usign = v->sign;
+ usecure = mpi_is_secure(v);
+ up = v->d;
+ vsize = u->nlimbs;
+ vsign = u->sign;
+ vsecure = mpi_is_secure(u);
+ vp = u->d;
+ }
+ else {
+ usize = u->nlimbs;
+ usign = u->sign;
+ usecure = mpi_is_secure(u);
+ up = u->d;
+ vsize = v->nlimbs;
+ vsign = v->sign;
+ vsecure = mpi_is_secure(v);
+ vp = v->d;
+ }
+ sign_product = usign ^ vsign;
+ wp = w->d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
+ /* w is not allocated in secure space but u or v is. To make sure
+ * that no temporray results are stored in w, we temporary use
+ * a newly allocated limb space for w */
+ wp = mpi_alloc_limb_space( wsize, 1 );
+ assign_wp = 2; /* mark it as 2 so that we can later copy it back to
+ * mormal memory */
+ }
+ else if( w->alloced < wsize ) {
+ if( wp == up || wp == vp ) {
+ wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
+ assign_wp = 1;
+ }
+ else {
+ mpi_resize(w, wsize );
+ wp = w->d;
+ }
+ }
+ else { /* Make U and V not overlap with W. */
+ if( wp == up ) {
+ /* W and U are identical. Allocate temporary space for U. */
+ tmp_limb_nlimbs = usize;
+ up = tmp_limb = mpi_alloc_limb_space( usize, usecure );
+ /* Is V identical too? Keep it identical with U. */
+ if( wp == vp )
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY( up, wp, usize );
+ }
+ else if( wp == vp ) {
+ /* W and V are identical. Allocate temporary space for V. */
+ tmp_limb_nlimbs = vsize;
+ vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
+ /* Copy to the temporary space. */
+ MPN_COPY( vp, wp, vsize );
+ }
+ }
+
+ if( !vsize )
+ wsize = 0;
+ else {
+ cy = _gcry_mpih_mul( wp, up, usize, vp, vsize );
+ wsize -= cy? 0:1;
+ }
+
+ if( assign_wp ) {
+ if (assign_wp == 2) {
+ /* copy the temp wp from secure memory back to normal memory */
+ mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
+ MPN_COPY (tmp_wp, wp, wsize);
+ _gcry_mpi_free_limb_space (wp, 0);
+ wp = tmp_wp;
+ }
+ _gcry_mpi_assign_limb_space( w, wp, wsize );
+ }
+ w->nlimbs = wsize;
+ w->sign = sign_product;
+ if( tmp_limb )
+ _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs);
+}
+
+
+void
+_gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ mpi_mul (w, u, v);
+ _gcry_mpi_tdiv_r (w, w, m);
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpi-pow.c b/comm/third_party/libgcrypt/mpi/mpi-pow.c
new file mode 100644
index 0000000000..62b4a80830
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-pow.c
@@ -0,0 +1,772 @@
+/* mpi-pow.c - MPI functions for exponentiation
+ * Copyright (C) 1994, 1996, 1998, 2000, 2002
+ * 2003 Free Software Foundation, Inc.
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+/*
+ * When you need old implementation, please add compilation option
+ * -DUSE_ALGORITHM_SIMPLE_EXPONENTIATION
+ * or expose this line:
+#define USE_ALGORITHM_SIMPLE_EXPONENTIATION 1
+ */
+
+#if defined(USE_ALGORITHM_SIMPLE_EXPONENTIATION)
+/****************
+ * RES = BASE ^ EXPO mod MOD
+ */
+void
+_gcry_mpi_powm (gcry_mpi_t res,
+ gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+{
+ /* Pointer to the limbs of the arguments, their size and signs. */
+ mpi_ptr_t rp, ep, mp, bp;
+ mpi_size_t esize, msize, bsize, rsize;
+ int msign, bsign, rsign;
+ /* Flags telling the secure allocation status of the arguments. */
+ int esec, msec, bsec;
+ /* Size of the result including space for temporary values. */
+ mpi_size_t size;
+ /* Helper. */
+ int mod_shift_cnt;
+ int negative_result;
+ mpi_ptr_t mp_marker = NULL;
+ mpi_ptr_t bp_marker = NULL;
+ mpi_ptr_t ep_marker = NULL;
+ mpi_ptr_t xp_marker = NULL;
+ unsigned int mp_nlimbs = 0;
+ unsigned int bp_nlimbs = 0;
+ unsigned int ep_nlimbs = 0;
+ unsigned int xp_nlimbs = 0;
+ mpi_ptr_t tspace = NULL;
+ mpi_size_t tsize = 0;
+
+
+ esize = expo->nlimbs;
+ msize = mod->nlimbs;
+ size = 2 * msize;
+ msign = mod->sign;
+
+ esec = mpi_is_secure(expo);
+ msec = mpi_is_secure(mod);
+ bsec = mpi_is_secure(base);
+
+ rp = res->d;
+ ep = expo->d;
+ MPN_NORMALIZE(ep, esize);
+
+ if (!msize)
+ _gcry_divide_by_zero();
+
+ if (!esize)
+ {
+ /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
+ on if MOD equals 1. */
+ res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+ if (res->nlimbs)
+ {
+ RESIZE_IF_NEEDED (res, 1);
+ rp = res->d;
+ rp[0] = 1;
+ }
+ res->sign = 0;
+ goto leave;
+ }
+
+ /* Normalize MOD (i.e. make its most significant bit set) as
+ required by mpn_divrem. This will make the intermediate values
+ in the calculation slightly larger, but the correct result is
+ obtained after a final reduction using the original MOD value. */
+ mp_nlimbs = msec? msize:0;
+ mp = mp_marker = mpi_alloc_limb_space(msize, msec);
+ count_leading_zeros (mod_shift_cnt, mod->d[msize-1]);
+ if (mod_shift_cnt)
+ _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt);
+ else
+ MPN_COPY( mp, mod->d, msize );
+
+ bsize = base->nlimbs;
+ bsign = base->sign;
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it.
+
+ Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp_nlimbs = bsec ? (bsize + 1):0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
+ MPN_COPY ( bp, base->d, bsize );
+ /* We don't care about the quotient, store it above the
+ * remainder, at BP + MSIZE. */
+ _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize );
+ bsize = msize;
+ /* Canonicalize the base, since we are going to multiply with it
+ quite a few times. */
+ MPN_NORMALIZE( bp, bsize );
+ }
+ else
+ bp = base->d;
+
+ if (!bsize)
+ {
+ res->nlimbs = 0;
+ res->sign = 0;
+ goto leave;
+ }
+
+
+ /* Make BASE, EXPO and MOD not overlap with RES. */
+ if ( rp == bp )
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ gcry_assert (!bp_marker);
+ bp_nlimbs = bsec? bsize:0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
+ MPN_COPY(bp, rp, bsize);
+ }
+ if ( rp == ep )
+ {
+ /* RES and EXPO are identical. Allocate temp. space for EXPO. */
+ ep_nlimbs = esec? esize:0;
+ ep = ep_marker = mpi_alloc_limb_space( esize, esec );
+ MPN_COPY(ep, rp, esize);
+ }
+ if ( rp == mp )
+ {
+ /* RES and MOD are identical. Allocate temporary space for MOD.*/
+ gcry_assert (!mp_marker);
+ mp_nlimbs = msec?msize:0;
+ mp = mp_marker = mpi_alloc_limb_space( msize, msec );
+ MPN_COPY(mp, rp, msize);
+ }
+
+ /* Copy base to the result. */
+ if (res->alloced < size)
+ {
+ mpi_resize (res, size);
+ rp = res->d;
+ }
+ MPN_COPY ( rp, bp, bsize );
+ rsize = bsize;
+ rsign = 0;
+
+ /* Main processing. */
+ {
+ mpi_size_t i;
+ mpi_ptr_t xp;
+ int c;
+ mpi_limb_t e;
+ mpi_limb_t carry_limb;
+ struct karatsuba_ctx karactx;
+ struct gcry_mpi w, u;
+
+ xp_nlimbs = msec? size:0;
+ xp = xp_marker = mpi_alloc_limb_space( size, msec );
+
+ w.sign = u.sign = 0;
+ w.flags = u.flags = 0;
+ w.alloced = w.nlimbs = size; /* RES->alloc may be longer. */
+ u.alloced = u.nlimbs = size;
+
+ memset( &karactx, 0, sizeof karactx );
+ negative_result = (ep[0] & 1) && bsign;
+
+ i = esize - 1;
+ e = ep[i];
+ count_leading_zeros (c, e);
+ e = (e << c) << 1; /* Shift the expo bits to the left, lose msb. */
+ c = BITS_PER_MPI_LIMB - 1 - c;
+
+ /* Main loop.
+
+ Make the result be pointed to alternately by XP and RP. This
+ helps us avoid block copying, which would otherwise be
+ necessary with the overlap restrictions of
+ _gcry_mpih_divmod. With 50% probability the result after this
+ loop will be in the area originally pointed by RP (==RES->d),
+ and with 50% probability in the area originally pointed to by XP. */
+ for (;;)
+ {
+ while (c)
+ {
+ mpi_ptr_t tp;
+ mpi_size_t xsize;
+
+ /*mpih_mul_n(xp, rp, rp, rsize);*/
+ if ( rsize < KARATSUBA_THRESHOLD )
+ _gcry_mpih_sqr_n_basecase( xp, rp, rsize );
+ else
+ {
+ if ( !tspace )
+ {
+ tsize = 2 * rsize;
+ tspace = mpi_alloc_limb_space( tsize, 0 );
+ }
+ else if ( tsize < (2*rsize) )
+ {
+ _gcry_mpi_free_limb_space (tspace, 0);
+ tsize = 2 * rsize;
+ tspace = mpi_alloc_limb_space (tsize, 0 );
+ }
+ _gcry_mpih_sqr_n (xp, rp, rsize, tspace);
+ }
+
+ xsize = 2 * rsize;
+ if ( xsize > msize )
+ {
+ _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+
+ /* To mitigate the Yarom/Falkner flush+reload cache
+ * side-channel attack on the RSA secret exponent, we do
+ * the multiplication regardless of the value of the
+ * high-bit of E. But to avoid this performance penalty
+ * we do it only if the exponent has been stored in secure
+ * memory and we can thus assume it is a secret exponent. */
+ if (esec || (mpi_limb_signed_t)e < 0)
+ {
+ /*mpih_mul( xp, rp, rsize, bp, bsize );*/
+ if( bsize < KARATSUBA_THRESHOLD )
+ _gcry_mpih_mul ( xp, rp, rsize, bp, bsize );
+ else
+ _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, bp, bsize,
+ &karactx);
+
+ xsize = rsize + bsize;
+ if ( xsize > msize )
+ {
+ _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+ }
+
+ w.d = rp;
+ u.d = xp;
+ mpi_set_cond (&w, &u, ((mpi_limb_signed_t)e < 0));
+
+ e <<= 1;
+ c--;
+ }
+
+ i--;
+ if ( i < 0 )
+ break;
+ e = ep[i];
+ c = BITS_PER_MPI_LIMB;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left
+ MOD_SHIFT_CNT steps. Adjust the result by reducing it with the
+ original MOD.
+
+ Also make sure the result is put in RES->d (where it already
+ might be, see above). */
+ if ( mod_shift_cnt )
+ {
+ carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
+ rp = res->d;
+ if ( carry_limb )
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ }
+ else if (res->d != rp)
+ {
+ MPN_COPY (res->d, rp, rsize);
+ rp = res->d;
+ }
+
+ if ( rsize >= msize )
+ {
+ _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
+ rsize = msize;
+ }
+
+ /* Remove any leading zero words from the result. */
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
+ MPN_NORMALIZE (rp, rsize);
+
+ _gcry_mpih_release_karatsuba_ctx (&karactx );
+ }
+
+ /* Fixup for negative results. */
+ if ( negative_result && rsize )
+ {
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt);
+ _gcry_mpih_sub( rp, mp, msize, rp, rsize);
+ rsize = msize;
+ rsign = msign;
+ MPN_NORMALIZE(rp, rsize);
+ }
+ gcry_assert (res->d == rp);
+ res->nlimbs = rsize;
+ res->sign = rsign;
+
+ leave:
+ if (mp_marker)
+ _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
+ if (bp_marker)
+ _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs );
+ if (ep_marker)
+ _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs );
+ if (xp_marker)
+ _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs );
+ if (tspace)
+ _gcry_mpi_free_limb_space( tspace, 0 );
+}
+#else
+/**
+ * Internal function to compute
+ *
+ * X = R * S mod M
+ *
+ * and set the size of X at the pointer XSIZE_P.
+ * Use karatsuba structure at KARACTX_P.
+ *
+ * Condition:
+ * RSIZE >= SSIZE
+ * Enough space for X is allocated beforehand.
+ *
+ * For generic cases, we can/should use gcry_mpi_mulm.
+ * This function is use for specific internal case.
+ */
+static void
+mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p,
+ mpi_ptr_t rp, mpi_size_t rsize,
+ mpi_ptr_t sp, mpi_size_t ssize,
+ mpi_ptr_t mp, mpi_size_t msize,
+ struct karatsuba_ctx *karactx_p)
+{
+ if( ssize < KARATSUBA_THRESHOLD )
+ _gcry_mpih_mul ( xp, rp, rsize, sp, ssize );
+ else
+ _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, sp, ssize, karactx_p);
+
+ if (rsize + ssize > msize)
+ {
+ _gcry_mpih_divrem (xp + msize, 0, xp, rsize + ssize, mp, msize);
+ *xsize_p = msize;
+ }
+ else
+ *xsize_p = rsize + ssize;
+}
+
+#define SIZE_PRECOMP ((1 << (5 - 1)))
+
+/****************
+ * RES = BASE ^ EXPO mod MOD
+ *
+ * To mitigate the Yarom/Falkner flush+reload cache side-channel
+ * attack on the RSA secret exponent, we don't use the square
+ * routine but multiplication.
+ *
+ * Reference:
+ * Handbook of Applied Cryptography
+ * Algorithm 14.83: Modified left-to-right k-ary exponentiation
+ */
+void
+_gcry_mpi_powm (gcry_mpi_t res,
+ gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+{
+ /* Pointer to the limbs of the arguments, their size and signs. */
+ mpi_ptr_t rp, ep, mp, bp;
+ mpi_size_t esize, msize, bsize, rsize;
+ int msign, bsign, rsign;
+ /* Flags telling the secure allocation status of the arguments. */
+ int esec, msec, bsec;
+ /* Size of the result including space for temporary values. */
+ mpi_size_t size;
+ /* Helper. */
+ int mod_shift_cnt;
+ int negative_result;
+ mpi_ptr_t mp_marker = NULL;
+ mpi_ptr_t bp_marker = NULL;
+ mpi_ptr_t ep_marker = NULL;
+ mpi_ptr_t xp_marker = NULL;
+ unsigned int mp_nlimbs = 0;
+ unsigned int bp_nlimbs = 0;
+ unsigned int ep_nlimbs = 0;
+ unsigned int xp_nlimbs = 0;
+ mpi_ptr_t precomp[SIZE_PRECOMP]; /* Pre-computed array: BASE^1, ^3, ^5, ... */
+ mpi_size_t precomp_size[SIZE_PRECOMP];
+ mpi_size_t W;
+ mpi_ptr_t base_u;
+ mpi_size_t base_u_size;
+ mpi_size_t max_u_size;
+
+ esize = expo->nlimbs;
+ msize = mod->nlimbs;
+ size = 2 * msize;
+ msign = mod->sign;
+
+ ep = expo->d;
+ MPN_NORMALIZE(ep, esize);
+
+ if (esize * BITS_PER_MPI_LIMB > 512)
+ W = 5;
+ else if (esize * BITS_PER_MPI_LIMB > 256)
+ W = 4;
+ else if (esize * BITS_PER_MPI_LIMB > 128)
+ W = 3;
+ else if (esize * BITS_PER_MPI_LIMB > 64)
+ W = 2;
+ else
+ W = 1;
+
+ esec = mpi_is_secure(expo);
+ msec = mpi_is_secure(mod);
+ bsec = mpi_is_secure(base);
+
+ rp = res->d;
+
+ if (!msize)
+ _gcry_divide_by_zero();
+
+ if (!esize)
+ {
+ /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
+ on if MOD equals 1. */
+ res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+ if (res->nlimbs)
+ {
+ RESIZE_IF_NEEDED (res, 1);
+ rp = res->d;
+ rp[0] = 1;
+ }
+ res->sign = 0;
+ goto leave;
+ }
+
+ /* Normalize MOD (i.e. make its most significant bit set) as
+ required by mpn_divrem. This will make the intermediate values
+ in the calculation slightly larger, but the correct result is
+ obtained after a final reduction using the original MOD value. */
+ mp_nlimbs = msec? msize:0;
+ mp = mp_marker = mpi_alloc_limb_space(msize, msec);
+ count_leading_zeros (mod_shift_cnt, mod->d[msize-1]);
+ if (mod_shift_cnt)
+ _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt);
+ else
+ MPN_COPY( mp, mod->d, msize );
+
+ bsize = base->nlimbs;
+ bsign = base->sign;
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it.
+
+ Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp_nlimbs = bsec ? (bsize + 1):0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
+ MPN_COPY ( bp, base->d, bsize );
+ /* We don't care about the quotient, store it above the
+ * remainder, at BP + MSIZE. */
+ _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize );
+ bsize = msize;
+ /* Canonicalize the base, since we are going to multiply with it
+ quite a few times. */
+ MPN_NORMALIZE( bp, bsize );
+ }
+ else
+ bp = base->d;
+
+ if (!bsize)
+ {
+ res->nlimbs = 0;
+ res->sign = 0;
+ goto leave;
+ }
+
+
+ /* Make BASE, EXPO not overlap with RES. We don't need to check MOD
+ because that has already been copied to the MP var. */
+ if ( rp == bp )
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ gcry_assert (!bp_marker);
+ bp_nlimbs = bsec? bsize:0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
+ MPN_COPY(bp, rp, bsize);
+ }
+ if ( rp == ep )
+ {
+ /* RES and EXPO are identical. Allocate temp. space for EXPO. */
+ ep_nlimbs = esec? esize:0;
+ ep = ep_marker = mpi_alloc_limb_space( esize, esec );
+ MPN_COPY(ep, rp, esize);
+ }
+
+ /* Copy base to the result. */
+ if (res->alloced < size)
+ {
+ mpi_resize (res, size);
+ rp = res->d;
+ }
+
+ /* Main processing. */
+ {
+ mpi_size_t i, j, k;
+ mpi_ptr_t xp;
+ mpi_size_t xsize;
+ int c;
+ mpi_limb_t e;
+ mpi_limb_t carry_limb;
+ struct karatsuba_ctx karactx;
+ mpi_ptr_t tp;
+
+ xp_nlimbs = msec? size:0;
+ xp = xp_marker = mpi_alloc_limb_space( size, msec );
+
+ memset( &karactx, 0, sizeof karactx );
+ negative_result = (ep[0] & 1) && bsign;
+
+ /* Precompute PRECOMP[], BASE^(2 * i + 1), BASE^1, ^3, ^5, ... */
+ if (W > 1) /* X := BASE^2 */
+ mul_mod (xp, &xsize, bp, bsize, bp, bsize, mp, msize, &karactx);
+ base_u = precomp[0] = mpi_alloc_limb_space (bsize, esec);
+ base_u_size = max_u_size = precomp_size[0] = bsize;
+ MPN_COPY (precomp[0], bp, bsize);
+ for (i = 1; i < (1 << (W - 1)); i++)
+ { /* PRECOMP[i] = BASE^(2 * i + 1) */
+ if (xsize >= base_u_size)
+ mul_mod (rp, &rsize, xp, xsize, base_u, base_u_size,
+ mp, msize, &karactx);
+ else
+ mul_mod (rp, &rsize, base_u, base_u_size, xp, xsize,
+ mp, msize, &karactx);
+ base_u = precomp[i] = mpi_alloc_limb_space (rsize, esec);
+ base_u_size = precomp_size[i] = rsize;
+ if (max_u_size < base_u_size)
+ max_u_size = base_u_size;
+ MPN_COPY (precomp[i], rp, rsize);
+ }
+
+ if (msize > max_u_size)
+ max_u_size = msize;
+ base_u = mpi_alloc_limb_space (max_u_size, esec);
+ MPN_ZERO (base_u, max_u_size);
+
+ i = esize - 1;
+
+ /* Main loop.
+
+ Make the result be pointed to alternately by XP and RP. This
+ helps us avoid block copying, which would otherwise be
+ necessary with the overlap restrictions of
+ _gcry_mpih_divmod. With 50% probability the result after this
+ loop will be in the area originally pointed by RP (==RES->d),
+ and with 50% probability in the area originally pointed to by XP. */
+ rsign = 0;
+ if (W == 1)
+ {
+ rsize = bsize;
+ }
+ else
+ {
+ rsize = msize;
+ MPN_ZERO (rp, rsize);
+ }
+ MPN_COPY ( rp, bp, bsize );
+
+ e = ep[i];
+ count_leading_zeros (c, e);
+ e = (e << c) << 1;
+ c = BITS_PER_MPI_LIMB - 1 - c;
+
+ j = 0;
+
+ for (;;)
+ if (e == 0)
+ {
+ j += c;
+ if ( --i < 0 )
+ break;
+
+ e = ep[i];
+ c = BITS_PER_MPI_LIMB;
+ }
+ else
+ {
+ int c0;
+ mpi_limb_t e0;
+ struct gcry_mpi w, u;
+ w.sign = u.sign = 0;
+ w.flags = u.flags = 0;
+ w.d = base_u;
+
+ count_leading_zeros (c0, e);
+ e = (e << c0);
+ c -= c0;
+ j += c0;
+
+ e0 = (e >> (BITS_PER_MPI_LIMB - W));
+ if (c >= W)
+ c0 = 0;
+ else
+ {
+ if ( --i < 0 )
+ {
+ e0 = (e >> (BITS_PER_MPI_LIMB - c));
+ j += c - W;
+ goto last_step;
+ }
+ else
+ {
+ c0 = c;
+ e = ep[i];
+ c = BITS_PER_MPI_LIMB;
+ e0 |= (e >> (BITS_PER_MPI_LIMB - (W - c0)));
+ }
+ }
+
+ e = e << (W - c0);
+ c -= (W - c0);
+
+ last_step:
+ count_trailing_zeros (c0, e0);
+ e0 = (e0 >> c0) >> 1;
+
+ for (j += W - c0; j >= 0; j--)
+ {
+
+ /*
+ * base_u <= precomp[e0]
+ * base_u_size <= precomp_size[e0]
+ */
+ base_u_size = 0;
+ for (k = 0; k < (1<< (W - 1)); k++)
+ {
+ w.alloced = w.nlimbs = precomp_size[k];
+ u.alloced = u.nlimbs = precomp_size[k];
+ u.d = precomp[k];
+
+ mpi_set_cond (&w, &u, k == e0);
+ base_u_size |= ( precomp_size[k] & (0UL - (k == e0)) );
+ }
+
+ w.alloced = w.nlimbs = rsize;
+ u.alloced = u.nlimbs = rsize;
+ u.d = rp;
+ mpi_set_cond (&w, &u, j != 0);
+ base_u_size ^= ((base_u_size ^ rsize) & (0UL - (j != 0)));
+
+ mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+ mp, msize, &karactx);
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+
+ j = c0;
+ if ( i < 0 )
+ break;
+ }
+
+ while (j--)
+ {
+ mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left
+ MOD_SHIFT_CNT steps. Adjust the result by reducing it with the
+ original MOD.
+
+ Also make sure the result is put in RES->d (where it already
+ might be, see above). */
+ if ( mod_shift_cnt )
+ {
+ carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
+ rp = res->d;
+ if ( carry_limb )
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ }
+ else if (res->d != rp)
+ {
+ MPN_COPY (res->d, rp, rsize);
+ rp = res->d;
+ }
+
+ if ( rsize >= msize )
+ {
+ _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
+ rsize = msize;
+ }
+
+ /* Remove any leading zero words from the result. */
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
+ MPN_NORMALIZE (rp, rsize);
+
+ _gcry_mpih_release_karatsuba_ctx (&karactx );
+ for (i = 0; i < (1 << (W - 1)); i++)
+ _gcry_mpi_free_limb_space( precomp[i], esec ? precomp_size[i] : 0 );
+ _gcry_mpi_free_limb_space (base_u, esec ? max_u_size : 0);
+ }
+
+ /* Fixup for negative results. */
+ if ( negative_result && rsize )
+ {
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt);
+ _gcry_mpih_sub( rp, mp, msize, rp, rsize);
+ rsize = msize;
+ rsign = msign;
+ MPN_NORMALIZE(rp, rsize);
+ }
+ gcry_assert (res->d == rp);
+ res->nlimbs = rsize;
+ res->sign = rsign;
+
+ leave:
+ if (mp_marker)
+ _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
+ if (bp_marker)
+ _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs );
+ if (ep_marker)
+ _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs );
+ if (xp_marker)
+ _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs );
+}
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/mpi-scan.c b/comm/third_party/libgcrypt/mpi/mpi-scan.c
new file mode 100644
index 0000000000..e27f7faa99
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpi-scan.c
@@ -0,0 +1,130 @@
+/* mpi-scan.c - MPI functions
+ * 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
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+/****************
+ * Scan through an mpi and return byte for byte. a -1 is returned to indicate
+ * the end of the mpi. Scanning is done from the lsb to the msb, returned
+ * values are in the range of 0 .. 255.
+ *
+ * FIXME: This code is VERY ugly!
+ */
+/* int */
+/* _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ) */
+/* { */
+/* int i, j; */
+/* unsigned n; */
+/* mpi_ptr_t ap; */
+/* mpi_limb_t limb; */
+
+/* ap = a->d; */
+/* for(n=0,i=0; i < a->nlimbs; i++ ) { */
+/* limb = ap[i]; */
+/* for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) */
+/* if( n == idx ) */
+/* return (limb >> j*8) & 0xff; */
+/* } */
+/* return -1; */
+/* } */
+
+
+/****************
+ * Put a value at position IDX into A. idx counts from lsb to msb
+ */
+/* void */
+/* _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc ) */
+/* { */
+/* int i, j; */
+/* unsigned n; */
+/* mpi_ptr_t ap; */
+/* mpi_limb_t limb, c; */
+
+/* c = xc & 0xff; */
+/* ap = a->d; */
+/* for(n=0,i=0; i < a->alloced; i++ ) { */
+/* limb = ap[i]; */
+/* for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) */
+/* if( n == idx ) { */
+/* #if BYTES_PER_MPI_LIMB == 4 */
+/* if( j == 0 ) */
+/* limb = (limb & 0xffffff00) | c; */
+/* else if( j == 1 ) */
+/* limb = (limb & 0xffff00ff) | (c<<8); */
+/* else if( j == 2 ) */
+/* limb = (limb & 0xff00ffff) | (c<<16); */
+/* else */
+/* limb = (limb & 0x00ffffff) | (c<<24); */
+/* #elif BYTES_PER_MPI_LIMB == 8 */
+/* if( j == 0 ) */
+/* limb = (limb & 0xffffffffffffff00) | c; */
+/* else if( j == 1 ) */
+/* limb = (limb & 0xffffffffffff00ff) | (c<<8); */
+/* else if( j == 2 ) */
+/* limb = (limb & 0xffffffffff00ffff) | (c<<16); */
+/* else if( j == 3 ) */
+/* limb = (limb & 0xffffffff00ffffff) | (c<<24); */
+/* else if( j == 4 ) */
+/* limb = (limb & 0xffffff00ffffffff) | (c<<32); */
+/* else if( j == 5 ) */
+/* limb = (limb & 0xffff00ffffffffff) | (c<<40); */
+/* else if( j == 6 ) */
+/* limb = (limb & 0xff00ffffffffffff) | (c<<48); */
+/* else */
+/* limb = (limb & 0x00ffffffffffffff) | (c<<56); */
+/* #else */
+/* #error please enhance this function, its ugly - i know. */
+/* #endif */
+/* if( a->nlimbs <= i ) */
+/* a->nlimbs = i+1; */
+/* ap[i] = limb; */
+/* return; */
+/* } */
+/* } */
+/* abort(); /\* index out of range *\/ */
+/* } */
+
+
+/****************
+ * Count the number of zerobits at the low end of A
+ */
+unsigned
+_gcry_mpi_trailing_zeros( gcry_mpi_t a )
+{
+ unsigned n, count = 0;
+
+ for(n=0; n < a->nlimbs; n++ ) {
+ if( a->d[n] ) {
+ unsigned nn;
+ mpi_limb_t alimb = a->d[n];
+
+ count_trailing_zeros( nn, alimb );
+ count += nn;
+ break;
+ }
+ count += BITS_PER_MPI_LIMB;
+ }
+ return count;
+
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpicoder.c b/comm/third_party/libgcrypt/mpi/mpicoder.c
new file mode 100644
index 0000000000..f61f777f8d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpicoder.c
@@ -0,0 +1,958 @@
+/* mpicoder.c - Coder for the external representation of MPIs
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "g10lib.h"
+
+/* The maximum length we support in the functions converting an
+ * external representation to an MPI. This limit is used to catch
+ * programming errors and to avoid DoS due to insane long allocations.
+ * The 16 MiB limit is actually ridiculous large but some of those PQC
+ * algorithms use quite large keys and they might end up using MPIs
+ * for that. */
+#define MAX_EXTERN_SCAN_BYTES (16*1024*1024)
+
+/* The maximum length (in bits) we support for OpenPGP MPIs. Note
+ * that OpenPGP's MPI format uses only two bytes and thus would be
+ * limited to 64k anyway. Note that this limit matches that used by
+ * GnuPG. */
+#define MAX_EXTERN_MPI_BITS 16384
+
+
+/* Helper used to scan PGP style MPIs. Returns NULL on failure. */
+static gcry_mpi_t
+mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
+ int secure)
+{
+ int i, j;
+ unsigned int nbits, nbytes, nlimbs, nread=0;
+ mpi_limb_t a;
+ gcry_mpi_t val = MPI_NULL;
+
+ if ( *ret_nread < 2 )
+ goto leave;
+ nbits = buffer[0] << 8 | buffer[1];
+ if ( nbits > MAX_EXTERN_MPI_BITS )
+ {
+/* log_debug ("mpi too large (%u bits)\n", nbits); */
+ goto leave;
+ }
+ buffer += 2;
+ nread = 2;
+
+ nbytes = (nbits+7) / 8;
+ nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
+ val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
+ i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
+ i %= BYTES_PER_MPI_LIMB;
+ j= val->nlimbs = nlimbs;
+ val->sign = 0;
+ for ( ; j > 0; j-- )
+ {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++ )
+ {
+ if ( ++nread > *ret_nread )
+ {
+/* log_debug ("mpi larger than buffer"); */
+ mpi_free (val);
+ val = NULL;
+ goto leave;
+ }
+ a <<= 8;
+ a |= *buffer++;
+ }
+ i = 0;
+ val->d[j-1] = a;
+ }
+
+ leave:
+ *ret_nread = nread;
+ return val;
+}
+
+
+/****************
+ * Fill the mpi VAL from the hex string in STR.
+ */
+static int
+mpi_fromstr (gcry_mpi_t val, const char *str)
+{
+ int sign = 0;
+ int prepend_zero = 0;
+ int i, j, c, c1, c2;
+ unsigned int nbits, nbytes, nlimbs;
+ mpi_limb_t a;
+
+ if ( *str == '-' )
+ {
+ sign = 1;
+ str++;
+ }
+
+ /* Skip optional hex prefix. */
+ if ( *str == '0' && str[1] == 'x' )
+ str += 2;
+
+ nbits = strlen (str);
+ if (nbits > MAX_EXTERN_SCAN_BYTES)
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ nbits *= 4;
+ if ((nbits % 8))
+ prepend_zero = 1;
+
+ nbytes = (nbits+7) / 8;
+ nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
+
+ if ( val->alloced < nlimbs )
+ mpi_resize (val, nlimbs);
+
+ i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
+ i %= BYTES_PER_MPI_LIMB;
+ j = val->nlimbs = nlimbs;
+ val->sign = sign;
+ for (; j > 0; j--)
+ {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++)
+ {
+ if (prepend_zero)
+ {
+ c1 = '0';
+ prepend_zero = 0;
+ }
+ else
+ c1 = *str++;
+
+ if (!c1)
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ c2 = *str++;
+ if (!c2)
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ if ( c1 >= '0' && c1 <= '9' )
+ c = c1 - '0';
+ else if ( c1 >= 'a' && c1 <= 'f' )
+ c = c1 - 'a' + 10;
+ else if ( c1 >= 'A' && c1 <= 'F' )
+ c = c1 - 'A' + 10;
+ else
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ c <<= 4;
+ if ( c2 >= '0' && c2 <= '9' )
+ c |= c2 - '0';
+ else if( c2 >= 'a' && c2 <= 'f' )
+ c |= c2 - 'a' + 10;
+ else if( c2 >= 'A' && c2 <= 'F' )
+ c |= c2 - 'A' + 10;
+ else
+ {
+ mpi_clear(val);
+ return 1; /* Error. */
+ }
+ a <<= 8;
+ a |= c;
+ }
+ i = 0;
+ val->d[j-1] = a;
+ }
+
+ return 0; /* Okay. */
+}
+
+
+/* Return an allocated buffer with the MPI (msb first). NBYTES
+ receives the length of this buffer. If FILL_LE is not 0, the
+ returned value is stored as little endian and right padded with
+ zeroes so that the returned buffer has at least FILL_LE bytes.
+
+ If EXTRAALLOC > 0 the returned buffer has these number of bytes
+ extra allocated at the end; if EXTRAALLOC < 0 the returned buffer
+ has the absolute value of EXTRAALLOC allocated at the begin of the
+ buffer (the are not initialized) and the MPI is stored right after
+ this. This feature is useful to allow the caller to prefix the
+ returned value. EXTRAALLOC is _not_ included in the value stored
+ at NBYTES.
+
+ Caller must free the return string. This function returns an
+ allocated buffer with NBYTES set to zero if the value of A is zero.
+ If sign is not NULL, it will be set to the sign of the A. On error
+ NULL is returned and ERRNO set appropriately. */
+static unsigned char *
+do_get_buffer (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
+ unsigned int *nbytes, int *sign, int force_secure)
+{
+ unsigned char *p, *buffer, *retbuffer;
+ unsigned int length, tmp;
+ mpi_limb_t alimb;
+ int i;
+ size_t n, n2;
+
+ if (sign)
+ *sign = a->sign;
+
+ *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
+ n = *nbytes? *nbytes:1; /* Allocate at least one byte. */
+ if (n < fill_le)
+ n = fill_le;
+ if (extraalloc < 0)
+ n2 = n + -extraalloc;
+ else
+ n2 = n + extraalloc;
+
+ retbuffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n2)
+ : xtrymalloc (n2);
+ if (!retbuffer)
+ return NULL;
+ if (extraalloc < 0)
+ buffer = retbuffer + -extraalloc;
+ else
+ buffer = retbuffer;
+ p = buffer;
+
+ for (i=a->nlimbs-1; i >= 0; i--)
+ {
+ alimb = a->d[i];
+#if BYTES_PER_MPI_LIMB == 4
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb ;
+#elif BYTES_PER_MPI_LIMB == 8
+ *p++ = alimb >> 56;
+ *p++ = alimb >> 48;
+ *p++ = alimb >> 40;
+ *p++ = alimb >> 32;
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb ;
+#else
+# error please implement for this limb size.
+#endif
+ }
+
+ if (fill_le)
+ {
+ length = *nbytes;
+ /* Reverse buffer and pad with zeroes. */
+ for (i=0; i < length/2; i++)
+ {
+ tmp = buffer[i];
+ buffer[i] = buffer[length-1-i];
+ buffer[length-1-i] = tmp;
+ }
+ /* Pad with zeroes. */
+ for (p = buffer + length; length < fill_le; length++)
+ *p++ = 0;
+ *nbytes = length;
+
+ return retbuffer;
+ }
+
+ /* This is sub-optimal but we need to do the shift operation because
+ the caller has to free the returned buffer. */
+ for (p=buffer; *nbytes && !*p; p++, --*nbytes)
+ ;
+ if (p != buffer)
+ memmove (buffer, p, *nbytes);
+ return retbuffer;
+}
+
+
+byte *
+_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
+ unsigned int *r_nbytes, int *sign)
+{
+ if (mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+ {
+ unsigned int nbits;
+ byte *p = _gcry_mpi_get_opaque_copy (a, &nbits);
+
+ if (r_nbytes)
+ *r_nbytes = (nbits+7)/8;
+
+ return p;
+ }
+ else
+ return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 0);
+}
+
+byte *
+_gcry_mpi_get_buffer_extra (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
+ unsigned int *r_nbytes, int *sign)
+{
+ return do_get_buffer (a, fill_le, extraalloc, r_nbytes, sign, 0);
+}
+
+byte *
+_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
+ unsigned int *r_nbytes, int *sign)
+{
+ return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 1);
+}
+
+
+/*
+ * Use the NBYTES at BUFFER_ARG to update A. Set the sign of a to
+ * SIGN.
+ */
+void
+_gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
+ unsigned int nbytes, int sign)
+{
+ const unsigned char *buffer = (const unsigned char*)buffer_arg;
+ const unsigned char *p;
+ mpi_limb_t alimb;
+ int nlimbs;
+ int i;
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
+ RESIZE_IF_NEEDED(a, nlimbs);
+ a->sign = sign;
+
+ for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
+ {
+#if BYTES_PER_MPI_LIMB == 4
+ alimb = (mpi_limb_t)*p-- ;
+ alimb |= (mpi_limb_t)*p-- << 8 ;
+ alimb |= (mpi_limb_t)*p-- << 16 ;
+ alimb |= (mpi_limb_t)*p-- << 24 ;
+#elif BYTES_PER_MPI_LIMB == 8
+ alimb = (mpi_limb_t)*p-- ;
+ alimb |= (mpi_limb_t)*p-- << 8 ;
+ alimb |= (mpi_limb_t)*p-- << 16 ;
+ alimb |= (mpi_limb_t)*p-- << 24 ;
+ alimb |= (mpi_limb_t)*p-- << 32 ;
+ alimb |= (mpi_limb_t)*p-- << 40 ;
+ alimb |= (mpi_limb_t)*p-- << 48 ;
+ alimb |= (mpi_limb_t)*p-- << 56 ;
+#else
+# error please implement for this limb size.
+#endif
+ a->d[i++] = alimb;
+ }
+ if ( p >= buffer )
+ {
+#if BYTES_PER_MPI_LIMB == 4
+ alimb = (mpi_limb_t)*p--;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 8;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 16;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 24;
+#elif BYTES_PER_MPI_LIMB == 8
+ alimb = (mpi_limb_t)*p--;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 8;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 16;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 24;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 32;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 40;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 48;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 56;
+#else
+# error please implement for this limb size.
+#endif
+ a->d[i++] = alimb;
+ }
+ a->nlimbs = i;
+ gcry_assert (i == nlimbs);
+}
+
+
+static void
+onecompl (gcry_mpi_t a)
+{
+ mpi_ptr_t ap;
+ mpi_size_t n;
+ unsigned int i;
+ unsigned int nbits;
+
+ if (!a || mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ nbits = mpi_get_nbits (a);
+
+ mpi_normalize (a);
+ ap = a->d;
+ n = a->nlimbs;
+
+ for( i = 0; i < n; i++ )
+ ap[i] ^= (mpi_limb_t)(-1);
+
+ a->sign = 0;
+ mpi_clear_highbit (a, nbits-1);
+}
+
+
+/* Perform a two's complement operation on buffer P of size N bytes. */
+static void
+twocompl (unsigned char *p, unsigned int n)
+{
+ int i;
+
+ for (i=n-1; i >= 0 && !p[i]; i--)
+ ;
+ if (i >= 0)
+ {
+ if ((p[i] & 0x01))
+ p[i] = (((p[i] ^ 0xfe) | 0x01) & 0xff);
+ else if ((p[i] & 0x02))
+ p[i] = (((p[i] ^ 0xfc) | 0x02) & 0xfe);
+ else if ((p[i] & 0x04))
+ p[i] = (((p[i] ^ 0xf8) | 0x04) & 0xfc);
+ else if ((p[i] & 0x08))
+ p[i] = (((p[i] ^ 0xf0) | 0x08) & 0xf8);
+ else if ((p[i] & 0x10))
+ p[i] = (((p[i] ^ 0xe0) | 0x10) & 0xf0);
+ else if ((p[i] & 0x20))
+ p[i] = (((p[i] ^ 0xc0) | 0x20) & 0xe0);
+ else if ((p[i] & 0x40))
+ p[i] = (((p[i] ^ 0x80) | 0x40) & 0xc0);
+ else
+ p[i] = 0x80;
+
+ for (i--; i >= 0; i--)
+ p[i] ^= 0xff;
+ }
+}
+
+
+/* Convert the external representation of an integer stored in BUFFER
+ * with a length of BUFLEN into a newly create MPI returned in
+ * RET_MPI. If NSCANNED is not NULL, it will receive the number of
+ * bytes actually scanned after a successful operation. */
+gcry_err_code_t
+_gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
+ const void *buffer_arg, size_t buflen, size_t *nscanned)
+{
+ const unsigned char *buffer = (const unsigned char*)buffer_arg;
+ struct gcry_mpi *a = NULL;
+ unsigned int len;
+ int secure = (buffer && _gcry_is_secure (buffer));
+
+ if (buflen > MAX_EXTERN_SCAN_BYTES)
+ {
+ if (nscanned)
+ *nscanned = 0;
+ return GPG_ERR_INV_OBJ;
+ }
+
+ if (format == GCRYMPI_FMT_SSH)
+ len = 0;
+ else
+ len = buflen;
+
+ if (format == GCRYMPI_FMT_STD)
+ {
+ const unsigned char *s = buffer;
+
+ a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+ if (len)
+ {
+ _gcry_mpi_set_buffer (a, s, len, 0);
+ a->sign = !!(*s & 0x80);
+ if (a->sign)
+ {
+ onecompl (a);
+ mpi_add_ui (a, a, 1);
+ a->sign = 1;
+ }
+ }
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ if (nscanned)
+ *nscanned = len;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_USG)
+ {
+ a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+
+ if (len)
+ _gcry_mpi_set_buffer (a, buffer, len, 0);
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ if (nscanned)
+ *nscanned = len;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_PGP)
+ {
+ a = mpi_read_from_buffer (buffer, &len, secure);
+ if (nscanned)
+ *nscanned = len;
+ if (ret_mpi && a)
+ {
+ mpi_normalize (a);
+ *ret_mpi = a;
+ }
+ else if (a)
+ {
+ mpi_free(a);
+ a = NULL;
+ }
+ return a? 0 : GPG_ERR_INV_OBJ;
+ }
+ else if (format == GCRYMPI_FMT_SSH)
+ {
+ const unsigned char *s = buffer;
+ size_t n;
+
+ /* This test is not strictly necessary and an assert (!len)
+ would be sufficient. We keep this test in case we later
+ allow the BUFLEN argument to act as a sanitiy check. Same
+ below. */
+ if (len && len < 4)
+ return GPG_ERR_TOO_SHORT;
+
+ n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
+ s += 4;
+ if (len)
+ len -= 4;
+ if (len && n > len)
+ return GPG_ERR_TOO_LARGE;
+
+ a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+ if (n)
+ {
+ _gcry_mpi_set_buffer( a, s, n, 0 );
+ a->sign = !!(*s & 0x80);
+ if (a->sign)
+ {
+ onecompl (a);
+ mpi_add_ui (a, a, 1);
+ a->sign = 1;
+ }
+ }
+ if (nscanned)
+ *nscanned = n+4;
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_HEX)
+ {
+ /* We can only handle C strings for now. */
+ if (buflen)
+ return GPG_ERR_INV_ARG;
+
+ a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
+ if (mpi_fromstr (a, (const char *)buffer))
+ {
+ mpi_free (a);
+ return GPG_ERR_INV_OBJ;
+ }
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ if (nscanned)
+ *nscanned = strlen ((const char*)buffer);
+ return 0;
+ }
+ else
+ return GPG_ERR_INV_ARG;
+}
+
+
+/* Convert the big integer A into the external representation
+ described by FORMAT and store it in the provided BUFFER which has
+ been allocated by the user with a size of BUFLEN bytes. NWRITTEN
+ receives the actual length of the external representation unless it
+ has been passed as NULL. BUFFER may be NULL to query the required
+ length. */
+gcry_err_code_t
+_gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten, struct gcry_mpi *a)
+{
+ unsigned int nbits = mpi_get_nbits (a);
+ size_t len;
+ size_t dummy_nwritten;
+ int negative;
+
+ if (!nwritten)
+ nwritten = &dummy_nwritten;
+
+ /* Libgcrypt does no always care to set clear the sign if the value
+ is 0. For printing this is a bit of a surprise, in particular
+ because if some of the formats don't support negative numbers but
+ should be able to print a zero. Thus we need this extra test
+ for a negative number. */
+ if (a->sign && _gcry_mpi_cmp_ui (a, 0))
+ negative = 1;
+ else
+ negative = 0;
+
+ len = buflen;
+ *nwritten = 0;
+ if (format == GCRYMPI_FMT_STD)
+ {
+ unsigned char *tmp;
+ int extra = 0;
+ unsigned int n;
+
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
+ if (!tmp)
+ return gpg_err_code_from_syserror ();
+
+ if (negative)
+ {
+ twocompl (tmp, n);
+ if (!(*tmp & 0x80))
+ {
+ /* Need to extend the sign. */
+ n++;
+ extra = 2;
+ }
+ }
+ else if (n && (*tmp & 0x80))
+ {
+ /* Positive but the high bit of the returned buffer is set.
+ Thus we need to print an extra leading 0x00 so that the
+ output is interpreted as a positive number. */
+ n++;
+ extra = 1;
+ }
+
+ if (buffer && n > len)
+ {
+ /* The provided buffer is too short. */
+ xfree (tmp);
+ return GPG_ERR_TOO_SHORT;
+ }
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ if (extra == 1)
+ *s++ = 0;
+ else if (extra)
+ *s++ = 0xff;
+ memcpy (s, tmp, n-!!extra);
+ }
+ xfree (tmp);
+ *nwritten = n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_USG)
+ {
+ unsigned int n = (nbits + 7)/8;
+
+ /* Note: We ignore the sign for this format. */
+ /* FIXME: for performance reasons we should put this into
+ mpi_aprint because we can then use the buffer directly. */
+
+ if (buffer && n > len)
+ return GPG_ERR_TOO_SHORT;
+ if (buffer)
+ {
+ unsigned char *tmp;
+
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
+ if (!tmp)
+ return gpg_err_code_from_syserror ();
+ memcpy (buffer, tmp, n);
+ xfree (tmp);
+ }
+ *nwritten = n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_PGP)
+ {
+ unsigned int n = (nbits + 7)/8;
+
+ /* The PGP format can only handle unsigned integers. */
+ if (negative)
+ return GPG_ERR_INV_ARG;
+
+ if (buffer && n+2 > len)
+ return GPG_ERR_TOO_SHORT;
+
+ if (buffer)
+ {
+ unsigned char *tmp;
+ unsigned char *s = buffer;
+
+ s[0] = nbits >> 8;
+ s[1] = nbits;
+
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
+ if (!tmp)
+ return gpg_err_code_from_syserror ();
+ memcpy (s+2, tmp, n);
+ xfree (tmp);
+ }
+ *nwritten = n+2;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_SSH)
+ {
+ unsigned char *tmp;
+ int extra = 0;
+ unsigned int n;
+
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
+ if (!tmp)
+ return gpg_err_code_from_syserror ();
+
+ if (negative)
+ {
+ twocompl (tmp, n);
+ if (!(*tmp & 0x80))
+ {
+ /* Need to extend the sign. */
+ n++;
+ extra = 2;
+ }
+ }
+ else if (n && (*tmp & 0x80))
+ {
+ n++;
+ extra=1;
+ }
+
+ if (buffer && n+4 > len)
+ {
+ xfree(tmp);
+ return GPG_ERR_TOO_SHORT;
+ }
+
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ *s++ = n >> 24;
+ *s++ = n >> 16;
+ *s++ = n >> 8;
+ *s++ = n;
+ if (extra == 1)
+ *s++ = 0;
+ else if (extra)
+ *s++ = 0xff;
+ memcpy (s, tmp, n-!!extra);
+ }
+ xfree (tmp);
+ *nwritten = 4+n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_HEX)
+ {
+ unsigned char *tmp;
+ int i;
+ int extra = 0;
+ unsigned int n = 0;
+
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
+ if (!tmp)
+ return gpg_err_code_from_syserror ();
+ if (!n || (*tmp & 0x80))
+ extra = 2;
+
+ if (buffer && 2*n + extra + negative + 1 > len)
+ {
+ xfree(tmp);
+ return GPG_ERR_TOO_SHORT;
+ }
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ if (negative)
+ *s++ = '-';
+ if (extra)
+ {
+ *s++ = '0';
+ *s++ = '0';
+ }
+
+ for (i=0; i < n; i++)
+ {
+ unsigned int c = tmp[i];
+
+ *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
+ c &= 15;
+ *s++ = c < 10? '0'+c : 'A'+c-10 ;
+ }
+ *s++ = 0;
+ *nwritten = s - buffer;
+ }
+ else
+ {
+ *nwritten = 2*n + extra + negative + 1;
+ }
+ xfree (tmp);
+ return 0;
+ }
+ else
+ return GPG_ERR_INV_ARG;
+}
+
+
+/*
+ * Like gcry_mpi_print but this function allocates the buffer itself.
+ * The caller has to supply the address of a pointer. NWRITTEN may be
+ * NULL.
+ */
+gcry_err_code_t
+_gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ struct gcry_mpi *a)
+{
+ size_t n;
+ gcry_err_code_t rc;
+
+ *buffer = NULL;
+ rc = _gcry_mpi_print (format, NULL, 0, &n, a);
+ if (rc)
+ return rc;
+
+ *buffer = mpi_is_secure(a) ? xtrymalloc_secure (n?n:1) : xtrymalloc (n?n:1);
+ if (!*buffer)
+ return gpg_err_code_from_syserror ();
+ /* If the returned buffer will have a length of 0, we nevertheless
+ allocated 1 byte (malloc needs it anyway) and store a 0. */
+ if (!n)
+ **buffer = 0;
+ rc = _gcry_mpi_print( format, *buffer, n, &n, a );
+ if (rc)
+ {
+ xfree (*buffer);
+ *buffer = NULL;
+ }
+ else if (nwritten)
+ *nwritten = n;
+ return rc;
+}
+
+
+/* Turn VALUE into an octet string and store it in an allocated buffer
+ at R_FRAME or - if R_RAME is NULL - copy it into the caller
+ provided buffer SPACE; either SPACE or R_FRAME may be used. If
+ SPACE if not NULL, the caller must provide a buffer of at least
+ NBYTES. If the resulting octet string is shorter than NBYTES pad
+ it to the left with zeroes. If VALUE does not fit into NBYTES
+ return an error code. */
+gpg_err_code_t
+_gcry_mpi_to_octet_string (unsigned char **r_frame, void *space,
+ gcry_mpi_t value, size_t nbytes)
+{
+ gpg_err_code_t rc;
+ size_t nframe, noff, n;
+ unsigned char *frame;
+
+ if (!r_frame == !space)
+ return GPG_ERR_INV_ARG; /* Only one may be used. */
+
+ if (r_frame)
+ *r_frame = NULL;
+
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
+ if (rc)
+ return rc;
+ if (nframe > nbytes)
+ return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES. */
+
+ noff = (nframe < nbytes)? nbytes - nframe : 0;
+ n = nframe + noff;
+ if (space)
+ frame = space;
+ else
+ {
+ frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
+ if (!frame)
+ {
+ rc = gpg_err_code_from_syserror ();
+ return rc;
+ }
+ }
+ if (noff)
+ memset (frame, 0, noff);
+ nframe += noff;
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
+ if (rc)
+ {
+ xfree (frame);
+ return rc;
+ }
+
+ if (r_frame)
+ *r_frame = frame;
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpih-const-time.c b/comm/third_party/libgcrypt/mpi/mpih-const-time.c
new file mode 100644
index 0000000000..968995059c
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpih-const-time.c
@@ -0,0 +1,197 @@
+/* mpih-const-time.c - Constant-time MPI helper functions
+ * Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "g10lib.h"
+
+#define A_LIMB_1 ((mpi_limb_t)1)
+
+/*
+ * W = U when OP_ENABLED=1
+ * otherwise, W keeps old value
+ */
+void
+_gcry_mpih_set_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned long op_enable)
+{
+ mpi_size_t i;
+ mpi_limb_t mask = ((mpi_limb_t)0) - op_enable;
+ mpi_limb_t x;
+
+ for (i = 0; i < usize; i++)
+ {
+ x = mask & (wp[i] ^ up[i]);
+ wp[i] = wp[i] ^ x;
+ }
+}
+
+
+/*
+ * W = U + V when OP_ENABLED=1
+ * otherwise, W = U
+ */
+mpi_limb_t
+_gcry_mpih_add_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t usize, unsigned long op_enable)
+{
+ mpi_size_t i;
+ mpi_limb_t cy;
+ mpi_limb_t mask = ((mpi_limb_t)0) - op_enable;
+
+ cy = 0;
+ for (i = 0; i < usize; i++)
+ {
+ mpi_limb_t x = up[i] + (vp[i] & mask);
+ mpi_limb_t cy1 = x < up[i];
+ mpi_limb_t cy2;
+
+ x = x + cy;
+ cy2 = x < cy;
+ cy = cy1 | cy2;
+ wp[i] = x;
+ }
+
+ return cy;
+}
+
+
+/*
+ * W = U - V when OP_ENABLED=1
+ * otherwise, W = U
+ */
+mpi_limb_t
+_gcry_mpih_sub_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t usize, unsigned long op_enable)
+{
+ mpi_size_t i;
+ mpi_limb_t cy;
+ mpi_limb_t mask = ((mpi_limb_t)0) - op_enable;
+
+ cy = 0;
+ for (i = 0; i < usize; i++)
+ {
+ mpi_limb_t x = up[i] - (vp[i] & mask);
+ mpi_limb_t cy1 = x > up[i];
+ mpi_limb_t cy2;
+
+ cy2 = x < cy;
+ x = x - cy;
+ cy = cy1 | cy2;
+ wp[i] = x;
+ }
+
+ return cy;
+}
+
+
+/*
+ * Swap value of U and V when OP_ENABLED=1
+ * otherwise, no change
+ */
+void
+_gcry_mpih_swap_cond (mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t usize,
+ unsigned long op_enable)
+{
+ mpi_size_t i;
+ mpi_limb_t mask = ((mpi_limb_t)0) - op_enable;
+
+ for (i = 0; i < usize; i++)
+ {
+ mpi_limb_t x = mask & (up[i] ^ vp[i]);
+
+ up[i] = up[i] ^ x;
+ vp[i] = vp[i] ^ x;
+ }
+}
+
+
+/*
+ * W = -U when OP_ENABLED=1
+ * otherwise, W = U
+ */
+void
+_gcry_mpih_abs_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned long op_enable)
+{
+ mpi_size_t i;
+ mpi_limb_t mask = ((mpi_limb_t)0) - op_enable;
+ mpi_limb_t cy = op_enable;
+
+ for (i = 0; i < usize; i++)
+ {
+ mpi_limb_t x = ~up[i] + cy;
+
+ cy = (x < ~up[i]);
+ wp[i] = up[i] ^ (mask & (x ^ up[i]));
+ }
+}
+
+
+/*
+ * Allocating memory for W,
+ * compute W = V % U, then return W
+ */
+mpi_ptr_t
+_gcry_mpih_mod (mpi_ptr_t vp, mpi_size_t vsize,
+ mpi_ptr_t up, mpi_size_t usize)
+{
+ int secure;
+ mpi_ptr_t rp;
+ mpi_size_t i;
+
+ secure = _gcry_is_secure (vp);
+ rp = mpi_alloc_limb_space (usize, secure);
+ MPN_ZERO (rp, usize);
+
+ for (i = 0; i < vsize * BITS_PER_MPI_LIMB; i++)
+ {
+ unsigned int j = vsize * BITS_PER_MPI_LIMB - 1 - i;
+ unsigned int limbno = j / BITS_PER_MPI_LIMB;
+ unsigned int bitno = j % BITS_PER_MPI_LIMB;
+ mpi_limb_t limb = vp[limbno];
+ unsigned int the_bit = ((limb & (A_LIMB_1 << bitno)) ? 1 : 0);
+ mpi_limb_t underflow;
+ mpi_limb_t overflow;
+
+ overflow = _gcry_mpih_lshift (rp, rp, usize, 1);
+ rp[0] |= the_bit;
+
+ underflow = _gcry_mpih_sub_n (rp, rp, up, usize);
+ mpih_add_n_cond (rp, rp, up, usize, overflow ^ underflow);
+ }
+
+ return rp;
+}
+
+int
+_gcry_mpih_cmp_ui (mpi_ptr_t up, mpi_size_t usize, unsigned long v)
+{
+ int is_all_zero = 1;
+ mpi_size_t i;
+
+ for (i = 1; i < usize; i++)
+ is_all_zero &= (up[i] == 0);
+
+ if (is_all_zero)
+ return up[0] - v;
+ return 1;
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpih-div.c b/comm/third_party/libgcrypt/mpi/mpih-div.c
new file mode 100644
index 0000000000..57c1b58487
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpih-div.c
@@ -0,0 +1,532 @@
+/* mpih-div.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2000,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+/* FIXME: We should be using invert_limb (or invert_normalized_limb)
+ * here (not udiv_qrnnd).
+ */
+
+mpi_limb_t
+_gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb)
+{
+ mpi_size_t i;
+ mpi_limb_t n1, n0, r;
+ mpi_limb_t dummy GCC_ATTR_UNUSED;
+
+ /* Botch: Should this be handled at all? Rely on callers? */
+ if( !dividend_size )
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ * dividend is large, pre-invert the divisor, and use
+ * only multiplications in the inner loop.
+ *
+ * This test should be read:
+ * Does it ever help to use udiv_qrnnd_preinv?
+ * && Does what we save compensate for the inversion overhead?
+ */
+ if( UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
+ int normalization_steps;
+
+ count_leading_zeros( normalization_steps, divisor_limb );
+ if( normalization_steps ) {
+ mpi_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ *
+ * Special case for DIVISOR_LIMB == 100...000.
+ */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ UDIV_QRNND_PREINV(dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else {
+ mpi_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ *
+ * Special case for DIVISOR_LIMB == 100...000.
+ */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if( r >= divisor_limb )
+ r = 0;
+ else
+ i--;
+
+ for( ; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(dummy, r, r,
+ n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+ }
+ }
+ else {
+ if( UDIV_NEEDS_NORMALIZATION ) {
+ int normalization_steps;
+
+ count_leading_zeros(normalization_steps, divisor_limb);
+ if( normalization_steps ) {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for(i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ * it, or because DIVISOR_LIMB is already normalized. */
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if(r >= divisor_limb)
+ r = 0;
+ else
+ i--;
+
+ for(; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r, n0, divisor_limb);
+ }
+ return r;
+ }
+}
+
+/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
+ * the NSIZE-DSIZE least significant quotient limbs at QP
+ * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is
+ * non-zero, generate that many fraction bits and append them after the
+ * other quotient limbs.
+ * Return the most significant limb of the quotient, this is always 0 or 1.
+ *
+ * Preconditions:
+ * 0. NSIZE >= DSIZE.
+ * 1. The most significant bit of the divisor must be set.
+ * 2. QP must either not overlap with the input operands at all, or
+ * QP + DSIZE >= NP must hold true. (This means that it's
+ * possible to put the quotient in the high part of NUM, right after the
+ * remainder in NUM.
+ * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero.
+ */
+
+mpi_limb_t
+_gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
+ mpi_ptr_t np, mpi_size_t nsize,
+ mpi_ptr_t dp, mpi_size_t dsize)
+{
+ mpi_limb_t most_significant_q_limb = 0;
+
+ switch(dsize) {
+ case 0:
+ _gcry_divide_by_zero();
+ break;
+
+ case 1:
+ {
+ mpi_size_t i;
+ mpi_limb_t n1;
+ mpi_limb_t d;
+
+ d = dp[0];
+ n1 = np[nsize - 1];
+
+ if( n1 >= d ) {
+ n1 -= d;
+ most_significant_q_limb = 1;
+ }
+
+ qp += qextra_limbs;
+ for( i = nsize - 2; i >= 0; i--)
+ udiv_qrnnd( qp[i], n1, n1, np[i], d );
+ qp -= qextra_limbs;
+
+ for( i = qextra_limbs - 1; i >= 0; i-- )
+ udiv_qrnnd (qp[i], n1, n1, 0, d);
+
+ np[0] = n1;
+ }
+ break;
+
+ case 2:
+ {
+ mpi_size_t i;
+ mpi_limb_t n1, n0, n2;
+ mpi_limb_t d1, d0;
+
+ np += nsize - 2;
+ d1 = dp[1];
+ d0 = dp[0];
+ n1 = np[1];
+ n0 = np[0];
+
+ if( n1 >= d1 && (n1 > d1 || n0 >= d0) ) {
+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
+ most_significant_q_limb = 1;
+ }
+
+ for( i = qextra_limbs + nsize - 2 - 1; i >= 0; i-- ) {
+ mpi_limb_t q;
+ mpi_limb_t r;
+
+ if( i >= qextra_limbs )
+ np--;
+ else
+ np[0] = 0;
+
+ if( n1 == d1 ) {
+ /* Q should be either 111..111 or 111..110. Need special
+ * treatment of this rare case as normal division would
+ * give overflow. */
+ q = ~(mpi_limb_t)0;
+
+ r = n0 + d1;
+ if( r < d1 ) { /* Carry in the addition? */
+ add_ssaaaa( n1, n0, r - d0, np[0], 0, d0 );
+ qp[i] = q;
+ continue;
+ }
+ n1 = d0 - (d0 != 0?1:0);
+ n0 = -d0;
+ }
+ else {
+ udiv_qrnnd (q, r, n1, n0, d1);
+ umul_ppmm (n1, n0, d0, q);
+ }
+
+ n2 = np[0];
+ q_test:
+ if( n1 > r || (n1 == r && n0 > n2) ) {
+ /* The estimated Q was too large. */
+ q--;
+ sub_ddmmss (n1, n0, n1, n0, 0, d0);
+ r += d1;
+ if( r >= d1 ) /* If not carry, test Q again. */
+ goto q_test;
+ }
+
+ qp[i] = q;
+ sub_ddmmss (n1, n0, r, n2, n1, n0);
+ }
+ np[1] = n1;
+ np[0] = n0;
+ }
+ break;
+
+ default:
+ {
+ mpi_size_t i;
+ mpi_limb_t dX, d1, n0;
+
+ np += nsize - dsize;
+ dX = dp[dsize - 1];
+ d1 = dp[dsize - 2];
+ n0 = np[dsize - 1];
+
+ if( n0 >= dX ) {
+ if(n0 > dX || _gcry_mpih_cmp(np, dp, dsize - 1) >= 0 ) {
+ _gcry_mpih_sub_n(np, np, dp, dsize);
+ n0 = np[dsize - 1];
+ most_significant_q_limb = 1;
+ }
+ }
+
+ for( i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) {
+ mpi_limb_t q;
+ mpi_limb_t n1, n2;
+ mpi_limb_t cy_limb;
+
+ if( i >= qextra_limbs ) {
+ np--;
+ n2 = np[dsize];
+ }
+ else {
+ n2 = np[dsize - 1];
+ MPN_COPY_DECR (np + 1, np, dsize - 1);
+ np[0] = 0;
+ }
+
+ if( n0 == dX ) {
+ /* This might over-estimate q, but it's probably not worth
+ * the extra code here to find out. */
+ q = ~(mpi_limb_t)0;
+ }
+ else {
+ mpi_limb_t r;
+
+ udiv_qrnnd(q, r, n0, np[dsize - 1], dX);
+ umul_ppmm(n1, n0, d1, q);
+
+ while( n1 > r || (n1 == r && n0 > np[dsize - 2])) {
+ q--;
+ r += dX;
+ if( r < dX ) /* I.e. "carry in previous addition?" */
+ break;
+ n1 -= n0 < d1;
+ n0 -= d1;
+ }
+ }
+
+ /* Possible optimization: We already have (q * n0) and (1 * n1)
+ * after the calculation of q. Taking advantage of that, we
+ * could make this loop make two iterations less. */
+ cy_limb = _gcry_mpih_submul_1(np, dp, dsize, q);
+
+ if( n2 != cy_limb ) {
+ _gcry_mpih_add_n(np, np, dp, dsize);
+ q--;
+ }
+
+ qp[i] = q;
+ n0 = np[dsize - 1];
+ }
+ }
+ }
+
+ return most_significant_q_limb;
+}
+
+
+/****************
+ * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
+ * Return the single-limb remainder.
+ * There are no constraints on the value of the divisor.
+ *
+ * QUOT_PTR and DIVIDEND_PTR might point to the same limb.
+ */
+
+mpi_limb_t
+_gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
+ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb)
+{
+ mpi_size_t i;
+ mpi_limb_t n1, n0, r;
+ mpi_limb_t dummy GCC_ATTR_UNUSED;
+
+ if( !dividend_size )
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ * dividend is large, pre-invert the divisor, and use
+ * only multiplications in the inner loop.
+ *
+ * This test should be read:
+ * Does it ever help to use udiv_qrnnd_preinv?
+ * && Does what we save compensate for the inversion overhead?
+ */
+ if( UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
+ int normalization_steps;
+
+ count_leading_zeros( normalization_steps, divisor_limb );
+ if( normalization_steps ) {
+ mpi_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ */
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV( quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ UDIV_QRNND_PREINV( quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else {
+ mpi_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ */
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t) 0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if( r >= divisor_limb )
+ r = 0;
+ else
+ quot_ptr[i--] = 0;
+
+ for( ; i >= 0; i-- ) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV( quot_ptr[i], r, r,
+ n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+ }
+ }
+ else {
+ if(UDIV_NEEDS_NORMALIZATION) {
+ int normalization_steps;
+
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if( normalization_steps ) {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ * it, or because DIVISOR_LIMB is already normalized. */
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if(r >= divisor_limb)
+ r = 0;
+ else
+ quot_ptr[i--] = 0;
+
+ for(; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd( quot_ptr[i], r, r, n0, divisor_limb );
+ }
+ return r;
+ }
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpih-mul.c b/comm/third_party/libgcrypt/mpi/mpih-mul.c
new file mode 100644
index 0000000000..8b6f06a30a
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpih-mul.c
@@ -0,0 +1,529 @@
+/* mpih-mul.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 1999, 2000,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if( (size) < KARATSUBA_THRESHOLD ) \
+ mul_n_basecase (prodp, up, vp, size); \
+ else \
+ mul_n (prodp, up, vp, size, tspace); \
+ } while (0);
+
+#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
+ do { \
+ if ((size) < KARATSUBA_THRESHOLD) \
+ _gcry_mpih_sqr_n_basecase (prodp, up, size); \
+ else \
+ _gcry_mpih_sqr_n (prodp, up, size, tspace); \
+ } while (0);
+
+
+
+
+/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
+ * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
+ * always stored. Return the most significant limb.
+ *
+ * Argument constraints:
+ * 1. PRODP != UP and PRODP != VP, i.e. the destination
+ * must be distinct from the multiplier and the multiplicand.
+ *
+ *
+ * Handle simple cases with traditional multiplication.
+ *
+ * This is the most critical code of multiplication. All multiplies rely
+ * on this, both small and huge. Small ones arrive here immediately. Huge
+ * ones arrive here as this is the base case for Karatsuba's recursive
+ * algorithm below.
+ */
+
+static mpi_limb_t
+mul_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up,
+ mpi_ptr_t vp, mpi_size_t size)
+{
+ mpi_size_t i;
+ mpi_limb_t cy;
+ mpi_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, size );
+ else
+ MPN_ZERO( prodp, size );
+ cy = 0;
+ }
+ else
+ cy = _gcry_mpih_mul_1( prodp, up, size, v_limb );
+
+ prodp[size] = cy;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i = 1; i < size; i++ ) {
+ v_limb = vp[i];
+ if( v_limb <= 1 ) {
+ cy = 0;
+ if( v_limb == 1 )
+ cy = _gcry_mpih_add_n(prodp, prodp, up, size);
+ }
+ else
+ cy = _gcry_mpih_addmul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy;
+ prodp++;
+ }
+
+ return cy;
+}
+
+
+static void
+mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t size, mpi_ptr_t tspace )
+{
+ if( size & 1 ) {
+ /* The size is odd, and the code below doesn't handle that.
+ * Multiply the least significant (size - 1) limbs with a recursive
+ * call, and handle the most significant limb of S1 and S2
+ * separately.
+ * A slightly faster way to do this would be to make the Karatsuba
+ * code below behave as if the size were even, and let it check for
+ * odd size in the end. I.e., in essence move this code to the end.
+ * Doing so would save us a recursive call, and potentially make the
+ * stack grow a lot less.
+ */
+ mpi_size_t esize = size - 1; /* even size */
+ mpi_limb_t cy_limb;
+
+ MPN_MUL_N_RECURSE( prodp, up, vp, esize, tspace );
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, vp[esize] );
+ prodp[esize + esize] = cy_limb;
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, vp, size, up[esize] );
+ prodp[esize + size] = cy_limb;
+ }
+ else {
+ /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
+ *
+ * Split U in two pieces, U1 and U0, such that
+ * U = U0 + U1*(B**n),
+ * and V in V1 and V0, such that
+ * V = V0 + V1*(B**n).
+ *
+ * UV is then computed recursively using the identity
+ *
+ * 2n n n n
+ * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
+ * 1 1 1 0 0 1 0 0
+ *
+ * Where B = 2**BITS_PER_MP_LIMB.
+ */
+ mpi_size_t hsize = size >> 1;
+ mpi_limb_t cy;
+ int negflg;
+
+ /* Product H. ________________ ________________
+ * |_____U1 x V1____||____U0 x V0_____|
+ * Put result in upper part of PROD and pass low part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize, tspace);
+
+ /* Product M. ________________
+ * |_(U1-U0)(V0-V1)_|
+ */
+ if( _gcry_mpih_cmp(up + hsize, up, hsize) >= 0 ) {
+ _gcry_mpih_sub_n(prodp, up + hsize, up, hsize);
+ negflg = 0;
+ }
+ else {
+ _gcry_mpih_sub_n(prodp, up, up + hsize, hsize);
+ negflg = 1;
+ }
+ if( _gcry_mpih_cmp(vp + hsize, vp, hsize) >= 0 ) {
+ _gcry_mpih_sub_n(prodp + hsize, vp + hsize, vp, hsize);
+ negflg ^= 1;
+ }
+ else {
+ _gcry_mpih_sub_n(prodp + hsize, vp, vp + hsize, hsize);
+ /* No change of NEGFLG. */
+ }
+ /* Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize, tspace + size);
+
+ /* Add/copy product H. */
+ MPN_COPY (prodp + hsize, prodp + size, hsize);
+ cy = _gcry_mpih_add_n( prodp + size, prodp + size,
+ prodp + size + hsize, hsize);
+
+ /* Add product M (if NEGFLG M is a negative number) */
+ if(negflg)
+ cy -= _gcry_mpih_sub_n(prodp + hsize, prodp + hsize, tspace, size);
+ else
+ cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size);
+
+ /* Product L. ________________ ________________
+ * |________________||____U0 x V0_____|
+ * Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size);
+
+ /* Add/copy Product L (twice) */
+
+ cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size);
+ if( cy )
+ _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size, hsize, cy);
+
+ MPN_COPY(prodp, tspace, hsize);
+ cy = _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace + hsize, hsize);
+ if( cy )
+ _gcry_mpih_add_1(prodp + size, prodp + size, size, 1);
+ }
+}
+
+
+void
+_gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size )
+{
+ mpi_size_t i;
+ mpi_limb_t cy_limb;
+ mpi_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = up[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, size );
+ else
+ MPN_ZERO(prodp, size);
+ cy_limb = 0;
+ }
+ else
+ cy_limb = _gcry_mpih_mul_1( prodp, up, size, v_limb );
+
+ prodp[size] = cy_limb;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i=1; i < size; i++) {
+ v_limb = up[i];
+ if( v_limb <= 1 ) {
+ cy_limb = 0;
+ if( v_limb == 1 )
+ cy_limb = _gcry_mpih_add_n(prodp, prodp, up, size);
+ }
+ else
+ cy_limb = _gcry_mpih_addmul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+ }
+}
+
+
+void
+_gcry_mpih_sqr_n( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace)
+{
+ if( size & 1 ) {
+ /* The size is odd, and the code below doesn't handle that.
+ * Multiply the least significant (size - 1) limbs with a recursive
+ * call, and handle the most significant limb of S1 and S2
+ * separately.
+ * A slightly faster way to do this would be to make the Karatsuba
+ * code below behave as if the size were even, and let it check for
+ * odd size in the end. I.e., in essence move this code to the end.
+ * Doing so would save us a recursive call, and potentially make the
+ * stack grow a lot less.
+ */
+ mpi_size_t esize = size - 1; /* even size */
+ mpi_limb_t cy_limb;
+
+ MPN_SQR_N_RECURSE( prodp, up, esize, tspace );
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, up[esize] );
+ prodp[esize + esize] = cy_limb;
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, size, up[esize] );
+
+ prodp[esize + size] = cy_limb;
+ }
+ else {
+ mpi_size_t hsize = size >> 1;
+ mpi_limb_t cy;
+
+ /* Product H. ________________ ________________
+ * |_____U1 x U1____||____U0 x U0_____|
+ * Put result in upper part of PROD and pass low part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace);
+
+ /* Product M. ________________
+ * |_(U1-U0)(U0-U1)_|
+ */
+ if( _gcry_mpih_cmp( up + hsize, up, hsize) >= 0 )
+ _gcry_mpih_sub_n( prodp, up + hsize, up, hsize);
+ else
+ _gcry_mpih_sub_n (prodp, up, up + hsize, hsize);
+
+ /* Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE. */
+ MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size);
+
+ /* Add/copy product H */
+ MPN_COPY(prodp + hsize, prodp + size, hsize);
+ cy = _gcry_mpih_add_n(prodp + size, prodp + size,
+ prodp + size + hsize, hsize);
+
+ /* Add product M (if NEGFLG M is a negative number). */
+ cy -= _gcry_mpih_sub_n (prodp + hsize, prodp + hsize, tspace, size);
+
+ /* Product L. ________________ ________________
+ * |________________||____U0 x U0_____|
+ * Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE. */
+ MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size);
+
+ /* Add/copy Product L (twice). */
+ cy += _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace, size);
+ if( cy )
+ _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size,
+ hsize, cy);
+
+ MPN_COPY(prodp, tspace, hsize);
+ cy = _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
+ if( cy )
+ _gcry_mpih_add_1 (prodp + size, prodp + size, size, 1);
+ }
+}
+
+
+/* This should be made into an inline function in gmp.h. */
+void
+_gcry_mpih_mul_n( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size)
+{
+ int secure;
+
+ if( up == vp ) {
+ if( size < KARATSUBA_THRESHOLD )
+ _gcry_mpih_sqr_n_basecase( prodp, up, size );
+ else {
+ mpi_ptr_t tspace;
+ secure = _gcry_is_secure( up );
+ tspace = mpi_alloc_limb_space( 2 * size, secure );
+ _gcry_mpih_sqr_n( prodp, up, size, tspace );
+ _gcry_mpi_free_limb_space (tspace, 2 * size );
+ }
+ }
+ else {
+ if( size < KARATSUBA_THRESHOLD )
+ mul_n_basecase( prodp, up, vp, size );
+ else {
+ mpi_ptr_t tspace;
+ secure = _gcry_is_secure( up ) || _gcry_is_secure( vp );
+ tspace = mpi_alloc_limb_space( 2 * size, secure );
+ mul_n (prodp, up, vp, size, tspace);
+ _gcry_mpi_free_limb_space (tspace, 2 * size );
+ }
+ }
+}
+
+
+
+void
+_gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize,
+ struct karatsuba_ctx *ctx )
+{
+ mpi_limb_t cy;
+
+ if( !ctx->tspace || ctx->tspace_size < vsize ) {
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ ctx->tspace_nlimbs = 2 * vsize;
+ ctx->tspace = mpi_alloc_limb_space (2 * vsize,
+ (_gcry_is_secure (up)
+ || _gcry_is_secure (vp)));
+ ctx->tspace_size = vsize;
+ }
+
+ MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace );
+
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ if( usize >= vsize ) {
+ if( !ctx->tp || ctx->tp_size < vsize ) {
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ ctx->tp_nlimbs = 2 * vsize;
+ ctx->tp = mpi_alloc_limb_space (2 * vsize,
+ (_gcry_is_secure (up)
+ || _gcry_is_secure (vp)));
+ ctx->tp_size = vsize;
+ }
+
+ do {
+ MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace );
+ cy = _gcry_mpih_add_n( prodp, prodp, ctx->tp, vsize );
+ _gcry_mpih_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy );
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ } while( usize >= vsize );
+ }
+
+ if( usize ) {
+ if( usize < KARATSUBA_THRESHOLD ) {
+ _gcry_mpih_mul( ctx->tspace, vp, vsize, up, usize );
+ }
+ else {
+ if( !ctx->next ) {
+ ctx->next = xcalloc( 1, sizeof *ctx );
+ }
+ _gcry_mpih_mul_karatsuba_case( ctx->tspace,
+ vp, vsize,
+ up, usize,
+ ctx->next );
+ }
+
+ cy = _gcry_mpih_add_n( prodp, prodp, ctx->tspace, vsize);
+ _gcry_mpih_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy );
+ }
+}
+
+
+void
+_gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx )
+{
+ struct karatsuba_ctx *ctx2;
+
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ for( ctx=ctx->next; ctx; ctx = ctx2 ) {
+ ctx2 = ctx->next;
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ xfree( ctx );
+ }
+}
+
+/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
+ * and v (pointed to by VP, with VSIZE limbs), and store the result at
+ * PRODP. USIZE + VSIZE limbs are always stored, but if the input
+ * operands are normalized. Return the most significant limb of the
+ * result.
+ *
+ * NOTE: The space pointed to by PRODP is overwritten before finished
+ * with U and V, so overlap is an error.
+ *
+ * Argument constraints:
+ * 1. USIZE >= VSIZE.
+ * 2. PRODP != UP and PRODP != VP, i.e. the destination
+ * must be distinct from the multiplier and the multiplicand.
+ */
+
+mpi_limb_t
+_gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize)
+{
+ mpi_ptr_t prod_endp = prodp + usize + vsize - 1;
+ mpi_limb_t cy;
+ struct karatsuba_ctx ctx;
+
+ if( vsize < KARATSUBA_THRESHOLD ) {
+ mpi_size_t i;
+ mpi_limb_t v_limb;
+
+ if( !vsize )
+ return 0;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, usize );
+ else
+ MPN_ZERO( prodp, usize );
+ cy = 0;
+ }
+ else
+ cy = _gcry_mpih_mul_1( prodp, up, usize, v_limb );
+
+ prodp[usize] = cy;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i = 1; i < vsize; i++ ) {
+ v_limb = vp[i];
+ if( v_limb <= 1 ) {
+ cy = 0;
+ if( v_limb == 1 )
+ cy = _gcry_mpih_add_n(prodp, prodp, up, usize);
+ }
+ else
+ cy = _gcry_mpih_addmul_1(prodp, up, usize, v_limb);
+
+ prodp[usize] = cy;
+ prodp++;
+ }
+
+ return cy;
+ }
+
+ memset( &ctx, 0, sizeof ctx );
+ _gcry_mpih_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx );
+ _gcry_mpih_release_karatsuba_ctx( &ctx );
+ return *prod_endp;
+}
diff --git a/comm/third_party/libgcrypt/mpi/mpiutil.c b/comm/third_party/libgcrypt/mpi/mpiutil.c
new file mode 100644
index 0000000000..86b8361e6c
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/mpiutil.c
@@ -0,0 +1,780 @@
+/* mpiutil.ac - Utility functions for MPI
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ * 2007 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi-internal.h"
+#include "mod-source-info.h"
+
+
+#if SIZEOF_UNSIGNED_INT == 2
+# define MY_UINT_MAX 0xffff
+/* (visual check: 0123 ) */
+#elif SIZEOF_UNSIGNED_INT == 4
+# define MY_UINT_MAX 0xffffffff
+/* (visual check: 01234567 ) */
+#elif SIZEOF_UNSIGNED_INT == 8
+# define MY_UINT_MAX 0xffffffffffffffff
+/* (visual check: 0123456789abcdef ) */
+#else
+# error Need MY_UINT_MAX for this limb size
+#endif
+
+
+/* Constants allocated right away at startup. */
+static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
+
+
+
+const char *
+_gcry_mpi_get_hw_config (void)
+{
+ return mod_source_info + 1;
+}
+
+
+/* Initialize the MPI subsystem. This is called early and allows to
+ do some initialization without taking care of threading issues. */
+gcry_err_code_t
+_gcry_mpi_init (void)
+{
+ int idx;
+ unsigned long value;
+
+ for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
+ {
+ switch (idx)
+ {
+ case MPI_C_ZERO: value = 0; break;
+ case MPI_C_ONE: value = 1; break;
+ case MPI_C_TWO: value = 2; break;
+ case MPI_C_THREE: value = 3; break;
+ case MPI_C_FOUR: value = 4; break;
+ case MPI_C_EIGHT: value = 8; break;
+ default: log_bug ("invalid mpi_const selector %d\n", idx);
+ }
+ constants[idx] = mpi_alloc_set_ui (value);
+ constants[idx]->flags = (16|32);
+ }
+
+ return 0;
+}
+
+
+/****************
+ * Note: It was a bad idea to use the number of limbs to allocate
+ * because on a alpha the limbs are large but we normally need
+ * integers of n bits - So we should change this to bits (or bytes).
+ *
+ * But mpi_alloc is used in a lot of places :-(. New code
+ * should use mpi_new.
+ */
+gcry_mpi_t
+_gcry_mpi_alloc( unsigned nlimbs )
+{
+ gcry_mpi_t a;
+
+ a = xmalloc( sizeof *a );
+ a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
+ a->alloced = nlimbs;
+ a->nlimbs = 0;
+ a->sign = 0;
+ a->flags = 0;
+ return a;
+}
+
+void
+_gcry_mpi_m_check( gcry_mpi_t a )
+{
+ _gcry_check_heap(a);
+ _gcry_check_heap(a->d);
+}
+
+gcry_mpi_t
+_gcry_mpi_alloc_secure( unsigned nlimbs )
+{
+ gcry_mpi_t a;
+
+ a = xmalloc( sizeof *a );
+ a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
+ a->alloced = nlimbs;
+ a->flags = 1;
+ a->nlimbs = 0;
+ a->sign = 0;
+ return a;
+}
+
+
+
+mpi_ptr_t
+_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
+{
+ mpi_ptr_t p;
+ size_t len;
+
+ len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
+ p = secure ? xmalloc_secure (len) : xmalloc (len);
+ if (! nlimbs)
+ *p = 0;
+
+ return p;
+}
+
+void
+_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
+{
+ if (a)
+ {
+ size_t len = nlimbs * sizeof(mpi_limb_t);
+
+ /* If we have information on the number of allocated limbs, we
+ better wipe that space out. This is a failsafe feature if
+ secure memory has been disabled or was not properly
+ implemented in user provided allocation functions. */
+ if (len)
+ wipememory (a, len);
+ xfree(a);
+ }
+}
+
+
+void
+_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
+{
+ _gcry_mpi_free_limb_space (a->d, a->alloced);
+ a->d = ap;
+ a->alloced = nlimbs;
+}
+
+
+
+/****************
+ * Resize the array of A to NLIMBS. The additional space is cleared
+ * (set to 0).
+ */
+void
+_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
+{
+ size_t i;
+
+ if (nlimbs <= a->alloced)
+ {
+ /* We only need to clear the new space (this is a nop if the
+ limb space is already of the correct size. */
+ for (i=a->nlimbs; i < a->alloced; i++)
+ a->d[i] = 0;
+ return;
+ }
+
+ /* Actually resize the limb space. */
+ if (a->d)
+ {
+ a->d = xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
+ for (i=a->alloced; i < nlimbs; i++)
+ a->d[i] = 0;
+ }
+ else
+ {
+ if (a->flags & 1)
+ /* Secure memory is wanted. */
+ a->d = xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
+ else
+ /* Standard memory. */
+ a->d = xcalloc (nlimbs , sizeof (mpi_limb_t));
+ }
+ a->alloced = nlimbs;
+}
+
+void
+_gcry_mpi_clear( gcry_mpi_t a )
+{
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+ a->nlimbs = 0;
+ a->flags = 0;
+}
+
+
+void
+_gcry_mpi_free( gcry_mpi_t a )
+{
+ if (!a )
+ return;
+ if ((a->flags & 32))
+ {
+#if GPGRT_VERSION_NUMBER >= 0x011600 /* 1.22 */
+ gpgrt_annotate_leaked_object(a);
+#endif
+ return; /* Never release a constant. */
+ }
+ if ((a->flags & 4))
+ xfree( a->d );
+ else
+ {
+ _gcry_mpi_free_limb_space(a->d, a->alloced);
+ }
+ /* Check that the flags makes sense. We better allow for bit 1
+ (value 2) for backward ABI compatibility. */
+ if ((a->flags & ~(1|2|4|16
+ |GCRYMPI_FLAG_USER1
+ |GCRYMPI_FLAG_USER2
+ |GCRYMPI_FLAG_USER3
+ |GCRYMPI_FLAG_USER4)))
+ log_bug("invalid flag value in mpi_free\n");
+ xfree (a);
+}
+
+
+void
+_gcry_mpi_immutable_failed (void)
+{
+ log_info ("Warning: trying to change an immutable MPI\n");
+}
+
+
+static void
+mpi_set_secure( gcry_mpi_t a )
+{
+ mpi_ptr_t ap, bp;
+
+ if ( (a->flags & 1) )
+ return;
+ a->flags |= 1;
+ ap = a->d;
+ if (!a->nlimbs)
+ {
+ gcry_assert (!ap);
+ return;
+ }
+ bp = mpi_alloc_limb_space (a->alloced, 1);
+ MPN_COPY( bp, ap, a->nlimbs );
+ a->d = bp;
+ _gcry_mpi_free_limb_space (ap, a->alloced);
+}
+
+
+gcry_mpi_t
+_gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
+{
+ if (!a)
+ a = mpi_alloc(0);
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return a;
+ }
+
+ if( a->flags & 4 )
+ xfree (a->d);
+ else
+ _gcry_mpi_free_limb_space (a->d, a->alloced);
+
+ a->d = p;
+ a->alloced = 0;
+ a->nlimbs = 0;
+ a->sign = nbits;
+ a->flags = 4 | (a->flags & (GCRYMPI_FLAG_USER1|GCRYMPI_FLAG_USER2
+ |GCRYMPI_FLAG_USER3|GCRYMPI_FLAG_USER4));
+ if (_gcry_is_secure (a->d))
+ a->flags |= 1;
+ return a;
+}
+
+
+gcry_mpi_t
+_gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
+{
+ void *d;
+ unsigned int n;
+
+ n = (nbits+7)/8;
+ d = _gcry_is_secure (p)? xtrymalloc_secure (n) : xtrymalloc (n);
+ if (!d)
+ return NULL;
+ memcpy (d, p, n);
+ return mpi_set_opaque (a, d, nbits);
+}
+
+
+void *
+_gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
+{
+ if( !(a->flags & 4) )
+ log_bug("mpi_get_opaque on normal mpi\n");
+ if( nbits )
+ *nbits = a->sign;
+ return a->d;
+}
+
+
+void *
+_gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits)
+{
+ const void *s;
+ void *d;
+ unsigned int n;
+
+ s = mpi_get_opaque (a, nbits);
+ if (!s && nbits)
+ return NULL;
+ n = (*nbits+7)/8;
+ d = _gcry_is_secure (s)? xtrymalloc_secure (n) : xtrymalloc (n);
+ if (d)
+ memcpy (d, s, n);
+ return d;
+}
+
+/****************
+ * Note: This copy function should not interpret the MPI
+ * but copy it transparently.
+ */
+gcry_mpi_t
+_gcry_mpi_copy (gcry_mpi_t a)
+{
+ int i;
+ gcry_mpi_t b;
+
+ if( a && (a->flags & 4) ) {
+ void *p = _gcry_is_secure(a->d)? xmalloc_secure ((a->sign+7)/8)
+ : xmalloc ((a->sign+7)/8);
+ if (a->d)
+ memcpy( p, a->d, (a->sign+7)/8 );
+ b = mpi_set_opaque( NULL, p, a->sign );
+ b->flags = a->flags;
+ b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
+ }
+ else if( a ) {
+ b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
+ : mpi_alloc( a->nlimbs );
+ b->nlimbs = a->nlimbs;
+ b->sign = a->sign;
+ b->flags = a->flags;
+ b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
+ for(i=0; i < b->nlimbs; i++ )
+ b->d[i] = a->d[i];
+ }
+ else
+ b = NULL;
+ return b;
+}
+
+
+/* Return true if A is negative. */
+int
+_gcry_mpi_is_neg (gcry_mpi_t a)
+{
+ if (a->sign && _gcry_mpi_cmp_ui (a, 0))
+ return 1;
+ else
+ return 0;
+}
+
+
+/* W = - U */
+void
+_gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
+{
+ if (w != u)
+ mpi_set (w, u);
+ else if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ w->sign = !u->sign;
+}
+
+
+/* W = [W] */
+void
+_gcry_mpi_abs (gcry_mpi_t w)
+{
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ w->sign = 0;
+}
+
+
+/****************
+ * This function allocates an MPI which is optimized to hold
+ * a value as large as the one given in the argument and allocates it
+ * with the same flags as A.
+ */
+gcry_mpi_t
+_gcry_mpi_alloc_like( gcry_mpi_t a )
+{
+ gcry_mpi_t b;
+
+ if( a && (a->flags & 4) ) {
+ int n = (a->sign+7)/8;
+ void *p = _gcry_is_secure(a->d)? xtrymalloc_secure (n)
+ : xtrymalloc (n);
+ memcpy( p, a->d, n );
+ b = mpi_set_opaque( NULL, p, a->sign );
+ }
+ else if( a ) {
+ b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
+ : mpi_alloc( a->nlimbs );
+ b->nlimbs = 0;
+ b->sign = 0;
+ b->flags = a->flags;
+ }
+ else
+ b = NULL;
+ return b;
+}
+
+
+/* Set U into W and release U. If W is NULL only U will be released. */
+void
+_gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
+{
+ if (w)
+ {
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+ _gcry_mpi_assign_limb_space (w, u->d, u->alloced);
+ w->nlimbs = u->nlimbs;
+ w->sign = u->sign;
+ w->flags = u->flags;
+ u->alloced = 0;
+ u->nlimbs = 0;
+ u->d = NULL;
+ }
+ _gcry_mpi_free (u);
+}
+
+
+gcry_mpi_t
+_gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u)
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize = u->nlimbs;
+ int usign = u->sign;
+
+ if (!w)
+ w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return w;
+ }
+ RESIZE_IF_NEEDED(w, usize);
+ wp = w->d;
+ up = u->d;
+ MPN_COPY( wp, up, usize );
+ w->nlimbs = usize;
+ w->flags = u->flags;
+ w->flags &= ~(16|32); /* Reset the immutable and constant flags. */
+ w->sign = usign;
+ return w;
+}
+
+/****************
+ * Set the value of W by the one of U, when SET is 1.
+ * Leave the value when SET is 0.
+ * This implementation should be constant-time regardless of SET.
+ */
+gcry_mpi_t
+_gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, unsigned long set)
+{
+ mpi_size_t i;
+ mpi_size_t nlimbs = u->alloced;
+ mpi_limb_t mask = ((mpi_limb_t)0) - set;
+ mpi_limb_t x;
+
+ if (w->alloced != u->alloced)
+ log_bug ("mpi_set_cond: different sizes\n");
+
+ for (i = 0; i < nlimbs; i++)
+ {
+ x = mask & (w->d[i] ^ u->d[i]);
+ w->d[i] = w->d[i] ^ x;
+ }
+
+ x = mask & (w->nlimbs ^ u->nlimbs);
+ w->nlimbs = w->nlimbs ^ x;
+
+ x = mask & (w->sign ^ u->sign);
+ w->sign = w->sign ^ x;
+ return w;
+}
+
+
+gcry_mpi_t
+_gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
+{
+ if (!w)
+ w = _gcry_mpi_alloc (1);
+ /* FIXME: If U is 0 we have no need to resize and thus possible
+ allocating the the limbs. */
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return w;
+ }
+ RESIZE_IF_NEEDED(w, 1);
+ w->d[0] = u;
+ w->nlimbs = u? 1:0;
+ w->sign = 0;
+ w->flags = 0;
+ return w;
+}
+
+/* If U is non-negative and small enough store it as an unsigned int
+ * at W. If the value does not fit into an unsigned int or is
+ * negative return GPG_ERR_ERANGE. Note that we return an unsigned
+ * int so that the value can be used with the bit test functions; in
+ * contrast the other _ui functions take an unsigned long so that on
+ * some platforms they may accept a larger value. On error the value
+ * at W is not changed. */
+gcry_err_code_t
+_gcry_mpi_get_ui (unsigned int *w, gcry_mpi_t u)
+{
+ mpi_limb_t x;
+
+ if (u->nlimbs > 1 || u->sign)
+ return GPG_ERR_ERANGE;
+
+ x = (u->nlimbs == 1) ? u->d[0] : 0;
+ if (sizeof (x) > sizeof (unsigned int) && x > MY_UINT_MAX)
+ return GPG_ERR_ERANGE;
+
+ *w = x;
+ return 0;
+}
+
+
+gcry_mpi_t
+_gcry_mpi_alloc_set_ui( unsigned long u)
+{
+ gcry_mpi_t w = mpi_alloc(1);
+ w->d[0] = u;
+ w->nlimbs = u? 1:0;
+ w->sign = 0;
+ return w;
+}
+
+void
+_gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
+{
+ struct gcry_mpi tmp;
+
+ tmp = *a; *a = *b; *b = tmp;
+}
+
+
+/****************
+ * Swap the value of A and B, when SWAP is 1.
+ * Leave the value when SWAP is 0.
+ * This implementation should be constant-time regardless of SWAP.
+ */
+void
+_gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
+{
+ mpi_size_t i;
+ mpi_size_t nlimbs;
+ mpi_limb_t mask = ((mpi_limb_t)0) - swap;
+ mpi_limb_t x;
+
+ if (a->alloced > b->alloced)
+ nlimbs = b->alloced;
+ else
+ nlimbs = a->alloced;
+ if (a->nlimbs > nlimbs || b->nlimbs > nlimbs)
+ log_bug ("mpi_swap_cond: different sizes\n");
+
+ for (i = 0; i < nlimbs; i++)
+ {
+ x = mask & (a->d[i] ^ b->d[i]);
+ a->d[i] = a->d[i] ^ x;
+ b->d[i] = b->d[i] ^ x;
+ }
+
+ x = mask & (a->nlimbs ^ b->nlimbs);
+ a->nlimbs = a->nlimbs ^ x;
+ b->nlimbs = b->nlimbs ^ x;
+
+ x = mask & (a->sign ^ b->sign);
+ a->sign = a->sign ^ x;
+ b->sign = b->sign ^ x;
+}
+
+
+/****************
+ * Set bit N of A, when SET is 1.
+ * This implementation should be constant-time regardless of SET.
+ */
+void
+_gcry_mpi_set_bit_cond (gcry_mpi_t a, unsigned int n, unsigned long set)
+{
+ unsigned int limbno, bitno;
+ mpi_limb_t set_the_bit = !!set;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ a->d[limbno] |= (set_the_bit<<bitno);
+}
+
+
+gcry_mpi_t
+_gcry_mpi_new (unsigned int nbits)
+{
+ return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
+ / BITS_PER_MPI_LIMB );
+}
+
+
+gcry_mpi_t
+_gcry_mpi_snew (unsigned int nbits)
+{
+ return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
+ / BITS_PER_MPI_LIMB );
+}
+
+void
+_gcry_mpi_release( gcry_mpi_t a )
+{
+ _gcry_mpi_free( a );
+}
+
+void
+_gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level)
+{
+ unsigned char *p;
+ size_t nbytes = (nbits+7)/8;
+
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+ if (level == GCRY_WEAK_RANDOM)
+ {
+ p = mpi_is_secure(w) ? xmalloc_secure (nbytes)
+ : xmalloc (nbytes);
+ _gcry_create_nonce (p, nbytes);
+ }
+ else
+ {
+ p = mpi_is_secure(w) ? _gcry_random_bytes_secure (nbytes, level)
+ : _gcry_random_bytes (nbytes, level);
+ }
+ _gcry_mpi_set_buffer( w, p, nbytes, 0 );
+ xfree (p);
+}
+
+
+void
+_gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
+ case GCRYMPI_FLAG_CONST: a->flags |= (16|32); break;
+ case GCRYMPI_FLAG_IMMUTABLE: a->flags |= 16; break;
+
+ case GCRYMPI_FLAG_USER1:
+ case GCRYMPI_FLAG_USER2:
+ case GCRYMPI_FLAG_USER3:
+ case GCRYMPI_FLAG_USER4: a->flags |= flag; break;
+
+ case GCRYMPI_FLAG_OPAQUE:
+ default: log_bug("invalid flag value\n");
+ }
+}
+
+void
+_gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ (void)a; /* Not yet used. */
+
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_IMMUTABLE:
+ if (!(a->flags & 32))
+ a->flags &= ~16;
+ break;
+
+ case GCRYMPI_FLAG_USER1:
+ case GCRYMPI_FLAG_USER2:
+ case GCRYMPI_FLAG_USER3:
+ case GCRYMPI_FLAG_USER4:
+ a->flags &= ~flag;
+ break;
+
+ case GCRYMPI_FLAG_CONST:
+ case GCRYMPI_FLAG_SECURE:
+ case GCRYMPI_FLAG_OPAQUE:
+ default: log_bug("invalid flag value\n");
+ }
+}
+
+int
+_gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_SECURE: return !!(a->flags & 1);
+ case GCRYMPI_FLAG_OPAQUE: return !!(a->flags & 4);
+ case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
+ case GCRYMPI_FLAG_CONST: return !!(a->flags & 32);
+ case GCRYMPI_FLAG_USER1:
+ case GCRYMPI_FLAG_USER2:
+ case GCRYMPI_FLAG_USER3:
+ case GCRYMPI_FLAG_USER4: return !!(a->flags & flag);
+ default: log_bug("invalid flag value\n");
+ }
+ /*NOTREACHED*/
+ return 0;
+}
+
+
+/* Return a constant MPI descripbed by NO which is one of the
+ MPI_C_xxx macros. There is no need to copy this returned value; it
+ may be used directly. */
+gcry_mpi_t
+_gcry_mpi_const (enum gcry_mpi_constants no)
+{
+ if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
+ log_bug("invalid mpi_const selector %d\n", no);
+ if (!constants[no])
+ log_bug("MPI subsystem not initialized\n");
+ return constants[no];
+}
diff --git a/comm/third_party/libgcrypt/mpi/pa7100/distfiles b/comm/third_party/libgcrypt/mpi/pa7100/distfiles
new file mode 100644
index 0000000000..fece94310d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pa7100/distfiles
@@ -0,0 +1,3 @@
+mpih-lshift.S
+mpih-rshift.S
+
diff --git a/comm/third_party/libgcrypt/mpi/pa7100/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/pa7100/mpih-lshift.S
new file mode 100644
index 0000000000..8ade19643e
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pa7100/mpih-lshift.S
@@ -0,0 +1,96 @@
+/* hppa lshift
+ * optimized for the PA7100, where it runs at 3.25 cycles/limb
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_lshift
+ .label _gcry_mpih_lshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(0,%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L$0004
+ vshd %r0,%r22,%r28 ; compute carry out limb
+ ldws,mb -4(0,%r25),%r29
+ addib,<= -5,%r24,L$rest
+ vshd %r22,%r29,%r20
+
+ .label L$loop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,> -4,%r24,L$loop
+ vshd %r22,%r29,%r20
+
+ .label L$rest
+ addib,= 4,%r24,L$end1
+ nop
+ .label L$eloop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ addib,<= -1,%r24,L$end2
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,> -1,%r24,L$eloop
+ vshd %r22,%r29,%r20
+
+ .label L$end1
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+ .label L$end2
+ stws,mb %r20,-4(0,%r26)
+ .label L$0004
+ vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+
+ .exit
+ .procend
+
+
+
diff --git a/comm/third_party/libgcrypt/mpi/pa7100/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/pa7100/mpih-rshift.S
new file mode 100644
index 0000000000..0624202725
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pa7100/mpih-rshift.S
@@ -0,0 +1,92 @@
+/* hppa rshift
+ * optimized for the PA7100, where it runs at 3.25 cycles/limb
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 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
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_rshift
+ .label _gcry_mpih_rshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L$r004
+ vshd %r22,%r0,%r28 ; compute carry out limb
+ ldws,ma 4(0,%r25),%r29
+ addib,<= -5,%r24,L$rrest
+ vshd %r29,%r22,%r20
+
+ .label L$roop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,> -4,%r24,L$roop
+ vshd %r29,%r22,%r20
+
+ .label L$rrest
+ addib,= 4,%r24,L$rend1
+ nop
+ .label L$eroop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ addib,<= -1,%r24,L$rend2
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,> -1,%r24,L$eroop
+ vshd %r29,%r22,%r20
+
+ .label L$rend1
+ stws,ma %r20,4(0,%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+ .label L$rend2
+ stws,ma %r20,4(0,%r26)
+ .label L$r004
+ vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+
+ .exit
+ .procend
+
+
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/README b/comm/third_party/libgcrypt/mpi/pentium4/README
new file mode 100644
index 0000000000..215fc7f8bf
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/README
@@ -0,0 +1,115 @@
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library 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.
+
+The GNU MP Library 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 the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+
+
+
+ INTEL PENTIUM-4 MPN SUBROUTINES
+
+
+This directory contains mpn functions optimized for Intel Pentium-4.
+
+The mmx subdirectory has routines using MMX instructions, the sse2
+subdirectory has routines using SSE2 instructions. All P4s have these, the
+separate directories are just so configure can omit that code if the
+assembler doesn't support it.
+
+
+STATUS
+
+ cycles/limb
+
+ mpn_add_n/sub_n 4 normal, 6 in-place
+
+ mpn_mul_1 4 normal, 6 in-place
+ mpn_addmul_1 6
+ mpn_submul_1 7
+
+ mpn_mul_basecase 6 cycles/crossproduct (approx)
+
+ mpn_sqr_basecase 3.5 cycles/crossproduct (approx)
+ or 7.0 cycles/triangleproduct (approx)
+
+ mpn_l/rshift 1.75
+
+
+
+The shifts ought to be able to go at 1.5 c/l, but not much effort has been
+applied to them yet.
+
+In-place operations, and all addmul, submul, mul_basecase and sqr_basecase
+calls, suffer from pipeline anomalies associated with write combining and
+movd reads and writes to the same or nearby locations. The movq
+instructions do not trigger the same hardware problems. Unfortunately,
+using movq and splitting/combining seems to require too many extra
+instructions to help. Perhaps future chip steppings will be better.
+
+
+
+NOTES
+
+The Pentium-4 pipeline "Netburst", provides for quite a number of surprises.
+Many traditional x86 instructions run very slowly, requiring use of
+alterative instructions for acceptable performance.
+
+adcl and sbbl are quite slow at 8 cycles for reg->reg. paddq of 32-bits
+within a 64-bit mmx register seems better, though the combination
+paddq/psrlq when propagating a carry is still a 4 cycle latency.
+
+incl and decl should be avoided, instead use add $1 and sub $1. Apparently
+the carry flag is not separately renamed, so incl and decl depend on all
+previous flags-setting instructions.
+
+shll and shrl have a 4 cycle latency, or 8 times the latency of the fastest
+integer instructions (addl, subl, orl, andl, and some more). shldl and
+shrdl seem to have 13 and 15 cycles latency, respectively. Bizarre.
+
+movq mmx -> mmx does have 6 cycle latency, as noted in the documentation.
+pxor/por or similar combination at 2 cycles latency can be used instead.
+The movq however executes in the float unit, thereby saving MMX execution
+resources. With the right juggling, data moves shouldn't be on a dependent
+chain.
+
+L1 is write-through, but the write-combining sounds like it does enough to
+not require explicit destination prefetching.
+
+xmm registers so far haven't found a use, but not much effort has been
+expended. A configure test for whether the operating system knows
+fxsave/fxrestor will be needed if they're used.
+
+
+
+REFERENCES
+
+Intel Pentium-4 processor manuals,
+
+ http://developer.intel.com/design/pentium4/manuals
+
+"Intel Pentium 4 Processor Optimization Reference Manual", Intel, 2001,
+order number 248966. Available on-line:
+
+ http://developer.intel.com/design/pentium4/manuals/248966.htm
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/distfiles b/comm/third_party/libgcrypt/mpi/pentium4/distfiles
new file mode 100644
index 0000000000..b419f85a9a
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/distfiles
@@ -0,0 +1,3 @@
+README
+
+
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/mmx/distfiles b/comm/third_party/libgcrypt/mpi/pentium4/mmx/distfiles
new file mode 100644
index 0000000000..8f0ea426db
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/mmx/distfiles
@@ -0,0 +1,2 @@
+mpih-lshift.S
+mpih-rshift.S
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S
new file mode 100644
index 0000000000..e2dd184ba3
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S
@@ -0,0 +1,457 @@
+/* Intel Pentium-4 mpn_lshift -- left shift.
+ *
+ * Copyright 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 1.75 cycles/limb
+ * P4 Prescott: 2.0 cycles/limb
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+
+
+ pushl %ebx
+ pushl %edi
+
+
+ movl 20(%esp), %eax
+ movl 12(%esp), %edx
+
+ movl 16(%esp), %ebx
+ movl 24(%esp), %ecx
+
+ cmp $5, %eax
+ jae .Lunroll
+
+ movl -4(%ebx,%eax,4), %edi
+ decl %eax
+
+ jnz .Lsimple
+
+ shldl %cl, %edi, %eax
+
+ shll %cl, %edi
+
+ movl %edi, (%edx)
+ popl %edi
+
+ popl %ebx
+
+ ret
+
+
+
+
+
+.Lsimple:
+
+
+
+
+
+
+
+
+
+ movd (%ebx,%eax,4), %mm5
+
+ movd %ecx, %mm6
+ negl %ecx
+
+ psllq %mm6, %mm5
+ addl $32, %ecx
+
+ movd %ecx, %mm7
+ psrlq $32, %mm5
+
+
+.Lsimple_top:
+
+
+
+
+
+
+
+
+
+
+
+
+ movq -4(%ebx,%eax,4), %mm0
+ decl %eax
+
+ psrlq %mm7, %mm0
+
+
+
+ movd %mm0, 4(%edx,%eax,4)
+ jnz .Lsimple_top
+
+
+ movd (%ebx), %mm0
+
+ movd %mm5, %eax
+ psllq %mm6, %mm0
+
+ popl %edi
+ popl %ebx
+
+ movd %mm0, (%edx)
+
+ emms
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll:
+
+
+
+
+
+
+
+
+
+ movd -4(%ebx,%eax,4), %mm5
+ leal (%ebx,%eax,4), %edi
+
+ movd %ecx, %mm6
+ andl $4, %edi
+
+ psllq %mm6, %mm5
+ jz .Lstart_src_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq -8(%ebx,%eax,4), %mm0
+
+ psllq %mm6, %mm0
+ decl %eax
+
+ psrlq $32, %mm0
+
+
+
+ movd %mm0, (%edx,%eax,4)
+.Lstart_src_aligned:
+
+ movq -8(%ebx,%eax,4), %mm1
+ leal (%edx,%eax,4), %edi
+
+ andl $4, %edi
+ psrlq $32, %mm5
+
+ movq -16(%ebx,%eax,4), %mm3
+ jz .Lstart_dst_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm1, %mm0
+ addl $32, %ecx
+
+ psllq %mm6, %mm0
+
+ movd %ecx, %mm6
+ psrlq $32, %mm0
+
+
+
+ movd %mm0, -4(%edx,%eax,4)
+ subl $4, %edx
+.Lstart_dst_aligned:
+
+
+ psllq %mm6, %mm1
+ negl %ecx
+
+ addl $64, %ecx
+ movq %mm3, %mm2
+
+ movd %ecx, %mm7
+ subl $8, %eax
+
+ psrlq %mm7, %mm3
+
+ por %mm1, %mm3
+ jc .Lfinish
+
+
+
+
+ .align 8, 0x90
+.Lunroll_loop:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq 8(%ebx,%eax,4), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ movq %mm3, 24(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq (%ebx,%eax,4), %mm3
+ psllq %mm6, %mm1
+
+ movq %mm0, 16(%edx,%eax,4)
+ movq %mm3, %mm2
+
+ psrlq %mm7, %mm3
+ subl $4, %eax
+
+ por %mm1, %mm3
+ jnc .Lunroll_loop
+
+
+
+.Lfinish:
+
+
+ testb $2, %al
+
+ jz .Lfinish_no_two
+
+ movq 8(%ebx,%eax,4), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ movq %mm3, 24(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq %mm1, %mm2
+ movq %mm0, %mm3
+
+ subl $2, %eax
+.Lfinish_no_two:
+
+
+
+
+
+
+
+ testb $1, %al
+ movd %mm5, %eax
+
+ popl %edi
+ jz .Lfinish_zero
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm3, 12(%edx)
+ psllq $32, %mm0
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ por %mm2, %mm0
+ psllq %mm6, %mm1
+
+ movq %mm0, 4(%edx)
+ psrlq $32, %mm1
+
+ andl $32, %ecx
+ popl %ebx
+
+ jz .Lfinish_one_unaligned
+
+ movd %mm1, (%edx)
+.Lfinish_one_unaligned:
+
+ emms
+
+ ret
+
+
+
+
+.Lfinish_zero:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm3, 8(%edx)
+ andl $32, %ecx
+
+ psllq %mm6, %mm2
+ jz .Lfinish_zero_unaligned
+
+ movq %mm2, (%edx)
+.Lfinish_zero_unaligned:
+
+ psrlq $32, %mm2
+ popl %ebx
+
+ movd %mm5, %eax
+
+ movd %mm2, 4(%edx)
+
+ emms
+
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S
new file mode 100644
index 0000000000..e3374e3ba3
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S
@@ -0,0 +1,453 @@
+/* Intel Pentium-4 mpn_rshift -- right shift.
+ *
+ * Copyright 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 1.75 cycles/limb
+ * P4 Prescott: 2.0 cycles/limb
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ pushl %ebx
+ pushl %edi
+
+
+ movl 20(%esp), %eax
+ movl 12(%esp), %edx
+
+ movl 16(%esp), %ebx
+ movl 24(%esp), %ecx
+
+ cmp $5, %eax
+ jae .Lunroll
+
+ decl %eax
+ movl (%ebx), %edi
+
+ jnz .Lsimple
+
+ shrdl %cl, %edi, %eax
+
+ shrl %cl, %edi
+
+ movl %edi, (%edx)
+ popl %edi
+
+ popl %ebx
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lsimple:
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm5
+ leal (%ebx,%eax,4), %ebx
+
+ movd %ecx, %mm6
+ leal -4(%edx,%eax,4), %edx
+
+ psllq $32, %mm5
+ negl %eax
+
+
+
+
+
+
+
+.Lsimple_top:
+
+
+
+
+
+
+
+
+
+ movq (%ebx,%eax,4), %mm0
+ incl %eax
+
+ psrlq %mm6, %mm0
+
+ movd %mm0, (%edx,%eax,4)
+ jnz .Lsimple_top
+
+
+ movd (%ebx), %mm0
+ psrlq %mm6, %mm5
+
+ psrlq %mm6, %mm0
+ popl %edi
+
+ movd %mm5, %eax
+ popl %ebx
+
+ movd %mm0, 4(%edx)
+
+ emms
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll:
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm5
+ movl $4, %edi
+
+ movd %ecx, %mm6
+ testl %edi, %ebx
+
+ psllq $32, %mm5
+ jz .Lstart_src_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq (%ebx), %mm0
+
+ psrlq %mm6, %mm0
+ addl $4, %ebx
+
+ decl %eax
+
+ movd %mm0, (%edx)
+ addl $4, %edx
+.Lstart_src_aligned:
+
+
+ movq (%ebx), %mm1
+ testl %edi, %edx
+
+ psrlq %mm6, %mm5
+ jz .Lstart_dst_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm1, %mm0
+ addl $32, %ecx
+
+ psrlq %mm6, %mm0
+
+ movd %ecx, %mm6
+
+ movd %mm0, (%edx)
+ addl $4, %edx
+.Lstart_dst_aligned:
+
+
+ movq 8(%ebx), %mm3
+ negl %ecx
+
+ movq %mm3, %mm2
+ addl $64, %ecx
+
+ movd %ecx, %mm7
+ psrlq %mm6, %mm1
+
+ leal -12(%ebx,%eax,4), %ebx
+ leal -20(%edx,%eax,4), %edx
+
+ psllq %mm7, %mm3
+ subl $7, %eax
+
+ por %mm1, %mm3
+ negl %eax
+
+ jns .Lfinish
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll_loop:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq (%ebx,%eax,4), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, -8(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq 8(%ebx,%eax,4), %mm3
+ psrlq %mm6, %mm1
+
+ movq %mm0, (%edx,%eax,4)
+ movq %mm3, %mm2
+
+ psllq %mm7, %mm3
+ addl $4, %eax
+
+ por %mm1, %mm3
+ js .Lunroll_loop
+
+
+.Lfinish:
+
+
+ testb $2, %al
+
+ jnz .Lfinish_no_two
+
+ movq (%ebx,%eax,4), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, -8(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq %mm1, %mm2
+ movq %mm0, %mm3
+
+ addl $2, %eax
+.Lfinish_no_two:
+
+
+
+
+
+
+
+ testb $1, %al
+ popl %edi
+
+ movd %mm5, %eax
+ jnz .Lfinish_zero
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movd 8(%ebx), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, (%edx)
+ por %mm2, %mm0
+
+ psrlq %mm6, %mm1
+ andl $32, %ecx
+
+ popl %ebx
+ jz .Lfinish_one_unaligned
+
+
+ movd %mm1, 16(%edx)
+.Lfinish_one_unaligned:
+
+ movq %mm0, 8(%edx)
+
+ emms
+
+ ret
+
+
+
+
+.Lfinish_zero:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm3, 4(%edx)
+ psrlq %mm6, %mm2
+
+ movd %mm2, 12(%edx)
+ andl $32, %ecx
+
+ popl %ebx
+ jz .Lfinish_zero_unaligned
+
+ movq %mm2, 12(%edx)
+.Lfinish_zero_unaligned:
+
+ emms
+
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/sse2/distfiles b/comm/third_party/libgcrypt/mpi/pentium4/sse2/distfiles
new file mode 100644
index 0000000000..7252cd7e3f
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/sse2/distfiles
@@ -0,0 +1,5 @@
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-sub1.S
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-add1.S b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-add1.S
new file mode 100644
index 0000000000..55ed663032
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-add1.S
@@ -0,0 +1,91 @@
+/* Intel Pentium-4 mpn_add_n -- mpn addition.
+ *
+ * Copyright 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+ /*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2
+ * 6.0 cycles/limb if dst==src1 or dst==src2
+ * P4 Prescott: >= 5 cycles/limb
+ *
+ * The 4 c/l achieved here isn't particularly good, but is better than 9 c/l
+ * for a basic adc loop.
+ */
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+
+ pxor %mm0, %mm0
+
+ movl 8(%esp), %eax /* s1_ptr */
+ movl %ebx, 8(%esp) /* re-use parameter space */
+ movl 12(%esp), %ebx /* res_ptr */
+ movl 4(%esp), %edx /* s2_ptr */
+ movl 16(%esp), %ecx /* size */
+
+ leal (%eax,%ecx,4), %eax /* src1 end */
+ leal (%ebx,%ecx,4), %ebx /* src2 end */
+ leal (%edx,%ecx,4), %edx /* dst end */
+ negl %ecx /* -size */
+
+Ltop:
+/*
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry bit
+*/
+
+ movd (%eax,%ecx,4), %mm1
+ movd (%ebx,%ecx,4), %mm2
+ paddq %mm2, %mm1
+
+ paddq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $32, %mm0
+
+ addl $1, %ecx
+ jnz Ltop
+
+
+ movd %mm0, %eax
+ movl 8(%esp), %ebx /* restore saved EBX */
+ emms
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S
new file mode 100644
index 0000000000..a0c98fb4dd
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S
@@ -0,0 +1,96 @@
+/* Intel Pentium-4 mpn_mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright 2001, 2002, 2003, 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * src != dst src == dst
+ * P6 model 9 (Banias) ?.?
+ * P6 model 13 (Dothan) 4.75 4.75
+ * P4 model 0 (Willamette) 4.0 6.0
+ * P4 model 1 (?) 4.0 6.0
+ * P4 model 2 (Northwood) 4.0 6.0
+ * P4 model 3 (Prescott) ?.? ?.?
+ * P4 model 4 (Nocona) ?.? ?.?
+ * Unfortunately when src==dst the write-combining described in
+ * pentium4/README takes us up to 6 c/l.
+ *
+ */
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:);
+
+ pxor %mm0, %mm0
+
+.Lstart_1c:
+ movl 8(%esp), %eax
+ movd 16(%esp), %mm7
+ movl 4(%esp), %edx
+ movl 12(%esp), %ecx
+
+.Ltop:
+
+/*
+ C eax src, incrementing
+ C ebx
+ C ecx counter, size iterations
+ C edx dst, incrementing
+ C
+ C mm0 carry limb
+ C mm7 multiplier
+*/
+
+ movd (%eax), %mm1
+ addl $4, %eax
+ pmuludq %mm7, %mm1
+
+ paddq %mm1, %mm0
+ movd %mm0, (%edx)
+ addl $4, %edx
+
+ psrlq $32, %mm0
+
+ subl $1, %ecx
+ jnz .Ltop
+
+
+ movd %mm0, %eax
+ emms
+ ret
+
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S
new file mode 100644
index 0000000000..f975adfca5
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S
@@ -0,0 +1,136 @@
+/* Intel Pentium-4 mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright 2001, 2002, 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * P3 model 9 (Banias) ?.?
+ * P3 model 13 (Dothan) 5.8
+ * P4 model 0 (Willamette) 5.5
+ * P4 model 1 (?) 5.5
+ * P4 model 2 (Northwood) 5.5
+ * P4 model 3 (Prescott) 6.0
+ * P4 model 4 (Nocona)
+ *
+ * Only the carry limb propagation is on the dependent chain, but some other
+ * Pentium4 pipeline magic brings down performance to 6 cycles/l from the
+ * ideal 4 cycles/l.
+ */
+
+
+ TEXT
+ ALIGN (4)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ pxor %mm4, %mm4
+.Lstart_1c:
+ movl 8(%esp), %eax
+ movl 12(%esp), %ecx
+ movl 4(%esp), %edx
+ movd 16(%esp), %mm7
+
+/*
+ C eax src, incrementing ; 5B
+ C ecx loop counter, decrementing
+ C edx dst, incrementing
+ C
+ C mm4 carry, low 32-bits
+ C mm7 multiplier
+*/
+
+ movd (%eax), %mm2
+ pmuludq %mm7, %mm2
+
+ shrl $1, %ecx
+ jnc .Leven
+
+ leal 4(%eax), %eax
+ movd (%edx), %mm1
+ paddq %mm2, %mm1
+ paddq %mm1, %mm4
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+
+ testl %ecx, %ecx
+ jz .Lrtn
+ leal 4(%edx), %edx
+
+ movd (%eax), %mm2
+ pmuludq %mm7, %mm2
+.Leven:
+ movd 4(%eax), %mm0
+ movd (%edx), %mm1
+ pmuludq %mm7, %mm0
+
+ subl $1, %ecx
+ jz .Lend
+.Lloop:
+ paddq %mm2, %mm1
+ movd 8(%eax), %mm2
+ paddq %mm1, %mm4
+ movd 4(%edx), %mm3
+ pmuludq %mm7, %mm2
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+
+ paddq %mm0, %mm3
+ movd 12(%eax), %mm0
+ paddq %mm3, %mm4
+ movd 8(%edx), %mm1
+ pmuludq %mm7, %mm0
+ movd %mm4, 4(%edx)
+ psrlq $32, %mm4
+
+ leal 8(%eax), %eax
+ leal 8(%edx), %edx
+ subl $1, %ecx
+ jnz .Lloop
+.Lend:
+ paddq %mm2, %mm1
+ paddq %mm1, %mm4
+ movd 4(%edx), %mm3
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+ paddq %mm0, %mm3
+ paddq %mm3, %mm4
+ movd %mm4, 4(%edx)
+ psrlq $32, %mm4
+.Lrtn:
+ movd %mm4, %eax
+ emms
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S
new file mode 100644
index 0000000000..ebcd2a68ea
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S
@@ -0,0 +1,127 @@
+/* Intel Pentium-4 mpn_submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ *
+ * Copyright 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * P4: 7 cycles/limb, unstable timing, at least on early Pentium4 silicon
+ * (stepping 10).
+ *
+ * This code is not particularly good at 7 c/l. The dependent chain is only
+ * 4 c/l and there's only 4 MMX unit instructions, so it's not clear why that
+ * speed isn't achieved.
+ *
+ * The arrangements made here to get a two instruction dependent chain are
+ * slightly subtle. In the loop the carry (or borrow rather) is a negative
+ * so that a paddq can be used to give a low limb ready to store, and a high
+ * limb ready to become the new carry after a psrlq.
+ *
+ * If the carry was a simple twos complement negative then the psrlq shift
+ * would need to bring in 0 bits or 1 bits according to whether the high was
+ * zero or non-zero, since a non-zero value would represent a negative
+ * needing sign extension. That wouldn't be particularly easy to arrange and
+ * certainly would add an instruction to the dependent chain, so instead an
+ * offset is applied so that the high limb will be 0xFFFFFFFF+c. With c in
+ * the range -0xFFFFFFFF to 0, the value 0xFFFFFFFF+c is in the range 0 to
+ * 0xFFFFFFFF and is therefore always positive and can always have 0 bits
+ * shifted in, which is what psrlq does.
+ *
+ * The extra 0xFFFFFFFF must be subtracted before c is used, but that can be
+ * done off the dependent chain. The total adjustment then is to add
+ * 0xFFFFFFFF00000000 to offset the new carry, and subtract
+ * 0x00000000FFFFFFFF to remove the offset from the current carry, for a net
+ * add of 0xFFFFFFFE00000001. In the code this is applied to the destination
+ * limb when fetched.
+ *
+ * It's also possible to view the 0xFFFFFFFF adjustment as a ones-complement
+ * negative, which is how it's undone for the return value, but that doesn't
+ * seem as clear.
+*/
+
+ TEXT
+ ALIGN (4)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ pxor %mm1, %mm1
+
+.Lstart_1c:
+ movl 8(%esp), %eax
+ pcmpeqd %mm0, %mm0
+
+ movd 16(%esp), %mm7
+ pcmpeqd %mm6, %mm6
+
+ movl 4(%esp), %edx
+ psrlq $32, %mm0
+
+ movl 12(%esp), %ecx
+ psllq $32, %mm6
+
+ psubq %mm0, %mm6
+
+ psubq %mm1, %mm0
+
+/*
+ C eax src, incrementing
+ C ebx
+ C ecx loop counter, decrementing
+ C edx dst, incrementing
+ C
+ C mm0 0xFFFFFFFF - borrow
+ C mm6 0xFFFFFFFE00000001
+ C mm7 multiplier
+*/
+
+.Lloop:
+ movd (%eax), %mm1
+ leal 4(%eax), %eax
+ movd (%edx), %mm2
+ paddq %mm6, %mm2
+ pmuludq %mm7, %mm1
+ psubq %mm1, %mm2
+ paddq %mm2, %mm0
+ subl $1, %ecx
+ movd %mm0, (%edx)
+ psrlq $32, %mm0
+ leal 4(%edx), %edx
+ jnz .Lloop
+
+ movd %mm0, %eax
+ notl %eax
+ emms
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S
new file mode 100644
index 0000000000..33900c742e
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S
@@ -0,0 +1,112 @@
+/* Intel Pentium-4 mpn_sub_n -- mpn subtraction.
+ *
+ * Copyright 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2
+ * 6.0 cycles/limb if dst==src1 or dst==src2
+ * P4 Prescott: >= 5 cycles/limb
+ *
+ * The main loop code is 2x unrolled so that the carry bit can alternate
+ * between mm0 and mm1.
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+
+ pxor %mm0, %mm0
+.Lstart_nc:
+ movl 8(%esp), %eax
+ movl %ebx, 8(%esp)
+ movl 12(%esp), %ebx
+ movl 4(%esp), %edx
+ movl 16(%esp), %ecx
+
+ leal (%eax,%ecx,4), %eax
+ leal (%ebx,%ecx,4), %ebx
+ leal (%edx,%ecx,4), %edx
+ negl %ecx
+
+.Ltop:
+/*
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry bit
+*/
+
+ movd (%eax,%ecx,4), %mm1
+ movd (%ebx,%ecx,4), %mm2
+ psubq %mm2, %mm1
+
+ psubq %mm0, %mm1
+ movd %mm1, (%edx,%ecx,4)
+
+ psrlq $63, %mm1
+
+ addl $1, %ecx
+ jz .Ldone_mm1
+
+ movd (%eax,%ecx,4), %mm0
+ movd (%ebx,%ecx,4), %mm2
+ psubq %mm2, %mm0
+
+ psubq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $63, %mm0
+
+ addl $1, %ecx
+ jnz .Ltop
+
+
+ movd %mm0, %eax
+ movl 8(%esp), %ebx
+ emms
+ ret
+
+
+
+.Ldone_mm1:
+ movd %mm1, %eax
+ movl 8(%esp), %ebx
+ emms
+ ret
diff --git a/comm/third_party/libgcrypt/mpi/power/distfiles b/comm/third_party/libgcrypt/mpi/power/distfiles
new file mode 100644
index 0000000000..e664c8db6a
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/power/distfiles
@@ -0,0 +1,7 @@
+mpih-add1.S
+mpih-lshift.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-rshift.S
+mpih-sub1.S
diff --git a/comm/third_party/libgcrypt/mpi/power/mpih-add1.S b/comm/third_party/libgcrypt/mpi/power/mpih-add1.S
new file mode 100644
index 0000000000..876b56c664
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/power/mpih-add1.S
@@ -0,0 +1,87 @@
+/* IBM POWER add_n -- Add two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1999,
+ * 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# s2_ptr r5
+# size r6
+ */
+
+ .toc
+ .extern _gcry_mpih_add_n[DS]
+ .extern ._gcry_mpih_add_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_add_n
+ .globl ._gcry_mpih_add_n
+ .csect _gcry_mpih_add_n[DS]
+_gcry_mpih_add_n:
+ .long ._gcry_mpih_add_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_add_n:
+ andil. 10,6,1 # odd or even number of limbs?
+ l 8,0(4) # load least significant s1 limb
+ l 0,0(5) # load least significant s2 limb
+ cal 3,-4(3) # offset res_ptr, it's updated before it's used
+ sri 10,6,1 # count for unrolled loop
+ a 7,0,8 # add least significant limbs, set cy
+ mtctr 10 # copy count into CTR
+ beq 0,Leven # branch if even # of limbs (# of limbs >= 2)
+
+# We have an odd # of limbs. Add the first limbs separately.
+ cmpi 1,10,0 # is count for unrolled loop zero?
+ bne 1,L1 # branch if not
+ st 7,4(3)
+ aze 3,10 # use the fact that r10 is zero...
+ br # return
+
+# We added least significant limbs. Now reload the next limbs to enter loop.
+L1: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ stu 7,4(3)
+ ae 7,0,8 # add limbs, set cy
+Leven: lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ bdz Lend # If done, skip loop
+
+Loop: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ ae 11,9,10 # add previous limbs with cy, set cy
+ stu 7,4(3) #
+ lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ ae 7,0,8 # add previous limbs with cy, set cy
+ stu 11,4(3) #
+ bdn Loop # decrement CTR and loop back
+
+Lend: ae 11,9,10 # add limbs with cy, set cy
+ st 7,4(3) #
+ st 11,8(3) #
+ lil 3,0 # load cy into ...
+ aze 3,3 # ... return value register
+ br
+
diff --git a/comm/third_party/libgcrypt/mpi/power/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/power/mpih-lshift.S
new file mode 100644
index 0000000000..d9e42daf81
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/power/mpih-lshift.S
@@ -0,0 +1,64 @@
+/* IBM POWER lshift
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s_ptr r4
+# size r5
+# cnt r6
+ */
+
+ .toc
+ .extern _gcry_mpih_lshift[DS]
+ .extern ._gcry_mpih_lshift
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_lshift
+ .globl ._gcry_mpih_lshift
+ .csect _gcry_mpih_lshift[DS]
+_gcry_mpih_lshift:
+ .long ._gcry_mpih_lshift, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_lshift:
+ sli 0,5,2
+ cax 9,3,0
+ cax 4,4,0
+ sfi 8,6,32
+ mtctr 5 # put limb count in CTR loop register
+ lu 0,-4(4) # read most significant limb
+ sre 3,0,8 # compute carry out limb, and init MQ register
+ bdz Lend2 # if just one limb, skip loop
+ lu 0,-4(4) # read 2:nd most significant limb
+ sreq 7,0,8 # compute most significant limb of result
+ bdz Lend # if just two limb, skip loop
+Loop: lu 0,-4(4) # load next lower limb
+ stu 7,-4(9) # store previous result during read latency
+ sreq 7,0,8 # compute result limb
+ bdn Loop # loop back until CTR is zero
+Lend: stu 7,-4(9) # store 2:nd least significant limb
+Lend2: sle 7,0,6 # compute least significant limb
+ st 7,-4(9) # store it
+ br
+
diff --git a/comm/third_party/libgcrypt/mpi/power/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/power/mpih-mul1.S
new file mode 100644
index 0000000000..35034fa408
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/power/mpih-mul1.S
@@ -0,0 +1,115 @@
+/* IBM POWER mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_mul_1[PR]
+ .align 2
+ .globl _gcry_mpih_mul_1
+ .globl ._gcry_mpih_mul_1
+ .csect _gcry_mpih_mul_1[DS]
+_gcry_mpih_mul_1:
+ .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_mul_1[PR]
+._gcry_mpih_mul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 8
+ ai 0,0,0 # reset carry
+ cax 9,9,7
+ blt Lneg
+Lpos: bdz Lend
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 8,0,9
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 8,0,10
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ cax 10,10,0 # adjust high limb for negative s2_limb
+ mfmq 0
+ ae 8,0,9
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ cax 9,9,0 # adjust high limb for negative s2_limb
+ mfmq 0
+ ae 8,0,10
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
diff --git a/comm/third_party/libgcrypt/mpi/power/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/power/mpih-mul2.S
new file mode 100644
index 0000000000..d056e8f3c2
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/power/mpih-mul2.S
@@ -0,0 +1,130 @@
+/* IBM POWER addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_addmul_1[PR]
+ .align 2
+ .globl _gcry_mpih_addmul_1
+ .globl ._gcry_mpih_addmul_1
+ .csect _gcry_mpih_addmul_1[DS]
+_gcry_mpih_addmul_1:
+ .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_addmul_1[PR]
+._gcry_mpih_addmul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 8
+ cax 9,9,7
+ l 7,4(3)
+ a 8,8,7 # add res_limb
+ blt Lneg
+Lpos: bdz Lend
+
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 8,0,9 # low limb + old_cy_limb + old cy
+ l 7,4(3)
+ aze 10,10 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 8,0,10
+ l 7,4(3)
+ aze 9,9
+ a 8,8,7
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 7
+ ae 8,7,9
+ l 7,4(3)
+ ae 10,10,0 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 7
+ ae 8,7,10
+ l 7,4(3)
+ ae 9,9,0 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
diff --git a/comm/third_party/libgcrypt/mpi/power/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/power/mpih-mul3.S
new file mode 100644
index 0000000000..8bc317b763
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/power/mpih-mul3.S
@@ -0,0 +1,135 @@
+/* IBM POWER submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*
+
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_submul_1[PR]
+ .align 2
+ .globl _gcry_mpih_submul_1
+ .globl ._gcry_mpih_submul_1
+ .csect _gcry_mpih_submul_1[DS]
+_gcry_mpih_submul_1:
+ .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_submul_1[PR]
+._gcry_mpih_submul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 11
+ cax 9,9,7
+ l 7,4(3)
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ blt Lneg
+Lpos: bdz Lend
+
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 11,0,9 # low limb + old_cy_limb + old cy
+ l 7,4(3)
+ aze 10,10 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 11,0,10
+ l 7,4(3)
+ aze 9,9
+ sf 8,11,7
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 7
+ ae 11,7,9
+ l 7,4(3)
+ ae 10,10,0 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 7
+ ae 11,7,10
+ l 7,4(3)
+ ae 9,9,0 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
diff --git a/comm/third_party/libgcrypt/mpi/power/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/power/mpih-rshift.S
new file mode 100644
index 0000000000..f131a86d7b
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/power/mpih-rshift.S
@@ -0,0 +1,64 @@
+/* IBM POWER rshift
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s_ptr r4
+# size r5
+# cnt r6
+*/
+
+ .toc
+ .extern _gcry_mpih_rshift[DS]
+ .extern ._gcry_mpih_rshift
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_rshift
+ .globl ._gcry_mpih_rshift
+ .csect _gcry_mpih_rshift[DS]
+_gcry_mpih_rshift:
+ .long ._gcry_mpih_rshift, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_rshift:
+ sfi 8,6,32
+ mtctr 5 # put limb count in CTR loop register
+ l 0,0(4) # read least significant limb
+ ai 9,3,-4 # adjust res_ptr since it's offset in the stu:s
+ sle 3,0,8 # compute carry limb, and init MQ register
+ bdz Lend2 # if just one limb, skip loop
+ lu 0,4(4) # read 2:nd least significant limb
+ sleq 7,0,8 # compute least significant limb of result
+ bdz Lend # if just two limb, skip loop
+Loop: lu 0,4(4) # load next higher limb
+ stu 7,4(9) # store previous result during read latency
+ sleq 7,0,8 # compute result limb
+ bdn Loop # loop back until CTR is zero
+Lend: stu 7,4(9) # store 2:nd most significant limb
+Lend2: sre 7,0,6 # compute most significant limb
+ st 7,4(9) # store it
+ br
+
+
diff --git a/comm/third_party/libgcrypt/mpi/power/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/power/mpih-sub1.S
new file mode 100644
index 0000000000..02748fc556
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/power/mpih-sub1.S
@@ -0,0 +1,88 @@
+/* IBM POWER sub_n -- Subtract two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1996, 1999,
+ * 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# s2_ptr r5
+# size r6
+ */
+
+ .toc
+ .extern _gcry_mpih_sub_n[DS]
+ .extern ._gcry_mpih_sub_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .globl ._gcry_mpih_sub_n
+ .csect _gcry_mpih_sub_n[DS]
+_gcry_mpih_sub_n:
+ .long ._gcry_mpih_sub_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_sub_n:
+ andil. 10,6,1 # odd or even number of limbs?
+ l 8,0(4) # load least significant s1 limb
+ l 0,0(5) # load least significant s2 limb
+ cal 3,-4(3) # offset res_ptr, it's updated before it's used
+ sri 10,6,1 # count for unrolled loop
+ sf 7,0,8 # subtract least significant limbs, set cy
+ mtctr 10 # copy count into CTR
+ beq 0,Leven # branch if even # of limbs (# of limbs >= 2)
+
+# We have an odd # of limbs. Add the first limbs separately.
+ cmpi 1,10,0 # is count for unrolled loop zero?
+ bne 1,L1 # branch if not
+ st 7,4(3)
+ sfe 3,0,0 # load !cy into ...
+ sfi 3,3,0 # ... return value register
+ br # return
+
+# We added least significant limbs. Now reload the next limbs to enter loop.
+L1: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ stu 7,4(3)
+ sfe 7,0,8 # subtract limbs, set cy
+Leven: lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ bdz Lend # If done, skip loop
+
+Loop: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ sfe 11,10,9 # subtract previous limbs with cy, set cy
+ stu 7,4(3) #
+ lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ sfe 7,0,8 # subtract previous limbs with cy, set cy
+ stu 11,4(3) #
+ bdn Loop # decrement CTR and loop back
+
+Lend: sfe 11,10,9 # subtract limbs with cy, set cy
+ st 7,4(3) #
+ st 11,8(3) #
+ sfe 3,0,0 # load !cy into ...
+ sfi 3,3,0 # ... return value register
+ br
+
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/distfiles b/comm/third_party/libgcrypt/mpi/powerpc32/distfiles
new file mode 100644
index 0000000000..af10d795b0
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/distfiles
@@ -0,0 +1,9 @@
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+syntax.h
+
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/mpih-add1.S b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-add1.S
new file mode 100644
index 0000000000..1661f5e679
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-add1.S
@@ -0,0 +1,136 @@
+/* PowerPC-32 add_n -- Add two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_ptr_t s2_ptr, (r5)
+ * mpi_size_t size) (r6)
+ */
+
+ .toc
+ .extern _gcry_mpih_add_n[DS]
+ .extern ._gcry_mpih_add_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_add_n
+ .globl ._gcry_mpih_add_n
+ .csect _gcry_mpih_add_n[DS]
+_gcry_mpih_add_n:
+ .long ._gcry_mpih_add_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_add_n:
+ mtctr 6 # copy size into CTR
+ lwz 8,0(4) # load least significant s1 limb
+ lwz 0,0(5) # load least significant s2 limb
+ addi 3,3,-4 # offset res_ptr, it is updated before used
+ addc 7,0,8 # add least significant limbs, set cy
+ bdz Lend # If done, skip loop
+Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr
+ lwzu 0,4(5) # load s2 limb and update s2_ptr
+ stwu 7,4(3) # store previous limb in load latency slot
+ adde 7,0,8 # add new limbs with cy, set cy
+ bdnz Loop # decrement CTR and loop back
+Lend: stw 7,4(3) # store ultimate result limb
+ li 3,0 # load cy into ...
+ addze 3,3 # ... return value register
+ blr
+
+#else
+/* Add two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN(_gcry_mpih_add_n,3,0)
+/* Set up for loop below. */
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ li %r10,0
+ mtctr %r7
+ bt 31,2f
+
+/* Clear the carry. */
+ addic %r0,%r0,0
+/* Adjust pointers for loop. */
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ addc %r6,%r6,%r7
+ stw %r6,0(%r3)
+ beq 1f
+
+/* The loop. */
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). */
+0: lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ adde %r8,%r9,%r8
+ stw %r8,4(%r3)
+ adde %r6,%r6,%r7
+ stwu %r6,8(%r3)
+ bdnz 0b
+/* Return the carry. */
+1: addze %r3,%r10
+ blr
+END(_gcry_mpih_add_n)
+#endif
+
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-lshift.S
new file mode 100644
index 0000000000..6231095dc2
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-lshift.S
@@ -0,0 +1,198 @@
+/* PowerPC-32 lshift
+ *
+ * Copyright (C) 1995, 1998, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (r3)
+ * mpi_ptr_t up, (r4)
+ * mpi_size_t usize, (r5)
+ * unsigned cnt) (r6)
+ */
+
+ .toc
+.csect .text[PR]
+ .align 2
+ .globl _gcry_mpih_lshift
+ .globl ._gcry_mpih_lshift
+ .csect _gcry_mpih_lshift[DS]
+_gcry_mpih_lshift:
+ .long ._gcry_mpih_lshift, TOC[tc0], 0
+ .csect .text[PR]
+._gcry_mpih_lshift:
+ mtctr 5 # copy size into CTR
+ slwi 0,5,2
+ add 7,3,0 # make r7 point at end of res
+ add 4,4,0 # make r4 point at end of s1
+ subfic 8,6,32
+ lwzu 11,-4(4) # load first s1 limb
+ srw 3,11,8 # compute function return value
+ bdz Lend1
+
+Loop: lwzu 10,-4(4)
+ slw 9,11,6
+ srw 12,10,8
+ or 9,9,12
+ stwu 9,-4(7)
+ bdz Lend2
+ lwzu 11,-4(4)
+ slw 9,10,6
+ srw 12,11,8
+ or 9,9,12
+ stwu 9,-4(7)
+ bdnz Loop
+
+Lend1: slw 0,11,6
+ stw 0,-4(7)
+ blr
+
+Lend2: slw 0,10,6
+ stw 0,-4(7)
+ blr
+
+#else
+/* Shift a limb left, low level routine.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+ unsigned int cnt) */
+
+EALIGN(_gcry_mpih_lshift,3,0)
+ mtctr %r5 # copy size into CTR
+ cmplwi %cr0,%r5,16 # is size < 16
+ slwi %r0,%r5,2
+ add %r7,%r3,%r0 # make r7 point at end of res
+ add %r4,%r4,%r0 # make r4 point at end of s1
+ lwzu %r11,-4(%r4) # load first s1 limb
+ subfic %r8,%r6,32
+ srw %r3,%r11,%r8 # compute function return value
+ bge %cr0,L(big) # branch if size >= 16
+
+ bdz L(end1)
+
+0: lwzu %r10,-4(%r4)
+ slw %r9,%r11,%r6
+ srw %r12,%r10,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdz L(end2)
+ lwzu %r11,-4(%r4)
+ slw %r9,%r10,%r6
+ srw %r12,%r11,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdnz 0b
+
+L(end1):slw %r0,%r11,%r6
+ stw %r0,-4(%r7)
+ blr
+
+
+/* Guaranteed not to succeed. */
+L(boom): tweq %r0,%r0
+
+/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
+ of size 4*12 bytes. We have to do this (or something) to make this PIC. */
+L(big): mflr %r9
+ bltl- %cr0,L(boom) # Never taken, only used to set LR.
+ slwi %r10,%r6,4
+ mflr %r12
+ add %r10,%r12,%r10
+ slwi %r8,%r6,5
+ add %r10,%r8,%r10
+ mtctr %r10
+ addi %r5,%r5,-1
+ mtlr %r9
+ bctr
+
+L(end2):slw %r0,%r10,%r6
+ stw %r0,-4(%r7)
+ blr
+
+#define DO_LSHIFT(n) \
+ mtctr %r5; \
+0: lwzu %r10,-4(%r4); \
+ slwi %r9,%r11,n; \
+ inslwi %r9,%r10,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdz- L(end2); \
+ lwzu %r11,-4(%r4); \
+ slwi %r9,%r10,n; \
+ inslwi %r9,%r11,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdnz 0b; \
+ b L(end1)
+
+ DO_LSHIFT(1)
+ DO_LSHIFT(2)
+ DO_LSHIFT(3)
+ DO_LSHIFT(4)
+ DO_LSHIFT(5)
+ DO_LSHIFT(6)
+ DO_LSHIFT(7)
+ DO_LSHIFT(8)
+ DO_LSHIFT(9)
+ DO_LSHIFT(10)
+ DO_LSHIFT(11)
+ DO_LSHIFT(12)
+ DO_LSHIFT(13)
+ DO_LSHIFT(14)
+ DO_LSHIFT(15)
+ DO_LSHIFT(16)
+ DO_LSHIFT(17)
+ DO_LSHIFT(18)
+ DO_LSHIFT(19)
+ DO_LSHIFT(20)
+ DO_LSHIFT(21)
+ DO_LSHIFT(22)
+ DO_LSHIFT(23)
+ DO_LSHIFT(24)
+ DO_LSHIFT(25)
+ DO_LSHIFT(26)
+ DO_LSHIFT(27)
+ DO_LSHIFT(28)
+ DO_LSHIFT(29)
+ DO_LSHIFT(30)
+ DO_LSHIFT(31)
+
+END(_gcry_mpih_lshift)
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul1.S
new file mode 100644
index 0000000000..bd418f7e3a
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul1.S
@@ -0,0 +1,120 @@
+/* PowerPC-32 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995,
+ * 1998, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+ .toc
+ .csect ._gcry_mpih_mul_1[PR]
+ .align 2
+ .globl _gcry_mpih_mul_1
+ .globl ._gcry_mpih_mul_1
+ .csect _gcry_mpih_mul_1[DS]
+_gcry_mpih_mul_1:
+ .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_mul_1[PR]
+._gcry_mpih_mul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ addi 3,3,-4 # adjust res_ptr
+ addic 5,5,0 # clear cy with dummy insn
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 7,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ bdnz Loop
+
+Lend: stw 7,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate s1*s2 and put result in res_ptr; return carry. */
+
+ENTRY(_gcry_mpih_mul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ addi %r3,%r3,-4 # adjust res_ptr
+ addic %r5,%r5,0 # clear cy with dummy insn
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r7,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ bdnz 0b
+
+1: stw %r7,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_mul_1)
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul2.S
new file mode 100644
index 0000000000..1d97b81a4d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul2.S
@@ -0,0 +1,127 @@
+/* PowerPC-32 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+
+ .toc
+ .csect ._gcry_mpih_addmul_1[PR]
+ .align 2
+ .globl _gcry_mpih_addmul_1
+ .globl ._gcry_mpih_addmul_1
+ .csect _gcry_mpih_addmul_1[DS]
+_gcry_mpih_addmul_1:
+ .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_addmul_1[PR]
+._gcry_mpih_addmul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ lwz 9,0(3)
+ addc 8,7,9
+ addi 3,3,-4
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 8,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ lwz 9,4(3)
+ addze 10,10
+ addc 8,7,9
+ bdnz Loop
+
+Lend: stw 8,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res+s1*s2 and put result back in res; return carry. */
+ENTRY(_gcry_mpih_addmul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ addc %r8,%r7,%r9
+ addi %r3,%r3,-4 /* adjust res_ptr */
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ addc %r8,%r7,%r9
+ bdnz 0b
+
+1: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_addmul_1)
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul3.S
new file mode 100644
index 0000000000..c410dbb02e
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-mul3.S
@@ -0,0 +1,130 @@
+/* PowerPC-32 submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+ .toc
+ .csect ._gcry_mpih_submul_1[PR]
+ .align 2
+ .globl _gcry_mpih_submul_1
+ .globl ._gcry_mpih_submul_1
+ .csect _gcry_mpih_submul_1[DS]
+_gcry_mpih_submul_1:
+ .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_submul_1[PR]
+._gcry_mpih_submul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ lwz 9,0(3)
+ subfc 8,7,9
+ addc 7,7,8 # invert cy (r7 is junk)
+ addi 3,3,-4
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 8,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ lwz 9,4(3)
+ addze 10,10
+ subfc 8,7,9
+ addc 7,7,8 # invert cy (r7 is junk)
+ bdnz Loop
+
+Lend: stw 8,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res-s1*s2 and put result back in res; return carry. */
+
+ENTRY(_gcry_mpih_submul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ addi %r3,%r3,-4 # adjust res_ptr
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ bdnz 0b
+
+1: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_submul_1)
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-rshift.S
new file mode 100644
index 0000000000..98349edb5b
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-rshift.S
@@ -0,0 +1,131 @@
+/* PowerPC-32 rshift
+ *
+ * Copyright (C) 1995, 1998, 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (r3)
+ * mpi_ptr_t up, (r4)
+ * mpi_size_t usize, (r5)
+ * unsigned cnt) (r6)
+ */
+
+ .toc
+.csect .text[PR]
+ .align 2
+ .globl _gcry_mpih_rshift
+ .globl ._gcry_mpih_rshift
+ .csect _gcry_mpih_rshift[DS]
+_gcry_mpih_rshift:
+ .long ._gcry_mpih_rshift, TOC[tc0], 0
+ .csect .text[PR]
+._gcry_mpih_rshift:
+ mtctr 5 # copy size into CTR
+ addi 7,3,-4 # move adjusted res_ptr to free return reg
+ subfic 8,6,32
+ lwz 11,0(4) # load first s1 limb
+ slw 3,11,8 # compute function return value
+ bdz Lend1
+
+Loop: lwzu 10,4(4)
+ srw 9,11,6
+ slw 12,10,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdz Lend2
+ lwzu 11,4(4)
+ srw 9,10,6
+ slw 12,11,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdnz Loop
+
+Lend1: srw 0,11,6
+ stw 0,4(7)
+ blr
+
+Lend2: srw 0,10,6
+ stw 0,4(7)
+ blr
+
+#else
+/* Shift a limb right, low level routine.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+/* INPUT PARAMETERS
+ res_ptr r3
+ s1_ptr r4
+ size r5
+ cnt r6 */
+
+ENTRY(_gcry_mpih_rshift)
+ mtctr 5 # copy size into CTR
+ addi 7,3,-4 # move adjusted res_ptr to free return reg
+ subfic 8,6,32
+ lwz 11,0(4) # load first s1 limb
+ slw 3,11,8 # compute function return value
+ bdz 1f
+
+0: lwzu 10,4(4)
+ srw 9,11,6
+ slw 12,10,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdz 2f
+ lwzu 11,4(4)
+ srw 9,10,6
+ slw 12,11,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdnz 0b
+
+1: srw 0,11,6
+ stw 0,4(7)
+ blr
+
+2: srw 0,10,6
+ stw 0,4(7)
+ blr
+END(_gcry_mpih_rshift)
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/mpih-sub1.S b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-sub1.S
new file mode 100644
index 0000000000..d612ea890a
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/mpih-sub1.S
@@ -0,0 +1,133 @@
+/* PowerPC-32 sub_n -- Subtract two limb vectors of the same length > 0
+ * and store difference in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2002 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_ptr_t s2_ptr, (r5)
+ * mpi_size_t size) (r6)
+ */
+
+ .toc
+ .extern _gcry_mpih_sub_n[DS]
+ .extern ._gcry_mpih_sub_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .globl ._gcry_mpih_sub_n
+ .csect _gcry_mpih_sub_n[DS]
+_gcry_mpih_sub_n:
+ .long ._gcry_mpih_sub_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_sub_n:
+ mtctr 6 # copy size into CTR
+ lwz 8,0(4) # load least significant s1 limb
+ lwz 0,0(5) # load least significant s2 limb
+ addi 3,3,-4 # offset res_ptr, it is updated before used
+ subfc 7,0,8 # add least significant limbs, set cy
+ bdz Lend # If done, skip loop
+Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr
+ lwzu 0,4(5) # load s2 limb and update s2_ptr
+ stwu 7,4(3) # store previous limb in load latency slot
+ subfe 7,0,8 # add new limbs with cy, set cy
+ bdnz Loop # decrement CTR and loop back
+Lend: stw 7,4(3) # store ultimate result limb
+ subfe 3,0,0 # load !cy into ...
+ subfic 3,3,0 # ... return value register
+ blr
+
+#else
+/* Subtract two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN(_gcry_mpih_sub_n,3,1)
+/* Set up for loop below. */
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ mtctr %r7
+ bt 31,2f
+
+/* Set the carry (clear the borrow). */
+ subfc %r0,%r0,%r0
+/* Adjust pointers for loop. */
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ subfc %r6,%r7,%r6
+ stw %r6,0(%r3)
+ beq 1f
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). This turns
+ out to be important. */
+0:
+ lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ subfe %r8,%r8,%r9
+ stw %r8,4(%r3)
+ subfe %r6,%r7,%r6
+ stwu %r6,8(%r3)
+ bdnz 0b
+/* Return the borrow. */
+1: subfe %r3,%r3,%r3
+ neg %r3,%r3
+ blr
+END(_gcry_mpih_sub_n)
+#endif
diff --git a/comm/third_party/libgcrypt/mpi/powerpc32/syntax.h b/comm/third_party/libgcrypt/mpi/powerpc32/syntax.h
new file mode 100644
index 0000000000..5d4af9f0ae
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc32/syntax.h
@@ -0,0 +1,75 @@
+/* gmp2-2.0.2-ppc/mpn/powerpc-linux/syntax.h Tue Oct 6 19:27:01 1998 */
+/* From glibc's sysdeps/unix/sysv/linux/powerpc/sysdep.h */
+
+/* Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#define USE_PPC_PATCHES 1
+
+/* This seems to always be the case on PPC. */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+#define ASM_GLOBAL_DIRECTIVE .globl
+
+#ifdef __STDC__
+#define C_LABEL(name) C_SYMBOL_NAME(name)##:
+#else
+#define C_LABEL(name) C_SYMBOL_NAME(name)/**/:
+#endif
+
+#ifdef __STDC__
+#define L(body) .L##body
+#else
+#define L(body) .L/**/body
+#endif
+
+/* No profiling of gmp's assembly for now... */
+#define CALL_MCOUNT /* no profiling */
+
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#define EALIGN_W_0 /* No words to insert. */
+#define EALIGN_W_1 nop
+#define EALIGN_W_2 nop;nop
+#define EALIGN_W_3 nop;nop;nop
+#define EALIGN_W_4 EALIGN_W_3;nop
+#define EALIGN_W_5 EALIGN_W_4;nop
+#define EALIGN_W_6 EALIGN_W_5;nop
+#define EALIGN_W_7 EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+ past a 2^align boundary. */
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ C_LABEL(name)
+
+#undef END
+#define END(name) \
+ ASM_SIZE_DIRECTIVE(name)
+
diff --git a/comm/third_party/libgcrypt/mpi/powerpc64/distfiles b/comm/third_party/libgcrypt/mpi/powerpc64/distfiles
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/powerpc64/distfiles
diff --git a/comm/third_party/libgcrypt/mpi/sparc32/distfiles b/comm/third_party/libgcrypt/mpi/sparc32/distfiles
new file mode 100644
index 0000000000..51329dbdbe
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32/distfiles
@@ -0,0 +1,5 @@
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+udiv.S
+
diff --git a/comm/third_party/libgcrypt/mpi/sparc32/mpih-add1.S b/comm/third_party/libgcrypt/mpi/sparc32/mpih-add1.S
new file mode 100644
index 0000000000..61a80ca320
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32/mpih-add1.S
@@ -0,0 +1,239 @@
+/* SPARC _add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 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
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr,
+ * mpi_ptr_t s1_ptr,
+ * mpi_ptr_t s2_ptr,
+ * mpi_size_t size)
+ */
+
+! INPUT PARAMETERS
+#define res_ptr %o0
+#define s1_ptr %o1
+#define s2_ptr %o2
+#define size %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n):
+ xor s2_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L1 ! branch if alignment differs
+ nop
+! ** V1a **
+L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
+ be L_v1 ! if no, branch
+ nop
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add size,-1,size
+ addcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+L_v1: addx %g0,%g0,%o4 ! save cy in register
+ cmp size,2 ! if size < 2 ...
+ bl Lend2 ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [s1_ptr+0],%g4
+ addcc size,-10,size
+ ld [s1_ptr+4],%g1
+ ldd [s2_ptr+0],%g2
+ blt Lfin1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop1: addxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+16],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+20],%g1
+ ldd [s2_ptr+16],%g2
+ std %o4,[res_ptr+8]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+24],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+28],%g1
+ ldd [s2_ptr+24],%g2
+ std %o4,[res_ptr+16]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+32],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+36],%g1
+ ldd [s2_ptr+32],%g2
+ std %o4,[res_ptr+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge Loop1
+ subcc %g0,%o4,%g0 ! restore cy
+
+Lfin1: addcc size,8-2,size
+ blt Lend1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1: addxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-2,size
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge Loope1
+ subcc %g0,%o4,%g0 ! restore cy
+Lend1: addxcc %g4,%g2,%o4
+ addxcc %g1,%g3,%o5
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc size,1,%g0
+ be Lret1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [s1_ptr+8],%g4
+ ld [s2_ptr+8],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[res_ptr+8]
+
+Lret1: retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+L1: xor s1_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L2
+ nop
+! ** V1b **
+ mov s2_ptr,%g1
+ mov s1_ptr,s2_ptr
+ b L0
+ mov %g1,s1_ptr
+
+! ** V2 **
+/* If we come here, the alignment of s1_ptr and res_ptr as well as the
+ alignment of s2_ptr and res_ptr differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of s1_ptr and s2_ptr are the same. */
+
+L2: cmp size,1
+ be Ljone
+ nop
+ andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
+ be L_v2 ! if no, branch
+ nop
+/* Add least significant limb separately to align s1_ptr and s2_ptr */
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add size,-1,size
+ addcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+
+L_v2: addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ blt Lfin2
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop2: ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ ldd [s1_ptr+8],%g2
+ ldd [s2_ptr+8],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+8]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+12]
+ ldd [s1_ptr+16],%g2
+ ldd [s2_ptr+16],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+16]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+20]
+ ldd [s1_ptr+24],%g2
+ ldd [s2_ptr+24],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+24]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+28]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge Loop2
+ subcc %g0,%o4,%g0 ! restore cy
+
+Lfin2: addcc size,8-2,size
+ blt Lend2
+ subcc %g0,%o4,%g0 ! restore cy
+Loope2: ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-2,size
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge Loope2
+ subcc %g0,%o4,%g0 ! restore cy
+Lend2: andcc size,1,%g0
+ be Lret2
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+Ljone: ld [s1_ptr],%g4
+ ld [s2_ptr],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+
+Lret2: retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+
+
diff --git a/comm/third_party/libgcrypt/mpi/sparc32/mpih-lshift.S b/comm/third_party/libgcrypt/mpi/sparc32/mpih-lshift.S
new file mode 100644
index 0000000000..3422ab04e5
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32/mpih-lshift.S
@@ -0,0 +1,97 @@
+/* sparc lshift
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 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
+ */
+
+
+! INPUT PARAMETERS
+! res_ptr %o0
+! src_ptr %o1
+! size %o2
+! cnt %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift):
+ sll %o2,2,%g1
+ add %o1,%g1,%o1 ! make %o1 point at end of src
+ ld [%o1-4],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o0,%g1,%o0 ! make %o0 point at end of res
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ srl %g2,%o5,%g1 ! compute function result
+ be L0 ! if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+Loop0: ld [%o1-8],%g3
+ add %o0,-4,%o0
+ add %o1,-4,%o1
+ addcc %g4,-1,%g4
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne Loop0
+ st %o4,[%o0+0]
+
+L0: tst %o2
+ be Lend
+ nop
+
+Loop: ld [%o1-8],%g3
+ add %o0,-16,%o0
+ addcc %o2,-4,%o2
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+
+ ld [%o1-12],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+12]
+ srl %g2,%o5,%g1
+
+ ld [%o1-16],%g3
+ sll %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0+8]
+ srl %g3,%o5,%g1
+
+ ld [%o1-20],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+4]
+ srl %g2,%o5,%g1
+
+ add %o1,-16,%o1
+ or %g4,%g1,%g4
+ bne Loop
+ st %g4,[%o0+0]
+
+Lend: sll %g2,%o3,%g2
+ st %g2,[%o0-4]
+ retl
+ ld [%sp+80],%o0
+
diff --git a/comm/third_party/libgcrypt/mpi/sparc32/mpih-rshift.S b/comm/third_party/libgcrypt/mpi/sparc32/mpih-rshift.S
new file mode 100644
index 0000000000..cd3db41df3
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32/mpih-rshift.S
@@ -0,0 +1,93 @@
+/* sparc rshift
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 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
+ */
+
+! INPUT PARAMETERS
+! res_ptr %o0
+! src_ptr %o1
+! size %o2
+! cnt %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift):
+ ld [%o1],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ sll %g2,%o5,%g1 ! compute function result
+ be L0 ! if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+Loop0: ld [%o1+4],%g3
+ add %o0,4,%o0
+ add %o1,4,%o1
+ addcc %g4,-1,%g4
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne Loop0
+ st %o4,[%o0-4]
+
+L0: tst %o2
+ be Lend
+ nop
+
+Loop: ld [%o1+4],%g3
+ add %o0,16,%o0
+ addcc %o2,-4,%o2
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+
+ ld [%o1+8],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-16]
+ sll %g2,%o5,%g1
+
+ ld [%o1+12],%g3
+ srl %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0-12]
+ sll %g3,%o5,%g1
+
+ ld [%o1+16],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-8]
+ sll %g2,%o5,%g1
+
+ add %o1,16,%o1
+ or %g4,%g1,%g4
+ bne Loop
+ st %g4,[%o0-4]
+
+Lend: srl %g2,%o3,%g2
+ st %g2,[%o0-0]
+ retl
+ ld [%sp+80],%o0
+
diff --git a/comm/third_party/libgcrypt/mpi/sparc32/udiv.S b/comm/third_party/libgcrypt/mpi/sparc32/udiv.S
new file mode 100644
index 0000000000..006b5c125c
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32/udiv.S
@@ -0,0 +1,195 @@
+/* SPARC v7 __udiv_qrnnd division support, used from longlong.h.
+ * This is for v7 CPUs without a floating-point unit.
+ *
+ * Copyright (C) 1993, 1994, 1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+! INPUT PARAMETERS
+! rem_ptr o0
+! n1 o1
+! n0 o2
+! d o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+ tst %o3
+ bneg Largedivisor
+ mov 8,%g1
+
+ b Lp1
+ addxcc %o2,%o2,%o2
+
+Lplop: bcc Ln1
+ addxcc %o2,%o2,%o2
+Lp1: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln2
+ addxcc %o2,%o2,%o2
+Lp2: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln3
+ addxcc %o2,%o2,%o2
+Lp3: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln4
+ addxcc %o2,%o2,%o2
+Lp4: addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne Lplop
+ subcc %o1,%o3,%o4
+ bcc Ln5
+ addxcc %o2,%o2,%o2
+Lp5: st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Lnlop: bcc Lp1
+ addxcc %o2,%o2,%o2
+Ln1: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp2
+ addxcc %o2,%o2,%o2
+Ln2: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp3
+ addxcc %o2,%o2,%o2
+Ln3: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp4
+ addxcc %o2,%o2,%o2
+Ln4: addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne Lnlop
+ subcc %o4,%o3,%o1
+ bcc Lp5
+ addxcc %o2,%o2,%o2
+Ln5: st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Largedivisor:
+ and %o2,1,%o5 ! %o5 = n0 & 1
+
+ srl %o2,1,%o2
+ sll %o1,31,%g2
+ or %g2,%o2,%o2 ! %o2 = lo(n1n0 >> 1)
+ srl %o1,1,%o1 ! %o1 = hi(n1n0 >> 1)
+
+ and %o3,1,%g2
+ srl %o3,1,%g3 ! %g3 = floor(d / 2)
+ add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
+
+ b LLp1
+ addxcc %o2,%o2,%o2
+
+LLplop: bcc LLn1
+ addxcc %o2,%o2,%o2
+LLp1: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn2
+ addxcc %o2,%o2,%o2
+LLp2: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn3
+ addxcc %o2,%o2,%o2
+LLp3: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn4
+ addxcc %o2,%o2,%o2
+LLp4: addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne LLplop
+ subcc %o1,%g3,%o4
+ bcc LLn5
+ addxcc %o2,%o2,%o2
+LLp5: add %o1,%o1,%o1 ! << 1
+ tst %g2
+ bne Oddp
+ add %o5,%o1,%o1
+ st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+LLnlop: bcc LLp1
+ addxcc %o2,%o2,%o2
+LLn1: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp2
+ addxcc %o2,%o2,%o2
+LLn2: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp3
+ addxcc %o2,%o2,%o2
+LLn3: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp4
+ addxcc %o2,%o2,%o2
+LLn4: addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne LLnlop
+ subcc %o4,%g3,%o1
+ bcc LLp5
+ addxcc %o2,%o2,%o2
+LLn5: add %o4,%o4,%o4 ! << 1
+ tst %g2
+ bne Oddn
+ add %o5,%o4,%o4
+ st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Oddp: xnor %g0,%o2,%o2
+ ! q' in %o2. r' in %o1
+ addcc %o1,%o2,%o1
+ bcc LLp6
+ addx %o2,0,%o2
+ sub %o1,%o3,%o1
+LLp6: subcc %o1,%o3,%g0
+ bcs LLp7
+ subx %o2,-1,%o2
+ sub %o1,%o3,%o1
+LLp7: st %o1,[%o0]
+ retl
+ mov %o2,%o0
+
+Oddn: xnor %g0,%o2,%o2
+ ! q' in %o2. r' in %o4
+ addcc %o4,%o2,%o4
+ bcc LLn6
+ addx %o2,0,%o2
+ sub %o4,%o3,%o4
+LLn6: subcc %o4,%o3,%g0
+ bcs LLn7
+ subx %o2,-1,%o2
+ sub %o4,%o3,%o4
+LLn7: st %o4,[%o0]
+ retl
+ mov %o2,%o0
diff --git a/comm/third_party/libgcrypt/mpi/sparc32v8/distfiles b/comm/third_party/libgcrypt/mpi/sparc32v8/distfiles
new file mode 100644
index 0000000000..2fcb0d1aa0
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32v8/distfiles
@@ -0,0 +1,4 @@
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+
diff --git a/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul1.S b/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul1.S
new file mode 100644
index 0000000000..03fcddab0e
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul1.S
@@ -0,0 +1,109 @@
+/* SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and
+ * store the product in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 8
+ .global C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1):
+ sll %o2,4,%g1
+ and %g1,(4-1)<<4,%g1
+#if PIC
+ mov %o7,%g4 ! Save return address register
+ call 1f
+ add %o7,LL-1f,%g3
+1: mov %g4,%o7 ! Restore return address register
+#else
+ sethi %hi(LL),%g3
+ or %g3,%lo(LL),%g3
+#endif
+ jmp %g3+%g1
+ ld [%o1+0],%o4 ! 1
+LL:
+LL00: add %o0,-4,%o0
+ add %o1,-4,%o1
+ b Loop00 /* 4, 8, 12, ... */
+ orcc %g0,%g0,%g2
+LL01: b Loop01 /* 1, 5, 9, ... */
+ orcc %g0,%g0,%g2
+ nop
+ nop
+LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
+ add %o1,4,%o1
+ b Loop10
+ orcc %g0,%g0,%g2
+ nop
+LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
+ add %o1,-8,%o1
+ b Loop11
+ orcc %g0,%g0,%g2
+
+Loop: addcc %g3,%g2,%g3 ! 1
+ ld [%o1+4],%o4 ! 2
+ st %g3,[%o0+0] ! 1
+ rd %y,%g2 ! 1
+Loop00: umul %o4,%o3,%g3 ! 2
+ addxcc %g3,%g2,%g3 ! 2
+ ld [%o1+8],%o4 ! 3
+ st %g3,[%o0+4] ! 2
+ rd %y,%g2 ! 2
+Loop11: umul %o4,%o3,%g3 ! 3
+ addxcc %g3,%g2,%g3 ! 3
+ ld [%o1+12],%o4 ! 4
+ add %o1,16,%o1
+ st %g3,[%o0+8] ! 3
+ rd %y,%g2 ! 3
+Loop10: umul %o4,%o3,%g3 ! 4
+ addxcc %g3,%g2,%g3 ! 4
+ ld [%o1+0],%o4 ! 1
+ st %g3,[%o0+12] ! 4
+ add %o0,16,%o0
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+Loop01: addcc %o2,-4,%o2
+ bg Loop
+ umul %o4,%o3,%g3 ! 1
+
+ addcc %g3,%g2,%g3 ! 4
+ st %g3,[%o0+0] ! 4
+ rd %y,%g2 ! 4
+
+ retl
+ addx %g0,%g2,%o0
+
+
diff --git a/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul2.S b/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul2.S
new file mode 100644
index 0000000000..6f5cc436a7
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul2.S
@@ -0,0 +1,132 @@
+/* SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and
+ * add the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1):
+ orcc %g0,%g0,%g2
+ ld [%o1+0],%o4 ! 1
+
+ sll %o2,4,%g1
+ and %g1,(4-1)<<4,%g1
+#if PIC
+ mov %o7,%g4 ! Save return address register
+ call 1f
+ add %o7,LL-1f,%g3
+1: mov %g4,%o7 ! Restore return address register
+#else
+ sethi %hi(LL),%g3
+ or %g3,%lo(LL),%g3
+#endif
+ jmp %g3+%g1
+ nop
+LL:
+LL00: add %o0,-4,%o0
+ b Loop00 /* 4, 8, 12, ... */
+ add %o1,-4,%o1
+ nop
+LL01: b Loop01 /* 1, 5, 9, ... */
+ nop
+ nop
+ nop
+LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
+ b Loop10
+ add %o1,4,%o1
+ nop
+LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
+ b Loop11
+ add %o1,-8,%o1
+ nop
+
+1: addcc %g3,%g2,%g3 ! 1
+ ld [%o1+4],%o4 ! 2
+ rd %y,%g2 ! 1
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] ! 1
+Loop00: umul %o4,%o3,%g3 ! 2
+ ld [%o0+4],%g1 ! 2
+ addxcc %g3,%g2,%g3 ! 2
+ ld [%o1+8],%o4 ! 3
+ rd %y,%g2 ! 2
+ addx %g0,%g2,%g2
+ nop
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+4] ! 2
+Loop11: umul %o4,%o3,%g3 ! 3
+ addxcc %g3,%g2,%g3 ! 3
+ ld [%o1+12],%o4 ! 4
+ rd %y,%g2 ! 3
+ add %o1,16,%o1
+ addx %g0,%g2,%g2
+ ld [%o0+8],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+8] ! 3
+Loop10: umul %o4,%o3,%g3 ! 4
+ addxcc %g3,%g2,%g3 ! 4
+ ld [%o1+0],%o4 ! 1
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+ ld [%o0+12],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+12] ! 4
+ add %o0,16,%o0
+ addx %g0,%g2,%g2
+Loop01: addcc %o2,-4,%o2
+ bg 1b
+ umul %o4,%o3,%g3 ! 1
+
+ addcc %g3,%g2,%g3 ! 4
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] ! 4
+ addx %g0,%g2,%o0
+
+ retl
+ nop
+
+
+! umul, ld, addxcc, rd, st
+
+! umul, ld, addxcc, rd, ld, addcc, st, addx
+
diff --git a/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul3.S b/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul3.S
new file mode 100644
index 0000000000..93bb19433d
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/sparc32v8/mpih-mul3.S
@@ -0,0 +1,67 @@
+/* SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1):
+ sub %g0,%o2,%o2 ! negate ...
+ sll %o2,2,%o2 ! ... and scale size
+ sub %o1,%o2,%o1 ! o1 is offset s1_ptr
+ sub %o0,%o2,%g1 ! g1 is offset res_ptr
+
+ mov 0,%o0 ! clear cy_limb
+
+Loop: ld [%o1+%o2],%o4
+ ld [%g1+%o2],%g2
+ umul %o4,%o3,%o5
+ rd %y,%g3
+ addcc %o5,%o0,%o5
+ addx %g3,0,%o0
+ subcc %g2,%o5,%g2
+ addx %o0,0,%o0
+ st %g2,[%g1+%o2]
+
+ addcc %o2,4,%o2
+ bne Loop
+ nop
+
+ retl
+ nop
+
+
diff --git a/comm/third_party/libgcrypt/mpi/supersparc/distfiles b/comm/third_party/libgcrypt/mpi/supersparc/distfiles
new file mode 100644
index 0000000000..550601cb58
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/supersparc/distfiles
@@ -0,0 +1,2 @@
+udiv.S
+
diff --git a/comm/third_party/libgcrypt/mpi/supersparc/udiv.S b/comm/third_party/libgcrypt/mpi/supersparc/udiv.S
new file mode 100644
index 0000000000..79e506a11f
--- /dev/null
+++ b/comm/third_party/libgcrypt/mpi/supersparc/udiv.S
@@ -0,0 +1,118 @@
+/* SuperSPARC __udiv_qrnnd division support, used from longlong.h.
+ * This is for SuperSPARC only, to compensate for its
+ * semi-functional udiv instruction.
+ *
+ * Copyright (C) 1993, 1994, 1996, 1998,
+ * 2001, 2002 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! rem_ptr i0
+! n1 i1
+! n0 i2
+! d i3
+
+#include "sysdep.h"
+#undef ret /* Kludge for glibc */
+
+ .text
+ .align 8
+LC0: .double 0r4294967296
+LC1: .double 0r2147483648
+
+ .align 4
+ .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+ !#PROLOGUE# 0
+ save %sp,-104,%sp
+ !#PROLOGUE# 1
+ st %i1,[%fp-8]
+ ld [%fp-8],%f10
+ sethi %hi(LC0),%o7
+ fitod %f10,%f4
+ ldd [%o7+%lo(LC0)],%f8
+ cmp %i1,0
+ bge L248
+ mov %i0,%i5
+ faddd %f4,%f8,%f4
+L248:
+ st %i2,[%fp-8]
+ ld [%fp-8],%f10
+ fmuld %f4,%f8,%f6
+ cmp %i2,0
+ bge L249
+ fitod %f10,%f2
+ faddd %f2,%f8,%f2
+L249:
+ st %i3,[%fp-8]
+ faddd %f6,%f2,%f2
+ ld [%fp-8],%f10
+ cmp %i3,0
+ bge L250
+ fitod %f10,%f4
+ faddd %f4,%f8,%f4
+L250:
+ fdivd %f2,%f4,%f2
+ sethi %hi(LC1),%o7
+ ldd [%o7+%lo(LC1)],%f4
+ fcmped %f2,%f4
+ nop
+ fbge,a L251
+ fsubd %f2,%f4,%f2
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ b L252
+ ld [%fp-8],%i4
+L251:
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ ld [%fp-8],%i4
+ sethi %hi(-2147483648),%g2
+ xor %i4,%g2,%i4
+L252:
+ umul %i3,%i4,%g3
+ rd %y,%i0
+ subcc %i2,%g3,%o7
+ subxcc %i1,%i0,%g0
+ be L253
+ cmp %o7,%i3
+
+ add %i4,-1,%i0
+ add %o7,%i3,%o7
+ st %o7,[%i5]
+ ret
+ restore
+L253:
+ blu L246
+ mov %i4,%i0
+ add %i4,1,%i0
+ sub %o7,%i3,%o7
+L246:
+ st %o7,[%i5]
+ ret
+ restore
+
diff --git a/comm/third_party/libgcrypt/random/ChangeLog-2011 b/comm/third_party/libgcrypt/random/ChangeLog-2011
new file mode 100644
index 0000000000..cd45c3d666
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/ChangeLog-2011
@@ -0,0 +1,191 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-09-08 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (_gcry_rndlinux_gather_random): Don't use select if
+ the fd number is too high. Reported by Jakub Bogusz.
+
+2010-10-18 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (registry_poll): Disable performace fata gathering if
+ GNUPG_RNDW32_NOPERF has been set.
+
+2010-04-27 Marcus Brinkmann <marcus@g10code.de>
+
+ * rndw32ce.c (fillup_buffer): Rewrite without using nested
+ functions, which are broken on arm/cegcc.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-24 Werner Koch <wk@g10code.com>
+
+ * rndw32.c: Revert all changes from 2010-01-21.
+
+ * rndw32ce.c: New.
+ * Makefile.am (EXTRA_librandom_la_SOURCES): Add it.
+ * random-csprng.c (getfnc_gather_random)
+ (getfnc_fast_random_poll) [USE_RNDW32CE]: Use rndw32ce.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (read_mbm_data) [W32CE]: Do not build.
+ (slow_gatherer) [W32CE]: Do not call read_mbm_data.
+ (_gcry_rndw32_gather_random_fast) [W32CE]: Exclude some calls.
+ (_gcry_rndw32_gather_random): Adjust version test for WindowsCE.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (system_is_w2000): New.
+ (_gcry_rndw32_gather_random): Set it.
+ (slow_gatherer): Ignore SystemObjectInformation on W2000. Fixes
+ bug#1167.
+
+2009-07-09 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (_gcry_rndlinux_gather_random): Print real values for
+ the progess function and call it before blocking. Suggested by
+ Christian Grothoff.
+ * rndunix.c (slow_poll): Add similar, but not yet functional, code.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * rndhw.c (poll_padlock): Asm change from Fedora.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * random.c (_gcry_random_deinit_external_test): Do not return a
+ value. Reported Albert Chin.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * random-fips.c (x931_aes_driver): No re-seeding with test contexts.
+ (_gcry_rngfips_init_external_test): Fix setting of test_dt_ptr.
+ (struct rng_context): Add flag TEST_NO_DUP_CHECK.
+ (x931_aes_driver): Use that flag.
+ (_gcry_rngfips_init_external_test): Add arg FLAGS and use it to
+ modify the test.
+ * random.c (_gcry_random_init_external_test): Pass FLAGS.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * random.c (_gcry_random_init_external_test): New.
+ (_gcry_random_run_external_test): New.
+ (_gcry_random_deinit_external_test): New.
+ * random-fips.c (struct rng_context): Turn TEST_DT_COUNTER into a
+ 32 bit integer.
+ (x931_get_dt): Ditto.
+ (selftest_kat): Intialize it accordingly.
+ (_gcry_rngfips_init_external_test): New.
+ (_gcry_rngfips_run_external_test): New.
+ (_gcry_rngfips_deinit_external_test): New.
+
+2008-09-05 Werner Koch <wk@g10code.com>
+
+ * random.c (_gcry_random_selftest): Return success if not in fips
+ mode.
+
+2008-09-01 Werner Koch <wk@g10code.com>
+
+ * random-fips.c (x931_get_dt) [W32]: Do not use getppid.
+ (get_entropy): Prepare for use under Windows.
+ (_gcry_rngfips_selftest): Ditto.
+ (entropy_collect_cb): Make sure that the gatherer never overflows
+ the buffers.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * random-fips.c (SEED_TTL): New.
+ (struct rng_context): Add USE_COUNTER, remove NEED_STRONG_ENTROPY.
+ (x931_aes_driver): Do re-seeding if required.
+ (x931_generate_key, x931_generate_seed): Factor common code out to ..
+ (get_entropy): .. new. Always use /dev/random.
+ (x931_generate_key): Seed key for nonce_context from std_rng_context.
+ (x931_reseed): New. Seed nonce context from std_rng_context.
+ (get_random): Use x931_reseed.
+ (_gcry_rngfips_selftest): Return an error if no /dev/radom support
+ has been compiled in.
+ (get_random): Remove locking.
+ (_gcry_rngfips_randomize, _gcry_rngfips_create_nonce): Lock here.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c (connect_to_socket): Use GPG_ERR_ENAMETOOLONG.
+
+2008-08-25 Werner Koch <wk@g10code.com>
+
+ * random-fips.c (x931_aes): Take datetime_GT from an arg.
+ (x931_aes_driver): Call x931_get_dt here.
+ (x931_get_dt): Implement the KAT hack.
+ (x931_generate_seed): Copy the seed value to the provided buffer.
+ (selftest_kat): New.
+
+2008-08-22 Werner Koch <wk@g10code.com>
+
+ * random.c (_gcry_update_random_seed_file): Move operational check
+ to _gcry_vcontrol.
+ (_gcry_fast_random_poll): Ditto.
+ (_gcry_random_selftest): New.
+ * random-fips.c (_gcry_rngfips_selftest): New.
+
+2008-08-21 Werner Koch <wk@g10code.com>
+
+ * random-fips.c: Finish implementation.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * random-fips.c: New.
+
+ * random-csprng.c (process-cb, progress_cb_data): Move to
+ random.c.
+ (_gcry_register_random_progress, _gcry_random_progress): Ditto.
+ (_gcry_random_initialize): Rename to _gcry_rngcsprng_initialize.
+ (_gcry_random_dump_stats): Rename to _gcry_rngcsprng_dump_stats.
+ (_gcry_secure_random_alloc): Rename to
+ _gcry_rngcsprng_secure_alloc.
+ (_gcry_enable_quick_random_gen): Rename to
+ _gcry_rngcsprng_enable_quick_gen.
+ (_gcry_set_random_daemon_socket): Rename to
+ _gcry_rngcsprng_set_daemon_socket.
+ (_gcry_use_random_daemon): Rename to _gcry_rngcsprng_use_daemon.
+ (_gcry_random_is_faked): Rename to _gcry_rngcsprng_is_faked.
+ (gcry_random_add_bytes): Rename to _gcry_rngcsprng_add_bytes.
+ (gcry_random_bytes): Remove
+ (gcry_random_bytes_secure): Remove.
+ (gcry_randomize): Rename to _gcry_rngcsprng_randomize.
+ (_gcry_set_random_seed_file): Rename to
+ _gcry_rngcsprng_set_seed_file.
+ (_gcry_update_random_seed_file): Rename to
+ _gcry_rngcsprng_update_seed_file.
+ (_gcry_fast_random_poll): Rename to _gcry_rngcsprng_fast_poll.
+ (gcry_create_nonce): Rename to _gcry_rngcsprng_create_nonce.
+
+ * random.c: Factor all code out to random-csprng.c and implement
+ wrapper functions.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c, random.h, rndhw.c, rndunix.c, rand-internal.h *
+ random.c, rndegd.c, rndlinux.c, rndw32.c: Move from ../cipher/ to
+ here.
+ * Makefile.am: New.
+
+ Copyright 2008, 2009 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/random/Makefile.am b/comm/third_party/libgcrypt/random/Makefile.am
new file mode 100644
index 0000000000..7e6e6f032f
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/Makefile.am
@@ -0,0 +1,69 @@
+# Makefile for cipher modules
+# Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+
+# 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
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+
+noinst_LTLIBRARIES = librandom.la
+
+GCRYPT_MODULES = @GCRYPT_RANDOM@
+
+librandom_la_DEPENDENCIES = $(GCRYPT_MODULES)
+librandom_la_LIBADD = $(GCRYPT_MODULES)
+
+librandom_la_SOURCES = \
+random.c random.h \
+rand-internal.h \
+random-csprng.c \
+random-drbg.c \
+random-system.c \
+rndjent.c \
+rndhw.c
+
+if USE_RANDOM_DAEMON
+librandom_la_SOURCES += random-daemon.c
+endif USE_RANDOM_DAEMON
+
+
+EXTRA_librandom_la_SOURCES = \
+rndlinux.c \
+rndegd.c \
+rndunix.c \
+rndw32.c \
+rndw32ce.c \
+jitterentropy-base.c jitterentropy.h jitterentropy-base-user.h
+
+
+# The rndjent module needs to be compiled without optimization. */
+if ENABLE_O_FLAG_MUNGING
+o_flag_munging = sed -e 's/-O\([1-9sg][1-9sg]*\)/-O0/g' -e 's/-Ofast/-O0/g'
+else
+o_flag_munging = cat
+endif
+
+rndjent.o: $(srcdir)/rndjent.c jitterentropy-base-user.h \
+ $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h
+ `echo $(COMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) `
+
+rndjent.lo: $(srcdir)/rndjent.c jitterentropy-base-user.h \
+ $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h
+ `echo $(LTCOMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) `
diff --git a/comm/third_party/libgcrypt/random/Makefile.in b/comm/third_party/libgcrypt/random/Makefile.in
new file mode 100644
index 0000000000..f9489de14b
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/Makefile.in
@@ -0,0 +1,744 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for cipher modules
+# Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@USE_RANDOM_DAEMON_TRUE@am__append_1 = random-daemon.c
+subdir = random
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am__librandom_la_SOURCES_DIST = random.c random.h rand-internal.h \
+ random-csprng.c random-drbg.c random-system.c rndjent.c \
+ rndhw.c random-daemon.c
+@USE_RANDOM_DAEMON_TRUE@am__objects_1 = random-daemon.lo
+am_librandom_la_OBJECTS = random.lo random-csprng.lo random-drbg.lo \
+ random-system.lo rndjent.lo rndhw.lo $(am__objects_1)
+librandom_la_OBJECTS = $(am_librandom_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/jitterentropy-base.Plo \
+ ./$(DEPDIR)/random-csprng.Plo ./$(DEPDIR)/random-daemon.Plo \
+ ./$(DEPDIR)/random-drbg.Plo ./$(DEPDIR)/random-system.Plo \
+ ./$(DEPDIR)/random.Plo ./$(DEPDIR)/rndegd.Plo \
+ ./$(DEPDIR)/rndhw.Plo ./$(DEPDIR)/rndjent.Plo \
+ ./$(DEPDIR)/rndlinux.Plo ./$(DEPDIR)/rndunix.Plo \
+ ./$(DEPDIR)/rndw32.Plo ./$(DEPDIR)/rndw32ce.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(librandom_la_SOURCES) $(EXTRA_librandom_la_SOURCES)
+DIST_SOURCES = $(am__librandom_la_SOURCES_DIST) \
+ $(EXTRA_librandom_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+noinst_LTLIBRARIES = librandom.la
+GCRYPT_MODULES = @GCRYPT_RANDOM@
+librandom_la_DEPENDENCIES = $(GCRYPT_MODULES)
+librandom_la_LIBADD = $(GCRYPT_MODULES)
+librandom_la_SOURCES = random.c random.h rand-internal.h \
+ random-csprng.c random-drbg.c random-system.c rndjent.c \
+ rndhw.c $(am__append_1)
+EXTRA_librandom_la_SOURCES = \
+rndlinux.c \
+rndegd.c \
+rndunix.c \
+rndw32.c \
+rndw32ce.c \
+jitterentropy-base.c jitterentropy.h jitterentropy-base-user.h
+
+@ENABLE_O_FLAG_MUNGING_FALSE@o_flag_munging = cat
+
+# The rndjent module needs to be compiled without optimization. */
+@ENABLE_O_FLAG_MUNGING_TRUE@o_flag_munging = sed -e 's/-O\([1-9sg][1-9sg]*\)/-O0/g' -e 's/-Ofast/-O0/g'
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu random/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu random/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+librandom.la: $(librandom_la_OBJECTS) $(librandom_la_DEPENDENCIES) $(EXTRA_librandom_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(librandom_la_OBJECTS) $(librandom_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jitterentropy-base.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-csprng.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-daemon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-drbg.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-system.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndegd.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndhw.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndjent.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndlinux.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndunix.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndw32.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndw32ce.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/jitterentropy-base.Plo
+ -rm -f ./$(DEPDIR)/random-csprng.Plo
+ -rm -f ./$(DEPDIR)/random-daemon.Plo
+ -rm -f ./$(DEPDIR)/random-drbg.Plo
+ -rm -f ./$(DEPDIR)/random-system.Plo
+ -rm -f ./$(DEPDIR)/random.Plo
+ -rm -f ./$(DEPDIR)/rndegd.Plo
+ -rm -f ./$(DEPDIR)/rndhw.Plo
+ -rm -f ./$(DEPDIR)/rndjent.Plo
+ -rm -f ./$(DEPDIR)/rndlinux.Plo
+ -rm -f ./$(DEPDIR)/rndunix.Plo
+ -rm -f ./$(DEPDIR)/rndw32.Plo
+ -rm -f ./$(DEPDIR)/rndw32ce.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/jitterentropy-base.Plo
+ -rm -f ./$(DEPDIR)/random-csprng.Plo
+ -rm -f ./$(DEPDIR)/random-daemon.Plo
+ -rm -f ./$(DEPDIR)/random-drbg.Plo
+ -rm -f ./$(DEPDIR)/random-system.Plo
+ -rm -f ./$(DEPDIR)/random.Plo
+ -rm -f ./$(DEPDIR)/rndegd.Plo
+ -rm -f ./$(DEPDIR)/rndhw.Plo
+ -rm -f ./$(DEPDIR)/rndjent.Plo
+ -rm -f ./$(DEPDIR)/rndlinux.Plo
+ -rm -f ./$(DEPDIR)/rndunix.Plo
+ -rm -f ./$(DEPDIR)/rndw32.Plo
+ -rm -f ./$(DEPDIR)/rndw32ce.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+rndjent.o: $(srcdir)/rndjent.c jitterentropy-base-user.h \
+ $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h
+ `echo $(COMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) `
+
+rndjent.lo: $(srcdir)/rndjent.c jitterentropy-base-user.h \
+ $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h
+ `echo $(LTCOMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) `
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/random/jitterentropy-base-user.h b/comm/third_party/libgcrypt/random/jitterentropy-base-user.h
new file mode 100644
index 0000000000..8a8dbd5581
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/jitterentropy-base-user.h
@@ -0,0 +1,134 @@
+/*
+ * Non-physical true random number generator based on timing jitter.
+ *
+ * Copyright Stephan Mueller <smueller@chronox.de>, 2013
+ *
+ * License
+ * =======
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#ifndef GCRYPT_JITTERENTROPY_BASE_USER_H
+#define GCRYPT_JITTERENTROPY_BASE_USER_H
+
+/*
+ * This is Libgcrypt specific platform dependent code. We use a
+ * separate file because jitterentropy.h expects such a file.
+ */
+
+#ifndef USE_JENT
+# error This file expects to be included from rndjent.c (via jitterentropy.h)
+#endif
+#ifndef HAVE_STDINT_H
+# error This module needs stdint.h - try ./configure --disable-jent-support
+#endif
+
+
+/* When using the libgcrypt secure memory mechanism, all precautions
+ * are taken to protect our state. If the user disables secmem during
+ * runtime, it is his decision and we thus try not to overrule his
+ * decision for less memory protection. */
+#define JENT_CPU_JITTERENTROPY_SECURE_MEMORY 1
+#define jent_zalloc(n) _gcry_calloc_secure (1, (n))
+
+
+static void
+jent_get_nstime(u64 *out)
+{
+#if USE_JENT == JENT_USES_RDTSC
+
+ u32 t_eax, t_edx;
+
+ asm volatile (".byte 0x0f,0x31\n\t"
+ : "=a" (t_eax), "=d" (t_edx)
+ );
+ *out = (((u64)t_edx << 32) | t_eax);
+
+#elif USE_JENT == JENT_USES_GETTIME
+
+ struct timespec tv;
+ u64 tmp;
+
+ /* On Linux we could use CLOCK_MONOTONIC(_RAW), but with
+ * CLOCK_REALTIME we get some nice extra entropy once in a while
+ * from the NTP actions that we want to use as well... though, we do
+ * not rely on that extra little entropy. */
+ if (!clock_gettime (CLOCK_REALTIME, &tv))
+ {
+ tmp = tv.tv_sec;
+ tmp = tmp << 32;
+ tmp = tmp | tv.tv_nsec;
+ }
+ else
+ tmp = 0;
+ *out = tmp;
+
+#elif USE_JENT == JENT_USES_READ_REAL_TIME
+
+ /* clock_gettime() on AIX returns a timer value that increments in
+ * steps of 1000. */
+ u64 tmp = 0;
+
+ timebasestruct_t aixtime;
+ read_real_time (&aixtime, TIMEBASE_SZ);
+ tmp = aixtime.tb_high;
+ tmp = tmp << 32;
+ tmp = tmp | aixtime.tb_low;
+ *out = tmp;
+
+#else
+# error No clock available in jent_get_nstime
+#endif
+}
+
+
+static GPGRT_INLINE void
+jent_zfree (void *ptr, unsigned int len)
+{
+ if (ptr)
+ {
+ wipememory (ptr, len);
+ _gcry_free (ptr);
+ }
+}
+
+
+static GPGRT_INLINE int
+jent_fips_enabled(void)
+{
+ return fips_mode();
+}
+
+
+#endif /* GCRYPT_JITTERENTROPY_BASE_USER_H */
diff --git a/comm/third_party/libgcrypt/random/jitterentropy-base.c b/comm/third_party/libgcrypt/random/jitterentropy-base.c
new file mode 100644
index 0000000000..ba435e1bdb
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/jitterentropy-base.c
@@ -0,0 +1,791 @@
+/*
+ * Non-physical true random number generator based on timing jitter.
+ *
+ * Copyright Stephan Mueller <smueller@chronox.de>, 2014 - 2017
+ *
+ * Design
+ * ======
+ *
+ * See documentation in doc/ folder.
+ *
+ * Interface
+ * =========
+ *
+ * See documentation in doc/ folder.
+ *
+ * License
+ * =======
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL2 are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#undef _FORTIFY_SOURCE
+#pragma GCC optimize ("O0")
+
+#include "jitterentropy.h"
+
+#ifndef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT
+ /* only check optimization in a compilation for real work */
+ #ifdef __OPTIMIZE__
+ #error "The CPU Jitter random number generator must not be compiled with optimizations. See documentation. Use the compiler switch -O0 for compiling jitterentropy-base.c."
+ #endif
+#endif
+
+#define MAJVERSION 2 /* API / ABI incompatible changes, functional changes that
+ * require consumer to be updated (as long as this number
+ * is zero, the API is not considered stable and can
+ * change without a bump of the major version) */
+#define MINVERSION 1 /* API compatible, ABI may change, functional
+ * enhancements only, consumer can be left unchanged if
+ * enhancements are not considered */
+#define PATCHLEVEL 0 /* API / ABI compatible, no functional changes, no
+ * enhancements, bug fixes only */
+
+/**
+ * jent_version() - Return machine-usable version number of jent library
+ *
+ * The function returns a version number that is monotonic increasing
+ * for newer versions. The version numbers are multiples of 100. For example,
+ * version 1.2.3 is converted to 1020300 -- the last two digits are reserved
+ * for future use.
+ *
+ * The result of this function can be used in comparing the version number
+ * in a calling program if version-specific calls need to be make.
+ *
+ * Return: Version number of kcapi library
+ */
+JENT_PRIVATE_STATIC
+unsigned int jent_version(void)
+{
+ unsigned int version = 0;
+
+ version = MAJVERSION * 1000000;
+ version += MINVERSION * 10000;
+ version += PATCHLEVEL * 100;
+
+ return version;
+}
+
+/**
+ * Update of the loop count used for the next round of
+ * an entropy collection.
+ *
+ * Input:
+ * @ec entropy collector struct -- may be NULL
+ * @bits is the number of low bits of the timer to consider
+ * @min is the number of bits we shift the timer value to the right at
+ * the end to make sure we have a guaranteed minimum value
+ *
+ * @return Newly calculated loop counter
+ */
+static uint64_t jent_loop_shuffle(struct rand_data *ec,
+ unsigned int bits, unsigned int min)
+{
+ uint64_t time = 0;
+ uint64_t shuffle = 0;
+ unsigned int i = 0;
+ unsigned int mask = (1<<bits) - 1;
+
+ jent_get_nstime(&time);
+ /*
+ * Mix the current state of the random number into the shuffle
+ * calculation to balance that shuffle a bit more.
+ */
+ if (ec)
+ time ^= ec->data;
+ /*
+ * We fold the time value as much as possible to ensure that as many
+ * bits of the time stamp are included as possible.
+ */
+ for (i = 0; (DATA_SIZE_BITS / bits) > i; i++) {
+ shuffle ^= time & mask;
+ time = time >> bits;
+ }
+
+ /*
+ * We add a lower boundary value to ensure we have a minimum
+ * RNG loop count.
+ */
+ return (shuffle + (1<<min));
+}
+
+/***************************************************************************
+ * Noise sources
+ ***************************************************************************/
+
+/**
+ * CPU Jitter noise source -- this is the noise source based on the CPU
+ * execution time jitter
+ *
+ * This function injects the individual bits of the time value into the
+ * entropy pool using an LFSR.
+ *
+ * The code is deliberately inefficient with respect to the bit shifting
+ * and shall stay that way. This function is the root cause why the code
+ * shall be compiled without optimization. This function not only acts as
+ * folding operation, but this function's execution is used to measure
+ * the CPU execution time jitter. Any change to the loop in this function
+ * implies that careful retesting must be done.
+ *
+ * Input:
+ * @ec entropy collector struct -- may be NULL
+ * @time time stamp to be injected
+ * @loop_cnt if a value not equal to 0 is set, use the given value as number of
+ * loops to perform the folding
+ *
+ * Output:
+ * updated ec->data
+ *
+ * @return Number of loops the folding operation is performed
+ */
+static uint64_t jent_lfsr_time(struct rand_data *ec, uint64_t time,
+ uint64_t loop_cnt)
+{
+ unsigned int i;
+ uint64_t j = 0;
+ uint64_t new = 0;
+#define MAX_FOLD_LOOP_BIT 4
+#define MIN_FOLD_LOOP_BIT 0
+ uint64_t fold_loop_cnt =
+ jent_loop_shuffle(ec, MAX_FOLD_LOOP_BIT, MIN_FOLD_LOOP_BIT);
+
+ /*
+ * testing purposes -- allow test app to set the counter, not
+ * needed during runtime
+ */
+ if (loop_cnt)
+ fold_loop_cnt = loop_cnt;
+ for (j = 0; j < fold_loop_cnt; j++) {
+ new = ec->data;
+ for (i = 1; (DATA_SIZE_BITS) >= i; i++) {
+ uint64_t tmp = time << (DATA_SIZE_BITS - i);
+
+ tmp = tmp >> (DATA_SIZE_BITS - 1);
+
+ /*
+ * Fibonacci LSFR with polynomial of
+ * x^64 + x^61 + x^56 + x^31 + x^28 + x^23 + 1 which is
+ * primitive according to
+ * http://poincare.matf.bg.ac.rs/~ezivkovm/publications/primpol1.pdf
+ * (the shift values are the polynomial values minus one
+ * due to counting bits from 0 to 63). As the current
+ * position is always the LSB, the polynomial only needs
+ * to shift data in from the left without wrap.
+ */
+ new ^= tmp;
+ new ^= ((new >> 63) & 1);
+ new ^= ((new >> 60) & 1);
+ new ^= ((new >> 55) & 1);
+ new ^= ((new >> 30) & 1);
+ new ^= ((new >> 27) & 1);
+ new ^= ((new >> 22) & 1);
+ new = rol64(new, 1);
+ }
+ }
+ ec->data = new;
+
+ return fold_loop_cnt;
+}
+
+/**
+ * Memory Access noise source -- this is a noise source based on variations in
+ * memory access times
+ *
+ * This function performs memory accesses which will add to the timing
+ * variations due to an unknown amount of CPU wait states that need to be
+ * added when accessing memory. The memory size should be larger than the L1
+ * caches as outlined in the documentation and the associated testing.
+ *
+ * The L1 cache has a very high bandwidth, albeit its access rate is usually
+ * slower than accessing CPU registers. Therefore, L1 accesses only add minimal
+ * variations as the CPU has hardly to wait. Starting with L2, significant
+ * variations are added because L2 typically does not belong to the CPU any more
+ * and therefore a wider range of CPU wait states is necessary for accesses.
+ * L3 and real memory accesses have even a wider range of wait states. However,
+ * to reliably access either L3 or memory, the ec->mem memory must be quite
+ * large which is usually not desirable.
+ *
+ * Input:
+ * @ec Reference to the entropy collector with the memory access data -- if
+ * the reference to the memory block to be accessed is NULL, this noise
+ * source is disabled
+ * @loop_cnt if a value not equal to 0 is set, use the given value as number of
+ * loops to perform the folding
+ *
+ * @return Number of memory access operations
+ */
+static unsigned int jent_memaccess(struct rand_data *ec, uint64_t loop_cnt)
+{
+ unsigned int wrap = 0;
+ uint64_t i = 0;
+#define MAX_ACC_LOOP_BIT 7
+#define MIN_ACC_LOOP_BIT 0
+ uint64_t acc_loop_cnt =
+ jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT);
+
+ if (NULL == ec || NULL == ec->mem)
+ return 0;
+ wrap = ec->memblocksize * ec->memblocks;
+
+ /*
+ * testing purposes -- allow test app to set the counter, not
+ * needed during runtime
+ */
+ if (loop_cnt)
+ acc_loop_cnt = loop_cnt;
+
+ for (i = 0; i < (ec->memaccessloops + acc_loop_cnt); i++) {
+ unsigned char *tmpval = ec->mem + ec->memlocation;
+ /*
+ * memory access: just add 1 to one byte,
+ * wrap at 255 -- memory access implies read
+ * from and write to memory location
+ */
+ *tmpval = (*tmpval + 1) & 0xff;
+ /*
+ * Addition of memblocksize - 1 to pointer
+ * with wrap around logic to ensure that every
+ * memory location is hit evenly
+ */
+ ec->memlocation = ec->memlocation + ec->memblocksize - 1;
+ ec->memlocation = ec->memlocation % wrap;
+ }
+ return i;
+}
+
+/***************************************************************************
+ * Start of entropy processing logic
+ ***************************************************************************/
+
+/**
+ * Stuck test by checking the:
+ * 1st derivation of the jitter measurement (time delta)
+ * 2nd derivation of the jitter measurement (delta of time deltas)
+ * 3rd derivation of the jitter measurement (delta of delta of time deltas)
+ *
+ * All values must always be non-zero.
+ *
+ * Input:
+ * @ec Reference to entropy collector
+ * @current_delta Jitter time delta
+ *
+ * @return
+ * 0 jitter measurement not stuck (good bit)
+ * 1 jitter measurement stuck (reject bit)
+ */
+static int jent_stuck(struct rand_data *ec, uint64_t current_delta)
+{
+ int64_t delta2 = ec->last_delta - current_delta;
+ int64_t delta3 = (uint64_t)delta2 - (uint64_t)ec->last_delta2;
+
+ ec->last_delta = current_delta;
+ ec->last_delta2 = delta2;
+
+ if (!current_delta || !delta2 || !delta3)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * This is the heart of the entropy generation: calculate time deltas and
+ * use the CPU jitter in the time deltas. The jitter is injected into the
+ * entropy pool.
+ *
+ * WARNING: ensure that ->prev_time is primed before using the output
+ * of this function! This can be done by calling this function
+ * and not using its result.
+ *
+ * Input:
+ * @entropy_collector Reference to entropy collector
+ *
+ * @return: result of stuck test
+ */
+static int jent_measure_jitter(struct rand_data *ec)
+{
+ uint64_t time = 0;
+ uint64_t current_delta = 0;
+ int stuck;
+
+ /* Invoke one noise source before time measurement to add variations */
+ jent_memaccess(ec, 0);
+
+ /*
+ * Get time stamp and calculate time delta to previous
+ * invocation to measure the timing variations
+ */
+ jent_get_nstime(&time);
+ current_delta = time - ec->prev_time;
+ ec->prev_time = time;
+
+ /* Now call the next noise sources which also injects the data */
+ jent_lfsr_time(ec, current_delta, 0);
+
+ /* Check whether we have a stuck measurement. */
+ stuck = jent_stuck(ec, current_delta);
+
+ /*
+ * Rotate the data buffer by a prime number (any odd number would
+ * do) to ensure that every bit position of the input time stamp
+ * has an even chance of being merged with a bit position in the
+ * entropy pool. We do not use one here as the adjacent bits in
+ * successive time deltas may have some form of dependency. The
+ * chosen value of 7 implies that the low 7 bits of the next
+ * time delta value is concatenated with the current time delta.
+ */
+ if (!stuck)
+ ec->data = rol64(ec->data, 7);
+
+ return stuck;
+}
+
+/**
+ * Shuffle the pool a bit by mixing some value with a bijective function (XOR)
+ * into the pool.
+ *
+ * The function generates a mixer value that depends on the bits set and the
+ * location of the set bits in the random number generated by the entropy
+ * source. Therefore, based on the generated random number, this mixer value
+ * can have 2**64 different values. That mixer value is initialized with the
+ * first two SHA-1 constants. After obtaining the mixer value, it is XORed into
+ * the random number.
+ *
+ * The mixer value is not assumed to contain any entropy. But due to the XOR
+ * operation, it can also not destroy any entropy present in the entropy pool.
+ *
+ * Input:
+ * @entropy_collector Reference to entropy collector
+ */
+static void jent_stir_pool(struct rand_data *entropy_collector)
+{
+ /*
+ * to shut up GCC on 32 bit, we have to initialize the 64 variable
+ * with two 32 bit variables
+ */
+ union c {
+ uint64_t uint64;
+ uint32_t uint32[2];
+ };
+ /*
+ * This constant is derived from the first two 32 bit initialization
+ * vectors of SHA-1 as defined in FIPS 180-4 section 5.3.1
+ */
+ union c constant;
+ /*
+ * The start value of the mixer variable is derived from the third
+ * and fourth 32 bit initialization vector of SHA-1 as defined in
+ * FIPS 180-4 section 5.3.1
+ */
+ union c mixer;
+ unsigned int i = 0;
+
+ /* Ensure that the function implements a constant time operation. */
+ union c throw_away;
+
+ /*
+ * Store the SHA-1 constants in reverse order to make up the 64 bit
+ * value -- this applies to a little endian system, on a big endian
+ * system, it reverses as expected. But this really does not matter
+ * as we do not rely on the specific numbers. We just pick the SHA-1
+ * constants as they have a good mix of bit set and unset.
+ */
+ constant.uint32[1] = 0x67452301;
+ constant.uint32[0] = 0xefcdab89;
+ mixer.uint32[1] = 0x98badcfe;
+ mixer.uint32[0] = 0x10325476;
+
+ for (i = 0; i < DATA_SIZE_BITS; i++) {
+ /*
+ * get the i-th bit of the input random number and only XOR
+ * the constant into the mixer value when that bit is set
+ */
+ if ((entropy_collector->data >> i) & 1)
+ mixer.uint64 ^= constant.uint64;
+ else
+ throw_away.uint64 ^= constant.uint64;
+ mixer.uint64 = rol64(mixer.uint64, 1);
+ }
+ entropy_collector->data ^= mixer.uint64;
+}
+
+/**
+ * Generator of one 64 bit random number
+ * Function fills rand_data->data
+ *
+ * Input:
+ * @ec Reference to entropy collector
+ */
+static void jent_gen_entropy(struct rand_data *ec)
+{
+ unsigned int k = 0;
+
+ /* priming of the ->prev_time value */
+ jent_measure_jitter(ec);
+
+ while (1) {
+ /* If a stuck measurement is received, repeat measurement */
+ if (jent_measure_jitter(ec))
+ continue;
+
+ /*
+ * We multiply the loop value with ->osr to obtain the
+ * oversampling rate requested by the caller
+ */
+ if (++k >= (DATA_SIZE_BITS * ec->osr))
+ break;
+ }
+ if (ec->stir)
+ jent_stir_pool(ec);
+}
+
+/**
+ * The continuous test required by FIPS 140-2 -- the function automatically
+ * primes the test if needed.
+ *
+ * Return:
+ * 0 if FIPS test passed
+ * < 0 if FIPS test failed
+ */
+static int jent_fips_test(struct rand_data *ec)
+{
+ if (ec->fips_enabled == -1)
+ return 0;
+
+ if (ec->fips_enabled == 0) {
+ if (!jent_fips_enabled()) {
+ ec->fips_enabled = -1;
+ return 0;
+ } else
+ ec->fips_enabled = 1;
+ }
+
+ /* prime the FIPS test */
+ if (!ec->old_data) {
+ ec->old_data = ec->data;
+ jent_gen_entropy(ec);
+ }
+
+ if (ec->data == ec->old_data)
+ return -1;
+
+ ec->old_data = ec->data;
+
+ return 0;
+}
+
+/**
+ * Entry function: Obtain entropy for the caller.
+ *
+ * This function invokes the entropy gathering logic as often to generate
+ * as many bytes as requested by the caller. The entropy gathering logic
+ * creates 64 bit per invocation.
+ *
+ * This function truncates the last 64 bit entropy value output to the exact
+ * size specified by the caller.
+ *
+ * Input:
+ * @ec Reference to entropy collector
+ * @data pointer to buffer for storing random data -- buffer must already
+ * exist
+ * @len size of the buffer, specifying also the requested number of random
+ * in bytes
+ *
+ * @return number of bytes returned when request is fulfilled or an error
+ *
+ * The following error codes can occur:
+ * -1 entropy_collector is NULL
+ * -2 FIPS test failed
+ */
+JENT_PRIVATE_STATIC
+ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len)
+{
+ char *p = data;
+ size_t orig_len = len;
+
+ if (NULL == ec)
+ return -1;
+
+ while (0 < len) {
+ size_t tocopy;
+
+ jent_gen_entropy(ec);
+ if (jent_fips_test(ec))
+ return -2;
+
+ if ((DATA_SIZE_BITS / 8) < len)
+ tocopy = (DATA_SIZE_BITS / 8);
+ else
+ tocopy = len;
+ memcpy(p, &ec->data, tocopy);
+
+ len -= tocopy;
+ p += tocopy;
+ }
+
+ /*
+ * To be on the safe side, we generate one more round of entropy
+ * which we do not give out to the caller. That round shall ensure
+ * that in case the calling application crashes, memory dumps, pages
+ * out, or due to the CPU Jitter RNG lingering in memory for long
+ * time without being moved and an attacker cracks the application,
+ * all he reads in the entropy pool is a value that is NEVER EVER
+ * being used for anything. Thus, he does NOT see the previous value
+ * that was returned to the caller for cryptographic purposes.
+ */
+ /*
+ * If we use secured memory, do not use that precaution as the secure
+ * memory protects the entropy pool. Moreover, note that using this
+ * call reduces the speed of the RNG by up to half
+ */
+#ifndef CONFIG_CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY
+ jent_gen_entropy(ec);
+#endif
+ return orig_len;
+}
+
+/***************************************************************************
+ * Initialization logic
+ ***************************************************************************/
+
+JENT_PRIVATE_STATIC
+struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
+ unsigned int flags)
+{
+ struct rand_data *entropy_collector;
+
+ entropy_collector = jent_zalloc(sizeof(struct rand_data));
+ if (NULL == entropy_collector)
+ return NULL;
+
+ if (!(flags & JENT_DISABLE_MEMORY_ACCESS)) {
+ /* Allocate memory for adding variations based on memory
+ * access
+ */
+ entropy_collector->mem =
+ (unsigned char *)jent_zalloc(JENT_MEMORY_SIZE);
+ if (NULL == entropy_collector->mem) {
+ jent_zfree(entropy_collector, sizeof(struct rand_data));
+ return NULL;
+ }
+ entropy_collector->memblocksize = JENT_MEMORY_BLOCKSIZE;
+ entropy_collector->memblocks = JENT_MEMORY_BLOCKS;
+ entropy_collector->memaccessloops = JENT_MEMORY_ACCESSLOOPS;
+ }
+
+ /* verify and set the oversampling rate */
+ if (0 == osr)
+ osr = 1; /* minimum sampling rate is 1 */
+ entropy_collector->osr = osr;
+
+ entropy_collector->stir = 1;
+ if (flags & JENT_DISABLE_STIR)
+ entropy_collector->stir = 0;
+ if (flags & JENT_DISABLE_UNBIAS)
+ entropy_collector->disable_unbias = 1;
+
+ /* fill the data pad with non-zero values */
+ jent_gen_entropy(entropy_collector);
+
+ return entropy_collector;
+}
+
+JENT_PRIVATE_STATIC
+void jent_entropy_collector_free(struct rand_data *entropy_collector)
+{
+ if (NULL != entropy_collector) {
+ if (NULL != entropy_collector->mem) {
+ jent_zfree(entropy_collector->mem, JENT_MEMORY_SIZE);
+ entropy_collector->mem = NULL;
+ }
+ jent_zfree(entropy_collector, sizeof(struct rand_data));
+ }
+}
+
+JENT_PRIVATE_STATIC
+int jent_entropy_init(void)
+{
+ int i;
+ uint64_t delta_sum = 0;
+ uint64_t old_delta = 0;
+ int time_backwards = 0;
+ int count_mod = 0;
+ int count_stuck = 0;
+ struct rand_data ec;
+
+ memset(&ec, 0, sizeof(ec));
+
+ /* We could perform statistical tests here, but the problem is
+ * that we only have a few loop counts to do testing. These
+ * loop counts may show some slight skew and we produce
+ * false positives.
+ *
+ * Moreover, only old systems show potentially problematic
+ * jitter entropy that could potentially be caught here. But
+ * the RNG is intended for hardware that is available or widely
+ * used, but not old systems that are long out of favor. Thus,
+ * no statistical tests.
+ */
+
+ /*
+ * We could add a check for system capabilities such as clock_getres or
+ * check for CONFIG_X86_TSC, but it does not make much sense as the
+ * following sanity checks verify that we have a high-resolution
+ * timer.
+ */
+ /*
+ * TESTLOOPCOUNT needs some loops to identify edge systems. 100 is
+ * definitely too little.
+ */
+#define TESTLOOPCOUNT 300
+#define CLEARCACHE 100
+ for (i = 0; (TESTLOOPCOUNT + CLEARCACHE) > i; i++) {
+ uint64_t time = 0;
+ uint64_t time2 = 0;
+ uint64_t delta = 0;
+ unsigned int lowdelta = 0;
+ int stuck;
+
+ /* Invoke core entropy collection logic */
+ jent_get_nstime(&time);
+ ec.prev_time = time;
+ jent_lfsr_time(&ec, time, 0);
+ jent_get_nstime(&time2);
+
+ /* test whether timer works */
+ if (!time || !time2)
+ return ENOTIME;
+ delta = time2 - time;
+ /*
+ * test whether timer is fine grained enough to provide
+ * delta even when called shortly after each other -- this
+ * implies that we also have a high resolution timer
+ */
+ if (!delta)
+ return ECOARSETIME;
+
+ stuck = jent_stuck(&ec, delta);
+
+ /*
+ * up to here we did not modify any variable that will be
+ * evaluated later, but we already performed some work. Thus we
+ * already have had an impact on the caches, branch prediction,
+ * etc. with the goal to clear it to get the worst case
+ * measurements.
+ */
+ if (CLEARCACHE > i)
+ continue;
+
+ if (stuck)
+ count_stuck++;
+
+ /* test whether we have an increasing timer */
+ if (!(time2 > time))
+ time_backwards++;
+
+ /* use 32 bit value to ensure compilation on 32 bit arches */
+ lowdelta = time2 - time;
+ if (!(lowdelta % 100))
+ count_mod++;
+
+ /*
+ * ensure that we have a varying delta timer which is necessary
+ * for the calculation of entropy -- perform this check
+ * only after the first loop is executed as we need to prime
+ * the old_data value
+ */
+ if (delta > old_delta)
+ delta_sum += (delta - old_delta);
+ else
+ delta_sum += (old_delta - delta);
+ old_delta = delta;
+ }
+
+ /*
+ * we allow up to three times the time running backwards.
+ * CLOCK_REALTIME is affected by adjtime and NTP operations. Thus,
+ * if such an operation just happens to interfere with our test, it
+ * should not fail. The value of 3 should cover the NTP case being
+ * performed during our test run.
+ */
+ if (3 < time_backwards)
+ return ENOMONOTONIC;
+
+ /*
+ * Variations of deltas of time must on average be larger
+ * than 1 to ensure the entropy estimation
+ * implied with 1 is preserved
+ */
+ if ((delta_sum) <= 1)
+ return EMINVARVAR;
+
+ /*
+ * Ensure that we have variations in the time stamp below 10 for at least
+ * 10% of all checks -- on some platforms, the counter increments in
+ * multiples of 100, but not always
+ */
+ if ((TESTLOOPCOUNT/10 * 9) < count_mod)
+ return ECOARSETIME;
+
+ /*
+ * If we have more than 90% stuck results, then this Jitter RNG is
+ * likely to not work well.
+ */
+ if (JENT_STUCK_INIT_THRES(TESTLOOPCOUNT) < count_stuck)
+ return ESTUCK;
+
+ return 0;
+}
+
+/***************************************************************************
+ * Statistical test logic not compiled for regular operation
+ ***************************************************************************/
+
+#ifdef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT
+/*
+ * Statistical test: return the time duration for the folding operation. If min
+ * is set, perform the given number of LFSR ops. Otherwise, allow the
+ * loop count shuffling to define the number of LFSR ops.
+ */
+JENT_PRIVATE_STATIC
+uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min)
+{
+ uint64_t time = 0;
+ uint64_t time2 = 0;
+
+ jent_get_nstime(&time);
+ jent_memaccess(ec, min);
+ jent_lfsr_time(ec, time, min);
+ jent_get_nstime(&time2);
+ return ((time2 - time));
+}
+#endif /* CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT */
diff --git a/comm/third_party/libgcrypt/random/jitterentropy.h b/comm/third_party/libgcrypt/random/jitterentropy.h
new file mode 100644
index 0000000000..3b7d14a18e
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/jitterentropy.h
@@ -0,0 +1,148 @@
+/*
+ * Non-physical true random number generator based on timing jitter.
+ *
+ * Copyright Stephan Mueller <smueller@chronox.de>, 2014
+ *
+ * License
+ * =======
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#ifndef _JITTERENTROPY_H
+#define _JITTERENTROPY_H
+
+#ifdef __KERNEL__
+#include "jitterentropy-base-kernel.h"
+#else
+#include "jitterentropy-base-user.h"
+#endif /* __KERNEL__ */
+
+/* The entropy pool */
+struct rand_data
+{
+ /* all data values that are vital to maintain the security
+ * of the RNG are marked as SENSITIVE. A user must not
+ * access that information while the RNG executes its loops to
+ * calculate the next random value. */
+ uint64_t data; /* SENSITIVE Actual random number */
+ uint64_t old_data; /* SENSITIVE Previous random number */
+ uint64_t prev_time; /* SENSITIVE Previous time stamp */
+#define DATA_SIZE_BITS ((sizeof(uint64_t)) * 8)
+ uint64_t last_delta; /* SENSITIVE stuck test */
+ int64_t last_delta2; /* SENSITIVE stuck test */
+ unsigned int osr; /* Oversample rate */
+ int fips_enabled; /* FIPS enabled? */
+ unsigned int stir:1; /* Post-processing stirring */
+ unsigned int disable_unbias:1; /* Deactivate Von-Neuman unbias */
+#define JENT_MEMORY_BLOCKS 64
+#define JENT_MEMORY_BLOCKSIZE 32
+#define JENT_MEMORY_ACCESSLOOPS 128
+#define JENT_MEMORY_SIZE (JENT_MEMORY_BLOCKS*JENT_MEMORY_BLOCKSIZE)
+ unsigned char *mem; /* Memory access location with size of
+ * memblocks * memblocksize */
+ unsigned int memlocation; /* Pointer to byte in *mem */
+ unsigned int memblocks; /* Number of memory blocks in *mem */
+ unsigned int memblocksize; /* Size of one memory block in bytes */
+ unsigned int memaccessloops; /* Number of memory accesses per random
+ * bit generation */
+};
+
+/* Flags that can be used to initialize the RNG */
+#define JENT_DISABLE_STIR (1<<0) /* Disable stirring the entropy pool */
+#define JENT_DISABLE_UNBIAS (1<<1) /* Disable the Von-Neuman Unbiaser */
+#define JENT_DISABLE_MEMORY_ACCESS (1<<2) /* Disable memory access for more
+ entropy, saves MEMORY_SIZE RAM for
+ entropy collector */
+
+/* -- BEGIN Main interface functions -- */
+
+#ifndef JENT_STUCK_INIT_THRES
+/*
+ * Per default, not more than 90% of all measurements during initialization
+ * are allowed to be stuck.
+ *
+ * It is allowed to change this value as required for the intended environment.
+ */
+#define JENT_STUCK_INIT_THRES(x) (x/10 * 9)
+#endif
+
+#ifdef JENT_PRIVATE_COMPILE
+# define JENT_PRIVATE_STATIC static
+#else /* JENT_PRIVATE_COMPILE */
+# define JENT_PRIVATE_STATIC
+#endif
+
+/* Number of low bits of the time value that we want to consider */
+/* get raw entropy */
+JENT_PRIVATE_STATIC
+ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len);
+/* initialize an instance of the entropy collector */
+JENT_PRIVATE_STATIC
+struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
+ unsigned int flags);
+/* clearing of entropy collector */
+JENT_PRIVATE_STATIC
+void jent_entropy_collector_free(struct rand_data *entropy_collector);
+
+/* initialization of entropy collector */
+JENT_PRIVATE_STATIC
+int jent_entropy_init(void);
+
+/* return version number of core library */
+JENT_PRIVATE_STATIC
+unsigned int jent_version(void);
+
+/* -- END of Main interface functions -- */
+
+/* -- BEGIN error codes for init function -- */
+#define ENOTIME 1 /* Timer service not available */
+#define ECOARSETIME 2 /* Timer too coarse for RNG */
+#define ENOMONOTONIC 3 /* Timer is not monotonic increasing */
+#define EMINVARIATION 4 /* Timer variations too small for RNG */
+#define EVARVAR 5 /* Timer does not produce variations of variations
+ (2nd derivation of time is zero) */
+#define EMINVARVAR 6 /* Timer variations of variations is too small */
+#define EPROGERR 7 /* Programming error */
+#define ESTUCK 8 /* Too many stuck results during init. */
+
+/* -- BEGIN statistical test functions only complied with CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -- */
+
+#ifdef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT
+JENT_PRIVATE_STATIC
+uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min);
+#endif /* CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT */
+
+/* -- END of statistical test function -- */
+
+#endif /* _JITTERENTROPY_H */
diff --git a/comm/third_party/libgcrypt/random/rand-internal.h b/comm/third_party/libgcrypt/random/rand-internal.h
new file mode 100644
index 0000000000..3422156957
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/rand-internal.h
@@ -0,0 +1,148 @@
+/* rand-internal.h - header to glue the random functions
+ * Copyright (C) 1998, 2002 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G10_RAND_INTERNAL_H
+#define G10_RAND_INTERNAL_H
+
+#include "../src/cipher-proto.h"
+
+/* Constants used to define the origin of random added to the pool.
+ The code is sensitive to the order of the values. */
+enum random_origins
+ {
+ RANDOM_ORIGIN_INIT = 0, /* Used only for initialization. */
+ RANDOM_ORIGIN_EXTERNAL = 1, /* Added from an external source. */
+ RANDOM_ORIGIN_FASTPOLL = 2, /* Fast random poll function. */
+ RANDOM_ORIGIN_SLOWPOLL = 3, /* Slow poll function. */
+ RANDOM_ORIGIN_EXTRAPOLL = 4 /* Used to mark an extra pool seed
+ due to a GCRY_VERY_STRONG_RANDOM
+ random request. */
+ };
+
+#define RANDOM_CONF_DISABLE_JENT 1
+#define RANDOM_CONF_ONLY_URANDOM 2
+
+
+/*-- random.c --*/
+unsigned int _gcry_random_read_conf (void);
+void _gcry_random_progress (const char *what, int printchar,
+ int current, int total);
+
+
+/*-- random-csprng.c --*/
+void _gcry_rngcsprng_initialize (int full);
+void _gcry_rngcsprng_close_fds (void);
+void _gcry_rngcsprng_dump_stats (void);
+void _gcry_rngcsprng_secure_alloc (void);
+void _gcry_rngcsprng_enable_quick_gen (void);
+void _gcry_rngcsprng_set_daemon_socket (const char *socketname);
+int _gcry_rngcsprng_use_daemon (int onoff);
+int _gcry_rngcsprng_is_faked (void);
+gcry_error_t _gcry_rngcsprng_add_bytes (const void *buf, size_t buflen,
+ int quality);
+void *_gcry_rngcsprng_get_bytes (size_t nbytes,
+ enum gcry_random_level level);
+void *_gcry_rngcsprng_get_bytes_secure (size_t nbytes,
+ enum gcry_random_level level);
+void _gcry_rngcsprng_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+void _gcry_rngcsprng_set_seed_file (const char *name);
+void _gcry_rngcsprng_update_seed_file (void);
+void _gcry_rngcsprng_fast_poll (void);
+
+/*-- random-drbg.c --*/
+void _gcry_rngdrbg_inititialize (int full);
+void _gcry_rngdrbg_close_fds (void);
+void _gcry_rngdrbg_dump_stats (void);
+int _gcry_rngdrbg_is_faked (void);
+gcry_error_t _gcry_rngdrbg_add_bytes (const void *buf, size_t buflen,
+ int quality);
+void _gcry_rngdrbg_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+gcry_error_t _gcry_rngdrbg_selftest (selftest_report_func_t report);
+
+/*-- random-system.c --*/
+void _gcry_rngsystem_initialize (int full);
+void _gcry_rngsystem_close_fds (void);
+void _gcry_rngsystem_dump_stats (void);
+int _gcry_rngsystem_is_faked (void);
+gcry_error_t _gcry_rngsystem_add_bytes (const void *buf, size_t buflen,
+ int quality);
+void _gcry_rngsystem_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+
+
+
+/*-- rndlinux.c --*/
+int _gcry_rndlinux_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+
+/*-- rndunix.c --*/
+int _gcry_rndunix_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+
+/*-- rndegd.c --*/
+int _gcry_rndegd_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+int _gcry_rndegd_connect_socket (int nofail);
+
+/*-- rndw32.c --*/
+int _gcry_rndw32_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+void _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin );
+
+/*-- rndw32ce.c --*/
+int _gcry_rndw32ce_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+void _gcry_rndw32ce_gather_random_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin );
+
+/*-- rndjent.c --*/
+size_t _gcry_rndjent_poll (void (*add)(const void*,
+ size_t, enum random_origins),
+ enum random_origins origin,
+ size_t length);
+void _gcry_rndjent_dump_stats (void);
+void _gcry_rndjent_fini (void);
+
+/*-- rndhw.c --*/
+int _gcry_rndhw_failed_p (void);
+void _gcry_rndhw_poll_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin);
+size_t _gcry_rndhw_poll_slow (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin, size_t req_length);
+
+
+
+#endif /*G10_RAND_INTERNAL_H*/
diff --git a/comm/third_party/libgcrypt/random/random-csprng.c b/comm/third_party/libgcrypt/random/random-csprng.c
new file mode 100644
index 0000000000..66f5786499
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/random-csprng.c
@@ -0,0 +1,1367 @@
+/* random-csprng.c - CSPRNG style random number generator (libgcrypt classic)
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ * 2007, 2008, 2010, 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This random number generator is modelled after the one described in
+ Peter Gutmann's 1998 Usenix Security Symposium paper: "Software
+ Generation of Practically Strong Random Numbers". See also chapter
+ 6 in his book "Cryptographic Security Architecture", New York,
+ 2004, ISBN 0-387-95387-6.
+
+ Note that the acronym CSPRNG stands for "Continuously Seeded
+ PseudoRandom Number Generator" as used in Peter's implementation of
+ the paper and not only for "Cryptographically Secure PseudoRandom
+ Number Generator".
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#ifdef HAVE_GETHRTIME
+#include <sys/times.h>
+#endif
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+#ifdef HAVE_GETRUSAGE
+#include <sys/resource.h>
+#endif
+#ifdef __MINGW32__
+#include <process.h>
+#endif
+#include "g10lib.h"
+#include "random.h"
+#include "rand-internal.h"
+#include "cipher.h" /* _gcry_sha1_hash_buffer */
+#include "../cipher/sha1.h" /* _gcry_sha1_mixblock */
+
+#ifndef RAND_MAX /* For SunOS. */
+#define RAND_MAX 32767
+#endif
+
+/* Check whether we can lock the seed file read write. */
+#if defined(HAVE_FCNTL) && defined(HAVE_FTRUNCATE) && !defined(HAVE_W32_SYSTEM)
+#define LOCK_SEED_FILE 1
+#else
+#define LOCK_SEED_FILE 0
+#endif
+
+/* Define the constant we use for transforming the pool at read-out. */
+#if SIZEOF_UNSIGNED_LONG == 8
+#define ADD_VALUE 0xa5a5a5a5a5a5a5a5
+#elif SIZEOF_UNSIGNED_LONG == 4
+#define ADD_VALUE 0xa5a5a5a5
+#else
+#error weird size for an unsigned long
+#endif
+
+/* Contstants pertaining to the hash pool. */
+#define BLOCKLEN 64 /* Hash this amount of bytes... */
+#define DIGESTLEN 20 /* ... into a digest of this length (sha-1). */
+/* POOLBLOCKS is the number of digests which make up the pool. */
+#define POOLBLOCKS 30
+/* POOLSIZE must be a multiple of the digest length to make the AND
+ operations faster, the size should also be a multiple of unsigned
+ long. */
+#define POOLSIZE (POOLBLOCKS*DIGESTLEN)
+#if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
+#error Please make sure that poolsize is a multiple of unsigned long
+#endif
+#define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
+
+
+/* RNDPOOL is the pool we use to collect the entropy and to stir it
+ up. Its allocated size is POOLSIZE+BLOCKLEN. Note that this is
+ also an indication on whether the module has been fully
+ initialized. */
+static unsigned char *rndpool;
+
+/* KEYPOOL is used as a scratch copy to read out random from RNDPOOL.
+ Its allocated size is also POOLSIZE+BLOCKLEN. */
+static unsigned char *keypool;
+
+/* This is the offset into RNDPOOL where the next random bytes are to
+ be mixed in. */
+static size_t pool_writepos;
+
+/* When reading data out of KEYPOOL, we start the read at different
+ positions. This variable keeps track on where to read next. */
+static size_t pool_readpos;
+
+/* This flag is set to true as soon as the pool has been completely
+ filled the first time. This may happen either by reading a seed
+ file or by adding enough entropy. */
+static int pool_filled;
+
+/* This counter is used to track whether the initial seeding has been
+ done with enough bytes from a reliable entropy source. */
+static size_t pool_filled_counter;
+
+/* If random of level GCRY_VERY_STRONG_RANDOM has been requested we
+ have stricter requirements on what kind of entropy is in the pool.
+ In particular POOL_FILLED is not sufficient. Thus we add some
+ extra seeding and set this flag to true if the extra seeding has
+ been done. */
+static int did_initial_extra_seeding;
+
+/* This variable is used to estimated the amount of fresh entropy
+ available in RNDPOOL. */
+static int pool_balance;
+
+/* After a mixing operation this variable will be set to true and
+ cleared if new entropy has been added or a remix is required for
+ other reasons. */
+static int just_mixed;
+
+/* The name of the seed file or NULL if no seed file has been defined.
+ The seed file needs to be registered at initialization time. We
+ keep a malloced copy here. */
+static char *seed_file_name;
+
+/* If a seed file has been registered and maybe updated on exit this
+ flag set. */
+static int allow_seed_file_update;
+
+/* Option flag set at initialiation time to force allocation of the
+ pool in secure memory. */
+static int secure_alloc;
+
+/* This function pointer is set to the actual entropy gathering
+ function during initialization. After initialization it is
+ guaranteed to point to function. (On systems without a random
+ gatherer module a dummy function is used).*/
+static int (*slow_gather_fnc)(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins, size_t, int);
+
+/* This function is set to the actual fast entropy gathering function
+ during initialization. If it is NULL, no such function is
+ available. */
+static void (*fast_gather_fnc)(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins);
+
+
+/* Option flag useful for debugging and the test suite. If set
+ requests for very strong random are degraded to strong random. Not
+ used by regular applications. */
+static int quick_test;
+
+/* This is the lock we use to protect all pool operations. */
+GPGRT_LOCK_DEFINE (pool_lock);
+
+/* This is a helper for assert calls. These calls are used to assert
+ that functions are called in a locked state. It is not meant to be
+ thread-safe but as a method to get aware of missing locks in the
+ test suite. */
+static int pool_is_locked;
+
+
+/* We keep some counters in this structure for the sake of the
+ _gcry_random_dump_stats () function. */
+static struct
+{
+ unsigned long mixrnd;
+ unsigned long mixkey;
+ unsigned long slowpolls;
+ unsigned long fastpolls;
+ unsigned long getbytes1;
+ unsigned long ngetbytes1;
+ unsigned long getbytes2;
+ unsigned long ngetbytes2;
+ unsigned long addbytes;
+ unsigned long naddbytes;
+} rndstats;
+
+
+
+/* --- Stuff pertaining to the random daemon support. --- */
+#ifdef USE_RANDOM_DAEMON
+
+/* If ALLOW_DAEMON is true, the module will try to use the random
+ daemon first. If the daemon has failed, this variable is set to
+ back to false and the code continues as normal. Note, we don't
+ test this flag in a locked state because a wrong value does not
+ harm and the trhead will find out itself that the daemon does not
+ work and set it (again) to false. */
+static int allow_daemon;
+
+/* During initialization, the user may set a non-default socket name
+ for accessing the random daemon. If this value is NULL, the
+ default name will be used. */
+static char *daemon_socket_name;
+
+#endif /*USE_RANDOM_DAEMON*/
+
+
+
+/* --- Prototypes --- */
+static void read_pool (byte *buffer, size_t length, int level );
+static void add_randomness (const void *buffer, size_t length,
+ enum random_origins origin);
+static void random_poll (void);
+static void do_fast_random_poll (void);
+static int (*getfnc_gather_random (void))(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins, size_t, int);
+static void (*getfnc_fast_random_poll (void))(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins);
+static void read_random_source (enum random_origins origin,
+ size_t length, int level);
+
+
+
+/* --- Functions --- */
+
+
+/* Basic initialization which is required to initialize mutexes and
+ such. It does not run a full initialization so that the filling of
+ the random pool can be delayed until it is actually needed. We
+ assume that this function is used before any concurrent access
+ happens. */
+static void
+initialize_basics(void)
+{
+ static int initialized;
+
+ if (!initialized)
+ {
+ initialized = 1;
+
+#ifdef USE_RANDOM_DAEMON
+ _gcry_daemon_initialize_basics ();
+#endif /*USE_RANDOM_DAEMON*/
+
+ /* Make sure that we are still using the values we have
+ traditionally used for the random levels. */
+ gcry_assert (GCRY_WEAK_RANDOM == 0
+ && GCRY_STRONG_RANDOM == 1
+ && GCRY_VERY_STRONG_RANDOM == 2);
+ }
+}
+
+/* Take the pool lock. */
+static void
+lock_pool (void)
+{
+ int err;
+
+ err = gpgrt_lock_lock (&pool_lock);
+ if (err)
+ log_fatal ("failed to acquire the pool lock: %s\n", gpg_strerror (err));
+ pool_is_locked = 1;
+}
+
+/* Release the pool lock. */
+static void
+unlock_pool (void)
+{
+ int err;
+
+ pool_is_locked = 0;
+ err = gpgrt_lock_unlock (&pool_lock);
+ if (err)
+ log_fatal ("failed to release the pool lock: %s\n", gpg_strerror (err));
+}
+
+
+/* Full initialization of this module. */
+static void
+initialize(void)
+{
+ /* Although the basic initialization should have happened already,
+ we call it here to make sure that all prerequisites are met. */
+ initialize_basics ();
+
+ /* Now we can look the pool and complete the initialization if
+ necessary. */
+ lock_pool ();
+ if (!rndpool)
+ {
+ /* The data buffer is allocated somewhat larger, so that we can
+ use this extra space (which is allocated in secure memory) as
+ a temporary hash buffer */
+ rndpool = (secure_alloc
+ ? xcalloc_secure (1, POOLSIZE + BLOCKLEN)
+ : xcalloc (1, POOLSIZE + BLOCKLEN));
+ keypool = (secure_alloc
+ ? xcalloc_secure (1, POOLSIZE + BLOCKLEN)
+ : xcalloc (1, POOLSIZE + BLOCKLEN));
+
+ /* Setup the slow entropy gathering function. The code requires
+ that this function exists. */
+ slow_gather_fnc = getfnc_gather_random ();
+
+ /* Setup the fast entropy gathering function. */
+ fast_gather_fnc = getfnc_fast_random_poll ();
+
+ }
+ unlock_pool ();
+}
+
+
+
+
+/* Initialize this random subsystem. If FULL is false, this function
+ merely calls the initialize and does not do anything more. Doing
+ this is not really required but when running in a threaded
+ environment we might get a race condition otherwise. */
+void
+_gcry_rngcsprng_initialize (int full)
+{
+ if (!full)
+ initialize_basics ();
+ else
+ initialize ();
+}
+
+
+/* Try to close the FDs of the random gather module. This is
+ currently only implemented for rndlinux. */
+void
+_gcry_rngcsprng_close_fds (void)
+{
+ lock_pool ();
+#if USE_RNDLINUX
+ _gcry_rndlinux_gather_random (NULL, 0, 0, 0);
+ pool_filled = 0; /* Force re-open on next use. */
+#endif
+ unlock_pool ();
+}
+
+
+void
+_gcry_rngcsprng_dump_stats (void)
+{
+ /* In theory we would need to lock the stats here. However this
+ function is usually called during cleanup and then we _might_ run
+ into problems. */
+
+ log_info ("random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n"
+ " outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu%s\n",
+ POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls,
+ rndstats.naddbytes, rndstats.addbytes,
+ rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
+ rndstats.ngetbytes2, rndstats.getbytes2,
+ _gcry_rndhw_failed_p()? " (hwrng failed)":"");
+}
+
+
+/* This function should be called during initialization and before
+ initialization of this module to place the random pools into secure
+ memory. */
+void
+_gcry_rngcsprng_secure_alloc (void)
+{
+ secure_alloc = 1;
+}
+
+
+/* This may be called before full initialization to degrade the
+ quality of the RNG for the sake of a faster running test suite. */
+void
+_gcry_rngcsprng_enable_quick_gen (void)
+{
+ quick_test = 1;
+}
+
+
+void
+_gcry_rngcsprng_set_daemon_socket (const char *socketname)
+{
+#ifdef USE_RANDOM_DAEMON
+ if (daemon_socket_name)
+ BUG ();
+
+ daemon_socket_name = gcry_xstrdup (socketname);
+#else /*!USE_RANDOM_DAEMON*/
+ (void)socketname;
+#endif /*!USE_RANDOM_DAEMON*/
+}
+
+/* With ONOFF set to 1, enable the use of the daemon. With ONOFF set
+ to 0, disable the use of the daemon. With ONOF set to -1, return
+ whether the daemon has been enabled. */
+int
+_gcry_rngcsprng_use_daemon (int onoff)
+{
+#ifdef USE_RANDOM_DAEMON
+ int last;
+
+ /* This is not really thread safe. However it is expected that this
+ function is being called during initialization and at that point
+ we are for other reasons not really thread safe. We do not want
+ to lock it because we might eventually decide that this function
+ may even be called prior to gcry_check_version. */
+ last = allow_daemon;
+ if (onoff != -1)
+ allow_daemon = onoff;
+
+ return last;
+#else /*!USE_RANDOM_DAEMON*/
+ (void)onoff;
+ return 0;
+#endif /*!USE_RANDOM_DAEMON*/
+}
+
+
+/* This function returns true if no real RNG is available or the
+ quality of the RNG has been degraded for test purposes. */
+int
+_gcry_rngcsprng_is_faked (void)
+{
+ /* We need to initialize due to the runtime determination of
+ available entropy gather modules. */
+ initialize();
+ return quick_test;
+}
+
+
+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY
+ should be in the range of 0..100 to indicate the goodness of the
+ entropy added, or -1 for goodness not known. */
+gcry_error_t
+_gcry_rngcsprng_add_bytes (const void *buf, size_t buflen, int quality)
+{
+ size_t nbytes;
+ const char *bufptr;
+
+ if (quality == -1)
+ quality = 35;
+ else if (quality > 100)
+ quality = 100;
+ else if (quality < 0)
+ quality = 0;
+
+ if (!buf)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ if (!buflen || quality < 10)
+ return 0; /* Take a shortcut. */
+
+ /* Because we don't increment the entropy estimation with FASTPOLL,
+ we don't need to take lock that estimation while adding from an
+ external source. This limited entropy estimation also means that
+ we can't take QUALITY into account. */
+ initialize_basics ();
+ bufptr = buf;
+ while (buflen)
+ {
+ nbytes = buflen > POOLSIZE? POOLSIZE : buflen;
+ lock_pool ();
+ if (rndpool)
+ add_randomness (bufptr, nbytes, RANDOM_ORIGIN_EXTERNAL);
+ unlock_pool ();
+ bufptr += nbytes;
+ buflen -= nbytes;
+ }
+ return 0;
+}
+
+
+/* Public function to fill the buffer with LENGTH bytes of
+ cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is
+ not very strong, GCRY_STRONG_RANDOM is strong enough for most
+ usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but
+ may be very slow. */
+void
+_gcry_rngcsprng_randomize (void *buffer, size_t length,
+ enum gcry_random_level level)
+{
+ unsigned char *p;
+
+ /* Make sure we are initialized. */
+ initialize ();
+
+ /* Handle our hack used for regression tests of Libgcrypt. */
+ if ( quick_test && level > GCRY_STRONG_RANDOM )
+ level = GCRY_STRONG_RANDOM;
+
+ /* Make sure the level is okay. */
+ level &= 3;
+
+#ifdef USE_RANDOM_DAEMON
+ if (allow_daemon
+ && !_gcry_daemon_randomize (daemon_socket_name, buffer, length, level))
+ return; /* The daemon succeeded. */
+ allow_daemon = 0; /* Daemon failed - switch off. */
+#endif /*USE_RANDOM_DAEMON*/
+
+ /* Acquire the pool lock. */
+ lock_pool ();
+
+ /* Update the statistics. */
+ if (level >= GCRY_VERY_STRONG_RANDOM)
+ {
+ rndstats.getbytes2 += length;
+ rndstats.ngetbytes2++;
+ }
+ else
+ {
+ rndstats.getbytes1 += length;
+ rndstats.ngetbytes1++;
+ }
+
+ /* Read the random into the provided buffer. */
+ for (p = buffer; length > 0;)
+ {
+ size_t n;
+
+ n = length > POOLSIZE? POOLSIZE : length;
+ read_pool (p, n, level);
+ length -= n;
+ p += n;
+ }
+
+ /* Release the pool lock. */
+ unlock_pool ();
+}
+
+
+
+
+/*
+ * Mix the 600 byte pool. Note that the 64 byte scratch area directly
+ * follows the pool. The numbers in the diagram give the number of
+ * bytes.
+ * <................600...............> <.64.>
+ * pool |------------------------------------| |------|
+ * <20><.24.> <20>
+ * | | +-----+
+ * +-----|-------------------------------|-+
+ * +-------------------------------|-|-+
+ * v v v
+ * |------|
+ * <hash>
+ * +---------------------------------------+
+ * v
+ * <20>
+ * pool' |------------------------------------|
+ * <20><20><.24.>
+ * +---|-----|---------------------------+
+ * +-----|---------------------------|-+
+ * +---------------------------|-|-+
+ * v v v
+ * |------|
+ * <hash>
+ * |
+ * +-----------------------------------+
+ * v
+ * <20>
+ * pool'' |------------------------------------|
+ * <20><20><20><.24.>
+ * +---|-----|-----------------------+
+ * +-----|-----------------------|-+
+ * +-----------------------|-|-+
+ * v v v
+ *
+ * and so on until we did this for all 30 blocks.
+ *
+ * To better protect against implementation errors in this code, we
+ * xor a digest of the entire pool into the pool before mixing.
+ *
+ * Note: this function must only be called with a locked pool.
+ */
+static void
+mix_pool(unsigned char *pool)
+{
+ static unsigned char failsafe_digest[DIGESTLEN];
+ static int failsafe_digest_valid;
+
+ unsigned char *hashbuf = pool + POOLSIZE;
+ unsigned char *p, *pend;
+ int i, n;
+ SHA1_CONTEXT md;
+ unsigned int nburn;
+
+#if DIGESTLEN != 20
+#error must have a digest length of 20 for SHA-1
+#endif
+
+ gcry_assert (pool_is_locked);
+ _gcry_sha1_mixblock_init (&md);
+
+ /* pool_0 -> pool'. */
+ pend = pool + POOLSIZE;
+ memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN);
+ memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
+ nburn = _gcry_sha1_mixblock (&md, hashbuf);
+ memcpy (pool, hashbuf, DIGESTLEN);
+
+ if (failsafe_digest_valid && pool == rndpool)
+ {
+ for (i=0; i < DIGESTLEN; i++)
+ pool[i] ^= failsafe_digest[i];
+ }
+
+ /* Loop for the remaining iterations. */
+ p = pool;
+ for (n=1; n < POOLBLOCKS; n++)
+ {
+ if (p + BLOCKLEN < pend)
+ memcpy (hashbuf, p, BLOCKLEN);
+ else
+ {
+ unsigned char *pp = p;
+
+ for (i=0; i < BLOCKLEN; i++ )
+ {
+ if ( pp >= pend )
+ pp = pool;
+ hashbuf[i] = *pp++;
+ }
+ }
+
+ _gcry_sha1_mixblock (&md, hashbuf);
+ p += DIGESTLEN;
+ memcpy (p, hashbuf, DIGESTLEN);
+ }
+
+ /* Our hash implementation does only leave small parts (64 bytes)
+ of the pool on the stack, so it is okay not to require secure
+ memory here. Before we use this pool, it will be copied to the
+ help buffer anyway. */
+ if ( pool == rndpool)
+ {
+ _gcry_sha1_hash_buffer (failsafe_digest, pool, POOLSIZE);
+ failsafe_digest_valid = 1;
+ }
+
+ _gcry_burn_stack (nburn);
+}
+
+
+void
+_gcry_rngcsprng_set_seed_file (const char *name)
+{
+ if (seed_file_name)
+ BUG ();
+ seed_file_name = xstrdup (name);
+}
+
+
+
+/* Helper for my_open.
+ * Return a malloced wide char string from an UTF-8 encoded input
+ * string STRING. Caller must free this value. Returns NULL and sets
+ * ERRNO on failure. Calling this function with STRING set to NULL is
+ * not defined. */
+#ifdef HAVE_W32_SYSTEM
+static wchar_t *
+utf8_to_wchar (const char *string)
+{
+ int n;
+ size_t nbytes;
+ wchar_t *result;
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
+ if (n < 0)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL;
+ }
+
+ nbytes = (size_t)(n+1) * sizeof(*result);
+ if (nbytes / sizeof(*result) != (n+1))
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ result = xtrymalloc (nbytes);
+ if (!result)
+ return NULL;
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+ if (n < 0)
+ {
+ xfree (result);
+ gpg_err_set_errno (EINVAL);
+ result = NULL;
+ }
+ return result;
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+
+/* Helper for my_open. */
+#ifdef HAVE_W32_SYSTEM
+static int
+any8bitchar (const char *string)
+{
+ if (string)
+ for ( ; *string; string++)
+ if ((*string & 0x80))
+ return 1;
+ return 0;
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+
+/* A wrapper around open to handle Unicode file names under Windows. */
+static int
+my_open (const char *name, int flags, unsigned int mode)
+{
+#ifdef HAVE_W32_SYSTEM
+ if (any8bitchar (name))
+ {
+ wchar_t *wname;
+ int ret;
+
+ wname = utf8_to_wchar (name);
+ if (!wname)
+ return -1;
+ ret = _wopen (wname, flags, mode);
+ xfree (wname);
+ return ret;
+ }
+ else
+ return open (name, flags, mode);
+#else
+ return open (name, flags, mode);
+#endif
+}
+
+
+/* Lock an open file identified by file descriptor FD and wait a
+ reasonable time to succeed. With FOR_WRITE set to true a write
+ lock will be taken. FNAME is used only for diagnostics. Returns 0
+ on success or -1 on error. */
+static int
+lock_seed_file (int fd, const char *fname, int for_write)
+{
+#ifdef __GCC__
+#warning Check whether we can lock on Windows.
+#endif
+#if LOCK_SEED_FILE
+ struct flock lck;
+ struct timeval tv;
+ int backoff=0;
+
+ /* We take a lock on the entire file. */
+ memset (&lck, 0, sizeof lck);
+ lck.l_type = for_write? F_WRLCK : F_RDLCK;
+ lck.l_whence = SEEK_SET;
+
+ while (fcntl (fd, F_SETLK, &lck) == -1)
+ {
+ if (errno != EAGAIN && errno != EACCES)
+ {
+ log_info (_("can't lock `%s': %s\n"), fname, strerror (errno));
+ return -1;
+ }
+
+ if (backoff > 2) /* Show the first message after ~2.25 seconds. */
+ log_info( _("waiting for lock on `%s'...\n"), fname);
+
+ tv.tv_sec = backoff;
+ tv.tv_usec = 250000;
+ select (0, NULL, NULL, NULL, &tv);
+ if (backoff < 10)
+ backoff++ ;
+ }
+#else
+ (void)fd;
+ (void)fname;
+ (void)for_write;
+#endif /*!LOCK_SEED_FILE*/
+ return 0;
+}
+
+
+/* Read in a seed from the random_seed file and return true if this
+ was successful.
+
+ Note: Multiple instances of applications sharing the same random
+ seed file can be started in parallel, in which case they will read
+ out the same pool and then race for updating it (the last update
+ overwrites earlier updates). They will differentiate only by the
+ weak entropy that is added in read_seed_file based on the PID and
+ clock, and up to 32 bytes from a non-blocking entropy source. The
+ consequence is that the output of these different instances is
+ correlated to some extent. In the perfect scenario, the attacker
+ can control (or at least guess) the PID and clock of the
+ application, and drain the system's entropy pool to reduce the "up
+ to 32 bytes" above to 0. Then the dependencies of the initial
+ states of the pools are completely known. */
+static int
+read_seed_file (void)
+{
+ int fd;
+ struct stat sb;
+ unsigned char buffer[POOLSIZE];
+ int n;
+
+ gcry_assert (pool_is_locked);
+
+ if (!seed_file_name)
+ return 0;
+
+#ifdef HAVE_DOSISH_SYSTEM
+ fd = my_open (seed_file_name, O_RDONLY | O_BINARY, 0);
+#else
+ fd = my_open (seed_file_name, O_RDONLY, 0);
+#endif
+ if( fd == -1 && errno == ENOENT)
+ {
+ allow_seed_file_update = 1;
+ return 0;
+ }
+
+ if (fd == -1 )
+ {
+ log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
+ return 0;
+ }
+ if (lock_seed_file (fd, seed_file_name, 0))
+ {
+ close (fd);
+ return 0;
+ }
+ if (fstat( fd, &sb ) )
+ {
+ log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
+ close(fd);
+ return 0;
+ }
+ if (!S_ISREG(sb.st_mode) )
+ {
+ log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
+ close(fd);
+ return 0;
+ }
+ if (!sb.st_size )
+ {
+ log_info(_("note: random_seed file is empty\n") );
+ close(fd);
+ allow_seed_file_update = 1;
+ return 0;
+ }
+ if (sb.st_size != POOLSIZE )
+ {
+ log_info(_("warning: invalid size of random_seed file - not used\n") );
+ close(fd);
+ return 0;
+ }
+
+ do
+ {
+ n = read( fd, buffer, POOLSIZE );
+ }
+ while (n == -1 && errno == EINTR );
+
+ if (n != POOLSIZE)
+ {
+ log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
+ close(fd);/*NOTREACHED*/
+ return 0;
+ }
+
+ close(fd);
+
+ add_randomness( buffer, POOLSIZE, RANDOM_ORIGIN_INIT );
+ /* add some minor entropy to the pool now (this will also force a mixing) */
+ {
+ pid_t x = getpid();
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
+ }
+ {
+ time_t x = time(NULL);
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
+ }
+ {
+ clock_t x = clock();
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
+ }
+
+ /* And read a few bytes from our entropy source. If we have the
+ * Jitter RNG we can fast get a lot of entropy. Thus we read 1024
+ * bits from that source.
+ *
+ * Without the Jitter RNG we keep the old method of reading only a
+ * few bytes usually from /dev/urandom which won't block. */
+ if (_gcry_rndjent_get_version (NULL))
+ read_random_source (RANDOM_ORIGIN_INIT, 128, GCRY_STRONG_RANDOM);
+ else
+ read_random_source (RANDOM_ORIGIN_INIT, 32, GCRY_STRONG_RANDOM);
+
+ allow_seed_file_update = 1;
+ return 1;
+}
+
+
+void
+_gcry_rngcsprng_update_seed_file (void)
+{
+ unsigned long *sp, *dp;
+ int fd, i;
+
+ /* We do only a basic initialization so that we can lock the pool.
+ This is required to cope with the case that this function is
+ called by some cleanup code at a point where the RNG has never
+ been initialized. */
+ initialize_basics ();
+ lock_pool ();
+
+ if ( !seed_file_name || !rndpool || !pool_filled )
+ {
+ unlock_pool ();
+ return;
+ }
+ if ( !allow_seed_file_update )
+ {
+ unlock_pool ();
+ log_info(_("note: random_seed file not updated\n"));
+ return;
+ }
+
+ /* At this point we know that there is something in the pool and
+ thus we can conclude that the pool has been fully initialized. */
+
+
+ /* Copy the entropy pool to a scratch pool and mix both of them. */
+ for (i=0,dp=(unsigned long*)(void*)keypool, sp=(unsigned long*)(void*)rndpool;
+ i < POOLWORDS; i++, dp++, sp++ )
+ {
+ *dp = *sp + ADD_VALUE;
+ }
+ mix_pool(rndpool); rndstats.mixrnd++;
+ mix_pool(keypool); rndstats.mixkey++;
+
+#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
+ fd = my_open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
+ S_IRUSR|S_IWUSR );
+#else
+# if LOCK_SEED_FILE
+ fd = my_open (seed_file_name, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR );
+# else
+ fd = my_open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
+# endif
+#endif
+
+ if (fd == -1 )
+ log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
+ else if (lock_seed_file (fd, seed_file_name, 1))
+ {
+ close (fd);
+ }
+#if LOCK_SEED_FILE
+ else if (ftruncate (fd, 0))
+ {
+ log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno));
+ close (fd);
+ }
+#endif /*LOCK_SEED_FILE*/
+ else
+ {
+ do
+ {
+ i = write (fd, keypool, POOLSIZE );
+ }
+ while (i == -1 && errno == EINTR);
+ if (i != POOLSIZE)
+ log_info (_("can't write `%s': %s\n"),seed_file_name, strerror(errno));
+ if (close(fd))
+ log_info (_("can't close `%s': %s\n"),seed_file_name, strerror(errno));
+ }
+
+ unlock_pool ();
+}
+
+
+/* Read random out of the pool. This function is the core of the
+ public random functions. Note that Level GCRY_WEAK_RANDOM is not
+ anymore handled special and in fact is an alias in the API for
+ level GCRY_STRONG_RANDOM. Must be called with the pool already
+ locked. */
+static void
+read_pool (byte *buffer, size_t length, int level)
+{
+ int i;
+ unsigned long *sp, *dp;
+ /* The volatile is there to make sure the compiler does not optimize
+ the code away in case the getpid function is badly attributed.
+ Note that we keep a pid in a static variable as well as in a
+ stack based one; the latter is to detect ill behaving thread
+ libraries, ignoring the pool mutexes. */
+ static volatile pid_t my_pid = (pid_t)(-1);
+ volatile pid_t my_pid2;
+
+ gcry_assert (pool_is_locked);
+
+ retry:
+ /* Get our own pid, so that we can detect a fork. */
+ my_pid2 = getpid ();
+ if (my_pid == (pid_t)(-1))
+ my_pid = my_pid2;
+ if ( my_pid != my_pid2 )
+ {
+ /* We detected a plain fork; i.e. we are now the child. Update
+ the static pid and add some randomness. */
+ pid_t x;
+
+ my_pid = my_pid2;
+ x = my_pid;
+ add_randomness (&x, sizeof(x), RANDOM_ORIGIN_INIT);
+ just_mixed = 0; /* Make sure it will get mixed. */
+ }
+
+ gcry_assert (pool_is_locked);
+
+ /* Our code does not allow to extract more than POOLSIZE. Better
+ check it here. */
+ if (length > POOLSIZE)
+ {
+ log_bug("too many random bits requested\n");
+ }
+
+ if (!pool_filled)
+ {
+ if (read_seed_file() )
+ pool_filled = 1;
+ }
+
+ /* For level 2 quality (key generation) we always make sure that the
+ pool has been seeded enough initially. */
+ if (level == GCRY_VERY_STRONG_RANDOM && !did_initial_extra_seeding)
+ {
+ size_t needed;
+
+ pool_balance = 0;
+ needed = length - pool_balance;
+ if (needed < 16) /* At least 128 bits. */
+ needed = 16;
+ else if( needed > POOLSIZE )
+ BUG ();
+ read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed,
+ GCRY_VERY_STRONG_RANDOM);
+ pool_balance += needed;
+ did_initial_extra_seeding = 1;
+ }
+
+ /* For level 2 make sure that there is enough random in the pool. */
+ if (level == GCRY_VERY_STRONG_RANDOM && pool_balance < length)
+ {
+ size_t needed;
+
+ if (pool_balance < 0)
+ pool_balance = 0;
+ needed = length - pool_balance;
+ if (needed > POOLSIZE)
+ BUG ();
+ read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed,
+ GCRY_VERY_STRONG_RANDOM);
+ pool_balance += needed;
+ }
+
+ /* Make sure the pool is filled. */
+ while (!pool_filled)
+ random_poll();
+
+ /* Always do a fast random poll (we have to use the unlocked version). */
+ do_fast_random_poll();
+
+ /* Mix the pid in so that we for sure won't deliver the same random
+ after a fork. */
+ {
+ pid_t apid = my_pid;
+ add_randomness (&apid, sizeof (apid), RANDOM_ORIGIN_INIT);
+ }
+
+ /* Mix the pool (if add_randomness() didn't it). */
+ if (!just_mixed)
+ {
+ mix_pool(rndpool);
+ rndstats.mixrnd++;
+ }
+
+ /* Create a new pool. */
+ for(i=0,dp=(unsigned long*)(void*)keypool, sp=(unsigned long*)(void*)rndpool;
+ i < POOLWORDS; i++, dp++, sp++ )
+ *dp = *sp + ADD_VALUE;
+
+ /* Mix both pools. */
+ mix_pool(rndpool); rndstats.mixrnd++;
+ mix_pool(keypool); rndstats.mixkey++;
+
+ /* Read the requested data. We use a read pointer to read from a
+ different position each time. */
+ while (length--)
+ {
+ *buffer++ = keypool[pool_readpos++];
+ if (pool_readpos >= POOLSIZE)
+ pool_readpos = 0;
+ pool_balance--;
+ }
+
+ if (pool_balance < 0)
+ pool_balance = 0;
+
+ /* Clear the keypool. */
+ memset (keypool, 0, POOLSIZE);
+
+ /* We need to detect whether a fork has happened. A fork might have
+ an identical pool and thus the child and the parent could emit
+ the very same random number. This test here is to detect forks
+ in a multi-threaded process. It does not work with all thread
+ implementations in particular not with pthreads. However it is
+ good enough for GNU Pth. */
+ if ( getpid () != my_pid2 )
+ {
+ pid_t x = getpid();
+ add_randomness (&x, sizeof(x), RANDOM_ORIGIN_INIT);
+ just_mixed = 0; /* Make sure it will get mixed. */
+ my_pid = x; /* Also update the static pid. */
+ goto retry;
+ }
+}
+
+
+
+/* Add LENGTH bytes of randomness from buffer to the pool. ORIGIN is
+ used to specify the randomness origin. This is one of the
+ RANDOM_ORIGIN_* values. */
+static void
+add_randomness (const void *buffer, size_t length, enum random_origins origin)
+{
+ const unsigned char *p = buffer;
+ size_t count = 0;
+
+ gcry_assert (pool_is_locked);
+
+ rndstats.addbytes += length;
+ rndstats.naddbytes++;
+ while (length-- )
+ {
+ rndpool[pool_writepos++] ^= *p++;
+ count++;
+ if (pool_writepos >= POOLSIZE )
+ {
+ /* It is possible that we are invoked before the pool is
+ filled using an unreliable origin of entropy, for example
+ the fast random poll. To avoid flagging the pool as
+ filled in this case, we track the initial filling state
+ separately. See also the remarks about the seed file. */
+ if (origin >= RANDOM_ORIGIN_SLOWPOLL && !pool_filled)
+ {
+ pool_filled_counter += count;
+ count = 0;
+ if (pool_filled_counter >= POOLSIZE)
+ pool_filled = 1;
+ }
+ pool_writepos = 0;
+ mix_pool(rndpool); rndstats.mixrnd++;
+ just_mixed = !length;
+ }
+ }
+}
+
+
+
+static void
+random_poll()
+{
+ rndstats.slowpolls++;
+ read_random_source (RANDOM_ORIGIN_SLOWPOLL, POOLSIZE/5, GCRY_STRONG_RANDOM);
+}
+
+
+/* Runtime determination of the slow entropy gathering module. */
+static int (*
+getfnc_gather_random (void))(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins, size_t, int)
+{
+ int (*fnc)(void (*)(const void*, size_t, enum random_origins),
+ enum random_origins, size_t, int);
+
+#if USE_RNDLINUX
+ if ( !access (NAME_OF_DEV_RANDOM, R_OK)
+ && !access (NAME_OF_DEV_URANDOM, R_OK))
+ {
+ fnc = _gcry_rndlinux_gather_random;
+ return fnc;
+ }
+#endif
+
+#if USE_RNDEGD
+ if ( _gcry_rndegd_connect_socket (1) != -1 )
+ {
+ fnc = _gcry_rndegd_gather_random;
+ return fnc;
+ }
+#endif
+
+#if USE_RNDUNIX
+ fnc = _gcry_rndunix_gather_random;
+ return fnc;
+#endif
+
+#if USE_RNDW32
+ fnc = _gcry_rndw32_gather_random;
+ return fnc;
+#endif
+
+#if USE_RNDW32CE
+ fnc = _gcry_rndw32ce_gather_random;
+ return fnc;
+#endif
+
+ log_fatal (_("no entropy gathering module detected\n"));
+
+ return NULL; /*NOTREACHED*/
+}
+
+/* Runtime determination of the fast entropy gathering function.
+ (Currently a compile time method is used.) */
+static void (*
+getfnc_fast_random_poll (void))( void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins)
+{
+#if USE_RNDW32
+ return _gcry_rndw32_gather_random_fast;
+#endif
+#if USE_RNDW32CE
+ return _gcry_rndw32ce_gather_random_fast;
+#endif
+ return NULL;
+}
+
+
+
+static void
+do_fast_random_poll (void)
+{
+ gcry_assert (pool_is_locked);
+
+ rndstats.fastpolls++;
+
+ if (fast_gather_fnc)
+ fast_gather_fnc (add_randomness, RANDOM_ORIGIN_FASTPOLL);
+
+ /* Continue with the generic functions. */
+#if HAVE_GETHRTIME
+ {
+ hrtime_t tv;
+ tv = gethrtime();
+ add_randomness( &tv, sizeof(tv), RANDOM_ORIGIN_FASTPOLL );
+ }
+#elif HAVE_GETTIMEOFDAY
+ {
+ struct timeval tv;
+ if( gettimeofday( &tv, NULL ) )
+ BUG();
+ add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL );
+ add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), RANDOM_ORIGIN_FASTPOLL );
+ }
+#elif HAVE_CLOCK_GETTIME
+ { struct timespec tv;
+ if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
+ BUG();
+ add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL );
+ add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), RANDOM_ORIGIN_FASTPOLL );
+ }
+#else /* use times */
+# ifndef HAVE_DOSISH_SYSTEM
+ { struct tms buf;
+ times( &buf );
+ add_randomness( &buf, sizeof buf, RANDOM_ORIGIN_FASTPOLL );
+ }
+# endif
+#endif
+
+#ifdef HAVE_GETRUSAGE
+# ifdef RUSAGE_SELF
+ {
+ struct rusage buf;
+ /* QNX/Neutrino does return ENOSYS - so we just ignore it and add
+ whatever is in buf. In a chroot environment it might not work
+ at all (i.e. because /proc/ is not accessible), so we better
+ ignore all error codes and hope for the best. */
+ getrusage (RUSAGE_SELF, &buf );
+ add_randomness( &buf, sizeof buf, RANDOM_ORIGIN_FASTPOLL );
+ memset( &buf, 0, sizeof buf );
+ }
+# else /*!RUSAGE_SELF*/
+# ifdef __GCC__
+# warning There is no RUSAGE_SELF on this system
+# endif
+# endif /*!RUSAGE_SELF*/
+#endif /*HAVE_GETRUSAGE*/
+
+ /* Time and clock are available on all systems - so we better do it
+ just in case one of the above functions didn't work. */
+ {
+ time_t x = time(NULL);
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL );
+ }
+ {
+ clock_t x = clock();
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL );
+ }
+
+ /* If the system features a fast hardware RNG, read some bytes from
+ there. */
+ _gcry_rndhw_poll_fast (add_randomness, RANDOM_ORIGIN_FASTPOLL);
+}
+
+
+/* The fast random pool function as called at some places in
+ libgcrypt. This is merely a wrapper to make sure that this module
+ is initialized and to lock the pool. Note, that this function is a
+ NOP unless a random function has been used or _gcry_initialize (1)
+ has been used. We use this hack so that the internal use of this
+ function in cipher_open and md_open won't start filling up the
+ random pool, even if no random will be required by the process. */
+void
+_gcry_rngcsprng_fast_poll (void)
+{
+ initialize_basics ();
+
+ lock_pool ();
+ if (rndpool)
+ {
+ /* Yes, we are fully initialized. */
+ do_fast_random_poll ();
+ }
+ unlock_pool ();
+}
+
+
+
+static void
+read_random_source (enum random_origins origin, size_t length, int level)
+{
+ if ( !slow_gather_fnc )
+ log_fatal ("Slow entropy gathering module not yet initialized\n");
+
+ if (slow_gather_fnc (add_randomness, origin, length, level) < 0)
+ log_fatal ("No way to gather entropy for the RNG\n");
+}
diff --git a/comm/third_party/libgcrypt/random/random-daemon.c b/comm/third_party/libgcrypt/random/random-daemon.c
new file mode 100644
index 0000000000..8ea4df285b
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/random-daemon.c
@@ -0,0 +1,336 @@
+/* random-daemon.c - Access to the external random daemon
+ * Copyright (C) 2006 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
+ */
+
+/*
+ The functions here are used by random.c to divert calls to an
+ external random number daemon. The actual daemon we use is
+ gcryptrnd. Such a daemon is useful to keep a persistent pool in
+ memory over invocations of a single application and to allow
+ prioritizing access to the actual entropy sources. The drawback is
+ that we need to use IPC (i.e. unix domain socket) to convey
+ sensitive data.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "random.h"
+
+
+
+/* This is default socket name we use in case the provided socket name
+ is NULL. */
+#define RANDOM_DAEMON_SOCKET "/var/run/libgcrypt/S.gcryptrnd"
+
+/* The lock serializing access to the daemon. */
+GPGRT_LOCK_DEFINE (daemon_lock);
+
+/* The socket connected to the daemon. */
+static int daemon_socket = -1;
+
+/* Creates a socket connected to the daemon. On success, store the
+ socket fd in *SOCK. Returns error code. */
+static gcry_error_t
+connect_to_socket (const char *socketname, int *sock)
+{
+ struct sockaddr_un *srvr_addr;
+ socklen_t addrlen;
+ gcry_error_t err;
+ int fd;
+ int rc;
+
+ srvr_addr = NULL;
+
+ /* Create a socket. */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ log_error ("can't create socket: %s\n", strerror (errno));
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Set up address. */
+ srvr_addr = gcry_malloc (sizeof *srvr_addr);
+ if (! srvr_addr)
+ {
+ log_error ("malloc failed: %s\n", strerror (errno));
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ memset (srvr_addr, 0, sizeof *srvr_addr);
+ srvr_addr->sun_family = AF_UNIX;
+ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
+ {
+ log_error ("socket name `%s' too long\n", socketname);
+ err = gcry_error (GPG_ERR_ENAMETOOLONG);
+ goto out;
+ }
+ strcpy (srvr_addr->sun_path, socketname);
+ addrlen = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (srvr_addr->sun_path) + 1);
+
+ /* Connect socket. */
+ rc = connect (fd, (struct sockaddr *) srvr_addr, addrlen);
+ if (rc == -1)
+ {
+ log_error ("error connecting socket `%s': %s\n",
+ srvr_addr->sun_path, strerror (errno));
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ err = 0;
+
+ out:
+
+ gcry_free (srvr_addr);
+ if (err)
+ {
+ close (fd);
+ fd = -1;
+ }
+ *sock = fd;
+
+ return err;
+}
+
+
+/* Initialize basics of this module. This should be viewed as a
+ constructor to prepare locking. */
+void
+_gcry_daemon_initialize_basics (void)
+{
+ /* Not anymore required. */
+}
+
+
+
+/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
+ success or another value on write error. */
+static int
+writen (int fd, const void *buffer, size_t length)
+{
+ ssize_t n;
+
+ while (length)
+ {
+ do
+ n = ath_write (fd, buffer, length);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ log_error ("write error: %s\n", strerror (errno));
+ return -1; /* write error */
+ }
+ length -= n;
+ buffer = (const char*)buffer + n;
+ }
+ return 0; /* Okay */
+}
+
+static int
+readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
+{
+ size_t nleft = buflen;
+ int nread;
+ char *p;
+
+ p = buf;
+ while (nleft > 0)
+ {
+ nread = ath_read (fd, buf, nleft);
+ if (nread < 0)
+ {
+ if (nread == EINTR)
+ nread = 0;
+ else
+ return -1;
+ }
+ else if (!nread)
+ break; /* EOF */
+ nleft -= nread;
+ buf = (char*)buf + nread;
+ }
+ if (ret_nread)
+ *ret_nread = buflen - nleft;
+ return 0;
+}
+
+/* This functions requests REQ_NBYTES from the daemon. If NONCE is
+ true, the data should be suited for a nonce. If NONCE is FALSE,
+ data of random level LEVEL will be generated. The retrieved random
+ data will be stored in BUFFER. Returns error code. */
+static gcry_error_t
+call_daemon (const char *socketname,
+ void *buffer, size_t req_nbytes, int nonce,
+ enum gcry_random_level level)
+{
+ static int initialized;
+ unsigned char buf[255];
+ gcry_error_t err = 0;
+ size_t nbytes;
+ size_t nread;
+ int rc;
+
+ if (!req_nbytes)
+ return 0;
+
+ gpgrt_lock_lock (&daemon_lock);
+
+ /* Open the socket if that has not been done. */
+ if (!initialized)
+ {
+ initialized = 1;
+ err = connect_to_socket (socketname ? socketname : RANDOM_DAEMON_SOCKET,
+ &daemon_socket);
+ if (err)
+ {
+ daemon_socket = -1;
+ log_info ("not using random daemon\n");
+ gpgrt_lock_unlock (&daemon_lock);
+ return err;
+ }
+ }
+
+ /* Check that we have a valid socket descriptor. */
+ if ( daemon_socket == -1 )
+ {
+ gpgrt_lock_unlock (&daemon_lock);
+ return gcry_error (GPG_ERR_INTERNAL);
+ }
+
+
+ /* Do the real work. */
+
+ do
+ {
+ /* Process in chunks. */
+ nbytes = req_nbytes > sizeof (buf) ? sizeof (buf) : req_nbytes;
+ req_nbytes -= nbytes;
+
+ /* Construct request. */
+ buf[0] = 3;
+ if (nonce)
+ buf[1] = 10;
+ else if (level == GCRY_VERY_STRONG_RANDOM)
+ buf[1] = 12;
+ else if (level == GCRY_STRONG_RANDOM)
+ buf[1] = 11;
+ buf[2] = nbytes;
+
+ /* Send request. */
+ rc = writen (daemon_socket, buf, 3);
+ if (rc == -1)
+ {
+ err = gcry_error_from_errno (errno);
+ break;
+ }
+
+ /* Retrieve response. */
+
+ rc = readn (daemon_socket, buf, 2, &nread);
+ if (rc == -1)
+ {
+ err = gcry_error_from_errno (errno);
+ log_error ("read error: %s\n", _gcry_strerror (err));
+ break;
+ }
+ if (nread && buf[0])
+ {
+ log_error ("random daemon returned error code %d\n", buf[0]);
+ err = gcry_error (GPG_ERR_INTERNAL); /* ? */
+ break;
+ }
+ if (nread != 2)
+ {
+ log_error ("response too small\n");
+ err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
+ break;
+ }
+
+ /* if (1)*/ /* Do this in verbose mode? */
+ /* log_info ("received response with %d bytes of data\n", buf[1]);*/
+
+ if (buf[1] < nbytes)
+ {
+ log_error ("error: server returned less bytes than requested\n");
+ err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
+ break;
+ }
+ else if (buf[1] > nbytes)
+ {
+ log_error ("warning: server returned more bytes than requested\n");
+ err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
+ break;
+ }
+
+ assert (nbytes <= sizeof (buf));
+
+ rc = readn (daemon_socket, buf, nbytes, &nread);
+ if (rc == -1)
+ {
+ err = gcry_error_from_errno (errno);
+ log_error ("read error: %s\n", _gcry_strerror (err));
+ break;
+ }
+
+ if (nread != nbytes)
+ {
+ log_error ("too little random data read\n");
+ err = gcry_error (GPG_ERR_INTERNAL);
+ break;
+ }
+
+ /* Successfuly read another chunk of data. */
+ memcpy (buffer, buf, nbytes);
+ buffer = ((char *) buffer) + nbytes;
+ }
+ while (req_nbytes);
+
+ gpgrt_lock_unlock (&daemon_lock);
+
+ return err;
+}
+
+/* Internal function to fill BUFFER with LENGTH bytes of random. We
+ support GCRY_STRONG_RANDOM and GCRY_VERY_STRONG_RANDOM here.
+ Return 0 on success. */
+int
+_gcry_daemon_randomize (const char *socketname,
+ void *buffer, size_t length,
+ enum gcry_random_level level)
+{
+ gcry_error_t err;
+
+ err = call_daemon (socketname, buffer, length, 0, level);
+
+ return err ? -1 : 0;
+}
+
+/* END */
diff --git a/comm/third_party/libgcrypt/random/random-drbg.c b/comm/third_party/libgcrypt/random/random-drbg.c
new file mode 100644
index 0000000000..6124f5fb6d
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/random-drbg.c
@@ -0,0 +1,2668 @@
+/* random-drbg.c - Deterministic Random Bits Generator
+ * Copyright 2014 Stephan Mueller <smueller@chronox.de>
+ *
+ * DRBG: Deterministic Random Bits Generator
+ * Based on NIST Recommended DRBG from NIST SP800-90A with the following
+ * properties:
+ * * CTR DRBG with DF with AES-128, AES-192, AES-256 cores
+ * * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores
+ * * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores
+ * * with and without prediction resistance
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * LGPLv2+, in which case the provisions of the LGPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the LGPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * gcry_control GCRYCTL_DRBG_REINIT
+ * ================================
+ * This control request re-initializes the DRBG completely, i.e. the entire
+ * state of the DRBG is zeroized (with two exceptions listed in
+ * GCRYCTL_DRBG_SET_ENTROPY).
+ *
+ * The control request takes the following values which influences how
+ * the DRBG is re-initialized:
+ *
+ * - const char *flagstr
+ *
+ * This variable specifies the DRBG type to be used for the next
+ * initialization. If set to NULL, the previous DRBG type is
+ * used for the initialization. If not NULL a space separated
+ * list of tokens with associated flag values is expected which
+ * are ORed to form the mandatory flags of the requested DRBG
+ * strength and cipher type. Optionally, the prediction
+ * resistance flag can be ORed into the flags variable.
+ *
+ * | String token | Flag value |
+ * |--------------+------------------------|
+ * | aes | DRBG_CTRAES |
+ * | serpent | DRBG_CTRSERPENT |
+ * | twofish | DRBG_CTRTWOFISH |
+ * | sha1 | DRBG_HASHSHA1 |
+ * | sha256 | DRBG_HASHSHA256 |
+ * | sha512 | DRBG_HASHSHA512 |
+ * | hmac | DRBG_HMAC |
+ * | sym128 | DRBG_SYM128 |
+ * | sym192 | DRBG_SYM192 |
+ * | sym256 | DRBG_SYM256 |
+ * | pr | DRBG_PREDICTION_RESIST |
+ *
+ * For example:
+ *
+ * - CTR-DRBG with AES-128 without prediction resistance:
+ * "aes sym128"
+ * - HMAC-DRBG with SHA-512 with prediction resistance:
+ * "hmac sha512 pr"
+ *
+ * - gcry_buffer_t *pers
+ *
+ * NULL terminated array with personalization strings to be used
+ * for initialization.
+ *
+ * - int npers
+ *
+ * Size of PERS.
+ *
+ * - void *guard
+ *
+ * A value of NULL must be passed for this.
+ *
+ * The variable of flags is independent from the pers/perslen variables. If
+ * flags is set to 0 and perslen is set to 0, the current DRBG type is
+ * completely reset without using a personalization string.
+ *
+ * DRBG Usage
+ * ==========
+ * The SP 800-90A DRBG allows the user to specify a personalization string
+ * for initialization as well as an additional information string for each
+ * random number request. The following code fragments show how a caller
+ * uses the API to use the full functionality of the DRBG.
+ *
+ * Usage without any additional data
+ * ---------------------------------
+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
+ *
+ *
+ * Usage with personalization string during initialization
+ * -------------------------------------------------------
+ * drbg_string_t pers;
+ * char personalization[11] = "some-string";
+ *
+ * drbg_string_fill(&pers, personalization, strlen(personalization));
+ * // The reset completely re-initializes the DRBG with the provided
+ * // personalization string without changing the DRBG type
+ * ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, &pers);
+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
+ *
+ *
+ * Usage with additional information string during random number request
+ * ---------------------------------------------------------------------
+ * drbg_string_t addtl;
+ * char addtl_string[11] = "some-string";
+ *
+ * drbg_string_fill(&addtl, addtl_string, strlen(addtl_string));
+ * // The following call is a wrapper to gcry_randomize() and returns
+ * // the same error codes.
+ * gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, &addtl);
+ *
+ *
+ * Usage with personalization and additional information strings
+ * -------------------------------------------------------------
+ * Just mix both scenarios above.
+ *
+ *
+ * Switch the DRBG type to some other type
+ * ---------------------------------------
+ * // Switch to CTR DRBG AES-128 without prediction resistance
+ * ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_NOPR_CTRAES128, NULL);
+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "g10lib.h"
+#include "random.h"
+#include "rand-internal.h"
+#include "../cipher/bufhelp.h"
+
+
+
+/******************************************************************
+ * Constants
+ ******************************************************************/
+
+/*
+ * DRBG flags bitmasks
+ *
+ * 31 (B) 28 19 (A) 0
+ * +-+-+-+--------+---+-----------+-----+
+ * |~|~|u|~~~~~~~~| 3 | 2 | 1 |
+ * +-+-+-+--------+- -+-----------+-----+
+ * ctl flg| |drbg use selection flags
+ *
+ */
+
+/* Internal state control flags (B) */
+#define DRBG_PREDICTION_RESIST ((u32)1<<28)
+
+/* CTR type modifiers (A.1)*/
+#define DRBG_CTRAES ((u32)1<<0)
+#define DRBG_CTRSERPENT ((u32)1<<1)
+#define DRBG_CTRTWOFISH ((u32)1<<2)
+#define DRBG_CTR_MASK (DRBG_CTRAES | DRBG_CTRSERPENT \
+ | DRBG_CTRTWOFISH)
+
+/* HASH type modifiers (A.2)*/
+#define DRBG_HASHSHA1 ((u32)1<<4)
+#define DRBG_HASHSHA224 ((u32)1<<5)
+#define DRBG_HASHSHA256 ((u32)1<<6)
+#define DRBG_HASHSHA384 ((u32)1<<7)
+#define DRBG_HASHSHA512 ((u32)1<<8)
+#define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 \
+ | DRBG_HASHSHA256 | DRBG_HASHSHA384 \
+ | DRBG_HASHSHA512)
+/* type modifiers (A.3)*/
+#define DRBG_HMAC ((u32)1<<12)
+#define DRBG_SYM128 ((u32)1<<13)
+#define DRBG_SYM192 ((u32)1<<14)
+#define DRBG_SYM256 ((u32)1<<15)
+#define DRBG_TYPE_MASK (DRBG_HMAC | DRBG_SYM128 | DRBG_SYM192 \
+ | DRBG_SYM256)
+#define DRBG_CIPHER_MASK (DRBG_CTR_MASK | DRBG_HASH_MASK \
+ | DRBG_TYPE_MASK)
+
+#define DRBG_PR_CTRAES128 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM128)
+#define DRBG_PR_CTRAES192 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM192)
+#define DRBG_PR_CTRAES256 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM256)
+#define DRBG_NOPR_CTRAES128 (DRBG_CTRAES | DRBG_SYM128)
+#define DRBG_NOPR_CTRAES192 (DRBG_CTRAES | DRBG_SYM192)
+#define DRBG_NOPR_CTRAES256 (DRBG_CTRAES | DRBG_SYM256)
+#define DRBG_PR_HASHSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1)
+#define DRBG_PR_HASHSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256)
+#define DRBG_PR_HASHSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384)
+#define DRBG_PR_HASHSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512)
+#define DRBG_NOPR_HASHSHA1 (DRBG_HASHSHA1)
+#define DRBG_NOPR_HASHSHA256 (DRBG_HASHSHA256)
+#define DRBG_NOPR_HASHSHA384 (DRBG_HASHSHA384)
+#define DRBG_NOPR_HASHSHA512 (DRBG_HASHSHA512)
+#define DRBG_PR_HMACSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1 \
+ | DRBG_HMAC)
+#define DRBG_PR_HMACSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256 \
+ | DRBG_HMAC)
+#define DRBG_PR_HMACSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384 \
+ | DRBG_HMAC)
+#define DRBG_PR_HMACSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512 \
+ | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA1 (DRBG_HASHSHA1 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA256 (DRBG_HASHSHA256 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA384 (DRBG_HASHSHA384 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA512 (DRBG_HASHSHA512 | DRBG_HMAC)
+
+
+/* The default DRGB type. */
+#define DRBG_DEFAULT_TYPE DRBG_NOPR_HMACSHA256
+
+
+#define DRBG_CTR_NULL_LEN 128
+
+
+/******************************************************************
+ * Common data structures
+ ******************************************************************/
+
+/*
+ * SP800-90A requires the concatenation of different data. To avoid copying
+ * buffers around or allocate additional memory, the following data structure
+ * is used to point to the original memory with its size. In addition, it
+ * is used to build a linked list. The linked list defines the concatenation
+ * of individual buffers. The order of memory block referenced in that
+ * linked list determines the order of concatenation.
+ */
+struct drbg_string_s
+{
+ const unsigned char *buf;
+ size_t len;
+ struct drbg_string_s *next;
+};
+typedef struct drbg_string_s drbg_string_t;
+
+
+/* DRBG input data structure for DRBG generate with additional
+ * information string. */
+struct drbg_gen_s
+{
+ unsigned char *outbuf; /* output buffer for random numbers */
+ unsigned int outlen; /* size of output buffer */
+ drbg_string_t *addtl; /* input buffer for
+ * additional information string */
+};
+typedef struct drbg_gen_s drbg_gen_t;
+
+
+/* Forward declaration of the state object pointer. */
+struct drbg_state_s;
+typedef struct drbg_state_s *drbg_state_t;
+
+
+struct drbg_core_s
+{
+ u32 flags; /* flags for the cipher */
+ ushort statelen; /* maximum state length */
+ ushort blocklen_bytes; /* block size of output in bytes */
+ int backend_cipher; /* libgcrypt backend cipher */
+};
+
+struct drbg_state_ops_s
+{
+ gpg_err_code_t (*update) (drbg_state_t drbg,
+ drbg_string_t *seed, int reseed);
+ gpg_err_code_t (*generate) (drbg_state_t drbg,
+ unsigned char *buf, unsigned int buflen,
+ drbg_string_t *addtl);
+ gpg_err_code_t (*crypto_init) (drbg_state_t drbg);
+ void (*crypto_fini) (drbg_state_t drbg);
+};
+
+struct drbg_test_data_s
+{
+ drbg_string_t *testentropy; /* TEST PARAMETER: test entropy */
+ int fail_seed_source:1; /* If set, the seed function will
+ * return an error. */
+};
+
+
+/* This state object keeps the state of an DRBG instance. */
+struct drbg_state_s
+{
+ unsigned char *V; /* internal state 10.1.1.1 1a) */
+ unsigned char *C; /* hash: static value 10.1.1.1 1b)
+ * hmac / ctr: key */
+ size_t reseed_ctr; /* Number of RNG requests since last reseed --
+ * 10.1.1.1 1c) */
+ unsigned char *scratchpad; /* some memory the DRBG can use for its
+ * operation -- allocated during init */
+ void *priv_data; /* Cipher handle */
+ gcry_cipher_hd_t ctr_handle; /* CTR mode cipher handle */
+ int seeded:1; /* DRBG fully seeded? */
+ int pr:1; /* Prediction resistance enabled? */
+ /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the
+ * process which did the initialization so that we can detect a fork.
+ * The volatile modifier is required so that the compiler does not
+ * optimize it away in case the getpid function is badly attributed. */
+ pid_t seed_init_pid;
+ const struct drbg_state_ops_s *d_ops;
+ const struct drbg_core_s *core;
+ struct drbg_test_data_s *test_data;
+};
+
+enum drbg_prefixes
+{
+ DRBG_PREFIX0 = 0x00,
+ DRBG_PREFIX1,
+ DRBG_PREFIX2,
+ DRBG_PREFIX3
+};
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+/***************************************************************
+ * Global variables
+ ***************************************************************/
+
+/* Global state variable holding the current instance of the DRBG. */
+static drbg_state_t drbg_state;
+
+/* This is the lock variable we use to serialize access to this RNG. */
+GPGRT_LOCK_DEFINE(drbg_lock_var);
+
+
+/***************************************************************
+ * Backend cipher definitions available to DRBG
+ ***************************************************************/
+
+static const struct drbg_core_s drbg_cores[] = {
+ /* Hash DRBGs */
+ {DRBG_HASHSHA1, 55, 20, GCRY_MD_SHA1},
+ {DRBG_HASHSHA256, 55, 32, GCRY_MD_SHA256},
+ {DRBG_HASHSHA384, 111, 48, GCRY_MD_SHA384},
+ {DRBG_HASHSHA512, 111, 64, GCRY_MD_SHA512},
+ /* HMAC DRBGs */
+ {DRBG_HASHSHA1 | DRBG_HMAC, 20, 20, GCRY_MD_SHA1},
+ {DRBG_HASHSHA256 | DRBG_HMAC, 32, 32, GCRY_MD_SHA256},
+ {DRBG_HASHSHA384 | DRBG_HMAC, 48, 48, GCRY_MD_SHA384},
+ {DRBG_HASHSHA512 | DRBG_HMAC, 64, 64, GCRY_MD_SHA512},
+ /* block ciphers */
+ {DRBG_CTRAES | DRBG_SYM128, 32, 16, GCRY_CIPHER_AES128},
+ {DRBG_CTRAES | DRBG_SYM192, 40, 16, GCRY_CIPHER_AES192},
+ {DRBG_CTRAES | DRBG_SYM256, 48, 16, GCRY_CIPHER_AES256}
+};
+
+static gpg_err_code_t drbg_hash_init (drbg_state_t drbg);
+static gpg_err_code_t drbg_hmac_init (drbg_state_t drbg);
+static gpg_err_code_t drbg_hmac_setkey (drbg_state_t drbg,
+ const unsigned char *key);
+static void drbg_hash_fini (drbg_state_t drbg);
+static byte *drbg_hash (drbg_state_t drbg, const drbg_string_t *buf);
+static gpg_err_code_t drbg_sym_init (drbg_state_t drbg);
+static void drbg_sym_fini (drbg_state_t drbg);
+static gpg_err_code_t drbg_sym_setkey (drbg_state_t drbg,
+ const unsigned char *key);
+static gpg_err_code_t drbg_sym (drbg_state_t drbg, unsigned char *outval,
+ const drbg_string_t *buf);
+static gpg_err_code_t drbg_sym_ctr (drbg_state_t drbg,
+ const unsigned char *inbuf, unsigned int inbuflen,
+ unsigned char *outbuf, unsigned int outbuflen);
+
+/******************************************************************
+ ******************************************************************
+ ******************************************************************
+ * Generic DRBG code
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************/
+
+/******************************************************************
+ * Generic helper functions
+ ******************************************************************/
+
+#if 0
+#define dbg(x) do { log_debug x; } while(0)
+#else
+#define dbg(x)
+#endif
+
+/*
+ * Parse a string of flags and store the flag values at R_FLAGS.
+ * Return 0 on success.
+ */
+static gpg_err_code_t
+parse_flag_string (const char *string, u32 *r_flags)
+{
+ struct {
+ const char *name;
+ u32 flag;
+ } table[] = {
+ { "aes", DRBG_CTRAES },
+ { "serpent", DRBG_CTRSERPENT },
+ { "twofish", DRBG_CTRTWOFISH },
+ { "sha1", DRBG_HASHSHA1 },
+ { "sha256", DRBG_HASHSHA256 },
+ { "sha512", DRBG_HASHSHA512 },
+ { "hmac", DRBG_HMAC },
+ { "sym128", DRBG_SYM128 },
+ { "sym192", DRBG_SYM192 },
+ { "sym256", DRBG_SYM256 },
+ { "pr", DRBG_PREDICTION_RESIST }
+ };
+
+ *r_flags = 0;
+ if (string)
+ {
+ char **tl;
+ const char *s;
+ int i, j;
+
+ tl = _gcry_strtokenize (string, NULL);
+ if (!tl)
+ return gpg_err_code_from_syserror ();
+ for (i=0; (s=tl[i]); i++)
+ {
+ for (j=0; j < DIM (table); j++)
+ if (!strcmp (s, table[j].name))
+ {
+ *r_flags |= table[j].flag;
+ break;
+ }
+ if (!(j < DIM (table)))
+ {
+ xfree (tl);
+ return GPG_ERR_INV_FLAG;
+ }
+ }
+ xfree (tl);
+ }
+
+ return 0;
+}
+
+static inline void
+drbg_string_fill (drbg_string_t *string,
+ const unsigned char *buf, size_t len)
+{
+ string->buf = buf;
+ string->len = len;
+ string->next = NULL;
+}
+
+static inline ushort
+drbg_statelen (drbg_state_t drbg)
+{
+ if (drbg && drbg->core)
+ return drbg->core->statelen;
+ return 0;
+}
+
+static inline ushort
+drbg_blocklen (drbg_state_t drbg)
+{
+ if (drbg && drbg->core)
+ return drbg->core->blocklen_bytes;
+ return 0;
+}
+
+static inline ushort
+drbg_keylen (drbg_state_t drbg)
+{
+ if (drbg && drbg->core)
+ return (drbg->core->statelen - drbg->core->blocklen_bytes);
+ return 0;
+}
+
+static inline size_t
+drbg_max_request_bytes (void)
+{
+ /* SP800-90A requires the limit 2**19 bits, but we return bytes */
+ return (1 << 16);
+}
+
+static inline size_t
+drbg_max_addtl (void)
+{
+ /* SP800-90A requires 2**35 bytes additional info str / pers str */
+#ifdef __LP64__
+ return (1UL << 35);
+#else
+ /*
+ * SP800-90A allows smaller maximum numbers to be returned -- we
+ * return SIZE_MAX - 1 to allow the verification of the enforcement
+ * of this value in drbg_healthcheck_sanity.
+ */
+ return (SIZE_MAX - 1);
+#endif
+}
+
+static inline size_t
+drbg_max_requests (void)
+{
+ /* SP800-90A requires 2**48 maximum requests before reseeding */
+#ifdef __LP64__
+ return (1UL << 48);
+#else
+ return SIZE_MAX;
+#endif
+}
+
+/*
+ * Return strength of DRBG according to SP800-90A section 8.4
+ *
+ * flags: DRBG flags reference
+ *
+ * Return: normalized strength value or 32 as a default to counter
+ * programming errors
+ */
+static inline unsigned short
+drbg_sec_strength (u32 flags)
+{
+ if ((flags & DRBG_HASHSHA1) || (flags & DRBG_SYM128))
+ return 16;
+ else if (flags & DRBG_SYM192)
+ return 24;
+ else if ((flags & DRBG_SYM256) || (flags & DRBG_HASHSHA256) ||
+ (flags & DRBG_HASHSHA384) || (flags & DRBG_HASHSHA512))
+ return 32;
+ else
+ return 32;
+}
+
+static void
+drbg_add_buf (unsigned char *dst, size_t dstlen,
+ unsigned char *add, size_t addlen)
+{
+ /* implied: dstlen > addlen */
+ unsigned char *dstptr, *addptr;
+ unsigned int remainder = 0;
+ size_t len = addlen;
+
+ dstptr = dst + (dstlen - 1);
+ addptr = add + (addlen - 1);
+ while (len)
+ {
+ remainder += *dstptr + *addptr;
+ *dstptr = remainder & 0xff;
+ remainder >>= 8;
+ len--;
+ dstptr--;
+ addptr--;
+ }
+ len = dstlen - addlen;
+ while (len && remainder > 0)
+ {
+ remainder = *dstptr + 1;
+ *dstptr = remainder & 0xff;
+ remainder >>= 8;
+ len--;
+ dstptr--;
+ }
+}
+
+/* Helper variables for read_cb().
+ *
+ * The _gcry_rnd*_gather_random interface does not allow to provide a
+ * data pointer. Thus we need to use a global variable for
+ * communication. However, the then required locking is anyway a good
+ * idea because it does not make sense to have several readers of (say
+ * /dev/random). It is easier to serve them one after the other.
+ */
+static unsigned char *read_cb_buffer; /* The buffer. */
+static size_t read_cb_size; /* Size of the buffer. */
+static size_t read_cb_len; /* Used length. */
+
+/* Callback for generating seed from kernel device. */
+static void
+drbg_read_cb (const void *buffer, size_t length,
+ enum random_origins origin)
+{
+ const unsigned char *p = buffer;
+
+ (void) origin;
+ gcry_assert (read_cb_buffer);
+
+ /* Note that we need to protect against gatherers returning more
+ * than the requested bytes (e.g. rndw32). */
+ while (length-- && read_cb_len < read_cb_size)
+ read_cb_buffer[read_cb_len++] = *p++;
+}
+
+static inline int
+drbg_get_entropy (drbg_state_t drbg, unsigned char *buffer,
+ size_t len)
+{
+ int rc = 0;
+
+ /* Perform testing as defined in 11.3.2 */
+ if (drbg->test_data && drbg->test_data->fail_seed_source)
+ return -1;
+
+ read_cb_buffer = buffer;
+ read_cb_size = len;
+ read_cb_len = 0;
+#if USE_RNDLINUX
+ rc = _gcry_rndlinux_gather_random (drbg_read_cb, 0, len,
+ GCRY_VERY_STRONG_RANDOM);
+#elif USE_RNDUNIX
+ rc = _gcry_rndunix_gather_random (drbg_read_cb, 0, len,
+ GCRY_VERY_STRONG_RANDOM);
+#elif USE_RNDW32
+ do
+ {
+ rc = _gcry_rndw32_gather_random (drbg_read_cb, 0, len,
+ GCRY_VERY_STRONG_RANDOM);
+ }
+ while (rc >= 0 && read_cb_len < read_cb_size);
+#else
+ rc = -1;
+#endif
+ return rc;
+}
+
+/******************************************************************
+ * CTR DRBG callback functions
+ ******************************************************************/
+
+/* BCC function for CTR DRBG as defined in 10.4.3 */
+static gpg_err_code_t
+drbg_ctr_bcc (drbg_state_t drbg,
+ unsigned char *out, const unsigned char *key,
+ drbg_string_t *in)
+{
+ gpg_err_code_t ret = GPG_ERR_GENERAL;
+ drbg_string_t *curr = in;
+ size_t inpos = curr->len;
+ const unsigned char *pos = curr->buf;
+ drbg_string_t data;
+
+ drbg_string_fill (&data, out, drbg_blocklen (drbg));
+
+ /* 10.4.3 step 1 */
+ memset (out, 0, drbg_blocklen (drbg));
+
+ ret = drbg_sym_setkey(drbg, key);
+ if (ret)
+ return ret;
+
+ /* 10.4.3 step 2 / 4 */
+ while (inpos)
+ {
+ short cnt = 0;
+ /* 10.4.3 step 4.1 */
+ for (cnt = 0; cnt < drbg_blocklen (drbg); cnt++)
+ {
+ out[cnt] ^= *pos;
+ pos++;
+ inpos--;
+ /* the following branch implements the linked list
+ * iteration. If we are at the end of the current data
+ * set, we have to start using the next data set if
+ * available -- the inpos value always points to the
+ * current byte and will be zero if we have processed
+ * the last byte of the last linked list member */
+ if (0 == inpos)
+ {
+ curr = curr->next;
+ if (NULL != curr)
+ {
+ pos = curr->buf;
+ inpos = curr->len;
+ }
+ else
+ {
+ inpos = 0;
+ break;
+ }
+ }
+ }
+ /* 10.4.3 step 4.2 */
+ ret = drbg_sym (drbg, out, &data);
+ if (ret)
+ return ret;
+ /* 10.4.3 step 2 */
+ }
+ return 0;
+}
+
+
+/*
+ * scratchpad usage: drbg_ctr_update is interlinked with drbg_ctr_df
+ * (and drbg_ctr_bcc, but this function does not need any temporary buffers),
+ * the scratchpad is used as follows:
+ * drbg_ctr_update:
+ * temp
+ * start: drbg->scratchpad
+ * length: drbg_statelen(drbg) + drbg_blocklen(drbg)
+ * note: the cipher writing into this variable works
+ * blocklen-wise. Now, when the statelen is not a multiple
+ * of blocklen, the generateion loop below "spills over"
+ * by at most blocklen. Thus, we need to give sufficient
+ * memory.
+ * df_data
+ * start: drbg->scratchpad +
+ * drbg_statelen(drbg) +
+ * drbg_blocklen(drbg)
+ * length: drbg_statelen(drbg)
+ *
+ * drbg_ctr_df:
+ * pad
+ * start: df_data + drbg_statelen(drbg)
+ * length: drbg_blocklen(drbg)
+ * iv
+ * start: pad + drbg_blocklen(drbg)
+ * length: drbg_blocklen(drbg)
+ * temp
+ * start: iv + drbg_blocklen(drbg)
+ * length: drbg_satelen(drbg) + drbg_blocklen(drbg)
+ * note: temp is the buffer that the BCC function operates
+ * on. BCC operates blockwise. drbg_statelen(drbg)
+ * is sufficient when the DRBG state length is a multiple
+ * of the block size. For AES192 (and maybe other ciphers)
+ * this is not correct and the length for temp is
+ * insufficient (yes, that also means for such ciphers,
+ * the final output of all BCC rounds are truncated).
+ * Therefore, add drbg_blocklen(drbg) to cover all
+ * possibilities.
+ */
+
+/* Derivation Function for CTR DRBG as defined in 10.4.2 */
+static gpg_err_code_t
+drbg_ctr_df (drbg_state_t drbg, unsigned char *df_data,
+ size_t bytes_to_return, drbg_string_t *addtl)
+{
+ gpg_err_code_t ret = GPG_ERR_GENERAL;
+ unsigned char L_N[8];
+ /* S3 is input */
+ drbg_string_t S1, S2, S4, cipherin;
+ drbg_string_t *tempstr = addtl;
+ unsigned char *pad = df_data + drbg_statelen (drbg);
+ unsigned char *iv = pad + drbg_blocklen (drbg);
+ unsigned char *temp = iv + drbg_blocklen (drbg);
+ size_t padlen = 0;
+ unsigned int templen = 0;
+ /* 10.4.2 step 7 */
+ unsigned int i = 0;
+ /* 10.4.2 step 8 */
+ const unsigned char *K = (unsigned char *)
+ "\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";
+ unsigned char *X;
+ size_t generated_len = 0;
+ size_t inputlen = 0;
+
+ memset (pad, 0, drbg_blocklen (drbg));
+ memset (iv, 0, drbg_blocklen (drbg));
+ memset (temp, 0, drbg_statelen (drbg));
+
+ /* 10.4.2 step 1 is implicit as we work byte-wise */
+
+ /* 10.4.2 step 2 */
+ if ((512 / 8) < bytes_to_return)
+ return GPG_ERR_INV_ARG;
+
+ /* 10.4.2 step 2 -- calculate the entire length of all input data */
+ for (; NULL != tempstr; tempstr = tempstr->next)
+ inputlen += tempstr->len;
+ buf_put_be32 (&L_N[0], inputlen);
+
+ /* 10.4.2 step 3 */
+ buf_put_be32 (&L_N[4], bytes_to_return);
+
+ /* 10.4.2 step 5: length is size of L_N, input_string, one byte, padding */
+ padlen = (inputlen + sizeof (L_N) + 1) % (drbg_blocklen (drbg));
+ /* wrap the padlen appropriately */
+ if (padlen)
+ padlen = drbg_blocklen (drbg) - padlen;
+ /* pad / padlen contains the 0x80 byte and the following zero bytes, so
+ * add one for byte for 0x80 */
+ padlen++;
+ pad[0] = 0x80;
+
+ /* 10.4.2 step 4 -- first fill the linked list and then order it */
+ drbg_string_fill (&S1, iv, drbg_blocklen (drbg));
+ drbg_string_fill (&S2, L_N, sizeof (L_N));
+ drbg_string_fill (&S4, pad, padlen);
+ S1.next = &S2;
+ S2.next = addtl;
+
+ /* Splice in addtl between S2 and S4 -- we place S4 at the end of the
+ * input data chain. As this code is only triggered when addtl is not
+ * NULL, no NULL checks are necessary.*/
+ tempstr = addtl;
+ while (tempstr->next)
+ tempstr = tempstr->next;
+ tempstr->next = &S4;
+
+ /* 10.4.2 step 9 */
+ while (templen < (drbg_keylen (drbg) + (drbg_blocklen (drbg))))
+ {
+ /* 10.4.2 step 9.1 - the padding is implicit as the buffer
+ * holds zeros after allocation -- even the increment of i
+ * is irrelevant as the increment remains within length of i */
+ buf_put_be32 (iv, i);
+ /* 10.4.2 step 9.2 -- BCC and concatenation with temp */
+ ret = drbg_ctr_bcc (drbg, temp + templen, K, &S1);
+ if (ret)
+ goto out;
+ /* 10.4.2 step 9.3 */
+ i++;
+ templen += drbg_blocklen (drbg);
+ }
+
+ /* 10.4.2 step 11 */
+ /* implicit key len with seedlen - blocklen according to table 3 */
+ X = temp + (drbg_keylen (drbg));
+ drbg_string_fill (&cipherin, X, drbg_blocklen (drbg));
+
+ /* 10.4.2 step 12: overwriting of outval */
+
+ /* 10.4.2 step 13 */
+ ret = drbg_sym_setkey(drbg, temp);
+ if (ret)
+ goto out;
+ while (generated_len < bytes_to_return)
+ {
+ short blocklen = 0;
+ /* 10.4.2 step 13.1 */
+ /* the truncation of the key length is implicit as the key
+ * is only drbg_blocklen in size -- check for the implementation
+ * of the cipher function callback */
+ ret = drbg_sym (drbg, X, &cipherin);
+ if (ret)
+ goto out;
+ blocklen = (drbg_blocklen (drbg) < (bytes_to_return - generated_len)) ?
+ drbg_blocklen (drbg) : (bytes_to_return - generated_len);
+ /* 10.4.2 step 13.2 and 14 */
+ memcpy (df_data + generated_len, X, blocklen);
+ generated_len += blocklen;
+ }
+
+ ret = 0;
+
+ out:
+ memset (iv, 0, drbg_blocklen (drbg));
+ memset (temp, 0, drbg_statelen (drbg));
+ memset (pad, 0, drbg_blocklen (drbg));
+ return ret;
+}
+
+/*
+ * Update function of CTR DRBG as defined in 10.2.1.2
+ *
+ * The reseed variable has an enhanced meaning compared to the update
+ * functions of the other DRBGs as follows:
+ * 0 => initial seed from initialization
+ * 1 => reseed via drbg_seed
+ * 2 => first invocation from drbg_ctr_update when addtl is present. In
+ * this case, the df_data scratchpad is not deleted so that it is
+ * available for another calls to prevent calling the DF function
+ * again.
+ * 3 => second invocation from drbg_ctr_update. When the update function
+ * was called with addtl, the df_data memory already contains the
+ * DFed addtl information and we do not need to call DF again.
+ */
+static gpg_err_code_t
+drbg_ctr_update (drbg_state_t drbg, drbg_string_t *addtl, int reseed)
+{
+ gpg_err_code_t ret = GPG_ERR_GENERAL;
+ /* 10.2.1.2 step 1 */
+ unsigned char *temp = drbg->scratchpad;
+ unsigned char *df_data = drbg->scratchpad +
+ drbg_statelen (drbg) + drbg_blocklen (drbg);
+ unsigned char prefix = DRBG_PREFIX1;
+
+ memset (temp, 0, drbg_statelen (drbg) + drbg_blocklen (drbg));
+ if (3 > reseed)
+ memset (df_data, 0, drbg_statelen (drbg));
+
+ if (!reseed)
+ {
+ /*
+ * The DRBG uses the CTR mode of the underlying AES cipher. The
+ * CTR mode increments the counter value after the AES operation
+ * but SP800-90A requires that the counter is incremented before
+ * the AES operation. Hence, we increment it at the time we set
+ * it by one.
+ */
+ drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
+
+ ret = _gcry_cipher_setkey (drbg->ctr_handle, drbg->C, drbg_keylen (drbg));
+ if (ret)
+ goto out;
+ }
+
+ /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
+ if (addtl && 0 < addtl->len)
+ {
+ ret =
+ drbg_ctr_df (drbg, df_data, drbg_statelen (drbg), addtl);
+ if (ret)
+ goto out;
+ }
+
+ ret = drbg_sym_ctr (drbg, df_data, drbg_statelen(drbg),
+ temp, drbg_statelen(drbg));
+ if (ret)
+ goto out;
+
+ /* 10.2.1.2 step 5 */
+ ret = _gcry_cipher_setkey (drbg->ctr_handle, temp, drbg_keylen (drbg));
+ if (ret)
+ goto out;
+
+ /* 10.2.1.2 step 6 */
+ memcpy (drbg->V, temp + drbg_keylen (drbg), drbg_blocklen (drbg));
+ /* See above: increment counter by one to compensate timing of CTR op */
+ drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1);
+ ret = 0;
+
+ out:
+ memset (temp, 0, drbg_statelen (drbg) + drbg_blocklen (drbg));
+ if (2 != reseed)
+ memset (df_data, 0, drbg_statelen (drbg));
+ return ret;
+}
+
+/*
+ * scratchpad use: drbg_ctr_update is called independently from
+ * drbg_ctr_extract_bytes. Therefore, the scratchpad is reused
+ */
+/* Generate function of CTR DRBG as defined in 10.2.1.5.2 */
+static gpg_err_code_t
+drbg_ctr_generate (drbg_state_t drbg,
+ unsigned char *buf, unsigned int buflen,
+ drbg_string_t *addtl)
+{
+ static const unsigned char drbg_ctr_null[DRBG_CTR_NULL_LEN] = { 0, };
+ gpg_err_code_t ret = 0;
+
+ memset (drbg->scratchpad, 0, drbg_blocklen (drbg));
+
+ /* 10.2.1.5.2 step 2 */
+ if (addtl && 0 < addtl->len)
+ {
+ addtl->next = NULL;
+ ret = drbg_ctr_update (drbg, addtl, 2);
+ if (ret)
+ return ret;
+ }
+
+ /* 10.2.1.5.2 step 4.1 */
+ ret = drbg_sym_ctr (drbg, drbg_ctr_null, sizeof(drbg_ctr_null), buf, buflen);
+ if (ret)
+ goto out;
+
+ /* 10.2.1.5.2 step 6 */
+ if (addtl)
+ addtl->next = NULL;
+ ret = drbg_ctr_update (drbg, addtl, 3);
+
+ out:
+ return ret;
+}
+
+static struct drbg_state_ops_s drbg_ctr_ops = {
+ drbg_ctr_update,
+ drbg_ctr_generate,
+ drbg_sym_init,
+ drbg_sym_fini,
+};
+
+/******************************************************************
+ * HMAC DRBG callback functions
+ ******************************************************************/
+
+static gpg_err_code_t
+drbg_hmac_update (drbg_state_t drbg, drbg_string_t *seed, int reseed)
+{
+ gpg_err_code_t ret = GPG_ERR_GENERAL;
+ int i = 0;
+ drbg_string_t seed1, seed2, cipherin;
+
+ if (!reseed)
+ {
+ /* 10.1.2.3 step 2 already implicitly covered with
+ * the initial memset(0) of drbg->C */
+ memset (drbg->V, 1, drbg_statelen (drbg));
+ ret = drbg_hmac_setkey (drbg, drbg->C);
+ if (ret)
+ return ret;
+ }
+
+ /* build linked list which implements the concatenation and fill
+ * first part*/
+ drbg_string_fill (&seed1, drbg->V, drbg_statelen (drbg));
+ /* buffer will be filled in for loop below with one byte */
+ drbg_string_fill (&seed2, NULL, 1);
+ seed1.next = &seed2;
+ /* seed may be NULL */
+ seed2.next = seed;
+
+ drbg_string_fill (&cipherin, drbg->V, drbg_statelen (drbg));
+ /* we execute two rounds of V/K massaging */
+ for (i = 2; 0 < i; i--)
+ {
+ byte *retval;
+ /* first round uses 0x0, second 0x1 */
+ unsigned char prefix = DRBG_PREFIX0;
+ if (1 == i)
+ prefix = DRBG_PREFIX1;
+ /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
+ seed2.buf = &prefix;
+ retval = drbg_hash (drbg, &seed1);
+ ret = drbg_hmac_setkey (drbg, retval);
+ if (ret)
+ return ret;
+
+ /* 10.1.2.2 step 2 and 5 -- HMAC for V */
+ retval = drbg_hash (drbg, &cipherin);
+ memcpy(drbg->V, retval, drbg_blocklen (drbg));
+
+ /* 10.1.2.2 step 3 */
+ if (!seed || 0 == seed->len)
+ return ret;
+ }
+ return 0;
+}
+
+/* generate function of HMAC DRBG as defined in 10.1.2.5 */
+static gpg_err_code_t
+drbg_hmac_generate (drbg_state_t drbg, unsigned char *buf, unsigned int buflen,
+ drbg_string_t *addtl)
+{
+ gpg_err_code_t ret = 0;
+ unsigned int len = 0;
+ drbg_string_t data;
+
+ /* 10.1.2.5 step 2 */
+ if (addtl && 0 < addtl->len)
+ {
+ addtl->next = NULL;
+ ret = drbg_hmac_update (drbg, addtl, 1);
+ if (ret)
+ return ret;
+ }
+
+ drbg_string_fill (&data, drbg->V, drbg_statelen (drbg));
+ while (len < buflen)
+ {
+ unsigned int outlen = 0;
+ /* 10.1.2.5 step 4.1 */
+ byte *retval = drbg_hash (drbg, &data);
+ memcpy(drbg->V, retval, drbg_blocklen (drbg));
+ outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
+ drbg_blocklen (drbg) : (buflen - len);
+
+ /* 10.1.2.5 step 4.2 */
+ memcpy (buf + len, drbg->V, outlen);
+ len += outlen;
+ }
+
+ /* 10.1.2.5 step 6 */
+ if (addtl)
+ addtl->next = NULL;
+ ret = drbg_hmac_update (drbg, addtl, 1);
+
+ return ret;
+}
+
+static struct drbg_state_ops_s drbg_hmac_ops = {
+ drbg_hmac_update,
+ drbg_hmac_generate,
+ drbg_hmac_init,
+ drbg_hash_fini,
+};
+
+/******************************************************************
+ * Hash DRBG callback functions
+ ******************************************************************/
+
+/*
+ * scratchpad usage: as drbg_hash_update and drbg_hash_df are used
+ * interlinked, the scratchpad is used as follows:
+ * drbg_hash_update
+ * start: drbg->scratchpad
+ * length: drbg_statelen(drbg)
+ * drbg_hash_df:
+ * start: drbg->scratchpad + drbg_statelen(drbg)
+ * length: drbg_blocklen(drbg)
+ */
+/* Derivation Function for Hash DRBG as defined in 10.4.1 */
+static gpg_err_code_t
+drbg_hash_df (drbg_state_t drbg,
+ unsigned char *outval, size_t outlen,
+ drbg_string_t *entropy)
+{
+ size_t len = 0;
+ unsigned char input[5];
+ drbg_string_t data1;
+
+ /* 10.4.1 step 3 */
+ input[0] = 1;
+ buf_put_be32 (&input[1], (outlen * 8));
+
+ /* 10.4.1 step 4.1 -- concatenation of data for input into hash */
+ drbg_string_fill (&data1, input, 5);
+ data1.next = entropy;
+
+ /* 10.4.1 step 4 */
+ while (len < outlen)
+ {
+ short blocklen = 0;
+ /* 10.4.1 step 4.1 */
+ byte *retval = drbg_hash (drbg, &data1);
+ /* 10.4.1 step 4.2 */
+ input[0]++;
+ blocklen = (drbg_blocklen (drbg) < (outlen - len)) ?
+ drbg_blocklen (drbg) : (outlen - len);
+ memcpy (outval + len, retval, blocklen);
+ len += blocklen;
+ }
+
+ return 0;
+}
+
+/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */
+static gpg_err_code_t
+drbg_hash_update (drbg_state_t drbg, drbg_string_t *seed, int reseed)
+{
+ gpg_err_code_t ret = 0;
+ drbg_string_t data1, data2;
+ unsigned char *V = drbg->scratchpad;
+ unsigned char prefix = DRBG_PREFIX1;
+
+ memset (drbg->scratchpad, 0, drbg_statelen (drbg));
+ if (!seed)
+ return GPG_ERR_INV_ARG;
+
+ if (reseed)
+ {
+ /* 10.1.1.3 step 1: string length is concatenation of
+ * 1 byte, V and seed (which is concatenated entropy/addtl
+ * input)
+ */
+ memcpy (V, drbg->V, drbg_statelen (drbg));
+ drbg_string_fill (&data1, &prefix, 1);
+ drbg_string_fill (&data2, V, drbg_statelen (drbg));
+ data1.next = &data2;
+ data2.next = seed;
+ }
+ else
+ {
+ drbg_string_fill (&data1, seed->buf, seed->len);
+ data1.next = seed->next;
+ }
+
+ /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */
+ ret = drbg_hash_df (drbg, drbg->V, drbg_statelen (drbg), &data1);
+ if (ret)
+ goto out;
+
+ /* 10.1.1.2 / 10.1.1.3 step 4 -- concatenation */
+ prefix = DRBG_PREFIX0;
+ drbg_string_fill (&data1, &prefix, 1);
+ drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg));
+ data1.next = &data2;
+ /* 10.1.1.2 / 10.1.1.3 step 4 -- df operation */
+ ret = drbg_hash_df (drbg, drbg->C, drbg_statelen (drbg), &data1);
+
+ out:
+ memset (drbg->scratchpad, 0, drbg_statelen (drbg));
+ return ret;
+}
+
+/* Processing of additional information string for Hash DRBG. */
+static gpg_err_code_t
+drbg_hash_process_addtl (drbg_state_t drbg, drbg_string_t *addtl)
+{
+ drbg_string_t data1, data2;
+ drbg_string_t *data3;
+ unsigned char prefix = DRBG_PREFIX2;
+ byte *retval;
+
+ /* 10.1.1.4 step 2 */
+ if (!addtl || 0 == addtl->len)
+ return 0;
+
+ /* 10.1.1.4 step 2a -- concatenation */
+ drbg_string_fill (&data1, &prefix, 1);
+ drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg));
+ data3 = addtl;
+ data1.next = &data2;
+ data2.next = data3;
+ data3->next = NULL;
+ /* 10.1.1.4 step 2a -- cipher invocation */
+ retval = drbg_hash (drbg, &data1);
+
+ /* 10.1.1.4 step 2b */
+ drbg_add_buf (drbg->V, drbg_statelen (drbg), retval, drbg_blocklen (drbg));
+
+ return 0;
+}
+
+/*
+ * Hashgen defined in 10.1.1.4
+ */
+static gpg_err_code_t
+drbg_hash_hashgen (drbg_state_t drbg, unsigned char *buf, unsigned int buflen)
+{
+ unsigned int len = 0;
+ unsigned char *src = drbg->scratchpad;
+ drbg_string_t data;
+ unsigned char prefix = DRBG_PREFIX1;
+
+ /* 10.1.1.4 step hashgen 2 */
+ memcpy (src, drbg->V, drbg_statelen (drbg));
+
+ drbg_string_fill (&data, src, drbg_statelen (drbg));
+ while (len < buflen)
+ {
+ unsigned int outlen = 0;
+ /* 10.1.1.4 step hashgen 4.1 */
+ byte *retval = drbg_hash (drbg, &data);
+ outlen = (drbg_blocklen (drbg) < (buflen - len)) ?
+ drbg_blocklen (drbg) : (buflen - len);
+ /* 10.1.1.4 step hashgen 4.2 */
+ memcpy (buf + len, retval, outlen);
+ len += outlen;
+ /* 10.1.1.4 hashgen step 4.3 */
+ if (len < buflen)
+ drbg_add_buf (src, drbg_statelen (drbg), &prefix, 1);
+ }
+
+ memset (drbg->scratchpad, 0, drbg_statelen (drbg));
+ return 0;
+}
+
+/* Generate function for Hash DRBG as defined in 10.1.1.4 */
+static gpg_err_code_t
+drbg_hash_generate (drbg_state_t drbg, unsigned char *buf, unsigned int buflen,
+ drbg_string_t *addtl)
+{
+ gpg_err_code_t ret;
+ unsigned char prefix = DRBG_PREFIX3;
+ drbg_string_t data1, data2;
+ byte *retval;
+ union
+ {
+ unsigned char req[8];
+ u64 req_int;
+ } u;
+
+ /* 10.1.1.4 step 2 */
+ ret = drbg_hash_process_addtl (drbg, addtl);
+ if (ret)
+ return ret;
+ /* 10.1.1.4 step 3 -- invocation of the Hashgen function defined in
+ * 10.1.1.4 */
+ ret = drbg_hash_hashgen (drbg, buf, buflen);
+ if (ret)
+ return ret;
+
+ /* 10.1.1.4 step 4 */
+ drbg_string_fill (&data1, &prefix, 1);
+ drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg));
+ data1.next = &data2;
+
+ /* this is the value H as documented in 10.1.1.4 */
+ retval = drbg_hash (drbg, &data1);
+
+ /* 10.1.1.4 step 5 */
+ drbg_add_buf (drbg->V, drbg_statelen (drbg), retval, drbg_blocklen (drbg));
+ drbg_add_buf (drbg->V, drbg_statelen (drbg), drbg->C, drbg_statelen (drbg));
+ u.req_int = be_bswap64 (drbg->reseed_ctr);
+ drbg_add_buf (drbg->V, drbg_statelen (drbg), u.req, sizeof (u.req));
+
+ return ret;
+}
+
+/*
+ * scratchpad usage: as update and generate are used isolated, both
+ * can use the scratchpad
+ */
+static struct drbg_state_ops_s drbg_hash_ops = {
+ drbg_hash_update,
+ drbg_hash_generate,
+ drbg_hash_init,
+ drbg_hash_fini,
+};
+
+/******************************************************************
+ * Functions common for DRBG implementations
+ ******************************************************************/
+
+/*
+ * Seeding or reseeding of the DRBG
+ *
+ * @drbg: DRBG state struct
+ * @pers: personalization / additional information buffer
+ * @reseed: 0 for initial seed process, 1 for reseeding
+ *
+ * return:
+ * 0 on success
+ * error value otherwise
+ */
+static gpg_err_code_t
+drbg_seed (drbg_state_t drbg, drbg_string_t *pers, int reseed)
+{
+ gpg_err_code_t ret = 0;
+ unsigned char *entropy = NULL;
+ size_t entropylen = 0;
+ drbg_string_t data1;
+
+ /* 9.1 / 9.2 / 9.3.1 step 3 */
+ if (pers && pers->len > (drbg_max_addtl ()))
+ {
+ dbg (("DRBG: personalization string too long %lu\n", pers->len));
+ return GPG_ERR_INV_ARG;
+ }
+ if (drbg->test_data && drbg->test_data->testentropy)
+ {
+ drbg_string_fill (&data1, drbg->test_data->testentropy->buf,
+ drbg->test_data->testentropy->len);
+ dbg (("DRBG: using test entropy\n"));
+ }
+ else
+ {
+ /* Gather entropy equal to the security strength of the DRBG.
+ * With a derivation function, a nonce is required in addition
+ * to the entropy. A nonce must be at least 1/2 of the security
+ * strength of the DRBG in size. Thus, entropy * nonce is 3/2
+ * of the strength. The consideration of a nonce is only
+ * applicable during initial seeding. */
+ entropylen = drbg_sec_strength (drbg->core->flags);
+ if (!entropylen)
+ return GPG_ERR_GENERAL;
+ if (0 == reseed)
+ /* make sure we round up strength/2 in
+ * case it is not divisible by 2 */
+ entropylen = ((entropylen + 1) / 2) * 3;
+ dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen));
+ entropy = xcalloc_secure (1, entropylen);
+ if (!entropy)
+ return GPG_ERR_ENOMEM;
+ ret = drbg_get_entropy (drbg, entropy, entropylen);
+ if (ret)
+ goto out;
+ drbg_string_fill (&data1, entropy, entropylen);
+ }
+
+ /* concatenation of entropy with personalization str / addtl input)
+ * the variable pers is directly handed by the caller, check its
+ * contents whether it is appropriate */
+ if (pers && pers->buf && 0 < pers->len && NULL == pers->next)
+ {
+ data1.next = pers;
+ dbg (("DRBG: using personalization string\n"));
+ }
+
+ ret = drbg->d_ops->update (drbg, &data1, reseed);
+ dbg (("DRBG: state updated with seed\n"));
+ if (ret)
+ goto out;
+ drbg->seeded = 1;
+ /* 10.1.1.2 / 10.1.1.3 step 5 */
+ drbg->reseed_ctr = 1;
+
+ out:
+ xfree (entropy);
+ return ret;
+}
+
+
+/*************************************************************************
+ * Exported interfaces.
+ *************************************************************************/
+
+/*
+ * DRBG generate function as required by SP800-90A - this function
+ * generates random numbers
+ *
+ * @drbg DRBG state handle
+ * @buf Buffer where to store the random numbers -- the buffer must already
+ * be pre-allocated by caller
+ * @buflen Length of output buffer - this value defines the number of random
+ * bytes pulled from DRBG
+ * @addtl Additional input that is mixed into state, may be NULL -- note
+ * the entropy is pulled by the DRBG internally unconditionally
+ * as defined in SP800-90A. The additional input is mixed into
+ * the state in addition to the pulled entropy.
+ *
+ * return: Generated number of bytes.
+ */
+static gpg_err_code_t
+drbg_generate (drbg_state_t drbg,
+ unsigned char *buf, unsigned int buflen,
+ drbg_string_t *addtl)
+{
+ gpg_err_code_t ret = GPG_ERR_INV_ARG;
+
+ if (0 == buflen || !buf)
+ {
+ dbg (("DRBG: no buffer provided\n"));
+ return ret;
+ }
+ if (addtl && NULL == addtl->buf && 0 < addtl->len)
+ {
+ dbg (("DRBG: wrong format of additional information\n"));
+ return ret;
+ }
+
+ /* 9.3.1 step 2 */
+ if (buflen > (drbg_max_request_bytes ()))
+ {
+ dbg (("DRBG: requested random numbers too large %u\n", buflen));
+ return ret;
+ }
+ /* 9.3.1 step 3 is implicit with the chosen DRBG */
+ /* 9.3.1 step 4 */
+ if (addtl && addtl->len > (drbg_max_addtl ()))
+ {
+ dbg (("DRBG: additional information string too long %lu\n",
+ addtl->len));
+ return ret;
+ }
+ /* 9.3.1 step 5 is implicit with the chosen DRBG */
+ /* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c -- the spec is a
+ * bit convoluted here, we make it simpler */
+ if ((drbg_max_requests ()) < drbg->reseed_ctr)
+ drbg->seeded = 0;
+
+ if (drbg->pr || !drbg->seeded)
+ {
+ dbg (("DRBG: reseeding before generation (prediction resistance: %s, state %s)\n", drbg->pr ? "true" : "false", drbg->seeded ? "seeded" : "unseeded"));
+ /* 9.3.1 steps 7.1 through 7.3 */
+ ret = drbg_seed (drbg, addtl, 1);
+ if (ret)
+ return ret;
+ /* 9.3.1 step 7.4 */
+ addtl = NULL;
+ }
+
+ if (addtl && addtl->buf)
+ {
+ dbg (("DRBG: using additional information string\n"));
+ }
+
+ /* 9.3.1 step 8 and 10 */
+ ret = drbg->d_ops->generate (drbg, buf, buflen, addtl);
+
+ /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */
+ drbg->reseed_ctr++;
+ if (ret)
+ return ret;
+
+ /* 11.3.3 -- re-perform self tests after some generated random
+ * numbers, the chosen value after which self test is performed
+ * is arbitrary, but it should be reasonable */
+ /* Here we do not perform the self tests because of the following
+ * reasons: it is mathematically impossible that the initial self tests
+ * were successfully and the following are not. If the initial would
+ * pass and the following would not, the system integrity is violated.
+ * In this case, the entire system operation is questionable and it
+ * is unlikely that the integrity violation only affects to the
+ * correct operation of the DRBG.
+ */
+#if 0
+ if (drbg->reseed_ctr && !(drbg->reseed_ctr % 4096))
+ {
+ dbg (("DRBG: start to perform self test\n"));
+ ret = drbg_healthcheck ();
+ if (ret)
+ {
+ log_fatal (("DRBG: self test failed\n"));
+ return ret;
+ }
+ else
+ {
+ dbg (("DRBG: self test successful\n"));
+ }
+ }
+#endif
+
+ return ret;
+}
+
+/*
+ * Wrapper around drbg_generate which can pull arbitrary long strings
+ * from the DRBG without hitting the maximum request limitation.
+ *
+ * Parameters: see drbg_generate
+ * Return codes: see drbg_generate -- if one drbg_generate request fails,
+ * the entire drbg_generate_long request fails
+ */
+static gpg_err_code_t
+drbg_generate_long (drbg_state_t drbg,
+ unsigned char *buf, unsigned int buflen,
+ drbg_string_t *addtl)
+{
+ gpg_err_code_t ret = 0;
+ unsigned int slice = 0;
+ unsigned char *buf_p = buf;
+ unsigned len = 0;
+ do
+ {
+ unsigned int chunk = 0;
+ slice = ((buflen - len) / drbg_max_request_bytes ());
+ chunk = slice ? drbg_max_request_bytes () : (buflen - len);
+ ret = drbg_generate (drbg, buf_p, chunk, addtl);
+ if (ret)
+ return ret;
+ buf_p += chunk;
+ len += chunk;
+ }
+ while (slice > 0 && (len < buflen));
+ return ret;
+}
+
+/*
+ * DRBG uninstantiate function as required by SP800-90A - this function
+ * frees all buffers and the DRBG handle
+ *
+ * @drbg DRBG state handle
+ *
+ * return
+ * 0 on success
+ */
+static gpg_err_code_t
+drbg_uninstantiate (drbg_state_t drbg)
+{
+ if (!drbg)
+ return GPG_ERR_INV_ARG;
+ drbg->d_ops->crypto_fini(drbg);
+ xfree (drbg->V);
+ drbg->V = NULL;
+ xfree (drbg->C);
+ drbg->C = NULL;
+ drbg->reseed_ctr = 0;
+ xfree (drbg->scratchpad);
+ drbg->scratchpad = NULL;
+ drbg->seeded = 0;
+ drbg->pr = 0;
+ drbg->seed_init_pid = 0;
+ return 0;
+}
+
+/*
+ * DRBG instantiation function as required by SP800-90A - this function
+ * sets up the DRBG handle, performs the initial seeding and all sanity
+ * checks required by SP800-90A
+ *
+ * @drbg memory of state -- if NULL, new memory is allocated
+ * @pers Personalization string that is mixed into state, may be NULL -- note
+ * the entropy is pulled by the DRBG internally unconditionally
+ * as defined in SP800-90A. The additional input is mixed into
+ * the state in addition to the pulled entropy.
+ * @coreref reference to core
+ * @flags Flags defining the requested DRBG type and cipher type. The flags
+ * are defined in drbg.h and may be XORed. Beware, if you XOR multiple
+ * cipher types together, the code picks the core on a first come first
+ * serve basis as it iterates through the available cipher cores and
+ * uses the one with the first match. The minimum required flags are:
+ * cipher type flag
+ *
+ * return
+ * 0 on success
+ * error value otherwise
+ */
+static gpg_err_code_t
+drbg_instantiate (drbg_state_t drbg,
+ drbg_string_t *pers, int coreref, int pr)
+{
+ gpg_err_code_t ret = GPG_ERR_ENOMEM;
+ unsigned int sb_size = 0;
+
+ if (!drbg)
+ return GPG_ERR_INV_ARG;
+
+ dbg (("DRBG: Initializing DRBG core %d with prediction resistance %s\n",
+ coreref, pr ? "enabled" : "disabled"));
+ drbg->core = &drbg_cores[coreref];
+ drbg->pr = pr;
+ drbg->seeded = 0;
+ if (drbg->core->flags & DRBG_HMAC)
+ drbg->d_ops = &drbg_hmac_ops;
+ else if (drbg->core->flags & DRBG_HASH_MASK)
+ drbg->d_ops = &drbg_hash_ops;
+ else if (drbg->core->flags & DRBG_CTR_MASK)
+ drbg->d_ops = &drbg_ctr_ops;
+ else
+ return GPG_ERR_GENERAL;
+ /* 9.1 step 1 is implicit with the selected DRBG type -- see
+ * drbg_sec_strength() */
+
+ /* 9.1 step 2 is implicit as caller can select prediction resistance
+ * and the flag is copied into drbg->flags --
+ * all DRBG types support prediction resistance */
+
+ /* 9.1 step 4 is implicit in drbg_sec_strength */
+
+ ret = drbg->d_ops->crypto_init(drbg);
+ if (ret)
+ goto err;
+
+ drbg->V = xcalloc_secure (1, drbg_statelen (drbg));
+ if (!drbg->V)
+ goto fini;
+ drbg->C = xcalloc_secure (1, drbg_statelen (drbg));
+ if (!drbg->C)
+ goto fini;
+ /* scratchpad is only generated for CTR and Hash */
+ if (drbg->core->flags & DRBG_HMAC)
+ sb_size = 0;
+ else if (drbg->core->flags & DRBG_CTR_MASK)
+ sb_size = drbg_statelen (drbg) + drbg_blocklen (drbg) + /* temp */
+ drbg_statelen (drbg) + /* df_data */
+ drbg_blocklen (drbg) + /* pad */
+ drbg_blocklen (drbg) + /* iv */
+ drbg_statelen (drbg) + drbg_blocklen (drbg); /* temp */
+ else
+ sb_size = drbg_statelen (drbg);
+
+ if (0 < sb_size)
+ {
+ drbg->scratchpad = xcalloc_secure (1, sb_size);
+ if (!drbg->scratchpad)
+ goto fini;
+ }
+ dbg (("DRBG: state allocated with scratchpad size %u bytes\n", sb_size));
+
+ /* 9.1 step 6 through 11 */
+ ret = drbg_seed (drbg, pers, 0);
+ if (ret)
+ goto fini;
+
+ dbg (("DRBG: core %d %s prediction resistance successfully initialized\n",
+ coreref, pr ? "with" : "without"));
+ return 0;
+
+ fini:
+ drbg->d_ops->crypto_fini(drbg);
+ err:
+ drbg_uninstantiate (drbg);
+ return ret;
+}
+
+/*
+ * DRBG reseed function as required by SP800-90A
+ *
+ * @drbg DRBG state handle
+ * @addtl Additional input that is mixed into state, may be NULL -- note
+ * the entropy is pulled by the DRBG internally unconditionally
+ * as defined in SP800-90A. The additional input is mixed into
+ * the state in addition to the pulled entropy.
+ *
+ * return
+ * 0 on success
+ * error value otherwise
+ */
+static gpg_err_code_t
+drbg_reseed (drbg_state_t drbg,drbg_string_t *addtl)
+{
+ gpg_err_code_t ret = 0;
+ ret = drbg_seed (drbg, addtl, 1);
+ return ret;
+}
+
+
+
+/******************************************************************
+ * Libgcrypt integration code.
+ ******************************************************************/
+
+/***************************************************
+ * Libgcrypt backend functions to the RNG API code.
+ ***************************************************/
+
+static inline void
+drbg_lock (void)
+{
+ gpg_err_code_t ec;
+
+ ec = gpgrt_lock_lock (&drbg_lock_var);
+ if (ec)
+ log_fatal ("failed to acquire the RNG lock: %s\n", gpg_strerror (ec));
+}
+
+static inline void
+drbg_unlock (void)
+{
+ gpg_err_code_t ec;
+
+ ec = gpgrt_lock_unlock (&drbg_lock_var);
+ if (ec)
+ log_fatal ("failed to release the RNG lock: %s\n", gpg_strerror (ec));
+}
+
+/* Basic initialization is required to initialize mutexes and
+ do a few checks on the implementation. */
+static void
+basic_initialization (void)
+{
+ static int initialized;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+ /* Make sure that we are still using the values we have
+ traditionally used for the random levels. */
+ gcry_assert (GCRY_WEAK_RANDOM == 0
+ && GCRY_STRONG_RANDOM == 1
+ && GCRY_VERY_STRONG_RANDOM == 2);
+}
+
+/****** helper functions where lock must be held by caller *****/
+
+/* Check whether given flags are known to point to an applicable DRBG */
+static gpg_err_code_t
+drbg_algo_available (u32 flags, int *coreref)
+{
+ int i = 0;
+ for (i = 0; ARRAY_SIZE (drbg_cores) > i; i++)
+ {
+ if ((drbg_cores[i].flags & DRBG_CIPHER_MASK) ==
+ (flags & DRBG_CIPHER_MASK))
+ {
+ *coreref = i;
+ return 0;
+ }
+ }
+ return GPG_ERR_GENERAL;
+}
+
+static gpg_err_code_t
+_drbg_init_internal (u32 flags, drbg_string_t *pers)
+{
+ static u32 oldflags;
+ gpg_err_code_t ret = 0;
+ int coreref = 0;
+ int pr = 0;
+
+ /* If a caller provides 0 as flags, use the flags of the previous
+ * initialization, otherwise use the current flags and remember them
+ * for the next invocation. If no flag is given and no global state
+ * is set this is the first initialization and we set the default
+ * type.
+ */
+ if (!flags && !drbg_state)
+ flags = oldflags = DRBG_DEFAULT_TYPE;
+ else if (!flags)
+ flags = oldflags;
+ else
+ oldflags = flags;
+
+ ret = drbg_algo_available (flags, &coreref);
+ if (ret)
+ return ret;
+
+ if (drbg_state)
+ {
+ drbg_uninstantiate (drbg_state);
+ }
+ else
+ {
+ drbg_state = xtrycalloc_secure (1, sizeof *drbg_state);
+ if (!drbg_state)
+ return gpg_err_code_from_syserror ();
+ }
+ if (flags & DRBG_PREDICTION_RESIST)
+ pr = 1;
+ ret = drbg_instantiate (drbg_state, pers, coreref, pr);
+ if (ret)
+ fips_signal_error ("DRBG cannot be initialized");
+ else
+ drbg_state->seed_init_pid = getpid ();
+ return ret;
+}
+
+/************* calls available to common RNG code **************/
+
+/*
+ * Initialize one DRBG invoked by the libgcrypt API
+ */
+void
+_gcry_rngdrbg_inititialize (int full)
+{
+ basic_initialization ();
+ if (!full)
+ return;
+ drbg_lock ();
+ if (!drbg_state)
+ _drbg_init_internal (0, NULL);
+ drbg_unlock ();
+}
+
+/*
+ * Backend handler function for GCRYCTL_DRBG_REINIT
+ *
+ * Select a different DRBG type and initialize it.
+ * Function checks whether requested DRBG type exists and returns an error in
+ * case it does not. In case of an error, the previous instantiated DRBG is
+ * left untouched and alive. Thus, in case of an error, a DRBG is always
+ * available, even if it is not the chosen one.
+ *
+ * Re-initialization will be performed in any case regardless whether flags
+ * or personalization string are set.
+ *
+ * If flags is NULL, do not change current DRBG. If PERS is NULL and
+ * NPERS is 0, re-initialize without personalization string. If PERS
+ * is not NULL NPERS must be one and PERS and the first ietm from the
+ * bufer is take as personalization string.
+ */
+gpg_err_code_t
+_gcry_rngdrbg_reinit (const char *flagstr, gcry_buffer_t *pers, int npers)
+{
+ gpg_err_code_t ret;
+ unsigned int flags;
+
+ /* If PERS is not given we expect NPERS to be zero; if given we
+ expect a one-item array. */
+ if ((!pers && npers) || (pers && npers != 1))
+ return GPG_ERR_INV_ARG;
+
+ ret = parse_flag_string (flagstr, &flags);
+ if (!ret)
+ {
+ dbg (("DRBG: reinitialize internal DRBG state with flags %u\n", flags));
+ drbg_lock ();
+ if (pers)
+ {
+ drbg_string_t persbuf;
+
+ drbg_string_fill
+ (&persbuf, (const unsigned char *)pers[0].data + pers[0].off,
+ pers[0].len);
+ ret = _drbg_init_internal (flags, &persbuf);
+ }
+ else
+ ret = _drbg_init_internal (flags, NULL);
+ drbg_unlock ();
+ }
+ return ret;
+}
+
+/* Try to close the FDs of the random gather module. This is
+ * currently only implemented for rndlinux. */
+void
+_gcry_rngdrbg_close_fds (void)
+{
+#if USE_RNDLINUX
+ drbg_lock ();
+ _gcry_rndlinux_gather_random (NULL, 0, 0, 0);
+ drbg_unlock ();
+#endif
+}
+
+/* Print some statistics about the RNG. */
+void
+_gcry_rngdrbg_dump_stats (void)
+{
+ /* Not yet implemented. */
+ /* Maybe dumping of reseed counter? */
+}
+
+/* This function returns true if no real RNG is available or the
+ * quality of the RNG has been degraded for test purposes. */
+int
+_gcry_rngdrbg_is_faked (void)
+{
+ return 0; /* Faked random is not allowed. */
+}
+
+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY
+ * should be in the range of 0..100 to indicate the goodness of the
+ * entropy added, or -1 for goodness not known. */
+gcry_error_t
+_gcry_rngdrbg_add_bytes (const void *buf, size_t buflen, int quality)
+{
+ gpg_err_code_t ret = 0;
+ drbg_string_t seed;
+ (void) quality;
+ _gcry_rngdrbg_inititialize (1); /* Auto-initialize if needed */
+ if (!drbg_state)
+ return GPG_ERR_GENERAL;
+ drbg_string_fill (&seed, (unsigned char *) buf, buflen);
+ drbg_lock ();
+ ret = drbg_reseed (drbg_state, &seed);
+ drbg_unlock ();
+ return ret;
+}
+
+/* This function is to be used for all types of random numbers, including
+ * nonces
+ */
+void
+_gcry_rngdrbg_randomize (void *buffer, size_t length,
+ enum gcry_random_level level)
+{
+ (void) level;
+ _gcry_rngdrbg_inititialize (1); /* Auto-initialize if needed */
+ drbg_lock ();
+ if (!drbg_state)
+ {
+ fips_signal_error ("DRBG is not initialized");
+ goto bailout;
+ }
+
+ /* As reseeding changes the entire state of the DRBG, including any
+ * key, either a re-init or a reseed is sufficient for a fork */
+ if (drbg_state->seed_init_pid != getpid ())
+ {
+ /* We are in a child of us. Perform a reseeding. */
+ if (drbg_reseed (drbg_state, NULL))
+ {
+ fips_signal_error ("reseeding upon fork failed");
+ log_fatal ("severe error getting random\n");
+ goto bailout;
+ }
+ }
+ /* potential integer overflow is covered by drbg_generate which
+ * ensures that length cannot overflow an unsigned int */
+ if (0 < length)
+ {
+ if (!buffer)
+ goto bailout;
+ if (drbg_generate_long (drbg_state, buffer, (unsigned int) length, NULL))
+ log_fatal ("No random numbers generated\n");
+ }
+ else
+ {
+ drbg_gen_t *data = (drbg_gen_t *)buffer;
+ /* catch NULL pointer */
+ if (!data || !data->outbuf)
+ {
+ fips_signal_error ("No output buffer provided");
+ goto bailout;
+ }
+ if (drbg_generate_long (drbg_state, data->outbuf, data->outlen,
+ data->addtl))
+ log_fatal ("No random numbers generated\n");
+ }
+
+ bailout:
+ drbg_unlock ();
+ return;
+
+}
+
+/***************************************************************
+ * Self-test code
+ ***************************************************************/
+
+/*
+ * Test vectors from
+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip
+ */
+struct gcry_drbg_test_vector drbg_test_pr[] = {
+ {
+ /* .flags = */ "sha256 pr" /* DRBG_PR_HASHSHA256 */,
+ /* .entropy = */ (unsigned char *)
+ "\x5d\xf2\x14\xbc\xf6\xb5\x4e\x0b\xf0\x0d\x6f\x2d"
+ "\xe2\x01\x66\x7b\xd0\xa4\x73\xa4\x21\xdd\xb0\xc0"
+ "\x51\x79\x09\xf4\xea\xa9\x08\xfa\xa6\x67\xe0\xe1"
+ "\xd1\x88\xa8\xad\xee\x69\x74\xb3\x55\x06\x9b\xf6",
+ /* .entropylen = */ 48,
+ /* .entpra = */ (unsigned char *)
+ "\xef\x48\x06\xa2\xc2\x45\xf1\x44\xfa\x34\x2c\xeb"
+ "\x8d\x78\x3c\x09\x8f\x34\x72\x20\xf2\xe7\xfd\x13"
+ "\x76\x0a\xf6\xdc\x3c\xf5\xc0\x15",
+ /* .entprb = */ (unsigned char *)
+ "\x4b\xbe\xe5\x24\xed\x6a\x2d\x0c\xdb\x73\x5e\x09"
+ "\xf9\xad\x67\x7c\x51\x47\x8b\x6b\x30\x2a\xc6\xde"
+ "\x76\xaa\x55\x04\x8b\x0a\x72\x95",
+ /* .entprlen = */ 32,
+ /* .addtla = */ (unsigned char *)
+ "\xbe\x13\xdb\x2a\xe9\xa8\xfe\x09\x97\xe1\xce\x5d"
+ "\xe8\xbb\xc0\x7c\x4f\xcb\x62\x19\x3f\x0f\xd2\xad"
+ "\xa9\xd0\x1d\x59\x02\xc4\xff\x70",
+ /* .addtlb = */ (unsigned char *)
+ "\x6f\x96\x13\xe2\xa7\xf5\x6c\xfe\xdf\x66\xe3\x31"
+ "\x63\x76\xbf\x20\x27\x06\x49\xf1\xf3\x01\x77\x41"
+ "\x9f\xeb\xe4\x38\xfe\x67\x00\xcd",
+ /* .addtllen = */ 32,
+ /* .pers = */ NULL,
+ /* .perslen = */ 0,
+ /* .expected = */ (unsigned char *)
+ "\x3b\x14\x71\x99\xa1\xda\xa0\x42\xe6\xc8\x85\x32"
+ "\x70\x20\x32\x53\x9a\xbe\xd1\x1e\x15\xef\xfb\x4c"
+ "\x25\x6e\x19\x3a\xf0\xb9\xcb\xde\xf0\x3b\xc6\x18"
+ "\x4d\x85\x5a\x9b\xf1\xe3\xc2\x23\x03\x93\x08\xdb"
+ "\xa7\x07\x4b\x33\x78\x40\x4d\xeb\x24\xf5\x6e\x81"
+ "\x4a\x1b\x6e\xa3\x94\x52\x43\xb0\xaf\x2e\x21\xf4"
+ "\x42\x46\x8e\x90\xed\x34\x21\x75\xea\xda\x67\xb6"
+ "\xe4\xf6\xff\xc6\x31\x6c\x9a\x5a\xdb\xb3\x97\x13"
+ "\x09\xd3\x20\x98\x33\x2d\x6d\xd7\xb5\x6a\xa8\xa9"
+ "\x9a\x5b\xd6\x87\x52\xa1\x89\x2b\x4b\x9c\x64\x60"
+ "\x50\x47\xa3\x63\x81\x16\xaf\x19",
+ /* .expectedlen = */ 128,
+ /* .entropyreseed = */ NULL,
+ /* .entropyreseed_len = */ 0,
+ /* .addtl_reseed = */ NULL,
+ /* .addtl_reseed_len = */ 0
+ },
+ {
+ /* flags = */ "hmac sha256 pr" /* DRBG_PR_HMACSHA256 */,
+ /* .entropy = */ (unsigned char *)
+ "\x13\x54\x96\xfc\x1b\x7d\x28\xf3\x18\xc9\xa7\x89"
+ "\xb6\xb3\xc8\x72\xac\x00\xd4\x59\x36\x25\x05\xaf"
+ "\xa5\xdb\x96\xcb\x3c\x58\x46\x87\xa5\xaa\xbf\x20"
+ "\x3b\xfe\x23\x0e\xd1\xc7\x41\x0f\x3f\xc9\xb3\x67",
+ /* .entropylen = */ 48,
+ /* .entpra = */ (unsigned char *)
+ "\xe2\xbd\xb7\x48\x08\x06\xf3\xe1\x93\x3c\xac\x79"
+ "\xa7\x2b\x11\xda\xe3\x2e\xe1\x91\xa5\x02\x19\x57"
+ "\x20\x28\xad\xf2\x60\xd7\xcd\x45",
+ /* .entprb = */ (unsigned char *)
+ "\x8b\xd4\x69\xfc\xff\x59\x95\x95\xc6\x51\xde\x71"
+ "\x68\x5f\xfc\xf9\x4a\xab\xec\x5a\xcb\xbe\xd3\x66"
+ "\x1f\xfa\x74\xd3\xac\xa6\x74\x60",
+ /* .entprlen = */ 32,
+ /* .addtla = */ NULL,
+ /* .addtlb = */ NULL,
+ /* .addtllen = */ 0,
+ /* .pers = */ (unsigned char *)
+ "\x64\xb6\xfc\x60\xbc\x61\x76\x23\x6d\x3f\x4a\x0f"
+ "\xe1\xb4\xd5\x20\x9e\x70\xdd\x03\x53\x6d\xbf\xce"
+ "\xcd\x56\x80\xbc\xb8\x15\xc8\xaa",
+ /* .perslen = */ 32,
+ /* .expected = */ (unsigned char *)
+ "\x1f\x9e\xaf\xe4\xd2\x46\xb7\x47\x41\x4c\x65\x99"
+ "\x01\xe9\x3b\xbb\x83\x0c\x0a\xb0\xc1\x3a\xe2\xb3"
+ "\x31\x4e\xeb\x93\x73\xee\x0b\x26\xc2\x63\xa5\x75"
+ "\x45\x99\xd4\x5c\x9f\xa1\xd4\x45\x87\x6b\x20\x61"
+ "\x40\xea\x78\xa5\x32\xdf\x9e\x66\x17\xaf\xb1\x88"
+ "\x9e\x2e\x23\xdd\xc1\xda\x13\x97\x88\xa5\xb6\x5e"
+ "\x90\x14\x4e\xef\x13\xab\x5c\xd9\x2c\x97\x9e\x7c"
+ "\xd7\xf8\xce\xea\x81\xf5\xcd\x71\x15\x49\x44\xce"
+ "\x83\xb6\x05\xfb\x7d\x30\xb5\x57\x2c\x31\x4f\xfc"
+ "\xfe\x80\xb6\xc0\x13\x0c\x5b\x9b\x2e\x8f\x3d\xfc"
+ "\xc2\xa3\x0c\x11\x1b\x80\x5f\xf3",
+ /* .expectedlen = */ 128,
+ /* .entropyreseed = */ NULL,
+ /* .entropyreseed_len = */ 0,
+ /* .addtl_reseed = */ NULL,
+ /* .addtl_reseed_len = */ 0
+ },
+ {
+ /* .flags = */ "aes sym128 pr", /* DRBG_PR_CTRAES128 */
+ /* .entropy = */ (unsigned char *)
+ "\x92\x89\x8f\x31\xfa\x1c\xff\x6d\x18\x2f\x26\x06"
+ "\x43\xdf\xf8\x18\xc2\xa4\xd9\x72\xc3\xb9\xb6\x97",
+ /* .entropylen = */ 24,
+ /* .entpra = */ (unsigned char *)
+ "\x20\x72\x8a\x06\xf8\x6f\x8d\xd4\x41\xe2\x72\xb7"
+ "\xc4\x2c\xe8\x10",
+ /* .entprb = */ (unsigned char *)
+ "\x3d\xb0\xf0\x94\xf3\x05\x50\x33\x17\x86\x3e\x22"
+ "\x08\xf7\xa5\x01",
+ /* .entprlen = */ 16,
+ /* .addtla = */ (unsigned char *)
+ "\x1a\x40\xfa\xe3\xcc\x6c\x7c\xa0\xf8\xda\xba\x59"
+ "\x23\x6d\xad\x1d",
+ /* .addtlb = */ (unsigned char *)
+ "\x9f\x72\x76\x6c\xc7\x46\xe5\xed\x2e\x53\x20\x12"
+ "\xbc\x59\x31\x8c",
+ /* .addtllen = */ 16,
+ /* .pers = */ (unsigned char *)
+ "\xea\x65\xee\x60\x26\x4e\x7e\xb6\x0e\x82\x68\xc4"
+ "\x37\x3c\x5c\x0b",
+ /* .perslen = */ 16,
+ /* .expected = */ (unsigned char *)
+ "\x5a\x35\x39\x87\x0f\x4d\x22\xa4\x09\x24\xee\x71"
+ "\xc9\x6f\xac\x72\x0a\xd6\xf0\x88\x82\xd0\x83\x28"
+ "\x73\xec\x3f\x93\xd8\xab\x45\x23\xf0\x7e\xac\x45"
+ "\x14\x5e\x93\x9f\xb1\xd6\x76\x43\x3d\xb6\xe8\x08"
+ "\x88\xf6\xda\x89\x08\x77\x42\xfe\x1a\xf4\x3f\xc4"
+ "\x23\xc5\x1f\x68",
+ /* .expectedlen = */ 64,
+ /* .entropyreseed = */ NULL,
+ /* .entropyreseed_len = */ 0,
+ /* .addtl_reseed = */ NULL,
+ /* .addtl_reseed_len = */ 0
+ }
+};
+
+struct gcry_drbg_test_vector drbg_test_nopr[] = {
+ {
+ /* .flags = */ "sha256" /* DRBG_NOPR_HASHSHA256 */,
+ /* .entropy = */ (unsigned char *)
+ "\x73\xd3\xfb\xa3\x94\x5f\x2b\x5f\xb9\x8f\xf6\x9c"
+ "\x8a\x93\x17\xae\x19\xc3\x4c\xc3\xd6\xca\xa3\x2d"
+ "\x16\xfc\x42\xd2\x2d\xd5\x6f\x56\xcc\x1d\x30\xff"
+ "\x9e\x06\x3e\x09\xce\x58\xe6\x9a\x35\xb3\xa6\x56",
+ /* .entropylen = */ 48,
+ /* .entpra = */ NULL,
+ /* .entprb = */ NULL,
+ /* .entprlen = */ 0,
+ /* .addtla = */ (unsigned char *)
+ "\xf4\xd5\x98\x3d\xa8\xfc\xfa\x37\xb7\x54\x67\x73"
+ "\xc7\xc3\xdd\x47\x34\x71\x02\x5d\xc1\xa0\xd3\x10"
+ "\xc1\x8b\xbd\xf5\x66\x34\x6f\xdd",
+ /* .addtlb = */ (unsigned char *)
+ "\xf7\x9e\x6a\x56\x0e\x73\xe9\xd9\x7a\xd1\x69\xe0"
+ "\x6f\x8c\x55\x1c\x44\xd1\xce\x6f\x28\xcc\xa4\x4d"
+ "\xa8\xc0\x85\xd1\x5a\x0c\x59\x40",
+ /* .addtllen = */ 32,
+ /* .pers = */ NULL,
+ /* .perslen = */ 0,
+ /* .expected = */ (unsigned char *)
+ "\x71\x7b\x93\x46\x1a\x40\xaa\x35\xa4\xaa\xc5\xe7"
+ "\x6d\x5b\x5b\x8a\xa0\xdf\x39\x7d\xae\x71\x58\x5b"
+ "\x3c\x7c\xb4\xf0\x89\xfa\x4a\x8c\xa9\x5c\x54\xc0"
+ "\x40\xdf\xbc\xce\x26\x81\x34\xf8\xba\x7d\x1c\xe8"
+ "\xad\x21\xe0\x74\xcf\x48\x84\x30\x1f\xa1\xd5\x4f"
+ "\x81\x42\x2f\xf4\xdb\x0b\x23\xf8\x73\x27\xb8\x1d"
+ "\x42\xf8\x44\x58\xd8\x5b\x29\x27\x0a\xf8\x69\x59"
+ "\xb5\x78\x44\xeb\x9e\xe0\x68\x6f\x42\x9a\xb0\x5b"
+ "\xe0\x4e\xcb\x6a\xaa\xe2\xd2\xd5\x33\x25\x3e\xe0"
+ "\x6c\xc7\x6a\x07\xa5\x03\x83\x9f\xe2\x8b\xd1\x1c"
+ "\x70\xa8\x07\x59\x97\xeb\xf6\xbe",
+ /* .expectedlen = */ 128,
+ /* .entropyreseed = */ NULL,
+ /* .entropyreseed_len = */ 0,
+ /* .addtl_reseed = */ NULL,
+ /* .addtl_reseed_len = */ 0
+ },
+ {
+ /* .flags = */ "hmac sha256" /* DRBG_NOPR_HMACSHA256 */,
+ /* .entropy = */ (unsigned char *)
+ "\x8d\xf0\x13\xb4\xd1\x03\x52\x30\x73\x91\x7d\xdf"
+ "\x6a\x86\x97\x93\x05\x9e\x99\x43\xfc\x86\x54\x54"
+ "\x9e\x7a\xb2\x2f\x7c\x29\xf1\x22\xda\x26\x25\xaf"
+ "\x2d\xdd\x4a\xbc\xce\x3c\xf4\xfa\x46\x59\xd8\x4e",
+ /* .entropylen = */ 48,
+ /* .entpra = */ NULL,
+ /* .entprb = */ NULL,
+ /* .entprlen = */ 0,
+ /* .addtla = */ NULL,
+ /* .addtlb = */ NULL,
+ /* .addtllen = */ 0,
+ /* .pers = */ (unsigned char *)
+ "\xb5\x71\xe6\x6d\x7c\x33\x8b\xc0\x7b\x76\xad\x37"
+ "\x57\xbb\x2f\x94\x52\xbf\x7e\x07\x43\x7a\xe8\x58"
+ "\x1c\xe7\xbc\x7c\x3a\xc6\x51\xa9",
+ /* .perslen = */ 32,
+ /* .expected = */ (unsigned char *)
+ "\xb9\x1c\xba\x4c\xc8\x4f\xa2\x5d\xf8\x61\x0b\x81"
+ "\xb6\x41\x40\x27\x68\xa2\x09\x72\x34\x93\x2e\x37"
+ "\xd5\x90\xb1\x15\x4c\xbd\x23\xf9\x74\x52\xe3\x10"
+ "\xe2\x91\xc4\x51\x46\x14\x7f\x0d\xa2\xd8\x17\x61"
+ "\xfe\x90\xfb\xa6\x4f\x94\x41\x9c\x0f\x66\x2b\x28"
+ "\xc1\xed\x94\xda\x48\x7b\xb7\xe7\x3e\xec\x79\x8f"
+ "\xbc\xf9\x81\xb7\x91\xd1\xbe\x4f\x17\x7a\x89\x07"
+ "\xaa\x3c\x40\x16\x43\xa5\xb6\x2b\x87\xb8\x9d\x66"
+ "\xb3\xa6\x0e\x40\xd4\xa8\xe4\xe9\xd8\x2a\xf6\xd2"
+ "\x70\x0e\x6f\x53\x5c\xdb\x51\xf7\x5c\x32\x17\x29"
+ "\x10\x37\x41\x03\x0c\xcc\x3a\x56",
+ /* .expectedlen = */ 128,
+ /* .entropyreseed = */ NULL,
+ /* .entropyreseed_len = */ 0,
+ /* .addtl_reseed = */ NULL,
+ /* .addtl_reseed_len = */ 0
+ },
+ {
+ /* .flags = */ "aes sym128" /* DRBG_NOPR_CTRAES128 */,
+ /* .entropy = */ (unsigned char *)
+ "\xc0\x70\x1f\x92\x50\x75\x8f\xcd\xf2\xbe\x73\x98"
+ "\x80\xdb\x66\xeb\x14\x68\xb4\xa5\x87\x9c\x2d\xa6",
+ /* .entropylen = */ 24,
+ /* .entpra = */ NULL,
+ /* .entprb = */ NULL,
+ /* .entprlen = */ 0,
+ /* .addtla = */ (unsigned char *)
+ "\xf9\x01\xf8\x16\x7a\x1d\xff\xde\x8e\x3c\x83\xe2"
+ "\x44\x85\xe7\xfe",
+ /* .addtlb = */ (unsigned char *)
+ "\x17\x1c\x09\x38\xc2\x38\x9f\x97\x87\x60\x55\xb4"
+ "\x82\x16\x62\x7f",
+ /* .addtllen = */ 16,
+ /* .pers = */ (unsigned char *)
+ "\x80\x08\xae\xe8\xe9\x69\x40\xc5\x08\x73\xc7\x9f"
+ "\x8e\xcf\xe0\x02",
+ /* .perslen = */ 16,
+ /* .expected = */ (unsigned char *)
+ "\x97\xc0\xc0\xe5\xa0\xcc\xf2\x4f\x33\x63\x48\x8a"
+ "\xdb\x13\x0a\x35\x89\xbf\x80\x65\x62\xee\x13\x95"
+ "\x7c\x33\xd3\x7d\xf4\x07\x77\x7a\x2b\x65\x0b\x5f"
+ "\x45\x5c\x13\xf1\x90\x77\x7f\xc5\x04\x3f\xcc\x1a"
+ "\x38\xf8\xcd\x1b\xbb\xd5\x57\xd1\x4a\x4c\x2e\x8a"
+ "\x2b\x49\x1e\x5c",
+ /* .expectedlen = */ 64,
+ /* .entropyreseed = */ NULL,
+ /* .entropyreseed_len = */ 0,
+ /* .addtl_reseed = */ NULL,
+ /* .addtl_reseed_len = */ 0
+ },
+ {
+ /* .flags = */ "sha1" /* DRBG_NOPR_HASHSHA1 */,
+ /* .entropy = */ (unsigned char *)
+ "\x16\x10\xb8\x28\xcc\xd2\x7d\xe0\x8c\xee\xa0\x32"
+ "\xa2\x0e\x92\x08\x49\x2c\xf1\x70\x92\x42\xf6\xb5",
+ /* .entropylen = */ 24,
+ /* .entpra = */ NULL,
+ /* .entprb = */ NULL,
+ /* .entprlen = */ 0,
+ /* .addtla = */ NULL,
+ /* .addtlb = */ NULL,
+ /* .addtllen = */ 0,
+ /* .pers = */ NULL,
+ /* .perslen = */ 0,
+ /* .expected = */ (unsigned char *)
+ "\x56\xf3\x3d\x4f\xdb\xb9\xa5\xb6\x4d\x26\x23\x44"
+ "\x97\xe9\xdc\xb8\x77\x98\xc6\x8d\x08\xf7\xc4\x11"
+ "\x99\xd4\xbd\xdf\x97\xeb\xbf\x6c\xb5\x55\x0e\x5d"
+ "\x14\x9f\xf4\xd5\xbd\x0f\x05\xf2\x5a\x69\x88\xc1"
+ "\x74\x36\x39\x62\x27\x18\x4a\xf8\x4a\x56\x43\x35"
+ "\x65\x8e\x2f\x85\x72\xbe\xa3\x33\xee\xe2\xab\xff"
+ "\x22\xff\xa6\xde\x3e\x22\xac\xa2",
+ /* .expectedlen = */ 80,
+ /* .entropyreseed = */ (unsigned char *)
+ "\x72\xd2\x8c\x90\x8e\xda\xf9\xa4\xd1\xe5\x26\xd8"
+ "\xf2\xde\xd5\x44",
+ /* .entropyreseed_len = */ 16,
+ /* .addtl_reseed = */ NULL,
+ /* .addtl_reseed_len = */ 0
+ },
+ {
+ /* .flags = */ "sha1" /* DRBG_NOPR_HASHSHA1 */,
+ /* .entropy = */ (unsigned char *)
+ "\xd9\xba\xb5\xce\xdc\xa9\x6f\x61\x78\xd6\x45\x09"
+ "\xa0\xdf\xdc\x5e\xda\xd8\x98\x94\x14\x45\x0e\x01",
+ /* .entropylen = */ 24,
+ /* .entpra = */ NULL,
+ /* .entprb = */ NULL,
+ /* .entprlen = */ 0,
+ /* .addtla = */ (unsigned char *)
+ "\x04\xfa\x28\x95\xaa\x5a\x6f\x8c\x57\x43\x34\x3b"
+ "\x80\x5e\x5e\xa4",
+ /* .addtlb = */ (unsigned char *)
+ "\xdf\x5d\xc4\x59\xdf\xf0\x2a\xa2\xf0\x52\xd7\x21"
+ "\xec\x60\x72\x30",
+ /* .addtllen = */ 16,
+ /* .pers = */ NULL,
+ /* .perslen = */ 0,
+ /* .expected = */ (unsigned char *)
+ "\xc4\x8b\x89\xf9\xda\x3f\x74\x82\x45\x55\x5d\x5d"
+ "\x03\x3b\x69\x3d\xd7\x1a\x4d\xf5\x69\x02\x05\xce"
+ "\xfc\xd7\x20\x11\x3c\xc2\x4e\x09\x89\x36\xff\x5e"
+ "\x77\xb5\x41\x53\x58\x70\xb3\x39\x46\x8c\xdd\x8d"
+ "\x6f\xaf\x8c\x56\x16\x3a\x70\x0a\x75\xb2\x3e\x59"
+ "\x9b\x5a\xec\xf1\x6f\x3b\xaf\x6d\x5f\x24\x19\x97"
+ "\x1f\x24\xf4\x46\x72\x0f\xea\xbe",
+ /* .expectedlen = */ 80,
+ /* .entropyreseed = */ (unsigned char *)
+ "\xc6\xba\xd0\x74\xc5\x90\x67\x86\xf5\xe1\xf3\x20"
+ "\x99\xf5\xb4\x91",
+ /* .entropyreseed_len = */ 16,
+ /* .addtl_reseed = */ (unsigned char *)
+ "\x3e\x6b\xf4\x6f\x4d\xaa\x38\x25\xd7\x19\x4e\x69"
+ "\x4e\x77\x52\xf7",
+ /* .addtl_reseed_len = */ 16
+ }
+};
+
+
+/*
+ * Tests implement the CAVS test approach as documented in
+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf
+ */
+
+/*
+ * CAVS test
+ *
+ * This function is not static as it is needed for as a private API
+ * call for the CAVS test tool.
+ */
+gpg_err_code_t
+_gcry_rngdrbg_cavs_test (struct gcry_drbg_test_vector *test, unsigned char *buf)
+{
+ gpg_err_code_t ret = 0;
+ drbg_state_t drbg = NULL;
+ struct drbg_test_data_s test_data;
+ drbg_string_t addtl, pers, testentropy;
+ int coreref = 0;
+ int pr = 0;
+ u32 flags;
+
+ ret = parse_flag_string (test->flagstr, &flags);
+ if (ret)
+ goto outbuf;
+
+ ret = drbg_algo_available (flags, &coreref);
+ if (ret)
+ goto outbuf;
+
+ drbg = xtrycalloc_secure (1, sizeof *drbg);
+ if (!drbg)
+ {
+ ret = gpg_err_code_from_syserror ();
+ goto outbuf;
+ }
+
+ if ((flags & DRBG_PREDICTION_RESIST))
+ pr = 1;
+
+ test_data.testentropy = &testentropy;
+ drbg_string_fill (&testentropy, test->entropy, test->entropylen);
+ drbg->test_data = &test_data;
+ drbg_string_fill (&pers, test->pers, test->perslen);
+ ret = drbg_instantiate (drbg, &pers, coreref, pr);
+ if (ret)
+ goto outbuf;
+
+ if (test->entropyreseed)
+ {
+ drbg_string_fill (&testentropy, test->entropyreseed,
+ test->entropyreseed_len);
+ drbg_string_fill (&addtl, test->addtl_reseed,
+ test->addtl_reseed_len);
+ if (drbg_reseed (drbg, &addtl))
+ goto outbuf;
+ }
+
+ drbg_string_fill (&addtl, test->addtla, test->addtllen);
+ if (test->entpra)
+ {
+ drbg_string_fill (&testentropy, test->entpra, test->entprlen);
+ drbg->test_data = &test_data;
+ }
+ drbg_generate_long (drbg, buf, test->expectedlen, &addtl);
+
+ drbg_string_fill (&addtl, test->addtlb, test->addtllen);
+ if (test->entprb)
+ {
+ drbg_string_fill (&testentropy, test->entprb, test->entprlen);
+ drbg->test_data = &test_data;
+ }
+ drbg_generate_long (drbg, buf, test->expectedlen, &addtl);
+ drbg_uninstantiate (drbg);
+
+ outbuf:
+ xfree (drbg);
+ return ret;
+}
+
+/*
+ * Invoke the CAVS test and perform the final check whether the
+ * calculated random value matches the expected one.
+ *
+ * This function is not static as it is needed for as a private API
+ * call for the CAVS test tool.
+ */
+gpg_err_code_t
+_gcry_rngdrbg_healthcheck_one (struct gcry_drbg_test_vector * test)
+{
+ gpg_err_code_t ret = GPG_ERR_ENOMEM;
+ unsigned char *buf = xcalloc_secure (1, test->expectedlen);
+ if (!buf)
+ return GPG_ERR_ENOMEM;
+
+ ret = _gcry_rngdrbg_cavs_test (test, buf);
+ /* FIXME: The next line is wrong. */
+ ret = memcmp (test->expected, buf, test->expectedlen);
+
+ xfree (buf);
+ return ret;
+}
+
+/*
+ * Tests as defined in 11.3.2 in addition to the cipher tests: testing
+ * of the error handling.
+ *
+ * Note, testing the reseed counter is not done as an automatic reseeding
+ * is performed in drbg_generate when the reseed counter is too large.
+ */
+static gpg_err_code_t
+drbg_healthcheck_sanity (struct gcry_drbg_test_vector *test)
+{
+ unsigned int len = 0;
+ drbg_state_t drbg = NULL;
+ gpg_err_code_t ret = GPG_ERR_GENERAL;
+ gpg_err_code_t tmpret = GPG_ERR_GENERAL;
+ struct drbg_test_data_s test_data;
+ drbg_string_t addtl, testentropy;
+ int coreref = 0;
+ unsigned char *buf = NULL;
+ size_t max_addtllen, max_request_bytes;
+ u32 flags;
+
+ /* only perform test in FIPS mode */
+ if (0 == fips_mode ())
+ return 0;
+
+ ret = parse_flag_string (test->flagstr, &flags);
+ if (ret)
+ return ret;
+ ret = GPG_ERR_GENERAL; /* Fixme: Improve handling of RET. */
+
+ buf = xtrycalloc_secure (1, test->expectedlen);
+ if (!buf)
+ return gpg_err_code_from_syserror ();
+ tmpret = drbg_algo_available (flags, &coreref);
+ if (tmpret)
+ goto outbuf;
+ drbg = xtrycalloc_secure (1, sizeof *drbg);
+ if (!drbg)
+ {
+ ret = gpg_err_code_from_syserror ();
+ goto outbuf;
+ }
+
+ /* if the following tests fail, it is likely that there is a buffer
+ * overflow and we get a SIGSEV */
+ ret = drbg_instantiate (drbg, NULL, coreref, 1);
+ if (ret)
+ goto outbuf;
+ max_addtllen = drbg_max_addtl ();
+ max_request_bytes = drbg_max_request_bytes ();
+ /* overflow addtllen with additional info string */
+ drbg_string_fill (&addtl, test->addtla, (max_addtllen + 1));
+ len = drbg_generate (drbg, buf, test->expectedlen, &addtl);
+ if (len)
+ goto outdrbg;
+
+ /* overflow max_bits */
+ len = drbg_generate (drbg, buf, (max_request_bytes + 1), NULL);
+ if (len)
+ goto outdrbg;
+ drbg_uninstantiate (drbg);
+
+ /* test failing entropy source as defined in 11.3.2 */
+ test_data.testentropy = NULL;
+ test_data.fail_seed_source = 1;
+ drbg->test_data = &test_data;
+ tmpret = drbg_instantiate (drbg, NULL, coreref, 0);
+ if (!tmpret)
+ goto outdrbg;
+ test_data.fail_seed_source = 0;
+
+ test_data.testentropy = &testentropy;
+ drbg_string_fill (&testentropy, test->entropy, test->entropylen);
+ /* overflow max addtllen with personalization string */
+ tmpret = drbg_instantiate (drbg, &addtl, coreref, 0);
+ if (!tmpret)
+ goto outdrbg;
+
+ dbg (("DRBG: Sanity tests for failure code paths successfully completed\n"));
+ ret = 0;
+
+ outdrbg:
+ drbg_uninstantiate (drbg);
+ outbuf:
+ xfree (buf);
+ xfree (drbg);
+ return ret;
+}
+
+/*
+ * DRBG Healthcheck function as required in SP800-90A
+ *
+ * return:
+ * 0 on success (all tests pass)
+ * >0 on error (return code indicate the number of failures)
+ */
+static int
+drbg_healthcheck (void)
+{
+ int ret = 0;
+ ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[0]);
+ ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[1]);
+ ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[2]);
+ ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[3]);
+ ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_nopr[4]);
+ ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_pr[0]);
+ ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_pr[1]);
+ ret += _gcry_rngdrbg_healthcheck_one (&drbg_test_pr[2]);
+ ret += drbg_healthcheck_sanity (&drbg_test_nopr[0]);
+ return ret;
+}
+
+/* Run the self-tests. */
+gcry_error_t
+_gcry_rngdrbg_selftest (selftest_report_func_t report)
+{
+ gcry_err_code_t ec;
+ const char *errtxt = NULL;
+ drbg_lock ();
+ if (0 != drbg_healthcheck ())
+ errtxt = "RNG output does not match known value";
+ drbg_unlock ();
+ if (report && errtxt)
+ report ("random", 0, "KAT", errtxt);
+ ec = errtxt ? GPG_ERR_SELFTEST_FAILED : 0;
+ return gpg_error (ec);
+}
+
+/***************************************************************
+ * Cipher invocations requested by DRBG
+ ***************************************************************/
+
+static gpg_err_code_t
+drbg_hash_init (drbg_state_t drbg)
+{
+ gcry_md_hd_t hd;
+ gpg_error_t err;
+
+ err = _gcry_md_open (&hd, drbg->core->backend_cipher, 0);
+ if (err)
+ return err;
+
+ drbg->priv_data = hd;
+
+ return 0;
+}
+
+static gpg_err_code_t
+drbg_hmac_init (drbg_state_t drbg)
+{
+ gcry_md_hd_t hd;
+ gpg_error_t err;
+
+ err = _gcry_md_open (&hd, drbg->core->backend_cipher, GCRY_MD_FLAG_HMAC);
+ if (err)
+ return err;
+
+ drbg->priv_data = hd;
+
+ return 0;
+}
+
+static gpg_err_code_t
+drbg_hmac_setkey (drbg_state_t drbg, const unsigned char *key)
+{
+ gcry_md_hd_t hd = (gcry_md_hd_t)drbg->priv_data;
+
+ return _gcry_md_setkey (hd, key, drbg_statelen (drbg));
+}
+
+static void
+drbg_hash_fini (drbg_state_t drbg)
+{
+ gcry_md_hd_t hd = (gcry_md_hd_t)drbg->priv_data;
+
+ _gcry_md_close (hd);
+}
+
+static byte *
+drbg_hash (drbg_state_t drbg, const drbg_string_t *buf)
+{
+ gcry_md_hd_t hd = (gcry_md_hd_t)drbg->priv_data;
+
+ _gcry_md_reset(hd);
+ for (; NULL != buf; buf = buf->next)
+ _gcry_md_write (hd, buf->buf, buf->len);
+ _gcry_md_final (hd);
+ return _gcry_md_read (hd, drbg->core->backend_cipher);
+}
+
+static void
+drbg_sym_fini (drbg_state_t drbg)
+{
+ gcry_cipher_hd_t hd = (gcry_cipher_hd_t)drbg->priv_data;
+
+ if (hd)
+ _gcry_cipher_close (hd);
+ if (drbg->ctr_handle)
+ _gcry_cipher_close (drbg->ctr_handle);
+}
+
+static gpg_err_code_t
+drbg_sym_init (drbg_state_t drbg)
+{
+ gcry_cipher_hd_t hd;
+ gpg_error_t err;
+
+ err = _gcry_cipher_open (&hd, drbg->core->backend_cipher,
+ GCRY_CIPHER_MODE_ECB, 0);
+ if (err)
+ {
+ drbg_sym_fini (drbg);
+ return err;
+ }
+ drbg->priv_data = hd;
+
+ err = _gcry_cipher_open (&drbg->ctr_handle, drbg->core->backend_cipher,
+ GCRY_CIPHER_MODE_CTR, 0);
+ if (err)
+ {
+ drbg_sym_fini (drbg);
+ return err;
+ }
+
+
+ if (drbg_blocklen (drbg) !=
+ _gcry_cipher_get_algo_blklen (drbg->core->backend_cipher))
+ {
+ drbg_sym_fini (drbg);
+ return -GPG_ERR_NO_ERROR;
+ }
+
+ return 0;
+}
+
+static gpg_err_code_t
+drbg_sym_setkey (drbg_state_t drbg, const unsigned char *key)
+{
+ gcry_cipher_hd_t hd = (gcry_cipher_hd_t)drbg->priv_data;
+
+ return _gcry_cipher_setkey (hd, key, drbg_keylen (drbg));
+}
+
+static gpg_err_code_t
+drbg_sym (drbg_state_t drbg, unsigned char *outval, const drbg_string_t *buf)
+{
+ gcry_cipher_hd_t hd = (gcry_cipher_hd_t)drbg->priv_data;
+
+ _gcry_cipher_reset(hd);
+ if (drbg_blocklen (drbg) < buf->len)
+ return -GPG_ERR_NO_ERROR;
+ /* in is only component */
+ return _gcry_cipher_encrypt (hd, outval, drbg_blocklen (drbg), buf->buf,
+ buf->len);
+}
+
+static gpg_err_code_t
+drbg_sym_ctr (drbg_state_t drbg,
+ const unsigned char *inbuf, unsigned int inbuflen,
+ unsigned char *outbuf, unsigned int outbuflen)
+{
+ gpg_error_t err;
+
+ _gcry_cipher_reset(drbg->ctr_handle);
+ err = _gcry_cipher_setctr(drbg->ctr_handle, drbg->V, drbg_blocklen (drbg));
+ if (err)
+ return err;
+
+ while (outbuflen)
+ {
+ unsigned int cryptlen = (inbuflen > outbuflen) ? outbuflen : inbuflen;
+
+ err = _gcry_cipher_encrypt (drbg->ctr_handle, outbuf, cryptlen, inbuf,
+ cryptlen);
+ if (err)
+ return err;
+
+ outbuflen -= cryptlen;
+ outbuf += cryptlen;
+ }
+ return _gcry_cipher_getctr(drbg->ctr_handle, drbg->V, drbg_blocklen (drbg));
+}
diff --git a/comm/third_party/libgcrypt/random/random-system.c b/comm/third_party/libgcrypt/random/random-system.c
new file mode 100644
index 0000000000..8b79511c64
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/random-system.c
@@ -0,0 +1,250 @@
+/* random-system.c - wrapper around the system's RNG
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This RNG is merely wrapper around the system's native RNG. For
+ example on Unix systems it directly uses /dev/{u,}random.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+
+#include "g10lib.h"
+#include "random.h"
+#include "rand-internal.h"
+
+/* This is the lock we use to serialize access to this RNG. The extra
+ integer variable is only used to check the locking state; that is,
+ it is not meant to be thread-safe but merely as a failsafe feature
+ to assert proper locking. */
+GPGRT_LOCK_DEFINE (system_rng_lock);
+static int system_rng_is_locked;
+
+
+/* --- Local prototypes --- */
+
+
+
+
+/* --- Functions --- */
+
+/* Basic initialization is required to initialize mutexes and
+ do a few checks on the implementation. */
+static void
+basic_initialization (void)
+{
+ static int initialized;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+ system_rng_is_locked = 0;
+
+ /* Make sure that we are still using the values we traditionally
+ used for the random levels. */
+ gcry_assert (GCRY_WEAK_RANDOM == 0
+ && GCRY_STRONG_RANDOM == 1
+ && GCRY_VERY_STRONG_RANDOM == 2);
+
+}
+
+
+/* Acquire the system_rng_lock. */
+static void
+lock_rng (void)
+{
+ gpg_err_code_t rc;
+
+ rc = gpgrt_lock_lock (&system_rng_lock);
+ if (rc)
+ log_fatal ("failed to acquire the System RNG lock: %s\n",
+ gpg_strerror (rc));
+ system_rng_is_locked = 1;
+}
+
+
+/* Release the system_rng_lock. */
+static void
+unlock_rng (void)
+{
+ gpg_err_code_t rc;
+
+ system_rng_is_locked = 0;
+ rc = gpgrt_lock_unlock (&system_rng_lock);
+ if (rc)
+ log_fatal ("failed to release the System RNG lock: %s\n",
+ gpg_strerror (rc));
+}
+
+
+/* Helper variables for read_cb().
+
+ The _gcry_rnd*_gather_random interface does not allow to provide a
+ data pointer. Thus we need to use a global variable for
+ communication. However, the then required locking is anyway a good
+ idea because it does not make sense to have several readers of (say
+ /dev/random). It is easier to serve them one after the other. */
+static unsigned char *read_cb_buffer; /* The buffer. */
+static size_t read_cb_size; /* Size of the buffer. */
+static size_t read_cb_len; /* Used length. */
+
+
+/* Callback for _gcry_rnd*_gather_random. */
+static void
+read_cb (const void *buffer, size_t length, enum random_origins origin)
+{
+ const unsigned char *p = buffer;
+
+ (void)origin;
+
+ gcry_assert (system_rng_is_locked);
+ gcry_assert (read_cb_buffer);
+
+ /* Note that we need to protect against gatherers returning more
+ than the requested bytes (e.g. rndw32). */
+ while (length-- && read_cb_len < read_cb_size)
+ {
+ read_cb_buffer[read_cb_len++] = *p++;
+ }
+}
+
+
+/* Fill BUFFER with LENGTH bytes of random at quality LEVEL. The
+ function either succeeds or terminates the process in case of a
+ fatal error. */
+static void
+get_random (void *buffer, size_t length, int level)
+{
+ int rc;
+
+ gcry_assert (buffer);
+
+ read_cb_buffer = buffer;
+ read_cb_size = length;
+ read_cb_len = 0;
+
+#if USE_RNDLINUX
+ rc = _gcry_rndlinux_gather_random (read_cb, 0, length, level);
+#elif USE_RNDUNIX
+ rc = _gcry_rndunix_gather_random (read_cb, 0, length, level);
+#elif USE_RNDW32
+ do
+ {
+ rc = _gcry_rndw32_gather_random (read_cb, 0, length, level);
+ }
+ while (rc >= 0 && read_cb_len < read_cb_size);
+#else
+ rc = -1;
+#endif
+
+ if (rc < 0 || read_cb_len != read_cb_size)
+ {
+ log_fatal ("error reading random from system RNG (rc=%d)\n", rc);
+ }
+}
+
+
+
+/* --- Public Functions --- */
+
+/* Initialize this random subsystem. If FULL is false, this function
+ merely calls the basic initialization of the module and does not do
+ anything more. Doing this is not really required but when running
+ in a threaded environment we might get a race condition
+ otherwise. */
+void
+_gcry_rngsystem_initialize (int full)
+{
+ basic_initialization ();
+ if (!full)
+ return;
+ /* Nothing more to initialize. */
+ return;
+}
+
+
+/* Try to close the FDs of the random gather module. This is
+ currently only implemented for rndlinux. */
+void
+_gcry_rngsystem_close_fds (void)
+{
+ lock_rng ();
+#if USE_RNDLINUX
+ _gcry_rndlinux_gather_random (NULL, 0, 0, 0);
+#endif
+ unlock_rng ();
+}
+
+
+/* Print some statistics about the RNG. */
+void
+_gcry_rngsystem_dump_stats (void)
+{
+ /* Not yet implemented. */
+}
+
+
+/* This function returns true if no real RNG is available or the
+ quality of the RNG has been degraded for test purposes. */
+int
+_gcry_rngsystem_is_faked (void)
+{
+ return 0; /* Faked random is not supported. */
+}
+
+
+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY
+ should be in the range of 0..100 to indicate the goodness of the
+ entropy added, or -1 for goodness not known. */
+gcry_error_t
+_gcry_rngsystem_add_bytes (const void *buf, size_t buflen, int quality)
+{
+ (void)buf;
+ (void)buflen;
+ (void)quality;
+ return 0; /* Not implemented. */
+}
+
+
+/* Public function to fill the buffer with LENGTH bytes of
+ cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is
+ here mapped to GCRY_STRONG_RANDOM, GCRY_STRONG_RANDOM is strong
+ enough for most usage, GCRY_VERY_STRONG_RANDOM is good for key
+ generation stuff but may be very slow. */
+void
+_gcry_rngsystem_randomize (void *buffer, size_t length,
+ enum gcry_random_level level)
+{
+ _gcry_rngsystem_initialize (1); /* Auto-initialize if needed. */
+
+ if (level != GCRY_VERY_STRONG_RANDOM)
+ level = GCRY_STRONG_RANDOM;
+
+ lock_rng ();
+ get_random (buffer, length, level);
+ unlock_rng ();
+}
diff --git a/comm/third_party/libgcrypt/random/random.c b/comm/third_party/libgcrypt/random/random.c
new file mode 100644
index 0000000000..9aab78930b
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/random.c
@@ -0,0 +1,584 @@
+/* random.c - Random number switch
+ * Copyright (C) 2003, 2006, 2008, 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This module switches between different implementations of random
+ number generators and provides a few help functions.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+#include <ctype.h>
+
+#include "g10lib.h"
+#include "random.h"
+#include "rand-internal.h"
+#include "cipher.h" /* For _gcry_sha1_hash_buffer(). */
+
+/* The name of a file used to globally configure the RNG. */
+#define RANDOM_CONF_FILE "/etc/gcrypt/random.conf"
+
+
+/* If not NULL a progress function called from certain places and the
+ opaque value passed along. Registered by
+ _gcry_register_random_progress (). */
+static void (*progress_cb) (void *,const char*,int,int, int );
+static void *progress_cb_data;
+
+/* Flags indicating the requested RNG types. */
+static struct
+{
+ int standard;
+ int fips;
+ int system;
+} rng_types;
+
+
+/* This is the lock we use to protect the buffer used by the nonce
+ generation. */
+GPGRT_LOCK_DEFINE (nonce_buffer_lock);
+
+
+
+/* --- Functions --- */
+
+
+/* Used to register a progress callback. This needs to be called
+ before any threads are created. */
+void
+_gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
+ void *cb_data )
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+
+/* This progress function is currently used by the random modules to
+ give hints on how much more entropy is required. */
+void
+_gcry_random_progress (const char *what, int printchar, int current, int total)
+{
+ if (progress_cb)
+ progress_cb (progress_cb_data, what, printchar, current, total);
+}
+
+
+/* Read a file with configure options. The file is a simple text file
+ * where empty lines and lines with the first non white-space
+ * character being '#' are ignored. Supported configure options are:
+ *
+ * disable-jent - Disable the jitter based extra entropy generator.
+ * This sets the RANDOM_CONF_DISABLE_JENT bit.
+ * only-urandom - Always use /dev/urandom instead of /dev/random.
+ * This sets the RANDOM_CONF_ONLY_URANDOM bit.
+ *
+ * The function returns a bit vector with flags read from the file.
+ */
+unsigned int
+_gcry_random_read_conf (void)
+{
+ const char *fname = RANDOM_CONF_FILE;
+ FILE *fp;
+ char buffer[256];
+ char *p, *pend;
+ int lnr = 0;
+ unsigned int result = 0;
+
+ fp = fopen (fname, "r");
+ if (!fp)
+ return result;
+
+ for (;;)
+ {
+ if (!fgets (buffer, sizeof buffer, fp))
+ {
+ if (!feof (fp))
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt warning: error reading '%s', line %d",
+ fname, lnr);
+#endif /*HAVE_SYSLOG*/
+ }
+ fclose (fp);
+ return result;
+ }
+ lnr++;
+ for (p=buffer; my_isascii (*p) && isspace (*p); p++)
+ ;
+ pend = strchr (p, '\n');
+ if (pend)
+ *pend = 0;
+ pend = p + (*p? (strlen (p)-1):0);
+ for ( ;pend > p; pend--)
+ if (my_isascii (*pend) && isspace (*pend))
+ *pend = 0;
+ if (!*p || *p == '#')
+ continue;
+
+ if (!strcmp (p, "disable-jent"))
+ result |= RANDOM_CONF_DISABLE_JENT;
+ else if (!strcmp (p, "only-urandom"))
+ result |= RANDOM_CONF_ONLY_URANDOM;
+ else
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt warning: unknown option in '%s', line %d",
+ fname, lnr);
+#endif /*HAVE_SYSLOG*/
+ }
+ }
+}
+
+
+/* Set the preferred RNG type. This may be called at any time even
+ before gcry_check_version. Thus we can't assume any thread system
+ initialization. A type of 0 is used to indicate that any Libgcrypt
+ initialization has been done.*/
+void
+_gcry_set_preferred_rng_type (int type)
+{
+ static int any_init;
+
+ if (!type)
+ {
+ any_init = 1;
+ }
+ else if (type == GCRY_RNG_TYPE_STANDARD)
+ {
+ rng_types.standard = 1;
+ }
+ else if (any_init)
+ {
+ /* After any initialization has been done we only allow to
+ upgrade to the standard RNG (handled above). All other
+ requests are ignored. The idea is that the application needs
+ to declare a preference for a weaker RNG as soon as possible
+ and before any library sets a preference. We assume that a
+ library which uses Libgcrypt calls an init function very
+ early. This way --- even if the library gets initialized
+ early by the application --- it is unlikely that it can
+ select a lower priority RNG.
+
+ This scheme helps to ensure that existing unmodified
+ applications (e.g. gpg2), which don't known about the new RNG
+ selection system, will continue to use the standard RNG and
+ not be tricked by some library to use a lower priority RNG.
+ There are some loopholes here but at least most GnuPG stuff
+ should be save because it calls src_c{gcry_control
+ (GCRYCTL_SUSPEND_SECMEM_WARN);} quite early and thus inhibits
+ switching to a low priority RNG.
+ */
+ }
+ else if (type == GCRY_RNG_TYPE_FIPS)
+ {
+ rng_types.fips = 1;
+ }
+ else if (type == GCRY_RNG_TYPE_SYSTEM)
+ {
+ rng_types.system = 1;
+ }
+}
+
+
+/* Initialize this random subsystem. If FULL is false, this function
+ merely calls the basic initialization of the module and does not do
+ anything more. Doing this is not really required but when running
+ in a threaded environment we might get a race condition
+ otherwise. */
+void
+_gcry_random_initialize (int full)
+{
+ if (fips_mode ())
+ _gcry_rngdrbg_inititialize (full);
+ else if (rng_types.standard)
+ _gcry_rngcsprng_initialize (full);
+ else if (rng_types.fips)
+ _gcry_rngdrbg_inititialize (full);
+ else if (rng_types.system)
+ _gcry_rngsystem_initialize (full);
+ else
+ _gcry_rngcsprng_initialize (full);
+}
+
+
+/* If possible close file descriptors used by the RNG. */
+void
+_gcry_random_close_fds (void)
+{
+ /* Note that we can't do that directly because each random system
+ has its own lock functions which need to be used for accessing
+ the entropy gatherer. */
+
+ if (fips_mode ())
+ _gcry_rngdrbg_close_fds ();
+ else if (rng_types.standard)
+ _gcry_rngcsprng_close_fds ();
+ else if (rng_types.fips)
+ _gcry_rngdrbg_close_fds ();
+ else if (rng_types.system)
+ _gcry_rngsystem_close_fds ();
+ else
+ _gcry_rngcsprng_close_fds ();
+}
+
+
+/* Return the current RNG type. IGNORE_FIPS_MODE is a flag used to
+ skip the test for FIPS. This is useful, so that we are able to
+ return the type of the RNG even before we have setup FIPS mode
+ (note that FIPS mode is enabled by default until it is switched off
+ by the initialization). This is mostly useful for the regression
+ test. */
+int
+_gcry_get_rng_type (int ignore_fips_mode)
+{
+ if (!ignore_fips_mode && fips_mode ())
+ return GCRY_RNG_TYPE_FIPS;
+ else if (rng_types.standard)
+ return GCRY_RNG_TYPE_STANDARD;
+ else if (rng_types.fips)
+ return GCRY_RNG_TYPE_FIPS;
+ else if (rng_types.system)
+ return GCRY_RNG_TYPE_SYSTEM;
+ else
+ return GCRY_RNG_TYPE_STANDARD;
+}
+
+
+void
+_gcry_random_dump_stats (void)
+{
+ if (fips_mode ())
+ _gcry_rngdrbg_dump_stats ();
+ else
+ _gcry_rngcsprng_dump_stats ();
+ _gcry_rndjent_dump_stats ();
+}
+
+
+/* This function should be called during initialization and before
+ initialization of this module to place the random pools into secure
+ memory. */
+void
+_gcry_secure_random_alloc (void)
+{
+ if (fips_mode ())
+ ; /* Not used; the FIPS RNG is always in secure mode. */
+ else
+ _gcry_rngcsprng_secure_alloc ();
+}
+
+
+/* This may be called before full initialization to degrade the
+ quality of the RNG for the sake of a faster running test suite. */
+void
+_gcry_enable_quick_random_gen (void)
+{
+ if (fips_mode ())
+ ; /* Not used. */
+ else
+ _gcry_rngcsprng_enable_quick_gen ();
+}
+
+
+void
+_gcry_set_random_daemon_socket (const char *socketname)
+{
+ if (fips_mode ())
+ ; /* Not used. */
+ else
+ _gcry_rngcsprng_set_daemon_socket (socketname);
+}
+
+/* With ONOFF set to 1, enable the use of the daemon. With ONOFF set
+ to 0, disable the use of the daemon. With ONOF set to -1, return
+ whether the daemon has been enabled. */
+int
+_gcry_use_random_daemon (int onoff)
+{
+ if (fips_mode ())
+ return 0; /* Never enabled in fips mode. */
+ else
+ return _gcry_rngcsprng_use_daemon (onoff);
+}
+
+
+/* This function returns true if no real RNG is available or the
+ quality of the RNG has been degraded for test purposes. */
+int
+_gcry_random_is_faked (void)
+{
+ if (fips_mode ())
+ return _gcry_rngdrbg_is_faked ();
+ else
+ return _gcry_rngcsprng_is_faked ();
+}
+
+
+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY
+ should be in the range of 0..100 to indicate the goodness of the
+ entropy added, or -1 for goodness not known. */
+gcry_err_code_t
+_gcry_random_add_bytes (const void *buf, size_t buflen, int quality)
+{
+ if (fips_mode ())
+ return 0; /* No need for this in fips mode. */
+ else if (rng_types.standard)
+ return gpg_err_code (_gcry_rngcsprng_add_bytes (buf, buflen, quality));
+ else if (rng_types.fips)
+ return 0;
+ else if (rng_types.system)
+ return 0;
+ else /* default */
+ return gpg_err_code (_gcry_rngcsprng_add_bytes (buf, buflen, quality));
+}
+
+
+/* Helper function. */
+static void
+do_randomize (void *buffer, size_t length, enum gcry_random_level level)
+{
+ if (fips_mode ())
+ _gcry_rngdrbg_randomize (buffer, length, level);
+ else if (rng_types.standard)
+ _gcry_rngcsprng_randomize (buffer, length, level);
+ else if (rng_types.fips)
+ _gcry_rngdrbg_randomize (buffer, length, level);
+ else if (rng_types.system)
+ _gcry_rngsystem_randomize (buffer, length, level);
+ else /* default */
+ _gcry_rngcsprng_randomize (buffer, length, level);
+}
+
+/* The public function to return random data of the quality LEVEL.
+ Returns a pointer to a newly allocated and randomized buffer of
+ LEVEL and NBYTES length. Caller must free the buffer. */
+void *
+_gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+{
+ void *buffer;
+
+ buffer = xmalloc (nbytes);
+ do_randomize (buffer, nbytes, level);
+ return buffer;
+}
+
+
+/* The public function to return random data of the quality LEVEL;
+ this version of the function returns the random in a buffer allocated
+ in secure memory. Caller must free the buffer. */
+void *
+_gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+{
+ void *buffer;
+
+ /* Historical note (1.3.0--1.4.1): The buffer was only allocated
+ in secure memory if the pool in random-csprng.c was also set to
+ use secure memory. */
+ buffer = xmalloc_secure (nbytes);
+ do_randomize (buffer, nbytes, level);
+ return buffer;
+}
+
+
+/* Public function to fill the buffer with LENGTH bytes of
+ cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is
+ not very strong, GCRY_STRONG_RANDOM is strong enough for most
+ usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but
+ may be very slow. */
+void
+_gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
+{
+ do_randomize (buffer, length, level);
+}
+
+
+/* This function may be used to specify the file to be used as a seed
+ file for the PRNG. This function should be called prior to the
+ initialization of the random module. NAME may not be NULL. */
+void
+_gcry_set_random_seed_file (const char *name)
+{
+ if (fips_mode ())
+ ; /* No need for this in fips mode. */
+ else if (rng_types.standard)
+ _gcry_rngcsprng_set_seed_file (name);
+ else if (rng_types.fips)
+ ;
+ else if (rng_types.system)
+ ;
+ else /* default */
+ _gcry_rngcsprng_set_seed_file (name);
+}
+
+
+/* If a seed file has been setup, this function may be used to write
+ back the random numbers entropy pool. */
+void
+_gcry_update_random_seed_file (void)
+{
+ if (fips_mode ())
+ ; /* No need for this in fips mode. */
+ else if (rng_types.standard)
+ _gcry_rngcsprng_update_seed_file ();
+ else if (rng_types.fips)
+ ;
+ else if (rng_types.system)
+ ;
+ else /* default */
+ _gcry_rngcsprng_update_seed_file ();
+}
+
+
+
+/* The fast random pool function as called at some places in
+ libgcrypt. This is merely a wrapper to make sure that this module
+ is initialized and to lock the pool. Note, that this function is a
+ NOP unless a random function has been used or _gcry_initialize (1)
+ has been used. We use this hack so that the internal use of this
+ function in cipher_open and md_open won't start filling up the
+ random pool, even if no random will be required by the process. */
+void
+_gcry_fast_random_poll (void)
+{
+ if (fips_mode ())
+ ; /* No need for this in fips mode. */
+ else if (rng_types.standard)
+ _gcry_rngcsprng_fast_poll ();
+ else if (rng_types.fips)
+ ;
+ else if (rng_types.system)
+ ;
+ else /* default */
+ _gcry_rngcsprng_fast_poll ();
+}
+
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void
+_gcry_create_nonce (void *buffer, size_t length)
+{
+ static unsigned char nonce_buffer[20+8];
+ static int nonce_buffer_initialized = 0;
+ static volatile pid_t my_pid; /* The volatile is there to make sure the
+ compiler does not optimize the code away
+ in case the getpid function is badly
+ attributed. */
+ volatile pid_t apid;
+ unsigned char *p;
+ size_t n;
+ int err;
+
+ /* First check whether we shall use the FIPS nonce generator. This
+ is only done in FIPS mode, in all other modes, we use our own
+ nonce generator which is seeded by the RNG actual in use. */
+ if (fips_mode ())
+ {
+ _gcry_rngdrbg_randomize (buffer, length, GCRY_WEAK_RANDOM);
+ return;
+ }
+
+ /* This is the nonce generator, which formerly lived in
+ random-csprng.c. It is now used by all RNG types except when in
+ FIPS mode (not that this means it is also used if the FIPS RNG
+ has been selected but we are not in fips mode). */
+
+ /* Make sure we are initialized. */
+ _gcry_random_initialize (1);
+
+ /* Acquire the nonce buffer lock. */
+ err = gpgrt_lock_lock (&nonce_buffer_lock);
+ if (err)
+ log_fatal ("failed to acquire the nonce buffer lock: %s\n",
+ gpg_strerror (err));
+
+ apid = getpid ();
+ /* The first time initialize our buffer. */
+ if (!nonce_buffer_initialized)
+ {
+ time_t atime = time (NULL);
+ pid_t xpid = apid;
+
+ my_pid = apid;
+
+ if ((sizeof apid + sizeof atime) > sizeof nonce_buffer)
+ BUG ();
+
+ /* Initialize the first 20 bytes with a reasonable value so that
+ a failure of gcry_randomize won't affect us too much. Don't
+ care about the uninitialized remaining bytes. */
+ p = nonce_buffer;
+ memcpy (p, &xpid, sizeof xpid);
+ p += sizeof xpid;
+ memcpy (p, &atime, sizeof atime);
+
+ /* Initialize the never changing private part of 64 bits. */
+ _gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
+
+ nonce_buffer_initialized = 1;
+ }
+ else if ( my_pid != apid )
+ {
+ /* We forked. Need to reseed the buffer - doing this for the
+ private part should be sufficient. */
+ do_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
+ /* Update the pid so that we won't run into here again and
+ again. */
+ my_pid = apid;
+ }
+
+ /* Create the nonce by hashing the entire buffer, returning the hash
+ and updating the first 20 bytes of the buffer with this hash. */
+ for (p = buffer; length > 0; length -= n, p += n)
+ {
+ _gcry_sha1_hash_buffer (nonce_buffer,
+ nonce_buffer, sizeof nonce_buffer);
+ n = length > 20? 20 : length;
+ memcpy (p, nonce_buffer, n);
+ }
+
+ /* Release the nonce buffer lock. */
+ err = gpgrt_lock_unlock (&nonce_buffer_lock);
+ if (err)
+ log_fatal ("failed to release the nonce buffer lock: %s\n",
+ gpg_strerror (err));
+}
+
+
+/* Run the self-tests for the RNG. This is currently only implemented
+ for the FIPS generator. */
+gpg_error_t
+_gcry_random_selftest (selftest_report_func_t report)
+{
+ if (fips_mode ())
+ return _gcry_rngdrbg_selftest (report);
+ else
+ return 0; /* No selftests yet. */
+}
diff --git a/comm/third_party/libgcrypt/random/random.h b/comm/third_party/libgcrypt/random/random.h
new file mode 100644
index 0000000000..c00b9ed537
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/random.h
@@ -0,0 +1,79 @@
+/* random.h - random functions
+ * Copyright (C) 1998, 2002, 2006 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
+ */
+#ifndef G10_RANDOM_H
+#define G10_RANDOM_H
+
+#include "types.h"
+#include "../src/gcrypt-testapi.h" /* struct gcry_drbg_test_vector */
+
+/*-- random.c --*/
+void _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
+ void *cb_data );
+
+void _gcry_set_preferred_rng_type (int type);
+void _gcry_random_initialize (int full);
+void _gcry_random_close_fds (void);
+int _gcry_get_rng_type (int ignore_fips_mode);
+void _gcry_random_dump_stats(void);
+void _gcry_secure_random_alloc(void);
+void _gcry_enable_quick_random_gen (void);
+int _gcry_random_is_faked(void);
+void _gcry_set_random_daemon_socket (const char *socketname);
+int _gcry_use_random_daemon (int onoff);
+void _gcry_set_random_seed_file (const char *name);
+void _gcry_update_random_seed_file (void);
+
+void _gcry_fast_random_poll( void );
+
+gcry_err_code_t _gcry_random_init_external_test (void **r_context,
+ unsigned int flags,
+ const void *key,
+ size_t keylen,
+ const void *seed,
+ size_t seedlen,
+ const void *dt,
+ size_t dtlen);
+gcry_err_code_t _gcry_random_run_external_test (void *context,
+ char *buffer, size_t buflen);
+void _gcry_random_deinit_external_test (void *context);
+
+/*-- random-drbg.c --*/
+gpg_err_code_t _gcry_rngdrbg_reinit (const char *flagstr,
+ gcry_buffer_t *pers, int npers);
+gpg_err_code_t _gcry_rngdrbg_cavs_test (struct gcry_drbg_test_vector *t,
+ unsigned char *buf);
+gpg_err_code_t _gcry_rngdrbg_healthcheck_one (struct gcry_drbg_test_vector *t);
+
+/*-- rndegd.c --*/
+gpg_error_t _gcry_rndegd_set_socket_name (const char *name);
+
+/*-- rndjent.c --*/
+unsigned int _gcry_rndjent_get_version (int *r_active);
+
+
+/*-- random-daemon.c (only used from random.c) --*/
+#ifdef USE_RANDOM_DAEMON
+void _gcry_daemon_initialize_basics (void);
+int _gcry_daemon_randomize (const char *socketname,
+ void *buffer, size_t length,
+ enum gcry_random_level level);
+#endif /*USE_RANDOM_DAEMON*/
+
+#endif /*G10_RANDOM_H*/
diff --git a/comm/third_party/libgcrypt/random/rndegd.c b/comm/third_party/libgcrypt/random/rndegd.c
new file mode 100644
index 0000000000..b87115f234
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/rndegd.c
@@ -0,0 +1,290 @@
+/* rndegd.c - interface to the EGD
+ * Copyright (C) 1999, 2000, 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
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "rand-internal.h"
+
+#ifndef offsetof
+#define offsetof(type, member) ((size_t) &((type *)0)->member)
+#endif
+
+static int egd_socket = -1;
+
+/* Allocated name of the socket if supplied at runtime. */
+static char *user_socket_name;
+
+
+/* Allocate a new filename from FIRST_PART and SECOND_PART and to
+ tilde expansion for first_part. SECOND_PART might be NULL.
+ */
+static char *
+my_make_filename (const char *first_part, const char *second_part)
+{
+ size_t n;
+ char *name, *home, *p;
+
+ n = strlen(first_part)+1;
+ if (second_part)
+ n += strlen (second_part) + 1;
+
+ home = NULL;
+ if( *first_part == '~' && first_part[1] == '/'
+ && (home = getenv("HOME")) && *home )
+ n += strlen(home);
+
+ name = _gcry_xmalloc(n);
+ p = (home
+ ? stpcpy (stpcpy (name, home), first_part+1 )
+ : stpcpy (name, first_part) );
+
+ if (second_part)
+ strcpy (stpcpy(p,"/"), second_part);
+
+ return name;
+}
+
+
+static int
+do_write( int fd, void *buf, size_t nbytes )
+{
+ size_t nleft = nbytes;
+ int nwritten;
+
+ while( nleft > 0 )
+ {
+ nwritten = write( fd, buf, nleft);
+ if( nwritten < 0 )
+ {
+ if( errno == EINTR )
+ continue;
+ return -1;
+ }
+ nleft -= nwritten;
+ buf = (char*)buf + nwritten;
+ }
+ return 0;
+}
+
+static int
+do_read( int fd, void *buf, size_t nbytes )
+{
+ int n, nread = 0;
+
+ do
+ {
+ do
+ {
+ n = read(fd, (char*)buf + nread, nbytes );
+ }
+ while( n == -1 && errno == EINTR );
+ if( n == -1)
+ return nread? nread:-1;
+ if( n == 0)
+ return -1;
+ nread += n;
+ nbytes -= n;
+ }
+ while( nread < nbytes );
+ return nread;
+}
+
+
+/* Note that his function is not thread-safe. */
+gpg_error_t
+_gcry_rndegd_set_socket_name (const char *name)
+{
+ char *newname;
+ struct sockaddr_un addr;
+
+ newname = my_make_filename (name, NULL);
+ if (strlen (newname)+1 >= sizeof addr.sun_path)
+ {
+ xfree (newname);
+ return gpg_error_from_syserror ();
+ }
+ xfree (user_socket_name);
+ user_socket_name = newname;
+ return 0;
+}
+
+
+/* Connect to the EGD and return the file descriptor. Return -1 on
+ error. With NOFAIL set to true, silently fail and return the
+ error, otherwise print an error message and die. */
+int
+_gcry_rndegd_connect_socket (int nofail)
+{
+ int fd;
+ const char *bname = NULL;
+ char *name;
+ struct sockaddr_un addr;
+ int addr_len;
+
+ if (egd_socket != -1)
+ {
+ close (egd_socket);
+ egd_socket = -1;
+ }
+
+#ifdef EGD_SOCKET_NAME
+ bname = EGD_SOCKET_NAME;
+#endif
+ if (user_socket_name)
+ {
+ name = _gcry_strdup (user_socket_name);
+ if (!name)
+ {
+ if (!nofail)
+ log_fatal ("error allocating memory in rndegd: %s\n",
+ strerror(errno) );
+ return -1;
+ }
+ }
+ else if ( !bname || !*bname )
+ name = my_make_filename ("~/.gnupg", "entropy");
+ else
+ name = my_make_filename (bname, NULL);
+
+ if (strlen(name)+1 >= sizeof addr.sun_path)
+ log_fatal ("EGD socketname is too long\n");
+
+ memset( &addr, 0, sizeof addr );
+ addr.sun_family = AF_UNIX;
+ strcpy( addr.sun_path, name );
+ addr_len = (offsetof( struct sockaddr_un, sun_path )
+ + strlen( addr.sun_path ));
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1 && !nofail)
+ log_fatal("can't create unix domain socket: %s\n", strerror(errno) );
+ else if (connect (fd, (struct sockaddr*)&addr, addr_len) == -1)
+ {
+ if (!nofail)
+ log_fatal("can't connect to EGD socket `%s': %s\n",
+ name, strerror(errno) );
+ close (fd);
+ fd = -1;
+ }
+ xfree (name);
+ if (fd != -1)
+ egd_socket = fd;
+ return fd;
+}
+
+/****************
+ * Note: We always use the highest level.
+ * To boost the performance we may want to add some
+ * additional code for level 1
+ *
+ * Using a level of 0 should never block and better add nothing
+ * to the pool. So this is just a dummy for EGD.
+ */
+int
+_gcry_rndegd_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ int fd = egd_socket;
+ int n;
+ byte buffer[256+2];
+ int nbytes;
+ int do_restart = 0;
+
+ if( !length )
+ return 0;
+ if( !level )
+ return 0;
+
+ restart:
+ if (fd == -1 || do_restart)
+ fd = _gcry_rndegd_connect_socket (0);
+
+ do_restart = 0;
+
+ nbytes = length < 255? length : 255;
+ /* First time we do it with a non blocking request */
+ buffer[0] = 1; /* non blocking */
+ buffer[1] = nbytes;
+ if( do_write( fd, buffer, 2 ) == -1 )
+ log_fatal("can't write to the EGD: %s\n", strerror(errno) );
+ n = do_read( fd, buffer, 1 );
+ if( n == -1 )
+ {
+ log_error("read error on EGD: %s\n", strerror(errno));
+ do_restart = 1;
+ goto restart;
+ }
+ n = buffer[0];
+ if( n )
+ {
+ n = do_read( fd, buffer, n );
+ if( n == -1 )
+ {
+ log_error("read error on EGD: %s\n", strerror(errno));
+ do_restart = 1;
+ goto restart;
+ }
+ (*add)( buffer, n, origin );
+ length -= n;
+ }
+
+ if( length )
+ {
+ log_info (
+ _("Please wait, entropy is being gathered. Do some work if it would\n"
+ "keep you from getting bored, because it will improve the quality\n"
+ "of the entropy.\n") );
+ }
+ while( length )
+ {
+ nbytes = length < 255? length : 255;
+
+ buffer[0] = 2; /* blocking */
+ buffer[1] = nbytes;
+ if( do_write( fd, buffer, 2 ) == -1 )
+ log_fatal("can't write to the EGD: %s\n", strerror(errno) );
+ n = do_read( fd, buffer, nbytes );
+ if( n == -1 )
+ {
+ log_error("read error on EGD: %s\n", strerror(errno));
+ do_restart = 1;
+ goto restart;
+ }
+ (*add)( buffer, n, origin );
+ length -= n;
+ }
+ memset(buffer, 0, sizeof(buffer) );
+
+ return 0; /* success */
+}
diff --git a/comm/third_party/libgcrypt/random/rndhw.c b/comm/third_party/libgcrypt/random/rndhw.c
new file mode 100644
index 0000000000..3cf9acc3a2
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/rndhw.c
@@ -0,0 +1,230 @@
+/* rndhw.c - Access to the external random daemon
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2012 Dmitry Kasatkin
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "rand-internal.h"
+
+#undef USE_PADLOCK
+#ifdef ENABLE_PADLOCK_SUPPORT
+# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)
+# define USE_PADLOCK 1
+# endif
+# endif
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+
+#undef USE_DRNG
+#ifdef ENABLE_DRNG_SUPPORT
+# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)
+# define USE_DRNG 1
+# endif
+# endif
+#endif /*ENABLE_RDRAND_SUPPORT*/
+
+typedef void (*add_fn_t)(const void*, size_t, enum random_origins);
+
+/* Keep track on whether the RNG has problems. */
+static volatile int rng_failed;
+
+
+#ifdef USE_PADLOCK
+static size_t
+poll_padlock (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins origin, int fast)
+{
+ volatile char buffer[64+8] __attribute__ ((aligned (8)));
+ volatile char *p;
+ unsigned int nbytes, status;
+
+ /* Peter Gutmann's cryptlib tests again whether the RNG is enabled
+ but we don't do so. We would have to do this also for our AES
+ implementation and that is definitely too time consuming. There
+ would be a race condition anyway. Thus we assume that the OS
+ does not change the Padlock initialization while a user process
+ is running. */
+ p = buffer;
+ nbytes = 0;
+ while (nbytes < 64)
+ {
+#if defined(__x86_64__) && SIZEOF_VOID_P == 8
+ asm volatile
+ ("movq %1, %%rdi\n\t" /* Set buffer. */
+ "xorq %%rdx, %%rdx\n\t" /* Request up to 8 bytes. */
+ ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */
+ : "=a" (status)
+ : "g" (p)
+ : "%rdx", "%rdi", "cc", "memory"
+ );
+#else
+ asm volatile
+ ("movl %1, %%edi\n\t" /* Set buffer. */
+ "xorl %%edx, %%edx\n\t" /* Request up to 8 bytes. */
+ ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */
+ : "=a" (status)
+ : "g" (p)
+ : "%edx", "%edi", "cc", "memory"
+ );
+#endif
+ if ((status & (1<<6)) /* RNG still enabled. */
+ && !(status & (1<<13)) /* von Neumann corrector is enabled. */
+ && !(status & (1<<14)) /* String filter is disabled. */
+ && !(status & 0x1c00) /* BIAS voltage at default. */
+ && (!(status & 0x1f) || (status & 0x1f) == 8) /* Sanity check. */
+ )
+ {
+ nbytes += (status & 0x1f);
+ if (fast)
+ break; /* Don't get into the loop with the fast flag set. */
+ p += (status & 0x1f);
+ }
+ else
+ {
+ /* If there was an error we need to break the loop and
+ record that there is something wrong with the padlock
+ RNG. */
+ rng_failed = 1;
+ break;
+ }
+ }
+
+ if (nbytes)
+ {
+ (*add) ((void*)buffer, nbytes, origin);
+ wipememory (buffer, nbytes);
+ }
+ return nbytes;
+}
+#endif /*USE_PADLOCK*/
+
+
+#ifdef USE_DRNG
+# define RDRAND_RETRY_LOOPS 10
+# define RDRAND_INT ".byte 0x0f,0xc7,0xf0"
+# if defined(__x86_64__) && SIZEOF_UNSIGNED_LONG == 8
+# define RDRAND_LONG ".byte 0x48,0x0f,0xc7,0xf0"
+# else
+# define RDRAND_LONG RDRAND_INT
+# endif
+static inline int
+rdrand_long (volatile unsigned long *v)
+{
+ int ok;
+ asm volatile ("1: " RDRAND_LONG "\n\t"
+ "jc 2f\n\t"
+ "decl %0\n\t"
+ "jnz 1b\n\t"
+ "2:"
+ : "=r" (ok), "=a" (*v)
+ : "0" (RDRAND_RETRY_LOOPS)
+ : "cc", "memory");
+ return ok;
+}
+
+
+static inline int
+rdrand_nlong (volatile unsigned long *v, int count)
+{
+ while (count--)
+ if (!rdrand_long(v++))
+ return 0;
+ return 1;
+}
+
+
+static size_t
+poll_drng (add_fn_t add, enum random_origins origin, int fast)
+{
+ volatile unsigned long buffer[8] __attribute__ ((aligned (8)));
+ unsigned int nbytes = sizeof (buffer);
+
+ (void)fast;
+
+ if (!rdrand_nlong (buffer, DIM(buffer)))
+ return 0;
+ (*add)((void *)buffer, nbytes, origin);
+ return nbytes;
+}
+#endif /*USE_DRNG*/
+
+
+int
+_gcry_rndhw_failed_p (void)
+{
+ return rng_failed;
+}
+
+
+/* Try to read random from a hardware RNG if a fast one is
+ available. */
+void
+_gcry_rndhw_poll_fast (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins origin)
+{
+ (void)add;
+ (void)origin;
+
+#ifdef USE_DRNG
+ if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND))
+ poll_drng (add, origin, 1);
+#endif
+#ifdef USE_PADLOCK
+ if ((_gcry_get_hw_features () & HWF_PADLOCK_RNG))
+ poll_padlock (add, origin, 1);
+#endif
+}
+
+
+/* Read 64 bytes from a hardware RNG and return the number of bytes
+ actually read. However hardware source is let account only
+ for up to 50% (or 25% for RDRAND) of the requested bytes. */
+size_t
+_gcry_rndhw_poll_slow (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins origin, size_t req_length)
+{
+ size_t nbytes = 0;
+
+ (void)add;
+ (void)origin;
+
+ req_length /= 2; /* Up to 50%. */
+
+#ifdef USE_DRNG
+ if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND))
+ {
+ req_length /= 2; /* Up to 25%. */
+ nbytes += poll_drng (add, origin, 0);
+ }
+#endif
+#ifdef USE_PADLOCK
+ if ((_gcry_get_hw_features () & HWF_PADLOCK_RNG))
+ nbytes += poll_padlock (add, origin, 0);
+#endif
+
+ if (nbytes > req_length)
+ nbytes = req_length;
+
+ return nbytes;
+}
diff --git a/comm/third_party/libgcrypt/random/rndjent.c b/comm/third_party/libgcrypt/random/rndjent.c
new file mode 100644
index 0000000000..56648a8756
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/rndjent.c
@@ -0,0 +1,389 @@
+/* rndjent.c - Driver for the jitterentropy module.
+ * Copyright (C) 2017 g10 Code GmbH
+ * Copyright (C) 2017 Bundesamt für Sicherheit in der Informationstechnik
+ * Copyright (C) 2013 Stephan Mueller <smueller@chronox.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "types.h"
+#include "g10lib.h"
+#include "../cipher/bithelp.h"
+#include "rand-internal.h"
+
+/*
+ * Decide whether we can support jent at compile time.
+ */
+#undef USE_JENT
+#define JENT_USES_RDTSC 1
+#define JENT_USES_GETTIME 2
+#define JENT_USES_READ_REAL_TIME 3
+#ifdef ENABLE_JENT_SUPPORT
+# if (defined (__i386__) || defined(__x86_64__)) && defined(HAVE_CPU_ARCH_X86)
+# define USE_JENT JENT_USES_RDTSC
+# elif defined (HAVE_CLOCK_GETTIME)
+# if _AIX
+# define USE_JENT JENT_USES_READ_REAL_TIME
+# else
+# define USE_JENT JENT_USES_GETTIME
+# endif
+# endif
+#endif /*ENABLE_JENT_SUPPORT*/
+
+
+#ifdef USE_JENT
+
+#undef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT
+/* Uncomment the next line to build with statistics. */
+/* #define CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT 1 */
+
+
+/* Note that we source include the actual jitter entropy code.
+ * Platform dependent code is indirectly included from our own
+ * jitterentropy-user-base.h file. */
+
+/* Tell jitterentropy* that all functions shall be static. */
+#define JENT_PRIVATE_COMPILE 1
+
+#include "jitterentropy-base.c"
+
+
+/* This is the lock we use to serialize access to this RNG. The extra
+ * integer variable is only used to check the locking state; that is,
+ * it is not meant to be thread-safe but merely as a failsafe feature
+ * to assert proper locking. */
+GPGRT_LOCK_DEFINE (jent_rng_lock);
+static int jent_rng_is_locked;
+
+/* This flag tracks whether the RNG has been initialized - either
+ * with error or with success. Protected by JENT_RNG_LOCK. */
+static int jent_rng_is_initialized;
+
+/* Our collector. The RNG is in a working state if its value is not
+ * NULL. Protected by JENT_RNG_LOCK. */
+struct rand_data *jent_rng_collector;
+
+/* The number of times the core entropy function has been called and
+ * the number of random bytes retrieved. */
+static unsigned long jent_rng_totalcalls;
+static unsigned long jent_rng_totalbytes;
+
+
+
+/* JENT statistic helper code. */
+#ifdef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT
+
+static void
+jent_init_statistic (struct rand_data *rand_data)
+{
+ /* int i; */
+ /* struct entropy_stat *stat = &rand_data->entropy_stat; */
+
+ /* for (i = 0; i < 64; i++) */
+ /* { */
+ /* stat->bitslot[i] = 0; */
+ /* stat->bitvar[i] = 0; */
+ /* } */
+
+ /* jent_get_nstime (&stat->collection_begin); */
+}
+
+static void
+jent_bit_count (struct rand_data *rand_data, u64 prev_data)
+{
+ /* int i; */
+
+ /* if (!rand_data->entropy_stat.enable_bit_test) */
+ /* return; */
+
+ /* for (i = 0; i < 64; i++) */
+ /* { */
+ /* /\* collect the count of set bits per bit position in the */
+ /* * current ->data field *\/ */
+ /* rand_data->entropy_stat.bitslot[i] += (rand_data->data & 1<<i) ? 1:0; */
+
+ /* /\* collect the count of bit changes between the current */
+ /* * and the previous random data value per bit position *\/ */
+ /* if ((rand_data->data & 1<<i) != (prev_data & 1<<i)) */
+ /* rand_data->entropy_stat.bitvar[i] += 1; */
+ /* } */
+}
+
+
+static void
+jent_statistic_copy_stat (struct entropy_stat *src, struct entropy_stat *dst)
+{
+ /* /\* not copying bitslot and bitvar as they are not needed for */
+ /* * statistic printout *\/ */
+ /* dst->collection_begin = src->collection_begin; */
+ /* dst->collection_end = src->collection_end; */
+ /* dst->old_delta = src->old_delta; */
+ /* dst->setbits = src->setbits; */
+ /* dst->varbits = src->varbits; */
+ /* dst->obsbits = src->obsbits; */
+ /* dst->collection_loop_cnt= src->collection_loop_cnt; */
+}
+
+
+/*
+ * Assessment of statistical behavior of the generated output and returning
+ * the information to the caller by filling the target value.
+ *
+ * Details about the bit statistics are given in chapter 4 of the doc.
+ * Chapter 5 documents the timer analysis and the resulting entropy.
+ */
+static void
+jent_calc_statistic (struct rand_data *rand_data,
+ struct entropy_stat *target, unsigned int loop_cnt)
+{
+ /* int i; */
+ /* struct entropy_stat *stat = &rand_data->entropy_stat; */
+
+ /* jent_get_nstime(&stat->collection_end); */
+
+ /* stat->collection_loop_cnt = loop_cnt; */
+
+ /* stat->setbits = 0; */
+ /* stat->varbits = 0; */
+ /* stat->obsbits = 0; */
+
+ /* for (i = 0; i < DATA_SIZE_BITS; i++) */
+ /* { */
+ /* stat->setbits += stat->bitslot[i]; */
+ /* stat->varbits += stat->bitvar[i]; */
+
+ /* /\* This is the sum of set bits in the current observation */
+ /* * of the random data. *\/ */
+ /* stat->obsbits += (rand_data->data & 1<<i) ? 1:0; */
+ /* } */
+
+ /* jent_statistic_copy_stat(stat, target); */
+
+ /* stat->old_delta = (stat->collection_end - stat->collection_begin); */
+}
+
+#endif /*CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT*/
+
+
+/* Acquire the jent_rng_lock. */
+static void
+lock_rng (void)
+{
+ gpg_err_code_t rc;
+
+ rc = gpgrt_lock_lock (&jent_rng_lock);
+ if (rc)
+ log_fatal ("failed to acquire the Jent RNG lock: %s\n",
+ gpg_strerror (rc));
+ jent_rng_is_locked = 1;
+}
+
+
+/* Release the jent_rng_lock. */
+static void
+unlock_rng (void)
+{
+ gpg_err_code_t rc;
+
+ jent_rng_is_locked = 0;
+ rc = gpgrt_lock_unlock (&jent_rng_lock);
+ if (rc)
+ log_fatal ("failed to release the Jent RNG lock: %s\n",
+ gpg_strerror (rc));
+}
+
+
+/* Return true if the JENT RNG code can be run. It may not yet been
+ * initialized, though. */
+static int
+is_rng_available (void)
+{
+#if USE_JENT == JENT_USES_RDTSC
+ return !!(_gcry_get_hw_features () & HWF_INTEL_RDTSC);
+#elif USE_JENT == JENT_USES_GETTIME
+ return 2;
+#elif USE_JENT == JENT_USES_READ_REAL_TIME
+ return 3;
+#else /* Ooops */
+ return 0;
+#endif
+}
+
+#endif /* USE_JENT */
+
+
+/*
+ * The API used by the high level code.
+ */
+
+/* Read up to LENGTH bytes from a jitter RNG and return the number of
+ * bytes actually read. */
+size_t
+_gcry_rndjent_poll (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins origin, size_t length)
+{
+ size_t nbytes = 0;
+
+#ifdef USE_JENT
+ if ( is_rng_available () )
+ {
+ lock_rng ();
+
+ if (!jent_rng_is_initialized)
+ {
+ /* Auto-initialize. */
+ jent_rng_is_initialized = 1;
+ jent_entropy_collector_free (jent_rng_collector);
+ jent_rng_collector = NULL;
+ if ( !(_gcry_random_read_conf () & RANDOM_CONF_DISABLE_JENT))
+ {
+ if (!jent_entropy_init ())
+ jent_rng_collector = jent_entropy_collector_alloc (1, 0);
+ }
+ }
+
+ if (jent_rng_collector && add)
+ {
+ /* We have a working JENT and it has not been disabled. */
+ char buffer[32];
+
+ while (length)
+ {
+ int rc;
+ size_t n = length < sizeof(buffer)? length : sizeof (buffer);
+
+ jent_rng_totalcalls++;
+ rc = jent_read_entropy (jent_rng_collector, buffer, n);
+ if (rc < 0)
+ break;
+ /* We need to hash the output to conform to the BSI
+ * NTG.1 specs. */
+ _gcry_md_hash_buffer (GCRY_MD_SHA256, buffer, buffer, rc);
+ n = rc < 32? rc : 32;
+ (*add) (buffer, n, origin);
+ length -= n;
+ nbytes += n;
+ jent_rng_totalbytes += n;
+ }
+ wipememory (buffer, sizeof buffer);
+ }
+
+ unlock_rng ();
+ }
+
+#else
+
+ (void)add;
+ (void)origin;
+
+#endif
+
+ return nbytes;
+}
+
+
+/* Return the version number of the JENT RNG. If the RNG is not
+ * initialized or usable 0 is returned. If R_ACTIVE is not NULL the
+ * jitter RNG will be initialized and true is stored at R_ACTIVE if
+ * the initialization succeeded. */
+unsigned int
+_gcry_rndjent_get_version (int *r_active)
+{
+ if (r_active)
+ *r_active = 0;
+#ifdef USE_JENT
+ if ( is_rng_available () )
+ {
+ if (r_active)
+ {
+ /* Make sure the RNG is initialized. */
+ _gcry_rndjent_poll (NULL, 0, 0);
+
+ lock_rng ();
+ /* To ease debugging we store 2 for a clock_gettime based
+ * implementation and 1 for a rdtsc based code. */
+ *r_active = jent_rng_collector? is_rng_available () : 0;
+ unlock_rng ();
+ }
+ return jent_version ();
+ }
+ else
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+
+/* Log statistical informantion about the use of this module. */
+void
+_gcry_rndjent_dump_stats (void)
+{
+ /* In theory we would need to lock the stats here. However this
+ * function is usually called during cleanup and then we _might_ run
+ * into problems. */
+
+#ifdef USE_JENT
+ if ( is_rng_available () )
+ {
+ log_info ("rndjent stat: collector=%p calls=%lu bytes=%lu\n",
+ jent_rng_collector, jent_rng_totalcalls, jent_rng_totalbytes);
+
+ }
+#endif /*USE_JENT*/
+}
+
+
+void
+_gcry_rndjent_fini (void)
+{
+#ifdef USE_JENT
+ lock_rng ();
+
+ if (jent_rng_is_initialized)
+ {
+ jent_entropy_collector_free (jent_rng_collector);
+ jent_rng_collector = NULL;
+ }
+
+ unlock_rng ();
+#endif
+}
diff --git a/comm/third_party/libgcrypt/random/rndlinux.c b/comm/third_party/libgcrypt/random/rndlinux.c
new file mode 100644
index 0000000000..a7a78906d2
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/rndlinux.c
@@ -0,0 +1,366 @@
+/* rndlinux.c - raw random number for OSes with /dev/random
+ * Copyright (C) 1998, 2001, 2002, 2003, 2007,
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_GETTIMEOFDAY
+# include <sys/times.h>
+#endif
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#if defined(__APPLE__) && defined(__MACH__)
+#include <Availability.h>
+#ifdef __MAC_10_11
+extern int getentropy (void *buf, size_t buflen) __attribute__ ((weak_import));
+#define HAVE_GETENTROPY
+#endif
+#endif
+#if defined(__linux__) || !defined(HAVE_GETENTROPY)
+#ifdef HAVE_SYSCALL
+# include <sys/syscall.h>
+# ifdef __NR_getrandom
+# define getentropy(buf,buflen) syscall (__NR_getrandom, buf, buflen, 0)
+# endif
+#endif
+#endif
+
+#include "types.h"
+#include "g10lib.h"
+#include "rand-internal.h"
+
+static int open_device (const char *name, int retry);
+
+
+static int
+set_cloexec_flag (int fd)
+{
+ int oldflags;
+
+ oldflags= fcntl (fd, F_GETFD, 0);
+ if (oldflags < 0)
+ return oldflags;
+ oldflags |= FD_CLOEXEC;
+ return fcntl (fd, F_SETFD, oldflags);
+}
+
+
+
+/*
+ * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it
+ * exists)). If RETRY is true, the function does not terminate with
+ * a fatal error but retries until it is able to reopen the device.
+ */
+static int
+open_device (const char *name, int retry)
+{
+ int fd;
+
+ if (retry)
+ _gcry_random_progress ("open_dev_random", 'X', 1, 0);
+ again:
+ fd = open (name, O_RDONLY);
+ if (fd == -1 && retry)
+ {
+ struct timeval tv;
+
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ _gcry_random_progress ("wait_dev_random", 'X', 0, (int)tv.tv_sec);
+ select (0, NULL, NULL, NULL, &tv);
+ goto again;
+ }
+ if (fd == -1)
+ log_fatal ("can't open %s: %s\n", name, strerror(errno) );
+
+ if (set_cloexec_flag (fd))
+ log_error ("error setting FD_CLOEXEC on fd %d: %s\n",
+ fd, strerror (errno));
+
+ /* We used to do the following check, however it turned out that this
+ is not portable since more OSes provide a random device which is
+ sometimes implemented as another device type.
+
+ struct stat sb;
+
+ if( fstat( fd, &sb ) )
+ log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
+ if( (!S_ISCHR(sb.st_mode)) && (!S_ISFIFO(sb.st_mode)) )
+ log_fatal("invalid random device!\n" );
+ */
+ return fd;
+}
+
+
+/* Note that the caller needs to make sure that this function is only
+ * called by one thread at a time. The function returns 0 on success
+ * or true on failure (in which case the caller will signal a fatal
+ * error). This function should be entered only by one thread at a
+ * time. */
+int
+_gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ static int fd_urandom = -1;
+ static int fd_random = -1;
+ static int only_urandom = -1;
+ static unsigned char ever_opened;
+ static volatile pid_t my_pid; /* The volatile is there to make sure
+ * the compiler does not optimize the
+ * code away in case the getpid
+ * function is badly attributed. */
+ volatile pid_t apid;
+ int fd;
+ int n;
+ byte buffer[768];
+ size_t n_hw;
+ size_t want = length;
+ size_t last_so_far = 0;
+ int any_need_entropy = 0;
+ int delay;
+
+ /* On the first call read the conf file to check whether we want to
+ * use only urandom. */
+ if (only_urandom == -1)
+ {
+ my_pid = getpid ();
+ if ((_gcry_random_read_conf () & RANDOM_CONF_ONLY_URANDOM))
+ only_urandom = 1;
+ else
+ only_urandom = 0;
+ }
+
+ if (!add)
+ {
+ /* Special mode to close the descriptors. */
+ if (fd_random != -1)
+ {
+ close (fd_random);
+ fd_random = -1;
+ }
+ if (fd_urandom != -1)
+ {
+ close (fd_urandom);
+ fd_urandom = -1;
+ }
+
+ _gcry_rndjent_fini ();
+ return 0;
+ }
+
+ /* Detect a fork and close the devices so that we don't use the old
+ * file descriptors. Note that open_device will be called in retry
+ * mode if the devices was opened by the parent process. */
+ apid = getpid ();
+ if (my_pid != apid)
+ {
+ if (fd_random != -1)
+ {
+ close (fd_random);
+ fd_random = -1;
+ }
+ if (fd_urandom != -1)
+ {
+ close (fd_urandom);
+ fd_urandom = -1;
+ }
+ my_pid = apid;
+ }
+
+
+ /* First read from a hardware source. Note that _gcry_rndhw_poll_slow lets
+ it account only for up to 50% (or 25% for RDRAND) of the requested
+ bytes. */
+ n_hw = _gcry_rndhw_poll_slow (add, origin, length);
+ if (length > 1)
+ length -= n_hw;
+
+ /* When using a blocking random generator try to get some entropy
+ * from the jitter based RNG. In this case we take up to 50% of the
+ * remaining requested bytes. */
+ if (level >= GCRY_VERY_STRONG_RANDOM)
+ {
+ n_hw = _gcry_rndjent_poll (add, origin, length/2);
+ if (n_hw > length/2)
+ n_hw = length/2;
+ if (length > 1)
+ length -= n_hw;
+ }
+
+
+ /* Open the requested device. The first time a device is to be
+ opened we fail with a fatal error if the device does not exists.
+ In case the device has ever been closed, further open requests
+ will however retry indefinitely. The rationale for this behaviour is
+ that we always require the device to be existent but want a more
+ graceful behaviour if the rarely needed close operation has been
+ used and the device needs to be re-opened later. */
+ if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom)
+ {
+ if (fd_random == -1)
+ {
+ fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1));
+ ever_opened |= 1;
+ }
+ fd = fd_random;
+ }
+ else
+ {
+ if (fd_urandom == -1)
+ {
+ fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2));
+ ever_opened |= 2;
+ }
+ fd = fd_urandom;
+ }
+
+ /* Enter the read loop. */
+ delay = 0; /* Start with 0 seconds so that we do no block on the
+ first iteration and in turn call the progress function
+ before blocking. To give the OS a better chance to
+ return with something we will actually use 100ms. */
+ while (length)
+ {
+ fd_set rfds;
+ struct timeval tv;
+ int rc;
+
+ /* If we have a modern operating system, we first try to use the new
+ * getentropy function. That call guarantees that the kernel's
+ * RNG has been properly seeded before returning any data. This
+ * is different from /dev/urandom which may, due to its
+ * non-blocking semantics, return data even if the kernel has
+ * not been properly seeded. And it differs from /dev/random by never
+ * blocking once the kernel is seeded. */
+#if defined(HAVE_GETENTROPY) || defined(__NR_getrandom)
+#if defined(__APPLE__) && defined(__MACH__)
+ if (&getentropy != NULL)
+#endif
+ {
+ long ret;
+ size_t nbytes;
+
+ do
+ {
+ nbytes = length < sizeof(buffer)? length : sizeof(buffer);
+ if (nbytes > 256)
+ nbytes = 256;
+ _gcry_pre_syscall ();
+ ret = getentropy (buffer, nbytes);
+ _gcry_post_syscall ();
+ }
+ while (ret == -1 && errno == EINTR);
+ if (ret == -1 && errno == ENOSYS)
+ ; /* getentropy is not supported - fallback to pulling from fd. */
+ else
+ { /* getentropy is supported. Some sanity checks. */
+ if (ret == -1)
+ log_fatal ("unexpected error from getentropy: %s\n",
+ strerror (errno));
+#ifdef __NR_getrandom
+ else if (ret != nbytes)
+ log_fatal ("getentropy returned only"
+ " %ld of %zu requested bytes\n", ret, nbytes);
+#endif
+
+ (*add)(buffer, nbytes, origin);
+ length -= nbytes;
+ continue; /* until LENGTH is zero. */
+ }
+ }
+#endif
+
+ /* If we collected some bytes update the progress indicator. We
+ do this always and not just if the select timed out because
+ often just a few bytes are gathered within the timeout
+ period. */
+ if (any_need_entropy || last_so_far != (want - length) )
+ {
+ last_so_far = want - length;
+ _gcry_random_progress ("need_entropy", 'X',
+ (int)last_so_far, (int)want);
+ any_need_entropy = 1;
+ }
+
+ /* If the system has no limit on the number of file descriptors
+ and we encounter an fd which is larger than the fd_set size,
+ we don't use the select at all. The select code is only used
+ to emit progress messages. A better solution would be to
+ fall back to poll() if available. */
+#ifdef FD_SETSIZE
+ if (fd < FD_SETSIZE)
+#endif
+ {
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ tv.tv_sec = delay;
+ tv.tv_usec = delay? 0 : 100000;
+ _gcry_pre_syscall ();
+ rc = select (fd+1, &rfds, NULL, NULL, &tv);
+ _gcry_post_syscall ();
+ if (!rc)
+ {
+ any_need_entropy = 1;
+ delay = 3; /* Use 3 seconds henceforth. */
+ continue;
+ }
+ else if( rc == -1 )
+ {
+ log_error ("select() error: %s\n", strerror(errno));
+ if (!delay)
+ delay = 1; /* Use 1 second if we encounter an error before
+ we have ever blocked. */
+ continue;
+ }
+ }
+
+ do
+ {
+ size_t nbytes;
+
+ nbytes = length < sizeof(buffer)? length : sizeof(buffer);
+ n = read (fd, buffer, nbytes);
+ if (n >= 0 && n > nbytes)
+ {
+ log_error("bogus read from random device (n=%d)\n", n );
+ n = nbytes;
+ }
+ }
+ while (n == -1 && errno == EINTR);
+ if (n == -1)
+ log_fatal("read error on random device: %s\n", strerror(errno));
+ (*add)(buffer, n, origin);
+ length -= n;
+ }
+ wipememory (buffer, sizeof buffer);
+
+ if (any_need_entropy)
+ _gcry_random_progress ("need_entropy", 'X', (int)want, (int)want);
+
+ return 0; /* success */
+}
diff --git a/comm/third_party/libgcrypt/random/rndunix.c b/comm/third_party/libgcrypt/random/rndunix.c
new file mode 100644
index 0000000000..aff2f85df5
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/rndunix.c
@@ -0,0 +1,937 @@
+/****************************************************************************
+ * *
+ * *
+ * Unix Randomness-Gathering Code *
+ * *
+ * Copyright Peter Gutmann, Paul Kendall, and Chris Wedgwood 1996-1999. *
+ * Heavily modified for GnuPG by Werner Koch *
+ * *
+ * *
+ ****************************************************************************/
+
+/* This module is part of the cryptlib continuously seeded pseudorandom
+ number generator. For usage conditions, see lib_rand.c
+
+ [Here is the notice from lib_rand.c:]
+
+ This module and the misc/rnd*.c modules represent the cryptlib
+ continuously seeded pseudorandom number generator (CSPRNG) as described in
+ my 1998 Usenix Security Symposium paper "The generation of random numbers
+ for cryptographic purposes".
+
+ The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
+ 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG
+ modules and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice
+ and this permission notice in its entirety.
+
+ 2. Redistributions in binary form must reproduce the copyright notice in
+ the documentation and/or other materials provided with the distribution.
+
+ 3. A copy of any bugfixes or enhancements made must be provided to the
+ author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
+ baseline version of the code.
+
+ ALTERNATIVELY, the code may be distributed under the terms of the
+ GNU Lesser General Public License, version 2.1 or any later version
+ published by the Free Software Foundation, in which case the
+ provisions of the GNU LGPL are required INSTEAD OF the above
+ restrictions.
+
+ Although not required under the terms of the LGPL, it would still be
+ nice if you could make any changes available to the author to allow
+ a consistent code base to be maintained. */
+/*************************************************************************
+ The above alternative was changed from GPL to LGPL on 2007-08-22 with
+ permission from Peter Gutmann:
+ ==========
+ From: pgut001 <pgut001@cs.auckland.ac.nz>
+ Subject: Re: LGPL for the windows entropy gatherer
+ To: wk@gnupg.org
+ Date: Wed, 22 Aug 2007 03:05:42 +1200
+
+ Hi,
+
+ >As of now libgcrypt is GPL under Windows due to that module and some people
+ >would really like to see it under LGPL too. Can you do such a license change
+ >to LGPL version 2? Note that LGPL give the user the option to relicense it
+ >under GPL, so the change would be pretty easy and backwar compatible.
+
+ Sure. I assumed that since GPG was GPLd, you'd prefer the GPL for the entropy
+ code as well, but Ian asked for LGPL as an option so as of the next release
+ I'll have LGPL in there. You can consider it to be retroactive, so your
+ current version will be LGPLd as well.
+
+ Peter.
+ ==========
+ From: pgut001 <pgut001@cs.auckland.ac.nz>
+ Subject: Re: LGPL for the windows entropy gatherer
+ To: wk@gnupg.org
+ Date: Wed, 22 Aug 2007 20:50:08 +1200
+
+ >Would you mind to extend this also to the Unix entropy gatherer which is
+ >still used on systems without /dev/random and when EGD is not installed? That
+ >would be the last GPLed piece in Libgcrypt.
+
+ Sure, it covers the entire entropy-gathering subsystem.
+
+ Peter.
+ =========
+*/
+
+/* General includes */
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <string.h>
+
+/* OS-specific includes */
+
+#ifdef __osf__
+ /* Somewhere in the morass of system-specific cruft which OSF/1 pulls in
+ * via the following includes are various endianness defines, so we
+ * undefine the cryptlib ones, which aren't really needed for this module
+ * anyway */
+#undef BIG_ENDIAN
+#undef LITTLE_ENDIAN
+#endif /* __osf__ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+#ifndef __QNX__
+#include <sys/errno.h>
+#include <sys/ipc.h>
+#endif /* __QNX__ */
+#include <sys/time.h> /* SCO and SunOS need this before resource.h */
+#ifndef __QNX__
+#include <sys/resource.h>
+#endif /* __QNX__ */
+#if defined( _AIX ) || defined( __QNX__ )
+#include <sys/select.h>
+#endif /* _AIX */
+#ifndef __QNX__
+#include <sys/shm.h>
+#include <signal.h>
+#include <sys/signal.h>
+#endif /* __QNX__ */
+#include <sys/stat.h>
+#include <sys/types.h> /* Verschiedene komische Typen */
+#if defined( __hpux ) && ( OS_VERSION == 9 )
+#include <vfork.h>
+#endif /* __hpux 9.x, after that it's in unistd.h */
+#include <sys/wait.h>
+/* #include <kitchensink.h> */
+#ifdef __QNX__
+#include <signal.h>
+#include <process.h>
+#endif /* __QNX__ */
+#include <errno.h>
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "rand-internal.h"
+
+#ifndef EAGAIN
+#define EAGAIN EWOULDBLOCK
+#endif
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#define GATHER_BUFSIZE 49152 /* Usually about 25K are filled */
+
+/* The structure containing information on random-data sources. Each
+ * record contains the source and a relative estimate of its usefulness
+ * (weighting) which is used to scale the number of kB of output from the
+ * source (total = data_bytes / usefulness). Usually the weighting is in the
+ * range 1-3 (or 0 for especially useless sources), resulting in a usefulness
+ * rating of 1...3 for each kB of source output (or 0 for the useless
+ * sources).
+ *
+ * If the source is constantly changing (certain types of network statistics
+ * have this characteristic) but the amount of output is small, the weighting
+ * is given as a negative value to indicate that the output should be treated
+ * as if a minimum of 1K of output had been obtained. If the source produces
+ * a lot of output then the scale factor is fractional, resulting in a
+ * usefulness rating of < 1 for each kB of source output.
+ *
+ * In order to provide enough randomness to satisfy the requirements for a
+ * slow poll, we need to accumulate at least 20 points of usefulness (a
+ * typical system should get about 30 points).
+ *
+ * Some potential options are missed out because of special considerations.
+ * pstat -i and pstat -f can produce amazing amounts of output (the record
+ * is 600K on an Oracle server) which floods the buffer and doesn't yield
+ * anything useful (apart from perhaps increasing the entropy of the vmstat
+ * output a bit), so we don't bother with this. pstat in general produces
+ * quite a bit of output, but it doesn't change much over time, so it gets
+ * very low weightings. netstat -s produces constantly-changing output but
+ * also produces quite a bit of it, so it only gets a weighting of 2 rather
+ * than 3. The same holds for netstat -in, which gets 1 rather than 2.
+ *
+ * Some binaries are stored in different locations on different systems so
+ * alternative paths are given for them. The code sorts out which one to
+ * run by itself, once it finds an exectable somewhere it moves on to the
+ * next source. The sources are arranged roughly in their order of
+ * usefulness, occasionally sources which provide a tiny amount of
+ * relatively useless data are placed ahead of ones which provide a large
+ * amount of possibly useful data because another 100 bytes can't hurt, and
+ * it means the buffer won't be swamped by one or two high-output sources.
+ * All the high-output sources are clustered towards the end of the list
+ * for this reason. Some binaries are checked for in a certain order, for
+ * example under Slowaris /usr/ucb/ps understands aux as an arg, but the
+ * others don't. Some systems have conditional defines enabling alternatives
+ * to commands which don't understand the usual options but will provide
+ * enough output (in the form of error messages) to look like they're the
+ * real thing, causing alternative options to be skipped (we can't check the
+ * return either because some commands return peculiar, non-zero status even
+ * when they're working correctly).
+ *
+ * In order to maximise use of the buffer, the code performs a form of run-
+ * length compression on its input where a repeated sequence of bytes is
+ * replaced by the occurrence count mod 256. Some commands output an awful
+ * lot of whitespace, this measure greatly increases the amount of data we
+ * can fit in the buffer.
+ *
+ * When we scale the weighting using the SC() macro, some preprocessors may
+ * give a division by zero warning for the most obvious expression
+ * 'weight ? 1024 / weight : 0' (and gcc 2.7.2.2 dies with a division by zero
+ * trap), so we define a value SC_0 which evaluates to zero when fed to
+ * '1024 / SC_0' */
+
+#define SC( weight ) ( 1024 / weight ) /* Scale factor */
+#define SC_0 16384 /* SC( SC_0 ) evaluates to 0 */
+
+static struct RI {
+ const char *path; /* Path to check for existence of source */
+ const char *arg; /* Args for source */
+ const int usefulness; /* Usefulness of source */
+ FILE *pipe; /* Pipe to source as FILE * */
+ int pipeFD; /* Pipe to source as FD */
+ pid_t pid; /* pid of child for waitpid() */
+ int length; /* Quantity of output produced */
+ const int hasAlternative; /* Whether source has alt.location */
+} dataSources[] = {
+
+ { "/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 0},
+ { "/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 0},
+ { "/usr/bin/pfstat", NULL, SC(-2), NULL, 0, 0, 0, 0},
+ { "/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 0},
+ { "/usr/ucb/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1},
+ { "/usr/etc/netstat", "-s", SC(2), NULL, 0, 0, 0, 0},
+ { "/usr/bin/nfsstat", NULL, SC(2), NULL, 0, 0, 0, 0},
+ { "/usr/ucb/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/netstat", "-m", SC(-1), NULL, 0, 0, 0, 0 },
+ { "/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/ucb/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1},
+ { "/usr/etc/netstat", "-in", SC(-1), NULL, 0, 0, 0, 0},
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.1.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* UDP in */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.4.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* UDP out */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.4.3.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* IP ? */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.10.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.11.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.13.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
+ { "/usr/bin/mpstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/w", NULL, SC(1), NULL, 0, 0, 0, 1 },
+ { "/usr/bsd/w", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/df", NULL, SC(1), NULL, 0, 0, 0, 1 },
+ { "/bin/df", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/sbin/portstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/iostat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bsd/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/usr/ucb/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 0 },
+#if defined( __sgi ) || defined( __hpux )
+ { "/bin/ps", "-el", SC(0.3), NULL, 0, 0, 0, 1 },
+#endif /* __sgi || __hpux */
+ { "/usr/ucb/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
+ { "/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 0 },
+ { "/bin/ps", "-A", SC(0.3), NULL, 0, 0, 0, 0 }, /*QNX*/
+ { "/usr/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 0 },
+ /* Unreliable source, depends on system usage */
+ { "/etc/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
+ /* pstat is your friend */
+ { "/usr/bin/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 1 },
+#ifdef __sgi
+ { "/usr/bsd/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
+#endif /* __sgi */
+#ifdef __hpux
+ { "/etc/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
+#endif /* __hpux */
+ { "/usr/bsd/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 0 },
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.1.0",
+ SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.3.0",
+ SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
+ { "/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 0 },
+ { "/usr/sbin/ripquery", "-nw 1 127.0.0.1",
+ SC(0.1), NULL, 0, 0, 0, 0 },
+ { "/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/ucb/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/tcpdump", "-c 5 -efvvx", SC(1), NULL, 0, 0, 0, 0 },
+ /* This is very environment-dependent. If network traffic is low, it'll
+ * probably time out before delivering 5 packets, which is OK because
+ * it'll probably be fixed stuff like ARP anyway */
+ { "/usr/sbin/advfsstat", "-b usr_domain",
+ SC(SC_0), NULL, 0, 0, 0, 0},
+ { "/usr/sbin/advfsstat", "-l 2 usr_domain",
+ SC(0.5), NULL, 0, 0, 0, 0},
+ { "/usr/sbin/advfsstat", "-p usr_domain",
+ SC(SC_0), NULL, 0, 0, 0, 0},
+ /* This is a complex and screwball program. Some systems have things
+ * like rX_dmn, x = integer, for RAID systems, but the statistics are
+ * pretty dodgy */
+#ifdef __QNXNTO__
+ { "/bin/pidin", "-F%A%B%c%d%E%I%J%K%m%M%n%N%p%P%S%s%T", SC(0.3),
+ NULL, 0, 0, 0, 0 },
+#endif
+#if 0
+ /* The following aren't enabled since they're somewhat slow and not very
+ * unpredictable, however they give an indication of the sort of sources
+ * you can use (for example the finger might be more useful on a
+ * firewalled internal network) */
+ { "/usr/bin/finger", "@ml.media.mit.edu", SC(0.9), NULL, 0, 0, 0, 0 },
+ { "/usr/local/bin/wget", "-O - http://lavarand.sgi.com/block.html",
+ SC(0.9), NULL, 0, 0, 0, 0 },
+ { "/bin/cat", "/usr/spool/mqueue/syslog", SC(0.9), NULL, 0, 0, 0, 0 },
+#endif /* 0 */
+ { NULL, NULL, 0, NULL, 0, 0, 0, 0 }
+};
+
+static byte *gather_buffer; /* buffer for gathering random noise */
+static int gather_buffer_size; /* size of the memory buffer */
+static uid_t gatherer_uid;
+
+/* The message structure used to communicate with the parent */
+typedef struct {
+ int usefulness; /* usefulness of data */
+ int ndata; /* valid bytes in data */
+ char data[500]; /* gathered data */
+} GATHER_MSG;
+
+#ifndef HAVE_WAITPID
+static pid_t
+waitpid(pid_t pid, int *statptr, int options)
+{
+#ifdef HAVE_WAIT4
+ return wait4(pid, statptr, options, NULL);
+#else
+ /* If wait4 is also not available, try wait3 for SVR3 variants */
+ /* Less ideal because can't actually request a specific pid */
+ /* For that reason, first check to see if pid is for an */
+ /* existing process. */
+ int tmp_pid, dummystat;;
+ if (kill(pid, 0) == -1) {
+ errno = ECHILD;
+ return -1;
+ }
+ if (statptr == NULL)
+ statptr = &dummystat;
+ while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
+ (tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
+ ;
+ return tmp_pid;
+#endif
+}
+#endif
+
+/* Under SunOS popen() doesn't record the pid of the child process. When
+ * pclose() is called, instead of calling waitpid() for the correct child, it
+ * calls wait() repeatedly until the right child is reaped. The problem is
+ * that this reaps any other children that happen to have died at that
+ * moment, and when their pclose() comes along, the process hangs forever.
+ * The fix is to use a wrapper for popen()/pclose() which saves the pid in
+ * the dataSources structure (code adapted from GNU-libc's popen() call).
+ *
+ * Aut viam inveniam aut faciam */
+
+static FILE *
+my_popen(struct RI *entry)
+{
+ int pipedes[2];
+ FILE *stream;
+
+ /* Create the pipe */
+ if (pipe(pipedes) < 0)
+ return (NULL);
+
+ /* Fork off the child ("vfork() is like an OS orgasm. All OS's want to
+ * do it, but most just end up faking it" - Chris Wedgwood). If your OS
+ * supports it, you should try to use vfork() here because it's somewhat
+ * more efficient */
+#if defined( sun ) || defined( __ultrix__ ) || defined( __osf__ ) || \
+ defined(__hpux)
+ entry->pid = vfork();
+#else /* */
+ entry->pid = fork();
+#endif /* Unixen which have vfork() */
+ if (entry->pid == (pid_t) - 1) {
+ /* The fork failed */
+ close(pipedes[0]);
+ close(pipedes[1]);
+ return (NULL);
+ }
+
+ if (entry->pid == (pid_t) 0) {
+ struct passwd *passwd;
+
+ /* We are the child. Make the read side of the pipe be stdout */
+ if (dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0)
+ exit(127);
+
+ /* Now that everything is set up, give up our permissions to make
+ * sure we don't read anything sensitive. If the getpwnam() fails,
+ * we default to -1, which is usually nobody */
+ if (gatherer_uid == (uid_t)-1 && \
+ (passwd = getpwnam("nobody")) != NULL)
+ gatherer_uid = passwd->pw_uid;
+
+ setuid(gatherer_uid);
+
+ /* Close the pipe descriptors */
+ close(pipedes[STDIN_FILENO]);
+ close(pipedes[STDOUT_FILENO]);
+
+ /* Try and exec the program */
+ execl(entry->path, entry->path, entry->arg, NULL);
+
+ /* Die if the exec failed */
+ exit(127);
+ }
+
+ /* We are the parent. Close the irrelevant side of the pipe and open
+ * the relevant side as a new stream. Mark our side of the pipe to
+ * close on exec, so new children won't see it */
+ close(pipedes[STDOUT_FILENO]);
+
+#ifdef FD_CLOEXEC
+ fcntl(pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
+#endif
+
+ stream = fdopen(pipedes[STDIN_FILENO], "r");
+
+ if (stream == NULL) {
+ int savedErrno = errno;
+
+ /* The stream couldn't be opened or the child structure couldn't be
+ * allocated. Kill the child and close the other side of the pipe */
+ kill(entry->pid, SIGKILL);
+ if (stream == NULL)
+ close(pipedes[STDOUT_FILENO]);
+ else
+ fclose(stream);
+
+ waitpid(entry->pid, NULL, 0);
+
+ entry->pid = 0;
+ errno = savedErrno;
+ return (NULL);
+ }
+
+ return (stream);
+}
+
+static int
+my_pclose(struct RI *entry)
+{
+ int status = 0;
+
+ if (fclose(entry->pipe))
+ return (-1);
+
+ /* We ignore the return value from the process because some
+ programs return funny values which would result in the input
+ being discarded even if they executed successfully. This isn't
+ a problem because the result data size threshold will filter
+ out any programs which exit with a usage message without
+ producing useful output. */
+ if (waitpid(entry->pid, NULL, 0) != entry->pid)
+ status = -1;
+
+ entry->pipe = NULL;
+ entry->pid = 0;
+ return (status);
+}
+
+
+/* Unix slow poll (without special support for Linux)
+ *
+ * If a few of the randomness sources create a large amount of output then
+ * the slowPoll() stops once the buffer has been filled (but before all the
+ * randomness sources have been sucked dry) so that the 'usefulness' factor
+ * remains below the threshold. For this reason the gatherer buffer has to
+ * be fairly sizeable on moderately loaded systems. This is something of a
+ * bug since the usefulness should be influenced by the amount of output as
+ * well as the source type */
+
+
+static int
+slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
+{
+ int moreSources;
+ struct timeval tv;
+ fd_set fds;
+#if defined( __hpux )
+ size_t maxFD = 0;
+#else
+ int maxFD = 0;
+#endif /* OS-specific brokenness */
+ int bufPos, i, usefulness = 0;
+ int last_so_far = 0;
+ int any_need_entropy = 0;
+ int delay;
+ int rc;
+
+ /* Fire up each randomness source */
+ FD_ZERO(&fds);
+ for (i = 0; dataSources[i].path != NULL; i++) {
+ /* Since popen() is a fairly heavy function, we check to see whether
+ * the executable exists before we try to run it */
+ if (access(dataSources[i].path, X_OK)) {
+ if( dbgfp && dbgall )
+ fprintf(dbgfp, "%s not present%s\n", dataSources[i].path,
+ dataSources[i].hasAlternative ?
+ ", has alternatives" : "");
+ dataSources[i].pipe = NULL;
+ }
+ else
+ dataSources[i].pipe = my_popen(&dataSources[i]);
+
+ if (dataSources[i].pipe != NULL) {
+ dataSources[i].pipeFD = fileno(dataSources[i].pipe);
+ if (dataSources[i].pipeFD > maxFD)
+ maxFD = dataSources[i].pipeFD;
+
+#ifdef O_NONBLOCK /* Ohhh what a hack (used for Atari) */
+ fcntl(dataSources[i].pipeFD, F_SETFL, O_NONBLOCK);
+#else
+#error O_NONBLOCK is missing
+#endif
+ /* FIXME: We need to make sure that the fd is less than
+ FD_SETSIZE. */
+ FD_SET(dataSources[i].pipeFD, &fds);
+ dataSources[i].length = 0;
+
+ /* If there are alternatives for this command, don't try and
+ * execute them */
+ while (dataSources[i].hasAlternative) {
+ if( dbgfp && dbgall )
+ fprintf(dbgfp, "Skipping %s\n", dataSources[i + 1].path);
+ i++;
+ }
+ }
+ }
+
+
+ /* Suck all the data we can get from each of the sources */
+ bufPos = 0;
+ moreSources = 1;
+ delay = 0; /* Return immediately (well, after 100ms) the first time. */
+ while (moreSources && bufPos <= gather_buffer_size) {
+ /* Wait for data to become available from any of the sources, with a
+ * timeout of 10 seconds. This adds even more randomness since data
+ * becomes available in a nondeterministic fashion. Kudos to HP's QA
+ * department for managing to ship a select() which breaks its own
+ * prototype */
+ tv.tv_sec = delay;
+ tv.tv_usec = delay? 0 : 100000;
+
+#if defined( __hpux ) && ( OS_VERSION == 9 )
+ rc = select(maxFD + 1, (int *)&fds, NULL, NULL, &tv);
+#else /* */
+ rc = select(maxFD + 1, &fds, NULL, NULL, &tv);
+#endif /* __hpux */
+ if (rc == -1)
+ break; /* Ooops; select failed. */
+
+ if (!rc)
+ {
+ /* FIXME: Because we run several tools at once it is
+ unlikely that we will see a block in select at all. */
+ if (!any_need_entropy
+ || last_so_far != (gather_buffer_size - bufPos) )
+ {
+ last_so_far = gather_buffer_size - bufPos;
+ _gcry_random_progress ("need_entropy", 'X',
+ last_so_far,
+ gather_buffer_size);
+ any_need_entropy = 1;
+ }
+ delay = 10; /* Use 10 seconds henceforth. */
+ /* Note that the fd_set is setup again at the end of this loop. */
+ }
+
+ /* One of the sources has data available, read it into the buffer */
+ for (i = 0; dataSources[i].path != NULL; i++) {
+ if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) {
+ size_t noBytes;
+
+ if ((noBytes = fread(gather_buffer + bufPos, 1,
+ gather_buffer_size - bufPos,
+ dataSources[i].pipe)) == 0) {
+ if (my_pclose(&dataSources[i]) == 0) {
+ int total = 0;
+
+ /* Try and estimate how much entropy we're getting
+ * from a data source */
+ if (dataSources[i].usefulness) {
+ if (dataSources[i].usefulness < 0)
+ total = (dataSources[i].length + 999)
+ / -dataSources[i].usefulness;
+ else
+ total = dataSources[i].length
+ / dataSources[i].usefulness;
+ }
+ if( dbgfp )
+ fprintf(dbgfp,
+ "%s %s contributed %d bytes, "
+ "usefulness = %d\n", dataSources[i].path,
+ (dataSources[i].arg != NULL) ?
+ dataSources[i].arg : "",
+ dataSources[i].length, total);
+ if( dataSources[i].length )
+ usefulness += total;
+ }
+ dataSources[i].pipe = NULL;
+ }
+ else {
+ int currPos = bufPos;
+ int endPos = bufPos + noBytes;
+
+ /* Run-length compress the input byte sequence */
+ while (currPos < endPos) {
+ int ch = gather_buffer[currPos];
+
+ /* If it's a single byte, just copy it over */
+ if (ch != gather_buffer[currPos + 1]) {
+ gather_buffer[bufPos++] = ch;
+ currPos++;
+ }
+ else {
+ int count = 0;
+
+ /* It's a run of repeated bytes, replace them
+ * with the byte count mod 256 */
+ while ((ch == gather_buffer[currPos])
+ && currPos < endPos) {
+ count++;
+ currPos++;
+ }
+ gather_buffer[bufPos++] = count;
+ noBytes -= count - 1;
+ }
+ }
+
+ /* Remember the number of (compressed) bytes of input we
+ * obtained */
+ dataSources[i].length += noBytes;
+ }
+ }
+ }
+
+ /* Check if there is more input available on any of the sources */
+ moreSources = 0;
+ FD_ZERO(&fds);
+ for (i = 0; dataSources[i].path != NULL; i++) {
+ if (dataSources[i].pipe != NULL) {
+ FD_SET(dataSources[i].pipeFD, &fds);
+ moreSources = 1;
+ }
+ }
+ }
+
+ if (any_need_entropy)
+ _gcry_random_progress ("need_entropy", 'X',
+ gather_buffer_size,
+ gather_buffer_size);
+
+ if( dbgfp ) {
+ fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness);
+ fflush(dbgfp);
+ }
+ *nbytes = bufPos;
+ return usefulness;
+}
+
+/****************
+ * Start the gatherer process which writes messages of
+ * type GATHERER_MSG to pipedes
+ */
+static void
+start_gatherer( int pipefd )
+{
+ FILE *dbgfp = NULL;
+ int dbgall;
+
+ {
+ const char *s = getenv("GCRYPT_RNDUNIX_DBG");
+ if( s ) {
+ dbgfp = (*s=='-' && !s[1])? stdout : fopen(s, "a");
+ if( !dbgfp )
+ log_info("can't open debug file `%s': %s\n",
+ s, strerror(errno) );
+ else
+ fprintf(dbgfp,"\nSTART RNDUNIX DEBUG pid=%d\n", (int)getpid());
+ }
+ dbgall = !!getenv("GCRYPT_RNDUNIX_DBGALL");
+ }
+ /* close all files but the ones we need */
+ { int nmax, n1, n2, i;
+#ifdef _SC_OPEN_MAX
+ if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) {
+# ifdef _POSIX_OPEN_MAX
+ nmax = _POSIX_OPEN_MAX;
+# else
+ nmax = 20; /* assume a reasonable value */
+# endif
+ }
+ /* AIX returns INT32_MAX instead of a proper value. We assume that
+ * this is always an error and use a reasonable value. */
+# ifdef INT32_MAX
+ if (nmax == INT32_MAX)
+ nmax = 20;
+# endif
+#else /*!_SC_OPEN_MAX*/
+ nmax = 20; /* assume a reasonable value */
+#endif /*!_SC_OPEN_MAX*/
+ n1 = fileno( stderr );
+ n2 = dbgfp? fileno( dbgfp ) : -1;
+ for(i=0; i < nmax; i++ ) {
+ if( i != n1 && i != n2 && i != pipefd )
+ close(i);
+ }
+ errno = 0;
+ }
+
+
+ /* Set up the buffer. Not ethat we use a plain standard malloc here. */
+ gather_buffer_size = GATHER_BUFSIZE;
+ gather_buffer = malloc( gather_buffer_size );
+ if( !gather_buffer ) {
+ log_error("out of core while allocating the gatherer buffer\n");
+ exit(2);
+ }
+
+ /* Reset the SIGC(H)LD handler to the system default. This is necessary
+ * because if the program which cryptlib is a part of installs its own
+ * SIGC(H)LD handler, it will end up reaping the cryptlib children before
+ * cryptlib can. As a result, my_pclose() will call waitpid() on a
+ * process which has already been reaped by the installed handler and
+ * return an error, so the read data won't be added to the randomness
+ * pool. There are two types of SIGC(H)LD naming, the SysV SIGCLD and
+ * the BSD/Posix SIGCHLD, so we need to handle either possibility */
+#ifdef SIGCLD
+ signal(SIGCLD, SIG_DFL);
+#else
+ signal(SIGCHLD, SIG_DFL);
+#endif
+
+ fclose(stderr); /* Arrghh!! It's Stuart code!! */
+
+ /* Mary goes to Berkeley: NetBSD emits warnings if the standard
+ descriptors are not open when running setuid program. Thus we
+ connect them to the bitbucket if they are not already open. */
+ {
+ struct stat statbuf;
+
+ if (fstat (STDIN_FILENO, &statbuf) == -1 && errno == EBADF)
+ open ("/dev/null",O_RDONLY);
+ if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
+ open ("/dev/null",O_WRONLY);
+ if (fstat (STDERR_FILENO, &statbuf) == -1 && errno == EBADF)
+ open ("/dev/null",O_WRONLY);
+ }
+
+ for(;;) {
+ GATHER_MSG msg;
+ size_t nbytes;
+ const char *p;
+
+ msg.usefulness = slow_poll( dbgfp, dbgall, &nbytes );
+ p = (const char*)gather_buffer;
+ while( nbytes ) {
+ msg.ndata = nbytes > sizeof(msg.data)? sizeof(msg.data) : nbytes;
+ memcpy( msg.data, p, msg.ndata );
+ nbytes -= msg.ndata;
+ p += msg.ndata;
+
+ while( write( pipefd, &msg, sizeof(msg) ) != sizeof(msg) ) {
+ if( errno == EINTR )
+ continue;
+ if( errno == EAGAIN ) {
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 50000;
+ select(0, NULL, NULL, NULL, &tv);
+ continue;
+ }
+ if( errno == EPIPE ) /* parent has exited, so give up */
+ exit(0);
+
+ /* we can't do very much here because stderr is closed */
+ if( dbgfp )
+ fprintf(dbgfp, "gatherer can't write to pipe: %s\n",
+ strerror(errno) );
+ /* we start a new poll to give the system some time */
+ nbytes = 0;
+ break;
+ }
+ }
+ }
+ /* we are killed when the parent dies */
+}
+
+
+static int
+read_a_msg( int fd, GATHER_MSG *msg )
+{
+ char *buffer = (char*)msg;
+ size_t length = sizeof( *msg );
+ int n;
+
+ do {
+ do {
+ n = read(fd, buffer, length );
+ } while( n == -1 && errno == EINTR );
+ if( n == -1 )
+ return -1;
+ buffer += n;
+ length -= n;
+ } while( length );
+ return 0;
+}
+
+
+/****************
+ * Using a level of 0 should never block and better add nothing
+ * to the pool. So this is just a dummy for this gatherer.
+ */
+int
+_gcry_rndunix_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ static pid_t gatherer_pid = 0;
+ static int pipedes[2];
+ GATHER_MSG msg;
+ size_t n;
+
+ if( !level )
+ return 0;
+
+ if( !gatherer_pid ) {
+ /* Make sure we are not setuid. */
+ if ( getuid() != geteuid() )
+ BUG();
+ /* time to start the gatherer process */
+ if( pipe( pipedes ) ) {
+ log_error("pipe() failed: %s\n", strerror(errno));
+ return -1;
+ }
+ gatherer_pid = fork();
+ if( gatherer_pid == -1 ) {
+ log_error("can't for gatherer process: %s\n", strerror(errno));
+ return -1;
+ }
+ if( !gatherer_pid ) {
+ start_gatherer( pipedes[1] );
+ /* oops, can't happen */
+ return -1;
+ }
+ }
+
+ /* now read from the gatherer */
+ while( length ) {
+ int goodness;
+ unsigned long subtract;
+
+ if( read_a_msg( pipedes[0], &msg ) ) {
+ log_error("reading from gatherer pipe failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+
+ if( level > 1 ) {
+ if( msg.usefulness > 30 )
+ goodness = 100;
+ else if ( msg.usefulness )
+ goodness = msg.usefulness * 100 / 30;
+ else
+ goodness = 0;
+ }
+ else if( level ) {
+ if( msg.usefulness > 15 )
+ goodness = 100;
+ else if ( msg.usefulness )
+ goodness = msg.usefulness * 100 / 15;
+ else
+ goodness = 0;
+ }
+ else
+ goodness = 100; /* goodness of level 0 is always 100 % */
+
+ n = msg.ndata;
+ if( n > length )
+ n = length;
+ (*add)( msg.data, n, origin );
+
+ /* this is the trick how we cope with the goodness */
+ subtract = (unsigned long)n * goodness / 100;
+ /* subtract at least 1 byte to avoid infinite loops */
+ length -= subtract ? subtract : 1;
+ }
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/random/rndw32.c b/comm/third_party/libgcrypt/random/rndw32.c
new file mode 100644
index 0000000000..b3f63d2072
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/rndw32.c
@@ -0,0 +1,1030 @@
+/* rndw32.c - W32 entropy gatherer
+ * Copyright (C) 1999, 2000, 2002, 2003, 2007,
+ * 2010 Free Software Foundation, Inc.
+ * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-2006
+ *
+ * This file is part of Libgcrypt.
+ *
+ *************************************************************************
+ * The code here is based on code from Cryptlib 3.0 beta by Peter Gutmann.
+ * Source file misc/rndwin32.c "Win32 Randomness-Gathering Code" with this
+ * copyright notice:
+ *
+ * This module is part of the cryptlib continuously seeded pseudorandom
+ * number generator. For usage conditions, see lib_rand.c
+ *
+ * [Here is the notice from lib_rand.c, which is now called dev_sys.c]
+ *
+ * This module and the misc/rnd*.c modules represent the cryptlib
+ * continuously seeded pseudorandom number generator (CSPRNG) as described in
+ * my 1998 Usenix Security Symposium paper "The generation of random numbers
+ * for cryptographic purposes".
+ *
+ * The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
+ * 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG
+ * modules and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice
+ * and this permission notice in its entirety.
+ *
+ * 2. Redistributions in binary form must reproduce the copyright notice in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * 3. A copy of any bugfixes or enhancements made must be provided to the
+ * author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
+ * baseline version of the code.
+ *
+ * ALTERNATIVELY, the code may be distributed under the terms of the
+ * GNU Lesser General Public License, version 2.1 or any later version
+ * published by the Free Software Foundation, in which case the
+ * provisions of the GNU LGPL are required INSTEAD OF the above
+ * restrictions.
+ *
+ * Although not required under the terms of the LGPL, it would still
+ * be nice if you could make any changes available to the author to
+ * allow a consistent code base to be maintained.
+ *************************************************************************
+ * The above alternative was changed from GPL to LGPL on 2007-08-22 with
+ * permission from Peter Gutmann:
+ *==========
+ From: pgut001 <pgut001@cs.auckland.ac.nz>
+ Subject: Re: LGPL for the windows entropy gatherer
+ To: wk@gnupg.org
+ Date: Wed, 22 Aug 2007 03:05:42 +1200
+
+ Hi,
+
+ >As of now libgcrypt is GPL under Windows due to that module and some people
+ >would really like to see it under LGPL too. Can you do such a license change
+ >to LGPL version 2? Note that LGPL give the user the option to relicense it
+ >under GPL, so the change would be pretty easy and backwar compatible.
+
+ Sure. I assumed that since GPG was GPLd, you'd prefer the GPL for the entropy
+ code as well, but Ian asked for LGPL as an option so as of the next release
+ I'll have LGPL in there. You can consider it to be retroactive, so your
+ current version will be LGPLd as well.
+
+ Peter.
+ *==========
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#ifdef __GNUC__
+#include <stdint.h>
+#endif
+
+#include <winsock2.h>
+#include <windows.h>
+
+
+#include "types.h"
+#include "g10lib.h"
+#include "rand-internal.h"
+
+
+/* Definitions which are missing from the current GNU Windows32Api. */
+#ifndef IOCTL_DISK_PERFORMANCE
+#define IOCTL_DISK_PERFORMANCE 0x00070020
+#endif
+
+/* This used to be (6*8+5*4+8*2), but Peter Gutmann figured a larger
+ value in a newer release. So we use a far larger value. */
+#define SIZEOF_DISK_PERFORMANCE_STRUCT 256
+
+/* We don't include wincrypt.h so define it here. */
+#define HCRYPTPROV HANDLE
+
+
+/* When we query the performance counters, we allocate an initial buffer and
+ * then reallocate it as required until RegQueryValueEx() stops returning
+ * ERROR_MORE_DATA. The following values define the initial buffer size and
+ * step size by which the buffer is increased
+ */
+#define PERFORMANCE_BUFFER_SIZE 65536 /* Start at 64K */
+#define PERFORMANCE_BUFFER_STEP 16384 /* Step by 16K */
+
+
+/* The number of bytes to read from the system RNG on each slow poll. */
+#define SYSTEMRNG_BYTES 64
+
+/* Intel Chipset CSP type and name */
+#define PROV_INTEL_SEC 22
+#define INTEL_DEF_PROV "Intel Hardware Cryptographic Service Provider"
+
+
+
+
+/* Type definitions for function pointers to call NetAPI32 functions. */
+typedef DWORD (WINAPI *NETSTATISTICSGET)(LPWSTR szServer, LPWSTR szService,
+ DWORD dwLevel, DWORD dwOptions,
+ LPBYTE *lpBuffer);
+typedef DWORD (WINAPI *NETAPIBUFFERSIZE)(LPVOID lpBuffer, LPDWORD cbBuffer);
+typedef DWORD (WINAPI *NETAPIBUFFERFREE)(LPVOID lpBuffer);
+
+/* Type definitions for function pointers to call native NT functions. */
+typedef DWORD (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD systemInformationClass,
+ PVOID systemInformation,
+ ULONG systemInformationLength,
+ PULONG returnLength);
+typedef DWORD (WINAPI *NTQUERYINFORMATIONPROCESS)
+ (HANDLE processHandle, DWORD processInformationClass,
+ PVOID processInformation, ULONG processInformationLength,
+ PULONG returnLength);
+typedef DWORD (WINAPI *NTPOWERINFORMATION)
+ (DWORD powerInformationClass, PVOID inputBuffer,
+ ULONG inputBufferLength, PVOID outputBuffer, ULONG outputBufferLength );
+
+/* Type definitions for function pointers to call CryptoAPI functions. */
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *phProv,
+ LPCTSTR pszContainer,
+ LPCTSTR pszProvider,
+ DWORD dwProvType,
+ DWORD dwFlags);
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,
+ BYTE *pbBuffer);
+typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv, DWORD dwFlags);
+
+/* Somewhat alternative functionality available as a direct call, for
+ Windows XP and newer. This is the CryptoAPI RNG, which isn't anywhere
+ near as good as the HW RNG, but we use it if it's present on the basis
+ that at least it can't make things any worse. This direct access version
+ is only available under Windows XP, we don't go out of our way to access
+ the more general CryptoAPI one since the main purpose of using it is to
+ take advantage of any possible future hardware RNGs that may be added,
+ for example via TCPA devices. */
+typedef BOOL (WINAPI *RTLGENRANDOM)(PVOID RandomBuffer,
+ ULONG RandomBufferLength);
+
+
+
+/* MBM data structures, originally by Alexander van Kaam, converted to C by
+ Anders@Majland.org, finally updated by Chris Zahrt <techn0@iastate.edu> */
+#define BusType char
+#define SMBType char
+#define SensorType char
+
+typedef struct
+{
+ SensorType iType; /* Type of sensor. */
+ int Count; /* Number of sensor for that type. */
+} SharedIndex;
+
+typedef struct
+{
+ SensorType ssType; /* Type of sensor */
+ unsigned char ssName[12]; /* Name of sensor */
+ char sspadding1[3]; /* Padding of 3 bytes */
+ double ssCurrent; /* Current value */
+ double ssLow; /* Lowest readout */
+ double ssHigh; /* Highest readout */
+ long ssCount; /* Total number of readout */
+ char sspadding2[4]; /* Padding of 4 bytes */
+ long double ssTotal; /* Total amount of all readouts */
+ char sspadding3[6]; /* Padding of 6 bytes */
+ double ssAlarm1; /* Temp & fan: high alarm; voltage: % off */
+ double ssAlarm2; /* Temp: low alarm */
+} SharedSensor;
+
+typedef struct
+{
+ short siSMB_Base; /* SMBus base address */
+ BusType siSMB_Type; /* SMBus/Isa bus used to access chip */
+ SMBType siSMB_Code; /* SMBus sub type, Intel, AMD or ALi */
+ char siSMB_Addr; /* Address of sensor chip on SMBus */
+ unsigned char siSMB_Name[41]; /* Nice name for SMBus */
+ short siISA_Base; /* ISA base address of sensor chip on ISA */
+ int siChipType; /* Chip nr, connects with Chipinfo.ini */
+ char siVoltageSubType; /* Subvoltage option selected */
+} SharedInfo;
+
+typedef struct
+{
+ double sdVersion; /* Version number (example: 51090) */
+ SharedIndex sdIndex[10]; /* Sensor index */
+ SharedSensor sdSensor[100]; /* Sensor info */
+ SharedInfo sdInfo; /* Misc.info */
+ unsigned char sdStart[41]; /* Start time */
+
+ /* We don't use the next two fields both because they're not random
+ and because it provides a nice safety margin in case of data size
+ mis- estimates (we always under-estimate the buffer size). */
+#if 0
+ unsigned char sdCurrent[41]; /* Current time */
+ unsigned char sdPath[256]; /* MBM path */
+#endif /*0*/
+} SharedData;
+
+
+
+/* One time initialized handles and function pointers. We use dynamic
+ loading of the DLLs to do without them in case libgcrypt does not
+ need any random. */
+static HANDLE hNetAPI32;
+static NETSTATISTICSGET pNetStatisticsGet;
+static NETAPIBUFFERSIZE pNetApiBufferSize;
+static NETAPIBUFFERFREE pNetApiBufferFree;
+
+static HANDLE hNTAPI;
+static NTQUERYSYSTEMINFORMATION pNtQuerySystemInformation;
+static NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess;
+static NTPOWERINFORMATION pNtPowerInformation;
+
+static HANDLE hAdvAPI32;
+static CRYPTACQUIRECONTEXT pCryptAcquireContext;
+static CRYPTGENRANDOM pCryptGenRandom;
+static CRYPTRELEASECONTEXT pCryptReleaseContext;
+static RTLGENRANDOM pRtlGenRandom;
+
+
+/* Other module global variables. */
+static int system_rng_available; /* Whether a system RNG is available. */
+static HCRYPTPROV hRNGProv; /* Handle to Intel RNG CSP. */
+
+/* The debug flag. Debugging is enabled if the value of the envvar
+ * GCRY_RNDW32_DBG is a positive number.*/
+static int debug_me;
+
+static int system_is_w2000; /* True if running on W2000. */
+
+
+
+/* Try and connect to the system RNG if there's one present. */
+static void
+init_system_rng (void)
+{
+ system_rng_available = 0;
+ hRNGProv = NULL;
+
+ hAdvAPI32 = GetModuleHandle ("AdvAPI32.dll");
+ if (!hAdvAPI32)
+ return;
+
+ pCryptAcquireContext = (CRYPTACQUIRECONTEXT)
+ GetProcAddress (hAdvAPI32, "CryptAcquireContextA");
+ pCryptGenRandom = (CRYPTGENRANDOM)
+ GetProcAddress (hAdvAPI32, "CryptGenRandom");
+ pCryptReleaseContext = (CRYPTRELEASECONTEXT)
+ GetProcAddress (hAdvAPI32, "CryptReleaseContext");
+
+ /* Get a pointer to the native randomness function if it's available.
+ This isn't exported by name, so we have to get it by ordinal. */
+ pRtlGenRandom = (RTLGENRANDOM)
+ GetProcAddress (hAdvAPI32, "SystemFunction036");
+
+ /* Try and connect to the PIII RNG CSP. The AMD 768 southbridge (from
+ the 760 MP chipset) also has a hardware RNG, but there doesn't appear
+ to be any driver support for this as there is for the Intel RNG so we
+ can't do much with it. OTOH the Intel RNG is also effectively dead
+ as well, mostly due to virtually nonexistent support/marketing by
+ Intel, it's included here mostly for form's sake. */
+ if ( (!pCryptAcquireContext || !pCryptGenRandom || !pCryptReleaseContext
+ || !pCryptAcquireContext (&hRNGProv, NULL, INTEL_DEF_PROV,
+ PROV_INTEL_SEC, 0) )
+ && !pRtlGenRandom)
+ {
+ hAdvAPI32 = NULL;
+ }
+ else
+ system_rng_available = 1;
+}
+
+
+/* Read data from the system RNG if availavle. */
+static void
+read_system_rng (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins requester)
+{
+ BYTE buffer[ SYSTEMRNG_BYTES + 8 ];
+ int quality = 0;
+
+ if (!system_rng_available)
+ return;
+
+ /* Read SYSTEMRNG_BYTES bytes from the system RNG. We don't rely on
+ this for all our randomness requirements (particularly the
+ software RNG) in case it's broken in some way. */
+ if (hRNGProv)
+ {
+ if (pCryptGenRandom (hRNGProv, SYSTEMRNG_BYTES, buffer))
+ quality = 80;
+ }
+ else if (pRtlGenRandom)
+ {
+ if ( pRtlGenRandom (buffer, SYSTEMRNG_BYTES))
+ quality = 50;
+ }
+ if (quality > 0)
+ {
+ if (debug_me)
+ log_debug ("rndw32#read_system_rng: got %d bytes of quality %d\n",
+ SYSTEMRNG_BYTES, quality);
+ (*add) (buffer, SYSTEMRNG_BYTES, requester);
+ wipememory (buffer, SYSTEMRNG_BYTES);
+ }
+}
+
+
+/* Read data from MBM. This communicates via shared memory, so all we
+ need to do is map a file and read the data out. */
+static void
+read_mbm_data (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins requester)
+{
+ HANDLE hMBMData;
+ SharedData *mbmDataPtr;
+
+ hMBMData = OpenFileMapping (FILE_MAP_READ, FALSE, "$M$B$M$5$S$D$" );
+ if (hMBMData)
+ {
+ mbmDataPtr = (SharedData*)MapViewOfFile (hMBMData, FILE_MAP_READ,0,0,0);
+ if (mbmDataPtr)
+ {
+ if (debug_me)
+ log_debug ("rndw32#read_mbm_data: got %d bytes\n",
+ (int)sizeof (SharedData));
+ (*add) (mbmDataPtr, sizeof (SharedData), requester);
+ UnmapViewOfFile (mbmDataPtr);
+ }
+ CloseHandle (hMBMData);
+ }
+}
+
+
+/* Fallback method using the registry to poll the statistics. */
+static void
+registry_poll (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins requester)
+{
+ static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
+ int iterations;
+ DWORD dwSize, status;
+ PERF_DATA_BLOCK *pPerfData;
+
+ /* Get information from the system performance counters. This can take a
+ few seconds to do. In some environments the call to RegQueryValueEx()
+ can produce an access violation at some random time in the future, in
+ some cases adding a short delay after the following code block makes
+ the problem go away. This problem is extremely difficult to
+ reproduce, I haven't been able to get it to occur despite running it
+ on a number of machines. MS knowledge base article Q178887 covers
+ this type of problem, it's typically caused by an external driver or
+ other program that adds its own values under the
+ HKEY_PERFORMANCE_DATA key. The NT kernel, via Advapi32.dll, calls the
+ required external module to map in the data inside an SEH try/except
+ block, so problems in the module's collect function don't pop up until
+ after it has finished, so the fault appears to occur in Advapi32.dll.
+ There may be problems in the NT kernel as well though, a low-level
+ memory checker indicated that ExpandEnvironmentStrings() in
+ Kernel32.dll, called an interminable number of calls down inside
+ RegQueryValueEx(), was overwriting memory (it wrote twice the
+ allocated size of a buffer to a buffer allocated by the NT kernel).
+ OTOH this could be coming from the external module calling back into
+ the kernel, which eventually causes the problem described above.
+
+ Possibly as an extension of the problem that the krnlWaitSemaphore()
+ call above works around, running two instances of cryptlib (e.g. two
+ applications that use it) under NT4 can result in one of them hanging
+ in the RegQueryValueEx() call. This happens only under NT4 and is
+ hard to reproduce in any consistent manner.
+
+ One workaround that helps a bit is to read the registry as a remote
+ (rather than local) registry, it's possible that the use of a network
+ RPC call isolates the calling app from the problem in that whatever
+ service handles the RPC is taking the hit and not affecting the
+ calling app. Since this would require another round of extensive
+ testing to verify and the NT native API call is working fine, we'll
+ stick with the native API call for now.
+
+ Some versions of NT4 had a problem where the amount of data returned
+ was mis-reported and would never settle down, because of this the code
+ below includes a safety-catch that bails out after 10 attempts have
+ been made, this results in no data being returned but at does ensure
+ that the thread will terminate.
+
+ In addition to these problems the code in RegQueryValueEx() that
+ estimates the amount of memory required to return the performance
+ counter information isn't very accurate (it's much worse than the
+ "slightly-inaccurate" level that the MS docs warn about, it's usually
+ wildly off) since it always returns a worst-case estimate which is
+ usually nowhere near the actual amount required. For example it may
+ report that 128K of memory is required, but only return 64K of data.
+
+ Even worse than the registry-based performance counters is the
+ performance data helper (PDH) shim that tries to make the counters
+ look like the old Win16 API (which is also used by Win95). Under NT
+ this can consume tens of MB of memory and huge amounts of CPU time
+ while it gathers its data, and even running once can still consume
+ about 1/2MB of memory */
+ if (getenv ("GCRYPT_RNDW32_NOPERF"))
+ {
+ static int shown;
+
+ if (!shown)
+ {
+ shown = 1;
+ log_info ("note: get performance data has been disabled\n");
+ }
+ }
+ else
+ {
+ pPerfData = xmalloc (cbPerfData);
+ for (iterations=0; iterations < 10; iterations++)
+ {
+ dwSize = cbPerfData;
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );
+
+ status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
+ NULL, (LPBYTE) pPerfData, &dwSize);
+ if (status == ERROR_SUCCESS)
+ {
+ if (!memcmp (pPerfData->Signature, L"PERF", 8))
+ (*add) ( pPerfData, dwSize, requester );
+ else
+ log_debug ("rndw32: no PERF signature\n");
+ break;
+ }
+ else if (status == ERROR_MORE_DATA)
+ {
+ cbPerfData += PERFORMANCE_BUFFER_STEP;
+ pPerfData = xrealloc (pPerfData, cbPerfData);
+ }
+ else
+ {
+ static int been_here;
+
+ /* Silence the error message. In particular under Wine (as
+ of 2008) we would get swamped with such diagnotiscs. One
+ such diagnotiscs should be enough. */
+ if (been_here != status)
+ {
+ been_here = status;
+ log_debug ("rndw32: get performance data problem: ec=%ld\n",
+ status);
+ }
+ break;
+ }
+ }
+ xfree (pPerfData);
+ }
+
+ /* Although this isn't documented in the Win32 API docs, it's necessary
+ to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
+ implicitly opened on the first call to RegQueryValueEx()). If this
+ isn't done then any system components which provide performance data
+ can't be removed or changed while the handle remains active. */
+ RegCloseKey (HKEY_PERFORMANCE_DATA);
+}
+
+
+static void
+slow_gatherer ( void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins requester )
+{
+ static int is_initialized = 0;
+ static int is_workstation = 1;
+ HANDLE hDevice;
+ DWORD dwType, dwSize, dwResult;
+ ULONG ulSize;
+ int drive_no, status;
+ int no_results = 0;
+ void *buffer;
+
+ if ( !is_initialized )
+ {
+ HKEY hKey;
+
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer: init toolkit\n" );
+ /* Find out whether this is an NT server or workstation if necessary */
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
+ 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ BYTE szValue[32 + 8];
+ dwSize = 32;
+
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer: check product options\n" );
+
+ status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
+ szValue, &dwSize);
+ if (status == ERROR_SUCCESS && stricmp ((char*)szValue, "WinNT"))
+ {
+ /* Note: There are (at least) three cases for ProductType:
+ WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
+ NT Server acting as a Domain Controller. */
+ is_workstation = 0;
+ if ( debug_me )
+ log_debug ("rndw32: this is a NT server\n");
+ }
+ RegCloseKey (hKey);
+ }
+
+ /* The following are fixed for the lifetime of the process so we
+ only add them once */
+ /* readPnPData (); - we have not implemented that. */
+
+ /* Initialize the NetAPI32 function pointers if necessary */
+ hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
+ if (hNetAPI32)
+ {
+ if (debug_me)
+ log_debug ("rndw32#slow_gatherer: netapi32 loaded\n" );
+ pNetStatisticsGet = (NETSTATISTICSGET)
+ GetProcAddress (hNetAPI32, "NetStatisticsGet");
+ pNetApiBufferSize = (NETAPIBUFFERSIZE)
+ GetProcAddress (hNetAPI32, "NetApiBufferSize");
+ pNetApiBufferFree = (NETAPIBUFFERFREE)
+ GetProcAddress (hNetAPI32, "NetApiBufferFree");
+
+ if (!pNetStatisticsGet || !pNetApiBufferSize || !pNetApiBufferFree)
+ {
+ FreeLibrary (hNetAPI32);
+ hNetAPI32 = NULL;
+ log_debug ("rndw32: No NETAPI found\n" );
+ }
+ }
+
+ /* Initialize the NT kernel native API function pointers if necessary */
+ hNTAPI = GetModuleHandle ("NTDll.dll");
+ if (hNTAPI)
+ {
+ /* Get a pointer to the NT native information query functions */
+ pNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)
+ GetProcAddress (hNTAPI, "NtQuerySystemInformation");
+ pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)
+ GetProcAddress (hNTAPI, "NtQueryInformationProcess");
+ pNtPowerInformation = (NTPOWERINFORMATION)
+ GetProcAddress(hNTAPI, "NtPowerInformation");
+
+ if (!pNtQuerySystemInformation || !pNtQueryInformationProcess)
+ hNTAPI = NULL;
+ }
+
+
+ is_initialized = 1;
+ }
+
+ read_system_rng ( add, requester );
+ read_mbm_data ( add, requester );
+
+ /* Get network statistics. Note: Both NT Workstation and NT Server by
+ default will be running both the workstation and server services. The
+ heuristic below is probably useful though on the assumption that the
+ majority of the network traffic will be via the appropriate service.
+ In any case the network statistics return almost no randomness. */
+ {
+ LPBYTE lpBuffer;
+
+ if (hNetAPI32
+ && !pNetStatisticsGet (NULL,
+ (LPWSTR)(is_workstation ? L"LanmanWorkstation" :
+ L"LanmanServer"), 0, 0, &lpBuffer))
+ {
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer: get netstats\n" );
+ pNetApiBufferSize (lpBuffer, &dwSize);
+ (*add) ( lpBuffer, dwSize, requester );
+ pNetApiBufferFree (lpBuffer);
+ }
+ }
+
+ /* Get disk I/O statistics for all the hard drives. 100 is an
+ arbitrary failsafe limit. */
+ for (drive_no = 0; drive_no < 100 ; drive_no++)
+ {
+ char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT + 8];
+ char szDevice[50];
+
+ /* Check whether we can access this device. */
+ snprintf (szDevice, sizeof szDevice, "\\\\.\\PhysicalDrive%d",
+ drive_no);
+ hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ if (hDevice == INVALID_HANDLE_VALUE)
+ break; /* No more drives. */
+
+ /* Note: This only works if you have turned on the disk performance
+ counters with 'diskperf -y'. These counters are off by default. */
+ dwSize = sizeof diskPerformance;
+ if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
+ diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT,
+ &dwSize, NULL))
+ {
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer: iostat drive %d\n",
+ drive_no);
+ (*add) (diskPerformance, dwSize, requester);
+ }
+ else
+ {
+ log_info ("NOTE: you should run 'diskperf -y' "
+ "to enable the disk statistics\n");
+ }
+ CloseHandle (hDevice);
+ }
+
+ /* In theory we should be using the Win32 performance query API to obtain
+ unpredictable data from the system, however this is so unreliable (see
+ the multiple sets of comments in registryPoll()) that it's too risky
+ to rely on it except as a fallback in emergencies. Instead, we rely
+ mostly on the NT native API function NtQuerySystemInformation(), which
+ has the dual advantages that it doesn't have as many (known) problems
+ as the Win32 equivalent and that it doesn't access the data indirectly
+ via pseudo-registry keys, which means that it's much faster. Note
+ that the Win32 equivalent actually works almost all of the time, the
+ problem is that on one or two systems it can fail in strange ways that
+ are never the same and can't be reproduced on any other system, which
+ is why we use the native API here. Microsoft officially documented
+ this function in early 2003, so it'll be fairly safe to use. */
+ if ( !hNTAPI )
+ {
+ registry_poll (add, requester);
+ return;
+ }
+
+
+ /* Scan the first 64 possible information types (we don't bother with
+ increasing the buffer size as we do with the Win32 version of the
+ performance data read, we may miss a few classes but it's no big deal).
+ This scan typically yields around 20 pieces of data, there's nothing
+ in the range 65...128 so chances are there won't be anything above
+ there either. */
+ buffer = xmalloc (PERFORMANCE_BUFFER_SIZE);
+ for (dwType = 0; dwType < 64; dwType++)
+ {
+ switch (dwType)
+ {
+ /* ID 17 = SystemObjectInformation hangs on some win2k systems. */
+ case 17:
+ if (system_is_w2000)
+ continue;
+ break;
+
+ /* Some information types are write-only (the IDs are shared with
+ a set-information call), we skip these. */
+ case 26: case 27: case 38: case 46: case 47: case 48: case 52:
+ continue;
+
+ /* ID 53 = SystemSessionProcessInformation reads input from the
+ output buffer, which has to contain a session ID and pointer
+ to the actual buffer in which to store the session information.
+ Because this isn't a standard query, we skip this. */
+ case 53:
+ continue;
+ }
+
+ /* Query the info for this ID. Some results (for example for
+ ID = 6, SystemCallCounts) are only available in checked builds
+ of the kernel. A smaller subcless of results require that
+ certain system config flags be set, for example
+ SystemObjectInformation requires that the
+ FLG_MAINTAIN_OBJECT_TYPELIST be set in NtGlobalFlags. To avoid
+ having to special-case all of these, we try reading each one and
+ only use those for which we get a success status. */
+ dwResult = pNtQuerySystemInformation (dwType, buffer,
+ PERFORMANCE_BUFFER_SIZE - 2048,
+ &ulSize);
+ if (dwResult != ERROR_SUCCESS)
+ continue;
+
+ /* Some calls (e.g. ID = 23, SystemProcessorStatistics, and ID = 24,
+ SystemDpcInformation) incorrectly return a length of zero, so we
+ manually adjust the length to the correct value. */
+ if ( !ulSize )
+ {
+ if (dwType == 23)
+ ulSize = 6 * sizeof (ULONG);
+ else if (dwType == 24)
+ ulSize = 5 * sizeof (ULONG);
+ }
+
+ /* If we got some data back, add it to the entropy pool. */
+ if (ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048)
+ {
+ if (debug_me)
+ log_debug ("rndw32#slow_gatherer: %lu bytes from sysinfo %ld\n",
+ ulSize, dwType);
+ (*add) (buffer, ulSize, requester);
+ no_results++;
+ }
+ }
+
+ /* Now we would do the same for the process information. This
+ call would rather ugly in that it requires an exact length
+ match for the data returned, failing with a
+ STATUS_INFO_LENGTH_MISMATCH error code (0xC0000004) if the
+ length isn't an exact match. It requires a compiler to handle
+ complex nested structs, alignment issues, and so on, and
+ without the headers in which the entries are declared it's
+ almost impossible to do. Thus we don't. */
+
+
+ /* Finally, do the same for the system power status information. There
+ are only a limited number of useful information types available so we
+ restrict ourselves to the useful types. In addition since this
+ function doesn't return length information, we have to hardcode in
+ length data. */
+ if (pNtPowerInformation)
+ {
+ static const struct { int type; int size; } powerInfo[] = {
+ { 0, 128 }, /* SystemPowerPolicyAc */
+ { 1, 128 }, /* SystemPowerPolicyDc */
+ { 4, 64 }, /* SystemPowerCapabilities */
+ { 5, 48 }, /* SystemBatteryState */
+ { 11, 48 }, /* ProcessorInformation */
+ { 12, 24 }, /* SystemPowerInformation */
+ { -1, -1 }
+ };
+ int i;
+
+ /* The 100 is a failsafe limit. */
+ for (i = 0; powerInfo[i].type != -1 && i < 100; i++ )
+ {
+ /* Query the info for this ID */
+ dwResult = pNtPowerInformation (powerInfo[i].type, NULL, 0, buffer,
+ PERFORMANCE_BUFFER_SIZE - 2048);
+ if (dwResult != ERROR_SUCCESS)
+ continue;
+ if (debug_me)
+ log_debug ("rndw32#slow_gatherer: %u bytes from powerinfo %d\n",
+ powerInfo[i].size, i);
+ (*add) (buffer, powerInfo[i].size, requester);
+ no_results++;
+ }
+ gcry_assert (i < 100);
+ }
+ xfree (buffer);
+
+ /* We couldn't get enough results from the kernel, fall back to the
+ somewhat troublesome registry poll. */
+ if (no_results < 15)
+ registry_poll (add, requester);
+}
+
+
+int
+_gcry_rndw32_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ static int is_initialized;
+ size_t n;
+
+ if (!level)
+ return 0;
+
+ /* We don't differentiate between level 1 and 2 here because there
+ is no internal entropy pool as a scary resource. It may all work
+ slower, but because our entropy source will never block but
+ deliver some not easy to measure entropy, we assume level 2. */
+
+ if (!is_initialized)
+ {
+ OSVERSIONINFO osvi = { sizeof( osvi ) };
+ const char *s;
+
+ if ((s = getenv ("GCRYPT_RNDW32_DBG")) && atoi (s) > 0)
+ debug_me = 1;
+
+ GetVersionEx( &osvi );
+ if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ log_fatal ("can only run on a Windows NT platform\n" );
+ system_is_w2000 = (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0);
+
+ init_system_rng ();
+ is_initialized = 1;
+ }
+
+ if (debug_me)
+ log_debug ("rndw32#gather_random: ori=%d len=%u lvl=%d\n",
+ origin, (unsigned int)length, level );
+
+ slow_gatherer (add, origin);
+
+ /* Round requested LENGTH up to full 32 bytes. */
+ n = _gcry_rndjent_poll (add, origin, ((length + 31) / 32) * 32);
+
+ if (debug_me)
+ log_debug ("rndw32#gather_random: jent contributed extra %u bytes\n",
+ (unsigned int)n);
+
+ return 0;
+}
+
+
+
+void
+_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin)
+{
+ static int addedFixedItems = 0;
+
+ if ( debug_me )
+ log_debug ("rndw32#gather_random_fast: ori=%d\n", origin );
+
+ /* Get various basic pieces of system information: Handle of active
+ window, handle of window with mouse capture, handle of clipboard
+ owner handle of start of clpboard viewer list, pseudohandle of
+ current process, current process ID, pseudohandle of current
+ thread, current thread ID, handle of desktop window, handle of
+ window with keyboard focus, whether system queue has any events,
+ cursor position for last message, 1 ms time for last message,
+ handle of window with clipboard open, handle of process heap,
+ handle of procs window station, types of events in input queue,
+ and milliseconds since Windows was started. On 64-bit platform
+ some of these return values are pointers and thus 64-bit wide.
+ We discard the upper 32-bit of those values. */
+
+ {
+ byte buffer[20*sizeof(unsigned long)], *bufptr;
+
+ bufptr = buffer;
+#define ADDINT(f) do { unsigned long along = (unsigned long)(f); \
+ memcpy (bufptr, &along, sizeof (along) ); \
+ bufptr += sizeof (along); \
+ } while (0)
+#define ADDPTR(f) do { void *aptr = (f); \
+ ADDINT((SIZE_T)aptr); \
+ } while (0)
+
+ ADDPTR ( GetActiveWindow ());
+ ADDPTR ( GetCapture ());
+ ADDPTR ( GetClipboardOwner ());
+ ADDPTR ( GetClipboardViewer ());
+ ADDPTR ( GetCurrentProcess ());
+ ADDINT ( GetCurrentProcessId ());
+ ADDPTR ( GetCurrentThread ());
+ ADDINT ( GetCurrentThreadId ());
+ ADDPTR ( GetDesktopWindow ());
+ ADDPTR ( GetFocus ());
+ ADDINT ( GetInputState ());
+ ADDINT ( GetMessagePos ());
+ ADDINT ( GetMessageTime ());
+ ADDPTR ( GetOpenClipboardWindow ());
+ ADDPTR ( GetProcessHeap ());
+ ADDPTR ( GetProcessWindowStation ());
+ /* Following function in some cases stops returning events, and cannot
+ be used as an entropy source. */
+ /*ADDINT ( GetQueueStatus (QS_ALLEVENTS));*/
+ ADDINT ( GetTickCount ());
+
+ gcry_assert ( bufptr-buffer < sizeof (buffer) );
+ (*add) ( buffer, bufptr-buffer, origin );
+#undef ADDINT
+#undef ADDPTR
+ }
+
+ /* Get multiword system information: Current caret position, current
+ mouse cursor position. */
+ {
+ POINT point;
+
+ GetCaretPos (&point);
+ (*add) ( &point, sizeof (point), origin );
+ GetCursorPos (&point);
+ (*add) ( &point, sizeof (point), origin );
+ }
+
+ /* Get percent of memory in use, bytes of physical memory, bytes of
+ free physical memory, bytes in paging file, free bytes in paging
+ file, user bytes of address space, and free user bytes. */
+ {
+ MEMORYSTATUS memoryStatus;
+
+ memoryStatus.dwLength = sizeof (MEMORYSTATUS);
+ GlobalMemoryStatus (&memoryStatus);
+ (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
+ }
+
+ /* Get thread and process creation time, exit time, time in kernel
+ mode, and time in user mode in 100ns intervals. */
+ {
+ HANDLE handle;
+ FILETIME creationTime, exitTime, kernelTime, userTime;
+ SIZE_T minimumWorkingSetSize, maximumWorkingSetSize;
+
+ handle = GetCurrentThread ();
+ GetThreadTimes (handle, &creationTime, &exitTime,
+ &kernelTime, &userTime);
+ (*add) ( &creationTime, sizeof (creationTime), origin );
+ (*add) ( &exitTime, sizeof (exitTime), origin );
+ (*add) ( &kernelTime, sizeof (kernelTime), origin );
+ (*add) ( &userTime, sizeof (userTime), origin );
+
+ handle = GetCurrentProcess ();
+ GetProcessTimes (handle, &creationTime, &exitTime,
+ &kernelTime, &userTime);
+ (*add) ( &creationTime, sizeof (creationTime), origin );
+ (*add) ( &exitTime, sizeof (exitTime), origin );
+ (*add) ( &kernelTime, sizeof (kernelTime), origin );
+ (*add) ( &userTime, sizeof (userTime), origin );
+
+ /* Get the minimum and maximum working set size for the current
+ process. */
+ GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
+ &maximumWorkingSetSize);
+ /* On 64-bit system, discard the high 32-bits. */
+ (*add) ( &minimumWorkingSetSize, sizeof (int), origin );
+ (*add) ( &maximumWorkingSetSize, sizeof (int), origin );
+ }
+
+
+ /* The following are fixed for the lifetime of the process so we only
+ * add them once */
+ if (!addedFixedItems)
+ {
+ STARTUPINFO startupInfo;
+
+ /* Get name of desktop, console window title, new window
+ position and size, window flags, and handles for stdin,
+ stdout, and stderr. */
+ startupInfo.cb = sizeof (STARTUPINFO);
+ GetStartupInfo (&startupInfo);
+ (*add) ( &startupInfo, sizeof (STARTUPINFO), origin );
+ addedFixedItems = 1;
+ }
+
+ /* The performance of QPC varies depending on the architecture it's
+ running on and on the OS, the MS documentation is vague about the
+ details because it varies so much. Under Win9x/ME it reads the
+ 1.193180 MHz PIC timer. Under NT/Win2K/XP it may or may not read the
+ 64-bit TSC depending on the HAL and assorted other circumstances,
+ generally on machines with a uniprocessor HAL
+ KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines
+ with a multiprocessor or APIC HAL it uses the TSC (the exact time
+ source is controlled by the HalpUse8254 flag in the kernel). That
+ choice of time sources is somewhat peculiar because on a
+ multiprocessor machine it's theoretically possible to get completely
+ different TSC readings depending on which CPU you're currently
+ running on, while for uniprocessor machines it's not a problem.
+ However, the kernel appears to synchronise the TSCs across CPUs at
+ boot time (it resets the TSC as part of its system init), so this
+ shouldn't really be a problem. Under WinCE it's completely platform-
+ dependent, if there's no hardware performance counter available, it
+ uses the 1ms system timer.
+
+ Another feature of the TSC (although it doesn't really affect us here)
+ is that mobile CPUs will turn off the TSC when they idle, Pentiums
+ will change the rate of the counter when they clock-throttle (to
+ match the current CPU speed), and hyperthreading Pentiums will turn
+ it off when both threads are idle (this more or less makes sense,
+ since the CPU will be in the halted state and not executing any
+ instructions to count).
+
+ To make things unambiguous, we detect a CPU new enough to call RDTSC
+ directly by checking for CPUID capabilities, and fall back to QPC if
+ this isn't present.
+
+ On AMD64, TSC is always available and intrinsic is provided for accessing
+ it. */
+#ifdef __x86_64__
+ {
+ unsigned __int64 aint64;
+
+ /* Note: cryptlib does not discard upper 32 bits of TSC on WIN64, but does
+ * on WIN32. Is this correct? */
+ aint64 = __rdtsc();
+ (*add) (&aint64, sizeof(aint64), origin);
+ }
+#else
+#ifdef __GNUC__
+/* FIXME: We would need to implement the CPU feature tests first. */
+/* if (cpu_has_feature_rdtsc) */
+/* { */
+/* uint32_t lo, hi; */
+ /* We cannot use "=A", since this would use %rax on x86_64. */
+/* __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */
+ /* Ignore high 32 bits, hwich are >1s res. */
+/* (*add) (&lo, 4, origin ); */
+/* } */
+/* else */
+#endif /*!__GNUC__*/
+ {
+ LARGE_INTEGER performanceCount;
+
+ if (QueryPerformanceCounter (&performanceCount))
+ {
+ if ( debug_me )
+ log_debug ("rndw32#gather_random_fast: perf data\n");
+ (*add) (&performanceCount, sizeof (performanceCount), origin);
+ }
+ else
+ {
+ /* Millisecond accuracy at best... */
+ DWORD aword = GetTickCount ();
+ (*add) (&aword, sizeof (aword), origin );
+ }
+ }
+#endif /*__x86_64__*/
+
+
+}
diff --git a/comm/third_party/libgcrypt/random/rndw32ce.c b/comm/third_party/libgcrypt/random/rndw32ce.c
new file mode 100644
index 0000000000..873e84606a
--- /dev/null
+++ b/comm/third_party/libgcrypt/random/rndw32ce.c
@@ -0,0 +1,199 @@
+/* rndw32ce.c - W32CE entropy gatherer
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <windows.h>
+#include <wincrypt.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "rand-internal.h"
+
+
+/* The Microsoft docs say that it is suggested to see the buffer with
+ some extra random. We do this, despite that it is a questionable
+ suggestion as the OS as better means of collecting entropy than an
+ application. */
+static size_t filler_used;
+static size_t filler_length;
+static unsigned char *filler_buffer;
+
+static void
+filler (const void *data, size_t datalen, enum random_origins dummy)
+{
+ (void)dummy;
+ if (filler_used + datalen > filler_length)
+ datalen = filler_length - filler_used;
+ memcpy (filler_buffer + filler_used, data, datalen);
+ filler_used += datalen;
+}
+
+
+static void
+fillup_buffer (unsigned char *buffer, size_t length)
+{
+ filler_used = 0;
+ filler_length = length;
+ filler_buffer = buffer;
+
+ while (filler_used < length)
+ _gcry_rndw32ce_gather_random_fast (filler, 0);
+}
+
+
+int
+_gcry_rndw32ce_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ HCRYPTPROV prov;
+ unsigned char buffer [256];
+ DWORD buflen;
+
+ if (!level)
+ return 0;
+
+ /* Note that LENGTH is not really important because the caller
+ checks the returned lengths and calls this function until it
+ feels that enough entropy has been gathered. */
+
+ buflen = sizeof buffer;
+ if (length+8 < buflen)
+ buflen = length+8; /* Return a bit more than requested. */
+
+ if (!CryptAcquireContext (&prov, NULL, NULL, PROV_RSA_FULL,
+ (CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) )
+ log_debug ("CryptAcquireContext failed: rc=%d\n", (int)GetLastError ());
+ else
+ {
+ fillup_buffer (buffer, buflen);
+ if (!CryptGenRandom (prov, buflen, buffer))
+ log_debug ("CryptGenRandom(%d) failed: rc=%d\n",
+ (int)buflen, (int)GetLastError ());
+ else
+ (*add) (buffer, buflen, origin);
+ CryptReleaseContext (prov, 0);
+ wipememory (buffer, sizeof buffer);
+ }
+
+ return 0;
+}
+
+
+
+void
+_gcry_rndw32ce_gather_random_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin)
+{
+
+ /* Add word sized values. */
+ {
+# define ADD(t,f) do { \
+ t along = (f); \
+ memcpy (bufptr, &along, sizeof (along)); \
+ bufptr += sizeof (along); \
+ } while (0)
+ unsigned char buffer[20*sizeof(unsigned long)], *bufptr;
+
+ bufptr = buffer;
+ ADD (HWND, GetActiveWindow ());
+ ADD (HWND, GetCapture ());
+ ADD (HWND, GetClipboardOwner ());
+ ADD (HANDLE, GetCurrentProcess ());
+ ADD (DWORD, GetCurrentProcessId ());
+ ADD (HANDLE, GetCurrentThread ());
+ ADD (DWORD, GetCurrentThreadId ());
+ ADD (HWND, GetDesktopWindow ());
+ ADD (HWND, GetFocus ());
+ ADD (DWORD, GetMessagePos ());
+ ADD (HWND, GetOpenClipboardWindow ());
+ ADD (HWND, GetProcessHeap ());
+ ADD (DWORD, GetQueueStatus (QS_ALLEVENTS));
+ ADD (DWORD, GetTickCount ());
+
+ gcry_assert ( bufptr-buffer < sizeof (buffer) );
+ (*add) ( buffer, bufptr-buffer, origin );
+# undef ADD
+ }
+
+ /* Get multiword system information: Current caret position, current
+ mouse cursor position. */
+ {
+ POINT point;
+
+ GetCaretPos (&point);
+ (*add) ( &point, sizeof (point), origin );
+ GetCursorPos (&point);
+ (*add) ( &point, sizeof (point), origin );
+ }
+
+ /* Get percent of memory in use, bytes of physical memory, bytes of
+ free physical memory, bytes in paging file, free bytes in paging
+ file, user bytes of address space, and free user bytes. */
+ {
+ MEMORYSTATUS memoryStatus;
+
+ memoryStatus.dwLength = sizeof (MEMORYSTATUS);
+ GlobalMemoryStatus (&memoryStatus);
+ (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
+ }
+
+
+ /* Get thread and process creation time, exit time, time in kernel
+ mode, and time in user mode in 100ns intervals. */
+ {
+ HANDLE handle;
+ FILETIME creationTime, exitTime, kernelTime, userTime;
+
+ handle = GetCurrentThread ();
+ GetThreadTimes (handle, &creationTime, &exitTime,
+ &kernelTime, &userTime);
+ (*add) ( &creationTime, sizeof (creationTime), origin );
+ (*add) ( &exitTime, sizeof (exitTime), origin );
+ (*add) ( &kernelTime, sizeof (kernelTime), origin );
+ (*add) ( &userTime, sizeof (userTime), origin );
+
+ handle = GetCurrentThread ();
+ GetThreadTimes (handle, &creationTime, &exitTime,
+ &kernelTime, &userTime);
+ (*add) ( &creationTime, sizeof (creationTime), origin );
+ (*add) ( &exitTime, sizeof (exitTime), origin );
+ (*add) ( &kernelTime, sizeof (kernelTime), origin );
+ (*add) ( &userTime, sizeof (userTime), origin );
+
+ }
+
+
+ /* In case the OEM provides a high precision timer get this. If
+ none is available the default implementation returns the
+ GetTickCount. */
+ {
+ LARGE_INTEGER performanceCount;
+
+ if (QueryPerformanceCounter (&performanceCount))
+ (*add) (&performanceCount, sizeof (performanceCount), origin);
+ }
+
+}
diff --git a/comm/third_party/libgcrypt/src/ChangeLog-2011 b/comm/third_party/libgcrypt/src/ChangeLog-2011
new file mode 100644
index 0000000000..3571fb1e4a
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/ChangeLog-2011
@@ -0,0 +1,2398 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-09-16 Werner Koch <wk@g10code.com>
+
+ Change ATH code and turn the thread initialization callbacks in
+ the API into dummy functions.
+
+ * global.c (global_init): Call _gcry_pimegen_init.
+
+ * gcrypt.h.in (GCRY_THREAD_OPTI ON_VERSION): Bump to 1.
+ (GCRY_THREAD_OPTION_PTH_IMPL): Simplify.
+ (GCRY_THREAD_OPTION_PTHREAD_IMPL): Simplify.
+
+ * ath.c (ath_read, ath_write): Remove. They are only used in the
+ optional random-daemon.
+ (ath_select, ath_waitpid, ath_accept, ath_connect, ath_sendmsg)
+ (ath_recvmsg): Remove. They are not used.
+ * ath.h: Remove prototypes and corresponding structure fields.
+
+2011-03-11 Werner Koch <wk@g10code.com>
+
+ * ath.c (mutex_init): Rename second arg to FORCE and invert
+ logic. Change all callers.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (enum gcry_thread_option): Remove deprecated enum.
+ (gcry_md_start_debug, gcry_md_stop_debug): Remove deprecated these
+ macros.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ Removal of the gcry_ac and the module register interfaces.
+
+ * Makefile.am (include_HEADERS): Remove gcrypt-module.h.
+ (libgcrypt_la_SOURCES): Add gcrypt-module.h which is now internal
+ header.
+ * gcrypt-module.h (gcry_md_register, gcry_md_unregister): Remove.
+ (gcry_pk_register, gcry_pk_unregister): Remove.
+ (gcry_cipher_register, gcry_cipher_unregister): Remove.
+ * visibility.h: Include gcrypt-module.h.
+ * gcrypt.h.in: Do not include gcrypt-module.h.
+ * gcrypt.h.in: Remove all gcry_ac symbols.
+ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+ * visibility.h: Remove all gcry_ac symbols.
+ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+ (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
+ (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
+ * visibility.c: Remove all gcry_ac wrappers.
+ (gcry_pk_list, gcry_cipher_list, gcry_md_list): Remove.
+ (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
+ (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
+ * libgcrypt.vers: Remove all gcry_ac symbols.
+ (GCRYPT_1.2): Rename to GCRYPT_1.6.
+ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+ * libgcrypt.def: Remove all gcry_ac symbols.
+ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+ * global.c (global_init): Remove comment code with a call to
+ _gcry_ac_init.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (main): Fix endless loop when using pipe input and
+ option --binary.
+
+2011-06-10 Werner Koch <wk@g10code.com>
+
+ * sexp.c (vsexp_sscan): Add new format specifiers 'M' and 'u'.
+
+2011-05-24 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h (pk_operation): New.
+ (pk_encoding_ctx): Add new fields: op, nbits, flags, verify_cmp,
+ and verify_arg.
+
+2011-05-19 Daiki Ueno <ueno@unixuser.org>
+
+ * Makefile.am (gcryptrnd_LDADD): Supply $(GPG_ERROR_LIBS) for
+ gpg_strerror.
+
+2011-05-18 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h: Remove PUBKEY_FLAG_UNPAD.
+
+2011-05-11 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h (PUBKEY_FLAG_UNPAD): New.
+ (enum pk_encoding): New.
+ (struct pk_encoding_ctx): New.
+
+2011-04-19 Werner Koch <wk@g10code.com>
+
+ * stdmem.c (_gcry_private_malloc_secure, _gcry_private_malloc):
+ Set ERRNO on failure.
+ * secmem.c (mb_get_new): Set ERRNO on failure.
+ (_gcry_secmem_malloc_internal): Ditto.
+
+2011-04-01 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_realloc): Divert to gcry_malloc or gcry_free.
+
+2011-03-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_kdf_algos): New.
+ (gcry_kdf_derive): New.
+ * visibility.c (gcry_kdf_derive): New.
+ * visibility.h, libgcrypt.vers, libgcrypt.def: Add gcry_kdf_derive.
+
+2011-02-23 Werner Koch <wk@g10code.com>
+
+ * libgcrypt-config.in: Add option --host.
+ * libgcrypt.m4: Use AC_PROG_TOOL to find the config script. Print
+ a warning is the config scripts does not match the configure host.
+
+2011-02-21 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_check_version): Do not take the patchlevel in
+ account; it is not well defined.
+
+2011-02-17 Werner Koch <wk@g10code.com>
+
+ * gcrypt-module.h (gcry_cipher_register, gcry_cipher_unregister)
+ (gcry_pk_register, gcry_pk_unregister, gcry_md_register)
+ (gcry_md_unregister): Mark as deprecated by the API; in a future
+ version the module register feature will be removed.
+
+ * gcrypt.h.in: Attribute all _ac_ functions and types as
+ deprecated by the API.
+
+ * hwfeatures.c (detect_ia32_gnuc): Fix AES-NI detection. Use AND
+ instead of SUB for bit testing.
+
+2011-02-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRYCTL_DISABLE_HWF): New.
+ * global.c (_gcry_vcontrol): Support new control code.
+ (print_config): Factor list of hwfeatures out to ...
+ (hwflist): new.
+ (disabled_hw_features): New.
+ (global_init): Pass new variable to _gcry_detect_hw_features.
+ * hwfeatures.c (_gcry_detect_hw_features): Add arg
+ DISABLED_FEATURES and disable detected features.
+
+2011-02-11 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (HWF_INTEL_AES): Rename to HWF_INTEL_AESNI.
+ * hwfeatures.c (detect_ia32_gnuc): Fix setting of this flag.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_pk_get_curve, gcry_pk_get_param): New.
+ * libgcrypt.vers (gcry_pk_get_curve, gcry_pk_get_param): Add.
+ * libgcrypt.def (gcry_pk_get_curve, gcry_pk_get_param): Add.
+ * visibility.c (gcry_pk_get_curve, gcry_pk_get_param): New.
+ * cipher-proto.h (pk_extra_spec): Add fields GET_CURVE and
+ GET_CURVE_PARM.
+
+2011-01-31 Werner Koch <wk@g10code.com>
+
+ * sexp.c (vsexp_sscan): Allow opaque MPIs in "%m".
+
+2010-08-27 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (HWF_INTEL_AES): New.
+ * global.c (print_config): Print new flag.
+ * hwfeatures.c (detect_ia32_gnuc): Detect this flag.
+
+2010-08-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [!WIN32]: Add INSERT_SYS_SELECT_H autoconf substitute.
+
+2010-07-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [!__GNUC__ && W32]: Typedef ssize_t and pid_t to
+ help building with MSVC.
+
+2010-06-24 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [W32]: Include time.h and not sys/time.h.
+
+2010-04-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * misc.c (write2stderr): Dummy variable to silence gcc warning.
+
+2010-04-16 Marcus Brinkmann <marcus@g10code.de>
+
+ * sexp.c: (sexp_sscan): Make it variable length, and rename the
+ old version to ...
+ (vsexp_sscan): ... this new function. Also swap last two arguments.
+ (gcry_sexp_create): Remove dummy va_list.
+ (gcry_sexp_build): Use vsexp_sscan instead of sexp_sscan.
+ (_gcry_sexp_vbuild): Likewise.
+ (gcry_sexp_build_array): Remove dummy va_list.
+ (gcry_sexp_sscan): Likewise.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in: Add autoconf template to set generated file to
+ read-only in an Emacs buffer.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (arch_gpg_error_cflags, arch_gpg_error_libs): New.
+ (dumpsexp_CFLAGS): New.
+ (dumpsexp_LDADD): Add arch_gpg_error_libs.
+ (hmac256_CFLAGS, hmac256_LDADD): Add the arch variables.
+ (libgcrypt_la_DEPENDENCIES): Add libcompat.
+ * secmem.c (lock_pool): Mark unused args.
+ * global.c (do_malloc, gcry_realloc, gcry_free, gcry_calloc)
+ (gcry_calloc_secure, gcry_xcalloc, gcry_xcalloc_secure): Use
+ gpg_err_set_errno.
+ (_gcry_vcontrol): Call _gcry_compat_identification.
+ * hmac256.c [__MINGW32CE__]: Include gpg-error.h.
+ (_gcry_hmac256_file): Use gpg_err_set_errno.
+ (gpg_err_set_errno) [!GPG_ERR_INLINE]: Add macro.
+ * g10lib.h: Include libcompat.h.
+
+2010-01-05 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_PK_ECDH): New.
+
+2009-12-08 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_CIPHER_MODE_AESWRAP): New.
+
+2009-12-08 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (LTRCCOMPILE): Refactor with ...
+ (RCCOMPILE): ... this new macro. Add $(libgcrypt_la_CPPFLAGS).
+ (SUFFIXES): Add .lo.
+ (.rc.o): Change to ...
+ (.rc.lo): ... this implicit rule.
+ (gcrypt_res_ldflag): Removed.
+ (gcrypt_res): Use libtool object file name here.
+ (libgcrypt_la_LDFLAGS): Remove gcrypt_res_ldflag usage.
+ (libgcrypt_la_LIBADD): Add gcrypt_res.
+
+2009-11-29 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Repalce "=r" by "+r" so that
+ HAS-CPUDID is always initialized. Thanks to Ben Hutchings for
+ pointing out this problem.
+
+2009-08-05 Werner Koch <wk@g10code.com>
+
+ * ath.h: Include sys/msg.h.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Do not use FIPS mode if
+ /proc/.../fips_enabled has insufficient permissions.
+
+ * dumpsexp.c (main): Fix handling multiple files.
+ (parse_and_print): Implement hex and octal escaping.
+
+ * sexp.c (unquote_string): Remove superfluous clearing of ESC.
+ * dumpsexp.c (parse_and_print): Add missing break.
+ (main): Fix return value.
+ Reported by Fabian Keil.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * ath.h [HAVE_SYS_SELECT_H]: Include <sys/select.h> for fd_set.
+ [!HAVE_SYS_SELECT_H]: Include <sys/time.h>. Move inclusion of
+ config.h to the top. The actual configure check was already
+ there.
+
+ * sexp.c: Remove memory.h.
+ * mpi.h: Remove memory.h. Add string.h.
+
+2009-02-02 Werner Koch <wk@g10code.com>
+
+ * ath.h: Include sys/time.h. Fixes bug#993.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Remove superfluous const
+ from static string. Reported by Albert Chin.
+ * hmac256.c (selftest): Ditto and change to unsigned char.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (finalize): Fix for big endian hosts.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_free): Save and restore ERRNO if set.
+
+2008-11-24 Werner Koch <wk@g10code.com>
+
+ * sexp.c (get_internal_buffer): New.
+ (sexp_sscan): Add format character S.
+ * cipher-proto.h (pk_ext_generate_t): Add field EXTRAINFO changed
+ all implementors.
+
+ * cipher-proto.h (pk_ext_generate_t): Simplify.
+ (pk_get_param): New.
+ (pk_extra_spec_t): Add field GET_PARAM.
+ * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): Remove.
+ (_gcry_pubkey_extraspec_elg): New.
+
+2008-11-05 Werner Koch <wk@g10code.com>
+
+ * cipher.h (CIPHER_INFO_NO_WEAK_KEY): New.
+
+ * cipher-proto.h (cipher_set_extra_info_t): New.
+ (cipher_extra_spec): Add field SET_EXTRA_INFO.
+
+2008-10-30 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (GCC_ATTR_FORMAT_ARG): New.
+ (_gcry_gettext): Use it.
+
+2008-10-24 Werner Koch <wk@g10code.com>
+
+ * global.c (inactive_fips_mode): Move to fips.c.
+ (gcry_set_allocation_handler): Factor code out to ...
+ * fips.c (_gcry_inactivate_fips_mode): New.
+ (_gcry_is_fips_mode_inactive): New.
+
+2008-09-29 Werner Koch <wk@g10code.com>
+
+ * gcrypt-module.h (GCRY_MODULE_ID_USER, GCRY_MODULE_ID_USER_LAST):
+ New.
+ * module.c (MODULE_ID_USER, MODULE_ID_USER_LAST): Define using new
+ macros.
+
+2008-09-20 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (finalize) [WORDS_BIGENDIAN]: Fix sigbus problem.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * cipher-proto.h (pk_ext_generate_t): Add args QBITS, NAME, DOMAIN.
+
+ * fips.c (fips_new_state): Allow Error => Error transition.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_fips_mode_active): New.
+
+ * secmem.c (_gcry_secmem_init): Factor most code out to ..
+ (secmem_init): .. new.
+ (DEFAULT_POOL_SIZE): Rename to MINIMUM_POOL_SIZE.
+ (STANDARD_POOL_SIZE): New.
+ (_gcry_secmem_malloc_internal): Don't abort if the pool is not
+ initialized but try to out intialize it first and only then print
+ an error message and return NULL. If the pool is not locked while
+ in FIPS mode, return NULL.
+
+ * fips.c (FIPS_FORCE_FILE): New constant. Change the file name to
+ "/etc/gcrypt/fips_enabled".
+ (enforced_fips_mode): New.
+ (_gcry_initialize_fips_mode): Set that flag.
+ (_gcry_enforced_fips_mode): New.
+ * global.c (inactive_fips_mode): New.
+ (_gcry_vcontrol): Take that flag in account for GCRYCTL_FIPS_MODE_P.
+ (gcry_set_allocation_handler): Take care of the enforced fips mdoe
+ flag.
+ (get_no_secure_memory): New.
+ (do_malloc, gcry_is_secure): Use it.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * global.c (print_config): Use y/n for fips mode.
+
+ * fips.c (fips_new_state): Allow transition to Error and
+ Fatal-error from Init.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * fips.c [HAVE_SYSLOG]: Include syslog.h.
+ (_gcry_initialize_fips_mode, lock_fsm, unlock_fsm)
+ (_gcry_fips_signal_error, fips_new_state)
+ (_gcry_fips_noreturn) [HAVE_SYSLOG]: Also log via syslog.
+ (check_binary_integrity) [HAVE_SYSLOG]: Log failure.
+ * global.h [HAVE_SYSLOG]: Include syslog.h.
+ (_gcry_global_is_operational) [HAVE_SYSLOG]: Print warning.
+
+ * global.c (_gcry_vcontrol): Use GCRYCTL_INITIALIZATION_FINISHED
+ to run power-up tests. Add unpublished control commands 58-60.
+
+ * global.c (_gcry_global_is_operational): New.
+ * g10lib.h (fips_is_operational): Change to call this function.
+
+2008-09-12 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_fips_run_selftests): Add arg EXTENDED.
+ (run_cipher_selftests, run_digest_selftests, run_hmac_selftests)
+ (run_pubkey_selftests): Ditto.
+ * cipher-proto.h (selftest_func_t): Add arg EXTENDED
+
+2008-09-11 Werner Koch <wk@g10code.com>
+
+ * fips.c: Include string.h.
+ (loxtoi_1, loxtoi_2, loxdigit_p): New.
+ (check_binary_integrity): Change the format of the expected file.
+
+ * fips.c (_gcry_fips_run_selftests): Run random tests before the
+ pubkey tests.
+
+2008-09-05 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCYRCTL_SELFTEST): New.
+ * global.c (_gcry_vcontrol): Implement.
+ * fips.c (_gcry_fips_run_selftests): Do state transitions only if
+ in fips mode. Return an error code.
+
+2008-09-01 Werner Koch <wk@g10code.com>
+
+ * stdmem.c: Re-indented.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Changed /proc file to test
+ for FIPS mode.
+
+ * cipher-proto.h (pk_compute_keygrip_t): New.
+ (pk_extra_spec): Add field comp_keygrip.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (_gcry_detect_hw_features): Disable hardware
+ detection in FIPS mode.
+
+2008-08-27 Werner Koch <wk@g10code.com>
+
+ * global.c (_gcry_vcontrol): Allow running selftests from error
+ state.
+ (gcry_set_outofcore_handler): Only print a warning if used in FIPS
+ mode.
+ (gcry_xmalloc, gcry_xrealloc, gcry_xmalloc_secure, gcry_xstrdup):
+ Ignore an outofcore handler in FIPS mode.
+
+ * fips.c (_gcry_fips_test_error_or_operational): New.
+ (fips_new_state): Allow transition from error into selftest.
+ Disallow error to init.
+
+2008-08-26 Werner Koch <wk@g10code.com>
+
+ * fips.c (fips_new_state): Print state transitions only at
+ verbosity level of 2.
+ (reporter): Likewise.
+
+ * cipher-proto.h (pk_ext_generate_t): New.
+ (pk_extra_spec): Add member ext_generate.
+ * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): New.
+
+2008-08-22 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (_gcry_hmac256_file): New.
+ (main): New option --binary.
+ * fips.c (check_binary_integrity): New.
+ (_gcry_fips_run_selftests): Run it.
+
+ * global.c (_gcry_vcontrol) <GCRYCTL_UPDATE_RANDOM_SEED_FILE>:
+ Check for fips operational state.
+ (_gcry_vcontrol) <GCRYCTL_FAST_POLL>: Ditt.
+
+2008-08-21 Werner Koch <wk@g10code.com>
+
+ * misc.c (_gcry_log_printhex): New.
+
+2008-08-20 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (gcry_assert): New. use this at almost all places
+ where we used a plain assert.
+ * misc.c (_gcry_assert_failed): New.
+ (_gcry_bug): Also use func variant for ISO-C99.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * visibility.c, visibility.h (gcry_mpi_lshift): New.
+ * libgcrypt.vers, libgcrypt.def, gcrypt.h.in: Ditto.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_cipher_setkey): Replace macro by function.
+ (gcry_cipher_setiv): Ditto.
+ (gcry_cipher_setctr): Ditto.
+ * visibility.c (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * visibility.h (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * libgcrypt.vers (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * libgcrypt.def (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+
+ * hmac256.h, hmac256.c: New.
+ * Makefile.am (hmac256_SOURCES): New.
+ * Makefile.am (bin_PROGRAMS): Add hmac256.
+
+ * gcrypt.h.in (struct gcry_thread_cbs): Change type of OPTION to
+ unsigned int. Although this is a type change it does not make a
+ difference.
+ * ath.c (ath_install): Take the version of the option field in
+ account.
+
+ * visibility.c (gcry_pk_encrypt, gcry_pk_decrypt, gcry_pk_sign)
+ (gcry_pk_verify, gcry_pk_testkey, gcry_pk_genkey)
+ (gcry_pk_get_nbits, gcry_pk_get_keygrip)
+ (gcry_md_open, gcry_md_copy, gcry_md_enable)
+ (gcry_md_write, md_final, gcry_md_ctl, gcry_md_setkey)
+ (gcry_md_hash_buffer, gcry_md_get_algo, gcry_md_info)
+ (gcry_md_is_enabled)
+ (gcry_cipher_open, gcry_cipher_encrypt)
+ (gcry_cipher_decrypt, gcry_cipher_ctl)
+ (gcry_cipher_algo_info): Check whether the library is operational.
+
+ * cipher-proto.h: New.
+ * cipher.h: Include cipher-proto.h.
+ * visibility.h: Remove duplicate macro definitions. Remove
+ gcry_cipher_register, gcry_md_register, gcry_pk_register macros.
+ * visibility.c: Include cipher-proto.h.
+ (gcry_cipher_register): Pass dummy extra args to the internal
+ register function.
+ (gcry_md_register, gcry_pk_register): Ditto.
+ * g10lib.h (struct gcry_module): Add field EXTRASPEC.
+ * module.c (_gcry_module_add): Add arg EXTRASPEC. Changed all
+ callers to pass NULL.
+
+ * fips.c: New.
+ * gcrypt.h.in (GCRYCTL_FIPS_MODE_P): New.
+ * global.c (global_init): Call fips initialization.
+ (_gcry_vcontrol): Add GCRYCTL_FIPS_MODE_P code.
+ (print_config): Add config item fips-mode.
+ (gcry_set_allocation_handler): Do not allow the use of custom
+ allocation handlers.
+ (gcry_set_outofcore_handler): Ditto.
+ (_gcry_get_debug_flag): Do not return any debug flags in fips mode.
+ * misc.c (_gcry_logv): Signal fips error on BUG or FATAL.
+ (_gcry_fatal_error): Ditto.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Include librandom.la.
+
+2008-04-18 Werner Koch <wk@g10code.com>
+
+ * missing-string.c (vasprintf): Remove. It is not used. Reported
+ by Simon Josefsson.
+
+2008-03-11 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_ac_em_t, gcry_ac_scheme_t): Remove trailing
+ comma for full C-89 compatibility.
+
+2008-01-21 Marcus Brinkmann <marcus@g10code.de>
+
+ * hwfeatures.c (detect_ia32_gnuc): Fix inline asm.
+
+2007-12-11 Werner Koch <wk@g10code.com>
+
+ * visibility.c (gcry_md_hash_buffer): Don't use return vor a void
+ function. Hey, why does gcc not complain about this?
+ (gcry_ac_io_init_va): Ditto.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Depend on ENABLE_PADLOCK_SUPPORT.
+
+2007-12-03 Werner Koch <wk@g10code.com>
+
+ * misc.c (_gcry_logv): Use abort for error levels fatal and bug as
+ this is more approriate for a library. Terminate the secmem
+ before doing so.
+ (_gcry_fatal_error): Terminate secmem before abort.
+ * secmem.c (_gcry_secmem_malloc_internal): Use log_bug instead of
+ exit.
+
+2007-11-29 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Detect Padlock engine.
+
+2007-11-13 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (_GCRY_GCC_ATTR_MALLOC): Fixed gcc version check.
+ Reported by Gabriele Monti.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_control): Factor most code out to ..
+ (_gcry_vcontrol): .. new.
+ * sexp.c (_gcry_sexp_vbuild): New.
+ * mpi.h (_gcry_mpi_set, _gcry_mpi_set_ui, _gcry_mpi_invm): Remove
+ prototypes as they are already in gcrypt.h.
+
+2007-10-30 Werner Koch <wk@g10code.com>
+
+ * sexp.c (gcry_sexp_nth_string): Replace by _gcry_sexp_nth_string.
+
+ * visibility.h, visibility.c: New.
+ * g10lib.h: Include visibility.h instead of gcrypt.h.
+ * globals.c (_gcry_malloc): Rename to ..
+ (do_malloc): .. this.
+
+ * hwfeatures.c: New.
+ * global.c (global_init): Detect features.
+ (print_config): Print them.
+
+2007-08-22 Werner Koch <wk@g10code.com>
+
+ * dumpsexp.c: New.
+ * Makefile.am (bin_PROGRAMS): Install it.
+
+ * getrandom.c (print_version): Use new standard license line.
+ * gcryptrnd.c (print_version): Ditto.
+
+2007-06-06 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTH_IMPL): Factror network
+ related code out so that the prototypes can be adjusted for W32.
+ (_GCRY_THREAD_OPTION_PTH_IMPL_NET): New.
+
+2007-05-09 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.m4: Print found version on success.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in (gcry_ac_io_t): Add name for anonymous union, and mark
+ all members as internal (actually: deprecated).
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (.rc.lo): New to replace gmake specific suffix rule.
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.def (gcry_sexp_nth_string): New.
+ * Makefile.am (EXTRA_DIST): Add libgcrypt.def.
+
+2007-05-02 Werner Koch <wk@g10code.com>
+
+ * global.c (print_config): Print ciphers, digests and pubkeys.
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * cipher.h, gcrypt.h.in: Add Camellia.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRYCTL_PRINT_CONFIG): New.
+ (GCRYCTL_SET_RNDEGD_SOCKET): New.
+ * global.c (gcry_control): Add GCRYCTL_PRINT_CONFIG and
+ GCRYCTL_SET_RNDEGD_SOCKET.
+ (print_config): New.
+ * misc.c (_gcry_log_info_with_dummy_fp): New.
+
+2007-04-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_sexp_nth_string): New.
+
+ * sexp.c (gcry_sexp_nth_data): Factored code out to ...
+ (sexp_nth_data): ... new.
+ (gcry_sexp_nth_string): New.
+ (gcry_sexp_nth_mpi): Reimplemented in terms of sexp_ntd_data.
+
+2007-04-16 Werner Koch <wk@g10code.com>
+
+ * secmem.c (init_pool): Use sysconf() if available to determine
+ page size.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * mpi.h (mpi_mod): New.
+ (mpi_new, mpi_snew): New.
+
+ * gcrypt.h.in: Add GCRY_PK_ECDSA.
+
+2007-03-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Fixed typo
+ introduced by me on 2006-10-23.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_ac_id_to_name, gcry_ac_name_to_id): Mark as
+ deprecated.
+
+ * libgcrypt.def (gcry_fast_random_poll): Removed - it is a macro.
+ (gcry_cipher_register, gcry_cipher_unregister): New.
+ (gcry_md_register, gcry_md_unregister): New.
+ (gcry_pk_register, gcry_pk_unregister): New.
+ (gcry_ac_data_from_sexp, gcry_ac_data_to_sexp): New.
+ (gcry_ac_io_init, gcry_ac_io_init_va): New.
+ (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme): New.
+ (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): New.
+
+ * missing-string.c: Include stdio.h for the vsprintf prototype.
+
+ * ath.h (struct ath_ops) [_WIN32]: Use int instead of socklen_t.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.def (gcry_create_nonce, gcry_fast_random_poll)
+ (gcry_md_debug): New.
+
+ * libgcrypt-config.in: Remove duplicates from --cflags and --libs.
+ Print a error for option --thread.
+
+ * gcrypt.h.in (gcry_sexp_sprint): Change BUFFER from char* to void*.
+ (gcry_md_ctl): Change BUFFER from unsigned char* to void*.
+ (gcry_md_debug): New.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Change buffer args to
+ void*.
+ (gcry_randomize): Change BUFFER to void.
+ (gcry_create_nonce): Ditto.
+
+ * libgcrypt.vers (gcry_md_debug): New.
+
+ * sexp.c (gcry_sexp_sprint): Ditto.
+ (normalize): Make P unsigned.
+ (gcry_sexp_nth_data): Cast return value to char*.
+ (sexp_sscan): Fix sign/unsigned conflicts.
+ (whitespacep): Change P to char*.
+ (unquote_string): Change STRING to char*.
+ (convert_to_hex): Change DEST to char*.
+ (convert_to_string): Change DEST and P to char*.
+ (convert_to_token): Chnage DEST to char*.
+ (gcry_sexp_canon_len): Change DISPHINT to unsigned char*.
+
+ * gcrypt-module.h (gcry_pk_spec): Made ALIASES a const.
+ (gcry_md_write_t): Changed BUF to a const void*.
+
+2007-02-12 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in: Include stdlib.h for the sake fo the trheading
+ macros. Suggested by Andreas Metzler.
+
+ * secmem.c (ptr_into_pool_p): New.
+ (_gcry_private_is_secure): Implement in terms of new function.
+ (BLOCK_VALID): Removed. Replaced all users by new function.
+
+2007-01-31 Werner Koch <wk@g10code.com>
+
+ * secmem.c (_gcry_private_is_secure): Fixed severe implementation
+ flaw. Might be the reason for some of the more obscure bugs.
+ (MB_WIPE_OUT): Use wipememory2.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Add some cast for
+ use by C-doubleplus. In general I don't like this but due to
+ public demand I give up ;-)
+
+2006-10-19 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_control) <GCRYCTL_INIT_SECMEM>: Return an error
+ if the memory could not be locked.
+ * secmem.c (not_locked): New.
+ (_gcry_secmem_get_flags): Return that flag.
+ * secmem.h (GCRY_SECMEM_FLAG_NOT_LOCKED): New.
+
+2006-10-05 Werner Koch <wk@g10code.com>
+
+ * module.c (_gcry_module_id_new): Don't assign modules in the range
+ the range of 1024..4096.
+ * gcrypt.h (GCRY_MD_USER, GCRY_MD_USER_LAST): New
+ (GCRY_PK_USER, GCRY_PK_USER_LAST): New.
+ (GCRY_CIPHER_USER, GCRY_CIPHER_USER_LAST): New.
+
+2006-10-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in: Replace socklen_t with gcry_socklen_t.
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in: Replace version by @VERSION@.
+
+2006-10-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h: Add fallback type for socklen_t. Move to ...
+ * gcrypt.h.in: ... this file.
+ * Makefile.am (EXTRA_DIST): Add gcrypt.h.in.
+
+2006-09-04 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Removed some trailing comma in enums.
+
+2006-08-29 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_xrealloc): Pass secure flag to outofcore handler.
+
+ * gcrypt.h (GCRY_CIPHER_SEED): New.
+
+2006-08-21 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRYCTL_FAKED_RANDOM_P): New.
+
+2006-07-29 Marcus Brinkmann <marcus@g10code.de>
+
+ * secmem.c (init_pool): Close FD after establishing the mapping.
+
+2006-07-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * ath.c (ath_mutex_destroy): Microoptimize destruction of unused
+ statitically initialized mutexes. Suggested by Victor Stinner
+ <victor.stinner@inl.fr>.
+
+ * gcrypt.h (GCRY_THREAD_OPTION_PTHREAD_IMPL,
+ (GCRY_THREAD_OPTION_PTH_IMPL): Add missing initializers to
+ suppress gcc warning.
+ Submitted by Victor Stinner <victor.stinner@inl.fr>.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * ath.c: Avoid warning about double defined type byte and other
+ hacks to let it build for W32 (backported from LIBGCRYPT-1-2-BRANCH).
+ * ath.h, gcrypt.h, tests/benchmark.c, src/types.h: Likewise.
+
+ * gcrypt.h: Revert last change, and instead:
+ [_WIN32 || __WIN32__]: Do not include <sys/socket.h>, but
+ <winsock2.h> and <ws2tcpip.h>.
+ Suggested by Simon Josefsson <jas@extundo.com>.
+
+ * Makefile.am (install-data-local, uninstall-local, %.lo,
+ (install-def-file, uninstall-def-file): New targets.
+ (LTRCCOMPILE, gcrypt_res, gcrypt_res_ldflag, no_undefined,
+ (export_symbols, gcrypt_deps): New variables.
+ * versioninfo.rc.in: New file.
+ * libgcrypt.def: New file from ../w32-dll/libgcrypt.def.
+
+ * gcrypt.h [!HAVE_SYS_SOCKET_H]: Do not include sys/socket.h, but
+ the appropriate windows socket header.
+
+2006-06-21 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_xcalloc, gcry_xcalloc_secure): Made safe against
+ integer overflow.
+
+ * sexp.c (make_space): Return an error on out of core.
+ (sexp_sscan): Remove all xmalloc style calls and return proper
+ error codes on allocation failures.
+ (gcry_sexp_find_token): Ditto.
+ (gcry_sexp_nth):
+
+ * sexp.c (gcry_sexp_find_token): Re-indented and removed a cruft
+ "while(level);" which fortunately had no effect.
+
+2006-04-28 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRY_MD_SHA224): Change value from 306 to 11 to match
+ the use in OpenPGP. There has been no release yet, so we can
+ safely do it.
+
+2006-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_ctl_cmds): New commands:
+ GCRYCTL_SET_RANDOM_DAEMON_SOCKET, GCRYCTL_USE_RANDOM_DAEMON.
+ * global.c (gcry_control): Handle new commands, calling
+ _gcry_set_random_daemon_socket() and _gcry_use_random_daemon().
+
+2006-04-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRY_PK_USAGE_CERT, GCRY_PK_USAGE_AUTH)
+ (GCRY_PK_USAGE_UNKN): New.
+
+2006-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_ac_eme_pkcs_v1_5): Removed members: key, handle;
+ added member: key_size.
+
+ * secmem.c (MB_FLAG_ACTIVE): Write braces around MB_FLAG_ACTIVE
+ definition.
+
+2006-03-15 Werner Koch <wk@g10code.com>
+
+ * getrandom.c: New.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * gcryptrnd.c: New.
+
+2006-03-10 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Add GCRY_MD_SHA224.
+
+2005-11-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Update comments for functions: gcry_cipher_algo_name,
+ gcry_pk_algo_name.
+
+2005-10-31 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Added documentation.
+
+2005-10-16 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (global_init): Use gcry_error_t instead of
+ gcry_err_code_t; use goto instead of if constructs.
+
+ * stdmem.c: Inserted description of the layered memory management
+ in Libgcrypt.
+
+ * g10lib.h: Removed G10_I18N_H related check; it seems to be a
+ GnuPG relict (Libgcrypt does not define this symbol anywhere).
+ (FLAG_MODULE_DISABLED): Don't forget parantheses around shifted
+ value.
+
+ Removed GCC_ATTR_PURE macro definitions, since gcrypt.h does
+ already contain such a macro named _GCRY_GCC_ATTR_PURE, which we
+ can use here as well.
+
+ Likewise for GCC_ATTR_MALLOC and _GCRY_GCC_ATTR_MALLOC.
+
+ * stdmem.h: Use _GCRY_GCC_ATTR_MALLOC instead of GCC_ATTR_MALLOC.
+ * secmem.h: Likewise.
+
+2005-10-09 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_control): Call global_init() after passing thread
+ cbs to ath. global_init() MUST to be called AFTER passing the cbs
+ to ath and BEFORE calling library functions, which make use of
+ ath. This change combines cbs installing with ath initialization
+ and thus removes the need to call other library initialization
+ functions inbetween like e.g. gcry_check_version().
+
+2005-10-01 Moritz Schulte <moritz@g10code.com>
+
+ * ath.c: Assign copyright to FSF.
+ * ath.h: Likewise.
+
+2005-06-25 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (pkgconfigdir, pkgconfig_DATA): Removed variables.
+ * libgcrypt.pc.in: Removed file - we do not want to support a
+ second, foreign configuration system.
+
+2005-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_xstrdup): Removed superfluous strcpy call.
+
+2005-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (pkgconfigdir, pkgconfig_DATA): New; support for
+ pkgconfig provided by Albert Chin.
+ * libgcrypt.pc.in (Cflags): New file.
+
+2005-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h (_gcry_ac_init): Declare.
+ * global.c (global_init): Call _gcry_ac_init; don't forget to set
+ err.
+
+2005-04-14 Werner Koch <wk@g10code.com>
+
+ * sexp.c (whitespacep): New.
+ (sexp_sscan): Replaced isdigit and isspace by whitespacep and
+ digitp.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_md_algos): Added: GCRY_MD_WHIRLPOOL.
+ * cipher.h (_gcry_digest_spec_whirlpool): Declare.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * libgcrypt.vers: Added: gcry_ac_io_init, gry_ac_io_init_va.
+
+ * gcrypt.h (gcry_ac_data_read_cb_t, gcry_ac_data_write_cb_t,
+ gcry_ac_io_mode_t, gcry_ac_io_type_t, gcry_ac_io_t): New types.
+ (gcry_ac_io_init_va): Declare function.
+ (gcry_ac_data_encode, gcry_ac_data_decode,
+ gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme,
+ gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): Use
+ gcry_ac_io_type_t objects instead of memory strings directly.
+
+2005-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * libgcrypt.vers: Added: gcry_ac_data_to_sexp() and
+ gcry_ac_data_from_sexp().
+
+2005-02-22 Werner Koch <wk@g10code.com>
+
+ * global.c (_gcry_malloc): Make sure ERRNO is set if we return
+ NULL. Remove unneeded initialization of M to allow the compiler
+ to catch errors.
+ (gcry_realloc): Make sure ERRNO is set if we return NULL>
+
+2005-02-13 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declare new functions: gcry_ac_data_encrypt_scheme,
+ gcry_ac_data_decrypt_scheme, gcry_ac_data_sign_scheme,
+ gcry_ac_data_verify_scheme, gcry_ac_data_encode,
+ gcry_ac_data_decode, gcry_ac_data_to_sexp, gcry_ac_data_from_sexp.
+ New types: gcry_ac_emsa_pkcs_v1_5_t, gcry_ac_ssa_pkcs_v1_5_t,
+ gcry_md_algo_t.
+ New enumeration lists: gcry_ac_scheme_t, gcry_ac_em_t.
+ * libgcrypt.vers: Added new ac functions.
+ * g10lib.h: Declare function: _gcry_pk_get_elements.
+ * mpi.h (mpi_get_ui): New macro.
+ Declare function: _gcry_mpi_get_ui.
+
+2004-11-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Removed 3 trailing commas from enums. Noted by Heiko
+ Stamer.
+
+2004-09-21 Werner Koch <wk@g10code.de>
+
+ * sexp.c (sexp_sscan): Removed C++ style comments. Noted by Yoann
+ Vandoorselaere.
+
+2004-08-23 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Do not include <assert.h>.
+ * sexp.c: Likewise.
+ * module.c: Likewise.
+ * misc.c: Likewise.
+
+2004-08-18 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (_gcry_secmem_init): Try to lock pool into core not
+ only when running with root privileges.
+
+2004-08-16 Werner Koch <wk@g10code.de>
+
+ * secmem.h (_gcry_secmem_set_flags,_gcry_secmem_get_flags):
+ Removed __pure__.
+ (GCRY_SECMEM_FLAG_NO_WARNING): Put macro value into parens.
+
+ * secmem.c (_gcry_secmem_init): Defer printing of the warning.
+
+2004-08-10 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Include <sys/time.h>, thanks to Simon Josefsson.
+
+2004-05-07 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRYCTL_FAST_POLL.
+ (gcry_fast_random_poll): New.
+ * global.c (gcry_control) <INITIALIZATION_FINISHED>: Do only basic
+ random subsystem init.
+ (gcry_control) <FAST_POLL>: New.
+
+2004-04-22 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt.m4: Quote first argument to AC_DEFUN.
+
+2004-04-15 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_malloc_internal): Removed old extra info
+ error output.
+ (_gcry_secmem_term): Use wipememory2 here.
+
+ * misc.c (_gcry_burn_stack): Use wipememory to avoid optimizations.
+
+ * string.c: Removed. Was never used.
+ * global.c (gcry_strdup): Replaced by the version from string.c
+ (gcry_xstrdup): Rewritten.
+ * gcrypt.h: Removed duplicate prototype for gcry_strdup.
+
+2004-03-29 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_realloc): Fixed double unlock; bug
+ manifested itself due to the more rigorous checking in the changed
+ ath.h
+
+ * libgcrypt-config.in (Options): Ignore the obsolete --threads
+ option for now.
+
+2004-03-17 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt-config.in (includedir, libdir): Quote'em. Use
+ $gpg_error_cflags and $gpg_error_libs. Fix construction of
+ $includes.
+
+2004-03-14 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt-config.in (includedir, libdir): New variables. For
+ --cflags, don't test $cflags. Also check against /include for the
+ GNU/Hurd. Don't overwrite but extend $cflags_final. Likewise for
+ --libs.
+
+2004-03-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (ltlib_libgcrypt_pthread, ltlib_libgcrypt_pth): Removed.
+ (lib_LTLIBRARIES): Remove those variables from here.
+ (libgcrypt_pthread_la_SOURCES, libgcrypt_pthread_la_LDFLAGS,
+ (libgcrypt_pthread_la_DEPENDENCIES, libgcrypt_pthread_la_LIBADD,
+ (libgcrypt_pth_la_SOURCES, libgcrypt_pth_la_LDFLAGS,
+ (libgcrypt_pth_la_DEPENDENCIES, libgcrypt_pth_la_LIBADD,
+ (noinst_LTLIBRARIES): Removed.
+ (libgcrypt_real_la_SOURCES): Merge with ...
+ (libgcrypt_la_SOURCES): ... likewise.
+ (libgcrypt_real_la_DEPENDENCIES): Merge with ...
+ (libgcrypt_la_DEPENDENCIES): ... this.
+ (libgcrypt_real_la_LIBADD): Merge with ...
+ (libgcrypt_la_LIBADD): ... this.
+ * libgcrypt-config.in (libs_pthread, libs_pth, cflags_pth)
+ (cflags_pthread, thread_module, thread_modules): Removed.
+ (Options): Remove --thread option from help output. If the option
+ is specified, output an error and exit.
+ For --cflags and --libs option, remove pth and pthread from output.
+ * gcrypt.h: Include <sys/types.h> and <sys/socket.h>.
+ (enum gcry_ctl_cmds): Add GCRYCTL_SET_THREAD_CBS.
+ (gcry_thread_cbs): New struct.
+ * global.c (gcry_control): Implement GCRYCTL_SET_THREAD_CBS.
+ (global_init): Don't call ath_init here.
+ * ath.h: Rewritten.
+ * ath.c: Rewritten.
+
+2004-03-06 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: s/--soname-number/--api-version/
+ * libgcrypt.m4: Changed test for API version.
+
+2004-03-05 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.m4: Optionally check the SONAME number.
+
+ * libgcrypt-config.in: Add option --soname-number
+
+2004-03-01 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Add ath.c.
+ * ath.c (ath_init): Add missing function.
+
+ * Makefile.am (ath_pth_src): Removed.
+ (ath_pthread_src): Removed.
+ (libgcrypt_la_SOURCES): Remove ath-compat, $(ath_pth_src) and
+ $(ath_pthread_src).
+ * ath-compat.c, ath-pth-compat.c, ath-pthread-compat.c: Files
+ removed.
+
+2004-02-20 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_PRIME_CHECK_AT_GOT_PRIME)
+ (GCRY_PRIME_CHECK_AT_FINISH),
+ (GCRY_PRIME_CHECK_AT_MAYBE_PRIME): New.
+
+2004-02-18 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: Ignore setting of --prefix.
+
+2004-02-13 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRY_CIPHER_RFC2268_128, alsthough not yet
+ supported.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRY_CIPHER_RFC2268_40.
+
+2004-02-03 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_init): Do not print the "not locked into
+ core warning" if the NO_WARNING flag has been set.
+
+ * sexp.c (sexp_sscan): Allocate result in secure memory if BUFFER
+ is in secure memory. Switch to secure memory for the a secure %b
+ format item. Extra paranoid wipe on error.
+ (gcry_sexp_release): Added paranoid wiping for securely allocated
+ S-expressions.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * ath.h: Include <config.h>.
+
+2004-01-12 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h: Adjusted declarations of: gcry_ac_data_set,
+ gcry_ac_data_get_name, gcry_ac_data_get_index,
+ gcry_ac_key_pair_generate, gcry_ac_key_test,
+ gcry_ac_key_get_nbits, gcry_ac_key_get_grip.
+
+ * gcrypt.h (GCRY_AC_FLAG_DATA_NO_BLINDING): Removed symbol.
+ (GCRY_AC_FLAG_DEALLOC, GCRY_AC_FLAG_COPY)
+ (GCRY_AC_FLAG_NO_BLINDING): New symbols.
+
+ * global.c (gcry_strdup): Removed function.
+ * string.c: New file.
+ * Makefile.am (libgcrypt_real_la_SOURCES): Added: string.c.
+ * string.c (gcry_strdup): New function.
+ * gcrypt.h (gcry_strdup): Declare.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * g10lib.h (wipememory, wipememory2): New; taken from gnupg.
+
+2003-11-14 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strdup): Don't copy the string after a malloc
+ error.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Implemented "%b" format specifier.
+
+2003-11-11 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt.m4: Do not set prefix when calling libgcrypt-config.
+ Thanks to Nikos Mavroyanopoulos.
+
+2003-11-08 Moritz Schulte <mo@g10code.com>
+
+ * cipher.h (small_prime_numbers): Removed declaration.
+ (PUBKEY_FLAG_NO_BLINDING): Put braces around shift.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * cipher.h (_gcry_sha1_has_buffer): New.
+
+ * gcrypt.h (gcry_create_nonce): New.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.vers (_gcry_generate_elg_prime): Removed this symbol;
+ gnutls does not need it anymore.
+
+ * secmem.c (mb_get_new): s/pool/block/ due to global pool.
+
+ * misc.c (gcry_set_log_handler): s/logf/f/ to avoid shadowing
+ warning against a builtin.
+
+ * ath-pth-compat.c: cast pth_connect to get rid of the const
+ prototype.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * ath.h (ATH_MUTEX_INITIALIZER): Removed spurious semicolon.
+
+2003-10-27 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt-config.in: Include libs/cflags of libgpg-error.
+
+ * sexp.c (sexp_sscan): Cleaned up, deallocate scanned sexp on
+ error.
+
+ * module.c (MODULE_ID_MIN): New symbol, use it.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_pk_testkey): Doc fix.
+
+2003-09-29 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt-config.in: Fix --algorithms option.
+
+2003-10-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_err_code): Use GPG_ERR_INLINE instead of
+ __inline__.
+
+ * secmem.c (lock_pool): Don't print the warning for certain
+ systems, handle ENOMEM.
+
+2003-10-21 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_dump_stats): Fixed format sepcifier for a
+ size_t. Reported by Stephane Corthesy.
+
+2003-10-10 Werner Koch <wk@gnupg.org>
+
+ * global.c (_gcry_malloc): Handle the no_secure_memory option.
+
+ * gcrypt.h (gcry_prime_group_generator): New.
+ (gcry_prime_release_factors): New.
+
+2003-10-07 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Check that parenthesis are matching.
+
+2003-09-28 Moritz Schulte <mo@g10code.com>
+
+ * g10lib.h: Declare: _gcry_malloc.
+ (GCRY_ALLOC_FLAG_SECURE): New symbol.
+
+ * global.c (_gcry_malloc): New function...
+ (gcry_malloc): ... use it.
+ (gcry_malloc_secure): Likewise.
+
+ * ath.c: Change License to LGPL.
+ * ath-pthread-compat.c: Likewise.
+ * ath-pthread.c: Likewise.
+ * ath-pth-compat.c: Likewise.
+ * ath-pth.c: Likewise.
+ * ath.h: Likewise.
+ * ath-compat.c: Likewise.
+
+ * secmem.c (_gcry_secmem_realloc): Do not forget to release secmem
+ lock. Thanks to low halo for triggering this bug.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (_GCRY_ERR_SOURCE_DEFAULT): Removed cruft.
+ (gcry_prime_check_func_t): Renamed arg for clarity.
+
+2003-09-02 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h (GCRY_PRIME_FLAG_SPECIAL_FACTOR): New symbol.
+
+2003-09-01 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h (gcry_random_level_t): New type.
+ (gcry_prime_check_func_t): Likewise.
+ (GCRY_PRIME_FLAG_SECRET): New symbol.
+ (gcry_prime_generate, gcry_prime_check): Declare functions.
+
+2003-08-28 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (libgcrypt_pth_la_LDFLAGS): Removed PTH_CFLAGS cruft.
+
+2003-08-27 Moritz Schulte <mo@g10code.com>
+
+ * global.c (gcry_control): Remove call to ath_deinit.
+
+ * Makefile.am (libgcrypt_real_la_DEPENDENCIES): Fixed.
+ (libgcrypt_real_la_LIBADD): Fixed.
+ Removed unecessary variables.
+
+ * libgcrypt-config.in: Adjusted script for new thread handling.
+
+ * Makefile.am: New version, based on GPGMEs Makefile.am.
+
+ * ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c,
+ ath-pthread.c, ath-pthread-compat.c: New files, merged from GPGME.
+ * ath.c, ath.h, ath-pthread.c, ath-pth.c: Removed files.
+
+2003-08-08 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_realloc): Remove FIXME about `clearing out
+ realloced memory', since _gcry_secmem_realloc takes care of
+ overwriting old memory.
+
+2003-08-07 Werner Koch <wk@gnupg.org>
+
+ * module.c (_gcry_module_release): Don't act if module is NULL.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_ac_id): Added: GCRY_AC_ELG_E.
+ Reverted change: use gcry_md_flags enumeration list instead of
+ defines.
+
+2003-07-29 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_control): Add GCRYCTL_SET_RANDOM_SEED_FILE and
+ GCRYCTL_UPDATE_RANDOM_SEED_FILE.
+ * gcrypt.h: Ditto. Renamed index to idx, so avoid warning
+ related to the old index function.
+
+2003-07-28 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_err_code_from_errno, gcry_err_code_to_errno)
+ (gcry_err_make_from_errno, gcry_error_from_errno): New functions.
+
+ * gcrypt.h: Declared: gcry_err_code_from_errno,
+ gcry_err_code_to_errno, gcry_err_make_from_errno,
+ gcry_error_from_errno.
+
+ * Makefile.am (include_HEADERS): Added: gcrypt-module.h.
+
+ * gcrypt.h: Include <gcrypt-module.h>.
+
+ * gcrypt-module.h: New file.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_mpi_scan, gcry_mpi_print): API change.
+ (gcry_mpi_dump): New.
+
+2003-07-21 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declared: gcry_ac_key_data_get.
+ (gcry_pk_spec): Renamed member `sexp_names' into `aliases'.
+
+2003-07-20 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_md_oid_spec_t): New type.
+ (gcry_md_spec): New member: oids.
+
+2003-07-19 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_oid_spec_t): New type.
+ (gcry_cipher_spec): New member: oids;
+
+2003-07-18 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_mpi_set_opaque): Add a warning comment.
+
+2003-07-15 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (compress_pool): Remove function, since unused blocks
+ are automatically concatenad.
+
+ * gcrypt.h: Bumped version number up to 1.1.42-cvs.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_spec): New member: aliases.
+
+ * Makefile.am (noinst_PROGRAMS, testapi_SOURCES, testapai_LDADD,
+ benchmark_SOURCES, benchmark_LDADD): Removed.
+
+ * benchmark.c, testapi.c: Removed files.
+
+ * mpi.h: Removed disabled typedef.
+ * g10lib.h: Likewise.
+
+ * benchmark.c, g10lib.h, gcrypt.h, global.c, module.c, sexp.c:
+ Used gcry_err* wrappers for libgpg-error symbols.
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Likewise.
+
+ * gcrypt.h: New type: gcry_error_t, gcry_err_code_t and
+ gcry_err_source_t.
+ (gcry_err_make, gcry_error, gcry_err_code, gcry_err_source): New
+ functions.
+
+ * global.c (gcry_strerror): New function.
+ (gcry_strsource): New function.
+
+ * gcrypt.h: New symbol: GCRY_CIPHER_TWOFISH128.
+
+2003-07-09 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_md_flags): Removed, used define instead,
+ since that is more common than an enumeration list when it comes
+ to flags that can be bitwise ORed.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Use new types for handlers.
+
+ * gcrypt.h: Declare: gcry_ac_data_copy.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (gcry_sexp_build_array): Use dummy argument pointer.
+ Thanks to Simon Josefsson <jas@extunde.com>.
+
+ * gcrypt.h: Declare: gcry_cipher_list, gcry_pk_list, gcry_md_list.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declare: gcry_cipher_register, gcry_cipher_unregister,
+ gcry_md_register, gcry_md_unregister, gcry_pk_register,
+ gcry_pk_unregister.
+ (gcry_cipher_spec): Removed member: algorithm.
+ (gcry_pk_spec): Likewise.
+ (gcry_md_spec): Likewise.
+ Adjusted declarations: gcry_cipher_register, gcry_pk_register,
+ gcry_md_register.
+
+ * module.c: Replaced all occurences of `id' with `mod_id', since
+ `id' is a keyword in obj-c.
+
+ * gcrypt.h (gcry_cipher_spec): Renamed member `id' to `algorithm'.
+ (gcry_pk_spec): Likewise.
+ (gcry_md_spec): Likewise.
+
+ * cipher.h: Removed types: gcry_pubkey_generate_t,
+ gcry_pubkey_check_secret_key_t, gcry_pubkey_encrypt_t,
+ gcry_pubkey_decrypt_t, gcry_pubkey_sign_t, gcry_pubkey_verify_t,
+ gcry_pubkey_get_nbits_t, gcry_pk_spec_t, gcry_digest_init_t,
+ gcry_digest_write_t, gcry_digest_final_t, gcry_digest_read_t,
+ gcry_digest_spec_t, gcry_cipher_setkey_t, gcry_cipher_encrypt_t,
+ gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t,
+ gcry_cipher_stdecrypt_t, gcry_cipher_spec_t.
+
+ * gcrypt.h: New types: gcry_pk_generate_t,
+ gcry_pk_check_secret_key_t, gcry_pk_encrypt_t, gcry_pk_decrypt_t,
+ gcry_pk_sign_t, gcry_pk_verify_t, gcry_pk_get_nbits_t,
+ gcry_pk_spec_t, gcry_md_init_t, gcry_md_write_t, gcry_md_final_t,
+ gcry_md_read_t, gcry_md_spec_t, gcry_cipher_setkey_t,
+ gcry_cipher_encrypt_t, gcry_cipher_decrypt_t,
+ gcry_cipher_stencrypt_t, gcry_cipher_stdecrypt_t,
+ gcry_cipher_spec_t, gcry_module_t.
+
+2003-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_list): New function.
+
+2003-07-02 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_lookup): Fixed typo.
+
+ * gcrypt.h: Added all definitions and declarations necessary for
+ the new ac interface.
+
+2003-06-30 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h: Added declarations: _gcry_pk_module_lookup,
+ _gcry_pk_module_release.
+
+2003-06-18 Werner Koch <wk@gnupg.org>
+
+ * benchmark.c (cipher_bench): Adjusted for new API of get_blklen
+ and get_keylen.
+
+ * gcrypt.h (gcry_cipher_get_algo_blklen)
+ (gcry_cipher_get_algo_keylen): Replaced macro by funcion.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h: Renamed types GcryDigestSpec, GcryCipherSpec and
+ GcryPubkeySpec into: gcry_digest_spec_t, gcry_cipher_spec_t and
+ gcry_pubkey_spec_t.
+ (gcry_pubkey_spec): Defined member `id' as unsigned.
+ (gcry_digest_spec): Likewise.
+ (gcry_cipher_spec): Likewise.
+
+ * module.c (_gcry_module_id_new): New function.
+ (_gcry_module_add): Generate a new ID via _gcry_module_id_new in
+ case `id' is zero.
+
+ * g10lib.h, module.c: Replace old type GcryModule with newer one:
+ gcry_module_t.
+
+ * module.c (_gcry_module_add): Added argument `id', use it.
+
+ * g10lib.h: Added declaration: _gcry_module_lookup_id.
+ (_gcry_module_add): Added argument `id'.
+
+ * module.c (_gcry_module_lookup_id): New function.
+
+ * g10lib.h (struct gcry_module): New member: id.
+
+ * gcrypt.h: New type: gcry_handler_progress_t,
+ gcry_handler_alloc_t, gcry_haandler_secure_check_t,
+ gcry_handler_realloc_t, gcry_handler_free_t,
+ gcry_handler_no_mem_t, gcry_handler_error_t, gcry_handler_log_t.
+ Use new types.
+
+ * cipher.h: Include <gcrypt.h>.
+ New types: gcry_pk_generate_t, gcry_pk_check_secret_key_t,
+ gcry_pk_encrypt_t, gcry_pk_decrypt_t, gcry_pk_sign_t,
+ gcry_pk_verify_t, gcry_pk_get_nbits_t, gcry_md_init_t,
+ gcry_md_write_t, gcry_md_final_t, gcry_md_read_t,
+ gcry_cipher_setkey_t, gcry_cipher_encrypt_t,
+ gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t,
+ gcry_cipher_stdecrypt_t.
+ Use new types.
+
+2003-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * mpi.h: Likewise.
+ * sexp.c: Likewise.
+
+2003-06-15 Moritz Schulte <moritz@g10code.com>
+
+ * testapi.c (test_genkey): Use gpg_strerror instead of
+ gcry_strerror.
+
+ * global.c (gcry_control): Fixed typo.
+
+ * misc.c (_gcry_fatal_error): Use gpg_strerror instead of
+ gcry_strerror.
+
+ * types.h (STRLIST): Removed type since it is not used.
+
+2003-06-11 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (global_init): Call: _gcry_cipher_init, _gcry_md_init,
+ _gcry_pk_init.
+
+ * g10lib.h: Declare: _gcry_cipher_init, _gcry_md_init,
+ _gcry_pk_init.
+
+ * global.c (gcry_strerror): Remove compatibility code.
+
+ * Makefile.am: Remove support libgpg-error special handling.
+ (AM_CPPFLAGS): Add @GPG_ERROR_CFLAGS@
+
+ * gcrypt.h: Likewise.
+
+2003-06-13 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_md_get_algo): Reverted to old API. This is a
+ convenience function anyway and error checking is not approriate.
+ (gcry_md_is_enabled): New.
+ (gcry_md_is_secure): Replaced macro by function and reverted to old
+ API.
+
+2003-06-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYERR): Define _GCRY_ERR_SOURCE_DEFAULT instead of
+ GPG_ERR_SOURCE_DEFAULT, so that libgpg-error still works despite
+ the use of the old gcrypt error codes.
+ (gcry_md_copy): Swapped arguments.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Support for libgpg-error.
+
+2003-06-08 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (gcry_sexp_create): Expect sane error values from
+ gcry_sexp_canon_len instead of the `historical' values.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * ath.c, ath.c, ath-pth.c, ath-pthread.c, benchmark.c, cipher.h,
+ g10lib.h, gcrypt.h, global.c, misc.c, missing-string.c, module.c,
+ mpi.h, secmem.c, secmem.h, sexp.c, stdmem.c, stdmem.h, testapi.c,
+ types.h: Edited all preprocessor instructions to remove whitespace
+ before the '#'. This is not required by C89, but there are some
+ compilers out there that don't like it. Replaced any occurence of
+ the now deprecated type names with the new ones.
+
+ * gcrypt.h: Re-organized checking for gcc features; New macro:
+ _GCRY_GCC_ATTR_DEPRECATED.
+ Include copy of libgpg-error's gpg-error.h in order to make it
+ easy to build libgcrypt without needing libgpg-error.h.
+
+ (GCRY_MPI, GcryMPI, GCRY_SEXP, GcrySexp, GCRY_CIPHER_HD,
+ GcryCipherHd, GCRY_MD_HD, GcryMDHd): Declared deprecated.
+ (gcry_mpi_t, gcry_sexp_t, gcry_cipher_hd_t, gcry_md_hd_t): New
+ types.
+
+2003-06-04 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (sexp_sscan): New argument: arg_list, adjusted all
+ callers.
+ (ARG_NEXT): New macro.
+ (sexp_sscan): Use ARG_NEXT for receiving format string arguments.
+ (gcry_sexp_build_array): New function.
+
+2003-06-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Added some comments describing the gcry_sexp_*
+ functions.
+ Include <gpg-error.h> instead of <gpg/error.h>.
+
+2003-06-01 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (OLDPARSECODE): Removed macro...
+ (gcry_sexp_canon_len): ... and do not use it.
+
+ * gcrypt.h (gcry_errno): Removed declaration.
+
+ * g10lib.h (string_to_pubkey_algo, pubkey_algo_to_string,
+ pubkey_nbits): Removed declarations for non-existing functions.
+
+2003-05-31 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (is_RSA, is_ELGAMAL): Removed macros.
+
+ * g10lib.h (set_lasterr): Removed macro.
+ (_gcry_set_lasterr): Removed declaration.
+
+ * gcrypt.h: Changed declarations for: gcry_pk_algo_info,
+ gcry_md_open, gcry_md_copy, gcry_md_algo_info, gcry_md_info,
+ gcry_md_get_algo, gcry_random_add_bytes.
+
+ (gcry_md_is_secure): Adjust macro for new API.
+
+2003-05-29 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Changed declarations for: gcry_cipher_open,
+ gcry_cipher_info, gcry_cipher_algo_info.
+ (gcry_cipher_get_algo_keylen): Adjuster for new
+ gcry_cipher_algo_info interface.
+ (gcry_cipher_get_algo_blklen): Likewise.
+
+ * global.c (gcry_errno): Removed function.
+ (gcry_strerror): Do not use gcry_errno.
+ (_gcry_set_lasterr): Removed function.
+ (last_ec): Removed variable.
+
+2003-05-27 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_cipher_algos): Make Serpent IDs do not
+ conflict with OpenPGP. Reported by Timo Schulz.
+
+ * global.c (gcry_control): Fixed name of enum list.
+
+2003-05-25 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_cipher_spec): Adjust return type of `setkey' for
+ libgpg-error.
+ (gcry_pubkey_spec): Adjust return type of `generate',
+ `check_secret_key', `encrypt', `decrypt', `sign' and `verify' for
+ libgpg-error.
+
+ * sexp.c (gcry_sexp_canon_len): Adjusted for libgpg-error.
+ (gcry_sexp_create): Likewise.
+ (gcry_sexp_new): Likewise.
+ (sexp_sscan): Likewise.
+ (gcry_sexp_build): Likewise.
+ (gcry_sexp_sscan): Likewise.
+
+ * module.c (_gcry_module_add): Likewise.
+
+ * global.c (last_ec): Change type to gpg_error_t.
+ (gcry_control): Adjust for libgpg-error.
+ (gcry_errno): Likewise.
+ (gcry_strerror): Likewise.
+ (_gcry_set_lasterr): Likewise.
+ (gcry_xmalloc): Likewise.
+ (gcry_xrealloc): Likewise.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * types.h: Merged code from GnuPG regarding U64_C.
+
+ * missing-string.c (strsep): Removed function.
+
+ * g10lib.h: Removed declarations: strsep, strlwr.
+
+ * secmem.c (secmem_lock): New variable.
+ (SECMEM_LOCK, SECMEM_UNLOCK): New macros.
+ (_gcry_secmem_set_flags): Use SECMEM_LOCK and SECMEM_UNLOCK.
+ (_gcry_secmem_get_flags): Likewise.
+ (_gcry_secmem_init): Likewie.
+ (_gcry_secmem_malloc): Likewise.
+ (_gcry_secmem_free): Likewise.
+ (_gcry_secmem_malloc): Renamed to ...
+ (_gcry_secmem_malloc_internal): ... this.
+ (_gcry_secmem_malloc): New function, use SECMEM_LOCK,
+ SECMEM_UNLOCK, call _gcry_secmem_malloc_internal.
+ (_gcry_secmem_free): Renamed to ...
+ (_gcry_secmem_free_internal): ... this.
+ (_gcry_secmem_free): New function, use SECMEM_LOCK, SECMEM_UNLOCK,
+ call _gcry_secmem_free_internal.
+ (_gcry_secmem_realloc): Use SECMEM_LOCK, SECMEM_UNLOCK, call
+ _gcry_secmem_malloc_internal and _gcry_secmem_free_internal.
+ (_gcry_private_is_secure): Use SECMEM_LOCK, SECMEM_UNLOCK.
+ (_gcry_secmem_dump_stats): Likewise.
+ (_gcry_secmem_malloc_internal): Removed unused variable:
+ compressed.
+ Include "ath.h".
+
+2003-05-21 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (GCRY_CIPHER_SERPENT128, GCRY_CIPHER_SERPENT192,
+ GCRY_CIPHER_SERPENT256): New symbols.
+
+2003-05-19 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Reversed changes from 2003-03-03 since they would have
+ been an unnecessary ABI break.
+
+2003-05-13 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (stats_update): New function.
+ (BLOCK_HEAD_SIZE): New symbol.
+ (MB_FLAG_ACTIVE): New symbol.
+ (ADDR_TO_BLOCK, BLOCK_VALID): New macros.
+ (mb_get_next): New function.
+ (mb_get_prev): New function.
+ (mb_merge): New function.
+ (mb_get_new): New function.
+ (unused_blocks): Removed variable.
+ (init_pool): Initialize new memory pool.
+ (_gcry_secmem_malloc): Use new heap management code.
+ (_gcry_secmem_free): Likewise.
+ (_gcry_secmem_realloc): Likewise.
+ Renamed type MEMBLOCK to memblock_t.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_pubkey_spec): New member: sexp_names.
+
+2003-04-23 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_pubkey_spec): Removed members: npkey, nskey,
+ nenc, nsig.
+ (gcry_pubkey_spec): Added members: elements_pkey, elements_skey,
+ elements_enc, elements_sig, elements_grip.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h (GcryModule): New typedef.
+
+ * gcrypt.h (gcry_cipher_register, gcry_cipher_unregister,
+ gcry_digest_register, gcry_digest_unregister,
+ gcry_pubkey_register, gcry_pubkey_unregister): Function
+ declarations removed - for now.
+
+ * gcrypt.h (GcryModule): Declaration removed.
+ * gcrypt.h (GcryPubkeySpec, GcryDigestSpec, GcryCipherSpec):
+ Types Moved...
+ * cipher.h: ... here.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h: Declare digest_spec_sha512 and digest_spec_384.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_use): New function.
+ * g10lib.h (_gcry_module_use): Declare function.
+
+ * libgcrypt-config.in: Support for --algorithms switch, which
+ prints the algorithms included in the built libgcrypt.
+
+ * global.c (gcry_set_progress_handler): Register progress
+ functions depending on the enabled algorithms.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Added module.c
+
+ * module.c: New file.
+ (_gcry_module_add): New function.
+ (_gcry_module_drop): New function.
+ (_gcry_module_lookup): New function.
+ (_gcry_module_release): New function.
+
+ * g10lib.h (GcryModule): New types.
+ (FLAG_MODULE_DISABLED): New symbol.
+ Added declarations for _gcry_module_add, _gcry_module_release and
+ _gcry_module_lookup.
+
+ * gcrypt.h: New types: GcryPubkeySpec, GcryDigestSpec,
+ GcryCipherSpec.
+ Added declarations for: gcry_cipher_register,
+ gcry_cipher_unregister, gcry_digest_register,
+ gcry_digest_unregister, gcry_pubkey_register and
+ gcry_pubkey_unregister.
+
+ * cipher.h: Removed symbols: CIPHER_ALGO_NONE, CIPHER_ALGO_IDEA,
+ CIPHER_ALGO_3DES, CIPHER_ALGO_CAST5, CIPHER_ALGO_BLOWFISH,
+ CIPHER_ALGO_SAFER_SK128, CIPHER_ALGO_DES_SK, CIPHER_ALGO_TWOFISH,
+ CIPHER_ALGO_TWOFISH_OLD, CIPHER_ALGO_DUMMY, PUBKEY_USAGE_SIG,
+ PUBKEY_USAGE_ENC, DIGEST_ALGO_MD5, DIGEST_ALGO_SHA1,
+ DIGEST_ALGO_RMD160, DIGEST_ALGO_TIGER, PUBKEY_ALGO_RSA,
+ PUBKEY_ALGO_RSA_E, PUBKEY_ALGO_RSA_S, PUBKEY_ALGO_DSA,
+ PUBKEY_ALGO_ELGAMAL, PUBKEY_ALGO_ELGAMAL_E.
+
+2003-04-02 Moritz Schulte <moritz@g10code.com>
+
+ * benchmark.c (md_bench): Fix error message.
+
+2003-03-31 Moritz Schulte <moritz@g10code.com>
+
+ * benchmark.c (cipher_bench): Added CTR mode.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (enum gcry_control_cmds): Add GCRY_SET_CTR.
+ (enum gcry_cipher_modes): Add GCRY_CIPHER_MODE_CTR.
+ (gcry_cipher_setctr): New macro to set counter.
+
+2003-03-19 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (PUBKEY_FLAG_NO_BLINDING): New symbol.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h: Add GCRYCTL_SET_CBC_MAC and GCRY_CIPHER_CBC_MAC.
+
+2003-03-19 Werner Koch <wk@gnupg.org>
+
+ * g10lib.h: Adjusted primegen.c prototypes.
+
+2003-03-12 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Initialize NM. Thanks to Ian Peters for
+ valgrinding this.
+
+2003-03-06 Moritz Schulte <mo@g10code.com>
+
+ * secmem.h (GCRY_SECMEM_FLAG_NO_WARNING,
+ GCRY_SECMEM_FLAG_SUSPEND_WARNING): New symbols.
+
+ * global.c (gcry_control): Use
+ GCRY_SECMEM_FLAG_{NO,SUSPEND}_WARNING, instead of hard-coded
+ values.
+ * secmem.c (_gcry_secmem_set_flags): Likewise.
+ * secmem.c (_gcry_secmem_get_flags): Likewise.
+
+2003-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * misc.c: Removed old FIXME, since there is already a function to
+ set the value of `verbosity_level'.
+
+ * gcrypt.h: Removed enumeration list: gcry_ctl_cmds.
+ New enumeration lists: gcry_global_control_cmds,
+ gcry_control_cmds, gcry_info_cmds, gcry_algo_info_cmds.
+
+2003-03-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_reset): New macro for resetting a handle.
+
+2003-02-28 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (DEFAULT_PAGESIZE): New symbol.
+ (init_pool): Use DEFAULT_PAGESIZE.
+
+2003-02-23 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.h: Fix typo in declaration of _gcry_secmem_term.
+
+ * sexp.c: Move macro definitions of `digitp', `octdigit', `alphap'
+ and `hexdigit' ...
+ * g10lib.h: ... here.
+
+ * misc.c (_gcry_burn_stack): New function (former name:
+ burn_stack).
+
+ * g10lib.h (burn_stack): Declare _gcry_burn_stack().
+
+2003-01-24 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_set_progress_handler): Register a random progress
+ handler.
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_ENABLE_QUICK_RANDOM): New.
+ * global.c (gcry_control): Make use of it.
+
+2003-01-21 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_random_add_bytes): Add QUALITY argument.
+
+2003-01-21 Timo Schulz <twoaday@freakmail.de>
+
+ * gcrypt.h (gcry_random_add_bytes): New.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (gcry_md_algos): Add GCRY_MD_CRC32,
+ GCRY_MD_CRC32_RFC1510, GCRY_MD_CRC24_RFC2440.
+
+2003-01-16 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_md_write): Changed type of 2nd argument to void*.
+ (gcry_md_hash_buffer): Changed type of both buffers to void*.
+ (gcry_md_setkey): Changed type of 2nd argument to void*.
+ (gcry_md_get_asnoid): New.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_length): Fixed. This was seriously broken.
+
+2003-01-14 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYERR_INV_FLAG), global.c (gcry_strerror): New.
+
+2003-01-02 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.vers: Temporary export _gcry_generate_elg_prime for
+ use by GNUTLS.
+
+2002-12-21 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Make use of gcc's pure and malloc attributes
+ (gcry_md_putc): Use a helper variable to avoid multiple
+ evaluation of H.
+ * g10lib.h, stdmem.h, secmem.h: Use gcc attributes pure and malloc.
+
+ * stdmem.c (use_m_guard): Don't default to yes.
+
+2002-12-19 Werner Koch <wk@gnupg.org>
+
+ * global.c (global_init): The meat was never run due to a faulty
+ check. Thanks to Nikos for pointing this out.
+
+ * global.c (gcry_control): Return 1 and not -1 for the
+ initialization tests.
+
+ * libgcrypt.vers: New.
+ * Makefile.am: Use this instead of the build symbol file.
+
+ * global.c (gcry_control) <initialization>: Call the random module
+ initializer to make sure that the pool lock flag has been
+ initialized.
+
+2002-12-09 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_calloc,gcry_calloc_secure): Check for overflow.
+ Noted by Florian Weimer.
+
+2002-11-10 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (gcry_ctl_cmds): New GCRYCTL_SET_CBC_CTS control flag.
+ (gcry_cipher_flags): New GCRY_CIPHER_CBC_CTS gcry_cipher_open() flag.
+ (gcry_cipher_cts): New macro for toggling CTS.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_MD_MD4): New. We use a non OpenPGP value here.
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ * ath.c: Include sys.time.h if sys/select.h does not exist.
+ (ath_select, ath_waitpid): Shortcut for Windows.
+ * ath.h: Include some Windows headers. By Timo.
+
+2002-09-18 Werner Koch <wk@gnupg.org>
+
+ * ath.h: Prefix ath_deinit.
+
+2002-09-17 Werner Koch <wk@gnupg.org>
+
+ * benchmark.c: New.
+ (mpi_bench, do_powm): Add a a simple test for RSA.
+
+ * global.c (global_init): New. Use it instead of the setting
+ any_init_done. Initialize the ATH system.
+ (gcry_check_version): Hook global_init in. This is the suggested
+ way to initialize the library.
+ (_gcry_no_internal_locking): Removed. We simply call a ath_deinit
+ and leave it to ATH to disbale the locking.
+
+ * ath.c, ath.h, ath-pth.c, ath-pthread.c: New. Taken from GPGME.
+ * mutex.h: Removed.
+ * Makefile.am (ath_components): New.
+
+2002-09-16 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_dump_stats): Replaced fprintf by log_*.
+
+2002-08-23 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: Removed unneeded strlwr.
+
+ * libgcrypt.m4: Made much more simple.
+ * libgcrypt-config.in: Made --prefix work for --libs.
+
+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Add GCRY_CIPGER_DES. Included string.h for size_t.
+ Suggested by Simon Josefsson.
+
+2002-07-25 Werner Koch <wk@gnupg.org>
+
+ * cipher.h: Added prototypes for progress functions.
+ * global.c: Include cipher.h for those prototypes.
+
+ * stdmem.c (_gcry_private_realloc): Replaced void* by char * for
+ pointer arithmetic reasons. Noted by Stephan Austermuehle.
+
+2002-06-24 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: Include ctype.h.
+
+ * gcrypt.h (gcry_mpi_invm, gcry_mpi_div, gcry_mpi_mod)
+ (gcry_mpi_swap): New.
+
+2002-06-18 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added a bunch of brief function descriptions.
+
+2002-05-21 Werner Koch <wk@gnupg.org>
+
+ * misc.c (_gcry_log_printf): Don't initialize a va_list. Noted by
+ Jeff Johnson.
+
+ * global.c (gcry_set_progress_handler): New.
+
+ * gcrypt.h: Replaced the typedef for byte.
+
+2002-05-16 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: New.
+
+ * gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs
+ GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old
+ ones using an underscore.
+
+ * global.c (gcry_strerror): Add strings fro the new error codes.
+ * sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to
+ old error codes.
+ (gcry_sexp_create,gcry_sexp_new): New.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * mutex.h (DEFINE_LOCAL_MUTEX): Macro to define a mutex and
+ initialize it so that we can detect an unitialized mutex and don't
+ read from stdin.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of all files to the LGPL.
+
+2002-05-07 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_control): Add commands
+ GCRYCTL_ANY_INITIALIZATION_P and GCRYCTL_INITIALIZATION_FINISHED_P
+ so that other libraries are able to check for required
+ initializations.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYCTL_DISABLE_INTERNAL_LOCKING): New.
+ * global.c (gcry_control): Implement it.
+ (_gcry_no_internal_locking): New.
+ * mutex.h: Prefixed all fucntions with _gcry_. Bypass all
+ functions when desired.
+
+ * gcrypt.h (GCRYCTL_DISABLE_SECMEM): New.
+ * global.c (gcry_control,gcry_malloc_secure,gcry_is_secure):
+ Implement it here.
+ * secmem.c (_gcry_private_is_secure): Return false if the pool is
+ not initialized.
+
+ * gcrypt.h (GCRYCTL_INITIALIZATION_FINISHED): New.
+
+ * gcrypt.h (gcry_cipher_algos): Replaced RINDAEL by AES and change
+ the macros to expand from rijdael to aes.
+
+ * stdmem.c (_gcry_private_malloc): Return NULL for 0 byte allocation.
+ (_gcry_private_malloc_secure): Ditto.
+
+ * g10lib.h: Copied the JNLIB_GCC macros from ../jnlib/mischelp.h
+ and removed the inclusion of that file.
+
+2002-04-15 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strdup): New.
+
+2002-03-18 Werner Koch <wk@gnupg.org>
+
+ * mutex.h: New file with a portable thread mutex implementation
+ written by Marcus Brinkmann. Taken from GPGME.
+
+2002-02-18 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_sscan): Don't initialize the dummy
+ variable. Suggested by Jordi Mallach.
+
+2002-01-31 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (suitable_encoding,convert_to_hex,convert_to_string)
+ (convert_to_token): New.
+ (gcry_sexp_sprint): Better formatting of advanced encoding, does
+ now insert LFs and escapes all unprintable characters.
+ (unquote_string): New.
+ (sexp_sscan): Implemented the missing conversion of quoted strings.
+
+2002-01-26 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: Add copyright notice.
+
+2002-01-11 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Fixed last change.
+
+2002-01-01 Timo Schulz <ts@winpt.org>
+
+ * stdmem.c (_gcry_private_realloc): If pointer is NULL now realloc
+ behaves like malloc.
+
+2001-12-20 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Describe the error codes and
+ return an error if this is not a S-Exp; i.e. it does not start
+ with an open parenthesis.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Fixed the test on NULL buffer.
+
+ * Makefile.am (DISTCLEANFILES): Include libgcrypt.sym
+
+ * sexp.c: Removed the commented test code because we now have a
+ test in ../tests/
+
+2001-12-17 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): New.
+
+2001-12-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Fixed AES128 macro, add enum for OFB mode.
+
+2001-12-05 Werner Koch <wk@gnupg.org>
+
+ * misc.c (_gcry_log_printf): New.
+ * sexp.c (dump_string,gcry_sexp_dump): Use logging functions
+ instead of stderr.
+
+2001-11-16 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: New constant GCRYCTL_IS_ALGO_ENABLED.
+
+2001-10-02 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Removed a couple of trailing commas.
+
+2001-08-28 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Add an argument to enable the
+ arg_ptr. Changed all callers. Suggested by Tom Holroyd.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strerror): Updated list of error codes.
+
+2001-07-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Replaced the last ulong. Noted by Rami Lehti.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h, mpi.h: Made some mpi functions public.
+
+ * wrapper.c: Removed.
+ * global.c: Renamed all g10_ prefixed functions which had wrappers
+ to gcry_xxx. So we now use the exported memory functions inernally.
+
+ Renamed all g10_ prefixed functions to _gcry_ prefixed ones.
+
+ * g10lib.h (_GCRYPT_IN_LIBGCRYPT): Replace defintion by a test on it.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.m4: Check GCRYPT_VERSION macro and not LIBGCRYPT_VERSION.
+
+ * mpi.h: Removed mpi_fromstr prototype.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Add mpi.h
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ * types.h: Moved from ../include to here.
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * mpi.h: Moved to ../mpi.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-11 Werner Koch <wk@gnupg.org>
+
+ * mpi.h: Changed the way mpi_limb_t is defined.
+
+2000-10-10 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am: Take version-info from configure.
+
+2000-10-09 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: New cipher mode, new algo Arcfour and new error code
+ GCRYERR_INV_CIPHER_MODE.
+ * global.c (gcry_strerror): New errorcode.
+
+Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
+
+ * gcrypt.h (gcry_md_setkey): Replaced macro by function prototype.
+
+Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
+
+ * gcrypt.h (GCRYCTL_GET_ALGO_USAGE): New.
+
+ * secmem.c (secmem_realloc): check for failed secmem_malloc. By
+ Matt Kraai.
+
+Mon Jul 31 10:04:47 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c: Removed the datalen fields from list tags.
+ (gcry_sexp_car_data,gcry_sexp_cdr_data,gcry_sexp_car_mpi,
+ gcry_sexp_cdr_mpi): Removed.
+ (gcry_sexp_nth,gcry_sexp_nth_data,gcry_sexp_nth_mpi): New.
+
+Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c (sexp_sscan): Fixed reallocation to secure memory.
+ (new_empty_list): Removed
+ (gcry_sexp_length): New.
+ (gcry_sexp_enum): Removed.
+ (normalize): New. Reworked the whole thing to use NULL for an empty list.
+ (make_space): New instead of the macro.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c: Major rewrite.
+ (gcry_sexp_sscan): Reordered arguments. Moved functionality to ..
+ (sexp_sscan): .. this.
+ (gcry_sexp_build): New.
+ (gcry_sexp_new_name_mpi, gcry_sexp_new_name_data, gcry_sexp_new_data,
+ gcry_sexp_new_mpi): Removed.
+
+Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
+
+ * gcrypt.h (gcry_md_start_debug, gcry_md_stop_debug): New.
+ (gcry_ctl_cmds): New control values
+
+ * sexp.c (gcry_sexp_sscan): Add hex format parsing.
+
+ * secmem.c (lock_pool): Check for ENOSYS return my mlock() on old SCOs.
+ (pool_is_mmapped): Made volatile.
+ (lock_pool): No more warning for QNX. By Sam Roberts.
+ (lock_pool,secmem_init): Additional check for dropped privs.
+
+2000-03-21 09:18:48 Werner Koch (wk@habibti.gnupg.de)
+
+ * gcrypt.h (gcry_md_setkey): New.
+ (GCRY_MD_FLAG_HMAC): New.
+
+Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * Makefile.am: Add g10lib.h
+
+Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (gcry_sexp_sscan): Allow NULL for erroff.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (gcry_sexp_alist): New.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * secmem.c: Moved from ../util to here.
+ * secmem.h: New.
+ * stdmem.c: New. Based on the old ../util/memory.c.
+ * stdmem.h: New.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * gcrypt.m4: New.
+ * gcrypt-config: New.
+
+ * mpi.h (mpi_get_nbit_info): Removed
+ (mpi_set_nbit_info): Removed.
+ (struct gcry_mpi): Removed the nbits field.
+
+ * misc.c (g10_log_verbosity): New.
+
+ * global.c (g10_xstrdup): New.
+
+ * mpiapi.c: Removed.
+
+ * mpi.h: Moved from ../include to here. Removed some obsolete
+ prototypes and the iobuf.h header.
+ * cipher.h: Moved from ../include to here. Removed the mpi.h header.
+ * g10lib.h: Moved from ../include to here.
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (dump_string): New. Taken from gnupg/util/miscutil.c.
+ (do_dump_list): s/print_string/dump_string/.
+
+ * testapi.c: New.
+
+ * mpiapi.c (gcry_mpi_randomize): Use new random API.
+
+Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * gloabl.c (gcry_control): Add cases for dumping random
+ and secmem stats.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * pkapi.c: Removed.
+
+ * symapi.c: Removed.
+
+ * g10lib.h: Moved to ../include.
+
+ * mdapi.c: Removed.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * sexp.c: New.
+
+Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gcrypt.h: New
+ * mpiapi.c: New
+
+
+ Copyright (C) 1998,1999,2000,2001,2002,2003
+ 2004,2005,2008,2009,2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/src/Makefile.am b/comm/third_party/libgcrypt/src/Makefile.am
new file mode 100644
index 0000000000..31aa6660b1
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/Makefile.am
@@ -0,0 +1,162 @@
+# Makefile.am - for gcrypt/src
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+# 2006, 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+## Process this file with automake to produce Makefile.in
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libgcrypt.pc
+
+EXTRA_DIST = libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
+ gcrypt.h.in libgcrypt.def libgcrypt.pc.in
+
+bin_SCRIPTS = libgcrypt-config
+m4datadir = $(datadir)/aclocal
+m4data_DATA = libgcrypt.m4
+nodist_include_HEADERS = gcrypt.h
+
+lib_LTLIBRARIES = libgcrypt.la
+bin_PROGRAMS = dumpsexp hmac256 mpicalc
+if USE_RANDOM_DAEMON
+sbin_PROGRAMS = gcryptrnd
+bin_PROGRAMS += getrandom
+endif USE_RANDOM_DAEMON
+
+# Depending on the architecture some targets require libgpg-error.
+if HAVE_W32CE_SYSTEM
+arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS)
+arch_gpg_error_libs = $(GPG_ERROR_LIBS)
+else
+arch_gpg_error_cflags =
+arch_gpg_error_libs =
+endif
+
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+
+if HAVE_LD_VERSION_SCRIPT
+ libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers
+else
+ libgcrypt_version_script_cmd =
+endif
+
+libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
+libgcrypt_la_SOURCES = \
+ gcrypt-int.h g10lib.h visibility.c visibility.h types.h \
+ gcrypt-testapi.h cipher.h cipher-proto.h \
+ misc.c global.c sexp.c hwfeatures.c hwf-common.h \
+ stdmem.c stdmem.h secmem.c secmem.h \
+ mpi.h missing-string.c fips.c \
+ hmac256.c hmac256.h context.c context.h \
+ ec-context.h
+
+EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c hwf-ppc.c hwf-s390x.c
+gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@
+
+
+if HAVE_W32_SYSTEM
+
+RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)
+LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
+
+SUFFIXES = .rc .lo
+
+.rc.lo:
+ $(LTRCCOMPILE) -i "$<" -o "$@"
+
+gcrypt_res = versioninfo.lo
+no_undefined = -no-undefined
+export_symbols = -export-symbols $(srcdir)/libgcrypt.def
+extra_ltoptions = -XCClinker -static-libgcc
+
+install-def-file:
+ -$(INSTALL) -d $(DESTDIR)$(libdir)
+ $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def
+
+uninstall-def-file:
+ -rm $(DESTDIR)$(libdir)/libgcrypt.def
+
+gcrypt_deps = $(gcrypt_res) libgcrypt.def
+
+else !HAVE_W32_SYSTEM
+
+gcrypt_res =
+gcrypt_res_ldflag =
+no_undefined =
+export_symbols =
+extra_ltoptions =
+install-def-file:
+uninstall-def-file:
+
+gcrypt_deps =
+
+endif !HAVE_W32_SYSTEM
+
+
+libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \
+ $(libgcrypt_version_script_cmd) -version-info \
+ @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
+libgcrypt_la_DEPENDENCIES = \
+ $(gcrypt_hwf_modules) \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la \
+ $(srcdir)/libgcrypt.vers $(gcrypt_deps)
+libgcrypt_la_LIBADD = $(gcrypt_res) \
+ $(gcrypt_hwf_modules) \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la $(DL_LIBS) $(GPG_ERROR_LIBS)
+
+
+dumpsexp_SOURCES = dumpsexp.c
+dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
+dumpsexp_LDADD = $(arch_gpg_error_libs)
+
+mpicalc_SOURCES = mpicalc.c
+mpicalc_CFLAGS = $(GPG_ERROR_CFLAGS)
+mpicalc_LDADD = libgcrypt.la $(GPG_ERROR_LIBS)
+
+hmac256_SOURCES = hmac256.c
+hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
+hmac256_LDADD = $(arch_gpg_error_libs)
+
+if USE_RANDOM_DAEMON
+gcryptrnd_SOURCES = gcryptrnd.c
+gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
+gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
+
+getrandom_SOURCES = getrandom.c
+endif USE_RANDOM_DAEMON
+
+
+install-data-local: install-def-file
+
+uninstall-local: uninstall-def-file
+
+# FIXME: We need to figure out how to get the actual name (parsing
+# libgcrypt.la?) and how to create the hmac file already at link time
+# so that it can be used without installing libgcrypt first.
+#install-exec-hook:
+# ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \
+# < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \
+# > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac
diff --git a/comm/third_party/libgcrypt/src/Makefile.in b/comm/third_party/libgcrypt/src/Makefile.in
new file mode 100644
index 0000000000..1e34f5be14
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/Makefile.in
@@ -0,0 +1,1361 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am - for gcrypt/src
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+# 2006, 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = dumpsexp$(EXEEXT) hmac256$(EXEEXT) mpicalc$(EXEEXT) \
+ $(am__EXEEXT_1)
+@USE_RANDOM_DAEMON_TRUE@sbin_PROGRAMS = gcryptrnd$(EXEEXT)
+@USE_RANDOM_DAEMON_TRUE@am__append_1 = getrandom
+subdir = src
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = gcrypt.h libgcrypt-config libgcrypt.pc \
+ versioninfo.rc
+CONFIG_CLEAN_VPATH_FILES =
+@USE_RANDOM_DAEMON_TRUE@am__EXEEXT_1 = getrandom$(EXEEXT)
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \
+ "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgconfigdir)" \
+ "$(DESTDIR)$(includedir)"
+PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+LTLIBRARIES = $(lib_LTLIBRARIES)
+@HAVE_W32_SYSTEM_TRUE@am__DEPENDENCIES_1 = versioninfo.lo
+am__DEPENDENCIES_2 =
+am_libgcrypt_la_OBJECTS = libgcrypt_la-visibility.lo \
+ libgcrypt_la-misc.lo libgcrypt_la-global.lo \
+ libgcrypt_la-sexp.lo libgcrypt_la-hwfeatures.lo \
+ libgcrypt_la-stdmem.lo libgcrypt_la-secmem.lo \
+ libgcrypt_la-missing-string.lo libgcrypt_la-fips.lo \
+ libgcrypt_la-hmac256.lo libgcrypt_la-context.lo
+libgcrypt_la_OBJECTS = $(am_libgcrypt_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libgcrypt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgcrypt_la_CFLAGS) \
+ $(CFLAGS) $(libgcrypt_la_LDFLAGS) $(LDFLAGS) -o $@
+am_dumpsexp_OBJECTS = dumpsexp-dumpsexp.$(OBJEXT)
+dumpsexp_OBJECTS = $(am_dumpsexp_OBJECTS)
+@HAVE_W32CE_SYSTEM_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2)
+dumpsexp_DEPENDENCIES = $(am__DEPENDENCIES_3)
+dumpsexp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dumpsexp_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am__gcryptrnd_SOURCES_DIST = gcryptrnd.c
+@USE_RANDOM_DAEMON_TRUE@am_gcryptrnd_OBJECTS = \
+@USE_RANDOM_DAEMON_TRUE@ gcryptrnd-gcryptrnd.$(OBJEXT)
+gcryptrnd_OBJECTS = $(am_gcryptrnd_OBJECTS)
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_DEPENDENCIES = libgcrypt.la \
+@USE_RANDOM_DAEMON_TRUE@ $(am__DEPENDENCIES_2) \
+@USE_RANDOM_DAEMON_TRUE@ $(am__DEPENDENCIES_2)
+gcryptrnd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(gcryptrnd_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am__getrandom_SOURCES_DIST = getrandom.c
+@USE_RANDOM_DAEMON_TRUE@am_getrandom_OBJECTS = getrandom.$(OBJEXT)
+getrandom_OBJECTS = $(am_getrandom_OBJECTS)
+getrandom_LDADD = $(LDADD)
+am_hmac256_OBJECTS = hmac256-hmac256.$(OBJEXT)
+hmac256_OBJECTS = $(am_hmac256_OBJECTS)
+hmac256_DEPENDENCIES = $(am__DEPENDENCIES_3)
+hmac256_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(hmac256_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_mpicalc_OBJECTS = mpicalc-mpicalc.$(OBJEXT)
+mpicalc_OBJECTS = $(am_mpicalc_OBJECTS)
+mpicalc_DEPENDENCIES = libgcrypt.la $(am__DEPENDENCIES_2)
+mpicalc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(mpicalc_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/dumpsexp-dumpsexp.Po \
+ ./$(DEPDIR)/gcryptrnd-gcryptrnd.Po ./$(DEPDIR)/getrandom.Po \
+ ./$(DEPDIR)/hmac256-hmac256.Po \
+ ./$(DEPDIR)/libgcrypt_la-context.Plo \
+ ./$(DEPDIR)/libgcrypt_la-fips.Plo \
+ ./$(DEPDIR)/libgcrypt_la-global.Plo \
+ ./$(DEPDIR)/libgcrypt_la-hmac256.Plo \
+ ./$(DEPDIR)/libgcrypt_la-hwf-arm.Plo \
+ ./$(DEPDIR)/libgcrypt_la-hwf-ppc.Plo \
+ ./$(DEPDIR)/libgcrypt_la-hwf-s390x.Plo \
+ ./$(DEPDIR)/libgcrypt_la-hwf-x86.Plo \
+ ./$(DEPDIR)/libgcrypt_la-hwfeatures.Plo \
+ ./$(DEPDIR)/libgcrypt_la-misc.Plo \
+ ./$(DEPDIR)/libgcrypt_la-missing-string.Plo \
+ ./$(DEPDIR)/libgcrypt_la-secmem.Plo \
+ ./$(DEPDIR)/libgcrypt_la-sexp.Plo \
+ ./$(DEPDIR)/libgcrypt_la-stdmem.Plo \
+ ./$(DEPDIR)/libgcrypt_la-visibility.Plo \
+ ./$(DEPDIR)/mpicalc-mpicalc.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libgcrypt_la_SOURCES) $(EXTRA_libgcrypt_la_SOURCES) \
+ $(dumpsexp_SOURCES) $(gcryptrnd_SOURCES) $(getrandom_SOURCES) \
+ $(hmac256_SOURCES) $(mpicalc_SOURCES)
+DIST_SOURCES = $(libgcrypt_la_SOURCES) $(EXTRA_libgcrypt_la_SOURCES) \
+ $(dumpsexp_SOURCES) $(am__gcryptrnd_SOURCES_DIST) \
+ $(am__getrandom_SOURCES_DIST) $(hmac256_SOURCES) \
+ $(mpicalc_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+DATA = $(m4data_DATA) $(pkgconfig_DATA)
+HEADERS = $(nodist_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/gcrypt.h.in \
+ $(srcdir)/libgcrypt-config.in $(srcdir)/libgcrypt.pc.in \
+ $(srcdir)/versioninfo.rc.in $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libgcrypt.pc
+EXTRA_DIST = libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
+ gcrypt.h.in libgcrypt.def libgcrypt.pc.in
+
+bin_SCRIPTS = libgcrypt-config
+m4datadir = $(datadir)/aclocal
+m4data_DATA = libgcrypt.m4
+nodist_include_HEADERS = gcrypt.h
+lib_LTLIBRARIES = libgcrypt.la
+@HAVE_W32CE_SYSTEM_FALSE@arch_gpg_error_cflags =
+
+# Depending on the architecture some targets require libgpg-error.
+@HAVE_W32CE_SYSTEM_TRUE@arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS)
+@HAVE_W32CE_SYSTEM_FALSE@arch_gpg_error_libs =
+@HAVE_W32CE_SYSTEM_TRUE@arch_gpg_error_libs = $(GPG_ERROR_LIBS)
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+@HAVE_LD_VERSION_SCRIPT_FALSE@libgcrypt_version_script_cmd =
+@HAVE_LD_VERSION_SCRIPT_TRUE@libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers
+libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
+libgcrypt_la_SOURCES = \
+ gcrypt-int.h g10lib.h visibility.c visibility.h types.h \
+ gcrypt-testapi.h cipher.h cipher-proto.h \
+ misc.c global.c sexp.c hwfeatures.c hwf-common.h \
+ stdmem.c stdmem.h secmem.c secmem.h \
+ mpi.h missing-string.c fips.c \
+ hmac256.c hmac256.h context.c context.h \
+ ec-context.h
+
+EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c hwf-ppc.c hwf-s390x.c
+gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@
+@HAVE_W32_SYSTEM_TRUE@RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+@HAVE_W32_SYSTEM_TRUE@ $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)
+
+@HAVE_W32_SYSTEM_TRUE@LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
+@HAVE_W32_SYSTEM_TRUE@SUFFIXES = .rc .lo
+@HAVE_W32_SYSTEM_FALSE@gcrypt_res =
+@HAVE_W32_SYSTEM_TRUE@gcrypt_res = versioninfo.lo
+@HAVE_W32_SYSTEM_FALSE@no_undefined =
+@HAVE_W32_SYSTEM_TRUE@no_undefined = -no-undefined
+@HAVE_W32_SYSTEM_FALSE@export_symbols =
+@HAVE_W32_SYSTEM_TRUE@export_symbols = -export-symbols $(srcdir)/libgcrypt.def
+@HAVE_W32_SYSTEM_FALSE@extra_ltoptions =
+@HAVE_W32_SYSTEM_TRUE@extra_ltoptions = -XCClinker -static-libgcc
+@HAVE_W32_SYSTEM_FALSE@gcrypt_deps =
+@HAVE_W32_SYSTEM_TRUE@gcrypt_deps = $(gcrypt_res) libgcrypt.def
+@HAVE_W32_SYSTEM_FALSE@gcrypt_res_ldflag =
+libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \
+ $(libgcrypt_version_script_cmd) -version-info \
+ @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
+
+libgcrypt_la_DEPENDENCIES = \
+ $(gcrypt_hwf_modules) \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la \
+ $(srcdir)/libgcrypt.vers $(gcrypt_deps)
+
+libgcrypt_la_LIBADD = $(gcrypt_res) \
+ $(gcrypt_hwf_modules) \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la $(DL_LIBS) $(GPG_ERROR_LIBS)
+
+dumpsexp_SOURCES = dumpsexp.c
+dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
+dumpsexp_LDADD = $(arch_gpg_error_libs)
+mpicalc_SOURCES = mpicalc.c
+mpicalc_CFLAGS = $(GPG_ERROR_CFLAGS)
+mpicalc_LDADD = libgcrypt.la $(GPG_ERROR_LIBS)
+hmac256_SOURCES = hmac256.c
+hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
+hmac256_LDADD = $(arch_gpg_error_libs)
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_SOURCES = gcryptrnd.c
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
+@USE_RANDOM_DAEMON_TRUE@getrandom_SOURCES = getrandom.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .rc .lo .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+gcrypt.h: $(top_builddir)/config.status $(srcdir)/gcrypt.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+libgcrypt-config: $(top_builddir)/config.status $(srcdir)/libgcrypt-config.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+libgcrypt.pc: $(top_builddir)/config.status $(srcdir)/libgcrypt.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+versioninfo.rc: $(top_builddir)/config.status $(srcdir)/versioninfo.rc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libgcrypt.la: $(libgcrypt_la_OBJECTS) $(libgcrypt_la_DEPENDENCIES) $(EXTRA_libgcrypt_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libgcrypt_la_LINK) -rpath $(libdir) $(libgcrypt_la_OBJECTS) $(libgcrypt_la_LIBADD) $(LIBS)
+
+dumpsexp$(EXEEXT): $(dumpsexp_OBJECTS) $(dumpsexp_DEPENDENCIES) $(EXTRA_dumpsexp_DEPENDENCIES)
+ @rm -f dumpsexp$(EXEEXT)
+ $(AM_V_CCLD)$(dumpsexp_LINK) $(dumpsexp_OBJECTS) $(dumpsexp_LDADD) $(LIBS)
+
+gcryptrnd$(EXEEXT): $(gcryptrnd_OBJECTS) $(gcryptrnd_DEPENDENCIES) $(EXTRA_gcryptrnd_DEPENDENCIES)
+ @rm -f gcryptrnd$(EXEEXT)
+ $(AM_V_CCLD)$(gcryptrnd_LINK) $(gcryptrnd_OBJECTS) $(gcryptrnd_LDADD) $(LIBS)
+
+getrandom$(EXEEXT): $(getrandom_OBJECTS) $(getrandom_DEPENDENCIES) $(EXTRA_getrandom_DEPENDENCIES)
+ @rm -f getrandom$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(getrandom_OBJECTS) $(getrandom_LDADD) $(LIBS)
+
+hmac256$(EXEEXT): $(hmac256_OBJECTS) $(hmac256_DEPENDENCIES) $(EXTRA_hmac256_DEPENDENCIES)
+ @rm -f hmac256$(EXEEXT)
+ $(AM_V_CCLD)$(hmac256_LINK) $(hmac256_OBJECTS) $(hmac256_LDADD) $(LIBS)
+
+mpicalc$(EXEEXT): $(mpicalc_OBJECTS) $(mpicalc_DEPENDENCIES) $(EXTRA_mpicalc_DEPENDENCIES)
+ @rm -f mpicalc$(EXEEXT)
+ $(AM_V_CCLD)$(mpicalc_LINK) $(mpicalc_OBJECTS) $(mpicalc_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dumpsexp-dumpsexp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcryptrnd-gcryptrnd.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getrandom.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac256-hmac256.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-context.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-fips.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-global.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hmac256.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwf-arm.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwf-ppc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwf-s390x.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwf-x86.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwfeatures.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-misc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-missing-string.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-secmem.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-sexp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-stdmem.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-visibility.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpicalc-mpicalc.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libgcrypt_la-visibility.lo: visibility.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-visibility.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-visibility.Tpo -c -o libgcrypt_la-visibility.lo `test -f 'visibility.c' || echo '$(srcdir)/'`visibility.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-visibility.Tpo $(DEPDIR)/libgcrypt_la-visibility.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='visibility.c' object='libgcrypt_la-visibility.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-visibility.lo `test -f 'visibility.c' || echo '$(srcdir)/'`visibility.c
+
+libgcrypt_la-misc.lo: misc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-misc.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-misc.Tpo -c -o libgcrypt_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-misc.Tpo $(DEPDIR)/libgcrypt_la-misc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='misc.c' object='libgcrypt_la-misc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
+
+libgcrypt_la-global.lo: global.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-global.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-global.Tpo -c -o libgcrypt_la-global.lo `test -f 'global.c' || echo '$(srcdir)/'`global.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-global.Tpo $(DEPDIR)/libgcrypt_la-global.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='global.c' object='libgcrypt_la-global.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-global.lo `test -f 'global.c' || echo '$(srcdir)/'`global.c
+
+libgcrypt_la-sexp.lo: sexp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-sexp.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-sexp.Tpo -c -o libgcrypt_la-sexp.lo `test -f 'sexp.c' || echo '$(srcdir)/'`sexp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-sexp.Tpo $(DEPDIR)/libgcrypt_la-sexp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sexp.c' object='libgcrypt_la-sexp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-sexp.lo `test -f 'sexp.c' || echo '$(srcdir)/'`sexp.c
+
+libgcrypt_la-hwfeatures.lo: hwfeatures.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hwfeatures.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwfeatures.Tpo -c -o libgcrypt_la-hwfeatures.lo `test -f 'hwfeatures.c' || echo '$(srcdir)/'`hwfeatures.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hwfeatures.Tpo $(DEPDIR)/libgcrypt_la-hwfeatures.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hwfeatures.c' object='libgcrypt_la-hwfeatures.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hwfeatures.lo `test -f 'hwfeatures.c' || echo '$(srcdir)/'`hwfeatures.c
+
+libgcrypt_la-stdmem.lo: stdmem.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-stdmem.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-stdmem.Tpo -c -o libgcrypt_la-stdmem.lo `test -f 'stdmem.c' || echo '$(srcdir)/'`stdmem.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-stdmem.Tpo $(DEPDIR)/libgcrypt_la-stdmem.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdmem.c' object='libgcrypt_la-stdmem.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-stdmem.lo `test -f 'stdmem.c' || echo '$(srcdir)/'`stdmem.c
+
+libgcrypt_la-secmem.lo: secmem.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-secmem.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-secmem.Tpo -c -o libgcrypt_la-secmem.lo `test -f 'secmem.c' || echo '$(srcdir)/'`secmem.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-secmem.Tpo $(DEPDIR)/libgcrypt_la-secmem.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='secmem.c' object='libgcrypt_la-secmem.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-secmem.lo `test -f 'secmem.c' || echo '$(srcdir)/'`secmem.c
+
+libgcrypt_la-missing-string.lo: missing-string.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-missing-string.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-missing-string.Tpo -c -o libgcrypt_la-missing-string.lo `test -f 'missing-string.c' || echo '$(srcdir)/'`missing-string.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-missing-string.Tpo $(DEPDIR)/libgcrypt_la-missing-string.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='missing-string.c' object='libgcrypt_la-missing-string.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-missing-string.lo `test -f 'missing-string.c' || echo '$(srcdir)/'`missing-string.c
+
+libgcrypt_la-fips.lo: fips.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-fips.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-fips.Tpo -c -o libgcrypt_la-fips.lo `test -f 'fips.c' || echo '$(srcdir)/'`fips.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-fips.Tpo $(DEPDIR)/libgcrypt_la-fips.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fips.c' object='libgcrypt_la-fips.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-fips.lo `test -f 'fips.c' || echo '$(srcdir)/'`fips.c
+
+libgcrypt_la-hmac256.lo: hmac256.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hmac256.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hmac256.Tpo -c -o libgcrypt_la-hmac256.lo `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hmac256.Tpo $(DEPDIR)/libgcrypt_la-hmac256.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac256.c' object='libgcrypt_la-hmac256.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hmac256.lo `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+
+libgcrypt_la-context.lo: context.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-context.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-context.Tpo -c -o libgcrypt_la-context.lo `test -f 'context.c' || echo '$(srcdir)/'`context.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-context.Tpo $(DEPDIR)/libgcrypt_la-context.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='context.c' object='libgcrypt_la-context.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-context.lo `test -f 'context.c' || echo '$(srcdir)/'`context.c
+
+libgcrypt_la-hwf-x86.lo: hwf-x86.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hwf-x86.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwf-x86.Tpo -c -o libgcrypt_la-hwf-x86.lo `test -f 'hwf-x86.c' || echo '$(srcdir)/'`hwf-x86.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hwf-x86.Tpo $(DEPDIR)/libgcrypt_la-hwf-x86.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hwf-x86.c' object='libgcrypt_la-hwf-x86.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hwf-x86.lo `test -f 'hwf-x86.c' || echo '$(srcdir)/'`hwf-x86.c
+
+libgcrypt_la-hwf-arm.lo: hwf-arm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hwf-arm.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwf-arm.Tpo -c -o libgcrypt_la-hwf-arm.lo `test -f 'hwf-arm.c' || echo '$(srcdir)/'`hwf-arm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hwf-arm.Tpo $(DEPDIR)/libgcrypt_la-hwf-arm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hwf-arm.c' object='libgcrypt_la-hwf-arm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hwf-arm.lo `test -f 'hwf-arm.c' || echo '$(srcdir)/'`hwf-arm.c
+
+libgcrypt_la-hwf-ppc.lo: hwf-ppc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hwf-ppc.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwf-ppc.Tpo -c -o libgcrypt_la-hwf-ppc.lo `test -f 'hwf-ppc.c' || echo '$(srcdir)/'`hwf-ppc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hwf-ppc.Tpo $(DEPDIR)/libgcrypt_la-hwf-ppc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hwf-ppc.c' object='libgcrypt_la-hwf-ppc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hwf-ppc.lo `test -f 'hwf-ppc.c' || echo '$(srcdir)/'`hwf-ppc.c
+
+libgcrypt_la-hwf-s390x.lo: hwf-s390x.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hwf-s390x.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwf-s390x.Tpo -c -o libgcrypt_la-hwf-s390x.lo `test -f 'hwf-s390x.c' || echo '$(srcdir)/'`hwf-s390x.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hwf-s390x.Tpo $(DEPDIR)/libgcrypt_la-hwf-s390x.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hwf-s390x.c' object='libgcrypt_la-hwf-s390x.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hwf-s390x.lo `test -f 'hwf-s390x.c' || echo '$(srcdir)/'`hwf-s390x.c
+
+dumpsexp-dumpsexp.o: dumpsexp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -MT dumpsexp-dumpsexp.o -MD -MP -MF $(DEPDIR)/dumpsexp-dumpsexp.Tpo -c -o dumpsexp-dumpsexp.o `test -f 'dumpsexp.c' || echo '$(srcdir)/'`dumpsexp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dumpsexp-dumpsexp.Tpo $(DEPDIR)/dumpsexp-dumpsexp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpsexp.c' object='dumpsexp-dumpsexp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -c -o dumpsexp-dumpsexp.o `test -f 'dumpsexp.c' || echo '$(srcdir)/'`dumpsexp.c
+
+dumpsexp-dumpsexp.obj: dumpsexp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -MT dumpsexp-dumpsexp.obj -MD -MP -MF $(DEPDIR)/dumpsexp-dumpsexp.Tpo -c -o dumpsexp-dumpsexp.obj `if test -f 'dumpsexp.c'; then $(CYGPATH_W) 'dumpsexp.c'; else $(CYGPATH_W) '$(srcdir)/dumpsexp.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dumpsexp-dumpsexp.Tpo $(DEPDIR)/dumpsexp-dumpsexp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpsexp.c' object='dumpsexp-dumpsexp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -c -o dumpsexp-dumpsexp.obj `if test -f 'dumpsexp.c'; then $(CYGPATH_W) 'dumpsexp.c'; else $(CYGPATH_W) '$(srcdir)/dumpsexp.c'; fi`
+
+gcryptrnd-gcryptrnd.o: gcryptrnd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -MT gcryptrnd-gcryptrnd.o -MD -MP -MF $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo -c -o gcryptrnd-gcryptrnd.o `test -f 'gcryptrnd.c' || echo '$(srcdir)/'`gcryptrnd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo $(DEPDIR)/gcryptrnd-gcryptrnd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gcryptrnd.c' object='gcryptrnd-gcryptrnd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -c -o gcryptrnd-gcryptrnd.o `test -f 'gcryptrnd.c' || echo '$(srcdir)/'`gcryptrnd.c
+
+gcryptrnd-gcryptrnd.obj: gcryptrnd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -MT gcryptrnd-gcryptrnd.obj -MD -MP -MF $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo -c -o gcryptrnd-gcryptrnd.obj `if test -f 'gcryptrnd.c'; then $(CYGPATH_W) 'gcryptrnd.c'; else $(CYGPATH_W) '$(srcdir)/gcryptrnd.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo $(DEPDIR)/gcryptrnd-gcryptrnd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gcryptrnd.c' object='gcryptrnd-gcryptrnd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -c -o gcryptrnd-gcryptrnd.obj `if test -f 'gcryptrnd.c'; then $(CYGPATH_W) 'gcryptrnd.c'; else $(CYGPATH_W) '$(srcdir)/gcryptrnd.c'; fi`
+
+hmac256-hmac256.o: hmac256.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -MT hmac256-hmac256.o -MD -MP -MF $(DEPDIR)/hmac256-hmac256.Tpo -c -o hmac256-hmac256.o `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hmac256-hmac256.Tpo $(DEPDIR)/hmac256-hmac256.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac256.c' object='hmac256-hmac256.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -c -o hmac256-hmac256.o `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+
+hmac256-hmac256.obj: hmac256.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -MT hmac256-hmac256.obj -MD -MP -MF $(DEPDIR)/hmac256-hmac256.Tpo -c -o hmac256-hmac256.obj `if test -f 'hmac256.c'; then $(CYGPATH_W) 'hmac256.c'; else $(CYGPATH_W) '$(srcdir)/hmac256.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hmac256-hmac256.Tpo $(DEPDIR)/hmac256-hmac256.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac256.c' object='hmac256-hmac256.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -c -o hmac256-hmac256.obj `if test -f 'hmac256.c'; then $(CYGPATH_W) 'hmac256.c'; else $(CYGPATH_W) '$(srcdir)/hmac256.c'; fi`
+
+mpicalc-mpicalc.o: mpicalc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpicalc_CFLAGS) $(CFLAGS) -MT mpicalc-mpicalc.o -MD -MP -MF $(DEPDIR)/mpicalc-mpicalc.Tpo -c -o mpicalc-mpicalc.o `test -f 'mpicalc.c' || echo '$(srcdir)/'`mpicalc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mpicalc-mpicalc.Tpo $(DEPDIR)/mpicalc-mpicalc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mpicalc.c' object='mpicalc-mpicalc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpicalc_CFLAGS) $(CFLAGS) -c -o mpicalc-mpicalc.o `test -f 'mpicalc.c' || echo '$(srcdir)/'`mpicalc.c
+
+mpicalc-mpicalc.obj: mpicalc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpicalc_CFLAGS) $(CFLAGS) -MT mpicalc-mpicalc.obj -MD -MP -MF $(DEPDIR)/mpicalc-mpicalc.Tpo -c -o mpicalc-mpicalc.obj `if test -f 'mpicalc.c'; then $(CYGPATH_W) 'mpicalc.c'; else $(CYGPATH_W) '$(srcdir)/mpicalc.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mpicalc-mpicalc.Tpo $(DEPDIR)/mpicalc-mpicalc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mpicalc.c' object='mpicalc-mpicalc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpicalc_CFLAGS) $(CFLAGS) -c -o mpicalc-mpicalc.obj `if test -f 'mpicalc.c'; then $(CYGPATH_W) 'mpicalc.c'; else $(CYGPATH_W) '$(srcdir)/mpicalc.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-m4dataDATA: $(m4data_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \
+ done
+
+uninstall-m4dataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir)
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+install-nodist_includeHEADERS: $(nodist_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-nodist_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(DATA) \
+ $(HEADERS)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libtool clean-sbinPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/dumpsexp-dumpsexp.Po
+ -rm -f ./$(DEPDIR)/gcryptrnd-gcryptrnd.Po
+ -rm -f ./$(DEPDIR)/getrandom.Po
+ -rm -f ./$(DEPDIR)/hmac256-hmac256.Po
+ -rm -f ./$(DEPDIR)/libgcrypt_la-context.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-fips.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-global.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hmac256.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwf-arm.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwf-ppc.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwf-s390x.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwf-x86.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwfeatures.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-misc.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-missing-string.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-secmem.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-sexp.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-stdmem.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-visibility.Plo
+ -rm -f ./$(DEPDIR)/mpicalc-mpicalc.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-m4dataDATA \
+ install-nodist_includeHEADERS install-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS \
+ install-libLTLIBRARIES install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/dumpsexp-dumpsexp.Po
+ -rm -f ./$(DEPDIR)/gcryptrnd-gcryptrnd.Po
+ -rm -f ./$(DEPDIR)/getrandom.Po
+ -rm -f ./$(DEPDIR)/hmac256-hmac256.Po
+ -rm -f ./$(DEPDIR)/libgcrypt_la-context.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-fips.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-global.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hmac256.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwf-arm.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwf-ppc.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwf-s390x.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwf-x86.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-hwfeatures.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-misc.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-missing-string.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-secmem.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-sexp.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-stdmem.Plo
+ -rm -f ./$(DEPDIR)/libgcrypt_la-visibility.Plo
+ -rm -f ./$(DEPDIR)/mpicalc-mpicalc.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-libLTLIBRARIES uninstall-local uninstall-m4dataDATA \
+ uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA \
+ uninstall-sbinPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-binSCRIPTS install-data install-data-am \
+ install-data-local install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-m4dataDATA \
+ install-man install-nodist_includeHEADERS install-pdf \
+ install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
+ install-sbinPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-binSCRIPTS uninstall-libLTLIBRARIES uninstall-local \
+ uninstall-m4dataDATA uninstall-nodist_includeHEADERS \
+ uninstall-pkgconfigDATA uninstall-sbinPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+@HAVE_W32_SYSTEM_TRUE@.rc.lo:
+@HAVE_W32_SYSTEM_TRUE@ $(LTRCCOMPILE) -i "$<" -o "$@"
+
+@HAVE_W32_SYSTEM_TRUE@install-def-file:
+@HAVE_W32_SYSTEM_TRUE@ -$(INSTALL) -d $(DESTDIR)$(libdir)
+@HAVE_W32_SYSTEM_TRUE@ $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def
+
+@HAVE_W32_SYSTEM_TRUE@uninstall-def-file:
+@HAVE_W32_SYSTEM_TRUE@ -rm $(DESTDIR)$(libdir)/libgcrypt.def
+@HAVE_W32_SYSTEM_FALSE@install-def-file:
+@HAVE_W32_SYSTEM_FALSE@uninstall-def-file:
+
+install-data-local: install-def-file
+
+uninstall-local: uninstall-def-file
+
+# FIXME: We need to figure out how to get the actual name (parsing
+# libgcrypt.la?) and how to create the hmac file already at link time
+# so that it can be used without installing libgcrypt first.
+#install-exec-hook:
+# ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \
+# < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \
+# > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/src/cipher-proto.h b/comm/third_party/libgcrypt/src/cipher-proto.h
new file mode 100644
index 0000000000..f9fbb553e8
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/cipher-proto.h
@@ -0,0 +1,280 @@
+/* cipher-proto.h - Internal declarations
+ * Copyright (C) 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file has been factored out from cipher.h so that it can be
+ used standalone in visibility.c . */
+
+#ifndef G10_CIPHER_PROTO_H
+#define G10_CIPHER_PROTO_H
+
+
+enum pk_encoding;
+
+
+/* Definition of a function used to report selftest failures.
+ DOMAIN is a string describing the function block:
+ "cipher", "digest", "pubkey or "random",
+ ALGO is the algorithm under test,
+ WHAT is a string describing what has been tested,
+ DESC is a string describing the error. */
+typedef void (*selftest_report_func_t)(const char *domain,
+ int algo,
+ const char *what,
+ const char *errdesc);
+
+/* Definition of the selftest functions. */
+typedef gpg_err_code_t (*selftest_func_t)
+ (int algo, int extended, selftest_report_func_t report);
+
+
+/*
+ *
+ * Public key related definitions.
+ *
+ */
+
+/* Type for the pk_generate function. */
+typedef gcry_err_code_t (*gcry_pk_generate_t) (gcry_sexp_t genparms,
+ gcry_sexp_t *r_skey);
+
+/* Type for the pk_check_secret_key function. */
+typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (gcry_sexp_t keyparms);
+
+/* Type for the pk_encrypt function. */
+typedef gcry_err_code_t (*gcry_pk_encrypt_t) (gcry_sexp_t *r_ciph,
+ gcry_sexp_t s_data,
+ gcry_sexp_t keyparms);
+
+/* Type for the pk_decrypt function. */
+typedef gcry_err_code_t (*gcry_pk_decrypt_t) (gcry_sexp_t *r_plain,
+ gcry_sexp_t s_data,
+ gcry_sexp_t keyparms);
+
+/* Type for the pk_sign function. */
+typedef gcry_err_code_t (*gcry_pk_sign_t) (gcry_sexp_t *r_sig,
+ gcry_sexp_t s_data,
+ gcry_sexp_t keyparms);
+
+/* Type for the pk_verify function. */
+typedef gcry_err_code_t (*gcry_pk_verify_t) (gcry_sexp_t s_sig,
+ gcry_sexp_t s_data,
+ gcry_sexp_t keyparms);
+
+/* Type for the pk_get_nbits function. */
+typedef unsigned (*gcry_pk_get_nbits_t) (gcry_sexp_t keyparms);
+
+
+/* The type used to compute the keygrip. */
+typedef gpg_err_code_t (*pk_comp_keygrip_t) (gcry_md_hd_t md,
+ gcry_sexp_t keyparm);
+
+/* The type used to query an ECC curve name. */
+typedef const char *(*pk_get_curve_t)(gcry_sexp_t keyparms, int iterator,
+ unsigned int *r_nbits);
+
+/* The type used to query ECC curve parameters by name. */
+typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name);
+
+
+/* Module specification structure for public key algorithms. */
+typedef struct gcry_pk_spec
+{
+ int algo;
+ struct {
+ unsigned int disabled:1;
+ unsigned int fips:1;
+ } flags;
+ int use;
+ const char *name;
+ const char **aliases;
+ const char *elements_pkey;
+ const char *elements_skey;
+ const char *elements_enc;
+ const char *elements_sig;
+ const char *elements_grip;
+ gcry_pk_generate_t generate;
+ gcry_pk_check_secret_key_t check_secret_key;
+ gcry_pk_encrypt_t encrypt;
+ gcry_pk_decrypt_t decrypt;
+ gcry_pk_sign_t sign;
+ gcry_pk_verify_t verify;
+ gcry_pk_get_nbits_t get_nbits;
+ selftest_func_t selftest;
+ pk_comp_keygrip_t comp_keygrip;
+ pk_get_curve_t get_curve;
+ pk_get_curve_param_t get_curve_param;
+} gcry_pk_spec_t;
+
+
+
+/*
+ *
+ * Symmetric cipher related definitions.
+ *
+ */
+
+struct cipher_bulk_ops;
+
+/* Type for the cipher_setkey function. */
+typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
+ const unsigned char *key,
+ unsigned keylen,
+ struct cipher_bulk_ops *bulk_ops);
+
+/* Type for the cipher_encrypt function. */
+typedef unsigned int (*gcry_cipher_encrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf);
+
+/* Type for the cipher_decrypt function. */
+typedef unsigned int (*gcry_cipher_decrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf);
+
+/* Type for the cipher_stencrypt function. */
+typedef void (*gcry_cipher_stencrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf,
+ size_t n);
+
+/* Type for the cipher_stdecrypt function. */
+typedef void (*gcry_cipher_stdecrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf,
+ size_t n);
+
+/* The type used to convey additional information to a cipher. */
+typedef gpg_err_code_t (*cipher_set_extra_info_t)
+ (void *c, int what, const void *buffer, size_t buflen);
+
+/* The type used to set an IV directly in the algorithm module. */
+typedef void (*cipher_setiv_func_t)(void *c, const byte *iv, size_t ivlen);
+
+/* A structure to map OIDs to encryption modes. */
+typedef struct gcry_cipher_oid_spec
+{
+ const char *oid;
+ int mode;
+} gcry_cipher_oid_spec_t;
+
+
+/* Module specification structure for ciphers. */
+typedef struct gcry_cipher_spec
+{
+ int algo;
+ struct {
+ unsigned int disabled:1;
+ unsigned int fips:1;
+ } flags;
+ const char *name;
+ const char **aliases;
+ gcry_cipher_oid_spec_t *oids;
+ size_t blocksize;
+ size_t keylen;
+ size_t contextsize;
+ gcry_cipher_setkey_t setkey;
+ gcry_cipher_encrypt_t encrypt;
+ gcry_cipher_decrypt_t decrypt;
+ gcry_cipher_stencrypt_t stencrypt;
+ gcry_cipher_stdecrypt_t stdecrypt;
+ selftest_func_t selftest;
+ cipher_set_extra_info_t set_extra_info;
+ cipher_setiv_func_t setiv;
+} gcry_cipher_spec_t;
+
+
+
+/*
+ *
+ * Message digest related definitions.
+ *
+ */
+
+/* Type for the md_init function. */
+typedef void (*gcry_md_init_t) (void *c, unsigned int flags);
+
+/* Type for the md_write function. */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
+
+/* Type for the md_final function. */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function. */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+/* Type for the md_extract function. */
+typedef void (*gcry_md_extract_t) (void *c, void *outbuf, size_t nbytes);
+
+/* Type for the md_hash_buffer function. */
+typedef void (*gcry_md_hash_buffer_t) (void *outbuf, const void *buffer,
+ size_t length);
+
+/* Type for the md_hash_buffers function. */
+typedef void (*gcry_md_hash_buffers_t) (void *outbuf, const gcry_buffer_t *iov,
+ int iovcnt);
+
+typedef struct gcry_md_oid_spec
+{
+ const char *oidstring;
+} gcry_md_oid_spec_t;
+
+/* Module specification structure for message digests. */
+typedef struct gcry_md_spec
+{
+ int algo;
+ struct {
+ unsigned int disabled:1;
+ unsigned int fips:1;
+ } flags;
+ const char *name;
+ unsigned char *asnoid;
+ int asnlen;
+ gcry_md_oid_spec_t *oids;
+ int mdlen;
+ gcry_md_init_t init;
+ gcry_md_write_t write;
+ gcry_md_final_t final;
+ gcry_md_read_t read;
+ gcry_md_extract_t extract;
+ gcry_md_hash_buffer_t hash_buffer;
+ gcry_md_hash_buffers_t hash_buffers;
+ size_t contextsize; /* allocate this amount of context */
+ selftest_func_t selftest;
+} gcry_md_spec_t;
+
+
+
+/* The selftest functions. */
+gcry_error_t _gcry_cipher_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_md_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_pk_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_mac_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_kdf_selftest (int algo, int extended,
+ selftest_report_func_t report);
+
+gcry_error_t _gcry_random_selftest (selftest_report_func_t report);
+
+
+
+
+#endif /*G10_CIPHER_PROTO_H*/
diff --git a/comm/third_party/libgcrypt/src/cipher.h b/comm/third_party/libgcrypt/src/cipher.h
new file mode 100644
index 0000000000..908e3b78a6
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/cipher.h
@@ -0,0 +1,244 @@
+/* cipher.h
+ * Copyright (C) 1998, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_CIPHER_H
+#define G10_CIPHER_H
+
+#include "gcrypt-int.h"
+
+#define DBG_CIPHER _gcry_get_debug_flag( 1 )
+
+#include "../random/random.h"
+
+#define PUBKEY_FLAG_NO_BLINDING (1 << 0)
+#define PUBKEY_FLAG_RFC6979 (1 << 1)
+#define PUBKEY_FLAG_FIXEDLEN (1 << 2)
+#define PUBKEY_FLAG_LEGACYRESULT (1 << 3)
+#define PUBKEY_FLAG_RAW_FLAG (1 << 4)
+#define PUBKEY_FLAG_TRANSIENT_KEY (1 << 5)
+#define PUBKEY_FLAG_USE_X931 (1 << 6)
+#define PUBKEY_FLAG_USE_FIPS186 (1 << 7)
+#define PUBKEY_FLAG_USE_FIPS186_2 (1 << 8)
+#define PUBKEY_FLAG_PARAM (1 << 9)
+#define PUBKEY_FLAG_COMP (1 << 10)
+#define PUBKEY_FLAG_NOCOMP (1 << 11)
+#define PUBKEY_FLAG_EDDSA (1 << 12)
+#define PUBKEY_FLAG_GOST (1 << 13)
+#define PUBKEY_FLAG_NO_KEYTEST (1 << 14)
+#define PUBKEY_FLAG_DJB_TWEAK (1 << 15)
+#define PUBKEY_FLAG_SM2 (1 << 16)
+#define PUBKEY_FLAG_PREHASH (1 << 17)
+
+
+enum pk_operation
+ {
+ PUBKEY_OP_ENCRYPT,
+ PUBKEY_OP_DECRYPT,
+ PUBKEY_OP_SIGN,
+ PUBKEY_OP_VERIFY
+ };
+
+enum pk_encoding
+ {
+ PUBKEY_ENC_RAW,
+ PUBKEY_ENC_PKCS1,
+ PUBKEY_ENC_PKCS1_RAW,
+ PUBKEY_ENC_OAEP,
+ PUBKEY_ENC_PSS,
+ PUBKEY_ENC_UNKNOWN
+ };
+
+struct pk_encoding_ctx
+{
+ enum pk_operation op;
+ unsigned int nbits;
+
+ enum pk_encoding encoding;
+ int flags;
+
+ int hash_algo;
+
+ /* for OAEP */
+ unsigned char *label;
+ size_t labellen;
+
+ /* for PSS */
+ size_t saltlen;
+
+ int (* verify_cmp) (void *opaque, gcry_mpi_t tmp);
+ void *verify_arg;
+};
+
+#define CIPHER_INFO_NO_WEAK_KEY 1
+
+#include "cipher-proto.h"
+
+/* The internal encryption modes. */
+enum gcry_cipher_internal_modes
+ {
+ GCRY_CIPHER_MODE_INTERNAL = 0x10000,
+ GCRY_CIPHER_MODE_CMAC = 0x10000 + 1 /* Cipher-based MAC. */
+ };
+
+
+/*-- cipher.c --*/
+gcry_err_code_t _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
+ int algo, int mode,
+ unsigned int flags);
+
+/*-- cipher-cmac.c --*/
+gcry_err_code_t _gcry_cipher_cmac_authenticate
+/* */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen);
+gcry_err_code_t _gcry_cipher_cmac_get_tag
+/* */ (gcry_cipher_hd_t c,
+ unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_cmac_check_tag
+/* */ (gcry_cipher_hd_t c,
+ const unsigned char *intag, size_t taglen);
+gcry_err_code_t _gcry_cipher_cmac_set_subkeys
+/* */ (gcry_cipher_hd_t c);
+
+/*-- rmd160.c --*/
+void _gcry_rmd160_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+
+/*-- sha1.c --*/
+void _gcry_sha1_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+void _gcry_sha1_hash_buffers (void *outbuf,
+ const gcry_buffer_t *iov, int iovcnt);
+
+/*-- sha256.c --*/
+void _gcry_sha256_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+void _gcry_sha256_hash_buffers (void *outbuf,
+ const gcry_buffer_t *iov, int iovcnt);
+
+/*-- sha512.c --*/
+void _gcry_sha512_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+void _gcry_sha512_hash_buffers (void *outbuf,
+ const gcry_buffer_t *iov, int iovcnt);
+
+/*-- sm3.c --*/
+void _gcry_sm3_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+void _gcry_sm3_hash_buffers (void *outbuf,
+ const gcry_buffer_t *iov, int iovcnt);
+
+/*-- blake2.c --*/
+gcry_err_code_t _gcry_blake2_init_with_key(void *ctx, unsigned int flags,
+ const unsigned char *key,
+ size_t keylen, int algo);
+
+/*-- dsa.c --*/
+void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data);
+
+/*-- elgamal.c --*/
+void _gcry_register_pk_elg_progress (gcry_handler_progress_t cb,
+ void *cb_data);
+
+
+/*-- ecc.c --*/
+void _gcry_register_pk_ecc_progress (gcry_handler_progress_t cbc,
+ void *cb_data);
+
+
+/*-- primegen.c --*/
+void _gcry_register_primegen_progress (gcry_handler_progress_t cb,
+ void *cb_data);
+
+/*-- pubkey.c --*/
+
+/* Declarations for the cipher specifications. */
+extern gcry_cipher_spec_t _gcry_cipher_spec_blowfish;
+extern gcry_cipher_spec_t _gcry_cipher_spec_des;
+extern gcry_cipher_spec_t _gcry_cipher_spec_tripledes;
+extern gcry_cipher_spec_t _gcry_cipher_spec_arcfour;
+extern gcry_cipher_spec_t _gcry_cipher_spec_cast5;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_twofish;
+extern gcry_cipher_spec_t _gcry_cipher_spec_twofish128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40;
+extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_seed;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_idea;
+extern gcry_cipher_spec_t _gcry_cipher_spec_salsa20;
+extern gcry_cipher_spec_t _gcry_cipher_spec_salsa20r12;
+extern gcry_cipher_spec_t _gcry_cipher_spec_gost28147;
+extern gcry_cipher_spec_t _gcry_cipher_spec_gost28147_mesh;
+extern gcry_cipher_spec_t _gcry_cipher_spec_chacha20;
+extern gcry_cipher_spec_t _gcry_cipher_spec_sm4;
+
+/* Declarations for the digest specifications. */
+extern gcry_md_spec_t _gcry_digest_spec_crc32;
+extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510;
+extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440;
+extern gcry_md_spec_t _gcry_digest_spec_gost3411_94;
+extern gcry_md_spec_t _gcry_digest_spec_gost3411_cp;
+extern gcry_md_spec_t _gcry_digest_spec_stribog_256;
+extern gcry_md_spec_t _gcry_digest_spec_stribog_512;
+extern gcry_md_spec_t _gcry_digest_spec_md2;
+extern gcry_md_spec_t _gcry_digest_spec_md4;
+extern gcry_md_spec_t _gcry_digest_spec_md5;
+extern gcry_md_spec_t _gcry_digest_spec_rmd160;
+extern gcry_md_spec_t _gcry_digest_spec_sha1;
+extern gcry_md_spec_t _gcry_digest_spec_sha224;
+extern gcry_md_spec_t _gcry_digest_spec_sha256;
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
+extern gcry_md_spec_t _gcry_digest_spec_sha512;
+extern gcry_md_spec_t _gcry_digest_spec_sha512_224;
+extern gcry_md_spec_t _gcry_digest_spec_sha512_256;
+extern gcry_md_spec_t _gcry_digest_spec_sha3_224;
+extern gcry_md_spec_t _gcry_digest_spec_sha3_256;
+extern gcry_md_spec_t _gcry_digest_spec_sha3_512;
+extern gcry_md_spec_t _gcry_digest_spec_sha3_384;
+extern gcry_md_spec_t _gcry_digest_spec_shake128;
+extern gcry_md_spec_t _gcry_digest_spec_shake256;
+extern gcry_md_spec_t _gcry_digest_spec_tiger;
+extern gcry_md_spec_t _gcry_digest_spec_tiger1;
+extern gcry_md_spec_t _gcry_digest_spec_tiger2;
+extern gcry_md_spec_t _gcry_digest_spec_whirlpool;
+extern gcry_md_spec_t _gcry_digest_spec_blake2b_512;
+extern gcry_md_spec_t _gcry_digest_spec_blake2b_384;
+extern gcry_md_spec_t _gcry_digest_spec_blake2b_256;
+extern gcry_md_spec_t _gcry_digest_spec_blake2b_160;
+extern gcry_md_spec_t _gcry_digest_spec_blake2s_256;
+extern gcry_md_spec_t _gcry_digest_spec_blake2s_224;
+extern gcry_md_spec_t _gcry_digest_spec_blake2s_160;
+extern gcry_md_spec_t _gcry_digest_spec_blake2s_128;
+extern gcry_md_spec_t _gcry_digest_spec_sm3;
+
+/* Declarations for the pubkey cipher specifications. */
+extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_elg;
+extern gcry_pk_spec_t _gcry_pubkey_spec_elg_e;
+extern gcry_pk_spec_t _gcry_pubkey_spec_dsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_ecc;
+
+
+#endif /*G10_CIPHER_H*/
diff --git a/comm/third_party/libgcrypt/src/context.c b/comm/third_party/libgcrypt/src/context.c
new file mode 100644
index 0000000000..f77878bc54
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/context.c
@@ -0,0 +1,137 @@
+/* context.c - Context management
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "context.h"
+
+#define CTX_MAGIC "cTx"
+#define CTX_MAGIC_LEN 3
+
+
+/* The definition of the generic context object. The public typedef
+ gcry_ctx_t is used to access it. */
+struct gcry_context
+{
+ char magic[CTX_MAGIC_LEN]; /* Magic value to cross check that this
+ is really a context object. */
+ char type; /* The type of the context (CONTEXT_TYPE_foo). */
+
+ void (*deinit)(void*); /* Function used to free the private part. */
+ PROPERLY_ALIGNED_TYPE u;
+};
+
+
+/* Allocate a fresh generic context of contect TYPE and allocate
+ LENGTH extra bytes for private use of the type handler. DEINIT is a
+ function used called to deinitialize the private part; it may be
+ NULL if de-initialization is not required. Returns NULL and sets
+ ERRNO if memory allocation failed. */
+gcry_ctx_t
+_gcry_ctx_alloc (int type, size_t length, void (*deinit)(void*))
+{
+ gcry_ctx_t ctx;
+
+ switch (type)
+ {
+ case CONTEXT_TYPE_EC:
+ break;
+ default:
+ log_bug ("bad context type %d given to _gcry_ctx_alloc\n", type);
+ break;
+ }
+
+ if (length < sizeof (PROPERLY_ALIGNED_TYPE))
+ length = sizeof (PROPERLY_ALIGNED_TYPE);
+
+ ctx = xtrycalloc (1, sizeof *ctx - sizeof (PROPERLY_ALIGNED_TYPE) + length);
+ if (!ctx)
+ return NULL;
+ memcpy (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN);
+ ctx->type = type;
+ ctx->deinit = deinit;
+
+ return ctx;
+}
+
+
+/* Return a pointer to the private part of the context CTX. TYPE is
+ the requested context type. Using an explicit type allows to cross
+ check the type and eventually allows to store several private
+ contexts in one context object. The function does not return an
+ error but aborts if the provided CTX is not valid. */
+void *
+_gcry_ctx_get_pointer (gcry_ctx_t ctx, int type)
+{
+ if (!ctx || memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
+ log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx);
+ if (ctx->type != type)
+ log_fatal ("wrong context type %d request for context %p of type %d\n",
+ type, ctx, ctx->type);
+ return &ctx->u;
+}
+
+/* Return a pointer to the private part of the context CTX. TYPE is
+ the requested context type. Using an explicit type allows to cross
+ check the type and eventually allows to store several private
+ contexts in one context object. In contrast to
+ _gcry_ctx_get_pointer, this function returns NULL if no context for
+ the given type was found. If CTX is NULL the function does not
+ abort but returns NULL. */
+void *
+_gcry_ctx_find_pointer (gcry_ctx_t ctx, int type)
+{
+ if (!ctx)
+ return NULL;
+ if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
+ log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx);
+ if (ctx->type != type)
+ return NULL;
+ return &ctx->u;
+}
+
+
+/* Release the generic context CTX. */
+void
+_gcry_ctx_release (gcry_ctx_t ctx)
+{
+ if (!ctx)
+ return;
+ if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
+ log_fatal ("bad pointer %p passed to gcry_ctx_relase\n", ctx);
+ switch (ctx->type)
+ {
+ case CONTEXT_TYPE_EC:
+ break;
+ default:
+ log_fatal ("bad context type %d detected in gcry_ctx_relase\n",
+ ctx->type);
+ break;
+ }
+ if (ctx->deinit)
+ ctx->deinit (&ctx->u);
+ xfree (ctx);
+}
diff --git a/comm/third_party/libgcrypt/src/context.h b/comm/third_party/libgcrypt/src/context.h
new file mode 100644
index 0000000000..875de24396
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/context.h
@@ -0,0 +1,32 @@
+/* context.h - Declarations for the context management
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_CONTEXT_H
+#define GCRY_CONTEXT_H
+
+/* Context types as used in struct gcry_context. */
+#define CONTEXT_TYPE_EC 1 /* The context is used with EC functions. */
+
+
+gcry_ctx_t _gcry_ctx_alloc (int type, size_t length, void (*deinit)(void*));
+void *_gcry_ctx_get_pointer (gcry_ctx_t ctx, int type);
+void *_gcry_ctx_find_pointer (gcry_ctx_t ctx, int type);
+
+
+#endif /*GCRY_CONTEXT_H*/
diff --git a/comm/third_party/libgcrypt/src/dumpsexp.c b/comm/third_party/libgcrypt/src/dumpsexp.c
new file mode 100644
index 0000000000..cedc4f4b47
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/dumpsexp.c
@@ -0,0 +1,768 @@
+/* dumpsexp.c - Dump S-expressions.
+ * Copyright (C) 2007, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2010 g10 Code GmbH.
+ *
+ * This program 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.
+ *
+ * This program 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <errno.h>
+/* For a native WindowsCE binary we need to include gpg-error.h to
+ provide a replacement for strerror. */
+#ifdef __MINGW32CE__
+# include <gpg-error.h>
+#endif
+
+#define PGM "dumpsexp"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+
+static int verbose; /* Verbose mode. */
+static int decimal; /* Print addresses in decimal. */
+static int assume_hex; /* Assume input is hexencoded. */
+static int advanced; /* Advanced format output. */
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2010 Free Software Foundation, Inc.\n"
+ "License LGPLv2.1+: GNU LGPL version 2.1 or later "
+ "<http://gnu.org/licenses/>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] [file]\n"
+ "Debug tool for S-expressions\n"
+ "\n"
+ " --decimal Print offsets using decimal notation\n"
+ " --assume-hex Assume input is a hex dump\n"
+ " --advanced Print file in advanced format\n"
+ " --verbose Show what we are doing\n"
+ " --version Print version of the program and exit\n"
+ " --help Display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+#define space_p(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
+#define digit_p(a) ((a) >= '0' && (a) <= '9')
+#define octdigit_p(a) ((a) >= '0' && (a) <= '7')
+#define alpha_p(a) ( ((a) >= 'A' && (a) <= 'Z') \
+ || ((a) >= 'a' && (a) <= 'z'))
+#define hexdigit_p(a) (digit_p (a) \
+ || ((a) >= 'A' && (a) <= 'F') \
+ || ((a) >= 'a' && (a) <= 'f'))
+#define xtoi_1(a) ((a) <= '9'? ((a)- '0'): \
+ (a) <= 'F'? ((a)-'A'+10):((a)-'a'+10))
+
+
+/* Return true if P points to a byte containing a whitespace according
+ to the S-expressions definition. */
+static inline int
+whitespace_p (int c)
+{
+ switch (c)
+ {
+ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
+ default: return 0;
+ }
+}
+
+static void
+logit (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ va_end (arg_ptr);
+}
+
+/* The raw data buffer and its current length */
+static unsigned char databuffer[16];
+static int databufferlen;
+/* The number of bytes in databuffer which should be skipped at a flush. */
+static int skipdatabufferlen;
+/* The number of raw bytes printed on the last line. */
+static int nbytesprinted;
+/* The file offset of the current data buffer . */
+static unsigned long databufferoffset;
+
+
+
+static int
+my_getc (FILE *fp)
+{
+ int c1, c2;
+
+ if (!assume_hex)
+ return getc (fp);
+
+ while ( (c1=getc (fp)) != EOF && space_p (c1) )
+ ;
+ if (c1 == EOF)
+ return EOF;
+
+ if (!hexdigit_p (c1))
+ {
+ logit ("non hex-digit encountered\n");
+ return EOF;
+ }
+
+ while ( (c2=getc (fp)) != EOF && space_p (c2) )
+ ;
+ if (c2 == EOF)
+ {
+ logit ("error reading second hex nibble\n");
+ return EOF;
+ }
+ if (!hexdigit_p (c2))
+ {
+ logit ("second hex nibble is not a hex-digit\n");
+ return EOF;
+ }
+ return xtoi_1 (c1) * 16 + xtoi_1 (c2);
+}
+
+
+
+
+
+/* Flush the raw data buffer. */
+static void
+flushdatabuffer (void)
+{
+ int i;
+
+ if (!databufferlen)
+ return;
+ nbytesprinted = 0;
+ if (decimal)
+ printf ("%08lu ", databufferoffset);
+ else
+ printf ("%08lx ", databufferoffset);
+ for (i=0; i < databufferlen; i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ if (i < skipdatabufferlen)
+ fputs (" ", stdout);
+ else
+ {
+ printf (" %02x", databuffer[i]);
+ databufferoffset++;
+ }
+ nbytesprinted++;
+ }
+ for (; i < sizeof (databuffer); i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ fputs (" ", stdout);
+ }
+ fputs (" |", stdout);
+ for (i=0; i < databufferlen; i++)
+ {
+ if (i < skipdatabufferlen)
+ putchar (' ');
+ else if (databuffer[i] >= ' ' && databuffer[i] <= '~'
+ && databuffer[i] != '|')
+ putchar (databuffer[i]);
+ else
+ putchar ('.');
+ }
+ putchar ('|');
+ putchar ('\n');
+ databufferlen = 0;
+ skipdatabufferlen = 0;
+}
+
+
+/* Add C to the raw data buffer and flush as needed. */
+static void
+addrawdata (int c)
+{
+ if ( databufferlen >= sizeof databuffer )
+ flushdatabuffer ();
+ databuffer[databufferlen++] = c;
+}
+
+
+static void
+printcursor (int both)
+{
+ int i;
+
+ flushdatabuffer ();
+ printf ("%8s ", "");
+ for (i=0; i < sizeof (databuffer); i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ if (i+1 == nbytesprinted)
+ {
+ fputs (" ^ ", stdout);
+ if (!both)
+ break;
+ }
+ else
+ fputs (" ", stdout);
+ }
+ if (both)
+ {
+ fputs (" ", stdout);
+ for (i=0; i < nbytesprinted-1; i++)
+ putchar (' ');
+ putchar ('^');
+ }
+ databufferlen = skipdatabufferlen = nbytesprinted;
+}
+
+static void
+printerr (const char *text)
+{
+ printcursor (1);
+ printf ("\n Error: %s\n", text);
+}
+
+static void
+printctl (const char *text)
+{
+ if (verbose && !advanced)
+ {
+ printcursor (0);
+ printf ("%s\n", text);
+ }
+}
+
+static void
+printchr (int c)
+{
+ putchar (c);
+}
+
+/* static void */
+/* printhex (int c) */
+/* { */
+/* printf ("\\x%02x", c); */
+/* } */
+
+
+#if 0
+/****************
+ * Print SEXP to buffer using the MODE. Returns the length of the
+ * SEXP in buffer or 0 if the buffer is too short (We have at least an
+ * empty list consisting of 2 bytes). If a buffer of NULL is provided,
+ * the required length is returned.
+ */
+size_t
+gcry_sexp_sprint (const gcry_sexp_t list,
+ void *buffer, size_t maxlength )
+{
+ static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
+ const unsigned char *s;
+ char *d;
+ DATALEN n;
+ char numbuf[20];
+ int i, indent = 0;
+
+ s = list? list->d : empty;
+ d = buffer;
+ while ( *s != ST_STOP )
+ {
+ switch ( *s )
+ {
+ case ST_OPEN:
+ s++;
+ if (indent)
+ putchar ('\n');
+ for (i=0; i < indent; i++)
+ putchar (' ');
+ putchar ('(');
+ indent++;
+ break;
+ case ST_CLOSE:
+ s++;
+ putchar (')');
+ indent--;
+ if (*s != ST_OPEN && *s != ST_STOP)
+ {
+ putchar ('\n');
+ for (i=0; i < indent; i++)
+ putchar (' ');
+ }
+ break;
+ case ST_DATA:
+ s++;
+ memcpy (&n, s, sizeof n);
+ s += sizeof n;
+ {
+ int type;
+ size_t nn;
+
+ switch ( (type=suitable_encoding (s, n)))
+ {
+ case 1: nn = convert_to_string (s, n, NULL); break;
+ case 2: nn = convert_to_token (s, n, NULL); break;
+ default: nn = convert_to_hex (s, n, NULL); break;
+ }
+ switch (type)
+ {
+ case 1: convert_to_string (s, n, d); break;
+ case 2: convert_to_token (s, n, d); break;
+ default: convert_to_hex (s, n, d); break;
+ }
+ d += nn;
+ if (s[n] != ST_CLOSE)
+ putchar (' ');
+ }
+ else
+ {
+ snprintf (numbuf, sizeof numbuf, "%u:", (unsigned int)n );
+ d = stpcpy (d, numbuf);
+ memcpy (d, s, n);
+ d += n;
+ }
+ s += n;
+ break;
+ default:
+ BUG ();
+ }
+ }
+ putchar ('\n');
+ return len;
+}
+#endif
+
+
+/* Prepare for saving a chunk of data. */
+static void
+init_data (void)
+{
+
+}
+
+/* Push C on the current data chunk. */
+static void
+push_data (int c)
+{
+ (void)c;
+}
+
+/* Flush and thus print the current data chunk. */
+static void
+flush_data (void)
+{
+
+}
+
+
+/* Returns 0 on success. */
+static int
+parse_and_print (FILE *fp)
+{
+ static const char tokenchars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-./_:*+=";
+ int c;
+ int level = 0;
+ int tokenc = 0;
+ int hexcount = 0;
+ int disphint = 0;
+ unsigned long datalen = 0;
+ char quote_buf[10];
+ int quote_idx = 0;
+ enum
+ {
+ INIT_STATE = 0, IN_NUMBER, PRE_DATA, IN_DATA, IN_STRING,
+ IN_ESCAPE, IN_OCT_ESC, IN_HEX_ESC,
+ CR_ESC, LF_ESC, IN_HEXFMT, IN_BASE64
+ }
+ state = INIT_STATE;
+
+
+ while ((c = my_getc (fp)) != EOF )
+ {
+ addrawdata (c);
+ switch (state)
+ {
+ case INIT_STATE:
+ if (tokenc)
+ {
+ if (strchr (tokenchars, c))
+ {
+ printchr (c);
+ continue;
+ }
+ tokenc = 0;
+ }
+ parse_init_state:
+ if (c == '(')
+ {
+ if (disphint)
+ {
+ printerr ("unmatched display hint");
+ disphint = 0;
+ }
+ printctl ("open");
+ level++;
+ }
+ else if (c == ')')
+ {
+ if (disphint)
+ {
+ printerr ("unmatched display hint");
+ disphint = 0;
+ }
+ printctl ("close");
+ level--;
+ }
+ else if (c == '\"')
+ {
+ state = IN_STRING;
+ printctl ("beginstring");
+ init_data ();
+ }
+ else if (c == '#')
+ {
+ state = IN_HEXFMT;
+ hexcount = 0;
+ printctl ("beginhex");
+ init_data ();
+ }
+ else if (c == '|')
+ {
+ state = IN_BASE64;
+ printctl ("beginbase64");
+ init_data ();
+ }
+ else if (c == '[')
+ {
+ if (disphint)
+ printerr ("nested display hint");
+ disphint = c;
+ }
+ else if (c == ']')
+ {
+ if (!disphint)
+ printerr ("no open display hint");
+ disphint = 0;
+ }
+ else if (c >= '0' && c <= '9')
+ {
+ if (c == '0')
+ printerr ("zero prefixed length");
+ state = IN_NUMBER;
+ datalen = (c - '0');
+ }
+ else if (strchr (tokenchars, c))
+ {
+ printchr (c);
+ tokenc = c;
+ }
+ else if (whitespace_p (c))
+ ;
+ else if (c == '{')
+ {
+ printerr ("rescanning is not supported");
+ }
+ else if (c == '&' || c == '\\')
+ {
+ printerr ("reserved punctuation detected");
+ }
+ else
+ {
+ printerr ("bad character detected");
+ }
+ break;
+
+ case IN_NUMBER:
+ if (digit_p (c))
+ {
+ unsigned long tmp = datalen * 10 + (c - '0');
+ if (tmp < datalen)
+ {
+ printerr ("overflow in data length");
+ state = INIT_STATE;
+ datalen = 0;
+ }
+ else
+ datalen = tmp;
+ }
+ else if (c == ':')
+ {
+ if (!datalen)
+ {
+ printerr ("no data length");
+ state = INIT_STATE;
+ }
+ else
+ state = PRE_DATA;
+ }
+ else if (c == '\"' || c == '#' || c == '|' )
+ {
+ /* We ignore the optional length and divert to the init
+ state parser code. */
+ goto parse_init_state;
+ }
+ else
+ printerr ("invalid length specification");
+ break;
+
+ case PRE_DATA:
+ state = IN_DATA;
+ printctl ("begindata");
+ init_data ();
+ /* fall through */
+ case IN_DATA:
+ if (datalen)
+ {
+ push_data (c);
+ datalen--;
+ }
+ if (!datalen)
+ {
+ state = INIT_STATE;
+ printctl ("enddata");
+ flush_data ();
+ }
+ break;
+
+ case IN_STRING:
+ if (c == '\"')
+ {
+ printctl ("endstring");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else if (c == '\\')
+ state = IN_ESCAPE;
+ else
+ push_data (c);
+ break;
+
+ case IN_ESCAPE:
+ switch (c)
+ {
+ case 'b': push_data ('\b'); state = IN_STRING; break;
+ case 't': push_data ('\t'); state = IN_STRING; break;
+ case 'v': push_data ('\v'); state = IN_STRING; break;
+ case 'n': push_data ('\n'); state = IN_STRING; break;
+ case 'f': push_data ('\f'); state = IN_STRING; break;
+ case 'r': push_data ('\r'); state = IN_STRING; break;
+ case '"': push_data ('"'); state = IN_STRING; break;
+ case '\'': push_data ('\''); state = IN_STRING; break;
+ case '\\': push_data ('\\'); state = IN_STRING; break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ state = IN_OCT_ESC;
+ quote_idx = 0;
+ quote_buf[quote_idx++] = c;
+ break;
+
+ case 'x':
+ state = IN_HEX_ESC;
+ quote_idx = 0;
+ break;
+
+ case '\r':
+ state = CR_ESC;
+ break;
+
+ case '\n':
+ state = LF_ESC;
+ break;
+
+ default:
+ printerr ("invalid escape sequence");
+ state = IN_STRING;
+ break;
+ }
+ break;
+
+ case IN_OCT_ESC:
+ if (quote_idx < 3 && strchr ("01234567", c))
+ {
+ quote_buf[quote_idx++] = c;
+ if (quote_idx == 3)
+ {
+ push_data ((unsigned int)quote_buf[0] * 8 * 8
+ + (unsigned int)quote_buf[1] * 8
+ + (unsigned int)quote_buf[2]);
+ state = IN_STRING;
+ }
+ }
+ else
+ state = IN_STRING;
+ break;
+ case IN_HEX_ESC:
+ if (quote_idx < 2 && strchr ("0123456789abcdefABCDEF", c))
+ {
+ quote_buf[quote_idx++] = c;
+ if (quote_idx == 2)
+ {
+ push_data (xtoi_1 (quote_buf[0]) * 16
+ + xtoi_1 (quote_buf[1]));
+ state = IN_STRING;
+ }
+ }
+ else
+ state = IN_STRING;
+ break;
+ case CR_ESC:
+ state = IN_STRING;
+ break;
+ case LF_ESC:
+ state = IN_STRING;
+ break;
+
+ case IN_HEXFMT:
+ if (hexdigit_p (c))
+ {
+ push_data (c);
+ hexcount++;
+ }
+ else if (c == '#')
+ {
+ if ((hexcount & 1))
+ printerr ("odd number of hex digits");
+ printctl ("endhex");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else if (!whitespace_p (c))
+ printerr ("bad hex character");
+ break;
+
+ case IN_BASE64:
+ if (c == '|')
+ {
+ printctl ("endbase64");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else
+ push_data (c);
+ break;
+
+ default:
+ logit ("invalid state %d detected", state);
+ exit (1);
+ }
+ }
+ flushdatabuffer ();
+ if (ferror (fp))
+ {
+ logit ("error reading input: %s\n", strerror (errno));
+ return -1;
+ }
+ return 0;
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ int rc;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ argc--; argv++;
+ verbose = 1;
+ }
+ else if (!strcmp (*argv, "--decimal"))
+ {
+ argc--; argv++;
+ decimal = 1;
+ }
+ else if (!strcmp (*argv, "--assume-hex"))
+ {
+ argc--; argv++;
+ assume_hex = 1;
+ }
+ else if (!strcmp (*argv, "--advanced"))
+ {
+ argc--; argv++;
+ advanced = 1;
+ }
+ else
+ print_usage ();
+ }
+
+ if (!argc)
+ {
+ rc = parse_and_print (stdin);
+ }
+ else
+ {
+ rc = 0;
+ for (; argc; argv++, argc--)
+ {
+ FILE *fp = fopen (*argv, "rb");
+ if (!fp)
+ {
+ logit ("can't open `%s': %s\n", *argv, strerror (errno));
+ rc = 1;
+ }
+ else
+ {
+ if (parse_and_print (fp))
+ rc = 1;
+ fclose (fp);
+ }
+ }
+ }
+
+ return !!rc;
+}
diff --git a/comm/third_party/libgcrypt/src/ec-context.h b/comm/third_party/libgcrypt/src/ec-context.h
new file mode 100644
index 0000000000..d1c6480413
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/ec-context.h
@@ -0,0 +1,106 @@
+/* ec-context.h - Private definitions for CONTEXT_TYPE_EC.
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_EC_CONTEXT_H
+#define GCRY_EC_CONTEXT_H
+
+/* This context is used with all our EC functions. */
+struct mpi_ec_ctx_s
+{
+ enum gcry_mpi_ec_models model; /* The model describing this curve. */
+
+ enum ecc_dialects dialect; /* The ECC dialect used with the curve. */
+
+ int flags; /* Public key flags (not always used). */
+
+ unsigned int nbits; /* Number of bits. */
+
+ /* Domain parameters. Note that they may not all be set and if set
+ the MPIs may be flaged as constant. */
+ gcry_mpi_t p; /* Prime specifying the field GF(p). */
+ gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */
+ gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */
+ gcry_mpi_point_t G; /* Base point (generator). */
+ gcry_mpi_t n; /* Order of G. */
+ unsigned int h; /* Cofactor. */
+
+ /* The actual key. May not be set. */
+ gcry_mpi_point_t Q; /* Public key. */
+ gcry_mpi_t d; /* Private key. */
+
+ const char *name; /* Name of the curve. */
+
+ /* This structure is private to mpi/ec.c! */
+ struct {
+ struct {
+ unsigned int a_is_pminus3:1;
+ unsigned int two_inv_p:1;
+ } valid; /* Flags to help setting the helper vars below. */
+
+ int a_is_pminus3; /* True if A = P - 3. */
+
+ gcry_mpi_t two_inv_p;
+
+ mpi_barrett_t p_barrett;
+
+ /* Scratch variables. */
+ gcry_mpi_t scratch[11];
+
+ /* Helper for fast reduction. */
+ /* int nist_nbits; /\* If this is a NIST curve, the # of bits. *\/ */
+ /* gcry_mpi_t s[10]; */
+ /* gcry_mpi_t c; */
+ } t;
+
+ /* Curve specific computation routines for the field. */
+ void (* addm) (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx);
+ void (* subm) (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec);
+ void (* mulm) (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx);
+ void (* pow2) (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx);
+ void (* mul2) (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx);
+};
+
+
+/*-- mpi/ec.c --*/
+void _gcry_mpi_ec_get_reset (mpi_ec_t ec);
+
+
+/*-- cipher/ecc-curves.c --*/
+gcry_mpi_t _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy);
+gcry_mpi_point_t _gcry_ecc_get_point (const char *name, mpi_ec_t ec);
+gpg_err_code_t _gcry_ecc_set_mpi (const char *name,
+ gcry_mpi_t newvalue, mpi_ec_t ec);
+gpg_err_code_t _gcry_ecc_set_point (const char *name,
+ gcry_mpi_point_t newvalue, mpi_ec_t ec);
+
+/*-- cipher/ecc-misc.c --*/
+gpg_err_code_t _gcry_ecc_sec_decodepoint (gcry_mpi_t value, mpi_ec_t ec,
+ mpi_point_t result);
+gpg_err_code_t _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx,
+ mpi_point_t result);
+
+/*-- cipher/ecc-eddsa.c --*/
+gpg_err_code_t _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx,
+ mpi_point_t result,
+ unsigned char **r_encpk,
+ unsigned int *r_encpklen);
+
+
+
+#endif /*GCRY_EC_CONTEXT_H*/
diff --git a/comm/third_party/libgcrypt/src/fips.c b/comm/third_party/libgcrypt/src/fips.c
new file mode 100644
index 0000000000..2facc45034
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/fips.c
@@ -0,0 +1,884 @@
+/* fips.c - FIPS mode management
+ * Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef ENABLE_HMAC_BINARY_CHECK
+# include <dlfcn.h>
+#endif
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+
+#include "g10lib.h"
+#include "cipher-proto.h"
+#include "hmac256.h"
+
+
+/* The name of the file used to force libgcrypt into fips mode. */
+#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
+
+
+/* The states of the finite state machine used in fips mode. */
+enum module_states
+ {
+ /* POWEROFF cannot be represented. */
+ STATE_POWERON = 0,
+ STATE_INIT,
+ STATE_SELFTEST,
+ STATE_OPERATIONAL,
+ STATE_ERROR,
+ STATE_FATALERROR,
+ STATE_SHUTDOWN
+ };
+
+
+/* Flag telling whether we are in fips mode. It uses inverse logic so
+ that fips mode is the default unless changed by the initialization
+ code. To check whether fips mode is enabled, use the function
+ fips_mode()! */
+int _gcry_no_fips_mode_required;
+
+/* Flag to indicate that we are in the enforced FIPS mode. */
+static int enforced_fips_mode;
+
+/* If this flag is set, the application may no longer assume that the
+ process is running in FIPS mode. This flag is protected by the
+ FSM_LOCK. */
+static int inactive_fips_mode;
+
+/* This is the lock we use to protect the FSM. */
+GPGRT_LOCK_DEFINE (fsm_lock);
+
+/* The current state of the FSM. The whole state machinery is only
+ used while in fips mode. Change this only while holding fsm_lock. */
+static enum module_states current_state;
+
+
+
+
+
+static void fips_new_state (enum module_states new_state);
+
+
+
+/* Convert lowercase hex digits; assumes valid hex digits. */
+#define loxtoi_1(p) (*(p) <= '9'? (*(p)- '0'): (*(p)-'a'+10))
+#define loxtoi_2(p) ((loxtoi_1(p) * 16) + loxtoi_1((p)+1))
+
+/* Returns true if P points to a lowercase hex digit. */
+#define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p))
+
+
+
+/* Check whether the OS is in FIPS mode and record that in a module
+ local variable. If FORCE is passed as true, fips mode will be
+ enabled anyway. Note: This function is not thread-safe and should
+ be called before any threads are created. This function may only
+ be called once. */
+void
+_gcry_initialize_fips_mode (int force)
+{
+ static int done;
+ gpg_error_t err;
+
+ /* Make sure we are not accidentally called twice. */
+ if (done)
+ {
+ if ( fips_mode () )
+ {
+ fips_new_state (STATE_FATALERROR);
+ fips_noreturn ();
+ }
+ /* If not in fips mode an assert is sufficient. */
+ gcry_assert (!done);
+ }
+ done = 1;
+
+ /* If the calling application explicitly requested fipsmode, do so. */
+ if (force)
+ {
+ gcry_assert (!_gcry_no_fips_mode_required);
+ goto leave;
+ }
+
+ /* For testing the system it is useful to override the system
+ provided detection of the FIPS mode and force FIPS mode using a
+ file. The filename is hardwired so that there won't be any
+ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
+ actually used. The file itself may be empty. */
+ if ( !access (FIPS_FORCE_FILE, F_OK) )
+ {
+ gcry_assert (!_gcry_no_fips_mode_required);
+ goto leave;
+ }
+
+ /* Checking based on /proc file properties. */
+ {
+ static const char procfname[] = "/proc/sys/crypto/fips_enabled";
+ FILE *fp;
+ int saved_errno;
+
+ fp = fopen (procfname, "r");
+ if (fp)
+ {
+ char line[256];
+
+ if (fgets (line, sizeof line, fp) && atoi (line))
+ {
+ /* System is in fips mode. */
+ fclose (fp);
+ gcry_assert (!_gcry_no_fips_mode_required);
+ goto leave;
+ }
+ fclose (fp);
+ }
+ else if ((saved_errno = errno) != ENOENT
+ && saved_errno != EACCES
+ && !access ("/proc/version", F_OK) )
+ {
+ /* Problem reading the fips file despite that we have the proc
+ file system. We better stop right away. */
+ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n",
+ procfname, strerror (saved_errno));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "reading `%s' failed: %s - abort",
+ procfname, strerror (saved_errno));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+ }
+
+ /* Fips not not requested, set flag. */
+ _gcry_no_fips_mode_required = 1;
+
+ leave:
+ if (!_gcry_no_fips_mode_required)
+ {
+ /* Yes, we are in FIPS mode. */
+ FILE *fp;
+
+ /* Intitialize the lock to protect the FSM. */
+ err = gpgrt_lock_init (&fsm_lock);
+ if (err)
+ {
+ /* If that fails we can't do anything but abort the
+ process. We need to use log_info so that the FSM won't
+ get involved. */
+ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
+ gpg_strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "creating FSM lock failed: %s - abort",
+ gpg_strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+
+
+ /* If the FIPS force files exists, is readable and has a number
+ != 0 on its first line, we enable the enforced fips mode. */
+ fp = fopen (FIPS_FORCE_FILE, "r");
+ if (fp)
+ {
+ char line[256];
+
+ if (fgets (line, sizeof line, fp) && atoi (line))
+ enforced_fips_mode = 1;
+ fclose (fp);
+ }
+
+ /* Now get us into the INIT state. */
+ fips_new_state (STATE_INIT);
+
+ }
+ return;
+}
+
+static void
+lock_fsm (void)
+{
+ gpg_error_t err;
+
+ err = gpgrt_lock_lock (&fsm_lock);
+ if (err)
+ {
+ log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n",
+ gpg_strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "acquiring FSM lock failed: %s - abort",
+ gpg_strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+}
+
+static void
+unlock_fsm (void)
+{
+ gpg_error_t err;
+
+ err = gpgrt_lock_unlock (&fsm_lock);
+ if (err)
+ {
+ log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n",
+ gpg_strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "releasing FSM lock failed: %s - abort",
+ gpg_strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+}
+
+
+/* Return a flag telling whether we are in the enforced fips mode. */
+int
+_gcry_enforced_fips_mode (void)
+{
+ if (!fips_mode ())
+ return 0;
+ return enforced_fips_mode;
+}
+
+/* Set a flag telling whether we are in the enforced fips mode. */
+void
+_gcry_set_enforced_fips_mode (void)
+{
+ enforced_fips_mode = 1;
+}
+
+/* If we do not want to enforce the fips mode, we can set a flag so
+ that the application may check whether it is still in fips mode.
+ TEXT will be printed as part of a syslog message. This function
+ may only be be called if in fips mode. */
+void
+_gcry_inactivate_fips_mode (const char *text)
+{
+ gcry_assert (fips_mode ());
+
+ if (_gcry_enforced_fips_mode () )
+ {
+ /* Get us into the error state. */
+ fips_signal_error (text);
+ return;
+ }
+
+ lock_fsm ();
+ if (!inactive_fips_mode)
+ {
+ inactive_fips_mode = 1;
+ unlock_fsm ();
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+ "%s - FIPS mode inactivated", text);
+#endif /*HAVE_SYSLOG*/
+ }
+ else
+ unlock_fsm ();
+}
+
+
+/* Return the FIPS mode inactive flag. If it is true the FIPS mode is
+ not anymore active. */
+int
+_gcry_is_fips_mode_inactive (void)
+{
+ int flag;
+
+ if (!fips_mode ())
+ return 0;
+ lock_fsm ();
+ flag = inactive_fips_mode;
+ unlock_fsm ();
+ return flag;
+}
+
+
+
+static const char *
+state2str (enum module_states state)
+{
+ const char *s;
+
+ switch (state)
+ {
+ case STATE_POWERON: s = "Power-On"; break;
+ case STATE_INIT: s = "Init"; break;
+ case STATE_SELFTEST: s = "Self-Test"; break;
+ case STATE_OPERATIONAL: s = "Operational"; break;
+ case STATE_ERROR: s = "Error"; break;
+ case STATE_FATALERROR: s = "Fatal-Error"; break;
+ case STATE_SHUTDOWN: s = "Shutdown"; break;
+ default: s = "?"; break;
+ }
+ return s;
+}
+
+
+/* Return true if the library is in the operational state. */
+int
+_gcry_fips_is_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ if (current_state == STATE_INIT)
+ {
+ /* If we are still in the INIT state, we need to run the
+ selftests so that the FSM can eventually get into
+ operational state. Given that we would need a 2-phase
+ initialization of libgcrypt, but that has traditionally
+ not been enforced, we use this on demand self-test
+ checking. Note that Proper applications would do the
+ application specific libgcrypt initialization between a
+ gcry_check_version() and gcry_control
+ (GCRYCTL_INITIALIZATION_FINISHED) where the latter will
+ run the selftests. The drawback of these on-demand
+ self-tests are a small chance that self-tests are
+ performed by several threads; that is no problem because
+ our FSM make sure that we won't oversee any error. */
+ unlock_fsm ();
+ _gcry_fips_run_selftests (0);
+ lock_fsm ();
+ }
+
+ result = (current_state == STATE_OPERATIONAL);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+/* This is test on whether the library is in the operational state. In
+ contrast to _gcry_fips_is_operational this function won't do a
+ state transition on the fly. */
+int
+_gcry_fips_test_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ result = (current_state == STATE_OPERATIONAL);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+/* This is a test on whether the library is in the error or
+ operational state. */
+int
+_gcry_fips_test_error_or_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ result = (current_state == STATE_OPERATIONAL
+ || current_state == STATE_ERROR);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+static void
+reporter (const char *domain, int algo, const char *what, const char *errtxt)
+{
+ if (!errtxt && !_gcry_log_verbosity (2))
+ return;
+
+ log_info ("libgcrypt selftest: %s %s%s (%d): %s%s%s%s\n",
+ !strcmp (domain, "hmac")? "digest":domain,
+ !strcmp (domain, "hmac")? "HMAC-":"",
+ !strcmp (domain, "cipher")? _gcry_cipher_algo_name (algo) :
+ !strcmp (domain, "digest")? _gcry_md_algo_name (algo) :
+ !strcmp (domain, "hmac")? _gcry_md_algo_name (algo) :
+ !strcmp (domain, "pubkey")? _gcry_pk_algo_name (algo) : "",
+ algo, errtxt? errtxt:"Okay",
+ what?" (":"", what? what:"", what?")":"");
+}
+
+/* Run self-tests for all required cipher algorithms. Return 0 on
+ success. */
+static int
+run_cipher_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_CIPHER_3DES,
+ GCRY_CIPHER_AES128,
+ GCRY_CIPHER_AES192,
+ GCRY_CIPHER_AES256,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_cipher_selftest (algos[idx], extended, reporter);
+ reporter ("cipher", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for all required hash algorithms. Return 0 on
+ success. */
+static int
+run_digest_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_MD_SHA1,
+ GCRY_MD_SHA224,
+ GCRY_MD_SHA256,
+ GCRY_MD_SHA384,
+ GCRY_MD_SHA512,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_md_selftest (algos[idx], extended, reporter);
+ reporter ("digest", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for MAC algorithms. Return 0 on success. */
+static int
+run_mac_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_MAC_HMAC_SHA1,
+ GCRY_MAC_HMAC_SHA224,
+ GCRY_MAC_HMAC_SHA256,
+ GCRY_MAC_HMAC_SHA384,
+ GCRY_MAC_HMAC_SHA512,
+ GCRY_MAC_HMAC_SHA3_224,
+ GCRY_MAC_HMAC_SHA3_256,
+ GCRY_MAC_HMAC_SHA3_384,
+ GCRY_MAC_HMAC_SHA3_512,
+ GCRY_MAC_CMAC_3DES,
+ GCRY_MAC_CMAC_AES,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_mac_selftest (algos[idx], extended, reporter);
+ reporter ("mac", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+/* Run self-tests for all KDF algorithms. Return 0 on success. */
+static int
+run_kdf_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_KDF_PBKDF2,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_kdf_selftest (algos[idx], extended, reporter);
+ reporter ("kdf", algos[idx], NULL, err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for all required public key algorithms. Return 0 on
+ success. */
+static int
+run_pubkey_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_PK_RSA,
+ GCRY_PK_DSA,
+ GCRY_PK_ECC,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_pk_selftest (algos[idx], extended, reporter);
+ reporter ("pubkey", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for the random number generator. Returns 0 on
+ success. */
+static int
+run_random_selftests (void)
+{
+ gpg_error_t err;
+
+ err = _gcry_random_selftest (reporter);
+ reporter ("random", 0, NULL, err? gpg_strerror (err):NULL);
+
+ return !!err;
+}
+
+/* Run an integrity check on the binary. Returns 0 on success. */
+static int
+check_binary_integrity (void)
+{
+#ifdef ENABLE_HMAC_BINARY_CHECK
+ gpg_error_t err;
+ Dl_info info;
+ unsigned char digest[32];
+ int dlen;
+ char *fname = NULL;
+ const char key[] = "What am I, a doctor or a moonshuttle conductor?";
+
+ if (!dladdr ("gcry_check_version", &info))
+ err = gpg_error_from_syserror ();
+ else
+ {
+ dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname,
+ key, strlen (key));
+ if (dlen < 0)
+ err = gpg_error_from_syserror ();
+ else if (dlen != 32)
+ err = gpg_error (GPG_ERR_INTERNAL);
+ else
+ {
+ fname = xtrymalloc (strlen (info.dli_fname) + 1 + 5 + 1 );
+ if (!fname)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ FILE *fp;
+ char *p;
+
+ /* Prefix the basename with a dot. */
+ strcpy (fname, info.dli_fname);
+ p = strrchr (fname, '/');
+ if (p)
+ p++;
+ else
+ p = fname;
+ memmove (p+1, p, strlen (p)+1);
+ *p = '.';
+ strcat (fname, ".hmac");
+
+ /* Open the file. */
+ fp = fopen (fname, "r");
+ if (!fp)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ /* A buffer of 64 bytes plus one for a LF and one to
+ detect garbage. */
+ unsigned char buffer[64+1+1];
+ const unsigned char *s;
+ int n;
+
+ /* The HMAC files consists of lowercase hex digits
+ with an optional trailing linefeed or optional
+ with two trailing spaces. The latter format
+ allows the use of the usual sha1sum format. Fail
+ if there is any garbage. */
+ err = gpg_error (GPG_ERR_SELFTEST_FAILED);
+ n = fread (buffer, 1, sizeof buffer, fp);
+ if (n == 64
+ || (n == 65 && buffer[64] == '\n')
+ || (n == 66 && buffer[64] == ' ' && buffer[65] == ' '))
+ {
+ buffer[64] = 0;
+ for (n=0, s= buffer;
+ n < 32 && loxdigit_p (s) && loxdigit_p (s+1);
+ n++, s += 2)
+ buffer[n] = loxtoi_2 (s);
+ if ( n == 32 && !memcmp (digest, buffer, 32) )
+ err = 0;
+ }
+ fclose (fp);
+ }
+ }
+ }
+ }
+ reporter ("binary", 0, fname, err? gpg_strerror (err):NULL);
+#ifdef HAVE_SYSLOG
+ if (err)
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "integrity check using `%s' failed: %s",
+ fname? fname:"[?]", gpg_strerror (err));
+#endif /*HAVE_SYSLOG*/
+ xfree (fname);
+ return !!err;
+#else
+ return 0;
+#endif
+}
+
+
+/* Run the self-tests. If EXTENDED is true, extended versions of the
+ selftest are run, that is more tests than required by FIPS. */
+gpg_err_code_t
+_gcry_fips_run_selftests (int extended)
+{
+ enum module_states result = STATE_ERROR;
+ gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
+
+ if (fips_mode ())
+ fips_new_state (STATE_SELFTEST);
+
+ if (run_cipher_selftests (extended))
+ goto leave;
+
+ if (run_digest_selftests (extended))
+ goto leave;
+
+ if (run_mac_selftests (extended))
+ goto leave;
+
+ if (run_kdf_selftests (extended))
+ goto leave;
+
+ /* Run random tests before the pubkey tests because the latter
+ require random. */
+ if (run_random_selftests ())
+ goto leave;
+
+ if (run_pubkey_selftests (extended))
+ goto leave;
+
+ if (fips_mode ())
+ {
+ /* Now check the integrity of the binary. We do this this after
+ having checked the HMAC code. */
+ if (check_binary_integrity ())
+ goto leave;
+ }
+
+ /* All selftests passed. */
+ result = STATE_OPERATIONAL;
+ ec = 0;
+
+ leave:
+ if (fips_mode ())
+ fips_new_state (result);
+
+ return ec;
+}
+
+
+/* This function is used to tell the FSM about errors in the library.
+ The FSM will be put into an error state. This function should not
+ be called directly but by one of the macros
+
+ fips_signal_error (description)
+ fips_signal_fatal_error (description)
+
+ where DESCRIPTION is a string describing the error. */
+void
+_gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc,
+ int is_fatal, const char *description)
+{
+ if (!fips_mode ())
+ return; /* Not required. */
+
+ /* Set new state before printing an error. */
+ fips_new_state (is_fatal? STATE_FATALERROR : STATE_ERROR);
+
+ /* Print error. */
+ log_info ("%serror in libgcrypt, file %s, line %d%s%s: %s\n",
+ is_fatal? "fatal ":"",
+ srcfile, srcline,
+ srcfunc? ", function ":"", srcfunc? srcfunc:"",
+ description? description : "no description available");
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "%serror in file %s, line %d%s%s: %s",
+ is_fatal? "fatal ":"",
+ srcfile, srcline,
+ srcfunc? ", function ":"", srcfunc? srcfunc:"",
+ description? description : "no description available");
+#endif /*HAVE_SYSLOG*/
+}
+
+
+/* Perform a state transition to NEW_STATE. If this is an invalid
+ transition, the module will go into a fatal error state. */
+static void
+fips_new_state (enum module_states new_state)
+{
+ int ok = 0;
+ enum module_states last_state;
+
+ lock_fsm ();
+
+ last_state = current_state;
+ switch (current_state)
+ {
+ case STATE_POWERON:
+ if (new_state == STATE_INIT
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_INIT:
+ if (new_state == STATE_SELFTEST
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_SELFTEST:
+ if (new_state == STATE_OPERATIONAL
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_OPERATIONAL:
+ if (new_state == STATE_SHUTDOWN
+ || new_state == STATE_SELFTEST
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_ERROR:
+ if (new_state == STATE_SHUTDOWN
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR
+ || new_state == STATE_SELFTEST)
+ ok = 1;
+ break;
+
+ case STATE_FATALERROR:
+ if (new_state == STATE_SHUTDOWN )
+ ok = 1;
+ break;
+
+ case STATE_SHUTDOWN:
+ /* We won't see any transition *from* Shutdown because the only
+ allowed new state is Power-Off and that one can't be
+ represented. */
+ break;
+
+ }
+
+ if (ok)
+ {
+ current_state = new_state;
+ }
+
+ unlock_fsm ();
+
+ if (!ok || _gcry_log_verbosity (2))
+ log_info ("libgcrypt state transition %s => %s %s\n",
+ state2str (last_state), state2str (new_state),
+ ok? "granted":"denied");
+
+ if (!ok)
+ {
+ /* Invalid state transition. Halting library. */
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR,
+ "Libgcrypt error: invalid state transition %s => %s",
+ state2str (last_state), state2str (new_state));
+#endif /*HAVE_SYSLOG*/
+ fips_noreturn ();
+ }
+ else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR)
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt notice: state transition %s => %s",
+ state2str (last_state), state2str (new_state));
+#endif /*HAVE_SYSLOG*/
+ }
+}
+
+
+
+
+/* This function should be called to ensure that the execution shall
+ not continue. */
+void
+_gcry_fips_noreturn (void)
+{
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application");
+#endif /*HAVE_SYSLOG*/
+ fflush (NULL);
+ abort ();
+ /*NOTREACHED*/
+}
diff --git a/comm/third_party/libgcrypt/src/g10lib.h b/comm/third_party/libgcrypt/src/g10lib.h
new file mode 100644
index 0000000000..243997ebaf
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/g10lib.h
@@ -0,0 +1,503 @@
+/* g10lib.h - Internal definitions for libgcrypt
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+ * 2007, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This header is to be used inside of libgcrypt in place of gcrypt.h.
+ This way we can better distinguish between internal and external
+ usage of gcrypt.h. */
+
+#ifndef G10LIB_H
+#define G10LIB_H 1
+
+#ifdef _GCRYPT_H
+#error gcrypt.h already included
+#endif
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+#error something is wrong with config.h
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "visibility.h"
+#include "types.h"
+
+
+
+
+/* Attribute handling macros. */
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
+#define JNLIB_GCC_M_FUNCTION 1
+#define JNLIB_GCC_A_NR __attribute__ ((noreturn))
+#define JNLIB_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a)))
+#define JNLIB_GCC_A_NR_PRINTF( f, a ) \
+ __attribute__ ((noreturn, format (printf,f,a)))
+#define GCC_ATTR_NORETURN __attribute__ ((__noreturn__))
+#else
+#define JNLIB_GCC_A_NR
+#define JNLIB_GCC_A_PRINTF( f, a )
+#define JNLIB_GCC_A_NR_PRINTF( f, a )
+#define GCC_ATTR_NORETURN
+#endif
+
+#if __GNUC__ >= 3
+/* According to glibc this attribute is available since 2.8 however we
+ better play safe and use it only with gcc 3 or newer. */
+#define GCC_ATTR_FORMAT_ARG(a) __attribute__ ((format_arg (a)))
+#else
+#define GCC_ATTR_FORMAT_ARG(a)
+#endif
+
+/* I am not sure since when the unused attribute is really supported.
+ In any case it it only needed for gcc versions which print a
+ warning. Thus let us require gcc >= 3.5. */
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 )
+#define GCC_ATTR_UNUSED __attribute__ ((unused))
+#else
+#define GCC_ATTR_UNUSED
+#endif
+
+#if __GNUC__ > 3
+#define NOINLINE_FUNC __attribute__((noinline))
+#else
+#define NOINLINE_FUNC
+#endif
+
+#if __GNUC__ >= 3
+#define LIKELY(expr) __builtin_expect( !!(expr), 1 )
+#define UNLIKELY(expr) __builtin_expect( !!(expr), 0 )
+#define CONSTANT_P(expr) __builtin_constant_p( expr )
+#else
+#define LIKELY(expr) (!!(expr))
+#define UNLIKELY(expr) (!!(expr))
+#define CONSTANT_P(expr) (0)
+#endif
+
+/* Gettext macros. */
+
+#define _(a) _gcry_gettext(a)
+#define N_(a) (a)
+
+/* Some handy macros */
+#ifndef STR
+#define STR(v) #v
+#endif
+#define STR2(v) STR(v)
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member) DIM(((type *)0)->member)
+
+#define my_isascii(c) (!((c) & 0x80))
+
+
+
+
+/*-- src/global.c -*/
+extern int _gcry_global_any_init_done;
+int _gcry_global_is_operational (void);
+gcry_err_code_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr);
+void _gcry_check_heap (const void *a);
+void _gcry_pre_syscall (void);
+void _gcry_post_syscall (void);
+int _gcry_get_debug_flag (unsigned int mask);
+
+char *_gcry_get_config (int mode, const char *what);
+
+/* Malloc functions and common wrapper macros. */
+void *_gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_realloc (void *a, size_t n);
+char *_gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_xrealloc (void *a, size_t n);
+char *_gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC;
+void _gcry_free (void *a);
+int _gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
+
+#define xtrymalloc(a) _gcry_malloc ((a))
+#define xtrycalloc(a,b) _gcry_calloc ((a),(b))
+#define xtrymalloc_secure(a) _gcry_malloc_secure ((a))
+#define xtrycalloc_secure(a,b) _gcry_calloc_secure ((a),(b))
+#define xtryrealloc(a,b) _gcry_realloc ((a),(b))
+#define xtrystrdup(a) _gcry_strdup ((a))
+#define xmalloc(a) _gcry_xmalloc ((a))
+#define xcalloc(a,b) _gcry_xcalloc ((a),(b))
+#define xmalloc_secure(a) _gcry_xmalloc_secure ((a))
+#define xcalloc_secure(a,b) _gcry_xcalloc_secure ((a),(b))
+#define xrealloc(a,b) _gcry_xrealloc ((a),(b))
+#define xstrdup(a) _gcry_xstrdup ((a))
+#define xfree(a) _gcry_free ((a))
+
+
+/*-- src/misc.c --*/
+
+#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
+void _gcry_bug (const char *file, int line,
+ const char *func) GCC_ATTR_NORETURN;
+void _gcry_assert_failed (const char *expr, const char *file, int line,
+ const char *func) GCC_ATTR_NORETURN;
+#else
+void _gcry_bug (const char *file, int line);
+void _gcry_assert_failed (const char *expr, const char *file, int line);
+#endif
+
+void _gcry_divide_by_zero (void) JNLIB_GCC_A_NR;
+
+const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1);
+void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR;
+void _gcry_logv (int level,
+ const char *fmt, va_list arg_ptr) JNLIB_GCC_A_PRINTF(2,0);
+void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3);
+void _gcry_log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
+void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
+void _gcry_log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_printhex (const char *text, const void *buffer, size_t length);
+void _gcry_log_printmpi (const char *text, gcry_mpi_t mpi);
+void _gcry_log_printsxp (const char *text, gcry_sexp_t sexp);
+
+void _gcry_set_log_verbosity( int level );
+int _gcry_log_verbosity( int level );
+
+
+#ifdef JNLIB_GCC_M_FUNCTION
+#define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ )
+#define gcry_assert(expr) (LIKELY(expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__))
+#elif __STDC_VERSION__ >= 199901L
+#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ )
+#define gcry_assert(expr) (LIKELY(expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__))
+#else
+#define BUG() _gcry_bug( __FILE__ , __LINE__ )
+#define gcry_assert(expr) (LIKELY(expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__))
+#endif
+
+
+#define log_bug _gcry_log_bug
+#define log_fatal _gcry_log_fatal
+#define log_error _gcry_log_error
+#define log_info _gcry_log_info
+#define log_debug _gcry_log_debug
+#define log_printf _gcry_log_printf
+#define log_printhex _gcry_log_printhex
+#define log_printmpi _gcry_log_printmpi
+#define log_printsxp _gcry_log_printsxp
+
+/* Compatibility macro. */
+#define log_mpidump _gcry_log_printmpi
+
+/* Tokeninze STRING and return a malloced array. */
+char **_gcry_strtokenize (const char *string, const char *delim);
+
+
+/*-- src/hwfeatures.c --*/
+#if defined(HAVE_CPU_ARCH_X86)
+
+#define HWF_PADLOCK_RNG (1 << 0)
+#define HWF_PADLOCK_AES (1 << 1)
+#define HWF_PADLOCK_SHA (1 << 2)
+#define HWF_PADLOCK_MMUL (1 << 3)
+
+#define HWF_INTEL_CPU (1 << 4)
+#define HWF_INTEL_FAST_SHLD (1 << 5)
+#define HWF_INTEL_BMI2 (1 << 6)
+#define HWF_INTEL_SSSE3 (1 << 7)
+#define HWF_INTEL_SSE4_1 (1 << 8)
+#define HWF_INTEL_PCLMUL (1 << 9)
+#define HWF_INTEL_AESNI (1 << 10)
+#define HWF_INTEL_RDRAND (1 << 11)
+#define HWF_INTEL_AVX (1 << 12)
+#define HWF_INTEL_AVX2 (1 << 13)
+#define HWF_INTEL_FAST_VPGATHER (1 << 14)
+#define HWF_INTEL_RDTSC (1 << 15)
+#define HWF_INTEL_SHAEXT (1 << 16)
+
+#elif defined(HAVE_CPU_ARCH_ARM)
+
+#define HWF_ARM_NEON (1 << 0)
+#define HWF_ARM_AES (1 << 1)
+#define HWF_ARM_SHA1 (1 << 2)
+#define HWF_ARM_SHA2 (1 << 3)
+#define HWF_ARM_PMULL (1 << 4)
+
+#elif defined(HAVE_CPU_ARCH_PPC)
+
+#define HWF_PPC_VCRYPTO (1 << 0)
+#define HWF_PPC_ARCH_3_00 (1 << 1)
+#define HWF_PPC_ARCH_2_07 (1 << 2)
+
+#elif defined(HAVE_CPU_ARCH_S390X)
+
+#define HWF_S390X_MSA (1 << 0)
+#define HWF_S390X_MSA_4 (1 << 1)
+#define HWF_S390X_MSA_8 (1 << 2)
+#define HWF_S390X_VX (1 << 3)
+
+#endif
+
+gpg_err_code_t _gcry_disable_hw_feature (const char *name);
+void _gcry_detect_hw_features (void);
+unsigned int _gcry_get_hw_features (void);
+const char *_gcry_enum_hw_features (int idx, unsigned int *r_feature);
+
+
+/*-- mpi/mpiutil.c --*/
+const char *_gcry_mpi_get_hw_config (void);
+
+
+/*-- cipher/pubkey.c --*/
+
+/* FIXME: shouldn't this go into mpi.h? */
+#ifndef mpi_powm
+#define mpi_powm(w,b,e,m) gcry_mpi_powm( (w), (b), (e), (m) )
+#endif
+
+/*-- primegen.c --*/
+gcry_err_code_t _gcry_primegen_init (void);
+gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg);
+gcry_mpi_t _gcry_generate_public_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg);
+gcry_err_code_t _gcry_generate_elg_prime (int mode,
+ unsigned int pbits,
+ unsigned int qbits,
+ gcry_mpi_t g,
+ gcry_mpi_t *r_prime,
+ gcry_mpi_t **factors);
+gcry_mpi_t _gcry_derive_x931_prime (const gcry_mpi_t xp,
+ const gcry_mpi_t xp1, const gcry_mpi_t xp2,
+ const gcry_mpi_t e,
+ gcry_mpi_t *r_p1, gcry_mpi_t *r_p2);
+gpg_err_code_t _gcry_generate_fips186_2_prime
+ (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen);
+gpg_err_code_t _gcry_generate_fips186_3_prime
+ (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen, int *r_hashalgo);
+
+gpg_err_code_t _gcry_fips186_4_prime_check (const gcry_mpi_t x,
+ unsigned int bits);
+
+
+/* Replacements of missing functions (missing-string.c). */
+#ifndef HAVE_STPCPY
+char *stpcpy (char *a, const char *b);
+#endif
+#ifndef HAVE_STRCASECMP
+int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE;
+#endif
+
+#include "../compat/libcompat.h"
+
+
+/* Macros used to rename missing functions. */
+#ifndef HAVE_STRTOUL
+#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c)))
+#endif
+#ifndef HAVE_MEMMOVE
+#define memmove(d, s, n) bcopy((s), (d), (n))
+#endif
+#ifndef HAVE_STRICMP
+#define stricmp(a,b) strcasecmp( (a), (b) )
+#endif
+#ifndef HAVE_ATEXIT
+#define atexit(a) (on_exit((a),0))
+#endif
+#ifndef HAVE_RAISE
+#define raise(a) kill(getpid(), (a))
+#endif
+
+
+/* Stack burning. */
+
+#ifdef HAVE_GCC_ASM_VOLATILE_MEMORY
+#define __gcry_burn_stack_dummy() asm volatile ("":::"memory")
+#else
+void __gcry_burn_stack_dummy (void);
+#endif
+
+void __gcry_burn_stack (unsigned int bytes);
+#define _gcry_burn_stack(bytes) \
+ do { __gcry_burn_stack (bytes); \
+ __gcry_burn_stack_dummy (); } while(0)
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+ macros may be used instead. For small constant length buffers,
+ memory wiping is inlined. For non-constant or large length buffers,
+ memory is wiped with memset through _gcry_fast_wipememory. */
+#define wipememory2(_ptr,_set,_len) do { \
+ if (!CONSTANT_P(_len) || _len > 64) { \
+ if (CONSTANT_P(_set) && (_set) == 0) \
+ _gcry_fast_wipememory((void *)_ptr, _len); \
+ else \
+ _gcry_fast_wipememory2((void *)_ptr, _set, _len); \
+ } else {\
+ volatile char *_vptr = (volatile char *)(_ptr); \
+ size_t _vlen = (_len); \
+ const unsigned char _vset = (_set); \
+ fast_wipememory2(_vptr, _vset, _vlen); \
+ while(_vlen) { *_vptr = (_vset); _vptr++; _vlen--; } \
+ } \
+ } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+void _gcry_fast_wipememory(void *ptr, size_t len);
+void _gcry_fast_wipememory2(void *ptr, int set, size_t len);
+
+#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
+ defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
+ defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS)
+typedef struct fast_wipememory_s
+{
+ u64 a;
+} __attribute__((packed, aligned(1), may_alias)) fast_wipememory_t;
+/* fast_wipememory may leave tail bytes unhandled, in which case tail bytes
+ are handled by wipememory. */
+# define fast_wipememory2(_vptr,_vset,_vlen) do { \
+ fast_wipememory_t _vset_long; \
+ if (_vlen < sizeof(fast_wipememory_t)) \
+ break; \
+ _vset_long.a = (_vset); \
+ _vset_long.a *= U64_C(0x0101010101010101); \
+ do { \
+ volatile fast_wipememory_t *_vptr_long = \
+ (volatile void *)_vptr; \
+ _vptr_long->a = _vset_long.a; \
+ _vlen -= sizeof(fast_wipememory_t); \
+ _vptr += sizeof(fast_wipememory_t); \
+ } while (_vlen >= sizeof(fast_wipememory_t)); \
+ } while (0)
+#else
+# define fast_wipememory2(_vptr,_vset,_vlen)
+#endif
+
+
+/* Digit predicates. */
+
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
+#define alphap(a) ( (*(a) >= 'A' && *(a) <= 'Z') \
+ || (*(a) >= 'a' && *(a) <= 'z'))
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+
+/* Init functions. */
+
+gcry_err_code_t _gcry_cipher_init (void);
+gcry_err_code_t _gcry_md_init (void);
+gcry_err_code_t _gcry_mac_init (void);
+gcry_err_code_t _gcry_pk_init (void);
+gcry_err_code_t _gcry_secmem_module_init (void);
+gcry_err_code_t _gcry_mpi_init (void);
+
+/* Memory management. */
+#define GCRY_ALLOC_FLAG_SECURE (1 << 0)
+#define GCRY_ALLOC_FLAG_XHINT (1 << 1) /* Called from xmalloc. */
+
+
+/*-- sexp.c --*/
+gcry_err_code_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, va_list arg_ptr);
+char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number);
+gpg_err_code_t _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
+ const char *list, va_list arg_ptr);
+
+
+/*-- fips.c --*/
+
+extern int _gcry_no_fips_mode_required;
+
+void _gcry_initialize_fips_mode (int force);
+
+/* This macro returns true if fips mode is enabled. This is
+ independent of the fips required finite state machine and only used
+ to enable fips specific code.
+
+ No locking is required because we have the requirement that this
+ variable is only initialized once with no other threads
+ existing. */
+#define fips_mode() (!_gcry_no_fips_mode_required)
+
+int _gcry_enforced_fips_mode (void);
+
+void _gcry_set_enforced_fips_mode (void);
+
+void _gcry_inactivate_fips_mode (const char *text);
+int _gcry_is_fips_mode_inactive (void);
+
+
+void _gcry_fips_signal_error (const char *srcfile,
+ int srcline,
+ const char *srcfunc,
+ int is_fatal,
+ const char *description);
+#ifdef JNLIB_GCC_M_FUNCTION
+# define fips_signal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 0, (a))
+# define fips_signal_fatal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 1, (a))
+#else
+# define fips_signal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 0, (a))
+# define fips_signal_fatal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a))
+#endif
+
+int _gcry_fips_is_operational (void);
+
+/* Return true if the library is in the operational state. */
+#define fips_is_operational() \
+ (!_gcry_global_any_init_done ? \
+ _gcry_global_is_operational() : \
+ (!fips_mode () || _gcry_global_is_operational ()))
+
+#define fips_not_operational() (GPG_ERR_NOT_OPERATIONAL)
+
+int _gcry_fips_test_operational (void);
+int _gcry_fips_test_error_or_operational (void);
+
+gpg_err_code_t _gcry_fips_run_selftests (int extended);
+
+void _gcry_fips_noreturn (void);
+#define fips_noreturn() (_gcry_fips_noreturn ())
+
+
+
+#endif /* G10LIB_H */
diff --git a/comm/third_party/libgcrypt/src/gcrypt-int.h b/comm/third_party/libgcrypt/src/gcrypt-int.h
new file mode 100644
index 0000000000..086953d79a
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/gcrypt-int.h
@@ -0,0 +1,534 @@
+/* gcrypt-int.h - Internal version of gcrypt.h
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_GCRYPT_INT_H
+#define GCRY_GCRYPT_INT_H
+
+#ifdef _GCRYPT_H
+#error gcrypt.h already included
+#endif
+
+#include "gcrypt.h"
+#include "types.h"
+
+/* These error codes are used but not defined in the required
+ * libgpg-error N.MM. Define them here. [None right now.] */
+
+
+
+/* Context used with elliptic curve functions. */
+struct mpi_ec_ctx_s;
+typedef struct mpi_ec_ctx_s *mpi_ec_t;
+
+
+
+/* Underscore prefixed internal versions of the public functions.
+ They return gpg_err_code_t and not gpg_error_t. Some macros also
+ need an underscore prefixed internal version.
+
+ Note that the memory allocation functions and macros (xmalloc etc.)
+ are not defined here but in g10lib.h because this file here is
+ included by some test programs which define theie own xmalloc
+ macros. */
+
+gpg_err_code_t _gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags);
+void _gcry_cipher_close (gcry_cipher_hd_t h);
+gpg_err_code_t _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
+ size_t buflen);
+gpg_err_code_t _gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+gpg_err_code_t _gcry_cipher_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+const char *_gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+int _gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+int _gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;
+gpg_err_code_t _gcry_cipher_encrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+gpg_err_code_t _gcry_cipher_decrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+gcry_err_code_t _gcry_cipher_setkey (gcry_cipher_hd_t hd,
+ const void *key, size_t keylen);
+gcry_err_code_t _gcry_cipher_setiv (gcry_cipher_hd_t hd,
+ const void *iv, size_t ivlen);
+gpg_err_code_t _gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
+ size_t abuflen);
+gpg_err_code_t _gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag,
+ size_t taglen);
+gpg_err_code_t _gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag,
+ size_t taglen);
+gpg_err_code_t _gcry_cipher_setctr (gcry_cipher_hd_t hd,
+ const void *ctr, size_t ctrlen);
+gpg_err_code_t _gcry_cipher_getctr (gcry_cipher_hd_t hd,
+ void *ctr, size_t ctrlen);
+size_t _gcry_cipher_get_algo_keylen (int algo);
+size_t _gcry_cipher_get_algo_blklen (int algo);
+
+#define _gcry_cipher_reset(h) _gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+
+
+
+gpg_err_code_t _gcry_pk_encrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+gpg_err_code_t _gcry_pk_decrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+gpg_err_code_t _gcry_pk_sign (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+gpg_err_code_t _gcry_pk_verify (gcry_sexp_t sigval,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+gpg_err_code_t _gcry_pk_testkey (gcry_sexp_t key);
+gpg_err_code_t _gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms);
+gpg_err_code_t _gcry_pk_ctl (int cmd, void *buffer, size_t buflen);
+gpg_err_code_t _gcry_pk_algo_info (int algo, int what,
+ void *buffer, size_t *nbytes);
+const char *_gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+int _gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+unsigned int _gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
+unsigned char *_gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
+const char *_gcry_pk_get_curve (gcry_sexp_t key, int iterator,
+ unsigned int *r_nbits);
+gcry_sexp_t _gcry_pk_get_param (int algo, const char *name);
+gpg_err_code_t _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp,
+ int mode, gcry_ctx_t ctx);
+unsigned int _gcry_ecc_get_algo_keylen (int algo);
+gpg_error_t _gcry_ecc_mul_point (int algo, unsigned char *result,
+ const unsigned char *scalar,
+ const unsigned char *point);
+
+
+gpg_err_code_t _gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);
+void _gcry_md_close (gcry_md_hd_t hd);
+gpg_err_code_t _gcry_md_enable (gcry_md_hd_t hd, int algo);
+gpg_err_code_t _gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);
+void _gcry_md_reset (gcry_md_hd_t hd);
+gpg_err_code_t _gcry_md_ctl (gcry_md_hd_t hd, int cmd,
+ void *buffer, size_t buflen);
+void _gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
+unsigned char *_gcry_md_read (gcry_md_hd_t hd, int algo);
+gpg_err_code_t _gcry_md_extract (gcry_md_hd_t hd, int algo, void *buffer,
+ size_t length);
+void _gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length);
+gpg_err_code_t _gcry_md_hash_buffers (int algo, unsigned int flags,
+ void *digest,
+ const gcry_buffer_t *iov, int iovcnt);
+int _gcry_md_get_algo (gcry_md_hd_t hd);
+unsigned int _gcry_md_get_algo_dlen (int algo);
+int _gcry_md_is_enabled (gcry_md_hd_t a, int algo);
+int _gcry_md_is_secure (gcry_md_hd_t a);
+gpg_err_code_t _gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+gpg_err_code_t _gcry_md_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+const char *_gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;
+int _gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+gpg_err_code_t _gcry_md_setkey (gcry_md_hd_t hd,
+ const void *key, size_t keylen);
+void _gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
+
+#define _gcry_md_test_algo(a) \
+ _gcry_md_algo_info ((a), GCRYCTL_TEST_ALGO, NULL, NULL)
+
+#define _gcry_md_final(a) \
+ _gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
+#define _gcry_md_putc(h,c) \
+ do { \
+ gcry_md_hd_t h__ = (h); \
+ if( (h__)->bufpos == (h__)->bufsize ) \
+ _gcry_md_write( (h__), NULL, 0 ); \
+ (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \
+ } while(0)
+
+
+
+gpg_err_code_t _gcry_mac_open (gcry_mac_hd_t *handle, int algo,
+ unsigned int flags, gcry_ctx_t ctx);
+void _gcry_mac_close (gcry_mac_hd_t h);
+gpg_err_code_t _gcry_mac_ctl (gcry_mac_hd_t h, int cmd, void *buffer,
+ size_t buflen);
+gpg_err_code_t _gcry_mac_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+gpg_err_code_t _gcry_mac_setkey (gcry_mac_hd_t hd, const void *key,
+ size_t keylen);
+gpg_err_code_t _gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv,
+ size_t ivlen);
+gpg_err_code_t _gcry_mac_write (gcry_mac_hd_t hd, const void *buffer,
+ size_t length);
+gpg_err_code_t _gcry_mac_read (gcry_mac_hd_t hd, void *buffer, size_t *buflen);
+gpg_err_code_t _gcry_mac_verify (gcry_mac_hd_t hd, const void *buffer,
+ size_t buflen);
+int _gcry_mac_get_algo (gcry_mac_hd_t hd);
+unsigned int _gcry_mac_get_algo_maclen (int algo);
+unsigned int _gcry_mac_get_algo_keylen (int algo);
+const char *_gcry_mac_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+int _gcry_mac_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+
+#define _gcry_mac_reset(h) _gcry_mac_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+
+gpg_err_code_t _gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int subalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer);
+
+
+gpg_err_code_t _gcry_prime_generate (gcry_mpi_t *prime,
+ unsigned int prime_bits,
+ unsigned int factor_bits,
+ gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func,
+ void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags);
+gpg_err_code_t _gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime,
+ gcry_mpi_t *factors,
+ gcry_mpi_t start_g);
+void _gcry_prime_release_factors (gcry_mpi_t *factors);
+gpg_err_code_t _gcry_prime_check (gcry_mpi_t x, unsigned int flags);
+
+
+void _gcry_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+gpg_err_code_t _gcry_random_add_bytes (const void *buffer, size_t length,
+ int quality);
+void *_gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+void _gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level);
+void _gcry_create_nonce (void *buffer, size_t length);
+
+
+void _gcry_ctx_release (gcry_ctx_t ctx);
+
+
+const char *_gcry_check_version (const char *req_version);
+
+void _gcry_set_allocation_handler (gcry_handler_alloc_t func_alloc,
+ gcry_handler_alloc_t func_alloc_secure,
+ gcry_handler_secure_check_t func_secure_check,
+ gcry_handler_realloc_t func_realloc,
+ gcry_handler_free_t func_free);
+void _gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque);
+void _gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque);
+void _gcry_set_log_handler (gcry_handler_log_t f, void *opaque);
+void _gcry_set_gettext_handler (const char *(*f)(const char*));
+void _gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data);
+
+
+/* Return a pointer to a string containing a description of the error
+ code in the error value ERR. */
+static inline const char *
+_gcry_strerror (gcry_error_t err)
+{
+ return gpg_strerror (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+ source in the error value ERR. */
+static inline const char *
+_gcry_strsource (gcry_error_t err)
+{
+ return gpg_strsource (err);
+}
+
+/* Retrieve the error code for the system error ERR. This returns
+ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+ this). */
+static inline gcry_err_code_t
+_gcry_err_code_from_errno (int err)
+{
+ return gpg_err_code_from_errno (err);
+}
+
+/* Retrieve the system error for the error code CODE. This returns 0
+ if CODE is not a system error code. */
+static inline int
+_gcry_err_code_to_errno (gcry_err_code_t code)
+{
+ return gpg_err_code_from_errno (code);
+}
+
+/* Return an error value with the error source SOURCE and the system
+ error ERR. */
+static inline gcry_error_t
+_gcry_err_make_from_errno (gpg_err_source_t source, int err)
+{
+ return gpg_err_make_from_errno (source, err);
+}
+
+
+/* Return an error value with the system error ERR. */
+static inline gcry_error_t
+_gcry_error_from_errno (int err)
+{
+ return gpg_error (gpg_err_code_from_errno (err));
+}
+
+
+
+gpg_err_code_t _gcry_sexp_new (gcry_sexp_t *retsexp,
+ const void *buffer, size_t length,
+ int autodetect);
+gpg_err_code_t _gcry_sexp_create (gcry_sexp_t *retsexp,
+ void *buffer, size_t length,
+ int autodetect, void (*freefnc) (void *));
+gpg_err_code_t _gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length);
+gpg_err_code_t _gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, ...);
+gpg_err_code_t _gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list);
+void _gcry_sexp_release (gcry_sexp_t sexp);
+size_t _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_err_code_t *errcode);
+size_t _gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
+ size_t maxlength);
+void _gcry_sexp_dump (const gcry_sexp_t a);
+gcry_sexp_t _gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b);
+gcry_sexp_t _gcry_sexp_alist (const gcry_sexp_t *array);
+gcry_sexp_t _gcry_sexp_vlist (const gcry_sexp_t a, ...);
+gcry_sexp_t _gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n);
+gcry_sexp_t _gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n);
+gcry_sexp_t _gcry_sexp_find_token (gcry_sexp_t list,
+ const char *tok, size_t toklen);
+int _gcry_sexp_length (const gcry_sexp_t list);
+gcry_sexp_t _gcry_sexp_nth (const gcry_sexp_t list, int number);
+gcry_sexp_t _gcry_sexp_car (const gcry_sexp_t list);
+gcry_sexp_t _gcry_sexp_cdr (const gcry_sexp_t list);
+gcry_sexp_t _gcry_sexp_cadr (const gcry_sexp_t list);
+const char *_gcry_sexp_nth_data (const gcry_sexp_t list, int number,
+ size_t *datalen);
+void *_gcry_sexp_nth_buffer (const gcry_sexp_t list, int number,
+ size_t *rlength);
+char *_gcry_sexp_nth_string (gcry_sexp_t list, int number);
+gcry_mpi_t _gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
+gpg_err_code_t _gcry_sexp_extract_param (gcry_sexp_t sexp,
+ const char *path,
+ const char *list,
+ ...) _GCRY_GCC_ATTR_SENTINEL(0);
+
+#define sexp_new(a, b, c, d) _gcry_sexp_new ((a), (b), (c), (d))
+#define sexp_create(a, b, c, d, e) _gcry_sexp_create ((a), (b), (c), (d), (e))
+#define sexp_sscan(a, b, c, d) _gcry_sexp_sscan ((a), (b), (c), (d))
+#define sexp_build _gcry_sexp_build
+#define sexp_build_array(a, b, c, d) _gcry_sexp_build_array ((a), (b), (c), (d))
+#define sexp_release(a) _gcry_sexp_release ((a))
+#define sexp_canon_len(a, b, c, d) _gcry_sexp_canon_len ((a), (b), (c), (d))
+#define sexp_sprint(a, b, c, d) _gcry_sexp_sprint ((a), (b), (c), (d))
+#define sexp_dump(a) _gcry_sexp_dump ((a))
+#define sexp_cons(a, b) _gcry_sexp_cons ((a), (b))
+#define sexp_alist(a) _gcry_sexp_alist ((a))
+#define sexp_vlist _gcry_sexp_vlist
+#define sexp_append(a, b) _gcry_sexp_append ((a), (b))
+#define sexp_prepend(a, b) _gcry_sexp_prepend ((a), (b))
+#define sexp_find_token(a, b, c) _gcry_sexp_find_token ((a), (b), (c))
+#define sexp_length(a) _gcry_sexp_length ((a))
+#define sexp_nth(a, b) _gcry_sexp_nth ((a), (b))
+#define sexp_car(a) _gcry_sexp_car ((a))
+#define sexp_cdr(a) _gcry_sexp_cdr ((a))
+#define sexp_cadr(a) _gcry_sexp_cadr ((a))
+#define sexp_nth_data(a, b, c) _gcry_sexp_nth_data ((a), (b), (c))
+#define sexp_nth_buffer(a, b, c) _gcry_sexp_nth_buffer ((a), (b), (c))
+#define sexp_nth_string(a, b) _gcry_sexp_nth_string ((a), (b))
+#define sexp_nth_mpi(a, b, c) _gcry_sexp_nth_mpi ((a), (b), (c))
+#define sexp_extract_param _gcry_sexp_extract_param
+
+
+
+gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
+gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
+void _gcry_mpi_release (gcry_mpi_t a);
+gcry_mpi_t _gcry_mpi_copy (const gcry_mpi_t a);
+void _gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u);
+gcry_mpi_t _gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);
+gcry_mpi_t _gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);
+gcry_err_code_t _gcry_mpi_get_ui (unsigned int *w, gcry_mpi_t u);
+void _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);
+int _gcry_mpi_is_neg (gcry_mpi_t a);
+void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u);
+void _gcry_mpi_abs (gcry_mpi_t w);
+int _gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
+int _gcry_mpi_cmpabs (const gcry_mpi_t u, const gcry_mpi_t v);
+int _gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
+gpg_err_code_t _gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+ const void *buffer, size_t buflen,
+ size_t *nscanned);
+gpg_err_code_t _gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten,
+ const gcry_mpi_t a);
+gpg_err_code_t _gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ const gcry_mpi_t a);
+void _gcry_mpi_dump (const gcry_mpi_t a);
+void _gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+void _gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);
+void _gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+void _gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+void _gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+void _gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+void _gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+void _gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+void _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+void _gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);
+void _gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+ gcry_mpi_t dividend, gcry_mpi_t divisor, int round);
+void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+void _gcry_mpi_powm (gcry_mpi_t w,
+ const gcry_mpi_t b, const gcry_mpi_t e,
+ const gcry_mpi_t m);
+int _gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
+int _gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);
+gcry_mpi_point_t _gcry_mpi_point_new (unsigned int nbits);
+void _gcry_mpi_point_release (gcry_mpi_point_t point);
+gcry_mpi_point_t _gcry_mpi_point_copy (gcry_mpi_point_t point);
+void _gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ gcry_mpi_point_t point);
+void _gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ gcry_mpi_point_t point);
+gcry_mpi_point_t _gcry_mpi_point_set (gcry_mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z);
+gcry_mpi_point_t _gcry_mpi_point_snatch_set (gcry_mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y,
+ gcry_mpi_t z);
+
+gcry_mpi_t _gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy);
+gcry_mpi_point_t _gcry_mpi_ec_get_point (const char *name,
+ gcry_ctx_t ctx, int copy);
+int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
+ mpi_ec_t ctx);
+void _gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx);
+void _gcry_mpi_ec_add (gcry_mpi_point_t w,
+ gcry_mpi_point_t u, gcry_mpi_point_t v, mpi_ec_t ctx);
+void _gcry_mpi_ec_sub (gcry_mpi_point_t w,
+ gcry_mpi_point_t u, gcry_mpi_point_t v, mpi_ec_t ctx);
+void _gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
+ mpi_ec_t ctx);
+int _gcry_mpi_ec_curve_point (gcry_mpi_point_t w, mpi_ec_t ctx);
+unsigned int _gcry_mpi_get_nbits (gcry_mpi_t a);
+int _gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+gcry_mpi_t _gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
+gcry_mpi_t _gcry_mpi_set_opaque_copy (gcry_mpi_t a,
+ const void *p, unsigned int nbits);
+void *_gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);
+void _gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+void _gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+
+/* Private function - do not use. */
+/* gcry_mpi_t _gcry_mpi_get_const (int no); */
+
+/* We need our internal versions of the macros. */
+#ifndef GCRYPT_NO_MPI_MACROS
+# error GCRYPT_NO_MPI_MACROS is not defined
+#endif
+
+#define mpi_new(n) _gcry_mpi_new ((n))
+#define mpi_secure_new( n ) _gcry_mpi_snew ((n))
+#define mpi_snew(n) _gcry_mpi_snew ((n))
+
+#define mpi_release(a) \
+ do \
+ { \
+ _gcry_mpi_release ((a));\
+ (a) = NULL; \
+ } \
+ while (0)
+
+#define mpi_snatch( w, u) _gcry_mpi_snatch( (w), (u) )
+#define mpi_set( w, u) _gcry_mpi_set( (w), (u) )
+#define mpi_set_ui( w, u) _gcry_mpi_set_ui( (w), (u) )
+#define mpi_get_ui(w,u) _gcry_mpi_get_ui( (w), (u) )
+#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b))
+#define mpi_abs( w ) _gcry_mpi_abs( (w) )
+#define mpi_neg( w, u) _gcry_mpi_neg( (w), (u) )
+#define mpi_cmp( u, v ) _gcry_mpi_cmp( (u), (v) )
+#define mpi_cmpabs( u, v ) _gcry_mpi_cmpabs( (u), (v) )
+#define mpi_cmp_ui( u, v ) _gcry_mpi_cmp_ui( (u), (v) )
+#define mpi_is_neg( a ) _gcry_mpi_is_neg ((a))
+
+#define mpi_add_ui(w,u,v) _gcry_mpi_add_ui((w),(u),(v))
+#define mpi_add(w,u,v) _gcry_mpi_add ((w),(u),(v))
+#define mpi_addm(w,u,v,m) _gcry_mpi_addm ((w),(u),(v),(m))
+#define mpi_sub_ui(w,u,v) _gcry_mpi_sub_ui ((w),(u),(v))
+#define mpi_sub(w,u,v) _gcry_mpi_sub ((w),(u),(v))
+#define mpi_subm(w,u,v,m) _gcry_mpi_subm ((w),(u),(v),(m))
+#define mpi_mul_ui(w,u,v) _gcry_mpi_mul_ui ((w),(u),(v))
+#define mpi_mul_2exp(w,u,v) _gcry_mpi_mul_2exp ((w),(u),(v))
+#define mpi_mul(w,u,v) _gcry_mpi_mul ((w),(u),(v))
+#define mpi_mulm(w,u,v,m) _gcry_mpi_mulm ((w),(u),(v),(m))
+#define mpi_powm(w,b,e,m) _gcry_mpi_powm ( (w), (b), (e), (m) )
+#define mpi_tdiv(q,r,a,m) _gcry_mpi_div ( (q), (r), (a), (m), 0)
+#define mpi_fdiv(q,r,a,m) _gcry_mpi_div ( (q), (r), (a), (m), -1)
+#define mpi_mod(r,a,m) _gcry_mpi_mod ((r), (a), (m))
+#define mpi_gcd(g,a,b) _gcry_mpi_gcd ( (g), (a), (b) )
+#define mpi_invm(g,a,b) _gcry_mpi_invm ( (g), (a), (b) )
+
+#define mpi_point_new(n) _gcry_mpi_point_new((n))
+
+#define mpi_point_release(p) \
+ do \
+ { \
+ _gcry_mpi_point_release ((p)); \
+ (p) = NULL; \
+ } \
+ while (0)
+
+#define mpi_point_copy(p) _gcry_mpi_point_copy((p))
+
+#define mpi_point_get(x,y,z,p) _gcry_mpi_point_get((x),(y),(z),(p))
+#define mpi_point_snatch_get(x,y,z,p) _gcry_mpi_point_snatch_get((x),(y), \
+ (z),(p))
+#define mpi_point_set(p,x,y,z) _gcry_mpi_point_set((p),(x),(y),(z))
+#define mpi_point_snatch_set(p,x,y,z) _gcry_mpi_point_snatch_set((p),(x), \
+ (y),(z))
+
+#define mpi_get_nbits(a) _gcry_mpi_get_nbits ((a))
+#define mpi_test_bit(a,b) _gcry_mpi_test_bit ((a),(b))
+#define mpi_set_bit(a,b) _gcry_mpi_set_bit ((a),(b))
+#define mpi_set_highbit(a,b) _gcry_mpi_set_highbit ((a),(b))
+#define mpi_clear_bit(a,b) _gcry_mpi_clear_bit ((a),(b))
+#define mpi_clear_highbit(a,b) _gcry_mpi_clear_highbit ((a),(b))
+#define mpi_rshift(a,b,c) _gcry_mpi_rshift ((a),(b),(c))
+#define mpi_lshift(a,b,c) _gcry_mpi_lshift ((a),(b),(c))
+
+#define mpi_set_opaque(a,b,c) _gcry_mpi_set_opaque ((a), (b), (c))
+#define mpi_get_opaque(a,b) _gcry_mpi_get_opaque ((a), (b))
+#define mpi_set_flag(a,f) _gcry_mpi_set_flag ((a), (f))
+#define mpi_set_flag(a,f) _gcry_mpi_set_flag ((a), (f))
+#define mpi_clear_flag(a,f) _gcry_mpi_clear_flag ((a), (f))
+#define mpi_get_flag(a,f) _gcry_mpi_get_flag ((a), (f))
+
+
+#endif /*GCRY_GCRYPT_INT_H*/
diff --git a/comm/third_party/libgcrypt/src/gcrypt-testapi.h b/comm/third_party/libgcrypt/src/gcrypt-testapi.h
new file mode 100644
index 0000000000..0417754f4d
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/gcrypt-testapi.h
@@ -0,0 +1,69 @@
+/* gcrypt-testapi.h - Definitiona for the Regression test API
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * WARNING: This is a private API to be used by regression tests. In
+ * particular this API does not constitute a well defined ABI. The
+ * header may only be used with its matching Libgcrypt version.
+ */
+
+#ifndef GCRY_GCRYPT_TESTAPI_H
+#define GCRY_GCRYPT_TESTAPI_H
+
+/* For use with gcry_control: */
+#define PRIV_CTL_INIT_EXTRNG_TEST 58
+#define PRIV_CTL_RUN_EXTRNG_TEST 59
+#define PRIV_CTL_DEINIT_EXTRNG_TEST 60
+#define PRIV_CTL_EXTERNAL_LOCK_TEST 61
+#define PRIV_CTL_DUMP_SECMEM_STATS 62
+
+#define EXTERNAL_LOCK_TEST_INIT 30111
+#define EXTERNAL_LOCK_TEST_LOCK 30112
+#define EXTERNAL_LOCK_TEST_UNLOCK 30113
+#define EXTERNAL_LOCK_TEST_DESTROY 30114
+
+/* For use with gcry_cipher_ctl: */
+#define PRIV_CIPHERCTL_DISABLE_WEAK_KEY 61
+#define PRIV_CIPHERCTL_GET_INPUT_VECTOR 62
+
+
+/* Private interfaces for testing of random-drbg.c. */
+struct gcry_drbg_test_vector
+{
+ const char *flagstr;
+ unsigned char *entropy;
+ size_t entropylen;
+ unsigned char *entpra;
+ unsigned char *entprb;
+ size_t entprlen;
+ unsigned char *addtla;
+ unsigned char *addtlb;
+ size_t addtllen;
+ unsigned char *pers;
+ size_t perslen;
+ unsigned char *expected;
+ size_t expectedlen;
+ unsigned char *entropyreseed;
+ size_t entropyreseed_len;
+ unsigned char *addtl_reseed;
+ size_t addtl_reseed_len;
+};
+
+
+#endif /*GCRY_GCRYPT_TESTAPI_H*/
diff --git a/comm/third_party/libgcrypt/src/gcrypt.h.in b/comm/third_party/libgcrypt/src/gcrypt.h.in
new file mode 100644
index 0000000000..e77b6e7486
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/gcrypt.h.in
@@ -0,0 +1,1845 @@
+/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*-
+ * Copyright (C) 1998-2018 Free Software Foundation, Inc.
+ * Copyright (C) 2012-2018 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 <http://www.gnu.org/licenses/>.
+ *
+ * File: @configure_input@
+ */
+
+#ifndef _GCRYPT_H
+#define _GCRYPT_H
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <gpg-error.h>
+
+#include <sys/types.h>
+
+#if defined _WIN32 || defined __WIN32__
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <time.h>
+# ifndef __GNUC__
+ typedef long ssize_t;
+ typedef int pid_t;
+# endif /*!__GNUC__*/
+#else
+# include <sys/socket.h>
+# include <sys/time.h>
+#@INSERT_SYS_SELECT_H@
+#endif /*!_WIN32*/
+
+@FALLBACK_SOCKLEN_T@
+
+/* This is required for error code compatibility. */
+#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+}
+#endif
+#endif
+
+/* The version of this header should match the one of the library. It
+ should not be used by a program because gcry_check_version() should
+ return the same version. The purpose of this macro is to let
+ autoconf (using the AM_PATH_GCRYPT macro) check that this header
+ matches the installed library. */
+#define GCRYPT_VERSION "@VERSION@"
+
+/* The version number of this header. It may be used to handle minor
+ API incompatibilities. */
+#define GCRYPT_VERSION_NUMBER @VERSION_NUMBER@
+
+
+/* Internal: We can't use the convenience macros for the multi
+ precision integer functions when building this library. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#ifndef GCRYPT_NO_MPI_MACROS
+#define GCRYPT_NO_MPI_MACROS 1
+#endif
+#endif
+
+/* We want to use gcc attributes when possible. Warning: Don't use
+ these macros in your programs: As indicated by the leading
+ underscore they are subject to change without notice. */
+#ifdef __GNUC__
+
+#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+
+#if _GCRY_GCC_VERSION >= 30100
+#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 29600
+#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 30200
+#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__))
+#endif
+
+#define _GCRY_GCC_ATTR_PRINTF(f,a) __attribute__ ((format (printf,f,a)))
+
+#if _GCRY_GCC_VERSION >= 40000
+#define _GCRY_GCC_ATTR_SENTINEL(a) __attribute__ ((sentinel(a)))
+#endif
+
+#endif /*__GNUC__*/
+
+#ifndef _GCRY_GCC_ATTR_DEPRECATED
+#define _GCRY_GCC_ATTR_DEPRECATED
+#endif
+#ifndef _GCRY_GCC_ATTR_PURE
+#define _GCRY_GCC_ATTR_PURE
+#endif
+#ifndef _GCRY_GCC_ATTR_MALLOC
+#define _GCRY_GCC_ATTR_MALLOC
+#endif
+#ifndef _GCRY_GCC_ATTR_PRINTF
+#define _GCRY_GCC_ATTR_PRINTF(f,a)
+#endif
+#ifndef _GCRY_GCC_ATTR_SENTINEL
+#define _GCRY_GCC_ATTR_SENTINEL(a)
+#endif
+
+/* Make up an attribute to mark functions and types as deprecated but
+ allow internal use by Libgcrypt. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#define _GCRY_ATTR_INTERNAL
+#else
+#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED
+#endif
+
+/* Wrappers for the libgpg-error library. */
+
+typedef gpg_error_t gcry_error_t;
+typedef gpg_err_code_t gcry_err_code_t;
+typedef gpg_err_source_t gcry_err_source_t;
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_err_make (gcry_err_source_t source, gcry_err_code_t code)
+{
+ return gpg_err_make (source, code);
+}
+
+/* The user can define GPG_ERR_SOURCE_DEFAULT before including this
+ file to specify a default source for gpg_error. */
+#ifndef GCRY_ERR_SOURCE_DEFAULT
+#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1
+#endif
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_error (gcry_err_code_t code)
+{
+ return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code);
+}
+
+static GPG_ERR_INLINE gcry_err_code_t
+gcry_err_code (gcry_error_t err)
+{
+ return gpg_err_code (err);
+}
+
+
+static GPG_ERR_INLINE gcry_err_source_t
+gcry_err_source (gcry_error_t err)
+{
+ return gpg_err_source (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+ code in the error value ERR. */
+const char *gcry_strerror (gcry_error_t err);
+
+/* Return a pointer to a string containing a description of the error
+ source in the error value ERR. */
+const char *gcry_strsource (gcry_error_t err);
+
+/* Retrieve the error code for the system error ERR. This returns
+ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+ this). */
+gcry_err_code_t gcry_err_code_from_errno (int err);
+
+/* Retrieve the system error for the error code CODE. This returns 0
+ if CODE is not a system error code. */
+int gcry_err_code_to_errno (gcry_err_code_t code);
+
+/* Return an error value with the error source SOURCE and the system
+ error ERR. */
+gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
+
+/* Return an error value with the system error ERR. */
+gcry_error_t gcry_error_from_errno (int err);
+
+
+/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore
+ used. However we keep it to allow for some source code
+ compatibility if used in the standard way. */
+
+/* Constants defining the thread model to use. Used with the OPTION
+ field of the struct gcry_thread_cbs. */
+#define GCRY_THREAD_OPTION_DEFAULT 0
+#define GCRY_THREAD_OPTION_USER 1
+#define GCRY_THREAD_OPTION_PTH 2
+#define GCRY_THREAD_OPTION_PTHREAD 3
+
+/* The version number encoded in the OPTION field of the struct
+ gcry_thread_cbs. */
+#define GCRY_THREAD_OPTION_VERSION 1
+
+/* Wrapper for struct ath_ops. */
+struct gcry_thread_cbs
+{
+ /* The OPTION field encodes the thread model and the version number
+ of this structure.
+ Bits 7 - 0 are used for the thread model
+ Bits 15 - 8 are used for the version number. */
+ unsigned int option;
+} _GCRY_ATTR_INTERNAL;
+
+#define GCRY_THREAD_OPTION_PTH_IMPL \
+ static struct gcry_thread_cbs gcry_threads_pth = { \
+ (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))}
+
+#define GCRY_THREAD_OPTION_PTHREAD_IMPL \
+ static struct gcry_thread_cbs gcry_threads_pthread = { \
+ (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))}
+
+
+
+/* A generic context object as used by some functions. */
+struct gcry_context;
+typedef struct gcry_context *gcry_ctx_t;
+
+/* The data objects used to hold multi precision integers. */
+struct gcry_mpi;
+typedef struct gcry_mpi *gcry_mpi_t;
+struct gcry_mpi_point;
+typedef struct gcry_mpi_point *gcry_mpi_point_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* A structure used for scatter gather hashing. */
+typedef struct
+{
+ size_t size; /* The allocated size of the buffer or 0. */
+ size_t off; /* Offset into the buffer. */
+ size_t len; /* The used length of the buffer. */
+ void *data; /* The buffer. */
+} gcry_buffer_t;
+
+
+
+
+/* Check that the library fulfills the version requirement. */
+const char *gcry_check_version (const char *req_version);
+
+/* Codes for function dispatchers. */
+
+/* Codes used with the gcry_control function. */
+enum gcry_ctl_cmds
+ {
+ /* Note: 1 .. 2 are not anymore used. */
+ GCRYCTL_CFB_SYNC = 3,
+ GCRYCTL_RESET = 4, /* e.g. for MDs */
+ GCRYCTL_FINALIZE = 5,
+ GCRYCTL_GET_KEYLEN = 6,
+ GCRYCTL_GET_BLKLEN = 7,
+ GCRYCTL_TEST_ALGO = 8,
+ GCRYCTL_IS_SECURE = 9,
+ GCRYCTL_GET_ASNOID = 10,
+ GCRYCTL_ENABLE_ALGO = 11,
+ GCRYCTL_DISABLE_ALGO = 12,
+ GCRYCTL_DUMP_RANDOM_STATS = 13,
+ GCRYCTL_DUMP_SECMEM_STATS = 14,
+ GCRYCTL_GET_ALGO_NPKEY = 15,
+ GCRYCTL_GET_ALGO_NSKEY = 16,
+ GCRYCTL_GET_ALGO_NSIGN = 17,
+ GCRYCTL_GET_ALGO_NENCR = 18,
+ GCRYCTL_SET_VERBOSITY = 19,
+ GCRYCTL_SET_DEBUG_FLAGS = 20,
+ GCRYCTL_CLEAR_DEBUG_FLAGS = 21,
+ GCRYCTL_USE_SECURE_RNDPOOL= 22,
+ GCRYCTL_DUMP_MEMORY_STATS = 23,
+ GCRYCTL_INIT_SECMEM = 24,
+ GCRYCTL_TERM_SECMEM = 25,
+ GCRYCTL_DISABLE_SECMEM_WARN = 27,
+ GCRYCTL_SUSPEND_SECMEM_WARN = 28,
+ GCRYCTL_RESUME_SECMEM_WARN = 29,
+ GCRYCTL_DROP_PRIVS = 30,
+ GCRYCTL_ENABLE_M_GUARD = 31,
+ GCRYCTL_START_DUMP = 32,
+ GCRYCTL_STOP_DUMP = 33,
+ GCRYCTL_GET_ALGO_USAGE = 34,
+ GCRYCTL_IS_ALGO_ENABLED = 35,
+ GCRYCTL_DISABLE_INTERNAL_LOCKING = 36,
+ GCRYCTL_DISABLE_SECMEM = 37,
+ GCRYCTL_INITIALIZATION_FINISHED = 38,
+ GCRYCTL_INITIALIZATION_FINISHED_P = 39,
+ GCRYCTL_ANY_INITIALIZATION_P = 40,
+ GCRYCTL_SET_CBC_CTS = 41,
+ GCRYCTL_SET_CBC_MAC = 42,
+ /* Note: 43 is not anymore used. */
+ GCRYCTL_ENABLE_QUICK_RANDOM = 44,
+ GCRYCTL_SET_RANDOM_SEED_FILE = 45,
+ GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46,
+ GCRYCTL_SET_THREAD_CBS = 47,
+ GCRYCTL_FAST_POLL = 48,
+ GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49,
+ GCRYCTL_USE_RANDOM_DAEMON = 50,
+ GCRYCTL_FAKED_RANDOM_P = 51,
+ GCRYCTL_SET_RNDEGD_SOCKET = 52,
+ GCRYCTL_PRINT_CONFIG = 53,
+ GCRYCTL_OPERATIONAL_P = 54,
+ GCRYCTL_FIPS_MODE_P = 55,
+ GCRYCTL_FORCE_FIPS_MODE = 56,
+ GCRYCTL_SELFTEST = 57,
+ /* Note: 58 .. 62 are used internally. */
+ GCRYCTL_DISABLE_HWF = 63,
+ GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64,
+ GCRYCTL_SET_PREFERRED_RNG_TYPE = 65,
+ GCRYCTL_GET_CURRENT_RNG_TYPE = 66,
+ GCRYCTL_DISABLE_LOCKED_SECMEM = 67,
+ GCRYCTL_DISABLE_PRIV_DROP = 68,
+ GCRYCTL_SET_CCM_LENGTHS = 69,
+ GCRYCTL_CLOSE_RANDOM_DEVICE = 70,
+ GCRYCTL_INACTIVATE_FIPS_FLAG = 71,
+ GCRYCTL_REACTIVATE_FIPS_FLAG = 72,
+ GCRYCTL_SET_SBOX = 73,
+ GCRYCTL_DRBG_REINIT = 74,
+ GCRYCTL_SET_TAGLEN = 75,
+ GCRYCTL_GET_TAGLEN = 76,
+ GCRYCTL_REINIT_SYSCALL_CLAMP = 77,
+ GCRYCTL_AUTO_EXPAND_SECMEM = 78,
+ GCRYCTL_SET_ALLOW_WEAK_KEY = 79
+ };
+
+/* Perform various operations defined by CMD. */
+gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...);
+
+
+/* S-expression management. */
+
+/* The object to represent an S-expression as used with the public key
+ functions. */
+struct gcry_sexp;
+typedef struct gcry_sexp *gcry_sexp_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* The possible values for the S-expression format. */
+enum gcry_sexp_format
+ {
+ GCRYSEXP_FMT_DEFAULT = 0,
+ GCRYSEXP_FMT_CANON = 1,
+ GCRYSEXP_FMT_BASE64 = 2,
+ GCRYSEXP_FMT_ADVANCED = 3
+ };
+
+/* Create an new S-expression object from BUFFER of size LENGTH and
+ return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER
+ is expected to be in canonized format. */
+gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp,
+ const void *buffer, size_t length,
+ int autodetect);
+
+ /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the
+ effect to transfer ownership of BUFFER to the created object. */
+gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp,
+ void *buffer, size_t length,
+ int autodetect, void (*freefnc) (void *));
+
+/* Scan BUFFER and return a new S-expression object in RETSEXP. This
+ function expects a printf like string in BUFFER. */
+gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length);
+
+/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus
+ only be used for certain encodings. */
+gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, ...);
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+ function arguments. */
+gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list);
+
+/* Release the S-expression object SEXP */
+void gcry_sexp_release (gcry_sexp_t sexp);
+
+/* Calculate the length of an canonized S-expression in BUFFER and
+ check for a valid encoding. */
+size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode);
+
+/* Copies the S-expression object SEXP into BUFFER using the format
+ specified in MODE. */
+size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
+ size_t maxlength);
+
+/* Dumps the S-expression object A in a format suitable for debugging
+ to Libgcrypt's logging stream. */
+void gcry_sexp_dump (const gcry_sexp_t a);
+
+gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b);
+gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array);
+gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...);
+gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n);
+gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n);
+
+/* Scan the S-expression for a sublist with a type (the car of the
+ list) matching the string TOKEN. If TOKLEN is not 0, the token is
+ assumed to be raw memory of this length. The function returns a
+ newly allocated S-expression consisting of the found sublist or
+ `NULL' when not found. */
+gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list,
+ const char *tok, size_t toklen);
+/* Return the length of the LIST. For a valid S-expression this
+ should be at least 1. */
+int gcry_sexp_length (const gcry_sexp_t list);
+
+/* Create and return a new S-expression from the element with index
+ NUMBER in LIST. Note that the first element has the index 0. If
+ there is no such element, `NULL' is returned. */
+gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number);
+
+/* Create and return a new S-expression from the first element in
+ LIST; this called the "type" and should always exist and be a
+ string. `NULL' is returned in case of a problem. */
+gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list);
+
+/* Create and return a new list form all elements except for the first
+ one. Note, that this function may return an invalid S-expression
+ because it is not guaranteed, that the type exists and is a string.
+ However, for parsing a complex S-expression it might be useful for
+ intermediate lists. Returns `NULL' on error. */
+gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list);
+
+gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);
+
+
+/* This function is used to get data from a LIST. A pointer to the
+ actual data with index NUMBER is returned and the length of this
+ data will be stored to DATALEN. If there is no data at the given
+ index or the index represents another list, `NULL' is returned.
+ *Note:* The returned pointer is valid as long as LIST is not
+ modified or released. */
+const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number,
+ size_t *datalen);
+
+/* This function is used to get data from a LIST. A malloced buffer to the
+ data with index NUMBER is returned and the length of this
+ data will be stored to RLENGTH. If there is no data at the given
+ index or the index represents another list, `NULL' is returned. */
+void *gcry_sexp_nth_buffer (const gcry_sexp_t list, int number,
+ size_t *rlength);
+
+/* This function is used to get and convert data from a LIST. The
+ data is assumed to be a Nul terminated string. The caller must
+ release the returned value using `gcry_free'. If there is no data
+ at the given index, the index represents a list or the value can't
+ be converted to a string, `NULL' is returned. */
+char *gcry_sexp_nth_string (gcry_sexp_t list, int number);
+
+/* This function is used to get and convert data from a LIST. This
+ data is assumed to be an MPI stored in the format described by
+ MPIFMT and returned as a standard Libgcrypt MPI. The caller must
+ release this returned value using `gcry_mpi_release'. If there is
+ no data at the given index, the index represents a list or the
+ value can't be converted to an MPI, `NULL' is returned. */
+gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
+
+/* Extract MPIs from an s-expression using a list of parameters. The
+ * names of these parameters are given by the string LIST. Some
+ * special characters may be given to control the conversion:
+ *
+ * + :: Switch to unsigned integer format (default).
+ * - :: Switch to standard signed format.
+ * / :: Switch to opaque format.
+ * & :: Switch to buffer descriptor mode - see below.
+ * ? :: The previous parameter is optional.
+ *
+ * In general parameter names are single letters. To use a string for
+ * a parameter name, enclose the name in single quotes.
+ *
+ * Unless in gcry_buffer_t mode for each parameter name a pointer to
+ * an MPI variable is expected that must be set to NULL prior to
+ * invoking this function, and finally a NULL is expected. Example:
+ *
+ * _gcry_sexp_extract_param (key, NULL, "n/x+ed",
+ * &mpi_n, &mpi_x, &mpi_e, NULL)
+ *
+ * This stores the parameter "N" from KEY as an unsigned MPI into
+ * MPI_N, the parameter "X" as an opaque MPI into MPI_X, and the
+ * parameter "E" again as an unsigned MPI into MPI_E.
+ *
+ * If in buffer descriptor mode a pointer to gcry_buffer_t descriptor
+ * is expected instead of a pointer to an MPI. The caller may use two
+ * different operation modes: If the DATA field of the provided buffer
+ * descriptor is NULL, the function allocates a new buffer and stores
+ * it at DATA; the other fields are set accordingly with OFF being 0.
+ * If DATA is not NULL, the function assumes that DATA, SIZE, and OFF
+ * describe a buffer where to but the data; on return the LEN field
+ * receives the number of bytes copied to that buffer; if the buffer
+ * is too small, the function immediately returns with an error code
+ * (and LEN set to 0).
+ *
+ * PATH is an optional string used to locate a token. The exclamation
+ * mark separated tokens are used to via gcry_sexp_find_token to find
+ * a start point inside SEXP.
+ *
+ * The function returns 0 on success. On error an error code is
+ * returned, all passed MPIs that might have been allocated up to this
+ * point are deallocated and set to NULL, and all passed buffers are
+ * either truncated if the caller supplied the buffer, or deallocated
+ * if the function allocated the buffer.
+ */
+gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp,
+ const char *path,
+ const char *list,
+ ...) _GCRY_GCC_ATTR_SENTINEL(0);
+
+
+/*******************************************
+ * *
+ * Multi Precision Integer Functions *
+ * *
+ *******************************************/
+
+/* Different formats of external big integer representation. */
+enum gcry_mpi_format
+ {
+ GCRYMPI_FMT_NONE= 0,
+ GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */
+ GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */
+ GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */
+ GCRYMPI_FMT_HEX = 4, /* Hex format. */
+ GCRYMPI_FMT_USG = 5, /* Like STD but unsigned. */
+ GCRYMPI_FMT_OPAQUE = 8 /* Opaque format (some functions only). */
+ };
+
+/* Flags used for creating big integers. */
+enum gcry_mpi_flag
+ {
+ GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */
+ GCRYMPI_FLAG_OPAQUE = 2, /* The number is not a real one but just
+ a way to store some bytes. This is
+ useful for encrypted big integers. */
+ GCRYMPI_FLAG_IMMUTABLE = 4, /* Mark the MPI as immutable. */
+ GCRYMPI_FLAG_CONST = 8, /* Mark the MPI as a constant. */
+ GCRYMPI_FLAG_USER1 = 0x0100,/* User flag 1. */
+ GCRYMPI_FLAG_USER2 = 0x0200,/* User flag 2. */
+ GCRYMPI_FLAG_USER3 = 0x0400,/* User flag 3. */
+ GCRYMPI_FLAG_USER4 = 0x0800 /* User flag 4. */
+ };
+
+
+/* Macros to return pre-defined MPI constants. */
+#define GCRYMPI_CONST_ONE (_gcry_mpi_get_const (1))
+#define GCRYMPI_CONST_TWO (_gcry_mpi_get_const (2))
+#define GCRYMPI_CONST_THREE (_gcry_mpi_get_const (3))
+#define GCRYMPI_CONST_FOUR (_gcry_mpi_get_const (4))
+#define GCRYMPI_CONST_EIGHT (_gcry_mpi_get_const (8))
+
+/* Allocate a new big integer object, initialize it with 0 and
+ initially allocate memory for a number of at least NBITS. */
+gcry_mpi_t gcry_mpi_new (unsigned int nbits);
+
+/* Same as gcry_mpi_new() but allocate in "secure" memory. */
+gcry_mpi_t gcry_mpi_snew (unsigned int nbits);
+
+/* Release the number A and free all associated resources. */
+void gcry_mpi_release (gcry_mpi_t a);
+
+/* Create a new number with the same value as A. */
+gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a);
+
+/* Store the big integer value U in W and release U. */
+void gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u);
+
+/* Store the big integer value U in W. */
+gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);
+
+/* Store the unsigned integer value U in W. */
+gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);
+
+/* Store U as an unsigned int at W or return GPG_ERR_ERANGE. */
+gpg_error_t gcry_mpi_get_ui (unsigned int *w, gcry_mpi_t u);
+
+/* Swap the values of A and B. */
+void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);
+
+/* Return 1 if A is negative; 0 if zero or positive. */
+int gcry_mpi_is_neg (gcry_mpi_t a);
+
+/* W = - U */
+void gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u);
+
+/* W = [W] */
+void gcry_mpi_abs (gcry_mpi_t w);
+
+/* Compare the big integer number U and V returning 0 for equality, a
+ positive value for U > V and a negative for U < V. */
+int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
+
+/* Compare the big integer number U with the unsigned integer V
+ returning 0 for equality, a positive value for U > V and a negative
+ for U < V. */
+int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
+
+/* Convert the external representation of an integer stored in BUFFER
+ with a length of BUFLEN into a newly create MPI returned in
+ RET_MPI. If NSCANNED is not NULL, it will receive the number of
+ bytes actually scanned after a successful operation. */
+gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+ const void *buffer, size_t buflen,
+ size_t *nscanned);
+
+/* Convert the big integer A into the external representation
+ described by FORMAT and store it in the provided BUFFER which has
+ been allocated by the user with a size of BUFLEN bytes. NWRITTEN
+ receives the actual length of the external representation unless it
+ has been passed as NULL. */
+gcry_error_t gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten,
+ const gcry_mpi_t a);
+
+/* Convert the big integer A into the external representation described
+ by FORMAT and store it in a newly allocated buffer which address
+ will be put into BUFFER. NWRITTEN receives the actual lengths of the
+ external representation. */
+gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ const gcry_mpi_t a);
+
+/* Dump the value of A in a format suitable for debugging to
+ Libgcrypt's logging stream. Note that one leading space but no
+ trailing space or linefeed will be printed. It is okay to pass
+ NULL for A. */
+void gcry_mpi_dump (const gcry_mpi_t a);
+
+
+/* W = U + V. */
+void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U + V. V is an unsigned integer. */
+void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);
+
+/* W = U + V mod M. */
+void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U - V. */
+void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U - V. V is an unsigned integer. */
+void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U - V mod M */
+void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * V. */
+void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U * V. V is an unsigned integer. */
+void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U * V mod M. */
+void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * (2 ^ CNT). */
+void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);
+
+/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR,
+ Q or R may be passed as NULL. ROUND should be negative or 0. */
+void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+ gcry_mpi_t dividend, gcry_mpi_t divisor, int round);
+
+/* R = DIVIDEND % DIVISOR */
+void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+
+/* W = B ^ E mod M. */
+void gcry_mpi_powm (gcry_mpi_t w,
+ const gcry_mpi_t b, const gcry_mpi_t e,
+ const gcry_mpi_t m);
+
+/* Set G to the greatest common divisor of A and B.
+ Return true if the G is 1. */
+int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
+
+/* Set X to the multiplicative inverse of A mod M.
+ Return true if the value exists. */
+int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);
+
+/* Create a new point object. NBITS is usually 0. */
+gcry_mpi_point_t gcry_mpi_point_new (unsigned int nbits);
+
+/* Release the object POINT. POINT may be NULL. */
+void gcry_mpi_point_release (gcry_mpi_point_t point);
+
+/* Return a copy of POINT. */
+gcry_mpi_point_t gcry_mpi_point_copy (gcry_mpi_point_t point);
+
+/* Store the projective coordinates from POINT into X, Y, and Z. */
+void gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ gcry_mpi_point_t point);
+
+/* Store the projective coordinates from POINT into X, Y, and Z and
+ release POINT. */
+void gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ gcry_mpi_point_t point);
+
+/* Store the projective coordinates X, Y, and Z into POINT. */
+gcry_mpi_point_t gcry_mpi_point_set (gcry_mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z);
+
+/* Store the projective coordinates X, Y, and Z into POINT and release
+ X, Y, and Z. */
+gcry_mpi_point_t gcry_mpi_point_snatch_set (gcry_mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y,
+ gcry_mpi_t z);
+
+/* Allocate a new context for elliptic curve operations based on the
+ parameters given by KEYPARAM or using CURVENAME. */
+gpg_error_t gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
+ gcry_sexp_t keyparam, const char *curvename);
+
+/* Get a named MPI from an elliptic curve context. */
+gcry_mpi_t gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy);
+
+/* Get a named point from an elliptic curve context. */
+gcry_mpi_point_t gcry_mpi_ec_get_point (const char *name,
+ gcry_ctx_t ctx, int copy);
+
+/* Store a named MPI into an elliptic curve context. */
+gpg_error_t gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
+ gcry_ctx_t ctx);
+
+/* Store a named point into an elliptic curve context. */
+gpg_error_t gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
+ gcry_ctx_t ctx);
+
+/* Decode and store VALUE into RESULT. */
+gpg_error_t gcry_mpi_ec_decode_point (gcry_mpi_point_t result,
+ gcry_mpi_t value, gcry_ctx_t ctx);
+
+/* Store the affine coordinates of POINT into X and Y. */
+int gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
+ gcry_ctx_t ctx);
+
+/* W = 2 * U. */
+void gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx);
+
+/* W = U + V. */
+void gcry_mpi_ec_add (gcry_mpi_point_t w,
+ gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx);
+
+/* W = U - V. */
+void gcry_mpi_ec_sub (gcry_mpi_point_t w,
+ gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx);
+
+/* W = N * U. */
+void gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
+ gcry_ctx_t ctx);
+
+/* Return true if POINT is on the curve described by CTX. */
+int gcry_mpi_ec_curve_point (gcry_mpi_point_t w, gcry_ctx_t ctx);
+
+/* Return the number of bits required to represent A. */
+unsigned int gcry_mpi_get_nbits (gcry_mpi_t a);
+
+/* Return true when bit number N (counting from 0) is set in A. */
+int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A. */
+void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A. */
+void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A and clear all bits greater than N. */
+void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A and all bits greater than N. */
+void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the right and store the result in X. */
+void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the left and store the result in X. */
+void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Store NBITS of the value P points to in A and mark A as an opaque
+ value. On success A received the the ownership of the value P.
+ WARNING: Never use an opaque MPI for anything thing else than
+ gcry_mpi_release, gcry_mpi_get_opaque. */
+gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
+
+/* Store NBITS of the value P points to in A and mark A as an opaque
+ value. The function takes a copy of the provided value P.
+ WARNING: Never use an opaque MPI for anything thing else than
+ gcry_mpi_release, gcry_mpi_get_opaque. */
+gcry_mpi_t gcry_mpi_set_opaque_copy (gcry_mpi_t a,
+ const void *p, unsigned int nbits);
+
+/* Return a pointer to an opaque value stored in A and return its size
+ in NBITS. Note that the returned pointer is still owned by A and
+ that the function should never be used for an non-opaque MPI. */
+void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);
+
+/* Set the FLAG for the big integer A. Currently only the flag
+ GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger
+ stored in "secure" memory. */
+void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Clear FLAG for the big integer A. Note that this function is
+ currently useless as no flags are allowed. */
+void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Return true if the FLAG is set for A. */
+int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Private function - do not use. */
+gcry_mpi_t _gcry_mpi_get_const (int no);
+
+/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of
+ convenience macros for the big integer functions. */
+#ifndef GCRYPT_NO_MPI_MACROS
+#define mpi_new(n) gcry_mpi_new( (n) )
+#define mpi_secure_new( n ) gcry_mpi_snew( (n) )
+#define mpi_release(a) \
+ do \
+ { \
+ gcry_mpi_release ((a)); \
+ (a) = NULL; \
+ } \
+ while (0)
+
+#define mpi_copy( a ) gcry_mpi_copy( (a) )
+#define mpi_snatch( w, u) gcry_mpi_snatch( (w), (u) )
+#define mpi_set( w, u) gcry_mpi_set( (w), (u) )
+#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) )
+#define mpi_get_ui( w, u) gcry_mpi_get_ui( (w), (u) )
+#define mpi_abs( w ) gcry_mpi_abs( (w) )
+#define mpi_neg( w, u) gcry_mpi_neg( (w), (u) )
+#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) )
+#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) )
+#define mpi_is_neg( a ) gcry_mpi_is_neg ((a))
+
+#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
+#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v))
+#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
+#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
+#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v))
+#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
+#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v))
+#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
+#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v))
+#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m))
+#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) )
+#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0)
+#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1)
+#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m))
+#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) )
+#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) )
+
+#define mpi_point_new(n) gcry_mpi_point_new((n))
+#define mpi_point_release(p) \
+ do \
+ { \
+ gcry_mpi_point_release ((p)); \
+ (p) = NULL; \
+ } \
+ while (0)
+#define mpi_point_copy(p) gcry_mpi_point_copy((p))
+#define mpi_point_get(x,y,z,p) gcry_mpi_point_get((x),(y),(z),(p))
+#define mpi_point_snatch_get(x,y,z,p) gcry_mpi_point_snatch_get((x),(y),(z),(p))
+#define mpi_point_set(p,x,y,z) gcry_mpi_point_set((p),(x),(y),(z))
+#define mpi_point_snatch_set(p,x,y,z) gcry_mpi_point_snatch_set((p),(x),(y),(z))
+
+#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a))
+#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b))
+#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b))
+#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b))
+#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b))
+#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
+#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c))
+#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c))
+
+#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) )
+#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) )
+#endif /* GCRYPT_NO_MPI_MACROS */
+
+
+
+/************************************
+ * *
+ * Symmetric Cipher Functions *
+ * *
+ ************************************/
+
+/* The data object used to hold a handle to an encryption object. */
+struct gcry_cipher_handle;
+typedef struct gcry_cipher_handle *gcry_cipher_hd_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* All symmetric encryption algorithms are identified by their IDs.
+ More IDs may be registered at runtime. */
+enum gcry_cipher_algos
+ {
+ GCRY_CIPHER_NONE = 0,
+ GCRY_CIPHER_IDEA = 1,
+ GCRY_CIPHER_3DES = 2,
+ GCRY_CIPHER_CAST5 = 3,
+ GCRY_CIPHER_BLOWFISH = 4,
+ GCRY_CIPHER_SAFER_SK128 = 5,
+ GCRY_CIPHER_DES_SK = 6,
+ GCRY_CIPHER_AES = 7,
+ GCRY_CIPHER_AES192 = 8,
+ GCRY_CIPHER_AES256 = 9,
+ GCRY_CIPHER_TWOFISH = 10,
+
+ /* Other cipher numbers are above 300 for OpenPGP reasons. */
+ GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */
+ GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */
+ GCRY_CIPHER_TWOFISH128 = 303,
+ GCRY_CIPHER_SERPENT128 = 304,
+ GCRY_CIPHER_SERPENT192 = 305,
+ GCRY_CIPHER_SERPENT256 = 306,
+ GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */
+ GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */
+ GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */
+ GCRY_CIPHER_CAMELLIA128 = 310,
+ GCRY_CIPHER_CAMELLIA192 = 311,
+ GCRY_CIPHER_CAMELLIA256 = 312,
+ GCRY_CIPHER_SALSA20 = 313,
+ GCRY_CIPHER_SALSA20R12 = 314,
+ GCRY_CIPHER_GOST28147 = 315,
+ GCRY_CIPHER_CHACHA20 = 316,
+ GCRY_CIPHER_GOST28147_MESH = 317, /* With CryptoPro key meshing. */
+ GCRY_CIPHER_SM4 = 318
+ };
+
+/* The Rijndael algorithm is basically AES, so provide some macros. */
+#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128
+#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192
+#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256
+
+/* The supported encryption modes. Note that not all of them are
+ supported for each algorithm. */
+enum gcry_cipher_modes
+ {
+ GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */
+ GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */
+ GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */
+ GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */
+ GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */
+ GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */
+ GCRY_CIPHER_MODE_CTR = 6, /* Counter. */
+ GCRY_CIPHER_MODE_AESWRAP = 7, /* AES-WRAP algorithm. */
+ GCRY_CIPHER_MODE_CCM = 8, /* Counter with CBC-MAC. */
+ GCRY_CIPHER_MODE_GCM = 9, /* Galois Counter Mode. */
+ GCRY_CIPHER_MODE_POLY1305 = 10, /* Poly1305 based AEAD mode. */
+ GCRY_CIPHER_MODE_OCB = 11, /* OCB3 mode. */
+ GCRY_CIPHER_MODE_CFB8 = 12, /* Cipher feedback (8 bit mode). */
+ GCRY_CIPHER_MODE_XTS = 13, /* XTS mode. */
+ GCRY_CIPHER_MODE_EAX = 14 /* EAX mode. */
+ };
+
+/* Flags used with the open function. */
+enum gcry_cipher_flags
+ {
+ GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */
+ GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */
+ GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */
+ GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */
+ };
+
+/* GCM works only with blocks of 128 bits */
+#define GCRY_GCM_BLOCK_LEN (128 / 8)
+
+/* CCM works only with blocks of 128 bits. */
+#define GCRY_CCM_BLOCK_LEN (128 / 8)
+
+/* OCB works only with blocks of 128 bits. */
+#define GCRY_OCB_BLOCK_LEN (128 / 8)
+
+/* XTS works only with blocks of 128 bits. */
+#define GCRY_XTS_BLOCK_LEN (128 / 8)
+
+/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may
+ be given as an bitwise OR of the gcry_cipher_flags values. */
+gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags);
+
+/* Close the cipher handle H and release all resource. */
+void gcry_cipher_close (gcry_cipher_hd_t h);
+
+/* Perform various operations on the cipher object H. */
+gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
+ size_t buflen);
+
+/* Retrieve various information about the cipher object H. */
+gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+
+/* Retrieve various information about the cipher algorithm ALGO. */
+gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
+ string representation of the algorithm name. For unknown algorithm
+ IDs this function returns "?". */
+const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if
+ the algorithm name is not known. */
+int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+
+/* Given an ASN.1 object identifier in standard IETF dotted decimal
+ format in STRING, return the encryption mode associated with that
+ OID or 0 if not known or applicable. */
+int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;
+
+/* Encrypt the plaintext of size INLEN in IN using the cipher handle H
+ into the buffer OUT which has an allocated length of OUTSIZE. For
+ most algorithms it is possible to pass NULL for in and 0 for INLEN
+ and do a in-place decryption of the data provided in OUT. */
+gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+
+/* The counterpart to gcry_cipher_encrypt. */
+gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+
+/* Set KEY of length KEYLEN bytes for the cipher handle HD. */
+gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd,
+ const void *key, size_t keylen);
+
+
+/* Set initialization vector IV of length IVLEN for the cipher handle HD. */
+gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
+ const void *iv, size_t ivlen);
+
+/* Provide additional authentication data for AEAD modes/ciphers. */
+gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
+ size_t abuflen);
+
+/* Get authentication tag for AEAD modes/ciphers. */
+gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag,
+ size_t taglen);
+
+/* Check authentication tag for AEAD modes/ciphers. */
+gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag,
+ size_t taglen);
+
+/* Reset the handle to the state after open. */
+#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+/* Perform the OpenPGP sync operation if this is enabled for the
+ cipher handle H. */
+#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0)
+
+/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */
+#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \
+ NULL, on )
+
+#define gcry_cipher_set_sbox(h,oid) gcry_cipher_ctl( (h), GCRYCTL_SET_SBOX, \
+ (void *) oid, 0);
+
+/* Indicate to the encrypt and decrypt functions that the next call
+ provides the final data. Only used with some modes. */
+#define gcry_cipher_final(a) \
+ gcry_cipher_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
+/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of
+ block size length, or (NULL,0) to set the CTR to the all-zero block. */
+gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
+ const void *ctr, size_t ctrlen);
+
+/* Retrieve the key length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_keylen (int algo);
+
+/* Retrieve the block length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_blklen (int algo);
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_cipher_test_algo(a) \
+ gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+
+/************************************
+ * *
+ * Asymmetric Cipher Functions *
+ * *
+ ************************************/
+
+/* The algorithms and their IDs we support. */
+enum gcry_pk_algos
+ {
+ GCRY_PK_RSA = 1, /* RSA */
+ GCRY_PK_RSA_E = 2, /* (deprecated: use 1). */
+ GCRY_PK_RSA_S = 3, /* (deprecated: use 1). */
+ GCRY_PK_ELG_E = 16, /* (deprecated: use 20). */
+ GCRY_PK_DSA = 17, /* Digital Signature Algorithm. */
+ GCRY_PK_ECC = 18, /* Generic ECC. */
+ GCRY_PK_ELG = 20, /* Elgamal */
+ GCRY_PK_ECDSA = 301, /* (only for external use). */
+ GCRY_PK_ECDH = 302, /* (only for external use). */
+ GCRY_PK_EDDSA = 303 /* (only for external use). */
+ };
+
+/* Flags describing usage capabilities of a PK algorithm. */
+#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */
+#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */
+#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */
+#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */
+#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */
+
+/* Modes used with gcry_pubkey_get_sexp. */
+#define GCRY_PK_GET_PUBKEY 1
+#define GCRY_PK_GET_SECKEY 2
+
+/* Encrypt the DATA using the public key PKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Decrypt the DATA using the private key SKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Sign the DATA using the private key SKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_sign (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Check the signature SIGVAL on DATA using the public key PKEY. */
+gcry_error_t gcry_pk_verify (gcry_sexp_t sigval,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Check that private KEY is sane. */
+gcry_error_t gcry_pk_testkey (gcry_sexp_t key);
+
+/* Generate a new key pair according to the parameters given in
+ S_PARMS. The new key pair is returned in as an S-expression in
+ R_KEY. */
+gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms);
+
+/* Catch all function for miscellaneous operations. */
+gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen);
+
+/* Retrieve information about the public key algorithm ALGO. */
+gcry_error_t gcry_pk_algo_info (int algo, int what,
+ void *buffer, size_t *nbytes);
+
+/* Map the public key algorithm whose ID is contained in ALGORITHM to
+ a string representation of the algorithm name. For unknown
+ algorithm IDs this functions returns "?". */
+const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a public key algorithm Id. Return 0 if
+ the algorithm name is not known. */
+int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* Return what is commonly referred as the key length for the given
+ public or private KEY. */
+unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
+
+/* Return the so called KEYGRIP which is the SHA-1 hash of the public
+ key parameters expressed in a way depending on the algorithm. */
+unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
+
+/* Return the name of the curve matching KEY. */
+const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator,
+ unsigned int *r_nbits);
+
+/* Return an S-expression with the parameters of the named ECC curve
+ NAME. ALGO must be set to an ECC algorithm. */
+gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
+
+/* Return 0 if the public key algorithm A is available for use. */
+#define gcry_pk_test_algo(a) \
+ gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Return an S-expression representing the context CTX. */
+gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp,
+ int mode, gcry_ctx_t ctx);
+
+/************************************
+ * *
+ * Modern ECC Functions *
+ * *
+ ************************************/
+
+/* The curves we support. */
+enum gcry_ecc_curves
+ {
+ GCRY_ECC_CURVE25519 = 1,
+ GCRY_ECC_CURVE448 = 2
+ };
+
+/* Get the length of point to prepare buffer for the result. */
+unsigned int gcry_ecc_get_algo_keylen (int curveid);
+
+/* Convenience function to compute scalar multiplication of the
+ * Montgomery form of curve. */
+gpg_error_t gcry_ecc_mul_point (int curveid, unsigned char *result,
+ const unsigned char *scalar,
+ const unsigned char *point);
+
+
+
+/************************************
+ * *
+ * Cryptograhic Hash Functions *
+ * *
+ ************************************/
+
+/* Algorithm IDs for the hash functions we know about. Not all of them
+ are implemented. */
+enum gcry_md_algos
+ {
+ GCRY_MD_NONE = 0,
+ GCRY_MD_MD5 = 1,
+ GCRY_MD_SHA1 = 2,
+ GCRY_MD_RMD160 = 3,
+ GCRY_MD_MD2 = 5,
+ GCRY_MD_TIGER = 6, /* TIGER/192 as used by gpg <= 1.3.2. */
+ GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */
+ GCRY_MD_SHA256 = 8,
+ GCRY_MD_SHA384 = 9,
+ GCRY_MD_SHA512 = 10,
+ GCRY_MD_SHA224 = 11,
+
+ GCRY_MD_MD4 = 301,
+ GCRY_MD_CRC32 = 302,
+ GCRY_MD_CRC32_RFC1510 = 303,
+ GCRY_MD_CRC24_RFC2440 = 304,
+ GCRY_MD_WHIRLPOOL = 305,
+ GCRY_MD_TIGER1 = 306, /* TIGER fixed. */
+ GCRY_MD_TIGER2 = 307, /* TIGER2 variant. */
+ GCRY_MD_GOSTR3411_94 = 308, /* GOST R 34.11-94. */
+ GCRY_MD_STRIBOG256 = 309, /* GOST R 34.11-2012, 256 bit. */
+ GCRY_MD_STRIBOG512 = 310, /* GOST R 34.11-2012, 512 bit. */
+ GCRY_MD_GOSTR3411_CP = 311, /* GOST R 34.11-94 with CryptoPro-A S-Box. */
+ GCRY_MD_SHA3_224 = 312,
+ GCRY_MD_SHA3_256 = 313,
+ GCRY_MD_SHA3_384 = 314,
+ GCRY_MD_SHA3_512 = 315,
+ GCRY_MD_SHAKE128 = 316,
+ GCRY_MD_SHAKE256 = 317,
+ GCRY_MD_BLAKE2B_512 = 318,
+ GCRY_MD_BLAKE2B_384 = 319,
+ GCRY_MD_BLAKE2B_256 = 320,
+ GCRY_MD_BLAKE2B_160 = 321,
+ GCRY_MD_BLAKE2S_256 = 322,
+ GCRY_MD_BLAKE2S_224 = 323,
+ GCRY_MD_BLAKE2S_160 = 324,
+ GCRY_MD_BLAKE2S_128 = 325,
+ GCRY_MD_SM3 = 326,
+ GCRY_MD_SHA512_256 = 327,
+ GCRY_MD_SHA512_224 = 328,
+ };
+
+/* Flags used with the open function. */
+enum gcry_md_flags
+ {
+ GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */
+ GCRY_MD_FLAG_HMAC = 2, /* Make an HMAC out of this algorithm. */
+ GCRY_MD_FLAG_BUGEMU1 = 0x0100
+ };
+
+/* (Forward declaration.) */
+struct gcry_md_context;
+
+/* This object is used to hold a handle to a message digest object.
+ This structure is private - only to be used by the public gcry_md_*
+ macros. */
+typedef struct gcry_md_handle
+{
+ /* Actual context. */
+ struct gcry_md_context *ctx;
+
+ /* Buffer management. */
+ int bufpos;
+ int bufsize;
+ unsigned char buf[1];
+} *gcry_md_hd_t;
+
+/* Compatibility types, do not use them. */
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* Create a message digest object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of the gcry_md_flags values. ALGO may be
+ given as 0 if the algorithms to be used are later set using
+ gcry_md_enable. */
+gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);
+
+/* Release the message digest object HD. */
+void gcry_md_close (gcry_md_hd_t hd);
+
+/* Add the message digest algorithm ALGO to the digest object HD. */
+gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo);
+
+/* Create a new digest object as an exact copy of the object HD. */
+gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);
+
+/* Reset the digest object HD to its initial state. */
+void gcry_md_reset (gcry_md_hd_t hd);
+
+/* Perform various operations on the digest object HD. */
+gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd,
+ void *buffer, size_t buflen);
+
+/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that
+ it can update the digest values. This is the actual hash
+ function. */
+void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
+
+/* Read out the final digest from HD return the digest value for
+ algorithm ALGO. */
+unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
+
+/* Read more output from algorithm ALGO to BUFFER of size LENGTH from
+ * digest object HD. Algorithm needs to be 'expendable-output function'. */
+gpg_error_t gcry_md_extract (gcry_md_hd_t hd, int algo, void *buffer,
+ size_t length);
+
+/* Convenience function to calculate the hash from the data in BUFFER
+ of size LENGTH using the algorithm ALGO avoiding the creation of a
+ hash object. The hash is returned in the caller provided buffer
+ DIGEST which must be large enough to hold the digest of the given
+ algorithm. */
+void gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length);
+
+/* Convenience function to hash multiple buffers. */
+gpg_error_t gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
+ const gcry_buffer_t *iov, int iovcnt);
+
+/* Retrieve the algorithm used with HD. This does not work reliable
+ if more than one algorithm is enabled in HD. */
+int gcry_md_get_algo (gcry_md_hd_t hd);
+
+/* Retrieve the length in bytes of the digest yielded by algorithm
+ ALGO. */
+unsigned int gcry_md_get_algo_dlen (int algo);
+
+/* Return true if the the algorithm ALGO is enabled in the digest
+ object A. */
+int gcry_md_is_enabled (gcry_md_hd_t a, int algo);
+
+/* Return true if the digest object A is allocated in "secure" memory. */
+int gcry_md_is_secure (gcry_md_hd_t a);
+
+/* Deprecated: Use gcry_md_is_enabled or gcry_md_is_secure. */
+gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
+ size_t *nbytes) _GCRY_ATTR_INTERNAL;
+
+/* Retrieve various information about the algorithm ALGO. */
+gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Map the digest algorithm id ALGO to a string representation of the
+ algorithm name. For unknown algorithms this function returns
+ "?". */
+const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a digest algorithm Id. Return 0 if
+ the algorithm name is not known. */
+int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* For use with the HMAC feature, the set MAC key to the KEY of
+ KEYLEN bytes. */
+gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen);
+
+/* Start or stop debugging for digest handle HD; i.e. create a file
+ named dbgmd-<n>.<suffix> while hashing. If SUFFIX is NULL,
+ debugging stops and the file will be closed. */
+void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
+
+
+/* Update the hash(s) of H with the character C. This is a buffered
+ version of the gcry_md_write function. */
+#define gcry_md_putc(h,c) \
+ do { \
+ gcry_md_hd_t h__ = (h); \
+ if( (h__)->bufpos == (h__)->bufsize ) \
+ gcry_md_write( (h__), NULL, 0 ); \
+ (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \
+ } while(0)
+
+/* Finalize the digest calculation. This is not really needed because
+ gcry_md_read() does this implicitly. */
+#define gcry_md_final(a) \
+ gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_md_test_algo(a) \
+ gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N
+ must point to size_t variable with the available size of buffer B.
+ After return it will receive the actual size of the returned
+ OID. */
+#define gcry_md_get_asnoid(a,b,n) \
+ gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
+
+
+
+/**********************************************
+ * *
+ * Message Authentication Code Functions *
+ * *
+ **********************************************/
+
+/* The data object used to hold a handle to an encryption object. */
+struct gcry_mac_handle;
+typedef struct gcry_mac_handle *gcry_mac_hd_t;
+
+/* Algorithm IDs for the hash functions we know about. Not all of them
+ are implemented. */
+enum gcry_mac_algos
+ {
+ GCRY_MAC_NONE = 0,
+ GCRY_MAC_GOST28147_IMIT = 1,
+
+ GCRY_MAC_HMAC_SHA256 = 101,
+ GCRY_MAC_HMAC_SHA224 = 102,
+ GCRY_MAC_HMAC_SHA512 = 103,
+ GCRY_MAC_HMAC_SHA384 = 104,
+ GCRY_MAC_HMAC_SHA1 = 105,
+ GCRY_MAC_HMAC_MD5 = 106,
+ GCRY_MAC_HMAC_MD4 = 107,
+ GCRY_MAC_HMAC_RMD160 = 108,
+ GCRY_MAC_HMAC_TIGER1 = 109, /* The fixed TIGER variant */
+ GCRY_MAC_HMAC_WHIRLPOOL = 110,
+ GCRY_MAC_HMAC_GOSTR3411_94 = 111,
+ GCRY_MAC_HMAC_STRIBOG256 = 112,
+ GCRY_MAC_HMAC_STRIBOG512 = 113,
+ GCRY_MAC_HMAC_MD2 = 114,
+ GCRY_MAC_HMAC_SHA3_224 = 115,
+ GCRY_MAC_HMAC_SHA3_256 = 116,
+ GCRY_MAC_HMAC_SHA3_384 = 117,
+ GCRY_MAC_HMAC_SHA3_512 = 118,
+ GCRY_MAC_HMAC_GOSTR3411_CP = 119,
+ GCRY_MAC_HMAC_BLAKE2B_512 = 120,
+ GCRY_MAC_HMAC_BLAKE2B_384 = 121,
+ GCRY_MAC_HMAC_BLAKE2B_256 = 122,
+ GCRY_MAC_HMAC_BLAKE2B_160 = 123,
+ GCRY_MAC_HMAC_BLAKE2S_256 = 124,
+ GCRY_MAC_HMAC_BLAKE2S_224 = 125,
+ GCRY_MAC_HMAC_BLAKE2S_160 = 126,
+ GCRY_MAC_HMAC_BLAKE2S_128 = 127,
+ GCRY_MAC_HMAC_SM3 = 128,
+ GCRY_MAC_HMAC_SHA512_256 = 129,
+ GCRY_MAC_HMAC_SHA512_224 = 130,
+
+ GCRY_MAC_CMAC_AES = 201,
+ GCRY_MAC_CMAC_3DES = 202,
+ GCRY_MAC_CMAC_CAMELLIA = 203,
+ GCRY_MAC_CMAC_CAST5 = 204,
+ GCRY_MAC_CMAC_BLOWFISH = 205,
+ GCRY_MAC_CMAC_TWOFISH = 206,
+ GCRY_MAC_CMAC_SERPENT = 207,
+ GCRY_MAC_CMAC_SEED = 208,
+ GCRY_MAC_CMAC_RFC2268 = 209,
+ GCRY_MAC_CMAC_IDEA = 210,
+ GCRY_MAC_CMAC_GOST28147 = 211,
+ GCRY_MAC_CMAC_SM4 = 212,
+
+ GCRY_MAC_GMAC_AES = 401,
+ GCRY_MAC_GMAC_CAMELLIA = 402,
+ GCRY_MAC_GMAC_TWOFISH = 403,
+ GCRY_MAC_GMAC_SERPENT = 404,
+ GCRY_MAC_GMAC_SEED = 405,
+
+ GCRY_MAC_POLY1305 = 501,
+ GCRY_MAC_POLY1305_AES = 502,
+ GCRY_MAC_POLY1305_CAMELLIA = 503,
+ GCRY_MAC_POLY1305_TWOFISH = 504,
+ GCRY_MAC_POLY1305_SERPENT = 505,
+ GCRY_MAC_POLY1305_SEED = 506
+ };
+
+/* Flags used with the open function. */
+enum gcry_mac_flags
+ {
+ GCRY_MAC_FLAG_SECURE = 1 /* Allocate all buffers in "secure" memory. */
+ };
+
+/* Create a MAC handle for algorithm ALGO. FLAGS may be given as an bitwise OR
+ of the gcry_mac_flags values. CTX maybe NULL or gcry_ctx_t object to be
+ associated with HANDLE. */
+gcry_error_t gcry_mac_open (gcry_mac_hd_t *handle, int algo,
+ unsigned int flags, gcry_ctx_t ctx);
+
+/* Close the MAC handle H and release all resource. */
+void gcry_mac_close (gcry_mac_hd_t h);
+
+/* Perform various operations on the MAC object H. */
+gcry_error_t gcry_mac_ctl (gcry_mac_hd_t h, int cmd, void *buffer,
+ size_t buflen);
+
+/* Retrieve various information about the MAC algorithm ALGO. */
+gcry_error_t gcry_mac_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Set KEY of length KEYLEN bytes for the MAC handle HD. */
+gcry_error_t gcry_mac_setkey (gcry_mac_hd_t hd, const void *key,
+ size_t keylen);
+
+/* Set initialization vector IV of length IVLEN for the MAC handle HD. */
+gcry_error_t gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv,
+ size_t ivlen);
+
+/* Pass LENGTH bytes of data in BUFFER to the MAC object HD so that
+ it can update the MAC values. */
+gcry_error_t gcry_mac_write (gcry_mac_hd_t hd, const void *buffer,
+ size_t length);
+
+/* Read out the final authentication code from the MAC object HD to BUFFER. */
+gcry_error_t gcry_mac_read (gcry_mac_hd_t hd, void *buffer, size_t *buflen);
+
+/* Verify the final authentication code from the MAC object HD with BUFFER. */
+gcry_error_t gcry_mac_verify (gcry_mac_hd_t hd, const void *buffer,
+ size_t buflen);
+
+/* Retrieve the algorithm used with MAC. */
+int gcry_mac_get_algo (gcry_mac_hd_t hd);
+
+/* Retrieve the length in bytes of the MAC yielded by algorithm ALGO. */
+unsigned int gcry_mac_get_algo_maclen (int algo);
+
+/* Retrieve the default key length in bytes used with algorithm A. */
+unsigned int gcry_mac_get_algo_keylen (int algo);
+
+/* Map the MAC algorithm whose ID is contained in ALGORITHM to a
+ string representation of the algorithm name. For unknown algorithm
+ IDs this function returns "?". */
+const char *gcry_mac_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm name NAME to an MAC algorithm ID. Return 0 if
+ the algorithm name is not known. */
+int gcry_mac_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+
+/* Reset the handle to the state after open/setkey. */
+#define gcry_mac_reset(h) gcry_mac_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_mac_test_algo(a) \
+ gcry_mac_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+
+/******************************
+ * *
+ * Key Derivation Functions *
+ * *
+ ******************************/
+
+/* Algorithm IDs for the KDFs. */
+enum gcry_kdf_algos
+ {
+ GCRY_KDF_NONE = 0,
+ GCRY_KDF_SIMPLE_S2K = 16,
+ GCRY_KDF_SALTED_S2K = 17,
+ GCRY_KDF_ITERSALTED_S2K = 19,
+ GCRY_KDF_PBKDF1 = 33,
+ GCRY_KDF_PBKDF2 = 34,
+ GCRY_KDF_SCRYPT = 48
+ };
+
+/* Derive a key from a passphrase. */
+gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int subalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer);
+
+
+
+
+/************************************
+ * *
+ * Random Generating Functions *
+ * *
+ ************************************/
+
+/* The type of the random number generator. */
+enum gcry_rng_types
+ {
+ GCRY_RNG_TYPE_STANDARD = 1, /* The default CSPRNG generator. */
+ GCRY_RNG_TYPE_FIPS = 2, /* The FIPS X9.31 AES generator. */
+ GCRY_RNG_TYPE_SYSTEM = 3 /* The system's native generator. */
+ };
+
+/* The possible values for the random quality. The rule of thumb is
+ to use STRONG for session keys and VERY_STRONG for key material.
+ WEAK is usually an alias for STRONG and should not be used anymore
+ (except with gcry_mpi_randomize); use gcry_create_nonce instead. */
+typedef enum gcry_random_level
+ {
+ GCRY_WEAK_RANDOM = 0,
+ GCRY_STRONG_RANDOM = 1,
+ GCRY_VERY_STRONG_RANDOM = 2
+ }
+gcry_random_level_t;
+
+/* Fill BUFFER with LENGTH bytes of random, using random numbers of
+ quality LEVEL. */
+void gcry_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+
+/* Add the external random from BUFFER with LENGTH bytes into the
+ pool. QUALITY should either be -1 for unknown or in the range of 0
+ to 100 */
+gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length,
+ int quality);
+
+/* If random numbers are used in an application, this macro should be
+ called from time to time so that new stuff gets added to the
+ internal pool of the RNG. */
+#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL)
+
+
+/* Return NBYTES of allocated random using a random numbers of quality
+ LEVEL. */
+void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+
+/* Return NBYTES of allocated random using a random numbers of quality
+ LEVEL. The random is returned in "secure" memory. */
+void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+
+
+/* Set the big integer W to a random value of NBITS using a random
+ generator with quality LEVEL. Note that by using a level of
+ GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */
+void gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level);
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void gcry_create_nonce (void *buffer, size_t length);
+
+
+
+
+
+/*******************************/
+/* */
+/* Prime Number Functions */
+/* */
+/*******************************/
+
+/* Mode values passed to a gcry_prime_check_func_t. */
+#define GCRY_PRIME_CHECK_AT_FINISH 0
+#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1
+#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2
+
+/* The function should return 1 if the operation shall continue, 0 to
+ reject the prime candidate. */
+typedef int (*gcry_prime_check_func_t) (void *arg, int mode,
+ gcry_mpi_t candidate);
+
+/* Flags for gcry_prime_generate(): */
+
+/* Allocate prime numbers and factors in secure memory. */
+#define GCRY_PRIME_FLAG_SECRET (1 << 0)
+
+/* Make sure that at least one prime factor is of size
+ `FACTOR_BITS'. */
+#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1)
+
+/* Generate a new prime number of PRIME_BITS bits and store it in
+ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of
+ (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is
+ non-zero, allocate a new, NULL-terminated array holding the prime
+ factors and store it in FACTORS. FLAGS might be used to influence
+ the prime number generation process. */
+gcry_error_t gcry_prime_generate (gcry_mpi_t *prime,
+ unsigned int prime_bits,
+ unsigned int factor_bits,
+ gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func,
+ void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags);
+
+/* Find a generator for PRIME where the factorization of (prime-1) is
+ in the NULL terminated array FACTORS. Return the generator as a
+ newly allocated MPI in R_G. If START_G is not NULL, use this as
+ the start for the search. */
+gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime,
+ gcry_mpi_t *factors,
+ gcry_mpi_t start_g);
+
+
+/* Convenience function to release the FACTORS array. */
+void gcry_prime_release_factors (gcry_mpi_t *factors);
+
+
+/* Check whether the number X is prime. */
+gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
+
+
+
+/************************************
+ * *
+ * Miscellaneous Stuff *
+ * *
+ ************************************/
+
+/* Release the context object CTX. */
+void gcry_ctx_release (gcry_ctx_t ctx);
+
+/* Log data using Libgcrypt's own log interface. */
+void gcry_log_debug (const char *fmt, ...) _GCRY_GCC_ATTR_PRINTF(1,2);
+void gcry_log_debughex (const char *text, const void *buffer, size_t length);
+void gcry_log_debugmpi (const char *text, gcry_mpi_t mpi);
+void gcry_log_debugpnt (const char *text,
+ gcry_mpi_point_t point, gcry_ctx_t ctx);
+void gcry_log_debugsxp (const char *text, gcry_sexp_t sexp);
+
+char *gcry_get_config (int mode, const char *what);
+
+/* Log levels used by the internal logging facility. */
+enum gcry_log_levels
+ {
+ GCRY_LOG_CONT = 0, /* (Continue the last log line.) */
+ GCRY_LOG_INFO = 10,
+ GCRY_LOG_WARN = 20,
+ GCRY_LOG_ERROR = 30,
+ GCRY_LOG_FATAL = 40,
+ GCRY_LOG_BUG = 50,
+ GCRY_LOG_DEBUG = 100
+ };
+
+/* Type for progress handlers. */
+typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int);
+
+/* Type for memory allocation handlers. */
+typedef void *(*gcry_handler_alloc_t) (size_t n);
+
+/* Type for secure memory check handlers. */
+typedef int (*gcry_handler_secure_check_t) (const void *);
+
+/* Type for memory reallocation handlers. */
+typedef void *(*gcry_handler_realloc_t) (void *p, size_t n);
+
+/* Type for memory free handlers. */
+typedef void (*gcry_handler_free_t) (void *);
+
+/* Type for out-of-memory handlers. */
+typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int);
+
+/* Type for fatal error handlers. */
+typedef void (*gcry_handler_error_t) (void *, int, const char *);
+
+/* Type for logging handlers. */
+typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list);
+
+/* Certain operations can provide progress information. This function
+ is used to register a handler for retrieving these information. */
+void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data);
+
+
+/* Register a custom memory allocation functions. */
+void gcry_set_allocation_handler (
+ gcry_handler_alloc_t func_alloc,
+ gcry_handler_alloc_t func_alloc_secure,
+ gcry_handler_secure_check_t func_secure_check,
+ gcry_handler_realloc_t func_realloc,
+ gcry_handler_free_t func_free);
+
+/* Register a function used instead of the internal out of memory
+ handler. */
+void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque);
+
+/* Register a function used instead of the internal fatal error
+ handler. */
+void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque);
+
+/* Register a function used instead of the internal logging
+ facility. */
+void gcry_set_log_handler (gcry_handler_log_t f, void *opaque);
+
+/* Reserved for future use. */
+void gcry_set_gettext_handler (const char *(*f)(const char*));
+
+/* Libgcrypt uses its own memory allocation. It is important to use
+ gcry_free () to release memory allocated by libgcrypt. */
+void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_realloc (void *a, size_t n);
+char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xrealloc (void *a, size_t n);
+char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC;
+void gcry_free (void *a);
+
+/* Return true if A is allocated in "secure" memory. */
+int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
+
+/* Return true if Libgcrypt is in FIPS mode. */
+#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+
+
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* _GCRYPT_H */
+/*
+@emacs_local_vars_begin@
+@emacs_local_vars_read_only@
+@emacs_local_vars_end@
+*/
diff --git a/comm/third_party/libgcrypt/src/gcryptrnd.c b/comm/third_party/libgcrypt/src/gcryptrnd.c
new file mode 100644
index 0000000000..b13931b6e8
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/gcryptrnd.c
@@ -0,0 +1,680 @@
+/* gcryptrnd.c - Libgcrypt Random Number Daemon
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * Gcryptend is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Gcryptrnd 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 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.
+ */
+
+/* We require vsyslog pth
+ We need to test for: setrlimit
+
+ We should also prioritize requests. This is best done by putting
+ the requests into queues and have a main thread processing these
+ queues.
+
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pth.h>
+#include <gcrypt.h>
+
+#define PGM "gcryptrnd"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+/* Pth wrapper function definitions. */
+GCRY_THREAD_OPTION_PTH_IMPL;
+
+
+/* Flag set to true if we have been daemonized. */
+static int running_detached;
+/* Flag indicating that a shutdown has been requested. */
+static int shutdown_pending;
+/* Counter for active connections. */
+static int active_connections;
+
+
+
+/* Local prototypes. */
+static void serve (int listen_fd);
+
+
+
+
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+ macros may be used instead. */
+#define wipememory2(_ptr,_set,_len) do { \
+ volatile char *_vptr=(volatile char *)(_ptr); \
+ size_t _vlen=(_len); \
+ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+ } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+
+
+
+/* Error printing utility. PRIORITY should be one of syslog's
+ priority levels. This functions prints to the stderr or syslog
+ depending on whether we are already daemonized. */
+static void
+logit (int priority, const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ if (running_detached)
+ {
+ vsyslog (priority, format, arg_ptr);
+ }
+ else
+ {
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ }
+ va_end (arg_ptr);
+}
+
+/* Callback used by libgcrypt for logging. */
+static void
+my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr)
+{
+ (void)dummy;
+
+ /* Map the log levels. */
+ switch (level)
+ {
+ case GCRY_LOG_CONT: level = LOG_INFO /* FIXME */; break;
+ case GCRY_LOG_INFO: level = LOG_INFO; break;
+ case GCRY_LOG_WARN: level = LOG_WARNING; break;
+ case GCRY_LOG_ERROR:level = LOG_ERR; break;
+ case GCRY_LOG_FATAL:level = LOG_CRIT; break;
+ case GCRY_LOG_BUG: level = LOG_CRIT; break;
+ case GCRY_LOG_DEBUG:level = LOG_DEBUG; break;
+ default: level = LOG_ERR; break;
+ }
+ if (running_detached)
+ {
+ vsyslog (level, format, arg_ptr);
+ }
+ else
+ {
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ if (!*format || format[strlen (format)-1] != '\n')
+ putc ('\n', stderr);
+ }
+}
+
+
+/* The cleanup handler - used to wipe out the secure memory. */
+static void
+cleanup (void)
+{
+ gcry_control (GCRYCTL_TERM_SECMEM );
+}
+
+
+/* Make us a daemon and open the syslog. */
+static void
+daemonize (void)
+{
+ int i;
+ pid_t pid;
+
+ fflush (NULL);
+
+ pid = fork ();
+ if (pid == (pid_t)-1)
+ {
+ logit (LOG_CRIT, "fork failed: %s", strerror (errno));
+ exit (1);
+ }
+ if (pid)
+ exit (0);
+
+ if (setsid() == -1)
+ {
+ logit (LOG_CRIT, "setsid() failed: %s", strerror(errno));
+ exit (1);
+ }
+
+ signal (SIGHUP, SIG_IGN);
+
+ pid = fork ();
+ if (pid == (pid_t)-1)
+ {
+ logit (LOG_CRIT, PGM ": second fork failed: %s", strerror (errno));
+ exit (1);
+ }
+ if (pid)
+ exit (0); /* First child exits. */
+
+ running_detached = 1;
+
+ if (chdir("/"))
+ {
+ logit (LOG_CRIT, "chdir(\"/\") failed: %s", strerror (errno));
+ exit (1);
+ }
+ umask (0);
+
+ for (i=0; i <= 2; i++)
+ close (i);
+
+ openlog (PGM, LOG_PID, LOG_DAEMON);
+}
+
+
+static void
+disable_core_dumps (void)
+{
+#ifdef HAVE_SETRLIMIT
+ struct rlimit limit;
+
+ if (getrlimit (RLIMIT_CORE, &limit))
+ limit.rlim_max = 0;
+ limit.rlim_cur = 0;
+ if( !setrlimit (RLIMIT_CORE, &limit) )
+ return 0;
+ if (errno != EINVAL && errno != ENOSYS)
+ logit (LOG_ERR, "can't disable core dumps: %s\n", strerror (errno));
+#endif /* HAVE_SETRLIMIT */
+}
+
+
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2006 Free Software Foundation, Inc.\n"
+ "License GPLv2+: GNU GPL version 2 or later "
+ "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] [SOCKETNAME]\n"
+ "Start Libgcrypt's random number daemon listening"
+ " on socket SOCKETNAME\n"
+ "SOCKETNAME defaults to XXX\n"
+ "\n"
+ " --no-detach do not deatach from the console\n"
+ " --version print version of the program and exit\n"
+ " --help display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] [SOCKETNAME]\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int no_detach = 0;
+ gpg_error_t err;
+ struct sockaddr_un *srvr_addr;
+ socklen_t addrlen;
+ int fd;
+ int rc;
+ const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
+
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--no-detach"))
+ {
+ no_detach = 1;
+ argc--; argv++;
+ }
+ else
+ print_usage ();
+ }
+
+ if (argc == 1)
+ socketname = argv[0];
+ else if (argc > 1)
+ print_usage ();
+
+ if (!no_detach)
+ daemonize ();
+
+ signal (SIGPIPE, SIG_IGN);
+
+ logit (LOG_NOTICE, "started version " VERSION );
+
+ /* Libgcrypt requires us to register the threading model before we
+ do anything else with it. Note that this also calls pth_init. We
+ do the initialization while already running as a daemon to avoid
+ overhead with double initialization of Libgcrypt. */
+ err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
+ if (err)
+ {
+ logit (LOG_CRIT, "can't register GNU Pth with Libgcrypt: %s",
+ gpg_strerror (err));
+ exit (1);
+ }
+
+ /* Check that the libgcrypt version is sufficient. */
+ if (!gcry_check_version (VERSION) )
+ {
+ logit (LOG_CRIT, "libgcrypt is too old (need %s, have %s)",
+ VERSION, gcry_check_version (NULL) );
+ exit (1);
+ }
+
+ /* Register the logging callback and tell Libcgrypt to put the
+ random pool into secure memory. */
+ gcry_set_log_handler (my_gcry_logger, NULL);
+ gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
+
+ /* Obviously we don't want to allow any core dumps. */
+ disable_core_dumps ();
+
+ /* Initialize the secure memory stuff which will also drop any extra
+ privileges we have. */
+ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+ /* Register a cleanup handler. */
+ atexit (cleanup);
+
+ /* Create and listen on the socket. */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ logit (LOG_CRIT, "can't create socket: %s", strerror (errno));
+ exit (1);
+ }
+ srvr_addr = gcry_xmalloc (sizeof *srvr_addr);
+ memset (srvr_addr, 0, sizeof *srvr_addr);
+ srvr_addr->sun_family = AF_UNIX;
+ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
+ {
+ logit (LOG_CRIT, "socket name `%s' too long", socketname);
+ exit (1);
+ }
+ strcpy (srvr_addr->sun_path, socketname);
+ addrlen = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (srvr_addr->sun_path) + 1);
+ rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
+ if (rc == -1 && errno == EADDRINUSE)
+ {
+ remove (socketname);
+ rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
+ }
+ if (rc == -1)
+ {
+ logit (LOG_CRIT, "error binding socket to `%s': %s",
+ srvr_addr->sun_path, strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ if (listen (fd, 5 ) == -1)
+ {
+ logit (LOG_CRIT, "listen() failed: %s", strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ logit (LOG_INFO, "listening on socket `%s', fd=%d",
+ srvr_addr->sun_path, fd);
+
+ serve (fd);
+ close (fd);
+
+ logit (LOG_NOTICE, "stopped version " VERSION );
+ return 0;
+}
+
+
+/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
+ success or another value on write error. */
+static int
+writen (int fd, const void *buffer, size_t length)
+{
+ while (length)
+ {
+ ssize_t n = pth_write (fd, buffer, length);
+ if (n < 0)
+ {
+ logit (LOG_ERR, "connection %d: write error: %s",
+ fd, strerror (errno));
+ return -1; /* write error */
+ }
+ length -= n;
+ buffer = (const char*)buffer + n;
+ }
+ return 0; /* Okay */
+}
+
+
+/* Send an error response back. Returns 0 on success. */
+static int
+send_error (int fd, int errcode)
+{
+ unsigned char buf[2];
+
+ buf[0] = errcode;
+ buf[1] = 0;
+ return writen (fd, buf, 2 );
+}
+
+/* Send a pong response back. Returns 0 on success or another value
+ on write error. */
+static int
+send_pong (int fd)
+{
+ return writen (fd, "\x00\x04pong", 6);
+}
+
+/* Send a nonce of size LENGTH back. Return 0 on success. */
+static int
+send_nonce (int fd, int length)
+{
+ unsigned char buf[2+255];
+ int rc;
+
+ assert (length >= 0 && length <= 255);
+ buf[0] = 0;
+ buf[1] = length;
+ gcry_create_nonce (buf+2, length);
+ rc = writen (fd, buf, 2+length );
+ wipememory (buf+2, length);
+ return rc;
+}
+
+/* Send a random of size LENGTH with quality LEVEL back. Return 0 on
+ success. */
+static int
+send_random (int fd, int length, int level)
+{
+ unsigned char buf[2+255];
+ int rc;
+
+ assert (length >= 0 && length <= 255);
+ assert (level == GCRY_STRONG_RANDOM || level == GCRY_VERY_STRONG_RANDOM);
+ buf[0] = 0;
+ buf[1] = length;
+ /* Note that we don't bother putting the random stuff into secure
+ memory because this daemon is anyway intended to be run under
+ root and it is questionable whether the kernel buffers etc. are
+ equally well protected. */
+ gcry_randomize (buf+2, length, level);
+ rc = writen (fd, buf, 2+length );
+ wipememory (buf+2, length);
+ return rc;
+}
+
+/* Main processing loop for a connection.
+
+ A request is made up of:
+
+ 1 byte Total length of request; must be 3
+ 1 byte Command
+ 0 = Ping
+ 10 = GetNonce
+ 11 = GetStrongRandom
+ 12 = GetVeryStrongRandom
+ (all other values are reserved)
+ 1 byte Number of requested bytes.
+ This is ignored for command Ping.
+
+ A response is made up of:
+
+ 1 byte Error Code
+ 0 = Everything is fine
+ 1 = Bad Command
+ 0xff = Other error.
+ (For a bad request the connection will simply be closed)
+ 1 byte Length of data
+ n byte data
+
+ The requests are read as long as the connection is open.
+
+
+ */
+static void
+connection_loop (int fd)
+{
+ unsigned char request[3];
+ unsigned char *p;
+ int nleft, n;
+ int rc;
+
+ for (;;)
+ {
+ for (nleft=3, p=request; nleft > 0; )
+ {
+ n = pth_read (fd, p, nleft);
+ if (!n && p == request)
+ return; /* Client terminated connection. */
+ if (n <= 0)
+ {
+ logit (LOG_ERR, "connection %d: read error: %s",
+ fd, n? strerror (errno) : "Unexpected EOF");
+ return;
+ }
+ p += n;
+ nleft -= n;
+ }
+ if (request[0] != 3)
+ {
+ logit (LOG_ERR, "connection %d: invalid length (%d) of request",
+ fd, request[0]);
+ return;
+ }
+
+ switch (request[1])
+ {
+ case 0: /* Ping */
+ rc = send_pong (fd);
+ break;
+ case 10: /* GetNonce */
+ rc = send_nonce (fd, request[2]);
+ break;
+ case 11: /* GetStrongRandom */
+ rc = send_random (fd, request[2], GCRY_STRONG_RANDOM);
+ break;
+ case 12: /* GetVeryStrongRandom */
+ rc = send_random (fd, request[2], GCRY_VERY_STRONG_RANDOM);
+ break;
+
+ default: /* Invalid command */
+ rc = send_error (fd, 1);
+ break;
+ }
+ if (rc)
+ break; /* A write error occurred while sending the response. */
+ }
+}
+
+
+
+/* Entry point for a connection's thread. */
+static void *
+connection_thread (void *arg)
+{
+ int fd = (int)arg;
+
+ active_connections++;
+ logit (LOG_INFO, "connection handler for fd %d started", fd);
+
+ connection_loop (fd);
+
+ close (fd);
+ logit (LOG_INFO, "connection handler for fd %d terminated", fd);
+ active_connections--;
+
+ return NULL;
+}
+
+
+/* This signal handler is called from the main loop between acepting
+ connections. It is called on the regular stack, thus no special
+ caution needs to be taken. It returns true to indicate that the
+ process should terminate. */
+static int
+handle_signal (int signo)
+{
+ switch (signo)
+ {
+ case SIGHUP:
+ logit (LOG_NOTICE, "SIGHUP received - re-reading configuration");
+ break;
+
+ case SIGUSR1:
+ logit (LOG_NOTICE, "SIGUSR1 received - no action defined");
+ break;
+
+ case SIGUSR2:
+ logit (LOG_NOTICE, "SIGUSR2 received - no action defined");
+ break;
+
+ case SIGTERM:
+ if (!shutdown_pending)
+ logit (LOG_NOTICE, "SIGTERM received - shutting down ...");
+ else
+ logit (LOG_NOTICE, "SIGTERM received - still %d active connections",
+ active_connections);
+ shutdown_pending++;
+ if (shutdown_pending > 2)
+ {
+ logit (LOG_NOTICE, "shutdown forced");
+ return 1;
+ }
+ break;
+
+ case SIGINT:
+ logit (LOG_NOTICE, "SIGINT received - immediate shutdown");
+ return 1;
+
+ default:
+ logit (LOG_NOTICE, "signal %d received - no action defined\n", signo);
+ }
+ return 0;
+}
+
+
+
+/* Main server loop. This is called with the FD of the listening
+ socket. */
+static void
+serve (int listen_fd)
+{
+ pth_attr_t tattr;
+ pth_event_t ev;
+ sigset_t sigs;
+ int signo;
+ struct sockaddr_un paddr;
+ socklen_t plen = sizeof (paddr);
+ int fd;
+
+ tattr = pth_attr_new();
+ pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
+ pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
+ pth_attr_set (tattr, PTH_ATTR_NAME, "connection");
+
+ sigemptyset (&sigs);
+ sigaddset (&sigs, SIGHUP);
+ sigaddset (&sigs, SIGUSR1);
+ sigaddset (&sigs, SIGUSR2);
+ sigaddset (&sigs, SIGINT);
+ sigaddset (&sigs, SIGTERM);
+ ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
+
+ for (;;)
+ {
+ if (shutdown_pending)
+ {
+ if (!active_connections)
+ break; /* Ready. */
+
+ /* Do not accept anymore connections but wait for existing
+ connections to terminate. */
+ signo = 0;
+ pth_wait (ev);
+ if (pth_event_occurred (ev) && signo)
+ if (handle_signal (signo))
+ break; /* Stop the loop. */
+ continue;
+ }
+
+ gcry_fast_random_poll ();
+ fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
+ if (fd == -1)
+ {
+ if (pth_event_occurred (ev))
+ {
+ if (handle_signal (signo))
+ break; /* Stop the loop. */
+ continue;
+ }
+ logit (LOG_WARNING, "accept failed: %s - waiting 1s\n",
+ strerror (errno));
+ gcry_fast_random_poll ();
+ pth_sleep (1);
+ continue;
+ }
+
+ if (!pth_spawn (tattr, connection_thread, (void*)fd))
+ {
+ logit (LOG_ERR, "error spawning connection handler: %s\n",
+ strerror (errno) );
+ close (fd);
+ }
+ }
+
+ pth_event_free (ev, PTH_FREE_ALL);
+}
diff --git a/comm/third_party/libgcrypt/src/getrandom.c b/comm/third_party/libgcrypt/src/getrandom.c
new file mode 100644
index 0000000000..f9bb5c0c5f
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/getrandom.c
@@ -0,0 +1,326 @@
+/* getrandom.c - Libgcrypt Random Number client
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * Getrandom is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Getrandom 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 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define PGM "getrandom"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+
+static void
+logit (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ va_end (arg_ptr);
+}
+
+
+/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
+ success or another value on write error. */
+static int
+writen (int fd, const void *buffer, size_t length)
+{
+ while (length)
+ {
+ ssize_t n;
+
+ do
+ n = write (fd, buffer, length);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("write error: %s", strerror (errno));
+ return -1; /* write error */
+ }
+ length -= n;
+ buffer = (const char *)buffer + n;
+ }
+ return 0; /* Okay */
+}
+
+
+
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2006 Free Software Foundation, Inc.\n"
+ "License GPLv2+: GNU GPL version 2 or later "
+ "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] NBYTES\n"
+ "Connect to libgcrypt's random number daemon and "
+ "return random numbers"
+ "\n"
+ " --nonce Return weak random suitable for a nonce\n"
+ " --very-strong Return very strong random\n"
+ " --ping Send a ping\n"
+ " --socket NAME Name of sockket to connect to\n"
+ " --hex Return result as a hex dump\n"
+ " --verbose Show what we are doing\n"
+ " --version Print version of the program and exit\n"
+ " --help Display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ struct sockaddr_un *srvr_addr;
+ socklen_t addrlen;
+ int fd;
+ int rc;
+ unsigned char buffer[300];
+ int nleft, nread;
+ const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
+ int do_ping = 0;
+ int get_nonce = 0;
+ int get_very_strong = 0;
+ int req_nbytes, nbytes, n;
+ int verbose = 0;
+ int fail = 0;
+ int do_hex = 0;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--socket") && argc > 1 )
+ {
+ argc--; argv++;
+ socketname = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--nonce"))
+ {
+ argc--; argv++;
+ get_nonce = 1;
+ }
+ else if (!strcmp (*argv, "--very-strong"))
+ {
+ argc--; argv++;
+ get_very_strong = 1;
+ }
+ else if (!strcmp (*argv, "--ping"))
+ {
+ argc--; argv++;
+ do_ping = 1;
+ }
+ else if (!strcmp (*argv, "--hex"))
+ {
+ argc--; argv++;
+ do_hex = 1;
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ argc--; argv++;
+ verbose = 1;
+ }
+ else
+ print_usage ();
+ }
+
+
+ if (!argc && do_ping)
+ ; /* This is allowed. */
+ else if (argc != 1)
+ print_usage ();
+ req_nbytes = argc? atoi (*argv) : 0;
+
+ if (req_nbytes < 0)
+ print_usage ();
+
+ /* Create a socket. */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ logit ("can't create socket: %s", strerror (errno));
+ exit (1);
+ }
+ srvr_addr = malloc (sizeof *srvr_addr);
+ if (!srvr_addr)
+ {
+ logit ("malloc failed: %s", strerror (errno));
+ exit (1);
+ }
+ memset (srvr_addr, 0, sizeof *srvr_addr);
+ srvr_addr->sun_family = AF_UNIX;
+ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
+ {
+ logit ("socket name `%s' too long", socketname);
+ exit (1);
+ }
+ strcpy (srvr_addr->sun_path, socketname);
+ addrlen = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (srvr_addr->sun_path) + 1);
+ rc = connect (fd, (struct sockaddr*) srvr_addr, addrlen);
+ if (rc == -1)
+ {
+ logit ("error connecting socket `%s': %s",
+ srvr_addr->sun_path, strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ do
+ {
+ nbytes = req_nbytes > 255? 255 : req_nbytes;
+ req_nbytes -= nbytes;
+
+ buffer[0] = 3;
+ if (do_ping)
+ buffer[1] = 0;
+ else if (get_nonce)
+ buffer[1] = 10;
+ else if (get_very_strong)
+ buffer[1] = 12;
+ else
+ buffer[1] = 11;
+ buffer[2] = nbytes;
+ if (writen (fd, buffer, 3))
+ fail = 1;
+ else
+ {
+ for (nleft=2, nread=0; nleft > 0; )
+ {
+ do
+ n = read (fd, buffer+nread, nleft);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("read error: %s", strerror (errno));
+ exit (1);
+ }
+ nleft -= n;
+ nread += n;
+ if (nread && buffer[0])
+ {
+ logit ("server returned error code %d", buffer[0]);
+ exit (1);
+ }
+ }
+ if (verbose)
+ logit ("received response with %d bytes of data", buffer[1]);
+ if (buffer[1] < nbytes)
+ {
+ logit ("warning: server returned less bytes than requested");
+ fail = 1;
+ }
+ else if (buffer[1] > nbytes && !do_ping)
+ {
+ logit ("warning: server returned more bytes than requested");
+ fail = 1;
+ }
+ nbytes = buffer[1];
+ if (nbytes > sizeof buffer)
+ {
+ logit ("buffer too short to receive data");
+ exit (1);
+ }
+
+ for (nleft=nbytes, nread=0; nleft > 0; )
+ {
+ do
+ n = read (fd, buffer+nread, nleft);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("read error: %s", strerror (errno));
+ exit (1);
+ }
+ nleft -= n;
+ nread += n;
+ }
+
+ if (do_hex)
+ {
+ for (n=0; n < nbytes; n++)
+ {
+ if (!n)
+ ;
+ else if (!(n % 16))
+ putchar ('\n');
+ else
+ putchar (' ');
+ printf ("%02X", buffer[n]);
+ }
+ if (nbytes)
+ putchar ('\n');
+ }
+ else
+ {
+ if (fwrite (buffer, nbytes, 1, stdout) != 1)
+ {
+ logit ("error writing to stdout: %s", strerror (errno));
+ fail = 1;
+ }
+ }
+ }
+ }
+ while (!fail && req_nbytes);
+
+ close (fd);
+ free (srvr_addr);
+ return fail? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/src/global.c b/comm/third_party/libgcrypt/src/global.c
new file mode 100644
index 0000000000..8940cea03b
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/global.c
@@ -0,0 +1,1368 @@
+/* global.c - global control functions
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2004, 2005, 2006, 2008, 2011,
+ * 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014, 2017 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+
+#include "g10lib.h"
+#include "gcrypt-testapi.h"
+#include "cipher.h"
+#include "stdmem.h" /* our own memory allocator */
+#include "secmem.h" /* our own secmem allocator */
+
+
+
+
+/****************
+ * flag bits: 0 : general cipher debug
+ * 1 : general MPI debug
+ */
+static unsigned int debug_flags;
+
+/* gcry_control (GCRYCTL_SET_FIPS_MODE), sets this flag so that the
+ initialization code switched fips mode on. */
+static int force_fips_mode;
+
+/* Controlled by global_init(). */
+int _gcry_global_any_init_done;
+
+/*
+ * Functions called before and after blocking syscalls.
+ * Initialized by global_init and used via
+ * _gcry_pre_syscall and _gcry_post_syscall.
+ */
+static void (*pre_syscall_func)(void);
+static void (*post_syscall_func)(void);
+
+
+/* Memory management. */
+
+static gcry_handler_alloc_t alloc_func;
+static gcry_handler_alloc_t alloc_secure_func;
+static gcry_handler_secure_check_t is_secure_func;
+static gcry_handler_realloc_t realloc_func;
+static gcry_handler_free_t free_func;
+static gcry_handler_no_mem_t outofcore_handler;
+static void *outofcore_handler_value;
+static int no_secure_memory;
+
+/* Prototypes. */
+static gpg_err_code_t external_lock_test (int cmd);
+
+
+
+
+/* This is our handmade constructor. It gets called by any function
+ likely to be called at startup. The suggested way for an
+ application to make sure that this has been called is by using
+ gcry_check_version. */
+static void
+global_init (void)
+{
+ gcry_error_t err = 0;
+
+ if (_gcry_global_any_init_done)
+ return;
+ _gcry_global_any_init_done = 1;
+
+ /* Tell the random module that we have seen an init call. */
+ _gcry_set_preferred_rng_type (0);
+
+ /* Get the system call clamp functions. */
+ if (!pre_syscall_func)
+ gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func);
+
+ /* See whether the system is in FIPS mode. This needs to come as
+ early as possible but after ATH has been initialized. */
+ _gcry_initialize_fips_mode (force_fips_mode);
+
+ /* Before we do any other initialization we need to test available
+ hardware features. */
+ _gcry_detect_hw_features ();
+
+ /* Initialize the modules - this is mainly allocating some memory and
+ creating mutexes. */
+ err = _gcry_cipher_init ();
+ if (err)
+ goto fail;
+ err = _gcry_md_init ();
+ if (err)
+ goto fail;
+ err = _gcry_mac_init ();
+ if (err)
+ goto fail;
+ err = _gcry_pk_init ();
+ if (err)
+ goto fail;
+ err = _gcry_primegen_init ();
+ if (err)
+ goto fail;
+ err = _gcry_secmem_module_init ();
+ if (err)
+ goto fail;
+ err = _gcry_mpi_init ();
+ if (err)
+ goto fail;
+
+ return;
+
+ fail:
+ BUG ();
+}
+
+
+/* This function is called by the macro fips_is_operational and makes
+ sure that the minimal initialization has been done. This is far
+ from a perfect solution and hides problems with an improper
+ initialization but at least in single-threaded mode it should work
+ reliable.
+
+ The reason we need this is that a lot of applications don't use
+ Libgcrypt properly by not running any initialization code at all.
+ They just call a Libgcrypt function and that is all what they want.
+ Now with the FIPS mode, that has the side effect of entering FIPS
+ mode (for security reasons, FIPS mode is the default if no
+ initialization has been done) and bailing out immediately because
+ the FSM is in the wrong state. If we always run the init code,
+ Libgcrypt can test for FIPS mode and at least if not in FIPS mode,
+ it will behave as before. Note that this on-the-fly initialization
+ is only done for the cryptographic functions subject to FIPS mode
+ and thus not all API calls will do such an initialization. */
+int
+_gcry_global_is_operational (void)
+{
+ if (!_gcry_global_any_init_done)
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+ "missing initialization - please fix the application");
+#endif /*HAVE_SYSLOG*/
+ global_init ();
+ }
+ return _gcry_fips_is_operational ();
+}
+
+
+
+
+/* Version number parsing. */
+
+/* This function parses the first portion of the version number S and
+ stores it in *NUMBER. On success, this function returns a pointer
+ into S starting with the first character, which is not part of the
+ initial number portion; on failure, NULL is returned. */
+static const char*
+parse_version_number( const char *s, int *number )
+{
+ int val = 0;
+
+ if( *s == '0' && isdigit(s[1]) )
+ return NULL; /* leading zeros are not allowed */
+ for ( ; isdigit(*s); s++ ) {
+ val *= 10;
+ val += *s - '0';
+ }
+ *number = val;
+ return val < 0? NULL : s;
+}
+
+/* This function breaks up the complete string-representation of the
+ version number S, which is of the following struture: <major
+ number>.<minor number>.<micro number><patch level>. The major,
+ minor and micro number components will be stored in *MAJOR, *MINOR
+ and *MICRO.
+
+ On success, the last component, the patch level, will be returned;
+ in failure, NULL will be returned. */
+
+static const char *
+parse_version_string( const char *s, int *major, int *minor, int *micro )
+{
+ s = parse_version_number( s, major );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, minor );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, micro );
+ if( !s )
+ return NULL;
+ return s; /* patchlevel */
+}
+
+/* If REQ_VERSION is non-NULL, check that the version of the library
+ is at minimum the requested one. Returns the string representation
+ of the library version if the condition is satisfied; return NULL
+ if the requested version is newer than that of the library.
+
+ If a NULL is passed to this function, no check is done, but the
+ string representation of the library is simply returned. */
+const char *
+_gcry_check_version (const char *req_version)
+{
+ const char *ver = VERSION;
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl;
+
+ if (req_version && req_version[0] == 1 && req_version[1] == 1)
+ return _gcry_compat_identification ();
+
+ /* Initialize library. */
+ global_init ();
+
+ if ( !req_version )
+ /* Caller wants our version number. */
+ return ver;
+
+ /* Parse own version number. */
+ my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
+ if ( !my_plvl )
+ /* very strange our own version is bogus. Shouldn't we use
+ assert() here and bail out in case this happens? -mo. */
+ return NULL;
+
+ /* Parse requested version number. */
+ if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro))
+ return NULL; /* req version string is invalid, this can happen. */
+
+ /* Compare version numbers. */
+ if ( my_major > rq_major
+ || (my_major == rq_major && my_minor > rq_minor)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro > rq_micro)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro == rq_micro))
+ {
+ return ver;
+ }
+
+ return NULL;
+}
+
+
+static void
+print_config (const char *what, gpgrt_stream_t fp)
+{
+ int i;
+ const char *s;
+
+ if (!what || !strcmp (what, "version"))
+ {
+ gpgrt_fprintf (fp, "version:%s:%x:%s:%x:\n",
+ VERSION, GCRYPT_VERSION_NUMBER,
+ GPGRT_VERSION, GPGRT_VERSION_NUMBER);
+ }
+ if (!what || !strcmp (what, "cc"))
+ {
+ gpgrt_fprintf (fp, "cc:%d:%s:\n",
+#if GPGRT_VERSION_NUMBER >= 0x011b00 /* 1.27 */
+ GPGRT_GCC_VERSION
+#else
+ _GPG_ERR_GCC_VERSION /* Due to a bug in gpg-error.h. */
+#endif
+ ,
+#ifdef __clang__
+ "clang:" __VERSION__
+#elif __GNUC__
+ "gcc:" __VERSION__
+#else
+ ":"
+#endif
+ );
+ }
+
+ if (!what || !strcmp (what, "ciphers"))
+ gpgrt_fprintf (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
+ if (!what || !strcmp (what, "pubkeys"))
+ gpgrt_fprintf (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
+ if (!what || !strcmp (what, "digests"))
+ gpgrt_fprintf (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
+
+ if (!what || !strcmp (what, "rnd-mod"))
+ {
+ gpgrt_fprintf (fp, "rnd-mod:"
+#if USE_RNDEGD
+ "egd:"
+#endif
+#if USE_RNDLINUX
+ "linux:"
+#endif
+#if USE_RNDUNIX
+ "unix:"
+#endif
+#if USE_RNDW32
+ "w32:"
+#endif
+ "\n");
+ }
+
+ if (!what || !strcmp (what, "cpu-arch"))
+ {
+ gpgrt_fprintf (fp, "cpu-arch:"
+#if defined(HAVE_CPU_ARCH_X86)
+ "x86"
+#elif defined(HAVE_CPU_ARCH_ALPHA)
+ "alpha"
+#elif defined(HAVE_CPU_ARCH_SPARC)
+ "sparc"
+#elif defined(HAVE_CPU_ARCH_MIPS)
+ "mips"
+#elif defined(HAVE_CPU_ARCH_M68K)
+ "m68k"
+#elif defined(HAVE_CPU_ARCH_PPC)
+ "ppc"
+#elif defined(HAVE_CPU_ARCH_ARM)
+ "arm"
+#endif
+ ":\n");
+ }
+
+ if (!what || !strcmp (what, "mpi-asm"))
+ gpgrt_fprintf (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
+
+ if (!what || !strcmp (what, "hwflist"))
+ {
+ unsigned int hwfeatures, afeature;
+
+ hwfeatures = _gcry_get_hw_features ();
+ gpgrt_fprintf (fp, "hwflist:");
+ for (i=0; (s = _gcry_enum_hw_features (i, &afeature)); i++)
+ if ((hwfeatures & afeature))
+ gpgrt_fprintf (fp, "%s:", s);
+ gpgrt_fprintf (fp, "\n");
+ }
+
+ if (!what || !strcmp (what, "fips-mode"))
+ {
+ /* We use y/n instead of 1/0 for the stupid reason that
+ * Emacsen's compile error parser would accidentally flag that
+ * line when printed during "make check" as an error. */
+ gpgrt_fprintf (fp, "fips-mode:%c:%c:\n",
+ fips_mode ()? 'y':'n',
+ _gcry_enforced_fips_mode ()? 'y':'n' );
+ }
+
+ if (!what || !strcmp (what, "rng-type"))
+ {
+ /* The currently used RNG type. */
+ unsigned int jver;
+ int active;
+
+ i = _gcry_get_rng_type (0);
+ switch (i)
+ {
+ case GCRY_RNG_TYPE_STANDARD: s = "standard"; break;
+ case GCRY_RNG_TYPE_FIPS: s = "fips"; break;
+ case GCRY_RNG_TYPE_SYSTEM: s = "system"; break;
+ default: BUG ();
+ }
+ jver = _gcry_rndjent_get_version (&active);
+ gpgrt_fprintf (fp, "rng-type:%s:%d:%u:%d:\n", s, i, jver, active);
+ }
+
+ if (!what || !strcmp (what, "compliance"))
+ {
+ /* Right now we have no certification for 1.9 so we return an
+ * empty string. As soon as this version has been approved for
+ * VS-Nfd we will put the string "de-vs" into the second
+ * field. If further specifications are required they are added
+ * as parameters to that field. Other certifications will go
+ * into field 3 and so on.
+ * field 1: keyword "compliance"
+ * field 2: German VS-Nfd is marked with "de-vs"
+ * field 3: reserved for FIPS.
+ */
+ gpgrt_fprintf (fp, "compliance:%s::\n", "");
+ }
+}
+
+
+/* With a MODE of 0 return a malloced string with configured features.
+ * In that case a WHAT of NULL returns everything in the same way
+ * GCRYCTL_PRINT_CONFIG would do. With a specific WHAT string only
+ * the requested feature is returned (w/o the trailing LF. On error
+ * NULL is returned. */
+char *
+_gcry_get_config (int mode, const char *what)
+{
+ gpgrt_stream_t fp;
+ int save_errno;
+ void *data;
+ char *p;
+
+ if (mode)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL;
+ }
+
+ fp = gpgrt_fopenmem (0, "w+b,samethread");
+ if (!fp)
+ return NULL;
+
+ print_config (what, fp);
+
+ if (!what)
+ {
+ /* Null-terminate bulk output. */
+ gpgrt_fwrite ("\0", 1, 1, fp);
+ }
+
+ if (gpgrt_ferror (fp))
+ {
+ save_errno = errno;
+ gpgrt_fclose (fp);
+ gpg_err_set_errno (save_errno);
+ return NULL;
+ }
+
+ gpgrt_rewind (fp);
+ if (gpgrt_fclose_snatch (fp, &data, NULL))
+ {
+ save_errno = errno;
+ gpgrt_fclose (fp);
+ gpg_err_set_errno (save_errno);
+ return NULL;
+ }
+
+ if (!data)
+ {
+ /* Nothing was printed (unknown value for WHAT). This is okay,
+ * so clear ERRNO to indicate this. */
+ gpg_err_set_errno (0);
+ return NULL;
+ }
+
+ /* Strip trailing LF. */
+ if (what && (p = strchr (data, '\n')))
+ *p = 0;
+
+ return data;
+}
+
+
+
+
+#if _GCRY_GCC_VERSION >= 40200
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wswitch"
+#endif
+
+/* Command dispatcher function, acting as general control
+ function. */
+gcry_err_code_t
+_gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
+{
+ static int init_finished = 0;
+ gcry_err_code_t rc = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_ENABLE_M_GUARD:
+ _gcry_private_enable_m_guard ();
+ break;
+
+ case GCRYCTL_ENABLE_QUICK_RANDOM:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_enable_quick_random_gen ();
+ break;
+
+ case GCRYCTL_FAKED_RANDOM_P:
+ /* Return an error if the RNG is faked one (e.g. enabled by
+ ENABLE_QUICK_RANDOM. */
+ if (_gcry_random_is_faked ())
+ rc = GPG_ERR_GENERAL; /* Use as TRUE value. */
+ break;
+
+ case GCRYCTL_DUMP_RANDOM_STATS:
+ _gcry_random_dump_stats ();
+ break;
+
+ case GCRYCTL_DUMP_MEMORY_STATS:
+ /*m_print_stats("[fixme: prefix]");*/
+ break;
+
+ case GCRYCTL_DUMP_SECMEM_STATS:
+ _gcry_secmem_dump_stats (0);
+ break;
+
+ case GCRYCTL_DROP_PRIVS:
+ global_init ();
+ _gcry_secmem_init (0);
+ break;
+
+ case GCRYCTL_DISABLE_SECMEM:
+ global_init ();
+ no_secure_memory = 1;
+ break;
+
+ case GCRYCTL_INIT_SECMEM:
+ global_init ();
+ _gcry_secmem_init (va_arg (arg_ptr, unsigned int));
+ if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED))
+ rc = GPG_ERR_GENERAL;
+ break;
+
+ case GCRYCTL_TERM_SECMEM:
+ global_init ();
+ _gcry_secmem_term ();
+ break;
+
+ case GCRYCTL_DISABLE_SECMEM_WARN:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_NO_WARNING));
+ break;
+
+ case GCRYCTL_SUSPEND_SECMEM_WARN:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_SUSPEND_WARNING));
+ break;
+
+ case GCRYCTL_RESUME_SECMEM_WARN:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
+ break;
+
+ case GCRYCTL_AUTO_EXPAND_SECMEM:
+ _gcry_secmem_set_auto_expand (va_arg (arg_ptr, unsigned int));
+ break;
+
+ case GCRYCTL_USE_SECURE_RNDPOOL:
+ global_init ();
+ _gcry_secure_random_alloc (); /* Put random number into secure memory. */
+ break;
+
+ case GCRYCTL_SET_RANDOM_SEED_FILE:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_set_random_seed_file (va_arg (arg_ptr, const char *));
+ break;
+
+ case GCRYCTL_UPDATE_RANDOM_SEED_FILE:
+ _gcry_set_preferred_rng_type (0);
+ if ( fips_is_operational () )
+ _gcry_update_random_seed_file ();
+ break;
+
+ case GCRYCTL_SET_VERBOSITY:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_set_log_verbosity (va_arg (arg_ptr, int));
+ break;
+
+ case GCRYCTL_SET_DEBUG_FLAGS:
+ debug_flags |= va_arg (arg_ptr, unsigned int);
+ break;
+
+ case GCRYCTL_CLEAR_DEBUG_FLAGS:
+ debug_flags &= ~va_arg (arg_ptr, unsigned int);
+ break;
+
+ case GCRYCTL_DISABLE_INTERNAL_LOCKING:
+ /* Not used anymore. */
+ global_init ();
+ break;
+
+ case GCRYCTL_ANY_INITIALIZATION_P:
+ if (_gcry_global_any_init_done)
+ rc = GPG_ERR_GENERAL;
+ break;
+
+ case GCRYCTL_INITIALIZATION_FINISHED_P:
+ if (init_finished)
+ rc = GPG_ERR_GENERAL; /* Yes. */
+ break;
+
+ case GCRYCTL_INITIALIZATION_FINISHED:
+ /* This is a hook which should be used by an application after
+ all initialization has been done and right before any threads
+ are started. It is not really needed but the only way to be
+ really sure that all initialization for thread-safety has
+ been done. */
+ if (! init_finished)
+ {
+ global_init ();
+ /* Do only a basic random initialization, i.e. init the
+ mutexes. */
+ _gcry_random_initialize (0);
+ init_finished = 1;
+ /* Force us into operational state if in FIPS mode. */
+ (void)fips_is_operational ();
+ }
+ break;
+
+ case GCRYCTL_SET_THREAD_CBS:
+ /* This is now a dummy call. We used to install our own thread
+ library here. */
+ _gcry_set_preferred_rng_type (0);
+ global_init ();
+ break;
+
+ case GCRYCTL_FAST_POLL:
+ _gcry_set_preferred_rng_type (0);
+ /* We need to do make sure that the random pool is really
+ initialized so that the poll function is not a NOP. */
+ _gcry_random_initialize (1);
+
+ if ( fips_is_operational () )
+ _gcry_fast_random_poll ();
+ break;
+
+ case GCRYCTL_SET_RNDEGD_SOCKET:
+#if USE_RNDEGD
+ _gcry_set_preferred_rng_type (0);
+ rc = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
+#else
+ rc = GPG_ERR_NOT_SUPPORTED;
+#endif
+ break;
+
+ case GCRYCTL_SET_RANDOM_DAEMON_SOCKET:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *));
+ break;
+
+ case GCRYCTL_USE_RANDOM_DAEMON:
+ /* We need to do make sure that the random pool is really
+ initialized so that the poll function is not a NOP. */
+ _gcry_set_preferred_rng_type (0);
+ _gcry_random_initialize (1);
+ _gcry_use_random_daemon (!! va_arg (arg_ptr, int));
+ break;
+
+ case GCRYCTL_CLOSE_RANDOM_DEVICE:
+ _gcry_random_close_fds ();
+ break;
+
+ /* This command dumps information pertaining to the
+ configuration of libgcrypt to the given stream. It may be
+ used before the initialization has been finished but not
+ before a gcry_version_check. See also gcry_get_config. */
+ case GCRYCTL_PRINT_CONFIG:
+ {
+ FILE *fp = va_arg (arg_ptr, FILE *);
+ char *tmpstr;
+ _gcry_set_preferred_rng_type (0);
+ tmpstr = _gcry_get_config (0, NULL);
+ if (tmpstr)
+ {
+ if (fp)
+ fputs (tmpstr, fp);
+ else
+ log_info ("%s", tmpstr);
+ xfree (tmpstr);
+ }
+ }
+ break;
+
+ case GCRYCTL_OPERATIONAL_P:
+ /* Returns true if the library is in an operational state. This
+ is always true for non-fips mode. */
+ _gcry_set_preferred_rng_type (0);
+ if (_gcry_fips_test_operational ())
+ rc = GPG_ERR_GENERAL; /* Used as TRUE value */
+ break;
+
+ case GCRYCTL_FIPS_MODE_P:
+ if (fips_mode ()
+ && !_gcry_is_fips_mode_inactive ()
+ && !no_secure_memory)
+ rc = GPG_ERR_GENERAL; /* Used as TRUE value */
+ break;
+
+ case GCRYCTL_FORCE_FIPS_MODE:
+ /* Performing this command puts the library into fips mode. If
+ the library has already been initialized into fips mode, a
+ selftest is triggered. It is not possible to put the libraty
+ into fips mode after having passed the initialization. */
+ _gcry_set_preferred_rng_type (0);
+ if (!_gcry_global_any_init_done)
+ {
+ /* Not yet initialized at all. Set a flag so that we are put
+ into fips mode during initialization. */
+ force_fips_mode = 1;
+ }
+ else
+ {
+ /* Already initialized. If we are already operational we
+ run a selftest. If not we use the is_operational call to
+ force us into operational state if possible. */
+ if (_gcry_fips_test_error_or_operational ())
+ _gcry_fips_run_selftests (1);
+ if (_gcry_fips_is_operational ())
+ rc = GPG_ERR_GENERAL; /* Used as TRUE value */
+ }
+ break;
+
+ case GCRYCTL_SELFTEST:
+ /* Run a selftest. This works in fips mode as well as in
+ standard mode. In contrast to the power-up tests, we use an
+ extended version of the selftests. Returns 0 on success or an
+ error code. */
+ global_init ();
+ rc = _gcry_fips_run_selftests (1);
+ break;
+
+ case PRIV_CTL_INIT_EXTRNG_TEST: /* Init external random test. */
+ rc = GPG_ERR_NOT_SUPPORTED;
+ break;
+ case PRIV_CTL_RUN_EXTRNG_TEST: /* Run external DRBG test. */
+ {
+ struct gcry_drbg_test_vector *test =
+ va_arg (arg_ptr, struct gcry_drbg_test_vector *);
+ unsigned char *buf = va_arg (arg_ptr, unsigned char *);
+
+ if (buf)
+ rc = _gcry_rngdrbg_cavs_test (test, buf);
+ else
+ rc = _gcry_rngdrbg_healthcheck_one (test);
+ }
+ break;
+ case PRIV_CTL_DEINIT_EXTRNG_TEST: /* Deinit external random test. */
+ rc = GPG_ERR_NOT_SUPPORTED;
+ break;
+ case PRIV_CTL_EXTERNAL_LOCK_TEST: /* Run external lock test */
+ rc = external_lock_test (va_arg (arg_ptr, int));
+ break;
+ case PRIV_CTL_DUMP_SECMEM_STATS:
+ _gcry_secmem_dump_stats (1);
+ break;
+
+ case GCRYCTL_DISABLE_HWF:
+ {
+ const char *name = va_arg (arg_ptr, const char *);
+ rc = _gcry_disable_hw_feature (name);
+ }
+ break;
+
+ case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
+ if (!_gcry_global_any_init_done)
+ {
+ /* Not yet initialized at all. Set the enforced fips mode flag */
+ _gcry_set_preferred_rng_type (0);
+ _gcry_set_enforced_fips_mode ();
+ }
+ else
+ rc = GPG_ERR_GENERAL;
+ break;
+
+ case GCRYCTL_SET_PREFERRED_RNG_TYPE:
+ /* This may be called before gcry_check_version. */
+ {
+ int i = va_arg (arg_ptr, int);
+ /* Note that we may not pass 0 to _gcry_set_preferred_rng_type. */
+ if (i > 0)
+ _gcry_set_preferred_rng_type (i);
+ }
+ break;
+
+ case GCRYCTL_GET_CURRENT_RNG_TYPE:
+ {
+ int *ip = va_arg (arg_ptr, int*);
+ if (ip)
+ *ip = _gcry_get_rng_type (!_gcry_global_any_init_done);
+ }
+ break;
+
+ case GCRYCTL_DISABLE_LOCKED_SECMEM:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_NO_MLOCK));
+ break;
+
+ case GCRYCTL_DISABLE_PRIV_DROP:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_NO_PRIV_DROP));
+ break;
+
+ case GCRYCTL_INACTIVATE_FIPS_FLAG:
+ case GCRYCTL_REACTIVATE_FIPS_FLAG:
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+ break;
+
+ case GCRYCTL_DRBG_REINIT:
+ {
+ const char *flagstr = va_arg (arg_ptr, const char *);
+ gcry_buffer_t *pers = va_arg (arg_ptr, gcry_buffer_t *);
+ int npers = va_arg (arg_ptr, int);
+ if (va_arg (arg_ptr, void *) || npers < 0)
+ rc = GPG_ERR_INV_ARG;
+ else if (_gcry_get_rng_type (!_gcry_global_any_init_done)
+ != GCRY_RNG_TYPE_FIPS)
+ rc = GPG_ERR_NOT_SUPPORTED;
+ else
+ rc = _gcry_rngdrbg_reinit (flagstr, pers, npers);
+ }
+ break;
+
+ case GCRYCTL_REINIT_SYSCALL_CLAMP:
+ if (!pre_syscall_func)
+ gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func);
+ break;
+
+ default:
+ _gcry_set_preferred_rng_type (0);
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return rc;
+}
+
+#if _GCRY_GCC_VERSION >= 40200
+# pragma GCC diagnostic pop
+#endif
+
+
+/* Set custom allocation handlers. This is in general not useful
+ * because the libgcrypt allocation functions are guaranteed to
+ * provide proper allocation handlers which zeroize memory if needed.
+ * NOTE: All 5 functions should be set. */
+void
+_gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
+ gcry_handler_alloc_t new_alloc_secure_func,
+ gcry_handler_secure_check_t new_is_secure_func,
+ gcry_handler_realloc_t new_realloc_func,
+ gcry_handler_free_t new_free_func)
+{
+ global_init ();
+
+ if (fips_mode ())
+ {
+ /* We do not want to enforce the fips mode, but merely set a
+ flag so that the application may check whether it is still in
+ fips mode. */
+ _gcry_inactivate_fips_mode ("custom allocation handler");
+ }
+
+ alloc_func = new_alloc_func;
+ alloc_secure_func = new_alloc_secure_func;
+ is_secure_func = new_is_secure_func;
+ realloc_func = new_realloc_func;
+ free_func = new_free_func;
+}
+
+
+
+/****************
+ * Set an optional handler which is called in case the xmalloc functions
+ * ran out of memory. This handler may do one of these things:
+ * o free some memory and return true, so that the xmalloc function
+ * tries again.
+ * o Do whatever it like and return false, so that the xmalloc functions
+ * use the default fatal error handler.
+ * o Terminate the program and don't return.
+ *
+ * The handler function is called with 3 arguments: The opaque value set with
+ * this function, the requested memory size, and a flag with these bits
+ * currently defined:
+ * bit 0 set = secure memory has been requested.
+ */
+void
+_gcry_set_outofcore_handler (int (*f)(void*, size_t, unsigned int), void *value)
+{
+ global_init ();
+
+ if (fips_mode () )
+ {
+ log_info ("out of core handler ignored in FIPS mode\n");
+ return;
+ }
+
+ outofcore_handler = f;
+ outofcore_handler_value = value;
+}
+
+/* Return the no_secure_memory flag. */
+static int
+get_no_secure_memory (void)
+{
+ if (!no_secure_memory)
+ return 0;
+ if (_gcry_enforced_fips_mode ())
+ {
+ no_secure_memory = 0;
+ return 0;
+ }
+ return no_secure_memory;
+}
+
+
+static gcry_err_code_t
+do_malloc (size_t n, unsigned int flags, void **mem)
+{
+ gcry_err_code_t err = 0;
+ void *m;
+
+ if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ())
+ {
+ if (alloc_secure_func)
+ m = (*alloc_secure_func) (n);
+ else
+ m = _gcry_private_malloc_secure (n, !!(flags & GCRY_ALLOC_FLAG_XHINT));
+ }
+ else
+ {
+ if (alloc_func)
+ m = (*alloc_func) (n);
+ else
+ m = _gcry_private_malloc (n);
+ }
+
+ if (!m)
+ {
+ /* Make sure that ERRNO has been set in case a user supplied
+ memory handler didn't it correctly. */
+ if (!errno)
+ gpg_err_set_errno (ENOMEM);
+ err = gpg_err_code_from_errno (errno);
+ }
+ else
+ *mem = m;
+
+ return err;
+}
+
+void *
+_gcry_malloc (size_t n)
+{
+ void *mem = NULL;
+
+ do_malloc (n, 0, &mem);
+
+ return mem;
+}
+
+static void *
+_gcry_malloc_secure_core (size_t n, int xhint)
+{
+ void *mem = NULL;
+
+ do_malloc (n, (GCRY_ALLOC_FLAG_SECURE | (xhint? GCRY_ALLOC_FLAG_XHINT:0)),
+ &mem);
+
+ return mem;
+}
+
+void *
+_gcry_malloc_secure (size_t n)
+{
+ return _gcry_malloc_secure_core (n, 0);
+}
+
+int
+_gcry_is_secure (const void *a)
+{
+ if (get_no_secure_memory ())
+ return 0;
+ if (is_secure_func)
+ return is_secure_func (a) ;
+ return _gcry_private_is_secure (a);
+}
+
+void
+_gcry_check_heap( const void *a )
+{
+ (void)a;
+
+ /* FIXME: implement this*/
+#if 0
+ if( some_handler )
+ some_handler(a)
+ else
+ _gcry_private_check_heap(a)
+#endif
+}
+
+static void *
+_gcry_realloc_core (void *a, size_t n, int xhint)
+{
+ void *p;
+
+ /* To avoid problems with non-standard realloc implementations and
+ our own secmem_realloc, we divert to malloc and free here. */
+ if (!a)
+ return _gcry_malloc (n);
+ if (!n)
+ {
+ xfree (a);
+ return NULL;
+ }
+
+ if (realloc_func)
+ p = realloc_func (a, n);
+ else
+ p = _gcry_private_realloc (a, n, xhint);
+ if (!p && !errno)
+ gpg_err_set_errno (ENOMEM);
+ return p;
+}
+
+
+void *
+_gcry_realloc (void *a, size_t n)
+{
+ return _gcry_realloc_core (a, n, 0);
+}
+
+
+void
+_gcry_free (void *p)
+{
+ int save_errno;
+
+ if (!p)
+ return;
+
+ /* In case ERRNO is set we better save it so that the free machinery
+ may not accidentally change ERRNO. We restore it only if it was
+ already set to comply with the usual C semantic for ERRNO. */
+ save_errno = errno;
+ if (free_func)
+ free_func (p);
+ else
+ _gcry_private_free (p);
+
+ if (save_errno)
+ gpg_err_set_errno (save_errno);
+}
+
+void *
+_gcry_calloc (size_t n, size_t m)
+{
+ size_t bytes;
+ void *p;
+
+ bytes = n * m; /* size_t is unsigned so the behavior on overflow is
+ defined. */
+ if (m && bytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+
+ p = _gcry_malloc (bytes);
+ if (p)
+ memset (p, 0, bytes);
+ return p;
+}
+
+void *
+_gcry_calloc_secure (size_t n, size_t m)
+{
+ size_t bytes;
+ void *p;
+
+ bytes = n * m; /* size_t is unsigned so the behavior on overflow is
+ defined. */
+ if (m && bytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+
+ p = _gcry_malloc_secure (bytes);
+ if (p)
+ memset (p, 0, bytes);
+ return p;
+}
+
+
+static char *
+_gcry_strdup_core (const char *string, int xhint)
+{
+ char *string_cp = NULL;
+ size_t string_n = 0;
+
+ string_n = strlen (string);
+
+ if (_gcry_is_secure (string))
+ string_cp = _gcry_malloc_secure_core (string_n + 1, xhint);
+ else
+ string_cp = _gcry_malloc (string_n + 1);
+
+ if (string_cp)
+ strcpy (string_cp, string);
+
+ return string_cp;
+}
+
+/* Create and return a copy of the null-terminated string STRING. If
+ * it is contained in secure memory, the copy will be contained in
+ * secure memory as well. In an out-of-memory condition, NULL is
+ * returned. */
+char *
+_gcry_strdup (const char *string)
+{
+ return _gcry_strdup_core (string, 0);
+}
+
+void *
+_gcry_xmalloc( size_t n )
+{
+ void *p;
+
+ while ( !(p = _gcry_malloc( n )) )
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, 0) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL);
+ }
+ }
+ return p;
+}
+
+void *
+_gcry_xrealloc( void *a, size_t n )
+{
+ void *p;
+
+ while (!(p = _gcry_realloc_core (a, n, 1)))
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n,
+ _gcry_is_secure(a)? 3:2))
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL );
+ }
+ }
+ return p;
+}
+
+void *
+_gcry_xmalloc_secure( size_t n )
+{
+ void *p;
+
+ while (!(p = _gcry_malloc_secure_core (n, 1)))
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, 1) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno),
+ _("out of core in secure memory"));
+ }
+ }
+ return p;
+}
+
+
+void *
+_gcry_xcalloc( size_t n, size_t m )
+{
+ size_t nbytes;
+ void *p;
+
+ nbytes = n * m;
+ if (m && nbytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
+ }
+
+ p = _gcry_xmalloc ( nbytes );
+ memset ( p, 0, nbytes );
+ return p;
+}
+
+void *
+_gcry_xcalloc_secure( size_t n, size_t m )
+{
+ size_t nbytes;
+ void *p;
+
+ nbytes = n * m;
+ if (m && nbytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
+ }
+
+ p = _gcry_xmalloc_secure ( nbytes );
+ memset ( p, 0, nbytes );
+ return p;
+}
+
+char *
+_gcry_xstrdup (const char *string)
+{
+ char *p;
+
+ while ( !(p = _gcry_strdup_core (string, 1)) )
+ {
+ size_t n = strlen (string);
+ int is_sec = !!_gcry_is_secure (string);
+
+ if (fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, is_sec) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno),
+ is_sec? _("out of core in secure memory"):NULL);
+ }
+ }
+
+ return p;
+}
+
+
+/* Used before blocking system calls. */
+void
+_gcry_pre_syscall (void)
+{
+ if (pre_syscall_func)
+ pre_syscall_func ();
+}
+
+
+/* Used after blocking system calls. */
+void
+_gcry_post_syscall (void)
+{
+ if (post_syscall_func)
+ post_syscall_func ();
+}
+
+
+int
+_gcry_get_debug_flag (unsigned int mask)
+{
+ if ( fips_mode () )
+ return 0;
+ return (debug_flags & mask);
+}
+
+
+
+/* It is often useful to get some feedback of long running operations.
+ This function may be used to register a handler for this.
+ The callback function CB is used as:
+
+ void cb (void *opaque, const char *what, int printchar,
+ int current, int total);
+
+ Where WHAT is a string identifying the the type of the progress
+ output, PRINTCHAR the character usually printed, CURRENT the amount
+ of progress currently done and TOTAL the expected amount of
+ progress. A value of 0 for TOTAL indicates that there is no
+ estimation available.
+
+ Defined values for WHAT:
+
+ "need_entropy" X 0 number-of-bytes-required
+ When running low on entropy
+ "primegen" '\n' 0 0
+ Prime generated
+ '!'
+ Need to refresh the prime pool
+ '<','>'
+ Number of bits adjusted
+ '^'
+ Looking for a generator
+ '.'
+ Fermat tests on 10 candidates failed
+ ':'
+ Restart with a new random value
+ '+'
+ Rabin Miller test passed
+ "pk_elg" '+','-','.','\n' 0 0
+ Only used in debugging mode.
+ "pk_dsa"
+ Only used in debugging mode.
+*/
+void
+_gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
+ void *cb_data)
+{
+#if USE_DSA
+ _gcry_register_pk_dsa_progress (cb, cb_data);
+#endif
+#if USE_ELGAMAL
+ _gcry_register_pk_elg_progress (cb, cb_data);
+#endif
+ _gcry_register_primegen_progress (cb, cb_data);
+ _gcry_register_random_progress (cb, cb_data);
+}
+
+
+
+/* This is a helper for the regression test suite to test Libgcrypt's locks.
+ It works using a one test lock with CMD controlling what to do:
+
+ 30111 - Allocate and init lock
+ 30112 - Take lock
+ 30113 - Release lock
+ 30114 - Destroy lock.
+
+ This function is used by tests/t-lock.c - it is not part of the
+ public API!
+ */
+static gpg_err_code_t
+external_lock_test (int cmd)
+{
+ GPGRT_LOCK_DEFINE (testlock);
+ gpg_err_code_t rc = 0;
+
+ switch (cmd)
+ {
+ case 30111: /* Init Lock. */
+ rc = gpgrt_lock_init (&testlock);
+ break;
+
+ case 30112: /* Take Lock. */
+ rc = gpgrt_lock_lock (&testlock);
+ break;
+
+ case 30113: /* Release Lock. */
+ rc = gpgrt_lock_unlock (&testlock);
+ break;
+
+ case 30114: /* Destroy Lock. */
+ rc = gpgrt_lock_destroy (&testlock);
+ break;
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ break;
+ }
+
+ return rc;
+}
diff --git a/comm/third_party/libgcrypt/src/hmac256.c b/comm/third_party/libgcrypt/src/hmac256.c
new file mode 100644
index 0000000000..78dcf8af05
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/hmac256.c
@@ -0,0 +1,800 @@
+/* hmac256.c - Standalone HMAC implementation
+ * Copyright (C) 2003, 2006, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This is a standalone HMAC-SHA-256 implementation based on the code
+ from ../cipher/sha256.c. It is a second implementation to allow
+ comparing against the standard implementations and to be used for
+ internal consistency checks. It should not be used for sensitive
+ data because no mechanisms to clear the stack etc are used.
+
+ This module may be used standalone.
+
+ Types:
+
+ u32 - unsigned 32 bit type.
+
+ Constants:
+
+ WORDS_BIGENDIAN Defined to 1 on big endian systems.
+ inline If defined, it should yield the keyword used
+ to inline a function.
+ HAVE_TYPE_U32 Defined if the u32 type is available.
+ SIZEOF_UNSIGNED_INT Defined to the size in bytes of an unsigned int.
+ SIZEOF_UNSIGNED_LONG Defined to the size in bytes of an unsigned long.
+
+ STANDALONE Compile a test driver similar to the
+ sha1sum tool. This driver uses a self-test
+ identically to the one used by Libcgrypt
+ for testing this included module.
+ */
+
+#ifdef STANDALONE
+#include <stdint.h>
+#define HAVE_TYPE_U32 1
+typedef uint32_t u32;
+#define VERSION "standalone"
+/* For GCC, we can detect endianness. If not GCC, please define manually. */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#endif
+#else
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#if defined(__WIN32) && defined(STANDALONE)
+# include <fcntl.h> /* We need setmode(). */
+#endif
+
+#ifdef STANDALONE
+#define xtrymalloc(a) malloc((a))
+#define gpg_err_set_errno(a) (errno = (a))
+#else
+#include "g10lib.h"
+#endif
+
+#include "hmac256.h"
+
+
+
+#ifndef HAVE_TYPE_U32
+# undef u32 /* Undef a possible macro with that name. */
+# if SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int u32;
+# elif SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned long u32;
+# else
+# error no typedef for u32
+# endif
+# define HAVE_TYPE_U32
+#endif
+
+
+
+
+/* The context used by this module. */
+struct hmac256_context
+{
+ u32 h0, h1, h2, h3, h4, h5, h6, h7;
+ u32 nblocks;
+ int count;
+ int finalized:1;
+ int use_hmac:1;
+ unsigned char buf[64];
+ unsigned char opad[64];
+};
+
+
+/* Rotate a 32 bit word. */
+static inline u32 ror(u32 x, int n)
+{
+ return ( ((x) >> (n)) | ((x) << (32-(n))) );
+}
+
+#define my_wipememory2(_ptr,_set,_len) do { \
+ volatile char *_vptr=(volatile char *)(_ptr); \
+ size_t _vlen=(_len); \
+ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+ } while(0)
+#define my_wipememory(_ptr,_len) my_wipememory2(_ptr,0,_len)
+
+
+
+
+/*
+ The SHA-256 core: Transform the message X which consists of 16
+ 32-bit-words. See FIPS 180-2 for details.
+ */
+static void
+transform (hmac256_context_t hd, const void *data_arg)
+{
+ const unsigned char *data = data_arg;
+
+#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
+#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
+#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
+#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
+ t2 = Sum0((a)) + Maj((a),(b),(c)); \
+ h = g; \
+ g = f; \
+ f = e; \
+ e = d + t1; \
+ d = c; \
+ c = b; \
+ b = a; \
+ a = t1 + t2; \
+ } while (0)
+
+ static const u32 K[64] =
+ {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ u32 a, b, c, d, e, f, g, h, t1, t2;
+ u32 x[16];
+ u32 w[64];
+ int i;
+
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+#ifdef WORDS_BIGENDIAN
+ memcpy (x, data, 64);
+#else /*!WORDS_BIGENDIAN*/
+ {
+ unsigned char *p2;
+
+ for (i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 )
+ {
+ p2[3] = *data++;
+ p2[2] = *data++;
+ p2[1] = *data++;
+ p2[0] = *data++;
+ }
+ }
+#endif /*!WORDS_BIGENDIAN*/
+
+ for (i=0; i < 16; i++)
+ w[i] = x[i];
+ for (; i < 64; i++)
+ w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
+
+ for (i=0; i < 64; i++)
+ R(a,b,c,d,e,f,g,h,K[i],w[i]);
+
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+}
+#undef Cho
+#undef Maj
+#undef Sum0
+#undef Sum1
+#undef S0
+#undef S1
+#undef R
+
+
+/* Finalize the current SHA256 calculation. */
+static void
+finalize (hmac256_context_t hd)
+{
+ u32 t, msb, lsb;
+ unsigned char *p;
+
+ if (hd->finalized)
+ return; /* Silently ignore a finalized context. */
+
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */
+
+ t = hd->nblocks;
+ /* Multiply by 64 to make a byte count. */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* Add the count. */
+ t = lsb;
+ if ((lsb += hd->count) < t)
+ msb++;
+ /* Multiply by 8 to make a bit count. */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->count < 56)
+ { /* Enough room. */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while (hd->count < 56)
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else
+ { /* Need one extra block. */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 64)
+ hd->buf[hd->count++] = 0;
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */;
+ memset (hd->buf, 0, 56 ); /* Zero out next next block. */
+ }
+ /* Append the 64 bit count. */
+ hd->buf[56] = msb >> 24;
+ hd->buf[57] = msb >> 16;
+ hd->buf[58] = msb >> 8;
+ hd->buf[59] = msb;
+ hd->buf[60] = lsb >> 24;
+ hd->buf[61] = lsb >> 16;
+ hd->buf[62] = lsb >> 8;
+ hd->buf[63] = lsb;
+ transform (hd, hd->buf);
+
+ /* Store the digest into hd->buf. */
+ p = hd->buf;
+#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
+ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+ X(5);
+ X(6);
+ X(7);
+#undef X
+ hd->finalized = 1;
+}
+
+
+
+/* Create a new context. On error NULL is returned and errno is set
+ appropriately. If KEY is given the function computes HMAC using
+ this key; with KEY given as NULL, a plain SHA-256 digest is
+ computed. */
+hmac256_context_t
+_gcry_hmac256_new (const void *key, size_t keylen)
+{
+ hmac256_context_t hd;
+
+ hd = xtrymalloc (sizeof *hd);
+ if (!hd)
+ return NULL;
+
+ hd->h0 = 0x6a09e667;
+ hd->h1 = 0xbb67ae85;
+ hd->h2 = 0x3c6ef372;
+ hd->h3 = 0xa54ff53a;
+ hd->h4 = 0x510e527f;
+ hd->h5 = 0x9b05688c;
+ hd->h6 = 0x1f83d9ab;
+ hd->h7 = 0x5be0cd19;
+ hd->nblocks = 0;
+ hd->count = 0;
+ hd->finalized = 0;
+ hd->use_hmac = 0;
+
+ if (key)
+ {
+ int i;
+ unsigned char ipad[64];
+
+ memset (ipad, 0, 64);
+ memset (hd->opad, 0, 64);
+ if (keylen <= 64)
+ {
+ memcpy (ipad, key, keylen);
+ memcpy (hd->opad, key, keylen);
+ }
+ else
+ {
+ hmac256_context_t tmphd;
+
+ tmphd = _gcry_hmac256_new (NULL, 0);
+ if (!tmphd)
+ {
+ free (hd);
+ return NULL;
+ }
+ _gcry_hmac256_update (tmphd, key, keylen);
+ finalize (tmphd);
+ memcpy (ipad, tmphd->buf, 32);
+ memcpy (hd->opad, tmphd->buf, 32);
+ _gcry_hmac256_release (tmphd);
+ }
+ for (i=0; i < 64; i++)
+ {
+ ipad[i] ^= 0x36;
+ hd->opad[i] ^= 0x5c;
+ }
+ hd->use_hmac = 1;
+ _gcry_hmac256_update (hd, ipad, 64);
+ my_wipememory (ipad, 64);
+ }
+
+ return hd;
+}
+
+/* Release a context created by _gcry_hmac256_new. CTX may be NULL
+ in which case the function does nothing. */
+void
+_gcry_hmac256_release (hmac256_context_t ctx)
+{
+ if (ctx)
+ {
+ /* Note: We need to take care not to modify errno. */
+ if (ctx->use_hmac)
+ my_wipememory (ctx->opad, 64);
+ free (ctx);
+ }
+}
+
+
+/* Update the message digest with the contents of BUFFER containing
+ LENGTH bytes. */
+void
+_gcry_hmac256_update (hmac256_context_t hd,
+ const void *buffer, size_t length)
+{
+ const unsigned char *inbuf = buffer;
+
+ if (hd->finalized)
+ return; /* Silently ignore a finalized context. */
+
+ if (hd->count == 64)
+ {
+ /* Flush the buffer. */
+ transform (hd, hd->buf);
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf)
+ return; /* Only flushing was requested. */
+ if (hd->count)
+ {
+ for (; length && hd->count < 64; length--)
+ hd->buf[hd->count++] = *inbuf++;
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */
+ if (!length)
+ return;
+ }
+
+
+ while (length >= 64)
+ {
+ transform (hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ length -= 64;
+ inbuf += 64;
+ }
+ for (; length && hd->count < 64; length--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/* Finalize an operation and return the digest. If R_DLEN is not NULL
+ the length of the digest will be stored at that address. The
+ returned value is valid as long as the context exists. On error
+ NULL is returned. */
+const void *
+_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen)
+{
+ finalize (hd);
+ if (hd->use_hmac)
+ {
+ hmac256_context_t tmphd;
+
+ tmphd = _gcry_hmac256_new (NULL, 0);
+ if (!tmphd)
+ return NULL;
+
+ _gcry_hmac256_update (tmphd, hd->opad, 64);
+ _gcry_hmac256_update (tmphd, hd->buf, 32);
+ finalize (tmphd);
+ memcpy (hd->buf, tmphd->buf, 32);
+ _gcry_hmac256_release (tmphd);
+ }
+ if (r_dlen)
+ *r_dlen = 32;
+ return (void*)hd->buf;
+}
+
+
+/* Convenience function to compute the HMAC-SHA256 of one file. The
+ user needs to provide a buffer RESULT of at least 32 bytes, he
+ needs to put the size of the buffer into RESULTSIZE and the
+ FILENAME. KEY and KEYLEN are as described for _gcry_hmac256_new.
+ On success the function returns the valid length of the result
+ buffer (which will be 32) or -1 on error. On error ERRNO is set
+ appropriate. */
+int
+_gcry_hmac256_file (void *result, size_t resultsize, const char *filename,
+ const void *key, size_t keylen)
+{
+ FILE *fp;
+ hmac256_context_t hd;
+ size_t buffer_size, nread, digestlen;
+ char *buffer;
+ const unsigned char *digest;
+
+ fp = fopen (filename, "rb");
+ if (!fp)
+ return -1;
+
+ hd = _gcry_hmac256_new (key, keylen);
+ if (!hd)
+ {
+ fclose (fp);
+ return -1;
+ }
+
+ buffer_size = 32768;
+ buffer = xtrymalloc (buffer_size);
+ if (!buffer)
+ {
+ fclose (fp);
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ while ( (nread = fread (buffer, 1, buffer_size, fp)))
+ _gcry_hmac256_update (hd, buffer, nread);
+
+ free (buffer);
+
+ if (ferror (fp))
+ {
+ fclose (fp);
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ fclose (fp);
+
+ digest = _gcry_hmac256_finalize (hd, &digestlen);
+ if (!digest)
+ {
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ if (digestlen > resultsize)
+ {
+ _gcry_hmac256_release (hd);
+ gpg_err_set_errno (EINVAL);
+ return -1;
+ }
+ memcpy (result, digest, digestlen);
+ _gcry_hmac256_release (hd);
+
+ return digestlen;
+}
+
+
+
+#ifdef STANDALONE
+static int
+selftest (void)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const unsigned char expect[32];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+ 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+ 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+ 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
+ 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
+ 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
+ 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\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",
+ { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
+ 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
+ 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
+ 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\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",
+ { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
+ 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
+ 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
+ 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
+
+ { "data-54 key-131",
+ "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",
+ { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
+ 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
+ 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
+ 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
+
+ { "data-152 key-131",
+ "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",
+ { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
+ 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
+ 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
+ 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
+
+ { NULL }
+ };
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ hmac256_context_t hmachd;
+ const unsigned char *digest;
+ size_t dlen;
+
+ hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
+ if (!hmachd)
+ return -1;
+ _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
+ digest = _gcry_hmac256_finalize (hmachd, &dlen);
+ if (!digest)
+ {
+ _gcry_hmac256_release (hmachd);
+ return -1;
+ }
+ if (dlen != sizeof (tv[tvidx].expect)
+ || memcmp (digest, tv[tvidx].expect, sizeof (tv[tvidx].expect)))
+ {
+ _gcry_hmac256_release (hmachd);
+ return -1;
+ }
+ _gcry_hmac256_release (hmachd);
+ }
+
+ return 0; /* Succeeded. */
+}
+
+
+int
+main (int argc, char **argv)
+{
+ const char *pgm;
+ int last_argc = -1;
+ const char *key;
+ size_t keylen;
+ FILE *fp;
+ hmac256_context_t hd;
+ const unsigned char *digest;
+ char buffer[4096];
+ size_t n, dlen, idx;
+ int use_stdin = 0;
+ int use_binary = 0;
+ int use_stdkey = 0;
+
+ assert (sizeof (u32) == 4);
+#ifdef __WIN32
+ setmode (fileno (stdin), O_BINARY);
+#endif
+
+ if (argc)
+ {
+ pgm = strrchr (*argv, '/');
+ if (pgm)
+ pgm++;
+ else
+ pgm = *argv;
+ argc--; argv++;
+ }
+ else
+ pgm = "?";
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ {
+ fputs ("hmac256 (Libgcrypt) " VERSION "\n"
+ "Copyright (C) 2008 Free Software Foundation, Inc.\n"
+ "License LGPLv2.1+: GNU LGPL version 2.1 or later "
+ "<http://gnu.org/licenses/old-licenses/lgpl-2.1.html>\n"
+ "This is free software: you are free to change and "
+ "redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--binary"))
+ {
+ argc--; argv++;
+ use_binary = 1;
+ }
+ else if (!strcmp (*argv, "--stdkey"))
+ {
+ argc--; argv++;
+ use_stdkey = 1;
+ }
+ }
+
+ if (argc < 1)
+ {
+ fprintf (stderr, "usage: %s [--binary] [--stdkey] key [filename]\n", pgm);
+ exit (1);
+ }
+
+#ifdef __WIN32
+ if (use_binary)
+ setmode (fileno (stdout), O_BINARY);
+#endif
+
+ key = use_stdkey? "What am I, a doctor or a moonshuttle conductor?" : *argv;
+ argc--, argv++;
+ keylen = strlen (key);
+ use_stdin = !argc;
+
+ if (selftest ())
+ {
+ fprintf (stderr, "%s: fatal error: self-test failed\n", pgm);
+ exit (2);
+ }
+
+ for (; argc || use_stdin; argv++, argc--)
+ {
+ const char *fname = use_stdin? "-" : *argv;
+ fp = use_stdin? stdin : fopen (fname, "rb");
+ if (!fp)
+ {
+ fprintf (stderr, "%s: can't open `%s': %s\n",
+ pgm, fname, strerror (errno));
+ exit (1);
+ }
+ hd = _gcry_hmac256_new (key, keylen);
+ if (!hd)
+ {
+ fprintf (stderr, "%s: can't allocate context: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ while ( (n = fread (buffer, 1, sizeof buffer, fp)))
+ _gcry_hmac256_update (hd, buffer, n);
+ if (ferror (fp))
+ {
+ fprintf (stderr, "%s: error reading `%s': %s\n",
+ pgm, fname, strerror (errno));
+ exit (1);
+ }
+ if (!use_stdin)
+ fclose (fp);
+
+ digest = _gcry_hmac256_finalize (hd, &dlen);
+ if (!digest)
+ {
+ fprintf (stderr, "%s: error computing HMAC: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ if (use_binary)
+ {
+ if (fwrite (digest, dlen, 1, stdout) != 1)
+ {
+ fprintf (stderr, "%s: error writing output: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ if (use_stdin)
+ break;
+ }
+ else
+ {
+ for (idx=0; idx < dlen; idx++)
+ printf ("%02x", digest[idx]);
+ _gcry_hmac256_release (hd);
+ if (use_stdin)
+ {
+ putchar ('\n');
+ break;
+ }
+ printf (" %s\n", fname);
+ }
+ }
+
+ return 0;
+}
+#endif /*STANDALONE*/
+
+
+/*
+Local Variables:
+compile-command: "cc -Wall -g -I.. -DSTANDALONE -o hmac256 hmac256.c"
+End:
+*/
diff --git a/comm/third_party/libgcrypt/src/hmac256.h b/comm/third_party/libgcrypt/src/hmac256.h
new file mode 100644
index 0000000000..df28e72721
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/hmac256.h
@@ -0,0 +1,36 @@
+/* hmac256.h - Declarations for _gcry_hmac256
+ * Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HMAC256_H
+#define HMAC256_H
+
+
+struct hmac256_context;
+typedef struct hmac256_context *hmac256_context_t;
+
+hmac256_context_t _gcry_hmac256_new (const void *key, size_t keylen);
+void _gcry_hmac256_update (hmac256_context_t hd, const void *buf, size_t len);
+const void *_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen);
+void _gcry_hmac256_release (hmac256_context_t hd);
+
+int _gcry_hmac256_file (void *result, size_t resultsize, const char *filename,
+ const void *key, size_t keylen);
+
+
+#endif /*HMAC256_H*/
diff --git a/comm/third_party/libgcrypt/src/hwf-arm.c b/comm/third_party/libgcrypt/src/hwf-arm.c
new file mode 100644
index 0000000000..4118858345
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/hwf-arm.c
@@ -0,0 +1,393 @@
+/* hwf-arm.c - Detect hardware features - ARM part
+ * Copyright (C) 2013,2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#if defined(HAVE_SYS_AUXV_H) && (defined(HAVE_GETAUXVAL) || \
+ defined(HAVE_ELF_AUX_INFO))
+#include <sys/auxv.h>
+#endif
+
+#include "g10lib.h"
+#include "hwf-common.h"
+
+#if !defined (__arm__) && !defined (__aarch64__)
+# error Module build for wrong CPU.
+#endif
+
+
+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ELF_AUX_INFO) && \
+ !defined(HAVE_GETAUXVAL) && defined(AT_HWCAP)
+#define HAVE_GETAUXVAL
+static unsigned long getauxval(unsigned long type)
+{
+ unsigned long auxval = 0;
+ int err;
+
+ /* FreeBSD provides 'elf_aux_info' function that does the same as
+ * 'getauxval' on Linux. */
+
+ err = elf_aux_info (type, &auxval, sizeof(auxval));
+ if (err)
+ {
+ errno = err;
+ auxval = 0;
+ }
+
+ return auxval;
+}
+#endif
+
+
+#undef HAS_SYS_AT_HWCAP
+#if defined(__linux__) || \
+ (defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL))
+#define HAS_SYS_AT_HWCAP 1
+
+struct feature_map_s {
+ unsigned int hwcap_flag;
+ unsigned int hwcap2_flag;
+ const char *feature_match;
+ unsigned int hwf_flag;
+};
+
+#ifdef __arm__
+
+/* Note: These macros have same values on Linux and FreeBSD. */
+#ifndef AT_HWCAP
+# define AT_HWCAP 16
+#endif
+#ifndef AT_HWCAP2
+# define AT_HWCAP2 26
+#endif
+
+#ifndef HWCAP_NEON
+# define HWCAP_NEON 4096
+#endif
+
+#ifndef HWCAP2_AES
+# define HWCAP2_AES 1
+#endif
+#ifndef HWCAP2_PMULL
+# define HWCAP2_PMULL 2
+#endif
+#ifndef HWCAP2_SHA1
+# define HWCAP2_SHA1 4
+#endif
+#ifndef HWCAP2_SHA2
+# define HWCAP2_SHA2 8
+#endif
+
+static const struct feature_map_s arm_features[] =
+ {
+#ifdef ENABLE_NEON_SUPPORT
+ { HWCAP_NEON, 0, " neon", HWF_ARM_NEON },
+#endif
+#ifdef ENABLE_ARM_CRYPTO_SUPPORT
+ { 0, HWCAP2_AES, " aes", HWF_ARM_AES },
+ { 0, HWCAP2_SHA1," sha1", HWF_ARM_SHA1 },
+ { 0, HWCAP2_SHA2, " sha2", HWF_ARM_SHA2 },
+ { 0, HWCAP2_PMULL, " pmull", HWF_ARM_PMULL },
+#endif
+ };
+
+#elif defined(__aarch64__)
+
+/* Note: These macros have same values on Linux and FreeBSD. */
+#ifndef AT_HWCAP
+# define AT_HWCAP 16
+#endif
+#ifndef AT_HWCAP2
+# define AT_HWCAP2 -1
+#endif
+
+#ifndef HWCAP_ASIMD
+# define HWCAP_ASIMD 2
+#endif
+#ifndef HWCAP_AES
+# define HWCAP_AES 8
+#endif
+#ifndef HWCAP_PMULL
+# define HWCAP_PMULL 16
+#endif
+#ifndef HWCAP_SHA1
+# define HWCAP_SHA1 32
+#endif
+#ifndef HWCAP_SHA2
+# define HWCAP_SHA2 64
+#endif
+
+static const struct feature_map_s arm_features[] =
+ {
+#ifdef ENABLE_NEON_SUPPORT
+ { HWCAP_ASIMD, 0, " asimd", HWF_ARM_NEON },
+#endif
+#ifdef ENABLE_ARM_CRYPTO_SUPPORT
+ { HWCAP_AES, 0, " aes", HWF_ARM_AES },
+ { HWCAP_SHA1, 0, " sha1", HWF_ARM_SHA1 },
+ { HWCAP_SHA2, 0, " sha2", HWF_ARM_SHA2 },
+ { HWCAP_PMULL, 0, " pmull", HWF_ARM_PMULL },
+#endif
+ };
+
+#endif
+
+static int
+get_hwcap(unsigned int *hwcap, unsigned int *hwcap2)
+{
+ struct { unsigned long a_type; unsigned long a_val; } auxv;
+ FILE *f;
+ int err = -1;
+ static int hwcap_initialized = 0;
+ static unsigned int stored_hwcap = 0;
+ static unsigned int stored_hwcap2 = 0;
+
+ if (hwcap_initialized)
+ {
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return 0;
+ }
+
+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL)
+ errno = 0;
+ auxv.a_val = getauxval (AT_HWCAP);
+ if (errno == 0)
+ {
+ stored_hwcap |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+
+ if (AT_HWCAP2 >= 0)
+ {
+ errno = 0;
+ auxv.a_val = getauxval (AT_HWCAP2);
+ if (errno == 0)
+ {
+ stored_hwcap2 |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+ }
+
+ if (hwcap_initialized && (stored_hwcap || stored_hwcap2))
+ {
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return 0;
+ }
+#endif
+
+ f = fopen("/proc/self/auxv", "r");
+ if (!f)
+ {
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return -1;
+ }
+
+ while (fread(&auxv, sizeof(auxv), 1, f) > 0)
+ {
+ if (auxv.a_type == AT_HWCAP)
+ {
+ stored_hwcap |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+
+ if (auxv.a_type == AT_HWCAP2)
+ {
+ stored_hwcap2 |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+ }
+
+ if (hwcap_initialized)
+ err = 0;
+
+ fclose(f);
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return err;
+}
+
+static unsigned int
+detect_arm_at_hwcap(void)
+{
+ unsigned int hwcap;
+ unsigned int hwcap2;
+ unsigned int features = 0;
+ unsigned int i;
+
+ if (get_hwcap(&hwcap, &hwcap2) < 0)
+ return features;
+
+ for (i = 0; i < DIM(arm_features); i++)
+ {
+ if (hwcap & arm_features[i].hwcap_flag)
+ features |= arm_features[i].hwf_flag;
+
+ if (hwcap2 & arm_features[i].hwcap2_flag)
+ features |= arm_features[i].hwf_flag;
+ }
+
+ return features;
+}
+
+#endif
+
+#undef HAS_PROC_CPUINFO
+#ifdef __linux__
+#define HAS_PROC_CPUINFO 1
+
+static unsigned int
+detect_arm_proc_cpuinfo(unsigned int *broken_hwfs)
+{
+ char buf[1024]; /* large enough */
+ char *str_features, *str_feat;
+ int cpu_implementer, cpu_arch, cpu_variant, cpu_part, cpu_revision;
+ FILE *f;
+ int readlen, i;
+ size_t mlen;
+ static int cpuinfo_initialized = 0;
+ static unsigned int stored_cpuinfo_features;
+ static unsigned int stored_broken_hwfs;
+ struct {
+ const char *name;
+ int *value;
+ } cpu_entries[5] = {
+ { "CPU implementer", &cpu_implementer },
+ { "CPU architecture", &cpu_arch },
+ { "CPU variant", &cpu_variant },
+ { "CPU part", &cpu_part },
+ { "CPU revision", &cpu_revision },
+ };
+
+ if (cpuinfo_initialized)
+ {
+ *broken_hwfs |= stored_broken_hwfs;
+ return stored_cpuinfo_features;
+ }
+
+ f = fopen("/proc/cpuinfo", "r");
+ if (!f)
+ return 0;
+
+ memset (buf, 0, sizeof(buf));
+ readlen = fread (buf, 1, sizeof(buf), f);
+ fclose (f);
+ if (readlen <= 0 || readlen > sizeof(buf))
+ return 0;
+
+ buf[sizeof(buf) - 1] = '\0';
+
+ cpuinfo_initialized = 1;
+ stored_cpuinfo_features = 0;
+ stored_broken_hwfs = 0;
+
+ /* Find features line. */
+ str_features = strstr(buf, "Features");
+ if (!str_features)
+ return stored_cpuinfo_features;
+
+ /* Find CPU version information. */
+ for (i = 0; i < DIM(cpu_entries); i++)
+ {
+ char *str;
+
+ *cpu_entries[i].value = -1;
+
+ str = strstr(buf, cpu_entries[i].name);
+ if (!str)
+ continue;
+
+ str = strstr(str, ": ");
+ if (!str)
+ continue;
+
+ str += 2;
+ if (strcmp(cpu_entries[i].name, "CPU architecture") == 0
+ && strcmp(str, "AArch64") == 0)
+ *cpu_entries[i].value = 8;
+ else
+ *cpu_entries[i].value = strtoul(str, NULL, 0);
+ }
+
+ /* Lines to strings. */
+ for (i = 0; i < sizeof(buf); i++)
+ if (buf[i] == '\n')
+ buf[i] = '\0';
+
+ /* Check features. */
+ for (i = 0; i < DIM(arm_features); i++)
+ {
+ str_feat = strstr(str_features, arm_features[i].feature_match);
+ if (str_feat)
+ {
+ mlen = strlen(arm_features[i].feature_match);
+ if (str_feat[mlen] == ' ' || str_feat[mlen] == '\0')
+ {
+ stored_cpuinfo_features |= arm_features[i].hwf_flag;
+ }
+ }
+ }
+
+ /* Check for CPUs with broken NEON implementation. See
+ * https://code.google.com/p/chromium/issues/detail?id=341598
+ */
+ if (cpu_implementer == 0x51
+ && cpu_arch == 7
+ && cpu_variant == 1
+ && cpu_part == 0x4d
+ && cpu_revision == 0)
+ {
+ stored_broken_hwfs = HWF_ARM_NEON;
+ }
+
+ *broken_hwfs |= stored_broken_hwfs;
+ return stored_cpuinfo_features;
+}
+
+#endif /* __linux__ */
+
+unsigned int
+_gcry_hwf_detect_arm (void)
+{
+ unsigned int ret = 0;
+ unsigned int broken_hwfs = 0;
+
+#if defined (HAS_SYS_AT_HWCAP)
+ ret |= detect_arm_at_hwcap ();
+#endif
+
+#if defined (HAS_PROC_CPUINFO)
+ ret |= detect_arm_proc_cpuinfo (&broken_hwfs);
+#endif
+
+#if defined(__ARM_NEON) && defined(ENABLE_NEON_SUPPORT)
+ ret |= HWF_ARM_NEON;
+#endif
+
+ ret &= ~broken_hwfs;
+
+ return ret;
+}
diff --git a/comm/third_party/libgcrypt/src/hwf-common.h b/comm/third_party/libgcrypt/src/hwf-common.h
new file mode 100644
index 0000000000..b10f86be6b
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/hwf-common.h
@@ -0,0 +1,28 @@
+/* hwf-common.h - Declarations for hwf-CPU.c modules
+ * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HWF_COMMON_H
+#define HWF_COMMON_H
+
+unsigned int _gcry_hwf_detect_x86 (void);
+unsigned int _gcry_hwf_detect_arm (void);
+unsigned int _gcry_hwf_detect_ppc (void);
+unsigned int _gcry_hwf_detect_s390x (void);
+
+#endif /*HWF_COMMON_H*/
diff --git a/comm/third_party/libgcrypt/src/hwf-ppc.c b/comm/third_party/libgcrypt/src/hwf-ppc.c
new file mode 100644
index 0000000000..7477a71bdd
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/hwf-ppc.c
@@ -0,0 +1,243 @@
+/* hwf-ppc.c - Detect hardware features - PPC part
+ * Copyright (C) 2013,2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2019 Shawn Landden <shawn@git.icu>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#if defined(HAVE_SYS_AUXV_H) && (defined(HAVE_GETAUXVAL) || \
+ defined(HAVE_ELF_AUX_INFO))
+#include <sys/auxv.h>
+#endif
+
+#include "g10lib.h"
+#include "hwf-common.h"
+
+#if !defined (__powerpc__) && !defined (__powerpc64__)
+# error Module build for wrong CPU.
+#endif
+
+
+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ELF_AUX_INFO) && \
+ !defined(HAVE_GETAUXVAL) && defined(AT_HWCAP)
+#define HAVE_GETAUXVAL
+static unsigned long getauxval(unsigned long type)
+{
+ unsigned long auxval = 0;
+ int err;
+
+ /* FreeBSD provides 'elf_aux_info' function that does the same as
+ * 'getauxval' on Linux. */
+
+ err = elf_aux_info (type, &auxval, sizeof(auxval));
+ if (err)
+ {
+ errno = err;
+ auxval = 0;
+ }
+
+ return auxval;
+}
+#endif
+
+
+#undef HAS_SYS_AT_HWCAP
+#if defined(__linux__) || \
+ (defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL))
+#define HAS_SYS_AT_HWCAP 1
+
+struct feature_map_s
+ {
+ unsigned int hwcap_flag;
+ unsigned int hwcap2_flag;
+ unsigned int hwf_flag;
+ };
+
+#if defined(__powerpc__) || defined(__powerpc64__)
+
+/* Note: These macros have same values on Linux and FreeBSD. */
+#ifndef AT_HWCAP
+# define AT_HWCAP 16
+#endif
+#ifndef AT_HWCAP2
+# define AT_HWCAP2 26
+#endif
+
+#ifndef PPC_FEATURE2_ARCH_2_07
+# define PPC_FEATURE2_ARCH_2_07 0x80000000
+#endif
+#ifndef PPC_FEATURE2_VEC_CRYPTO
+# define PPC_FEATURE2_VEC_CRYPTO 0x02000000
+#endif
+#ifndef PPC_FEATURE2_ARCH_3_00
+# define PPC_FEATURE2_ARCH_3_00 0x00800000
+#endif
+
+static const struct feature_map_s ppc_features[] =
+ {
+ { 0, PPC_FEATURE2_ARCH_2_07, HWF_PPC_ARCH_2_07 },
+#ifdef ENABLE_PPC_CRYPTO_SUPPORT
+ { 0, PPC_FEATURE2_VEC_CRYPTO, HWF_PPC_VCRYPTO },
+#endif
+ { 0, PPC_FEATURE2_ARCH_3_00, HWF_PPC_ARCH_3_00 },
+ };
+#endif
+
+static int
+get_hwcap(unsigned int *hwcap, unsigned int *hwcap2)
+{
+ struct { unsigned long a_type; unsigned long a_val; } auxv;
+ FILE *f;
+ int err = -1;
+ static int hwcap_initialized = 0;
+ static unsigned int stored_hwcap = 0;
+ static unsigned int stored_hwcap2 = 0;
+
+ if (hwcap_initialized)
+ {
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return 0;
+ }
+
+#if 0 // TODO: configure.ac detection for __builtin_cpu_supports
+ // TODO: move to 'detect_ppc_builtin_cpu_supports'
+#if defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ >= 6
+ /* __builtin_cpu_supports returns 0 if glibc support doesn't exist, so
+ * we can only trust positive results. */
+#ifdef ENABLE_PPC_CRYPTO_SUPPORT
+ if (__builtin_cpu_supports("vcrypto")) /* TODO: Configure.ac */
+ {
+ stored_hwcap2 |= PPC_FEATURE2_VEC_CRYPTO;
+ hwcap_initialized = 1;
+ }
+#endif
+
+ if (__builtin_cpu_supports("arch_3_00")) /* TODO: Configure.ac */
+ {
+ stored_hwcap2 |= PPC_FEATURE2_ARCH_3_00;
+ hwcap_initialized = 1;
+ }
+#endif
+#endif
+
+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL)
+ errno = 0;
+ auxv.a_val = getauxval (AT_HWCAP);
+ if (errno == 0)
+ {
+ stored_hwcap |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+
+ if (AT_HWCAP2 >= 0)
+ {
+ errno = 0;
+ auxv.a_val = getauxval (AT_HWCAP2);
+ if (errno == 0)
+ {
+ stored_hwcap2 |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+ }
+
+ if (hwcap_initialized && (stored_hwcap || stored_hwcap2))
+ {
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return 0;
+ }
+#endif
+
+ f = fopen("/proc/self/auxv", "r");
+ if (!f)
+ {
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return -1;
+ }
+
+ while (fread(&auxv, sizeof(auxv), 1, f) > 0)
+ {
+ if (auxv.a_type == AT_HWCAP)
+ {
+ stored_hwcap |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+
+ if (auxv.a_type == AT_HWCAP2)
+ {
+ stored_hwcap2 |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+ }
+
+ if (hwcap_initialized)
+ err = 0;
+
+ fclose(f);
+
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return err;
+}
+
+static unsigned int
+detect_ppc_at_hwcap(void)
+{
+ unsigned int hwcap;
+ unsigned int hwcap2;
+ unsigned int features = 0;
+ unsigned int i;
+
+ if (get_hwcap(&hwcap, &hwcap2) < 0)
+ return features;
+
+ for (i = 0; i < DIM(ppc_features); i++)
+ {
+ if (hwcap & ppc_features[i].hwcap_flag)
+ features |= ppc_features[i].hwf_flag;
+
+ if (hwcap2 & ppc_features[i].hwcap2_flag)
+ features |= ppc_features[i].hwf_flag;
+ }
+
+ return features;
+}
+
+#endif
+
+unsigned int
+_gcry_hwf_detect_ppc (void)
+{
+ unsigned int ret = 0;
+ unsigned int broken_hwfs = 0;
+
+#if defined (HAS_SYS_AT_HWCAP)
+ ret |= detect_ppc_at_hwcap ();
+#endif
+
+ ret &= ~broken_hwfs;
+
+ return ret;
+}
diff --git a/comm/third_party/libgcrypt/src/hwf-s390x.c b/comm/third_party/libgcrypt/src/hwf-s390x.c
new file mode 100644
index 0000000000..25121b91ce
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/hwf-s390x.c
@@ -0,0 +1,230 @@
+/* hwf-s390x.c - Detect hardware features - s390x/zSeries part
+ * Copyright (C) 2020 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#if defined(HAVE_SYS_AUXV_H) && (defined(HAVE_GETAUXVAL) || \
+ defined(HAVE_ELF_AUX_INFO))
+#include <sys/auxv.h>
+#endif
+
+#include "g10lib.h"
+#include "hwf-common.h"
+
+#if !defined (__s390x__)
+# error Module build for wrong CPU.
+#endif
+
+#undef HAVE_STFLE
+#ifdef HAVE_GCC_INLINE_ASM_S390X
+# define HAVE_STFLE 1
+#endif
+
+#ifndef AT_HWCAP
+# define AT_HWCAP 16
+#endif
+#ifndef HWCAP_S390_STFLE
+# define HWCAP_S390_STFLE 4
+#endif
+#ifndef HWCAP_S390_VXRS
+# define HWCAP_S390_VXRS 2048
+#endif
+
+struct feature_map_s
+ {
+ unsigned int facilities_bit;
+ unsigned int hwcap_flag;
+ unsigned int hwf_flag;
+ };
+
+static const struct feature_map_s s390x_features[] =
+ {
+ { 17, 0, HWF_S390X_MSA },
+ { 77, 0, HWF_S390X_MSA_4 },
+ { 146, 0, HWF_S390X_MSA_8 },
+#ifdef HAVE_GCC_INLINE_ASM_S390X_VX
+ { 129, HWCAP_S390_VXRS, HWF_S390X_VX },
+#endif
+ };
+
+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ELF_AUX_INFO) && \
+ !defined(HAVE_GETAUXVAL) && defined(AT_HWCAP)
+#define HAVE_GETAUXVAL
+static unsigned long getauxval(unsigned long type)
+{
+ unsigned long auxval = 0;
+ int err;
+
+ /* FreeBSD provides 'elf_aux_info' function that does the same as
+ * 'getauxval' on Linux. */
+
+ err = elf_aux_info (type, &auxval, sizeof(auxval));
+ if (err)
+ {
+ errno = err;
+ auxval = 0;
+ }
+
+ return auxval;
+}
+#endif
+
+
+#undef HAS_SYS_AT_HWCAP
+#if defined(__linux__) || \
+ (defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL))
+#define HAS_SYS_AT_HWCAP 1
+
+struct facilities_s
+ {
+ u64 bits[3];
+ };
+
+static int
+get_hwcap(unsigned int *hwcap)
+{
+ struct { unsigned long a_type; unsigned long a_val; } auxv;
+ FILE *f;
+ int err = -1;
+ static int hwcap_initialized = 0;
+ static unsigned int stored_hwcap = 0;
+
+ if (hwcap_initialized)
+ {
+ *hwcap = stored_hwcap;
+ return 0;
+ }
+
+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL)
+ errno = 0;
+ auxv.a_val = getauxval (AT_HWCAP);
+ if (errno == 0)
+ {
+ stored_hwcap |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+
+ if (hwcap_initialized && stored_hwcap)
+ {
+ *hwcap = stored_hwcap;
+ return 0;
+ }
+#endif
+
+ f = fopen("/proc/self/auxv", "r");
+ if (!f)
+ {
+ *hwcap = stored_hwcap;
+ return -1;
+ }
+
+ while (fread(&auxv, sizeof(auxv), 1, f) > 0)
+ {
+ if (auxv.a_type == AT_HWCAP)
+ {
+ stored_hwcap |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+ }
+
+ if (hwcap_initialized)
+ err = 0;
+
+ fclose(f);
+
+ *hwcap = stored_hwcap;
+ return err;
+}
+#endif
+
+#ifdef HAVE_STFLE
+static void
+get_stfle(struct facilities_s *out)
+{
+ static int stfle_initialized = 0;
+ static struct facilities_s stored_facilities;
+
+ if (!stfle_initialized)
+ {
+ register unsigned long reg0 asm("0") = DIM(stored_facilities.bits) - 1;
+
+ asm ("stfle %1\n\t"
+ : "+d" (reg0),
+ "=Q" (stored_facilities.bits[0])
+ :
+ : "cc", "memory");
+
+ stfle_initialized = 1;
+ }
+
+ *out = stored_facilities;
+}
+#endif
+
+static unsigned int
+detect_s390x_features(void)
+{
+ struct facilities_s facilities = { { 0, } };
+ unsigned int hwcap = 0;
+ unsigned int features = 0;
+ unsigned int i;
+
+#if defined (HAS_SYS_AT_HWCAP)
+ if (get_hwcap(&hwcap) < 0)
+ return features;
+#endif
+
+ if ((hwcap & HWCAP_S390_STFLE) == 0)
+ return features;
+
+#ifdef HAVE_STFLE
+ get_stfle(&facilities);
+#endif
+
+ for (i = 0; i < DIM(s390x_features); i++)
+ {
+ if (s390x_features[i].hwcap_flag == 0 ||
+ (s390x_features[i].hwcap_flag & hwcap))
+ {
+ unsigned int idx = s390x_features[i].facilities_bit;
+ unsigned int u64_idx = idx / 64;
+ unsigned int u64_bit = 63 - (idx % 64);
+
+ if (facilities.bits[u64_idx] & (U64_C(1) << u64_bit))
+ features |= s390x_features[i].hwf_flag;
+ }
+ }
+
+ return features;
+}
+
+unsigned int
+_gcry_hwf_detect_s390x (void)
+{
+ unsigned int ret = 0;
+
+ ret |= detect_s390x_features ();
+
+ return ret;
+}
diff --git a/comm/third_party/libgcrypt/src/hwf-x86.c b/comm/third_party/libgcrypt/src/hwf-x86.c
new file mode 100644
index 0000000000..9a9ed6d354
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/hwf-x86.c
@@ -0,0 +1,409 @@
+/* hwf-x86.c - Detect hardware features - x86 part
+ * Copyright (C) 2007, 2011, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "hwf-common.h"
+
+#if !defined (__i386__) && !defined (__x86_64__)
+# error Module build for wrong CPU.
+#endif
+
+/* We use the next macro to decide whether we can test for certain
+ features. */
+#undef HAS_X86_CPUID
+
+#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+# define HAS_X86_CPUID 1
+
+#if _GCRY_GCC_VERSION >= 40700 /* 4.7 */
+# define FORCE_FUNC_FRAME_POINTER \
+ __attribute__ ((optimize("no-omit-frame-pointer")))
+#else
+# define FORCE_FUNC_FRAME_POINTER
+#endif
+
+static FORCE_FUNC_FRAME_POINTER int
+is_cpuid_available(void)
+{
+ int has_cpuid = 0;
+
+ /* Detect the CPUID feature by testing some undefined behaviour (16
+ vs 32 bit pushf/popf). */
+ asm volatile
+ ("pushf\n\t" /* Copy flags to EAX. */
+ "popl %%eax\n\t"
+ "movl %%eax, %%ecx\n\t" /* Save flags into ECX. */
+ "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags. */
+ "pushl %%eax\n\t"
+ "popf\n\t"
+ "pushf\n\t" /* Copy changed flags again to EAX. */
+ "popl %%eax\n\t"
+ "pushl %%ecx\n\t" /* Restore flags from ECX. */
+ "popf\n\t"
+ "xorl %%eax, %%ecx\n\t" /* Compare flags against saved flags. */
+ "jz .Lno_cpuid%=\n\t" /* Toggling did not work, thus no CPUID. */
+ "movl $1, %0\n" /* Worked. true -> HAS_CPUID. */
+ ".Lno_cpuid%=:\n\t"
+ : "+r" (has_cpuid)
+ :
+ : "%eax", "%ecx", "cc", "memory"
+ );
+
+ return has_cpuid;
+}
+
+static void
+get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
+{
+ unsigned int regs[4];
+
+ asm volatile
+ ("movl %%ebx, %%edi\n\t" /* Save GOT register. */
+ "xorl %%ebx, %%ebx\n\t"
+ "cpuid\n\t"
+ "movl %%ebx, %1\n\t"
+ "movl %%edi, %%ebx\n\t" /* Restore GOT register. */
+ : "=a" (regs[0]), "=g" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
+ : "0" (in), "2" (0), "3" (0)
+ : "cc", "edi"
+ );
+
+ if (eax)
+ *eax = regs[0];
+ if (ebx)
+ *ebx = regs[1];
+ if (ecx)
+ *ecx = regs[2];
+ if (edx)
+ *edx = regs[3];
+}
+
+#if defined(ENABLE_AVX_SUPPORT) || defined(ENABLE_AVX2_SUPPORT)
+static unsigned int
+get_xgetbv(void)
+{
+ unsigned int t_eax, t_edx;
+
+ asm volatile
+ ("xgetbv\n\t"
+ : "=a" (t_eax), "=d" (t_edx)
+ : "c" (0)
+ );
+
+ return t_eax;
+}
+#endif /* ENABLE_AVX_SUPPORT || ENABLE_AVX2_SUPPORT */
+
+#endif /* i386 && GNUC */
+
+
+#if defined (__x86_64__) && defined (__GNUC__)
+# define HAS_X86_CPUID 1
+
+static int
+is_cpuid_available(void)
+{
+ return 1;
+}
+
+static void
+get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
+{
+ unsigned int regs[4];
+
+ asm volatile
+ ("cpuid\n\t"
+ : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
+ : "0" (in), "1" (0), "2" (0), "3" (0)
+ : "cc"
+ );
+
+ if (eax)
+ *eax = regs[0];
+ if (ebx)
+ *ebx = regs[1];
+ if (ecx)
+ *ecx = regs[2];
+ if (edx)
+ *edx = regs[3];
+}
+
+#if defined(ENABLE_AVX_SUPPORT) || defined(ENABLE_AVX2_SUPPORT)
+static unsigned int
+get_xgetbv(void)
+{
+ unsigned int t_eax, t_edx;
+
+ asm volatile
+ ("xgetbv\n\t"
+ : "=a" (t_eax), "=d" (t_edx)
+ : "c" (0)
+ );
+
+ return t_eax;
+}
+#endif /* ENABLE_AVX_SUPPORT || ENABLE_AVX2_SUPPORT */
+
+#endif /* x86-64 && GNUC */
+
+
+#ifdef HAS_X86_CPUID
+static unsigned int
+detect_x86_gnuc (void)
+{
+ union
+ {
+ char c[12+1];
+ unsigned int ui[3];
+ } vendor_id;
+ unsigned int features, features2;
+ unsigned int os_supports_avx_avx2_registers = 0;
+ unsigned int max_cpuid_level;
+ unsigned int fms, family, model;
+ unsigned int result = 0;
+ unsigned int avoid_vpgather = 0;
+
+ (void)os_supports_avx_avx2_registers;
+
+ if (!is_cpuid_available())
+ return 0;
+
+ get_cpuid(0, &max_cpuid_level, &vendor_id.ui[0], &vendor_id.ui[2],
+ &vendor_id.ui[1]);
+ vendor_id.c[12] = 0;
+
+ if (0)
+ ; /* Just to make "else if" and ifdef macros look pretty. */
+#ifdef ENABLE_PADLOCK_SUPPORT
+ else if (!strcmp (vendor_id.c, "CentaurHauls"))
+ {
+ /* This is a VIA CPU. Check what PadLock features we have. */
+
+ /* Check for extended centaur (EAX). */
+ get_cpuid(0xC0000000, &features, NULL, NULL, NULL);
+
+ /* Has extended centaur features? */
+ if (features > 0xC0000000)
+ {
+ /* Ask for the extended feature flags (EDX). */
+ get_cpuid(0xC0000001, NULL, NULL, NULL, &features);
+
+ /* Test bits 2 and 3 to see whether the RNG exists and is enabled. */
+ if ((features & 0x0C) == 0x0C)
+ result |= HWF_PADLOCK_RNG;
+
+ /* Test bits 6 and 7 to see whether the ACE exists and is enabled. */
+ if ((features & 0xC0) == 0xC0)
+ result |= HWF_PADLOCK_AES;
+
+ /* Test bits 10 and 11 to see whether the PHE exists and is
+ enabled. */
+ if ((features & 0xC00) == 0xC00)
+ result |= HWF_PADLOCK_SHA;
+
+ /* Test bits 12 and 13 to see whether the MONTMUL exists and is
+ enabled. */
+ if ((features & 0x3000) == 0x3000)
+ result |= HWF_PADLOCK_MMUL;
+ }
+ }
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+ else if (!strcmp (vendor_id.c, "GenuineIntel"))
+ {
+ /* This is an Intel CPU. */
+ result |= HWF_INTEL_CPU;
+ }
+ else if (!strcmp (vendor_id.c, "AuthenticAMD"))
+ {
+ /* This is an AMD CPU. */
+ }
+
+ /* Detect Intel features, that might also be supported by other
+ vendors. */
+
+ /* Get CPU family/model/stepping (EAX) and Intel feature flags (ECX, EDX). */
+ get_cpuid(1, &fms, NULL, &features, &features2);
+
+ family = ((fms & 0xf00) >> 8) + ((fms & 0xff00000) >> 20);
+ model = ((fms & 0xf0) >> 4) + ((fms & 0xf0000) >> 12);
+
+ if ((result & HWF_INTEL_CPU) && family == 6)
+ {
+ /* These Intel Core processor models have SHLD/SHRD instruction that
+ * can do integer rotation faster actual ROL/ROR instructions. */
+ switch (model)
+ {
+ case 0x2A:
+ case 0x2D:
+ case 0x3A:
+ case 0x3C:
+ case 0x3F:
+ case 0x45:
+ case 0x46:
+ case 0x3D:
+ case 0x4F:
+ case 0x56:
+ case 0x47:
+ case 0x4E:
+ case 0x5E:
+ case 0x8E:
+ case 0x9E:
+ case 0x55:
+ case 0x66:
+ result |= HWF_INTEL_FAST_SHLD;
+ break;
+ }
+
+ /* These Intel Core processors that have AVX2 have slow VPGATHER and
+ * should be avoided for table-lookup use. */
+ switch (model)
+ {
+ case 0x3C:
+ case 0x3F:
+ case 0x45:
+ case 0x46:
+ /* Haswell */
+ avoid_vpgather |= 1;
+ break;
+ }
+ }
+ else
+ {
+ /* Avoid VPGATHER for non-Intel CPUs as testing is needed to
+ * make sure it is fast enough. */
+
+ avoid_vpgather |= 1;
+ }
+
+#ifdef ENABLE_FORCE_SOFT_HWFEATURES
+ /* Soft HW features mark functionality that is available on all systems
+ * but not feasible to use because of slow HW implementation. */
+
+ /* SHLD is faster at rotating register than actual ROR/ROL instructions
+ * on older Intel systems (~sandy-bridge era). However, SHLD is very
+ * slow on almost anything else and later Intel processors have faster
+ * ROR/ROL. Therefore in regular build HWF_INTEL_FAST_SHLD is enabled
+ * only for those Intel processors that benefit from the SHLD
+ * instruction. Enabled here unconditionally as requested. */
+ result |= HWF_INTEL_FAST_SHLD;
+
+ /* VPGATHER instructions are used for look-up table based
+ * implementations which require VPGATHER to be fast enough to beat
+ * regular parallelized look-up table implementations (see Twofish).
+ * So far, only Intel processors beginning with skylake have had
+ * VPGATHER fast enough to be enabled. AMD Zen3 comes close to
+ * being feasible, but not quite (where twofish-avx2 is few percent
+ * slower than twofish-3way). Enable VPGATHER here unconditionally
+ * as requested. */
+ avoid_vpgather = 0;
+#endif
+
+#ifdef ENABLE_PCLMUL_SUPPORT
+ /* Test bit 1 for PCLMUL. */
+ if (features & 0x00000002)
+ result |= HWF_INTEL_PCLMUL;
+#endif
+ /* Test bit 9 for SSSE3. */
+ if (features & 0x00000200)
+ result |= HWF_INTEL_SSSE3;
+ /* Test bit 19 for SSE4.1. */
+ if (features & 0x00080000)
+ result |= HWF_INTEL_SSE4_1;
+#ifdef ENABLE_AESNI_SUPPORT
+ /* Test bit 25 for AES-NI. */
+ if (features & 0x02000000)
+ result |= HWF_INTEL_AESNI;
+#endif /*ENABLE_AESNI_SUPPORT*/
+#if defined(ENABLE_AVX_SUPPORT) || defined(ENABLE_AVX2_SUPPORT)
+ /* Test bit 27 for OSXSAVE (required for AVX/AVX2). */
+ if (features & 0x08000000)
+ {
+ /* Check that OS has enabled both XMM and YMM state support. */
+ if ((get_xgetbv() & 0x6) == 0x6)
+ os_supports_avx_avx2_registers = 1;
+ }
+#endif
+#ifdef ENABLE_AVX_SUPPORT
+ /* Test bit 28 for AVX. */
+ if (features & 0x10000000)
+ if (os_supports_avx_avx2_registers)
+ result |= HWF_INTEL_AVX;
+#endif /*ENABLE_AVX_SUPPORT*/
+#ifdef ENABLE_DRNG_SUPPORT
+ /* Test bit 30 for RDRAND. */
+ if (features & 0x40000000)
+ result |= HWF_INTEL_RDRAND;
+#endif /*ENABLE_DRNG_SUPPORT*/
+
+ /* Test bit 4 of EDX for TSC. */
+ if (features2 & 0x00000010)
+ result |= HWF_INTEL_RDTSC;
+
+ /* Check additional Intel feature flags. Early Intel P5 processors report
+ * too high max_cpuid_level, so don't check level 7 if processor does not
+ * support SSE3 (as cpuid:7 contains only features for newer processors).
+ * Source: http://www.sandpile.org/x86/cpuid.htm */
+ if (max_cpuid_level >= 7 && (features & 0x00000001))
+ {
+ /* Get CPUID:7 contains further Intel feature flags. */
+ get_cpuid(7, NULL, &features, NULL, NULL);
+
+ /* Test bit 8 for BMI2. */
+ if (features & 0x00000100)
+ result |= HWF_INTEL_BMI2;
+
+#ifdef ENABLE_AVX2_SUPPORT
+ /* Test bit 5 for AVX2. */
+ if (features & 0x00000020)
+ if (os_supports_avx_avx2_registers)
+ result |= HWF_INTEL_AVX2;
+
+ if ((result & HWF_INTEL_AVX2) && !avoid_vpgather)
+ result |= HWF_INTEL_FAST_VPGATHER;
+#endif /*ENABLE_AVX_SUPPORT*/
+
+ /* Test bit 29 for SHA Extensions. */
+ if (features & (1 << 29))
+ result |= HWF_INTEL_SHAEXT;
+ }
+
+ return result;
+}
+#endif /* HAS_X86_CPUID */
+
+
+unsigned int
+_gcry_hwf_detect_x86 (void)
+{
+#if defined (HAS_X86_CPUID)
+ return detect_x86_gnuc ();
+#else
+ return 0;
+#endif
+}
diff --git a/comm/third_party/libgcrypt/src/hwfeatures.c b/comm/third_party/libgcrypt/src/hwfeatures.c
new file mode 100644
index 0000000000..db58d2a378
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/hwfeatures.c
@@ -0,0 +1,237 @@
+/* hwfeatures.c - Detect hardware features.
+ * Copyright (C) 2007, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+
+#include "g10lib.h"
+#include "hwf-common.h"
+
+/* The name of a file used to globally disable selected features. */
+#define HWF_DENY_FILE "/etc/gcrypt/hwf.deny"
+
+/* A table to map hardware features to a string. */
+static struct
+{
+ unsigned int flag;
+ const char *desc;
+} hwflist[] =
+ {
+#if defined(HAVE_CPU_ARCH_X86)
+ { HWF_PADLOCK_RNG, "padlock-rng" },
+ { HWF_PADLOCK_AES, "padlock-aes" },
+ { HWF_PADLOCK_SHA, "padlock-sha" },
+ { HWF_PADLOCK_MMUL, "padlock-mmul"},
+ { HWF_INTEL_CPU, "intel-cpu" },
+ { HWF_INTEL_FAST_SHLD, "intel-fast-shld" },
+ { HWF_INTEL_BMI2, "intel-bmi2" },
+ { HWF_INTEL_SSSE3, "intel-ssse3" },
+ { HWF_INTEL_SSE4_1, "intel-sse4.1" },
+ { HWF_INTEL_PCLMUL, "intel-pclmul" },
+ { HWF_INTEL_AESNI, "intel-aesni" },
+ { HWF_INTEL_RDRAND, "intel-rdrand" },
+ { HWF_INTEL_AVX, "intel-avx" },
+ { HWF_INTEL_AVX2, "intel-avx2" },
+ { HWF_INTEL_FAST_VPGATHER, "intel-fast-vpgather" },
+ { HWF_INTEL_RDTSC, "intel-rdtsc" },
+ { HWF_INTEL_SHAEXT, "intel-shaext" },
+#elif defined(HAVE_CPU_ARCH_ARM)
+ { HWF_ARM_NEON, "arm-neon" },
+ { HWF_ARM_AES, "arm-aes" },
+ { HWF_ARM_SHA1, "arm-sha1" },
+ { HWF_ARM_SHA2, "arm-sha2" },
+ { HWF_ARM_PMULL, "arm-pmull" },
+#elif defined(HAVE_CPU_ARCH_PPC)
+ { HWF_PPC_VCRYPTO, "ppc-vcrypto" },
+ { HWF_PPC_ARCH_3_00, "ppc-arch_3_00" },
+ { HWF_PPC_ARCH_2_07, "ppc-arch_2_07" },
+#elif defined(HAVE_CPU_ARCH_S390X)
+ { HWF_S390X_MSA, "s390x-msa" },
+ { HWF_S390X_MSA_4, "s390x-msa-4" },
+ { HWF_S390X_MSA_8, "s390x-msa-8" },
+ { HWF_S390X_VX, "s390x-vx" },
+#endif
+ };
+
+/* A bit vector with the hardware features which shall not be used.
+ This variable must be set prior to any initialization. */
+static unsigned int disabled_hw_features;
+
+/* A bit vector describing the hardware features currently
+ available. */
+static unsigned int hw_features;
+
+
+
+/* Disable a feature by name. This function must be called *before*
+ _gcry_detect_hw_features is called. */
+gpg_err_code_t
+_gcry_disable_hw_feature (const char *name)
+{
+ int i;
+ size_t n1, n2;
+
+ while (name && *name)
+ {
+ n1 = strcspn (name, ":,");
+ if (!n1)
+ ;
+ else if (n1 == 3 && !strncmp (name, "all", 3))
+ disabled_hw_features = ~0;
+ else
+ {
+ for (i=0; i < DIM (hwflist); i++)
+ {
+ n2 = strlen (hwflist[i].desc);
+ if (n1 == n2 && !strncmp (hwflist[i].desc, name, n2))
+ {
+ disabled_hw_features |= hwflist[i].flag;
+ break;
+ }
+ }
+ if (!(i < DIM (hwflist)))
+ return GPG_ERR_INV_NAME;
+ }
+ name += n1;
+ if (*name)
+ name++; /* Skip delimiter ':' or ','. */
+ }
+ return 0;
+}
+
+
+/* Return a bit vector describing the available hardware features.
+ The HWF_ constants are used to test for them. */
+unsigned int
+_gcry_get_hw_features (void)
+{
+ return hw_features;
+}
+
+
+/* Enumerate all features. The caller is expected to start with an
+ IDX of 0 and then increment IDX until NULL is returned. */
+const char *
+_gcry_enum_hw_features (int idx, unsigned int *r_feature)
+{
+ if (idx < 0 || idx >= DIM (hwflist))
+ return NULL;
+ if (r_feature)
+ *r_feature = hwflist[idx].flag;
+ return hwflist[idx].desc;
+}
+
+
+/* Read a file with features which shall not be used. The file is a
+ simple text file where empty lines and lines with the first non
+ white-space character being '#' are ignored. */
+static void
+parse_hwf_deny_file (void)
+{
+ const char *fname = HWF_DENY_FILE;
+ FILE *fp;
+ char buffer[256];
+ char *p, *pend;
+ int lnr = 0;
+
+ fp = fopen (fname, "r");
+ if (!fp)
+ return;
+
+ for (;;)
+ {
+ if (!fgets (buffer, sizeof buffer, fp))
+ {
+ if (!feof (fp))
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt warning: error reading '%s', line %d",
+ fname, lnr);
+#endif /*HAVE_SYSLOG*/
+ }
+ fclose (fp);
+ return;
+ }
+ lnr++;
+ for (p=buffer; my_isascii (*p) && isspace (*p); p++)
+ ;
+ pend = strchr (p, '\n');
+ if (pend)
+ *pend = 0;
+ pend = p + (*p? (strlen (p)-1):0);
+ for ( ;pend > p; pend--)
+ if (my_isascii (*pend) && isspace (*pend))
+ *pend = 0;
+ if (!*p || *p == '#')
+ continue;
+
+ if (_gcry_disable_hw_feature (p) == GPG_ERR_INV_NAME)
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt warning: unknown feature in '%s', line %d",
+ fname, lnr);
+#endif /*HAVE_SYSLOG*/
+ }
+ }
+}
+
+
+/* Detect the available hardware features. This function is called
+ once right at startup and we assume that no other threads are
+ running. */
+void
+_gcry_detect_hw_features (void)
+{
+ hw_features = 0;
+
+ if (fips_mode ())
+ return; /* Hardware support is not to be evaluated. */
+
+ parse_hwf_deny_file ();
+
+#if defined (HAVE_CPU_ARCH_X86)
+ {
+ hw_features = _gcry_hwf_detect_x86 ();
+ }
+#elif defined (HAVE_CPU_ARCH_ARM)
+ {
+ hw_features = _gcry_hwf_detect_arm ();
+ }
+#elif defined (HAVE_CPU_ARCH_PPC)
+ {
+ hw_features = _gcry_hwf_detect_ppc ();
+ }
+#elif defined (HAVE_CPU_ARCH_S390X)
+ {
+ hw_features = _gcry_hwf_detect_s390x ();
+ }
+#endif
+ hw_features &= ~disabled_hw_features;
+}
diff --git a/comm/third_party/libgcrypt/src/libgcrypt-config.in b/comm/third_party/libgcrypt/src/libgcrypt-config.in
new file mode 100644
index 0000000000..6b3b356773
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/libgcrypt-config.in
@@ -0,0 +1,201 @@
+#!/bin/sh
+# Copyright (C) 1999, 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# File: @configure_input@
+
+# General.
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+version="@PACKAGE_VERSION@"
+includedir="@includedir@"
+libdir="@libdir@"
+gpg_error_libs="@GPG_ERROR_LIBS@"
+gpg_error_cflags="@GPG_ERROR_CFLAGS@"
+
+# libgcrypt values.
+libs="@LIBGCRYPT_CONFIG_LIBS@"
+cflags="@LIBGCRYPT_CONFIG_CFLAGS@"
+
+# API info
+api_version="@LIBGCRYPT_CONFIG_API_VERSION@"
+
+# Configured for host
+my_host="@LIBGCRYPT_CONFIG_HOST@"
+
+# Misc information.
+symmetric_ciphers="@LIBGCRYPT_CIPHERS@"
+asymmetric_ciphers="@LIBGCRYPT_PUBKEY_CIPHERS@"
+digests="@LIBGCRYPT_DIGESTS@"
+
+# State variables.
+echo_libs=no
+echo_cflags=no
+echo_prefix=no
+echo_algorithms=no
+echo_exec_prefix=no
+echo_version=no
+echo_api_version=no
+echo_host=no
+
+# Prints usage information.
+usage()
+{
+ cat <<EOF
+Usage: $0 [OPTIONS]
+Options:
+ [--prefix]
+ [--exec-prefix]
+ [--version]
+ [--api-version]
+ [--libs]
+ [--cflags]
+ [--algorithms]
+ [--host]
+EOF
+ exit $1
+}
+
+if test $# -eq 0; then
+ # Nothing to do.
+ usage 1 1>&2
+fi
+
+while test $# -gt 0; do
+ case "$1" in
+ # Set up `optarg'.
+ --*=*)
+ optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
+ ;;
+ *)
+ optarg=""
+ ;;
+ esac
+
+ case $1 in
+ --thread=*)
+ echo "$0: --thread option obsolete: use the thread callback interface" 1>&2
+ exit 1
+ ;;
+ --prefix=*)
+ # For compatibility reasons with old M4 macros, we ignore
+ # setting of prefix.
+ ;;
+ --prefix)
+ echo_prefix=yes
+ ;;
+ --exec-prefix=*)
+ ;;
+ --exec-prefix)
+ echo_exec_prefix=yes
+ ;;
+ --variable=*)
+ case "${1#*=}" in
+ prefix) echo "$prefix" ;;
+ exec_prefix) echo "$exec_prefix" ;;
+ host) echo "$my_host" ;;
+ api_version) echo "$api_version" ;;
+ symmetric_ciphers) echo "$symmetric_ciphers" ;;
+ asymmetric_ciphers) echo "$asymmetric_ciphers" ;;
+ digests) echo "$digests" ;;
+ esac
+ exit 0
+ ;;
+ --modversion|--version)
+ echo_version=yes
+ ;;
+ --api-version)
+ echo_api_version=yes
+ ;;
+ --cflags)
+ echo_cflags=yes
+ ;;
+ --libs)
+ echo_libs=yes
+ ;;
+ --algorithms)
+ echo_algorithms=yes
+ ;;
+ --host)
+ echo_host=yes
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+
+if test "$echo_prefix" = "yes"; then
+ echo "$prefix"
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+ echo "$exec_prefix"
+fi
+
+if test "$echo_cflags" = "yes"; then
+ includes=""
+ cflags_final="$cflags"
+
+ # Set up `includes'.
+ if test "x$includedir" != "x/usr/include" -a "x$includedir" != "x/include"; then
+ includes="-I$includedir"
+ fi
+ # Set up `cflags_final'.
+ cflags_final="$cflags_final $gpg_error_cflags"
+
+ tmp=""
+ for i in $includes $cflags_final; do
+ if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then
+ tmp="$tmp $i"
+ fi
+ done
+ echo $tmp
+fi
+
+if test "$echo_libs" = "yes"; then
+ libdirs=""
+ libs_final="$libs"
+
+ # Set up `libdirs'.
+ if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then
+ libdirs="-L$libdir"
+ fi
+
+ # Set up `libs_final'.
+ libs_final="$libs_final $gpg_error_libs"
+
+ tmp=""
+ for i in $libdirs $libs_final; do
+ if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then
+ tmp="$tmp $i"
+ fi
+ done
+ echo $tmp
+fi
+
+if test "$echo_version" = "yes"; then
+ echo "$version"
+fi
+
+if test "$echo_api_version" = "yes"; then
+ echo "$api_version"
+fi
+
+if test "$echo_host" = "yes"; then
+ echo "$my_host"
+fi
+
+if test "$echo_algorithms" = "yes"; then
+ echo "Symmetric cipher algorithms: $symmetric_ciphers"
+ echo "Public-key cipher algorithms: $asymmetric_ciphers"
+ echo "Message digest algorithms: $digests"
+fi
diff --git a/comm/third_party/libgcrypt/src/libgcrypt.def b/comm/third_party/libgcrypt/src/libgcrypt.def
new file mode 100644
index 0000000000..5fb207c91c
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/libgcrypt.def
@@ -0,0 +1,292 @@
+;; libgcrypt.defs - Exported symbols for W32
+;; Copyright (C) 2003, 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 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
+;;
+
+;; Note: This file should be updated manually and the ordinals shall
+;; never be changed. Also check libgcrypt.vers and visibility.h.
+
+
+EXPORTS
+ gcry_check_version @1
+ gcry_control @2
+
+ gcry_malloc @3
+ gcry_calloc @4
+ gcry_malloc_secure @5
+ gcry_calloc_secure @6
+ gcry_realloc @7
+ gcry_strdup @8
+ gcry_xmalloc @9
+ gcry_xcalloc @10
+ gcry_xmalloc_secure @11
+ gcry_xcalloc_secure @12
+ gcry_xrealloc @13
+ gcry_xstrdup @14
+ gcry_is_secure @15
+ gcry_free @16
+
+ gcry_set_progress_handler @17
+ gcry_set_allocation_handler @18
+ gcry_set_outofcore_handler @19
+ gcry_set_fatalerror_handler @20
+ gcry_set_log_handler @21
+ gcry_set_gettext_handler @22
+
+ gcry_strerror @23
+ gcry_strsource @24
+ gcry_err_code_from_errno @25
+ gcry_err_code_to_errno @26
+ gcry_err_make_from_errno @27
+ gcry_error_from_errno @28
+
+ gcry_sexp_new @29
+ gcry_sexp_create @30
+ gcry_sexp_sscan @31
+ gcry_sexp_build @32
+ gcry_sexp_build_array @33
+ gcry_sexp_release @34
+ gcry_sexp_canon_len @35
+ gcry_sexp_sprint @36
+ gcry_sexp_dump @37
+ gcry_sexp_cons @38
+ gcry_sexp_alist @39
+ gcry_sexp_vlist @40
+ gcry_sexp_append @41
+ gcry_sexp_prepend @42
+ gcry_sexp_find_token @43
+ gcry_sexp_length @44
+ gcry_sexp_nth @45
+ gcry_sexp_car @46
+ gcry_sexp_cdr @47
+ gcry_sexp_cadr @48
+ gcry_sexp_nth_data @49
+ gcry_sexp_nth_mpi @50
+
+ gcry_mpi_new @51
+ gcry_mpi_snew @52
+ gcry_mpi_release @53
+ gcry_mpi_copy @54
+ gcry_mpi_set @55
+ gcry_mpi_set_ui @56
+ gcry_mpi_swap @57
+ gcry_mpi_cmp @58
+ gcry_mpi_cmp_ui @59
+ gcry_mpi_scan @60
+ gcry_mpi_print @61
+ gcry_mpi_aprint @62
+ gcry_mpi_dump @63
+ gcry_mpi_add @64
+ gcry_mpi_add_ui @65
+ gcry_mpi_addm @66
+ gcry_mpi_sub @67
+ gcry_mpi_sub_ui @68
+ gcry_mpi_subm @69
+ gcry_mpi_mul @70
+ gcry_mpi_mul_ui @71
+ gcry_mpi_mulm @72
+ gcry_mpi_mul_2exp @73
+ gcry_mpi_div @74
+ gcry_mpi_mod @75
+ gcry_mpi_powm @76
+ gcry_mpi_gcd @77
+ gcry_mpi_invm @78
+ gcry_mpi_get_nbits @79
+ gcry_mpi_test_bit @80
+ gcry_mpi_set_bit @81
+ gcry_mpi_clear_bit @82
+ gcry_mpi_set_highbit @83
+ gcry_mpi_clear_highbit @84
+ gcry_mpi_rshift @85
+ gcry_mpi_set_opaque @86
+ gcry_mpi_get_opaque @87
+ gcry_mpi_set_flag @88
+ gcry_mpi_clear_flag @89
+ gcry_mpi_get_flag @90
+ gcry_mpi_get_ui @91
+
+ gcry_cipher_open @92
+ gcry_cipher_close @93
+ gcry_cipher_ctl @94
+ gcry_cipher_info @95
+ gcry_cipher_algo_info @96
+ gcry_cipher_algo_name @97
+ gcry_cipher_map_name @98
+ gcry_cipher_mode_from_oid @99
+ gcry_cipher_encrypt @100
+ gcry_cipher_decrypt @101
+ gcry_cipher_get_algo_keylen @102
+ gcry_cipher_get_algo_blklen @103
+
+;; @104 used to be part of the module register interface
+
+ gcry_pk_encrypt @105
+ gcry_pk_decrypt @106
+ gcry_pk_sign @107
+ gcry_pk_verify @108
+ gcry_pk_testkey @109
+ gcry_pk_genkey @110
+ gcry_pk_ctl @111
+ gcry_pk_algo_info @112
+ gcry_pk_algo_name @113
+ gcry_pk_map_name @114
+ gcry_pk_get_nbits @115
+ gcry_pk_get_keygrip @116
+
+;; @117 used to be part of the module register interface
+
+;;
+;; 118 to 142 were used in previous Libgcrypt versions for the gcry_ac
+;; interface
+;;
+
+ gcry_md_open @143
+ gcry_md_close @144
+ gcry_md_enable @145
+ gcry_md_copy @146
+ gcry_md_reset @147
+ gcry_md_ctl @148
+ gcry_md_write @149
+ gcry_md_read @150
+ gcry_md_hash_buffer @151
+ gcry_md_get_algo @152
+ gcry_md_get_algo_dlen @153
+ gcry_md_is_enabled @154
+ gcry_md_is_secure @155
+ gcry_md_info @156
+ gcry_md_algo_info @157
+ gcry_md_algo_name @158
+ gcry_md_map_name @159
+ gcry_md_setkey @160
+;; @161 used to be part of the module register interface
+ gcry_randomize @162
+ gcry_random_add_bytes @163
+ gcry_random_bytes @164
+ gcry_random_bytes_secure @165
+ gcry_mpi_randomize @166
+
+ gcry_prime_generate @167
+ gcry_prime_group_generator @168
+ gcry_prime_release_factors @169
+ gcry_prime_check @170
+
+ gcry_create_nonce @171
+
+ gcry_md_debug @172
+
+;; @173 used to be part of the module register interface
+;; @174 used to be part of the module register interface
+;; @175 used to be part of the module register interface
+;; @176 used to be part of the module register interface
+;; @177 used to be part of the module register interface
+;; @178 used to be part of the module register interface
+;;
+;; @179 to @186 used to be part of the removed gcry_ac interface
+;;
+
+ gcry_sexp_nth_string @187
+
+ gcry_cipher_setkey @188
+ gcry_cipher_setiv @189
+ gcry_cipher_setctr @190
+
+ gcry_mpi_lshift @191
+
+ gcry_pk_get_curve @192
+ gcry_pk_get_param @193
+
+ gcry_kdf_derive @194
+
+ gcry_mpi_snatch @195
+
+ gcry_mpi_point_new @196
+ gcry_mpi_point_release @197
+ gcry_mpi_point_get @198
+ gcry_mpi_point_snatch_get @199
+ gcry_mpi_point_set @200
+ gcry_mpi_point_snatch_set @201
+
+ gcry_ctx_release @202
+
+ gcry_mpi_ec_new @203
+ gcry_mpi_ec_get_mpi @204
+ gcry_mpi_ec_get_point @205
+ gcry_mpi_ec_set_mpi @206
+ gcry_mpi_ec_set_point @207
+ gcry_mpi_ec_get_affine @208
+ gcry_mpi_ec_dup @209
+ gcry_mpi_ec_add @210
+ gcry_mpi_ec_mul @211
+
+ gcry_pubkey_get_sexp @212
+
+ _gcry_mpi_get_const @213
+
+ gcry_sexp_nth_buffer @214
+
+ gcry_mpi_is_neg @215
+ gcry_mpi_neg @216
+ gcry_mpi_abs @217
+
+ gcry_mpi_ec_curve_point @218
+
+ gcry_md_hash_buffers @219
+
+ gcry_log_debug @220
+ gcry_log_debughex @221
+ gcry_log_debugmpi @222
+ gcry_log_debugpnt @223
+ gcry_log_debugsxp @224
+
+ gcry_sexp_extract_param @225
+
+ gcry_cipher_authenticate @226
+ gcry_cipher_gettag @227
+ gcry_cipher_checktag @228
+
+ gcry_mpi_set_opaque_copy @229
+
+ gcry_mac_algo_info @230
+ gcry_mac_algo_name @231
+ gcry_mac_map_name @232
+ gcry_mac_get_algo_maclen @233
+ gcry_mac_get_algo_keylen @234
+ gcry_mac_open @235
+ gcry_mac_close @236
+ gcry_mac_setkey @237
+ gcry_mac_setiv @238
+ gcry_mac_write @239
+ gcry_mac_read @240
+ gcry_mac_verify @241
+ gcry_mac_ctl @242
+ gcry_mac_get_algo @243
+
+ gcry_mpi_ec_sub @244
+
+ gcry_md_extract @245
+
+ gcry_mpi_ec_decode_point @246
+
+ gcry_get_config @247
+
+ gcry_mpi_point_copy @248
+
+ gcry_ecc_get_algo_keylen @249
+ gcry_ecc_mul_point @250
+
+;; end of file with public symbols for Windows.
diff --git a/comm/third_party/libgcrypt/src/libgcrypt.m4 b/comm/third_party/libgcrypt/src/libgcrypt.m4
new file mode 100644
index 0000000000..19d514fd53
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/libgcrypt.m4
@@ -0,0 +1,167 @@
+# libgcrypt.m4 - Autoconf macros to detect libgcrypt
+# Copyright (C) 2002, 2003, 2004, 2011, 2014, 2018, 2020 g10 Code GmbH
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Last-changed: 2020-09-27
+
+
+dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
+dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
+dnl MINIMUM-VERSION is a string with the version number optionally prefixed
+dnl with the API version to also check the API compatibility. Example:
+dnl a MINIMUM-VERSION of 1:1.2.5 won't pass the test unless the installed
+dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
+dnl this features allows to prevent build against newer versions of libgcrypt
+dnl with a changed API.
+dnl
+dnl If a prefix option is not used, the config script is first
+dnl searched in $SYSROOT/bin and then along $PATH. If the used
+dnl config script does not match the host specification the script
+dnl is added to the gpg_config_script_warn variable.
+dnl
+AC_DEFUN([AM_PATH_LIBGCRYPT],
+[ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_ARG_WITH(libgcrypt-prefix,
+ AS_HELP_STRING([--with-libgcrypt-prefix=PFX],
+ [prefix where LIBGCRYPT is installed (optional)]),
+ libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
+ if test x"${LIBGCRYPT_CONFIG}" = x ; then
+ if test x"${libgcrypt_config_prefix}" != x ; then
+ LIBGCRYPT_CONFIG="${libgcrypt_config_prefix}/bin/libgcrypt-config"
+ fi
+ fi
+
+ use_gpgrt_config=""
+ if test x"${LIBGCRYPT_CONFIG}" = x -a x"$GPGRT_CONFIG" != x -a "$GPGRT_CONFIG" != "no"; then
+ if $GPGRT_CONFIG libgcrypt --exists; then
+ LIBGCRYPT_CONFIG="$GPGRT_CONFIG libgcrypt"
+ AC_MSG_NOTICE([Use gpgrt-config as libgcrypt-config])
+ use_gpgrt_config=yes
+ fi
+ fi
+ if test -z "$use_gpgrt_config"; then
+ if test x"${LIBGCRYPT_CONFIG}" = x ; then
+ case "${SYSROOT}" in
+ /*)
+ if test -x "${SYSROOT}/bin/libgcrypt-config" ; then
+ LIBGCRYPT_CONFIG="${SYSROOT}/bin/libgcrypt-config"
+ fi
+ ;;
+ '')
+ ;;
+ *)
+ AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.])
+ ;;
+ esac
+ fi
+ AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
+ fi
+
+ tmp=ifelse([$1], ,1:1.2.0,$1)
+ if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+ req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
+ min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+ else
+ req_libgcrypt_api=0
+ min_libgcrypt_version="$tmp"
+ fi
+
+ AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
+ ok=no
+ if test "$LIBGCRYPT_CONFIG" != "no" ; then
+ req_major=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+ req_minor=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+ req_micro=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+ if test -z "$use_gpgrt_config"; then
+ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
+ else
+ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --modversion`
+ fi
+ major=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+ minor=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+ micro=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
+ if test "$major" -gt "$req_major"; then
+ ok=yes
+ else
+ if test "$major" -eq "$req_major"; then
+ if test "$minor" -gt "$req_minor"; then
+ ok=yes
+ else
+ if test "$minor" -eq "$req_minor"; then
+ if test "$micro" -ge "$req_micro"; then
+ ok=yes
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ AC_MSG_RESULT([yes ($libgcrypt_config_version)])
+ else
+ AC_MSG_RESULT(no)
+ fi
+ if test $ok = yes; then
+ # If we have a recent libgcrypt, we should also check that the
+ # API is compatible
+ if test "$req_libgcrypt_api" -gt 0 ; then
+ if test -z "$use_gpgrt_config"; then
+ tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
+ else
+ tmp=`$LIBGCRYPT_CONFIG --variable=api_version 2>/dev/null || echo 0`
+ fi
+ if test "$tmp" -gt 0 ; then
+ AC_MSG_CHECKING([LIBGCRYPT API version])
+ if test "$req_libgcrypt_api" -eq "$tmp" ; then
+ AC_MSG_RESULT([okay])
+ else
+ ok=no
+ AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
+ LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
+ ifelse([$2], , :, [$2])
+ if test -z "$use_gpgrt_config"; then
+ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+ else
+ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --variable=host 2>/dev/null || echo none`
+ fi
+ if test x"$libgcrypt_config_host" != xnone ; then
+ if test x"$libgcrypt_config_host" != x"$host" ; then
+ AC_MSG_WARN([[
+***
+*** The config script "$LIBGCRYPT_CONFIG" was
+*** built for $libgcrypt_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-libgcrypt-prefix
+*** to specify a matching config script or use \$SYSROOT.
+***]])
+ gpg_config_script_warn="$gpg_config_script_warn libgcrypt"
+ fi
+ fi
+ else
+ LIBGCRYPT_CFLAGS=""
+ LIBGCRYPT_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(LIBGCRYPT_CFLAGS)
+ AC_SUBST(LIBGCRYPT_LIBS)
+])
diff --git a/comm/third_party/libgcrypt/src/libgcrypt.pc.in b/comm/third_party/libgcrypt/src/libgcrypt.pc.in
new file mode 100644
index 0000000000..325f5c2b6b
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/libgcrypt.pc.in
@@ -0,0 +1,18 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+libdir=@libdir@
+host=@LIBGCRYPT_CONFIG_HOST@
+api_version=@LIBGCRYPT_CONFIG_API_VERSION@
+symmetric_ciphers="@LIBGCRYPT_CIPHERS@"
+asymmetric_ciphers="@LIBGCRYPT_PUBKEY_CIPHERS@"
+digests="@LIBGCRYPT_DIGESTS@"
+
+Name: libgcrypt
+Description: General purpose cryptographic library
+Requires.private: gpg-error
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir} @LIBGCRYPT_CONFIG_CFLAGS@
+Libs: -L${libdir} @LIBGCRYPT_CONFIG_LIBS@
+Libs.private: @DL_LIBS@
+URL: https://www.gnupg.org/software/libgcrypt/index.html
diff --git a/comm/third_party/libgcrypt/src/libgcrypt.vers b/comm/third_party/libgcrypt/src/libgcrypt.vers
new file mode 100644
index 0000000000..0ed10d517f
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/libgcrypt.vers
@@ -0,0 +1,128 @@
+# libgcrypt.vers - What symbols to export -*- std -*-
+# Copyright (C) 2002, 2004, 2008, 2011 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# NOTE: When adding new functions, please make sure to add them to
+# visibility.h and libgcrypt.def as well.
+
+GCRYPT_1.6 {
+ global:
+ gcry_check_version; gcry_control;
+ gcry_set_allocation_handler; gcry_set_fatalerror_handler;
+ gcry_set_gettext_handler; gcry_set_log_handler;
+ gcry_set_outofcore_handler; gcry_set_progress_handler;
+
+ gcry_err_code_from_errno; gcry_err_code_to_errno;
+ gcry_err_make_from_errno; gcry_error_from_errno;
+ gcry_strerror; gcry_strsource;
+
+ gcry_free; gcry_malloc; gcry_malloc_secure; gcry_calloc;
+ gcry_calloc_secure; gcry_realloc; gcry_strdup; gcry_is_secure;
+ gcry_xcalloc; gcry_xcalloc_secure; gcry_xmalloc;
+ gcry_xmalloc_secure; gcry_xrealloc; gcry_xstrdup;
+
+ gcry_md_algo_info; gcry_md_algo_name; gcry_md_close;
+ gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get;
+ gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer;
+ gcry_md_hash_buffers;
+ gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure;
+ gcry_md_map_name; gcry_md_open; gcry_md_read; gcry_md_extract;
+ gcry_md_reset; gcry_md_setkey;
+ gcry_md_write; gcry_md_debug;
+
+ gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close;
+ gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt;
+ gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen;
+ gcry_cipher_info; gcry_cipher_map_name;
+ gcry_cipher_mode_from_oid; gcry_cipher_open;
+ gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr;
+ gcry_cipher_authenticate; gcry_cipher_gettag; gcry_cipher_checktag;
+
+ gcry_mac_algo_info; gcry_mac_algo_name; gcry_mac_map_name;
+ gcry_mac_get_algo_maclen; gcry_mac_get_algo_keylen; gcry_mac_get_algo;
+ gcry_mac_open; gcry_mac_close; gcry_mac_setkey; gcry_mac_setiv;
+ gcry_mac_write; gcry_mac_read; gcry_mac_verify; gcry_mac_ctl;
+
+ gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl;
+ gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey;
+ gcry_pk_get_keygrip; gcry_pk_get_nbits;
+ gcry_pk_map_name; gcry_pk_register; gcry_pk_sign;
+ gcry_pk_testkey; gcry_pk_verify;
+ gcry_pk_get_curve; gcry_pk_get_param;
+
+ gcry_pubkey_get_sexp;
+
+ gcry_ecc_get_algo_keylen;
+ gcry_ecc_mul_point;
+
+ gcry_kdf_derive;
+
+ gcry_prime_check; gcry_prime_generate;
+ gcry_prime_group_generator; gcry_prime_release_factors;
+
+ gcry_random_add_bytes; gcry_random_bytes; gcry_random_bytes_secure;
+ gcry_randomize; gcry_create_nonce;
+
+ gcry_sexp_alist; gcry_sexp_append; gcry_sexp_build;
+ gcry_sexp_build_array; gcry_sexp_cadr; gcry_sexp_canon_len;
+ gcry_sexp_car; gcry_sexp_cdr; gcry_sexp_cons; gcry_sexp_create;
+ gcry_sexp_dump; gcry_sexp_find_token; gcry_sexp_length;
+ gcry_sexp_new; gcry_sexp_nth; gcry_sexp_nth_buffer; gcry_sexp_nth_data;
+ gcry_sexp_nth_mpi; gcry_sexp_prepend; gcry_sexp_release;
+ gcry_sexp_sprint; gcry_sexp_sscan; gcry_sexp_vlist;
+ gcry_sexp_nth_string; gcry_sexp_extract_param;
+
+ gcry_mpi_is_neg; gcry_mpi_neg; gcry_mpi_abs;
+ gcry_mpi_add; gcry_mpi_add_ui; gcry_mpi_addm; gcry_mpi_aprint;
+ gcry_mpi_clear_bit; gcry_mpi_clear_flag; gcry_mpi_clear_highbit;
+ gcry_mpi_cmp; gcry_mpi_cmp_ui; gcry_mpi_copy; gcry_mpi_div;
+ gcry_mpi_dump; gcry_mpi_gcd; gcry_mpi_get_flag; gcry_mpi_get_nbits;
+ gcry_mpi_get_opaque; gcry_mpi_invm; gcry_mpi_mod; gcry_mpi_mul;
+ gcry_mpi_mul_2exp; gcry_mpi_mul_ui; gcry_mpi_mulm; gcry_mpi_new;
+ gcry_mpi_powm; gcry_mpi_print; gcry_mpi_randomize; gcry_mpi_release;
+ gcry_mpi_rshift; gcry_mpi_scan; gcry_mpi_set; gcry_mpi_set_bit;
+ gcry_mpi_set_flag; gcry_mpi_set_highbit;
+ gcry_mpi_set_opaque; gcry_mpi_set_opaque_copy;
+ gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui;
+ gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit;
+ gcry_mpi_lshift; gcry_mpi_snatch;
+ gcry_mpi_point_new; gcry_mpi_point_release;
+ gcry_mpi_point_get; gcry_mpi_point_snatch_get;
+ gcry_mpi_point_set; gcry_mpi_point_snatch_set;
+ gcry_mpi_ec_new;
+ gcry_mpi_ec_get_mpi; gcry_mpi_ec_get_point;
+ gcry_mpi_ec_set_mpi; gcry_mpi_ec_set_point;
+ gcry_mpi_ec_get_affine;
+ gcry_mpi_ec_dup; gcry_mpi_ec_add; gcry_mpi_ec_sub; gcry_mpi_ec_mul;
+ gcry_mpi_ec_curve_point; gcry_mpi_ec_decode_point;
+ gcry_mpi_point_copy;
+ gcry_mpi_get_ui;
+
+ gcry_log_debug;
+ gcry_log_debughex; gcry_log_debugmpi; gcry_log_debugpnt; gcry_log_debugsxp;
+
+ gcry_get_config;
+
+ _gcry_mpi_get_const;
+
+ gcry_ctx_release;
+
+ local:
+ *;
+
+};
diff --git a/comm/third_party/libgcrypt/src/misc.c b/comm/third_party/libgcrypt/src/misc.c
new file mode 100644
index 0000000000..4db2d9a4dd
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/misc.c
@@ -0,0 +1,579 @@
+/* misc.c
+ * Copyright (C) 1999, 2001, 2002, 2003, 2007,
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "secmem.h"
+#include "mpi.h"
+
+static int verbosity_level = 0;
+
+#ifndef HAVE_EXPLICIT_MEMSET
+/* Prevent compiler from optimizing away the call to memset by accessing
+ memset through volatile pointer. */
+static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset;
+#endif
+
+static void (*fatal_error_handler)(void*,int, const char*) = NULL;
+static void *fatal_error_handler_value = 0;
+static void (*log_handler)(void*,int, const char*, va_list) = NULL;
+static void *log_handler_value = 0;
+
+static const char *(*user_gettext_handler)( const char * ) = NULL;
+
+void
+_gcry_set_gettext_handler (const char *(*f)(const char*))
+{
+ user_gettext_handler = f;
+}
+
+
+const char *
+_gcry_gettext( const char *key )
+{
+ if( user_gettext_handler )
+ return user_gettext_handler( key );
+ /* FIXME: switch the domain to gnupg and restore later */
+ return key;
+}
+
+void
+_gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value)
+{
+ fatal_error_handler_value = value;
+ fatal_error_handler = fnc;
+}
+
+static void
+write2stderr( const char *s )
+{
+ /* Dummy variable to silence gcc warning. */
+ int res = write( 2, s, strlen(s) );
+ (void) res;
+}
+
+/*
+ * This function is called for fatal errors. A caller might want to
+ * set his own handler because this function simply calls abort().
+ */
+void
+_gcry_fatal_error (int rc, const char *text)
+{
+ if ( !text ) /* get a default text */
+ text = gpg_strerror (rc);
+
+ if (fatal_error_handler && !fips_mode () )
+ fatal_error_handler (fatal_error_handler_value, rc, text);
+
+ fips_signal_fatal_error (text);
+ write2stderr("\nFatal error: ");
+ write2stderr(text);
+ write2stderr("\n");
+ _gcry_secmem_term ();
+ abort ();
+}
+
+void
+_gcry_set_log_handler (void (*f)(void*,int, const char*, va_list), void *opaque)
+{
+ log_handler = f;
+ log_handler_value = opaque;
+}
+
+void
+_gcry_set_log_verbosity( int level )
+{
+ verbosity_level = level;
+}
+
+int
+_gcry_log_verbosity( int level )
+{
+ return verbosity_level >= level;
+}
+
+/****************
+ * This is our log function which prints all log messages to stderr or
+ * using the function defined with gcry_set_log_handler().
+ */
+void
+_gcry_logv( int level, const char *fmt, va_list arg_ptr )
+{
+ if (log_handler)
+ log_handler (log_handler_value, level, fmt, arg_ptr);
+ else
+ {
+ switch (level)
+ {
+ case GCRY_LOG_CONT: break;
+ case GCRY_LOG_INFO: break;
+ case GCRY_LOG_WARN: break;
+ case GCRY_LOG_ERROR: break;
+ case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break;
+ case GCRY_LOG_BUG: fputs("Ohhhh jeeee: ", stderr); break;
+ case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break;
+ default: fprintf(stderr,"[Unknown log level %d]: ", level ); break;
+ }
+ vfprintf(stderr,fmt,arg_ptr) ;
+ }
+
+ if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG )
+ {
+ fips_signal_fatal_error ("internal error (fatal or bug)");
+ _gcry_secmem_term ();
+ abort ();
+ }
+}
+
+
+void
+_gcry_log( int level, const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( level, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
+void
+_gcry_bug( const char *file, int line, const char *func )
+{
+ _gcry_log( GCRY_LOG_BUG,
+ ("... this is a bug (%s:%d:%s)\n"), file, line, func );
+ abort(); /* never called, but it makes the compiler happy */
+}
+void
+_gcry_assert_failed (const char *expr, const char *file, int line,
+ const char *func)
+{
+ _gcry_log (GCRY_LOG_BUG,
+ ("Assertion `%s' failed (%s:%d:%s)\n"), expr, file, line, func );
+ abort(); /* Never called, but it makes the compiler happy. */
+}
+#else
+void
+_gcry_bug( const char *file, int line )
+{
+ _gcry_log( GCRY_LOG_BUG,
+ _("you found a bug ... (%s:%d)\n"), file, line);
+ abort(); /* never called, but it makes the compiler happy */
+}
+void
+_gcry_assert_failed (const char *expr, const char *file, int line)
+{
+ _gcry_log (GCRY_LOG_BUG,
+ ("Assertion `%s' failed (%s:%d)\n"), expr, file, line);
+ abort(); /* Never called, but it makes the compiler happy. */
+}
+#endif
+
+void
+_gcry_log_info( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+void
+_gcry_log_error( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+void
+_gcry_log_fatal( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr );
+ va_end(arg_ptr);
+ abort(); /* never called, but it makes the compiler happy */
+}
+
+void
+_gcry_log_bug( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr );
+ va_end(arg_ptr);
+ abort(); /* never called, but it makes the compiler happy */
+}
+
+void
+_gcry_log_debug( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+void
+_gcry_log_printf (const char *fmt, ...)
+{
+ va_list arg_ptr;
+
+ if (fmt)
+ {
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr);
+ va_end(arg_ptr);
+ }
+}
+
+
+/* Helper for _gcry_log_printhex and _gcry_log_printmpi. */
+static void
+do_printhex (const char *text, const char *text2,
+ const void *buffer, size_t length)
+{
+ int wrap = 0;
+ int cnt = 0;
+
+ if (text && *text)
+ {
+ wrap = 1;
+ log_debug ("%s:%s", text, text2);
+ if (text2[1] == '[' && length && buffer)
+ {
+ /* Start with a new line so that we get nice output for
+ opaque MPIS:
+ "value: [31 bit]"
+ " 01020300" */
+ log_printf ("\n");
+ text2 = " ";
+ log_debug ("%*s ", (int)strlen(text), "");
+ }
+ }
+ if (length && buffer)
+ {
+ const unsigned char *p = buffer;
+ for (; length--; p++)
+ {
+ log_printf ("%02x", *p);
+ if (wrap && ++cnt == 32 && length)
+ {
+ cnt = 0;
+ log_printf (" \\\n");
+ log_debug ("%*s %*s",
+ (int)strlen(text), "", (int)strlen(text2), "");
+ }
+ }
+ }
+ if (text)
+ log_printf ("\n");
+}
+
+
+/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw
+ dump without any wrappping, with TEXT an empty string, print a
+ trailing linefeed, otherwise print an entire debug line. */
+void
+_gcry_log_printhex (const char *text, const void *buffer, size_t length)
+{
+ do_printhex (text, " ", buffer, length);
+}
+
+
+/* Print MPI in hex notation. To make clear that the output is an MPI
+ a sign is always printed. With TEXT of NULL print just the raw dump
+ without any wrapping, with TEXT an empty string, print a trailing
+ linefeed, otherwise print an entire debug line. */
+void
+_gcry_log_printmpi (const char *text, gcry_mpi_t mpi)
+{
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+ int sign;
+
+ if (!mpi)
+ do_printhex (text? text:" ", " (null)", NULL, 0);
+ else if (mpi_is_opaque (mpi))
+ {
+ unsigned int nbits;
+ const unsigned char *p;
+ char prefix[30];
+
+ p = mpi_get_opaque (mpi, &nbits);
+ snprintf (prefix, sizeof prefix, " [%u bit]", nbits);
+ do_printhex (text? text:" ", prefix, p, (nbits+7)/8);
+ }
+ else
+ {
+ rawmpi = _gcry_mpi_get_buffer (mpi, 0, &rawmpilen, &sign);
+ if (!rawmpi)
+ do_printhex (text? text:" ", " [out of core]", NULL, 0);
+ else
+ {
+ if (!rawmpilen)
+ do_printhex (text, sign? "-":"+", "", 1);
+ else
+ do_printhex (text, sign? "-":"+", rawmpi, rawmpilen);
+ xfree (rawmpi);
+ }
+ }
+}
+
+
+static int
+count_closing_parens (const char *p)
+{
+ int count = 0;
+
+ for (; *p; p++)
+ if (*p == ')')
+ count++;
+ else if (!strchr ("\n \t", *p))
+ return 0;
+
+ return count;
+}
+
+
+/* Print SEXP in human readabale format. With TEXT of NULL print just the raw
+ dump without any wrappping, with TEXT an empty string, print a
+ trailing linefeed, otherwise print the full debug output. */
+void
+_gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
+{
+ int with_lf = 0;
+
+ if (text && *text)
+ {
+ if ((with_lf = !!strchr (text, '\n')))
+ log_debug ("%s", text);
+ else
+ log_debug ("%s: ", text);
+ }
+ if (sexp)
+ {
+ int any = 0;
+ int n_closing;
+ char *buf, *pend;
+ const char *p;
+ size_t size;
+
+ size = sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ p = buf = xmalloc (size);
+ sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, size);
+
+ do
+ {
+ if (any && !with_lf)
+ log_debug ("%*s ", text?(int)strlen(text):0, "");
+ else
+ any = 1;
+ pend = strchr (p, '\n');
+ size = pend? (pend - p) : strlen (p);
+ if (with_lf)
+ log_debug ("%.*s", (int)size, p);
+ else
+ log_printf ("%.*s", (int)size, p);
+ if (pend)
+ p = pend + 1;
+ else
+ p += size;
+ n_closing = count_closing_parens (p);
+ if (n_closing)
+ {
+ while (n_closing--)
+ log_printf (")");
+ p = "";
+ }
+ log_printf ("\n");
+ }
+ while (*p);
+ xfree (buf);
+ }
+ else if (text)
+ log_printf ("\n");
+}
+
+
+/*
+ * Tokenize STRING using the set of delimiters in DELIM. Leading
+ * white spaces are removed from all tokens. The caller must xfree
+ * the result.
+ *
+ * Returns: A malloced and NULL delimited array with the tokens. On
+ * memory error NULL is returned and ERRNO is set.
+ */
+char **
+_gcry_strtokenize (const char *string, const char *delim)
+{
+ const char *s;
+ size_t fields;
+ size_t bytes, n;
+ char *buffer;
+ char *p, *px, *pend;
+ char **result;
+ char const ws[] = " \t\v\f\r\n";
+
+ if (!delim)
+ delim = ws;
+
+ /* Count the number of fields. */
+ for (fields = 1, s = strpbrk (string, delim); s; s = strpbrk (s + 1, delim))
+ fields++;
+ fields++; /* Add one for the terminating NULL. */
+
+ /* Allocate an array for all fields, a terminating NULL, and space
+ for a copy of the string. */
+ bytes = fields * sizeof *result;
+ if (bytes / sizeof *result != fields)
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ n = strlen (string) + 1;
+ bytes += n;
+ if (bytes < n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ result = xtrymalloc (bytes);
+ if (!result)
+ return NULL;
+ buffer = (char*)(result + fields);
+
+ /* Copy and parse the string. */
+ strcpy (buffer, string);
+ for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
+ {
+ *pend = 0;
+ while (strchr (ws, *(byte*)p))
+ p++;
+ for (px = pend - 1; px >= p && strchr (ws, *(byte*)px); px--)
+ *px = 0;
+ result[n++] = p;
+ }
+ while (*p && strchr (ws, *(byte*)p))
+ p++;
+ for (px = p + strlen (p) - 1; px >= p && strchr (ws, *(byte*)px); px--)
+ *px = 0;
+ /* Traling spaces may result in an empty field. We do not want to
+ store that. */
+ result[n++] = *p? p : NULL;
+ result[n] = NULL;
+
+ gcry_assert ((char*)(result + n + 1) == buffer);
+
+ return result;
+}
+
+
+void
+_gcry_fast_wipememory (void *ptr, size_t len)
+{
+ /* Note: This function is called from wipememory/wipememory2 only if LEN
+ is large or unknown at compile time. New wipe function alternatives
+ need to be checked before adding to this function. New implementations
+ need to be faster than wipememory/wipememory2 macros in 'g10lib.h'.
+
+ Following implementations were found to have suboptimal performance:
+
+ - [_WIN32/mingw32] SecureZeroMemory; Inline function, equivalent to
+ volatile byte buffer set: while(buflen--) (volatile char *)(buf++)=set;
+ */
+#ifdef HAVE_EXPLICIT_BZERO
+ explicit_bzero (ptr, len);
+#elif defined(HAVE_EXPLICIT_MEMSET)
+ explicit_memset (ptr, 0, len);
+#else
+ memset_ptr (ptr, 0, len);
+#endif
+}
+
+
+void
+_gcry_fast_wipememory2 (void *ptr, int set, size_t len)
+{
+#ifdef HAVE_EXPLICIT_MEMSET
+ explicit_memset (ptr, set, len);
+#else
+#ifdef HAVE_EXPLICIT_BZERO
+ if (set == 0)
+ {
+ explicit_bzero (ptr, len);
+ return;
+ }
+#endif
+
+ memset_ptr (ptr, set, len);
+#endif
+}
+
+
+void NOINLINE_FUNC
+__gcry_burn_stack (unsigned int bytes)
+{
+#ifdef HAVE_VLA
+ /* (bytes == 0 ? 1 : bytes) == (!bytes + bytes) */
+ unsigned int buflen = ((!bytes + bytes) + 63) & ~63;
+ char buf[buflen];
+
+ _gcry_fast_wipememory (buf, buflen);
+#else
+ volatile char buf[64];
+
+ _gcry_fast_wipememory (buf, sizeof buf);
+
+ if (bytes > sizeof buf)
+ _gcry_burn_stack (bytes - sizeof buf);
+#endif
+}
+
+#ifndef HAVE_GCC_ASM_VOLATILE_MEMORY
+void
+__gcry_burn_stack_dummy (void)
+{
+}
+#endif
+
+void
+_gcry_divide_by_zero (void)
+{
+ gpg_err_set_errno (EDOM);
+ _gcry_fatal_error (gpg_err_code_from_errno (errno), "divide by zero");
+}
diff --git a/comm/third_party/libgcrypt/src/missing-string.c b/comm/third_party/libgcrypt/src/missing-string.c
new file mode 100644
index 0000000000..4756c00ea7
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/missing-string.c
@@ -0,0 +1,54 @@
+/* missing-string.c - missing string utilities
+ * Copyright (C) 1994, 1998, 1999, 2000, 2001,
+ * 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
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "g10lib.h"
+
+
+#ifndef HAVE_STPCPY
+char *
+stpcpy(char *a,const char *b)
+{
+ while( *b )
+ *a++ = *b++;
+ *a = 0;
+
+ return (char*)a;
+}
+#endif
+
+
+#ifndef HAVE_STRCASECMP
+int
+strcasecmp( const char *a, const char *b )
+{
+ for( ; *a && *b; a++, b++ ) {
+ if( *a != *b && toupper(*a) != toupper(*b) )
+ break;
+ }
+ return *(const byte*)a - *(const byte*)b;
+}
+#endif
diff --git a/comm/third_party/libgcrypt/src/mpi.h b/comm/third_party/libgcrypt/src/mpi.h
new file mode 100644
index 0000000000..9e234eff77
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/mpi.h
@@ -0,0 +1,327 @@
+/* mpi.h - Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998,
+ * 2001, 2002, 2003, 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
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_H
+#define G10_MPI_H
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "types.h"
+#include "../mpi/mpi-asm-defs.h"
+
+#include "g10lib.h"
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+#error this file should only be used inside libgcrypt
+#endif
+
+#ifndef BITS_PER_MPI_LIMB
+#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
+ typedef unsigned int mpi_limb_t;
+ typedef signed int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
+ typedef unsigned long int mpi_limb_t;
+ typedef signed long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
+ typedef unsigned long long int mpi_limb_t;
+ typedef signed long long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
+ typedef unsigned short int mpi_limb_t;
+ typedef signed short int mpi_limb_signed_t;
+#else
+#error BYTES_PER_MPI_LIMB does not match any C type
+#endif
+#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
+#endif /*BITS_PER_MPI_LIMB*/
+
+#define DBG_MPI _gcry_get_debug_flag( 2 );
+
+struct gcry_mpi
+{
+ int alloced; /* Array size (# of allocated limbs). */
+ int nlimbs; /* Number of valid limbs. */
+ int sign; /* Indicates a negative number and is also used
+ for opaque MPIs to store the length. */
+ unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/
+ /* Bit 2: The limb is a pointer to some m_alloced data.*/
+ /* Bit 4: Immutable MPI - the MPI may not be modified. */
+ /* Bit 5: Constant MPI - the MPI will not be freed. */
+ mpi_limb_t *d; /* Array with the limbs */
+};
+
+#define MPI_NULL NULL
+
+#define mpi_get_nlimbs(a) ((a)->nlimbs)
+#define mpi_has_sign(a) ((a)->sign)
+
+/*-- mpiutil.c --*/
+
+#ifdef M_DEBUG
+# define mpi_alloc(n) _gcry_mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) )
+# define mpi_alloc_secure(n) _gcry_mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) )
+# define mpi_free(a) _gcry_mpi_debug_free((a), M_DBGINFO(__LINE__) )
+# define mpi_resize(a,b) _gcry_mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) )
+# define mpi_copy(a) _gcry_mpi_debug_copy((a), M_DBGINFO(__LINE__) )
+ gcry_mpi_t _gcry_mpi_debug_alloc( unsigned nlimbs, const char *info );
+ gcry_mpi_t _gcry_mpi_debug_alloc_secure( unsigned nlimbs, const char *info );
+ void _gcry_mpi_debug_free( gcry_mpi_t a, const char *info );
+ void _gcry_mpi_debug_resize( gcry_mpi_t a, unsigned nlimbs, const char *info );
+ gcry_mpi_t _gcry_mpi_debug_copy( gcry_mpi_t a, const char *info );
+#else
+# define mpi_alloc(n) _gcry_mpi_alloc((n) )
+# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) )
+# define mpi_free(a) _gcry_mpi_free((a) )
+# define mpi_resize(a,b) _gcry_mpi_resize((a),(b))
+# define mpi_copy(a) _gcry_mpi_copy((a))
+ gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs );
+ gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs );
+ void _gcry_mpi_free( gcry_mpi_t a );
+ void _gcry_mpi_resize( gcry_mpi_t a, unsigned nlimbs );
+ gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a );
+#endif
+
+void _gcry_mpi_immutable_failed (void);
+#define mpi_immutable_failed() _gcry_mpi_immutable_failed ()
+
+#define mpi_is_const(a) ((a)->flags&32)
+#define mpi_is_immutable(a) ((a)->flags&16)
+#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
+#define mpi_is_secure(a) ((a) && ((a)->flags&1))
+#define mpi_clear(a) _gcry_mpi_clear ((a))
+#define mpi_alloc_like(a) _gcry_mpi_alloc_like((a))
+
+#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a))
+#define mpi_m_check(a) _gcry_mpi_m_check ((a))
+#define mpi_const(n) _gcry_mpi_const ((n))
+#define mpi_swap_cond(a,b,sw) _gcry_mpi_swap_cond ((a),(b),(sw))
+#define mpi_set_cond(w,u,set) _gcry_mpi_set_cond ((w),(u),(set))
+#define mpi_set_bit_cond(a,n,set) _gcry_mpi_set_bit_cond ((a),(n),(set))
+
+void _gcry_mpi_clear( gcry_mpi_t a );
+gcry_mpi_t _gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u,
+ unsigned long swap);
+gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a );
+gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u);
+void _gcry_mpi_m_check( gcry_mpi_t a );
+void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
+void _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap);
+void _gcry_mpi_set_bit_cond (gcry_mpi_t a, unsigned int n, unsigned long set);
+gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
+gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
+gcry_mpi_t _gcry_mpi_set_opaque_copy (gcry_mpi_t a,
+ const void *p, unsigned int nbits);
+void *_gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits);
+int _gcry_mpi_is_neg (gcry_mpi_t a);
+void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u);
+void _gcry_mpi_abs (gcry_mpi_t w);
+
+/* Constants used to return constant MPIs. See _gcry_mpi_init if you
+ want to add more constants. */
+#define MPI_NUMBER_OF_CONSTANTS 6
+enum gcry_mpi_constants
+ {
+ MPI_C_ZERO,
+ MPI_C_ONE,
+ MPI_C_TWO,
+ MPI_C_THREE,
+ MPI_C_FOUR,
+ MPI_C_EIGHT
+ };
+
+
+gcry_mpi_t _gcry_mpi_const (enum gcry_mpi_constants no);
+
+
+/*-- mpicoder.c --*/
+void _gcry_log_mpidump( const char *text, gcry_mpi_t a );
+u32 _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid );
+byte *_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
+ unsigned int *r_nbytes, int *sign);
+byte *_gcry_mpi_get_buffer_extra (gcry_mpi_t a, unsigned int fill_le,
+ int extraalloc,
+ unsigned int *r_nbytes, int *sign);
+byte *_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
+ unsigned *r_nbytes, int *sign);
+void _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer,
+ unsigned int nbytes, int sign );
+gpg_err_code_t _gcry_mpi_to_octet_string (unsigned char **r_frame,
+ void *space,
+ gcry_mpi_t value, size_t nbytes);
+
+/*-- mpi-div.c --*/
+#define mpi_fdiv_r_ui(a,b,c) _gcry_mpi_fdiv_r_ui((a),(b),(c))
+#define mpi_fdiv_r(a,b,c) _gcry_mpi_fdiv_r((a),(b),(c))
+#define mpi_fdiv_q(a,b,c) _gcry_mpi_fdiv_q((a),(b),(c))
+#define mpi_fdiv_qr(a,b,c,d) _gcry_mpi_fdiv_qr((a),(b),(c),(d))
+#define mpi_tdiv_r(a,b,c) _gcry_mpi_tdiv_r((a),(b),(c))
+#define mpi_tdiv_qr(a,b,c,d) _gcry_mpi_tdiv_qr((a),(b),(c),(d))
+#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c))
+#define mpi_divisible_ui(a,b) _gcry_mpi_divisible_ui((a),(b))
+
+unsigned long _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, unsigned long divisor );
+void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
+void _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
+void _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count );
+int _gcry_mpi_divisible_ui(gcry_mpi_t dividend, unsigned long divisor );
+
+
+/*-- mpi-mod.c --*/
+#define mpi_barrett_init(m,f) _gcry_mpi_barrett_init ((m),(f))
+#define mpi_barrett_free(c) _gcry_mpi_barrett_free ((c))
+#define mpi_mod_barrett(r,a,c) _gcry_mpi_mod_barrett ((r), (a), (c))
+#define mpi_mul_barrett(r,u,v,c) _gcry_mpi_mul_barrett ((r), (u), (v), (c))
+
+/* Context used with Barrett reduction. */
+struct barrett_ctx_s;
+typedef struct barrett_ctx_s *mpi_barrett_t;
+
+mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy);
+void _gcry_mpi_barrett_free (mpi_barrett_t ctx);
+void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx);
+void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
+ mpi_barrett_t ctx);
+
+
+/*-- mpi-mpow.c --*/
+#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d))
+void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod);
+
+/*-- mpi-scan.c --*/
+#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a))
+int _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx );
+void _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value );
+unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a );
+
+/*-- mpi-bit.c --*/
+#define mpi_normalize(a) _gcry_mpi_normalize ((a))
+
+void _gcry_mpi_normalize( gcry_mpi_t a );
+
+/*-- ec.c --*/
+
+/* Object to represent a point in projective coordinates. */
+struct gcry_mpi_point
+{
+ gcry_mpi_t x;
+ gcry_mpi_t y;
+ gcry_mpi_t z;
+};
+typedef struct gcry_mpi_point mpi_point_struct;
+typedef struct gcry_mpi_point *mpi_point_t;
+
+void _gcry_mpi_point_init (mpi_point_t p);
+void _gcry_mpi_point_free_parts (mpi_point_t p);
+void _gcry_mpi_get_point (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ mpi_point_t point);
+void _gcry_mpi_snatch_point (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ mpi_point_t point);
+
+
+/* Models describing an elliptic curve. */
+enum gcry_mpi_ec_models
+ {
+ /* The Short Weierstrass equation is
+ y^2 = x^3 + ax + b
+ */
+ MPI_EC_WEIERSTRASS = 0,
+ /* The Montgomery equation is
+ by^2 = x^3 + ax^2 + x
+ */
+ MPI_EC_MONTGOMERY,
+ /* The Twisted Edwards equation is
+ ax^2 + y^2 = 1 + bx^2y^2
+ Note that we use 'b' instead of the commonly used 'd'. */
+ MPI_EC_EDWARDS
+ };
+
+/* Dialects used with elliptic curves. It is easier to keep the
+ definition here than in ecc-common.h. */
+enum ecc_dialects
+ {
+ ECC_DIALECT_STANDARD = 0,
+ ECC_DIALECT_ED25519,
+ ECC_DIALECT_SAFECURVE
+ };
+
+
+void _gcry_mpi_point_log (const char *name, mpi_point_t point, mpi_ec_t ctx);
+#define log_printpnt(a,p,c) _gcry_mpi_point_log ((a), (p), (c))
+
+mpi_ec_t _gcry_mpi_ec_p_internal_new (enum gcry_mpi_ec_models model,
+ enum ecc_dialects dialect,
+ int flags,
+ gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b);
+gpg_err_code_t _gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
+ enum gcry_mpi_ec_models model,
+ enum ecc_dialects dialect,
+ int flags,
+ gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b);
+void _gcry_mpi_ec_free (mpi_ec_t ctx);
+
+void _gcry_mpi_ec_dup_point (mpi_point_t result,
+ mpi_point_t point, mpi_ec_t ctx);
+void _gcry_mpi_ec_add_points (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx);
+void _gcry_mpi_ec_sub_points (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx);
+void _gcry_mpi_ec_mul_point (mpi_point_t result,
+ gcry_mpi_t scalar, mpi_point_t point,
+ mpi_ec_t ctx);
+int _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx);
+int _gcry_mpi_ec_bad_point (gcry_mpi_point_t point, mpi_ec_t ctx);
+
+gcry_mpi_t _gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ectx);
+
+gcry_mpi_t _gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy);
+gcry_mpi_point_t _gcry_mpi_ec_get_point (const char *name,
+ gcry_ctx_t ctx, int copy);
+gpg_err_code_t _gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
+ gcry_ctx_t ctx);
+gpg_err_code_t _gcry_mpi_ec_set_point (const char *name,
+ gcry_mpi_point_t newvalue,
+ gcry_ctx_t ctx);
+gpg_err_code_t _gcry_mpi_ec_decode_point (mpi_point_t result,
+ gcry_mpi_t value, mpi_ec_t ec);
+
+/*-- ecc-curves.c --*/
+gpg_err_code_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
+ gcry_sexp_t keyparam, const char *curvename);
+gpg_err_code_t _gcry_mpi_ec_internal_new (mpi_ec_t *r_ec, int *r_flags,
+ const char *name_op,
+ gcry_sexp_t keyparam,
+ const char *curvename);
+
+
+
+#endif /*G10_MPI_H*/
diff --git a/comm/third_party/libgcrypt/src/mpicalc.c b/comm/third_party/libgcrypt/src/mpicalc.c
new file mode 100644
index 0000000000..0903e0a4d3
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/mpicalc.c
@@ -0,0 +1,627 @@
+/* mpicalc.c - Simple RPN calculator using gcry_mpi functions
+ * Copyright (C) 1997, 1998, 1999, 2004, 2006, 2013 Werner Koch
+ *
+ * This program 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.
+ *
+ * This program 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This program is a simple RPN calculator which was originally used
+ to develop the mpi functions of GnuPG. Values must be given in
+ hex. Operation is like dc(1) except that the input/output radix is
+ always 16 and you can use a '-' to prefix a negative number.
+ Addition operators: ++ and --. All operators must be delimited by
+ a blank.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# undef _GCRYPT_IN_LIBGCRYPT
+# include "gcrypt.h"
+#else
+# include <gcrypt.h>
+#endif
+
+
+#define MPICALC_VERSION "2.0"
+#define NEED_LIBGCRYPT_VERSION "1.6.0"
+
+#define STACKSIZE 500
+static gcry_mpi_t stack[STACKSIZE];
+static int stackidx;
+
+
+static int
+scan_mpi (gcry_mpi_t retval, const char *string)
+{
+ gpg_error_t err;
+ gcry_mpi_t val;
+
+ err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (err)
+ {
+ fprintf (stderr, "scanning input failed: %s\n", gpg_strerror (err));
+ return -1;
+ }
+ mpi_set (retval, val);
+ mpi_release (val);
+ return 0;
+}
+
+
+static void
+print_mpi (gcry_mpi_t a)
+{
+ gpg_error_t err;
+ char *buf;
+ void *bufaddr = &buf;
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+ if (err)
+ fprintf (stderr, "[error printing number: %s]\n", gpg_strerror (err));
+ else
+ {
+ fputs (buf, stdout);
+ gcry_free (buf);
+ }
+}
+
+
+
+static void
+do_add (void)
+{
+ if (stackidx < 2)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_add (stack[stackidx - 2], stack[stackidx - 2], stack[stackidx - 1]);
+ stackidx--;
+}
+
+static void
+do_sub (void)
+{
+ if (stackidx < 2)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_sub (stack[stackidx - 2], stack[stackidx - 2], stack[stackidx - 1]);
+ stackidx--;
+}
+
+static void
+do_inc (void)
+{
+ if (stackidx < 1)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_add_ui (stack[stackidx - 1], stack[stackidx - 1], 1);
+}
+
+static void
+do_dec (void)
+{
+ if (stackidx < 1)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ /* mpi_sub_ui( stack[stackidx-1], stack[stackidx-1], 1 ); */
+}
+
+static void
+do_mul (void)
+{
+ if (stackidx < 2)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_mul (stack[stackidx - 2], stack[stackidx - 2], stack[stackidx - 1]);
+ stackidx--;
+}
+
+static void
+do_mulm (void)
+{
+ if (stackidx < 3)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_mulm (stack[stackidx - 3], stack[stackidx - 3],
+ stack[stackidx - 2], stack[stackidx - 1]);
+ stackidx -= 2;
+}
+
+static void
+do_div (void)
+{
+ if (stackidx < 2)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_fdiv (stack[stackidx - 2], NULL,
+ stack[stackidx - 2], stack[stackidx - 1]);
+ stackidx--;
+}
+
+static void
+do_rem (void)
+{
+ if (stackidx < 2)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_mod (stack[stackidx - 2],
+ stack[stackidx - 2], stack[stackidx - 1]);
+ stackidx--;
+}
+
+static void
+do_powm (void)
+{
+ gcry_mpi_t a;
+ if (stackidx < 3)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ a = mpi_new (0);
+ mpi_powm (a, stack[stackidx - 3], stack[stackidx - 2], stack[stackidx - 1]);
+ mpi_release (stack[stackidx - 3]);
+ stack[stackidx - 3] = a;
+ stackidx -= 2;
+}
+
+static void
+do_inv (void)
+{
+ gcry_mpi_t a;
+
+ if (stackidx < 2)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ a = mpi_new (0);
+ mpi_invm (a, stack[stackidx - 2], stack[stackidx - 1]);
+ mpi_set (stack[stackidx - 2], a);
+ mpi_release (a);
+ stackidx--;
+}
+
+static void
+do_gcd (void)
+{
+ gcry_mpi_t a;
+
+ if (stackidx < 2)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ a = mpi_new (0);
+ mpi_gcd (a, stack[stackidx - 2], stack[stackidx - 1]);
+ mpi_set (stack[stackidx - 2], a);
+ mpi_release (a);
+ stackidx--;
+}
+
+static void
+do_lshift (void)
+{
+ if (stackidx < 1)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_lshift (stack[stackidx - 1], stack[stackidx - 1], 1);
+}
+
+static void
+do_rshift (void)
+{
+ if (stackidx < 1)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ mpi_rshift (stack[stackidx - 1], stack[stackidx - 1], 1);
+}
+
+static void
+do_nbits (void)
+{
+ unsigned int n;
+
+ if (stackidx < 1)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ n = mpi_get_nbits (stack[stackidx - 1]);
+ mpi_set_ui (stack[stackidx - 1], n);
+}
+
+
+static void
+do_primecheck (void)
+{
+ gpg_error_t err;
+
+ if (stackidx < 1)
+ {
+ fputs ("stack underflow\n", stderr);
+ return;
+ }
+ err = gcry_prime_check (stack[stackidx - 1], 0);
+ mpi_set_ui (stack[stackidx - 1], !err);
+ if (err && gpg_err_code (err) != GPG_ERR_NO_PRIME)
+ fprintf (stderr, "checking prime failed: %s\n", gpg_strerror (err));
+}
+
+
+static int
+my_getc (void)
+{
+ static int shown;
+ int c;
+
+ for (;;)
+ {
+ if ((c = getc (stdin)) == EOF)
+ return EOF;
+ if (!(c & 0x80))
+ return c;
+
+ if (!shown)
+ {
+ shown = 1;
+ fputs ("note: Non ASCII characters are ignored\n", stderr);
+ }
+ }
+}
+
+
+static void
+print_help (void)
+{
+ fputs ("+ add [0] := [1] + [0] {-1}\n"
+ "- subtract [0] := [1] - [0] {-1}\n"
+ "* multiply [0] := [1] * [0] {-1}\n"
+ "/ divide [0] := [1] / [0] {-1}\n"
+ "% modulo [0] := [1] % [0] {-1}\n"
+ "< left shift [0] := [0] << 1 {0}\n"
+ "> right shift [0] := [0] >> 1 {0}\n"
+ "++ increment [0] := [0]++ {0}\n"
+ "-- decrement [0] := [0]-- {0}\n"
+ "m multiply mod [0] := [2] * [1] mod [0] {-2}\n"
+ "^ power mod [0] := [2] ^ [1] mod [0] {-2}\n"
+ "I inverse mod [0] := [1]^-1 mod [0] {-1}\n"
+ "G gcd [0] := gcd([1],[0]) {-1}\n"
+ "i remove item [0] := [1] {-1}\n"
+ "d dup item [-1] := [0] {+1}\n"
+ "r reverse [0] := [1], [1] := [0] {0}\n"
+ "b # of bits [0] := nbits([0]) {0}\n"
+ "P prime check [0] := is_prime([0])?1:0 {0}\n"
+ "c clear stack\n"
+ "p print top item\n"
+ "f print the stack\n"
+ "# ignore until end of line\n"
+ "? print this help\n"
+ , stdout);
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ const char *pgm;
+ int last_argc = -1;
+ int print_config = 0;
+ int i, c;
+ int state = 0;
+ char strbuf[4096];
+ int stridx = 0;
+
+ if (argc)
+ {
+ pgm = strrchr (*argv, '/');
+ if (pgm)
+ pgm++;
+ else
+ pgm = *argv;
+ argc--; argv++;
+ }
+ else
+ pgm = "?";
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version")
+ || !strcmp (*argv, "--help"))
+ {
+ printf ("%s " MPICALC_VERSION "\n"
+ "libgcrypt %s\n"
+ "Copyright (C) 1997, 2013 Werner Koch\n"
+ "License LGPLv2.1+: GNU LGPL version 2.1 or later "
+ "<http://gnu.org/licenses/old-licenses/lgpl-2.1.html>\n"
+ "This is free software: you are free to change and "
+ "redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n"
+ "\n"
+ "Syntax: mpicalc [options]\n"
+ "Simple interactive big integer RPN calculator\n"
+ "\n"
+ "Options:\n"
+ " --version print version information\n"
+ " --print-config print the Libgcrypt config\n"
+ " --disable-hwf NAME disable feature NAME\n",
+ pgm, gcry_check_version (NULL));
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--print-config"))
+ {
+ argc--; argv++;
+ print_config = 1;
+ }
+ else if (!strcmp (*argv, "--disable-hwf"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
+ fprintf (stderr, "%s: unknown hardware feature `%s'"
+ " - option ignored\n", pgm, *argv);
+ argc--; argv++;
+ }
+ }
+ }
+
+ if (argc)
+ {
+ fprintf (stderr, "usage: %s [options] (--help for help)\n", pgm);
+ exit (1);
+ }
+
+ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
+ {
+ fprintf (stderr, "%s: Libgcrypt is too old (need %s, have %s)\n",
+ pgm, NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
+ exit (1);
+ }
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (print_config)
+ {
+ gcry_control (GCRYCTL_PRINT_CONFIG, stdout);
+ exit (0);
+ }
+
+ for (i = 0; i < STACKSIZE; i++)
+ stack[i] = NULL;
+ stackidx = 0;
+
+ while ((c = my_getc ()) != EOF)
+ {
+ if (!state) /* waiting */
+ {
+ if (isdigit (c))
+ {
+ state = 1;
+ ungetc (c, stdin);
+ strbuf[0] = '0';
+ strbuf[1] = 'x';
+ stridx = 2;
+ }
+ else if (isspace (c))
+ ;
+ else
+ {
+ switch (c)
+ {
+ case '#':
+ state = 2;
+ break;
+ case '+':
+ if ((c = my_getc ()) == '+')
+ do_inc ();
+ else
+ {
+ ungetc (c, stdin);
+ do_add ();
+ }
+ break;
+ case '-':
+ if ((c = my_getc ()) == '-')
+ do_dec ();
+ else if (isdigit (c)
+ || (c >= 'A' && c <= 'F')
+ || (c >= 'a' && c <= 'f'))
+ {
+ state = 1;
+ ungetc (c, stdin);
+ strbuf[0] = '-';
+ strbuf[1] = '0';
+ strbuf[2] = 'x';
+ stridx = 3;
+ }
+ else
+ {
+ ungetc (c, stdin);
+ do_sub ();
+ }
+ break;
+ case '*':
+ do_mul ();
+ break;
+ case 'm':
+ do_mulm ();
+ break;
+ case '/':
+ do_div ();
+ break;
+ case '%':
+ do_rem ();
+ break;
+ case '^':
+ do_powm ();
+ break;
+ case '<':
+ do_lshift ();
+ break;
+ case '>':
+ do_rshift ();
+ break;
+ case 'I':
+ do_inv ();
+ break;
+ case 'G':
+ do_gcd ();
+ break;
+ case 'i': /* dummy */
+ if (!stackidx)
+ fputs ("stack underflow\n", stderr);
+ else
+ {
+ mpi_release (stack[stackidx - 1]);
+ stackidx--;
+ }
+ break;
+ case 'd': /* duplicate the tos */
+ if (!stackidx)
+ fputs ("stack underflow\n", stderr);
+ else if (stackidx < STACKSIZE)
+ {
+ mpi_release (stack[stackidx]);
+ stack[stackidx] = mpi_copy (stack[stackidx - 1]);
+ stackidx++;
+ }
+ else
+ fputs ("stack overflow\n", stderr);
+ break;
+ case 'r': /* swap top elements */
+ if (stackidx < 2)
+ fputs ("stack underflow\n", stderr);
+ else if (stackidx < STACKSIZE)
+ {
+ gcry_mpi_t tmp = stack[stackidx-1];
+ stack[stackidx-1] = stack[stackidx - 2];
+ stack[stackidx-2] = tmp;
+ }
+ break;
+ case 'b':
+ do_nbits ();
+ break;
+ case 'P':
+ do_primecheck ();
+ break;
+ case 'c':
+ for (i = 0; i < stackidx; i++)
+ {
+ mpi_release (stack[i]); stack[i] = NULL;
+ }
+ stackidx = 0;
+ break;
+ case 'p': /* print the tos */
+ if (!stackidx)
+ puts ("stack is empty");
+ else
+ {
+ print_mpi (stack[stackidx - 1]);
+ putchar ('\n');
+ }
+ break;
+ case 'f': /* print the stack */
+ for (i = stackidx - 1; i >= 0; i--)
+ {
+ printf ("[%2d]: ", i);
+ print_mpi (stack[i]);
+ putchar ('\n');
+ }
+ break;
+ case '?':
+ print_help ();
+ break;
+ default:
+ fputs ("invalid operator\n", stderr);
+ }
+ }
+ }
+ else if (state == 1) /* In a number. */
+ {
+ if (!isxdigit (c))
+ {
+ /* Store the number */
+ state = 0;
+ ungetc (c, stdin);
+ if (stridx < sizeof strbuf)
+ strbuf[stridx] = 0;
+
+ if (stackidx < STACKSIZE)
+ {
+ if (!stack[stackidx])
+ stack[stackidx] = mpi_new (0);
+ if (scan_mpi (stack[stackidx], strbuf))
+ fputs ("invalid number\n", stderr);
+ else
+ stackidx++;
+ }
+ else
+ fputs ("stack overflow\n", stderr);
+ }
+ else
+ { /* Store a digit. */
+ if (stridx < sizeof strbuf - 1)
+ strbuf[stridx++] = c;
+ else if (stridx == sizeof strbuf - 1)
+ {
+ strbuf[stridx] = 0;
+ fputs ("input too large - truncated\n", stderr);
+ stridx++;
+ }
+ }
+ }
+ else if (state == 2) /* In a comment. */
+ {
+ if (c == '\n')
+ state = 0;
+ }
+
+ }
+
+ for (i = 0; i < stackidx; i++)
+ mpi_release (stack[i]);
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/src/secmem.c b/comm/third_party/libgcrypt/src/secmem.c
new file mode 100644
index 0000000000..b36c44f6de
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/secmem.c
@@ -0,0 +1,952 @@
+/* secmem.c - memory allocation from a secure heap
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stddef.h>
+
+#if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#ifdef USE_CAPABILITIES
+#include <sys/capability.h>
+#endif
+#endif
+
+#include "g10lib.h"
+#include "secmem.h"
+
+#if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#define MINIMUM_POOL_SIZE 16384
+#define STANDARD_POOL_SIZE 32768
+#define DEFAULT_PAGE_SIZE 4096
+
+typedef struct memblock
+{
+ unsigned size; /* Size of the memory available to the
+ user. */
+ int flags; /* See below. */
+ PROPERLY_ALIGNED_TYPE aligned;
+} memblock_t;
+
+/* This flag specifies that the memory block is in use. */
+#define MB_FLAG_ACTIVE (1 << 0)
+
+/* An object describing a memory pool. */
+typedef struct pooldesc_s
+{
+ /* A link to the next pool. This is used to connect the overflow
+ * pools. */
+ struct pooldesc_s * volatile next;
+
+ /* A memory buffer used as allocation pool. */
+ void *mem;
+
+ /* The allocated size of MEM. */
+ size_t size;
+
+ /* Flag indicating that this memory pool is ready for use. May be
+ * checked in an atexit function. */
+ volatile int okay;
+
+ /* Flag indicating whether MEM is mmapped. */
+ volatile int is_mmapped;
+
+ /* The number of allocated bytes and the number of used blocks in
+ * this pool. */
+ unsigned int cur_alloced, cur_blocks;
+} pooldesc_t;
+
+
+/* The pool of secure memory. This is the head of a linked list with
+ * the first element being the standard mlock-ed pool and the
+ * following elements being the overflow pools. */
+static pooldesc_t mainpool;
+
+
+/* A couple of flags with some being set early. */
+static int disable_secmem;
+static int show_warning;
+static int not_locked;
+static int no_warning;
+static int suspend_warning;
+static int no_mlock;
+static int no_priv_drop;
+static unsigned int auto_expand;
+
+
+/* Lock protecting accesses to the memory pools. */
+GPGRT_LOCK_DEFINE (secmem_lock);
+
+/* Convenient macros. */
+#define SECMEM_LOCK gpgrt_lock_lock (&secmem_lock)
+#define SECMEM_UNLOCK gpgrt_lock_unlock (&secmem_lock)
+
+/* The size of the memblock structure; this does not include the
+ memory that is available to the user. */
+#define BLOCK_HEAD_SIZE \
+ offsetof (memblock_t, aligned)
+
+/* Convert an address into the according memory block structure. */
+#define ADDR_TO_BLOCK(addr) \
+ (memblock_t *) (void *) ((char *) addr - BLOCK_HEAD_SIZE)
+
+/* Prototypes. */
+static void secmem_dump_stats_internal (int extended);
+
+
+/*
+ * Functions
+ */
+
+/* Memory barrier */
+static inline void
+memory_barrier(void)
+{
+#ifdef HAVE_SYNC_SYNCHRONIZE
+#ifdef HAVE_GCC_ASM_VOLATILE_MEMORY
+ asm volatile ("":::"memory");
+#endif
+ /* Use GCC / clang intrinsic for memory barrier. */
+ __sync_synchronize();
+#else
+ /* Slow portable alternative, implement memory barrier by using mutex. */
+ gpgrt_lock_t tmp;
+ memset (&tmp, 0, sizeof(tmp));
+ gpgrt_lock_init (&tmp);
+ gpgrt_lock_lock (&tmp);
+ gpgrt_lock_unlock (&tmp);
+ gpgrt_lock_destroy (&tmp);
+#endif
+}
+
+
+/* Check whether P points into POOL. */
+static inline int
+ptr_into_pool_p (pooldesc_t *pool, const void *p)
+{
+ /* We need to convert pointers to addresses. This is required by
+ C-99 6.5.8 to avoid undefined behaviour. See also
+ http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
+ */
+ uintptr_t p_addr = (uintptr_t)p;
+ uintptr_t pool_addr = (uintptr_t)pool->mem;
+
+ return p_addr >= pool_addr && p_addr < pool_addr + pool->size;
+}
+
+/* Update the stats. */
+static void
+stats_update (pooldesc_t *pool, size_t add, size_t sub)
+{
+ if (add)
+ {
+ pool->cur_alloced += add;
+ pool->cur_blocks++;
+ }
+ if (sub)
+ {
+ pool->cur_alloced -= sub;
+ pool->cur_blocks--;
+ }
+}
+
+/* Return the block following MB or NULL, if MB is the last block. */
+static memblock_t *
+mb_get_next (pooldesc_t *pool, memblock_t *mb)
+{
+ memblock_t *mb_next;
+
+ mb_next = (memblock_t *) (void *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size);
+
+ if (! ptr_into_pool_p (pool, mb_next))
+ mb_next = NULL;
+
+ return mb_next;
+}
+
+/* Return the block preceding MB or NULL, if MB is the first
+ block. */
+static memblock_t *
+mb_get_prev (pooldesc_t *pool, memblock_t *mb)
+{
+ memblock_t *mb_prev, *mb_next;
+
+ if (mb == pool->mem)
+ mb_prev = NULL;
+ else
+ {
+ mb_prev = (memblock_t *) pool->mem;
+ while (1)
+ {
+ mb_next = mb_get_next (pool, mb_prev);
+ if (mb_next == mb)
+ break;
+ else
+ mb_prev = mb_next;
+ }
+ }
+
+ return mb_prev;
+}
+
+/* If the preceding block of MB and/or the following block of MB
+ exist and are not active, merge them to form a bigger block. */
+static void
+mb_merge (pooldesc_t *pool, memblock_t *mb)
+{
+ memblock_t *mb_prev, *mb_next;
+
+ mb_prev = mb_get_prev (pool, mb);
+ mb_next = mb_get_next (pool, mb);
+
+ if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE)))
+ {
+ mb_prev->size += BLOCK_HEAD_SIZE + mb->size;
+ mb = mb_prev;
+ }
+ if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE)))
+ mb->size += BLOCK_HEAD_SIZE + mb_next->size;
+}
+
+/* Return a new block, which can hold SIZE bytes. */
+static memblock_t *
+mb_get_new (pooldesc_t *pool, memblock_t *block, size_t size)
+{
+ memblock_t *mb, *mb_split;
+
+ for (mb = block; ptr_into_pool_p (pool, mb); mb = mb_get_next (pool, mb))
+ if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size)
+ {
+ /* Found a free block. */
+ mb->flags |= MB_FLAG_ACTIVE;
+
+ if (mb->size - size > BLOCK_HEAD_SIZE)
+ {
+ /* Split block. */
+
+ mb_split = (memblock_t *) (void *) (((char *) mb) + BLOCK_HEAD_SIZE
+ + size);
+ mb_split->size = mb->size - size - BLOCK_HEAD_SIZE;
+ mb_split->flags = 0;
+
+ mb->size = size;
+
+ mb_merge (pool, mb_split);
+
+ }
+
+ break;
+ }
+
+ if (! ptr_into_pool_p (pool, mb))
+ {
+ gpg_err_set_errno (ENOMEM);
+ mb = NULL;
+ }
+
+ return mb;
+}
+
+/* Print a warning message. */
+static void
+print_warn (void)
+{
+ if (!no_warning)
+ log_info (_("Warning: using insecure memory!\n"));
+}
+
+
+/* Lock the memory pages of pool P of size N into core and drop
+ * privileges. */
+static void
+lock_pool_pages (void *p, size_t n)
+{
+#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
+ int err;
+
+ {
+ cap_t cap;
+
+ if (!no_priv_drop)
+ {
+ cap = cap_from_text ("cap_ipc_lock+ep");
+ cap_set_proc (cap);
+ cap_free (cap);
+ }
+ err = no_mlock? 0 : mlock (p, n);
+ if (err && errno)
+ err = errno;
+ if (!no_priv_drop)
+ {
+ cap = cap_from_text ("cap_ipc_lock+p");
+ cap_set_proc (cap);
+ cap_free(cap);
+ }
+ }
+
+ if (err)
+ {
+ if (err != EPERM
+#ifdef EAGAIN /* BSD and also Linux may return EAGAIN */
+ && err != EAGAIN
+#endif
+#ifdef ENOSYS /* Some SCOs return this (function not implemented) */
+ && err != ENOSYS
+#endif
+#ifdef ENOMEM /* Linux might return this. */
+ && err != ENOMEM
+#endif
+ )
+ log_error ("can't lock memory: %s\n", strerror (err));
+ show_warning = 1;
+ not_locked = 1;
+ }
+
+#elif defined(HAVE_MLOCK)
+ uid_t uid;
+ int err;
+
+ uid = getuid ();
+
+#ifdef HAVE_BROKEN_MLOCK
+ /* Under HP/UX mlock segfaults if called by non-root. Note, we have
+ noch checked whether mlock does really work under AIX where we
+ also detected a broken nlock. Note further, that using plock ()
+ is not a good idea under AIX. */
+ if (uid)
+ {
+ errno = EPERM;
+ err = errno;
+ }
+ else
+ {
+ err = no_mlock? 0 : mlock (p, n);
+ if (err && errno)
+ err = errno;
+ }
+#else /* !HAVE_BROKEN_MLOCK */
+ err = no_mlock? 0 : mlock (p, n);
+ if (err && errno)
+ err = errno;
+#endif /* !HAVE_BROKEN_MLOCK */
+
+ /* Test whether we are running setuid(0). */
+ if (uid && ! geteuid ())
+ {
+ /* Yes, we are. */
+ if (!no_priv_drop)
+ {
+ /* Check that we really dropped the privs.
+ * Note: setuid(0) should always fail */
+ if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+ log_fatal ("failed to reset uid: %s\n", strerror (errno));
+ }
+ }
+
+ if (err)
+ {
+ if (err != EPERM
+#ifdef EAGAIN /* BSD and also Linux may return this. */
+ && err != EAGAIN
+#endif
+#ifdef ENOSYS /* Some SCOs return this (function not implemented). */
+ && err != ENOSYS
+#endif
+#ifdef ENOMEM /* Linux might return this. */
+ && err != ENOMEM
+#endif
+ )
+ log_error ("can't lock memory: %s\n", strerror (err));
+ show_warning = 1;
+ not_locked = 1;
+ }
+
+#elif defined ( __QNX__ )
+ /* QNX does not page at all, so the whole secure memory stuff does
+ * not make much sense. However it is still of use because it
+ * wipes out the memory on a free().
+ * Therefore it is sufficient to suppress the warning. */
+ (void)p;
+ (void)n;
+#elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
+ /* It does not make sense to print such a warning, given the fact that
+ * this whole Windows !@#$% and their user base are inherently insecure. */
+ (void)p;
+ (void)n;
+#elif defined (__riscos__)
+ /* No virtual memory on RISC OS, so no pages are swapped to disc,
+ * besides we don't have mmap, so we don't use it! ;-)
+ * But don't complain, as explained above. */
+ (void)p;
+ (void)n;
+#else
+ (void)p;
+ (void)n;
+ if (!no_mlock)
+ log_info ("Please note that you don't have secure memory on this system\n");
+#endif
+}
+
+/* Initialize POOL. */
+static void
+init_pool (pooldesc_t *pool, size_t n)
+{
+ memblock_t *mb;
+
+ pool->size = n;
+
+ if (disable_secmem)
+ log_bug ("secure memory is disabled");
+
+
+#if HAVE_MMAP
+ {
+ size_t pgsize;
+ long int pgsize_val;
+
+# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pgsize_val = sysconf (_SC_PAGESIZE);
+# elif defined(HAVE_GETPAGESIZE)
+ pgsize_val = getpagesize ();
+# else
+ pgsize_val = -1;
+# endif
+ pgsize = (pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
+
+ pool->size = (pool->size + pgsize - 1) & ~(pgsize - 1);
+# ifdef MAP_ANONYMOUS
+ pool->mem = mmap (0, pool->size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+# else /* map /dev/zero instead */
+ {
+ int fd;
+
+ fd = open ("/dev/zero", O_RDWR);
+ if (fd == -1)
+ {
+ log_error ("can't open /dev/zero: %s\n", strerror (errno));
+ pool->mem = (void *) -1;
+ }
+ else
+ {
+ pool->mem = mmap (0, pool->size,
+ (PROT_READ | PROT_WRITE), MAP_PRIVATE, fd, 0);
+ close (fd);
+ }
+ }
+# endif
+ if (pool->mem == (void *) -1)
+ log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
+ (unsigned) pool->size, strerror (errno));
+ else
+ {
+ pool->is_mmapped = 1;
+ pool->okay = 1;
+ }
+ }
+#endif /*HAVE_MMAP*/
+
+ if (!pool->okay)
+ {
+ pool->mem = malloc (pool->size);
+ if (!pool->mem)
+ log_fatal ("can't allocate memory pool of %u bytes\n",
+ (unsigned) pool->size);
+ else
+ pool->okay = 1;
+ }
+
+ /* Initialize first memory block. */
+ mb = (memblock_t *) pool->mem;
+ mb->size = pool->size - BLOCK_HEAD_SIZE;
+ mb->flags = 0;
+}
+
+
+/* Enable overflow pool allocation in all cases. CHUNKSIZE is a hint
+ * on how large to allocate overflow pools. */
+void
+_gcry_secmem_set_auto_expand (unsigned int chunksize)
+{
+ /* Round up to a multiple of the STANDARD_POOL_SIZE. */
+ chunksize = ((chunksize + (2*STANDARD_POOL_SIZE) - 1)
+ / STANDARD_POOL_SIZE ) * STANDARD_POOL_SIZE;
+ if (chunksize < STANDARD_POOL_SIZE) /* In case of overflow. */
+ chunksize = STANDARD_POOL_SIZE;
+
+ SECMEM_LOCK;
+ auto_expand = chunksize;
+ SECMEM_UNLOCK;
+}
+
+
+void
+_gcry_secmem_set_flags (unsigned flags)
+{
+ int was_susp;
+
+ SECMEM_LOCK;
+
+ was_susp = suspend_warning;
+ no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
+ suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
+ no_mlock = flags & GCRY_SECMEM_FLAG_NO_MLOCK;
+ no_priv_drop = flags & GCRY_SECMEM_FLAG_NO_PRIV_DROP;
+
+ /* and now issue the warning if it is not longer suspended */
+ if (was_susp && !suspend_warning && show_warning)
+ {
+ show_warning = 0;
+ print_warn ();
+ }
+
+ SECMEM_UNLOCK;
+}
+
+unsigned int
+_gcry_secmem_get_flags (void)
+{
+ unsigned flags;
+
+ SECMEM_LOCK;
+
+ flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
+ flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
+ flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
+ flags |= no_mlock ? GCRY_SECMEM_FLAG_NO_MLOCK : 0;
+ flags |= no_priv_drop ? GCRY_SECMEM_FLAG_NO_PRIV_DROP : 0;
+
+ SECMEM_UNLOCK;
+
+ return flags;
+}
+
+
+/* This function initializes the main memory pool MAINPOOL. It is
+ * expected to be called with the secmem lock held. */
+static void
+_gcry_secmem_init_internal (size_t n)
+{
+ pooldesc_t *pool;
+
+ pool = &mainpool;
+ if (!n)
+ {
+#ifdef USE_CAPABILITIES
+ /* drop all capabilities */
+ if (!no_priv_drop)
+ {
+ cap_t cap;
+
+ cap = cap_from_text ("all-eip");
+ cap_set_proc (cap);
+ cap_free (cap);
+ }
+
+#elif !defined(HAVE_DOSISH_SYSTEM)
+ uid_t uid;
+
+ disable_secmem = 1;
+ uid = getuid ();
+ if (uid != geteuid ())
+ {
+ if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+ log_fatal ("failed to drop setuid\n");
+ }
+#endif
+ }
+ else
+ {
+ if (n < MINIMUM_POOL_SIZE)
+ n = MINIMUM_POOL_SIZE;
+ if (! pool->okay)
+ {
+ init_pool (pool, n);
+ lock_pool_pages (pool->mem, n);
+ }
+ else
+ log_error ("Oops, secure memory pool already initialized\n");
+ }
+}
+
+
+
+/* Initialize the secure memory system. If running with the necessary
+ privileges, the secure memory pool will be locked into the core in
+ order to prevent page-outs of the data. Furthermore allocated
+ secure memory will be wiped out when released. */
+void
+_gcry_secmem_init (size_t n)
+{
+ SECMEM_LOCK;
+
+ _gcry_secmem_init_internal (n);
+
+ SECMEM_UNLOCK;
+}
+
+
+gcry_err_code_t
+_gcry_secmem_module_init ()
+{
+ /* Not anymore needed. */
+ return 0;
+}
+
+
+static void *
+_gcry_secmem_malloc_internal (size_t size, int xhint)
+{
+ pooldesc_t *pool;
+ memblock_t *mb;
+
+ pool = &mainpool;
+
+ if (!pool->okay)
+ {
+ /* Try to initialize the pool if the user forgot about it. */
+ _gcry_secmem_init_internal (STANDARD_POOL_SIZE);
+ if (!pool->okay)
+ {
+ log_info (_("operation is not possible without "
+ "initialized secure memory\n"));
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ }
+ if (not_locked && fips_mode ())
+ {
+ log_info (_("secure memory pool is not locked while in FIPS mode\n"));
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ if (show_warning && !suspend_warning)
+ {
+ show_warning = 0;
+ print_warn ();
+ }
+
+ /* Blocks are always a multiple of 32. */
+ size = ((size + 31) / 32) * 32;
+
+ mb = mb_get_new (pool, (memblock_t *) pool->mem, size);
+ if (mb)
+ {
+ stats_update (pool, mb->size, 0);
+ return &mb->aligned.c;
+ }
+
+ /* If we are called from xmalloc style functions resort to the
+ * overflow pools to return memory. We don't do this in FIPS mode,
+ * though. If the auto-expand option is active we do the expanding
+ * also for the standard malloc functions.
+ *
+ * The idea of using them by default only for the xmalloc function
+ * is so that a user can control whether memory will be allocated in
+ * the initial created mlock protected secmem area or may also be
+ * allocated from the overflow pools. */
+ if ((xhint || auto_expand) && !fips_mode ())
+ {
+ /* Check whether we can allocate from the overflow pools. */
+ for (pool = pool->next; pool; pool = pool->next)
+ {
+ mb = mb_get_new (pool, (memblock_t *) pool->mem, size);
+ if (mb)
+ {
+ stats_update (pool, mb->size, 0);
+ return &mb->aligned.c;
+ }
+ }
+ /* Allocate a new overflow pool. We put a new pool right after
+ * the mainpool so that the next allocation will happen in that
+ * pool and not in one of the older pools. When this new pool
+ * gets full we will try to find space in the older pools. */
+ pool = calloc (1, sizeof *pool);
+ if (!pool)
+ return NULL; /* Not enough memory for a new pool descriptor. */
+ pool->size = auto_expand? auto_expand : STANDARD_POOL_SIZE;
+ pool->mem = malloc (pool->size);
+ if (!pool->mem)
+ {
+ free (pool);
+ return NULL; /* Not enough memory available for a new pool. */
+ }
+ /* Initialize first memory block. */
+ mb = (memblock_t *) pool->mem;
+ mb->size = pool->size - BLOCK_HEAD_SIZE;
+ mb->flags = 0;
+
+ pool->okay = 1;
+
+ /* Take care: in _gcry_private_is_secure we do not lock and thus
+ * we assume that the second assignment below is atomic. Memory
+ * barrier prevents reordering of stores to new pool structure after
+ * MAINPOOL.NEXT assigment and prevents _gcry_private_is_secure seeing
+ * non-initialized POOL->NEXT pointers. */
+ pool->next = mainpool.next;
+ memory_barrier();
+ mainpool.next = pool;
+
+ /* After the first time we allocated an overflow pool, print a
+ * warning. */
+ if (!pool->next)
+ print_warn ();
+
+ /* Allocate. */
+ mb = mb_get_new (pool, (memblock_t *) pool->mem, size);
+ if (mb)
+ {
+ stats_update (pool, mb->size, 0);
+ return &mb->aligned.c;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Allocate a block from the secmem of SIZE. With XHINT set assume
+ * that the caller is a xmalloc style function. */
+void *
+_gcry_secmem_malloc (size_t size, int xhint)
+{
+ void *p;
+
+ SECMEM_LOCK;
+ p = _gcry_secmem_malloc_internal (size, xhint);
+ SECMEM_UNLOCK;
+
+ return p;
+}
+
+static int
+_gcry_secmem_free_internal (void *a)
+{
+ pooldesc_t *pool;
+ memblock_t *mb;
+ int size;
+
+ for (pool = &mainpool; pool; pool = pool->next)
+ if (pool->okay && ptr_into_pool_p (pool, a))
+ break;
+ if (!pool)
+ return 0; /* A does not belong to use. */
+
+ mb = ADDR_TO_BLOCK (a);
+ size = mb->size;
+
+ /* This does not make much sense: probably this memory is held in the
+ * cache. We do it anyway: */
+#define MB_WIPE_OUT(byte) \
+ wipememory2 (((char *) mb + BLOCK_HEAD_SIZE), (byte), size);
+
+ MB_WIPE_OUT (0xff);
+ MB_WIPE_OUT (0xaa);
+ MB_WIPE_OUT (0x55);
+ MB_WIPE_OUT (0x00);
+
+ /* Update stats. */
+ stats_update (pool, 0, size);
+
+ mb->flags &= ~MB_FLAG_ACTIVE;
+
+ mb_merge (pool, mb);
+
+ return 1; /* Freed. */
+}
+
+
+/* Wipe out and release memory. Returns true if this function
+ * actually released A. */
+int
+_gcry_secmem_free (void *a)
+{
+ int mine;
+
+ if (!a)
+ return 1; /* Tell caller that we handled it. */
+
+ SECMEM_LOCK;
+ mine = _gcry_secmem_free_internal (a);
+ SECMEM_UNLOCK;
+ return mine;
+}
+
+
+static void *
+_gcry_secmem_realloc_internal (void *p, size_t newsize, int xhint)
+{
+ memblock_t *mb;
+ size_t size;
+ void *a;
+
+ mb = (memblock_t *) (void *) ((char *) p
+ - ((size_t) &((memblock_t *) 0)->aligned.c));
+ size = mb->size;
+ if (newsize < size)
+ {
+ /* It is easier to not shrink the memory. */
+ a = p;
+ }
+ else
+ {
+ a = _gcry_secmem_malloc_internal (newsize, xhint);
+ if (a)
+ {
+ memcpy (a, p, size);
+ memset ((char *) a + size, 0, newsize - size);
+ _gcry_secmem_free_internal (p);
+ }
+ }
+
+ return a;
+}
+
+
+/* Realloc memory. With XHINT set assume that the caller is a xmalloc
+ * style function. */
+void *
+_gcry_secmem_realloc (void *p, size_t newsize, int xhint)
+{
+ void *a;
+
+ SECMEM_LOCK;
+ a = _gcry_secmem_realloc_internal (p, newsize, xhint);
+ SECMEM_UNLOCK;
+
+ return a;
+}
+
+
+/* Return true if P points into the secure memory areas. */
+int
+_gcry_private_is_secure (const void *p)
+{
+ pooldesc_t *pool;
+
+ /* We do no lock here because once a pool is allocated it will not
+ * be removed anymore (except for gcry_secmem_term). Further, as
+ * assigment of POOL->NEXT in new pool structure is visible in
+ * this thread before assigment of MAINPOOL.NEXT, pool list can be
+ * iterated locklessly. This visiblity is ensured by memory barrier
+ * between POOL->NEXT and MAINPOOL.NEXT assignments in
+ * _gcry_secmem_malloc_internal. */
+ for (pool = &mainpool; pool; pool = pool->next)
+ if (pool->okay && ptr_into_pool_p (pool, p))
+ return 1;
+
+ return 0;
+}
+
+
+/****************
+ * Warning: This code might be called by an interrupt handler
+ * and frankly, there should really be such a handler,
+ * to make sure that the memory is wiped out.
+ * We hope that the OS wipes out mlocked memory after
+ * receiving a SIGKILL - it really should do so, otherwise
+ * there is no chance to get the secure memory cleaned.
+ */
+void
+_gcry_secmem_term ()
+{
+ pooldesc_t *pool, *next;
+
+ for (pool = &mainpool; pool; pool = next)
+ {
+ next = pool->next;
+ if (!pool->okay)
+ continue;
+
+ wipememory2 (pool->mem, 0xff, pool->size);
+ wipememory2 (pool->mem, 0xaa, pool->size);
+ wipememory2 (pool->mem, 0x55, pool->size);
+ wipememory2 (pool->mem, 0x00, pool->size);
+ if (0)
+ ;
+#if HAVE_MMAP
+ else if (pool->is_mmapped)
+ munmap (pool->mem, pool->size);
+#endif
+ else
+ free (pool->mem);
+ pool->mem = NULL;
+ pool->okay = 0;
+ pool->size = 0;
+ if (pool != &mainpool)
+ free (pool);
+ }
+ mainpool.next = NULL;
+ not_locked = 0;
+}
+
+
+/* Print stats of the secmem allocator. With EXTENDED passwed as true
+ * a detiled listing is returned (used for testing). */
+void
+_gcry_secmem_dump_stats (int extended)
+{
+ SECMEM_LOCK;
+ secmem_dump_stats_internal (extended);
+ SECMEM_UNLOCK;
+}
+
+
+static void
+secmem_dump_stats_internal (int extended)
+{
+ pooldesc_t *pool;
+ memblock_t *mb;
+ int i, poolno;
+
+ for (pool = &mainpool, poolno = 0; pool; pool = pool->next, poolno++)
+ {
+ if (!extended)
+ {
+ if (pool->okay)
+ log_info ("%-13s %u/%lu bytes in %u blocks\n",
+ pool == &mainpool? "secmem usage:":"",
+ pool->cur_alloced, (unsigned long)pool->size,
+ pool->cur_blocks);
+ }
+ else
+ {
+ for (i = 0, mb = (memblock_t *) pool->mem;
+ ptr_into_pool_p (pool, mb);
+ mb = mb_get_next (pool, mb), i++)
+ log_info ("SECMEM: pool %d %s block %i size %i\n",
+ poolno,
+ (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
+ i,
+ mb->size);
+ }
+ }
+}
diff --git a/comm/third_party/libgcrypt/src/secmem.h b/comm/third_party/libgcrypt/src/secmem.h
new file mode 100644
index 0000000000..8ad6ef1a38
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/secmem.h
@@ -0,0 +1,42 @@
+/* secmem.h - internal definitions for secmem
+ * Copyright (C) 2000, 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
+ */
+
+#ifndef G10_SECMEM_H
+#define G10_SECMEM_H 1
+
+void _gcry_secmem_init (size_t npool);
+void _gcry_secmem_term (void);
+void *_gcry_secmem_malloc (size_t size, int xhint) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_secmem_realloc (void *a, size_t newsize, int xhint);
+int _gcry_secmem_free (void *a);
+void _gcry_secmem_dump_stats (int extended);
+void _gcry_secmem_set_auto_expand (unsigned int chunksize);
+void _gcry_secmem_set_flags (unsigned flags);
+unsigned _gcry_secmem_get_flags(void);
+int _gcry_private_is_secure (const void *p);
+
+/* Flags for _gcry_secmem_{set,get}_flags. */
+#define GCRY_SECMEM_FLAG_NO_WARNING (1 << 0)
+#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
+#define GCRY_SECMEM_FLAG_NOT_LOCKED (1 << 2)
+#define GCRY_SECMEM_FLAG_NO_MLOCK (1 << 3)
+#define GCRY_SECMEM_FLAG_NO_PRIV_DROP (1 << 4)
+
+#endif /* G10_SECMEM_H */
diff --git a/comm/third_party/libgcrypt/src/sexp.c b/comm/third_party/libgcrypt/src/sexp.c
new file mode 100644
index 0000000000..864916bef7
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/sexp.c
@@ -0,0 +1,2699 @@
+/* sexp.c - S-Expression handling
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003,
+ * 2004, 2006, 2007, 2008, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014, 2017 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 <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+
+#define GCRYPT_NO_MPI_MACROS 1
+#include "g10lib.h"
+
+
+/* Notes on the internal memory layout.
+
+ We store an S-expression as one memory buffer with tags, length and
+ value. The simplest list would thus be:
+
+ /----------+----------+---------+------+-----------+----------\
+ | open_tag | data_tag | datalen | data | close_tag | stop_tag |
+ \----------+----------+---------+------+-----------+----------/
+
+ Expressed more compact and with an example:
+
+ /----+----+----+---+----+----\
+ | OT | DT | DL | D | CT | ST | "(foo)"
+ \----+----+----+---+----+----/
+
+ The open tag must always be the first tag of a list as requires by
+ the S-expression specs. At least data element (data_tag, datalen,
+ data) is required as well. The close_tag finishes the list and
+ would actually be sufficient. For fail-safe reasons a final stop
+ tag is always the last byte in a buffer; it has a value of 0 so
+ that string function accidentally applied to an S-expression will
+ never access unallocated data. We do not support display hints and
+ thus don't need to represent them. A list may have more an
+ arbitrary number of data elements but at least one is required.
+ The length of each data must be greater than 0 and has a current
+ limit to 65535 bytes (by means of the DATALEN type).
+
+ A list with two data elements:
+
+ /----+----+----+---+----+----+---+----+----\
+ | OT | DT | DL | D | DT | DL | D | CT | ST | "(foo bar)"
+ \----+----+----+---+----+----+---+----+----/
+
+ In the above example both DL fields have a value of 3.
+ A list of a list with one data element:
+
+ /----+----+----+----+---+----+----+----\
+ | OT | OT | DT | DL | D | CT | CT | ST | "((foo))"
+ \----+----+----+----+---+----+----+----/
+
+ A list with one element followed by another list:
+
+ /----+----+----+---+----+----+----+---+----+----+----\
+ | OT | DT | DL | D | OT | DT | DL | D | CT | CT | ST | "(foo (bar))"
+ \----+----+----+---+----+----+----+---+----+----+----/
+
+ */
+
+typedef unsigned short DATALEN;
+
+struct gcry_sexp
+{
+ byte d[1];
+};
+
+#define ST_STOP 0
+#define ST_DATA 1 /* datalen follows */
+/*#define ST_HINT 2 datalen follows (currently not used) */
+#define ST_OPEN 3
+#define ST_CLOSE 4
+
+/* The atoi macros assume that the buffer has only valid digits. */
+#define atoi_1(p) (*(p) - '0' )
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
+#define TOKEN_SPECIALS "-./_:*+="
+
+static gcry_err_code_t
+do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, va_list arg_ptr);
+
+static gcry_err_code_t
+do_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, ...);
+
+/* Return true if P points to a byte containing a whitespace according
+ to the S-expressions definition. */
+#undef whitespacep
+static GPG_ERR_INLINE int
+whitespacep (const char *p)
+{
+ switch (*p)
+ {
+ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
+ default: return 0;
+ }
+}
+
+
+#if 0
+static void
+dump_mpi( gcry_mpi_t a )
+{
+ char buffer[1000];
+ size_t n = 1000;
+
+ if( !a )
+ fputs("[no MPI]", stderr );
+ else if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) )
+ fputs("[MPI too large to print]", stderr );
+ else
+ fputs( buffer, stderr );
+}
+#endif
+
+static void
+dump_string (const byte *p, size_t n, int delim )
+{
+ for (; n; n--, p++ )
+ {
+ if ((*p & 0x80) || iscntrl( *p ) || *p == delim )
+ {
+ if( *p == '\n' )
+ log_printf ("\\n");
+ else if( *p == '\r' )
+ log_printf ("\\r");
+ else if( *p == '\f' )
+ log_printf ("\\f");
+ else if( *p == '\v' )
+ log_printf ("\\v");
+ else if( *p == '\b' )
+ log_printf ("\\b");
+ else if( !*p )
+ log_printf ("\\0");
+ else
+ log_printf ("\\x%02x", *p );
+ }
+ else
+ log_printf ("%c", *p);
+ }
+}
+
+
+void
+_gcry_sexp_dump (const gcry_sexp_t a)
+{
+ const byte *p;
+ int indent = 0;
+ int type;
+
+ if (!a)
+ {
+ log_printf ( "[nil]\n");
+ return;
+ }
+
+ p = a->d;
+ while ( (type = *p) != ST_STOP )
+ {
+ p++;
+ switch ( type )
+ {
+ case ST_OPEN:
+ log_printf ("%*s[open]\n", 2*indent, "");
+ indent++;
+ break;
+ case ST_CLOSE:
+ if( indent )
+ indent--;
+ log_printf ("%*s[close]\n", 2*indent, "");
+ break;
+ case ST_DATA: {
+ DATALEN n;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ log_printf ("%*s[data=\"", 2*indent, "" );
+ dump_string (p, n, '\"' );
+ log_printf ("\"]\n");
+ p += n;
+ }
+ break;
+ default:
+ log_printf ("%*s[unknown tag %d]\n", 2*indent, "", type);
+ break;
+ }
+ }
+}
+
+
+/* Pass list through except when it is an empty list - in that case
+ * return NULL and release the passed list. This is used to make sure
+ * that no forbidden empty lists are created.
+ */
+static gcry_sexp_t
+normalize ( gcry_sexp_t list )
+{
+ unsigned char *p;
+
+ if ( !list )
+ return NULL;
+ p = list->d;
+ if ( *p == ST_STOP )
+ {
+ /* this is "" */
+ sexp_release ( list );
+ return NULL;
+ }
+ if ( *p == ST_OPEN && p[1] == ST_CLOSE )
+ {
+ /* this is "()" */
+ sexp_release ( list );
+ return NULL;
+ }
+
+ return list;
+}
+
+/* Create a new S-expression object by reading LENGTH bytes from
+ BUFFER, assuming it is canonical encoded or autodetected encoding
+ when AUTODETECT is set to 1. With FREEFNC not NULL, ownership of
+ the buffer is transferred to the newly created object. FREEFNC
+ should be the freefnc used to release BUFFER; there is no guarantee
+ at which point this function is called; most likey you want to use
+ free() or gcry_free().
+
+ Passing LENGTH and AUTODETECT as 0 is allowed to indicate that
+ BUFFER points to a valid canonical encoded S-expression. A LENGTH
+ of 0 and AUTODETECT 1 indicates that buffer points to a
+ null-terminated string.
+
+ This function returns 0 and and the pointer to the new object in
+ RETSEXP or an error code in which case RETSEXP is set to NULL. */
+gcry_err_code_t
+_gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
+ int autodetect, void (*freefnc)(void*) )
+{
+ gcry_err_code_t errcode;
+ gcry_sexp_t se;
+
+ if (!retsexp)
+ return GPG_ERR_INV_ARG;
+ *retsexp = NULL;
+ if (autodetect < 0 || autodetect > 1 || !buffer)
+ return GPG_ERR_INV_ARG;
+
+ if (!length && !autodetect)
+ { /* What a brave caller to assume that there is really a canonical
+ encoded S-expression in buffer */
+ length = _gcry_sexp_canon_len (buffer, 0, NULL, &errcode);
+ if (!length)
+ return errcode;
+ }
+ else if (!length && autodetect)
+ { /* buffer is a string */
+ length = strlen ((char *)buffer);
+ }
+
+ errcode = do_sexp_sscan (&se, NULL, buffer, length, 0, NULL);
+ if (errcode)
+ return errcode;
+
+ *retsexp = se;
+ if (freefnc)
+ {
+ /* For now we release the buffer immediately. As soon as we
+ have changed the internal represenation of S-expression to
+ the canoncial format - which has the advantage of faster
+ parsing - we will use this function as a closure in our
+ GCRYSEXP object and use the BUFFER directly. */
+ freefnc (buffer);
+ }
+ return 0;
+}
+
+/* Same as gcry_sexp_create but don't transfer ownership */
+gcry_err_code_t
+_gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
+ int autodetect)
+{
+ return _gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
+}
+
+
+/****************
+ * Release resource of the given SEXP object.
+ */
+void
+_gcry_sexp_release( gcry_sexp_t sexp )
+{
+ if (sexp)
+ {
+ if (_gcry_is_secure (sexp))
+ {
+ /* Extra paranoid wiping. */
+ const byte *p = sexp->d;
+ int type;
+
+ while ( (type = *p) != ST_STOP )
+ {
+ p++;
+ switch ( type )
+ {
+ case ST_OPEN:
+ break;
+ case ST_CLOSE:
+ break;
+ case ST_DATA:
+ {
+ DATALEN n;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ p += n;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ wipememory (sexp->d, p - sexp->d);
+ }
+ xfree ( sexp );
+ }
+}
+
+
+/****************
+ * Make a pair from lists a and b, don't use a or b later on.
+ * Special behaviour: If one is a single element list we put the
+ * element straight into the new pair.
+ */
+gcry_sexp_t
+_gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
+{
+ (void)a;
+ (void)b;
+
+ /* NYI: Implementation should be quite easy with our new data
+ representation */
+ BUG ();
+ return NULL;
+}
+
+
+/****************
+ * Make a list from all items in the array the end of the array is marked
+ * with a NULL.
+ */
+gcry_sexp_t
+_gcry_sexp_alist( const gcry_sexp_t *array )
+{
+ (void)array;
+
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+/****************
+ * Make a list from all items, the end of list is indicated by a NULL
+ */
+gcry_sexp_t
+_gcry_sexp_vlist( const gcry_sexp_t a, ... )
+{
+ (void)a;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+
+/****************
+ * Append n to the list a
+ * Returns: a new list (which maybe a)
+ */
+gcry_sexp_t
+_gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n )
+{
+ (void)a;
+ (void)n;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+gcry_sexp_t
+_gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n )
+{
+ (void)a;
+ (void)n;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+
+
+/****************
+ * Locate token in a list. The token must be the car of a sublist.
+ * Returns: A new list with this sublist or NULL if not found.
+ */
+gcry_sexp_t
+_gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
+{
+ const byte *p;
+ DATALEN n;
+
+ if ( !list )
+ return NULL;
+
+ if ( !toklen )
+ toklen = strlen(tok);
+
+ p = list->d;
+ while ( *p != ST_STOP )
+ {
+ if ( *p == ST_OPEN && p[1] == ST_DATA )
+ {
+ const byte *head = p;
+
+ p += 2;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ if ( n == toklen && !memcmp( p, tok, toklen ) )
+ { /* found it */
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 1;
+
+ /* Look for the end of the list. */
+ for ( p += n; level; p++ )
+ {
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--; /* Compensate for later increment. */
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ BUG ();
+ }
+ }
+ n = p - head;
+
+ newlist = xtrymalloc ( sizeof *newlist + n );
+ if (!newlist)
+ {
+ /* No way to return an error code, so we can only
+ return Not Found. */
+ return NULL;
+ }
+ d = newlist->d;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_STOP;
+ return normalize ( newlist );
+ }
+ p += n;
+ }
+ else if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n ); p += sizeof n;
+ p += n;
+ }
+ else
+ p++;
+ }
+ return NULL;
+}
+
+/****************
+ * Return the length of the given list
+ */
+int
+_gcry_sexp_length (const gcry_sexp_t list)
+{
+ const byte *p;
+ DATALEN n;
+ int type;
+ int length = 0;
+ int level = 0;
+
+ if (!list)
+ return 0;
+
+ p = list->d;
+ while ((type=*p) != ST_STOP)
+ {
+ p++;
+ if (type == ST_DATA)
+ {
+ memcpy (&n, p, sizeof n);
+ p += sizeof n + n;
+ if (level == 1)
+ length++;
+ }
+ else if (type == ST_OPEN)
+ {
+ if (level == 1)
+ length++;
+ level++;
+ }
+ else if (type == ST_CLOSE)
+ {
+ level--;
+ }
+ }
+ return length;
+}
+
+
+/* Return the internal lengths offset of LIST. That is the size of
+ the buffer from the first ST_OPEN, which is returned at R_OFF, to
+ the corresponding ST_CLOSE inclusive. */
+static size_t
+get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
+{
+ const unsigned char *p;
+ DATALEN n;
+ int type;
+ int level = 0;
+
+ *r_off = 0;
+ if (list)
+ {
+ p = list->d;
+ while ( (type=*p) != ST_STOP )
+ {
+ p++;
+ if (type == ST_DATA)
+ {
+ memcpy (&n, p, sizeof n);
+ p += sizeof n + n;
+ }
+ else if (type == ST_OPEN)
+ {
+ if (!level)
+ *r_off = (p-1) - list->d;
+ level++;
+ }
+ else if ( type == ST_CLOSE )
+ {
+ level--;
+ if (!level)
+ return p - list->d;
+ }
+ }
+ }
+ return 0; /* Not a proper list. */
+}
+
+
+
+/* Extract the n-th element of the given LIST. Returns NULL for
+ no-such-element, a corrupt list, or memory failure. */
+gcry_sexp_t
+_gcry_sexp_nth (const gcry_sexp_t list, int number)
+{
+ const byte *p;
+ DATALEN n;
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 0;
+
+ if (!list || list->d[0] != ST_OPEN)
+ return NULL;
+ p = list->d;
+
+ while (number > 0)
+ {
+ p++;
+ if (*p == ST_DATA)
+ {
+ memcpy (&n, ++p, sizeof n);
+ p += sizeof n + n;
+ p--;
+ if (!level)
+ number--;
+ }
+ else if (*p == ST_OPEN)
+ {
+ level++;
+ }
+ else if (*p == ST_CLOSE)
+ {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if (*p == ST_STOP)
+ {
+ return NULL;
+ }
+ }
+ p++;
+
+ if (*p == ST_DATA)
+ {
+ memcpy (&n, p+1, sizeof n);
+ newlist = xtrymalloc (sizeof *newlist + 1 + 1 + sizeof n + n + 1);
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ *d++ = ST_OPEN;
+ memcpy (d, p, 1 + sizeof n + n);
+ d += 1 + sizeof n + n;
+ *d++ = ST_CLOSE;
+ *d = ST_STOP;
+ }
+ else if (*p == ST_OPEN)
+ {
+ const byte *head = p;
+
+ level = 1;
+ do {
+ p++;
+ if (*p == ST_DATA)
+ {
+ memcpy (&n, ++p, sizeof n);
+ p += sizeof n + n;
+ p--;
+ }
+ else if (*p == ST_OPEN)
+ {
+ level++;
+ }
+ else if (*p == ST_CLOSE)
+ {
+ level--;
+ }
+ else if (*p == ST_STOP)
+ {
+ BUG ();
+ }
+ } while (level);
+ n = p + 1 - head;
+
+ newlist = xtrymalloc (sizeof *newlist + n);
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ memcpy (d, head, n);
+ d += n;
+ *d++ = ST_STOP;
+ }
+ else
+ newlist = NULL;
+
+ return normalize (newlist);
+}
+
+
+gcry_sexp_t
+_gcry_sexp_car (const gcry_sexp_t list)
+{
+ return _gcry_sexp_nth (list, 0);
+}
+
+
+/* Helper to get data from the car. The returned value is valid as
+ long as the list is not modified. */
+static const char *
+do_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
+{
+ const byte *p;
+ DATALEN n;
+ int level = 0;
+
+ *datalen = 0;
+ if ( !list )
+ return NULL;
+
+ p = list->d;
+ if ( *p == ST_OPEN )
+ p++; /* Yep, a list. */
+ else if (number)
+ return NULL; /* Not a list but N > 0 requested. */
+
+ /* Skip over N elements. */
+ while (number > 0)
+ {
+ if (*p == ST_DATA)
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
+ }
+ else if (*p == ST_OPEN)
+ {
+ level++;
+ }
+ else if (*p == ST_CLOSE)
+ {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if (*p == ST_STOP)
+ {
+ return NULL;
+ }
+ p++;
+ }
+
+ /* If this is data, return it. */
+ if (*p == ST_DATA)
+ {
+ memcpy ( &n, ++p, sizeof n );
+ *datalen = n;
+ return (const char*)p + sizeof n;
+ }
+
+ return NULL;
+}
+
+
+/* Get data from the car. The returned value is valid as long as the
+ list is not modified. */
+const char *
+_gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
+{
+ return do_sexp_nth_data (list, number, datalen);
+}
+
+
+/* Get the nth element of a list which needs to be a simple object.
+ The returned value is a malloced buffer and needs to be freed by
+ the caller. This is basically the same as gcry_sexp_nth_data but
+ with an allocated result. */
+void *
+_gcry_sexp_nth_buffer (const gcry_sexp_t list, int number, size_t *rlength)
+{
+ const char *s;
+ size_t n;
+ char *buf;
+
+ *rlength = 0;
+ s = do_sexp_nth_data (list, number, &n);
+ if (!s || !n)
+ return NULL;
+ buf = xtrymalloc (n);
+ if (!buf)
+ return NULL;
+ memcpy (buf, s, n);
+ *rlength = n;
+ return buf;
+}
+
+
+/* Get a string from the car. The returned value is a malloced string
+ and needs to be freed by the caller. */
+char *
+_gcry_sexp_nth_string (const gcry_sexp_t list, int number)
+{
+ const char *s;
+ size_t n;
+ char *buf;
+
+ s = do_sexp_nth_data (list, number, &n);
+ if (!s || n < 1 || (n+1) < 1)
+ return NULL;
+ buf = xtrymalloc (n+1);
+ if (!buf)
+ return NULL;
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ return buf;
+}
+
+
+/*
+ * Get a MPI from the car
+ */
+gcry_mpi_t
+_gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt)
+{
+ size_t n;
+ gcry_mpi_t a;
+
+ if (mpifmt == GCRYMPI_FMT_OPAQUE)
+ {
+ char *p;
+
+ p = _gcry_sexp_nth_buffer (list, number, &n);
+ if (!p)
+ return NULL;
+
+ a = _gcry_is_secure (list)? _gcry_mpi_snew (0) : _gcry_mpi_new (0);
+ if (a)
+ mpi_set_opaque (a, p, n*8);
+ else
+ xfree (p);
+ }
+ else
+ {
+ const char *s;
+
+ if (!mpifmt)
+ mpifmt = GCRYMPI_FMT_STD;
+
+ s = do_sexp_nth_data (list, number, &n);
+ if (!s)
+ return NULL;
+
+ if (_gcry_mpi_scan (&a, mpifmt, s, n, NULL))
+ return NULL;
+ }
+
+ return a;
+}
+
+
+/****************
+ * Get the CDR
+ */
+gcry_sexp_t
+_gcry_sexp_cdr(const gcry_sexp_t list)
+{
+ const byte *p;
+ const byte *head;
+ DATALEN n;
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 0;
+ int skip = 1;
+
+ if (!list || list->d[0] != ST_OPEN)
+ return NULL;
+ p = list->d;
+
+ while (skip > 0)
+ {
+ p++;
+ if (*p == ST_DATA)
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ skip--;
+ }
+ else if (*p == ST_OPEN)
+ {
+ level++;
+ }
+ else if (*p == ST_CLOSE)
+ {
+ level--;
+ if ( !level )
+ skip--;
+ }
+ else if (*p == ST_STOP)
+ {
+ return NULL;
+ }
+ }
+ p++;
+
+ head = p;
+ level = 0;
+ do {
+ if (*p == ST_DATA)
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ }
+ else if (*p == ST_OPEN)
+ {
+ level++;
+ }
+ else if (*p == ST_CLOSE)
+ {
+ level--;
+ }
+ else if (*p == ST_STOP)
+ {
+ return NULL;
+ }
+ p++;
+ } while (level);
+ n = p - head;
+
+ newlist = xtrymalloc (sizeof *newlist + n + 2);
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ *d++ = ST_OPEN;
+ memcpy (d, head, n);
+ d += n;
+ *d++ = ST_CLOSE;
+ *d++ = ST_STOP;
+
+ return normalize (newlist);
+}
+
+
+gcry_sexp_t
+_gcry_sexp_cadr ( const gcry_sexp_t list )
+{
+ gcry_sexp_t a, b;
+
+ a = _gcry_sexp_cdr (list);
+ b = _gcry_sexp_car (a);
+ sexp_release (a);
+ return b;
+}
+
+
+static GPG_ERR_INLINE int
+hextonibble (int s)
+{
+ if (s >= '0' && s <= '9')
+ return s - '0';
+ else if (s >= 'A' && s <= 'F')
+ return 10 + s - 'A';
+ else if (s >= 'a' && s <= 'f')
+ return 10 + s - 'a';
+ else
+ return 0;
+}
+
+
+struct make_space_ctx
+{
+ gcry_sexp_t sexp;
+ size_t allocated;
+ byte *pos;
+};
+
+
+static gpg_err_code_t
+make_space ( struct make_space_ctx *c, size_t n )
+{
+ size_t used = c->pos - c->sexp->d;
+
+ if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
+ {
+ gcry_sexp_t newsexp;
+ byte *newhead;
+ size_t newsize;
+
+ newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
+ if (newsize <= c->allocated)
+ return GPG_ERR_TOO_LARGE;
+ newsexp = xtryrealloc ( c->sexp, sizeof *newsexp + newsize - 1);
+ if (!newsexp)
+ return gpg_err_code_from_errno (errno);
+ c->allocated = newsize;
+ newhead = newsexp->d;
+ c->pos = newhead + used;
+ c->sexp = newsexp;
+ }
+ return 0;
+}
+
+
+/* Unquote STRING of LENGTH and store it into BUF. The surrounding
+ quotes are must already be removed from STRING. We assume that the
+ quoted string is syntacillay correct. */
+static size_t
+unquote_string (const char *string, size_t length, unsigned char *buf)
+{
+ int esc = 0;
+ const unsigned char *s = (const unsigned char*)string;
+ unsigned char *d = buf;
+ size_t n = length;
+
+ for (; n; n--, s++)
+ {
+ if (esc)
+ {
+ switch (*s)
+ {
+ case 'b': *d++ = '\b'; break;
+ case 't': *d++ = '\t'; break;
+ case 'v': *d++ = '\v'; break;
+ case 'n': *d++ = '\n'; break;
+ case 'f': *d++ = '\f'; break;
+ case 'r': *d++ = '\r'; break;
+ case '"': *d++ = '\"'; break;
+ case '\'': *d++ = '\''; break;
+ case '\\': *d++ = '\\'; break;
+
+ case '\r': /* ignore CR[,LF] */
+ if (n>1 && s[1] == '\n')
+ {
+ s++; n--;
+ }
+ break;
+
+ case '\n': /* ignore LF[,CR] */
+ if (n>1 && s[1] == '\r')
+ {
+ s++; n--;
+ }
+ break;
+
+ case 'x': /* hex value */
+ if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
+ {
+ s++; n--;
+ *d++ = xtoi_2 (s);
+ s++; n--;
+ }
+ break;
+
+ default:
+ if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
+ {
+ *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
+ s += 2;
+ n -= 2;
+ }
+ break;
+ }
+ esc = 0;
+ }
+ else if( *s == '\\' )
+ esc = 1;
+ else
+ *d++ = *s;
+ }
+
+ return d - buf;
+}
+
+/****************
+ * Scan the provided buffer and return the S expression in our internal
+ * format. Returns a newly allocated expression. If erroff is not NULL and
+ * a parsing error has occurred, the offset into buffer will be returned.
+ * If ARGFLAG is true, the function supports some printf like
+ * expressions.
+ * These are:
+ * %m - MPI
+ * %s - string (no autoswitch to secure allocation)
+ * %d - integer stored as string (no autoswitch to secure allocation)
+ * %b - memory buffer; this takes _two_ arguments: an integer with the
+ * length of the buffer and a pointer to the buffer.
+ * %S - Copy an gcry_sexp_t here. The S-expression needs to be a
+ * regular one, starting with a parenthesis.
+ * (no autoswitch to secure allocation)
+ * all other format elements are currently not defined and return an error.
+ * this includes the "%%" sequence becauce the percent sign is not an
+ * allowed character.
+ * FIXME: We should find a way to store the secure-MPIs not in the string
+ * but as reference to somewhere - this can help us to save huge amounts
+ * of secure memory. The problem is, that if only one element is secure, all
+ * other elements are automagicaly copied to secure memory too, so the most
+ * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
+ * regardless whether it is needed or not.
+ */
+static gpg_err_code_t
+do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, va_list arg_ptr)
+{
+ gcry_err_code_t err = 0;
+ static const char tokenchars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-./_:*+=";
+ const char *p;
+ size_t n;
+ const char *digptr = NULL;
+ const char *quoted = NULL;
+ const char *tokenp = NULL;
+ const char *hexfmt = NULL;
+ const char *base64 = NULL;
+ const char *disphint = NULL;
+ const char *percent = NULL;
+ int hexcount = 0;
+ int b64count = 0;
+ int quoted_esc = 0;
+ size_t datalen = 0;
+ size_t dummy_erroff;
+ struct make_space_ctx c;
+ int arg_counter = 0;
+ int level = 0;
+
+ if (!retsexp)
+ return GPG_ERR_INV_ARG;
+ *retsexp = NULL;
+
+ if (!buffer)
+ return GPG_ERR_INV_ARG;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+
+ /* Depending on whether ARG_LIST is non-zero or not, this macro gives
+ us the next argument, either from the variable argument list as
+ specified by ARG_PTR or from the argument array ARG_LIST. */
+#define ARG_NEXT(storage, type) \
+ do \
+ { \
+ if (!arg_list) \
+ storage = va_arg (arg_ptr, type); \
+ else \
+ storage = *((type *) (arg_list[arg_counter++])); \
+ } \
+ while (0)
+
+ /* The MAKE_SPACE macro is used before each store operation to
+ ensure that the buffer is large enough. It requires a global
+ context named C and jumps out to the label LEAVE on error! It
+ also sets ERROFF using the variables BUFFER and P. */
+#define MAKE_SPACE(n) do { \
+ gpg_err_code_t _ms_err = make_space (&c, (n)); \
+ if (_ms_err) \
+ { \
+ err = _ms_err; \
+ *erroff = p - buffer; \
+ goto leave; \
+ } \
+ } while (0)
+
+ /* The STORE_LEN macro is used to store the length N at buffer P. */
+#define STORE_LEN(p,n) do { \
+ DATALEN ashort = (n); \
+ memcpy ( (p), &ashort, sizeof(ashort) ); \
+ (p) += sizeof (ashort); \
+ } while (0)
+
+ /* We assume that the internal representation takes less memory than
+ the provided one. However, we add space for one extra datalen so
+ that the code which does the ST_CLOSE can use MAKE_SPACE */
+ c.allocated = length + sizeof(DATALEN);
+ if (length && _gcry_is_secure (buffer))
+ c.sexp = xtrymalloc_secure (sizeof *c.sexp + c.allocated - 1);
+ else
+ c.sexp = xtrymalloc (sizeof *c.sexp + c.allocated - 1);
+ if (!c.sexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ *erroff = 0;
+ goto leave;
+ }
+ c.pos = c.sexp->d;
+
+ for (p = buffer, n = length; n; p++, n--)
+ {
+ if (tokenp && !hexfmt)
+ {
+ if (strchr (tokenchars, *p))
+ continue;
+ else
+ {
+ datalen = p - tokenp;
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, tokenp, datalen);
+ c.pos += datalen;
+ tokenp = NULL;
+ }
+ }
+
+ if (quoted)
+ {
+ if (quoted_esc)
+ {
+ switch (*p)
+ {
+ case 'b': case 't': case 'v': case 'n': case 'f':
+ case 'r': case '"': case '\'': case '\\':
+ quoted_esc = 0;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ if (!((n > 2)
+ && (p[1] >= '0') && (p[1] <= '7')
+ && (p[2] >= '0') && (p[2] <= '7')))
+ {
+ *erroff = p - buffer;
+ /* Invalid octal value. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ p += 2;
+ n -= 2;
+ quoted_esc = 0;
+ break;
+
+ case 'x':
+ if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
+ {
+ *erroff = p - buffer;
+ /* Invalid hex value. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ p += 2;
+ n -= 2;
+ quoted_esc = 0;
+ break;
+
+ case '\r':
+ /* ignore CR[,LF] */
+ if (n && (p[1] == '\n'))
+ {
+ p++;
+ n--;
+ }
+ quoted_esc = 0;
+ break;
+
+ case '\n':
+ /* ignore LF[,CR] */
+ if (n && (p[1] == '\r'))
+ {
+ p++;
+ n--;
+ }
+ quoted_esc = 0;
+ break;
+
+ default:
+ *erroff = p - buffer;
+ /* Invalid quoted string escape. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ }
+ else if (*p == '\\')
+ quoted_esc = 1;
+ else if (*p == '\"')
+ {
+ /* Keep it easy - we know that the unquoted string will
+ never be larger. */
+ unsigned char *save;
+ size_t len;
+
+ quoted++; /* Skip leading quote. */
+ MAKE_SPACE (p - quoted);
+ *c.pos++ = ST_DATA;
+ save = c.pos;
+ STORE_LEN (c.pos, 0); /* Will be fixed up later. */
+ len = unquote_string (quoted, p - quoted, c.pos);
+ c.pos += len;
+ STORE_LEN (save, len);
+ quoted = NULL;
+ }
+ }
+ else if (hexfmt)
+ {
+ if (isxdigit (*p))
+ hexcount++;
+ else if (*p == '#')
+ {
+ if ((hexcount & 1))
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
+ goto leave;
+ }
+
+ datalen = hexcount / 2;
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ for (hexfmt++; hexfmt < p; hexfmt++)
+ {
+ int tmpc;
+
+ if (whitespacep (hexfmt))
+ continue;
+ tmpc = hextonibble (*(const unsigned char*)hexfmt);
+ for (hexfmt++; hexfmt < p && whitespacep (hexfmt); hexfmt++)
+ ;
+ if (hexfmt < p)
+ {
+ tmpc *= 16;
+ tmpc += hextonibble (*(const unsigned char*)hexfmt);
+ }
+ *c.pos++ = tmpc;
+ }
+ hexfmt = NULL;
+ }
+ else if (!whitespacep (p))
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_HEX_CHAR;
+ goto leave;
+ }
+ }
+ else if (base64)
+ {
+ if (digitp (p) || alphap (p) || *p == '+' || *p == '/' || *p == '=')
+ b64count++;
+ else if (*p == '|')
+ {
+ gpgrt_b64state_t b64state;
+ char *b64buf;
+ int i;
+
+ base64++; /* Skip beginning '|' */
+ b64buf = xtrymalloc (b64count);
+ if (!b64buf)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ memcpy (b64buf, base64, b64count);
+
+ b64state = gpgrt_b64dec_start (NULL);
+ if (!b64state)
+ {
+ err = gpg_err_code_from_syserror ();
+ xfree (b64buf);
+ goto leave;
+ }
+ err = gpgrt_b64dec_proc (b64state, b64buf, b64count,
+ &datalen);
+ if (err && gpg_err_code (err) != GPG_ERR_EOF)
+ {
+ xfree (b64state);
+ xfree (b64buf);
+ goto leave;
+ }
+ err = gpgrt_b64dec_finish (b64state);
+ if (err)
+ {
+ xfree (b64buf);
+ goto leave;
+ }
+
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ for (i = 0; i < datalen; i++)
+ *c.pos++ = b64buf[i];
+
+ xfree (b64buf);
+ base64 = NULL;
+ }
+ else
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_CHARACTER;
+ goto leave;
+ }
+ }
+ else if (digptr)
+ {
+ if (digitp (p))
+ ;
+ else if (*p == ':')
+ {
+ datalen = atoi (digptr); /* FIXME: check for overflow. */
+ digptr = NULL;
+ if (datalen > n - 1)
+ {
+ *erroff = p - buffer;
+ /* Buffer too short. */
+ err = GPG_ERR_SEXP_STRING_TOO_LONG;
+ goto leave;
+ }
+ /* Make a new list entry. */
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, p + 1, datalen);
+ c.pos += datalen;
+ n -= datalen;
+ p += datalen;
+ }
+ else if (*p == '\"')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ quoted = p;
+ quoted_esc = 0;
+ }
+ else if (*p == '#')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ hexfmt = p;
+ hexcount = 0;
+ }
+ else if (*p == '|')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ base64 = p;
+ b64count = 0;
+ }
+ else
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_INV_LEN_SPEC;
+ goto leave;
+ }
+ }
+ else if (percent)
+ {
+ if (*p == 'm' || *p == 'M')
+ {
+ /* Insert an MPI. */
+ gcry_mpi_t m;
+ size_t nm = 0;
+ int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG;
+
+ ARG_NEXT (m, gcry_mpi_t);
+
+ if (mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
+ {
+ void *mp;
+ unsigned int nbits;
+
+ mp = mpi_get_opaque (m, &nbits);
+ nm = (nbits+7)/8;
+ if (mp && nm)
+ {
+ MAKE_SPACE (nm);
+ if (!_gcry_is_secure (c.sexp->d)
+ && mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = xtrymalloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ xfree (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, nm);
+ memcpy (c.pos, mp, nm);
+ c.pos += nm;
+ }
+ }
+ else
+ {
+ if (mpifmt == GCRYMPI_FMT_USG && mpi_cmp_ui (m, 0) < 0)
+ {
+ err = GPG_ERR_INV_ARG;
+ goto leave;
+ }
+
+ err = _gcry_mpi_print (mpifmt, NULL, 0, &nm, m);
+ if (err)
+ goto leave;
+
+ MAKE_SPACE (nm);
+ if (!_gcry_is_secure (c.sexp->d)
+ && mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = xtrymalloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ xfree (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, nm);
+ err = _gcry_mpi_print (mpifmt, c.pos, nm, &nm, m);
+ if (err)
+ goto leave;
+ c.pos += nm;
+ }
+ }
+ else if (*p == 's')
+ {
+ /* Insert an string. */
+ const char *astr;
+ size_t alen;
+
+ ARG_NEXT (astr, const char *);
+ alen = strlen (astr);
+
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, astr, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'b')
+ {
+ /* Insert a memory buffer. */
+ const char *astr;
+ int alen;
+
+ ARG_NEXT (alen, int);
+ ARG_NEXT (astr, const char *);
+
+ if (alen < 0)
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_INV_ARG;
+ goto leave;
+ }
+
+ MAKE_SPACE (alen);
+ if (alen
+ && !_gcry_is_secure (c.sexp->d)
+ && _gcry_is_secure (astr))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = xtrymalloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ xfree (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, astr, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'd')
+ {
+ /* Insert an integer as string. */
+ int aint;
+ size_t alen;
+ char buf[35];
+
+ ARG_NEXT (aint, int);
+ snprintf (buf, sizeof buf, "%d", aint);
+ alen = strlen (buf);
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, buf, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'u')
+ {
+ /* Insert an unsigned integer as string. */
+ unsigned int aint;
+ size_t alen;
+ char buf[35];
+
+ ARG_NEXT (aint, unsigned int);
+ snprintf (buf, sizeof buf, "%u", aint);
+ alen = strlen (buf);
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, buf, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'S')
+ {
+ /* Insert a gcry_sexp_t. */
+ gcry_sexp_t asexp;
+ size_t alen, aoff;
+
+ ARG_NEXT (asexp, gcry_sexp_t);
+ alen = get_internal_buffer (asexp, &aoff);
+ if (alen)
+ {
+ MAKE_SPACE (alen);
+ memcpy (c.pos, asexp->d + aoff, alen);
+ c.pos += alen;
+ }
+ }
+ else
+ {
+ *erroff = p - buffer;
+ /* Invalid format specifier. */
+ err = GPG_ERR_SEXP_INV_LEN_SPEC;
+ goto leave;
+ }
+ percent = NULL;
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_OPEN;
+ level++;
+ }
+ else if (*p == ')')
+ {
+ /* Walk up. */
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+
+ if (level == 0)
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNMATCHED_PAREN;
+ goto leave;
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_CLOSE;
+ level--;
+ }
+ else if (*p == '\"')
+ {
+ quoted = p;
+ quoted_esc = 0;
+ }
+ else if (*p == '#')
+ {
+ hexfmt = p;
+ hexcount = 0;
+ }
+ else if (*p == '|')
+ {
+ base64 = p;
+ b64count = 0;
+ }
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_NESTED_DH;
+ goto leave;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if (!disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ disphint = NULL;
+ }
+ else if (digitp (p))
+ {
+ if (*p == '0')
+ {
+ /* A length may not begin with zero. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_ZERO_PREFIX;
+ goto leave;
+ }
+ digptr = p;
+ }
+ else if (strchr (tokenchars, *p))
+ tokenp = p;
+ else if (whitespacep (p))
+ ;
+ else if (*p == '{')
+ {
+ /* fixme: handle rescanning: we can do this by saving our
+ current state and start over at p+1 -- Hmmm. At this
+ point here we are in a well defined state, so we don't
+ need to save it. Great. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ goto leave;
+ }
+ else if (strchr ("&\\", *p))
+ {
+ /* Reserved punctuation. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ goto leave;
+ }
+ else if (argflag && (*p == '%'))
+ percent = p;
+ else
+ {
+ /* Bad or unavailable. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_CHARACTER;
+ goto leave;
+ }
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_STOP;
+
+ if (level && !err)
+ err = GPG_ERR_SEXP_UNMATCHED_PAREN;
+
+ leave:
+ if (err)
+ {
+ /* Error -> deallocate. */
+ if (c.sexp)
+ {
+ /* Extra paranoid wipe on error. */
+ if (_gcry_is_secure (c.sexp))
+ wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
+ xfree (c.sexp);
+ }
+ }
+ else
+ *retsexp = normalize (c.sexp);
+
+ return err;
+#undef MAKE_SPACE
+#undef STORE_LEN
+}
+
+
+static gpg_err_code_t
+do_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, ...)
+{
+ gcry_err_code_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, arg_list);
+ rc = do_vsexp_sscan (retsexp, erroff, buffer, length, argflag,
+ arg_list, arg_ptr);
+ va_end (arg_ptr);
+
+ return rc;
+}
+
+
+gpg_err_code_t
+_gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
+{
+ gcry_err_code_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ rc = do_vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+ NULL, arg_ptr);
+ va_end (arg_ptr);
+
+ return rc;
+}
+
+
+gcry_err_code_t
+_gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, va_list arg_ptr)
+{
+ return do_vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+ NULL, arg_ptr);
+}
+
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+ function arguments. */
+gcry_err_code_t
+_gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list)
+{
+ return do_sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
+}
+
+
+gcry_err_code_t
+_gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length)
+{
+ return do_sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
+}
+
+
+/* Figure out a suitable encoding for BUFFER of LENGTH.
+ Returns: 0 = Binary
+ 1 = String possible
+ 2 = Token possible
+*/
+static int
+suitable_encoding (const unsigned char *buffer, size_t length)
+{
+ const unsigned char *s;
+ int maybe_token = 1;
+
+ if (!length)
+ return 1;
+
+ if (*buffer & 0x80)
+ return 0; /* If the MSB is set we assume that buffer represents a
+ negative number. */
+ if (!*buffer)
+ return 0; /* Starting with a zero is pretty much a binary string. */
+
+ for (s=buffer; length; s++, length--)
+ {
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
+ && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
+ return 0; /*binary*/
+ if ( maybe_token
+ && !alphap (s) && !digitp (s) && !strchr (TOKEN_SPECIALS, *s))
+ maybe_token = 0;
+ }
+ s = buffer;
+ if ( maybe_token && !digitp (s) )
+ return 2;
+ return 1;
+}
+
+
+static int
+convert_to_hex (const unsigned char *src, size_t len, char *dest)
+{
+ int i;
+
+ if (dest)
+ {
+ *dest++ = '#';
+ for (i=0; i < len; i++, dest += 2 )
+ snprintf (dest, 3, "%02X", src[i]);
+ *dest++ = '#';
+ }
+ return len*2+2;
+}
+
+static int
+convert_to_string (const unsigned char *s, size_t len, char *dest)
+{
+ if (dest)
+ {
+ char *p = dest;
+ *p++ = '\"';
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b': *p++ = '\\'; *p++ = 'b'; break;
+ case '\t': *p++ = '\\'; *p++ = 't'; break;
+ case '\v': *p++ = '\\'; *p++ = 'v'; break;
+ case '\n': *p++ = '\\'; *p++ = 'n'; break;
+ case '\f': *p++ = '\\'; *p++ = 'f'; break;
+ case '\r': *p++ = '\\'; *p++ = 'r'; break;
+ case '\"': *p++ = '\\'; *p++ = '\"'; break;
+ case '\'': *p++ = '\\'; *p++ = '\''; break;
+ case '\\': *p++ = '\\'; *p++ = '\\'; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ {
+ snprintf (p, 5, "\\x%02x", *s);
+ p += 4;
+ }
+ else
+ *p++ = *s;
+ }
+ }
+ *p++ = '\"';
+ return p - dest;
+ }
+ else
+ {
+ int count = 2;
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b':
+ case '\t':
+ case '\v':
+ case '\n':
+ case '\f':
+ case '\r':
+ case '\"':
+ case '\'':
+ case '\\': count += 2; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ count += 4;
+ else
+ count++;
+ }
+ }
+ return count;
+ }
+}
+
+
+
+static int
+convert_to_token (const unsigned char *src, size_t len, char *dest)
+{
+ if (dest)
+ memcpy (dest, src, len);
+ return len;
+}
+
+
+/****************
+ * Print SEXP to buffer using the MODE. Returns the length of the
+ * SEXP in buffer or 0 if the buffer is too short (We have at least an
+ * empty list consisting of 2 bytes). If a buffer of NULL is provided,
+ * the required length is returned.
+ */
+size_t
+_gcry_sexp_sprint (const gcry_sexp_t list, int mode,
+ void *buffer, size_t maxlength )
+{
+ static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
+ const unsigned char *s;
+ char *d;
+ DATALEN n;
+ char numbuf[20];
+ size_t len = 0;
+ int i, indent = 0;
+
+ s = list? list->d : empty;
+ d = buffer;
+ while ( *s != ST_STOP )
+ {
+ switch ( *s )
+ {
+ case ST_OPEN:
+ s++;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ len++;
+ len += indent;
+ }
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ *d++ = '(';
+ }
+ indent++;
+ break;
+ case ST_CLOSE:
+ s++;
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = ')';
+ }
+ indent--;
+ if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
+ {
+ len++;
+ len += indent;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ }
+ break;
+ case ST_DATA:
+ s++;
+ memcpy ( &n, s, sizeof n ); s += sizeof n;
+ if (mode == GCRYSEXP_FMT_ADVANCED)
+ {
+ int type;
+ size_t nn;
+
+ switch ( (type=suitable_encoding (s, n)))
+ {
+ case 1: nn = convert_to_string (s, n, NULL); break;
+ case 2: nn = convert_to_token (s, n, NULL); break;
+ default: nn = convert_to_hex (s, n, NULL); break;
+ }
+ len += nn;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ switch (type)
+ {
+ case 1: convert_to_string (s, n, d); break;
+ case 2: convert_to_token (s, n, d); break;
+ default: convert_to_hex (s, n, d); break;
+ }
+ d += nn;
+ }
+ if (s[n] != ST_CLOSE)
+ {
+ len++;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = ' ';
+ }
+ }
+ }
+ else
+ {
+ snprintf (numbuf, sizeof numbuf, "%u:", (unsigned int)n );
+ len += strlen (numbuf) + n;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ d = stpcpy ( d, numbuf );
+ memcpy ( d, s, n ); d += n;
+ }
+ }
+ s += n;
+ break;
+ default:
+ BUG ();
+ }
+ }
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ len++;
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = '\n';
+ }
+ }
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = 0; /* for convenience we make a C string */
+ }
+ else
+ len++; /* we need one byte more for this */
+
+ return len;
+}
+
+
+/* Scan a canonical encoded buffer with implicit length values and
+ return the actual length this S-expression uses. For a valid S-Exp
+ it should never return 0. If LENGTH is not zero, the maximum
+ length to scan is given - this can be used for syntax checks of
+ data passed from outside. errorcode and erroff may both be passed as
+ NULL. */
+size_t
+_gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_err_code_t *errcode)
+{
+ const unsigned char *p;
+ const unsigned char *disphint = NULL;
+ unsigned int datalen = 0;
+ size_t dummy_erroff;
+ gcry_err_code_t dummy_errcode;
+ size_t count = 0;
+ int level = 0;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+ if (!errcode)
+ errcode = &dummy_errcode;
+
+ *errcode = GPG_ERR_NO_ERROR;
+ *erroff = 0;
+ if (!buffer)
+ return 0;
+ if (*buffer != '(')
+ {
+ *errcode = GPG_ERR_SEXP_NOT_CANONICAL;
+ return 0;
+ }
+
+ for (p=buffer; ; p++, count++ )
+ {
+ if (length && count >= length)
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_STRING_TOO_LONG;
+ return 0;
+ }
+
+ if (datalen)
+ {
+ if (*p == ':')
+ {
+ if (length && (count+datalen) >= length)
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_STRING_TOO_LONG;
+ return 0;
+ }
+ count += datalen;
+ p += datalen;
+ datalen = 0;
+ }
+ else if (digitp(p))
+ datalen = datalen*10 + atoi_1(p);
+ else
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_INV_LEN_SPEC;
+ return 0;
+ }
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
+ return 0;
+ }
+ level++;
+ }
+ else if (*p == ')')
+ { /* walk up */
+ if (!level)
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_UNMATCHED_PAREN;
+ return 0;
+ }
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
+ return 0;
+ }
+ if (!--level)
+ return ++count; /* ready */
+ }
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_NESTED_DH;
+ return 0;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if ( !disphint )
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
+ return 0;
+ }
+ disphint = NULL;
+ }
+ else if (digitp (p) )
+ {
+ if (*p == '0')
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_ZERO_PREFIX;
+ return 0;
+ }
+ datalen = atoi_1 (p);
+ }
+ else if (*p == '&' || *p == '\\')
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ return 0;
+ }
+ else
+ {
+ *erroff = count;
+ *errcode = GPG_ERR_SEXP_BAD_CHARACTER;
+ return 0;
+ }
+ }
+}
+
+
+/* Extract MPIs from an s-expression using a list of parameters. The
+ * names of these parameters are given by the string LIST. Some
+ * special characters may be given to control the conversion:
+ *
+ * + :: Switch to unsigned integer format (default).
+ * - :: Switch to standard signed format.
+ * / :: Switch to opaque format
+ * & :: Switch to buffer descriptor mode - see below.
+ * %s :: Switch to allocated string arguments.
+ * %#s :: Switch to allocated string arguments for a list of string flags.
+ * %u :: Switch to unsigned integer arguments.
+ * %lu :: Switch to unsigned long integer arguments.
+ * %zu :: Switch to size_t arguments.
+ * %d :: Switch to signed integer arguments.
+ * %ld :: Switch to signed long integer arguments.
+ * ? :: The previous parameter is optional.
+ *
+ * In general parameter names are single letters. To use a string for
+ * a parameter name, enclose the name in single quotes.
+ *
+ * Unless in gcry_buffer_t mode for each parameter name a pointer to
+ * an MPI variable is expected that must be set to NULL prior to
+ * invoking this function, and finally a NULL is expected. Example:
+ *
+ * _gcry_sexp_extract_param (key, NULL, "n/x+ed",
+ * &mpi_n, &mpi_x, &mpi_e, NULL)
+ *
+ * This stores the parameter "N" from KEY as an unsigned MPI into
+ * MPI_N, the parameter "X" as an opaque MPI into MPI_X, and the
+ * parameter "E" again as an unsigned MPI into MPI_E.
+ *
+ * If in buffer descriptor mode a pointer to gcry_buffer_t descriptor
+ * is expected instead of a pointer to an MPI. The caller may use two
+ * different operation modes: If the DATA field of the provided buffer
+ * descriptor is NULL, the function allocates a new buffer and stores
+ * it at DATA; the other fields are set accordingly with OFF being 0.
+ * If DATA is not NULL, the function assumes that DATA, SIZE, and OFF
+ * describe a buffer where to but the data; on return the LEN field
+ * receives the number of bytes copied to that buffer; if the buffer
+ * is too small, the function immediately returns with an error code
+ * (and LEN set to 0).
+ *
+ * For a flag list ("%#s") which has other lists as elements these
+ * sub-lists are skipped and a indicated by "()" in the output.
+ *
+ * PATH is an optional string used to locate a token. The exclamation
+ * mark separated tokens are used to via gcry_sexp_find_token to find
+ * a start point inside SEXP.
+ *
+ * The function returns 0 on success. On error an error code is
+ * returned, all passed MPIs that might have been allocated up to this
+ * point are deallocated and set to NULL, and all passed buffers are
+ * either truncated if the caller supplied the buffer, or deallocated
+ * if the function allocated the buffer.
+ */
+gpg_err_code_t
+_gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
+ const char *list, va_list arg_ptr)
+{
+ gpg_err_code_t rc;
+ const char *s, *s2;
+ void **array[20];
+ char arrayisdesc[20];
+ int idx, i;
+ gcry_sexp_t l1 = NULL;
+ int mode = '+'; /* Default to GCRYMPI_FMT_USG. */
+ int submode = 0;
+ gcry_sexp_t freethis = NULL;
+ char *tmpstr = NULL;
+
+ /* Values in ARRAYISDESC describing what the ARRAY holds.
+ * 0 - MPI
+ * 1 - gcry_buffer_t provided by caller.
+ * 2 - gcry_buffer_t allocated by us.
+ * 's' - String allocated by us.
+ * 'x' - Ignore
+ */
+ memset (arrayisdesc, 0, sizeof arrayisdesc);
+
+ /* First copy all the args into an array. This is required so that
+ we are able to release already allocated MPIs if later an error
+ was found. */
+ for (s=list, idx=0; *s && idx < DIM (array); s++)
+ {
+ if (*s == '&' || *s == '+' || *s == '-' || *s == '/' || *s == '?')
+ ;
+ else if (*s == '%')
+ {
+ s++;
+ if (*s == 'l' && (s[1] == 'u' || s[1] == 'd'))
+ s++;
+ else if (*s == 'z' && s[1] == 'u')
+ s++;
+ else if (*s == '#' && s[1] == 's')
+ s++;
+ continue;
+ }
+ else if (whitespacep (s))
+ ;
+ else
+ {
+ if (*s == '\'')
+ {
+ s++;
+ s2 = strchr (s, '\'');
+ if (!s2 || s2 == s)
+ {
+ /* Closing quote not found or empty string. */
+ return GPG_ERR_SYNTAX;
+ }
+ s = s2;
+ }
+ array[idx] = va_arg (arg_ptr, void *);
+ if (!array[idx])
+ return GPG_ERR_MISSING_VALUE; /* NULL pointer given. */
+ idx++;
+ }
+ }
+ if (*s)
+ return GPG_ERR_LIMIT_REACHED; /* Too many list elements. */
+ if (va_arg (arg_ptr, gcry_mpi_t *))
+ return GPG_ERR_INV_ARG; /* Not enough list elemends. */
+
+ /* Drill down. */
+ while (path && *path)
+ {
+ size_t n;
+
+ s = strchr (path, '!');
+ if (s == path)
+ {
+ rc = GPG_ERR_NOT_FOUND;
+ goto cleanup;
+ }
+ n = s? s - path : 0;
+ l1 = _gcry_sexp_find_token (sexp, path, n);
+ if (!l1)
+ {
+ rc = GPG_ERR_NOT_FOUND;
+ goto cleanup;
+ }
+ sexp = l1; l1 = NULL;
+ sexp_release (freethis);
+ freethis = sexp;
+ if (n)
+ path += n + 1;
+ else
+ path = NULL;
+ }
+
+
+ /* Now extract all parameters. */
+ for (s=list, idx=0; *s; s++)
+ {
+ if (*s == '&' || *s == '+' || *s == '-' || *s == '/')
+ mode = *s;
+ else if (*s == '%')
+ {
+ s++;
+ if (!*s)
+ continue; /* Ignore at end of format. */
+ if (*s == 's' || *s == 'd' || *s == 'u')
+ {
+ mode = *s;
+ submode = 0;
+ }
+ else if (*s == 'l' && (s[1] == 'u' || s[1] == 'd'))
+ {
+ mode = s[1];
+ submode = 'l';
+ s++;
+ }
+ else if (*s == 'z' && s[1] == 'u')
+ {
+ mode = s[1];
+ submode = 'z';
+ s++;
+ }
+ else if (*s == '#' && s[1] == 's')
+ {
+ mode = s[1];
+ submode = '#';
+ s++;
+ }
+ continue;
+ }
+ else if (whitespacep (s))
+ ;
+ else if (*s == '?')
+ ; /* Only used via lookahead. */
+ else
+ {
+ if (*s == '\'')
+ {
+ /* Find closing quote, find token, set S to closing quote. */
+ s++;
+ s2 = strchr (s, '\'');
+ if (!s2 || s2 == s)
+ {
+ /* Closing quote not found or empty string. */
+ rc = GPG_ERR_SYNTAX;
+ goto cleanup;
+ }
+ l1 = _gcry_sexp_find_token (sexp, s, s2 - s);
+ s = s2;
+ }
+ else
+ l1 = _gcry_sexp_find_token (sexp, s, 1);
+
+ if (!l1 && s[1] == '?')
+ {
+ /* Optional element not found. */
+ if (mode == '&')
+ {
+ gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
+ if (!spec->data)
+ {
+ spec->size = 0;
+ spec->off = 0;
+ }
+ spec->len = 0;
+ }
+ else if (mode == 's')
+ {
+ *array[idx] = NULL;
+ arrayisdesc[idx] = 's';
+ }
+ else if (mode == 'd')
+ {
+ if (submode == 'l')
+ *(long *)array[idx] = 0;
+ else
+ *(int *)array[idx] = 0;
+ arrayisdesc[idx] = 'x';
+ }
+ else if (mode == 'u')
+ {
+ if (submode == 'l')
+ *(unsigned long *)array[idx] = 0;
+ else if (submode == 'z')
+ *(size_t *)array[idx] = 0;
+ else
+ *(unsigned int *)array[idx] = 0;
+ arrayisdesc[idx] = 'x';
+ }
+ else
+ *array[idx] = NULL;
+ }
+ else if (!l1)
+ {
+ rc = GPG_ERR_NO_OBJ; /* List element not found. */
+ goto cleanup;
+ }
+ else
+ {
+ if (mode == '&')
+ {
+ gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
+
+ if (spec->data)
+ {
+ const char *pbuf;
+ size_t nbuf;
+
+ pbuf = _gcry_sexp_nth_data (l1, 1, &nbuf);
+ if (!pbuf || !nbuf)
+ {
+ rc = GPG_ERR_INV_OBJ;
+ goto cleanup;
+ }
+ if (spec->off + nbuf > spec->size)
+ {
+ rc = GPG_ERR_BUFFER_TOO_SHORT;
+ goto cleanup;
+ }
+ memcpy ((char*)spec->data + spec->off, pbuf, nbuf);
+ spec->len = nbuf;
+ arrayisdesc[idx] = 1;
+ }
+ else
+ {
+ spec->data = _gcry_sexp_nth_buffer (l1, 1, &spec->size);
+ if (!spec->data)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Or out of core. */
+ goto cleanup;
+ }
+ spec->len = spec->size;
+ spec->off = 0;
+ arrayisdesc[idx] = 2;
+ }
+ }
+ else if (mode == 's')
+ {
+ if (submode == '#')
+ {
+ size_t needed = 0;
+ size_t n;
+ int l1len;
+ char *p;
+
+ l1len = l1? sexp_length (l1) : 0;
+ for (i = 1; i < l1len; i++)
+ {
+ s2 = sexp_nth_data (l1, i, &n);
+ if (!s2)
+ n = 2; /* Not a data element; we use "()". */
+ needed += n + 1;
+ }
+ if (!needed)
+ {
+ *array[idx] = p = xtrymalloc (1);
+ if (p)
+ *p = 0;
+ }
+ else if ((*array[idx] = p = xtrymalloc (needed)))
+ {
+ for (i = 1; i < l1len; i++)
+ {
+ s2 = sexp_nth_data (l1, i, &n);
+ if (!s2)
+ memcpy (p, "()", (n=2));
+ else
+ memcpy (p, s2, n);
+ p[n] = ' ';
+ p += n + 1;
+ }
+ if (p != *array[idx])
+ p[-1] = 0;
+ }
+ }
+ else
+ *array[idx] = _gcry_sexp_nth_string (l1, 1);
+ if (!*array[idx])
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto cleanup;
+ }
+ arrayisdesc[idx] = 's';
+ }
+ else if (mode == 'd')
+ {
+ long along;
+
+ xfree (tmpstr);
+ tmpstr = _gcry_sexp_nth_string (l1, 1);
+ if (!tmpstr)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto cleanup;
+ }
+ along = strtol (tmpstr, NULL, 10);
+ if (submode == 'l')
+ *(long *)array[idx] = along;
+ else
+ *(int *)array[idx] = along;
+ arrayisdesc[idx] = 'x';
+ }
+ else if (mode == 'u')
+ {
+ long aulong;
+
+ xfree (tmpstr);
+ tmpstr = _gcry_sexp_nth_string (l1, 1);
+ if (!tmpstr)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto cleanup;
+ }
+ aulong = strtoul (tmpstr, NULL, 10);
+ if (submode == 'l')
+ *(unsigned long *)array[idx] = aulong;
+ else if (submode == 'z')
+ *(size_t *)array[idx] = aulong;
+ else
+ *(unsigned int *)array[idx] = aulong;
+ arrayisdesc[idx] = 'x';
+ }
+ else
+ {
+ if (mode == '/')
+ *array[idx] = _gcry_sexp_nth_mpi (l1,1,GCRYMPI_FMT_OPAQUE);
+ else if (mode == '-')
+ *array[idx] = _gcry_sexp_nth_mpi (l1,1,GCRYMPI_FMT_STD);
+ else
+ *array[idx] = _gcry_sexp_nth_mpi (l1,1,GCRYMPI_FMT_USG);
+ if (!*array[idx])
+ {
+ rc = GPG_ERR_INV_OBJ; /* Conversion failed. */
+ goto cleanup;
+ }
+ }
+ sexp_release (l1); l1 = NULL;
+ }
+ idx++;
+ }
+ }
+
+ xfree (tmpstr);
+ sexp_release (freethis);
+ return 0;
+
+ cleanup:
+ xfree (tmpstr);
+ sexp_release (freethis);
+ sexp_release (l1);
+ while (idx--)
+ {
+ if (!arrayisdesc[idx])
+ {
+ _gcry_mpi_release (*array[idx]);
+ *array[idx] = NULL;
+ }
+ else if (arrayisdesc[idx] == 1)
+ {
+ /* Caller provided buffer. */
+ gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
+ spec->len = 0;
+ }
+ else if (arrayisdesc[idx] == 2)
+ {
+ /* We might have allocated a buffer. */
+ gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
+ xfree (spec->data);
+ spec->data = NULL;
+ spec->size = spec->off = spec->len = 0;
+ }
+ else if (arrayisdesc[idx] == 's')
+ {
+ /* We might have allocated a buffer. */
+ xfree (*array[idx]);
+ *array[idx] = NULL;
+ }
+ }
+ return rc;
+}
+
+gpg_err_code_t
+_gcry_sexp_extract_param (gcry_sexp_t sexp, const char *path,
+ const char *list, ...)
+{
+ gcry_err_code_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, list);
+ rc = _gcry_sexp_vextract_param (sexp, path, list, arg_ptr);
+ va_end (arg_ptr);
+ return rc;
+}
diff --git a/comm/third_party/libgcrypt/src/stdmem.c b/comm/third_party/libgcrypt/src/stdmem.c
new file mode 100644
index 0000000000..04ce64fba1
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/stdmem.c
@@ -0,0 +1,246 @@
+/* stdmem.c - private memory allocator
+ * Copyright (C) 1998, 2000, 2002, 2005, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Description of the layered memory management in Libgcrypt:
+ *
+ * [User]
+ * |
+ * |
+ * \ /
+ * global.c: [MM entrance points] -----> [user callbacks]
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * stdmem.c: [non-secure handlers] [secure handlers]
+ *
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * stdmem.c: [ memory guard ]
+ *
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * libc: [ MM functions ] secmem.c: [ secure MM functions]
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "stdmem.h"
+#include "secmem.h"
+
+
+
+#define MAGIC_NOR_BYTE 0x55
+#define MAGIC_SEC_BYTE 0xcc
+#define MAGIC_END_BYTE 0xaa
+
+#if SIZEOF_UNSIGNED_LONG == 8
+#define EXTRA_ALIGN 4
+#else
+#define EXTRA_ALIGN 0
+#endif
+
+
+static int use_m_guard = 0;
+
+/****************
+ * Warning: Never use this function after any of the functions
+ * here have been used.
+ */
+void
+_gcry_private_enable_m_guard (void)
+{
+ use_m_guard = 1;
+}
+
+
+/*
+ * Allocate memory of size n.
+ * Return NULL if we are out of memory.
+ */
+void *
+_gcry_private_malloc (size_t n)
+{
+ if (!n)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL; /* Allocating 0 bytes is undefined - we better return
+ an error to detect such coding errors. */
+ }
+
+ if (use_m_guard)
+ {
+ char *p;
+
+ if ( !(p = malloc (n + EXTRA_ALIGN+5)) )
+ return NULL;
+ ((byte*)p)[EXTRA_ALIGN+0] = n;
+ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
+ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
+ ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE;
+ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
+ return p+EXTRA_ALIGN+4;
+ }
+ else
+ {
+ return malloc( n );
+ }
+}
+
+
+/*
+ * Allocate memory of size N from the secure memory pool. Return NULL
+ * if we are out of memory. XHINT tells the allocator that the caller
+ * used an xmalloc style call.
+ */
+void *
+_gcry_private_malloc_secure (size_t n, int xhint)
+{
+ if (!n)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL; /* Allocating 0 bytes is undefined - better return an
+ error to detect such coding errors. */
+ }
+
+ if (use_m_guard)
+ {
+ char *p;
+
+ if (!(p = _gcry_secmem_malloc (n + EXTRA_ALIGN + 5, xhint)))
+ return NULL;
+ ((byte*)p)[EXTRA_ALIGN+0] = n;
+ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
+ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
+ ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE;
+ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
+ return p+EXTRA_ALIGN+4;
+ }
+ else
+ {
+ return _gcry_secmem_malloc (n, xhint);
+ }
+}
+
+
+/*
+ * Realloc and clear the old space. XHINT tells the allocator that
+ * the caller used an xmalloc style call. Returns NULL if there is
+ * not enough memory.
+ */
+void *
+_gcry_private_realloc (void *a, size_t n, int xhint)
+{
+ if (use_m_guard)
+ {
+ unsigned char *p = a;
+ char *b;
+ size_t len;
+
+ if (!a)
+ return _gcry_private_malloc(n);
+
+ _gcry_private_check_heap(p);
+ len = p[-4];
+ len |= p[-3] << 8;
+ len |= p[-2] << 16;
+ if( len >= n ) /* We don't shrink for now. */
+ return a;
+ if (p[-1] == MAGIC_SEC_BYTE)
+ b = _gcry_private_malloc_secure (n, xhint);
+ else
+ b = _gcry_private_malloc(n);
+ if (!b)
+ return NULL;
+ memcpy (b, a, len);
+ memset (b+len, 0, n-len);
+ _gcry_private_free (p);
+ return b;
+ }
+ else if ( _gcry_private_is_secure(a) )
+ {
+ return _gcry_secmem_realloc (a, n, xhint);
+ }
+ else
+ {
+ return realloc( a, n );
+ }
+}
+
+
+void
+_gcry_private_check_heap (const void *a)
+{
+ if (use_m_guard)
+ {
+ const byte *p = a;
+ size_t len;
+
+ if (!p)
+ return;
+
+ if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) )
+ _gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]);
+ len = p[-4];
+ len |= p[-3] << 8;
+ len |= p[-2] << 16;
+ if ( p[len] != MAGIC_END_BYTE )
+ _gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]);
+ }
+}
+
+
+/*
+ * Free a memory block allocated by this or the secmem module
+ */
+void
+_gcry_private_free (void *a)
+{
+ unsigned char *p = a;
+ unsigned char *freep;
+
+ if (!p)
+ return;
+ if (use_m_guard)
+ {
+ _gcry_private_check_heap (p);
+ freep = p - EXTRA_ALIGN - 4;
+ }
+ else
+ {
+ freep = p;
+ }
+
+ if (!_gcry_private_is_secure (freep) ||
+ !_gcry_secmem_free (freep))
+ {
+ free (freep);
+ }
+}
diff --git a/comm/third_party/libgcrypt/src/stdmem.h b/comm/third_party/libgcrypt/src/stdmem.h
new file mode 100644
index 0000000000..c52aab540d
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/stdmem.h
@@ -0,0 +1,32 @@
+/* stdmem.h - internal definitions for stdmem
+ * Copyright (C) 2000, 2002, 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
+ */
+
+#ifndef G10_STDMEM_H
+#define G10_STDMEM_H 1
+
+void _gcry_private_enable_m_guard(void);
+
+void *_gcry_private_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_private_malloc_secure (size_t n, int xhint) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_private_realloc (void *a, size_t n, int xhint);
+void _gcry_private_check_heap (const void *a);
+void _gcry_private_free (void *a);
+
+#endif /* G10_STDMEM_H */
diff --git a/comm/third_party/libgcrypt/src/types.h b/comm/third_party/libgcrypt/src/types.h
new file mode 100644
index 0000000000..abcba2b943
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/types.h
@@ -0,0 +1,136 @@
+/* types.h - some common typedefs
+ * Copyright (C) 1998, 2000, 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
+ */
+
+#ifndef GCRYPT_TYPES_H
+#define GCRYPT_TYPES_H
+
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+# error config.h must be included before types.h
+#endif
+
+/* The AC_CHECK_SIZEOF() in configure fails for some machines.
+ * we provide some fallback values here */
+#if !SIZEOF_UNSIGNED_SHORT
+# undef SIZEOF_UNSIGNED_SHORT
+# define SIZEOF_UNSIGNED_SHORT 2
+#endif
+#if !SIZEOF_UNSIGNED_INT
+# undef SIZEOF_UNSIGNED_INT
+# define SIZEOF_UNSIGNED_INT 4
+#endif
+#if !SIZEOF_UNSIGNED_LONG
+# undef SIZEOF_UNSIGNED_LONG
+# define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+
+#include <sys/types.h>
+
+/* Provide uintptr_t */
+#ifdef HAVE_STDINT_H
+# include <stdint.h> /* uintptr_t */
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#else
+/* In this case, uintptr_t is provided by config.h. */
+#endif
+
+
+
+#ifndef HAVE_TYPE_BYTE
+# undef byte /* In case there is a macro with that name. */
+# if !(defined(_WIN32) && defined(cbNDRContext))
+ /* Windows typedefs byte in the rpc headers. Avoid warning about
+ double definition. */
+ typedef unsigned char byte;
+# endif
+# define HAVE_TYPE_BYTE
+#endif
+
+#ifndef HAVE_TYPE_USHORT
+# undef ushort /* In case there is a macro with that name. */
+ typedef unsigned short ushort;
+# define HAVE_TYPE_USHORT
+#endif
+
+#ifndef HAVE_TYPE_U16
+# undef u16 /* In case there is a macro with that name. */
+# if SIZEOF_UNSIGNED_INT == 2
+ typedef unsigned int u16;
+# elif SIZEOF_UNSIGNED_SHORT == 2
+ typedef unsigned short u16;
+# else
+# error no typedef for u16
+# endif
+# define HAVE_TYPE_U16
+#endif
+
+#ifndef HAVE_TYPE_U32
+# undef u32 /* In case there is a macro with that name. */
+# if SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int u32;
+# elif SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned long u32;
+# else
+# error no typedef for u32
+# endif
+# define HAVE_TYPE_U32
+#endif
+
+/*
+ * Warning: Some systems segfault when this u64 typedef and
+ * the dummy code in cipher/md.c is not available. Examples are
+ * Solaris and IRIX.
+ */
+#ifndef HAVE_TYPE_U64
+# undef u64 /* In case there is a macro with that name. */
+# if SIZEOF_UNSIGNED_INT == 8
+ typedef unsigned int u64;
+# define U64_C(c) (c ## U)
+# define HAVE_TYPE_U64
+# elif SIZEOF_UNSIGNED_LONG == 8
+ typedef unsigned long u64;
+# define U64_C(c) (c ## UL)
+# define HAVE_TYPE_U64
+# elif SIZEOF_UNSIGNED_LONG_LONG == 8
+ typedef unsigned long long u64;
+# define U64_C(c) (c ## ULL)
+# define HAVE_TYPE_U64
+# elif SIZEOF_UINT64_T == 8
+ typedef uint64_t u64;
+# define U64_C(c) (UINT64_C(c))
+# define HAVE_TYPE_U64
+# else
+# error No way to declare a 64 bit integer type
+# endif
+#endif
+
+typedef union
+{
+ int a;
+ short b;
+ char c[1];
+ long d;
+ u64 e;
+ float f;
+ double g;
+} PROPERLY_ALIGNED_TYPE;
+
+#endif /*GCRYPT_TYPES_H*/
diff --git a/comm/third_party/libgcrypt/src/versioninfo.rc.in b/comm/third_party/libgcrypt/src/versioninfo.rc.in
new file mode 100644
index 0000000000..f87d0d0597
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/versioninfo.rc.in
@@ -0,0 +1,51 @@
+/* versioninfo.rc.in - for libgcrypt
+ * Copyright (C) 2005, 2006 g10 Code GmbH
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* This file is processed by configure to create versioninfo.rc */
+
+#line __LINE__ "versioninfo.rc.in"
+
+#include <afxres.h>
+
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @BUILD_FILEVERSION@
+ PRODUCTVERSION @BUILD_FILEVERSION@
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x21L
+#else
+ FILEFLAGS 0x20L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).\0"
+ VALUE "CompanyName", "g10 Code GmbH\0"
+ VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0"
+ VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0"
+ VALUE "InternalName", "libgcrypt\0"
+ VALUE "LegalCopyright", "Copyright © 2021 g10 Code GmbH\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "libgcrypt.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "libgcrypt\0"
+ VALUE "ProductVersion", "@VERSION@\0"
+ VALUE "SpecialBuild", "@BUILD_TIMESTAMP@\0"
+ END
+ END
+END
diff --git a/comm/third_party/libgcrypt/src/visibility.c b/comm/third_party/libgcrypt/src/visibility.c
new file mode 100644
index 0000000000..8cda962cc7
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/visibility.c
@@ -0,0 +1,1599 @@
+/* visibility.c - Wrapper for all public functions.
+ * Copyright (C) 2007, 2008, 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdarg.h>
+
+#define _GCRY_INCLUDED_BY_VISIBILITY_C
+#include "g10lib.h"
+#include "cipher-proto.h"
+#include "context.h"
+#include "mpi.h"
+
+const char *
+gcry_strerror (gcry_error_t err)
+{
+ return _gcry_strerror (err);
+}
+
+const char *
+gcry_strsource (gcry_error_t err)
+{
+ return _gcry_strsource (err);
+}
+
+gcry_err_code_t
+gcry_err_code_from_errno (int err)
+{
+ return _gcry_err_code_from_errno (err);
+}
+
+int
+gcry_err_code_to_errno (gcry_err_code_t code)
+{
+ return _gcry_err_code_to_errno (code);
+}
+
+gcry_error_t
+gcry_err_make_from_errno (gcry_err_source_t source, int err)
+{
+ return _gcry_err_make_from_errno (source, err);
+}
+
+gcry_error_t
+gcry_error_from_errno (int err)
+{
+ return _gcry_error_from_errno (err);
+}
+
+const char *
+gcry_check_version (const char *req_version)
+{
+ return _gcry_check_version (req_version);
+}
+
+gcry_error_t
+gcry_control (enum gcry_ctl_cmds cmd, ...)
+{
+ gcry_error_t err;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, cmd);
+ err = gpg_error (_gcry_vcontrol (cmd, arg_ptr));
+ va_end(arg_ptr);
+ return err;
+}
+
+gcry_error_t
+gcry_sexp_new (gcry_sexp_t *retsexp,
+ const void *buffer, size_t length,
+ int autodetect)
+{
+ return gpg_error (_gcry_sexp_new (retsexp, buffer, length, autodetect));
+}
+
+gcry_error_t
+gcry_sexp_create (gcry_sexp_t *retsexp,
+ void *buffer, size_t length,
+ int autodetect, void (*freefnc) (void *))
+{
+ return gpg_error (_gcry_sexp_create (retsexp, buffer, length,
+ autodetect, freefnc));
+}
+
+gcry_error_t
+gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length)
+{
+ return gpg_error (_gcry_sexp_sscan (retsexp, erroff, buffer, length));
+}
+
+gcry_error_t
+gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, ...)
+{
+ gcry_err_code_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ rc = _gcry_sexp_vbuild (retsexp, erroff, format, arg_ptr);
+ va_end (arg_ptr);
+ return gpg_error (rc);
+}
+
+gcry_error_t
+gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list)
+{
+ return gpg_error (_gcry_sexp_build_array (retsexp, erroff, format, arg_list));
+}
+
+void
+gcry_sexp_release (gcry_sexp_t sexp)
+{
+ _gcry_sexp_release (sexp);
+}
+
+size_t
+gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode)
+{
+ size_t n;
+ gpg_err_code_t rc;
+
+ n = _gcry_sexp_canon_len (buffer, length, erroff, &rc);
+ if (errcode)
+ *errcode = gpg_error (rc);
+ return n;
+}
+
+size_t
+gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, size_t maxlength)
+{
+ return _gcry_sexp_sprint (sexp, mode, buffer, maxlength);
+}
+
+void
+gcry_sexp_dump (const gcry_sexp_t a)
+{
+ _gcry_sexp_dump (a);
+}
+
+gcry_sexp_t
+gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b)
+{
+ return _gcry_sexp_cons (a, b);
+}
+
+gcry_sexp_t
+gcry_sexp_alist (const gcry_sexp_t *array)
+{
+ return _gcry_sexp_alist (array);
+}
+
+gcry_sexp_t
+gcry_sexp_vlist (const gcry_sexp_t a, ...)
+{
+ /* This is not yet implemented in sexp.c. */
+ (void)a;
+ BUG ();
+ return NULL;
+}
+
+gcry_sexp_t
+gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n)
+{
+ return _gcry_sexp_append (a, n);
+}
+
+gcry_sexp_t
+gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n)
+{
+ return _gcry_sexp_prepend (a, n);
+}
+
+
+gcry_sexp_t
+gcry_sexp_find_token (gcry_sexp_t list, const char *tok, size_t toklen)
+{
+ return _gcry_sexp_find_token (list, tok, toklen);
+}
+
+int
+gcry_sexp_length (const gcry_sexp_t list)
+{
+ return _gcry_sexp_length (list);
+}
+
+gcry_sexp_t
+gcry_sexp_nth (const gcry_sexp_t list, int number)
+{
+ return _gcry_sexp_nth (list, number);
+}
+
+gcry_sexp_t
+gcry_sexp_car (const gcry_sexp_t list)
+{
+ return _gcry_sexp_car (list);
+}
+
+gcry_sexp_t
+gcry_sexp_cdr (const gcry_sexp_t list)
+{
+ return _gcry_sexp_cdr (list);
+}
+
+gcry_sexp_t
+gcry_sexp_cadr (const gcry_sexp_t list)
+{
+ return _gcry_sexp_cadr (list);
+}
+
+const char *
+gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
+{
+ return _gcry_sexp_nth_data (list, number, datalen);
+}
+
+void *
+gcry_sexp_nth_buffer (const gcry_sexp_t list, int number, size_t *rlength)
+{
+ return _gcry_sexp_nth_buffer (list, number, rlength);
+}
+
+char *
+gcry_sexp_nth_string (gcry_sexp_t list, int number)
+{
+ return _gcry_sexp_nth_string (list, number);
+}
+
+gcry_mpi_t
+gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt)
+{
+ return _gcry_sexp_nth_mpi (list, number, mpifmt);
+}
+
+gpg_error_t
+gcry_sexp_extract_param (gcry_sexp_t sexp, const char *path,
+ const char *list, ...)
+{
+ gcry_err_code_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, list);
+ rc = _gcry_sexp_vextract_param (sexp, path, list, arg_ptr);
+ va_end (arg_ptr);
+ return gpg_error (rc);
+}
+
+
+
+gcry_mpi_t
+gcry_mpi_new (unsigned int nbits)
+{
+ return _gcry_mpi_new (nbits);
+}
+
+gcry_mpi_t
+gcry_mpi_snew (unsigned int nbits)
+{
+ return _gcry_mpi_snew (nbits);
+}
+
+void
+gcry_mpi_release (gcry_mpi_t a)
+{
+ _gcry_mpi_release (a);
+}
+
+gcry_mpi_t
+gcry_mpi_copy (const gcry_mpi_t a)
+{
+ return _gcry_mpi_copy (a);
+}
+
+void
+gcry_mpi_snatch (gcry_mpi_t w, const gcry_mpi_t u)
+{
+ _gcry_mpi_snatch (w, u);
+}
+
+gcry_mpi_t
+gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u)
+{
+ return _gcry_mpi_set (w, u);
+}
+
+gcry_mpi_t
+gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
+{
+ return _gcry_mpi_set_ui (w, u);
+}
+
+gcry_error_t
+gcry_mpi_get_ui (unsigned int *w, gcry_mpi_t u)
+{
+ return gpg_error (_gcry_mpi_get_ui (w, u));
+}
+
+void
+gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
+{
+ _gcry_mpi_swap (a, b);
+}
+
+int
+gcry_mpi_is_neg (gcry_mpi_t a)
+{
+ return _gcry_mpi_is_neg (a);
+}
+
+void
+gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
+{
+ _gcry_mpi_neg (w, u);
+}
+
+void
+gcry_mpi_abs (gcry_mpi_t w)
+{
+ _gcry_mpi_abs (w);
+}
+
+int
+gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v)
+{
+ return _gcry_mpi_cmp (u, v);
+}
+
+int
+gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v)
+{
+ return _gcry_mpi_cmp_ui (u, v);
+}
+
+gcry_error_t
+gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+ const void *buffer, size_t buflen,
+ size_t *nscanned)
+{
+ return gpg_error (_gcry_mpi_scan (ret_mpi, format, buffer, buflen, nscanned));
+}
+
+gcry_error_t
+gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten,
+ const gcry_mpi_t a)
+{
+ return gpg_error (_gcry_mpi_print (format, buffer, buflen, nwritten, a));
+}
+
+gcry_error_t
+gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ const gcry_mpi_t a)
+{
+ return gpg_error (_gcry_mpi_aprint (format, buffer, nwritten, a));
+}
+
+void
+gcry_mpi_dump (const gcry_mpi_t a)
+{
+ _gcry_log_printmpi (NULL, a);
+}
+
+void
+gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_add (w, u, v);
+}
+
+void
+gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v)
+{
+ _gcry_mpi_add_ui (w, u, v);
+}
+
+void
+gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_addm (w, u, v, m);
+}
+
+void
+gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_sub (w, u, v);
+}
+
+void
+gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ _gcry_mpi_sub_ui (w, u, v);
+}
+
+void
+gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_subm (w, u, v, m);
+}
+
+void
+gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_mul (w, u, v);
+}
+
+void
+gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ _gcry_mpi_mul_ui (w, u, v);
+}
+
+void
+gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_mulm (w, u, v, m);
+}
+
+void
+gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
+{
+ _gcry_mpi_mul_2exp (w, u, cnt);
+}
+
+void
+gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+ gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
+{
+ _gcry_mpi_div (q, r, dividend, divisor, round);
+}
+
+void
+gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor)
+{
+ _gcry_mpi_mod (r, dividend, divisor);
+}
+
+void
+gcry_mpi_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
+ const gcry_mpi_t m)
+{
+ _gcry_mpi_powm (w, b, e, m);
+}
+
+int
+gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b)
+{
+ return _gcry_mpi_gcd (g, a, b);
+}
+
+int
+gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m)
+{
+ return _gcry_mpi_invm (x, a, m);
+}
+
+gcry_mpi_point_t
+gcry_mpi_point_new (unsigned int nbits)
+{
+ return _gcry_mpi_point_new (nbits);
+}
+
+void
+gcry_mpi_point_release (gcry_mpi_point_t point)
+{
+ _gcry_mpi_point_release (point);
+}
+
+gcry_mpi_point_t
+gcry_mpi_point_copy (gcry_mpi_point_t point)
+{
+ return _gcry_mpi_point_copy (point);
+}
+
+void
+gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ gcry_mpi_point_t point)
+{
+ _gcry_mpi_point_get (x, y, z, point);
+}
+
+void
+gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ gcry_mpi_point_t point)
+{
+ _gcry_mpi_point_snatch_get (x, y, z, point);
+}
+
+gcry_mpi_point_t
+gcry_mpi_point_set (gcry_mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
+{
+ return _gcry_mpi_point_set (point, x, y, z);
+}
+
+gcry_mpi_point_t
+gcry_mpi_point_snatch_set (gcry_mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
+{
+ return _gcry_mpi_point_snatch_set (point, x, y, z);
+}
+
+gpg_error_t
+gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
+ gcry_sexp_t keyparam, const char *curvename)
+{
+ return gpg_error (_gcry_mpi_ec_new (r_ctx, keyparam, curvename));
+}
+
+gcry_mpi_t
+gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy)
+{
+ return _gcry_mpi_ec_get_mpi (name, ctx, copy);
+}
+
+gcry_mpi_point_t
+gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy)
+{
+ return _gcry_mpi_ec_get_point (name, ctx, copy);
+}
+
+gpg_error_t
+gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue, gcry_ctx_t ctx)
+{
+ return gpg_error (_gcry_mpi_ec_set_mpi (name, newvalue, ctx));
+}
+
+gpg_error_t
+gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
+ gcry_ctx_t ctx)
+{
+ return gpg_error (_gcry_mpi_ec_set_point (name, newvalue, ctx));
+}
+
+gpg_error_t
+gcry_mpi_ec_decode_point (gcry_mpi_point_t result, gcry_mpi_t value,
+ gcry_ctx_t ctx)
+{
+ return gpg_error (_gcry_mpi_ec_decode_point
+ (result, value,
+ ctx? _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC) : NULL));
+}
+
+int
+gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
+ gcry_ctx_t ctx)
+{
+ return _gcry_mpi_ec_get_affine (x, y, point,
+ _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+void
+gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx)
+{
+ _gcry_mpi_ec_dup_point (w, u, _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+void
+gcry_mpi_ec_add (gcry_mpi_point_t w,
+ gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx)
+{
+ _gcry_mpi_ec_add_points (w, u, v,
+ _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+void
+gcry_mpi_ec_sub (gcry_mpi_point_t w,
+ gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx)
+{
+ _gcry_mpi_ec_sub_points (w, u, v,
+ _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+void
+gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
+ gcry_ctx_t ctx)
+{
+ _gcry_mpi_ec_mul_point (w, n, u,
+ _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+int
+gcry_mpi_ec_curve_point (gcry_mpi_point_t point, gcry_ctx_t ctx)
+{
+ return _gcry_mpi_ec_curve_point
+ (point, _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+unsigned int
+gcry_mpi_get_nbits (gcry_mpi_t a)
+{
+ return _gcry_mpi_get_nbits (a);
+}
+
+int
+gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n)
+{
+ return _gcry_mpi_test_bit (a, n);
+}
+
+void
+gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_set_bit (a, n);
+}
+
+void
+gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_clear_bit (a, n);
+}
+
+void
+gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_set_highbit (a, n);
+}
+
+void
+gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_clear_highbit (a, n);
+}
+
+void
+gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_rshift (x, a, n);
+}
+
+void
+gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_lshift (x, a, n);
+}
+
+gcry_mpi_t
+gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
+{
+ return _gcry_mpi_set_opaque (a, p, nbits);
+}
+
+gcry_mpi_t
+gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
+{
+ return _gcry_mpi_set_opaque_copy (a, p, nbits);
+}
+
+void *
+gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
+{
+ return _gcry_mpi_get_opaque (a, nbits);
+}
+
+void
+gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ _gcry_mpi_set_flag (a, flag);
+}
+
+void
+gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ _gcry_mpi_clear_flag (a, flag);
+}
+
+int
+gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ return _gcry_mpi_get_flag (a, flag);
+}
+
+gcry_mpi_t
+_gcry_mpi_get_const (int no)
+{
+ switch (no)
+ {
+ case 1: return _gcry_mpi_const (MPI_C_ONE);
+ case 2: return _gcry_mpi_const (MPI_C_TWO);
+ case 3: return _gcry_mpi_const (MPI_C_THREE);
+ case 4: return _gcry_mpi_const (MPI_C_FOUR);
+ case 8: return _gcry_mpi_const (MPI_C_EIGHT);
+ default: log_bug("unsupported GCRYMPI_CONST_ macro used\n");
+ }
+}
+
+gcry_error_t
+gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags)
+{
+ if (!fips_is_operational ())
+ {
+ *handle = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+
+ return gpg_error (_gcry_cipher_open (handle, algo, mode, flags));
+}
+
+void
+gcry_cipher_close (gcry_cipher_hd_t h)
+{
+ _gcry_cipher_close (h);
+}
+
+gcry_error_t
+gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gcry_error (_gcry_cipher_setkey (hd, key, keylen));
+}
+
+gcry_error_t
+gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gcry_error (_gcry_cipher_setiv (hd, iv, ivlen));
+}
+
+gpg_error_t
+gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gcry_error (_gcry_cipher_setctr (hd, ctr, ctrlen));
+}
+
+gcry_error_t
+gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf, size_t abuflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_cipher_authenticate (hd, abuf, abuflen));
+}
+
+gcry_error_t
+gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_cipher_gettag (hd, outtag, taglen));
+}
+
+gcry_error_t
+gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_cipher_checktag (hd, intag, taglen));
+}
+
+
+gcry_error_t
+gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_cipher_ctl (h, cmd, buffer, buflen));
+}
+
+gcry_error_t
+gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes)
+{
+ return gpg_error (_gcry_cipher_info (h, what, buffer, nbytes));
+}
+
+gcry_error_t
+gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_cipher_algo_info (algo, what, buffer, nbytes));
+}
+
+const char *
+gcry_cipher_algo_name (int algorithm)
+{
+ return _gcry_cipher_algo_name (algorithm);
+}
+
+int
+gcry_cipher_map_name (const char *name)
+{
+ return _gcry_cipher_map_name (name);
+}
+
+int
+gcry_cipher_mode_from_oid (const char *string)
+{
+ return _gcry_cipher_mode_from_oid (string);
+}
+
+gcry_error_t
+gcry_cipher_encrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ if (!fips_is_operational ())
+ {
+ /* Make sure that the plaintext will never make it to OUT. */
+ if (out)
+ memset (out, 0x42, outsize);
+ return gpg_error (fips_not_operational ());
+ }
+
+ return gpg_error (_gcry_cipher_encrypt (h, out, outsize, in, inlen));
+}
+
+gcry_error_t
+gcry_cipher_decrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_cipher_decrypt (h, out, outsize, in, inlen));
+}
+
+size_t
+gcry_cipher_get_algo_keylen (int algo)
+{
+ return _gcry_cipher_get_algo_keylen (algo);
+}
+
+size_t
+gcry_cipher_get_algo_blklen (int algo)
+{
+ return _gcry_cipher_get_algo_blklen (algo);
+}
+
+gcry_error_t
+gcry_mac_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_mac_algo_info (algo, what, buffer, nbytes));
+}
+
+const char *
+gcry_mac_algo_name (int algorithm)
+{
+ return _gcry_mac_algo_name (algorithm);
+}
+
+int
+gcry_mac_map_name (const char *string)
+{
+ return _gcry_mac_map_name (string);
+}
+
+int
+gcry_mac_get_algo (gcry_mac_hd_t hd)
+{
+ return _gcry_mac_get_algo (hd);
+}
+
+unsigned int
+gcry_mac_get_algo_maclen (int algo)
+{
+ return _gcry_mac_get_algo_maclen (algo);
+}
+
+unsigned int
+gcry_mac_get_algo_keylen (int algo)
+{
+ return _gcry_mac_get_algo_keylen (algo);
+}
+
+gcry_error_t
+gcry_mac_open (gcry_mac_hd_t *handle, int algo, unsigned int flags,
+ gcry_ctx_t ctx)
+{
+ if (!fips_is_operational ())
+ {
+ *handle = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+
+ return gpg_error (_gcry_mac_open (handle, algo, flags, ctx));
+}
+
+void
+gcry_mac_close (gcry_mac_hd_t hd)
+{
+ _gcry_mac_close (hd);
+}
+
+gcry_error_t
+gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_mac_setkey (hd, key, keylen));
+}
+
+gcry_error_t
+gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_mac_setiv (hd, iv, ivlen));
+}
+
+gcry_error_t
+gcry_mac_write (gcry_mac_hd_t hd, const void *buf, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_mac_write (hd, buf, buflen));
+}
+
+gcry_error_t
+gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t *outlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_mac_read (hd, outbuf, outlen));
+}
+
+gcry_error_t
+gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_mac_verify (hd, buf, buflen));
+}
+
+gcry_error_t
+gcry_mac_ctl (gcry_mac_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_mac_ctl (h, cmd, buffer, buflen));
+}
+
+gcry_error_t
+gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return gpg_error (_gcry_pk_encrypt (result, data, pkey));
+}
+
+gcry_error_t
+gcry_pk_decrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return gpg_error (_gcry_pk_decrypt (result, data, skey));
+}
+
+gcry_error_t
+gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return gpg_error (_gcry_pk_sign (result, data, skey));
+}
+
+gcry_error_t
+gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_pk_verify (sigval, data, pkey));
+}
+
+gcry_error_t
+gcry_pk_testkey (gcry_sexp_t key)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_pk_testkey (key));
+}
+
+gcry_error_t
+gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
+{
+ if (!fips_is_operational ())
+ {
+ *r_key = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return gpg_error (_gcry_pk_genkey (r_key, s_parms));
+}
+
+gcry_error_t
+gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
+{
+ return gpg_error (_gcry_pk_ctl (cmd, buffer, buflen));
+}
+
+gcry_error_t
+gcry_pk_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_pk_algo_info (algo, what, buffer, nbytes));
+}
+
+const char *
+gcry_pk_algo_name (int algorithm)
+{
+ return _gcry_pk_algo_name (algorithm);
+}
+
+int
+gcry_pk_map_name (const char *name)
+{
+ return _gcry_pk_map_name (name);
+}
+
+unsigned int
+gcry_pk_get_nbits (gcry_sexp_t key)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return 0;
+ }
+
+ return _gcry_pk_get_nbits (key);
+}
+
+unsigned char *
+gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_keygrip (key, array);
+}
+
+const char *
+gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_curve (key, iterator, r_nbits);
+}
+
+gcry_sexp_t
+gcry_pk_get_param (int algo, const char *name)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_param (algo, name);
+}
+
+gcry_error_t
+gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
+{
+ if (!fips_is_operational ())
+ {
+ *r_sexp = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return gpg_error (_gcry_pubkey_get_sexp (r_sexp, mode, ctx));
+}
+
+unsigned int
+gcry_ecc_get_algo_keylen (int curveid)
+{
+ return _gcry_ecc_get_algo_keylen (curveid);
+}
+
+gpg_error_t
+gcry_ecc_mul_point (int curveid, unsigned char *result,
+ const unsigned char *scalar, const unsigned char *point)
+{
+ return _gcry_ecc_mul_point (curveid, result, scalar, point);
+}
+
+gcry_error_t
+gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
+{
+ if (!fips_is_operational ())
+ {
+ *h = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+
+ return gpg_error (_gcry_md_open (h, algo, flags));
+}
+
+void
+gcry_md_close (gcry_md_hd_t hd)
+{
+ _gcry_md_close (hd);
+}
+
+gcry_error_t
+gcry_md_enable (gcry_md_hd_t hd, int algo)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_md_enable (hd, algo));
+}
+
+gcry_error_t
+gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd)
+{
+ if (!fips_is_operational ())
+ {
+ *bhd = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return gpg_error (_gcry_md_copy (bhd, ahd));
+}
+
+void
+gcry_md_reset (gcry_md_hd_t hd)
+{
+ _gcry_md_reset (hd);
+}
+
+gcry_error_t
+gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_md_ctl (hd, cmd, buffer, buflen));
+}
+
+void
+gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return;
+ }
+ _gcry_md_write (hd, buffer, length);
+}
+
+unsigned char *
+gcry_md_read (gcry_md_hd_t hd, int algo)
+{
+ return _gcry_md_read (hd, algo);
+}
+
+gcry_error_t
+gcry_md_extract (gcry_md_hd_t hd, int algo, void *buffer, size_t length)
+{
+ return gpg_error (_gcry_md_extract(hd, algo, buffer, length));
+}
+
+void
+gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_error ("called in non-operational state");
+ }
+ _gcry_md_hash_buffer (algo, digest, buffer, length);
+}
+
+gpg_error_t
+gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
+ const gcry_buffer_t *iov, int iovcnt)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_error ("called in non-operational state");
+ }
+ return gpg_error (_gcry_md_hash_buffers (algo, flags, digest, iov, iovcnt));
+}
+
+int
+gcry_md_get_algo (gcry_md_hd_t hd)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_error ("used in non-operational state");
+ return 0;
+ }
+ return _gcry_md_get_algo (hd);
+}
+
+unsigned int
+gcry_md_get_algo_dlen (int algo)
+{
+ return _gcry_md_get_algo_dlen (algo);
+}
+
+int
+gcry_md_is_enabled (gcry_md_hd_t a, int algo)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return 0;
+ }
+
+ return _gcry_md_is_enabled (a, algo);
+}
+
+int
+gcry_md_is_secure (gcry_md_hd_t a)
+{
+ return _gcry_md_is_secure (a);
+}
+
+gcry_error_t
+gcry_md_info (gcry_md_hd_t h, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return gpg_error (_gcry_md_info (h, what, buffer, nbytes));
+}
+
+gcry_error_t
+gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ return gpg_error (_gcry_md_algo_info (algo, what, buffer, nbytes));
+}
+
+const char *
+gcry_md_algo_name (int algo)
+{
+ return _gcry_md_algo_name (algo);
+}
+
+int
+gcry_md_map_name (const char* name)
+{
+ return _gcry_md_map_name (name);
+}
+
+gcry_error_t
+gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_md_setkey (hd, key, keylen));
+}
+
+void
+gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
+{
+ _gcry_md_debug (hd, suffix);
+}
+
+gpg_error_t
+gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo,
+ salt, saltlen, iterations,
+ keysize, keybuffer));
+}
+
+void
+gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+ _gcry_randomize (buffer, length, level);
+}
+
+gcry_error_t
+gcry_random_add_bytes (const void *buffer, size_t length, int quality)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_random_add_bytes (buffer, length, quality));
+}
+
+void *
+gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+
+ return _gcry_random_bytes (nbytes,level);
+}
+
+void *
+gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+
+ return _gcry_random_bytes_secure (nbytes, level);
+}
+
+void
+gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+
+ _gcry_mpi_randomize (w, nbits, level);
+}
+
+void
+gcry_create_nonce (void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+ _gcry_create_nonce (buffer, length);
+}
+
+gcry_error_t
+gcry_prime_generate (gcry_mpi_t *prime,
+ unsigned int prime_bits,
+ unsigned int factor_bits,
+ gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func,
+ void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits,
+ factors, cb_func, cb_arg,
+ random_level, flags));
+}
+
+gcry_error_t
+gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime, gcry_mpi_t *factors,
+ gcry_mpi_t start_g)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return gpg_error (_gcry_prime_group_generator (r_g, prime, factors, start_g));
+}
+
+void
+gcry_prime_release_factors (gcry_mpi_t *factors)
+{
+ _gcry_prime_release_factors (factors);
+}
+
+gcry_error_t
+gcry_prime_check (gcry_mpi_t x, unsigned int flags)
+{
+ return gpg_error (_gcry_prime_check (x, flags));
+}
+
+void
+gcry_ctx_release (gcry_ctx_t ctx)
+{
+ _gcry_ctx_release (ctx);
+}
+
+void
+gcry_log_debug (const char *fmt, ...)
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv (GCRY_LOG_DEBUG, fmt, arg_ptr);
+ va_end (arg_ptr);
+}
+
+void
+gcry_log_debughex (const char *text, const void *buffer, size_t length)
+{
+ _gcry_log_printhex (text, buffer, length);
+}
+
+void
+gcry_log_debugmpi (const char *text, gcry_mpi_t mpi)
+{
+ _gcry_log_printmpi (text, mpi);
+}
+
+void
+gcry_log_debugpnt (const char *text, mpi_point_t point, gcry_ctx_t ctx)
+{
+ mpi_ec_t ec = ctx? _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC) : NULL;
+
+ _gcry_mpi_point_log (text, point, ec);
+}
+
+void
+gcry_log_debugsxp (const char *text, gcry_sexp_t sexp)
+{
+ _gcry_log_printsxp (text, sexp);
+}
+
+char *
+gcry_get_config (int mode, const char *what)
+{
+ return _gcry_get_config (mode, what);
+}
+
+void
+gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data)
+{
+ _gcry_set_progress_handler (cb, cb_data);
+}
+
+void
+gcry_set_allocation_handler (gcry_handler_alloc_t func_alloc,
+ gcry_handler_alloc_t func_alloc_secure,
+ gcry_handler_secure_check_t func_secure_check,
+ gcry_handler_realloc_t func_realloc,
+ gcry_handler_free_t func_free)
+{
+ _gcry_set_allocation_handler (func_alloc, func_alloc_secure,
+ func_secure_check, func_realloc, func_free);
+}
+
+void
+gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque)
+{
+ _gcry_set_outofcore_handler (h, opaque);
+}
+
+void
+gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque)
+{
+ _gcry_set_fatalerror_handler (fnc, opaque);
+}
+
+void
+gcry_set_log_handler (gcry_handler_log_t f, void *opaque)
+{
+ _gcry_set_log_handler (f, opaque);
+}
+
+void
+gcry_set_gettext_handler (const char *(*f)(const char*))
+{
+ _gcry_set_gettext_handler (f);
+}
+
+void *
+gcry_malloc (size_t n)
+{
+ return _gcry_malloc (n);
+}
+
+void *
+gcry_calloc (size_t n, size_t m)
+{
+ return _gcry_calloc (n, m);
+}
+
+void *
+gcry_malloc_secure (size_t n)
+{
+ return _gcry_malloc_secure (n);
+}
+
+void *
+gcry_calloc_secure (size_t n, size_t m)
+{
+ return _gcry_calloc_secure (n,m);
+}
+
+void *
+gcry_realloc (void *a, size_t n)
+{
+ return _gcry_realloc (a, n);
+}
+
+char *
+gcry_strdup (const char *string)
+{
+ return _gcry_strdup (string);
+}
+
+void *
+gcry_xmalloc (size_t n)
+{
+ return _gcry_xmalloc (n);
+}
+
+void *
+gcry_xcalloc (size_t n, size_t m)
+{
+ return _gcry_xcalloc (n, m);
+}
+
+void *
+gcry_xmalloc_secure (size_t n)
+{
+ return _gcry_xmalloc_secure (n);
+}
+
+void *
+gcry_xcalloc_secure (size_t n, size_t m)
+{
+ return _gcry_xcalloc_secure (n, m);
+}
+
+void *
+gcry_xrealloc (void *a, size_t n)
+{
+ return _gcry_xrealloc (a, n);
+}
+
+char *
+gcry_xstrdup (const char *a)
+{
+ return _gcry_xstrdup (a);
+}
+
+void
+gcry_free (void *a)
+{
+ _gcry_free (a);
+}
+
+int
+gcry_is_secure (const void *a)
+{
+ return _gcry_is_secure (a);
+}
diff --git a/comm/third_party/libgcrypt/src/visibility.h b/comm/third_party/libgcrypt/src/visibility.h
new file mode 100644
index 0000000000..b7e8369a39
--- /dev/null
+++ b/comm/third_party/libgcrypt/src/visibility.h
@@ -0,0 +1,521 @@
+/* visibility.h - Set visibility attribute
+ * 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 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_VISIBILITY_H
+#define GCRY_VISIBILITY_H
+
+/* Redefine all public symbols with an underscore unless we already
+ use the underscore prefixed version internally. */
+
+
+/* Include the main header here so that public symbols are mapped to
+ the internal underscored ones. */
+#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C
+ /* We need to redeclare the deprecated functions without the
+ deprecated attribute. */
+# define GCRYPT_NO_DEPRECATED
+# include "gcrypt-int.h"
+ /* None in this version. */
+#else
+# include "gcrypt-int.h"
+#endif
+
+/* Prototypes of functions exported but not ready for use. */
+gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
+ unsigned char *buffer, int buflen);
+
+
+/* Our use of the ELF visibility feature works by passing
+ -fvisibiliy=hidden on the command line and by explicitly marking
+ all exported functions as visible.
+
+ NOTE: When adding new functions, please make sure to add them to
+ libgcrypt.vers and libgcrypt.def as well. */
+
+#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C
+
+/* A macro to flag a function as visible. */
+#ifdef GCRY_USE_VISIBILITY
+# define MARK_VISIBLEX(name) \
+ extern __typeof__ (name) name __attribute__ ((visibility("default")));
+#else
+# define MARK_VISIBLEX(name) /* */
+#endif
+
+
+/* Now mark all symbols. */
+
+MARK_VISIBLEX (gcry_check_version)
+MARK_VISIBLEX (gcry_control)
+
+MARK_VISIBLEX (gcry_set_allocation_handler)
+MARK_VISIBLEX (gcry_set_fatalerror_handler)
+MARK_VISIBLEX (gcry_set_gettext_handler)
+MARK_VISIBLEX (gcry_set_log_handler)
+MARK_VISIBLEX (gcry_set_outofcore_handler)
+MARK_VISIBLEX (gcry_set_progress_handler)
+
+MARK_VISIBLEX (gcry_err_code_from_errno)
+MARK_VISIBLEX (gcry_err_code_to_errno)
+MARK_VISIBLEX (gcry_err_make_from_errno)
+MARK_VISIBLEX (gcry_error_from_errno)
+MARK_VISIBLEX (gcry_strerror)
+MARK_VISIBLEX (gcry_strsource)
+
+MARK_VISIBLEX (gcry_malloc)
+MARK_VISIBLEX (gcry_malloc_secure)
+MARK_VISIBLEX (gcry_calloc)
+MARK_VISIBLEX (gcry_calloc_secure)
+MARK_VISIBLEX (gcry_realloc)
+MARK_VISIBLEX (gcry_strdup)
+MARK_VISIBLEX (gcry_is_secure)
+MARK_VISIBLEX (gcry_xcalloc)
+MARK_VISIBLEX (gcry_xcalloc_secure)
+MARK_VISIBLEX (gcry_xmalloc)
+MARK_VISIBLEX (gcry_xmalloc_secure)
+MARK_VISIBLEX (gcry_xrealloc)
+MARK_VISIBLEX (gcry_xstrdup)
+MARK_VISIBLEX (gcry_free)
+
+MARK_VISIBLEX (gcry_md_algo_info)
+MARK_VISIBLEX (gcry_md_algo_name)
+MARK_VISIBLEX (gcry_md_close)
+MARK_VISIBLEX (gcry_md_copy)
+MARK_VISIBLEX (gcry_md_ctl)
+MARK_VISIBLEX (gcry_md_enable)
+MARK_VISIBLEX (gcry_md_get)
+MARK_VISIBLEX (gcry_md_get_algo)
+MARK_VISIBLEX (gcry_md_get_algo_dlen)
+MARK_VISIBLEX (gcry_md_hash_buffer)
+MARK_VISIBLEX (gcry_md_hash_buffers)
+MARK_VISIBLEX (gcry_md_info)
+MARK_VISIBLEX (gcry_md_is_enabled)
+MARK_VISIBLEX (gcry_md_is_secure)
+MARK_VISIBLEX (gcry_md_map_name)
+MARK_VISIBLEX (gcry_md_open)
+MARK_VISIBLEX (gcry_md_read)
+MARK_VISIBLEX (gcry_md_extract)
+MARK_VISIBLEX (gcry_md_reset)
+MARK_VISIBLEX (gcry_md_setkey)
+MARK_VISIBLEX (gcry_md_write)
+MARK_VISIBLEX (gcry_md_debug)
+
+MARK_VISIBLEX (gcry_cipher_algo_info)
+MARK_VISIBLEX (gcry_cipher_algo_name)
+MARK_VISIBLEX (gcry_cipher_close)
+MARK_VISIBLEX (gcry_cipher_setkey)
+MARK_VISIBLEX (gcry_cipher_setiv)
+MARK_VISIBLEX (gcry_cipher_setctr)
+MARK_VISIBLEX (gcry_cipher_authenticate)
+MARK_VISIBLEX (gcry_cipher_checktag)
+MARK_VISIBLEX (gcry_cipher_gettag)
+MARK_VISIBLEX (gcry_cipher_ctl)
+MARK_VISIBLEX (gcry_cipher_decrypt)
+MARK_VISIBLEX (gcry_cipher_encrypt)
+MARK_VISIBLEX (gcry_cipher_get_algo_blklen)
+MARK_VISIBLEX (gcry_cipher_get_algo_keylen)
+MARK_VISIBLEX (gcry_cipher_info)
+MARK_VISIBLEX (gcry_cipher_map_name)
+MARK_VISIBLEX (gcry_cipher_mode_from_oid)
+MARK_VISIBLEX (gcry_cipher_open)
+
+MARK_VISIBLEX (gcry_mac_algo_info)
+MARK_VISIBLEX (gcry_mac_algo_name)
+MARK_VISIBLEX (gcry_mac_map_name)
+MARK_VISIBLEX (gcry_mac_get_algo)
+MARK_VISIBLEX (gcry_mac_get_algo_maclen)
+MARK_VISIBLEX (gcry_mac_get_algo_keylen)
+MARK_VISIBLEX (gcry_mac_open)
+MARK_VISIBLEX (gcry_mac_close)
+MARK_VISIBLEX (gcry_mac_setkey)
+MARK_VISIBLEX (gcry_mac_setiv)
+MARK_VISIBLEX (gcry_mac_write)
+MARK_VISIBLEX (gcry_mac_read)
+MARK_VISIBLEX (gcry_mac_verify)
+MARK_VISIBLEX (gcry_mac_ctl)
+
+MARK_VISIBLEX (gcry_pk_algo_info)
+MARK_VISIBLEX (gcry_pk_algo_name)
+MARK_VISIBLEX (gcry_pk_ctl)
+MARK_VISIBLEX (gcry_pk_decrypt)
+MARK_VISIBLEX (gcry_pk_encrypt)
+MARK_VISIBLEX (gcry_pk_genkey)
+MARK_VISIBLEX (gcry_pk_get_keygrip)
+MARK_VISIBLEX (gcry_pk_get_curve)
+MARK_VISIBLEX (gcry_pk_get_param)
+MARK_VISIBLEX (gcry_pk_get_nbits)
+MARK_VISIBLEX (gcry_pk_map_name)
+MARK_VISIBLEX (gcry_pk_sign)
+MARK_VISIBLEX (gcry_pk_testkey)
+MARK_VISIBLEX (gcry_pk_verify)
+MARK_VISIBLEX (gcry_pubkey_get_sexp)
+MARK_VISIBLEX (gcry_ecc_get_algo_keylen)
+MARK_VISIBLEX (gcry_ecc_mul_point)
+
+MARK_VISIBLEX (gcry_kdf_derive)
+
+MARK_VISIBLEX (gcry_prime_check)
+MARK_VISIBLEX (gcry_prime_generate)
+MARK_VISIBLEX (gcry_prime_group_generator)
+MARK_VISIBLEX (gcry_prime_release_factors)
+
+MARK_VISIBLEX (gcry_random_add_bytes)
+MARK_VISIBLEX (gcry_random_bytes)
+MARK_VISIBLEX (gcry_random_bytes_secure)
+MARK_VISIBLEX (gcry_randomize)
+MARK_VISIBLEX (gcry_create_nonce)
+
+MARK_VISIBLEX (gcry_sexp_alist)
+MARK_VISIBLEX (gcry_sexp_append)
+MARK_VISIBLEX (gcry_sexp_build)
+MARK_VISIBLEX (gcry_sexp_build_array)
+MARK_VISIBLEX (gcry_sexp_cadr)
+MARK_VISIBLEX (gcry_sexp_canon_len)
+MARK_VISIBLEX (gcry_sexp_car)
+MARK_VISIBLEX (gcry_sexp_cdr)
+MARK_VISIBLEX (gcry_sexp_cons)
+MARK_VISIBLEX (gcry_sexp_create)
+MARK_VISIBLEX (gcry_sexp_dump)
+MARK_VISIBLEX (gcry_sexp_find_token)
+MARK_VISIBLEX (gcry_sexp_length)
+MARK_VISIBLEX (gcry_sexp_new)
+MARK_VISIBLEX (gcry_sexp_nth)
+MARK_VISIBLEX (gcry_sexp_nth_buffer)
+MARK_VISIBLEX (gcry_sexp_nth_data)
+MARK_VISIBLEX (gcry_sexp_nth_mpi)
+MARK_VISIBLEX (gcry_sexp_nth_string)
+MARK_VISIBLEX (gcry_sexp_prepend)
+MARK_VISIBLEX (gcry_sexp_release)
+MARK_VISIBLEX (gcry_sexp_sprint)
+MARK_VISIBLEX (gcry_sexp_sscan)
+MARK_VISIBLEX (gcry_sexp_vlist)
+MARK_VISIBLEX (gcry_sexp_extract_param)
+
+MARK_VISIBLEX (gcry_mpi_abs)
+MARK_VISIBLEX (gcry_mpi_add)
+MARK_VISIBLEX (gcry_mpi_add_ui)
+MARK_VISIBLEX (gcry_mpi_addm)
+MARK_VISIBLEX (gcry_mpi_aprint)
+MARK_VISIBLEX (gcry_mpi_clear_bit)
+MARK_VISIBLEX (gcry_mpi_clear_flag)
+MARK_VISIBLEX (gcry_mpi_clear_highbit)
+MARK_VISIBLEX (gcry_mpi_cmp)
+MARK_VISIBLEX (gcry_mpi_cmp_ui)
+MARK_VISIBLEX (gcry_mpi_copy)
+MARK_VISIBLEX (gcry_mpi_div)
+MARK_VISIBLEX (gcry_mpi_dump)
+MARK_VISIBLEX (gcry_mpi_ec_add)
+MARK_VISIBLEX (gcry_mpi_ec_sub)
+MARK_VISIBLEX (gcry_mpi_ec_curve_point)
+MARK_VISIBLEX (gcry_mpi_ec_dup)
+MARK_VISIBLEX (gcry_mpi_ec_decode_point)
+MARK_VISIBLEX (gcry_mpi_ec_get_affine)
+MARK_VISIBLEX (gcry_mpi_ec_mul)
+MARK_VISIBLEX (gcry_mpi_ec_new)
+MARK_VISIBLEX (gcry_mpi_ec_get_mpi)
+MARK_VISIBLEX (gcry_mpi_ec_get_point)
+MARK_VISIBLEX (gcry_mpi_ec_set_mpi)
+MARK_VISIBLEX (gcry_mpi_ec_set_point)
+MARK_VISIBLEX (gcry_mpi_gcd)
+MARK_VISIBLEX (gcry_mpi_get_flag)
+MARK_VISIBLEX (gcry_mpi_get_nbits)
+MARK_VISIBLEX (gcry_mpi_get_opaque)
+MARK_VISIBLEX (gcry_mpi_is_neg)
+MARK_VISIBLEX (gcry_mpi_invm)
+MARK_VISIBLEX (gcry_mpi_mod)
+MARK_VISIBLEX (gcry_mpi_mul)
+MARK_VISIBLEX (gcry_mpi_mul_2exp)
+MARK_VISIBLEX (gcry_mpi_mul_ui)
+MARK_VISIBLEX (gcry_mpi_mulm)
+MARK_VISIBLEX (gcry_mpi_neg)
+MARK_VISIBLEX (gcry_mpi_new)
+MARK_VISIBLEX (gcry_mpi_point_get)
+MARK_VISIBLEX (gcry_mpi_point_new)
+MARK_VISIBLEX (gcry_mpi_point_release)
+MARK_VISIBLEX (gcry_mpi_point_copy)
+MARK_VISIBLEX (gcry_mpi_point_set)
+MARK_VISIBLEX (gcry_mpi_point_snatch_get)
+MARK_VISIBLEX (gcry_mpi_point_snatch_set)
+MARK_VISIBLEX (gcry_mpi_powm)
+MARK_VISIBLEX (gcry_mpi_print)
+MARK_VISIBLEX (gcry_mpi_randomize)
+MARK_VISIBLEX (gcry_mpi_release)
+MARK_VISIBLEX (gcry_mpi_rshift)
+MARK_VISIBLEX (gcry_mpi_lshift)
+MARK_VISIBLEX (gcry_mpi_scan)
+MARK_VISIBLEX (gcry_mpi_snatch)
+MARK_VISIBLEX (gcry_mpi_set)
+MARK_VISIBLEX (gcry_mpi_set_bit)
+MARK_VISIBLEX (gcry_mpi_set_flag)
+MARK_VISIBLEX (gcry_mpi_set_highbit)
+MARK_VISIBLEX (gcry_mpi_set_opaque)
+MARK_VISIBLEX (gcry_mpi_set_opaque_copy)
+MARK_VISIBLEX (gcry_mpi_set_ui)
+MARK_VISIBLEX (gcry_mpi_get_ui)
+MARK_VISIBLEX (gcry_mpi_snew)
+MARK_VISIBLEX (gcry_mpi_sub)
+MARK_VISIBLEX (gcry_mpi_sub_ui)
+MARK_VISIBLEX (gcry_mpi_subm)
+MARK_VISIBLEX (gcry_mpi_swap)
+MARK_VISIBLEX (gcry_mpi_test_bit)
+
+MARK_VISIBLEX (gcry_ctx_release)
+
+MARK_VISIBLEX (gcry_log_debug)
+MARK_VISIBLEX (gcry_log_debughex)
+MARK_VISIBLEX (gcry_log_debugmpi)
+MARK_VISIBLEX (gcry_log_debugpnt)
+MARK_VISIBLEX (gcry_log_debugsxp)
+
+MARK_VISIBLEX (gcry_get_config)
+
+/* Functions used to implement macros. */
+MARK_VISIBLEX (_gcry_mpi_get_const)
+
+
+#undef MARK_VISIBLEX
+
+#else /*!_GCRY_INCLUDED_BY_VISIBILITY_C*/
+
+/* To avoid accidental use of the public functions inside Libgcrypt,
+ we redefine them to catch such errors. The usual difference
+ between a public and an internal version is that the internal
+ version use gpg_err_code_t and the public version gpg_error_t. */
+
+#define gcry_check_version _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_control _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_set_allocation_handler _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_fatalerror_handler _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_gettext_handler _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_log_handler _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_outofcore_handler _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_progress_handler _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_err_code_from_errno _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_err_code_to_errno _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_err_make_from_errno _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_error_from_errno _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_strerror _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_strsource _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_malloc _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_malloc_secure _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_calloc _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_calloc_secure _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_realloc _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_strdup _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xcalloc _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xcalloc_secure _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xmalloc _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xmalloc_secure _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xrealloc _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xstrdup _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_free _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_is_secure _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_cipher_open _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_close _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_setkey _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_setiv _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_setctr _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_algo_info _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_algo_name _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_authenticate _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_checktag _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_gettag _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_ctl _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_decrypt _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_encrypt _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_get_algo_blklen _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_get_algo_keylen _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_info _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_map_name _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_mode_from_oid _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_pk_algo_info _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_algo_name _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_ctl _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_decrypt _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_encrypt _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_genkey _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_get_keygrip _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_get_curve _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_get_param _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_get_nbits _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_map_name _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_sign _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_testkey _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_verify _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pubkey_get_sexp _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_ecc_get_algo_keylen _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_ecc_mul_point _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_md_algo_info _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_algo_name _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_close _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_copy _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_ctl _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_enable _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_get _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_get_algo _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_get_algo_dlen _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_hash_buffer _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_hash_buffers _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_info _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_is_enabled _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_is_secure _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_map_name _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_open _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_read _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_extract _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_reset _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_setkey _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_write _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_debug _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_mac_algo_info _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_algo_name _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_map_name _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_get_algo _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_get_algo_maclen _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_get_algo_keylen _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_open _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_close _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_setkey _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_setiv _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_write _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_read _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_verify _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_ctl _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_kdf_derive _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_prime_check _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_prime_generate _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_prime_group_generator _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_prime_release_factors _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_random_add_bytes _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_random_bytes _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_random_bytes_secure _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_randomize _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_create_nonce _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_ctx_release _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_sexp_alist _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_append _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_build _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_build_array _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_cadr _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_canon_len _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_car _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_cdr _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_cons _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_create _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_dump _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_find_token _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_length _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_new _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth_buffer _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth_data _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth_mpi _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth_string _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_prepend _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_release _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_sprint _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_sscan _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_vlist _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_extract_param _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_mpi_add _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_add_ui _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_addm _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_aprint _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_clear_bit _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_clear_flag _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_clear_highbit _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_cmp _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_cmp_ui _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_copy _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_div _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_dump _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_gcd _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_get_flag _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_get_nbits _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_get_opaque _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_invm _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mod _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mul _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mul_2exp _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mul_ui _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mulm _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_new _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_get _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_new _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_release _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_copy _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_set _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_snatch_get _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_snatch_set _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_powm _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_print _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_randomize _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_release _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_rshift _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_lshift _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_scan _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_bit _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_flag _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_highbit _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_opaque _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_ui _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_get_ui _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_snatch _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_snew _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_sub _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_sub_ui _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_subm _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_swap _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_test_bit _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_mpi_abs _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_add _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_sub _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_curve_point _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_dup _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_decode_point _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_get_affine _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_get_mpi _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_get_point _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_mul _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_new _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_set_mpi _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_set_point _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_is_neg _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_neg _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_opaque_copy _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+
+#endif /*!_GCRY_INCLUDED_BY_VISIBILITY_C*/
+
+#endif /*GCRY_VISIBILITY_H*/
diff --git a/comm/third_party/libgcrypt/tests/ChangeLog-2011 b/comm/third_party/libgcrypt/tests/ChangeLog-2011
new file mode 100644
index 0000000000..a9fb1cafce
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/ChangeLog-2011
@@ -0,0 +1,944 @@
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-11-11 Jim Meyering <meyering@redhat.com>
+
+ tests: avoid write-beyond-end-of-heap buffer
+ * basic.c (check_bulk_cipher_modes): Allocate one more byte in
+ each of the two test buffers. Otherwise, running
+ "env -i MALLOC_CHECK_=3 ./basic" would abort.
+
+2011-09-15 Werner Koch <wk@g10code.com>
+
+ * register.c: Remove.
+
+ * ac-data.c, ac-schemes.c, ac.c: Remove.
+
+2011-06-13 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_pubkey_sign): Run PKCS1 tests only for RSA.
+ (check_pubkey_crypt): Ditto.
+
+ * pkcs1v2-pss.h, pkcs1v2-oaep.h, pkcs1v2-v15s.h, pkcs1v2-v15c.h: New.
+ * pkcs1v2.c: (check_pss, check_v15crypt): New.
+ (check_pss, check_pss): Factor test vector tables out.
+
+2011-06-10 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_pubkey_crypt): Run OAEP tests only for RSA.
+
+2011-06-09 Werner Koch <wk@g10code.com>
+
+ * pkcs1v2.c: New.
+ * Makefile.am (TESTS): Add pkcs1v2.
+
+ * basic.c (check_pubkey_sign): Add a test using random-override.
+ (check_pubkey_crypt): Ditto. Print ALGO in verbose mode.
+ (check_pubkey_grip): Silence unused parameter warning.
+
+2011-06-03 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): Add option --die.
+
+2011-05-27 Daiki Ueno <ueno@unixuser.org>
+
+ * basic.c (check_pubkey_crypt): Add test data with invalid padding.
+
+2011-05-24 Daiki Ueno <ueno@unixuser.org>
+
+ * basic.c (do_check_one_pubkey): Add new arg ALGO to tell which PK
+ algorithm is used for check_pubkey_sign, check_pubkey_crypt,
+ check_pubkey_grip.
+ (check_pubkey_sign): Add new arg ALGO; skip test data if it does
+ not match ALGO.
+ (check_pubkey_crypt): Add new arg ALGO.
+ (check_pubkey_grip): Ditto.
+
+2011-05-18 Daiki Ueno <ueno@unixuser.org>
+
+ * basic.c (check_pubkey_crypt): Remove unused "unpad" flag.
+
+2011-05-11 Daiki Ueno <ueno@unixuser.org>
+
+ * basic.c (check_pubkey_sign): Add an OAEP flag parsing test case.
+ (check_pubkey_crypt): New.
+ (do_check_one_pubkey): Call it.
+ (check_one_pubkey): Free SKEY and PKEY.
+
+2011-04-11 Werner Koch <wk@g10code.com>
+
+ * basic.c (mismatch): New.
+ (check_ctr_cipher): Remove length error code checks. Add
+ truncation and streaming checks.
+
+2011-04-04 Werner Koch <wk@g10code.com>
+
+ * keygrip.c (main): Add option --repetitions.
+ (check): Make use of it.
+
+2011-03-28 Werner Koch <wk@g10code.com>
+
+ * random.c (readn): Remove used var P.
+
+2011-02-21 Werner Koch <wk@g10code.com>
+
+ * version.c (main): Do a verbatim check of the version string.
+ * basic.c (main): Ditto. But die on mismatch.
+
+ * benchmark.c (md_bench): Allow for the --alignment option.
+ (main): Allow alignments between 1 and 16.
+
+2011-02-16 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Add option --disable-hwf.
+
+ * basic.c (DIM): New.
+ (check_bulk_cipher_modes): New.
+ (main): Run new test.
+
+2011-02-15 Werner Koch <wk@g10code.com>
+
+ * benchmark.c: Add option --cipher-with-keysetup.
+ (cipher_bench): Implement this option.
+
+2011-02-14 Werner Koch <wk@g10code.com>
+
+ * benchmark.c: Add option --alignment.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * curves.c: New.
+
+2011-01-04 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (LDADD): Fix typo in last change. Reported by
+ Andrey Jivsov.
+
+2010-07-19 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (LDADD): Add GPG_ERROR_LIBS to help a new wannabe ld.
+
+2010-06-10 Werner Koch <wk@g10code.com>
+
+ * t-mpi-bit.c (mpi2bitstr_nlz): Handle case for LENGTH==0.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * basic.c (check_cbc_mac_cipher): Print more info.
+ (main): Factor some code out to ...
+ (check_cipher_modes): .. new.
+
+2010-04-06 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * aeswrap.c, hmac.c, basic.c: Typo fixes.
+
+2010-03-26 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_digests): Add tests for TIGER1 and TIGER2 from
+ the NESSIE project.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * benchmark.c [_GCRYPT_IN_LIBGCRYPT]: Include libcompat.h.
+ (start_timer, stop_timer) [__MINGW32CE__]: Use GetThreadTimes.
+ * Makefile.am (LDADD): Add libcompat.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_ctr_cipher): Add some return code checks.
+
+ * benchmark.c (cipher_bench): Merge Stream with ECB column.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * aeswrap.c: New.
+
+2009-07-09 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (progress_cb): New.
+ (main): Add option --progress.
+
+2009-06-08 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (cipher_bench): Center labels. Suggested by Brad Hards.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (print_buffer): Remove parens from initializer for
+ better portability. Reported by Dan Fandrich.
+
+2009-02-13 Werner Koch <wk@g10code.com>
+
+ * rsacvt.c (compute_missing): Fix dqm1 computation. Take care of
+ openpgp flag.
+ (main): Add option --openpgp.
+
+2009-02-11 Werner Koch <wk@g10code.com>
+
+ * rsacvt.c: New.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * cavs_tests.sh: Pass option -D to driver if required.
+
+ * fipsdrv.c (run_dsa_sign): Use hash of the data.
+ (dsa_gen_with_seed): New.
+ (run_dsa_pqg_gen): Add args SEED and SEEDLEN and use them.
+ (main): Optically take a seed for dsa-pgq-gen.
+ (standalone_mode): New.
+ (main): Add option --standalone.
+ (print_dsa_domain_parameters): Implement standalone mode.
+
+2009-01-21 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_dsa_verify): Use gcry_mpi_scan again.
+ (run_rsa_derive): Also print N.
+
+ * fipsdrv.c (run_dsa_verify): Use hash of the data.
+
+ * pubkey.c (get_dsa_key_fips186_with_seed_new): New.
+ (check_run): Call it.
+
+2008-12-11 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_rsa_derive): New.
+ (main): Add mode rsa-derive.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): Check for error after running self-test in
+ non-fips mode.
+
+ * pubkey.c (get_dsa_key_with_domain_new): New.
+ (get_dsa_key_fips186_with_domain_new): New.
+ (check_run): Call them.
+
+2008-12-08 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c [W32]: Include fcntl.h.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (get_dsa_key_new): Add arg transient_key.
+ (check_run): Use it.
+
+2008-12-03 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_dsa_pqg_gen): Facor code out into ..
+ (print_dsa_domain_parameters, dsa_gen): .. these two new functions.
+ (print_sexp, read_sexp_from_file): New.
+ (run_dsa_sign): New.
+ (run_dsa_verify): New.
+
+2008-12-02 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c: All standalone build.
+
+ * mpitests.c (mpi_powm): New.
+
+2008-11-28 Werner Koch <wk@g10code.com>
+
+ * fips186-dsa.c: New.
+
+ * fipsdrv.c (print_mpi_line, print_data_line): New.
+ (run_dsa_pqg_gen): New.
+ (usage): Add mode dsa-pqg-gen.
+
+2008-11-25 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (get_dsa_key_new): New.
+
+2008-11-24 Werner Koch <wk@g10code.com>
+
+ * tsexp.c (basic): Add test for format character S.
+
+ * pubkey.c (check_x931_derived_key): New.
+ (get_keys_x931_new): New.
+ (check_run): Check X9.31 generated RSA key.
+
+2008-11-07 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_cipher_mct_loop, get_current_iv): New.
+ (read_textline, read_hexline, skip_to_empty_line): New.
+ (main): New option --mct-server.
+ * cavs_driver.pl: Update from upstream and adjust to new fipsdrv.
+
+2008-11-05 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_encrypt_decrypt): Disable weak key detection.
+
+2008-10-31 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_rsa_sign): Buffer needs to be larger for SHA512.
+
+2008-10-27 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_encrypt_decrypt): Make IV_BUFFER optional.
+ (main): Ditto.
+ * cavs_driver.pl: Remove the --no-fips flags.
+ (libgcrypt_encdec($$$$$)): Make IV optional.
+ (libgcrypt_state_cipher($$$$$)): Ditto.
+
+2008-10-24 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (md_bench): Do not test MD5 in fips mode.
+ * basic.c (check_digests, check_hmac): Ditto.
+
+2008-10-06 Werner Koch <wk@g10code.com>
+
+ * cavs_driver.pl: New version from upstream.
+ (libgcrypt_rsa_verify($$$$)): Pass pkcs1.
+ (libgcrypt_rsa_sign($$$)): Pass pkcs1 and hash algo.
+
+ * fipsdrv.c (run_rsa_sign): Hash data in pkcs1 mode.
+ (run_rsa_verify): Ditto.
+ (read_key_file): Rename to read_private_key_file. Factor public
+ key code out to..
+ (read_public_key_file): .. new.
+
+2008-10-02 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (print_buffer): Add base64 printing code.
+ (base64_decode, read_key_file, parse_tag, read_sig_file): New.
+ (run_rsa_gen, run_rsa_sign): New.
+ (main): Add modes rsa-gen, rsa-sign and rsa-verify.
+
+
+2008-09-29 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c: Merge code from fipsrngdrv.c
+ * fipsrngdrv.c: Remove.
+
+2008-09-26 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Distribute cavs_driver.pl.
+ * cavs_tests.sh: New.
+ * fipsdrv.c: New.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Do not disable secure memory in FIPS mode.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): Do not disable secure memory in FIPS mode.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * fipsrngdrv.c (main): Bail out on write error. Implement verbose
+ option.
+ (main): Use flag to disable dup block checks.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * fipsrngdrv.c: New.
+
+2008-09-09 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): New option --selftest.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * keygrip.c: Update to also check ECDSA.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * rsa-16k.key: New sample key.
+
+2008-08-27 Werner Koch <wk@g10code.com>
+
+ * pkbench.c (read_file): New.
+ (process_key_pair_file): Replace mmap by read_file.
+ (main): Add a --fips option.
+ * Makefile.am (EXTRA_DIST): Remove.
+ (EXTRA_PROGRAMS): Add pkbench.
+
+ * basic.c (main): Extended FIPS self-test test.
+
+2008-08-26 Werner Koch <wk@g10code.com>
+
+ * basic.c (get_keys_new): Use transient-key flag.
+ * benchmark.c (main): First check options then do the libgcrypt
+ initialization.
+ (rsa_bench): Use transient-key flag if not in fips mode.
+
+2008-08-20 Werner Koch <wk@g10code.com>
+
+ * t-mpi-bit.c (test_lshift): New.
+ (mpi2bitstr_nlz, lshiftbitstring): New.
+ (main): Run test.
+
+2008-08-18 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): Add option --fips.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * register.c (main): Check for fips mode.
+ (check_run): Take care of fips mode.
+
+ * basic.c (check_cbc_mac_cipher, check_ciphers, check_digests)
+ (check_hmac, check_pubkey): Do not test unavalaible algorithms in
+ fips mode.
+ (main): Check for fips mode.
+
+2008-04-22 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_one_cipher): Also check in-place encryption.
+
+2008-03-17 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Add option --cipher-repetition.
+ (cipher_bench): Use it.
+
+2008-03-12 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (rsa_bench): Add arg NO_BLINDING.
+ (main): Add option --no-blinding.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sample_private_key_1_1,sample_private_key_1_2): New.
+ (get_keys_sample): Add arg SECRET_VARIANT.
+ (check_run): Check all variants. Also check gcry_pk_testkey.
+ (check_keys_crypt): Add DECRYPT_FAIL_CODE.
+ (check_keys): Ditto.
+
+2007-11-30 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Add optione --verbose and reworked the
+ option parsing.
+ (random_bench): Dump random stats.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (start_timer, stop_timer, elapsed_time) [W32]: Fixed.
+
+2007-06-20 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (rsa_bench): New.
+ (main): New command "rsa".
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (EXTRA_DIST): Do not build pkbench.c
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * basic.c (check_ciphers): Add Camellia.
+
+2007-04-30 David Shaw <dshaw@jabberwocky.com>
+
+ * basic.c (check_ciphers): #if out ciphers we don't have. Add
+ test for GCRY_CIPHER_RFC2268_40.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * version.c: New.
+ * Makefile.am (TESTS): Add version.
+
+2007-04-30 Marcus Brinkmann <marcus@g10code.de>
+
+ * benchmark.c (ecc_bench): Release KEY_SPEC.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac-data.c (check_run): Don't give redundant GCRY_AC_FLAG_DEALLOC
+ in addition to GCRY_AC_FLAG_COPY. Don't release LABEL1 or MPI0,
+ as those are donated to libgcrypt, but do release MPI0 and MPI2.
+
+2007-04-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac-schemes.c (scheme_spec): Revert last change.
+
+ * ac-schemes.c (scheme_spec): Remove const qualifier from member M.
+ (es_check): Remove const qualifier from C and M2.
+
+2007-03-28 Werner Koch <wk@g10code.com>
+
+ * pkbench.c (generate_key): Support named curves.
+
+ * benchmark.c (dsa_bench): New args ITERATIONS and PRINT_HEADER.
+ (main): Call dsa and ecc benchs.
+ (show_sexp): New.
+
+ * Makefile.am (TESTS): Move pkbench to EXTRA_PROGRAMS.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (die): New.
+ (ecc_bench): New.
+
+ * pkbench.c (main): Reworked to provide proper option handling.
+
+2007-03-13 Werner Koch <wk@g10code.com>
+
+ * mpitests.c: Reformatted to GNU standards.
+ (main): Add options --verbose and --debug for future use.
+
+2007-03-13 Werner Dittmann <Werner.Dittmann@t-online.de> (wk)
+
+ * mpitests.c: New.
+
+2007-02-23 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (TEST): Run benchmark as last.
+
+ * ac-data.c (check_sexp_conversion): Print label only in verbose
+ mode.
+
+ * pubkey.c (main): Run test just 2 times instead of 10.
+ (get_elg_key_new): New.
+ (check_run): Also run tests with Elgamal keys.
+ (check_keys): New arg NBITS_DATA.
+ (get_elg_key_new): Use only 400 for the 512 bit Elgamal test.
+
+ * random.c: New.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_pubkey_sign): Also try signing using an OID.
+
+ * Makefile.am (TESTS) [W32]: Removed pkbench for now.
+ * pkbench.c (benchmark): Fixed for W32.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * hmac.c (check_one_mac): Make pointer args const.
+ * basic.c (check_one_md): Ditto.
+ (check_one_hmac): Ditto.
+
+ * keygen.c (progress_cb): Filter out line feeds.
+ * basic.c (progress_handler): Ditto.
+
+2006-12-18 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (AM_CFLAGS, AM_CPPFLAGS): Splitted and merged with
+ Moritz' changes.
+ (INCLUDES): Removed.
+
+ * keygen.c (progress_handler): New.
+ (main): Use it in verbose mode.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
+ new gcrypt.h is used, not the one installed in the system.
+
+2006-10-17 Werner Koch <wk@g10code.com>
+
+ * keygen.c (check_rsa_keys): Also create an 1536 bit DSA key.
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * t-mpi-bit.c: New.
+
+2006-07-06 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): New option --use-random-daemon. New command
+ strongrandom.
+ (random_bench): New arg VERY_STRONG.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Allow for seed file argument to random bench.
+
+ * basic.c (main): Use progress handler only in verbose mode.
+ (main): Speed up test key generation.
+ * ac-data.c (check_sexp_conversion, check_run): Take care of VERBOSE.
+ * ac.c (main): Ditto.
+ * pubkey.c (main): Ditto.
+ * pkbench.c (main): Ditto.
+ * keygen.c (main): Ditto.
+ (check_rsa_keys): Print key only in verbose mode.
+
+2006-03-10 Brad Hards <bradh@frogmouth.net> (wk, patch 2006-02-18)
+
+ * basic.c (check_one_hmac, check_hmac): New.
+
+2006-03-07 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (cipher_bench): Add OFB mode.
+
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * basic.c: Added test cases for OFB and CFB modes. Fixed some
+ compiler warnings for signedness.
+
+2005-11-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac-data.c: Added way more test cases.
+
+2005-09-15 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added keygrip.
+ * keygrip.c: New.
+
+2005-09-19 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (dsa_bench): New.
+
+2005-08-19 Werner Koch <wk@g10code.com>
+
+ * hmac.c (main): Added all FIPS tests.
+
+2005-08-18 Werner Koch <wk@g10code.com>
+
+ * hmac.c: New.
+
+2005-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * tsexp.c: Include <config.h> in case HAVE_CONFIG_H is defined;
+ thanks to Albert Chin.
+ * testapi.c: Likewise.
+ * register.c: Likewise.
+ * pubkey.c: Likewise.
+ * prime.c: Likewise.
+ * pkbench.c: Likewise.
+ * keygen.c: Likewise.
+ * benchmark.c: Likewise.
+ * basic.c: Likewise.
+ * ac-schemes.c: Likewise.
+ * ac-data.c: Likewise.
+ * ac.c: Likewise.
+
+2005-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * ac-data.c (check_run): Include new test.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_digests): Add tests for Whirlpool.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * ac-schemes.c: New file.
+ * ac-data.c: New file.
+ * Makefile.am (TESTS): Added ac-schemes and ac-data.
+
+2004-09-15 Moritz Schulte <moritz@g10code.com>
+
+ * pkbench.c: Include <time.h>.
+
+2004-08-24 Moritz Schulte <moritz@g10code.com>
+
+ * pkbench.c (context_init): Improve generation of test data.
+
+2004-08-23 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added: pkbench.
+ * pkbench.c: New file.
+
+2004-02-25 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (TEST): Add benchmark.
+
+ * benchmark.c (md_bench, cipher_bench): Allow NULL arg to to run
+ tests for all algorithms.
+ (main): Run all tests by default.
+
+2004-02-03 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (basic): New pass to check secure memory switching.
+
+2004-01-12 Moritz Schulte <mo@g10code.com>
+
+ * ac.c (check_one): Adjust to new ac API.
+
+2003-11-22 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (check_keys_crypt): Fixed my last patch.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (basic): Add pass structure and a test for the %b
+ format.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (noinst_PROGRAMS): Use this so that test programs
+ get always build.
+
+ * keygen.c (check_nonce): New.
+ (main): Add a basic check for the nocen function.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_aes128_cbc_cts_cipher): Make it a prototype
+
+ * ac.c (check_run): Comment unused variable.
+
+2003-10-10 Werner Koch <wk@gnupg.org>
+
+ * prime.c (check_primes): Generate a generator and avoid printing
+ unless in verbose mode.
+
+2003-10-07 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (check_sscan): New.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (check_keys_crypt): Fix for compatibility mode.
+
+2003-09-02 Moritz Schulte <mo@g10code.com>
+
+ * Makefile.am (TESTS): Added: prime.
+
+ * prime.c: New file.
+
+2003-08-27 Moritz Schulte <mo@g10code.com>
+
+ * basic.c (check_ciphers): Added: Serpent.
+ Write braces around flags.
+
+2003-08-04 Moritz Schulte <moritz@g10code.com>
+
+ * benchmark.c (do_powm): Adjust for new gcry_mpi_scan interface.
+
+2003-07-23 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (key_copy): New function...
+ (check_one): ... use it.
+
+2003-07-22 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_ciphers): Use gcry_cipher_map_name.
+
+2003-07-18 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (check_run): Renamed to ...
+ (check_one): ... this, changed calling interface.
+ (check_run): New function.
+
+ * register.c: Adjust gcry_cipher_spec_t structure.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * register.c: Adjust cipher specification structure.
+
+ * benchmark.c: New file.
+ * testapi.c: New file.
+
+ * Makefile.am (EXTRA_PROGRAMS): Set to: benchmark testapi.
+ (check_PROGRAMS): Set to: $(TESTS).
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c, basic.c, keygen.c, register.c, sexp.c, tsexp.c: Used
+ gcry_err* wrappers for libgpg symbols.
+
+ * basic.c (check_ciphers): Added: GCRY_CIPHER_TWOFISH128.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (LIBS): Remove: -lpthread.
+
+ * basic.c (check_one_cipher): Fix variable initialization. Thanks
+ to Simon Joseffson <jas@extundo.com>.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added: register.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * register.c (check_run): Adjusted for new gcry_cipher_register API.
+
+2003-07-02 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added: ac.
+ * ac.c: New file.
+
+2003-06-18 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_cbc_mac_cipher): Adjusted for new API of get_blklen
+ and get_keylen.
+ (check_ctr_cipher): Ditto.
+ (check_one_cipher): Ditto.
+ (check_one_md): Adjusted for new API of gcry_md_copy.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * register.c: Replace old type GcryModule with newer one:
+ gcry_module_t.
+ Adjusted for new API.
+
+ * Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+
+2003-06-15 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (get_keys_new): New function.
+ (do_check_one_pubkey): New function ...
+ (check_one_pubkey): ... use it.
+ (progress_handler): New function.
+ (main): Use gcry_set_progress_handler.
+
+2003-06-14 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c: Replaced calls to gcry_strerror with calls to
+ gpg_strerror.
+ (check_one_md): Adjust for new gcry_md_copy API.
+
+ * tsexp.c: Likewise.
+ * keygen.c: Likewise.
+
+2003-06-12 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c: Changed here and there, reorganized pubkey checks,
+ added DSA and ELG keys.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c, keygen.c, pubkey.c, register.c, tsexp.c: Changed to use
+ new API.
+
+2003-06-01 Moritz Schulte <moritz@g10code.com>
+
+ * tsexp.c (canon_len): Adjust for new gcry_sexp_canon_len API.
+
+2003-05-26 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (verify_one_signature): Adjust for libgpg-error.
+ (check_pubkey_sign): Likewise.
+ (check_pubkey): Likewise.
+ * basic.c (check_pubkey_sign): Likewise.
+ * tsexp.c (canon_len): Likewise.
+ (back_and_forth_one): Likewise.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c: Changed the sample private key to contain the
+ identifier `openpgp-rsa' instead of `rsa'.
+
+ * basic.c (check_digests): Enabled/fixed some tests for TIGER.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Removed `register' for now.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_digests): Include checks for SHA512 and SHA384.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_one_md): Also test md_copy.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added register.
+
+ * register.c: New file.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * basic.c (check_one_cipher): New. Test CTR.
+ (main): Call it.
+ (check_ciphers): Check CTR mode.
+
+2003-03-26 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added pubkey.
+
+ * pubkey.c: New file.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * basic.c (check_cbc_mac_cipher): New.
+ (main): Use it.
+
+2003-03-19 Werner Koch <wk@gnupg.org>
+
+ * keygen.c (check_rsa_keys): Don't expect an exponent when asking
+ for e=0.
+ (check_generated_rsa_key): Just print exponent if EXPECTED_E is 0.
+
+2003-03-02 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_one_cipher): Use gcry_cipher_reset() instead of
+ gcry_cipher_close(), gcry_cipher_open and gcry_cipher_setkey().
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * keygen.c: New.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * basic.c (check_digests): Add CRC.
+ (check_one_md): Print computed and expected values on error.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_one_md): Kludge to check a one million "a".
+ (check_digests): Add checks for SHA-256.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_pubkey): Check the keygrip for the sample key.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * basic.c (verify_one_signature,check_pubkey_sign)
+ (check_pubkey): New.
+ (main): Check public key functions. Add a --debug option.
+
+2002-11-23 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_digests): Add another test for MD4. By Simon
+ Josefsson.
+
+2002-11-10 Simon Josefsson <jas@extundo.com>
+
+ * basic.c (check_aes128_cbc_cts_cipher): New function.
+ (check_one_cipher): Add flags parameter.
+ (check_ciphers): Support flags parameter.
+ (main): Check CTS.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_one_md): New. By Simon Josefsson.
+ (check_digests): New tests for MD4. By Simon.
+
+2002-08-26 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_ciphers): Check simple DES.
+
+2002-05-16 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (back_and_forth): Very minimal test of the new functions.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of all files to the LGPL.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * basic.c: Add option --verbose.
+
+2002-01-11 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (canon_len): Fixed tests.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c: New.
+
+
+ Copyright 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/comm/third_party/libgcrypt/tests/Makefile.am b/comm/third_party/libgcrypt/tests/Makefile.am
new file mode 100644
index 0000000000..ab201f02ec
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/Makefile.am
@@ -0,0 +1,113 @@
+# Copyright (C) 2001, 2002, 2003, 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
+
+## Process this file with automake to produce Makefile.in
+
+# Note: Please keep these tests in sync with those in testdrv.c.
+# We will eventually switch over to the the new driver but as of now
+# the driver is only used for cross-compiling.
+tests_bin = \
+ version t-secmem mpitests t-sexp t-convert \
+ t-mpi-bit t-mpi-point curves t-lock \
+ prime basic keygen pubkey hmac hashtest t-kdf keygrip \
+ fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 \
+ t-ed25519 t-cv25519 t-x448 t-ed448
+
+tests_bin_last = benchmark bench-slope
+
+tests_sh = basic-disable-all-hwf
+
+tests_sh_last = hashtest-256g
+
+TESTS = $(tests_bin) $(tests_sh) $(tests_bin_last) $(tests_sh_last)
+
+# Force sequential run of some tests.
+bench-slope.log: benchmark.log
+hashtest-256g.log: bench-slope.log
+
+
+TESTS_ENVIRONMENT = GCRYPT_IN_REGRESSION_TEST=1
+
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_LDFLAGS = -no-install
+
+standard_ldadd = \
+ ../src/libgcrypt.la \
+ ../compat/libcompat.la
+
+EXTRA_PROGRAMS = testapi pkbench
+noinst_PROGRAMS = testdrv $(tests_bin) $(tests_bin_last) \
+ fipsdrv rsacvt genhashdata gchash
+noinst_HEADERS = t-common.h
+
+CLEANFILES = testdrv-build
+
+EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl \
+ pkcs1v2-oaep.h pkcs1v2-pss.h pkcs1v2-v15c.h pkcs1v2-v15s.h \
+ t-ed25519.inp t-ed448.inp stopwatch.h hashtest-256g.in \
+ sha3-224.h sha3-256.h sha3-384.h sha3-512.h \
+ blake2b.h blake2s.h \
+ basic-disable-all-hwf.in basic_all_hwfeature_combinations.sh
+
+LDADD = $(standard_ldadd) $(GPG_ERROR_LIBS) @LDADD_FOR_TESTS_KLUDGE@
+pkbench_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+prime_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+t_mpi_bit_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+t_secmem_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+testapi_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+t_lock_LDADD = $(standard_ldadd) $(GPG_ERROR_MT_LIBS) @LDADD_FOR_TESTS_KLUDGE@
+t_lock_CFLAGS = $(GPG_ERROR_MT_CFLAGS)
+testdrv_LDADD = $(LDADD_FOR_TESTS_KLUDGE)
+
+# Build a version of the test driver for the build platform.
+testdrv-build: testdrv.c
+ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) \
+ $(CPPFLAGS_FOR_BUILD) -DTESTDRV_EXEEXT=\"$(EXEEXT)\" \
+ -o $@ $(srcdir)/testdrv.c
+
+if HAVE_W32_SYSTEM
+xtestsuite_libs = ../src/.libs/libgcrypt-20.dll \
+ $(prefix)/bin/libgpg-error*-0.dll
+xtestsuite_driver = .libs/testdrv.exe
+else
+xtestsuite_libs = ../src/.libs/libgcrypt.so*
+xtestsuite_driver = testdrv
+endif
+
+# xcheck uses our new testdrv instead of the automake test runner.
+.PHONY: xcheck xtestsuite
+xcheck: testdrv$(EXEEXT)
+ srcdir=$(srcdir) ./testdrv$(EXEEXT) --verbose
+
+# Make a tarballs with all the tests.
+xtestsuite: testdrv$(EXEEXT) testdrv-build $(TESTS)
+ +(set -e; \
+ name="$(PACKAGE_TARNAME)-tests-$(PACKAGE_VERSION)";\
+ xname="$$name/$(host)" ;\
+ rm -rf $$name; mkdir $$name ; mkdir $$xname ;\
+ cp -L $(xtestsuite_driver) \
+ $$(srcdir=$(srcdir) ./testdrv-build --files|sort|uniq) $$xname/ ;\
+ cp -P $(xtestsuite_libs) $$xname/ ;\
+ touch $$xname/libgcrypt-standalone-tests ;\
+ $(AMTAR) czf "$(PACKAGE_TARNAME)-tests-$(PACKAGE_VERSION)".tar.gz \
+ $$name ;\
+ )
diff --git a/comm/third_party/libgcrypt/tests/Makefile.in b/comm/third_party/libgcrypt/tests/Makefile.in
new file mode 100644
index 0000000000..fc60e910f7
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/Makefile.in
@@ -0,0 +1,1293 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2001, 2002, 2003, 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
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = $(am__EXEEXT_1) $(tests_sh) $(am__EXEEXT_2) $(tests_sh_last)
+EXTRA_PROGRAMS = testapi$(EXEEXT) pkbench$(EXEEXT)
+noinst_PROGRAMS = testdrv$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \
+ fipsdrv$(EXEEXT) rsacvt$(EXEEXT) genhashdata$(EXEEXT) \
+ gchash$(EXEEXT)
+subdir = tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = hashtest-256g basic-disable-all-hwf
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = version$(EXEEXT) t-secmem$(EXEEXT) mpitests$(EXEEXT) \
+ t-sexp$(EXEEXT) t-convert$(EXEEXT) t-mpi-bit$(EXEEXT) \
+ t-mpi-point$(EXEEXT) curves$(EXEEXT) t-lock$(EXEEXT) \
+ prime$(EXEEXT) basic$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) \
+ hmac$(EXEEXT) hashtest$(EXEEXT) t-kdf$(EXEEXT) \
+ keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \
+ pkcs1v2$(EXEEXT) random$(EXEEXT) dsa-rfc6979$(EXEEXT) \
+ t-ed25519$(EXEEXT) t-cv25519$(EXEEXT) t-x448$(EXEEXT) \
+ t-ed448$(EXEEXT)
+am__EXEEXT_2 = benchmark$(EXEEXT) bench-slope$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+aeswrap_SOURCES = aeswrap.c
+aeswrap_OBJECTS = aeswrap.$(OBJEXT)
+aeswrap_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+aeswrap_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+basic_SOURCES = basic.c
+basic_OBJECTS = basic.$(OBJEXT)
+basic_LDADD = $(LDADD)
+basic_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+bench_slope_SOURCES = bench-slope.c
+bench_slope_OBJECTS = bench-slope.$(OBJEXT)
+bench_slope_LDADD = $(LDADD)
+bench_slope_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+benchmark_SOURCES = benchmark.c
+benchmark_OBJECTS = benchmark.$(OBJEXT)
+benchmark_LDADD = $(LDADD)
+benchmark_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+curves_SOURCES = curves.c
+curves_OBJECTS = curves.$(OBJEXT)
+curves_LDADD = $(LDADD)
+curves_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+dsa_rfc6979_SOURCES = dsa-rfc6979.c
+dsa_rfc6979_OBJECTS = dsa-rfc6979.$(OBJEXT)
+dsa_rfc6979_LDADD = $(LDADD)
+dsa_rfc6979_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+fips186_dsa_SOURCES = fips186-dsa.c
+fips186_dsa_OBJECTS = fips186-dsa.$(OBJEXT)
+fips186_dsa_LDADD = $(LDADD)
+fips186_dsa_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+fipsdrv_SOURCES = fipsdrv.c
+fipsdrv_OBJECTS = fipsdrv.$(OBJEXT)
+fipsdrv_LDADD = $(LDADD)
+fipsdrv_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+gchash_SOURCES = gchash.c
+gchash_OBJECTS = gchash.$(OBJEXT)
+gchash_LDADD = $(LDADD)
+gchash_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+genhashdata_SOURCES = genhashdata.c
+genhashdata_OBJECTS = genhashdata.$(OBJEXT)
+genhashdata_LDADD = $(LDADD)
+genhashdata_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+hashtest_SOURCES = hashtest.c
+hashtest_OBJECTS = hashtest.$(OBJEXT)
+hashtest_LDADD = $(LDADD)
+hashtest_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+hmac_SOURCES = hmac.c
+hmac_OBJECTS = hmac.$(OBJEXT)
+hmac_LDADD = $(LDADD)
+hmac_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+keygen_SOURCES = keygen.c
+keygen_OBJECTS = keygen.$(OBJEXT)
+keygen_LDADD = $(LDADD)
+keygen_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+keygrip_SOURCES = keygrip.c
+keygrip_OBJECTS = keygrip.$(OBJEXT)
+keygrip_LDADD = $(LDADD)
+keygrip_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+mpitests_SOURCES = mpitests.c
+mpitests_OBJECTS = mpitests.$(OBJEXT)
+mpitests_LDADD = $(LDADD)
+mpitests_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+pkbench_SOURCES = pkbench.c
+pkbench_OBJECTS = pkbench.$(OBJEXT)
+pkbench_DEPENDENCIES = $(standard_ldadd)
+pkcs1v2_SOURCES = pkcs1v2.c
+pkcs1v2_OBJECTS = pkcs1v2.$(OBJEXT)
+pkcs1v2_LDADD = $(LDADD)
+pkcs1v2_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+prime_SOURCES = prime.c
+prime_OBJECTS = prime.$(OBJEXT)
+prime_DEPENDENCIES = $(standard_ldadd)
+pubkey_SOURCES = pubkey.c
+pubkey_OBJECTS = pubkey.$(OBJEXT)
+pubkey_LDADD = $(LDADD)
+pubkey_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+random_SOURCES = random.c
+random_OBJECTS = random.$(OBJEXT)
+random_LDADD = $(LDADD)
+random_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+rsacvt_SOURCES = rsacvt.c
+rsacvt_OBJECTS = rsacvt.$(OBJEXT)
+rsacvt_LDADD = $(LDADD)
+rsacvt_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_convert_SOURCES = t-convert.c
+t_convert_OBJECTS = t-convert.$(OBJEXT)
+t_convert_LDADD = $(LDADD)
+t_convert_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_cv25519_SOURCES = t-cv25519.c
+t_cv25519_OBJECTS = t-cv25519.$(OBJEXT)
+t_cv25519_LDADD = $(LDADD)
+t_cv25519_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_ed25519_SOURCES = t-ed25519.c
+t_ed25519_OBJECTS = t-ed25519.$(OBJEXT)
+t_ed25519_LDADD = $(LDADD)
+t_ed25519_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_ed448_SOURCES = t-ed448.c
+t_ed448_OBJECTS = t-ed448.$(OBJEXT)
+t_ed448_LDADD = $(LDADD)
+t_ed448_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_kdf_SOURCES = t-kdf.c
+t_kdf_OBJECTS = t-kdf.$(OBJEXT)
+t_kdf_LDADD = $(LDADD)
+t_kdf_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_lock_SOURCES = t-lock.c
+t_lock_OBJECTS = t_lock-t-lock.$(OBJEXT)
+t_lock_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_lock_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_lock_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+t_mpi_bit_SOURCES = t-mpi-bit.c
+t_mpi_bit_OBJECTS = t-mpi-bit.$(OBJEXT)
+t_mpi_bit_DEPENDENCIES = $(standard_ldadd)
+t_mpi_point_SOURCES = t-mpi-point.c
+t_mpi_point_OBJECTS = t-mpi-point.$(OBJEXT)
+t_mpi_point_LDADD = $(LDADD)
+t_mpi_point_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_secmem_SOURCES = t-secmem.c
+t_secmem_OBJECTS = t-secmem.$(OBJEXT)
+t_secmem_DEPENDENCIES = $(standard_ldadd)
+t_sexp_SOURCES = t-sexp.c
+t_sexp_OBJECTS = t-sexp.$(OBJEXT)
+t_sexp_LDADD = $(LDADD)
+t_sexp_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+t_x448_SOURCES = t-x448.c
+t_x448_OBJECTS = t-x448.$(OBJEXT)
+t_x448_LDADD = $(LDADD)
+t_x448_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+testapi_SOURCES = testapi.c
+testapi_OBJECTS = testapi.$(OBJEXT)
+testapi_DEPENDENCIES = $(standard_ldadd)
+testdrv_SOURCES = testdrv.c
+testdrv_OBJECTS = testdrv.$(OBJEXT)
+testdrv_DEPENDENCIES = $(am__DEPENDENCIES_1)
+version_SOURCES = version.c
+version_OBJECTS = version.$(OBJEXT)
+version_LDADD = $(LDADD)
+version_DEPENDENCIES = $(standard_ldadd) $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/aeswrap.Po ./$(DEPDIR)/basic.Po \
+ ./$(DEPDIR)/bench-slope.Po ./$(DEPDIR)/benchmark.Po \
+ ./$(DEPDIR)/curves.Po ./$(DEPDIR)/dsa-rfc6979.Po \
+ ./$(DEPDIR)/fips186-dsa.Po ./$(DEPDIR)/fipsdrv.Po \
+ ./$(DEPDIR)/gchash.Po ./$(DEPDIR)/genhashdata.Po \
+ ./$(DEPDIR)/hashtest.Po ./$(DEPDIR)/hmac.Po \
+ ./$(DEPDIR)/keygen.Po ./$(DEPDIR)/keygrip.Po \
+ ./$(DEPDIR)/mpitests.Po ./$(DEPDIR)/pkbench.Po \
+ ./$(DEPDIR)/pkcs1v2.Po ./$(DEPDIR)/prime.Po \
+ ./$(DEPDIR)/pubkey.Po ./$(DEPDIR)/random.Po \
+ ./$(DEPDIR)/rsacvt.Po ./$(DEPDIR)/t-convert.Po \
+ ./$(DEPDIR)/t-cv25519.Po ./$(DEPDIR)/t-ed25519.Po \
+ ./$(DEPDIR)/t-ed448.Po ./$(DEPDIR)/t-kdf.Po \
+ ./$(DEPDIR)/t-mpi-bit.Po ./$(DEPDIR)/t-mpi-point.Po \
+ ./$(DEPDIR)/t-secmem.Po ./$(DEPDIR)/t-sexp.Po \
+ ./$(DEPDIR)/t-x448.Po ./$(DEPDIR)/t_lock-t-lock.Po \
+ ./$(DEPDIR)/testapi.Po ./$(DEPDIR)/testdrv.Po \
+ ./$(DEPDIR)/version.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = aeswrap.c basic.c bench-slope.c benchmark.c curves.c \
+ dsa-rfc6979.c fips186-dsa.c fipsdrv.c gchash.c genhashdata.c \
+ hashtest.c hmac.c keygen.c keygrip.c mpitests.c pkbench.c \
+ pkcs1v2.c prime.c pubkey.c random.c rsacvt.c t-convert.c \
+ t-cv25519.c t-ed25519.c t-ed448.c t-kdf.c t-lock.c t-mpi-bit.c \
+ t-mpi-point.c t-secmem.c t-sexp.c t-x448.c testapi.c testdrv.c \
+ version.c
+DIST_SOURCES = aeswrap.c basic.c bench-slope.c benchmark.c curves.c \
+ dsa-rfc6979.c fips186-dsa.c fipsdrv.c gchash.c genhashdata.c \
+ hashtest.c hmac.c keygen.c keygrip.c mpitests.c pkbench.c \
+ pkcs1v2.c prime.c pubkey.c random.c rsacvt.c t-convert.c \
+ t-cv25519.c t-ed25519.c t-ed448.c t-kdf.c t-lock.c t-mpi-bit.c \
+ t-mpi-point.c t-secmem.c t-sexp.c t-x448.c testapi.c testdrv.c \
+ version.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(srcdir)/basic-disable-all-hwf.in $(srcdir)/hashtest-256g.in \
+ $(top_srcdir)/build-aux/depcomp README
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+BUILD_VERSION = @BUILD_VERSION@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPGRT_CONFIG = @GPGRT_CONFIG@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@
+GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_FOR_TESTS_KLUDGE = @LDADD_FOR_TESTS_KLUDGE@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSROOT = @SYSROOT@
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Note: Please keep these tests in sync with those in testdrv.c.
+# We will eventually switch over to the the new driver but as of now
+# the driver is only used for cross-compiling.
+tests_bin = \
+ version t-secmem mpitests t-sexp t-convert \
+ t-mpi-bit t-mpi-point curves t-lock \
+ prime basic keygen pubkey hmac hashtest t-kdf keygrip \
+ fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 \
+ t-ed25519 t-cv25519 t-x448 t-ed448
+
+tests_bin_last = benchmark bench-slope
+tests_sh = basic-disable-all-hwf
+tests_sh_last = hashtest-256g
+TESTS_ENVIRONMENT = GCRYPT_IN_REGRESSION_TEST=1
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_LDFLAGS = -no-install
+standard_ldadd = \
+ ../src/libgcrypt.la \
+ ../compat/libcompat.la
+
+noinst_HEADERS = t-common.h
+CLEANFILES = testdrv-build
+EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl \
+ pkcs1v2-oaep.h pkcs1v2-pss.h pkcs1v2-v15c.h pkcs1v2-v15s.h \
+ t-ed25519.inp t-ed448.inp stopwatch.h hashtest-256g.in \
+ sha3-224.h sha3-256.h sha3-384.h sha3-512.h \
+ blake2b.h blake2s.h \
+ basic-disable-all-hwf.in basic_all_hwfeature_combinations.sh
+
+LDADD = $(standard_ldadd) $(GPG_ERROR_LIBS) @LDADD_FOR_TESTS_KLUDGE@
+pkbench_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+prime_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+t_mpi_bit_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+t_secmem_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+testapi_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@
+t_lock_LDADD = $(standard_ldadd) $(GPG_ERROR_MT_LIBS) @LDADD_FOR_TESTS_KLUDGE@
+t_lock_CFLAGS = $(GPG_ERROR_MT_CFLAGS)
+testdrv_LDADD = $(LDADD_FOR_TESTS_KLUDGE)
+@HAVE_W32_SYSTEM_FALSE@xtestsuite_libs = ../src/.libs/libgcrypt.so*
+@HAVE_W32_SYSTEM_TRUE@xtestsuite_libs = ../src/.libs/libgcrypt-20.dll \
+@HAVE_W32_SYSTEM_TRUE@ $(prefix)/bin/libgpg-error*-0.dll
+
+@HAVE_W32_SYSTEM_FALSE@xtestsuite_driver = testdrv
+@HAVE_W32_SYSTEM_TRUE@xtestsuite_driver = .libs/testdrv.exe
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+hashtest-256g: $(top_builddir)/config.status $(srcdir)/hashtest-256g.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+basic-disable-all-hwf: $(top_builddir)/config.status $(srcdir)/basic-disable-all-hwf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+aeswrap$(EXEEXT): $(aeswrap_OBJECTS) $(aeswrap_DEPENDENCIES) $(EXTRA_aeswrap_DEPENDENCIES)
+ @rm -f aeswrap$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(aeswrap_OBJECTS) $(aeswrap_LDADD) $(LIBS)
+
+basic$(EXEEXT): $(basic_OBJECTS) $(basic_DEPENDENCIES) $(EXTRA_basic_DEPENDENCIES)
+ @rm -f basic$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(basic_OBJECTS) $(basic_LDADD) $(LIBS)
+
+bench-slope$(EXEEXT): $(bench_slope_OBJECTS) $(bench_slope_DEPENDENCIES) $(EXTRA_bench_slope_DEPENDENCIES)
+ @rm -f bench-slope$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(bench_slope_OBJECTS) $(bench_slope_LDADD) $(LIBS)
+
+benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) $(EXTRA_benchmark_DEPENDENCIES)
+ @rm -f benchmark$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(benchmark_OBJECTS) $(benchmark_LDADD) $(LIBS)
+
+curves$(EXEEXT): $(curves_OBJECTS) $(curves_DEPENDENCIES) $(EXTRA_curves_DEPENDENCIES)
+ @rm -f curves$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(curves_OBJECTS) $(curves_LDADD) $(LIBS)
+
+dsa-rfc6979$(EXEEXT): $(dsa_rfc6979_OBJECTS) $(dsa_rfc6979_DEPENDENCIES) $(EXTRA_dsa_rfc6979_DEPENDENCIES)
+ @rm -f dsa-rfc6979$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(dsa_rfc6979_OBJECTS) $(dsa_rfc6979_LDADD) $(LIBS)
+
+fips186-dsa$(EXEEXT): $(fips186_dsa_OBJECTS) $(fips186_dsa_DEPENDENCIES) $(EXTRA_fips186_dsa_DEPENDENCIES)
+ @rm -f fips186-dsa$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(fips186_dsa_OBJECTS) $(fips186_dsa_LDADD) $(LIBS)
+
+fipsdrv$(EXEEXT): $(fipsdrv_OBJECTS) $(fipsdrv_DEPENDENCIES) $(EXTRA_fipsdrv_DEPENDENCIES)
+ @rm -f fipsdrv$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(fipsdrv_OBJECTS) $(fipsdrv_LDADD) $(LIBS)
+
+gchash$(EXEEXT): $(gchash_OBJECTS) $(gchash_DEPENDENCIES) $(EXTRA_gchash_DEPENDENCIES)
+ @rm -f gchash$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gchash_OBJECTS) $(gchash_LDADD) $(LIBS)
+
+genhashdata$(EXEEXT): $(genhashdata_OBJECTS) $(genhashdata_DEPENDENCIES) $(EXTRA_genhashdata_DEPENDENCIES)
+ @rm -f genhashdata$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(genhashdata_OBJECTS) $(genhashdata_LDADD) $(LIBS)
+
+hashtest$(EXEEXT): $(hashtest_OBJECTS) $(hashtest_DEPENDENCIES) $(EXTRA_hashtest_DEPENDENCIES)
+ @rm -f hashtest$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(hashtest_OBJECTS) $(hashtest_LDADD) $(LIBS)
+
+hmac$(EXEEXT): $(hmac_OBJECTS) $(hmac_DEPENDENCIES) $(EXTRA_hmac_DEPENDENCIES)
+ @rm -f hmac$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(hmac_OBJECTS) $(hmac_LDADD) $(LIBS)
+
+keygen$(EXEEXT): $(keygen_OBJECTS) $(keygen_DEPENDENCIES) $(EXTRA_keygen_DEPENDENCIES)
+ @rm -f keygen$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(keygen_OBJECTS) $(keygen_LDADD) $(LIBS)
+
+keygrip$(EXEEXT): $(keygrip_OBJECTS) $(keygrip_DEPENDENCIES) $(EXTRA_keygrip_DEPENDENCIES)
+ @rm -f keygrip$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(keygrip_OBJECTS) $(keygrip_LDADD) $(LIBS)
+
+mpitests$(EXEEXT): $(mpitests_OBJECTS) $(mpitests_DEPENDENCIES) $(EXTRA_mpitests_DEPENDENCIES)
+ @rm -f mpitests$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(mpitests_OBJECTS) $(mpitests_LDADD) $(LIBS)
+
+pkbench$(EXEEXT): $(pkbench_OBJECTS) $(pkbench_DEPENDENCIES) $(EXTRA_pkbench_DEPENDENCIES)
+ @rm -f pkbench$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pkbench_OBJECTS) $(pkbench_LDADD) $(LIBS)
+
+pkcs1v2$(EXEEXT): $(pkcs1v2_OBJECTS) $(pkcs1v2_DEPENDENCIES) $(EXTRA_pkcs1v2_DEPENDENCIES)
+ @rm -f pkcs1v2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pkcs1v2_OBJECTS) $(pkcs1v2_LDADD) $(LIBS)
+
+prime$(EXEEXT): $(prime_OBJECTS) $(prime_DEPENDENCIES) $(EXTRA_prime_DEPENDENCIES)
+ @rm -f prime$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(prime_OBJECTS) $(prime_LDADD) $(LIBS)
+
+pubkey$(EXEEXT): $(pubkey_OBJECTS) $(pubkey_DEPENDENCIES) $(EXTRA_pubkey_DEPENDENCIES)
+ @rm -f pubkey$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pubkey_OBJECTS) $(pubkey_LDADD) $(LIBS)
+
+random$(EXEEXT): $(random_OBJECTS) $(random_DEPENDENCIES) $(EXTRA_random_DEPENDENCIES)
+ @rm -f random$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(random_OBJECTS) $(random_LDADD) $(LIBS)
+
+rsacvt$(EXEEXT): $(rsacvt_OBJECTS) $(rsacvt_DEPENDENCIES) $(EXTRA_rsacvt_DEPENDENCIES)
+ @rm -f rsacvt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(rsacvt_OBJECTS) $(rsacvt_LDADD) $(LIBS)
+
+t-convert$(EXEEXT): $(t_convert_OBJECTS) $(t_convert_DEPENDENCIES) $(EXTRA_t_convert_DEPENDENCIES)
+ @rm -f t-convert$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_convert_OBJECTS) $(t_convert_LDADD) $(LIBS)
+
+t-cv25519$(EXEEXT): $(t_cv25519_OBJECTS) $(t_cv25519_DEPENDENCIES) $(EXTRA_t_cv25519_DEPENDENCIES)
+ @rm -f t-cv25519$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_cv25519_OBJECTS) $(t_cv25519_LDADD) $(LIBS)
+
+t-ed25519$(EXEEXT): $(t_ed25519_OBJECTS) $(t_ed25519_DEPENDENCIES) $(EXTRA_t_ed25519_DEPENDENCIES)
+ @rm -f t-ed25519$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_ed25519_OBJECTS) $(t_ed25519_LDADD) $(LIBS)
+
+t-ed448$(EXEEXT): $(t_ed448_OBJECTS) $(t_ed448_DEPENDENCIES) $(EXTRA_t_ed448_DEPENDENCIES)
+ @rm -f t-ed448$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_ed448_OBJECTS) $(t_ed448_LDADD) $(LIBS)
+
+t-kdf$(EXEEXT): $(t_kdf_OBJECTS) $(t_kdf_DEPENDENCIES) $(EXTRA_t_kdf_DEPENDENCIES)
+ @rm -f t-kdf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_kdf_OBJECTS) $(t_kdf_LDADD) $(LIBS)
+
+t-lock$(EXEEXT): $(t_lock_OBJECTS) $(t_lock_DEPENDENCIES) $(EXTRA_t_lock_DEPENDENCIES)
+ @rm -f t-lock$(EXEEXT)
+ $(AM_V_CCLD)$(t_lock_LINK) $(t_lock_OBJECTS) $(t_lock_LDADD) $(LIBS)
+
+t-mpi-bit$(EXEEXT): $(t_mpi_bit_OBJECTS) $(t_mpi_bit_DEPENDENCIES) $(EXTRA_t_mpi_bit_DEPENDENCIES)
+ @rm -f t-mpi-bit$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_mpi_bit_OBJECTS) $(t_mpi_bit_LDADD) $(LIBS)
+
+t-mpi-point$(EXEEXT): $(t_mpi_point_OBJECTS) $(t_mpi_point_DEPENDENCIES) $(EXTRA_t_mpi_point_DEPENDENCIES)
+ @rm -f t-mpi-point$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_mpi_point_OBJECTS) $(t_mpi_point_LDADD) $(LIBS)
+
+t-secmem$(EXEEXT): $(t_secmem_OBJECTS) $(t_secmem_DEPENDENCIES) $(EXTRA_t_secmem_DEPENDENCIES)
+ @rm -f t-secmem$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_secmem_OBJECTS) $(t_secmem_LDADD) $(LIBS)
+
+t-sexp$(EXEEXT): $(t_sexp_OBJECTS) $(t_sexp_DEPENDENCIES) $(EXTRA_t_sexp_DEPENDENCIES)
+ @rm -f t-sexp$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_sexp_OBJECTS) $(t_sexp_LDADD) $(LIBS)
+
+t-x448$(EXEEXT): $(t_x448_OBJECTS) $(t_x448_DEPENDENCIES) $(EXTRA_t_x448_DEPENDENCIES)
+ @rm -f t-x448$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(t_x448_OBJECTS) $(t_x448_LDADD) $(LIBS)
+
+testapi$(EXEEXT): $(testapi_OBJECTS) $(testapi_DEPENDENCIES) $(EXTRA_testapi_DEPENDENCIES)
+ @rm -f testapi$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testapi_OBJECTS) $(testapi_LDADD) $(LIBS)
+
+testdrv$(EXEEXT): $(testdrv_OBJECTS) $(testdrv_DEPENDENCIES) $(EXTRA_testdrv_DEPENDENCIES)
+ @rm -f testdrv$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testdrv_OBJECTS) $(testdrv_LDADD) $(LIBS)
+
+version$(EXEEXT): $(version_OBJECTS) $(version_DEPENDENCIES) $(EXTRA_version_DEPENDENCIES)
+ @rm -f version$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(version_OBJECTS) $(version_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aeswrap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench-slope.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/benchmark.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curves.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa-rfc6979.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips186-dsa.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fipsdrv.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gchash.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genhashdata.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashtest.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygen.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygrip.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpitests.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkbench.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs1v2.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsacvt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-convert.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-cv25519.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ed25519.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ed448.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-kdf.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-mpi-bit.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-mpi-point.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-secmem.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-sexp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-x448.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_lock-t-lock.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testapi.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testdrv.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+t_lock-t-lock.o: t-lock.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_lock_CFLAGS) $(CFLAGS) -MT t_lock-t-lock.o -MD -MP -MF $(DEPDIR)/t_lock-t-lock.Tpo -c -o t_lock-t-lock.o `test -f 't-lock.c' || echo '$(srcdir)/'`t-lock.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_lock-t-lock.Tpo $(DEPDIR)/t_lock-t-lock.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t-lock.c' object='t_lock-t-lock.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_lock_CFLAGS) $(CFLAGS) -c -o t_lock-t-lock.o `test -f 't-lock.c' || echo '$(srcdir)/'`t-lock.c
+
+t_lock-t-lock.obj: t-lock.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_lock_CFLAGS) $(CFLAGS) -MT t_lock-t-lock.obj -MD -MP -MF $(DEPDIR)/t_lock-t-lock.Tpo -c -o t_lock-t-lock.obj `if test -f 't-lock.c'; then $(CYGPATH_W) 't-lock.c'; else $(CYGPATH_W) '$(srcdir)/t-lock.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_lock-t-lock.Tpo $(DEPDIR)/t_lock-t-lock.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t-lock.c' object='t_lock-t-lock.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(t_lock_CFLAGS) $(CFLAGS) -c -o t_lock-t-lock.obj `if test -f 't-lock.c'; then $(CYGPATH_W) 't-lock.c'; else $(CYGPATH_W) '$(srcdir)/t-lock.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/aeswrap.Po
+ -rm -f ./$(DEPDIR)/basic.Po
+ -rm -f ./$(DEPDIR)/bench-slope.Po
+ -rm -f ./$(DEPDIR)/benchmark.Po
+ -rm -f ./$(DEPDIR)/curves.Po
+ -rm -f ./$(DEPDIR)/dsa-rfc6979.Po
+ -rm -f ./$(DEPDIR)/fips186-dsa.Po
+ -rm -f ./$(DEPDIR)/fipsdrv.Po
+ -rm -f ./$(DEPDIR)/gchash.Po
+ -rm -f ./$(DEPDIR)/genhashdata.Po
+ -rm -f ./$(DEPDIR)/hashtest.Po
+ -rm -f ./$(DEPDIR)/hmac.Po
+ -rm -f ./$(DEPDIR)/keygen.Po
+ -rm -f ./$(DEPDIR)/keygrip.Po
+ -rm -f ./$(DEPDIR)/mpitests.Po
+ -rm -f ./$(DEPDIR)/pkbench.Po
+ -rm -f ./$(DEPDIR)/pkcs1v2.Po
+ -rm -f ./$(DEPDIR)/prime.Po
+ -rm -f ./$(DEPDIR)/pubkey.Po
+ -rm -f ./$(DEPDIR)/random.Po
+ -rm -f ./$(DEPDIR)/rsacvt.Po
+ -rm -f ./$(DEPDIR)/t-convert.Po
+ -rm -f ./$(DEPDIR)/t-cv25519.Po
+ -rm -f ./$(DEPDIR)/t-ed25519.Po
+ -rm -f ./$(DEPDIR)/t-ed448.Po
+ -rm -f ./$(DEPDIR)/t-kdf.Po
+ -rm -f ./$(DEPDIR)/t-mpi-bit.Po
+ -rm -f ./$(DEPDIR)/t-mpi-point.Po
+ -rm -f ./$(DEPDIR)/t-secmem.Po
+ -rm -f ./$(DEPDIR)/t-sexp.Po
+ -rm -f ./$(DEPDIR)/t-x448.Po
+ -rm -f ./$(DEPDIR)/t_lock-t-lock.Po
+ -rm -f ./$(DEPDIR)/testapi.Po
+ -rm -f ./$(DEPDIR)/testdrv.Po
+ -rm -f ./$(DEPDIR)/version.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/aeswrap.Po
+ -rm -f ./$(DEPDIR)/basic.Po
+ -rm -f ./$(DEPDIR)/bench-slope.Po
+ -rm -f ./$(DEPDIR)/benchmark.Po
+ -rm -f ./$(DEPDIR)/curves.Po
+ -rm -f ./$(DEPDIR)/dsa-rfc6979.Po
+ -rm -f ./$(DEPDIR)/fips186-dsa.Po
+ -rm -f ./$(DEPDIR)/fipsdrv.Po
+ -rm -f ./$(DEPDIR)/gchash.Po
+ -rm -f ./$(DEPDIR)/genhashdata.Po
+ -rm -f ./$(DEPDIR)/hashtest.Po
+ -rm -f ./$(DEPDIR)/hmac.Po
+ -rm -f ./$(DEPDIR)/keygen.Po
+ -rm -f ./$(DEPDIR)/keygrip.Po
+ -rm -f ./$(DEPDIR)/mpitests.Po
+ -rm -f ./$(DEPDIR)/pkbench.Po
+ -rm -f ./$(DEPDIR)/pkcs1v2.Po
+ -rm -f ./$(DEPDIR)/prime.Po
+ -rm -f ./$(DEPDIR)/pubkey.Po
+ -rm -f ./$(DEPDIR)/random.Po
+ -rm -f ./$(DEPDIR)/rsacvt.Po
+ -rm -f ./$(DEPDIR)/t-convert.Po
+ -rm -f ./$(DEPDIR)/t-cv25519.Po
+ -rm -f ./$(DEPDIR)/t-ed25519.Po
+ -rm -f ./$(DEPDIR)/t-ed448.Po
+ -rm -f ./$(DEPDIR)/t-kdf.Po
+ -rm -f ./$(DEPDIR)/t-mpi-bit.Po
+ -rm -f ./$(DEPDIR)/t-mpi-point.Po
+ -rm -f ./$(DEPDIR)/t-secmem.Po
+ -rm -f ./$(DEPDIR)/t-sexp.Po
+ -rm -f ./$(DEPDIR)/t-x448.Po
+ -rm -f ./$(DEPDIR)/t_lock-t-lock.Po
+ -rm -f ./$(DEPDIR)/testapi.Po
+ -rm -f ./$(DEPDIR)/testdrv.Po
+ -rm -f ./$(DEPDIR)/version.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Force sequential run of some tests.
+bench-slope.log: benchmark.log
+hashtest-256g.log: bench-slope.log
+
+# Build a version of the test driver for the build platform.
+testdrv-build: testdrv.c
+ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) \
+ $(CPPFLAGS_FOR_BUILD) -DTESTDRV_EXEEXT=\"$(EXEEXT)\" \
+ -o $@ $(srcdir)/testdrv.c
+
+# xcheck uses our new testdrv instead of the automake test runner.
+.PHONY: xcheck xtestsuite
+xcheck: testdrv$(EXEEXT)
+ srcdir=$(srcdir) ./testdrv$(EXEEXT) --verbose
+
+# Make a tarballs with all the tests.
+xtestsuite: testdrv$(EXEEXT) testdrv-build $(TESTS)
+ +(set -e; \
+ name="$(PACKAGE_TARNAME)-tests-$(PACKAGE_VERSION)";\
+ xname="$$name/$(host)" ;\
+ rm -rf $$name; mkdir $$name ; mkdir $$xname ;\
+ cp -L $(xtestsuite_driver) \
+ $$(srcdir=$(srcdir) ./testdrv-build --files|sort|uniq) $$xname/ ;\
+ cp -P $(xtestsuite_libs) $$xname/ ;\
+ touch $$xname/libgcrypt-standalone-tests ;\
+ $(AMTAR) czf "$(PACKAGE_TARNAME)-tests-$(PACKAGE_VERSION)".tar.gz \
+ $$name ;\
+ )
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/comm/third_party/libgcrypt/tests/README b/comm/third_party/libgcrypt/tests/README
new file mode 100644
index 0000000000..5326890259
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/README
@@ -0,0 +1,9 @@
+Some notes about the tests.
+
+rsa-16k.key - A 16384 bit RSA key (public and privat), created 2008-08-28.
+ It took 91 minutes to create it on a 1500Mhz Pentium M.
+ pkpench showed these results:
+ encrypt: 80 ms
+ decrypt: 14370 ms
+ sign: 14110 ms
+ verify: 30 ms
diff --git a/comm/third_party/libgcrypt/tests/aeswrap.c b/comm/third_party/libgcrypt/tests/aeswrap.c
new file mode 100644
index 0000000000..7c7e60bf18
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/aeswrap.c
@@ -0,0 +1,284 @@
+/* aeswrap.c - AESWRAP mode regression tests
+ * Copyright (C) 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#define PGM "aeswrap"
+#include "t-common.h"
+
+
+static void
+check_one (int algo,
+ const void *kek, size_t keklen,
+ const void *data, size_t datalen,
+ const void *expected, size_t expectedlen,
+ int inplace)
+{
+ gcry_error_t err;
+ gcry_cipher_hd_t hd;
+ unsigned char outbuf[32+8];
+ size_t outbuflen;
+
+ err = gcry_cipher_open (&hd, algo, GCRY_CIPHER_MODE_AESWRAP, 0);
+ if (err)
+ {
+ fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_cipher_setkey (hd, kek, keklen);
+ if (err)
+ {
+ fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ outbuflen = datalen + 8;
+ if (outbuflen > sizeof outbuf)
+ {
+ err = gpg_error (GPG_ERR_INTERNAL);
+ }
+ else if (inplace)
+ {
+ memcpy (outbuf, data, datalen);
+ err = gcry_cipher_encrypt (hd, outbuf, outbuflen, outbuf, datalen);
+ }
+ else
+ {
+ err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, datalen);
+ }
+
+ if (err)
+ {
+ fail ("gcry_cipher_encrypt failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ if (outbuflen != expectedlen || memcmp (outbuf, expected, expectedlen))
+ {
+ const unsigned char *s;
+ int i;
+
+ fail ("mismatch at encryption!%s\n", inplace ? " (inplace)" : "");
+ fprintf (stderr, "computed: ");
+ for (i = 0; i < outbuflen; i++)
+ fprintf (stderr, "%02x ", outbuf[i]);
+ fprintf (stderr, "\nexpected: ");
+ for (s = expected, i = 0; i < expectedlen; s++, i++)
+ fprintf (stderr, "%02x ", *s);
+ putc ('\n', stderr);
+ }
+
+
+ outbuflen = expectedlen - 8;
+ if (outbuflen > sizeof outbuf)
+ {
+ err = gpg_error (GPG_ERR_INTERNAL);
+ }
+ else if (inplace)
+ {
+ memcpy (outbuf, expected, expectedlen);
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, outbuf, expectedlen);
+ }
+ else
+ {
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
+ }
+
+ if (err)
+ {
+ fail ("gcry_cipher_decrypt failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ if (outbuflen != datalen || memcmp (outbuf, data, datalen))
+ {
+ const unsigned char *s;
+ int i;
+
+ fail ("mismatch at decryption!%s\n", inplace ? " (inplace)" : "");
+ fprintf (stderr, "computed: ");
+ for (i = 0; i < outbuflen; i++)
+ fprintf (stderr, "%02x ", outbuf[i]);
+ fprintf (stderr, "\nexpected: ");
+ for (s = data, i = 0; i < datalen; s++, i++)
+ fprintf (stderr, "%02x ", *s);
+ putc ('\n', stderr);
+ }
+
+ /* Now the last step again with a key reset. */
+ gcry_cipher_reset (hd);
+
+ outbuflen = expectedlen - 8;
+ if (outbuflen > sizeof outbuf)
+ {
+ err = gpg_error (GPG_ERR_INTERNAL);
+ }
+ else if (inplace)
+ {
+ memcpy (outbuf, expected, expectedlen);
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, outbuf, expectedlen);
+ }
+ else
+ {
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
+ }
+
+ if (err)
+ {
+ fail ("gcry_cipher_decrypt(2) failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ if (outbuflen != datalen || memcmp (outbuf, data, datalen))
+ fail ("mismatch at decryption(2)!%s\n", inplace ? " (inplace)" : "");
+
+ /* And once more without a key reset. */
+ outbuflen = expectedlen - 8;
+ if (outbuflen > sizeof outbuf)
+ {
+ err = gpg_error (GPG_ERR_INTERNAL);
+ }
+ else if (inplace)
+ {
+ memcpy (outbuf, expected, expectedlen);
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, outbuf, expectedlen);
+ }
+ else
+ {
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
+ }
+
+ if (err)
+ {
+ fail ("gcry_cipher_decrypt(3) failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ if (outbuflen != datalen || memcmp (outbuf, data, datalen))
+ fail ("mismatch at decryption(3)!%s\n", inplace ? " (inplace)" : "");
+
+ gcry_cipher_close (hd);
+}
+
+
+static void
+check (int algo,
+ const void *kek, size_t keklen,
+ const void *data, size_t datalen,
+ const void *expected, size_t expectedlen)
+{
+ check_one (algo, kek, keklen, data, datalen, expected, expectedlen, 0);
+ check_one (algo, kek, keklen, data, datalen, expected, expectedlen, 1);
+}
+
+
+static void
+check_all (void)
+{
+ if (verbose)
+ fprintf (stderr, "4.1 Wrap 128 bits of Key Data with a 128-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES128,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16,
+ "\x1F\xA6\x8B\x0A\x81\x12\xB4\x47\xAE\xF3\x4B\xD8\xFB\x5A\x7B\x82"
+ "\x9D\x3E\x86\x23\x71\xD2\xCF\xE5", 24);
+
+ if (verbose)
+ fprintf (stderr, "4.2 Wrap 128 bits of Key Data with a 192-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES192,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17", 24,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16,
+ "\x96\x77\x8B\x25\xAE\x6C\xA4\x35\xF9\x2B\x5B\x97\xC0\x50\xAE\xD2"
+ "\x46\x8A\xB8\xA1\x7A\xD8\x4E\x5D", 24);
+
+ if (verbose)
+ fprintf (stderr, "4.3 Wrap 128 bits of Key Data with a 256-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES256,
+ "\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,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16,
+ "\x64\xE8\xC3\xF9\xCE\x0F\x5B\xA2\x63\xE9\x77\x79\x05\x81\x8A\x2A"
+ "\x93\xC8\x19\x1E\x7D\x6E\x8A\xE7", 24);
+
+ if (verbose)
+ fprintf (stderr, "4.4 Wrap 192 bits of Key Data with a 192-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES192,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17", 24,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+ "\x00\x01\x02\x03\x04\x05\x06\x07", 24,
+ "\x03\x1D\x33\x26\x4E\x15\xD3\x32\x68\xF2\x4E\xC2\x60\x74\x3E\xDC"
+ "\xE1\xC6\xC7\xDD\xEE\x72\x5A\x93\x6B\xA8\x14\x91\x5C\x67\x62\xD2", 32);
+
+ if (verbose)
+ fprintf (stderr, "4.5 Wrap 192 bits of Key Data with a 256-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES256,
+ "\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,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+ "\x00\x01\x02\x03\x04\x05\x06\x07", 24,
+ "\xA8\xF9\xBC\x16\x12\xC6\x8B\x3F\xF6\xE6\xF4\xFB\xE3\x0E\x71\xE4"
+ "\x76\x9C\x8B\x80\xA3\x2C\xB8\x95\x8C\xD5\xD1\x7D\x6B\x25\x4D\xA1", 32);
+
+ if (verbose)
+ fprintf (stderr, "4.6 Wrap 256 bits of Key Data with a 256-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES,
+ "\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,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 32,
+ "\x28\xC9\xF4\x04\xC4\xB8\x10\xF4\xCB\xCC\xB3\x5C\xFB\x87\xF8\x26"
+ "\x3F\x57\x86\xE2\xD8\x0E\xD3\x26\xCB\xC7\xF0\xE7\x1A\x99\xF4\x3B"
+ "\xFB\x98\x8B\x9B\x7A\x02\xDD\x21", 40);
+}
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ check_all ();
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/basic-disable-all-hwf.in b/comm/third_party/libgcrypt/tests/basic-disable-all-hwf.in
new file mode 100644
index 0000000000..1f0a4de0a7
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/basic-disable-all-hwf.in
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+echo " now running 'basic' test with all hardware features disabled."
+exec ./basic@EXEEXT@ --disable-hwf all
diff --git a/comm/third_party/libgcrypt/tests/basic.c b/comm/third_party/libgcrypt/tests/basic.c
new file mode 100644
index 0000000000..2b54384649
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/basic.c
@@ -0,0 +1,14576 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#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)
+
+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 ( "<LF>", 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" },
+ { GCRY_CIPHER_3DES,
+ "abcdefghABCDEFGH01234567",
+ "This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
+ 0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" },
+ { GCRY_CIPHER_DES,
+ "abcdefgh",
+ "This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
+ 0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" }
+ };
+ gcry_cipher_hd_t hd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, blklen, keylen;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting CBC MAC checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ err = gcry_cipher_open (&hd,
+ tv[i].algo,
+ GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
+ if (!hd)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_open failed: %s\n",
+ tv[i].algo, gpg_strerror (err));
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n",
+ tv[i].algo);
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen (tv[i].algo);
+ if (!keylen)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n",
+ tv[i].algo);
+ return;
+ }
+
+ err = gcry_cipher_setkey (hd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n",
+ tv[i].algo, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hd, NULL, 0);
+ if (err)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n",
+ tv[i].algo, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking CBC MAC for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_encrypt (hd,
+ out, blklen,
+ tv[i].plaintext,
+ tv[i].plaintextlen ?
+ tv[i].plaintextlen :
+ strlen ((char*)tv[i].plaintext));
+ if (err)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n",
+ tv[i].algo, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+#if 0
+ {
+ int j;
+ for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++)
+ printf ("\\x%02x", out[j] & 0xFF);
+ printf ("\n");
+ }
+#endif
+
+ if (memcmp (tv[i].mac, out, blklen))
+ fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i);
+
+ gcry_cipher_close (hd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed CBC MAC checks.\n");
+}
+
+static void
+check_aes128_cbc_cts_cipher (void)
+{
+ static const char key[128 / 8] = "chicken teriyaki";
+ static const unsigned char plaintext[] =
+ "I would like the General Gau's Chicken, please, and wonton soup.";
+ static const struct tv
+ {
+ unsigned char out[MAX_DATA_LEN];
+ int inlen;
+ } tv[] =
+ {
+ { "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
+ "\x97",
+ 17 },
+ { "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
+ "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5",
+ 31 },
+ { "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+ "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
+ 32 },
+ { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5",
+ 47 },
+ { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
+ 48 },
+ { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+ "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
+ "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
+ 64 },
+ };
+ gcry_cipher_hd_t hd;
+ unsigned char out[MAX_DATA_LEN];
+ int i;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting AES128 CBC CTS checks.\n");
+ err = gcry_cipher_open (&hd,
+ GCRY_CIPHER_AES,
+ GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_cipher_setkey (hd, key, 128 / 8);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ err = gcry_cipher_setiv (hd, NULL, 0);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking encryption for length %i\n", tv[i].inlen);
+ err = gcry_cipher_encrypt (hd, out, MAX_DATA_LEN,
+ plaintext, tv[i].inlen);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (memcmp (tv[i].out, out, tv[i].inlen))
+ fail ("aes-cbc-cts, encrypt mismatch entry %d\n", i);
+
+ err = gcry_cipher_setiv (hd, NULL, 0);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+ if (verbose)
+ fprintf (stderr, " checking decryption for length %i\n", tv[i].inlen);
+ err = gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (memcmp (plaintext, out, tv[i].inlen))
+ fail ("aes-cbc-cts, decrypt mismatch entry %d\n", i);
+ }
+
+ gcry_cipher_close (hd);
+ if (verbose)
+ fprintf (stderr, " Completed AES128 CBC CTS checks.\n");
+}
+
+static void
+check_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;
+ struct
+ {
+ const char *plaintext;
+ int keylen;
+ int inlen;
+ const char *out;
+ } data[MAX_DATA_LEN];
+ } tv[] =
+ {
+ /* 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,
+ { { "\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,
+ { { "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ 56,
+ 8,
+ "\xc0\x45\x04\x01\x2e\x4e\x1f\x53" },
+ { }
+ }
+ },
+ /* Weak-key testing */
+ { GCRY_CIPHER_DES,
+ "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+ 1,
+ { { "\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,
+ { { "\x00\x00\x00\x00\x00\x00\x00\x00",
+ 8,
+ 8,
+ "\xca\xaa\xaf\x4d\xea\xf1\xdb\xae" },
+ { }
+ }
+ },
+ { GCRY_CIPHER_SM4,
+ "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ 0,
+ { { "\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,
+ { { "\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" },
+ { }
+ }
+ },
+ };
+ 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 (gcry_cipher_test_algo (algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\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;
+ 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,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
+
+ { "", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES192,
+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
+ "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" },
+ { "", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES256,
+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" },
+ { "", 0, "" }
+ }
+ },
+ /* Some truncation tests. With a truncated second block and
+ also with a single truncated block. */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e",
+ 15,
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" },
+ {"", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ {"\xae",
+ 1,
+ "\x98" },
+ {"", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17",
+ 15,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6" },
+ {"", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b",
+ 1,
+ "\x87" },
+ {"", 0, "" }
+ }
+ },
+ /* Tests to see whether it works correctly as a stream cipher. */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e",
+ 15,
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" },
+ {"\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 17,
+ "\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" },
+ {"\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
+
+ { "", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b",
+ 1,
+ "\x87" },
+ {"\xc1\xbe",
+ 2,
+ "\x4d\x61" },
+ {"\xe2\x2e\x40",
+ 3,
+ "\x91\xb6\x20" },
+ {"\x9f",
+ 1,
+ "\xe3" },
+ {"\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 9,
+ "\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e",
+ 15,
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" },
+ {"\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+ 9,
+ "\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e" },
+
+ { "", 0, "" }
+ }
+ },
+ /* 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,
+ "\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,
+ "\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,
+ "\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,
+ "\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,
+ "\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,
+ "\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,
+ "\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,
+ "\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, "" }
+ }
+ },
+#ifdef USE_CAMELLIA
+ { GCRY_CIPHER_CAMELLIA256,
+ "\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,
+ "\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,
+ "\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,
+ "\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,
+ "\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*/
+ { GCRY_CIPHER_SM4,
+ "\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,
+ "\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, "" }
+ }
+ },
+ { 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 (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
+ if (err)
+ {
+ fail ("aes-ctr, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-ctr, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setctr (hde, tv[i].ctr, blklen);
+ if (!err)
+ err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen);
+ if (err)
+ {
+ fail ("aes-ctr, gcry_cipher_setctr failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+
+ err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+ if (gpg_err_code (err) != GPG_ERR_INV_CIPHER_MODE)
+ {
+ fail ("aes-ctr, gcryctl_get_taglen failed to fail (tv %d): %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking CTR mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ err = gcry_cipher_encrypt (hde, out, 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 cfb8;
+ char key[MAX_DATA_LEN];
+ char iv[MAX_DATA_LEN];
+ struct data
+ {
+ unsigned char plaintext[MAX_DATA_LEN];
+ int inlen;
+ char out[MAX_DATA_LEN];
+ }
+ data[MAX_DATA_LEN];
+ 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, 1,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b",
+ 1,
+ "\x3b"},
+ { "\xc1",
+ 1,
+ "\x79"},
+ { "\xbe",
+ 1,
+ "\x42"},
+ { "\xe2",
+ 1,
+ "\x4c"},
+ }
+ },
+ { GCRY_CIPHER_AES192, 1,
+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b",
+ 1,
+ "\xcd"},
+ { "\xc1",
+ 1,
+ "\xa2"},
+ { "\xbe",
+ 1,
+ "\x52"},
+ { "\xe2",
+ 1,
+ "\x1e"},
+ }
+ },
+ { GCRY_CIPHER_AES256, 1,
+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b",
+ 1,
+ "\xdc"},
+ { "\xc1",
+ 1,
+ "\x1f"},
+ { "\xbe",
+ 1,
+ "\x1a"},
+ { "\xe2",
+ 1,
+ "\x85"},
+ }
+ },
+ { GCRY_CIPHER_AES, 1,
+ "\x3a\x6f\x91\x59\x26\x3f\xa6\xce\xf2\xa0\x75\xca\xfa\xce\x58\x17",
+ "\x0f\xc2\x36\x62\xb7\xdb\xf7\x38\x27\xf0\xc7\xde\x32\x1c\xa3\x6e",
+ { { "\x87\xef\xeb\x8d\x55\x9e\xd3\x36\x77\x28",
+ 10,
+ "\x8e\x9c\x50\x42\x56\x14\xd5\x40\xce\x11"},
+ }
+ },
+ { GCRY_CIPHER_AES192, 1,
+ "\x53\x7e\x7b\xf6\x61\xfd\x40\x24\xa0\x24\x61\x3f\x15\xb1\x36\x90"
+ "\xf7\xd0\xc8\x47\xc1\xe1\x89\x65",
+ "\x3a\x81\xf9\xd9\xd3\xc1\x55\xb0\xca\xad\x5d\x73\x34\x94\x76\xfc",
+ { { "\xd3\xd8\xb9\xb9\x84\xad\xc2\x42\x37\xee",
+ 10,
+ "\x38\x79\xfe\xa7\x2a\xc9\x99\x29\xe5\x3a"},
+ }
+ },
+ { GCRY_CIPHER_AES256, 1,
+ "\xeb\xbb\x45\x66\xb5\xe1\x82\xe0\xf0\x72\x46\x6b\x0b\x31\x1d\xf3"
+ "\x8f\x91\x75\xbc\x02\x13\xa5\x53\x0b\xce\x2e\xc4\xd7\x4f\x40\x0d",
+ "\x09\x56\xa4\x8e\x01\x00\x2c\x9e\x16\x37\x6d\x6e\x30\x8d\xba\xd1",
+ { { "\xb0\xfe\x25\xac\x8d\x3d\x28\xa2\xf4\x71",
+ 10,
+ "\x63\x8c\x68\x23\xe7\x25\x6f\xb5\x62\x6e"},
+ }
+ },
+ { GCRY_CIPHER_3DES, 1,
+ "\xe3\x34\x7a\x6b\x0b\xc1\x15\x2c\x64\x2a\x25\xcb\xd3\xbc\x31\xab"
+ "\xfb\xa1\x62\xa8\x1f\x19\x7c\x15",
+ "\xb7\x40\xcc\x21\xe9\x25\xe3\xc8",
+ { { "\xdb\xe9\x15\xfc\xb3\x3b\xca\x18\xef\x14",
+ 10,
+ "\xf4\x80\x1a\x8d\x03\x9d\xb4\xca\x8f\xf6"},
+ }
+ },
+ { GCRY_CIPHER_3DES, 1,
+ "\x7c\xa2\x89\x38\xba\x6b\xec\x1f\xfe\xc7\x8f\x7c\xd6\x97\x61\x94"
+ "\x7c\xa2\x89\x38\xba\x6b\xec\x1f",
+ "\x95\x38\x96\x58\x6e\x49\xd3\x8f",
+ { { "\x2e\xa9\x56\xd4\xa2\x11\xdb\x68\x59\xb7",
+ 10,
+ "\xf2\x0e\x53\x66\x74\xa6\x6f\xa7\x38\x05"},
+ }
+ },
+#ifdef USE_GOST28147
+ { GCRY_CIPHER_GOST28147_MESH, 0,
+ "\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
+ { GCRY_CIPHER_SM4, 0,
+ "\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, 0,
+ "\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" },
+ }
+ },
+ };
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, j, keylen, blklen, mode;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting CFB checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ mode = tv[i].cfb8? GCRY_CIPHER_MODE_CFB8 : GCRY_CIPHER_MODE_CFB;
+
+ if (verbose)
+ fprintf (stderr, " checking CFB mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_open (&hde, tv[i].algo, mode, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, mode, 0);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ 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;
+ char key[MAX_DATA_LEN];
+ char iv[MAX_DATA_LEN];
+ struct data
+ {
+ unsigned char plaintext[MAX_DATA_LEN];
+ unsigned int inlen;
+ char out[MAX_DATA_LEN];
+ }
+ data[MAX_DATA_LEN];
+ } tv[] =
+ {
+ /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5\x3c\x52\xda\xc5\x4e\xd8\x25"},
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43\x44\xf7\xa8\x22\x60\xed\xcc" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x30\x4c\x65\x28\xf6\x59\xc7\x78\x66\xa5\x10\xd9\xc1\xd6\xae\x5e" },
+ }
+ },
+ { GCRY_CIPHER_AES192,
+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
+ "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\xfc\xc2\x8b\x8d\x4c\x63\x83\x7c\x09\xe8\x17\x00\xc1\x10\x04\x01" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x8d\x9a\x9a\xea\xc0\xf6\x59\x6f\x55\x9c\x6d\x4d\xaf\x59\xa5\xf2" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x6d\x9f\x20\x08\x57\xca\x6c\x3e\x9c\xac\x52\x4b\xd9\xac\xc9\x2a" },
+ }
+ },
+ { GCRY_CIPHER_AES256,
+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x4f\xeb\xdc\x67\x40\xd2\x0b\x3a\xc8\x8f\x6a\xd8\x2a\x4f\xb0\x8d" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x71\xab\x47\xa0\x86\xe8\x6e\xed\xf3\x9d\x1c\x5b\xba\x97\xc4\x08" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x01\x26\x14\x1d\x67\xf3\x7b\xe8\x53\x8f\x5a\x8b\xe7\x40\xe4\x84" }
+ }
+ },
+ { GCRY_CIPHER_SM4,
+ "\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,
+ "\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" },
+ }
+ }
+ };
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, j, keylen, blklen;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting OFB checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking OFB mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-ofb, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("aes-ofb, gcry_cipher_get_algo_blklen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, blklen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, blklen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ tv[i].data[j].plaintext,
+ tv[i].data[j].inlen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j);
+
+ err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+ err = gcry_cipher_reset(hde);
+ if (!err)
+ err = gcry_cipher_reset(hdd);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_reset (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* gcry_cipher_reset clears the IV */
+ err = gcry_cipher_setiv (hde, tv[i].iv, blklen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, blklen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* this time we encrypt and decrypt one byte at a time */
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ int byteNum;
+ for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+ {
+ err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+ (tv[i].data[j].plaintext) + byteNum,
+ 1);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j);
+
+ for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+ {
+ err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed OFB checks.\n");
+}
+
+static void
+_check_gcm_cipher (unsigned int step)
+{
+#define MAX_GCM_DATA_LEN (256 + 32)
+ static const struct tv
+ {
+ int algo;
+ char key[MAX_DATA_LEN];
+ char iv[MAX_DATA_LEN];
+ int ivlen;
+ unsigned char aad[MAX_DATA_LEN];
+ int aadlen;
+ unsigned char plaintext[MAX_GCM_DATA_LEN];
+ int inlen;
+ char out[MAX_GCM_DATA_LEN];
+ char tag[MAX_DATA_LEN];
+ int taglen;
+ int should_fail;
+ } tv[] =
+ {
+ /* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf */
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45\x5a" },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45",
+ 15 },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7",
+ 14 },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4",
+ 13 },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57",
+ 12 },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d",
+ 11, 1 },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58\xe2\xfc\xce\xfa\x7e\x30\x61",
+ 8 },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58\xe2\xfc\xce",
+ 4 },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x58",
+ 1, 1 },
+ { GCRY_CIPHER_AES,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 16,
+ "\x03\x88\xda\xce\x60\xb6\xa3\x92\xf3\x28\xc2\xb9\x71\xb2\xfe\x78",
+ "\xab\x6e\x47\xd4\x2c\xec\x13\xbd\xf5\x3a\x67\xb2\x12\x57\xbd\xdf" },
+ { GCRY_CIPHER_AES,
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12,
+ "", 0,
+ "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+ 64,
+ "\x42\x83\x1e\xc2\x21\x77\x74\x24\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+ "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+ "\x21\xd5\x14\xb2\x54\x66\x93\x1c\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+ "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85",
+ "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4" },
+ { GCRY_CIPHER_AES,
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12,
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2", 20,
+ "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+ 60,
+ "\x42\x83\x1e\xc2\x21\x77\x74\x24\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+ "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+ "\x21\xd5\x14\xb2\x54\x66\x93\x1c\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+ "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85",
+ "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb\x94\xfa\xe9\x5a\xe7\x12\x1a\x47" },
+ { GCRY_CIPHER_AES,
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ "\xca\xfe\xba\xbe\xfa\xce\xdb\xad", 8,
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2", 20,
+ "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+ 60,
+ "\x61\x35\x3b\x4c\x28\x06\x93\x4a\x77\x7f\xf5\x1f\xa2\x2a\x47\x55"
+ "\x69\x9b\x2a\x71\x4f\xcd\xc6\xf8\x37\x66\xe5\xf9\x7b\x6c\x74\x23"
+ "\x73\x80\x69\x00\xe4\x9f\x24\xb2\x2b\x09\x75\x44\xd4\x89\x6b\x42"
+ "\x49\x89\xb5\xe1\xeb\xac\x0f\x07\xc2\x3f\x45\x98",
+ "\x36\x12\xd2\xe7\x9e\x3b\x07\x85\x56\x1b\xe1\x4a\xac\xa2\xfc\xcb" },
+ { GCRY_CIPHER_AES,
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa"
+ "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28"
+ "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54"
+ "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60,
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2", 20,
+ "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+ 60,
+ "\x8c\xe2\x49\x98\x62\x56\x15\xb6\x03\xa0\x33\xac\xa1\x3f\xb8\x94"
+ "\xbe\x91\x12\xa5\xc3\xa2\x11\xa8\xba\x26\x2a\x3c\xca\x7e\x2c\xa7"
+ "\x01\xe4\xa9\xa4\xfb\xa4\x3c\x90\xcc\xdc\xb2\x81\xd4\x8c\x7c\x6f"
+ "\xd6\x28\x75\xd2\xac\xa4\x17\x03\x4c\x34\xae\xe5",
+ "\x61\x9c\xc5\xae\xff\xfe\x0b\xfa\x46\x2a\xf4\x3c\x16\x99\xd0\x50" },
+ { GCRY_CIPHER_AES192,
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+ "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa"
+ "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28"
+ "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54"
+ "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60,
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2", 20,
+ "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+ 60,
+ "\xd2\x7e\x88\x68\x1c\xe3\x24\x3c\x48\x30\x16\x5a\x8f\xdc\xf9\xff"
+ "\x1d\xe9\xa1\xd8\xe6\xb4\x47\xef\x6e\xf7\xb7\x98\x28\x66\x6e\x45"
+ "\x81\xe7\x90\x12\xaf\x34\xdd\xd9\xe2\xf0\x37\x58\x9b\x29\x2d\xb3"
+ "\xe6\x7c\x03\x67\x45\xfa\x22\xe7\xe9\xb7\x37\x3b",
+ "\xdc\xf5\x66\xff\x29\x1c\x25\xbb\xb8\x56\x8f\xc3\xd3\x76\xa6\xd9" },
+ { GCRY_CIPHER_AES256,
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+ "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+ "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa"
+ "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28"
+ "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54"
+ "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60,
+ "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+ "\xab\xad\xda\xd2", 20,
+ "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+ "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+ "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+ "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+ 60,
+ "\x5a\x8d\xef\x2f\x0c\x9e\x53\xf1\xf7\x5d\x78\x53\x65\x9e\x2a\x20"
+ "\xee\xb2\xb2\x2a\xaf\xde\x64\x19\xa0\x58\xab\x4f\x6f\x74\x6b\xf4"
+ "\x0f\xc0\xc3\xb7\x80\xf2\x44\x45\x2d\xa3\xeb\xf1\xc5\xd8\x2c\xde"
+ "\xa2\x41\x89\x97\x20\x0e\xf8\x2e\x44\xae\x7e\x3f",
+ "\xa4\x4a\x82\x66\xee\x1c\x8e\xb0\xc8\xb5\xd4\xcf\x5a\xe9\xf1\x9a" },
+ /* Test vectors for overflowing CTR. */
+ /* After setiv, ctr_low: 0xffffffff */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\xdd\x40\xe7",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x7d\x6e\x38\xfd\xd0\x04\x9d\x28\xdf\x4a\x10\x3f\xa3\x9e\xf8\xf8"
+ "\x6c\x2c\x10\xa7\x91\xab\xc0\x86\xd4\x6d\x69\xea\x58\xc4\xf9\xc0"
+ "\xd4\xee\xc2\xb0\x9d\x36\xae\xe7\xc9\xa9\x1f\x71\xa8\xee\xa2\x1d"
+ "\x20\xfd\x79\xc7\xd9\xc4\x90\x51\x38\x97\xb6\x9f\x55\xea\xf3\xf0"
+ "\x78\xb4\xd3\x8c\xa9\x9b\x32\x7d\x19\x36\x96\xbc\x8e\xab\x80\x9f"
+ "\x61\x56\xcc\xbd\x3a\x80\xc6\x69\x37\x0a\x89\x89\x21\x82\xb7\x79"
+ "\x6d\xe9\xb4\x34\xc4\x31\xe0\xbe\x71\xad\xf3\x50\x05\xb2\x61\xab"
+ "\xb3\x1a\x80\x57\xcf\xe1\x11\x26\xcb\xa9\xd1\xf6\x58\x46\xf1\x69"
+ "\xa2\xb8\x42\x3c\xe8\x28\x13\xca\x58\xd9\x28\x99\xf8\xc8\x17\x32"
+ "\x4a\xf9\xb3\x4c\x7a\x47\xad\xe4\x77\x64\xec\x70\xa1\x01\x0b\x88"
+ "\xe7\x30\x0b\xbd\x66\x25\x39\x1e\x51\x67\xee\xec\xdf\xb8\x24\x5d"
+ "\x7f\xcb\xee\x7a\x4e\xa9\x93\xf0\xa1\x84\x7b\xfe\x5a\xe3\x86\xb2"
+ "\xfb\xcd\x39\xe7\x1e\x5e\x48\x65\x4b\x50\x2b\x4a\x99\x46\x3f\x6f"
+ "\xdb\xd9\x97\xdb\xe5\x6d\xa4\xdd\x6c\x18\x64\x5e\xae\x7e\x2c\xd3"
+ "\xb4\xf3\x57\x5c\xb5\xf8\x7f\xe5\x87\xb5\x35\xdb\x80\x38\x6e\x2c"
+ "\x5c\xdd\xeb\x7c\x63\xac\xe4\xb5\x5a\x6a\x40\x6d\x72\x69\x9a\xa9"
+ "\x8f\x5e\x93\x91\x4d\xce\xeb\x87\xf5\x25\xed\x75\x6b\x3b\x1a\xf2"
+ "\x0c\xd2\xa4\x10\x45\xd2\x87\xae\x29\x6d\xeb\xea\x66\x5f\xa0\xc2",
+ "\x8c\x22\xe3\xda\x9d\x94\x8a\xbe\x8a\xbc\x55\x2c\x94\x63\x44\x40" },
+ /* After setiv, ctr_low: 0xfffffffe */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xd1\xc1\xdf",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\xac\x6a\x10\x3f\xe2\x8d\xed\x27\x55\x14\xca\x1f\x03\x67\x0a\xa8"
+ "\xa1\x07\xbf\x00\x73\x5b\x64\xef\xac\x30\x83\x81\x48\x4c\xaa\xd5"
+ "\xff\xca\xef\x2f\x77\xbe\xfe\x1b\x20\x5c\x86\x19\xc7\xf9\x11\x99"
+ "\x27\xc5\x57\xa7\x0a\xc2\xa8\x05\xd9\x07\x2b\xb9\x38\xa4\xef\x58"
+ "\x92\x74\xcf\x89\xc7\xba\xfc\xb9\x70\xac\x86\xe2\x31\xba\x7c\xf9"
+ "\xc4\xe2\xe0\x4c\x1b\xe4\x3f\x75\x83\x5c\x40\x0e\xa4\x13\x8b\x04"
+ "\x60\x78\x57\x29\xbb\xe6\x61\x93\xe3\x16\xf9\x58\x07\x75\xd0\x96"
+ "\xfb\x8f\x6d\x1e\x49\x0f\xd5\x31\x9e\xee\x31\xe6\x0a\x85\x93\x49"
+ "\x22\xcf\xd6\x1b\x40\x44\x63\x9c\x95\xaf\xf0\x44\x23\x51\x37\x92"
+ "\x0d\xa0\x22\x37\xb9\x6d\x13\xf9\x78\xba\x27\x27\xed\x08\x7e\x35"
+ "\xe4\xe2\x28\xeb\x0e\xbe\x3d\xce\x89\x93\x35\x84\x0f\xa0\xf9\x8d"
+ "\x94\xe9\x5a\xec\xd4\x0d\x1f\x5c\xbe\x6f\x8e\x6a\x4d\x10\x65\xbb"
+ "\xc7\x0b\xa0\xd5\x5c\x20\x80\x0b\x4a\x43\xa6\xe1\xb0\xe0\x56\x6a"
+ "\xde\x90\xe0\x6a\x45\xe7\xc2\xd2\x69\x9b\xc6\x62\x11\xe3\x2b\xa5"
+ "\x45\x98\xb0\x80\xd3\x57\x4d\x1f\x09\x83\x58\xd4\x4d\xa6\xc5\x95"
+ "\x87\x59\xb0\x58\x6c\x81\x49\xc5\x95\x18\x23\x1b\x6f\x10\x86\xa2"
+ "\xd9\x56\x19\x30\xec\xd3\x4a\x4b\xe8\x1c\x11\x37\xfb\x31\x60\x4d"
+ "\x4f\x9b\xc4\x95\xba\xda\x49\x43\x6c\xc7\x3d\x5b\x13\xf9\x91\xf8",
+ "\xcd\x2b\x83\xd5\x5b\x5a\x8e\x0b\x2e\x77\x0d\x97\xbf\xf7\xaa\xab" },
+ /* After setiv, ctr_low: 0xfffffffd */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x76\x8c\x18\x92",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x3d\x6f\x4e\xf6\xd2\x6f\x4e\xce\xa6\xb4\x4a\x9e\xcb\x57\x13\x90"
+ "\x51\x3b\xf6\xb2\x40\x55\x0c\x2c\xa2\x85\x44\x72\xf2\x90\xaf\x6b"
+ "\x86\x8c\x75\x2a\x9c\xd6\x52\x50\xee\xc6\x5f\x59\xbc\x8d\x18\xd7"
+ "\x87\xa5\x7f\xa0\x13\xd1\x5d\x54\x77\x30\xe2\x5d\x1b\x4f\x87\x9f"
+ "\x3a\x41\xcb\x6a\xdf\x44\x4f\xa2\x1a\xbc\xfb\x4b\x16\x67\xed\x59"
+ "\x65\xf0\x77\x48\xca\xfd\xf0\xb6\x90\x65\xca\x23\x09\xca\x83\x43"
+ "\x8f\xf0\x78\xb4\x5f\x96\x2a\xfd\x29\xae\xda\x62\x85\xc5\x87\x4b"
+ "\x2a\x3f\xba\xbe\x15\x5e\xb0\x4e\x8e\xe7\x66\xae\xb4\x80\x66\x90"
+ "\x10\x9d\x81\xb9\x64\xd3\x36\x00\xb2\x95\xa8\x7d\xaf\x54\xf8\xbd"
+ "\x8f\x7a\xb1\xa1\xde\x09\x0d\x10\xc8\x8e\x1e\x18\x2c\x1e\x73\x71"
+ "\x2f\x1e\xfd\x16\x6e\xbe\xe1\x3e\xe5\xb4\xb5\xbf\x03\x63\xf4\x5a"
+ "\x0d\xeb\xff\xe0\x61\x80\x67\x51\xb4\xa3\x1f\x18\xa5\xa9\xf1\x9a"
+ "\xeb\x2a\x7f\x56\xb6\x01\x88\x82\x78\xdb\xec\xb7\x92\xfd\xef\x56"
+ "\x55\xd3\x72\x35\xcd\xa4\x0d\x19\x6a\xb6\x79\x91\xd5\xcb\x0e\x3b"
+ "\xfb\xea\xa3\x55\x9f\x77\xfb\x75\xc2\x3e\x09\x02\x73\x7a\xff\x0e"
+ "\xa5\xf0\x83\x11\xeb\xe7\xff\x3b\xd0\xfd\x7a\x07\x53\x63\x43\x89"
+ "\xf5\x7b\xc4\x7d\x3b\x2c\x9b\xca\x1c\xf6\xb2\xab\x13\xf5\xc4\x2a"
+ "\xbf\x46\x77\x3b\x09\xdd\xd1\x80\xef\x55\x11\x3e\xd8\xe4\x42\x22",
+ "\xa3\x86\xa1\x5f\xe3\x4f\x3b\xed\x12\x23\xeb\x5c\xb8\x0c\xad\x4a" },
+ /* After setiv, ctr_low: 0xfffffffc */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xc8\xc3\xaf",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x33\x5f\xdc\x8d\x5d\x77\x7b\x78\xc1\x5b\x7b\xb3\xd9\x08\x9a\x0c"
+ "\xce\x63\x4e\xef\x19\xf8\x8c\x7a\xcb\x31\x39\x93\x69\x7a\x2c\x97"
+ "\x3a\xb4\x52\x45\x9e\x7b\x78\xbc\xa9\xad\x54\x7f\x88\xa6\xae\xd5"
+ "\xc0\x8b\x7a\xe4\x23\x6b\xb2\x29\x98\xea\x25\x7a\xae\x11\x0c\xc9"
+ "\xf3\x77\xa1\x74\x82\xde\x0c\xec\x68\xce\x94\xfd\xb0\xa0\xc5\x32"
+ "\xd6\xbb\xc3\xe7\xed\x3c\x6f\x0b\x53\x9d\xf3\xc8\xeb\x4e\xee\x99"
+ "\x19\xc7\x16\xd1\xa5\x59\x1d\xa9\xd3\xe6\x43\x52\x74\x61\x28\xe6"
+ "\xac\xd8\x47\x63\xc2\xb7\x53\x39\xc1\x9a\xb0\xa3\xa4\x26\x14\xd0"
+ "\x88\xa9\x8c\xc5\x6d\xe9\x21\x7c\xb9\xa5\xab\x67\xe3\x8d\xe9\x1d"
+ "\xe3\x1c\x7b\xcd\xa4\x12\x0c\xd7\xa6\x5d\x41\xcf\xdd\x3d\xfc\xbc"
+ "\x2a\xbb\xa2\x7a\x9c\x4b\x3a\x42\x6c\x98\x1d\x50\x99\x9c\xfb\xda"
+ "\x21\x09\x2a\x31\xff\x05\xeb\xa5\xf1\xba\x65\x78\xbe\x15\x8e\x84"
+ "\x35\xdd\x45\x29\xcc\xcd\x32\x2d\x27\xe9\xa8\x94\x4b\x16\x16\xcc"
+ "\xab\xf2\xec\xfb\xa0\xb5\x9d\x39\x81\x3e\xec\x5e\x3d\x13\xd1\x83"
+ "\x04\x79\x2d\xbb\x2c\x76\x76\x93\x28\x77\x27\x13\xdd\x1d\x3e\x89"
+ "\x3e\x37\x46\x4c\xb8\x34\xbe\xbf\x9f\x4f\x9f\x37\xff\x0c\xe6\x14"
+ "\x14\x66\x52\x41\x18\xa9\x39\x2b\x0c\xe5\x44\x04\xb0\x93\x06\x64"
+ "\x67\xf7\xa0\x19\xa7\x61\xcf\x03\x7b\xcb\xc8\xb3\x88\x28\xe4\xe7",
+ "\xe6\xe8\x0a\xe3\x72\xfc\xe0\x07\x69\x09\xf2\xeb\xbc\xc8\x6a\xf0" },
+ /* After setiv, ctr_low: 0xfffffffb */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x95\x1a\xe2",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\xd8\x32\x5a\xe3\x55\x8e\xb3\xc2\x51\x84\x2b\x09\x01\x5e\x6c\xfb"
+ "\x4a\xc4\x88\xa0\x33\xe7\x3e\xbf\xe5\x7c\xd2\x00\x4c\x1a\x85\x32"
+ "\x34\xec\x38\x9d\x18\x5f\xf1\x50\x61\x82\xee\xf3\x84\x5a\x84\x4e"
+ "\xeb\x29\x08\x4c\x7b\xb5\x27\xec\x7d\x79\x77\xd7\xa1\x68\x91\x32"
+ "\x2d\xf3\x38\xa9\xd6\x27\x16\xfb\x7d\x8b\x09\x5e\xcf\x1b\x74\x6d"
+ "\xcf\x51\x91\x91\xa1\xe7\x40\x19\x43\x7b\x0d\xa5\xa9\xa5\xf4\x2e"
+ "\x7f\x1c\xc7\xba\xa2\xea\x00\xdd\x24\x01\xa8\x66\x1e\x88\xf1\xf6"
+ "\x0c\x9a\xd6\x2b\xda\x3f\x3e\xb2\x98\xea\x89\xc7\xc6\x63\x27\xb7"
+ "\x6a\x48\x9a\xee\x1e\x70\xa0\xc8\xec\x3d\xc3\x3e\xb5\xf0\xc2\xb1"
+ "\xb9\x71\x1a\x69\x9d\xdd\x72\x1e\xfe\x72\xa0\x21\xb8\x9f\x18\x96"
+ "\x26\xcf\x89\x2e\x92\xf1\x02\x65\xa5\xb4\x2e\xb7\x4e\x12\xbd\xa0"
+ "\x48\xbe\xf6\x5c\xef\x7e\xf3\x0a\xcf\x9d\x1f\x1e\x14\x70\x3e\xa0"
+ "\x01\x0f\x14\xbf\x38\x10\x3a\x3f\x3f\xc2\x76\xe0\xb0\xe0\x7c\xc6"
+ "\x77\x6d\x7f\x69\x8e\xa0\x4b\x00\xc3\x9d\xf9\x0b\x7f\x8a\x8e\xd3"
+ "\x17\x58\x40\xfe\xaf\xf4\x16\x3a\x65\xff\xce\x85\xbb\x80\xfa\xb8"
+ "\x34\xc9\xef\x3a\xdd\x04\x46\xca\x8f\x70\x48\xbc\x1c\x71\x4d\x6a"
+ "\x17\x30\x32\x87\x2e\x2e\x54\x9e\x3f\x15\xed\x17\xd7\xa1\xcf\x6c"
+ "\x5d\x0f\x3c\xee\xf5\x96\xf1\x8f\x68\x1c\xbc\x27\xdc\x10\x3c\x3c",
+ "\x8c\x31\x06\xbb\xf8\x18\x2d\x9d\xd1\x0d\x03\x56\x2b\x28\x25\x9b" },
+ /* After setiv, ctr_low: 0xfffffffa */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x99\x9b\xda",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x7a\x74\x57\xe7\xc1\xb8\x7e\xcf\x91\x98\xf4\x1a\xa4\xdb\x4d\x2c"
+ "\x6e\xdc\x05\x0b\xd1\x16\xdf\x25\xa8\x1e\x42\xa6\xf9\x09\x36\xfb"
+ "\x02\x8a\x10\x7d\xa1\x07\x88\x40\xb7\x41\xfd\x64\xf6\xe3\x92\x20"
+ "\xfd\xc9\xde\xbd\x88\x46\xd3\x1f\x20\x14\x73\x86\x09\xb6\x68\x61"
+ "\x64\x90\xda\x24\xa8\x0f\x6a\x10\xc5\x01\xbf\x52\x8a\xee\x23\x44"
+ "\xd5\xb0\xd8\x68\x5e\x77\xc3\x62\xed\xcb\x3c\x1b\x0c\x1f\x13\x92"
+ "\x2c\x74\x6d\xee\x40\x1b\x6b\xfe\xbe\x3c\xb8\x02\xdd\x24\x9d\xd3"
+ "\x3d\x4e\xd3\x9b\x18\xfd\xd6\x8f\x95\xef\xa3\xbf\xa9\x2f\x33\xa8"
+ "\xc2\x37\x69\x58\x92\x42\x3a\x30\x46\x12\x1b\x2c\x04\xf0\xbf\xa9"
+ "\x79\x55\xcd\xac\x45\x36\x79\xc0\xb4\xb2\x5f\x82\x88\x49\xe8\xa3"
+ "\xbf\x33\x41\x7a\xcb\xc4\x11\x0e\xcc\x61\xed\xd1\x6b\x59\x5f\x9d"
+ "\x20\x6f\x85\x01\xd0\x16\x2a\x51\x1b\x79\x35\x42\x5e\x49\xdf\x6f"
+ "\x64\x68\x31\xac\x49\x34\xfb\x2b\xbd\xb1\xd9\x12\x4e\x4b\x16\xc5"
+ "\xa6\xfe\x15\xd3\xaf\xac\x51\x08\x95\x1f\x8c\xd2\x52\x37\x8b\x88"
+ "\xf3\x20\xe2\xf7\x09\x55\x82\x83\x1c\x38\x5f\x17\xfc\x37\x26\x21"
+ "\xb8\xf1\xfe\xa9\xac\x54\x1e\x53\x83\x53\x3f\x43\xe4\x67\x22\xd5"
+ "\x86\xec\xf2\xb6\x4a\x8b\x8a\x66\xea\xe0\x92\x50\x3b\x51\xe4\x00"
+ "\x25\x2a\x7a\x64\x14\xd6\x09\xe1\x6c\x75\x32\x28\x53\x5e\xb3\xab",
+ "\x5d\x4b\xb2\x8f\xfe\xa5\x7f\x01\x6d\x78\x6c\x13\x58\x08\xe4\x94" },
+ /* After setiv, ctr_low: 0xfffffff9 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xc4\x42\x97",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\xf5\xc1\xed\xb8\x7f\x55\x7b\xb5\x47\xed\xaa\x42\xd2\xda\x33\x41"
+ "\x4a\xe0\x36\x6d\x51\x28\x40\x9c\x35\xfb\x11\x65\x18\x83\x9c\xb5"
+ "\x02\xb2\xa7\xe5\x52\x27\xa4\xe8\x57\x3d\xb3\xf5\xea\xcb\x21\x07"
+ "\x67\xbe\xbe\x0f\xf6\xaa\x32\xa1\x4b\x5e\x79\x4f\x50\x67\xcd\x80"
+ "\xfc\xf1\x65\xf2\x6c\xd0\xdb\x17\xcc\xf9\x52\x93\xfd\x5e\xa6\xb9"
+ "\x5c\x9f\xa8\xc6\x36\xb7\x80\x80\x6a\xea\x62\xdc\x61\x13\x45\xbe"
+ "\xab\x8f\xd8\x99\x17\x51\x9b\x29\x04\x6e\xdb\x3e\x9f\x83\xc6\x35"
+ "\xb3\x90\xce\xcc\x74\xec\xcb\x04\x41\xac\xb1\x92\xde\x20\xb1\x67"
+ "\xb0\x38\x14\xaa\x7d\xee\x3c\xb2\xd3\xbb\x2f\x88\x0b\x73\xcf\x7b"
+ "\x69\xc1\x55\x5b\x2b\xf2\xd4\x38\x2b\x3c\xef\x04\xc9\x14\x7c\x31"
+ "\xd6\x61\x88\xa8\xb3\x8c\x69\xb4\xbc\xaa\x0d\x15\xd2\xd5\x27\x63"
+ "\xc4\xa4\x80\xe9\x2b\xe9\xd2\x34\xc9\x0e\x3f\x7b\xd3\x43\x0d\x47"
+ "\x5d\x37\x8e\x42\xa4\x4e\xef\xcd\xbb\x3a\x5b\xa4\xe1\xb0\x8d\x64"
+ "\xb7\x0b\x58\x52\xec\x55\xd0\xef\x23\xfe\xf2\x8d\xe0\xd1\x6a\x2c"
+ "\xaa\x1c\x03\xc7\x3e\x58\x4c\x61\x72\x07\xc6\xfd\x0e\xbc\xd4\x6b"
+ "\x99\x4f\x91\xda\xff\x6f\xea\x81\x0c\x76\x85\x5d\x0c\x7f\x1c\xb8"
+ "\x84\x8c\x2f\xe1\x36\x3e\x68\xa0\x57\xf5\xdf\x13\x0a\xd6\xe1\xcd"
+ "\xae\x23\x99\x4e\xed\x7a\x72\x1b\x7c\xe5\x65\xd1\xb7\xcf\x2f\x73",
+ "\x1e\x2f\xcf\x3c\x95\x9a\x29\xec\xd3\x37\x90\x8c\x84\x8a\xfb\x95" },
+ /* After setiv, ctr_low: 0xfffffff8 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xfa\xc7\x4f",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x14\x33\xc6\x9d\x04\xd3\x48\x29\x0c\x6a\x24\x27\xdf\x5f\x0a\xd2"
+ "\x71\xd6\xd0\x18\x04\xc0\x9f\x72\x0a\x60\xb7\x10\x52\x56\xf7\xae"
+ "\x64\xb0\x28\xd4\xfd\x25\x93\x8e\x67\x7e\xac\xc2\x93\xc7\x54\x2e"
+ "\x82\x93\x88\x6a\xb9\x8b\x73\xbc\x88\xec\x27\xdd\x4f\x9b\x21\x9e"
+ "\x77\x98\x70\x0b\xf4\xd8\x55\xfe\xf4\xc3\x3a\xcb\xca\x3a\xfb\xd4"
+ "\x52\x72\x2f\xf8\xac\xa9\x6a\xf5\x13\xab\x7a\x2e\x9f\x52\x41\xbd"
+ "\x87\x90\x68\xad\x17\xbd\x5a\xff\xc3\xc6\x10\x4d\xc1\xfe\xfc\x72"
+ "\x21\xb5\x53\x4a\x3f\xe0\x15\x9f\x29\x36\x23\xc0\x9a\x31\xb2\x0f"
+ "\xcd\x2f\xa6\xd0\xfc\xe6\x4d\xed\x68\xb3\x3d\x26\x67\xab\x40\xf0"
+ "\xab\xcf\x72\xc0\x50\xb1\x1e\x86\x38\xe2\xe0\x46\x3a\x2e\x3e\x1d"
+ "\x07\xd6\x9d\xe8\xfc\xa3\xe7\xac\xc9\xa0\xb3\x22\x05\xbc\xbf\xd2"
+ "\x63\x44\x66\xfc\xb4\x7b\xb4\x70\x7e\x96\xa9\x16\x1b\xb2\x7d\x93"
+ "\x44\x92\x5e\xbd\x16\x34\xa7\x11\xd0\xdf\x52\xad\x6f\xbd\x23\x3c"
+ "\x3d\x58\x16\xaf\x99\x8b\xbb\xa0\xdc\x3a\xff\x17\xda\x56\xba\x77"
+ "\xae\xc4\xb1\x51\xe2\x61\x4f\xf0\x66\x1b\x4c\xac\x79\x34\x1c\xfd"
+ "\x6c\x5f\x9a\x2c\x60\xfc\x47\x00\x5f\x2d\x81\xcc\xa9\xdd\x2b\xf4"
+ "\x5b\x53\x44\x61\xd4\x13\x5a\xf3\x93\xf0\xc9\x24\xd4\xe6\x60\x6f"
+ "\x78\x02\x0c\x75\x9d\x0d\x23\x97\x35\xe2\x06\x8a\x49\x5e\xe5\xbe",
+ "\x23\xc0\x4a\x2f\x98\x93\xca\xbd\x2e\x44\xde\x05\xcc\xe7\xf1\xf5" },
+ /* After setiv, ctr_low: 0xfffffff7 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4c\xa7\x1e\x02",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x51\x51\x64\x89\xeb\x9f\xf9\xd6\xb1\xa6\x73\x5f\xf1\x62\xb5\xe4"
+ "\x00\x80\xdb\x4c\x1c\xce\xe5\x00\xeb\xea\x6c\x57\xe4\x27\xfc\x71"
+ "\x08\x8c\xa1\xfc\x59\x1d\x07\x45\x3c\xc9\x4e\x0f\xb6\xea\x96\x90"
+ "\xae\xf7\x81\x1e\x7e\x6c\x5e\x50\xaf\x34\x3e\xa0\x55\x59\x8e\xe7"
+ "\xc1\xba\x48\xfa\x9e\x07\xf6\x6a\x24\x54\x3e\x9b\xa5\xfe\x31\x16"
+ "\x3d\x4d\x9c\xc4\xe1\xec\x26\xa0\x8b\x59\xa6\xf3\x94\xf8\x88\xda"
+ "\x1f\x88\x23\x5f\xfb\xfd\x79\xa2\xd3\x62\x30\x66\x69\xd9\x0d\x05"
+ "\xc0\x75\x4c\xb8\x48\x34\x1d\x97\xcf\x29\x6a\x12\x1c\x26\x54\x1d"
+ "\x80\xa9\x06\x74\x86\xff\xc6\xb4\x72\xee\x34\xe2\x56\x06\x6c\xf5"
+ "\x11\xe7\x26\x71\x47\x6b\x05\xbd\xe4\x0b\x40\x78\x84\x3c\xf9\xf2"
+ "\x78\x34\x2b\x3c\x5f\x0e\x4c\xfb\x17\x39\xdc\x59\x6b\xd1\x56\xac"
+ "\xe4\x1f\xb9\x19\xbc\xec\xb1\xd0\x6d\x47\x3b\x37\x4d\x0d\x6b\x65"
+ "\x7c\x70\xe9\xec\x58\xcc\x09\xd4\xd9\xbf\x9f\xe0\x6c\x7f\x60\x28"
+ "\xd8\xdf\x8e\xd1\x6a\x73\x42\xf3\x50\x01\x79\x68\x41\xc3\xba\x19"
+ "\x1e\x2d\x30\xc2\x81\x2c\x9f\x11\x8b\xd0\xdc\x31\x3b\x01\xfe\x53"
+ "\xa5\x11\x13\x22\x89\x40\xb9\x1b\x12\x89\xef\x9a\xcb\xa8\x03\x4f"
+ "\x54\x1a\x15\x6d\x11\xba\x05\x09\xd3\xdb\xbf\x05\x42\x3a\x5a\x27"
+ "\x3b\x34\x5c\x58\x8a\x5c\xa4\xc2\x28\xdc\xb2\x3a\xe9\x99\x01\xd6",
+ "\x30\xb2\xb5\x11\x8a\x3a\x8d\x70\x67\x71\x14\xde\xed\xa7\x43\xb5" },
+ /* After setiv, ctr_low: 0xfffffff6 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\xab\x9f\x3a",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x05\x72\x44\xa0\x99\x11\x1d\x2c\x4b\x03\x4f\x20\x92\x88\xbe\x55"
+ "\xee\x31\x2c\xd9\xc0\xc1\x64\x77\x79\xd7\x3e\xfa\x5a\x7d\xf0\x48"
+ "\xf8\xc8\xfe\x81\x8f\x89\x92\xa6\xc2\x07\xdc\x9f\x3f\xb2\xc8\xf2"
+ "\xf3\xe9\xe1\xd3\xed\x55\xb4\xab\xc3\x22\xed\x8f\x00\xde\x32\x95"
+ "\x91\xc0\xc5\xf3\xd3\x93\xf0\xee\x56\x14\x8f\x96\xff\xd0\x6a\xbd"
+ "\xfc\x57\xc2\xc3\x7b\xc1\x1d\x56\x48\x3f\xa6\xc7\x92\x47\xf7\x2f"
+ "\x0b\x85\x1c\xff\x87\x29\xe1\xbb\x9b\x14\x6c\xac\x51\x0a\xc0\x7b"
+ "\x22\x25\xb0\x48\x92\xad\x09\x09\x6e\x39\x8e\x96\x13\x05\x55\x92"
+ "\xbd\xd7\x5d\x95\x35\xdd\x8a\x9d\x05\x59\x60\xae\xbb\xc0\x85\x92"
+ "\x4c\x8b\xa0\x3f\xa2\x4a\xe5\x2e\xde\x85\x1a\x39\x10\x22\x11\x1b"
+ "\xdd\xcc\x96\xf4\x93\x97\xf5\x81\x85\xf3\x33\xda\xa1\x9a\xba\xfd"
+ "\xb8\xaf\x60\x81\x37\xf1\x02\x88\x54\x15\xeb\x21\xd1\x19\x1a\x1f"
+ "\x28\x9f\x02\x27\xca\xce\x97\xda\xdc\xd2\x0f\xc5\x0e\x2e\xdd\x4f"
+ "\x1d\x24\x62\xe4\x6e\x4a\xbe\x96\x95\x38\x0c\xe9\x26\x14\xf3\xf0"
+ "\x92\xbc\x97\xdc\x38\xeb\x64\xc3\x04\xc1\xa2\x6c\xad\xbd\xf8\x03"
+ "\xa0\xa4\x68\xaa\x9d\x1f\x09\xe6\x62\x95\xa2\x1c\x32\xef\x62\x28"
+ "\x7e\x54\x6d\x4b\x6a\xcc\x4a\xd0\x82\x47\x46\x0d\x45\x3c\x36\x03"
+ "\x86\x90\x44\x65\x18\xac\x19\x75\xe6\xba\xb1\x9a\xb4\x5d\x84\x9b",
+ "\x31\x22\x2b\x11\x6e\x2b\x94\x56\x37\x9d\xc3\xa5\xde\xe7\x6e\xc9" },
+ /* After setiv, ctr_low: 0xfffffff5 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xf6\x46\x77",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x6e\x32\xdb\x04\x32\x57\x15\x78\x0e\x4c\x70\x66\x5c\x91\x43\x0c"
+ "\x63\x73\xb8\x86\xad\xb0\xf1\x34\x0f\x0c\x7e\xd3\x4e\xcb\xc9\xea"
+ "\x19\x3c\xb8\x14\xd0\xab\x9e\x9b\x22\xda\x7a\x96\xa7\xf5\xa2\x99"
+ "\x58\xe3\xd6\x72\x0f\xf5\xdf\x88\xd1\x33\xb1\xe5\x03\x72\x62\x1c"
+ "\xa7\xf2\x67\x50\x0e\x70\xc3\x7a\x6c\x4a\x90\xba\x78\x9e\xd2\x0b"
+ "\x29\xd4\xc8\xa7\x57\x06\xf2\xf4\x01\x4b\x30\x53\xea\xf7\xde\xbf"
+ "\x1c\x12\x03\xcf\x9f\xcf\x80\x8b\x77\xfd\x73\x48\x79\x19\xbe\x38"
+ "\x75\x0b\x6d\x78\x7d\x79\x05\x98\x65\x3b\x35\x8f\x68\xff\x30\x7a"
+ "\x6e\xf7\x10\x9e\x11\x25\xc4\x95\x97\x7d\x92\x0f\xbf\x38\x95\xbd"
+ "\x5d\x2a\xf2\x06\x2c\xd9\x5a\x80\x91\x4e\x22\x7d\x5f\x69\x85\x03"
+ "\xa7\x5d\xda\x22\x09\x2b\x8d\x29\x67\x7c\x8c\xf6\xb6\x49\x20\x63"
+ "\xb9\xb6\x4d\xb6\x37\xa3\x7b\x19\xa4\x28\x90\x83\x55\x3d\x4e\x18"
+ "\xc8\x65\xbc\xd1\xe7\xb5\xcf\x65\x28\xea\x19\x11\x5c\xea\x83\x8c"
+ "\x44\x1f\xac\xc5\xf5\x3a\x4b\x1c\x2b\xbf\x76\xd8\x98\xdb\x50\xeb"
+ "\x64\x45\xae\xa5\x39\xb7\xc8\xdf\x5a\x73\x6d\x2d\x0f\x4a\x5a\x17"
+ "\x37\x66\x1c\x3d\x27\xd5\xd6\x7d\xe1\x08\x7f\xba\x4d\x43\xc2\x29"
+ "\xf7\xbe\x83\xec\xd0\x3b\x2e\x19\x9e\xf7\xbf\x1b\x16\x34\xd8\xfa"
+ "\x32\x17\x2a\x90\x55\x93\xd5\x3e\x14\x8d\xd6\xa1\x40\x45\x09\x52",
+ "\x89\xf2\xae\x78\x38\x8e\xf2\xd2\x52\xa8\xba\xb6\xf2\x5d\x7c\xfc" },
+ /* After setiv, ctr_low: 0xfffffff4 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\xb2\x9d\x4a",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x1d\xb8\x77\xcd\xcd\xfe\xde\x07\x97\xcb\x97\x3a\x4f\xa0\xd0\xe6"
+ "\xcc\xcf\x8b\x71\xd5\x65\x3d\xc4\x17\x52\xe7\x1d\x6a\x68\x4a\x77"
+ "\xca\x04\x4a\xef\x8e\x7e\xce\x79\xa1\x80\x0d\x9e\xd5\xf4\xce\x66"
+ "\x4d\x54\xb1\x09\xd1\xb6\xb0\x43\x28\xe8\x53\xe2\x24\x9c\x76\xc5"
+ "\x4d\x22\xf3\x6e\x13\xf3\xd7\xe0\x85\xb8\x9e\x0b\x17\x22\xc0\x79"
+ "\x2b\x72\x57\xaa\xbd\x43\xc3\xf7\xde\xce\x22\x41\x3c\x7e\x37\x1a"
+ "\x55\x2e\x36\x0e\x7e\xdc\xb3\xde\xd7\x33\x36\xc9\xc8\x56\x93\x51"
+ "\x68\x77\x9a\xb0\x08\x5c\x22\x35\xef\x5c\x9b\xbf\x3e\x20\x8a\x84"
+ "\x3d\xb3\x60\x10\xe1\x97\x30\xd7\xb3\x6f\x40\x5a\x2c\xe0\xe5\x52"
+ "\x19\xb6\x2b\xed\x6e\x8e\x18\xb4\x8d\x78\xbd\xc4\x9f\x4f\xbd\x82"
+ "\x98\xd6\x71\x3d\x71\x5b\x78\x73\xee\x8e\x4b\x37\x88\x9e\x21\xca"
+ "\x00\x6c\xc2\x96\x8d\xf0\xcd\x09\x58\x54\x5a\x58\x59\x8e\x9b\xf8"
+ "\x72\x93\xd7\xa0\xf9\xc4\xdc\x48\x89\xaa\x31\x95\xda\x4e\x2f\x79"
+ "\x1e\x37\x49\x92\x2e\x32\x2e\x76\x54\x2a\x64\xa8\x96\x67\xe9\x75"
+ "\x10\xa6\xeb\xad\xc6\xa8\xec\xb7\x18\x0a\x32\x26\x8d\x6e\x03\x74"
+ "\x0e\x1f\xfc\xde\x76\xff\x6e\x96\x42\x2d\x80\x0a\xc6\x78\x70\xc4"
+ "\xd8\x56\x7b\xa6\x38\x2f\xf6\xc0\x9b\xd7\x21\x6e\x88\x5d\xc8\xe5"
+ "\x02\x6a\x09\x1e\xb3\x46\x44\x80\x82\x5b\xd1\x66\x06\x61\x4f\xb8",
+ "\x16\x0e\x73\xa3\x14\x43\xdb\x15\x9c\xb0\x0d\x30\x6d\x9b\xe1\xb1" },
+ /* After setiv, ctr_low: 0xfffffff3 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\xef\x44\x07",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x42\x71\x54\xe2\xdb\x50\x5d\x3c\x10\xbd\xf8\x60\xbd\xdb\x26\x14"
+ "\x7d\x13\x59\x98\x28\xfb\x43\x42\xca\x72\xe6\xd8\x58\x00\xa2\x1b"
+ "\x6a\x61\xb4\x3a\x80\x6b\x9e\x14\xbd\x11\x33\xab\xe9\xb9\x91\x95"
+ "\xd7\x5d\xc3\x98\x1f\x7f\xcb\xa8\xf0\xec\x31\x26\x51\xea\x2e\xdf"
+ "\xd9\xde\x70\xf5\x84\x27\x3a\xac\x22\x05\xb9\xce\x2a\xfb\x2a\x83"
+ "\x1e\xce\x0e\xb2\x31\x35\xc6\xe6\xc0\xd7\xb0\x5f\xf5\xca\xdb\x13"
+ "\xa7\xfe\x4f\x85\xa3\x4f\x94\x5c\xc1\x04\x12\xde\x6f\xa1\xdb\x41"
+ "\x59\x82\x22\x22\x65\x97\x6d\xc8\x67\xab\xf3\x90\xeb\xa4\x00\xb3"
+ "\x7d\x94\x3d\x7b\x2a\xe2\x85\x36\x87\x16\xb8\x19\x92\x02\xe0\x43"
+ "\x42\x85\xa1\xe6\xb8\x11\x30\xcc\x2c\xd8\x63\x09\x0e\x53\x5f\xa3"
+ "\xe0\xd4\xee\x0e\x04\xee\x65\x61\x96\x84\x42\x0c\x68\x8d\xb7\x48"
+ "\xa3\x02\xb4\x82\x69\xf2\x35\xe4\xce\x3b\xe3\x44\xce\xad\x49\x32"
+ "\xab\xda\x04\xea\x06\x60\xa6\x2a\x7d\xee\x0f\xb8\x95\x90\x22\x62"
+ "\x9c\x78\x59\xd3\x7b\x61\x02\x65\x63\x96\x9f\x67\x50\xa0\x61\x43"
+ "\x53\xb2\x3f\x22\xed\x8c\x42\x39\x97\xd9\xbc\x6e\x81\xb9\x21\x97"
+ "\xc6\x5b\x68\xd7\x7f\xd0\xc5\x4a\xfb\x74\xc4\xfd\x9a\x2a\xb8\x9b"
+ "\x48\xe0\x00\xea\x6d\xf5\x30\x26\x61\x8f\xa5\x45\x70\xc9\x3a\xea"
+ "\x6d\x19\x11\x57\x0f\x21\xe6\x0a\x53\x94\xe3\x0c\x99\xb0\x2f\xc5",
+ "\x92\x92\x89\xcd\x4f\x3c\x6d\xbc\xe8\xb3\x70\x14\x5b\x3c\x12\xe4" },
+ /* After setiv, ctr_low: 0xfffffff2 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xe3\xc5\x3f",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\x41\xc3\xcb\xd7\x6e\xde\x2a\xc6\x15\x05\xc6\xba\x27\xae\xcd\x37"
+ "\xc0\xe5\xbf\xb9\x5c\xdc\xd6\xad\x1a\xe1\x35\x7c\xc0\x85\x85\x51"
+ "\x8c\x98\x06\xc0\x72\x43\x71\x7a\x2d\x7c\x81\x3c\xe7\xd6\x32\x8e"
+ "\x22\x2b\x46\x95\x6a\xde\x45\x40\x56\xe9\x63\x32\x68\xbf\xb6\x78"
+ "\xb7\x86\x00\x9d\x2c\x9e\xed\x67\xc1\x9b\x09\x9e\xd9\x0a\x56\xcb"
+ "\x57\xc9\x48\x14\x23\x4e\x97\x04\xb5\x85\x25\x1d\xcb\x1a\x79\x9b"
+ "\x54\x06\x95\xad\x16\x81\x84\x3a\x38\xec\x41\x90\x2a\xfa\x50\xe0"
+ "\xb9\x20\xa6\xeb\xfe\x2e\x5c\xa1\xf6\x3c\x69\x4c\xce\xf8\x30\xe0"
+ "\x87\x68\xa2\x3a\x9d\xad\x75\xd4\xa5\x6b\x0a\x90\x65\xa2\x27\x64"
+ "\x9d\xf5\xa0\x6f\xd0\xd3\x62\xa5\x2d\xae\x02\x89\xb4\x1a\xfa\x32"
+ "\x9b\xa0\x44\xdd\x50\xde\xaf\x41\xa9\x89\x1e\xb0\x41\xbc\x9c\x41"
+ "\xb0\x35\x5e\xf1\x9a\xd9\xab\x57\x53\x21\xca\x39\xfc\x8b\xb4\xd4"
+ "\xb2\x19\x8a\xe9\xb2\x24\x1e\xce\x2e\x19\xb0\xd2\x93\x30\xc4\x70"
+ "\xe2\xf8\x6a\x8a\x99\x3b\xed\x71\x7e\x9e\x98\x99\x2a\xc6\xdd\xcf"
+ "\x43\x32\xdb\xfb\x27\x22\x89\xa4\xc5\xe0\xa2\x94\xe9\xcf\x9d\x48"
+ "\xab\x3f\xfa\x4f\x75\x63\x46\xdd\xfe\xfa\xf0\xbf\x6e\xa1\xf9\xca"
+ "\xb1\x77\x79\x35\x6c\x33\xe1\x57\x68\x50\xe9\x78\x4e\xe4\xe2\xf0"
+ "\xcf\xe4\x23\xde\xf4\xa7\x34\xb3\x44\x97\x38\xd2\xbd\x27\x44\x0e",
+ "\x75\x0a\x41\x3b\x87\xe3\xc7\xf6\xd6\xe3\xab\xfa\x4b\xbe\x2e\x56" },
+ /* After setiv, ctr_low: 0xfffffff1 */
+ { GCRY_CIPHER_AES256,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5a\xbe\x1c\x72",
+ 16,
+ "", 0,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 288,
+ "\xf1\x3c\x7a\xa4\xa9\xaf\xe7\x49\x19\x7d\xad\x50\xc1\x6a\x84\x87"
+ "\xf5\x69\xe4\xe5\xc2\x0a\x90\x33\xc3\xeb\x76\x63\x5f\x9b\x1d\xf9"
+ "\x53\x4a\x2a\x6d\x6b\x61\xe0\x5d\xed\xcb\x98\x0d\xf2\x57\x33\x12"
+ "\xd1\x44\xaa\x7a\x7e\x4e\x41\x0e\xe6\xa7\x9f\x17\x92\x28\x91\xad"
+ "\xca\xce\xf2\xa8\x73\x4a\xad\x89\x62\x73\x0b\x9a\x68\x91\xa8\x11"
+ "\x44\x01\xfd\x57\xe4\xf8\x84\x55\x2b\x66\xdb\xb9\xd6\xee\x83\xe5"
+ "\x57\xea\x5c\x6a\x23\x87\xdd\x0a\x45\x63\xb4\x0c\x8f\xc5\x9f\x22"
+ "\xf3\x4f\x4e\x6f\x7b\x14\x62\xf7\x80\x59\x4a\xc5\xc8\xae\x8a\x6f"
+ "\x5e\xe3\x1e\xe6\xae\xec\x99\x77\x6b\x88\x14\xe3\x58\x88\x61\x74"
+ "\x38\x91\xa1\x32\xb8\xd2\x39\x6b\xe2\xcb\x8e\x77\xde\x92\x36\x78"
+ "\xad\x50\xcf\x08\xb8\xfa\x29\x59\xb4\x68\x1b\x23\x10\x57\x32\x92"
+ "\xf8\xec\xe1\x97\xdb\x30\x85\x22\xb5\x68\x2f\xf2\x98\xda\x06\xee"
+ "\x65\x02\xe7\xf9\xc8\xc1\xca\x8f\xd3\xed\x4a\x3c\x09\xdd\xde\x64"
+ "\xd9\x85\x17\x2c\x62\x41\x35\x24\xed\x6b\x87\x78\x1e\xb5\x7a\x9b"
+ "\xa3\x90\xa3\x99\xc7\x39\x51\x10\xb7\x6a\x12\x3b\x64\xfe\x32\x3c"
+ "\xb6\x84\x9a\x3f\x95\xd3\xcb\x22\x69\x9c\xf9\xb7\xc2\x8b\xf4\x55"
+ "\x68\x60\x11\x20\xc5\x3e\x0a\xc0\xba\x00\x0e\x88\x96\x66\xfa\xf0"
+ "\x75\xbc\x2b\x9c\xff\xc5\x33\x7b\xaf\xb2\xa6\x34\x78\x44\x9c\xa7",
+ "\x01\x24\x0e\x17\x17\xe5\xfc\x90\x07\xfa\x78\xd5\x5d\x66\xa3\xf5" },
+ };
+
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_GCM_DATA_LEN];
+ unsigned char tag[GCRY_GCM_BLOCK_LEN];
+ int i, keylen;
+ gcry_error_t err = 0;
+ size_t pos, poslen, taglen2;
+ int byteNum;
+
+ if (verbose)
+ fprintf (stderr, " Starting GCM checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking GCM mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_GCM, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_GCM, 0);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-gcm, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+ if (err)
+ {
+ fail ("cipher-gcm, gcryctl_get_taglen failed (tv %d): %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ if (taglen2 != GCRY_GCM_BLOCK_LEN)
+ {
+ fail ("cipher-gcm, gcryctl_get_taglen returned bad length"
+ " (tv %d): got=%zu want=%d\n",
+ i, taglen2, GCRY_GCM_BLOCK_LEN);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ for (pos = 0; pos < tv[i].aadlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].aadlen) ? step : tv[i].aadlen - pos;
+
+ err = gcry_cipher_authenticate(hde, tv[i].aad + pos, poslen);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_authenticate (%d) (%lu:%d) failed: "
+ "%s\n", i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ err = gcry_cipher_authenticate(hdd, tv[i].aad + pos, poslen);
+ if (err)
+ {
+ fail ("aes-gcm, de gcry_cipher_authenticate (%d) (%lu:%d) failed: "
+ "%s\n", i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ for (pos = 0; pos < tv[i].inlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos;
+
+ err = gcry_cipher_encrypt (hde, out + pos, poslen,
+ tv[i].plaintext + pos, poslen);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_encrypt (%d) (%lu:%d) failed: %s\n",
+ i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].out, out, tv[i].inlen))
+ fail ("aes-gcm, encrypt mismatch entry %d (step %d)\n", i, step);
+
+ for (pos = 0; pos < tv[i].inlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos;
+
+ err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_decrypt (%d) (%lu:%d) failed: %s\n",
+ i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].plaintext, out, tv[i].inlen))
+ fail ("aes-gcm, decrypt mismatch entry %d (step %d)\n", i, step);
+
+ taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN;
+
+ err = gcry_cipher_gettag (hde, out, taglen2);
+ if (err)
+ {
+ if (tv[i].should_fail)
+ goto next_tv;
+
+ fail ("aes-gcm, gcry_cipher_gettag(%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].tag, out, taglen2))
+ fail ("aes-gcm, encrypt tag mismatch entry %d\n", i);
+
+ err = gcry_cipher_checktag (hdd, out, taglen2);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_checktag(%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_reset(hde);
+ if (!err)
+ err = gcry_cipher_reset(hdd);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_reset (%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* gcry_cipher_reset clears the IV */
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* this time we authenticate, encrypt and decrypt one byte at a time */
+ for (byteNum = 0; byteNum < tv[i].aadlen; ++byteNum)
+ {
+ err = gcry_cipher_authenticate(hde, tv[i].aad + byteNum, 1);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_authenticate (%d) (byte-buf) failed: "
+ "%s\n", i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ err = gcry_cipher_authenticate(hdd, tv[i].aad + byteNum, 1);
+ if (err)
+ {
+ fail ("aes-gcm, de gcry_cipher_authenticate (%d) (byte-buf) "
+ "failed: %s\n", i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
+ {
+ err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+ (tv[i].plaintext) + byteNum,
+ 1);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].out, out, tv[i].inlen))
+ fail ("aes-gcm, encrypt mismatch entry %d, (byte-buf)\n", i);
+
+ /* Test output to larger than 16-byte buffer. */
+ taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN + 1;
+
+ err = gcry_cipher_gettag (hde, tag, taglen2);
+ if (err)
+ {
+ if (tv[i].should_fail)
+ goto next_tv;
+
+ fail ("aes-gcm, gcry_cipher_gettag(%d, %lu) (byte-buf) failed: %s\n",
+ i, (unsigned long) taglen2, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN;
+
+ if (memcmp (tv[i].tag, tag, taglen2))
+ fail ("aes-gcm, encrypt tag mismatch entry %d, (byte-buf)\n", i);
+
+ for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
+ {
+ err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].plaintext, out, tv[i].inlen))
+ fail ("aes-gcm, decrypt mismatch entry %d\n", i);
+
+ err = gcry_cipher_checktag (hdd, tag, taglen2);
+ if (err)
+ {
+ fail ("aes-gcm, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_checktag (hdd, tag, 1);
+ if (!err)
+ {
+ fail ("aes-gcm, gcry_cipher_checktag(%d) did not fail for invalid "
+ " tag length of '%d'\n", i, 1);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ err = gcry_cipher_checktag (hdd, tag, 17);
+ if (!err)
+ {
+ fail ("aes-gcm, gcry_cipher_checktag(%d) did not fail for invalid "
+ " tag length of '%d'\n", i, 17);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (tv[i].should_fail)
+ {
+ fail ("aes-gcm, negative test succeeded %d\n", i);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ next_tv:
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed GCM checks.\n");
+}
+
+
+static void
+check_gcm_cipher (void)
+{
+ /* Large buffers, no splitting. */
+ _check_gcm_cipher(0xffffffff);
+ /* Split input to one byte buffers. */
+ _check_gcm_cipher(1);
+ /* Split input to 7 byte buffers. */
+ _check_gcm_cipher(7);
+ /* Split input to 15 byte buffers. */
+ _check_gcm_cipher(15);
+ /* Split input to 16 byte buffers. */
+ _check_gcm_cipher(16);
+ /* Split input to 17 byte buffers. */
+ _check_gcm_cipher(17);
+}
+
+
+static void
+_check_eax_cipher (unsigned int step)
+{
+ static const struct tv
+ {
+ int algo;
+ char key[MAX_DATA_LEN];
+ char nonce[MAX_DATA_LEN];
+ int noncelen;
+ unsigned char header[MAX_DATA_LEN];
+ int headerlen;
+ unsigned char plaintext[MAX_DATA_LEN];
+ int inlen;
+ char out[MAX_DATA_LEN];
+ char tag[MAX_DATA_LEN];
+ int taglen;
+ int should_fail;
+ } tv[] =
+ {
+ /* Test vectors from http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf */
+ { GCRY_CIPHER_AES,
+ "\x23\x39\x52\xDE\xE4\xD5\xED\x5F\x9B\x9C\x6D\x6F\xF8\x0F\xF4\x78",
+ "\x62\xEC\x67\xF9\xC3\xA4\xA4\x07\xFC\xB2\xA8\xC4\x90\x31\xA8\xB3", 16,
+ "\x6B\xFB\x91\x4F\xD0\x7E\xAE\x6B", 8,
+ "",
+ 0,
+ "",
+ "\xE0\x37\x83\x0E\x83\x89\xF2\x7B\x02\x5A\x2D\x65\x27\xE7\x9D\x01", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\x91\x94\x5D\x3F\x4D\xCB\xEE\x0B\xF4\x5E\xF5\x22\x55\xF0\x95\xA4",
+ "\xBE\xCA\xF0\x43\xB0\xA2\x3D\x84\x31\x94\xBA\x97\x2C\x66\xDE\xBD", 16,
+ "\xFA\x3B\xFD\x48\x06\xEB\x53\xFA", 8,
+ "\xF7\xFB",
+ 2,
+ "\x19\xDD",
+ "\x5C\x4C\x93\x31\x04\x9D\x0B\xDA\xB0\x27\x74\x08\xF6\x79\x67\xE5", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\x01\xF7\x4A\xD6\x40\x77\xF2\xE7\x04\xC0\xF6\x0A\xDA\x3D\xD5\x23",
+ "\x70\xC3\xDB\x4F\x0D\x26\x36\x84\x00\xA1\x0E\xD0\x5D\x2B\xFF\x5E", 16,
+ "\x23\x4A\x34\x63\xC1\x26\x4A\xC6", 8,
+ "\x1A\x47\xCB\x49\x33",
+ 5,
+ "\xD8\x51\xD5\xBA\xE0",
+ "\x3A\x59\xF2\x38\xA2\x3E\x39\x19\x9D\xC9\x26\x66\x26\xC4\x0F\x80", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\xD0\x7C\xF6\xCB\xB7\xF3\x13\xBD\xDE\x66\xB7\x27\xAF\xD3\xC5\xE8",
+ "\x84\x08\xDF\xFF\x3C\x1A\x2B\x12\x92\xDC\x19\x9E\x46\xB7\xD6\x17", 16,
+ "\x33\xCC\xE2\xEA\xBF\xF5\xA7\x9D", 8,
+ "\x48\x1C\x9E\x39\xB1",
+ 5,
+ "\x63\x2A\x9D\x13\x1A",
+ "\xD4\xC1\x68\xA4\x22\x5D\x8E\x1F\xF7\x55\x93\x99\x74\xA7\xBE\xDE", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\x35\xB6\xD0\x58\x00\x05\xBB\xC1\x2B\x05\x87\x12\x45\x57\xD2\xC2",
+ "\xFD\xB6\xB0\x66\x76\xEE\xDC\x5C\x61\xD7\x42\x76\xE1\xF8\xE8\x16", 16,
+ "\xAE\xB9\x6E\xAE\xBE\x29\x70\xE9", 8,
+ "\x40\xD0\xC0\x7D\xA5\xE4",
+ 6,
+ "\x07\x1D\xFE\x16\xC6\x75",
+ "\xCB\x06\x77\xE5\x36\xF7\x3A\xFE\x6A\x14\xB7\x4E\xE4\x98\x44\xDD", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\xBD\x8E\x6E\x11\x47\x5E\x60\xB2\x68\x78\x4C\x38\xC6\x2F\xEB\x22",
+ "\x6E\xAC\x5C\x93\x07\x2D\x8E\x85\x13\xF7\x50\x93\x5E\x46\xDA\x1B", 16,
+ "\xD4\x48\x2D\x1C\xA7\x8D\xCE\x0F", 8,
+ "\x4D\xE3\xB3\x5C\x3F\xC0\x39\x24\x5B\xD1\xFB\x7D",
+ 12,
+ "\x83\x5B\xB4\xF1\x5D\x74\x3E\x35\x0E\x72\x84\x14",
+ "\xAB\xB8\x64\x4F\xD6\xCC\xB8\x69\x47\xC5\xE1\x05\x90\x21\x0A\x4F", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\x7C\x77\xD6\xE8\x13\xBE\xD5\xAC\x98\xBA\xA4\x17\x47\x7A\x2E\x7D",
+ "\x1A\x8C\x98\xDC\xD7\x3D\x38\x39\x3B\x2B\xF1\x56\x9D\xEE\xFC\x19", 16,
+ "\x65\xD2\x01\x79\x90\xD6\x25\x28", 8,
+ "\x8B\x0A\x79\x30\x6C\x9C\xE7\xED\x99\xDA\xE4\xF8\x7F\x8D\xD6\x16\x36",
+ 17,
+ "\x02\x08\x3E\x39\x79\xDA\x01\x48\x12\xF5\x9F\x11\xD5\x26\x30\xDA\x30",
+ "\x13\x73\x27\xD1\x06\x49\xB0\xAA\x6E\x1C\x18\x1D\xB6\x17\xD7\xF2", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\x5F\xFF\x20\xCA\xFA\xB1\x19\xCA\x2F\xC7\x35\x49\xE2\x0F\x5B\x0D",
+ "\xDD\xE5\x9B\x97\xD7\x22\x15\x6D\x4D\x9A\xFF\x2B\xC7\x55\x98\x26", 16,
+ "\x54\xB9\xF0\x4E\x6A\x09\x18\x9A", 8,
+ "\x1B\xDA\x12\x2B\xCE\x8A\x8D\xBA\xF1\x87\x7D\x96\x2B\x85\x92\xDD"
+ "\x2D\x56",
+ 18,
+ "\x2E\xC4\x7B\x2C\x49\x54\xA4\x89\xAF\xC7\xBA\x48\x97\xED\xCD\xAE"
+ "\x8C\xC3",
+ "\x3B\x60\x45\x05\x99\xBD\x02\xC9\x63\x82\x90\x2A\xEF\x7F\x83\x2A", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\xA4\xA4\x78\x2B\xCF\xFD\x3E\xC5\xE7\xEF\x6D\x8C\x34\xA5\x61\x23",
+ "\xB7\x81\xFC\xF2\xF7\x5F\xA5\xA8\xDE\x97\xA9\xCA\x48\xE5\x22\xEC", 16,
+ "\x89\x9A\x17\x58\x97\x56\x1D\x7E", 8,
+ "\x6C\xF3\x67\x20\x87\x2B\x85\x13\xF6\xEA\xB1\xA8\xA4\x44\x38\xD5"
+ "\xEF\x11",
+ 18,
+ "\x0D\xE1\x8F\xD0\xFD\xD9\x1E\x7A\xF1\x9F\x1D\x8E\xE8\x73\x39\x38"
+ "\xB1\xE8",
+ "\xE7\xF6\xD2\x23\x16\x18\x10\x2F\xDB\x7F\xE5\x5F\xF1\x99\x17\x00", 16,
+ 0
+ },
+ { GCRY_CIPHER_AES,
+ "\x83\x95\xFC\xF1\xE9\x5B\xEB\xD6\x97\xBD\x01\x0B\xC7\x66\xAA\xC3",
+ "\x22\xE7\xAD\xD9\x3C\xFC\x63\x93\xC5\x7E\xC0\xB3\xC1\x7D\x6B\x44", 16,
+ "\x12\x67\x35\xFC\xC3\x20\xD2\x5A", 8,
+ "\xCA\x40\xD7\x44\x6E\x54\x5F\xFA\xED\x3B\xD1\x2A\x74\x0A\x65\x9F"
+ "\xFB\xBB\x3C\xEA\xB7",
+ 21,
+ "\xCB\x89\x20\xF8\x7A\x6C\x75\xCF\xF3\x96\x27\xB5\x6E\x3E\xD1\x97"
+ "\xC5\x52\xD2\x95\xA7",
+ "\xCF\xC4\x6A\xFC\x25\x3B\x46\x52\xB1\xAF\x37\x95\xB1\x24\xAB\x6E", 16,
+ 0
+ },
+ /* Negative test for bad tag. */
+ { GCRY_CIPHER_AES,
+ "\x23\x39\x52\xDE\xE4\xD5\xED\x5F\x9B\x9C\x6D\x6F\xF8\x0F\xF4\x78",
+ "\x62\xEC\x67\xF9\xC3\xA4\xA4\x07\xFC\xB2\xA8\xC4\x90\x31\xA8\xB3", 16,
+ "\x6B\xFB\x91\x4F\xD0\x7E\xAE\x6B", 8,
+ "",
+ 0,
+ "",
+ "\x00\x37\x83\x0E\x83\x89\xF2\x7B\x02\x5A\x2D\x65\x27\xE7\x9D\x01", 16,
+ 1
+ },
+ /* Test vectors from libtomcrypt. */
+ {
+ GCRY_CIPHER_AES,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ "", 0,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x9a\xd0\x7e\x7d\xbf\xf3\x01\xf5\x05\xde\x59\x6b\x96\x15\xdf\xff", 16,
+ 0
+ },
+ {
+ GCRY_CIPHER_AES,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16,
+ "", 0,
+ "",
+ 0,
+ "",
+ "\x1c\xe1\x0d\x3e\xff\xd4\xca\xdb\xe2\xe4\x4b\x58\xd6\x0a\xb9\xec", 16,
+ 0
+ },
+ {
+ GCRY_CIPHER_AES,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ "", 0,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16,
+ "",
+ 0,
+ "",
+ "\x3a\x69\x8f\x7a\x27\x0e\x51\xb0\xf6\x5b\x3d\x3e\x47\x19\x3c\xff", 16,
+ 0
+ },
+ {
+ GCRY_CIPHER_AES,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ 32,
+ "\x29\xd8\x78\xd1\xa3\xbe\x85\x7b\x6f\xb8\xc8\xea\x59\x50\xa7\x78"
+ "\x33\x1f\xbf\x2c\xcf\x33\x98\x6f\x35\xe8\xcf\x12\x1d\xcb\x30\xbc",
+ "\x4f\xbe\x03\x38\xbe\x1c\x8c\x7e\x1d\x7a\xe7\xe4\x5b\x92\xc5\x87", 16,
+ 0
+ },
+ {
+ GCRY_CIPHER_AES,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e", 15,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d", 14,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c",
+ 29,
+ "\xdd\x25\xc7\x54\xc5\xb1\x7c\x59\x28\xb6\x9b\x73\x15\x5f\x7b\xb8"
+ "\x88\x8f\xaf\x37\x09\x1a\xd9\x2c\x8a\x24\xdb\x86\x8b",
+ "\x0d\x1a\x14\xe5\x22\x24\xff\xd2\x3a\x05\xfa\x02\xcd\xef\x52\xda", 16,
+ 0
+ },
+ };
+
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ unsigned char tag[16];
+ int i, keylen;
+ gcry_error_t err = 0;
+ size_t pos, poslen, taglen2;
+ int byteNum;
+
+ if (verbose)
+ fprintf (stderr, " Starting EAX checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking EAX mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_EAX, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_EAX, 0);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-eax, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+ if (err)
+ {
+ fail ("cipher-eax, gcryctl_get_taglen failed (tv %d): %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ if (taglen2 != 16)
+ {
+ fail ("cipher-eax, gcryctl_get_taglen returned bad length"
+ " (tv %d): got=%zu want=%d\n",
+ i, taglen2, 16);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ for (pos = 0; pos < tv[i].headerlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].headerlen) ?
+ step : tv[i].headerlen - pos;
+
+ err = gcry_cipher_authenticate(hde, tv[i].header + pos, poslen);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_authenticate (%d) (%lu:%d) failed: "
+ "%s\n", i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ err = gcry_cipher_authenticate(hdd, tv[i].header + pos, poslen);
+ if (err)
+ {
+ fail ("aes-eax, de gcry_cipher_authenticate (%d) (%lu:%d) failed: "
+ "%s\n", i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ for (pos = 0; pos < tv[i].inlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos;
+
+ err = gcry_cipher_encrypt (hde, out + pos, poslen,
+ tv[i].plaintext + pos, poslen);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_encrypt (%d) (%lu:%d) failed: %s\n",
+ i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].out, out, tv[i].inlen))
+ fail ("aes-eax, encrypt mismatch entry %d (step %d)\n", i, step);
+
+ for (pos = 0; pos < tv[i].inlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos;
+
+ err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_decrypt (%d) (%lu:%d) failed: %s\n",
+ i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].plaintext, out, tv[i].inlen))
+ fail ("aes-eax, decrypt mismatch entry %d (step %d)\n", i, step);
+
+ taglen2 = tv[i].taglen ? tv[i].taglen : 16;
+
+ err = gcry_cipher_gettag (hde, out, taglen2);
+ if (err)
+ {
+ if (tv[i].should_fail)
+ goto next_tv;
+
+ fail ("aes-eax, gcry_cipher_gettag(%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if ((memcmp (tv[i].tag, out, taglen2) != 0) ^ tv[i].should_fail)
+ fail ("aes-eax, encrypt tag mismatch entry %d\n", i);
+
+ err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2);
+ if (err)
+ {
+ if (tv[i].should_fail)
+ goto next_tv;
+
+ fail ("aes-eax, gcry_cipher_checktag(%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_reset(hde);
+ if (!err)
+ err = gcry_cipher_reset(hdd);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_reset (%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* gcry_cipher_reset clears the IV */
+ err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* this time we authenticate, encrypt and decrypt one byte at a time */
+ for (byteNum = 0; byteNum < tv[i].headerlen; ++byteNum)
+ {
+ err = gcry_cipher_authenticate(hde, tv[i].header + byteNum, 1);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_authenticate (%d) (byte-buf) failed: "
+ "%s\n", i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ err = gcry_cipher_authenticate(hdd, tv[i].header + byteNum, 1);
+ if (err)
+ {
+ fail ("aes-eax, de gcry_cipher_authenticate (%d) (byte-buf) "
+ "failed: %s\n", i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
+ {
+ err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+ (tv[i].plaintext) + byteNum,
+ 1);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].out, out, tv[i].inlen))
+ fail ("aes-eax, encrypt mismatch entry %d, (byte-buf)\n", i);
+
+ /* Test output to larger than 16-byte buffer. */
+ taglen2 = tv[i].taglen ? tv[i].taglen : 16 + 1;
+
+ err = gcry_cipher_gettag (hde, tag, taglen2);
+ if (err)
+ {
+ if (tv[i].should_fail)
+ goto next_tv;
+
+ fail ("aes-eax, gcry_cipher_gettag(%d, %lu) (byte-buf) failed: %s\n",
+ i, (unsigned long) taglen2, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ taglen2 = tv[i].taglen ? tv[i].taglen : 16;
+
+ if ((memcmp (tv[i].tag, tag, taglen2) != 0) ^ tv[i].should_fail)
+ fail ("aes-eax, encrypt tag mismatch entry %d, (byte-buf)\n", i);
+
+ for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
+ {
+ err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+ if (err)
+ {
+ fail ("aes-eax, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].plaintext, out, tv[i].inlen))
+ fail ("aes-eax, decrypt mismatch entry %d\n", i);
+
+ err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2);
+ if (err)
+ {
+ if (tv[i].should_fail)
+ goto next_tv;
+
+ fail ("aes-eax, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_checktag (hdd, tag, 17);
+ if (!err)
+ {
+ fail ("aes-eax, gcry_cipher_checktag(%d) did not fail for invalid "
+ " tag length of '%d'\n", i, 17);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (tv[i].should_fail)
+ {
+ fail ("aes-eax, negative test succeeded %d\n", i);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ next_tv:
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed EAX checks.\n");
+}
+
+
+static void
+check_eax_cipher (void)
+{
+ /* Large buffers, no splitting. */
+ _check_eax_cipher(0xffffffff);
+ /* Split input to one byte buffers. */
+ _check_eax_cipher(1);
+ /* Split input to 7 byte buffers. */
+ _check_eax_cipher(7);
+ /* Split input to 16 byte buffers. */
+ _check_eax_cipher(16);
+}
+
+
+static void
+_check_poly1305_cipher (unsigned int step)
+{
+ static const struct tv
+ {
+ int algo;
+ const char *key;
+ const char *iv;
+ int ivlen;
+ const char *aad;
+ int aadlen;
+ const char *plaintext;
+ int inlen;
+ const char *out;
+ const char *tag;
+ } tv[] =
+ {
+ /* draft-irtf-cfrg-chacha20-poly1305-03 */
+ { GCRY_CIPHER_CHACHA20,
+ "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0"
+ "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0",
+ "\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08", 12,
+ "\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91", 12,
+ "\x49\x6e\x74\x65\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20"
+ "\x61\x72\x65\x20\x64\x72\x61\x66\x74\x20\x64\x6f\x63\x75\x6d\x65"
+ "\x6e\x74\x73\x20\x76\x61\x6c\x69\x64\x20\x66\x6f\x72\x20\x61\x20"
+ "\x6d\x61\x78\x69\x6d\x75\x6d\x20\x6f\x66\x20\x73\x69\x78\x20\x6d"
+ "\x6f\x6e\x74\x68\x73\x20\x61\x6e\x64\x20\x6d\x61\x79\x20\x62\x65"
+ "\x20\x75\x70\x64\x61\x74\x65\x64\x2c\x20\x72\x65\x70\x6c\x61\x63"
+ "\x65\x64\x2c\x20\x6f\x72\x20\x6f\x62\x73\x6f\x6c\x65\x74\x65\x64"
+ "\x20\x62\x79\x20\x6f\x74\x68\x65\x72\x20\x64\x6f\x63\x75\x6d\x65"
+ "\x6e\x74\x73\x20\x61\x74\x20\x61\x6e\x79\x20\x74\x69\x6d\x65\x2e"
+ "\x20\x49\x74\x20\x69\x73\x20\x69\x6e\x61\x70\x70\x72\x6f\x70\x72"
+ "\x69\x61\x74\x65\x20\x74\x6f\x20\x75\x73\x65\x20\x49\x6e\x74\x65"
+ "\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20\x61\x73\x20\x72"
+ "\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x6d\x61\x74\x65\x72\x69\x61"
+ "\x6c\x20\x6f\x72\x20\x74\x6f\x20\x63\x69\x74\x65\x20\x74\x68\x65"
+ "\x6d\x20\x6f\x74\x68\x65\x72\x20\x74\x68\x61\x6e\x20\x61\x73\x20"
+ "\x2f\xe2\x80\x9c\x77\x6f\x72\x6b\x20\x69\x6e\x20\x70\x72\x6f\x67"
+ "\x72\x65\x73\x73\x2e\x2f\xe2\x80\x9d", 265,
+ "\x64\xa0\x86\x15\x75\x86\x1a\xf4\x60\xf0\x62\xc7\x9b\xe6\x43\xbd"
+ "\x5e\x80\x5c\xfd\x34\x5c\xf3\x89\xf1\x08\x67\x0a\xc7\x6c\x8c\xb2"
+ "\x4c\x6c\xfc\x18\x75\x5d\x43\xee\xa0\x9e\xe9\x4e\x38\x2d\x26\xb0"
+ "\xbd\xb7\xb7\x3c\x32\x1b\x01\x00\xd4\xf0\x3b\x7f\x35\x58\x94\xcf"
+ "\x33\x2f\x83\x0e\x71\x0b\x97\xce\x98\xc8\xa8\x4a\xbd\x0b\x94\x81"
+ "\x14\xad\x17\x6e\x00\x8d\x33\xbd\x60\xf9\x82\xb1\xff\x37\xc8\x55"
+ "\x97\x97\xa0\x6e\xf4\xf0\xef\x61\xc1\x86\x32\x4e\x2b\x35\x06\x38"
+ "\x36\x06\x90\x7b\x6a\x7c\x02\xb0\xf9\xf6\x15\x7b\x53\xc8\x67\xe4"
+ "\xb9\x16\x6c\x76\x7b\x80\x4d\x46\xa5\x9b\x52\x16\xcd\xe7\xa4\xe9"
+ "\x90\x40\xc5\xa4\x04\x33\x22\x5e\xe2\x82\xa1\xb0\xa0\x6c\x52\x3e"
+ "\xaf\x45\x34\xd7\xf8\x3f\xa1\x15\x5b\x00\x47\x71\x8c\xbc\x54\x6a"
+ "\x0d\x07\x2b\x04\xb3\x56\x4e\xea\x1b\x42\x22\x73\xf5\x48\x27\x1a"
+ "\x0b\xb2\x31\x60\x53\xfa\x76\x99\x19\x55\xeb\xd6\x31\x59\x43\x4e"
+ "\xce\xbb\x4e\x46\x6d\xae\x5a\x10\x73\xa6\x72\x76\x27\x09\x7a\x10"
+ "\x49\xe6\x17\xd9\x1d\x36\x10\x94\xfa\x68\xf0\xff\x77\x98\x71\x30"
+ "\x30\x5b\xea\xba\x2e\xda\x04\xdf\x99\x7b\x71\x4d\x6c\x6f\x2c\x29"
+ "\xa6\xad\x5c\xb4\x02\x2b\x02\x70\x9b",
+ "\xee\xad\x9d\x67\x89\x0c\xbb\x22\x39\x23\x36\xfe\xa1\x85\x1f\x38" },
+ /* draft-irtf-cfrg-chacha20-poly1305-03 */
+ { GCRY_CIPHER_CHACHA20,
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
+ "\x07\x00\x00\x00\x40\x41\x42\x43\x44\x45\x46\x47", 12,
+ "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", 12,
+ "Ladies and Gentlemen of the class of '99: If I could offer you "
+ "only one tip for the future, sunscreen would be it.", 114,
+ "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2"
+ "\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6"
+ "\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b"
+ "\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36"
+ "\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58"
+ "\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc"
+ "\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b"
+ "\x61\x16",
+ "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" },
+ /* 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 (verbose)
+ fprintf (stderr, " checking POLY1305 mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_POLY1305, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_POLY1305, 0);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("poly1305, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+ if (err)
+ {
+ fail ("cipher-poly1305, gcryctl_get_taglen failed (tv %d): %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ if (taglen2 != 16)
+ {
+ fail ("cipher-poly1305, gcryctl_get_taglen returned bad length"
+ " (tv %d): got=%zu want=%d\n",
+ i, taglen2, 16);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ for (pos = 0; pos < tv[i].aadlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].aadlen) ? step : tv[i].aadlen - pos;
+
+ err = gcry_cipher_authenticate(hde, tv[i].aad + pos, poslen);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_authenticate (%d) (%lu:%d) failed: "
+ "%s\n", i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ err = gcry_cipher_authenticate(hdd, tv[i].aad + pos, poslen);
+ if (err)
+ {
+ fail ("poly1305, de gcry_cipher_authenticate (%d) (%lu:%d) failed: "
+ "%s\n", i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ for (pos = 0; pos < tv[i].inlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos;
+
+ err = gcry_cipher_encrypt (hde, out + pos, poslen,
+ tv[i].plaintext + pos, poslen);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_encrypt (%d) (%lu:%d) failed: %s\n",
+ i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].out, out, tv[i].inlen))
+ fail ("poly1305, encrypt mismatch entry %d (step %d)\n", i, step);
+
+ for (pos = 0; pos < tv[i].inlen; pos += step)
+ {
+ poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos;
+
+ err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_decrypt (%d) (%lu:%d) failed: %s\n",
+ i, (unsigned long) pos, step, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].plaintext, out, tv[i].inlen))
+ fail ("poly1305, decrypt mismatch entry %d (step %d)\n", i, step);
+
+ err = gcry_cipher_gettag (hde, out, 16);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_gettag(%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].tag, out, 16))
+ fail ("poly1305, encrypt tag mismatch entry %d\n", i);
+
+
+ err = gcry_cipher_checktag (hdd, out, 16);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_checktag(%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_reset(hde);
+ if (!err)
+ err = gcry_cipher_reset(hdd);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_reset (%d) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* gcry_cipher_reset clears the IV */
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* this time we authenticate, encrypt and decrypt one byte at a time */
+ for (byteNum = 0; byteNum < tv[i].aadlen; ++byteNum)
+ {
+ err = gcry_cipher_authenticate(hde, tv[i].aad + byteNum, 1);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_authenticate (%d) (byte-buf) failed: "
+ "%s\n", i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ err = gcry_cipher_authenticate(hdd, tv[i].aad + byteNum, 1);
+ if (err)
+ {
+ fail ("poly1305, de gcry_cipher_authenticate (%d) (byte-buf) "
+ "failed: %s\n", i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
+ {
+ err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+ (tv[i].plaintext) + byteNum,
+ 1);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].out, out, tv[i].inlen))
+ fail ("poly1305, encrypt mismatch entry %d, (byte-buf)\n", i);
+
+ err = gcry_cipher_gettag (hde, tag, 16);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_gettag(%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].tag, tag, 16))
+ fail ("poly1305, encrypt tag mismatch entry %d, (byte-buf)\n", i);
+
+ for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
+ {
+ err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].plaintext, out, tv[i].inlen))
+ fail ("poly1305, decrypt mismatch entry %d\n", i);
+
+ err = gcry_cipher_checktag (hdd, tag, 16);
+ if (err)
+ {
+ fail ("poly1305, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n",
+ i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed POLY1305 checks.\n");
+}
+
+
+static void
+check_poly1305_cipher (void)
+{
+ /* Large buffers, no splitting. */
+ _check_poly1305_cipher(0xffffffff);
+ /* Split input to one byte buffers. */
+ _check_poly1305_cipher(1);
+ /* Split input to 7 byte buffers. */
+ _check_poly1305_cipher(7);
+ /* Split input to 16 byte buffers. */
+ _check_poly1305_cipher(16);
+}
+
+
+static void
+check_ccm_cipher (void)
+{
+ static const struct tv
+ {
+ int algo;
+ int keylen;
+ const char *key;
+ int noncelen;
+ const char *nonce;
+ int aadlen;
+ const char *aad;
+ int plainlen;
+ const char *plaintext;
+ int cipherlen;
+ const char *ciphertext;
+ } tv[] =
+ {
+ /* RFC 3610 */
+ { GCRY_CIPHER_AES, /* Packet Vector #1 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x03\x02\x01\x00\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 23,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+ 31,
+ "\x58\x8C\x97\x9A\x61\xC6\x63\xD2\xF0\x66\xD0\xC2\xC0\xF9\x89\x80\x6D\x5F\x6B\x61\xDA\xC3\x84\x17\xE8\xD1\x2C\xFD\xF9\x26\xE0"},
+ { GCRY_CIPHER_AES, /* Packet Vector #2 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x04\x03\x02\x01\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 24,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ 32,
+ "\x72\xC9\x1A\x36\xE1\x35\xF8\xCF\x29\x1C\xA8\x94\x08\x5C\x87\xE3\xCC\x15\xC4\x39\xC9\xE4\x3A\x3B\xA0\x91\xD5\x6E\x10\x40\x09\x16"},
+ { GCRY_CIPHER_AES, /* Packet Vector #3 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x05\x04\x03\x02\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 25,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+ 33,
+ "\x51\xB1\xE5\xF4\x4A\x19\x7D\x1D\xA4\x6B\x0F\x8E\x2D\x28\x2A\xE8\x71\xE8\x38\xBB\x64\xDA\x85\x96\x57\x4A\xDA\xA7\x6F\xBD\x9F\xB0\xC5"},
+ { GCRY_CIPHER_AES, /* Packet Vector #4 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x06\x05\x04\x03\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 19,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+ 27,
+ "\xA2\x8C\x68\x65\x93\x9A\x9A\x79\xFA\xAA\x5C\x4C\x2A\x9D\x4A\x91\xCD\xAC\x8C\x96\xC8\x61\xB9\xC9\xE6\x1E\xF1"},
+ { GCRY_CIPHER_AES, /* Packet Vector #5 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x07\x06\x05\x04\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 20,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ 28,
+ "\xDC\xF1\xFB\x7B\x5D\x9E\x23\xFB\x9D\x4E\x13\x12\x53\x65\x8A\xD8\x6E\xBD\xCA\x3E\x51\xE8\x3F\x07\x7D\x9C\x2D\x93"},
+ { GCRY_CIPHER_AES, /* Packet Vector #6 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x08\x07\x06\x05\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 21,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+ 29,
+ "\x6F\xC1\xB0\x11\xF0\x06\x56\x8B\x51\x71\xA4\x2D\x95\x3D\x46\x9B\x25\x70\xA4\xBD\x87\x40\x5A\x04\x43\xAC\x91\xCB\x94"},
+ { GCRY_CIPHER_AES, /* Packet Vector #7 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x09\x08\x07\x06\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 23,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+ 33,
+ "\x01\x35\xD1\xB2\xC9\x5F\x41\xD5\xD1\xD4\xFE\xC1\x85\xD1\x66\xB8\x09\x4E\x99\x9D\xFE\xD9\x6C\x04\x8C\x56\x60\x2C\x97\xAC\xBB\x74\x90"},
+ { GCRY_CIPHER_AES, /* Packet Vector #8 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0A\x09\x08\x07\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 24,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ 34,
+ "\x7B\x75\x39\x9A\xC0\x83\x1D\xD2\xF0\xBB\xD7\x58\x79\xA2\xFD\x8F\x6C\xAE\x6B\x6C\xD9\xB7\xDB\x24\xC1\x7B\x44\x33\xF4\x34\x96\x3F\x34\xB4"},
+ { GCRY_CIPHER_AES, /* Packet Vector #9 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0B\x0A\x09\x08\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 25,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+ 35,
+ "\x82\x53\x1A\x60\xCC\x24\x94\x5A\x4B\x82\x79\x18\x1A\xB5\xC8\x4D\xF2\x1C\xE7\xF9\xB7\x3F\x42\xE1\x97\xEA\x9C\x07\xE5\x6B\x5E\xB1\x7E\x5F\x4E"},
+ { GCRY_CIPHER_AES, /* Packet Vector #10 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0C\x0B\x0A\x09\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 19,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+ 29,
+ "\x07\x34\x25\x94\x15\x77\x85\x15\x2B\x07\x40\x98\x33\x0A\xBB\x14\x1B\x94\x7B\x56\x6A\xA9\x40\x6B\x4D\x99\x99\x88\xDD"},
+ { GCRY_CIPHER_AES, /* Packet Vector #11 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0D\x0C\x0B\x0A\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 20,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ 30,
+ "\x67\x6B\xB2\x03\x80\xB0\xE3\x01\xE8\xAB\x79\x59\x0A\x39\x6D\xA7\x8B\x83\x49\x34\xF5\x3A\xA2\xE9\x10\x7A\x8B\x6C\x02\x2C"},
+ { GCRY_CIPHER_AES, /* Packet Vector #12 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0E\x0D\x0C\x0B\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 21,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+ 31,
+ "\xC0\xFF\xA0\xD6\xF0\x5B\xDB\x67\xF2\x4D\x43\xA4\x33\x8D\x2A\xA4\xBE\xD7\xB2\x0E\x43\xCD\x1A\xA3\x16\x62\xE7\xAD\x65\xD6\xDB"},
+ { GCRY_CIPHER_AES, /* Packet Vector #13 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x41\x2B\x4E\xA9\xCD\xBE\x3C\x96\x96\x76\x6C\xFA",
+ 8, "\x0B\xE1\xA8\x8B\xAC\xE0\x18\xB1",
+ 23,
+ "\x08\xE8\xCF\x97\xD8\x20\xEA\x25\x84\x60\xE9\x6A\xD9\xCF\x52\x89\x05\x4D\x89\x5C\xEA\xC4\x7C",
+ 31,
+ "\x4C\xB9\x7F\x86\xA2\xA4\x68\x9A\x87\x79\x47\xAB\x80\x91\xEF\x53\x86\xA6\xFF\xBD\xD0\x80\xF8\xE7\x8C\xF7\xCB\x0C\xDD\xD7\xB3"},
+ { GCRY_CIPHER_AES, /* Packet Vector #14 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x33\x56\x8E\xF7\xB2\x63\x3C\x96\x96\x76\x6C\xFA",
+ 8, "\x63\x01\x8F\x76\xDC\x8A\x1B\xCB",
+ 24,
+ "\x90\x20\xEA\x6F\x91\xBD\xD8\x5A\xFA\x00\x39\xBA\x4B\xAF\xF9\xBF\xB7\x9C\x70\x28\x94\x9C\xD0\xEC",
+ 32,
+ "\x4C\xCB\x1E\x7C\xA9\x81\xBE\xFA\xA0\x72\x6C\x55\xD3\x78\x06\x12\x98\xC8\x5C\x92\x81\x4A\xBC\x33\xC5\x2E\xE8\x1D\x7D\x77\xC0\x8A"},
+ { GCRY_CIPHER_AES, /* Packet Vector #15 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x10\x3F\xE4\x13\x36\x71\x3C\x96\x96\x76\x6C\xFA",
+ 8, "\xAA\x6C\xFA\x36\xCA\xE8\x6B\x40",
+ 25,
+ "\xB9\x16\xE0\xEA\xCC\x1C\x00\xD7\xDC\xEC\x68\xEC\x0B\x3B\xBB\x1A\x02\xDE\x8A\x2D\x1A\xA3\x46\x13\x2E",
+ 33,
+ "\xB1\xD2\x3A\x22\x20\xDD\xC0\xAC\x90\x0D\x9A\xA0\x3C\x61\xFC\xF4\xA5\x59\xA4\x41\x77\x67\x08\x97\x08\xA7\x76\x79\x6E\xDB\x72\x35\x06"},
+ { GCRY_CIPHER_AES, /* Packet Vector #16 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x76\x4C\x63\xB8\x05\x8E\x3C\x96\x96\x76\x6C\xFA",
+ 12, "\xD0\xD0\x73\x5C\x53\x1E\x1B\xEC\xF0\x49\xC2\x44",
+ 19,
+ "\x12\xDA\xAC\x56\x30\xEF\xA5\x39\x6F\x77\x0C\xE1\xA6\x6B\x21\xF7\xB2\x10\x1C",
+ 27,
+ "\x14\xD2\x53\xC3\x96\x7B\x70\x60\x9B\x7C\xBB\x7C\x49\x91\x60\x28\x32\x45\x26\x9A\x6F\x49\x97\x5B\xCA\xDE\xAF"},
+ { GCRY_CIPHER_AES, /* Packet Vector #17 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\xF8\xB6\x78\x09\x4E\x3B\x3C\x96\x96\x76\x6C\xFA",
+ 12, "\x77\xB6\x0F\x01\x1C\x03\xE1\x52\x58\x99\xBC\xAE",
+ 20,
+ "\xE8\x8B\x6A\x46\xC7\x8D\x63\xE5\x2E\xB8\xC5\x46\xEF\xB5\xDE\x6F\x75\xE9\xCC\x0D",
+ 28,
+ "\x55\x45\xFF\x1A\x08\x5E\xE2\xEF\xBF\x52\xB2\xE0\x4B\xEE\x1E\x23\x36\xC7\x3E\x3F\x76\x2C\x0C\x77\x44\xFE\x7E\x3C"},
+ { GCRY_CIPHER_AES, /* Packet Vector #18 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\xD5\x60\x91\x2D\x3F\x70\x3C\x96\x96\x76\x6C\xFA",
+ 12, "\xCD\x90\x44\xD2\xB7\x1F\xDB\x81\x20\xEA\x60\xC0",
+ 21,
+ "\x64\x35\xAC\xBA\xFB\x11\xA8\x2E\x2F\x07\x1D\x7C\xA4\xA5\xEB\xD9\x3A\x80\x3B\xA8\x7F",
+ 29,
+ "\x00\x97\x69\xEC\xAB\xDF\x48\x62\x55\x94\xC5\x92\x51\xE6\x03\x57\x22\x67\x5E\x04\xC8\x47\x09\x9E\x5A\xE0\x70\x45\x51"},
+ { GCRY_CIPHER_AES, /* Packet Vector #19 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x42\xFF\xF8\xF1\x95\x1C\x3C\x96\x96\x76\x6C\xFA",
+ 8, "\xD8\x5B\xC7\xE6\x9F\x94\x4F\xB8",
+ 23,
+ "\x8A\x19\xB9\x50\xBC\xF7\x1A\x01\x8E\x5E\x67\x01\xC9\x17\x87\x65\x98\x09\xD6\x7D\xBE\xDD\x18",
+ 33,
+ "\xBC\x21\x8D\xAA\x94\x74\x27\xB6\xDB\x38\x6A\x99\xAC\x1A\xEF\x23\xAD\xE0\xB5\x29\x39\xCB\x6A\x63\x7C\xF9\xBE\xC2\x40\x88\x97\xC6\xBA"},
+ { GCRY_CIPHER_AES, /* Packet Vector #20 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x92\x0F\x40\xE5\x6C\xDC\x3C\x96\x96\x76\x6C\xFA",
+ 8, "\x74\xA0\xEB\xC9\x06\x9F\x5B\x37",
+ 24,
+ "\x17\x61\x43\x3C\x37\xC5\xA3\x5F\xC1\xF3\x9F\x40\x63\x02\xEB\x90\x7C\x61\x63\xBE\x38\xC9\x84\x37",
+ 34,
+ "\x58\x10\xE6\xFD\x25\x87\x40\x22\xE8\x03\x61\xA4\x78\xE3\xE9\xCF\x48\x4A\xB0\x4F\x44\x7E\xFF\xF6\xF0\xA4\x77\xCC\x2F\xC9\xBF\x54\x89\x44"},
+ { GCRY_CIPHER_AES, /* Packet Vector #21 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x27\xCA\x0C\x71\x20\xBC\x3C\x96\x96\x76\x6C\xFA",
+ 8, "\x44\xA3\xAA\x3A\xAE\x64\x75\xCA",
+ 25,
+ "\xA4\x34\xA8\xE5\x85\x00\xC6\xE4\x15\x30\x53\x88\x62\xD6\x86\xEA\x9E\x81\x30\x1B\x5A\xE4\x22\x6B\xFA",
+ 35,
+ "\xF2\xBE\xED\x7B\xC5\x09\x8E\x83\xFE\xB5\xB3\x16\x08\xF8\xE2\x9C\x38\x81\x9A\x89\xC8\xE7\x76\xF1\x54\x4D\x41\x51\xA4\xED\x3A\x8B\x87\xB9\xCE"},
+ { GCRY_CIPHER_AES, /* Packet Vector #22 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x5B\x8C\xCB\xCD\x9A\xF8\x3C\x96\x96\x76\x6C\xFA",
+ 12, "\xEC\x46\xBB\x63\xB0\x25\x20\xC3\x3C\x49\xFD\x70",
+ 19,
+ "\xB9\x6B\x49\xE2\x1D\x62\x17\x41\x63\x28\x75\xDB\x7F\x6C\x92\x43\xD2\xD7\xC2",
+ 29,
+ "\x31\xD7\x50\xA0\x9D\xA3\xED\x7F\xDD\xD4\x9A\x20\x32\xAA\xBF\x17\xEC\x8E\xBF\x7D\x22\xC8\x08\x8C\x66\x6B\xE5\xC1\x97"},
+ { GCRY_CIPHER_AES, /* Packet Vector #23 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x3E\xBE\x94\x04\x4B\x9A\x3C\x96\x96\x76\x6C\xFA",
+ 12, "\x47\xA6\x5A\xC7\x8B\x3D\x59\x42\x27\xE8\x5E\x71",
+ 20,
+ "\xE2\xFC\xFB\xB8\x80\x44\x2C\x73\x1B\xF9\x51\x67\xC8\xFF\xD7\x89\x5E\x33\x70\x76",
+ 30,
+ "\xE8\x82\xF1\xDB\xD3\x8C\xE3\xED\xA7\xC2\x3F\x04\xDD\x65\x07\x1E\xB4\x13\x42\xAC\xDF\x7E\x00\xDC\xCE\xC7\xAE\x52\x98\x7D"},
+ { GCRY_CIPHER_AES, /* Packet Vector #24 */
+ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+ 13, "\x00\x8D\x49\x3B\x30\xAE\x8B\x3C\x96\x96\x76\x6C\xFA",
+ 12, "\x6E\x37\xA6\xEF\x54\x6D\x95\x5D\x34\xAB\x60\x59",
+ 21,
+ "\xAB\xF2\x1C\x0B\x02\xFE\xB8\x8F\x85\x6D\xF4\xA3\x73\x81\xBC\xE3\xCC\x12\x85\x17\xD4",
+ 31,
+ "\xF3\x29\x05\xB8\x8A\x64\x1B\x04\xB9\xC9\xFF\xB5\x8C\xC3\x90\x90\x0F\x3D\xA1\x2A\xB1\x6D\xCE\x9E\x82\xEF\xA1\x6D\xA6\x20\x59"},
+ /* RFC 5528 */
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #1 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x03\x02\x01\x00\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 23,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+ 31,
+ "\xBA\x73\x71\x85\xE7\x19\x31\x04\x92\xF3\x8A\x5F\x12\x51\xDA\x55\xFA\xFB\xC9\x49\x84\x8A\x0D\xFC\xAE\xCE\x74\x6B\x3D\xB9\xAD"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #2 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x04\x03\x02\x01\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 24,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ 32,
+ "\x5D\x25\x64\xBF\x8E\xAF\xE1\xD9\x95\x26\xEC\x01\x6D\x1B\xF0\x42\x4C\xFB\xD2\xCD\x62\x84\x8F\x33\x60\xB2\x29\x5D\xF2\x42\x83\xE8"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #3 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x05\x04\x03\x02\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 25,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+ 33,
+ "\x81\xF6\x63\xD6\xC7\x78\x78\x17\xF9\x20\x36\x08\xB9\x82\xAD\x15\xDC\x2B\xBD\x87\xD7\x56\xF7\x92\x04\xF5\x51\xD6\x68\x2F\x23\xAA\x46"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #4 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x06\x05\x04\x03\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 19,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+ 27,
+ "\xCA\xEF\x1E\x82\x72\x11\xB0\x8F\x7B\xD9\x0F\x08\xC7\x72\x88\xC0\x70\xA4\xA0\x8B\x3A\x93\x3A\x63\xE4\x97\xA0"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #5 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x07\x06\x05\x04\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 20,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ 28,
+ "\x2A\xD3\xBA\xD9\x4F\xC5\x2E\x92\xBE\x43\x8E\x82\x7C\x10\x23\xB9\x6A\x8A\x77\x25\x8F\xA1\x7B\xA7\xF3\x31\xDB\x09"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #6 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x08\x07\x06\x05\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 21,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+ 29,
+ "\xFE\xA5\x48\x0B\xA5\x3F\xA8\xD3\xC3\x44\x22\xAA\xCE\x4D\xE6\x7F\xFA\x3B\xB7\x3B\xAB\xAB\x36\xA1\xEE\x4F\xE0\xFE\x28"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #7 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x09\x08\x07\x06\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 23,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+ 33,
+ "\x54\x53\x20\x26\xE5\x4C\x11\x9A\x8D\x36\xD9\xEC\x6E\x1E\xD9\x74\x16\xC8\x70\x8C\x4B\x5C\x2C\xAC\xAF\xA3\xBC\xCF\x7A\x4E\xBF\x95\x73"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #8 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0A\x09\x08\x07\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 24,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ 34,
+ "\x8A\xD1\x9B\x00\x1A\x87\xD1\x48\xF4\xD9\x2B\xEF\x34\x52\x5C\xCC\xE3\xA6\x3C\x65\x12\xA6\xF5\x75\x73\x88\xE4\x91\x3E\xF1\x47\x01\xF4\x41"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #9 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0B\x0A\x09\x08\xA0\xA1\xA2\xA3\xA4\xA5",
+ 8, "\x00\x01\x02\x03\x04\x05\x06\x07",
+ 25,
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+ 35,
+ "\x5D\xB0\x8D\x62\x40\x7E\x6E\x31\xD6\x0F\x9C\xA2\xC6\x04\x74\x21\x9A\xC0\xBE\x50\xC0\xD4\xA5\x77\x87\x94\xD6\xE2\x30\xCD\x25\xC9\xFE\xBF\x87"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #10 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0C\x0B\x0A\x09\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 19,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E",
+ 29,
+ "\xDB\x11\x8C\xCE\xC1\xB8\x76\x1C\x87\x7C\xD8\x96\x3A\x67\xD6\xF3\xBB\xBC\x5C\xD0\x92\x99\xEB\x11\xF3\x12\xF2\x32\x37"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #11 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0D\x0C\x0B\x0A\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 20,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ 30,
+ "\x7C\xC8\x3D\x8D\xC4\x91\x03\x52\x5B\x48\x3D\xC5\xCA\x7E\xA9\xAB\x81\x2B\x70\x56\x07\x9D\xAF\xFA\xDA\x16\xCC\xCF\x2C\x4E"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #12 */
+ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+ 13, "\x00\x00\x00\x0E\x0D\x0C\x0B\xA0\xA1\xA2\xA3\xA4\xA5",
+ 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B",
+ 21,
+ "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20",
+ 31,
+ "\x2C\xD3\x5B\x88\x20\xD2\x3E\x7A\xA3\x51\xB0\xE9\x2F\xC7\x93\x67\x23\x8B\x2C\xC7\x48\xCB\xB9\x4C\x29\x47\x79\x3D\x64\xAF\x75"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #13 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\xA9\x70\x11\x0E\x19\x27\xB1\x60\xB6\xA3\x1C\x1C",
+ 8, "\x6B\x7F\x46\x45\x07\xFA\xE4\x96",
+ 23,
+ "\xC6\xB5\xF3\xE6\xCA\x23\x11\xAE\xF7\x47\x2B\x20\x3E\x73\x5E\xA5\x61\xAD\xB1\x7D\x56\xC5\xA3",
+ 31,
+ "\xA4\x35\xD7\x27\x34\x8D\xDD\x22\x90\x7F\x7E\xB8\xF5\xFD\xBB\x4D\x93\x9D\xA6\x52\x4D\xB4\xF6\x45\x58\xC0\x2D\x25\xB1\x27\xEE"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #14 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\x83\xCD\x8C\xE0\xCB\x42\xB1\x60\xB6\xA3\x1C\x1C",
+ 8, "\x98\x66\x05\xB4\x3D\xF1\x5D\xE7",
+ 24,
+ "\x01\xF6\xCE\x67\x64\xC5\x74\x48\x3B\xB0\x2E\x6B\xBF\x1E\x0A\xBD\x26\xA2\x25\x72\xB4\xD8\x0E\xE7",
+ 32,
+ "\x8A\xE0\x52\x50\x8F\xBE\xCA\x93\x2E\x34\x6F\x05\xE0\xDC\x0D\xFB\xCF\x93\x9E\xAF\xFA\x3E\x58\x7C\x86\x7D\x6E\x1C\x48\x70\x38\x06"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #15 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\x5F\x54\x95\x0B\x18\xF2\xB1\x60\xB6\xA3\x1C\x1C",
+ 8, "\x48\xF2\xE7\xE1\xA7\x67\x1A\x51",
+ 25,
+ "\xCD\xF1\xD8\x40\x6F\xC2\xE9\x01\x49\x53\x89\x70\x05\xFB\xFB\x8B\xA5\x72\x76\xF9\x24\x04\x60\x8E\x08",
+ 33,
+ "\x08\xB6\x7E\xE2\x1C\x8B\xF2\x6E\x47\x3E\x40\x85\x99\xE9\xC0\x83\x6D\x6A\xF0\xBB\x18\xDF\x55\x46\x6C\xA8\x08\x78\xA7\x90\x47\x6D\xE5"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #16 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\xEC\x60\x08\x63\x31\x9A\xB1\x60\xB6\xA3\x1C\x1C",
+ 12, "\xDE\x97\xDF\x3B\x8C\xBD\x6D\x8E\x50\x30\xDA\x4C",
+ 19,
+ "\xB0\x05\xDC\xFA\x0B\x59\x18\x14\x26\xA9\x61\x68\x5A\x99\x3D\x8C\x43\x18\x5B",
+ 27,
+ "\x63\xB7\x8B\x49\x67\xB1\x9E\xDB\xB7\x33\xCD\x11\x14\xF6\x4E\xB2\x26\x08\x93\x68\xC3\x54\x82\x8D\x95\x0C\xC5"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #17 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\x60\xCF\xF1\xA3\x1E\xA1\xB1\x60\xB6\xA3\x1C\x1C",
+ 12, "\xA5\xEE\x93\xE4\x57\xDF\x05\x46\x6E\x78\x2D\xCF",
+ 20,
+ "\x2E\x20\x21\x12\x98\x10\x5F\x12\x9D\x5E\xD9\x5B\x93\xF7\x2D\x30\xB2\xFA\xCC\xD7",
+ 28,
+ "\x0B\xC6\xBB\xE2\xA8\xB9\x09\xF4\x62\x9E\xE6\xDC\x14\x8D\xA4\x44\x10\xE1\x8A\xF4\x31\x47\x38\x32\x76\xF6\x6A\x9F"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #18 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\x0F\x85\xCD\x99\x5C\x97\xB1\x60\xB6\xA3\x1C\x1C",
+ 12, "\x24\xAA\x1B\xF9\xA5\xCD\x87\x61\x82\xA2\x50\x74",
+ 21,
+ "\x26\x45\x94\x1E\x75\x63\x2D\x34\x91\xAF\x0F\xC0\xC9\x87\x6C\x3B\xE4\xAA\x74\x68\xC9",
+ 29,
+ "\x22\x2A\xD6\x32\xFA\x31\xD6\xAF\x97\x0C\x34\x5F\x7E\x77\xCA\x3B\xD0\xDC\x25\xB3\x40\xA1\xA3\xD3\x1F\x8D\x4B\x44\xB7"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #19 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\xC2\x9B\x2C\xAA\xC4\xCD\xB1\x60\xB6\xA3\x1C\x1C",
+ 8, "\x69\x19\x46\xB9\xCA\x07\xBE\x87",
+ 23,
+ "\x07\x01\x35\xA6\x43\x7C\x9D\xB1\x20\xCD\x61\xD8\xF6\xC3\x9C\x3E\xA1\x25\xFD\x95\xA0\xD2\x3D",
+ 33,
+ "\x05\xB8\xE1\xB9\xC4\x9C\xFD\x56\xCF\x13\x0A\xA6\x25\x1D\xC2\xEC\xC0\x6C\xCC\x50\x8F\xE6\x97\xA0\x06\x6D\x57\xC8\x4B\xEC\x18\x27\x68"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #20 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\x2C\x6B\x75\x95\xEE\x62\xB1\x60\xB6\xA3\x1C\x1C",
+ 8, "\xD0\xC5\x4E\xCB\x84\x62\x7D\xC4",
+ 24,
+ "\xC8\xC0\x88\x0E\x6C\x63\x6E\x20\x09\x3D\xD6\x59\x42\x17\xD2\xE1\x88\x77\xDB\x26\x4E\x71\xA5\xCC",
+ 34,
+ "\x54\xCE\xB9\x68\xDE\xE2\x36\x11\x57\x5E\xC0\x03\xDF\xAA\x1C\xD4\x88\x49\xBD\xF5\xAE\x2E\xDB\x6B\x7F\xA7\x75\xB1\x50\xED\x43\x83\xC5\xA9"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #21 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\xC5\x3C\xD4\xC2\xAA\x24\xB1\x60\xB6\xA3\x1C\x1C",
+ 8, "\xE2\x85\xE0\xE4\x80\x8C\xDA\x3D",
+ 25,
+ "\xF7\x5D\xAA\x07\x10\xC4\xE6\x42\x97\x79\x4D\xC2\xB7\xD2\xA2\x07\x57\xB1\xAA\x4E\x44\x80\x02\xFF\xAB",
+ 35,
+ "\xB1\x40\x45\x46\xBF\x66\x72\x10\xCA\x28\xE3\x09\xB3\x9B\xD6\xCA\x7E\x9F\xC8\x28\x5F\xE6\x98\xD4\x3C\xD2\x0A\x02\xE0\xBD\xCA\xED\x20\x10\xD3"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #22 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\xBE\xE9\x26\x7F\xBA\xDC\xB1\x60\xB6\xA3\x1C\x1C",
+ 12, "\x6C\xAE\xF9\x94\x11\x41\x57\x0D\x7C\x81\x34\x05",
+ 19,
+ "\xC2\x38\x82\x2F\xAC\x5F\x98\xFF\x92\x94\x05\xB0\xAD\x12\x7A\x4E\x41\x85\x4E",
+ 29,
+ "\x94\xC8\x95\x9C\x11\x56\x9A\x29\x78\x31\xA7\x21\x00\x58\x57\xAB\x61\xB8\x7A\x2D\xEA\x09\x36\xB6\xEB\x5F\x62\x5F\x5D"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #23 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\xDF\xA8\xB1\x24\x50\x07\xB1\x60\xB6\xA3\x1C\x1C",
+ 12, "\x36\xA5\x2C\xF1\x6B\x19\xA2\x03\x7A\xB7\x01\x1E",
+ 20,
+ "\x4D\xBF\x3E\x77\x4A\xD2\x45\xE5\xD5\x89\x1F\x9D\x1C\x32\xA0\xAE\x02\x2C\x85\xD7",
+ 30,
+ "\x58\x69\xE3\xAA\xD2\x44\x7C\x74\xE0\xFC\x05\xF9\xA4\xEA\x74\x57\x7F\x4D\xE8\xCA\x89\x24\x76\x42\x96\xAD\x04\x11\x9C\xE7"},
+ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #24 */
+ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+ 13, "\x00\x3B\x8F\xD8\xD3\xA9\x37\xB1\x60\xB6\xA3\x1C\x1C",
+ 12, "\xA4\xD4\x99\xF7\x84\x19\x72\x8C\x19\x17\x8B\x0C",
+ 21,
+ "\x9D\xC9\xED\xAE\x2F\xF5\xDF\x86\x36\xE8\xC6\xDE\x0E\xED\x55\xF7\x86\x7E\x33\x33\x7D",
+ 31,
+ "\x4B\x19\x81\x56\x39\x3B\x0F\x77\x96\x08\x6A\xAF\xB4\x54\xF8\xC3\xF0\x34\xCC\xA9\x66\x94\x5F\x1F\xCE\xA7\xE1\x1B\xEE\x6A\x2F"}
+ };
+ static const int cut[] = { 0, 1, 8, 10, 16, 19, -1 };
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ u64 ctl_params[3];
+ int split, aadsplit;
+ size_t j, i, keylen, blklen, authlen, taglen2;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting CCM checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking CCM mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+
+ for (j = 0; j < sizeof (cut) / sizeof (cut[0]); j++)
+ {
+ split = cut[j] < 0 ? tv[i].plainlen : cut[j];
+ if (tv[i].plainlen < split)
+ continue;
+
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CCM, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CCM, 0);
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_open failed: %s\n",
+ gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("cipher-ccm, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("cipher-ccm, gcry_cipher_get_algo_blklen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen);
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ authlen = tv[i].cipherlen - tv[i].plainlen;
+ ctl_params[0] = tv[i].plainlen; /* encryptedlen */
+ ctl_params[1] = tv[i].aadlen; /* aadlen */
+ ctl_params[2] = authlen; /* authtaglen */
+ err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+ sizeof(ctl_params));
+ if (!err)
+ err = gcry_cipher_ctl (hdd, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+ sizeof(ctl_params));
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS "
+ "failed: %s\n", gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+ if (err)
+ {
+ fail ("cipher-ccm, gcryctl_get_taglen failed (tv %lu): %s\n",
+ (unsigned long) i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ if (taglen2 != authlen)
+ {
+ fail ("cipher-ccm, gcryctl_get_taglen returned bad length"
+ " (tv %lu): got=%zu want=%zu\n",
+ (unsigned long) i, taglen2, authlen);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ aadsplit = split > tv[i].aadlen ? 0 : split;
+
+ err = gcry_cipher_authenticate (hde, tv[i].aad,
+ tv[i].aadlen - aadsplit);
+ if (!err)
+ err = gcry_cipher_authenticate (hde,
+ &tv[i].aad[tv[i].aadlen - aadsplit],
+ aadsplit);
+ if (!err)
+ err = gcry_cipher_authenticate (hdd, tv[i].aad,
+ tv[i].aadlen - aadsplit);
+ if (!err)
+ err = gcry_cipher_authenticate (hdd,
+ &tv[i].aad[tv[i].aadlen - aadsplit],
+ aadsplit);
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_authenticate failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].plaintext,
+ tv[i].plainlen - split);
+ if (!err)
+ err = gcry_cipher_encrypt (hde, &out[tv[i].plainlen - split],
+ MAX_DATA_LEN - (tv[i].plainlen - split),
+ &tv[i].plaintext[tv[i].plainlen - split],
+ split);
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_encrypt (%lu:%lu) failed: %s\n",
+ (unsigned long) i, (unsigned long) j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_gettag (hde, &out[tv[i].plainlen], authlen);
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_gettag (%lu:%lu) failed: %s\n",
+ (unsigned long) i, (unsigned long) j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].ciphertext, out, tv[i].cipherlen))
+ fail ("cipher-ccm, encrypt mismatch entry %lu:%lu\n",
+ (unsigned long) i, (unsigned long) j);
+
+ err = gcry_cipher_decrypt (hdd, out, tv[i].plainlen - split, NULL, 0);
+ if (!err)
+ err = gcry_cipher_decrypt (hdd, &out[tv[i].plainlen - split], split,
+ NULL, 0);
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_decrypt (%lu:%lu) failed: %s\n",
+ (unsigned long) i, (unsigned long) j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].plaintext, out, tv[i].plainlen))
+ fail ("cipher-ccm, decrypt mismatch entry %lu:%lu\n",
+ (unsigned long) i, (unsigned long) j);
+
+ err = gcry_cipher_checktag (hdd, &out[tv[i].plainlen], authlen);
+ if (err)
+ {
+ fail ("cipher-ccm, gcry_cipher_checktag (%lu:%lu) failed: %s\n",
+ (unsigned long) i, (unsigned long) j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ }
+
+ /* Large buffer tests. */
+
+ /* Test encoding of aadlen > 0xfeff. */
+ {
+ static const char key[]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+ 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
+ static const char iv[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
+ static const char tag[]={0x9C,0x76,0xE7,0x33,0xD5,0x15,0xB3,0x6C,
+ 0xBA,0x76,0x95,0xF7,0xFB,0x91};
+ char buf[1024];
+ size_t enclen = 0x20000;
+ size_t aadlen = 0x20000;
+ size_t taglen = sizeof(tag);
+
+ err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0);
+ if (err)
+ {
+ fail ("cipher-ccm-large, gcry_cipher_open failed: %s\n",
+ gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, key, sizeof (key));
+ if (err)
+ {
+ fail ("cipher-ccm-large, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, iv, sizeof (iv));
+ if (err)
+ {
+ fail ("cipher-ccm-large, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ ctl_params[0] = enclen; /* encryptedlen */
+ ctl_params[1] = aadlen; /* aadlen */
+ ctl_params[2] = taglen; /* authtaglen */
+ err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+ sizeof(ctl_params));
+ if (err)
+ {
+ fail ("cipher-ccm-large, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS "
+ "failed: %s\n", gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ memset (buf, 0xaa, sizeof(buf));
+
+ for (i = 0; i < aadlen; i += sizeof(buf))
+ {
+ err = gcry_cipher_authenticate (hde, buf, sizeof (buf));
+ if (err)
+ {
+ fail ("cipher-ccm-large, gcry_cipher_authenticate failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+ }
+
+ for (i = 0; i < enclen; i += sizeof(buf))
+ {
+ memset (buf, 0xee, sizeof(buf));
+ err = gcry_cipher_encrypt (hde, buf, sizeof (buf), NULL, 0);
+ if (err)
+ {
+ fail ("cipher-ccm-large, gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+ }
+
+ err = gcry_cipher_gettag (hde, buf, taglen);
+ if (err)
+ {
+ fail ("cipher-ccm-large, gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ if (memcmp (buf, tag, taglen) != 0)
+ fail ("cipher-ccm-large, encrypt mismatch entry\n");
+
+ gcry_cipher_close (hde);
+ }
+
+#if 0
+ /* Test encoding of aadlen > 0xffffffff. */
+ {
+ static const char key[]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+ 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
+ static const char iv[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
+ static const char tag[]={0x01,0xB2,0xC3,0x4A,0xA6,0x6A,0x07,0x6D,
+ 0xBC,0xBD,0xEA,0x17,0xD3,0x73,0xD7,0xD4};
+ char buf[1024];
+ size_t enclen = (size_t)0xffffffff + 1 + 1024;
+ size_t aadlen = (size_t)0xffffffff + 1 + 1024;
+ size_t taglen = sizeof(tag);
+
+ err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0);
+ if (err)
+ {
+ fail ("cipher-ccm-huge, gcry_cipher_open failed: %s\n",
+ gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, key, sizeof (key));
+ if (err)
+ {
+ fail ("cipher-ccm-huge, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, iv, sizeof (iv));
+ if (err)
+ {
+ fail ("cipher-ccm-huge, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ ctl_params[0] = enclen; /* encryptedlen */
+ ctl_params[1] = aadlen; /* aadlen */
+ ctl_params[2] = taglen; /* authtaglen */
+ err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params,
+ sizeof(ctl_params));
+ if (err)
+ {
+ fail ("cipher-ccm-huge, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS failed:"
+ "%s\n", gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ memset (buf, 0xaa, sizeof(buf));
+
+ for (i = 0; i < aadlen; i += sizeof(buf))
+ {
+ err = gcry_cipher_authenticate (hde, buf, sizeof (buf));
+ if (err)
+ {
+ fail ("cipher-ccm-huge, gcry_cipher_authenticate failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+ }
+
+ for (i = 0; i < enclen; i += sizeof(buf))
+ {
+ memset (buf, 0xee, sizeof(buf));
+ err = gcry_cipher_encrypt (hde, buf, sizeof (buf), NULL, 0);
+ if (err)
+ {
+ fail ("cipher-ccm-huge, gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+ }
+
+ err = gcry_cipher_gettag (hde, buf, taglen);
+ if (err)
+ {
+ fail ("cipher-ccm-huge, gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ if (memcmp (buf, tag, taglen) != 0)
+ fail ("cipher-ccm-huge, encrypt mismatch entry\n");
+
+ gcry_cipher_close (hde);
+ }
+
+ if (verbose)
+ fprintf (stderr, " Completed CCM checks.\n");
+#endif
+}
+
+
+static void
+do_check_ocb_cipher (int inplace)
+{
+ /* Note that we use hex strings and not binary strings in TV. That
+ makes it easier to maintain the test vectors. */
+ static const struct
+ {
+ int algo;
+ int taglen; /* 16, 12, or 8 bytes */
+ const char *key; /* NULL means "000102030405060708090A0B0C0D0E0F" */
+ const char *nonce;
+ const char *aad;
+ const char *plain;
+ const char *ciph;
+ } tv[] = {
+ /* The RFC-7253 test vectos*/
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221100",
+ "",
+ "",
+ "785407BFFFC8AD9EDCC5520AC9111EE6"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221101",
+ "0001020304050607",
+ "0001020304050607",
+ "6820B3657B6F615A5725BDA0D3B4EB3A257C9AF1F8F03009"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221102",
+ "0001020304050607",
+ "",
+ "81017F8203F081277152FADE694A0A00"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221103",
+ "",
+ "0001020304050607",
+ "45DD69F8F5AAE72414054CD1F35D82760B2CD00D2F99BFA9"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221104",
+ "000102030405060708090A0B0C0D0E0F",
+ "000102030405060708090A0B0C0D0E0F",
+ "571D535B60B277188BE5147170A9A22C3AD7A4FF3835B8C5"
+ "701C1CCEC8FC3358"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221105",
+ "000102030405060708090A0B0C0D0E0F",
+ "",
+ "8CF761B6902EF764462AD86498CA6B97"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221106",
+ "",
+ "000102030405060708090A0B0C0D0E0F",
+ "5CE88EC2E0692706A915C00AEB8B2396F40E1C743F52436B"
+ "DF06D8FA1ECA343D"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221107",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "1CA2207308C87C010756104D8840CE1952F09673A448A122"
+ "C92C62241051F57356D7F3C90BB0E07F"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221108",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "",
+ "6DC225A071FC1B9F7C69F93B0F1E10DE"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA99887766554433221109",
+ "",
+ "000102030405060708090A0B0C0D0E0F1011121314151617",
+ "221BD0DE7FA6FE993ECCD769460A0AF2D6CDED0C395B1C3C"
+ "E725F32494B9F914D85C0B1EB38357FF"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA9988776655443322110A",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F",
+ "BD6F6C496201C69296C11EFD138A467ABD3C707924B964DE"
+ "AFFC40319AF5A48540FBBA186C5553C68AD9F592A79A4240"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA9988776655443322110B",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F",
+ "",
+ "FE80690BEE8A485D11F32965BC9D2A32"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA9988776655443322110C",
+ "",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F",
+ "2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973792EF4"
+ "6040C53F1432BCDFB5E1DDE3BC18A5F840B52E653444D5DF"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA9988776655443322110D",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F2021222324252627",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F2021222324252627",
+ "D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460"
+ "6E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483"
+ "A7035490C5769E60"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA9988776655443322110E",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F2021222324252627",
+ "",
+ "C5CD9D1850C141E358649994EE701B68"
+ },
+ { GCRY_CIPHER_AES, 16, NULL,
+ "BBAA9988776655443322110F",
+ "",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F2021222324252627",
+ "4412923493C57D5DE0D700F753CCE0D1D2D95060122E9F15"
+ "A5DDBFC5787E50B5CC55EE507BCB084E479AD363AC366B95"
+ "A98CA5F3000B1479"
+ },
+ { GCRY_CIPHER_AES, 12, "0F0E0D0C0B0A09080706050403020100",
+ "BBAA9988776655443322110D",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F2021222324252627",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F2021222324252627",
+ "1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1"
+ "A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FD"
+ "AC4F02AA"
+ },
+ { GCRY_CIPHER_AES, 12, "0F0E0D0C0B0A09080706050403020100",
+ "BBAA9988776655443322110D",
+ "000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F2021222324252627",
+ /* test vector for checksumming */
+ "01000000000000000000000000000000"
+ "02000000000000000000000000000000"
+ "04000000000000000000000000000000"
+ "08000000000000000000000000000000"
+ "10000000000000000000000000000000"
+ "20000000000000000000000000000000"
+ "40000000000000000000000000000000"
+ "80000000000000000000000000000000"
+ "00010000000000000000000000000000"
+ "00020000000000000000000000000000"
+ "00040000000000000000000000000000"
+ "00080000000000000000000000000000"
+ "00100000000000000000000000000000"
+ "00200000000000000000000000000000"
+ "00400000000000000000000000000000"
+ "00800000000000000000000000000000"
+ "00000100000000000000000000000000"
+ "00000200000000000000000000000000"
+ "00000400000000000000000000000000"
+ "00000800000000000000000000000000"
+ "00001000000000000000000000000000"
+ "00002000000000000000000000000000"
+ "00004000000000000000000000000000"
+ "00008000000000000000000000000000"
+ "00000001000000000000000000000000"
+ "00000002000000000000000000000000"
+ "00000004000000000000000000000000"
+ "00000008000000000000000000000000"
+ "00000010000000000000000000000000"
+ "00000020000000000000000000000000"
+ "00000040000000000000000000000000"
+ "00000080000000000000000000000000"
+ "00000000010000000000000000000000"
+ "00000000020000000000000000000000"
+ "00000000040000000000000000000000"
+ "00000000080000000000000000000000"
+ "00000000100000000000000000000000"
+ "00000000200000000000000000000000"
+ "00000000400000000000000000000000"
+ "00000000800000000000000000000000"
+ "00000000000100000000000000000000"
+ "00000000000200000000000000000000"
+ "00000000000400000000000000000000"
+ "00000000000800000000000000000000"
+ "00000000001000000000000000000000"
+ "00000000002000000000000000000000"
+ "00000000004000000000000000000000"
+ "00000000008000000000000000000000",
+ "01105c6e36f6ac480f022c51e31ed702"
+ "90fda4b7b783194d4b4be8e4e1e2dff4"
+ "6a0804d1c5f9f808ea7933e31c063233"
+ "2bf65a22b20bb13cde3b80b3682ba965"
+ "b1207c58916f7856fa9968b410e50dee"
+ "98b35c071163d1b352b9bbccd09fde29"
+ "b850f40e71a8ae7d2e2d577f5ee39c46"
+ "7fa28130b50a123c29958e4665dda9a5"
+ "e0793997f8f19633a96392141d6e0e88"
+ "77850ed4364065d1d2f8746e2f1d5fd1"
+ "996cdde03215306503a30e41f58ef3c4"
+ "400365cfea4fa6381157c12a46598edf"
+ "18604854462ec66e3d3cf26d4723cb6a"
+ "9d801095048086a606fdb9192760889b"
+ "a8ce2e70e1b55a469137a9e2e6734565"
+ "283cb1e2c74f37e0854d03e33f8ba499"
+ "ef5d9af4edfce077c6280338f0a64286"
+ "2e6bc27ebd5a4c91b3778e22631251c8"
+ "c5bb75a10945597a9d6c274fc82d3338"
+ "b403a0a549d1375f26e71ef22bce0941"
+ "93ea87e2ed72fce0546148c351eec3be"
+ "867bb1b96070c377fff3c98e21562beb"
+ "475cfe28abcaaedf49981f6599b15140"
+ "ea6130d24407079f18ba9d4a8960b082"
+ "b39c57320e2e064f02fde88c23112146"
+ "1cac3655868aef584714826ee4f361fb"
+ "e6d692e1589cbb9dd3c74fa628df2a1f"
+ "3b0029b1d62b7e9978013ed3c793c1dd"
+ "1f184c8f7022a853cac40b74ac749aa3"
+ "f33f0d14732dfda0f2c3c20591bf1f5a"
+ "710ec0d0bca342baa5146068a78ff58c"
+ "66316312b7a98af35a0f4e92799b4047"
+ "f047ae61f25c28d232ce5c168cc745d6"
+ "6da13cb0f9e38a696635dba7a21571cf"
+ "cd64ec8cc33db7879f59a90d9edd00f6"
+ "a899e39ab36b9269a3ac04ebad9326bf"
+ "53cd9b400168a61714cd628a4056d236"
+ "bd8622c76daa54cb65f5db2fe03bafbe"
+ "0b23549ae31136f607293e8093a21934"
+ "74fd5e9c2451b4c8e0499e6ad34fafc8"
+ "ab77722a282f7f84b14ddebf7e696300"
+ "c1ef92d4a0263c6cca104530f996e272"
+ "f58992ff68d642b071a5848dc4acf2ae"
+ "28fb1f27ae0f297d5136a7a0a4a03e89"
+ "b588755b8217a1c62773790e69261269"
+ "19f45daf7b3ccf18e3fc590a9a0e172f"
+ "033ac4d13c3decc4c62d7de718ace802"
+ "140452dc850989f6762e3578bbb04be3"
+ "1a237c599c4649f4e586b2de"
+ }
+ };
+ gpg_error_t err = 0;
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[1024];
+ unsigned char tag[16];
+ int tidx;
+
+ if (verbose)
+ fprintf (stderr, " Starting OCB checks.\n");
+
+ for (tidx = 0; tidx < DIM (tv); tidx++)
+ {
+ char *key, *nonce, *aad, *ciph, *plain;
+ size_t keylen, noncelen, aadlen, ciphlen, plainlen;
+ int taglen;
+ size_t taglen2;
+
+ if (verbose)
+ fprintf (stderr, " checking OCB mode for %s [%i] (tv %d)\n",
+ gcry_cipher_algo_name (tv[tidx].algo), tv[tidx].algo, tidx);
+
+ /* Convert to hex strings to binary. */
+ key = hex2buffer (tv[tidx].key? tv[tidx].key
+ /* */: "000102030405060708090A0B0C0D0E0F",
+ &keylen);
+ nonce = hex2buffer (tv[tidx].nonce, &noncelen);
+ aad = hex2buffer (tv[tidx].aad, &aadlen);
+ plain = hex2buffer (tv[tidx].plain, &plainlen);
+ ciph = hex2buffer (tv[tidx].ciph, &ciphlen);
+
+ /* Check that our test vectors are sane. */
+ assert (plainlen <= sizeof out);
+ assert (tv[tidx].taglen <= ciphlen);
+ assert (tv[tidx].taglen <= sizeof tag);
+
+ err = gcry_cipher_open (&hde, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_open failed (tv %d): %s\n",
+ tidx, gpg_strerror (err));
+ return;
+ }
+
+ /* Set the taglen. For the first handle we do this only for a
+ non-default taglen. For the second handle we check that we
+ can also set to the default taglen. */
+ taglen = tv[tidx].taglen;
+ if (taglen != 16)
+ {
+ err = gcry_cipher_ctl (hde, GCRYCTL_SET_TAGLEN,
+ &taglen, sizeof taglen);
+ if (err)
+ {
+ fail ("cipher-ocb, gcryctl_set_taglen failed (tv %d): %s\n",
+ tidx, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+ err = gcry_cipher_ctl (hdd, GCRYCTL_SET_TAGLEN,
+ &taglen, sizeof taglen);
+ if (err)
+ {
+ fail ("cipher-ocb, gcryctl_set_taglen failed (tv %d): %s\n",
+ tidx, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2);
+ if (err)
+ {
+ fail ("cipher-ocb, gcryctl_get_taglen failed (tv %d): %s\n",
+ tidx, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ if (taglen2 != tv[tidx].taglen)
+ {
+ fail ("cipher-ocb, gcryctl_get_taglen returned bad length (tv %d): "
+ "got=%zu want=%d\n",
+ tidx, taglen2, tv[tidx].taglen);
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, key, keylen);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_setkey failed (tv %d): %s\n",
+ tidx, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, nonce, noncelen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, nonce, noncelen);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_setiv failed (tv %d): %s\n",
+ tidx, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_authenticate (hde, aad, aadlen);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_authenticate failed (tv %d): %s\n",
+ tidx, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ err = gcry_cipher_final (hde);
+ if (!err)
+ {
+ if (inplace)
+ {
+ memcpy(out, plain, plainlen);
+ err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0);
+ }
+ else
+ {
+ err = gcry_cipher_encrypt (hde, out, 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++)
+ inbuf[i] = (unsigned int)(i + 181081) * 5039U;
+
+ err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_open failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ goto out_free;
+ }
+
+ err = gcry_cipher_setkey (hde, key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, key, keylen);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_setkey failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ goto out_free;
+ }
+
+ err = gcry_cipher_setiv (hde, nonce, 12);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, nonce, 12);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_setiv failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ goto out_free;
+ }
+
+ if (splitpos)
+ {
+ err = gcry_cipher_authenticate (hde, inbuf, splitpos);
+ }
+ if (!err)
+ {
+ err = gcry_cipher_authenticate (hde, inbuf + splitpos, buflen - splitpos);
+ }
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_authenticate failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ goto out_free;
+ }
+
+ if (splitpos)
+ {
+ err = gcry_cipher_encrypt (hde, outbuf, splitpos, inbuf, splitpos);
+ }
+ if (!err)
+ {
+ err = gcry_cipher_final (hde);
+ if (!err)
+ {
+ err = gcry_cipher_encrypt (hde, outbuf + splitpos, buflen - splitpos,
+ inbuf + splitpos, buflen - splitpos);
+ }
+ }
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_encrypt failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ goto out_free;
+ }
+
+ /* Check that the tag matches. */
+ err = gcry_cipher_gettag (hde, tag, 16);
+ if (err)
+ {
+ fail ("cipher_ocb, gcry_cipher_gettag failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ }
+ if (memcmp (tagexpect, tag, 16))
+ {
+ mismatch (tagexpect, 16, tag, 16);
+ fail ("cipher-ocb, encrypt tag mismatch (large, algo %d)\n", algo);
+ }
+
+ err = gcry_cipher_authenticate (hdd, inbuf, buflen);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_authenticate failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ goto out_free;
+ }
+
+ /* Now for the decryption. */
+ if (splitpos)
+ {
+ err = gcry_cipher_decrypt (hdd, outbuf, splitpos, NULL, 0);
+ }
+ if (!err)
+ {
+ err = gcry_cipher_final (hdd);
+ if (!err)
+ {
+ err = gcry_cipher_decrypt (hdd, outbuf + splitpos, buflen - splitpos,
+ NULL, 0);
+ }
+ }
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_decrypt (large, algo %d) failed: %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ goto out_free;
+ }
+
+ /* We still have TAG from the encryption. */
+ err = gcry_cipher_checktag (hdd, tag, 16);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_checktag failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ }
+
+ /* Check that the decrypt output matches the original plaintext. */
+ if (memcmp (inbuf, outbuf, buflen))
+ {
+ /*mismatch (inbuf, buflen, outbuf, buflen);*/
+ fail ("cipher-ocb, decrypt data mismatch (large, algo %d)\n", algo);
+ }
+
+ /* Check that gettag also works for decryption. */
+ err = gcry_cipher_gettag (hdd, tag, 16);
+ if (err)
+ {
+ fail ("cipher_ocb, decrypt gettag failed (large, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ }
+ if (memcmp (tagexpect, tag, 16))
+ {
+ mismatch (tagexpect, 16, tag, 16);
+ fail ("cipher-ocb, decrypt tag mismatch (large, algo %d)\n", algo);
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+
+out_free:
+ xfree(outbuf);
+ xfree(inbuf);
+}
+
+
+static void
+check_ocb_cipher_checksum (int algo, int keylen)
+{
+ static const unsigned char key[32] =
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+ static const unsigned char nonce[12] =
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x00\x01\x02\x03";
+ const size_t buflen = 128 * 16;
+ unsigned char *inbuf, *outbuf;
+ gpg_error_t err = 0;
+ gcry_cipher_hd_t hde, hde2;
+ unsigned char tag[16];
+ unsigned char tag2[16];
+ int i;
+
+ inbuf = xmalloc(buflen);
+ if (!inbuf)
+ {
+ fail ("out-of-memory\n");
+ return;
+ }
+ outbuf = xmalloc(buflen);
+ if (!inbuf)
+ {
+ fail ("out-of-memory\n");
+ xfree(inbuf);
+ return;
+ }
+
+ memset(inbuf, 0, buflen);
+ for (i = 0; i < 128; i += 16)
+ {
+ unsigned char *blk = inbuf + i;
+ int bit2set = i / 16;
+ int byteidx = bit2set / 8;
+ int bitpos = bit2set % 8;
+
+ blk[byteidx] |= 1 << bitpos;
+ }
+
+ err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0);
+ if (!err)
+ err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_open failed (checksum, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ goto out_free;
+ }
+
+ err = gcry_cipher_setkey (hde, key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hde2, key, keylen);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_setkey failed (checksum, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hde2);
+ goto out_free;
+ }
+
+ err = gcry_cipher_setiv (hde, nonce, 12);
+ if (!err)
+ err = gcry_cipher_setiv (hde2, nonce, 12);
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_setiv failed (checksum, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hde2);
+ goto out_free;
+ }
+
+ err = gcry_cipher_final (hde);
+ if (!err)
+ {
+ err = gcry_cipher_encrypt (hde, outbuf, buflen, inbuf, buflen);
+ }
+ for (i = 0; i < buflen && !err; i += 16)
+ {
+ if (i + 16 == buflen)
+ err = gcry_cipher_final (hde2);
+ if (!err)
+ err = gcry_cipher_encrypt (hde2, outbuf + i, 16, inbuf + i, 16);
+ }
+
+ if (err)
+ {
+ fail ("cipher-ocb, gcry_cipher_encrypt failed (checksum, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hde2);
+ goto out_free;
+ }
+
+ /* Check that the tag matches. */
+ err = gcry_cipher_gettag (hde, tag, 16);
+ if (err)
+ {
+ fail ("cipher_ocb, gcry_cipher_gettag failed (checksum, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ }
+ err = gcry_cipher_gettag (hde2, tag2, 16);
+ if (err)
+ {
+ fail ("cipher_ocb, gcry_cipher_gettag failed (checksum2, algo %d): %s\n",
+ algo, gpg_strerror (err));
+ }
+ if (memcmp (tag, tag2, 16))
+ {
+ mismatch (tag, 16, tag2, 16);
+ fail ("cipher-ocb, encrypt tag mismatch (checksum, algo %d)\n", algo);
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hde2);
+
+out_free:
+ xfree(inbuf);
+ xfree(outbuf);
+}
+
+
+static void
+check_ocb_cipher_largebuf (int algo, int keylen, const char *tagexpect)
+{
+ unsigned int split;
+
+ for (split = 0; split < 32 * 16; split = split * 2 + 16)
+ {
+ check_ocb_cipher_largebuf_split(algo, keylen, tagexpect, split);
+ }
+
+ check_ocb_cipher_checksum(algo, keylen);
+}
+
+
+static void
+check_ocb_cipher_splitaad (void)
+{
+ const char t_nonce[] = ("BBAA9988776655443322110D");
+ const char t_plain[] = ("000102030405060708090A0B0C0D0E0F1011121314151617"
+ "18191A1B1C1D1E1F2021222324252627");
+ const char t_ciph[] = ("D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460"
+ "6E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483"
+ "A7035490C5769E60");
+ struct {
+ const char *aad0;
+ const char *aad1;
+ const char *aad2;
+ const char *aad3;
+ } tv[] = {
+ {
+ "000102030405060708090A0B0C0D0E0F"
+ "101112131415161718191A1B1C1D1E1F2021222324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "101112131415161718191A1B1C1D1E1F",
+ "2021222324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "1011121314151617",
+ "18191A1B1C1D1E1F",
+ "2021222324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "101112131415161718191A1B1C1D1E1F",
+ "20",
+ "21222324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "101112131415161718191A1B1C1D1E1F",
+ "2021",
+ "222324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "101112131415161718191A1B1C1D1E1F",
+ "202122",
+ "2324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "101112131415161718191A1B1C1D1E1F",
+ "20212223",
+ "24252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "101112131415161718191A1B1C1D1E1F",
+ "2021222324",
+ "252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "101112131415161718191A1B1C1D1E1F",
+ "202122232425",
+ "2627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "101112131415161718191A1B1C1D1E1F",
+ "20212223242526"
+ "27"
+ },
+ {
+ "000102030405060708090A0B0C0D0E0F",
+ "1011121314151617",
+ "18191A1B1C1D1E1F2021222324252627"
+ },
+ {
+ "00",
+ "0102030405060708090A0B0C0D0E0F",
+ "1011121314151617",
+ "18191A1B1C1D1E1F2021222324252627"
+ },
+ {
+ "0001",
+ "02030405060708090A0B0C0D0E0F",
+ "1011121314151617",
+ "18191A1B1C1D1E1F2021222324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D",
+ "0E0F",
+ "1011121314151617",
+ "18191A1B1C1D1E1F2021222324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E",
+ "0F",
+ "1011121314151617",
+ "18191A1B1C1D1E1F2021222324252627"
+ },
+ {
+ "000102030405060708090A0B0C0D0E",
+ "0F101112131415161718191A1B1C1D1E1F20212223242526",
+ "27"
+ }
+ };
+
+ gpg_error_t err = 0;
+ gcry_cipher_hd_t hde;
+ unsigned char out[MAX_DATA_LEN];
+ unsigned char tag[16];
+ int tidx;
+ char *key, *nonce, *ciph, *plain;
+ size_t keylen, noncelen, ciphlen, plainlen;
+ int i;
+
+ /* Convert to hex strings to binary. */
+ key = hex2buffer ("000102030405060708090A0B0C0D0E0F", &keylen);
+ nonce = hex2buffer (t_nonce, &noncelen);
+ plain = hex2buffer (t_plain, &plainlen);
+ ciph = hex2buffer (t_ciph, &ciphlen);
+
+ /* Check that our test vectors are sane. */
+ assert (plainlen <= sizeof out);
+ assert (16 <= ciphlen);
+ assert (16 <= sizeof tag);
+
+ for (tidx = 0; tidx < DIM (tv); tidx++)
+ {
+ char *aad[4];
+ size_t aadlen[4];
+
+ if (verbose)
+ fprintf (stderr, " checking OCB aad split (tv %d)\n", tidx);
+
+ aad[0] = tv[tidx].aad0? hex2buffer (tv[tidx].aad0, aadlen+0) : NULL;
+ aad[1] = tv[tidx].aad1? hex2buffer (tv[tidx].aad1, aadlen+1) : NULL;
+ aad[2] = tv[tidx].aad2? hex2buffer (tv[tidx].aad2, aadlen+2) : NULL;
+ aad[3] = tv[tidx].aad3? hex2buffer (tv[tidx].aad3, aadlen+3) : NULL;
+
+ err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB, 0);
+ if (err)
+ {
+ fail ("cipher-ocb-splitadd, gcry_cipher_open failed: %s\n",
+ gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, key, keylen);
+ if (err)
+ {
+ fail ("cipher-ocb-splitaad, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, nonce, noncelen);
+ if (err)
+ {
+ fail ("cipher-ocb-splitaad, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ for (i=0; i < DIM (aad); i++)
+ {
+ if (!aad[i])
+ continue;
+ err = gcry_cipher_authenticate (hde, aad[i], aadlen[i]);
+ if (err)
+ {
+ fail ("cipher-ocb-splitaad,"
+ " gcry_cipher_authenticate failed (tv=%d,i=%d): %s\n",
+ tidx, i, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+ }
+
+ err = gcry_cipher_final (hde);
+ if (!err)
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, plain, plainlen);
+ if (err)
+ {
+ fail ("cipher-ocb-splitaad, gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ return;
+ }
+
+ /* Check that the encrypt output matches the expected cipher
+ text without the tag (i.e. at the length of plaintext). */
+ if (memcmp (ciph, out, plainlen))
+ {
+ mismatch (ciph, plainlen, out, plainlen);
+ fail ("cipher-ocb-splitaad, encrypt data mismatch\n");
+ }
+
+ /* Check that the tag matches TAGLEN bytes from the end of the
+ expected ciphertext. */
+ err = gcry_cipher_gettag (hde, tag, 16);
+ if (err)
+ {
+ fail ("cipher-ocb-splitaad, gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ }
+ if (memcmp (ciph + ciphlen - 16, tag, 16))
+ {
+ mismatch (ciph + ciphlen - 16, 16, tag, 16);
+ fail ("cipher-ocb-splitaad, encrypt tag mismatch\n");
+ }
+
+
+ gcry_cipher_close (hde);
+ xfree (aad[0]);
+ xfree (aad[1]);
+ xfree (aad[2]);
+ xfree (aad[3]);
+ }
+
+ xfree (nonce);
+ xfree (ciph);
+ xfree (plain);
+ xfree (key);
+}
+
+
+static void
+check_ocb_cipher (void)
+{
+ /* Check OCB cipher with separate destination and source buffers for
+ * encryption/decryption. */
+ do_check_ocb_cipher(0);
+
+ /* Check OCB cipher with inplace encrypt/decrypt. */
+ do_check_ocb_cipher(1);
+
+ /* Check large buffer encryption/decryption. */
+ check_ocb_cipher_largebuf(GCRY_CIPHER_AES, 16,
+ "\xc1\x5b\xf1\x80\xa4\xd5\xea\xfd\xae\x17\xa6\xcd\x6b\x10\xa8\xea");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32,
+ "\x2b\xb7\x25\x6b\x77\xc7\xfb\x21\x5c\xc9\x6c\x36\x17\x1a\x1a\xd5");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16,
+ "\xe0\xae\x3f\x29\x3a\xee\xd8\xe3\xf2\x20\xc1\xa2\xd8\x72\x12\xd9");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24,
+ "\xd7\x98\x71\xcf\x19\x5c\xa3\x3d\x6c\xfc\xc9\xbe\x9f\x13\x6b\xbd");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32,
+ "\x03\xf6\xec\x1a\x0e\xae\x66\x24\x2b\xba\x26\x0f\xb3\xb3\x1f\xb9");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16,
+ "\x1c\xf9\xc7\xfc\x3a\x32\xac\xc7\x5e\x0a\xc2\x5c\x90\xd6\xf6\xf9");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32,
+ "\x53\x02\xc8\x0d\x4e\x9a\x44\x9e\x43\xd4\xaa\x06\x30\x93\xcc\x16");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16,
+ "\xd3\x64\xac\x40\x48\x88\x77\xe2\x41\x26\x4c\xde\x21\x29\x21\x8d");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24,
+ "\x99\xeb\x35\xb0\x62\x4e\x7b\xf1\x5e\x9f\xed\x32\x78\x90\x0b\xd0");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32,
+ "\x71\x66\x2f\x68\xbf\xdd\xcc\xb1\xbf\x81\x56\x5f\x01\x73\xeb\x44");
+ check_ocb_cipher_largebuf(GCRY_CIPHER_SM4, 16,
+ "\x2c\x0b\x31\x0b\xf4\x71\x9b\x01\xf4\x18\x5d\xf1\xe9\x3d\xed\x6b");
+
+ /* 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");
+ 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[] = {
+#ifdef USE_SALSA20
+ {
+ "Salsa20 128 bit, test 1",
+ GCRY_CIPHER_SALSA20, 16, 8,
+ "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x4D\xFA\x5E\x48\x1D\xA2\x3E\xA0"
+ }
+ }
+ },
+ {
+ "Salsa20 128 bit, test 2",
+ GCRY_CIPHER_SALSA20, 16, 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x80\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xB6\x6C\x1E\x44\x46\xDD\x95\x57"
+ }
+ }
+ },
+ {
+ "Salsa20 128 bit, test 3",
+ GCRY_CIPHER_SALSA20, 16, 8,
+ "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD",
+ "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x05\xE1\xE7\xBE\xB6\x97\xD9\x99"
+ }
+ }
+ },
+ {
+ "Salsa20 256 bit, test 1",
+ GCRY_CIPHER_SALSA20, 32, 8,
+ "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xE3\xBE\x8F\xDD\x8B\xEC\xA2\xE3"
+ }
+ }
+ },
+ {
+ "Salsa20 256 bit, test 2",
+ GCRY_CIPHER_SALSA20, 32, 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x80\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x2A\xBA\x3D\xC4\x5B\x49\x47\x00"
+ }
+ }
+ },
+ {
+ "Salsa20 256 bit, ecrypt verified, set 6, vector 0",
+ GCRY_CIPHER_SALSA20, 32, 8,
+ "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD"
+ "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D",
+ "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58"
+ },
+ { 64,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58\xC4\xAE\xA0\xD0\xED\x9A\x96\x01"
+ "\xF2\x78\x11\x2C\xA7\x18\x0D\x56\x5B\x42\x0A\x48\x01\x96\x70\xEA"
+ "\xF2\x4C\xE4\x93\xA8\x62\x63\xF6\x77\xB4\x6A\xCE\x19\x24\x77\x3D"
+ "\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71"
+ }
+ }
+ },
+ {
+ "Salsa20/12 128 bit, test 1",
+ GCRY_CIPHER_SALSA20R12, 16, 8,
+ "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xFC\x20\x7D\xBF\xC7\x6C\x5E\x17"
+ }
+ }
+ },
+ {
+ "Salsa20/12 128 bit, test 2",
+ GCRY_CIPHER_SALSA20R12, 16, 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x80\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x08\x28\x39\x9A\x6F\xEF\x20\xDA"
+ }
+ }
+ },
+ {
+ "Salsa20/12 128 bit, test 3",
+ GCRY_CIPHER_SALSA20R12, 16, 8,
+ "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD",
+ "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xAD\x9E\x60\xE6\xD2\xA2\x64\xB8"
+ }
+ }
+ },
+ {
+ "Salsa20/12 256 bit, test 1",
+ GCRY_CIPHER_SALSA20R12, 32, 8,
+ "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xAF\xE4\x11\xED\x1C\x4E\x07\xE4"
+ }
+ }
+ },
+ {
+ "Salsa20/12 256 bit, test 2",
+ GCRY_CIPHER_SALSA20R12, 32, 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x80\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x17\x2C\x51\x92\xCB\x6E\x64\x5B"
+ }
+ }
+ },
+ {
+ "Salsa20/12 256 bit, ecrypt verified, set 6, vector 0",
+ GCRY_CIPHER_SALSA20R12, 32, 8,
+ "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD"
+ "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D",
+ "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82"
+ },
+ { 64,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82\xF2\x00\xC2\x99\x9F\xE4\xBA\x31"
+ "\xA7\xA1\x8F\x1D\x5C\x97\x16\x19\x1D\x12\x31\x75\xE1\x47\xBD\x4E"
+ "\x8C\xA6\xED\x16\x6C\xE0\xFC\x8E\x65\xA5\xCA\x60\x84\x20\xFC\x65"
+ "\x44\xC9\x70\x0A\x0F\x21\x38\xE8\xC1\xA2\x86\xFB\x8C\x1F\xBF\xA0"
+ }
+ }
+ },
+#endif /*USE_SALSA20*/
+#ifdef USE_CHACHA20
+ /* From draft-strombergson-chacha-test-vectors-01 */
+ {
+ "ChaCha20 128 bit, TC1",
+ GCRY_CIPHER_CHACHA20, 16, 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x89\x67\x09\x52\x60\x83\x64\xfd"
+ },
+ { 112,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x89\x67\x09\x52\x60\x83\x64\xfd\x00\xb2\xf9\x09\x36\xf0\x31\xc8"
+ "\xe7\x56\xe1\x5d\xba\x04\xb8\x49\x3d\x00\x42\x92\x59\xb2\x0f\x46"
+ "\xcc\x04\xf1\x11\x24\x6b\x6c\x2c\xe0\x66\xbe\x3b\xfb\x32\xd9\xaa"
+ "\x0f\xdd\xfb\xc1\x21\x23\xd4\xb9\xe4\x4f\x34\xdc\xa0\x5a\x10\x3f"
+ "\x6c\xd1\x35\xc2\x87\x8c\x83\x2b\x58\x96\xb1\x34\xf6\x14\x2a\x9d"
+ "\x4d\x8d\x0d\x8f\x10\x26\xd2\x0a\x0a\x81\x51\x2c\xbc\xe6\xe9\x75"
+ "\x8a\x71\x43\xd0\x21\x97\x80\x22\xa3\x84\x14\x1a\x80\xce\xa3\x06"
+ },
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x89\x67\x09\x52\x60\x83\x64\xfd\x00\xb2\xf9\x09\x36\xf0\x31\xc8"
+ "\xe7\x56\xe1\x5d\xba\x04\xb8\x49\x3d\x00\x42\x92\x59\xb2\x0f\x46"
+ "\xcc\x04\xf1\x11\x24\x6b\x6c\x2c\xe0\x66\xbe\x3b\xfb\x32\xd9\xaa"
+ "\x0f\xdd\xfb\xc1\x21\x23\xd4\xb9\xe4\x4f\x34\xdc\xa0\x5a\x10\x3f"
+ "\x6c\xd1\x35\xc2\x87\x8c\x83\x2b\x58\x96\xb1\x34\xf6\x14\x2a\x9d"
+ "\x4d\x8d\x0d\x8f\x10\x26\xd2\x0a\x0a\x81\x51\x2c\xbc\xe6\xe9\x75"
+ "\x8a\x71\x43\xd0\x21\x97\x80\x22\xa3\x84\x14\x1a\x80\xce\xa3\x06"
+ "\x2f\x41\xf6\x7a\x75\x2e\x66\xad\x34\x11\x98\x4c\x78\x7e\x30\xad"
+ }
+ }
+ },
+ {
+ "ChaCha20 256 bit, TC1",
+ GCRY_CIPHER_CHACHA20, 32, 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90"
+ },
+ { 112,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28"
+ "\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7"
+ "\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37"
+ "\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86"
+ "\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d"
+ "\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed"
+ "\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5"
+ },
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28"
+ "\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7"
+ "\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37"
+ "\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86"
+ "\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d"
+ "\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed"
+ "\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5"
+ "\x31\xed\x1f\x28\x51\x0a\xfb\x45\xac\xe1\x0a\x1f\x4b\x79\x4d\x6f"
+ }
+ }
+ },
+ {
+ "ChaCha20 256 bit, TC2",
+ GCRY_CIPHER_CHACHA20, 32, 8,
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xc5\xd3\x0a\x7c\xe1\xec\x11\x93\x78\xc8\x4f\x48\x7d\x77\x5a\x85"
+ "\x42\xf1\x3e\xce\x23\x8a\x94\x55\xe8\x22\x9e\x88\x8d\xe8\x5b\xbd"
+ "\x29\xeb\x63\xd0\xa1\x7a\x5b\x99\x9b\x52\xda\x22\xbe\x40\x23\xeb"
+ "\x07\x62\x0a\x54\xf6\xfa\x6a\xd8\x73\x7b\x71\xeb\x04\x64\xda\xc0"
+ "\x10\xf6\x56\xe6\xd1\xfd\x55\x05\x3e\x50\xc4\x87\x5c\x99\x30\xa3"
+ "\x3f\x6d\x02\x63\xbd\x14\xdf\xd6\xab\x8c\x70\x52\x1c\x19\x33\x8b"
+ "\x23\x08\xb9\x5c\xf8\xd0\xbb\x7d\x20\x2d\x21\x02\x78\x0e\xa3\x52"
+ "\x8f\x1c\xb4\x85\x60\xf7\x6b\x20\xf3\x82\xb9\x42\x50\x0f\xce\xac"
+ }
+ }
+ },
+ {
+ "ChaCha20 256 bit, TC3",
+ GCRY_CIPHER_CHACHA20, 32, 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x01\x00\x00\x00\x00\x00\x00\x00",
+ {
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xef\x3f\xdf\xd6\xc6\x15\x78\xfb\xf5\xcf\x35\xbd\x3d\xd3\x3b\x80"
+ "\x09\x63\x16\x34\xd2\x1e\x42\xac\x33\x96\x0b\xd1\x38\xe5\x0d\x32"
+ "\x11\x1e\x4c\xaf\x23\x7e\xe5\x3c\xa8\xad\x64\x26\x19\x4a\x88\x54"
+ "\x5d\xdc\x49\x7a\x0b\x46\x6e\x7d\x6b\xbd\xb0\x04\x1b\x2f\x58\x6b"
+ "\x53\x05\xe5\xe4\x4a\xff\x19\xb2\x35\x93\x61\x44\x67\x5e\xfb\xe4"
+ "\x40\x9e\xb7\xe8\xe5\xf1\x43\x0f\x5f\x58\x36\xae\xb4\x9b\xb5\x32"
+ "\x8b\x01\x7c\x4b\x9d\xc1\x1f\x8a\x03\x86\x3f\xa8\x03\xdc\x71\xd5"
+ "\x72\x6b\x2b\x6b\x31\xaa\x32\x70\x8a\xfe\x5a\xf1\xd6\xb6\x90\x58"
+ }
+ }
+ },
+ {
+ "ChaCha20 256 bit, TC4",
+ GCRY_CIPHER_CHACHA20, 32, 8,
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
+ "\xff\xff\xff\xff\xff\xff\xff\xff",
+ {
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xd9\xbf\x3f\x6b\xce\x6e\xd0\xb5\x42\x54\x55\x77\x67\xfb\x57\x44"
+ "\x3d\xd4\x77\x89\x11\xb6\x06\x05\x5c\x39\xcc\x25\xe6\x74\xb8\x36"
+ "\x3f\xea\xbc\x57\xfd\xe5\x4f\x79\x0c\x52\xc8\xae\x43\x24\x0b\x79"
+ "\xd4\x90\x42\xb7\x77\xbf\xd6\xcb\x80\xe9\x31\x27\x0b\x7f\x50\xeb"
+ "\x5b\xac\x2a\xcd\x86\xa8\x36\xc5\xdc\x98\xc1\x16\xc1\x21\x7e\xc3"
+ "\x1d\x3a\x63\xa9\x45\x13\x19\xf0\x97\xf3\xb4\xd6\xda\xb0\x77\x87"
+ "\x19\x47\x7d\x24\xd2\x4b\x40\x3a\x12\x24\x1d\x7c\xca\x06\x4f\x79"
+ "\x0f\x1d\x51\xcc\xaf\xf6\xb1\x66\x7d\x4b\xbc\xa1\x95\x8c\x43\x06"
+ }
+ }
+ },
+ {
+ "ChaCha20 256 bit, TC5",
+ GCRY_CIPHER_CHACHA20, 32, 8,
+ "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55"
+ "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55",
+ "\x55\x55\x55\x55\x55\x55\x55\x55",
+ {
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xbe\xa9\x41\x1a\xa4\x53\xc5\x43\x4a\x5a\xe8\xc9\x28\x62\xf5\x64"
+ "\x39\x68\x55\xa9\xea\x6e\x22\xd6\xd3\xb5\x0a\xe1\xb3\x66\x33\x11"
+ "\xa4\xa3\x60\x6c\x67\x1d\x60\x5c\xe1\x6c\x3a\xec\xe8\xe6\x1e\xa1"
+ "\x45\xc5\x97\x75\x01\x7b\xee\x2f\xa6\xf8\x8a\xfc\x75\x80\x69\xf7"
+ "\xe0\xb8\xf6\x76\xe6\x44\x21\x6f\x4d\x2a\x34\x22\xd7\xfa\x36\xc6"
+ "\xc4\x93\x1a\xca\x95\x0e\x9d\xa4\x27\x88\xe6\xd0\xb6\xd1\xcd\x83"
+ "\x8e\xf6\x52\xe9\x7b\x14\x5b\x14\x87\x1e\xae\x6c\x68\x04\xc7\x00"
+ "\x4d\xb5\xac\x2f\xce\x4c\x68\xc7\x26\xd0\x04\xb1\x0f\xca\xba\x86"
+ }
+ }
+ },
+ {
+ "ChaCha20 256 bit, TC6",
+ GCRY_CIPHER_CHACHA20, 32, 8,
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ {
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x9a\xa2\xa9\xf6\x56\xef\xde\x5a\xa7\x59\x1c\x5f\xed\x4b\x35\xae"
+ "\xa2\x89\x5d\xec\x7c\xb4\x54\x3b\x9e\x9f\x21\xf5\xe7\xbc\xbc\xf3"
+ "\xc4\x3c\x74\x8a\x97\x08\x88\xf8\x24\x83\x93\xa0\x9d\x43\xe0\xb7"
+ "\xe1\x64\xbc\x4d\x0b\x0f\xb2\x40\xa2\xd7\x21\x15\xc4\x80\x89\x06"
+ "\x72\x18\x44\x89\x44\x05\x45\xd0\x21\xd9\x7e\xf6\xb6\x93\xdf\xe5"
+ "\xb2\xc1\x32\xd4\x7e\x6f\x04\x1c\x90\x63\x65\x1f\x96\xb6\x23\xe6"
+ "\x2a\x11\x99\x9a\x23\xb6\xf7\xc4\x61\xb2\x15\x30\x26\xad\x5e\x86"
+ "\x6a\x2e\x59\x7e\xd0\x7b\x84\x01\xde\xc6\x3a\x09\x34\xc6\xb2\xa9"
+ }
+ }
+ },
+ {
+ "ChaCha20 256 bit, TC7",
+ GCRY_CIPHER_CHACHA20, 32, 8,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
+ "\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00",
+ "\x0f\x1e\x2d\x3c\x4b\x5a\x69\x78",
+ {
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x9f\xad\xf4\x09\xc0\x08\x11\xd0\x04\x31\xd6\x7e\xfb\xd8\x8f\xba"
+ "\x59\x21\x8d\x5d\x67\x08\xb1\xd6\x85\x86\x3f\xab\xbb\x0e\x96\x1e"
+ "\xea\x48\x0f\xd6\xfb\x53\x2b\xfd\x49\x4b\x21\x51\x01\x50\x57\x42"
+ "\x3a\xb6\x0a\x63\xfe\x4f\x55\xf7\xa2\x12\xe2\x16\x7c\xca\xb9\x31"
+ "\xfb\xfd\x29\xcf\x7b\xc1\xd2\x79\xed\xdf\x25\xdd\x31\x6b\xb8\x84"
+ "\x3d\x6e\xde\xe0\xbd\x1e\xf1\x21\xd1\x2f\xa1\x7c\xbc\x2c\x57\x4c"
+ "\xcc\xab\x5e\x27\x51\x67\xb0\x8b\xd6\x86\xf8\xa0\x9d\xf8\x7e\xc3"
+ "\xff\xb3\x53\x61\xb9\x4e\xbf\xa1\x3f\xec\x0e\x48\x89\xd1\x8d\xa5"
+ }
+ }
+ },
+ {
+ "ChaCha20 256 bit, TC8",
+ GCRY_CIPHER_CHACHA20, 32, 8,
+ "\xc4\x6e\xc1\xb1\x8c\xe8\xa8\x78\x72\x5a\x37\xe7\x80\xdf\xb7\x35"
+ "\x1f\x68\xed\x2e\x19\x4c\x79\xfb\xc6\xae\xbe\xe1\xa6\x67\x97\x5d",
+ "\x1a\xda\x31\xd5\xcf\x68\x82\x21",
+ {
+ { 128,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xf6\x3a\x89\xb7\x5c\x22\x71\xf9\x36\x88\x16\x54\x2b\xa5\x2f\x06"
+ "\xed\x49\x24\x17\x92\x30\x2b\x00\xb5\xe8\xf8\x0a\xe9\xa4\x73\xaf"
+ "\xc2\x5b\x21\x8f\x51\x9a\xf0\xfd\xd4\x06\x36\x2e\x8d\x69\xde\x7f"
+ "\x54\xc6\x04\xa6\xe0\x0f\x35\x3f\x11\x0f\x77\x1b\xdc\xa8\xab\x92"
+ "\xe5\xfb\xc3\x4e\x60\xa1\xd9\xa9\xdb\x17\x34\x5b\x0a\x40\x27\x36"
+ "\x85\x3b\xf9\x10\xb0\x60\xbd\xf1\xf8\x97\xb6\x29\x0f\x01\xd1\x38"
+ "\xae\x2c\x4c\x90\x22\x5b\xa9\xea\x14\xd5\x18\xf5\x59\x29\xde\xa0"
+ "\x98\xca\x7a\x6c\xcf\xe6\x12\x27\x05\x3c\x84\xe4\x9a\x4a\x33\x32"
+ },
+ { 127,
+ "\xf6\x3a\x89\xb7\x5c\x22\x71\xf9\x36\x88\x16\x54\x2b\xa5\x2f\x06"
+ "\xed\x49\x24\x17\x92\x30\x2b\x00\xb5\xe8\xf8\x0a\xe9\xa4\x73\xaf"
+ "\xc2\x5b\x21\x8f\x51\x9a\xf0\xfd\xd4\x06\x36\x2e\x8d\x69\xde\x7f"
+ "\x54\xc6\x04\xa6\xe0\x0f\x35\x3f\x11\x0f\x77\x1b\xdc\xa8\xab\x92"
+ "\xe5\xfb\xc3\x4e\x60\xa1\xd9\xa9\xdb\x17\x34\x5b\x0a\x40\x27\x36"
+ "\x85\x3b\xf9\x10\xb0\x60\xbd\xf1\xf8\x97\xb6\x29\x0f\x01\xd1\x38"
+ "\xae\x2c\x4c\x90\x22\x5b\xa9\xea\x14\xd5\x18\xf5\x59\x29\xde\xa0"
+ "\x98\xca\x7a\x6c\xcf\xe6\x12\x27\x05\x3c\x84\xe4\x9a\x4a\x33",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ }
+ }
+ },
+ /* from draft-nir-cfrg-chacha20-poly1305-02 */
+ {
+ "ChaCha20 256 bit, IV96-bit",
+ GCRY_CIPHER_CHACHA20, 32, 12,
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
+ "\x07\x00\x00\x00\x40\x41\x42\x43\x44\x45\x46\x47",
+ {
+ { 64,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x7b\xac\x2b\x25\x2d\xb4\x47\xaf\x09\xb6\x7a\x55\xa4\xe9\x55\x84"
+ "\x0a\xe1\xd6\x73\x10\x75\xd9\xeb\x2a\x93\x75\x78\x3e\xd5\x53\xff"
+ "\xa2\x7e\xcc\xde\xad\xdb\x4d\xb4\xd1\x17\x9c\xe4\xc9\x0b\x43\xd8"
+ "\xbc\xb7\x94\x8c\x4b\x4b\x7d\x8b\x7d\xf6\x27\x39\x32\xa4\x69\x16"
+ },
+ },
+ },
+#endif /*USE_CHACHA20*/
+ };
+
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, j;
+ gcry_error_t err = 0;
+
+
+ if (verbose)
+ fprintf (stderr, " Starting stream cipher checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr, " checking stream mode for %s [%i] (%s)\n",
+ gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].name);
+
+ if (gcry_cipher_get_algo_blklen(tv[i].algo) != 1)
+ {
+ fail ("stream, gcry_cipher_get_algo_blklen: bad block length\n");
+ continue;
+ }
+
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_open for stream mode failed: %s\n",
+ gpg_strerror (err));
+ continue;
+ }
+
+ /* Now loop over all the data samples. */
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ goto next;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ goto next;
+ }
+
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ tv[i].data[j].plaintext,
+ tv[i].data[j].inlen);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ goto next;
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ {
+ fail ("stream, encrypt mismatch entry %d:%d\n", i, j);
+ mismatch (tv[i].data[j].out, tv[i].data[j].inlen,
+ out, tv[i].data[j].inlen);
+ }
+
+ err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ goto next;
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("stream, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+
+ /* This time we encrypt and decrypt one byte at a time */
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ int byteNum;
+
+ err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ goto next;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ goto next;
+ }
+
+ for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+ {
+ err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+ (tv[i].data[j].plaintext) + byteNum,
+ 1);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ goto next;
+ }
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ fail ("stream, encrypt mismatch entry %d:%d (byte-wise)\n", i, j);
+
+ for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+ {
+ err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+ if (err)
+ {
+ fail ("stream, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ goto next;
+ }
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("stream, decrypt mismatch entry %d:%d (byte-wise)\n", i, j);
+ }
+
+ next:
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed stream cipher checks.\n");
+}
+
+
+static void
+check_stream_cipher_large_block (void)
+{
+ static const struct tv
+ {
+ const char *name;
+ int algo;
+ int keylen;
+ int ivlen;
+ const char *key;
+ const char *iv;
+ struct data
+ {
+ int offset, length;
+ const char *result;
+ } data[MAX_DATA_LEN];
+ } tv[] = {
+#ifdef USE_SALSA20
+ {
+ "Salsa20 256 bit, ecrypt verified, set 6, vector 0",
+ GCRY_CIPHER_SALSA20, 32, 8,
+ "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD"
+ "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D",
+ "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+ {
+ { 0, 64,
+ "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58\xC4\xAE\xA0\xD0\xED\x9A\x96\x01"
+ "\xF2\x78\x11\x2C\xA7\x18\x0D\x56\x5B\x42\x0A\x48\x01\x96\x70\xEA"
+ "\xF2\x4C\xE4\x93\xA8\x62\x63\xF6\x77\xB4\x6A\xCE\x19\x24\x77\x3D"
+ "\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71"
+ },
+ { 65472, 64,
+ "\xB7\x0C\x50\x13\x9C\x63\x33\x2E\xF6\xE7\x7A\xC5\x43\x38\xA4\x07"
+ "\x9B\x82\xBE\xC9\xF9\xA4\x03\xDF\xEA\x82\x1B\x83\xF7\x86\x07\x91"
+ "\x65\x0E\xF1\xB2\x48\x9D\x05\x90\xB1\xDE\x77\x2E\xED\xA4\xE3\xBC"
+ "\xD6\x0F\xA7\xCE\x9C\xD6\x23\xD9\xD2\xFD\x57\x58\xB8\x65\x3E\x70"
+ },
+ { 65536, 64,
+ "\x81\x58\x2C\x65\xD7\x56\x2B\x80\xAE\xC2\xF1\xA6\x73\xA9\xD0\x1C"
+ "\x9F\x89\x2A\x23\xD4\x91\x9F\x6A\xB4\x7B\x91\x54\xE0\x8E\x69\x9B"
+ "\x41\x17\xD7\xC6\x66\x47\x7B\x60\xF8\x39\x14\x81\x68\x2F\x5D\x95"
+ "\xD9\x66\x23\xDB\xC4\x89\xD8\x8D\xAA\x69\x56\xB9\xF0\x64\x6B\x6E"
+ },
+ { 131008, 64,
+ "\xA1\x3F\xFA\x12\x08\xF8\xBF\x50\x90\x08\x86\xFA\xAB\x40\xFD\x10"
+ "\xE8\xCA\xA3\x06\xE6\x3D\xF3\x95\x36\xA1\x56\x4F\xB7\x60\xB2\x42"
+ "\xA9\xD6\xA4\x62\x8C\xDC\x87\x87\x62\x83\x4E\x27\xA5\x41\xDA\x2A"
+ "\x5E\x3B\x34\x45\x98\x9C\x76\xF6\x11\xE0\xFE\xC6\xD9\x1A\xCA\xCC"
+ }
+ }
+ },
+ {
+ "Salsa20 256 bit, ecrypt verified, set 6, vector 1",
+ GCRY_CIPHER_SALSA20, 32, 8,
+ "\x05\x58\xAB\xFE\x51\xA4\xF7\x4A\x9D\xF0\x43\x96\xE9\x3C\x8F\xE2"
+ "\x35\x88\xDB\x2E\x81\xD4\x27\x7A\xCD\x20\x73\xC6\x19\x6C\xBF\x12",
+ "\x16\x7D\xE4\x4B\xB2\x19\x80\xE7",
+ {
+ { 0, 64,
+ "\x39\x44\xF6\xDC\x9F\x85\xB1\x28\x08\x38\x79\xFD\xF1\x90\xF7\xDE"
+ "\xE4\x05\x3A\x07\xBC\x09\x89\x6D\x51\xD0\x69\x0B\xD4\xDA\x4A\xC1"
+ "\x06\x2F\x1E\x47\xD3\xD0\x71\x6F\x80\xA9\xB4\xD8\x5E\x6D\x60\x85"
+ "\xEE\x06\x94\x76\x01\xC8\x5F\x1A\x27\xA2\xF7\x6E\x45\xA6\xAA\x87"
+ },
+ { 65472, 64,
+ "\x36\xE0\x3B\x4B\x54\xB0\xB2\xE0\x4D\x06\x9E\x69\x00\x82\xC8\xC5"
+ "\x92\xDF\x56\xE6\x33\xF5\xD8\xC7\x68\x2A\x02\xA6\x5E\xCD\x13\x71"
+ "\x8C\xA4\x35\x2A\xAC\xCB\x0D\xA2\x0E\xD6\xBB\xBA\x62\xE1\x77\xF2"
+ "\x10\xE3\x56\x0E\x63\xBB\x82\x2C\x41\x58\xCA\xA8\x06\xA8\x8C\x82"
+ },
+ { 65536, 64,
+ "\x1B\x77\x9E\x7A\x91\x7C\x8C\x26\x03\x9F\xFB\x23\xCF\x0E\xF8\xE0"
+ "\x8A\x1A\x13\xB4\x3A\xCD\xD9\x40\x2C\xF5\xDF\x38\x50\x10\x98\xDF"
+ "\xC9\x45\xA6\xCC\x69\xA6\xA1\x73\x67\xBC\x03\x43\x1A\x86\xB3\xED"
+ "\x04\xB0\x24\x5B\x56\x37\x9B\xF9\x97\xE2\x58\x00\xAD\x83\x7D\x7D"
+ },
+ { 131008, 64,
+ "\x7E\xC6\xDA\xE8\x1A\x10\x5E\x67\x17\x2A\x0B\x8C\x4B\xBE\x7D\x06"
+ "\xA7\xA8\x75\x9F\x91\x4F\xBE\xB1\xAF\x62\xC8\xA5\x52\xEF\x4A\x4F"
+ "\x56\x96\x7E\xA2\x9C\x74\x71\xF4\x6F\x3B\x07\xF7\xA3\x74\x6E\x95"
+ "\x3D\x31\x58\x21\xB8\x5B\x6E\x8C\xB4\x01\x22\xB9\x66\x35\x31\x3C"
+ }
+ }
+ },
+ {
+ "Salsa20 256 bit, ecrypt verified, set 6, vector 2",
+ GCRY_CIPHER_SALSA20, 32, 8,
+ "\x0A\x5D\xB0\x03\x56\xA9\xFC\x4F\xA2\xF5\x48\x9B\xEE\x41\x94\xE7"
+ "\x3A\x8D\xE0\x33\x86\xD9\x2C\x7F\xD2\x25\x78\xCB\x1E\x71\xC4\x17",
+ "\x1F\x86\xED\x54\xBB\x22\x89\xF0",
+ {
+ { 0, 64,
+ "\x3F\xE8\x5D\x5B\xB1\x96\x0A\x82\x48\x0B\x5E\x6F\x4E\x96\x5A\x44"
+ "\x60\xD7\xA5\x45\x01\x66\x4F\x7D\x60\xB5\x4B\x06\x10\x0A\x37\xFF"
+ "\xDC\xF6\xBD\xE5\xCE\x3F\x48\x86\xBA\x77\xDD\x5B\x44\xE9\x56\x44"
+ "\xE4\x0A\x8A\xC6\x58\x01\x15\x5D\xB9\x0F\x02\x52\x2B\x64\x40\x23"
+ },
+ { 65472, 64,
+ "\xC8\xD6\xE5\x4C\x29\xCA\x20\x40\x18\xA8\x30\xE2\x66\xCE\xEE\x0D"
+ "\x03\x7D\xC4\x7E\x92\x19\x47\x30\x2A\xCE\x40\xD1\xB9\x96\xA6\xD8"
+ "\x0B\x59\x86\x77\xF3\x35\x2F\x1D\xAA\x6D\x98\x88\xF8\x91\xAD\x95"
+ "\xA1\xC3\x2F\xFE\xB7\x1B\xB8\x61\xE8\xB0\x70\x58\x51\x51\x71\xC9"
+ },
+ { 65536, 64,
+ "\xB7\x9F\xD7\x76\x54\x2B\x46\x20\xEF\xCB\x88\x44\x95\x99\xF2\x34"
+ "\x03\xE7\x4A\x6E\x91\xCA\xCC\x50\xA0\x5A\x8F\x8F\x3C\x0D\xEA\x8B"
+ "\x00\xE1\xA5\xE6\x08\x1F\x55\x26\xAE\x97\x5B\x3B\xC0\x45\x0F\x1A"
+ "\x0C\x8B\x66\xF8\x08\xF1\x90\x4B\x97\x13\x61\x13\x7C\x93\x15\x6F"
+ },
+ { 131008, 64,
+ "\x79\x98\x20\x4F\xED\x70\xCE\x8E\x0D\x02\x7B\x20\x66\x35\xC0\x8C"
+ "\x8B\xC4\x43\x62\x26\x08\x97\x0E\x40\xE3\xAE\xDF\x3C\xE7\x90\xAE"
+ "\xED\xF8\x9F\x92\x26\x71\xB4\x53\x78\xE2\xCD\x03\xF6\xF6\x23\x56"
+ "\x52\x9C\x41\x58\xB7\xFF\x41\xEE\x85\x4B\x12\x35\x37\x39\x88\xC8"
+ }
+ }
+ },
+ {
+ "Salsa20 256 bit, ecrypt verified, set 6, vector 3",
+ GCRY_CIPHER_SALSA20, 32, 8,
+ "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC"
+ "\x3F\x92\xE5\x38\x8B\xDE\x31\x84\xD7\x2A\x7D\xD0\x23\x76\xC9\x1C",
+ "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9",
+ {
+ { 0, 64,
+ "\x5E\x5E\x71\xF9\x01\x99\x34\x03\x04\xAB\xB2\x2A\x37\xB6\x62\x5B"
+ "\xF8\x83\xFB\x89\xCE\x3B\x21\xF5\x4A\x10\xB8\x10\x66\xEF\x87\xDA"
+ "\x30\xB7\x76\x99\xAA\x73\x79\xDA\x59\x5C\x77\xDD\x59\x54\x2D\xA2"
+ "\x08\xE5\x95\x4F\x89\xE4\x0E\xB7\xAA\x80\xA8\x4A\x61\x76\x66\x3F"
+ },
+ { 65472, 64,
+ "\x2D\xA2\x17\x4B\xD1\x50\xA1\xDF\xEC\x17\x96\xE9\x21\xE9\xD6\xE2"
+ "\x4E\xCF\x02\x09\xBC\xBE\xA4\xF9\x83\x70\xFC\xE6\x29\x05\x6F\x64"
+ "\x91\x72\x83\x43\x6E\x2D\x3F\x45\x55\x62\x25\x30\x7D\x5C\xC5\xA5"
+ "\x65\x32\x5D\x89\x93\xB3\x7F\x16\x54\x19\x5C\x24\x0B\xF7\x5B\x16"
+ },
+ { 65536, 64,
+ "\xAB\xF3\x9A\x21\x0E\xEE\x89\x59\x8B\x71\x33\x37\x70\x56\xC2\xFE"
+ "\xF4\x2D\xA7\x31\x32\x75\x63\xFB\x67\xC7\xBE\xDB\x27\xF3\x8C\x7C"
+ "\x5A\x3F\xC2\x18\x3A\x4C\x6B\x27\x7F\x90\x11\x52\x47\x2C\x6B\x2A"
+ "\xBC\xF5\xE3\x4C\xBE\x31\x5E\x81\xFD\x3D\x18\x0B\x5D\x66\xCB\x6C"
+ },
+ { 131008, 64,
+ "\x1B\xA8\x9D\xBD\x3F\x98\x83\x97\x28\xF5\x67\x91\xD5\xB7\xCE\x23"
+ "\x50\x36\xDE\x84\x3C\xCC\xAB\x03\x90\xB8\xB5\x86\x2F\x1E\x45\x96"
+ "\xAE\x8A\x16\xFB\x23\xDA\x99\x7F\x37\x1F\x4E\x0A\xAC\xC2\x6D\xB8"
+ "\xEB\x31\x4E\xD4\x70\xB1\xAF\x6B\x9F\x8D\x69\xDD\x79\xA9\xD7\x50"
+ }
+ }
+ },
+ {
+ "Salsa20/12 256 bit, ecrypt verified, set 6, vector 0",
+ GCRY_CIPHER_SALSA20R12, 32, 8,
+ "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD"
+ "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D",
+ "\x0D\x74\xDB\x42\xA9\x10\x77\xDE",
+ {
+ { 0, 64,
+ "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82\xF2\x00\xC2\x99\x9F\xE4\xBA\x31"
+ "\xA7\xA1\x8F\x1D\x5C\x97\x16\x19\x1D\x12\x31\x75\xE1\x47\xBD\x4E"
+ "\x8C\xA6\xED\x16\x6C\xE0\xFC\x8E\x65\xA5\xCA\x60\x84\x20\xFC\x65"
+ "\x44\xC9\x70\x0A\x0F\x21\x38\xE8\xC1\xA2\x86\xFB\x8C\x1F\xBF\xA0"
+ },
+ { 65472, 64,
+ "\x8F\xBC\x9F\xE8\x69\x1B\xD4\xF0\x82\xB4\x7F\x54\x05\xED\xFB\xC1"
+ "\x6F\x4D\x5A\x12\xDD\xCB\x2D\x75\x4E\x8A\x99\x98\xD0\xB2\x19\x55"
+ "\x7D\xFE\x29\x84\xF4\xA1\xD2\xDD\xA7\x6B\x95\x96\x92\x8C\xCE\x05"
+ "\x56\xF5\x00\x66\xCD\x59\x9E\x44\xEF\x5C\x14\xB2\x26\x68\x3A\xEF"
+ },
+ { 65536, 64,
+ "\xBC\xBD\x01\xDD\x28\x96\x1C\xC7\xAD\x30\x47\x38\x6C\xBC\xC6\x7C"
+ "\x10\x8D\x6A\xF1\x11\x67\xE4\x0D\x7A\xE1\xB2\xFC\x45\x18\xA8\x67"
+ "\xEF\xE4\x02\x65\x1D\x1D\x88\x51\xC4\xFD\x23\x30\xC5\x97\xB3\x6A"
+ "\x46\xD5\x68\x9E\x00\xFC\x96\xFE\xCF\x9C\xE3\xE2\x21\x1D\x44\xBE"
+ },
+ { 131008, 64,
+ "\x91\x66\xF3\x1C\xD8\x5B\x5B\xB1\x8F\xC6\x14\xE5\x4E\x4A\xD6\x7F"
+ "\xB8\x65\x8E\x3B\xF9\xFB\x19\xB7\xA8\x2F\x0F\xE7\xDC\x90\x2D\xF5"
+ "\x63\xC6\xAC\x4F\x44\x67\x48\xC4\xBC\x3E\x14\x05\xE1\x24\x82\x0D"
+ "\xC4\x09\x41\x99\x8F\x44\xA8\x10\xE7\x22\x78\x7F\xCD\x47\x78\x4C"
+ }
+ }
+ },
+ {
+ "Salsa20/12 256 bit, ecrypt verified, set 6, vector 1",
+ GCRY_CIPHER_SALSA20R12, 32, 8,
+ "\x05\x58\xAB\xFE\x51\xA4\xF7\x4A\x9D\xF0\x43\x96\xE9\x3C\x8F\xE2"
+ "\x35\x88\xDB\x2E\x81\xD4\x27\x7A\xCD\x20\x73\xC6\x19\x6C\xBF\x12",
+ "\x16\x7D\xE4\x4B\xB2\x19\x80\xE7",
+ {
+ { 0, 64,
+ "\xC0\x75\x60\xB3\xE7\x76\xB4\x71\xC5\xE2\x93\x14\x26\xCA\xF1\xED"
+ "\x3A\xE4\xB8\x67\x08\x76\x82\xCA\x9D\xFD\xC2\xBA\xE8\x93\x50\xBD"
+ "\x84\x82\x1C\xAE\xFF\x85\xAA\xC4\x9D\x74\x35\xA7\xD9\x88\x93\x52"
+ "\xF5\x27\x9E\x36\x12\x3F\x41\x72\x8A\x14\xEF\x26\x9F\xCB\x94\x4B"
+ },
+ { 65472, 64,
+ "\xEE\xD1\xBB\x58\xF9\x0C\x89\xE0\x5C\xC6\x8B\x2D\xB6\x05\x58\x49"
+ "\xB3\xD2\xB1\x87\xB7\xF0\x2F\x9A\x24\xCE\x34\x2A\xF0\xFC\x47\xA3"
+ "\x74\xBD\x75\x90\xFB\xF4\xFD\x9E\xE5\x9B\x1A\x38\x1E\xBF\xD2\x29"
+ "\xAD\x2A\x29\x01\xB3\xFB\x61\x08\x12\x90\x0B\x92\x30\xE6\x22\xE9"
+ },
+ { 65536, 64,
+ "\x70\xF0\x49\x3A\x1B\x62\x53\xCC\x5E\xD3\x45\x0A\x31\xCF\x37\x7D"
+ "\x83\x4B\xAD\x20\x72\x30\x29\x27\xCC\xD8\x30\x10\x4B\xD3\x05\xFF"
+ "\x59\xD2\x94\x17\xB2\x32\x88\x4E\xC9\x59\x19\x4D\x60\x47\xC3\xDD"
+ "\x66\x56\xC4\x7E\x32\x00\x64\xEB\x01\x44\xF7\x34\x1B\xC3\xD6\x97"
+ },
+ { 131008, 64,
+ "\xD2\xCC\xF7\xC1\xAF\x2A\xB4\x66\xE6\x27\xDB\x44\x08\x40\x96\x9A"
+ "\xBD\xAB\x68\xD8\x86\xAE\x6A\x38\xA1\x3F\xEE\x17\x50\xCA\x97\xB5"
+ "\xD3\x31\x5B\x84\x08\x47\x28\x86\x2F\xBC\xC7\xD4\xA9\x7C\x75\xC8"
+ "\x65\x5F\xF9\xD6\xBB\xC2\x61\x88\x63\x6F\x3E\xDF\xE1\x5C\x7D\x30"
+ }
+ }
+ },
+ {
+ "Salsa20/12 256 bit, ecrypt verified, set 6, vector 2",
+ GCRY_CIPHER_SALSA20R12, 32, 8,
+ "\x0A\x5D\xB0\x03\x56\xA9\xFC\x4F\xA2\xF5\x48\x9B\xEE\x41\x94\xE7"
+ "\x3A\x8D\xE0\x33\x86\xD9\x2C\x7F\xD2\x25\x78\xCB\x1E\x71\xC4\x17",
+ "\x1F\x86\xED\x54\xBB\x22\x89\xF0",
+ {
+ { 0, 64,
+ "\x51\x22\x52\x91\x01\x90\xD1\x54\xD1\x4D\x0B\x92\x32\xB8\x84\x31"
+ "\x8C\xCB\x43\x81\x9B\xD5\x42\x19\x32\xC0\x3A\x13\xF0\x7B\x40\x10"
+ "\x83\xD7\x89\x72\x5A\xA9\xDA\x0B\x41\xCB\x62\x24\x94\x5E\xDC\xB0"
+ "\xFB\x6F\xD7\xC2\x34\x22\x35\xC9\x70\xF6\x4E\x10\x1C\x25\x68\x64"
+ },
+ { 65472, 64,
+ "\x97\x96\x74\x55\x84\x0A\x4A\xE5\xC1\xCA\xCE\x49\x15\x19\x13\x8A"
+ "\xA3\x5E\x5F\x02\x40\x7D\x4A\x1F\xE5\x08\x6D\x35\xF3\x55\x1E\xF4"
+ "\x77\xD9\x28\x9D\x17\x23\x79\x7C\x1A\x49\xEC\x26\x62\x9A\xFA\xDC"
+ "\x56\xA0\x38\xA3\x8C\x75\x88\x1B\x62\x17\xFD\x74\x67\x25\x59\x09"
+ },
+ { 65536, 64,
+ "\x1B\xF8\x2E\x3D\x5C\x54\xDA\xAB\xCF\x84\x15\xF8\xA2\xA1\xA2\x2E"
+ "\x86\x88\x06\x33\x4F\xF3\x11\x36\x04\x74\x1C\x1D\xF2\xB9\x84\x0F"
+ "\x87\xDE\xEF\xB0\x07\x23\xA8\xA1\xB2\x4A\x4D\xA1\x7E\xCD\xAD\x00"
+ "\x01\xF9\x79\xDD\xAE\x2D\xF0\xC5\xE1\xE5\x32\xC4\x8F\x8E\x0D\x34"
+ },
+ { 131008, 64,
+ "\x06\xD8\x4F\x6A\x71\x34\x84\x20\x32\x9F\xCD\x0C\x41\x75\x9A\xD1"
+ "\x8F\x99\x57\xA3\x8F\x22\x89\x3B\xA5\x58\xC5\x05\x11\x97\x28\x5C"
+ "\x6B\xE2\xFD\x6C\x96\xA5\xC6\x62\xAF\xD3\x11\x78\xE7\x0F\x96\x0A"
+ "\xAB\x3F\x47\x96\x23\xA4\x44\xB6\x81\x91\xE4\xC5\x28\x46\x93\x88"
+ }
+ }
+ },
+ {
+ "Salsa20/12 256 bit, ecrypt verified, set 6, vector 3",
+ GCRY_CIPHER_SALSA20R12, 32, 8,
+ "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC"
+ "\x3F\x92\xE5\x38\x8B\xDE\x31\x84\xD7\x2A\x7D\xD0\x23\x76\xC9\x1C",
+ "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9",
+ {
+ { 0, 64,
+ "\x99\xDB\x33\xAD\x11\xCE\x0C\xCB\x3B\xFD\xBF\x8D\x0C\x18\x16\x04"
+ "\x52\xD0\x14\xCD\xE9\x89\xB4\xC4\x11\xA5\x59\xFF\x7C\x20\xA1\x69"
+ "\xE6\xDC\x99\x09\xD8\x16\xBE\xCE\xDC\x40\x63\xCE\x07\xCE\xA8\x28"
+ "\xF4\x4B\xF9\xB6\xC9\xA0\xA0\xB2\x00\xE1\xB5\x2A\xF4\x18\x59\xC5"
+ },
+ { 65472, 64,
+ "\x2F\xF2\x02\x64\xEE\xAF\x47\xAB\x7D\x57\xC3\x62\x24\x53\x54\x51"
+ "\x73\x5A\xC8\x36\xD3\x2D\xD2\x8A\xE6\x36\x45\xCE\x95\x2F\x7F\xDB"
+ "\xE6\x68\x9C\x69\x59\x77\xB1\xC7\x6E\x60\xDD\x5B\x27\xAC\xA4\x76"
+ "\xD2\x62\x0F\xDC\x93\x13\xE8\x48\x9B\xA5\x6A\x70\xC9\xF4\xC3\xA8"
+ },
+ { 65536, 64,
+ "\xEB\x30\xCD\xA7\x27\xC0\xF8\xB7\xE4\x5D\x5E\xF3\x0D\xB7\xCB\xE0"
+ "\x21\xF2\x29\x1E\x5F\x56\x93\x8D\x56\xF6\x87\xB7\x37\xC3\xB4\x27"
+ "\x54\x5C\x56\xA6\xD3\xA0\xBF\x2B\x2F\x47\xB4\x84\x93\xFA\xE4\x5E"
+ "\xD5\x0C\x2E\x9B\xBE\x49\xFD\x92\xD6\x7C\x76\x49\x05\x5F\x06\xFD"
+ },
+ { 131008, 64,
+ "\x0E\xBF\x6C\xC3\xCB\xCB\xE7\x4E\x6E\xE8\x07\x47\x1B\x49\x2A\x67"
+ "\x39\xA5\x2F\x57\x11\x31\xA2\x50\xBC\xDF\xA0\x76\xA2\x65\x90\xD7"
+ "\xED\xE6\x75\x1C\x03\x26\xA0\x2C\xB1\x1C\x58\x77\x35\x52\x80\x4F"
+ "\xD8\x68\x67\x15\x35\x5C\x5A\x5C\xC5\x91\x96\x3A\x75\xE9\x94\xB4"
+ }
+ }
+ }
+#endif /*USE_SALSA20*/
+ };
+
+
+ char zeroes[512];
+ gcry_cipher_hd_t hde;
+ unsigned char *buffer;
+ unsigned char *p;
+ size_t buffersize;
+ unsigned int n;
+ int i, j;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting large block stream cipher checks.\n");
+
+ memset (zeroes, 0, 512);
+
+ buffersize = 128 * 1024;
+ buffer = gcry_xmalloc (buffersize+1024);
+ memset (buffer+buffersize, 0x5a, 1024);
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking large block stream for %s [%i] (%s)\n",
+ gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].name);
+
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0);
+ if (err)
+ {
+ fail ("large stream, gcry_cipher_open for stream mode failed: %s\n",
+ gpg_strerror (err));
+ continue;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+ if (err)
+ {
+ fail ("large stream, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ goto next;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("large stream, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ goto next;
+ }
+
+ for (j=0, p=buffer; j < buffersize/512; j++, p += 512)
+ {
+ err = gcry_cipher_encrypt (hde, p, 512, zeroes, 512);
+ if (err)
+ {
+ fail ("large stream, "
+ "gcry_cipher_encrypt (%d) block %d failed: %s\n",
+ i, j, gpg_strerror (err));
+ goto next;
+ }
+ }
+ for (j=0, p=buffer+buffersize; j < 1024; j++, p++)
+ if (*p != 0x5a)
+ die ("large stream, buffer corrupted at j=%d\n", j);
+
+ /* Now loop over all the data samples. */
+ for (j = 0; tv[i].data[j].length; j++)
+ {
+ assert (tv[i].data[j].offset + tv[i].data[j].length <= buffersize);
+
+ if (memcmp (tv[i].data[j].result,
+ buffer + tv[i].data[j].offset, tv[i].data[j].length))
+ {
+ fail ("large stream, encrypt mismatch entry %d:%d\n", i, j);
+ mismatch (tv[i].data[j].result, tv[i].data[j].length,
+ buffer + tv[i].data[j].offset, tv[i].data[j].length);
+ }
+ }
+
+ /*
+ * Let's do the same thing again but using changing block sizes.
+ */
+ err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+ if (err)
+ {
+ fail ("large stream, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ goto next;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("large stream, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ goto next;
+ }
+
+ for (n=0, p=buffer, j = 0; n < buffersize; n += j, p += j)
+ {
+ switch (j)
+ {
+ case 0: j = 1; break;
+ case 1: j = 64; break;
+ case 64: j= 384; break;
+ case 384: j = 63; break;
+ case 63: j = 512; break;
+ case 512: j = 32; break;
+ case 32: j = 503; break;
+ default: j = 509; break;
+ }
+ if ( n + j >= buffersize )
+ j = buffersize - n;
+ assert (j <= 512);
+ err = gcry_cipher_encrypt (hde, p, j, zeroes, j);
+ if (err)
+ {
+ fail ("large stream, "
+ "gcry_cipher_encrypt (%d) offset %u failed: %s\n",
+ i, n, gpg_strerror (err));
+ goto next;
+ }
+ }
+ for (j=0, p=buffer+buffersize; j < 1024; j++, p++)
+ if (*p != 0x5a)
+ die ("large stream, buffer corrupted at j=%d (line %d)\n",
+ j, __LINE__);
+
+ /* Now loop over all the data samples. */
+ for (j = 0; tv[i].data[j].length; j++)
+ {
+ assert (tv[i].data[j].offset + tv[i].data[j].length <= buffersize);
+
+ if (memcmp (tv[i].data[j].result,
+ buffer + tv[i].data[j].offset, tv[i].data[j].length))
+ {
+ fail ("large stream var, encrypt mismatch entry %d:%d\n", i, j);
+ mismatch (tv[i].data[j].result, tv[i].data[j].length,
+ buffer + tv[i].data[j].offset, tv[i].data[j].length);
+ }
+ }
+
+ next:
+ gcry_cipher_close (hde);
+ }
+
+ gcry_free (buffer);
+ if (verbose)
+ fprintf (stderr, " Completed large block stream cipher checks.\n");
+}
+
+
+
+/* Check that our bulk encryption functions work properly. */
+static void
+check_bulk_cipher_modes (void)
+{
+ static const struct
+ {
+ int algo;
+ int mode;
+ const char *key;
+ int keylen;
+ const char *iv;
+ int ivlen;
+ char t1_hash[20];
+ } tv[] = {
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[0]*/
+ { 0x53, 0xda, 0x27, 0x3c, 0x78, 0x3d, 0x54, 0x66, 0x19, 0x63,
+ 0xd7, 0xe6, 0x20, 0x10, 0xcd, 0xc0, 0x5a, 0x0b, 0x06, 0xcc }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[1]*/
+ { 0xc7, 0xb1, 0xd0, 0x09, 0x95, 0x04, 0x34, 0x61, 0x2b, 0xd9,
+ 0xcb, 0xb3, 0xc7, 0xcb, 0xef, 0xea, 0x16, 0x19, 0x9b, 0x3e }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[2]*/
+ { 0x31, 0xe1, 0x1f, 0x63, 0x65, 0x47, 0x8c, 0x3f, 0x53, 0xdb,
+ 0xd9, 0x4d, 0x91, 0x1d, 0x02, 0x9c, 0x05, 0x25, 0x58, 0x29 }
+ },
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[3]*/
+ { 0xdc, 0x0c, 0xc2, 0xd9, 0x6b, 0x47, 0xf9, 0xeb, 0x06, 0xb4,
+ 0x2f, 0x6e, 0xec, 0x72, 0xbf, 0x55, 0x26, 0x7f, 0xa9, 0x97 }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[4]*/
+ { 0x2b, 0x90, 0x9b, 0xe6, 0x40, 0xab, 0x6e, 0xc2, 0xc5, 0xb1,
+ 0x87, 0xf5, 0x43, 0x84, 0x7b, 0x04, 0x06, 0x47, 0xd1, 0x8f }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[5]*/
+ { 0xaa, 0xa8, 0xdf, 0x03, 0xb0, 0xba, 0xc4, 0xe3, 0xc1, 0x02,
+ 0x38, 0x31, 0x8d, 0x86, 0xcb, 0x49, 0x6d, 0xad, 0xae, 0x01 }
+ },
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[6]*/
+ { 0x65, 0xfe, 0xde, 0x48, 0xd0, 0xa1, 0xa6, 0xf9, 0x24, 0x6b,
+ 0x52, 0x5f, 0x21, 0x8a, 0x6f, 0xc7, 0x70, 0x3b, 0xd8, 0x4a }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[7]*/
+ { 0x59, 0x5b, 0x02, 0xa2, 0x88, 0xc0, 0xbe, 0x94, 0x43, 0xaa,
+ 0x39, 0xf6, 0xbd, 0xcc, 0x83, 0x99, 0xee, 0x00, 0xa1, 0x91 }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[8]*/
+ { 0x38, 0x8c, 0xe1, 0xe2, 0xbe, 0x67, 0x60, 0xe8, 0xeb, 0xce,
+ 0xd0, 0xc6, 0xaa, 0xd6, 0xf6, 0x26, 0x15, 0x56, 0xd0, 0x2b }
+ },
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[9]*/
+ { 0x9a, 0x48, 0x94, 0xd6, 0x50, 0x46, 0x81, 0xdb, 0x68, 0x34,
+ 0x3b, 0xc5, 0x9e, 0x66, 0x94, 0x81, 0x98, 0xa0, 0xf9, 0xff }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[10]*/
+ { 0x2c, 0x2c, 0xd3, 0x75, 0x81, 0x2a, 0x59, 0x07, 0xeb, 0x08,
+ 0xce, 0x28, 0x4c, 0x0c, 0x6a, 0xa8, 0x8f, 0xa3, 0x98, 0x7e }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[11]*/
+ { 0x64, 0xce, 0x73, 0x03, 0xc7, 0x89, 0x99, 0x1f, 0xf1, 0xce,
+ 0xfe, 0xfb, 0xb9, 0x42, 0x30, 0xdf, 0xbb, 0x68, 0x6f, 0xd3 }
+ },
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[12]*/
+ { 0x51, 0xae, 0xf5, 0xac, 0x22, 0xa0, 0xba, 0x11, 0xc5, 0xaa,
+ 0xb4, 0x70, 0x99, 0xce, 0x18, 0x08, 0x12, 0x9b, 0xb1, 0xc5 }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[13]*/
+ { 0x57, 0x91, 0xea, 0x48, 0xd8, 0xbf, 0x9e, 0xc1, 0xae, 0x33,
+ 0xb3, 0xfd, 0xf7, 0x7a, 0xeb, 0x30, 0xb1, 0x62, 0x0d, 0x82 }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[14]*/
+ { 0x2d, 0x71, 0x54, 0xb9, 0xc5, 0x28, 0x76, 0xff, 0x76, 0xb5,
+ 0x99, 0x37, 0x99, 0x9d, 0xf7, 0x10, 0x6d, 0x86, 0x4f, 0x3f }
+ },
+ { GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_XTS,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[15]*/
+ { 0x71, 0x46, 0x40, 0xb0, 0xed, 0x6f, 0xc4, 0x82, 0x2b, 0x3f,
+ 0xb6, 0xf7, 0x81, 0x08, 0x4c, 0x8b, 0xc1, 0x66, 0x4c, 0x1b }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_XTS,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP_abcdefghijklmnopABCDEFGHIJKLMNO", 64,
+ "1234567890123456", 16,
+/*[16]*/
+ { 0x8e, 0xbc, 0xa5, 0x21, 0x0a, 0x4b, 0x53, 0x14, 0x79, 0x81,
+ 0x25, 0xad, 0x24, 0x45, 0x98, 0xbd, 0x9f, 0x27, 0x5f, 0x01 }
+ },
+ { GCRY_CIPHER_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);
+ 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 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 (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 = 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 = 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 = 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 = 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+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,
+ 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,
+ 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,
+ 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,
+ 50))
+ 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
+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
+ };
+ int i;
+
+ if (verbose)
+ fprintf (stderr, "Starting Cipher checks.\n");
+ for (i = 0; algos[i]; i++)
+ {
+ if (gcry_cipher_test_algo (algos[i]) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos[i]);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr, " checking %s [%i]\n",
+ gcry_cipher_algo_name (algos[i]),
+ gcry_cipher_map_name (gcry_cipher_algo_name (algos[i])));
+
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB8, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_OFB, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_EAX, 0);
+ if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN)
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0);
+ if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN)
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0);
+ if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN)
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0);
+ if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_XTS_BLOCK_LEN)
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_XTS, 0);
+ }
+
+ for (i = 0; algos2[i]; i++)
+ {
+ if (gcry_cipher_test_algo (algos2[i]) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos2[i]);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr, " checking %s\n",
+ gcry_cipher_algo_name (algos2[i]));
+
+ check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0);
+ if (algos2[i] == GCRY_CIPHER_CHACHA20)
+ check_one_cipher (algos2[i], GCRY_CIPHER_MODE_POLY1305, 0);
+ }
+ /* we have now run all cipher's selftests */
+
+ if (verbose)
+ fprintf (stderr, "Completed Cipher checks.\n");
+
+ /* TODO: add some extra encryption to test the higher level functions */
+}
+
+
+static void
+check_cipher_modes(void)
+{
+ if (verbose)
+ fprintf (stderr, "Starting Cipher Mode checks.\n");
+
+ check_ecb_cipher ();
+ check_aes128_cbc_cts_cipher ();
+ check_cbc_mac_cipher ();
+ check_ctr_cipher ();
+ check_cfb_cipher ();
+ check_ofb_cipher ();
+ check_ccm_cipher ();
+ check_gcm_cipher ();
+ check_poly1305_cipher ();
+ check_ocb_cipher ();
+ check_xts_cipher ();
+ check_eax_cipher ();
+ check_gost28147_cipher ();
+ check_stream_cipher ();
+ check_stream_cipher_large_block ();
+
+ if (verbose)
+ fprintf (stderr, "Completed Cipher Mode checks.\n");
+}
+
+
+static void
+fillbuf_count (char *buf, size_t buflen, unsigned char pos)
+{
+ while (buflen--)
+ *((unsigned char *)(buf++)) = pos++;
+}
+
+
+static void
+check_one_md (int algo, const char *data, int len, const char *expect, int elen,
+ const char *key, int klen)
+{
+ gcry_md_hd_t hd, hd2;
+ unsigned char *p;
+ int mdlen;
+ int i, 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_RMD160;
+ gcry_md_hd_t crc1, crc2;
+ size_t startlen;
+ size_t piecelen;
+ size_t left;
+ const unsigned char *p1, *p2;
+ int crclen;
+
+ crclen = gcry_md_get_algo_dlen (crcalgo);
+
+ err = gcry_md_open (&crc1, crcalgo, 0);
+ if (err)
+ {
+ fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo,
+ crcalgo, gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_md_open (&crc2, crcalgo, 0);
+ if (err)
+ {
+ fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo,
+ crcalgo, gpg_strerror (err));
+ return;
+ }
+
+ /* Extract large chucks, total 1000000 additional bytes. */
+ for (i = 0; i < 1000; i++)
+ {
+ 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" },
+
+ { 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" },
+
+ { 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" },
+ { 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" },
+ { 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))
+ {
+ show_md_not_available (algos[i].md);
+ continue;
+ }
+ if (gcry_md_test_algo (algos[i].md) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos[i].md);
+ continue;
+ }
+
+ if (!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;
+ }
+
+ gcry_md_setkey( hd, key, keylen );
+
+ 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))
+ {
+ show_old_hmac_not_available (algos[i].md);
+ continue;
+ }
+ if (gcry_md_test_algo (algos[i].md) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos[i].md);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr,
+ " checking %s [%i] for %d byte key and %d byte data\n",
+ gcry_md_algo_name (algos[i].md),
+ algos[i].md,
+ (int)strlen(algos[i].key), (int)strlen(algos[i].data));
+
+ check_one_hmac (algos[i].md, algos[i].data, strlen (algos[i].data),
+ algos[i].key, strlen(algos[i].key),
+ algos[i].expect);
+ }
+
+ if (verbose)
+ fprintf (stderr, "Completed hashed MAC checks.\n");
+}
+
+
+static void
+check_one_mac (int algo, const char *data, int datalen,
+ const char *key, int keylen, const char *iv, int ivlen,
+ const char *expect, int test_buffering)
+{
+ gcry_mac_hd_t hd;
+ unsigned char *p;
+ unsigned int maclen;
+ size_t macoutlen;
+ int i;
+ gcry_error_t err = 0;
+
+ if (test_buffering)
+ {
+ if ((*data == '!' && !data[1]) ||
+ (*data == '?' && !data[1]))
+ {
+ return; /* Skip. */
+ }
+ }
+
+ err = gcry_mac_open (&hd, algo, 0, NULL);
+ if (err)
+ {
+ fail ("algo %d, gcry_mac_open failed: %s\n", algo, gpg_strerror (err));
+ return;
+ }
+
+ i = gcry_mac_get_algo (hd);
+ if (i != algo)
+ {
+ fail ("algo %d, gcry_mac_get_algo failed: %d\n", algo, i);
+ }
+
+ maclen = gcry_mac_get_algo_maclen (algo);
+ if (maclen < 1 || maclen > 500)
+ {
+ fail ("algo %d, gcry_mac_get_algo_maclen failed: %d\n", algo, maclen);
+ return;
+ }
+
+ p = malloc(maclen);
+ if (!p)
+ {
+ fail ("algo %d, could not malloc %d bytes\n", algo, maclen);
+ return;
+ }
+
+ clutter_vector_registers();
+ err = gcry_mac_setkey (hd, key, keylen);
+ if (err)
+ fail("algo %d, mac gcry_mac_setkey failed: %s\n", algo, gpg_strerror (err));
+ if (err)
+ goto out;
+
+ if (ivlen && iv)
+ {
+ 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" },
+ { GCRY_MAC_CMAC_3DES,
+ "",
+ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
+ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5",
+ "\xb7\xa6\x88\xe1\x22\xff\xaf\x95" },
+ { GCRY_MAC_CMAC_3DES,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96",
+ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
+ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5",
+ "\x8e\x8f\x29\x31\x36\x28\x37\x97" },
+ { GCRY_MAC_CMAC_3DES,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57",
+ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
+ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5",
+ "\x74\x3d\xdb\xe0\xce\x2d\xc2\xed" },
+ { GCRY_MAC_CMAC_3DES,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
+ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5",
+ "\x33\xe6\xb1\x09\x24\x00\xea\xe5" },
+ { GCRY_MAC_CMAC_3DES,
+ "",
+ "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38"
+ "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5",
+ "\xbd\x2e\xbf\x9a\x3b\xa0\x03\x61" },
+ { GCRY_MAC_CMAC_3DES,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96",
+ "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38"
+ "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5",
+ "\x4f\xf2\xab\x81\x3c\x53\xce\x83" },
+ { GCRY_MAC_CMAC_3DES,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57",
+ "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38"
+ "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5",
+ "\x62\xdd\x1b\x47\x19\x02\xbd\x4e" },
+ { GCRY_MAC_CMAC_3DES,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38"
+ "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5",
+ "\x31\xb1\xe4\x31\xda\xbc\x4e\xb8" },
+ { GCRY_MAC_CMAC_3DES, "?", "????????????????????????",
+ "\xc1\x38\x13\xb2\x31\x8f\x3a\xdf" },
+ /* CMAC Camellia test vectors from
+ http://tools.ietf.org/html/draft-kato-ipsec-camellia-cmac96and128-05 */
+ { GCRY_MAC_CMAC_CAMELLIA,
+ "",
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xba\x92\x57\x82\xaa\xa1\xf5\xd9\xa0\x0f\x89\x64\x80\x94\xfc\x71" },
+ { GCRY_MAC_CMAC_CAMELLIA,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\x6d\x96\x28\x54\xa3\xb9\xfd\xa5\x6d\x7d\x45\xa9\x5e\xe1\x79\x93" },
+ { GCRY_MAC_CMAC_CAMELLIA,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\x5c\x18\xd1\x19\xcc\xd6\x76\x61\x44\xac\x18\x66\x13\x1d\x9f\x22" },
+ { GCRY_MAC_CMAC_CAMELLIA,
+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xc2\x69\x9a\x6e\xba\x55\xce\x9d\x93\x9a\x8a\x4e\x19\x46\x6e\xe9" },
+ { GCRY_MAC_CMAC_CAMELLIA, "?", "????????????????????????????????",
+ "\xba\x8a\x5a\x8d\xa7\x54\x26\x83\x3e\xb1\x20\xb5\x45\xd0\x9f\x4e" },
+ /* http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip */
+ { GCRY_MAC_GMAC_AES,
+ "",
+ "\x11\x75\x4c\xd7\x2a\xec\x30\x9b\xf5\x2f\x76\x87\x21\x2e\x89\x57",
+ "\x25\x03\x27\xc6\x74\xaa\xf4\x77\xae\xf2\x67\x57\x48\xcf\x69\x71",
+ "\x3c\x81\x9d\x9a\x9b\xed\x08\x76\x15\x03\x0b\x65" },
+ { GCRY_MAC_GMAC_AES,
+ "\x2b\x63\x26\x64\x29\x67\x4a\xb5\xe2\xea\xff\x63\x9c\x23\x14\x66"
+ "\x2f\x92\x57\x4b\x29\x8f\x57\x7a\xcf\x7d\x6f\x99\x1a\x87\x92\x1f"
+ "\xc2\x32\xea\xfc\xc7\xb1\x46\x48\x96\x63\x2d\x6c\x8a\xbe\x88\xc2"
+ "\xcc\xa4\x04\xdb\xf8\x7c\x20\x6a\x19\xd3\x73\xed\x99\x50\x17\x34"
+ "\x69\x13\x4d\x7c\x14\xc2\x84\x7d\xf2\x4a\x88\xc1\xc5\x3b\x4d\xe4"
+ "\x9d\xb3\x66\x39\x2b\x6d\xc6\x51\x27\x6e",
+ "\x0f\x3b\x17\xde\xae\x62\x13\x64\x55\x4a\xe5\x39\xdb\x09\xde\x11",
+ "\xff\xb0\xbb\x6d\xfc\x23\x58\x75\x4f\x17\x78\x48\x5b\x59\x65\x7f",
+ "\xa7\xf6\x07\x4c\xda\x56\x1c\xd2\xaa\x15\xba\x8c\x2f\xa6\x39\x42"
+ "\x59\x3e\x7c\xcf\x45\xc2\x9a\x57\xda\xd8\xa6\xe2\xea\x63\x54\xce"
+ "\x8a\xde\x39\xdd\xde\x4a\xc4\x5b\xbd\xc6\x63\xf0\xa5\x37\xc9\x48"
+ "\x18\x23\x5a\x73\xd8\xa0\x8b\xd8\x98\xab\xd0\x99\xe1\x5c\x08\x8c"
+ "\x6e\x21\x17\x5a\xf4\xe9\xa4\x99\x70\x12\x82\xed\x32\x81\x50\xa6"
+ "\xd9\x90\xe8\xec\x87\x85\xce\x26\x1b\xe1\xb8\x3f\xd8\x59\x1e\x57"
+ "\x76\x5f\x3d\xc1\x11\x3f\xd0\x2a\x40\xf5\x01\x6a\xd0\xd0\xed\xc4"
+ "\x92\x9a\x02\xe0\x17\xb2\xc5\xf4\x18\xd2\x96\xab\xd6\xc2\xea\x2e" },
+ { GCRY_MAC_GMAC_AES,
+ "\x61\x14\x60\x11\x90\xf6\xef\x5e\x59\x23\x5d\xc0\x42\x8c\x09\xe3"
+ "\x27\x0b\x19\xea",
+ "\x15\xa4\x14\x46\x6a\x7f\x90\xea\x32\xbf\xd7\xf6\xe5\x8b\xfa\x06"
+ "\xe9\x07\xfc\x41\x66\x89\xd9\x60\x39\x45\xd7\x94\x54\xd4\x23\x17",
+ "\x19\x6e\x0e\x01\x0f\x08\x56\xf9\x82\xb4\x08\x92\x41\xd6\x24\x84",
+ "\xab" },
+ { GCRY_MAC_GMAC_AES,
+ "\x8b\x5c\x12\x4b\xef\x6e\x2f\x0f\xe4\xd8\xc9\x5c\xd5\xfa\x4c\xf1",
+ "\x41\xc5\xda\x86\x67\xef\x72\x52\x20\xff\xe3\x9a\xe0\xac\x59\x0a"
+ "\xc9\xfc\xa7\x29\xab\x60\xad\xa0",
+ "\x20\x4b\xdb\x1b\xd6\x21\x54\xbf\x08\x92\x2a\xaa\x54\xee\xd7\x05",
+ "\x05\xad\x13\xa5\xe2\xc2\xab\x66\x7e\x1a\x6f\xbc" },
+ { GCRY_MAC_GMAC_AES, "?", "????????????????????????????????",
+ "\x84\x37\xc3\x42\xae\xf5\xd0\x40\xd3\x73\x90\xa9\x36\xed\x8a\x12" },
+ /* from NaCl */
+ { GCRY_MAC_POLY1305,
+ "\x8e\x99\x3b\x9f\x48\x68\x12\x73\xc2\x96\x50\xba\x32\xfc\x76\xce"
+ "\x48\x33\x2e\xa7\x16\x4d\x96\xa4\x47\x6f\xb8\xc5\x31\xa1\x18\x6a"
+ "\xc0\xdf\xc1\x7c\x98\xdc\xe8\x7b\x4d\xa7\xf0\x11\xec\x48\xc9\x72"
+ "\x71\xd2\xc2\x0f\x9b\x92\x8f\xe2\x27\x0d\x6f\xb8\x63\xd5\x17\x38"
+ "\xb4\x8e\xee\xe3\x14\xa7\xcc\x8a\xb9\x32\x16\x45\x48\xe5\x26\xae"
+ "\x90\x22\x43\x68\x51\x7a\xcf\xea\xbd\x6b\xb3\x73\x2b\xc0\xe9\xda"
+ "\x99\x83\x2b\x61\xca\x01\xb6\xde\x56\x24\x4a\x9e\x88\xd5\xf9\xb3"
+ "\x79\x73\xf6\x22\xa4\x3d\x14\xa6\x59\x9b\x1f\x65\x4c\xb4\x5a\x74"
+ "\xe3\x55\xa5",
+ "\xee\xa6\xa7\x25\x1c\x1e\x72\x91\x6d\x11\xc2\xcb\x21\x4d\x3c\x25"
+ "\x25\x39\x12\x1d\x8e\x23\x4e\x65\x2d\x65\x1f\xa4\xc8\xcf\xf8\x80",
+ "\xf3\xff\xc7\x70\x3f\x94\x00\xe5\x2a\x7d\xfb\x4b\x3d\x33\x05\xd9" },
+ /* from draft-nir-cfrg-chacha20-poly1305-03 */
+ { GCRY_MAC_POLY1305,
+ "Cryptographic Forum Research Group",
+ "\x85\xd6\xbe\x78\x57\x55\x6d\x33\x7f\x44\x52\xfe\x42\xd5\x06\xa8"
+ "\x01\x03\x80\x8a\xfb\x0d\xb2\xfd\x4a\xbf\xf6\xaf\x41\x49\xf5\x1b",
+ "\xa8\x06\x1d\xc1\x30\x51\x36\xc6\xc2\x2b\x8b\xaf\x0c\x01\x27\xa9" },
+ { GCRY_MAC_POLY1305,
+ "'Twas brillig, and the slithy toves\n"
+ "Did gyre and gimble in the wabe:\n"
+ "All mimsy were the borogoves,\n"
+ "And the mome raths outgrabe.",
+ "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0"
+ "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0",
+ "\x45\x41\x66\x9a\x7e\xaa\xee\x61\xe7\x08\xdc\x7c\xbc\xc5\xeb\x62" },
+ { GCRY_MAC_POLY1305,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ NULL,
+ 191, 32 },
+ { GCRY_MAC_POLY1305,
+ "Any submission to the IETF intended by the Contributor for "
+ "publication as all or part of an IETF Internet-Draft or RFC and "
+ "any statement made within the context of an IETF activity is "
+ "considered an \"IETF Contribution\". Such statements include "
+ "oral statements in IETF sessions, as well as written and "
+ "electronic communications made at any time or place, which are "
+ "addressed to",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e",
+ "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e",
+ NULL,
+ 0, 32 },
+ { GCRY_MAC_POLY1305,
+ "Any submission to the IETF intended by the Contributor for "
+ "publication as all or part of an IETF Internet-Draft or RFC and "
+ "any statement made within the context of an IETF activity is "
+ "considered an \"IETF Contribution\". Such statements include "
+ "oral statements in IETF sessions, as well as written and "
+ "electronic communications made at any time or place, which are "
+ "addressed to",
+ "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xf3\x47\x7e\x7c\xd9\x54\x17\xaf\x89\xa6\xb8\x79\x4c\x31\x0c\xf0",
+ NULL,
+ 0, 32 },
+ /* draft-irtf-cfrg-chacha20-poly1305-01 */
+ /* TV#5 */
+ { GCRY_MAC_POLY1305,
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ NULL,
+ 16, 32 },
+ /* TV#6 */
+ { GCRY_MAC_POLY1305,
+ "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ NULL,
+ 16, 32 },
+ /* TV#7 */
+ { GCRY_MAC_POLY1305,
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ NULL,
+ 48, 32 },
+ /* TV#8 */
+ { GCRY_MAC_POLY1305,
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFB\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE"
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01",
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ NULL,
+ 48, 32 },
+ /* TV#9 */
+ { GCRY_MAC_POLY1305,
+ "\xFD\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xFA\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ NULL,
+ 16, 32 },
+ /* TV#10 */
+ { GCRY_MAC_POLY1305,
+ "\xE3\x35\x94\xD7\x50\x5E\x43\xB9\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x33\x94\xD7\x50\x5E\x43\x79\xCD\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x14\x00\x00\x00\x00\x00\x00\x00\x55\x00\x00\x00\x00\x00\x00\x00",
+ NULL,
+ 64, 32 },
+ /* TV#11 */
+ { GCRY_MAC_POLY1305,
+ "\xE3\x35\x94\xD7\x50\x5E\x43\xB9\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x33\x94\xD7\x50\x5E\x43\x79\xCD\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ NULL,
+ 48, 32 },
+ /* from http://cr.yp.to/mac/poly1305-20050329.pdf */
+ { GCRY_MAC_POLY1305,
+ "\xf3\xf6",
+ "\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00"
+ "\x58\x0b\x3b\x0f\x94\x47\xbb\x1e\x69\xd0\x95\xb5\x92\x8b\x6d\xbc",
+ "\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde",
+ NULL,
+ 0, 32 },
+ { GCRY_MAC_POLY1305,
+ "",
+ "\xa0\xf3\x08\x00\x00\xf4\x64\x00\xd0\xc7\xe9\x07\x6c\x83\x44\x03"
+ "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7",
+ "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7",
+ NULL,
+ 0, 32 },
+ { GCRY_MAC_POLY1305,
+ "\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24"
+ "\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36",
+ "\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08"
+ "\x83\x14\x9c\x69\xb5\x61\xdd\x88\x29\x8a\x17\x98\xb1\x07\x16\xef",
+ "\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe",
+ NULL,
+ 0, 32 },
+ { GCRY_MAC_POLY1305,
+ "\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1"
+ "\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0"
+ "\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67"
+ "\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9",
+ "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07"
+ "\x80\xf8\xc2\x0a\xa7\x12\x02\xd1\xe2\x91\x79\xcb\xcb\x55\x5a\x57",
+ "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b" },
+ { GCRY_MAC_POLY1305, "?", "????????????????????????????????",
+ "\xc3\x88\xce\x8a\x52\xd6\xe7\x21\x86\xfa\xaa\x5d\x2d\x16\xf9\xa3" },
+ /* from http://cr.yp.to/mac/poly1305-20050329.pdf */
+ { GCRY_MAC_POLY1305_AES,
+ "\xf3\xf6",
+ "\xec\x07\x4c\x83\x55\x80\x74\x17\x01\x42\x5b\x62\x32\x35\xad\xd6"
+ "\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00",
+ "\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde",
+ "\xfb\x44\x73\x50\xc4\xe8\x68\xc5\x2a\xc3\x27\x5c\xf9\xd4\x32\x7e",
+ 0, 32 },
+ { GCRY_MAC_POLY1305_AES,
+ "",
+ "\x75\xde\xaa\x25\xc0\x9f\x20\x8e\x1d\xc4\xce\x6b\x5c\xad\x3f\xbf"
+ "\xa0\xf3\x08\x00\x00\xf4\x64\x00\xd0\xc7\xe9\x07\x6c\x83\x44\x03",
+ "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7",
+ "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc",
+ 0, 32 },
+ { GCRY_MAC_POLY1305_AES,
+ "\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24"
+ "\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36",
+ "\x6a\xcb\x5f\x61\xa7\x17\x6d\xd3\x20\xc5\xc1\xeb\x2e\xdc\xdc\x74"
+ "\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08",
+ "\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe",
+ "\xae\x21\x2a\x55\x39\x97\x29\x59\x5d\xea\x45\x8b\xc6\x21\xff\x0e",
+ 0, 32 },
+ { GCRY_MAC_POLY1305_AES,
+ "\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1"
+ "\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0"
+ "\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67"
+ "\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9",
+ "\xe1\xa5\x66\x8a\x4d\x5b\x66\xa5\xf6\x8c\xc5\x42\x4e\xd5\x98\x2d"
+ "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07",
+ "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b",
+ "\x9a\xe8\x31\xe7\x43\x97\x8d\x3a\x23\x52\x7c\x71\x28\x14\x9e\x3a",
+ 0, 32 },
+ { GCRY_MAC_POLY1305_AES, "?", "????????????????????????????????",
+ "\x9d\xeb\xb0\xcd\x24\x90\xd3\x9b\x47\x78\x37\x0a\x81\xf2\x83\x2a",
+ "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc",
+ 0, 32 },
+ { 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 },
+ { 0 },
+ };
+ int i;
+
+ if (verbose)
+ fprintf (stderr, "Starting MAC checks.\n");
+
+ for (i = 0; algos[i].algo; i++)
+ {
+ size_t klen, dlen;
+
+ if (gcry_mac_test_algo (algos[i].algo))
+ {
+ show_mac_not_available (algos[i].algo);
+ continue;
+ }
+ if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos[i].algo);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr,
+ " checking %s [%i] for %d byte key and %d byte data\n",
+ gcry_mac_algo_name (algos[i].algo),
+ algos[i].algo, (int)strlen(algos[i].key),
+ (!strcmp(algos[i].data, "!") || !strcmp(algos[i].data, "?"))
+ ? 1000000 : (int)strlen(algos[i].data));
+
+ klen = algos[i].klen ? algos[i].klen : strlen(algos[i].key);
+ dlen = algos[i].dlen ? algos[i].dlen : strlen (algos[i].data);
+
+ check_one_mac (algos[i].algo, algos[i].data, dlen, algos[i].key, klen,
+ algos[i].iv, algos[i].iv ? strlen(algos[i].iv) : 0,
+ algos[i].expect, 0);
+ check_one_mac (algos[i].algo, algos[i].data, dlen, algos[i].key, klen,
+ algos[i].iv, algos[i].iv ? strlen(algos[i].iv) : 0,
+ algos[i].expect, 1);
+ }
+
+ if (verbose)
+ fprintf (stderr, "Completed MAC checks.\n");
+}
+
+/* Check that the signature SIG matches the hash HASH. PKEY is the
+ public key used for the verification. BADHASH is a hash value which
+ should result in a bad signature status. */
+static void
+verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash,
+ gcry_sexp_t badhash, gcry_sexp_t sig)
+{
+ gcry_error_t rc;
+
+ rc = gcry_pk_verify (sig, hash, pkey);
+ if (rc)
+ fail ("gcry_pk_verify failed: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_verify (sig, badhash, pkey);
+ if (gcry_err_code (rc) != GPG_ERR_BAD_SIGNATURE)
+ fail ("gcry_pk_verify failed to detect a bad signature: %s\n",
+ gpg_strerror (rc));
+}
+
+
+/* Test the public key sign function using the private key SKEY. PKEY
+ is used for verification. */
+static void
+check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
+{
+ gcry_error_t rc;
+ gcry_sexp_t sig, badhash, hash;
+ int dataidx;
+ static const char baddata[] =
+ "(data\n (flags pkcs1)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n";
+ static const struct
+ {
+ const char *data;
+ int algo;
+ int expected_rc;
+ } datas[] =
+ {
+ { "(data\n (flags pkcs1)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { "(data\n (flags pkcs1-raw)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ GPG_ERR_CONFLICT },
+ { "(data\n (flags oaep)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ 0,
+ GPG_ERR_CONFLICT },
+ /* This test is to see whether hash algorithms not hard wired in
+ pubkey.c are detected: */
+ { "(data\n (flags pkcs1)\n"
+ " (hash oid.1.3.14.3.2.29 "
+ " #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { "(data\n (flags )\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ 0,
+ GPG_ERR_CONFLICT },
+ { "(data\n (flags pkcs1)\n"
+ " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ GPG_ERR_DIGEST_ALGO },
+ { "(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
+ 0,
+ 0 },
+ { "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n",
+ 0,
+ 0 },
+ { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n",
+ 0,
+ 0 },
+ { "(data\n (flags pkcs1)\n"
+ " (value #11223344556677889900AA#))\n",
+ GCRY_PK_RSA,
+ GPG_ERR_CONFLICT },
+ { "(data\n (flags pkcs1-raw)\n"
+ " (value #11223344556677889900AA#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { "(data\n (flags raw foo)\n"
+ " (value #11223344556677889900AA#))\n",
+ 0,
+ GPG_ERR_INV_FLAG },
+ { "(data\n (flags pss)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { "(data\n (flags pss)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#)\n"
+ " (random-override #4253647587980912233445566778899019283747#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { NULL }
+ };
+
+ rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata));
+ if (rc)
+ die ("converting data failed: %s\n", gpg_strerror (rc));
+
+ for (dataidx = 0; datas[dataidx].data; dataidx++)
+ {
+ if (datas[dataidx].algo && datas[dataidx].algo != algo)
+ continue;
+
+ if (verbose)
+ fprintf (stderr, " test %d, signature test %d (%s)\n",
+ n, dataidx, gcry_pk_algo_name (algo));
+
+ rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data,
+ strlen (datas[dataidx].data));
+ if (rc)
+ die ("converting data failed: %s\n", gpg_strerror (rc));
+
+ rc = gcry_pk_sign (&sig, hash, skey);
+ if (gcry_err_code (rc) != datas[dataidx].expected_rc)
+ fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc));
+
+ if (!rc)
+ verify_one_signature (pkey, hash, badhash, sig);
+
+ gcry_sexp_release (sig);
+ sig = NULL;
+ gcry_sexp_release (hash);
+ hash = NULL;
+ }
+
+ gcry_sexp_release (badhash);
+}
+
+
+/* Test the public key sign function using the private 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)
+{
+ 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);
+
+ for (dataidx = 0; datas[dataidx].data; dataidx++)
+ {
+ if (datas[dataidx].nbits != nbits)
+ continue;
+
+ if (verbose)
+ fprintf (stderr, " test %d, signature test %d (%u bit ecdsa)\n",
+ n, dataidx, nbits);
+
+ rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data,
+ strlen (datas[dataidx].data));
+ if (rc)
+ die ("converting data failed: %s\n", gpg_strerror (rc));
+ rc = gcry_sexp_sscan (&badhash, NULL, datas[dataidx].baddata,
+ strlen (datas[dataidx].baddata));
+ if (rc)
+ die ("converting data failed: %s\n", gpg_strerror (rc));
+
+ rc = gcry_pk_sign (&sig, hash, skey);
+ if (gcry_err_code (rc) != datas[dataidx].expected_rc)
+ fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc));
+
+ if (!rc && verbose > 1)
+ show_sexp ("ECDSA signature:\n", sig);
+
+ if (!rc)
+ verify_one_signature (pkey, hash, badhash, sig);
+
+ gcry_sexp_release (sig);
+ sig = NULL;
+ gcry_sexp_release (badhash);
+ badhash = NULL;
+ gcry_sexp_release (hash);
+ hash = NULL;
+ }
+}
+
+
+static void
+check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
+{
+ gcry_error_t rc;
+ gcry_sexp_t plain = NULL;
+ gcry_sexp_t ciph = NULL;
+ gcry_sexp_t data = NULL;
+ int dataidx;
+ static const struct
+ {
+ int algo; /* If not 0 run test only if ALGO matches. */
+ const char *data;
+ const char *hint;
+ int unpadded;
+ int encrypt_expected_rc;
+ int decrypt_expected_rc;
+ int special;
+ } datas[] =
+ {
+ { GCRY_PK_RSA,
+ "(data\n (flags pkcs1)\n"
+ " (value #11223344556677889900AA#))\n",
+ NULL,
+ 0,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags pkcs1)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags pkcs1)",
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags oaep)",
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n (hash-algo sha1)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags oaep)(hash-algo sha1)",
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags oaep)(hash-algo sha1)(label \"test\")",
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n"
+ " (value #11223344556677889900AA#)\n"
+ " (random-override #4253647587980912233445566778899019283747#))\n",
+ "(flags oaep)(hash-algo sha1)(label \"test\")",
+ 1,
+ 0,
+ 0 },
+ { 0,
+ "(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
+ NULL,
+ 1,
+ 0,
+ 0 },
+ { 0,
+ "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n",
+ NULL,
+ 1,
+ 0,
+ 0 },
+ { 0,
+ "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n",
+ NULL,
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags pkcs1)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ NULL,
+ 0,
+ GPG_ERR_CONFLICT,
+ 0},
+ { 0,
+ "(data\n (flags raw foo)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ NULL,
+ 0,
+ GPG_ERR_INV_FLAG,
+ 0},
+ { 0,
+ "(data\n (flags raw)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags oaep)",
+ 1,
+ 0,
+ GPG_ERR_ENCODING_PROBLEM, 1 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags pkcs1)",
+ 1,
+ 0,
+ GPG_ERR_ENCODING_PROBLEM, 1 },
+ { 0,
+ "(data\n (flags pss)\n"
+ " (value #11223344556677889900AA#))\n",
+ NULL,
+ 0,
+ GPG_ERR_CONFLICT },
+ { 0, NULL }
+ };
+
+ (void)n;
+
+ for (dataidx = 0; datas[dataidx].data; dataidx++)
+ {
+ if (datas[dataidx].algo && datas[dataidx].algo != algo)
+ continue;
+
+ if (verbose)
+ fprintf (stderr, " encryption/decryption test %d (algo %d)\n",
+ dataidx, algo);
+
+ rc = gcry_sexp_sscan (&data, NULL, datas[dataidx].data,
+ strlen (datas[dataidx].data));
+ if (rc)
+ die ("converting data failed: %s\n", gpg_strerror (rc));
+
+ rc = gcry_pk_encrypt (&ciph, data, pkey);
+ if (gcry_err_code (rc) != datas[dataidx].encrypt_expected_rc)
+ fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (rc));
+
+ if (!rc)
+ {
+ int expect_mismatch = 0;
+
+ /* Insert decoding hint to CIPH. */
+ if (datas[dataidx].hint)
+ {
+ size_t hint_len, len;
+ char *hint, *buf;
+ gcry_sexp_t list;
+
+ /* Convert decoding hint into canonical sexp. */
+ gcry_sexp_new (&list, datas[dataidx].hint,
+ strlen (datas[dataidx].hint), 1);
+ hint_len = gcry_sexp_sprint (list, GCRYSEXP_FMT_CANON, NULL, 0);
+ hint = gcry_malloc (hint_len);
+ if (!hint)
+ die ("can't allocate memory\n");
+ hint_len = gcry_sexp_sprint (list, GCRYSEXP_FMT_CANON, hint,
+ hint_len);
+ gcry_sexp_release (list);
+
+ /* Convert CIPH into canonical sexp. */
+ len = gcry_sexp_sprint (ciph, GCRYSEXP_FMT_CANON, NULL, 0);
+ buf = gcry_malloc (len + hint_len);
+ if (!buf)
+ die ("can't allocate memory\n");
+ len = gcry_sexp_sprint (ciph, GCRYSEXP_FMT_CANON, buf, len);
+ /* assert (!strcmp (buf, "(7:enc-val", 10)); */
+
+ /* Copy decoding hint into CIPH. */
+ memmove (buf + 10 + hint_len, buf + 10, len - 10);
+ memcpy (buf + 10, hint, hint_len);
+ gcry_free (hint);
+ gcry_sexp_new (&list, buf, len + hint_len, 1);
+ gcry_free (buf);
+ gcry_sexp_release (ciph);
+ ciph = list;
+ }
+ rc = gcry_pk_decrypt (&plain, ciph, skey);
+ if (!rc && datas[dataidx].special == 1)
+ {
+ /* It may happen that OAEP formatted data which is
+ decrypted as pkcs#1 data returns a valid pkcs#1
+ frame. However, the returned value will not be
+ identical - thus we expect a mismatch and test further on
+ whether this mismatch actually happened. */
+ expect_mismatch = 1;
+ }
+ else if (gcry_err_code (rc) != datas[dataidx].decrypt_expected_rc)
+ {
+ if (verbose)
+ {
+ show_sexp (" data:\n", data);
+ show_sexp (" ciph:\n", ciph);
+ show_sexp (" key:\n", skey);
+ }
+ fail ("gcry_pk_decrypt failed: expected %d (%s), got %d (%s)\n",
+ datas[dataidx].decrypt_expected_rc,
+ gpg_strerror (datas[dataidx].decrypt_expected_rc),
+ rc, gpg_strerror (rc));
+ }
+
+ if (!rc && datas[dataidx].unpadded)
+ {
+ gcry_sexp_t p1, p2;
+
+ p1 = gcry_sexp_find_token (data, "value", 0);
+ p2 = gcry_sexp_find_token (plain, "value", 0);
+ if (p1 && p2)
+ {
+ const char *s1, *s2;
+ size_t n1, n2;
+
+ s1 = gcry_sexp_nth_data (p1, 1, &n1);
+ s2 = gcry_sexp_nth_data (p2, 1, &n2);
+ if (n1 != n2 || memcmp (s1, s2, n1))
+ {
+ if (expect_mismatch)
+ expect_mismatch = 0;
+ else
+ fail ("gcry_pk_encrypt/gcry_pk_decrypt "
+ "do not roundtrip\n");
+ }
+ }
+
+ if (expect_mismatch)
+ fail ("gcry_pk_encrypt/gcry_pk_decrypt "
+ "expected mismatch did not happen\n");
+
+ gcry_sexp_release (p1);
+ gcry_sexp_release (p2);
+ }
+ }
+
+ gcry_sexp_release (plain);
+ plain = NULL;
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ gcry_sexp_release (data);
+ data = NULL;
+ }
+}
+
+static void
+check_pubkey_grip (int n, const unsigned char *grip,
+ gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
+{
+ unsigned char sgrip[20], pgrip[20];
+
+ (void)algo;
+
+ if (!gcry_pk_get_keygrip (skey, sgrip))
+ die ("get keygrip for private RSA key failed\n");
+ if (!gcry_pk_get_keygrip (pkey, pgrip))
+ die ("[%i] get keygrip for public RSA key failed\n", n);
+ if (memcmp (sgrip, pgrip, 20))
+ fail ("[%i] keygrips don't match\n", n);
+ if (memcmp (sgrip, grip, 20))
+ fail ("wrong keygrip for RSA key\n");
+}
+
+static void
+do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey,
+ const unsigned char *grip, int algo, int flags)
+{
+ if (flags & FLAG_SIGN)
+ {
+ if (algo == GCRY_PK_ECDSA)
+ check_pubkey_sign_ecdsa (n, skey, pkey);
+ else
+ check_pubkey_sign (n, skey, pkey, algo);
+ }
+ if (flags & FLAG_CRYPT)
+ check_pubkey_crypt (n, skey, pkey, algo);
+ if (grip && (flags & FLAG_GRIP))
+ check_pubkey_grip (n, grip, skey, pkey, algo);
+}
+
+static void
+check_one_pubkey (int n, test_spec_pubkey_t spec)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_sexp_t skey, pkey;
+
+ err = gcry_sexp_sscan (&skey, NULL, spec.key.secret,
+ strlen (spec.key.secret));
+ if (!err)
+ err = gcry_sexp_sscan (&pkey, NULL, spec.key.public,
+ strlen (spec.key.public));
+ if (err)
+ die ("converting sample key failed: %s\n", gpg_strerror (err));
+
+ do_check_one_pubkey (n, skey, pkey,
+ (const unsigned char*)spec.key.grip,
+ spec.id, spec.flags);
+
+ gcry_sexp_release (skey);
+ gcry_sexp_release (pkey);
+}
+
+static void
+get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+ if (verbose)
+ fprintf (stderr, " generating RSA key:");
+ rc = gcry_sexp_new (&key_spec,
+ in_fips_mode ? "(genkey (rsa (nbits 4:2048)))"
+ : "(genkey (rsa (nbits 4:1024)(transient-key)))",
+ 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (! pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (! sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+static void
+check_one_pubkey_new (int n)
+{
+ gcry_sexp_t skey, pkey;
+
+ get_keys_new (&pkey, &skey);
+ do_check_one_pubkey (n, skey, pkey, NULL,
+ GCRY_PK_RSA, FLAG_SIGN | FLAG_CRYPT);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+}
+
+/* Run all tests for the public key functions. */
+static void
+check_pubkey (void)
+{
+ static const test_spec_pubkey_t pubkeys[] = {
+ {
+ GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN | FLAG_GRIP,
+ {
+ "(private-key\n"
+ " (rsa\n"
+ " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea2"
+ " 51#)\n"
+ " (e #010001#)\n"
+ " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ " 7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ " C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ " C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781"
+ " #)\n"
+ " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ " fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424"
+ " f1#)\n"
+ " (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+ " 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad3"
+ " 61#)\n"
+ " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ " ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b"
+ " #)))\n",
+
+ "(public-key\n"
+ " (rsa\n"
+ " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea2"
+ " 51#)\n"
+ " (e #010001#)))\n",
+
+ "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9"
+ "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"}
+ },
+ {
+ GCRY_PK_DSA, FLAG_SIGN | FLAG_GRIP,
+ {
+ "(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,
+ {
+ "(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,
+ {
+ "(private-key\n"
+ " (ecc\n"
+ " (curve GOST2001-test)\n"
+ " (q #047F2B49E270DB6D90D8595BEC458B50C58585BA1D4E9B78"
+ " 8F6689DBD8E56FD80B26F1B489D6701DD185C8413A977B3C"
+ " BBAF64D1C593D26627DFFB101A87FF77DA#)\n"
+ " (d #7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE"
+ " 1D19CE9891EC3B28#)))\n",
+
+ "(public-key\n"
+ " (ecc\n"
+ " (curve GOST2001-test)\n"
+ " (q #047F2B49E270DB6D90D8595BEC458B50C58585BA1D4E9B78"
+ " 8F6689DBD8E56FD80B26F1B489D6701DD185C8413A977B3C"
+ " BBAF64D1C593D26627DFFB101A87FF77DA#)))\n",
+
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+ },
+ { /* GOST R 34.10-2012 test 512 bit. */
+ GCRY_PK_ECDSA, FLAG_SIGN,
+ {
+ "(private-key\n"
+ " (ecc\n"
+ " (curve GOST2012-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,
+ {
+ "(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" }
+ }
+ };
+ int i;
+
+ if (verbose)
+ fprintf (stderr, "Starting public key checks.\n");
+ for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++)
+ if (pubkeys[i].id)
+ {
+ if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ pubkeys[i].id);
+ continue;
+ }
+ check_one_pubkey (i, pubkeys[i]);
+ }
+ if (verbose)
+ fprintf (stderr, "Completed public key checks.\n");
+
+ if (verbose)
+ fprintf (stderr, "Starting additional public key checks.\n");
+ for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++)
+ if (pubkeys[i].id)
+ {
+ if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ pubkeys[i].id);
+ continue;
+ }
+ check_one_pubkey_new (i);
+ }
+ if (verbose)
+ fprintf (stderr, "Completed additional public key checks.\n");
+
+}
+
+int
+main (int argc, char **argv)
+{
+ gpg_error_t err;
+ int last_argc = -1;
+ int use_fips = 0;
+ int selftest_only = 0;
+ int pubkey_only = 0;
+ int cipher_modes_only = 0;
+ int loop = 0;
+ unsigned int loopcount = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--fips"))
+ {
+ use_fips = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--selftest"))
+ {
+ selftest_only = 1;
+ verbose += 2;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--pubkey"))
+ {
+ pubkey_only = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--cipher-modes"))
+ {
+ cipher_modes_only = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--die"))
+ {
+ die_on_error = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--loop"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ loop = atoi (*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--disable-hwf"))
+ {
+ argc--;
+ argv++;
+ if (argc)
+ {
+ if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
+ fprintf (stderr,
+ PGM
+ ": unknown hardware feature `%s' - option ignored\n",
+ *argv);
+ argc--;
+ argv++;
+ }
+ }
+ }
+
+ xgcry_control ((GCRYCTL_SET_VERBOSITY, (int)verbose));
+
+ if (use_fips)
+ xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+
+ /* Check that we test exactly our version - including the patchlevel. */
+ if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL)))
+ die ("version mismatch; pgm=%s, library=%s\n",
+ GCRYPT_VERSION,gcry_check_version (NULL));
+
+ if ( gcry_fips_mode_active () )
+ in_fips_mode = 1;
+
+ if (!in_fips_mode)
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+
+ if (verbose)
+ gcry_set_progress_handler (progress_handler, NULL);
+
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ /* No valuable keys are create, so we can speed up our RNG. */
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+
+ do
+ {
+ if (pubkey_only)
+ check_pubkey ();
+ else if (cipher_modes_only)
+ {
+ check_ciphers ();
+ check_cipher_modes ();
+ }
+ else if (!selftest_only)
+ {
+ check_ciphers ();
+ check_cipher_modes ();
+ check_bulk_cipher_modes ();
+ check_digests ();
+ check_hmac ();
+ check_mac ();
+ check_pubkey ();
+ }
+ loopcount++;
+ if (loop)
+ {
+ fprintf (stderr, "Test iteration %u completed.\n", loopcount);
+ if (loop != -1)
+ loop--;
+ }
+ }
+ while (loop);
+
+ if (in_fips_mode && !selftest_only)
+ {
+ /* If we are in fips mode do some more tests. */
+ gcry_md_hd_t md;
+
+ /* First trigger a self-test. */
+ xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+ if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0))
+ fail ("not in operational state after self-test\n");
+
+ /* Get us into the error state. */
+ err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+ if (err)
+ fail ("failed to open SHA-1 hash context: %s\n", gpg_strerror (err));
+ else
+ {
+ err = gcry_md_enable (md, GCRY_MD_SHA256);
+ if (err)
+ fail ("failed to add SHA-256 hash context: %s\n",
+ gpg_strerror (err));
+ else
+ {
+ /* gcry_md_get_algo is only defined for a context with
+ just one digest algorithm. With our setup it should
+ put the oibrary intoerror state. */
+ fputs ("Note: Two lines with error messages follow "
+ "- this is expected\n", stderr);
+ gcry_md_get_algo (md);
+ gcry_md_close (md);
+ if (gcry_control (GCRYCTL_OPERATIONAL_P, 0))
+ fail ("expected error state but still in operational state\n");
+ else
+ {
+ /* Now run a self-test and to get back into
+ operational state. */
+ xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+ if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0))
+ fail ("did not reach operational after error "
+ "and self-test\n");
+ }
+ }
+ }
+
+ }
+ else
+ {
+ /* If in standard mode, run selftests. */
+ if (gcry_control (GCRYCTL_SELFTEST, 0))
+ fail ("running self-test failed\n");
+ }
+
+ if (verbose)
+ fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count);
+
+ if (in_fips_mode && !gcry_fips_mode_active ())
+ fprintf (stderr, "FIPS mode is not anymore active\n");
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/basic_all_hwfeature_combinations.sh b/comm/third_party/libgcrypt/tests/basic_all_hwfeature_combinations.sh
new file mode 100755
index 0000000000..138719047c
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/basic_all_hwfeature_combinations.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+# Run basic tests with all HW feature combinations
+# Copyright 2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+
+# Use BINEXT to set executable extension
+# For example for Windows executables: BINEXT=.exe
+if [ "x$BINEXT" != "x" ] && [ -e "tests/version$BINEXT" ]; then
+ binext="$BINEXT"
+else
+ binext=""
+fi
+
+# Use BINPRE to set executable prefix
+# For example to run Windows executable with WINE: BINPRE="wine "
+if [ "x$BINPRE" != "x" ]; then
+ binpre="$BINPRE"
+else
+ binpre=""
+fi
+
+# Use NJOBS to define number of parallel tasks
+if [ "x$NJOBS" != "x" ]; then
+ njobs="$NJOBS"
+else
+ # default to cpu count
+ ncpus=$(nproc --all)
+ if [ "x@cpus" != "x" ]; then
+ njobs=$ncpus
+ else
+ # could not get cpu count, use 4 parallel tasks instead
+ njobs=4
+ fi
+fi
+
+get_supported_hwfeatures() {
+ $binpre "tests/version$binext" 2>&1 | \
+ grep "hwflist" | \
+ sed -e 's/hwflist://' -e 's/:/ /g' -e 's/\x0d/\x0a/g'
+}
+
+hwfs=($(get_supported_hwfeatures))
+retcodes=()
+optslist=()
+echo "Total HW-feature combinations: $((1<<${#hwfs[@]}))"
+for ((cbits=0; cbits < (1<<${#hwfs[@]}); cbits++)); do
+ for ((mask=0; mask < ${#hwfs[@]}; mask++)); do
+ match=$(((1<<mask) & cbits))
+ if [ "x$match" != "x0" ]; then
+ echo -n "--disable-hwf ${hwfs[$mask]} "
+ fi
+ done
+ echo ""
+done | sort | (
+ # Run all combinations
+ nbasic=0
+ nwait=0
+ failed=0
+ output=""
+ while read opts; do
+ currn=$nbasic
+ curr_jobs=($(jobs -p))
+ while [ "${#curr_jobs[@]}" -ge "$njobs" ]; do
+ # Wait for one job to complete
+ wait ${retcodes[$nwait]}
+ retval=$?
+ if [ "x$retval" != "x0" ]; then
+ output="$output\nERROR: HWF disable failed: [${optslist[$nwait]}]"
+ failed=1
+ else
+ output="$output\nSUCCESS: HWF disable OK: [${optslist[$nwait]}]"
+ fi
+ nwait=$((nwait+1))
+ curr_jobs=($(jobs -p))
+ if [ $failed != 0 ]; then
+ break
+ fi
+ done
+ if [ $failed != 0 ]; then
+ break
+ fi
+ nbasic=$((nbasic+1))
+ echo "[$nbasic/$((1<<${#hwfs[@]}))] Basic test with '$opts'"
+ optslist[$currn]="$opts"
+ nice nice $binpre "tests/basic$binext" $opts & retcodes[$currn]=$!
+ done
+
+ # Fetch remaining return codes
+ for ((; nwait < nbasic; nwait++)); do
+ # Wait for one job to complete
+ wait ${retcodes[$nwait]}
+ retval=$?
+ if [ "x$retval" != "x0" ]; then
+ output="$output\nERROR: HWF disable failed: [${optslist[$nwait]}]"
+ failed=1
+ else
+ output="$output\nSUCCESS: HWF disable OK: [${optslist[$nwait]}]"
+ fi
+ done
+
+ echo -e "$output"
+ exit $failed
+)
diff --git a/comm/third_party/libgcrypt/tests/bench-slope.c b/comm/third_party/libgcrypt/tests/bench-slope.c
new file mode 100644
index 0000000000..c8647b6b98
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/bench-slope.c
@@ -0,0 +1,2349 @@
+/* bench-slope.c - for libgcrypt
+ * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <time.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt-int.h"
+# include "../compat/libcompat.h"
+#else
+# include <gcrypt.h>
+#endif
+
+#ifndef STR
+#define STR(v) #v
+#define STR2(v) STR(v)
+#endif
+
+#define PGM "bench-slope"
+#include "t-common.h"
+
+static int verbose;
+static int csv_mode;
+static int unaligned_mode;
+static int num_measurement_repetitions;
+
+/* CPU Ghz value provided by user, allows constructing cycles/byte and other
+ results. */
+static double cpu_ghz = -1;
+
+/* Attempt to autodetect CPU Ghz. */
+static int auto_ghz;
+
+/* Whether we are running as part of the regression test suite. */
+static int in_regression_test;
+
+/* The name of the currently printed section. */
+static char *current_section_name;
+/* The name of the currently printed algorithm. */
+static char *current_algo_name;
+/* The name of the currently printed mode. */
+static char *current_mode_name;
+
+
+/* Currently used CPU Ghz (either user input or auto-detected. */
+static double bench_ghz;
+
+/* Current accuracy of auto-detected CPU Ghz. */
+static double bench_ghz_diff;
+
+
+/*************************************** Default parameters for measurements. */
+
+/* Start at small buffer size, to get reasonable timer calibration for fast
+ * implementations (AES-NI etc). Sixteen selected to support the largest block
+ * size of current set cipher blocks. */
+#define BUF_START_SIZE 16
+
+/* From ~0 to ~4kbytes give comparable results with results from academia
+ * (SUPERCOP). */
+#define BUF_END_SIZE (BUF_START_SIZE + 4096)
+
+/* With 128 byte steps, we get (4096)/64 = 64 data points. */
+#define BUF_STEP_SIZE 64
+
+/* Number of repeated measurements at each data point. The median of these
+ * measurements is selected as data point further analysis. */
+#define NUM_MEASUREMENT_REPETITIONS 64
+
+/* Target accuracy for auto-detected CPU Ghz. */
+#define AUTO_GHZ_TARGET_DIFF (5e-5)
+
+/**************************************************** High-resolution timers. */
+
+/* This benchmarking module needs needs high resolution timer. */
+#undef NO_GET_NSEC_TIME
+#if defined(_WIN32)
+struct nsec_time
+{
+ LARGE_INTEGER perf_count;
+};
+
+static void
+get_nsec_time (struct nsec_time *t)
+{
+ BOOL ok;
+
+ ok = QueryPerformanceCounter (&t->perf_count);
+ assert (ok);
+}
+
+static double
+get_time_nsec_diff (struct nsec_time *start, struct nsec_time *end)
+{
+ static double nsecs_per_count = 0.0;
+ double nsecs;
+
+ if (nsecs_per_count == 0.0)
+ {
+ LARGE_INTEGER perf_freq;
+ BOOL ok;
+
+ /* Get counts per second. */
+ ok = QueryPerformanceFrequency (&perf_freq);
+ assert (ok);
+
+ nsecs_per_count = 1.0 / perf_freq.QuadPart;
+ nsecs_per_count *= 1000000.0 * 1000.0; /* sec => nsec */
+
+ assert (nsecs_per_count > 0.0);
+ }
+
+ nsecs = end->perf_count.QuadPart - start->perf_count.QuadPart; /* counts */
+ nsecs *= nsecs_per_count; /* counts * (nsecs / count) => nsecs */
+
+ return nsecs;
+}
+#elif defined(HAVE_CLOCK_GETTIME)
+struct nsec_time
+{
+ struct timespec ts;
+};
+
+static void
+get_nsec_time (struct nsec_time *t)
+{
+ int err;
+
+ err = clock_gettime (CLOCK_REALTIME, &t->ts);
+ assert (err == 0);
+}
+
+static double
+get_time_nsec_diff (struct nsec_time *start, struct nsec_time *end)
+{
+ double nsecs;
+
+ nsecs = end->ts.tv_sec - start->ts.tv_sec;
+ nsecs *= 1000000.0 * 1000.0; /* sec => nsec */
+
+ /* This way we don't have to care if tv_nsec unsigned or signed. */
+ if (end->ts.tv_nsec >= start->ts.tv_nsec)
+ nsecs += end->ts.tv_nsec - start->ts.tv_nsec;
+ else
+ nsecs -= start->ts.tv_nsec - end->ts.tv_nsec;
+
+ return nsecs;
+}
+#elif defined(HAVE_GETTIMEOFDAY)
+struct nsec_time
+{
+ struct timeval tv;
+};
+
+static void
+get_nsec_time (struct nsec_time *t)
+{
+ int err;
+
+ err = gettimeofday (&t->tv, NULL);
+ assert (err == 0);
+}
+
+static double
+get_time_nsec_diff (struct nsec_time *start, struct nsec_time *end)
+{
+ double nsecs;
+
+ nsecs = end->tv.tv_sec - start->tv.tv_sec;
+ nsecs *= 1000000; /* sec => µsec */
+
+ /* This way we don't have to care if tv_usec unsigned or signed. */
+ if (end->tv.tv_usec >= start->tv.tv_usec)
+ nsecs += end->tv.tv_usec - start->tv.tv_usec;
+ else
+ nsecs -= start->tv.tv_usec - end->tv.tv_usec;
+
+ nsecs *= 1000; /* µsec => nsec */
+
+ return nsecs;
+}
+#else
+#define NO_GET_NSEC_TIME 1
+#endif
+
+
+/* If no high resolution timer found, provide dummy bench-slope. */
+#ifdef NO_GET_NSEC_TIME
+
+
+int
+main (void)
+{
+ /* No nsec timer => SKIP test. */
+ return 77;
+}
+
+
+#else /* !NO_GET_NSEC_TIME */
+
+
+/********************************************** Slope benchmarking framework. */
+
+struct bench_obj
+{
+ const struct bench_ops *ops;
+
+ unsigned int num_measure_repetitions;
+ unsigned int min_bufsize;
+ unsigned int max_bufsize;
+ unsigned int step_size;
+
+ void *priv;
+ void *hd;
+};
+
+typedef int (*const bench_initialize_t) (struct bench_obj * obj);
+typedef void (*const bench_finalize_t) (struct bench_obj * obj);
+typedef void (*const bench_do_run_t) (struct bench_obj * obj, void *buffer,
+ size_t buflen);
+
+struct bench_ops
+{
+ bench_initialize_t initialize;
+ bench_finalize_t finalize;
+ bench_do_run_t do_run;
+};
+
+
+double
+get_slope (double (*const get_x) (unsigned int idx, void *priv),
+ void *get_x_priv, double y_points[], unsigned int npoints,
+ double *overhead)
+{
+ double sumx, sumy, sumx2, sumy2, sumxy;
+ unsigned int i;
+ double b, a;
+
+ sumx = sumy = sumx2 = sumy2 = sumxy = 0;
+
+ for (i = 0; i < npoints; i++)
+ {
+ double x, y;
+
+ x = get_x (i, get_x_priv); /* bytes */
+ y = y_points[i]; /* nsecs */
+
+ sumx += x;
+ sumy += y;
+ sumx2 += x * x;
+ /*sumy2 += y * y;*/
+ sumxy += x * y;
+ }
+
+ b = (npoints * sumxy - sumx * sumy) / (npoints * sumx2 - sumx * sumx);
+ a = (sumy - b * sumx) / npoints;
+
+ if (overhead)
+ *overhead = a; /* nsecs */
+
+ return b; /* nsecs per byte */
+}
+
+
+double
+get_bench_obj_point_x (unsigned int idx, void *priv)
+{
+ struct bench_obj *obj = priv;
+ return (double) (obj->min_bufsize + (idx * obj->step_size));
+}
+
+
+unsigned int
+get_num_measurements (struct bench_obj *obj)
+{
+ unsigned int buf_range = obj->max_bufsize - obj->min_bufsize;
+ unsigned int num = buf_range / obj->step_size + 1;
+
+ while (obj->min_bufsize + (num * obj->step_size) > obj->max_bufsize)
+ num--;
+
+ return num + 1;
+}
+
+
+static int
+double_cmp (const void *_a, const void *_b)
+{
+ const double *a, *b;
+
+ a = _a;
+ b = _b;
+
+ if (*a > *b)
+ return 1;
+ if (*a < *b)
+ return -1;
+ return 0;
+}
+
+
+double
+do_bench_obj_measurement (struct bench_obj *obj, void *buffer, size_t buflen,
+ double *measurement_raw,
+ unsigned int loop_iterations)
+{
+ const unsigned int num_repetitions = obj->num_measure_repetitions;
+ const bench_do_run_t do_run = obj->ops->do_run;
+ struct nsec_time start, end;
+ unsigned int rep, loop;
+ double res;
+
+ if (num_repetitions < 1 || loop_iterations < 1)
+ return 0.0;
+
+ for (rep = 0; rep < num_repetitions; rep++)
+ {
+ get_nsec_time (&start);
+
+ for (loop = 0; loop < loop_iterations; loop++)
+ do_run (obj, buffer, buflen);
+
+ get_nsec_time (&end);
+
+ measurement_raw[rep] = get_time_nsec_diff (&start, &end);
+ }
+
+ /* Return median of repeated measurements. */
+ qsort (measurement_raw, num_repetitions, sizeof (measurement_raw[0]),
+ double_cmp);
+
+ if (num_repetitions % 2 == 1)
+ return measurement_raw[num_repetitions / 2];
+
+ res = measurement_raw[num_repetitions / 2]
+ + measurement_raw[num_repetitions / 2 - 1];
+ return res / 2;
+}
+
+
+unsigned int
+adjust_loop_iterations_to_timer_accuracy (struct bench_obj *obj, void *buffer,
+ double *measurement_raw)
+{
+ const double increase_thres = 3.0;
+ double tmp, nsecs;
+ unsigned int loop_iterations;
+ unsigned int test_bufsize;
+
+ test_bufsize = obj->min_bufsize;
+ if (test_bufsize == 0)
+ test_bufsize += obj->step_size;
+
+ loop_iterations = 0;
+ do
+ {
+ /* Increase loop iterations until we get other results than zero. */
+ nsecs =
+ do_bench_obj_measurement (obj, buffer, test_bufsize,
+ measurement_raw, ++loop_iterations);
+ }
+ while (nsecs < 1.0 - 0.1);
+ do
+ {
+ /* Increase loop iterations until we get reasonable increase for elapsed time. */
+ tmp =
+ do_bench_obj_measurement (obj, buffer, test_bufsize,
+ measurement_raw, ++loop_iterations);
+ }
+ while (tmp < nsecs * (increase_thres - 0.1));
+
+ return loop_iterations;
+}
+
+
+/* Benchmark and return linear regression slope in nanoseconds per byte. */
+double
+slope_benchmark (struct bench_obj *obj)
+{
+ unsigned int num_measurements;
+ double *measurements = NULL;
+ double *measurement_raw = NULL;
+ double slope, overhead;
+ unsigned int loop_iterations, midx, i;
+ unsigned char *real_buffer = NULL;
+ unsigned char *buffer;
+ size_t cur_bufsize;
+ int err;
+
+ err = obj->ops->initialize (obj);
+ if (err < 0)
+ return -1;
+
+ num_measurements = get_num_measurements (obj);
+ measurements = calloc (num_measurements, sizeof (*measurements));
+ if (!measurements)
+ goto err_free;
+
+ measurement_raw =
+ calloc (obj->num_measure_repetitions, sizeof (*measurement_raw));
+ if (!measurement_raw)
+ goto err_free;
+
+ if (num_measurements < 1 || obj->num_measure_repetitions < 1 ||
+ obj->max_bufsize < 1 || obj->min_bufsize > obj->max_bufsize)
+ goto err_free;
+
+ real_buffer = malloc (obj->max_bufsize + 128 + unaligned_mode);
+ if (!real_buffer)
+ goto err_free;
+ /* Get aligned buffer */
+ buffer = real_buffer;
+ buffer += 128 - ((real_buffer - (unsigned char *) 0) & (128 - 1));
+ if (unaligned_mode)
+ buffer += unaligned_mode; /* Make buffer unaligned */
+
+ for (i = 0; i < obj->max_bufsize; i++)
+ buffer[i] = 0x55 ^ (-i);
+
+ /* Adjust number of loop iterations up to timer accuracy. */
+ loop_iterations = adjust_loop_iterations_to_timer_accuracy (obj, buffer,
+ measurement_raw);
+
+ /* Perform measurements */
+ for (midx = 0, cur_bufsize = obj->min_bufsize;
+ cur_bufsize <= obj->max_bufsize; cur_bufsize += obj->step_size, midx++)
+ {
+ measurements[midx] =
+ do_bench_obj_measurement (obj, buffer, cur_bufsize, measurement_raw,
+ loop_iterations);
+ measurements[midx] /= loop_iterations;
+ }
+
+ assert (midx == num_measurements);
+
+ slope =
+ get_slope (&get_bench_obj_point_x, obj, measurements, num_measurements,
+ &overhead);
+
+ free (measurement_raw);
+ free (measurements);
+ free (real_buffer);
+ obj->ops->finalize (obj);
+
+ return slope;
+
+err_free:
+ if (measurement_raw)
+ free (measurement_raw);
+ if (measurements)
+ free (measurements);
+ if (real_buffer)
+ free (real_buffer);
+ obj->ops->finalize (obj);
+
+ return -1;
+}
+
+/********************************************* CPU frequency auto-detection. */
+
+static int
+auto_ghz_init (struct bench_obj *obj)
+{
+ obj->min_bufsize = 16;
+ obj->max_bufsize = 64 + obj->min_bufsize;
+ obj->step_size = 8;
+ obj->num_measure_repetitions = 16;
+
+ return 0;
+}
+
+static void
+auto_ghz_free (struct bench_obj *obj)
+{
+ (void)obj;
+}
+
+static void
+auto_ghz_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+ (void)obj;
+ (void)buf;
+
+ buflen *= 1024;
+
+ /* Turbo frequency detection benchmark. Without CPU turbo-boost, this
+ * function will give cycles/iteration result 1024.0 on high-end CPUs.
+ * With turbo, result will be less and can be used detect turbo-clock. */
+
+#ifdef HAVE_GCC_ASM_VOLATILE_MEMORY
+ /* Auto-ghz operation takes two CPU cycles to perform. Memory barriers
+ * are used to prevent compiler from optimizing this loop away. */
+ #define AUTO_GHZ_OPERATION \
+ asm volatile ("":"+r"(buflen)::"memory"); \
+ buflen ^= 1; \
+ asm volatile ("":"+r"(buflen)::"memory"); \
+ buflen -= 2
+#else
+ /* TODO: Needs alternative way of preventing compiler optimizations.
+ * Mix of XOR and subtraction appears to do the trick for now. */
+ #define AUTO_GHZ_OPERATION \
+ buflen ^= 1; \
+ buflen -= 2
+#endif
+
+#define AUTO_GHZ_OPERATION_2 \
+ AUTO_GHZ_OPERATION; \
+ AUTO_GHZ_OPERATION
+
+#define AUTO_GHZ_OPERATION_4 \
+ AUTO_GHZ_OPERATION_2; \
+ AUTO_GHZ_OPERATION_2
+
+#define AUTO_GHZ_OPERATION_8 \
+ AUTO_GHZ_OPERATION_4; \
+ AUTO_GHZ_OPERATION_4
+
+#define AUTO_GHZ_OPERATION_16 \
+ AUTO_GHZ_OPERATION_8; \
+ AUTO_GHZ_OPERATION_8
+
+#define AUTO_GHZ_OPERATION_32 \
+ AUTO_GHZ_OPERATION_16; \
+ AUTO_GHZ_OPERATION_16
+
+#define AUTO_GHZ_OPERATION_64 \
+ AUTO_GHZ_OPERATION_32; \
+ AUTO_GHZ_OPERATION_32
+
+#define AUTO_GHZ_OPERATION_128 \
+ AUTO_GHZ_OPERATION_64; \
+ AUTO_GHZ_OPERATION_64
+
+ do
+ {
+ /* 1024 auto-ghz operations per loop, total 2048 instructions. */
+ AUTO_GHZ_OPERATION_128; AUTO_GHZ_OPERATION_128;
+ AUTO_GHZ_OPERATION_128; AUTO_GHZ_OPERATION_128;
+ AUTO_GHZ_OPERATION_128; AUTO_GHZ_OPERATION_128;
+ AUTO_GHZ_OPERATION_128; AUTO_GHZ_OPERATION_128;
+ }
+ while (buflen);
+}
+
+static struct bench_ops auto_ghz_detect_ops = {
+ &auto_ghz_init,
+ &auto_ghz_free,
+ &auto_ghz_bench
+};
+
+
+double
+get_auto_ghz (void)
+{
+ struct bench_obj obj = { 0 };
+ double nsecs_per_iteration;
+ double cycles_per_iteration;
+
+ obj.ops = &auto_ghz_detect_ops;
+
+ nsecs_per_iteration = slope_benchmark (&obj);
+
+ cycles_per_iteration = nsecs_per_iteration * cpu_ghz;
+
+ /* Adjust CPU Ghz so that cycles per iteration would give '1024.0'. */
+
+ return cpu_ghz * 1024 / cycles_per_iteration;
+}
+
+
+double
+do_slope_benchmark (struct bench_obj *obj)
+{
+ double ret;
+
+ if (!auto_ghz)
+ {
+ /* Perform measurement without autodetection of CPU frequency. */
+
+ ret = slope_benchmark (obj);
+
+ bench_ghz = cpu_ghz;
+ bench_ghz_diff = 0;
+ }
+ else
+ {
+ double target_diff = AUTO_GHZ_TARGET_DIFF;
+ double cpu_auto_ghz_before;
+ double cpu_auto_ghz_after;
+ double nsecs_per_iteration;
+ double diff;
+ unsigned int try_count = 0;
+
+ /* Perform measurement with CPU frequency autodetection. */
+
+ do
+ {
+ /* Repeat measurement until CPU turbo frequency has stabilized. */
+
+ if (try_count++ > 4)
+ {
+ /* Too much frequency instability on the system, relax target
+ * accuracy. */
+
+ try_count = 0;
+ target_diff *= 2;
+ }
+
+ cpu_auto_ghz_before = get_auto_ghz ();
+
+ nsecs_per_iteration = slope_benchmark (obj);
+
+ cpu_auto_ghz_after = get_auto_ghz ();
+
+ diff = 1.0 - (cpu_auto_ghz_before / cpu_auto_ghz_after);
+ diff = diff < 0 ? -diff : diff;
+ }
+ while (diff > target_diff);
+
+ ret = nsecs_per_iteration;
+
+ bench_ghz = (cpu_auto_ghz_before + cpu_auto_ghz_after) / 2;
+ bench_ghz_diff = diff;
+ }
+
+ return ret;
+}
+
+
+/********************************************************** Printing results. */
+
+static void
+double_to_str (char *out, size_t outlen, double value)
+{
+ const char *fmt;
+
+ if (value < 1.0)
+ fmt = "%.3f";
+ else if (value < 100.0)
+ fmt = "%.2f";
+ else if (value < 1000.0)
+ fmt = "%.1f";
+ else
+ fmt = "%.0f";
+
+ snprintf (out, outlen, fmt, value);
+}
+
+static void
+bench_print_result_csv (double nsecs_per_byte)
+{
+ double cycles_per_byte, mbytes_per_sec;
+ char nsecpbyte_buf[16];
+ char mbpsec_buf[16];
+ char cpbyte_buf[16];
+ char mhz_buf[16];
+ char mhz_diff_buf[32];
+
+ strcpy (mhz_diff_buf, "");
+ *cpbyte_buf = 0;
+ *mhz_buf = 0;
+
+ double_to_str (nsecpbyte_buf, sizeof (nsecpbyte_buf), nsecs_per_byte);
+
+ /* If user didn't provide CPU speed, we cannot show cycles/byte results. */
+ if (bench_ghz > 0.0)
+ {
+ cycles_per_byte = nsecs_per_byte * bench_ghz;
+ double_to_str (cpbyte_buf, sizeof (cpbyte_buf), cycles_per_byte);
+ double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000);
+ if (auto_ghz && bench_ghz_diff * 1000 >= 1)
+ {
+ snprintf(mhz_diff_buf, sizeof(mhz_diff_buf), ",%.0f,Mhz-diff",
+ bench_ghz_diff * 1000);
+ }
+ }
+
+ mbytes_per_sec =
+ (1000.0 * 1000.0 * 1000.0) / (nsecs_per_byte * 1024 * 1024);
+ double_to_str (mbpsec_buf, sizeof (mbpsec_buf), mbytes_per_sec);
+
+ /* We print two empty fields to allow for future enhancements. */
+ if (auto_ghz)
+ {
+ printf ("%s,%s,%s,,,%s,ns/B,%s,MiB/s,%s,c/B,%s,Mhz%s\n",
+ current_section_name,
+ current_algo_name? current_algo_name : "",
+ current_mode_name? current_mode_name : "",
+ nsecpbyte_buf,
+ mbpsec_buf,
+ cpbyte_buf,
+ mhz_buf,
+ mhz_diff_buf);
+ }
+ else
+ {
+ printf ("%s,%s,%s,,,%s,ns/B,%s,MiB/s,%s,c/B\n",
+ current_section_name,
+ current_algo_name? current_algo_name : "",
+ current_mode_name? current_mode_name : "",
+ nsecpbyte_buf,
+ mbpsec_buf,
+ cpbyte_buf);
+ }
+}
+
+static void
+bench_print_result_std (double nsecs_per_byte)
+{
+ double cycles_per_byte, mbytes_per_sec;
+ char nsecpbyte_buf[16];
+ char mbpsec_buf[16];
+ char cpbyte_buf[16];
+ char mhz_buf[16];
+ char mhz_diff_buf[32];
+
+ strcpy (mhz_diff_buf, "");
+
+ double_to_str (nsecpbyte_buf, sizeof (nsecpbyte_buf), nsecs_per_byte);
+
+ /* If user didn't provide CPU speed, we cannot show cycles/byte results. */
+ if (bench_ghz > 0.0)
+ {
+ cycles_per_byte = nsecs_per_byte * bench_ghz;
+ double_to_str (cpbyte_buf, sizeof (cpbyte_buf), cycles_per_byte);
+ double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000);
+ if (auto_ghz && bench_ghz_diff * 1000 >= 0.5)
+ {
+ snprintf(mhz_diff_buf, sizeof(mhz_diff_buf), "±%.0f",
+ bench_ghz_diff * 1000);
+ }
+ }
+ else
+ {
+ strcpy (cpbyte_buf, "-");
+ strcpy (mhz_buf, "-");
+ }
+
+ mbytes_per_sec =
+ (1000.0 * 1000.0 * 1000.0) / (nsecs_per_byte * 1024 * 1024);
+ double_to_str (mbpsec_buf, sizeof (mbpsec_buf), mbytes_per_sec);
+
+ if (auto_ghz)
+ {
+ printf ("%9s ns/B %9s MiB/s %9s c/B %9s%s\n",
+ nsecpbyte_buf, mbpsec_buf, cpbyte_buf, mhz_buf, mhz_diff_buf);
+ }
+ else
+ {
+ printf ("%9s ns/B %9s MiB/s %9s c/B\n",
+ nsecpbyte_buf, mbpsec_buf, cpbyte_buf);
+ }
+}
+
+static void
+bench_print_result (double nsecs_per_byte)
+{
+ if (csv_mode)
+ bench_print_result_csv (nsecs_per_byte);
+ else
+ bench_print_result_std (nsecs_per_byte);
+}
+
+static void
+bench_print_section (const char *section_name, const char *print_name)
+{
+ if (csv_mode)
+ {
+ gcry_free (current_section_name);
+ current_section_name = gcry_xstrdup (section_name);
+ }
+ else
+ printf ("%s:\n", print_name);
+}
+
+static void
+bench_print_header (int algo_width, const char *algo_name)
+{
+ if (csv_mode)
+ {
+ gcry_free (current_algo_name);
+ current_algo_name = gcry_xstrdup (algo_name);
+ }
+ else
+ {
+ if (algo_width < 0)
+ printf (" %-*s | ", -algo_width, algo_name);
+ else
+ printf (" %-*s | ", algo_width, algo_name);
+
+ if (auto_ghz)
+ printf ("%14s %15s %13s %9s\n", "nanosecs/byte", "mebibytes/sec",
+ "cycles/byte", "auto Mhz");
+ else
+ printf ("%14s %15s %13s\n", "nanosecs/byte", "mebibytes/sec",
+ "cycles/byte");
+ }
+}
+
+static void
+bench_print_algo (int algo_width, const char *algo_name)
+{
+ if (csv_mode)
+ {
+ gcry_free (current_algo_name);
+ current_algo_name = gcry_xstrdup (algo_name);
+ }
+ else
+ {
+ if (algo_width < 0)
+ printf (" %-*s | ", -algo_width, algo_name);
+ else
+ printf (" %-*s | ", algo_width, algo_name);
+ }
+}
+
+static void
+bench_print_mode (int width, const char *mode_name)
+{
+ if (csv_mode)
+ {
+ gcry_free (current_mode_name);
+ current_mode_name = gcry_xstrdup (mode_name);
+ }
+ else
+ {
+ if (width < 0)
+ printf (" %-*s | ", -width, mode_name);
+ else
+ printf (" %*s | ", width, mode_name);
+ fflush (stdout);
+ }
+}
+
+static void
+bench_print_footer (int algo_width)
+{
+ if (!csv_mode)
+ printf (" %-*s =\n", algo_width, "");
+}
+
+
+/********************************************************* Cipher benchmarks. */
+
+struct bench_cipher_mode
+{
+ int mode;
+ const char *name;
+ struct bench_ops *ops;
+
+ int algo;
+};
+
+
+static int
+bench_encrypt_init (struct bench_obj *obj)
+{
+ struct bench_cipher_mode *mode = obj->priv;
+ gcry_cipher_hd_t hd;
+ int err, keylen;
+
+ obj->min_bufsize = BUF_START_SIZE;
+ obj->max_bufsize = BUF_END_SIZE;
+ obj->step_size = BUF_STEP_SIZE;
+ obj->num_measure_repetitions = num_measurement_repetitions;
+
+ err = gcry_cipher_open (&hd, mode->algo, mode->mode, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening cipher `%s'\n",
+ gcry_cipher_algo_name (mode->algo));
+ exit (1);
+ }
+
+ keylen = gcry_cipher_get_algo_keylen (mode->algo);
+ if (keylen)
+ {
+ char key[keylen];
+ int i;
+
+ for (i = 0; i < keylen; i++)
+ key[i] = 0x33 ^ (11 - i);
+
+ err = gcry_cipher_setkey (hd, key, keylen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+ else
+ {
+ fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
+ gcry_cipher_algo_name (mode->algo));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ obj->hd = hd;
+
+ return 0;
+}
+
+static void
+bench_encrypt_free (struct bench_obj *obj)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+
+ gcry_cipher_close (hd);
+}
+
+static void
+bench_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+ int err;
+
+ err = gcry_cipher_reset (hd);
+ if (!err)
+ err = gcry_cipher_encrypt (hd, buf, buflen, buf, buflen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+static void
+bench_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+ int err;
+
+ err = gcry_cipher_reset (hd);
+ if (!err)
+ err = gcry_cipher_decrypt (hd, buf, buflen, buf, buflen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+static struct bench_ops encrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_encrypt_do_bench
+};
+
+static struct bench_ops decrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_decrypt_do_bench
+};
+
+
+static int
+bench_xts_encrypt_init (struct bench_obj *obj)
+{
+ struct bench_cipher_mode *mode = obj->priv;
+ gcry_cipher_hd_t hd;
+ int err, keylen;
+
+ obj->min_bufsize = BUF_START_SIZE;
+ obj->max_bufsize = BUF_END_SIZE;
+ obj->step_size = BUF_STEP_SIZE;
+ obj->num_measure_repetitions = num_measurement_repetitions;
+
+ err = gcry_cipher_open (&hd, mode->algo, mode->mode, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening cipher `%s'\n",
+ gcry_cipher_algo_name (mode->algo));
+ exit (1);
+ }
+
+ /* Double key-length for XTS. */
+ keylen = gcry_cipher_get_algo_keylen (mode->algo) * 2;
+ if (keylen)
+ {
+ char key[keylen];
+ int i;
+
+ for (i = 0; i < keylen; i++)
+ key[i] = 0x33 ^ (11 - i);
+
+ err = gcry_cipher_setkey (hd, key, keylen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+ else
+ {
+ fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
+ gcry_cipher_algo_name (mode->algo));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ obj->hd = hd;
+
+ return 0;
+}
+
+static struct bench_ops xts_encrypt_ops = {
+ &bench_xts_encrypt_init,
+ &bench_encrypt_free,
+ &bench_encrypt_do_bench
+};
+
+static struct bench_ops xts_decrypt_ops = {
+ &bench_xts_encrypt_init,
+ &bench_encrypt_free,
+ &bench_decrypt_do_bench
+};
+
+
+static void
+bench_ccm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+ int err;
+ char tag[8];
+ char nonce[11] = { 0x80, 0x01, };
+ u64 params[3];
+
+ gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+
+ /* Set CCM lengths */
+ params[0] = buflen;
+ params[1] = 0; /*aadlen */
+ params[2] = sizeof (tag);
+ err =
+ gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof (params));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_ctl failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_encrypt (hd, buf, buflen, buf, buflen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_gettag (hd, tag, sizeof (tag));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+static void
+bench_ccm_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+ int err;
+ char tag[8] = { 0, };
+ char nonce[11] = { 0x80, 0x01, };
+ u64 params[3];
+
+ gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+
+ /* Set CCM lengths */
+ params[0] = buflen;
+ params[1] = 0; /*aadlen */
+ params[2] = sizeof (tag);
+ err =
+ gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof (params));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_ctl failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_decrypt (hd, buf, buflen, buf, buflen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_checktag (hd, tag, sizeof (tag));
+ if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
+ err = gpg_error (GPG_ERR_NO_ERROR);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+static void
+bench_ccm_authenticate_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+ int err;
+ char tag[8] = { 0, };
+ char nonce[11] = { 0x80, 0x01, };
+ u64 params[3];
+ char data = 0xff;
+
+ gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+
+ /* Set CCM lengths */
+ params[0] = sizeof (data); /*datalen */
+ params[1] = buflen; /*aadlen */
+ params[2] = sizeof (tag);
+ err =
+ gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof (params));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_ctl failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_authenticate (hd, buf, buflen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_authenticate failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_encrypt (hd, &data, sizeof (data), &data, sizeof (data));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_gettag (hd, tag, sizeof (tag));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+static struct bench_ops ccm_encrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_ccm_encrypt_do_bench
+};
+
+static struct bench_ops ccm_decrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_ccm_decrypt_do_bench
+};
+
+static struct bench_ops ccm_authenticate_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_ccm_authenticate_do_bench
+};
+
+
+static void
+bench_aead_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen,
+ const char *nonce, size_t noncelen)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+ int err;
+ char tag[16];
+
+ gcry_cipher_setiv (hd, nonce, noncelen);
+
+ gcry_cipher_final (hd);
+ err = gcry_cipher_encrypt (hd, buf, buflen, buf, buflen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_gettag (hd, tag, sizeof (tag));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+static void
+bench_aead_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen,
+ const char *nonce, size_t noncelen)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+ int err;
+ char tag[16] = { 0, };
+
+ gcry_cipher_setiv (hd, nonce, noncelen);
+
+ gcry_cipher_final (hd);
+ err = gcry_cipher_decrypt (hd, buf, buflen, buf, buflen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_checktag (hd, tag, sizeof (tag));
+ if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
+ err = gpg_error (GPG_ERR_NO_ERROR);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+static void
+bench_aead_authenticate_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen, const char *nonce,
+ size_t noncelen)
+{
+ gcry_cipher_hd_t hd = obj->hd;
+ int err;
+ char tag[16] = { 0, };
+ char data = 0xff;
+
+ err = gcry_cipher_setiv (hd, nonce, noncelen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_authenticate (hd, buf, buflen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_authenticate failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ gcry_cipher_final (hd);
+ err = gcry_cipher_encrypt (hd, &data, sizeof (data), &data, sizeof (data));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ err = gcry_cipher_gettag (hd, tag, sizeof (tag));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+
+static void
+bench_gcm_encrypt_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88 };
+ bench_aead_encrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_gcm_decrypt_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88 };
+ bench_aead_decrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_gcm_authenticate_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88 };
+ bench_aead_authenticate_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static struct bench_ops gcm_encrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_gcm_encrypt_do_bench
+};
+
+static struct bench_ops gcm_decrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_gcm_decrypt_do_bench
+};
+
+static struct bench_ops gcm_authenticate_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_gcm_authenticate_do_bench
+};
+
+
+static void
+bench_ocb_encrypt_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[15] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+ 0x00, 0x00, 0x01 };
+ bench_aead_encrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_ocb_decrypt_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[15] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+ 0x00, 0x00, 0x01 };
+ bench_aead_decrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_ocb_authenticate_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[15] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+ 0x00, 0x00, 0x01 };
+ bench_aead_authenticate_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static struct bench_ops ocb_encrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_ocb_encrypt_do_bench
+};
+
+static struct bench_ops ocb_decrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_ocb_decrypt_do_bench
+};
+
+static struct bench_ops ocb_authenticate_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_ocb_authenticate_do_bench
+};
+
+static void
+bench_eax_encrypt_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[16] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+ 0x00, 0x00, 0x01, 0x00 };
+ bench_aead_encrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_eax_decrypt_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[16] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+ 0x00, 0x00, 0x01, 0x00 };
+ bench_aead_decrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_eax_authenticate_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[16] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
+ 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
+ 0x00, 0x00, 0x01, 0x00 };
+ bench_aead_authenticate_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static struct bench_ops eax_encrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_eax_encrypt_do_bench
+};
+
+static struct bench_ops eax_decrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_eax_decrypt_do_bench
+};
+
+static struct bench_ops eax_authenticate_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_eax_authenticate_do_bench
+};
+
+static void
+bench_poly1305_encrypt_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[8] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+ bench_aead_encrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_poly1305_decrypt_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[8] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+ bench_aead_decrypt_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static void
+bench_poly1305_authenticate_do_bench (struct bench_obj *obj, void *buf,
+ size_t buflen)
+{
+ char nonce[8] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+ bench_aead_authenticate_do_bench (obj, buf, buflen, nonce, sizeof(nonce));
+}
+
+static struct bench_ops poly1305_encrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_poly1305_encrypt_do_bench
+};
+
+static struct bench_ops poly1305_decrypt_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_poly1305_decrypt_do_bench
+};
+
+static struct bench_ops poly1305_authenticate_ops = {
+ &bench_encrypt_init,
+ &bench_encrypt_free,
+ &bench_poly1305_authenticate_do_bench
+};
+
+
+static struct bench_cipher_mode cipher_modes[] = {
+ {GCRY_CIPHER_MODE_ECB, "ECB enc", &encrypt_ops},
+ {GCRY_CIPHER_MODE_ECB, "ECB dec", &decrypt_ops},
+ {GCRY_CIPHER_MODE_CBC, "CBC enc", &encrypt_ops},
+ {GCRY_CIPHER_MODE_CBC, "CBC dec", &decrypt_ops},
+ {GCRY_CIPHER_MODE_CFB, "CFB enc", &encrypt_ops},
+ {GCRY_CIPHER_MODE_CFB, "CFB dec", &decrypt_ops},
+ {GCRY_CIPHER_MODE_OFB, "OFB enc", &encrypt_ops},
+ {GCRY_CIPHER_MODE_OFB, "OFB dec", &decrypt_ops},
+ {GCRY_CIPHER_MODE_CTR, "CTR enc", &encrypt_ops},
+ {GCRY_CIPHER_MODE_CTR, "CTR dec", &decrypt_ops},
+ {GCRY_CIPHER_MODE_XTS, "XTS enc", &xts_encrypt_ops},
+ {GCRY_CIPHER_MODE_XTS, "XTS dec", &xts_decrypt_ops},
+ {GCRY_CIPHER_MODE_CCM, "CCM enc", &ccm_encrypt_ops},
+ {GCRY_CIPHER_MODE_CCM, "CCM dec", &ccm_decrypt_ops},
+ {GCRY_CIPHER_MODE_CCM, "CCM auth", &ccm_authenticate_ops},
+ {GCRY_CIPHER_MODE_EAX, "EAX enc", &eax_encrypt_ops},
+ {GCRY_CIPHER_MODE_EAX, "EAX dec", &eax_decrypt_ops},
+ {GCRY_CIPHER_MODE_EAX, "EAX auth", &eax_authenticate_ops},
+ {GCRY_CIPHER_MODE_GCM, "GCM enc", &gcm_encrypt_ops},
+ {GCRY_CIPHER_MODE_GCM, "GCM dec", &gcm_decrypt_ops},
+ {GCRY_CIPHER_MODE_GCM, "GCM auth", &gcm_authenticate_ops},
+ {GCRY_CIPHER_MODE_OCB, "OCB enc", &ocb_encrypt_ops},
+ {GCRY_CIPHER_MODE_OCB, "OCB dec", &ocb_decrypt_ops},
+ {GCRY_CIPHER_MODE_OCB, "OCB auth", &ocb_authenticate_ops},
+ {GCRY_CIPHER_MODE_POLY1305, "POLY1305 enc", &poly1305_encrypt_ops},
+ {GCRY_CIPHER_MODE_POLY1305, "POLY1305 dec", &poly1305_decrypt_ops},
+ {GCRY_CIPHER_MODE_POLY1305, "POLY1305 auth", &poly1305_authenticate_ops},
+ {0},
+};
+
+
+static void
+cipher_bench_one (int algo, struct bench_cipher_mode *pmode)
+{
+ struct bench_cipher_mode mode = *pmode;
+ struct bench_obj obj = { 0 };
+ double result;
+ unsigned int blklen;
+
+ mode.algo = algo;
+
+ /* Check if this mode is ok */
+ blklen = gcry_cipher_get_algo_blklen (algo);
+ if (!blklen)
+ return;
+
+ /* Stream cipher? Only test with "ECB" and POLY1305. */
+ if (blklen == 1 && (mode.mode != GCRY_CIPHER_MODE_ECB &&
+ mode.mode != GCRY_CIPHER_MODE_POLY1305))
+ return;
+ if (blklen == 1 && mode.mode == GCRY_CIPHER_MODE_ECB)
+ {
+ mode.mode = GCRY_CIPHER_MODE_STREAM;
+ mode.name = mode.ops == &encrypt_ops ? "STREAM enc" : "STREAM dec";
+ }
+
+ /* Poly1305 has restriction for cipher algorithm */
+ if (mode.mode == GCRY_CIPHER_MODE_POLY1305 && algo != GCRY_CIPHER_CHACHA20)
+ return;
+
+ /* CCM has restrictions for block-size */
+ if (mode.mode == GCRY_CIPHER_MODE_CCM && blklen != GCRY_CCM_BLOCK_LEN)
+ return;
+
+ /* GCM has restrictions for block-size */
+ if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN)
+ return;
+
+ /* XTS has restrictions for block-size */
+ if (mode.mode == GCRY_CIPHER_MODE_XTS && blklen != GCRY_XTS_BLOCK_LEN)
+ return;
+
+ /* Our OCB implementation has restrictions for block-size. */
+ if (mode.mode == GCRY_CIPHER_MODE_OCB && blklen != GCRY_OCB_BLOCK_LEN)
+ return;
+
+ bench_print_mode (14, mode.name);
+
+ obj.ops = mode.ops;
+ obj.priv = &mode;
+
+ result = do_slope_benchmark (&obj);
+
+ bench_print_result (result);
+}
+
+
+static void
+_cipher_bench (int algo)
+{
+ const char *algoname;
+ int i;
+
+ algoname = gcry_cipher_algo_name (algo);
+
+ bench_print_header (14, algoname);
+
+ for (i = 0; cipher_modes[i].mode; i++)
+ cipher_bench_one (algo, &cipher_modes[i]);
+
+ bench_print_footer (14);
+}
+
+
+void
+cipher_bench (char **argv, int argc)
+{
+ int i, algo;
+
+ bench_print_section ("cipher", "Cipher");
+
+ if (argv && argc)
+ {
+ for (i = 0; i < argc; i++)
+ {
+ algo = gcry_cipher_map_name (argv[i]);
+ if (algo)
+ _cipher_bench (algo);
+ }
+ }
+ else
+ {
+ for (i = 1; i < 400; i++)
+ if (!gcry_cipher_test_algo (i))
+ _cipher_bench (i);
+ }
+}
+
+
+/*********************************************************** Hash benchmarks. */
+
+struct bench_hash_mode
+{
+ const char *name;
+ struct bench_ops *ops;
+
+ int algo;
+};
+
+
+static int
+bench_hash_init (struct bench_obj *obj)
+{
+ struct bench_hash_mode *mode = obj->priv;
+ gcry_md_hd_t hd;
+ int err;
+
+ obj->min_bufsize = BUF_START_SIZE;
+ obj->max_bufsize = BUF_END_SIZE;
+ obj->step_size = BUF_STEP_SIZE;
+ obj->num_measure_repetitions = num_measurement_repetitions;
+
+ err = gcry_md_open (&hd, mode->algo, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening hash `%s'\n",
+ gcry_md_algo_name (mode->algo));
+ exit (1);
+ }
+
+ obj->hd = hd;
+
+ return 0;
+}
+
+static void
+bench_hash_free (struct bench_obj *obj)
+{
+ gcry_md_hd_t hd = obj->hd;
+
+ gcry_md_close (hd);
+}
+
+static void
+bench_hash_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+ gcry_md_hd_t hd = obj->hd;
+
+ gcry_md_reset (hd);
+ gcry_md_write (hd, buf, buflen);
+ gcry_md_final (hd);
+}
+
+static struct bench_ops hash_ops = {
+ &bench_hash_init,
+ &bench_hash_free,
+ &bench_hash_do_bench
+};
+
+
+static struct bench_hash_mode hash_modes[] = {
+ {"", &hash_ops},
+ {0},
+};
+
+
+static void
+hash_bench_one (int algo, struct bench_hash_mode *pmode)
+{
+ struct bench_hash_mode mode = *pmode;
+ struct bench_obj obj = { 0 };
+ double result;
+
+ mode.algo = algo;
+
+ if (mode.name[0] == '\0')
+ bench_print_algo (-14, gcry_md_algo_name (algo));
+ else
+ bench_print_algo (14, mode.name);
+
+ obj.ops = mode.ops;
+ obj.priv = &mode;
+
+ result = do_slope_benchmark (&obj);
+
+ bench_print_result (result);
+}
+
+static void
+_hash_bench (int algo)
+{
+ int i;
+
+ for (i = 0; hash_modes[i].name; i++)
+ hash_bench_one (algo, &hash_modes[i]);
+}
+
+void
+hash_bench (char **argv, int argc)
+{
+ int i, algo;
+
+ bench_print_section ("hash", "Hash");
+ bench_print_header (14, "");
+
+ if (argv && argc)
+ {
+ for (i = 0; i < argc; i++)
+ {
+ algo = gcry_md_map_name (argv[i]);
+ if (algo)
+ _hash_bench (algo);
+ }
+ }
+ else
+ {
+ for (i = 1; i < 400; i++)
+ if (!gcry_md_test_algo (i))
+ _hash_bench (i);
+ }
+
+ bench_print_footer (14);
+}
+
+
+/************************************************************ MAC benchmarks. */
+
+struct bench_mac_mode
+{
+ const char *name;
+ struct bench_ops *ops;
+
+ int algo;
+};
+
+
+static int
+bench_mac_init (struct bench_obj *obj)
+{
+ struct bench_mac_mode *mode = obj->priv;
+ gcry_mac_hd_t hd;
+ int err;
+ unsigned int keylen;
+ void *key;
+
+ obj->min_bufsize = BUF_START_SIZE;
+ obj->max_bufsize = BUF_END_SIZE;
+ obj->step_size = BUF_STEP_SIZE;
+ obj->num_measure_repetitions = num_measurement_repetitions;
+
+ keylen = gcry_mac_get_algo_keylen (mode->algo);
+ if (keylen == 0)
+ keylen = 32;
+ key = malloc (keylen);
+ if (!key)
+ {
+ fprintf (stderr, PGM ": couldn't allocate %d bytes\n", keylen);
+ exit (1);
+ }
+ memset(key, 42, keylen);
+
+ err = gcry_mac_open (&hd, mode->algo, 0, NULL);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening mac `%s'\n",
+ gcry_mac_algo_name (mode->algo));
+ free (key);
+ exit (1);
+ }
+
+ err = gcry_mac_setkey (hd, key, keylen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error setting key for mac `%s'\n",
+ gcry_mac_algo_name (mode->algo));
+ free (key);
+ exit (1);
+ }
+
+ switch (mode->algo)
+ {
+ default:
+ break;
+ case GCRY_MAC_POLY1305_AES:
+ case GCRY_MAC_POLY1305_CAMELLIA:
+ case GCRY_MAC_POLY1305_TWOFISH:
+ case GCRY_MAC_POLY1305_SERPENT:
+ case GCRY_MAC_POLY1305_SEED:
+ gcry_mac_setiv (hd, key, 16);
+ break;
+ }
+
+ obj->hd = hd;
+
+ free (key);
+ return 0;
+}
+
+static void
+bench_mac_free (struct bench_obj *obj)
+{
+ gcry_mac_hd_t hd = obj->hd;
+
+ gcry_mac_close (hd);
+}
+
+static void
+bench_mac_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+ gcry_mac_hd_t hd = obj->hd;
+ size_t bs;
+ char b;
+
+ gcry_mac_reset (hd);
+ gcry_mac_write (hd, buf, buflen);
+ bs = sizeof(b);
+ gcry_mac_read (hd, &b, &bs);
+}
+
+static struct bench_ops mac_ops = {
+ &bench_mac_init,
+ &bench_mac_free,
+ &bench_mac_do_bench
+};
+
+
+static struct bench_mac_mode mac_modes[] = {
+ {"", &mac_ops},
+ {0},
+};
+
+
+static void
+mac_bench_one (int algo, struct bench_mac_mode *pmode)
+{
+ struct bench_mac_mode mode = *pmode;
+ struct bench_obj obj = { 0 };
+ double result;
+
+ mode.algo = algo;
+
+ if (mode.name[0] == '\0')
+ bench_print_algo (-18, gcry_mac_algo_name (algo));
+ else
+ bench_print_algo (18, mode.name);
+
+ obj.ops = mode.ops;
+ obj.priv = &mode;
+
+ result = do_slope_benchmark (&obj);
+
+ bench_print_result (result);
+}
+
+static void
+_mac_bench (int algo)
+{
+ int i;
+
+ for (i = 0; mac_modes[i].name; i++)
+ mac_bench_one (algo, &mac_modes[i]);
+}
+
+void
+mac_bench (char **argv, int argc)
+{
+ int i, algo;
+
+ bench_print_section ("mac", "MAC");
+ bench_print_header (18, "");
+
+ if (argv && argc)
+ {
+ for (i = 0; i < argc; i++)
+ {
+ algo = gcry_mac_map_name (argv[i]);
+ if (algo)
+ _mac_bench (algo);
+ }
+ }
+ else
+ {
+ for (i = 1; i < 600; i++)
+ if (!gcry_mac_test_algo (i))
+ _mac_bench (i);
+ }
+
+ bench_print_footer (18);
+}
+
+
+/************************************************************ KDF benchmarks. */
+
+struct bench_kdf_mode
+{
+ struct bench_ops *ops;
+
+ int algo;
+ int subalgo;
+};
+
+
+static int
+bench_kdf_init (struct bench_obj *obj)
+{
+ struct bench_kdf_mode *mode = obj->priv;
+
+ if (mode->algo == GCRY_KDF_PBKDF2)
+ {
+ obj->min_bufsize = 2;
+ obj->max_bufsize = 2 * 32;
+ obj->step_size = 2;
+ }
+
+ obj->num_measure_repetitions = num_measurement_repetitions;
+
+ return 0;
+}
+
+static void
+bench_kdf_free (struct bench_obj *obj)
+{
+ (void)obj;
+}
+
+static void
+bench_kdf_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+ struct bench_kdf_mode *mode = obj->priv;
+ char keybuf[16];
+
+ (void)buf;
+
+ if (mode->algo == GCRY_KDF_PBKDF2)
+ {
+ gcry_kdf_derive("qwerty", 6, mode->algo, mode->subalgo, "01234567", 8,
+ buflen, sizeof(keybuf), keybuf);
+ }
+}
+
+static struct bench_ops kdf_ops = {
+ &bench_kdf_init,
+ &bench_kdf_free,
+ &bench_kdf_do_bench
+};
+
+
+static void
+kdf_bench_one (int algo, int subalgo)
+{
+ struct bench_kdf_mode mode = { &kdf_ops };
+ struct bench_obj obj = { 0 };
+ double nsecs_per_iteration;
+ double cycles_per_iteration;
+ char algo_name[32];
+ char nsecpiter_buf[16];
+ char cpiter_buf[16];
+ char mhz_buf[16];
+
+ mode.algo = algo;
+ mode.subalgo = subalgo;
+
+ switch (subalgo)
+ {
+ case GCRY_MD_CRC32:
+ case GCRY_MD_CRC32_RFC1510:
+ case GCRY_MD_CRC24_RFC2440:
+ case GCRY_MD_MD4:
+ /* Skip CRC32s. */
+ return;
+ }
+
+ if (gcry_md_get_algo_dlen (subalgo) == 0)
+ {
+ /* Skip XOFs */
+ return;
+ }
+
+ *algo_name = 0;
+
+ if (algo == GCRY_KDF_PBKDF2)
+ {
+ snprintf (algo_name, sizeof(algo_name), "PBKDF2-HMAC-%s",
+ gcry_md_algo_name (subalgo));
+ }
+
+ bench_print_algo (-24, algo_name);
+
+ obj.ops = mode.ops;
+ obj.priv = &mode;
+
+ nsecs_per_iteration = do_slope_benchmark (&obj);
+
+ strcpy(cpiter_buf, csv_mode ? "" : "-");
+ strcpy(mhz_buf, csv_mode ? "" : "-");
+
+ double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration);
+
+ /* If user didn't provide CPU speed, we cannot show cycles/iter results. */
+ if (bench_ghz > 0.0)
+ {
+ cycles_per_iteration = nsecs_per_iteration * bench_ghz;
+ double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration);
+ double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000);
+ }
+
+ if (csv_mode)
+ {
+ if (auto_ghz)
+ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n",
+ current_section_name,
+ current_algo_name ? current_algo_name : "",
+ current_mode_name ? current_mode_name : "",
+ nsecpiter_buf,
+ cpiter_buf,
+ mhz_buf);
+ else
+ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n",
+ current_section_name,
+ current_algo_name ? current_algo_name : "",
+ current_mode_name ? current_mode_name : "",
+ nsecpiter_buf,
+ cpiter_buf);
+ }
+ else
+ {
+ if (auto_ghz)
+ printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf);
+ else
+ printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf);
+ }
+}
+
+void
+kdf_bench (char **argv, int argc)
+{
+ char algo_name[32];
+ int i, j;
+
+ bench_print_section ("kdf", "KDF");
+
+ if (!csv_mode)
+ {
+ printf (" %-*s | ", 24, "");
+ if (auto_ghz)
+ printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz");
+ else
+ printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter");
+ }
+
+ if (argv && argc)
+ {
+ for (i = 0; i < argc; i++)
+ {
+ for (j = 1; j < 400; j++)
+ {
+ if (gcry_md_test_algo (j))
+ continue;
+
+ snprintf (algo_name, sizeof(algo_name), "PBKDF2-HMAC-%s",
+ gcry_md_algo_name (j));
+
+ if (!strcmp(argv[i], algo_name))
+ kdf_bench_one (GCRY_KDF_PBKDF2, j);
+ }
+ }
+ }
+ else
+ {
+ for (i = 1; i < 400; i++)
+ if (!gcry_md_test_algo (i))
+ kdf_bench_one (GCRY_KDF_PBKDF2, i);
+ }
+
+ bench_print_footer (24);
+}
+
+
+/************************************************************** Main program. */
+
+void
+print_help (void)
+{
+ static const char *help_lines[] = {
+ "usage: bench-slope [options] [hash|mac|cipher|kdf [algonames]]",
+ "",
+ " options:",
+ " --cpu-mhz <mhz> Set CPU speed for calculating cycles",
+ " per bytes results. Set as \"auto\"",
+ " for auto-detection of CPU speed.",
+ " --disable-hwf <features> Disable hardware acceleration feature(s)",
+ " for benchmarking.",
+ " --repetitions <n> Use N repetitions (default "
+ STR2(NUM_MEASUREMENT_REPETITIONS) ")",
+ " --unaligned Use unaligned input buffers.",
+ " --csv Use CSV output format",
+ NULL
+ };
+ const char **line;
+
+ for (line = help_lines; *line; line++)
+ fprintf (stdout, "%s\n", *line);
+}
+
+
+/* Warm up CPU. */
+static void
+warm_up_cpu (void)
+{
+ struct nsec_time start, end;
+
+ get_nsec_time (&start);
+ do
+ {
+ get_nsec_time (&end);
+ }
+ while (get_time_nsec_diff (&start, &end) < 1000.0 * 1000.0 * 1000.0);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+
+ if (argc)
+ {
+ argc--;
+ argv++;
+ }
+
+ /* We skip this test if we are running under the test suite (no args
+ and srcdir defined) and GCRYPT_NO_BENCHMARKS is set. */
+ if (!argc && getenv ("srcdir") && getenv ("GCRYPT_NO_BENCHMARKS"))
+ exit (77);
+
+ if (getenv ("GCRYPT_IN_REGRESSION_TEST"))
+ {
+ in_regression_test = 1;
+ num_measurement_repetitions = 2;
+ }
+ else
+ num_measurement_repetitions = NUM_MEASUREMENT_REPETITIONS;
+
+ while (argc && last_argc != argc)
+ {
+ last_argc = argc;
+
+ if (!strcmp (*argv, "--"))
+ {
+ argc--;
+ argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ print_help ();
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--;
+ argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--;
+ argv++;
+ }
+ else if (!strcmp (*argv, "--csv"))
+ {
+ csv_mode = 1;
+ argc--;
+ argv++;
+ }
+ else if (!strcmp (*argv, "--unaligned"))
+ {
+ unaligned_mode = 1;
+ 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++;
+ }
+ }
+ else if (!strcmp (*argv, "--cpu-mhz"))
+ {
+ argc--;
+ argv++;
+ if (argc)
+ {
+ if (!strcmp (*argv, "auto"))
+ {
+ auto_ghz = 1;
+ }
+ else
+ {
+ cpu_ghz = atof (*argv);
+ cpu_ghz /= 1000; /* Mhz => Ghz */
+ }
+
+ argc--;
+ argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--repetitions"))
+ {
+ argc--;
+ argv++;
+ if (argc)
+ {
+ num_measurement_repetitions = atof (*argv);
+ if (num_measurement_repetitions < 2)
+ {
+ fprintf (stderr,
+ PGM
+ ": value for --repetitions too small - using %d\n",
+ NUM_MEASUREMENT_REPETITIONS);
+ num_measurement_repetitions = NUM_MEASUREMENT_REPETITIONS;
+ }
+ argc--;
+ argv++;
+ }
+ }
+ }
+
+ xgcry_control ((GCRYCTL_SET_VERBOSITY, (int) verbose));
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fprintf (stderr, PGM ": version mismatch; pgm=%s, library=%s\n",
+ GCRYPT_VERSION, gcry_check_version (NULL));
+ exit (1);
+ }
+
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+
+ if (in_regression_test)
+ fputs ("Note: " PGM " running in quick regression test mode.\n", stdout);
+
+ if (!argc)
+ {
+ warm_up_cpu ();
+ hash_bench (NULL, 0);
+ mac_bench (NULL, 0);
+ cipher_bench (NULL, 0);
+ kdf_bench (NULL, 0);
+ }
+ else if (!strcmp (*argv, "hash"))
+ {
+ argc--;
+ argv++;
+
+ warm_up_cpu ();
+ hash_bench ((argc == 0) ? NULL : argv, argc);
+ }
+ else if (!strcmp (*argv, "mac"))
+ {
+ argc--;
+ argv++;
+
+ warm_up_cpu ();
+ mac_bench ((argc == 0) ? NULL : argv, argc);
+ }
+ else if (!strcmp (*argv, "cipher"))
+ {
+ argc--;
+ argv++;
+
+ warm_up_cpu ();
+ cipher_bench ((argc == 0) ? NULL : argv, argc);
+ }
+ else if (!strcmp (*argv, "kdf"))
+ {
+ argc--;
+ argv++;
+
+ warm_up_cpu ();
+ kdf_bench ((argc == 0) ? NULL : argv, argc);
+ }
+ else
+ {
+ fprintf (stderr, PGM ": unknown argument: %s\n", *argv);
+ print_help ();
+ }
+
+ return 0;
+}
+
+#endif /* !NO_GET_NSEC_TIME */
diff --git a/comm/third_party/libgcrypt/tests/benchmark.c b/comm/third_party/libgcrypt/tests/benchmark.c
new file mode 100644
index 0000000000..5963527e1d
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/benchmark.c
@@ -0,0 +1,2037 @@
+/* benchmark.c - for libgcrypt
+ * Copyright (C) 2002, 2004, 2005, 2006, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt-int.h"
+# include "../compat/libcompat.h"
+#else
+# include <gcrypt.h>
+#endif
+
+#include "stopwatch.h"
+
+
+#define PGM "benchmark"
+#include "t-common.h"
+
+/* Do encryption tests with large buffers (100 KiB). */
+static int large_buffers;
+
+/* Do encryption tests with huge buffers (256 MiB). */
+static int huge_buffers;
+
+/* Number of cipher repetitions. */
+static int cipher_repetitions;
+
+/* Number of hash repetitions. */
+static int hash_repetitions;
+
+/* Number of hash repetitions. */
+static int mac_repetitions;
+
+/* Alignment of the buffers. */
+static int buffer_alignment;
+
+/* Whether to include the keysetup in the cipher timings. */
+static int cipher_with_keysetup;
+
+/* Whether fips mode was active at startup. */
+static int in_fips_mode;
+
+/* Whether we are running as part of the regression test suite. */
+static int in_regression_test;
+
+/* Whether --progress is in use. */
+static int with_progress;
+
+/* Runtime flag to switch to a different progress output. */
+static int single_char_progress;
+
+
+static const char sample_private_dsa_key_1024[] =
+"(private-key\n"
+" (dsa\n"
+" (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
+ "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
+ "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
+ "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
+" (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
+" (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
+ "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
+ "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
+ "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
+" (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
+ "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
+ "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
+ "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
+" (x #4186F8A58C5DF46C5BCFC7006BEEBF05E93C0CA7#)\n"
+"))\n";
+
+static const char sample_public_dsa_key_1024[] =
+"(public-key\n"
+" (dsa\n"
+" (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
+ "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
+ "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
+ "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
+" (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
+" (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
+ "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
+ "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
+ "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
+" (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
+ "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
+ "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
+ "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
+"))\n";
+
+
+static const char sample_private_dsa_key_2048[] =
+"(private-key\n"
+" (dsa\n"
+" (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
+ "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
+ "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
+ "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
+ "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
+ "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
+ "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
+ "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
+" (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
+" (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
+ "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
+ "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
+ "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
+ "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
+ "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
+ "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
+ "6EE4425A553AF8885FEA15A88135BE133520#)\n"
+" (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
+ "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
+ "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
+ "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
+ "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
+ "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
+ "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
+ "14A264330AECCB24DE2A1107847B23490897#)\n"
+" (x #477BD14676E22563C5ABA68025CEBA2A48D485F5B2D4AD4C0EBBD6D0#)\n"
+"))\n";
+
+
+static const char sample_public_dsa_key_2048[] =
+"(public-key\n"
+" (dsa\n"
+" (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
+ "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
+ "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
+ "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
+ "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
+ "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
+ "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
+ "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
+" (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
+" (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
+ "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
+ "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
+ "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
+ "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
+ "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
+ "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
+ "6EE4425A553AF8885FEA15A88135BE133520#)\n"
+" (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
+ "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
+ "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
+ "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
+ "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
+ "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
+ "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
+ "14A264330AECCB24DE2A1107847B23490897#)\n"
+"))\n";
+
+
+static const char sample_private_dsa_key_3072[] =
+"(private-key\n"
+" (dsa\n"
+" (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
+ "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
+ "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
+ "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
+ "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
+ "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
+ "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
+ "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
+ "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
+ "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
+ "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
+ "8015353D3778B02B892AF7#)\n"
+" (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
+" (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
+ "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
+ "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
+ "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
+ "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
+ "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
+ "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
+ "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
+ "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
+ "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
+ "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
+ "4997AF9EB55C6660B01A#)\n"
+" (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
+ "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
+ "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
+ "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
+ "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
+ "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
+ "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
+ "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
+ "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
+ "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
+ "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
+ "2703D518D8D49FF0EBE6#)\n"
+" (x #00A9FFFC88E67D6F7B810E291C050BAFEA7FC4A75E8D2F16CFED3416FD77607232#)\n"
+"))\n";
+
+static const char sample_public_dsa_key_3072[] =
+"(public-key\n"
+" (dsa\n"
+" (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
+ "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
+ "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
+ "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
+ "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
+ "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
+ "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
+ "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
+ "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
+ "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
+ "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
+ "8015353D3778B02B892AF7#)\n"
+" (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
+" (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
+ "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
+ "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
+ "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
+ "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
+ "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
+ "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
+ "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
+ "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
+ "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
+ "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
+ "4997AF9EB55C6660B01A#)\n"
+" (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
+ "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
+ "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
+ "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
+ "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
+ "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
+ "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
+ "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
+ "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
+ "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
+ "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
+ "2703D518D8D49FF0EBE6#)\n"
+"))\n";
+
+
+static const char sample_public_elg_key_1024[] =
+"(public-key"
+" (elg"
+" (p #00F7CC7C08AF096B620C545C9353B1140D698FF8BE2D97A3515C17C7F8DABCDB8FB6"
+ "64A46416C90C530C18DF5ABB6C1DDE3AE2FA9DDC9CE40DF644CDE2E759F6DE43F31A"
+ "EEEBC136A460B3E4B0A8F99326A335145B19F4C81B13804894B7D2A30F78A8A7D7F4"
+ "52B83836FDB0DE90BE327FB5E5318757BEF5FE0FC3A5461CBEA0D3#)"
+" (g #06#)"
+" (y #36B38FB63E3340A0DD8A0468E9FAA512A32DA010BF7110201D0A3DF1B8FEA0E16F3C"
+ "80374584E554804B96EAA8C270FE531F75D0DBD81BA65640EDB1F76D46C27D2925B7"
+ "3EC3B295CDAEEF242904A84D74FB2879425F82D4C5B59BB49A992F85D574168DED85"
+ "D227600BBEF7AF0B8F0DEB785528370E4C4B3E4D65C536122A5A#)"
+" ))";
+static const char sample_private_elg_key_1024[] =
+"(private-key"
+" (elg"
+" (p #00F7CC7C08AF096B620C545C9353B1140D698FF8BE2D97A3515C17C7F8DABCDB8FB6"
+ "64A46416C90C530C18DF5ABB6C1DDE3AE2FA9DDC9CE40DF644CDE2E759F6DE43F31A"
+ "EEEBC136A460B3E4B0A8F99326A335145B19F4C81B13804894B7D2A30F78A8A7D7F4"
+ "52B83836FDB0DE90BE327FB5E5318757BEF5FE0FC3A5461CBEA0D3#)"
+" (g #06#)"
+" (y #36B38FB63E3340A0DD8A0468E9FAA512A32DA010BF7110201D0A3DF1B8FEA0E16F3C"
+ "80374584E554804B96EAA8C270FE531F75D0DBD81BA65640EDB1F76D46C27D2925B7"
+ "3EC3B295CDAEEF242904A84D74FB2879425F82D4C5B59BB49A992F85D574168DED85"
+ "D227600BBEF7AF0B8F0DEB785528370E4C4B3E4D65C536122A5A#)"
+" (x #03656C6186FCD27D4A4B1F5010DC0D2AE7833B501E423FCD51DE5EB6D80DACFE#)"
+" ))";
+
+
+static const char sample_public_elg_key_2048[] =
+"(public-key"
+" (elg"
+" (p #00BE5A2BB4E562D7B644E3D01321CB818DBA27295C339FC2C47EAE9823225EE1E7B6"
+ "38C5DE300E931080E09CC89A18C9D180C16559FEF0D89D6A09534BB86489CCCEE30D"
+ "C18E007A8726BB99F2B2D90D2694597757B120CD2435C0098AD1B74C20004C25BA97"
+ "73EAA4FBEC594EE17F8B25867EEB0F9F857C751116ADED68ADA2A1E9F9F4F40D18F0"
+ "EC1221CA6A746FC5F4CDA2B8B5D0AB83834564ACF6FDBB1AB01D4BFBD1E2C0108FF5"
+ "5FB3190C6D6DA4D95EA683EFA44935CFBC0BF5C6118ACC3768AEA9A98D06024841B8"
+ "D07C234289D22A5E3948F199C397AA991C59A55BEA0C01E91902E039116946FEA135"
+ "768011AF6B622C5AF366EF0196FC4EAEAA8127#)"
+" (g #07#)"
+" (y #5AFF87BC23D8B97AA62897A5C1CDFFA86C59F39EDBD6012B6F333CE23D872009B8C8"
+ "D1E220E18CFCADFE0AA16346BA2EA132472FFEC746D11C6E758896052313BB501210"
+ "2389C683A25A3464E9B35A192BAE0A3BB99C973126F7560D968C4A754901DC967354"
+ "D61A90ACD56D90DCC4337AFB71FAE3FD18C60EB0D6DD173877DF5DB5199C4931FE4E"
+ "5046F814422580E1162798406FC6554781142DBB7922D4B5B37A111F23761636090F"
+ "6212681E133365191CF15753AE737F17943ED4B7506DE0A85C3B6D63227F9D65ADF8"
+ "2C3DF0676C8F43B5B1C07D9AD4E6D0C812401D7DA7B9484DBA8CD3B73B19A95EB237"
+ "D493E092AEA2371AA904009C8960B0969D12#)"
+" ))";
+static const char sample_private_elg_key_2048[] =
+"(private-key"
+" (elg"
+" (p #00BE5A2BB4E562D7B644E3D01321CB818DBA27295C339FC2C47EAE9823225EE1E7B6"
+ "38C5DE300E931080E09CC89A18C9D180C16559FEF0D89D6A09534BB86489CCCEE30D"
+ "C18E007A8726BB99F2B2D90D2694597757B120CD2435C0098AD1B74C20004C25BA97"
+ "73EAA4FBEC594EE17F8B25867EEB0F9F857C751116ADED68ADA2A1E9F9F4F40D18F0"
+ "EC1221CA6A746FC5F4CDA2B8B5D0AB83834564ACF6FDBB1AB01D4BFBD1E2C0108FF5"
+ "5FB3190C6D6DA4D95EA683EFA44935CFBC0BF5C6118ACC3768AEA9A98D06024841B8"
+ "D07C234289D22A5E3948F199C397AA991C59A55BEA0C01E91902E039116946FEA135"
+ "768011AF6B622C5AF366EF0196FC4EAEAA8127#)"
+" (g #07#)"
+" (y #5AFF87BC23D8B97AA62897A5C1CDFFA86C59F39EDBD6012B6F333CE23D872009B8C8"
+ "D1E220E18CFCADFE0AA16346BA2EA132472FFEC746D11C6E758896052313BB501210"
+ "2389C683A25A3464E9B35A192BAE0A3BB99C973126F7560D968C4A754901DC967354"
+ "D61A90ACD56D90DCC4337AFB71FAE3FD18C60EB0D6DD173877DF5DB5199C4931FE4E"
+ "5046F814422580E1162798406FC6554781142DBB7922D4B5B37A111F23761636090F"
+ "6212681E133365191CF15753AE737F17943ED4B7506DE0A85C3B6D63227F9D65ADF8"
+ "2C3DF0676C8F43B5B1C07D9AD4E6D0C812401D7DA7B9484DBA8CD3B73B19A95EB237"
+ "D493E092AEA2371AA904009C8960B0969D12#)"
+" (x #0628C3903972C55BDC1BC4223075616D3F3BA57D55532DDB40CB14CF72070E0D28BF"
+ "D0402B9088D25ED8FC#)"
+" ))";
+
+static const char sample_public_elg_key_3072[] =
+"(public-key"
+" (elg"
+" (p #008EAA3497AFE3706E1A57FFA52E68C64C500731B58EBAFEB51C4A20AB15BA57FA72"
+ "BA1510A4703D5AA6F05DB67E4A776F92AD08800577DC686D00B793167A5D79C997E0"
+ "5B9A9E5974B4B68B4D71ED8EC37F2F45235D901997D72915643F058E712AA18275A2"
+ "C6F9F7C2B9B7CD1E814D215F12A840800B546AEF2A2E6C077CDD1A322738FFD36DB2"
+ "FA5420B5848EED870BC1A6CF55040AE8D2A5945F11AE2BCBE107B41A59EFDBD3B05C"
+ "F4C876C02C9AEAE22CD4C86806A415302936E4C1E5AA59DBBCCD2F83C20941A29888"
+ "A70ADB94D3B8A6489C46BF2C5219CD9FD2341EA21D4E68A4ECC468FD09D215FE96D4"
+ "7AEA12FD22B2456D2CC13672FC7E9772A365C68668157C51E46966B6A1831C429BA0"
+ "D513519713C49C13C5FC7C14BE0A117627B204C4478D0A93C6B57929E448C9B65BF2"
+ "390E04BC5940320C0262FC1A221E7C796493432239A6F12BC62C5CF32E8ADBC1730C"
+ "84C6E6E6BD95AF62835941F3F344AF46BFE5A8F629D5FA699FE37EF8B8C6A2484E42"
+ "D226206FDF7D1FB93A5457#)"
+" (g #0B#)"
+" (y #18E734FF645AE169079AEAFC78772371089AD3088627ECF77034AFBDF33ADF594AAF"
+ "3288F6979E0DB59CE3D2F0FEE031DFF187F1E4549D3C79668794CB19C14481ECDE2D"
+ "D50861AB674F87A011D50D35F28E424D0D2353850899C2CDD0CC8FDBFC5A0CA395F0"
+ "E605D46CBDD140DBEF426EBD638C9ADD83C195C45CE84ED2D2B21B87800C783A4F79"
+ "12226FEFBDA01C66B254534A51765AF09687275AA80C5DFBA143A6262E47C547D7E2"
+ "289413F8C5C56AED3FA7E5DF5526958E2294FE318AF590C0E720029C202563E6E686"
+ "9EC810F39A859262FB6047C1D418CAA9047A00BDB127B44B69CF6BC8E6B3709B4C23"
+ "79783C5F8457EFE23EDA6FF00D1DDCC29268FC4A6C18577BE2B7004089CBB824027A"
+ "A53C86B51DB054CC83B4F50C8923E2E9431F0A77D741237226CC68591083A2E40171"
+ "5C7B74100BB74003E2264F8B44A0B0BC5404C44218ABE65C04AA573877506CE4F48C"
+ "9E3F8AD1CD8DD9F285DD015C2FC5DEBCFA5779AD87F0BBC62E9EC6246021AB450DB9"
+ "4DDDEFAFD2C7C66E235D#)"
+" ))";
+static const char sample_private_elg_key_3072[] =
+"(private-key"
+" (elg"
+" (p #008EAA3497AFE3706E1A57FFA52E68C64C500731B58EBAFEB51C4A20AB15BA57FA72"
+ "BA1510A4703D5AA6F05DB67E4A776F92AD08800577DC686D00B793167A5D79C997E0"
+ "5B9A9E5974B4B68B4D71ED8EC37F2F45235D901997D72915643F058E712AA18275A2"
+ "C6F9F7C2B9B7CD1E814D215F12A840800B546AEF2A2E6C077CDD1A322738FFD36DB2"
+ "FA5420B5848EED870BC1A6CF55040AE8D2A5945F11AE2BCBE107B41A59EFDBD3B05C"
+ "F4C876C02C9AEAE22CD4C86806A415302936E4C1E5AA59DBBCCD2F83C20941A29888"
+ "A70ADB94D3B8A6489C46BF2C5219CD9FD2341EA21D4E68A4ECC468FD09D215FE96D4"
+ "7AEA12FD22B2456D2CC13672FC7E9772A365C68668157C51E46966B6A1831C429BA0"
+ "D513519713C49C13C5FC7C14BE0A117627B204C4478D0A93C6B57929E448C9B65BF2"
+ "390E04BC5940320C0262FC1A221E7C796493432239A6F12BC62C5CF32E8ADBC1730C"
+ "84C6E6E6BD95AF62835941F3F344AF46BFE5A8F629D5FA699FE37EF8B8C6A2484E42"
+ "D226206FDF7D1FB93A5457#)"
+" (g #0B#)"
+" (y #18E734FF645AE169079AEAFC78772371089AD3088627ECF77034AFBDF33ADF594AAF"
+ "3288F6979E0DB59CE3D2F0FEE031DFF187F1E4549D3C79668794CB19C14481ECDE2D"
+ "D50861AB674F87A011D50D35F28E424D0D2353850899C2CDD0CC8FDBFC5A0CA395F0"
+ "E605D46CBDD140DBEF426EBD638C9ADD83C195C45CE84ED2D2B21B87800C783A4F79"
+ "12226FEFBDA01C66B254534A51765AF09687275AA80C5DFBA143A6262E47C547D7E2"
+ "289413F8C5C56AED3FA7E5DF5526958E2294FE318AF590C0E720029C202563E6E686"
+ "9EC810F39A859262FB6047C1D418CAA9047A00BDB127B44B69CF6BC8E6B3709B4C23"
+ "79783C5F8457EFE23EDA6FF00D1DDCC29268FC4A6C18577BE2B7004089CBB824027A"
+ "A53C86B51DB054CC83B4F50C8923E2E9431F0A77D741237226CC68591083A2E40171"
+ "5C7B74100BB74003E2264F8B44A0B0BC5404C44218ABE65C04AA573877506CE4F48C"
+ "9E3F8AD1CD8DD9F285DD015C2FC5DEBCFA5779AD87F0BBC62E9EC6246021AB450DB9"
+ "4DDDEFAFD2C7C66E235D#)"
+" (x #03A73F0389E470AAC831B039F8AA0C4EBD3A47DD083E32EEA08E4911236CD597C272"
+ "9823D47A51C8535DA52FE6DAB3E8D1C20D#)"
+" ))";
+
+
+#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
+ exit(2);} while(0)
+
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = malloc (size);
+ if (!buf)
+ die ("out of core\n");
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+}
+
+
+static void
+progress_cb (void *cb_data, const char *what, int printchar,
+ int current, int total)
+{
+ (void)cb_data;
+
+ if (single_char_progress)
+ {
+ fputc (printchar, stdout);
+ fflush (stderr);
+ }
+ else
+ {
+ fprintf (stderr, PGM ": progress (%s %c %d %d)\n",
+ what, printchar, current, total);
+ fflush (stderr);
+ }
+}
+
+
+static void
+random_bench (int very_strong)
+{
+ char buf[128];
+ int i;
+
+ printf ("%-10s", "random");
+
+ if (!very_strong)
+ {
+ start_timer ();
+ for (i=0; i < 100; i++)
+ gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ }
+
+ start_timer ();
+ for (i=0; i < 100; i++)
+ gcry_randomize (buf, 8,
+ very_strong? GCRY_VERY_STRONG_RANDOM:GCRY_STRONG_RANDOM);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+
+ putchar ('\n');
+ if (verbose)
+ xgcry_control ((GCRYCTL_DUMP_RANDOM_STATS));
+}
+
+
+
+static void
+md_bench ( const char *algoname )
+{
+ int algo;
+ gcry_md_hd_t hd;
+ int i, j, repcount;
+ char buf_base[1000+15];
+ size_t bufsize = 1000;
+ char *buf;
+ char *largebuf_base;
+ char *largebuf;
+ char digest[512/8];
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+
+ if (!algoname)
+ {
+ for (i=1; i < 400; i++)
+ if (in_fips_mode && i == GCRY_MD_MD5)
+ ; /* Don't use MD5 in fips mode. */
+ else if ( !gcry_md_test_algo (i) )
+ md_bench (gcry_md_algo_name (i));
+ return;
+ }
+
+ buf = buf_base + ((16 - ((size_t)buf_base & 0x0f)) % buffer_alignment);
+
+ algo = gcry_md_map_name (algoname);
+ if (!algo)
+ {
+ fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
+ exit (1);
+ }
+
+ err = gcry_md_open (&hd, algo, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname);
+ exit (1);
+ }
+
+ for (i=0; i < bufsize; i++)
+ buf[i] = i;
+
+ printf ("%-12s", gcry_md_algo_name (algo));
+
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 1000; i++)
+ gcry_md_write (hd, buf, bufsize);
+ gcry_md_final (hd);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ gcry_md_reset (hd);
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 10000; i++)
+ gcry_md_write (hd, buf, bufsize/10);
+ gcry_md_final (hd);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ gcry_md_reset (hd);
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 1000000; i++)
+ gcry_md_write (hd, buf, 1);
+ gcry_md_final (hd);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 1000; i++)
+ for (j=0; j < bufsize; j++)
+ gcry_md_putc (hd, buf[j]);
+ gcry_md_final (hd);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ gcry_md_close (hd);
+
+ /* Now 100 hash operations on 10000 bytes using the fast function.
+ We initialize the buffer so that all memory pages are committed
+ and we have repeatable values. */
+ if (gcry_md_get_algo_dlen (algo) > sizeof digest)
+ die ("digest buffer too short\n");
+
+ if (gcry_md_get_algo_dlen (algo))
+ {
+ largebuf_base = malloc (10000+15);
+ if (!largebuf_base)
+ die ("out of core\n");
+ largebuf = (largebuf_base
+ + ((16 - ((size_t)largebuf_base & 0x0f)) % buffer_alignment));
+
+ for (i=0; i < 10000; i++)
+ largebuf[i] = i;
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 100; i++)
+ gcry_md_hash_buffer (algo, digest, largebuf, 10000);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ free (largebuf_base);
+ }
+
+ putchar ('\n');
+ fflush (stdout);
+}
+
+
+
+static void
+mac_bench ( const char *algoname )
+{
+ int algo;
+ gcry_mac_hd_t hd;
+ int step, pos, j, i, repcount;
+ char buf_base[1000+15];
+ size_t bufsize = 1000;
+ char *buf;
+ char mac[3][512];
+ char key[512];
+ unsigned int maclen, keylen;
+ size_t macoutlen;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+
+ if (!algoname)
+ {
+ for (i=1; i < 600; i++)
+ if (in_fips_mode && i == GCRY_MAC_HMAC_MD5)
+ ; /* Don't use MD5 in fips mode. */
+ else if ( !gcry_mac_test_algo (i) )
+ mac_bench (gcry_mac_algo_name (i));
+ return;
+ }
+
+ buf = buf_base + ((16 - ((size_t)buf_base & 0x0f)) % buffer_alignment);
+
+ algo = gcry_mac_map_name (algoname);
+ if (!algo)
+ {
+ fprintf (stderr, PGM ": invalid MAC algorithm `%s'\n", algoname);
+ exit (1);
+ }
+
+ maclen = gcry_mac_get_algo_maclen (algo);
+ if (maclen > sizeof(mac))
+ maclen = sizeof(mac);
+
+ keylen = gcry_mac_get_algo_keylen (algo);
+ if (keylen == 0)
+ keylen = 32;
+ if (keylen > sizeof(key))
+ keylen = sizeof(key);
+ for (i=0; i < keylen; i++)
+ key[i] = (keylen - i) ^ 0x54;
+
+ err = gcry_mac_open (&hd, algo, 0, NULL);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening mac algorithm `%s': %s\n", algoname,
+ gpg_strerror (err));
+ exit (1);
+ }
+
+ err = gcry_mac_setkey (hd, key, keylen);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error setting key for mac algorithm `%s': %s\n",
+ algoname, gpg_strerror (err));
+ exit (1);
+ }
+
+ for (i=0; i < bufsize; i++)
+ buf[i] = i;
+
+ if (algo >= GCRY_MAC_POLY1305_AES && algo <= GCRY_MAC_POLY1305_SEED)
+ {
+ static const char iv[16] = { 1, 2, 3, 4, };
+ err = gcry_mac_setiv(hd, iv, sizeof(iv));
+ if (err)
+ {
+ fprintf (stderr, PGM ": error setting nonce for mac algorithm `%s': %s\n",
+ algoname, gpg_strerror (err));
+ exit (1);
+ }
+ }
+
+ printf ("%-20s", gcry_mac_algo_name (algo));
+
+ start_timer ();
+ for (repcount=0; repcount < mac_repetitions; repcount++)
+ for (i=0; i < 1000; i++)
+ gcry_mac_write (hd, buf, bufsize);
+ macoutlen = maclen;
+ gcry_mac_read (hd, mac[0], &macoutlen);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ gcry_mac_reset (hd);
+ start_timer ();
+ for (repcount=0; repcount < mac_repetitions; repcount++)
+ for (i=0; i < 1000; i++)
+ for (step=bufsize/10, pos=0, j=0; j < 10; j++, pos+=step)
+ gcry_mac_write (hd, &buf[pos], step);
+ macoutlen = maclen;
+ gcry_mac_read (hd, mac[1], &macoutlen);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ gcry_mac_reset (hd);
+ start_timer ();
+ for (repcount=0; repcount < mac_repetitions; repcount++)
+ for (i=0; i < 1000; i++)
+ for (step=bufsize/100, pos=0, j=0; j < 100; j++, pos+=step)
+ gcry_mac_write (hd, &buf[pos], step);
+ macoutlen = maclen;
+ gcry_mac_read (hd, mac[2], &macoutlen);
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ gcry_mac_close (hd);
+
+ for (i=1; i < 3; i++)
+ {
+ if (memcmp(mac[i-1], mac[i], maclen))
+ {
+ fprintf (stderr, PGM ": mac mismatch with algorithm `%s'\n",
+ algoname);
+ exit(1);
+ }
+ }
+
+ putchar ('\n');
+ fflush (stdout);
+}
+
+
+static void ccm_aead_init(gcry_cipher_hd_t hd, size_t buflen, int authlen)
+{
+ const int _L = 4;
+ const int noncelen = 15 - _L;
+ char nonce[noncelen];
+ u64 params[3];
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+
+ memset (nonce, 0x33, noncelen);
+
+ err = gcry_cipher_setiv (hd, nonce, noncelen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+
+ params[0] = buflen; /* encryptedlen */
+ params[1] = 0; /* aadlen */
+ params[2] = authlen; /* authtaglen */
+ err = gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof(params));
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+}
+
+
+static gcry_error_t
+cipher_encrypt (gcry_cipher_hd_t h, char *out, size_t outsize,
+ const char *in, size_t inlen, size_t max_inlen)
+{
+ gcry_error_t ret;
+
+ while (inlen)
+ {
+ size_t currlen = inlen;
+
+ if (currlen > max_inlen)
+ currlen = max_inlen;
+
+ ret = gcry_cipher_encrypt(h, out, outsize, in, currlen);
+ if (ret)
+ return ret;
+
+ out += currlen;
+ in += currlen;
+ outsize -= currlen;
+ inlen -= currlen;
+ }
+
+ return 0;
+}
+
+
+static gcry_error_t
+cipher_decrypt (gcry_cipher_hd_t h, char *out, size_t outsize,
+ const char *in, size_t inlen, size_t max_inlen)
+{
+ gcry_error_t ret;
+
+ while (inlen)
+ {
+ size_t currlen = inlen;
+
+ if (currlen > max_inlen)
+ currlen = max_inlen;
+
+ ret = gcry_cipher_decrypt(h, out, outsize, in, currlen);
+ if (ret)
+ return ret;
+
+ out += currlen;
+ in += currlen;
+ outsize -= currlen;
+ inlen -= currlen;
+ }
+
+ return 0;
+}
+
+
+static void
+cipher_bench ( const char *algoname )
+{
+ static int header_printed;
+ int algo;
+ gcry_cipher_hd_t hd;
+ int i;
+ int keylen, blklen;
+ char key[128];
+ char *outbuf, *buf;
+ char *raw_outbuf, *raw_buf;
+ size_t allocated_buflen, buflen;
+ int repetitions;
+ static const struct {
+ int mode;
+ const char *name;
+ int blocked;
+ unsigned int max_inlen;
+ void (* const aead_init)(gcry_cipher_hd_t hd, size_t buflen, int authlen);
+ int req_blocksize;
+ int authlen;
+ int noncelen;
+ int doublekey;
+ } modes[] = {
+ { GCRY_CIPHER_MODE_ECB, " ECB/Stream", 1, 0xffffffffU },
+ { GCRY_CIPHER_MODE_CBC, " CBC/Poly1305", 1, 0xffffffffU },
+ { GCRY_CIPHER_MODE_CFB, " CFB", 0, 0xffffffffU },
+ { GCRY_CIPHER_MODE_OFB, " OFB", 0, 0xffffffffU },
+ { GCRY_CIPHER_MODE_CTR, " CTR", 0, 0xffffffffU },
+ { GCRY_CIPHER_MODE_XTS, " XTS", 0, 16 << 20,
+ NULL, GCRY_XTS_BLOCK_LEN, 0, 0, 1 },
+ { GCRY_CIPHER_MODE_CCM, " CCM", 0, 0xffffffffU,
+ ccm_aead_init, GCRY_CCM_BLOCK_LEN, 8, },
+ { GCRY_CIPHER_MODE_GCM, " GCM", 0, 0xffffffffU,
+ NULL, GCRY_GCM_BLOCK_LEN, GCRY_GCM_BLOCK_LEN },
+ { GCRY_CIPHER_MODE_OCB, " OCB", 1, 0xffffffffU,
+ NULL, 16, 16, 15 },
+ { GCRY_CIPHER_MODE_EAX, " EAX", 0, 0xffffffffU,
+ NULL, 0, 8, 8 },
+ { GCRY_CIPHER_MODE_STREAM, "", 0, 0xffffffffU },
+ { GCRY_CIPHER_MODE_POLY1305, "", 0, 0xffffffffU,
+ NULL, 1, 16, 12 },
+ {0}
+ };
+ int modeidx;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+
+ if (!algoname)
+ {
+ for (i=1; i < 400; i++)
+ if ( !gcry_cipher_test_algo (i) )
+ cipher_bench (gcry_cipher_algo_name (i));
+ return;
+ }
+
+ if (huge_buffers)
+ {
+ allocated_buflen = 256 * 1024 * 1024;
+ repetitions = 4;
+ }
+ else if (large_buffers)
+ {
+ allocated_buflen = 1024 * 100;
+ repetitions = 10;
+ }
+ else
+ {
+ allocated_buflen = 1024;
+ repetitions = 1000;
+ }
+ repetitions *= cipher_repetitions;
+
+ raw_buf = gcry_xcalloc (allocated_buflen+15, 1);
+ buf = (raw_buf
+ + ((16 - ((size_t)raw_buf & 0x0f)) % buffer_alignment));
+ outbuf = raw_outbuf = gcry_xmalloc (allocated_buflen+15);
+ outbuf = (raw_outbuf
+ + ((16 - ((size_t)raw_outbuf & 0x0f)) % buffer_alignment));
+
+ if (!header_printed)
+ {
+ if (cipher_repetitions != 1)
+ printf ("Running each test %d times.\n", cipher_repetitions);
+ printf ("%-12s", "");
+ for (modeidx=0; modes[modeidx].mode; modeidx++)
+ if (*modes[modeidx].name)
+ printf (" %-15s", modes[modeidx].name );
+ putchar ('\n');
+ printf ("%-12s", "");
+ for (modeidx=0; modes[modeidx].mode; modeidx++)
+ if (*modes[modeidx].name)
+ printf (" ---------------" );
+ putchar ('\n');
+ header_printed = 1;
+ }
+
+ algo = gcry_cipher_map_name (algoname);
+ if (!algo)
+ {
+ fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname);
+ exit (1);
+ }
+
+ keylen = gcry_cipher_get_algo_keylen (algo);
+ if (!keylen)
+ {
+ fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
+ algoname);
+ exit (1);
+ }
+ if ( keylen * 2 > sizeof key )
+ {
+ fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n",
+ algo, keylen );
+ exit (1);
+ }
+ for (i=0; i < keylen * 2; i++)
+ key[i] = i + (clock () & 0xff);
+
+ blklen = gcry_cipher_get_algo_blklen (algo);
+ if (!blklen)
+ {
+ fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n",
+ algoname);
+ exit (1);
+ }
+
+ printf ("%-12s", gcry_cipher_algo_name (algo));
+ fflush (stdout);
+
+ for (modeidx=0; modes[modeidx].mode; modeidx++)
+ {
+ size_t modekeylen = keylen * (!!modes[modeidx].doublekey + 1);
+ int is_stream = modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM
+ || modes[modeidx].mode == GCRY_CIPHER_MODE_POLY1305;
+
+ if ((blklen > 1 && is_stream) || (blklen == 1 && !is_stream))
+ continue;
+
+ if (modes[modeidx].mode == GCRY_CIPHER_MODE_POLY1305
+ && algo != GCRY_CIPHER_CHACHA20)
+ continue;
+
+ if (modes[modeidx].req_blocksize > 0
+ && blklen != modes[modeidx].req_blocksize)
+ {
+ printf (" %7s %7s", "-", "-" );
+ continue;
+ }
+
+ for (i=0; i < sizeof buf; i++)
+ buf[i] = i;
+
+ err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname);
+ exit (1);
+ }
+
+ if (!cipher_with_keysetup)
+ {
+ err = gcry_cipher_setkey (hd, key, modekeylen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
+ buflen = allocated_buflen;
+ if (modes[modeidx].blocked)
+ buflen = (buflen / blklen) * blklen;
+
+ start_timer ();
+ for (i=err=0; !err && i < repetitions; i++)
+ {
+ if (cipher_with_keysetup)
+ {
+ err = gcry_cipher_setkey (hd, key, modekeylen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
+ if (modes[modeidx].noncelen)
+ {
+ char nonce[100];
+ size_t noncelen;
+
+ noncelen = modes[modeidx].noncelen;
+ if (noncelen > sizeof nonce)
+ noncelen = sizeof nonce;
+ memset (nonce, 42, noncelen);
+ err = gcry_cipher_setiv (hd, nonce, noncelen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
+ if (modes[modeidx].aead_init)
+ {
+ (*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
+ gcry_cipher_final (hd);
+ err = cipher_encrypt (hd, outbuf, buflen, buf, buflen,
+ modes[modeidx].max_inlen);
+ if (err)
+ break;
+ err = gcry_cipher_gettag (hd, outbuf, modes[modeidx].authlen);
+ }
+ else
+ {
+ err = cipher_encrypt (hd, outbuf, buflen, buf, buflen,
+ modes[modeidx].max_inlen);
+ }
+ }
+ stop_timer ();
+
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+ gcry_cipher_close (hd);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err) );
+ exit (1);
+ }
+
+ err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname);
+ exit (1);
+ }
+
+ if (!cipher_with_keysetup)
+ {
+ err = gcry_cipher_setkey (hd, key, modekeylen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
+ start_timer ();
+ for (i=err=0; !err && i < repetitions; i++)
+ {
+ if (cipher_with_keysetup)
+ {
+ err = gcry_cipher_setkey (hd, key, modekeylen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
+ if (modes[modeidx].noncelen)
+ {
+ char nonce[100];
+ size_t noncelen;
+
+ noncelen = modes[modeidx].noncelen;
+ if (noncelen > sizeof nonce)
+ noncelen = sizeof nonce;
+ memset (nonce, 42, noncelen);
+ err = gcry_cipher_setiv (hd, nonce, noncelen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
+ if (modes[modeidx].aead_init)
+ {
+ (*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
+ gcry_cipher_final (hd);
+ err = cipher_decrypt (hd, outbuf, buflen, buf, buflen,
+ modes[modeidx].max_inlen);
+ if (err)
+ break;
+ err = gcry_cipher_checktag (hd, outbuf, modes[modeidx].authlen);
+ if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
+ err = 0;
+ }
+ else
+ {
+ gcry_cipher_final (hd);
+ err = cipher_decrypt (hd, outbuf, buflen, buf, buflen,
+ modes[modeidx].max_inlen);
+ }
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+ gcry_cipher_close (hd);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_decrypt failed: %s\n",
+ gpg_strerror (err) );
+ exit (1);
+ }
+ }
+
+ putchar ('\n');
+ gcry_free (raw_buf);
+ gcry_free (raw_outbuf);
+}
+
+
+
+static void
+rsa_bench (int iterations, int print_header, int no_blinding)
+{
+ gpg_error_t err;
+ int p_sizes[] = { 1024, 2048, 3072, 4096 };
+ int testno;
+
+ if (print_header)
+ printf ("Algorithm generate %4d*priv %4d*public\n"
+ "------------------------------------------------\n",
+ iterations, iterations );
+ for (testno=0; testno < DIM (p_sizes); testno++)
+ {
+ gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
+ gcry_mpi_t x;
+ gcry_sexp_t data;
+ gcry_sexp_t sig = NULL;
+ int count;
+ unsigned nbits = p_sizes[testno];
+
+ printf ("RSA %3d bit ", nbits);
+ fflush (stdout);
+
+ if (in_fips_mode && !(nbits == 2048 || nbits == 3072))
+ {
+ puts ("[skipped in fips mode]");
+ continue;
+ }
+
+ err = gcry_sexp_build (&key_spec, NULL,
+ gcry_fips_mode_active ()
+ ? "(genkey (RSA (nbits %d)))"
+ : "(genkey (RSA (nbits %d)(transient-key)))",
+ nbits);
+ if (err)
+ die ("creating S-expression failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ err = gcry_pk_genkey (&key_pair, key_spec);
+ if (err)
+ die ("creating %d bit RSA key failed: %s\n",
+ nbits, gcry_strerror (err));
+
+ pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
+ if (! pub_key)
+ die ("public part missing in key\n");
+ sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
+ if (! sec_key)
+ die ("private part missing in key\n");
+ gcry_sexp_release (key_pair);
+ gcry_sexp_release (key_spec);
+
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ x = gcry_mpi_new (nbits);
+ gcry_mpi_randomize (x, nbits-8, GCRY_WEAK_RANDOM);
+ err = gcry_sexp_build (&data, NULL,
+ "(data (flags raw) (value %m))", x);
+ gcry_mpi_release (x);
+ if (err)
+ die ("converting data failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ gcry_sexp_release (sig);
+ err = gcry_pk_sign (&sig, data, sec_key);
+ if (err)
+ die ("signing failed (%d): %s\n", count, gpg_strerror (err));
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ err = gcry_pk_verify (sig, data, pub_key);
+ if (err)
+ {
+ putchar ('\n');
+ show_sexp ("seckey:\n", sec_key);
+ show_sexp ("data:\n", data);
+ show_sexp ("sig:\n", sig);
+ die ("verify failed (%d): %s\n", count, gpg_strerror (err));
+ }
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+
+ if (no_blinding)
+ {
+ fflush (stdout);
+ x = gcry_mpi_new (nbits);
+ gcry_mpi_randomize (x, nbits-8, GCRY_WEAK_RANDOM);
+ err = gcry_sexp_build (&data, NULL,
+ "(data (flags no-blinding) (value %m))", x);
+ gcry_mpi_release (x);
+ if (err)
+ die ("converting data failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ gcry_sexp_release (sig);
+ err = gcry_pk_sign (&sig, data, sec_key);
+ if (err)
+ die ("signing failed (%d): %s\n", count, gpg_strerror (err));
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+ }
+
+ putchar ('\n');
+ fflush (stdout);
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data);
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+static void
+elg_bench (int iterations, int print_header)
+{
+ gpg_error_t err;
+ gcry_sexp_t pub_key[3], sec_key[3];
+ int p_sizes[3] = { 1024, 2048, 3072 };
+ gcry_sexp_t data = NULL;
+ gcry_sexp_t enc = NULL;
+ gcry_sexp_t plain = NULL;
+ int i, j;
+
+ err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_elg_key_1024,
+ strlen (sample_public_elg_key_1024));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_elg_key_1024,
+ strlen (sample_private_elg_key_1024));
+ if (!err)
+ err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_elg_key_2048,
+ strlen (sample_public_elg_key_2048));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_elg_key_2048,
+ strlen (sample_private_elg_key_2048));
+ if (!err)
+ err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_elg_key_3072,
+ strlen (sample_public_elg_key_3072));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_elg_key_3072,
+ strlen (sample_private_elg_key_3072));
+ if (err)
+ {
+ fprintf (stderr, PGM ": converting sample keys failed: %s\n",
+ gcry_strerror (err));
+ exit (1);
+ }
+
+ if (print_header)
+ printf ("Algorithm generate %4d*priv %4d*public\n"
+ "------------------------------------------------\n",
+ iterations, iterations );
+ for (i=0; i < DIM (p_sizes); i++)
+ {
+ char timerbuf1[100];
+
+ {
+ gcry_mpi_t x = gcry_mpi_new (p_sizes[i]);
+ gcry_mpi_randomize (x, p_sizes[i] - 16, GCRY_WEAK_RANDOM);
+ err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
+ gcry_mpi_release (x);
+ }
+ if (err)
+ {
+ fprintf (stderr, PGM ": converting data failed: %s\n",
+ gcry_strerror (err));
+ exit (1);
+ }
+
+ printf ("ELG %d bit -", p_sizes[i]);
+ fflush (stdout);
+
+ start_timer ();
+ for (j=0; j < iterations; j++)
+ {
+ gcry_sexp_release (enc);
+ err = gcry_pk_encrypt (&enc, data, pub_key[i]);
+ if (err)
+ {
+ putchar ('\n');
+ fprintf (stderr, PGM ": encrypt failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ stop_timer ();
+ snprintf (timerbuf1, sizeof timerbuf1, " %s", elapsed_time (1));
+ fflush (stdout);
+
+ start_timer ();
+ for (j=0; j < iterations; j++)
+ {
+ gcry_sexp_release (plain);
+ err = gcry_pk_decrypt (&plain, enc, sec_key[i]);
+ if (err)
+ {
+ putchar ('\n');
+ fprintf (stderr, PGM ": decrypt failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ stop_timer ();
+
+ printf (" %s %s\n", elapsed_time (1), timerbuf1);
+ fflush (stdout);
+
+ gcry_sexp_release (plain);
+ plain = NULL;
+ gcry_sexp_release (enc);
+ enc = NULL;
+ gcry_sexp_release (data);
+ data = NULL;
+ }
+
+ for (i=0; i < DIM (p_sizes); i++)
+ {
+ gcry_sexp_release (sec_key[i]);
+ gcry_sexp_release (pub_key[i]);
+ }
+}
+
+
+static void
+dsa_bench (int iterations, int print_header)
+{
+ gpg_error_t err;
+ gcry_sexp_t pub_key[3], sec_key[3];
+ int p_sizes[3] = { 1024, 2048, 3072 };
+ int q_sizes[3] = { 160, 224, 256 };
+ gcry_sexp_t data;
+ gcry_sexp_t sig = NULL;
+ int i, j;
+
+ err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024,
+ strlen (sample_public_dsa_key_1024));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024,
+ strlen (sample_private_dsa_key_1024));
+ if (!err)
+ err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048,
+ strlen (sample_public_dsa_key_2048));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048,
+ strlen (sample_private_dsa_key_2048));
+ if (!err)
+ err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072,
+ strlen (sample_public_dsa_key_3072));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072,
+ strlen (sample_private_dsa_key_3072));
+ if (err)
+ {
+ fprintf (stderr, PGM ": converting sample keys failed: %s\n",
+ gcry_strerror (err));
+ exit (1);
+ }
+
+ if (print_header)
+ printf ("Algorithm generate %4d*priv %4d*public\n"
+ "------------------------------------------------\n",
+ iterations, iterations );
+ for (i=0; i < DIM (q_sizes); i++)
+ {
+ gcry_mpi_t x;
+
+ x = gcry_mpi_new (q_sizes[i]);
+ gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM);
+ err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
+ gcry_mpi_release (x);
+ if (err)
+ {
+ fprintf (stderr, PGM ": converting data failed: %s\n",
+ gcry_strerror (err));
+ exit (1);
+ }
+
+ printf ("DSA %d/%d -", p_sizes[i], q_sizes[i]);
+ fflush (stdout);
+
+ start_timer ();
+ for (j=0; j < iterations; j++)
+ {
+ gcry_sexp_release (sig);
+ err = gcry_pk_sign (&sig, data, sec_key[i]);
+ if (err)
+ {
+ putchar ('\n');
+ fprintf (stderr, PGM ": signing failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ start_timer ();
+ for (j=0; j < iterations; j++)
+ {
+ err = gcry_pk_verify (sig, data, pub_key[i]);
+ if (err)
+ {
+ putchar ('\n');
+ fprintf (stderr, PGM ": verify failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ stop_timer ();
+ printf (" %s\n", elapsed_time (1));
+ fflush (stdout);
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data);
+ sig = NULL;
+ }
+
+
+ for (i=0; i < DIM (q_sizes); i++)
+ {
+ gcry_sexp_release (sec_key[i]);
+ gcry_sexp_release (pub_key[i]);
+ }
+}
+
+
+static void
+ecc_bench (int iterations, int print_header)
+{
+#if USE_ECC
+ gpg_error_t err;
+ const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519",
+ "gost256", "gost512" };
+ int testno;
+
+ if (print_header)
+ printf ("Algorithm generate %4d*priv %4d*public\n"
+ "------------------------------------------------\n",
+ iterations, iterations );
+ for (testno=0; testno < DIM (p_sizes); testno++)
+ {
+ gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
+ gcry_mpi_t x;
+ gcry_sexp_t data;
+ gcry_sexp_t sig = NULL;
+ int count;
+ int p_size;
+ int is_ed25519;
+ int is_gost;
+
+ is_ed25519 = !strcmp (p_sizes[testno], "Ed25519");
+ is_gost = !strncmp (p_sizes[testno], "gost", 4);
+
+ /* Only P-{224,256,384,521} are allowed in fips mode */
+ if (gcry_fips_mode_active()
+ && (is_ed25519 || is_gost || !strcmp (p_sizes[testno], "192")))
+ continue;
+
+ if (is_ed25519)
+ {
+ p_size = 256;
+ printf ("EdDSA Ed25519 ");
+ fflush (stdout);
+ }
+ else if (is_gost)
+ {
+ p_size = atoi (p_sizes[testno] + 4);
+ printf ("GOST %3d bit ", p_size);
+ fflush (stdout);
+ }
+ else
+ {
+ p_size = atoi (p_sizes[testno]);
+ printf ("ECDSA %3d bit ", p_size);
+ }
+ fflush (stdout);
+
+ if (is_ed25519)
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (ecdsa (curve \"Ed25519\")"
+ "(flags eddsa)))");
+ else if (is_gost)
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (ecdsa (curve %s)))",
+ p_size == 256 ? "GOST2001-test" : "GOST2012-512-test");
+ else
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (ECDSA (nbits %d)))", p_size);
+ if (err)
+ die ("creating S-expression failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ err = gcry_pk_genkey (&key_pair, key_spec);
+ if (err)
+ die ("creating %d bit ECC key failed: %s\n",
+ p_size, gcry_strerror (err));
+ if (verbose > 2)
+ show_sexp ("ECC key:\n", key_pair);
+
+ pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
+ if (! pub_key)
+ die ("public part missing in key\n");
+ sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
+ if (! sec_key)
+ die ("private part missing in key\n");
+ gcry_sexp_release (key_pair);
+ gcry_sexp_release (key_spec);
+
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ x = gcry_mpi_new (p_size);
+ gcry_mpi_randomize (x, p_size, GCRY_WEAK_RANDOM);
+ if (is_ed25519)
+ err = gcry_sexp_build (&data, NULL,
+ "(data (flags eddsa)(hash-algo sha512)"
+ " (value %m))", x);
+ else if (is_gost)
+ err = gcry_sexp_build (&data, NULL, "(data (flags gost) (value %m))", x);
+ else
+ err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
+ gcry_mpi_release (x);
+
+ if (err)
+ die ("converting data failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ gcry_sexp_release (sig);
+ err = gcry_pk_sign (&sig, data, sec_key);
+ if (err)
+ {
+ if (verbose)
+ {
+ putc ('\n', stderr);
+ show_sexp ("signing key:\n", sec_key);
+ show_sexp ("signed data:\n", data);
+ }
+ die ("signing failed: %s\n", gpg_strerror (err));
+ }
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time (1));
+ fflush (stdout);
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ err = gcry_pk_verify (sig, data, pub_key);
+ if (err)
+ {
+ putchar ('\n');
+ show_sexp ("seckey:\n", sec_key);
+ show_sexp ("data:\n", data);
+ show_sexp ("sig:\n", sig);
+ die ("verify failed: %s\n", gpg_strerror (err));
+ }
+ }
+ stop_timer ();
+ printf (" %s\n", elapsed_time (1));
+ fflush (stdout);
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data);
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+#endif /*USE_ECC*/
+}
+
+
+
+static void
+do_powm ( const char *n_str, const char *e_str, const char *m_str)
+{
+ gcry_mpi_t e, n, msg, cip;
+ gcry_error_t err;
+ int i;
+
+ err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0);
+ if (err) BUG ();
+ err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0);
+ if (err) BUG ();
+ err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0);
+ if (err) BUG ();
+
+ cip = gcry_mpi_new (0);
+
+ start_timer ();
+ for (i=0; i < 1000; i++)
+ gcry_mpi_powm (cip, msg, e, n);
+ stop_timer ();
+ printf (" %s", elapsed_time (1)); fflush (stdout);
+/* { */
+/* char *buf; */
+
+/* if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */
+/* BUG (); */
+/* printf ("result: %s\n", buf); */
+/* gcry_free (buf); */
+/* } */
+ gcry_mpi_release (cip);
+ gcry_mpi_release (msg);
+ gcry_mpi_release (n);
+ gcry_mpi_release (e);
+}
+
+
+static void
+mpi_bench (void)
+{
+ printf ("%-10s", "powm"); fflush (stdout);
+
+ do_powm (
+"20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4",
+ "29",
+"B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8"
+ );
+ do_powm (
+ "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
+ "29",
+ "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
+ );
+ do_powm (
+ "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA4071620A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
+ "29",
+ "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
+ );
+
+ putchar ('\n');
+
+
+}
+
+
+static void
+prime_bench (void)
+{
+ gpg_error_t err;
+ int i;
+ gcry_mpi_t prime;
+ int old_prog = single_char_progress;
+
+ single_char_progress = 1;
+ if (!with_progress)
+ printf ("%-10s", "prime");
+ fflush (stdout);
+ start_timer ();
+ for (i=0; i < 10; i++)
+ {
+ if (with_progress)
+ fputs ("primegen ", stdout);
+ err = gcry_prime_generate (&prime,
+ 1024, 0,
+ NULL,
+ NULL, NULL,
+ GCRY_WEAK_RANDOM,
+ GCRY_PRIME_FLAG_SECRET);
+ if (with_progress)
+ {
+ fputc ('\n', stdout);
+ fflush (stdout);
+ }
+ if (err)
+ {
+ fprintf (stderr, PGM ": error creating prime: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ gcry_mpi_release (prime);
+ }
+ stop_timer ();
+ if (with_progress)
+ printf ("%-10s", "prime");
+ printf (" %s\n", elapsed_time (1)); fflush (stdout);
+
+ single_char_progress = old_prog;
+}
+
+
+int
+main( int argc, char **argv )
+{
+ int last_argc = -1;
+ int no_blinding = 0;
+ int use_random_daemon = 0;
+ int use_secmem = 0;
+ int pk_count = 100;
+
+ buffer_alignment = 1;
+
+ if (argc)
+ { argc--; argv++; }
+
+ /* We skip this test if we are running under the test suite (no args
+ and srcdir defined) and GCRYPT_NO_BENCHMARKS is set. */
+ if (!argc && getenv ("srcdir") && getenv ("GCRYPT_NO_BENCHMARKS"))
+ exit (77);
+
+ if (getenv ("GCRYPT_IN_REGRESSION_TEST"))
+ {
+ in_regression_test = 1;
+ pk_count = 10;
+ }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: benchmark "
+ "[md|mac|cipher|random|mpi|rsa|dsa|ecc|prime [algonames]]\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--use-random-daemon"))
+ {
+ use_random_daemon = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--use-secmem"))
+ {
+ use_secmem = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--prefer-standard-rng"))
+ {
+ /* This is anyway the default, but we may want to use it for
+ debugging. */
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD));
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--prefer-fips-rng"))
+ {
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS));
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--prefer-system-rng"))
+ {
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM));
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--no-blinding"))
+ {
+ no_blinding = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--large-buffers"))
+ {
+ large_buffers = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--huge-buffers"))
+ {
+ huge_buffers = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--cipher-repetitions"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ cipher_repetitions = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--cipher-with-keysetup"))
+ {
+ cipher_with_keysetup = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--hash-repetitions"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ hash_repetitions = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--mac-repetitions"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ mac_repetitions = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--pk-count"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ pk_count = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--alignment"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ buffer_alignment = 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++;
+ }
+ }
+ else if (!strcmp (*argv, "--fips"))
+ {
+ argc--; argv++;
+ /* This command needs to be called before gcry_check_version. */
+ xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+ }
+ else if (!strcmp (*argv, "--progress"))
+ {
+ argc--; argv++;
+ with_progress = 1;
+ }
+ }
+
+ if (buffer_alignment < 1 || buffer_alignment > 16)
+ die ("value for --alignment must be in the range 1 to 16\n");
+
+ xgcry_control ((GCRYCTL_SET_VERBOSITY, (int)verbose));
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fprintf (stderr, PGM ": version mismatch; pgm=%s, library=%s\n",
+ GCRYPT_VERSION, gcry_check_version (NULL));
+ exit (1);
+ }
+
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0));
+
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
+ else if (!use_secmem)
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+
+ if (use_random_daemon)
+ xgcry_control ((GCRYCTL_USE_RANDOM_DAEMON, 1));
+
+ if (with_progress)
+ gcry_set_progress_handler (progress_cb, NULL);
+
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ if (cipher_repetitions < 1)
+ cipher_repetitions = 1;
+ if (hash_repetitions < 1)
+ hash_repetitions = 1;
+ if (mac_repetitions < 1)
+ mac_repetitions = 1;
+
+ if (in_regression_test)
+ fputs ("Note: " PGM " running in quick regression test mode.\n", stdout);
+
+ if ( !argc )
+ {
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ md_bench (NULL);
+ putchar ('\n');
+ mac_bench (NULL);
+ putchar ('\n');
+ cipher_bench (NULL);
+ putchar ('\n');
+ rsa_bench (pk_count, 1, no_blinding);
+ elg_bench (pk_count, 0);
+ dsa_bench (pk_count, 0);
+ ecc_bench (pk_count, 0);
+ putchar ('\n');
+ mpi_bench ();
+ putchar ('\n');
+ random_bench (0);
+ }
+ else if ( !strcmp (*argv, "random") || !strcmp (*argv, "strongrandom"))
+ {
+ if (argc == 1)
+ random_bench ((**argv == 's'));
+ else if (argc == 2)
+ {
+ xgcry_control ((GCRYCTL_SET_RANDOM_SEED_FILE, argv[1]));
+ random_bench ((**argv == 's'));
+ xgcry_control ((GCRYCTL_UPDATE_RANDOM_SEED_FILE));
+ }
+ else
+ fputs ("usage: benchmark [strong]random [seedfile]\n", stdout);
+ }
+ else if ( !strcmp (*argv, "md"))
+ {
+ if (argc == 1)
+ md_bench (NULL);
+ else
+ for (argc--, argv++; argc; argc--, argv++)
+ md_bench ( *argv );
+ }
+ else if ( !strcmp (*argv, "mac"))
+ {
+ if (argc == 1)
+ mac_bench (NULL);
+ else
+ for (argc--, argv++; argc; argc--, argv++)
+ mac_bench ( *argv );
+ }
+ else if ( !strcmp (*argv, "cipher"))
+ {
+ if (argc == 1)
+ cipher_bench (NULL);
+ else
+ for (argc--, argv++; argc; argc--, argv++)
+ cipher_bench ( *argv );
+ }
+ else if ( !strcmp (*argv, "mpi"))
+ {
+ mpi_bench ();
+ }
+ else if ( !strcmp (*argv, "pubkey"))
+ {
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ rsa_bench (pk_count, 1, no_blinding);
+ elg_bench (pk_count, 0);
+ dsa_bench (pk_count, 0);
+ ecc_bench (pk_count, 0);
+ }
+ else if ( !strcmp (*argv, "rsa"))
+ {
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ rsa_bench (pk_count, 1, no_blinding);
+ }
+ else if ( !strcmp (*argv, "elg"))
+ {
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ elg_bench (pk_count, 1);
+ }
+ else if ( !strcmp (*argv, "dsa"))
+ {
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ dsa_bench (pk_count, 1);
+ }
+ else if ( !strcmp (*argv, "ecc"))
+ {
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ ecc_bench (pk_count, 1);
+ }
+ else if ( !strcmp (*argv, "prime"))
+ {
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ prime_bench ();
+ }
+ else
+ {
+ fprintf (stderr, PGM ": bad arguments\n");
+ return 1;
+ }
+
+
+ if (in_fips_mode && !gcry_fips_mode_active ())
+ fprintf (stderr, PGM ": FIPS mode is not anymore active\n");
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/blake2b.h b/comm/third_party/libgcrypt/tests/blake2b.h
new file mode 100644
index 0000000000..1bec43b52f
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/blake2b.h
@@ -0,0 +1,1539 @@
+/* Generated from https://raw.githubusercontent.com/BLAKE2/BLAKE2/master/testvectors/blake2-kat.h */
+
+ /* blake2b_kat[]: */
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x78\x6a\x02\xf7\x42\x01\x59\x03\xc6\xc6\xfd\x85\x25\x52\xd2\x72"
+ "\x91\x2f\x47\x40\xe1\x58\x47\x61\x8a\x86\xe2\x17\xf7\x1f\x54\x19"
+ "\xd2\x5e\x10\x31\xaf\xee\x58\x53\x13\x89\x64\x44\x93\x4e\xb0\x4b"
+ "\x90\x3a\x68\x5b\x14\x48\xb7\x55\xd5\x6f\x70\x1a\xfe\x9b\xe2\xce",
+ 0 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x2f\xa3\xf6\x86\xdf\x87\x69\x95\x16\x7e\x7c\x2e\x5d\x74\xc4\xc7"
+ "\xb6\xe4\x8f\x80\x68\xfe\x0e\x44\x20\x83\x44\xd4\x80\xf7\x90\x4c"
+ "\x36\x96\x3e\x44\x11\x5f\xe3\xeb\x2a\x3a\xc8\x69\x4c\x28\xbc\xb4"
+ "\xf5\xa0\xf3\x27\x6f\x2e\x79\x48\x7d\x82\x19\x05\x7a\x50\x6e\x4b",
+ 1 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x1c\x08\x79\x8d\xc6\x41\xab\xa9\xde\xe4\x35\xe2\x25\x19\xa4\x72"
+ "\x9a\x09\xb2\xbf\xe0\xff\x00\xef\x2d\xcd\x8e\xd6\xf8\xa0\x7d\x15"
+ "\xea\xf4\xae\xe5\x2b\xbf\x18\xab\x56\x08\xa6\x19\x0f\x70\xb9\x04"
+ "\x86\xc8\xa7\xd4\x87\x37\x10\xb1\x11\x5d\x3d\xeb\xbb\x43\x27\xb5",
+ 2 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x40\xa3\x74\x72\x73\x02\xd9\xa4\x76\x9c\x17\xb5\xf4\x09\xff\x32"
+ "\xf5\x8a\xa2\x4f\xf1\x22\xd7\x60\x3e\x4f\xda\x15\x09\xe9\x19\xd4"
+ "\x10\x7a\x52\xc5\x75\x70\xa6\xd9\x4e\x50\x96\x7a\xea\x57\x3b\x11"
+ "\xf8\x6f\x47\x3f\x53\x75\x65\xc6\x6f\x70\x39\x83\x0a\x85\xd1\x86",
+ 3 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x77\xdd\xf4\xb1\x44\x25\xeb\x3d\x05\x3c\x1e\x84\xe3\x46\x9d\x92"
+ "\xc4\xcd\x91\x0e\xd2\x0f\x92\x03\x5e\x0c\x99\xd8\xa7\xa8\x6c\xec"
+ "\xaf\x69\xf9\x66\x3c\x20\xa7\xaa\x23\x0b\xc8\x2f\x60\xd2\x2f\xb4"
+ "\xa0\x0b\x09\xd3\xeb\x8f\xc6\x5e\xf5\x47\xfe\x63\xc8\xd3\xdd\xce",
+ 4 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xcb\xaa\x0b\xa7\xd4\x82\xb1\xf3\x01\x10\x9a\xe4\x10\x51\x99\x1a"
+ "\x32\x89\xbc\x11\x98\x00\x5a\xf2\x26\xc5\xe4\xf1\x03\xb6\x65\x79"
+ "\xf4\x61\x36\x10\x44\xc8\xba\x34\x39\xff\x12\xc5\x15\xfb\x29\xc5"
+ "\x21\x61\xb7\xeb\x9c\x28\x37\xb7\x6a\x5d\xc3\x3f\x7c\xb2\xe2\xe8",
+ 5 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xf9\x5d\x45\xcf\x69\xaf\x5c\x20\x23\xbd\xb5\x05\x82\x1e\x62\xe8"
+ "\x5d\x7c\xae\xdf\x7b\xed\xa1\x2c\x02\x48\x77\x5b\x0c\x88\x20\x5e"
+ "\xeb\x35\xaf\x3a\x90\x81\x6f\x66\x08\xce\x7d\xd4\x4e\xc2\x8d\xb1"
+ "\x14\x06\x14\xe1\xdd\xeb\xf3\xaa\x9c\xd1\x84\x3e\x0f\xad\x2c\x36",
+ 6 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x8f\x94\x5b\xa7\x00\xf2\x53\x0e\x5c\x2a\x7d\xf7\xd5\xdc\xe0\xf8"
+ "\x3f\x9e\xfc\x78\xc0\x73\xfe\x71\xae\x1f\x88\x20\x4a\x4f\xd1\xcf"
+ "\x70\xa0\x73\xf5\xd1\xf9\x42\xed\x62\x3a\xa1\x6e\x90\xa8\x71\x24"
+ "\x6c\x90\xc4\x5b\x62\x1b\x34\x01\xa5\xdd\xbd\x9d\xf6\x26\x41\x65",
+ 7 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xe9\x98\xe0\xdc\x03\xec\x30\xeb\x99\xbb\x6b\xfa\xaf\x66\x18\xac"
+ "\xc6\x20\x32\x0d\x72\x20\xb3\xaf\x2b\x23\xd1\x12\xd8\xe9\xcb\x12"
+ "\x62\xf3\xc0\xd6\x0d\x18\x3b\x1e\xe7\xf0\x96\xd1\x2d\xae\x42\xc9"
+ "\x58\x41\x86\x00\x21\x4d\x04\xf5\xed\x6f\x5e\x71\x8b\xe3\x55\x66",
+ 8 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6a\x9a\x09\x0c\x61\xb3\x41\x0a\xed\xe7\xec\x91\x38\x14\x6c\xeb"
+ "\x2c\x69\x66\x2f\x46\x0c\x3d\xa5\x3c\x65\x15\xc1\xeb\x31\xf4\x1c"
+ "\xa3\xd2\x80\xe5\x67\x88\x2f\x95\xcf\x66\x4a\x94\x14\x7d\x78\xf4"
+ "\x2c\xfc\x71\x4a\x40\xd2\x2e\xf1\x94\x70\xe0\x53\x49\x35\x08\xa2",
+ 9 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x29\x10\x25\x11\xd7\x49\xdb\x3c\xc9\xb4\xe3\x35\xfa\x1f\x5e\x8f"
+ "\xac\xa8\x42\x1d\x55\x8f\x6a\x3f\x33\x21\xd5\x0d\x04\x4a\x24\x8b"
+ "\xa5\x95\xcf\xc3\xef\xd3\xd2\xad\xc9\x73\x34\xda\x73\x24\x13\xf5"
+ "\xcb\xf4\x75\x1c\x36\x2b\xa1\xd5\x38\x62\xac\x1e\x8d\xab\xee\xe8",
+ 10 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc9\x7a\x47\x79\xd4\x7e\x6f\x77\x72\x9b\x59\x17\xd0\x13\x8a\xbb"
+ "\x35\x98\x0a\xb6\x41\xbd\x73\xa8\x85\x9e\xb1\xac\x98\xc0\x53\x62"
+ "\xed\x7d\x60\x8f\x2e\x95\x87\xd6\xba\x9e\x27\x1d\x34\x31\x25\xd4"
+ "\x0d\x93\x3a\x8e\xd0\x4e\xc1\xfe\x75\xec\x40\x7c\x7a\x53\xc3\x4e",
+ 11 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x10\xf0\xdc\x91\xb9\xf8\x45\xfb\x95\xfa\xd6\x86\x0e\x6c\xe1\xad"
+ "\xfa\x00\x2c\x7f\xc3\x27\x11\x6d\x44\xd0\x47\xcd\x7d\x58\x70\xd7"
+ "\x72\xbb\x12\xb5\xfa\xc0\x0e\x02\xb0\x8a\xc2\xa0\x17\x4d\x04\x46"
+ "\xc3\x6a\xb3\x5f\x14\xca\x31\x89\x4c\xd6\x1c\x78\xc8\x49\xb4\x8a",
+ 12 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xde\xa9\x10\x1c\xac\x62\xb8\xf6\xa3\xc6\x50\xf9\x0e\xea\x5b\xfa"
+ "\xe2\x65\x3a\x4e\xaf\xd6\x3a\x6d\x1f\x0f\x13\x2d\xb9\xe4\xf2\xb1"
+ "\xb6\x62\x43\x2e\xc8\x5b\x17\xbc\xac\x41\xe7\x75\x63\x78\x81\xf6"
+ "\xaa\xb3\x8d\xd6\x6d\xcb\xd0\x80\xf0\x99\x0a\x7a\x6e\x98\x54\xfe",
+ 13 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x44\x1f\xfa\xa0\x8c\xd7\x9d\xff\x4a\xfc\x9b\x9e\x5b\x56\x20\xee"
+ "\xc0\x86\x73\x0c\x25\xf6\x61\xb1\xd6\xfb\xfb\xd1\xce\xc3\x14\x8d"
+ "\xd7\x22\x58\xc6\x56\x41\xf2\xfc\xa5\xeb\x15\x5f\xad\xbc\xab\xb1"
+ "\x3c\x6e\x21\xdc\x11\xfa\xf7\x2c\x2a\x28\x1b\x7d\x56\x14\x5f\x19",
+ 14 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x44\x4b\x24\x0f\xe3\xed\x86\xd0\xe2\xef\x4c\xe7\xd8\x51\xed\xde"
+ "\x22\x15\x55\x82\xaa\x09\x14\x79\x7b\x72\x6c\xd0\x58\xb6\xf4\x59"
+ "\x32\xe0\xe1\x29\x51\x68\x76\x52\x7b\x1d\xd8\x8f\xc6\x6d\x71\x19"
+ "\xf4\xab\x3b\xed\x93\xa6\x1a\x0e\x2d\x2d\x2a\xea\xc3\x36\xd9\x58",
+ 15 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xbf\xba\xbb\xef\x45\x55\x4c\xcf\xa0\xdc\x83\x75\x2a\x19\xcc\x35"
+ "\xd5\x92\x09\x56\xb3\x01\xd5\x58\xd7\x72\x28\x2b\xc8\x67\x00\x91"
+ "\x68\xe9\xe9\x86\x06\xbb\x5b\xa7\x3a\x38\x5d\xe5\x74\x92\x28\xc9"
+ "\x25\xa8\x50\x19\xb7\x1f\x72\xfe\x29\xb3\xcd\x37\xca\x52\xef\xe6",
+ 16 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x9c\x4d\x0c\x3e\x1c\xdb\xbf\x48\x5b\xec\x86\xf4\x1c\xec\x7c\x98"
+ "\x37\x3f\x0e\x09\xf3\x92\x84\x9a\xaa\x22\x9e\xbf\xbf\x39\x7b\x22"
+ "\x08\x55\x29\xcb\x7e\xf3\x9f\x9c\x7c\x22\x22\xa5\x14\x18\x2b\x1e"
+ "\xff\xaa\x17\x8c\xc3\x68\x7b\x1b\x2b\x6c\xbc\xb6\xfd\xeb\x96\xf8",
+ 17 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x47\x71\x76\xb3\xbf\xcb\xad\xd7\x65\x7c\x23\xc2\x46\x25\xe4\xd0"
+ "\xd6\x74\xd1\x86\x8f\x00\x60\x06\x39\x8a\xf9\x7a\xa4\x18\x77\xc8"
+ "\xe7\x0d\x3d\x14\xc3\xbb\xc9\xbb\xcd\xce\xa8\x01\xbd\x0e\x15\x99"
+ "\xaf\x1f\x3e\xec\x67\x40\x51\x70\xf4\xe2\x6c\x96\x4a\x57\xa8\xb7",
+ 18 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa7\x8c\x49\x0e\xda\x31\x73\xbb\x3f\x10\xde\xe5\x2f\x11\x0f\xb1"
+ "\xc0\x8e\x03\x02\x23\x0b\x85\xdd\xd7\xc1\x12\x57\xd9\x2d\xe1\x48"
+ "\x78\x5e\xf0\x0c\x03\x9c\x0b\xb8\xeb\x98\x08\xa3\x5b\x2d\x8c\x08"
+ "\x0f\x57\x28\x59\x71\x4c\x9d\x40\x69\xc5\xbc\xaf\x09\x0e\x89\x8e",
+ 19 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x58\xd0\x23\x39\x7b\xeb\x5b\x41\x45\xcb\x22\x55\xb0\x7d\x74\x29"
+ "\x0b\x36\xd9\xfd\x1e\x59\x4a\xfb\xd8\xee\xa4\x7c\x20\x5b\x2e\xfb"
+ "\xfe\x6f\x46\x19\x0f\xaf\x95\xaf\x50\x4a\xb0\x72\xe3\x6f\x6c\x85"
+ "\xd7\x67\xa3\x21\xbf\xd7\xf2\x26\x87\xa4\xab\xbf\x49\x4a\x68\x9c",
+ 20 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x40\x01\xec\x74\xd5\xa4\x6f\xd2\x9c\x2c\x3c\xdb\xe5\xd1\xb9\xf2"
+ "\x0e\x51\xa9\x41\xbe\x98\xd2\xa4\xe1\xe2\xfb\xf8\x66\xa6\x72\x12"
+ "\x1d\xb6\xf8\x1a\x51\x4c\xfd\x10\xe7\x35\x8d\x57\x1b\xdb\xa4\x8e"
+ "\x4c\xe7\x08\xb9\xd1\x24\x89\x4b\xc0\xb5\xed\x55\x49\x35\xf7\x3a",
+ 21 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xcc\xd1\xb2\x2d\xab\x65\x11\x22\x5d\x24\x01\xea\x2d\x86\x25\xd2"
+ "\x06\xa1\x24\x73\xcc\x73\x2b\x61\x5e\x56\x40\xce\xff\xf0\xa4\xad"
+ "\xf9\x71\xb0\xe8\x27\xa6\x19\xe0\xa8\x0f\x5d\xb9\xcc\xd0\x96\x23"
+ "\x29\x01\x0d\x07\xe3\x4a\x20\x64\xe7\x31\xc5\x20\x81\x7b\x21\x83",
+ 22 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb4\xa0\xa9\xe3\x57\x4e\xdb\x9e\x1e\x72\xaa\x31\xe3\x9c\xc5\xf3"
+ "\x0d\xbf\x94\x3f\x8c\xab\xc4\x08\x44\x96\x54\xa3\x91\x31\xe6\x6d"
+ "\x71\x8a\x18\x81\x91\x43\xe3\xea\x96\xb4\xa1\x89\x59\x88\xa1\xc0"
+ "\x05\x6c\xf2\xb6\xe0\x4f\x9a\xc1\x9d\x65\x73\x83\xc2\x91\x0c\x44",
+ 23 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x44\x7b\xec\xab\x16\x63\x06\x08\xd3\x9f\x4f\x05\x8b\x16\xf7\xaf"
+ "\x95\xb8\x5a\x76\xaa\x0f\xa7\xce\xa2\xb8\x07\x55\xfb\x76\xe9\xc8"
+ "\x04\xf2\xca\x78\xf0\x26\x43\xc9\x15\xfb\xf2\xfc\xe5\xe1\x9d\xe8"
+ "\x60\x00\xde\x03\xb1\x88\x61\x81\x5a\x83\x12\x60\x71\xf8\xa3\x7b",
+ 24 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x54\xe6\xda\xb9\x97\x73\x80\xa5\x66\x58\x22\xdb\x93\x37\x4e\xda"
+ "\x52\x8d\x9b\xeb\x62\x6f\x9b\x94\x02\x70\x71\xcb\x26\x67\x5e\x11"
+ "\x2b\x4a\x7f\xec\x94\x1e\xe6\x0a\x81\xe4\xd2\xea\x3f\xf7\xbc\x52"
+ "\xcf\xc4\x5d\xfb\xfe\x73\x5a\x1c\x64\x6b\x2c\xf6\xd6\xa4\x9b\x62",
+ 25 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x3e\xa6\x26\x25\x94\x9e\x36\x46\x70\x4d\x7e\x3c\x90\x6f\x82\xf6"
+ "\xc0\x28\xf5\x40\xf5\xf7\x2a\x79\x4b\x0c\x57\xbf\x97\xb7\x64\x9b"
+ "\xfe\xb9\x0b\x01\xd3\xca\x3e\x82\x9d\xe2\x1b\x38\x26\xe6\xf8\x70"
+ "\x14\xd3\xc7\x73\x50\xcb\x5a\x15\xff\x5d\x46\x8a\x81\xbe\xc1\x60",
+ 26 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x21\x3c\xfe\x14\x5c\x54\xa3\x36\x91\x56\x99\x80\xe5\x93\x8c\x88"
+ "\x83\xa4\x6d\x84\xd1\x49\xc8\xff\x1a\x67\xcd\x28\x7b\x4d\x49\xc6"
+ "\xda\x69\xd3\xa0\x35\x44\x3d\xb0\x85\x98\x3d\x0e\xfe\x63\x70\x6b"
+ "\xd5\xb6\xf1\x5a\x7d\xa4\x59\xe8\xd5\x0a\x19\x09\x3d\xb5\x5e\x80",
+ 27 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x57\x16\xc4\xa3\x8f\x38\xdb\x10\x4e\x49\x4a\x0a\x27\xcb\xe8\x9a"
+ "\x26\xa6\xbb\x6f\x49\x9e\xc0\x1c\x8c\x01\xaa\x7c\xb8\x84\x97\xe7"
+ "\x51\x48\xcd\x6e\xee\x12\xa7\x16\x8b\x6f\x78\xab\x74\xe4\xbe\x74"
+ "\x92\x51\xa1\xa7\x4c\x38\xc8\x6d\x61\x29\x17\x7e\x28\x89\xe0\xb6",
+ 28 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x03\x04\x60\xa9\x8b\xdf\x9f\xf1\x7c\xd9\x64\x04\xf2\x8f\xc3\x04"
+ "\xf2\xb7\xc0\x4e\xaa\xde\x53\x67\x7f\xd2\x8f\x78\x8c\xa2\x21\x86"
+ "\xb8\xbc\x80\xdd\x21\xd1\x7f\x85\x49\xc7\x11\xaf\xf0\xe5\x14\xe1"
+ "\x9d\x4e\x15\xf5\x99\x02\x52\xa0\x3e\x08\x2f\x28\xdc\x20\x52\xf6",
+ 29 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x19\xe7\xf1\xcc\xee\x88\xa1\x06\x72\x33\x3e\x39\x0c\xf2\x20\x13"
+ "\xa8\xc7\x34\xc6\xcb\x9e\xab\x41\xf1\x7c\x3c\x80\x32\xa2\xe4\xac"
+ "\xa0\x56\x9e\xa3\x6f\x08\x60\xc7\xa1\xaf\x28\xfa\x47\x68\x40\xd6"
+ "\x60\x11\x16\x88\x59\x33\x4a\x9e\x4e\xf9\xcc\x2e\x61\xa0\xe2\x9e",
+ 30 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x29\xf8\xb8\xc7\x8c\x80\xf2\xfc\xb4\xbd\xf7\x82\x5e\xd9\x0a\x70"
+ "\xd6\x25\xff\x78\x5d\x26\x26\x77\xe2\x50\xc0\x4f\x37\x20\xc8\x88"
+ "\xd0\x3f\x80\x45\xe4\xed\xf3\xf5\x28\x5b\xd3\x9d\x92\x8a\x10\xa7"
+ "\xd0\xa5\xdf\x00\xb8\x48\x4a\xc2\x86\x81\x42\xa1\xe8\xbe\xa3\x51",
+ 31 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5c\x52\x92\x0a\x72\x63\xe3\x9d\x57\x92\x0c\xa0\xcb\x75\x2a\xc6"
+ "\xd7\x9a\x04\xfe\xf8\xa7\xa2\x16\xa1\xec\xb7\x11\x5c\xe0\x6d\x89"
+ "\xfd\x7d\x73\x5b\xd6\xf4\x27\x25\x55\xdb\xa2\x2c\x2d\x1c\x96\xe6"
+ "\x35\x23\x22\xc6\x2c\x56\x30\xfd\xe0\xf4\x77\x7a\x76\xc3\xde\x2c",
+ 32 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x83\xb0\x98\xf2\x62\x25\x1b\xf6\x60\x06\x4a\x9d\x35\x11\xce\x76"
+ "\x87\xa0\x9e\x6d\xfb\xb8\x78\x29\x9c\x30\xe9\x3d\xfb\x43\xa9\x31"
+ "\x4d\xb9\xa6\x00\x33\x7d\xb2\x6e\xbe\xed\xaf\x22\x56\xa9\x6d\xab"
+ "\xe9\xb2\x9e\x75\x73\xad\x11\xc3\x52\x3d\x87\x4d\xde\x5b\xe7\xed",
+ 33 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x94\x47\xd9\x8a\xa5\xc9\x33\x13\x52\xf4\x3d\x3e\x56\xd0\xa9\xa9"
+ "\xf9\x58\x18\x65\x99\x8e\x28\x85\xcc\x56\xdd\x0a\x0b\xd5\xa7\xb5"
+ "\x05\x95\xbd\x10\xf7\x52\x9b\xcd\x31\xf3\x7d\xc1\x6a\x14\x65\xd5"
+ "\x94\x07\x96\x67\xda\x2a\x3f\xcb\x70\x40\x14\x98\x83\x7c\xed\xeb",
+ 34 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x86\x77\x32\xf2\xfe\xeb\x23\x89\x30\x97\x56\x1a\xc7\x10\xa4\xbf"
+ "\xf4\x53\xbe\x9c\xfb\xed\xba\x8b\xa3\x24\xf9\xd3\x12\xa8\x2d\x73"
+ "\x2e\x1b\x83\xb8\x29\xfd\xcd\x17\x7b\x88\x2c\xa0\xc1\xbf\x54\x4b"
+ "\x22\x3b\xe5\x29\x92\x4a\x24\x6a\x63\xcf\x05\x9b\xfd\xc5\x0a\x1b",
+ 35 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xf1\x5a\xb2\x6d\x4c\xdf\xcf\x56\xe1\x96\xbb\x6b\xa1\x70\xa8\xfc"
+ "\xcc\x41\x4d\xe9\x28\x5a\xfd\x98\xa3\xd3\xcf\x2f\xb8\x8f\xcb\xc0"
+ "\xf1\x98\x32\xac\x43\x3a\x5b\x2c\xc2\x39\x2a\x4c\xe3\x43\x32\x98"
+ "\x7d\x8d\x2c\x2b\xef\x6c\x34\x66\x13\x8d\xb0\xc6\xe4\x2f\xa4\x7b",
+ 36 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x28\x13\x51\x6d\x68\xed\x4a\x08\xb3\x9d\x64\x8a\xa6\xaa\xcd\x81"
+ "\xe9\xd6\x55\xec\xd5\xf0\xc1\x35\x56\xc6\x0f\xdf\x0d\x33\x3e\xa3"
+ "\x84\x64\xb3\x6c\x02\xba\xcc\xd7\x46\xe9\x57\x5e\x96\xc6\x30\x14"
+ "\xf0\x74\xae\x34\xa0\xa2\x5b\x32\x0f\x0f\xbe\xdd\x6a\xcf\x76\x65",
+ 37 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd3\x25\x9a\xfc\xa8\xa4\x89\x62\xfa\x89\x2e\x14\x5a\xcf\x54\x7f"
+ "\x26\x92\x3a\xe8\xd4\x92\x4c\x8a\x53\x15\x81\x52\x6b\x04\xb4\x4c"
+ "\x7a\xf8\x3c\x64\x3e\xf5\xa0\xbc\x28\x2d\x36\xf3\xfb\x04\xc8\x4e"
+ "\x28\xb3\x51\xf4\x0c\x74\xb6\x9d\xc7\x84\x0b\xc7\x17\xb6\xf1\x5f",
+ 38 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xf1\x4b\x06\x1a\xe3\x59\xfa\x31\xb9\x89\xe3\x03\x32\xbf\xe8\xde"
+ "\x8c\xc8\xcd\xb5\x68\xe1\x4b\xe2\x14\xa2\x22\x3b\x84\xca\xab\x74"
+ "\x19\x54\x9e\xcf\xcc\x96\xce\x2a\xce\xc1\x19\x48\x5d\x87\xd1\x57"
+ "\xd3\xa8\x73\x4f\xc4\x26\x59\x7d\x64\xf3\x65\x70\xce\xaf\x22\x4d",
+ 39 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x55\xe7\x0b\x01\xd1\xfb\xf8\xb2\x3b\x57\xfb\x62\xe2\x6c\x2c\xe5"
+ "\x4f\x13\xf8\xfa\x24\x64\xe6\xeb\x98\xd1\x6a\x61\x17\x02\x6d\x8b"
+ "\x90\x81\x90\x12\x49\x6d\x40\x71\xeb\xe2\xe5\x95\x57\xec\xe3\x51"
+ "\x9a\x7a\xa4\x58\x02\xf9\x61\x53\x74\x87\x73\x32\xb7\x34\x90\xb3",
+ 40 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x25\x26\x1e\xb2\x96\x97\x1d\x6e\x4a\x71\xb2\x92\x8e\x64\x83\x9c"
+ "\x67\xd4\x22\x87\x2b\xf9\xf3\xc3\x19\x93\x61\x52\x22\xde\x9f\x8f"
+ "\x0b\x2c\x4b\xe8\x54\x85\x59\xb4\xb3\x54\xe7\x36\x41\x6e\x32\x18"
+ "\xd4\xe8\xa1\xe2\x19\xa4\xa6\xd4\x3e\x1a\x9a\x52\x1d\x0e\x75\xfc",
+ 41 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x08\x30\x7f\x34\x7c\x41\x29\x4e\x34\xbb\x54\xcb\x42\xb1\x52\x2d"
+ "\x22\xf8\x24\xf7\xb6\xe5\xdb\x50\xfd\xa0\x96\x79\x8e\x18\x1a\x8f"
+ "\x02\x6f\xa2\x7b\x4a\xe4\x5d\x52\xa6\x2c\xaf\x9d\x51\x98\xe2\x4a"
+ "\x49\x13\xc6\x67\x17\x75\xb2\xd7\x23\xc1\x23\x9b\xfb\xf0\x16\xd7",
+ 42 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x1e\x5c\x62\xe7\xe9\xbf\xa1\xb1\x18\x74\x7a\x2d\xe0\x8b\x3c\xa1"
+ "\x01\x12\xaf\x96\xa4\x6e\x4b\x22\xc3\xfc\x06\xf9\xbf\xee\x4e\xb5"
+ "\xc4\x9e\x05\x7a\x4a\x48\x86\x23\x43\x24\x57\x25\x76\xbb\x9b\x5e"
+ "\xcf\xde\x0d\x99\xb0\xde\x4f\x98\xec\x16\xe4\xd1\xb8\x5f\xa9\x47",
+ 43 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc7\x4a\x77\x39\x5f\xb8\xbc\x12\x64\x47\x45\x48\x38\xe5\x61\xe9"
+ "\x62\x85\x3d\xc7\xeb\x49\xa1\xe3\xcb\x67\xc3\xd0\x85\x1f\x3e\x39"
+ "\x51\x7b\xe8\xc3\x50\xac\x91\x09\x03\xd4\x9c\xd2\xbf\xdf\x54\x5c"
+ "\x99\x31\x6d\x03\x46\x17\x0b\x73\x9f\x0a\xdd\x5d\x53\x3c\x2c\xfc",
+ 44 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x0d\xd5\x7b\x42\x3c\xc0\x1e\xb2\x86\x13\x91\xeb\x88\x6a\x0d\x17"
+ "\x07\x9b\x93\x3f\xc7\x6e\xb3\xfc\x08\xa1\x9f\x8a\x74\x95\x2c\xb6"
+ "\x8f\x6b\xcd\xc6\x44\xf7\x73\x70\x96\x6e\x4d\x13\xe8\x05\x60\xbc"
+ "\xf0\x82\xef\x04\x79\xd4\x8f\xbb\xab\x4d\xf0\x3b\x53\xa4\xe1\x78",
+ 45 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x4d\x8d\xc3\x92\x3e\xdc\xcd\xfc\xe7\x00\x72\x39\x8b\x8a\x3d\xa5"
+ "\xc3\x1f\xcb\x3e\xe3\xb6\x45\xc8\x5f\x71\x7c\xba\xeb\x4b\x67\x3a"
+ "\x19\x39\x44\x25\xa5\x85\xbf\xb4\x64\xd9\x2f\x15\x97\xd0\xb7\x54"
+ "\xd1\x63\xf9\x7c\xed\x34\x3b\x25\xdb\x5a\x70\xef\x48\xeb\xb3\x4f",
+ 46 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xf0\xa5\x05\x53\xe4\xdf\xb0\xc4\xe3\xe3\xd3\xba\x82\x03\x48\x57"
+ "\xe3\xb1\xe5\x09\x18\xf5\xb8\xa7\xd6\x98\xe1\x0d\x24\x2b\x0f\xb5"
+ "\x44\xaf\x6c\x92\xd0\xc3\xaa\xf9\x93\x22\x20\x41\x61\x17\xb4\xe7"
+ "\x8e\xcb\x8a\x8f\x43\x0e\x13\xb8\x2a\x59\x15\x29\x0a\x58\x19\xc5",
+ 47 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb1\x55\x43\xf3\xf7\x36\x08\x66\x27\xcc\x53\x65\xe7\xe8\x98\x8c"
+ "\x2e\xf1\x55\xc0\xfd\x4f\x42\x89\x61\xb0\x0d\x15\x26\xf0\x4d\x6d"
+ "\x6a\x65\x8b\x4b\x8e\xd3\x2c\x5d\x86\x21\xe7\xf4\xf8\xe8\xa9\x33"
+ "\xd9\xec\xc9\xdd\x1b\x83\x33\xcb\xe2\x8c\xfc\x37\xd9\x71\x9e\x1c",
+ 48 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x7b\x4f\xa1\x58\xe4\x15\xfe\xf0\x23\x24\x72\x64\xcb\xbe\x15\xd1"
+ "\x6d\x91\xa4\x44\x24\xa8\xdb\x70\x7e\xb1\xe2\x03\x3c\x30\xe9\xe1"
+ "\xe7\xc8\xc0\x86\x45\x95\xd2\xcb\x8c\x58\x0e\xb4\x7e\x9d\x16\xab"
+ "\xbd\x7e\x44\xe8\x24\xf7\xce\xdb\x7d\xef\x57\x13\x0e\x52\xcf\xe9",
+ 49 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x60\x42\x4f\xf2\x32\x34\xc3\x4d\xc9\x68\x7a\xd5\x02\x86\x93\x72"
+ "\xcc\x31\xa5\x93\x80\x18\x6b\xc2\x36\x1c\x83\x5d\x97\x2f\x49\x66"
+ "\x6e\xb1\xac\x69\x62\x9d\xe6\x46\xf0\x3f\x9b\x4d\xb9\xe2\xac\xe0"
+ "\x93\xfb\xfd\xf8\xf2\x0a\xb5\xf9\x85\x41\x97\x8b\xe8\xef\x54\x9f",
+ 50 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x74\x06\x01\x8c\xe7\x04\xd8\x4f\x5e\xb9\xc7\x9f\xea\x97\xda\x34"
+ "\x56\x99\x46\x8a\x35\x0e\xe0\xb2\xd0\xf3\xa4\xbf\x20\x70\x30\x4e"
+ "\xa8\x62\xd7\x2a\x51\xc5\x7d\x30\x64\x94\x72\x86\xf5\x31\xe0\xea"
+ "\xf7\x56\x37\x02\x26\x2e\x6c\x72\x4a\xbf\x5e\xd8\xc8\x39\x8d\x17",
+ 51 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x14\xef\x5c\x6d\x64\x7b\x3b\xd1\xe6\xe3\x20\x06\xc2\x31\x19\x98"
+ "\x10\xde\x5c\x4d\xc8\x8e\x70\x24\x02\x73\xb0\xea\x18\xe6\x51\xa3"
+ "\xeb\x4f\x5c\xa3\x11\x4b\x8a\x56\x71\x69\x69\xc7\xcd\xa2\x7e\x0c"
+ "\x8d\xb8\x32\xad\x5e\x89\xa2\xdc\x6c\xb0\xad\xbe\x7d\x93\xab\xd1",
+ 52 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x38\xcf\x6c\x24\xe3\xe0\x8b\xcf\x1f\x6c\xf3\xd1\xb1\xf6\x5b\x90"
+ "\x52\x39\xa3\x11\x80\x33\x24\x9e\x44\x81\x13\xec\x63\x2e\xa6\xdc"
+ "\x34\x6f\xee\xb2\x57\x1c\x38\xbd\x9a\x73\x98\xb2\x22\x12\x80\x32"
+ "\x80\x02\xb2\x3e\x1a\x45\xad\xaf\xfe\x66\xd9\x3f\x65\x64\xea\xa2",
+ 53 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6c\xd7\x20\x8a\x4b\xc7\xe7\xe5\x62\x01\xbb\xba\x02\xa0\xf4\x89"
+ "\xcd\x38\x4a\xbe\x40\xaf\xd4\x22\x2f\x15\x8b\x3d\x98\x6e\xe7\x2a"
+ "\x54\xc5\x0f\xb6\x4f\xd4\xed\x25\x30\xed\xa2\xc8\xaf\x29\x28\xa0"
+ "\xda\x6d\x4f\x83\x0a\xe1\xc9\xdb\x46\x9d\xfd\x97\x0f\x12\xa5\x6f",
+ 54 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x65\x98\x58\xf0\xb5\xc9\xed\xab\x5b\x94\xfd\x73\x2f\x6e\x6b\x17"
+ "\xc5\x1c\xc0\x96\x10\x4f\x09\xbe\xb3\xaf\xc3\xaa\x46\x7c\x2e\xcf"
+ "\x88\x5c\x4c\x65\x41\xef\xfa\x90\x23\xd3\xb5\x73\x8a\xe5\xa1\x4d"
+ "\x86\x7e\x15\xdb\x06\xfe\x1f\x9d\x11\x27\xb7\x7e\x1a\xab\xb5\x16",
+ 55 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x26\xcc\xa0\x12\x6f\x5d\x1a\x81\x3c\x62\xe5\xc7\x10\x01\xc0\x46"
+ "\xf9\xc9\x20\x95\x70\x45\x50\xbe\x58\x73\xa4\x95\xa9\x99\xad\x01"
+ "\x0a\x4f\x79\x49\x1f\x24\xf2\x86\x50\x0a\xdc\xe1\xa1\x37\xbc\x20"
+ "\x84\xe4\x94\x9f\x5b\x72\x94\xce\xfe\x51\xec\xaf\xf8\xe9\x5c\xba",
+ 56 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x41\x47\xc1\xf5\x51\x72\x78\x8c\x55\x67\xc5\x61\xfe\xef\x87\x6f"
+ "\x62\x1f\xff\x1c\xe8\x77\x86\xb8\x46\x76\x37\xe7\x0d\xfb\xcd\x0d"
+ "\xbd\xb6\x41\x5c\xb6\x00\x95\x4a\xb9\xc0\x4c\x0e\x45\x7e\x62\x5b"
+ "\x40\x72\x22\xc0\xfe\x1a\xe2\x1b\x21\x43\x68\x8a\xda\x94\xdc\x58",
+ 57 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5b\x1b\xf1\x54\xc6\x2a\x8a\xf6\xe9\x3d\x35\xf1\x8f\x7f\x90\xab"
+ "\xb1\x6a\x6e\xf0\xe8\xd1\xae\xcd\x11\x8b\xf7\x01\x67\xba\xb2\xaf"
+ "\x08\x93\x5c\x6f\xdc\x06\x63\xce\x74\x48\x2d\x17\xa8\xe5\x4b\x54"
+ "\x6d\x1c\x29\x66\x31\xc6\x5f\x3b\x52\x2a\x51\x58\x39\xd4\x3d\x71",
+ 58 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x9f\x60\x04\x19\xa4\xe8\xf4\xfb\x83\x4c\x24\xb0\xf7\xfc\x13\xbf"
+ "\x4e\x27\x9d\x98\xe8\xa3\xc7\x65\xee\x93\x49\x17\x40\x3e\x3a\x66"
+ "\x09\x71\x82\xea\x21\x45\x3c\xb6\x3e\xbb\xe8\xb7\x3a\x9c\x21\x67"
+ "\x59\x64\x46\x43\x8c\x57\x62\x7f\x33\x0b\xad\xd4\xf5\x69\xf7\xd6",
+ 59 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x45\x7e\xf6\x46\x6a\x89\x24\xfd\x80\x11\xa3\x44\x71\xa5\xa1\xac"
+ "\x8c\xcd\x9b\xd0\xd0\x7a\x97\x41\x4a\xc9\x43\x02\x1c\xe4\xb9\xe4"
+ "\xb9\xc8\xdb\x0a\x28\xf0\x16\xed\x43\xb1\x54\x24\x81\x99\x00\x22"
+ "\x14\x7b\x31\x3e\x19\x46\x71\x13\x1e\x70\x8d\xd4\x3a\x3e\xd7\xdc",
+ 60 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x99\x97\xb2\x19\x4d\x9a\xf6\xdf\xcb\x91\x43\xf4\x1c\x0e\xd8\x3d"
+ "\x3a\x3f\x43\x88\x36\x11\x03\xd3\x8c\x2a\x49\xb2\x80\xa5\x81\x21"
+ "\x27\x15\xfd\x90\x8d\x41\xc6\x51\xf5\xc7\x15\xca\x38\xc0\xce\x28"
+ "\x30\xa3\x7e\x00\xe5\x08\xce\xd1\xbc\xdc\x32\x0e\x5e\x4d\x1e\x2e",
+ 61 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5c\x6b\xbf\x16\xba\xa1\x80\xf9\x86\xbd\x40\xa1\x28\x7e\xd4\xc5"
+ "\x49\x77\x0e\x72\x84\x85\x8f\xc4\x7b\xc2\x1a\xb9\x5e\xbb\xf3\x37"
+ "\x4b\x4e\xe3\xfd\x9f\x2a\xf6\x0f\x33\x95\x22\x1b\x2a\xcc\x76\xf2"
+ "\xd3\x4c\x13\x29\x54\x04\x9f\x8a\x3a\x99\x6f\x1e\x32\xec\x84\xe5",
+ 62 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd1\x0b\xf9\xa1\x5b\x1c\x9f\xc8\xd4\x1f\x89\xbb\x14\x0b\xf0\xbe"
+ "\x08\xd2\xf3\x66\x61\x76\xd1\x3b\xaa\xc4\xd3\x81\x35\x8a\xd0\x74"
+ "\xc9\xd4\x74\x8c\x30\x05\x20\xeb\x02\x6d\xae\xae\xa7\xc5\xb1\x58"
+ "\x89\x2f\xde\x4e\x8e\xc1\x7d\xc9\x98\xdc\xd5\x07\xdf\x26\xeb\x63",
+ 63 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x2f\xc6\xe6\x9f\xa2\x6a\x89\xa5\xed\x26\x90\x92\xcb\x9b\x2a\x44"
+ "\x9a\x44\x09\xa7\xa4\x40\x11\xee\xca\xd1\x3d\x7c\x4b\x04\x56\x60"
+ "\x2d\x40\x2f\xa5\x84\x4f\x1a\x7a\x75\x81\x36\xce\x3d\x5d\x8d\x0e"
+ "\x8b\x86\x92\x1f\xff\xf4\xf6\x92\xdd\x95\xbd\xc8\xe5\xff\x00\x52",
+ 64 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xfc\xbe\x8b\xe7\xdc\xb4\x9a\x32\xdb\xdf\x23\x94\x59\xe2\x63\x08"
+ "\xb8\x4d\xff\x1e\xa4\x80\xdf\x8d\x10\x4e\xef\xf3\x4b\x46\xfa\xe9"
+ "\x86\x27\xb4\x50\xc2\x26\x7d\x48\xc0\x94\x6a\x69\x7c\x5b\x59\x53"
+ "\x14\x52\xac\x04\x84\xf1\xc8\x4e\x3a\x33\xd0\xc3\x39\xbb\x2e\x28",
+ 65 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa1\x90\x93\xa6\xe3\xbc\xf5\x95\x2f\x85\x0f\x20\x30\xf6\x9b\x96"
+ "\x06\xf1\x47\xf9\x0b\x8b\xae\xe3\x36\x2d\xa7\x1d\x9f\x35\xb4\x4e"
+ "\xf9\xd8\xf0\xa7\x71\x2b\xa1\x87\x7f\xdd\xcd\x2d\x8e\xa8\xf1\xe5"
+ "\xa7\x73\xd0\xb7\x45\xd4\x72\x56\x05\x98\x3a\x2d\xe9\x01\xf8\x03",
+ 66 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x3c\x20\x06\x42\x3f\x73\xe2\x68\xfa\x59\xd2\x92\x03\x77\xeb\x29"
+ "\xa4\xf9\xa8\xb4\x62\xbe\x15\x98\x3e\xe3\xb8\x5a\xe8\xa7\x8e\x99"
+ "\x26\x33\x58\x1a\x90\x99\x89\x3b\x63\xdb\x30\x24\x1c\x34\xf6\x43"
+ "\x02\x7d\xc8\x78\x27\x9a\xf5\x85\x0d\x7e\x2d\x4a\x26\x53\x07\x3a",
+ 67 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd0\xf2\xf2\xe3\x78\x76\x53\xf7\x7c\xce\x2f\xa2\x48\x35\x78\x5b"
+ "\xbd\x0c\x43\x3f\xc7\x79\x46\x5a\x11\x51\x49\x90\x5a\x9d\xd1\xcb"
+ "\x82\x7a\x62\x85\x06\xd4\x57\xfc\xf1\x24\xa0\xc2\xae\xf9\xce\x2d"
+ "\x2a\x0a\x0f\x63\x54\x55\x70\xd8\x66\x7f\xf9\xe2\xeb\xa0\x73\x34",
+ 68 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x78\xa9\xfc\x04\x8e\x25\xc6\xdc\xb5\xde\x45\x66\x7d\xe8\xff\xdd"
+ "\x3a\x93\x71\x11\x41\xd5\x94\xe9\xfa\x62\xa9\x59\x47\x5d\xa6\x07"
+ "\x5e\xa8\xf0\x91\x6e\x84\xe4\x5a\xd9\x11\xb7\x54\x67\x07\x7e\xe5"
+ "\x2d\x2c\x9a\xeb\xf4\xd5\x8f\x20\xce\x4a\x3a\x00\x45\x8b\x05\xd4",
+ 69 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x45\x81\x3f\x44\x17\x69\xab\x6e\xd3\x7d\x34\x9f\xf6\xe7\x22\x67"
+ "\xd7\x6a\xe6\xbb\x3e\x3c\x61\x2e\xc0\x5c\x6e\x02\xa1\x2a\xf5\xa3"
+ "\x7c\x91\x8b\x52\xbf\x74\x26\x7c\x3f\x6a\x3f\x18\x3a\x80\x64\xff"
+ "\x84\xc0\x7b\x19\x3d\x08\x06\x67\x89\xa0\x1a\xcc\xdb\x6f\x93\x40",
+ 70 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x95\x6d\xa1\xc6\x8d\x83\xa7\xb8\x81\xe0\x1b\x9a\x96\x6c\x3c\x0b"
+ "\xf2\x7f\x68\x60\x6a\x8b\x71\xd4\x57\xbd\x01\x6d\x4c\x41\xdd\x8a"
+ "\x38\x0c\x70\x9a\x29\x6c\xb4\xc6\x54\x47\x92\x92\x0f\xd7\x88\x83"
+ "\x57\x71\xa0\x7d\x4a\x16\xfb\x52\xed\x48\x05\x03\x31\xdc\x4c\x8b",
+ 71 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xdf\x18\x6c\x2d\xc0\x9c\xaa\x48\xe1\x4e\x94\x2f\x75\xde\x5a\xc1"
+ "\xb7\xa2\x1e\x4f\x9f\x07\x2a\x5b\x37\x1e\x09\xe0\x73\x45\xb0\x74"
+ "\x0c\x76\x17\x7b\x01\x27\x88\x08\xfe\xc0\x25\xed\xed\x98\x22\xc1"
+ "\x22\xaf\xd1\xc6\x3e\x6f\x0c\xe2\xe3\x26\x31\x04\x10\x63\x14\x5c",
+ 72 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x87\x47\x56\x40\x96\x6a\x9f\xdc\xd6\xd3\xa3\xb5\xa2\xcc\xa5\xc0"
+ "\x8f\x0d\x88\x2b\x10\x24\x3c\x0e\xc1\xbf\x3c\x6b\x1c\x37\xf2\xcd"
+ "\x32\x12\xf1\x9a\x05\x78\x64\x47\x7d\x5e\xaf\x8f\xae\xd7\x3f\x29"
+ "\x37\xc7\x68\xa0\xaf\x41\x5e\x84\xbb\xce\x6b\xd7\xde\x23\xb6\x60",
+ 73 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc3\xb5\x73\xbb\xe1\x09\x49\xa0\xfb\xd4\xff\x88\x4c\x44\x6f\x22"
+ "\x29\xb7\x69\x02\xf9\xdf\xdb\xb8\xa0\x35\x3d\xa5\xc8\x3c\xa1\x4e"
+ "\x81\x51\xbb\xaa\xc8\x2f\xd1\x57\x6a\x00\x9a\xdc\x6f\x19\x35\xcf"
+ "\x26\xed\xd4\xf1\xfb\x8d\xa4\x83\xe6\xc5\xcd\x9d\x89\x23\xad\xc3",
+ 74 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb0\x9d\x8d\x0b\xba\x8a\x72\x86\xe4\x35\x68\xf7\x90\x75\x50\xe4"
+ "\x20\x36\xd6\x74\xe3\xc8\xfc\x34\xd8\xca\x46\xf7\x71\xd6\x46\x6b"
+ "\x70\xfb\x60\x58\x75\xf6\xa8\x63\xc8\x77\xd1\x2f\x07\x06\x3f\xdc"
+ "\x2e\x90\xcc\xd4\x59\xb1\x91\x0d\xcd\x52\xd8\xf1\x0b\x2b\x0a\x15",
+ 75 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xaf\x3a\x22\xbf\x75\xb2\x1a\xbf\xb0\xac\xd5\x44\x22\xba\x1b\x73"
+ "\x00\xa9\x52\xef\xf0\x2e\xbe\xb6\x5b\x5c\x23\x44\x71\xa9\x8d\xf3"
+ "\x2f\x4f\x96\x43\xce\x19\x04\x10\x8a\x16\x87\x67\x92\x42\x80\xbd"
+ "\x76\xc8\x3f\x8c\x82\xd9\xa7\x9d\x92\x59\xb1\x95\x36\x2a\x2a\x04",
+ 76 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xbf\x4f\xf2\x22\x1b\x7e\x69\x57\xa7\x24\xcd\x96\x4a\xa3\xd5\xd0"
+ "\xd9\x94\x1f\x54\x04\x13\x75\x2f\x46\x99\xd8\x10\x1b\x3e\x53\x75"
+ "\x08\xbf\x09\xf8\x50\x8b\x31\x77\x36\xff\xd2\x65\xf2\x84\x7a\xa7"
+ "\xd8\x4b\xd2\xd9\x75\x69\xc4\x9d\x63\x2a\xed\x99\x45\xe5\xfa\x5e",
+ 77 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x9c\x6b\x6b\x78\x19\x9b\x1b\xda\xcb\x43\x00\xe3\x14\x79\xfa\x62"
+ "\x2a\x6b\x5b\xc8\x0d\x46\x78\xa6\x07\x8f\x88\xa8\x26\x8c\xd7\x20"
+ "\x6a\x27\x99\xe8\xd4\x62\x1a\x46\x4e\xf6\xb4\x3d\xd8\xad\xff\xe9"
+ "\x7c\xaf\x22\x1b\x22\xb6\xb8\x77\x8b\x14\x9a\x82\x2a\xef\xbb\x09",
+ 78 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x89\x06\x56\xf0\x9c\x99\xd2\x80\xb5\xec\xb3\x81\xf5\x64\x27\xb8"
+ "\x13\x75\x1b\xc6\x52\xc7\x82\x80\x78\xb2\x3a\x4a\xf8\x3b\x4e\x3a"
+ "\x61\xfd\xba\xc6\x1f\x89\xbe\xe8\x4e\xa6\xbe\xe7\x60\xc0\x47\xf2"
+ "\x5c\x6b\x0a\x20\x1c\x69\xa3\x8f\xd6\xfd\x97\x1a\xf1\x85\x88\xbb",
+ 79 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x31\xa0\x46\xf7\x88\x2f\xfe\x6f\x83\xce\x47\x2e\x9a\x07\x01\x83"
+ "\x2e\xc7\xb3\xf7\x6f\xbc\xfd\x1d\xf6\x0f\xe3\xea\x48\xfd\xe1\x65"
+ "\x12\x54\x24\x7c\x3f\xd9\x5e\x10\x0f\x91\x72\x73\x1e\x17\xfd\x52"
+ "\x97\xc1\x1f\x4b\xb3\x28\x36\x3c\xa3\x61\x62\x4a\x81\xaf\x79\x7c",
+ 80 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x27\xa6\x0b\x2d\x00\xe7\xa6\x71\xd4\x7d\x0a\xec\x2a\x68\x6a\x0a"
+ "\xc0\x4b\x52\xf4\x0a\xb6\x62\x90\x28\xeb\x7d\x13\xf4\xba\xa9\x9a"
+ "\xc0\xfe\x46\xee\x6c\x81\x49\x44\xf2\xf4\xb4\xd2\x0e\x93\x78\xe4"
+ "\x84\x7e\xa4\x4c\x13\x17\x80\x91\xe2\x77\xb8\x7e\xa7\xa5\x57\x11",
+ 81 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x8b\x5c\xce\xf1\x94\x16\x2c\x1f\x19\xd6\x8f\x91\xe0\xb0\x92\x8f"
+ "\x28\x9e\xc5\x28\x37\x20\x84\x0c\x2f\x73\xd2\x53\x11\x12\x38\xdc"
+ "\xfe\x94\xaf\x2b\x59\xc2\xc1\xca\x25\x91\x90\x1a\x7b\xc0\x60\xe7"
+ "\x45\x9b\x6c\x47\xdf\x0f\x71\x70\x1a\x35\xcc\x0a\xa8\x31\xb5\xb6",
+ 82 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x57\xab\x6c\x4b\x22\x29\xae\xb3\xb7\x04\x76\xd8\x03\xcd\x63\x81"
+ "\x2f\x10\x7c\xe6\xda\x17\xfe\xd9\xb1\x78\x75\xe8\xf8\x6c\x72\x4f"
+ "\x49\xe0\x24\xcb\xf3\xa1\xb8\xb1\x19\xc5\x03\x57\x65\x2b\x81\x87"
+ "\x9d\x2a\xde\x2d\x58\x8b\x9e\x4f\x7c\xed\xba\x0e\x46\x44\xc9\xee",
+ 83 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x01\x90\xa8\xda\xc3\x20\xa7\x39\xf3\x22\xe1\x57\x31\xaa\x14\x0d"
+ "\xda\xf5\xbe\xd2\x94\xd5\xc8\x2e\x54\xfe\xf2\x9f\x21\x4e\x18\xaa"
+ "\xfa\xa8\x4f\x8b\xe9\x9a\xf6\x29\x50\x26\x6b\x8f\x90\x1f\x15\xdd"
+ "\x4c\x5d\x35\x51\x6f\xc3\x5b\x4c\xab\x2e\x96\xe4\x69\x5b\xbe\x1c",
+ 84 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd1\x4d\x7c\x4c\x41\x5e\xeb\x0e\x10\xb1\x59\x22\x4b\xea\x12\x7e"
+ "\xbd\x84\xf9\x59\x1c\x70\x2a\x33\x0f\x5b\xb7\xbb\x7a\xa4\x4e\xa3"
+ "\x9d\xe6\xed\x01\xf1\x8d\xa7\xad\xf4\x0c\xfb\x97\xc5\xd1\x52\xc2"
+ "\x75\x28\x82\x4b\x21\xe2\x39\x52\x6a\xf8\xf3\x6b\x21\x4e\x0c\xfb",
+ 85 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xbe\x28\xc4\xbe\x70\x69\x70\x48\x8f\xac\x7d\x29\xc3\xbd\x5c\x4e"
+ "\x98\x60\x85\xc4\xc3\x33\x2f\x1f\x3f\xd3\x09\x73\xdb\x61\x41\x64"
+ "\xba\x2f\x31\xa7\x88\x75\xff\xdc\x15\x03\x25\xc8\x83\x27\xa9\x44"
+ "\x3e\xd0\x4f\xdf\xe5\xbe\x93\x87\x6d\x16\x28\x56\x0c\x76\x4a\x80",
+ 86 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x03\x1d\xa1\x06\x9e\x3a\x2e\x9c\x33\x82\xe4\x36\xff\xd7\x9d\xf7"
+ "\x4b\x1c\xa6\xa8\xad\xb2\xde\xab\xe6\x76\xab\x45\x99\x4c\xbc\x05"
+ "\x4f\x03\x7d\x2f\x0e\xac\xe8\x58\xd3\x2c\x14\xe2\xd1\xc8\xb4\x60"
+ "\x77\x30\x8e\x3b\xdc\x2c\x1b\x53\x17\x2e\xcf\x7a\x8c\x14\xe3\x49",
+ 87 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x46\x65\xce\xf8\xba\x4d\xb4\xd0\xac\xb1\x18\xf2\x98\x7f\x0b\xb0"
+ "\x9f\x8f\x86\xaa\x44\x5a\xa3\xd5\xfc\x9a\x8b\x34\x68\x64\x78\x74"
+ "\x89\xe8\xfc\xec\xc1\x25\xd1\x7e\x9b\x56\xe1\x29\x88\xea\xc5\xec"
+ "\xc7\x28\x68\x83\xdb\x06\x61\xb8\xff\x05\xda\x2a\xff\xf3\x0f\xe4",
+ 88 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x63\xb7\x03\x2e\x5f\x93\x0c\xc9\x93\x95\x17\xf9\xe9\x86\x81\x6c"
+ "\xfb\xec\x2b\xe5\x9b\x95\x68\xb1\x3f\x2e\xad\x05\xba\xe7\x77\x7c"
+ "\xab\x62\x0c\x66\x59\x40\x4f\x74\x09\xe4\x19\x9a\x3b\xe5\xf7\x86"
+ "\x5a\xa7\xcb\xdf\x8c\x42\x53\xf7\xe8\x21\x9b\x1b\xd5\xf4\x6f\xea",
+ 89 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x9f\x09\xbf\x09\x3a\x2b\x0f\xf8\xc2\x63\x4b\x49\xe3\x7f\x1b\x21"
+ "\x35\xb4\x47\xaa\x91\x44\xc9\x78\x7d\xbf\xd9\x21\x29\x31\x6c\x99"
+ "\xe8\x8a\xab\x8a\x21\xfd\xef\x23\x72\xd1\x18\x9a\xec\x50\x0f\x95"
+ "\x77\x5f\x1f\x92\xbf\xb4\x55\x45\xe4\x25\x9f\xb9\xb7\xb0\x2d\x14",
+ 90 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xf9\xf8\x49\x3c\x68\x08\x88\x07\xdf\x7f\x6a\x26\x93\xd6\x4e\xa5"
+ "\x9f\x03\xe9\xe0\x5a\x22\x3e\x68\x52\x4c\xa3\x21\x95\xa4\x73\x4b"
+ "\x65\x4f\xce\xa4\xd2\x73\x4c\x86\x6c\xf9\x5c\x88\x9f\xb1\x0c\x49"
+ "\x15\x9b\xe2\xf5\x04\x3d\xc9\x8b\xb5\x5e\x02\xef\x7b\xdc\xb0\x82",
+ 91 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x3c\x9a\x73\x59\xab\x4f\xeb\xce\x07\xb2\x0a\xc4\x47\xb0\x6a\x24"
+ "\x0b\x7f\xe1\xda\xe5\x43\x9c\x49\xb6\x0b\x58\x19\xf7\x81\x2e\x4c"
+ "\x17\x24\x06\xc1\xaa\xc3\x16\x71\x3c\xf0\xdd\xed\x10\x38\x07\x72"
+ "\x58\xe2\xef\xf5\xb3\x39\x13\xd9\xd9\x5c\xae\xb4\xe6\xc6\xb9\x70",
+ 92 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xad\x6a\xab\x80\x84\x51\x0e\x82\x2c\xfc\xe8\x62\x5d\x62\xcf\x4d"
+ "\xe6\x55\xf4\x76\x38\x84\xc7\x1e\x80\xba\xb9\xac\x9d\x53\x18\xdb"
+ "\xa4\xa6\x03\x3e\xd2\x90\x84\xe6\x52\x16\xc0\x31\x60\x6c\xa1\x76"
+ "\x15\xdc\xfe\x3b\xa1\x1d\x26\x85\x1a\xe0\x99\x9c\xa6\xe2\x32\xcf",
+ 93 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x15\x6e\x9e\x62\x61\x37\x4c\x9d\xc8\x84\xf3\x6e\x70\xf0\xfe\x1a"
+ "\xb9\x29\x79\x97\xb8\x36\xfa\x7d\x17\x0a\x9c\x9e\xbf\x57\x5b\x88"
+ "\x1e\x7b\xce\xa4\x4d\x6c\x02\x48\xd3\x55\x97\x90\x71\x54\x82\x89"
+ "\x55\xbe\x19\x13\x58\x52\xf9\x22\x88\x15\xec\xa0\x24\xa8\xad\xfb",
+ 94 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x42\x15\x40\x76\x33\xf4\xcc\xa9\xb6\x78\x8b\xe9\x3e\x6a\xa3\xd9"
+ "\x63\xc7\xd6\xce\x4b\x14\x72\x47\x09\x9f\x46\xa3\xac\xb5\x00\xa3"
+ "\x00\x38\xcb\x3e\x78\x8c\x3d\x29\xf1\x32\xad\x84\x4e\x80\xe9\xe9"
+ "\x92\x51\xf6\xdb\x96\xac\xd8\xa0\x91\xcf\xc7\x70\xaf\x53\x84\x7b",
+ 95 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x1c\x07\x7e\x27\x9d\xe6\x54\x85\x23\x50\x2b\x6d\xf8\x00\xff\xda"
+ "\xb5\xe2\xc3\xe9\x44\x2e\xb8\x38\xf5\x8c\x29\x5f\x3b\x14\x7c\xef"
+ "\x9d\x70\x1c\x41\xc3\x21\x28\x3f\x00\xc7\x1a\xff\xa0\x61\x93\x10"
+ "\x39\x91\x26\x29\x5b\x78\xdd\x4d\x1a\x74\x57\x2e\xf9\xed\x51\x35",
+ 96 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xf0\x7a\x55\x5f\x49\xfe\x48\x1c\xf4\xcd\x0a\x87\xb7\x1b\x82\xe4"
+ "\xa9\x50\x64\xd0\x66\x77\xfd\xd9\x0a\x0e\xb5\x98\x87\x7b\xa1\xc8"
+ "\x3d\x46\x77\xb3\x93\xc3\xa3\xb6\x66\x1c\x42\x1f\x5b\x12\xcb\x99"
+ "\xd2\x03\x76\xba\x72\x75\xc2\xf3\xa8\xf5\xa9\xb7\x82\x17\x20\xda",
+ 97 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb5\x91\x1b\x38\x0d\x20\xc7\xb0\x43\x23\xe4\x02\x6b\x38\xe2\x00"
+ "\xf5\x34\x25\x92\x33\xb5\x81\xe0\x2c\x1e\x3e\x2d\x84\x38\xd6\xc6"
+ "\x6d\x5a\x4e\xb2\x01\xd5\xa8\xb7\x50\x72\xc4\xec\x29\x10\x63\x34"
+ "\xda\x70\xbc\x79\x52\x1b\x0c\xed\x2c\xfd\x53\x3f\x5f\xf8\x4f\x95",
+ 98 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x01\xf0\x70\xa0\x9b\xae\x91\x12\x96\x36\x1f\x91\xaa\x0e\x8e\x0d"
+ "\x09\xa7\x72\x54\x78\x53\x6d\x9d\x48\xc5\xfe\x1e\x5e\x7c\x3c\x5b"
+ "\x9b\x9d\x6e\xb0\x77\x96\xf6\xda\x57\xae\x56\x2a\x7d\x70\xe8\x82"
+ "\xe3\x7a\xdf\xde\x83\xf0\xc4\x33\xc2\xcd\x36\x35\x36\xbb\x22\xc8",
+ 99 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6f\x79\x3e\xb4\x37\x4a\x48\xb0\x77\x5a\xca\xf9\xad\xcf\x8e\x45"
+ "\xe5\x42\x70\xc9\x47\x5f\x00\x4a\xd8\xd5\x97\x3e\x2a\xca\x52\x74"
+ "\x7f\xf4\xed\x04\xae\x96\x72\x75\xb9\xf9\xeb\x0e\x1f\xf7\x5f\xb4"
+ "\xf7\x94\xfa\x8b\xe9\xad\xd7\xa4\x13\x04\x86\x8d\x10\x3f\xab\x10",
+ 100 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x96\x5f\x20\xf1\x39\x76\x5f\xcc\x4c\xe4\xba\x37\x94\x67\x58\x63"
+ "\xca\xc2\x4d\xb4\x72\xcd\x2b\x79\x9d\x03\x5b\xce\x3d\xbe\xa5\x02"
+ "\xda\x7b\x52\x48\x65\xf6\xb8\x11\xd8\xc5\x82\x8d\x3a\x88\x96\x46"
+ "\xfe\x64\xa3\x80\xda\x1a\xa7\xc7\x04\x4e\x9f\x24\x5d\xce\xd1\x28",
+ 101 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xec\x29\x5b\x57\x83\x60\x12\x44\xc3\x0e\x46\x41\xe3\xb4\x5b\xe2"
+ "\x22\xc4\xdc\xe7\x7a\x58\x70\x0f\x53\xbc\x8e\xc5\x2a\x94\x16\x90"
+ "\xb4\xd0\xb0\x87\xfb\x6f\xcb\x3f\x39\x83\x2b\x9d\xe8\xf7\x5e\xc2"
+ "\x0b\xd4\x30\x79\x81\x17\x49\xcd\xc9\x07\xed\xb9\x41\x57\xd1\x80",
+ 102 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x61\xc7\x2f\x8c\xcc\x91\xdb\xb5\x4c\xa6\x75\x0b\xc4\x89\x67\x2d"
+ "\xe0\x9f\xae\xdb\x8f\xdd\x4f\x94\xff\x23\x20\x90\x9a\x30\x3f\x5d"
+ "\x5a\x98\x48\x1c\x0b\xc1\xa6\x25\x41\x9f\xb4\xde\xbf\xbf\x7f\x8a"
+ "\x53\xbb\x07\xec\x3d\x98\x5e\x8e\xa1\x1e\x72\xd5\x59\x94\x07\x80",
+ 103 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xaf\xd8\x14\x5b\x25\x9e\xef\xc8\xd1\x26\x20\xc3\xc5\xb0\x3e\x1e"
+ "\xd8\xfd\x2c\xce\xfe\x03\x65\x07\x8c\x80\xfd\x42\xc1\x77\x0e\x28"
+ "\xb4\x49\x48\xf2\x7e\x65\xa1\x88\x66\x90\x11\x0d\xb8\x14\x39\x7b"
+ "\x68\xe4\x3d\x80\xd1\xba\x16\xdf\xa3\x58\xe7\x39\xc8\x98\xcf\xa3",
+ 104 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x55\x2f\xc7\x89\x3c\xf1\xce\x93\x3a\xda\x35\xc0\xda\x98\x84\x4e"
+ "\x41\x54\x5e\x24\x4c\x31\x57\xa1\x42\x8d\x7b\x4c\x21\xf9\xcd\x7e"
+ "\x40\x71\xae\xd7\x7b\x7c\xa9\xf1\xc3\x8f\xba\x32\x23\x74\x12\xef"
+ "\x21\xa3\x42\x74\x2e\xc8\x32\x43\x78\xf2\x1e\x50\x7f\xaf\xdd\x88",
+ 105 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x46\x7a\x33\xfb\xad\xf5\xeb\xc5\x25\x96\xef\x86\xaa\xae\xfc\x6f"
+ "\xab\xa8\xee\x65\x1b\x1c\xe0\x4d\xe3\x68\xa0\x3a\x5a\x90\x40\xef"
+ "\x28\x35\xe0\x0a\xdb\x09\xab\xb3\xfb\xd2\xbc\xe8\x18\xa2\x41\x3d"
+ "\x0b\x02\x53\xb5\xbd\xa4\xfc\x5b\x2f\x6f\x85\xf3\xfd\x5b\x55\xf2",
+ 106 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x22\xef\xf8\xe6\xdd\x52\x36\xf5\xf5\x7d\x94\xed\xe8\x74\xd6\xc9"
+ "\x42\x8e\x8f\x5d\x56\x6f\x17\xcd\x6d\x18\x48\xcd\x75\x2f\xe1\x3c"
+ "\x65\x5c\xb1\x0f\xba\xaf\xf7\x68\x72\xf2\xbf\x2d\xa9\x9e\x15\xdc"
+ "\x62\x40\x75\xe1\xec\x2f\x58\xa3\xf6\x40\x72\x12\x18\x38\x56\x9e",
+ 107 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x9c\xec\x6b\xbf\x62\xc4\xbc\xe4\x13\x8a\xba\xe1\xcb\xec\x8d\xad"
+ "\x31\x95\x04\x44\xe9\x03\x21\xb1\x34\x71\x96\x83\x4c\x11\x4b\x86"
+ "\x4a\xf3\xf3\xcc\x35\x08\xf8\x37\x51\xff\xb4\xed\xa7\xc8\x4d\x14"
+ "\x07\x34\xbb\x42\x63\xc3\x62\x5c\x00\xf0\x4f\x4c\x80\x68\x98\x1b",
+ 108 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa8\xb6\x0f\xa4\xfc\x24\x42\xf6\xf1\x51\x4a\xd7\x40\x26\x26\x92"
+ "\x0c\xc7\xc2\xc9\xf7\x21\x24\xb8\xcb\xa8\xee\x2c\xb7\xc4\x58\x6f"
+ "\x65\x8a\x44\x10\xcf\xfc\xc0\xab\x88\x34\x39\x55\xe0\x94\xc6\xaf"
+ "\x0d\x20\xd0\xc7\x14\xfb\x0a\x98\x8f\x54\x3f\x30\x0f\x58\xd3\x89",
+ 109 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x82\x71\xcc\x45\xdf\xa5\xe4\x17\x0e\x84\x7e\x86\x30\xb9\x52\xcf"
+ "\x9c\x2a\xa7\x77\xd0\x6f\x26\xa7\x58\x5b\x83\x81\xf1\x88\xda\xcc"
+ "\x73\x37\x39\x1c\xfc\xc9\x4b\x05\x3d\xc4\xec\x29\xcc\x17\xf0\x77"
+ "\x87\x04\x28\xf1\xac\x23\xfd\xdd\xa1\x65\xef\x5a\x3f\x15\x5f\x39",
+ 110 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xbf\x23\xc0\xc2\x5c\x80\x60\xe4\xf6\x99\x5f\x16\x23\xa3\xbe\xbe"
+ "\xca\xa9\x6e\x30\x86\x80\x00\x0a\x8a\xa3\xcd\x56\xbb\x1a\x6d\xa0"
+ "\x99\xe1\x0d\x92\x31\xb3\x7f\x45\x19\xb2\xef\xd2\xc2\x4d\xe7\x2f"
+ "\x31\xa5\xf1\x95\x35\x24\x1b\x4a\x59\xfa\x3c\x03\xce\xb7\x90\xe7",
+ 111 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x87\x7f\xd6\x52\xc0\x52\x81\x00\x9c\x0a\x52\x50\xe7\xa3\xa6\x71"
+ "\xf8\xb1\x8c\x10\x88\x17\xfe\x4a\x87\x4d\xe2\x2d\xa8\xe4\x5d\xb1"
+ "\x19\x58\xa6\x00\xc5\xf6\x2e\x67\xd3\x6c\xbf\x84\x47\x4c\xf2\x44"
+ "\xa9\xc2\xb0\x3a\x9f\xb9\xdc\x71\x1c\xd1\xa2\xca\xb6\xf3\xfa\xe0",
+ 112 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x29\xdf\x4d\x87\xea\x44\x4b\xaf\x5b\xcd\xf5\xf4\xe4\x15\x79\xe2"
+ "\x8a\x67\xde\x84\x14\x9f\x06\xc0\x3f\x11\x0e\xa8\x4f\x57\x2a\x9f"
+ "\x67\x6a\xdd\xd0\x4c\x48\x78\xf4\x9c\x5c\x00\xac\xcd\xa4\x41\xb1"
+ "\xa3\x87\xca\xce\xb2\xe9\x93\xbb\x7a\x10\xcd\x8c\x2d\x67\x17\xe1",
+ 113 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x71\x0d\xac\xb1\x66\x84\x46\x39\xcd\x7b\x63\x7c\x27\x42\x09\x42"
+ "\x4e\x24\x49\xdc\x35\xd7\x90\xbb\xfa\x4f\x76\x17\x70\x54\xa3\x6b"
+ "\x3b\x76\xfa\xc0\xca\x6e\x61\xdf\x1e\x68\x70\x00\x67\x8a\xc0\x74"
+ "\x6d\xf7\x5d\x0a\x39\x54\x89\x76\x81\xfd\x39\x3a\x15\x5a\x1b\xb4",
+ 114 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc1\xd5\xf9\x3b\x8d\xea\x1f\x25\x71\xba\xbc\xcb\xc0\x17\x64\x54"
+ "\x1a\x0c\xda\x87\xe4\x44\xd6\x73\xc5\x09\x66\xca\x55\x9c\x33\x35"
+ "\x4b\x3a\xcb\x26\xe5\xd5\x78\x1f\xfb\x28\x84\x7a\x4b\x47\x54\xd7"
+ "\x70\x08\xc6\x2a\x83\x58\x35\xf5\x00\xde\xa7\xc3\xb5\x8b\xda\xe2",
+ 115 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa4\x1e\x41\x27\x1c\xda\xb8\xaf\x4d\x72\xb1\x04\xbf\xb2\xad\x04"
+ "\x1a\xc4\xdf\x14\x67\x7d\xa6\x71\xd8\x56\x40\xc4\xb1\x87\xf5\x0c"
+ "\x2b\x66\x51\x3c\x46\x19\xfb\xd5\xd5\xdc\x4f\xe6\x5d\xd3\x7b\x90"
+ "\x42\xe9\x84\x8d\xda\x55\x6a\x50\x4c\xaa\x2b\x1c\x6a\xfe\x47\x30",
+ 116 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xe7\xbc\xba\xcd\xc3\x79\xc4\x3d\x81\xeb\xad\xcb\x37\x78\x15\x52"
+ "\xfc\x1d\x75\x3e\x8c\xf3\x10\xd9\x68\x39\x2d\x06\xc9\x1f\x1d\x64"
+ "\xcc\x9e\x90\xce\x1d\x22\xc3\x2d\x27\x7f\xc6\xcd\xa4\x33\xa4\xd4"
+ "\x42\xc7\x62\xe9\xea\xcf\x2c\x25\x9f\x32\xd6\x4c\xf9\xda\x3a\x22",
+ 117 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x51\x75\x5b\x4a\xc5\x45\x6b\x13\x21\x8a\x19\xc5\xb9\x24\x2f\x57"
+ "\xc4\xa9\x81\xe4\xd4\xec\xdc\xe0\x9a\x31\x93\x36\x2b\x80\x8a\x57"
+ "\x93\x45\xd4\x88\x1c\x26\x07\xa5\x65\x34\xdd\x7f\x21\x95\x6a\xff"
+ "\x72\xc2\xf4\x17\x3a\x6e\x7b\x6c\xc2\x21\x2b\xa0\xe3\xda\xee\x1f",
+ 118 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xdc\xc2\xc4\xbe\xb9\xc1\xf2\x60\x7b\x78\x6c\x20\xc6\x31\x97\x23"
+ "\x47\x03\x4c\x1c\xc0\x2f\xcc\x7d\x02\xff\x01\x09\x9c\xfe\x1c\x69"
+ "\x89\x84\x0a\xc2\x13\x92\x36\x29\x11\x3a\xa8\xba\xd7\x13\xcc\xf0"
+ "\xfe\x4c\xe1\x32\x64\xfb\x32\xb8\xb0\xfe\x37\x2d\xa3\x82\x54\x4a",
+ 119 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x3d\x55\x17\x6a\xce\xa4\xa7\xe3\xa6\x5f\xfa\x9f\xb1\x0a\x7a\x17"
+ "\x67\x19\x9c\xf0\x77\xce\xe9\xf7\x15\x32\xd6\x7c\xd7\xc7\x3c\x9f"
+ "\x93\xcf\xc3\x7c\xcd\xcc\x1f\xde\xf5\x0a\xad\x46\xa5\x04\xa6\x50"
+ "\xd2\x98\xd5\x97\xa3\xa9\xfa\x95\xc6\xc4\x0c\xb7\x1f\xa5\xe7\x25",
+ 120 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd0\x77\x13\xc0\x05\xde\x96\xdd\x21\xd2\xeb\x8b\xbe\xca\x66\x74"
+ "\x6e\xa5\x1a\x31\xae\x92\x2a\x3e\x74\x86\x48\x89\x54\x0a\x48\xdb"
+ "\x27\xd7\xe4\xc9\x03\x11\x63\x8b\x22\x4b\xf0\x20\x1b\x50\x18\x91"
+ "\x75\x48\x48\x11\x3c\x26\x61\x08\xd0\xad\xb1\x3d\xb7\x19\x09\xc7",
+ 121 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x58\x98\x3c\x21\x43\x3d\x95\x0c\xaa\x23\xe4\xbc\x18\x54\x3b\x8e"
+ "\x60\x1c\x20\x43\x18\x53\x21\x52\xda\xf5\xe1\x59\xa0\xcd\x14\x80"
+ "\x18\x3d\x29\x28\x5c\x05\xf1\x29\xcb\x0c\xc3\x16\x46\x87\x92\x80"
+ "\x86\xff\xe3\x80\x15\x8d\xf1\xd3\x94\xc6\xac\x0d\x42\x88\xbc\xa8",
+ 122 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x81\x00\xa8\xdc\x52\x8d\x2b\x68\x2a\xb4\x25\x08\x01\xba\x33\xf0"
+ "\x2a\x3e\x94\xc5\x4d\xac\x0a\xe1\x48\x2a\xa2\x1f\x51\xef\x3a\x82"
+ "\xf3\x80\x7e\x6f\xac\xb0\xae\xb0\x59\x47\xbf\x7a\xa2\xad\xcb\x03"
+ "\x43\x56\xf9\x0f\xa4\x56\x0e\xde\x02\x20\x1a\x37\xe4\x11\xec\x1a",
+ 123 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x07\x02\x5f\x1b\xb6\xc7\x84\xf3\xfe\x49\xde\x5c\x14\xb9\x36\xa5"
+ "\xac\xac\xac\xaa\xb3\x3f\x6a\xc4\xd0\xe0\x0a\xb6\xa1\x24\x83\xd6"
+ "\xbe\xc0\x0b\x4f\xe6\x7c\x7c\xa5\xcc\x50\x8c\x2a\x53\xef\xb5\xbf"
+ "\xa5\x39\x87\x69\xd8\x43\xff\x0d\x9e\x8b\x14\xd3\x6a\x01\xa7\x7f",
+ 124 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xba\x6a\xef\xd9\x72\xb6\x18\x6e\x02\x7a\x76\x27\x3a\x4a\x72\x33"
+ "\x21\xa3\xf5\x80\xcf\xa8\x94\xda\x5a\x9c\xe8\xe7\x21\xc8\x28\x55"
+ "\x2c\x64\xda\xce\xe3\xa7\xfd\x2d\x74\x3b\x5c\x35\xad\x0c\x8e\xfa"
+ "\x71\xf8\xce\x99\xbf\x96\x33\x47\x10\xe2\xc2\x34\x6e\x8f\x3c\x52",
+ 125 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xe0\x72\x1e\x02\x51\x7a\xed\xfa\x4e\x7e\x9b\xa5\x03\xe0\x25\xfd"
+ "\x46\xe7\x14\x56\x6d\xc8\x89\xa8\x4c\xbf\xe5\x6a\x55\xdf\xbe\x2f"
+ "\xc4\x93\x8a\xc4\x12\x05\x88\x33\x5d\xea\xc8\xef\x3f\xa2\x29\xad"
+ "\xc9\x64\x7f\x54\xad\x2e\x34\x72\x23\x4f\x9b\x34\xef\xc4\x65\x43",
+ 126 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb6\x29\x26\x69\xcc\xd3\x8d\x5f\x01\xca\xae\x96\xba\x27\x2c\x76"
+ "\xa8\x79\xa4\x57\x43\xaf\xa0\x72\x5d\x83\xb9\xeb\xb2\x66\x65\xb7"
+ "\x31\xf1\x84\x8c\x52\xf1\x19\x72\xb6\x64\x4f\x55\x4c\x06\x4f\xa9"
+ "\x07\x80\xdb\xbb\xf3\xa8\x9d\x4f\xc3\x1f\x67\xdf\x3e\x58\x57\xef",
+ 127 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x23\x19\xe3\x78\x9c\x47\xe2\xda\xa5\xfe\x80\x7f\x61\xbe\xc2\xa1"
+ "\xa6\x53\x7f\xa0\x3f\x19\xff\x32\xe8\x7e\xec\xbf\xd6\x4b\x7e\x0e"
+ "\x8c\xcf\xf4\x39\xac\x33\x3b\x04\x0f\x19\xb0\xc4\xdd\xd1\x1a\x61"
+ "\xe2\x4a\xc1\xfe\x0f\x10\xa0\x39\x80\x6c\x5d\xcc\x0d\xa3\xd1\x15",
+ 128 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xf5\x97\x11\xd4\x4a\x03\x1d\x5f\x97\xa9\x41\x3c\x06\x5d\x1e\x61"
+ "\x4c\x41\x7e\xde\x99\x85\x90\x32\x5f\x49\xba\xd2\xfd\x44\x4d\x3e"
+ "\x44\x18\xbe\x19\xae\xc4\xe1\x14\x49\xac\x1a\x57\x20\x78\x98\xbc"
+ "\x57\xd7\x6a\x1b\xcf\x35\x66\x29\x2c\x20\xc6\x83\xa5\xc4\x64\x8f",
+ 129 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xdf\x0a\x9d\x0c\x21\x28\x43\xa6\xa9\x34\xe3\x90\x2b\x2d\xd3\x0d"
+ "\x17\xfb\xa5\xf9\x69\xd2\x03\x0b\x12\xa5\x46\xd8\xa6\xa4\x5e\x80"
+ "\xcf\x56\x35\xf0\x71\xf0\x45\x2e\x9c\x91\x92\x75\xda\x99\xbe\xd5"
+ "\x1e\xb1\x17\x3c\x1a\xf0\x51\x87\x26\xb7\x5b\x0e\xc3\xba\xe2\xb5",
+ 130 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa3\xeb\x6e\x6c\x7b\xf2\xfb\x8b\x28\xbf\xe8\xb1\x5e\x15\xbb\x50"
+ "\x0f\x78\x1e\xcc\x86\xf7\x78\xc3\xa4\xe6\x55\xfc\x58\x69\xbf\x28"
+ "\x46\xa2\x45\xd4\xe3\x3b\x7b\x14\x43\x6a\x17\xe6\x3b\xe7\x9b\x36"
+ "\x65\x5c\x22\x6a\x50\xff\xbc\x71\x24\x20\x7b\x02\x02\x34\x2d\xb5",
+ 131 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x56\xd4\xcb\xcd\x07\x05\x63\x42\x6a\x01\x70\x69\x42\x5c\x2c\xd2"
+ "\xae\x54\x06\x68\x28\x7a\x5f\xb9\xda\xc4\x32\xeb\x8a\xb1\xa3\x53"
+ "\xa3\x0f\x2f\xe1\xf4\x0d\x83\x33\x3a\xfe\x69\x6a\x26\x77\x95\x40"
+ "\x8a\x92\xfe\x7d\xa0\x7a\x0c\x18\x14\xcf\x77\xf3\x6e\x10\x5e\xe8",
+ 132 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xe5\x9b\x99\x87\xd4\x28\xb3\xed\xa3\x7d\x80\xab\xdb\x16\xcd\x2b"
+ "\x0a\xef\x67\x4c\x2b\x1d\xda\x44\x32\xea\x91\xee\x6c\x93\x5c\x68"
+ "\x4b\x48\xb4\x42\x8a\x8c\xc7\x40\xe5\x79\xa3\x0d\xef\xf3\x5a\x80"
+ "\x30\x13\x82\x0d\xd2\x3f\x14\xae\x1d\x84\x13\xb5\xc8\x67\x2a\xec",
+ 133 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xcd\x9f\xcc\x99\xf9\x9d\x4c\xc1\x6d\x03\x19\x00\xb2\xa7\x36\xe1"
+ "\x50\x8d\xb4\xb5\x86\x81\x4e\x63\x45\x85\x7f\x35\x4a\x70\xcc\xec"
+ "\xb1\xdf\x3b\x50\xa1\x9a\xda\xf4\x3c\x27\x8e\xfa\x42\x3f\xf4\xbb"
+ "\x6c\x52\x3e\xc7\xfd\x78\x59\xb9\x7b\x16\x8a\x7e\xbf\xf8\x46\x7c",
+ 134 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x06\x02\x18\x5d\x8c\x3a\x78\x73\x8b\x99\x16\x4b\x8b\xc6\xff\xb2"
+ "\x1c\x7d\xeb\xeb\xbf\x80\x63\x72\xe0\xda\x44\xd1\x21\x54\x55\x97"
+ "\xb9\xc6\x62\xa2\x55\xdc\x31\x54\x2c\xf9\x95\xec\xbe\x6a\x50\xfb"
+ "\x5e\x6e\x0e\xe4\xef\x24\x0f\xe5\x57\xed\xed\x11\x88\x08\x7e\x86",
+ 135 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc0\x8a\xfa\x5b\x92\x7b\xf0\x80\x97\xaf\xc5\xff\xf9\xca\x4e\x78"
+ "\x00\x12\x5c\x1f\x52\xf2\xaf\x35\x53\xfa\x2b\x89\xe1\xe3\x01\x5c"
+ "\x4f\x87\xd5\xe0\xa4\x89\x56\xad\x31\x45\x0b\x08\x3d\xad\x14\x7f"
+ "\xfb\x5e\xc0\x34\x34\xa2\x68\x30\xcf\x37\xd1\x03\xab\x50\xc5\xda",
+ 136 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x36\xf1\xe1\xc1\x1d\x6e\xf6\xbc\x3b\x53\x6d\x50\x5d\x54\x4a\x87"
+ "\x15\x22\xc5\xc2\xa2\x53\x06\x7e\xc9\x93\x3b\x6e\xc2\x54\x64\xda"
+ "\xf9\x85\x52\x5f\x5b\x95\x60\xa1\x6d\x89\x02\x59\xac\x1b\xb5\xcc"
+ "\x67\xc0\xc4\x69\xcd\xe1\x33\xde\xf0\x00\xea\x1d\x68\x6f\x4f\x5d",
+ 137 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xbf\x2a\xb2\xe2\x47\x0f\x54\x38\xc3\xb6\x89\xe6\x6e\x76\x86\xff"
+ "\xfa\x0c\xb1\xe1\x79\x8a\xd3\xa8\x6f\xf9\x90\x75\xbf\x61\x38\xe3"
+ "\x3d\x9c\x0c\xe5\x9a\xfb\x24\xac\x67\xa0\x2a\xf3\x44\x28\x19\x1a"
+ "\x9a\x0a\x60\x41\xc0\x74\x71\xb7\xc3\xb1\xa7\x52\xd6\xfc\x0b\x8b",
+ 138 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd4\x00\x60\x1f\x97\x28\xcc\xc4\xc9\x23\x42\xd9\x78\x7d\x8d\x28"
+ "\xab\x32\x3a\xf3\x75\xca\x56\x24\xb4\xbb\x91\xd1\x72\x71\xfb\xae"
+ "\x86\x2e\x41\x3b\xe7\x3f\x1f\x68\xe6\x15\xb8\xc5\xc3\x91\xbe\x0d"
+ "\xbd\x91\x44\x74\x6e\xb3\x39\xad\x54\x15\x47\xba\x9c\x46\x8a\x17",
+ 139 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x79\xfe\x2f\xe1\x57\xeb\x85\xa0\x38\xab\xb8\xeb\xbc\x64\x77\x31"
+ "\xd2\xc8\x3f\x51\xb0\xac\x6e\xe1\x4a\xa2\x84\xcb\x6a\x35\x49\xa4"
+ "\xdc\xce\xb3\x00\x74\x0a\x82\x5f\x52\xf5\xfb\x30\xb0\x3b\x8c\x4d"
+ "\x8b\x0f\x4a\xa6\x7a\x63\xf4\xa9\x4e\x33\x03\xc4\xed\xa4\xc0\x2b",
+ 140 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x75\x35\x13\x13\xb5\x2a\x85\x29\x29\x8d\x8c\x18\x6b\x17\x68\x66"
+ "\x6d\xcc\xa8\x59\x53\x17\xd7\xa4\x81\x6e\xb8\x8c\x06\x20\x20\xc0"
+ "\xc8\xef\xc5\x54\xbb\x34\x1b\x64\x68\x8d\xb5\xcc\xaf\xc3\x5f\x3c"
+ "\x3c\xd0\x9d\x65\x64\xb3\x6d\x7b\x04\xa2\x48\xe1\x46\x98\x0d\x4b",
+ 141 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xe3\x12\x8b\x1d\x31\x1d\x02\x17\x9d\x7f\x25\xf9\x7a\x5a\x8b\xee"
+ "\x2c\xc8\xc8\x63\x03\x64\x4f\xcd\x66\x4e\x15\x7d\x1f\xef\x00\xf2"
+ "\x3e\x46\xf9\xa5\xe8\xe5\xc8\x90\xce\x56\x5b\xb6\xab\xd4\x30\x2c"
+ "\xe0\x64\x69\xd5\x2a\x5b\xd5\x3e\x1c\x5a\x54\xd0\x46\x49\xdc\x03",
+ 142 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc2\x38\x2a\x72\xd2\xd3\xac\xe9\xd5\x93\x3d\x00\xb6\x08\x27\xed"
+ "\x38\x0c\xda\x08\xd0\xba\x5f\x6d\xd4\x1e\x29\xee\x6d\xbe\x8e\xcb"
+ "\x92\x35\xf0\x6b\xe9\x5d\x83\xb6\x81\x6a\x2f\xb7\xa5\xad\x47\x03"
+ "\x5e\x8a\x4b\x69\xa4\x88\x4b\x99\xe4\xbe\xce\x58\xca\xb2\x5d\x44",
+ 143 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6b\x1c\x69\x46\x0b\xbd\x50\xac\x2e\xd6\xf3\x2e\x6e\x88\x7c\xfe"
+ "\xd4\x07\xd4\x7d\xcf\x0a\xaa\x60\x38\x7f\xe3\x20\xd7\x80\xbd\x03"
+ "\xea\xb6\xd7\xba\xeb\x2a\x07\xd1\x0c\xd5\x52\xa3\x00\x34\x13\x54"
+ "\xea\x9a\x5f\x03\x18\x3a\x62\x3f\x92\xa2\xd4\xd9\xf0\x09\x26\xaf",
+ 144 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6c\xda\x20\x6c\x80\xcd\xc9\xc4\x4b\xa9\x90\xe0\x32\x8c\x31\x4f"
+ "\x81\x9b\x14\x2d\x00\x63\x04\x04\xc4\x8c\x05\xdc\x76\xd1\xb0\x0c"
+ "\xe4\xd7\x2f\xc6\xa4\x8e\x14\x69\xdd\xef\x60\x94\x12\xc3\x64\x82"
+ "\x08\x54\x21\x4b\x48\x69\xaf\x09\x0f\x00\xd3\xc1\xba\x44\x3e\x1b",
+ 145 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x7f\xfc\x8c\x26\xfb\xd6\xa0\xf7\xa6\x09\xe6\xe1\x93\x9f\x6a\x9e"
+ "\xdf\x1b\x0b\x06\x66\x41\xfb\x76\xc4\xf9\x60\x2e\xd7\x48\xd1\x16"
+ "\x02\x49\x6b\x35\x35\x5b\x1a\xa2\x55\x85\x0a\x50\x9d\x2f\x8e\xe1"
+ "\x8c\x8f\x3e\x1d\x7d\xcb\xc3\x7a\x13\x65\x98\xf5\x6a\x59\xed\x17",
+ 146 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x70\xde\x1f\x08\xdd\x4e\x09\xd5\xfc\x15\x1f\x17\xfc\x99\x1a\x23"
+ "\xab\xfc\x05\x10\x42\x90\xd5\x04\x68\x88\x2e\xfa\xf5\x82\xb6\xec"
+ "\x2f\x14\xf5\x77\xc0\xd6\x8c\x3a\xd0\x66\x26\x91\x6e\x3c\x86\xe6"
+ "\xda\xab\x6c\x53\xe5\x16\x3e\x82\xb6\xbd\x0c\xe4\x9f\xc0\xd8\xdf",
+ 147 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x4f\x81\x93\x57\x56\xed\x35\xee\x20\x58\xee\x0c\x6a\x61\x10\xd6"
+ "\xfa\xc5\xcb\x6a\x4f\x46\xaa\x94\x11\x60\x3f\x99\x96\x58\x23\xb6"
+ "\xda\x48\x38\x27\x6c\x5c\x06\xbc\x78\x80\xe3\x76\xd9\x27\x58\x36"
+ "\x9e\xe7\x30\x5b\xce\xc8\xd3\xcf\xd2\x8c\xca\xbb\x7b\x4f\x05\x79",
+ 148 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xab\xcb\x61\xcb\x36\x83\xd1\x8f\x27\xad\x52\x79\x08\xed\x2d\x32"
+ "\xa0\x42\x6c\xb7\xbb\x4b\xf1\x80\x61\x90\x3a\x7d\xc4\x2e\x7e\x76"
+ "\xf9\x82\x38\x23\x04\xd1\x8a\xf8\xc8\x0d\x91\xdd\x58\xdd\x47\xaf"
+ "\x76\xf8\xe2\xc3\x6e\x28\xaf\x24\x76\xb4\xbc\xcf\x82\xe8\x9f\xdf",
+ 149 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x02\xd2\x61\xad\x56\xa5\x26\x33\x1b\x64\x3d\xd2\x18\x6d\xe9\xa8"
+ "\x2e\x72\xa5\x82\x23\xcd\x1e\x72\x36\x86\xc5\x3d\x86\x9b\x83\xb9"
+ "\x46\x32\xb7\xb6\x47\xab\x2a\xfc\x0d\x52\x2e\x29\xda\x3a\x56\x15"
+ "\xb7\x41\xd8\x28\x52\xe0\xdf\x41\xb6\x60\x07\xdb\xcb\xa9\x05\x43",
+ 150 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc5\x83\x27\x41\xfa\x30\xc5\x43\x68\x23\x01\x53\x83\xd2\x97\xff"
+ "\x4c\x4a\x5d\x72\x76\xc3\xf9\x02\x12\x20\x66\xe0\x4b\xe5\x43\x1b"
+ "\x1a\x85\xfa\xf7\x3b\x91\x84\x34\xf9\x30\x09\x63\xd1\xde\xa9\xe8"
+ "\xac\x39\x24\xef\x49\x02\x26\xed\xee\xa5\xf7\x43\xe4\x10\x66\x9f",
+ 151 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xcf\xae\xab\x26\x8c\xd0\x75\xa5\xa6\xae\xd5\x15\x02\x3a\x03\x2d"
+ "\x54\xf2\xf2\xff\x73\x3c\xe0\xcb\xc7\x8d\xb5\x1d\xb4\x50\x4d\x67"
+ "\x59\x23\xf8\x27\x46\xd6\x59\x46\x06\xad\x5d\x67\x73\x4b\x11\xa6"
+ "\x7c\xc6\xa4\x68\xc2\x03\x2e\x43\xca\x1a\x94\xc6\x27\x3a\x98\x5e",
+ 152 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x86\x08\x50\xf9\x2e\xb2\x68\x27\x2b\x67\xd1\x33\x60\x9b\xd6\x4e"
+ "\x34\xf6\x1b\xf0\x3f\x4c\x17\x38\x64\x5c\x17\xfe\xc8\x18\x46\x5d"
+ "\x7e\xcd\x2b\xe2\x90\x76\x41\x13\x00\x25\xfd\xa7\x94\x70\xab\x73"
+ "\x16\x46\xe7\xf6\x94\x40\xe8\x36\x7e\xa7\x6a\xc4\xce\xe8\xa1\xdf",
+ 153 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x84\xb1\x54\xed\x29\xbb\xed\xef\xa6\x48\x28\x68\x39\x04\x6f\x4b"
+ "\x5a\xa3\x44\x30\xe2\xd6\x7f\x74\x96\xe4\xc3\x9f\x2c\x7e\xa7\x89"
+ "\x95\xf6\x9e\x12\x92\x20\x00\x16\xf1\x6a\xc3\xb3\x77\x00\xe6\xc7"
+ "\xe7\x86\x1a\xfc\x39\x6b\x64\xa5\x9a\x1d\xbf\x47\xa5\x5c\x4b\xbc",
+ 154 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xae\xee\xc2\x60\xa5\xd8\xef\xf5\xcc\xab\x8b\x95\xda\x43\x5a\x63"
+ "\xed\x7a\x21\xea\x7f\xc7\x55\x94\x13\xfd\x61\x7e\x33\x60\x9f\x8c"
+ "\x29\x0e\x64\xbb\xac\xc5\x28\xf6\xc0\x80\x26\x22\x88\xb0\xf0\xa3"
+ "\x21\x9b\xe2\x23\xc9\x91\xbe\xe9\x2e\x72\x34\x95\x93\xe6\x76\x38",
+ 155 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x8a\xd7\x8a\x9f\x26\x60\x1d\x12\x7e\x8d\x2f\x2f\x97\x6e\x63\xd1"
+ "\x9a\x05\x4a\x17\xdc\xf5\x9e\x0f\x01\x3a\xb5\x4a\x68\x87\xbb\xdf"
+ "\xfd\xe7\xaa\xae\x11\x7e\x0f\xbf\x32\x71\x01\x65\x95\xb9\xd9\xc7"
+ "\x12\xc0\x1b\x2c\x53\xe9\x65\x5a\x38\x2b\xc4\x52\x2e\x61\x66\x45",
+ 156 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x89\x34\x15\x9d\xad\xe1\xac\x74\x14\x7d\xfa\x28\x2c\x75\x95\x4f"
+ "\xce\xf4\x43\xef\x25\xf8\x0d\xfe\x9f\xb6\xea\x63\x3b\x85\x45\x11"
+ "\x1d\x08\xb3\x4e\xf4\x3f\xff\x17\x02\x6c\x79\x64\xf5\xde\xac\x6d"
+ "\x2b\x3c\x29\xda\xcf\x27\x47\xf0\x22\xdf\x59\x67\xdf\xdc\x1a\x0a",
+ 157 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xcd\x36\xdd\x0b\x24\x06\x14\xcf\x2f\xa2\xb9\xe9\x59\x67\x9d\xcd"
+ "\xd7\x2e\xc0\xcd\x58\xa4\x3d\xa3\x79\x0a\x92\xf6\xcd\xeb\x9e\x1e"
+ "\x79\x5e\x47\x8a\x0a\x47\xd3\x71\x10\x0d\x34\x0c\x5c\xed\xcd\xbb"
+ "\xc9\xe6\x8b\x3f\x46\x08\x18\xe5\xbd\xff\x7b\x4c\xda\x4c\x27\x44",
+ 158 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x00\xdf\x4e\x09\x9b\x80\x71\x37\xa8\x59\x90\xf4\x9d\x3a\x94\x31"
+ "\x5e\x5a\x5f\x7f\x7a\x60\x76\xb3\x03\xe9\x6b\x05\x6f\xb9\x38\x00"
+ "\x11\x1f\x47\x96\x28\xe2\xf8\xdb\x59\xae\xb6\xac\x70\xc3\xb6\x1f"
+ "\x51\xf9\xb4\x6e\x80\xff\xde\xae\x25\xeb\xdd\xb4\xaf\x6c\xb4\xee",
+ 159 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x2b\x9c\x95\x5e\x6c\xae\xd4\xb7\xc9\xe2\x46\xb8\x6f\x9a\x17\x26"
+ "\xe8\x10\xc5\x9d\x12\x6c\xee\x66\xed\x71\xbf\x01\x5b\x83\x55\x8a"
+ "\x4b\x6d\x84\xd1\x8d\xc3\xff\x46\x20\xc2\xff\xb7\x22\x35\x9f\xde"
+ "\xf8\x5b\xa0\xd4\xe2\xd2\x2e\xcb\xe0\xed\x78\x4f\x99\xaf\xe5\x87",
+ 160 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x18\x1d\xf0\xa2\x61\xa2\xf7\xd2\x9e\xa5\xa1\x57\x72\x71\x51\x05"
+ "\xd4\x50\xa4\xb6\xc2\x36\xf6\x99\xf4\x62\xd6\x0c\xa7\x64\x87\xfe"
+ "\xed\xfc\x9f\x5e\xb9\x2d\xf8\x38\xe8\xfb\x5d\xc3\x69\x4e\x84\xc5"
+ "\xe0\xf4\xa1\x0b\x76\x1f\x50\x67\x62\xbe\x05\x2c\x74\x5a\x6e\xe8",
+ 161 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x21\xfb\x20\x34\x58\xbf\x3a\x7e\x9a\x80\x43\x9f\x9a\x90\x28\x99"
+ "\xcd\x5d\xe0\x13\x9d\xfd\x56\xf7\x11\x0c\x9d\xec\x84\x37\xb2\x6b"
+ "\xda\x63\xde\x2f\x56\x59\x26\xd8\x5e\xdb\x1d\x6c\x68\x25\x66\x97"
+ "\x43\xdd\x99\x92\x65\x3d\x13\x97\x95\x44\xd5\xdc\x82\x28\xbf\xaa",
+ 162 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xef\x02\x1f\x29\xc5\xff\xb8\x30\xe6\x4b\x9a\xa9\x05\x8d\xd6\x60"
+ "\xfd\x2f\xcb\x81\xc4\x97\xa7\xe6\x98\xbc\xfb\xf5\x9d\xe5\xad\x4a"
+ "\x86\xff\x93\xc1\x0a\x4b\x9d\x1a\xe5\x77\x47\x25\xf9\x07\x2d\xcd"
+ "\xe9\xe1\xf1\x99\xba\xb9\x1f\x8b\xff\x92\x18\x64\xaa\x50\x2e\xee",
+ 163 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb3\xcf\xda\x40\x52\x6b\x7f\x1d\x37\x56\x9b\xdf\xcd\xf9\x11\xe5"
+ "\xa6\xef\xe6\xb2\xec\x90\xa0\x45\x4c\x47\xb2\xc0\x46\xbf\x13\x0f"
+ "\xc3\xb3\x52\xb3\x4d\xf4\x81\x3d\x48\xd3\x3a\xb8\xe2\x69\xb6\x9b"
+ "\x07\x56\x76\xcb\x6d\x00\xa8\xdc\xf9\xe1\xf9\x67\xec\x19\x1b\x2c",
+ 164 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb4\xc6\xc3\xb2\x67\x07\x1e\xef\xb9\xc8\xc7\x2e\x0e\x2b\x94\x12"
+ "\x93\x64\x1f\x86\x73\xcb\x70\xc1\xcc\x26\xad\x1e\x73\xcf\x14\x17"
+ "\x55\x86\x0a\xd1\x9b\x34\xc2\xf3\x4e\xd3\x5b\xb5\x2e\xc4\x50\x7c"
+ "\xc1\xfe\x59\x04\x77\x43\xa5\xf0\xc6\xfe\xbd\xe6\x25\xe2\x60\x91",
+ 165 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x57\xa3\x4f\x2b\xcc\xa6\x0d\x4b\x85\x10\x3b\x83\x0c\x9d\x79\x52"
+ "\xa4\x16\xbe\x52\x63\xae\x42\x9c\x9e\x5e\x53\xfe\x85\x90\xa8\xf7"
+ "\x8e\xc6\x5a\x51\x10\x9e\xa8\x5d\xcd\xf7\xb6\x22\x3f\x9f\x2b\x34"
+ "\x05\x39\xfa\xd8\x19\x23\xdb\xf8\xed\xab\xf9\x51\x29\xe4\xdf\xf6",
+ 166 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x9c\xf4\x66\x62\xfc\xd6\x1a\x23\x22\x77\xb6\x85\x66\x3b\x8b\x5d"
+ "\xa8\x32\xdf\xd9\xa3\xb8\xcc\xfe\xec\x99\x3e\xc6\xac\x41\x5a\xd0"
+ "\x7e\x04\x8a\xdf\xe4\x14\xdf\x27\x27\x70\xdb\xa8\x67\xda\x5c\x12"
+ "\x24\xc6\xfd\x0a\xa0\xc2\x18\x7d\x42\x6a\xc6\x47\xe9\x88\x73\x61",
+ 167 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5c\xe1\x04\x2a\xb4\xd5\x42\xc2\xf9\xee\x9d\x17\x26\x2a\xf8\x16"
+ "\x40\x98\x93\x5b\xef\x17\x3d\x0e\x18\x48\x9b\x04\x84\x17\x46\xcd"
+ "\x2f\x2d\xf8\x66\xbd\x7d\xa6\xe5\xef\x90\x24\xc6\x48\x02\x3e\xc7"
+ "\x23\xab\x9c\x62\xfd\x80\x28\x57\x39\xd8\x4f\x15\xd2\xab\x51\x5a",
+ 168 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x84\x88\x39\x6b\xd4\xa8\x72\x9b\x7a\x47\x31\x78\xf2\x32\xda\xdf"
+ "\x3f\x0f\x8e\x22\x67\x8b\xa5\xa4\x3e\x04\x1e\x72\xda\x1e\x2c\xf8"
+ "\x21\x94\xc3\x07\x20\x7a\x54\xcb\x81\x56\x29\x33\x39\xea\xec\x69"
+ "\x3f\xf6\x6b\xfc\xd5\xef\xc6\x5e\x95\xe4\xec\xaf\x54\x53\x0a\xbd",
+ 169 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xf5\x98\xda\x90\x1c\x38\x35\xbc\xa5\x60\x77\x90\x37\xdf\xde\x9f"
+ "\x0c\x51\xdc\x61\xc0\xb7\x60\xfc\x15\x22\xd7\xb4\x70\xee\x63\xf5"
+ "\xbd\xc6\x49\x84\x76\xe8\x60\x49\xad\x86\xe4\xe2\x1a\xf2\x85\x4a"
+ "\x98\x4c\xc9\x05\x42\x7d\x2f\x17\xf6\x6b\x1f\x41\xc3\xda\x6f\x61",
+ 170 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5f\x93\x26\x97\x98\xcf\x02\x13\x21\x07\x33\x76\x60\xa8\xd7\xa1"
+ "\x77\x35\x4c\x02\x12\xeb\x93\xe5\x55\xe7\xc3\x7a\x08\xae\xf3\xd8"
+ "\xdc\xe0\x12\x17\x01\x1c\xd9\x65\xc0\x4d\xd2\xc1\x05\xf2\xe2\xb6"
+ "\xca\xe5\xe4\xe6\xbc\xaf\x09\xdf\xbe\xe3\xe0\xa6\xa6\x35\x7c\x37",
+ 171 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x0e\xcf\x58\x1d\x47\xba\xc9\x23\x09\x86\xfa\xab\xd7\x0c\x2f\x5b"
+ "\x80\xe9\x10\x66\xf0\xec\x55\xa8\x42\x93\x78\x82\x28\x6d\x2c\xa0"
+ "\x07\xbb\x4e\x97\x3b\x0b\x09\x1d\x52\x16\x7f\xf7\xc4\x00\x9c\x7a"
+ "\xb4\xad\x38\xff\xf1\xdc\xea\xcd\xb7\xbe\x81\xef\x4a\x45\x29\x52",
+ 172 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5a\xec\xa8\xab\xe1\x52\x85\x82\xb2\xa3\x07\xb4\x00\x95\x85\x49"
+ "\x8a\x3d\x46\x7c\xa6\x10\x1c\xb0\xc5\x12\x6f\x99\x76\x05\x6e\x9f"
+ "\xfc\x12\x3c\xc2\x0c\x30\x2b\x2a\x73\x7f\x49\x2c\x75\xd2\x1f\x01"
+ "\x51\x2c\x90\xca\x05\x41\xdf\xa5\x6e\x95\x0a\x32\x1d\xcb\x28\xd8",
+ 173 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x73\x2f\xbf\x8f\x1c\xb2\xb8\x32\x92\x63\xed\xe2\x78\x58\xfe\x46"
+ "\xf8\xd3\x35\x4d\x37\x6b\xcd\xa0\x54\x8e\x7c\xe1\xfa\x9d\xd1\x1f"
+ "\x85\xeb\x66\x1f\xe9\x50\xb5\x43\xaa\x63\x5c\xa4\xd3\xf0\x4e\xde"
+ "\x5b\x32\xd6\xb6\x56\xe5\xce\x1c\x44\xd3\x5c\x4a\x6c\x56\xcf\xf8",
+ 174 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd5\xe9\x38\x73\x5d\x63\x78\x8c\x80\x10\x0a\xef\xd1\x86\x48\xd1"
+ "\x8c\xf2\x72\xf6\x9f\x20\xff\x24\xcf\xe2\x89\x5c\x08\x8a\xd0\x8b"
+ "\x01\x04\xda\x16\x72\xa4\xeb\x26\xfc\x52\x54\x5c\xc7\xd7\xa0\x1b"
+ "\x26\x6c\xf5\x46\xc4\x03\xc4\x5b\xd1\x29\xeb\x41\xbd\xd9\x20\x0b",
+ 175 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x65\xa2\x45\xb4\x93\x52\xee\x29\x7d\x91\xaf\x8c\x8b\xe0\x05\x28"
+ "\xac\x6e\x04\x6d\xd8\x3a\xc7\xbd\x46\x5a\x98\x81\x6d\xd6\x8f\x3e"
+ "\x00\xe1\xae\x8f\x89\x53\x27\xa7\xe9\xa8\xc9\x32\x65\x98\x37\x9a"
+ "\x29\xc9\xfc\x91\xec\x0c\x6e\xef\x08\xf3\xe2\xb2\x16\xc1\x10\x08",
+ 176 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc9\x56\x54\xb6\x30\x19\x13\x0a\xb4\x5d\xd0\xfb\x49\x41\xb9\x8a"
+ "\xeb\x3a\xf2\xa1\x23\x91\x3e\xca\x2c\xe9\x9b\x3e\x97\x41\x0a\x7b"
+ "\xf8\x66\x1c\xc7\xfb\xaa\x2b\xc1\xcf\x2b\x13\x11\x3b\x1e\xd4\x0a"
+ "\x01\x18\xb8\x8e\x5f\xff\xc3\x54\x27\x59\xea\x00\x7e\xd4\xc5\x8d",
+ 177 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x1e\xb2\x62\xf3\x8f\xa4\x94\x43\x1f\x01\x7d\xad\x44\xc0\xdf\xb6"
+ "\x93\x24\xac\x03\x2f\x04\xb6\x57\xfc\x91\xa8\x86\x47\xbb\x74\x76"
+ "\x0f\x24\xe7\xc9\x56\x51\x4f\x0c\xf0\x02\x99\x0b\x18\x2c\x16\x42"
+ "\xb9\xb2\x42\x6e\x96\xa6\x11\x87\xe4\xe0\x12\xf0\x0e\x21\x7d\x84",
+ 178 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x3b\x95\x5a\xee\xbf\xa5\x15\x1a\xc1\xab\x8e\x3f\x5c\xc1\xe3\x76"
+ "\x70\x84\xc8\x42\xa5\x75\xd3\x62\x69\x83\x6e\x97\x35\x3d\x41\x62"
+ "\x2b\x73\x1d\xdd\xcd\x5f\x26\x95\x50\xa3\xa5\xb8\x7b\xe1\xe9\x03"
+ "\x26\x34\x0b\x6e\x0e\x62\x55\x58\x15\xd9\x60\x05\x97\xac\x6e\xf9",
+ 179 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x68\x28\x9f\x66\x05\x47\x3b\xa0\xe4\xf2\x41\xba\xf7\x47\x7a\x98"
+ "\x85\x42\x6a\x85\x8f\x19\xef\x2a\x18\xb0\xd4\x0e\xf8\xe4\x12\x82"
+ "\xed\x55\x26\xb5\x19\x79\x9e\x27\x0f\x13\x88\x13\x27\x91\x82\x78"
+ "\x75\x57\x11\x07\x1d\x85\x11\xfe\x96\x3e\x3b\x56\x06\xaa\x37\x16",
+ 180 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x80\xa3\x37\x87\x54\x26\x12\xc3\x8f\x6b\xcd\x7c\xd8\x6c\xab\x46"
+ "\x02\x27\x50\x9b\x1c\xba\xd5\xec\x40\x8a\x91\x41\x3d\x51\x15\x5a"
+ "\x04\x76\xda\xdb\xf3\xa2\x51\x8e\x4a\x6e\x77\xcc\x34\x66\x22\xe3"
+ "\x47\xa4\x69\xbf\x8b\xaa\x5f\x04\xeb\x2d\x98\x70\x53\x55\xd0\x63",
+ 181 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x34\x62\x9b\xc6\xd8\x31\x39\x1c\x4c\xdf\x8a\xf1\xb4\xb7\xb6\xb8"
+ "\xe8\xee\x17\xcf\x98\xc7\x0e\x5d\xd5\x86\xcd\x99\xf1\x4b\x11\xdf"
+ "\x94\x51\x66\x23\x6a\x95\x71\xe6\xd5\x91\xbb\x83\xee\x4d\x16\x4d"
+ "\x46\xf6\xb9\xd8\xef\x86\xff\x86\x5a\x81\xbf\xb9\x1b\x00\x42\x4b",
+ 182 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x8b\x7c\xc3\x39\x16\x38\x63\xbb\x43\x83\xe5\x42\xb0\xef\x0e\x7c"
+ "\xf3\x6b\x84\xad\x93\x2c\xdf\x5a\x80\x41\x9e\xc9\xad\x69\x2e\x7a"
+ "\x7e\x78\x4d\x2c\x7c\xb3\x79\x6a\x18\xb8\xf8\x00\x03\x5f\x3a\xa0"
+ "\x6c\x82\x41\x00\x61\x11\x20\xa7\xbd\xeb\x35\x61\x8c\xcb\x81\xb7",
+ 183 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x4f\x08\x4e\x49\x39\xdd\x5a\x7f\x5a\x65\x8f\xad\x58\xa1\x8a\x15"
+ "\xc2\x5c\x32\xec\x1c\x7f\xd5\xc5\xc6\xc3\xe8\x92\xb3\x97\x1a\xea"
+ "\xac\x30\x83\x04\xef\x17\xb1\xc4\x72\x39\xea\x4b\xb3\x98\xb3\xfd"
+ "\x6d\x45\x28\xd8\xde\x8e\x76\x8a\xe0\xf1\xa5\xa5\xc6\xb5\xc2\x97",
+ 184 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x48\xf4\x07\xa1\xaf\x5b\x80\x09\xb2\x05\x17\x42\xe8\xcf\x5c\xd5"
+ "\x65\x66\x69\xe7\xd7\x22\xee\x8e\x7b\xd2\x02\x06\x08\x49\x44\x21"
+ "\x68\xd8\xfa\xcc\x11\x7c\x01\x2b\xfb\x7b\xf4\x49\xd9\x9b\xef\xff"
+ "\x6a\x34\xae\xa2\x03\xf1\xd8\xd3\x52\x72\x2b\xe5\x01\x4e\xc8\x18",
+ 185 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa6\xaa\x82\xcd\x1e\x42\x6f\x9a\x73\xbf\xa3\x9a\x29\x03\x78\x76"
+ "\x11\x46\x55\xb8\xc2\x2d\x6d\x3f\xf8\xb6\x38\xae\x7d\xea\x6b\x17"
+ "\x84\x3e\x09\xe5\x2e\xb6\x6f\xa1\xe4\x75\xe4\xa8\xa3\xde\x42\x9b"
+ "\x7d\x0f\x4a\x77\x6f\xcb\x8b\xdc\x9b\x9f\xed\xe7\xd5\x2e\x81\x5f",
+ 186 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x58\x17\x02\x7d\x6b\xdd\x00\xc5\xdd\x10\xac\x59\x3c\xd5\x60\x37"
+ "\x22\x70\x77\x5a\x18\x52\x6d\x7e\x6f\x13\x87\x2a\x2e\x20\xea\xb6"
+ "\x64\x62\x5b\xe7\x16\x8a\xc4\xbd\x7c\x9e\x0c\xe7\xfc\x40\x99\xe0"
+ "\xf4\x84\x42\xe2\xc7\x67\x19\x1c\x6e\x12\x84\xe9\xb2\xcc\xea\x8c",
+ 187 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x08\xe4\x10\x28\x34\x0a\x45\xc7\x4e\x40\x52\xb3\xa8\xd6\x38\x9e"
+ "\x22\xe0\x43\xa1\xad\xab\x5e\x28\xd9\x76\x19\x45\x0d\x72\x34\x69"
+ "\xb6\x20\xca\xa5\x19\xb8\x1c\x14\x52\x38\x54\xf6\x19\xfd\x30\x27"
+ "\xe3\x84\x7b\xd0\x32\x76\xe6\x06\x04\xa8\x0d\xdb\x4d\xe8\x76\xd6",
+ 188 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x13\x0b\x84\x20\x53\x7e\xb0\x7d\x72\xab\xda\x07\xc8\x5a\xcb\xd8"
+ "\xb9\xa4\x4f\x16\x32\x1d\xd0\x42\x21\x45\xf8\x09\x67\x3d\x30\xf2"
+ "\xb5\x32\x13\x26\xe2\xbf\xf3\x17\xef\x3f\xef\x98\x3c\x51\xc4\xf8"
+ "\xab\x24\xa3\x25\xd2\x98\xe3\x4a\xfc\xe5\x69\xa8\x25\x55\x77\x4c",
+ 189 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xac\x49\xb8\x44\xaf\xaa\x01\x2e\x31\xc4\x74\xca\x26\x36\x48\x84"
+ "\x4f\xd2\xf6\x30\x79\x92\xc2\xf7\x52\xac\xa0\x2c\x38\x28\x96\x51"
+ "\x75\x79\x4d\xee\xe2\xd2\xee\x95\xc6\x1c\xd2\x84\xf6\xb5\xa2\xd7"
+ "\x5e\x2e\xf2\xb2\x9e\xe8\x14\x9e\x77\xfb\x81\x44\x7b\x2f\xd0\x4b",
+ 190 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb9\xd7\xca\x81\xcc\x60\xbb\x95\x78\xe4\x40\x24\xe5\xa0\xa0\xbe"
+ "\x80\xf2\x73\x36\xa6\xa9\xf4\xe5\x3d\xf3\x99\x9c\xb1\x91\x28\x0b"
+ "\x09\x0e\x2a\xc2\xd2\x9c\x5b\xaa\xd9\xd7\x14\x15\xbd\xc1\x29\xe6"
+ "\x9a\xa2\x66\x7a\xf6\xa7\xfd\x5e\x18\x9f\xcc\xdc\xee\x81\x73\x40",
+ 191 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa7\x55\xe1\x13\x38\x65\x72\xc7\x5c\xed\x61\xd7\x19\x70\x60\x70"
+ "\xb9\x14\x60\x48\xe4\x2a\x9f\x8c\xd3\x56\x67\xa0\x88\xb4\x2f\x08"
+ "\x80\x8a\xbd\xf7\x7e\x61\x8a\xbd\x95\x9a\xfc\x75\x73\x79\xca\x2c"
+ "\x00\xbc\xc1\xa4\x83\x90\xfa\x2b\xff\x61\x8b\x1e\x00\x78\xa6\x13",
+ 192 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa7\x3c\x7d\xeb\xed\x32\x6f\x1c\x0d\xb0\x79\x5e\xe7\xd6\xe3\x94"
+ "\x68\x94\xb8\x26\xb1\xf8\x10\x1c\x56\xc8\x23\xba\x17\x16\x83\x12"
+ "\xe7\xf5\x3f\xc7\xdb\xe5\x2c\x3e\x11\xe6\x98\x52\xc4\x04\x85\xe2"
+ "\xef\x18\x24\x77\x86\x2e\xa6\xa3\x4e\xc1\x36\xe2\xdf\xee\xa6\xf4",
+ 193 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6c\xb8\xf9\xd5\x2c\x56\xd8\x2c\xac\x28\xf3\x9e\xa1\x59\x3e\x8b"
+ "\xb2\x50\x62\x93\xac\x0d\x68\x37\x6a\x17\x09\xb6\x2a\x46\xdf\x14"
+ "\xa4\xae\x64\xb2\xd8\xfa\xb7\x67\x33\xa1\xce\xd2\xd5\x48\xe3\xf3"
+ "\xc6\xfc\xb4\x9d\x40\xc3\xd5\x80\x8e\x44\x9c\xd8\x3d\x1c\x2a\xa2",
+ 194 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x68\x3f\xa2\xb2\x36\x9a\x10\x16\x2c\x1c\x1c\x7b\x24\xbc\x97\x0e"
+ "\xe6\x7d\xa2\x20\x56\x4f\x32\x20\x3f\x62\x56\x96\xc0\x35\x2a\x0b"
+ "\x9a\xd9\x66\x24\x36\x2d\x95\x2d\x84\x46\x3c\x11\x06\xa2\xdb\xa7"
+ "\xa0\x92\x59\x98\x84\xb3\x5a\x0b\x89\xc8\xf1\xb6\xa9\xb5\xa6\x1e",
+ 195 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xaa\xd9\xad\x44\x61\x01\x18\xb7\x7d\x50\x8a\xeb\x1b\xbc\xd1\xc1"
+ "\xb7\xd0\x17\x13\x97\xfb\x51\x0a\x40\x1b\xbc\x0e\xc3\x46\x23\x67"
+ "\x0d\x86\xa2\xdc\x3c\x8f\x3a\xb5\xa2\x04\x4d\xf7\x30\x25\x67\x27"
+ "\x54\x5f\x08\x60\xce\x21\xa1\xea\xc7\x17\xdf\xc4\x8f\x5d\x22\x8e",
+ 196 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc4\x25\x78\xde\x23\xb4\xc9\x87\xd5\xe1\xac\x4d\x68\x9e\xd5\xde"
+ "\x4b\x04\x17\xf9\x70\x4b\xc6\xbc\xe9\x69\xfa\x13\x47\x15\x85\xd6"
+ "\x2c\x2c\xb1\x21\x2a\x94\x4f\x39\x7f\xc9\xca\x2c\x37\x47\xc3\xbe"
+ "\xb6\x94\xec\x4c\x5b\xe6\x88\x28\xdd\xa5\x3e\xf4\x3f\xae\xc6\xc0",
+ 197 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x47\x0f\x00\x84\x1e\xe8\x24\x4e\x63\xed\x2c\x7e\xa3\x0e\x2e\x41"
+ "\x98\x97\xc1\x97\x46\x2e\xcc\xce\xcf\x71\x3b\x42\xa5\x06\x5f\xff"
+ "\x59\x14\xbc\x9b\x79\xaf\xfe\x8f\x6b\x65\x78\x75\xe7\x89\xae\x21"
+ "\x3b\xd9\x14\xcd\x35\xbd\x17\x4d\x46\xe9\xd1\x8b\xd8\x43\x77\x3d",
+ 198 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x34\xfc\x42\x13\x73\x0f\x47\xa5\xe9\xa3\x58\x0f\x64\x3e\x12\x94"
+ "\x5c\xfc\xb3\x1b\xf2\x06\xf6\xad\x45\x0c\xe5\x28\xda\x3f\xa4\x32"
+ "\xe0\x05\xd6\xb0\xec\xce\x10\xdc\xa7\xc5\x99\x5f\x6a\xac\xc5\x15"
+ "\x0e\x1b\x00\x9e\x19\x75\x1e\x83\x09\xf8\x85\x95\x31\x84\x43\x74",
+ 199 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xfb\x3c\x1f\x0f\x56\xa5\x6f\x8e\x31\x6f\xdf\x5d\x85\x3c\x8c\x87"
+ "\x2c\x39\x63\x5d\x08\x36\x34\xc3\x90\x4f\xc3\xac\x07\xd1\xb5\x78"
+ "\xe8\x5f\xf0\xe4\x80\xe9\x2d\x44\xad\xe3\x3b\x62\xe8\x93\xee\x32"
+ "\x34\x3e\x79\xdd\xf6\xef\x29\x2e\x89\xb5\x82\xd3\x12\x50\x23\x14",
+ 200 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc7\xc9\x7f\xc6\x5d\xd2\xb9\xe3\xd3\xd6\x07\xd3\x15\x98\xd3\xf8"
+ "\x42\x61\xe9\x91\x92\x51\xe9\xc8\xe5\x7b\xb5\xf8\x29\x37\x7d\x5f"
+ "\x73\xea\xbb\xed\x55\xc6\xc3\x81\x18\x0f\x29\xad\x02\xe5\xbe\x79"
+ "\x7f\xfe\xc7\xe5\x7b\xde\xcb\xc5\x0a\xd3\xd0\x62\xf0\x99\x3a\xb0",
+ 201 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa5\x7a\x49\xcd\xbe\x67\xae\x7d\x9f\x79\x7b\xb5\xcc\x7e\xfc\x2d"
+ "\xf0\x7f\x4e\x1b\x15\x95\x5f\x85\xda\xe7\x4b\x76\xe2\xec\xb8\x5a"
+ "\xfb\x6c\xd9\xee\xed\x88\x88\xd5\xca\x3e\xc5\xab\x65\xd2\x7a\x7b"
+ "\x19\xe5\x78\x47\x57\x60\xa0\x45\xac\x3c\x92\xe1\x3a\x93\x8e\x77",
+ 202 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc7\x14\x3f\xce\x96\x14\xa1\x7f\xd6\x53\xae\xb1\x40\x72\x6d\xc9"
+ "\xc3\xdb\xb1\xde\x6c\xc5\x81\xb2\x72\x68\x97\xec\x24\xb7\xa5\x03"
+ "\x59\xad\x49\x22\x43\xbe\x66\xd9\xed\xd8\xc9\x33\xb5\xb8\x0e\x0b"
+ "\x91\xbb\x61\xea\x98\x05\x60\x06\x51\x69\x76\xfa\xe8\xd9\x9a\x35",
+ 203 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x65\xbb\x58\xd0\x7f\x93\x7e\x2d\x3c\x7e\x65\x38\x5f\x9c\x54\x73"
+ "\x0b\x70\x41\x05\xcc\xdb\x69\x1f\x6e\x14\x6d\x4e\xe8\xf6\xc0\x86"
+ "\xf4\x95\x11\x03\x51\x10\xa9\xad\x60\x31\xfd\xce\xb9\x43\xe0\xf9"
+ "\x61\x3b\xcb\x27\x6d\xd4\x0f\x06\x24\xef\x0f\x92\x4f\x80\x97\x83",
+ 204 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xe5\x40\x27\x7f\x68\x3b\x11\x86\xdd\x3b\x5b\x3f\x61\x43\x33\x96"
+ "\x58\x1a\x35\xfe\xb1\x20\x02\xbe\x8c\x6a\x62\x31\xfc\x40\xff\xa7"
+ "\x0f\x08\x08\x1b\xc5\x8b\x2d\x94\xf7\x64\x95\x43\x61\x4a\x43\x5f"
+ "\xaa\x2d\x62\x11\x0e\x13\xda\xbc\x7b\x86\x62\x9b\x63\xaf\x9c\x24",
+ 205 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x41\x85\x00\x87\x8c\x5f\xbc\xb5\x84\xc4\x32\xf4\x28\x5e\x05\xe4"
+ "\x9f\x2e\x3e\x07\x53\x99\xa0\xdb\xfc\xf8\x74\xeb\xf8\xc0\x3d\x02"
+ "\xbf\x16\xbc\x69\x89\xd1\x61\xc7\x7c\xa0\x78\x6b\x05\x05\x3c\x6c"
+ "\x70\x94\x33\x71\x23\x19\x19\x21\x28\x83\x5c\xf0\xb6\x60\x59\x5b",
+ 206 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x88\x90\x90\xdb\xb1\x94\x4b\xdc\x94\x33\xee\x5e\xf1\x01\x0c\x7a"
+ "\x4a\x24\xa8\xe7\x1e\xce\xa8\xe1\x2a\x31\x31\x8c\xe4\x9d\xca\xb0"
+ "\xac\xa5\xc3\x80\x23\x34\xaa\xb2\xcc\x84\xb1\x4c\x6b\x93\x21\xfe"
+ "\x58\x6b\xf3\xf8\x76\xf1\x9c\xd4\x06\xeb\x11\x27\xfb\x94\x48\x01",
+ 207 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x53\xb6\xa2\x89\x10\xaa\x92\xe2\x7e\x53\x6f\xb5\x49\xcf\x9b\x99"
+ "\x18\x79\x10\x60\x89\x8e\x0b\x9f\xe1\x83\x57\x7f\xf4\x3b\x5e\x9c"
+ "\x76\x89\xc7\x45\xb3\x2e\x41\x22\x69\x83\x7c\x31\xb8\x9e\x6c\xc1"
+ "\x2b\xf7\x6e\x13\xca\xd3\x66\xb7\x4e\xce\x48\xbb\x85\xfd\x09\xe9",
+ 208 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x7c\x09\x20\x80\xc6\xa8\x0d\x67\x24\x09\xd0\x81\xd3\xd1\x77\x10"
+ "\x6b\xcd\x63\x56\x77\x85\x14\x07\x19\x49\x09\x50\xae\x07\xae\x8f"
+ "\xca\xab\xba\xaa\xb3\x30\xcf\xbc\xf7\x37\x44\x82\xc2\x20\xaf\x2e"
+ "\xad\xee\xb7\x3d\xcb\xb3\x5e\xd8\x23\x34\x4e\x14\x4e\x7d\x48\x99",
+ 209 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x9c\xcd\xe5\x66\xd2\x40\x05\x09\x18\x11\x11\xf3\x2d\xde\x4c\xd6"
+ "\x32\x09\xfe\x59\xa3\x0c\x11\x45\x46\xad\x27\x76\xd8\x89\xa4\x1b"
+ "\xad\x8f\xa1\xbb\x46\x8c\xb2\xf9\xd4\x2c\xa9\x92\x8a\x77\x70\xfe"
+ "\xf8\xe8\xba\x4d\x0c\x81\x2d\x9a\x1e\x75\xc3\xd8\xd2\xcc\xd7\x5a",
+ 210 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6e\x29\x3b\xf5\xd0\x3f\xe4\x39\x77\xcf\xe3\xf5\x7c\xcd\xb3\xae"
+ "\x28\x2a\x85\x45\x5d\xca\x33\xf3\x7f\x4b\x74\xf8\x39\x8c\xc6\x12"
+ "\x43\x3d\x75\x5c\xbe\xc4\x12\xf8\xf8\x2a\x3b\xd3\xbc\x4a\x27\x8f"
+ "\x7e\xcd\x0d\xfa\x9b\xbd\xc4\x0b\xe7\xa7\x87\xc8\xf1\x59\xb2\xdf",
+ 211 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc5\x65\x46\xfb\x21\x78\x45\x6f\x33\x61\x64\xc1\x8b\x90\xde\xff"
+ "\xc8\x3a\xe2\xb5\xa3\xac\xa7\x7b\x68\x84\xd3\x6d\x2c\x1d\xb3\x95"
+ "\x01\xb3\xe6\x5e\x36\xc7\x58\xc6\x6e\x31\x88\x45\x1f\xdb\x35\x15"
+ "\xee\x16\x2c\x00\x1f\x06\xc3\xe8\xcb\x57\x3a\xdf\x30\xf7\xa1\x01",
+ 212 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6f\x82\xf8\x9f\x29\x9e\xbc\xa2\xfe\x01\x4b\x59\xbf\xfe\x1a\xa8"
+ "\x4e\x88\xb1\x91\x5f\xe2\x56\xaf\xb6\x46\xfd\x84\x48\xaf\x2b\x88"
+ "\x91\xa7\xfa\xb3\x7a\x4e\xa6\xf9\xa5\x0e\x6c\x31\x70\x39\xd8\xcf"
+ "\x87\x8f\x4c\x8e\x1a\x0d\xd4\x64\xf0\xb4\xd6\xff\x1c\x7e\xa8\x53",
+ 213 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x2b\x85\x99\xff\x9c\x3d\x61\x98\x63\x7a\xd5\x1e\x57\xd1\x99\x8b"
+ "\x0d\x75\x31\x3f\xe2\xdd\x61\xa5\x33\xc9\x64\xa6\xdd\x96\x07\xc6"
+ "\xf7\x23\xe9\x45\x2c\xe4\x6e\x01\x4b\x1c\x1d\x6d\xe7\x7b\xa5\xb8"
+ "\x8c\x91\x4d\x1c\x59\x7b\xf1\xea\xe1\x34\x74\xb4\x29\x0e\x89\xb2",
+ 214 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x08\xbf\x34\x6d\x38\xe1\xdf\x06\xc8\x26\x0e\xdb\x1d\xa7\x55\x79"
+ "\x27\x59\x48\xd5\xc0\xa0\xaa\x9e\xd2\x88\x6f\x88\x56\xde\x54\x17"
+ "\xa1\x56\x99\x87\x58\xf5\xb1\x7e\x52\xf1\x01\xca\x95\x7a\x71\x13"
+ "\x74\x73\xdf\xd1\x8d\x7d\x20\x9c\x4c\x10\xd9\x23\x3c\x93\x69\x1d",
+ 215 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6d\xf2\x15\x6d\x77\x31\x14\xd3\x10\xb6\x3d\xb9\xee\x53\x50\xd7"
+ "\x7e\x6b\xcf\x25\xb0\x5f\xcd\x91\x0f\x9b\x31\xbc\x42\xbb\x13\xfe"
+ "\x82\x25\xeb\xcb\x2a\x23\xa6\x22\x80\x77\x7b\x6b\xf7\x4e\x2c\xd0"
+ "\x91\x7c\x76\x40\xb4\x3d\xef\xe4\x68\xcd\x1e\x18\xc9\x43\xc6\x6a",
+ 216 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x7c\x70\x38\xbc\x13\xa9\x11\x51\x82\x8a\x5b\xa8\x2b\x4a\x96\x04"
+ "\x0f\x25\x8a\x4d\xfb\x1b\x13\x73\xf0\xd3\x59\x16\x8a\xfb\x05\x17"
+ "\xa2\x0b\x28\xa1\x2d\x36\x44\x04\x6b\xe6\x6b\x8d\x08\xd8\xae\x7f"
+ "\x6a\x92\x3e\xa1\xc0\x01\x87\xc6\xd1\x1d\xc5\x02\xba\xc7\x13\x05",
+ 217 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xbc\xd1\xb3\x0d\x80\x8f\xb7\x39\xb9\x87\xcb\xf1\x54\xbe\xa0\x0d"
+ "\xa9\xd4\x03\x80\xb8\x61\xd4\xc1\xd6\x37\x71\x22\xda\xdd\x61\xc0"
+ "\xe5\x90\x18\xb7\x19\x41\xcf\xb6\x2e\x00\xdc\xd7\x0a\xeb\x9a\xbf"
+ "\x04\x73\xe8\x0f\x0a\x7e\xca\x6b\x6d\xea\x24\x6a\xb2\x29\xdd\x2b",
+ 218 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x7e\xd4\x46\x8d\x96\x85\x30\xfe\x7a\xb2\xc3\x35\x40\xb2\x6d\x8c"
+ "\x3b\xd3\xed\x44\xb3\x4f\xbe\x8c\x2a\x9d\x7f\x80\x5b\x5a\xda\x0e"
+ "\xa2\x52\xee\xad\xe4\xfc\xe9\x7f\x89\x72\x8a\xd8\x5b\xc8\xbb\x24"
+ "\x30\xb1\xbe\xf2\xcd\xdd\x32\xc8\x44\x6e\x59\xb8\xe8\xba\x3c\x67",
+ 219 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x6d\x30\xb7\xc6\xce\x8a\x32\x36\xc0\xca\x2f\x8d\x72\x8b\x10\x88"
+ "\xca\x06\x98\x3a\x80\x43\xe6\x21\xd5\xdc\xf0\xc5\x37\xd1\x3b\x08"
+ "\x79\x1e\xde\xb0\x1a\x3c\xf0\x94\x3e\xc1\xc8\x90\xab\x6e\x29\xb1"
+ "\x46\xa2\x36\xcd\x46\xbc\xb9\xd9\x3b\xf5\x16\xfb\x67\xc6\x3f\xe5",
+ 220 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x97\xfe\x03\xce\xf3\x14\x38\x50\x89\x11\xbd\xed\x97\x59\x80\xa6"
+ "\x60\x29\x30\x5d\xc5\xe3\xfa\x8a\xd1\xb4\xfb\x22\xfc\xdf\x5a\x19"
+ "\xa7\x33\x32\x03\x27\xd8\xf7\x1c\xcf\x49\x6c\xb3\xa4\x4a\x77\xaf"
+ "\x56\xe3\xdd\xe7\x3d\x3a\x5f\x17\x68\x96\xcc\x57\xc9\xa5\xad\x99",
+ 221 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x78\x5a\x9d\x0f\xbd\x21\x13\x6d\xbc\xe8\xfa\x7e\xaf\xd6\x3c\x9d"
+ "\xad\x22\x00\x52\x97\x84\x16\xb3\x1d\x97\x53\xea\xa1\x49\x09\x78"
+ "\x47\xed\x9b\x30\xa6\x5c\x70\x50\x7e\xff\x01\x87\x91\x49\xed\x5c"
+ "\xf0\x47\x1d\x37\x79\x8e\xdc\x05\xab\xd5\x6a\xd4\xa2\xcc\xcb\x1d",
+ 222 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xad\x40\x8d\x2a\xbd\xdf\xd3\x7b\x3b\xf3\x47\x94\xc1\xa3\x37\x1d"
+ "\x92\x8e\xd7\xfc\x8d\x96\x62\x25\x33\x35\x84\xc5\x66\x58\x17\x83"
+ "\x2a\x37\xc0\x7f\x0d\xc7\xcb\x5a\xa8\x74\xcd\x7d\x20\xfe\x8f\xab"
+ "\x8e\xab\xcb\x9b\x33\xd2\xe0\x84\x1f\x6e\x20\x09\x60\x89\x9d\x95",
+ 223 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x97\x66\x8f\x74\x5b\x60\x32\xfc\x81\x5d\x95\x79\x32\x27\x69\xdc"
+ "\xcd\x95\x01\xa5\x08\x00\x29\xb8\xae\x82\x6b\xef\xb6\x74\x23\x31"
+ "\xbd\x9f\x76\xef\xeb\x3e\x2b\x8e\x81\xa9\x78\x6b\x28\x2f\x50\x68"
+ "\xa3\xa2\x42\x46\x97\xa7\x7c\x41\x87\x6b\x7e\x75\x3f\x4c\x77\x67",
+ 224 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x26\xbb\x98\x5f\x47\xe7\xfe\xe0\xcf\xd2\x52\xd4\xef\x96\xbe\xd4"
+ "\x2b\x9c\x37\x0c\x1c\x6a\x3e\x8c\x9e\xb0\x4e\xf7\xf7\x81\x8b\x83"
+ "\x3a\x0d\x1f\x04\x3e\xba\xfb\x91\x1d\xc7\x79\xe0\x27\x40\xa0\x2a"
+ "\x44\xd3\xa1\xea\x45\xed\x4a\xd5\x5e\x68\x6c\x92\x7c\xaf\xe9\x7e",
+ 225 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5b\xfe\x2b\x1d\xcf\x7f\xe9\xb9\x50\x88\xac\xed\xb5\x75\xc1\x90"
+ "\x16\xc7\x43\xb2\xe7\x63\xbf\x58\x51\xac\x40\x7c\x9e\xda\x43\x71"
+ "\x5e\xdf\xa4\x8b\x48\x25\x49\x2c\x51\x79\x59\x3f\xff\x21\x35\x1b"
+ "\x76\xe8\xb7\xe0\x34\xe4\xc5\x3c\x79\xf6\x1f\x29\xc4\x79\xbd\x08",
+ 226 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xc7\x65\x09\xef\x72\xf4\xa6\xf9\xc9\xc4\x06\x18\xed\x52\xb2\x08"
+ "\x4f\x83\x50\x22\x32\xe0\xac\x8b\xda\xf3\x26\x43\x68\xe4\xd0\x18"
+ "\x0f\x68\x54\xc4\xab\xf4\xf6\x50\x9c\x79\xca\xaf\xc4\x4c\xf3\x19"
+ "\x4a\xfc\x57\xbd\x07\x7b\xd7\xb3\xc9\xbd\xa3\xd4\xb8\x77\x58\x16",
+ 227 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd6\x6f\x2b\xea\xb9\x90\xe3\x54\xcc\xb9\x10\xe4\xe9\xc7\xac\x61"
+ "\x8c\x7b\x63\xef\x29\x2a\x96\xb5\x52\x34\x1d\xe7\x8d\xc4\x6d\x3e"
+ "\xc8\xcf\xab\xc6\x99\xb5\x0a\xf4\x1f\xda\x39\xcf\x1b\x01\x73\x66"
+ "\x09\x23\x51\x0a\xd6\x7f\xae\xde\xf5\x20\x7c\xff\xe8\x64\x1d\x20",
+ 228 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x7d\x8f\x06\x72\x99\x2b\x79\xbe\x3a\x36\x4d\x8e\x59\x04\xf4\xab"
+ "\x71\x3b\xbc\x8a\xb0\x1b\x4f\x30\x9a\xd8\xcc\xf2\x23\xce\x10\x34"
+ "\xa8\x60\xdc\xb0\xb0\x05\x50\x61\x2c\xc2\xfa\x17\xf2\x96\x9e\x18"
+ "\xf2\x2e\x14\x27\xd2\x54\xb4\xa8\x2b\x3a\x03\xa3\xeb\x39\x4a\xdf",
+ 229 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa5\x6d\x67\x25\xbf\xb3\xde\x47\xc1\x41\x4a\xdf\x25\xfc\x8f\x0f"
+ "\xc9\x84\x6f\x69\x87\x72\x2b\xc0\x63\x66\xd5\xca\x4e\x89\x72\x29"
+ "\x25\xeb\xbc\x88\x14\x18\x84\x40\x75\x39\x7a\x0c\xa8\x98\x42\xc7"
+ "\xb9\xe9\xe0\x7e\x1d\x9d\x18\x3e\xbe\xb3\x9e\x12\x0b\x48\x3b\xf7",
+ 230 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xaf\x5e\x03\xd7\xfe\x60\xc6\x7e\x10\x31\x33\x44\x43\x4e\x79\x48"
+ "\x5a\x03\xa7\x58\xd6\xdc\xe9\x85\x57\x47\x45\x76\x3c\x1c\x5c\x77"
+ "\xd4\xfb\x3e\x6f\xb1\x22\x30\x36\x83\x70\x99\x3b\xf9\x0f\xee\xd0"
+ "\xc5\xd1\x60\x75\x24\x56\x2d\x7c\x09\xc0\xc2\x10\xed\x39\x3d\x7c",
+ 231 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x7a\x20\x54\x0c\xc0\x7b\xf7\x2b\x58\x24\x21\xfc\x34\x2e\x82\xf5"
+ "\x21\x34\xb6\x98\x41\xec\x28\xed\x18\x9e\x2e\xa6\xa2\x9d\xd2\xf8"
+ "\x2a\x64\x03\x52\xd2\x22\xb5\x2f\x29\x11\xdc\x72\xa7\xda\xb3\x1c"
+ "\xaa\xdd\x80\xc6\x11\x8f\x13\xc5\x6b\x2a\x1e\x43\x73\xbe\x0e\xa3",
+ 232 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x48\x6f\x02\xc6\x3e\x54\x67\xea\x1f\xdd\xe7\xe8\x2b\xfa\xcc\x2c"
+ "\x1b\xa5\xd6\x36\xd9\xf3\xd0\x8b\x21\x0d\xa3\xf3\x72\xf7\x06\xec"
+ "\x21\x8c\xc1\x7f\xf6\x0a\xef\x70\x3b\xbe\x0c\x15\xc3\x8a\xe5\x5d"
+ "\x28\x6a\x68\x4f\x86\x4c\x78\x21\x1c\xca\xb4\x17\x8c\x92\xad\xba",
+ 233 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x1c\x7a\x5c\x1d\xed\xcd\x04\xa9\x21\x78\x8f\x7e\xb2\x33\x61\xca"
+ "\x19\x53\xb0\x4b\x9c\x7a\xec\x35\xd6\x5e\xa3\xe4\x99\x6d\xb2\x6f"
+ "\x28\x12\x78\xea\x4a\xe6\x66\xad\x81\x02\x7d\x98\xaf\x57\x26\x2c"
+ "\xdb\xfa\x4c\x08\x5f\x42\x10\x56\x8c\x7e\x15\xee\xc7\x80\x51\x14",
+ 234 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x9c\xe3\xfa\x9a\x86\x0b\xdb\xd5\x37\x8f\xd6\xd7\xb8\xb6\x71\xc6"
+ "\xcb\x76\x92\x91\x0c\xe8\xf9\xb6\xcb\x41\x22\xcb\xcb\xe6\xac\x06"
+ "\xca\x04\x22\xce\xf1\x22\x59\x35\x05\x3b\x7d\x19\x3a\x81\xb9\xe9"
+ "\x72\xeb\x85\xa1\xd3\x07\x4f\x14\xcb\xb5\xec\x9f\x05\x73\x89\x2d",
+ 235 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xa9\x11\x87\xbe\x5c\x37\x1c\x42\x65\xc1\x74\xfd\x46\x53\xb8\xab"
+ "\x70\x85\x51\xf8\x3d\x1f\xee\x1c\xc1\x47\x95\x81\xbc\x00\x6d\x6f"
+ "\xb7\x8f\xcc\x9a\x5d\xee\x1d\xb3\x66\x6f\x50\x8f\x97\x80\xa3\x75"
+ "\x93\xeb\xcc\xcf\x5f\xbe\xd3\x96\x67\xdc\x63\x61\xe9\x21\xf7\x79",
+ 236 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x46\x25\x76\x7d\x7b\x1d\x3d\x3e\xd2\xfb\xc6\x74\xaf\x14\xe0\x24"
+ "\x41\x52\xf2\xa4\x02\x1f\xcf\x33\x11\x50\x5d\x89\xbd\x81\xe2\xf9"
+ "\xf9\xa5\x00\xc3\xb1\x99\x91\x4d\xb4\x95\x00\xb3\xc9\x8d\x03\xea"
+ "\x93\x28\x67\x51\xa6\x86\xa3\xb8\x75\xda\xab\x0c\xcd\x63\xb4\x4f",
+ 237 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x43\xdf\xdf\xe1\xb0\x14\xfe\xd3\xa2\xac\xab\xb7\xf3\xe9\xa1\x82"
+ "\xf2\xaa\x18\x01\x9d\x27\xe3\xe6\xcd\xcf\x31\xa1\x5b\x42\x8e\x91"
+ "\xe7\xb0\x8c\xf5\xe5\xc3\x76\xfc\xe2\xd8\xa2\x8f\xf8\x5a\xb0\xa0"
+ "\xa1\x65\x6e\xdb\x4a\x0a\x91\x53\x26\x20\x09\x6d\x9a\x5a\x65\x2d",
+ 238 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x27\x9e\x32\x02\xbe\x39\x89\xba\x31\x12\x77\x25\x85\x17\x74\x87"
+ "\xe4\xfe\x3e\xe3\xea\xb4\x9c\x2f\x7f\xa7\xfe\x87\xcf\xe7\xb8\x0d"
+ "\x3e\x03\x55\xed\xff\x6d\x03\x1e\x6c\x96\xc7\x95\xdb\x1c\x6f\x04"
+ "\x18\x80\xec\x38\x24\xde\xfa\xcf\x92\x63\x82\x0a\x8e\x73\x27\xde",
+ 239 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xea\x2d\x06\x6a\xc2\x29\xd4\xd4\xb6\x16\xa8\xbe\xde\xc7\x34\x32"
+ "\x52\x24\xe4\xb4\xe5\x8f\x1a\xe6\xda\xd7\xe4\x0c\x2d\xa2\x91\x96"
+ "\xc3\xb1\xea\x95\x71\xda\xcc\x81\xe8\x73\x28\xca\xa0\x21\x1e\x09"
+ "\x02\x7b\x05\x24\xaa\x3f\x4a\x84\x99\x17\xb3\x58\x67\x47\xeb\xbb",
+ 240 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x49\xf0\x14\xf5\xc6\x18\x22\xc8\x99\xab\x5c\xae\x51\xbe\x40\x44"
+ "\xa4\x49\x5e\x77\x7d\xeb\x7d\xa9\xb6\xd8\x49\x0e\xfb\xb8\x75\x30"
+ "\xad\xf2\x93\xda\xf0\x79\xf9\x4c\x33\xb7\x04\x4e\xf6\x2e\x2e\x5b"
+ "\xb3\xeb\x11\xe1\x73\x04\xf8\x45\x3e\xe6\xce\x24\xf0\x33\xdd\xb0",
+ 241 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x92\x33\x49\x03\x44\xe5\xb0\xdc\x59\x12\x67\x1b\x7a\xe5\x4c\xee"
+ "\x77\x30\xdb\xe1\xf4\xc7\xd9\x2a\x4d\x3e\x3a\xab\x50\x57\x17\x08"
+ "\xdb\x51\xdc\xf9\xc2\x94\x45\x91\xdb\x65\x1d\xb3\x2d\x22\x93\x5b"
+ "\x86\x94\x49\x69\xbe\x77\xd5\xb5\xfe\xae\x6c\x38\x40\xa8\xdb\x26",
+ 242 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb6\xe7\x5e\x6f\x4c\x7f\x45\x3b\x74\x65\xd2\x5b\x5a\xc8\xc7\x19"
+ "\x69\x02\xea\xa9\x53\x87\x52\x28\xc8\x63\x4e\x16\xe2\xae\x1f\x38"
+ "\xbc\x32\x75\x30\x43\x35\xf5\x98\x9e\xcc\xc1\xe3\x41\x67\xd4\xe6"
+ "\x8d\x77\x19\x96\x8f\xba\x8e\x2f\xe6\x79\x47\xc3\x5c\x48\xe8\x06",
+ 243 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xcc\x14\xca\x66\x5a\xf1\x48\x3e\xfb\xc3\xaf\x80\x08\x0e\x65\x0d"
+ "\x50\x46\xa3\x93\x2f\x4f\x51\xf3\xfe\x90\xa0\x70\x5e\xc2\x51\x04"
+ "\xad\xf0\x78\x39\x26\x5d\xc5\x1d\x43\x40\x14\x11\x24\x6e\x47\x4f"
+ "\x0d\x5e\x56\x37\xaf\x94\x76\x72\x83\xd5\x3e\x06\x17\xe9\x81\xf4",
+ 244 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x23\x0a\x1c\x85\x7c\xb2\xe7\x85\x2e\x41\xb6\x47\xe9\x0e\x45\x85"
+ "\xd2\xd8\x81\xe1\x73\x4d\xc3\x89\x55\x35\x6e\x8d\xd7\xbf\xf3\x90"
+ "\x53\x09\x2c\x6b\x38\xe2\x36\xe1\x89\x95\x25\x64\x70\x73\xdd\xdf"
+ "\x68\x95\xd6\x42\x06\x32\x5e\x76\x47\xf2\x75\x56\x7b\x25\x59\x09",
+ 245 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xcb\xb6\x53\x21\xac\x43\x6e\x2f\xfd\xab\x29\x36\x35\x9c\xe4\x90"
+ "\x23\xf7\xde\xe7\x61\x4e\xf2\x8d\x17\x3c\x3d\x27\xc5\xd1\xbf\xfa"
+ "\x51\x55\x3d\x43\x3f\x8e\xe3\xc9\xe4\x9c\x05\xa2\xb8\x83\xcc\xe9"
+ "\x54\xc9\xa8\x09\x3b\x80\x61\x2a\x0c\xdd\x47\x32\xe0\x41\xf9\x95",
+ 246 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x3e\x7e\x57\x00\x74\x33\x72\x75\xef\xb5\x13\x15\x58\x80\x34\xc3"
+ "\xcf\x0d\xdd\xca\x20\xb4\x61\x2e\x0b\xd5\xb8\x81\xe7\xe5\x47\x6d"
+ "\x31\x9c\xe4\xfe\x9f\x19\x18\x6e\x4c\x08\x26\xf4\x4f\x13\x1e\xb0"
+ "\x48\xe6\x5b\xe2\x42\xb1\x17\x2c\x63\xba\xdb\x12\x3a\xb0\xcb\xe8",
+ 247 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xd3\x2e\x9e\xc0\x2d\x38\xd4\xe1\xb8\x24\x9d\xf8\xdc\xb0\x0c\x5b"
+ "\x9c\x68\xeb\x89\x22\x67\x2e\x35\x05\x39\x3b\x6a\x21\x0b\xa5\x6f"
+ "\x94\x96\xe5\xee\x04\x90\xef\x38\x7c\x3c\xde\xc0\x61\xf0\x6b\xc0"
+ "\x38\x2d\x93\x04\xca\xfb\xb8\xe0\xcd\x33\xd5\x70\x29\xe6\x2d\xf2",
+ 248 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x8c\x15\x12\x46\x60\x89\xf0\x5b\x37\x75\xc2\x62\xb6\x2d\x22\xb8"
+ "\x38\x54\xa8\x32\x18\x13\x0b\x4e\xc9\x1b\x3c\xcb\xd2\x93\xd2\xa5"
+ "\x43\x02\xce\xca\xab\x9b\x10\x0c\x68\xd1\xe6\xdd\xc8\xf0\x7c\xdd"
+ "\xbd\xfe\x6f\xda\xaa\xf0\x99\xcc\x09\xd6\xb7\x25\x87\x9c\x63\x69",
+ 249 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x91\xa7\xf6\x1c\x97\xc2\x91\x1e\x4c\x81\x2e\xf7\x1d\x78\x0a\xd8"
+ "\xfa\x78\x87\x94\x56\x1d\x08\x30\x3f\xd1\xc1\xcb\x60\x8a\x46\xa1"
+ "\x25\x63\x08\x6e\xc5\xb3\x9d\x47\x1a\xed\x94\xfb\x0f\x6c\x67\x8a"
+ "\x43\xb8\x79\x29\x32\xf9\x02\x8d\x77\x2a\x22\x76\x8e\xa2\x3a\x9b",
+ 250 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x4f\x6b\xb2\x22\xa3\x95\xe8\xb1\x8f\x6b\xa1\x55\x47\x7a\xed\x3f"
+ "\x07\x29\xac\x9e\x83\xe1\x6d\x31\xa2\xa8\xbc\x65\x54\x22\xb8\x37"
+ "\xc8\x91\xc6\x19\x9e\x6f\x0d\x75\x79\x9e\x3b\x69\x15\x25\xc5\x81"
+ "\x95\x35\x17\xf2\x52\xc4\xb9\xe3\xa2\x7a\x28\xfb\xaf\x49\x64\x4c",
+ 251 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5d\x06\xc0\x7e\x7a\x64\x6c\x41\x3a\x50\x1c\x3f\x4b\xb2\xfc\x38"
+ "\x12\x7d\xe7\x50\x9b\x70\x77\xc4\xd9\xb5\x61\x32\x01\xc1\xaa\x02"
+ "\xfd\x5f\x79\xd2\x74\x59\x15\xdd\x57\xfb\xcb\x4c\xe0\x86\x95\xf6"
+ "\xef\xc0\xcb\x3d\x2d\x33\x0e\x19\xb4\xb0\xe6\x00\x4e\xa6\x47\x1e",
+ 252 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xb9\x67\x56\xe5\x79\x09\x96\x8f\x14\xb7\x96\xa5\xd3\x0f\x4c\x9d"
+ "\x67\x14\x72\xcf\x82\xc8\xcf\xb2\xca\xca\x7a\xc7\xa4\x4c\xa0\xa1"
+ "\x4c\x98\x42\xd0\x0c\x82\xe3\x37\x50\x2c\x94\xd5\x96\x0a\xca\x4c"
+ "\x49\x2e\xa7\xb0\xdf\x91\x9d\xdf\x1a\xad\xa2\xa2\x75\xbb\x10\xd4",
+ 253 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\xff\x0a\x01\x5e\x98\xdb\x9c\x99\xf0\x39\x77\x71\x0a\xac\x3e\x65"
+ "\x8c\x0d\x89\x6f\x6d\x71\xd6\x18\xba\x79\xdc\x6c\xf7\x2a\xc7\x5b"
+ "\x7c\x03\x8e\xb6\x86\x2d\xed\xe4\x54\x3e\x14\x54\x13\xa6\x36\x8d"
+ "\x69\xf5\x72\x2c\x82\x7b\xa3\xef\x25\xb6\xae\x64\x40\xd3\x92\x76",
+ 254 },
+ { GCRY_MD_BLAKE2B_512, blake2_data_vector,
+ "\x5b\x21\xc5\xfd\x88\x68\x36\x76\x12\x47\x4f\xa2\xe7\x0e\x9c\xfa"
+ "\x22\x01\xff\xee\xe8\xfa\xfa\xb5\x79\x7a\xd5\x8f\xef\xa1\x7c\x9b"
+ "\x5b\x10\x7d\xa4\xa3\xdb\x63\x20\xba\xaf\x2c\x86\x17\xd5\xa5\x1d"
+ "\xf9\x14\xae\x88\xda\x38\x67\xc2\xd4\x1f\x0c\xc1\x4f\xa6\x79\x28",
+ 255 },
diff --git a/comm/third_party/libgcrypt/tests/blake2s.h b/comm/third_party/libgcrypt/tests/blake2s.h
new file mode 100644
index 0000000000..82e323795c
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/blake2s.h
@@ -0,0 +1,1027 @@
+/* Generated from https://raw.githubusercontent.com/BLAKE2/BLAKE2/master/testvectors/blake2-kat.h */
+
+ /* blake2s_kat[]: */
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x69\x21\x7a\x30\x79\x90\x80\x94\xe1\x11\x21\xd0\x42\x35\x4a\x7c"
+ "\x1f\x55\xb6\x48\x2c\xa1\xa5\x1e\x1b\x25\x0d\xfd\x1e\xd0\xee\xf9",
+ 0 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe3\x4d\x74\xdb\xaf\x4f\xf4\xc6\xab\xd8\x71\xcc\x22\x04\x51\xd2"
+ "\xea\x26\x48\x84\x6c\x77\x57\xfb\xaa\xc8\x2f\xe5\x1a\xd6\x4b\xea",
+ 1 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xdd\xad\x9a\xb1\x5d\xac\x45\x49\xba\x42\xf4\x9d\x26\x24\x96\xbe"
+ "\xf6\xc0\xba\xe1\xdd\x34\x2a\x88\x08\xf8\xea\x26\x7c\x6e\x21\x0c",
+ 2 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe8\xf9\x1c\x6e\xf2\x32\xa0\x41\x45\x2a\xb0\xe1\x49\x07\x0c\xdd"
+ "\x7d\xd1\x76\x9e\x75\xb3\xa5\x92\x1b\xe3\x78\x76\xc4\x5c\x99\x00",
+ 3 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x0c\xc7\x0e\x00\x34\x8b\x86\xba\x29\x44\xd0\xc3\x20\x38\xb2\x5c"
+ "\x55\x58\x4f\x90\xdf\x23\x04\xf5\x5f\xa3\x32\xaf\x5f\xb0\x1e\x20",
+ 4 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xec\x19\x64\x19\x10\x87\xa4\xfe\x9d\xf1\xc7\x95\x34\x2a\x02\xff"
+ "\xc1\x91\xa5\xb2\x51\x76\x48\x56\xae\x5b\x8b\x57\x69\xf0\xc6\xcd",
+ 5 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe1\xfa\x51\x61\x8d\x7d\xf4\xeb\x70\xcf\x0d\x5a\x9e\x90\x6f\x80"
+ "\x6e\x9d\x19\xf7\xf4\xf0\x1e\x3b\x62\x12\x88\xe4\x12\x04\x05\xd6",
+ 6 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x59\x80\x01\xfa\xfb\xe8\xf9\x4e\xc6\x6d\xc8\x27\xd0\x12\xcf\xcb"
+ "\xba\x22\x28\x56\x9f\x44\x8e\x89\xea\x22\x08\xc8\xbf\x76\x92\x93",
+ 7 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc7\xe8\x87\xb5\x46\x62\x36\x35\xe9\x3e\x04\x95\x59\x8f\x17\x26"
+ "\x82\x19\x96\xc2\x37\x77\x05\xb9\x3a\x1f\x63\x6f\x87\x2b\xfa\x2d",
+ 8 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc3\x15\xa4\x37\xdd\x28\x06\x2a\x77\x0d\x48\x19\x67\x13\x6b\x1b"
+ "\x5e\xb8\x8b\x21\xee\x53\xd0\x32\x9c\x58\x97\x12\x6e\x9d\xb0\x2c",
+ 9 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xbb\x47\x3d\xed\xdc\x05\x5f\xea\x62\x28\xf2\x07\xda\x57\x53\x47"
+ "\xbb\x00\x40\x4c\xd3\x49\xd3\x8c\x18\x02\x63\x07\xa2\x24\xcb\xff",
+ 10 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x68\x7e\x18\x73\xa8\x27\x75\x91\xbb\x33\xd9\xad\xf9\xa1\x39\x12"
+ "\xef\xef\xe5\x57\xca\xfc\x39\xa7\x95\x26\x23\xe4\x72\x55\xf1\x6d",
+ 11 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x1a\xc7\xba\x75\x4d\x6e\x2f\x94\xe0\xe8\x6c\x46\xbf\xb2\x62\xab"
+ "\xbb\x74\xf4\x50\xef\x45\x6d\x6b\x4d\x97\xaa\x80\xce\x6d\xa7\x67",
+ 12 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x01\x2c\x97\x80\x96\x14\x81\x6b\x5d\x94\x94\x47\x7d\x4b\x68\x7d"
+ "\x15\xb9\x6e\xb6\x9c\x0e\x80\x74\xa8\x51\x6f\x31\x22\x4b\x5c\x98",
+ 13 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x91\xff\xd2\x6c\xfa\x4d\xa5\x13\x4c\x7e\xa2\x62\xf7\x88\x9c\x32"
+ "\x9f\x61\xf6\xa6\x57\x22\x5c\xc2\x12\xf4\x00\x56\xd9\x86\xb3\xf4",
+ 14 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xd9\x7c\x82\x8d\x81\x82\xa7\x21\x80\xa0\x6a\x78\x26\x83\x30\x67"
+ "\x3f\x7c\x4e\x06\x35\x94\x7c\x04\xc0\x23\x23\xfd\x45\xc0\xa5\x2d",
+ 15 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xef\xc0\x4c\xdc\x39\x1c\x7e\x91\x19\xbd\x38\x66\x8a\x53\x4e\x65"
+ "\xfe\x31\x03\x6d\x6a\x62\x11\x2e\x44\xeb\xeb\x11\xf9\xc5\x70\x80",
+ 16 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x99\x2c\xf5\xc0\x53\x44\x2a\x5f\xbc\x4f\xaf\x58\x3e\x04\xe5\x0b"
+ "\xb7\x0d\x2f\x39\xfb\xb6\xa5\x03\xf8\x9e\x56\xa6\x3e\x18\x57\x8a",
+ 17 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x38\x64\x0e\x9f\x21\x98\x3e\x67\xb5\x39\xca\xcc\xae\x5e\xcf\x61"
+ "\x5a\xe2\x76\x4f\x75\xa0\x9c\x9c\x59\xb7\x64\x83\xc1\xfb\xc7\x35",
+ 18 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x21\x3d\xd3\x4c\x7e\xfe\x4f\xb2\x7a\x6b\x35\xf6\xb4\x00\x0d\x1f"
+ "\xe0\x32\x81\xaf\x3c\x72\x3e\x5c\x9f\x94\x74\x7a\x5f\x31\xcd\x3b",
+ 19 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xec\x24\x6e\xee\xb9\xce\xd3\xf7\xad\x33\xed\x28\x66\x0d\xd9\xbb"
+ "\x07\x32\x51\x3d\xb4\xe2\xfa\x27\x8b\x60\xcd\xe3\x68\x2a\x4c\xcd",
+ 20 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xac\x9b\x61\xd4\x46\x64\x8c\x30\x05\xd7\x89\x2b\xf3\xa8\x71\x9f"
+ "\x4c\x81\x81\xcf\xdc\xbc\x2b\x79\xfe\xf1\x0a\x27\x9b\x91\x10\x95",
+ 21 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x7b\xf8\xb2\x29\x59\xe3\x4e\x3a\x43\xf7\x07\x92\x23\xe8\x3a\x97"
+ "\x54\x61\x7d\x39\x1e\x21\x3d\xfd\x80\x8e\x41\xb9\xbe\xad\x4c\xe7",
+ 22 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x68\xd4\xb5\xd4\xfa\x0e\x30\x2b\x64\xcc\xc5\xaf\x79\x29\x13\xac"
+ "\x4c\x88\xec\x95\xc0\x7d\xdf\x40\x69\x42\x56\xeb\x88\xce\x9f\x3d",
+ 23 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb2\xc2\x42\x0f\x05\xf9\xab\xe3\x63\x15\x91\x93\x36\xb3\x7e\x4e"
+ "\x0f\xa3\x3f\xf7\xe7\x6a\x49\x27\x67\x00\x6f\xdb\x5d\x93\x54\x62",
+ 24 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x13\x4f\x61\xbb\xd0\xbb\xb6\x9a\xed\x53\x43\x90\x45\x51\xa3\xe6"
+ "\xc1\xaa\x7d\xcd\xd7\x7e\x90\x3e\x70\x23\xeb\x7c\x60\x32\x0a\xa7",
+ 25 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x46\x93\xf9\xbf\xf7\xd4\xf3\x98\x6a\x7d\x17\x6e\x6e\x06\xf7\x2a"
+ "\xd1\x49\x0d\x80\x5c\x99\xe2\x53\x47\xb8\xde\x77\xb4\xdb\x6d\x9b",
+ 26 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x85\x3e\x26\xf7\x41\x95\x3b\x0f\xd5\xbd\xb4\x24\xe8\xab\x9e\x8b"
+ "\x37\x50\xea\xa8\xef\x61\xe4\x79\x02\xc9\x1e\x55\x4e\x9c\x73\xb9",
+ 27 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf7\xde\x53\x63\x61\xab\xaa\x0e\x15\x81\x56\xcf\x0e\xa4\xf6\x3a"
+ "\x99\xb5\xe4\x05\x4f\x8f\xa4\xc9\xd4\x5f\x62\x85\xca\xd5\x56\x94",
+ 28 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x4c\x23\x06\x08\x86\x0a\x99\xae\x8d\x7b\xd5\xc2\xcc\x17\xfa\x52"
+ "\x09\x6b\x9a\x61\xbe\xdb\x17\xcb\x76\x17\x86\x4a\xd2\x9c\xa7\xa6",
+ 29 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xae\xb9\x20\xea\x87\x95\x2d\xad\xb1\xfb\x75\x92\x91\xe3\x38\x81"
+ "\x39\xa8\x72\x86\x50\x01\x88\x6e\xd8\x47\x52\xe9\x3c\x25\x0c\x2a",
+ 30 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xab\xa4\xad\x9b\x48\x0b\x9d\xf3\xd0\x8c\xa5\xe8\x7b\x0c\x24\x40"
+ "\xd4\xe4\xea\x21\x22\x4c\x2e\xb4\x2c\xba\xe4\x69\xd0\x89\xb9\x31",
+ 31 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x05\x82\x56\x07\xd7\xfd\xf2\xd8\x2e\xf4\xc3\xc8\xc2\xae\xa9\x61"
+ "\xad\x98\xd6\x0e\xdf\xf7\xd0\x18\x98\x3e\x21\x20\x4c\x0d\x93\xd1",
+ 32 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa7\x42\xf8\xb6\xaf\x82\xd8\xa6\xca\x23\x57\xc5\xf1\xcf\x91\xde"
+ "\xfb\xd0\x66\x26\x7d\x75\xc0\x48\xb3\x52\x36\x65\x85\x02\x59\x62",
+ 33 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2b\xca\xc8\x95\x99\x00\x0b\x42\xc9\x5a\xe2\x38\x35\xa7\x13\x70"
+ "\x4e\xd7\x97\x89\xc8\x4f\xef\x14\x9a\x87\x4f\xf7\x33\xf0\x17\xa2",
+ 34 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xac\x1e\xd0\x7d\x04\x8f\x10\x5a\x9e\x5b\x7a\xb8\x5b\x09\xa4\x92"
+ "\xd5\xba\xff\x14\xb8\xbf\xb0\xe9\xfd\x78\x94\x86\xee\xa2\xb9\x74",
+ 35 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe4\x8d\x0e\xcf\xaf\x49\x7d\x5b\x27\xc2\x5d\x99\xe1\x56\xcb\x05"
+ "\x79\xd4\x40\xd6\xe3\x1f\xb6\x24\x73\x69\x6d\xbf\x95\xe0\x10\xe4",
+ 36 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x12\xa9\x1f\xad\xf8\xb2\x16\x44\xfd\x0f\x93\x4f\x3c\x4a\x8f\x62"
+ "\xba\x86\x2f\xfd\x20\xe8\xe9\x61\x15\x4c\x15\xc1\x38\x84\xed\x3d",
+ 37 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x7c\xbe\xe9\x6e\x13\x98\x97\xdc\x98\xfb\xef\x3b\xe8\x1a\xd4\xd9"
+ "\x64\xd2\x35\xcb\x12\x14\x1f\xb6\x67\x27\xe6\xe5\xdf\x73\xa8\x78",
+ 38 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xeb\xf6\x6a\xbb\x59\x7a\xe5\x72\xa7\x29\x7c\xb0\x87\x1e\x35\x5a"
+ "\xcc\xaf\xad\x83\x77\xb8\xe7\x8b\xf1\x64\xce\x2a\x18\xde\x4b\xaf",
+ 39 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x71\xb9\x33\xb0\x7e\x4f\xf7\x81\x8c\xe0\x59\xd0\x08\x82\x9e\x45"
+ "\x3c\x6f\xf0\x2e\xc0\xa7\xdb\x39\x3f\xc2\xd8\x70\xf3\x7a\x72\x86",
+ 40 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x7c\xf7\xc5\x13\x31\x22\x0b\x8d\x3e\xba\xed\x9c\x29\x39\x8a\x16"
+ "\xd9\x81\x56\xe2\x61\x3c\xb0\x88\xf2\xb0\xe0\x8a\x1b\xe4\xcf\x4f",
+ 41 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x3e\x41\xa1\x08\xe0\xf6\x4a\xd2\x76\xb9\x79\xe1\xce\x06\x82\x79"
+ "\xe1\x6f\x7b\xc7\xe4\xaa\x1d\x21\x1e\x17\xb8\x11\x61\xdf\x16\x02",
+ 42 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x88\x65\x02\xa8\x2a\xb4\x7b\xa8\xd8\x67\x10\xaa\x9d\xe3\xd4\x6e"
+ "\xa6\x5c\x47\xaf\x6e\xe8\xde\x45\x0c\xce\xb8\xb1\x1b\x04\x5f\x50",
+ 43 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc0\x21\xbc\x5f\x09\x54\xfe\xe9\x4f\x46\xea\x09\x48\x7e\x10\xa8"
+ "\x48\x40\xd0\x2f\x64\x81\x0b\xc0\x8d\x9e\x55\x1f\x7d\x41\x68\x14",
+ 44 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x20\x30\x51\x6e\x8a\x5f\xe1\x9a\xe7\x9c\x33\x6f\xce\x26\x38\x2a"
+ "\x74\x9d\x3f\xd0\xec\x91\xe5\x37\xd4\xbd\x23\x58\xc1\x2d\xfb\x22",
+ 45 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x55\x66\x98\xda\xc8\x31\x7f\xd3\x6d\xfb\xdf\x25\xa7\x9c\xb1\x12"
+ "\xd5\x42\x58\x60\x60\x5c\xba\xf5\x07\xf2\x3b\xf7\xe9\xf4\x2a\xfe",
+ 46 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2f\x86\x7b\xa6\x77\x73\xfd\xc3\xe9\x2f\xce\xd9\x9a\x64\x09\xad"
+ "\x39\xd0\xb8\x80\xfd\xe8\xf1\x09\xa8\x17\x30\xc4\x45\x1d\x01\x78",
+ 47 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x17\x2e\xc2\x18\xf1\x19\xdf\xae\x98\x89\x6d\xff\x29\xdd\x98\x76"
+ "\xc9\x4a\xf8\x74\x17\xf9\xae\x4c\x70\x14\xbb\x4e\x4b\x96\xaf\xc7",
+ 48 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x3f\x85\x81\x4a\x18\x19\x5f\x87\x9a\xa9\x62\xf9\x5d\x26\xbd\x82"
+ "\xa2\x78\xf2\xb8\x23\x20\x21\x8f\x6b\x3b\xd6\xf7\xf6\x67\xa6\xd9",
+ 49 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x1b\x61\x8f\xba\xa5\x66\xb3\xd4\x98\xc1\x2e\x98\x2c\x9e\xc5\x2e"
+ "\x4d\xa8\x5a\x8c\x54\xf3\x8f\x34\xc0\x90\x39\x4f\x23\xc1\x84\xc1",
+ 50 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x0c\x75\x8f\xb5\x69\x2f\xfd\x41\xa3\x57\x5d\x0a\xf0\x0c\xc7\xfb"
+ "\xf2\xcb\xe5\x90\x5a\x58\x32\x3a\x88\xae\x42\x44\xf6\xe4\xc9\x93",
+ 51 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa9\x31\x36\x0c\xad\x62\x8c\x7f\x12\xa6\xc1\xc4\xb7\x53\xb0\xf4"
+ "\x06\x2a\xef\x3c\xe6\x5a\x1a\xe3\xf1\x93\x69\xda\xdf\x3a\xe2\x3d",
+ 52 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xcb\xac\x7d\x77\x3b\x1e\x3b\x3c\x66\x91\xd7\xab\xb7\xe9\xdf\x04"
+ "\x5c\x8b\xa1\x92\x68\xde\xd1\x53\x20\x7f\x5e\x80\x43\x52\xec\x5d",
+ 53 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x23\xa1\x96\xd3\x80\x2e\xd3\xc1\xb3\x84\x01\x9a\x82\x32\x58\x40"
+ "\xd3\x2f\x71\x95\x0c\x45\x80\xb0\x34\x45\xe0\x89\x8e\x14\x05\x3c",
+ 54 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf4\x49\x54\x70\xf2\x26\xc8\xc2\x14\xbe\x08\xfd\xfa\xd4\xbc\x4a"
+ "\x2a\x9d\xbe\xa9\x13\x6a\x21\x0d\xf0\xd4\xb6\x49\x29\xe6\xfc\x14",
+ 55 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe2\x90\xdd\x27\x0b\x46\x7f\x34\xab\x1c\x00\x2d\x34\x0f\xa0\x16"
+ "\x25\x7f\xf1\x9e\x58\x33\xfd\xbb\xf2\xcb\x40\x1c\x3b\x28\x17\xde",
+ 56 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9f\xc7\xb5\xde\xd3\xc1\x50\x42\xb2\xa6\x58\x2d\xc3\x9b\xe0\x16"
+ "\xd2\x4a\x68\x2d\x5e\x61\xad\x1e\xff\x9c\x63\x30\x98\x48\xf7\x06",
+ 57 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x8c\xca\x67\xa3\x6d\x17\xd5\xe6\x34\x1c\xb5\x92\xfd\x7b\xef\x99"
+ "\x26\xc9\xe3\xaa\x10\x27\xea\x11\xa7\xd8\xbd\x26\x0b\x57\x6e\x04",
+ 58 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x40\x93\x92\xf5\x60\xf8\x68\x31\xda\x43\x73\xee\x5e\x00\x74\x26"
+ "\x05\x95\xd7\xbc\x24\x18\x3b\x60\xed\x70\x0d\x45\x83\xd3\xf6\xf0",
+ 59 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x28\x02\x16\x5d\xe0\x90\x91\x55\x46\xf3\x39\x8c\xd8\x49\x16\x4a"
+ "\x19\xf9\x2a\xdb\xc3\x61\xad\xc9\x9b\x0f\x20\xc8\xea\x07\x10\x54",
+ 60 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xad\x83\x91\x68\xd9\xf8\xa4\xbe\x95\xba\x9e\xf9\xa6\x92\xf0\x72"
+ "\x56\xae\x43\xfe\x6f\x98\x64\xe2\x90\x69\x1b\x02\x56\xce\x50\xa9",
+ 61 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x75\xfd\xaa\x50\x38\xc2\x84\xb8\x6d\x6e\x8a\xff\xe8\xb2\x80\x7e"
+ "\x46\x7b\x86\x60\x0e\x79\xaf\x36\x89\xfb\xc0\x63\x28\xcb\xf8\x94",
+ 62 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe5\x7c\xb7\x94\x87\xdd\x57\x90\x24\x32\xb2\x50\x73\x38\x13\xbd"
+ "\x96\xa8\x4e\xfc\xe5\x9f\x65\x0f\xac\x26\xe6\x69\x6a\xef\xaf\xc3",
+ 63 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x56\xf3\x4e\x8b\x96\x55\x7e\x90\xc1\xf2\x4b\x52\xd0\xc8\x9d\x51"
+ "\x08\x6a\xcf\x1b\x00\xf6\x34\xcf\x1d\xde\x92\x33\xb8\xea\xaa\x3e",
+ 64 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x1b\x53\xee\x94\xaa\xf3\x4e\x4b\x15\x9d\x48\xde\x35\x2c\x7f\x06"
+ "\x61\xd0\xa4\x0e\xdf\xf9\x5a\x0b\x16\x39\xb4\x09\x0e\x97\x44\x72",
+ 65 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x05\x70\x5e\x2a\x81\x75\x7c\x14\xbd\x38\x3e\xa9\x8d\xda\x54\x4e"
+ "\xb1\x0e\x6b\xc0\x7b\xae\x43\x5e\x25\x18\xdb\xe1\x33\x52\x53\x75",
+ 66 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xd8\xb2\x86\x6e\x8a\x30\x9d\xb5\x3e\x52\x9e\xc3\x29\x11\xd8\x2f"
+ "\x5c\xa1\x6c\xff\x76\x21\x68\x91\xa9\x67\x6a\xa3\x1a\xaa\x6c\x42",
+ 67 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf5\x04\x1c\x24\x12\x70\xeb\x04\xc7\x1e\xc2\xc9\x5d\x4c\x38\xd8"
+ "\x03\xb1\x23\x7b\x0f\x29\xfd\x4d\xb3\xeb\x39\x76\x69\xe8\x86\x99",
+ 68 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9a\x4c\xe0\x77\xc3\x49\x32\x2f\x59\x5e\x0e\xe7\x9e\xd0\xda\x5f"
+ "\xab\x66\x75\x2c\xbf\xef\x8f\x87\xd0\xe9\xd0\x72\x3c\x75\x30\xdd",
+ 69 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x65\x7b\x09\xf3\xd0\xf5\x2b\x5b\x8f\x2f\x97\x16\x3a\x0e\xdf\x0c"
+ "\x04\xf0\x75\x40\x8a\x07\xbb\xeb\x3a\x41\x01\xa8\x91\x99\x0d\x62",
+ 70 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x1e\x3f\x7b\xd5\xa5\x8f\xa5\x33\x34\x4a\xa8\xed\x3a\xc1\x22\xbb"
+ "\x9e\x70\xd4\xef\x50\xd0\x04\x53\x08\x21\x94\x8f\x5f\xe6\x31\x5a",
+ 71 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x80\xdc\xcf\x3f\xd8\x3d\xfd\x0d\x35\xaa\x28\x58\x59\x22\xab\x89"
+ "\xd5\x31\x39\x97\x67\x3e\xaf\x90\x5c\xea\x9c\x0b\x22\x5c\x7b\x5f",
+ 72 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x8a\x0d\x0f\xbf\x63\x77\xd8\x3b\xb0\x8b\x51\x4b\x4b\x1c\x43\xac"
+ "\xc9\x5d\x75\x17\x14\xf8\x92\x56\x45\xcb\x6b\xc8\x56\xca\x15\x0a",
+ 73 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9f\xa5\xb4\x87\x73\x8a\xd2\x84\x4c\xc6\x34\x8a\x90\x19\x18\xf6"
+ "\x59\xa3\xb8\x9e\x9c\x0d\xfe\xea\xd3\x0d\xd9\x4b\xcf\x42\xef\x8e",
+ 74 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x80\x83\x2c\x4a\x16\x77\xf5\xea\x25\x60\xf6\x68\xe9\x35\x4d\xd3"
+ "\x69\x97\xf0\x37\x28\xcf\xa5\x5e\x1b\x38\x33\x7c\x0c\x9e\xf8\x18",
+ 75 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xab\x37\xdd\xb6\x83\x13\x7e\x74\x08\x0d\x02\x6b\x59\x0b\x96\xae"
+ "\x9b\xb4\x47\x72\x2f\x30\x5a\x5a\xc5\x70\xec\x1d\xf9\xb1\x74\x3c",
+ 76 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x3e\xe7\x35\xa6\x94\xc2\x55\x9b\x69\x3a\xa6\x86\x29\x36\x1e\x15"
+ "\xd1\x22\x65\xad\x6a\x3d\xed\xf4\x88\xb0\xb0\x0f\xac\x97\x54\xba",
+ 77 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xd6\xfc\xd2\x32\x19\xb6\x47\xe4\xcb\xd5\xeb\x2d\x0a\xd0\x1e\xc8"
+ "\x83\x8a\x4b\x29\x01\xfc\x32\x5c\xc3\x70\x19\x81\xca\x6c\x88\x8b",
+ 78 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x05\x20\xec\x2f\x5b\xf7\xa7\x55\xda\xcb\x50\xc6\xbf\x23\x3e\x35"
+ "\x15\x43\x47\x63\xdb\x01\x39\xcc\xd9\xfa\xef\xbb\x82\x07\x61\x2d",
+ 79 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xaf\xf3\xb7\x5f\x3f\x58\x12\x64\xd7\x66\x16\x62\xb9\x2f\x5a\xd3"
+ "\x7c\x1d\x32\xbd\x45\xff\x81\xa4\xed\x8a\xdc\x9e\xf3\x0d\xd9\x89",
+ 80 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xd0\xdd\x65\x0b\xef\xd3\xba\x63\xdc\x25\x10\x2c\x62\x7c\x92\x1b"
+ "\x9c\xbe\xb0\xb1\x30\x68\x69\x35\xb5\xc9\x27\xcb\x7c\xcd\x5e\x3b",
+ 81 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe1\x14\x98\x16\xb1\x0a\x85\x14\xfb\x3e\x2c\xab\x2c\x08\xbe\xe9"
+ "\xf7\x3c\xe7\x62\x21\x70\x12\x46\xa5\x89\xbb\xb6\x73\x02\xd8\xa9",
+ 82 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x7d\xa3\xf4\x41\xde\x90\x54\x31\x7e\x72\xb5\xdb\xf9\x79\xda\x01"
+ "\xe6\xbc\xee\xbb\x84\x78\xea\xe6\xa2\x28\x49\xd9\x02\x92\x63\x5c",
+ 83 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x12\x30\xb1\xfc\x8a\x7d\x92\x15\xed\xc2\xd4\xa2\xde\xcb\xdd\x0a"
+ "\x6e\x21\x6c\x92\x42\x78\xc9\x1f\xc5\xd1\x0e\x7d\x60\x19\x2d\x94",
+ 84 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x57\x50\xd7\x16\xb4\x80\x8f\x75\x1f\xeb\xc3\x88\x06\xba\x17\x0b"
+ "\xf6\xd5\x19\x9a\x78\x16\xbe\x51\x4e\x3f\x93\x2f\xbe\x0c\xb8\x71",
+ 85 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x6f\xc5\x9b\x2f\x10\xfe\xba\x95\x4a\xa6\x82\x0b\x3c\xa9\x87\xee"
+ "\x81\xd5\xcc\x1d\xa3\xc6\x3c\xe8\x27\x30\x1c\x56\x9d\xfb\x39\xce",
+ 86 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc7\xc3\xfe\x1e\xeb\xdc\x7b\x5a\x93\x93\x26\xe8\xdd\xb8\x3e\x8b"
+ "\xf2\xb7\x80\xb6\x56\x78\xcb\x62\xf2\x08\xb0\x40\xab\xdd\x35\xe2",
+ 87 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x0c\x75\xc1\xa1\x5c\xf3\x4a\x31\x4e\xe4\x78\xf4\xa5\xce\x0b\x8a"
+ "\x6b\x36\x52\x8e\xf7\xa8\x20\x69\x6c\x3e\x42\x46\xc5\xa1\x58\x64",
+ 88 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x21\x6d\xc1\x2a\x10\x85\x69\xa3\xc7\xcd\xde\x4a\xed\x43\xa6\xc3"
+ "\x30\x13\x9d\xda\x3c\xcc\x4a\x10\x89\x05\xdb\x38\x61\x89\x90\x50",
+ 89 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa5\x7b\xe6\xae\x67\x56\xf2\x8b\x02\xf5\x9d\xad\xf7\xe0\xd7\xd8"
+ "\x80\x7f\x10\xfa\x15\xce\xd1\xad\x35\x85\x52\x1a\x1d\x99\x5a\x89",
+ 90 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x81\x6a\xef\x87\x59\x53\x71\x6c\xd7\xa5\x81\xf7\x32\xf5\x3d\xd4"
+ "\x35\xda\xb6\x6d\x09\xc3\x61\xd2\xd6\x59\x2d\xe1\x77\x55\xd8\xa8",
+ 91 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9a\x76\x89\x32\x26\x69\x3b\x6e\xa9\x7e\x6a\x73\x8f\x9d\x10\xfb"
+ "\x3d\x0b\x43\xae\x0e\x8b\x7d\x81\x23\xea\x76\xce\x97\x98\x9c\x7e",
+ 92 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x8d\xae\xdb\x9a\x27\x15\x29\xdb\xb7\xdc\x3b\x60\x7f\xe5\xeb\x2d"
+ "\x32\x11\x77\x07\x58\xdd\x3b\x0a\x35\x93\xd2\xd7\x95\x4e\x2d\x5b",
+ 93 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x16\xdb\xc0\xaa\x5d\xd2\xc7\x74\xf5\x05\x10\x0f\x73\x37\x86\xd8"
+ "\xa1\x75\xfc\xbb\xb5\x9c\x43\xe1\xfb\xff\x3e\x1e\xaf\x31\xcb\x4a",
+ 94 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x86\x06\xcb\x89\x9c\x6a\xea\xf5\x1b\x9d\xb0\xfe\x49\x24\xa9\xfd"
+ "\x5d\xab\xc1\x9f\x88\x26\xf2\xbc\x1c\x1d\x7d\xa1\x4d\x2c\x2c\x99",
+ 95 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x84\x79\x73\x1a\xed\xa5\x7b\xd3\x7e\xad\xb5\x1a\x50\x7e\x30\x7f"
+ "\x3b\xd9\x5e\x69\xdb\xca\x94\xf3\xbc\x21\x72\x60\x66\xad\x6d\xfd",
+ 96 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x58\x47\x3a\x9e\xa8\x2e\xfa\x3f\x3b\x3d\x8f\xc8\x3e\xd8\x86\x31"
+ "\x27\xb3\x3a\xe8\xde\xae\x63\x07\x20\x1e\xdb\x6d\xde\x61\xde\x29",
+ 97 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9a\x92\x55\xd5\x3a\xf1\x16\xde\x8b\xa2\x7c\xe3\x5b\x4c\x7e\x15"
+ "\x64\x06\x57\xa0\xfc\xb8\x88\xc7\x0d\x95\x43\x1d\xac\xd8\xf8\x30",
+ 98 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9e\xb0\x5f\xfb\xa3\x9f\xd8\x59\x6a\x45\x49\x3e\x18\xd2\x51\x0b"
+ "\xf3\xef\x06\x5c\x51\xd6\xe1\x3a\xbe\x66\xaa\x57\xe0\x5c\xfd\xb7",
+ 99 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x81\xdc\xc3\xa5\x05\xea\xce\x3f\x87\x9d\x8f\x70\x27\x76\x77\x0f"
+ "\x9d\xf5\x0e\x52\x1d\x14\x28\xa8\x5d\xaf\x04\xf9\xad\x21\x50\xe0",
+ 100 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe3\xe3\xc4\xaa\x3a\xcb\xbc\x85\x33\x2a\xf9\xd5\x64\xbc\x24\x16"
+ "\x5e\x16\x87\xf6\xb1\xad\xcb\xfa\xe7\x7a\x8f\x03\xc7\x2a\xc2\x8c",
+ 101 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x67\x46\xc8\x0b\x4e\xb5\x6a\xea\x45\xe6\x4e\x72\x89\xbb\xa3\xed"
+ "\xbf\x45\xec\xf8\x20\x64\x81\xff\x63\x02\x12\x29\x84\xcd\x52\x6a",
+ 102 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2b\x62\x8e\x52\x76\x4d\x7d\x62\xc0\x86\x8b\x21\x23\x57\xcd\xd1"
+ "\x2d\x91\x49\x82\x2f\x4e\x98\x45\xd9\x18\xa0\x8d\x1a\xe9\x90\xc0",
+ 103 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe4\xbf\xe8\x0d\x58\xc9\x19\x94\x61\x39\x09\xdc\x4b\x1a\x12\x49"
+ "\x68\x96\xc0\x04\xaf\x7b\x57\x01\x48\x3d\xe4\x5d\x28\x23\xd7\x8e",
+ 104 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xeb\xb4\xba\x15\x0c\xef\x27\x34\x34\x5b\x5d\x64\x1b\xbe\xd0\x3a"
+ "\x21\xea\xfa\xe9\x33\xc9\x9e\x00\x92\x12\xef\x04\x57\x4a\x85\x30",
+ 105 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x39\x66\xec\x73\xb1\x54\xac\xc6\x97\xac\x5c\xf5\xb2\x4b\x40\xbd"
+ "\xb0\xdb\x9e\x39\x88\x36\xd7\x6d\x4b\x88\x0e\x3b\x2a\xf1\xaa\x27",
+ 106 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xef\x7e\x48\x31\xb3\xa8\x46\x36\x51\x8d\x6e\x4b\xfc\xe6\x4a\x43"
+ "\xdb\x2a\x5d\xda\x9c\xca\x2b\x44\xf3\x90\x33\xbd\xc4\x0d\x62\x43",
+ 107 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x7a\xbf\x6a\xcf\x5c\x8e\x54\x9d\xdb\xb1\x5a\xe8\xd8\xb3\x88\xc1"
+ "\xc1\x97\xe6\x98\x73\x7c\x97\x85\x50\x1e\xd1\xf9\x49\x30\xb7\xd9",
+ 108 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x88\x01\x8d\xed\x66\x81\x3f\x0c\xa9\x5d\xef\x47\x4c\x63\x06\x92"
+ "\x01\x99\x67\xb9\xe3\x68\x88\xda\xdd\x94\x12\x47\x19\xb6\x82\xf6",
+ 109 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x39\x30\x87\x6b\x9f\xc7\x52\x90\x36\xb0\x08\xb1\xb8\xbb\x99\x75"
+ "\x22\xa4\x41\x63\x5a\x0c\x25\xec\x02\xfb\x6d\x90\x26\xe5\x5a\x97",
+ 110 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x0a\x40\x49\xd5\x7e\x83\x3b\x56\x95\xfa\xc9\x3d\xd1\xfb\xef\x31"
+ "\x66\xb4\x4b\x12\xad\x11\x24\x86\x62\x38\x3a\xe0\x51\xe1\x58\x27",
+ 111 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x81\xdc\xc0\x67\x8b\xb6\xa7\x65\xe4\x8c\x32\x09\x65\x4f\xe9\x00"
+ "\x89\xce\x44\xff\x56\x18\x47\x7e\x39\xab\x28\x64\x76\xdf\x05\x2b",
+ 112 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe6\x9b\x3a\x36\xa4\x46\x19\x12\xdc\x08\x34\x6b\x11\xdd\xcb\x9d"
+ "\xb7\x96\xf8\x85\xfd\x01\x93\x6e\x66\x2f\xe2\x92\x97\xb0\x99\xa4",
+ 113 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x5a\xc6\x50\x3b\x0d\x8d\xa6\x91\x76\x46\xe6\xdc\xc8\x7e\xdc\x58"
+ "\xe9\x42\x45\x32\x4c\xc2\x04\xf4\xdd\x4a\xf0\x15\x63\xac\xd4\x27",
+ 114 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xdf\x6d\xda\x21\x35\x9a\x30\xbc\x27\x17\x80\x97\x1c\x1a\xbd\x56"
+ "\xa6\xef\x16\x7e\x48\x08\x87\x88\x8e\x73\xa8\x6d\x3b\xf6\x05\xe9",
+ 115 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe8\xe6\xe4\x70\x71\xe7\xb7\xdf\x25\x80\xf2\x25\xcf\xbb\xed\xf8"
+ "\x4c\xe6\x77\x46\x62\x66\x28\xd3\x30\x97\xe4\xb7\xdc\x57\x11\x07",
+ 116 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x53\xe4\x0e\xad\x62\x05\x1e\x19\xcb\x9b\xa8\x13\x3e\x3e\x5c\x1c"
+ "\xe0\x0d\xdc\xad\x8a\xcf\x34\x2a\x22\x43\x60\xb0\xac\xc1\x47\x77",
+ 117 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9c\xcd\x53\xfe\x80\xbe\x78\x6a\xa9\x84\x63\x84\x62\xfb\x28\xaf"
+ "\xdf\x12\x2b\x34\xd7\x8f\x46\x87\xec\x63\x2b\xb1\x9d\xe2\x37\x1a",
+ 118 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xcb\xd4\x80\x52\xc4\x8d\x78\x84\x66\xa3\xe8\x11\x8c\x56\xc9\x7f"
+ "\xe1\x46\xe5\x54\x6f\xaa\xf9\x3e\x2b\xc3\xc4\x7e\x45\x93\x97\x53",
+ 119 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x25\x68\x83\xb1\x4e\x2a\xf4\x4d\xad\xb2\x8e\x1b\x34\xb2\xac\x0f"
+ "\x0f\x4c\x91\xc3\x4e\xc9\x16\x9e\x29\x03\x61\x58\xac\xaa\x95\xb9",
+ 120 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x44\x71\xb9\x1a\xb4\x2d\xb7\xc4\xdd\x84\x90\xab\x95\xa2\xee\x8d"
+ "\x04\xe3\xef\x5c\x3d\x6f\xc7\x1a\xc7\x4b\x2b\x26\x91\x4d\x16\x41",
+ 121 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa5\xeb\x08\x03\x8f\x8f\x11\x55\xed\x86\xe6\x31\x90\x6f\xc1\x30"
+ "\x95\xf6\xbb\xa4\x1d\xe5\xd4\xe7\x95\x75\x8e\xc8\xc8\xdf\x8a\xf1",
+ 122 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xdc\x1d\xb6\x4e\xd8\xb4\x8a\x91\x0e\x06\x0a\x6b\x86\x63\x74\xc5"
+ "\x78\x78\x4e\x9a\xc4\x9a\xb2\x77\x40\x92\xac\x71\x50\x19\x34\xac",
+ 123 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x28\x54\x13\xb2\xf2\xee\x87\x3d\x34\x31\x9e\xe0\xbb\xfb\xb9\x0f"
+ "\x32\xda\x43\x4c\xc8\x7e\x3d\xb5\xed\x12\x1b\xb3\x98\xed\x96\x4b",
+ 124 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x02\x16\xe0\xf8\x1f\x75\x0f\x26\xf1\x99\x8b\xc3\x93\x4e\x3e\x12"
+ "\x4c\x99\x45\xe6\x85\xa6\x0b\x25\xe8\xfb\xd9\x62\x5a\xb6\xb5\x99",
+ 125 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x38\xc4\x10\xf5\xb9\xd4\x07\x20\x50\x75\x5b\x31\xdc\xa8\x9f\xd5"
+ "\x39\x5c\x67\x85\xee\xb3\xd7\x90\xf3\x20\xff\x94\x1c\x5a\x93\xbf",
+ 126 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf1\x84\x17\xb3\x9d\x61\x7a\xb1\xc1\x8f\xdf\x91\xeb\xd0\xfc\x6d"
+ "\x55\x16\xbb\x34\xcf\x39\x36\x40\x37\xbc\xe8\x1f\xa0\x4c\xec\xb1",
+ 127 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x1f\xa8\x77\xde\x67\x25\x9d\x19\x86\x3a\x2a\x34\xbc\xc6\x96\x2a"
+ "\x2b\x25\xfc\xbf\x5c\xbe\xcd\x7e\xde\x8f\x1f\xa3\x66\x88\xa7\x96",
+ 128 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x5b\xd1\x69\xe6\x7c\x82\xc2\xc2\xe9\x8e\xf7\x00\x8b\xdf\x26\x1f"
+ "\x2d\xdf\x30\xb1\xc0\x0f\x9e\x7f\x27\x5b\xb3\xe8\xa2\x8d\xc9\xa2",
+ 129 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc8\x0a\xbe\xeb\xb6\x69\xad\x5d\xee\xb5\xf5\xec\x8e\xa6\xb7\xa0"
+ "\x5d\xdf\x7d\x31\xec\x4c\x0a\x2e\xe2\x0b\x0b\x98\xca\xec\x67\x46",
+ 130 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe7\x6d\x3f\xbd\xa5\xba\x37\x4e\x6b\xf8\xe5\x0f\xad\xc3\xbb\xb9"
+ "\xba\x5c\x20\x6e\xbd\xec\x89\xa3\xa5\x4c\xf3\xdd\x84\xa0\x70\x16",
+ 131 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x7b\xba\x9d\xc5\xb5\xdb\x20\x71\xd1\x77\x52\xb1\x04\x4c\x1e\xce"
+ "\xd9\x6a\xaf\x2d\xd4\x6e\x9b\x43\x37\x50\xe8\xea\x0d\xcc\x18\x70",
+ 132 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf2\x9b\x1b\x1a\xb9\xba\xb1\x63\x01\x8e\xe3\xda\x15\x23\x2c\xca"
+ "\x78\xec\x52\xdb\xc3\x4e\xda\x5b\x82\x2e\xc1\xd8\x0f\xc2\x1b\xd0",
+ 133 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9e\xe3\xe3\xe7\xe9\x00\xf1\xe1\x1d\x30\x8c\x4b\x2b\x30\x76\xd2"
+ "\x72\xcf\x70\x12\x4f\x9f\x51\xe1\xda\x60\xf3\x78\x46\xcd\xd2\xf4",
+ 134 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x70\xea\x3b\x01\x76\x92\x7d\x90\x96\xa1\x85\x08\xcd\x12\x3a\x29"
+ "\x03\x25\x92\x0a\x9d\x00\xa8\x9b\x5d\xe0\x42\x73\xfb\xc7\x6b\x85",
+ 135 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x67\xde\x25\xc0\x2a\x4a\xab\xa2\x3b\xdc\x97\x3c\x8b\xb0\xb5\x79"
+ "\x6d\x47\xcc\x06\x59\xd4\x3d\xff\x1f\x97\xde\x17\x49\x63\xb6\x8e",
+ 136 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb2\x16\x8e\x4e\x0f\x18\xb0\xe6\x41\x00\xb5\x17\xed\x95\x25\x7d"
+ "\x73\xf0\x62\x0d\xf8\x85\xc1\x3d\x2e\xcf\x79\x36\x7b\x38\x4c\xee",
+ 137 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2e\x7d\xec\x24\x28\x85\x3b\x2c\x71\x76\x07\x45\x54\x1f\x7a\xfe"
+ "\x98\x25\xb5\xdd\x77\xdf\x06\x51\x1d\x84\x41\xa9\x4b\xac\xc9\x27",
+ 138 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xca\x9f\xfa\xc4\xc4\x3f\x0b\x48\x46\x1d\xc5\xc2\x63\xbe\xa3\xf6"
+ "\xf0\x06\x11\xce\xac\xab\xf6\xf8\x95\xba\x2b\x01\x01\xdb\xb6\x8d",
+ 139 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x74\x10\xd4\x2d\x8f\xd1\xd5\xe9\xd2\xf5\x81\x5c\xb9\x34\x17\x99"
+ "\x88\x28\xef\x3c\x42\x30\xbf\xbd\x41\x2d\xf0\xa4\xa7\xa2\x50\x7a",
+ 140 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x50\x10\xf6\x84\x51\x6d\xcc\xd0\xb6\xee\x08\x52\xc2\x51\x2b\x4d"
+ "\xc0\x06\x6c\xf0\xd5\x6f\x35\x30\x29\x78\xdb\x8a\xe3\x2c\x6a\x81",
+ 141 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xac\xaa\xb5\x85\xf7\xb7\x9b\x71\x99\x35\xce\xb8\x95\x23\xdd\xc5"
+ "\x48\x27\xf7\x5c\x56\x88\x38\x56\x15\x4a\x56\xcd\xcd\x5e\xe9\x88",
+ 142 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x66\x6d\xe5\xd1\x44\x0f\xee\x73\x31\xaa\xf0\x12\x3a\x62\xef\x2d"
+ "\x8b\xa5\x74\x53\xa0\x76\x96\x35\xac\x6c\xd0\x1e\x63\x3f\x77\x12",
+ 143 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa6\xf9\x86\x58\xf6\xea\xba\xf9\x02\xd8\xb3\x87\x1a\x4b\x10\x1d"
+ "\x16\x19\x6e\x8a\x4b\x24\x1e\x15\x58\xfe\x29\x96\x6e\x10\x3e\x8d",
+ 144 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x89\x15\x46\xa8\xb2\x9f\x30\x47\xdd\xcf\xe5\xb0\x0e\x45\xfd\x55"
+ "\x75\x63\x73\x10\x5e\xa8\x63\x7d\xfc\xff\x54\x7b\x6e\xa9\x53\x5f",
+ 145 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x18\xdf\xbc\x1a\xc5\xd2\x5b\x07\x61\x13\x7d\xbd\x22\xc1\x7c\x82"
+ "\x9d\x0f\x0e\xf1\xd8\x23\x44\xe9\xc8\x9c\x28\x66\x94\xda\x24\xe8",
+ 146 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb5\x4b\x9b\x67\xf8\xfe\xd5\x4b\xbf\x5a\x26\x66\xdb\xdf\x4b\x23"
+ "\xcf\xf1\xd1\xb6\xf4\xaf\xc9\x85\xb2\xe6\xd3\x30\x5a\x9f\xf8\x0f",
+ 147 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x7d\xb4\x42\xe1\x32\xba\x59\xbc\x12\x89\xaa\x98\xb0\xd3\xe8\x06"
+ "\x00\x4f\x8e\xc1\x28\x11\xaf\x1e\x2e\x33\xc6\x9b\xfd\xe7\x29\xe1",
+ 148 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x25\x0f\x37\xcd\xc1\x5e\x81\x7d\x2f\x16\x0d\x99\x56\xc7\x1f\xe3"
+ "\xeb\x5d\xb7\x45\x56\xe4\xad\xf9\xa4\xff\xaf\xba\x74\x01\x03\x96",
+ 149 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x4a\xb8\xa3\xdd\x1d\xdf\x8a\xd4\x3d\xab\x13\xa2\x7f\x66\xa6\x54"
+ "\x4f\x29\x05\x97\xfa\x96\x04\x0e\x0e\x1d\xb9\x26\x3a\xa4\x79\xf8",
+ 150 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xee\x61\x72\x7a\x07\x66\xdf\x93\x9c\xcd\xc8\x60\x33\x40\x44\xc7"
+ "\x9a\x3c\x9b\x15\x62\x00\xbc\x3a\xa3\x29\x73\x48\x3d\x83\x41\xae",
+ 151 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x3f\x68\xc7\xec\x63\xac\x11\xeb\xb9\x8f\x94\xb3\x39\xb0\x5c\x10"
+ "\x49\x84\xfd\xa5\x01\x03\x06\x01\x44\xe5\xa2\xbf\xcc\xc9\xda\x95",
+ 152 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x05\x6f\x29\x81\x6b\x8a\xf8\xf5\x66\x82\xbc\x4d\x7c\xf0\x94\x11"
+ "\x1d\xa7\x73\x3e\x72\x6c\xd1\x3d\x6b\x3e\x8e\xa0\x3e\x92\xa0\xd5",
+ 153 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf5\xec\x43\xa2\x8a\xcb\xef\xf1\xf3\x31\x8a\x5b\xca\xc7\xc6\x6d"
+ "\xdb\x52\x30\xb7\x9d\xb2\xd1\x05\xbc\xbe\x15\xf3\xc1\x14\x8d\x69",
+ 154 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2a\x69\x60\xad\x1d\x8d\xd5\x47\x55\x5c\xfb\xd5\xe4\x60\x0f\x1e"
+ "\xaa\x1c\x8e\xda\x34\xde\x03\x74\xec\x4a\x26\xea\xaa\xa3\x3b\x4e",
+ 155 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xdc\xc1\xea\x7b\xaa\xb9\x33\x84\xf7\x6b\x79\x68\x66\x19\x97\x54"
+ "\x74\x2f\x7b\x96\xd6\xb4\xc1\x20\x16\x5c\x04\xa6\xc4\xf5\xce\x10",
+ 156 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x13\xd5\xdf\x17\x92\x21\x37\x9c\x6a\x78\xc0\x7c\x79\x3f\xf5\x34"
+ "\x87\xca\xe6\xbf\x9f\xe8\x82\x54\x1a\xb0\xe7\x35\xe3\xea\xda\x3b",
+ 157 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x8c\x59\xe4\x40\x76\x41\xa0\x1e\x8f\xf9\x1f\x99\x80\xdc\x23\x6f"
+ "\x4e\xcd\x6f\xcf\x52\x58\x9a\x09\x9a\x96\x16\x33\x96\x77\x14\xe1",
+ 158 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x83\x3b\x1a\xc6\xa2\x51\xfd\x08\xfd\x6d\x90\x8f\xea\x2a\x4e\xe1"
+ "\xe0\x40\xbc\xa9\x3f\xc1\xa3\x8e\xc3\x82\x0e\x0c\x10\xbd\x82\xea",
+ 159 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa2\x44\xf9\x27\xf3\xb4\x0b\x8f\x6c\x39\x15\x70\xc7\x65\x41\x8f"
+ "\x2f\x6e\x70\x8e\xac\x90\x06\xc5\x1a\x7f\xef\xf4\xaf\x3b\x2b\x9e",
+ 160 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x3d\x99\xed\x95\x50\xcf\x11\x96\xe6\xc4\xd2\x0c\x25\x96\x20\xf8"
+ "\x58\xc3\xd7\x03\x37\x4c\x12\x8c\xe7\xb5\x90\x31\x0c\x83\x04\x6d",
+ 161 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2b\x35\xc4\x7d\x7b\x87\x76\x1f\x0a\xe4\x3a\xc5\x6a\xc2\x7b\x9f"
+ "\x25\x83\x03\x67\xb5\x95\xbe\x8c\x24\x0e\x94\x60\x0c\x6e\x33\x12",
+ 162 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x5d\x11\xed\x37\xd2\x4d\xc7\x67\x30\x5c\xb7\xe1\x46\x7d\x87\xc0"
+ "\x65\xac\x4b\xc8\xa4\x26\xde\x38\x99\x1f\xf5\x9a\xa8\x73\x5d\x02",
+ 163 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb8\x36\x47\x8e\x1c\xa0\x64\x0d\xce\x6f\xd9\x10\xa5\x09\x62\x72"
+ "\xc8\x33\x09\x90\xcd\x97\x86\x4a\xc2\xbf\x14\xef\x6b\x23\x91\x4a",
+ 164 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x91\x00\xf9\x46\xd6\xcc\xde\x3a\x59\x7f\x90\xd3\x9f\xc1\x21\x5b"
+ "\xad\xdc\x74\x13\x64\x3d\x85\xc2\x1c\x3e\xee\x5d\x2d\xd3\x28\x94",
+ 165 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xda\x70\xee\xdd\x23\xe6\x63\xaa\x1a\x74\xb9\x76\x69\x35\xb4\x79"
+ "\x22\x2a\x72\xaf\xba\x5c\x79\x51\x58\xda\xd4\x1a\x3b\xd7\x7e\x40",
+ 166 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf0\x67\xed\x6a\x0d\xbd\x43\xaa\x0a\x92\x54\xe6\x9f\xd6\x6b\xdd"
+ "\x8a\xcb\x87\xde\x93\x6c\x25\x8c\xfb\x02\x28\x5f\x2c\x11\xfa\x79",
+ 167 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x71\x5c\x99\xc7\xd5\x75\x80\xcf\x97\x53\xb4\xc1\xd7\x95\xe4\x5a"
+ "\x83\xfb\xb2\x28\xc0\xd3\x6f\xbe\x20\xfa\xf3\x9b\xdd\x6d\x4e\x85",
+ 168 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe4\x57\xd6\xad\x1e\x67\xcb\x9b\xbd\x17\xcb\xd6\x98\xfa\x6d\x7d"
+ "\xae\x0c\x9b\x7a\xd6\xcb\xd6\x53\x96\x34\xe3\x2a\x71\x9c\x84\x92",
+ 169 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xec\xe3\xea\x81\x03\xe0\x24\x83\xc6\x4a\x70\xa4\xbd\xce\xe8\xce"
+ "\xb6\x27\x8f\x25\x33\xf3\xf4\x8d\xbe\xed\xfb\xa9\x45\x31\xd4\xae",
+ 170 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x38\x8a\xa5\xd3\x66\x7a\x97\xc6\x8d\x3d\x56\xf8\xf3\xee\x8d\x3d"
+ "\x36\x09\x1f\x17\xfe\x5d\x1b\x0d\x5d\x84\xc9\x3b\x2f\xfe\x40\xbd",
+ 171 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x8b\x6b\x31\xb9\xad\x7c\x3d\x5c\xd8\x4b\xf9\x89\x47\xb9\xcd\xb5"
+ "\x9d\xf8\xa2\x5f\xf7\x38\x10\x10\x13\xbe\x4f\xd6\x5e\x1d\xd1\xa3",
+ 172 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x06\x62\x91\xf6\xbb\xd2\x5f\x3c\x85\x3d\xb7\xd8\xb9\x5c\x9a\x1c"
+ "\xfb\x9b\xf1\xc1\xc9\x9f\xb9\x5a\x9b\x78\x69\xd9\x0f\x1c\x29\x03",
+ 173 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa7\x07\xef\xbc\xcd\xce\xed\x42\x96\x7a\x66\xf5\x53\x9b\x93\xed"
+ "\x75\x60\xd4\x67\x30\x40\x16\xc4\x78\x0d\x77\x55\xa5\x65\xd4\xc4",
+ 174 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x38\xc5\x3d\xfb\x70\xbe\x7e\x79\x2b\x07\xa6\xa3\x5b\x8a\x6a\x0a"
+ "\xba\x02\xc5\xc5\xf3\x8b\xaf\x5c\x82\x3f\xdf\xd9\xe4\x2d\x65\x7e",
+ 175 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf2\x91\x13\x86\x50\x1d\x9a\xb9\xd7\x20\xcf\x8a\xd1\x05\x03\xd5"
+ "\x63\x4b\xf4\xb7\xd1\x2b\x56\xdf\xb7\x4f\xec\xc6\xe4\x09\x3f\x68",
+ 176 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc6\xf2\xbd\xd5\x2b\x81\xe6\xe4\xf6\x59\x5a\xbd\x4d\x7f\xb3\x1f"
+ "\x65\x11\x69\xd0\x0f\xf3\x26\x92\x6b\x34\x94\x7b\x28\xa8\x39\x59",
+ 177 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x29\x3d\x94\xb1\x8c\x98\xbb\x32\x23\x36\x6b\x8c\xe7\x4c\x28\xfb"
+ "\xdf\x28\xe1\xf8\x4a\x33\x50\xb0\xeb\x2d\x18\x04\xa5\x77\x57\x9b",
+ 178 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2c\x2f\xa5\xc0\xb5\x15\x33\x16\x5b\xc3\x75\xc2\x2e\x27\x81\x76"
+ "\x82\x70\xa3\x83\x98\x5d\x13\xbd\x6b\x67\xb6\xfd\x67\xf8\x89\xeb",
+ 179 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xca\xa0\x9b\x82\xb7\x25\x62\xe4\x3f\x4b\x22\x75\xc0\x91\x91\x8e"
+ "\x62\x4d\x91\x16\x61\xcc\x81\x1b\xb5\xfa\xec\x51\xf6\x08\x8e\xf7",
+ 180 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x24\x76\x1e\x45\xe6\x74\x39\x53\x79\xfb\x17\x72\x9c\x78\xcb\x93"
+ "\x9e\x6f\x74\xc5\xdf\xfb\x9c\x96\x1f\x49\x59\x82\xc3\xed\x1f\xe3",
+ 181 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x55\xb7\x0a\x82\x13\x1e\xc9\x48\x88\xd7\xab\x54\xa7\xc5\x15\x25"
+ "\x5c\x39\x38\xbb\x10\xbc\x78\x4d\xc9\xb6\x7f\x07\x6e\x34\x1a\x73",
+ 182 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x6a\xb9\x05\x7b\x97\x7e\xbc\x3c\xa4\xd4\xce\x74\x50\x6c\x25\xcc"
+ "\xcd\xc5\x66\x49\x7c\x45\x0b\x54\x15\xa3\x94\x86\xf8\x65\x7a\x03",
+ 183 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x24\x06\x6d\xee\xe0\xec\xee\x15\xa4\x5f\x0a\x32\x6d\x0f\x8d\xbc"
+ "\x79\x76\x1e\xbb\x93\xcf\x8c\x03\x77\xaf\x44\x09\x78\xfc\xf9\x94",
+ 184 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x20\x00\x0d\x3f\x66\xba\x76\x86\x0d\x5a\x95\x06\x88\xb9\xaa\x0d"
+ "\x76\xcf\xea\x59\xb0\x05\xd8\x59\x91\x4b\x1a\x46\x65\x3a\x93\x9b",
+ 185 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb9\x2d\xaa\x79\x60\x3e\x3b\xdb\xc3\xbf\xe0\xf4\x19\xe4\x09\xb2"
+ "\xea\x10\xdc\x43\x5b\xee\xfe\x29\x59\xda\x16\x89\x5d\x5d\xca\x1c",
+ 186 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe9\x47\x94\x87\x05\xb2\x06\xd5\x72\xb0\xe8\xf6\x2f\x66\xa6\x55"
+ "\x1c\xbd\x6b\xc3\x05\xd2\x6c\xe7\x53\x9a\x12\xf9\xaa\xdf\x75\x71",
+ 187 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x3d\x67\xc1\xb3\xf9\xb2\x39\x10\xe3\xd3\x5e\x6b\x0f\x2c\xcf\x44"
+ "\xa0\xb5\x40\xa4\x5c\x18\xba\x3c\x36\x26\x4d\xd4\x8e\x96\xaf\x6a",
+ 188 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc7\x55\x8b\xab\xda\x04\xbc\xcb\x76\x4d\x0b\xbf\x33\x58\x42\x51"
+ "\x41\x90\x2d\x22\x39\x1d\x9f\x8c\x59\x15\x9f\xec\x9e\x49\xb1\x51",
+ 189 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x0b\x73\x2b\xb0\x35\x67\x5a\x50\xff\x58\xf2\xc2\x42\xe4\x71\x0a"
+ "\xec\xe6\x46\x70\x07\x9c\x13\x04\x4c\x79\xc9\xb7\x49\x1f\x70\x00",
+ 190 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xd1\x20\xb5\xef\x6d\x57\xeb\xf0\x6e\xaf\x96\xbc\x93\x3c\x96\x7b"
+ "\x16\xcb\xe6\xe2\xbf\x00\x74\x1c\x30\xaa\x1c\x54\xba\x64\x80\x1f",
+ 191 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x58\xd2\x12\xad\x6f\x58\xae\xf0\xf8\x01\x16\xb4\x41\xe5\x7f\x61"
+ "\x95\xbf\xef\x26\xb6\x14\x63\xed\xec\x11\x83\xcd\xb0\x4f\xe7\x6d",
+ 192 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb8\x83\x6f\x51\xd1\xe2\x9b\xdf\xdb\xa3\x25\x56\x53\x60\x26\x8b"
+ "\x8f\xad\x62\x74\x73\xed\xec\xef\x7e\xae\xfe\xe8\x37\xc7\x40\x03",
+ 193 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc5\x47\xa3\xc1\x24\xae\x56\x85\xff\xa7\xb8\xed\xaf\x96\xec\x86"
+ "\xf8\xb2\xd0\xd5\x0c\xee\x8b\xe3\xb1\xf0\xc7\x67\x63\x06\x9d\x9c",
+ 194 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x5d\x16\x8b\x76\x9a\x2f\x67\x85\x3d\x62\x95\xf7\x56\x8b\xe4\x0b"
+ "\xb7\xa1\x6b\x8d\x65\xba\x87\x63\x5d\x19\x78\xd2\xab\x11\xba\x2a",
+ 195 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa2\xf6\x75\xdc\x73\x02\x63\x8c\xb6\x02\x01\x06\x4c\xa5\x50\x77"
+ "\x71\x4d\x71\xfe\x09\x6a\x31\x5f\x2f\xe7\x40\x12\x77\xca\xa5\xaf",
+ 196 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc8\xaa\xb5\xcd\x01\x60\xae\x78\xcd\x2e\x8a\xc5\xfb\x0e\x09\x3c"
+ "\xdb\x5c\x4b\x60\x52\xa0\xa9\x7b\xb0\x42\x16\x82\x6f\xa7\xa4\x37",
+ 197 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xff\x68\xca\x40\x35\xbf\xeb\x43\xfb\xf1\x45\xfd\xdd\x5e\x43\xf1"
+ "\xce\xa5\x4f\x11\xf7\xbe\xe1\x30\x58\xf0\x27\x32\x9a\x4a\x5f\xa4",
+ 198 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x1d\x4e\x54\x87\xae\x3c\x74\x0f\x2b\xa6\xe5\x41\xac\x91\xbc\x2b"
+ "\xfc\xd2\x99\x9c\x51\x8d\x80\x7b\x42\x67\x48\x80\x3a\x35\x0f\xd4",
+ 199 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x6d\x24\x4e\x1a\x06\xce\x4e\xf5\x78\xdd\x0f\x63\xaf\xf0\x93\x67"
+ "\x06\x73\x51\x19\xca\x9c\x8d\x22\xd8\x6c\x80\x14\x14\xab\x97\x41",
+ 200 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xde\xcf\x73\x29\xdb\xcc\x82\x7b\x8f\xc5\x24\xc9\x43\x1e\x89\x98"
+ "\x02\x9e\xce\x12\xce\x93\xb7\xb2\xf3\xe7\x69\xa9\x41\xfb\x8c\xea",
+ 201 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2f\xaf\xcc\x0f\x2e\x63\xcb\xd0\x77\x55\xbe\x7b\x75\xec\xea\x0a"
+ "\xdf\xf9\xaa\x5e\xde\x2a\x52\xfd\xab\x4d\xfd\x03\x74\xcd\x48\x3f",
+ 202 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xaa\x85\x01\x0d\xd4\x6a\x54\x6b\x53\x5e\xf4\xcf\x5f\x07\xd6\x51"
+ "\x61\xe8\x98\x28\xf3\xa7\x7d\xb7\xb9\xb5\x6f\x0d\xf5\x9a\xae\x45",
+ 203 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x07\xe8\xe1\xee\x73\x2c\xb0\xd3\x56\xc9\xc0\xd1\x06\x9c\x89\xd1"
+ "\x7a\xdf\x6a\x9a\x33\x4f\x74\x5e\xc7\x86\x73\x32\x54\x8c\xa8\xe9",
+ 204 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x0e\x01\xe8\x1c\xad\xa8\x16\x2b\xfd\x5f\x8a\x8c\x81\x8a\x6c\x69"
+ "\xfe\xdf\x02\xce\xb5\x20\x85\x23\xcb\xe5\x31\x3b\x89\xca\x10\x53",
+ 205 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x6b\xb6\xc6\x47\x26\x55\x08\x43\x99\x85\x2e\x00\x24\x9f\x8c\xb2"
+ "\x47\x89\x6d\x39\x2b\x02\xd7\x3b\x7f\x0d\xd8\x18\xe1\xe2\x9b\x07",
+ 206 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x42\xd4\x63\x6e\x20\x60\xf0\x8f\x41\xc8\x82\xe7\x6b\x39\x6b\x11"
+ "\x2e\xf6\x27\xcc\x24\xc4\x3d\xd5\xf8\x3a\x1d\x1a\x7e\xad\x71\x1a",
+ 207 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x48\x58\xc9\xa1\x88\xb0\x23\x4f\xb9\xa8\xd4\x7d\x0b\x41\x33\x65"
+ "\x0a\x03\x0b\xd0\x61\x1b\x87\xc3\x89\x2e\x94\x95\x1f\x8d\xf8\x52",
+ 208 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x3f\xab\x3e\x36\x98\x8d\x44\x5a\x51\xc8\x78\x3e\x53\x1b\xe3\xa0"
+ "\x2b\xe4\x0c\xd0\x47\x96\xcf\xb6\x1d\x40\x34\x74\x42\xd3\xf7\x94",
+ 209 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xeb\xab\xc4\x96\x36\xbd\x43\x3d\x2e\xc8\xf0\xe5\x18\x73\x2e\xf8"
+ "\xfa\x21\xd4\xd0\x71\xcc\x3b\xc4\x6c\xd7\x9f\xa3\x8a\x28\xb8\x10",
+ 210 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xa1\xd0\x34\x35\x23\xb8\x93\xfc\xa8\x4f\x47\xfe\xb4\xa6\x4d\x35"
+ "\x0a\x17\xd8\xee\xf5\x49\x7e\xce\x69\x7d\x02\xd7\x91\x78\xb5\x91",
+ 211 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x26\x2e\xbf\xd9\x13\x0b\x7d\x28\x76\x0d\x08\xef\x8b\xfd\x3b\x86"
+ "\xcd\xd3\xb2\x11\x3d\x2c\xae\xf7\xea\x95\x1a\x30\x3d\xfa\x38\x46",
+ 212 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf7\x61\x58\xed\xd5\x0a\x15\x4f\xa7\x82\x03\xed\x23\x62\x93\x2f"
+ "\xcb\x82\x53\xaa\xe3\x78\x90\x3e\xde\xd1\xe0\x3f\x70\x21\xa2\x57",
+ 213 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x26\x17\x8e\x95\x0a\xc7\x22\xf6\x7a\xe5\x6e\x57\x1b\x28\x4c\x02"
+ "\x07\x68\x4a\x63\x34\xa1\x77\x48\xa9\x4d\x26\x0b\xc5\xf5\x52\x74",
+ 214 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc3\x78\xd1\xe4\x93\xb4\x0e\xf1\x1f\xe6\xa1\x5d\x9c\x27\x37\xa3"
+ "\x78\x09\x63\x4c\x5a\xba\xd5\xb3\x3d\x7e\x39\x3b\x4a\xe0\x5d\x03",
+ 215 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x98\x4b\xd8\x37\x91\x01\xbe\x8f\xd8\x06\x12\xd8\xea\x29\x59\xa7"
+ "\x86\x5e\xc9\x71\x85\x23\x55\x01\x07\xae\x39\x38\xdf\x32\x01\x1b",
+ 216 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc6\xf2\x5a\x81\x2a\x14\x48\x58\xac\x5c\xed\x37\xa9\x3a\x9f\x47"
+ "\x59\xba\x0b\x1c\x0f\xdc\x43\x1d\xce\x35\xf9\xec\x1f\x1f\x4a\x99",
+ 217 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x92\x4c\x75\xc9\x44\x24\xff\x75\xe7\x4b\x8b\x4e\x94\x35\x89\x58"
+ "\xb0\x27\xb1\x71\xdf\x5e\x57\x89\x9a\xd0\xd4\xda\xc3\x73\x53\xb6",
+ 218 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x0a\xf3\x58\x92\xa6\x3f\x45\x93\x1f\x68\x46\xed\x19\x03\x61\xcd"
+ "\x07\x30\x89\xe0\x77\x16\x57\x14\xb5\x0b\x81\xa2\xe3\xdd\x9b\xa1",
+ 219 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xcc\x80\xce\xfb\x26\xc3\xb2\xb0\xda\xef\x23\x3e\x60\x6d\x5f\xfc"
+ "\x80\xfa\x17\x42\x7d\x18\xe3\x04\x89\x67\x3e\x06\xef\x4b\x87\xf7",
+ 220 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc2\xf8\xc8\x11\x74\x47\xf3\x97\x8b\x08\x18\xdc\xf6\xf7\x01\x16"
+ "\xac\x56\xfd\x18\x4d\xd1\x27\x84\x94\xe1\x03\xfc\x6d\x74\xa8\x87",
+ 221 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xbd\xec\xf6\xbf\xc1\xba\x0d\xf6\xe8\x62\xc8\x31\x99\x22\x07\x79"
+ "\x6a\xcc\x79\x79\x68\x35\x88\x28\xc0\x6e\x7a\x51\xe0\x90\x09\x8f",
+ 222 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x24\xd1\xa2\x6e\x3d\xab\x02\xfe\x45\x72\xd2\xaa\x7d\xbd\x3e\xc3"
+ "\x0f\x06\x93\xdb\x26\xf2\x73\xd0\xab\x2c\xb0\xc1\x3b\x5e\x64\x51",
+ 223 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xec\x56\xf5\x8b\x09\x29\x9a\x30\x0b\x14\x05\x65\xd7\xd3\xe6\x87"
+ "\x82\xb6\xe2\xfb\xeb\x4b\x7e\xa9\x7a\xc0\x57\x98\x90\x61\xdd\x3f",
+ 224 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x11\xa4\x37\xc1\xab\xa3\xc1\x19\xdd\xfa\xb3\x1b\x3e\x8c\x84\x1d"
+ "\xee\xeb\x91\x3e\xf5\x7f\x7e\x48\xf2\xc9\xcf\x5a\x28\xfa\x42\xbc",
+ 225 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x53\xc7\xe6\x11\x4b\x85\x0a\x2c\xb4\x96\xc9\xb3\xc6\x9a\x62\x3e"
+ "\xae\xa2\xcb\x1d\x33\xdd\x81\x7e\x47\x65\xed\xaa\x68\x23\xc2\x28",
+ 226 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x15\x4c\x3e\x96\xfe\xe5\xdb\x14\xf8\x77\x3e\x18\xaf\x14\x85\x79"
+ "\x13\x50\x9d\xa9\x99\xb4\x6c\xdd\x3d\x4c\x16\x97\x60\xc8\x3a\xd2",
+ 227 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x40\xb9\x91\x6f\x09\x3e\x02\x7a\x87\x86\x64\x18\x18\x92\x06\x20"
+ "\x47\x2f\xbc\xf6\x8f\x70\x1d\x1b\x68\x06\x32\xe6\x99\x6b\xde\xd3",
+ 228 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x24\xc4\xcb\xba\x07\x11\x98\x31\xa7\x26\xb0\x53\x05\xd9\x6d\xa0"
+ "\x2f\xf8\xb1\x48\xf0\xda\x44\x0f\xe2\x33\xbc\xaa\x32\xc7\x2f\x6f",
+ 229 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x5d\x20\x15\x10\x25\x00\x20\xb7\x83\x68\x96\x88\xab\xbf\x8e\xcf"
+ "\x25\x94\xa9\x6a\x08\xf2\xbf\xec\x6c\xe0\x57\x44\x65\xdd\xed\x71",
+ 230 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x04\x3b\x97\xe3\x36\xee\x6f\xdb\xbe\x2b\x50\xf2\x2a\xf8\x32\x75"
+ "\xa4\x08\x48\x05\xd2\xd5\x64\x59\x62\x45\x4b\x6c\x9b\x80\x53\xa0",
+ 231 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x56\x48\x35\xcb\xae\xa7\x74\x94\x85\x68\xbe\x36\xcf\x52\xfc\xdd"
+ "\x83\x93\x4e\xb0\xa2\x75\x12\xdb\xe3\xe2\xdb\x47\xb9\xe6\x63\x5a",
+ 232 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf2\x1c\x33\xf4\x7b\xde\x40\xa2\xa1\x01\xc9\xcd\xe8\x02\x7a\xaf"
+ "\x61\xa3\x13\x7d\xe2\x42\x2b\x30\x03\x5a\x04\xc2\x70\x89\x41\x83",
+ 233 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x9d\xb0\xef\x74\xe6\x6c\xbb\x84\x2e\xb0\xe0\x73\x43\xa0\x3c\x5c"
+ "\x56\x7e\x37\x2b\x3f\x23\xb9\x43\xc7\x88\xa4\xf2\x50\xf6\x78\x91",
+ 234 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xab\x8d\x08\x65\x5f\xf1\xd3\xfe\x87\x58\xd5\x62\x23\x5f\xd2\x3e"
+ "\x7c\xf9\xdc\xaa\xd6\x58\x87\x2a\x49\xe5\xd3\x18\x3b\x6c\xce\xbd",
+ 235 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x6f\x27\xf7\x7e\x7b\xcf\x46\xa1\xe9\x63\xad\xe0\x30\x97\x33\x54"
+ "\x30\x31\xdc\xcd\xd4\x7c\xaa\xc1\x74\xd7\xd2\x7c\xe8\x07\x7e\x8b",
+ 236 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xe3\xcd\x54\xda\x7e\x44\x4c\xaa\x62\x07\x56\x95\x25\xa6\x70\xeb"
+ "\xae\x12\x78\xde\x4e\x3f\xe2\x68\x4b\x3e\x33\xf5\xef\x90\xcc\x1b",
+ 237 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb2\xc3\xe3\x3a\x51\xd2\x2c\x4c\x08\xfc\x09\x89\xc8\x73\xc9\xcc"
+ "\x41\x50\x57\x9b\x1e\x61\x63\xfa\x69\x4a\xd5\x1d\x53\xd7\x12\xdc",
+ 238 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xbe\x7f\xda\x98\x3e\x13\x18\x9b\x4c\x77\xe0\xa8\x09\x20\xb6\xe0"
+ "\xe0\xea\x80\xc3\xb8\x4d\xbe\x7e\x71\x17\xd2\x53\xf4\x81\x12\xf4",
+ 239 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb6\x00\x8c\x28\xfa\xe0\x8a\xa4\x27\xe5\xbd\x3a\xad\x36\xf1\x00"
+ "\x21\xf1\x6c\x77\xcf\xea\xbe\xd0\x7f\x97\xcc\x7d\xc1\xf1\x28\x4a",
+ 240 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x6e\x4e\x67\x60\xc5\x38\xf2\xe9\x7b\x3a\xdb\xfb\xbc\xde\x57\xf8"
+ "\x96\x6b\x7e\xa8\xfc\xb5\xbf\x7e\xfe\xc9\x13\xfd\x2a\x2b\x0c\x55",
+ 241 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x4a\xe5\x1f\xd1\x83\x4a\xa5\xbd\x9a\x6f\x7e\xc3\x9f\xc6\x63\x33"
+ "\x8d\xc5\xd2\xe2\x07\x61\x56\x6d\x90\xcc\x68\xb1\xcb\x87\x5e\xd8",
+ 242 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb6\x73\xaa\xd7\x5a\xb1\xfd\xb5\x40\x1a\xbf\xa1\xbf\x89\xf3\xad"
+ "\xd2\xeb\xc4\x68\xdf\x36\x24\xa4\x78\xf4\xfe\x85\x9d\x8d\x55\xe2",
+ 243 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x13\xc9\x47\x1a\x98\x55\x91\x35\x39\x83\x66\x60\x39\x8d\xa0\xf3"
+ "\xf9\x9a\xda\x08\x47\x9c\x69\xd1\xb7\xfc\xaa\x34\x61\xdd\x7e\x59",
+ 244 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x2c\x11\xf4\xa7\xf9\x9a\x1d\x23\xa5\x8b\xb6\x36\x35\x0f\xe8\x49"
+ "\xf2\x9c\xba\xc1\xb2\xa1\x11\x2d\x9f\x1e\xd5\xbc\x5b\x31\x3c\xcd",
+ 245 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc7\xd3\xc0\x70\x6b\x11\xae\x74\x1c\x05\xa1\xef\x15\x0d\xd6\x5b"
+ "\x54\x94\xd6\xd5\x4c\x9a\x86\xe2\x61\x78\x54\xe6\xae\xee\xbb\xd9",
+ 246 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x19\x4e\x10\xc9\x38\x93\xaf\xa0\x64\xc3\xac\x04\xc0\xdd\x80\x8d"
+ "\x79\x1c\x3d\x4b\x75\x56\xe8\x9d\x8d\x9c\xb2\x25\xc4\xb3\x33\x39",
+ 247 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x6f\xc4\x98\x8b\x8f\x78\x54\x6b\x16\x88\x99\x18\x45\x90\x8f\x13"
+ "\x4b\x6a\x48\x2e\x69\x94\xb3\xd4\x83\x17\xbf\x08\xdb\x29\x21\x85",
+ 248 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x56\x65\xbe\xb8\xb0\x95\x55\x25\x81\x3b\x59\x81\xcd\x14\x2e\xd4"
+ "\xd0\x3f\xba\x38\xa6\xf3\xe5\xad\x26\x8e\x0c\xc2\x70\xd1\xcd\x11",
+ 249 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xb8\x83\xd6\x8f\x5f\xe5\x19\x36\x43\x1b\xa4\x25\x67\x38\x05\x3b"
+ "\x1d\x04\x26\xd4\xcb\x64\xb1\x6e\x83\xba\xdc\x5e\x9f\xbe\x3b\x81",
+ 250 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x53\xe7\xb2\x7e\xa5\x9c\x2f\x6d\xbb\x50\x76\x9e\x43\x55\x4d\xf3"
+ "\x5a\xf8\x9f\x48\x22\xd0\x46\x6b\x00\x7d\xd6\xf6\xde\xaf\xff\x02",
+ 251 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\x1f\x1a\x02\x29\xd4\x64\x0f\x01\x90\x15\x88\xd9\xde\xc2\x2d\x13"
+ "\xfc\x3e\xb3\x4a\x61\xb3\x29\x38\xef\xbf\x53\x34\xb2\x80\x0a\xfa",
+ 252 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc2\xb4\x05\xaf\xa0\xfa\x66\x68\x85\x2a\xee\x4d\x88\x04\x08\x53"
+ "\xfa\xb8\x00\xe7\x2b\x57\x58\x14\x18\xe5\x50\x6f\x21\x4c\x7d\x1f",
+ 253 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xc0\x8a\xa1\xc2\x86\xd7\x09\xfd\xc7\x47\x37\x44\x97\x71\x88\xc8"
+ "\x95\xba\x01\x10\x14\x24\x7e\x4e\xfa\x8d\x07\xe7\x8f\xec\x69\x5c",
+ 254 },
+ { GCRY_MD_BLAKE2S_256, blake2_data_vector,
+ "\xf0\x3f\x57\x89\xd3\x33\x6b\x80\xd0\x02\xd5\x9f\xdf\x91\x8b\xdb"
+ "\x77\x5b\x00\x95\x6e\xd5\x52\x8e\x86\xaa\x99\x4a\xcb\x38\xfe\x2d",
+ 255 },
diff --git a/comm/third_party/libgcrypt/tests/cavs_driver.pl b/comm/third_party/libgcrypt/tests/cavs_driver.pl
new file mode 100755
index 0000000000..bc93feb9ee
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/cavs_driver.pl
@@ -0,0 +1,2243 @@
+#!/usr/bin/env perl
+#
+# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $
+#
+# CAVS test driver (based on the OpenSSL driver)
+# Written by: Stephan Müller <sm@atsec.com>
+# Copyright (c) atsec information security corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# NO WARRANTY
+#
+# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+# REPAIR OR CORRECTION.
+#
+# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES.
+#
+#
+# test execution instruction:
+# 1. get the request files from the lab
+# 2. call each request file from 1. with this program:
+# $0 <FILE>.rep
+# 3. send the resulting file <FILE>.rsp to the lab
+#
+#
+# Test should be easily adoptable to other implementations
+# See the first functions for this task
+#
+# Following tests are covered (others may also be covered
+# but have not been tested)
+#
+# AES
+# [CBC|CFB128|ECB|OFB]GFSbox[128|192|256]
+# [CBC|CFB128|ECB|OFB]MCT[128|192|256]
+# [CBC|CFB128|ECB|OFB]VarKey[128|192|256]
+# [CBC|CFB128|ECB|OFB]KeySbox[128|192|256]
+# [CBC|CFB128|ECB|OFB]MMT[128|192|256]
+# [CBC|CFB128|ECB|OFB]VarTxt[128|192|256]
+#
+# RSA
+# SigGen[15|RSA]
+# SigVer15
+# (SigVerRSA is not applicable for OpenSSL as X9.31 padding
+# is not done through openssl dgst)
+# KeyGen RSA X9.31
+#
+# SHA
+# SHA[1|224|256|384|512]ShortMsg
+# SHA[1|224|256|384|512]LongMsg
+# SHA[1|224|256|384|512]Monte
+#
+# HMAC (SHA - caveat: we only support hash output equal to the block size of
+# of the hash - we do not support truncation of the hash; to support
+# that, we first need to decipher the HMAC.req file - see hmac_kat() )
+# HMAC
+#
+# TDES
+# T[CBC|CFB??|ECB|OFB]Monte[1|2|3]
+# T[CBC|CFB??|ECB|OFB]permop
+# T[CBC|CFB??|ECB|OFB]MMT[1|2|3]
+# T[CBC|CFB??|ECB|OFB]subtab
+# T[CBC|CFB??|ECB|OFB]varkey
+# T[CBC|CFB??|ECB|OFB]invperm
+# T[CBC|CFB??|ECB|OFB]vartext
+#
+# ANSI X9.31 RNG
+# ANSI931_AES128MCT
+# ANSI931_AES128VST
+#
+# DSA
+# PQGGen
+# SigGen
+# SigVer
+#
+# RC4 (atsec developed tests)
+# RC4KeyBD
+# RC4MCT
+# RC4PltBD
+# RC4REGT
+#
+
+use strict;
+use warnings;
+use IPC::Open2;
+use Getopt::Std;
+use MIME::Base64;
+
+# Contains the command line options
+my %opt;
+
+#################################################################
+##### Central interface functions to the external ciphers #######
+#################################################################
+# Only these interface routines should be changed in case of
+# porting to a new cipher library
+#
+# For porting to a new library, create implementation of these functions
+# and then add pointers to the respective implementation of each
+# function to the given variables.
+
+# common encryption/decryption routine
+# $1 key in hex form (please note for 3DES: even when ede3 for three
+# independent ciphers is given with the cipher specification, we hand in
+# either one key for k1 = k2 = k3, two keys which are concatinated for
+# k1 = k3, k2 independent, or three keys which are concatinated for
+# k1, k2, k3 independent)
+# $2 iv in hex form
+# $3 cipher - the cipher string is defined as specified in the openssl
+# enc(1ssl) specification for the option "-ciphername"
+# (e.g. aes-128-cbc or des-ede3-cbc)
+# $4 encrypt=1/decrypt=0
+# $5 de/encrypted data in hex form
+# return en/decrypted data in hex form
+my $encdec;
+
+#
+# Derive an RSA key from the given X9.31 parameters.
+# $1: modulus size
+# $2: E in hex form
+# $3: Xp1 in hex form
+# $4: Xp2 in hex form
+# $5: Xp in hex form
+# $6: Xq1 in hex form
+# $7: Xq2 in hex form
+# $8: Xq in hex form
+# return: string with the calculated values in hex format, where each value
+# is separated from the previous with a \n in the following order:
+# P\n
+# Q\n
+# N\n
+# D\n
+my $rsa_derive;
+
+# Sign a message with RSA
+# $1: data to be signed in hex form
+# $2: Hash algo
+# $3: Key file in PEM format with the private key
+# return: digest in hex format
+my $rsa_sign;
+
+# Verify a message with RSA
+# $1: data to be verified in hex form
+# $2: hash algo
+# $3: file holding the public RSA key in PEM format
+# $4: file holding the signature in binary form
+# return: 1 == verified / 0 == not verified
+my $rsa_verify;
+
+# generate a new private RSA key with the following properties:
+# exponent is 65537
+# PEM format
+# $1 key size in bit
+# $2 keyfile name
+# return: nothing, but file created
+my $gen_rsakey;
+
+# Creating a hash
+# $1: Plaintext in hex form
+# $2: hash type in the form documented in openssl's dgst(1ssl) - e.g.
+# sha1, sha224, sha256, sha384, sha512
+# return: hash in hex form
+my $hash;
+
+# supplying the call to the external cipher implementation
+# that is being used to keep STDIN and STDOUT open
+# to maintain the state of the block chaining
+# $1: cipher
+# $2: 1=encryption, 0=decryption
+# $3: buffersize needed for openssl
+# $4: encryption key in binary form
+# $5: IV in binary form
+# return: command line to execute the application
+my $state_cipher;
+# the only difference of the DES version is that it implements the inner loop
+# of the TDES tests
+my $state_cipher_des;
+
+# supplying the call to the external cipher implementation
+# that is being used to keep STDIN and STDOUT open
+# to maintain the state of the RNG with its seed
+#
+# input holds seed values
+# $1: cipher key in hex format
+# $2: DT value in hex format
+# $3: V value in hex format
+#
+# return: command line to execute the application
+#
+# the application is expected to deliver random values on STDOUT - the script
+# reads 128 bits repeatedly where the state of the RNG must be retained
+# between the reads. The output of the RNG on STDOUT is assumed to be binary.
+my $state_rng;
+
+# Generate an HMAC based on SHAx
+# $1: Key to be used for the HMAC in hex format
+# $2: length of the hash to be calculated in bits
+# $3: Message for which the HMAC shall be calculated in hex format
+# $4: hash type (1 - SHA1, 224 - SHA224, and so on)
+# return: calculated HMAC in hex format
+my $hmac;
+
+#
+# Generate the P, Q, G, Seed, counter, h (value used to generate g) values
+# for DSA
+# $1: modulus size
+# return: string with the calculated values in hex format, where each value
+# is separated from the previous with a \n in the following order:
+# P\n
+# Q\n
+# G\n
+# Seed\n
+# counter\n
+# h
+my $dsa_pqggen;
+
+#
+# Generate an DSA public key from the provided parameters:
+# $1: Name of file to create
+# $2: P in hex form
+# $3: Q in hex form
+# $4: G in hex form
+# $5: Y in hex form
+my $dsa_genpubkey;
+
+# Verify a message with DSA
+# $1: data to be verified in hex form
+# $2: file holding the public DSA key in PEM format
+# $3: R value of the signature
+# $4: S value of the signature
+# return: 1 == verified / 0 == not verified
+my $dsa_verify;
+
+# generate a new DSA key with the following properties:
+# PEM format
+# $1 keyfile name
+# return: file created, hash with keys of P, Q, G in hex format
+my $gen_dsakey;
+
+# Sign a message with DSA
+# $1: data to be signed in hex form
+# $2: Key file in PEM format with the private key
+# return: hash of digest information in hex format with Y, R, S as keys
+my $dsa_sign;
+
+################################################################
+##### OpenSSL interface functions
+################################################################
+sub openssl_encdec($$$$$) {
+ my $key=shift;
+ my $iv=shift;
+ my $cipher=shift;
+ my $enc = (shift) ? "-e" : "-d";
+ my $data=shift;
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "-iv $iv" if ($iv);
+
+ $data=hex2bin($data);
+ my $program="openssl enc -$cipher -nopad -nosalt -K $key $enc $iv";
+ $program = "rc4 -k $key" if $opt{'R'}; #for ARCFOUR, no IV must be given
+ $data=pipe_through_program($data,$program);
+ return bin2hex($data);
+}
+
+sub openssl_rsa_sign($$$) {
+ my $data = shift;
+ my $cipher = shift;
+ my $keyfile = shift;
+
+ $data=hex2bin($data);
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ $data=pipe_through_program($data,
+ "openssl dgst -$cipher -binary -sign $keyfile");
+ return bin2hex($data);
+}
+
+sub openssl_rsa_verify($$$$) {
+ my $data = shift;
+ my $cipher = shift;
+ my $keyfile = shift;
+ my $sigfile = shift;
+
+ $data = hex2bin($data);
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ $data = pipe_through_program($data,
+ "openssl dgst -$cipher -binary -verify $keyfile -signature $sigfile");
+
+ # Parse through the OpenSSL output information
+ return ($data =~ /OK/);
+}
+
+sub openssl_gen_rsakey($$) {
+ my $keylen = shift;
+ my $file = shift;
+
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ # generating of a key with exponent 0x10001
+ my @args = ("openssl", "genrsa", "-F4", "-out", "$file", "$keylen");
+ system(@args) == 0
+ or die "system @args failed: $?";
+ die "system @args failed: file $file not created" if (! -f $file);
+}
+
+sub openssl_hash($$) {
+ my $pt = shift;
+ my $cipher = shift;
+
+ die "ARCFOUR not available for hashes" if $opt{'R'};
+ my $hash = hex2bin($pt);
+ #bin2hex not needed as the '-hex' already converts it
+ return pipe_through_program($hash, "openssl dgst -$cipher -hex");
+}
+
+sub openssl_state_cipher($$$$$) {
+ my $cipher = shift;
+ my $encdec = shift;
+ my $bufsize = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ my $enc = $encdec ? "-e": "-d";
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "-iv ".bin2hex($iv) if ($iv);
+
+ my $out = "openssl enc -'$cipher' $enc -nopad -nosalt -bufsize $bufsize -K ".bin2hex($key)." $iv";
+ #for ARCFOUR, no IV must be given
+ $out = "rc4 -k " . bin2hex($key) if $opt{'R'};
+ return $out;
+}
+
+###### End of OpenSSL interface implementation ############
+
+###########################################################
+###### libgcrypt implementation
+###########################################################
+sub libgcrypt_encdec($$$$$) {
+ my $key=shift;
+ my $iv=shift;
+ my $cipher=shift;
+ my $enc = (shift) ? "encrypt" : "decrypt";
+ my $data=shift;
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "--iv $iv" if ($iv);
+
+ my $program="fipsdrv --key $key $iv --algo $cipher $enc";
+
+ return pipe_through_program($data,$program);
+
+}
+
+sub libgcrypt_rsa_derive($$$$$$$$) {
+ my $n = shift;
+ my $e = shift;
+ my $xp1 = shift;
+ my $xp2 = shift;
+ my $xp = shift;
+ my $xq1 = shift;
+ my $xq2 = shift;
+ my $xq = shift;
+ my $sexp;
+ my @tmp;
+
+ $n = sprintf ("%u", $n);
+ $e = sprintf ("%u", hex($e));
+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")"
+ . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")"
+ . "(derive-parms"
+ . "(Xp1 #$xp1#)"
+ . "(Xp2 #$xp2#)"
+ . "(Xp #$xp#)"
+ . "(Xq1 #$xq1#)"
+ . "(Xq2 #$xq2#)"
+ . "(Xq #$xq#))))\n";
+
+ return pipe_through_program($sexp, "fipsdrv rsa-derive");
+}
+
+
+sub libgcrypt_rsa_sign($$$) {
+ my $data = shift;
+ my $hashalgo = shift;
+ my $keyfile = shift;
+
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+
+ return pipe_through_program($data,
+ "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile rsa-sign");
+}
+
+sub libgcrypt_rsa_verify($$$$) {
+ my $data = shift;
+ my $hashalgo = shift;
+ my $keyfile = shift;
+ my $sigfile = shift;
+
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ $data = pipe_through_program($data,
+ "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify");
+
+ # Parse through the output information
+ return ($data =~ /GOOD signature/);
+}
+
+sub libgcrypt_gen_rsakey($$) {
+ my $keylen = shift;
+ my $file = shift;
+
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ my @args = ("fipsdrv --keysize $keylen rsa-gen > $file");
+ system(@args) == 0
+ or die "system @args failed: $?";
+ die "system @args failed: file $file not created" if (! -f $file);
+}
+
+sub libgcrypt_hash($$) {
+ my $pt = shift;
+ my $hashalgo = shift;
+
+ my $program = "fipsdrv --algo $hashalgo digest";
+ die "ARCFOUR not available for hashes" if $opt{'R'};
+
+ return pipe_through_program($pt, $program);
+}
+
+sub libgcrypt_state_cipher($$$$$) {
+ my $cipher = shift;
+ my $enc = (shift) ? "encrypt": "decrypt";
+ my $bufsize = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "--iv ".bin2hex($iv) if ($iv);
+
+ my $program="fipsdrv --binary --key ".bin2hex($key)." $iv --algo '$cipher' --chunk '$bufsize' $enc";
+
+ return $program;
+}
+
+sub libgcrypt_state_cipher_des($$$$$) {
+ my $cipher = shift;
+ my $enc = (shift) ? "encrypt": "decrypt";
+ my $bufsize = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "--iv ".bin2hex($iv) if ($iv);
+
+ my $program="fipsdrv --algo '$cipher' --mct-server $enc";
+
+ return $program;
+}
+
+sub libgcrypt_state_rng($$$) {
+ my $key = shift;
+ my $dt = shift;
+ my $v = shift;
+
+ return "fipsdrv --binary --loop --key $key --iv $v --dt $dt random";
+}
+
+sub libgcrypt_hmac($$$$) {
+ my $key = shift;
+ my $maclen = shift;
+ my $msg = shift;
+ my $hashtype = shift;
+
+ my $program = "fipsdrv --key $key --algo $hashtype hmac-sha";
+ return pipe_through_program($msg, $program);
+}
+
+sub libgcrypt_dsa_pqggen($) {
+ my $mod = shift;
+
+ my $program = "fipsdrv --keysize $mod dsa-pqg-gen";
+ return pipe_through_program("", $program);
+}
+
+sub libgcrypt_gen_dsakey($) {
+ my $file = shift;
+
+ my $program = "fipsdrv --keysize 1024 --key $file dsa-gen";
+ my $tmp;
+ my %ret;
+
+ die "ARCFOUR not available for DSA" if $opt{'R'};
+
+ $tmp = pipe_through_program("", $program);
+ die "dsa key gen failed: file $file not created" if (! -f $file);
+
+ @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp);
+ return %ret;
+}
+
+sub libgcrypt_dsa_genpubkey($$$$$) {
+ my $filename = shift;
+ my $p = shift;
+ my $q = shift;
+ my $g = shift;
+ my $y = shift;
+
+ my $sexp;
+
+ $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))";
+
+ open(FH, ">", $filename) or die;
+ print FH $sexp;
+ close FH;
+}
+
+sub libgcrypt_dsa_sign($$) {
+ my $data = shift;
+ my $keyfile = shift;
+ my $tmp;
+ my %ret;
+
+ die "ARCFOUR not available for DSA" if $opt{'R'};
+
+ $tmp = pipe_through_program($data, "fipsdrv --key $keyfile dsa-sign");
+ @ret{'Y', 'R', 'S'} = split(/\n/, $tmp);
+ return %ret;
+}
+
+sub libgcrypt_dsa_verify($$$$) {
+ my $data = shift;
+ my $keyfile = shift;
+ my $r = shift;
+ my $s = shift;
+
+ my $ret;
+
+ die "ARCFOUR not available for DSA" if $opt{'R'};
+
+ my $sigfile = "$keyfile.sig";
+ open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?";
+ print FH "(sig-val(dsa(r #$r#)(s #$s#)))";
+ close FH;
+
+ $ret = pipe_through_program($data,
+ "fipsdrv --key $keyfile --signature $sigfile dsa-verify");
+ unlink ($sigfile);
+ # Parse through the output information
+ return ($ret =~ /GOOD signature/);
+}
+
+######### End of libgcrypt implementation ################
+
+################################################################
+###### Vendor1 interface functions
+################################################################
+
+sub vendor1_encdec($$$$$) {
+ my $key=shift;
+ my $iv=shift;
+ my $cipher=shift;
+ my $enc = (shift) ? "encrypt" : "decrypt";
+ my $data=shift;
+
+ $data=hex2bin($data);
+ my $program = "./aes $enc $key";
+ $data=pipe_through_program($data,$program);
+ return bin2hex($data);
+}
+
+sub vendor1_state_cipher($$$$$) {
+ my $cipher = shift;
+ my $encdec = shift;
+ my $bufsize = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ $key = bin2hex($key);
+ my $enc = $encdec ? "encrypt": "decrypt";
+ my $out = "./aes $enc $key $bufsize";
+ return $out;
+}
+
+##### No other interface functions below this point ######
+##########################################################
+
+##########################################################
+# General helper routines
+
+# Executing a program by feeding STDIN and retrieving
+# STDOUT
+# $1: data string to be piped to the app on STDIN
+# rest: program and args
+# returns: STDOUT of program as string
+sub pipe_through_program($@) {
+ my $in = shift;
+ my @args = @_;
+
+ my ($CO, $CI);
+ my $pid = open2($CO, $CI, @args);
+
+ my $out = "";
+ my $len = length($in);
+ my $first = 1;
+ while (1) {
+ my $rin = "";
+ my $win = "";
+ # Output of prog is FD that we read
+ vec($rin,fileno($CO),1) = 1;
+ # Input of prog is FD that we write
+ # check for $first is needed because we can have NULL input
+ # that is to be written to the app
+ if ( $len > 0 || $first) {
+ (vec($win,fileno($CI),1) = 1);
+ $first=0;
+ }
+ # Let us wait for 100ms
+ my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1);
+ if ( $wout ) {
+ my $written = syswrite($CI, $in, $len);
+ die "broken pipe" if !defined $written;
+ $len -= $written;
+ substr($in, 0, $written) = "";
+ if ($len <= 0) {
+ close $CI or die "broken pipe: $!";
+ }
+ }
+ if ( $rout ) {
+ my $tmp_out = "";
+ my $bytes_read = sysread($CO, $tmp_out, 4096);
+ $out .= $tmp_out;
+ last if ($bytes_read == 0);
+ }
+ }
+ close $CO or die "broken pipe: $!";
+ waitpid $pid, 0;
+
+ return $out;
+}
+
+#
+# convert ASCII hex to binary input
+# $1 ASCII hex
+# return binary representation
+sub hex2bin($) {
+ my $in = shift;
+ my $len = length($in);
+ $len = 0 if ($in eq "00");
+ return pack("H$len", "$in");
+}
+
+#
+# convert binary input to ASCII hex
+# $1 binary value
+# return ASCII hex representation
+sub bin2hex($) {
+ my $in = shift;
+ my $len = length($in)*2;
+ return unpack("H$len", "$in");
+}
+
+# $1: binary byte (character)
+# returns: binary byte with odd parity using low bit as parity bit
+sub odd_par($) {
+ my $in = ord(shift);
+ my $odd_count=0;
+ for(my $i=1; $i<8; $i++) {
+ $odd_count++ if ($in & (1<<$i));
+ }
+
+ my $out = $in;
+ if ($odd_count & 1) { # check if parity is already odd
+ $out &= ~1; # clear the low bit
+ } else {
+ $out |= 1; # set the low bit
+ }
+
+ return chr($out);
+}
+
+# DES keys uses only the 7 high bits of a byte, the 8th low bit
+# is the parity bit
+# as the new key is calculated from oldkey XOR cipher in the MCT test,
+# the parity is not really checked and needs to be set to match
+# expectation (OpenSSL does not really care, but the FIPS
+# test result is expected that the key has the appropriate parity)
+# $1: arbitrary binary string
+# returns: string with odd parity set in low bit of each byte
+sub fix_key_parity($) {
+ my $in = shift;
+ my $out = "";
+ for (my $i = 0; $i < length($in); $i++) {
+ $out .= odd_par(substr($in, $i, 1));
+ }
+
+ return $out;
+}
+
+####################################################
+# DER/PEM utility functions
+# Cf. http://www.columbia.edu/~ariel/ssleay/layman.html
+
+# Convert unsigned integer to base256 bigint bytes
+# $1 integer
+# returns base256 octet string
+sub int_base256_unsigned($) {
+ my $n = shift;
+
+ my $out = chr($n & 255);
+ while ($n>>=8) {
+ $out = chr($n & 255) . $out;
+ }
+
+ return $out;
+}
+
+# Convert signed integer to base256 bigint bytes
+# $1 integer
+# returns base256 octet string
+sub int_base256_signed($) {
+ my $n = shift;
+ my $negative = ($n < 0);
+
+ if ($negative) {
+ $n = -$n-1;
+ }
+
+ my $out = int_base256_unsigned($n);
+
+ if (ord(substr($out, 0, 1)) & 128) {
+ # it's supposed to be positive but has sign bit set,
+ # add a leading zero
+ $out = chr(0) . $out;
+ }
+
+ if ($negative) {
+ my $neg = chr(255) x length($out);
+ $out ^= $neg;
+ }
+
+ return $out;
+}
+
+# Length header for specified DER object length
+# $1 length as integer
+# return octet encoding for length
+sub der_len($) {
+ my $len = shift;
+
+ if ($len <= 127) {
+ return chr($len);
+ } else {
+ my $blen = int_base256_unsigned($len);
+
+ return chr(128 | length($blen)) . $blen;
+ }
+}
+
+# Prepend length header to object
+# $1 object as octet sequence
+# return length header for object followed by object as octets
+sub der_len_obj($) {
+ my $x = shift;
+
+ return der_len(length($x)) . $x;
+}
+
+# DER sequence
+# $* objects
+# returns DER sequence consisting of the objects passed as arguments
+sub der_seq {
+ my $seq = join("", @_);
+ return chr(0x30) . der_len_obj($seq);
+}
+
+# DER bitstring
+# $1 input octets (must be full octets, fractional octets not supported)
+# returns input encapsulated as bitstring
+sub der_bitstring($) {
+ my $x = shift;
+
+ $x = chr(0) . $x;
+
+ return chr(0x03) . der_len_obj($x);
+}
+
+# base-128-encoded integer, used for object numbers.
+# $1 integer
+# returns octet sequence
+sub der_base128($) {
+ my $n = shift;
+
+ my $out = chr($n & 127);
+
+ while ($n>>=7) {
+ $out = chr(128 | ($n & 127)) . $out;
+ }
+
+ return $out;
+}
+
+# Generating the PEM certificate string
+# (base-64-encoded DER string)
+# $1 DER string
+# returns octet sequence
+sub pem_cert($) {
+ my $n = shift;
+
+ my $out = "-----BEGIN PUBLIC KEY-----\n";
+ $out .= encode_base64($n);
+ $out .= "-----END PUBLIC KEY-----\n";
+
+ return $out;
+}
+
+# DER object identifier
+# $* sequence of id numbers
+# returns octets
+sub der_objectid {
+ my $v1 = shift;
+ my $v2 = shift;
+
+ my $out = chr(40*$v1 + $v2) . join("", map { der_base128($_) } @_);
+
+ return chr(0x06) . der_len_obj($out);
+}
+
+# DER signed integer
+# $1 number as octet string (base 256 representation, high byte first)
+# returns number in DER integer encoding
+sub der_bigint($) {
+ my $x = shift;
+
+ return chr(0x02) . der_len_obj($x);
+}
+
+# DER positive integer with leading zeroes stripped
+# $1 number as octet string (base 256 representation, high byte first)
+# returns number in DER integer encoding
+sub der_pos_bigint($) {
+ my $x = shift;
+
+ # strip leading zero digits
+ $x =~ s/^[\0]+//;
+
+ # need to prepend a zero if high bit set, since it would otherwise be
+ # interpreted as a negative number. Also needed for number 0.
+ if (!length($x) || ord(substr($x, 0, 1)) >= 128) {
+ $x = chr(0) . $x;
+ }
+
+ return der_bigint($x);
+}
+
+# $1 number as signed integer
+# returns number as signed DER integer encoding
+sub der_int($) {
+ my $n = shift;
+
+ return der_bigint(int_base256_signed($n));
+}
+
+# the NULL object constant
+sub der_null() {
+ return chr(0x05) . chr(0x00);
+}
+
+# Unit test helper
+# $1 calculated result
+# $2 expected result
+# no return value, dies if results differ, showing caller's line number
+sub der_test($$) {
+ my $actual = bin2hex(shift);
+ my $expected = shift;
+
+ my @caller = caller;
+ $actual eq $expected or die "Error:line $caller[2]:assertion failed: "
+ ."$actual != $expected\n";
+}
+
+# Unit testing for the DER encoding functions
+# Examples from http://www.columbia.edu/~ariel/ssleay/layman.html
+# No input, no output. Dies if unit tests fail.
+sub der_unit_test {
+ ## uncomment these if you want to test the test framework
+ #print STDERR "Unit test running\n";
+ #der_test chr(0), "42";
+
+ der_test der_null, "0500";
+
+ # length bytes
+ der_test der_len(1), "01";
+ der_test der_len(127), "7f";
+ der_test der_len(128), "8180";
+ der_test der_len(256), "820100";
+ der_test der_len(65536), "83010000";
+
+ # bigint
+ der_test der_bigint(chr(0)), "020100";
+ der_test der_bigint(chr(128)), "020180"; # -128
+ der_test der_pos_bigint(chr(128)), "02020080"; # +128
+ der_test der_pos_bigint(chr(0).chr(0).chr(1)), "020101";
+ der_test der_pos_bigint(chr(0)), "020100";
+
+ # integers (tests base256 conversion)
+ der_test der_int( 0), "020100";
+ der_test der_int( 127), "02017f";
+ der_test der_int( 128), "02020080";
+ der_test der_int( 256), "02020100";
+ der_test der_int( -1), "0201ff";
+ der_test der_int( -128), "020180";
+ der_test der_int( -129), "0202ff7f";
+ der_test der_int(-65536), "0203ff0000";
+ der_test der_int(-65537), "0203feffff";
+
+ # object encoding, "RSA Security"
+ der_test der_base128(840), "8648";
+ der_test der_objectid(1, 2, 840, 113549), "06062a864886f70d";
+
+ # Combinations
+ der_test der_bitstring("ABCD"), "03050041424344";
+ der_test der_bitstring(der_null), "0303000500";
+ der_test der_seq(der_int(0), der_null), "30050201000500";
+
+ # The big picture
+ der_test der_seq(der_seq(der_objectid(1, 2, 840, 113549), der_null),
+ der_bitstring(der_seq(der_pos_bigint(chr(5)),
+ der_pos_bigint(chr(3))))),
+ "3017300a06062a864886f70d05000309003006020105020103";
+}
+
+####################################################
+# OpenSSL missing functionality workarounds
+
+## Format of an RSA public key:
+# 0:d=0 hl=3 l= 159 cons: SEQUENCE
+# 3:d=1 hl=2 l= 13 cons: SEQUENCE
+# 5:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
+# 16:d=2 hl=2 l= 0 prim: NULL
+# 18:d=1 hl=3 l= 141 prim: BIT STRING
+# [ sequence: INTEGER (n), INTEGER (e) ]
+
+# generate RSA pub key in PEM format
+# $1: filename where PEM key is to be stored
+# $2: n of the RSA key in hex
+# $3: e of the RSA key in hex
+# return: nothing, but file created
+sub gen_pubrsakey($$$) {
+ my $filename=shift;
+ my $n = shift;
+ my $e = shift;
+
+ # make sure the DER encoder works ;-)
+ der_unit_test();
+
+ # generate DER encoding of the public key
+
+ my $rsaEncryption = der_objectid(1, 2, 840, 113549, 1, 1, 1);
+
+ my $der = der_seq(der_seq($rsaEncryption, der_null),
+ der_bitstring(der_seq(der_pos_bigint(hex2bin($n)),
+ der_pos_bigint(hex2bin($e)))));
+
+ open(FH, ">", $filename) or die;
+ print FH pem_cert($der);
+ close FH;
+
+}
+
+# generate RSA pub key in PEM format
+#
+# This implementation uses "openssl asn1parse -genconf" which was added
+# in openssl 0.9.8. It is not available in older openssl versions.
+#
+# $1: filename where PEM key is to be stored
+# $2: n of the RSA key in hex
+# $3: e of the RSA key in hex
+# return: nothing, but file created
+sub gen_pubrsakey_using_openssl($$$) {
+ my $filename=shift;
+ my $n = shift;
+ my $e = shift;
+
+ my $asn1 = "asn1=SEQUENCE:pubkeyinfo
+
+[pubkeyinfo]
+algorithm=SEQUENCE:rsa_alg
+pubkey=BITWRAP,SEQUENCE:rsapubkey
+
+[rsa_alg]
+algorithm=OID:rsaEncryption
+parameter=NULL
+
+[rsapubkey]
+n=INTEGER:0x$n
+
+e=INTEGER:0x$e";
+
+ open(FH, ">$filename.cnf") or die "Cannot create file $filename.cnf: $?";
+ print FH $asn1;
+ close FH;
+ my @args = ("openssl", "asn1parse", "-genconf", "$filename.cnf", "-noout", "-out", "$filename.der");
+ system(@args) == 0 or die "system @args failed: $?";
+ @args = ("openssl", "rsa", "-inform", "DER", "-in", "$filename.der",
+ "-outform", "PEM", "-pubin", "-pubout", "-out", "$filename");
+ system(@args) == 0 or die "system @args failed: $?";
+ die "RSA PEM formatted key file $filename was not created"
+ if (! -f $filename);
+
+ unlink("$filename.cnf");
+ unlink("$filename.der");
+}
+
+############################################
+# Test cases
+
+# This is the Known Answer Test
+# $1: the string that we have to put in front of the key
+# when printing the key
+# $2: crypto key1 in hex form
+# $3: crypto key2 in hex form (TDES, undef otherwise)
+# $4: crypto key3 in hex form (TDES, undef otherwise)
+# $5: IV in hex form
+# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form
+# $7: cipher
+# $8: encrypt=1/decrypt=0
+# return: string formatted as expected by CAVS
+sub kat($$$$$$$$) {
+ my $keytype = shift;
+ my $key1 = shift;
+ my $key2 = shift;
+ my $key3 = shift;
+ my $iv = shift;
+ my $pt = shift;
+ my $cipher = shift;
+ my $enc = shift;
+
+ my $out = "";
+
+ $out .= "$keytype = $key1\n";
+
+ # this is the concardination of the keys for 3DES
+ if (defined($key2)) {
+ $out .= "KEY2 = $key2\n";
+ $key1 = $key1 . $key2;
+ }
+ if (defined($key3)) {
+ $out .= "KEY3 = $key3\n";
+ $key1= $key1 . $key3;
+ }
+
+ $out .= "IV = $iv\n" if (defined($iv) && $iv ne "");
+ if ($enc) {
+ $out .= "PLAINTEXT = $pt\n";
+ $out .= "CIPHERTEXT = " . &$encdec($key1, $iv, $cipher, 1, $pt) . "\n";
+ } else {
+ $out .= "CIPHERTEXT = $pt\n";
+ $out .= "PLAINTEXT = " . &$encdec($key1, $iv, $cipher, 0, $pt) . "\n";
+ }
+
+ return $out;
+}
+
+# This is the Known Answer Test for Hashes
+# $1: Plaintext in hex form
+# $2: hash
+# $3: hash length (undef if not applicable)
+# return: string formatted as expected by CAVS
+sub hash_kat($$$) {
+ my $pt = shift;
+ my $cipher = shift;
+ my $len = shift;
+
+ my $out = "";
+ $out .= "Len = $len\n" if (defined($len));
+ $out .= "Msg = $pt\n";
+
+ $pt = "" if(!$len);
+ $out .= "MD = " . &$hash($pt, $cipher) . "\n";
+ return $out;
+}
+
+# Known Answer Test for HMAC hash
+# $1: key length in bytes
+# $2: MAC length in bytes
+# $3: key for HMAC in hex form
+# $4: message to be hashed
+# return: string formatted as expected by CAVS
+sub hmac_kat($$$$) {
+ my $klen = shift;
+ my $tlen = shift;
+ my $key = shift;
+ my $msg = shift;
+
+ # XXX this is a hack - we need to decipher the HMAC REQ files in a more
+ # sane way
+ #
+ # This is a conversion table from the expected hash output size
+ # to the assumed hash type - we only define here the block size of
+ # the underlying hashes and do not allow any truncation
+ my %hashtype = (
+ 20 => 1,
+ 28 => 224,
+ 32 => 256,
+ 48 => 384,
+ 64 => 512
+ );
+
+ die "Hash output size $tlen is not supported!"
+ if(!defined($hashtype{$tlen}));
+
+ my $out = "";
+ $out .= "Klen = $klen\n";
+ $out .= "Tlen = $tlen\n";
+ $out .= "Key = $key\n";
+ $out .= "Msg = $msg\n";
+ $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n";
+
+ return $out;
+}
+
+
+# Cipher Monte Carlo Testing
+# $1: the string that we have to put in front of the key
+# when printing the key
+# $2: crypto key1 in hex form
+# $3: crypto key2 in hex form (TDES, undef otherwise)
+# $4: crypto key3 in hex form (TDES, undef otherwise)
+# $5: IV in hex form
+# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form
+# $7: cipher
+# $8: encrypt=1/decrypt=0
+# return: string formatted as expected by CAVS
+sub crypto_mct($$$$$$$$) {
+ my $keytype = shift;
+ my $key1 = hex2bin(shift);
+ my $key2 = shift;
+ my $key3 = shift;
+ my $iv = hex2bin(shift);
+ my $source_data = hex2bin(shift);
+ my $cipher = shift;
+ my $enc = shift;
+
+ my $out = "";
+
+ $key2 = hex2bin($key2) if (defined($key2));
+ $key3 = hex2bin($key3) if (defined($key3));
+ my $bufsize = length($source_data);
+
+ # for AES: outer loop 0-99, inner 0-999 based on FIPS compliance tests
+ # for RC4: outer loop 0-99, inner 0-999 based on atsec compliance tests
+ # for DES: outer loop 0-399, inner 0-9999 based on FIPS compliance tests
+ my $ciph = substr($cipher,0,3);
+ my $oloop=100;
+ my $iloop=1000;
+ if ($ciph =~ /des/) {$oloop=400;$iloop=10000;}
+
+ for (my $i=0; $i<$oloop; ++$i) {
+ $out .= "COUNT = $i\n";
+ if (defined($key2)) {
+ $out .= "$keytype = ". bin2hex($key1). "\n";
+ $out .= "KEY2 = ". bin2hex($key2). "\n";
+ $key1 = $key1 . $key2;
+ } else {
+ $out .= "$keytype = ". bin2hex($key1). "\n";
+ }
+ if(defined($key3)) {
+ $out .= "KEY3 = ". bin2hex($key3). "\n";
+ $key1 = $key1 . $key3;
+ }
+ my $keylen = length($key1);
+
+ $out .= "IV = ". bin2hex($iv) . "\n"
+ if (defined($iv) && $iv ne "");
+
+ if ($enc) {
+ $out .= "PLAINTEXT = ". bin2hex($source_data). "\n";
+ } else {
+ $out .= "CIPHERTEXT = ". bin2hex($source_data). "\n";
+ }
+ my ($CO, $CI);
+ my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv);
+ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/);
+ my $pid = open2($CO, $CI, $cipher_imp);
+
+ my $calc_data = $iv; # CT[j]
+ my $old_calc_data; # CT[j-1]
+ my $old_old_calc_data; # CT[j-2]
+ my $next_source;
+
+ # TDES inner loop implements logic within driver
+ if ($cipher =~ /des/) {
+ # Need to provide a dummy IV in case of ECB mode.
+ my $iv_arg = (defined($iv) && $iv ne "")
+ ? bin2hex($iv)
+ : "00"x(length($source_data));
+ print $CI "1\n"
+ .$iloop."\n"
+ .bin2hex($key1)."\n"
+ .$iv_arg."\n"
+ .bin2hex($source_data)."\n\n" or die;
+ chomp(my $line = <$CO>);
+ $calc_data = hex2bin($line);
+ chomp($line = <$CO>);
+ $old_calc_data = hex2bin($line);
+ chomp($line = <$CO>);
+ $old_old_calc_data = hex2bin($line);
+ chomp($line = <$CO>);
+ $iv = hex2bin($line) if (defined($iv) && $iv ne "");
+ chomp($line = <$CO>);
+ $next_source = hex2bin($line);
+ # Skip over empty line.
+ $line = <$CO>;
+ } else {
+ for (my $j = 0; $j < $iloop; ++$j) {
+ $old_old_calc_data = $old_calc_data;
+ $old_calc_data = $calc_data;
+
+ #print STDERR "source_data=", bin2hex($source_data), "\n";
+ syswrite $CI, $source_data or die $!;
+ my $len = sysread $CO, $calc_data, $bufsize;
+
+ #print STDERR "len=$len, bufsize=$bufsize\n";
+ die if $len ne $bufsize;
+ #print STDERR "calc_data=", bin2hex($calc_data), "\n";
+
+ if ( (!$enc && $ciph =~ /des/) ||
+ $ciph =~ /rc4/ ||
+ $cipher =~ /ecb/ ) {
+ #TDES in decryption mode, RC4 and ECB mode
+ #have a special rule
+ $source_data = $calc_data;
+ } else {
+ $source_data = $old_calc_data;
+ }
+ }
+ }
+ close $CO;
+ close $CI;
+ waitpid $pid, 0;
+
+ if ($enc) {
+ $out .= "CIPHERTEXT = ". bin2hex($calc_data). "\n\n";
+ } else {
+ $out .= "PLAINTEXT = ". bin2hex($calc_data). "\n\n";
+ }
+
+ if ( $ciph =~ /aes/ ) {
+ $key1 ^= substr($old_calc_data . $calc_data, -$keylen);
+ #print STDERR bin2hex($key1)."\n";
+ } elsif ( $ciph =~ /des/ ) {
+ die "Wrong keylen $keylen" if ($keylen != 24);
+
+ # $nkey needed as $key holds the concatenation of the
+ # old key atm
+ my $nkey = fix_key_parity(substr($key1,0,8) ^ $calc_data);
+ #print STDERR "KEY1 = ". bin2hex($nkey)."\n";
+ if (substr($key1,0,8) ne substr($key1,8,8)) {
+ #print STDERR "KEY2 recalc: KEY1==KEY3, KEY2 indep. or all KEYs are indep.\n";
+ $key2 = fix_key_parity((substr($key1,8,8) ^ $old_calc_data));
+ } else {
+ #print STDERR "KEY2 recalc: KEY1==KEY2==KEY3\n";
+ $key2 = fix_key_parity((substr($key1,8,8) ^ $calc_data));
+ }
+ #print STDERR "KEY2 = ". bin2hex($key2)."\n";
+ if ( substr($key1,0,8) eq substr($key1,16)) {
+ #print STDERR "KEY3 recalc: KEY1==KEY2==KEY3 or KEY1==KEY3, KEY2 indep.\n";
+ $key3 = fix_key_parity((substr($key1,16) ^ $calc_data));
+ } else {
+ #print STDERR "KEY3 recalc: all KEYs are independent\n";
+ $key3 = fix_key_parity((substr($key1,16) ^ $old_old_calc_data));
+ }
+ #print STDERR "KEY3 = ". bin2hex($key3)."\n";
+
+ # reset the first key - concardination happens at
+ # beginning of loop
+ $key1=$nkey;
+ } elsif ($ciph =~ /rc4/ ) {
+ $key1 ^= substr($calc_data, 0, 16);
+ #print STDERR bin2hex($key1)."\n";
+ } else {
+ die "Test limitation: cipher '$cipher' not supported in Monte Carlo testing";
+ }
+
+ if ($cipher =~ /des-ede3-ofb/) {
+ $source_data = $source_data ^ $next_source;
+ } elsif (!$enc && $cipher =~ /des-ede3-cfb/) {
+ #TDES decryption CFB has a special rule
+ $source_data = $next_source;
+ } elsif ( $ciph =~ /rc4/ || $cipher eq "des-ede3" || $cipher =~ /ecb/) {
+ #No resetting of IV as the IV is all zero set initially (i.e. no IV)
+ $source_data = $calc_data;
+ } elsif (! $enc && $ciph =~ /des/ ) {
+ #TDES in decryption mode has a special rule
+ $iv = $old_calc_data;
+ $source_data = $calc_data;
+ } else {
+ $iv = $calc_data;
+ $source_data = $old_calc_data;
+ }
+ }
+
+ return $out;
+}
+
+# Hash Monte Carlo Testing
+# $1: Plaintext in hex form
+# $2: hash
+# return: string formatted as expected by CAVS
+sub hash_mct($$) {
+ my $pt = shift;
+ my $cipher = shift;
+
+ my $out = "";
+
+ $out .= "Seed = $pt\n\n";
+
+ for (my $j=0; $j<100; ++$j) {
+ $out .= "COUNT = $j\n";
+ my $md0=$pt;
+ my $md1=$pt;
+ my $md2=$pt;
+ for (my $i=0; $i<1000; ++$i) {
+ #print STDERR "outer loop $j; inner loop $i\n";
+ my $mi= $md0 . $md1 . $md2;
+ $md0=$md1;
+ $md1=$md2;
+ $md2 = &$hash($mi, $cipher);
+ $md2 =~ s/\n//;
+ }
+ $out .= "MD = $md2\n\n";
+ $pt=$md2;
+ }
+
+ return $out;
+}
+
+# RSA SigGen test
+# $1: Message to be signed in hex form
+# $2: Hash algorithm
+# $3: file name with RSA key in PEM form
+# return: string formatted as expected by CAVS
+sub rsa_siggen($$$) {
+ my $data = shift;
+ my $cipher = shift;
+ my $keyfile = shift;
+
+ my $out = "";
+
+ $out .= "SHAAlg = $cipher\n";
+ $out .= "Msg = $data\n";
+ $out .= "S = " . &$rsa_sign($data, lc($cipher), $keyfile) . "\n";
+
+ return $out;
+}
+
+# RSA SigVer test
+# $1: Message to be verified in hex form
+# $2: Hash algorithm
+# $3: Signature of message in hex form
+# $4: n of the RSA key in hex in hex form
+# $5: e of the RSA key in hex in hex form
+# return: string formatted as expected by CAVS
+sub rsa_sigver($$$$$) {
+ my $data = shift;
+ my $cipher = shift;
+ my $signature = shift;
+ my $n = shift;
+ my $e = shift;
+
+ my $out = "";
+
+ $out .= "SHAAlg = $cipher\n";
+ $out .= "e = $e\n";
+ $out .= "Msg = $data\n";
+ $out .= "S = $signature\n";
+
+ # XXX maybe a secure temp file name is better here
+ # but since it is not run on a security sensitive
+ # system, I hope that this is fine
+ my $keyfile = "rsa_sigver.tmp.$$";
+ gen_pubrsakey($keyfile, $n, $e);
+
+ my $sigfile = "$keyfile.sig";
+ open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?";
+ print FH hex2bin($signature);
+ close FH;
+
+ $out .= "Result = " . (&$rsa_verify($data, lc($cipher), $keyfile, $sigfile) ? "P\n" : "F\n");
+
+ unlink($keyfile);
+ unlink($sigfile);
+
+ return $out;
+}
+
+# RSA X9.31 key generation test
+# $1 modulus size
+# $2 e
+# $3 xp1
+# $4 xp2
+# $5 Xp
+# $6 xq1
+# $7 xq2
+# $8 Xq
+# return: string formatted as expected by CAVS
+sub rsa_keygen($$$$$$$$) {
+ my $modulus = shift;
+ my $e = shift;
+ my $xp1 = shift;
+ my $xp2 = shift;
+ my $Xp = shift;
+ my $xq1 = shift;
+ my $xq2 = shift;
+ my $Xq = shift;
+
+ my $out = "";
+
+ my $ret = &$rsa_derive($modulus, $e, $xp1, $xp2, $Xp, $xq1, $xq2, $Xq);
+
+ my ($P, $Q, $N, $D) = split(/\n/, $ret);
+
+ $out .= "e = $e\n";
+ $out .= "xp1 = $xp1\n";
+ $out .= "xp2 = $xp2\n";
+ $out .= "Xp = $Xp\n";
+ $out .= "p = $P\n";
+ $out .= "xq1 = $xq1\n";
+ $out .= "xq2 = $xq2\n";
+ $out .= "Xq = $Xq\n";
+ $out .= "q = $Q\n";
+ $out .= "n = $N\n";
+ $out .= "d = $D\n\n";
+
+ return $out;
+
+}
+
+# X9.31 RNG test
+# $1 key for the AES cipher
+# $2 DT value
+# $3 V value
+# $4 type ("VST", "MCT")
+# return: string formatted as expected by CAVS
+sub rngx931($$$$) {
+ my $key=shift;
+ my $dt=shift;
+ my $v=shift;
+ my $type=shift;
+
+ my $out = "Key = $key\n";
+ $out .= "DT = $dt\n";
+ $out .= "V = $v\n";
+
+ my $count = 1;
+ $count = 10000 if ($type eq "MCT");
+
+ my $rnd_val = "";
+
+ # we read 16 bytes from RNG
+ my $bufsize = 16;
+
+ my ($CO, $CI);
+ my $rng_imp = &$state_rng($key, $dt, $v);
+ my $pid = open2($CO, $CI, $rng_imp);
+ for (my $i = 0; $i < $count; ++$i) {
+ my $len = sysread $CO, $rnd_val, $bufsize;
+ #print STDERR "len=$len, bufsize=$bufsize\n";
+ die "len=$len != bufsize=$bufsize" if $len ne $bufsize;
+ #print STDERR "calc_data=", bin2hex($rnd_val), "\n";
+ }
+ close $CO;
+ close $CI;
+ waitpid $pid, 0;
+
+ $out .= "R = " . bin2hex($rnd_val) . "\n\n";
+
+ return $out;
+}
+
+# DSA PQGGen test
+# $1 modulus size
+# $2 number of rounds to perform the test
+# return: string formatted as expected by CAVS
+sub dsa_pqggen_driver($$) {
+ my $mod = shift;
+ my $rounds = shift;
+
+ my $out = "";
+ for(my $i=0; $i<$rounds; $i++) {
+ my $ret = &$dsa_pqggen($mod);
+ my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret);
+ die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen"
+ if (!defined($P) || !defined($Q) || !defined($G) ||
+ !defined($Seed) || !defined($c) || !defined($H));
+
+ # now change the counter to decimal as CAVS wants decimal
+ # counter value although all other is HEX
+ $c = hex($c);
+
+ $out .= "P = $P\n";
+ $out .= "Q = $Q\n";
+ $out .= "G = $G\n";
+ $out .= "Seed = $Seed\n";
+ $out .= "c = $c\n";
+ $out .= "H = $H\n\n";
+ }
+
+ return $out;
+}
+
+
+# DSA SigGen test
+# $1: Message to be signed in hex form
+# $2: file name with DSA key in PEM form
+# return: string formatted as expected by CAVS
+sub dsa_siggen($$) {
+ my $data = shift;
+ my $keyfile = shift;
+
+ my $out = "";
+
+ my %ret = &$dsa_sign($data, $keyfile);
+
+ $out .= "Msg = $data\n";
+ $out .= "Y = " . $ret{'Y'} . "\n";
+ $out .= "R = " . $ret{'R'} . "\n";
+ $out .= "S = " . $ret{'S'} . "\n";
+
+ return $out;
+}
+
+
+# DSA signature verification
+# $1 modulus
+# $2 P
+# $3 Q
+# $4 G
+# $5 Y - public key
+# $6 r
+# $7 s
+# $8 message to be verified
+# return: string formatted as expected by CAVS
+sub dsa_sigver($$$$$$$$) {
+ my $modulus = shift;
+ my $p = shift;
+ my $q = shift;
+ my $g = shift;
+ my $y = shift;
+ my $r = shift;
+ my $s = shift;
+ my $msg = shift;
+
+ my $out = "";
+
+ #PQG are already printed - do not print them here
+
+ $out .= "Msg = $msg\n";
+ $out .= "Y = $y\n";
+ $out .= "R = $r\n";
+ $out .= "S = $s\n";
+
+ # XXX maybe a secure temp file name is better here
+ # but since it is not run on a security sensitive
+ # system, I hope that this is fine
+ my $keyfile = "dsa_sigver.tmp.$$";
+ &$dsa_genpubkey($keyfile, $p, $q, $g, $y);
+
+ $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n");
+
+ unlink($keyfile);
+
+ return $out;
+}
+
+##############################################################
+# Parser of input file and generator of result file
+#
+
+sub usage() {
+
+ print STDERR "Usage:
+$0 [-R] [-D] [-I name] <CAVS-test vector file>
+
+-R execution of ARCFOUR instead of OpenSSL
+-I NAME Use interface style NAME:
+ openssl OpenSSL (default)
+ libgcrypt Libgcrypt
+-D SigGen and SigVer are executed with DSA
+ Please note that the DSA CAVS vectors do not allow distinguishing
+ them from the RSA vectors. As the RSA test is the default, you have
+ to supply this option to apply the DSA logic";
+}
+
+# Parser of CAVS test vector file
+# $1: Test vector file
+# $2: Output file for test results
+# return: nothing
+sub parse($$) {
+ my $infile = shift;
+ my $outfile = shift;
+
+ my $out = "";
+
+ # this is my cipher/hash type
+ my $cipher = "";
+
+ # Test type
+ # 1 - cipher known answer test
+ # 2 - cipher Monte Carlo test
+ # 3 - hash known answer test
+ # 4 - hash Monte Carlo test
+ # 5 - RSA signature generation
+ # 6 - RSA signature verification
+ my $tt = 0;
+
+ # Variables for tests
+ my $keytype = ""; # we can have "KEY", "KEYs", "KEY1"
+ my $key1 = "";
+ my $key2 = undef; #undef needed for allowing
+ my $key3 = undef; #the use of them as input variables
+ my $pt = "";
+ my $enc = 1;
+ my $iv = "";
+ my $len = undef; #see key2|3
+ my $n = "";
+ my $e = "";
+ my $signature = "";
+ my $rsa_keyfile = "";
+ my $dsa_keyfile = "";
+ my $dt = "";
+ my $v = "";
+ my $klen = "";
+ my $tlen = "";
+ my $modulus = "";
+ my $capital_n = 0;
+ my $capital_p = "";
+ my $capital_q = "";
+ my $capital_g = "";
+ my $capital_y = "";
+ my $capital_r = "";
+ my $xp1 = "";
+ my $xp2 = "";
+ my $Xp = "";
+ my $xq1 = "";
+ my $xq2 = "";
+ my $Xq = "";
+
+ my $mode = "";
+
+ open(IN, "<$infile");
+ while(<IN>) {
+
+ my $line = $_;
+ chomp($line);
+ $line =~ s/\r//;
+
+ my $keylen = "";
+
+ # Mode and type check
+ # consider the following parsed line
+ # '# AESVS MCT test data for CBC'
+ # '# TDES Multi block Message Test for CBC'
+ # '# INVERSE PERMUTATION - KAT for CBC'
+ # '# SUBSTITUTION TABLE - KAT for CBC'
+ # '# TDES Monte Carlo (Modes) Test for CBC'
+ # '# "SHA-1 Monte" information for "IBMRHEL5"'
+ # '# "SigVer PKCS#1 Ver 1.5" information for "IBMRHEL5"'
+ # '# "SigGen PKCS#1 Ver 1.5" information for "IBMRHEL5"'
+ # '#RC4VS MCT test data'
+
+ # avoid false positives from user specified 'for "PRODUCT"' strings
+ my $tmpline = $line;
+ $tmpline =~ s/ for ".*"//;
+
+ ##### Extract cipher
+ # XXX there may be more - to be added
+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) {
+ if ($tmpline =~ /CBC/) { $mode="cbc"; }
+ elsif ($tmpline =~ /ECB/) { $mode="ecb"; }
+ elsif ($tmpline =~ /OFB/) { $mode="ofb"; }
+ elsif ($tmpline =~ /CFB/) { $mode="cfb"; }
+ #we do not need mode as the cipher is already clear
+ elsif ($tmpline =~ /SHA-1/) { $cipher="sha1"; }
+ elsif ($tmpline =~ /SHA-224/) { $cipher="sha224"; }
+ elsif ($tmpline =~ /SHA-256/) { $cipher="sha256"; }
+ elsif ($tmpline =~ /SHA-384/) { $cipher="sha384"; }
+ elsif ($tmpline =~ /SHA-512/) { $cipher="sha512"; }
+ #we do not need mode as the cipher is already clear
+ elsif ($tmpline =~ /RC4VS/) { $cipher="rc4"; }
+ elsif ($tmpline =~ /SigGen|SigVer/) {
+ die "Error: X9.31 is not supported"
+ if ($tmpline =~ /X9/);
+ $cipher="sha1"; #place holder - might be overwritten later
+ }
+
+ if ($tmpline =~ /^#.*AESVS/) {
+ # AES cipher (part of it)
+ $cipher="aes";
+ }
+ if ($tmpline =~ /^#.*(TDES|KAT)/) {
+ # TDES cipher (full definition)
+ # the FIPS-140 test generator tool does not produce
+ # machine readable output!
+ if ($mode eq "cbc") { $cipher="des-ede3-cbc"; }
+ if ($mode eq "ecb") { $cipher="des-ede3"; }
+ if ($mode eq "ofb") { $cipher="des-ede3-ofb"; }
+ if ($mode eq "cfb") { $cipher="des-ede3-cfb"; }
+ }
+
+ # check for RNG
+ if ($tmpline =~ /ANSI X9\.31/) {
+ # change the tmpline to add the type of the
+ # test which is ONLY visible from the file
+ # name :-(
+ if ($infile =~ /MCT\.req/) {
+ $tmpline .= " MCT";
+ } elsif ($infile =~ /VST\.req/) {
+ $tmpline .= " VST";
+ } else {
+ die "Unexpected cipher type with $infile";
+ }
+ }
+
+ if ($tt == 0) {
+ ##### Identify the test type
+ if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) {
+ $tt = 13;
+ die "Interface function rsa_derive for RSA key generation not defined for tested library"
+ if (!defined($rsa_derive));
+ } elsif ($tmpline =~ /SigVer/ && $opt{'D'} ) {
+ $tt = 12;
+ die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library"
+ if (!defined($dsa_verify) || !defined($dsa_genpubkey));
+ } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) {
+ $tt = 11;
+ die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library"
+ if (!defined($dsa_sign) || !defined($gen_rsakey));
+ } elsif ($tmpline =~ /PQGGen/) {
+ $tt = 10;
+ die "Interface function for DSA PQGGen testing not defined for tested library"
+ if (!defined($dsa_pqggen));
+ } elsif ($tmpline =~ /Hash sizes tested/) {
+ $tt = 9;
+ die "Interface function hmac for HMAC testing not defined for tested library"
+ if (!defined($hmac));
+ } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) {
+ $tt = 8;
+ die "Interface function state_rng for RNG MCT not defined for tested library"
+ if (!defined($state_rng));
+ } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /VST/) {
+ $tt = 7;
+ die "Interface function state_rng for RNG KAT not defined for tested library"
+ if (!defined($state_rng));
+ } elsif ($tmpline =~ /SigVer/ ) {
+ $tt = 6;
+ die "Interface function rsa_verify or gen_rsakey for RSA verification not defined for tested library"
+ if (!defined($rsa_verify) || !defined($gen_rsakey));
+ } elsif ($tmpline =~ /SigGen/ ) {
+ $tt = 5;
+ die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library"
+ if (!defined($rsa_sign) || !defined($gen_rsakey));
+ } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher =~ /^sha/) {
+ $tt = 4;
+ die "Interface function hash for Hashing not defined for tested library"
+ if (!defined($hash));
+ } elsif ($tmpline =~ /Monte|MCT|Carlo/) {
+ $tt = 2;
+ die "Interface function state_cipher for Stateful Cipher operation defined for tested library"
+ if (!defined($state_cipher) || !defined($state_cipher_des));
+ } elsif ($cipher =~ /^sha/) {
+ $tt = 3;
+ die "Interface function hash for Hashing not defined for tested library"
+ if (!defined($hash));
+ } else {
+ $tt = 1;
+ die "Interface function encdec for Encryption/Decryption not defined for tested library"
+ if (!defined($encdec));
+ }
+ }
+ }
+
+ # This is needed as ARCFOUR does not operate with an IV
+ $iv = "00000000000000000000000000000000" if ($cipher eq "rc4"
+ && $iv eq "" );
+
+ # we are now looking for the string
+ # '# Key Length : 256'
+ # found in AES
+ if ($tmpline =~ /^# Key Length.*?(128|192|256)/) {
+ if ($cipher eq "aes") {
+ $cipher="$cipher-$1-$mode";
+ } else {
+ die "Error: Key length $1 given for cipher $cipher which is unexpected";
+ }
+ }
+
+ # Get the test data
+ if ($line =~ /^(KEY|KEY1|Key)\s*=\s*(.*)/) { # found in ciphers and RNG
+ die "KEY seen twice - input file crap" if ($key1 ne "");
+ $keytype=$1;
+ $key1=$2;
+ $key1 =~ s/\s//g; #replace potential white spaces
+ }
+ elsif ($line =~ /^(KEYs)\s*=\s*(.*)/) { # found in ciphers and RNG
+ die "KEY seen twice - input file crap" if ($key1 ne "");
+ $keytype=$1;
+ $key1=$2;
+ $key1 =~ s/\s//g; #replace potential white spaces
+ $key2 = $key1;
+ $key3 = $key1;
+ }
+ elsif ($line =~ /^KEY2\s*=\s*(.*)/) { # found in TDES
+ die "First key not set, but got already second key - input file crap" if ($key1 eq "");
+ die "KEY2 seen twice - input file crap" if (defined($key2));
+ $key2=$1;
+ $key2 =~ s/\s//g; #replace potential white spaces
+ }
+ elsif ($line =~ /^KEY3\s*=\s*(.*)/) { # found in TDES
+ die "Second key not set, but got already third key - input file crap" if ($key2 eq "");
+ die "KEY3 seen twice - input file crap" if (defined($key3));
+ $key3=$1;
+ $key3 =~ s/\s//g; #replace potential white spaces
+ }
+ elsif ($line =~ /^IV\s*=\s*(.*)/) { # found in ciphers
+ die "IV seen twice - input file crap" if ($iv ne "");
+ $iv=$1;
+ $iv =~ s/\s//g; #replace potential white spaces
+ }
+ elsif ($line =~ /^PLAINTEXT\s*=\s*(.*)/) { # found in ciphers
+ if ( $1 !~ /\?/ ) { #only use it if there is valid hex data
+ die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne "");
+ $pt=$1;
+ $pt =~ s/\s//g; #replace potential white spaces
+ $enc=1;
+ }
+ }
+ elsif ($line =~ /^CIPHERTEXT\s*=\s*(.*)/) { # found in ciphers
+ if ( $1 !~ /\?/ ) { #only use it if there is valid hex data
+ die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne "");
+ $pt=$1;
+ $pt =~ s/\s//g; #replace potential white spaces
+ $enc=0;
+ }
+ }
+ elsif ($line =~ /^Len\s*=\s*(.*)/) { # found in hashs
+ $len=$1;
+ }
+ elsif ($line =~ /^(Msg|Seed)\s*=\s*(.*)/) { # found in hashs
+ die "Msg/Seed seen twice - input file crap" if ($pt ne "");
+ $pt=$2;
+ }
+ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests
+ $modulus = $1;
+ $out .= $line . "\n\n"; # print it
+ # generate the private key with given bit length now
+ # as we have the required key length in bit
+ if ($tt == 11) {
+ $dsa_keyfile = "dsa_siggen.tmp.$$";
+ my %pqg = &$gen_dsakey($dsa_keyfile);
+ $out .= "P = " . $pqg{'P'} . "\n";
+ $out .= "Q = " . $pqg{'Q'} . "\n";
+ $out .= "G = " . $pqg{'G'} . "\n";
+ } elsif ( $tt == 5 ) {
+ # XXX maybe a secure temp file name is better here
+ # but since it is not run on a security sensitive
+ # system, I hope that this is fine
+ $rsa_keyfile = "rsa_siggen.tmp.$$";
+ &$gen_rsakey($modulus, $rsa_keyfile);
+ my $modulus = pipe_through_program("", "openssl rsa -pubout -modulus -in $rsa_keyfile");
+ $modulus =~ s/Modulus=(.*?)\s(.|\s)*/$1/;
+ $out .= "n = $modulus\n";
+ $out .= "\ne = 10001\n"
+ }
+ }
+ elsif ($line =~ /^SHAAlg\s*=\s*(.*)/) { #found in RSA requests
+ $cipher=$1;
+ }
+ elsif($line =~ /^n\s*=\s*(.*)/) { # found in RSA requests
+ $out .= $line . "\n";
+ $n=$1;
+ }
+ elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests
+ $e=$1;
+ }
+ elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests
+ die "S seen twice - input file crap" if ($signature ne "");
+ $signature=$1;
+ }
+ elsif ($line =~ /^DT\s*=\s*(.*)/) { # X9.31 RNG requests
+ die "DT seen twice - check input file"
+ if ($dt ne "");
+ $dt=$1;
+ }
+ elsif ($line =~ /^V\s*=\s*(.*)/) { # X9.31 RNG requests
+ die "V seen twice - check input file"
+ if ($v ne "");
+ $v=$1;
+ }
+ elsif ($line =~ /^Klen\s*=\s*(.*)/) { # HMAC requests
+ die "Klen seen twice - check input file"
+ if ($klen ne "");
+ $klen=$1;
+ }
+ elsif ($line =~ /^Tlen\s*=\s*(.*)/) { # HMAC RNG requests
+ die "Tlen seen twice - check input file"
+ if ($tlen ne "");
+ $tlen=$1;
+ }
+ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen
+ die "N seen twice - check input file"
+ if ($capital_n);
+ $capital_n = $1;
+ }
+ elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer
+ die "P seen twice - check input file"
+ if ($capital_p);
+ $capital_p = $1;
+ $out .= $line . "\n"; # print it
+ }
+ elsif ($line =~ /^Q\s*=\s*(.*)/) { #DSA SigVer
+ die "Q seen twice - check input file"
+ if ($capital_q);
+ $capital_q = $1;
+ $out .= $line . "\n"; # print it
+ }
+ elsif ($line =~ /^G\s*=\s*(.*)/) { #DSA SigVer
+ die "G seen twice - check input file"
+ if ($capital_g);
+ $capital_g = $1;
+ $out .= $line . "\n"; # print it
+ }
+ elsif ($line =~ /^Y\s*=\s*(.*)/) { #DSA SigVer
+ die "Y seen twice - check input file"
+ if ($capital_y);
+ $capital_y = $1;
+ }
+ elsif ($line =~ /^R\s*=\s*(.*)/) { #DSA SigVer
+ die "R seen twice - check input file"
+ if ($capital_r);
+ $capital_r = $1;
+ }
+ elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen
+ die "xp1 seen twice - check input file"
+ if ($xp1);
+ $xp1 = $1;
+ }
+ elsif ($line =~ /^xp2\s*=\s*(.*)/) { #RSA key gen
+ die "xp2 seen twice - check input file"
+ if ($xp2);
+ $xp2 = $1;
+ }
+ elsif ($line =~ /^Xp\s*=\s*(.*)/) { #RSA key gen
+ die "Xp seen twice - check input file"
+ if ($Xp);
+ $Xp = $1;
+ }
+ elsif ($line =~ /^xq1\s*=\s*(.*)/) { #RSA key gen
+ die "xq1 seen twice - check input file"
+ if ($xq1);
+ $xq1 = $1;
+ }
+ elsif ($line =~ /^xq2\s*=\s*(.*)/) { #RSA key gen
+ die "xq2 seen twice - check input file"
+ if ($xq2);
+ $xq2 = $1;
+ }
+ elsif ($line =~ /^Xq\s*=\s*(.*)/) { #RSA key gen
+ die "Xq seen twice - check input file"
+ if ($Xq);
+ $Xq = $1;
+ }
+ else {
+ $out .= $line . "\n";
+ }
+
+ # call tests if all input data is there
+ if ($tt == 1) {
+ if ($key1 ne "" && $pt ne "" && $cipher ne "") {
+ $out .= kat($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
+ $keytype = "";
+ $key1 = "";
+ $key2 = undef;
+ $key3 = undef;
+ $iv = "";
+ $pt = "";
+ }
+ }
+ elsif ($tt == 2) {
+ if ($key1 ne "" && $pt ne "" && $cipher ne "") {
+ $out .= crypto_mct($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
+ $keytype = "";
+ $key1 = "";
+ $key2 = undef;
+ $key3 = undef;
+ $iv = "";
+ $pt = "";
+ }
+ }
+ elsif ($tt == 3) {
+ if ($pt ne "" && $cipher ne "") {
+ $out .= hash_kat($pt, $cipher, $len);
+ $pt = "";
+ $len = undef;
+ }
+ }
+ elsif ($tt == 4) {
+ if ($pt ne "" && $cipher ne "") {
+ $out .= hash_mct($pt, $cipher);
+ $pt = "";
+ }
+ }
+ elsif ($tt == 5) {
+ if ($pt ne "" && $cipher ne "" && $rsa_keyfile ne "") {
+ $out .= rsa_siggen($pt, $cipher, $rsa_keyfile);
+ $pt = "";
+ }
+ }
+ elsif ($tt == 6) {
+ if ($pt ne "" && $cipher ne "" && $signature ne "" && $n ne "" && $e ne "") {
+ $out .= rsa_sigver($pt, $cipher, $signature, $n, $e);
+ $pt = "";
+ $signature = "";
+ }
+ }
+ elsif ($tt == 7 ) {
+ if ($key1 ne "" && $dt ne "" && $v ne "") {
+ $out .= rngx931($key1, $dt, $v, "VST");
+ $key1 = "";
+ $dt = "";
+ $v = "";
+ }
+ }
+ elsif ($tt == 8 ) {
+ if ($key1 ne "" && $dt ne "" && $v ne "") {
+ $out .= rngx931($key1, $dt, $v, "MCT");
+ $key1 = "";
+ $dt = "";
+ $v = "";
+ }
+ }
+ elsif ($tt == 9) {
+ if ($klen ne "" && $tlen ne "" && $key1 ne "" && $pt ne "") {
+ $out .= hmac_kat($klen, $tlen, $key1, $pt);
+ $key1 = "";
+ $tlen = "";
+ $klen = "";
+ $pt = "";
+ }
+ }
+ elsif ($tt == 10) {
+ if ($modulus ne "" && $capital_n > 0) {
+ $out .= dsa_pqggen_driver($modulus, $capital_n);
+ #$mod is not resetted
+ $capital_n = 0;
+ }
+ }
+ elsif ($tt == 11) {
+ if ($pt ne "" && $dsa_keyfile ne "") {
+ $out .= dsa_siggen($pt, $dsa_keyfile);
+ $pt = "";
+ }
+ }
+ elsif ($tt == 12) {
+ if ($modulus ne "" &&
+ $capital_p ne "" &&
+ $capital_q ne "" &&
+ $capital_g ne "" &&
+ $capital_y ne "" &&
+ $capital_r ne "" &&
+ $signature ne "" &&
+ $pt ne "") {
+ $out .= dsa_sigver($modulus,
+ $capital_p,
+ $capital_q,
+ $capital_g,
+ $capital_y,
+ $capital_r,
+ $signature,
+ $pt);
+
+ # We do not clear the domain values PQG and
+ # the modulus value as they
+ # are specified only once in a file
+ # and we do not need to print them as they
+ # are already printed above
+ $capital_y = "";
+ $capital_r = "";
+ $signature = "";
+ $pt = "";
+ }
+ }
+ elsif ($tt == 13) {
+ if($modulus ne "" &&
+ $e ne "" &&
+ $xp1 ne "" &&
+ $xp2 ne "" &&
+ $Xp ne "" &&
+ $xq1 ne "" &&
+ $xq2 ne "" &&
+ $Xq ne "") {
+ $out .= rsa_keygen($modulus,
+ $e,
+ $xp1,
+ $xp2,
+ $Xp,
+ $xq1,
+ $xq2,
+ $Xq);
+ $e = "";
+ $xp1 = "";
+ $xp2 = "";
+ $Xp = "";
+ $xq1 = "";
+ $xq2 = "";
+ $Xq = "";
+ }
+ }
+ elsif ($tt > 0) {
+ die "Test case $tt not defined";
+ }
+ }
+
+ close IN;
+ $out =~ s/\n/\r\n/g; # make it a dos file
+ open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?";
+ print OUT $out;
+ close OUT;
+
+}
+
+# Signalhandler
+sub cleanup() {
+ unlink("rsa_siggen.tmp.$$");
+ unlink("rsa_sigver.tmp.$$");
+ unlink("rsa_sigver.tmp.$$.sig");
+ unlink("rsa_sigver.tmp.$$.der");
+ unlink("rsa_sigver.tmp.$$.cnf");
+ unlink("dsa_siggen.tmp.$$");
+ unlink("dsa_sigver.tmp.$$");
+ unlink("dsa_sigver.tmp.$$.sig");
+ exit;
+}
+
+############################################################
+#
+# let us pretend to be C :-)
+sub main() {
+
+ usage() unless @ARGV;
+
+ getopts("DRI:", \%opt) or die "bad option";
+
+ ##### Set library
+
+ if ( ! defined $opt{'I'} || $opt{'I'} eq 'openssl' ) {
+ print STDERR "Using OpenSSL interface functions\n";
+ $encdec = \&openssl_encdec;
+ $rsa_sign = \&openssl_rsa_sign;
+ $rsa_verify = \&openssl_rsa_verify;
+ $gen_rsakey = \&openssl_gen_rsakey;
+ $hash = \&openssl_hash;
+ $state_cipher = \&openssl_state_cipher;
+ } elsif ( $opt{'I'} eq 'libgcrypt' ) {
+ print STDERR "Using libgcrypt interface functions\n";
+ $encdec = \&libgcrypt_encdec;
+ $rsa_sign = \&libgcrypt_rsa_sign;
+ $rsa_verify = \&libgcrypt_rsa_verify;
+ $gen_rsakey = \&libgcrypt_gen_rsakey;
+ $rsa_derive = \&libgcrypt_rsa_derive;
+ $hash = \&libgcrypt_hash;
+ $state_cipher = \&libgcrypt_state_cipher;
+ $state_cipher_des = \&libgcrypt_state_cipher_des;
+ $state_rng = \&libgcrypt_state_rng;
+ $hmac = \&libgcrypt_hmac;
+ $dsa_pqggen = \&libgcrypt_dsa_pqggen;
+ $gen_dsakey = \&libgcrypt_gen_dsakey;
+ $dsa_sign = \&libgcrypt_dsa_sign;
+ $dsa_verify = \&libgcrypt_dsa_verify;
+ $dsa_genpubkey = \&libgcrypt_dsa_genpubkey;
+ } else {
+ die "Invalid interface option given";
+ }
+
+ my $infile=$ARGV[0];
+ die "Error: Test vector file $infile not found" if (! -f $infile);
+
+ my $outfile = $infile;
+ # let us add .rsp regardless whether we could strip .req
+ $outfile =~ s/\.req$//;
+ if ($opt{'R'}) {
+ $outfile .= ".rc4";
+ } else {
+ $outfile .= ".rsp";
+ }
+ if (-f $outfile) {
+ die "Output file $outfile could not be removed: $?"
+ unless unlink($outfile);
+ }
+ print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n";
+
+ #Signal handler
+ $SIG{HUP} = \&cleanup;
+ $SIG{INT} = \&cleanup;
+ $SIG{QUIT} = \&cleanup;
+ $SIG{TERM} = \&cleanup;
+
+ # Do the job
+ parse($infile, $outfile);
+
+ cleanup();
+
+}
+
+###########################################
+# Call it
+main();
+1;
diff --git a/comm/third_party/libgcrypt/tests/cavs_tests.sh b/comm/third_party/libgcrypt/tests/cavs_tests.sh
new file mode 100755
index 0000000000..7d8499bda4
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/cavs_tests.sh
@@ -0,0 +1,135 @@
+#!/bin/sh
+# Run FIPS CAVS tests
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Instructions:
+#
+# 1. Cd to the libgcrypt/tests directory
+#
+# 2. Unpack the test vector tarball into subdirectory named "cavs".
+# An example directory layout after unpacking might be:
+# libgcrypt/tests/cavs/AES/req/CBCGFSbox128.req
+# libgcrypt/tests/cavs/AES/req/CFB128MCT128.req
+#
+# Note that below the "cavs" directory there should only be one
+# directory part named "req". Further avoid directory part
+# names "resp".
+#
+# 3. Run this script from the libgcrypt/tests directory:
+# ./cavs_tests.sh
+#
+# 4. Send the result file cavs/CAVS_results-*.zip to the testing lab.
+#
+
+# Stop script if something unexpected happens.
+set -e
+
+# A global flag to keep track of errors.
+errors_seen_file="$(pwd)/.#cavs_test.errors_seen.tmp"
+[ -f "$errors_seen_file" ] && rm "$errors_seen_file"
+continue_mode=no
+[ "$1" = "--continue" ] && continue_mode=yes
+
+
+# Function to run one test.
+# The argument is the request file name.
+function run_one_test () {
+ local reqfile="$1"
+ local rspfile
+ local tmprspfile
+ local respdir
+ local dflag=""
+
+ tmprspfile=$(echo "$reqfile" | sed 's,.req$,.rsp,')
+ rspfile=$(echo "$tmprspfile" | sed 's,/req/,/resp/,' )
+ respdir=$(dirname "$rspfile")
+ [ -f "$tmprspfile" ] && rm "$tmprspfile"
+ [ -d "$respdir" ] || mkdir "$respdir"
+ [ -f "$rspfile" ] && rm "$rspfile"
+
+ if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then
+ dflag="-D"
+ fi
+
+ if ./cavs_driver.pl -I libgcrypt $dflag "$reqfile"; then
+ if [ -f "$tmprspfile" ]; then
+ mv "$tmprspfile" "$rspfile"
+ else
+ echo "failed test: $reqfile" >&2
+ : >"$errors_seen_file"
+ fi
+ else
+ echo "failed test: $reqfile rc=$?" >&2
+ : >"$errors_seen_file"
+ fi
+}
+
+
+
+# Save date and system architecure to construct the output archive name
+DATE=$(date +%Y%m%d)
+ARCH=$(arch || echo unknown)
+result_file="CAVS_results-$ARCH-$DATE.zip"
+
+for f in fipsdrv cavs_driver.pl; do
+ if [ ! -f "./$f" ]; then
+ echo "required program \"$f\" missing in current directory" >&2
+ exit 2
+ fi
+done
+if [ ! -d cavs ]; then
+ echo "required directory \"cavs\" missing below current directory" >&2
+ exit 2
+fi
+if [ ! zip -h >/dev/null 2>&1 ]; then
+ echo "required program \"zip\" is not installed on this system" >&2
+ exit 2
+fi
+
+# Set the PATH to this directory so that the perl script is able to
+# find the test drivers.
+PATH=.:$PATH
+
+# Check whether there are any stale response files
+find cavs -type f -name "*.rsp" | ( while read f ; do
+ echo "Stale response file: $f" >&2
+ any=yes
+done
+if [ "$any" = "yes" ]; then
+ echo "Stale response files found" >&2
+ if [ "$continue_mode" != "yes" ]; then
+ echo "use option --continue if that is not a problem" >&2
+ exit 1
+ fi
+fi
+) || exit 1
+
+
+# Find all test files and run the tests.
+find cavs -type f -name "*.req" | while read f ; do
+ echo "Running test file $f" >&2
+ run_one_test "$f"
+ if [ -f "$errors_seen_file" ]; then
+ break;
+ fi
+done
+
+if [ -f "$errors_seen_file" ]; then
+ rm "$errors_seen_file"
+ echo "Error encountered - not packing up response file" >&2
+ exit 1
+fi
+
+echo "Packing up all response files" >&2
+cd cavs
+find . -type f -name "*rsp" -print | zip -@ "$result_file"
+
+echo "Result file is: cavs/$result_file" >&2
diff --git a/comm/third_party/libgcrypt/tests/curves.c b/comm/third_party/libgcrypt/tests/curves.c
new file mode 100644
index 0000000000..55ba7422ab
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/curves.c
@@ -0,0 +1,190 @@
+/* curves.c - ECC curves regression tests
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt-int.h"
+
+
+#define PGM "curves"
+#include "t-common.h"
+
+/* Number of curves defined in ../cipger/ecc-curves.c */
+#define N_CURVES 27
+
+/* A real world sample public key. */
+static char const sample_key_1[] =
+"(public-key\n"
+" (ecdsa\n"
+" (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)\n"
+" (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)\n"
+" (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)\n"
+" (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n"
+" (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n"
+" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n"
+" (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE"
+ "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n"
+" ))";
+static char const sample_key_1_curve[] = "NIST P-256";
+static unsigned int sample_key_1_nbits = 256;
+
+/* A made up sample public key. */
+static char const sample_key_2[] =
+"(public-key\n"
+" (ecdh\n"
+" (p #00e95e4a5f737059dc60dfc7ad95b3d8139515620f#)\n"
+" (a #340e7be2a280eb74e2be61bada745d97e8f7c300#)\n"
+" (b #1e589a8595423412134faa2dbdec95c8d8675e58#)\n"
+" (g #04bed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3"
+ "1667cb477a1a8ec338f94741669c976316da6321#)\n"
+" (n #00e95e4a5f737059dc60df5991d45029409e60fc09#)\n"
+" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n"
+" (q #041111111111111111111111111111111111111111"
+ "2222222222222222222222222222222222222222#)\n"
+" ))";
+static char const sample_key_2_curve[] = "brainpoolP160r1";
+static unsigned int sample_key_2_nbits = 160;
+
+
+static void
+list_curves (void)
+{
+ int idx;
+ const char *name;
+ unsigned int nbits;
+
+ for (idx=0; (name = gcry_pk_get_curve (NULL, idx, &nbits)); idx++)
+ {
+ if (verbose)
+ printf ("%s - %u bits\n", name, nbits);
+ }
+ if (idx != N_CURVES)
+ fail ("expected %d curves but got %d\n", N_CURVES, idx);
+ if (gcry_pk_get_curve (NULL, -1, NULL))
+ fail ("curve iteration failed\n");
+}
+
+
+static void
+check_matching (void)
+{
+ gpg_error_t err;
+ gcry_sexp_t key;
+ const char *name;
+ unsigned int nbits;
+
+ err = gcry_sexp_new (&key, sample_key_1, 0, 1);
+ if (err)
+ die ("parsing s-expression string failed: %s\n", gpg_strerror (err));
+ name = gcry_pk_get_curve (key, 0, &nbits);
+ if (!name)
+ fail ("curve name not found for sample_key_1\n");
+ else if (strcmp (name, sample_key_1_curve))
+ fail ("expected curve name %s but got %s for sample_key_1\n",
+ sample_key_1_curve, name);
+ else if (nbits != sample_key_1_nbits)
+ fail ("expected curve size %u but got %u for sample_key_1\n",
+ sample_key_1_nbits, nbits);
+
+ gcry_sexp_release (key);
+
+ err = gcry_sexp_new (&key, sample_key_2, 0, 1);
+ if (err)
+ die ("parsing s-expression string failed: %s\n", gpg_strerror (err));
+ name = gcry_pk_get_curve (key, 0, &nbits);
+ if (!name)
+ fail ("curve name not found for sample_key_2\n");
+ else if (strcmp (name, sample_key_2_curve))
+ fail ("expected curve name %s but got %s for sample_key_2\n",
+ sample_key_2_curve, name);
+ else if (nbits != sample_key_2_nbits)
+ fail ("expected curve size %u but got %u for sample_key_2\n",
+ sample_key_2_nbits, nbits);
+
+ gcry_sexp_release (key);
+}
+
+
+static void
+check_get_params (void)
+{
+ gcry_sexp_t param;
+ const char *name;
+
+ param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_1_curve);
+ if (!param)
+ fail ("error gerring parameters for `%s'\n", sample_key_1_curve);
+
+ name = gcry_pk_get_curve (param, 0, NULL);
+ if (!name)
+ fail ("get_param: curve name not found for sample_key_1\n");
+ else if (strcmp (name, sample_key_1_curve))
+ fail ("get_param: expected curve name %s but got %s for sample_key_1\n",
+ sample_key_1_curve, name);
+
+ gcry_sexp_release (param);
+
+ /* Brainpool curves are not supported in fips mode */
+ if (gcry_fips_mode_active())
+ return;
+
+ param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_2_curve);
+ if (!param)
+ fail ("error gerring parameters for `%s'\n", sample_key_2_curve);
+
+ name = gcry_pk_get_curve (param, 0, NULL);
+ if (!name)
+ fail ("get_param: curve name not found for sample_key_2\n");
+ else if (strcmp (name, sample_key_2_curve))
+ fail ("get_param: expected curve name %s but got %s for sample_key_2\n",
+ sample_key_2_curve, name);
+
+ gcry_sexp_release (param);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ list_curves ();
+ check_matching ();
+ check_get_params ();
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/dsa-rfc6979.c b/comm/third_party/libgcrypt/tests/dsa-rfc6979.c
new file mode 100644
index 0000000000..7d3d208032
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/dsa-rfc6979.c
@@ -0,0 +1,983 @@
+/* dsa-rfc6979.c - Test for Deterministic DSA
+ * Copyright (C) 2008 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+# include <gcrypt.h>
+#endif
+
+#define PGM "dsa-rfc6979"
+#include "t-common.h"
+
+
+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);
+}
+
+
+/* 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 returns NULL on
+ error. */
+static void *
+data_from_hex (const char *string, size_t *r_length)
+{
+ const char *s;
+ unsigned char *buffer;
+ size_t length;
+
+ buffer = gcry_xmalloc (strlen(string)/2+1);
+ length = 0;
+ for (s=string; *s; s +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ die ("error parsing hex string `%s'\n", string);
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static void
+extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
+{
+ gcry_sexp_t l1;
+ const void *a;
+ size_t alen;
+ void *b;
+ size_t blen;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_data (l1, 1, &alen);
+ b = data_from_hex (expected, &blen);
+ if (!a)
+ fail ("parameter \"%s\" missing in key\n", name);
+ else if ( alen != blen || memcmp (a, b, alen) )
+ {
+ fail ("parameter \"%s\" does not match expected value\n", name);
+ if (verbose)
+ {
+ info ("expected: %s\n", expected);
+ show_sexp ("sexp: ", sexp);
+ }
+ }
+ gcry_free (b);
+ gcry_sexp_release (l1);
+}
+
+
+/* These test vectors are from RFC 6979. */
+static void
+check_dsa_rfc6979 (void)
+{
+ static struct {
+ const char *name;
+ const char *key;
+ } keys[] = {
+ {
+ "DSA, 1024 bits",
+ "(private-key"
+ " (DSA"
+ " (p #86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447"
+ " E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED88"
+ " 73ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C"
+ " 881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779#)"
+ " (q #996F967F6C8E388D9E28D01E205FBA957A5698B1#)"
+ " (g #07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D"
+ " 89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD"
+ " 87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA4"
+ " 17BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD#)"
+ " (x #411602CB19A6CCC34494D79D98EF1E7ED5AF25F7#)"
+ " (y #5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F653"
+ " 92195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D"
+ " 4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E6"
+ " 82F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B#)"
+ " ))"
+ },
+ {
+ "DSA, 2048 bits",
+ "(private-key"
+ " (DSA"
+ " (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48"
+ " C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F"
+ " FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5"
+ " B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2"
+ " 35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41"
+ " F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE"
+ " 92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15"
+ " 3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
+ " (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
+ " (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613"
+ " D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4"
+ " 6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472"
+ " 085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5"
+ " AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA"
+ " 3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71"
+ " BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0"
+ " DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
+ " (x #69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC#)"
+ " (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD94"
+ " 9F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA61"
+ " 1728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADE"
+ " CB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB"
+ " 5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254"
+ " 687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D1"
+ " 23AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA"
+ " 74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)"
+ " ))"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "(private-key"
+ " (ecdsa"
+ " (curve \"NIST P-192\")"
+ " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56"
+ " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)"
+ " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)"
+ " ))"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "(private-key"
+ " (ecdsa"
+ " (curve \"NIST P-224\")"
+ " (q #04"
+ " 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C"
+ " EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)"
+ " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)"
+ " ))"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "(private-key"
+ " (ecdsa"
+ " (curve \"NIST P-256\")"
+ " (q #04"
+ " 60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
+ " 7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)"
+ " (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)"
+ " ))"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "(private-key"
+ " (ecdsa"
+ " (curve \"NIST P-384\")"
+ " (q #04"
+ " EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64"
+ " DEF8F0EA9055866064A254515480BC13"
+ " 8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1"
+ " 288B231C3AE0D4FE7344FD2533264720#)"
+ " (d #6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8"
+ " 96D5724E4C70A825F872C9EA60D2EDF5#)"
+ " ))"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "(private-key"
+ " (ecdsa"
+ " (curve \"NIST P-521\")"
+ " (q #04"
+ " 01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD"
+ " 371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F50"
+ " 23A4"
+ " 00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A"
+ " 28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFD"
+ " FCF5#)"
+ " (d #FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75"
+ " CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B8"
+ " 3538#)"
+ " ))"
+ },
+ { NULL }
+ };
+
+ static struct {
+ const char *keyname;
+ const char *name;
+ const char *hashname;
+ const char *message;
+ const char *k, *r, *s;
+ } tests[] = {
+ {
+ "DSA, 1024 bits",
+ "With SHA-1, message = \"sample\"",
+ "sha1", "sample",
+ "7BDB6B0FF756E1BB5D53583EF979082F9AD5BD5B",
+ "2E1A0C2562B2912CAAF89186FB0F42001585DA55",
+ "29EFB6B0AFF2D7A68EB70CA313022253B9A88DF5"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-224, message = \"sample\"",
+ "sha224", "sample",
+ "562097C06782D60C3037BA7BE104774344687649",
+ "4BC3B686AEA70145856814A6F1BB53346F02101E",
+ "410697B92295D994D21EDD2F4ADA85566F6F94C1"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-256, message = \"sample\"",
+ "sha256", "sample",
+ "519BA0546D0C39202A7D34D7DFA5E760B318BCFB",
+ "81F2F5850BE5BC123C43F71A3033E9384611C545",
+ "4CDD914B65EB6C66A8AAAD27299BEE6B035F5E89"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-384, message = \"sample\"",
+ "sha384", "sample",
+ "95897CD7BBB944AA932DBC579C1C09EB6FCFC595",
+ "07F2108557EE0E3921BC1774F1CA9B410B4CE65A",
+ "54DF70456C86FAC10FAB47C1949AB83F2C6F7595"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-512, message = \"sample\"",
+ "sha512", "sample",
+ "09ECE7CA27D0F5A4DD4E556C9DF1D21D28104F8B",
+ "16C3491F9B8C3FBBDD5E7A7B667057F0D8EE8E1B",
+ "02C36A127A7B89EDBB72E4FFBC71DABC7D4FC69C"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-1, message = \"test\"",
+ "sha1", "test",
+ "5C842DF4F9E344EE09F056838B42C7A17F4A6433",
+ "42AB2052FD43E123F0607F115052A67DCD9C5C77",
+ "183916B0230D45B9931491D4C6B0BD2FB4AAF088"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-224, message = \"test\"",
+ "sha224", "test",
+ "4598B8EFC1A53BC8AECD58D1ABBB0C0C71E67297",
+ "6868E9964E36C1689F6037F91F28D5F2C30610F2",
+ "49CEC3ACDC83018C5BD2674ECAAD35B8CD22940F"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-256, message = \"test\"",
+ "sha256", "test",
+ "5A67592E8128E03A417B0484410FB72C0B630E1A",
+ "22518C127299B0F6FDC9872B282B9E70D0790812",
+ "6837EC18F150D55DE95B5E29BE7AF5D01E4FE160"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-384, message = \"test\"",
+ "sha384", "test",
+ "220156B761F6CA5E6C9F1B9CF9C24BE25F98CD89",
+ "854CF929B58D73C3CBFDC421E8D5430CD6DB5E66",
+ "91D0E0F53E22F898D158380676A871A157CDA622"
+ },
+ {
+ "DSA, 1024 bits",
+ "With SHA-512, message = \"test\"",
+ "sha512", "test",
+ "65D2C2EEB175E370F28C75BFCDC028D22C7DBE9C",
+ "8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A0",
+ "7C670C7AD72B6C050C109E1790008097125433E8"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-1, message = \"sample\"",
+ "sha1", "sample",
+ "888FA6F7738A41BDC9846466ABDB8174C0338250AE50CE955CA16230F9CBD53E",
+ "3A1B2DBD7489D6ED7E608FD036C83AF396E290DBD602408E8677DAABD6E7445A",
+ "D26FCBA19FA3E3058FFC02CA1596CDBB6E0D20CB37B06054F7E36DED0CDBBCCF"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-224, message = \"sample\"",
+ "sha224", "sample",
+ "BC372967702082E1AA4FCE892209F71AE4AD25A6DFD869334E6F153BD0C4D806",
+ "DC9F4DEADA8D8FF588E98FED0AB690FFCE858DC8C79376450EB6B76C24537E2C",
+ "A65A9C3BC7BABE286B195D5DA68616DA8D47FA0097F36DD19F517327DC848CEC"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-256, message = \"sample\"",
+ "sha256", "sample",
+ "8926A27C40484216F052F4427CFD5647338B7B3939BC6573AF4333569D597C52",
+ "EACE8BDBBE353C432A795D9EC556C6D021F7A03F42C36E9BC87E4AC7932CC809",
+ "7081E175455F9247B812B74583E9E94F9EA79BD640DC962533B0680793A38D53"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-384, message = \"sample\"",
+ "sha384", "sample",
+ "C345D5AB3DA0A5BCB7EC8F8FB7A7E96069E03B206371EF7D83E39068EC564920",
+ "B2DA945E91858834FD9BF616EBAC151EDBC4B45D27D0DD4A7F6A22739F45C00B",
+ "19048B63D9FD6BCA1D9BAE3664E1BCB97F7276C306130969F63F38FA8319021B"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-512, message = \"sample\"",
+ "sha512", "sample",
+ "5A12994431785485B3F5F067221517791B85A597B7A9436995C89ED0374668FC",
+ "2016ED092DC5FB669B8EFB3D1F31A91EECB199879BE0CF78F02BA062CB4C942E",
+ "D0C76F84B5F091E141572A639A4FB8C230807EEA7D55C8A154A224400AFF2351"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-1, message = \"test\"",
+ "sha1", "test",
+ "6EEA486F9D41A037B2C640BC5645694FF8FF4B98D066A25F76BE641CCB24BA4F",
+ "C18270A93CFC6063F57A4DFA86024F700D980E4CF4E2CB65A504397273D98EA0",
+ "414F22E5F31A8B6D33295C7539C1C1BA3A6160D7D68D50AC0D3A5BEAC2884FAA"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-224, message = \"test\"",
+ "sha224", "test",
+ "06BD4C05ED74719106223BE33F2D95DA6B3B541DAD7BFBD7AC508213B6DA6670",
+ "272ABA31572F6CC55E30BF616B7A265312018DD325BE031BE0CC82AA17870EA3",
+ "E9CC286A52CCE201586722D36D1E917EB96A4EBDB47932F9576AC645B3A60806"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-256, message = \"test\"",
+ "sha256", "test",
+ "1D6CE6DDA1C5D37307839CD03AB0A5CBB18E60D800937D67DFB4479AAC8DEAD7",
+ "8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0",
+ "7452A53F7075D417B4B013B278D1BB8BBD21863F5E7B1CEE679CF2188E1AB19E"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-384, message = \"test\"",
+ "sha384", "test",
+ "206E61F73DBE1B2DC8BE736B22B079E9DACD974DB00EEBBC5B64CAD39CF9F91C",
+ "239E66DDBE8F8C230A3D071D601B6FFBDFB5901F94D444C6AF56F732BEB954BE",
+ "6BD737513D5E72FE85D1C750E0F73921FE299B945AAD1C802F15C26A43D34961"
+ },
+ {
+ "DSA, 2048 bits",
+ "With SHA-512, message = \"test\"",
+ "sha512", "test",
+ "AFF1651E4CD6036D57AA8B2A05CCF1A9D5A40166340ECBBDC55BE10B568AA0AA",
+ "89EC4BB1400ECCFF8E7D9AA515CD1DE7803F2DAFF09693EE7FD1353E90A68307",
+ "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-1, message = \"sample\"",
+ "sha1", "sample",
+ "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021",
+ "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF",
+ "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-224, message = \"sample\"",
+ "sha224", "sample",
+ "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8",
+ "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5",
+ "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-256, message = \"sample\"",
+ "sha256", "sample",
+ "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496",
+ "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55",
+ "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-384, message = \"sample\"",
+ "sha384", "sample",
+ "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311",
+ "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5",
+ "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-512, message = \"sample\"",
+ "sha512", "sample",
+ "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1",
+ "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8",
+ "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-1, message = \"test\"",
+ "sha1", "test",
+ "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25",
+ "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D",
+ "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-224, message = \"test\"",
+ "sha224", "test",
+ "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE",
+ "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34",
+ "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-256, message = \"test\"",
+ "sha256", "test",
+ "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C",
+ "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE",
+ "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-384, message = \"test\"",
+ "sha384", "test",
+ "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693",
+ "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367",
+ "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A"
+ },
+ {
+ "ECDSA, 192 bits (prime field)",
+ "With SHA-512, message = \"test\"",
+ "sha512", "test",
+ "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527",
+ "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739",
+ "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290"
+ },
+
+
+
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-1, message = \"sample\"",
+ "sha1", "sample",
+ "7EEFADD91110D8DE6C2C470831387C50D3357F7F4D477054B8B426BC",
+ "22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC",
+ "66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-224, message = \"sample\"",
+ "sha224", "sample",
+ "C1D1F2F10881088301880506805FEB4825FE09ACB6816C36991AA06D",
+ "1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E",
+ "A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-256, message = \"sample\"",
+ "sha256", "sample",
+ "AD3029E0278F80643DE33917CE6908C70A8FF50A411F06E41DEDFCDC",
+ "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA",
+ "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-384, message = \"sample\"",
+ "sha384", "sample",
+ "52B40F5A9D3D13040F494E83D3906C6079F29981035C7BD51E5CAC40",
+ "0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953",
+ "830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-512, message = \"sample\"",
+ "sha512", "sample",
+ "9DB103FFEDEDF9CFDBA05184F925400C1653B8501BAB89CEA0FBEC14",
+ "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397",
+ "A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-1, message = \"test\"",
+ "sha1", "test",
+ "2519178F82C3F0E4F87ED5883A4E114E5B7A6E374043D8EFD329C253",
+ "DEAA646EC2AF2EA8AD53ED66B2E2DDAA49A12EFD8356561451F3E21C",
+ "95987796F6CF2062AB8135271DE56AE55366C045F6D9593F53787BD2"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-224, message = \"test\"",
+ "sha224", "test",
+ "DF8B38D40DCA3E077D0AC520BF56B6D565134D9B5F2EAE0D34900524",
+ "C441CE8E261DED634E4CF84910E4C5D1D22C5CF3B732BB204DBEF019",
+ "902F42847A63BDC5F6046ADA114953120F99442D76510150F372A3F4"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-256, message = \"test\"",
+ "sha256", "test",
+ "FF86F57924DA248D6E44E8154EB69F0AE2AEBAEE9931D0B5A969F904",
+ "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6",
+ "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-384, message = \"test\"",
+ "sha384", "test",
+ "7046742B839478C1B5BD31DB2E862AD868E1A45C863585B5F22BDC2D",
+ "389B92682E399B26518A95506B52C03BC9379A9DADF3391A21FB0EA4",
+ "414A718ED3249FF6DBC5B50C27F71F01F070944DA22AB1F78F559AAB"
+ },
+ {
+ "ECDSA, 224 bits (prime field)",
+ "With SHA-512, message = \"test\"",
+ "sha512", "test",
+ "E39C2AA4EA6BE2306C72126D40ED77BF9739BB4D6EF2BBB1DCB6169D",
+ "049F050477C5ADD858CAC56208394B5A55BAEBBE887FDF765047C17C",
+ "077EB13E7005929CEFA3CD0403C7CDCC077ADF4E44F3C41B2F60ECFF"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-1, message = \"sample\"",
+ "sha1", "sample",
+ "882905F1227FD620FBF2ABF21244F0BA83D0DC3A9103DBBEE43A1FB858109DB4",
+ "61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32",
+ "6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-224, message = \"sample\"",
+ "sha224", "sample",
+ "103F90EE9DC52E5E7FB5132B7033C63066D194321491862059967C715985D473",
+ "53B2FFF5D1752B2C689DF257C04C40A587FABABB3F6FC2702F1343AF7CA9AA3F",
+ "B9AFB64FDC03DC1A131C7D2386D11E349F070AA432A4ACC918BEA988BF75C74C"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-256, message = \"sample\"",
+ "sha256", "sample",
+ "A6E3C57DD01ABE90086538398355DD4C3B17AA873382B0F24D6129493D8AAD60",
+ "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716",
+ "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-384, message = \"sample\"",
+ "sha384", "sample",
+ "09F634B188CEFD98E7EC88B1AA9852D734D0BC272F7D2A47DECC6EBEB375AAD4",
+ "0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719",
+ "4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-512, message = \"sample\"",
+ "sha512", "sample",
+ "5FA81C63109BADB88C1F367B47DA606DA28CAD69AA22C4FE6AD7DF73A7173AA5",
+ "8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00",
+ "2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-1, message = \"test\"",
+ "sha1", "test",
+ "8C9520267C55D6B980DF741E56B4ADEE114D84FBFA2E62137954164028632A2E",
+ "0CBCC86FD6ABD1D99E703E1EC50069EE5C0B4BA4B9AC60E409E8EC5910D81A89",
+ "01B9D7B73DFAA60D5651EC4591A0136F87653E0FD780C3B1BC872FFDEAE479B1"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-224, message = \"test\"",
+ "sha224", "test",
+ "669F4426F2688B8BE0DB3A6BD1989BDAEFFF84B649EEB84F3DD26080F667FAA7",
+ "C37EDB6F0AE79D47C3C27E962FA269BB4F441770357E114EE511F662EC34A692",
+ "C820053A05791E521FCAAD6042D40AEA1D6B1A540138558F47D0719800E18F2D"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-256, message = \"test\"",
+ "sha256", "test",
+ "D16B6AE827F17175E040871A1C7EC3500192C4C92677336EC2537ACAEE0008E0",
+ "F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367",
+ "019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-384, message = \"test\"",
+ "sha384", "test",
+ "16AEFFA357260B04B1DD199693960740066C1A8F3E8EDD79070AA914D361B3B8",
+ "83910E8B48BB0C74244EBDF7F07A1C5413D61472BD941EF3920E623FBCCEBEB6",
+ "8DDBEC54CF8CD5874883841D712142A56A8D0F218F5003CB0296B6B509619F2C"
+ },
+ {
+ "ECDSA, 256 bits (prime field)",
+ "With SHA-512, message = \"test\"",
+ "sha512", "test",
+ "6915D11632ACA3C40D5D51C08DAF9C555933819548784480E93499000D9F0B7F",
+ "461D93F31B6540894788FD206C07CFA0CC35F46FA3C91816FFF1040AD1581A04",
+ "39AF9F15DE0DB8D97E72719C74820D304CE5226E32DEDAE67519E840D1194E55"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-1, message = \"sample\"",
+ "sha1", "sample",
+ "4471EF7518BB2C7C20F62EAE1C387AD0C5E8E470995DB4ACF694466E6AB09663"
+ "0F29E5938D25106C3C340045A2DB01A7",
+ "EC748D839243D6FBEF4FC5C4859A7DFFD7F3ABDDF72014540C16D73309834FA3"
+ "7B9BA002899F6FDA3A4A9386790D4EB2",
+ "A3BCFA947BEEF4732BF247AC17F71676CB31A847B9FF0CBC9C9ED4C1A5B3FACF"
+ "26F49CA031D4857570CCB5CA4424A443"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-224, message = \"sample\"",
+ "sha224", "sample",
+ "A4E4D2F0E729EB786B31FC20AD5D849E304450E0AE8E3E341134A5C1AFA03CAB"
+ "8083EE4E3C45B06A5899EA56C51B5879",
+ "42356E76B55A6D9B4631C865445DBE54E056D3B3431766D0509244793C3F9366"
+ "450F76EE3DE43F5A125333A6BE060122",
+ "9DA0C81787064021E78DF658F2FBB0B042BF304665DB721F077A4298B095E483"
+ "4C082C03D83028EFBF93A3C23940CA8D"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-256, message = \"sample\"",
+ "sha256", "sample",
+ "180AE9F9AEC5438A44BC159A1FCB277C7BE54FA20E7CF404B490650A8ACC414E"
+ "375572342863C899F9F2EDF9747A9B60",
+ "21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33"
+ "BDE1E888E63355D92FA2B3C36D8FB2CD",
+ "F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEB"
+ "EFDC63ECCD1AC42EC0CB8668A4FA0AB0"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-384, message = \"sample\"",
+ "sha384", "sample",
+ "94ED910D1A099DAD3254E9242AE85ABDE4BA15168EAF0CA87A555FD56D10FBCA"
+ "2907E3E83BA95368623B8C4686915CF9",
+ "94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C"
+ "81A648152E44ACF96E36DD1E80FABE46",
+ "99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94F"
+ "A329C145786E679E7B82C71A38628AC8"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-512, message = \"sample\"",
+ "sha512", "sample",
+ "92FC3C7183A883E24216D1141F1A8976C5B0DD797DFA597E3D7B32198BD35331"
+ "A4E966532593A52980D0E3AAA5E10EC3",
+ "ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799C"
+ "FE30F35CC900056D7C99CD7882433709",
+ "512C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112"
+ "DC7CC3EF3446DEFCEB01A45C2667FDD5"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-1, message = \"test\"",
+ "sha1", "test",
+ "66CC2C8F4D303FC962E5FF6A27BD79F84EC812DDAE58CF5243B64A4AD8094D47"
+ "EC3727F3A3C186C15054492E30698497",
+ "4BC35D3A50EF4E30576F58CD96CE6BF638025EE624004A1F7789A8B8E43D0678"
+ "ACD9D29876DAF46638645F7F404B11C7",
+ "D5A6326C494ED3FF614703878961C0FDE7B2C278F9A65FD8C4B7186201A29916"
+ "95BA1C84541327E966FA7B50F7382282"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-224, message = \"test\"",
+ "sha224", "test",
+ "18FA39DB95AA5F561F30FA3591DC59C0FA3653A80DAFFA0B48D1A4C6DFCBFF6E"
+ "3D33BE4DC5EB8886A8ECD093F2935726",
+ "E8C9D0B6EA72A0E7837FEA1D14A1A9557F29FAA45D3E7EE888FC5BF954B5E624"
+ "64A9A817C47FF78B8C11066B24080E72",
+ "07041D4A7A0379AC7232FF72E6F77B6DDB8F09B16CCE0EC3286B2BD43FA8C614"
+ "1C53EA5ABEF0D8231077A04540A96B66"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-256, message = \"test\"",
+ "sha256", "test",
+ "0CFAC37587532347DC3389FDC98286BBA8C73807285B184C83E62E26C401C0FA"
+ "A48DD070BA79921A3457ABFF2D630AD7",
+ "6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559"
+ "F918EEDAF2293BE5B475CC8F0188636B",
+ "2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D"
+ "51AB373F9845C0514EEFB14024787265"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-384, message = \"test\"",
+ "sha384", "test",
+ "015EE46A5BF88773ED9123A5AB0807962D193719503C527B031B4C2D225092AD"
+ "A71F4A459BC0DA98ADB95837DB8312EA",
+ "8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB"
+ "0542A7F0812998DA8F1DD3CA3CF023DB",
+ "DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E0"
+ "6A739F040649A667BF3B828246BAA5A5"
+ },
+ {
+ "ECDSA, 384 bits (prime field)",
+ "With SHA-512, message = \"test\"",
+ "sha512", "test",
+ "3780C4F67CB15518B6ACAE34C9F83568D2E12E47DEAB6C50A4E4EE5319D1E8CE"
+ "0E2CC8A136036DC4B9C00E6888F66B6C",
+ "A0D5D090C9980FAF3C2CE57B7AE951D31977DD11C775D314AF55F76C676447D0"
+ "6FB6495CD21B4B6E340FC236584FB277",
+ "976984E59B4C77B0E8E4460DCA3D9F20E07B9BB1F63BEEFAF576F6B2E8B22463"
+ "4A2092CD3792E0159AD9CEE37659C736"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-1, message = \"sample\"",
+ "sha1", "sample",
+ "0089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB"
+ "42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D"
+ "0F9",
+ "343B6EC45728975EA5CBA6659BBB6062A5FF89EEA58BE3C80B619F322C87910"
+ "FE092F7D45BB0F8EEE01ED3F20BABEC079D202AE677B243AB40B5431D497C55D"
+ "75D",
+ "E7B0E675A9B24413D448B8CC119D2BF7B2D2DF032741C096634D6D65D0DBE3D"
+ "5694625FB9E8104D3B842C1B0E2D0B98BEA19341E8676AEF66AE4EBA3D5475D5"
+ "D16"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-224, message = \"sample\"",
+ "sha224", "sample",
+ "121415EC2CD7726330A61F7F3FA5DE14BE9436019C4DB8CB4041F3B54CF31BE0"
+ "493EE3F427FB906393D895A19C9523F3A1D54BB8702BD4AA9C99DAB2597B9211"
+ "3F3",
+ "01776331CFCDF927D666E032E00CF776187BC9FDD8E69D0DABB4109FFE1B5E2A3"
+ "0715F4CC923A4A5E94D2503E9ACFED92857B7F31D7152E0F8C00C15FF3D87E2E"
+ "D2E",
+ "50CB5265417FE2320BBB5A122B8E1A32BD699089851128E360E620A30C7E17B"
+ "A41A666AF126CE100E5799B153B60528D5300D08489CA9178FB610A2006C254B"
+ "41F"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-256, message = \"sample\"",
+ "sha256", "sample",
+ "0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C3257576"
+ "1793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E"
+ "1A0",
+ "01511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659"
+ "D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E"
+ "1A7",
+ "4A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916"
+ "E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7E"
+ "CFC"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-384, message = \"sample\"",
+ "sha384", "sample",
+ "1546A108BC23A15D6F21872F7DED661FA8431DDBD922D0DCDB77CC878C8553FF"
+ "AD064C95A920A750AC9137E527390D2D92F153E66196966EA554D9ADFCB109C4"
+ "211",
+ "01EA842A0E17D2DE4F92C15315C63DDF72685C18195C2BB95E572B9C5136CA4B4"
+ "B576AD712A52BE9730627D16054BA40CC0B8D3FF035B12AE75168397F5D50C67"
+ "451",
+ "01F21A3CEE066E1961025FB048BD5FE2B7924D0CD797BABE0A83B66F1E35EEAF5"
+ "FDE143FA85DC394A7DEE766523393784484BDF3E00114A1C857CDE1AA203DB65"
+ "D61"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-512, message = \"sample\"",
+ "sha512", "sample",
+ "1DAE2EA071F8110DC26882D4D5EAE0621A3256FC8847FB9022E2B7D28E6F1019"
+ "8B1574FDD03A9053C08A1854A168AA5A57470EC97DD5CE090124EF52A2F7ECBF"
+ "FD3",
+ "C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F1"
+ "74E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E37"
+ "7FA",
+ "617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF2"
+ "82623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A"
+ "67A"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-1, message = \"test\"",
+ "sha1", "test",
+ "0BB9F2BF4FE1038CCF4DABD7139A56F6FD8BB1386561BD3C6A4FC818B20DF5DD"
+ "BA80795A947107A1AB9D12DAA615B1ADE4F7A9DC05E8E6311150F47F5C57CE8B"
+ "222",
+ "013BAD9F29ABE20DE37EBEB823C252CA0F63361284015A3BF430A46AAA80B87B0"
+ "693F0694BD88AFE4E661FC33B094CD3B7963BED5A727ED8BD6A3A202ABE009D0"
+ "367",
+ "01E9BB81FF7944CA409AD138DBBEE228E1AFCC0C890FC78EC8604639CB0DBDC90"
+ "F717A99EAD9D272855D00162EE9527567DD6A92CBD629805C0445282BBC91679"
+ "7FF"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-224, message = \"test\"",
+ "sha224", "test",
+ "040D09FCF3C8A5F62CF4FB223CBBB2B9937F6B0577C27020A99602C25A011369"
+ "87E452988781484EDBBCF1C47E554E7FC901BC3085E5206D9F619CFF07E73D6F"
+ "706",
+ "01C7ED902E123E6815546065A2C4AF977B22AA8EADDB68B2C1110E7EA44D42086"
+ "BFE4A34B67DDC0E17E96536E358219B23A706C6A6E16BA77B65E1C595D43CAE1"
+ "7FB",
+ "0177336676304FCB343CE028B38E7B4FBA76C1C1B277DA18CAD2A8478B2A9A9F5"
+ "BEC0F3BA04F35DB3E4263569EC6AADE8C92746E4C82F8299AE1B8F1739F8FD51"
+ "9A4"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-256, message = \"test\"",
+ "sha256", "test",
+ "01DE74955EFAABC4C4F17F8E84D881D1310B5392D7700275F82F145C61E84384"
+ "1AF09035BF7A6210F5A431A6A9E81C9323354A9E69135D44EBD2FCAA7731B909"
+ "258",
+ "0E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D807104"
+ "2EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656"
+ "AA8",
+ "CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9"
+ "FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694"
+ "E86"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-384, message = \"test\"",
+ "sha384", "test",
+ "1F1FC4A349A7DA9A9E116BFDD055DC08E78252FF8E23AC276AC88B1770AE0B5D"
+ "CEB1ED14A4916B769A523CE1E90BA22846AF11DF8B300C38818F713DADD85DE0"
+ "C88",
+ "014BEE21A18B6D8B3C93FAB08D43E739707953244FDBE924FA926D76669E7AC8C"
+ "89DF62ED8975C2D8397A65A49DCC09F6B0AC62272741924D479354D74FF60755"
+ "78C",
+ "0133330865C067A0EAF72362A65E2D7BC4E461E8C8995C3B6226A21BD1AA78F0E"
+ "D94FE536A0DCA35534F0CD1510C41525D163FE9D74D134881E35141ED5E8E95B"
+ "979"
+ },
+ {
+ "ECDSA, 521 bits (prime field)",
+ "With SHA-512, message = \"test\"",
+ "sha512", "test",
+ "16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1"
+ "B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC"
+ "56D",
+ "013E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10"
+ "CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47E"
+ "E6D",
+ "01FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78"
+ "A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4D"
+ "CE3"
+ },
+ { NULL }
+ };
+
+ gpg_error_t err;
+ int tno, i, hashalgo;
+ gcry_sexp_t seckey, data, sig;
+ unsigned char digest[64];
+ int digestlen;
+
+ for (tno = 0; tests[tno].keyname; tno++)
+ {
+ if (verbose)
+ info ("Test %d: %s. %s.\n", tno, tests[tno].keyname, tests[tno].name);
+
+ {
+ for (i=0; keys[i].name; i++)
+ if (!strcmp (tests[tno].keyname, keys[i].name))
+ break;
+ if (!keys[i].name)
+ die ("Key '%s' used by test '%s' not found\n",
+ tests[tno].keyname, tests[tno].name);
+
+ err = gcry_sexp_new (&seckey, keys[i].key, 0, 1);
+ if (err)
+ die ("reading key failed: %s\n", gpg_strerror (err));
+ }
+
+ hashalgo = gcry_md_map_name (tests[tno].hashname);
+ if (!hashalgo)
+ die ("hash with name '%s' is not supported\n", tests[tno].hashname);
+
+ digestlen = gcry_md_get_algo_dlen (hashalgo);
+ if (digestlen > sizeof digest)
+ die ("internal error: digest does not fit into our buffer\n");
+
+ gcry_md_hash_buffer (hashalgo, digest,
+ tests[tno].message, strlen (tests[tno].message));
+
+ err = gcry_sexp_build (&data, NULL,
+ "(data "
+ " (flags rfc6979)"
+ " (hash %s %b))",
+ tests[tno].hashname, digestlen, digest);
+ if (err)
+ die ("building data sexp failed: %s\n", gpg_strerror (err));
+
+ err = gcry_pk_sign (&sig, data, seckey);
+ if (err)
+ fail ("signing failed: %s\n", gpg_strerror (err));
+
+ extract_cmp_data (sig, "r", tests[tno].r);
+ extract_cmp_data (sig, "s", tests[tno].s);
+
+ err = gcry_pk_verify (sig, data, seckey);
+ if (err)
+ fail ("verification failed: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data);
+ gcry_sexp_release (seckey);
+ }
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ {
+ verbose = 2;
+ debug = 1;
+ }
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 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));
+ 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));
+
+ check_dsa_rfc6979 ();
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/fips186-dsa.c b/comm/third_party/libgcrypt/tests/fips186-dsa.c
new file mode 100644
index 0000000000..eb74cc2b12
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/fips186-dsa.c
@@ -0,0 +1,572 @@
+/* fips186-dsa.c - FIPS 186 DSA tests
+ * Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt-int.h"
+#else
+# include <gcrypt.h>
+#endif
+
+#define PGM "fips186-dsa"
+#include "t-common.h"
+
+
+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 gcry_mpi_t
+mpi_from_string (const char *string)
+{
+ gpg_error_t err;
+ gcry_mpi_t a;
+
+ err = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (err)
+ die ("error converting string to mpi: %s\n", gpg_strerror (err));
+ return a;
+}
+
+/* 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 returns NULL on
+ error. */
+static void *
+data_from_hex (const char *string, size_t *r_length)
+{
+ const char *s;
+ unsigned char *buffer;
+ size_t length;
+
+ buffer = gcry_xmalloc (strlen(string)/2+1);
+ length = 0;
+ for (s=string; *s; s +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ die ("error parsing hex string `%s'\n", string);
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static void
+extract_cmp_mpi (gcry_sexp_t sexp, const char *name, const char *expected)
+{
+ gcry_sexp_t l1;
+ gcry_mpi_t a, b;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ b = mpi_from_string (expected);
+ if (!a)
+ fail ("parameter \"%s\" missing in key\n", name);
+ else if ( gcry_mpi_cmp (a, b) )
+ fail ("parameter \"%s\" does not match expected value\n", name);
+ gcry_mpi_release (b);
+ gcry_mpi_release (a);
+ gcry_sexp_release (l1);
+}
+
+
+static void
+extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
+{
+ gcry_sexp_t l1;
+ const void *a;
+ size_t alen;
+ void *b;
+ size_t blen;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_data (l1, 1, &alen);
+ b = data_from_hex (expected, &blen);
+ if (!a)
+ fail ("parameter \"%s\" missing in key\n", name);
+ else if ( alen != blen || memcmp (a, b, alen) )
+ fail ("parameter \"%s\" does not match expected value\n", name);
+ gcry_free (b);
+ gcry_sexp_release (l1);
+}
+
+static void
+extract_cmp_int (gcry_sexp_t sexp, const char *name, int expected)
+{
+ gcry_sexp_t l1;
+ char *a;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_string (l1, 1);
+ if (!a)
+ fail ("parameter \"%s\" missing in key\n", name);
+ else if ( strtoul (a, NULL, 10) != expected )
+ fail ("parameter \"%s\" does not match expected value\n", name);
+ gcry_free (a);
+ gcry_sexp_release (l1);
+}
+
+
+static void
+check_dsa_gen_186_2 (void)
+{
+ static struct {
+ int nbits;
+ const char *p, *q, *g;
+ const char *seed;
+ int counter;
+ const char *h;
+ } tbl[] = {
+ /* These tests are from FIPS 186-2, DSAVS B.3.1 PQGGen.rsp. CAVS 2.2. */
+ {
+ 1024,
+ "d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
+ "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
+ "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
+ "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69",
+ "9c916d121de9a03f71fb21bc2e1c0d116f065a4f",
+ "8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
+ "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
+ "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
+ "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44",
+ "0cb1990c1fd3626055d7a0096f8fa99807399871",
+ 98,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002"
+ },
+ {
+ 1024,
+ "f5c73304080353357de1b5967597c27d65f70aa2fe9b6aed1d0afc2b499adf22f"
+ "8e37937096d88548ac36c4a067f8353c7fed73f96f0d688b19b0624aedbae5dbb"
+ "0ee8835a4c269288c0e1d69479e701ee266bb767af39d748fe7d6afc73fdf44be"
+ "3eb6e661e599670061203e75fc8b3dbd59e40b54f358d0097013a0f3867f9",
+ "f8751166cf4f6f3b07c081fd2a9071f23ca1988d",
+ "1e288a442e02461c418ed67a66d24cacbeb8936fbde62ff995f5fd569dee6be62"
+ "4e4f0f9f8c8093f5d192ab3b3f9ae3f2665d95d27fb10e382f45cd356e7f4eb7a"
+ "665db432113ed06478f93b7cf188ec7a1ee97aec8f91ea7bfceaf8b6e7e5a349c"
+ "4ad3225362ef440c57cbc6e69df15b6699caac85f733555075f04781b2b33",
+ "34b3520d45d240a8861b82c8b61ffa16e67b5cce",
+ 622,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002",
+ },
+ {
+ 1024,
+ "c6c6f4f4eed927fb1c3b0c81010967e530658e6f9698ebe058b4f47b2dc8fcbc7"
+ "b69296b9e8b6cf55681181fe72492668061b262b0046a0d409902e269b0cb69a4"
+ "55ed1a086caf41927f5912bf0e0cbc45ee81a4f98bf6146f6168a228aec80e9cc"
+ "1162d6f6aa412efe82d4f18b95e34ab790daac5bd7aef0b22fa08ba5dbaad",
+ "d32b29f065c1394a30490b6fcbf812a32a8634ab",
+ "06f973c879e2e89345d0ac04f9c34ad69b9eff1680f18d1c8f3e1596c2e8fa8e1"
+ "ecef6830409e9012d4788bef6ec7414d09c981b47c941b77f39dfc49caff5e714"
+ "c97abe25a7a8b5d1fe88700bb96eff91cca64d53700a28b1146d81bad1212d231"
+ "80154c95a01f5aeebb553a8365c38a5ebe05539b51734233776ce9aff98b2",
+ "b6ec750da2f824cb42c5f7e28c81350d97f75125",
+ 185,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002",
+ },
+ {
+ 1024,
+ "b827a9dc9221a6ed1bec7b64d61232aacb2812f888b0a0b3a95033d7a22e77d0b"
+ "ff23bfeed0fb1281b21b8ff7421f0c727d1fb8aa2b843d6885f067e763f83d41f"
+ "d800ab15a7e2b12f71ec2058ee7bd62cd72c26989b272e519785da57bfa1f974b"
+ "c652e1a2d6cfb68477de5635fd019b37add656cff0b802558b31b6d2851e5",
+ "de822c03445b77cec4ad3a6fb0ca39ff97059ddf",
+ "65a9e2d43a378d7063813104586868cacf2fccd51aec1e0b6af8ba3e66dee6371"
+ "681254c3fb5e3929d65e3c4bcd20abd4ddc7cf815623e17b9fc92f02b8d44278b"
+ "848480ffd193104cf5612639511e45bd247708ff6028bd3824f8844c263b46c69"
+ "1f2076f8cd13c5d0be95f1f2a1a17ab1f7e5bc73500bac27d57b473ba9748",
+ "cd2221dd73815a75224e9fde7faf52829b81ac7a",
+ 62,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002",
+ },
+ {
+ 1024,
+ "898a8d93e295c8ef2ffd46976225a1543640640d155a576fafa0be32136165803"
+ "ba2eff2782a2be75cc9ec65db6bd3238cca695b3a5a14726a2a314775c377d891"
+ "354b3de6c89e714a05599ca04132c987f889f72c4fe298ccb31f711c03b07e1d9"
+ "8d72af590754cf3847398b60cecd55a4611692b308809560a83880404c227",
+ "c6d786643d2acfc6b8d576863fda8cfbfbd5e03f",
+ "2fd38b8d21c58e8fb5315a177b8d5dc4c450d574e69348b7b9da367c26e72438d"
+ "af8372e7f0bee84ef5dcbbc3727194a2228431192f1779be24837f22a0e14d10d"
+ "5344da1b8b403df9f9b2655095b3d0f67418ed6cd989f35aa4232e4b7001764fb"
+ "e85d6b2c716980f13272fc4271ac1e234f7e24c023cfc2d2dc0aa1e9af2fb",
+ "73483e697599871af983a281e3afa22e0ed86b68",
+ 272,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002",
+ },
+
+ /* These tests are generated by the OpenSSL FIPS version. */
+ {
+ 1024,
+ "A404363903FDCE86839BCFD953AAD2DA2B0E70CAED3B5FF5D68F15A1C4BB0A793C"
+ "A9D58FC956804C5901DE0AF99F345ED1A8617C687864BAC044B7C3C3E732A2B255"
+ "EC986AA76EA8CB0E0815B3E0E605650AF7D8058EE7E8EBCDEFFDAB8100D3FC1033"
+ "11BA3AB232EF06BB74BA9A949EC0C7ED324C19B202F4AB725BBB4080C9",
+ "C643946CEA8748E12D430C48DB038F9165814389",
+ "59B7E7BA0033CCE8E6837173420FBB382A784D4154A3C166043F5A68CB92945D16"
+ "892D4CC5585F2D28C780E75A6C20A379E2B58304C1E5FC0D8C15E4E89C4498C8BC"
+ "B90FB36ED8DC0489B9D0BC09EC4411FB0BFADF25485EEAB6700BE0ACF5C44A6ED7"
+ "44A015382FF9B8DA7EAA00DEA135FADC59212DBBFFC1537336FA4B7225",
+ "02708ab36e3f0bfd67ec3b8bd8829d03b84f56bd",
+ 50,
+ "02"
+ },
+ {
+ 1024,
+ "9C664033DB8B203D826F896D2293C62EF9351D5CFD0F4C0AD7EFDA4DDC7F15987"
+ "6A3C68CAB2586B44FD1BD4DEF7A17905D88D321DD77C4E1720D848CA21D79F9B3"
+ "D8F537338E09B44E9F481E8DA3C56569F63146596A050EF8FAEE8ACA32C666450"
+ "04F675C8806EB4025B0A5ECC39CE89983EA40A183A7CF5208BA958045ABD5",
+ "AD0D8CBA369AF6CD0D2BAC0B4CFCAF0A1F9BCDF7",
+ "74D717F7092A2AF725FDD6C2561D1DBE5AEE40203C638BA8B9F49003857873701"
+ "95A44E515C4E8B344F5CDC7F4A6D38097CD57675E7643AB9700692C69F0A99B0E"
+ "039FDDDFCA8CEB607BDB4ADF2834DE1690F5823FC8199FB8F6F29E5A583B6786A"
+ "C14C7E67106C3B30568CBB9383F89287D578159778EB18216799D16D46498",
+ "6481a12a50384888ee84b61024f7c9c685d6ac96",
+ 289,
+ "02"
+ },
+ {
+ 1024,
+
+ "B0DFB602EB8462B1DC8C2214A52B587D3E6842CCF1C38D0F7C7F967ED30CF6828"
+ "1E2675B3BAB594755FB1634E66B4C23936F0725A358F8DFF3C307E2601FD66D63"
+ "5B17270450C50BD2BEC29E0E9A471DF1C15B0191517952268A2763D4BD28B8503"
+ "B3399686272B76B11227F693D7833105EF70C2289C3194CF4527024B272DF",
+ "EA649C04911FAB5A41440287A517EF752A40354B",
+ "88C5A4563ECB949763E0B696CD04B21321360F54C0EE7B23E2CEDC30E9E486162"
+ "01BFB1619E7C54B653D1F890C50E04B29205F5E3E2F93A13B0751AF25491C5194"
+ "93C09DDF6B9C173B3846DFB0E7A5C870BBFC78419260C90E20315410691C8326C"
+ "858D7063E7921F3F601158E912C7EE487FF259202BEEB10F6D9E99190F696",
+ "5bf9d17bc62fbbf3d569c92bd4505586b2e5ef1a",
+ 626,
+ "02"
+ },
+ {
+ 1024,
+ "F783C08D7F9463E48BA87893805C4B34B63C85DF7EBDD9EBEE94DB4AF4E4A415C"
+ "F0F3793AE55096BA1199598798FA8403B28DED7F7C7AFD54FD535861A0150EF4D"
+ "5871465B13837CCF46BEB0A22F8D38DC7D6AE0E14A3845FD0C027CFA97791B977"
+ "CE2808BAD9B43CE69390C0F40016056722D82C0D7B1B27413D026A39D7DAD",
+ "A40D9EE456AED4C8A653FDB47B6629C0B843FE8F",
+ "DF876263E21F263AE6DA57409BD517DCEADB9216048F066D6B58867F8E59A5EEE"
+ "700283A946C1455534618979BE6C227673C1B803910262BD93BC94D5089850614"
+ "F3E29AB64E8C989A7E3E28FE670FFA3EE21DEEEC1AB0B60E1D8E2AA39663BADD7"
+ "2C9F957D7F3D4F17D9FDAD050EB373A6DEFD09F5DA752EAFE046836E14B67",
+ "8a9a57706f69f4f566252cdf6d5cbfdf2020150b",
+ 397,
+ "02"
+ },
+ {
+ 1024,
+ "D40E4F6461E145859CCF60FD57962840BD75FFF12C22F76626F566842252AD068"
+ "29745F0147056354F6C016CF12762B0E331787925B8128CF5AF81F9B176A51934"
+ "96D792430FF83C7B79BD595BDA10787B34600787FA552EFE3662F37B99AAD3F3A"
+ "093732680A01345192A19BECCE6BF5D498E44ED6BED5B0BA72AAD49E8276B",
+ "D12F1BD0AA78B99247FD9F18EAFEE5C136686EA5",
+ "468EBD20C99449C1E440E6F8E452C6A6BC7551C555FE5E94996E20CFD4DA3B9CC"
+ "58499D6CC2374CCF9C392715A537DE10CFCA8A6A37AFBD187CF6B88D26881E5F5"
+ "7521D9D2C9BBA51E7B87B070BBE73F5C5FE31E752CAF88183516D8503BAAC1159"
+ "928EF50DEE52D96F396B93FB4138D786464C315401A853E57C9A0F9D25839",
+ "30b3599944a914a330a3f49d11ec88f555422aef",
+ 678,
+ "02"
+ }
+ };
+ gpg_error_t err;
+ int tno;
+ gcry_sexp_t key_spec, key, pub_key, sec_key, seed_values;
+ gcry_sexp_t l1;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ if (verbose)
+ info ("generating FIPS 186-2 test key %d\n", tno);
+
+ {
+ void *data;
+ size_t datalen;
+
+ data = data_from_hex (tbl[tno].seed, &datalen);
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (dsa (nbits %d)(use-fips186-2)"
+ "(derive-parms(seed %b))))",
+ tbl[tno].nbits, (int)datalen, data);
+ gcry_free (data);
+ }
+ if (err)
+ die ("error creating S-expression %d: %s\n", tno, gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (err)
+ {
+ fail ("error generating key %d: %s\n", tno, gpg_strerror (err));
+ continue;
+ }
+
+ if (verbose > 1)
+ show_sexp ("generated key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ fail ("public part missing in key %d\n", tno);
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ fail ("private part missing in key %d\n", tno);
+
+ l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
+ if (!l1)
+ fail ("misc_key_info part missing in key %d\n", tno);
+ seed_values = gcry_sexp_find_token (l1, "seed-values", 0);
+ if (!seed_values)
+ fail ("seed-values part missing in key %d\n", tno);
+ gcry_sexp_release (l1);
+
+ extract_cmp_mpi (sec_key, "p", tbl[tno].p);
+ extract_cmp_mpi (sec_key, "q", tbl[tno].q);
+ extract_cmp_mpi (sec_key, "g", tbl[tno].g);
+
+ extract_cmp_data (seed_values, "seed", tbl[tno].seed);
+ extract_cmp_int (seed_values, "counter", tbl[tno].counter);
+ extract_cmp_mpi (seed_values, "h", tbl[tno].h);
+
+ gcry_sexp_release (seed_values);
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ gcry_sexp_release (key);
+ }
+}
+
+
+static void
+check_dsa_gen_186_3 (void)
+{
+ static struct {
+ int nbits, qbits;
+ const char *p, *q;
+ const char *seed;
+ int counter;
+ } tbl[] = {
+ /* These tests are from FIPS 186-3 Test Vectors, PQGGen.rsp. CAVS 11.1. */
+ {
+ 2048,
+ 256,
+ "8e2266d5cb5b1e9ad34ac6380e3d166fd4d60dadc6dfa1be8492a5642c91fdf7"
+ "e81b9634a4eeff59e7e93b1b0e8f49ded45a72788866dff71b1329feeb4b6cdb"
+ "f2c7166c7cbca20b04300ae127c9940233e891712ac905ed6b43495717a2998e"
+ "a8c4eef4ec6c32dc9e774e8e66476f17d9c39abac59e8b583b1107b679e0bed0"
+ "78476e933a90cfcf80c89b831c0e054f86eac7ca848e059662d938a4e12947e2"
+ "e73b1ffedd7125dd54ba463217abc9c5f3399132aec77b946c806429f6f812c1"
+ "0716d57dde7b5d45cb2e5eb6e4dbb81d5a465054fa17e613cbe01afb49ea593f"
+ "33f1a696a774941ca1ff6f208577fe529f5e7592f39698c63bf6ae9d56cd2d93",
+ "b19c6d094e1210c92910f49aa083957fbe68c0ca4602896f50123fd776786275",
+ "f770a4598ff756931fc529764513b103ce57d85f4ad8c5cf297c9b4d48241c5b",
+ 105
+ },
+ {
+ 2048,
+ 256,
+ "b636e5970383cecab68840cca8a909a29325c3924e2c187dd034222f9e1a4334"
+ "1061ca620f82787bd349fb8f380fc3f0adb84be116c695529114aecee8a0a1b0"
+ "9e7ebb6888e6da71f48eefb3e9990e2d7bd36c1aa24fb10e011a193d6b5a1b22"
+ "6cf97fab302e237ecb1dc824264dba2e2285930005717c4e9a12cc1a1ac336c2"
+ "0619c4d06ec4e1e02e0d1d2d285661a7472d30c4282646506487cbe6a5c988ee"
+ "8402d474713a7d8213eeb19a0719996bbfd3835eb8832eead5a3a340e61c52f0"
+ "0dde1c98655a13839ad215d8f43c8e482317af8b086c3d555fc8dbb2f595f256"
+ "3520a0c6387661774e1e6ca5fe2626b26a2c4f99b7aff043a091434dfd3275b7",
+ "fe9f06fa1901182ab00bf063bff8fd4f736922ce830fd50fee47ebbd21e291e9",
+ "3a66a430f23374ce3d2e758881c411c23dad4a8cd6ad697056d24b8cfcc8c353",
+ 720
+ },
+ {
+ 2048,
+ 256,
+ "8d636640981c2ce1935bd16ad3aa3ce2a6efa26f23f07ceda92766f80e82fa03"
+ "5c6cf44dc41e08fea242c5cd5846d839bdf0c11d3a29ebaca00aad844cd33a80"
+ "448f1f96cebe66b9963f7e3b5c976e29dc430bc5ddf5d2c198eb736339adc14d"
+ "5c8a3d22533d7c6a861b6a8b31c55e46804e4c2f95e2e9cc2bbb23bbc833995a"
+ "7afe619127d28fa53b0712b17da4786f9116cc39e2c6254845e85513c220e368"
+ "fe9c92bc71eabfa831062f01e66e8a970f043112ca0af175f64d13fcff2f087f"
+ "ff9198a9fe9732001ab49b2a48d0e39f99d036698703aa853ac02c65f3d55993"
+ "5a72c8bbc6ab2fa59ff9a2fcd837a4675229abed23d42badc12a60b34a3bf0f5",
+ "b5f3c535e7f48d3251d353b73b3a05c4bdb4591a8c2f2ba4a6a945a889f5aeff",
+ "77eb88f087bfbbc312bca7572bafd36f2a7aca2e4d7378dd923b0b277f3d730f",
+ 137
+ },
+ {
+ 2048,
+ 256,
+ "8fa95228b848a9533375e4789c88bb7df505c4478ed3c79545c5d2b04f0e0efb"
+ "ac8d3f603603a48b203e1cc67ded22b840ac21bc41b7ab78c73a9cd0773148ca"
+ "7c87a5a51564164f683e8f8a77b97cf7d91f989aa3668819bca8f54e0ec8f10c"
+ "78ecd26982048cf0ab0446a6de154bbed8891be916627d470061811caf51bef1"
+ "b5be8ef2b560cf981c2a097b3769bed61d6ee9b66221e956fe2c49f1809a2d5f"
+ "6996be7b39f41afea5184a73c049f3abbd28fddbf37bcae6c4aa4a7255464c2e"
+ "ee915c44b8d90d76e5d9e3d8e6cf4ac7c5d9436d19ccc27c5bc1b65dbb56723b"
+ "5e77624489652313f9da2ce38554401fdbd61c78f2a4fa69bcc2f5aaffbfed2d",
+ "ed3f52bce81572d126b27fb1e9c02346ae523532af82b79943565593d6f46d45",
+ "e0ed96bf5e7d78754b5095ed766a1bbc4338eaa8f3d00e9906ef51a8798bc1c2",
+ 40
+ },
+ {
+ 2048,
+ 256,
+ "a80f2481a814d07eb47a7c67e24bc3f8f1ccebc6cf684a0bc9fbb0054cc24cef"
+ "24872315b566630d5147184980b4bce3f0849660c84b22dfacb785446c0f6314"
+ "b7a53a92cf821bcceb325e03dc9e404832146d34ff8a9b112ed0e69efe69c619"
+ "5de03373e590eba88fc5b9d337d6566dc7e82e326a28343f644779f6784159eb"
+ "3d33f2ddf1157a02f2f91d0897a4e8ad53f614186a5fe043187510316904bd95"
+ "6966e10735d6ef01c195b7dd7fd245a83c18af7908fef0bced2f454e1954f2a3"
+ "2c35658f4e0f5811a3d06c81cca715537debabbbc65ba4dd0e7fb0c08397622f"
+ "039a51df69f5b10dda61f57bbb84c55f25eacd0f3d8b40ae016ed0ba856837e7",
+ "9e3b5a7939082c95069902d3833df8421871ca2dab8a34f7be6cd39151291d07",
+ "c7bb440d973189ca07464b037fd309f68ec38baba390988a2e986ecee281e2f5",
+ 722
+ }
+ };
+ gpg_error_t err;
+ int tno;
+ gcry_sexp_t key_spec, key, pub_key, sec_key, seed_values;
+ gcry_sexp_t l1;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ if (verbose)
+ info ("generating FIPS 186-3 test key %d\n", tno);
+
+ {
+ void *data;
+ size_t datalen;
+
+ data = data_from_hex (tbl[tno].seed, &datalen);
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)"
+ "(derive-parms(seed %b))))",
+ tbl[tno].nbits, tbl[tno].qbits,
+ (int)datalen, data);
+ gcry_free (data);
+ }
+ if (err)
+ die ("error creating S-expression %d: %s\n", tno, gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (err)
+ {
+ fail ("error generating key %d: %s\n", tno, gpg_strerror (err));
+ continue;
+ }
+
+ if (verbose > 1)
+ show_sexp ("generated key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ fail ("public part missing in key %d\n", tno);
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ fail ("private part missing in key %d\n", tno);
+
+ l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
+ if (!l1)
+ fail ("misc_key_info part missing in key %d\n", tno);
+ seed_values = gcry_sexp_find_token (l1, "seed-values", 0);
+ if (!seed_values)
+ fail ("seed-values part missing in key %d\n", tno);
+ gcry_sexp_release (l1);
+
+ extract_cmp_mpi (sec_key, "p", tbl[tno].p);
+ extract_cmp_mpi (sec_key, "q", tbl[tno].q);
+
+ extract_cmp_data (seed_values, "seed", tbl[tno].seed);
+ extract_cmp_int (seed_values, "counter", tbl[tno].counter);
+
+ gcry_sexp_release (seed_values);
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ gcry_sexp_release (key);
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ {
+ verbose = 2;
+ debug = 1;
+ }
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ 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));
+
+
+ check_dsa_gen_186_2 ();
+ check_dsa_gen_186_3 ();
+
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/fipsdrv.c b/comm/third_party/libgcrypt/tests/fipsdrv.c
new file mode 100644
index 0000000000..f6268e2acf
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/fipsdrv.c
@@ -0,0 +1,2865 @@
+/* fipsdrv.c - A driver to help with FIPS CAVS tests.
+ Copyright (C) 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#ifdef HAVE_W32_SYSTEM
+# include <fcntl.h> /* We need setmode(). */
+#else
+# include <signal.h>
+#endif
+#include <assert.h>
+#include <unistd.h>
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+# include <gcrypt.h>
+# define PACKAGE_BUGREPORT "devnull@example.org"
+# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]"
+#endif
+#include "../src/gcrypt-testapi.h"
+
+#define PGM "fipsdrv"
+#include "t-common.h"
+
+
+/* Binary input flag. */
+static int binary_input;
+
+/* Binary output flag. */
+static int binary_output;
+
+/* Base64 output flag. */
+static int base64_output;
+
+/* We need to know whether we are in loop_mode. */
+static int loop_mode;
+
+/* If true some functions are modified to print the output in the CAVS
+ response file format. */
+static int standalone_mode;
+
+
+/* ASN.1 classes. */
+enum
+{
+ UNIVERSAL = 0,
+ APPLICATION = 1,
+ ASNCONTEXT = 2,
+ PRIVATE = 3
+};
+
+
+/* ASN.1 tags. */
+enum
+{
+ TAG_NONE = 0,
+ TAG_BOOLEAN = 1,
+ TAG_INTEGER = 2,
+ TAG_BIT_STRING = 3,
+ TAG_OCTET_STRING = 4,
+ TAG_NULL = 5,
+ TAG_OBJECT_ID = 6,
+ TAG_OBJECT_DESCRIPTOR = 7,
+ TAG_EXTERNAL = 8,
+ TAG_REAL = 9,
+ TAG_ENUMERATED = 10,
+ TAG_EMBEDDED_PDV = 11,
+ TAG_UTF8_STRING = 12,
+ TAG_REALTIVE_OID = 13,
+ TAG_SEQUENCE = 16,
+ TAG_SET = 17,
+ TAG_NUMERIC_STRING = 18,
+ TAG_PRINTABLE_STRING = 19,
+ TAG_TELETEX_STRING = 20,
+ TAG_VIDEOTEX_STRING = 21,
+ TAG_IA5_STRING = 22,
+ TAG_UTC_TIME = 23,
+ TAG_GENERALIZED_TIME = 24,
+ TAG_GRAPHIC_STRING = 25,
+ TAG_VISIBLE_STRING = 26,
+ TAG_GENERAL_STRING = 27,
+ TAG_UNIVERSAL_STRING = 28,
+ TAG_CHARACTER_STRING = 29,
+ TAG_BMP_STRING = 30
+};
+
+/* ASN.1 Parser object. */
+struct tag_info
+{
+ int class; /* Object class. */
+ unsigned long tag; /* The tag of the object. */
+ unsigned long length; /* Length of the values. */
+ int nhdr; /* Length of the header (TL). */
+ unsigned int ndef:1; /* The object has an indefinite length. */
+ unsigned int cons:1; /* This is a constructed object. */
+};
+
+
+static void
+showhex (const char *prefix, const void *buffer, size_t length)
+{
+ const unsigned char *p = buffer;
+
+ if (prefix)
+ fprintf (stderr, PGM ": %s: ", prefix);
+ while (length-- )
+ fprintf (stderr, "%02X", *p++);
+ if (prefix)
+ putc ('\n', stderr);
+}
+
+/* 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); */
+/* } */
+
+
+/* Convert STRING consisting of hex characters into its binary
+ representation and store that at BUFFER. BUFFER needs to be of
+ LENGTH bytes. The function checks that the STRING will convert
+ exactly to LENGTH bytes. The string is delimited by either end of
+ string or a white space character. The function returns -1 on
+ error or the length of the parsed string. */
+static int
+hex2bin (const char *string, void *buffer, size_t length)
+{
+ int i;
+ const char *s = string;
+
+ for (i=0; i < length; )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ return -1; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[i++] = xtoi_2 (s);
+ s += 2;
+ }
+ if (*s && (!my_isascii (*s) || !isspace (*s)) )
+ return -1; /* Not followed by Nul or white space. */
+ if (i != length)
+ return -1; /* Not of expected length. */
+ if (*s)
+ s++; /* Skip the delimiter. */
+ return s - string;
+}
+
+
+/* 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 returns NULL on
+ error. */
+static void *
+hex2buffer (const char *string, size_t *r_length)
+{
+ const char *s;
+ unsigned char *buffer;
+ size_t length;
+
+ buffer = gcry_xmalloc (strlen(string)/2+1);
+ length = 0;
+ for (s=string; *s; s +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static char *
+read_textline (FILE *fp)
+{
+ char line[256];
+ char *p;
+ int any = 0;
+
+ /* Read line but skip over initial empty lines. */
+ do
+ {
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return NULL;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ p = strchr (line, '\n');
+ if (p)
+ *p = 0;
+ p = line + (*line? (strlen (line)-1):0);
+ for ( ;p > line; p--)
+ if (my_isascii (*p) && isspace (*p))
+ *p = 0;
+ }
+ while (!any && !*line);
+ any = 1;
+ }
+ while (*line == '#'); /* Always skip comment lines. */
+ if (verbose > 1)
+ fprintf (stderr, PGM ": received line: %s\n", line);
+ return gcry_xstrdup (line);
+}
+
+static char *
+read_hexline (FILE *fp, size_t *retlen)
+{
+ char *line, *p;
+
+ line = read_textline (fp);
+ if (!line)
+ return NULL;
+ p = hex2buffer (line, retlen);
+ if (!p)
+ die ("error decoding hex string on input\n");
+ gcry_free (line);
+ return p;
+}
+
+static void
+skip_to_empty_line (FILE *fp)
+{
+ char line[256];
+ char *p;
+
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ p = strchr (line, '\n');
+ if (p)
+ *p =0;
+ }
+ while (*line);
+}
+
+
+
+/* Read a file from stream FP into a newly allocated buffer and return
+ that buffer. The valid length of the buffer is stored at R_LENGTH.
+ Returns NULL on failure. If decode is set, the file is assumed to
+ be hex encoded and the decoded content is returned. */
+static void *
+read_file (FILE *fp, int decode, size_t *r_length)
+{
+ char *buffer;
+ size_t buflen;
+ size_t nread, bufsize = 0;
+
+ *r_length = 0;
+#define NCHUNK 8192
+#ifdef HAVE_DOSISH_SYSTEM
+ setmode (fileno(fp), O_BINARY);
+#endif
+ buffer = NULL;
+ buflen = 0;
+ do
+ {
+ bufsize += NCHUNK;
+ if (!buffer)
+ buffer = gcry_xmalloc (bufsize);
+ else
+ buffer = gcry_xrealloc (buffer, bufsize);
+
+ nread = fread (buffer + buflen, 1, NCHUNK, fp);
+ if (nread < NCHUNK && ferror (fp))
+ {
+ gcry_free (buffer);
+ return NULL;
+ }
+ buflen += nread;
+ }
+ while (nread == NCHUNK);
+#undef NCHUNK
+ if (decode)
+ {
+ const char *s;
+ char *p;
+
+ for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ {
+ gcry_free (buffer);
+ return NULL; /* Invalid hex digits. */
+ }
+ *(unsigned char*)p++ = xtoi_2 (s);
+ }
+ if (nread != buflen)
+ {
+ gcry_free (buffer);
+ return NULL; /* Odd number of hex digits. */
+ }
+ buflen = p - buffer;
+ }
+
+ *r_length = buflen;
+ return buffer;
+}
+
+/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Returns
+ the new length of the buffer. Dies on error. */
+static size_t
+base64_decode (char *buffer, size_t length)
+{
+ static unsigned char const asctobin[128] =
+ {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+ 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+
+ int idx = 0;
+ unsigned char val = 0;
+ int c = 0;
+ char *d, *s;
+ int lfseen = 1;
+
+ /* Find BEGIN line. */
+ for (s=buffer; length; length--, s++)
+ {
+ if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11))
+ {
+ for (; length && *s != '\n'; length--, s++)
+ ;
+ break;
+ }
+ lfseen = (*s == '\n');
+ }
+
+ /* Decode until pad character or END line. */
+ for (d=buffer; length; length--, s++)
+ {
+ if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9))
+ break;
+ if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t')
+ continue;
+ if (*s == '=')
+ {
+ /* Pad character: stop */
+ if (idx == 1)
+ *d++ = val;
+ break;
+ }
+
+ if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff)
+ die ("invalid base64 character %02X at pos %d detected\n",
+ *(unsigned char*)s, (int)(s-buffer));
+
+ switch (idx)
+ {
+ case 0:
+ val = c << 2;
+ break;
+ case 1:
+ val |= (c>>4)&3;
+ *d++ = val;
+ val = (c<<4)&0xf0;
+ break;
+ case 2:
+ val |= (c>>2)&15;
+ *d++ = val;
+ val = (c<<6)&0xc0;
+ break;
+ case 3:
+ val |= c&0x3f;
+ *d++ = val;
+ break;
+ }
+ idx = (idx+1) % 4;
+ }
+
+ return d - buffer;
+}
+
+
+/* Parse the buffer at the address BUFFER which consists of the number
+ of octets as stored at BUFLEN. Return the tag and the length part
+ from the TLV triplet. Update BUFFER and BUFLEN on success. Checks
+ that the encoded length does not exhaust the length of the provided
+ buffer. */
+static int
+parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti)
+{
+ int c;
+ unsigned long tag;
+ const unsigned char *buf = *buffer;
+ size_t length = *buflen;
+
+ ti->length = 0;
+ ti->ndef = 0;
+ ti->nhdr = 0;
+
+ /* Get the tag */
+ if (!length)
+ return -1; /* Premature EOF. */
+ c = *buf++; length--;
+ ti->nhdr++;
+
+ ti->class = (c & 0xc0) >> 6;
+ ti->cons = !!(c & 0x20);
+ tag = (c & 0x1f);
+
+ if (tag == 0x1f)
+ {
+ tag = 0;
+ do
+ {
+ tag <<= 7;
+ if (!length)
+ return -1; /* Premature EOF. */
+ c = *buf++; length--;
+ ti->nhdr++;
+ tag |= (c & 0x7f);
+ }
+ while ( (c & 0x80) );
+ }
+ ti->tag = tag;
+
+ /* Get the length */
+ if (!length)
+ return -1; /* Premature EOF. */
+ c = *buf++; length--;
+ ti->nhdr++;
+
+ if ( !(c & 0x80) )
+ ti->length = c;
+ else if (c == 0x80)
+ ti->ndef = 1;
+ else if (c == 0xff)
+ return -1; /* Forbidden length value. */
+ else
+ {
+ unsigned long len = 0;
+ int count = c & 0x7f;
+
+ for (; count; count--)
+ {
+ len <<= 8;
+ if (!length)
+ return -1; /* Premature EOF. */
+ c = *buf++; length--;
+ ti->nhdr++;
+ len |= (c & 0xff);
+ }
+ ti->length = len;
+ }
+
+ if (ti->class == UNIVERSAL && !ti->tag)
+ ti->length = 0;
+
+ if (ti->length > length)
+ return -1; /* Data larger than buffer. */
+
+ *buffer = buf;
+ *buflen = length;
+ return 0;
+}
+
+
+/* Read the file FNAME assuming it is a PEM encoded private key file
+ and return an S-expression. With SHOW set, the key parameters are
+ printed. */
+static gcry_sexp_t
+read_private_key_file (const char *fname, int show)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ const unsigned char *der;
+ size_t derlen;
+ struct tag_info ti;
+ gcry_mpi_t keyparms[8];
+ int n_keyparms = 8;
+ int idx;
+ gcry_sexp_t s_key;
+
+ fp = fopen (fname, binary_input?"rb":"r");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+
+ buflen = base64_decode (buffer, buflen);
+
+ /* Parse the ASN.1 structure. */
+ der = (const unsigned char*)buffer;
+ derlen = buflen;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (ti.length != 1 || *der)
+ goto bad_asn1; /* The value of the first integer is no 0. */
+ der += ti.length; derlen -= ti.length;
+
+ for (idx=0; idx < n_keyparms; idx++)
+ {
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (show)
+ {
+ char prefix[2];
+
+ prefix[0] = idx < 8? "nedpq12u"[idx] : '?';
+ prefix[1] = 0;
+ showhex (prefix, der, ti.length);
+ }
+ err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
+ if (err)
+ die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
+ der += ti.length; derlen -= ti.length;
+ }
+ if (idx != n_keyparms)
+ die ("not enough RSA key parameters\n");
+
+ gcry_free (buffer);
+
+ /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
+ /* First check that p < q; if not swap p and q and recompute u. */
+ if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
+ {
+ gcry_mpi_swap (keyparms[3], keyparms[4]);
+ gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
+ }
+
+ /* Build the S-expression. */
+ err = gcry_sexp_build (&s_key, NULL,
+ "(private-key(rsa(n%m)(e%m)"
+ /**/ "(d%m)(p%m)(q%m)(u%m)))",
+ keyparms[0], keyparms[1], keyparms[2],
+ keyparms[3], keyparms[4], keyparms[7] );
+ if (err)
+ die ("error building S-expression: %s\n", gpg_strerror (err));
+
+ for (idx=0; idx < n_keyparms; idx++)
+ gcry_mpi_release (keyparms[idx]);
+
+ return s_key;
+
+ bad_asn1:
+ die ("invalid ASN.1 structure in `%s'\n", fname);
+ return NULL; /*NOTREACHED*/
+}
+
+
+/* Read the file FNAME assuming it is a PEM encoded public key file
+ and return an S-expression. With SHOW set, the key parameters are
+ printed. */
+static gcry_sexp_t
+read_public_key_file (const char *fname, int show)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ const unsigned char *der;
+ size_t derlen;
+ struct tag_info ti;
+ gcry_mpi_t keyparms[2];
+ int n_keyparms = 2;
+ int idx;
+ gcry_sexp_t s_key;
+
+ fp = fopen (fname, binary_input?"rb":"r");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+
+ buflen = base64_decode (buffer, buflen);
+
+ /* Parse the ASN.1 structure. */
+ der = (const unsigned char*)buffer;
+ derlen = buflen;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+ /* We skip the description of the key parameters and assume it is RSA. */
+ der += ti.length; derlen -= ti.length;
+
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (ti.length < 1 || *der)
+ goto bad_asn1; /* The number of unused bits needs to be 0. */
+ der += 1; derlen -= 1;
+
+ /* Parse the BIT string. */
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+
+ for (idx=0; idx < n_keyparms; idx++)
+ {
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (show)
+ {
+ char prefix[2];
+
+ prefix[0] = idx < 2? "ne"[idx] : '?';
+ prefix[1] = 0;
+ showhex (prefix, der, ti.length);
+ }
+ err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
+ if (err)
+ die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
+ der += ti.length; derlen -= ti.length;
+ }
+ if (idx != n_keyparms)
+ die ("not enough RSA key parameters\n");
+
+ gcry_free (buffer);
+
+ /* Build the S-expression. */
+ err = gcry_sexp_build (&s_key, NULL,
+ "(public-key(rsa(n%m)(e%m)))",
+ keyparms[0], keyparms[1] );
+ if (err)
+ die ("error building S-expression: %s\n", gpg_strerror (err));
+
+ for (idx=0; idx < n_keyparms; idx++)
+ gcry_mpi_release (keyparms[idx]);
+
+ return s_key;
+
+ bad_asn1:
+ die ("invalid ASN.1 structure in `%s'\n", fname);
+ return NULL; /*NOTREACHED*/
+}
+
+
+
+/* Read the file FNAME assuming it is a binary signature result and
+ return an an S-expression suitable for gcry_pk_verify. */
+static gcry_sexp_t
+read_sig_file (const char *fname)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ gcry_mpi_t tmpmpi;
+ gcry_sexp_t s_sig;
+
+ fp = fopen (fname, "rb");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+
+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL);
+ if (!err)
+ err = gcry_sexp_build (&s_sig, NULL,
+ "(sig-val(rsa(s %m)))", tmpmpi);
+ if (err)
+ die ("error building S-expression: %s\n", gpg_strerror (err));
+ gcry_mpi_release (tmpmpi);
+ gcry_free (buffer);
+
+ return s_sig;
+}
+
+
+/* Read an S-expression from FNAME. */
+static gcry_sexp_t
+read_sexp_from_file (const char *fname)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ gcry_sexp_t sexp;
+
+ fp = fopen (fname, "rb");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+ if (!buflen)
+ die ("error: file `%s' is empty\n", fname);
+
+ err = gcry_sexp_create (&sexp, buffer, buflen, 1, gcry_free);
+ if (err)
+ die ("error parsing `%s': %s\n", fname, gpg_strerror (err));
+
+ return sexp;
+}
+
+
+static void
+print_buffer (const void *buffer, size_t length)
+{
+ int writerr = 0;
+
+ if (base64_output)
+ {
+ static const unsigned char bintoasc[64+1] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+ const unsigned char *p;
+ unsigned char inbuf[4];
+ char outbuf[4];
+ int idx, quads;
+
+ idx = quads = 0;
+ for (p = buffer; length; p++, length--)
+ {
+ inbuf[idx++] = *p;
+ if (idx > 2)
+ {
+ outbuf[0] = bintoasc[(*inbuf>>2)&077];
+ outbuf[1] = bintoasc[(((*inbuf<<4)&060)
+ |((inbuf[1] >> 4)&017))&077];
+ outbuf[2] = bintoasc[(((inbuf[1]<<2)&074)
+ |((inbuf[2]>>6)&03))&077];
+ outbuf[3] = bintoasc[inbuf[2]&077];
+ if (fwrite (outbuf, 4, 1, stdout) != 1)
+ writerr = 1;
+ idx = 0;
+ if (++quads >= (64/4))
+ {
+ if (fwrite ("\n", 1, 1, stdout) != 1)
+ writerr = 1;
+ quads = 0;
+ }
+ }
+ }
+ if (idx)
+ {
+ outbuf[0] = bintoasc[(*inbuf>>2)&077];
+ if (idx == 1)
+ {
+ outbuf[1] = bintoasc[((*inbuf<<4)&060)&077];
+ outbuf[2] = outbuf[3] = '=';
+ }
+ else
+ {
+ outbuf[1] = bintoasc[(((*inbuf<<4)&060)
+ |((inbuf[1]>>4)&017))&077];
+ outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077];
+ outbuf[3] = '=';
+ }
+ if (fwrite (outbuf, 4, 1, stdout) != 1)
+ writerr = 1;
+ quads++;
+ }
+ if (quads && fwrite ("\n", 1, 1, stdout) != 1)
+ writerr = 1;
+ }
+ else if (binary_output)
+ {
+ if (fwrite (buffer, length, 1, stdout) != 1)
+ writerr++;
+ }
+ else
+ {
+ const unsigned char *p = buffer;
+
+ if (verbose > 1)
+ showhex ("sent line", buffer, length);
+ while (length-- && !ferror (stdout) )
+ printf ("%02X", *p++);
+ if (ferror (stdout))
+ writerr++;
+ }
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ {
+#ifndef HAVE_W32_SYSTEM
+ if (loop_mode && errno == EPIPE)
+ loop_mode = 0;
+ else
+#endif
+ die ("writing output failed: %s\n", strerror (errno));
+ }
+}
+
+
+/* Print an MPI on a line. */
+static void
+print_mpi_line (gcry_mpi_t a, int no_lz)
+{
+ unsigned char *buf, *p;
+ gcry_error_t err;
+ int writerr = 0;
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
+ if (err)
+ die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
+
+ p = buf;
+ if (no_lz && p[0] == '0' && p[1] == '0' && p[2])
+ p += 2;
+
+ printf ("%s\n", p);
+ if (ferror (stdout))
+ writerr++;
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ die ("writing output failed: %s\n", strerror (errno));
+ gcry_free (buf);
+}
+
+
+/* Print some data on hex format on a line. */
+static void
+print_data_line (const void *data, size_t datalen)
+{
+ const unsigned char *p = data;
+ int writerr = 0;
+
+ while (data && datalen-- && !ferror (stdout) )
+ printf ("%02X", *p++);
+ putchar ('\n');
+ if (ferror (stdout))
+ writerr++;
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ die ("writing output failed: %s\n", strerror (errno));
+}
+
+/* Print the S-expression A to the stream FP. */
+static void
+print_sexp (gcry_sexp_t a, FILE *fp)
+{
+ char *buf;
+ size_t size;
+
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = gcry_xmalloc (size);
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ if (fwrite (buf, size, 1, fp) != 1)
+ die ("error writing to stream: %s\n", strerror (errno));
+ gcry_free (buf);
+}
+
+
+
+
+static gcry_error_t
+init_external_rng_test (void **r_context,
+ unsigned int flags,
+ const void *key, size_t keylen,
+ const void *seed, size_t seedlen,
+ const void *dt, size_t dtlen)
+{
+ return gcry_control (PRIV_CTL_INIT_EXTRNG_TEST,
+ r_context, flags,
+ key, keylen,
+ seed, seedlen,
+ dt, dtlen);
+}
+
+static gcry_error_t
+run_external_rng_test (void *context, void *buffer, size_t buflen)
+{
+ return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen);
+}
+
+static void
+deinit_external_rng_test (void *context)
+{
+ xgcry_control ((PRIV_CTL_DEINIT_EXTRNG_TEST, context));
+}
+
+
+/* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm
+ identified and store the libgcrypt mode at R_MODE. Returns 0 on
+ error. */
+static int
+map_openssl_cipher_name (const char *name, int *r_mode)
+{
+ static struct {
+ const char *name;
+ int algo;
+ int mode;
+ } table[] =
+ {
+ { "bf-cbc", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
+ { "bf", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
+ { "bf-cfb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB },
+ { "bf-ecb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB },
+ { "bf-ofb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB },
+
+ { "cast-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
+ { "cast", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
+ { "cast5-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
+ { "cast5-cfb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
+ { "cast5-ecb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB },
+ { "cast5-ofb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
+
+ { "des-cbc", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
+ { "des", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
+ { "des-cfb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB },
+ { "des-ofb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB },
+ { "des-ecb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB },
+
+ { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
+ { "des-ede3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
+ { "des3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
+ { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
+ { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB },
+
+ { "rc4", GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM },
+
+ { "aes-128-cbc", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
+ { "aes-128", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
+ { "aes-128-cfb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
+ { "aes-128-ecb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
+ { "aes-128-ofb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
+
+ { "aes-192-cbc", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
+ { "aes-192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
+ { "aes-192-cfb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
+ { "aes-192-ecb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
+ { "aes-192-ofb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
+
+ { "aes-256-cbc", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
+ { "aes-256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
+ { "aes-256-cfb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
+ { "aes-256-ecb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
+ { "aes-256-ofb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
+
+ { NULL, 0 , 0 }
+ };
+ int idx;
+
+ for (idx=0; table[idx].name; idx++)
+ if (!strcmp (name, table[idx].name))
+ {
+ *r_mode = table[idx].mode;
+ return table[idx].algo;
+ }
+ *r_mode = 0;
+ return 0;
+}
+
+
+
+/* Run an encrypt or decryption operations. If DATA is NULL the
+ function reads its input in chunks of size DATALEN from fp and
+ processes it and writes it out until EOF. */
+static void
+run_encrypt_decrypt (int encrypt_mode,
+ int cipher_algo, int cipher_mode,
+ const void *iv_buffer, size_t iv_buflen,
+ const void *key_buffer, size_t key_buflen,
+ const void *data, size_t datalen, FILE *fp)
+{
+ gpg_error_t err;
+ gcry_cipher_hd_t hd;
+ void *outbuf;
+ size_t outbuflen;
+ void *inbuf;
+ size_t inbuflen;
+ size_t blocklen;
+
+ err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
+ if (err)
+ die ("gcry_cipher_open failed for algo %d, mode %d: %s\n",
+ cipher_algo, cipher_mode, gpg_strerror (err));
+
+ blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
+ assert (blocklen);
+
+ gcry_cipher_ctl (hd, PRIV_CIPHERCTL_DISABLE_WEAK_KEY, NULL, 0);
+
+ err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
+ if (err)
+ die ("gcry_cipher_setkey failed with keylen %u: %s\n",
+ (unsigned int)key_buflen, gpg_strerror (err));
+
+ if (iv_buffer)
+ {
+ err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
+ if (err)
+ die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
+ (unsigned int)iv_buflen, gpg_strerror (err));
+ }
+
+ inbuf = data? NULL : gcry_xmalloc (datalen);
+ outbuflen = datalen;
+ outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen);
+
+ do
+ {
+ if (inbuf)
+ {
+ int nread = fread (inbuf, 1, datalen, fp);
+ if (nread < (int)datalen && ferror (fp))
+ die ("error reading input\n");
+ data = inbuf;
+ inbuflen = nread;
+ }
+ else
+ inbuflen = datalen;
+
+ if (encrypt_mode)
+ err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
+ else
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
+ if (err)
+ die ("gcry_cipher_%scrypt failed: %s\n",
+ encrypt_mode? "en":"de", gpg_strerror (err));
+
+ print_buffer (outbuf, outbuflen);
+ }
+ while (inbuf);
+
+ gcry_cipher_close (hd);
+ gcry_free (outbuf);
+ gcry_free (inbuf);
+}
+
+
+static void
+get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen)
+{
+ unsigned char tmp[17];
+
+ if (gcry_cipher_ctl (hd, PRIV_CIPHERCTL_GET_INPUT_VECTOR, tmp, sizeof tmp))
+ die ("error getting current input vector\n");
+ if (buflen > *tmp)
+ die ("buffer too short to store the current input vector\n");
+ memcpy (buffer, tmp+1, *tmp);
+}
+
+/* Run the inner loop of the CAVS monte carlo test. */
+static void
+run_cipher_mct_loop (int encrypt_mode, int cipher_algo, int cipher_mode,
+ const void *iv_buffer, size_t iv_buflen,
+ const void *key_buffer, size_t key_buflen,
+ const void *data, size_t datalen, int iterations)
+{
+ gpg_error_t err;
+ gcry_cipher_hd_t hd;
+ size_t blocklen;
+ int count;
+ char input[16];
+ char output[16];
+ char last_output[16];
+ char last_last_output[16];
+ char last_iv[16];
+
+
+ err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
+ if (err)
+ die ("gcry_cipher_open failed for algo %d, mode %d: %s\n",
+ cipher_algo, cipher_mode, gpg_strerror (err));
+
+ blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
+ if (!blocklen || blocklen > sizeof output)
+ die ("invalid block length %d\n", (int)blocklen);
+
+
+ gcry_cipher_ctl (hd, PRIV_CIPHERCTL_DISABLE_WEAK_KEY, NULL, 0);
+
+ err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
+ if (err)
+ die ("gcry_cipher_setkey failed with keylen %u: %s\n",
+ (unsigned int)key_buflen, gpg_strerror (err));
+
+ if (iv_buffer)
+ {
+ err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
+ if (err)
+ die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
+ (unsigned int)iv_buflen, gpg_strerror (err));
+ }
+
+ if (datalen != blocklen)
+ die ("length of input (%u) does not match block length (%u)\n",
+ (unsigned int)datalen, (unsigned int)blocklen);
+ memcpy (input, data, datalen);
+ memset (output, 0, sizeof output);
+ for (count=0; count < iterations; count++)
+ {
+ memcpy (last_last_output, last_output, sizeof last_output);
+ memcpy (last_output, output, sizeof output);
+
+ get_current_iv (hd, last_iv, blocklen);
+
+ if (encrypt_mode)
+ err = gcry_cipher_encrypt (hd, output, blocklen, input, blocklen);
+ else
+ err = gcry_cipher_decrypt (hd, output, blocklen, input, blocklen);
+ if (err)
+ die ("gcry_cipher_%scrypt failed: %s\n",
+ encrypt_mode? "en":"de", gpg_strerror (err));
+
+
+ if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB
+ || cipher_mode == GCRY_CIPHER_MODE_CBC))
+ memcpy (input, last_iv, blocklen);
+ else if (cipher_mode == GCRY_CIPHER_MODE_OFB)
+ memcpy (input, last_iv, blocklen);
+ else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB)
+ {
+ /* Reconstruct the output vector. */
+ int i;
+ for (i=0; i < blocklen; i++)
+ input[i] ^= output[i];
+ }
+ else
+ memcpy (input, output, blocklen);
+ }
+
+ print_buffer (output, blocklen);
+ putchar ('\n');
+ print_buffer (last_output, blocklen);
+ putchar ('\n');
+ print_buffer (last_last_output, blocklen);
+ putchar ('\n');
+ get_current_iv (hd, last_iv, blocklen);
+ print_buffer (last_iv, blocklen); /* Last output vector. */
+ putchar ('\n');
+ print_buffer (input, blocklen); /* Next input text. */
+ putchar ('\n');
+ if (verbose > 1)
+ showhex ("sent line", "", 0);
+ putchar ('\n');
+ fflush (stdout);
+
+ gcry_cipher_close (hd);
+}
+
+
+
+/* Run a digest operation. */
+static void
+run_digest (int digest_algo, const void *data, size_t datalen)
+{
+ gpg_error_t err;
+ gcry_md_hd_t hd;
+ const unsigned char *digest;
+ unsigned int digestlen;
+
+ err = gcry_md_open (&hd, digest_algo, 0);
+ if (err)
+ die ("gcry_md_open failed for algo %d: %s\n",
+ digest_algo, gpg_strerror (err));
+
+ gcry_md_write (hd, data, datalen);
+ digest = gcry_md_read (hd, digest_algo);
+ digestlen = gcry_md_get_algo_dlen (digest_algo);
+ print_buffer (digest, digestlen);
+ gcry_md_close (hd);
+}
+
+
+/* Run a HMAC operation. */
+static void
+run_hmac (int digest_algo, const void *key, size_t keylen,
+ const void *data, size_t datalen)
+{
+ gpg_error_t err;
+ gcry_md_hd_t hd;
+ const unsigned char *digest;
+ unsigned int digestlen;
+
+ err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC);
+ if (err)
+ die ("gcry_md_open failed for HMAC algo %d: %s\n",
+ digest_algo, gpg_strerror (err));
+
+ gcry_md_setkey (hd, key, keylen);
+ if (err)
+ die ("gcry_md_setkey failed for HMAC algo %d: %s\n",
+ digest_algo, gpg_strerror (err));
+
+ gcry_md_write (hd, data, datalen);
+ digest = gcry_md_read (hd, digest_algo);
+ digestlen = gcry_md_get_algo_dlen (digest_algo);
+ print_buffer (digest, digestlen);
+ gcry_md_close (hd);
+}
+
+
+
+/* Derive an RSA key using the S-expression in (DATA,DATALEN). This
+ S-expression is used directly as input to gcry_pk_genkey. The
+ result is printed to stdout with one parameter per line in hex
+ format and in this order: p, q, n, d. */
+static void
+run_rsa_derive (const void *data, size_t datalen)
+{
+ gpg_error_t err;
+ gcry_sexp_t s_keyspec, s_key, s_top, l1;
+ gcry_mpi_t mpi;
+ const char *parmlist;
+ int idx;
+
+ if (!datalen)
+ err = gpg_error (GPG_ERR_NO_DATA);
+ else
+ err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
+ if (err)
+ die ("gcry_sexp_new failed for RSA key derive: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&s_key, s_keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (s_keyspec);
+
+ /* P and Q might have been swapped but we need to to return them in
+ the proper order. Build the parameter list accordingly. */
+ parmlist = "pqnd";
+ s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0);
+ if (s_top)
+ {
+ l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0);
+ if (l1)
+ parmlist = "qpnd";
+ gcry_sexp_release (l1);
+ gcry_sexp_release (s_top);
+ }
+
+ /* Parse and print the parameters. */
+ l1 = gcry_sexp_find_token (s_key, "private-key", 0);
+ s_top = gcry_sexp_find_token (l1, "rsa", 0);
+ gcry_sexp_release (l1);
+ if (!s_top)
+ die ("private-key part not found in result\n");
+
+ for (idx=0; parmlist[idx]; idx++)
+ {
+ l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
+ mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l1);
+ if (!mpi)
+ die ("parameter %c missing in private-key\n", parmlist[idx]);
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ }
+
+ gcry_sexp_release (s_top);
+ gcry_sexp_release (s_key);
+}
+
+
+/* Generate RSA key using the S-expression in (DATA,DATALEN). This
+ S-expression is used directly as input to gcry_pk_genkey. The
+ result is printed to stdout with one parameter per line in hex
+ format and in this order: e, p, q, n, d. */
+static void
+run_rsa_keygen (const void *data, size_t datalen, int test)
+{
+ gpg_error_t err;
+ gcry_sexp_t s_keyspec, s_key, s_top, l1;
+ gcry_mpi_t mpi;
+ const char *parmlist;
+ int idx;
+
+ if (!datalen)
+ err = gpg_error (GPG_ERR_NO_DATA);
+ else
+ err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
+ if (err)
+ die ("gcry_sexp_new failed for RSA key generation: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&s_key, s_keyspec);
+
+ gcry_sexp_release (s_keyspec);
+
+ if (test) {
+ if (err)
+ printf("F\n");
+ else {
+ gcry_sexp_release (s_key);
+ printf("P\n");
+ }
+ return;
+ }
+
+ if (err)
+ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
+
+ parmlist = "epqnd";
+
+ /* Parse and print the parameters. */
+ l1 = gcry_sexp_find_token (s_key, "private-key", 0);
+ s_top = gcry_sexp_find_token (l1, "rsa", 0);
+ gcry_sexp_release (l1);
+ if (!s_top)
+ die ("private-key part not found in result\n");
+
+ for (idx=0; parmlist[idx]; idx++)
+ {
+ l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
+ mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l1);
+ if (!mpi)
+ die ("parameter %c missing in private-key\n", parmlist[idx]);
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ }
+
+ gcry_sexp_release (s_top);
+ gcry_sexp_release (s_key);
+}
+
+
+
+static size_t
+compute_tag_length (size_t n)
+{
+ int needed = 0;
+
+ if (n < 128)
+ needed += 2; /* Tag and one length byte. */
+ else if (n < 256)
+ needed += 3; /* Tag, number of length bytes, 1 length byte. */
+ else if (n < 65536)
+ needed += 4; /* Tag, number of length bytes, 2 length bytes. */
+ else
+ die ("DER object too long to encode\n");
+
+ return needed;
+}
+
+static unsigned char *
+store_tag_length (unsigned char *p, int tag, size_t n)
+{
+ if (tag == TAG_SEQUENCE)
+ tag |= 0x20; /* constructed */
+
+ *p++ = tag;
+ if (n < 128)
+ *p++ = n;
+ else if (n < 256)
+ {
+ *p++ = 0x81;
+ *p++ = n;
+ }
+ else if (n < 65536)
+ {
+ *p++ = 0x82;
+ *p++ = n >> 8;
+ *p++ = n;
+ }
+
+ return p;
+}
+
+
+/* Generate an RSA key of size KEYSIZE using the public exponent
+ PUBEXP and print it to stdout in the OpenSSL format. The format
+ is:
+
+ SEQUENCE {
+ INTEGER (0) -- Unknown constant.
+ INTEGER -- n
+ INTEGER -- e
+ INTEGER -- d
+ INTEGER -- p
+ INTEGER -- q (with p < q)
+ INTEGER -- dmp1 = d mod (p-1)
+ INTEGER -- dmq1 = d mod (q-1)
+ INTEGER -- u = p^{-1} mod q
+ }
+
+*/
+static void
+run_rsa_gen (int keysize, int pubexp)
+{
+ gpg_error_t err;
+ gcry_sexp_t keyspec, key, l1;
+ const char keyelems[] = "nedpq..u";
+ gcry_mpi_t keyparms[8];
+ size_t keyparmslen[8];
+ int idx;
+ size_t derlen, needed, n;
+ unsigned char *derbuf, *der;
+
+ err = gcry_sexp_build (&keyspec, NULL,
+ "(genkey (rsa (nbits %d)(rsa-use-e %d)))",
+ keysize, pubexp);
+ if (err)
+ die ("gcry_sexp_build failed for RSA key generation: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (keyspec);
+
+ l1 = gcry_sexp_find_token (key, "private-key", 0);
+ if (!l1)
+ die ("private key not found in genkey result\n");
+ gcry_sexp_release (key);
+ key = l1;
+
+ l1 = gcry_sexp_find_token (key, "rsa", 0);
+ if (!l1)
+ die ("returned private key not formed as expected\n");
+ gcry_sexp_release (key);
+ key = l1;
+
+ /* Extract the parameters from the S-expression and store them in a
+ well defined order in KEYPARMS. */
+ for (idx=0; idx < DIM(keyparms); idx++)
+ {
+ if (keyelems[idx] == '.')
+ {
+ keyparms[idx] = gcry_mpi_new (0);
+ continue;
+ }
+ l1 = gcry_sexp_find_token (key, keyelems+idx, 1);
+ if (!l1)
+ die ("no %c parameter in returned private key\n", keyelems[idx]);
+ keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ if (!keyparms[idx])
+ die ("no value for %c parameter in returned private key\n",
+ keyelems[idx]);
+ gcry_sexp_release (l1);
+ }
+
+ gcry_sexp_release (key);
+
+ /* Check that p < q; if not swap p and q and recompute u. */
+ if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
+ {
+ gcry_mpi_swap (keyparms[3], keyparms[4]);
+ gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
+ }
+
+ /* Compute the additional parameters. */
+ gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1);
+ gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]);
+ gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1);
+ gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]);
+
+ /* Compute the length of the DER encoding. */
+ needed = compute_tag_length (1) + 1;
+ for (idx=0; idx < DIM(keyparms); idx++)
+ {
+ err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]);
+ if (err)
+ die ("error formatting parameter: %s\n", gpg_strerror (err));
+ keyparmslen[idx] = n;
+ needed += compute_tag_length (n) + n;
+ }
+
+ /* Store the key parameters. */
+ derlen = compute_tag_length (needed) + needed;
+ der = derbuf = gcry_xmalloc (derlen);
+
+ der = store_tag_length (der, TAG_SEQUENCE, needed);
+ der = store_tag_length (der, TAG_INTEGER, 1);
+ *der++ = 0;
+ for (idx=0; idx < DIM(keyparms); idx++)
+ {
+ der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]);
+ err = gcry_mpi_print (GCRYMPI_FMT_STD, der,
+ keyparmslen[idx], NULL, keyparms[idx]);
+ if (err)
+ die ("error formatting parameter: %s\n", gpg_strerror (err));
+ der += keyparmslen[idx];
+ }
+
+ /* Print the stuff. */
+ for (idx=0; idx < DIM(keyparms); idx++)
+ gcry_mpi_release (keyparms[idx]);
+
+ assert (der - derbuf == derlen);
+
+ if (base64_output)
+ puts ("-----BEGIN RSA PRIVATE KEY-----");
+ print_buffer (derbuf, derlen);
+ if (base64_output)
+ puts ("-----END RSA PRIVATE KEY-----");
+
+ gcry_free (derbuf);
+}
+
+
+
+/* Sign DATA of length DATALEN using the key taken from the PEM
+ encoded KEYFILE and the hash algorithm HASHALGO. */
+static void
+run_rsa_sign (const void *data, size_t datalen,
+ int hashalgo, int pkcs1, int pss, const char *keyfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig, s_tmp;
+ gcry_mpi_t sig_mpi = NULL;
+ unsigned char *outbuf;
+ size_t outlen;
+
+/* showhex ("D", data, datalen); */
+ if (pkcs1)
+ {
+ unsigned char hash[64];
+ unsigned int hashsize;
+
+ hashsize = gcry_md_get_algo_dlen (hashalgo);
+ if (!hashsize || hashsize > sizeof hash)
+ die ("digest too long for buffer or unknown hash algorithm\n");
+ gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags pkcs1)(hash %s %b))",
+ gcry_md_algo_name (hashalgo),
+ (int)hashsize, hash);
+ }
+ else if (pss)
+ {
+ unsigned char hash[64];
+ unsigned int hashsize;
+
+ hashsize = gcry_md_get_algo_dlen (hashalgo);
+ if (!hashsize || hashsize > sizeof hash)
+ die ("digest too long for buffer or unknown hash algorithm\n");
+ gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags pss)(salt-length #00#)(hash %s %b))",
+ gcry_md_algo_name (hashalgo),
+ (int)hashsize, hash);
+ }
+ else
+ {
+ gcry_mpi_t tmp;
+
+ err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(value %m))", tmp);
+ gcry_mpi_release (tmp);
+ }
+ }
+ if (err)
+ die ("gcry_sexp_build failed for RSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_key = read_private_key_file (keyfile, 0);
+
+ err = gcry_pk_sign (&s_sig, s_data, s_key);
+ if (err)
+ {
+ gcry_sexp_release (read_private_key_file (keyfile, 1));
+ die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
+ (int)datalen, keyfile, gpg_strerror (err));
+ }
+ gcry_sexp_release (s_key);
+ gcry_sexp_release (s_data);
+
+ s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+ if (s_tmp)
+ {
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0);
+ if (s_tmp)
+ {
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
+ if (s_tmp)
+ {
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG);
+ }
+ }
+ }
+ gcry_sexp_release (s_sig);
+
+ if (!sig_mpi)
+ die ("no value in returned S-expression\n");
+ err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi);
+ if (err)
+ die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
+ gcry_mpi_release (sig_mpi);
+
+ print_buffer (outbuf, outlen);
+ gcry_free (outbuf);
+}
+
+
+
+/* Verify DATA of length DATALEN using the public key taken from the
+ PEM encoded KEYFILE and the hash algorithm HASHALGO against the
+ binary signature in SIGFILE. */
+static void
+run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1,
+ int pss, const char *keyfile, const char *sigfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig;
+
+ if (pkcs1)
+ {
+ unsigned char hash[64];
+ unsigned int hashsize;
+
+ hashsize = gcry_md_get_algo_dlen (hashalgo);
+ if (!hashsize || hashsize > sizeof hash)
+ die ("digest too long for buffer or unknown hash algorithm\n");
+ gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags pkcs1)(hash %s %b))",
+ gcry_md_algo_name (hashalgo),
+ (int)hashsize, hash);
+ }
+ else if (pss)
+ {
+ unsigned char hash[64];
+ unsigned int hashsize;
+
+ hashsize = gcry_md_get_algo_dlen (hashalgo);
+ if (!hashsize || hashsize > sizeof hash)
+ die ("digest too long for buffer or unknown hash algorithm\n");
+ gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags pss)(salt-length #00#)(hash %s %b))",
+ gcry_md_algo_name (hashalgo),
+ (int)hashsize, hash);
+ }
+ else
+ {
+ gcry_mpi_t tmp;
+
+ err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(value %m))", tmp);
+ gcry_mpi_release (tmp);
+ }
+ }
+ if (err)
+ die ("gcry_sexp_build failed for RSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_key = read_public_key_file (keyfile, 0);
+
+ s_sig = read_sig_file (sigfile);
+
+ err = gcry_pk_verify (s_sig, s_data, s_key);
+ if (!err)
+ puts ("GOOD signature");
+ else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
+ puts ("BAD signature");
+ else
+ printf ("ERROR (%s)\n", gpg_strerror (err));
+
+ gcry_sexp_release (s_sig);
+ gcry_sexp_release (s_key);
+ gcry_sexp_release (s_data);
+}
+
+
+
+/* Generate a DSA key of size KEYSIZE and return the complete
+ S-expression. */
+static gcry_sexp_t
+dsa_gen (int keysize)
+{
+ gpg_error_t err;
+ gcry_sexp_t keyspec, key;
+
+ err = gcry_sexp_build (&keyspec, NULL,
+ "(genkey (dsa (nbits %d)(use-fips186-2)))",
+ keysize);
+ if (err)
+ die ("gcry_sexp_build failed for DSA key generation: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (keyspec);
+
+ return key;
+}
+
+
+/* Generate a DSA key of size KEYSIZE and return the complete
+ S-expression. */
+static gcry_sexp_t
+dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen)
+{
+ gpg_error_t err;
+ gcry_sexp_t keyspec, key;
+
+ err = gcry_sexp_build (&keyspec, NULL,
+ "(genkey"
+ " (dsa"
+ " (nbits %d)"
+ " (use-fips186-2)"
+ " (derive-parms"
+ " (seed %b))))",
+ keysize, (int)seedlen, seed);
+ if (err)
+ die ("gcry_sexp_build failed for DSA key generation: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (keyspec);
+
+ return key;
+}
+
+
+/* Generate an ECDSA key on the specified curve and return the complete
+ S-expression. */
+static gcry_sexp_t
+ecdsa_gen_key (const char *curve)
+{
+ gpg_error_t err;
+ gcry_sexp_t keyspec, key;
+
+ err = gcry_sexp_build (&keyspec, NULL,
+ "(genkey"
+ " (ecc"
+ " (use-fips186)"
+ " (curve %s)))",
+ curve);
+ if (err)
+ die ("gcry_sexp_build failed for ECDSA key generation: %s\n",
+ gpg_strerror (err));
+ err = gcry_pk_genkey (&key, keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for ECDSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (keyspec);
+
+ return key;
+}
+
+
+/* Print the domain parameter as well as the derive information. KEY
+ is the complete key as returned by dsa_gen. We print to stdout
+ with one parameter per line in hex format using this order: p, q,
+ g, seed, counter, h. */
+static void
+print_dsa_domain_parameters (gcry_sexp_t key)
+{
+ gcry_sexp_t l1, l2;
+ gcry_mpi_t mpi;
+ int idx;
+ const void *data;
+ size_t datalen;
+ char *string;
+
+ l1 = gcry_sexp_find_token (key, "public-key", 0);
+ if (!l1)
+ die ("public key not found in genkey result\n");
+
+ l2 = gcry_sexp_find_token (l1, "dsa", 0);
+ if (!l2)
+ die ("returned public key not formed as expected\n");
+ gcry_sexp_release (l1);
+ l1 = l2;
+
+ /* Extract the parameters from the S-expression and print them to stdout. */
+ for (idx=0; "pqg"[idx]; idx++)
+ {
+ l2 = gcry_sexp_find_token (l1, &"pqg"[idx], 1);
+ if (!l2)
+ die ("no %c parameter in returned public key\n", "pqg"[idx]);
+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!mpi)
+ die ("no value for %c parameter in returned public key\n","pqg"[idx]);
+ gcry_sexp_release (l2);
+ if (standalone_mode)
+ printf ("%c = ", "PQG"[idx]);
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ }
+ gcry_sexp_release (l1);
+
+ /* Extract the seed values. */
+ l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
+ if (!l1)
+ die ("misc-key-info not found in genkey result\n");
+
+ l2 = gcry_sexp_find_token (l1, "seed-values", 0);
+ if (!l2)
+ die ("no seed-values in returned key\n");
+ gcry_sexp_release (l1);
+ l1 = l2;
+
+ l2 = gcry_sexp_find_token (l1, "seed", 0);
+ if (!l2)
+ die ("no seed value in returned key\n");
+ data = gcry_sexp_nth_data (l2, 1, &datalen);
+ if (!data)
+ die ("no seed value in returned key\n");
+ if (standalone_mode)
+ printf ("Seed = ");
+ print_data_line (data, datalen);
+ gcry_sexp_release (l2);
+
+ l2 = gcry_sexp_find_token (l1, "counter", 0);
+ if (!l2)
+ die ("no counter value in returned key\n");
+ string = gcry_sexp_nth_string (l2, 1);
+ if (!string)
+ die ("no counter value in returned key\n");
+ if (standalone_mode)
+ printf ("c = %ld\n", strtoul (string, NULL, 10));
+ else
+ printf ("%lX\n", strtoul (string, NULL, 10));
+ gcry_free (string);
+ gcry_sexp_release (l2);
+
+ l2 = gcry_sexp_find_token (l1, "h", 0);
+ if (!l2)
+ die ("no n value in returned key\n");
+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!mpi)
+ die ("no h value in returned key\n");
+ if (standalone_mode)
+ printf ("H = ");
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ gcry_sexp_release (l2);
+
+ gcry_sexp_release (l1);
+}
+
+
+/* Print public key Q (in octet-string format) and private key d.
+ KEY is the complete key as returned by ecdsa_gen_key.
+ with one parameter per line in hex format using this order: d, Q. */
+static void
+print_ecdsa_dq (gcry_sexp_t key)
+{
+ gcry_sexp_t l1, l2;
+ gcry_mpi_t mpi;
+ int idx;
+
+ l1 = gcry_sexp_find_token (key, "private-key", 0);
+ if (!l1)
+ die ("private key not found in genkey result\n");
+
+ l2 = gcry_sexp_find_token (l1, "ecc", 0);
+ if (!l2)
+ die ("returned private key not formed as expected\n");
+ gcry_sexp_release (l1);
+ l1 = l2;
+
+ /* Extract the parameters from the S-expression and print them to stdout. */
+ for (idx=0; "dq"[idx]; idx++)
+ {
+ l2 = gcry_sexp_find_token (l1, &"dq"[idx], 1);
+ if (!l2)
+ die ("no %c parameter in returned public key\n", "dq"[idx]);
+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!mpi)
+ die ("no value for %c parameter in returned private key\n","dq"[idx]);
+ gcry_sexp_release (l2);
+ if (standalone_mode)
+ printf ("%c = ", "dQ"[idx]);
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ }
+
+ gcry_sexp_release (l1);
+}
+
+
+/* Generate DSA domain parameters for a modulus size of KEYSIZE. The
+ result is printed to stdout with one parameter per line in hex
+ format and in this order: p, q, g, seed, counter, h. If SEED is
+ not NULL this seed value will be used for the generation. */
+static void
+run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen)
+{
+ gcry_sexp_t key;
+
+ if (seed)
+ key = dsa_gen_with_seed (keysize, seed, seedlen);
+ else
+ key = dsa_gen (keysize);
+ print_dsa_domain_parameters (key);
+ gcry_sexp_release (key);
+}
+
+
+/* Generate a DSA key of size of KEYSIZE and write the private key to
+ FILENAME. Also write the parameters to stdout in the same way as
+ run_dsa_pqg_gen. */
+static void
+run_dsa_gen (int keysize, const char *filename)
+{
+ gcry_sexp_t key, private_key;
+ FILE *fp;
+
+ key = dsa_gen (keysize);
+ private_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!private_key)
+ die ("private key not found in genkey result\n");
+ print_dsa_domain_parameters (key);
+
+ fp = fopen (filename, "wb");
+ if (!fp)
+ die ("can't create `%s': %s\n", filename, strerror (errno));
+ print_sexp (private_key, fp);
+ fclose (fp);
+
+ gcry_sexp_release (private_key);
+ gcry_sexp_release (key);
+}
+
+
+
+/* Sign DATA of length DATALEN using the key taken from the S-expression
+ encoded KEYFILE. */
+static void
+run_dsa_sign (const void *data, size_t datalen, const char *keyfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2;
+ char hash[20];
+ gcry_mpi_t tmpmpi;
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen);
+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(value %m))", tmpmpi);
+ gcry_mpi_release (tmpmpi);
+ }
+ if (err)
+ die ("gcry_sexp_build failed for DSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_key = read_sexp_from_file (keyfile);
+
+ err = gcry_pk_sign (&s_sig, s_data, s_key);
+ if (err)
+ {
+ gcry_sexp_release (read_private_key_file (keyfile, 1));
+ die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
+ (int)datalen, keyfile, gpg_strerror (err));
+ }
+ gcry_sexp_release (s_data);
+
+ /* We need to return the Y parameter first. */
+ s_tmp = gcry_sexp_find_token (s_key, "private-key", 0);
+ if (!s_tmp)
+ die ("private key part not found in provided key\n");
+
+ s_tmp2 = gcry_sexp_find_token (s_tmp, "dsa", 0);
+ if (!s_tmp2)
+ die ("private key part is not a DSA key\n");
+ gcry_sexp_release (s_tmp);
+
+ s_tmp = gcry_sexp_find_token (s_tmp2, "y", 0);
+ tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+ if (!tmpmpi)
+ die ("no y parameter in DSA key\n");
+ print_mpi_line (tmpmpi, 1);
+ gcry_mpi_release (tmpmpi);
+ gcry_sexp_release (s_tmp);
+
+ gcry_sexp_release (s_key);
+
+
+ /* Now return the actual signature. */
+ s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+ if (!s_tmp)
+ die ("no sig-val element in returned S-expression\n");
+
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_sig, "dsa", 0);
+ if (!s_tmp)
+ die ("no dsa element in returned S-expression\n");
+
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+
+ s_tmp = gcry_sexp_find_token (s_sig, "r", 0);
+ tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+ if (!tmpmpi)
+ die ("no r parameter in returned S-expression\n");
+ print_mpi_line (tmpmpi, 1);
+ gcry_mpi_release (tmpmpi);
+ gcry_sexp_release (s_tmp);
+
+ s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
+ tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+ if (!tmpmpi)
+ die ("no s parameter in returned S-expression\n");
+ print_mpi_line (tmpmpi, 1);
+ gcry_mpi_release (tmpmpi);
+ gcry_sexp_release (s_tmp);
+
+ gcry_sexp_release (s_sig);
+}
+
+
+
+/* Verify DATA of length DATALEN using the public key taken from the
+ S-expression in KEYFILE against the S-expression formatted
+ signature in SIGFILE. */
+static void
+run_dsa_verify (const void *data, size_t datalen,
+ const char *keyfile, const char *sigfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig;
+ char hash[20];
+ gcry_mpi_t tmpmpi;
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen);
+ /* Note that we can't simply use %b with HASH to build the
+ S-expression, because that might yield a negative value. */
+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(value %m))", tmpmpi);
+ gcry_mpi_release (tmpmpi);
+ }
+ if (err)
+ die ("gcry_sexp_build failed for DSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_key = read_sexp_from_file (keyfile);
+ s_sig = read_sexp_from_file (sigfile);
+
+ err = gcry_pk_verify (s_sig, s_data, s_key);
+ if (!err)
+ puts ("GOOD signature");
+ else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
+ puts ("BAD signature");
+ else
+ printf ("ERROR (%s)\n", gpg_strerror (err));
+
+ gcry_sexp_release (s_sig);
+ gcry_sexp_release (s_key);
+ gcry_sexp_release (s_data);
+}
+
+
+
+/* Sign DATA of length DATALEN using the key taken from the S-expression
+ encoded KEYFILE. */
+static void
+run_ecdsa_sign (const void *data, size_t datalen,
+ const char *keyfile, const int algo)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig, s_tmp;
+ char hash[128];
+ gcry_mpi_t tmpmpi;
+
+ s_key = read_sexp_from_file (keyfile);
+
+ gcry_md_hash_buffer (algo, hash, data, datalen);
+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash,
+ gcry_md_get_algo_dlen(algo), NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(hash %s %M))",
+ gcry_md_algo_name(algo), tmpmpi);
+ gcry_mpi_release (tmpmpi);
+ }
+ if (err)
+ die ("gcry_sexp_build failed for ECDSA data input: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_sign (&s_sig, s_data, s_key);
+ if (err)
+ {
+ die ("gcry_pk_signed failed: %s\n", gpg_strerror (err));
+ }
+ gcry_sexp_release (s_data);
+ gcry_sexp_release (s_key);
+
+ /* Now return the actual signature. */
+ s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+ if (!s_tmp)
+ die ("no sig-val element in returned S-expression\n");
+
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_sig, "ecdsa", 0);
+ if (!s_tmp)
+ die ("no ecdsa element in returned S-expression\n");
+
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+
+ s_tmp = gcry_sexp_find_token (s_sig, "r", 0);
+ tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+ if (!tmpmpi)
+ die ("no r parameter in returned S-expression\n");
+ print_mpi_line (tmpmpi, 1);
+ gcry_mpi_release (tmpmpi);
+ gcry_sexp_release (s_tmp);
+
+ s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
+ tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+ if (!tmpmpi)
+ die ("no s parameter in returned S-expression\n");
+ print_mpi_line (tmpmpi, 1);
+ gcry_mpi_release (tmpmpi);
+ gcry_sexp_release (s_tmp);
+
+ gcry_sexp_release (s_sig);
+}
+
+
+
+/* Verify DATA of length DATALEN using the public key taken from the
+ S-expression in KEYFILE against the S-expression formatted
+ signature in SIGFILE. */
+static void
+run_ecdsa_verify (const void *data, size_t datalen,
+ const char *keyfile, const int algo, const char *sigfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig;
+ char hash[128];
+ gcry_mpi_t tmpmpi;
+
+ s_key = read_sexp_from_file (keyfile);
+
+ gcry_md_hash_buffer (algo, hash, data, datalen);
+ /* Note that we can't simply use %b with HASH to build the
+ S-expression, because that might yield a negative value. */
+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash,
+ gcry_md_get_algo_dlen(algo), NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(hash %s %M))",
+ gcry_md_algo_name(algo), tmpmpi);
+ gcry_mpi_release (tmpmpi);
+ }
+ if (err)
+ die ("gcry_sexp_build failed for DSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_sig = read_sexp_from_file (sigfile);
+
+ err = gcry_pk_verify (s_sig, s_data, s_key);
+ if (!err)
+ puts ("GOOD signature");
+ else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
+ puts ("BAD signature");
+ else
+ printf ("ERROR (%s)\n", gpg_strerror (err));
+
+ gcry_sexp_release (s_sig);
+ gcry_sexp_release (s_key);
+ gcry_sexp_release (s_data);
+}
+
+
+/* Generate an ECDSA key with specified domain parameters
+ and print the d and Q values, in the standard octet-string format. */
+static void
+run_ecdsa_gen_key (const char *curve)
+{
+ gcry_sexp_t key;
+
+ key = ecdsa_gen_key (curve);
+ print_ecdsa_dq (key);
+
+ gcry_sexp_release (key);
+}
+
+
+
+static void
+usage (int show_help)
+{
+ if (!show_help)
+ {
+ fputs ("usage: " PGM
+ " [OPTION] [FILE] (try --help for more information)\n", stderr);
+ exit (2);
+ }
+ fputs
+ ("Usage: " PGM " [OPTIONS] MODE [FILE]\n"
+ "Run a crypto operation using hex encoded input and output.\n"
+ "MODE:\n"
+ " encrypt, decrypt, digest, random, hmac-sha,\n"
+ " rsa-{derive,gen,sign,verify},\n"
+ " dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n"
+ "OPTIONS:\n"
+ " --verbose Print additional information\n"
+ " --binary Input and output is in binary form\n"
+ " --no-fips Do not force FIPS mode\n"
+ " --key KEY Use the hex encoded KEY\n"
+ " --iv IV Use the hex encoded IV\n"
+ " --dt DT Use the hex encoded DT for the RNG\n"
+ " --algo NAME Use algorithm NAME\n"
+ " --curve NAME Select ECC curve spec NAME\n"
+ " --keysize N Use a keysize of N bits\n"
+ " --signature NAME Take signature from file NAME\n"
+ " --chunk N Read in chunks of N bytes (implies --binary)\n"
+ " --pkcs1 Use PKCS#1 encoding\n"
+ " --pss Use PSS encoding with a zero length salt\n"
+ " --mct-server Run a monte carlo test server\n"
+ " --loop Enable random loop mode\n"
+ " --progress Print pogress indicators\n"
+ " --help Print this text\n"
+ "With no FILE, or when FILE is -, read standard input.\n"
+ "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
+ exit (0);
+}
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ gpg_error_t err;
+ int no_fips = 0;
+ int progress = 0;
+ int use_pkcs1 = 0;
+ int use_pss = 0;
+ const char *mode_string;
+ const char *curve_string = NULL;
+ const char *key_string = NULL;
+ const char *iv_string = NULL;
+ const char *dt_string = NULL;
+ const char *algo_string = NULL;
+ const char *keysize_string = NULL;
+ const char *signature_string = NULL;
+ FILE *input;
+ void *data;
+ size_t datalen;
+ size_t chunksize = 0;
+ int mct_server = 0;
+
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ usage (1);
+ }
+ else if (!strcmp (*argv, "--version"))
+ {
+ fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--binary"))
+ {
+ binary_input = binary_output = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--no-fips"))
+ {
+ no_fips++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--loop"))
+ {
+ loop_mode = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--progress"))
+ {
+ progress = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--key"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ key_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--iv"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ iv_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--dt"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ dt_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--algo"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ algo_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--keysize"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ keysize_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--signature"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ signature_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--chunk"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ chunksize = atoi (*argv);
+ binary_input = binary_output = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--curve"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ curve_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--pkcs1"))
+ {
+ use_pkcs1 = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--pss"))
+ {
+ use_pss = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--mct-server"))
+ {
+ mct_server = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--standalone"))
+ {
+ standalone_mode = 1;
+ argc--; argv++;
+ }
+ }
+
+ if (!argc || argc > 2)
+ usage (0);
+
+ mode_string = *argv;
+
+ if (use_pkcs1 && use_pss)
+ die ("Only one of --pkcs or --pss may be given\n");
+
+ if (!strcmp (mode_string, "rsa-derive"))
+ binary_input = 1;
+
+ if (argc == 2 && strcmp (argv[1], "-"))
+ {
+ input = fopen (argv[1], binary_input? "rb":"r");
+ if (!input)
+ die ("can't open `%s': %s\n", argv[1], strerror (errno));
+ }
+ else
+ input = stdin;
+
+#ifndef HAVE_W32_SYSTEM
+ if (loop_mode)
+ signal (SIGPIPE, SIG_IGN);
+#endif
+
+ if (verbose)
+ fprintf (stderr, PGM ": started (mode=%s)\n", mode_string);
+
+ xgcry_control ((GCRYCTL_SET_VERBOSITY, (int)verbose));
+ if (!no_fips)
+ xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+ if (!gcry_check_version ("1.4.3"))
+ die ("Libgcrypt is not sufficient enough\n");
+ if (verbose)
+ fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL));
+ if (no_fips)
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ /* Most operations need some input data. */
+ if (!chunksize
+ && !mct_server
+ && strcmp (mode_string, "random")
+ && strcmp (mode_string, "rsa-gen")
+ && strcmp (mode_string, "rsa-keygen")
+ && strcmp (mode_string, "rsa-keygen-kat")
+ && strcmp (mode_string, "dsa-gen")
+ && strcmp (mode_string, "ecdsa-gen-key") )
+ {
+ data = read_file (input, !binary_input, &datalen);
+ if (!data)
+ die ("error reading%s input\n", binary_input?"":" and decoding");
+ if (verbose)
+ fprintf (stderr, PGM ": %u bytes of input data\n",
+ (unsigned int)datalen);
+ }
+ else
+ {
+ data = NULL;
+ datalen = 0;
+ }
+
+
+ if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt"))
+ {
+ int cipher_algo, cipher_mode;
+ void *iv_buffer = NULL;
+ void *key_buffer = NULL;
+ size_t iv_buflen, key_buflen;
+
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode);
+ if (!cipher_algo)
+ die ("cipher algorithm `%s' is not supported\n", algo_string);
+ if (mct_server)
+ {
+ int iterations;
+
+ for (;;)
+ {
+ gcry_free (key_buffer); key_buffer = NULL;
+ gcry_free (iv_buffer); iv_buffer = NULL;
+ gcry_free (data); data = NULL;
+ if (!(key_buffer = read_textline (input)))
+ {
+ if (feof (input))
+ break;
+ die ("no version info in input\n");
+ }
+ if (atoi (key_buffer) != 1)
+ die ("unsupported input version %s\n",
+ (const char*)key_buffer);
+ gcry_free (key_buffer);
+ if (!(key_buffer = read_textline (input)))
+ die ("no iteration count in input\n");
+ iterations = atoi (key_buffer);
+ gcry_free (key_buffer);
+ if (!(key_buffer = read_hexline (input, &key_buflen)))
+ die ("no key in input\n");
+ if (!(iv_buffer = read_hexline (input, &iv_buflen)))
+ die ("no IV in input\n");
+ if (!(data = read_hexline (input, &datalen)))
+ die ("no data in input\n");
+ skip_to_empty_line (input);
+
+ run_cipher_mct_loop ((*mode_string == 'e'),
+ cipher_algo, cipher_mode,
+ iv_buffer, iv_buflen,
+ key_buffer, key_buflen,
+ data, datalen, iterations);
+ }
+ }
+ else
+ {
+ if (cipher_mode != GCRY_CIPHER_MODE_ECB)
+ {
+ if (!iv_string)
+ die ("option --iv is required in this mode\n");
+ iv_buffer = hex2buffer (iv_string, &iv_buflen);
+ if (!iv_buffer)
+ die ("invalid value for IV\n");
+ }
+ else
+ {
+ iv_buffer = NULL;
+ iv_buflen = 0;
+ }
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ key_buffer = hex2buffer (key_string, &key_buflen);
+ if (!key_buffer)
+ die ("invalid value for KEY\n");
+
+ run_encrypt_decrypt ((*mode_string == 'e'),
+ cipher_algo, cipher_mode,
+ iv_buffer, iv_buflen,
+ key_buffer, key_buflen,
+ data, data? datalen:chunksize, input);
+ }
+ gcry_free (key_buffer);
+ gcry_free (iv_buffer);
+ }
+ else if (!strcmp (mode_string, "digest"))
+ {
+ int algo;
+
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ algo = gcry_md_map_name (algo_string);
+ if (!algo)
+ die ("digest algorithm `%s' is not supported\n", algo_string);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+
+ run_digest (algo, data, datalen);
+ }
+ else if (!strcmp (mode_string, "random"))
+ {
+ void *context;
+ unsigned char key[16];
+ unsigned char seed[16];
+ unsigned char dt[16];
+ unsigned char buffer[16];
+ size_t count = 0;
+
+ if (!key_string || hex2bin (key_string, key, 16) < 0 )
+ die ("value for --key are not 32 hex digits\n");
+ if (!iv_string || hex2bin (iv_string, seed, 16) < 0 )
+ die ("value for --iv are not 32 hex digits\n");
+ if (!dt_string || hex2bin (dt_string, dt, 16) < 0 )
+ die ("value for --dt are not 32 hex digits\n");
+
+ /* The flag value 1 disables the dup check, so that the RNG
+ returns all generated data. */
+ err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16);
+ if (err)
+ die ("init external RNG test failed: %s\n", gpg_strerror (err));
+
+ do
+ {
+ err = run_external_rng_test (context, buffer, sizeof buffer);
+ if (err)
+ die ("running external RNG test failed: %s\n", gpg_strerror (err));
+ print_buffer (buffer, sizeof buffer);
+ if (progress)
+ {
+ if (!(++count % 1000))
+ fprintf (stderr, PGM ": %lu random bytes so far\n",
+ (unsigned long int)(count * sizeof buffer));
+ }
+ }
+ while (loop_mode);
+
+ if (progress)
+ fprintf (stderr, PGM ": %lu random bytes\n",
+ (unsigned long int)(count * sizeof buffer));
+
+ deinit_external_rng_test (context);
+ }
+ else if (!strcmp (mode_string, "hmac-sha"))
+ {
+ int algo;
+ void *key_buffer;
+ size_t key_buflen;
+
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ switch (atoi (algo_string))
+ {
+ case 1: algo = GCRY_MD_SHA1; break;
+ case 224: algo = GCRY_MD_SHA224; break;
+ case 256: algo = GCRY_MD_SHA256; break;
+ case 384: algo = GCRY_MD_SHA384; break;
+ case 512: algo = GCRY_MD_SHA512; break;
+ default: algo = 0; break;
+ }
+ if (!algo)
+ die ("no digest algorithm found for hmac type `%s'\n", algo_string);
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ key_buffer = hex2buffer (key_string, &key_buflen);
+ if (!key_buffer)
+ die ("invalid value for KEY\n");
+
+ run_hmac (algo, key_buffer, key_buflen, data, datalen);
+
+ gcry_free (key_buffer);
+ }
+ else if (!strcmp (mode_string, "rsa-derive"))
+ {
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ run_rsa_derive (data, datalen);
+ }
+ else if (!strcmp (mode_string, "rsa-keygen"))
+ {
+ data = read_file (input, 0, &datalen);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ run_rsa_keygen (data, datalen, 0);
+ }
+ else if (!strcmp (mode_string, "rsa-keygen-kat"))
+ {
+ data = read_file (input, 0, &datalen);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ run_rsa_keygen (data, datalen, 1);
+ }
+ else if (!strcmp (mode_string, "rsa-gen"))
+ {
+ int keysize;
+
+ if (!binary_output)
+ base64_output = 1;
+
+ keysize = keysize_string? atoi (keysize_string) : 0;
+ if (keysize < 128 || keysize > 16384)
+ die ("invalid keysize specified; needs to be 128 .. 16384\n");
+ run_rsa_gen (keysize, 65537);
+ }
+ else if (!strcmp (mode_string, "rsa-sign"))
+ {
+ int algo;
+
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ algo = gcry_md_map_name (algo_string);
+ if (!algo)
+ die ("digest algorithm `%s' is not supported\n", algo_string);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+
+ run_rsa_sign (data, datalen, algo, use_pkcs1, use_pss, key_string);
+
+ }
+ else if (!strcmp (mode_string, "rsa-verify"))
+ {
+ int algo;
+
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ algo = gcry_md_map_name (algo_string);
+ if (!algo)
+ die ("digest algorithm `%s' is not supported\n", algo_string);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ if (!signature_string)
+ die ("option --signature is required in this mode\n");
+ if (access (signature_string, R_OK))
+ die ("option --signature needs to specify an existing file\n");
+
+ run_rsa_verify (data, datalen, algo, use_pkcs1, use_pss, key_string,
+ signature_string);
+
+ }
+ else if (!strcmp (mode_string, "dsa-pqg-gen"))
+ {
+ int keysize;
+
+ keysize = keysize_string? atoi (keysize_string) : 0;
+ if (keysize < 1024 || keysize > 3072)
+ die ("invalid keysize specified; needs to be 1024 .. 3072\n");
+ run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen);
+ }
+ else if (!strcmp (mode_string, "dsa-gen"))
+ {
+ int keysize;
+
+ keysize = keysize_string? atoi (keysize_string) : 0;
+ if (keysize < 1024 || keysize > 3072)
+ die ("invalid keysize specified; needs to be 1024 .. 3072\n");
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ run_dsa_gen (keysize, key_string);
+ }
+ else if (!strcmp (mode_string, "dsa-sign"))
+ {
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+
+ run_dsa_sign (data, datalen, key_string);
+ }
+ else if (!strcmp (mode_string, "dsa-verify"))
+ {
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ if (!signature_string)
+ die ("option --signature is required in this mode\n");
+ if (access (signature_string, R_OK))
+ die ("option --signature needs to specify an existing file\n");
+
+ run_dsa_verify (data, datalen, key_string, signature_string);
+ }
+ else if (!strcmp (mode_string, "ecdsa-gen-key"))
+ {
+ if (!curve_string)
+ die ("option --curve containing name of the specified curve is required in this mode\n");
+ run_ecdsa_gen_key (curve_string);
+ }
+ else if (!strcmp (mode_string, "ecdsa-sign"))
+ {
+ int algo;
+
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!algo_string)
+ die ("use --algo to specify the digest algorithm\n");
+ algo = gcry_md_map_name (algo_string);
+ if (!algo)
+ die ("digest algorithm `%s' is not supported\n", algo_string);
+
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+
+ run_ecdsa_sign (data, datalen, key_string, algo);
+ }
+ else if (!strcmp (mode_string, "ecdsa-verify"))
+ {
+ int algo;
+
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!algo_string)
+ die ("use --algo to specify the digest algorithm\n");
+ algo = gcry_md_map_name (algo_string);
+ if (!algo)
+ die ("digest algorithm `%s' is not supported\n", algo_string);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ if (!signature_string)
+ die ("option --signature is required in this mode\n");
+ if (access (signature_string, R_OK))
+ die ("option --signature needs to specify an existing file\n");
+
+ run_ecdsa_verify (data, datalen, key_string, algo, signature_string);
+ }
+ else
+ usage (0);
+
+ gcry_free (data);
+
+ /* Because Libgcrypt does not enforce FIPS mode in all cases we let
+ the process die if Libgcrypt is not anymore in FIPS mode after
+ the actual operation. */
+ if (!no_fips && !gcry_fips_mode_active ())
+ die ("FIPS mode is not anymore active\n");
+
+ if (verbose)
+ fputs (PGM ": ready\n", stderr);
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/gchash.c b/comm/third_party/libgcrypt/tests/gchash.c
new file mode 100644
index 0000000000..43ce53ba3b
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/gchash.c
@@ -0,0 +1,123 @@
+/* gchash.c - Calculate hash values
+ * Copyright (C) 2013 Dmitry Eremin-Solenikov
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# undef _GCRYPT_IN_LIBGCRYPT
+# include "gcrypt.h"
+#else
+# include <gcrypt.h>
+#endif
+
+#define PGM "gchash"
+#include "t-common.h"
+
+
+void
+init_gcrypt (void)
+{
+ if (!gcry_check_version (GCRYPT_VERSION)) {
+ fputs ("libgcrypt version mismatch\n", stderr);
+ exit (2);
+ }
+
+ xgcry_control ((GCRYCTL_SUSPEND_SECMEM_WARN));
+
+ /* Allocate a pool of 16k secure memory. This make the secure memory
+ * available and also drops privileges where needed. */
+ xgcry_control ((GCRYCTL_INIT_SECMEM, 16384, 0));
+
+ xgcry_control ((GCRYCTL_RESUME_SECMEM_WARN));
+
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+}
+
+int
+main (int argc, char **argv)
+{
+ gcry_md_hd_t hd;
+ gcry_error_t err;
+ int algo;
+
+ init_gcrypt();
+
+ if (argc < 2 || (argv[1] && !strcmp(argv[1], "--help")))
+ {
+ fprintf (stderr, "Usage: %s <digest> <file>...\n", argv[0]);
+ return 1;
+ }
+
+ algo = gcry_md_map_name (argv[1]);
+ if (algo == GCRY_MD_NONE)
+ {
+ fprintf (stderr, "Unknown algorithm '%s'\n", argv[1]);
+ return 1;
+ }
+
+ err = gcry_md_open(&hd, algo, 0);
+ if (err)
+ {
+ fprintf (stderr, "LibGCrypt error %s/%s\n",
+ gcry_strsource (err),
+ gcry_strerror (err));
+ exit (1);
+ }
+
+ for (argv += 2; *argv; argv++)
+ {
+ FILE *fp;
+ unsigned char buf[1024];
+ size_t size;
+ int i;
+ unsigned char *h;
+ if (!strcmp (*argv, "-"))
+ fp = stdin;
+ else
+ fp = fopen (*argv, "r");
+
+ if (fp == NULL)
+ {
+ perror ("fopen");
+ return 1;
+ }
+
+ while (!feof (fp))
+ {
+ size = fread (buf, 1, sizeof(buf), fp);
+ gcry_md_write (hd, buf, size);
+ }
+
+ h = gcry_md_read(hd, 0);
+
+ for (i = 0; i < gcry_md_get_algo_dlen (algo); i++)
+ printf("%02x", h[i]);
+ printf(" %s\n", *argv);
+
+ gcry_md_reset(hd);
+ }
+
+ gcry_md_close(hd);
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/genhashdata.c b/comm/third_party/libgcrypt/tests/genhashdata.c
new file mode 100644
index 0000000000..138a534b16
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/genhashdata.c
@@ -0,0 +1,160 @@
+/* genhashdata.c - Create data for hash tests
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* Results:
+
+$ for i in -64 -1 0 1 64; do ./genhashdata --gigs 256 --bytes $i|sha1sum;done
+92fc51850c7b750e6e774b75f294f6979d4059f0 -
+4bddeeb4c08683f02d4944d93dbcb02ebab50134 -
+71b923afde1c8c040884c723a2e3335b333e64c6 -
+2d99f9b5b86e9c9c937104f4242bd6b8bc0927ef -
+a60dabe8d749f798b7ec3a684cc3eab487451482 -
+
+$ for i in -64 -1 0 1 64; do ./genhashdata --gigs 256 --bytes $i|sha224sum;done
+b5672b54d2480a5688a2dc727a1ad4db7a81ef31ce8999e0bbaeffdc -
+814ea7159473e6ffc1c64b90026a542e13ac6980f7f3ca3c4582a9b8 -
+9ec0e1829455db8650ec7a8b06912196f97a7358bc3a73c79911cd4e -
+e578d5d523320876565bbbc892511a485427caee6dd754d57e3e58c2 -
+ff0464df248cd298b63765bc4f87f21e25c93c657fdf3656d3c878e5 -
+
+$ for i in -64 -1 0 1 64; do ./genhashdata --gigs 256 --bytes $i|sha256sum;done
+87a9828d3de78d55d252341db2a622908c4e0ceaee9961ecf9768700fc799ec8 -
+823bf95f64ef04a4a77579c38760b1d401b56bf3a8e664bdf56ca15afb468a03 -
+2d0723878cb2c3d5c59dfad910cdb857f4430a6ba2a7d687938d7a20e63dde47 -
+5a2e21b1e79cd866acf53a2a18ca76bd4e02c4b01bf4627354171824c812d95f -
+34444808af8e9d995e67f9e155ed94bf55f195a51dc1d8a989e6bcf95511c8a2 -
+
+
+$ for i in -64 -1 0 1 64; do ./genhashdata --gigs 256 --bytes $i|sha512sum;done
+e01bf8140874bf240e8426cb2bcbc377cbed2e6037334116637149e1cd8cd462 \
+96828b71f32b9f002771d4cb51172ce578b73b7939221e4df655ecd08601e655 -
+4917ff94514b1757705c289fdc3e7d6ffcce5771b20ae237ebc03d2ec9eb435f \
+b7ce9f0e27272be8cced77a5edae1a01a0ad62b0a44169d88bbee45474a17734 -
+1e28e8b3c79f2f47da11f3c0b7da4e7981e7d932db6d17d528a31e191922edda \
+8fc4bb2df10ea876232db5a1c606bc41886e8b2c570a3e721221f60c8c7dc4ab -
+027d3324dd1cf127770ceb53681f4c70937c9bca4e3acd5fd76cb266c7d4527d \
+58140290a1822e8d60c4d3ae9725fb923183230d6dfd2d7d73c0d74a4757f34a -
+49920704ea9d6ee19f0742d6c868110fa3eda8ac09f026e9ef22cc731af53020 \
+de40eedef66cb1afd94c61e285fa9327e01336e804903740a9145ab1f065c2d5 -
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define PGM "genhashdata"
+#include "t-common.h"
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int gigs = 0;
+ int bytes = 0;
+ char pattern[1024];
+ int i, g;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: " PGM " [options]\n"
+ "Options:\n"
+ " --gigs N Emit N GiB of test bytes\n"
+ " --bytes DIFF Stop DIFF bytes earlier or later\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--gigs"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ gigs = atoi (*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--bytes"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ bytes = atoi (*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ }
+
+ if (gigs < 0 || gigs > 1024*1024)
+ die ("value for --gigs must be in the range 0 to %d", 1024*1024);
+ if (bytes < -1024 || bytes > 1024)
+ die ("value for --bytes must be in the range -1024 to 1024");
+ if (sizeof pattern != 1024)
+ die ("internal error");
+
+ if (argc > 1)
+ die ("arguments are not expected");
+
+ memset (pattern, 'a', sizeof pattern);
+
+ for (g=0; g < gigs; g++)
+ {
+ if (g + 1 == gigs && bytes < 0)
+ {
+ for (i = 0; i < 1024*1023; i++)
+ if (fwrite (pattern, sizeof pattern, 1, stdout) != 1)
+ die ("writing to stdout failed: %s", strerror (errno));
+ for (i = 0; i < 1023; i++)
+ if (fwrite (pattern, sizeof pattern, 1, stdout) != 1)
+ die ("writing to stdout failed: %s", strerror (errno));
+ if (fwrite (pattern, sizeof pattern + bytes, 1, stdout) != 1)
+ die ("writing to stdout failed: %s", strerror (errno));
+ }
+ else
+ {
+ for (i = 0; i < 1024*1024; i++)
+ if (fwrite (pattern, sizeof pattern, 1, stdout) != 1)
+ die ("writing to stdout failed: %s", strerror (errno));
+ }
+ }
+ if (bytes > 0)
+ if (fwrite (pattern, bytes, 1, stdout) != 1)
+ die ("writing to stdout failed: %s", strerror (errno));
+ if (fflush (stdout))
+ die ("writing to stdout failed: %s", strerror (errno));
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/hashtest-256g.in b/comm/third_party/libgcrypt/tests/hashtest-256g.in
new file mode 100755
index 0000000000..a52b86924b
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/hashtest-256g.in
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+algos="SHA1 SHA256 SHA512 SM3"
+
+test "@RUN_LARGE_DATA_TESTS@" = yes || exit 77
+echo " now running 256 GiB tests for $algos - this takes looong"
+exec ./hashtest@EXEEXT@ --gigs 256 $algos
diff --git a/comm/third_party/libgcrypt/tests/hashtest.c b/comm/third_party/libgcrypt/tests/hashtest.c
new file mode 100644
index 0000000000..4c9704f3fd
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/hashtest.c
@@ -0,0 +1,451 @@
+/* hashtest.c - Check the hash functions
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "../src/gcrypt-int.h"
+
+#include "stopwatch.h"
+
+#define PGM "hashtest"
+#include "t-common.h"
+
+static int missing_test_vectors;
+
+static struct {
+ int algo;
+ int gigs;
+ int bytes;
+ const char *hex;
+} testvectors[] = {
+ { GCRY_MD_SHA1, 256, -64, "92fc51850c7b750e6e774b75f294f6979d4059f0" },
+ { GCRY_MD_SHA1, 256, -1, "4bddeeb4c08683f02d4944d93dbcb02ebab50134" },
+ { GCRY_MD_SHA1, 256, -0, "71b923afde1c8c040884c723a2e3335b333e64c6" },
+ { GCRY_MD_SHA1, 256, 1, "2d99f9b5b86e9c9c937104f4242bd6b8bc0927ef" },
+ { GCRY_MD_SHA1, 256, 64, "a60dabe8d749f798b7ec3a684cc3eab487451482" },
+
+ { GCRY_MD_SHA224, 256, -64,
+ "b5672b54d2480a5688a2dc727a1ad4db7a81ef31ce8999e0bbaeffdc" },
+ { GCRY_MD_SHA224, 256, -1,
+ "814ea7159473e6ffc1c64b90026a542e13ac6980f7f3ca3c4582a9b8" },
+ { GCRY_MD_SHA224, 256, 0,
+ "9ec0e1829455db8650ec7a8b06912196f97a7358bc3a73c79911cd4e" },
+ { GCRY_MD_SHA224, 256, 1,
+ "e578d5d523320876565bbbc892511a485427caee6dd754d57e3e58c2" },
+ { GCRY_MD_SHA224, 256, 64,
+ "ff0464df248cd298b63765bc4f87f21e25c93c657fdf3656d3c878e5" },
+
+ { GCRY_MD_SHA256, 256, -64,
+ "87a9828d3de78d55d252341db2a622908c4e0ceaee9961ecf9768700fc799ec8" },
+ { GCRY_MD_SHA256, 256, -1,
+ "823bf95f64ef04a4a77579c38760b1d401b56bf3a8e664bdf56ca15afb468a03" },
+ { GCRY_MD_SHA256, 256, 0,
+ "2d0723878cb2c3d5c59dfad910cdb857f4430a6ba2a7d687938d7a20e63dde47" },
+ { GCRY_MD_SHA256, 256, 1,
+ "5a2e21b1e79cd866acf53a2a18ca76bd4e02c4b01bf4627354171824c812d95f" },
+ { GCRY_MD_SHA256, 256, 64,
+ "34444808af8e9d995e67f9e155ed94bf55f195a51dc1d8a989e6bcf95511c8a2" },
+
+ { GCRY_MD_SHA512, 256, -64,
+ "e01bf8140874bf240e8426cb2bcbc377cbed2e6037334116637149e1cd8cd462"
+ "96828b71f32b9f002771d4cb51172ce578b73b7939221e4df655ecd08601e655" },
+ { GCRY_MD_SHA512, 256, -1,
+ "4917ff94514b1757705c289fdc3e7d6ffcce5771b20ae237ebc03d2ec9eb435f"
+ "b7ce9f0e27272be8cced77a5edae1a01a0ad62b0a44169d88bbee45474a17734" },
+ { GCRY_MD_SHA512, 256, 0,
+ "1e28e8b3c79f2f47da11f3c0b7da4e7981e7d932db6d17d528a31e191922edda"
+ "8fc4bb2df10ea876232db5a1c606bc41886e8b2c570a3e721221f60c8c7dc4ab" },
+ { GCRY_MD_SHA512, 256, 1,
+ "027d3324dd1cf127770ceb53681f4c70937c9bca4e3acd5fd76cb266c7d4527d"
+ "58140290a1822e8d60c4d3ae9725fb923183230d6dfd2d7d73c0d74a4757f34a" },
+ { GCRY_MD_SHA512, 256, 64,
+ "49920704ea9d6ee19f0742d6c868110fa3eda8ac09f026e9ef22cc731af53020"
+ "de40eedef66cb1afd94c61e285fa9327e01336e804903740a9145ab1f065c2d5" },
+
+ { GCRY_MD_SHA3_512, 256, -64,
+ "c6e082b3db996dbe5f2c5709818a7f325ef4febd883d7e9c545c06bfa7225198"
+ "1ecf40103788913cd5a5bdf13246b952ded6651043684b24197eb23544882a97" },
+ { GCRY_MD_SHA3_512, 256, -1,
+ "d7bf28e8216bf7d3d0d3969e34078e94b98598e17b6f21f256379389e4eba8ee"
+ "74eb288774797263fec00bdfd357d132cea9e408be36b982f5a60ab56ad01613" },
+ { GCRY_MD_SHA3_512, 256, +0,
+ "c1270852ba7b1e1a3eaa777969b8a65be28c3894537c61eb8cd22b1df6af703d"
+ "b59939f6adadeb64317faece8167d4817e73daf73e28a5ccd26bebee0a35c322" },
+ { GCRY_MD_SHA3_512, 256, +1,
+ "8bdfeb3a1a9a1cdcef21172cbc5bb3b87c0d8f7111df0aaf7f1bc03ad4775bd6"
+ "a03e0a875c4e7d02d2230c213562c6a57be28d92eaf6e4bea4bc24690454c8ef" },
+ { GCRY_MD_SHA3_512, 256, +64,
+ "0c91b91665ceaf7af5102e0ed31aa4f050668ab3c57b1f4763946d567efe66b3"
+ "ab9a2016cf238dee5b44eae9f0cdfbf7b7a6eb1e759986273243dc35894706b6" },
+
+ { GCRY_MD_SM3, 256, -64,
+ "4ceb893abeb43965d4cac7626da9a4be895585b5b2f16f302626801308b1c02a" },
+ { GCRY_MD_SM3, 256, -1,
+ "825f01e4f2b6084136abc356fa1b343a9411d844a4dc1474293aad817cd2a48f" },
+ { GCRY_MD_SM3, 256, +0,
+ "d948a4025ac3ea0aa8989f43203411bd22ad17eaa5fd92ebdf9cabf869f1ba1b" },
+ { GCRY_MD_SM3, 256, +1,
+ "4f6d0e260299c1f286ef1dbb4638a0770979f266b6c007c55410ee6849cba2a8" },
+ { GCRY_MD_SM3, 256, +64,
+ "ed34869dbadd62e3bec1f511004d7bbfc9cafa965477cc48843b248293bbe867" },
+
+ { 0 }
+};
+
+
+static void
+showhex (const void *buffer, size_t buflen, const char *format, ...)
+{
+ va_list arg_ptr;
+ const unsigned char *s;
+
+ fprintf (stderr, "%s: ", PGM);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+
+ for (s=buffer; buflen; buflen--, s++)
+ fprintf (stderr, "%02x", *s);
+ putc ('\n', stderr);
+}
+
+
+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);
+}
+
+/* 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 returns NULL 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))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static void
+run_selftest (int algo)
+{
+ gpg_error_t err;
+ size_t n;
+
+ n = 1;
+ err = gcry_md_algo_info (algo, GCRYCTL_SELFTEST, NULL, &n);
+ if (err && gpg_err_code (err) != GPG_ERR_NOT_IMPLEMENTED)
+ fail ("extended selftest for %s (%d) failed: %s",
+ gcry_md_algo_name (algo), algo, gpg_strerror (err));
+ else if (err && verbose)
+ info ("extended selftest for %s (%d) not implemented",
+ gcry_md_algo_name (algo), algo);
+ else if (verbose)
+ info ("extended selftest for %s (%d) passed",
+ gcry_md_algo_name (algo), algo);
+}
+
+/* Compare DIGEST of length DIGESTLEN generated using ALGO and GIGS
+ plus BYTES with the test vector and print an error message if the
+ don't match. Return 0 on match. */
+static int
+cmp_digest (const unsigned char *digest, size_t digestlen,
+ int algo, int gigs, int bytes)
+{
+ int idx;
+ unsigned char *tv_digest;
+ size_t tv_digestlen = 0;
+
+ for (idx=0; testvectors[idx].algo; idx++)
+ {
+ if (testvectors[idx].algo == algo
+ && testvectors[idx].gigs == gigs
+ && testvectors[idx].bytes == bytes)
+ break;
+ }
+ if (!testvectors[idx].algo)
+ {
+ info ("%d GiB %+3d %-10s warning: %s",
+ gigs, bytes, gcry_md_algo_name (algo), "no test vector");
+ missing_test_vectors++;
+ return 1;
+ }
+
+ tv_digest = hex2buffer (testvectors[idx].hex, &tv_digestlen);
+ if (tv_digestlen != digestlen) /* Ooops. */
+ {
+ fail ("%d GiB %+3d %-10s error: %s",
+ gigs, bytes, gcry_md_algo_name (algo), "digest length mismatch");
+ xfree (tv_digest);
+ return 1;
+ }
+ if (memcmp (tv_digest, digest, tv_digestlen))
+ {
+ fail ("%d GiB %+3d %-10s error: %s",
+ gigs, bytes, gcry_md_algo_name (algo), "mismatch");
+ xfree (tv_digest);
+ return 1;
+ }
+ xfree (tv_digest);
+
+ return 0;
+}
+
+
+static void
+run_longtest (int algo, int gigs)
+{
+ gpg_error_t err;
+ gcry_md_hd_t hd;
+ gcry_md_hd_t hd_pre = NULL;
+ gcry_md_hd_t hd_pre2 = NULL;
+ gcry_md_hd_t hd_post = NULL;
+ gcry_md_hd_t hd_post2 = NULL;
+ char pattern[1024];
+ int i, g;
+ const unsigned char *digest;
+ unsigned int digestlen;
+
+ memset (pattern, 'a', sizeof pattern);
+
+ err = gcry_md_open (&hd, algo, 0);
+ if (err)
+ {
+ fail ("gcry_md_open failed for %s (%d): %s",
+ gcry_md_algo_name (algo), algo, gpg_strerror (err));
+ return;
+ }
+
+ digestlen = gcry_md_get_algo_dlen (algo);
+
+
+ for (g=0; g < gigs; g++)
+ {
+ if (g == gigs - 1)
+ {
+ for (i = 0; i < 1024*1023; i++)
+ gcry_md_write (hd, pattern, sizeof pattern);
+ for (i = 0; i < 1023; i++)
+ gcry_md_write (hd, pattern, sizeof pattern);
+ err = gcry_md_copy (&hd_pre, hd);
+ if (!err)
+ err = gcry_md_copy (&hd_pre2, hd);
+ if (err)
+ die ("gcry_md_copy failed for %s (%d): %s",
+ gcry_md_algo_name (algo), algo, gpg_strerror (err));
+ gcry_md_write (hd, pattern, sizeof pattern);
+ }
+ else
+ {
+ for (i = 0; i < 1024*1024; i++)
+ gcry_md_write (hd, pattern, sizeof pattern);
+ }
+ if (g && !(g % 16))
+ show_note ("%d GiB so far hashed with %s", g, gcry_md_algo_name (algo));
+ }
+ if (g >= 16)
+ show_note ("%d GiB hashed with %s", g, gcry_md_algo_name (algo));
+
+ err = gcry_md_copy (&hd_post, hd);
+ if (err)
+ die ("gcry_md_copy failed for %s (%d): %s",
+ gcry_md_algo_name (algo), algo, gpg_strerror (err));
+ err = gcry_md_copy (&hd_post2, hd);
+ if (err)
+ die ("gcry_md_copy failed for %s (%d): %s",
+ gcry_md_algo_name (algo), algo, gpg_strerror (err));
+
+ gcry_md_write (hd_pre2, pattern, sizeof pattern - 64);
+ gcry_md_write (hd_pre, pattern, sizeof pattern - 1);
+ gcry_md_write (hd_post, pattern, 1);
+ gcry_md_write (hd_post2, pattern, 64);
+
+ digest = gcry_md_read (hd_pre2, algo);
+ if (cmp_digest (digest, digestlen, algo, gigs, -64) || verbose)
+ showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+ gigs, -64, gcry_md_algo_name (algo));
+ digest = gcry_md_read (hd_pre, algo);
+ if (cmp_digest (digest, digestlen, algo, gigs, -1) || verbose)
+ showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+ gigs, -1, gcry_md_algo_name (algo));
+ digest = gcry_md_read (hd, algo);
+ if (cmp_digest (digest, digestlen, algo, gigs, 0) || verbose)
+ showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+ gigs, 0, gcry_md_algo_name (algo));
+ digest = gcry_md_read (hd_post, algo);
+ if (cmp_digest (digest, digestlen, algo, gigs, 1) || verbose)
+ showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+ gigs, 1, gcry_md_algo_name (algo));
+ digest = gcry_md_read (hd_post2, algo);
+ if (cmp_digest (digest, digestlen, algo, gigs, 64) || verbose)
+ showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+ gigs, 64, gcry_md_algo_name (algo));
+
+ gcry_md_close (hd);
+ gcry_md_close (hd_pre);
+ gcry_md_close (hd_pre2);
+ gcry_md_close (hd_post);
+ gcry_md_close (hd_post2);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int gigs = 0;
+ int algo = 0;
+ int idx;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: " PGM " [options] [algos]\n"
+ "Options:\n"
+ " --verbose print timings etc.\n"
+ " --debug flyswatter\n"
+ " --gigs N Run a test on N GiB\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--gigs"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ gigs = atoi (*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ }
+
+ if (gigs < 0 || gigs > 1024*1024)
+ die ("value for --gigs must be in the range 0 to %d", 1024*1024);
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ /* A quick check that all given algorithms are valid. */
+ for (idx=0; idx < argc; idx++)
+ {
+ algo = gcry_md_map_name (argv[idx]);
+ if (!algo)
+ fail ("invalid algorithm '%s'", argv[idx]);
+ }
+ if (error_count)
+ exit (1);
+
+ /* Start checking. */
+ start_timer ();
+ if (!argc)
+ {
+ for (algo=1; algo < 400; algo++)
+ if (!gcry_md_test_algo (algo))
+ {
+ if (!gigs)
+ run_selftest (algo);
+ else
+ run_longtest (algo, gigs);
+ }
+ }
+ else
+ {
+ for (idx=0; idx < argc; idx++)
+ {
+ algo = gcry_md_map_name (argv[idx]);
+ if (!algo)
+ die ("invalid algorithm '%s'", argv[idx]);
+
+ if (!gigs)
+ run_selftest (algo);
+ else
+ run_longtest (algo, gigs);
+ }
+ }
+ stop_timer ();
+
+ if (missing_test_vectors)
+ fail ("Some test vectors are missing");
+
+ if (verbose)
+ info ("All tests completed in %s. Errors: %d\n",
+ elapsed_time (1), error_count);
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/hmac.c b/comm/third_party/libgcrypt/tests/hmac.c
new file mode 100644
index 0000000000..2b4c0f9f92
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/hmac.c
@@ -0,0 +1,203 @@
+/* hmac.c - HMAC regression tests
+ * Copyright (C) 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#define PGM "hmac"
+#include "t-common.h"
+
+
+static void
+check_one_mac (int algo,
+ const void *key, size_t keylen,
+ const void *data, size_t datalen,
+ const char *expect)
+{
+ gcry_md_hd_t hd;
+ 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)
+ {
+ fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err));
+ return;
+ }
+
+ gcry_md_write (hd, data, datalen);
+
+ p = gcry_md_read (hd, 0);
+
+ 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, MAC does not match\n", algo);
+ }
+
+ gcry_md_close (hd);
+}
+
+static void
+check_hmac (void)
+{
+ unsigned char key[128];
+ int i, j;
+
+ if (verbose)
+ fprintf (stderr, "checking FIPS-198a, A.1\n");
+ for (i=0; i < 64; i++)
+ key[i] = i;
+ check_one_mac (GCRY_MD_SHA1, key, 64, "Sample #1", 9,
+ "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
+ "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
+
+ if (verbose)
+ fprintf (stderr, "checking FIPS-198a, A.2\n");
+ for (i=0, j=0x30; i < 20; i++)
+ key[i] = j++;
+ check_one_mac (GCRY_MD_SHA1, key, 20, "Sample #2", 9,
+ "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
+ "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24");
+
+ if (verbose)
+ fprintf (stderr, "checking FIPS-198a, A.3\n");
+ for (i=0, j=0x50; i < 100; i++)
+ key[i] = j++;
+ check_one_mac (GCRY_MD_SHA1, key, 100, "Sample #3", 9,
+ "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
+ "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa");
+
+ if (verbose)
+ fprintf (stderr, "checking FIPS-198a, A.4\n");
+ for (i=0, j=0x70; i < 49; i++)
+ key[i] = j++;
+ check_one_mac (GCRY_MD_SHA1, key, 49, "Sample #4", 9,
+ "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
+ "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26");
+
+}
+
+
+static void
+check_hmac_multi (void)
+{
+ gpg_error_t err;
+ unsigned char key[128];
+ const char msg[] = "Sample #1";
+ const char mac[] = ("\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
+ "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
+ gcry_buffer_t iov[4];
+ char digest[64];
+ int i;
+ int algo;
+ int maclen;
+
+ if (verbose)
+ fprintf (stderr, "checking HMAC using multiple buffers\n");
+ for (i=0; i < 64; i++)
+ key[i] = i;
+
+ memset (iov, 0, sizeof iov);
+ iov[0].data = key;
+ iov[0].len = 64;
+ iov[1].data = (void*)msg;
+ iov[1].off = 0;
+ iov[1].len = 3;
+ iov[2].data = (void*)msg;
+ iov[2].off = 3;
+ iov[2].len = 1;
+ iov[3].data = (void*)msg;
+ iov[3].off = 4;
+ iov[3].len = 5;
+
+ algo = GCRY_MD_SHA1;
+ maclen = gcry_md_get_algo_dlen (algo);
+ err = gcry_md_hash_buffers (algo, GCRY_MD_FLAG_HMAC, digest, iov, 4);
+ if (err)
+ {
+ fail ("gcry_md_hash_buffers failed for algo %d: %s\n",
+ algo, gpg_strerror (err));
+ return;
+ }
+
+ if (memcmp (digest, mac, maclen))
+ {
+ printf ("computed: ");
+ for (i = 0; i < maclen; i++)
+ printf ("%02x ", digest[i] & 0xFF);
+ printf ("\nexpected: ");
+ for (i = 0; i < maclen; i++)
+ printf ("%02x ", mac[i] & 0xFF);
+ printf ("\n");
+
+ fail ("gcry_md_hash_buffers, algo %d, MAC does not match\n", algo);
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ check_hmac ();
+ check_hmac_multi ();
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/keygen.c b/comm/third_party/libgcrypt/tests/keygen.c
new file mode 100644
index 0000000000..4e7dfd35d0
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/keygen.c
@@ -0,0 +1,787 @@
+/* keygen.c - key generation regression tests
+ * Copyright (C) 2003, 2005, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2015 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "../src/gcrypt-int.h"
+
+
+#define PGM "keygen"
+#include "t-common.h"
+
+static int in_fips_mode;
+
+
+/* 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_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ fprintf (stderr, "%s: ", PGM);
+ if (prefix)
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = xmalloc (size);
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+ gcry_free (buf);
+}
+
+
+static void
+show_mpi (const char *prefix, gcry_mpi_t a)
+{
+ char *buf;
+ void *bufaddr = &buf;
+ gcry_error_t rc;
+
+ fprintf (stderr, "%s: ", PGM);
+ if (prefix)
+ fputs (prefix, stderr);
+ rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+ if (rc)
+ fprintf (stderr, "[error printing number: %s]\n", gpg_strerror (rc));
+ else
+ {
+ fprintf (stderr, "%s\n", buf);
+ gcry_free (buf);
+ }
+}
+
+
+static void
+check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e)
+{
+ gcry_sexp_t skey, pkey, list;
+
+ pkey = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pkey)
+ fail ("public part missing in return value\n");
+ else
+ {
+ gcry_mpi_t e = NULL;
+
+ list = gcry_sexp_find_token (pkey, "e", 0);
+ if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) )
+ fail ("public exponent not found\n");
+ else if (!expected_e)
+ {
+ if (verbose)
+ show_mpi ("public exponent: ", e);
+ }
+ else if ( gcry_mpi_cmp_ui (e, expected_e))
+ {
+ show_mpi ("public exponent: ", e);
+ fail ("public exponent is not %lu\n", expected_e);
+ }
+ gcry_sexp_release (list);
+ gcry_mpi_release (e);
+ gcry_sexp_release (pkey);
+ }
+
+ skey = gcry_sexp_find_token (key, "private-key", 0);
+ if (!skey)
+ fail ("private part missing in return value\n");
+ else
+ {
+ int rc = gcry_pk_testkey (skey);
+ if (rc)
+ fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
+ gcry_sexp_release (skey);
+ }
+}
+
+
+static void
+check_rsa_keys (void)
+{
+ gcry_sexp_t keyparm, key;
+ int rc;
+
+ if (verbose)
+ info ("creating 2048 bit RSA key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:2048)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+ if (verbose)
+ info ("creating 1024 bit RSA key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1024)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+
+ gcry_sexp_release (key);
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ fail ("error generating RSA key: %s\n", gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ fail ("generating 1024 bit RSA key must not work!");
+
+ if (!rc)
+ {
+ if (verbose > 1)
+ show_sexp ("1024 bit RSA key:\n", key);
+ check_generated_rsa_key (key, 65537);
+ }
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating 2048 bit RSA key with e=65539\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:2048)\n"
+ " (rsa-use-e 5:65539)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ fail ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+ if (!rc)
+ check_generated_rsa_key (key, 65539);
+ gcry_sexp_release (key);
+
+
+ if (verbose)
+ info ("creating 512 bit RSA key with e=257\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 3:512)\n"
+ " (rsa-use-e 3:257)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ fail ("error generating RSA key: %s\n", gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ fail ("generating 512 bit RSA key must not work!");
+
+ if (verbose && rc && in_fips_mode)
+ info ("... correctly rejected key creation in FIPS mode (%s)\n",
+ gpg_strerror (rc));
+
+ if (!rc)
+ check_generated_rsa_key (key, 257);
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating 512 bit RSA key with default e\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 3:512)\n"
+ " (rsa-use-e 1:0)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ fail ("error generating RSA key: %s\n", gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ fail ("generating 512 bit RSA key must not work!");
+
+ if (verbose && rc && in_fips_mode)
+ info ("... correctly rejected key creation in FIPS mode (%s)\n",
+ gpg_strerror (rc));
+
+
+ if (!rc)
+ check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
+ gcry_sexp_release (key);
+}
+
+
+static void
+check_elg_keys (void)
+{
+ gcry_sexp_t keyparm, key;
+ int rc;
+
+ if (verbose)
+ info ("creating 1024 bit Elgamal key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (elg\n"
+ " (nbits 4:1024)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating Elgamal key: %s\n", gpg_strerror (rc));
+ if (verbose > 1)
+ show_sexp ("1024 bit Elgamal key:\n", key);
+ gcry_sexp_release (key);
+}
+
+
+static void
+check_dsa_keys (void)
+{
+ gcry_sexp_t keyparm, key;
+ int rc;
+ int i;
+
+ /* Check that DSA generation works and that it can grok the qbits
+ argument. */
+ if (verbose)
+ info ("creating 5 1024 bit DSA keys\n");
+ for (i=0; i < 5; i++)
+ {
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (dsa\n"
+ " (nbits 4:1024)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ die ("error generating DSA key: %s\n", gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ die ("generating 1024 bit DSA key must not work!");
+ if (!i && verbose > 1)
+ show_sexp ("1024 bit DSA key:\n", key);
+ gcry_sexp_release (key);
+ }
+
+ if (verbose)
+ info ("creating 1536 bit DSA key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (dsa\n"
+ " (nbits 4:1536)\n"
+ " (qbits 3:224)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ die ("error generating DSA key: %s\n", gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ die ("generating 1536 bit DSA key must not work!");
+ if (verbose > 1)
+ show_sexp ("1536 bit DSA key:\n", key);
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating 3072 bit DSA key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (dsa\n"
+ " (nbits 4:3072)\n"
+ " (qbits 3:256)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating DSA key: %s\n", gpg_strerror (rc));
+ if (verbose > 1)
+ show_sexp ("3072 bit DSA key:\n", key);
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating 2048/256 bit DSA key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (dsa\n"
+ " (nbits 4:2048)\n"
+ " (qbits 3:256)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating DSA key: %s\n", gpg_strerror (rc));
+ if (verbose > 1)
+ show_sexp ("2048 bit DSA key:\n", key);
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating 2048/224 bit DSA key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (dsa\n"
+ " (nbits 4:2048)\n"
+ " (qbits 3:224)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating DSA key: %s\n", gpg_strerror (rc));
+ if (verbose > 1)
+ show_sexp ("2048 bit DSA key:\n", key);
+ gcry_sexp_release (key);
+}
+
+
+static void
+check_generated_ecc_key (gcry_sexp_t key)
+{
+ gcry_sexp_t skey, pkey;
+
+ pkey = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pkey)
+ fail ("public part missing in return value\n");
+ else
+ {
+ /* Fixme: Check more stuff. */
+ gcry_sexp_release (pkey);
+ }
+
+ skey = gcry_sexp_find_token (key, "private-key", 0);
+ if (!skey)
+ fail ("private part missing in return value\n");
+ else
+ {
+ int rc = gcry_pk_testkey (skey);
+ if (rc)
+ fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
+ gcry_sexp_release (skey);
+ }
+
+ /* Finally check that gcry_pk_testkey also works on the entire
+ S-expression. */
+ {
+ int rc = gcry_pk_testkey (key);
+ if (rc)
+ fail ("gcry_pk_testkey failed on key pair: %s\n", gpg_strerror (rc));
+ }
+}
+
+
+static void
+check_ecc_keys (void)
+{
+ const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256",
+ "Ed25519", NULL };
+ int testno;
+ gcry_sexp_t keyparm, key;
+ int rc;
+
+ for (testno=0; curves[testno]; testno++)
+ {
+ if (verbose)
+ info ("creating ECC key using curve %s\n", curves[testno]);
+ if (!strcmp (curves[testno], "Ed25519"))
+ {
+ /* Ed25519 isn't allowed in fips mode */
+ if (in_fips_mode)
+ continue;
+ rc = gcry_sexp_build (&keyparm, NULL,
+ "(genkey(ecc(curve %s)(flags param eddsa)))",
+ curves[testno]);
+ }
+ else
+ rc = gcry_sexp_build (&keyparm, NULL,
+ "(genkey(ecc(curve %s)(flags param)))",
+ curves[testno]);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating ECC key using curve %s: %s\n",
+ curves[testno], gpg_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("ECC key:\n", key);
+
+ check_generated_ecc_key (key);
+
+ gcry_sexp_release (key);
+ }
+
+ if (verbose)
+ info ("creating ECC key using curve Ed25519 for ECDSA\n");
+ rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve Ed25519)))");
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
+ gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ fail ("generating Ed25519 key must not work!");
+
+ if (verbose && rc && in_fips_mode)
+ info ("... correctly rejected key creation in FIPS mode (%s)\n",
+ gpg_strerror (rc));
+
+ if (!rc)
+ {
+ if (verbose > 1)
+ show_sexp ("ECC key:\n", key);
+
+ check_generated_ecc_key (key);
+ }
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
+ rc = gcry_sexp_build (&keyparm, NULL,
+ "(genkey(ecc(curve Ed25519)(flags nocomp)))");
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ die ("error generating ECC key using curve Ed25519 for ECDSA"
+ " (nocomp): %s\n",
+ gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ fail ("generating Ed25519 key must not work in FIPS mode!");
+
+ if (verbose && rc && in_fips_mode)
+ info ("... correctly rejected key creation in FIPS mode (%s)\n",
+ gpg_strerror (rc));
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating ECC key using curve NIST P-384 for ECDSA\n");
+
+ /* Must be specified as nistp384 (one word), because ecc_generate
+ * uses _gcry_sexp_nth_string which takes the first word of the name
+ * and thus libgcrypt can't find it later in its curves table. */
+ rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve nistp384)))");
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating ECC key using curve NIST P-384 for ECDSA: %s\n",
+ gpg_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("ECC key:\n", key);
+
+ check_generated_ecc_key (key);
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating ECC key using curve NIST P-384 for ECDSA (nocomp)\n");
+ rc = gcry_sexp_build (&keyparm, NULL,
+ "(genkey(ecc(curve nistp384)(flags nocomp)))");
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating ECC key using curve NIST P-384 for ECDSA"
+ " (nocomp): %s\n",
+ gpg_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("ECC key:\n", key);
+
+ check_generated_ecc_key (key);
+ gcry_sexp_release (key);
+
+
+ if (verbose)
+ info ("creating ECC key using curve Ed25519 for ECDSA (transient-key)\n");
+ rc = gcry_sexp_build (&keyparm, NULL,
+ "(genkey(ecc(curve Ed25519)(flags transient-key)))");
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ die ("error generating ECC key using curve Ed25519 for ECDSA"
+ " (transient-key): %s\n",
+ gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ fail ("generating Ed25519 key must not work in FIPS mode!");
+
+ if (verbose && rc && in_fips_mode)
+ info ("... correctly rejected key creation in FIPS mode (%s)\n",
+ gpg_strerror (rc));
+
+ if (!rc)
+ {
+ if (verbose > 1)
+ show_sexp ("ECC key:\n", key);
+ check_generated_ecc_key (key);
+ }
+ gcry_sexp_release (key);
+
+ if (verbose)
+ info ("creating ECC key using curve Ed25519 for ECDSA "
+ "(transient-key no-keytest)\n");
+ rc = gcry_sexp_build (&keyparm, NULL,
+ "(genkey(ecc(curve Ed25519)"
+ "(flags transient-key no-keytest)))");
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc && !in_fips_mode)
+ die ("error generating ECC key using curve Ed25519 for ECDSA"
+ " (transient-key no-keytest): %s\n",
+ gpg_strerror (rc));
+ else if (!rc && in_fips_mode)
+ fail ("generating Ed25519 key must not work in FIPS mode!");
+
+ if (verbose && rc && in_fips_mode)
+ info ("... correctly rejected key creation in FIPS mode (%s)\n",
+ gpg_strerror (rc));
+
+ if (!rc)
+ {
+ if (verbose > 1)
+ show_sexp ("ECC key:\n", key);
+ check_generated_ecc_key (key);
+ }
+ gcry_sexp_release (key);
+}
+
+
+static void
+check_nonce (void)
+{
+ char a[32], b[32];
+ int i,j;
+ int oops=0;
+
+ if (verbose)
+ info ("checking gcry_create_nonce\n");
+
+ gcry_create_nonce (a, sizeof a);
+ for (i=0; i < 10; i++)
+ {
+ gcry_create_nonce (b, sizeof b);
+ if (!memcmp (a, b, sizeof a))
+ die ("identical nonce found\n");
+ }
+ for (i=0; i < 10; i++)
+ {
+ gcry_create_nonce (a, sizeof a);
+ if (!memcmp (a, b, sizeof a))
+ die ("identical nonce found\n");
+ }
+
+ again:
+ for (i=1,j=0; i < sizeof a; i++)
+ if (a[0] == a[i])
+ j++;
+ if (j+1 == sizeof (a))
+ {
+ if (oops)
+ die ("impossible nonce found\n");
+ oops++;
+ gcry_create_nonce (a, sizeof a);
+ goto again;
+ }
+}
+
+
+static void
+progress_cb (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 ( "<LF>", stdout);
+ else
+ putchar (printchar);
+ fflush (stdout);
+}
+
+
+static void
+usage (int mode)
+{
+ fputs ("usage: " PGM " [options] [{rsa|elg|dsa|ecc|nonce}]\n"
+ "Options:\n"
+ " --verbose be verbose\n"
+ " --debug flyswatter\n"
+ " --fips run in FIPS mode\n"
+ " --no-quick To not use the quick RNG hack\n"
+ " --progress print progress indicators\n",
+ mode? stderr : stdout);
+ if (mode)
+ exit (1);
+}
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int opt_fips = 0;
+ int with_progress = 0;
+ int no_quick = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ usage (0);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--fips"))
+ {
+ argc--; argv++;
+ opt_fips = 1;
+ }
+ else if (!strcmp (*argv, "--progress"))
+ {
+ argc--; argv++;
+ with_progress = 1;
+ }
+ else if (!strcmp (*argv, "--no-quick"))
+ {
+ argc--; argv++;
+ no_quick = 1;
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ else
+ break;
+ }
+
+ xgcry_control ((GCRYCTL_SET_VERBOSITY, (int)verbose));
+ if (opt_fips)
+ xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ if (!opt_fips)
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+
+ 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. */
+ if (!no_quick)
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ if (with_progress)
+ gcry_set_progress_handler (progress_cb, NULL);
+
+ if ( gcry_fips_mode_active () )
+ in_fips_mode = 1;
+
+ if (opt_fips && !in_fips_mode)
+ die ("failed to switch into FIPS mode\n");
+
+ if (!argc)
+ {
+ check_rsa_keys ();
+ check_elg_keys ();
+ check_dsa_keys ();
+ check_ecc_keys ();
+ check_nonce ();
+ }
+ else
+ {
+ for (; argc; argc--, argv++)
+ if (!strcmp (*argv, "rsa"))
+ check_rsa_keys ();
+ else if (!strcmp (*argv, "elg"))
+ check_elg_keys ();
+ else if (!strcmp (*argv, "dsa"))
+ check_dsa_keys ();
+ else if (!strcmp (*argv, "ecc"))
+ check_ecc_keys ();
+ else if (!strcmp (*argv, "nonce"))
+ check_nonce ();
+ else
+ usage (1);
+ }
+
+ return error_count? 1:0;
+}
diff --git a/comm/third_party/libgcrypt/tests/keygrip.c b/comm/third_party/libgcrypt/tests/keygrip.c
new file mode 100644
index 0000000000..56fbba80b0
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/keygrip.c
@@ -0,0 +1,341 @@
+/* keygrip.c - verifies that keygrips are calculated as expected
+ * Copyright (C) 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#define PGM "keygrip"
+#include "t-common.h"
+
+static int repetitions;
+
+
+
+static void
+print_hex (const char *text, const void *buf, size_t n)
+{
+ const unsigned char *p = buf;
+
+ fputs (text, stdout);
+ for (; n; n--, p++)
+ printf ("%02X", *p);
+ putchar ('\n');
+}
+
+
+
+
+static struct
+{
+ int algo;
+ const char *key;
+ const unsigned char grip[20];
+} key_grips[] =
+ {
+ {
+ GCRY_PK_RSA,
+ "(private-key"
+ " (rsa"
+ " (n #00B6B509596A9ECABC939212F891E656A626BA07DA8521A9CAD4C08E640C04052FBB87F424EF1A0275A48A9299AC9DB69ABE3D0124E6C756B1F7DFB9B842D6251AEA6EE85390495CADA73D671537FCE5850A932F32BAB60AB1AC1F852C1F83C625E7A7D70CDA9EF16D5C8E47739D77DF59261ABE8454807FF441E143FBD37F8545#)"
+ " (e #010001#)"
+ " (d #077AD3DE284245F4806A1B82B79E616FBDE821C82D691A65665E57B5FAD3F34E67F401E7BD2E28699E89D9C496CF821945AE83AC7A1231176A196BA6027E77D85789055D50404A7A2A95B1512F91F190BBAEF730ED550D227D512F89C0CDB31AC06FA9A19503DDF6B66D0B42B9691BFD6140EC1720FFC48AE00C34796DC899E5#)"
+ " (p #00D586C78E5F1B4BF2E7CD7A04CA091911706F19788B93E44EE20AAF462E8363E98A72253ED845CCBF2481BB351E8557C85BCFFF0DABDBFF8E26A79A0938096F27#)"
+ " (q #00DB0CDF60F26F2A296C88D6BF9F8E5BE45C0DDD713C96CC73EBCB48B061740943F21D2A93D6E42A7211E7F02A95DCED6C390A67AD21ECF739AE8A0CA46FF2EBB3#)"
+ " (u #33149195F16912DB20A48D020DBC3B9E3881B39D722BF79378F6340F43148A6E9FC5F53E2853B7387BA4443BA53A52FCA8173DE6E85B42F9783D4A7817D0680B#)))",
+ "\x32\xCF\xFA\x85\xB1\x79\x1F\xBB\x26\x14\xE9\x1A\xFD\xF3\xAF\xE3\x32\x08\x2E\x25"
+ },
+ {
+ GCRY_PK_DSA,
+ " (public-key"
+ " (dsa"
+ " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)"
+ " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)"
+ " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)"
+ " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)))",
+ "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10"
+
+ },
+ {
+ GCRY_PK_DSA,
+ "(private-key"
+ " (dsa"
+ " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)"
+ " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)"
+ " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)"
+ " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)"
+ " (x #0087F9E91BFBCC1163DE71ED86D557708E32F8ADDE#)))",
+ "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10"
+ },
+ {
+ GCRY_PK_ECDSA,
+ "(public-key"
+ " (ecdsa(flags param)"
+ " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)"
+ " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)"
+ " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)"
+ " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)"
+ " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)"
+ " (h #000000000000000000000000000000000000000000000000000000000000000001#)"
+ " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+ "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+ },
+ {
+ GCRY_PK_ECDSA,
+ "(public-key"
+ " (ecdsa(flags param)"
+ " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)"
+ " (curve \"NIST P-256\")"
+ " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)"
+ " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)"
+ " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)"
+ " (h #000000000000000000000000000000000000000000000000000000000000000001#)"
+ " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+ "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+ },
+ {
+ GCRY_PK_ECDSA,
+ "(public-key"
+ " (ecdsa"
+ " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)"
+ " (curve \"NIST P-256\")"
+ " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)"
+ " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)"
+ " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)"
+ " (h #000000000000000000000000000000000000000000000000000000000000000001#)"
+ " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+ "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+ },
+ {
+ GCRY_PK_ECDSA,
+ "(public-key"
+ " (ecdsa"
+ " (curve secp256r1)"
+ " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+ "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+ },
+ {
+ GCRY_PK_ECC,
+ "(public-key"
+ " (ecc"
+ " (curve secp256r1)"
+ " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+ "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+ },
+ { /* Ed25519 standard */
+ GCRY_PK_ECC,
+ "(public-key"
+ " (ecc"
+ " (curve Ed25519)"
+ " (q #04"
+ " 1CC662926E7EFF4982B7FB8B928E61CD74CCDD85277CC57196C3AD20B611085F"
+ " 47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)"
+ " ))",
+ "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8"
+ "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1"
+ },
+ { /* Ed25519+EdDSA */
+ GCRY_PK_ECC,
+ "(public-key"
+ " (ecc"
+ " (curve Ed25519)(flags eddsa)"
+ " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)"
+ " ))",
+ "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70"
+ "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47"
+ },
+ { /* Ed25519+EdDSA (with compression prefix) */
+ GCRY_PK_ECC,
+ "(public-key"
+ " (ecc"
+ " (curve Ed25519)(flags eddsa)"
+ " (q #40"
+ " 773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)"
+ " ))",
+ "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70"
+ "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47"
+ },
+ { /* Ed25519+EdDSA (same but uncompressed)*/
+ GCRY_PK_ECC,
+ "(public-key"
+ " (ecc"
+ " (curve Ed25519)(flags eddsa)"
+ " (q #04"
+ " 629ad237d1ed04dcd4abe1711dd699a1cf51b1584c4de7a4ef8b8a640180b26f"
+ " 5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)"
+ " ))",
+ "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70"
+ "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47"
+ },
+ { /* Cv25519 */
+ GCRY_PK_ECC,
+ "(public-key"
+ " (ecc"
+ " (curve Curve25519)(flags djb-tweak)"
+ " (q #40"
+ " 918C1733127F6BF2646FAE3D081A18AE77111C903B906310B077505EFFF12740#)"
+ " ))",
+ "\x0F\x89\xA5\x65\xD3\xEA\x18\x7C\xE8\x39"
+ "\x33\x23\x98\xF5\xD4\x80\x67\x7D\xF4\x9C"
+ },
+ { /* Random key */
+ GCRY_PK_RSA,
+ "(shadowed-private-key"
+ " (rsa"
+ " (n #00B493C79928398DA9D99AC0E949FE6EB62F683CB974FFFBFBC01066F5C9A89B"
+ " D3DC48EAD7C65F36EA943C2B2C865C26C4884FF9EDFDA8C99C855B737D77EEF6"
+ " B85DBC0CCEC0E900C1F89A6893A2A93E8B31028469B6927CEB2F08687E547C68"
+ " 6B0A2F7E50A194FF7AB7637E03DE0912EF7F6E5F1EC37625BD1620CCC2E7A564"
+ " 31E168CDAFBD1D9E61AE47A69A6FA03EF22F844528A710B2392F262B95A3078C"
+ " F321DC8325F92A5691EF69F34FD0DE0B22C79D29DC87723FCADE463829E8E5F7"
+ " D196D73D6C9C180F6A6A0DDBF7B9D8F7FA293C36163B12199EF6A1A95CAE4051"
+ " E3069C522CC6C4A7110F663A5DAD20F66C13A1674D050088208FAE4F33B3AB51"
+ " 03#)"
+ " (e #00010001#)"
+ " (shadowed t1-v1"
+ " (#D2760001240102000005000123350000# OPENPGP.1)"
+ ")))",
+ "\xE5\x6E\xE6\xEE\x5A\x2F\xDC\x3E\x98\x9D"
+ "\xFE\x49\xDA\xF5\x67\x43\xE3\x27\x28\x33"
+ }
+ };
+
+
+static void
+check (void)
+{
+ unsigned char buf[20];
+ unsigned char *ret;
+ gcry_error_t err;
+ gcry_sexp_t sexp;
+ unsigned int i;
+ int repn;
+
+ for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++)
+ {
+ if (gcry_pk_test_algo (key_grips[i].algo))
+ {
+ if (verbose)
+ fprintf (stderr, "algo %d not available; test skipped\n",
+ key_grips[i].algo);
+ continue;
+ }
+ err = gcry_sexp_sscan (&sexp, NULL, key_grips[i].key,
+ strlen (key_grips[i].key));
+ if (err)
+ die ("scanning data %d failed: %s\n", i, gpg_strerror (err));
+
+ if (debug)
+ info ("check(%d): s-exp='%s'\n", i, key_grips[i].key);
+
+ for (repn=0; repn < repetitions; repn++)
+ {
+ ret = gcry_pk_get_keygrip (sexp, buf);
+ if (!ret)
+ die ("gcry_pk_get_keygrip failed for %d\n", i);
+
+ if ( memcmp (key_grips[i].grip, buf, sizeof (buf)) )
+ {
+ print_hex ("keygrip: ", buf, sizeof buf);
+ die ("keygrip for %d does not match\n", i);
+ }
+ else if (debug && !repn)
+ print_hex ("keygrip: ", buf, sizeof buf);
+ }
+
+ gcry_sexp_release (sexp);
+ }
+}
+
+
+
+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;
+
+ putchar (printchar);
+}
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = 1;
+ debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--repetitions"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ repetitions = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ }
+
+ if (repetitions < 1)
+ repetitions = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_set_progress_handler (progress_handler, NULL);
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+
+ check ();
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/mpitests.c b/comm/third_party/libgcrypt/tests/mpitests.c
new file mode 100644
index 0000000000..96e0155165
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/mpitests.c
@@ -0,0 +1,610 @@
+/* mpitests.c - basic mpi tests
+ * Copyright (C) 2001, 2002, 2003, 2006 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt-int.h"
+#else
+# include <gcrypt.h>
+#endif
+
+#define PGM "mpitests"
+#include "t-common.h"
+
+
+/* Set up some test patterns */
+
+/* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char ones[] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+};
+
+/* 48 bytes with value 2: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char twos[] = {
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
+};
+
+/* 48 bytes with value 3: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char threes[] = {
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+};
+
+/* 48 bytes with value 0x80: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char eighties[] = {
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
+};
+
+/* 48 bytes with value 0xff: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char manyff[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+
+static int
+test_const_and_immutable (void)
+{
+ gcry_mpi_t one, second_one;
+
+ one = gcry_mpi_set_ui (NULL, 1);
+ if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)
+ || gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+ die ("immutable or const flag initially set\n");
+
+ second_one = gcry_mpi_copy (one);
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("immutable flag set after copy\n");
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+ die ("const flag set after copy\n");
+ gcry_mpi_release (second_one);
+
+ gcry_mpi_set_flag (one, GCRYMPI_FLAG_IMMUTABLE);
+ if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("failed to set immutable flag\n");
+ if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+ die ("const flag unexpectly set\n");
+
+ second_one = gcry_mpi_copy (one);
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("immutable flag not cleared after copy\n");
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+ die ("const flag unexpectly set after copy\n");
+ gcry_mpi_release (second_one);
+
+ gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
+ if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("failed to clear immutable flag\n");
+ if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+ die ("const flag unexpectly set\n");
+
+ gcry_mpi_set_flag (one, GCRYMPI_FLAG_CONST);
+ if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+ die ("failed to set const flag\n");
+ if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("failed to set immutable flag with const flag\n");
+
+ second_one = gcry_mpi_copy (one);
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("immutable flag not cleared after copy\n");
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+ die ("const flag not cleared after copy\n");
+ gcry_mpi_release (second_one);
+
+ gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
+ if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("clearing immutable flag not ignored for a constant MPI\n");
+ if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+ die ("const flag unexpectly cleared\n");
+
+
+ second_one = gcry_mpi_set (NULL, GCRYMPI_CONST_ONE);
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("immutable flag not cleared by mpi_set (NULL,x)\n");
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+ die ("const flag not cleared by mpi_set (NULL,x)\n");
+ gcry_mpi_release (second_one);
+
+ second_one = gcry_mpi_set_ui (NULL, 42);
+ gcry_mpi_set (second_one, GCRYMPI_CONST_ONE);
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+ die ("immutable flag not cleared after mpi_set (a,x)\n");
+ if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+ die ("const flag not cleared mpi_set (a,x)\n");
+ gcry_mpi_release (second_one);
+
+
+ /* Due to the the constant flag the release below should be a NOP
+ and will leak memory. */
+ gcry_mpi_release (one);
+ return 1;
+}
+
+
+static void
+test_opaque (void)
+{
+ gcry_mpi_t a;
+ char *p;
+ unsigned int nbits;
+
+ p = gcry_xstrdup ("This is a test buffer");
+ a = gcry_mpi_set_opaque (NULL, p, 21*8+1); /* (a non byte aligned length) */
+
+ if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+ die ("opaque flag not set\n");
+
+ p = gcry_mpi_get_opaque (a, &nbits);
+ if (!p)
+ die ("gcry_mpi_get_opaque returned NULL\n");
+ if (nbits != 21*8+1)
+ die ("gcry_mpi_get_opaque returned a changed bit size\n");
+ if (strcmp (p, "This is a test buffer"))
+ die ("gcry_mpi_get_opaque returned a changed buffer\n");
+
+ if (debug)
+ gcry_log_debugmpi ("mpi", a);
+ gcry_mpi_release (a);
+
+ p = gcry_xstrdup ("This is a test buffer");
+ a = gcry_mpi_set_opaque_copy (NULL, p, 21*8+1);
+ gcry_free (p);
+
+ if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+ die ("opaque flag not set\n");
+
+ p = gcry_mpi_get_opaque (a, &nbits);
+ if (!p)
+ die ("gcry_mpi_get_opaque returned NULL\n");
+ if (nbits != 21*8+1)
+ die ("gcry_mpi_get_opaque returned a changed bit size\n");
+ if (strcmp (p, "This is a test buffer"))
+ die ("gcry_mpi_get_opaque returned a changed buffer\n");
+
+ if (debug)
+ gcry_log_debugmpi ("mpi", a);
+
+ gcry_mpi_release (a);
+}
+
+
+static void
+test_maxsize (void)
+{
+ gpg_error_t err;
+ gcry_mpi_t a;
+ unsigned int val;
+ char buffer[2+2048]; /* For PGP: 2 length bytes and 16384 bits. */
+
+ memset (buffer, 0x55, sizeof buffer);
+
+ /* We use a short buffer but a give a too large length to simulate a
+ * programming error. In case this test fails (i.e. die() is
+ * called) the scan function may have access data outside of BUFFER
+ * which may result in a segv but we ignore that to avoid actually
+ * allocating such a long buffer. */
+ err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, buffer, 16*1024*1024 +1, NULL);
+ if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
+ die ("gcry_mpi_scan does not detect its generic input limit\n");
+
+ /* Now test the PGP limit. The scan code check the two length bytes
+ * from the buffer and thus it is sufficient to fake them. */
+ buffer[0] = (16385 >> 8);
+ buffer[1] = (16385 & 0xff);
+ err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
+ if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
+ die ("gcry_mpi_scan does not detect the PGP input limit\n");
+
+ buffer[0] = (16384 >> 8);
+ buffer[1] = (16384 & 0xff);
+
+ err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
+ if (err)
+ die ("gcry_mpi_scan did not parse a large PGP: %s\n", gpg_strerror (err));
+
+ /* Let's also test get_ui. */
+ gcry_mpi_set_ui (a, 0);
+ val = 4711;
+ err = gcry_mpi_get_ui (&val, a);
+ if (err || val != 0)
+ die ("gcry_mpi_get_ui failed at %d: %s\n", __LINE__, gpg_strerror (err));
+
+ gcry_mpi_sub_ui (a, a, 1);
+ val = 4711;
+ err = gcry_mpi_get_ui (&val, a);
+ if (gpg_err_code (err) != GPG_ERR_ERANGE || val != 4711)
+ die ("gcry_mpi_get_ui failed at %d: %s\n", __LINE__, gpg_strerror (err));
+
+ gcry_mpi_set_ui (a, 0xffffffff);
+ val = 4711;
+ err = gcry_mpi_get_ui (&val, a);
+ if (err || val != 0xffffffff)
+ die ("gcry_mpi_get_ui failed at %d: %s\n", __LINE__, gpg_strerror (err));
+
+ if (sizeof (val) == 4)
+ {
+ gcry_mpi_add_ui (a, a, 1);
+ err = gcry_mpi_get_ui (&val, a);
+ if (gpg_err_code (err) != GPG_ERR_ERANGE)
+ die ("gcry_mpi_get_ui failed at %d: %s\n", __LINE__,gpg_strerror (err));
+ }
+
+ gcry_mpi_release (a);
+
+}
+
+
+static void
+test_cmp (void)
+{
+ gpg_error_t rc;
+ gcry_mpi_t zero, zero2;
+ gcry_mpi_t one;
+ gcry_mpi_t two;
+ gcry_mpi_t all_ones;
+ gcry_mpi_t opa1, opa2;
+ gcry_mpi_t opa1s, opa2s;
+ gcry_mpi_t opa0, opa02;
+
+ zero = gcry_mpi_new (0);
+ zero2= gcry_mpi_set_ui (NULL, 0);
+ one = gcry_mpi_set_ui (NULL, 1);
+ two = gcry_mpi_set_ui (NULL, 2);
+ rc = gcry_mpi_scan (&all_ones, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
+ if (rc)
+ die ("scanning number failed at line %d", __LINE__);
+ opa0 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 0);
+ opa02 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 0);
+ opa1 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("aaaaaaaaaaaaaaaa"), 16*8);
+ opa1s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 1*8);
+ opa2 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("bbbbbbbbbbbbbbbb"), 16*8);
+ opa2s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 1*8);
+
+
+ /* Single limb test with cmp_ui */
+ if (gcry_mpi_cmp_ui (zero, 0))
+ fail ("mpi_cmp_ui failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp_ui (zero, 1) < 0))
+ fail ("mpi_cmp_ui failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp_ui (zero, (-1)) < 0))
+ fail ("mpi_cmp_ui failed at line %d", __LINE__);
+
+ if (gcry_mpi_cmp_ui (two, 2))
+ fail ("mpi_cmp_ui failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp_ui (two, 3) < 0))
+ fail ("mpi_cmp_ui failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp_ui (two, 1) > 0))
+ fail ("mpi_cmp_ui failed at line %d", __LINE__);
+
+ /* Multi limb tests with cmp_ui. */
+ if (!(gcry_mpi_cmp_ui (all_ones, 0) > 0))
+ fail ("mpi_cmp_ui failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp_ui (all_ones, (-1)) > 0))
+ fail ("mpi_cmp_ui failed at line %d", __LINE__);
+
+ /* Single limb test with cmp */
+ if (gcry_mpi_cmp (zero, zero2))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (zero, one) < 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (one, zero) > 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+
+ gcry_mpi_neg (one, one);
+ if (!(gcry_mpi_cmp (zero, one) > 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (one, zero) < 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (one, two) < 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ gcry_mpi_neg (one, one);
+
+ if (!(gcry_mpi_cmp (one, two) < 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (two, one) > 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (one, all_ones) < 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+
+ /* Tests with opaque values. */
+ if (!(gcry_mpi_cmp (opa1, one) < 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (one, opa1) > 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (opa0, opa02) == 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (opa1s, opa1) < 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (opa2, opa1s) > 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (opa1, opa2) < 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (opa2, opa1) > 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+ if (!(gcry_mpi_cmp (opa1, opa1) == 0))
+ fail ("mpi_cmp failed at line %d", __LINE__);
+
+
+ gcry_mpi_release(opa2s);
+ gcry_mpi_release(opa2);
+ gcry_mpi_release(opa1s);
+ gcry_mpi_release(opa1);
+ gcry_mpi_release(opa02);
+ gcry_mpi_release(opa0);
+ gcry_mpi_release(all_ones);
+ gcry_mpi_release(two);
+ gcry_mpi_release(one);
+ gcry_mpi_release(zero2);
+ gcry_mpi_release(zero);
+}
+
+
+static int
+test_add (void)
+{
+ gcry_mpi_t one;
+ gcry_mpi_t two;
+ gcry_mpi_t ff;
+ gcry_mpi_t result;
+ unsigned char* pc;
+
+ gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
+ gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
+ gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
+ result = gcry_mpi_new(0);
+
+ gcry_mpi_add(result, one, two);
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
+ if (debug)
+ gcry_log_debug ("Result of one plus two:\n%s\n", pc);
+ gcry_free(pc);
+
+ gcry_mpi_add(result, ff, one);
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
+ if (debug)
+ gcry_log_debug ("Result of ff plus one:\n%s\n", pc);
+ gcry_free(pc);
+
+ gcry_mpi_release(one);
+ gcry_mpi_release(two);
+ gcry_mpi_release(ff);
+ gcry_mpi_release(result);
+ return 1;
+}
+
+
+static int
+test_sub (void)
+{
+ gcry_mpi_t one;
+ gcry_mpi_t two;
+ gcry_mpi_t result;
+ unsigned char* pc;
+
+ gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
+ gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
+ result = gcry_mpi_new(0);
+ gcry_mpi_sub(result, two, one);
+
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
+ if (debug)
+ gcry_log_debug ("Result of two minus one:\n%s\n", pc);
+ gcry_free(pc);
+
+ gcry_mpi_release(one);
+ gcry_mpi_release(two);
+ gcry_mpi_release(result);
+ return 1;
+}
+
+
+static int
+test_mul (void)
+{
+ gcry_mpi_t two;
+ gcry_mpi_t three;
+ gcry_mpi_t result;
+ unsigned char* pc;
+
+ gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
+ gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
+ result = gcry_mpi_new(0);
+ gcry_mpi_mul(result, two, three);
+
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
+ if (debug)
+ gcry_log_debug ("Result of two mul three:\n%s\n", pc);
+ gcry_free(pc);
+
+ gcry_mpi_release(two);
+ gcry_mpi_release(three);
+ gcry_mpi_release(result);
+ return 1;
+}
+
+
+/* What we test here is that we don't overwrite our args and that
+ using the same mpi for several args works. */
+static int
+test_powm (void)
+{
+ int b_int = 17;
+ int e_int = 3;
+ int m_int = 19;
+ gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
+ gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
+ gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
+ gcry_mpi_t res = gcry_mpi_new (0);
+
+ gcry_mpi_powm (res, base, exp, mod);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (exp, e_int))
+ die ("test_powm_ui failed for exp at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check using base for the result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui (exp, e_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (base, base, exp, mod);
+ if (gcry_mpi_cmp (res, base))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (exp, e_int))
+ die ("test_powm_ui failed for exp at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check using exp for the result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui (exp, e_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (exp, base, exp, mod);
+ if (gcry_mpi_cmp (res, exp))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check using mod for the result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui (exp, e_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (mod, base, exp, mod);
+ if (gcry_mpi_cmp (res, mod))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (exp, e_int))
+ die ("test_powm_ui failed for exp at %d\n", __LINE__);
+
+ /* Now check base ^ base mod mod. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (res, base, base, mod);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check base ^ base mod mod with base as result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (base, base, base, mod);
+ if (gcry_mpi_cmp (res, base))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check base ^ base mod mod with mod as result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (mod, base, base, mod);
+ if (gcry_mpi_cmp (res, mod))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+
+ /* Now check base ^ base mod base. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_powm (res, base, base, base);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+
+ /* Check base ^ base mod base with base as result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_powm (base, base, base, base);
+ if (gcry_mpi_cmp (res, base))
+ die ("test_powm failed at %d\n", __LINE__);
+
+ /* Check for a case: base is negative and expo is even. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_neg (base, base);
+ gcry_mpi_set_ui (exp, e_int * 2);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (res, base, exp, mod);
+ /* Result should be positive and it's 7 = (-17)^6 mod 19. */
+ if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7))
+ {
+ if (verbose)
+ {
+ fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res));
+ fprintf (stderr, "mpi: ");
+ gcry_mpi_dump (res);
+ putc ('\n', stderr);
+ }
+ die ("test_powm failed for negative base at %d\n", __LINE__);
+ }
+
+ gcry_mpi_release (base);
+ gcry_mpi_release (exp);
+ gcry_mpi_release (mod);
+ gcry_mpi_release (res);
+ /* Fixme: We should add the rest of the cases of course. */
+
+
+
+ return 1;
+}
+
+
+int
+main (int argc, char* argv[])
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fputs ("version mismatch\n", stderr);
+ exit (1);
+ }
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM));
+
+ test_const_and_immutable ();
+ test_opaque ();
+ test_maxsize ();
+ test_cmp ();
+ test_add ();
+ test_sub ();
+ test_mul ();
+ test_powm ();
+
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/pkbench.c b/comm/third_party/libgcrypt/tests/pkbench.c
new file mode 100644
index 0000000000..a7665f4619
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/pkbench.c
@@ -0,0 +1,485 @@
+/* pkbench.c - Pubkey menchmarking
+ * Copyright (C) 2004, 2005, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <gcrypt.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#ifndef HAVE_W32_SYSTEM
+# include <sys/times.h>
+#endif /*HAVE_W32_SYSTEM*/
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+
+#define PGM "pkbench"
+#include "t-common.h"
+
+
+typedef struct context
+{
+ gcry_sexp_t key_secret;
+ gcry_sexp_t key_public;
+ gcry_sexp_t data;
+ gcry_sexp_t data_encrypted;
+ gcry_sexp_t data_signed;
+} *context_t;
+
+typedef int (*work_t) (context_t context, unsigned int final);
+
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ 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 *
+read_file (const char *fname, size_t *r_length)
+{
+ FILE *fp;
+ struct stat st;
+ char *buf;
+ size_t buflen;
+
+ fp = fopen (fname, "rb");
+ if (!fp)
+ {
+ fail ("can't open `%s': %s\n", fname, strerror (errno));
+ return NULL;
+ }
+
+ if (fstat (fileno(fp), &st))
+ {
+ fail ("can't stat `%s': %s\n", fname, strerror (errno));
+ fclose (fp);
+ return NULL;
+ }
+
+ buflen = st.st_size;
+ buf = gcry_xmalloc (buflen+1);
+ if (fread (buf, buflen, 1, fp) != 1)
+ {
+ fail ("error reading `%s': %s\n", fname, strerror (errno));
+ fclose (fp);
+ gcry_free (buf);
+ return NULL;
+ }
+ fclose (fp);
+
+ if (r_length)
+ *r_length = buflen;
+ return buf;
+}
+
+
+
+static void
+benchmark (work_t worker, context_t context)
+{
+ clock_t timer_start, timer_stop;
+ unsigned int loop = 10;
+ unsigned int i = 0;
+ struct tms timer;
+ int ret = 0;
+
+#ifdef HAVE_W32_SYSTEM
+ timer_start = clock ();
+#else
+ times (&timer);
+ timer_start = timer.tms_utime;
+#endif
+ for (i = 0; i < loop; i++)
+ {
+ ret = (*worker) (context, (i + 1) == loop);
+ if (! ret)
+ break;
+ }
+#ifdef HAVE_W32_SYSTEM
+ timer_stop = clock ();
+#else
+ times (&timer);
+ timer_stop = timer.tms_utime;
+#endif
+
+ if (ret)
+ printf ("%.0f ms\n",
+ (((double) ((timer_stop - timer_start) / loop)) / CLOCKS_PER_SEC)
+ * 10000000);
+ else
+ printf ("[skipped]\n");
+}
+
+static int
+work_encrypt (context_t context, unsigned int final)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_sexp_t data_encrypted = NULL;
+ int ret = 1;
+
+ err = gcry_pk_encrypt (&data_encrypted,
+ context->data, context->key_public);
+ if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+ {
+ err = GPG_ERR_NO_ERROR;
+ ret = 0;
+ }
+ else
+ {
+ assert (! err);
+
+ if (final)
+ context->data_encrypted = data_encrypted;
+ else
+ gcry_sexp_release (data_encrypted);
+ }
+
+ return ret;
+}
+
+static int
+work_decrypt (context_t context, unsigned int final)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ int ret = 1;
+
+ if (! context->data_encrypted)
+ ret = 0;
+ else
+ {
+ gcry_sexp_t data_decrypted = NULL;
+
+ err = gcry_pk_decrypt (&data_decrypted,
+ context->data_encrypted,
+ context->key_secret);
+ assert (! err);
+ if (final)
+ {
+ gcry_sexp_release (context->data_encrypted);
+ context->data_encrypted = NULL;
+ }
+ gcry_sexp_release (data_decrypted);
+ }
+
+ return ret;
+}
+
+static int
+work_sign (context_t context, unsigned int final)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_sexp_t data_signed = NULL;
+ int ret = 1;
+
+ err = gcry_pk_sign (&data_signed,
+ context->data, context->key_secret);
+ if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+ {
+ err = GPG_ERR_NO_ERROR;
+ ret = 0;
+ }
+ else if (err)
+ {
+ fail ("pk_sign failed: %s\n", gpg_strerror (err));
+ ret = 0;
+ }
+ else
+ {
+ if (final)
+ context->data_signed = data_signed;
+ else
+ gcry_sexp_release (data_signed);
+ }
+
+ return ret;
+}
+
+static int
+work_verify (context_t context, unsigned int final)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ int ret = 1;
+
+ if (!context->data_signed)
+ return 0;
+
+ err = gcry_pk_verify (context->data_signed,
+ context->data,
+ context->key_public);
+ if (err)
+ {
+ show_sexp ("data_signed:\n", context->data_signed);
+ show_sexp ("data:\n", context->data);
+ fail ("pk_verify failed: %s\n", gpg_strerror (err));
+ ret = 0;
+ }
+ else if (final)
+ {
+ gcry_sexp_release (context->data_signed);
+ context->data_signed = NULL;
+ }
+
+ return ret;
+}
+
+static void
+process_key_pair (context_t context)
+{
+ struct
+ {
+ work_t worker;
+ const char *identifier;
+ } worker_functions[] = { { work_encrypt, "encrypt" },
+ { work_decrypt, "decrypt" },
+ { work_sign, "sign" },
+ { work_verify, "verify" } };
+ unsigned int i = 0;
+
+ for (i = 0; i < (sizeof (worker_functions) / sizeof (*worker_functions)); i++)
+ {
+ printf ("%s: ", worker_functions[i].identifier);
+ benchmark (worker_functions[i].worker, context);
+ }
+}
+
+static void
+context_init (context_t context, gcry_sexp_t key_secret, gcry_sexp_t key_public)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int key_size = 0;
+ gcry_mpi_t data = NULL;
+ gcry_sexp_t data_sexp = NULL;
+
+ key_size = gcry_pk_get_nbits (key_secret);
+ assert (key_size);
+
+ data = gcry_mpi_new (key_size);
+ assert (data);
+
+ gcry_mpi_randomize (data, key_size, GCRY_STRONG_RANDOM);
+ gcry_mpi_clear_bit (data, key_size - 1);
+ err = gcry_sexp_build (&data_sexp, NULL,
+ "(data (flags raw) (value %m))",
+ data);
+ assert (! err);
+ gcry_mpi_release (data);
+
+ context->key_secret = key_secret;
+ context->key_public = key_public;
+ context->data = data_sexp;
+ context->data_encrypted = NULL;
+ context->data_signed = NULL;
+}
+
+static void
+context_destroy (context_t context)
+{
+ gcry_sexp_release (context->key_secret);
+ gcry_sexp_release (context->key_public);
+ gcry_sexp_release (context->data);
+}
+
+static void
+process_key_pair_file (const char *key_pair_file)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ void *key_pair_buffer = NULL;
+ gcry_sexp_t key_pair_sexp = NULL;
+ gcry_sexp_t key_secret_sexp = NULL;
+ gcry_sexp_t key_public_sexp = NULL;
+ struct context context = { NULL };
+ size_t file_length;
+
+ key_pair_buffer = read_file (key_pair_file, &file_length);
+ if (!key_pair_buffer)
+ die ("failed to open `%s'\n", key_pair_file);
+
+ err = gcry_sexp_sscan (&key_pair_sexp, NULL,
+ key_pair_buffer, file_length);
+ if (err)
+ die ("gcry_sexp_sscan failed\n");
+
+ key_secret_sexp = gcry_sexp_find_token (key_pair_sexp, "private-key", 0);
+ assert (key_secret_sexp);
+ key_public_sexp = gcry_sexp_find_token (key_pair_sexp, "public-key", 0);
+ assert (key_public_sexp);
+
+ gcry_sexp_release (key_pair_sexp);
+
+ context_init (&context, key_secret_sexp, key_public_sexp);
+
+ printf ("Key file: %s\n", key_pair_file);
+ process_key_pair (&context);
+ printf ("\n");
+
+ context_destroy (&context);
+ gcry_free (key_pair_buffer);
+}
+
+
+static void
+generate_key (const char *algorithm, const char *key_size)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ size_t key_pair_buffer_size = 0;
+ char *key_pair_buffer = NULL;
+ gcry_sexp_t key_spec = NULL;
+ gcry_sexp_t key_pair = NULL;
+
+ if (isdigit ((unsigned int)*key_size))
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (%s (nbits %s)))",
+ algorithm, key_size);
+ else
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (%s (curve %s)))",
+ algorithm, key_size);
+ if (err)
+ die ("sexp_build failed: %s\n", gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key_pair, key_spec);
+ if (err)
+ {
+ show_sexp ("request:\n", key_spec);
+ die ("pk_genkey failed: %s\n", gpg_strerror (err));
+ }
+
+ key_pair_buffer_size = gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED,
+ NULL, 0);
+ key_pair_buffer = gcry_xmalloc (key_pair_buffer_size);
+
+ gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED,
+ key_pair_buffer, key_pair_buffer_size);
+
+ printf ("%.*s", (int)key_pair_buffer_size, key_pair_buffer);
+ gcry_free (key_pair_buffer);
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int genkey_mode = 0;
+ int fips_mode = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ puts ("Usage: " PGM " [OPTIONS] [FILES]\n"
+ "Various public key tests:\n\n"
+ " Default is to process all given key files\n\n"
+ " --genkey ALGONAME SIZE Generate a public key\n"
+ "\n"
+ " --verbose enable extra informational output\n"
+ " --debug enable additional debug output\n"
+ " --help display this help and exit\n\n");
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--genkey"))
+ {
+ genkey_mode = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--fips"))
+ {
+ fips_mode = 1;
+ argc--; argv++;
+ }
+ }
+
+ xgcry_control ((GCRYCTL_SET_VERBOSITY, (int)verbose));
+
+ if (fips_mode)
+ xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fprintf (stderr, PGM ": version mismatch\n");
+ exit (1);
+ }
+
+ if (genkey_mode)
+ {
+ /* No valuable keys are create, so we can speed up our RNG. */
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ }
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+
+ if (genkey_mode && argc == 2)
+ {
+ generate_key (argv[0], argv[1]);
+ }
+ else if (!genkey_mode && argc)
+ {
+ int i;
+
+ for (i = 0; i < argc; i++)
+ process_key_pair_file (argv[i]);
+ }
+ else
+ {
+ fprintf (stderr, "usage: " PGM
+ " [OPTIONS] [FILES] (try --help for more information)\n");
+ exit (1);
+ }
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/pkcs1v2-oaep.h b/comm/third_party/libgcrypt/tests/pkcs1v2-oaep.h
new file mode 100644
index 0000000000..17f865fcbd
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/pkcs1v2-oaep.h
@@ -0,0 +1,781 @@
+/* pkcs1v2-oaep.h - OAEP test vector table
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Manually created from the OAEP file in
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip
+ */
+
+ static struct {
+ const char *desc;
+ const char *n, *e, *d;
+ struct {
+ const char *desc;
+ const char *mesg;
+ const char *seed;
+ const char *encr;
+ } m[6];
+ } tbl[] = {
+ {
+ "Example 1: A 1024-bit RSA key pair",
+ "a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0ab"
+ "c4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72"
+ "f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb514"
+ "8ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb",
+ "010001",
+ "53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd"
+ "8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55"
+ "fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbf"
+ "b78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1",
+ {
+ {
+ "OAEP Example 1.1",
+ "6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34",
+ "18b776ea21069d69776a33e96bad48e1dda0a5ef",
+ "354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb"
+ "21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535f"
+ "a9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426"
+ "d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a"
+ },{
+ "OAEP Example 1.2",
+ "750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5",
+ "0cc742ce4a9b7f32f951bcb251efd925fe4fe35f",
+ "640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c11"
+ "65988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352"
+ "d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74b"
+ "bbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44"
+ },{
+ "OAEP Example 1.3",
+ "d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c245"
+ "1fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051",
+ "2514df4695755a67b288eaf4905c36eec66fd2fd",
+ "423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603"
+ "595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4"
+ "360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3"
+ "066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb"
+ },{
+ "OAEP Example 1.4",
+ "52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85",
+ "c4435a3e1a18a68b6820436290a37cefb85db3fb",
+ "45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40fd3d38e"
+ "22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646f"
+ "d0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4"
+ "bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755"
+ },{
+ "OAEP Example 1.5",
+ "8da89fd9e5f974a29feffb462b49180f6cf9e802",
+ "b318c42df3be0f83fea823f5a7b47ed5e425a3b5",
+ "36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e2"
+ "19005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea"
+ "0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6d"
+ "d18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439"
+ },{
+ "OAEP Example 1.6",
+ "26521050844271",
+ "e4ec0982c2336f3a677f6a356174eb0ce887abc2",
+ "42cee2617b1ecea4db3f4829386fbd61dafbf038e180d837c96366df24c097b4"
+ "ab0fac6bdf590d821c9f10642e681ad05b8d78b378c0f46ce2fad63f74e0ad3d"
+ "f06b075d7eb5f5636f8d403b9059ca761b5c62bb52aa45002ea70baace08ded2"
+ "43b9d8cbd62a68ade265832b56564e43a6fa42ed199a099769742df1539e8255"
+ }
+ }
+ },
+ {
+ "Example 2: A 1025-bit RSA key pair",
+ "01947c7fce90425f47279e70851f25d5e62316fe8a1df19371e3e628e260543e"
+ "4901ef6081f68c0b8141190d2ae8daba7d1250ec6db636e944ec3722877c7c1d"
+ "0a67f14b1694c5f0379451a43e49a32dde83670b73da91a1c99bc23b436a6005"
+ "5c610f0baf99c1a079565b95a3f1526632d1d4da60f20eda25e653c4f002766f"
+ "45",
+ "010001",
+ "0823f20fadb5da89088a9d00893e21fa4a1b11fbc93c64a3be0baaea97fb3b93"
+ "c3ff713704c19c963c1d107aae99054739f79e02e186de86f87a6ddefea6d8cc"
+ "d1d3c81a47bfa7255be20601a4a4b2f08a167b5e279d715b1b455bdd7eab2459"
+ "41d9768b9acefb3ccda5952da3cee72525b4501663a8ee15c9e992d92462fe39",
+ {
+ {
+ "OAEP Example 2.1",
+ "8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7",
+ "8c407b5ec2899e5099c53e8ce793bf94e71b1782",
+ "0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a"
+ "5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df34"
+ "56653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8a"
+ "bb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe72"
+ "0e"
+ },{
+ "OAEP Example 2.2",
+ "2d",
+ "b600cf3c2e506d7f16778c910d3a8b003eee61d5",
+ "018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165ee"
+ "e33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b0709939"
+ "98e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc"
+ "95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba102"
+ "45"
+ },{
+ "OAEP Example 2.3",
+ "74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e",
+ "a73768aeeaa91f9d8c1ed6f9d2b63467f07ccae3",
+ "018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c7"
+ "9f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651"
+ "bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8b"
+ "b2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be20"
+ "53"
+ },{
+ "OAEP Example 2.4",
+ "a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721"
+ "dfe885072c78a203b151739be540fa8c153a10f00a",
+ "9a7b3b0e708bd96f8190ecab4fb9b2b3805a8156",
+ "00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c"
+ "649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b"
+ "31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa0876"
+ "36965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc76"
+ "41"
+ },{
+ "OAEP Example 2.5",
+ "2ef2b066f854c33f3bdcbb5994a435e73d6c6c",
+ "eb3cebbc4adc16bb48e88c8aec0e34af7f427fd3",
+ "00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d"
+ "931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da0"
+ "8bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806"
+ "e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7a"
+ "ec",
+ },{
+ "OAEP Example 2.6",
+ "8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba89c0",
+ "4c45cf4d57c98e3d6d2095adc51c489eb50dff84",
+ "010839ec20c27b9052e55befb9b77e6fc26e9075d7a54378c646abdf51e445bd"
+ "5715de81789f56f1803d9170764a9e93cb78798694023ee7393ce04bc5d8f8c5"
+ "a52c171d43837e3aca62f609eb0aa5ffb0960ef04198dd754f57f7fbe6abf765"
+ "cf118b4ca443b23b5aab266f952326ac4581100644325f8b721acd5d04ff14ef"
+ "3a"
+ }
+ }
+ },
+ {
+ "Example 3: A 1026-bit RSA key pair",
+ "02b58fec039a860700a4d7b6462f93e6cdd491161ddd74f4e810b40e3c165200"
+ "6a5c277b2774c11305a4cbab5a78efa57e17a86df7a3fa36fc4b1d2249f22ec7"
+ "c2dd6a463232accea906d66ebe80b5704b10729da6f833234abb5efdd4a292cb"
+ "fad33b4d33fa7a14b8c397b56e3acd21203428b77cdfa33a6da706b3d8b0fc43"
+ "e9",
+ "010001",
+ "15b48a5b5683a94670e23b5718f814fa0e13f85038f50711182cba61510581f3"
+ "d22c7e232ef937e22e551d68b86e2f8cb1aad8be2e488f5df7efd279e3f568d4"
+ "eaf36f80cf7141ace60fcc9113fb6c4a841fd50bbc7c512ffcbeff21487aa811"
+ "eb3ca8c62005346a86de86bfa1d8a948fd3f348c22eaadf333c3ce6ce13208fd",
+ {
+ {
+ "OAEP Example 3.1",
+ "087820b569e8fa8d",
+ "8ced6b196290805790e909074015e6a20b0c4894",
+ "026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d"
+ "5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2"
+ "b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d3"
+ "7e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae"
+ "80"
+ },{
+ "OAEP Example 3.2",
+ "4653acaf171960b01f52a7be63a3ab21dc368ec43b50d82ec3781e04",
+ "b4291d6567550848cc156967c809baab6ca507f0",
+ "024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da"
+ "72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca206"
+ "9d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3"
+ "e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4b"
+ "f5"
+ },{
+ "OAEP Example 3.3",
+ "d94cd0e08fa404ed89",
+ "ce8928f6059558254008badd9794fadcd2fd1f65",
+ "0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844"
+ "ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950"
+ "fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962be"
+ "c22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a"
+ "3a"
+ },{
+ "OAEP Example 3.4",
+ "6cc641b6b61e6f963974dad23a9013284ef1",
+ "6e2979f52d6814a57d83b090054888f119a5b9a3",
+ "02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b"
+ "42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9d"
+ "ec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8"
+ "d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9"
+ "a0"
+ },{
+ "OAEP Example 3.5",
+ "df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca69"
+ "18017cfda1153bf7a6af87593223",
+ "2d760bfe38c59de34cdc8b8c78a38e66284a2d27",
+ "0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee6"
+ "7f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545"
+ "fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943a"
+ "b8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c"
+ "60",
+ },{
+ "OAEP Example 3.6",
+ "3c3bad893c544a6d520ab022319188c8d504b7a788b850903b85972eaa18552e"
+ "1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1",
+ "f174779c5fd3cfe007badcb7a36c9b55bfcfbf0e",
+ "00112051e75d064943bc4478075e43482fd59cee0679de6893eec3a943daa490"
+ "b9691c93dfc0464b6623b9f3dbd3e70083264f034b374f74164e1a00763725e5"
+ "74744ba0b9db83434f31df96f6e2a26f6d8eba348bd4686c2238ac07c37aac37"
+ "85d1c7eea2f819fd91491798ed8e9cef5e43b781b0e0276e37c43ff9492d0057"
+ "30"
+ }
+ }
+ },
+ {
+ "Example 4: A 1027-bit RSA key pair",
+ "051240b6cc0004fa48d0134671c078c7c8dec3b3e2f25bc2564467339db38853"
+ "d06b85eea5b2de353bff42ac2e46bc97fae6ac9618da9537a5c8f553c1e35762"
+ "5991d6108dcd7885fb3a25413f53efcad948cb35cd9b9ae9c1c67626d113d57d"
+ "de4c5bea76bb5bb7de96c00d07372e9685a6d75cf9d239fa148d70931b5f3fb0"
+ "39",
+ "010001",
+ "0411ffca3b7ca5e9e9be7fe38a85105e353896db05c5796aecd2a725161eb365"
+ "1c8629a9b862b904d7b0c7b37f8cb5a1c2b54001018a00a1eb2cafe4ee4e9492"
+ "c348bc2bedab4b9ebbf064e8eff322b9009f8eec653905f40df88a3cdc49d456"
+ "7f75627d41aca624129b46a0b7c698e5e65f2b7ba102c749a10135b6540d0401",
+ {
+ {
+ "OAEP Example 4.1",
+ "4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d"
+ "7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2",
+ "1cac19ce993def55f98203f6852896c95ccca1f3",
+ "04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5"
+ "781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96f"
+ "e155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896"
+ "935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1"
+ "a8"
+ },{
+ "OAEP Example 4.2",
+ "b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98"
+ "f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8",
+ "f545d5897585e3db71aa0cb8da76c51d032ae963",
+ "0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b1"
+ "3b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186"
+ "c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18"
+ "381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed1"
+ "5e"
+ },{
+ "OAEP Example 4.3",
+ "bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b"
+ "0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99",
+ "ad997feef730d6ea7be60d0dc52e72eacbfdd275",
+ "0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77"
+ "319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd0"
+ "01dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193"
+ "302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d0"
+ "65"
+ },{
+ "OAEP Example 4.4",
+ "fb2ef112f5e766eb94019297934794f7be2f6fc1c58e",
+ "136454df5730f73c807a7e40d8c1a312ac5b9dd3",
+ "02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a"
+ "796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e4"
+ "4fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c6"
+ "8e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11"
+ "e4"
+ },{
+ "OAEP Example 4.5",
+ "28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c"
+ "2284",
+ "bca8057f824b2ea257f2861407eef63d33208681",
+ "00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a4431079"
+ "9066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f1"
+ "8ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a8324756"
+ "8292536583340948d7a8c97c4acd1e98d1e29dc320e97a260532a8aa7a758a1e"
+ "c2"
+ },{
+ "OAEP Example 4.6",
+ "f22242751ec6b1",
+ "2e7e1e17f647b5ddd033e15472f90f6812f3ac4e",
+ "00a5ffa4768c8bbecaee2db77e8f2eec99595933545520835e5ba7db9493d3e1"
+ "7cddefe6a5f567624471908db4e2d83a0fbee60608fc84049503b2234a07dc83"
+ "b27b22847ad8920ff42f674ef79b76280b00233d2b51b8cb2703a9d42bfbc825"
+ "0c96ec32c051e57f1b4ba528db89c37e4c54e27e6e64ac69635ae887d9541619"
+ "a9"
+ }
+ }
+ },
+ {
+ "Example 5: A 1028-bit RSA key pair",
+ "0aadf3f9c125e5d891f31ac448e993defe580f802b45f9d7f22ba5021e9c4757"
+ "6b5a1e68031ba9db4e6dabe4d96a1d6f3d267268cff408005f118efcadb99888"
+ "d1c234467166b2a2b849a05a889c060ac0da0c5fae8b55f309ba62e703742fa0"
+ "326f2d10b011021489ff497770190d895fd39f52293c39efd73a698bdab9f10e"
+ "d9",
+ "010001",
+ "0256eb4cba7067f2d2be540dcdff4582a36b7d31d1c9099bb214b79848466a26"
+ "8f80f58a49ac04c0e3648934a0206c04537c19b236643a6082732144df75fa21"
+ "7588f794682be89168276dc726c5c0cbdb84d31bbf26d0a43af495717f7d528a"
+ "cfee341561f6ff3cae05c578f8470d9682f9c0d072f9f6068b56d5880f682be2"
+ "c5",
+ {
+ {
+ "OAEP Example 5.1",
+ "af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8",
+ "44c92e283f77b9499c603d963660c87d2f939461",
+ "036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a6"
+ "8651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df79"
+ "9f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a"
+ "519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000"
+ "e5"
+ },{
+ "OAEP Example 5.2",
+ "a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b"
+ "4ac3303ec73f0f87cfb32399",
+ "cb28f5860659fceee49c3eeafce625a70803bd32",
+ "03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f"
+ "54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399"
+ "fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a283"
+ "7a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7"
+ "ad"
+ },{
+ "OAEP Example 5.3",
+ "308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a31"
+ "4bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7",
+ "2285f40d770482f9a9efa2c72cb3ac55716dc0ca",
+ "0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2c"
+ "a7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325"
+ "a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c"
+ "9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b69"
+ "67"
+ },{
+ "OAEP Example 5.4",
+ "15c5b9ee1185",
+ "49fa45d3a78dd10dfd577399d1eb00af7eed5513",
+ "0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588f"
+ "f59a82cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671"
+ "a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2"
+ "e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719a"
+ "bf"
+ },{
+ "OAEP Example 5.5",
+ "21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a673"
+ "7277365d3fea11db8923a2029a",
+ "f0287413234cc5034724a094c4586b87aff133fc",
+ "07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241"
+ "c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51de"
+ "b507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0e"
+ "e3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc25097"
+ "23"
+ },{
+ "OAEP Example 5.6",
+ "541e37b68b6c8872b84c02",
+ "d9fba45c96f21e6e26d29eb2cdcb6585be9cb341",
+ "08c36d4dda33423b2ed6830d85f6411ba1dcf470a1fae0ebefee7c089f256cef"
+ "74cb96ea69c38f60f39abee44129bcb4c92de7f797623b20074e3d9c2899701e"
+ "d9071e1efa0bdd84d4c3e5130302d8f0240baba4b84a71cc032f2235a5ff0fae"
+ "277c3e8f9112bef44c9ae20d175fc9a4058bfc930ba31b02e2e4f444483710f2"
+ "4a"
+ }
+ }
+ },
+ {
+ "Example 6: A 1029-bit RSA key pair",
+ "12b17f6dad2ecd19ff46dc13f7860f09e0e0cfb677b38a52592305ceaf022c16"
+ "6db90d04ac29e33f7dd12d9faf66e0816bb63ead267cc7d46c17c37be214bca2"
+ "a22d723a64e44407436b6fc965729aefc2554f376cd5dcea68293780a62bf39d"
+ "0029485a160bbb9e5dc0972d21a504f52e5ee028aa416332f510b2e9cff5f722"
+ "af",
+ "010001",
+ "0295eca3560618369559cecd303aa9cfdafc1d9f06959df75ffef929aa896961"
+ "bcd190dc6997eda7f5963e724d07b4dc11f3065e5ae97d96835112280b9084bb"
+ "14f2a21ebd4e889d41b9c4132ec1956fcab8bb2fed0575884936522c5ff7d332"
+ "61904824e7cadee4e0bb372d2457cf78e2bd1286228ff83f10731ce63c90cff3"
+ "f9",
+ {
+ {
+ "OAEP Example 6.1",
+ "4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4",
+ "dd0f6cfe415e88e5a469a51fbba6dfd40adb4384",
+ "0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ac"
+ "e583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc"
+ "3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34d"
+ "ebdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1"
+ "a3"
+ },{
+ "OAEP Example 6.2",
+ "5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92"
+ "b22512214e4be6c914792ddabdf57faa8aa7",
+ "8d14bd946a1351148f5cae2ed9a0c653e85ebd85",
+ "0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c"
+ "436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50"
+ "f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3"
+ "f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e6"
+ "3f"
+ },{
+ "OAEP Example 6.3",
+ "b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d8"
+ "31f2ab068b23b149879c002f6bf3feee97591112562c",
+ "6c075bc45520f165c0bf5ea4c5df191bc9ef0e44",
+ "0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844"
+ "202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350"
+ "c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c"
+ "7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d"
+ "65"
+ },{
+ "OAEP Example 6.4",
+ "684e3038c5c041f7",
+ "3bbc3bd6637dfe12846901029bf5b0c07103439c",
+ "008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e6"
+ "95263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa3997"
+ "4b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c560"
+ "90267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52"
+ "f8"
+ },{
+ "OAEP Example 6.5",
+ "32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693",
+ "b46b41893e8bef326f6759383a83071dae7fcabc",
+ "00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31f"
+ "edf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045"
+ "ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f"
+ "42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384"
+ "ab"
+ },{
+ "OAEP Example 6.6",
+ "50ba14be8462720279c306ba",
+ "0a2403312a41e3d52f060fbc13a67de5cf7609a7",
+ "0a026dda5fc8785f7bd9bf75327b63e85e2c0fdee5dadb65ebdcac9ae1de95c9"
+ "2c672ab433aa7a8e69ce6a6d8897fac4ac4a54de841ae5e5bbce7687879d7963"
+ "4cea7a30684065c714d52409b928256bbf53eabcd5231eb7259504537399bd29"
+ "164b726d33a46da701360a4168a091ccab72d44a62fed246c0ffea5b1348ab54"
+ "70"
+ }
+ }
+ },
+ {
+ "Example 7: A 1030-bit RSA key pair",
+ "311179f0bcfc9b9d3ca315d00ef30d7bdd3a2cfae9911bfedcb948b3a4782d07"
+ "32b6ab44aa4bf03741a644dc01bec3e69b01a033e675d8acd7c4925c6b1aec31"
+ "19051dfd89762d215d45475ffcb59f908148623f37177156f6ae86dd7a7c5f43"
+ "dc1e1f908254058a284a5f06c0021793a87f1ac5feff7dcaee69c5e51a3789e3"
+ "73",
+ "010001",
+ "070cfcff2feb8276e27432c45dfee48f49b7917d6530e1f0ca3460f32e027617"
+ "4487c56e22a45d2500d7775495219d7d165a9cf3bd92c32af9a98d8dc9cc2968"
+ "00adc94a0a54fb40f34291bf84ee8ea12b6f109359c6d3542a50f9c767f5cfff"
+ "05a681c2e656fb77caaadb4be9468d8abcd4df98f58e86d2053fa1349f748e21"
+ "b1",
+ {
+ {
+ "OAEP Example 7.1",
+ "47aae909",
+ "43dd09a07ff4cac71caa4632ee5e1c1daee4cd8f",
+ "1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97"
+ "b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d28"
+ "2f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223d"
+ "c60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85"
+ "c1"
+ },{
+ "OAEP Example 7.2",
+ "1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7",
+ "3a9c3cec7b84f9bd3adecbc673ec99d54b22bc9b",
+ "1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b973"
+ "6edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451"
+ "f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323"
+ "d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3"
+ "b6"
+ },{
+ "OAEP Example 7.3",
+ "d976fc",
+ "76a75e5b6157a556cf8884bb2e45c293dd545cf5",
+ "2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298"
+ "707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1"
+ "c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85"
+ "018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc5455"
+ "6b"
+ },{
+ "OAEP Example 7.4",
+ "d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5"
+ "f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb",
+ "7866314a6ad6f2b250a35941db28f5864b585859",
+ "0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a"
+ "312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423"
+ "b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c"
+ "1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bf"
+ "ac"
+ },{
+ "OAEP Example 7.5",
+ "bb47231ca5ea1d3ad46c99345d9a8a61",
+ "b2166ed472d58db10cab2c6b000cccf10a7dc509",
+ "028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b241"
+ "84114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8"
+ "e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e"
+ "4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed3474"
+ "78"
+ },{
+ "OAEP Example 7.6",
+ "2184827095d35c3f86f600e8e59754013296",
+ "52673bde2ca166c2aa46131ac1dc808d67d7d3b1",
+ "14c678a94ad60525ef39e959b2f3ba5c097a94ff912b67dbace80535c187abd4"
+ "7d075420b1872152bba08f7fc31f313bbf9273c912fc4c0149a9b0cfb79807e3"
+ "46eb332069611bec0ff9bcd168f1f7c33e77313cea454b94e2549eecf002e2ac"
+ "f7f6f2d2845d4fe0aab2e5a92ddf68c480ae11247935d1f62574842216ae6741"
+ "15"
+ }
+ }
+ },
+ {
+ "Example 8: A 1031-bit RSA key pair",
+ "5bdf0e30d321dda5147f882408fa69195480df8f80d3f6e8bf5818504f36427c"
+ "a9b1f5540b9c65a8f6974cf8447a244d9280201bb49fcbbe6378d1944cd227e2"
+ "30f96e3d10f819dcef276c64a00b2a4b6701e7d01de5fabde3b1e9a0df82f463"
+ "1359cd22669647fbb1717246134ed7b497cfffbdc42b59c73a96ed90166212df"
+ "f7",
+ "010001",
+ "0f7d1e9e5aaa25fd13e4a0663ae144e0d15f5cd18bcdb09df2cc7e64e3c5e915"
+ "ad62645304161d098c715bb7ab8bd01d07eaf3fed7c7ed08af2a8a62ef44ab16"
+ "b320e14af72a48f96afe262a0ae4cf65e635e910790cd4ee5cea768a4b2639f7"
+ "e6f677b3f0bb6be32b75747d8909036f0264f58d401cdba131716157a75ecf63"
+ "31",
+ {
+ {
+ "OAEP Example 8.1",
+ "050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c82"
+ "5bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967",
+ "7706ffca1ecfb1ebee2a55e5c6e24cd2797a4125",
+ "09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b3040"
+ "9472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d1291979"
+ "0410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0"
+ "970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b"
+ "61"
+ },{
+ "OAEP Example 8.2",
+ "4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18"
+ "a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc",
+ "a3717da143b4dcffbc742665a8fa950585548343",
+ "2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256"
+ "f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a341165"
+ "6424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df5"
+ "06fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee3"
+ "9d"
+ },{
+ "OAEP Example 8.3",
+ "8604ac56328c1ab5ad917861",
+ "ee06209073cca026bb264e5185bf8c68b7739f86",
+ "4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e"
+ "0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd"
+ "31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2b"
+ "e780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca989"
+ "3f"
+ },{
+ "OAEP Example 8.4",
+ "fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0d"
+ "ddcc",
+ "990ad573dc48a973235b6d82543618f2e955105d",
+ "2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812"
+ "fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175"
+ "a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b"
+ "15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fb"
+ "d0"
+ },{
+ "OAEP Example 8.5",
+ "4a5f4914bee25de3c69341de07",
+ "ecc63b28f0756f22f52ac8e6ec1251a6ec304718",
+ "1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5"
+ "e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923"
+ "359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5"
+ "f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7"
+ "b2"
+ },{
+ "OAEP Example 8.6",
+ "8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be",
+ "3925c71b362d40a0a6de42145579ba1e7dd459fc",
+ "3afd9c6600147b21798d818c655a0f4c9212db26d0b0dfdc2a7594ccb3d22f5b"
+ "f1d7c3e112cd73fc7d509c7a8bafdd3c274d1399009f9609ec4be6477e453f07"
+ "5aa33db382870c1c3409aef392d7386ae3a696b99a94b4da0589447e955d16c9"
+ "8b17602a59bd736279fcd8fb280c4462d590bfa9bf13fed570eafde97330a2c2"
+ "10"
+ }
+ }
+ },
+ {
+ "Example 9: A 1536-bit RSA key pair",
+ "cf2cd41e34ca3a728ea5cb8aff64c36d27bdef5364e336fd68d3123c5a196a8c"
+ "287013e853d5156d58d151954520fb4f6d7b17abb6817765909c576119659d90"
+ "2b1906ed8a2b10c155c24d124528dab9eeae379beac66e4a411786dcb8fd0062"
+ "ebc030de1219a04c2a8c1b7dd3131e4d6b6caee2e31a5ed41ac1509b2ef1ee2a"
+ "b18364be568ca941c25ecc84ff9d643b5ec1aaae102a20d73f479b780fd6da91"
+ "075212d9eac03a0674d899eba2e431f4c44b615b6ba2232bd4b33baed73d625d",
+ "010001",
+ "198c141e23715a92bccf6a119a5bc11389468d2811f548d727e17b4ab0eb986d"
+ "6f211efb53b71f7ccbea87ee69c75ee615008c5332deb52bf390abdfbfe37d72"
+ "05368159b2638c1de326e21d22251f0fb5848b3bf15005d2a74330f0afe916ee"
+ "62ccc1344d1d83a709e60676273840f7f377424a5e0a4da75f01b31ff76819cf"
+ "9cbfdd215243c3917c03ef38199312e567b3bf7aed3ab457f371ef8a1423f45b"
+ "68c6e282ec111bba2833b987fd69fad83bc1b8c613c5e1ea16c11ed125ea7ec1",
+ {
+ {
+ "OAEP Example 9.1",
+ "f735fd55ba92592c3b52b8f9c4f69aaa1cbef8fe88add095595412467f9cf4ec"
+ "0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6",
+ "8ec965f134a3ec9931e92a1ca0dc8169d5ea705c",
+ "267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4d"
+ "b751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376c"
+ "a7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182"
+ "c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c0"
+ "91ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b554"
+ "90d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72"
+ },{
+ "OAEP Example 9.2",
+ "81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc"
+ "818bf420c54659",
+ "ecb1b8b25fa50cdab08e56042867f4af5826d16c",
+ "93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a1"
+ "4841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f"
+ "5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5f"
+ "cb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d860"
+ "97ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673"
+ "c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8"
+ },{
+ "OAEP Example 9.3",
+ "fd326429df9b890e09b54b18b8f34f1e24",
+ "e89bb032c6ce622cbdb53bc9466014ea77f777c0",
+ "81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba"
+ "5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e"
+ "813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93"
+ "edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f"
+ "20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753e"
+ "aaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3"
+ },{
+ "OAEP Example 9.4",
+ "f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4"
+ "e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e",
+ "606f3b99c0b9ccd771eaa29ea0e4c884f3189ccc",
+ "bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87"
+ "b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446"
+ "ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f497"
+ "7af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b475"
+ "62792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec25"
+ "79c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858"
+ },{
+ "OAEP Example 9.5",
+ "53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef37"
+ "39e7b595abb96e8d55e54f7bd41ab433378ffb911d",
+ "fcbc421402e9ecabc6082afa40ba5f26522c840e",
+ "232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d2"
+ "81b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e"
+ "66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a"
+ "1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8a019edef1bb3accc697cc6"
+ "cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d"
+ "44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e"
+ },{
+ "OAEP Example 9.6",
+ "b6b28ea2198d0c1008bc64",
+ "23aade0e1e08bb9b9a78d2302a52f9c21b2e1ba2",
+ "438cc7dc08a68da249e42505f8573ba60e2c2773d5b290f4cf9dff718e842081"
+ "c383e67024a0f29594ea987b9d25e4b738f285970d195abb3a8c8054e3d79d6b"
+ "9c9a8327ba596f1259e27126674766907d8d582ff3a8476154929adb1e6d1235"
+ "b2ccb4ec8f663ba9cc670a92bebd853c8dbf69c6436d016f61add836e9473245"
+ "0434207f9fd4c43dec2a12a958efa01efe2669899b5e604c255c55fb7166de55"
+ "89e369597bb09168c06dd5db177e06a1740eb2d5c82faeca6d92fcee9931ba9f"
+ }
+ }
+ },
+ {
+ "Example 10: A 2048-bit RSA key pair",
+ "ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8"
+ "df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5"
+ "404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2f"
+ "a1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a0"
+ "3381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600"
+ "c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aef"
+ "a2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88"
+ "d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb",
+ "010001",
+ "056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e59"
+ "6a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d"
+ "19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbe"
+ "be57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f10"
+ "2cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564"
+ "fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c43"
+ "0ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101"
+ "848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e79",
+ {
+ {
+ "OAEP Example 10.1",
+ "8bba6bf82a6c0f86d5f1756e97956870b08953b06b4eb205bc1694ee",
+ "47e1ab7119fee56c95ee5eaad86f40d0aa63bd33",
+ "53ea5dc08cd260fb3b858567287fa91552c30b2febfba213f0ae87702d068d19"
+ "bab07fe574523dfb42139d68c3c5afeee0bfe4cb7969cbf382b804d6e6139614"
+ "4e2d0e60741f8993c3014b58b9b1957a8babcd23af854f4c356fb1662aa72bfc"
+ "c7e586559dc4280d160c126785a723ebeebeff71f11594440aaef87d10793a87"
+ "74a239d4a04c87fe1467b9daf85208ec6c7255794a96cc29142f9a8bd418e3c1"
+ "fd67344b0cd0829df3b2bec60253196293c6b34d3f75d32f213dd45c6273d505"
+ "adf4cced1057cb758fc26aeefa441255ed4e64c199ee075e7f16646182fdb464"
+ "739b68ab5daff0e63e9552016824f054bf4d3c8c90a97bb6b6553284eb429fcc"
+ },{
+ "OAEP Example 10.2",
+ "e6ad181f053b58a904f2457510373e57",
+ "6d17f5b4c1ffac351d195bf7b09d09f09a4079cf",
+ "a2b1a430a9d657e2fa1c2bb5ed43ffb25c05a308fe9093c01031795f58744001"
+ "10828ae58fb9b581ce9dddd3e549ae04a0985459bde6c626594e7b05dc4278b2"
+ "a1465c1368408823c85e96dc66c3a30983c639664fc4569a37fe21e5a195b577"
+ "6eed2df8d8d361af686e750229bbd663f161868a50615e0c337bec0ca35fec0b"
+ "b19c36eb2e0bbcc0582fa1d93aacdb061063f59f2ce1ee43605e5d89eca183d2"
+ "acdfe9f81011022ad3b43a3dd417dac94b4e11ea81b192966e966b182082e719"
+ "64607b4f8002f36299844a11f2ae0faeac2eae70f8f4f98088acdcd0ac556e9f"
+ "ccc511521908fad26f04c64201450305778758b0538bf8b5bb144a828e629795"
+ },{
+ "OAEP Example 10.3",
+ "510a2cf60e866fa2340553c94ea39fbc256311e83e94454b4124",
+ "385387514deccc7c740dd8cdf9daee49a1cbfd54",
+ "9886c3e6764a8b9a84e84148ebd8c3b1aa8050381a78f668714c16d9cfd2a6ed"
+ "c56979c535d9dee3b44b85c18be8928992371711472216d95dda98d2ee8347c9"
+ "b14dffdff84aa48d25ac06f7d7e65398ac967b1ce90925f67dce049b7f812db0"
+ "742997a74d44fe81dbe0e7a3feaf2e5c40af888d550ddbbe3bc20657a29543f8"
+ "fc2913b9bd1a61b2ab2256ec409bbd7dc0d17717ea25c43f42ed27df8738bf4a"
+ "fc6766ff7aff0859555ee283920f4c8a63c4a7340cbafddc339ecdb4b0515002"
+ "f96c932b5b79167af699c0ad3fccfdf0f44e85a70262bf2e18fe34b850589975"
+ "e867ff969d48eabf212271546cdc05a69ecb526e52870c836f307bd798780ede"
+ },{
+ "OAEP Example 10.4",
+ "bcdd190da3b7d300df9a06e22caae2a75f10c91ff667b7c16bde8b53064a2649"
+ "a94045c9",
+ "5caca6a0f764161a9684f85d92b6e0ef37ca8b65",
+ "6318e9fb5c0d05e5307e1683436e903293ac4642358aaa223d7163013aba87e2"
+ "dfda8e60c6860e29a1e92686163ea0b9175f329ca3b131a1edd3a77759a8b97b"
+ "ad6a4f8f4396f28cf6f39ca58112e48160d6e203daa5856f3aca5ffed577af49"
+ "9408e3dfd233e3e604dbe34a9c4c9082de65527cac6331d29dc80e0508a0fa71"
+ "22e7f329f6cca5cfa34d4d1da417805457e008bec549e478ff9e12a763c477d1"
+ "5bbb78f5b69bd57830fc2c4ed686d79bc72a95d85f88134c6b0afe56a8ccfbc8"
+ "55828bb339bd17909cf1d70de3335ae07039093e606d655365de6550b872cd6d"
+ "e1d440ee031b61945f629ad8a353b0d40939e96a3c450d2a8d5eee9f678093c8"
+ },{
+ "OAEP Example 10.5",
+ "a7dd6c7dc24b46f9dd5f1e91ada4c3b3df947e877232a9",
+ "95bca9e3859894b3dd869fa7ecd5bbc6401bf3e4",
+ "75290872ccfd4a4505660d651f56da6daa09ca1301d890632f6a992f3d565cee"
+ "464afded40ed3b5be9356714ea5aa7655f4a1366c2f17c728f6f2c5a5d1f8e28"
+ "429bc4e6f8f2cff8da8dc0e0a9808e45fd09ea2fa40cb2b6ce6ffff5c0e159d1"
+ "1b68d90a85f7b84e103b09e682666480c657505c0929259468a314786d74eab1"
+ "31573cf234bf57db7d9e66cc6748192e002dc0deea930585f0831fdcd9bc33d5"
+ "1f79ed2ffc16bcf4d59812fcebcaa3f9069b0e445686d644c25ccf63b456ee5f"
+ "a6ffe96f19cdf751fed9eaf35957754dbf4bfea5216aa1844dc507cb2d080e72"
+ "2eba150308c2b5ff1193620f1766ecf4481bafb943bd292877f2136ca494aba0"
+ },{
+ "OAEP Example 10.6",
+ "eaf1a73a1b0c4609537de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4634ed0"
+ "0b7c39ec6922d7b8ea2c04ebac",
+ "9f47ddf42e97eea856a9bdbc714eb3ac22f6eb32",
+ "2d207a73432a8fb4c03051b3f73b28a61764098dfa34c47a20995f8115aa6816"
+ "679b557e82dbee584908c6e69782d7deb34dbd65af063d57fca76a5fd069492f"
+ "d6068d9984d209350565a62e5c77f23038c12cb10c6634709b547c46f6b4a709"
+ "bd85ca122d74465ef97762c29763e06dbc7a9e738c78bfca0102dc5e79d65b97"
+ "3f28240caab2e161a78b57d262457ed8195d53e3c7ae9da021883c6db7c24afd"
+ "d2322eac972ad3c354c5fcef1e146c3a0290fb67adf007066e00428d2cec18ce"
+ "58f9328698defef4b2eb5ec76918fde1c198cbb38b7afc67626a9aefec4322bf"
+ "d90d2563481c9a221f78c8272c82d1b62ab914e1c69f6af6ef30ca5260db4a46"
+ }
+ }
+ }
+ };
diff --git a/comm/third_party/libgcrypt/tests/pkcs1v2-pss.h b/comm/third_party/libgcrypt/tests/pkcs1v2-pss.h
new file mode 100644
index 0000000000..cb07858258
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/pkcs1v2-pss.h
@@ -0,0 +1,968 @@
+/* pkcs1v2-pss.h - PSS test vector table
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Manually created from the PSS file in
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip
+ */
+
+ static struct {
+ const char *desc;
+ const char *n, *e, *d;
+ struct {
+ const char *desc;
+ const char *mesg;
+ const char *salt;
+ const char *sign;
+ } m[6];
+ } tbl[] =
+ {
+ {
+ "Example 1: A 1024-bit RSA key pair",
+ "a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991"
+ "d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1df"
+ "d5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f1"
+ "05acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",
+ "010001",
+ "33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e8"
+ "94a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9a"
+ "e55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c"
+ "31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",
+ {
+ {
+ "PSS Example 1.1",
+ "cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b6"
+ "2371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb76"
+ "9757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb0"
+ "61a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d61"
+ "93c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c"
+ "296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16"
+ "be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0",
+ "dee959c7e06411361420ff80185ed57f3e6776af",
+ "9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887"
+ "e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215"
+ "df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65"
+ "984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c"
+ },{
+ "PSS Example 1.2",
+ "851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f"
+ "71a1cca582d43ecc72b1bca16dfc7013226b9e",
+ "ef2869fa40c346cb183dab3d7bffc98fd56df42d",
+ "3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04e"
+ "f29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c45"
+ "17832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b935"
+ "90241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843"
+ },{
+ "PSS Example 1.3",
+ "a4b159941761c40c6a82f2b80d1b94f5aa2654fd17e12d588864679b54cd04ef"
+ "8bd03012be8dc37f4b83af7963faff0dfa225477437c48017ff2be8191cf3955"
+ "fc07356eab3f322f7f620e21d254e5db4324279fe067e0910e2e81ca2cab31c7"
+ "45e67a54058eb50d993cdb9ed0b4d029c06d21a94ca661c3ce27fae1d6cb20f4"
+ "564d66ce4767583d0e5f060215b59017be85ea848939127bd8c9c4d47b51056c"
+ "031cf336f17c9980f3b8f5b9b6878e8b797aa43b882684333e17893fe9caa6aa"
+ "299f7ed1a18ee2c54864b7b2b99b72618fb02574d139ef50f019c9eef4169713"
+ "38e7d470",
+ "710b9c4747d800d4de87f12afdce6df18107cc77",
+ "666026fba71bd3e7cf13157cc2c51a8e4aa684af9778f91849f34335d141c001"
+ "54c4197621f9624a675b5abc22ee7d5baaffaae1c9baca2cc373b3f33e78e614"
+ "3c395a91aa7faca664eb733afd14d8827259d99a7550faca501ef2b04e33c23a"
+ "a51f4b9e8282efdb728cc0ab09405a91607c6369961bc8270d2d4f39fce612b1"
+ },{
+ "PSS Example 1.4",
+ "bc656747fa9eafb3f0",
+ "056f00985de14d8ef5cea9e82f8c27bef720335e",
+ "4609793b23e9d09362dc21bb47da0b4f3a7622649a47d464019b9aeafe53359c"
+ "178c91cd58ba6bcb78be0346a7bc637f4b873d4bab38ee661f199634c547a1ad"
+ "8442e03da015b136e543f7ab07c0c13e4225b8de8cce25d4f6eb8400f81f7e18"
+ "33b7ee6e334d370964ca79fdb872b4d75223b5eeb08101591fb532d155a6de87",
+ },{
+ "PSS Example 1.5",
+ "b45581547e5427770c768e8b82b75564e0ea4e9c32594d6bff706544de0a8776"
+ "c7a80b4576550eee1b2acabc7e8b7d3ef7bb5b03e462c11047eadd00629ae575"
+ "480ac1470fe046f13a2bf5af17921dc4b0aa8b02bee6334911651d7f8525d10f"
+ "32b51d33be520d3ddf5a709955a3dfe78283b9e0ab54046d150c177f037fdccc"
+ "5be4ea5f68b5e5a38c9d7edcccc4975f455a6909b4",
+ "80e70ff86a08de3ec60972b39b4fbfdcea67ae8e",
+ "1d2aad221ca4d31ddf13509239019398e3d14b32dc34dc5af4aeaea3c095af73"
+ "479cf0a45e5629635a53a018377615b16cb9b13b3e09d671eb71e387b8545c59"
+ "60da5a64776e768e82b2c93583bf104c3fdb23512b7b4e89f633dd0063a530db"
+ "4524b01c3f384c09310e315a79dcd3d684022a7f31c865a664e316978b759fad"
+ },{
+ "PSS Example 1.6",
+ "10aae9a0ab0b595d0841207b700d48d75faedde3b775cd6b4cc88ae06e4694ec"
+ "74ba18f8520d4f5ea69cbbe7cc2beba43efdc10215ac4eb32dc302a1f53dc6c4"
+ "352267e7936cfebf7c8d67035784a3909fa859c7b7b59b8e39c5c2349f1886b7"
+ "05a30267d402f7486ab4f58cad5d69adb17ab8cd0ce1caf5025af4ae24b1fb87"
+ "94c6070cc09a51e2f9911311e3877d0044c71c57a993395008806b723ac38373"
+ "d395481818528c1e7053739282053529510e935cd0fa77b8fa53cc2d474bd4fb"
+ "3cc5c672d6ffdc90a00f9848712c4bcfe46c60573659b11e6457e861f0f604b6"
+ "138d144f8ce4e2da73",
+ "a8ab69dd801f0074c2a1fc60649836c616d99681",
+ "2a34f6125e1f6b0bf971e84fbd41c632be8f2c2ace7de8b6926e31ff93e9af98"
+ "7fbc06e51e9be14f5198f91f3f953bd67da60a9df59764c3dc0fe08e1cbef0b7"
+ "5f868d10ad3fba749fef59fb6dac46a0d6e504369331586f58e4628f39aa2789"
+ "82543bc0eeb537dc61958019b394fb273f215858a0a01ac4d650b955c67f4c58"
+ }
+ }
+ },
+ {
+ "Example 2: A 1025-bit RSA key pair",
+ "01d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fe"
+ "d006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c"
+ "7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b47"
+ "2cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33"
+ "c9",
+ "010001",
+ "027d147e4673057377fd1ea201565772176a7dc38358d376045685a2e787c23c"
+ "15576bc16b9f444402d6bfc5d98a3e88ea13ef67c353eca0c0ddba9255bd7b8b"
+ "b50a644afdfd1dd51695b252d22e7318d1b6687a1c10ff75545f3db0fe602d5f"
+ "2b7f294e3601eab7b9d1cecd767f64692e3e536ca2846cb0c2dd486a39fa75b1",
+ {
+ {
+ "PSS Example 2.1",
+ "daba032066263faedb659848115278a52c44faa3a76f37515ed336321072c40a"
+ "9d9b53bc05014078adf520875146aae70ff060226dcb7b1f1fc27e9360",
+ "57bf160bcb02bb1dc7280cf0458530b7d2832ff7",
+ "014c5ba5338328ccc6e7a90bf1c0ab3fd606ff4796d3c12e4b639ed9136a5fec"
+ "6c16d8884bdd99cfdc521456b0742b736868cf90de099adb8d5ffd1deff39ba4"
+ "007ab746cefdb22d7df0e225f54627dc65466131721b90af445363a8358b9f60"
+ "7642f78fab0ab0f43b7168d64bae70d8827848d8ef1e421c5754ddf42c2589b5"
+ "b3"
+ },{
+ "PSS Example 2.2",
+ "e4f8601a8a6da1be34447c0959c058570c3668cfd51dd5f9ccd6ad4411fe8213"
+ "486d78a6c49f93efc2ca2288cebc2b9b60bd04b1e220d86e3d4848d709d032d1"
+ "e8c6a070c6af9a499fcf95354b14ba6127c739de1bb0fd16431e46938aec0cf8"
+ "ad9eb72e832a7035de9b7807bdc0ed8b68eb0f5ac2216be40ce920c0db0eddd3"
+ "860ed788efaccaca502d8f2bd6d1a7c1f41ff46f1681c8f1f818e9c4f6d91a0c"
+ "7803ccc63d76a6544d843e084e363b8acc55aa531733edb5dee5b5196e9f03e8"
+ "b731b3776428d9e457fe3fbcb3db7274442d785890e9cb0854b6444dace791d7"
+ "273de1889719338a77fe",
+ "7f6dd359e604e60870e898e47b19bf2e5a7b2a90",
+ "010991656cca182b7f29d2dbc007e7ae0fec158eb6759cb9c45c5ff87c7635dd"
+ "46d150882f4de1e9ae65e7f7d9018f6836954a47c0a81a8a6b6f83f2944d6081"
+ "b1aa7c759b254b2c34b691da67cc0226e20b2f18b42212761dcd4b908a62b371"
+ "b5918c5742af4b537e296917674fb914194761621cc19a41f6fb953fbcbb649d"
+ "ea"
+ },{
+ "PSS Example 2.3",
+ "52a1d96c8ac39e41e455809801b927a5b445c10d902a0dcd3850d22a66d2bb07"
+ "03e67d5867114595aabf5a7aeb5a8f87034bbb30e13cfd4817a9be7623002360"
+ "6d0286a3faf8a4d22b728ec518079f9e64526e3a0cc7941aa338c437997c680c"
+ "cac67c66bfa1",
+ "fca862068bce2246724b708a0519da17e648688c",
+ "007f0030018f53cdc71f23d03659fde54d4241f758a750b42f185f87578520c3"
+ "0742afd84359b6e6e8d3ed959dc6fe486bedc8e2cf001f63a7abe16256a1b84d"
+ "f0d249fc05d3194ce5f0912742dbbf80dd174f6c51f6bad7f16cf3364eba095a"
+ "06267dc3793803ac7526aebe0a475d38b8c2247ab51c4898df7047dc6adf52c6"
+ "c4"
+ },{
+ "PSS Example 2.4",
+ "a7182c83ac18be6570a106aa9d5c4e3dbbd4afaeb0c60c4a23e1969d79ff",
+ "8070ef2de945c02387684ba0d33096732235d440",
+ "009cd2f4edbe23e12346ae8c76dd9ad3230a62076141f16c152ba18513a48ef6"
+ "f010e0e37fd3df10a1ec629a0cb5a3b5d2893007298c30936a95903b6ba85555"
+ "d9ec3673a06108fd62a2fda56d1ce2e85c4db6b24a81ca3b496c36d4fd06eb7c"
+ "9166d8e94877c42bea622b3bfe9251fdc21d8d5371badad78a488214796335b4"
+ "0b"
+ },{
+ "PSS Example 2.5",
+ "86a83d4a72ee932a4f5630af6579a386b78fe88999e0abd2d49034a4bfc854dd"
+ "94f1094e2e8cd7a179d19588e4aefc1b1bd25e95e3dd461f",
+ "17639a4e88d722c4fca24d079a8b29c32433b0c9",
+ "00ec430824931ebd3baa43034dae98ba646b8c36013d1671c3cf1cf8260c374b"
+ "19f8e1cc8d965012405e7e9bf7378612dfcc85fce12cda11f950bd0ba8876740"
+ "436c1d2595a64a1b32efcfb74a21c873b3cc33aaf4e3dc3953de67f0674c0453"
+ "b4fd9f604406d441b816098cb106fe3472bc251f815f59db2e4378a3addc181e"
+ "cf"
+ },{
+ "PSS Example 2.6",
+
+ "049f9154d871ac4a7c7ab45325ba7545a1ed08f70525b2667cf1",
+ "37810def1055ed922b063df798de5d0aabf886ee",
+ "00475b1648f814a8dc0abdc37b5527f543b666bb6e39d30e5b49d3b876dccc58"
+ "eac14e32a2d55c2616014456ad2f246fc8e3d560da3ddf379a1c0bd200f10221"
+ "df078c219a151bc8d4ec9d2fc2564467811014ef15d8ea01c2ebbff8c2c8efab"
+ "38096e55fcbe3285c7aa558851254faffa92c1c72b78758663ef4582843139d7"
+ "a6"
+ }
+ }
+ },
+ {
+ "Example 3: A 1026-bit RSA key pair",
+ "02f246ef451ed3eebb9a310200cc25859c048e4be798302991112eb68ce6db67"
+ "4e280da21feded1ae74880ca522b18db249385012827c515f0e466a1ffa691d9"
+ "8170574e9d0eadb087586ca48933da3cc953d95bd0ed50de10ddcb6736107d6c"
+ "831c7f663e833ca4c097e700ce0fb945f88fb85fe8e5a773172565b914a471a4"
+ "43",
+ "010001",
+ "651451733b56de5ac0a689a4aeb6e6894a69014e076c88dd7a667eab3232bbcc"
+ "d2fc44ba2fa9c31db46f21edd1fdb23c5c128a5da5bab91e7f952b67759c7cff"
+ "705415ac9fa0907c7ca6178f668fb948d869da4cc3b7356f4008dfd5449d32ee"
+ "02d9a477eb69fc29266e5d9070512375a50fbbcc27e238ad98425f6ebbf88991",
+ {
+ {
+ "PSS Example 3.1",
+ "594b37333bbb2c84524a87c1a01f75fcec0e3256f108e38dca36d70d0057",
+ "f31ad6c8cf89df78ed77feacbcc2f8b0a8e4cfaa",
+ "0088b135fb1794b6b96c4a3e678197f8cac52b64b2fe907d6f27de761124964a"
+ "99a01a882740ecfaed6c01a47464bb05182313c01338a8cd097214cd68ca103b"
+ "d57d3bc9e816213e61d784f182467abf8a01cf253e99a156eaa8e3e1f90e3c6e"
+ "4e3aa2d83ed0345b89fafc9c26077c14b6ac51454fa26e446e3a2f153b2b1679"
+ "7f"
+ },{
+ "PSS Example 3.2",
+ "8b769528884a0d1ffd090cf102993e796dadcfbddd38e44ff6324ca451",
+ "fcf9f0e1f199a3d1d0da681c5b8606fc642939f7",
+ "02a5f0a858a0864a4f65017a7d69454f3f973a2999839b7bbc48bf7864116917"
+ "9556f595fa41f6ff18e286c2783079bc0910ee9cc34f49ba681124f923dfa88f"
+ "426141a368a5f5a930c628c2c3c200e18a7644721a0cbec6dd3f6279bde3e8f2"
+ "be5e2d4ee56f97e7ceaf33054be7042bd91a63bb09f897bd41e81197dee99b11"
+ "af"
+ },{
+ "PSS Example 3.3",
+ "1abdba489c5ada2f995ed16f19d5a94d9e6ec34a8d84f84557d26e5ef9b02b22"
+ "887e3f9a4b690ad1149209c20c61431f0c017c36c2657b35d7b07d3f5ad87085"
+ "07a9c1b831df835a56f831071814ea5d3d8d8f6ade40cba38b42db7a2d3d7a29"
+ "c8f0a79a7838cf58a9757fa2fe4c40df9baa193bfc6f92b123ad57b07ace3e6a"
+ "c068c9f106afd9eeb03b4f37c25dbfbcfb3071f6f9771766d072f3bb070af660"
+ "5532973ae25051",
+ "986e7c43dbb671bd41b9a7f4b6afc80e805f2423",
+ "0244bcd1c8c16955736c803be401272e18cb990811b14f72db964124d5fa7606"
+ "49cbb57afb8755dbb62bf51f466cf23a0a1607576e983d778fceffa92df7548a"
+ "ea8ea4ecad2c29dd9f95bc07fe91ecf8bee255bfe8762fd7690aa9bfa4fa0849"
+ "ef728c2c42c4532364522df2ab7f9f8a03b63f7a499175828668f5ef5a29e380"
+ "2c"
+ },{
+ "PSS Example 3.4",
+ "8fb431f5ee792b6c2ac7db53cc428655aeb32d03f4e889c5c25de683c461b53a"
+ "cf89f9f8d3aabdf6b9f0c2a1de12e15b49edb3919a652fe9491c25a7fce1f722"
+ "c2543608b69dc375ec",
+ "f8312d9c8eea13ec0a4c7b98120c87509087c478",
+ "0196f12a005b98129c8df13c4cb16f8aa887d3c40d96df3a88e7532ef39cd992"
+ "f273abc370bc1be6f097cfebbf0118fd9ef4b927155f3df22b904d90702d1f7b"
+ "a7a52bed8b8942f412cd7bd676c9d18e170391dcd345c06a730964b3f30bcce0"
+ "bb20ba106f9ab0eeb39cf8a6607f75c0347f0af79f16afa081d2c92d1ee6f836"
+ "b8"
+ },{
+ "PSS Example 3.5",
+ "fef4161dfaaf9c5295051dfc1ff3810c8c9ec2e866f7075422c8ec4216a9c4ff"
+ "49427d483cae10c8534a41b2fd15fee06960ec6fb3f7a7e94a2f8a2e3e43dc4a"
+ "40576c3097ac953b1de86f0b4ed36d644f23ae14425529622464ca0cbf0b1741"
+ "347238157fab59e4de5524096d62baec63ac64",
+ "50327efec6292f98019fc67a2a6638563e9b6e2d",
+ "021eca3ab4892264ec22411a752d92221076d4e01c0e6f0dde9afd26ba5acf6d"
+ "739ef987545d16683e5674c9e70f1de649d7e61d48d0caeb4fb4d8b24fba84a6"
+ "e3108fee7d0705973266ac524b4ad280f7ae17dc59d96d3351586b5a3bdb895d"
+ "1e1f7820ac6135d8753480998382ba32b7349559608c38745290a85ef4e9f9bd"
+ "83"
+ },{
+ "PSS Example 3.6",
+ "efd237bb098a443aeeb2bf6c3f8c81b8c01b7fcb3feb",
+ "b0de3fc25b65f5af96b1d5cc3b27d0c6053087b3",
+ "012fafec862f56e9e92f60ab0c77824f4299a0ca734ed26e0644d5d222c7f0bd"
+ "e03964f8e70a5cb65ed44e44d56ae0edf1ff86ca032cc5dd4404dbb76ab85458"
+ "6c44eed8336d08d457ce6c03693b45c0f1efef93624b95b8ec169c616d20e553"
+ "8ebc0b6737a6f82b4bc0570924fc6b35759a3348426279f8b3d7744e2d222426"
+ "ce"
+ }
+ }
+ },
+ {
+ "Example 4: A 1027-bit RSA key pair",
+
+ "054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c42"
+ "1b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba9"
+ "00fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277c"
+ "e559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c37"
+ "05",
+ "010001",
+ "fa041f8cd9697ceed38ec8caa275523b4dd72b09a301d3541d72f5d31c05cbce"
+ "2d6983b36183af10690bd46c46131e35789431a556771dd0049b57461bf060c1"
+ "f68472e8a67c25f357e5b6b4738fa541a730346b4a07649a2dfa806a69c975b6"
+ "aba64678acc7f5913e89c622f2d8abb1e3e32554e39df94ba60c002e387d9011",
+ {
+ {
+ "PSS Example 4.1",
+ "9fb03b827c8217d9",
+ "ed7c98c95f30974fbe4fbddcf0f28d6021c0e91d",
+ "0323d5b7bf20ba4539289ae452ae4297080feff4518423ff4811a817837e7d82"
+ "f1836cdfab54514ff0887bddeebf40bf99b047abc3ecfa6a37a3ef00f4a0c4a8"
+ "8aae0904b745c846c4107e8797723e8ac810d9e3d95dfa30ff4966f4d75d1376"
+ "8d20857f2b1406f264cfe75e27d7652f4b5ed3575f28a702f8c4ed9cf9b2d449"
+ "48"
+ },{
+ "PSS Example 4.2",
+ "0ca2ad77797ece86de5bf768750ddb5ed6a3116ad99bbd17edf7f782f0db1cd0"
+ "5b0f677468c5ea420dc116b10e80d110de2b0461ea14a38be68620392e7e893c"
+ "b4ea9393fb886c20ff790642305bf302003892e54df9f667509dc53920df583f"
+ "50a3dd61abb6fab75d600377e383e6aca6710eeea27156e06752c94ce25ae99f"
+ "cbf8592dbe2d7e27453cb44de07100ebb1a2a19811a478adbeab270f94e8fe36"
+ "9d90b3ca612f9f",
+ "22d71d54363a4217aa55113f059b3384e3e57e44",
+ "049d0185845a264d28feb1e69edaec090609e8e46d93abb38371ce51f4aa65a5"
+ "99bdaaa81d24fba66a08a116cb644f3f1e653d95c89db8bbd5daac2709c89840"
+ "00178410a7c6aa8667ddc38c741f710ec8665aa9052be929d4e3b16782c16621"
+ "14c5414bb0353455c392fc28f3db59054b5f365c49e1d156f876ee10cb4fd705"
+ "98"
+ },{
+ "PSS Example 4.3",
+ "288062afc08fcdb7c5f8650b29837300461dd5676c17a20a3c8fb5148949e3f7"
+ "3d66b3ae82c7240e27c5b3ec4328ee7d6ddf6a6a0c9b5b15bcda196a9d0c76b1"
+ "19d534d85abd123962d583b76ce9d180bce1ca",
+ "4af870fbc6516012ca916c70ba862ac7e8243617",
+ "03fbc410a2ced59500fb99f9e2af2781ada74e13145624602782e2994813eefc"
+ "a0519ecd253b855fb626a90d771eae028b0c47a199cbd9f8e3269734af416359"
+ "9090713a3fa910fa0960652721432b971036a7181a2bc0cab43b0b598bc62174"
+ "61d7db305ff7e954c5b5bb231c39e791af6bcfa76b147b081321f72641482a2a"
+ "ad"
+ },{
+ "PSS Example 4.4",
+ "6f4f9ab9501199cef55c6cf408fe7b36c557c49d420a4763d2463c8ad44b3cfc"
+ "5be2742c0e7d9b0f6608f08c7f47b693ee",
+ "40d2e180fae1eac439c190b56c2c0e14ddf9a226",
+ "0486644bc66bf75d28335a6179b10851f43f09bded9fac1af33252bb9953ba42"
+ "98cd6466b27539a70adaa3f89b3db3c74ab635d122f4ee7ce557a61e59b82ffb"
+ "786630e5f9db53c77d9a0c12fab5958d4c2ce7daa807cd89ba2cc7fcd02ff470"
+ "ca67b229fcce814c852c73cc93bea35be68459ce478e9d4655d121c8472f371d"
+ "4f"
+ },{
+ "PSS Example 4.5",
+ "e17d20385d501955823c3f666254c1d3dd36ad5168b8f18d286fdcf67a7dad94"
+ "097085fab7ed86fe2142a28771717997ef1a7a08884efc39356d76077aaf8245"
+ "9a7fad45848875f2819b098937fe923bcc9dc442d72d754d812025090c9bc03d"
+ "b3080c138dd63b355d0b4b85d6688ac19f4de15084a0ba4e373b93ef4a555096"
+ "691915dc23c00e954cdeb20a47cd55d16c3d8681d46ed7f2ed5ea42795be17ba"
+ "ed25f0f4d113b3636addd585f16a8b5aec0c8fa9c5f03cbf3b9b73",
+ "2497dc2b4615dfae5a663d49ffd56bf7efc11304",
+ "022a80045353904cb30cbb542d7d4990421a6eec16a8029a8422adfd22d6aff8"
+ "c4cc0294af110a0c067ec86a7d364134459bb1ae8ff836d5a8a2579840996b32"
+ "0b19f13a13fad378d931a65625dae2739f0c53670b35d9d3cbac08e733e4ec2b"
+ "83af4b9196d63e7c4ff1ddeae2a122791a125bfea8deb0de8ccf1f4ffaf6e6fb"
+ "0a"
+ },{
+ "PSS Example 4.6",
+ "afbc19d479249018fdf4e09f618726440495de11ddeee38872d775fcea74a238"
+ "96b5343c9c38d46af0dba224d047580cc60a65e9391cf9b59b36a860598d4e82"
+ "16722f993b91cfae87bc255af89a6a199bca4a391eadbc3a24903c0bd667368f"
+ "6be78e3feabfb4ffd463122763740ffbbefeab9a25564bc5d1c24c93e422f750"
+ "73e2ad72bf45b10df00b52a147128e73fee33fa3f0577d77f80fbc2df1bed313"
+ "290c12777f50",
+ "a334db6faebf11081a04f87c2d621cdec7930b9b",
+ "00938dcb6d583046065f69c78da7a1f1757066a7fa75125a9d2929f0b79a60b6"
+ "27b082f11f5b196f28eb9daa6f21c05e5140f6aef1737d2023075c05ecf04a02"
+ "8c686a2ab3e7d5a0664f295ce12995e890908b6ad21f0839eb65b70393a7b5af"
+ "d9871de0caa0cedec5b819626756209d13ab1e7bb9546a26ff37e9a51af9fd56"
+ "2e"
+ }
+ }
+ },
+ {
+ "Example 5: A 1028-bit RSA key pair",
+ "0d10f661f29940f5ed39aa260966deb47843679d2b6fb25b3de370f3ac7c1991"
+ "6391fd25fb527ebfa6a4b4df45a1759d996c4bb4ebd18828c44fc52d01918717"
+ "40525f47a4b0cc8da325ed8aa676b0d0f626e0a77f07692170acac8082f42faa"
+ "7dc7cd123e730e31a87985204cabcbe6670d43a2dd2b2ddef5e05392fc213bc5"
+ "07",
+ "010001",
+ "03ce08b104fff396a979bd3e4e46925b6319ddb63acbcfd819f17d16b8077b3a"
+ "87101ff34b77fe48b8b205a96e9151ba8ecea64d0cce7b23c3e6a6b83058bc49"
+ "dae816ae736db5a4708e2ad435232b567f9096ce59ff28061e79ab1c02d717e6"
+ "b23cea6db8eb5192fa7c1eab227dba74621c45601896eef13792c8440beb15aa"
+ "c1",
+ {
+ {
+ "PSS Example 5.1",
+ "30c7d557458b436decfdc14d06cb7b96b06718c48d7de57482a868ae7f065870"
+ "a6216506d11b779323dfdf046cf5775129134b4d5689e4d9c0ce1e12d7d4b06c"
+ "b5fc5820decfa41baf59bf257b32f025b7679b445b9499c92555145885992f1b"
+ "76f84891ee4d3be0f5150fd5901e3a4c8ed43fd36b61d022e65ad5008dbf3329"
+ "3c22bfbfd07321f0f1d5fa9fdf0014c2fcb0358aad0e354b0d29",
+ "081b233b43567750bd6e78f396a88b9f6a445151",
+ "0ba373f76e0921b70a8fbfe622f0bf77b28a3db98e361051c3d7cb92ad045291"
+ "5a4de9c01722f6823eeb6adf7e0ca8290f5de3e549890ac2a3c5950ab217ba58"
+ "590894952de96f8df111b2575215da6c161590c745be612476ee578ed384ab33"
+ "e3ece97481a252f5c79a98b5532ae00cdd62f2ecc0cd1baefe80d80b962193ec"
+ "1d"
+ },{
+ "PSS Example 5.2",
+ "e7b32e1556ea1b2795046ac69739d22ac8966bf11c116f614b166740e96b9065"
+ "3e5750945fcf772186c03790a07fda323e1a61916b06ee2157db3dff80d67d5e"
+ "39a53ae268c8f09ed99a732005b0bc6a04af4e08d57a00e7201b3060efaadb73"
+ "113bfc087fd837093aa25235b8c149f56215f031c24ad5bde7f29960df7d5240"
+ "70f7449c6f785084be1a0f733047f336f9154738674547db02a9f44dfc6e6030"
+ "1081e1ce99847f3b5b601ff06b4d5776a9740b9aa0d34058fd3b906e4f7859df"
+ "b07d7173e5e6f6350adac21f27b2307469",
+ "bd0ce19549d0700120cbe51077dbbbb00a8d8b09",
+ "08180de825e4b8b014a32da8ba761555921204f2f90d5f24b712908ff84f3e22"
+ "0ad17997c0dd6e706630ba3e84add4d5e7ab004e58074b549709565d43ad9e97"
+ "b5a7a1a29e85b9f90f4aafcdf58321de8c5974ef9abf2d526f33c0f2f82e95d1"
+ "58ea6b81f1736db8d1af3d6ac6a83b32d18bae0ff1b2fe27de4c76ed8c7980a3"
+ "4e"
+ },{
+ "PSS Example 5.3",
+ "8d8396e36507fe1ef6a19017548e0c716674c2fec233adb2f775665ec41f2bd0"
+ "ba396b061a9daa7e866f7c23fd3531954300a342f924535ea1498c48f6c87993"
+ "2865fc02000c528723b7ad0335745b51209a0afed932af8f0887c219004d2abd"
+ "894ea92559ee3198af3a734fe9b9638c263a728ad95a5ae8ce3eb15839f3aa78"
+ "52bb390706e7760e43a71291a2e3f827237deda851874c517665f545f27238df"
+ "86557f375d09ccd8bd15d8ccf61f5d78ca5c7f5cde782e6bf5d0057056d4bad9"
+ "8b3d2f9575e824ab7a33ff57b0ac100ab0d6ead7aa0b50f6e4d3e5ec0b966b",
+ "815779a91b3a8bd049bf2aeb920142772222c9ca",
+ "05e0fdbdf6f756ef733185ccfa8ced2eb6d029d9d56e35561b5db8e70257ee6f"
+ "d019d2f0bbf669fe9b9821e78df6d41e31608d58280f318ee34f559941c8df13"
+ "287574bac000b7e58dc4f414ba49fb127f9d0f8936638c76e85356c994f79750"
+ "f7fa3cf4fd482df75e3fb9978cd061f7abb17572e6e63e0bde12cbdcf18c68b9"
+ "79"
+ },{
+ "PSS Example 5.4",
+ "328c659e0a6437433cceb73c14",
+ "9aec4a7480d5bbc42920d7ca235db674989c9aac",
+ "0bc989853bc2ea86873271ce183a923ab65e8a53100e6df5d87a24c4194eb797"
+ "813ee2a187c097dd872d591da60c568605dd7e742d5af4e33b11678ccb639032"
+ "04a3d080b0902c89aba8868f009c0f1c0cb85810bbdd29121abb8471ff2d39e4"
+ "9fd92d56c655c8e037ad18fafbdc92c95863f7f61ea9efa28fea401369d19dae"
+ "a1"
+ },{
+ "PSS Example 5.5",
+ "f37b962379a47d415a376eec8973150bcb34edd5ab654041b61430560c214458"
+ "2ba133c867d852d6b8e23321901302ecb45b09ec88b1527178fa043263f3067d"
+ "9ffe973032a99f4cb08ad2c7e0a2456cdd57a7df56fe6053527a5aeb67d7e552"
+ "063c1ca97b1beffa7b39e997caf27878ea0f62cbebc8c21df4c889a202851e94"
+ "9088490c249b6e9acf1d8063f5be2343989bf95c4da01a2be78b4ab6b378015b"
+ "c37957f76948b5e58e440c28453d40d7cfd57e7d690600474ab5e75973b1ea0c"
+ "5f1e45d14190afe2f4eb6d3bdf71f1d2f8bb156a1c295d04aaeb9d689dce79ed"
+ "62bc443e",
+ "e20c1e9878512c39970f58375e1549a68b64f31d",
+ "0aefa943b698b9609edf898ad22744ac28dc239497cea369cbbd84f65c95c0ad"
+ "776b594740164b59a739c6ff7c2f07c7c077a86d95238fe51e1fcf33574a4ae0"
+ "684b42a3f6bf677d91820ca89874467b2c23add77969c80717430d0efc1d3695"
+ "892ce855cb7f7011630f4df26def8ddf36fc23905f57fa6243a485c770d5681f"
+ "cd"
+ },{
+ "PSS Example 5.6",
+ "c6103c330c1ef718c141e47b8fa859be4d5b96259e7d142070ecd485839dba5a"
+ "8369c17c1114035e532d195c74f44a0476a2d3e8a4da210016caced0e367cb86"
+ "7710a4b5aa2df2b8e5daf5fdc647807d4d5ebb6c56b9763ccdae4dea3308eb0a"
+ "c2a89501cb209d2639fa5bf87ce790747d3cb2d295e84564f2f637824f0c1302"
+ "8129b0aa4a422d162282",
+ "23291e4a3307e8bbb776623ab34e4a5f4cc8a8db",
+ "02802dccfa8dfaf5279bf0b4a29ba1b157611faeaaf419b8919d15941900c133"
+ "9e7e92e6fae562c53e6cc8e84104b110bce03ad18525e3c49a0eadad5d3f28f2"
+ "44a8ed89edbafbb686277cfa8ae909714d6b28f4bf8e293aa04c41efe7c0a812"
+ "66d5c061e2575be032aa464674ff71626219bd74cc45f0e7ed4e3ff96eee758e"
+ "8f"
+ }
+ }
+ },
+ {
+ "Example 6: A 1029-bit RSA key pair",
+ "164ca31cff609f3a0e7101b039f2e4fe6dd37519ab98598d179e174996598071"
+ "f47d3a04559158d7be373cf1aa53f0aa6ef09039e5678c2a4c63900514c8c4f8"
+ "aaed5de12a5f10b09c311af8c0ffb5b7a297f2efc63b8d6b0510931f0b98e48b"
+ "f5fc6ec4e7b8db1ffaeb08c38e02adb8f03a48229c99e969431f61cb8c4dc698"
+ "d1",
+ "010001",
+ "03b664ee3b7566723fc6eaf28abb430a3980f1126c81de8ad709eab39ac9dcd0"
+ "b1550b3729d87068e952009df544534c1f50829a78f4591eb8fd57140426a6bb"
+ "0405b6a6f51a57d9267b7bbc653391a699a2a90dac8ae226bcc60fa8cd934c73"
+ "c7b03b1f6b818158631838a8612e6e6ea92be24f8324faf5b1fd8587225267ba"
+ "6f",
+ {
+ {
+ "PSS Example 6.1",
+ "0a20b774addc2fa51245ed7cb9da609e50cac6636a52543f97458eed7340f8d5"
+ "3ffc64918f949078ee03ef60d42b5fec246050bd5505cd8cb597bad3c4e713b0"
+ "ef30644e76adabb0de01a1561efb255158c74fc801e6e919e581b46f0f0ddd08"
+ "e4f34c7810b5ed8318f91d7c8c",
+ "5b4ea2ef629cc22f3b538e016904b47b1e40bfd5",
+ "04c0cfacec04e5badbece159a5a1103f69b3f32ba593cb4cc4b1b7ab455916a9"
+ "6a27cd2678ea0f46ba37f7fc9c86325f29733b389f1d97f43e7201c0f348fc45"
+ "fe42892335362eee018b5b161f2f9393031225c713012a576bc88e2305248986"
+ "8d9010cbf033ecc568e8bc152bdc59d560e41291915d28565208e22aeec9ef85"
+ "d1"
+ },{
+ "PSS Example 6.2",
+ "2aaff6631f621ce615760a9ebce94bb333077ad86488c861d4b76d29c1f48746"
+ "c611ae1e03ced4445d7cfa1fe5f62e1b3f08452bde3b6ef81973bafbb57f97bc"
+ "eef873985395b8260589aa88cb7db50ab469262e551bdcd9a56f275a0ac4fe48"
+ "4700c35f3dbf2b469ede864741b86fa59172a360ba95a02e139be50ddfb7cf0b"
+ "42faeabbfbbaa86a4497699c4f2dfd5b08406af7e14144427c253ec0efa20eaf"
+ "9a8be8cd49ce1f1bc4e93e619cf2aa8ed4fb39bc8590d0f7b96488f7317ac9ab"
+ "f7bee4e3a0e715",
+ "83146a9e782722c28b014f98b4267bda2ac9504f",
+ "0a2314250cf52b6e4e908de5b35646bcaa24361da8160fb0f9257590ab3ace42"
+ "b0dc3e77ad2db7c203a20bd952fbb56b1567046ecfaa933d7b1000c3de9ff05b"
+ "7d989ba46fd43bc4c2d0a3986b7ffa13471d37eb5b47d64707bd290cfd6a9f39"
+ "3ad08ec1e3bd71bb5792615035cdaf2d8929aed3be098379377e777ce79aaa47"
+ "73"
+ },{
+ "PSS Example 6.3",
+ "0f6195d04a6e6fc7e2c9600dbf840c39ea8d4d624fd53507016b0e26858a5e0a"
+ "ecd7ada543ae5c0ab3a62599cba0a54e6bf446e262f989978f9ddf5e9a41",
+ "a87b8aed07d7b8e2daf14ddca4ac68c4d0aabff8",
+ "086df6b500098c120f24ff8423f727d9c61a5c9007d3b6a31ce7cf8f3cbec1a2"
+ "6bb20e2bd4a046793299e03e37a21b40194fb045f90b18bf20a47992ccd799cf"
+ "9c059c299c0526854954aade8a6ad9d97ec91a1145383f42468b231f4d72f237"
+ "06d9853c3fa43ce8ace8bfe7484987a1ec6a16c8daf81f7c8bf42774707a9df4"
+ "56"
+ },{
+ "PSS Example 6.4",
+ "337d25fe9810ebca0de4d4658d3ceb8e0fe4c066aba3bcc48b105d3bf7e0257d"
+ "44fecea6596f4d0c59a08402833678f70620f9138dfeb7ded905e4a6d5f05c47"
+ "3d55936652e2a5df43c0cfda7bacaf3087f4524b06cf42157d01539739f7fdde"
+ "c9d58125df31a32eab06c19b71f1d5bf",
+ "a37932f8a7494a942d6f767438e724d6d0c0ef18",
+ "0b5b11ad549863ffa9c51a14a1106c2a72cc8b646e5c7262509786105a984776"
+ "534ca9b54c1cc64bf2d5a44fd7e8a69db699d5ea52087a4748fd2abc1afed1e5"
+ "d6f7c89025530bdaa2213d7e030fa55df6f34bcf1ce46d2edf4e3ae4f3b01891"
+ "a068c9e3a44bbc43133edad6ecb9f35400c4252a5762d65744b99cb9f4c55932"
+ "9f"
+ },{
+ "PSS Example 6.5",
+ "84ec502b072e8287789d8f9235829ea3b187afd4d4c785611bda5f9eb3cb9671"
+ "7efa7007227f1c08cbcb972e667235e0fb7d431a6570326d2ecce35adb373dc7"
+ "53b3be5f829b89175493193fab16badb41371b3aac0ae670076f24bef420c135"
+ "add7cee8d35fbc944d79fafb9e307a13b0f556cb654a06f973ed22672330197e"
+ "f5a748bf826a5db2383a25364b686b9372bb2339aeb1ac9e9889327d016f1670"
+ "776db06201adbdcaf8a5e3b74e108b73",
+ "7b790c1d62f7b84e94df6af28917cf571018110e",
+ "02d71fa9b53e4654fefb7f08385cf6b0ae3a817942ebf66c35ac67f0b069952a"
+ "3ce9c7e1f1b02e480a9500836de5d64cdb7ecde04542f7a79988787e24c2ba05"
+ "f5fd482c023ed5c30e04839dc44bed2a3a3a4fee01113c891a47d32eb8025c28"
+ "cb050b5cdb576c70fe76ef523405c08417faf350b037a43c379339fcb18d3a35"
+ "6b"
+ },{
+ "PSS Example 6.6",
+ "9906d89f97a9fdedd3ccd824db687326f30f00aa25a7fca2afcb3b0f86cd41e7"
+ "3f0e8ff7d2d83f59e28ed31a5a0d551523374de22e4c7e8ff568b386ee3dc411"
+ "63f10bf67bb006261c9082f9af90bf1d9049a6b9fae71c7f84fbe6e55f02789d"
+ "e774f230f115026a4b4e96c55b04a95da3aacbb2cece8f81764a1f1c99515411"
+ "087cf7d34aeded0932c183",
+ "fbbe059025b69b89fb14ae2289e7aaafe60c0fcd",
+ "0a40a16e2fe2b38d1df90546167cf9469c9e3c3681a3442b4b2c2f581deb385c"
+ "e99fc6188bb02a841d56e76d301891e24560550fcc2a26b55f4ccb26d837d350"
+ "a154bcaca8392d98fa67959e9727b78cad03269f56968fc56b68bd679926d83c"
+ "c9cb215550645ccda31c760ff35888943d2d8a1d351e81e5d07b86182e751081"
+ "ef"
+ }
+ }
+ },
+ {
+ "Example 7: A 1030-bit RSA key pair",
+ "37c9da4a66c8c408b8da27d0c9d79f8ccb1eafc1d2fe48746d940b7c4ef5dee1"
+ "8ad12647cefaa0c4b3188b221c515386759b93f02024b25ab9242f8357d8f3fd"
+ "49640ee5e643eaf6c64deefa7089727c8ff03993333915c6ef21bf5975b6e50d"
+ "118b51008ec33e9f01a0a545a10a836a43ddbca9d8b5c5d3548022d7064ea29a"
+ "b3",
+ "010001",
+ "3bed999052d957bc06d651eef6e3a98094b1621bd38b5449bd6c4aea3de7e084"
+ "679a4484ded25be0f0826cf3377825414b14d4d61db14de626fbb80e5f4faec9"
+ "56f9a0a2d24f99576380f084eb62e46a57d554278b535626193ce02060575eb6"
+ "6c5798d36f6c5d40fb00d809b42a73102c1c74ee95bd71420fffef6318b52c29",
+ {
+ {
+ "PSS Example 7.1",
+ "9ead0e01945640674eb41cad435e2374eaefa8ad7197d97913c44957d8d83f40"
+ "d76ee60e39bf9c0f9eaf3021421a074d1ade962c6e9d3dc3bb174fe4dfe652b0"
+ "9115495b8fd2794174020a0602b5ca51848cfc96ce5eb57fc0a2adc1dda36a7c"
+ "c452641a14911b37e45bfa11daa5c7ecdb74f6d0100d1d3e39e752800e203397"
+ "de0233077b9a88855537fae927f924380d780f98e18dcff39c5ea741b17d6fdd"
+ "1885bc9d581482d771ceb562d78a8bf88f0c75b11363e5e36cd479ceb0545f9d"
+ "a84203e0e6e508375cc9e844b88b7ac7a0a201ea0f1bee9a2c577920ca02c01b"
+ "9d8320e974a56f4efb5763b96255abbf8037bf1802cf018f56379493e569a9",
+ "b7867a59958cb54328f8775e6546ec06d27eaa50",
+ "187f390723c8902591f0154bae6d4ecbffe067f0e8b795476ea4f4d51ccc8105"
+ "20bb3ca9bca7d0b1f2ea8a17d873fa27570acd642e3808561cb9e975ccfd80b2"
+ "3dc5771cdb3306a5f23159dacbd3aa2db93d46d766e09ed15d900ad897a8d274"
+ "dc26b47e994a27e97e2268a766533ae4b5e42a2fcaf755c1c4794b294c605558"
+ "23"
+ },{
+ "PSS Example 7.2",
+ "8d80d2d08dbd19c154df3f14673a14bd03735231f24e86bf153d0e69e74cbff7"
+ "b1836e664de83f680124370fc0f96c9b65c07a366b644c4ab3",
+ "0c09582266df086310821ba7e18df64dfee6de09",
+ "10fd89768a60a67788abb5856a787c8561f3edcf9a83e898f7dc87ab8cce7942"
+ "9b43e56906941a886194f137e591fe7c339555361fbbe1f24feb2d4bcdb80601"
+ "f3096bc9132deea60ae13082f44f9ad41cd628936a4d51176e42fc59cb76db81"
+ "5ce5ab4db99a104aafea68f5d330329ebf258d4ede16064bd1d00393d5e1570e"
+ "b8"
+ },{
+ "PSS Example 7.3",
+ "808405cdfc1a58b9bb0397c720722a81fffb76278f335917ef9c473814b3e016"
+ "ba2973cd2765f8f3f82d6cc38aa7f8551827fe8d1e3884b7e61c94683b8f82f1"
+ "843bdae2257eeec9812ad4c2cf283c34e0b0ae0fe3cb990cf88f2ef9",
+ "28039dcfe106d3b8296611258c4a56651c9e92dd",
+ "2b31fde99859b977aa09586d8e274662b25a2a640640b457f594051cb1e7f7a9"
+ "11865455242926cf88fe80dfa3a75ba9689844a11e634a82b075afbd69c12a0d"
+ "f9d25f84ad4945df3dc8fe90c3cefdf26e95f0534304b5bdba20d3e5640a2ebf"
+ "b898aac35ae40f26fce5563c2f9f24f3042af76f3c7072d687bbfb959a88460a"
+ "f1"
+ },{
+ "PSS Example 7.4",
+ "f337b9bad937de22a1a052dff11134a8ce26976202981939b91e0715ae5e6096"
+ "49da1adfcef3f4cca59b238360e7d1e496c7bf4b204b5acff9bbd6166a1d87a3"
+ "6ef2247373751039f8a800b8399807b3a85f44893497c0d05fb7017b82228152"
+ "de6f25e6116dcc7503c786c875c28f3aa607e94ab0f19863ab1b5073770b0cd5"
+ "f533acde30c6fb953cf3da680264e30fc11bff9a19bffab4779b6223c3fb3fe0"
+ "f71abade4eb7c09c41e24c22d23fa148e6a173feb63984d1bc6ee3a02d915b75"
+ "2ceaf92a3015eceb38ca586c6801b37c34cefb2cff25ea23c08662dcab26a7a9"
+ "3a285d05d3044c",
+ "a77821ebbbef24628e4e12e1d0ea96de398f7b0f",
+ "32c7ca38ff26949a15000c4ba04b2b13b35a3810e568184d7ecabaa166b7ffab"
+ "ddf2b6cf4ba07124923790f2e5b1a5be040aea36fe132ec130e1f10567982d17"
+ "ac3e89b8d26c3094034e762d2e031264f01170beecb3d1439e05846f25458367"
+ "a7d9c02060444672671e64e877864559ca19b2074d588a281b5804d23772fbbe"
+ "19"
+ },{
+ "PSS Example 7.5",
+ "45013cebafd960b255476a8e2598b9aa32efbe6dc1f34f4a498d8cf5a2b4548d"
+ "08c55d5f95f7bcc9619163056f2d58b52fa032",
+ "9d5ad8eb452134b65dc3a98b6a73b5f741609cd6",
+ "07eb651d75f1b52bc263b2e198336e99fbebc4f332049a922a10815607ee2d98"
+ "9db3a4495b7dccd38f58a211fb7e193171a3d891132437ebca44f318b280509e"
+ "52b5fa98fcce8205d9697c8ee4b7ff59d4c59c79038a1970bd2a0d451ecdc5ef"
+ "11d9979c9d35f8c70a6163717607890d586a7c6dc01c79f86a8f28e85235f8c2"
+ "f1"
+ },{
+ "PSS Example 7.6",
+ "2358097086c899323e75d9c90d0c09f12d9d54edfbdf70a9c2eb5a04d8f36b9b"
+ "2bdf2aabe0a5bda1968937f9d6ebd3b6b257efb3136d4131f9acb59b85e2602c"
+ "2a3fcdc835494a1f4e5ec18b226c80232b36a75a45fdf09a7ea9e98efbde1450"
+ "d1194bf12e15a4c5f9eb5c0bce5269e0c3b28cfab655d81a61a20b4be2f54459"
+ "bb25a0db94c52218be109a7426de83014424789aaa90e5056e632a698115e282"
+ "c1a56410f26c2072f193481a9dcd880572005e64f4082ecf",
+ "3f2efc595880a7d47fcf3cba04983ea54c4b73fb",
+ "18da3cdcfe79bfb77fd9c32f377ad399146f0a8e810620233271a6e3ed324890"
+ "3f5cdc92dc79b55d3e11615aa056a795853792a3998c349ca5c457e8ca7d29d7"
+ "96aa24f83491709befcfb1510ea513c92829a3f00b104f655634f320752e130e"
+ "c0ccf6754ff893db302932bb025eb60e87822598fc619e0e981737a9a4c4152d"
+ "33"
+ }
+ }
+ },
+ {
+ "Example 8: A 1031-bit RSA key pair",
+ "495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6f"
+ "bbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2"
+ "d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaa"
+ "dced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada073"
+ "3f",
+ "010001",
+ "6c66ffe98980c38fcdeab5159898836165f4b4b817c4f6a8d486ee4ea9130fe9"
+ "b9092bd136d184f95f504a607eac565846d2fdd6597a8967c7396ef95a6eeebb"
+ "4578a643966dca4d8ee3de842de63279c618159c1ab54a89437b6a6120e4930a"
+ "fb52a4ba6ced8a4947ac64b30a3497cbe701c2d6266d517219ad0ec6d347dbe9",
+ {
+ {
+ "PSS Example 8.1",
+ "81332f4be62948415ea1d899792eeacf6c6e1db1da8be13b5cea41db2fed4670"
+ "92e1ff398914c714259775f595f8547f735692a575e6923af78f22c6997ddb90"
+ "fb6f72d7bb0dd5744a31decd3dc3685849836ed34aec596304ad11843c4f8848"
+ "9f209735f5fb7fdaf7cec8addc5818168f880acbf490d51005b7a8e84e43e542"
+ "87977571dd99eea4b161eb2df1f5108f12a4142a83322edb05a75487a3435c9a"
+ "78ce53ed93bc550857d7a9fb",
+ "1d65491d79c864b373009be6f6f2467bac4c78fa",
+ "0262ac254bfa77f3c1aca22c5179f8f040422b3c5bafd40a8f21cf0fa5a667cc"
+ "d5993d42dbafb409c520e25fce2b1ee1e716577f1efa17f3da28052f40f0419b"
+ "23106d7845aaf01125b698e7a4dfe92d3967bb00c4d0d35ba3552ab9a8b3eef0"
+ "7c7fecdbc5424ac4db1e20cb37d0b2744769940ea907e17fbbca673b20522380"
+ "c5"
+ },{
+ "PSS Example 8.2",
+ "e2f96eaf0e05e7ba326ecca0ba7fd2f7c02356f3cede9d0faabf4fcc8e60a973"
+ "e5595fd9ea08",
+ "435c098aa9909eb2377f1248b091b68987ff1838",
+ "2707b9ad5115c58c94e932e8ec0a280f56339e44a1b58d4ddcff2f312e5f34dc"
+ "fe39e89c6a94dcee86dbbdae5b79ba4e0819a9e7bfd9d982e7ee6c86ee68396e"
+ "8b3a14c9c8f34b178eb741f9d3f121109bf5c8172fada2e768f9ea1433032c00"
+ "4a8aa07eb990000a48dc94c8bac8aabe2b09b1aa46c0a2aa0e12f63fbba775ba"
+ "7e"
+ },{
+ "PSS Example 8.3",
+ "e35c6ed98f64a6d5a648fcab8adb16331db32e5d15c74a40edf94c3dc4a4de79"
+ "2d190889f20f1e24ed12054a6b28798fcb42d1c548769b734c96373142092aed"
+ "277603f4738df4dc1446586d0ec64da4fb60536db2ae17fc7e3c04bbfbbbd907"
+ "bf117c08636fa16f95f51a6216934d3e34f85030f17bbbc5ba69144058aff081"
+ "e0b19cf03c17195c5e888ba58f6fe0a02e5c3bda9719a7",
+ "c6ebbe76df0c4aea32c474175b2f136862d04529",
+ "2ad20509d78cf26d1b6c406146086e4b0c91a91c2bd164c87b966b8faa42aa0c"
+ "a446022323ba4b1a1b89706d7f4c3be57d7b69702d168ab5955ee290356b8c4a"
+ "29ed467d547ec23cbadf286ccb5863c6679da467fc9324a151c7ec55aac6db40"
+ "84f82726825cfe1aa421bc64049fb42f23148f9c25b2dc300437c38d428aa75f"
+ "96"
+ },{
+ "PSS Example 8.4",
+ "dbc5f750a7a14be2b93e838d18d14a8695e52e8add9c0ac733b8f56d2747e529"
+ "a0cca532dd49b902aefed514447f9e81d16195c2853868cb9b30f7d0d495c69d"
+ "01b5c5d50b27045db3866c2324a44a110b1717746de457d1c8c45c3cd2a92970"
+ "c3d59632055d4c98a41d6e99e2a3ddd5f7f9979ab3cd18f37505d25141de2a1b"
+ "ff17b3a7dce9419ecc385cf11d72840f19953fd0509251f6cafde2893d0e75c7"
+ "81ba7a5012ca401a4fa99e04b3c3249f926d5afe82cc87dab22c3c1b105de48e"
+ "34ace9c9124e59597ac7ebf8",
+ "021fdcc6ebb5e19b1cb16e9c67f27681657fe20a",
+ "1e24e6e58628e5175044a9eb6d837d48af1260b0520e87327de7897ee4d5b9f0"
+ "df0be3e09ed4dea8c1454ff3423bb08e1793245a9df8bf6ab3968c8eddc3b532"
+ "8571c77f091cc578576912dfebd164b9de5454fe0be1c1f6385b328360ce67ec"
+ "7a05f6e30eb45c17c48ac70041d2cab67f0a2ae7aafdcc8d245ea3442a6300cc"
+ "c7"
+ },{
+ "PSS Example 8.5",
+ "04dc251be72e88e5723485b6383a637e2fefe07660c519a560b8bc18bdedb86e"
+ "ae2364ea53ba9dca6eb3d2e7d6b806af42b3e87f291b4a8881d5bf572cc9a85e"
+ "19c86acb28f098f9da0383c566d3c0f58cfd8f395dcf602e5cd40e8c7183f714"
+ "996e2297ef",
+ "c558d7167cbb4508ada042971e71b1377eea4269",
+ "33341ba3576a130a50e2a5cf8679224388d5693f5accc235ac95add68e5eb1ee"
+ "c31666d0ca7a1cda6f70a1aa762c05752a51950cdb8af3c5379f18cfe6b5bc55"
+ "a4648226a15e912ef19ad77adeea911d67cfefd69ba43fa4119135ff642117ba"
+ "985a7e0100325e9519f1ca6a9216bda055b5785015291125e90dcd07a2ca9673"
+ "ee"
+ },{
+ "PSS Example 8.6",
+ "0ea37df9a6fea4a8b610373c24cf390c20fa6e2135c400c8a34f5c183a7e8ea4"
+ "c9ae090ed31759f42dc77719cca400ecdcc517acfc7ac6902675b2ef30c50966"
+ "5f3321482fc69a9fb570d15e01c845d0d8e50d2a24cbf1cf0e714975a5db7b18"
+ "d9e9e9cb91b5cb16869060ed18b7b56245503f0caf90352b8de81cb5a1d9c633"
+ "6092f0cd",
+ "76fd4e64fdc98eb927a0403e35a084e76ba9f92a",
+ "1ed1d848fb1edb44129bd9b354795af97a069a7a00d0151048593e0c72c3517f"
+ "f9ff2a41d0cb5a0ac860d736a199704f7cb6a53986a88bbd8abcc0076a2ce847"
+ "880031525d449da2ac78356374c536e343faa7cba42a5aaa6506087791c06a8e"
+ "989335aed19bfab2d5e67e27fb0c2875af896c21b6e8e7309d04e4f6727e6946"
+ "3e"
+ }
+ }
+ },
+ {
+ "Example 9: A 1536-bit RSA key pair",
+ "e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b"
+ "5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268"
+ "352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbc"
+ "ec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614"
+ "833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb39702"
+ "7357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b",
+ "010001",
+ "6a7fd84fb85fad073b34406db74f8d61a6abc12196a961dd79565e9da6e5187b"
+ "ce2d980250f7359575359270d91590bb0e427c71460b55d51410b191bcf309fe"
+ "a131a92c8e702738fa719f1e0041f52e40e91f229f4d96a1e6f172e15596b451"
+ "0a6daec26105f2bebc53316b87bdf21311666070e8dfee69d52c71a976caae79"
+ "c72b68d28580dc686d9f5129d225f82b3d615513a882b3db91416b48ce088882"
+ "13e37eeb9af800d81cab328ce420689903c00c7b5fd31b75503a6d419684d629",
+ {
+ {
+ "PSS Example 9.1",
+ "a88e265855e9d7ca36c68795f0b31b591cd6587c71d060a0b3f7f3eaef437959"
+ "22028bc2b6ad467cfc2d7f659c5385aa70ba3672cdde4cfe4970cc7904601b27"
+ "8872bf51321c4a972f3c95570f3445d4f57980e0f20df54846e6a52c668f1288"
+ "c03f95006ea32f562d40d52af9feb32f0fa06db65b588a237b34e592d55cf979"
+ "f903a642ef64d2ed542aa8c77dc1dd762f45a59303ed75e541ca271e2b60ca70"
+ "9e44fa0661131e8d5d4163fd8d398566ce26de8730e72f9cca737641c2441594"
+ "20637028df0a18079d6208ea8b4711a2c750f5",
+ "c0a425313df8d7564bd2434d311523d5257eed80",
+ "586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef"
+ "589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d1"
+ "3dfbf095bf599e0d9686948c1964747b67e89c9aba5cd85016236f566cc5802c"
+ "b13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d231627"
+ "9edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f611"
+ "21f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e"
+ },{
+ "PSS Example 9.2",
+ "c8c9c6af04acda414d227ef23e0820c3732c500dc87275e95b0d095413993c26"
+ "58bc1d988581ba879c2d201f14cb88ced153a01969a7bf0a7be79c84c1486bc1"
+ "2b3fa6c59871b6827c8ce253ca5fefa8a8c690bf326e8e37cdb96d90a82ebab6"
+ "9f86350e1822e8bd536a2e",
+ "b307c43b4850a8dac2f15f32e37839ef8c5c0e91",
+ "80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66d"
+ "d7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f"
+ "7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546"
+ "bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83ea"
+ "e46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee"
+ "361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958"
+ },{
+ "PSS Example 9.3",
+ "0afad42ccd4fc60654a55002d228f52a4a5fe03b8bbb08ca82daca558b44dbe1"
+ "266e50c0e745a36d9d2904e3408abcd1fd569994063f4a75cc72f2fee2a0cd89"
+ "3a43af1c5b8b487df0a71610024e4f6ddf9f28ad0813c1aab91bcb3c9064d5ff"
+ "742deffea657094139369e5ea6f4a96319a5cc8224145b545062758fefd1fe34"
+ "09ae169259c6cdfd6b5f2958e314faecbe69d2cace58ee55179ab9b3e6d1ecc1"
+ "4a557c5febe988595264fc5da1c571462eca798a18a1a4940cdab4a3e92009cc"
+ "d42e1e947b1314e32238a2dece7d23a89b5b30c751fd0a4a430d2c548594",
+ "9a2b007e80978bbb192c354eb7da9aedfc74dbf5",
+ "484408f3898cd5f53483f80819efbf2708c34d27a8b2a6fae8b322f9240237f9"
+ "81817aca1846f1084daa6d7c0795f6e5bf1af59c38e1858437ce1f7ec419b98c"
+ "8736adf6dd9a00b1806d2bd3ad0a73775e05f52dfef3a59ab4b08143f0df05cd"
+ "1ad9d04bececa6daa4a2129803e200cbc77787caf4c1d0663a6c5987b6059520"
+ "19782caf2ec1426d68fb94ed1d4be816a7ed081b77e6ab330b3ffc073820fecd"
+ "e3727fcbe295ee61a050a343658637c3fd659cfb63736de32d9f90d3c2f63eca"
+ },{
+ "PSS Example 9.4",
+ "1dfd43b46c93db82629bdae2bd0a12b882ea04c3b465f5cf93023f01059626db"
+ "be99f26bb1be949dddd16dc7f3debb19a194627f0b224434df7d8700e9e98b06"
+ "e360c12fdbe3d19f51c9684eb9089ecbb0a2f0450399d3f59eac7294085d044f"
+ "5393c6ce737423d8b86c415370d389e30b9f0a3c02d25d0082e8ad6f3f1ef24a"
+ "45c3cf82b383367063a4d4613e4264f01b2dac2e5aa42043f8fb5f69fa871d14"
+ "fb273e767a531c40f02f343bc2fb45a0c7e0f6be2561923a77211d66a6e2dbb4"
+ "3c366350beae22da3ac2c1f5077096fcb5c4bf255f7574351ae0b1e1f0363281"
+ "7c0856d4a8ba97afbdc8b85855402bc56926fcec209f9ea8",
+ "70f382bddf4d5d2dd88b3bc7b7308be632b84045",
+ "84ebeb481be59845b46468bafb471c0112e02b235d84b5d911cbd1926ee5074a"
+ "e0424495cb20e82308b8ebb65f419a03fb40e72b78981d88aad143053685172c"
+ "97b29c8b7bf0ae73b5b2263c403da0ed2f80ff7450af7828eb8b86f0028bd2a8"
+ "b176a4d228cccea18394f238b09ff758cc00bc04301152355742f282b54e663a"
+ "919e709d8da24ade5500a7b9aa50226e0ca52923e6c2d860ec50ff480fa57477"
+ "e82b0565f4379f79c772d5c2da80af9fbf325ece6fc20b00961614bee89a183e"
+ },{
+ "PSS Example 9.5",
+ "1bdc6e7c98fb8cf54e9b097b66a831e9cfe52d9d4888448ee4b0978093ba1d7d"
+ "73ae78b3a62ba4ad95cd289ccb9e005226bb3d178bccaa821fb044a4e21ee976"
+ "96c14d0678c94c2dae93b0ad73922218553daa7e44ebe57725a7a45cc72b9b21"
+ "38a6b17c8db411ce8279ee1241aff0a8bec6f77f87edb0c69cb27236e3435a80"
+ "0b192e4f11e519e3fe30fc30eaccca4fbb41769029bf708e817a9e683805be67"
+ "fa100984683b74838e3bcffa79366eed1d481c76729118838f31ba8a048a93c1"
+ "be4424598e8df6328b7a77880a3f9c7e2e8dfca8eb5a26fb86bdc556d42bbe01"
+ "d9fa6ed80646491c9341",
+ "d689257a86effa68212c5e0c619eca295fb91b67",
+ "82102df8cb91e7179919a04d26d335d64fbc2f872c44833943241de845481027"
+ "4cdf3db5f42d423db152af7135f701420e39b494a67cbfd19f9119da233a23da"
+ "5c6439b5ba0d2bc373eee3507001378d4a4073856b7fe2aba0b5ee93b27f4afe"
+ "c7d4d120921c83f606765b02c19e4d6a1a3b95fa4c422951be4f52131077ef17"
+ "179729cddfbdb56950dbaceefe78cb16640a099ea56d24389eef10f8fecb31ba"
+ "3ea3b227c0a86698bb89e3e9363905bf22777b2a3aa521b65b4cef76d83bde4c"
+ },{
+ "PSS Example 9.6",
+ "88c7a9f1360401d90e53b101b61c5325c3c75db1b411fbeb8e830b75e96b5667"
+ "0ad245404e16793544ee354bc613a90cc9848715a73db5893e7f6d279815c0c1"
+ "de83ef8e2956e3a56ed26a888d7a9cdcd042f4b16b7fa51ef1a0573662d16a30"
+ "2d0ec5b285d2e03ad96529c87b3d374db372d95b2443d061b6b1a350ba87807e"
+ "d083afd1eb05c3f52f4eba5ed2227714fdb50b9d9d9dd6814f62f6272fcd5cdb"
+ "ce7a9ef797",
+ "c25f13bf67d081671a0481a1f1820d613bba2276",
+ "a7fdb0d259165ca2c88d00bbf1028a867d337699d061193b17a9648e14ccbbaa"
+ "deacaacdec815e7571294ebb8a117af205fa078b47b0712c199e3ad05135c504"
+ "c24b81705115740802487992ffd511d4afc6b854491eb3f0dd523139542ff15c"
+ "3101ee85543517c6a3c79417c67e2dd9aa741e9a29b06dcb593c2336b3670ae3"
+ "afbac7c3e76e215473e866e338ca244de00b62624d6b9426822ceae9f8cc4608"
+ "95f41250073fd45c5a1e7b425c204a423a699159f6903e710b37a7bb2bc8049f"
+ }
+ }
+ },
+ {
+ "Example 10: A 2048-bit RSA key pair",
+ "a5dd867ac4cb02f90b9457d48c14a770ef991c56c39c0ec65fd11afa8937cea5"
+ "7b9be7ac73b45c0017615b82d622e318753b6027c0fd157be12f8090fee2a7ad"
+ "cd0eef759f88ba4997c7a42d58c9aa12cb99ae001fe521c13bb5431445a8d5ae"
+ "4f5e4c7e948ac227d3604071f20e577e905fbeb15dfaf06d1de5ae6253d63a6a"
+ "2120b31a5da5dabc9550600e20f27d3739e2627925fea3cc509f21dff04e6eea"
+ "4549c540d6809ff9307eede91fff58733d8385a237d6d3705a33e39190099207"
+ "0df7adf1357cf7e3700ce3667de83f17b8df1778db381dce09cb4ad058a51100"
+ "1a738198ee27cf55a13b754539906582ec8b174bd58d5d1f3d767c613721ae05",
+ "010001",
+ "2d2ff567b3fe74e06191b7fded6de112290c670692430d5969184047da234c96"
+ "93deed1673ed429539c969d372c04d6b47e0f5b8cee0843e5c22835dbd3b05a0"
+ "997984ae6058b11bc4907cbf67ed84fa9ae252dfb0d0cd49e618e35dfdfe59bc"
+ "a3ddd66c33cebbc77ad441aa695e13e324b518f01c60f5a85c994ad179f2a6b5"
+ "fbe93402b11767be01bf073444d6ba1dd2bca5bd074d4a5fae3531ad1303d84b"
+ "30d897318cbbba04e03c2e66de6d91f82f96ea1d4bb54a5aae102d594657f5c9"
+ "789553512b296dea29d8023196357e3e3a6e958f39e3c2344038ea604b31edc6"
+ "f0f7ff6e7181a57c92826a268f86768e96f878562fc71d85d69e448612f7048f",
+ {
+ {
+ "PSS Example 10.1",
+ "883177e5126b9be2d9a9680327d5370c6f26861f5820c43da67a3ad609",
+ "04e215ee6ff934b9da70d7730c8734abfcecde89",
+ "82c2b160093b8aa3c0f7522b19f87354066c77847abf2a9fce542d0e84e920c5"
+ "afb49ffdfdace16560ee94a1369601148ebad7a0e151cf16331791a5727d05f2"
+ "1e74e7eb811440206935d744765a15e79f015cb66c532c87a6a05961c8bfad74"
+ "1a9a6657022894393e7223739796c02a77455d0f555b0ec01ddf259b6207fd0f"
+ "d57614cef1a5573baaff4ec00069951659b85f24300a25160ca8522dc6e6727e"
+ "57d019d7e63629b8fe5e89e25cc15beb3a647577559299280b9b28f79b040900"
+ "0be25bbd96408ba3b43cc486184dd1c8e62553fa1af4040f60663de7f5e49c04"
+ "388e257f1ce89c95dab48a315d9b66b1b7628233876ff2385230d070d07e1666"
+ },{
+ "PSS Example 10.2",
+ "dd670a01465868adc93f26131957a50c52fb777cdbaa30892c9e12361164ec13"
+ "979d43048118e4445db87bee58dd987b3425d02071d8dbae80708b039dbb64db"
+ "d1de5657d9fed0c118a54143742e0ff3c87f74e45857647af3f79eb0a14c9d75"
+ "ea9a1a04b7cf478a897a708fd988f48e801edb0b7039df8c23bb3c56f4e821ac",
+ "8b2bdd4b40faf545c778ddf9bc1a49cb57f9b71b",
+ "14ae35d9dd06ba92f7f3b897978aed7cd4bf5ff0b585a40bd46ce1b42cd27030"
+ "53bb9044d64e813d8f96db2dd7007d10118f6f8f8496097ad75e1ff692341b28"
+ "92ad55a633a1c55e7f0a0ad59a0e203a5b8278aec54dd8622e2831d87174f8ca"
+ "ff43ee6c46445345d84a59659bfb92ecd4c818668695f34706f66828a8995963"
+ "7f2bf3e3251c24bdba4d4b7649da0022218b119c84e79a6527ec5b8a5f861c15"
+ "9952e23ec05e1e717346faefe8b1686825bd2b262fb2531066c0de09acde2e42"
+ "31690728b5d85e115a2f6b92b79c25abc9bd9399ff8bcf825a52ea1f56ea76dd"
+ "26f43baafa18bfa92a504cbd35699e26d1dcc5a2887385f3c63232f06f3244c3"
+ },{
+ "PSS Example 10.3",
+ "48b2b6a57a63c84cea859d65c668284b08d96bdcaabe252db0e4a96cb1bac601"
+ "9341db6fbefb8d106b0e90eda6bcc6c6262f37e7ea9c7e5d226bd7df85ec5e71"
+ "efff2f54c5db577ff729ff91b842491de2741d0c631607df586b905b23b91af1"
+ "3da12304bf83eca8a73e871ff9db",
+ "4e96fc1b398f92b44671010c0dc3efd6e20c2d73",
+ "6e3e4d7b6b15d2fb46013b8900aa5bbb3939cf2c095717987042026ee62c74c5"
+ "4cffd5d7d57efbbf950a0f5c574fa09d3fc1c9f513b05b4ff50dd8df7edfa201"
+ "02854c35e592180119a70ce5b085182aa02d9ea2aa90d1df03f2daae885ba2f5"
+ "d05afdac97476f06b93b5bc94a1a80aa9116c4d615f333b098892b25fface266"
+ "f5db5a5a3bcc10a824ed55aad35b727834fb8c07da28fcf416a5d9b2224f1f8b"
+ "442b36f91e456fdea2d7cfe3367268de0307a4c74e924159ed33393d5e065553"
+ "1c77327b89821bdedf880161c78cd4196b5419f7acc3f13e5ebf161b6e7c6724"
+ "716ca33b85c2e25640192ac2859651d50bde7eb976e51cec828b98b6563b86bb"
+ },{
+ "PSS Example 10.4",
+ "0b8777c7f839baf0a64bbbdbc5ce79755c57a205b845c174e2d2e90546a089c4"
+ "e6ec8adffa23a7ea97bae6b65d782b82db5d2b5a56d22a29a05e7c4433e2b82a"
+ "621abba90add05ce393fc48a840542451a",
+ "c7cd698d84b65128d8835e3a8b1eb0e01cb541ec",
+ "34047ff96c4dc0dc90b2d4ff59a1a361a4754b255d2ee0af7d8bf87c9bc9e7dd"
+ "eede33934c63ca1c0e3d262cb145ef932a1f2c0a997aa6a34f8eaee7477d82cc"
+ "f09095a6b8acad38d4eec9fb7eab7ad02da1d11d8e54c1825e55bf58c2a23234"
+ "b902be124f9e9038a8f68fa45dab72f66e0945bf1d8bacc9044c6f07098c9fce"
+ "c58a3aab100c805178155f030a124c450e5acbda47d0e4f10b80a23f803e774d"
+ "023b0015c20b9f9bbe7c91296338d5ecb471cafb032007b67a60be5f69504a9f"
+ "01abb3cb467b260e2bce860be8d95bf92c0c8e1496ed1e528593a4abb6df462d"
+ "de8a0968dffe4683116857a232f5ebf6c85be238745ad0f38f767a5fdbf486fb"
+ },{
+ "PSS Example 10.5",
+ "f1036e008e71e964dadc9219ed30e17f06b4b68a955c16b312b1eddf028b7497"
+ "6bed6b3f6a63d4e77859243c9cccdc98016523abb02483b35591c33aad81213b"
+ "b7c7bb1a470aabc10d44256c4d4559d916",
+ "efa8bff96212b2f4a3f371a10d574152655f5dfb",
+ "7e0935ea18f4d6c1d17ce82eb2b3836c55b384589ce19dfe743363ac9948d1f3"
+ "46b7bfddfe92efd78adb21faefc89ade42b10f374003fe122e67429a1cb8cbd1"
+ "f8d9014564c44d120116f4990f1a6e38774c194bd1b8213286b077b0499d2e7b"
+ "3f434ab12289c556684deed78131934bb3dd6537236f7c6f3dcb09d476be0772"
+ "1e37e1ceed9b2f7b406887bd53157305e1c8b4f84d733bc1e186fe06cc59b6ed"
+ "b8f4bd7ffefdf4f7ba9cfb9d570689b5a1a4109a746a690893db3799255a0cb9"
+ "215d2d1cd490590e952e8c8786aa0011265252470c041dfbc3eec7c3cbf71c24"
+ "869d115c0cb4a956f56d530b80ab589acfefc690751ddf36e8d383f83cedd2cc"
+ },{
+ "PSS Example 10.6",
+ "25f10895a87716c137450bb9519dfaa1f207faa942ea88abf71e9c17980085b5"
+ "55aebab76264ae2a3ab93c2d12981191ddac6fb5949eb36aee3c5da940f00752"
+ "c916d94608fa7d97ba6a2915b688f20323d4e9d96801d89a72ab5892dc2117c0"
+ "7434fcf972e058cf8c41ca4b4ff554f7d5068ad3155fced0f3125bc04f919337"
+ "8a8f5c4c3b8cb4dd6d1cc69d30ecca6eaa51e36a05730e9e342e855baf099def"
+ "b8afd7",
+ "ad8b1523703646224b660b550885917ca2d1df28",
+ "6d3b5b87f67ea657af21f75441977d2180f91b2c5f692de82955696a686730d9"
+ "b9778d970758ccb26071c2209ffbd6125be2e96ea81b67cb9b9308239fda17f7"
+ "b2b64ecda096b6b935640a5a1cb42a9155b1c9ef7a633a02c59f0d6ee59b852c"
+ "43b35029e73c940ff0410e8f114eed46bbd0fae165e42be2528a401c3b28fd81"
+ "8ef3232dca9f4d2a0f5166ec59c42396d6c11dbc1215a56fa17169db9575343e"
+ "f34f9de32a49cdc3174922f229c23e18e45df9353119ec4319cedce7a17c6408"
+ "8c1f6f52be29634100b3919d38f3d1ed94e6891e66a73b8fb849f5874df59459"
+ "e298c7bbce2eee782a195aa66fe2d0732b25e595f57d3e061b1fc3e4063bf98f"
+ }
+ }
+ }
+ };
diff --git a/comm/third_party/libgcrypt/tests/pkcs1v2-v15c.h b/comm/third_party/libgcrypt/tests/pkcs1v2-v15c.h
new file mode 100644
index 0000000000..26c7b23845
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/pkcs1v2-v15c.h
@@ -0,0 +1,3919 @@
+/* pkcs1v2-v15c.h - pkcs#1 v1.5 crypt test vector table
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Manually created from the file
+ ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt .
+ */
+ static struct {
+ const char *desc;
+ const char *n, *e, *d;
+ struct {
+ const char *desc;
+ const char *mesg;
+ const char *seed;
+ const char *encr;
+ } m[20];
+ } tbl[] =
+ {
+ {
+ "A 1024-bit RSA key pair",
+ "a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0ab"
+ "c4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72"
+ "f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb514"
+ "8ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb",
+ "010001",
+ "53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd"
+ "8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55"
+ "fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbf"
+ "b78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 1.1",
+ "6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34",
+ "017341ae3875d5f87101f8cc4fa9b9bc156bb04628fccdb2f4f11e905bd3a155"
+ "d376f593bd7304210874eba08a5e22bcccb4c9d3882a93a54db022f503d16338"
+ "b6b7ce16dc7f4bbf9a96b59772d6606e9747c7649bf9e083db981884a954ab3c"
+ "6f",
+ "50b4c14136bd198c2f3c3ed243fce036e168d56517984a263cd66492b80804f1"
+ "69d210f2b9bdfb48b12f9ea05009c77da257cc600ccefe3a6283789d8ea0e607"
+ "ac58e2690ec4ebc10146e8cbaa5ed4d5cce6fe7b0ff9efc1eabb564dbf498285"
+ "f449ee61dd7b42ee5b5892cb90601f30cda07bf26489310bcd23b528ceab3c31"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.2",
+ "750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5",
+ "ac4728a8428c1e522471a8df735a8e9292af0d55bcb73a12ac32c264f3881c7c"
+ "8a710f70feb10485c8370f781fffd021816f058739766da0a9c9db0eae7e9a25"
+ "b6c43318d0caac236522ca310f17fc52ad4229c83a24e9e545eb35e9826d559f"
+ "57",
+ "6842e5e2cc0041d6b0c81a562c39a617379a515cab74abcb2619c7740a541d95"
+ "55dd9165975bf8a3ebd0d0456661dfb1a6861ba2332269930e0db514fca0733e"
+ "eb9c405713eb1f9d768033ed293e1e081a125f32ddb9ea52edbe275c4af60f8a"
+ "7bf832bd227561c208dc0031a84b5012c9dd9f74459dcb070bdbe13cfa8c2d50"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.3",
+ "d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c245"
+ "1fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051",
+ "dd2d60a5e008ebe1d0be6f60dbc43f2962ef50bfde542bbbe98fedd1feac057e"
+ "771cf15fc632c8db272e28d29b5793ea6ab806218c538239b93a935e65d24416"
+ "ec6c6e99ae04",
+ "709c7d2d4598c96065b6588da2f89fa87f062d7241ef6595898f637ada57eae9"
+ "0173f0fb4bf6a91ebd96506907c853dacf208494be94d313a04185d474a90741"
+ "2effc3e024d07e4d09aa245fbcb130219bfa5de02d4f7e2ec9e62e8ad32dee5f"
+ "f4d8e4cfecbc5033a1c2c61c5233ae16192a481d0075bfc7ce028212cd27bebe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.4",
+ "52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85",
+ "2629a7aac0c3905e831eb602388c545af554b96b2ae51532e9ccdb8972ef30b6"
+ "4a2f98c695297a01c5812a2c401582f37b144a3e90e59d81b69039c64b844b02"
+ "8c105c8e683615afb658b6c4d9f38238a76301bb14449113b69de126045e26f1"
+ "3ee6d7",
+ "54ddb784268eadb3955bd9f9498842595ad29ff8a667feb41f6f530cb60bc926"
+ "ac6c71c772f803d022b41ca57204223b27ca79ec5b72652ca9afbf40dc2f6a0e"
+ "13bcd60d37f79504b0ffcc01cf5342d6d34ac6f1f2f9f2f4874625b9fdbb7dda"
+ "2ec87df0cf87259798df86a06bd5aef7354b8cb1cb137575f4cfbc46281bb331"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.5",
+ "8da89fd9e5f974a29feffb462b49180f6cf9e802",
+ "c3ca84600f35c8655fc7c64c75c5873853d3aa8a9426a51b63d7e75dcf6cae97"
+ "a4253fba871d6f968997199bf01b6a4d3428ce4c96d1c487b2830cb9e35d6405"
+ "5623699ab4979a02584b92e6ba39e757284079abf133a7da54e5425217a210f6"
+ "7c18269b511f61f8c5",
+ "a85548013bd0e20ee0ebd36fb748977f985846d7610eed24c36cd83033dd2aa4"
+ "580bd15335209dcf782ee26c48c30644b0b5cc86c8cd165ae21eadf578041867"
+ "7607031875e221ecdf3b1057316f3f12a47d5da40c41539b636430da2e542190"
+ "119e429c53c2226f959b19ccf48a3d240217c4de70d7072a7e0d95b616d115a8"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.6",
+ "26521050844271",
+ "3c6a0471daf00b7c2efc9ee88041654f87629007c124322211a5f4ea3c582385"
+ "7bc8fc7e21c94548b0eebdcff79160e112461e40509110cfdc4f0f13c7fb921a"
+ "bac8dfaac21acb0f7b8a13a4b5cca523d5c7ddf70523eb570c59b6c7ae9767e4"
+ "ec9a63d1136d10231b401e20e74102848348017a1616",
+ "5e514363287de9b380048cc4435d53294ad5941c551a97e13c16dc1398de610d"
+ "c7337bc6bde578e9e9f56af14454f2e831beef3231a85068e8fef72c89e1df1c"
+ "99430a60f6d94289cfba87b2b432a40b88db61dae088f9ed4e284a2163af65bf"
+ "2b43559a5da2aec5bb8f43f92c1b04a5146a65b6e019b4cdd2940c35d9645b2d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.7",
+ "8a847dd9e2",
+ "a13dff8a48e80494ae66e6ba9f179a010d9e6d403187967f99fdd90ef90e0a94"
+ "073ff0e4d0e6664ff373b509953e04ef7783be0fb46c8a9fc0ed8c1f33cb4d0d"
+ "2f1d0d5cdba14dca508ca1d73d208018639bc8e1658623de1e5ba3f05ed0914d"
+ "2f96902f2520332d8492d3734acdebbdf43e50a43e7aa872",
+ "827a67e815781c4d4e2b2e169d80cae9366872a792afbf3c0cd51ce28c70e86d"
+ "41ebb9752f3f92dba51adbb6851b1f784561a8f197208fde02970b38f2a97422"
+ "ec7f4fc8a10675a9dbde109eed0ce06527703ee05b657d3408f7fddb1eeccffa"
+ "e16b1da107307a2cf256fa60e8152172de9f9527fe920a901d93c4f4d57e546e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.8",
+ "373236b7202d39b2ee30cfb46db09511f6f307cc61cc21606c18a75b8a62f822"
+ "df031ba0e0e82dd2f3e5d31e4ea257b15b",
+ "219974a087f0a28193e649a04ae9d84cf2c8a9a46cdfd8f1ac62c7e0f20f4e27"
+ "030c72b20a5db725b4a8683df5556ee7947fa0a7661b6d99dcb79e494f4673f0"
+ "73a041dd907c87324e8625dd",
+ "1a6df5759984f2c4119355c5db35c8a478164d5e5ee77b4991f104ba91b9870f"
+ "1591be1f19f55a8051a62c0e59493df6f00fe50ef73a6cf0c43541f5320dab7b"
+ "2fc67c93225cccd6d50347aa969ad87bd3d82081454fead810dc1ab8c21781f7"
+ "612e6406729b322e04b1624f8538985659ae34d9931e019f762c797d5cbfa32d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.9",
+ "97e0b636bfddb8e1c8a9cf5b305cef3a8f47f9a8b3344f1355fa3dbab67bb972"
+ "10",
+ "c1f89bcdc56040d5e663b74bfde2397b584608cdf32d5a5844724ac7e598a86e"
+ "f7114b1be08730cb10f661fbfb8609f7c6c37442a1b11e04a611ff8ca5ce9afc"
+ "1eb3aaa92c9f28bae220440578990226078378c493411374c53e3ddc",
+ "873cc4dca427972b63c6cc8ac11ccc33c959f7fcfe4b45bbd47b29d9c988c01a"
+ "96bc1eae0ef9b1948dce2cc9f0aa917e86a6c11f8da3da29df905901f1918a76"
+ "168de1175e2735128c097299d66ea5ccf9b95b3692eebfc6ea11bc37091b795f"
+ "18803d70e79558e12516230fed5515e51b45ae86cefe47b93790e4994dc41e05"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.10",
+ "82b5075bfc88f4006576aa80a0007a7451184d4f760cf9242804222b0e0726f5"
+ "55030e4e6b01f793b097018127824a3e402457d8495fc0",
+ "d55e3d4897e9d865014cb15d3ee3f9fbd29c92e5c237dcae46672a463eaaa4f7"
+ "dd09861e946ac65b8562506393b85192ad41fb0c48c8c052981bddcd5f1fc8b1"
+ "39cd47cacffc",
+ "2e83c3d288015a5f503d3e5de7d2ad9106545ef97d63e4d06a5a0d9dbc29f6ba"
+ "fb93a5173fa5063a6939dba6c7a428c35e7dbe6a9593fe5ec4c19878893f3137"
+ "09c87602726cb3255be75adc7f2f27e6db91c3a343eaff1c28d9d5f7cb6574e6"
+ "31069003cdcfa07743a7340d58839e708bf36af6342db8dfa41feadafc6953ac"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.11",
+ "3648c36f851f52f2328779091985a3c812e18a7055d090bbf0324c13793bb822"
+ "1a57",
+ "c1277185c35955caedfdf9de55d5d95a398d58f5f333191fc02945efdfadfb6d"
+ "b05ee2a2d34183edf89a1a4dccc46591b3532ba7039362c75df194ec106448af"
+ "b7f6bfb2807e383e159954255e827cb9dadc8d9b7e68a1aa097635",
+ "8862f1973fefe0af02d96cc458334ded6c02d8d7eaf593779c5d386c4e49f768"
+ "f130b487b3c91e323a477e4c110a3341ff46eee37c773e5c0ac839bc55cc0c07"
+ "0cac01cd45183cfee6b88bfb82361d3560197cdeab42e5c755d237971a88daf6"
+ "10cb3952614b364056cd491420effe3a0b8ce31f2e3e49cad6f3b0640f4491de"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.12",
+ "94f78cf45c53fc46e7eb1b26618a29e9485012c1",
+ "e6de9e9b9022a55f56121d5ac00aa6df299c8a369422e7542956b6da2e0dcdee"
+ "968db07d995a7bb876f7f8cd66b2f542c05308f74983a3f8360c6b8947f87d60"
+ "8b031a2c68dde1471ae496ae9b16e2a81181eb6fc2f65baaadda6422a93431f6"
+ "f3b07b5b46a3cf8948",
+ "3c6d3b43d23adb79d697233808b074487697f335fd99cde865411fb182289256"
+ "1fdc24a8b8bb2c4f653c4d156c77a75de31600b5709e8d506e98e1d373cbda01"
+ "f4d9feb0297198cad0ca2a7e3b1e63903b1043ce79494c5754f7f90fc1f073a6"
+ "19929ef126394b0624f3b8ba6d5645e990e7c0132ce2123146fd9cadf745ec61"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.13",
+ "779d1eb84fa284c37d29d5e179d00306b413c44a800a077e59853f6305f92e59"
+ "fb7f81",
+ "c3e6d18bda97782ca781fa76d97a6c94d854d14199b4ea7d82c5bcbbe6cdaab5"
+ "255747443c59bf8c77ecdaa64ae7ce61e2c7300132b754e9162f7cde758f480a"
+ "e588cfd44a946d64e2720a2d17525545220484838118ad6e6b54",
+ "722ca92566c73cc85d19ce3faa14cb2e79849f205092d1589282313c0427f067"
+ "798afae3e3f0a561f399346e9d107da04af44b0c6f044adefe097a0cd14a47a9"
+ "9cd9819a98413706307cbd0da01697469eff71d31441639493fbed8eee1ba39f"
+ "dd07fc0ea08230186179f90e7ef13c61ee56f167fc2f6b15793e1a3224ffa29e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.14",
+ "88",
+ "c0169d76e4ea4545410ddf6646c1ba7dd272d7c3498ba6b0804b426130a80fbf"
+ "ff4bb7b5f559b0a9090e4ad9b9f416a6dfdc1501b1ba46877b1a96fa8491dcfd"
+ "de50ebeed24d3f98962413346ed4a3393e235b77bc1ed67468ece2792a2fd3a8"
+ "348fc5509b5906f2885615df8c1461377a741d5952fb36eac0201e27",
+ "4ed7d1291a0336654d5ca2b1f9d20cb2da7226f7116b930988439b4463981104"
+ "bd63c2ce2b77d626b3109c931403ac5b49b4247c4f6967b8c0db063c9995af9d"
+ "36540650938b01f93906f9838907ed5936abb343b0e25509a1d2d4c5c8b95806"
+ "50da2ce11fa3cf3e640723eacbee87fad3ee35958b45075df781c413466af139"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.15",
+ "a2dc087778d543408e8973f1363159edb8f0783c457089072dce66d3102bb4fa"
+ "e60aa60e41933c48a1be3953ec2f804c0cc96c",
+ "18112014065329d04bfb0cf544dd38d7bef1549b4a49a16776dda74d0a7edc49"
+ "67b4240c37142fa3f6639c2696cd7d4b18a11e2fb54081f2de5bd7bd15cdda92"
+ "c94c3a47187b5ff43b53",
+ "7115190a210488f04fa0c00c93a468a8030b7b9fc10020d8310bcb01a5c8dda1"
+ "d06ce241dc775b43e6f13b19abfcbf3616e84f107c9ed80d1b86bf87c98c2b62"
+ "9ffadaa6ec01f4e675558ef52606eaf126068fa7534dd13b920d2381695ad775"
+ "fff0bb7cec4690901d6f1e1736b82cfe3a0c224d18f12915fdc95c18397c3570"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.16",
+ "110bf2b1d0dd812f2a5a21f3404fa2f2c454c4432fdfa70f1b0f23ec69c10237"
+ "73a73aba",
+ "17b85f7653ff0ef5de7f25696cd49023ad8eac948a83e22458ecd5d10a43866d"
+ "c791555e64f078c38c752b6e9c6eeeb339eec91016d258886d012775ad643602"
+ "a0f0d1793454a0609471162288223950826ed8e2025da9a4e9",
+ "5d0f2fd85e6f9d9e432fad860fdc49969624ff4fa0715d361e9f00b05b3aa0ba"
+ "9eb27bae610efde1143cbc933b52dea7018760bb251be0e1e30cd1c5991aef74"
+ "4db82f166b9063efb7e33840a2569005654b140e115fa56c30406e45656e8199"
+ "af394f6386346d5f1a300b95ba48fc0873d618d692bb025bf15e9d232c641ada"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.17",
+ "d9d937131ff1940a86bf7139b48114364195b4005222a8bbbc261a7f2e212b8d"
+ "d035e53f9144f5610b4cec32ea01bda9d3c80cf29464f80f5f5656c8",
+ "3305e1da60e58673fc46cd33be2a66d3a102c3db161ef48c0d60ef25031b4014"
+ "167826246aa528a3a3e5b0ab95078d8401d92903595afc1aa854e6044e5eb5f5"
+ "be",
+ "0e12167489f0baefcad63934bc159f1bbd9e9b287e500f490923c16a85564a1d"
+ "a63659375f22af7ba49798e1578cf315fae3e9ed5699c691e3c1d0bb46da492d"
+ "01349e9329593d4381d074a0a531df921b31316f7e2b4fe915347283242335f0"
+ "b0b23192c72102f2c63624b1e78965450e8230d4877e4617b03d44831398ddbf"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.18",
+ "81b34aeb8afb8a3f",
+ "02f748342d010fb56a6f69f21f8c6a631679c8c4b8f6feb525cf8e72fda8ef8d"
+ "f6623128c0fe74bc590caa34f1eed1ad2d6142dcc5bcae84ef313762f2e4e703"
+ "03d209c8d9577a7c843d2b9172ed4efe2ad629614b99a91a4cc8325ba324116e"
+ "cf0c5e29094938ae498984f4f4cbb1623886e03973",
+ "43b276c7d368ea21c6807116cde8608298f24002072d776e56e62c3572bfb99d"
+ "a4c56e938a47dc075fa1ff7a618fb5faed3ee37b91dfc39153495aeba9df6d45"
+ "df94b0e8a8ad2db37a9fe46d0fdf154231fd6f3221474e8f5c191fdb8538e1a6"
+ "03e59897e150faf95b65da140667edb19809eb4a16acd01ecc604bda57f20ef2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.19",
+ "7bf9fad889de73ed873d",
+ "fa5dad45a4bb5e74c4cf2e213ed40aa9617598d11d49ae1c32d794e09cd0e5c7"
+ "aaae81b9554dde3108d60a9a82f42cc6c2a689f460ff1d53ad85bf838311e758"
+ "9e1967957b51567aa0d33afa3752cde6c5661d4f27aed3df52905f1cf2253304"
+ "618e0786041e70b4dcbac8c108ba34ac3939f4",
+ "61c2550e0b36a6797ff86493801b1146d89059498352e4c262275b1404b13315"
+ "e956bb3d312185b521b3c708e9d954021719a059d984724c53c04f5ad274bef9"
+ "ff0a7950b2fdecc5290cd5f3bc26524cd1342048184b0e2cdf9406a453a2ef9f"
+ "3bb23c4e7c1c8b2952a0202bcc238247ea327b8c0700c8003fd634ec1ed9bf30"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.20",
+ "b6a3509bb3b9b0b57cd58de409d953201a042f9492dc1d7e34a7d0941a1a1b",
+ "3a9e15065786b3e01d826b862a8f702b5cac8c1662ee7d15ff323cdfe71ebf4a"
+ "d1b1f3a6bcbdd4b0010877ecac091f615908e2be400bb0c498e355d571fd1089"
+ "5b8ee9c3a9c31e4b110389c3d5c46ebf76b3b35ad1f4791b6d2097f109f2",
+ "6b4b6d7babfe4d6417acadfb78572e7c87e3fe1bd58eefb0d4b1279c7b7c8326"
+ "a68bb28795e09f9b1ce2e24a539f4b0d93b29274cecf7cd9f0b732aebeda9111"
+ "bdfe25e268a88e3422e29b52bd4b7a0547db8fe12a6fcf1a3c06a002bf870a2f"
+ "abb7c457e4bbce3e316f7232449f87a9d702b12d19bde7f9590f9467b06bd58a"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "98b70582ca808fd1d3509562a0ef305af6d9875443b35bdf24d536353e3f1228"
+ "dcd12a78568356c6ff323abf72ac1cdbfe712fb49fe594a5a2175d48b6732538"
+ "d8df37cb970be4a5b562c3f298db9ddf75607877918cced1d0d1f377338c0d3d"
+ "3207797e862c65d11439e588177527a7ded91971adcf91e2e834e37f05a73655",
+ "010001",
+ "0614a786052d284cd906a8e413f7622c050f3549c026589ea27750e0bed9410e"
+ "5a7883a1e603f5c517ad36d49faac5bd66bcb8030fa8d309e351ddd782d843df"
+ "975680ae73eea9aab289b757205dadb8fdfb989ec8db8e7095f51f24529f5637"
+ "aa669331e2569f8b854abecec99aa264c3da7cc6866f0c0e1fb8469848581c73",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 2.1",
+ "e9a771e0a65f28708e83d5e6cc898a41d7",
+ "168e3eb5809b0870e1f2487e1be77a176b34716de141ba4c9059da90e5e51a36"
+ "94e858fed10b926c02523980a8909da996c64333ea676787bce677f11fda77db"
+ "b1a9516edda9b1294fc2e450522288e930be7fa729b250e3aac520511e9516aa"
+ "863af6bc075cbdbff4304670",
+ "71c2b8fb3819f134c2247c6babb4cfbe17d7b2643f87ace5c571277be1908ef3"
+ "a5288e34384e460a70386e7ea1d19d3dca1ce15ba93239a8cdda18e317fe0796"
+ "80ce7e6ac6d9bdaf86cb9aebf1cf46cd10ef6a688b0cb2ce765dd0b325204239"
+ "66eee1aa05c6c28c6f3524fb686b5fb15853659e583ac437219def8edc58be2d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.2",
+ "664bf05d612baf61524c608eda36fc6ea2c93c143153221bcfd6ba0cfbbd6b64"
+ "1447e4788b0a462cb5b3f9fafc9a75",
+ "e7f0a27918cad915da28113659ffb5dfa0b51b24d5a71c2027f8e4d9409e8c64"
+ "72f0c54b5c08858da63d4b8172b07dcf8c5a7e8f9e90f017c24b44d16b670bdc"
+ "96030c8353a2839ba4c075d24c20",
+ "0686901813db053ac708e3fcec6bae0360088fd344e9d7ea118bb3f537531425"
+ "1e606737f5824b3628f6650348f6ab553b277da01544d05673baedf455cc0332"
+ "f613f65478fcfe066734c46558bc233b4b6f5241e4f4ac53fc18c55384c8fd96"
+ "183f0bb5515e893114f9c61ccc11fc1983de74469264dbdbb0c749174ecdfbe3"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.3",
+ "5e76e66ed57541fc23d359f4adbf3f568201d3c6f0e026aaa5676356cc9866f1"
+ "755de98cb39f236dafa9e6bc794b7443b53a2d85",
+ "5c6568b6e33bc13ad2dcd6012d17da81b13dbd62aae40a64af97e219e75dc181"
+ "126077d120dda19d6312cf1e9871c115f0867fe662d78a4031976bddef68f52b"
+ "68995867cd809505dd",
+ "19e79966ff1fbc10073de73df3a531637874e47df639256c51d0bba935610b46"
+ "34f9e5b4689bd921735b32236efcc6e7cc49a9e06a25ac9659b7fe829cb3e8b0"
+ "1f103179422365741b76c8342149cedc76eb0ad018ed4235fbd524fd87c9549a"
+ "b33ff23ee4f8200efa33027e9deec60fac013d1e56e6e333d493a4a9460fe58a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.4",
+ "5b195048eb90eb4793",
+ "bbbd49550ed1ea1b6bc7206ce0b003a632a52b0bac5f32710b39fa64b3556ad6"
+ "f6c82bd9d531b307469e863f54b5fe2183056954f2a967e4dc2b326e41dddf74"
+ "3a764f7e82886829a8fab2772a3497706b9538a9f84296c82d9bafc29c39d468"
+ "4f75ff6bb1c12e39bb8056af2d24344b2cae4629",
+ "42c9cb6821b55dae30d90025753112e6ee02f4ad6f0f5b3cc4952a127c8a16f6"
+ "6479b8144f3cf29d84e43d67d67712c7f5b76da2c66ba0e90cd4b1fc1c1b3f17"
+ "a392e70408288af69b50fe8a50b3296a0dabd7c8dc3984a1940688be70982516"
+ "20256cc21b7c76ed29d86ff7c01ec287df4738be3469b30a3f8fb7be83d9361a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.5",
+ "660bbd40069cc67bade41a09ecf43cc4513f7c7cc02dde972d2b1f29295e09b9"
+ "910c59edba0ed2ddf11a6d4169351f97240733528f91b268faa7af906e",
+ "307f61b183a8dcf9155ab235e61fb56ba2b8795dc4235385e8acf366d25233b4"
+ "70e05d7011b6fc532f0a658ad13afd290c6f30e2795ee3d39dbdc80f560ece2f",
+ "049b26050a3abef83ec2776111e3b72fb9a2d6a801055d6b5e0da4e95ccf2ebd"
+ "0a786a9721aa7925bf15beb62713a313877dd85d2658b208e88e6445fc35019b"
+ "0cad6bf4d06e2ca5f11949eeee7ee47f1d5b4c88241f50e4d6edf0183d4fa35a"
+ "371fc407364f2dcaa4cdaecefcea6dfac1d513f905e747944744bb64576ba1c8"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.6",
+ "81cb0a97698f823b56b45f",
+ "938c8dfda08b89055b68af011f246cec1f93a2771da97dba20954c900912285e"
+ "5db187b29e3272e99e694e1214172528453084064e5c60f01e786fc5d0d9af06"
+ "39a498c57ade937760ae517484afd7025ea0d55a62b11f9aab7fa5ddd093e5ea"
+ "bad61b67a295a775be96c6b76ec3fe472950",
+ "7fb8f335eedc4af6af44073da196457d046145030147f8420fc79bd589774a73"
+ "0a6d94fb7efadc5aeea7c070f189249125e166c6d30129ecf2c4822a50496bc2"
+ "f21e79ac57dbfbdd71a68b58d9051b480bf47748a13dfb673eaed7710a468fe7"
+ "2f7d74e6f4a28944043a52d930de68dbcb6ee7fb8b69640541e3ed5b754e65fe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.7",
+ "05f7835623c8cfaae482a91085b97f6b95928bb974acad02364aaf1317ed53c9"
+ "db2ffbc8a3cb3a00f44dacef78",
+ "80c83d2547be41baf2321bd30a9ab7749c5eebb5a1fff0b31d6bdb0ad16dd0c0"
+ "fb3ec157e78b0986602041cde88957a55329e3e2cfe85a594474945efa333585"
+ "fffd41ebb8e7c518c3c9259aea8de635",
+ "87f9ce05f0ac9c05e45fb7bb555a7a18a9cdc55f544a542101e9a71cd2036682"
+ "0e7ff6dca34675229d86e4fb5871f9310b12bb74e28618d6d6586587f66acc89"
+ "68a83cd807f4d21297731d7c22c14599e75719fd23052b8aa65b7e9c5c020038"
+ "2d35d560f2d33dd049e06ac827cbdd9af581a6b26db61d43d7124b34721df142"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.8",
+ "e2e0f6b328d9bbe9fd66cd87987c1160ed237b1c7c656a89fb1f21d709403b04"
+ "10f8e4e12eb9690aebeb3807319a936564f66717a71c4862ccc56e",
+ "cf18e608b156145c44de314966cbcc6674a45ae0df900406e40d3dfc322f3940"
+ "4ceeb6dc58f801bbf2ac4f47841abd796179d0824f3bf5518d78cc66ad8dfbed"
+ "b117",
+ "1401aa21ec6ebaa7e3a9f713c86b508e375f6c125b29626ebd349f64e20fa48a"
+ "1b068479fff33022f66f86e97d9c5edd9026e3183ce08641570659352f87a618"
+ "91f3d86a3d245f0245e39d99892c67fa2bed8e37548de23defdd1e43d5d7e3d9"
+ "a3c22ce6a368d84c5afa1cc5bf49b68fe5c25a326b0eec5e44c5e2ff5a359dd1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.9",
+ "c69578ea03e269b1b91633a72f9fb4d10c",
+ "e0a1a9bae30a7ac66cab3d86433c1ca5e8ac2b74e483ca7f34597716ee161890"
+ "6c97772f2886f46d783121b7fe1b8fa5fbec09c068e5635c89e6a0a9accf2b12"
+ "c64706b6ae9a5a74abb83f64e13a8c53f926760466b645e28e9ad6461ae7b89d"
+ "5efccf7d89149aa2e69f0d25",
+ "78f87d6b06761bd7e717e0c5eb40e1fb80899c7be4017c2efb075978ee38d0f9"
+ "5e9803dcd40fee9792c61d4a2d85dabdea96ca29f3ca1e8bcf817655d0c09474"
+ "d98094eb6a7ef0333d6971c93836fe0232f718463dc9541853463bc1cf03677e"
+ "786ee52e7271c3c11ac00553c6752707e0df9280c4f2b7d19fd6f3d8bbcc7be6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.10",
+ "7672cfc27a41d501aa4c41baabf4525a7c455fc8",
+ "4ceea1a89464a5d2f89e078953caf776365898a5bd5e8e448c65da26ff98900c"
+ "d08061ef446c69b48dc4609ed8654a646d708262cb8409ac27c4a49adfed47a8"
+ "5ad429ed75077578e4c273c61e2c3b46beb472f0a345a05d61a7eaaad8a63e0b"
+ "3d4952f27c4081329e",
+ "252b14133f1db25013293501e356534f26afe334688e68d791833a0d82560570"
+ "bbb3ce2b16d8b5f7f89e7ebc7cf9c294ab3416b7c21187707fe5e7992e720ff9"
+ "58daa40f5ad45bc747479639a537fe0a4a75fcfb45a53f0173afc0f3cc910b86"
+ "ae3137628d90ff675ae1ae31e1640537ea1a7cccfb73f8be5aeca03bab193bb0"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.11",
+ "a16ad8f2e0932342ed21e13777f4652a3550ddb4368b5ea71c66dbc3bbfeb7db",
+ "55884c830d4a80b79f089da74dc25ae0c482462145e1d09523da3c9344bb97b0"
+ "52fbdc1543dfb53cf2378259687c7b1b35caf2f91999ed4ace39af10d6bed0fa"
+ "22444c129d90741cfcda90198e2782fb03bdcc7cfafd89db6fb0fed224",
+ "08326aff6d03cc4e2610dd536af7f21d76227d827d5280d8b83ab9eb30e0769c"
+ "fa02b5c1352bf4d170ceb66f8be698784e1a6c203fa5ab9007a6f7fc2065204b"
+ "982fa561fbb361af2b8eea42ab3fec0ed08622e5f289805275380b69342a96f7"
+ "6a9904876890d92f24002032351d8a1cbc3d27b2464821bbfbfbb9a678519610"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.12",
+ "4a",
+ "8aa0ced17f09adae610a46030dad40311bf1469c2737411e40f92396751dd566"
+ "37c958dbc58a17fdbddddbbf7975187898be1aa63c5eee5f9a1902980f595184"
+ "b9b5b465b92e20f7ae8b5a5cee7f3b57d997a06a702d238350a92698ef275dff"
+ "5277bd2c999647405adbe4fb3f1be75e159a4c438313b7fd8aca9dea",
+ "4c4e5ab62d0c967ab82921429ffe50d2240e7e0a1875488755bb7ff615a8c99a"
+ "bc37b2e47147a927d7b98c30db24da8cd35e13d7b71414d032bd0c3ce38b89b1"
+ "1b2c3f9d830816716a2e8ccd8c79e9c74931a7b8a8db13128ce40b2159e498da"
+ "98f2aa352f23853106b661d88ed06ff66a56e756597220bd10158153ce5c0263"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.13",
+ "bffc420873f5af5dd23bb0",
+ "dd31ccd47d4e3102df0fc59b1b8477af3a78c2fa9c8ecb4f0b3bde2350043655"
+ "0364665f81c0356abc0b78e9731911140275c866f75ad0cbbc88ad6b5d4da52d"
+ "08e22ee539b58e92c6196387e221a087396cbe57ec5603f6162627983eff82de"
+ "048bdc1b5edbb5d4ea84f50224bd88a905da",
+ "0da2d6f7bcb50a472eda24609da67728e53c9880aa5fb6fbe60d83c11e6bb3cf"
+ "db17d14dbce8ec55c73ab0143e9b2756bb6968e5af1aedcf6a80c26d490e4718"
+ "7ea5d8cd2facb81ce64a723c40f0ba4c693e1b1143df15a42091709ab4c7cd9d"
+ "47079ecd68f6a196448a44679a041410418f11a1e1bce78e772604a2f2778195"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.14",
+ "1a9b8729210a8471fc5cd709f2edd3240150244bec96a92ff807e3b30d295d3c"
+ "345c044f2e956037",
+ "5878c91b166e90c34e6e66568c151f4d444340b5f1d73052cc5633ea2e47aced"
+ "7b178a64fb09a5ad0846aee4116d6780ee75eb20851668820cdec0f2c496e4c2"
+ "88d8279c1c5d4ec00d980c272e870518486dcaea85",
+ "3700ac362cf60e163947a198d00f3b3b26e03ee2fb782b4288b8c1de76e9e899"
+ "46c9807c56e09c7b52be0078acf692964acb97d1fa5ceb5776a1d556b4bc9db0"
+ "0bda25237a751b7c229b6b57f7ff751c12d1f22a4fb0e90b63d042d9499e0f7e"
+ "feadd3c588f2c743a12c567c81578dbeebfd3774da34ad09eebe9017890214b5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.15",
+ "a6d0e8c1ea4ab4ecc8957d62281579675a648d62b7f22b2b08d1313f406f137e"
+ "99426735cdb9372feca1ee78463fa5de9cdd84756c68bd1d92ba965f506410b1",
+ "1c25c9b832169a1fdb6c148e47e66c3cc82141e611a6f30cc90c5049e8c502b3"
+ "1cadc76239b7bdaf93fa97343e7ee551bc52fdb5ec9e400af05dbeacda",
+ "00e8b2fc76dfb4a6cc4364de8f683c3fcd0a9ecfbd4a5a7224f49ae9b4f3b5cd"
+ "c71cbb8c66fd35f3d18eca98967bd4005df79152416fd47e562c55edc6d61212"
+ "286ef975bcc802692592653900973c72e01a693b05fc2d5856eaef7ac08ff5ec"
+ "d531e2c2ce927745a1165a51aa6698a1ffcb87f81ef6510bcaf9cb761e9e1f0f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.16",
+ "f3405b218f3ec603a980690099c2cf5cbe0b2b059679c46b7e48f6fdc4da4092"
+ "d831c8b52b2cc79bd2bbf6e9f57b4e8caa94b581f9f231261f0e2bbbf53dbb",
+ "f4707f58642b54cbf80a9b5048a6ec0bd35d095716db12060cbf50585fb92379"
+ "81052f7bb1583cd87bc8bfb55b733e890eb9c08ef0e880e9ba0d50ec9541",
+ "6d9d39198b5fcb132d93151149d75991024ac22eb6eb2dc7c6058f6487564510"
+ "2b95254e25e9f0ae4506d43c601c188a314f4bb4e038c81539416e105e8097fb"
+ "695aab36fef516e6a33f36f7f95ad1ff15889025b1b2e81e1bf3b2de5ba9187c"
+ "a96ceba9fcecef9c53e4943486185967cf7a6477c329f00ea695525bca99f2c7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.17",
+ "6afadbe3da68d90285bb8f1e2129ffebb1c65b9588d6c2c04024c238b20c65d2"
+ "aca5e38276000a0e6a0d0537efeef6d3e3d94fb9",
+ "ee176ea3cfd490b6c049d2e74c90c0ee7468520349b851653db058a1c3e956e0"
+ "885f261b6e71cf1e623d3b9d1d56fa1367e47ff374ad39309ffa2e671128d5ab"
+ "b4a61a5b0dc2db2c08",
+ "672fe95159a9893f3498b616c17b59da71da802febf7cd38110614a1b25d96aa"
+ "8a74aaaa2a0f000ef8aca3b41ad161b62633f241319c33e4ecb7706ab3adc6a3"
+ "efea22430f3f5c9c4ce5404eb8e75a109369c0aa0b7dd713bd8b77cca5f74bca"
+ "5bc555696b68e1172db402501dcd2649685db0fd88c88360dacc6509ffa8dfc2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.18",
+ "6d9f9b4bb123ba909553a7573a971f64b72524cfeb042de39215f650db612d66"
+ "d7ae8605d0441954625fa98122330e92",
+ "7ff8685aecf340261390ad0742730cb639283014ab3773556c697f97ef621a4d"
+ "cbf8ec6edec50d8ec9590adbaf2351ddfa0e52ea6ed18eb6c378f38085ae5ee4"
+ "cc48c1891ba47b2010d5d43539",
+ "8d30655cf15bf10a469787c6a10e79254ff0bd11938bc60a81a758d93cf2a030"
+ "2459fc2f0d7700b86dd6ed618383b44b458704ca11928e504f028efe5037172c"
+ "3e51b837be6156de6a09c55597be74c97caa1debf314cd94b91b9f94cbf7640f"
+ "86c26d1d6a0b104628b587114aa31d99f69cf95737932c0cb5333374dea07fac"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.19",
+ "33cccb597de95cedb8b657fcd8f88886da04c757935314",
+ "5342f4684391cd74f5282db83141fff678f23a3ea652e0d427fb6ad976c5a710"
+ "a6379577718947ac727b4d58a0b0bd207ae373a8b99ac8e251eb02458a9edc39"
+ "52fb28426d18fda18a802bbf0a0b8b2cf25ca3a022f778c7f47fc530d0b7a5bc"
+ "846eea9180f2",
+ "8c4a63d0731e2e71eb4615189a968b3e4a242856b2090245238b6645978f1ee8"
+ "d79811062ebd2d1f3d523ae600e0e5a6e405c4e4b5a16e8dfb4924304b0d1ff4"
+ "d641bf987fc6d41d3eb7cdc53134d0069cdb5afef7f8f9cac0ee5230b6f88622"
+ "a84de52ad6f75047843706ca969742c58da77262ff1f128a664e51cd635e7115"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.20",
+ "19d6",
+ "eaacb578aeabf69d4eaeeb36d04cd8a22e8fd7a25f0443a11e4e08b3ffac1e05"
+ "421a876cca91318250befaffef9b2749dc402fad4fdb7c1b66aa5e089ff99f8b"
+ "300cdc46f48f5648c9408b5f8b3f5a12e65050dcbc0d5343d63d58081921652d"
+ "5bc82dd3d70e075d32d802c2976478fc9f0993dd0859c90e228e87",
+ "613bba5c190ad772e08c29076e2e9e5f12efc9292e3b5cee52c2697fb7b607dc"
+ "72e82578e8b753bacadf23b47725213db89f8873fa79b914a4b5161efd9e15cf"
+ "a8dd1effe89f8947a6f3826dc6bf53beca365b9381184562a79e21ca0e68ebf0"
+ "ab82ae762b28c14365152ae0f54f2e9d14439a846b383f5e2c55efa7008597b5"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "b93096d0261efe000b3d1704f5043160abd3eb566c61e53c76c401e2b65521bc"
+ "12d481215183e8f46c2ca8d00ada5dfd04dcf7cf36cc581105d99d2a7dd94b56"
+ "760a6564fee5e8aaeb0607e145196210a31b7ed8dd2af32d29d2bad6f15ffa5a"
+ "11dc735cc36219021ee8d1eeed34639b5a91ac6a92674e183970c59d5b196d4b",
+ "010001",
+ "0107ea61adeca5e9007c59134a7d38fc7af3103ad2c4a2bee39708befc83dc79"
+ "b70dc97592db6df70fb3c49c2535fcfd9fc2ce7b055392e3eeb3e79793cc1b60"
+ "153f4a0bff26be667bbcdbbf6e32afa6fd14837f3c79be44cb1c638ffa5c6b17"
+ "709a96e127030bb1116decfde52bb040842a94d2e674f11751ecb903ee104845",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 3.1",
+ "44e56aa77bd935ac59a9bd323783e12742",
+ "92eef619f04f52028f4cc3e5241f0aa0921b4d183c1f5bd68d86fbe9e7b7d0bb"
+ "104ed1cae07ac7d80bfd9c1ceff8dcda1dcc6930f4c55137346bfd68c19d8797"
+ "2f7f34cbae5663260feb79f760221cd67be066d5af0f073c0f2c439e8bcb7463"
+ "ede44c8b150ebaf3298726c3",
+ "1591d1ce0fad66d86fd42efdb31e9a028a3157fb0914b247eb3d22d76f9769b0"
+ "e19f6c064ca1b9890639ee6e37b709224d6b58ebb655ae4b69ed4cd75d812921"
+ "17c06930d42ac4d42ea73514218f49ea07ca97436709683d67a8e9e808da69a5"
+ "0b739c42eb0deb94a3498fc5450eb69ace23767661fedf34183a1b6f425dd6a0"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.2",
+ "a75738291fad5413957fa3b9f3b2caac9f5a",
+ "3a191aaf45ed4c2589205d9cf6a30f07700e38be06256243018d23c684daece7"
+ "e867e39d76c6b6f03543fc15af81bf84f964eaf3a95a4b808628fd51553899f8"
+ "11c08c62609c514cfa1dbb78d5a5b33cc0b857fcb1eecc531b132634439059f5"
+ "5a733e146e1ca1eb5a97f4",
+ "70aaf724396c1ac50edbbfe8341b087ba0ffe287605a8c3a8ccf85ab2ed2fe22"
+ "159d62aa027476ebbf0770026d2d3b0c0d7734faaaa8d15e2ce51c85535c26b4"
+ "150ad6346e3bfd38db5dacf752e75d75314054d167a96d819f3438a7bec4467f"
+ "c560a694469485e8e78e47e4e8277ca7d3fd2ad94a30464c2457854725c61615"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.3",
+ "87312f787de0659750d602ac1102",
+ "a229e3e8ef1caa66caf0d8acd8d66b9e41cc771f26e20f12ecc6e2aa3845513d"
+ "d134f7c6e574f41b215d1d111756daf971ccf39ccdce781619d79720df918d33"
+ "9c826dc049b390917c17ba0fb1302fff110a14dd2384902741f912b26a1adbe0"
+ "ed1e8fd989710b403d27c4e018fb9b",
+ "033846d7664c8f926257c7fd3264484792ac7f9bc8758a7a16abb89fa3ccc4d1"
+ "3a1eed88af7323bc3c74e23fdab50381894c8626dfd0ac8589d46234d3c35f18"
+ "998179448431dc816fb63e55cf26d74a9d2a0932673cb4beb829cd7d49508848"
+ "c6d0c00d5c70f7fb476770e40319237c786bf4e26c48d2cfd96ee362bf292825"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.4",
+ "9a2bca75e32649777b9f13ec30fe16bb8ab46d6d5e0c6463a73d8c3663adabc7"
+ "23bde72a50765e7b300ef6b561dee88484880e4d612c",
+ "8bfae9222f75a06998ed6d9b149e8905cfc8db055a0e32acedf824d2f6b5b42b"
+ "3aeac6a7104e144d5e4834280e36445ab850f3a6de164c2c790fe7d9d7bc7f9b"
+ "dbe25217da2ded",
+ "6ec5f559c8a320d90d1eb5ef091c4d1255a24a6919410eb1df65a97b30cdd7fa"
+ "e18e6512a027e976704b4fa044374393d501e2ba46186200ef0dddf19c757758"
+ "e4679430bcd9fd119ea243b349dcf81c3432d31fba911ec6fc686eaadff6b9fd"
+ "f53aa4c85a49a22a051c5f1807f3083b1b3e6117b4ef1208de0a8001dc291c4e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.5",
+ "dfd63e6ec61e07275b8e37cc6369e1f3ec0bfc57a298b905ae5d0774e0f522e6"
+ "759c7d116f8e8efe69450fa7a8389f81",
+ "c422377b89864b0df38b4f9c15f98a059655e1c9b0c709635ca60649d8d2475e"
+ "e16cb127f6763912964e1984d6daad4d6abd04b04618b32e5325ba95eb5e76db"
+ "d46d9fb59df07a081e956cb073",
+ "9e06cd91a44a9adea6a79803d3e6bbab17db1062b6510bed40075566749544c0"
+ "3d7a78b137b0dc1e6626321fedafc20dcdbf7080f7f5bdd56744ce999f76705c"
+ "4f5e6fa15f46c5ae508090dbbc85fb86899c9578608dfd778aa4a79d3d736354"
+ "ccfbfa2c86f29a7a58453d757fd522f78408d9916b1bd0654bffe6e066baeb50"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.6",
+ "5d91fbc1a7ba79939b89a2408cce8ed4bb2666ddfe09d91921a0aa69096a9569"
+ "92c21c",
+ "af07fea321eaa267af7f09806f9ea8b4cf135ed6f1432d51b28f92448709c2ee"
+ "8aed7f73b6282cbfd37f82dba8723e5e5e0a81f590f82e2fa84c3bc00c9b9f91"
+ "aa553b8b2c074bfecac2f55237f4cb70543aba499468cf6844c3",
+ "76050e2264220e10052c49b96cc8411e396a7a6e4aedb06b48fdb071de839b40"
+ "1cac0c468de8d1ed0b568ce690e8037af5def6b3d2dbc7b5f2fade356c26cffc"
+ "dd334033ea2c997792d930a72646125c0ee86a4dd843c824c7a52ac988c92e6c"
+ "69b580761c49881f29dd8a76da793f432e7d5dc731a25e5bb50258d027395fbd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.7",
+ "04edd83c65656a01",
+ "88f9a27197f9f257fa81c0e30590b73e9e11c76bc89e08536b4b64a2506aeb33"
+ "b45074730809a05c45b9bc95717369cf92c1bf986e53ba11238330fdc4e05ea1"
+ "07334ab31106aebd9c6c29e501a57d997c01bbc1010bd52f0538b95159f39132"
+ "0de6db23d8162cf146584c6e076c4eae862072eb5b",
+ "791b379148a83a034d312a82bbb37b111b40bcf6a337fde289b08e072e440319"
+ "73ff9d0c27f70d64a8eafc6eb5f8eb4e52e2c4197ecfa545ed63ae9a128379d3"
+ "f562a18fe3ad14052767f0541b90168185cbb78db60381c092bc23e1aa05b408"
+ "92f9a116e625cb148b560742cc1278c4d21a4a7d37f6982aee27f2a4c0c573d2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.8",
+ "3f7eea781b77d85fe371b3e9373e7b69217d3150a02d8958de",
+ "4999c64cbfa38524adcab66f64454d36fbfcb2986e1fa4753a0e03889ff06ee1"
+ "600eee23be53a97442b42c69621866632e4a6b6a1c710573261d71f38abf9e52"
+ "49ddc8e1b77b3f126ba08815c4fe63314f9b9e8e7a40c7fc72862520ed49d412"
+ "59ab2e0c",
+ "74fd8b9856d7576e0f1287e0e9085a3801e6b6774db733541debd39e72cfa829"
+ "1fec27018c9f5305a44ccb5a3cb591fed2e6a1d1d85caaa74dc23759d6665a45"
+ "70a637f3ab304b7661313b96713c7b7e49773133dd5d4ef9d29a1af712001502"
+ "8daab3df042c562620aa49d2c014414dfb1577d719a9588264712de3bf4a7679"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.9",
+ "a38508d9460c63f41581a8869a75824b14f5c650322999dc411350d0d4e8624f"
+ "f09ceb00d3bedc5d762a40c9398004",
+ "6a0a288a1e67430c666aebea44b582a90969cc01e90aae1053ce55eeb9879bcc"
+ "62253915e922f1096667bda02a14e70747b3593524c2848547d2114d1d0cdcb9"
+ "7eb4df455bbac9b0cc290839b73a",
+ "a67757808f5abdc81edb7f692f9fb852f1a1661c4a009805c44b216cd3b1322b"
+ "bb25d1458e31b0f07d65505759c4b4147f23cbee2af4a1a5938a068ce9c5323f"
+ "f53f4b392e1250d037b31e6281dcdfb96bf4bfeaa147f096c784c92f4ac57091"
+ "1228025029c3b523303fe8227e8b2cc0ef157014cb6731aac09bfe6ffa18eaf6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.10",
+ "f78405236a9eb557aacec6007dbc4c0ede78ed12b04c82888a82c213",
+ "86f0723b3168e2aeace9ec2e95fda6e6d6fc8d6294556566399d7311e799faa9"
+ "b1ee1f032ab2e534a91fbcd07c8a7d04a9b485f31e0723fd29eb2188069d9bbd"
+ "7629dc6e3fc89be604bcf00c52fa8e1d6c62555fd1f60cec02d4d961d828dabc"
+ "4a",
+ "6e8d2fb0b2eef82fc110cee0a9d3842f2a058a24407fa11ba905d1aa50e8cc12"
+ "decc073dbd08a8c70518ef25db96fda2411cca08728788956f73dfa120e0ea60"
+ "5bffc93b43a441a43d0eaa3ff073e6982eef5296390607e25a588a398255ba00"
+ "5a485e6e732e3a1920cd43a390fb66d5428dfd628974b8aff2f0602da578d625"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.11",
+ "561d27c1d3f6d5d1a643aa47e55d78eb00f32d42896a34e0c1d71bc3a5457c92"
+ "05bed13b984c5259",
+ "98176e1d67a2462f5dc1bfa6e0759542104ac14811d3187938250455c65e4aaa"
+ "7632bd2d1d752e1f34c53cab267676a78c10c998e773fd8ffe35c867c443bef7"
+ "9865aa2da2915a85c7026323693e454d8ab32a7715",
+ "0bc04783c692447a3de61f53b72f7aa410316dd509a6f49e3aba56ad1ff86ebe"
+ "9e6366e17e51450076bea371d4c689cd61495cd8fa29c0e87b6dbfa8e386c2e8"
+ "20e4c742a487e89b275a2186e23840be9c02527ba717e9e60b5bf417711df34d"
+ "7b8e2d12bceb859385fa001d4b4bffbbc0edefbd4002418468c566fdf6b83509"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.12",
+ "eb5f8c0dc9d901061b82aeff8d67d8bffc0c047ecc4aa346b23bdba62a87e9dc"
+ "770b11695fbf1902f24b66ceab",
+ "7482770f3cf57edb8140ebc33a028245ee0648520689a50e33f5f467f6d1e432"
+ "4e1c50c899e5ad2c46c97f8120d1c72239d6a82d8f8ebc80b973eea8c5456929"
+ "504514b4b15662844f295062f21ebd92",
+ "b8404354a381b7c2abe5f72825f3d315bdace6c3cfbd88b89768612005197c61"
+ "663883f2c2574f995ea6f94eb34f276862b33f58a8839223706be1c1ff472305"
+ "f11ba9562a0eb012f1aaf85c22e88f2fdfeaff8633d3cfeb5f764f4228920de3"
+ "0c6bde2cb4e8f03d90ed548f648500351a5f41df74ad65e8c3bee9505a7d70e1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.13",
+ "5a7f0eaebae49cf57c475a6da67943a7d3046e3f7c7d50b09a8098b544693968"
+ "93cfc0b2f08f6c2bff235051575e6e56",
+ "fb084886db3798d2b5bb35a3b1d3af4fdfc0456cbc797b9640d8c44a0e034e40"
+ "372b34fc7c1e8b66011b4ecdfaec6ee4cdc828cb1ab491274ac1e39f67587a55"
+ "476709b4023fc569cbe8b4fd4b",
+ "07784ecb8cc5ba02d207bab055c0e55d10a9b94270cca250ee75fa1b5ae190b3"
+ "3b9696eb2ec972b26a0e9423af16aa3789176276060a76400321117482963403"
+ "4f9712c9171017f2fb213f25c146c2651f89440ca536e533e305cc6b0113398f"
+ "61b463b073e1be05073e9d64bcaeea5444b820c6abf3465430ff4de4a8bc0e75"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.14",
+ "f91c71af5aeacae179e16e87c9023ba94d84d7516cec6c3989801fb3e7add064"
+ "bddf928b5000940bbde539d623379c",
+ "deb260258be2c853352157b06526b143ba133c4f49bf3df2c050ecb2c9ca3253"
+ "11b3c3e3d88df6c24a894eab63745b6253e3c46bca171a26a4f2fc0ab62b8a2e"
+ "63a018eb47018cab951f59f0203a",
+ "0dffff519710c9eadc533b108a4c2974fe531891a34107a67427935ba720cdc6"
+ "f6ee029a1b036861db1404c5864990541fa2421301a7b248cb11f365b6a4aa94"
+ "6f2231cbb14732b01aa4a60bcbe520ec6c3853a6958a93c5b68b85d4bc3d8415"
+ "ef8b1d4f63038f4d942ca6bc7a38251f15a4e33b189c250bcfbc03156e4f9211"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.15",
+ "0790c081f361c95b59d527d3cb50710e66e27259501025ed3f20f30c",
+ "fcfc2d56cb926d905db36e1e2eff1fbb75d653517f59e86f71bc4bc55726f088"
+ "b821624483b3e29ac21a49bd859134908e6c0ec1a0dc8079930144120d1f6bf9"
+ "3bc627b99969b2afe21a7de10d96f6ef43c567b5e238385cc11a5a2a13e17855"
+ "8b",
+ "7f0e6b342d6a135466be4173381ac04abaab7e14fdcf51018987e96967169aea"
+ "977803ebb3242ae9adb46ff51120934b39214631b03f5af5bdea1cacd328addc"
+ "d40a3a29966bf98bd7c8c6fd0f4e8b972e2da10c6cc55205867f3904ed60f5b5"
+ "bedf7c3b3c7dd5f387548f40056702ea720176dce206d413d7423f943fcdf639"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.16",
+ "93c41a1adda8f69360f41a58eca0b55ecb37a6a900fbc7dacd9ca399c23d3172"
+ "615377ac0cc6b0ed43bf597f21cd259d8f80887b159d96d66161d5589b95f1fe",
+ "991a2a7c061c23a8ebc9489abc1b4a64a5d4e838d9fcba4288c01fead66d59f4"
+ "9636e4a8d7524cb89d7adc7af3f61ae6b39b588fb77eb7022362ffd26b",
+ "7e54a432f525c52333abe3bb45487e039af94dd3efc35844dd8e835ee1006178"
+ "e24dcd19fc07667b4a34f3bd771d09a7e29f8ca17e88d029b90ddb5f2813be99"
+ "000d59f5432c466a84287577204bf7659739276998305747667fafd8029cdcbb"
+ "5918393c2cfce4d84a9220ea3e3819725336f25fee8e085debed3332d5ddf1ee"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.17",
+ "9e2a7b3774b11e62b6490b5651a0c18e092e9fab8b2284ae4643bec36b265e5b"
+ "a3c51ac385b2c73d220b2dc2e10b0d690f67945a0c42b3bd09d0a8a7",
+ "a18bfb74f6debcedcfb47c7d5dbf106e774d7ef6638ec3821869cd2ed62dd532"
+ "5f4e5733b8bfd5fafc43e4164e78d438994d85337d7f0d38f0ea3ba37f4f41b6"
+ "a7",
+ "18c88aee2536d942f7622a644fad6fecd33228c7aea0cada0e531f4ccbf1c1f2"
+ "69cc958629a43b9752fcaf2bf953ec9f7ef4bb0e62d128e0cf4babe92c6d9284"
+ "9e9838dd88e2b468bdcefc04a9e4cb55e2a518ca259f9e81a49f28df34761f9d"
+ "ea2e70595662626cf96ac05a7c8b103333e906e132639b65a766f4092c8ca078"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.18",
+ "0ac52d4001f25c2c9db91ce50bddf0d5919e19962e83b07cb79adb00436e1366"
+ "b0aa8f3fd1ee796b23c8bc560ccfa4bcbdb1f8404dd6f7551520d7d9e2",
+ "22ffdcfec6f06b1bbd1453977043a34eddf8594da022130914975542f2f00e98"
+ "f31e0dd0c48f7ee5f09d6a527121ad23371c6cd0e0790eb7308bbb0896dd590d",
+ "b26957c562294de1f39324b1cd803cfc39fcee2d3c9d1379f8a112079d694368"
+ "f55503c2094d988a8a5b5ac549be1cf55316045df5b6f633a4ef1e1f019ba1b5"
+ "42bf0a87fa3e5ca3f6b61cc8566128a0fa418b0825c90ec2f1ec74e587cd8057"
+ "d952967ac4521ccdbf6326f350930093826d2efa058ed64415374db3204885ca"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.19",
+ "a8003462f806b7f661fb664632",
+ "c743f4a6da03ab2de5a731cb88d8ca9b61c7319a5f8bf9d237877a05d0f368c3"
+ "608a052ac6ce13731795475542ea16a862913d0432f08bd8c8b6ff8195691fee"
+ "5ed142fb9eca9467524bd3b5fa5a4ac6143b0d38250ae621d439909cbe3a6b5c"
+ "01fbea2d7a3f1ae41d61fdd64764149f",
+ "b738e1c429f8fc0682faadc8ca87ed8f16df930faf43b1991aac71d88f264c0d"
+ "829ac03d23c25fc5f3e85dd302cb7b1533e68c2416c51a79bbcc7c29b07e2e0e"
+ "23c6f2df0d0781917eba1a5708628eed8a15b3b184af700d0dabb14df60b09ba"
+ "d2127df180f4d6f729658760d633c7775a7b596d09d903491f21096c34c3953b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.20",
+ "ef32",
+ "4399cb044a60076d18ccb34e8b078c818ea77f63b0a43abdecc5778193a8bbba"
+ "5d56d0fc4e82a211516bbdef44e7f4e7febbe1e1923c999a7e961cd6ee1c416a"
+ "8596e24b6383a469935f33d156fd5bcfdbd427460d486683061e4105f35b5e75"
+ "2320155c7f69ad8eb402cc1106e0289a9b4965823e7a51cfe4d26d",
+ "131b625e86e6cd1e08acf195d93cd3a0dc8ba9e2dcd6fc996be21724af1790b6"
+ "88d79d3ea9a95098cabbe8a5d48592e4746b0ed2af7caf89b7b6152e3824d915"
+ "89eeec3375c71a899748703acc1e8d1de471ea7528040b795f299e668cec9f5a"
+ "f3eb48f98c0d852067773e101fa24aeb6b404dafb42e7a63b04a66bd0e9f9c94"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "e9f25e48140b5dcf4699e3037fa834f0c78b16735ff79f6b18ae60b51848d306"
+ "99ec646d857f15770e2c7a0c0c900fb6040b5f34484e9cf5ceda23d5b250ef93"
+ "286f011e9a5bf9e542e5c9f442de5458e23e41d1d9cd9f0ce1cf2008d3ea4d80"
+ "32e854cffcdf5f698d1316e029c488fcbb2be29a4e7bfb8e6e81d342123ee75b",
+ "010001",
+ "45458868445327486049e1bfdff56113a8aa45100dab074fd16394ec1a9039b8"
+ "1b2cb581fe84e648b5f032854dd4fc69f361a0a39d0376138cd7e7c37784e2a2"
+ "f9d4f26684cc5cc9f512ba6215ebd232f9aa3da469db43da1c0646e75b33aac5"
+ "70081b5b2e96eab7546acf931785aa2fd1824cbe2c5f9bf56334ec1566d1cf45",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 4.1",
+ "ca24721c88e04774f415b4c46ca0fc26d5bb53aafb1992f6de785c763a",
+ "fc7f85c1386dc43c3a2846e4dae4d9548054459da23182f984079b071fdb5e6d"
+ "9d0fa0b22e3de636ee5b253a42f95eed4422956c70f48dfecf0e555b05157b15"
+ "6a55c8bc658cd3b5397fab78d711564e89c7e6248aa06ad105c40c31c4b1997d",
+ "e395ff1fa552fc2e79c4a53558df1400f8704eb36cf7cb051bab93150ac6396a"
+ "dd63669b04248b9db36a9c94f5198c6e5d9a17d474edb20345fd6a78b51de816"
+ "6e98cab5b6d16568b41a8e93e4838865d4bd9c51cde8dfbeeea5882b09dc70bc"
+ "9fe749b5d24bb7ca511db2c2b829a7c9146c774eb0bd7aafdc5c38d3d7cd5827"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.2",
+ "25c7bc4cb243ac1f0740869cd26ba826f355d477c4aa6cbe543addea844444f4"
+ "1c3592bb3da7d421",
+ "272be3fbcc7614996f1ac0e0a5e2690623bb0b6970fcde0b6f4558ee623426fa"
+ "60add6c5a8a10d4a3751501536fe8a45c542f627f4229fa12457c11331137205"
+ "552b014c91b1c4e09e459678340a74c285e26aefb9",
+ "7650d6f81aef5c0e320ec77fc89b7c3e6183850d10c98ad7e9feea47e38cfb37"
+ "a025db421fb6d005809e38bb3c51951da9d9433ba7efb17de7d8fe3e9b9ce455"
+ "5374ea663a1b5da4a092294ce966985655e2ddd20d7de3aa3537058cfd7e7a7b"
+ "97fcdd9853792ba83fcc89074a8d0f3cefdf985b9e78aebfb05967364f2411cd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.3",
+ "cf007ebd23da06971af79aa634d5d25505bd5229",
+ "9cf7237e28a86e418d664fe3be7ae30eeb955a3f7102b27d5fa096749c7fc206"
+ "4c880bf3d30eaa981fce3986a910feeae184c01025048ba6794896fccff74a59"
+ "42f962f3e36371f6b3551829434ad8d00a2c597cf6d451eace88868538a480f6"
+ "8ce68fc6856ebb57dc",
+ "b63252af2e8ea271e706fd683d0f8c10b3f4a345c4f5b6785ba9329f446243c6"
+ "f369e30ea8fb11084db97988e9c3874b34d6fd08717d9e810e9c224360346bec"
+ "cd3e0e53d10b1ed458e64f3fb092f48cb66ae03b64f6aa9c63bd279fae4c33f4"
+ "2a9d73bb39118eb87d2512b9d936a27ed2e449607dbf0e3e223a53952635599c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.4",
+ "efda79e9c336c234ff37b4f58fdbd31af3675b3d2b105eafbead4bbbfff54e68"
+ "6ab5",
+ "30c20943f1bfc42361d4d22f51a8d786cb2d0dd5ff7d705b3028601811293dbe"
+ "5d72c3559710ce0ae95d2f16b239a4ac8445537d488e3e6d2cf5b7a64c06c375"
+ "6e11606763633edbddbf26bee6511842d2752dcd88896cb8558a87",
+ "bb91b2f6f4331d64d0736a2ea60329aa16c2ed7a4d5ca8d784e6304ce4844c71"
+ "58f822d2af29c890977d75a935e43d93b5be10c1d44fa00ce28e75f527bd84a3"
+ "be5af5bee94567c55e15ee3e93426ad8d50f064c5793ca38c43a70c5f560740b"
+ "16eea16b7f13415f751b3fdb877a88293321f50fffa6f1249496c2b027a218ed"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.5",
+ "4a01fc13c1d86fe7b2fdc792f5280f875adc5ae99ff911d02c8c003d39bbee54"
+ "b851efa34b4131be520d8100ef62c25a4b517e9b",
+ "be6ba5d11df1bfcb2b846771b6c9dfc9334da86c4b7c25439318e8ba8e47492b"
+ "cd511bd4cae1677d312ca22a9457cc81d90e4d524ba2265f0fbca18e3c3f482d"
+ "caa788332239346d6f",
+ "16bfcfb42d28b9d16270cd138dc3ca6442956a41825ed0230b71091613333a9e"
+ "7c52ce8cc4b0bf29107941a0d72cc34afd0048bbf4c716c73aa9b0c78d37c193"
+ "719ebe03a9317453b553d4f5b385d141fc3b0ed19b96dc350dfd4d12e3dd03ff"
+ "1839d4782c6dfd5fdf5971f3ddb0e312a91606f31373020db3a76d04fd6d65d6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.6",
+ "7ab06e196922c0",
+ "de0d6033c1e96b5fd831214f30d81b8fd9a2693e5e8a36eaffd039e7473c28ee"
+ "43a3916c78c9a112958a94ce671ccc40d97ed4187a3fffa0dc129d88a8b8c496"
+ "6ea394a910896125f54dafbb3b17b9fa10c48220096490c6f75be25183e9984d"
+ "f5e4d7ebf9475d11ea39335ac72f93d333bd74221942",
+ "541823f905576da142e265d89045ab6620fd1a74c9533ada4bc7b43d95629a31"
+ "186f4e89892083d2549b0e638bdfc0d27e14ec18c45ca35861dfe612a3a1edaa"
+ "fc72fb4681a99ea6e648be8962f1561e750d1449f23f430af9307225544d8a8b"
+ "8965af5dd18cb78953ce6d16d85eb211af0c6468a2af9f72e78661b0fcaa4815"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.7",
+ "9ada9c10b8ae22",
+ "cc2343724ac50ee54708fc5fd03f09a1cc1222a44bcd4403877c6bde86bf43e4"
+ "2c1084f6efff20fac0acc31eca17c738d46868736552fd2f7e93b8222561054e"
+ "6dadc315604eaf8f77f05dd8583a93bf03cb9cc2139bc419bb10e9b201b2a7e1"
+ "8b03790cc83ed605d6d5663305347139c75e1ae2a56a",
+ "9f54d0dea05a5d0072235bc46793cfc47b006daaac0241c7e66d333e23c3cf97"
+ "63b61d9eeaddd83f5d7f0aa97d16c7699255cf7e4872b6a0079562d2607d6440"
+ "d7ed37c6713ce96643a441f8395564d26adea5823a4942da4ab8e47bed5881b9"
+ "d184057957df6539e436da35e30a253af12d541d4b0ef83c5ef3c135ab95949a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.8",
+ "d8126f4a8878978293117651b30e7922d14acf",
+ "adf9b0a9152f0e6ec6f4395971ad403f02e7fa98f815560afaffa7cad5b4474b"
+ "6ece65edabe27ec24a0aa473ed75a61f5c2490a536b1a4df7b03417737c534e1"
+ "d45bf72694386bee820c48dbd18317bd617c04b6a417e30eed79588dc23fd4db"
+ "a13744b4b2aa5af80a8a",
+ "3b2b85edfcd7c7c27bdedee1c28ab6187abf1c96d945300792cf8af197c2f9a3"
+ "91b48b8332cfde7e4c7dc34c4230295692cefda5efb25735492b9ff784c7bae7"
+ "3511c618e3aa7bc87bc313f26709a8ea4ad73a349ab9e5ad826c96ad0eca97e3"
+ "13286bccbf8e33c91f036839b9948b4eb0c38e213ef47f77661a27f8cfe49903"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.9",
+ "f5df01afe6a922518b3f4b80cd4fca73b97bab61716e27d251bd465f4b35a1a2"
+ "32e2da00901c294bf22350ce490d099f642b5375612db63ba1f2",
+ "6bf2810db8fb269398412dbb88060282d45fbe9627337e5434261a5dbc193ad6"
+ "18c11f7bdec1de2505f86037fc1851bf6fb49d2360627347499efc98e29205da"
+ "906d32",
+ "4012fcc5cfb978def88fb8f8174aa5b4a30775ac4559f0b2f3d3b4389b828a79"
+ "d1402510c9a0337d489d1182ab31c838ac7c80b748609a2aa537da7acc3a4a7a"
+ "31d2ad252bfd59280b3d1813a26f93c59ee8c5ee688718f4278393fece323a9d"
+ "ff833755e89ac8ee1fa2904bf24cdf4f01e6eaedb6a8ef01f407bef3309f0339"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.10",
+ "a3823faf",
+ "94f670fd82f6913275eea4c67116caaabd33578cf84d22636438a6fd7ecfeefc"
+ "0b187decf793891c6e4cfc52b567d872bffbee0a67472a1a48c0f1ba598ad825"
+ "8901c56a5592f141147e81339d747e0632def00d3dbee95c4e4321cc25b53114"
+ "47a302c534929cf7e534f9ae67f41e01e22a3d7ce41b3b3135",
+ "7b602542b64f0a1e0ec2aa01cbed377e331ea3ff86f356fb7a5883764be4cbf7"
+ "d0754c5829643136f2572336a23f15411d838514a1438724ad7409e8ec8fe263"
+ "41aeea5668345d0d823fb5c21df459e8bf7c15b80b072e5f8a8465a44aa9d09d"
+ "825c0315a0ecd2d649702b109be8fe35eb22843a20e7fd874f1c6b46a80b68df"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.11",
+ "75b9a4a0bb2d4643e478f654f2cc1a8c1bb46719760d4541a8a733f33b713d32"
+ "c60bfd35f16174834847e8812cbd7f06ce7289f372c58230f2b001459b5d",
+ "49a73deb93e3f1beaaad3a199a70569e099afacaf7a75fc4ce648fa82eaf2a0f"
+ "e411d264fe45f74525c91f3c751017f80a02babff35799626f2b8ddb9f3691",
+ "e5aee70de862723c5173dffbf6926c3d3316d5909cf5a1d663e680ab2bb576e3"
+ "5b93fd432743a18e8db4faa332f44668a3d19e5e695732f84bbd86d0dded7665"
+ "b70b97632eabe2364cafef7b74dcd1bfbd625e2bbbf6654cc0266181ac0a757c"
+ "3fbabd430ae86371eb56af610f77cf2fff6e248f8c579160b91dcecc0d202b50"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.12",
+ "1506eb3491785aa72106bf6c85d01002046d1c16d435dd4e7c4b7e8e90dddf16"
+ "332f94f4b835d0e4ad55d83a81b35c54b679d3cf",
+ "f66e6a8475844086e28477229746801d4350d9ad0768f3c3d8faa8107d95fb20"
+ "5e4ba8c64b738e54e5ac0dfeab996d61125c2679807259bc9e47d8bdd2c04095"
+ "05448bbf872bf6647a",
+ "d1fa3952cc6145ff771b6c5a68275bbc22d00392036617375f0c2bec3e288583"
+ "ecfdc6df6a828de37f77c556a8cbc4d44336e8d2e30587e331587317e97b05a3"
+ "fd78025b2d496b3bbeeb6c725d9ea561a732288233d68b79497fb0b6fee0a6b6"
+ "8ac313661b4b654739f918f6fd3bffc17c1df41f014495d55f9590147b82d15d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.13",
+ "9e3e",
+ "9b3ddf17cd74e76c69b5ca3a010a0e0fbd1705d69c3074353be7d3c0c205f099"
+ "c7a810b7a1ade09f5a036bb769eff53a53d4c6f87152922d9a7b86edeba37237"
+ "d7f1734d9d9739383f4880af3ad68887e0fe7c87a174fb3238b1e51ead2a8434"
+ "40c2b27f22dda4228dce70f91c98d471a8744d2765557958810244",
+ "42126b492a1e7cc03395b2ac7033cf6a6736b12e76825a173b9e011ae8bfed44"
+ "fecb8d9f58cce19911fe42d455e249200932a9b68fe2e419bc639c1178d11ffb"
+ "dbd9955d459f5ecfe09020098e297b8e91485e94bf11e7bf77edf5a27011c82b"
+ "927365a12c9c77c7e49bb7fe2f613339de3f512087795386ca585a7024782790"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.14",
+ "70aa78a4d37f74c181aa27407f2f9fe663a91b16be9bea6fc612887f",
+ "d0fd16c0f0d7909a3886170811e44f24fadf94ff17039a5684a09b24e1933fa0"
+ "c47151635d757b73c23ff39101cbe2529a63a7f3a0195b6e47510711de171a16"
+ "56c9eab3cf82d1c65226b58fd0fe58ec3196247f34b1a0552702dc037512c681"
+ "04",
+ "9536d47e1d687f1f24996cb46ce946ae54d4a149b34b5bc34443a201518387f4"
+ "b6381837cb7e4b0a4475137042f1448c1ea41515ef31c2fcbf62e7e95867b674"
+ "ac230aed9c7d8d61c52752b2fc2a0bbafc77b31c514930de9823b438b6faaa40"
+ "d25531033c66483fa0023af21da64fcc8bb8c5d52d3f6c4380f1d608d8c0118f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.15",
+ "0116a4617773b6ddb219161c4fd071937bbb0715cc627c17b8e75280d99cdd41"
+ "6ea5cdfa0906b9af0a20cd477fdcad1415a19a9d1b96fdc3c0edb9",
+ "86b158609bfa08a8ede4ef3f23e12eb50d245574264d764d871267db8a9524ea"
+ "3fa2e3845ffc291bda989989bf715aa2b08c49798a819f6858d9fa35f94df3c7"
+ "e086",
+ "74a3df385d20877bca9dbcebca2e532c6abe9562d6817be16e118a60f4ab0a1a"
+ "c0a8466653a8f8170e35fce14b449cd59f558e020a898894bd2a717558e6650f"
+ "3a128570d8c169a7746663c1d7ef62145f4b75c5feb6386fdb853394c659a91a"
+ "a2aae03bef9113dd4928ff28b380927ad1ba4e8a37edd172efe8e9eabb614d83"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.16",
+ "15c5fcc7547d63761f6af1f26eed9be8134f9f92127e76b03a33a97b9be3f78b"
+ "2e22fc7c850699a15c0e0ecebe2a71805f024b9388a3bdb2b360d69c5c0c46",
+ "5b4f17a9de91737a7fe854e8a176be5a0a16fc1042cb870cc01892fcd38ea75b"
+ "073c0ffa014f96a358e3aa5e73eaf8a91fce75470bde64e87ab891ba3bf2",
+ "7362d7398d0c251f835817e47937a9255836ca0230457ff608b078d50931a880"
+ "33ea7650811265f8e268b53315d8438e52a6a4b1b3895d30c3dae11a3b8ea8c3"
+ "0f05e9d71def46d4511192a10f54218d3936cb17983a1e7aff18188939b94692"
+ "7649b0fc4f7bbfcbfc14e1c0eca07d00c903db78169c50ef0a38f1da19ae4459"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.17",
+ "7cad18f175138742285e9035d13ad41fc3a85210e1544e24dea3fcfe66",
+ "9a06ca10fcc6610e77dff90dd176f82e3f96e4a9d7ab872c748ed422f34b3348"
+ "619440f0aaa22a669851dac8894a8efa34ea2c2da5e95869e0adc005a49ba458"
+ "18caa474115c3449966a85c418fcaa8f45630efe0b1b4d3d69be1bc0068aa799",
+ "1efad41446b91fdadd8b80619f68273668b7585fd91f3449ec85c242d0849e4a"
+ "53a5977b61aa40d12cc485ec7e4ff20f988691cb9d73af46ea376afc69ba2233"
+ "86e9f15d032697da75e2f952be2af062e8246cf749b89c4cbcd64e23f882bb55"
+ "3c3ce305203622b5a7397735a634aab0d17ef9b5559ddd34f4872b56e7986efc"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.18",
+ "fd98c38be3193070b5c4334b11c25b334a44",
+ "f357911103e987d1a9f15cc2e52f42390e0faa5002c4f17d40a4af50f31a2317"
+ "50e7af61d9afdf9caa3861a20dc721895861fb118e088d3218e6fb3556b162d6"
+ "bd67911dbc94219842658272a5d49bf5abb4a0879495c5e6e686285929a55a36"
+ "8f524c14a40b0c61380d0e",
+ "deae183b56c3fb3841ea574234acd30aff00d0051f57803758a4714abcbedcda"
+ "8bd1a48a980153df896b1376aa4b45958013d619be7eaff6c1a675e292efc3f4"
+ "393ddbdeab47e890a78cef69002449578748906c1021b891b943d818d3a61e67"
+ "a315612d4cb1cf197ce5dfabefdaeb590b8e8c73685e747e59a395c845c5d0c3"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.19",
+ "9653d79469f05d401965a95ce874fa225ec47974e8d06841c13b4785e00d547f"
+ "9d3144c3879e6ccdaf787aefc2f8452a4a3c884e38ee",
+ "855d6d1512e543a45d3a9aa9685d5dfda70479ba39526364141bb63627458985"
+ "71200122f4bc82c6224345c69d3ef542f123bde3015b60c4c0ffb98d630131ae"
+ "e81fe4a0b01538",
+ "69ca62e29a5bdb4b04e24016212c259140a60cfa81eb6693bffafc9f600dce10"
+ "822a007b6ade93facda1b2b165b557760f0a675ac9bcb206b964fb90cf6a2cf9"
+ "9f186b36d2eb991d8253a0754f9cc2d72de549abae9094f5a86ce1db494dbb6e"
+ "516286715b3dd40559b3107b9524b729ac654cfb40f9ab35d034e027197cbc36"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.20",
+ "0bdf3fce8e487db22d0760ab711586ca8e459c394ff8b1a1867067a9315199a8"
+ "012474b0f90dcc87cb",
+ "c9b78dce9dfd7f0404ff982e06b59650bafe31ea19bc1f2e1f3989f4cefce46f"
+ "c652423db3c99d92a8fb58f3ee393d555b7684889a4bf815a13e3b9bf2437140"
+ "66b9075890675047f17e935bdcf0e66fcfe39bcf",
+ "43ad3e625fb17215578bef2f465faa72ae694383369ff7aa151201a3f259c8d8"
+ "ce8c16bd25522149f666e8d692a0795ea71569d2881f9707085d3f59bdfa2873"
+ "66d7f5a3f76ea5dc109fcb03302da0b78699713e0d3009584f97176c1b9ba63e"
+ "80cfa8fd4c013d74b5fade8472d52c11e2e93681ba19d353d31ce6fa3c0ab60d"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "ab29d49cdc925c69cae75292fc03620373c6fb36d3c249dd5bb50f881a4c9389"
+ "afe73e8c56b8d667a5eaf2b5714adaf4caa006a49ac4bd4b91d545cf3c10009d"
+ "318a9de0f3bbd8384e8c7e96ca1595e32a7041d168caa73443b885bf7f614ae1"
+ "212e3b5adda29dfad501b8b1a81c3f48a456e133ad52da2abce5d6e782f275c9",
+ "010001",
+ "077bb273323486ec4c25ed6706341aa8a67aec58430d533fe586c6b94f570a3b"
+ "4290c45c0bdd94681f29a4b7588eea8039cca1c5b80b8270279dd0a9c5093911"
+ "93e3d5c25c1075c4a1d3dc3274066dab817fb51b16bc267ed9a9980ffbc09285"
+ "d97f112f152695e6e09cae72bb55066cb9dbd098a75ceb47b46272005c6bd215",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 5.1",
+ "5dc9f8b12dc812a09aa4b06dfcb57e1d2e8d1c7d2c076b25d5c18edbc046bd63"
+ "c7ca4a599f18de26f3be738cc28d16672c006e4d9c",
+ "43d605a5740a970b323727af352a1bd48de69d9505e22c2fad030c3b84b6dea2"
+ "d22f916406a7693cf506c2d251886f02203e3f7655a30a6837af8a8cbec7b5c9"
+ "2fc04c8c18dfe9d3",
+ "215a35f4c0435b07ed5d2c4b6865bc281cea7050cfea7a7e86e03f8acb28b58d"
+ "bee65458919ceaa5a33edd98201ea6e7632d7622d5a51d35a35fede86ef203ee"
+ "f6eb3475ec8f19e69c0ed52c05dd7d59e353f52b6710af4026655504107ddb86"
+ "f957e6c06ba67b1f4fc9f121e15f82736709d2de8d77432df08dccd2a0cc7704"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.2",
+ "d77407d8f69f80dc08eba5f426282de7",
+ "b829c789be381cd59de21489dba141e0bd1fa8a3c3826d59c6d110e7df7242ba"
+ "98c47a4392c7f2ac1c6e9dae22b9eb74a76436088bd0ba6e1991e19e3af79cf3"
+ "f7defb6a1161802534ba0e7ed16534938872eca677058ac73467d49ed1125b50"
+ "dfe5d6d65a5d245399b6bf1bf1",
+ "2d4806cfafe4af36bd02f62d6a43b00b416f708e9685b17ac8e3a4d8c2918093"
+ "05769d7898f6fc85917ba2fd8e589ff7a8bb84bb7c12202ed279e06409a5c0a7"
+ "d324bc46ae4f9282c9023d3dfb3a7915defc164b3f08266acf1241f826249815"
+ "07414e562978351dc8b7a79ef531402101a8d3d3eaa3539bbf62aad99a3bb11e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.3",
+ "238a",
+ "a5881acff3529f251b1b9c619ce9f9df91e0a03dd889163646871a627207eef1"
+ "47680c32f450a776e19f54ec055dc68b04bd4d89376df3eafa6fcaf60eb83184"
+ "3910b625b64f25d9299afc306a23765380455194b75dc0135d27c3b7d72df908"
+ "775c7e90befc0c5adf74a169ed5868f3d634327a05781892544543",
+ "7710eea8657dfd1565166562df0e2e840ec3e3dedc0b802bb0213e47a5ce97f4"
+ "b85ba9ba141977363d8f54b06d578d5b2a96e969cfa915df219f002a85d03257"
+ "047b3116a1c4ddaf791d93982d1b9ffa243186e9e2b19ef0741ce98de2a4a158"
+ "6e5012c481de23a0eff882fd623838d2011f4f63738affd7efb8c50f46a6c20e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.4",
+ "25a27eb1b21f10cf9d571c3305610b97f0daee39905c6594bfbf452a9a00d9e8"
+ "2b",
+ "2504618011c673db3c412279dc8ad165ab7b6473ae195e8d6d41214918198b34"
+ "51a6508d6138cedc518d8012ba0ec79b386af8fa40b03478bbf2ba065e582d61"
+ "95ccbe158f11781eaeb1b1720b72d9b52127deb9551711e887dbd0b8",
+ "3572bdea2305e1785c754de744c4fa3fa2cb757160e5cb39a31497e1485bbd7c"
+ "0899c53585b2bbbbd99081b416efc68578db78e0ecd08da7a3953e386bb25c12"
+ "bbb87c78944283a8c80187b4508dabbc7697f43a8ae78a33febb15f3cd581c80"
+ "d49b971bcbd48e44142f58c2c91adb1ae145aa9a83b3c5815aa1a8ff8dd231fe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.5",
+ "59cf0b6b50ea",
+ "2bf19160df6988935bd246106b8909dd7bb3e51690df84d76e4d31ac82104456"
+ "346b4c3c9ba7b5e9e68ee2086c8473c68302e2599abf6b31ceb3f781ad6b5689"
+ "86f21cd6d755328fb83afd5548501d070ac2dd8f5cdfb62cef545e815fe382bc"
+ "0c67b676e5456ebb9ab67df47740c6a43de3f9a2477a9b",
+ "2ed591fd4b357e94f481ba84ff4ebe7ae431054e5cd98a99589648e616cd68e0"
+ "d4724fa8a6c599686bfee1747ad077dbedad45f1244d7f8e00da3a3a06d23132"
+ "d3171d744ef14e1e97cdda109bd2e556a5fc7bbc609a7ff24cfabef4b56cbbb7"
+ "0e050653b69848d7113075a5debe7a468215f8dc08e7ef84fd55778cd5b596e5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.6",
+ "e94452f50a5edbe67573ab22309fa21babc6d22520e6e83bf72e7afa6d71e202"
+ "96daeaf54a60c8036304879a2131d178780e348ee0120b997c",
+ "c530443a16efd8d6d72ab4443f8db24491de99d5aabe5188b3f61dc0483b7ee0"
+ "0b1c13259b8ae2409f1ae62d9930c11a4ddef3e83582938893f9ac668f79c64c"
+ "7f5d796d",
+ "0eee90c70818221ae2704bbe38d68f8e154c6ee7ade53e2a1f4d1dbaac98c575"
+ "91ebb6c638bcb68e181435b70001bad180192bfda05732c05e7fb5af22aa89d2"
+ "a8ff80cf9f0862f04c05caca3d2a3a5b0779946c6ddfa04cd79fa164d602f1b7"
+ "de5c95be85e9608467e25c29d035c4660906269f6dc00a472b0446ea56e72a59"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.7",
+ "1cbfa0e7b1a10c13d75077b1cbd80310cd2410340d5f537293464a6781a9cc30"
+ "2cb5380ed9267b3eb23cdb13",
+ "d36b7e1799059d1ed1347b0bf8247c6be5187d8f15219e3cb66ec62e1ac41ff7"
+ "ed357ed7ca0384e31d39948561fc16cbd96b7e704279e572bf564e06c3a3401a"
+ "2714dd51d7215beba1c66154f60dd0cd4d",
+ "9c03dc0133a6e6aaba92059bdf5a6cc1b144b90d2a94a48e7b3cb90b0bb6f624"
+ "c7b1d172331e4323d08d2e8e099532dcb3b2a87ca420749fc6345c0d86e9abca"
+ "71af09a0929edeeede83e72244203b2bf45ceb187e9db3c7d3ad05b23b59624c"
+ "246696cfc75806391402e444e397496988e1e1f42c6aded30cdc937937f30054"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.8",
+ "e172a6b8b496f077738b74f6d8b292dda607f2adbfb372be37ee000888bea31f"
+ "99cba1cf3932e4be3717c9e168901a32d1b820be4fb0137527a2481877fe01ee",
+ "840ce13bbc9617dc9f3f26b147301a6f46300d7781a5d981162f869287371f1d"
+ "5958764fb00b055370ec711bba5283fcb00b83bc02175ea1017bcc8353",
+ "993e396fb57b2ea6a1a3fced9a69d361cbb6265b26503c175f84c61a41ea3e1c"
+ "e4fbb62e01d6420e22fef1d9e28a5883e2eac82e05f358ea75f77da4897b6b64"
+ "9aa47428394193ddec648c3a7fb81cfcf4b51ce3ebba78aedca7bb917b35b3e2"
+ "2aeb201cea96592e50e0d2841e7d2ce0d69ff3039dc01e964a977a017683b387"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.9",
+ "c8f0ea23e06611e4fd27b61db7920c55f3c0a222128838e4cdb062e176b21fc2"
+ "3253558c5d40de2dfd620fb7cdf1399c2af8fc77ca3335",
+ "164d77b5d26ae6d7abe7caed625d87c211cc509ad0172c20833d8f98cae38a2c"
+ "370ef21d4096da841dbeee948ec63403cabd4a5f71ace49364aa7de20f32c988"
+ "337a115f8346",
+ "7a8f15eef510ade8d5c317f9064ad7dae6c93e7cf156a73722023258f8b57447"
+ "34700034a3de6f137af6e90046d86e9b90590fa5a650cef4fdb4d3360233af86"
+ "f4a7a23c243d1951c666b673c33c7dec4f51ace34b805c0a9e67e209cc7f9ed6"
+ "9b8f5eb5c553e0f15c10304bf56d7be171f31cce88f37d1fb4a2a00418897576"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.10",
+ "19db242205c03d7fa9935d9e04fa6ecf38a51ea998ac8e4baca6cdfd6a0ace1d"
+ "f367e73d23c240af76b62e9fe9215fe943",
+ "be495205556956fae2a22ea70ce102de066c9e58959606217484a5b15036ffa1"
+ "d461239dd47b4f381cea71516e2db0fc369d72b440696512a97288f06fc0bceb"
+ "968286e995e02d218d9c2662",
+ "5512b3999b30c9c1440e5975931d55f21e9eb422b62dafcdab5d5003a75eb124"
+ "819986361913361dfc46ac29aaba8e1aa02e1ba44467162d20f63ad170fe0d87"
+ "a53d93c64e026b12be6bc2b8eb0e57c039eb60f32c4b527035f703a7a8374bd7"
+ "faa7b5404a3c5aadb792e25ff92876b23dd3a7422c45266c6d986eec5334b9ba"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.11",
+ "49a761f8c18ef92362d6abb24c07fc728255842453694e17605899f437b31ac9"
+ "8db516",
+ "d8cd85edfa0a84d076a9f8b2f93daaeba9ae374381ea4f8ceabc14f62a4ed763"
+ "8c1e396757de3ae2b7efa3a17c9a5586da84a5e50ecded61087fa6f0ce938287"
+ "998ac1b9bc3321a7ed160d286704e0526ece7b30b46814649fec",
+ "9b478268406212ca0530f431bdb26372615084ca488da43451d25a22b35ac6fc"
+ "61e37074a5c22bc1c701db1932b8c557b8487cea566050e48ad6e0376f8db419"
+ "8c4d27db2e6b28c25aed837ef47742d5eb8eb1d8b432c9d573cd4b86fdf32c52"
+ "a3d0f6cf92cf3cd9519677a58b1d1d994fc1c9057ac106e816045926b45b00e5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.12",
+ "84e828f715f228a60265",
+ "f7f275a853d4e126d7d0c38ef703f3fbda7a9520788d7a81a31b0530d43fe6c9"
+ "4b1b1bb10851209db26ac4b888aeceea7713824c2938b4c6431b2b03c693ab7b"
+ "54631541546ac40394798548fbba95882d91a17c27e7dd53026c96791ee55f24"
+ "7d7f898feab3709a132a782666a14d0df1a84e",
+ "4e3fe96e8f96e5b3c611cadb96ed51042098ecc547be7b88f8dea765ae14e835"
+ "0cfe39dcb1c1d6e4179ca404d5384d87b0665075eed7da7aaf71008e2467d70b"
+ "fff623b4594b6dfff90e3d8485f94189486ca0ca9e722b2a777e25b582f7ad4e"
+ "c5103ad767859ac59a1b8c5c1971301748fcc264f6c929364a8d9af42255c0f6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.13",
+ "c4797e8a6f269bf25d4cb4ec3fa46f8f11e6b369fbdaec1e51978358d46f3cf3"
+ "b842917d967aa9d30b183453937a682656b27b",
+ "177742197f0411443bd87e28ea88d54b4f2c7ab1dcaed81a56f8d78791124454"
+ "028504d322e1de346047a493933e87628ce08b06c017082dccd38b48946514ea"
+ "377c2dfc752adc24fb57",
+ "7984c3bad86a547990e0475a484f8dba5d4dceb0d3e3fce071d6f87176b7cbe6"
+ "f8112d81d7cdaad77ed0d5788e65f8bf5f0c2ad0df07ccdf54b2dacefc19ba65"
+ "201ccfd361d186b7d9e269aa1e6ad2c72bd23f58084fdbc3bc60e17a33e3c55a"
+ "95eb0c38a081bc0d3981db26a7212d6f691b336dac46b64ae22538a7b0087f25"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.14",
+ "a5e9deb1c20f982d5b7d4b87d799461f053d919e",
+ "59759cf5f838d952493d0f4281e3ea0fe216971c0a2e2454b96c8a11b4c69127"
+ "159024db6ec5c33640d120295899f6666c9417b202a86c26efd7c6134c92fd86"
+ "b8323d174a62534881382d7c6c9e1b8c1e95daf210c3e9ba43e58879f34f2fa7"
+ "1ef6ae4b68d64147be",
+ "70ac102d071e3d902281836216e081290bb5dfcd5668d11daefa0ab064599d0f"
+ "914b472961375bbf5f2a666fae0f6a25bafd44f665c17c144dc4d4cc0a5d5ba5"
+ "5c47a4cde959b32baa5232a07fbf9378c9c53ca2b37781c93a1cc8d6529478a1"
+ "c673034dda7ff33560786a464f5b4a559c626ae295bc91d0eed9375f49e3e4aa"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.15",
+ "739fa76dbd127303b7abf93e1d7ba729755d6c811b5e93355e0c011f74464c7d"
+ "b479193c3fb7380a62a0c006a2d1dc49a766af63fba4527cd157506d62c21a",
+ "a0b4daff3e26cebb3e4e3a43db36c466fb8ce605b25af4c9da744b62d41f9e62"
+ "c2285c390d60d18e3d7e675b4ac3196724451946bc1ccf2a9b562c4533c9",
+ "2b798091b3a391533d62dc0e417ba6deda005bfc30ab7dc82e8f9bcc7417bcb0"
+ "04348c6d00e537d2722b843861489245ab0d51f211447dac33a3f9dd6f3ca66b"
+ "bfa0d1adf98bc9099515926976b9258aab63204ad89165c87bbefd8d988534b3"
+ "7407df7d43ad391eed99824728efc3a533b789b47e8aa7121617474f3325c51a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.16",
+ "5a44b547bda19ecca1dc7bc04550205f66c5de0acb",
+ "2f5485d25fe5ce40ae62a112976cb4a539b74d96ef8be873325e204bb3f86607"
+ "a16a2c2ab50f697809ed03017270ef20a102c43a2c4c3be6ab7a8ae2dcb56984"
+ "d5e065524593eb7070834ce553f1756920bbcbbe4fb26d35d4adcb59df524635"
+ "6ff12e7aa9ee6def",
+ "62d1489a403a90faac677abc174aa7243bc751a964695f6c32b39de018fe4643"
+ "4420ea7659be2c410bc56c4e3e7a1b1677fdf4adfb2324f041edd5790c4cdfab"
+ "3655e07e41fe9d73292151b0dd5b96fc84a6b20f6f3bc0f60eaea8d82917b210"
+ "83055940fc02ee3e17c378bd4d8506d08ec45f33de5780f01bd318a9a16787ad"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.17",
+ "16802d803c",
+ "02f0e762c33917bf6a4df11fa28473547a5ab0767dd3a61a8d05cc1e6f98345a"
+ "f1a00e42f62bd8eccacbd37f4ccb809e9e055f73d3375a6041d9782ccd85d59d"
+ "14f43e5c9410257b906e41cc8b973547d0622bd21db29a9138d3b1bede38ce5c"
+ "94c4e1d2a0a8400b45bacd4269797c385aa3066e65807299",
+ "753b9cee70d4181f95638780db7a04f9b12ea38e5daee4f2894c02673a53f485"
+ "30746ff2858b787efcb42d45e531bea1c8dae94877153b956ac7b28746ee21c6"
+ "31bf9a3ba79d2ba81321b79603b1d01a4e909ed5a27cbf27c957783d3f7950e0"
+ "1dd8f447f10eced36f2d193586f5cc17fb622a05faa1fb5cd2aa064c0867b1ca"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.18",
+ "d6d0f60385979ca506fc833421bcd22da6a06a8f370a7f02fef47c1cb2199f26"
+ "45c75490fbf789ad524704da8a2766c6",
+ "a03c05672efe23b44b26c793e7053a77048ba2dbb4b53ae9751854e7add7d67c"
+ "12cbd16c0b1934d2c23e77cdcc89ce1d45c761158aa8613171a73901ac1f61c6"
+ "5705533d3e639b57a248929179",
+ "0078dc48a66158992aaa68fc3ccc628f92a708d0b1d43837208d534bc3f9be1c"
+ "1412ed0f9f7bef49430dc9e998f752e0747768b4ae38144696c003d6d25ea1a6"
+ "ca6aec924a9f4d9b575a8f136bba29bf31c13b7050bd55d1000d433daa6cf10b"
+ "49116c8063107fd3a5bdf61545c5d863f6a78881786cc8dc376d36c911368225"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.19",
+ "b0381cac04f3101504968f26d6554745383bd171d36156dd3680b3db6fad7f77"
+ "1f7d",
+ "cc548a6777cde953c15a71fc497c0c3617b1bb056b03288d9a548b693bb4308b"
+ "67c1dac38bb9b8c9cc896ac244a9e30d132430f4ceae5790343dbce38d056f27"
+ "b86bdd9d32a8171f3b3cc2fd142265ac9a68dc353627339cd88303",
+ "456f7c3e3be85ff7bdd6b5b250bfb81cd6fbb186d25e0c1c5259d6788793c541"
+ "edacb4ecdedb8a89290134a606f46a81991c13b120e33056bc0fc7e97b342d0f"
+ "20051813dde45e0b596a7dcd6904903b8fc076a6e24b3ad8013416d9fd184830"
+ "554ad54d5548bcaddaf5920a024955887825dd371ae4ef90069a4f311c5a1729"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.20",
+ "e5",
+ "fe0bc7acb56ce14b4e2f55fba0e2b17154907be94ce485c6984d61f67c04a740"
+ "a28d6094aeae33b3ea0d58183e1ec7f601b2ab820fb8a7ffac0b4f960e1b4acb"
+ "e57cdc35b225c497fcaca03019a295b3e66da96f5379ccd1da44479a4f2135e1"
+ "063d71a282c1e66fdbd5d953f5718c2539d00ce49b451820454d2d49",
+ "5c533677a1dcb36395da9a6d3477bfbf71512c6a933d041ca31344e1cbe1e555"
+ "88a1146e3dec4610efac41b5f80266026652b3d7aa594274d9d920d33aa0ad9b"
+ "4ec59aa880712a1d1c368a457f35c74388b042f2498e9f4bd45a26f321dd9eb3"
+ "33ef80afe3af9f729ca18f42c88a7173858c542066f8a252ccf0feafe6b5a924"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "ddcad6a38b3704cbe06bb1b51d1162584978a4291fb673b4ea30ed8b51a4bf26"
+ "1dc9f0f469ce9988a089f084366464a180cfd7171069a6f636d75f23401b30cf"
+ "43adcf870ecd24582f4da295229151ddcfc7c99186b245885cb63196c4a5726f"
+ "207ee360af3ad8c48385a4e0841d7d851d54545de767d8f999dc17eb0c571189",
+ "010001",
+ "5e48e03dddeca1a959d9ee4da3f1c3f0ec2ad0fe7a70c177632731944c3cd0d5"
+ "8f4c4d9659746e685a76c93c2b333a643db21d29bcdc6d11b5f6908717b57765"
+ "99ff3088b2014ffc51f18d932224f1059b2239ea5644e8069a5cc431aef60738"
+ "0aa924c158abcbdd9751f54e6779c4ec232168b0014f4c8b497be949aee65751",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 6.1",
+ "a3e15275fb33aec37bd3dd582e19f5d38b9d0d",
+ "78daa61c07f941b4b440e738338d06cc157a01574a72fa78d363dce994090422"
+ "0a7132356996f07c01d54ee54fa32c5faa1b90d2430c80a23217e06bb1c8043d"
+ "61ffa18aa1d18e15e430aa121cdff43fab2bb0debf73e3d5a75b46f90df73d65"
+ "6bb066ac1c768fa383e4",
+ "9bf1dcfc654ca7a23d80a12c09c259d04bae07e831f609e9f035d356414ed106"
+ "f9b46235fa3da91a32b8fdc8fb8830c96523dcaa9b2538fc0102dc0f7a5fae86"
+ "35b3b12314c39055faacfbe00a15163424148cc9e0f0ab42df09023c052a46ae"
+ "3f86a18dcc5380ce39062e362375d3a5f9e3b34a5da25cf0de9cc19c4d04f63f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.2",
+ "443ab03c4604dbd8bf8006aecc2aa8de64a155b4f90cdb0859986d5ca3606603"
+ "59808c59bd9c2de775fc18520224b669c325",
+ "3a6a6089f727dd169297a579fcaf8ea7f8e12d5427f1f7901a9022a21e2d82d2"
+ "f08e63baca267b653aaf89de232ba3d392d1cb49dd76b388b2dadfb0094fda97"
+ "18f1783738d18fa7aaa629",
+ "5a0ae0de28fd33cc9801bf4dd3067123745363cace4dd8b7b8b811d6482f5912"
+ "0c0d653eee86a61a012a180ec5d17e99146d0cca0a587c85cf01dc7add84230d"
+ "9180bddf5a7719f69d1fc481af6f47db8cbd4ee1871a573fc8767ce8beedb5c7"
+ "3fa93f0c53804afe2e76ccebb87cba00cdac94de40e2b0beaa8e2e4158c77850"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.3",
+ "d1ba30e88cdda33d2b41896f43df081eef20caf78d7c1b970c6a6172e83839dc"
+ "43d4be29f9a772ba4159738bc6132968618dc7197c0edc57a1",
+ "9bb62bf9a751fe418166436898ede835cfaee2f50efcad60942f2fb2da1a2038"
+ "03f0be80beb17ffad0dab218b128027f3497a4f8d41ab9a1be264e96b4454876"
+ "7be8d4a7",
+ "81191c5475273de66a41bf5604f32b58b759a14e7426c746de4b53baf780bba4"
+ "2b42e9278aa94527f0eebf855f462d6fbb2978a4653037d8b448e1b807a1831d"
+ "bc5322d066984eec28114fb7201c796b573adcc5cc927f3a5897b2005564ef1a"
+ "2c0167f54365511834ac6f4958b8318d09e67854d631ca52807686ab705d71a3"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.4",
+ "a54bc2278b567685c9b56854e4c1c406d9161747c6813480163ee3af23b21ed1"
+ "9983e0f42bfc9325cb5c82e1a47b8f",
+ "ccba5fa5c94e79832ab046c9777495b163bd3af217590fec5ac48c62786a27f3"
+ "70d2859955e45afb2b79f12de4161145be62ac13a03bf48195fb9e5a18b82deb"
+ "bf3ddfc80825d593fcd402e74eef",
+ "3de4c3e059357b8a54837ea15962cfe2007c5ea8985c93519164a689b755b61c"
+ "8bd273969d333c4bcd9b060353c37baf13eb422f1cb97756e6b4946adfe1af75"
+ "e9fe2d95b4b13da1732bd8b8be1197027919530c347f3dd1039e348a53b116f9"
+ "f8fe8936a84acc39f2e06956b678d20fdf9517072e02f57078fdc04659400c5c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.5",
+ "f3c00b009e5e08a63be1e40035cdaca5011cc701cf7eebcb99f0ffe17cfd0a4b"
+ "f7befd2dd536ac946db797fdbc679cbe68f1a2f36259c558f04d",
+ "e22d5e43b1eba1ac0ce65c3270510e0f13c94e9624ee525659ef4d57378820c9"
+ "35229b3099aa2b2350614f8cc4295815a2c9edb2d9c59c73d1aa900c2134c0a7"
+ "d0909c",
+ "533e67a2bc5b3f01342d8cb8d925d73b4db34cb675da9039226a98e4d813c620"
+ "110990a8e6acba50fd04f3307debaf20d4f374cf6de0d9b21d86e266079cf2f1"
+ "8b4503208a215de2b11cca9e3464fc5ac1dd7e96b2fc0409e42f46a50612a6b2"
+ "061ed1619a7fe46796ed8f52069a5bfc8408d558f52a03332ee8eddef8f745d9"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.6",
+ "aafe5b271111efb8792f5aa92383072976b72a0a272f90c52461f88afb1bb6b7"
+ "ec26381c6576a41087a039809d14f6116067594ebb",
+ "750ef0869f8c757ef431578b45a6e741bd1d960efc3789b10d2bde273818074e"
+ "bfe5faae10ac244f89f6c02de5d1adaefc7a8fd24d7bc376fd65d35e39508c42"
+ "36acbe2d5ca7694b",
+ "344d4337612b22dd402be379e6b2650b519ef37b7ab485819452d167c1b215db"
+ "d3fb24f9b2f9298669cb1aee141a7d8901642043111fc38b3f40ef0b7ffd7df7"
+ "6c2d92e329411c75e0f17285bb6bb82688128ed9bb951caedd7d067edd0b13e8"
+ "275ac88625d97ce8d20b69b35738b2f4726e2984b8dfa86695aae88d9e176df6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.7",
+ "a1224df9aab6587845b2a393a5a876c17d959d535b5419d412a9a531bb437e1d"
+ "ac1b546d62",
+ "761dc4f51bc8518d627c45b3e9818b8542a06ffe172be3af5ce7a9053fe54e69"
+ "70124973374dfcc1f49fcffe957aae8c9c3b130f4605d2c3efa2932ad083dec5"
+ "8e70d4f6926c80b5d4891a1a559edb0caffacad75eb26483",
+ "785f6aaab4d2f318d4af37b6e0074ed5a4194fa605a7ec87d05a07f3349b5b92"
+ "f5fc4790eab13786cbf035c78ffcf1344d1f3ecdaae01672222e6d4a965559e2"
+ "c08291cb1d4c2d4e68ff8ee71523f6ddaec50a4ab22edca247364c92d87399e8"
+ "a71df7436b62d8ba8ad20294cbc60dcae0305c7973f7fcb4a5cbed15713a7a16"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.8",
+ "1e0e3f650c32dbb2f6916f36f135bcae881d545507402d6afd3d5b3bd8385a50"
+ "b4fad6f78949fde62164ed7689e5f9a4",
+ "eea90a54d016da7e8f0876a733b0f2a06f90a73c1a3cd639b6cfa906ce08ef78"
+ "8bb6fea74f22eb91a6ab3284cdfc1e72e63e78d18a64d67f9d1a291949ed2e32"
+ "3e91dc033876eeeb09ffa71f59",
+ "6bbdae20f989bfaa5d65dadcd61a86b66307a0602fb551a73806122db188ec1d"
+ "41e84daa2cc7d6be541e12288809a17e085f2cafa8ae13670e0f3365a1471cb3"
+ "157c06e0f63b8200f3160c163fde7c901ef326e5700c9f5e07fe0198810fa80c"
+ "8c5dc53a50bce254f7d19901cf6cbb603413e41f9030e739c8ba964997847499"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.9",
+ "73ddf0a14d57ba65b4f693ac761e202b1e5b857c8b3404e14185dfa8aaf04989",
+ "fd433d7b0176b731d780dd6c5851b82f176d62b80d96aeb631d7fb8ac5be55ac"
+ "217f4e08bc7ecf81f8e3f5ddaacdc6c2178df781882397533a638e62f074ac48"
+ "8f4c12aa57be2ece5bb6e9096cd92259a45b0b032f101431a28b8640fb",
+ "ae97ff434e9a5ee487761db356900b063737465be5058dc03a28a322e5c0e091"
+ "b799bf659455cfbe05427ac4d04405e56ee04e063a2373dbcb9b4fa16e430794"
+ "6a49b35634520d416f65c3c322edc54671569128a2a152a76fe444c430aa6f03"
+ "c4129c6e2131755d764cec4a1486a81ba8a3168d16e74dca8e77bbfd67ea372b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.10",
+ "ef3e7698e7d9cc863b466bb288556e4ac25282e094fb5b57c17617bb98",
+ "db90a7580d8d429e22bd7ea5c7b4cd0c65ad0e2e27f53341bc23a8b1358a76a0"
+ "b5e94fc5b42a9f756cc63b9d623f551767fbc6f7114e40ba7361fd32d6f8d772"
+ "3437436df724b1327aaef7b957562768f8fadd57862ba0b314096a3b38770e31",
+ "43f8cccea812d3385f43fa837cb5e6fa590f1affb862d2caccc6d8e8bb5d5c0d"
+ "50ffb9f8f8098900c12e772a847b378157782b0a9040f7a616c2eb058e44d4a7"
+ "e20b485ac29f40d68e03c39ddc8dae7e7e09e28f9dd2190f3a9f3574b2f63400"
+ "1544363c861fe27f7a39236692fe3582140b2172ce647eed417685c6e1db856c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.11",
+ "f86918474f881697111bdddc1f00613eb2c3d9c1787668353ebb02b320a326",
+ "cb7d99da9b11ea57f6405543447dd15fb5cca0a10f3b69b4d23309eff2750c48"
+ "6ca655325b55a327ffe8bd6dca99bc8efb5bc2942ec039e28425e4a56a07d380"
+ "12f10d215a22d637685943d364725301dd40e217228ab791598998836bbf",
+ "2a408780ad514e5671fe1dfc367d7aa465fc3469f1c152aee18145e0f5f0759f"
+ "4469b43d55123f5dc9ffc617f23fa49b78960219660ec62274d6c59ba31460bd"
+ "10941ebb5e05694151c57b5b9588caf09f455020a54e977c3cc027dae31f2ce4"
+ "4217023e10adb6f2d8aa0f8084fc458605803fd44b21abc27bdb8d4c561784cf"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.12",
+ "6a40bb60708c5a992ecfdc7ee53f54084d19affd4d21",
+ "c3f4faca56c1ff07d1ad103707d1b6682047b4d9d6246c2e5c4b0ce6553d5531"
+ "3f8f38aee5e4d8073a55d24ad796c4b76126c8aa61c46a4ee85fa9057a526cd0"
+ "aa245e5828f2181b4a6479868748e7479f4034533c0f3e1eb435fa47d53b58e4"
+ "2c9617bf7e777e",
+ "c46411c7116fe6f46f1ca0f74c6081a55df41d2c0b8fc5d38faa340b5ecf7183"
+ "f85f88c4fb28ac5fb1f18aebfcfc10bfdd3a19002c6b52241492704b6fe63d61"
+ "a73010c149ff6303283e9978cd845404fa06b8c698aaea8f861361d886b2c0f0"
+ "1b47a1a9a3dd903f8a58aed66afc85e9b71efc3f55a121667416a300001313e8"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.13",
+ "3252fe99620974e077d6eb5575",
+ "bf069b4bcf15448bc39e45f4426aad0d5d82b74e93ae1cdd71f71bb9beb9b23d"
+ "59732f9c8bc6343d130231de18f7c89fc2f422189cd927e509b13197aa56d81a"
+ "7376f8333e4742448cc892de4044972c7f67dcbe8544a90eec59e795ae596408"
+ "392af5776da0d6cb29c7e0a7868130a7",
+ "7653cbff586892cdd258bfe6baebd99145eb1b22894e1a764d02b2ba995952a0"
+ "1258208de1a01d8e8cbb5cdaf0d603694f88255e809097b70e9d79e62bd5c0d8"
+ "36dcc29dd19b05a16026904205b60c4503d4fbe9933855e86802c75428d9a634"
+ "7303167632d33c5d9ecc8ae2493b58c36b2a6553a7b9e2b1358ae28dad50280d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.14",
+ "dc94",
+ "05e805bffbd1b74d1a5a838d857167b4c7d40a6cd3e68f31be4693b98cec6d75"
+ "894919ab18572c75822e75e9ded72da0679783a7721814e199160b7507f67f4e"
+ "de587c88be76815c50b261df308b314323730c1e073aa72998cc2f8e0a8a5bd6"
+ "5bf934aca8a64859e25f02c5a2713941c8c8e62720846dfb51c2ff",
+ "6adde244f0638c5ab745ffbab5abe1fe800b0eee153550c48c36f4249f9d5d36"
+ "b47b28ccda71a7dd832e6435ad0eb85ef7556bb84bf95a59ccc9c20751ed3e1a"
+ "d0de102994a712c514014692a67f1d87ca2e4fef29ec83e01e29ad0c978acca4"
+ "d5c502745a6c500df20004bc9bf16f5fcc69bf52709e31cf6a2b9fe624d9a364"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.15",
+ "4fae6cf37e9d5f59",
+ "e7f9ed4a0c3a646669039bd01f249f32bea1e6576c21d45189d0f891cf4afd62"
+ "32083a321ed2d34d070984f5e9457839b2ebc1e03a2c0d8dd709731e95b2e694"
+ "1ca0907187affdcf5a87f5cbead2f9052c38d0ee54e1f128ffc337de4566a592"
+ "5e1e947aef50881cbdaed99b1bbc1af513232c0ff4",
+ "46e6705eb1252debf8ec672c4fdeaf6988268459f99589bbd3054133d483abe1"
+ "e27caab0a7f0221b1b67a14ebf45126e601348b0434406da3a8c76d4f1e3f1a0"
+ "e06d0db823da5117b92a40b6f39f57e483a7da36e99b677bb3f76e6c5db03f3c"
+ "e44504ebd45e9f14fe0f613a2eb79547ab578c586d3b654a06fe1ef37a221066"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.16",
+ "cdfdfdaabca3767e70bbc5e9abf6",
+ "ac777f67299de4c1c4c574f31f674f6faabde031f8ec33e82676eb32a93f6579"
+ "aac3e959359fc573ee5c0e3e077653eff9d5f8db4b1e7acadb059971531f49b0"
+ "7c93eb9fdedcf0903a7d50b479676fcde8740afbd7d37c3a2102412bde1d3a82"
+ "44156ad8089d45dfdc91cde6c3a159",
+ "513c761eb1929aff7977a9ff0e61b7a1d511c8cb253924332425569a07e229cb"
+ "3901715390f7de37bd362c96fc0b0d79810c1e8b15e13b0032734778cf964e6f"
+ "6d17fc41c7867672b2540f569d0a460a80fad56b5f054ab8e49e409e9e0b8613"
+ "cb3da20c35c3e1bb99b7ecab7a00fc1fc2370f9c808567df89be2eddbdb6b110"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.17",
+ "b820c32e737daa234f29ba90647fc3bf0a8e",
+ "f5caf8feb42df7b6b389f50599a4ec20e619ca22d2bfc91bc7f14ae9f1229e07"
+ "c888ed57aa6ad3c1041044c51afb55217b0caa2334ad79f47abbf9b4208333b7"
+ "2b4ba4bb5fd037981dd80170c80360c14d5af51e5f82abf51fd36f021867a6ec"
+ "097bc33922acead9e33558",
+ "3e23251841db2e207a27101f1329191ab7fa6a701a526261482353a1a221efa9"
+ "d3a9d459cd2a2d8668908b783bb09c879a217f1e400f95b217b040a53e341c17"
+ "b93d3c3d65460c5c7f2b4d79a34b5a96117aa36751d9eaf233b03f68dba6a457"
+ "1b907177f828336e825a92261b623639bec98d3a09f872c2ec591b4c383a69c7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.18",
+ "606bbd613715ddcd92c7b6df04b36072f01162d008766312ca6977dd3a06eb95"
+ "e1bac7bc1bc6602c9ee644",
+ "513a5c9568e89b9a53d5af716e55fb340f8a392370e888a80caeda502e7f9dfc"
+ "175195a50e47071396d6ec554eb72f183be18f3bf4ec73b30592faef2fb514de"
+ "befcc65c8d23c4ad259456c1e80b360ad459",
+ "4721a23940188730f5deac85002e3831b149ae57afc69735a045ee3fc3536472"
+ "fc833c27c87eab6fc905e367961b312498636be6c77aa80b8da2f5d948aaa77b"
+ "5fab724bbf64ee89d281eed47b212c3295266577f4fd93a22239dee540c9400f"
+ "e56d7aef51df36a89ae92f926f558331e41bfdfefe35758b93ce1140ac9b6a54"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.19",
+ "1d82def8c592875008a5f89e7eb64e252edde9ddb881d37362317f6e6e6e993c"
+ "60233b0f",
+ "875e075ef1b054b5841e08450d78eb54a55c88b6d01813c107a09b74543b3f9f"
+ "e1b7c90211c62ea7338120d4ae0f73ba82c01d28f8194b3a396bdf50f9413a7f"
+ "b03be225fe0545db80cdf0f610a95fd90376e039e3831ff99e",
+ "8fb546263c1d1875c743f52f0267b2f2fe688d2542021049f53489ce7c359130"
+ "f8e11e3c461c5e863e4dc19f07a13a4c1a88224b26c5c0cbe2020245d91e1b83"
+ "42425252f53fc40e4b14fa02bbd74737d4022cc54fe38f0d27d8fea50f2fdd84"
+ "65d4f32f8ac03ee006be6233e4d1a3c16eb144b5d8be729ad304f82361e07cfb"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.20",
+ "8a8a3eabdca7cab0cc296a291ea8a93da4d2d2a196ff2f8d181fee1f",
+ "2e4736e4296ab46618b1ef34da26776e92ef66f7cd174ef94769724223a765b4"
+ "ebef08a88fedbe270560e5f67437cf49d57ea6620aca59898afd52cdef30a8b0"
+ "d9855e5dfbe347de77c4c0280b0f1fd44d4fe68906be8a4f12c533087bf5bcea"
+ "fb",
+ "03f3e4ba034831a0e30a4a3344cead61b28b43be31532c2d7637539b9013837e"
+ "dcb1f216d32fdfae73323674a2814565dbf29e712d18c4373964df60c9399fda"
+ "5414a0eb45bde8661a89091295a1ef71616a3cd145e9b318b651af175d4ec350"
+ "1d5eb763e8d35a2b72746e020b4ba59973834b2150026b432b179a9ae8172b7b"
+ }
+ }
+ },
+ {
+ "A 1025-bit RSA key pair",
+ "01709341d2ec0804a74034e8fa728642983d1650d746e449c9ee4079aa15e51f"
+ "1fc134242e524b0d3d0dbf5a5121939b125fcc863e514160b634e37aa6989477"
+ "6c7d33e1e7c619521de482a0aea45c3c6abc3f33e25d86ffa1393325659bf2d4"
+ "098df169b4072187660e277700199b7a3e3484b3845f6fbf3198657df8cbf3a8"
+ "1b",
+ "010001",
+ "6febf798121e993324972c8c28ccc65a2e6aa15fcde232da03e4464db4da5faa"
+ "27e42a7c7a76d9ed49486b27a9d785c67d9ac0c519ad8dada6bfd115d7cd75b9"
+ "9c4b59c76983a7015b0da6973c69fa950810ae2768d97588900562e86a6df7c7"
+ "14b844b1e046686a5afc667b13573a55be9b5b38b99bd3cf54e4344a2f2d0e21",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 7.1",
+ "da509dce45e24700379bfe5aa1a81c24706c1842d9b13e7a2e0a15d3a4af8e6d"
+ "08612dcaa15d460ece872988e3e90fb27e5ca5c10fa1facdcb0e",
+ "808c2046fb505c37695c8dc35c38f9f9905ab48a2b8a146e8e8eda3385ced95a"
+ "313b2dc6eb418367feeff79a02ad74646df7a5d87054acddaf34eafd5c1db58e"
+ "5dec0481",
+ "00fc3d0aaaf26cdf25a1a8dfcb71700fb65e2ab5551ae5f419b2d2f94cef0173"
+ "02b00abd9e6c6efae94474d18e68da0a7c17ef2c5fcc89071d3b07121b9c01e3"
+ "0ff053663f61f89fdbc49bdcf8e671669443919d41342845e3e99e46a8a3b48e"
+ "2398a88e5b45d99a17dd1f212edabcbcd300a84d398ef57935bdae959e6054e7"
+ "3a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.2",
+ "ce0a794749874160e5d2e4ff",
+ "f4b2c9f311c1fd41d47944b50e1755d4eac5ee65087c9fc6d2f075b738c64926"
+ "eaf7d4316bcdb63654d5420da61e0245f195b9e824aa0b06c88799b127fe9b03"
+ "6df36175c0a6bd80e4e0af6ebc2f4270b04ce30b9fa27f0435860fccf40b3dc7"
+ "eaeffdbab9e1766619bb016c17902663cb24",
+ "010cf74bebc2636d2c49d9c622bd76cc0b1d02ebb52fdfaec01c4ac1e756071a"
+ "8ef76e122a4c62c6ba3265fa4c905626d113d59db79ad65f8640b3c4344d7340"
+ "c16e38deb189e3a1b11eaab0b2606a7f82f5946d419acebbbb3a937d41e29b33"
+ "edd3ad15f1e7770fcfc30ae06aa01bcd03d5dfb162f87a183967553c2502cb5f"
+ "fe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.3",
+ "41d6",
+ "556e59b2c189587508e20892fa5602d249fbfb71a10905ed5af7b79be87111a0"
+ "c69addb19eef316d7c0b21817990dc3ed8c76cb23e830e17c0f43873159fab7c"
+ "5c4a6cf219cb1dc5c5da4553a3e0bf183b8e112b61f692a7ddf004bdbfdcc8d6"
+ "659c3dd80cb23aabe8c6fdf2675d073b662312e4accde91c1225e6d1",
+ "002a100495596655304bddf9097f78d9ddb5eb429b66635a58a298f1928eed61"
+ "534f80b4ea05ee39b02a64566f6c456e3b586e7cb43a88940ee129340f578e56"
+ "e72d8b2783361006d97129abef02cf1c1912e17f0cd1d71c0b328d0b48a4ac7a"
+ "ece3c005a6190eac22c1991041159a2ad1db0896015c4ff1d7b35447cfc10a24"
+ "be"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.4",
+ "0bb4abc7dc6ca4235c29ed0a2cb63fd141341e2c4c901e6dc95da9f0010fa2e0"
+ "22ccfe8adfdb6ecf4d89f579a10a5170be18c46a241ca7eed107cafe4a9d",
+ "bb80be7802dd8bf5fb5b1b86396654f4739f5d4351f19ce31b72c210aea1a2ed"
+ "2142d8d6f7ae374f06133a315c6264da65cef233ed3dcc8159d76c3a17f36d0c",
+ "006f1b6c1fb37ae5c8c024449abc3840e8e5097143eed16beaf67b6c7a4824ac"
+ "38b6f8c353b645c8cea4fab09c02fa6c325a507438b9645ec8230086b315e34e"
+ "7a56adb0ecd89fd07b98739c24db6fe11ff2e5ad38318ec31df2ed2508debca7"
+ "a67e240196aa9acd80329f4c4343c10b72699f9d6b5bc243995b09c46dd3d803"
+ "ce"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.5",
+ "ed26ec202d5e69740da3488406bbbd",
+ "f2fd08cc0db9a55abfebd92e2a9d75872ab7dffb0b4da13606e152759f866f22"
+ "eb8729fb8c9a5c45ba2f4acae43159a7ad3cf78e81fd0954909b1f0e7089ca86"
+ "a4588d8c87a1a61f1a48398236def9b4975e2549573f60adb5e861b7c3b2dfeb"
+ "810d13e297a6cd3f2afecb0e4f147c",
+ "00933c58a50c70150da0823a7c1e367d36e5213f66a30050fded72d5755b5f9c"
+ "24050b4114f53509988b625420cfd00ac1c8cd84489ca26b743fb47d1b64d0a8"
+ "808ee32127c771224a0dd5a564e636add73bcff7b473e9a12b7d464d7dd4a752"
+ "048661a8b074b9fa1506fef603dd96d11996a7d9e74879f99bb2d91c37aab135"
+ "72"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.6",
+ "dc285a26395939e7997204c71a932f795b4de401e96f34e189363237e9cfdadc"
+ "61",
+ "d80bfcc291ce518ce0bb6ae934dfd85658b239fb4539cbe05da126a898b7f364"
+ "887c0ddfb1eaea1d5a90de7695665c55822a1172cb5be8a112d28c8602c513be"
+ "48c292f05972e6711a44cbc7281715094b490fde29165a6b6b7d99dbed",
+ "0157e7b54a341b8df8bd9b99fc2e6c58d886fc79e7442a9e76d0d67e4858c4ab"
+ "f0ed25c33df62e2aada399dfeadc7ff68928e6b9007102ddf809f5908eefc10f"
+ "2a73710609231f5d45e00adda134b602dd0eee0f6722494b7e4f7b405772c831"
+ "b63729be0f1c4b6d2a542c1565c7df231d9e892e586a18ec54377376db77f813"
+ "84"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.7",
+ "4647d841c5a0b9973a91454dd1a05ec0e57503ed99672ac002dfee777f7fa506"
+ "fb41b2ec8b8d2cdb9bef0133bd5e3a7d0c4344b28fa8db",
+ "f527a14e2e06e73f1c245d190d02cced011e468487acfa5e0bce39786b46a9a8"
+ "c751a8b4406ccfa1fc5b7ab9bada7b4ad452467e50b7fc41318edc73dc2d84a2"
+ "8a081fa17905bc",
+ "004e03caa9481d7f9678207c17b6822a5f6917ed01eb402e7f230135a123cd9b"
+ "6de3bec3b9bf338adef8076fb7652fc7e3a373fc1622f1dc679d415c3200026d"
+ "8a8a50f8db6a583f666929d0318ebf91d95912fc06102d9be87525a736b5af21"
+ "e16de3efaa66e9cf41ca73482323dde80eec308581a44ca3aabf76dd481de652"
+ "9a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.8",
+ "ba10d47a9f624281",
+ "379fdcfa5d8c6137c36bad143fd9b1f7e894fa0e9ac0fb9cec60e86c8253975d"
+ "8e78742108495e594ad0898fd04c91e401e7c88089a87b4a4a82e834cd3777a7"
+ "d3f80e6486812d4ab0d33723162bcbc7e081a99d3f9b5c3ba44b19bdf884a462"
+ "6fd7def7674057bea082e00db4b761ad753ab5985a94",
+ "00c4965e2963d7bc5b1044d8fc75eb3382cedd9907419792efc88c92b1d5c390"
+ "fab190011c518ac9ce45c1b8e7276bffc7c7e05c2537089137a98df6e0c69202"
+ "0ed654af83339bab11927177f2f523226b4fe64b99c1729f6c922906bc16d31f"
+ "0c94dc2ea413810d55940c97afdd4829fbf1618a8c9de89dc24006e7e421a58d"
+ "38"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.9",
+ "efc7489fec779e052e379c1ad9045903b6842a9ca41b48bddce58080a5edec63"
+ "f36ee11560fd",
+ "c8ecba627214c414d7c3fdd316c2d82a98535728b9a9376f69a953d7cd1cead7"
+ "1053dbe0140c7f02bd71e0137fea29cd4c21a58bdec66640990d28c10b701759"
+ "3c1d11fe9abebd7124e1d985631e94e9e51241260f9ef1f1",
+ "0032184ef288fa0aaa0c2c1a19e7c29f81c7012f4529eb9eeb53681f6247f8d4"
+ "35691345a5148a2c877b2b18926bae9de5b317bac0e902c96025eec2f9eabd0f"
+ "9e8886ef9519c8249feb834665c1010db7624f487e161f89f6ae0018c1f4e0ab"
+ "5472f7f0993561cd5985f383d049dd832b82c83748b2281bfb99d9d5008dc807"
+ "de"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.10",
+ "5b264ff88defd3c299993d81129a6e5dd2b57b",
+ "0be7ab5b29704843c1c0d7e4ef5e93f3ba717db7815af572e3a9ab3f99b1ac9a"
+ "22b92d9b43da2b9965c7977057173c03573f32480a927019afff0e0e34e4095e"
+ "4a4d392dcd1bd9f27d32fde7159f023c83089e88a71f2433648ef8c84045b9c3"
+ "6d8e5f6eff034b91b70234",
+ "004c65293556f2fd15ab90eb22e07533b3dc17334f5eed27a3993180c56c8e3d"
+ "8f51eeb27595f878d23665ba3ab0e728a5aef7234f6036b023f871c2d6552a18"
+ "ad5a25bec55bc76bee6383461281d39a30f6d66092e0cff6923268fc043cdf74"
+ "7e8d5489504e7db30a7bd91a2bfc6c1b3414405701753d5b85ff7352012d55e9"
+ "23"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.11",
+ "72e20900e5bcc23cf879ed3531889a1ed5aa3d5c792e34e3b12690d9ac2403d0"
+ "f6f78f5923",
+ "116275e9be1bd4e6f203ffe4f0ab9a32738410e923e83971ee9a6b992c650a03"
+ "1f940f6ef33d6150dff8b39dcf2250d5665c04273b2be2dec99712bbc012f75a"
+ "31b30ba06ff9ebe3b89f58a68f2685e338ff6cb8d4181a8a14",
+ "00214a83be453a75bcda9433a7b951433439983072071cc82112b77742be0c38"
+ "226ca3c6f38d55b9ca3f08c8793789796e6cde67376d673f5ec57dacc374c4c3"
+ "173444dd8a6376de8f9ddc31a4c060d772f02eb749512dcd040231175d0b6942"
+ "a947b2c82f7c19e2ce875000af84274cbe2adbf2fbfb537ccbe2fbd072871378"
+ "75"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.12",
+ "16b110e2909b11b0cf36b052c6f3936a2ca13fc3a5",
+ "c2bf9e4fb1ed70ca212d15ee8eb3cd660eb65c5278e03a3b10eb12b25334a472"
+ "8b949920122fb992bf2ce430103d74ab74e6d6e762b85d6ef9beb7d72598f293"
+ "a43562e90689541111511d314a9c46022376ad055d54ced6ac1f36e98c2b25a0"
+ "acde64dcf6522c3d22",
+ "016aa95a082382c10c045310fefecc8d17dbf216d8edc04bdacd4f524de485b7"
+ "fe8a26f14cabd297e7f03b3c85086a16147d5f6193919bb95a53c146c784c00b"
+ "5332e018f643cf958724cd08075eb64ca5680c27c705d40d88b9d7f426b736e3"
+ "c5f6394ea683b65c2373a6fceb14f2ea851ca8e000e24dc8f7e7c81b1d4e720c"
+ "36"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.13",
+ "3c860a28fae8da2ac0d9a33989977ffa04",
+ "7c9699906c9f1665125c0b10673f3dad98c91a4ff0faaa647db554fd6227ef50"
+ "909c97b706092be210db2c24ba9e8e6a87f9ddd9f3f491291029ac6ee46e08d0"
+ "d7a53c462db4f0fd1cc23ec8f55eda07f4ca0d3e3cd37622855b4db08f64be3e"
+ "26c3e97875171294eadf86fcd6",
+ "010c1e04a858c615ee9695f64ab2db99806da482d2b460293c46dc7b717a5976"
+ "a3c7e36d8d47a84a34d63cdfca2c1e38452573ed44c3a040405ecf3fbf368341"
+ "c4a1fc9083a8f5529367b99cb89fc5a08b8f3475a0d55e3e42cccbeb20d04a19"
+ "97eeda4e3cc9e992d237ec7d32fe25845ab024d5882805ed52f10ed7d25d62d0"
+ "af"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.14",
+ "4edf4ad3440f17b10d26afcdf4e444d2aa61a19755a62107983f0122fb2a",
+ "e020093939b4189e934cb62d27ca5e9719652c137fc49e721c4ab9e9f398b0a6"
+ "12de8a8a8999af0dbc1cea0b6163da4261232814ed92eb2160cf4b26d0551b1b"
+ "dd919d494793786e1b86f79d6416612a282261363d6c9b7a0d92ad1758eaad51",
+ "008cf9b3f3e76090d101174ecd97d10bff6de4d46440003fc0d428f19b8558f3"
+ "1374a5fa283d03d4dd43f93a4d9f14ca0068dc2cf3e25437b05ab1d40621eebd"
+ "8416f5828ae7c6cfd297b4518f79942b914323284e2976a54d3cd911633a307e"
+ "daf1edb67498466b3e98916f9904f4a0ea9b87a98344f073833edf9b2b5394cf"
+ "d7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.15",
+ "8a6d53b0ada1854e2313691aab23063de131bc36c764",
+ "2685458aebfbd6074ebeb0fc0cc4921c273e8c0a881551502e4c299f334dd567"
+ "f51675b0ff30f2c48263200364996699f9b172affec0e79e5c523d1e779ec06d"
+ "ecd476a57430781e2dc81f25d60d3a73976579a2f01f07584cf8e5fb3ebd8d5a"
+ "932d57aa8a180aaa",
+ "013a3d32eec735ebda13f8be7602a0475cf3cf285b4286ad93d612c3ad917248"
+ "809d1c4c180b367015cc66c4d8e7867384168cf4cb719bd593355355cdd7d753"
+ "0c80c867745f9661c6c33bcb97f2cf75a4c27c3cbbdbbe7eaf4f8234f212e305"
+ "8256d4439a9f9781df48efdb023568f94ae4594654a0f9baf6ea30b7d8d9480a"
+ "d3"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.16",
+ "20f02044e63ac92eb9faf1a0ce35ba7209",
+ "2de1fcc117f821f1dea794b5eeb313f429e00b976b53419d3d03ecaa1b507688"
+ "77e8b7fbd6c363047e15c255793b3cbe0f5884f0a511254d31bfb23741023c1f"
+ "881fe016a12eef1b8af22b9368207e7b1639f7271debe3c8df5293eec3a032f1"
+ "ce559c0a04771bbf8898947ca4",
+ "017006e86f6c5858fe5ade0dcbfa9ccd11c02d4e7d0de6c158adf9eef10107e7"
+ "a4c36bd3d929ea6a476ecfa0b6ecd05149b51215954893a1ab2669c042da83e8"
+ "c818b00ae734de5f9e0b97ba1fe3e9c46ae9816b63b15c2dcc61cb3b8b2c23dd"
+ "b99fcd54e95560918b9a0fa3c4b6273d1b28a213e120b4f24286965ebee94ff8"
+ "96"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.17",
+ "d3883b",
+ "5ca3bbf992d7ae3594c605c39c3e979025ccb0a35c6ef0fa574a98be05ef7c32"
+ "8a19a2775ba06f2dd1e0ff6f0f1f6a3b20fbda2162d0924ff55b70ebfe2b16d4"
+ "ff6aef8d47ebe59638e5810ffdb58db05f4d9b4a3a423f967fe579f87378369d"
+ "5c5c07e5e3cb5dddf389621180270a21e01078c89afbab189e87f7",
+ "016f5505f74ff1104da1f8a52e50bfe29c998710c57de44098a9579e7a3313b6"
+ "29603102f08d2d911f917a9c9662608c97a1ea371734f67cbf7003d93c4c314c"
+ "3a0e77f3658fa4d0722562c4e13e85a7c8d0d9d4fbf7125884ba62ad2859b4d9"
+ "6136f7a2455469ceb60b63ba8474e6160c8317921a07b4b6436f376c5f98257b"
+ "17"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.18",
+ "06a2ae82a4853207c9f975",
+ "e2c33633d54754addd24c85c32d28ad870f1603d444460a03aacad7dcb809601"
+ "56bbb259cad346be90c0d4f3fb18ac6e9d5a9ae2a5ab98a1f84b8e70c71d0ccc"
+ "0a1a2aa39970d9c83b4b0c25aea43a5a5deadf9dc611b96d11334ef943090389"
+ "a8d3c66cf31877aa2cdff1119943278addff5e",
+ "0122410e765b2c9e90bdacbcff1bca8ae64be99cf013297485721768370c36f8"
+ "c0d9db8d79376254b9c69152720e05caefd4ce7eae08b3dfe3eaa91c4602eff3"
+ "8e4d81bcd3787a14d622dbb79ce8644c4fd1d2e41f7c1c97279611740fc50000"
+ "3178b37bbd81c5a5829b5c14bf459c4238b03beef73e498f865f6ca79a9ed60f"
+ "65"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.19",
+ "ad8b11a927de",
+ "5ecacff63a7938e998068a2f4ba6bcc1020e1f28c734e434e8863c48e6dffae2"
+ "8d1852727ffa7f2efa3de7013b812a02b2171a0f940b36d928dbdb960a6b2203"
+ "0c893789cbfdea9735e9ad1094a68461c2eb6f718be474d93a51930e3cda02c2"
+ "1f6363914e7eda5484037a76adc53312eb9dbbe45e23a14b",
+ "011fa43f5f4fbb983011814d4af545521df0b59e9b6ffd71333b8f9bbaaa0fcd"
+ "c1421ce4bf31bf9959fdc6b09b4f4251ddeee8210fc3a52fe7c71a876e6dde1d"
+ "fb59a4dab27d34fdce5bbfc6ed623e89967fb6fe73162015282c5f450138f250"
+ "4ab61c1f12d2649d815d6e8138438f8a8046c4e840cb718598e1e4a9fc25a945"
+ "64"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.20",
+ "bee29436c2a0de16f66042917007fb5130f3c1aa7df2c7c3bd99fbc1b413af4f"
+ "96a65b0e543ec6a50be83a9f",
+ "2391a68425dd8f0b83c9b3612467a779cf92f5ff9611c01493bcbef865e15bba"
+ "5e8fcf74beb9ea2573a9fce54164d06baa8b6df367cc4c6a114aa0346c454a2a"
+ "9e60535918d3660c66484ed953727a9c9a25",
+ "00989ddbd28d6095ada6881e28341ce7a0a1ca6bf7f31f772f910493afdba2d6"
+ "359d50b9833f83d0ab8713abe8e2102a27ab2a601fb77b9a25d6a0aff40cfdcf"
+ "9e12c42843ebad328324a719f29e8d79ea9e5d0d988695736034db5fea73dd36"
+ "00136f57a398fe352b278c60cb74ec98ad57a3e1d8c4478ca6179f4d0426f0f4"
+ "20"
+ }
+ }
+ },
+ {
+ "A 1026-bit RSA key pair",
+ "0252e95bb11ba1e1c7c95b6853f8de0bfe2b6403ac1bde819d918907747b0199"
+ "fadb8059c25aaf1ac565a74929d015a201f897a9bafe754168955b355bb009ce"
+ "16149312283c39cee220d0f0858b13812e86a7d4e5388b7eae5aca7c886a76d3"
+ "b1e6dd679268a82311e2820318cb8f0f7e85f0e6692eb0dedf30881caf7315d2"
+ "7d",
+ "010001",
+ "0104c85fd5d8d7932a2985c4cb7e9e13a2c4f1903c8b70f3df9712faee2017b9"
+ "2082c51653c0bdde9de66c3901b7c22be4f24cc56dffaa75d43b18a2e0c0dfe3"
+ "726b198caa0c9665263a93796a27d32984465f4b4affca0d92f4e51a37e41ab1"
+ "550766d5ca7e90d4de909bbd794e8bc52b7499a73e468ab44213cb3a3b5452d2"
+ "ff",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 8.1",
+ "f72637aec28d2b6ebf8f73d74875df01cd12248f0020608e61c73d1a01f972f7"
+ "4dee",
+ "cc2077a24001f3e3869694e4fe2772bf938f7627667b62d590f9ee4fcfffbbb4"
+ "7afd5fed6a180844a9121a32ed7cbc56cd2870a2d696b943d6fde9767c1b9648"
+ "616c32ed6c400d423dd4ab7216afada028402eb2a1c3ebcc245afc7f",
+ "0072575d3b11c5ffd6ae24f353ff749927b4ae5df463f70c5f3ef5496b0d145e"
+ "b2b8a53c28d53efe8bf9f27b2ef4ceea48310577c3d2b4b949a12e3df3f56776"
+ "828818452d81bd45af158c87bb57745b8a10fc1a92a0ea55c85139f842f73f1d"
+ "613b9a964af8ed720d0e0847f7ae5b305c05f12cbc4c9c1684acf902970d8209"
+ "49"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.2",
+ "2a8e3ee7eac6b22ec658ad44d666c8cd3f57ecea299b5cb7bf9a373dfa66972f"
+ "13e5f3a300e80e6dbf7415680d0d24901ad6b140b000aab85351f92f",
+ "fb19209d8a29afafbc053ac1f320ba60fc1fe104aa7839c84c9b3eaa18a8f943"
+ "bb219f59cc167a384bac7bd365824e103631b97bb9a6d118f4f0a951fa478a05"
+ "ea09",
+ "021b54646571a9a93f0b0a0382e540a8c3974cb31c87ebf17b3ba62a1c9521c5"
+ "0d7f90702e13ae0e22263834e7646035159445a0877d9a4f5b16177f7fe052bb"
+ "d023d081894f2d97cac2452076ca1191a171a48fa1cbbbc3f0f6f3bc1a447840"
+ "3a5a488febb3a41380163d942c977bb8ecd2866c5f5d919ed20c0db3ee31ef2f"
+ "51"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.3",
+ "d99b4f10d9f32e12ecfae2630b22ac026af964b9c715d207",
+ "e0af8b7eab36a6ee316d781367f09ea11e31fdc1ef2cf9c97c379eaacf6872a8"
+ "213cbe4ce2e29c778b35954010063f1776ab5b172da624b406a1c58e0b574a03"
+ "b1b1b2cd7d3a9e5035a9a973058f0497652d2f73b1dc8f487c09cfe71d8ff8f1"
+ "458c790ee0c5",
+ "01023bbe8557c2630a262246db7abc540343887038f64c641fd74ee874ae9670"
+ "fb2862d424703da20be4f48b239cd06043819d8f615144e2b1f00c8f88492e62"
+ "f6e07316f84905353b0b1880ed77da2b62d3a93bb70ff6a5007938b973b4cd5a"
+ "bfee0cf13f5d4ab2160102685cac8081834f9555806bb322d0dc5b8a2bf12845"
+ "62"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.4",
+ "caeca8e59b810cf75112f7ed047a46692ca0b7a86e1841d719",
+ "761f6864dcebc95a779bc0b16a95866c33dc8dcace61cd7bf90172d99aa457db"
+ "6d90887d84c4738d25cdf0e89569ae47d3073ec446eeedd52d57208bdb694557"
+ "034657a703784937ba694d42512138532b8ad1d986fe47318b2823de82ce276f"
+ "a6f0d3c8ef",
+ "011c0c03f7b6e1c1a8411740a6e5b473c28d6221176c9d4f68024ca57cda273a"
+ "f554740360990a1b74de34bcea103c2d0c36576002080b30bd28f076fb75fc9b"
+ "eb9e05d1989a311d12c1f28fd69392ad4be52ce389dec11eba946be05991da7f"
+ "d887a8d8768de736b905bf4bdbe88b85dfc3b25aea30fe90df1d22d8a8d61565"
+ "1c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.5",
+ "101212856e60cd272fb169cf62cf47f1bc50ef9f1fcfd214816c807f184a903f"
+ "16f0e809acf5e0",
+ "6043c8df6a7f4ab83e3197e8cd0225dc3866b5d8e6993c2cc5b876351ee33c71"
+ "c1a4ccdce45f3e9dc7b7e51b52eebe0e270e716207ca1403e13e723ce73f1045"
+ "5edbde85b0829052edafe56e9a22024d4068371d36c91f",
+ "0005c5cff89b933d8b6523b35906bb3a711a0f7f503f92147466598503912730"
+ "3b0011e7a42b41c33bd20db31b1560c9b5222089cdcf53b82c95f8c1adcd8b78"
+ "3fd4b48a454020668e0b62520e52585209db529f38708649d8e064890b228fb3"
+ "c1981b2aef3a5465ceb13021ebe08d02e33aa2dc3c39284ef7a858dcceb28ffa"
+ "28"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.6",
+ "6f03b5725230de7f9963698edb7975ece8",
+ "a30ee5aeab5931033efb70afbc2d3d11a63384cb8cb33a8fcae6146684e63f0c"
+ "c32e89a7e4ea43327bf035669543192886dec3fb4e2d0811efa9aec5109e31b6"
+ "a056e53e317f6a904b13a7356f5e7ae60b97215ed14817d28f74b1640b1f2e42"
+ "ef0d38ca35a354a0afefa803a4",
+ "0010bd2b356f9eabc22f7e68f72f6175f9ab9deda96423b74b11de82c607a138"
+ "863e17966c07f56cde9ed6bc422ed9feaa1f65367ccf91cd4c9158a749571a0e"
+ "9f9607cb48cd00a448de03649106ce0c2406aa50aa1217178cdb06801c70a89a"
+ "7a1a83068e68db95d24ca3db33a7e5e43a68152274bbbf4006d9fb69f0514cc9"
+ "e2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.7",
+ "879913045461bc0eac",
+ "c3c6a24ac340a4a3ff3b2c302b56eb8391bbd95fafb66478384438abd8b45d13"
+ "2b269909b187840a6844ad399fa8137205e02ccae7775ce6662120e154b7bfd3"
+ "0e8ea4d34a7db6a23488a5daea38085bed56780cff8727125f1ad5f9d5a0bc3b"
+ "e580bc4fa068267b27de383c55c7fc1764c86ac21a",
+ "01d21ece33f440c72a111d62ef486c77c6c890cd81a4eb0532ad2c0ec768dd1d"
+ "e5b2112fdf04e287a95b950b1fca5ae693cf0e8acc936f374714de7495908c29"
+ "15a707213ac3dbdabad81b4ba1cb50b95f9314531fec833f0821c04b5740d73b"
+ "8cf1f9e3d7abc9744926138fb015c0f056cc4ba2f3163734db443ebd68858c4f"
+ "a6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.8",
+ "5b",
+ "42b999fb163a6ffa67a9bc4e6ba12f81b1d56e54bf0866397fd314eb0cf97f13"
+ "b7804f768fba540621f05cd37264d8e8f58228fb6ab30ef54e30fa8cfcb5a87e"
+ "148fbabf85886ab1f0d525492f56c647f7229b2bf394a0ceabbd37c93e6da809"
+ "7e82727b3d53e8c2ad1f7713e34ed13ba59e0a914db06faae49cb37996",
+ "0090e5355947902bc3fb580a84770903a3955b3dd7191c928f7407ba747265dc"
+ "8cbc1d22f9377272b1a8c35c238f04a11937d1b4354f643795e986dee2e40a40"
+ "6741b021fdf05c4ba11562e83e9f28592e0a7914fe88b2c0fe7a5eeaf500f7e9"
+ "8a5ba954f75077bc8f659f21bb2203314be0d6d21e6320c05e6e2d557979226b"
+ "80"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.9",
+ "f63529901324a20fe5e9258ada2f9537b01f5839b44597e3293a1225ca3a2adf"
+ "684a72a793c69c56af2d3498d32a092e914b",
+ "7bfa8597a434cdadfe156314449513d76c105df1bfc48c4d076abfc05b5dda72"
+ "e0dd15f9fe82a9955bd56d3343e7c6f25a60741207e73a2d10bb95d1d729a227"
+ "93e6c455e916235a811694db",
+ "00adf4787467eac2ea61fe7ef82fd87c2da5899f30302bbc112786d2fb11c142"
+ "f3f1d8cf37160d2e4a43983ffbd393a41b599ee6a27e246425502d4690202fe5"
+ "f8ee1bc6c1d5d16be23b973aedf7f9111bd8b142844265fd93577a43c3acc6e2"
+ "af2089d9d2f3f31a5c247a7b68315bae25d5ae8140a51ffc0097107ec1620ab3"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.10",
+ "c6d14b047145f317781dd7382dc0a97257d554bb53539ee9a292e7da5cb6426f",
+ "01ff38d5ded6c43dc1dc5c27a7e4813f448f45c96edf4bd93e96fada9bc8ec5b"
+ "434f0619a38e04356e06278551407b7f37e42d9145620a81981850a49e285117"
+ "2d230b37824110f8ffdb847794639d2650cbed36260105f1f1296e52a7d4",
+ "005edc939789cfbfaaff282baf9701d61f9dbee6f2d206cfab775761f42cb274"
+ "ecba31c7cd2fe6031aba0b84d4627d3037e31ce7e15623ba7cb7690251c06327"
+ "a431371298df292195b6451162d2da92a7078e2d07c9f56a07068a9a3e173e4a"
+ "ae25a5d1c68e68208cb5253a0a53aa6e2ef6c295d1516569b862cb92ca823ccb"
+ "ab"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.11",
+ "c11653e810b53e6511f13323fe5226a170c21f6daa4429d968efda0529d7b6e1"
+ "0dced80c6b6301ded22f52911c0f7ff4535bd5e20ff53588cd3de6648ac02d",
+ "85fa7c6ce96d0a8a1fba7504717ccbe137138093956eff063fc2efd4a46d7dc7"
+ "4e90f1da9e43dba9129f14ec559a4d2d6c5a19cbf3a68c62d0983452a9ee0c",
+ "01b08d498313a7d74a055314eb4315ba028760dad41114d5942d63bf8d27be3f"
+ "49ccd94acf9d3aa22d09b99bf97409bcf33213c0996707868203a9ab27708d3f"
+ "ff69b89d02e36e0121a119b8d4d9bfd4fe8b168fd7c12a243f7a000b39bf8d56"
+ "481724208023bb607b30505dd1742f879f16c10ce490d34a680d27ac39607da2"
+ "4e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.12",
+ "095b77c94dc1b18788e400e6916a4b4cfd73ace0df9a3ac131bdf9ad0a12db76"
+ "6deb225359d901cd56ed88cda3d328565402",
+ "a34a6805557109c261dddf5f85d371ae6520f45adf469601b5c359fec744cb2a"
+ "ae80983c732db6c545df55e0208acfbbf1c2c5e79988f34ecd6e5bb4b525c1b8"
+ "bcb070d0d84248b1f8e7480e",
+ "00395636a82667dcf00d5dbdd8541206948d49368917ec0e00fd7ac5ca8bf44e"
+ "c58378386e594bc065a9a63cf2a355a608b6f0bacba56008bba4722a7c470545"
+ "a20f387853d460313b2e864e17b233e596354132af173b4d04492647790262d3"
+ "a43f8427378837466b0673a81527e6be104580326fec84ba371ea61091fa4033"
+ "a4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.13",
+ "38",
+ "547c91751905d5a284ac3fe432cbe03055b285065896110ea36d05a140083ce3"
+ "955fa82841eaf6db4a50d12c074f45a688b5576d6e616807540ac117585c5bc3"
+ "be5260727cdf123c774db40cff297088624853e4695136b931161517a7b9b5dd"
+ "cd9d32de3dfe3ee2ea688cf7bf882ccf7b9c48d5e19effa6504a42620b",
+ "0089e39dcfdf91693defe39d12bb25f80a768d441b481d6a7548695042480cd4"
+ "a0ba9783d5c5bd38896dce06acb177a4ac5968e655a7aaf50d694a649713b7a4"
+ "bdd14c819f83b2047de2195f7303665453a8a1115e5b48ac0e9a65eddb318951"
+ "7b046fcbc2d14381776a77fb468e11293c78c8374c8f4660351ac2b2c7845a25"
+ "fe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.14",
+ "80646b3c4df0eb791bda0ccc4d97d81ea8f6f74eb245e2c7c348fd7fb99016a9"
+ "d40a605ac742b27ad248",
+ "11b8e798d7a142d082e0598a8cb4f8c2aa875d5b65178c4ee67a5cb841d1cda3"
+ "0431d020df2880d7935815d59d91b9993e53ac341c972861eaa26697cf10ca8b"
+ "2794b45303be03489ebe074d8f239854c3a606fb",
+ "01f1e5a3dbd824752d2fba3c3242e9d996e627430d493e1b446a2dbcd86a4809"
+ "3e37a2e128b28c49d2d172bf5a977c369baa9ffb839bd2fdf00bd30ff5228b57"
+ "6b94e6d8ecf944247adad019f21d06fbe418d3a6d54cdf113e8d14f6ea06d8db"
+ "796493bcb1896fc4f3f30386c5c8bab7037c879afea47c8fb7a3c5b50b291866"
+ "b9"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.15",
+ "6b631c7c35ea75a1b0",
+ "3e4240c3e09ea78355358cda6129534730f48a9c9a1a5213284bfd0771216ad4"
+ "ca233d993ee6357f4b1b12a6baa17743134a857fd769a8bc78d61fb14fea0522"
+ "1dcf5aeb1affd40d8bc6945c301045b686c611fa437e30ca0fab5a4cdef5205b"
+ "af9926c607be9637b1507f5083e940ccfa2fb38619",
+ "0047cb9a9198d983b32224cf27fc7299bbd4ae0778a83fc59c4745fa99e917bb"
+ "74f8bd4ef13f140ca9b72e2aa174ceea264894e215f41c36d4e6f346f69b4f85"
+ "505c54cd46259c712e30c49294badb1c4716851f2b75e39612cd5466ba56e3f3"
+ "1599c2dce23d04c93a64402227df40b514c74d0aa36e1e8658e29277b305af35"
+ "15"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.16",
+ "400855da54a6d1fe5fb58a73d2a5e5583870fbd525d2f572adb5963006d0a133"
+ "9bea889d6d46a43762f513bb7cc03622bf859244d6",
+ "496e50bab5ef18f22c3f62b921148d36c101ad0a9a2038675808ce8b62f8a6a0"
+ "ba8d9105f92ed8a02b312f324f3fd39192bd4153784fb55905c3b669307bada8"
+ "27afa1b5cb3dc11dc4",
+ "00d3a85dec97d34488ee33c658ba188e64cb57837d2eddbcba8ee52f13f1e4fe"
+ "9bec2f92e7210987e1c3fe345d4019770b07749451b04d6730d53a91015b257e"
+ "810dae0a0c116a4f224514edbd39b2c65e152d3b9789dda4f0d45bf9832d279d"
+ "3431062b4de1b0677ef59c6c332768ecda3aa6bcd10f70bd06030a7665ed3f20"
+ "79"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.17",
+ "b87edb455a7e85539f928edae909fbf8f7a199c03a94a9a45acab25efaeecc26"
+ "2974cae0bb72243a99c6472079f19738",
+ "035e31594a5665605b84fec93adf925850851df7b394e9bbecbe4d72c92f2703"
+ "b6d60896e0054c59cafa5e0d286c812b23e537885e4c3438a772a1610ae9fae9"
+ "18e34d4992c7f263f3e8e2f980b8",
+ "021c8c959aec4729688768930d67e20299dd47902db079f239b8c288b0a70447"
+ "c7196b84912eaa5bc3aff6ba630c2eaa3fcbb24be463836531250bd4c4f2a1da"
+ "68c8bf4f40cf5c98b685ebeca4d03e76b334af0b1b34488b582e2935253572f7"
+ "fcfaa83544e7fd52ef458acccb19301a4ddd50516f16a5fb78f3959900dbcca1"
+ "f2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.18",
+ "302ac80e30c6553e9359df85b1e24a16c862a20ff4fd9d5f146be281dc3066ae"
+ "b8fa00b52a99",
+ "326c99358c4e5fa4d2c043f02f92705f791cf712bc01045b4cf349b42ae5acfa"
+ "c3783811bbf07f34bd6c851955cba4a8b2a7d139a78bc4d88e3a88e6c4cf494e"
+ "6a4a52354145e11883cb5c78b572f30a51ed23f2564b6960",
+ "02032987ccf75a638624178064dba4b72be539e07ecdf5300356cc43d729fe34"
+ "fb35bbbf5a32172ce39ea1fb47d38e497a03b601eeafdaaf99a34fd721184af2"
+ "e18e83d050a4108b15e5e3a27e0e636df8d94f981658ebdecdab0defcc0daf3a"
+ "c9a27b3f22a0541d35002752e9cc4fb2582fae2511a132ec5c228a8872bdbad6"
+ "87"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.19",
+ "00b38201746dcaf40348af57bad72570caf5a2855fec6c42ee22dcfe64c997ec"
+ "62a5c975624bbd1f8ec916",
+ "939105c004c01aa9f47446d3ccf530e9b2174c50aebca0a95cb7a4d83954efb8"
+ "039e591c1971d776cec761129206db7ad3dd871668255a5550ac4e948be05c16"
+ "2220dcefec13ff1fd8a5a7f78bf715b49d03ba",
+ "012ba87dc03a1a38bfedf121ed8722827bd97dd63fddfdd59050c53c5e7b49fb"
+ "7ae6038487820efd5fb9714381ce8daeb56d1350bfc67df091bea2acdffde929"
+ "2ab1291cc9751d9e39a826f054ad1f33a2b794da50ef80672917e0b3814045d2"
+ "3df45dba3fdc6f09ab0a018b060aa9fafc3a5d19d5eb64310bd602a9911dcb7f"
+ "24"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.20",
+ "ba2833660476d8731507669f50298c2c68d44c53e3d0a803786e",
+ "86ce8e92ad88b1462a171af28b4e99088c0498a29b4ca5e66f64f86adec7f964"
+ "e8eb8257c5c01cda165e0f7511db147c10bc07515f04f05f52d2bc89228357c6"
+ "61b43f43d542dbe77834091c7ce70b182e19bc936c30684a831e2c3b8a4a7446"
+ "3f0c9f1b",
+ "0112ac2898a25c1328791fc96a82b72918b51a668c540bcffc8e0b3aafe205ee"
+ "871f5eb76ad116d304cc0442bdb1af5b9a6345827e678e40e33fc858ef6c456b"
+ "e43652bb2ebc3964b4bf4a93a8eeef8404aef1a044415a156f7cfd7995ac25e7"
+ "b03026698e14489efcc1ae929658bb663de0ac44a7a55caa0b0b2034c2aaec13"
+ "4e"
+ }
+ }
+ },
+ {
+ "A 1027-bit RSA key pair",
+ "068ef0b274157d7b5ec72903865956183e0e3462ecd22114cad4c7baac94c7c2"
+ "c5e6cbdfa2abfeaf8d23182e9c08815d100d8e8f621d3cd4afbb9985966fd6a4"
+ "182b599088a35d77fe0178acf7531c70d896ff788edc82060540efefd9f3c24d"
+ "5be69af7f2f44485b19118a468814fc513e3a1ced67791f9036eee56fa9e2060"
+ "2b",
+ "010001",
+ "71940be6797bb3285ebdc20cc9275f5d775588e9af6f687a2e39d2c191111076"
+ "95ddede391d2196b29581df3154a3712fa6fcdf85bb4fd48641f071ffdb1de08"
+ "a1d5921ca10e68dc041313c9bbcb8081bdb5d4604227cbe57807416574d1a38d"
+ "a0b2344bb215b4182b106b2b534a8d3206f2d7d303b8dd5bce292abf75cd7649",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 9.1",
+ "96ad3ba4d29bdd3525bbc5d02e88c0133ffdea409474db34df733ca59c3a232f"
+ "6a64c2143ca131a7f18d005bb3aa6ca1eabeaa136bec37db111d4d8f61",
+ "10e9f5093cec872edb16162b6bbd5212f6101a71d51dc1420cadd1d550faf9af"
+ "40f573d3e3ab6891d8a882ef0656bc30062a05b1cc277a11c9ba2efd5103c56e"
+ "23",
+ "04dec01bbf8e0c2296d9f5bc2d2ba895343ec30ec54413576d8084b93143cfa2"
+ "d2033bf4c2c2e03f5b0259edf14a8f3e11698577652a2ab9f51ab0187cc75175"
+ "c86dfc9a45b1e4eb8b5447a94ab9b5177a0404ba49e57f83c93f7fe2de241845"
+ "f581f64212437e0c04ff34ea1dee6dd28f6ff3367235441374f0f2ef71a9cdae"
+ "9e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.2",
+ "7f92abb6e52ed5d420849ed6ccab36c3d0849255431e193d67bd944b6c0fcefb"
+ "7729cf5a31",
+ "cea968be78ab5faac227dc3c6fc9ced49f851ed58b08d5ca375428489afbef3b"
+ "f5ed83746d959a0a56e9ac66ff2e7c8b8c3ada97fa15dd7f991341747070ccad"
+ "6542bd7f4b33f55604458b9103ae13dc89b4e62ccbf84ff73b",
+ "025a1e65eb37f4b328cc31b01724f83c26ed8d18a65165213ba0eff7ae767ee6"
+ "0b9927761a0694b5c3bb64b7e03996a3568d6fd1ac6b7a8b71975bb0716d945c"
+ "02d47368966fffb1d449fc6ed73e2d19831b86d1876751293669e77d6e12a0f0"
+ "c962dfcd400fb83ce8260716317ad5fde21849aa6f68e70ce0b5b31142898ad1"
+ "a2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.3",
+ "f5b535b63d535e2137732c301337c953ea2edd58a78c2025832dca9d6bcdad87"
+ "c997c906836b2bf95c83f03f7afa2901346d674aa69a1b47f6b916fd4b",
+ "c89efdb234e01a2f07762957e8c0a4f91abae6d4f360e89a7c486c5549f3d0ad"
+ "75777f0ccd97a0975e9844d986870276c9825f5d1eef3d1b487abcd19b512d08"
+ "be",
+ "039a1ce8c0916251a01e5fb6615d2e11982f4fae7d46df21daa298f2c74611b5"
+ "5816cc27fa37279aaf5902ecb6c839fa900cf3af86ff40a447dc402235f90667"
+ "9123f3cd381904f33eee353ac90d5f7f203a6ea891351adb11601bd9d6b0a024"
+ "333a2455be1ca62ed82cf37cf8de4e2392dd54e775033c56990bae5c4391b665"
+ "3a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.4",
+ "a7cf29820347a52ab9cc4204bb6ac1bd7fd90a758a156dfa9ce71927e74ee215"
+ "98708cf69cfd7985742f5027ffa710",
+ "109f0d6ca0e13f504c07d84a5bbe43ed6a94acbafab048893605d341c5d28d85"
+ "44c3fd284350f2c22d1f367dfb9b6a6751d06aaeb17c3c0a1011ae38fba4e46d"
+ "4e44c482879eba0644374871b5c53b",
+ "0448c39cc457d6ccc30b0d76ff5a132e00c75d533646b8440b13ce730e1b7ad8"
+ "3bb2ba4a082bb5a33cf41466e067fcf16c6a29f1879f77e9b0dbf3ec080575be"
+ "bac0c5676baee002d573d1bcc8a70fed2ab67943efc9bc13139e5d8dde2cb30e"
+ "1b934f50cf6c4573923f7398de6670cc26341f3e35a419361e59f60898f2692b"
+ "94"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.5",
+ "b803c7ef5f9a9bd58401",
+ "8e7758ed4d1ba4dce088926c10b2f3d4c1e2671ae72e659f721ff7be6fc035e3"
+ "85d512d07a38dcca1eb831fef906100444ee995cb07bc26a5dc92b272a74a92d"
+ "2149732522d539434fa4d03b07cf9699958c19891d1d5906aa36d0a8d06c6fc8"
+ "7a4551bf1858bdfed5f886cc8d31ee4c164e981d",
+ "04b62d4d4b9c1c3e051309795c69248aed389de24a6c79538a2d51d5d03719a8"
+ "a528750d5d254a1b914096db96d83d2d9aaa2a165bb1346e44c3572756c38d52"
+ "f8d307c04e1efee5847822317ab469345b86c7b85b541541c992abea98d108a7"
+ "dfc7091c30c6685af0e33d0466ace4ccccb34e5b266d3d6b947bc7c0ae34d5e2"
+ "64"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.6",
+ "617ea9e4a56c4ec1d3d7fd7f3281ae7fa932b2a0a6cf55eb6048145681b3588e"
+ "df701269f89fe64aa14ad8df0d46796131",
+ "64d7ebd04850eb6f7ae1af48120a80130f32edb50369640b222b8d63eff65712"
+ "70dcab3176d0247228dcd1c3f3cfd51331b756a8652a14ddaab99396b9199a73"
+ "8750d69efcd377f184ae19b5a9",
+ "02dfe72958595881d807566d3e3607c022e461fe1dbed3cc6d63dedcb7190f06"
+ "c7d24b4f03264cafbb7482ec28b9ba489d03115af58fde475eda58bf0155cdf1"
+ "af16df206bcd125704c3e315ad3d9544b9e2c2fea810ce484556d29e07adbf0f"
+ "f461ccbcf662bd74959a437d4c8011ceada5502af7676d9a1521e3189dafde00"
+ "dd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.7",
+ "c91f2c98c75b2fd4cd8d5c7ff2e769b12f28f313fbacb51b5e5014dfce9d635e"
+ "7c6b2d88af5eac30d162b8ddc22ed8bc7bee506bfbf31e51ba48f426",
+ "6c445961f86fa298d7647c2224d95bc127dafcbd5b9021ec7e9ebde96f5d7a76"
+ "f4eed0ac922a6e93eb3b4c3c43f8a57e18294e1a5173b0f7e2dd2c4e577a4bec"
+ "e714",
+ "03a885aaf7b7d94fdae34b41c3741766a409c1ee0232b1c53e5f6c5aa54ac1ef"
+ "0e5bf99b9f7df3e9b00ced9476ee1adb8fc5716891f54d45ceda70b9db3b8fad"
+ "25e77795af1481ec492184c49e9df823ee6466410f65013ce3c57916635da830"
+ "677f932bdabab5c0a208d7f4367a7eaba75b045d25acfdb415fee05219a58423"
+ "7a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.8",
+ "7b1c3151a38d32ec7b82c48c000aa481de418e803b673d2e9a0fc3d5e974adcd"
+ "cebd3c2a8f41142118a55e87d04bbad5b36425",
+ "b0f5be9b3f237cc5afca5a99fccb77b6efd868947f98554fbeceacfa884c1515"
+ "39d7cf423e726031bfeb8dd2d4f301da6bdfcad6e5816582addce10d85d5ee1d"
+ "0446f373b95ee160bcf035",
+ "066c3009dc6cbac7b8bd5141c55cf86a3d7969d585452e3a66540f9402dba215"
+ "e3fb3a277f0d3396c8c008af19913e3d91e40f867606b5bf54304c0471dadd64"
+ "04b67a4857bf52246c0d601823dd0380c6609dacb92db602e55764ae4650df1a"
+ "dbb4b95fa5af4bcd1121f13c0a7323ada8c60de3d081729d197f9cf8e27cde80"
+ "b1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.9",
+ "b293c6f6d05d1f38b561ea3d0d0ad6a2af8309bb9adefa778fd6bb9fff3e010c"
+ "404c533997ccfed7e1917a669261cfcca4e37029991d2de9b299",
+ "87bd2f6bb48245591d65f023a65b63bbba8419792c0141092b1db1be53e8c9b4"
+ "df95f0ad55b96e5e57615d214b4977870a272f723166c62045765e6b4a73a7c9"
+ "ebe11d24",
+ "03104ec6c4ab9dacae427fb10699bcae003da56f6d07509587145b733edb5323"
+ "9a6f422286839cac064adfeee5dc89780cddadcc807219d6a97b85c13f27937d"
+ "70327f82cc36a5da8e456377fca23aee514e044abf1f66c3e7bdebc2cff628bd"
+ "524a0966e2638d2833bfa343ebc741f76b5b70a1136f4abc602864a2ad43a791"
+ "bd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.10",
+ "0838f4a592",
+ "89c5898c6c3dc6cbdb1acb2805df5398f0b3358a18e5e63c14d20c98d21d9fd8"
+ "b2ecc9a0e83daf0c069268bbe86feea51c93791b68e5d93b745feaf6adc42b83"
+ "c309c9cd3dfe1c06153ab8808556189890be053a925488d029fe5040e3e7d5d5"
+ "31b32eb9d2f4eea22111b38a6553f00edd2365575bb949f363",
+ "014f2797dde8d46018ff23d89be2e3ae046eed3197c879c60e26f3d2400866eb"
+ "50d7b45f6b01ae9ca006847efbe9abcc9bc3e35690072b68db9ecd926d945f78"
+ "7b27c3753bf96b2d49983084142c42a1261aff7b17ff4b20de9bffa58624ab37"
+ "1d4ce2f96469a8e1038d5720b81cf042dc78bfda9a3ccb6160812ddea158bd2f"
+ "5c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.11",
+ "12380c5e80bb95bbc8857357fefd17bf9e509627d28cdfcd12bb131661b342df"
+ "a6ca672e13a8851fce19b1a8caf0e33cd6ef538a05fa54269a1378e7",
+ "880331ebe91ab6ce1684d9af5d977eb426ca7156e0b6f4336c6e0933d6fa4878"
+ "2c0ac969f3dde61d8fd74c47fe9e3061710d245b1d3811042860c1f48d2b8ffd"
+ "809e",
+ "046c545ff496c21f690127245418cc5fb18f09102e7aca87e26e2082fc16f62f"
+ "e9f42a722271a79eaee9625a7e632c1936404cec6211d823863ba02c6b0a8319"
+ "58b4ed8fc625a2e52a054f8f181f130f8bc4b1dfbd44b70a35b35e9c7f4ac55e"
+ "e5e2cb068b758639b2cd643dbfa82e2d9720e489f5c821d8ebdc1368a9d3468a"
+ "37"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.12",
+ "eee1e45d18b147c269a60a9c642018ed6cd1157cd0ce2b2968dfa4b497fc40b2"
+ "24bd861e2535122b",
+ "5c513e514452b14aee33b61760b858c5357c7d7f20e4a37c7eefe419cae3fd16"
+ "f9d83e5ecde19ee63285ddce6680ee9464fe83756e9031d6379e6a6b384ce277"
+ "bc642ced83b29cf74b72cefff5307104e183de2ce6a1",
+ "03a86483cbb72c15f5a6932b012f40c4b173333b2686f4984ba66e24c7cf4441"
+ "23ba2ea666a1755d09357beea4379ce3cdb0a77a6ee3b7ca60db682417f7163d"
+ "7d3ac7352811bb94c5b771f3d3fda773e5cebc8bc6601155b3f4e4b4ca85d9ba"
+ "b8ec258cecff4433c92e8f863d96fcc79429498a9e1790330bc487c010d79924"
+ "5d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.13",
+ "5509a5c1ac5489dcb765f37cebbe7d81cf0276b1f2cff95d274bbd04",
+ "76e81a51371fb50741141dcb31d51d1c461fcc026aea852015d468740b452340"
+ "5f95ba879b0869bf031a60654fc4e568c1957ce4e42a350a95bf8cb2a8b5fde6"
+ "dcfd2505c037a29ede689c53d83219e73e640817bf8afc9ab004ecaec843e4fe"
+ "4e38",
+ "0255de280b71afefafa20f241e081b7ec6c162ddda1884fa9f825c4ce7636efb"
+ "c11b84a6ebea35892571ac9e6b1ad8473fa573c883c9f215a19580c3ea302f88"
+ "f44f48e4d95c3440d4931f1766a1fe7e790e5d38e85d1f63850a3c707ad8977b"
+ "88c38cb9ed98345cd350c3dd45309fc81cb46276e4ad647fa84c14125efd67d8"
+ "ba"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.14",
+ "025381a55c8e487d7f4ff7c36cfb375007d19f9371136e2b3df4425eeeee5d79"
+ "c35261fbb4ea68bd91e8edaba2329e29315306c7d71833155b88",
+ "aa310f62da90da4a2028b381399cb7e0ed3bb510575c9bd0f638215baf7808e3"
+ "245eaf38b76e2652290b7cc620907cda0cb7af073c122ff83daae1986b43ec1a"
+ "1482dba6",
+ "049bfac6410b7780397a49fb8893b24d903b3600f33c782c1475b5d24b4f4e88"
+ "fd1124ef0645f3d391ed31006dd1b7c264128d0db9aa0d65a09ffbe29a94cca3"
+ "58da64bd1b72ff55888808105be091ae23ea3f347505179eccb2410d89decb62"
+ "330f36c744262eb2b078b4254bcdcece211cf0574a2468e2a1e018bc31f50222"
+ "35"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.15",
+ "073c4367bafd4810d7704460c783d350f7ccd099472f79f7fdf23ef0cfaaccab"
+ "9571df53fde4",
+ "f95a3996def1cafc1a4a0b34146b73de6b5a92cb812e20b20c122a251e6b22e0"
+ "469c98db128d43cefcdd80c7ff36998016a892a8b634b36b9b0ce87ea80b5dd9"
+ "fd7a082914e73b83a3841de51b71b1a6b7ef7de4e4b88edc",
+ "02dee48b0f9953ee12c718b303b0c89d6150ebbe83ad624e117e3f2704a0b17a"
+ "2ebee8385256f0e64280fb06c3b146c099af23a9f24793393781a555ac4ea2d8"
+ "8d785d8cdb6e7a2f8952d2503ccf901f1239f6f7b1acd44121c365fdae370746"
+ "de4526e7c6560f87546ed577cf9798bef47e492065509c49212d370dea0522d7"
+ "94"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.16",
+ "bab20b9a6a532e6f8af078b3a185e0aa86e61681bd1bd775044a2c958d61edc2"
+ "51607cd9f31148f5a911",
+ "376cf018143b0ce67021684cbb36e4afe2ff9de18bc7f02bed863bf1bc346631"
+ "9e720feef19d38e26bca7e99d4096a9eed8de5bf203fc7dd9c8485dfa5b69075"
+ "ef0cc037fcdfb55a0c928cdac0cba0497eb60e3f",
+ "048dd7509918430edabc01468db7e287a7381e428b5fc93ce8defd7f49d5e934"
+ "153043d137aca9f7b97577b70dc01680f2dba91e932b53acf2a7f3348f5654b2"
+ "cfcfe75d48f0fa4500d1ba5d29247ff142d6b980e11b9dba6883f73bb855a24c"
+ "c4eb9068236daa0f2f93458d72726c2d8e31259acd3a7fdeb6feb5c6d2ed178d"
+ "db"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.17",
+ "19b1f4cd3dbdf05b3d5f1680856c5a744f5162b520bfcdfc9887dd92be9d8cb6"
+ "25c725ad75f4f2caa5ef51faca71b5e66f84f2fc6f678ace809d76b842eafe",
+ "78a71882853d85af165cc0b22ffdc8873df49e2d6cc0ad0b0a995b4a259c867d"
+ "c1aab6428a5b8e9f3be87d87f9e6eac550f4df11368e7f6cfd7d0e476a459b",
+ "062a78db5ca69a304810789493db8cd644fb294e17fd364532b8ec17ce3fda70"
+ "476465624a60a6ecdbd5d97240c8d89deac11dc30d7b851441408edd642881a0"
+ "112b62f8cfde34d9c11385c29189bf3893a6abace04a10aa680cd3a6ee002c30"
+ "7035d2399a2a60b5a7f1caaf0584d10fd06d6efd56114c05e43d42d834f03e3f"
+ "e9"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.18",
+ "8cb73bc47850c17febd34ff4b7323b5053030b96221403cdef45dec65ba60ea3",
+ "ed6478614881ebe3fdd6d9ee05f2765fc8a3eaa58031235af96f86e7f2c813ec"
+ "0480661d1c2b4def742b2e41419df2883ed58679cb9adae4dec4cf77f8bc2941"
+ "d033f8877a906ddc88d6dd3c5396adaac03eb2a7094c0fdf0a44a6b923ab",
+ "03978d4effc6d62f232bf46b4290c5011d73280ab0e80ab9d6050a852a6679e0"
+ "17e170d9e7156c8dcbd46cdeda70ff9a55168b9fdc0365b8aabb909aad40d595"
+ "c90b9f00c1e00ad6f01d544307b254eaf4255de62bfd8a5f7e79dcfc7445cec6"
+ "3df0c2bd0ad96cb70242b30b3242078816b58b0a9ffa16f1d86315f8a1cb2f8f"
+ "6b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.19",
+ "8ea55643dfe7cbe075c17b93c6ba6b5a74ea8d1abab9c728ae5b00866c62880d"
+ "3c00052037cf802d2cf2a8e1bea58c7ba604774d4f80bc04",
+ "af9d9d312e22570fbc4bc85a445ed8d899660ed24cf0301533946e5cb9471a27"
+ "c510cd175591d23d363dc4e3e69c7bb465517a4cd1d1ce413e1016aeafd55d2c"
+ "b9debcfe4b1d",
+ "0587111916bb42f84757691efede7eb7796a5cf887c37ca9f61b451fb1bade38"
+ "9cfc5fdc219841bb41da827452725fc82b4d1ade569ceec80579edb1b4b15b46"
+ "ad7d45b245988023ea0dfcb3744a692eb9aca85f211010afb1e9894f854a5e34"
+ "fe89aa051968a3b2362c150c6d970edd82b9e2d13b38c3c2956d9150088641d5"
+ "30"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.20",
+ "525cffa3",
+ "0c99304cc6263d1ee2446e248c27112c8f96da82515f06f812398a88811f39fb"
+ "056205c44d6bd4855a62c21c601b88f80234e23241f716322d8054a84a1fc3c8"
+ "46defb61767cc4d816fa7b3747f8729bf3372ac2c229d052f45bc42fc38050dc"
+ "a3f2632e6007b60853b7e0ccb3daa494e55335fd04f13d5fada7",
+ "063e4508e5312b5c38694de82a71eda312e9aed05bc143d338f7f22812d93c28"
+ "65126a9b3a42c3ca19edb34601c0b28a75663b18f239f5adcaa4e9fa9f611804"
+ "726fa12962bba3230cb886d66782a47ea9502a8371e7573bb6b0266c33646bdf"
+ "53f8de368ef205b11a85baf21daf3ce7a2599f008b9945eeb186ec192c540ac2"
+ "3c"
+ }
+ }
+ },
+ {
+ "A 1028-bit RSA key pair",
+ "0b52cb6b5c3b9ec5aaad894e5177f7f45b8d33dcbbe96a5b26f30072bf1573a6"
+ "c41fb0a97ae1e52ed8c25c62b98bf59de7b68ab98c2d8b93c4942723cc4baed2"
+ "b393c07b2b11909c732df7c1dcbb433a839d46f428e9ddc8d35fd33eed298180"
+ "f75f2d5c9fe8534f0347f8685c28c437ea5b811a286e810c697a88cd7e45364c"
+ "1f",
+ "010001",
+ "45cc1417b26fce3e9fd31089b1a3ccc46f8ff21eac2e1d67c0ae20152dc50d1c"
+ "e7ce6f26404e2e6495b977bf13f9a405b24580d6393a85225496e4abc49ebeff"
+ "de70cf26766866f276e15b492af8033f1bac7f66b71a3baf571ffccc038a4886"
+ "9394cca3fa004985b434a51517877eae97a384947f01a72cf4b20193dd276481",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 10.1",
+ "5922d09fdf6522802fbcf7a28ec3d9fadf607203a31bd0da963aa0315f35e1a0"
+ "a374d487dd0862a6f6bec932b7db",
+ "61395a0fa12e1ec2ffea2a8890653e8f378dc46ce2b8aa4a0a1c567b30e59c3a"
+ "33a668989714fc3d45ac886327e36c345da858f903d1e606740314cb808d86ab"
+ "c31b49b35b3f20e37929dcc859d59141",
+ "0439e7dd09af61c0ee25f3e5c2951da49d3fd708b297a3055ff9983a9ea538b8"
+ "3d59dabdb85daf82ae7bb1978e7da2a6dc0587ef9c732ee688373fbcbfa2dacf"
+ "f9b3c12f704ee14f8324bd4cc6bf9dcd3f0533c3b11a0d38dbcc7bb7ef9a7229"
+ "6b6c13dc42d7ec17f851a51612c7494c6368a7fbec93d22e8f9b72bdc0449fb4"
+ "30"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.2",
+ "5fbad43a910a290e5055d514e71c8eabf1f93320ebd0da8f90d146a8f3dd5c1a"
+ "2c720b93211e482934149f1d21b978f48a0bb8e4cca3f5d45d3f3e3ba8e1",
+ "21045261804bf754bcb8bf3498b1ad10aff33da1f225eda5646590458b20709f"
+ "c8d0b498907a8364ce1c436b6b1e73181c86c677af45c17f9e4af3759cad2487",
+ "029f64ac330134007f77f72c37f4177c24d660be4ebac1868ad11f9e3051b8cd"
+ "77c4691199ac4919db2ed363740d2dde3291f10d9268e7c7de37ea421ebb1fad"
+ "6529f292192a9680ba963eda9374037ab9529a486f35cbd29e09ea98a5045d9e"
+ "16bb8770155d70afd217a146862749ec1ad159cf6e6a63df142b8246d844a737"
+ "2d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.3",
+ "22bbc616ec6ef3573156b41761ac3bdb57bd9b7036edc9a6978875e2a614cde3"
+ "efedafd3889a5dbdcc5fad9e9becf8a8bb8033ff91dfed604bf8c6e9bbc7",
+ "3b47d2ca9554b34f9429578d4fdec5d96eca89b68172d1db1356b3da7a69f158"
+ "4d4c846b18432f02f259cadc24e154ff15f806f25343500e13b5be43c7b5ae7e",
+ "00c4e6c10c255e4beb2b31c1656846b97ca23a3ba32ab19c648520113d7034df"
+ "a46b0cd23d7399a93cb02f1eba948318e3791c306a2eb9c0c56d8f7e83250f83"
+ "ad492fadf7831769f02e1824347445d0419b98b8e795456532300b92d6e455b5"
+ "a4eba853d6f7459290ab0231994853a8c07e54f59c624537080289f93143ebc6"
+ "61"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.4",
+ "316cc4450a53703c058c901f507d7ad0cb6396c551d4f06182abd3a43aacbabb"
+ "3159c026b3e7dbc160f41953317e0f20808c",
+ "c1ecb1164b3e6623f0d9b9c5ebf99e788b7bd94eb74374f61ed314304caf46f8"
+ "4a3fea1ba0e47fc8be4197d1d2cd4141cb9a615d89c4bd9110ca6ac9a560f076"
+ "ebe69b74a10fe9ccdb76dabd",
+ "0616b8bc772c5564d451b128d9b1364c9e33b6e558ec67f2105c9800117d0b73"
+ "ccab9db51d967a9d66322cbc5a01746e4731dd7d04e636e64d35f2c86ca39d26"
+ "1492176b8dabdb134be94be51b6c023a0d55fcc1f04c94c86d477db403b04fb6"
+ "c028505724793840cbf468aaaa91bc54e0d6477ce648cedd1276f2ad2d4d423b"
+ "6c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.5",
+ "d54ea37cbfbdb8183b3b547f6df2d5d63c415b1c44ed6393c697b4d93a97fa0d"
+ "2f4d300a68e98f7fd0460701d1579d9683612b",
+ "d1ceb0c072d6888fa91a757cbf50d66976bbb72e619462614d5dec0fc0bbcabb"
+ "070789c2b0895091b8fa9c7e75ab20b89758f97fd047bc44a568a2612d0d501d"
+ "15d4fb82e77528796949f3",
+ "03c138c79199b0b1700bab2e63e1d2a0031ef602f7ddf1ed3a161a5e70f16451"
+ "daa101f74cdd6547a7c652c7329bb1737fb14c1cc0c0c3e7612ae20ee021ab21"
+ "d70bf9517b4d33a9d809612e7f426885b79b312e266e42b202b571c66f9a107b"
+ "8fd7c56c050a8e1eb18956db06a0209dd16ef2d90524db87917f34006be6b15a"
+ "13"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.6",
+ "f64b2511cbe3cc6581",
+ "daca1963cb3de5245779e96477ffda277f4b923fa9a8d9385d523169233f5879"
+ "a3c9fc7a38e1b208c32de40bbe1da077471e61c8b9b7093c41b0a65c996432d6"
+ "45521184a66afcb96f07a8f8eebb6ef817e027ee2f379545239ef6f9c1d0d860"
+ "e82144ec71597f246a83ccf660ea4c70ee1df014ef",
+ "0508ed845c96238e3a07e8ec027f7b098a83f03eac1fec426f4d6005b60d0735"
+ "db0537082f23b750f6db5488214181e114cf1f7207419ca293750aa766fa7a5b"
+ "9be00e37292c23231c6ab3be2dedeed321b0f9cd832c5edb41677c1ab983e7e3"
+ "ebc8b51993821d76df2ac2298d8b80ab17c38b3853f18fe309cc7bf7c4a2c27d"
+ "63"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.7",
+ "852649015206e2a4097876f8abb9b846",
+ "034fe34e20e606a8dc7cbcd0d6ab3e0797c5dc4ed7868edc7959893e58137d26"
+ "32b2c5a29a8135c24af699b59d68103a1f423393e3886e3fa854e39721501941"
+ "3af0b0d4fb1bd69bd4934d4d1e2e9f3b9e7c46d4984fe9e7a37ab2f1c78b0b8d"
+ "9cd8fabb3d18d4c506e2fd3f85ae",
+ "016fbf2a7d368071cc7be59449354b9de05a85e1bb97b2514b52b8d1f3e26994"
+ "e12cfeda59e058a2f3c8792350c068417f99441bfe7417e0b5316e163ba8d1f9"
+ "e32c59a4449882f47ad9b24f6876d478d3f5b7d2753573e3f697bf64c7b3ac22"
+ "28ce69e75e8e14ab93f21978059a143b877c6dd421b6e20b0735a53605552ab0"
+ "a8"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.8",
+ "f4fb50beabecba77e71dd8d16c975a86f619ea7dbf41969a24bae2b842c269e0"
+ "b4d6a29e829dbe2e49799c9ed971a30335e6ed9bf39d124be0f8",
+ "9dbd92daeeb82bde816c593f706b1592568522bca0797f9e811dd9dc0e896e98"
+ "4a4a9ace77def5a9250db79581af33fb6de2427d1af6a5f6929fa8b67bad023f"
+ "04b3ffd2",
+ "0292edfbac38e2224545af8286232763bcb18bae13709799e3507758d0141ac2"
+ "976f30b85467d783abf6fc71df619e1a59e6234f27b632feaabfd9853377354d"
+ "933ef4ec5994c0d50d952e0ece0be1be4d38f11f66e7c3da88c83b4bedcc062e"
+ "09f9af95eacac0099c525f241ea7d565e1b768cb9708f3bcd59177b6766a3734"
+ "88"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.9",
+ "76913e848fb7b9faca91baf4f4420106a94d6ce25d1497fc4e7f859654795d7f"
+ "24399f3a1208af028e61678a6d19a18640b4d50f75558600",
+ "9ceeaa2609ba90eb61e4f749c4cda01aea236881762dfc150d97c11eb6440cb0"
+ "57e53c3fd9b39e560a46e9d3fa3af3fee5ee2d02fa4249af9998f53ed04db010"
+ "e96d8a01ff6b",
+ "01963089c343ed88b56d6acfefbc655a37ccfd96203f218764695ad310c0b266"
+ "65ee745eb010fc83be8c20645c4347dcd944655d9fe6cd9877dc70e5c188cfc9"
+ "a66e71da745cd3e1a7b7f5a1b25b4fc1470adfbf7d8e45fb107c5aeb50ea8b56"
+ "e04ca55b9b652ad834d9c96577b642ef33f164d4931fb89e0c8c6bf91708fda6"
+ "db"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.10",
+ "c339f857e4d0231fa37c06f0956b4d53a6c58e0610d8da4317dc8411d3a0f898"
+ "49b94e8d7ccdb0c7d5330c25",
+ "2490816ac96976ca725eb498e2ff040afe3d6417d32e4ffbd9fc9e3fa68ce849"
+ "c881be379f17504b97e1e0d22d32ff8dfe76bb4549f713b5b8d870ed3659ddd3"
+ "984b6fb39f6ebddc1177ad698d90443968ab",
+ "00b5fb7b1e9d71df8b16c63a1a496e6f7bf772864cb411552b50e0b7f15e4597"
+ "16f5646243687633a9106c346c8c6b7cfac750b4566b1b88aac0acb916c07a78"
+ "0be06df7975ccd8b726078687a8ea5d3903e04ab1d23dc9b1ed36000c9bbc3dc"
+ "8161e9483a18abb8641ebb1fdd0266c084bf0bd09cc94eebb9283c5a5f74e360"
+ "13"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.11",
+ "475865a57bdb91addf777cc9d0a17a71a9f9710a931bd0c3149b2391a353",
+ "562f7970946ac4cf05edfb2634167e14d6658d24cdaef75b407c9004818efa75"
+ "d1645e8152d1fc80d699dfe99a27a7df997a8a66475aafce419598e2a19199fc"
+ "2053e3acdd07fec8ba61f2b03efc7deed815cda8952e21e3c0b9a9352ab36f5e",
+ "03e268d7d180d03c7cbc8507ed1f830ed37a7995712d7d915732243de685d5bd"
+ "99a14a8e86a67cdd60dcd90c339210835a46ceac1936ab3aa9c381882d7694a8"
+ "383d6898e27344bd156fe9282c71322625d68d3070eff01ac8d595f6486d79b7"
+ "88e36912fd3ccf284edd5fcee2409dca7d4f29cc182a78478bd3ea2362112510"
+ "a5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.12",
+ "9e1e53f986599da898d56dc1c7556fefcaa3395d8450d52b3ba7",
+ "0b1763cc340e6e3978626a06d6efc40ded73db535a822ec04c9924d9ec40d385"
+ "2015d7e1029c1393adcf0150308acb273c36356828a477fcf9a29acab9093570"
+ "425026dac14da6cd304cdaa54c9a4c5a994ed68a5ceac7e081dec4646e237e47"
+ "1e525ef8",
+ "06d519a730ea5f549fe19e301ba5152d103a3ead3f89ab3516ff7b344c4f72a1"
+ "c26aa90d5a01a2a65193d3cf6341e59a31fd2d7dfe435c0984d1bbe81132010f"
+ "4358eebfe83faf241e7f35af98b7c7ab91e4f0e8a32a2f57f07f49d5c21f1e13"
+ "80ba0e179a38d3a2ca464fc14d2b74a03a8884aa857b66014702b1bc4e7cc5e1"
+ "eb"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.13",
+ "1ae31e0cbe4497ba43c5d15f535fe018841c73145767a6a4c8",
+ "8ff0faa7a2b4ff553ccbb20ff310ac5e0ea92818562ec9a06064f5de7986b4f6"
+ "c9aea2b9f0114238e5a499a8ae20eae4021fcdd8f060c993a9bf642da0256739"
+ "334808e388e1da8237278bf4f47e05015a8b88c5420cebc8bb37ee4352837af7"
+ "6470184197",
+ "04a210f76c0f8493990953589886f62c1c4825012af44bdcf2c99b32a70a17f7"
+ "64a3a97b2b047e39d80cde154ebed5d2813ee84ac9c8d6ec6a96f402dbb326d5"
+ "a6e9c0f787c15e9823c508b3235f3a008dddcddb079e80ff50fe37254a0cc468"
+ "297ee33253a74c1e037026056958ad0778e0aa1250df1c14857cb0d71aa6937e"
+ "31"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.14",
+ "a6e3d1070321d8ff76b85c7093faa04283",
+ "d160b12c76622c3d34d85587e6e81cf054618a346b6752d5369a71c492357a13"
+ "4b7f67f334a4f3b328baa9f0071847d0dafdac225d7b7f071618ea8681fcd2d2"
+ "305c2f64631e623185fc0996e61c84f4180c637bf6ea2d060375f16a65e5b1e2"
+ "b865285da3d8fb1b6a60ea36e1",
+ "0a7003b5861a85a8f72f199dc65c17fc58a924bcc40819e28c9583e821038c00"
+ "05365e909eee4f3266f59a84e325b1bea9d281b4823f2fce44153f03170fadcb"
+ "16a279b2c9587f6b79effc55a3c434e0bc5dafe9d4032648aae7e4ed1d7f141b"
+ "fe722683fa32c89ddd673c3f0c03c85459890ab7fbc1d9a814bfe9b0d12ab17f"
+ "51"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.15",
+ "d0bc89039ba19ee50a7382984e428aed88614f789813018916e2e7eb0db83da2"
+ "8ec23c04a0c2f76a",
+ "c64d10a4b52f490ab62a6038b32b23c63a1c85970d9345148394cd35cfd6f6b1"
+ "590fce8c675beef87cd0345e5cade8950945565426b6b28303b0b0393298cdd9"
+ "5c881fa06533ca9d2d2714d0f13785a61b3a17a78140",
+ "008b197558ca4ce5901458abd8e8fd52d989960f01c216efb581f861148d1a2b"
+ "44eb0b7c15ddc345dc83f9037ddb8fe2eaa2cbed9b1c1eeeaeb865bd29f44ee1"
+ "478c95e9fbf444828eedcbc0170200de3549b22c11e4b433798b9d63bb49f0b0"
+ "2daf5658ceedeaa93c0faeb9446538ba92eb17c85db5eea204ba2f49c3ce65bf"
+ "13"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.16",
+ "ce0a4a5939f6aa263bbf8e1e5e94310356aba57559c41b39442770b61f6b3c9b"
+ "5fe727f319522808d58019",
+ "27cce2d43c71318ed4fc8c0bdb9b791353199f3d89fc12ac47fdb6d88b44c654"
+ "5e9eeed9f4c68515d4f530b8137d7745713bad0ebb7052231f6b4ced187aecd1"
+ "e7a169d86cbd13d50b78be27c6545d8192e0ec",
+ "0ad3ae7e5a98652c1bf345c491903f5517c611ac310005877fa91abcee6485f2"
+ "778abf0a6c73878737639b2672fdd00a3965d7d3d8d7688e77b5459e145ece64"
+ "a9a52c3797f36107c9368bdf7990f3fb6c5cff59f4f8a3d49093dffe7406c910"
+ "aa5723228dae5a9b29a4cc4769af8bd5fd6ece8858a29db1b19c081bf0d6b0dc"
+ "78"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.17",
+ "03bfb259bd9246de3f71c3139c728574b44d97ad57bbdd67019495c2a2004139"
+ "2634e31aad63f63b",
+ "5fa4bbb70e1f9ecb5eb2147bf459d1d06443f025c08e364ccc1b160c16416fb1"
+ "74b44b953638a9688c5ea2d060171f3054f3ca3fe013b9e3188ee39da91f8016"
+ "d4b7331879351f322ae529864d9074098aa2516b44ca",
+ "0178e3a017ed2fc118bb2e0328beb28a98c853b9e5a5f83080c0f1017fdca837"
+ "9207722c25737a8915e0eb72c52285e88f6130a1cf56ad1d96ca2ce4b71ec368"
+ "947bd071f8365910c792575b8cd6fd27e523e85965dda92282d5dfd1c064eaab"
+ "6abeac65e16ae04f0d40b3bb68410b9274dfeea32a43f94083c10780353f43e4"
+ "3c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.18",
+ "162cca9ed4708dd10340e194c35c0a5fa49a5c3b5b247171203ca48a79e52dff"
+ "40f2bca99a",
+ "4d73ffcdc26943a8707823478da31aac01274b1717c50c6ad0c62ee2bcd55795"
+ "2ef13f15ffaf66bb4f45399911c6d65ad187572bc1eba0d286cc45aa4932e73e"
+ "470c5dc8293904025c863fbc9622370490c91c8740b094d8f0",
+ "042bce0dfceca9ff05a6e3f74a6a70cdcbe0dec81eddc88e467f47bb760da44c"
+ "794d3cdcab939249f849d1d43956641b0b79c6861c5f715b9d8d8be9f0766adb"
+ "3f18af7db36ad95ffcd7e0fac1628523e8f69adeb7ff5094a2b5bf92b9d0efb1"
+ "118b85392625fd56f88faa0a16d54730fbc5caf16682e9e41b7e79d2022f7ccf"
+ "96"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.19",
+ "8e1b52cb4e007727c4b5f65d7847f34916891ef9c73ad18cf271f89f182c693e"
+ "5289dc31dabc34cf7f44fbde579e645169ecba6e4e877f7def44",
+ "ba14748e6da7b6ac1833323295adb5422dbd19e2ec72dfd0aafd7bd07bfb97e7"
+ "db108a3eaadcff67b67ec7e4c67004c178346a125dd3b6ca552370594f7f42cb"
+ "334b4485",
+ "094b4030e30c8b462eca00f16bb17019d1ea3125f1c64c671cb00d46e3ad8784"
+ "2852b201496ee2b3d5422893a80c66a30da2c9f1a32ad4d4e7737743ca1b78ef"
+ "7d4a63c5e1e0be7e5188cce942956974ffd481e6478344230c37da5b25f6b599"
+ "a59a0580f1a000c25954f3a463f2895f32b05cc08821b1a023609f18ca7d449c"
+ "b4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.20",
+ "82ff62affad8003094cc6535",
+ "1c7f21fd02097907405eaa77ae728865721d9386f5aabc2e0a95f3edb05d46e2"
+ "33793ba1a388e4b0dda00cc32b948ac265ae6a2bf2c390a4dcce110d5e866447"
+ "28f5378136476cf71dc7baac50cc41c20148dd37d5f70a812a294e242de803b4"
+ "8b6340f428d3c9bca96f766fc4f44167e04a",
+ "00303c352e1fdd2af8a8e3a169b5dac54345caa335a71a37e938bf9847088656"
+ "8418ae98d0aadfe79d0c651b3f516e70f10174fe6322cd376da02f226d15b36a"
+ "bf6d1cbdab6dd5654d9925f7253ce991512a44e9fa152712d7b8db7f18337580"
+ "fe51dc32a0582ce26053f1b9492869b9c47df92839c0502f2db4cc4d0b204f6f"
+ "d1"
+ }
+ }
+ },
+ {
+ "A 1029-bit RSA key pair",
+ "11654794f4649a97ac87ef6794f6a6ffb5cdab8702c23254fde034f3129aad82"
+ "5cf3c0cc3880a96fb64e48d7595ede06c31d0acbd1f8ef9cd1f9f6f00b24ba53"
+ "45aba146d41c563baece3b2523df6a9f43018a5f0869b6ec993469886b5d2317"
+ "d59cffd4ede9466a03f6dfec175cad5a85443095c730b98bbfa0489b91bb2739"
+ "9d",
+ "010001",
+ "1d4c4c6e13dab2846ce685d0c493525bb0ad3562596db9ad16945d445ce67c54"
+ "e938f654542b0934480291ac21aed098e85ad6fec6d0fe154c3c342b16999a8c"
+ "ece7faf990b7c8ce87b66fe327fb352ed011323d2b819a36cabecc5aae7230d3"
+ "f8e00245af35af808862e54d925607ee8b58e6a9f3ad8fa728fce26856c367b1",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 11.1",
+ "4ea8dfda3a9c2670ca9b80fa89710a",
+ "9606421b973ab4ba2ae22ff538707d7d4e563e8f05f20bc3381ff45b0c2919a1"
+ "b346b076035ae774b32af8ee566c73e20949684e447480dfa34dbb0c22666150"
+ "909a59e1bb22d095abe5025a76d60ec101c780e83a0ff159465c3e7ac0212bb3"
+ "8b2f1e0e6e0b54d35f4c7604c2d093",
+ "09bbcd8b63b29ce95226ec1d51912af39789fce5e77e7be67896c2c4e4c4376f"
+ "a428ec5d8a497acca9e0821e1f6de1067819c48a516f0691cbeacbb19d1ba509"
+ "f04fc01336d90f7396b43aa2f2b5150c28a45f35a9de1a2973ea10286794940a"
+ "b79f129e318cf97a5fd72b045b466d666e5de0b714f212a0b9052a0c91448e52"
+ "0d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.2",
+ "c6e257f3a1b35bbdc5cf420bd7654c52b252df32c570d428e63ea2",
+ "77bbd72b7b8fd28502ecf79fd1c8af8ebfe244327093b824795e95c0b436eb41"
+ "e5f0f2aec43363aa2c08fc33f287e6538040e4280dba4723e53292e0a67b21ef"
+ "77707985b72b2ecade280a61fa73d73dbb2fdb17f775f45fa175b77cb1067d6f"
+ "93a437",
+ "0d21495c4928c26a92c16a907f083335ade8eb0c20b0b45fe0e08ef39ae24ec0"
+ "b5057e6078dd7a1b9d102c24818557e90b83ffda14f3cc373c84c105ceee71bc"
+ "731a7f3571bd7bbba1d4f23ff4df0a84f312990ff771ff118f05bcfa222f11c1"
+ "ea01f6a468ca5a8750804098f846a86430ea23e9f07e2348461ef00ba62534fc"
+ "e7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.3",
+ "2d307f44ddff9c4535a06eda014a191304fb3fa8e3a2be88bb3b7be99f94d133"
+ "9c219a51ff5cadda93",
+ "5fab242dd9f2924b20d378a887b5de21d195769c3b5371c00f4c3f1b63268b01"
+ "0c31f32bb87c9a5229e0d9305f5fc83b8934b998d8cedf916f7a4d7268fe3be5"
+ "1235f8beac800d4fffca6ffddb29da4fa1c7769d51",
+ "0fafb61c3716c79669fcd1645246a0d3b075b28b73822015a8cadc88a22b7da5"
+ "3943e2544de396beeed3b0a989ad20a73ddcd191e8aa5caeb6e9088a4a3ae840"
+ "67f9198e924a9cfe1450b018a6b69dd23758e9251c76cceae840da2cc6251739"
+ "e23b9a42b63446eca0d61599a146b741fd43511c73663a923e3757f18a171c3b"
+ "12"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.4",
+ "1f033388554bebfaa01c",
+ "9d81575674663b3d877d4b0aa4fdc605470abc550b535272c8237018867c5022"
+ "cafe6a4ac83737e99c6ebafe69caa7fdca7027c8fbc437ec5232ce2e2529a0f7"
+ "03e201f7e5103235ba65a64794f190ef425493b648ed24a2197d0ab04d81c7b3"
+ "35a2dafd6b59c943a09b48eac35e35596291f5f7",
+ "001bdf3393342c3813ee3b8707eaf54647bade4c718a4b64547812e010c2b746"
+ "c88cdafdc316f0369a6c430ae7e6c50f05d545c3f798deb1d9a5bb69c5913933"
+ "c2d7792fae9d42ad76494dc9a3e27c211db4ef1985187a6c4d281c47721774a7"
+ "a11c1218d4dd267b57485877aa751f6c2819f81b5054a28a26a53df3ea3482b3"
+ "40"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.5",
+ "f71bc7374bd59c37775976f335244a36843c59e7489ad28b1a822d2d7d0b9a6f"
+ "e9ac5bf43682d63d636ef6",
+ "a1ff9844a73ec4b3befb1a860352cf9b75fc66ff479a2ded5998845a79773a8c"
+ "6206a36436c880a55e18711835456d91454b5ba132078f2037fbda7286251bad"
+ "d12d0a9781af3f5897cd947b1e1425f9705509",
+ "093fb68526cead010a54d116cd7d6035099bf1abffe9331de36486f053a80298"
+ "e4abfab40d3b03a3e7e925597338f1703b04535a9c87c65836f16111aae889e6"
+ "c8d90a2407d441a1c2a311cbd94611a42e93c73a3d21483fadb8f4e246d089f1"
+ "cfd70852b4dc778a60d152d3fca75fd6066704e933bf99f5bb77afc9a9cb3b8c"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.6",
+ "468783d4eac8813432048547ce241f72db1c85ce4adbe3ee2c",
+ "c6e32630ed90d0afb168c08b752259ef4b9e811762f7cf4c535cb4a0a04b1d43"
+ "654ed4fadfc7ddbc3aad0314078b226c4f3e9784457c91c7768c5c37b7600893"
+ "2e8d0457850573ce6b41a43cdda970031836840e4e60a3487b47a185c86f8a16"
+ "f6f221d0a0",
+ "0171a12b00cfd109674e5bf7f84347fda3fe4a8ea2f48e0d6b6d94b49fd7bdfb"
+ "26e32400a71251ab842206921d83723a89ea09930025920e3ef8a887d2bc2415"
+ "a7f1ed37ba8a5d03ef926acef61190001c5ea0f8cd92020cd89667e9ea5f7f2b"
+ "15378a210b8ae914819098da1cbec9c543a263300f994fb0b4928571401c202b"
+ "d6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.7",
+ "af631d76c97fd995e494aa9b4bd758c5c672c5e4158f3aaf874b",
+ "406e1e23f992bb0762125ca463bd0f2efdf1bfcb082a8df506af5f7270c39fde"
+ "01d9eed3226661db22a9c404b7d765fa384f9ad4f51b9369d74b0e37706631bc"
+ "6536f6555ec7fdebd348ef3cf5f8a877f606437c278cb8163ad349384baae32f"
+ "31b686e0",
+ "01ff8fe79af318d756f284083b51b43b66aae83c6aa91a99934b4de84bd5fd24"
+ "fa8d07c7551474665e62360a65984e67a4856c3dbd2c75f246e22222e9f4b969"
+ "516726ed287f423a6747821fbbb7fa176235c850a861f299f7394c2c4307b102"
+ "590940fed1206ad59b9dd6444e1e196e947325224ffaca069e9cdf8c62026907"
+ "7d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.8",
+ "73cb539082fb06dcae3c2068e989e7c0d8fff0fb340b6de80d0ba5d1e0064f22"
+ "13928a4baf20a80348af3cde9de63f886d63e56a3e32cd8e",
+ "28e2a97c7e9e033b49aadcee8fdc07edfdfdb950354b708ce5df848d1b51aa2f"
+ "4aff9974160181422947b133764c5a400657046a49363ffdf1f93ca48b3e5293"
+ "7e1f38fb50fb",
+ "0c72e69548c34ecaf248b2dc6bb64387f4f3350f668e59013560808c413fa835"
+ "fd360e04e4747a0031c8a64a9d7a07b363fad293b703a7dc990f806fb90e3912"
+ "21a116df108f546eae51716ba04501ab777b0c2a17712f71e406275f017377cf"
+ "2488c435ef6c6e7c45cdb98f24477ced180eb3efc8703e963826bfb344f16eb4"
+ "a1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.9",
+ "f2f985b8031273cb5fc89a31ddeb4c67a4e4f38c09d302874209b39c69b71f84"
+ "9588868fa5f8",
+ "c120446f5bdda06c63738f18155595f62bc26567284c35036591cd5d753e4ef7"
+ "900dff33bfdd3b108c102d089880c7b69d86e9ce3d688cda156fd6a99231058c"
+ "c3183396380946e8a969a7fcbe9edc959a0e504532bab8ea",
+ "10e0bc14ba16012698cc76cb82045e2bfdbcb2b118f183067959d7137fd50fa8"
+ "8fe4f9cecf6631a99cccab76cdb7744babd06b2bedfbca7724dafd91e6dfa88b"
+ "ea2b44a8cbb06219b15c2ae76872fad288e8438acd395ce5cbe28a712b67f561"
+ "a1786d75343ed9ad0d0a5eb6faed07b06aef03318ff1afe472db4ee3e21ec129"
+ "33"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.10",
+ "39872cfd6cf74b4ccc1a70d973b31899a67aeedee5d671e05bd60112e64512bb"
+ "e43bb840",
+ "68ac3f9697b750754fa7532e4161c12018e033a60251c8dca8387816f42379ab"
+ "978e15578ae2e94c1776488b0cfdff186fa6d79888f8169ee449eaddc8e7f5a6"
+ "58d0997a934f586e31f74730be603f1ee62fa6c08b0bffae6b88",
+ "09b77007f15d659efccaca66c1e7d962e047a1e149e52dcc0e1adc9e183bf73b"
+ "5f2348d34328241b407f61822f6d57e1abb322d302f4530d2cb9a41a2770238a"
+ "1bdf875edd797810d904e97a4d7c515132d6abbf3a4a407486dd004ea38aff8d"
+ "4ed3825fe13142f136fd1d713e80e0cf225769b419cca54c156e54668b306b5f"
+ "2a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.11",
+ "74d56bf8d9c180dc099371a5af72",
+ "337870f0479cf1283a0c87c9c4af54ba8f850644d59a2025263d2bdc49bfa663"
+ "6e7518f94b6ab18f85b19321209b769f0c1975d1d5ada06fd2a76c82450e4e09"
+ "cdadb7832ffb8ae7dcb47410b287804dddc7493d610a81399b6df6df5ef15209"
+ "2984fe2776a4f930546be1dc18313c14",
+ "0761ebaad8ff1c3dbe710f60e3be9f289fb27a6b5377755b71fb384c5facb160"
+ "3c953e1e2ca11e784325ae42f321ae5c58648c84f524df9de9f93fb4b0c2e097"
+ "97ff2d11407073b95a786df51a43f79982d86c49fb9e5014b1b768760a513026"
+ "6d0699306a904ed2dfe20138d531c5dc4bbf4dccf10249a6e2b355f7ccb326a4"
+ "8a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.12",
+ "611063b5da123ce2129617df38599557b95d1b05e6b66bcd49afe9831a0421a5"
+ "be4e48",
+ "10f9df30ec9777fcab5a924ded36fdfd6e1f381449ad99d20aea0e3972ea604e"
+ "a22750d0601d10a377dad1a94f9b027340948123827398bb22b1445f71c505c6"
+ "23aaf516cd9fb3e977f778cfdd3a5d28c2299e4b2abd9f98c4355a",
+ "07f2d58bc4163994d76f491edd69743c45dda0c38ccb0769de9cf9f4fd0055d3"
+ "0a0cf002800d76ed8c12cbd36af051a9d7337b29bc774dc3c4012bf5c28aead8"
+ "c3e036aa41398a8b0fe991c0bf66b5341c99d9377d94704ad490a9f8746fc5ce"
+ "f726e196f341f93a1f1eae2c13e00cfd22062f8eb3da9dafb95a1e7b81b1fdb6"
+ "56"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.13",
+ "80764f785fd4176e1641e129a35a9b31b3a89a7567ad6c1f0d65ec8af95fc16e"
+ "15281409",
+ "2036d098a6e935f9a411201d2bcb629f790a94db2ec69867433b1761d7c6954b"
+ "e91a9fc719190e108613cd584cbb977687046924bca6b2fe1a54bf76acf77b36"
+ "8c39650f6d0a498dbdedae3f4c21040a8aed634de4ed8af1346e",
+ "049c61444e924772f94a795ccd99eb2fe430997b91b42de6163629ab98d25a71"
+ "e7f96886a57e979d9c94c962209c1f712c70571a81f377eaf74e80e70722e1be"
+ "3d1337c5045f797bd57df2f5ae5ef33ae579e93b38fb250df0c2bc59b33a7486"
+ "7b8f3dfe5ba785d728b89d96b3002bc0054db5bb0d84fda45db4a1f2628ab112"
+ "30"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.14",
+ "0abc2bc5fcd040189f8422f1ca045021da95",
+ "e4732e4990699fd74740c852ae8d4d707fbd79460f88740984ae53ffb9fc3962"
+ "683ead0d1404f53151d1aee80fcd6a1ff65fc88ef08fd76d9fdca8f9e3ac7d8d"
+ "82b82ece789c66c5402280b3e568101ce2a2a7b2b2f1e96519cfb41e60493d76"
+ "8eb5b96ccc49bb0f6ec711fd",
+ "03d8ae604f92953173c77a01ffa090aa0e37a38a47c97219c0b9f864d348746a"
+ "f7f4a6321129c6046a994ced1ccf3324da937153888dd6c67019a7caa7655a36"
+ "42838edfa0e2ed8dc25c14bff8bff565c718f8b6c92056c9bbe8d9308370c7cd"
+ "75a04e11b6e25aa6c3c2cddd172a4b6aeef04fb835b68637cf0ca0b9a911b8b8"
+ "74"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.15",
+ "8f9835efb69cca8c07bfef4d8f535d0cbda5367bbd41080a",
+ "32d4be07e6c7fb81d5208c2501c5df7c56d1986dc6d63110ad21d81e57ce113f"
+ "3dbbfebe0f80c016b719e9d5c3d9a3bbbb2f35be95d456222b51c3d65b388e7a"
+ "daf6b9ceae1fd46a6e05ca1bb199c27bacdc8b5fd14f0351aeb3fdd6dc1d93f3"
+ "b53156efa3c6",
+ "0e47ad4d92d19a1ebcacbf875d801927d4fe5afaf66ed8015c559b566a9f3cbf"
+ "0abe8a76fe7324f628c2e4f34584a50ff77e822a54118efa9bae9d0fa50294c6"
+ "180baf3a8b0c7e453a7437ab1a19cc00307a8c6aed95c315b24b4790072456c9"
+ "4460995dbb1fe5a12b4cf4454296f7400283cefdce6b00cc8049dd5dd8cb2af3"
+ "6f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.16",
+ "6dfbd93b0078d49ae4fe1e24cca97d0a9affd7bee062aed29def0b1c0b3aefad"
+ "811d6e7ace8b49d7242a9fe6e23c22",
+ "319f9cda2c93388ebe1a50e76c9397559dcaf14fe10352aa511dc5baa64dc152"
+ "fcc79cbb23d4e69b12b9f27a7909159887bb04129ad63516813386374f31892d"
+ "4cdc4fe63969b5bfddc667f946897d",
+ "01c5ce836be2208a3d814e7e60c27674acb7cd3e31c024d9d38fc22953aafe73"
+ "af5240434dcf54a388992eac36ec8464d9a042ac58d18a70398b8a773e6669bb"
+ "3d76eeacdf1fd152474099bfa662a481dbab4ca46714958745e2b7832a59ccb0"
+ "053649b7e0950743333f5fcd6f65197ddcb4e1bc12a66e8e92a8659faee57131"
+ "e2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.17",
+ "e5879ffce0b629b8857c195cf5d09f7b93bff1f7a9f2d8a45a563bbbe9e62d",
+ "bace2cea0bfec25a2d34d72992c2b8ea0aea17b7a3a8bed60d1bb51013347b2d"
+ "036a75a4ec3eb2c1788d44a9e1c5c88d041e82af878155ddc7d81b3e27cddd20"
+ "409dbdda4a64bf8311a7b7eb77299312661a6e37df3502f86a22492befacf4",
+ "01e4faebcab89d7baa3e0393f71684b0ae53df8eb9873e65a716ec2f41741f8b"
+ "7816d2e197d976fd53a8ee7f924bf4bfd41042e16445e9060b55a0b6dc16aaf3"
+ "064491d18928223950393328c147dbd03531ec012d8c527502e7eb3dca509b7d"
+ "e16995924607c8b28a2bda9bcb2c7781461c76663b887b9643e2317f0ea1d1bb"
+ "14"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.18",
+ "0a2e24130e8a9d28dfcb9df9765f4683e9da78425a28199806a93b322efa8849"
+ "3ac37252c29a264f3e85ae56538e808dc55642a4885f054640f69c8981fe",
+ "20431ef31fce19939da545a08530112db0fa07138dd86db1cc65e2b03fc2be60"
+ "7c3e6038ebb7891755b23129fb969a7fe10610f2ebc3f077b2c8f4601e09ab4c",
+ "0c14b7d32d3d4ce2b08ee44f516aee2990b6305240b25d2334aa31752aef2802"
+ "1639f76a4c4719569b30052d4bd08b3a07f23be686237e481e67bf3f5a01add7"
+ "56da772c7dc13d32298b9bbc3d33e6df82d85c089d347600497a8b8ea4de68ab"
+ "b90e5c6aeb269a97be426cefacdebbcc0c1f2c409bbc7c72d90bdb426b13ccc1"
+ "9a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.19",
+ "7efc627ba5fa2825aae0ca94030e704708d35f92239826b42e2d4dbbe402ab7d"
+ "196a7f54880cf2c5a4d0fce53a20a32b6830e62dcd00dbcbf33b5c0c704401",
+ "f0497919c142f3a98ef55bcd5988234fdc8aebf736d47af97090a7a9dde0a735"
+ "09f9cd413626bb8ba767c9d638491c286e67bf22d670d56b24c15bad70351e",
+ "01dbce3b3f84b2da06b167e206649d424a42b8e9ea5453a16b5fc6c2e9cb17ed"
+ "a1effe4e7836a5e58f99e531530b40171e4b51fc0b92de3031300936d2595e39"
+ "1009e2e53c32f759604a6dbad9c970900fa6e41a35083f787b9bf3bebceaa1a7"
+ "71841b5e6e4c8b509629007b467e3cec8a1d0323c3c5dbc34d8d4125a398c9d5"
+ "3d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.20",
+ "593d3fcd05acee3029815e1e76a890",
+ "1235ee3e7a9df5967fe98d9710ffdd5f7eb22dc07147af436fe20aa526bf0b94"
+ "190cabb5213de98a23f5ef275022a2f73e60e9efe2c034c55ceb26aa806cded6"
+ "739ddb2cbd3ec3b555204a798465c37c6757195686a3ea3c5657c360a0158d99"
+ "2d4febfa0429eeb7c92a468434c5b7",
+ "0f699881a1524618bc25d4e514e2073068ea7d35384bafd46fc282e1d855119e"
+ "e969f211c7184a07030647fc40990ecf2ea40522865d91778a627eca8e50c2bb"
+ "9760b045daaf1277a4fa983576ca8cfad7608329c1881588017d63722b70e98b"
+ "e524e0033995982573d3387078c8b7c1c5f9aef264a0484684b3426643737d34"
+ "bb"
+ }
+ }
+ },
+ {
+ "A 1030-bit RSA key pair",
+ "261fe0284459c2fa6f05546bed585e1ee0a130b71c2b8a6fbb3bdc75787b2655"
+ "d0ed4e325b54c7b371a6fcf2b6788277a50d4705ba23c596285da7e3c9304a41"
+ "e7cc488b44922f7be2b47c16319e337451173d40b1ea481d1a9c1129b1feb7d0"
+ "9f67497aeb98948f1abf3b7786bd3b87047187c8f37015682b3f2de50e078e8d"
+ "0f",
+ "010001",
+ "05df768372cc0a64d3c21418302423139f479573e50b5c09b6e3be23fbc9aa1a"
+ "76d32799a047761ffc21079448170104cca5e2a14ce457d00d807d42c76a55f6"
+ "16874ba7f7eaa1ce63cbf132deb081aad2fd80d124c4da86ec6c020e8ca82dcd"
+ "cd3554e69bb19872262a5031ab5db7cc8c9259a146d58b1db94cc7e756253d5a"
+ "a1",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 12.1",
+ "7de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4",
+ "33d62cd667823fbf13d592ae4d02a2370d1d99db06c725425e0d12fcb4834ef9"
+ "e5499d607e8aaefeba819649fb3d61c705f5e9a3a2f896276189a3200d2faff7"
+ "7679e056349a5b9b7b4449b675cd48b6980932c2cfc46bf89a7734f68dd9f4fe"
+ "77e1d9cf1f31b21c4c61",
+ "04caeffcd51c3fc9236346774da0cfa77e9e6465f6437ff46d9fa458b3623412"
+ "c3103009fbfe203196df729626e0ee3afb6b10a5acd72e84281d9d9bcba3e0ef"
+ "77dd84f3db192d31b5b666f76c93810681373baa58e6dadb01fa5c65ec89fa51"
+ "cc2474611b9a7cb00e862fd3d49b1cd31afc2db449e09dae2d0a7d4df0bc320b"
+ "5a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.2",
+ "97eea856a9bdbc714eb3ac22f6eb32719669c42f9430c58950c64c0dabff3a9e"
+ "2043416c67caaaab7c68ccb3ca99a3",
+ "9f141261cec4f2c52f969125a36f141027088250d36b17421cd0961476190646"
+ "8afab7622c0d02193691744791e0d35b6bc9f3377e10b2856c8ed9199c89f4a4"
+ "1613d3c40cca373a7cc63c5260fe5a",
+ "0d26a05de93b707b8540fdc19889d2d1e7937157d32d303c528de35e553f9420"
+ "28744af6a0402eca0fcf5a85261ad475d8710cc9f8b11ba2c6daf1d672690c68"
+ "ed11e035e9c660ece1d80cdab800ead3c6e078617a1b0d273dedd8d65749166b"
+ "d07774fb4c1486aa8a0adf595dbc3d10ffaef1838498a67555c77b6ed983d5b9"
+ "de"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.3",
+ "8e3e772f39",
+ "9eb731fa6d8d5b7581f8fad2c8225bc96834af61db3d409dd56304ae23ea6269"
+ "63a4d80440c24e431e419760903ac44bfe41a75081a5462bae6547c0e7a06e91"
+ "60df9c01fa6c5354c83318db656dee0a437787fa46394e552ea5331559b4017b"
+ "b6a0e1d6fc8a65b45da0c45d88954861cd6e7a417e037b1b05",
+ "244a8634519af49f569b6986ab477964a6b2920d843a1d97efd7fef83e81bada"
+ "4c4b562961ef4e1fc333464b926bd74b07ad50c65b681683d389fe41d6d213b6"
+ "469f182b14b462d72c1ce3928ca806d966b52d42d0bfd60c9d04914d50837cda"
+ "e09b330e372744dce17f18e94d711c8b58ea449f1449d369faef514683d30160"
+ "79"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.4",
+ "dcfae7718c247c40f9a2a3c3535c509280c873c3",
+ "b93bbea6c1853f153b5e01e7e4e5d0c63d9dfb245fc6cf64043d7a9220b0b81a"
+ "c2af656b99714ba430e0a39695d25ff269b0b9b865fc4d4eee5e07a5b5be3543"
+ "82aaa414bc6208545c86ce02388c07b376fb0298c37d1ac39ea189b0adf780f6"
+ "e830bce917b50adb7a31",
+ "0c412052d4ef4ab51b2f623705f07f41fad64daffdba6244efd47f519de2e71a"
+ "01a6c57d1f28b6bf7b5c8dbb9fe7b149b0ebaa53596199376df490323d25c217"
+ "bc71be37f181035cf457eb5c06d6a3ded3d66d5b35f06181bf94d0ec13ec447c"
+ "708233491c554f9e991f6bcb8b78d33c9c36955b8dce5179ff8bc59244f66790"
+ "87"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.5",
+ "d71dd87a13991a0da2c74a58b0485634b3e04fec9e3f1cf2604a93bed79696fa"
+ "6378eb1ba0e5d20470a4",
+ "0990599258e97a2ebfbe10977225c416762e95d2553a801f726cc249bcdf3221"
+ "32585719fc12399acd7254ae77da343fe2a9a3acb11c14e214e2d85a76708c3e"
+ "72173da5d99058e0c8709edf28c36938769f1f22",
+ "0ff9cce7b69d7fca48d7c4f6ccff248c3db88bf1b7852cd9d8525c3b41e44a9b"
+ "540f208ffbb8c85bfa890ac02e994959d6b07f64814078556f8ec60db357acea"
+ "f839115fad41f8918d69c21a3affef6eb14a5d2cd0645cd706b58143394a2735"
+ "3682e3baa198002e1680f28f34be089a5784ace5ca6b110899dfb9582f2e4b2a"
+ "40"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.6",
+ "5e4b158f8dcbcdd7e308385b40190f5def8cf3305fc49de63c9e35b40236aee1"
+ "f456205a5267a2aa7d88cb2c11af7f2899d01da1b2c7466ffef7",
+ "a522f9808d9c01d8ff79775f7b22098fc5fe3254e1b04eb1cb850e10e2c5065e"
+ "23274dc0a05587436da37559335fe7093fa5e7a2a9c9a4dcaf235179d0e98fa3"
+ "3e34b616",
+ "1c0e86a6366beb1e12d6bcfa6ad49406c8b7e48d1d5be45cbd83194987496faa"
+ "3e21927ec662f502ac3f91a4b4b91d160c1986a5ed092766883b8555e3c9314b"
+ "44ba3383db287423af91b413918c0802c7778e46c296dc9f04cdb8b06adc7c53"
+ "d859f442ccbd5ffab5af752b979bf523a40a1d08d76063ffb3d5cfc82f15ebd6"
+ "d4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.7",
+ "359ba50756a80330409d3f236a340b90f42f732a87711fe22352d4c8250d4547"
+ "5e32b95883e1609755a13cdfc1bf394c5c67369eca1f9a33e8ba",
+ "f9ebddac9de1709a06bf6bbddf5894e23b962ba0c064bfcd7cc576603b0a1a1f"
+ "f35d645ee87ac6f821a6a151e6bbb05bf3e05cd9a6e2cd9c6cf553bfb07bd2fd"
+ "a040dfb6",
+ "083360e649059d00658dba21f2df28a2764c4589f7a77d5af99579a8ab4480c8"
+ "26a77c2fb7954f4f31fe1d9eb1bf40e809577f39301ad3ab95b3816c90ec3f1c"
+ "d629c4396174bed9fe1e0f476823e53b41d135b49a02b00effc761ec909423af"
+ "15855237b77ee07df25ab4e858467d4ccfe80843241bbf88eb4f853ef4b43ba3"
+ "ac"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.8",
+ "a9f39f8ba06466250c265df0ca46570a160112cf38fd745999",
+ "88b3c28bd3999a860b8de775935b8ed78fa2f27c268b243a0245af8672254719"
+ "f23a4b7fedc00d54e12e9d701f64699424b6b87d14d9676efa959be21a04b643"
+ "5d251003dd153d7d08ff28d93a9320dc1bbc3db397a54894f20579f93e4ead65"
+ "c31a407eb4",
+ "19839650b925f1f96d611e4dbb914993545c67390c32935fbf82259dad10f237"
+ "30eb48f34200465a20387277e2b961e08318d2077447c9109271e4ded8ff3dc4"
+ "f379eee455ae96081a1ae24b96ca730a62f7acc5a5ea5228e3a48ea6741cb30e"
+ "829d5509ccc6c287c7291f3a1d89d626bc981577de52a11f12ae2143d3b0b52f"
+ "86"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.9",
+ "68",
+ "538b095e4f2ad67730687421915242251d07f661edac7fe79e31d6c345aff59d"
+ "f388c7182fff0c0427b59935c691dab8bc42be47d76911880d917b862718b4c1"
+ "c1888d4220b9f8231acdf12d9b85186be0950c1aff84cd0fe36586a50e7e04b1"
+ "72ca9c859e2ded6b8ea579dd5e6eee772ccaa6b4a5d8ab1731a835d6a8",
+ "1e868adb0e653280604e8d3bc4d96984a20aa09d480b4dffac62ba78cbb7eed0"
+ "645a6d94d9d2f2d1e917c146b41faa3d1d2c190105368fb48406a1d2426af3dc"
+ "c85bd02d5c26c897ccb22e575912641a188ef4ac47a0a9fe9aa2706d8e1061f5"
+ "d93063f49017003b2309ca7d8d36703bfdda3f7f43df158a15bb22139aae1510"
+ "77"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.10",
+ "356587e6c6c0b46c2445e018635276ab845fd1076d107f",
+ "e5d33e4d93c70844ee4a016556242d08e8e62f1a7f794779e223ee9dfb231c3a"
+ "520f297e5073e4f92f535cf144557f94ee1e1e5cc6bf4c0c0c8e5ed40d066356"
+ "06f754cc2dd83fe02c576ccd2b835fd0f53a99083f4d15bfe9268899ef09ff5f"
+ "2f3cec9f9b8a7e",
+ "15d364a4499b30a5f78b6d7d4f667a1f76d715158f280119b055e1f2663fc796"
+ "e33c0eb64e34a8dada5c81754257a8bdf0ed8115f607b7c9cca481f74520b6d9"
+ "ac98f5e72c2baf3cbb6bd9baea5d75860cbdae3403fd5c37964aae64366ab09b"
+ "c9c67276951448193bb4b1afa27079c34170a26956510d442764229908420fe8"
+ "0a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.11",
+ "e153276a6879678fee19894828d6262ea39ad054c89edcb23f72dcda1b0073c2"
+ "87620218d92d0eb30c62afbf2b45df62d06665f80525b6727f95e34229e682a8",
+ "2ad7142fcfa3bdbeb755b2c5b5cf13e6969eb73b7a06bc29bcad7e7530a59023"
+ "0f6a43fc03d6c3a9c641e53a4177d5750291ec6d4b33f871668ad8569077",
+ "178e49770a4c8ffb7f65f382cdb576e608e975c4371339102b952a1e71cbcb91"
+ "fdcd0c0ed5a85fbd263da6a74e491fb04b60a5961d8e6ac724ec8a8161c22ae3"
+ "10407f59f7e602da48aa2dad683e88db1d84295e0fba5ff2f673df32854d01b7"
+ "1a89460ff0e6e1be98aebfa227e397eacc8b23174147c44e16201ec6babd165b"
+ "a4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.12",
+ "fa4eb931a7e2090f31edb1ff7d8361",
+ "437fa151f43405db22422cb35d1c5761161cb9a78abcb6f06dc4e7a869481f40"
+ "b21ae1d33e075c485cd8501a3caa6018325b7f850d4d8f6dcfd2affe19d3e6c7"
+ "0874e7101114f0fbb9822581bae6ba2ba1e7498881a5dc5bb8852738a82fb06d"
+ "1527b4334487b324013e32bcf17bab",
+ "226d776700c5e1ddb9994b3291f1d334b69dd863065fa83421e01d5206ec2cdb"
+ "8990cf78973109dc9f126b6033d6d5d6918ec850d69c713cb5bbe32ee59e445b"
+ "cb4e50c6f164434d2a6ca63969a29b25036415b0f7cb21b4f8b34a8d9b74653f"
+ "ff4f5db9d1a6b5152a644836b68b8ede9dc5a169dc60dc5fac468f2427845810"
+ "62"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.13",
+ "588115e53709eb15a3374c25329e883826e3213f37a1b7a65de12df23172f17f"
+ "a496ff492b09173ba0c6f58c293d47f148",
+ "078185e083cbb06fe1a749743515f3a0b4b26f853b10e568e87082ce44412ca6"
+ "7e59888ccc0f503101521acabfd98fb7b5c11d8a941ba03c495aa03e13522f48"
+ "7f6e1616bec2072b3996faee29",
+ "0e7e50a7b247b0297dec65c9523f67cab6b52a025f53320e9486cd207410cadc"
+ "74e4b03fc06bbed598b022b63b37762a65fd351cb2727f3d8035a4cdba9c6a31"
+ "e4ed6beb4fed3134eb63dfceab4f5f2459e59fca0174758aab3753b5c193c81e"
+ "11490f97b622b73fa73f8eae7da8393484b8297971a3e923129ce4357b645cc6"
+ "38"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.14",
+ "20f1cfaa6367c7c39b54a0",
+ "4a1c7b70f783ba0d5a26d4645cf05fa610f5be0177fdde9f2c345057db424457"
+ "faa430c9424a54f7e55fcfee6faea4244c03977481edfcbb288837c6a48dbd72"
+ "96677a24e06cc9d85e688c14090fa2830ff4967933eaf0db694b6ae402caf9c2"
+ "beff04a52a2f847fe40f4ffbdf3d58b7c4fda8",
+ "1e528420bcbba7d59c6c40d446d1aa956aff0305365b4d7ce9810f22c34f09a5"
+ "55e5ffbe5175037f903eaa6c40563636d381f45325b5e61a2c705112556402a7"
+ "dcbe86cfa54a6e6a50378d05e21c95cc6c45ffdd0517f77a36b224d1700a1f3e"
+ "bb81d3678a66e14534a80a598bd71726fe322e739c17eba508da8a031a27f6bb"
+ "28"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.15",
+ "7360cdb6c15996b060331e9f2a368995c064adda56559527782c170c691bb3bd"
+ "3b",
+ "58dd80f4fdc5c95dd9eb56ac80a02d53e8cc2efb3cbac6727d75b1e7b35e0542"
+ "19433af5aae198fd62f2ecd2ab8e263877b5c91ed513e235497a63192db9a9bc"
+ "b3bca97ae9bfcedf935644b2d3bc20e02ae5e7424e812a2949616b8201",
+ "203bcde1b412e3cea25b8630b208f978ab22c1da8125076e10ff91d7bcfaefd7"
+ "dcd8391655c886e8a945a7f57a74ce2dc0e8ec7fdb17cf195780d3ce80e0dde7"
+ "639c677205b8f9ecea115468977bdea3500b239fce0d7a94be6de333ea7ecc22"
+ "c07e65d0ebd65a390a185f181789e7ca8c1ac2fca828bb8d28227e38c9889ce0"
+ "08"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.16",
+ "319b8294bdf07cd40685e88009fa7b3f1290160ef33067add5ef4d80fd",
+ "4e07d7f963be24ee6d8bd4dd95e9e3334930e03e658d296bb795486d724e0741"
+ "dd507347a5b57b79c90d3c90c1aea71619091acc8198b55122da5099582e0db7"
+ "da3cbd3cfd85298f31554e29cbcba1199ce470163ca0337cc414ad3276708111"
+ "d6",
+ "04fc7bb6fb6419612b6ef54b3ca00a87465195c37f7f940c233ecb1d4a505d3c"
+ "56ed23e09e03f1454f04b56f6da25d0a6fcab0c400874ae9806ee18780b75c6c"
+ "a56629e577e8e7b5d2fc2c440b9800195b58511bc3a7954412c8f273cc0e9d97"
+ "1abbddd7028e6f84876a3058a454fe2f33c75e3dd062f119cd3eca8106b6bfbe"
+ "a4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.17",
+ "79c682a2b979fe5c9632af1831c2aacf0c6bf566885bf5256250",
+ "5c2a956d4b5f06f750835ab8b29cf7c641d793c556e12aaba956dfde4632d5e5"
+ "02d59041783afd1da7b2e2d24e22d6447835bf6d77c6eebc0d2d64e7ed2c1417"
+ "18ad8687c597b7718f38bf1a3316edeff6b72e2851828807bcffa9b8e1a852f3"
+ "faa807f6",
+ "251d4856b7a7580d53880162281bb4e41bdeb2a87ddbd5ae1b307d4448be1f11"
+ "695ff722c432415d0c74baa3fc0dd51166ac865b310c4f5c8707986254c89604"
+ "ccdabce6c692446621898b4f5a08bcdf6462e518ee3aeb75e26d8f63a06fcbb3"
+ "df098ceebb0fd2f637e3a7937f4d19e3a1924c16082edc333cb6de37637246e4"
+ "98"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.18",
+ "1e0d1807a2bd496bb0cba841c77158bfa5f8aa77d05675c64a5eb1856591d348"
+ "54f865925b371b686aaab44598b4a16ab6b79344d3c23f7d5bf173b842d78c",
+ "dbafa5332f0b552796636d8a0928b7d87d9cee3d4be6a31c77e14e0e5dfdd403"
+ "efb98fa338816e1262c06496fde9d557c00cc0dd35fc33accd79a3150690eb",
+ "1b2ecea5fa9003fab6559857c6d94f957003f4e41c094564804fe69639e540b6"
+ "8f263faaeca199697a48858b8a0fcea491057df2fb8b35d093d894aec17c5cde"
+ "5dfd8f33512bcc66cde76da07336985a97435b6efee4ee09d3a28aff34ce6ae8"
+ "750da41e16ca47e938818e44a9b41fe91a6a801d355ee8d660e27e4fe2ce7f32"
+ "5b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.19",
+ "1c105d5ebea36646a97284c17a86c4",
+ "c6f80340a6557e0753a9573fe4f5214977efdb082a50eb5d5c517d46729fd2a3"
+ "4af7cee1aa46b79d47e25d83090aeb4f502298c0313724fab54e54bebb48d6cd"
+ "9bebddcbee0f07537727d65c50e7d4cc0c6d19fc480ba57867262cf2eedd9cfa"
+ "ba607d658287eba42b469944ccb612",
+ "05b23dc0c62d90c1771eba378e43179d7ca6af515e2619ae4d7c8fc8bda378cb"
+ "f7a1dbba1a14f494c4e0d71338797c7ee06e1a79e9ff2856fbf74fe6f1a7ca6e"
+ "5b9ca283c4c97e61cf9f4073e032ca27d69b1b4eebea77cc95a9281f26b64a05"
+ "a93944c82c5a13428ece21fb4401ad426e7ac1f05bff84b347cdc4dbe52e678a"
+ "ed"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.20",
+ "f10402f00205c52757ed6e9d",
+ "e2aee7fcf43cede07552a2dfe5b5a9ef808276d8f10eb3f9bc50f1bd940aaae6"
+ "34c9d8a0788d44d41e8a5c603649efea83033231516c69d33e12f1f5d3f0ac1f"
+ "c23a9b3f5da4e0ef6e4550cb43fdff02b25dac86272d66db59cdd635f9c0dd0d"
+ "aa0857910c15881b160d70ea53405aa959f4",
+ "0b9656317832a940c795bba58daa159a4f733e826ce55a4ec56433c51684444c"
+ "78e2e2fcb37f85ad877916522d8a35a43f53c59517a818e521e1982a5091bf2c"
+ "68b00ee49abd90dd776c02f64f34f680a88eee05ec088892bc0a9555b3f20c8b"
+ "ee579c0ddde1511a18af98bc1d9cf90b81bf132abd58970b3e84d814e27d025b"
+ "73"
+ }
+ }
+ },
+ {
+ "A 1031-bit RSA key pair",
+ "555dc2baf041b7f09a0478423aebcb5f49b95dbe1570e9a542128d332287866a"
+ "c4cc63e76f8e3aef22c9753a545199942452418a67d1a2230ddb6f4222c663d3"
+ "8e80050eeb67956ec5f54994a0bea695fa59fadf2dcfe7acb54ed9da3d0beb12"
+ "2c8a691b0bb51ae65a774d75b1b349cb68c517cbd386ae482f05ee4603ecf295"
+ "5d",
+ "010001",
+ "059787bb0123fced98d9341b7a8a999edb5076308e6d0011203be0ddf9a4110d"
+ "0b692c1e2bf3902ebc03a0573ad0c193afb167b3ae4b5028a5aebb2204ef23f8"
+ "e58360be9484951e34711176062e53e3f63874fc9e3591a9d9068aa5e6c8c7a9"
+ "ab08e9792470066d71a07c3433dd703a42a6b3a9b1bffb3149498dcff8b35756"
+ "ed",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 13.1",
+ "7bc81d8146e359",
+ "76655e4ad8fb9934d1847cc90c02473c572b5fdfd164a970a3cd96bc8cd796ac"
+ "802c50282290ead4c77aa5cc2a7e343418c9df47efb88786af4cc8d1821c5007"
+ "3909e84f7b451af4a32aee6c7cc897eef7660e1c4c535d10039d3aa2035c9851"
+ "0125ec5f2a2e9dac639589ff8bb39f07438defb7d13377",
+ "146d6512dfdffbc02d5d54bff3e036a35b4c2aa944d6f6724793306537081bd1"
+ "1ee568a4e9719f1e31f2d14e18c2da624470c5b0ffab397f9231b6ef4634f63a"
+ "18285df3414517a51f93586d66b03cab1e78a4eb941b9d3d7f9203b59e1cb3bb"
+ "4864b646dc17a06411ebd5ff03372058881b4a24b24f4c2dcd5cb44c2eeabe6f"
+ "72"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.2",
+ "686a810a031d8061e41a776a7dfbdb3af626fe9769deeea460ba2867acf03d9f"
+ "924d321e8a8f425c2851929867a326ae275b49d2",
+ "f79b49f6a6be3e68884c80dfe1e8501e544ca782238843d419764112250edc1b"
+ "69c7d1c3587fdc75987c62cb4c33bb81202f72dba7eee24bfcf89d4dae150c07"
+ "272458fb01b6cd270925",
+ "088a47f11cb134dec4b5087725e8a5bd04f7fe582a69914f683ee6de7c324fed"
+ "7e07f57005c0e0df7500e370a42efd6fe5b290199519b19806b6e691698afd95"
+ "17d780da0bebf70a26d65c5b64e340a6405e889555dfa0a92c429ae9c3ec88e8"
+ "88eeda045e410e3a9e6199ab39eb1ac864e228c2cc1b64e3361695b5aa113dc5"
+ "a7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.3",
+ "18544aad24ab075d3a",
+ "23204b8ad94575f6e2f46c797bb873aa3f461acd05e7db7846a23157592d52e9"
+ "a9a7043819c48896275ed9df0b1e540493c077ea15419afa87dc35f9fdf7ab8a"
+ "af47eee1d33ecc28950645f1b691382d87541ed06406930c7ee1109aa5ca75a4"
+ "90934ea8d3b2a04ba1521be092c868f7ea5be378ea",
+ "34d6e546d69e2706cdfc6d9e7418f8be03e45756a8b19b60c21d273420aa7d5e"
+ "bbbf460ef4c84f6d4777e6bf203ff9185fd57dc723b58f35c1e9b5fff47cf95a"
+ "e569a5cb64dd9cb8d6407c0ba5efd148f18b5696b047daaaa277ed8d4528614e"
+ "e3da52387132b7a9ccfe073be50332c9e2837353c67daa0fdfefc3b652cf7d79"
+ "fd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.4",
+ "d90fa38f",
+ "3e09f6506f7f719147ae21e39453ae0b416098da103af84c0f7cefae500199c9"
+ "855967a8300a1a7f8d2cc13b91727eebd93cf77d3facb19e83a840eb583bcea6"
+ "c6113a9c6f6f1fb5a0b332559a6b431547457cda1d3dcee341d171c62e95e7ea"
+ "ae16ae0eaf1c1fe810fbb0b7138cfa3d66c63850f381e49a2dad",
+ "27133f43791b39227c8e954e1caa830fa65995f8a9f88e0d1f756785ed5c8c78"
+ "54fb1a9dc4a95fa44dbdf0f28599c472849379750a6a1bcb42cafb5bbfe08c65"
+ "106dc840cbec8ee2cb5a206c8118aa061da4d21d1b5c46117f77c896bc71cee2"
+ "f8757aff5cb2b3c34774558e8b82edb4ef9bf2d4f2ca4fc597fab40a2d74e523"
+ "3a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.5",
+ "fcbdd0248df857af175b4396875c006d5114cc11164280043808aa79886c4caa"
+ "29117bf3ce45a9be5507c6b8bf0d30",
+ "2c9d1457ba4450df4021e4e51183f795d091c07f6ae0dd962d5728c54b7fc3c7"
+ "72d79d7bece1bb0c996c9ac07f9954dda7687bec86bcdb3140b245bb5e01275b"
+ "38d1f252335e36c68c0e58f4ce117e",
+ "2ceddef202691aae4271852a8983de7c214cee00dbe1a15884f4c3c1de7a3ea0"
+ "1eccf47ae86c269324ae52377337b6ca82e85d553fbb2ee5f977dc664e142f1b"
+ "54538faf85cac27c29f2ed0c404267335d48ea40e8a3ddd896bbb3e0edf0e16f"
+ "9e8944683b8cfbaab5eaf22530f158c4880bc3e460c06a240342210aa87b7909"
+ "68"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.6",
+ "25f2a306eabe6e3a1830dc936bfa41cdebb88005175df4a3c9c4642301456111"
+ "5aa8",
+ "cb8e0ff41bab01a142f96e7d7cd392820a82a1736674b92135ef33089688dd30"
+ "b2c2f7ba111af78d3f76a37f667db3975fce64ec9afb0968507f7b31097eaae4"
+ "881b3624065616ca090c204c1fa4be134850ea5e90fecdc845b9d839",
+ "4c7ac81245e7d4de3c4dbfb315c468341cbf22875735c5f80590505853068d6b"
+ "e7039b1cee6d07ecb7669c42f6b92f2a71f645f72cbaff76341637d2f1d6b1fe"
+ "ceb07f21e14c70fb77bc7f87b031c2c8f2ada4ec43e912682c2f49639e757157"
+ "1877fc481cbf2698b37315bd4b930783f47945642b7d815e0432d45dd1d0d3b2"
+ "a5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.7",
+ "a0daab4f9fe04a2a51bf083270115d0d06dc2921cf8dd13f5cff2604bc551efd"
+ "983d9b25b7274f3ccb0adcc11b1a3954ab9db4",
+ "c81d1c02f06e7ffd6e03b81b7193aabdac5663ab1425a67d1a2950885f5d1c4b"
+ "725e209dcbce9f7bf296752342f184fea06a7d6cb2bd39b2a318075164a2e761"
+ "b702702b019246c1e50e6e",
+ "06c06c975fc6b9c260d3d8813b5714248beb399b7d68fcac250338cac54c4072"
+ "959f62038444e9e666bab5f936067047bcaf4ba4ed68c6c8185746293256e7c7"
+ "2416658154dec067f4250dc6b29bbac18e821e49a4c9b163831f7bb38392326c"
+ "6b4685464fe4f026c9ae4dbc5849477b4c260aa4ac02d21a264020f10ca11b4b"
+ "0e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.8",
+ "743cddb361c0bb32476495ad5dc63a2bce5fbac1c8c20393693267d843f28b8c"
+ "f3ea13e374e09d0aa3f7ae5d8f72d8e6cb9dbd",
+ "f72ed2d069b8ae5027046e0327b987845809b4e816c8865824fc4a2301b45680"
+ "2b189cbb43f04832ac25c848d74fbe1d625aa98ae05eb62547761c78b81761c3"
+ "03f93df3fc0fea3c5a7bb1",
+ "383ebbf159e1d0a21c74eb61e3643cb631be18c7a2a54e248933587d345e9952"
+ "72466dc1bd613addb4cd7ba50192fc2d894d7fdaf78363b079d998019f164231"
+ "cc2d752db76a9f9d0c5204bfb0f9930553096b5b7680b0894fb99c11425c67d6"
+ "5d965e35128e154746b3fed8d016993070a70e07ebebe06f2f4e976c9a63fbe3"
+ "20"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.9",
+ "e53192febcd36958bd0803f2ea0afdbfdf993b58a9e4ee70df95b06d4e7d74b6"
+ "745b87f581f342f8aef9ae4c3182c4199b6551fe18f8d3b9ffe4",
+ "ad982fa729f27fce8a674903ecac694dd33413c78e3428aeed469f84d9575c6d"
+ "a27529f2c14b53b758d20fb6b247c829c5fb1a16af55079a7073cca05625962b"
+ "6d1a6bef",
+ "221d88a86c9ed37aa09cf572549782e58ca8d4851f016acf289ee8bf23790b1a"
+ "8f148c165508bc3fdb1ef9c9011627427c5f32e5cab850cb6bc0bc04a11da2f0"
+ "1813f341417b3e632bcae002977d64ffc962c7fa7572f56d2617e2a52d3ef917"
+ "c44a33b71582aff1390b7c774d607c8d578f7bc90b3580d77b0373191477bc14"
+ "26"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.10",
+ "d0eb480e2745779c8a30fe820aef56d4ce39ef84ea40c7df0c",
+ "465f91e3f07cb72283bc2bbe528b9ab3681654fe20b61a33f123ade52e832ffa"
+ "8a1b74a4443cc89295a21a2aac9874da0a5679d18cb5c4cd690bd0a20cbd9e9a"
+ "a072aa8713448f95e5d6a6e624d5b9085cfcecb7992f10ea2da6d626ebe543d8"
+ "702236ee6c",
+ "06f3f8c70d0fc4e74473e68fd23cc9df1edd4235b428b772a083b41c3451625a"
+ "6f15dea4bf313bf4f03fdc4fe9f6a2071ac69aa3f0fc4157efc621f9594061f6"
+ "c19806bd5d759ad023cad148e447d259b62bf7342591be83baec77714cfe2b90"
+ "1f369aea680248babf068710cbb970484f324a235253a31e022534abec7b3996"
+ "06"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.11",
+ "1c4297f6dfc07ffe5759aa1eaa5b79378afcdd1a9a33a2133a39ac",
+ "a7af2a8601e408c318fd1e0f82445b509544d5ec97a7958f594b2054c509f7ef"
+ "fdd416306b2b2c91b5a637a156820d601a23ffdb31fb35d305aa9374578eefb8"
+ "102e8b7244191f4ec74aa26a0b7db36cab44999c81b36157016b558906e5d708"
+ "8d5132",
+ "3cdf2dc67a4aa531cfa1428008bd0544abbd032922dcc2436da0b5d7ef9a7017"
+ "e6193a8baf38c58e91962d65a375f08c1d55579cf94a795c9c70b6e42e1643ce"
+ "f540dce1e986dd998887b69552444b6de93ba7d5f7648354bfcb702139ed3954"
+ "947d7b180b6c02bcad8243a0ab27ca665276291b46cc318da9b5f60a04affebc"
+ "b0"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.12",
+ "00927fca7f5ec76f548dd48263e339be",
+ "debc2c1f22d932ffcb897cf10ae62c3e051e3f78463ae67d9561cf1a73d55c4b"
+ "14aca6c21d83baf976cd8bf246c2297861a6b1e9c9ef3081c51c4b687c67b5dd"
+ "0fe0f7553f738c2c8a5f81d1268a0c2d4a461d635b0e59d23ba417abb8045e9c"
+ "10d66b0ec892f953c6f211f02ff0",
+ "49b92089b52ab78c33b5bb3032cf7024944ac68e139d2d56068c7a262a53e780"
+ "9fb5b01565cc6561d7133046875230ac2175647296cf2b4847e12b7363197253"
+ "21bea264757de0eb498872d89a4d7ce4a1bdb7335daea78ba196fd50d90382e6"
+ "d62f8df7ae685a1dfc849e11997dee8860d10f707b0d35365a812430731e7a50"
+ "8d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.13",
+ "8b6df2d6da631ac8d5556a26975428fc4d20ef5b4a1f068ed2e5",
+ "ff2c0698852d1b0ae3c5c5c9be26e83c9044842c1607f5f4086a6d6cf108adca"
+ "61eaf665400d7cff2a3adadfafd80c64956da2d7d7c135abf5a0d176062556eb"
+ "4d8b75b95cd11ea9c0442f846f037da8772902bffcde6559e1b59e60c6d0f989"
+ "6ba5c3c4",
+ "41527669803339ebd8f2d1cc186c7e8ebb80cf4b949d8a284365329f3ce46ebd"
+ "ac0a969f6761900cfe342bc84c7d6951accf45280baf24a0cbb242a94218ef9f"
+ "d371b1e008246262070bf554ed57007b9739791635861d86c65b1a8256f425f9"
+ "f3ae519e1b1bdc5875b878ddcfc1470feef2aeeb014b7e33efb9f4dd0783d171"
+ "23"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.14",
+ "ea039669bcd7a8cdceab585591b56361e90bda0ea440104964e889ece18aeb04"
+ "ce0ab5b1ccb230ae03255a39",
+ "204faeb313965cc1a18faf1039fdde681bc43b223e28bc471c50423da0bd797d"
+ "6a8c738c54033c8e559ea2d10c3b79b80e2efdecfe891cea2ecb3451a1a8e2ec"
+ "2f447b798d7de5641bda4aa990b301e1dde7",
+ "4ca1c85ce3c620d42991cf41733ead26a09311185fffe58f41288f6d0bb6845b"
+ "2d5acf1aa06c78d71f769396a9434203e38bb01fd88eb23e6bc51ba0c5f3eeb3"
+ "2713cad4d087805061ab473a1567e79bbf4eae4936f18d0205b3746a17e0648c"
+ "52223dd9f9997281b535ab2fb3cff03ca890f710aa88fd2d0f392ff4a88d311a"
+ "a1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.15",
+ "0f462bebc6",
+ "4eae5d5492d944ffdb042ad9501681adb3eb6ab528b6e8135355b623ab55a740"
+ "87b19fc59b8534da9a88da29f66f71f9452aede0e3e93907709c344956728574"
+ "b66fb9a6f3383d58a0136f94c4ed86ca9dd38bff070fcc2def29bdd6fc985970"
+ "967f02fd6f9301cd56d048a442d702409a98a132ab6bedd4fe",
+ "29369eb00a3f878438c938f9d7bda3856c45a6d77c1788511b982c58f63dbea3"
+ "3e63ae1d45c2df6ba80f0de997592e1f8a3b3a09ed760651453e109978cfde3a"
+ "600a74faa8a91b7c724f973cb80b96835f050b7dc09d2f157476c5b7051f94d9"
+ "c0f317e1f188e30980795b096cf9bbceb5636b3db987054a5608752275962997"
+ "e7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.16",
+ "514d3b380022b3782e8a77d77bf24afdf92f3397474dae0d4bd6e4fa31ca6083"
+ "df496b36626e7f8e1c919f9f2e",
+ "d4d3a9e8fbeb1dc607b4dd7887ba25c3d0bd813484bd5376dc83efb58ec5b256"
+ "2cb44f985e59f50b9ade3c66716cc6f42e51c60a2f4d8d75bfb9b824105d1ee1"
+ "5835f5f5f254fc6f680eee0b85af547c17",
+ "19fb391a310087bc3d08791fd59994be8012dffd76a02adbd479cc0c1556605d"
+ "4da2a3461c7c71a85ed8cf85e08f45dade518c00af09f493ee8a5546ffbefb05"
+ "3cca2eef0684763cf780f2e097bd8e5c2ea84cb1a8b8f8496cc918167f656cdc"
+ "9e1d3b2a2338b64c61e90ecc274a1210e3db5783ae3c00abd3748a810fd91491"
+ "14"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.17",
+ "fba16317b093083e3720aa064817e74ca751a517874b692650c4147f119f6890"
+ "702cf8b14f0c1882212d72406c3a45d7d9ffa4312410a6",
+ "9cc9a4bf8cc275a6b9b13510319110917ad85324c5a4345e58f1fa47275ee592"
+ "1569dcbcbd723670cf4a24ebcd57f57e998c4bbd4a95679d60baa0abe879668a"
+ "2cb6ed0fb94e4a",
+ "4c41b9cbcc6fa87f23f17a36d051e7780a070656cae7beba14fa91c555b8588e"
+ "8809e7d3354e7ef5e0faefe1cf392e6fdad4044aef08e33e6fc201c547fdbdf7"
+ "c73d3be096ed253f9df4af52e13b9a1925aa7393a6429530209201e55b20e51d"
+ "5005d06b58353bfafceec37d60e1ca0d9dddd8680bd0a5d692e74f2dbdfce266"
+ "02"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.18",
+ "5ffe82e033544245b84962d3927c2fa59972ef59c237a386a51bd0ba1f2c1f8e"
+ "45b46a05ad97db49d3acc6344f1edadf6564c28ce1",
+ "cc2359bfd0d57bcebf075b87a585a9bde6593eb24961eff1987e735605d4e30e"
+ "971937f6f3f5be5278fd476dc660ee0730cd07e5d1f42009a333312d9328f3b0"
+ "085c4075bc709a10f1",
+ "058b50e0bca6b934c01bf7c33bb615b722ea41807a7d2c7cb3d438e28dbe333e"
+ "d6d837477af84bb006bbb10b36944f15d4f6d28b5ed249d5690c0837a16e157b"
+ "a8802274101cd44e7fed72a75981c97566bc70e5559702bf5b62fb09b2136056"
+ "73aaebb7fe9b1ae6d80403a20133803e1ed2350b8e15ff019a700f2abe87d6e7"
+ "33"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.19",
+ "22633cc3fe7a7b4f00fa999c4fe0d882c31bdc0d670c0cc3d288961fbe6372e0"
+ "e5324642c7b1fa852e1b4f696f12f55866",
+ "3edfcaf48871d291d5b7f7723d92d9515152b6bf52b823699c588f75f34e3795"
+ "550d078118e286c96e9007aee154f57ce7f1d46039473a4a37a9b590a37eea59"
+ "947fe8587c956988bcb174e97c",
+ "3debbc6cfb0eed87166bccd54c7597ad36ca0ac96cf16676e1874bf5f10a0ec6"
+ "9c3be2259678eea63a1808d90665ffce9af0827ee629edd65943437f8ca0a671"
+ "172c521cc0d1dd01e22f20a6c79c427ada8856000c4e035d9c5ef2e105f2c9f6"
+ "457d9ee95b43bc4be3294a0ee1d5c833ae91078aed09e792bb42c25e00b087e5"
+ "61"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.20",
+ "552b384c5e5174f51f380d8b53e3c897b48c669a9c2d11985b8654de7f76d962"
+ "396a37b95341f99dece4afd71d3c84e1287b0f0f86eeffcfd97ba188e3799e",
+ "2e2f3e3f46d4740cb26cbc65aae2afe49d0be66639d0db10dfd6af606446f3b7"
+ "de98212f86174bdfa5b2e2358507453c20ada69a4ffe0a35e12efbab3bb44c",
+ "149291eeb536fc0703f7bdf1f031a430cc83adc43e09686491266934ef37eaea"
+ "b11bc7f39149ab33436694593673ccc6390b529e64d342e9f21d176da21fa65a"
+ "bd57eec60ddec7d1a093dba376445f1bcfe5a6aace9f1342af39db8ad485ba22"
+ "2d39126228faeeb49bb3b271fd38e11525d803154e74084b75c3dbcdff2e3d10"
+ "42"
+ }
+ }
+ },
+ {
+ "A 1536-bit RSA key pair",
+ "be0ca01f9c172166f912391e5d58ddc30d5dd0279a49bb312a31e4c8a66a52fb"
+ "4e8b6742faacb224c3039f1e198f3323b888ba0e35bb94c511bd22b886405a71"
+ "5e409de3bceb4fc9911b0e9c3b1e42e257d5bbea0722b5d5dd3537569dc75606"
+ "46a750b87eaa6f3a405a94bf2ada72b50a4b0187bb9d00ec451d50a6a91a1e2a"
+ "91192a7fd756b900141fe88f96e2080dfdd80166a7bf67e37144d09e3af89974"
+ "e57c72b03a2b88fd2995252ace4f30e2e47c2818057240536b58db4207509e59",
+ "010001",
+ "f37d28d61f2899a5c0e0a0749d1389387c64c8c358a971dad13cff85c59a62dd"
+ "a7bbc0f7e5bdc65dff9de9c745404631758148168dfe6ac0a2876a56053bab2a"
+ "2a9ff272794dd5d8139eed10bcfb4df33020d59e3048fd2f0c431426145e36a1"
+ "d0a6bfce4443ef3c7e31d4a92fb8517a49f788c3b4e137395a4beeea63e0e0ad"
+ "c3224f980925037df6f5b26c007239b4f01f8a9a61ea0b5119bc9d5496a95b60"
+ "ea766ccbade037e340324f25f02e7245c236eae4367a6468a7a0938d85c0a1",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 14.1",
+ "2bd6e3c1defddd5a43",
+ "e784d52503e6291f258e442db577f9916382a0d14c7b9dccbdb607af01f0258f"
+ "dc972397da1239d4449a58286ece2008f718f690cee73a027fabf84bdf7ace45"
+ "f7ed2d77324cbee90ecc6f1e7b86cc2935a47ba156650b42fc71aad07099a27e"
+ "97fe5a3f25fe1348e442391212a5cf1b445a1e70191ffa8fcade635d2e4465f5"
+ "f913c53e33b59152cd8a149784f27d831828af2d666a5c309b56d0719cfd8073"
+ "4069a23e092d8315399f95c40ad7fd0bb5f94377",
+ "85ef3e477677bf76071a27bbc7395715cb350796e44f1b52a08e905e08ff1256"
+ "705a9bf0152e872bdc74bb1f2fc8631ef8812d16946a30b58f4464d6e7b2450b"
+ "e45b48ccff5d8ecf7a00b1b78fc8fa54713dd696a14acb6800c0d3b69a0b4443"
+ "77fa303a7d66db4927918a4bfb0fd493bfaa016aebff995330a6dcb6215dd3bd"
+ "b35d7cd61ccf0e9cccbf51e9ea658ea31d1243444c4b72fff01ac93f28eb7f67"
+ "c1832e568ed72fd957d5b4fd2f00b6023171b85ab0caa1030ed3e3edc9503145"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.2",
+ "104735d9ad726046473df4b13b2f5fa285c3d233ecd46170582dd228cdee464d"
+ "a5095e208cf8fbca05388b",
+ "dc6a631e297545d2f6fe9c69a5d306a10916d7e7ef0dc953f21b6a041431ec8b"
+ "a5ce1c138743faac5497d699f2ff1d4a44a3e0637cc5e5e638cd73677d09afee"
+ "3ec9fe8052947a73334c3270472856f307243ac58bf8638074667d7f7c18e3ab"
+ "327ea3fc7891f1c58ab47e4ffa6e7d9011a33d9b40a2d789ee4221256230ca8a"
+ "61811b0972cfd986017526181d24eebb32cc",
+ "921d2b026d6b7e22201de77fbf679990f9aff4ea7fe7ce4502215f9e7aa418b8"
+ "5f72eadb6b6942bb08a08be7da6619aa5f1d2ff961c9dc2c341ae32a254fdeab"
+ "a2f6450ac4474b6274f0c346f26da4ed555a8c951189dc8369f34d76d837d6f3"
+ "8a9518a6271c5b56346225a5ab8da6032a5930fd5b77729de632e1752fc72a0c"
+ "34aece25657b281be8932c5650c982fa145fde0bcdd48a73aa0288b4de461133"
+ "f27d51e386016a72726a9ede1d32dfc7e6f9780c04eb70ffffc2688295667333"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.3",
+ "317e6f5e17500fe94fdff284bbe50301044d1422d3ca700598",
+ "466d53c8d0bb9ed460caa63d79bfb877bc4ea345cab4357e639a95dcae379ddc"
+ "ea5d64fee99fb6f75ff24eb74d440344d147e43314a0f89f8b96148215368eb8"
+ "651f6d3ca0d08d0b4c73e6d1a768409826d43c2f81f30840605c43d0fe671d3f"
+ "024c70d0b89923cf904e39979962cd515c1674292aa30dac700db4eb7e63d56f"
+ "df08c22470f243861945d00fa4e27990212cfed4285df1edda4b0aec913559f5"
+ "9d125590",
+ "141fca68dd2e4d1de5086dbb785ff47d81e39c311d917a9939a6ff5b13439ca9"
+ "56c9742bcfe450b5bd035b541fab307f24fbfb3f8b90215b5604676e5696f3ba"
+ "95fdb8d090a6c24a29d990fbff1da2028142558f0ad75343c72f38823db7667b"
+ "05e16b5192b9336007f758106c328bd476118df82ad07548a726921fb2e192b4"
+ "3c8c30cc9b8434630e27fd8b23ef8d8f22be7f73aecdcb2b1ec5539d5fbb2cff"
+ "9ed5e7f19b49183d221dfd537d4f37032ef32f63b6ff74ee24a096cf45592709"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.4",
+ "90963ddab37891e7288b53be5d9dc567b1a07a1566c2afddd7727324ba",
+ "a49f1215175ba04c274abc051f0c17a08a63648943db2e8c7622bcbb1dcc567e"
+ "be6add8c444816c9d436ee93cefe23ec41ddfcb0a403bb6dbff0ae5d6fcdd764"
+ "dac1a72a484f36471f4f3bd725b2db5afa6acf530e4e4e86b4fda8782047871c"
+ "b055ad68c841de545a5540c8cc12e7e3f15814a0039a81034bde9c68ae2285e6"
+ "16b7b5555f98c613ce2ef666a022465c6367d0bda40c12e941f6998a14a2b5e3",
+ "8ad5bf78232aa36fb783583e71bc1393037d13e77454a9dc1111434e75dd8020"
+ "46bab42025420c63961ea0062657ca5065deb653ac78eb6498cf14d1704cec59"
+ "1169608db01fc93d0d68e62801b465a387a9c72f7eb35b0ba53a5efa98c9f0cb"
+ "7c7cba1804cd701d0297b66005ae25ec3b6cd4cf3194a3fa65d98c4b95333079"
+ "0efde74fa275d2a79d3310a5bcc2c81c91fc25562ca939f8d9c175edf4b07673"
+ "d53924e27b1552881c10831923715d149f1f319e38e91dfa566c5453bacc148b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.5",
+ "3d81021ff6473337e04b92",
+ "9b7029731377e82697fa56b086ce49d3c4b1549de81e3e99e16cd972297a560f"
+ "f483f2ef5b71b00fc684744f224e857e6d7239f156d7b6102f2304f8a55050b3"
+ "756c548f6ea26ea6f7394d2bb379333584e3b481d073c0a58a0ad787adb480e1"
+ "f20a1a590e031e6b2bb7f36a93610ddf7083a50768c998623f6e64376a29b4a4"
+ "18032d2739bd4e747ddfc77fe3cf2793a29bc767bfacc713e5f10e531b4c7189"
+ "97b9bb6b6515e071132889747e546b13468d",
+ "1b884b067d0bb1597f5fab933095755a530d9d04e2754a5797ffff5ef9cef189"
+ "5499982300503b3febcbaa09d36b7dacc30df3c868f01a5f17ed4a72a85b6adc"
+ "80a26a1b81976b393cba9b0c82cb1e2c583ab6f314eda29a433221b6e3ed5351"
+ "5374bbcd2b96f5cb5bd5815d1a5dcbf080d2d37cb96c4d961dc47e130db7b8d0"
+ "182e3369def4c0f6c42c6c20531af1a19036def08d4baca71b99af3c4e1ed527"
+ "d51f37d0ee1ea2c8b8ebf4fd5279851dc320e742008e04044d0da06436613d1b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.6",
+ "5c745dd4a8c592934ed15e22fa9dec4a4dc20a9f",
+ "0e6abb829a3b16d08b0bd43eb95c791af2a33912ea833ee6893ed5ad3ee744c8"
+ "b2dd28fcee808d3f01495825be0fe6373207a878d4a525ea72cfb0bb58a26776"
+ "fb39eebd335f04cf7186be61c5635d95e560eddfd45dd86a4e670d33568d83d2"
+ "ca203ed28d90e48b064d09a75f828deacd5b37efcf784fb11b17d6d9f2315224"
+ "f8e763791bac6cf46e1c23b0b0252c19edf040d35f592553265b886b29ca56eb"
+ "c5386371414d82a340",
+ "2b0a43b3cdc99d6cfc74da2a86ecd7d5762475d143e5486fa9cbebbf27d8e414"
+ "1ef72b6d4f13f664b3d2e9ec32227c1ad5b76c0d1befbd658968c7db14952382"
+ "49bcd95e7540254e65749823b8a34bf6a1410721df34f3c8d579f36aed9e0bac"
+ "231e54c27f7673197d19f51ce6acbbcb7b1a55e38edebeed3461073e80c79a4f"
+ "c3093130696bfff2bbcb74905f2d3444338057fdfacbc4db81935b29e99e55cc"
+ "c1d48d89e9dc4a63a011a62332cf570262a06359cc36c05a6fe18afb7832b32e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.7",
+ "b0e77f42c1a1e3f4155723a90db88eb153cb3d3a28eddf259c47056a470c915e"
+ "c955f83189f71aeacdd55c335f",
+ "fb3601105caa9a2fdd6dd6c5746f4fcafef441bcb0fb8a2cc03d0b57349f9321"
+ "af9d9984e64e2ec485c9ad755f140c0b66db1cfc26691c267731d1a3afe68720"
+ "2a9677e42e844d477b75bcbb8c97d99fcf72b3fb6d349fa9c476619147217a04"
+ "dc06aa3c3c176495380cb92c0a7e097b4b4c5ffe04631ab1d1bfea03678650c8"
+ "5c170fa4a1d64a4c135e61481490b62b",
+ "a4bdd492fec79c3a79093a44334272d9d17f543d0202c39e408bfb39366be2de"
+ "61df50ac458caeddeffb69e213ca92b7495366347ede733ff399aec796c3c3b1"
+ "df349f011da01fee7d21c1c261843de88208560c0e8984b95223ea3731db91c5"
+ "937a79b0db9387591ce32ec7f583e600f52444dfa7671ce8273898fbbca3a4aa"
+ "6832cbb3543abe9647e5f8c137728252ce5440fce10e4d4ef75d56b814d51964"
+ "4441411c10a2a14c350472827c99ea3ee5fda3880f341dca8d3d3a4e5e05ba42"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.8",
+ "b87f04b3350e1263daa3f9405e6fd3d25d8efa132556a49571f5708a42527af3"
+ "1db01edf79820f9326645fb1",
+ "ec8d014d6eb8d0239a9773bdd320bfb3f2ee8fc27d5fdd91f3f3905dc8a4c5ff"
+ "13529aeee461854cccd4e09b624afa647a7c04814eb1e57ba14df4c795b42e84"
+ "c4d08629245dacbbed27399a725a948f3ba2f8b64d2602dd0d5f55cb23eaaffb"
+ "3a66508e4a689ad9eee644e6a26d438f3663fea9bd0312bb0e7e5a6dee04bbe8"
+ "a0745a73d5ac89faa096a52ed3046d77de",
+ "775dc324fe9d5e05ad015013d65f0eba0dcd52ff9dfc1795ea93d0f433579896"
+ "86fe3f8b046223bba5c7849acac3123543432616c3103ac2ba8db0a1d29940bb"
+ "a262470e5e53be60e0eb724d07cd912aefbb87fb51980e9e1ac194da31929541"
+ "ca43224b152be6f2df6c5f0442b4f4d2cc2fb02739d485a01162bc8dbbad1476"
+ "eb06e245ab36c4c72d3f3607d05084a0f6b72dc8bac346bd19091b02f5982c91"
+ "457c7b10f4472b57184524214b23825b59f434cc48a2b854cab50ff79e59091c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.9",
+ "e195a036a530e1c2a9d7a103358dc2bd25b101bf704450ab8e5062cb63df5610"
+ "35",
+ "0ef881defc45ad3f3e58b1105e49b423ab89124a65b52cfd81cfd542b91e7c4c"
+ "1a6071a2cf12b4827ed5d19cbaf8feea54bb3d73857ee87c715c71b9ed1c07c3"
+ "afd90fce40448bb57e3524d038809839e36a4f5544c3e181e8c2e293cd5754c8"
+ "6574ade6dfce0ab34a80b4d48a9d42e7115d8cbcb1fa28c8a26501db7d0bb496"
+ "d01dd69265a026e1a97e9d3a1a65a8aa8ec2df0634e6f2651ef43540",
+ "1ad77a007ca437abd0159ed4b0b6815416f9f09d1b1215fb7cff115297601a88"
+ "30f20917863563853ed78e9c3d7ba4c97a05cf19dd329248471a4703a465178b"
+ "85d4ecd542241298c2fecd413e23a70c8a5d47c20e31c2dabe3c82a954502727"
+ "49ae2ebb89985d00b63dedd9596d0516d12a78c374b7eddc7dcee8e4fdd16c1d"
+ "fabff7ffd4c1fd61ce04be8e4975c5cd71e2cb0e541b8461bb81fb28cce77365"
+ "3e8b16b28a8c207428895f28535587a5c99d46ba4df9ae085018513d69aba3f6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.10",
+ "042a3922aa871eea0d78422ce78566abbb5b08c2ddf1ee30cf",
+ "5ae85114b0027a23c72bdb46ae7bb887bec5bad7a9884e93f6f4fd0bc938bc72"
+ "410cce96a14f4de199197735051efcdcc196f3adbfaa063cb3f7a234c6cf99d7"
+ "0fbb7e35b6aec66414669391e3cbe721ec991a1e5dfbb038f270368593749b20"
+ "8d089aaee2ef35c3daf6238b5fe42d13dde407df14f2d618c979c97d2de02933"
+ "b57fe8812204862b2f1dee983f24c2c596ea668e637d0a6ae6dc5265276994e7"
+ "e4f02b6e",
+ "1244de880e0f7852e996959d762fcad91565a4d0ad3bc52750d4a0440f0b5c65"
+ "1aa0e6f492061b2c8624c52ede6858fa2518ae8e8b116558b2c8076c17ae783d"
+ "8db25f0d8fb1f2758a82ab971fa7283ef0749a37be2893f89437fb8ea90072b5"
+ "855a2608fc542f5d2e0cb543f4fac528f94352d01640fc2c531b79810c00777b"
+ "c9e10dd9ea9996e74087fadcb71aa14300676571614882943f4a561412c05467"
+ "dca66ca49f8229351823db8a6b9f803d709c1187ed7410cf910015595ceab63e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.11",
+ "f31d3d0c30fd65d7b98b709944782e20525ca7c1f42d5d03a0f6d2759df1919e"
+ "ea82f80f1000fd5cf859df59871bac82dd9076cf",
+ "044bc377e8589fa5af1c17347d50e0cbbf901576f241de690c8816c129cd9f2f"
+ "b0831a017bec30b82b68f698311af6e07772bcd898fa0c27f62afde895897784"
+ "4625552d9bcb5a81aa3d7415b242a03b12fc1d3fe2d2ce6e5f71c4a4a4c7ca83"
+ "e0656f5002ac36d8d02b69ae65734498f131952cea481fa2c2965b6ef0517ede"
+ "50ddb09b3ea7026d06",
+ "86f66f0c250585065943de2f711fae4ff262700e0d3306a24c9430f87cfd93de"
+ "f4c3447cc7210fd94a143362f4f945c6dbe280bdef5d14f75eb7bb31320bcbd0"
+ "d88f0ccf2c95a74cb458c6272b58bf743093c4bba2d7bee9ea2dd30cf72fe293"
+ "c90c97430a047b17266391c51f5c398ba3df8cb74ba3e372f9555ccc97d6db76"
+ "14ea06d5c48c1c6006133d0e9d6995799385920ad8afc3deadf631cecc559caf"
+ "f495b08d683fb22aa697d71c696e46b1bf4fd76b8d0b39f179bf66841bbb9707"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.12",
+ "6a3555579dad03943543ff74e1747c257a83d35294c2539383e235de69",
+ "5d92434edbd4f5bd27197171f853ceb726303083ad4567a1d7c6104d192b9bcc"
+ "dfd0daeda274e5cdfb3d0c5d19c9682581ec7adc1a87e08151415d5a9adc1af4"
+ "50b1ba88d0ef32ac2d1f8ae345952814753af38e12635cff8c092159b4e75dee"
+ "a1983ed3d2d9ec2fe7b9a2e16a141e818b84cd9b71c129a8b3c6db620232dc03"
+ "a2401f731ff8a63da458a7d878905625aee1fc094dfb07b4575a7f0aad233e82",
+ "9310272d124bc5cdb721889840aa7715e767321700cb39b2b8a5a82ae3f02eb9"
+ "67e8db46843bc1bf62ed8bd2abe81434497f9900640253982d372b2bf7c1b09b"
+ "d5019674a834fbbdff3568a2824aed4a8048d2b861362775bd5f0d63b348363d"
+ "1378691f5dd1d7961074ed95fc9007bd5f5c2923c17c42904e2bf9d248779fdf"
+ "b203973841a11290c7e9e9356d4eab170e431bfe454a88010d9aff33700cee55"
+ "c704c82a7ffb15e253ef84f4019e12438f7c7386dc535b19ca86af71d477608e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.13",
+ "cb79af5aeafdf2bad21dfe62926642cba804ec7fd0ea5d5408ace9edff28e7e8"
+ "dfff6df383af144021460476c0c82c",
+ "5fcea257cfa92c84f0b8937d173faecf7503ab162e0baeef7e4c511f3e32a324"
+ "ed40e242a852ba57895b7cfe4d617961e036f663e0228a29cd1a95acac08a255"
+ "26d1ebff0ab3f033edbf1ae276a8d236736cc7af51b5d2bdc83dcc7d7d3bf5b8"
+ "22af2effed7efcb617e083e51be994aed6569b2383b941aee594c7b012e6751c"
+ "37b7a54e2a191824a130d55cf845",
+ "11fa819d3a638804eef1d9560a11f5230a0badfd66eb684e7d69dfa2898c8e0b"
+ "6e04af8efc7061081ec59e45857642e8b20041af508d9d4e288220f9fd389de8"
+ "b29124ce747eb68e2eaa8c8f6fb493f611ac09b723095d07eed924f6ab8e09ff"
+ "93c5516d1f0ebf62c5f022f5bb4f4cb5b8f5d487a17df7d012d704357abf1748"
+ "67ce40cdc55011b07139bea45ca0e581780de65417cc835ff26984fd0feba187"
+ "69c394a2e485023e31d3b0a888a7b14c781dd85bab408674f5f57e4b763d8435"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.14",
+ "d16233fc775c319f157aa200476cd6ed64a1ea",
+ "bb33b22b5f46794be83e6aff34a0e411d1f3f4b8daf9b5858724effdb969c955"
+ "25c62dc44bb2b083386003054bbd3666b78282606fe6ea172731bee11672d601"
+ "de32423d83f463cc2930f5fb79da1534c415c96582756594a999b226354248a0"
+ "9f141caecf88839078f77f40bd4851349c1fc75e1ece6fd6966bc9c9d5ec1209"
+ "6ed5043546859e4f957d3188e1d9060b59c1f7f62efbfe825dda45353e6fd4fa"
+ "bac983f944f4c2c79cbb",
+ "10c20c0c71b11bbece14c81483dcfa730c23d4dd61b8755b39949dfd4a3c5033"
+ "2160eec6f7710e09c7a97af93f7044b92f41d09fa3e6c6ce1f6411484ed47540"
+ "a1b59e23c19334b66d6820c2d44db0f6aaf85aa27f53a41f856bf6a591365986"
+ "9ba4abddecbe87413ac95be64009593b5ca2d0783a16f608665755245393fc14"
+ "4fe3ea5e9aac9f1f991a928538b46997d3063cc1a69adc192a40c76f92d47a05"
+ "80e3c02120023ece7032807b7c091343aa873f6a4ddde43fb2dcc379aeeef654"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.15",
+ "d2f3c2e6f43b0fc9fc2293b84588e66115",
+ "b9816489525cd026156fb4e8a4a8f34aea8a3aa1a634cccb3258918fe85cb8d4"
+ "aa02a52852a8941d3ea6c048b58cc6c75685675625e5e4dd7df93b8acec07967"
+ "0b49f3dc6e0763ed4c8e2d0ee9b5ca5bb62de006919838e4b69ba105d4c5a4cc"
+ "6dca67b12193a032b692739644cccf723f9f69e48b94c0bdce5aa35f75dc5392"
+ "7b81e342ce72c6b65cf75eaecac5fe0dea93885ba420af9932d84ca4b50e07e3"
+ "28ec5f816d2d8696b20df75f",
+ "80f1df25f36f314b982c9c8aafc0b8a1a2f174abb2980869c29d19be1d2d93b4"
+ "fb4299906c357fdd40e89a195492a9797661f05d3871d1bd0a5c45d8f9b0fee5"
+ "65b0004ff5afc5a6f89ad603e82283570bdb4c6e0cfc313e4e665a9434b32fcc"
+ "773d6edabce85fe7c80f03302a84e208b5bd0aad91ce62fb8c2bf54ba66f7e8d"
+ "002192162920a46e36dea5661fdd758153564074b8559f88936242fc0998148f"
+ "19eb50fc11fb24a7ed8c8349658fe9d31e6274d45d6f2b609bb5ccd17e284c99"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.16",
+ "21ee5812e3246dab9c3c259b2137d65f98a05e5740465ca22c69349700a42cbe"
+ "4ffb393fe28199339c51031cd3b22f2f0a83",
+ "e9de5bd355e6aff19fa11a2d0d3edc3f6469bd3c757206d66b3f09908ff618af"
+ "4801ac77b52cde03d4ae749d02155e5c70fc995f487672d280635855db4b64a2"
+ "2609b0c16067163c519042057cb36712c7c2fefed11f73c28bdb9d25f0636a4c"
+ "aa11269e5fe65a2b175686a15f1e48d28d345dd9a1b2900a24f9ddda3df3a69f"
+ "fb9cf5045ac4a193ae902f",
+ "7d8c531d4d3549e0bd2ee162b682539da61722b88ecf8c7df6d6b81fef5018bc"
+ "4ea10a7e1a4eaa0215d9b3cdf41347929eac2748ebd779945c9bc461dc51f48d"
+ "f6527553f07037e533ceb1348a46a7ea797d85a26a9f44c58869996ef11469bc"
+ "c10b756c02d5c0e61883685cc37d758dfde4c9b7354e3b4f316ca7f7fde659c3"
+ "fd5e332e1b6392a2929e131766ce9ba1d971ad246f3df0224338638bb653458c"
+ "d4b526d961744dafecd5998ad72aed3c34599f7a4098e3d2df9d13a21ce2370c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.17",
+ "a034a6c166cf0b25d2dde53af4b833b478c6b0d2fb0cef137fbf5c2712706491"
+ "237f7b286d1211d57310f8a762b1b3bfe19c9a4b16d3e0a8",
+ "d84417972287130a24a606f583297ac911528adcdbbd7de14a5b489b6786f9f6"
+ "f7e0b73bab538eb6c45ff34bd5dc43eae8d8c43f716516a60da247536f634be0"
+ "65d94e7f92adf52a967ee05fd9afd732333f99ad058297b28f8ec6feff802844"
+ "a0097df91a97702c483aa1c7892c7d43b6b91cd4d85d3ed2f1e955395706c3b3"
+ "39baf2a0e0",
+ "904e040723ab9788a5ed0352eb96c7f3d707cf0dbc258c51dcf6243406f0c742"
+ "c6cdf20767132c095e6c82a5025be7b4134d8fa4de187f8ecf12fdd3beabdb06"
+ "158aef46c3fed2d1833406eca7a69eb2d208a2f6f440d54f6be5dd564709eda8"
+ "12ac0629a94c7f8aee78beaf9e9378c8dd9c620374bbaca3941859dd702f6f7b"
+ "25a238459ee89759de9422b5bb6d2857166ca2120e634774a0d1d42eb8d94815"
+ "a1044bea8bfb02da5862cd9a745f1592478c6f57bfd13a5fdf4b8faae8a4bfc4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.18",
+ "8fc6394cd6e17533d1ff8ebbf3e1aeaea330ed9f5a6e1efb83454294c6ce24f6"
+ "904a0e",
+ "be1c1802db44682e58c61fe38757ea0e384ebadd7959484b38bb235755c46177"
+ "e671769f36573d7cb0ee7e82087b584b58bb3005303368c6590ad9f2882cfa74"
+ "0d51dc55eb0c790f5bb6b6a3bd71f8b2146bb9e8034c35b7cabcbe10936ffc5f"
+ "0a8d7b30476ab91685aed8fa958e73c1eea3044c56b4b870da89371a93b89652"
+ "79b55bb92cc316c23ef0975351c749817db5dcd86b94adf603bd",
+ "b83c718ce5c6ab1e40ffa5670ac166664d3a6833cb3bdef462794a25d53e1704"
+ "6006858e63f88ab95d04f4fb6774f7005dbb2e22d519360d5e1338ad15308f6c"
+ "6412549567007e021cb237ed4af5eef3bcf9b731599f7253ceba8304f4ee8c34"
+ "3339d0a064eb77f1e93fd1cc7ba5fc3bb8184ced0e8697ac47b74620c494eab5"
+ "86ed9fe76e07e4bd2a2d1b95595b69c64677a8835d56ac639df8f643241b3e2c"
+ "4688d2adf228de2da9bb0a363438e751b5250deae305a3905e7e077a4e8c7466"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.19",
+ "89a12d22bf877d440a2e03aea932eb5183379b3c8b90bee8fed6fc6dafb0cf05"
+ "27",
+ "6072895e4780c8f77e0b195fc9f5db7833f7b6f5c81c1d30cbe9e80ccb386606"
+ "9f8db6963ad46d52942a5a73f6a327a94ed119dfce4c3765843713b619f9c438"
+ "3203d55e2ab61da8961a81037f1118a78297eb366a1c51d9f9466b715bb62999"
+ "e0a9d6e02501d47f97db409e3886e1366c3eff2ba790e26243227aa1588082bc"
+ "e6d5cde3ea7efbf15c6c7dfa545472fa9e93956a4551d5a77ca00e26",
+ "b7acbbcff0fa9fca6f0bbde5a2f0a1e6a0abadb32c89e317255bd18d12e1a60b"
+ "3e002c1d69356448329a49b5bd241910fa0ce03b3e68a590507599391ed15397"
+ "92293fef13174dacea6d2a05b39f684828a5d6d217f84b782c8fc9843caf6aeb"
+ "178f0e2c6bd2a0e6f7b809296117cc8a6bf73735846424adeba1ab31145fca3b"
+ "8af768c9d0a28e09d58ad496423108f08caac174acd1f3ac43486961c5c90e1e"
+ "fb89bddb7bb39f4ca3af5712f553af594cd5d364132914261007aa1d5f216b8e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.20",
+ "09d6948ce1c1f24c6d529cbc5d6d6c1beaab5695b30caab744969bf7f9dbd283"
+ "335e98a9bcd65dad2b4f0e3cec890b05e67fe97823d4",
+ "eded62a650f7de3b1280229d5fb1c4408e82dfe0317e6430fcf471b1e28da8cf"
+ "6b4bf4c5d031e3ee688b640772aa5008e5863c707a4022c329a6664e71101206"
+ "b54db5406e7fa9c8226f42931119620ca30de7d03be143940cbb4d1a9c86e986"
+ "3c987bff07023de19864f733da0c89bd039f19f4d8ed616f7c6e9494185b604a"
+ "1a7bf7490fd0d8",
+ "7addb05cbf0b17aa508a0b170c4c5aee84ce06650d08c9966d95d3071a9a8f3a"
+ "93f96a875399b478c256d0415e74849598211f9f9d0b89367baaaf174b7f13d8"
+ "490baaa740961f52d7e353c504818a000b03674d9ce493dc3a4ee9161301f61d"
+ "e521aef3f6d41d82e1c5dce02e636e7740a183f8023ad2614941d9b161cdbdf4"
+ "8f8a562c8ffe44f57a746f2639e5e83bcfd392d23e1fb4a8d85e3ba5e1cb9c0e"
+ "53f0d91b01cec0f0ef9dfe3f2b3065bd55b72fb17060abe8830aca004464fe7d"
+ }
+ }
+ },
+ {
+ "A 2048-bit RSA key pair",
+ "dcfa10ffa74665aeef870974ea99b2ce54547c67f42aaa6dd01a2ed31fd2c242"
+ "af5d960b1f896efba3543d6554b7b12687a5c688568f32e026c532d25993b97a"
+ "7c2842ec2b8e1235eee2414d25806c6fbae438954eba9d2755dffeeb1b477009"
+ "57815a8a233f97b1a2c714b3e2be2e42d8be30b1961582ea9948910e0c797c50"
+ "fc4bb455f0fc45e5e34e6396ac5b2d46239365c7f3daaf0909400d61cf9e0ca8"
+ "083eaf335a6fceb6863c1cc0cf5a171aff35d97ecb60ef251c7ec2c8a588361d"
+ "c41266a4b7ed38b026ce0d53786449dbb11a06ea33ccf1eca575201ed1aa473e"
+ "d1187ec1d8a744ea345bed7ea00ee4e81bba4648601dd537dc91015d31f0c2c1",
+ "010001",
+ "21950851cdf25320318b305afa0f371f07ae5a44b314ebd729f5dcb15da7fa39"
+ "47acdd915daed574bd16df88bf85f61060b387172fae6e01262b3864c2d3c22f"
+ "94e04a8159422b4ed279c48a4c9d767d4966071a5bbf5d043e16ff46ec1ba071"
+ "6f00bbc97bff5d5693e214e99c9721f12b3ec6282ae2a485721b96ddcf7403fa"
+ "037d0c57ab463c448de5cc12265add886d311ea8d8a5903fa56c5f1c9cf2eb11"
+ "cb657a1a7d3e41352dc3e686898c4ce4305e8b638e1b08a2a86cc9eb9866f349"
+ "9ac77b6136b81cb276d614cfeb7b6ed3f3bc775e46c00066ebeee2cff7166b57"
+ "520598947ff6210320b288fb4f2c3f8fe97b279414ebf7203000a19fc0424875",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 15.1",
+ "2aacec86f423dd925ec158822a748cbe6c31a0",
+ "cc4b87f674497bb0e33d9e2a4a8070b7d78b5fd2c4b4f6ebaccd4ee505b71fca"
+ "fe2156337ddf27b475af33f6c3405b8e3c0c206ec2812922fcd8a3661b8619bb"
+ "c182f807f3a1072e62ca2bf1fa8b944e58a0e203dbb753f9f1b6ef627ebee598"
+ "967b387a5f9636d8b641b38984b1ca037e3aaeaa1710f51625ea85f8fb9a6e02"
+ "9e64575814d530fc146b3445ac4201b4e408adf655f67843d8871cace5d906d7"
+ "fc038fea885b96fb8eb1a721c6c14abbeb78fb4c798a19589959898455a31684"
+ "3c6cd99ef58c2b0b49b8ab4191b402a54c9297310cd224b17f214167725c48fc"
+ "c61bc47cfaccf15eb3b0",
+ "6042e745589af03af87520f93c45d8c35985ada1161a37d822e9f9460fc75fcf"
+ "0179d8491b8f5d1e4de8ceb31e07c4865c5a3efdbbb69a8803b89ee65a430a58"
+ "09c707569150b580bb686a94c5541c46adcd827960ce244ff688387d1616e85b"
+ "4d1780c6483606cf924b54f080cf4154e66829bf6e532481048ec41fadc07d75"
+ "5bb34bb28145219cb30d47d0d618709180e90303ff9ef09018bed3da75761da7"
+ "94811f96bc9e8d7c4ba1b5946bda0bd313faec4c993ed2748eed8cce4bdb520b"
+ "a7db165f9fe56aa8454d6ff33874feeebf29de2df5b7f00aa1d9fb073fc4067b"
+ "58dc50624e127f711dde2cc2cfdab4919ccf28c83660dfc227b0f500ec1f904f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.2",
+ "5c8bf2acab08bffefa6480952b24daa5019d125fee",
+ "5e163070efddb79f4764f8a81d44460b5c400bec7037522920f772959fd4cf3a"
+ "ef2f14454dcd9e862512ca69db8368a4cd8d1a44da595d6b439391c93146b123"
+ "f186083c4b6447bf7e20815146ac7549efb67460e8ff1b2bba5c95a51ef813d5"
+ "dc4e6c3892bc4f439c99117ed06c14a6c540fd4c65d195d8c61ea7796838e5a5"
+ "dfaf11d0713c191e8a0b8080f7a77e703ab36622f1c648b765435b9027971811"
+ "b1152d972fb76aa89205033d9578187ae63488fda3c86b2f28e779ac4c89cd25"
+ "2017d1a9958a52c5b87ec1bf9cbdf7de0e97c58ba11ba3a33705f3f499589a3a"
+ "72e2c0fc5b16fca2",
+ "44e671e03bb66780ec0586d56f8f6a49415ad4bbce226d75d70f06ce29deea7d"
+ "a1afa8287e44363c510f34eb8bf31ca2472959269c18df0936ff12c6166f4f45"
+ "96cb1caec41deda8c50999bf4c944d21375b36753191b4cb7caa1b43e9116cbf"
+ "1da8b201d297a4d08bb0e5bdc8953270f7c2809678c44bea75e81fac22d27106"
+ "302bb69da074b6efa6688cf835c80bf5e4553528ece0b7c1b77b666ea34523ec"
+ "1fcb3e25054e0bb8e4ba027e5c21bf7a5143bf041ce9ccbcfafa878082fe41f7"
+ "8c70bf4e53cf487c1aadb01915cedde8cd9fb84efd981ac98cd57a8256d4e9e2"
+ "d0862dab0454d3ff4fb985264a46995ab068a74edc7ed8aeff5fa30f3a7d7594"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.3",
+ "e2004b310739982cfa9e95453a",
+ "e93e6412337ab7b0f1b569801a3c164a6f23e3c27c7c55a8c5ac9eaf318855f8"
+ "328b5d7ab4cb8619a00e9941ccaa948570527182617443c1d21e4a6e21b3f6d4"
+ "f698a61ae029172cf4da039d91585a87dad128c2fac5531b2f45dcef9b9fc331"
+ "c804488528847c90875d19075fffb005763d88e08147669228a9aad01625bc61"
+ "112cc7b772f321d433d4f26978209d0e79676af3b8a74b973f52ab919085f352"
+ "355f856aa40ffabce543d4e76d454892989cb383f3e66bbb0e8feebff7c6a54e"
+ "f2625fc4050e6f87a323132a4e671268fb83cff2d82251b79cbe32daa8e55320"
+ "2fe8872261f60d5bb511f2fa2f1421a3",
+ "2bbf6b0c5cf20ef2f6c5a0aa48454f850aa5f6bbeb030db4e2bec11fb200f01e"
+ "4eaef044d8143333338e5e66380087660ed0173a76821285677e371f28ec4500"
+ "f4d59fabab2073e734365fc6b094ee0adbceaccfe24988ce615d605fc3408c03"
+ "be221c993f61aa724fc8714a8a4a1815f9e9a99882aa46883e70474e3329b991"
+ "e6d53dc6b500861992343a6da89a8bd6f37f34e5deeef80e7d56b93a45176066"
+ "3650fa455d5541899a76aad1c6275ec82c4607122659b508cb5dc026acf93fa0"
+ "1a5fca3d81c1bb20a5a5cf357a23c95688ea42eb1ef2c9d46ae37f8cbe615c20"
+ "84d989b892f0167b23be3362face808d6a5eb896194408db7c01639c5862304c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.4",
+ "db6af1292305278c5b3383f8a41d6c83522114c988855074065b23f9feae8ea4"
+ "31fd5da36f9babf9dc61df2e39234783047338ec4f",
+ "cb851fb276a7491cd3efe4d3395016c1ec2b15094a1ec6d930d4ca21b420f847"
+ "ff6868f014d209ff807e8b1f71670b325094c0f6e32f84f768222202b21be36a"
+ "286b30e082ef3bba647cebeeafe310694418d70a679eb2010780dd0e96553c43"
+ "cbc6d00eac22aa71f24821c4d6c1778e786cd8c7bf2cbbf214e203e2ef2f3335"
+ "78cf1a947e27e59996290cbcd6ca3f8f96ba67e0e34130cfdf86ef48e67c90b8"
+ "b72e6f4255017da2d1f3aedd7fb1d9de42efc037abe6616ebda8d0b40bd780cb"
+ "db68ce54318fdafd",
+ "c99a9ab67cad0c41ec847bc27467fdf5bf61ed6d04c65f7d9dd8bb7007a8a9b8"
+ "3a3c38a9cb925e3e7b3c407d64669315b35449e75428ae961914b0b91023e783"
+ "191f9541b67865971c95b0be18931eb1c847c26a2983c0584eb217c99c705f5a"
+ "d8cbb09f99b06bdf7bd12628ae3667c12c7227d96ff9c108dce3225106f62f9a"
+ "4a3a8117a992f288c3b5979109878fcd59c6796b1998482ea82f301c939183b2"
+ "dd47880448678acba12d7bc8a552eb327634e92d0cdcf71effb666ad902d9e26"
+ "ad1860e29281d02fb0c5493bf74ac02c9440436e0d75322892777d325ec8452d"
+ "e758cc6a5cbb02d341f45c9ac8edf150dad71582dc77958a8544b0b558ee2a0b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.5",
+ "e799e4ebc869319ee22580",
+ "3a0757cb49a3fe6ae80d3742068b5c8068b8c5885420011093c22099edaadb49"
+ "1f226f856066163ab5105e7879c7491c1835985dc494210ef78bad4816d9b694"
+ "c9c8be466a4d178a7ddecbce5365400d6821b6e9ae0e03bb69adc4ec734afdcd"
+ "ea6dc0c48596c48b2735ef70f3734c186d0318378d2bf8099688672fa38591da"
+ "4ae6fc112b727ec81984df7b56c9844e25b0fcd81d2be7d18d01646a6d9fe225"
+ "d3697c34ed2e336cc0373daa28d882e497757b0a6510862eac10d3b24adb252f"
+ "30d434e30a6376469d80b95711161778df35889b3acfb1f653ea63072f35a3c8"
+ "9f6ba52afbbdc28f23d38f4d4e79fc397c10",
+ "3a3e725c6e4bb0061269618cbb8a6267d95583abaa03d8df85a4f6a5cc359bf1"
+ "15260ddb70ae7c66bb8d87d6331ff1b0b54be5648e83e83a91c54cf371496ee5"
+ "ca0273b19f700370c2c8cdf4281338a6e72f66324168ea8cdbc64c609ba96791"
+ "c791b5ac8400992a8c66fb09f4e313074912af0cb7415fb215eb97faebbef1a4"
+ "47239a91db4a34fca4d84346259ee0a1dadd10b7f01fc8c53e420f88cdfa0cbc"
+ "f62be44b8a7940864ff8137edb122ac2dae5410a47cf0762e20f2086cbf66ff4"
+ "d1a9f7270f009cb2e07d9020b48a76d24108e9989bf904e4a71ddb91740ad7e5"
+ "d1b68ec64e3e66cd0e897dcc665739ebac451993f02cc5bfc63a602f558381da"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.6",
+ "099712b826ba67cf929225bd612ec065d451ede231c8d5c20404d470e79a7a1f"
+ "246e3eecdcc75f085329f8f17b81d130300fc3b9f093a2",
+ "81cd64c84d7765fc60e4de3ba9b4dd21ddfb74fe2dfb7cf619dba4cbcc176ed9"
+ "4e6f37ed1a97e3bfd36365d2644d3b6ee6c77109fa18412ee7cddd3be8d4bdee"
+ "94c096f072cab6f1886e3a84a7fdb5aff3dd83f7e5c5b49bb1b38f8faa752531"
+ "d89c88393e9eb8f57edc5b9fe6ed2bc95d272ca995f7e259b00832d98b872312"
+ "cbef8a048f6eb7919784aed3d31eb4b12fd80760a134c9d6c334c2dd3dfdf497"
+ "5cf1b51e87122b973333449608ffbb2cf30a02bc46ea247b4539b18607bd47d3"
+ "cdf0877214ba",
+ "786b3f599d1b743e23582624fa2c94a36fb6bd33fddd576408cc854ad7cf667f"
+ "17380af20b0b730c6be98c018076b9b5041daf2eeb025469300aa4364335be26"
+ "7d33b06b4a7a797a3c0aa5fd3f916a55dc274c0a2487f125f9da82596f434c7f"
+ "bac7ece2ef6c83e0348bf4f2c083050755b56a9c6347f39c76b0e0eedc615410"
+ "25c23aa1855c0b22b446fe1ec5f1112c5a7fc285efdc8420ec01a3a7c33f735b"
+ "4555092a9e8de16f3f7d469f88cd75c01c7f2e7d546a1b9e7f4984fa29a2cc80"
+ "d310f9d7818df6d9ad6cc205374d52e8e17390bde72f25b712a4269f23aeb241"
+ "a666e96496cd84b833fb53d0571f7ac2d1964b8f2a7e13336d9a7e03041dcfcb"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.7",
+ "5f2a5c7f93e714eecab3a55a69c79a3cbc15bd19df27989a9bab59fbbea9ffcc"
+ "663bf8e1e7407dc273",
+ "e01960826d1a69f684c9c0b85d84dca5811c89a2c0742f33a2ad199fb657a1aa"
+ "9813601d29936a43d9b9eb4d3289cd7d3706ab86b4d66adaa7e0a13451b2edb2"
+ "bc771091110cdadd7ee2e6aaea2b35cfae4ce3b1da1816684c89c0b3fb2f8779"
+ "b25ce0c12d42b1d3d30b8f20beb899916e4fd0a1588637192e0528ce6ea54c8e"
+ "b754fd7ff0032581a9505998e69e14f072bf95dfeff014df99ed7853b982e889"
+ "4129a1d27c53eaaa234c8d14a7ffc5f5e2187cef79ebf52b3d6c0665895bfb87"
+ "e4bd610e358f3526da0592c9e502b72b76e46566",
+ "77d907181cc3b1bb1981e8cb22f7ad75f882e26afd281b64db70c84c6a50fe74"
+ "249e22fbee90e30d0b70ae2f7e12acddf678f00d227e5361542662430269feea"
+ "34124792afb3f87b30f950f4edf22c4404c9688dec38ea0b99cb3dc384bd88fa"
+ "3183d7e07a2054d73ea51d4286bb39dae3ae6d0b9651f1ea488f805f2a216ea2"
+ "1a5676b97d1b11d3b4036ce167fef64e0eba419af673983fc6ee01c637b164e5"
+ "aaacc99adee9f47d219254696c8fceec6c74ac4e39051e15269401738264f0ca"
+ "5bf122c55c9e5dd847b1d5774e7408c3684aa974b0baaf40edc22a0357af72c8"
+ "16cf731fcb63965360699f269997b8480f30a6b5d57e12a5cc54ec0c805fdcf6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.8",
+ "556139593eee8b6e87",
+ "2de2a57224f5f5b12e223eb5f82b9f47249d25559379136eaf18e2f6c833e3f0"
+ "1bdeea9c303bd9677c2a85717d593a2802aecbc6b3b71f2c7903ff690e3f3c49"
+ "57dd74cc9c2a68dc1d319c1e1787bbb7f0e6e51e39a5badbba9fd46766197431"
+ "2b557af18952549f6eba9df49f70eab3689f9fa8fbea1c97e1bb2f093e6aca9c"
+ "380edc546a19c44f91f6dcaa289bd114fea1b036f99b1a57f86143d8675bd07d"
+ "4deabc9d510c617099449ccced5c4507b79e851efeb18d06b199810bb6b3cbe4"
+ "1273baa7351602e5f95213f96955ad5fdd3a2052dbc75fcf60aa2247f2d4e603"
+ "da45370de1c1da687e268ee44667f94dad13bc9b",
+ "4ace54a752f556e36eabb11948958412140c80c31b61dc40f81a6b1217a01ce0"
+ "67ab37f53df4c77d9ea9c2d7950c8cd49700b8cd24d4e78f7fa3462962cbfde6"
+ "d02fb0e5036564932505ae1c851aa6d1d84efd04d578ad68273a36a8ae23d145"
+ "2f94a9378817713e764a0917452629b5dc75b57b0d5e6a728c83691172d2cd95"
+ "f8bad07db468ebf545b7f3f2c863b6e20c67c4769ded0391a336f3a5d87e24fc"
+ "f91aaf774bee77a789a5908009c7a55eac92af4c3d461e7b40616ce806194bfc"
+ "2074c3f4f13559700b2708a0b755789670a3626a14638811bb18e15b1025c3b9"
+ "bef111176bc1f2469ea99aad20860573d6c6a1fe40db51e36fe33800101bda20"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.9",
+ "9a1396622d066c10560858c2c4cd5c04449e2b9550c5bc9293761a9104411da1"
+ "8a57d9b6a997333cdbce77e9fdbe6bb831",
+ "f17861acffb24caced90ba38aa7ea0f2e54eeaa62ae66498f3c28f996bcee253"
+ "bee8199e3eb80d627feeb6e0b39490edf76d16a2a0bc20093252a9d7f1f9388b"
+ "061944852afbe73ce413a3fca521b9474e678129464d91b82bcaa59f56ecfb12"
+ "4f61f50467130105b2cbc6943b953695cfcd20c9b6ef53f3f210331d3932dc01"
+ "0c735929096b2e68ff16664b0b90a0fa1be460578592b0cb4d6ca45ea06bde3e"
+ "8a1ebfef70d83ef79b3a74db060fc0203b74807f407001f4b4d99ec5158e8e7e"
+ "4b102a515de95d2b70fe1fb4",
+ "100ece634525d467f6d4a6b66ede1cc237f61fb2b67023a83dc456b92cda183e"
+ "d6620fe57d5a67332c77233ac1e8725b36f8e1b108412ca6fb35dcd4d81677a2"
+ "b30d5eaf25e0b9191b38f7eef83f9121a808438c92ab03f520807bc9a894705e"
+ "af4eed066823a67aa2a5599cd95e58da7c094836d2afeba39dd009a64ade0305"
+ "3376f02936cf3f56bf64c1f3bdc07c45a95b9fcd9396cd9a8d41bcc56424937a"
+ "1371b3847c905b9ab58402393d4046e4a015c14708f74ce7790eba8af7920724"
+ "40bcafb14c0f8108971187c80f463a1fff258646ea16e51c6ee361b661a14f07"
+ "cd4f5a82c709f494f1df0f803b6f64a72fb9c450ffe268fcab487d4d63013e41"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.10",
+ "b3824fb545a83f82ef8223118284c5456bab600adf79f50733b6668fbc515da5"
+ "963162a6d7d7e96ff91aff12eb3e9311e221e70bc0",
+ "b8268e4bce7e53f2e8be98b192d63ad06544a80d6e62d632486e15e575ba706e"
+ "3e768930dc8e411f8eeb0b6e8f060629da8a242368e479ccb331697070b4b352"
+ "4e69169276bab0a94514ccd660702528ed20b5d1df07779a62c65686e7d66846"
+ "6ffc748eb34344ca6f305cda3dc3e8f01c43ea9179da462147f4d3ec92f888b7"
+ "eeaa410e12c86d8942c7d012f45c61ffa6e2b78f843e9a75d9673214d558caf0"
+ "1b45f93686eeda5479db8052792559cc236a4a1ee65d3ca60e09a3c184d4b395"
+ "d70b8ef88d78091a",
+ "c0e98d50894ada849fce8983f6f89574034d6cf3b8352bfc50724a703dd4f42f"
+ "4006ae008ad97233cef6f16ce1b423f52c6b677ef005131ba987f98c722faa49"
+ "42ecce2c99663740a1a1e98120faed97fd03ff36fe73758e70df17f31f1f3941"
+ "812d34cae6c39de787ef5704bc39c920ea5b0eb1833e83b45794fde0ff0005c6"
+ "2733c70a296ca0bd47f065503ddce2d649de1c328ddf6032a33fad46ba041dc0"
+ "a994bf0f56a465f1625fcb81ce01fa299fc2b3c80939ebe6a673826e2b2f12ec"
+ "dda5035c9509312dd19f10c35c8a8b0da63c085197006a9be236108eb98791b2"
+ "6e2808b5ccd5acec738bca025b24182ef4ab9cccb171a69fb423a46e037a4d0a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.11",
+ "a3a7da1bedb2ca99fcdeb7a46d633eca35062df2896b695907a7f971d2cc50b6"
+ "e3d2a367d16e727f5697c0",
+ "f018a9b13fbe560bfe9552ed8a8606beea90055ed3f62bb2af07f692cb60acfb"
+ "6d5907d60e0a597a54caeaf844911cdc874faf956953a27d300e9b715b104df3"
+ "c232c3c96382cf5b5f3d07b230b525bb330e319d1a7c82d153af817ef11cf72e"
+ "76dd50b0d7e5562265c8345da829f560d6a54e6f1e288a3dc2176d19a68a0b1c"
+ "5c92b16b8bb29e4d01dfbd0b18079bd40cfcd52335b3a18bc4ee9244760eb494"
+ "f5be5b1971886ca2beece0a3944fff8be6b42d96e1c2c72e4e90f87ed1361546"
+ "7cfc91c26eb38a7af9f56686931a4726da04",
+ "25177bfe12619b44f4a4fe7cb76de93d4ed4a05a31e5be8cc4e560661de9a34a"
+ "e317cc02ff63106708328bd3f78763ab3e57652c63f105f7971d2d8d701e6297"
+ "a79c787b7ccd62a53b39d9c03946e66f488a92e8e17dc6ecb0f65bf01e3affee"
+ "997687311be0e945add63fa3f400382cb8ffd8915754018cc75e828226b5039c"
+ "d9c57fc6d99cbe8ea4a3d29cbd09d54d95cc0734c23544f8e1fbc7493e06d16c"
+ "0a0ac1530d21f0337e262fd9d27fcc4afeb574d66866d4ca84cfd6e0af2bb977"
+ "a5d99a5b0b3744042d332b936bbdd869e5f2c883b400ac8bc0683e679063429d"
+ "98d494f31804d65bb3c974aa72e6657d4c1638c679c81a16453f6b0baa3f0517"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.12",
+ "49f6f8a4a86a8aa09763aac85572b0e7ee776aeff8a829000776ffa6",
+ "6db6a827ac2a5e0616c0f443b23458e175acf9a3b255f5c8525e7253424faa91"
+ "38054c3dbaa471f27fe855c1c0cec362597a1a1e6eb4f298ac3eb734d31ff0ef"
+ "1008c0e02b9b06e29315fc094a7ed26b11ea55270a3dcb6706f46a9450bf8312"
+ "881065130248d2644766a79966efdadbaaf575ef4dd35a937ff0bfbf3d9561c7"
+ "54409be7b8847a608d791fb987eed46afeb0db1ca975c05f61570dd070985f13"
+ "e4e0ed7a8cb391ce4d420832b45a8b7e9f90884e611898f472a0ac46c57aa7f8"
+ "468aa19d9c7b312f134322990393881d32aa1468f6e5f8eb85a2c3c2daed92b9"
+ "3c",
+ "0ff95f4a2a0718d673f9202c809f1045101f52b9dba77288fe288cb277c4dbaa"
+ "35db9327eceec3765ae033e0b6b777b22ca6be662003eafa2bfbda606fd8cee7"
+ "eee06c6a00c945a6556c60b00869f999971a8c57afe1ddee7a7577047a0db90f"
+ "62cd247a887f3227ef6da907a75bcff19aa30c908f5835ef10100adc7f6ad6fb"
+ "3199790b3f4d6ad19a0df5027fdb8f846604e02daf3355d956407779af155acf"
+ "a5a32e6d6174dc90131dbd7abe585dd759fa3cb7e9f721453f3e354fe7be0b11"
+ "8ef5b87942b5fed4c30d7a08fe2464eb79a3debab37b6d3a0ab31577de7e9322"
+ "9b49d1e8fd5632d026d83ee06aa78534cee3081b222ec4cd9488ccde4e152905"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.13",
+ "12975db73d",
+ "6a4b4fb805807272965bff2f4c800f964fa3aeb9fb433b40c8acc598b4840298"
+ "93a219c9532134c06ac8425c28a5f063c284200a045643489716516a987bf81b"
+ "a186f4ceb8d8d9dc1d73f2267fd1988d6a2ffd68cd3669de2b04700943d0d444"
+ "ae3da8f0594e6261e5fff607f04df31e3d9c9122d76fb90f3f82c393253b7520"
+ "165bd1f319ab3b875ecc6ab3ed0247d03770f8d6471d69cd13ee257c1fc8b30f"
+ "19b93fe4f2fc9c21492813d1fc852af70cdc6384d2ae55b91e39ae6c3b19fd1a"
+ "7deaf718c05d57809596a288fc9aefb815aea29faf6783c00535fd71d6254940"
+ "b762f507261f209bc8ba9479bb3f5d64642319cc3186859c",
+ "2715d6eb53aee6d4bddd3be9b663144a410d0381779f799dca880792ab431af9"
+ "989deb17369dc67438add82bdf0a59dd3bc278010258c7df876984ff527678bf"
+ "9b34c07743b5d22f4f30cb5d7d8a6cfd505824f2e094024fb04330f66da7cbc0"
+ "1d5ecc8dfca1ca9e5091b9d9c8e38d0ac3931de5d1fdc833738482a7fd152c1d"
+ "24e69ea01dd3e1fa772354a607d62c60b561dc5ccb012b712f5c2da1892c3120"
+ "ef990d74611ddd3566af1acd8b4850061c9128f82ad112da9f68ac88393f9a5c"
+ "2c1020aa77e9b62e2d1e985fef864cc1aeb451ac839c720cb973e7b5df24a98c"
+ "cb6e67726629a366fea3f9a9521daa19b04430e810f2c45a57d4253bedb91da0"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.14",
+ "8de0f5a413a7f786396f09a45e5e774f3c609ce6f1b490dde222b322d5340e9b"
+ "105581f4c5be44eabb3d1b23f845",
+ "f871a897aee845c3bb826990b731d2777cf476b5cfc5596df3a523ba6979c7a4"
+ "5179da5fd60f810bf414c54e182f2601720ffe8a50d7d9d11e564318e9026f07"
+ "c5aaa13ef891283a9663c1e3d27b93817d01a56fce33d5169bfea62a8ee6c370"
+ "a3aa8c7194d9d353d0981661fe85816250e0324eae1b847fc732919160d01e11"
+ "92ac16be0eb8e995e48640276a2db7b87f84b3fac04ce862f02238623f62b92a"
+ "2e327b01b8c7b9e5ec87055c6cb7b55651ab5ac989833b034f8be0116f28b1e8"
+ "86a2ced123298eb004075a6b5b71b1",
+ "d367aca8d4f17414e9bf09ad811d78db0e850c45c8f9d7024475d3e56e3cbfbe"
+ "6ee8abbfd7745826417cc8ed52f54e00a92f817ef983e98d100a1f990db1e290"
+ "a8516d609bb32e502a77e11f76200b0025765e9bd2859ba94a696333a5ebe2eb"
+ "25ba9d19007f64360cc075cad7f09950e4b7afcbac36e6ecb017cf4a1f25a4d2"
+ "b951bb85e81cb2b4eb6f45cdd400d2ac4e2169896d941582449ce30f69c17cb4"
+ "49321f65e44df303878627621351f52e5a0752e3b5eb126361697f53cf246616"
+ "5c3fbd662b837580b76d459ff04497e5fe1b3cd18c4d58ffedabdd04a8c108d8"
+ "59b65298639c3af80cd94e2387a8694409ef9e0b78b6f467390be108579c9b2c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.15",
+ "9e78c82bfd0f23d391e7600164019aad28f59b14154404d9e966133c103fc37c",
+ "bb42247db240bacacbcbe8c68cb0f70e460a4973dae65699358fef8270d65c3d"
+ "0c455a379c563c597b28f4ffa070e0ec1ebb9ed427fe89abcd4793c422c33887"
+ "8c8b145b46c4f71378a0fd7d5053b86798bc02d93293fed847f18fe06159074a"
+ "c189d956232074db6ddcf9941a70f28b60e483395a2d210154b62abab8750f5a"
+ "ebf1acefe2056f5abd2f0e0ec494afa82fc59bb357f116a94ec1cd0603b52fe5"
+ "6d31a43b87aa637788c724cb6f88373c92f60711bf3f3594e23dee2fecedfe6f"
+ "5fc886e96aee7c746822e56cba7ebdaa2a9210ea8198e4c22de9298945",
+ "818dcbba98c346793c79d4bb785aa640191b05f8835ff73974443bce357a269d"
+ "44646e8c79102dce22923978a3941ebcb9904fc1bb1fb43f11275e71eb7a84d2"
+ "74be104b00af9225e2a4f7f5a048abb66cbab6525d1b115da8c0bb08deeaec7f"
+ "80eb6c39504dc4eb38154ce4b691b4069319b293c25dc30b8fb38bca153e2fa6"
+ "1b3376ddc3c53a579321d910a171fc42aaf17050ed6d311a7df5b9a5cf3a98fd"
+ "69aa85ac2346c16fa03b1e53d103d6f5a04b0d9d3f1883531e2f6341fd91bd63"
+ "a5aa993b6edb9992e5db17a7be555eafa3bbab32086e92b8b791066968e00f8a"
+ "177161440ce538579789c2912ebd7ad019be29376cadeec2992107c9db076049"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.16",
+ "6d7208b2ffb01ad2360c4609f3bad31579c8d4005cc960142e2b696b26e94f2d"
+ "99980bad384105b1899557af890525",
+ "72ae49971828ba5423ab963cdb18f4bdfdbc7473cf70fb77213441f1d446ae48"
+ "109303a260c091ab5199d964e62163c24657247173cb0511b9cbb163459c956f"
+ "9c0b1883b691b5e4eae04f0af24ea328c6de882cebc4f89a56373282d60af2ba"
+ "967e257ac401a37f9441c11f2e0e421b2d151eb243a97eae5aaa86cd38df43c2"
+ "6a1d6e3b12c13fa3597b85bbaa1309452c7e9b325d8c73fa799c575652737b92"
+ "a247d23c4c701240c53dcfe2ea697af61c072fa76bdb052a58c919e69ec57b39"
+ "a2a6c47d770ede6710fc7bdde601",
+ "4b56dcd304bdc7f0ccb70d2c586f5274601ee60536bb218061671350d6d3ae2e"
+ "284f07b5ed630179269413122b98376090f7a4a4f6434af73ac40c7af4b6d7a3"
+ "e314702ab9b85e08731da0d12ed3f0070b0d2095053b3f0d09d6c2cd8f98bade"
+ "d91148c35b7b33c543653ccc32d836f5f7f2ee39cabd0bd89dd9a4a94e912b4c"
+ "a97f1851d017451f6096acbf20a65ec5a29f08f8135c7318a2216d1b7d103795"
+ "c7ec8ee57a79280f9a844bd6ab7128820e1fb5e82554fec02a78aa8d3fd6a13e"
+ "0fad0ecee7ab611de4b0a0481f42b8d0b55cb8813d1ca6e2615cf5ae8ae86d0b"
+ "5d4695507549f7a37366a445fb55b7c4b6b58ea699dbe5ddc8193e2bf3d5b840"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.17",
+ "7deb6d404148232c4821634d3df9bc",
+ "e6f83c8c993e6015af430409684e627f3d9b84ad0555c6a6c09113a712472abb"
+ "36f61192326cf84082aabd1ec95f4d1a92d9107e30610c8d2759556d5d61475c"
+ "a3f3cbd949fac2203c423d56c27558e6118faa0f6f684ada13c3153f6d255338"
+ "bff734e95f60ad2919abf28815d3cc0b1efd385d0d4581b0ee8494f2bbe29959"
+ "91ac1ea81540cb7e885668e5a52eca9057ed9a1fb23fdf83b57551358c23cd43"
+ "ce0e7a33c72566b88fe59343f1872446d32c44b3990aa4db3ee593424c8e0946"
+ "d261e3270ef4076bb35df3c3c6da4bbe423f591b5c93ba56c5cf01d4f0a94096"
+ "7109d39b939df282532e5483108b",
+ "aa6e6e4af689264d61bfa8f5086d8279ddc2289c5541af453519c44b95eae6a1"
+ "5e7e7bd15fd31a4fad5f7c85905efca226930d67daf558b715b21f3628f61a3b"
+ "042c1a38f9af3ada82ec4488c8ade5f1da81e1a8ab90e1b312dcda835f9e925f"
+ "2e72463fa833a08b93253fdfe8cf4e5f3cfa91107719a6a9469acd7125ae67b2"
+ "bd75857c59be0abe984074e295478af2740e25894e56a6250ef7362194138103"
+ "743ca9544733d2505571bee00f178a2cfa38e1f8f22fb23930d6a75dd17c689a"
+ "476d8715318595108fcce895e3449eca97a7ddbae3e6d6f0e35e666d6fbd7878"
+ "48f8681337b1d4c5238b1c24de77a7e675e7aed8dc13dd9eb1068798517c0b6e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.18",
+ "031fc3a3eaa42b0d9f6d7dd5993d6189cbb2e0e96faa33d61f317b6b3c00",
+ "16ab6485cac0397114880e6f72bc1f1ef34ba27d1c433d77f3372b1fd5b21ba5"
+ "7a505cd8f35b75242cf1b76d381c68342401eeefc84253a2de1a1913e438773b"
+ "7bcb31cbab258f726ac934a87126969adb7f768c1bab8754a13a3ccbba6f3dd8"
+ "d0ec6a7c6d687d0495b6e22c9ae767afc9d94f2e45a106133c42c79b52c26ad4"
+ "b67bd8ece55e84325ca6f49c8e9531f5f6b9cac35c933eebe3b9a11b9bb1c9ea"
+ "8ce6d2285da908e5919782b5b308fe478d98e49aea543bf8ca1b22edf43fdbf6"
+ "af31cc8cd4fb7de2d819afa5483eacdd56d7787bc8bb1622384049bc309a66",
+ "61c754763043b584e4a8546b79f0a3e2e0f3b3e2db6c94ad817e9281f485c082"
+ "08fed4f4d7d0a78c6c311a07c75b9bbe8504f4b7a692990216de12585c009ae5"
+ "8c26f085071f395e5af8925f3933f6d9f412d425546454e800b7e3aac78b7a08"
+ "b92e798bb834ebeadc4b4a6356af1ca09bf586745f616d51748cc7a37b48cb10"
+ "977e303bbe10bf27c69bdff0ba5cab8f62d0587a09d6e022823233c8c7aa4187"
+ "2223ed15a74accb0f1f822f24d7594ed9925a1c6c0c0f9ad0e071eb6b5ebe1ba"
+ "b6ba3b6d99a31652047f469260bee8710e370f04ed707593937a08dd82264992"
+ "311f4af9884cf8ad34afb9f675993c8abf41519839f76fa1e931bdae1d08a634"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.19",
+ "c9c93afea997b1ee36fa72720354c704649bc6ef44f5187c6c28542b9ae955a7"
+ "193fffec867bb62e219e68",
+ "52d4c3bf0c772c02d3bb711d7f146d8c4976f83081be4953d4afeb078e5412a3"
+ "2c3dc737b59bc454c3de93a1aed07c1ba64d1de4368014d04f6440556a4a1697"
+ "9d0803cc2922da97ed67619012f8f7d3b1a45584b0946af6dbd4a0857d4c2db9"
+ "9a17bbd27acd9a62e67f8879dbef27f1046a867e6995162b2a1a1cccdceaf45b"
+ "e1337e5fa8f85edaadf7508d58f326aa7cf301f441ba558b60e0fac6e0d19920"
+ "61a0a469be021626890ee87e68139bd519ae773e3ec481b7f2b377331f52f2e3"
+ "86884f765723e26cd4a8d968614c9c33dcdb",
+ "d06867022a0faf573d62cc24a6e06a44cd3d83eac5d0809ebf91304568cb1b27"
+ "561bb292e8776e216d1d023e753c124b51867b94dc60894d62c7dae5fa1a9faf"
+ "0376e1758cb6adc71417e83102528f23f4c5e5b50362a39e2aa9768b1062086f"
+ "a8c53ff1c39a0ee03d383d24bf490722b786daec908cd7151e185ddd17882678"
+ "027e368b0512cf98413f3e596fa3db4ec196ae5ff524a8266d760e0051433d18"
+ "98ffc230e96a2f0bfdf2b24429adfa918aba1a450f76783472301293848bd82d"
+ "5a338431d6cb1c106dc741d234bf5a80dbd325da64a394a0065f22028d0fdc5a"
+ "df0d0de29f22fb8c2a41331fe1fcb61589e0ec7500ed8442d61846df6cca46cc"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.20",
+ "69b7644855f91d1c61c8498e4ba1ba4d845ba882b173",
+ "b22fc7de85c5f75a2f32af1bfbcd5789715687de06e66d064ae3eb8dfb07a257"
+ "5be0e9e6f29f50d7396d078b36ef802f751a77cc92d7614c91dd279931fce007"
+ "ebf915a0f14e312ce91fe5aa6fb37451614fe37c73fc6f6d6f8e52789b5d88e8"
+ "6beb1633f5ddd5c070f14fd3cfee97dd4a643d35d45dd9bf34df8c310b48592e"
+ "946831b34ef3c0b916f17cb0acb2cfc1c25d0309acc1124f265c1a83ed885c87"
+ "fa826fda5710b54e16ec0f448cdb7ee0580ff7386530ea461e042a0b7742c461"
+ "976bb5a380adbcb00106f2671b6cce4f7267752f8066804278350b01753e31b3"
+ "8eccfbe90569f6",
+ "ab4267972c7796839388d4ad87ded74bb653e9a7050e282e82192875689f70ee"
+ "1da18a1f7322092cd29fd00119922a6de12601980aa9fa6e619e2775e87adae3"
+ "1695c1304e77f52cce016665f2267c20762643c6003c016d8480443c701df6c1"
+ "d8d655549600ee455b70e473319b0d4445e0b7552a1f808e88f3264842735ae6"
+ "1df0325ed03690d6d5d693ad1fed22668450379db5323dc01c89affae369b9c3"
+ "01c319c37ddf51edf46e09b21e5de91483e8e3cb21eeb7057bc2ebdc3aaa3d65"
+ "00c92f99b17b3180bba047d76073776336b15d054d79a440cc5e985ea543fcaa"
+ "25db1dd892b71bb74a5cf68263d8fd58f1a48e6c2fcb8c0b71a251cfc1a20157"
+ }
+ }
+ }
+ };
diff --git a/comm/third_party/libgcrypt/tests/pkcs1v2-v15s.h b/comm/third_party/libgcrypt/tests/pkcs1v2-v15s.h
new file mode 100644
index 0000000000..3d23aa7af2
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/pkcs1v2-v15s.h
@@ -0,0 +1,3660 @@
+/* pkcs1v2-v15s.h - pkcs#1 v1.5 sign test vector table
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Manually created from the file
+ ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt .
+ */
+ static struct {
+ const char *desc;
+ const char *n, *e, *d;
+ struct {
+ const char *desc;
+ const char *mesg;
+ const char *sign;
+ } m[20];
+ } tbl[] =
+ {
+ {
+ "A 1024-bit RSA key pair",
+ "a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991"
+ "d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1df"
+ "d5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f1"
+ "05acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",
+ "010001",
+ "33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e8"
+ "94a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9a"
+ "e55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c"
+ "31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 1.1",
+ "cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b6"
+ "2371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb76"
+ "9757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb0"
+ "61a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d61"
+ "93c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c"
+ "296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16"
+ "be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0",
+ "6bc3a06656842930a247e30d5864b4d819236ba7c68965862ad7dbc4e24af28e"
+ "86bb531f03358be5fb74777c6086f850caef893f0d6fcc2d0c91ec013693b4ea"
+ "00b80cd49aac4ecb5f8911afe539ada4a8f3823d1d13e472d1490547c659c761"
+ "7f3d24087ddb6f2b72096167fc097cab18e9a458fcb634cdce8ee35894c484d7"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.2",
+ "851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f"
+ "71a1cca582d43ecc72b1bca16dfc7013226b9e",
+ "84fd2ce734ec1da828d0f15bf49a8707c15d05948136de537a3db421384167c8"
+ "6fae022587ee9e137daee754738262932d271c744c6d3a189ad4311bdb020492"
+ "e322fbddc40406ea860d4e8ea2a4084aa98b9622a446756fdb740ddb3d91db76"
+ "70e211661bbf8709b11c08a70771422d1a12def29f0688a192aebd89e0f896f8"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.3",
+ "a4b159941761c40c6a82f2b80d1b94f5aa2654fd17e12d588864679b54cd04ef"
+ "8bd03012be8dc37f4b83af7963faff0dfa225477437c48017ff2be8191cf3955"
+ "fc07356eab3f322f7f620e21d254e5db4324279fe067e0910e2e81ca2cab31c7"
+ "45e67a54058eb50d993cdb9ed0b4d029c06d21a94ca661c3ce27fae1d6cb20f4"
+ "564d66ce4767583d0e5f060215b59017be85ea848939127bd8c9c4d47b51056c"
+ "031cf336f17c9980f3b8f5b9b6878e8b797aa43b882684333e17893fe9caa6aa"
+ "299f7ed1a18ee2c54864b7b2b99b72618fb02574d139ef50f019c9eef4169713"
+ "38e7d470",
+ "0b1f2e5180e5c7b4b5e672929f664c4896e50c35134b6de4d5a934252a3a245f"
+ "f48340920e1034b7d5a5b524eb0e1cf12befef49b27b732d2c19e1c43217d6e1"
+ "417381111a1d36de6375cf455b3c9812639dbc27600c751994fb61799ecf7da6"
+ "bcf51540afd0174db4033188556675b1d763360af46feeca5b60f882829ee7b2"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.4",
+ "bc656747fa9eafb3f0",
+ "45607ad611cf5747a41ac94d0ffec878bdaf63f6b57a4b088bf36e34e109f840"
+ "f24b742ada16102dabf951cbc44f8982e94ed4cd09448d20ec0efa73545f80b6"
+ "5406bed6194a61c340b4ad1568cbb75851049f11af1734964076e02029aee200"
+ "e40e80be0f4361f69841c4f92a4450a2286d43289b405554c54d25c6ecb584f4"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.5",
+ "b45581547e5427770c768e8b82b75564e0ea4e9c32594d6bff706544de0a8776"
+ "c7a80b4576550eee1b2acabc7e8b7d3ef7bb5b03e462c11047eadd00629ae575"
+ "480ac1470fe046f13a2bf5af17921dc4b0aa8b02bee6334911651d7f8525d10f"
+ "32b51d33be520d3ddf5a709955a3dfe78283b9e0ab54046d150c177f037fdccc"
+ "5be4ea5f68b5e5a38c9d7edcccc4975f455a6909b4",
+ "54be9d90877515f450279c15b5f61ad6f15ecc95f18cbed82b65b1667a575809"
+ "587994668044f3bc2ae7f884501f64f0b43f588cfa205a6ab704328c2d4ab92a"
+ "7ae13440614d3e085f401da9ad28e2105e4a0edb681a6424df047388ce051ee9"
+ "df7bc2163fe347520ad51ccd518064383e741acad3cbdc2cb5a7c68e868464c2"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.6",
+ "10aae9a0ab0b595d0841207b700d48d75faedde3b775cd6b4cc88ae06e4694ec"
+ "74ba18f8520d4f5ea69cbbe7cc2beba43efdc10215ac4eb32dc302a1f53dc6c4"
+ "352267e7936cfebf7c8d67035784a3909fa859c7b7b59b8e39c5c2349f1886b7"
+ "05a30267d402f7486ab4f58cad5d69adb17ab8cd0ce1caf5025af4ae24b1fb87"
+ "94c6070cc09a51e2f9911311e3877d0044c71c57a993395008806b723ac38373"
+ "d395481818528c1e7053739282053529510e935cd0fa77b8fa53cc2d474bd4fb"
+ "3cc5c672d6ffdc90a00f9848712c4bcfe46c60573659b11e6457e861f0f604b6"
+ "138d144f8ce4e2da73",
+ "0e6ff63a856b9cbd5dbe423183122047dd39d6f76d1b2310e546fe9ee73b33ef"
+ "a7c78f9474455c9e5b88cb383aafc3698668e7b7a59a9cbb5b0897b6c5afb7f8"
+ "bac4b924e98d760a15fc43d2814ab2d5187f79bed9915a93397ebc22a7677506"
+ "a02e076d3ffdc0441dbd4db00453dc28d830e0573f77b817b505c38b4a4bb5d0"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.7",
+ "efb5da1b4d1e6d9a5dff92d0184da7e31f877d1281ddda625664869e8379e67a"
+ "d3b75eae74a580e9827abd6eb7a002cb5411f5266797768fb8e95ae40e3e8b34"
+ "66f5ab15d69553952939ec23e61d58497fac76aa1c0bb5a3cb4a54383587c7bb"
+ "78d13eefda205443e6ce4365802df55c64713497984e7ca96722b3edf84d56",
+ "8385d58533a995f72df262b70f40b391ddf515f464b9d2cc2d66398fc05689d8"
+ "11632946d62eabdca7a31fcf6cd6c981d28bbc29083e4a6d5b2b378ca4e540f0"
+ "60b96d53ad2693f82178b94e2e2f86b9accfa02025107e062ab7080175684501"
+ "028f676461d81c008fe4750671649970878fc175cf98e96b2ecbf6874d77dacb"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.8",
+ "53bb58ce42f1984940552657233b14969af365c0a561a4132af18af39432280e"
+ "3e437082434b19231837184f02cf2b2e726bebf74d7ae3256d8b72f3eafdb134"
+ "d33de06f2991d299d59f5468d43b9958d6a968f5969edbbc6e7185cbc716c7c9"
+ "45dafa9cc71ddfaaa01094a452ddf5e2407320400bf05ea9729cafbf0600e788"
+ "07ef9462e3fde32ed7d981a56f4751ef64fb4549910ecc911d728053b3994300"
+ "4740e6f5821fe8d75c0617bf2c6b24bbfc34013fc95f0dedf5ba297f504fb833"
+ "da2a436d1d8ff1cc5193e2a64389fced918e7feb6716330f66801db9497549cf"
+ "1d3bd97cf1bc6255",
+ "8e1f3d26ec7c6bbb8c54c5d25f3120587803af6d3c2b99a37ced6a3657d4ae54"
+ "266f63fffde660c866d65d0ab0589e1d12d9ce6054b05c8668ae127171ccaae7"
+ "f1cd409677f52157b6123ab227f27a00966d1439b42a32169d1070394026fc8b"
+ "c93545b1ac252d0f7da751c02e33a47831fbd71514c2bbbd3adb6740c0fd68ad"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.9",
+ "27cadc698450945f204ec3cf8c6cbd8ceb4cc0cbe312274fa96b04deac855160"
+ "c0e04e4ac5d38210c27c",
+ "7b63f9223356f35f6117f68c8f8220034fc2384ab5dc6904141f139314d6ee89"
+ "f54ec6ffd18c413a23c5931c7fbb13c555ccfd590e0eaa853c8c94d2520cd425"
+ "0d9a05a193b65dc749b82478af0156ee1de55ddad33ec1f0099cad6c891a3617"
+ "c7393d05fbfbbb00528a001df0b204ebdf1a341090dea89f870a877458427f7b"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.10",
+ "716407e901b9ef92d761b013fd13eb7ad72aed",
+ "2a22dbe3774d5b297201b55a0f17f42dce63b7845cb325cfe951d0badb5c5a14"
+ "472143d896c86cc339f83671164215abc97862f2151654e75a3b357c37311b3d"
+ "7268cab540202e23bee52736f2cd86cce0c7dbde95e1c600a47395dc5eb0a472"
+ "153fbc4fb21b643e0c04ae14dd37e97e617a7567c89652219781001ba6f83298"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.11",
+ "46c24e4103001629c712dd4ce8d747ee595d6c744ccc4f71347d9b8abf49d1b8"
+ "fb2ef91b95dc899d4c0e3d2997e638f4cf3f68e0498de5aabd13f0dfe02ff26b"
+ "a4379104e78ffa95ffbd15067ef8cbd7eb7860fecc71abe13d5c720a66851f2d"
+ "efd4e795054d7bec024bb422a46a7368b56d95b47aebafbeadd612812593a70d"
+ "b9f96d451ee15edb299308d777f4bb68ed3377c32156b41b7a9c92a14c8b8114"
+ "4399c56a5a432f4f770aa97da8415d0bda2e813206031e70620031c881d616bf"
+ "fd5f03bf147c1e73766c26246208",
+ "12235b0b406126d9d260d447e923a11051fb243079f446fd73a70181d53634d7"
+ "a0968e4ee27777eda63f6e4a3a91ad5985998a4848da59ce697b24bb332fa2ad"
+ "9ce462ca4affdc21dab908e8ce15af6eb9105b1abcf39142aa17b34c4c092386"
+ "a7abbfe028afdbebc14f2ce26fbee5edeca11502d39a6b7403154843d98a62a7"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.12",
+ "bc99a932aa16d622bfff79c50b4c42358673261129e28d6a918ff1b0f1c4f46a"
+ "d8afa98b0ca0f56f967975b0a29be882e93b6cd3fc33e1faef72e52b2ae0a3f1"
+ "2024506e25690e902e782982145556532284cf505789738f4da31fa1333d3af8"
+ "62b2ba6b6ce7ab4cce6aba",
+ "872ec5ad4f1846256f17e9936ac50e43e9963ea8c1e76f15879b7874d77d122a"
+ "609dc8c561145b94bf4ffdffdeb17e6e76ffc6c10c0747f5e37a9f434f5609e7"
+ "9da5250215a457afdf12c6507cc1551f54a28010595826a2c9b97fa0aa851cc6"
+ "8b705d7a06d720ba027e4a1c0b019500fb63b78071684dcfa9772700b982dc66"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.13",
+ "731e172ac063992c5b11ba170dfb23bb000d47ba195329cf278061037381514c"
+ "146064c5285db130dd5bae98b772225950eab05d3ea996f6fffb9a8c8622913f"
+ "279914c89ada4f3dd77666a868bfcbff2b95b7daf453d4e2c9d75beee7f8e709"
+ "05e4066a4f73aecc67f956aa5a3292b8488c917d317cfdc86253e690381e15ab",
+ "76204eacc1d63ec1d6ad5bd0692e1a2f686df6e64ca945c77a824de212efa6d9"
+ "782d81b4591403ff4020620298c07ebd3a8a61c5bf4dad62cbfc4ae6a03937be"
+ "4b49a216d570fc6e81872937876e27bd19cf601effc30ddca573c9d56cd4569b"
+ "db4851c450c42cb21e738cdd61027b8be5e9b410fc46aa3f29e4be9e64451346"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.14",
+ "0211382683a74d8d2a2cb6a06550563be1c26ca62821e4ff163b720464fc3a28"
+ "d91bedddc62749a5538eaf41fbe0c82a77e06ad99383c9e985ffb8a93fd4d7c5"
+ "8db51ad91ba461d69a8fd7ddabe2496757a0c49122c1a79a85cc0553e8214d03"
+ "6dfe0185efa0d05860c612fa0882c82d246e5830a67355dff18a2c36b732f988"
+ "cfedc562264c6254b40fcabb97b760947568dcd6a17cda6ee8855bddbab93702"
+ "471aa0cfb1bed2e13118eba1175b73c96253c108d0b2aba05ab8e17e84392e20"
+ "085f47404d8365527dc3fb8f2bb48a50038e71361ccf973407",
+ "525500918331f1042eae0c5c2054aa7f92deb26991b5796634f229daf9b49eb2"
+ "054d87319f3cfa9b466bd075ef6699aea4bd4a195a1c52968b5e2b75e092d846"
+ "ea1b5cc27905a8e1d5e5de0edfdb21391ebb951864ebd9f0b0ec35b654287136"
+ "0a317b7ef13ae06af684e38e21b1e19bc7298e5d6fe0013a164bfa25d3e7313d"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.15",
+ "fc6b700d22583388ab2f8dafcaf1a05620698020da4bae44dafbd0877b501250"
+ "6dc3181d5c66bf023f348b41fd9f94795ab96452a4219f2d39d72af359cf1956"
+ "51c7",
+ "4452a6cc2626b01e95ab306df0d0cc7484fbab3c22e9703283567f66eadc248d"
+ "bda58fce7dd0c70cce3f150fca4b369dff3b6237e2b16281ab55b53fb13089c8"
+ "5cd265056b3d62a88bfc2135b16791f7fbcab9fd2dc33becb617be419d2c0461"
+ "42a4d47b338314552edd4b6fe9ce1104ecec4a9958d7331e930fc09bf08a6e64"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.16",
+ "13ba086d709cfa5fedaa557a89181a6140f2300ed6d7c3febb6cf68abebcbc67"
+ "8f2bca3dc2330295eec45bb1c4075f3ada987eae88b39c51606cb80429e649d9"
+ "8acc8441b1f8897db86c5a4ce0abf28b1b81dca3667697b850696b74a5ebd85d"
+ "ec56c90f8abe513efa857853720be319607921bca947522cd8fac8cace5b827c"
+ "3e5a129e7ee57f6b84932f14141ac4274e8cbb46e6912b0d3e2177d499d1840c"
+ "d47d4d7ae0b4cdc4d3",
+ "1f3b5a87db72a2c97bb3eff2a65a301268eacd89f42abc1098c1f2de77b0832a"
+ "65d7815feb35070063f221bb3453bd434386c9a3fde18e3ca1687fb649e86c51"
+ "d658619dde5debb86fe15491ff77ab748373f1be508880d66ea81e870e91cdf1"
+ "704875c17f0b10103188bc64eef5a3551b414c733670215b1a22702562581ab1"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.17",
+ "eb1e5935",
+ "370cb9839ae6074f84b2acd6e6f6b7921b4b523463757f6446716140c4e6c0e7"
+ "5bec6ad0197ebfa86bf46d094f5f6cd36dca3a5cc73c8bbb70e2c7c9ab5d964e"
+ "c8e3dfde481b4a1beffd01b4ad15b31ae7aebb9b70344a9411083165fdf9c375"
+ "4bbb8b94dd34bd4813dfada1f6937de4267d5597ca09a31e83d7f1a79dd19b5e"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.18",
+ "6346b153e889c8228209630071c8a57783f368760b8eb908cfc2b276",
+ "2479c975c5b1ae4c4e940f473a9045b8bf5b0bfca78ec29a38dfbedc8a749b7a"
+ "2692f7c52d5bc7c831c7232372a00fed3b6b49e760ec99e074ff2eead5134e83"
+ "05725dfa39212b84bd4b8d80bc8bc17a512823a3beb18fc08e45ed19c26c8177"
+ "07d67fb05832ef1f12a33e90cd93b8a780319e2963ca25a2af7b09ad8f595c21"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.19",
+ "64702db9f825a0f3abc361974659f5e9d30c3aa4f56feac69050c72905e77fe0"
+ "c22f88a378c21fcf45fe8a5c717302093929",
+ "152f3451c858d69594e6567dfb31291c1ee7860b9d15ebd5a5edd276ac3e6f7a"
+ "8d1480e42b3381d2be023acf7ebbdb28de3d2163ae44259c6df98c335d045b61"
+ "dac9dba9dbbb4e6ab4a083cd76b580cbe472206a1a9fd60680ceea1a570a29b0"
+ "881c775eaef5525d6d2f344c28837d0aca422bbb0f1aba8f6861ae18bd73fe44"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.20",
+ "941921de4a1c9c1618d6f3ca3c179f6e29bae6ddf9a6a564f929e3ce82cf3265"
+ "d7837d5e692be8dcc9e86c",
+ "7076c287fc6fff2b20537435e5a3107ce4da10716186d01539413e609d27d1da"
+ "6fd952c61f4bab91c045fa4f8683ecc4f8dde74227f773cff3d96db84718c494"
+ "4b06affeba94b725f1b07d3928b2490a85c2f1abf492a9177a7cd2ea0c966875"
+ "6f825bbec900fa8ac3824e114387ef573780ca334882387b94e5aad7a27a28dc"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "ac13d9fdae7b7335b69cd98567e9647d99bf373a9e05ce3435d66465f328b7f7"
+ "334b792aee7efa044ebc4c7a30b21a5d7a89cdb3a30dfcd9fee9995e09415edc"
+ "0bf9e5b4c3f74ff53fb4d29441bf1b7ed6cbdd4a47f9252269e1646f6c1aee05"
+ "14e93f6cb9df71d06c060a2104b47b7260ac37c106861dc78ca5a25faa9cb2e3",
+ "010001",
+ "0484ccefad7a4e6f35a96ec8e30eacf5e368b31195febf087df57053810c2bb0"
+ "9127453a4c63073bbfb99024914ccc067266560186a1a267331b7d4c8bdfac96"
+ "fda9f3f70bec4eeabce7cd5219343c2e491cce827e44ee230e4f69589e575ae9"
+ "063030442a31c82cde30dc9c79cf64e7a0975e75e16ea45815488b455256eeb1",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 2.1",
+ "e1c0f98d53f8f8b1419057d5b9b10b07feeaec32c0463a4d68382f531ba1d6cf"
+ "e4ed38a2694a34b9c805adf072ffbcebe21d8d4b5c0e8c33452dd8f9c9bf45d1"
+ "e633751133588229d293c6496b7c983c2c72bd21d339272d7828b0d09d010bba"
+ "d318d998f7047967338acefd01e874ace5f86d2a60f3b3cae13fc5c66508cfb7"
+ "2378fdd6c8de249765103ce8fe7cd33ad0ef1686feb25e6a35fb64e096a4",
+ "64ac093971f8f096a4c1d4a543662a2e5a1281c950987de898707f029c159bd8"
+ "32cac55d9136e0e9b4a80bf6f21b68cf9770a6349ae51e7f09dbda9d59c45837"
+ "37472d4d6532c7177ee98108d2cf42cd085abb4922eb29d96f3d0f6b1d0d43c7"
+ "39ccf1ba651675e1968b507d51902f38cdec0b6132729045325fc1fb8fd558e8"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.2",
+ "c111464e002e4ec618a8e263dbcca91fb18a00a18b440c4b5597bee7db2aeda8"
+ "31e621fcac8dd81cee3503242b33b0daa987fe2f5493ad2d06a15007590040ce"
+ "3c2277642fd27f3f255e3d98d89dfaeb86be34e0b8fbb935fb928560fa292d26"
+ "34625a507dd580a89124b921293e8dfeddc281d79eb3a569d59e0db8013e53f7"
+ "d4c2f96e5f2ec27fd8ddb01825d17fca406daa6224c7606d2c915282096a7805"
+ "5a49621537b4f025a6e5b2129bc8c1a407",
+ "6e7eaad804945eb04670dd8676b7057d03ac3e226465b1fb8403e6ae7983e0a4"
+ "6a89a4eb32bdc8e7ae5a53d48aa64bc9c3dbc8cf9cd6dc6a68fceae9e29f4745"
+ "fa49e18d184dc5d26c4feb351fb4b228c4c18cabdbde8601724ae3803db305f2"
+ "a076fa8a57f4610b8a6e0ed43575be5d5bfc1630479df3bcbc515177afe4994a"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.3",
+ "29b85b14b2da947a4c3ad1e5937da192c6050865af9504a5445370e43d3a8da5"
+ "d355fd58766b2543ac6f93108783c13ff28b2be56083f0298239e0ee9681ee47"
+ "c6",
+ "80b38ce735126c8545d91d18ec9037654d46e4f3c51a6b8618e15f72cd207500"
+ "a470017577d0a8c55a2ba334383f1f8d99fce2460b3297bc037ef64ac4a3098c"
+ "6aaa24a4d0144af102d0dda17e07dc695923932e568ada00dc4f7dbfbcdec43c"
+ "c908388017d2eef04e60dfe4d57340fab916e2b811244cb1e4a552386fe3ed4c"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.4",
+ "d3b7aad37a4890e0365b86c7da9491e73cdf555d1b02b451816dc52f9630d590"
+ "de83a5c93961012522dff6dbbb9cdb0e71ae51401964af1890e89325dbd626f2"
+ "da013458e39eeca583e89e4c08e5d412be498495886e0551cfe742b8b5",
+ "9d8a8889a311b486cbe2225703f5d4ae2a54c2bcaaad06fe7648b9e2d85edda1"
+ "a07d856d6ae9bd5cc1e5153266ec7f1e1df3d929cc44700fac926458414c2841"
+ "da83328e81e0b9d6c3885e767370ad5cf1f576d9dce348caec5e6443e0aeb7c3"
+ "f72b7dd253667023b9a477ab34df8f2067e225adcb73ee11e159eb649147d602"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.5",
+ "f658188c8f9de60b5e99a29f52d3b889201b30d464c3b72792a302095dc1e77d"
+ "45e94f5dab73dbb313543857ff91dbf473dfc145d73bd5062075d192a3fbf4a1"
+ "33e7e568df20b8cff77b3af687aa22559ec1",
+ "0a95a44f6274e74cec451796af5688d4be010893faae27d490f4771b003f7046"
+ "cccd419fc819d7331955f41eac9339f546c584a8b42a5ac63290583ff3eb6b29"
+ "cadc754ae58d5a5637b6609796e8055173ff20a9cce492fd7837468615e84108"
+ "87f0b4a59ff252a8259776c8ffdaa67c87dff8983ae679d1de22ea158d48f68b"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.6",
+ "31ae5f83a0fb3ac9255ffa435f70e2ab655566e5fb8b78b802c187cff1c5e40f"
+ "ed06978c5d5976eb4ca775806399a6fc4db50c1f88661ba68abc21fb2ccd537f"
+ "5018f36ed1f7d45383fd469e77bab3e8a95dfa1b941e430ddec552dcd82f5d10"
+ "d29cd10a22d17ce2425928ff5d0710dce7d9f83b12e04c1a0159c27176e04acc",
+ "3f11ea739f329c9d40046034b6c0cfceb49bc3201a5f25eaf5015aeded02189c"
+ "e0b0cfde19125bd288b7d0c062321a5bdc2cfa4226f5104a1fbaebbe7f72f5f7"
+ "927e1eae26fdc5ba92f2d3f869ebc32d9018dd04ede86de5c454f1f7a1b2e2d1"
+ "940aacae27796355fe18ac80975353929ac6a838458b5d9dc7576e3887ee7bca"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.7",
+ "96ff99f15060c973a65b69a8b5b63adb3325320da937297584ad4fad5c3c7469"
+ "019e9cf72acb315f1e491927bba1948755823eb07e3f20acdf78653cae450e47"
+ "bc54baf8ca1167a5050844e022220ee6658a8ddd95632e9adc1a6c14379c1c5a"
+ "e5a0ce5dc4020809622afdecf81f18a51e28666d02b1dcda0a27b8c3d2c27b2c"
+ "07b3802200017a7c124a4337cc4b6ea2aea75c68b440e37947e3619bcfee055b"
+ "b2edabc4244907e0483dd3a17d8edff3a650293fd4abf5c45d1a5b6c5402ba2b"
+ "81b7b0e0c95ee949b2a238c19956206c124e0cd9c24620b36a83bf93b96ef204"
+ "bde5316c1f5327c0a621ecce2093c0652ddf321768d74502f1908529629bab68",
+ "183f853d0d03621870e3ba586850c5ea59fc4e9acf3794b9ad59a1bb80181e77"
+ "b111d6648647e139a39ec04f86187491e77b4d75c060795bf7270846d396e0bf"
+ "ea8315795e79d76a919ea76b06eec13baf4ce8afe1e34bc22457d7b7992e0842"
+ "efade179b0aedaccfbe2d23d3eb314e1de91c871b9db5abffb17477fba233a06"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.8",
+ "3a176c793a546e2d276fb8ffc328163b494997a5302aae2e5045a2a20687ea6d"
+ "1f181c6abfe6090c8dc40256db3de08322647fb795bba1713fb57e33d53e0e13"
+ "bedac6a658ad4ab491223881198df29367faade8be9fcaa4e483f7b7f3dc7cbb"
+ "f97a17aad88c26cfc6410f945b54fc53db55ac803d8b73691b1484847d7f3b7e"
+ "9394e55f0a51fe61ae84523c94b22e82396db6cfacb72e0ee494aa0f1fa59312"
+ "5443ae1555a6a933face0074791dc2c29242eb",
+ "413c9223a2e9b122cd872577e52f313d41dac79a26cb1033da0b6fcc4b482107"
+ "744bf490fa798dccd0cbd118ef39c0f559d87b89335db09be7700fb09fdbd340"
+ "40a00be5ca42883477b06e4e10a7cb11768fcb02c34fb106e522860d10693906"
+ "260f43d90612990393a8ffac9fd70ca37829111eeba6f3dee54ef1c16268b33e"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.9",
+ "068a991b32b676c64b898c67e1137282b43711b0d0671c247d9f7c48f5043e4f"
+ "c206dc65af8906f252f0245205ea084323d4276be5aa0fc5af9c3f34b2fd6634"
+ "df572fc313d273b53e9e36b946e7e672f98d857d7eddd3dd04393132f461f22c"
+ "990026166f385be1595c7f23f89ff57e05a7be285d105615485f356abab1ff2a"
+ "b927d609952a627e468ca7590acb5213f43139f8e2c9d4d17c6bd7914e53f02f"
+ "d19a131ff49cd25ede8f418a88530a8239887f0fc797edb504647964bf31caaf"
+ "080d5817a0",
+ "575da9e9befca1829546e8293815001132030e749ca51088f168bd150b1394c7"
+ "acd5978bca03f7b9d92a29b8e2856b0da07f0bb15c0b33e05487991ad97a812d"
+ "c904aaf0fd1e387ef1c270c6868d3ee1c611577bc4d07ff456b2439832908a3d"
+ "cc4fc0990472fda3cc6111930b99795d60c0e37888e87ce00bbf3c1cf307f9e1"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.10",
+ "d6839ee6d07450327e09a03e1ec280e1c8d11500dc390a49a9c9828749c3e9a4"
+ "bee2ba576f6d1217a8e7854a907eeb93dfff92308ad0d94e2b381f92b0e84a47"
+ "1bf1f37a68e965f65859d1fdfd6fea844079c40370dceae2",
+ "a7c5f6d0de9cf8f41737f23ae3e8cf609aebcf22d5de1213d9573cb94403f89c"
+ "0f7088fffc61106fa609c7371a8d7e1bcd221bc1ad94912fabf2ffc02f848456"
+ "4c225c069bfc6da9f3f9f4974e08e1fe56f748ff790597906a954e383743a37e"
+ "575fef074f060f3dd15b5ee0f94dba69d86c99223fa9c3a61a8cb2af2fab1e04"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.11",
+ "33849c67df9a6ffac3da90a8cd31731a0297b9d6010a03320f8845035fc34309"
+ "ad",
+ "1b87051f1591c8ae7ee3cb24267039a728405dbf231caf21f3247f05858b2a51"
+ "650b81bc5377865e4c1e8fd0364152a16bc58f7d2ac01ca679cc49dd048903d5"
+ "5ad05f102c74b3601f25ad30624025c30b6f0f7911fc22458e5d435f388e3fbc"
+ "495fa0c610c1298f821da538403a93364d2eabf1e3b32f8110a7e03e372ecbc5"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.12",
+ "b3dabaca2059a70e25cbddf4aa5925995754ace43c5d603640489af48fea6edc"
+ "4e19cbeea2c0db62ae0a104c72e4cd56cb532f4fe577b36a8198b4879d7ff804"
+ "2690f662773f3d6393f25898d2",
+ "26f13770263fc5bdbeadf88fb4dd307a38959b16f3df946ade864b1e7e914d36"
+ "4ebf9adfd86a70022dc61b43fb1fdf8696978e2d1f6a2defee75adaa69a39532"
+ "074050be708eaf031d5fae0ffe245ba4ff3c5e340af5dfec6a4cce0e18876cfc"
+ "1366eeeddfce0f835b38e81881b1fc5832930fc79b08f1fb34fb224233f4c468"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.13",
+ "099112fae740888ceaac7054d597351d79e159a958d8121578e52c837db3543c"
+ "fa6f8e7f1dbd2a61978645a4d385b9bb1c60bfb11bb3c8752ae31f996dbb5262"
+ "8f93d52694f182e69035a5e557ec718262f403df5211f73c6de0d55a0ba7",
+ "8d8c8f3a86f49edbd125c83ebf6d52e765161501482154598c283abe94027787"
+ "2b00d0777c2e697b7883cc321e151c80116f9fcd177ac4c7deddf03ca1b2c593"
+ "31dc1c8e947f1eb2aaee8cc941ddc5f374a63d6c9938ecd8e88cbcec58929cff"
+ "ddef0ba2175885a80dc4cd92d6b79d9c6a81696e16f9a83a10ca8efaf1975f55"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.14",
+ "aa17e6bbd6db19e54bee1a7f0edccaceab635d7628fcaa18ecfafc401cb3feb5"
+ "1f9a3731f3802cbea81c733028c9584b6b78e2055954cf9104daa677aa40be9b"
+ "7c65b07ac4a8bf25c1149e054735cf3ce332d429bc73802445dfb3688bb81948"
+ "b57e276af32462f7ad804d50c93bc7e9ef7537695a271af72e4bd47ce5fa9d62"
+ "f2dac0333623f49eb9d6d78034ed1df6e12bfd04261bbe5ce040e03ebe258d2d"
+ "052a12ad4e3bf253042301c76458ed910c5ffa705c747ad8ca0c1c6228da2c97"
+ "e138",
+ "644ea076214dbddd30055d7c561892279b46bab1e12253424c28f449e172646a"
+ "f3498c7afcbff768e046a7c2e3d9c0e7128f877b92195aa2bb9f1cfbdfd15bb6"
+ "5fbd23efb294fbb11a3c66056d6063853bb23c274665a13ef4f3c12f5921a419"
+ "e949b30c0bc0d77d6b28691d2364d95bf68be8d5978ef1bc9852a4f06604474a"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.15",
+ "28249c387a061440e98638e1ed78a4865130e57533d789108c63e15fd8019bad"
+ "2cd1a7552bd8afd206d978eb1f2cf3f23afc4b34e6dd7f69c1fdf4fec25268d1"
+ "865551944922906dce6dc441f94a466bf8391ad82bf5940e447110f1d15de129"
+ "3129fb4424a1717519d6d428d66b7a109142acc915f1eac96def2c3290b01d05"
+ "990bf8023a6a64712f63137a8e",
+ "5702060669ed47bbca11b91668289ea3f5e746ad2e386dd1bc2a8bab1746ba2a"
+ "64bf15b3fc2ec8b0cc99d854fa3211c955c455d7ff2e1ee239f54f386a42bb25"
+ "40a8758f3297e552de1ebe8eac70f35487942bbadad5bd957390ff1793af3d30"
+ "d936b6f79b44a9b63cee62d5584da3a1fcffa5b6feeec11cd63b180f0bfc5b6b"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.16",
+ "e491a156fdba316a2a20a12eea50be774ec9aabeb1c398e908bea32968217ea4"
+ "1e966db7272f0efa37c90ae4e9f38621a627a9d12c8b4e8060c545c56059e9e4"
+ "8a7f1681367247335819ba127e65931e1d9fb70dfddf4c9956a5b04c52bcf8cb"
+ "dfcdf2291964dafaca7ee70e80a2759cec735d01aca8ff894b689b93783da893"
+ "9c6209dd683c60",
+ "9f205ba90df2d4014926481f9b3f45a89d23ecd84f5f16e67334c4caf3f3b9c2"
+ "01a798d4eec56276598823180e078d0aef4f8fba0b25c1fda3e33654c474a9c1"
+ "1a23b08710913dff7656f0e7ee22cc44c999c095a6514a9d2fc0ca4ef208de0d"
+ "9293b0c5608baed1074a0cfd57b99ef8ceabfd3472b7db3ab9606d13f9bb439a"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.17",
+ "06add75ab689de067744e69a2ebd4b90fa9383003cd05ff536cbf294cd215f09"
+ "23b7fc9004f0aa185271a1d0061fd0e9777ad1ec0c71591f578bf7b8e5a1",
+ "4514210e541d5bad7dd60ae549b943acc44f21390df5b61318455a17610df5b7"
+ "4d84aed232f17e59d91dd2659922f812dbd49681690384b954e9adfb9b1a968c"
+ "0cbff763eceed62750c59164b5e080a8fef3d55bfe2acfad2752a6a8459fa1fa"
+ "b49ad378c6964b23ee97fd1034610c5cc14c61e0ebfb1711f8ade96fe6557b38"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.18",
+ "311c88800535d1b4e9bc78651831a3e967e74b5828e014115fbe5f609ce865fe"
+ "d241970f872ec8f23dc2bf616b8020e44564f934dcbf72386170074d920ba895"
+ "d33ddf279369f236a19acd4feb2b",
+ "894663e63ec19f56203f4a446b5e2b5174c814a54cbea2c8e298f99b34c4bbc2"
+ "c8b177ba9857d81c854436bd99af58c09dde5acad2d6415043fb40e78475ef74"
+ "012e4d4f75b2e95885c851a23b4a255493f30c172eae01d47910fabd269f5794"
+ "0ba443506c0522bf728a257ac1073bdf99b42956db002a30a54dbdaf284d8f69"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.19",
+ "b265a9777faaf158a808aae7085a83e7079cef80d5fc9d7cdc963ec9",
+ "281e88ce190e9862903436a86ba4372716449cc0ce8d554f702d7252a06760af"
+ "42121dd09bf6ea13f0eb252ecc76421061f5744bd8e32c5a8c4fc1f9521b3f5c"
+ "29146dd0591291acbdc5b63b551d228ae53895b197e6e27a7068aa3103b70cfb"
+ "30f415845c7e5287f1114e4cdfb401ed519864cf61bc469c66699b2960a0aff2"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.20",
+ "7c439e7ab990cdef956c4239479b49da842f8b76765a7ad4897bc16c61ed3d09"
+ "805d76e8a5be8b578b951f4545df92a8a537ba3e2c13dce0a003e7b6249e32be"
+ "941f21cda725b80407be1e28bb9e393738325356ec21741d5c86f3c2b4f7b947"
+ "afd56b2d3aec",
+ "6afad77a056d07290586e913809a0437d39ab307324512b2f5bc2baf580bf455"
+ "43eb04ff83e963a6d7f33e9dffc1fcf42448c5fcfa472719c651f81f3c622298"
+ "3d38917e29b48485879cebb0a61d389e238c9c71c368ede4083a946297f7190b"
+ "4cef867e9ccda8f9ffc61984fcf05d4fbafe107dacf5b1dc8e2b1495b244f8e7"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "b5d707b792e056f72fd76d8da889a53ce4d8ebaa082aeeb23032e3c5d8ebc4c1"
+ "5561319be8dfe188991a8951d4b23a51e8a9382c805e4cfd490ebbceaa20802a"
+ "d683b05a100f29985f011c3c8a44262552d83d9a1b7c27315e144ad8df5cbe8b"
+ "c6400fd9cbe76b7421d708aa64f040bae07b7bd6f92218f9a729284cc598cdd1",
+ "010001",
+ "451792b59447cc9378a8a4d645fb22ff4bbf067061511ac836db2743a624136b"
+ "186b6943a1cceb6f91290d933bbb8ac053a4749528236ca272cf77d9d337ad2a"
+ "b36a87a9153c5e16716e09ba0beaa64b312526d4a8c2dc68fe09e37e5074a090"
+ "9d3f04ab73908a980dec1da7eb4505a48bcad3b60d0160845864a6511ff559a7",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 3.1",
+ "986e7c43dbb671bd41b9a7f4b6afc80e805f2423488fb431f5ee792b6c2ac7db"
+ "53cc428655aeb32d03f4e889c5c25de683c461b53acf89f9f8d3aabdf6b9f0c2"
+ "a1de12e15b49edb3919a652fe9491c25a7fc",
+ "6275e87397e3092aab3698bb1b5cf24b8cd7712becac35e32203d54314e5470e"
+ "a9aabc8657f56434e5af9fae778ff6045c20e2e1ef7cbdf88f0075f33ea99277"
+ "7cb7e92f7da18a0ffd00aa4671ed63911fe9e92fb4a76e77dc6e0a916576716c"
+ "15eaef089a71a0aea35bed9447a6c17f2aadb727fd42f0acc82462381d9fa2ef"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.2",
+ "4c7b98120c87509087c478",
+ "59e5cbe7331b92e0cb8f689eaebb30f2b334a746a657055912ff1c92760b0b85"
+ "bc4282f3184b9a814f4437f825ae07d356bac69e540c90942c7f7e6ff44fe574"
+ "f121250ad230f4b50c78311e4fd3c9e265f517ce3297c3e1dddb5c869c698f44"
+ "af525e736401a81b459f198ad1808ccd929d490474caf7005f910dacde21b077"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.3",
+ "66f7075422c8ec4216a9c4ff49427d483cae10c8534a41b2fd15fee06960ec6f"
+ "b3f7a7e94a2f8a2e3e43dc4a40576c3097ac953b1de86f0b4ed36d644f23ae14"
+ "425529622464ca0cbf0b1741347238157fab59e4de5524096d62baec63ac6450"
+ "327efec6292f98019fc67a2a6638563e9b6e2d15efd237bb098a443aeeb2bf6c"
+ "3f8c81b8c01b7fcb3febb0de3fc25b65f5af96b1d5cc3b27d0c6053087b39680"
+ "e492a4ab2367471169e52838945dba9dd7723f4e624a05f7375b927a87abe6a8"
+ "93a1658fd49f47f6c7b0fa596c65fa68a23f0ab432962d18d4343bd6fd67d00b"
+ "25b81b09b562038564",
+ "599e69c154e4fe66b36a690492faebb2bbe734e0415d9f3cf7e37828f53e6113"
+ "0449173a33460c6b4c8dc7d681ca6f4daf1cb816d40aa9082ee1937be4bc6a09"
+ "c6de798c8286fcd2a2b2196c59994c937f37130752612c6bff6dbb53e0647f88"
+ "58bc383864021e6d56681920249297822246a0f528aab3ed185eebce919cf83e"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.4",
+ "d9344428fa8a58f8fa7b443e51fc9b51e37a70210db8bd1de7f8675d8479ff65"
+ "7ca72955b23c6f4a0916379a4edee1f26c85e05290211eeb25832b09cbe5eaed"
+ "3e3965b05a52fb5b16491182c5913cb1825748e81ad014f13d296dc16957082b"
+ "1b83b4be50a0f959c9e7f3aa8077972e2b93c2effd9f308625b8ca7f54d7b696"
+ "48790447ac91f7985e510df70d6ebc3572c205e6",
+ "2c060165fcc5655c0657c8fe08e05bdc8cd77c1fecb6d18b893811c99dd091e0"
+ "d8506dccb49e33daaff6da967b99e344cb17fa3c9631299b3589818b37ed9d5d"
+ "7894e4a69ddb24832e1a8860014ee5e5eb953e8b35484ba4fec9c3033ae2e118"
+ "9af794a72e4267215bfe458f0fce6b37a5549ef80543d0d41a87b2c6e4d84cb5"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.5",
+ "8c6702daaf58f6a475fad2c7a4bb156a5706425577d5e30c6a6bd3669fd030af"
+ "d789faa3d01018d45db2a047f52cb4f63dea360942afe476264206d983ad3836"
+ "e155c56b2ecc08763afb9fd51d19990efc3363f657e285e03521e8cad01d2c93"
+ "5a183ae23f0ee8710086a85b9fad4e7f2b09452ebc403ce0c0e5755a7b2f33f4"
+ "def0db71c97931ff904a81319984bdc5166f6b920c97ee74fb7e890f490c90de"
+ "30cac976b71723e2f86e9de1d503a41bc81d53ccbef8ac405357d9dfdf306466"
+ "b4269580212e9d7132",
+ "0d89fcf844a9dc223d5f638dcc3a5978716f2628b8a83ab33e6e255ff8aa0157"
+ "8c14e3897da45aefd63fa87cf35e244bf4828ecd21950f3085a36621c9da1bbe"
+ "7ea62731c68d4de0a376e22dac2f548cd4ba4a542e710f55ce85a9c19593c08c"
+ "87d296d63587b3fe2c5d1165ee27744c75d8f4f14371637c0c0a446276289583"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.6",
+ "56f4ffd1279dcfe562a9ddd41ecdf60a3ff58246bfaf9565cf674b0b9075f40e"
+ "eac08f0b8966618a196b1228ebce93fc9dd79bd463ea7d2c974d2c2f539eafb1"
+ "b2bc1ea34d74f720e119342ff7131225aa9ada894b76b2ecb12f2f402844b442"
+ "5cf8f1a39b0a9c83b45b03cfc0d15fd314d6abf532b8edfcf236514b2e458697"
+ "86fefe27f54d666ee524e4b9c053be397501582991fa2d802c7d1b178b23e9b6"
+ "ece6fd2ef0132c0601a86f0768badc59c5cc33f24ded554ae51ae3ec23f9dd08"
+ "9e324a6821f6157f128442ac5807658ad34026b8fcfda6dc7f02a93c166ec945"
+ "ee",
+ "0deb397bf2cff979d4719c648b0a3525351f5e08405ca2614a83e56ace86f552"
+ "e41bb928de50f0bc0fe31a2ef2ad799fd3cf4742b1131a37bd08f2a13cacda67"
+ "f495c9f1a9ef64857072329f00cc4c012235599a83fc4594fed923034901edc2"
+ "7d5f05799834935cabe264ffc19663714d8c3de8e9619fd2842d2298f7a72c99"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.7",
+ "0e79ac9c9c0396d969fb3f7cc9947b078bac493b0352c8e0cde5463ea5c1184f"
+ "d52a1fb748193c147a74800d24f751ba935e19c9115edf072288330bf383f495"
+ "296be1aa4a5095b9573bcbdb228a43131237865d26dfbfcfef078f359f9a9562"
+ "e25b696385e12813fffbc8d529819a91451d33a50726392e4fef29418cca2c73"
+ "a068e60eae318470331a0f1db4bbb637173be80fea03c82c15d00193362d3a18"
+ "ad9e2f680500d7265b1557033a520977d810fc",
+ "733b7fea120ca5f0359a8905750c49c363d884f56c2b7a729fad7bff445a1e54"
+ "798941745393e1767712ac4b9dd2683888d9e68b905dbab87921851848727386"
+ "02eaf4a80f4595f78fd4a4610bf8220b86a2885fda24e1996428ccd15f2008e0"
+ "6851b2eeadc3dc8e03012f9bdb3ce0575ddc3adc7c5908498b69a797ba5829c7"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.8",
+ "22eb7dba73307c7c52a07ced89db8bc5394aed2272f7e81a74f4c02d14",
+ "9ea4600a1a6549fd3975f6498a04d69f96fad0e8e6febcfbe01c2f83170bc74e"
+ "b91f2e335338d583e885aac61424c9b266c3d2d98e7977ffe495f9c1a6ee5ef4"
+ "1a4cc7478c24b316c7d9f6dbaa65a4cadef181ca946f9b92184faeca8a1316ae"
+ "ab5cd3878c6df074f9060b9db66dece9a9367d7549035ac6bf1962365e1fd3fc"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.9",
+ "f680",
+ "51639061fa7b7cd5df64b30a394ccf7e2426972aa1dcf5d45eb8ec2cd90b9b19"
+ "6892be5fa03c43f3c3723ae3130d6151b33a637cfc50ba3526a7396cf8479c50"
+ "8c1811810d68b3880af6e64b16bd7079be9c003929512261898fa57c06ff7e1d"
+ "8039fa993fd2056ac7019b8dbcf2530d5380e601a4a1871b86c20bc1c489c5f3"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.10",
+ "650e64ed1da88bcf8ae27522be1d5c9919f2099dd632455f66d9afe8baf46cc8"
+ "a198409b0928dd87226284d669bf01bcec44376cb0e9bdc686acaa8b46348608"
+ "5994cafb5a8cfc33d49ceef479fc6e04f8eef637eb68cb57818d5f9770ac523e"
+ "d5b01638367ff47f",
+ "503e05661d681eca574e0230af2daa877b90516e5e19728c91768d6eefee001b"
+ "35419c5fcb5611d60e7ecbe3c95e5c88ba93460704f1694ae80444eb9718a08b"
+ "6686fad86e525990c3c1a66c8c53aa31aed8cbc40fd54f5ff8a134749d79d38f"
+ "bb0d58442678ff2f70c6c50f25472a72d63205e782423df40b6c43de03a18f8b"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.11",
+ "57f8ac6a9e468b7f1f745dffe39e9cbf9024a0ff36e0228392be6b2994291776"
+ "b89c0a4b1fa86b2ec8bb7c3e64f5585afa77",
+ "90be16b408b385739539b3b9a29b94c729385f79dd4a79811e6f67c80ed359e5"
+ "f4b2a19c222a82b3d6d62a903fb180c1f43cb3fe06a250bcb0e7c688665c8368"
+ "a11ab1160adb740291352b3838b6923a4a37ad06040a535920dc0f10579ecf48"
+ "1cd4413717d7d4d960aa751a743e2f7c616e542ee65fbbfe24660e101daa2bdd"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.12",
+ "80ef01aacc5bfb0db48c6de3d81495b9c2311a389389f23b70c024da4478bfab"
+ "2bfe4e546f13fffdb963894ec6dadb3d2b0ee337f11631058eac8609e5a1554a"
+ "f797a9f9ab478c2d5b9188c825",
+ "44c3f51dcc6fb2b4e70f537f5464c6320ad42e2128fadfd9a7e937cd65dcbf35"
+ "ac66cffafd39283966f2f15de527723550715a31042945e200cc5c86faba5ec8"
+ "abaf509c0ccd64d99dedc76e3ceaa8c447179337f4a0777b11526e472acd413b"
+ "4ac7c303cdcd84cafc025243ef006f79ddaf55c15cc4a8f15ea2c87f05773814"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.13",
+ "ac17959155283b0c7cff515c3315d89bdfe9587cc00120d3ab31bb7607bdb301"
+ "caeaf5e15f5a6f58c9c568ffb3d23402516ffe230c6981a81c178a8a18ca330b"
+ "b8ecafb481b249b466a8cf78b70d9e78a139a88f484cce7c2035b2e89d493bde"
+ "885e1cde42cb1a9449ff570dcf9e33c5cc77b259bee28305396802edc16fc5a8"
+ "e10b56da2da786b5fb6c812b2e175b696b1a9a96fc722a432146450f07a648ef"
+ "3ccf996ef3081fa5bb4221c913ba2228970c9b0ea5266bff",
+ "48458c72f067dd9ab720ef160cf3184bb9801e26d614a889a835844107ac0165"
+ "0b1184a00bcaa7af1ff7de3a2ef2e7ceb5b25c3b5d5bcb29865934324748c68f"
+ "07de174e1780a70fa24d6a3a9f7a41b81937c4984b2cbe06b3d7b44cdae9cbd4"
+ "1632d00943c3b573b1aa2912750a9aeb07f110130ba361dcf8f536790d607847"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.14",
+ "99098f77f6ed35c08fab3fa9788693671a5800dc303c9cce424616fa0c7ee888"
+ "8687674ca88ab22a5ff2d12e2b388b094ffd7dbf9a0927a9621717151e08ecb8"
+ "ade1559f4b48e23d31cf57cd3884dfe2b3e4b260e896029407969496026c74a2"
+ "1890d9a9afd2cbb8f2830a566aed24f016197401a8cd22c82fb8b22891845824"
+ "0a23d10185ebe772dc19bcfe3e44922fe73209c1ee0040079fb03b827c8217d9"
+ "ed7c98c95f30974fbe4fbddcf0f28d6021c0e91da60ca2ad77797ece86de5bf7"
+ "68750ddb5ed6a3116ad99bbd17edf7f782f0db1cd05b0f677468c5ea420dc116"
+ "b10e80d110de2b04",
+ "b46ae866139189b6b171a76205fb9ce041b40298e5ba92c2e9cc0bbfbb4a7642"
+ "5de6ce13021ae1a4a942299f98ff89f552f43a9073de64f49c2ca3620d09d7e6"
+ "e3fe28221e9368987e110cd6067106c4db31a03890236796c84252f56c95034a"
+ "01c5fe981e81b654855aaf2747501155720c2193f3a1d10f49fee90c52fee9e4"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.15",
+ "ff790642305bf302003892e54df9f667509dc53920df583f50a3dd61abb6fab7"
+ "5d",
+ "07563247734f3c3d7a3102bcb45bb5681568ed10f2ec459e469e1a9e3409a139"
+ "fb151b98d3f3b62daaac8b8f8916df85d6dfa9ab760df1e15ac89044e579cf47"
+ "a1af6cd6ec704ced9b034c6aaa90d0e70e0852140e7541f2efbe2cf190b95894"
+ "1ec8b5974f9c444d26c34316c9216b6595e656bc6c7844fac16c515260928e78"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.16",
+ "e99fcbf8592dbe2d7e27453cb44de07100ebb1a2a19811a478adbeab270f94e8"
+ "fe369d90b3ca612f9f22d71d54363a4217aa55113f059b3384e3e57e44522880"
+ "62afc08fcdb7c5f8650b29837300461dd5676c17a20a3c8fb51489",
+ "22746436164e63937871c1d47d8e3e70c9e52d1117316bb154cd552e836f2a3f"
+ "be6d89d6074b51b0159c26c28df75e3d7cfb7cf002f65d1ee521edc2c3a65c52"
+ "6c98c7c025fa8bb631470916d301b8f7809ddd919ded31a0d46683ec5bb44170"
+ "616eabcd970205ed760202d0d87a65795908b28d326f936213f29feb59773491"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.17",
+ "6a6a0c9b5b15bcda196a9d0c76b119d534d85abd123962d583b76ce9d180bce1"
+ "ca4af870fbc6516012ca916c70ba862ac7e8243617306f4f9ab9501199cef55c"
+ "6cf408fe7b36c557c49d420a4763d2463c8ad44b3cfc5be2742c0e7d9b0f6608"
+ "f08c7f47b693ee40d2e180fae1eac439c190b56c2c0e14ddf9a226bae17d2038"
+ "5d501955823c3f666254c1d3dd36ad5168b8f18d286fdcf67a7dad94097085fa"
+ "b7ed86fe2142a28771717997ef1a7a08884efc39356d76077aaf82459a7fad45"
+ "848875f2819b098937fe923bcc9dc442d72d754d812025090c9bc03db3080c13",
+ "419322facace76f2d5e2fbc19aab86c718a28064f1d7b4c662f0474a8777a959"
+ "bd6569538c16081c0f52698b2f001730c03b9a3d26947374c961fdeda115b6b7"
+ "daf66518f1fe820f67c3ff12f0bc3f1101e3911c43906b0a127e50be0140c5ef"
+ "c435e2957b442e60ad525ad70ac9ef61c3d64f0e566cbc1f9d51bae1d47271da"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.18",
+ "3b93ef4a555096691915dc23c00e954cdeb20a47cd55d16c3d8681d46ed7f2ed"
+ "5ea42795be17baed25f0f4d113b3636addd585f16a8b5aec",
+ "ae211f4f77da1be6af9c9ea704dbac4b3f3e270d2facf3651d787d0ebf59a79a"
+ "39612da12d57c4ac8abc728e1da3f01a1520fc9b32cb0ffe008c8069928f83e1"
+ "3590a78b817e819fbf2fd05893ece5b14186d901c768e342dc54722345ae8aa8"
+ "738d4d5970c5085472bd9899fa0042cf14bcedffdbc0ef50819075842fc36bb8"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.19",
+ "49ffd56bf7efc11304a5afbc19d479249018fdf4e09f618726440495de11ddee"
+ "e38872d775fcea74a23896b5343c9c38d46af0dba224d047580cc60a65e9",
+ "68fb0bd519bf6f96e076af29012f3c3a1137c0988de7b6fcedf4f51bdfee645b"
+ "897f17709e05caa0b113500d904dc0600d17a9ff8eb02e1efc9c467a24003ef8"
+ "1e727467c47dd656356d70372a15ea884121634b015d29511f2895557799079d"
+ "03c6d4de259b3b362b80492d81bc9fe8544463ec030bb5c9c73c3274e3ed1222"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.20",
+ "bc255af89a6a199bca4a391eadbc3a24903c0bd667368f6be78e3feabfb4ffd4"
+ "63122763740ffbbefeab9a25564bc5d1c24c93e422f75073e2ad72bf45b10df0"
+ "0b52a147128e73fee33fa3f0577d77f80fbc2df1bed313290c12777f50a334db"
+ "6faebf11081a04f87c2d621cdec7930b9b183a990475dcbb9cc7f345a3b55803"
+ "030cf0361a5d8081",
+ "41f652df79fdd26de95c7a98fa858713fb566d8b39928e71764b2beb198403e0"
+ "3b7e06dc960c505157bdf40592c4d77503fb72a4e0055f974fe939448da368f5"
+ "3bd2efe26e6f9a254b3e8732aad81687b361e21a40cf3e5e92389a2b489c05c5"
+ "97f0e164e267709372004327163562dd8a0adbbdfe3bc616bd08429684c20c69"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "d131e09243370dd2cd5425c8d030f99adb105b147b8a3d0067c616443b7d4b96"
+ "8238e06dbb5f2028e853574b7c14be1083c1e57e132c1df4a3a2713263fade12"
+ "f7114f4369bbf05620554841331ed811005052192572ceb48d662407fd3081cf"
+ "ab8b48c7e92d3c4a26a9645a38e6dee88bb0075975a4dad9646b21603840af5f",
+ "010001",
+ "56b531bbee1837a6946cb86c8fbe7cf6eeadccd2a4921bcebb34a3ae0c6a5696"
+ "3fcb8b5a703b717d032ee813e58e43695cf35547f87264c82dbafae844008b62"
+ "d9122e9de8958560c8dbb007727e7139e0a982e0758814113de54ba0a4551751"
+ "fca0fcb12d8de30d78b8b11298a7f78f0b088f1687053c84a5762f62a4bd05c1",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 4.1",
+ "2c936bf6133a9693f146ee5a1a91c2f169b2e644a518e85a75f6e43b560d4a72"
+ "f38c64f84c05240e8b4e55786163e7276265ba213ba93dee1b2e102135a989b6"
+ "248e88327e300361a74f2e9bc41f2a37683f1a1a15f9dd472e118e1c4b3ede58"
+ "dd70f3bacc252e0c654b0f7a6e41a9287510efa03bc92e805e5b2c913f51e25c"
+ "7f858640cafac9d3c917686507fa94f8866f869a4e5a6a3d4f9d97ed8137f414"
+ "d1447a86eef9e1496994ad2da597",
+ "9e93f7acc50fb3a0b1243dc338c8ccb12bcab4aa450440b6306c81b50b8f95a9"
+ "36dd166330c699b28580da1be275616402da85bfd8eefcd6993587e6092865d8"
+ "253b04081d572f262759f556dfb911e8d94e92e55af6d5898018ff33e5f6b1f9"
+ "901996e92faf336e2dcce3ab0a93db932e942cc6478d6cc2fb660811910ccd17"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.2",
+ "94323f7c38b995cc6bd85d479f8de2dec1ef2e84b1feefecf39150b5d9f2cb15"
+ "85ac0d719ab348bdc9750ddb8e3276db89818735bd6231413cbca2de941b55e8"
+ "cfa1ab132cc78aa4f2b51fd6578ee2e032e90e34080f0f8e3db14d1b56f3d077"
+ "f29dbc0216a41344998c0fe1ab412247df21e74ec22f5db0148ecaf473eeeccc"
+ "14ff9e45d58c2e62b5fe6a501ab96fd7c5eddef14aa89266692e",
+ "09402a4356be73449b469e3631e1b02307c5cac2ce1528d784fab926dff51f86"
+ "241b9d66f79d6d8eeeeb249d76fa9f166ff9a8c6a39e832d5d14b9d7ec5a3dc2"
+ "8f01ebb06e39d59e8461b955b2a7f5b1f204b04cc6cc62646161ac1c2bf5bab5"
+ "0f068c908d28de5eaef7e8ebfcabb09b7d75d83540dd4b354d131d86f0770717"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.3",
+ "0e233b2549bdd21ba51480da8e3dcef4db20e0dcc05ee237351edbc9a53c52f6"
+ "74d105fec0939d3699647efc1e25cb4e9b1ab752ab6fe28869ff73f23e01eef8"
+ "674c535c4c9335f798f1deecd489d06dc88fd6bc1d4996eff72b439e3c014dd1"
+ "4cbf17715c158943de2e6f971c349987a1b395d682c3b0c17b66cd3ca41060b5"
+ "7111e228314b2d34b5e44e55f1c11c31a6eb80b5f82d96bd4a17",
+ "d075be06cbd6223e871b0f3362a797de282da5c40323f37c2cc37465a1a86368"
+ "ddcfa6daa135866c3203d0472260b29c3c9b1b8894085d547c5eb931424f2414"
+ "0a5cba153bded4b9ce7daedc645d3980c5f583f76711c67b193a5212f2a9354a"
+ "6796af090820913134ecf305befb6532cd48d4113a0ec4869a0a5655dbdc7259"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.4",
+ "d47c0f5c922e4f809e9ceed207f124a5acde37fa14638e8fbd0a72fe45262195"
+ "8e37682c6ff283f3d51da152aa1f6374cd27d2a4a533053916dff1c07ba93631"
+ "7481696360690458d8d1e5d66c35f9c99a5055d9f7cfe7605cca57eac335ade2"
+ "eff6b5aa627d5b",
+ "11860bf4d74519ff8cfcce3d33e3aabdf77140a15636b2678df9673144c241b0"
+ "a99a0a37f292cad51df0b63b14f8ab17e3fa15587790fb062b5f266c166b2ca7"
+ "5157a0f9e1a5c8ec26b9199d07187799806a1de98715fbe52757a703773c918a"
+ "000c211a78228525cb52eb441b269b3f33050ed1935ac0e8596319ae80c75b84"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.5",
+ "bebd9ddea3abf9f8eb58559766f8b3ab83535238c43dcd81a2949303a95f055a"
+ "8340ceee1615e58df1e014c7552d769f8841ba09975cefe7e48dfc6a2649e820"
+ "03e7bf420e70101b327d9170f73e8d887cd298f53dc1bfc882cf0efcfad6e86a"
+ "0e7f9094c4f26c46921e09",
+ "84a26fbe67010aa1ef2d6c79263239b978f4e893dd1ec6f07d2317f151a2a1b3"
+ "23e505f9450c37df6b1bf3e24f38b636bf774e96741ffaa769cfd7a8a6b3a5ef"
+ "aba23aab3a437a225bd94186e91d392bed2ead8a78f381f40949cf1f3d272458"
+ "1f25704bdf6608dd119e36d87d0355e6706c8a5259fd60c8df13bc62aa9fd57a"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.6",
+ "9d198e2c6e12f74a9a081bcf70fc04168a49e09c5faaa011e9a09e2c43ee2cd3"
+ "9bb2f7e5682deab1fa111e41a3194a20a86da55101824d3d78a7e32db2b60aa7"
+ "73770b573907b409a2592c83f347febb2d5c85e9255d6dc12aaa335adfbb5dc8"
+ "62d7861953e2687d5303b686fff9634ee4d15cbcc29f7a3505a73deb6f9e388e"
+ "9685fff4d5450f1e3275359a2b99440c6739f5b91ebd14ef78ae73c1a61911f5"
+ "ae3a2b914967491727818065ee010df49d5a16ed8dcee848ae0948a2524eac7c"
+ "4ff9096ced61357642c5e0f80680afffce0ba7eb59589949526ff51235cdc72d"
+ "47a27b39b8d4ac849c3bc04fa836cf184bae0c83415956",
+ "38ef245b940d93970a503bf43e28e17b8aff083ccbe1e9c48e4d80f516c27d08"
+ "5ca2a4e573236a2494d9b997f812484812f66525d06c0a0bb2130c15d6ce18b2"
+ "2f3cee57097fc0d558afd9af27f151f8436fbc87d6be6142647a17e04df6dec7"
+ "0a95c7daa84ede94ccb43e1d2c37b945817310d14a22b5b9ae611448ee41bc70"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.7",
+ "8e8ba8436fe3104b7ce2a4efc36c857d49e849c0085fc657baa0331793b3f36c"
+ "7ce738b6130bfac75e5011f32aa3d1",
+ "7844699f1c4f296e50261f1526e0dd84f01c82cb85fa24609eb03358752c6cf5"
+ "9994d84e12f46a7200cf5ad97c08dd4ffc44657db57214cd1f4eed6b77d239fb"
+ "58216988c5e5bc735a4fdff408eb9f1279d65bbaf6a681924418349e62ff5e58"
+ "15eaea592d90d1eef556fcd4d5b4b89c6c70739d6f0d3d0bd16a50f1e0024e98"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.8",
+ "585fa6a7f77a4b6eba5690e73e7128b72e677cdb3aaa8629ed61f2ee63af1a71"
+ "ba87136a52db1a3321fcfeb248bf2e5cf5c639571d5895adf1fb0617ed140a2a"
+ "0d9837c3c1d8450c289d33bc962379d73e3087f2b7ee6eadd6650148c042b6ff"
+ "04482196c718fdc0ce579ceb62a81e584373eb937540c426b5566a9f407cfccf"
+ "bc4b753694af0df4cd6aa9f16546a63394a0f6577371343ffddb651a62a3a58e"
+ "ddec67a29ccae896563c63e3c90d54d91358adf194e6aab1f9",
+ "6893351c73915fac47c962cc6017ca74a5b5ee4cb1bb5a10ada2a43158a2261e"
+ "b27b866db39d3590b4f8d20ee67cb1a5789463150d839343232543c826505101"
+ "e1d2570426ab9fefd65ba84faaec731f27374ab10191c960831693f29a854c38"
+ "128599f7287749b0b48bf7e9dfdaedc84eece071404584730cecce0d5cf005cc"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.9",
+ "783c18b11f",
+ "132fdfb84193dfb79fdfe6babc2efd39b26aa20968a07c0e41560ee4dfcd4fca"
+ "7917490f24e8df84f4e0115a3e63273e7a3b128abbbd17b8aa5a06ba155ecb23"
+ "0fe797260479957010e44ba575292ec3f151abf48e9103e55142ec67a4134dd8"
+ "f38ec659f9a789fd0341cef2bbcf9f529b93218fc3e43a766969d1bf87884807"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.10",
+ "96dc98b0eb84f55948307addeccbe76439ca3658bc36359624c8fe2fa09c52e4"
+ "7acdc32a156d907682410a8567abcafdc6d8bb5325359ec75ffdb73ee0a9515a"
+ "4ddf9a31e5d519460374280ada30de7dd534deaa57",
+ "8fb43dc8f06f2ba48f19be5b1a0931213a990aed9c9fed1de5d6f35a2a782f0a"
+ "198ff6388d96e9d59b88e97822f349ff4164eea50a62935c61cbc76e3df75f68"
+ "4d962475e563596496c9880a48ed978a6315a345571791cb2ddc88dabe418798"
+ "a6a441c47afbb1cd15213eca3b1115ec8f58f877be8fbd38f4fdaef939f52640"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.11",
+ "372001599d9930c7d557458b436decfdc14d06cb7b96b06718c48d7de57482a8"
+ "68ae7f065870a6216506d11b779323dfdf046cf5775129134b4d5689e4d9c0ce"
+ "1e12d7d4b06cb5fc5820decfa41baf59bf257b32f025b7679b445b9499c92555"
+ "145885992f1b76f84891ee4d3be0f5150fd590",
+ "a897c7f972e11749e1e7c155ce9462aa7e1cc0a979c12729795126cb8c0ea502"
+ "21c426f1bb06c1caf7c51ac2fbd94d688da67ddf3ef66606e989a16de1f92b17"
+ "706f88e87d9f1469a005c9fd76788ee8c4a7f01209e28b86f674881af57db6c3"
+ "429b6fb45698bf5d3007f61c7d441178ad1243a49b2aa6029bfe902d26e42375"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.12",
+ "bfbfd07321f0f1d5fa9fdf0014c2fcb0358aad0e354b0d29081b233b43567750"
+ "bd6e78",
+ "c24d31049409aa16d3f972ef8b7595eaa007833e2bcdc7504852f2505fba1fc1"
+ "5f19a0eadde8335c7306fc3f51661da520ecc8db7f473885cabde93f0cebf1df"
+ "9e8a82370b00a043ad632cdcc78f3fac1d8a3757fc8e5241bfed55c49604ac19"
+ "abdac0c9c40da373c15f3c1bcc973ffb4f8b7b5b553ae075e1b1bdddd23d7d2a"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.13",
+ "c69739d22ac8966bf11c116f614b166740e96b90653e5750945fcf772186c037"
+ "90a07fda323e1a61916b06ee2157db3dff80d67d5e39a53ae268c8f09ed99a73"
+ "2005b0bc6a04af4e08d57a00e7201b3060efaadb73113bfc087fd837093aa252"
+ "35b8c149f56215f031c24a",
+ "d06d32260da2db48104fbdc24e16a65b48737d43ce243704042aad6c03fde5a3"
+ "dc0f2cc6e3ad68c3c62eabfa1f7b1cab009d1175aff77be58fb12a4e58127fed"
+ "63ea3df44181bda38c773c83b9e804bb3db7963263df30e92c4c271956e7e810"
+ "452c15e06e939666df0c8334033096c07dea05b44ebb142492e7669131ebcf2c"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.14",
+ "733047f336f9154738674547db02a9f4",
+ "c113c0465c84cbfb0fa1bdbc54c3e1068ca23e69b8391909c3900fe5b4e7e3f0"
+ "34c9a988a3ddc3c381756a1e1a27c1ecfb3a70e1ee0e920418ac4ab6d9532b8d"
+ "0959a653b4c508670663462b2e135816b694a6b9b468a29f38de53bfcddf97e0"
+ "3d8dd24f972633a49cf3eaae1d6962943860dd254340086b10357b80c1cfbf31"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.15",
+ "a9740b9aa0d34058fd3b906e4f7859dfb07d7173e5e6f6350adac21f27b23074"
+ "69bd0ce19549d0700120cbe51077dbbbb00a8d8b09de8d8396e36507fe1ef6a1"
+ "9017548e0c716674c2fec233adb2f775665ec41f2bd0ba396b061a9daa7e866f"
+ "7c23fd3531954300a342f924535ea1498c48f6c8799328",
+ "4fbd4fb23704f4149ada327fa53388526a07dd43d915fcbda9a13bb2a3738f4a"
+ "db1c3db26ab69048805a80c81605c96d68f841802f5abb02057b611fe2f39471"
+ "6265e545252c230ce474aff0bbd4ff1f3808496036a4948ca7a110ff26c638c5"
+ "0f3215b28a09f23af6f84cdc897898d0fd223b13481fe892b1a58ba2e4b3685b"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.16",
+ "af8f0887c219004d2abd894ea92559ee3198af3a734fe9b9638c263a728ad95a"
+ "5ae8ce3eb15839f3aa7852bb390706e7760e43",
+ "327ec9d0be7aab7bc959d40227e1d00481fc04011fe08fd5449b90c0f054e0d6"
+ "59b926cc812921c20a563c4abe4f825d6b5eef57b3e2d65d20a8013a50dd5c93"
+ "238cf049f2ff0c7ebeb8e8caf72e46e7cf8a0c3f4925616b1bc1826ffcb0bda6"
+ "0bbebedfd4c60f2788d1666fb84511853646c2dd466851fac85be0ed5ace5fe2"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.17",
+ "38df86557f375d09ccd8bd15d8ccf61f5d78ca5c7f5cde782e6bf5d0057056d4"
+ "bad98b3d2f9575e824ab7a33ff57b0ac100ab0d6ead7aa0b50f6e4d3e5ec0b96"
+ "6b815779a91b3a8bd049bf2aeb920142772222c9ca0c328c659e0a6437433cce"
+ "b73c149aec4a7480d5bbc42920d7ca235db674",
+ "3046055c2b8ef7fa92c8a9e395985bd460fb6b47986553944d21045119f7e761"
+ "7e03fe80870ac6aabf63b096cad5cce7f506953a7f693fe137adfb97cd458128"
+ "ae95c47ca948dacf24036adeaa48f29a469fb513191e05acf79e67a793a3af5e"
+ "4f9c6d0d01fdd0e0cd4296ad3da2ca89a50eedcd9f7b877d2ae1d58d98dcd78f"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.18",
+ "cb34edd5ab654041b6143056",
+ "1ddf48ba5351bed0795f55b306aa1c6ed836f592ba93cf0c46b7c273709d36b8"
+ "dff02abdb1a768d1c7114a86a457496da579e4d819f72a192e298be2152f7cf3"
+ "9d1e30827d0282ccf34dc8889f1c2f5970930d9735042f8a5a712263165d6e6c"
+ "5035e2e4a50e863c06799e3c89ccb5cb0e70b3c99c084030677a7c97907a1724"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.19",
+ "5b09ec88b1527178fa043263f3067d9ffe973032a99f4cb08ad2c7e0a2456cdd"
+ "57a7df56fe6053527a5aeb67d7e552063c1ca97b1beffa7b39e997caf27878ea"
+ "0f62cbebc8c21df4c889a202851e949088490c249b6e9acf1d8063f5be234398"
+ "9bf95c4da01a2be78b4ab6b378015bc37957f76948b5e58e440c28453d40d7cf"
+ "d57e7d690600474ab5e75973b1ea0c5f1e45d14190afe2f4eb6d3bdf71f1d2f8"
+ "bb156a1c295d04aaeb9d689dce79ed62bc443ee20c",
+ "af56fc329739e2f7754b6ca25164a6fa58f685ddb742b4841d73a5e2c4c45343"
+ "b74dfd2f0d370edddd36a017564a8d3ad402e2a341c972062c23814a00131e17"
+ "b1dec7b4c57c5bf1d4fa79222937a4dc5c00235f853dd23dc9757f335c85c207"
+ "eb074d4bcc243edaa7831b83135655e2277ef29e7aebf34a0f7b234a28650a30"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.20",
+ "3c330c1ef718c141e47b8fa859be4d5b96",
+ "0b1022dc38e217fd3b0e7ef19dfcb4b456366240983095f6db965831a70f0f8e"
+ "20e2dd2ac231cc379045c27365e73a53719bb6f011c3f8636b64994ca480602f"
+ "b3b4f0e2274b58b363e0d308b528e15859a91dcf99bffefbc8052241b974192e"
+ "636218f398332dafe8259ca5f5ccfa54c9b32b2735af0724f40b5a5d6121a40d"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "c55ffbdd6a2753bc02af20ae18ea0daf230bb6f8795d05efecc815baece22b38"
+ "79995f6d9764c1df8f97851381686266b8092fb6011898a76707a4d1d5bda08d"
+ "246c687a8bbafa6398ac9ea2726823714a0c3934ca6e5f8ce33987b534857ea9"
+ "f85cc4e19a1d2183e0e4c8aa55cb227b0e56ceb2b62b30efc78864b2f9fb9249",
+ "010001",
+ "07e3fa71b398b6e44147370b3ebbbca84fc25c223ad7d930ea4a6573ff9c5b15"
+ "fae682c622d3485ce3a4af11448f23bfef838e80bc327b87d5ba9c80370749af"
+ "c8c1c017546fc6b65931b759ca4341fa5e5e10b24087e6e2c0f4dbb790695299"
+ "9cbd90d2435fcacc9c82e48fdf24e495cff30ad419e7123e3ac942272e1abab1",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 5.1",
+ "eae9a40bff183f4114732e7b3ba556f4ce288daa83e3ff23611244a7a0901f11"
+ "7d86c09c33a5232bd320fa37a238a8aa62dd21abbfacdb93fa1c44cc55ac61be"
+ "a24a6a34cc6476753837e16facd82eb49e1c57c958fbbff568887cf82eebe961"
+ "e580e064db9cbec3b53df1f27199e49a04cbe59c69a265cfac8ce4f91ca95d52"
+ "b1145c8b9f4440b39c185094be184874da5971d7d763fe07ce16e57f1e50d228"
+ "6504b481e2c685bc9d9c01493fd3a6d8bb9b2e96bfdeb6c92914ca",
+ "44ceb442242bae085994ead07b709543ea2395a6e8d46473d70df34a9555aa56"
+ "7f4da138e963fe9286a84fb7c5cf8200035904b50c32403cae517bfa7fca8a66"
+ "fcfd632af747c49cdfb0b9aee35228b7dc4c21003969b0a013ede1292b65d10a"
+ "50c90263fb0bf4f4b8376641b03e1fafb883f038f4323dfe5beac468deea99c3"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.2",
+ "9de5ca46748561a0b928b260a95a3ed920adc8d5eeb9271dc71bc14f69ccd631"
+ "1d186a779f5eb8db17c690d6867cf3369bbff15fabb3cd2cfdd6f7d75286ff2d"
+ "2499c5abb48ed54fd4d849a9180e110e0a53a721398292110fe8be26",
+ "445ff5b6879f8ce75395016f0495f13135b179e73a3caeb330e3cda7f31f1dcb"
+ "a7aa82e268c935e9d7014e0b0dcea69c7b968adb17424a64dfd1e2bc5707f920"
+ "fc0c83cc63dfc74b963e682b46a22ac256ac6be5709c07cfcc3d4eba3a1d61ab"
+ "15f1badb0a49fb5cf09a1f7481a3aaeaf7c257540377aea7b54417a609c76f4c"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.3",
+ "183ba1a3811d625ca9da1bbaaedc76192012fcb674bb9e77d8f37708d240d349"
+ "e05797416feb24e3018c7a205d059de8e0ae05a8d7e09eafeeb9f06de5d4287a"
+ "bbef059bc586b21c82d64aece8d7428afcd7b22fc5d168bc076b615f02733cb6"
+ "3125c8f36d5cb809ce8065082398b3885a8919570c478a072f596615d78f0136"
+ "d11be32b3fe0f4fbe3c7da5d81341910177e48b1bbac276c12ee815465dc67d4"
+ "5324f905aaca4838d81f7431463e89eb8b9536586936afb42cb47bd8c31829d3"
+ "1ec1ee29f91ccc6df9cd1b0b9b8646b60267fd7eceae92c0ae9e0ce5ff6f7e0b"
+ "f756a9b8ffc9c616",
+ "ab4b78964c2a35d32855e0efced34bf80219b58c488ea375b1f327166a5135e5"
+ "da9945c287297a3d932e572746f022748b85585a0abd9186f4ac35edc850d2fd"
+ "8805b9e9f51a5adcb95e1ac1729e57b85331c1ed15c3d0cfae33f61c119b55c9"
+ "5e344b72f2b4f8e7e8fac7a33e5b8b276a6088a7fabf4fa172357fb6e3f44a94"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.4",
+ "8707dcdb49d283a23a9bd6ff87aff834f06ff7f47b0e5f57ff1a0d995bba9cdd"
+ "5ea01b42b25d6ff17a0dc10605cf452aca73be54ed5e0ce21566afcc17912abe"
+ "18dfacd1bc03e3e2882a4bb3a4f39eeaf963d7c35e6ba858b1376a075160c6cf"
+ "aed5e8c52e451132347219bd88893eebe35659a0ee4d94f94d035b7a8686ffb4"
+ "16eb99fb2aaa81236b05ac4645925f2c2bc19ebe89a63f2f451d0b13b2fef061"
+ "e530a349baf3b2356422b095fd9f192993ab99c9f9226ef9a7b3cfb365820859"
+ "29c876b5e9d7c6acac7bb0275234e41ed351c838b7a31a",
+ "1753988b39dc745df9691af9ee69cada73a9877cca12f6d40627dced7622147e"
+ "c901a5b463e7ef9b37fbd692785aa22a465df403af92a29f795d40a83fa964b8"
+ "5a7ec05a3cdae3f8bc8a61a79dc842e1d377bc5e1d46adaaa866be282c6e2388"
+ "173644f40627bcf8a0974a4be8fcc48aee7e8259f868a2bd789a908992056e55"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.5",
+ "ac9fa3f63df068e90d692eccfa7d8796491aca795b9858a45518623229af28b1"
+ "3a502d8cb3b95092505882eb994de74659625698a0050417940d8bfa28a3f93d"
+ "149ff8b0bb3926f618ef91966f4d39bdba5a0517ddebb16d2bc4b4e33a7d619c"
+ "95a33cf5f572dbe07fab4aa67fb3f39aa2981a3dc0caee64758ea898ebce10bf"
+ "3aa4fc8449e8e0cf7e88b188238c2068efacebfeef4073a654a58a3099d036ae"
+ "ee2d818298d4ab39238edc459a9fd3577e9f5bfc0368aa657aeeda1eeb8ae7f5"
+ "ac1eaf3b1c95817dde2ec1a59fcb5ef27cc34fb75331da7a4996925ac3ad17bb"
+ "c3dafe6a9c644e3098effef8fea5cc0d5f0c048e1088",
+ "11e1a828f00a987e03d62e2a536c297ddac022e063ee0de4e4695ded1fdb2209"
+ "00a3ac3f87d1be75f959c28b578a43b256643cdfff921595fdfbeaf410c2aed9"
+ "e5e47e1d151ae28c7699aee225a645bc42b3beb52f08387ec554d0204d283c3b"
+ "ccbcca216edad94ec64f9c20b3406ab78a6c4a4dae3fa617a00c6ab2f8e24762"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.6",
+ "1574697344e98685cd6e65e46783f0b5",
+ "3b7d67d13cd3c0fd305ad404d8a3dcde4a45179c2d0b87115d6d060c249b87f3"
+ "9e463b764b4207c48a74cfce2531e8183d3d012585ce5739d162c4ea22324402"
+ "ea2e6eafb8a573fcff4015c95c45e4ca7ac51ae3a06f421e606d683f5e122b55"
+ "79148a9c466adeb02428f4896a86df63be587ddd7a6a8de7176be4e7ff4aaa99"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.7",
+ "be46be8bdd8543d370bbb7ac839f5e6453f30cd8752a4b926732c59e6109044b"
+ "e3a0756c7025a23280df2ed766ba39abb20b944c065fe1487dea31b4708a689a"
+ "50b28d542994cbbb3a5bb9460ee7a9c1538bda751a528b7670f91578d6673e08"
+ "abccdf5f4d8c1ebecfcac75cc42dbbb8cde3c1b474b556b32bb848fc327ba6e3"
+ "cf5f77b1ebc04a19f3c8c39b6b847784eaa325a2b6f3",
+ "91de2f903247b2d13abe93ddd96dfaef1b4d172b090958f0cc34fa92835ad60c"
+ "44b427fe031cadbf92ff1cd0384144c9b5f28f645c63e8d716bcec2e043bc396"
+ "56641785c26ba36ba2a109e3644ebfd962d7a316916b3f13662013cc0f37ad8f"
+ "9e0d9ec8b4c8ad5c7532cfa044aedc73787794c298797c8a7e1449ead6150ded"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.8",
+ "0b7e0663e715ea38bc930ec9d8e2a029aa1a4c95e7b20047ae1544d5b2d8476f"
+ "c805539fb0efab7d5ff12c36d76a797b75c0b53fa9265473dab680c255d57e99"
+ "b6d9fe08cf1a573491e21978fae9539cc05884633a1dd5cb21536fd42ddd731c"
+ "a76c3457813ce1bb59c21dd31bf2ae3bfd7d20c6c712a9dd43951f1b198deaf7"
+ "4108ead22926d2b0191e59d5f679ad97c71edc69de97987e543e87a96a9fee77"
+ "e3f0ea957bd46a",
+ "4851098a85e70da33392a9e90b3476a48ba0e32cd6ad3dc1dd91da57e88dfbc7"
+ "b6574b08e8716080e15df40579c5705d5bef584b08b263dbc4f0d15956ff1125"
+ "c48f89591ebc941d9fe8f9a780c82ea32bf3efa16cabbee580fd6b9574080f69"
+ "07feaff81d48c49a6de2248480f1d85239e9a418dd5310def776e08f509a1478"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.9",
+ "134233bacfa16dc84d8fa4bdbb4793d1dac07d6054bd083961da68679ca37533"
+ "4f0920b9dfb8a68ed77f27fd9219281361e09fa6084f96e69885b47ea775af06"
+ "772d6612d4d16f4a5cc4cd0d1eb23b7a1f09564b842ea07cbdde60453a2aa4ab"
+ "69ddfeb5b13e9f08cd072e5b71ced334ea704c749ff4727ebe12c0290e00a841"
+ "d74b0655cfd8065d2820fdf8fdc1bd455881808bff0ec727607475bf0b2bc893"
+ "5958329b778efce560fc26c3bb6e2dc9aef18f969fba64745ed4d85b14757bb8"
+ "33eadb9c5cb0eaed08d30b9515005a3e88091fc5cd2f36ad955b7c6f2b19bba3"
+ "74fd",
+ "3e37b42dbec129db81c5e2a222f31e81b937ff02249518183730378b4c092aa7"
+ "f3b23459611a824fc52754421a27cce918b62aa7b44638a0c082798052a58846"
+ "6882510690ac773023280246c890ff1f6227049e668bc9d6e489b6944a34e8f9"
+ "3002bbb00d752b577ce352530082becd309b0daccd1d68d06e1df71221c62269"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.10",
+ "35da3d0234bd74fcd76e8e69528f651b88271cbf16286938c2c4a37d411de8f6"
+ "7578eb8b3d20a8fd7dcde7b656fe96a680873228ed0f9a620f1505442372f9b2"
+ "b4168498723490f811f3111f5f77386347b4822ed9d6b5538392215cb6c4865b"
+ "b7b5b7e2842eea0e9001ca0cdf5d6b",
+ "12ff2ab5fc83d649597c47bff329b7f461dbbbda01fb6bad26543e4dbcd60c5e"
+ "2cdebfb112784a964e27f2a2e7fd07ec390aab1494370358a75b5e1fa4f1ad52"
+ "02e6d546c0f315e86faff1d25b947282da32eab56c22f06c8a9d32aef281d6f0"
+ "aa55d7ad3bcdfdb209a16ef45cc6f9682eae963cbb213adb7fad1bef49c0704f"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.11",
+ "75fdb07273f754d1116f997af2d11a512b94e9e04801b3fc739130b747b4be87"
+ "44d7e7f8a297a089d9050c5f54f8a39aa3f2",
+ "07ffc1b7a10ddaba9605f0a3d93c8a5e4c0b77586139050731d9cc9b3c83d2b7"
+ "3faf9a4e24d1c8bb0d623df10fc8407d151448fa43ee6581e7b0ac80d14adfa4"
+ "f6d27a766750b231cbc1c5cfd62df1b9727d8b8741469f68e50a9b3bc7ade137"
+ "db06747603742856d5e7ddb4e16a5b49d7365db2763bf5fdea083d81fac92d87"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.12",
+ "96c9facefba2ed33ed8b7b3d8b6df28f2fab0dcdd7a3cd7a7deda2545ed4470e"
+ "d25b46d2166eebb7e147101783b645bac62664b8727009f35d1ea5fda5e7c28d"
+ "6af6fe92046ca724cab8425a52a085f9ac9083d4d690bbdddfd0a82d948f70d6"
+ "85e26bb9f527408abc847bff1202dedf6d2fac6cf3682a516ba72f4fe97b9046"
+ "6af6e543123165b8a683caba2fa23a86ac06213065e1ed9b4f49af4fff6d46b3"
+ "6d133d8da2dd29d55f9f322c40785ddc21c426c5e0a67d414f5ab971c4460ff9"
+ "b114305a8ae7e7b95c73034e8e93c03529dd50c94f076279775a5a3a80c5d248"
+ "6a2d510848bdc9b852ac1d32ceb7c041a08f2f8e62",
+ "46d03faec4a72318621ef4d0c1bca71a2aeea7a81df8febb8ba3fb3540d72d15"
+ "34b9826916e89f27d325676ccf5a0aa16112db2d9303e0ebce4b85587c55aca0"
+ "6850de84dec213d1137404a5dee6ca88d91ae28b7b536c90202bc7726da5042a"
+ "8508d3b13cfbaadcee1278d35d303acfee6e0741904911a5f18810add3e7b8f6"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.13",
+ "c4b4c9966e56f40aff4708131cd3714421343ede70c4d46db6efbe1b19a9e3c2"
+ "e58106008a983859cf942a319774695a0c98a963e2fe9d9379bc",
+ "b16b10f2bd7ea0f76a9ed2ffcf3ec10edcb82460fe5582a7764c0c5056ecfb09"
+ "720648d5f19b3deaf2acc986460e7114261583a5f4a990e922feb5b4789734fd"
+ "cce15ddc87cac3f6c7c9e9e2192315f0841f43ea86dea9a9380508b06c9ca5e9"
+ "d4a651d01216627c466bf0d6ae744bf30fd791a8210339f5057ff85ceb84f196"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.14",
+ "b838a5d888950f1b8e4d947bba51aff9bb60b83d09ed9d97967a76955ed1ddf0"
+ "481520bcf4f08bebbf899cc7c3ef0c04d5001b1e2e845fafc583300c98aca7a0"
+ "3e90a434de77fef720da3663f21998208a94f894767d3ed81396b7efb286e0ff"
+ "7db6ea8fdb4e72834600fe5f7f150a01b1d4a08b5ec9ee1fbc1001d12d5236db"
+ "f0727e7ea36078f3ebac5046b765b4e23cdcefd115d62a50344dbbd7428d48ff"
+ "c94b11e21c",
+ "b15681eef296a66b9fcd6630f89c55826a389e0c2d3d476a0f8a1e08cbcacc66"
+ "02c714438f32f34e02c36e5c0f168ab028917e9050fbc850f0cf65d5eedb3b54"
+ "be5495bbf0faeeb32bbe5a8f87bbacdd2585fb907b13185b02615663d2011ef2"
+ "3d0ab04dad1ffa679b53152c9c42b84639684eaeaf644e4fc6ff2ec7d47ba5ac"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.15",
+ "9fd539c8ad864924eec1d655c07d1f28270cdb326b572c4667eca6488c033657"
+ "ff29254b91f3216e1cac979753f223b179ea5f9efc236d401d1b9a3c20eb2afc"
+ "9bfcfd0792acc5b00c9828a645",
+ "38bfdfd3272e48cfee68ceb91304eb91ee25e483401f30fe12d5e43518e4b771"
+ "14a12c8c7992aee7d2e774fff91d8fd1cb7c6a2adf79b7c8ab93e8374db74c26"
+ "909c659a97c76a222df4fc8c7ef5199080eaae2d031ca751c5013289db4ead77"
+ "b28b76a4c496ad0eb422fca88fc684e42aea88fd33c256751ba066834e77a1e2"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.16",
+ "1de807409d0a61b0322dfed499e8c33241ec89cd7d9fc5",
+ "8b6664f869d755c5d3e6df9922e227c110918a6fbd88c1a2e1289523adbbd8aa"
+ "431d0786853ab596dd5b001243b54a2cb10c3166bf002338fca20345aede1b22"
+ "ea1fa3d241c86c76bfc02f4fceae12c8a9d7e44ad6171665e88f128522dd535a"
+ "9d65008f6a732d40af204e220f1facd942e09d15099fdc51b3a1426cb2dd3293"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.17",
+ "4b2bcb2679a14c3c4c069ed089a65aba29f22b6178c0",
+ "1c47828ea53fb6436e9596b0ce47d9f38b5deb0b197c1bc474e2e8226570cc1b"
+ "72f239312ae7c3c6382e1d8cda7d4f12febad70afae5acbf2428abc04421bb4e"
+ "1e5990111b9ac83c62435c21aa25fd9b4907585411d253ba9b8778f624053d46"
+ "fe95d7e22ca39381c7792eff46438fbc165ed7629c2fc1cef1b34d77768a2055"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.18",
+ "ef46ae51e0158cd0ef9c78d71e001567d66ae3c5e9a64f245715c7c2ad8eea0f"
+ "9d320023072fdb0fb86a45217fd712cc80e5b94147c45fe00b692ccda1102598"
+ "41b2c7e5c3dcff5956f2a596cda68eb77f4c8590d736b8fd6066773ef6f95a38"
+ "cd384e9483a89dc2b6c2e8745c95c12fa672a1becfb63eac9b553eda8d293754"
+ "ec3947eac0228de26314b59b66994cc60e8360e75d3876298f8f8a7d141da064"
+ "e5ca026a973e28f254738cee669c721b034cb5f8e244dadd7cd1e159d451d4bf"
+ "6580f3e69cdc0271382e8dc14bc733af38992c1cd882c7b150d23a067b9bcf3c"
+ "cdab6b0fba132b4c1447c87c393f",
+ "8c1de15ab86cbf5bd9317ce2b8fc82f5722db6961c9f555140f78ebda24e3f51"
+ "fd7301c1e4fe12b6957c30144fa1e127274603dc02051130b25385fc8646ee96"
+ "a74550d2d63f858185bb984652a3431d533da6014622a64e0691662a4f7c9d58"
+ "319ba3f85f19182475e1509bbf213af01010b4b9f82e647511fc97c6b7c97e8d"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.19",
+ "f87bb12daaad62c864ac3d444d514eec6e59b67cd0820dfcbdf851ea73891f58"
+ "a8be6e843ee8773e4dc1c7d742da82ff16c1011b99566b9f3fd17d68d5ac99ce"
+ "f5a3a0f75318769dc013bb055be13056df49a839b8395251399b27a0bb31c554"
+ "aedf3d9c7482b6620c5d7c6914a564db04a000045699ee1e5088a5b68d814efe"
+ "9d130dc34e2bd97851139c73460765b1f2654686fede9c9b3e92409db2d42a32"
+ "ba9e20bcaeb2c4f9ff9b0e834b7492a2b1d8c65c8ba498342ae7d1d9fe7405c2",
+ "207a348cdf684aa8e1a4af7b7c252707ce6f1f9db2291f2a95a0715d9c7fc51a"
+ "a230110b5b518a9c8f958dd20c7524d5b65106d7421ba9fcfb789178412c3640"
+ "f540b81bb31897d2645ec79d8e5975048e452261a1c2009cfeee0715a01beefd"
+ "75e704b2a6f0f0ae7ea36c53cfe36f57f034e385448fcaab08dcff477d36ff15"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.20",
+ "4c4b",
+ "1cb6881283dcd1863ba79dfb22351bc9a8e0358b2f8a1de3f9065d8ca859314a"
+ "e11213a2cc87b2f632efa67d2103f38200b9193eb8d49982099afc74428f4b41"
+ "316f4878b3f600bc2fb30458cc9c2a034a068e98d57ae79ce3e2fc84b6a745f0"
+ "37a5dea2b9da4e8db4ada69fb82d20a41bb8430793eef92a4fd6186d179663cb"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "d6311457e1caf1224436697983c86dd338205862d2a105baf7103428fd8353a1"
+ "9b7ba4228f78b47f7907357034c52d8597da2b5d13dc535b836c74130a364891"
+ "8d4a7a83990c2e28816aec0fca01d105c6c652ec5733d01f0058b2df5ae67333"
+ "405a3a5b1220a26ac3d142f2b4d837eb7386a40a74cc3d1e4fbc64fd7da63c41",
+ "010001",
+ "5ea61177442f899ebac5d09601c5efc2066b44a366b000f83d74cb97d16ed6e5"
+ "f2ef0ff8b5ad81155345fc37391a68a340170852791443418d31bf992a4a1286"
+ "6fe9ffccdebbbba637ee887b716caa92e249ced657eed71f5ccdd9163f326952"
+ "5d789f4b33c48a95764436ec325e8689691c272d90bd88889851372fb8dcb9",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 6.1",
+ "8f750e65951b5de75814b0b76630dc9f1c6253a0590eacb5512a8a4e1a8be852"
+ "5d36941fa9d092f6bb4422aa8c0ad6423ea28c10caa6e954b79569d44c860f1c"
+ "6581eb17a7543e7bf7fe",
+ "b18b5ec88d4e24c914b665ff9a2c75f4e91937df8c19955943e451addf3484e4"
+ "97978d26da231af14d9c2927ed210afbf9dee33267aa45684649e86fb225a053"
+ "b5455290c320e3f640623c75ca423721f280b887442497f32a90d78f64440477"
+ "ad0927c7ba01c44da9d5c283a438be0dc580a00528fc65e204d42a2d4e2913c1"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.2",
+ "bdbf3b364073fe048fbae55e3cde668e84f753abfc710b8cdb7b6c0cf82dd5b6"
+ "74d21e2b3e36b1b0360df8bf7e6227c92e15f3d784",
+ "66acf043bc6aae81a4d52b4e8c40128b25c6d10a8c698c83aed71e8f3583898b"
+ "e8f4c9bea4b63190e21526caf83ab14a4f8bebe813a5abeb959567bb2f06c5f1"
+ "1e464b5cdf7b2a132d426ddbecf585900a0d8092ca52b6dc0abc35f140946989"
+ "46e1cd0ecd6bd41e2c6f963ee89c82193ecc5fd47630d34ad16ca2479eaf062d"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.3",
+ "3c5c74bc8fae807ae58bd213e6272aa3857931575c2aa2be4bcae4d79ae087b6"
+ "b86f915df8c096c122edfbdc797f9d70b9761397fce3d3e0b8a6f256dbc6605b"
+ "a948d5fbe6f5245c0295ce5dd73bf7436517f7c4222d2cfd8542e7a100cf0513"
+ "04a1ab6fe005da077b62878fd0b741e6271e0d346b20723b7e00b3b8194e1a46"
+ "0c6bf25600768290c1dcaa2f41b941a64fd90214d5166d78aabbaf7e41d24ff6"
+ "36c9762fd892199d2cfd9deda50051e001b9fd3e5e2227aecb15c1b31371b35a"
+ "78b3b8b7636376f134562b4e52f451b741a19ac932569ff3041faf12279f90",
+ "5e897f879ba46f67112cd7c7c6fb2737ad793a872879052a88457af5e9d59959"
+ "a848134a6824de3a674f72a906879e95be0ed87ea9f974a7a07ba9adbec2fbfa"
+ "0294378b14e735f55f403ca053084f51d3d342d8af9c64b4d154ad9aa3c6bcaa"
+ "ce1f1bbe62eeb5d0e6c4c03093c2af0f07888b8bbefa79400323133f776a3213"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.4",
+ "425646650d6b379e16e15bf3853ddc9d444f44535c493a3703b00163af3476df"
+ "372a5b28f334c0860313e8136de608291b3378381b9e21ebef24825d12",
+ "a6a0cb02481af248abae89cdf4161f6776d47108f18ec6e8437c224a14f452ad"
+ "a136520f0fe010a7345af1971a02e4bcf8c98b26c5b8c6003de4d2b4072d8def"
+ "1e1923d9cce0a675141d37873e5948ea6c8a780ed2a5ecc2ba9a81206c7eccc8"
+ "0eac026db7d760223aa2387a182e98d66f1e23dfeaf3515cee4fa1abd464b768"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.5",
+ "f47d87bfd488af5b24db34ad0c131efca10cdd1aaeffbe6e36484722ed6809b1"
+ "d57a183ba03d5e405d1256b2505ecb84db35dfa94de85dc2a1588b6e83124cf8"
+ "6c5e9166860d4dd47170432b08ae6a6e30871086fa",
+ "6c008ff0e128fcec265f379eb083db50624a2798f93367c6d16e5d95a989f4f1"
+ "eed0cc4cd861c6a524f2b9fa30e886f1477741d7ea8a60df140aecf3a6ccf004"
+ "3dab92cbe72953cb1c1841e05918eced5b0f694af9a98ec7f4e2286d233dfd35"
+ "132a0b584bf0e0dcbf05119ce2e3a4d813cf028fec48c34a1881ebb531ca489b"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.6",
+ "031878d588ee",
+ "cc154e1af713f2f95e16f411175d9836ad6d8bbdc8f98cf05cfa0058235d1fdd"
+ "e04082764c29dcdcc59ebe26578bf9e8ad6a5aa86b9d62914b4cf696a8ec2da8"
+ "79f8fa4231463132ead7bb3be750ae0c5628a396b70adfa27b403423b10018f9"
+ "d24fea337030147fbfaa15d47532c9257c2c7f541b5b974d15dd1e3fd2e20a69"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.7",
+ "27263852eaa960bf7671876fc7900f898ea82eb2b0fc418565fdae62f7d9ec4c"
+ "e2217b97990dd272db157f99f63c0dcbb9fbacdbd4c4dadb6df67756358ca440"
+ "115d3e5b3deb1ba1bd90ca1286fd100caf9be485a44a3845005718104bbdfc5e"
+ "781a9e37d67affe556dca10f8efa39f9cb6392a72e3f2825811a2c05af84af9b"
+ "e7f371dbd4106d9f",
+ "94798d179478bfe06d96a34ac99bc9d5de35dc4697ac3f70e9b34c95e22b1c30"
+ "d1426be3508e622c1a18ab3c4672fe3de340eb510fb987b53ae93a59af6b00bb"
+ "aee0e82708e6c6ae82c8455324017836db17660d069d80271e1ea9981163b14b"
+ "66876dfd128f09cd2e3d6a36b73c3b40ad8e1324849029c8b8e3c8894ebfa194"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.8",
+ "a4fb2103d0be290e996016a439462e6bbdb0724d86cd51859133ca3d39dab77d"
+ "a2069d82835896387ccf3df5cdd7a5793f223f3d923ea463513531ada667abfe"
+ "f75398c7a4bc6efadd4edeef35ab8f5401e0daf7c2fca1cdbbeed3bcdd0933ff"
+ "3ee4c5e288abdf219e36a3ee6f210841a03c9e3e4dac18122482ef85f49fdacd"
+ "c502d279f1577be77a4e00b7c7f17ba5da6b28c01a07a863dfb21c156da32001"
+ "f53d7ea3fcb8c9554f075459a67cc3c4e69a6a37178787463cebcaeda6490a8f"
+ "80b392def9f22a4f",
+ "726670c9510b58354c8af32b41db8f692107c0c876e55273a820a0c30d392446"
+ "0fa5bc33dfe19d72e56349282a80fb12a8fa9ea4a5da69c582d7c64122a8a791"
+ "b3212c39e028265b8454df715ba30b003d129169cf12511c0d3e7aaecef3792c"
+ "f185644cf80e448147b1a7961af384417d182c6f855246dad5b893d9a7680ebc"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.9",
+ "e5506e04b191841076858725a9fdd8f9745f242e99494a423f80367474271dce"
+ "95a99a2f71134f39fb3f2e47c6a0b2fb6f615b0dee6df33b28f8b0d41e92d142"
+ "b146e8cde9b11d6ec1d37d71fd82b719ce1addb821ca4cafbd2aa4f1e611a259"
+ "e5f05b531fa11e3b671b7a5b10b4c8156c25b0a59ec6e158f6d346d84804fcf9"
+ "2a72768f4ebc935eee5cfec7f6e6e83cbe158a13275e84183a94d724b0e96696",
+ "34220edafd4ac884b9d00fbbfb71a4a6c4d4b71c198422050799d0c0fd54e909"
+ "a4cad2298faab3347a0af0d27d5301a886009cf5c6f125dfc1131ace388bb214"
+ "c2844420c023dbc8b4a96611b3b393acc3839490fc4ee2d369b8c3c876572283"
+ "ef34d70c6403ef9e2e87a276b23572ed82e2402267c2737f75bb4a27d3cf16d2"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.10",
+ "8fc9cfa721dfa09ba0729ef9189e5427b3e738c5ae38a2657f7c7e314a49caeb"
+ "a0fc9d4540f5f8d6c04753600ef6b9c3396540f86c1175b60bf40e3d8c845135"
+ "5e1374f43043c0c6aa41d3796bd8279b3c3062b374996b7eaedd4db0aee8c94b"
+ "93b171fc411d4dfc3728d0231558cfc8fa45f951b35c9d461218a650c702cea9"
+ "3bb3fa1436ed445c95249dc220547101b9a93eb014cd843ff39ce4c96f82a39f"
+ "863a4c2e1fa9",
+ "a26e7dbd5dfe08c72bd80d5e2668d5d72abb1a0c0420ff0ea86a9c7608c470e1"
+ "c3f72ebf445d12187181415558dd03ebe407aa06b51647bafe0c85f3d3b8dce9"
+ "0cebf0a0eecbac1228e785820c4f909d2ef392f03117561ec38eb0d88b023272"
+ "a4286351620f21043ccaf7503684002957ef79bcff9d1c201c42e0960bd96979"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.11",
+ "961fe34a212cb0e6f6dcdecf1a4cb7b214390a77f44d3a3b3ee2b12f1f0ee314"
+ "2e9eaf708955ec837ea1d0d2954e6ce950f34c8730548f2e095d5dbb938b190b"
+ "738bff81719302b6798b768b0bbdd2e2b9672d891405c771a77902fd5427425a"
+ "f04e21b91c5f39372041e494d9be62dece31bd8a262f6ddb849f068aa99f7d62"
+ "62e184ab9cb1622447d62ff6710920307071c272be0bb37f0eef645f99eab51b"
+ "0bcbbb6487d8d2b49f3f23e0aa918c89ac855653e1ccc00591580e0ce1e38779"
+ "c04be7df1c6663acd9937e472b3eb6d4b70a080de8e03548f51245be7ce0b86d"
+ "eec176e00e54bd63bd5bb02fc954",
+ "98ac477359159e93e1b336ee05606d42b7e1250d129560c0d095f8f8ea3c0474"
+ "32a99c1ec4bc887d7f07f61df16f0c09f715b705388bb8a61187346e8d7b07ea"
+ "b2fc05db89e0300944ae3773e44cb92c5cf0f4fbe01a05ad79bfaa247f83ed1e"
+ "da48baafd1e180078ca8d321d50b425787f01243a493374e84f5cd56b753d7ac"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.12",
+ "96ff0a5ecac95116bd7343795af83c87ed9f8345d03f6f322f295493f40b19ba"
+ "8ffe2c898c7b206621f72e02c7f0f00f9f1c523d73d335a26ceddc7398b7ca20"
+ "09cacbb18283b76b2815d1e90100096e95b88530f1c48c3961c435bce0289ff6"
+ "2e21bf4d3ec899c87e14c8ead7922e795e3e6f4180c0899ea0",
+ "7c7b0157f6a50909510963282f00111eea70193754e427a02b346feb682f4c71"
+ "87bb381d31d23b94768843245aad5361fca42d8b284c8d92e6fb992fa7712fa5"
+ "a93155df020d300a3bf89886668cf37bd13b550adb2d2a86c69daaacdc5030dc"
+ "84343c8b4934f03cdc0eef0f6c1ea7ec0962007903b448217de93b7507549b2e"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.13",
+ "32a12e0c670ed215ae5449a0917ae95e23db803ad28a1842edfa90bc405dd89a"
+ "1b468acebd08fe9c693d8fb105e8222eb57f79e4b22700e07f276d4aecc7a15f"
+ "b74733065627b879b016eed4ab4a1c",
+ "85b90eb826514a0ec0fc1bdc3486a8dc8b0f263efe57cf1750a42a6b5b997264"
+ "fa617864837e639f45d9205841cdc134abeacf6ee0ecda09b98d769f51f3947a"
+ "33587ff0c8dd01b7f6b24a2fbf29c9fff737eee56ada2ceb746b025d956522d9"
+ "20d12ddd13dba08b20e1eee13a8b2580e592c34e39333766115a23b9d00e2a42"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.14",
+ "bbda73cbe2bff7ff5362ebe932c0a0dd68ac84ee998fbf59a2a9265520323163"
+ "b30d9e7008b94b0c0ebc5f6c4c973c13ff153d31690c3c95ab231f0c9ec998fb"
+ "fcadc28b2d7f06507e17d21e82da",
+ "26f952b657fdb9a11dc843790c9d2a6a51c976101efb82d053606762aba33af6"
+ "280bde3815e0874d6078753842e5b1c90cf7991220fcfa62284943690c301e9f"
+ "c6e479af68b9694785be40d46986a62a121aa9ad0de969521f1cb8e7c4bd70c7"
+ "c8cd7a9d1354e7d0aa0d85d6d7aa00e4649026d6f070f8b3c27c98556beaa4c0"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.15",
+ "2c325ddaf6526a1ea3518ee5e5407f0390e0ebaaa5f472a1e9ab46f746d71ba2"
+ "e217faa81799bf358f95e98308270b18a0019929a288d0c956e0bf17c5198ceb"
+ "2cd9fe40d702a44e5645eca5b439abca7b2c6f95acc3c2c365195c795e91d63b"
+ "3c0933244ff12563af6622a40c7415db60a78dca0260251439538d38aa38289d"
+ "928886ab128736a6a8739c1455c4849f2d5456453793",
+ "6d1f203dc3ffa7a334d31b9a75e012581b8d62b2bf73800be51d026533998318"
+ "c0cac92a02d46d759bf80a41daa0a6a29f4fa0bb60664cacade24a65cb476511"
+ "09beec8231919525d1473268745578db9e3064108ae46a4870f18066789b0366"
+ "a7d0ce37e030b58946ec8c1a141154db0e261bef8baf2e9f65fcd16b7d5797b6"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.16",
+ "2985e8b550812fb66c18f80e6f092a945d091583861b625d1e",
+ "2e843013cd5e795e2166c8e91b06c3131dc3a5e12136d7160ffd11bbefcf6ab6"
+ "40e05d76e0c61ed306f6086bbb567ca87e40c6924d5c84a6ce28a83950bd4b84"
+ "e27fc5069fd0624d50eac24a9411b5f76785d9db5da30f425695b019b84cdbb8"
+ "25bd46e7352e08f114c87b066fe43d1056a2c610cea7e3d3dc98bf4497eb4f13"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.17",
+ "77788e838b834e8f4d045aa894b90abb85940cfc58d7725e7f373da5547137c6"
+ "0bea751e0142bf9a6f4649aeb546ed560cc4ea1562d4a5fa3eb1b11477a3051e"
+ "24c606b8a71c1a774bdcf1a5310fed555923730fa8af4c15800d362b37adf14f"
+ "7afce78efa6bd893563efe0b3b828ebd499f12a2fe332bfe46dcbb314bbdbf69"
+ "087e2a665df110835de55d61e5c2025fd8db",
+ "8e5f3353c49cbbb2ea696abb5740bae015effd950d5607137605a100c4a53f1b"
+ "95176caf349f4fd588aedddcf5060ccb72478cfb098562f34d8f8eba446a3847"
+ "565a7b8955ad9e0c6eb67099e1a46c3eb2d49d9090ae5f63e8a08b6e8f21f003"
+ "e451d250ffc5a790d66a0e2e3e28a6339fe91d112921f55d1230306fad5c0190"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.18",
+ "1d599d762cd54df70f1a0983bc3ea2bbca6fcbbd162603ba81561077fd928492"
+ "5cf1f1b08bea1e70bc595df0b343b83b9cf3d634f95e37e8d1c585fab199",
+ "717497a4e60dbffa196eff758e901ce1fe6e2bc7e1d53a3dcf6225671af146c5"
+ "dee200a814f4898d16a9b5f508dc9fde4d64070e55ae3b1fdf7919f42b7cffb7"
+ "e928c4caeb552dc6fd081834b2dc2fed07e7e627d34b3910ca713bf4154eff99"
+ "9657361518fce5a8f642dc9a18a66ede22190f60aaf958d6246b00a032c39841"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.19",
+ "da51008660b63b8767e65f12c6308ec18ed9575a426bc5fbe66010ec3f01175f"
+ "fa5741eaccddb02fce7b2ef7784440d72d3752203f534e52fcf626a8c596513f"
+ "419064bbbafde7f8d65f30d7ca68718970de71fc8c0eed4da00a4e1ab54102d9"
+ "d165bd7c54af5c31c15c05bca55b6fdd191086a53e5296f484c347d8fb945a10"
+ "c49449752732f62f34c32515588651137919285a2c8ef7b4aa0e690b0b65437f"
+ "f8d56fc95dcbc3e78d",
+ "32677228ff08c66fd03bb31f0dfe890153b3446b57eb84ef3956208f72a07c87"
+ "67e6bf09f038bcf7f735ee24a1f640a1898d409eb53abdb693942734569af71a"
+ "4cd99a6520baca5d4286b199cc67628e2fcad296a30eca499eb880507f6a3744"
+ "0b61c1284c403c41321b99053f5d69728d5b973576cf04748333d808d5e68a8f"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.20",
+ "8cd2dad2a5d5f9faa07e24a96e86f9b0ac8b40222ac9fb8a8a15727cf2f53e68"
+ "4af4abdc9868a7253b25b096bd701f46a943",
+ "8f0322eb2c54052485a64549adff2a3631db6576fc0cafb551697dc5356f02e0"
+ "93cb69173a7e8355a0dadebfa53cb2907f002db3a3e387da057b7c7355164384"
+ "3ef574481f807415177e4b34c25bd55f4c02fa0adea3a9580465f358c00596b5"
+ "cc062d5892303e1acc113c3b4bc74d42e858029078482a1b234a625b04284406"
+ }
+ }
+ },
+ {
+ "A 1025-bit RSA key pair",
+ "016934cdff4850b6002cc0f0f4010a32c655e5cf6e7c89937fd755ef6abe379d"
+ "adde70cc217751f14cba6d90fe52dc0af58b252f26bf72da579fdaf57ddd6cd6"
+ "021879949a0276b4433ff01efcccf35a11e7c77b38c18cca94ae012d0f370421"
+ "491c52ad15ac76b12ecd218f52e757866e089dd8adbb48e9ba894336c575c406"
+ "55",
+ "010001",
+ "0d1719e5bd476d87c7ecc31eb8ab425d4fe4c8f5c7ae230a1047553ffb539fd3"
+ "855af5a43b2ddd4e95a2b30d407aa88159bbad2a873d8093b48a4bce20ad9926"
+ "253ed339ac3b543fc7429695338db0bc1dc3686cfd139bb5b28736bc1660a953"
+ "48fc91c325d03a7fb216d2d9cd9364de4ee7d2119c3b0fbba8a71f0d3f5ab9b9",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 7.1",
+ "3539997ae709fe32c1036a132757f2a1667a91cc83be733aada1bdd217924c9a"
+ "2c9fed1fecf61d1cf79dae9a83f8ae3f4d051b34fbb559cbfda492f1d83b8beb"
+ "a045d4ae1c8fea15b7577a1b8a3f55bac1727edca7f8f52cb4ba61caf1fa8f8f"
+ "d9aac779095ca84c7991529fb80699d0d4688dfdb142ed61a95b89ce3306bf97"
+ "80e1b91b848c8d2003970e52702a1f612e2f4017cfe0a91db9e46db9dc",
+ "00080f770a2d1f6abf5f221f62e166abd79d06c7b9a878d61b80fc4d5ba290b2"
+ "3abaab518f09447e45aee6f3bd0610244436a4730160e6a672110c01aeb5624b"
+ "718dc7c0861e586ba8b60a29d6a5755cd2cc508599c6e28d7355b27e40b740c6"
+ "fbbbb1a91823b1c1242ba693d452695147dbb23ea89cbf11eb8b07ec3a027b0f"
+ "17"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.2",
+ "318008873c4cfea7125ea6fd5215dfd98d5c5e73323f03f215c69c8f2bb1983b"
+ "59dfa6e99add306966f3110c161ca22624b88070265b8f3f9d5df72991e79e5b"
+ "189aa3d9cd9b2047cfa61d01234b233d36ac4b96ed081648877490fa4a80ec4c"
+ "bbd9d2e0062c39e1853a0c38344ba858bd1d995f6caa28bf904026268a997211"
+ "43c86a4343baf89b6d550764251fb07d167b4c4b1b70f99ef5fe50e62e5413fc"
+ "ce0f9959c2a378c41d6f4236178b14b8919db1d0",
+ "006d547da4edcb103315cb8e4b669bee96aa2156235ca5c3e31b24a15a1392e4"
+ "94047fedcb7081907c5617a8aa18d101b0532a3632451923c48a75b0ec2176cb"
+ "98e5ce51588bcf868e29d5d9694f00ae2c924e73d2e6dd144d24fa45d01206a3"
+ "f5d936413ccbb74b0e2d047d82b600b89d51594fce7de6bbd95b97fcfec598c4"
+ "eb"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.3",
+ "7f83b3e054c024825078dd9f040e1d09058200c9757b76fb372b8b5266b9dc26"
+ "9ec7569d00",
+ "0134ee215151e53250f5a0016acce3701e2a58ddaad6cc369df0dcd9346a2b53"
+ "0fe3715afeff1e9bcb720831c12558970a9e03896004f287adb821f317cf6393"
+ "00cae6e909e91ed2a3eacb9952a7cc5494765264247951d28c16af03e24b80ee"
+ "32b0b62edf10d70091927135f05a889f2f6056b95cddace47c69f97308c0df2e"
+ "ba"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.4",
+ "17ebc15007bb5e4af917201c3ba384926589c3159a89d1abd4c2c986fba0379e"
+ "8af12975c5d031d1bfc15ca91736f07b1766d8b8a72db10c268c98fd7aa11e29"
+ "99f06d86127cc889cf150dcc738f6ab8baae943cc606dd4d9ece701a4a7b101e"
+ "351dee20b15ebc55256db3ce46a6bd5061125b62b995e970d16f7c9a8fc157ff"
+ "68cec7e60f608f6626dd39528b2409aa2ff932fc119b2a7a81772a576b3d50a0"
+ "d287a7fa2db87d2b92e1c961a70caa44d88137b950e100711a9854adfafb494d"
+ "34e28606a27c",
+ "0105dadc99c59b5e3ac554b1b5e7480e5c0a62c7abaefdacf4426eccfe686b8a"
+ "aa1ca4f51ebabffa77d99803e7ee8d20d1204aad8c67385d0744c854de2f997a"
+ "56aaae04cecc656535c16bb2145d1801812594a8013b0eb54e7bf65d38420054"
+ "ec46dac71a125208b302214a7c9b3a92ca9bf73739c766309af803edde7c54d2"
+ "46"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.5",
+ "6a52ba190e44ca0f1070021048762f3e79ed51c94f6dc1a9f1ed78352ef379aa"
+ "49b3a9387e3ca7a196f105dcab18506f294a69",
+ "000b70e601c5ec58684e0918ba7a539e9d2dd29b01a3f453cad4a9a40e50f5db"
+ "df72c11052f20be44a5d3851b01fd09d9c9208470f0a4a95035e989eed7d6b06"
+ "2e13f4995bf0930b4a3d9b8a9ed75e33886e4b194ab5ccd6b412959cb4f5498b"
+ "d32f668546be2c007ae8de5d98977b94b17e1263884b54e784b38fc112b8cbdd"
+ "56"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.6",
+ "bbe0b9de2b5e9dcd316742943f9219b24f66a38f9de709464fa5495d794a637b"
+ "9ebc067762da7a6eeff098fa44f3cc36f2ccef67fd46c59e24738c810c69eddc"
+ "d90cc7d71a4c3e693bcaa28a533d904b41ced3399b4c7647e5ec4b3ad903870f"
+ "5b5f8d6a8d8128ae2381cec86c4d85b78a451e1ea97e3393ffe997e546b09c8c"
+ "f82252b33f745feed4133206518e2b880319dcdf9106718afb016c514b380532"
+ "65bc9879100e47b03eba0368f09e2923ac6f40a04b75054cd505bbc8965d649a"
+ "1bae7bb6643cb74195e91c51f4183db2d738ce603550d634e6dd4f27f4daac61"
+ "56cfa7e2468b5d6aeb782909",
+ "00c2e074dfbcd0e73ac0021aeb9933106b201b93c17a7bf93356d291fb4aaeb3"
+ "d1316300a8de7b07e3d779bcc299e52b6cb03088016daeb841382eb3435f2e03"
+ "ebf22dc086fb20ebe53ac54590249763a2655aa7eb0e7d3864936b34006a6c4f"
+ "a02d9ca104adada6aa01b977b6def2750608a78f3ed83ad712a7a1b0fbde7c7c"
+ "8d"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.7",
+ "83a48bff886d1d68f2920a0ecff298321a96f5cadcdfd8be16b50d34d67d94cd"
+ "b1a1bfa0eae24699b663c7ba3a08a390f7225884856794d180c546cac06e4118",
+ "012e81bd38635065bf6554336b00d10618330553e0e80878aad355f00d5940d8"
+ "ba4501c5c49f1016d5f0e6a73a4d9f8740d2cfc25ea248df3f7b1ae8fcd26bd5"
+ "62e0f6eb777f46d7573069db8907c021b645d3b24058475199a91b5572d8ac87"
+ "f83ee6af5cf9e171a858f60d2b8140f52daed68442228b4fffd8de40078d3de8"
+ "cb"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.8",
+ "18",
+ "00f2c299024ab7bd252c6946bea10dc053973898bd5f0e3c9460e6fe09d7d191"
+ "e71bf79d436caa84e986be3fc09819c080e56a085cf424414af3fc7007cf1ac3"
+ "6f1cf8635780b5568d734ad6d81a2ba8eb188b294669d871ca40e608f0ed33d5"
+ "690cc61570c5b847ebdbdcdc4fa78f429efce13c6747e54d6f261b0455d6dd65"
+ "c2"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.9",
+ "04a6e24b93c2e5f6b4bbe05f5fb0afa042d204fe3378d365c2f288b6a8dad7ef"
+ "e45d153eef40cacc",
+ "00ecc895fbd947e2dfc47c03ba2e993d1a143a7a6ad63a916ed54483ce26389f"
+ "89d580f4edbdd0b37e08caaa5a0c1e526e1e9a1a8c0dc9cf50ed77de2676460d"
+ "288dce565f128a266ea29b4ecc329a94cc252396dc50d5c0a13d809381fad88a"
+ "0789ad4f56aa77e544ec2570af9918b7f741b486ca50b3384ad1124060591685"
+ "a1"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.10",
+ "9965bda55cbf0efed8d6553b4027f2d86208a6e6b489c176128092d629e49d16"
+ "9f16fe51c4c08a6494b50073622091a3822ea57c328bd9b69d2465a2122af178"
+ "bf6b1be307ee4c31479ffd9f4d11f33ea20b7aece812cab4eedd46993151d568"
+ "ff64a16704a55d950ab7791aa23b26a0a8af880f6f8056bdd206838b44c607b6"
+ "61b4f1dc3621065fded3db6f9e3f2dc8f400efe3c2afa6c0279940576bb05e39"
+ "804bd3505f4bd28252918b28e74e058f24f27ef0db3d0dcf9eb29d41ffc11007"
+ "ce86b982e89c0375bd9976a5af131a614d2808ba25079d977f0b239796ba6b1b"
+ "cd5e855d96",
+ "015662e30e790e37868381b4f677a2aed6b2acc564491731824910ed80adc477"
+ "159c88618cc7d0beb049b1aae74b1721e90ba7f7b0ea26bf33ad04f86ff31438"
+ "97bf0d4eb45eb7deb54411ba9680aab13adbfcf18af46b87fcb1461c26206a95"
+ "3bc3cdbb31e296ea09024bc5c7b62de6c69c14bfcfeb56391a9ef58cd805eb63"
+ "1f"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.11",
+ "71c7b18b4aa8ea5389ad7849232865be2a93e347a168d25c6c6ea2439c1cc80b"
+ "b0b7223be9c8937122845bb0a39c025c43759defe6e4e8eb3baab4f1ebdca2c8"
+ "ad12a465a30f8a6525b120ef6aaec9bddb45cd42c0150c407b048edf65199492"
+ "f207ca01aaa5543af38ee98d53bd10d8eebc3b64977e75751d7450ddb1c0e1fc"
+ "24da1718811fbe9b0abfc3ca31e6995fc7349073e217b37e23c5f17a8b7a3f00"
+ "486a3702b9510d6f051b2761716e32c62bb5939b2fb11acb1c83",
+ "013ab63ab183353a235fb893ab4c35d6409c21849dcfcda3bfda1429fee742a7"
+ "d8160fd3c83b3853a333f951539bb5771f4d0fe13adeb64e4030b92e8b0813eb"
+ "52b1aa33bd94c5b8bc1bbccdf6c1df0ba670717c0cf6fd485be2fe9e16813be8"
+ "cdd580e61086675e31831c924a41d4671a95d835e3fca495e88658d1e570e628"
+ "c7"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.12",
+ "0beb19b562928c271bb706189e43cfa57be76b2f7a83e02aa2ccb037c0f4f7f7"
+ "3162d6c26f70de971821e7b9665cb931bb0eac820bf859984db4beefef4ab88e"
+ "91631c0cd31db7f9358a5aa1dff2406b45f9bdcbef20d55c282bae5cfb610602"
+ "3b5633c051af17e729bb07c9af6dd2",
+ "00d63da4d5d3e2284a192a6a9da3f1a7d3fcc164b9fc3dfd7452b02fed6ef1be"
+ "5ad2a769ec9c36059b71911ccf7ab71ce30987ec47bbf55e6d4630d62342b315"
+ "5048ee0bf43d24fe69abdac12f794b6798bd1a7cb489a64ce082254c3d92f475"
+ "566b56400d9620cdfd63fc17c193c425d7ede941f76da1e345af0e2a8b8844c7"
+ "40"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.13",
+ "0287abe2670a45f8779048f5",
+ "0042f414782df65d9347bf1cad534853746cc0b853c1c526f9171445fcfaa499"
+ "1a70f5a8445bcf4114f07fc8354c84a93b943733d3937a59883b896ce65fdb16"
+ "5b1e3055374ce242e1268c1641cc443bb9e7da7f71f3e7f6313f239e6200e79a"
+ "1be3ead6c36e941f24460baa57df639e57dab3eff9e77b87af355b83dae77cbe"
+ "06"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.14",
+ "3f49542c0e9f50932c0d453dc95320af21dd2bd1729c29f4f08c70944c2cc75d"
+ "e9166b4fd230aa93702c5f2c3d9c299a359102570033540eb828cad75a5776d2"
+ "e8cb456141a6fa97bc4e6e62d3df082982a4d98c2de441e59e9312",
+ "015c3993ceebd8dba45a368dd405af8a53b93e827019f994e4ed782c3911b9b5"
+ "80d54224269b7997f1749630e52f221fafab9641c781e7044d3256e2e44e1437"
+ "917232694518ba9e7138da47fe534329b8c9689e2785c02b603dd160d37336a2"
+ "b05be04782659ac0e9671fe932ea8091d61318b2b201bda79af6c0c4446938e3"
+ "f6"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.15",
+ "d0dbc96cf9bfb1e3cd6de2eaa08d6d795bed8187ceb0856580e4b142b9ae60a0"
+ "98cd42984e8dbf1d05a0c0ab8351548f0a13646f33390b2bb0c864b397cf1337"
+ "1f8b2f675a82e46bf16c4afc605ee3e5a1469cac51fa734b4465d4c13d5b2dd1"
+ "2eeda54e7d081cd9e3eaaf9e57db422020a0b5a5ec28ca43977a5d676ffab62f"
+ "78107193594159cebfbd86269819a0f341a0f41284dd0a73ca8014d2e0b80179"
+ "c6380b403afbb11b42db349bafd7570fbecbd14bd0c21ad641687a6ac32925f7"
+ "031a24a6568ab9e287eb80754110dfba688a596325bcac4a39ce8b84a4",
+ "008cc82d64559de0040f5541199aeff3999fe2f086f157ff51f2220db345519a"
+ "a114b01762e70bc96583bb38b22b3f87beab32e23a3debdb8a595429ff12fad4"
+ "95d74e220e4f7dca22272843899e8104c69a59642f6fa825890fe8132a0f7994"
+ "0253e5007fb1177a5bf418067eddc8d32c5e5935bf338f1c690efc8011dc8c84"
+ "2e"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.16",
+ "7df0236e871a71c31790eb5f011c911c27c60373b8dc9ebb13ac85accb3bcbd3"
+ "b474f978862dd84202ab20b334739425e1b79e0bb8b4bc47dc7153f57ada0412"
+ "447bf5a5e6673419baad653e5f5c39e2ef7cfe7ef4778ab998caf97ce16c5833"
+ "2772dddf826f1eec1af3db80e31375d6680aa254b4ab6ef9a3ec0e0403e4b583"
+ "d371ddd96dd57b2c61a6e401251a1a630d1ddcdd84d90d82faf5a018d2a88e26"
+ "5855e9d7ca36c68795f0b31b591cd6587c71d060a0b3f7f3eaef43795922028b"
+ "c2b6ad467cfc2d7f659c5385aa70ba3672cdde4cfe4970cc7904601b278872bf"
+ "51321c4a972f",
+ "01455e3bb29cbca8839b9f544d51472ebcfd25c29227c4655d5f7ebbd83c48e7"
+ "643e7b594d6f7cd5f6bf9a40b05c4a05cbee1fd659d3cede3e7cad61e6fdf8f0"
+ "e4fdef0812a853908f0f99ca7e388ebc19e874765b11640f1ee1e98f54953de6"
+ "176f1582037017c838609a57a12acbafa6a56547f57d62dbe87669edc0fe3baa"
+ "da"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.17",
+ "1288c03f95006ea32f562d40d52af9feb32f0fa06db65b588a237b34e592d55c"
+ "f979f903a642ef64d2ed542aa8c77dc1dd762f45a59303ed75e541ca271e2b60"
+ "ca709e44fa0661131e8d5d4163fd8d398566ce26de8730e72f9cca737641c244"
+ "159420637028df0a18079d6208ea8b4711a2c750f5c0a425313df8d7564bd243"
+ "4d311523d5257eed806ac8c9c6af04ac",
+ "006bebb96f0e282f1b4d03e6c56505b93778da9f493650e8aaeb65cfe6285004"
+ "2f75abe6e6eafeb9a70abd21eb5dba73cbb87c12980aacdf16716b1998c9499c"
+ "e439c54aab4d19ce727b7875a41a3d30814e508daa26eb70aabbd0dcaecc4d4b"
+ "51698071511eb31b210e66dcbc7fc0b8c62314daea69d47ae278100deb514092"
+ "00"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.18",
+ "5413993c2658bc1d9885",
+ "00bbeb2ca0bd64cb8960375b08a9480e69c09fd382dea2f94089b1533a0851fa"
+ "0cbd0eadefca8c70b770797ad089e840d2fe1a8fb8549f3290583bbb81d3ee2b"
+ "1c48f1ea751bf32f9590be3afdb7745e166e0b322c083124e645839482d08126"
+ "22d31ab1877a9bb41b8daad868f30e7507832ac3410112133aa17b2d476d476d"
+ "89"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.19",
+ "9c84c1486bc12b3fa6c59871b6827c8ce253ca5fefa8a8c690bf326e8e37cdb9"
+ "6d90a82ebab69f86350e1822e8bd536a2eb307c43b4850a8dac2f15f32e37839"
+ "ef8c5c0e91dd0afad42ccd4fc60654a55002d228f52a4a5fe03b8bbb08ca82da"
+ "ca558b44dbe1266e50c0e745a36d9d2904e3408abcd1fd569994063f4a75cc72"
+ "f2fee2a0cd893a43af1c5b8b487df0a71610024e4f6ddf9f28ad0813c1aab91b"
+ "cb3c9064d5ff742deffea657094139369e5ea6f4a96319a5cc8224145b545062"
+ "758fefd1fe3409ae169259c6cdfd6b5f2958e314faecbe69d2cace58ee55179a"
+ "b9b3e6d1ecc14a55",
+ "00e6be96e18dcebf8388ba82ec6f27105bc27871595e01705a2b97a1f4d78838"
+ "352b0e7c0a2c627a6ff37db169a9a4648ad27af06533a4f041d4c820abf4fb52"
+ "6464081434df36788503c65af762aa219fb76a91cbb40e1492a9cb77369bb4cc"
+ "a1934e3853de6c86a5dc1148edeeb3b0030414fe3083ad72fe295c29b5ea9b66"
+ "60"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.20",
+ "940cdab4a3e92009ccd42e1e947b1314e32238a2dece7d23a89b5b30c751fd0a"
+ "4a430d2c5485949a2b007e80978bbb192c354eb7da9aedfc74dbf5f71dfd43b4"
+ "6c93db82629bdae2bd0a12b882ea04c3b465f5cf93023f01059626dbbe99f26b"
+ "b1be949dddd16dc7f3debb19a194627f0b224434df7d8700e9e98b06e360c12f"
+ "dbe3d19f51c9684eb9089ecbb0a2f0450399d3f59eac7294085d044f5393c6ce"
+ "737423d8b8",
+ "0080e2c34fd4ab4d1d701ea3f085763acaffc9fd3ed918d04bffee1931624898"
+ "c78f8941bd2a59ceb5b840f0114516ce411fae752b1b8a221ffca7a68766c697"
+ "c50a3d88d8d02ffc1241d84bb7a7227f3d05149e15111277a136a5b8dd96dd4b"
+ "225c5f49cdf6071dbf71935c7a6f1e2e9af3021c0d58a9b81c9bde61fa472c07"
+ "a6"
+ }
+ }
+ },
+ {
+ "A 1026-bit RSA key pair",
+ "0333126488f7a2915132e30d5e97f6ed7bbb67b61985008eaea2a5dafb96a448"
+ "ab75ce3d6e68a6265e7c245684999324c81e0ba6389863feb488b3f255d0d619"
+ "c19040b74c189f0c9af4b0d5a55a544c090cd6152c90a6f2550d7d2a6b6d347d"
+ "5b1b9dfb1de4403c796623d703bf9db443bf6702683b8d2a9c61e9368ac425a5"
+ "81",
+ "010001",
+ "014a2b15dfa8831db4efa05b195084b742734ee136f4483f3be2509d2f619023"
+ "c30a1ff2df78cbd117b14f2c9913171f7293b9fa6d41f0bd11a5317474675486"
+ "d7f0aec0a778ba920e81f564d15930cddee7e2b06ad8adb612751f4e384d6f3f"
+ "a0a6639fd62edf86f52c9fe0776291832183d359b7343260c94e125f4ab8bf43"
+ "69",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 8.1",
+ "9a2820f3b9029abc1865eb06fe61b8d397b65572d60061caa74e6356931e256b"
+ "89712d186684b4de1e14c9ebfef16e40d99d1094396c561c883177e5126b9be2"
+ "d9a9680327d5370c6f26861f5820c43da67a3ad60904e215ee6ff934b9da70d7"
+ "730c8734abfcecde897fdd670a01465868adc93f26131957a50c52fb777cdbaa"
+ "30892c9e12361164ec13979d43048118e4445db87bee58dd987b3425d02071d8"
+ "dbae80708b039dbb64dbd1de5657d9fed0c118a541",
+ "0322d00fc1d96694f36eaed2309056f3ea1c1cc22b13b65e79118d202c42d161"
+ "3099380509da7435bb579216fd5765066842e356a6416fc842a24a9ea1bc6a90"
+ "980523b428e399bbd6fcdc2cb771daf0037a2de8c7649bd53317de0e37c314ba"
+ "b0c437bbd798dfb965506c348b742f138ef1d1a203e051e34bdd3a30e0fce1ac"
+ "43"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.2",
+ "ea9a1a04b7cf478a897a708fd988f48e801edb0b7039df8c23bb3c56f4e821ac"
+ "8b2bdd4b40faf545c778ddf9bc1a49cb57f9b71b6d48b2b6a57a63c84cea859d"
+ "65c668284b08d96bdcaabe252db0e4a96cb1bac6019341db6fbefb8d106b0e90"
+ "eda6bcc6c6262f37e7ea9c7e5d226bd7df85ec5e71ef",
+ "0268440939996ae5cbdafdbca86a7c428a04b578fe2dbe5126a82faf2becff09"
+ "9ac60cb81b117f1ebf4204fe4370548d5d2c468063682da87dc80179bb3bba85"
+ "a148ae2de7dcb494f476221df8219d4aae1e45af65de334a1a6dc1455286ae09"
+ "cf26725885e774809972d7819805fff5a8c89d37376450739249f57eb151b71d"
+ "c0"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.3",
+ "07df586b905b23b91af13da12304bf83eca8a73e871ff9",
+ "01bfd915ff7780f14ccc55bd0306b3aeda5b5b5955a826d4526b0bc766154fa8"
+ "da59560578ccd4882fe97092fbc736fda73ceefd103894063e93e22a7b5c44f7"
+ "a85e3bdb96719a09374303c91ed7e22749fe3c4d6b96699d507c50adcfbdfc13"
+ "1d6b5f2cf1830e31eabe39aeb517969c94a81cfefe6731aa2cdffe28c8af7140"
+ "f4"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.4",
+ "500b8777c7f839baf0a64bbbdbc5ce79755c57a205b845c174e2d2e90546a089"
+ "c4e6ec8adffa23a7ea97bae6b65d782b82db5d2b5a56d22a29a05e7c4433e2b8"
+ "2a621abba90add05ce393fc48a840542451ac7cd698d84b65128d8835e3a8b1e"
+ "b0e01cb541ec50f1036e008e71e964dadc9219ed",
+ "007ae0cfd7f4c6ad1ff84b4a606ba1c4798c2e499b045b567d32634fd955f268"
+ "260ab659bf5be99e0826eb3870e8f62f5a3ce758e6d156c3299b431cd9dfc658"
+ "37ee94220d952351148799be9fcaf9be264daebeba2be86605201ef9a0d98f58"
+ "ec638abfc4f27848f5d479d334acc2a97fdd2d327ec4c7ddc5a8abd566de35d1"
+ "4f"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.5",
+ "6b3f6a63d4e77859243c9cccdc98016523abb02483b35591c33aad81213bb7c7"
+ "bb1a470aabc10d44256c4d4559d916efa8bff96212b2f4a3f371a10d57415265"
+ "5f5dfba225f10895a87716c137450bb9519dfaa1f207faa942ea88abf71e9c17"
+ "980085b555aebab76264ae2a3ab93c2d12981191ddac6fb5949eb36aee3c5da9"
+ "40f00752c916d94608fa7d97ba6a2915b688f20323d4e9d96801d89a72ab5892"
+ "dc2117c07434fcf972e058cf8c41ca4b4ff554f7d5068ad3155fced0f3125bc0"
+ "4f9193378a8f5c4c3b8cb4dd6d1cc69d30ecca6eaa51e36a05730e9e342e855b"
+ "af099defb8afd7ad8b1523703646",
+ "01921f22f471a08af819a952e18368ce15f9b064eb1d00b12899780244fe8c44"
+ "24b21f64350b9226fe95ff54f11439839bfb54f939c91495e4f027901897273c"
+ "fa295a57151f4e911dc102a77d958b622724c0fd3a34b3b7befb8b8cd0666e81"
+ "5d0c07f2ecb7c4dd2f42b7f4091312e3d7b2df267887e0aca70b541c4c1eea16"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.6",
+ "9329a58090de8be57c42",
+ "015ce24a6f2b373a19997bb20c18ac659f1edc0f25c9e5bf76d569996520c280"
+ "efdcf15e2d63caaff6c77ae03897037a0615f9838c52104e972518e290fac38f"
+ "63247530b4cf61c6ece3429b530781cf34964f32ae50f10934638386d3b4df76"
+ "1c597d4aa7feca266c27f8ce66ade1be2659ce142ba5f935883c7e8c9b8957ab"
+ "f2"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.7",
+ "6ace0f1e1dc63e394a061f522a542fbe7120254e36e9f65d1957c95628782cb0"
+ "368f3c13dad6567179c1ea24fe835a266385e4688317b82b0c3fe63cf2d52f04"
+ "ae8a38a57559bb95d9ebd5fe8a9afe1479909eb99e0d3ef3f312e0a4abb766c7"
+ "e2131a5ffb483183fbb42234d32e581f595065c4898261ecd0ae572c221c258d"
+ "e950a40801ef796d4dd0040645fc534d8e7858234838ed12c68740c14e371613"
+ "f0046176bbb0f43d997519c40c671496ff350a3fdf429cc22f464f435f6b29e7"
+ "e1c30ebd505927d4a096587fc38d3d6494391e",
+ "0273ba2c502b3f2984c548d9f7d6c9b3d7fd460878c84d6be33b28106e15fc22"
+ "17eff741cdc266834beaa86da405f3cae606cc61f2547bb922920345fe8fbb5e"
+ "7b6abf91eae8c42660645025cc7fc07a534b76d37875e3f40d5270c10ef46c7f"
+ "e45afabcffae2a9c9411bd04d61d4c0e5ffc022cb36a64b7c3a8c89bfde436ba"
+ "fd"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.8",
+ "fdcc0f1e5dcbe5016a6b0f8c28f5b331ff582837138dbf62ef7ff61bc1a35396"
+ "c92e3d548d399e350a3c6bc2fdb5da94b986a4ce6dee104e9f274b152558bfa7"
+ "22ccfdda3b26b9f8e51525f381034c51fdc9f7912ac927d1a708cc2dbbcd7ba6"
+ "c031b011cba8e2df8fc9b88364ee965f24270e4348623253cb9e59d6f7940909"
+ "94a7a4c9300270b57f2439ebbba4658467afdb7fe86b4f1aad1d3d3b2f",
+ "00a7c450b30b2ecb19bb709a9231cbfa9f0d61697a26b90a96d91c24c4da70d7"
+ "b00b5923c8e12d41094b705d50c778bbdacec660d5c15dffd3a2478fd9337080"
+ "dca16b9c13e6233b8292b2fdcc29e9bf3b21a71878f34ef5eb7cd50ad4120372"
+ "5a0f1c663f7342ec7c3df3d5aa51d058dfccce5fe69d363b4284320879e86d58"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.9",
+ "2d1fcd1766f7d45f29594f9d4f743941ae912a97911ffc3d65dcd9656010773b"
+ "b0224ba6df111b1c1368384f2492fc4fa7280c066514ae84f7614563d9052ca9"
+ "4ef446a31b463bd6c25056805088c1d31abaff5215f7a8f89e7b64f2",
+ "02c0e071e83690dc14d9a37d61e0afc27df978039da601ca2cec1dec8f0d17d2"
+ "ffc450e678380a025a41c746118f58364252a122539eccbbb4ab3d8d377bdbb9"
+ "11c58a4cb9462f36dc389248501bd08f48e3533b82591a2a20cf62df5f5a1f84"
+ "ea300cb39457137141ad8cd1d185abb17ba5d03be348c06797b09558f0331c24"
+ "b9"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.10",
+ "4f469ab79cb893a53c0ee3815a8bc087eb74ea36615bddc333dee05fc72665aa"
+ "6d0bd59e47229829834b1f91c9cd81ce28d68f14825a345f3a4f38a01b2dae59"
+ "100764aab990a850b11c13d5dfe419f1d920d00cf13bf430e4ca8287989beebe"
+ "da3e5d4036028c8ef9546e350150d196f00560bae1472299e7f4291d544629c4"
+ "f652e35cde4f803e1b3ca33809515ef23d254b8e65202a14a411b1bc315c5ffa"
+ "ecb8211197809dcb5ced682c09f67e41d1602c",
+ "01712964ea9ab970295b81b0fbd8357e54b936ee8772d8ae9c9612716fcc2fcb"
+ "784ca9abeeebb8fcb68982161cc74e40c7c02247c0d00e03bc8e1a7051b87c90"
+ "dd7d3dfc95e0b3c88e7a0f37f30e1bd5fe8b6eee465a0b34cb59c64ebdb57d6f"
+ "5fdff2e70bb19c60d988ea956cdcdd1be562f26fb37c34da52a9f911b9974381"
+ "2c"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.11",
+ "52bb76c9ea265d6fad108372ffab2503bb20d38d37df199254a2f6de0c4fca7a"
+ "730336",
+ "010c553423602260158a17133b5d30efe98e9aeb353bab3371e491cdbebd350a"
+ "0a470b9dbfd18933511f0d0e3694a8ac4bf3f5b6eb9bf71c23d94c2e64beb7b7"
+ "c72252ca827bd0c0567ba8a10a6d3b7e187b0fd8e9e95d4fe480f250dc7f0342"
+ "290e9a7d32703a7213c65213aded455754781f3db73e79e3d1ba6af7f690fe81"
+ "73"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.12",
+ "5f597a19cbf51430d3c6a247a5235407386caed0a294f3f41f3f378250d4c5a2"
+ "c99275f95544ccc1d77e5c151af13ed60be522eb8cabed89a9b45b09654600f9"
+ "fc751e8b12e67e52",
+ "003bd4aa9081fe7e9f69a269fec8c8a73670c037e85a1f36fcad74e5b52d710a"
+ "5a18ba095b9810cc6937bc76340951e7fed75b326d0a3b0f26c29cd5eb6415bb"
+ "f7e2dd60adf6a0e61302dcc660cce910408b4f99a440ae2ad6c30772c29a9e7b"
+ "3280e2e2939aba0b54ab022aa3295022718cd3b787b1137990fbebefacec8cb7"
+ "49"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.13",
+ "840cc900cb4b2cb67a304a9b02826db0d66736922e787013d6bf214df579ff0c"
+ "f4821f9b",
+ "013b6c080f68939505e187a49482c791278da3ad4a747c4f01791b924805b682"
+ "f649bbd80dba12fbbe5940f17f27e75d42677c4cccdffd0048772e36934c6912"
+ "128ff903afea5e1ca8fe9424fc979b2187987698a5c5a75e7d7070a2a674852b"
+ "d805bf13bbd1296bff1310a6d6ed45fdf8672d5241e74cd4c41986e43625500c"
+ "23"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.14",
+ "c6417194133b5f8ea63d95581c896f5b9ef3d87cf66c0291640f350a325b4911"
+ "52e9d1430d6870346e468e719945d4e365d001075fa970f2a9870a1c65434ba1"
+ "7002412acc4cc74d28b2dee29b36e397b68c5d59cf677c29aee793a9300b7bf4"
+ "c673b3e0b603a3611ca90244ff087875c5168857cb92a95aaa61dff3c212dc62"
+ "06f17147c44b9507d5c890758bb35bb72a2a5e9d4db265e5373a5b3402904f0f"
+ "1a1205d5bcc59025d3220a5de1b182a84d30412b8426d46932321b57ef72640a"
+ "dd2ceebf5be968436bcd1216907884823293b010ec28f0d9",
+ "016047caad6c47bf27d0ccfa0341017e565e028cf26c8e660f79e091f350ceb2"
+ "aacf92f7d01d373f7155119c072917f24f01bf747be2dcdc41d1be588535c2d6"
+ "ac1704c5fb16f6e5dc4bbc8453f521db731eba7898e6e5212b80ce9da0f15628"
+ "189998313503dfd44e3d69de9ba9cb5eb32ac41cb8e3621ba1d291d0c5da249f"
+ "15"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.15",
+ "a642f0f70b4bd3b54be220119a7f79",
+ "00a0336e6367527bbf13b0a933b631c72cb33eabbc292a0f8f75550c2230fe82"
+ "57f2af76d543ccd107dd2c8778d3ac8a7b5bb4acfa57f2af6a231495235a51da"
+ "ddb083e373b777a95cf9c4a9b6be7751b65feb623ab334433654b1210f7f782b"
+ "1725c6ba4ffd20d17ed4b6ec4a3af64bd2734755b7739eebf418f09d3aff289d"
+ "13"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.16",
+ "ca16e43d9c82d9d30c8fcb4022933cffc7d74caa0df4863509318edaba4e0d51"
+ "99779c03504affa27d87191b6bf686a84d979a2fdd5b8a4c49321445c6f75d25"
+ "235917adbee2a5cff8a97aef78c009221011d83c0f9d37160875af7367718b10"
+ "eec3b42990e643f63707cfbb30a7fa74ab16a7ebf1c838c3b22637b63ccdcb6e"
+ "b34c62eba9e948c7ac9030f0637729d3e2780ae6be4d2faf346c1163d3f98248"
+ "193a76399fb784cacf68fb33c74babc9ddb627520c0c6112346468cf20a8e02c"
+ "c9a9bd27910e83297b85e857324a0100f5cdd5931b6a6de05f94833aa8610a3a"
+ "4b08a5a39353",
+ "024859233fb9db7cd141f4b8776a1d83e103db3ac94289d36ef40f5e6e63c312"
+ "12afdddd1688c2c1c8d4db04719e1c6e8dbf7d60be25f1d68887fdadda3d112e"
+ "3d0d24c0cdd7988a55c7102940082d1ac31fb3efabe7c288cb4ee72a992ac96d"
+ "1edd78ec728273970a796995c3e2a38581e22803258eb4cd9da2040faf741c54"
+ "2a"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.17",
+ "3baa7e9ada2143f848825d22936704d1c997b2da76769c986fa152b898aeb11c"
+ "10b94579764f9dc933652a8103670476958d59867ab24a971284056e99c648b7"
+ "7e7a653644870fe4c7cef37f9001604872adede16aaced8aa5df42053304e4d1"
+ "71120d7ab3ce81a4d1a27498d138018f6621bdfc1d53e7f3c1a5aa5d62b09a55"
+ "4a56f1ed4f385a0768eaa2da0c9f5637034c2eef58cc35178bc2a6272cf529b6"
+ "5adf",
+ "01e63b86d0c15999093d4428af7c6de6480745d819e429623f472b45de61aa56"
+ "7b60d994792a0d1165805598f4e21fe613999a96225d0bba98f9cfbee83af585"
+ "fa078439a742515ae218ec31f8d508f29b0e5875fca8f04f11a1c82f2bb0ae52"
+ "8fdad3ca5075bb3f41bb5783348133fba8a0b3ad951a1a649ca0f9758b20c870"
+ "fd"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.18",
+ "7eb3c98e46fd1b5c9ff1b11be1619b566057f26c55e288f4844ccd50baa91b03"
+ "8d6095836f771fc1c425fb533ef2b1dc4a3e949bb99525c28fe8a3e93178f3a0"
+ "ac97fd5daa81b59286188e17b44b3771bca855d85f3c4d286f106810f4e522ea"
+ "05834f11a31e89c35990c51b080c03a661e3d4a1b97a2c27940f5b2e412b699e"
+ "a610e8996ae6715ab6e20969b6aa54cc72319dfee63bd2cacfd0608d40e2b403"
+ "95fe55dda5bea3b0f9b94b5aadc098dd568da395db2d44e4",
+ "015cfad96e4b57d9cbb578c79074a2ba869c06028868c5a3fcf4a5e361831bd8"
+ "c02c25b12b90234c8ea4822fb65e82d091a90f89b6c1156e4b44d78d32a64737"
+ "d61587c0ce3f4b343e71f8f7a84c6f8fc8aef8f464c8b359e4fb18adc699c5a0"
+ "76453755930c5f6fa7071f8fecb8631aa414f50835038be7ab05a4b050f3f56e"
+ "86"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.19",
+ "6a45ee0b7ea80368b2c429af288153f456cc663217a8ffcd2aa05c5d322db757"
+ "56cdbc0f684141fe6bcae189bf24de1c8edd5b113644a4500d0d4ff580083640"
+ "e12a2c95de69e9596bfb1d44365786e167d025d89ea2f8d13a0e6477f13b85bb"
+ "dcf160774b18258ca0bec0bd7bf13911b3896b4889fa3de04ab26bd682b4ab43"
+ "7c0c17f353a23a43e92e20e7f820694e403aabdd5d196e93895b479255df4030"
+ "ad8ce3a53d1573be226d81aa18e4858957a2d0a3359c2e7a",
+ "0164f0dbcdd9521186a28084a3f3ae6aacb6596b856e8aab2e72a7f233d62d2d"
+ "3ef196d3787e4b045731da9c6150ad9d5f918c6b06c92a11a0bfd5efccb7b03a"
+ "0107241439d34d313d35b36a0d8ca0813c3623b2bd78f2e3a97199648da35806"
+ "ffc58eed33ac9fcf79538fa88915b1a5758578b9a2db013804bf32e7a56dc724"
+ "37"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.20",
+ "92a4b4bce3daa0a7a64b72ad871f3aa8eab5ac4011aaaea2ceeba89277c64329"
+ "572626c956884f4854f8613d22518b14f038fcaf9e68e13002fb0a00a78cc2ea"
+ "5144fc131176d5e5d67e106a99879c",
+ "0124fd8b2acf2237fc71a2ee97e26a4dab7dea829e15beb2f8a73791a0ba152d"
+ "a5b06adf341d7409e8d3d3175b510134325a353297a8d6d66c09700322eec5e3"
+ "3f62486a211130d74c70dd925df8602ae3c4c6ccaf93cc9a970d1e853260eec6"
+ "9481c5f1337e9dd3aeda88d88299be08095b715a5b2166e617c926722cedd6ef"
+ "34"
+ }
+ }
+ },
+ {
+ "A 1027-bit RSA key pair",
+ "05f3743488261c6f0625e432fa6eb87fb12b26218290bfe396ba76ea4261322f"
+ "8143e4b4ebcd5d2ae19b0f9d8dcd2fc7e6823208a751833d3b4e8e387c39f8ed"
+ "6bbc9fdaec32d3ea9abbff574723f3f1229990963ea4fd9fb544f64290aa2ea7"
+ "da631191a20dbc9423b461233b937249f2f4ea10928fae2a6fe664f12c0923ed"
+ "11",
+ "010001",
+ "014cc3263252f8c4fb77cd57a1420c04c043278a0c45e7d42379493e340f9cf1"
+ "a96f96063ab759d1630406ae286a1834b6d1db71ee722c93745fdd4ad33faa72"
+ "d89351da691a7d0a71d2c55c5797d2ccb3b4626208bc5f5c84fe432f664dc30e"
+ "de0963e658452b2ad5efa4935a122f461d1eab841c8ae0e6e82fc1fee85d181c"
+ "bd",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 9.1",
+ "82e5c5aae64e608b27504b91db",
+ "014582dae935e6b2aeff7d725089dab058c678b2ee28bcd444a72bdfac31463e"
+ "18e94d7b5ecc84a431696a1cdd79f9c08c33e1d4b322dd277b503ae6e4f9c315"
+ "305b4372fe45fe4a7ebbfc4ae590fa3c520bf828158f7820299f09b134ede117"
+ "b672a1eac2f050c044b255ca8d4552d4b5f3f57b8734db2474500744a5337500"
+ "5e"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.2",
+ "77e0fbdcd6e0498fc5684ff13d4c9f5b780e77e2464637ff66eaa2d7d9c3defb"
+ "9b0e3a383773db97a4fb491beb2114fdea2c2a480ffc219b796ad805d54fbec1"
+ "7dcb34b1da1796cb9cd5f2416ab5e766f8e006918ebec1822998a28fffa6230c"
+ "078726fba2e4a7b0",
+ "059327cee726ffb603e8a9fcd574aba9cbdfc36c0aa66fcfe3555cf2ef3582d3"
+ "220df9d6bf8a78e3fff0c129b3abb3dc712112a2056bca08636554c1ac57df87"
+ "f3664152688c6ac72e6b88f5637cd73f166989c82909fb67bc1fa2e2d523e51c"
+ "918f2bbec1d75202af240a61cd2dcc555caeae9a68570d77810cf1df8123ff41"
+ "c0"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.3",
+ "0dfa5baa1cddb834707a5f8cc6ece571a7a7fca5676362d2b23741a9570ae263"
+ "8f6b1c2389853675ccc6cc1b4c6dae23cda71ab96b5a2f22145750433e2d6ba4"
+ "276ac1ff9a48afc9f312f4133785ca5af3746674319a6757a164e34d1498bd55"
+ "30902e321855e3bed40881f00542256aa21a42fc",
+ "01d1954169af58993e14772a94f19bc47924ccdb2e90ee4336fb6e08498af4da"
+ "2651a2b7836c313a57c861b55184ec3b15fac8145351bec5a7270a3aa8694db4"
+ "e9a92cb9327bb7a4f7b70d244eaf9ebfa9edfd4d54782f3f97262695b97d416e"
+ "527be4ea2deffe6eb5e06cda6f0a7e416677ac0fd6f8195d4ce28970d2ca411a"
+ "2b"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.4",
+ "167e79568c7736690c3bedbbc8d424eb536a12855a60cdb10f94ba112317e917"
+ "a1b7d6fcfaa3438d68ee09fd47",
+ "029a2b908614ed7a5fab72f2a1c8e548b6f8b8b45b7581fd2451fe45a622fa0f"
+ "08dd0ba2e8f3c417201ea0277910184f376da803fa72c50d39be2882526d1e85"
+ "df9ab17975764acfb207366f6cd2c8b136a999daaf48f1c08a9ea1f08425c21b"
+ "654180da4adf109b4bc5b817dd67bf7daab4a384034ab4ade694898cfc272ab6"
+ "53"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.5",
+ "0d03f71284f2e483242d923fd1e153bc160f0cdc2c0b76f1bc2cf7d1be9ccc7f"
+ "afa6afc39034018409ccfd1628a70b358333bd96eed3adf3142b1760bf8a9bb1"
+ "9ea2473a2ed85c91cd5f0a5f2d4632d6176419fa1d8cc88b6708477711ea4958"
+ "a83901fef284f5a6c502798c8bd0a350f2ea83ed181eb970d30b78134c8e1d64"
+ "f0d1495b7017245fa69bd57427f74920ba0eede9cba34eb22276b0f27413ba3f"
+ "0da8ebdedb9b0c800e44481d01e6bbb0dfebf9a15ef6a7020b2c55ee02791179"
+ "6f66f43dd846021f8d6f7e01bb802bac09fde9b904becf9990e684e6569acaeb"
+ "3cc64dcf5d",
+ "0422791fe7b43e1f319ae67d918c5987e6393681a1861c1e71dd6fce1923710d"
+ "bced4301fdcd4aad8f4fc27dfa02a94d91bd96200aed8b3c5a96efee7d11af90"
+ "87fb81905c5df2c24ed7ed63d5fc22babd6b9e3b57cd25419a7817e93616e934"
+ "54b95853fe5204b58c098b46de0b3f01f582763248c290b9e80969652442a4d8"
+ "e5"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.6",
+ "4aca963f14acf6a79c51081ef257166671e3b45fee312407ba3cf6d711aba1ae"
+ "25a4a8ba454819a3912a312e990f1fa74cbcb72777f1c7c663a2d1cdb2c5c007"
+ "4d4516f48717de1403e8ff7d0f9de7c7c851f3e351168ba6c414bed5d42bae52"
+ "7b724ceb834d79bacf702c56a623c1688087dc9de9538ea7c7c761cd2fd578f0"
+ "dc3f552ffbd4afc7f4ec7122fdec1a3a2b104d532db81cb9141854d57dcf54b7"
+ "5601a905faeda65c2a7a7bc2b029ad12dd7a6ad1b40be04028b4b5b63730ef98"
+ "4473f0c482148993c36b44e54be9a5f234e743292a12a34bf2ff73b7f798",
+ "042643c03ada724e2dbb19cc07ad0e752228b9d36f653c6a9c0c29356cf4c3f1"
+ "ca193776d5fef43fc55417716669de9ab2addd3ea88a90ae939a5eb11013e228"
+ "ae0816eefa4dd42c6c08c878bd58b49040296a863bfd11285f8bbd315be16d2d"
+ "65d7f5e5f26aa97147f95f5ee36f989aa896d7f9f1b3051f824244f90596723d"
+ "11"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.7",
+ "a75a4580",
+ "004fe4c5d9143c851e46167cc181575c075e69b981f9c103f9d9b011ff8b29ba"
+ "55a43187ce8777996317a03c9d90afc1890a9adeec8eac087f99b815e6eb2b87"
+ "1dcddc8092249d8f513c6c5609fdae2cfc6bf01fcb8025a4f79bf12aa8e10982"
+ "9a0bb38a09d1a39365e0405652dae451e5c3298f47040598ecd70e4b403389bc"
+ "d5"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.8",
+ "7cfc00a643ae99796801ee3cebe2cbb1a6be1cac15c648d4ba3301293871a99f"
+ "7cb143c128c77f96311fe43a3901df2c2a5c404be8314697e09b2e80aac6ac39"
+ "971bbe0dbc26673f31959f238eafd15012e4967d33551892a3d3651fe4469b2d"
+ "ba4557df893ab6b94f1325c3a1",
+ "05985a4cced0e8fdc58924edba9e400e6748214f8d0b83aafa20350bbf0e6876"
+ "ca5a9af3970dd63be684f9936db282ff8b53cf5f1bb1cbf4473301f372d9948a"
+ "f9391b2002b2be3e45ff24a2d899ae8b52b671b04bab460106bedcfac013959a"
+ "48189598427fb957159a6d329c19f36ca75381b9350d34389c16e180a851e457"
+ "cd"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.9",
+ "3d90de7235515949245f490368c1f49383e44c1db51dd5385bdff5bd34450e63"
+ "ce42150b441ef9ebc729a9033453f0a9399ff6861f5065b6666dc20b28720342"
+ "8e72bdf4cb748ac8d4a55f43d2235e0ab2ec2cf2b06a015f41e35168ac7e3c56"
+ "8f2f16ef5728b2be9524919d3676d68f537efef29a05af97cfed7ce9ec45c12f"
+ "165e4d7a4fe72b99eabf83316cdf2bd1644b82fa13e4ffc449e76d44c3876963"
+ "51478b1a0f859615da905f20e68b24565c873f834e593458518ade41c1428174"
+ "da0c47663a7600c65025015e09c1",
+ "009813b2fdc51bff88dedbeca3b14ae58bc7e714c1d92d7426e4944ef93ef9ce"
+ "6d10dc989eafe7348d0a95f99f56948f72602ac5e8614f6b38e68da79f48e276"
+ "8eda5864cff2545137f3cf4d81a5aeb89b21072674caeba0007100c07ef4dcbb"
+ "d05afbad9e8b30d746ea360d6cf875d10a67a57f4b5df4121d7297a4bdce128c"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.10",
+ "20e6a3fe16b521b3c1e6ae993ec6e849a9c11f2042a2d4ce89cf0f99e1b4b947"
+ "1da9a1730da8851fc5ab3c0922055f003758b235c28de40880663fcd80140718"
+ "15dd06494a547ccec3348e12d538d5dfb48f807b59e9b7cd81f391c02c016cd9"
+ "c1a84f9c595179d8f200242a5668182cf2cba3b9fb6ead451d6d27d9c7361525"
+ "d688b55233ff45291cc07402d292de0be83d1646c43c28881fd45549b14d1261"
+ "b12f120438276c6b3f98f55bcf1780bc1a91eb11d0229e1d7868d7fee49d6b91"
+ "68e24de1cb4f0f22e67cbb1569204113027294b37ec7fae58bc64e825eaa4d56"
+ "94d0058f2cd4c7d21418da3c0307fa2f0492e8b37758d3ea40a4e30f60",
+ "01f02b3f839123aff2a3f43da5aaa0b6bbb60c043782f4962a7b9f025c948e34"
+ "322e98de3703e3bb45a706a2bb0509bed9f410528c881ab9a1dc0197068c3728"
+ "c3716d8381d9f86780fe78a6434b72f51e69cd32a7213ccea743b33c3c96eb00"
+ "42fb98a70c2e52fc178ab2cb9ff8bdddc1046b08e047baddd65a45a4e65339d7"
+ "25"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.11",
+ "6eb49f8abc5b4948720a7f42f74084780022e0e9f9f68886d9f34e7f7f8ac154"
+ "dbe19c91b8ed38ec036b614212ca35f79ed874579e2485dac8205d0e56b4b4c0"
+ "000a8a75a6d497fc5119111a40db513df6619655b58a116fabee082bfa79373d"
+ "917656871011241887f442608bd1eb1d95d1768065fa63324fab2736f922705c"
+ "f289fde9267433859207a8bcf12d17861cfd062b88df78870d5a5e91131b63",
+ "02a2fa32717796710b52b051906cdb9815b2d0366c070a78ff72d45942d7adde"
+ "ae7edc73ca9301f1f9fae68a0bd4b1df05a9a671f8a5b7d45cd11fdc0f0ba09d"
+ "25cec3b6303d9a666c76326496ea31ae3886a0c3b7d22762eea278934b96a4f9"
+ "0a501ad3088f702e14763ce33846e2fdbe6d661cb82e6d989df3c5ac8fe40a85"
+ "62"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.12",
+ "45cfec132ee593f0c3f3813d3cb449e6e5e61d13de529ae3e71c998ea456359c"
+ "e66b82045b7ac797fe96985deabc5122530b2e29efc975ee9603b4f96f3ff4e5"
+ "9b0e35a9ad92f2b867794d8e",
+ "039be48f133ae7f0b19eddb213560973a3e2a1146c7942f8264bba5ad008692d"
+ "113801fc2778a7e33a9e115ea632e50188c87b69e8d4d8cca48abf9f251efc00"
+ "17b99edee566dcdc0bc58dbf6d67bf863db8a89abdf12a77f1b70de439d176f2"
+ "eaada5464c79a584270ca514f48f1dae8678ecf1ac296d07c46898bad41acb19"
+ "9d"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.13",
+ "22512987157cf9b9ab4e5337b09891d63cec3743c0f7bc9d182e",
+ "02c7757f9993ef8c6d60a3f5abedcea535dff55ab9f4f62d1254bf261dd6a2ee"
+ "52da6349f47b9b289f1d0ea3e0ff08f455fa5485658e4217f440c08b90ae4c6c"
+ "c25697cb833531dbb474032543100b5f92b678195ddbfb1b59c59be7c83dd817"
+ "45cd4e709a0e3f798ead5bf8662da65c1057cc082d905050c465958b555d77b8"
+ "b1"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.14",
+ "ae48cd83f4a1f94e1719219690c8c6f6737abd15e0d08e7fc2ea0d315b45bec2"
+ "46e845bf1760c86c3f82d84b1e9d68dccc01d9a7d07ecc6bfbeed83d7ad03a6d"
+ "566a89bc64421e7eb47e52c0238658d5e4c5597f125afc6c833c63cd6f97f9dd"
+ "5cce8a2638807ce8a583da032bec81a38cd299a9c78e8254f288516413525fd9"
+ "4a9e0a95c656d73cd52a4dcc7dd0947f4a005eaedccfd03bb1715c351cf059cd"
+ "522c7f538c1628e72a05644e8fff50926fa8682a6753786f2aa2610abfaa95bf"
+ "99af15617151d0bd0fc46fc3b29cbee1e663b923136b5e1992839f0ba52e44fc"
+ "cbd9f320ede20f55a423770e573a9fb2b36dc8f184",
+ "00fba9f6f959b170b0946dcbdb98dc8e8479c669adba6c54636a2dc7d7f7033d"
+ "350405d717f2d63dae65c24b37db1dc3e9f61743af1ce6de2467d185aef08d2b"
+ "f865f075baa6a29c580661dcd4a48f21ff4e7b039eef1e1e20ba80cf20eab6ec"
+ "de60fa5d3767a30e6ad4144713ca49fc038099af536c0d5f55c4cb15335381be"
+ "a0"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.15",
+ "2c8a007b603056d33187bf52cef6161aa5f5f5337fc359d46344721d945fbc4d"
+ "240d30620b296c3977cf45c247eb2c36394079983f03ad82399c4b286c481659"
+ "10b348b95ef39c43bfbeb3566d1d1eea5a427f4cb1681f2a7c401f3f0d6d9ee7"
+ "993be5ec5d34a75541e9f8dc7c6069a8977c9f936edbe41a4ef785a3ef7ba051"
+ "899009ed612a228f903167a934eee69b4f8736c29511c6bdc61eee9608a9911b"
+ "ba52839be99f91d2ef85b8cf10c1d635080829ba7991fe2ef82e2bae27081406"
+ "e89bab75c3ed19e87a4adb72ec2621f3f2585b38cbb36b3c0d405ffca7a6fb02"
+ "24420794cbd8d7831801c881e165",
+ "041047e242b6448741f28a4c8b2dfecacc0ff6619e956a6a6b10cdd01eedd201"
+ "c80e0fbf7c5bef52a7aa9900a859394b47e83d08b5e1da03a33554000cce17c1"
+ "d86229a3a20350d11643a758c116b8fbf72660df4c86ef8c1fc4544c3ae1d1fc"
+ "3ce9f263f62e8007cd7ff7ea8d50a0828389ff431fc5c562816d3d24b607211d"
+ "29"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.16",
+ "7b15d1a79c7ad2d12f75da57d14a8eb71fdd4c4eff5243741acde23ce6dad308"
+ "c81d5d580ff9c3f893ff124fe458b31884daf7fc4466d700dc493f1c7a7dbf62"
+ "241b17e73623fa17814ab4d2c9245be83bb3cc5f9444b15217b2441f459c00b8"
+ "2e58689a11dd5c59fa395d1a6f9b2c25cc8499927ab9a49828533652cee23232"
+ "972d6569ee56447866f10ebad54ea3f061320c6d3fefce34552b6266967b0578"
+ "d6c455b9ac2466361712e7d05bd3332ec130d45c6a4976162c797ad1363f4969"
+ "e4ae3ded6e36ea2cd7fb356609be031a79b294",
+ "03025290b4462f9ab79fdfaa7b1d53a4d12796c85aac28deac2127c8252c2a62"
+ "395a8b819dfceebf68dd4dbfc87c1cf3d017a53a264092506bb6fc9528e6f876"
+ "78736ca56a14a1aa2677a8b84f5e03fa2c0ce4785b26ba92e75fbdc16d8d4c7f"
+ "b0bc39a88e132e1e05ad00f12f072706343f5eb3dab5112e3bbe76ed0bbc7bdf"
+ "cf"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.17",
+ "7a7644001f8013c50fd717b24465477abc34ba9c1e53ad7632645a6ef7c8e64e"
+ "8ecb7bca5b4f09b52f4dd48f8bb3dd338c78182ce86e8bfb1c68a876f7321663"
+ "06a8ea8c0d7c21ff26faaf4ab45510361950c76f95c2730b9d3e4d6d85ea2558"
+ "4ac967a02b1e0a26",
+ "03b2accfeff063bd175ef8ae0cb85bdb800ddc27776f8d3dc7e21d199bb8d65f"
+ "5b242e79d45ecdcff02e803f5681ff044a43b55a9aacb1eaf16784838b1d5a2b"
+ "7c1a364dc405311a6555057ec73f0a8f4e0ffca423022ca6ad74469bbd5557bf"
+ "a1cf4b95636f534537eff2fb16af5e6471824afe2167918c89ade01d52aea739"
+ "9d"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.18",
+ "12d224fc10a0fc40953ab6d701c416c3a823772beafa",
+ "032cb5c8d61290b766e6498aa601494d9f066f27a47a2870f3678943291ab22d"
+ "3c45c076e560819d33f889f8cfab2df6c63c0ce1ed5ceb51547077c08278187a"
+ "8272fec7de9554cdc916ca72f2c45143f2cf3243c4bd200c6e993f0db5b71d4f"
+ "63771e249b19b997a6e5a919ca100c90fea6a2d4dc6881c3a0e1c1355383cfbb"
+ "4b"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.19",
+ "e0d4e2a5e98a51237da5085dcf098ae2c05b4e169254ee6dda16210e4a3fe81c"
+ "7256eaeff28c0c63d854b7841a136c4360b215dca058748a4bfa825868042821"
+ "992a4ed5a7d58f8012207549be8cc9cecc8501b9f802830f865845ce2e339bec"
+ "28059611a1a00b5535c3c615e9d2a13959f1015c8bad2d753a59a6143b3a3058"
+ "ef722560ffe1c18487c741dad61f07a15642e726ad18a984875e68c62eebedcf"
+ "946f13b893b2808f78f9294807d774685494e6b89040eee6de1ba718ba2e082c"
+ "3d5ef17c1028cd66",
+ "03e783bb53dbb67cf2195fc1a57f4b74c98203b1f3d615feb920e4abe8375834"
+ "672f4b8f55fef2aca8b5d40aefe4efbdaac3e82108d07f2f1cf8c0d4dff81b39"
+ "66ec69be5117ac1aa6118e460b92d88fcdd94d08ebaa5362e59d52004b433695"
+ "1437da0f51d63e505615b4b75554080b94897fef293a34c40400c4f99aa1defe"
+ "35"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.20",
+ "64b3ba409803c9b960c1c4962f51271bc89a40bd405ce5bcdc8851d97c9be5e5"
+ "b7464e50d99b6cf8adf8ff832b737de8b6ff1abeb89dbae93a90639487806b05"
+ "96cd316860f68f0027a3503e158967afdff469076817fc7da3223cca1e6c4897"
+ "3b570e0bf74bb8b39654372b7a1d6f",
+ "00d200eba0b6522afb420ebf16488c530352c42dde81e764c0cadb43828cb998"
+ "d0a60b23b5b6958a00fc2553e235e8574e4d4fec9e668dba40de6661abe13fcb"
+ "84c1ad15c4b0cc0c6f4f0f837787c4325f045d61ee2c9972b01f3212654ec426"
+ "62567faac40e9c0a28158a2a6c31f01a849126df9e96cb8209beb581d6846bb5"
+ "ab"
+ }
+ }
+ },
+ {
+ "A 1028-bit RSA key pair",
+ "0d5fb99fdedf4256e28d4b41d707fc27633e899515f4dabf6b462710ac112581"
+ "fa73fa8369582c9fd4525a70161899df6325849e5c43493e13354e270955a43e"
+ "3835b5998ed42a575bbf688d69ec366d2ba6f0504c1ee17dc59b7ea0b4640cbe"
+ "cd8bd7962be8566f0ebd655743656a291285e037bbfa8655801bd0314f464c56"
+ "91",
+ "010001",
+ "e76f42b47402d5e0f96464925ab4b3bc6894300ee486fb70ced491f2d1b36780"
+ "84c1c2cb969568a5f77dabcd40933937a867f934fb2aeaae6d786798e0d04a10"
+ "6f545e41a9c93833d81fd4d75353179cb0bca45e79aac9413464b0367f31ac5a"
+ "ca566f2214bf5146a9484b87e42bdac2b01a996703506be07749aa0fbeb3b229",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 10.1",
+ "b2d588509c2eacda281e7671cba2fca914ef73a3aea9202043ead6b72125c1b0"
+ "d5cc15414620d573d7ab0b3a8ab66a92df870b75b1c4d68ea7056be0419ea253"
+ "e6b08b129e0f64f10abf82e167f8e3e9282e7bf71b043baa2ba2d8756d46b6d3"
+ "6e973415f4f8c0eb43fc604ced493dc046a25a119bd1581dbb597c3e67c2fddc"
+ "396df5d23b7ba80bd2e31290bfc26225e00955a98d911911a399676fbb",
+ "079a7b916f674117f1d877f4934325684148d5d0b0d5c2c6156a11159bc0bd30"
+ "d0a73534dc9445ebe206d6075eb4ea7a7c0432bd44b83cfae4685a9eb9a97cbb"
+ "fa4e82f71db51afa0d27cf27f0609bb3f8806413247d5d4954f789a101bf3921"
+ "728b487e85fa3fd4dcd72d04448e42d3ec05cc475d74cbf765c34e3ec14cca50"
+ "40"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.2",
+ "ca2518a5a224b23d4205d8dd7eb04cbdcd0ccb82bc87961d859d6600b1ac3e25"
+ "a9407b6c065027c04081f445a230ab9308e755f33a759773be6b969e0ea774aa"
+ "6e334fb604184275f36a031daea6518697795bd6a7d6697b406da2cece15dc11"
+ "3d8544988561131d4fc6f6e3c580d806807df2c6856509542e4ed39d346eba15"
+ "976a8fd01d7941b0165606c76176649a161005a0",
+ "00beb921ce7489819d2f85c78839a27d7e19ea0a764ac53101e86f3170a76e31"
+ "8a7ee89b1f5e23e7e2db9666eb4391b2792a5767ee359b5c71e2747910c82c60"
+ "83d6d34829b96fa5a2ec0f62f1bcda5d78f8dc3c650b94e32b3860da5fc5b17f"
+ "bf687ec0075a9c73dc1e98d1f36aaec4493f7891e3ab08e2042d8b1e462e8c4c"
+ "33"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.3",
+ "d433d15b2d61b86ac8ec0daeba65e11ded3c38842525e4b7c8e453b0f553cb4e"
+ "b875a69d7816f54c87793e3abb79fc55113537b4762965cfee586e0a17997851"
+ "e3dc9eaf6f1c9c2e98c9613e3bbea013ff58616b2ab05ab324a9c5ff4c5efdd9"
+ "90dd97d91693c1ebd4c09c732116c8dfc3ec515c20532cba7e4758c68a69cfa0"
+ "ac3186",
+ "03ae3be1c7446ad3efd8bae61b3d32d3ef152482b1bfee312fe9e6beeeab8cbd"
+ "08f4c8f9cf067deab6bac7c0fecd87bbabc7f6798c77ef1c3fd8bca28cf9ece6"
+ "56795f60b37875eabef82153a12bc7fde3fbc9e5e148f4e16cb72a773d9dd023"
+ "17f70b3391400805e85e7a23567b34aa65a35f744170affcb323371ad2ab9f1e"
+ "4d"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.4",
+ "7d0f5bd7900f1e65654e6c7eeb064cb828f355d6de9bf0d34783ffcbe80ab1b8"
+ "ae07b7f1e3f5a320dd9b8b76be0e9772de19a8d3",
+ "09e7a5304171da638be7601fbff6e49536f3366082253abc1db5d1b65493da59"
+ "5ec93c37f5890b5f4715bd5e80c0bbc5c63b74af2e60439132d25213750bc1de"
+ "302e3e8b83dad2de0dffc4faab4056dd7c405e04d5942453659d490f3c3daa7d"
+ "3f117011816b56590104de7f9c052373e2dde414490427a58964493ff45f08a6"
+ "e8"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.5",
+ "d96aa091c160b552b16df0658fa8",
+ "0b69754ed6d7a7d2d85b2c7a306c78d63d0ffa438f43beec3a0286ce57e7e0f8"
+ "5ca430e63908c0fa584ba2505f8c94656ec02494bb032f920c4b6b8c943e6be9"
+ "2f578aa8ccdfaac0a54b8a9c0df548271f8973c9ffa2a20c84762e9017e7452e"
+ "5d74da690f75c099ab91e2a7963bc537f9c24ccc3c418c6e985861d93daab2e6"
+ "13"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.6",
+ "56f048645a49fa0141f4d674aafcf2fffa83f9b452f1feed43057cac27675ea1"
+ "a141d87f92f9cebf6ee4f78f8ed4c3a29deb729747b4f98e4c7590aaa8d56dbc"
+ "61d38cb5622226f68e43f9c4f4c03998aee90934395bc840c86dcc8874776f43"
+ "039f56a89d24bdc4b305df09e5ca0c0512ad6d1571919a3db3a6bd98b7820ada"
+ "0869d225a404027acb6d767fc314db377e8d1db6ef0af29454db2bd4c1cee013"
+ "a59743486d32329583cf80113cdaa10e4f2cea6c4f9fc6e4e2716ede85727c3a"
+ "fd43494609777630ee33637ea35c9b4f688e492c3c640d",
+ "0666ef71e2c8a1eb1c46403fd23e521883ada1b9bc5fbd353bbb3c3dfb570ac1"
+ "c721faf3f59732f213377380397948462fd20a3f0e5e0891a6b07c31b360aaa9"
+ "65e2f0930eb341ee77ec439065c0aad91787ab6d2e6cdeddf55481651aebbf9d"
+ "11d54bc11326183ebff49bd40bdf76d7ef69b67ea3968fa849032fb824b6dd6a"
+ "e3"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.7",
+ "79da89e355d551a0e031f4fb71ab6f4144c4762e07d0641433cb5ec86134963f"
+ "7d2c4dc7beb5c6d46157c6c4e14a4b9c7a2c0d460f1fc062ea1b4f9874d5b1c2"
+ "9ae2f2a5b39062e41212e65c85c28e767589965d1710ad5bc76fa5a6729a06fd"
+ "496e2e0997e57337bd516e6bc79be9e070aa7b86c2ddf14f94985fe1582a292c"
+ "d13934b3c38dfe5977ed1d9f8ad324c0dc07e5853c7e4890bfbdc1a01ecd72c5"
+ "ff68a02f1e",
+ "0a0682f742e743e1c7dabaac618a786f28ed13a6587adfc33c9829d752c13ef2"
+ "7a00c7e6d45e27171a5841771d78698c6cc66778b8c09338e35b9b6f59c064ce"
+ "b3eb20ce909a5c6ceaaebbe93e86c7c5ff4a3917f126819632cf96fab1d39173"
+ "a7ae7fc2ff5c0fb4090535dadb58d87d0da3db32ecec13718b3ac5c30ba802e3"
+ "8b"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.8",
+ "e69ac9433e6c28ac53f8034a868da9883e319e82e6bc2e49455e6e4f098b53f2"
+ "87a858da1d876a9a5a6a9fc14fd24238cd4e4b5731077a4dbdd5038a9bc1f5de"
+ "f43fec77f67eb062faefef7d0429238b25d031857896623a3f1d37bf",
+ "08a020e4209878f1e637ad59daaf835daf4ca664844794c1c648f0e2233dba75"
+ "48bd161f0c0a1824d762031a417572842f8e644aa93f9d91dd7709e16a429cc1"
+ "43903ef4f837a458396bcac24092b01724c6fe3dd1ad243f3f70b5ae6faa09f3"
+ "70caa512104b9176060df2bf121cbce9198ec2fe45a59ebddc467532b5afb9b2"
+ "35"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.9",
+ "45e09056a28e4b2e7c11f65e688a1e3c33f0e52c9a036c09d81de5a6dab58d4d"
+ "55cf411b53ad646e83a34b0c08c221ae0376ab76a79d1fee671a584420564f8e"
+ "852eb6f2d427aee0a096dd72dbe8507c677f8aa00eb7c25dfb0a49dd88a6c784"
+ "76b80011b6828b3aaf4647794422ba6bd63b7ab0e7dafbd36f6c41dea03d7322"
+ "3564969460d928540b739257e70bb68d5c653c3796945895",
+ "08717d5086a6453bdeff77d4c2b856e3ba990babf69701df6ca0a3b3a81b5569"
+ "7d31889d100d6895c97f0a56b47168c98da62e59ec79d7aeab2f9a570746988a"
+ "26f423576c703fd841ae51c9c229a2e9c25fe94c5b6ce2fa645412bee659faf6"
+ "09a32eb2c05beeabaa4f58caac3133e5eaaa27344d30eeca22c6ebd8d9e34441"
+ "0e"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.10",
+ "b81c8bc4ac1fd971b21f027e06f4d87b34d5769d23c8599d1f157b08a7f92e34"
+ "19fec4c8c1b34ca463c768b72e07f9dabc3cbbdd8b5617cc252875002a1a1392"
+ "af0fafc08c7211758f3c042050ad731b636c0e83191a79de5aa2cb94dc8b0bdd"
+ "e75db7d0c8bafb4223d347b024b3d9c6b239619b5d8b6346ea86fb8f24c584dc"
+ "1a47791cb7c8c7ebf1ed438b88",
+ "01b9f43394c7cb885bfdcc3c84962223e8aaa94c6c9b7905401d24f0dc443b2e"
+ "8d840e28a95fa22e1ae36ffe08966f38d38714cf68da8db23764b88c4bb2be4f"
+ "d3da9ccd1b506942aa9d73fc09382dc3308314706e6ce27f00761f3c9bd54fa0"
+ "e31c96719afbf0763e35cad889b72e13bd12b76d6f2020faf61dd3d708228df0"
+ "6d"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.11",
+ "d0322883e598163d722036da3e632aa65597acbcd1f47603109696f9b39fdc",
+ "078d17ab8e6ff0be50b3539eb03ae8f0903b7a077481781fb0b1f09edcf77886"
+ "312ad6c060274f0c389c16314040c8d7d9909cb75df18c82d62dd34eb59c6a87"
+ "d3c46a7ef7474a5e447f7744a6a92f5990eaec7bfb00844d684d307ddb498189"
+ "4149e752bfbe2e77057da7605469af7ffb6727a9981b9439caa5d80e6ae3b3d6"
+ "51"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.12",
+ "e8742f04b5654d9288b231a47a365839bb01be87",
+ "09b75306a7212ea6f47eb0ccf4e2e0d6f8f3abdb9cdcfaadbe51922f92ea6262"
+ "3c58ea74ea1a247c9d731f2c033536b35273c717495f325a60405bd5f5e405b6"
+ "80279e752160478740457216dc929ddd65dea505535546e4770f8211b849c365"
+ "218e566e5bb41bfc361b65cdccb0e604c9edb970ee6a286a1fcec0ae9d92558e"
+ "ab"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.13",
+ "a03c2b85fde46468d1c50637b00a72dcfc32c41631739c060245f53e57c66c51"
+ "766f24eafd93e6c66743480591bf14446e040b67a4f84699576c2e1463caccbc"
+ "b073e4b7ec6da6c8cb41d4a123c748cd7e83d261e54c2fd2bc495bc4c44a78f9"
+ "82003403092ec6960c088e2bcde348a2e0e55a4b4f42eab229b95c383f2113ed"
+ "6cd1f3f3167de3d28d362c8d78b2eb6e31620e34b2f0f941dacdf7b4b8568c6a"
+ "863a551d7bd4a5d7093eda69e1e28056dcb1eb69ae03ad74be72a75ae8fb56a2"
+ "7125ca3d2db3769d13d35db108e2644a7f3b37938fec9762315206d30ccfd576"
+ "ae7de0769869e5044d07646cf78c64a486480b0fd42cc7b246",
+ "058da5494c4e98aa121f67f65a2c865425a9e6002b223f0388809753573b4f33"
+ "4de45d8f0007255d112ddc84db266700e440b5a86900c3d3d35b024c18d8a25a"
+ "5800226d0a56d838d8919e6d5a8730d619499015ec4665c63d778083a042dd4f"
+ "052a1bbb5f4080cbbb41fa945bad6a74779f680725e47a08a0514f350fa5adf9"
+ "0a"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.14",
+ "c40c70f26da569486bace785da32e337a0eb94fb3a0aa409c5770175c8e8cb2b"
+ "aa8d2a1b9846c37df7d671036d5e91",
+ "05256128afba1f55d81f79ea33879147a24ad7779346ee798b211c247153ea38"
+ "d26b217065f61e0110b53d72cb64934d9b1ad1b3dec332092d258f0caf1c4aee"
+ "8b23e09bab0f0c278858b441d08ca3ae9f00aa9a3f018f7d9fa98a18df0d2484"
+ "7e567a47f5779bd1793a4b0252f2bad40c9c4a81301cc28c2609d7bb3337e97f"
+ "14"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.15",
+ "9e6dcb11e0e8477139faf041a74e2bed643a62adedac7cbef365ecc43ae4e582"
+ "60bc724623bd6342dc660d66142ea63680715f522ff3cd4b636f84aa9d75fbfb"
+ "c384107e43004d986fbce1a27f7ecc7d02392c",
+ "0ccf234eb480085d920d37d687965d2fd2e4a4f3bd3bf7ddc16b5d62a6903274"
+ "207c6f90836e29ffc63a57f98130c525232519c708f0dc8a1255ab55db1a2b9a"
+ "bc11061602075ff6f97f9092796b98871a6cd5d2617ddc9d255a7300c910fd21"
+ "0b14a981e5a0e0c6bb2b045fa9756898b93b8a634544d77afdb1cf0e7958f11a"
+ "43"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.16",
+ "20bc463b5e1220a39c84e89fe6716eecab5555f8bfce60cfb83793cc40a4da1d"
+ "22c0ab4eaa931fb747be35f1cf6fb1465bef1df2760fcb3f70d3e296e7b27045"
+ "0dffe2d588c4396a5f6f1e6387aa86971fb0ad24df550443dd122bdb2cf3c9ed"
+ "6125fe55cec991cbae8ee1562a8c0f4f364f8f0a80cb30fd99440bf655f0804f"
+ "92968ca2e01c0d5abb4ee267636dd4f511a8d3294116216bedc1088645e465d8"
+ "e198b8afe1cd5424b42a533ced198ad597",
+ "051b714266066bbb819a2a3805a89cff461875c095f4f38982d1afc2ad2f1424"
+ "50b8a752947f031cce2c9c340c8ac9f9f7a548b7cc17e4cc525696ea0c8753a1"
+ "e15bcb985deaec776fb9e7d9f75862f8983523d9f871c63fb7561ac71c376bf4"
+ "95d4323859bd14188fcdfb4b37abcb5dc1a58eedea7e0fe62ac16e208aab4cee"
+ "26"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.17",
+ "92da260bc213b72b48a05753503d00a1dbfd02ac7b9fd44d2401ea7ad58ad186"
+ "1fda536329ae4173c9168005b9662c05cbea47ad864af7cb16602d3d183471bc"
+ "98bcc62c6d00d334bff5b90cfe7d7e12d07fe7d4cbd9dcd3c4c23490be8cbadc"
+ "08c9177980373c79eb4eea6d81a6bee2270bf420f91979ad3f271fd68dd4283b"
+ "e81410928ca45b9deb58d3ae98b2f4fca62125950b5ee128dba105c35cc398d1"
+ "5e742bba92697b5c62b267ce01141cecef807507de29c485305d0a990943230d"
+ "8d9b7252ee0b1956de845f2fbb2838785b470a7c2053db396b315a30d8a7f91c"
+ "fffd03e8a39ba8bc",
+ "03e23f8652374d48d381c378353eb47d9064cd708e1b9bf688704c04c0090088"
+ "46e6a47e0bd2e30c3340f5d4e19d2dc5d8890c8f0104dd6f5dd6cad9c4d99484"
+ "09c3cc0be670719dd0484180891c935b9979db8eb468a23e4ef46029f3af1457"
+ "4bd10b473edd9b127a306e5124ada402c148f51b52e7e628bfacec3fc2543a0f"
+ "92"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.18",
+ "8603a5622a2dbbbcbbe53330e908d5a25f6e67a51e0768d7c3c3fbe8b92e8b1b"
+ "36dc00743ce33da0f1c8cfb00d63edd6b2252fb6721397d2504b30ed1d293a82"
+ "e244c951bbfc24298a42ffee26e456a7be105cb5e37b3d25de28bfc01042c4a8"
+ "2ce870455487e5b30e26f8d5398c86126e",
+ "0822fc22a9cd877c09b6f92e8017ccc028d5379967c7d04ef32f869c7ef67d59"
+ "3c7745f629d93df260038cd333eaee92359fdbbf84623b7b5514235b8306272f"
+ "4efd13a6700be9289ad54e57d52d1febb46a37afd695942c4cbcfd3768f2821e"
+ "888efa0e2c5fd3c9c42cc35550d7955cdbd35c8ef8581b41f8ddab2618262e3d"
+ "ff"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.19",
+ "067d4becb03e1eb275ae22507a77a5396e719b5f00b105950bc7998e0803da57"
+ "a4de08a4078b9a00d2d46f",
+ "09108d44575f614a683ee4d78bce1c58f5243687cbe9c5483460b65df236927d"
+ "bc78c06439ce1c7c519739c8f8950082d956d60fc3645ba7af8e78895470631b"
+ "b4da00c01b982cc11c68d2650c7caea4a26e210ff4b1cae1db505fcea9293487"
+ "b2073178ca245cf0ca2356baf865546b54af9535bab18db679ef5627092979c0"
+ "a8"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.20",
+ "884fc502c8824849478b2eac1e7ebbb7caf28eeb4889458602ec703581d05ef9"
+ "b1a4220bd2f922f25e464c880701c8a45b1d1fabc8662eb249400426c2226238"
+ "eb8ad0f9069c90f0018277448025a64180ed55d1afd27aff4f00702f715d2910"
+ "000df3925c7010ff117f6d8d2a816709489efd29a45c5923177bf92cd0bf6b94"
+ "745d348a144e98740f72226a3e2a9d417b7c1fd8f895f515c5c6d406a72bdccd"
+ "39152c30fdbdda0e62823ee9dfab3432e6642eecb6987b9046e040a478a4df64"
+ "8defb3016aa443d067a1fa4155555374f8ba325a8b55e4d6b5fa090eebaec9c9"
+ "2e261cc04ceaa48b3bed7b3f87d3",
+ "0b41b412197126159e9bda1a2462c8a4fd3dffdc6e98e4dbfc06cfccf16f74fc"
+ "b52338af14ed3936e02c1d7e77236cc6a489f00f089852de5cc425b45094a042"
+ "e385464b64c3b2ffd01f19a01c2c0381f758a67365d1e65a707b134e3f8a9316"
+ "b4aacb7e851a5eab3cd811bd4522dd141a00157dc3fcafc4154caf0593ca6210"
+ "2e"
+ }
+ }
+ },
+ {
+ "A 1029-bit RSA key pair",
+ "1ed7eea9405f507f941623a17bea717b860de44cb77687b8b85a6d7d1ef4f862"
+ "8d257cb94238c625ba25d46aae593960af79f75e28ab63ac3cac4820b82da1cf"
+ "750d6c930d6b827854aaf6cac0c17b80b029f5d319ccca665c5694f54ba5f096"
+ "f4543413ec4c5e97cc1dda89d2afd428578759032adf92895065baafe88d2d8b"
+ "61",
+ "010001",
+ "0d938072b16a02f5d50a15aeebeb5afe431874482c6d18fa7ef316c47f4ed6d2"
+ "124cd0e47eb89cc7587374576cdccb3bbaa195f7b531139369b56f9e2f53aea8"
+ "ac7a97e1d7458f526cf7d710c4902aaedf997c1194b87b62ccd8dab8ff5b67d4"
+ "0fe83de1b82b91609a7c5cf39229eb3a1b2f0ebf0b125cb80091a07ebc779ce7"
+ "fd",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 11.1",
+ "845519dd45d2ddcbc8dbe0b82954c458c3664d88274e502d279146b18f6a8167"
+ "50e94b4ecdee6832cb35dfcbdbdd3e5dc06404d5f0c70e7c7cd0e19f38bc5ae3"
+ "2c7cd91f94d8f56782397bc74e6b069827ec2730173740ce4a10e648c78897af"
+ "1a89e83331d0f461378d06052873f17d9ffce46a32472607fe73e4a561879e61"
+ "9e7c1ae814e45e1d2bdb121946b2aeb8563916c543ebfdc2c090feb5566500a8"
+ "ce74afa45372bde0c6673a7f6accb0ee9d57bde93c36ddc57b8490aa2d68585a"
+ "3db7297ada6d9b3f356dbc74d315c5fa1abf7de6cebca83c9df7",
+ "0863a626dc42baf3e161c35b3de3b1abc1aa5adf5416465d4c7b6b01ae2dad73"
+ "f9f158eb213dbc360be4d47e5707871c39c38dbbc96b46c8f9afebd3ddac8716"
+ "9098e1a76718d354cd091ca35296a77c21d2512ffe65e3b71b9022e9cd1f7c35"
+ "ce1365fd1f2c2cb967ff4c8f90f0c8eaef0db73fed00e98cfc83f80c67b3be1d"
+ "33"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.2",
+ "868e7c4fc6340b6bbeb7b86ea89ee7265f3231f48baa92e4a2e8ce0fa1c1a8c0"
+ "fb0aca944c74bccd",
+ "10cbf8717f76278fcc8fc0aab46e90a3d180c3c92a4a83eb93c8920af88bd650"
+ "6b4073453f0beff3e61edbb4dbc9c947c69deb69a1ac929efc15625b9ed7cf1b"
+ "c423a8875f3780ddda9eb2fccd9fa014626a7fcf998649bcfa5953a3c43efbcc"
+ "38704d024919df2fc4adea39e34cd15cd4f86ad3f501012f6bd28aa5002c3b41"
+ "ba"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.3",
+ "92cf880da58915e3aa95089353e46184c915945c57679c1e4bd3825ed919a320"
+ "52e9786e23b942539b9315f581daf0b41fa3261b967de40cd5d92a4824f364bd"
+ "1e1f51844b109b1454134adf234e",
+ "08828966ac5836c513da4ffb87618797943c612ede7e12b31003ef171065b4ce"
+ "dc6a80b1456c21b674b3779ad35f70177aa92c6eac0b833a967d7e98990b4824"
+ "4205dbf26f5cd57ef87dc6fe5ed999cf8ca75dc8e626fd6eb281c499aff72989"
+ "edf52ec6f3bcaf81ec5f8e8230b87ededcf7b778143ed6c8cebbac9de54109dc"
+ "f7"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.4",
+ "873c4715902ff19de08bccb0cf263763fab016d0220f0327b4755e354eb247f5"
+ "dbc2d396989bbd36d31f61989390cac16643125e63e1a1ae1f1bc9bbedacce67"
+ "fc1b51a7",
+ "05259c481593ea86d1f002ca58aaee9329fafe218f6750f0e588f33b64e708fb"
+ "27a6fe81ebca8adaec757a14ff55a0c88ada2c3b43e39e8dfbe676894365a221"
+ "0c2aa81f424d8529c2076b00c92dd8c8ae3b780d87dba729ddfdef7d407f854a"
+ "71cb688b9f03c71f3baa24a2a6e1cb410774309e40c13c2b264738e5697cfdde"
+ "f3"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.5",
+ "14b27602ece8f067b58483af1777c4ed10b8b64e64c69f57ef889a1ca5d5b5d6"
+ "51c608db239deea150ff12cf50c8679612f97ecb09f7",
+ "15c4b3f081a2e58af594e42fd6accf1d0d61d93a5e3a84cf904b98d9ad713361"
+ "b784b24d9295e43c23be93ef36514a9bac2c1bdf4ee7323436763a20662f2db3"
+ "41d9e38bed5f12c7dd18bc3bb0fcba5c0050bd1a2a44037197b8c9fc2aa599eb"
+ "43c3d9679242c99bbc49b03b98eaca8346287259e6ea2e89155d0dd2b4778035"
+ "75"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.6",
+ "e566e5fa556c765b62bd6e374521f508fe446668c6474bef046cc6894a87322e"
+ "1931e80d9ed9ea806b167a3af77fc04938b5548efbc068d4f1966a997625af31"
+ "a4007f0698a8469ab681f4d508b4a48c8fe720cb5a94a7f443dd5a58030497da"
+ "a959a3aaf6e34184397a",
+ "07e7c9442624bd266cc1cd1af3b8f06294dda1c07767fe19bced6c9ed7c4b1ed"
+ "7f26e203db7f3a1bfa57daba6f3aa06003bcdc1e00c2d3d76b9cbff96849b1af"
+ "f542d0d7afc6e422492eab0ab7f8e1d1ae0b279b851945b765851b9f8ad880dd"
+ "164c11ac4a57f96a0e484ba16abf1cbe8aac090adb6a71797e1335eefe2ac998"
+ "0d"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.7",
+ "b443c343527b30d5ff",
+ "0b3f13c27224d16101b9c8201f1b4f8537db3c116f3ce130be0de0dc0dd20f77"
+ "3cdf7b7f372387c4b653e5dd442184457411a82f8ed00366ecc077a4267c9d7e"
+ "56549663239b4319fe499aa78954049c743bbf09d77b3029d918bb7b9a6ae80b"
+ "129e41bb56dad2b8a4b6f3193374c8292fe017d063347e91cbf4dd3939c237f8"
+ "3c"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.8",
+ "db90047f615ad71972baed0c10626ec8cb18c6d75eaae058219fd6195426d44d"
+ "5c543bef3c4c1498e877d7c853e53121eb31570081d5de4885cbc925a6c22321"
+ "ccc9c3784eb219e42b7edb928877607329798d55739c89d6d6b3f0d430bbbc47"
+ "22eafa67defc86aba6e63483fd6499b03fabdc8465d98bbbe4402b0231135c21"
+ "243d7e02ad5f7e9e8b9460c12dde2a395b456961cc3dfd9a12f5d9359e0b3a6b"
+ "d77f44655b603b0255dbbaff8bc840759a3462fece0d8db6e45e2fe2bbf8b6e9"
+ "7b3feac07986738257ab9f8cfa795a20192b5e2cea118ca762252af6c6eb00ec"
+ "5c6820bcc7c7",
+ "00aab067d3a8633d0bebd591ed34d067f4718cd7f9b1e35aaa405da1222ab940"
+ "3866921fbd057433407a4aae7e26c5cfa0bc9c1157057b1da1cf3628518719a6"
+ "03f6c3c4dea30bf49db9b068afec698121dce5d60d93a6f5633fc6af9df4c5dc"
+ "cc138c294edd429d4afe3b3378868255cc53788cf2b47745d64acd885bb47d2e"
+ "ec"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.9",
+ "2be0067b95185bade118dce95c57029b554b25e1c39519f8f89073b9a04b7e91"
+ "299cdb87b0bd17c9f151925c756eb9b645072561264107882138854ae7d507e1"
+ "5fcfe847094540e71a547f63b590467fadff647f643e1cec11246529062c9e40"
+ "8892f2a20cccc0ae45ca97a47fcadc8fede21a24711167706cc4b5d69477e5a8"
+ "a146b960cd4b1727427b16517b63ebfbcf84d0b1ac8e7e70f044357522b1d0cb",
+ "0976811217714544410133243beba9a21a6f7212c687915c72027bba3112f697"
+ "05425cb994cbb6d359c146b95db1446435d4cf961dfd5c498739bfd4be6ef1ad"
+ "d74b81b2898a4ce43dc37cb0e9ed7744cf409babff71788542ffd286ebe5255d"
+ "63dd7bd55ba43f5184e248d3a66933cdb06991ecc90eb39ee71d65c88ed24d94"
+ "4c"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.10",
+ "a790e6ac5d556fb7cf44460c7b9be5eb7f24f987ff890dcb7840241d45545b71"
+ "05635a1aaf4457e6410c65aece5011e2775ec8530a64a18839e9c58a7b77424f"
+ "74293dcb9e9ea8736d6ba58b1c6653d57beaab98735f7af732477b9af6a33ff0"
+ "75c7e46639d748550820ba6abd4a9d48cb4903f65b76f814c6cdc95e8d9e870c"
+ "244a029b294a8a5c826ab161f6f978d9f1c03fcddaaefbfadb8caae84bc2dd33"
+ "2eb04997d61efa91e9241e4ccd9764c726e766ed3b0338d086f1032c1533ef59"
+ "3f88fd56033791b1d0625c6ca51eec279cfb6ae3f12700cf5bac271e6567",
+ "0d1b111ce8de1d7c4f7fceac73df70aa6eda58dc32eb98f78e7fb9bc25de3e6b"
+ "09ab8cae3b2026b6187ff63672e57da4ac28962445d1fe951d27be6a6ce7a580"
+ "7e1376139446e8549d48aa59fc223354d121fdcc38f1d0275e4186922700adc6"
+ "1dae1e4be805222a1cf07f110a6158a2a26258f19c657a110c0d9ad291680c75"
+ "96"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.11",
+ "32afd13e607d87b25ff40a885b2509f521f2a0a772a96a39fb3f71c96384b3d7"
+ "578f48fcea9739560a65bfb483d9608d202555f66d612d16b9255387b4e11241"
+ "15ed48bfef8b89d8ddfc219ccce48786c9e6426a9212e7b16d971d278a1118f2"
+ "f86b9c4bbf75c9c2d099e3f66548f1f4a8a821d7274498f7cce6ec5e2bf2bfad"
+ "2c6fc005e80a48cae46992fc8267a6480acb894ccc9b62095cad97db70d882a1"
+ "3fb38588c48ca190f180cb3e61acb4e2cfd9cdbf855c539921f68e1149d0547e"
+ "f59af53792dc660da5ef48a7ab8936d3d36ed6b6469eb6fd95e3af182c8768fa"
+ "60047854f18f3741c1883bb0792688cadb9e4df391d91145b85e2ae24ffdfe51",
+ "01a937b3cc8254d51508709e4a4de7b181ded9a447b3ec8dad492c397952df7c"
+ "550e4b26c95017299d8d455ff7971c338cd014df78e2a8aa5ebee258f49253d5"
+ "1ace9a49319ffc807ad70b2df2c96dcdb73b48acbc4f6c3c2a701e7c154b279b"
+ "0705bdf2548c8b3611b97da1ac09cd12125099540bf7ba99b08c2f3d5f6aea7d"
+ "40"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.12",
+ "5b00b8b794a10d21f1b45ecaa20df7c5b3522c1b1db4b084b959aa4e5658ac54"
+ "68f6e8fb612ff99f3216b5d21cb4acc0bb42eefdb8e82d754b85d09745894a52"
+ "3c0162d08ecce48b99dd6c38e2bd3d531c8562deecfc6152369aacf580eaf9db"
+ "6c68b69df2fbf3053f601f70022c9e381dfbc59099c37bde5ad89a8cc1efe4c7"
+ "b7d78e9097e08121eda64ac45c327e5edaf922d3c35f88b52c93d399f4c23836"
+ "2fe9",
+ "0fc6ac1d42947938cd2586d0e7fc3a0542b9af12d36eebf92b5d049c7965b11b"
+ "a9ccbf4700f34560911177b9d1296f1c68e3af469f4f399dbc189c23ea746598"
+ "2813323305ed6c35ff9cc109d0a2303fe7d329ca317ec4b18edd19c62c60a3c8"
+ "c3106f86dbd072e3e1eb8785288c21abcac22e0c0d41f4e23e7f394d4682f6ce"
+ "87"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.13",
+ "b750ae6d4d2ceb92140534648d36ef25e45155f52bde1bf26ab7",
+ "16aadedca09e062560c661d2a49b0ee4d9ce23907c69d10004f149d103c59c16"
+ "fe7d4373597db9ffd8923a77a6b943b188c47425e2a9e530413efdb6848dd342"
+ "0ba53ef81c25c578f8d9514d93fcc9cb1fb52f58d88a57d1fd3fe22da310ecea"
+ "9ece55e9608d63ae21dbaea6571b78fcfdd271bb659257476b5995687a02bbe7"
+ "89"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.14",
+ "47be01020eb7e7875bd4fcc005a82b36fdf2145ef132e2ed162ff694bc71589c"
+ "7dc6d5a3f89d597f2d2aa343335118f6fdbdeef23e613cbaccde4195e664a009"
+ "4b07fc0a32848d6139031cf572a1e323c5a707b6fa2aeef2dc872dd5a3e76b13"
+ "f8ef94adebd4e205748e485b4001d5d2a090b89b2e6474c479e7b00d2d57f586"
+ "ab76b80f795ba8996288292c3f2ca51a44e4e841c03707e48025af4bfd0ab6ef"
+ "eb8362edd5d23405ba0e231b3324e1ca3c5d639d2c9d82",
+ "063917929bbb209217ff48ed4f55d07a03f76d6d94048b6f71310b2c96e214ab"
+ "220d4e45ac01c93dcc8a5c26a02df61ffdb317549665610c84bdb8945fc6bbd3"
+ "8baed7fee98eb056d9f039a860d452b3acac1800a932a28c88286abda8de3cb6"
+ "c0d794daab7a8ba0110933b4d1ded239cbdd557d3e5a162917853315de680900"
+ "a8"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.15",
+ "4b9c09644810d4b30655ed8338bb276b624c68019822d1fc8f78861e13e22ac1"
+ "71821cfdbd3f8f5b8dc9c0de732b746e1d132e5f3f149a5a867c2ee478e8f14a"
+ "d4b9ddebd3ae7817e84955b3404b094393e61ca0189d055369b4243009a0f540"
+ "3f41c1002308c00ce699671937baf13c7893d663c947fc7f84071a672e5e0737"
+ "8aac08b3faf0fccf5bf283092585ebe240a3004620b6f3aeb6732b7b9d8d3bea"
+ "fc8467d1f1f1c7da66b1bf5ccc145b3224245fae31dfb403f493c0755357add7"
+ "cb2763713226c54f43640f7a670eb7b1f6e9e772f2e51417a705cfc5873ffb88"
+ "a5db07ecc4ee89f330a6690a8812",
+ "1a0b698cf3a058b44919af73c3de328e86ce9a5d4999e0122f414b94f32b2d8a"
+ "b1e6550cc0d48dc04befac2c67a4d069a7208f142dc267b3e38f6338a0b1839a"
+ "93a836807d181e3f0c7e877fb2421602005bca25a9c372266d18e6d500c5c7ab"
+ "13385283d2af919d0bba0dcb88bf7bb9972d67008ff498547d80fca658efe764"
+ "a5"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.16",
+ "ec9ff14b9f197a2b4f24948c29d2f64a64625223ddb85346378c2c25343fcbef"
+ "585a99e1ec0bef0ef9d09ead85bee1c4bfb35e48fb26411bdf180dc5cf317b3a"
+ "348371c7c5f4aa6d5908fcfc1ea39018cf0449e55f4ef994bfda404f1c189fdb"
+ "8a0a5b0906c3d40de1e787c2db4d88dbc210b9f801f4cd9c97227e9b2fbc2811"
+ "e38cedd9e9f03560031d4c958a7681ba9d7ea5e78e9bd8bdeddb4156790ef21f"
+ "b74fbc4158c2939e4efcb82efdc881886a5b6713a24b9b5f2ee25ccf721a64e0"
+ "f640778ecb3d35b4b8eea8ece31232636310ae3cc6b82b8a",
+ "013b42057820c73e3acfc1df4de1440c658e0180436da7185a9fabd26eb32674"
+ "b554de354d1f4f24e87773267fed9dd0fd8293eaca4af3d3a9dc518c8e495a14"
+ "7695111d3dc17763f1f02eec1ee29fb1ab749cf30c7886da8b2f646969598aa7"
+ "0f9a92fa4f935c7cc77bfab6981f0df0d285cfb10d66581539f78d0368ed4f93"
+ "01"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.17",
+ "414cea8eec6da3c66ffc8470f7e14760f74bf6e75b84dc98fc8060dd3c219e76"
+ "777dfabaa6e6b92955379f3ecaaf5fcb8aa5549ec9cdd1f5d577201b8e329f72"
+ "faa2bcadeaee388daf7d408afde6553d2417860f3c8e25305dff76dbbd9516b6"
+ "868ee456fc1f7b58d9ed18a46e4fc1e353e8d076bea30bf247c60e6f685801a6"
+ "d3f630aea6abb412a941ffa6f607f6bfb13d900127bbecee4f98a7aca6920811"
+ "575053ab2d427013801d8cfbc3880f1475431555a086fa5560c6e2206d9ee938"
+ "1344b8241c1dd1d86448753af44b00a0c9",
+ "1697bb23e291525f4a0e79262f3406630d0d6df332496926c4e5aef96e41d955"
+ "148647eaf790696af68c78eb2ab62ff7196296e1ea886df0917366090b630aa3"
+ "1858b51615873fa6bc8ff0885c57b2e77a04908893ccefb1412403991d0d23c5"
+ "57d222291cb8517b43286ee0056758d9c10bcd69bd68b84a2d1f537905b8a465"
+ "e9"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.18",
+ "1789b808b10de8d1778aa43f94101cb89f56343061a1a943bb8da55ee6b979e2"
+ "7afeab0ed8ee3714fbe70b3be820603e5ceadec4b22f958773225df3aad487b2"
+ "8057ebfebe2c8793da3846bdb15903ac71e9c93b2016668bd906301a0a7d50dc"
+ "60b2fad8759d18db147f2066865fd90950a188747d9b696853486deaab8e443f"
+ "ad2992fc8a565bdcbadab0b9333ab7fcdb9c3d0bcfde50a58d2aeaf1cefb0c95"
+ "f90773b2fac137cdbc",
+ "02f99751c84438eac7f9963250d9ee22fda7297b6e86e2a8bcc7a9b5ac01f790"
+ "e09911704660858ea5c16272c38133fadadefa23c102908e419de2ebe9ac2719"
+ "4572878e2a971f8831c8f917e852e851df99d4df018fddb2cea31ac3a7b68975"
+ "e80a997cb7dd4d4df757bb8c3ecd910bcb06033552127ac308117739a02c2017"
+ "17"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.19",
+ "ff875cca0efc3d90f56e31f4bb668414894d09de90127f8466324310e11369a3"
+ "f2f6493c1c78a362b2a14fb5488cb56ce022739e43aa763d9c1c97b621cc5368"
+ "c9c00e81606792695f9af9ab633ef239eab3449dda9e6607089c375190354f7a"
+ "59a4b3ef75229d1c47ecdae33b2769ff5542655e781022d0c43b421a99843c3d"
+ "e10422ad2fd89dfe446615f5192e7579d4374379bbffb9",
+ "0268917f8bdaac9ebe32b0dc6cd9d39efd3f88d817d66cb6390d7b55c6921221"
+ "844ab8c08986d3f2ea49bc6e3a1002086c0b6df163f79d16116a93c4a2cc0422"
+ "c94841e1e3b945ab1d253ab8d7d139c9188ba83027c593f83a6f38370e7f0379"
+ "ffddf1427d6fcccf6083313f1815b5ded6737430bb4a70ba81484834d8d1d29a"
+ "5e"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.20",
+ "e07ecf00e2401ac98b2d5ae0c9b83f219ab027a65199fdb634596e2344624138"
+ "729532495328f93fb3a33255278f3ec26065ce54995d424193bcb7581bfe1ab8"
+ "957d0b961c3030b820d09c9e326cc30c0af642666154",
+ "00c46db41b65ddc71fbbfc125a4f9bab880a2f0c1f041c411df7d45d1e19997b"
+ "348eabba19bf79b22177b2a0d73fefa5008362ce5960d7ef58a58993e74603d4"
+ "d9d0b3dad4b20c829d36efcaf57f0c4f0cef89015a48450242bd020d5f52d8b5"
+ "0ea13e56a1aad601915d60ec9abfc307f18af20672384dcc12f9822731369971"
+ "40"
+ }
+ }
+ },
+ {
+ "A 1030-bit RSA key pair",
+ "36981a95ae24181452da257c038f05821412d84eb47a43fcc7ef1217959ba677"
+ "027f7086d3a85cdd349f920f034c0278792dc8a8cf0c0080e5c61f474883c687"
+ "9f4dee0ae952478a5ee2ce4e3918641e813cb374f7b2832bcd6aea809d254fc2"
+ "ca9ac5a332424ab65c2a261275d19a414b616500d5e373706315f063dc885d7f"
+ "b9",
+ "010001",
+ "09ad031730b6327355acd69468700e7e9baeac5a24a7ffc93b292eb871da5492"
+ "46a5ce0c835255651a28c6e2f4c761afb6f06b9e2995fbb7dca174d5362faebd"
+ "c39a72c5795d1f3392ec088b5dc2a785b2c9c4c6e669e723b5dd0ce443255512"
+ "67dd62e0f78d2424adae48e249443aef4a370410db9e709399ac37cc481b5900"
+ "c5",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 12.1",
+ "e4b2d60e3bdd27816f",
+ "13fd4ac1ac6848173780965aff5e61c596892bc147760d43079b5d7177e423d4"
+ "86f5a73e1a16b3ce9b5edac161ea6d4f6c23fcfc3e6219cac556067ffaed4ada"
+ "c0a95005090b89844c54354db22aaff9eeff9da5aaa5490425e135cc0f64584c"
+ "7f05fe336e4440bb869286d44af157880e3a40fb06725d09deb37f1ebb181c8f"
+ "5c"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.2",
+ "788685fc5805d627b13f2fe7fe6f7c9ab2ca4944abf308b86d1a0f583d17b576"
+ "02439e1f2c6e0c5bf78170501338b4c447e9197b6503fb73ebabf776defae33b"
+ "dcdce77de79b82be1485a8aa9b820937dbf428a20550966a86b62a172e6cfbdc"
+ "fe0d6fc67a4db62252fdaf85f1e6bc14f8ab1c53326aa6a7bc5eec88e0b11d48"
+ "d2b561f2260650102ff27b57b70072bcc121e35e70f3780c8333b5bf6b08fa12"
+ "08260f33",
+ "0904cc11ac66a9837b74568be250e53ae4bef78dc67ffee509e5d9b472583eaa"
+ "a56d4c9ee70f6e82dc998b53eff1272bf01f09e5262b155a6e56d1504003e4c8"
+ "a46e6502553278230d6e81b7291843ab9769737f3c693152f17bf2d8bfc782bd"
+ "b3fa0aeadf0d441e1e52dea54b75cf165e35c382d31174f6679d2f21b981f413"
+ "58"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.3",
+ "4ec7393fdc4b90af8fffcaf34e845a09656aef9dda12b0342c46eb049174aa51"
+ "1b43c94d75c0e29070aff5b41423a170d9b3e8b21224aabc531d88886e2646d6"
+ "788f1baad4ef4b0b4bde4b12ce9052082e2ddd0e3e6caabb0a14344b0a583f40"
+ "4c1b6a3c7bca8a5885d5f224af1fcac3fad9370e9b2974e8ca62e22aceb9",
+ "21a66af627ee0dd05fe7563cc1d29ccf6f8731b41e3db39597893ba1cf375f78"
+ "1788fdf073b0b593c76df2816ec6defc224221ac19f5bee44fc0e5d4093d3468"
+ "278fb42d405a0704465322da4d3a7ca9c3da73c3d082aee567b77083323e75bb"
+ "35ed77e8db9c01b496a04cc4a899df359da4a2287cafffe1ed63cddead876c94"
+ "07"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.4",
+ "907760db32969b097dc124ef89751511a5d230596d2fd8a891ff00f05fbad45f"
+ "72a45d465624a3ab67afdbb9e5f9e65b63e30c2e57fe7f32f399011033dc0529"
+ "c0971fbe064fc5edb01f84cd57283fbbbd2aa02944110b6b534f74082f56be34"
+ "6cc343bd4d0b348091c005c6199a7e3d56885247b0c16a36b235b8f5d4f00a6c"
+ "6bb6feede88fcd788d75cacff7d95687996571559c05796a55711d7746bb92d8"
+ "52893ba90675f98b0f5408481bf1543f39de3d0c0c1f53495bd212ddcdc6d0e5"
+ "7d7a3dbe24208cb24ed41de03a5f052a9b5812700a5ce05c0200d4719c55544e"
+ "7fb294d344a4f205ef9a3497b567547cbd1a633e2b79d3349095",
+ "0ec938a0d4b2a4edd278d63de761c102e2592102ee05db1b591e0d857bf66684"
+ "9e74cc19b7e4e9cc392de539f790fc68e3b521db3a1a267e5a4e1219752e0199"
+ "e7019a248554c5bae3112beea40cf3e64f8aaf9bb1e9d1c1d8833c2bfa31b9d5"
+ "450fa249297fe2e46ab03e99b1f9c651d539eb53ce0961ce6023c17dd7383dd1"
+ "2b"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.5",
+ "bda554954732d1d5f3947555c61ffab801dbcdc8121dc6819127c2f22a436d20"
+ "622d1f4a447c3a77b6585731afc03e77baeb709c1bfb906a1aa1949ab6763a15"
+ "c7da5a12a8f395101e646a837173141f2a0cf536024b36918cf9db95b1cc405a"
+ "efe63a3a93bc4ada60a0f4e0729f4db8b76fd64efcbcb66f0e4aaff3",
+ "07262fe1f3d7b77932cdb7cd96ac198b9303eb44460f5298e8e52fe6705299bb"
+ "d618efd0b36331562f20b20e866d99c2d04a0149f564ddf66ba319f3b8482539"
+ "6ea8b893ba5b3ee5e5245cfe6b616e30a900bf83bb763d20b3303701cabe9433"
+ "4148882ae4ef14e6d9e6c752bce253bdda5739e33bdc32eb082828c1c399c22f"
+ "ea"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.6",
+ "5176ad7c99be4cdbbb5d79ba5f496cad9f42dc25d527a5d5e8e3359179225e6b"
+ "0e43666d3d82ab5baf424c85c33121606eb79ada6bafcab5c1e2546cabf6a360"
+ "038405ca18c0083667",
+ "0627238b0b93e4cf985713d291296cede345e88e17824525535939b3f3d5ff4e"
+ "bc40740011490025dfeaaee90638c5391eb44e9ff370457b60d5de80c16538cb"
+ "3860559585caf5e3332c7b1fdd8f45fb6e3557f2c7a60d099e94f8e96baa1e03"
+ "199ac83cec8f9c16bb49151a8872cbfe70f002cf3b53b611d6cbb665897cebf5"
+ "99"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.7",
+ "e174719364f7bdc86e2f0c61265bf8057d649cca",
+ "09771954fc8a1feee90f60c4b8a5bbd462c634379ab3da19ffeba6e031b4243a"
+ "83509ceeed6e012a9163c6145cf70502a9fb0c21db31fad5ad14695de00262e4"
+ "e567095e16110c6e65d6bcb9cc02e919f90d19e7307f4434503f9fe02c12c1d3"
+ "f50cc160086fe460298c881225bff2e9e313da384444bec72a67ac344467e82b"
+ "66"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.8",
+ "98cbc91fd49b507c887e97c3cfa9b59c26001fcac16487f6004f0b6874546320"
+ "02d549b5461ff1530c0f5fc09aacc46adada7dc9d7b3e20fedfeecd8f2f16841"
+ "773268542e86431c7fb4d163f31e8e3172203426bc0d88a23b137634bfc71401"
+ "7220fbfbec888e01e3eff7bbbdf93f083b88fdd6407d989bcc5ecb153c9cee34"
+ "10fd006bcdf07af228790fd5e04f5c0a1b63648d48609bf163c6fd656020757c"
+ "3c0638e1b82d75e2b4b908b7e0a3c8d7266b801f60fc2b4f317ebb8bf22ab9e1"
+ "cb7b7784395bd7b424329e861d478661f6dc1298515f48564a3ff99735bb9003"
+ "3875a25be8b724f3",
+ "0f2d7a5eab83584503d94ebf7dde9eed494110be94ed648af0cf6e891b062d2c"
+ "9def958755b1a308488d1670742951ec0060545d2ec43fe84aec8901adf4fe8d"
+ "67aae57a319f491c85c21cd7f9c599813ceb9df84778adc82a33c4e7674d7fbe"
+ "1348dc207551104f5442acd684869ac22cac516cc9887fd1d021efcc54abdaf2"
+ "b6"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.9",
+ "3eed6bf116cb31e0fdd4c5c93358bab68fbfa8b5c515bcabf9051cdf95a243e5"
+ "ee6815154eeb4ac10f5231d0493813e28149e9682bb1c8b77a6e1360b2b2c0f9"
+ "c3161e417ef6cb3d9abbdc742ce025fafcd538c77c4d0716491da54bcdf167b4"
+ "7a61a03527c96e4b42bfdc985b178781b6920f60f11cd5fa76663f56f319f450"
+ "cc2a7f13bcce59e41cb666",
+ "07673fa683e098bfa2b955b6c34e9ce8eccc5ab0ab4c2cf79b9be1e664425a7c"
+ "177a47d5320cd57086f951891845094b1fbbc9dee5f9b556df3e61e7e66973d6"
+ "3e69c9da17296fe615d633c86218dca399258c04f805bd04d9dc97a29f39d606"
+ "ff8e9c0a1371aaeec003ea274895ff7ba1502b28f8176302c24eece5b528d671"
+ "00"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.10",
+ "084ec287865e8fe6880472372097ad5b964c40a935eed1bea51ab1b5bc75c846"
+ "bbcbd95488e9ecc363cf073a90b20be8b679364622f345e122d0566acd34a4ae"
+ "11244525a38f47dc1f92b17f89ede06d836b4426ecbbea7933ac0e847e551033"
+ "b5f7ea4eaf1f63f3479db7eaf802c996de923386cd15b122de5a2398d3f39702"
+ "c3e9065c327395b9a995fa254de9c7adb451",
+ "13a7f004c0a88d513e2f1aaeab417fa0b2702fb93b828720ccd800cbb0af5a19"
+ "65725b6ee0587117cbcb81a46318521c950dd8469bd85573f5d29d865303ebac"
+ "45c7f6031c6f9378eb12b42f050944316f0b93db899bec937d5d0f58ed407004"
+ "01cd3265a6a44b09bb11a438eea07715efe42de4e8808f88240261148e8de293"
+ "ed"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.11",
+ "610700007c3c6cb096c994d65d95c9b9a147c34614cd722f29ebc5e093786f79"
+ "094802141a3108d2ec8a874c53187eb0d6ee2a859138cfbc29221506d0bd89b0"
+ "f3dbef506bd1ba4036b0f1ec0073327060752b428cfa12db280c53aae5f3e357"
+ "0e918cb09b90e9847f1f5ca4487a6bf3edad425f78407ecbe3f9bc7cab007566"
+ "5879431c6cc39e0c7e67006067418bee8d0db5e7dbe12da716ca",
+ "1ebeaf85d18f37840e8a3eaf07d69f524d883fa42f291e2007db595ad6930e8d"
+ "5a75b40bb95beb72d7ced038179747e9661d083840d587dcdf21c3adc7d47a01"
+ "f6eca9c7bf9e2a9887751b36d1abaf25a313fc29d7f834d2a2482985575e1be2"
+ "4bc4ef43a57ef4b0a6836993e11b67078504e3b79c721775f5b99bfaccc48a8c"
+ "34"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.12",
+ "da31f9be2609",
+ "1d2bbafca41ca06c4b811cb9d8369687166d14d9f92c5b98fc7c772f2d75d35a"
+ "5f9acce59b99efb2dcb97dccbbc86d7fd6b4ae8beab1e981e6c7745a1bfb4c1f"
+ "44a472b2ad07d41cc17515b7b14a49990b243442ff2c8fe505b1849fa991cacf"
+ "6809a20e55f2af7798870d65776f1f9ee48797e313aa66a47e695f3e731b2c7f"
+ "30"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.13",
+ "f98be52d9a5e55ad92",
+ "292ea34d3e6118bf8cd054e21517e863ce7cb7dd7273308f7ecfeacf9b457583"
+ "d9b9b97c54abf74e5a5ca36a87067e47d67aa047a1c2ed7a23d055ab4f094a83"
+ "c439ef8dd2d02035ef0562d967313d81102fc68b74525bb0e1d7962eb2758ec5"
+ "e5aeab65a93d2ec8e655405af88c00fa35f59de9d0cd8045abd37173b9fc6c51"
+ "d8"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.14",
+ "f438eff84c373fc12744a384158243dd97f4365e87d71e8b56b29791df44adf3"
+ "49e7626004a2c53335ec6352cce2edd963947fd2393893c248ba1b840842ca77"
+ "6c31729f707af50411001c287fba8fe72502320c445bb143fb7bf5394ec1fb2c"
+ "d501592432154091de5a2365d678f35782fea8b47f64d60919f0f1d5afa7626c"
+ "40d16cec19bfe025d116f42d22e20adb56375ad77089f9a93381fd78b7b1511c"
+ "b4e4984d2ddc7c9d75b310f295422560d66e3602a871209616131a847143dd07"
+ "8f23587db502dda03e18606482dbbe014ea083b7ec161b",
+ "0eafebf15d84ee4a13f1a82b8405118641e22e51da94d85887fc4a3b11f03249"
+ "cc39a0374501071c7eef4abaa11408d02fae1786dea37588479c90d627698591"
+ "c3bae1fefd6e8c40e3ff4b9f6061e06c12fdd21c7f45ddc5b78d1cbc41c15706"
+ "fa20ba92f99f58b22be27675bee081a06067eed158f8e20bf04a6e968f719a32"
+ "34"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.15",
+ "fa1c0f7b1015a895b1a565f32996b2b8ccfd864b95544dbb9cf4f6e1a841de92"
+ "06d55726fdf7eea2bf336a829fd2bc1209bd215aabb977d23a083f10ae69db43"
+ "7ca32d7bfe4c8825b93488f01afdf784458cef5cdd8dffdd17",
+ "25e22e6df7fc6bd4e0f61ebc8da063fe478a3ed74d68f7763435e0e374f65262"
+ "a5d7612e8678596122c0e5b8fa0c0b12812ba9653a0f273883c6264c6dfb74bb"
+ "34405d2a043043fbb0abf2af7a123d2ddbf16992e09baa37d731d72ef1996265"
+ "8a8fb010a10f7d5562ad5433479001af36d3d326eadb2e9abec7b555709d5d47"
+ "e9"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.16",
+ "828ebe2f51e58829cfa61526dded7e1f1ba311dbf1064c08ac0bb5d6716eab29"
+ "8a23d63b793ffd9d9cea60229598823f282f107b6ee88a53fd93e7ddd48a731a"
+ "2109ffedc89aeba2c0f16bcb140a0a89dc57ee8b5d000a2142175bc707bb409a"
+ "ae3a039c663d019a0bd913c13f7ff6f6b91e905a589d38b150485d89092d18a3"
+ "a762252765525d984566425b05770de9a8bef443ff5fc14833afa4ccece542d4"
+ "f2cef1e796f59fb3a4bf37cb677ae4223666c82b31a16a6cd701a0493cd99686"
+ "6c84bfcddf852b19ffc89e936179fce8b99e72fd4afc28b51173afbb25c4c7",
+ "1617559e43ba182e953486436f15b602831e42eed203c269f653bf639c2b760b"
+ "0d49fb532ca8ad01e7b4af83729255db559bcf55fab3659cebecd537694fef2d"
+ "ef9c9e762d05d2321ed688c3f7e2c05733ab4fa81b08cf79facb75c3200b7a48"
+ "3af08cb183c50927cc6169e432f7fc9b11780dbf4d3b72d2d0b85593d8b5b018"
+ "2a"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.17",
+ "bb4a6eccbdd6de0ac5c3b7f99798104a5869c1cf1a1fac7f859fe95149297eb7"
+ "79110059e269f12756f08a548b66af",
+ "277bae63e6e3253a0e204f4e6c9fe84b040b864f21edd4426d82be8f1b911b0b"
+ "d281cf114953d40209da2e9aae133bcd1855ef0a99693a9443c93f6dd275f058"
+ "fd1bb69532b64a1dd7e1d0e780d75204fa8c61c2eb5de88272cb93aef080f702"
+ "bb78889425a5f166f63b5b1a31ec5c1c26a599fafe58774298b97db314fc81d0"
+ "92"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.18",
+ "f1d111ad08e038ca3ab4e52e5eab7101876ca9be626a135917f45b1f9d1b32ef"
+ "e4ff867ab8a305f949c0048b25f5462261b1a3493b8190210f5cfa6bf7e5c300"
+ "5498deecc1e1c504f3a34998be6ad6ac004051c4e0a3db2c22eb5e14165528df"
+ "7812a20d5c7f05b940ca13e9383ae00d6cd4d0f4ae3dad047ab9c4178db66d3b"
+ "80960caf0a924dc94eb8e07709bcdb349e90fa2e10c5d526d2219ca76f8801fd"
+ "c661bdca6a93da48d045ac375134ccd6ff7c52fd15c7cd3d1f31afe504bce7c0"
+ "333a8979e3cecc53c4eadd7d95d46fa3b2a9f006100d6bfc0ed5ee77694ff1a2"
+ "4e16a544de71465290dddd189f01670359f8c6b5d4c6b6b9f5c57aa5a38f0799",
+ "0de94231c06ab187b00dda2b34e2b4cbac41f608c48c7227a6282a179e58c32e"
+ "f5ddc9764fa2dfc3fbe021ddb48156a6373cd69b85d364d89b5a32fabb2d465d"
+ "0562d4a1dd6fca64780b062a947124a7fc0b82e4fed12b8b4f726a0c8539c6cd"
+ "e21af655acc8de1e7ba9d67b87b8e777d48acd868a80db15314f355560103577"
+ "eb"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.19",
+ "9c4ecc4b2444a401bfb6f4b7244923a5ad3386c3b841678cf5e6447b8a3a0759"
+ "86c33fd001b843724dddc4212ff45ab3fecaa90a16f6b5592c515cc4ee54aea4"
+ "593432167096678f934159856d14c432e7d6d28d71b2687f54ed719e5c201100"
+ "688e85f20e79a9ee8aa4b61431343d1e99c21435c61e8bc104f2bad52960fcee"
+ "e67b85033d3aeefae413ce29701effcb02b484a031e2f319ef7ed0d6e69b2916"
+ "eeb38c4f1942ba23c2a1790ce3fe09d01b9b9fe6dba8dc210eaa8fe73ca76f1b"
+ "5b",
+ "1853c21a4a18547d867b3ced02daf0b22ce8d4d5af2b8ef5f7c8fd385b815364"
+ "8d81831d6acb5da830f67740259ffb339f7b90af4883819c4715e08c2899d4c7"
+ "246e07e5bc6ef3cfd9a04da06c43e95c772be221cfaaf6954ef93331e595ff48"
+ "921f05fce8fa0d429e0c99562a9c2f68ebf32cf1c6c6bb8b274a2e42d6715912"
+ "ff"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.20",
+ "c381e60399865166d2baa03145268334184039e05335a300c2804e2bfef5a7d1"
+ "4c443d6538e16bdf9da7ad1fea634ebfe113bc821e79a449b2eb2f57c21fba35"
+ "ffcc6a7e525572277e8f5537c7b5b9794defb39aab060785d1994002dcf80701"
+ "2e1d1791da943b2b759c366bb424e42c9c2043ce788a25fbfebb87e74cb020b1"
+ "1e8eaf161884d6672bbe9c09fbb3b8afa061",
+ "199069573753018f33592af15c1d3131bf5d8ac4f64cf614d3a01bf372df002e"
+ "b5b5fc8f82ba137f83dc142ede38c58180e7bda69c4f1bc7bf96ecd3fa79bccb"
+ "ddb7d92e4fd864c5fa933a4dfc600e1083008a386f4d022c2024ff7e0b3722ea"
+ "fea05a1e02c7a63eeb40f4f4c4f660c32472a0a78923e3863a99445e7cfe2700"
+ "60"
+ }
+ }
+ },
+ {
+ "A 1031-bit RSA key pair",
+ "70e923a5a0cd8ecdf99bbe93d7d02882955d91b6efe3cec86c93d21c0ac301b8"
+ "293e51435b878bc6b34bed4111590e764676588b116c2a36a4c77ed9c90a13c1"
+ "4d23e1994787fcdb8f5c97410fcad4045b8585702cce29da11f97e79a97c2e5f"
+ "6a5fc0bb8ce76d1554a8bc47961720d364050bf27419bff168c0a7ecc8734cb5"
+ "a5",
+ "010001",
+ "029e10f6bbb7d02debb1a5d5190d6906ffedeb9d154a0f66db8780b92831b596"
+ "3e94847f3e7db1aa9148fb0ec5576e6ba4fe04d6f27832b1521812d37b22d9ea"
+ "e28008e092c67e72324267e1b1ee454355741d8de1d2a6a05074bb1ce5818b41"
+ "bd19dc6b58c8937d8ad640d7043fa11f468d6ccbec4ade520a9e159d605d0928"
+ "29",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 13.1",
+ "b5e86c8ba3985aa5541df95e513cff67612eaf2e16688576f7d673f6f1891fb7"
+ "5c9dd2cd",
+ "6b42fd516309197f8af3c73e39624d8ebabecda3ec3ce657b1117f43e983877a"
+ "1ba1aaf8e95cc39991d92e35e2db1e413090143d16467198b9b9a990d774c27a"
+ "d3bbb4352d3f075d61732c6b58ec0f66e492a3f7ac4bbcf012ed6b401feb4ff3"
+ "95cb8b218a81d61731eece376f688e66aea698b4a8862f58c91d876085496fd0"
+ "14"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.2",
+ "9546346cf22194c787888170a482f7f49217c3940dc6210ce39e4550a39b4528"
+ "22419aeac24bec198bb359d08be8196df2e757766196c958e2b159c74c1c3023"
+ "c2dbcce9ed5d0ef3fb51450bff6445db265e606e194bee064ca5b321d7e15514"
+ "230c2b3b55d5da4cd040522f7bb86a962b813f9da39e51389bc64f56e447b2a2"
+ "bf819d7a80094e2b8de27f104bb6eb2f2fb43af1d01eadca23a196ba125b6a78"
+ "579974c0eec8a5496771f67dbd5069f336e4ef1f404742dfc69ce325aa649f8a"
+ "6331cf403555e13f0810a76350a7e18d2992fab48f397f3b93c5bd5a6fe1d2c4"
+ "618ba1f59f002dc257ec39ee2f876298da90f7440ad4c6c93fc114df05",
+ "67e414993f987a22643dd039e7f9fe1cae744a7ae41d4c044fa4ed8dc9e340ce"
+ "bb1e2afb198e847aef4bc061fd800d81d4d367b0fc2f730933c19b88d4ddf05e"
+ "d98a5856de5eb45b116b7d24feb45677849dab76e9e0ccb45ba6b6f6141f37bb"
+ "ad7c191c3777113bc7388e4e4644eca94703a72bddcc6f50cf980e3f6de39d73"
+ "12"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.3",
+ "5652b4c57520b255fb96f70a30ab92eec1939956b6a943c83ed0986e2e6ee4ef"
+ "bf8a52287867281203a7a6d1d886b7005952b43b778544eda898e0df2fa06f68"
+ "380318f14a53fe55d72f8cfa6af21d93bbfc20d358c208c562d739be0001ce07"
+ "fd8cd2f46c3b44c836518809b76f3a70cf6926be069c3575d5",
+ "016411a231a738944b3e44f7885cf81acab732d1736de34c56cf40f99a6ce400"
+ "70a20aa94c487844a93cef287a58bc0ea181b2cf27d914f293b929779d39036c"
+ "4e5aaed35eee8a7fd50efd096c91a8f72c3c141c576c8d10b636fc4ddc1e6714"
+ "f17ffcce106d221b4fd7d6fe1e7cbd3f3b08f5546b44d1feb718fbc13370c7fa"
+ "2c"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.4",
+ "6d57f079a3e8adcb47cf2e3ca976e03b09c77d1d9d9d8484357e912309e8f4a8"
+ "3cb50cb6a7388c414aec844671ff810651e828103a1f6a199be260f74600028c"
+ "6a7b7bb9416ce7b6350a3a6805620cf5e6b0095dfa22b54601f619afd10da203"
+ "d28190cf9b0db5986d293033691ec5bbba6d73ea32472efa3f160fd2b1b5e43b"
+ "0bfad31677305fef467244114ee10f5cb2d67b478323a711041e294c46b2ed39"
+ "ccde079c877fe75cb875144ac31eb031a738a4cefef91f017ba71523f5124818"
+ "cf48b972bc47c8f2ed356f5bf691fd94670bb2",
+ "315ce417d0bbd73e7c4356797e73ed7abfe9fcfff1a5342899a7d11fb0d0542b"
+ "fcab66de2e4ec07c7dc2be7d797290a30db8c407dd16376588a6dcc1a207bf7f"
+ "f311540faa9dd6f19a73ab25a7496e682fa8a7054081076c1a02157be63e7f64"
+ "5de82df7c615503fa83b4edba20581812e097f65056ed417f6f24803530cf818"
+ "58"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.5",
+ "bb75446f787823dda2422b1adc7d7fefd06a6e9af5c04901ac5b99913ad6298c"
+ "9d1a3322e8b217e4e0994c42204280d404d01eceb5ec53fb86f761a396b23ae1"
+ "9d467905a0fe8050b895d8ba3746685c47439f90c3669c70ffb81994565c4df2"
+ "a31eb2a452bc3cb312b8147cec191032f38f3b3d89d7582bf18e7b7275fb4f16"
+ "ee89567e2a56bc73b3e2e109f9940ebd10b9df2b88accf0ba18e5b349520d2c7"
+ "f5a31bd5226d12ec35bfc9e36203e13506ba12b756c8ba00af91b85b0b4c07c7"
+ "f484adc458c926aaeb4f082fec987d9f276b8949597ec0401bb71a2fea9c7b74"
+ "e0dfe6aa52ac8b80beead336a49db22fb3",
+ "53d0d795bb082f2001036f472c2ece6e7d2db69f292da7213675c7cbba0d33b2"
+ "3212f8f43a4a8e09a6a50e019bbdd59a58898cc46c58a46e42ce7ba093fb4692"
+ "f383de33a9a34f47c7e61938bf8a6adaa88df21296b4c67b526835f757f2c26c"
+ "1d309d7cdd5ad5fd8f61f851ed23c4be2abb627dfd817f8477dc042b6a2e4069"
+ "40"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.6",
+ "883939d149a544e62ef04c610351a2dfa252eb9a9d1e11ae54c9b07ebcf1fdc4"
+ "7ec1d94703411da415f59fb3e5041ed9470e7bcc819b5afeaf860c016ef125bd"
+ "08a6cb8bcdf3b93a51dcadb2f68c8cc3775514282aff7567ec65f270d02beb95"
+ "fb8fac24095e1706e48b524865bc14461d3ece8c501c3d802ade985ae95cfe1a"
+ "b9d6b9ab0d15fcc8866f7f259c5e41c02cd413437e7d6ba7f15b0a70dafbd55c"
+ "0edb6b8075c27cff3b289e6c99e9a884ff7f086da9f75d6a4cbbccaf52ba25c6"
+ "342c38a76b44e101155df755e39c14862e220ca36ffbcc832afecba87f8abd96"
+ "0a577f56ca6cd8e99126658f27ac6e53c442ed4766",
+ "1ec02ae6a0a3f611992961ca27ccbf296e11361832e1ee7520569a9aee06345c"
+ "da22b4fa48fc345e4778bc3ccdfebd2dc5a6c9d48451aa441bea4b951199654a"
+ "e8d2f7522e17edbc2f51ce15cbcd366f4939cb53c3b77081f4a73750054e00b3"
+ "0ba2fe58f6f02e36a862542397dba6a3cd2277708819e78a2d876a23a5a269d7"
+ "75"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.7",
+ "4031e0def4f3d1ad9bc082770a88a1d9b4b7107548cdf8462b0bae3d994d8ebc"
+ "4da044b905dd8ed91a1da676727822360ee2b6d5e12bb70316d79e8abb82a643"
+ "44afb3b225885c",
+ "0be5a6d043be5d27d1d51d9e3aa61d92c9d84323119b48c84a80389718d7a1aa"
+ "f57a9a0d214f6506484864dfae85db7b8474073a8f977b42b53b407e44c7c62b"
+ "168d1e7778f4f27857bfba85dddc8b0e9f0e9a5b6de71a0443720e92bb88b077"
+ "cba15d3f6e2be4d27a7c509c7dc03f1fdd4fe338a4e545c46c034522ccc0d45d"
+ "4c"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.8",
+ "7fdc96a4565774029fffa93b39f05dee9f84fa8953fd0f6338c81c9dec6cdd66"
+ "1ffab96f0e08eb0b9ba9ca5be17b57c4b4868fd5341154de50277113c7185341",
+ "1dd21fa495be7c490f982f69eab14e24daa04bd138b7143249cdccd78ccfc910"
+ "6acaa03ec876694232566ec6cab9122840f669c800f2ee092bb9b6cb2a4542a9"
+ "0de604c4f105000a3a0deccd3dd97a3261fa38227eb381a1f8f23b6665d28480"
+ "dfb72117882ed8db25d76de40de2fbe72dc394ec6fbdaa99c64fade72978a51f"
+ "c4"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.9",
+ "631832ab1918cd020828e47ae2b4476b1469f272e30e53e596fba26b402937dc"
+ "44c2ea5745c79d2dc64a10e1225ca0b6929d4954bc5d374096fd878dd101f766"
+ "6313d9a8f826bc671401422c1cfe1a6d01a4d7864a14c60cebc2f070914ceede"
+ "b1782fe540a0a5d2578444f9b36034ec77d6b803a0c9761b327592aa4846635c"
+ "563f1c6a6df68faabce497af4dc9a3642b75a4a294d308568e6d73c11db56724"
+ "042b55c3a24a7bc7a1050e4f448b6a",
+ "45d3a6ae8f48355c012b501079ee92affe3c9e602e4a080cfc94723ae96dac2a"
+ "66e455a40e728b2a1b27e62240554ec7c5c0ad6aa00c0922e53d7b12ed42c087"
+ "322d1536e46b7debda8095f55d1e12bc2442f43b4d128fee231dcd6f8c37aa6b"
+ "cf4fe7b5e0dea9c6709d3d91f9e42a53168a16b6fe997b5dfebafb46ed9aea5c"
+ "66"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.10",
+ "8b043d90dae3416685d53a5b4c3cc254cda0cbd23b4e408de820a4da7ade6dd9"
+ "5d4e1a97e2312c3e84261ee0b6cefe60e6b082fd5965efa1648f4fae61605fe3"
+ "55332700469605265347e6547aea775b856e5a46c341d29952bbea927049963e"
+ "3740208cfb0b652857b6f52e366a170be34f13d35846bde69720462001b09dd2"
+ "68b89b0900318e733db2009efd9b517741e510d3f394f7adb54559b157",
+ "6b278f362c292eea09b90bf353d143f2ca099ff879573479df2aff9b250d1c91"
+ "87c6a3343ea14c076f2a20c1a19db26aad3548ec6fb3b2fafc751b59082d8b23"
+ "c82c8a51f7faf7a4d4a82398bfbed449bde4ee9dc8680160666fd9c774c6aa57"
+ "7b4ec54cf0d5bd9e3d1afa9c3b4b91467678c9d4c4fe400aa857a3b0545bdf84"
+ "a6"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.11",
+ "3b28a6092e470898af070a087c4553188de6c344bb0b5fdc7f66fbc52dc93a8b"
+ "92a374112037d6a43286128acef95a3505c0abb1afa62c48cb2136077f8a0e0e"
+ "0b5a4ee9b2c77d7a0c0b53f38a51cc3db9b583b3aec07f1e224fcb3f1dad195e"
+ "058659a9d11f8edc7444994686ed62c97566e9e00cbf8f0dbc1716e6b7f0f88f"
+ "e89a867a41d643135ad8b18aa143e7375df19529",
+ "3262fe17e44e5ecc843170d3ae2751da1f48d6e961d81e9359b0982c6d61308e"
+ "bacfe2607c538c170ce0e72a07bc01487b295c36b8e22afdf6e7fe39c03a5c0c"
+ "3661061f23fbf5890ead59f872c946cce0f816c9ed3a2c1e11f8f74da1e97a39"
+ "0d534d785578a2455fcd874783f4572a15f4937dca98093fd0e9990af0005256"
+ "bf"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.12",
+ "4fdd6a3631ddd4bc3c76071902a227fd5b3653b1f970f2b767ef554e1c75cade"
+ "819d8d1fca76bc10541cbf8b1d8b0e7255f95740",
+ "29cba5b43fa3565775893491b118578b14b5fa1eebe0c80759a6d191e7c2131e"
+ "e10ac5b9b8ae1aa7d696c98488a35cdfa2aa006d91bf7e05a5c1909efb20dabc"
+ "82133b6264c042180c2cca65459f66cc7eb1ba75d15d4f56c7528aab2838e679"
+ "537a4c8dcd37d4b4ca825ce165fa4a97158244dc87c061fb12001e5533fbd4cc"
+ "62"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.13",
+ "590cd23050e57b28d5c2185ead60b1e9529f2bd52613eb03f6ed1aefa4a67288"
+ "d5a3a34fd95ca63894af3a40cd68873a1f37e354d30414297b19254bc6c1a3f7"
+ "a47520eea56eff77dbfda6bd7779d02fd816fc0e99919fe4395eaee5b2f5f032"
+ "cfc4336f9cf9acef74dbbf4c9a0918da6558b4b4e3209bfcd71ddd597607b6e2"
+ "8c3985dbf52ca7d1d751cb8169c0b1b13ff8b65b731e69dd2effe44c636f2b69"
+ "9535831aeb5e62902f",
+ "67eb8957ce4c06f7391d00c7412453f4b68b3303a1292554e2a5fc7262c52e74"
+ "bed70ec58c8950cdc4315a8fb7c6801554cd35781d44fb5e57d68d59a00f43b8"
+ "6d53b84372d556e5a4153cbe6b397c4c9c6800705d2fc0c548645e11b9d8d512"
+ "b2dd9bf59f3dc5d11c3c773d59ccbed9e6bc14320910cdf83b465901b746b596"
+ "74"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.14",
+ "808cb97613fd878535801c8008791510a5fe866ad5b6843a6e0019a0fcc21776"
+ "0354f60cc699fbbe1adfe8b00ecd6a36a2b5a5a1faa23d343820024e3a3197ae"
+ "673c",
+ "1c539659f872469916fb0007ef9e48574e964e4c0e6a2fa74b1373fd60b664a7"
+ "98ac8129c08c12cdbf3749750be125602a7154326767327e92ba57b5e289b5ac"
+ "9d7771b4520a7a2ce66c5eaf704afc5a190fa60be1376f943d2baf70523e47c3"
+ "defc0a25a6001831a37aab0cf1f6487be37f0e31ca7db5ac41b5630957559369"
+ "ff"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.15",
+ "57edaa0566251686f65205efc62660e2c2e04fa5eaa3302de87a3f6b491f7fa3"
+ "ac7270cc76751a436942ac765ef5f4749162d7e797126bcb8fdac19cf18dcc6e"
+ "ff48593c05c8893b591a51332fa26ab863c5eaa4d751e8d1b19c582690b5415e"
+ "6a89e05f231b33ac38c53f95a2d5f91051c2ec6ddb2b6dba789d553adb9f10c5"
+ "83597036d3486fbb32172a1c11079e5f09aa29eb4674c8d7bf5bbd6d057e6b87"
+ "a8b3aaf48086d721cbbc8efac6244d3239ae18f16623fa528e2e70fa25656a6a"
+ "4a2292950fc928edb81c",
+ "33732fcc23342c585138b25b17c812ee3e9d3da41f6ffbcc1617a2ee75cc5b25"
+ "01254fd1976d258800e905d7e44a0ab6fb4b8a88bb7bf9317395303ab2fca431"
+ "28486a2bab36c75ef6aa5eb3fc5bd555b3ea79124aad7897e3a434dee7926371"
+ "de2d6d237e89b03b8dd7096058e2a4b32cb557c7ada298a7e2edd3a3a3b529b4"
+ "d2"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.16",
+ "083376bb82212bf880be1285653af2cad625c52e94e321436877f725a83bbd43"
+ "f4486d896cf67e31391b8706f8c0f8f4bb1ddba95c332f034f3909113f655692"
+ "60a2e4f10406657c99faff001fe16ebb896e9e18115af1d4986c8579ab5652cc"
+ "ca4774",
+ "2af46c00d1d915941e212a7b8d8105ee0f0ec480fffbb4f13bf28d73e2b319b9"
+ "84a7b7c8367adca7ab12aaf53acb98d0cb54ee34204c908e60c7c79efb42c311"
+ "4a02589e1ae6afb5975354578c1435ecc89c116e9026b6bc889ee288ae4daf03"
+ "47cccefc5dfd1ef83cb86852eeffd84098599b725bf602ee620bdf44afbd84c0"
+ "cd"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.17",
+ "8c874cd0ce335139c08d760b825eb9905d",
+ "669a8ad7cb81ef2187f5a85647684b72484aff279f0af35435867cc2b04333a1"
+ "96eca6cf44a97a1bd39d0f6a0ff9595702835bc80a72d71404ef3f46fa3b0d20"
+ "e86d7a1d5f7efc3f3b8e8a7e37e87e27a99feba96ad81320be8fff78557d07bf"
+ "bae21603a1368cafa5ae1d1b630aa21ff20e4585650a773d7e2f5e7f51729719"
+ "3c"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.18",
+ "cb3e6121d38b7d97e18ba15c493d1ac32e9d2ef4e3bd16df9c67e4a196e9247a"
+ "8d0c24b21c4ab23e77d6db117d591195bbaf4466825f63978f114085281b79ae"
+ "a37e32c6b36c1e9ddd4ad1236e97fd427b4d976e07649dca4f33a89c46fb8c00"
+ "b4267b144704",
+ "568417803a400e9d050a4320ae7b7d8d248e163650869d9fdd100cc1a6b9bc29"
+ "1c3f23f1256003164f619dbc78635ebdf089490afa5aa00b6f97eb0636c3bba8"
+ "9d86360afe260043d861a74f64c71d9cbd31eae2393a1af1561f1ab92caa76dd"
+ "1e76ab2333098c83c2d99fae827398758005c176cbc4a2e22efa0e6c12f4e342"
+ "81"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.19",
+ "219a2f8d0b000aedb5f185455ed3ea094c45426b285bab4a07cf3d0a2906f3e2"
+ "03184c2d3d81a809b89c9fc48bc9af9ab32f84f15d81389c4edb0ac68ad09502"
+ "e3f30c7cf645102954b297c8661466fc10",
+ "03835d9057e2b821dc4c6eaca3f4156a56550b6f9d7400fc5c5195a4aee4717d"
+ "f32929122b43273a079a24f99dd9e7c34056aea4fc4e457d8314ef34427f8e20"
+ "4b81bb4903fb3e779e389e41339068c157d9b09f2c5e99cc54e6ef86eeac0e19"
+ "f44e33e707c4261a0a83ceb422f2e06bccae3b8bba428d7557152f40846ec011"
+ "34"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.20",
+ "e39ca40d2e9d03ae0596f60eb8f609993085a5db156b0d5098fe5faac55f7099"
+ "3fe176d2d0c038b860bbf9a66243f5e78e6cbe526ecf25128dae319656cc321e"
+ "e80a50531490c9a6243fbdb0c5eb4cd642d2611505ae1084975738ad84621d67"
+ "f5",
+ "4fcfa57397f27ee0f8ae75a0a54d54b0c51b957ee63bf7901b6055cc3987c32d"
+ "f7220e166a71606abc78f91107f974dff7d6257c256dc6ed7a69c3c99f9f89ab"
+ "b58fe589b7ee7cad0f48c16010d046a9c4e004bbe1a8297968d40bc70682ebae"
+ "a448525dbee16b03bd0b6526d098d09b6bad9aba039305e2ab796902086580cc"
+ "f0"
+ }
+ }
+ },
+ {
+ "A 1536-bit RSA key pair",
+ "d870a776cd13ed443df39908bee2cad73c485fd9bf06321322887fbe655c08cb"
+ "e4c8f63e254fc91c75f0557d901d435b0e8ded82d49173414d29860324e46c1b"
+ "030dfeaa29d80f9898c2c5e101cbf6daa0628978d415b502dea26de6561c79ab"
+ "065c6dca6abc4d4d4d5e9f5c74cb3e6a5af71d1f90fa5eaa1be0ca947a70a39e"
+ "fd315c4df21a1a821caaff8dcbad13b29c7e82aad53c64f582ec9ec31e6bde82"
+ "ea5a5f4cccf0c457b888f1550c4ff8e1c178a76a46c196f4bef59e61dd944e47",
+ "010001",
+ "05888fc77a43bda7a67bd15847650df185c185edcfb3ed58cee3b57c5d2406b7"
+ "8bc055874e35e57adc4b0a2c7d203a661c0fa5d857ede607efdc9568042bf0d5"
+ "99f4e4235e917f0894333a92df9462d9c10af3dfca7049a1eaa63570139883c5"
+ "befebee4e2218943d30fc645ffe8b914d218dd58960aadc121715bce5ccdde4a"
+ "2c73a8d9d86a4eb6e455dc924fd74a0b1f75691c281bae914d699ee259d85c5f"
+ "b5dd999ebef9b70a4bd94aa4fafae26ca784d32fd4e077dbb6ea693bcd6d27d5",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 14.1",
+ "f7a3c67e92a787f35dcc47aed7d6b6192967bdfd00a6acbf6f7efe46d3acaed9"
+ "788aa4f1db184402249f9acefc1c7dfb1e690d24738de86fa5b5250f979ebd8f"
+ "778eec0d7fcf731fa225086c866564ed3eb154dd458d0500282f86804887d443"
+ "5eda9a4436a8e923a20cb4b4d0e81c91114bdc0682278ec258860799b59c9436"
+ "f43a53cab4c4cd",
+ "09d1435bf5a9c17203d537fe57df987b7a51f34b2a14097e06a0de563be7d64b"
+ "4ea37973b4fe9973a66a3f31ba8e07e9117b6a1ee70961337b4d2b0df59810b6"
+ "24085118bda70ac74ae43e2fbcf89227630323da6830f5b1a2b954f1b15aea07"
+ "54df2c5118579516e877ccb0b1286c5724655ef8d29185666f6e9bd32a6bd9ce"
+ "9e1ef94729fc67d6a30e64560ecf78bf8e1b2b40e50605e25ae80c386764aed1"
+ "1a0e71449049c939b2962f6c2417a358cdc8106b12b1a5587639438af1a68d32"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.2",
+ "2a133003ab67cdd2e83b44e9e9dc777de01f4d233d22e7d2b4467f04812a3aeb"
+ "ffb10a092454e33b9e7028249328747ea14a11c798ac2e146e4e49659ba86067"
+ "db64e9bd80a7021aabcc22856e810140c20fd8c6527badbbd9fa5953fa77e685"
+ "8700beb6c74d5a463c9da861133baa5bd6a599807ae9162e3af3a348d04a4edd"
+ "2ffbab",
+ "35e666cfb87c0488a86fdfed5f9deaedbc4674171c318459acaaaa20e1cad7c5"
+ "8604140a80ff7f565bfbc86e90328d4c729b91bf72a98db701c1be638a6e8f2e"
+ "468f20392470c7c5c34442d51b1b155fb464b8a556f4a170c02301fed0d1aa92"
+ "aafdebc3f18ea8b4d71e245c2526f6fe665de48385f46ce1bf3312fa8928098e"
+ "d3312b61116ca7e423204ef08bd2df3ad7bbc850098cb02683266625bbd95982"
+ "5135a45f03829d096fed18b20baa3f9d44b007aa241f92f8886055d98e0e0704"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.3",
+ "58627ffaaa8e800a8be98e42f51a83611cfab7ee376b34737b3e48e1bc1742da"
+ "a77de47e1a9b293377aa",
+ "3d17cb386c88784d359ad3c38dbe888bfae831bfb8edc9d0e801e7d69e1dd4c2"
+ "441d68fdbb35126c73a4edabbff54e74fa5109dad8b5c313d86a79e4d4127660"
+ "fc2a8e1c93fa8d092accf01cc18a606cf07de2dc3e7b55331152db01b6caea1e"
+ "cec9093199be62c3e123e2873113503b22030f168dafc4e6bd065ad2f6b1ded0"
+ "5be0c2f9b67bdc1a3bb18da9594c957da4e49fac3fe76e0766f74eb0d523e4dd"
+ "1ae759dad6b9b908b7fc8b97ef5f4c8292320ac387c3508b54cfb85d34f6ad39"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.4",
+ "0f0f8d3c0e4d2608afad5a888ea14b3f6b2b2789dd2212b85909e64bfb104d0f"
+ "7de427d14a9ffa855e2d4ca2442336e559568b28415d60cf8063de5592171b26"
+ "9b3d763351c7f7d9d25809e70220ee30fe8a00b95d4c202026897ed2c61d7ad4"
+ "3aeddf36b5c2cbe21e0086dbd0fdfd19e43f0277f3bc95ed55a34af930916602"
+ "193cfe04514bd26a057e562a1190c27eaab6c322fcfaf4bbcc7f20c3779c638d"
+ "7bbc07086cf75bf83996db4463",
+ "50904512361050872eae80102628b63d02168dca52f0abd87720ea48050d2c62"
+ "061aa2153268bef8efb34eed46171a6288e504d420f6fc145138611e75ed3cf7"
+ "9b4d102664d8644ff3e9e5dbfd71cdc27a210efb10be90275604f8d449148b3f"
+ "86099039c33aef90bf191b3518eb459da3ba14fd0c72229dea5fac2f7dade108"
+ "5c8a2370bbfcfa2e3a9e63ca224f6de8c8d297a3b1f06f1fc9497890fd0e0e13"
+ "887facb152d12d96392528ef28d0724331ff414030c7a63855813ccd89fbdb1b"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.5",
+ "2665cb5ee36aa9bb1a5cde7ce8",
+ "4f38c2ba84c50d46df531091b62712149c1f42dbd77e03d185ea96eda802337c"
+ "22c1130bc3becebf1539fd11893851dae3cc1567cb6c73a72fa1c96948682112"
+ "7e7cfea1363eee952b7c6eb59e102c6657c08035272cdf4ab5e583ed737ad028"
+ "ac1cfafeddc9073dfbd7d3ba3da9e8dcd846fa365c9ccd8e9b39483d37073c1a"
+ "7b782ee7121bb1a2ad8bf5f8ed6e653e924debad871b744339e5ae7e96f60dcc"
+ "45ea5d697d3b1cc7c5e8da04e92be06cad2e614eac318aecaf12d5a76234c2c0"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.6",
+ "7b7b6161020fafb488716321340daf2c06ac43ce2132868684aaafab1399653d"
+ "353b2693ad73cb55b71d66acd01a160cbf743767bd96e7fd1c7a13320665bbad"
+ "1c4a0ced26593ce89cd82f546bd4d1b1bcd82c65a466f99da012a41e8c412069"
+ "810958475b4d9c2f80d82d06414c8325eb4f2c5a1166f1f1d2d107d48c",
+ "d5cbb6c7eff4a63ad8250de94cc29f7f31a0d7106d5d771b715df8a675fd1634"
+ "d6e8ab58875cc4c1517b2fadf4e85c1cb8b85360e0687587d148089f3f48b79d"
+ "98d2027c50770b334f1252ac0c3b2f036534c3c29722f6087d06d706cec7c4bd"
+ "ce1cd64f7b4e0799a87aa073ea8320292b8ec82717406d36ef9125e41fb5d53b"
+ "ccdd622d388fccee60a385ec206a715dc54d7877bd7285d0844c25d593779791"
+ "278396ff9a8a91306a54ea76607c813f801f38760c3a814b9396959c29dbff9d"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.7",
+ "2b0ad613822878a572e14280",
+ "89c81084daa8f914b7e24455107417ca621c9102d501eeb43d174c7bad381db1"
+ "8d9533c3411aec6057ca5a4dfdc3f131c888b88f013003d617e06d64479502ae"
+ "7e424a5dd637b03356404d260f5ed6b8cb16d2578528cc3e8500346eb790bdad"
+ "41b2e36ca6f19885e3f6f51086bffb6abb9c66336b49473464c5d7ed8e9ff85e"
+ "11aeff409067bab0a05c41e8151b8be987f3f5958e3e6f26515d96bf234b22ab"
+ "91c0857b6c08a46b0305fe044ca9aaa0d70a2758a1ce431664a8dd79408c16ba"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.8",
+ "36938c8c7c6f7e355234db5a32a64810db502b67c6f592544ffb27eb1f22e06f"
+ "2d638b56d5d2f7d19e9e271f2cc90cc0dd36d6cc2c06178bcc706aef20e56a35"
+ "8e524f6316769c54b6de2dd5",
+ "a03753a5fb54aa51f6dd8dab91f19cb865568485f8558f0d103f0d2b6d78536e"
+ "79c815c4a037bcaf11b69d4cdbab035abe216f7152f630ffc79f849d8dcd463a"
+ "ae6ae97d3df15a9e73d23f1878fac754cbdd571afea5d25357d4b88345f489be"
+ "0d67b9bfadf023f26e67315ed5fbf391910af4969b724bf0ca31c1059f8a3913"
+ "b48a13819c236c9be8e824ca4cb619fb7d784cd5f9526b397c76c5d0c60cf7f4"
+ "8d11196e54f72a08bb42f75aefe38f0b91b42bb806de4b87c9082f721a6880ca"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.9",
+ "60830c01cfa86ff2dcac7af9321ee5fe502e0e7a6facb73e3f6bc902640a6109"
+ "5f646fd03e80d58182465331e75d6611a0977681627086241729de9f44ab4394"
+ "9dac193673bd6cf87f5d65771ef87281633fdd07bac409a6e232b601aece2d",
+ "4058f6e0240d851d619395a75287a88fafd8dc5600b069bf19dc3e1921e117b4"
+ "97b82b3c520269b1d1128164fcd88dd2b46dc85c42ecf67debad21a3b9a15542"
+ "fea22606eab582fc329711ffc07f4eef1f3bbfe0888cbca485bafc1188b0afe8"
+ "09c9aaf8fa3666b9c9058539db1ec6a18e5be0b80144d2c37ca614c090b4a7f1"
+ "3458e0d3a4cb0cb73dcc4d90806f61085889eb5c9b1409def360fd1c2e49438d"
+ "7c67d79dbd9a592ab504c4715f65b29d846509951569a8c37909f5d550eefffa"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.10",
+ "635d2203ed9d5b9120e31bf69d305be6068697e35ce59c553e508dc77b073ffa"
+ "3aaa59f996c30b2e686323819fde22be6c8d53868414b3545abf435768a611f0"
+ "c1a479a0c7660d535e805b5fedc3779cf0c52c3cd040ab6514c7f8133d47b0ac"
+ "c6914e6d4ad3c4737cf51291094e859433ba3066e19d6aa2da896dc9d95ef9e5"
+ "636dab35f7298705c6d876175412f8842519ffe16cf74362ab",
+ "9461a1a841423ed5cfc6089a74dbfc53731103bf4985ddb150b0e9380d3fe0cf"
+ "6d457c5c68a7f25504022d695ff842118ebf61022fea47fa45f7c1cc726e1de5"
+ "0bd064b3bb701657162b88c0b910feb72f487a5c7f4b9ecfee24e07aa2d198d1"
+ "13cb845d817bb59bb1da24a82b91c2fe3fba895183cbd9c0fe0ac0be64fef2e0"
+ "139205b10bcabfe5a3a7a890fc0fe78dabe1adb5bd11448503cb0dcd0b68f160"
+ "196e9613e29fbe9a3f9406ec20c030e81ec30965ea019c17aa971101c2e53059"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.11",
+ "87fba989f3cc15af7ee761c088264ab7715239e0b8c8a9e48e11db68033139c2"
+ "a289ea426ebe269f5fb707090afb891a49ca05c0550d729bf4d37c8f1da7a3ca"
+ "2f4387a40b5f7913a385f55b8141af36be8f571665f857e77a5c9ccce6ba8f2b"
+ "e46323cc5691566ff4b6d7854304b93bba1a1759dfb144c9547cf2bc8eaaedaa"
+ "4f1dd252823b7287ca555d2106089a243e5dfe8fc31d3f46222a68abaf31815a"
+ "947e5857cf6a33170eccb6a5e06d23cc9d48eaf6cdbc",
+ "0b5f1cfc253baad4b983f8fe050d4a017cc466980ebd23c9d55343f5107e041e"
+ "b6547810fdba4686e610832f9282edf06604b0abfeea38013279177940997b28"
+ "902b14db379eeb4f44005dfcb0036803c9f125bce1f2a82c4d3007ae96b848b8"
+ "13ec8c97ca3f710a9ae0dbc28a55e05881b858db557120f33c59cd4360f9208c"
+ "74b27ec65d11ea41fa6a9eacf2a61168ad07c209948f35a161f41f87540ea182"
+ "84aab8d8f9786131f043902b89c17a560d909464475a0dfce58909187cd6e446"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.12",
+ "4b5e80305cbea90d637fdb2347c6feb67842ebac6f903db5a71ebaab8a1c2df1"
+ "1260a1ec907b8b634d37d36ed8de7d0da103bc4a9e933fb7bfee591cc933299f"
+ "ee460f3542c978f307ae052464f30620cebf3c9a9cb6a901530c1d5613df0774"
+ "312d4b5f",
+ "b6f03d35335007a747ae686760f9edad0889d2d4ca0cb88b674312d32c552b7a"
+ "66c5a9528c014b58c849f231a2e045682e3bbb14c7f95ff8bdb6587f2511cc6b"
+ "f9243960081103d47e7769a177ebdb91f12873decd5dc067e45c2b2a044ffa3f"
+ "bb04c20a3dc20138403ff25ca0ebad96e4859fa4a0d732852af350a275699a94"
+ "aa6e47f217e383ef8fce8eb6eed7826d7c6158fc5882e4613545fa26eee0c9f9"
+ "3de7a16508ea161970460d6a7ca770f8de8ba93ceaf397ddf1fbcee282a1537d"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.13",
+ "e5ad627f24f4117a0a6be4a55fdb883d75a67312154a718923d0e8f5730a54d8"
+ "ca7c974e4d59338bb571305cce990cbbcfa91ea9b773b83d7a1f0ffec4c6b143"
+ "fe05058bc90ce146f369cbae3b3d99705ef43d0721b8",
+ "732986d4eddb8a7e9b65dc016dd571efabeb84490e88e3e73b63e80d1cc86a45"
+ "2dec29fc817e8ad4eebddcd97c745bc4797e54fec6ace291b196dc2465f08cf1"
+ "ddd217e77aaf7d50987791de81b04110d11ab8558906604eb9d92b35f90075af"
+ "42280145b088e8753d0db73cd3a32bd19cea3538ee4f09273ef66d0705d45ee7"
+ "109fe595df55767b3d10817227bb6ba39575b85d6a35a2ffb88cb267dbfc282b"
+ "b8a3dee02ec77b0cb8135570f8a7d7ad04341a0864e67ff6fa0259a16974c86a"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.14",
+ "03e39ba7a80c771416d85263e4d43c6393dfe796523b89e0a461628880800d8f"
+ "c2431b66305409e06c95ae7a17d534b1e84c199dfe731da949f164571decc8b1"
+ "66beb8dc087cb4869998c2",
+ "60763beaf7c3e22b3b22dc44d947826e23fcf96b01b7741b24b1b9d93c07f0c6"
+ "4d396798bb589bd425295369bfb879add342cd76280b57e6354f6195e842fa2a"
+ "95f1c46f0b70786c318de9a55a8ac4545ee7cff399c678e578f8939ed49e84bb"
+ "a9aae57c1a36fcc39486466e4012f95887a68110f1a48467e4c234f581c5ec47"
+ "7106ccb3ec8617b4be219337448fe72e25deab53eacb92e5966295b3a5571219"
+ "58dfe79ca472f79efbda1dcfba9dbd0f976732c093b98ff193c902987a426c0f"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.15",
+ "d4c235967d4e87b6711e32ac7037a397f99b1cad95a188946a48640eb6b7b003"
+ "c32f85a121b09ca4c8bec0b82744aaf27d166cefc7a9702ad31dbd15ea2a185f"
+ "5b9ba642f949078bc609b9a8a33692d7184939d1f9eb426a6db740ead94cfea1"
+ "7feb0618d74d9a651688e90b9bb70524305d618c88a55f454450e0c585d3a8d9"
+ "8165818f363b20a252492e1512585890a8c320a7187158ce0d4e4be1c701f8af"
+ "dc545c4dab868d41d41c21c2cb1f67df7953d5f7261c5092bbc4332ac5575b6e"
+ "0e03149c040c3e201c7915ac2022884ea0e6c21403f0b44e0f71343fc9111a7d"
+ "b2f5e9e509c2d89784efb22c31e8165e0e936c",
+ "469f08bdd03b75640e8a44a07ca8de4bacf8331fe39c44d23aa7b581dc3f00f5"
+ "421b5c172d0ffce91497d3d4b104f56a98ec94f719271e58b43efbd876e1c131"
+ "fa97820728a5567555214cd94a18fcce5c2f53b19d1f3c73d09f7be1809738b0"
+ "3ce769e454ed4cbedcaf43c48bd39df2f8bb63b8fc4d0d4d5b204fc220013a66"
+ "8c19f9750293a4711583882645dbf3ac4f839b6fd1cf3b5ee8d734e1da374d91"
+ "d89ea318e9183483f4a09a93514af54f75d0a35651b240f79f20a2977d14578c"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.16",
+ "d06adca4c20f0d9f7be65a20327c294756e3edd9e1d39d0f95c79df1bac33435"
+ "9fab943d8545a3baa37a59295c58b237752b8de7d4323c56e9d7cb0c7f831d54"
+ "9cb38719a081d58b6057ecb7429e2ca607cd1306355943159dc924ad3e9cb13d"
+ "0e71eadcb005e184c0c2ceaaf9d74a1c1df6fec18c97a0",
+ "9fd9525c15c843b8069c15f26d3f95246af37a8b8e6b939ddf5b3828cdb62cfa"
+ "373a92ecc41384a877caa090aa13c847ef2829ddca14142014021481550550da"
+ "a29de2ab7001b855c9342f0c90bfa6c3349b2c396213ef70cbd84bb4ce6ef58b"
+ "176e9f6fccdb6e46cac34114a1b9f98a8a32757bf75d6bfc455ade6a01f96050"
+ "1b79f5fbe3b38fca03464e43d49663c79ff64d32981e4480cdf42d8af8daa7f1"
+ "2b81a5aa965fadaa3c03b7ff22d3cfdffe3cadf4d5989ed14c969a6e8c9a1e04"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.17",
+ "3a6302d79e26b555c77de92a91e078571ed1572ffc3e4fc905ce53f104b32200"
+ "957eb2b5e5f3e3fcbbc162f9e525c706f1dd04fcab516bc18a8e4f88a938a5b2"
+ "5685d78ddc9f104e49bf5ca0b65a4b9657e04a71fb50eb4aac22c0bb93f60cac"
+ "9483f17713553dca4b31e2727b32e350fe204cecd9a7cda4dada2e87ff6f2b73"
+ "e7b0781e212f34fe363610f018a799373755ab46667bb6525d7dc7a0e8289017"
+ "f5487fa692ef2fddce38ad3f4530de7ee5056670a735d378d1efc99481f8c9fb"
+ "eea99f566a0b6e28462644a6d9c6cc88fb",
+ "b757fa747c5c876766f358acbfc7e7b80596368d0d862950e555f471646f640e"
+ "851d612a556f55a74a3292429e4c14f78ba3ebbd9687f308dedb3cfed71f4a9d"
+ "d26fa5122f7f7194aeb63bc8b75c343187115a1dbd359590f7ff3862b70885af"
+ "1ca934b8cebc2cc9e647253fd1327a2ed4244dc8f58555a6897ca3229c801e7b"
+ "f628f525e6c948804d0b1b6dbcd7902acde7a25ba591d886e28daa8ded5ee401"
+ "e34e6412f1e644eec12ae94261906a172611dd5a9867789c419034688429e906"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.18",
+ "9dc7ce1d02cadcf10df1110456b8a7a5ea4376b27e8bf8cc8db81049fda3fbd0"
+ "db8a3d0f6bd7486b8d84bf9ffd4b641752df7edf50865e8e58ad49f7240e47d3"
+ "fc985edb596dabfe01722a227760383ce24d4a05d8b06ef5b96f117d81",
+ "05a95e11b5bfb01dcfde3efa9f313d81bb0dfd46de63b0658056c53af7ad9e89"
+ "438b7de78ff8ea88d072b1749a529f1cc9cf2cf32e5ab720e069b4906d282a03"
+ "dd78d1b3ca2a3f925bf51c7491b73ba0bf54d50d971de5b27726d8fb3ee27734"
+ "97df3549517eedcd9de68d90df35d3f05081151adab5397385abeea72b69bd0d"
+ "e18dcee9a2be00e91a032403b1f81bbc0ae731c6c0d9cfdd06c331ed89d7de1d"
+ "e1df46cf09ce53df1597fb6994681c7fbe94c9b08e50aa1b12419602987f37dd"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.19",
+ "87a645611bb191853f4fd9b740b2de4c163e7562b11762633e72dfb6f6be7efb"
+ "9041a96582943ab2018391c05adfab464dd6e33f960ddbf3b17ac62bb78afc1c"
+ "6a45396c0908707c62361255cbf09bad959b3133da48d532ba7ef1d20fb6572a"
+ "1f0ed6f2c6e1bec1b17cc319baf72a198aa001b83d4e9869c34090f229a9c7f1"
+ "42a74e85ab3ed51c69ac15fab4abe4671573cf5ad2b58e78a944edcceac5ee58"
+ "bfce66f40aac2abe4e5fa072dd0f664fac811aef084210e5641b9cd08c8724f4"
+ "b41eed1d9d4a18778046597bd1a27bbbc056c15e43c038ef375b435e73a7d32f"
+ "015016b78235ce75a7b762049968e9932253e42ca976c8d8dca1bb2dbf",
+ "b8806226fbd3d97b79f0dd1d8cf9a235e51b94b7e223ec68332d686ed3313ed1"
+ "bef6887023af7a5c99df0368a349c6a594795b623536101342690deb5fad9023"
+ "782f6dbe1643a45618574f16728112a7e0ef9f58656f6adbf400409f4aa5013c"
+ "159a368ca59bde6b3918dfe1d802fa6cfa06c9ca31aca78cb263c8ed917af9a9"
+ "a795d5e2c401e729964cf7ac28ccdb36d959ed7fd9af1c47097b6255c64e1b16"
+ "f21d86870455d5f0bf901fcc68c34b72c1bee72e6b8c4e36ae33996c7a59d09a"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.20",
+ "032e283e596e87faa6cfcfb8fa04df6a61e611dfe73bbf668ee67b496bfb0ffb"
+ "7f9dc931a98bcedb25",
+ "b9fdc03dc19970713c4a17e87e7ebb5f13505d59cbb22ba72e9ff16bdf8b659c"
+ "3330a93dcc092a5d385b2d5e1534003146c050b7ddc4f756569da21180158226"
+ "6119f5599b1e65e8ebea6bc96442ee12acb96c6dba083e921094da9c9ecf5afa"
+ "a54b7fde7a0cae3fdfe4d251933a52f02dc23e1b3214c683e19af46e18c74956"
+ "dc6ab3502d46caac3cb26b707cdc3025b6de4e83543b95845b4a159760770a4b"
+ "d09e4635a04e217d665c9594879f381d71100934fada61c7cc22b8d2ff8eb35a"
+ }
+ }
+ },
+ {
+ "A 2048-bit RSA key pair",
+ "df271fd25f8644496b0c81be4bd50297ef099b002a6fd67727eb449cea566ed6"
+ "a3981a71312a141cabc9815c1209e320a25b32464e9999f18ca13a9fd3892558"
+ "f9e0adefdd3650dd23a3f036d60fe398843706a40b0b8462c8bee3bce12f1f28"
+ "60c2444cdc6a44476a75ff4aa24273ccbe3bf80248465f8ff8c3a7f3367dfc0d"
+ "f5b6509a4f82811cedd81cdaaa73c491da412170d544d4ba96b97f0afc806549"
+ "8d3a49fd910992a1f0725be24f465cfe7e0eabf678996c50bc5e7524abf73f15"
+ "e5bef7d518394e3138ce4944506aaaaf3f9b236dcab8fc00f87af596fdc3d9d6"
+ "c75cd508362fae2cbeddcc4c7450b17b776c079ecca1f256351a43b97dbe2153",
+ "010001",
+ "5bd910257830dce17520b03441a51a8cab94020ac6ecc252c808f3743c95b7c8"
+ "3b8c8af1a5014346ebc4242cdfb5d718e30a733e71f291e4d473b61bfba6daca"
+ "ed0a77bd1f0950ae3c91a8f90111882589e1d62765ee671e7baeea309f64d447"
+ "bbcfa9ea12dce05e9ea8939bc5fe6108581279c982b308794b3448e7f7b95229"
+ "2df88c80cb40142c4b5cf5f8ddaa0891678d610e582fcb880f0d707caf47d09a"
+ "84e14ca65841e5a3abc5e9dba94075a9084341f0edad9b68e3b8e082b80b6e6e"
+ "8a0547b44fb5061b6a9131603a5537ddabd01d8e863d8922e9aa3e4bfaea0b39"
+ "d79283ad2cbc8a59cce7a6ecf4e4c81ed4c6591c807defd71ab06866bb5e7745",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 15.1",
+ "f45d55f35551e975d6a8dc7ea9f488593940cc75694a278f27e578a163d839b3"
+ "4040841808cf9c58c9b8728bf5f9ce8ee811ea91714f47bab92d0f6d5a26fcfe"
+ "ea6cd93b910c0a2c963e64eb1823f102753d41f0335910ad3a977104f1aaf6c3"
+ "742716a9755d11b8eed690477f445c5d27208b2e284330fa3d301423fa7f2d08"
+ "6e0ad0b892b9db544e456d3f0dab85d953c12d340aa873eda727c8a649db7fa6"
+ "3740e25e9af1533b307e61329993110e95194e039399c3824d24c51f22b26bde"
+ "1024cd395958a2dfeb4816a6e8adedb50b1f6b56d0b3060ff0f1c4cb0d0e001d"
+ "d59d73be12",
+ "b75a5466b65d0f300ef53833f2175c8a347a3804fc63451dc902f0b71f908345"
+ "9ed37a5179a3b723a53f1051642d77374c4c6c8dbb1ca20525f5c9f32db77695"
+ "3556da31290e22197482ceb69906c46a758fb0e7409ba801077d2a0a20eae7d1"
+ "d6d392ab4957e86b76f0652d68b83988a78f26e11172ea609bf849fbbd78ad7e"
+ "dce21de662a081368c040607cee29db0627227f44963ad171d2293b633a392e3"
+ "31dca54fe3082752f43f63c161b447a4c65a6875670d5f6600fcc860a1caeb0a"
+ "88f8fdec4e564398a5c46c87f68ce07001f6213abe0ab5625f87d19025f08d81"
+ "dac7bd4586bc9382191f6d2880f6227e5df3eed21e7792d249480487f3655261"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.2",
+ "c14b4c6075b2f9aad661def4ecfd3cb933c623f4e63bf53410d2f016d1ab98e2"
+ "729eccf8006cd8e08050737d95fdbf296b66f5b9792a902936c4f7ac69f51453"
+ "ce4369452dc22d96f037748114662000dd9cd3a5e179f4e0f81fa6a0311ca1ae"
+ "e6519a0f63cec78d27bb726393fb7f1f88cde7c97f8a66cd66301281dac3f3a4"
+ "33248c75d6c2dcd708b6a97b0a3f325e0b2964f8a5819e479b",
+ "afa7343462bea122cc149fca70abdae79446677db5373666af7dc313015f4de7"
+ "86e6e394946fad3cc0e2b02bedba5047fe9e2d7d099705e4a39f28683279cf0a"
+ "c85c1530412242c0e918953be000e939cf3bf182525e199370fa7907eba69d5d"
+ "b4631017c0e36df70379b5db8d4c695a979a8e6173224065d7dc15132ef28cd8"
+ "22795163063b54c651141be86d36e36735bc61f31fca574e5309f3a3bbdf91ef"
+ "f12b99e9cc1744f1ee9a1bd22c5bad96ad481929251f0343fd36bcf0acde7f11"
+ "e5ad60977721202796fe061f9ada1fc4c8e00d6022a8357585ffe9fdd59331a2"
+ "8c4aa3121588fb6cf68396d8ac0546599500c9708500a5972bd54f72cf8db0c8"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.3",
+ "d02371ad7ee48bbfdb2763de7a843b9408ce5eb5abf847ca3d735986df84e906"
+ "0bdbcdd3a55ba55dde20d4761e1a21d225c1a186f4ac4b3019d3adf78fe63346"
+ "67f56f70c901a0a2700c6f0d56add719592dc88f6d2306c7009f6e7a635b4cb3"
+ "a502dfe68ddc58d03be10a1170004fe74dd3e46b82591ff75414f0c4a03e605e"
+ "20524f2416f12eca589f111b75d639c61baa80cafd05cf3500244a219ed9ced9"
+ "f0b10297182b653b526f400f2953ba214d5bcd47884132872ae90d4d6b1f4215"
+ "39f9f34662a56dc0e7b4b923b6231e30d2676797817f7c337b5ac824ba93143b"
+ "3381fa3dce0e6aebd38e67735187b1ebd95c02",
+ "3bac63f86e3b70271203106b9c79aabd9f477c56e4ee58a4fce5baf2cab4960f"
+ "88391c9c23698be75c99aedf9e1abf1705be1dac33140adb48eb31f450bb9efe"
+ "83b7b90db7f1576d33f40c1cba4b8d6b1d3323564b0f1774114fa7c08e6d1e20"
+ "dd8fbba9b6ac7ad41e26b4568f4a8aacbfd178a8f8d2c9d5f5b88112935a8bc9"
+ "ae32cda40b8d20375510735096536818ce2b2db71a9772c9b0dda09ae10152fa"
+ "11466218d091b53d92543061b7294a55be82ff35d5c32fa233f05aaac7585030"
+ "7ecf81383c111674397b1a1b9d3bf7612ccbe5bacd2b38f0a98397b24c83658f"
+ "b6c0b4140ef11970c4630d44344e76eaed74dcbee811dbf6575941f08a6523b8"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.4",
+ "29035584ab7e0226a9ec4b02e8dcf1272dc9a41d73e2820007b0f6e21feccd5b"
+ "d9dbb9ef88cd6758769ee1f956da7ad18441de6fab8386dbc693",
+ "28d8e3fcd5dddb21ffbd8df1630d7377aa2651e14cad1c0e43ccc52f907f946d"
+ "66de7254e27a6c190eb022ee89ecf6224b097b71068cd60728a1aed64b80e545"
+ "7bd3106dd91706c937c9795f2b36367ff153dc2519a8db9bdf2c807430c451de"
+ "17bbcd0ce782b3e8f1024d90624dea7f1eedc7420b7e7caa6577cef43141a726"
+ "4206580e44a167df5e41eea0e69a805454c40eefc13f48e423d7a32d02ed42c0"
+ "ab03d0a7cf70c5860ac92e03ee005b60ff3503424b98cc894568c7c56a023355"
+ "1cebe588cf8b0167b7df13adcad828676810499c704da7ae23414d69e3c0d2db"
+ "5dcbc2613bc120421f9e3653c5a8767297643c7e0740de016355453d6c95ae72"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.5",
+ "bda3a1c79059eae598308d3df609",
+ "a156176cb96777c7fb96105dbd913bc4f74054f6807c6008a1a956ea92c1f81c"
+ "b897dc4b92ef9f4e40668dc7c556901acb6cf269fe615b0fb72b30a513386923"
+ "14b0e5878a88c2c7774bd16939b5abd82b4429d67bd7ac8e5ea7fe924e20a6ec"
+ "662291f2548d734f6634868b039aa5f9d4d906b2d0cb8585bf428547afc91c6e"
+ "2052ddcd001c3ef8c8eefc3b6b2a82b6f9c88c56f2e2c3cb0be4b80da95eba37"
+ "1d8b5f60f92538743ddbb5da2972c71fe7b9f1b790268a0e770fc5eb4d5dd852"
+ "47d48ae2ec3f26255a3985520206a1f268e483e9dbb1d5cab190917606de31e7"
+ "c5182d8f151bf41dfeccaed7cde690b21647106b490c729d54a8fe2802a6d126"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.6",
+ "c187915e4e87da81c08ed4356a0cceac1c4fb5c046b45281b387ec28f1abfd56"
+ "7e546b236b37d01ae71d3b2834365d3df380b75061b736b0130b070be58ae8a4"
+ "6d12166361b613dbc47dfaeb4ca746456c2e888385525cca9dd1c3c7a9ada76d"
+ "6c",
+ "9cab74163608669f7555a333cf196fe3a0e9e5eb1a32d34bb5c85ff689aaab0e"
+ "3e65668ed3b1153f94eb3d8be379b8eef007c4a02c7071ce30d8bb341e58c620"
+ "f73d37b4ecbf48be294f6c9e0ecb5e63fec41f120e5553dfa0ebebbb72640a95"
+ "37badcb451330229d9f710f62e3ed8ec784e50ee1d9262b42671340011d7d098"
+ "c6f2557b2131fa9bd0254636597e88ecb35a240ef0fd85957124df8080fee1e1"
+ "49af939989e86b26c85a5881fae8673d9fd40800dd134eb9bdb6410f420b0aa9"
+ "7b20efcf2eb0c807faeb83a3ccd9b51d4553e41dfc0df6ca80a1e81dc234bb83"
+ "89dd195a38b42de4edc49d346478b9f11f0557205f5b0bd7ffe9c850f396d7c4"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.7",
+ "abfa2ecb7d29bd5bcb9931ce2bad2f74383e95683cee11022f08e8e7d0b8fa05"
+ "8bf9eb7eb5f98868b5bb1fb5c31ceda3a64f1a12cdf20fcd0e5a246d7a1773d8"
+ "dba0e3b277545babe58f2b96e3f4edc18eabf5cd2a560fca75fe96e07d859def"
+ "b2564f3a34f16f11e91b3a717b41af53f6605323001aa406c6",
+ "c4b437bcf703f352e1faf74eb9622039426b5672caf2a7b381c6c4f0191e7e4a"
+ "98f0eebcd6f41784c2537ff0f99e74982c87201bfbc65eae832db71d16dacadb"
+ "0977e5c504679e40be0f9db06ffd848dd2e5c38a7ec021e7f68c47dfd38cc354"
+ "493d5339b4595a5bf31e3f8f13816807373df6ad0dc7e731e51ad19eb4754b13"
+ "4485842fe709d378444d8e36b1724a4fda21cafee653ab80747f7952ee804dea"
+ "b1039d84139945bbf4be82008753f3c54c7821a1d241f42179c794ef7042bbf9"
+ "955656222e45c34369a384697b6ae742e18fa5ca7abad27d9fe71052e3310d0f"
+ "52c8d12ea33bf053a300f4afc4f098df4e6d886779d64594d369158fdbc1f694"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.8",
+ "df4044a89a83e9fcbf1262540ae3038bbc90f2b2628bf2a4467ac67722d8546b"
+ "3a71cb0ea41669d5b4d61859c1b4e47cecc5933f757ec86db0644e311812d00f"
+ "b802f03400639c0e364dae5aebc5791bc655762361bc43c53d3c7886768f7968"
+ "c1c544c6f79f7be820c7e2bd2f9d73e62ded6d2e937e6a6daef90ee37a1a52a5"
+ "4f00e31addd64894cf4c02e16099e29f9eb7f1a7bb7f84c47a2b594813be02a1"
+ "7b7fc43b34c22c91925264126c89f86bb4d87f3ef131296c53a308e0331dac8b"
+ "af3b63422266ecef2b90781535dbda41cbd0cf22a8cbfb532ec68fc6afb2ac06",
+ "1414b38567ae6d973ede4a06842dcc0e0559b19e65a4889bdbabd0fd02806829"
+ "13bacd5dc2f01b30bb19eb810b7d9ded32b284f147bbe771c930c6052aa73413"
+ "90a849f81da9cd11e5eccf246dbae95fa95828e9ae0ca3550325326deef9f495"
+ "30ba441bed4ac29c029c9a2736b1a4190b85084ad150426b46d7f85bd702f48d"
+ "ac5f71330bc423a766c65cc1dcab20d3d3bba72b63b3ef8244d42f157cb7e3a8"
+ "ba5c05272c64cc1ad21a13493c3911f60b4e9f4ecc9900eb056ee59d6fe4b8ff"
+ "6e8048ccc0f38f2836fd3dfe91bf4a386e1ecc2c32839f0ca4d1b27a568fa940"
+ "dd64ad16bd0125d0348e383085f08894861ca18987227d37b42b584a8357cb04"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.9",
+ "ea941ff06f86c226927fcf0e3b11b0872676170c1bfc33bda8e265c77771f9d0"
+ "850164a5eecbcc5ce827fbfa07c85214796d8127e8caa81894ea61ceb1449e72"
+ "fea0a4c943b2da6d9b105fe053b9039a9cc53d420b7539fab2239c6b51d17e69"
+ "4c957d4b0f0984461879a0759c4401beecd4c606a0afbd7a076f50a2dfc2807f"
+ "24f1919baa7746d3a64e268ed3f5f8e6da83a2a5c9152f837cb07812bd5ba7d3"
+ "a07985de88113c1796e9b466ec299c5ac1059e27f09415",
+ "ceeb84ccb4e9099265650721eea0e8ec89ca25bd354d4f64564967be9d4b08b3"
+ "f1c018539c9d371cf8961f2291fbe0dc2f2f95fea47b639f1e12f4bc381cef0c"
+ "2b7a7b95c3adf27605b7f63998c3cbad542808c3822e064d4ad14093679e6e01"
+ "418a6d5c059684cd56e34ed65ab605b8de4fcfa640474a54a8251bbb7326a42d"
+ "08585cfcfc956769b15b6d7fdf7da84f81976eaa41d692380ff10eaecfe0a579"
+ "682909b5521fade854d797b8a0345b9a864e0588f6caddbf65f177998e180d1f"
+ "102443e6dca53a94823caa9c3b35f322583c703af67476159ec7ec93d1769b30"
+ "0af0e7157dc298c6cd2dee2262f8cddc10f11e01741471bbfd6518a175734575"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.10",
+ "d8b81645c13cd7ecf5d00ed2c91b9acd46c15568e5303c4a9775ede76b48403d"
+ "6be56c05b6b1cf77c6e75de096c5cb3551cb6fa964f3c879cf589d28e1da2f9d"
+ "ec",
+ "2745074ca97175d992e2b44791c323c57167165cdd8da579cdef4686b9bb404b"
+ "d36a56504eb1fd770f60bfa188a7b24b0c91e881c24e35b04dc4dd4ce38566bc"
+ "c9ce54f49a175fc9d0b22522d9579047f9ed42eca83f764a10163997947e7d2b"
+ "52ff08980e7e7c2257937b23f3d279d4cd17d6f495546373d983d536efd7d1b6"
+ "7181ca2cb50ac616c5c7abfbb9260b91b1a38e47242001ff452f8de10ca6eaea"
+ "dcaf9edc28956f28a711291fc9a80878b8ba4cfe25b8281cb80bc9cd6d2bd182"
+ "5246eebe252d9957ef93707352084e6d36d423551bf266a85340fb4a6af37088"
+ "0aab07153d01f48d086df0bfbec05e7b443b97e71718970e2f4bf62023e95b67"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.11",
+ "e5739b6c14c92d510d95b826933337ff0d24ef721ac4ef64c2bad264be8b44ef"
+ "a1516e08a27eb6b611d3301df0062daefc73a8c0d92e2c521facbc7b26473876"
+ "7ea6fc97d588a0baf6ce50adf79e600bd29e345fcb1dba71ac5c0289023fe4a8"
+ "2b46a5407719197d2e958e3531fd54aef903aabb4355f88318994ed3c3dd62f4"
+ "20a7",
+ "be40a5fb94f113e1b3eff6b6a33986f202e363f07483b792e68dfa5554df0466"
+ "cc32150950783b4d968b639a04fd2fb97f6eb967021f5adccb9fca95acc8f2cd"
+ "885a380b0a4e82bc760764dbab88c1e6c0255caa94f232199d6f597cc9145b00"
+ "e3d4ba346b559a8833ad1516ad5163f016af6a59831c82ea13c8224d84d0765a"
+ "9d12384da460a8531b4c407e04f4f350709eb9f08f5b220ffb45abf6b75d1579"
+ "fd3f1eb55fc75b00af8ba3b087827fe9ae9fb4f6c5fa63031fe582852fe2834f"
+ "9c89bff53e2552216bc7c1d4a3d5dc2ba6955cd9b17d1363e7fee8ed7629753f"
+ "f3125edd48521ae3b9b03217f4496d0d8ede57acbc5bd4deae74a56f86671de2"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.12",
+ "7af42835917a88d6b3c6716ba2f5b0d5b20bd4e2e6e574e06af1eef7c81131be"
+ "22bf8128b9cbc6ec00275ba80294a5d1172d0824a79e8fdd830183e4c00b9678"
+ "2867b1227fea249aad32ffc5fe007bc51f21792f728deda8b5708aa99cabab20"
+ "a4aa783ed86f0f27b5d563f42e07158cea72d097aa6887ec411dd012912a5e03"
+ "2bbfa678507144bcc95f39b58be7bfd1759adb9a91fa1d6d8226a8343a8b849d"
+ "ae76f7b98224d59e28f781f13ece605f84f6c90bae5f8cf378816f4020a7dda1"
+ "bed90c92a23634d203fac3fcd86d68d3182a7d9ccabe7b0795f5c655e9acc4e3"
+ "ec185140d10cef053464ab175c83bd83935e3dabaf3462eebe63d15f573d269a",
+ "4e78c5902b807914d12fa537ae6871c86db8021e55d1adb8eb0ccf1b8f36ab7d"
+ "ad1f682e947a627072f03e627371781d33221d174abe460dbd88560c22f69011"
+ "6e2fbbe6e964363a3e5283bb5d946ef1c0047eba038c756c40be7923055809b0"
+ "e9f34a03a58815ebdde767931f018f6f1878f2ef4f47dd374051dd48685ded6e"
+ "fb3ea8021f44be1d7d149398f98ea9c08d62888ebb56192d17747b6b8e170954"
+ "31f125a8a8e9962aa31c285264e08fb21aac336ce6c38aa375e42bc92ab0ab91"
+ "038431e1f92c39d2af5ded7e43bc151e6ebea4c3e2583af3437e82c43c5e3b5b"
+ "07cf0359683d2298e35948ed806c063c606ea178150b1efc15856934c7255cfe"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.13",
+ "ebaef3f9f23bdfe5fa6b8af4c208c189f2251bf32f5f137b9de4406378686b3f"
+ "0721f62d24cb8688d6fc41a27cbae21d30e429feacc7111941c277",
+ "c48dbef507114f03c95fafbeb4df1bfa88e0184a33cc4f8a9a1035ff7f822a5e"
+ "38cda18723915ff078244429e0f6081c14fd83331fa65c6ba7bb9a12dbf66223"
+ "74cd0ca57de3774e2bd7ae823677d061d53ae9c4040d2da7ef7014f3bbdc95a3"
+ "61a43855c8ce9b97ecabce174d926285142b534a3087f9f4ef74511ec742b0d5"
+ "685603faf403b5072b985df46adf2d2529a02d40711e2190917052371b79b749"
+ "b83abf0ae29486c3f2f62477b2bd362b039c013c0c5076ef520dbb405f42cee9"
+ "5425c373a975e1cdd032c49622c85079b09e88dab2b13969ef7a723973781040"
+ "459f57d5013638483de2d91cb3c490da81c46de6cd76ea8a0c8f6fe331712d24"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.14",
+ "c5a2711278761dfcdd4f0c99e6f5619d6c48b5d4c1a80982faa6b4cf1cf7a60f"
+ "f327abef93c801429efde086408581461056acc33f3d04f5ada21216cacd5fd1"
+ "f9ed83203e0e2fe6138e3eae8424e5915a083f3f7ab76052c8be55ae882d6ec1"
+ "482b1e45c5dae9f41015405327022ec32f0ea2429763b255043b1958ee3cf6d6"
+ "3983596eb385844f8528cc9a9865835dc5113c02b80d0fca68aa25e72bcaaeb3"
+ "cf9d79d84f984fd417",
+ "6bd5257aa06611fb4660087cb4bc4a9e449159d31652bd980844daf3b1c7b353"
+ "f8e56142f7ea9857433b18573b4deede818a93b0290297783f1a2f23cbc72797"
+ "a672537f01f62484cd4162c3214b9ac628224c5de01f32bb9b76b27354f2b151"
+ "d0e8c4213e4615ad0bc71f515e300d6a64c6743411fffde8e5ff190e54923043"
+ "126ecfc4c4539022668fb675f25c07e20099ee315b98d6afec4b1a9a93dc3349"
+ "6a15bd6fde1663a7d49b9f1e639d38664b37a010b1f35e658682d9cd63e57de0"
+ "f15e8bdd096558f07ec0caa218a8c06f4788453940287c9d34b6d40a3f09bf77"
+ "99fe98ae4eb49f3ff41c5040a50cefc9bdf2394b749cf164480df1ab6880273b"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.15",
+ "9bf8aa253b872ea77a7e23476be26b2329578cf6ac9ea2805b357f6fc3ad130d"
+ "baeb3d869a13cce7a808bbbbc969857e03945c7bb61df1b5c2589b8e046c2a5d"
+ "7e4057b1a74f24c711216364288529ec9570f25197213be1f5c2e596f8bf8b2c"
+ "f3cb38aa56ffe5e31df7395820e94ecf3b1189a965dcf9a9cb4298d3c88b2923"
+ "c19fc6bc34aacecad4e0931a7c4e5d73dc86dfa798a8476d82463eefaa90a8a9"
+ "192ab08b23088dd58e1280f7d72e4548396baac112252dd5c5346adb2004a2f7"
+ "101ccc899cc7fafae8bbe295738896a5b2012285014ef6",
+ "27f7f4da9bd610106ef57d32383a448a8a6245c83dc1309c6d770d357ba89e73"
+ "f2ad0832062eb0fe0ac915575bcd6b8bcadb4e2ba6fa9da73a59175152b2d4fe"
+ "72b070c9b7379e50000e55e6c269f6658c937972797d3add69f130e34b85bdec"
+ "9f3a9b392202d6f3e430d09caca8227759ab825f7012d2ff4b5b62c8504dbad8"
+ "55c05edd5cab5a4cccdc67f01dd6517c7d41c43e2a4957aff19db6f18b17859a"
+ "f0bc84ab67146ec1a4a60a17d7e05f8b4f9ced6ad10908d8d78f7fc88b76adc8"
+ "290f87daf2a7be10ae408521395d54ed2556fb7661854a730ce3d82c71a8d493"
+ "ec49a378ac8a3c74439f7cc555ba13f859070890ee18ff658fa4d741969d70a5"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.16",
+ "32474830e2203754c8bf0681dc4f842afe360930378616c108e833656e5640c8"
+ "6856885bb05d1eb9438efede679263de07cb39553f6a25e006b0a52311a063ca"
+ "088266d2564ff6490c46b5609818548f88764dad34a25e3a85d575023f0b9e66"
+ "5048a03c350579a9d32446c7bb96cc92e065ab94d3c8952e8df68ef0d9fa456b"
+ "3a06bb80e3bbc4b28e6a94b6d0ff7696a64efe05e735fea025d7bdbc4139f3a3"
+ "b546075cba7efa947374d3f0ac80a68d765f5df6210bca069a2d88647af7ea04"
+ "2dac690cb57378ec0777614fb8b65ff453ca6b7dce6098451a2f8c0da9bfecf1"
+ "fdf391bbaa4e2a91ca18a1121a7523a2abd42514f489e8",
+ "6917437257c22ccb5403290c3dee82d9cf7550b31bd31c51bd57bfd35d452ab4"
+ "db7c4be6b2e25ac9a59a1d2a7feb627f0afd4976b3003cc9cffd8896505ec382"
+ "f265104d4cf8c932fa9fe86e008707959912389da4b2d6b369b36a5e72e29d24"
+ "c9a98c9d31a3ab44e643e6941266a47a45e3446ce8776abe241a8f5fc6423b24"
+ "b1ff250dc2c3a8172353561077e850a769b25f0325dac88965a3b9b472c494e9"
+ "5f719b4eac332caa7a65c7dfe46d9aa7e6e00f525f303dd63ab7919218901868"
+ "f9337f8cd26aafe6f33b7fb2c98810af19f7fcb282ba1577912c1d368975fd5d"
+ "440b86e10c199715fa0b6f4250b533732d0befe1545150fc47b876de09b00a94"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.17",
+ "008e59505eafb550aae5e845584cebb00b6de1733e9f95d42c882a5bbeb5ce1c"
+ "57e119e7c0d4daca9f1ff7870217f7cfd8a6b373977cac9cab8e71e420",
+ "922503b673ee5f3e691e1ca85e9ff4173cf72b05ac2c131da5603593e3bc259c"
+ "94c1f7d3a06a5b9891bf113fa39e59ff7c1ed6465e908049cb89e4e125cd37d2"
+ "ffd9227a41b4a0a19c0a44fbbf3de55bab802087a3bb8d4ff668ee6bbb8ad89e"
+ "6857a79a9c72781990dfcf92cd519404c950f13d1143c3184f1d250c90e17ac6"
+ "ce36163b9895627ad6ffec1422441f55e4499dba9be89546ae8bc63cca01dd08"
+ "463ae7f1fce3d893996938778c1812e674ad9c309c5acca3fde44e7dd8695993"
+ "e9c1fa87acda99ece5c8499e468957ad66359bf12a51adbe78d3a213b449bf0b"
+ "5f8d4d496acf03d3033b7ccd196bc22f68fb7bef4f697c5ea2b35062f48a36dd"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.18",
+ "6abc54cf8d1dff1f53b17d8160368878a8788cc6d22fa5c2258c88e660b09a89"
+ "33f9f2c0504ddadc21f6e75e0b833beb555229dee656b9047b92f62e76b8ffcc"
+ "60dab06b80",
+ "0b6daf42f7a862147e417493c2c401efae32636ab4cbd44192bbf5f195b50ae0"
+ "96a475a1614f0a9fa8f7a026cb46c6506e518e33d83e56477a875aca8c7e714c"
+ "e1bdbd61ef5d535239b33f2bfdd61771bab62776d78171a1423cea8731f82e60"
+ "766d6454265620b15f5c5a584f55f95b802fe78c574ed5dacfc831f3cf2b0502"
+ "c0b298f25ccf11f973b31f85e474421985f3cff702df3946ef0a6605682111b2"
+ "f55b1f8ab0d2ea3a683c69985ead93ed449ea48f0358ddf70802cb41de2fd83f"
+ "3c808082d84936948e0c84a131b4927827460527bb5cd24bfab7b48e071b2417"
+ "1930f99763272f9797bcb76f1d2481575558fcf260b1f0e554ebb3df3cfcb958"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.19",
+ "af2d78152cf10efe01d274f217b177f6b01b5e749f1567715da324859cd3dd88"
+ "db848ec79f48dbba7b6f1d33111ef31b64899e7391c2bffd69f49025cf201fc5"
+ "85dbd1542c1c778a2ce7a7ee108a309feca26d133a5ffedc4e869dcd7656596a"
+ "c8427ea3ef6e3fd78fe99d8ddc71d839f6786e0da6e786bd62b3a4f19b891a56"
+ "157a554ec2a2b39e25a1d7c7d37321c7a1d946cf4fbe758d9276f08563449d67"
+ "414a2c030f4251cfe2213d04a541063787",
+ "209c61157857387b71e24bf3dd56414550503bec180ff53bdd9bac062a2d4995"
+ "09bf991281b79527df9136615b7a6d9db3a103b535e0202a2caca197a7b74e53"
+ "56f3dd595b49acfd9d30049a98ca88f625bca1d5f22a392d8a749efb6eed9b78"
+ "21d3110ac0d244199ecb4aa3d735a83a2e8893c6bf8581383ccaee834635b7fa"
+ "1faffa45b13d15c1da33af71e89303d68090ff62ee615fdf5a84d120711da53c"
+ "2889198ab38317a9734ab27d67924cea74156ff99bef9876bb5c339e93745283"
+ "e1b34e072226b88045e017e9f05b2a8c416740258e223b2690027491732273f3"
+ "229d9ef2b1b3807e321018920ad3e53dae47e6d9395c184b93a374c671faa2ce"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.20",
+ "40ee992458d6f61486d25676a96dd2cb93a37f04b178482f2b186cf88215270d"
+ "ba29d786d774b0c5e78c7f6e56a956e7f73950a2b0c0c10a08dbcd67e5b210bb"
+ "21c58e2767d44f7dd4014e3966143bf7e3d66ff0c09be4c55f93b39994b8518d"
+ "9c1d76d5b47374dea08f157d57d70634978f3856e0e5b481afbbdb5a3ac48d48"
+ "4be92c93de229178354c2de526e9c65a31ede1ef68cb6398d7911684fec0babc"
+ "3a781a66660783506974d0e14825101c3bfaea",
+ "927502b824afc42513ca6570de338b8a64c3a85eb828d3193624f27e8b1029c5"
+ "5c119c9733b18f5849b3500918bcc00551d9a8fdf53a97749fa8dc480d6fe974"
+ "2a5871f973926528972a1af49e3925b0adf14a842719b4a5a2d89fa9c0b6605d"
+ "212bed1e6723b93406ad30e86829a5c719b890b389306dc5506486ee2f36a8df"
+ "e0a96af678c9cbd6aff397ca200e3edc1e36bd2f08b31d540c0cb282a9559e4a"
+ "dd4fc9e6492eed0ccbd3a6982e5faa2ddd17be47417c80b4e5452d31f72401a0"
+ "42325109544d954c01939079d409a5c378d7512dfc2d2a71efcc3432a765d1c6"
+ "a52cfce899cd79b15b4fc3723641ef6bd00acc10407e5df58dd1c3c5c559a506"
+ }
+ }
+ }
+ };
diff --git a/comm/third_party/libgcrypt/tests/pkcs1v2.c b/comm/third_party/libgcrypt/tests/pkcs1v2.c
new file mode 100644
index 0000000000..968d3fea21
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/pkcs1v2.c
@@ -0,0 +1,676 @@
+/* pkcs1v2.c - Test OAEP and PSS padding
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt-int.h"
+#else
+# include <gcrypt.h>
+#endif
+
+
+#define PGM "pkcs1v2"
+#include "t-common.h"
+
+
+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);
+}
+
+
+/* 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 returns NULL on
+ error. */
+static void *
+data_from_hex (const char *string, size_t *r_length)
+{
+ const char *s;
+ unsigned char *buffer;
+ size_t length;
+
+ buffer = gcry_xmalloc (strlen(string)/2+1);
+ length = 0;
+ for (s=string; *s; s +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ die ("error parsing hex string `%s'\n", string);
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static int
+extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected,
+ const char *description)
+{
+ gcry_sexp_t l1;
+ const void *a;
+ size_t alen;
+ void *b;
+ size_t blen;
+ int rc = 0;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_data (l1, 1, &alen);
+ b = data_from_hex (expected, &blen);
+ if (!a)
+ {
+ info ("%s: parameter \"%s\" missing in key\n", description, name);
+ rc = 1;
+ }
+ else if ( alen != blen || memcmp (a, b, alen) )
+ {
+ info ("%s: parameter \"%s\" does not match expected value\n",
+ description, name);
+ rc = 1;
+ }
+ gcry_free (b);
+ gcry_sexp_release (l1);
+ return rc;
+}
+
+
+/* Check against the OAEP test vectors from
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip . */
+static void
+check_oaep (void)
+{
+#include "pkcs1v2-oaep.h"
+ gpg_error_t err;
+ int tno, mno;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ void *rsa_n, *rsa_e, *rsa_d;
+ size_t rsa_n_len, rsa_e_len, rsa_d_len;
+ gcry_sexp_t sec_key, pub_key;
+
+ if (verbose > 1)
+ info ("(%s)\n", tbl[tno].desc);
+
+ rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
+ rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
+ rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
+ err = gcry_sexp_build (&sec_key, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e,
+ (int)rsa_d_len, rsa_d);
+ if (err)
+ die ("constructing private key failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&pub_key, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e);
+ if (err)
+ die ("constructing public key failed: %s\n", gpg_strerror (err));
+ gcry_free (rsa_n);
+ gcry_free (rsa_e);
+ gcry_free (rsa_d);
+
+ for (mno = 0; mno < DIM (tbl[0].m); mno++)
+ {
+ void *mesg, *seed, *encr;
+ size_t mesg_len, seed_len, encr_len;
+ gcry_sexp_t plain, ciph;
+
+ if (verbose)
+ info ("running test: %s\n", tbl[tno].m[mno].desc);
+
+ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
+ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
+
+ err = gcry_sexp_build (&plain, NULL,
+ "(data (flags oaep)(hash-algo sha1)"
+ "(value %b)(random-override %b))",
+ (int)mesg_len, mesg,
+ (int)seed_len, seed);
+ if (err)
+ die ("constructing plain data failed: %s\n", gpg_strerror (err));
+ gcry_free (mesg);
+ gcry_free (seed);
+
+ err = gcry_pk_encrypt (&ciph, plain, pub_key);
+ if (err)
+ {
+ show_sexp ("plain:\n", ciph);
+ fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("encrypt result:\n", ciph);
+ fail ("mismatch in gcry_pk_encrypt\n");
+ }
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ }
+ gcry_sexp_release (plain);
+ plain = NULL;
+
+ /* Now test the decryption. */
+ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
+ encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len);
+
+ err = gcry_sexp_build (&ciph, NULL,
+ "(enc-val (flags oaep)(hash-algo sha1)"
+ "(random-override %b)"
+ "(rsa (a %b)))",
+ (int)seed_len, seed,
+ (int)encr_len, encr);
+ if (err)
+ die ("constructing cipher data failed: %s\n", gpg_strerror (err));
+ gcry_free (encr);
+ gcry_free (seed);
+
+ err = gcry_pk_decrypt (&plain, ciph, sec_key);
+ if (err)
+ {
+ show_sexp ("ciph:\n", ciph);
+ fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("decrypt result:\n", plain);
+ fail ("mismatch in gcry_pk_decrypt\n");
+ }
+ gcry_sexp_release (plain);
+ plain = NULL;
+ }
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ }
+
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+/* Check against the PSS test vectors from
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip . */
+static void
+check_pss (void)
+{
+#include "pkcs1v2-pss.h"
+ gpg_error_t err;
+ int tno, mno;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ void *rsa_n, *rsa_e, *rsa_d;
+ size_t rsa_n_len, rsa_e_len, rsa_d_len;
+ gcry_sexp_t sec_key, pub_key;
+
+ if (verbose > 1)
+ info ("(%s)\n", tbl[tno].desc);
+
+ rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
+ rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
+ rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
+ err = gcry_sexp_build (&sec_key, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e,
+ (int)rsa_d_len, rsa_d);
+ if (err)
+ die ("constructing private key failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&pub_key, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e);
+ if (err)
+ die ("constructing public key failed: %s\n", gpg_strerror (err));
+ gcry_free (rsa_n);
+ gcry_free (rsa_e);
+ gcry_free (rsa_d);
+
+ for (mno = 0; mno < DIM (tbl[0].m); mno++)
+ {
+ void *mesg, *salt, *sign;
+ size_t mesg_len, salt_len, sign_len;
+ gcry_sexp_t sigtmpl, sig;
+ char mhash[20];
+
+ if (verbose)
+ info ("running test: %s\n", tbl[tno].m[mno].desc);
+
+ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
+ salt = data_from_hex (tbl[tno].m[mno].salt, &salt_len);
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len);
+ err = gcry_sexp_build (&sigtmpl, NULL,
+ "(data (flags pss)"
+ "(hash sha1 %b)"
+ "(random-override %b))",
+ 20, mhash,
+ (int)salt_len, salt);
+ if (err)
+ die ("constructing sig template failed: %s\n", gpg_strerror (err));
+ gcry_free (mesg);
+ gcry_free (salt);
+
+ err = gcry_pk_sign (&sig, sigtmpl, sec_key);
+ if (err)
+ {
+ show_sexp ("sigtmpl:\n", sigtmpl);
+ fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("sign result:\n", sig);
+ fail ("mismatch in gcry_pk_sign\n");
+ }
+ gcry_sexp_release (sig);
+ sig = NULL;
+ }
+ gcry_sexp_release (sigtmpl);
+ sigtmpl = NULL;
+
+ /* Now test the verification. */
+ salt = data_from_hex (tbl[tno].m[mno].salt, &salt_len);
+ sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len);
+
+ err = gcry_sexp_build (&sig, NULL,
+ "(sig-val(rsa(s %b)))",
+ (int)sign_len, sign);
+ if (err)
+ die ("constructing verify data failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&sigtmpl, NULL,
+ "(data (flags pss)"
+ "(hash sha1 %b)"
+ "(random-override %b))",
+ 20, mhash,
+ (int)salt_len, salt);
+ if (err)
+ die ("constructing verify tmpl failed: %s\n", gpg_strerror (err));
+ gcry_free (sign);
+ gcry_free (salt);
+
+ err = gcry_pk_verify (sig, sigtmpl, pub_key);
+ if (err)
+ {
+ show_sexp ("sig:\n", sig);
+ show_sexp ("sigtmpl:\n", sigtmpl);
+ fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err));
+ }
+ gcry_sexp_release (sig);
+ sig = NULL;
+ gcry_sexp_release (sigtmpl);
+ sigtmpl = NULL;
+ }
+
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+/* Check against PKCS#1 v1.5 encryption test vectors as found at
+ ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt . */
+static void
+check_v15crypt (void)
+{
+#include "pkcs1v2-v15c.h"
+ gpg_error_t err;
+ int tno, mno;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ void *rsa_n, *rsa_e, *rsa_d;
+ size_t rsa_n_len, rsa_e_len, rsa_d_len;
+ gcry_sexp_t sec_key, pub_key;
+
+ if (verbose > 1)
+ info ("(%s)\n", tbl[tno].desc);
+
+ rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
+ rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
+ rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
+ err = gcry_sexp_build (&sec_key, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e,
+ (int)rsa_d_len, rsa_d);
+ if (err)
+ die ("constructing private key failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&pub_key, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e);
+ if (err)
+ die ("constructing public key failed: %s\n", gpg_strerror (err));
+ gcry_free (rsa_n);
+ gcry_free (rsa_e);
+ gcry_free (rsa_d);
+
+ for (mno = 0; mno < DIM (tbl[0].m); mno++)
+ {
+ void *mesg, *seed, *encr;
+ size_t mesg_len, seed_len, encr_len;
+ gcry_sexp_t plain, ciph;
+
+ if (verbose)
+ info ("running test: %s\n", tbl[tno].m[mno].desc);
+
+ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
+ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
+
+ err = gcry_sexp_build (&plain, NULL,
+ "(data (flags pkcs1)(hash-algo sha1)"
+ "(value %b)(random-override %b))",
+ (int)mesg_len, mesg,
+ (int)seed_len, seed);
+ if (err)
+ die ("constructing plain data failed: %s\n", gpg_strerror (err));
+ gcry_free (mesg);
+ gcry_free (seed);
+
+ err = gcry_pk_encrypt (&ciph, plain, pub_key);
+ if (err)
+ {
+ show_sexp ("plain:\n", ciph);
+ fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("encrypt result:\n", ciph);
+ fail ("mismatch in gcry_pk_encrypt\n");
+ }
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ }
+ gcry_sexp_release (plain);
+ plain = NULL;
+
+ /* Now test the decryption. */
+ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
+ encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len);
+
+ err = gcry_sexp_build (&ciph, NULL,
+ "(enc-val (flags pkcs1)(hash-algo sha1)"
+ "(random-override %b)"
+ "(rsa (a %b)))",
+ (int)seed_len, seed,
+ (int)encr_len, encr);
+ if (err)
+ die ("constructing cipher data failed: %s\n", gpg_strerror (err));
+ gcry_free (encr);
+ gcry_free (seed);
+
+ err = gcry_pk_decrypt (&plain, ciph, sec_key);
+ if (err)
+ {
+ show_sexp ("ciph:\n", ciph);
+ fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("decrypt result:\n", plain);
+ fail ("mismatch in gcry_pk_decrypt\n");
+ }
+ gcry_sexp_release (plain);
+ plain = NULL;
+ }
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ }
+
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+/* Check against PKCS#1 v1.5 signature test vectors as found at
+ ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt . */
+static void
+check_v15sign (void)
+{
+#include "pkcs1v2-v15s.h"
+ gpg_error_t err;
+ int tno, mno;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ void *rsa_n, *rsa_e, *rsa_d;
+ size_t rsa_n_len, rsa_e_len, rsa_d_len;
+ gcry_sexp_t sec_key, pub_key;
+
+ if (verbose > 1)
+ info ("(%s)\n", tbl[tno].desc);
+
+ rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
+ rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
+ rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
+ err = gcry_sexp_build (&sec_key, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e,
+ (int)rsa_d_len, rsa_d);
+ if (err)
+ die ("constructing private key failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&pub_key, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e);
+ if (err)
+ die ("constructing public key failed: %s\n", gpg_strerror (err));
+ gcry_free (rsa_n);
+ gcry_free (rsa_e);
+ gcry_free (rsa_d);
+
+ for (mno = 0; mno < DIM (tbl[0].m); mno++)
+ {
+ void *mesg, *sign;
+ size_t mesg_len, sign_len;
+ gcry_sexp_t sigtmpl, sig;
+ char mhash[20];
+
+ if (verbose)
+ info ("running test: %s\n", tbl[tno].m[mno].desc);
+
+ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len);
+ err = gcry_sexp_build (&sigtmpl, NULL,
+ "(data (flags pkcs1)"
+ "(hash sha1 %b))",
+ 20, mhash);
+ if (err)
+ die ("constructing sig template failed: %s\n", gpg_strerror (err));
+ gcry_free (mesg);
+
+ err = gcry_pk_sign (&sig, sigtmpl, sec_key);
+ if (err)
+ {
+ show_sexp ("sigtmpl:\n", sigtmpl);
+ fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("sign result:\n", sig);
+ fail ("mismatch in gcry_pk_sign\n");
+ }
+ gcry_sexp_release (sig);
+ sig = NULL;
+ }
+ gcry_sexp_release (sigtmpl);
+ sigtmpl = NULL;
+
+ /* Now test the verification. */
+ sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len);
+
+ err = gcry_sexp_build (&sig, NULL,
+ "(sig-val(rsa(s %b)))",
+ (int)sign_len, sign);
+ if (err)
+ die ("constructing verify data failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&sigtmpl, NULL,
+ "(data (flags pkcs1)"
+ "(hash sha1 %b))",
+ 20, mhash);
+ if (err)
+ die ("constructing verify tmpl failed: %s\n", gpg_strerror (err));
+ gcry_free (sign);
+
+ err = gcry_pk_verify (sig, sigtmpl, pub_key);
+ if (err)
+ {
+ show_sexp ("sig:\n", sig);
+ show_sexp ("sigtmpl:\n", sigtmpl);
+ fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err));
+ }
+ gcry_sexp_release (sig);
+ sig = NULL;
+ gcry_sexp_release (sigtmpl);
+ sigtmpl = NULL;
+ }
+
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int run_oaep = 0;
+ int run_pss = 0;
+ int run_v15c = 0;
+ int run_v15s = 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 = 2;
+ debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--die"))
+ {
+ die_on_error = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--oaep"))
+ {
+ run_oaep = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--pss"))
+ {
+ run_pss = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--v15c"))
+ {
+ run_v15c = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--v15s"))
+ {
+ run_v15s = 1;
+ argc--; argv++;
+ }
+ }
+
+ if (!run_oaep && !run_pss && !run_v15c && !run_v15s)
+ run_oaep = run_pss = run_v15c = run_v15s = 1;
+
+ xgcry_control ((GCRYCTL_SET_VERBOSITY, (int)verbose));
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version ("1.5.0"))
+ die ("version mismatch\n");
+ 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));
+
+ if (run_oaep)
+ check_oaep ();
+ if (run_pss)
+ check_pss ();
+ if (run_v15c)
+ check_v15crypt ();
+ if (run_v15s)
+ check_v15sign ();
+
+ if (verbose)
+ fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count);
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/prime.c b/comm/third_party/libgcrypt/tests/prime.c
new file mode 100644
index 0000000000..422649806d
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/prime.c
@@ -0,0 +1,241 @@
+/* prime.c - part of the Libgcrypt test suite.
+ Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program 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 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. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define PGM "prime"
+#include "t-common.h"
+
+static void
+check_primes (void)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_mpi_t *factors = NULL;
+ gcry_mpi_t prime = NULL;
+ gcry_mpi_t g;
+ unsigned int i = 0;
+ struct prime_spec
+ {
+ unsigned int prime_bits;
+ unsigned int factor_bits;
+ unsigned int flags;
+ } prime_specs[] =
+ {
+ { 1024, 100, GCRY_PRIME_FLAG_SPECIAL_FACTOR },
+ { 128, 0, 0 },
+ { 0 },
+ };
+
+ for (i = 0; prime_specs[i].prime_bits; i++)
+ {
+ err = gcry_prime_generate (&prime,
+ prime_specs[i].prime_bits,
+ prime_specs[i].factor_bits,
+ &factors,
+ NULL, NULL,
+ GCRY_WEAK_RANDOM,
+ prime_specs[i].flags);
+ assert (! err);
+ if (verbose)
+ {
+ fprintf (stderr, "test %d: p = ", i);
+ gcry_mpi_dump (prime);
+ putc ('\n', stderr);
+ }
+
+ err = gcry_prime_check (prime, 0);
+ assert (! err);
+
+ err = gcry_prime_group_generator (&g, prime, factors, NULL);
+ assert (!err);
+ gcry_prime_release_factors (factors); factors = NULL;
+
+ if (verbose)
+ {
+ fprintf (stderr, " %d: g = ", i);
+ gcry_mpi_dump (g);
+ putc ('\n', stderr);
+ }
+ gcry_mpi_release (g);
+
+
+ gcry_mpi_add_ui (prime, prime, 1);
+ err = gcry_prime_check (prime, 0);
+ assert (err);
+ gcry_mpi_release (prime); prime = NULL;
+ }
+}
+
+
+/* Print an MPI S-expression. */
+static void
+print_mpi (const char *name, gcry_mpi_t a)
+{
+ gcry_error_t err;
+ unsigned char *buf;
+ int writerr = 0;
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
+ if (err)
+ die ("gcry_mpi_aprint failed: %s\n", gcry_strerror (err));
+
+ printf (" (%s #%s#)\n", name, buf);
+ if (ferror (stdout))
+ writerr++;
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ die ("writing output failed\n");
+ gcry_free (buf);
+}
+
+
+/* Create the key for our public standard dummy CA. */
+static void
+create_42prime (void)
+{
+ gcry_error_t err;
+ char string[128*2+1];
+ int i;
+ gcry_mpi_t start = NULL;
+ gcry_mpi_t p, q, n, t1, t2, phi, f, g, e, d, u;
+
+
+ /* Our start value is a string of 0x42 values, with the exception
+ that the two high order bits are set. This is to resemble the
+ way Lingcrypt generates RSA primes. */
+ for (i=0; i < 128;)
+ {
+ string[i++] = '4';
+ string[i++] = '2';
+ }
+ string[i] = 0;
+ string[0] = 'C';
+
+ err = gcry_mpi_scan (&start, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (err)
+ die ("gcry_mpi_scan failed: %s\n", gcry_strerror (err));
+ fputs ("start:", stderr); gcry_mpi_dump (start); putc ('\n', stderr);
+
+ /* Generate two primes with p < q. We take the first primes below
+ and above a start value. */
+ p = gcry_mpi_copy (start);
+ gcry_mpi_sub_ui (p, p, 1);
+ while (gcry_prime_check (p, 0))
+ gcry_mpi_sub_ui (p, p, 2);
+ fputs (" p:", stderr); gcry_mpi_dump (p); putc ('\n', stderr);
+ q = gcry_mpi_copy (start);
+ gcry_mpi_add_ui (q, q, 1);
+ while (gcry_prime_check (q, 0))
+ gcry_mpi_add_ui (q, q, 2);
+ fputs (" q:", stderr); gcry_mpi_dump (q); putc ('\n', stderr);
+
+ /* Compute the modulus. */
+ n = gcry_mpi_new (1024);
+ gcry_mpi_mul (n, p, q);
+ fputs (" n:", stderr); gcry_mpi_dump (n); putc ('\n', stderr);
+ if (gcry_mpi_get_nbits (n) != 1024)
+ die ("Oops: the size of N is not 1024 but %u\n", gcry_mpi_get_nbits (n));
+
+ /* Calculate Euler totient: phi = (p-1)(q-1) */
+ t1 = gcry_mpi_new (0);
+ t2 = gcry_mpi_new (0);
+ phi = gcry_mpi_new (0);
+ g = gcry_mpi_new (0);
+ f = gcry_mpi_new (0);
+ gcry_mpi_sub_ui (t1, p, 1);
+ gcry_mpi_sub_ui (t2, q, 1);
+ gcry_mpi_mul (phi, t1, t2);
+ gcry_mpi_gcd (g, t1, t2);
+ gcry_mpi_div (f, NULL, phi, g, -1);
+
+ /* Check the public exponent. */
+ e = gcry_mpi_set_ui (NULL, 65537);
+ if (!gcry_mpi_gcd (t1, e, phi))
+ die ("Oops: E is not a generator\n");
+ fputs (" e:", stderr); gcry_mpi_dump (e); putc ('\n', stderr);
+
+ /* Compute the secret key: d = e^-1 mod phi */
+ d = gcry_mpi_new (0);
+ gcry_mpi_invm (d, e, f );
+ fputs (" d:", stderr); gcry_mpi_dump (d); putc ('\n', stderr);
+
+ /* Compute the inverse of p and q. */
+ u = gcry_mpi_new (0);
+ gcry_mpi_invm (u, p, q);
+ fputs (" u:", stderr); gcry_mpi_dump (u); putc ('\n', stderr);
+
+ /* Print the S-expression. */
+ fputs ("(private-key\n (rsa\n", stdout);
+ print_mpi ("n", n);
+ print_mpi ("e", e);
+ print_mpi ("d", d);
+ print_mpi ("p", p);
+ print_mpi ("q", q);
+ print_mpi ("u", u);
+ fputs ("))\n", stdout);
+
+ gcry_mpi_release (p);
+ gcry_mpi_release (q);
+ gcry_mpi_release (n);
+ gcry_mpi_release (t1);
+ gcry_mpi_release (t2);
+ gcry_mpi_release (phi);
+ gcry_mpi_release (f);
+ gcry_mpi_release (g);
+ gcry_mpi_release (e);
+ gcry_mpi_release (d);
+ gcry_mpi_release (u);
+}
+
+
+
+
+int
+main (int argc, char **argv)
+{
+ int mode42 = 0;
+
+ if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
+ verbose = 1;
+ else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
+ verbose = debug = 1;
+ else if ((argc > 1) && (! strcmp (argv[1], "--42")))
+ verbose = debug = mode42 = 1;
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (! gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+
+ if (mode42)
+ create_42prime ();
+ else
+ check_primes ();
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/pubkey.c b/comm/third_party/libgcrypt/tests/pubkey.c
new file mode 100644
index 0000000000..754952eeef
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/pubkey.c
@@ -0,0 +1,1203 @@
+/* pubkey.c - Public key encryption/decryption tests
+ * Copyright (C) 2001, 2002, 2003, 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define PGM "pubkey"
+#include "t-common.h"
+
+
+/* Sample RSA keys, taken from basic.c. */
+
+static const char sample_private_key_1[] =
+"(private-key\n"
+" (openpgp-rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
+" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+ "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
+" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
+" )\n"
+")\n";
+
+/* The same key as above but without p, q and u to test the non CRT case. */
+static const char sample_private_key_1_1[] =
+"(private-key\n"
+" (openpgp-rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+" )\n"
+")\n";
+
+/* The same key as above but just without q to test the non CRT case. This
+ should fail. */
+static const char sample_private_key_1_2[] =
+"(private-key\n"
+" (openpgp-rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
+" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
+" )\n"
+")\n";
+
+static const char sample_public_key_1[] =
+"(public-key\n"
+" (rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" )\n"
+")\n";
+
+
+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);
+}
+
+/* from ../cipher/pubkey-util.c */
+static gpg_err_code_t
+_gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
+{
+ char buf[50];
+ const char *s;
+ size_t n;
+
+ *r_nbits = 0;
+
+ list = gcry_sexp_find_token (list, "nbits", 0);
+ if (!list)
+ return 0; /* No NBITS found. */
+
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s || n >= DIM (buf) - 1 )
+ {
+ /* NBITS given without a cdr. */
+ gcry_sexp_release (list);
+ return GPG_ERR_INV_OBJ;
+ }
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
+ gcry_sexp_release (list);
+ return 0;
+}
+
+/* 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 returns NULL on
+ error. */
+static void *
+data_from_hex (const char *string, size_t *r_length)
+{
+ const char *s;
+ unsigned char *buffer;
+ size_t length;
+
+ buffer = gcry_xmalloc (strlen(string)/2+1);
+ length = 0;
+ for (s=string; *s; s +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ die ("error parsing hex string `%s'\n", string);
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static void
+extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
+{
+ gcry_sexp_t l1;
+ const void *a;
+ size_t alen;
+ void *b;
+ size_t blen;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_data (l1, 1, &alen);
+ b = data_from_hex (expected, &blen);
+ if (!a)
+ fail ("parameter \"%s\" missing in key\n", name);
+ else if ( alen != blen || memcmp (a, b, alen) )
+ {
+ fail ("parameter \"%s\" does not match expected value\n", name);
+ if (verbose)
+ {
+ info ("expected: %s\n", expected);
+ show_sexp ("sexp: ", sexp);
+ }
+ }
+ gcry_free (b);
+ gcry_sexp_release (l1);
+}
+
+
+static void
+check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
+ gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
+{
+ gcry_sexp_t plain1, cipher, l;
+ gcry_mpi_t x0, x1;
+ int rc;
+ int have_flags;
+
+ /* Extract data from plaintext. */
+ l = gcry_sexp_find_token (plain0, "value", 0);
+ x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l);
+
+ /* Encrypt data. */
+ rc = gcry_pk_encrypt (&cipher, plain0, pkey);
+ if (rc)
+ die ("encryption failed: %s\n", gcry_strerror (rc));
+
+ l = gcry_sexp_find_token (cipher, "flags", 0);
+ have_flags = !!l;
+ gcry_sexp_release (l);
+
+ /* Decrypt data. */
+ rc = gcry_pk_decrypt (&plain1, cipher, skey);
+ gcry_sexp_release (cipher);
+ if (rc)
+ {
+ if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
+ {
+ gcry_mpi_release (x0);
+ return; /* This is the expected failure code. */
+ }
+ die ("decryption failed: %s\n", gcry_strerror (rc));
+ }
+
+ /* Extract decrypted data. Note that for compatibility reasons, the
+ output of gcry_pk_decrypt depends on whether a flags lists (even
+ if empty) occurs in its input data. Because we passed the output
+ of encrypt directly to decrypt, such a flag value won't be there
+ as of today. We check it anyway. */
+ l = gcry_sexp_find_token (plain1, "value", 0);
+ if (l)
+ {
+ if (!have_flags)
+ die ("compatibility mode of pk_decrypt broken\n");
+ gcry_sexp_release (plain1);
+ x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l);
+ }
+ else
+ {
+ if (have_flags)
+ die ("compatibility mode of pk_decrypt broken\n");
+ x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
+ gcry_sexp_release (plain1);
+ }
+
+ /* Compare. */
+ if (gcry_mpi_cmp (x0, x1))
+ die ("data corrupted\n");
+ gcry_mpi_release (x0);
+ gcry_mpi_release (x1);
+}
+
+static void
+check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
+ gpg_err_code_t decrypt_fail_code)
+{
+ gcry_sexp_t plain;
+ gcry_mpi_t x;
+ int rc;
+
+ /* Create plain text. */
+ x = gcry_mpi_new (nbits_data);
+ gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
+
+ rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
+ if (rc)
+ die ("converting data for encryption failed: %s\n",
+ gcry_strerror (rc));
+
+ check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
+ gcry_sexp_release (plain);
+ gcry_mpi_release (x);
+
+ /* Create plain text. */
+ x = gcry_mpi_new (nbits_data);
+ gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
+
+ rc = gcry_sexp_build (&plain, NULL,
+ "(data (flags raw no-blinding) (value %m))", x);
+ gcry_mpi_release (x);
+ if (rc)
+ die ("converting data for encryption failed: %s\n",
+ gcry_strerror (rc));
+
+ check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
+ gcry_sexp_release (plain);
+}
+
+static void
+get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
+{
+ gcry_sexp_t pub_key, sec_key;
+ int rc;
+ static const char *secret;
+
+
+ switch (secret_variant)
+ {
+ case 0: secret = sample_private_key_1; break;
+ case 1: secret = sample_private_key_1_1; break;
+ case 2: secret = sample_private_key_1_2; break;
+ default: die ("BUG\n");
+ }
+
+ rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
+ strlen (sample_public_key_1));
+ if (!rc)
+ rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
+ if (rc)
+ die ("converting sample keys failed: %s\n", gcry_strerror (rc));
+
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+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;
+
+ rc = gcry_sexp_new (&key_spec,
+ "(genkey (rsa (nbits 4:2048)))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating RSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated RSA key:\n", key);
+
+ 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
+get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new (&key_spec,
+ "(genkey (rsa (nbits 4:2048)(use-x931)))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating RSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated RSA (X9.31) key:\n", key);
+
+ 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
+get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec,
+ (fixed_x
+ ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
+ : "(genkey (elg (nbits 3:512)))"),
+ 0, 1);
+
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated ELG key:\n", key);
+
+ 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
+get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new (&key_spec,
+ transient_key
+ ? "(genkey (dsa (nbits 4:2048)(transient-key)))"
+ : "(genkey (dsa (nbits 4:2048)))",
+ 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key:\n", key);
+
+ 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
+get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec, "(genkey (dsa (nbits 4:2048)(use-fips186)))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key (fips 186):\n", key);
+
+ 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
+get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec,
+ "(genkey (dsa (transient-key)(domain"
+ "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
+ "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
+ "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
+ "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
+ "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
+ "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
+ "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
+ "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
+ "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
+ ")))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key:\n", key);
+
+ 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;
+}
+
+#if 0
+static void
+get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec,
+ "(genkey (dsa (transient-key)(use-fips186)(domain"
+ "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
+ "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
+ "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
+ "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
+ "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
+ "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
+ "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
+ "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
+ "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
+ ")))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key:\n", key);
+
+ 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;
+}
+#endif /*0*/
+
+static void
+get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec,
+ "(genkey"
+ " (dsa"
+ " (nbits 4:2048)"
+ " (qbits 3:256)"
+ " (use-fips186)"
+ " (transient-key)"
+ " (derive-parms"
+ " (seed #f770a4598ff756931fc529764513b103ce57d85f4ad8c5cf297c9b4d48241c5b#))))",
+ 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key (fips 186 with seed):\n", key);
+
+ 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_run (void)
+{
+ gpg_error_t err;
+ gcry_sexp_t pkey, skey;
+ int variant;
+
+ for (variant=0; variant < 3; variant++)
+ {
+ if (verbose)
+ fprintf (stderr, "Checking sample key (%d).\n", variant);
+ get_keys_sample (&pkey, &skey, variant);
+ /* Check gcry_pk_testkey which requires all elements. */
+ err = gcry_pk_testkey (skey);
+ if ((variant == 0 && err)
+ || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
+ die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
+ /* Run the usual check but expect an error from variant 2. */
+ check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ }
+
+ if (verbose)
+ fprintf (stderr, "Checking generated RSA key.\n");
+ get_keys_new (&pkey, &skey);
+ check_keys (pkey, skey, 800, 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Checking generated RSA key (X9.31).\n");
+ get_keys_x931_new (&pkey, &skey);
+ check_keys (pkey, skey, 800, 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Checking generated Elgamal key.\n");
+ get_elg_key_new (&pkey, &skey, 0);
+ check_keys (pkey, skey, 400, 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
+ get_elg_key_new (&pkey, &skey, 1);
+ check_keys (pkey, skey, 800, 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key.\n");
+ get_dsa_key_new (&pkey, &skey, 0);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (!gcry_fips_mode_active ())
+ {
+ if (verbose)
+ fprintf (stderr, "Generating transient DSA key.\n");
+ get_dsa_key_new (&pkey, &skey, 1);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ }
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key (FIPS 186).\n");
+ get_dsa_key_fips186_new (&pkey, &skey);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key with given domain.\n");
+ get_dsa_key_with_domain_new (&pkey, &skey);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ /* We need new test vectors for get_dsa_key_fips186_with_domain_new. */
+ if (verbose)
+ fprintf (stderr, "Generating DSA key with given domain (FIPS 186)"
+ " - skipped.\n");
+ /* get_dsa_key_fips186_with_domain_new (&pkey, &skey); */
+ /* /\* Fixme: Add a check function for DSA keys. *\/ */
+ /* gcry_sexp_release (pkey); */
+ /* gcry_sexp_release (skey); */
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n");
+ get_dsa_key_fips186_with_seed_new (&pkey, &skey);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+}
+
+
+
+static gcry_mpi_t
+key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
+{
+ gcry_sexp_t l1, l2;
+ gcry_mpi_t result;
+
+ l1 = gcry_sexp_find_token (sexp, topname, 0);
+ if (!l1)
+ return NULL;
+
+ l2 = gcry_sexp_find_token (l1, name, 0);
+ if (!l2)
+ {
+ gcry_sexp_release (l1);
+ return NULL;
+ }
+
+ result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l2);
+ gcry_sexp_release (l1);
+ return result;
+}
+
+
+static void
+check_x931_derived_key (int what)
+{
+ static struct {
+ const char *param;
+ const char *expected_d;
+ } testtable[] = {
+ { /* First example from X9.31 (D.1.1). */
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1024)\n"
+ " (rsa-use-e 1:3)\n"
+ " (derive-parms\n"
+ " (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
+ " (Xp2 #192E8AAC41C576C822D93EA433#)\n"
+ " (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
+ " 769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
+ " 39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
+ " B98BD984#)\n"
+ " (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
+ " (Xq2 #134E4CAA16D2350A21D775C404#)\n"
+ " (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
+ " 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
+ " 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
+ " 321DE34A#))))\n",
+ "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
+ "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
+ "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
+ "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
+ "241D3C4B"
+ },
+
+ { /* Second example from X9.31 (D.2.1). */
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1536)\n"
+ " (rsa-use-e 1:3)\n"
+ " (derive-parms\n"
+ " (Xp1 #18272558B61316348297EACA74#)\n"
+ " (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
+ " (Xp #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
+ " 0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
+ " 60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
+ " 318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
+ " EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
+ " (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
+ " (Xq2 #18AB178ECA907D72472F65E480#)\n"
+ " (Xq #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
+ " CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
+ " B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
+ " E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
+ " EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
+ "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
+ "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
+ "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
+ "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
+ "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
+ "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
+ "BBCCB9F65C83"
+ /* Note that this example in X9.31 gives this value for D:
+
+ "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
+ "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
+ "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
+ "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
+ "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
+ "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
+ "EF32E7D9720B"
+
+ This is a bug in X9.31, obviously introduced by using
+
+ d = e^{-1} mod (p-1)(q-1)
+
+ instead of using the universal exponent as required by 4.1.3:
+
+ d = e^{-1} mod lcm(p-1,q-1)
+
+ The examples in X9.31 seem to be pretty buggy, see
+ cipher/primegen.c for another bug. Not only that I had to
+ spend 100 USD for the 66 pages of the document, it also took
+ me several hours to figure out that the bugs are in the
+ document and not in my code.
+ */
+ },
+
+ { /* First example from NIST RSAVS (B.1.1). */
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1024)\n"
+ " (rsa-use-e 1:3)\n"
+ " (derive-parms\n"
+ " (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
+ " (Xp2 #16e5457b8844967ce83cab8c11#)\n"
+ " (Xp #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
+ " ab262da1dcda8194720672a4e02229a0c71f60ae\n"
+ " c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
+ " cab44595#)\n"
+ " (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
+ " (Xq2 #1f9cca85f185341516d92e82fd#)\n"
+ " (Xq #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
+ " c225655a9310cceac9f4cf1bce653ec916d45788\n"
+ " f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
+ " 2f389eda#))))\n",
+ "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
+ "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
+ "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
+ "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
+ "dc7e8feb"
+ },
+
+ { /* Second example from NIST RSAVS (B.1.1). */
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1536)\n"
+ " (rsa-use-e 1:3)\n"
+ " (derive-parms\n"
+ " (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
+ " (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
+ " (Xp #c8c67df894c882045ede26a9008ab09ea0672077\n"
+ " d7bc71d412511cd93981ddde8f91b967da404056\n"
+ " c39f105f7f239abdaff92923859920f6299e82b9\n"
+ " 5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
+ " 26974eb7bb1f14843841281b363b9cdb#)\n"
+ " (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
+ " (Xq2 #143edd7b22d828913abf24ca4d#)\n"
+ " (Xq #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
+ " b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
+ " 7552195fae8b061077e03920814d8b9cfb5a3958\n"
+ " b3a82c2a7fc97e55db543948d3396289245336ec\n"
+ " 9e3cb308cc655aebd766340da8921383#))))\n",
+ "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
+ "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
+ "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
+ "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
+ "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
+ "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
+ "2ccf8a84835b"
+ }
+ };
+ gpg_error_t err;
+ gcry_sexp_t key_spec = NULL, key = NULL, pub_key = NULL, sec_key = NULL;
+ gcry_mpi_t d_expected = NULL, d_have = NULL;
+
+ if (what < 0 && what >= sizeof testtable)
+ die ("invalid WHAT value\n");
+
+ err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
+ if (err)
+ die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
+
+ {
+ unsigned nbits;
+ err = _gcry_pk_util_get_nbits(key_spec, &nbits);
+ if (err)
+ die ("nbits not found\n");
+ if (gcry_fips_mode_active() && nbits < 2048)
+ {
+ info("RSA key test with %d bits skipped in fips mode\n", nbits);
+ goto leave;
+ }
+ }
+
+ err = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (err)
+ {
+ fail ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
+ goto leave;
+ }
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key [%d]\n", what);
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key [%d]\n", what);
+
+ err = gcry_mpi_scan
+ (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
+ if (err)
+ die ("error converting string [%d]\n", what);
+
+ if (verbose > 1)
+ show_sexp ("generated key:\n", key);
+
+ d_have = key_param_from_sexp (sec_key, "rsa", "d");
+ if (!d_have)
+ die ("parameter d not found in RSA secret key [%d]\n", what);
+ if (gcry_mpi_cmp (d_expected, d_have))
+ {
+ show_sexp (NULL, sec_key);
+ die ("parameter d does match expected value [%d]\n", what);
+ }
+leave:
+ gcry_mpi_release (d_expected);
+ gcry_mpi_release (d_have);
+
+ gcry_sexp_release (key);
+ gcry_sexp_release (pub_key);
+ gcry_sexp_release (sec_key);
+}
+
+
+
+static void
+check_ecc_sample_key (void)
+{
+ static const char ecc_private_key[] =
+ "(private-key\n"
+ " (ecdsa\n"
+ " (curve \"NIST P-256\")\n"
+ " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
+ "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n"
+ " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
+ "))";
+ static const char ecc_private_key_wo_q[] =
+ "(private-key\n"
+ " (ecdsa\n"
+ " (curve \"NIST P-256\")\n"
+ " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
+ "))";
+ static const char ecc_public_key[] =
+ "(public-key\n"
+ " (ecdsa\n"
+ " (curve \"NIST P-256\")\n"
+ " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
+ "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)"
+ "))";
+ static const char hash_string[] =
+ "(data (flags raw)\n"
+ " (value #00112233445566778899AABBCCDDEEFF"
+ /* */ "000102030405060708090A0B0C0D0E0F#))";
+ static const char hash2_string[] =
+ "(data (flags raw)\n"
+ " (hash sha1 #00112233445566778899AABBCCDDEEFF"
+ /* */ "000102030405060708090A0B0C0D0E0F"
+ /* */ "000102030405060708090A0B0C0D0E0F"
+ /* */ "00112233445566778899AABBCCDDEEFF#))";
+ /* hash2, but longer than curve length, so it will be truncated */
+ static const char hash3_string[] =
+ "(data (flags raw)\n"
+ " (hash sha1 #00112233445566778899AABBCCDDEEFF"
+ /* */ "000102030405060708090A0B0C0D0E0F"
+ /* */ "000102030405060708090A0B0C0D0E0F"
+ /* */ "00112233445566778899AABBCCDDEEFF"
+ /* */ "000102030405060708090A0B0C0D0E0F#))";
+
+ gpg_error_t err;
+ gcry_sexp_t key, hash, hash2, hash3, sig, sig2;
+
+ if (verbose)
+ fprintf (stderr, "Checking sample ECC key.\n");
+
+ if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ if ((err = gcry_sexp_new (&hash2, hash2_string, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ if ((err = gcry_sexp_new (&hash3, hash3_string, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ if ((err = gcry_pk_sign (&sig, hash, key)))
+ die ("gcry_pk_sign failed: %s", gpg_strerror (err));
+
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ if ((err = gcry_pk_verify (sig, hash, key)))
+ die ("gcry_pk_verify failed: %s", gpg_strerror (err));
+
+ /* Verify hash truncation */
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ if ((err = gcry_pk_sign (&sig2, hash2, key)))
+ die ("gcry_pk_sign failed: %s", gpg_strerror (err));
+
+ gcry_sexp_release (sig);
+ if ((err = gcry_pk_sign (&sig, hash3, key)))
+ die ("gcry_pk_sign failed: %s", gpg_strerror (err));
+
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ if ((err = gcry_pk_verify (sig, hash2, key)))
+ die ("gcry_pk_verify failed: %s", gpg_strerror (err));
+
+ if ((err = gcry_pk_verify (sig2, hash3, key)))
+ die ("gcry_pk_verify failed: %s", gpg_strerror (err));
+
+ /* Now try signing without the Q parameter. */
+
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ gcry_sexp_release (sig);
+ if ((err = gcry_pk_sign (&sig, hash, key)))
+ die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err));
+
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+ if ((err = gcry_pk_verify (sig, hash, key)))
+ die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err));
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (sig2);
+ gcry_sexp_release (key);
+ gcry_sexp_release (hash);
+ gcry_sexp_release (hash2);
+ gcry_sexp_release (hash3);
+}
+
+
+static void
+check_ed25519ecdsa_sample_key (void)
+{
+ static const char ecc_private_key[] =
+ "(private-key\n"
+ " (ecc\n"
+ " (curve \"Ed25519\")\n"
+ " (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
+ " 156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
+ " (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
+ "))";
+ static const char ecc_private_key_wo_q[] =
+ "(private-key\n"
+ " (ecc\n"
+ " (curve \"Ed25519\")\n"
+ " (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
+ "))";
+ static const char ecc_public_key[] =
+ "(public-key\n"
+ " (ecc\n"
+ " (curve \"Ed25519\")\n"
+ " (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
+ " 156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
+ "))";
+ static const char ecc_public_key_comp[] =
+ "(public-key\n"
+ " (ecc\n"
+ " (curve \"Ed25519\")\n"
+ " (q #047b57c2c1d3ded93332b52d588dd45863478b658387413a718779c0dd1a6d95#)"
+ "))";
+ static const char hash_string[] =
+ "(data (flags rfc6979)\n"
+ " (hash sha256 #00112233445566778899AABBCCDDEEFF"
+ /* */ "000102030405060708090A0B0C0D0E0F#))";
+
+ gpg_error_t err;
+ gcry_sexp_t key, hash, sig;
+
+ if (verbose)
+ fprintf (stderr, "Checking sample Ed25519/ECDSA key.\n");
+
+ /* Sign. */
+ if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+ if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+ if ((err = gcry_pk_sign (&sig, hash, key)))
+ die ("gcry_pk_sign failed: %s", gpg_strerror (err));
+
+ /* Verify. */
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+ if ((err = gcry_pk_verify (sig, hash, key)))
+ die ("gcry_pk_verify failed: %s", gpg_strerror (err));
+
+ /* Verify again using a compressed public key. */
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+ if ((err = gcry_pk_verify (sig, hash, key)))
+ die ("gcry_pk_verify failed (comp): %s", gpg_strerror (err));
+
+ /* Sign without a Q parameter. */
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+ gcry_sexp_release (sig);
+ if ((err = gcry_pk_sign (&sig, hash, key)))
+ die ("gcry_pk_sign w/o Q failed: %s", gpg_strerror (err));
+
+ /* Verify. */
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+ if ((err = gcry_pk_verify (sig, hash, key)))
+ die ("gcry_pk_verify signed w/o Q failed: %s", gpg_strerror (err));
+
+ /* Verify again using a compressed public key. */
+ gcry_sexp_release (key);
+ if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
+ die ("line %d: %s", __LINE__, gpg_strerror (err));
+ if ((err = gcry_pk_verify (sig, hash, key)))
+ die ("gcry_pk_verify signed w/o Q failed (comp): %s", gpg_strerror (err));
+
+ extract_cmp_data (sig, "r", ("a63123a783ef29b8276e08987daca4"
+ "655d0179e22199bf63691fd88eb64e15"));
+ extract_cmp_data (sig, "s", ("0d9b45c696ab90b96b08812b485df185"
+ "623ddaf5d02fa65ca5056cb6bd0f16f1"));
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (key);
+ gcry_sexp_release (hash);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int i;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ {
+ verbose = 2;
+ debug = 1;
+ }
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ 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));
+
+ for (i=0; i < 2; i++)
+ check_run ();
+
+ for (i=0; i < 4; i++)
+ check_x931_derived_key (i);
+
+ check_ecc_sample_key ();
+ if (!gcry_fips_mode_active ())
+ check_ed25519ecdsa_sample_key ();
+
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/random.c b/comm/third_party/libgcrypt/tests/random.c
new file mode 100644
index 0000000000..2ffd528b2d
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/random.c
@@ -0,0 +1,826 @@
+/* random.c - part of the Libgcrypt test suite.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program 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 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. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#ifndef HAVE_W32_SYSTEM
+# include <signal.h>
+# include <sys/wait.h>
+#endif
+
+#include "stopwatch.h"
+
+
+#define PGM "random"
+#define NEED_EXTRA_TEST_SUPPORT 1
+#include "t-common.h"
+
+static int with_progress;
+
+
+/* Prepend FNAME with the srcdir environment variable's value and
+ * return an allocated filename. */
+static char *
+prepend_srcdir (const char *fname)
+{
+ static const char *srcdir;
+ char *result;
+
+ if (!srcdir && !(srcdir = getenv ("srcdir")))
+ srcdir = ".";
+
+ result = xmalloc (strlen (srcdir) + 1 + strlen (fname) + 1);
+ strcpy (result, srcdir);
+ strcat (result, "/");
+ strcat (result, fname);
+ return result;
+}
+
+
+static void
+print_hex (const char *text, const void *buf, size_t n)
+{
+ const unsigned char *p = buf;
+
+ info ("%s", text);
+ for (; n; n--, p++)
+ fprintf (stderr, "%02X", *p);
+ putc ('\n', stderr);
+}
+
+
+static void
+progress_cb (void *cb_data, const char *what, int printchar,
+ int current, int total)
+{
+ (void)cb_data;
+
+ info ("progress (%s %c %d %d)\n", what, printchar, current, total);
+ fflush (stderr);
+}
+
+
+#ifndef HAVE_W32_SYSTEM
+static int
+writen (int fd, const void *buf, size_t nbytes)
+{
+ size_t nleft = nbytes;
+ int nwritten;
+
+ while (nleft > 0)
+ {
+ nwritten = write (fd, buf, nleft);
+ if (nwritten < 0)
+ {
+ if (errno == EINTR)
+ nwritten = 0;
+ else
+ return -1;
+ }
+ nleft -= nwritten;
+ buf = (const char*)buf + nwritten;
+ }
+
+ return 0;
+}
+#endif /*!HAVE_W32_SYSTEM*/
+
+
+#ifndef HAVE_W32_SYSTEM
+static int
+readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
+{
+ size_t nleft = buflen;
+ int nread;
+
+ while ( nleft > 0 )
+ {
+ nread = read ( fd, buf, nleft );
+ if (nread < 0)
+ {
+ if (nread == EINTR)
+ nread = 0;
+ else
+ return -1;
+ }
+ else if (!nread)
+ break; /* EOF */
+ nleft -= nread;
+ buf = (char*)buf + nread;
+ }
+ if (ret_nread)
+ *ret_nread = buflen - nleft;
+ return 0;
+}
+#endif /*!HAVE_W32_SYSTEM*/
+
+
+/* Check that forking won't return the same random. */
+static void
+check_forking (void)
+{
+#ifdef HAVE_W32_SYSTEM
+ if (verbose)
+ info ("check_forking skipped: not applicable on Windows\n");
+#else /*!HAVE_W32_SYSTEM*/
+ pid_t pid;
+ int rp[2];
+ int i, status;
+ size_t nread;
+ char tmp1[16], tmp1c[16], tmp1p[16];
+
+ if (verbose)
+ info ("checking that a fork won't cause the same random output\n");
+
+ /* We better make sure that the RNG has been initialzied. */
+ gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+ if (verbose)
+ print_hex ("initial random: ", tmp1, sizeof tmp1);
+
+ if (pipe (rp) == -1)
+ die ("pipe failed: %s\n", strerror (errno));
+
+ pid = fork ();
+ if (pid == (pid_t)(-1))
+ die ("fork failed: %s\n", strerror (errno));
+ if (!pid)
+ {
+ gcry_randomize (tmp1c, sizeof tmp1c, GCRY_STRONG_RANDOM);
+ if (writen (rp[1], tmp1c, sizeof tmp1c))
+ die ("write failed: %s\n", strerror (errno));
+ if (verbose)
+ {
+ print_hex (" child random: ", tmp1c, sizeof tmp1c);
+ fflush (stdout);
+ }
+ _exit (0);
+ }
+ gcry_randomize (tmp1p, sizeof tmp1p, GCRY_STRONG_RANDOM);
+ if (verbose)
+ print_hex (" parent random: ", tmp1p, sizeof tmp1p);
+
+ close (rp[1]);
+ if (readn (rp[0], tmp1c, sizeof tmp1c, &nread))
+ die ("read failed: %s\n", strerror (errno));
+ if (nread != sizeof tmp1c)
+ die ("read too short\n");
+
+ while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+ ;
+ if (i != (pid_t)(-1)
+ && WIFEXITED (status) && !WEXITSTATUS (status))
+ ;
+ else
+ die ("child failed\n");
+
+ if (!memcmp (tmp1p, tmp1c, sizeof tmp1c))
+ die ("parent and child got the same random number\n");
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+
+/* Check that forking won't return the same nonce. */
+static void
+check_nonce_forking (void)
+{
+#ifdef HAVE_W32_SYSTEM
+ if (verbose)
+ info ("check_nonce_forking skipped: not applicable on Windows\n");
+#else /*!HAVE_W32_SYSTEM*/
+ pid_t pid;
+ int rp[2];
+ int i, status;
+ size_t nread;
+ char nonce1[10], nonce1c[10], nonce1p[10];
+
+ if (verbose)
+ info ("checking that a fork won't cause the same nonce output\n");
+
+ /* We won't get the same nonce back if we never initialized the
+ nonce subsystem, thus we get one nonce here and forget about
+ it. */
+ gcry_create_nonce (nonce1, sizeof nonce1);
+ if (verbose)
+ print_hex ("initial nonce: ", nonce1, sizeof nonce1);
+
+ if (pipe (rp) == -1)
+ die ("pipe failed: %s\n", strerror (errno));
+
+ pid = fork ();
+ if (pid == (pid_t)(-1))
+ die ("fork failed: %s\n", strerror (errno));
+ if (!pid)
+ {
+ gcry_create_nonce (nonce1c, sizeof nonce1c);
+ if (writen (rp[1], nonce1c, sizeof nonce1c))
+ die ("write failed: %s\n", strerror (errno));
+ if (verbose)
+ {
+ print_hex (" child nonce: ", nonce1c, sizeof nonce1c);
+ fflush (stdout);
+ }
+ _exit (0);
+ }
+ gcry_create_nonce (nonce1p, sizeof nonce1p);
+ if (verbose)
+ print_hex (" parent nonce: ", nonce1p, sizeof nonce1p);
+
+ close (rp[1]);
+ if (readn (rp[0], nonce1c, sizeof nonce1c, &nread))
+ die ("read failed: %s\n", strerror (errno));
+ if (nread != sizeof nonce1c)
+ die ("read too short\n");
+
+ while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+ ;
+ if (i != (pid_t)(-1)
+ && WIFEXITED (status) && !WEXITSTATUS (status))
+ ;
+ else
+ die ("child failed\n");
+
+ if (!memcmp (nonce1p, nonce1c, sizeof nonce1c))
+ die ("parent and child got the same nonce\n");
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+/* Check that a closed random device os re-opened if needed. */
+static void
+check_close_random_device (void)
+{
+#ifdef HAVE_W32_SYSTEM
+ if (verbose)
+ info ("check_close_random_device skipped: not applicable on Windows\n");
+#else /*!HAVE_W32_SYSTEM*/
+ pid_t pid;
+ int i, status;
+ char buf[4];
+
+ if (verbose)
+ info ("checking that close_random_device works\n");
+
+ gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
+ if (verbose)
+ print_hex ("parent random: ", buf, sizeof buf);
+
+ pid = fork ();
+ if (pid == (pid_t)(-1))
+ die ("fork failed: %s\n", strerror (errno));
+ if (!pid)
+ {
+ xgcry_control ((GCRYCTL_CLOSE_RANDOM_DEVICE, 0));
+
+ /* The next call will re-open the device. */
+ gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
+ if (verbose)
+ {
+ print_hex ("child random : ", buf, sizeof buf);
+ fflush (stdout);
+ }
+ _exit (0);
+ }
+
+ while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+ ;
+ if (i != (pid_t)(-1)
+ && WIFEXITED (status) && !WEXITSTATUS (status))
+ ;
+ else
+ die ("child failed\n");
+
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+static int
+rng_type (void)
+{
+ int rngtype;
+ if (gcry_control (GCRYCTL_GET_CURRENT_RNG_TYPE, &rngtype))
+ die ("retrieving RNG type failed\n");
+ return rngtype;
+}
+
+
+static void
+check_rng_type_switching (void)
+{
+ int rngtype, initial;
+ char tmp1[4];
+
+ if (verbose)
+ info ("checking whether RNG type switching works\n");
+
+ rngtype = rng_type ();
+ if (debug)
+ info ("rng type: %d\n", rngtype);
+ initial = rngtype;
+ gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+ if (debug)
+ print_hex (" sample: ", tmp1, sizeof tmp1);
+ if (rngtype != rng_type ())
+ die ("RNG type unexpectedly changed\n");
+
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM));
+
+ rngtype = rng_type ();
+ if (debug)
+ info ("rng type: %d\n", rngtype);
+ if (rngtype != initial)
+ die ("switching to System RNG unexpectedly succeeded\n");
+ gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+ if (debug)
+ print_hex (" sample: ", tmp1, sizeof tmp1);
+ if (rngtype != rng_type ())
+ die ("RNG type unexpectedly changed\n");
+
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS));
+
+ rngtype = rng_type ();
+ if (debug)
+ info ("rng type: %d\n", rngtype);
+ if (rngtype != initial)
+ die ("switching to FIPS RNG unexpectedly succeeded\n");
+ gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+ if (debug)
+ print_hex (" sample: ", tmp1, sizeof tmp1);
+ if (rngtype != rng_type ())
+ die ("RNG type unexpectedly changed\n");
+
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD));
+
+ rngtype = rng_type ();
+ if (debug)
+ info ("rng type: %d\n", rngtype);
+ if (rngtype != GCRY_RNG_TYPE_STANDARD)
+ die ("switching to standard RNG failed\n");
+ gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+ if (debug)
+ print_hex (" sample: ", tmp1, sizeof tmp1);
+ if (rngtype != rng_type ())
+ die ("RNG type unexpectedly changed\n");
+}
+
+
+static void
+check_early_rng_type_switching (void)
+{
+ int rngtype, initial;
+
+ if (verbose)
+ info ("checking whether RNG type switching works in the early stage\n");
+
+ rngtype = rng_type ();
+ if (debug)
+ info ("rng type: %d\n", rngtype);
+ initial = rngtype;
+
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM));
+
+ rngtype = rng_type ();
+ if (debug)
+ info ("rng type: %d\n", rngtype);
+ if (initial >= GCRY_RNG_TYPE_SYSTEM && rngtype != GCRY_RNG_TYPE_SYSTEM)
+ die ("switching to System RNG failed\n");
+
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS));
+
+ rngtype = rng_type ();
+ if (debug)
+ info ("rng type: %d\n", rngtype);
+ if (initial >= GCRY_RNG_TYPE_FIPS && rngtype != GCRY_RNG_TYPE_FIPS)
+ die ("switching to FIPS RNG failed\n");
+
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD));
+
+ rngtype = rng_type ();
+ if (debug)
+ info ("rng type: %d\n", rngtype);
+ if (rngtype != GCRY_RNG_TYPE_STANDARD)
+ die ("switching to standard RNG failed\n");
+}
+
+
+static void
+check_drbg_reinit (void)
+{
+ static struct { const char *flags; } tv[] = {
+ { NULL },
+ { "" },
+ { "sha1" },
+ { "sha1 pr" },
+ { "sha256" },
+ { "sha256 pr" },
+ { "sha512" },
+ { "sha512 pr" },
+ { "hmac sha1" },
+ { "hmac sha1 pr" },
+ { "hmac sha256" },
+ { "hmac sha256 pr" },
+ { "hmac sha512" },
+ { "hmac sha512 pr" },
+ { "aes sym128" },
+ { "aes sym128 pr" },
+ { "aes sym192" },
+ { "aes sym192 pr" },
+ { "aes sym256" },
+ { "aes sym256 pr" }
+ };
+ int tidx;
+ gpg_error_t err;
+ char pers_string[] = "I'm a doctor, not an engineer.";
+ gcry_buffer_t pers[1];
+
+ if (verbose)
+ info ("checking DRBG_REINIT\n");
+
+ memset (pers, 0, sizeof pers);
+ pers[0].data = pers_string;
+ pers[0].len = strlen (pers_string);
+
+ err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 0, &err);
+ if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+ die ("gcry_control(DRBG_REINIT) guard value did not work\n");
+
+ err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, -1, NULL);
+ if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+ die ("gcry_control(DRBG_REINIT) npers negative detection failed\n");
+
+ if (rng_type () != GCRY_RNG_TYPE_FIPS)
+ {
+ err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 0, NULL);
+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
+ die ("DRBG_REINIT worked despite that DRBG is not active\n");
+ return;
+ }
+
+ err = gcry_control (GCRYCTL_DRBG_REINIT, "", NULL, 1, NULL);
+ if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+ die ("_gcry_rngdrbg_reinit failed to detact: (!pers && npers)\n");
+ err = gcry_control (GCRYCTL_DRBG_REINIT, "", pers, 2, NULL);
+ if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+ die ("_gcry_rngdrbg_reinit failed to detect: (pers && npers != 1)\n");
+
+ err = gcry_control (GCRYCTL_DRBG_REINIT, "aes sym128 bad pr ", pers, 1, NULL);
+ if (gpg_err_code (err) != GPG_ERR_INV_FLAG)
+ die ("_gcry_rngdrbg_reinit failed to detect a bad flag\n");
+
+ for (tidx=0; tidx < DIM(tv); tidx++)
+ {
+ err = gcry_control (GCRYCTL_DRBG_REINIT, tv[tidx].flags, NULL, 0, NULL);
+ if (err)
+ die ("_gcry_rngdrbg_reinit failed for \"%s\" w/o pers: %s\n",
+
+ tv[tidx].flags, gpg_strerror (err));
+ err = gcry_control (GCRYCTL_DRBG_REINIT, tv[tidx].flags, pers, 1, NULL);
+ if (err)
+ die ("_gcry_rngdrbg_reinit failed for \"%s\" with pers: %s\n",
+ tv[tidx].flags, gpg_strerror (err));
+ /* fixme: We should extract some random after each test. */
+ }
+}
+
+
+#if defined(USE_POSIX_SPAWN_FOR_TESTS) && defined (HAVE_SPAWN_H)
+#include <spawn.h>
+extern char **environ;
+
+static void
+run_all_rng_tests (const char *program)
+{
+ static const char *options[][2] = {
+ { "--early-rng-check", NULL },
+ { "--early-rng-check", "--prefer-standard-rng" },
+ { "--early-rng-check", "--prefer-fips-rng" },
+ { "--early-rng-check", "--prefer-system-rng" },
+ { "--prefer-standard-rng", NULL },
+ { "--prefer-fips-rng", NULL },
+ { "--prefer-system-rng", NULL },
+ { NULL, NULL }
+ };
+ int idx;
+ char *argv[8];
+
+ for (idx=0; options[idx][0]; idx++)
+ {
+ int i;
+ pid_t pid;
+ int status;
+
+ if (verbose)
+ info ("now running with options '%s%s%s'\n",
+ options[idx][0],
+ options[idx][1] ? " " : "",
+ options[idx][1] ? options[idx][1] : "");
+
+ i = 0;
+ argv[i++] = xstrdup (program);
+ argv[i++] = xstrdup ("--in-recursion");
+ argv[i++] = xstrdup ("--verbose");
+ argv[i++] = xstrdup ("--debug");
+ argv[i++] = xstrdup ("--progress");
+ argv[i++] = xstrdup (options[idx][0]);
+ if (options[idx][1])
+ argv[i++] = xstrdup (options[idx][1]);
+ argv[i++] = NULL;
+
+ if (posix_spawn (&pid, program, NULL, NULL, argv, environ))
+ die ("spawning '%s' failed\n", program);
+
+ if (waitpid (pid, &status, 0) < 0)
+ die ("waitpid for '%s' failed\n", program);
+
+ if (WIFEXITED (status) && WEXITSTATUS (status))
+ die ("running '%s' failed with %d\n", program, WEXITSTATUS (status));
+ else if (!WIFEXITED (status))
+ die ("running '%s' failed\n", program);
+
+ while (i)
+ xfree (argv[--i]);
+ }
+}
+#else
+/* Because we want to check initialization behaviour, we need to
+ fork/exec this program with several command line arguments. We use
+ system, so that these tests work also on Windows. */
+static void
+run_all_rng_tests (const char *program)
+{
+ static const char *options[] = {
+ "--early-rng-check",
+ "--early-rng-check --prefer-standard-rng",
+ "--early-rng-check --prefer-fips-rng",
+ "--early-rng-check --prefer-system-rng",
+ "--prefer-standard-rng",
+ "--prefer-fips-rng",
+ "--prefer-system-rng",
+ NULL
+ };
+ int idx;
+ size_t len, maxlen;
+ char *cmdline;
+
+ maxlen = 0;
+ for (idx=0; options[idx]; idx++)
+ {
+ len = strlen (options[idx]);
+ if (len > maxlen)
+ maxlen = len;
+ }
+ maxlen += strlen (program);
+ maxlen += strlen (" --in-recursion --verbose --debug --progress");
+ maxlen++;
+ cmdline = malloc (maxlen + 1);
+ if (!cmdline)
+ die ("out of core\n");
+
+ for (idx=0; options[idx]; idx++)
+ {
+ if (verbose)
+ info ("now running with options '%s'\n", options[idx]);
+ strcpy (cmdline, program);
+ strcat (cmdline, " --in-recursion");
+ if (verbose)
+ strcat (cmdline, " --verbose");
+ if (debug)
+ strcat (cmdline, " --debug");
+ if (with_progress)
+ strcat (cmdline, " --progress");
+ strcat (cmdline, " ");
+ strcat (cmdline, options[idx]);
+ if (system (cmdline))
+ die ("running '%s' failed\n", cmdline);
+ }
+
+ free (cmdline);
+}
+#endif
+
+
+static void
+run_benchmark (void)
+{
+ char rndbuf[32];
+ int i, j;
+
+ if (verbose)
+ info ("benchmarking GCRY_STRONG_RANDOM (/dev/urandom)\n");
+
+ start_timer ();
+ gcry_randomize (rndbuf, sizeof rndbuf, GCRY_STRONG_RANDOM);
+ stop_timer ();
+
+ info ("getting first 256 bits: %s", elapsed_time (1));
+
+ for (j=0; j < 5; j++)
+ {
+ start_timer ();
+ for (i=0; i < 100; i++)
+ gcry_randomize (rndbuf, sizeof rndbuf, GCRY_STRONG_RANDOM);
+ stop_timer ();
+
+ info ("100 calls of 256 bits each: %s", elapsed_time (100));
+ }
+
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int early_rng = 0;
+ int in_recursion = 0;
+ int benchmark = 0;
+ int with_seed_file = 0;
+ const char *program = NULL;
+
+ if (argc)
+ {
+ program = *argv;
+ argc--; argv++;
+ }
+ else
+ die ("argv[0] missing\n");
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: random [options]\n", stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ debug = verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--progress"))
+ {
+ argc--; argv++;
+ with_progress = 1;
+ }
+ else if (!strcmp (*argv, "--in-recursion"))
+ {
+ in_recursion = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--benchmark"))
+ {
+ benchmark = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--early-rng-check"))
+ {
+ early_rng = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--with-seed-file"))
+ {
+ with_seed_file = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--prefer-standard-rng"))
+ {
+ /* This is anyway the default, but we may want to use it for
+ debugging. */
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE,
+ GCRY_RNG_TYPE_STANDARD));
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--prefer-fips-rng"))
+ {
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS));
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--prefer-system-rng"))
+ {
+ xgcry_control ((GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM));
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--disable-hwf"))
+ {
+ argc--;
+ argv++;
+ if (argc)
+ {
+ if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
+ die ("unknown hardware feature `%s'\n", *argv);
+ argc--;
+ argv++;
+ }
+ }
+ }
+
+#ifndef HAVE_W32_SYSTEM
+ signal (SIGPIPE, SIG_IGN);
+#endif
+
+ if (benchmark && !verbose)
+ verbose = 1;
+
+ if (early_rng)
+ {
+ /* Don't switch RNG in fips mode. */
+ if (!gcry_fips_mode_active())
+ check_early_rng_type_switching ();
+ }
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ if (with_progress)
+ gcry_set_progress_handler (progress_cb, NULL);
+
+ if (with_seed_file)
+ {
+ char *fname = prepend_srcdir ("random.seed");
+
+ if (access (fname, F_OK))
+ info ("random seed file '%s' not found\n", fname);
+ gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, fname);
+ xfree (fname);
+ }
+
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+
+ if (benchmark)
+ {
+ run_benchmark ();
+ }
+ else if (!in_recursion)
+ {
+ check_forking ();
+ check_nonce_forking ();
+ check_close_random_device ();
+ }
+ /* For now we do not run the drgb_reinit check from "make check" due
+ to its high requirement for entropy. */
+ if (!benchmark && !getenv ("GCRYPT_IN_REGRESSION_TEST"))
+ check_drbg_reinit ();
+
+ /* Don't switch RNG in fips mode. */
+ if (!benchmark && !gcry_fips_mode_active())
+ check_rng_type_switching ();
+
+ if (!in_recursion && !benchmark)
+ run_all_rng_tests (program);
+
+ /* Print this info last so that it does not influence the
+ * initialization and thus the benchmarking. */
+ if (!in_recursion && verbose)
+ {
+ char *buf;
+ char *fields[5];
+
+ buf = gcry_get_config (0, "rng-type");
+ if (buf
+ && split_fields_colon (buf, fields, DIM (fields)) >= 5
+ && atoi (fields[4]) > 0)
+ info ("The JENT RNG was active\n");
+ gcry_free (buf);
+ }
+
+ if (debug)
+ xgcry_control ((GCRYCTL_DUMP_RANDOM_STATS));
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/rsa-16k.key b/comm/third_party/libgcrypt/tests/rsa-16k.key
new file mode 100644
index 0000000000..017915a239
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/rsa-16k.key
@@ -0,0 +1,18 @@
+(key-data
+ (public-key
+ (rsa
+ (n #00D6007A7AD47BB8D6B356E4F24DFAEE3A722FEE77F7E9547F866CB369C233E6CB3916D416973E3157B4DC1837E6D4C907D1063855735EAA857176A7DA3CA9F378FF7AE9EF227C193965F106F35DB2A833D2760CF9F2D041938CD310D9CE38EDD179C33EBC4963A02221D8000FDBF4BEB592CAB1ED1EEEC9D6916F27263C76DE70184F5399DE3B3862227346B1B3FBA306174D08BEC3675E2593CFD42159655B0BE1A2B69C2BA9F4F03B8C6BA505F6BFDFC6163D74F42A6D4908284D6879CECCF6512F9225612E3030ACF3663DFB77B41AFFCFC70BC11B224E14B397D25AC15E4E342B34B363056EA76CB0265DBD41F733C7FDE98B7C2340289E338CD31F993ABFACA6E83B54BCB50DD1DD11165C188C80EBDA190A11B6D8982CDA1B6B9D1631AA3EACC93040237831A52D15826A0D3E92C833D0234975C92A7236F902FA6703C89C7779765020C11F714B4C9D33B76CD466DC2BE9A102488B0635F31E6FBB9282E5139D32623E10ED9C295DA3B39F68227218EDF8C6FE9372F174AE1DE5BBE7B0AF09A869CAEDBEFE05458BFD43CF32F10F5C345A2E3D588C8C16B4DA8B44FA9539C679B81133A35498696F5D866E3B6A89811AEA7BFD1BF690EC329D87989CDADA7EAB106785D2D6661BD400D76C113E28F13FD883027E1CAC848B13750C7CCD530273C165BDFDA93E6F72897E97F003308704B95801F223EE89160786B1DE440BA9C1F371CBA37E5B09650CDB3AA1ABAA237AD15B89DCD03390A28308643E219490BEC83403F6A09B94F81D7BB391C121FC9028A6908E5B287AC79209B905B33724B1869A679CB347BF192D80D2D66CF1DAEFEBBF22CEDB8CEC010D6F8D86CD055ED71425DA72DF1C07A573E6F070235C378DAB5404ED004B4946CCDA4786ACBBF379A47CC36A049C50651CA4B1CEF03EE87DB6D2484C3D10AF71798A6AD1E20780814F79348D45BD1004880D2DEDEBD152694C80B9F93DF32F5930911DB379B4CBB9230CFC5FC126B9B77F074B9C82BDB4F12471B3FE92079525FD276293B63B978B55E039024EE688180D7C7C6C094B754AB9B652AC31812F2F7E45EF2B6D4478D7C6E5C8F3CB0A4D04A3E693D1DD4D8F894E910D9A999DDABE0427A1AB0C715C5A695A69140B20B9DA1195E6C9536B5DF24B4D45ED24D0F2C276E3CF48066EFB977C2B7096B02EB52309D916BD432347D72799BF9D76A03D54DE211460017C0E268BC9E23B415ABF46EB8B939B5A413EBD3F20E95F704E1F2CDCDF974A8743923DBC6D8363DC8948BE85EF1D368CD3EABDBE5B82648D2F676EB310D7B77465D3A14B86050463E43AC745F3781E7A6F582BD7B8AB22BC4EEECD2CB155E6E0B2604843E3906D47EBDA2C10B6D8BFCBB5722CE5394EB50721E90EFD28C63A62269C8C14593D69076D0F198D2BDCCB6D753CB81C4BED56A90E2DDBFFC0B9076C65F973B5EA3242E71E3CBBFE0976CFE22475F56726058D2D0CE3BD52AA940A0F559DD055BE9A6F50846902E02B70DB4FF5BED33762E10409D25ABDACF661BD9BA2A22212E02893A1625CA44850887B4B3A00D0AF63645E2EC42333035062090E8E7E63037C692FBA0B3FC7F3686FC2831F4DE2D4D82CF6FD6321D6621C8227715E3772EE8805911AA9E67083C511F17863C4D6F2C29E19CF329200024E539A7C5BF1A9D601AFF8DB7CFD75C6532488469E44BAC7266A3C127720E640328F9970B75509E292CCEC0B55A1F729456CB2804BE50451185F8CDA313C7D4DF6C1C67D6C411025A2BFFF06C5062470F97B17E75B4F81CD1FEC777465D684849809B4281B690D2A8FE5C4FA87DB00328630FC31BFDDA4641B29CB434147806A614E450E3E2B50317E3B4EE6262A2D4D0A8FE7530CEDFBCB5016C4D6E61C34E61AFA324871A9C75F9BC6BF6C92B95910C9D0FE049AEEF2E96E4C9E69E1FCE1F6CC687D533668F55367E2695197BE392A7FE66C4F88C0B1A9DEC6DFF682675855979DEA2A5644748DD882CE1F0D8FDA8530617BAA130AD9C16ABF8D76B5853104AD2E0C54C9639C3F6E1343AC94139621245EE8E12CA4366A6EC752BD9D1A0948CCC3626CEDB882BA4638115BBF55444DD4544EEC561F0E762C9989A9306D4749ABD47C31F40AD3F735FEEE6E1FDCEB626073CD5F76730B348103B041B9EEB941EFA61581DD9278802A2934C33FF0668C25CEF2546C44263A68919ECBB540B4A18E1867EA15C9F7A2853F55EFBB01C3D27D28579E030D0A771B754680FCD46B56EBD3431C24F202A343E20294076E56A09FA5F6C3E844DAF5BDCFBFF55CCC3FDDDB060FBC680BA520153098E57FC7741D77DFA8932F9028D8E0E66600974A41DAC5BBA4690407AC36EC206655ADCECC8AA0471601F67C3DF48B830585FA15C52061C4FF958453B1E75626120CDC0ADCE44743027FA4C59C1931E90726CD2BE240D0DC6D61CDE5165350D86FFF17260A823C0AE3467A597D774A67BE843951975E17BC1CB69DC8A0C7BFF799FB8FD2BDB37853D2EB28C9B7B8A2212FC73FDF2F21FF3FBCD798533FC4867739E48BA061B174BAC224064F3E867A1CF52E091FDD36871955FBEA90CD3D23B1BF0039930E0636080E6A36206ED5DD1CE4546EC0B0802BBEE2869DCCAEA01B8FC3A6392820180AA4D99AB67C57E8FD0874E7C54BBC7B9A2AA4D1EA4ADC1A2802DF908AF74F915AF98EEEBF822AC958CD0D9AF5A754AB2F4790225F18864A94734E526BDE497FF21F3392472D4F0E3B7E2EE97DDCA15060BF35A05E2593418809D3C9738C328EB4D44F35E6C913069096B0742809F55F01D06D40EB0476C34950FDAEF9BD2CC1F7653B4BCF1AA304963530C8F0C39697EAD32ADF464E3CAC931D33992B357A3A231FB978A56C3592A61411A5428C3549A991D811#)
+ (e #010001#)
+ )
+ )
+ (private-key
+ (rsa
+ (n #00D6007A7AD47BB8D6B356E4F24DFAEE3A722FEE77F7E9547F866CB369C233E6CB3916D416973E3157B4DC1837E6D4C907D1063855735EAA857176A7DA3CA9F378FF7AE9EF227C193965F106F35DB2A833D2760CF9F2D041938CD310D9CE38EDD179C33EBC4963A02221D8000FDBF4BEB592CAB1ED1EEEC9D6916F27263C76DE70184F5399DE3B3862227346B1B3FBA306174D08BEC3675E2593CFD42159655B0BE1A2B69C2BA9F4F03B8C6BA505F6BFDFC6163D74F42A6D4908284D6879CECCF6512F9225612E3030ACF3663DFB77B41AFFCFC70BC11B224E14B397D25AC15E4E342B34B363056EA76CB0265DBD41F733C7FDE98B7C2340289E338CD31F993ABFACA6E83B54BCB50DD1DD11165C188C80EBDA190A11B6D8982CDA1B6B9D1631AA3EACC93040237831A52D15826A0D3E92C833D0234975C92A7236F902FA6703C89C7779765020C11F714B4C9D33B76CD466DC2BE9A102488B0635F31E6FBB9282E5139D32623E10ED9C295DA3B39F68227218EDF8C6FE9372F174AE1DE5BBE7B0AF09A869CAEDBEFE05458BFD43CF32F10F5C345A2E3D588C8C16B4DA8B44FA9539C679B81133A35498696F5D866E3B6A89811AEA7BFD1BF690EC329D87989CDADA7EAB106785D2D6661BD400D76C113E28F13FD883027E1CAC848B13750C7CCD530273C165BDFDA93E6F72897E97F003308704B95801F223EE89160786B1DE440BA9C1F371CBA37E5B09650CDB3AA1ABAA237AD15B89DCD03390A28308643E219490BEC83403F6A09B94F81D7BB391C121FC9028A6908E5B287AC79209B905B33724B1869A679CB347BF192D80D2D66CF1DAEFEBBF22CEDB8CEC010D6F8D86CD055ED71425DA72DF1C07A573E6F070235C378DAB5404ED004B4946CCDA4786ACBBF379A47CC36A049C50651CA4B1CEF03EE87DB6D2484C3D10AF71798A6AD1E20780814F79348D45BD1004880D2DEDEBD152694C80B9F93DF32F5930911DB379B4CBB9230CFC5FC126B9B77F074B9C82BDB4F12471B3FE92079525FD276293B63B978B55E039024EE688180D7C7C6C094B754AB9B652AC31812F2F7E45EF2B6D4478D7C6E5C8F3CB0A4D04A3E693D1DD4D8F894E910D9A999DDABE0427A1AB0C715C5A695A69140B20B9DA1195E6C9536B5DF24B4D45ED24D0F2C276E3CF48066EFB977C2B7096B02EB52309D916BD432347D72799BF9D76A03D54DE211460017C0E268BC9E23B415ABF46EB8B939B5A413EBD3F20E95F704E1F2CDCDF974A8743923DBC6D8363DC8948BE85EF1D368CD3EABDBE5B82648D2F676EB310D7B77465D3A14B86050463E43AC745F3781E7A6F582BD7B8AB22BC4EEECD2CB155E6E0B2604843E3906D47EBDA2C10B6D8BFCBB5722CE5394EB50721E90EFD28C63A62269C8C14593D69076D0F198D2BDCCB6D753CB81C4BED56A90E2DDBFFC0B9076C65F973B5EA3242E71E3CBBFE0976CFE22475F56726058D2D0CE3BD52AA940A0F559DD055BE9A6F50846902E02B70DB4FF5BED33762E10409D25ABDACF661BD9BA2A22212E02893A1625CA44850887B4B3A00D0AF63645E2EC42333035062090E8E7E63037C692FBA0B3FC7F3686FC2831F4DE2D4D82CF6FD6321D6621C8227715E3772EE8805911AA9E67083C511F17863C4D6F2C29E19CF329200024E539A7C5BF1A9D601AFF8DB7CFD75C6532488469E44BAC7266A3C127720E640328F9970B75509E292CCEC0B55A1F729456CB2804BE50451185F8CDA313C7D4DF6C1C67D6C411025A2BFFF06C5062470F97B17E75B4F81CD1FEC777465D684849809B4281B690D2A8FE5C4FA87DB00328630FC31BFDDA4641B29CB434147806A614E450E3E2B50317E3B4EE6262A2D4D0A8FE7530CEDFBCB5016C4D6E61C34E61AFA324871A9C75F9BC6BF6C92B95910C9D0FE049AEEF2E96E4C9E69E1FCE1F6CC687D533668F55367E2695197BE392A7FE66C4F88C0B1A9DEC6DFF682675855979DEA2A5644748DD882CE1F0D8FDA8530617BAA130AD9C16ABF8D76B5853104AD2E0C54C9639C3F6E1343AC94139621245EE8E12CA4366A6EC752BD9D1A0948CCC3626CEDB882BA4638115BBF55444DD4544EEC561F0E762C9989A9306D4749ABD47C31F40AD3F735FEEE6E1FDCEB626073CD5F76730B348103B041B9EEB941EFA61581DD9278802A2934C33FF0668C25CEF2546C44263A68919ECBB540B4A18E1867EA15C9F7A2853F55EFBB01C3D27D28579E030D0A771B754680FCD46B56EBD3431C24F202A343E20294076E56A09FA5F6C3E844DAF5BDCFBFF55CCC3FDDDB060FBC680BA520153098E57FC7741D77DFA8932F9028D8E0E66600974A41DAC5BBA4690407AC36EC206655ADCECC8AA0471601F67C3DF48B830585FA15C52061C4FF958453B1E75626120CDC0ADCE44743027FA4C59C1931E90726CD2BE240D0DC6D61CDE5165350D86FFF17260A823C0AE3467A597D774A67BE843951975E17BC1CB69DC8A0C7BFF799FB8FD2BDB37853D2EB28C9B7B8A2212FC73FDF2F21FF3FBCD798533FC4867739E48BA061B174BAC224064F3E867A1CF52E091FDD36871955FBEA90CD3D23B1BF0039930E0636080E6A36206ED5DD1CE4546EC0B0802BBEE2869DCCAEA01B8FC3A6392820180AA4D99AB67C57E8FD0874E7C54BBC7B9A2AA4D1EA4ADC1A2802DF908AF74F915AF98EEEBF822AC958CD0D9AF5A754AB2F4790225F18864A94734E526BDE497FF21F3392472D4F0E3B7E2EE97DDCA15060BF35A05E2593418809D3C9738C328EB4D44F35E6C913069096B0742809F55F01D06D40EB0476C34950FDAEF9BD2CC1F7653B4BCF1AA304963530C8F0C39697EAD32ADF464E3CAC931D33992B357A3A231FB978A56C3592A61411A5428C3549A991D811#)
+ (e #010001#)
+ (d #0125A7ED14E014111AE2BD8FD81A69B0BDED886DBE477D9CC08C6B07F1F82BD5BD73797FF9FFFB0D2542BE97FD1DCE9FE30F516F117DB449B513C85EF779DC91DD57B6B2E1BDD077A1EBE148486C2ADC8FEAC7FE1BD40BDD45E6833B26FB75388D05293177EE12678B197B42EFD59A38985B4BB471A3761E41F1BA8AB3A2AFA5A241B999096B8A9809BC7C5DBB3BDF476049AE7671A47213C9922B7E4C1A5545BA92C555100DB00AB77254C8E1DFC283F3EDE901819B611CD5E551133D14E8FD18840F6331D29E2EED47118E7094C1E36E53DA2AA90133856A351367224B51F80C184A5C3C4CDA5CC822126B3DF696AE96BFB8B836FA56E4E8D7D8A545E5F668F23203AC6968BE0A8A0C3BEEAC0AC9CFAE994B8EA5E293A5B9817D49B89761528595BB99D83C2B1AA4054FA2FF1D1D4F8ADBC3E863D8F4BD8C76C38E057D81740FB4FB12BC3CF80AB510223934FE8D3FD461D17E9B4EA07380A7E5202DD93A40B1F2E6C2048160949A247AC9A3F962A4E2F4EE809F00C76AF8DA4737D1398E6A95BE4637C949A33492C9691B254EB239EA7B1EC0E2D4261A27183F90577F04B356FD10FDB5E23A4471068952930EAFF4EDC757ACE25781DBA807A0C153FEDDCCB55A08B774AB44AD2CC75BD319D4822BFC6AF24C9F837C72D1A615109882906ADC2B2C679630A6FAE363144B77A134F2856DF1D8E9A77AAEC08A72FD67C122BD280D591A6C4045D0497362FB91C8C38C00A457A0BBE8D625210E4BF55FC4041FBE0A1515B70EA98C4F4284B3C96C15DD21C8CC15305DB5BFA2C21EB9520C9ACD823F5E7ABCDA3993D89A7B561C101FEC08A8AE6621245CAA1406D7536FBC6E835692D2B1BB540B8F2B2EAB7A1406B2FE83873CDEDFB0A0E717A037CD3A6322AE0B6F5E36187646866A0D406F7F54007FEC9711311BCE87FC6B4F44C5D1F7BEDD2DED081F1439F38312FA27CB65665B1595F88713378797AB624C728CA6632653EC8E762A76E3E597AAD4C3C3FE41648AEB07FCB8BFE9C70A1818E4F1B19124BECD320E4CDA6A9FD02B0A422114B5DE31376549C3B5FE1A896F8FCB256B814BD100FFBF5359510D8FD243DB014DBCFA3036C857A41DCBAE29ECE25012AF0B88827A1B3F3FA6E75EDF1790B0CCD794D0E733315743EF50FA18E5E1A93DC5D1EB28F555C0A8541B729954EA1865C6FDBE810D153CB50C024E8E7A59D324C22B626A30F4AAA0FA46EDCA4CC42F4B2D033B147DA54A67D103633A88EBFFF0EFFB61AA98DD2B057700FAC0986A9FB27C2CC29EE30B699DE063C76A1E2863D13951C35C5ABD357555781D2A5E68B0BFACF2E11747006E0810DD0CF97D585318A3B0DF7A67465EC3761004AA9B7C141B4E5444D9EB649BBD94F983FCFAEC982D994C7A620DE2D8AEE012BFD22AA9322F3DD3BD5CE90C17660D18F8CB679B02BDABC0D4D0F876B0DD6D258E08DC50B35544A4BDBE5F75604493D5FDF98B7FB812475C7B7122DDEC512322E1855C31105397AF284B7C2B4DC315D2E8D5017BBD2400885D5EB6C321B5093EF98A14EB4C29DC2B7DF9565D9E23A2BE6A2E334CE3485A8677E463DD86F49E3B56D2974F7D930FFDD60BA54AB49AE9DCDC588A4FC7AFCDB89A7713C51FA97BFA8868EE207C3C0032FDB302E45DFA0DFD8A2DE4D50A959A424626CC92CE74F8A2627C3B20406D714BB64825FBAE1B44A2F7569E32A8CBB41DBA3D9115691B07C3951A2D1394BF06BB0690B710D438CCC4E5B92B0CF302109A60C836E3AB40E4D3579C2E1C77F432C62925A751D92A564440A563B3C373D9A46FFCB0EB478962450C11192FDE187718F9AEDFF61DFE39AE98714B1DD49C356593F23F2BADE0E753B25BDCB3D618E3CDC5C5D8F37974A449E6E2D21B46FA90435F399AFF98988DEA9048B8031E1AE2E4B2B7C3FBB7CA775B6058500DB8852FF7358251CBF12A3CA233719760D251939A29778D7B4BDE15B5244B8AB47555C18925222331443DD6B227282A101443F14851734796FF4E323B66ED8304E594973EDBCA57B9413BB83574673623CB9BA282F92FBE49BFC7D6D18644C1741DAFEE86B58A174AA1B576F2599CAA8F15C9AC513CCC3778EAB81D6EF90557E73E207E96BC2D83BD3FED3717B0E8E527AE27BD05B28962280099AD1AF8C8D0B0E668EDC73AB3BD7E21C9C9134BFBC837BBC8E68FE8DF48365491371D378CB768A24A956F0D625D47EDBBAB051E4B4EE5D59574A4F2C4371D491ED182CD945DDAF11EB17382A58F2AFB6B79DE3EA1636C67449340F77A1CF14DFEDCB42B18BFFB866DD007B9A606C7BAEA70F9C5EAC98CBB52ECE5932F2925ACEAAE412E6114090CB54145A751E430EF1CA3A418C4D76EA7D797FF882401FD21984F4FBC347C4BFBB5B2B946B65F4FE0C7B9E5E16CBC1B6612325A0C83A8740D5D885C443EB8D02289BFC72E3BD2925E599B863F117C8A32E81F4B6F2C0C5D8CEA6E75C03E564E3F8D1663B5F3D21D844B6F80FB982484809303019670115FF5CC5FF6681E1C9B9AB01EA719AECAB7A4C4F1044017449741C726A4D1D97D0FB0D390F37DE0F838038270AEDD5E058113252D4F8E91B1377FD24F528EEDF58AE575327BE17F4A9D68E24B39DDF1187C8ABCEB1A84AB6BAB0735F3756E512641E62D3B51DF0316D065949379DD06C07606A82126A129A2A70F91EF54096CFCBC3447B49D5DD5F7DC7AA9F3E86E8ECD581F51731DF726194CD3143CC1E608AE882EA8848CDFD9F3FF6282AC6D722C2D5F51F2652724FEB601E02E1F078E32B36892ED9E2DE0A637836A005B01CEFDADF90534049565E8B965224B3E7EFF5707F3DEB6BFDB8D8045549168CD1C81910E584978A555DE877CFBDCB8D7388D3081F9DD8067198562521FEE99C57E3401#)
+ (p #00E6BBCBEBFCA813CED7907F5FA73C4C2D3532AF7A7650C4A88563DF805D54D0CEA528347A60F703C8FFE91997505F8C238383E03C53DFD347D0E385A5CFFE4E2A944DD45ACBC481D54D7B22F4C59A2BFC8C686E527B907AD9C5ECE870D102550D8D4A02B404DAE7023CC8F0436DE5F50A7CE1F4E741147F676B5DC9437CB47727B93155AE5C1EBE236E9F436D723FF770104305A1460C21BE9361582CB107CAF036F0600BCC6D78DE73C1F44C25F377B9A65349E9B73C446E5C6281DCB68EC65AF684AB39F6C84CF96E4CD909B61FA2D8BBB69A7994B78865FFEACD3838F851C944039C2422B75AE4F9C2A1702B005641EB41CE9FB042757E86F6E9651428EBA4D908D60A99AD61E5D09E7A05C7E59A9615DE965200CFB75A228B1D5DB8D2C040A65D940D5516C9FC5069B94D2F1903EF6B07F70ECF3E8D720F74139A4647D79131835CF7F15EA839350A00BD9D733359503497BCE39A2497CACCAD41B0AE7A36E6F01FECA1B0B062F9C3232BD6F6734C97DB2EE7DE050370087210F8161B07237E712E29E0BA6B2B661EC22DAD0509D50EF75255D40B954D2B3694C30E5982EB2D15B72A8709BC4F9B6FEFC4E6F01FF04D128311209B4C4353AF43BDE58D631DB7E047D7B469CDE4A9176415F6F7B60BC129E0BA8363D77140DA0FC685DB76FCB968C8C58657DB86FC908E7D11F41D907CA367C17AD3EF81280721FD40E6AEDC118538AFE109B8FA818502982578BB2EAE3ACC3028EF79C4CAB575CC8473E05FF5D911186058BCA7F5269FAA66CBB68CE47EE0748F2A8E52EEB8475030D34E54C365572BA282226730ADA3BEF16D582A409F15AB89188F1737F7CA82EE0D96BD2B3A2153CDF6EE27FD04F4AEF4AA3FC6EB02E92EC21359864507EAD3E09D3117EEDD61AF34265412C362EE01B26B925BC74A2679A1C112C653AE88FD124220742A05DDCB1CDE7DF2342669FDF76E1C3F9BF8FE13633ADF33050FA491FA708A918ECA787FF074E90F9A0AA216ACB1160D22BE7A9817DEF5FA2E27FC906ACF5B5774A5DB069A66F5F1752D7521E1CE49F8888218BA24C97A92C287DAB8B08B4433EC1DDEB5C7A3D96956EBCC46A2DE2B95CACA91BECBCB15DCA20D13C977F50F6DC0D705DB78B597581F850E20E0EEB6EA9A7A9D2708A650A3CD0748EE1DDAEA559C80D2A00F2DBD29C3EF58C13CB0B84AFA30C508BC8AD71A4FC3E14690F16B52943013D7BB09F5627D7D1343DAED88198D5ADA23E0B94484E06A827FE49227540110ECEC9E354F87E27496B7FF5ED31521817C8B5B182129EE0C521C85A996BF5EAF1F87583BDFE69386EDCE63337252F58D37AEC742702D97F3B97CE0FD06EE60EE4380C2E48D7AAD49E26F76CE981237ADB617B0BB6D59DAE31B6335866E7F9670F8A25D9BC44D7C32602BA3D58002BD53473E3F781249AB17C1C78C496611#)
+ (q #00ED6FA36442A240865581B5C398C93F55AFD5386A801AF1D8BF8A9FF8AB9C578F97DA02AFC44180AB581A1E10A4D65B7D1E9C0B04D57FB1FD13B7ECF1AD7C0296F1F5D52C3223CB117E6C6BED1FDA701A7A4079FBD35B180D2295B216FEAB284F85594EDDDC179C9AAE6E6CA545D2FBCA308B0961B21A1B4A4E9DE27CF8D6922FC902C35313B05F0FFB5CC667E64E0706D5210D3919074B384CA5968359CBA5F4BCA096323AD48E2CDE9D25F08E2EF945A1DD46457F48B4BF8EBEC2DC3737CC09E333E30F17A3ACD19567A5C5D200E7A4303A97A893F0884ED3CD976B41C2BCEEF04D9FCE4F30218CC9AAE26FFC5749B10011B805ADA9C4857B691A7A820F2564DF5979F570F8D524DDE268F702891E9CCDBD9F821C2ECF27F60C795E743AC67CADB07D22D3A7BD322DA9C3E7A35AC6A35333F871FE6DE0162BA2A1F9565E411ADD424FF0727B2280BAFDDF522C272D3A2910EFE27F5590F8E0F6C38BEA1895A0893755F44BDF41FECF3BF3BA27C6D6F036A1AA70736DE71465FA78EA46F34341E05DE7AB37A5074B4E99E0BAB54D658629503E1242ACAFDE08721058F208D3F62FAE742D158CAE521994514CF0BEC580F075046319FBFC8E971F0FF5EED9E2AB7D194CD21ECCCB2E54D239AA3B0254F4AB1641E6E8E1512FF1D1ED579205F1807898828CFA24B80D230FA6C52C6A92348E1A069C239F7B6F2E7CC995BD3CD1B413FC86C626FE962C7EC3CF19FA193B3A732AF17E51E6B57CC263DE82A5C45CB9E37C2BAB44E88E5792FBBC40748F86134D221BF775E2BF57F98A884FCBA494718661A3FF73AAE04A6F5CDFB6F143D680D09BA4CCD6C6F186E92569B8F67A35B5796B9F2ED404F11C54ED290D7D7836501473F06D8A623D53AB586B644F3F5BDF8B0B670CA696A23B7B52319C91D2CA27FCDF421030CEA8A6B079FEC2E467BE0427AFCEA12648F3E12F09745166D20D3D1CD6965EABA2732469C077B3C4E44D3503D882937DA5139076144FAEAB75083BF4E16725BB9625A99DE92F6F226DE343F73E974577F8D6F5B57CFBEB60763627240A28C90A73BC7A9E47D74CBABB6486988C983A5A3DC91A4D8E353AE6C608499D21391E32D8EF3A030925959B52C1BC03F17AAE2FEE4E28B2B51889EC2A5FE587C60139C9CF29AF46555B089B54B5EF0BB3B92BCC0EA0E6E94F944FE8E9741DDA902F185E0D16876A10351AD22FE6ABD4378AD74A13CD2BD9696F0B59A069CD6582F92458A89B15648E833614598D6FDABAC026791CDB3FA87873CA86E3DF7187C9230AFFB1089EF83B8CB54856ADC234D07DF479514A8F47EC9903930E47F9E93AE1F96D7358F4208E19CCED8AEC063AFE8A31E39C921F7D7867D57E8F68B1494793E6DCD06F3DC68809BD455DBB44076D6AB64586E0A09A42CEBA2829A5F81BDEA5EDB23DC251D69C373D2E275201#)
+ (u #00EA2CBBEFBFFBD4BD3850584AEA315F88ED892F7398E5C4ECD17F8E4588B073DA32AC708DADC0E55417553FB4DC25130F42A9A04E435C63E1091744232D53FF98ABA450E3B91AF512631E28BF453BE4FCB9713112F890F368523FE175B0909385F0B404B3E6370FA6DB33490DC216CE3DE548FDDF68C81FE49BB9683C30FA6D1DE8B019A94683E508B720F2EDA20133325FD4644620D086182F1E8283215D2BCBBC1B302DEA714CE1E59FE8E996489018078F8CCDDAEF086EFDF82BA45DF424E539ABC9D61ABEC14346275AA9256031514AAC59FF40C7D1B4363AC7C74E8CC3854C9E57F6913C2CFC599E9DBB446D553482C9B531563A7CADD562D64151B3961FB52A0D542406D491F8090EBB737C388016F95918313C0EC987F701F2A25AE3F0CEF2B9F3460A9E48AEE382F01CB09B0A9372104FAC2EE692BB2B14E6FE376A29891687E157C40F09FB3283402E4D319C9791E7A06025C542B4411EEA71890D22E34E8038B3002AC7FB75A50ED29AAEAFF36588950A06A8D2139B0420673DCB37087E8196A034D0A5C78A824BCD0A74BBD7E08B04B8F08F473C09F6350508CEB476DEE1E41D0CF960CA3E87AE8489811577F7D49CB1EF885453F7087B8126FB99028B5771EC9E159040109102DEE175DAFA038EE7B62B96797E56E6361C37DFC42398020114765E28C3F3B4B6A4C33A86A995A0D5647068B7147552F4E6130866527D4833949E9F9204406F096735F33BFD1BB57734E15D0B4035A37CCA7C897C18162B12951A684F586F1B7FF041A85B7F44FAC125A80AC782AD3F4D7EC52C318EEA52CFA6AF09EBA50813B5BAC8367B1FF80A99DB8BDEC3E3842455A06D22DA99F0BE5B52330D1D5C0CCACB3661D703BE1D96E7832A159C8858E08CC23101FBC0DE783D3209A80A3ED4EBCF57661B01D84EBCFBE70A0EC921588B8CD9B9BF21918D86C3C97B0F6BBF4037E80C99A349A1A2B78F337CC4029415FF0DB54AC9A3A1DF7E07482DC9F04E638C9D5BBAAD32A627F2EF1DC3E17AEC365E416C703C449AA40104DEC358202F7F78CCF77115ADAD567CDAE6B4B2C81DA4FBE6A97BBF2A704389911E4A5B39C3C1F187101E53B3DF7A0CE05C4B7956F4ED31DD225B46036C5344B3CDB236E5B1A12E159008D106D1CF6C14C5F7335A4A5D80E008F0106F636EF750723B50511F37B3BA6FFBEB27A270828B9CB123D7F59EA0BE956C0D024C77AC06086460998F18610ECB94651DF47AB37DDDCDB9797203A4321CBC1E6E85EC64919EB74AC7E2F3C15FEB5DFCCFC2359D353C8B6B600152D4211A55477FF31026B34C10C5F1FC1A1DD1C1EF6A14B26CFD1AF70D6BAA4461B4387631E4DCFDFFAB118F710A8B8B2D12EEC4924751720B9AA9D94527B9F19E8B352222567F662FC6753AA4BE22C2A851F2378AD5EE5539C1E0F4DD90400DD7DC6F1EA675D9#)
+ )
+ )
+ )
diff --git a/comm/third_party/libgcrypt/tests/rsacvt.c b/comm/third_party/libgcrypt/tests/rsacvt.c
new file mode 100644
index 0000000000..3cc50d7993
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/rsacvt.c
@@ -0,0 +1,399 @@
+/* rsacvt.c - A debug tool to convert RSA formats.
+ Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+/* Input data format:
+
+=======
+# A hash denotes a comment line
+e861b700e17e8afe68[...]f1
+f7a7ca5367c661f8e6[...]61
+10001
+
+# After an empty line another input block may follow.
+7861b700e17e8afe68[...]f3
+e7a7ca5367c661f8e6[...]71
+3
+=========
+
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#ifdef HAVE_W32_SYSTEM
+# include <fcntl.h> /* We need setmode(). */
+#else
+# include <signal.h>
+#endif
+#include <assert.h>
+#include <unistd.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt-int.h"
+#else
+# include <gcrypt.h>
+# define PACKAGE_BUGREPORT "devnull@example.org"
+# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]"
+#endif
+
+
+#define PGM "rsacvt"
+#include "t-common.h"
+
+
+/* Prefix output with labels. */
+static int with_labels;
+
+/* Do not suppress leading zeroes. */
+static int keep_lz;
+
+/* Create parameters as specified by OpenPGP (rfc4880). That is we
+ don't store dmp1 and dmp1 but d and make sure that p is less than q. */
+static int openpgp_mode;
+
+
+static char *
+read_textline (FILE *fp)
+{
+ char line[4096];
+ char *p;
+ int any = 0;
+
+ /* Read line but skip over initial empty lines. */
+ do
+ {
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return NULL;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ p = strchr (line, '\n');
+ if (p)
+ *p = 0;
+ p = line + (*line? (strlen (line)-1):0);
+ for ( ;p > line; p--)
+ if (my_isascii (*p) && isspace (*p))
+ *p = 0;
+ }
+ while (!any && !*line);
+ any = 1;
+ }
+ while (*line == '#'); /* Always skip comment lines. */
+ if (verbose > 1)
+ fprintf (stderr, PGM ": received line: %s\n", line);
+ return gcry_xstrdup (line);
+}
+
+
+static gcry_mpi_t
+read_hexmpi_line (FILE *fp, int *got_eof)
+{
+ gpg_error_t err;
+ gcry_mpi_t a;
+ char *line;
+
+ *got_eof = 0;
+ line = read_textline (fp);
+ if (!line)
+ {
+ *got_eof = 1;
+ return NULL;
+ }
+ err = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
+ gcry_free (line);
+ if (err)
+ a = NULL;
+ return a;
+}
+
+
+static int
+skip_to_empty_line (FILE *fp)
+{
+ char line[256];
+ char *p;
+
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return -1;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ p = strchr (line, '\n');
+ if (p)
+ *p =0;
+ }
+ while (*line);
+ return 0;
+}
+
+
+/* Print an MPI on a line. */
+static void
+print_mpi_line (const char *label, gcry_mpi_t a)
+{
+ unsigned char *buf, *p;
+ gcry_error_t err;
+ int writerr = 0;
+
+ if (with_labels && label)
+ printf ("%s = ", label);
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
+ if (err)
+ die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
+
+ p = buf;
+ if (!keep_lz && p[0] == '0' && p[1] == '0' && p[2])
+ p += 2;
+
+ printf ("%s\n", p);
+ if (ferror (stdout))
+ writerr++;
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ die ("writing output failed: %s\n", strerror (errno));
+ gcry_free (buf);
+}
+
+
+/* Compute and print missing RSA parameters. */
+static void
+compute_missing (gcry_mpi_t rsa_p, gcry_mpi_t rsa_q, gcry_mpi_t rsa_e)
+{
+ gcry_mpi_t rsa_n, rsa_d, rsa_pm1, rsa_qm1, rsa_u;
+ gcry_mpi_t phi, tmp_g, tmp_f;
+
+ rsa_n = gcry_mpi_new (0);
+ rsa_d = gcry_mpi_new (0);
+ rsa_pm1 = gcry_mpi_new (0);
+ rsa_qm1 = gcry_mpi_new (0);
+ rsa_u = gcry_mpi_new (0);
+
+ phi = gcry_mpi_new (0);
+ tmp_f = gcry_mpi_new (0);
+ tmp_g = gcry_mpi_new (0);
+
+ /* Check that p < q; if not swap p and q. */
+ if (openpgp_mode && gcry_mpi_cmp (rsa_p, rsa_q) > 0)
+ {
+ fprintf (stderr, PGM ": swapping p and q\n");
+ gcry_mpi_swap (rsa_p, rsa_q);
+ }
+
+ gcry_mpi_mul (rsa_n, rsa_p, rsa_q);
+
+
+ /* Compute the Euler totient: phi = (p-1)(q-1) */
+ gcry_mpi_sub_ui (rsa_pm1, rsa_p, 1);
+ gcry_mpi_sub_ui (rsa_qm1, rsa_q, 1);
+ gcry_mpi_mul (phi, rsa_pm1, rsa_qm1);
+
+ if (!gcry_mpi_gcd (tmp_g, rsa_e, phi))
+ die ("parameter 'e' does match 'p' and 'q'\n");
+
+ /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
+ gcry_mpi_gcd (tmp_g, rsa_pm1, rsa_qm1);
+ gcry_mpi_div (tmp_f, NULL, phi, tmp_g, -1);
+
+ /* Compute the secret key: d = e^{-1} mod lcm(p-1,q-1) */
+ gcry_mpi_invm (rsa_d, rsa_e, tmp_f);
+
+ /* Compute the CRT helpers: d mod (p-1), d mod (q-1) */
+ gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1);
+ gcry_mpi_mod (rsa_qm1, rsa_d, rsa_qm1);
+
+ /* Compute the CRT value: OpenPGP: u = p^{-1} mod q
+ Standard: iqmp = q^{-1} mod p */
+ if (openpgp_mode)
+ gcry_mpi_invm (rsa_u, rsa_p, rsa_q);
+ else
+ gcry_mpi_invm (rsa_u, rsa_q, rsa_p);
+
+ gcry_mpi_release (phi);
+ gcry_mpi_release (tmp_f);
+ gcry_mpi_release (tmp_g);
+
+ /* Print everything. */
+ print_mpi_line ("n", rsa_n);
+ print_mpi_line ("e", rsa_e);
+ if (openpgp_mode)
+ print_mpi_line ("d", rsa_d);
+ print_mpi_line ("p", rsa_p);
+ print_mpi_line ("q", rsa_q);
+ if (openpgp_mode)
+ print_mpi_line ("u", rsa_u);
+ else
+ {
+ print_mpi_line ("dmp1", rsa_pm1);
+ print_mpi_line ("dmq1", rsa_qm1);
+ print_mpi_line ("iqmp", rsa_u);
+ }
+
+ gcry_mpi_release (rsa_n);
+ gcry_mpi_release (rsa_d);
+ gcry_mpi_release (rsa_pm1);
+ gcry_mpi_release (rsa_qm1);
+ gcry_mpi_release (rsa_u);
+}
+
+
+
+static void
+usage (int show_help)
+{
+ if (!show_help)
+ {
+ fputs ("usage: " PGM
+ " [OPTION] [FILE] (try --help for more information)\n", stderr);
+ exit (2);
+ }
+ fputs
+ ("Usage: " PGM " [OPTIONS] [FILE]\n"
+ "Take RSA parameters p, n, e and compute missing parameters.\n"
+ "OPTIONS:\n"
+ " --openpgp Compute as specified by RFC4880\n"
+ " --labels Prefix output with labels\n"
+ " --keep-lz Keep all leading zeroes in the output\n"
+ " --verbose Print additional information\n"
+ " --version Print version information\n"
+ " --help Print this text\n"
+ "With no FILE, or if FILE is -, read standard input.\n"
+ "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
+ exit (0);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ FILE *input;
+ gcry_mpi_t rsa_p, rsa_q, rsa_e;
+ int got_eof;
+ int any = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ usage (1);
+ }
+ else if (!strcmp (*argv, "--version"))
+ {
+ fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
+ printf ("libgcrypt %s\n", gcry_check_version (NULL));
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--labels"))
+ {
+ with_labels = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--keep-lz"))
+ {
+ keep_lz = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--openpgp"))
+ {
+ openpgp_mode = 1;
+ argc--; argv++;
+ }
+ }
+
+ if (argc > 1)
+ usage (0);
+
+#if !defined (HAVE_W32_SYSTEM) && !defined (_WIN32)
+ signal (SIGPIPE, SIG_IGN);
+#endif
+
+ if (argc == 1 && strcmp (argv[0], "-"))
+ {
+ input = fopen (argv[0], "r");
+ if (!input)
+ die ("can't open `%s': %s\n", argv[0], strerror (errno));
+ }
+ else
+ input = stdin;
+
+ xgcry_control ((GCRYCTL_SET_VERBOSITY, (int)verbose));
+ if (!gcry_check_version ("1.4.0"))
+ die ("Libgcrypt is not sufficient enough\n");
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ do
+ {
+ rsa_p = read_hexmpi_line (input, &got_eof);
+ if (!rsa_p && got_eof)
+ break;
+ if (!rsa_p)
+ die ("RSA parameter 'p' missing or not properly hex encoded\n");
+ rsa_q = read_hexmpi_line (input, &got_eof);
+ if (!rsa_q)
+ die ("RSA parameter 'q' missing or not properly hex encoded\n");
+ rsa_e = read_hexmpi_line (input, &got_eof);
+ if (!rsa_e)
+ die ("RSA parameter 'e' missing or not properly hex encoded\n");
+ got_eof = skip_to_empty_line (input);
+
+ if (any)
+ putchar ('\n');
+
+ compute_missing (rsa_p, rsa_q, rsa_e);
+
+ gcry_mpi_release (rsa_p);
+ gcry_mpi_release (rsa_q);
+ gcry_mpi_release (rsa_e);
+
+ any = 1;
+ }
+ while (!got_eof);
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/sha3-224.h b/comm/third_party/libgcrypt/tests/sha3-224.h
new file mode 100644
index 0000000000..46c1b055cc
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/sha3-224.h
@@ -0,0 +1,1025 @@
+/* Generated from https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHA3-224.txt */
+ { 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",
+ 0 },
+ { GCRY_MD_SHA3_224,
+ "\xcc",
+ "\xdf\x70\xad\xc4\x9b\x2e\x76\xee\xe3\xa6\x93\x1b\x93\xfa\x41\x84\x1c\x3a\xf2\xcd\xf5\xb3\x2a\x18\xb5\x47\x8c\x39",
+ 1 },
+ { GCRY_MD_SHA3_224,
+ "\x41\xfb",
+ "\xbf\xf2\x95\x86\x1d\xae\xdf\x33\xe7\x05\x19\xb1\xe2\xbc\xb4\xc2\xe9\xfe\x33\x64\xd7\x89\xbc\x3b\x17\x30\x1c\x15",
+ 2 },
+ { GCRY_MD_SHA3_224,
+ "\x1f\x87\x7c",
+ "\x14\x88\x9d\xf4\x9c\x07\x6a\x9a\xf2\xf4\xbc\xb1\x63\x39\xbc\xc4\x5a\x24\xeb\xf9\xce\x4d\xcd\xce\x7e\xc1\x72\x17",
+ 3 },
+ { GCRY_MD_SHA3_224,
+ "\xc1\xec\xfd\xfc",
+ "\xa3\x3c\x58\xdf\x8a\x80\x26\xf0\xf9\x59\x19\x66\xbd\x6d\x00\xee\xd3\xb1\xe8\x29\x58\x0a\xb9\xbe\x26\x8c\xaf\x39",
+ 4 },
+ { GCRY_MD_SHA3_224,
+ "\x21\xf1\x34\xac\x57",
+ "\x10\xe5\x80\xa3\x21\x99\x59\x61\x69\x33\x1a\xd4\x3c\xfc\xf1\x02\x64\xf8\x15\x65\x03\x70\x40\x02\x8a\x06\xb4\x58",
+ 5 },
+ { GCRY_MD_SHA3_224,
+ "\xc6\xf5\x0b\xb7\x4e\x29",
+ "\xfe\x52\xc3\x0c\x95\xc1\xe5\x19\x32\x07\xe9\x7d\x35\x5f\xde\x09\x45\x34\x82\x70\x8c\x08\x76\xaa\x96\x15\x08\xf0",
+ 6 },
+ { GCRY_MD_SHA3_224,
+ "\x11\x97\x13\xcc\x83\xee\xef",
+ "\x8b\x44\x98\x49\xcb\x7c\x47\x76\xc5\x93\xde\x58\xfd\x5c\x2e\x32\x2c\xb5\x31\x6b\xe0\x8a\x75\x05\x7a\x01\xed\x6a",
+ 7 },
+ { GCRY_MD_SHA3_224,
+ "\x4a\x4f\x20\x24\x84\x51\x25\x26",
+ "\x01\x38\x6c\xdd\x70\x58\x9b\x3b\x34\x94\x1e\xfe\x16\xb8\x50\x71\xe9\xba\x94\x81\x79\x92\x20\x44\xf6\x40\x86\x8e",
+ 8 },
+ { GCRY_MD_SHA3_224,
+ "\x1f\x66\xab\x41\x85\xed\x9b\x63\x75",
+ "\x86\x95\x3d\x08\x64\x01\x9c\x81\xfd\x3a\x80\x53\x57\xa1\x62\xfd\x76\xa1\x3a\x7c\xbf\x6f\xf0\xd6\x35\x01\x5d\x0e",
+ 9 },
+ { GCRY_MD_SHA3_224,
+ "\xee\xd7\x42\x22\x27\x61\x3b\x6f\x53\xc9",
+ "\xe5\x6f\xc2\xa5\xa5\x87\x09\x03\x1d\xf0\x2a\x2e\x46\xad\x95\xf9\x35\x83\xe2\x74\x56\x30\x54\x0d\x8d\x97\xf7\x03",
+ 10 },
+ { GCRY_MD_SHA3_224,
+ "\xea\xee\xd5\xcd\xff\xd8\x9d\xec\xe4\x55\xf1",
+ "\x1d\x78\x3c\x37\xc3\x2a\x2b\x71\xb5\x04\xbc\xaa\x05\xfc\x00\xb6\x39\xf1\xfa\xe7\xe8\xd8\xe3\xf3\xbc\x49\xf0\x41",
+ 11 },
+ { GCRY_MD_SHA3_224,
+ "\x5b\xe4\x3c\x90\xf2\x29\x02\xe4\xfe\x8e\xd2\xd3",
+ "\x54\xc7\xe4\xbf\x3c\x73\xe1\x92\xad\xe2\x23\xdf\xea\x86\xf2\xd0\x4a\xcf\x95\x36\x12\x73\x19\x58\xf8\x54\xc7\xbd",
+ 12 },
+ { GCRY_MD_SHA3_224,
+ "\xa7\x46\x27\x32\x28\x12\x2f\x38\x1c\x3b\x46\xe4\xf1",
+ "\x77\xe5\x1c\xea\xda\x2a\xa1\xcb\xbf\x95\xac\xd8\x21\x00\x8b\x57\xe9\x46\xf7\x94\x02\x23\xb1\x9f\x0c\x53\xe6\x2e",
+ 13 },
+ { GCRY_MD_SHA3_224,
+ "\x3c\x58\x71\xcd\x61\x9c\x69\xa6\x3b\x54\x0e\xb5\xa6\x25",
+ "\x9e\xd5\x9e\xd1\x55\xe9\x71\x54\xe0\x67\xfa\x0f\x5a\x13\x08\x39\xb5\x7b\xdb\xda\x6f\xeb\x82\xda\xbe\x00\x6f\x00",
+ 14 },
+ { GCRY_MD_SHA3_224,
+ "\xfa\x22\x87\x4b\xcc\x06\x88\x79\xe8\xef\x11\xa6\x9f\x07\x22",
+ "\x81\xb3\xe5\x6c\xfe\xee\x8e\x91\x38\xd3\xbf\xe2\x4b\xb7\xcc\xdf\xd4\xb5\x0d\x0b\x8c\xa1\x1a\xe7\xd4\xb0\xc9\x60",
+ 15 },
+ { GCRY_MD_SHA3_224,
+ "\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76",
+ "\xb1\x57\x1b\xed\x52\xe5\x4e\xef\x37\x7d\x99\xdf\x7b\xe4\xbc\x66\x82\xc4\x33\x87\xf2\xbf\x9a\xcc\x92\xdf\x60\x8f",
+ 16 },
+ { GCRY_MD_SHA3_224,
+ "\x82\xe1\x92\xe4\x04\x3d\xdc\xd1\x2e\xcf\x52\x96\x9d\x0f\x80\x7e\xed",
+ "\x08\x04\x5c\xf7\x8d\x23\x8d\x56\x97\x2f\x1c\x85\x04\x14\xbc\x40\x4f\xc6\xdc\xb1\x1f\x8d\x82\x10\xd0\x34\xc6\x10",
+ 17 },
+ { GCRY_MD_SHA3_224,
+ "\x75\x68\x3d\xcb\x55\x61\x40\xc5\x22\x54\x3b\xb6\xe9\x09\x8b\x21\xa2\x1e",
+ "\x9f\xfd\x84\x0c\x55\x0a\xd2\x39\x71\xeb\x5c\xe8\x9a\xe2\xfd\x62\x22\xab\xfb\x7f\x0a\xaf\xd7\xeb\x00\x05\x71\x6b",
+ 18 },
+ { GCRY_MD_SHA3_224,
+ "\x06\xe4\xef\xe4\x50\x35\xe6\x1f\xaa\xf4\x28\x7b\x4d\x8d\x1f\x12\xca\x97\xe5",
+ "\x72\xde\xcb\x5e\xa1\xb2\x5a\x2d\xaa\xeb\x23\x4a\x8d\x96\xe0\xf5\x72\x11\x42\x66\x66\xa2\xee\x76\xb2\x38\x5c\x62",
+ 19 },
+ { GCRY_MD_SHA3_224,
+ "\xe2\x61\x93\x98\x9d\x06\x56\x8f\xe6\x88\xe7\x55\x40\xae\xa0\x67\x47\xd9\xf8\x51",
+ "\xa5\x89\x93\x63\x70\xa3\xd2\x00\x39\xc4\x69\xd4\x4a\x1c\x26\xe6\x28\x23\xab\x28\xcc\x50\x17\x5a\x98\x97\xf9\x8e",
+ 20 },
+ { GCRY_MD_SHA3_224,
+ "\xd8\xdc\x8f\xde\xfb\xdc\xe9\xd4\x4e\x4c\xba\xfe\x78\x44\x7b\xae\x3b\x54\x36\x10\x2a",
+ "\x96\xf4\x34\x01\xad\x49\xc5\x8d\x88\x70\x20\xf3\x95\xbd\xd0\x1f\x6d\xad\x04\x12\x8a\x85\xb1\x77\x80\x40\x8c\x37",
+ 21 },
+ { GCRY_MD_SHA3_224,
+ "\x57\x08\x5f\xd7\xe1\x42\x16\xab\x10\x2d\x83\x17\xb0\xcb\x33\x8a\x78\x6d\x5f\xc3\x2d\x8f",
+ "\xa3\xa0\xf0\xc5\x52\xe7\xcd\x27\x23\xfe\x22\xe1\xd5\x71\x9e\x21\x3d\x9a\x3d\xa1\xdb\x99\xe3\x2e\xff\xfd\x0f\x46",
+ 22 },
+ { GCRY_MD_SHA3_224,
+ "\xa0\x54\x04\xdf\x5d\xbb\x57\x69\x7e\x2c\x16\xfa\x29\xde\xfa\xc8\xab\x35\x60\xd6\x12\x6f\xa0",
+ "\xe9\x91\xf4\xa1\x4b\x56\xdc\x6b\x22\x4e\xf3\x52\xae\x8b\xc8\xca\xe8\xb1\xaf\x1c\x25\xc6\x73\x3d\xfb\x7f\xfe\x1f",
+ 23 },
+ { GCRY_MD_SHA3_224,
+ "\xae\xcb\xb0\x27\x59\xf7\x43\x3d\x6f\xcb\x06\x96\x3c\x74\x06\x1c\xd8\x3b\x5b\x3f\xfa\x6f\x13\xc6",
+ "\x71\x88\x66\xc2\x1c\xbe\x3f\x29\x13\x64\xc0\x7b\x36\x07\x8a\x6b\xf0\xb8\x25\x8b\x0e\xc1\x55\xe2\xe2\xb1\xaf\x23",
+ 24 },
+ { GCRY_MD_SHA3_224,
+ "\xaa\xfd\xc9\x24\x3d\x3d\x4a\x09\x65\x58\xa3\x60\xcc\x27\xc8\xd8\x62\xf0\xbe\x73\xdb\x5e\x88\xaa\x55",
+ "\x23\x60\x6d\x06\xfd\x8f\x87\xc2\x20\x5a\xbb\x5f\xd0\x4c\x33\xeb\xa3\x05\x09\x95\x52\x00\x56\x6a\x0f\x77\x2b\x49",
+ 25 },
+ { GCRY_MD_SHA3_224,
+ "\x7b\xc8\x48\x67\xf6\xf9\xe9\xfd\xc3\xe1\x04\x6c\xae\x3a\x52\xc7\x7e\xd4\x85\x86\x0e\xe2\x60\xe3\x0b\x15",
+ "\x05\x93\x5f\x0a\xd2\x26\x44\x75\xdf\x34\xfa\x96\xf6\xa9\x11\x8c\x32\xb2\x17\xe8\x61\x69\xeb\x7a\xde\x4e\x2f\xdb",
+ 26 },
+ { GCRY_MD_SHA3_224,
+ "\xfa\xc5\x23\x57\x5a\x99\xec\x48\x27\x9a\x7a\x45\x9e\x98\xff\x90\x19\x18\xa4\x75\x03\x43\x27\xef\xb5\x58\x43",
+ "\xfb\xec\x83\xcb\xdb\x6d\x08\xc7\xbf\xdd\xc2\xe3\x7f\x73\xb1\x6d\xc9\x29\x26\xa5\xc2\x3d\xab\x41\xde\xeb\xfb\x1b",
+ 27 },
+ { GCRY_MD_SHA3_224,
+ "\x0f\x8b\x2d\x8f\xcf\xd9\xd6\x8c\xff\xc1\x7c\xcf\xb1\x17\x70\x9b\x53\xd2\x64\x62\xa3\xf3\x46\xfb\x7c\x79\xb8\x5e",
+ "\x1e\x69\x3b\x0b\xce\x23\x72\x55\x0d\xae\xf3\x5b\x14\xf1\x3a\xb4\x34\x41\xed\x67\x42\xde\xe3\xe8\x6f\xd1\xd8\xef",
+ 28 },
+ { GCRY_MD_SHA3_224,
+ "\xa9\x63\xc3\xe8\x95\xff\x5a\x0b\xe4\x82\x44\x00\x51\x8d\x81\x41\x2f\x87\x5f\xa5\x05\x21\xe2\x6e\x85\xea\xc9\x0c\x04",
+ "\x17\x81\xf1\x34\x4d\xc1\x7f\x67\x85\x71\xf4\xe5\xdf\x39\x98\xb1\xd3\x8b\x1d\x83\x60\x2b\x53\xb9\xb6\xf2\x83\xd6",
+ 29 },
+ { GCRY_MD_SHA3_224,
+ "\x03\xa1\x86\x88\xb1\x0c\xc0\xed\xf8\x3a\xdf\x0a\x84\x80\x8a\x97\x18\x38\x3c\x40\x70\xc6\xc4\xf2\x95\x09\x86\x99\xac\x2c",
+ "\x03\xb7\x4b\x7d\x8f\xc1\xf2\x3f\x76\xba\xb2\xb6\xc3\x5f\x29\x2c\x15\x50\x6d\xe6\x49\x78\xfc\xf6\xd9\x97\x3f\xce",
+ 30 },
+ { GCRY_MD_SHA3_224,
+ "\x84\xfb\x51\xb5\x17\xdf\x6c\x5a\xcc\xb5\xd0\x22\xf8\xf2\x8d\xa0\x9b\x10\x23\x2d\x42\x32\x0f\xfc\x32\xdb\xec\xc3\x83\x5b\x29",
+ "\x6a\x68\x57\xfb\xa9\x03\xb9\xda\x27\x53\x69\x0c\x39\xc5\x48\xbe\x00\x8e\x22\xeb\xb3\x72\xee\xaa\x16\xc8\x59\x18",
+ 31 },
+ { GCRY_MD_SHA3_224,
+ "\x9f\x2f\xcc\x7c\x90\xde\x09\x0d\x6b\x87\xcd\x7e\x97\x18\xc1\xea\x6c\xb2\x11\x18\xfc\x2d\x5d\xe9\xf9\x7e\x5d\xb6\xac\x1e\x9c\x10",
+ "\x88\x79\x21\x84\x8a\xd9\x84\x58\xf3\xdb\x3e\x0e\xcd\x5a\xd5\xdb\x1f\x0b\xf9\xf2\xd0\xca\x08\x60\x10\x74\xd5\x97",
+ 32 },
+ { GCRY_MD_SHA3_224,
+ "\xde\x8f\x1b\x3f\xaa\x4b\x70\x40\xed\x45\x63\xc3\xb8\xe5\x98\x25\x31\x78\xe8\x7e\x4d\x0d\xf7\x5e\x4f\xf2\xf2\xde\xdd\x5a\x0b\xe0\x46",
+ "\xe0\x57\x3a\xd7\x06\xb4\x4d\x8c\x4d\x20\x4f\x88\x4b\x95\xab\x18\x91\x3e\x76\xf4\x1c\xf2\x9a\x16\xdb\xe3\x47\x94",
+ 33 },
+ { GCRY_MD_SHA3_224,
+ "\x62\xf1\x54\xec\x39\x4d\x0b\xc7\x57\xd0\x45\xc7\x98\xc8\xb8\x7a\x00\xe0\x65\x5d\x04\x81\xa7\xd2\xd9\xfb\x58\xd9\x3a\xed\xc6\x76\xb5\xa0",
+ "\xba\x31\x23\x30\x99\x05\x54\x83\xc9\x9f\x7a\xd8\x2d\x0d\x24\xaf\x48\x7e\xd4\xb5\x3f\xff\x1a\x89\x2a\x55\xdd\xb3",
+ 34 },
+ { GCRY_MD_SHA3_224,
+ "\xb2\xdc\xfe\x9f\xf1\x9e\x2b\x23\xce\x7d\xa2\xa4\x20\x7d\x3e\x5e\xc7\xc6\x11\x2a\x8a\x22\xae\xc9\x67\x5a\x88\x63\x78\xe1\x4e\x5b\xfb\xad\x4e",
+ "\xbe\xfa\xa1\xcb\x47\xcf\x78\xdd\xd4\xe0\x96\xb8\x61\xbc\x34\x0b\x77\x6f\x52\xe3\x51\xeb\xe3\x78\xad\xe3\x05\xba",
+ 35 },
+ { GCRY_MD_SHA3_224,
+ "\x47\xf5\x69\x7a\xc8\xc3\x14\x09\xc0\x86\x88\x27\x34\x7a\x61\x3a\x35\x62\x04\x1c\x63\x3c\xf1\xf1\xf8\x68\x65\xa5\x76\xe0\x28\x35\xed\x2c\x24\x92",
+ "\xf1\xe7\xa1\xb2\x8e\xa4\xd6\xfb\x86\x57\x0f\x66\x91\x1e\x32\x58\xc3\xf4\x9f\x89\x16\x54\xfb\xce\x9b\xc7\x9b\x8b",
+ 36 },
+ { GCRY_MD_SHA3_224,
+ "\x51\x2a\x6d\x29\x2e\x67\xec\xb2\xfe\x48\x6b\xfe\x92\x66\x09\x53\xa7\x54\x84\xff\x4c\x4f\x2e\xca\x2b\x0a\xf0\xed\xcd\xd4\x33\x9c\x6b\x2e\xe4\xe5\x42",
+ "\xc2\xb3\x17\x46\x44\x69\x34\xfe\x29\xe8\x4c\xfb\x5c\x25\xb0\x3b\xe3\x3e\x90\x04\xf7\x4e\x91\xc1\xaf\x0d\xb7\x89",
+ 37 },
+ { GCRY_MD_SHA3_224,
+ "\x97\x3c\xf2\xb4\xdc\xf0\xbf\xa8\x72\xb4\x11\x94\xcb\x05\xbb\x4e\x16\x76\x0a\x18\x40\xd8\x34\x33\x01\x80\x25\x76\x19\x7e\xc1\x9e\x2a\x14\x93\xd8\xf4\xfb",
+ "\x3a\x80\x64\x5f\xe4\x27\x13\x46\xaa\xed\xc3\xae\x50\x11\xb7\x5d\xf1\x63\xfa\xd3\xee\x61\x28\xd8\x7f\x3d\x9d\xa3",
+ 38 },
+ { GCRY_MD_SHA3_224,
+ "\x80\xbe\xeb\xcd\x2e\x3f\x8a\x94\x51\xd4\x49\x99\x61\xc9\x73\x1a\xe6\x67\xcd\xc2\x4e\xa0\x20\xce\x3b\x9a\xa4\xbb\xc0\xa7\xf7\x9e\x30\xa9\x34\x46\x7d\xa4\xb0",
+ "\x3c\x5e\xbe\x43\xa2\x57\x1b\xce\xf2\x5e\x4e\xa6\x7a\x4c\xa9\x83\x87\x70\xd2\x35\x99\x05\x99\x55\xaf\x93\xff\x83",
+ 39 },
+ { GCRY_MD_SHA3_224,
+ "\x7a\xba\xa1\x2e\xc2\xa7\x34\x76\x74\xe4\x44\x14\x0a\xe0\xfb\x65\x9d\x08\xe1\xc6\x6d\xec\xd8\xd6\xea\xe9\x25\xfa\x45\x1d\x65\xf3\xc0\x30\x8e\x29\x44\x6b\x8e\xd3",
+ "\xaf\x71\xda\xb0\xf3\x3d\x3b\x48\x73\x3a\xd6\x33\x5c\xa6\x09\x39\x8d\x89\x4e\x6f\xa9\x6f\x55\x10\xae\x73\xe5\xd2",
+ 40 },
+ { GCRY_MD_SHA3_224,
+ "\xc8\x8d\xee\x99\x27\x67\x9b\x8a\xf4\x22\xab\xcb\xac\xf2\x83\xb9\x04\xff\x31\xe1\xca\xc5\x8c\x78\x19\x80\x9f\x65\xd5\x80\x7d\x46\x72\x3b\x20\xf6\x7b\xa6\x10\xc2\xb7",
+ "\xdd\x75\x12\xda\xa0\xc6\x34\xcc\x15\x88\x87\x0b\x84\x69\x1d\x7d\xe2\xc1\x82\xe5\x57\x0d\x57\x86\x8e\x7d\xda\x5d",
+ 41 },
+ { GCRY_MD_SHA3_224,
+ "\x01\xe4\x3f\xe3\x50\xfc\xec\x45\x0e\xc9\xb1\x02\x05\x3e\x6b\x5d\x56\xe0\x98\x96\xe0\xdd\xd9\x07\x4f\xe1\x38\xe6\x03\x82\x10\x27\x0c\x83\x4c\xe6\xea\xdc\x2b\xb8\x6b\xf6",
+ "\x6c\xb4\xf9\x29\x2b\xa3\x3c\xa8\xd2\x93\xb7\xa7\xef\x76\x61\x9e\x77\x30\x9b\xa2\x17\x8c\xd4\xa1\x30\xbf\x92\x18",
+ 42 },
+ { GCRY_MD_SHA3_224,
+ "\x33\x70\x23\x37\x0a\x48\xb6\x2e\xe4\x35\x46\xf1\x7c\x4e\xf2\xbf\x8d\x7e\xcd\x1d\x49\xf9\x0b\xab\x60\x4b\x83\x9c\x2e\x6e\x5b\xd2\x15\x40\xd2\x9b\xa2\x7a\xb8\xe3\x09\xa4\xb7",
+ "\xa9\xb8\x43\x5e\x55\xfc\x50\xfe\x93\x5e\xc9\x67\x98\xa6\x29\xc1\x3e\x85\x6c\x3c\x5c\xfd\x24\x81\x26\x97\x6e\x0d",
+ 43 },
+ { GCRY_MD_SHA3_224,
+ "\x68\x92\x54\x0f\x96\x4c\x8c\x74\xbd\x2d\xb0\x2c\x0a\xd8\x84\x51\x0c\xb3\x8a\xfd\x44\x38\xaf\x31\xfc\x91\x27\x56\xf3\xef\xec\x6b\x32\xb5\x8e\xbc\x38\xfc\x2a\x6b\x91\x35\x96\xa8",
+ "\x93\xe7\x98\x50\x62\x2b\x91\xf7\x29\xab\x05\x6e\xa4\x02\xe2\x7f\x01\xb5\x32\x31\x58\x11\x1b\x29\x36\x2a\x96\xd5",
+ 44 },
+ { GCRY_MD_SHA3_224,
+ "\xf5\x96\x1d\xfd\x2b\x1f\xff\xfd\xa4\xff\xbf\x30\x56\x0c\x16\x5b\xfe\xda\xb8\xce\x0b\xe5\x25\x84\x5d\xeb\x8d\xc6\x10\x04\xb7\xdb\x38\x46\x72\x05\xf5\xdc\xfb\x34\xa2\xac\xfe\x96\xc0",
+ "\x7e\x51\xd5\x53\x13\x82\x49\x06\x70\x11\x5d\xe1\x31\x37\xcb\x3a\xdb\x6e\x76\x21\xb7\xd9\xec\xa8\x17\x0f\xaa\x96",
+ 45 },
+ { GCRY_MD_SHA3_224,
+ "\xca\x06\x1a\x2e\xb6\xce\xed\x88\x81\xce\x20\x57\x17\x2d\x86\x9d\x73\xa1\x95\x1e\x63\xd5\x72\x61\x38\x4b\x80\xce\xb5\x45\x1e\x77\xb0\x6c\xf0\xf5\xa0\xea\x15\xca\x90\x7e\xe1\xc2\x7e\xba",
+ "\x95\xc3\x50\x37\xa8\x07\x69\x26\xfc\x5c\x42\x1c\x35\x16\x0a\xc5\xfe\x53\x3a\x27\x82\xf2\x0f\x2d\x3f\x4b\x1b\x7d",
+ 46 },
+ { GCRY_MD_SHA3_224,
+ "\x17\x43\xa7\x72\x51\xd6\x92\x42\x75\x0c\x4f\x11\x40\x53\x2c\xd3\xc3\x3f\x9b\x5c\xcd\xf7\x51\x4e\x85\x84\xd4\xa5\xf9\xfb\xd7\x30\xbc\xf8\x4d\x0d\x47\x26\x36\x4b\x9b\xf9\x5a\xb2\x51\xd9\xbb",
+ "\xbf\x02\x4a\x4f\xe4\x80\x63\x61\x18\xfc\xc8\x5b\x80\x77\x04\xd5\x9b\x64\xd1\x6a\x15\x0a\xa5\x3c\xde\x41\xf0\x30",
+ 47 },
+ { GCRY_MD_SHA3_224,
+ "\xd8\xfa\xba\x1f\x51\x94\xc4\xdb\x5f\x17\x6f\xab\xff\xf8\x56\x92\x4e\xf6\x27\xa3\x7c\xd0\x8c\xf5\x56\x08\xbb\xa8\xf1\xe3\x24\xd7\xc7\xf1\x57\x29\x8e\xab\xc4\xdc\xe7\xd8\x9c\xe5\x16\x24\x99\xf9",
+ "\xb7\xa5\x1f\xbb\x08\x4d\xee\xb5\x51\x36\xef\xd7\x26\x0e\x5b\x11\x2e\x3c\x40\xd1\xa2\xd1\x4b\x14\x2d\xf9\x30\xdf",
+ 48 },
+ { GCRY_MD_SHA3_224,
+ "\xbe\x96\x84\xbe\x70\x34\x08\x60\x37\x3c\x9c\x48\x2b\xa5\x17\xe8\x99\xfc\x81\xba\xaa\x12\xe5\xc6\xd7\x72\x79\x75\xd1\xd4\x1b\xa8\xbe\xf7\x88\xcd\xb5\xcf\x46\x06\xc9\xc1\xc7\xf6\x1a\xed\x59\xf9\x7d",
+ "\x61\xcf\x83\x0a\x2c\x4f\x8f\x48\xbc\x64\x3f\x97\xa2\x5f\x82\x2c\x01\x3f\x73\xbd\xf4\xcb\x41\x94\xbc\x8d\x55\xdf",
+ 49 },
+ { GCRY_MD_SHA3_224,
+ "\x7e\x15\xd2\xb9\xea\x74\xca\x60\xf6\x6c\x8d\xfa\xb3\x77\xd9\x19\x8b\x7b\x16\xde\xb6\xa1\xba\x0e\xa3\xc7\xee\x20\x42\xf8\x9d\x37\x86\xe7\x79\xcf\x05\x3c\x77\x78\x5a\xa9\xe6\x92\xf8\x21\xf1\x4a\x7f\x51",
+ "\xd8\x7f\x62\xea\x81\x1a\x2f\x6b\xf3\xc5\xfd\xe1\x34\x75\xb9\xc6\x76\x62\x0c\x01\x84\xf8\x71\x49\xdc\x86\x86\xc8",
+ 50 },
+ { GCRY_MD_SHA3_224,
+ "\x9a\x21\x9b\xe4\x37\x13\xbd\x57\x80\x15\xe9\xfd\xa6\x6c\x0f\x2d\x83\xca\xc5\x63\xb7\x76\xab\x9f\x38\xf3\xe4\xf7\xef\x22\x9c\xb4\x43\x30\x4f\xba\x40\x1e\xfb\x2b\xdb\xd7\xec\xe9\x39\x10\x22\x98\x65\x1c\x86",
+ "\x02\x8a\x63\x9c\x7e\xc0\xba\x1d\xce\xc0\xb6\x89\xaa\x26\xe2\xc0\x16\x76\x22\x46\x26\x69\xa5\xc5\x20\x31\x60\x2b",
+ 51 },
+ { GCRY_MD_SHA3_224,
+ "\xc8\xf2\xb6\x93\xbd\x0d\x75\xef\x99\xca\xeb\xdc\x22\xad\xf4\x08\x8a\x95\xa3\x54\x2f\x63\x72\x03\xe2\x83\xbb\xc3\x26\x87\x80\xe7\x87\xd6\x8d\x28\xcc\x38\x97\x45\x2f\x6a\x22\xaa\x85\x73\xcc\xeb\xf2\x45\x97\x2a",
+ "\x90\x8e\xf2\x8a\xb2\xb6\xcb\xb4\x49\xb9\xaf\x7f\xa7\x8b\x3d\x90\xe0\x19\xc3\x91\x65\x62\xeb\x48\x19\xa0\xc8\x7f",
+ 52 },
+ { GCRY_MD_SHA3_224,
+ "\xec\x0f\x99\x71\x10\x16\xc6\xa2\xa0\x7a\xd8\x0d\x16\x42\x75\x06\xce\x6f\x44\x10\x59\xfd\x26\x94\x42\xba\xaa\x28\xc6\xca\x03\x7b\x22\xee\xac\x49\xd5\xd8\x94\xc0\xbf\x66\x21\x9f\x2c\x08\xe9\xd0\xe8\xab\x21\xde\x52",
+ "\x6a\xc8\x41\x49\xf8\x90\xe1\x35\x2c\x6d\x73\x97\xda\xc3\xb3\x77\x39\x47\xb3\x75\x7e\x8e\xd4\xec\x05\x9e\xf8\x99",
+ 53 },
+ { GCRY_MD_SHA3_224,
+ "\x0d\xc4\x51\x81\x33\x7c\xa3\x2a\x82\x22\xfe\x7a\x3b\xf4\x2f\xc9\xf8\x97\x44\x25\x9c\xff\x65\x35\x04\xd6\x05\x1f\xe8\x4b\x1a\x7f\xfd\x20\xcb\x47\xd4\x69\x6c\xe2\x12\xa6\x86\xbb\x9b\xe9\xa8\xab\x1c\x69\x7b\x6d\x6a\x33",
+ "\x45\xda\x27\x71\x5c\xd7\x5f\x58\x75\xbe\xb7\xd9\x14\xcf\x74\x88\x24\x0d\x1b\x1f\x97\x5d\x43\x0d\x2f\x49\xe9\xbf",
+ 54 },
+ { GCRY_MD_SHA3_224,
+ "\xde\x28\x6b\xa4\x20\x6e\x8b\x00\x57\x14\xf8\x0f\xb1\xcd\xfa\xeb\xde\x91\xd2\x9f\x84\x60\x3e\x4a\x3e\xbc\x04\x68\x6f\x99\xa4\x6c\x9e\x88\x0b\x96\xc5\x74\x82\x55\x82\xe8\x81\x2a\x26\xe5\xa8\x57\xff\xc6\x57\x9f\x63\x74\x2f",
+ "\x63\xaf\xba\xbb\xec\x07\x21\x40\xdf\xce\xfe\x64\xcf\x7b\xc9\x53\x4d\xca\x10\x95\x60\x42\xe3\x1d\xbe\x58\xd0\xa5",
+ 55 },
+ { GCRY_MD_SHA3_224,
+ "\xee\xbc\xc1\x80\x57\x25\x2c\xbf\x3f\x9c\x07\x0f\x1a\x73\x21\x33\x56\xd5\xd4\xbc\x19\xac\x2a\x41\x1e\xc8\xcd\xee\xe7\xa5\x71\xe2\xe2\x0e\xaf\x61\xfd\x0c\x33\xa0\xff\xeb\x29\x7d\xdb\x77\xa9\x7f\x0a\x41\x53\x47\xdb\x66\xbc\xaf",
+ "\x64\x87\x19\x3d\x9c\xbe\x59\x3b\x3d\xaa\x50\xd4\xdf\xdf\x7d\xd2\x61\x23\x00\xbb\x93\xcb\x39\xe3\xee\xfa\x1a\xfa",
+ 56 },
+ { GCRY_MD_SHA3_224,
+ "\x41\x6b\x5c\xdc\x9f\xe9\x51\xbd\x36\x1b\xd7\xab\xfc\x12\x0a\x50\x54\x75\x8e\xba\x88\xfd\xd6\x8f\xd8\x4e\x39\xd3\xb0\x9a\xc2\x54\x97\xd3\x6b\x43\xcb\xe7\xb8\x5a\x6a\x3c\xeb\xda\x8d\xb4\xe5\x54\x9c\x3e\xe5\x1b\xb6\xfc\xb6\xac\x1e",
+ "\x0d\xec\x25\xbe\x32\x77\xe2\x7d\x4f\x78\x4a\xd5\xff\x8f\x79\xd6\x1d\x9a\x30\x9b\xd6\x93\x51\x3a\xcb\xee\xd1\x2f",
+ 57 },
+ { GCRY_MD_SHA3_224,
+ "\x5c\x5f\xaf\x66\xf3\x2e\x0f\x83\x11\xc3\x2e\x8d\xa8\x28\x4a\x4e\xd6\x08\x91\xa5\xa7\xe5\x0f\xb2\x95\x6b\x3c\xba\xa7\x9f\xc6\x6c\xa3\x76\x46\x0e\x10\x04\x15\x40\x1f\xc2\xb8\x51\x8c\x64\x50\x2f\x18\x7e\xa1\x4b\xfc\x95\x03\x75\x97\x05",
+ "\x13\x0b\x67\xc6\xd1\xa5\x61\x62\x27\xab\xd7\x3a\xbf\x6f\xeb\x70\xfc\xe1\xd5\xa4\xbf\x33\x38\xc6\xdc\xcb\x39\xd5",
+ 58 },
+ { GCRY_MD_SHA3_224,
+ "\x71\x67\xe1\xe0\x2b\xe1\xa7\xca\x69\xd7\x88\x66\x6f\x82\x3a\xe4\xee\xf3\x92\x71\xf3\xc2\x6a\x5c\xf7\xce\xe0\x5b\xca\x83\x16\x10\x66\xdc\x2e\x21\x7b\x33\x0d\xf8\x21\x10\x37\x99\xdf\x6d\x74\x81\x0e\xed\x36\x3a\xdc\x4a\xb9\x9f\x36\x04\x6a",
+ "\x3a\xbb\x5a\xcb\x84\x85\xe2\x0b\xb6\x20\xd4\xa0\x30\xb9\xc2\x5d\x31\x56\xa9\xb2\x68\x93\xae\x00\x7c\x79\xf3\x05",
+ 59 },
+ { GCRY_MD_SHA3_224,
+ "\x2f\xda\x31\x1d\xbb\xa2\x73\x21\xc5\x32\x95\x10\xfa\xe6\x94\x8f\x03\x21\x0b\x76\xd4\x3e\x74\x48\xd1\x68\x9a\x06\x38\x77\xb6\xd1\x4c\x4f\x6d\x0e\xaa\x96\xc1\x50\x05\x13\x71\xf7\xdd\x8a\x41\x19\xf7\xda\x5c\x48\x3c\xc3\xe6\x72\x3c\x01\xfb\x7d",
+ "\x92\x2e\x21\x65\x29\xa9\x53\x05\x30\x7e\x90\x8c\x69\x36\x7e\xbb\x9a\xd9\x31\xec\xa3\x14\x56\x3a\xc3\x6a\xab\x80",
+ 60 },
+ { GCRY_MD_SHA3_224,
+ "\x95\xd1\x47\x4a\x5a\xab\x5d\x24\x22\xac\xa6\xe4\x81\x18\x78\x33\xa6\x21\x2b\xd2\xd0\xf9\x14\x51\xa6\x7d\xd7\x86\xdf\xc9\x1d\xfe\xd5\x1b\x35\xf4\x7e\x1d\xeb\x8a\x8a\xb4\xb9\xcb\x67\xb7\x01\x79\xcc\x26\xf5\x53\xae\x7b\x56\x99\x69\xce\x15\x1b\x8d",
+ "\xc7\x2e\x93\xa2\xc3\x9a\xbc\xd9\x0a\xb1\x1c\xd3\xf1\x5d\x59\xda\x3c\x23\xc0\xf1\x7c\x4e\x26\xc9\xc5\x89\x08\x87",
+ 61 },
+ { GCRY_MD_SHA3_224,
+ "\xc7\x1b\xd7\x94\x1f\x41\xdf\x04\x4a\x29\x27\xa8\xff\x55\xb4\xb4\x67\xc3\x3d\x08\x9f\x09\x88\xaa\x25\x3d\x29\x4a\xdd\xbd\xb3\x25\x30\xc0\xd4\x20\x8b\x10\xd9\x95\x98\x23\xf0\xc0\xf0\x73\x46\x84\x00\x6d\xf7\x9f\x70\x99\x87\x0f\x6b\xf5\x32\x11\xa8\x8d",
+ "\xcc\xcc\x3b\x59\xf2\x8c\x3f\xc4\x62\xdc\x0a\x69\x61\x50\xf5\xae\xa6\x2d\xa0\xab\xa9\x7c\x47\x6b\xd0\xd8\x66\xc1",
+ 62 },
+ { GCRY_MD_SHA3_224,
+ "\xf5\x7c\x64\x00\x6d\x9e\xa7\x61\x89\x2e\x14\x5c\x99\xdf\x1b\x24\x64\x08\x83\xda\x79\xd9\xed\x52\x62\x85\x9d\xcd\xa8\xc3\xc3\x2e\x05\xb0\x3d\x98\x4f\x1a\xb4\xa2\x30\x24\x2a\xb6\xb7\x8d\x36\x8d\xc5\xaa\xa1\xe6\xd3\x49\x8d\x53\x37\x1e\x84\xb0\xc1\xd4\xba",
+ "\x28\xcf\xd0\xc6\xf0\x20\x8d\x24\xaa\xa6\x9e\x6c\x39\xf5\x25\x7c\x13\x30\x3e\x91\xc2\xd6\x83\xa9\xaf\x29\xb9\x73",
+ 63 },
+ { GCRY_MD_SHA3_224,
+ "\xe9\x26\xae\x8b\x0a\xf6\xe5\x31\x76\xdb\xff\xcc\x2a\x6b\x88\xc6\xbd\x76\x5f\x93\x9d\x3d\x17\x8a\x9b\xde\x9e\xf3\xaa\x13\x1c\x61\xe3\x1c\x1e\x42\xcd\xfa\xf4\xb4\xdc\xde\x57\x9a\x37\xe1\x50\xef\xbe\xf5\x55\x5b\x4c\x1c\xb4\x04\x39\xd8\x35\xa7\x24\xe2\xfa\xe7",
+ "\xc1\x54\x60\x7f\x98\x6f\x9b\xf9\x02\xd8\x31\x29\x3c\x83\x86\xd3\x6b\x20\x1e\xab\xa6\xf6\xfb\x0b\x67\x8b\x4b\x81",
+ 64 },
+ { GCRY_MD_SHA3_224,
+ "\x16\xe8\xb3\xd8\xf9\x88\xe9\xbb\x04\xde\x9c\x96\xf2\x62\x78\x11\xc9\x73\xce\x4a\x52\x96\xb4\x77\x2c\xa3\xee\xfe\xb8\x0a\x65\x2b\xdf\x21\xf5\x0d\xf7\x9f\x32\xdb\x23\xf9\xf7\x3d\x39\x3b\x2d\x57\xd9\xa0\x29\x7f\x7a\x2f\x2e\x79\xcf\xda\x39\xfa\x39\x3d\xf1\xac\x00",
+ "\x95\xe8\x7a\xc9\x0f\x54\x1a\xb9\x0c\xbc\xf7\xfd\x7e\x0e\x0c\x15\x2c\xef\x78\xd5\xee\x18\x30\xe9\xed\x8a\x1e\xd7",
+ 65 },
+ { GCRY_MD_SHA3_224,
+ "\xfc\x42\x4e\xeb\x27\xc1\x8a\x11\xc0\x1f\x39\xc5\x55\xd8\xb7\x8a\x80\x5b\x88\xdb\xa1\xdc\x2a\x42\xed\x5e\x2c\x0e\xc7\x37\xff\x68\xb2\x45\x6d\x80\xeb\x85\xe1\x17\x14\xfa\x3f\x8e\xab\xfb\x90\x6d\x3c\x17\x96\x4c\xb4\xf5\xe7\x6b\x29\xc1\x76\x5d\xb0\x3d\x91\xbe\x37\xfc",
+ "\x35\xbd\x7d\x02\x54\x1d\x6d\x4b\x10\xac\xe6\x02\x9a\x24\xc0\x7a\x38\xfd\x56\x3a\xba\x22\x7f\x0f\x77\x6e\xa5\xe2",
+ 66 },
+ { GCRY_MD_SHA3_224,
+ "\xab\xe3\x47\x2b\x54\xe7\x27\x34\xbd\xba\x7d\x91\x58\x73\x64\x64\x25\x1c\x4f\x21\xb3\x3f\xbb\xc9\x2d\x7f\xac\x9a\x35\xc4\xe3\x32\x2f\xf0\x1d\x23\x80\xcb\xaa\x4e\xf8\xfb\x07\xd2\x1a\x21\x28\xb7\xb9\xf5\xb6\xd9\xf3\x4e\x13\xf3\x9c\x7f\xfc\x2e\x72\xe4\x78\x88\x59\x9b\xa5",
+ "\x99\xde\xcb\x8c\xf1\xd4\x74\x97\x0b\x3c\xfa\x87\xfa\x46\x2b\x75\xe3\x28\x7b\x98\xb4\xbe\x40\x93\x42\x9e\x22\xd6",
+ 67 },
+ { GCRY_MD_SHA3_224,
+ "\x36\xf9\xf0\xa6\x5f\x2c\xa4\x98\xd7\x39\xb9\x44\xd6\xef\xf3\xda\x5e\xbb\xa5\x7e\x7d\x9c\x41\x59\x8a\x2b\x0e\x43\x80\xf3\xcf\x4b\x47\x9e\xc2\x34\x8d\x01\x5f\xfe\x62\x56\x27\x35\x11\x15\x4a\xfc\xf3\xb4\xb4\xbf\x09\xd6\xc4\x74\x4f\xdd\x0f\x62\xd7\x50\x79\xd4\x40\x70\x6b\x05",
+ "\x8c\x20\xfd\x3d\x8e\x08\x23\x5b\x01\x72\x7a\x4d\xf4\x4d\x86\xe7\x1e\x82\x4f\x14\xb0\xc2\xfe\x4e\x8d\xa7\xf1\xbb",
+ 68 },
+ { GCRY_MD_SHA3_224,
+ "\xab\xc8\x77\x63\xca\xe1\xca\x98\xbd\x8c\x5b\x82\xca\xba\x54\xac\x83\x28\x6f\x87\xe9\x61\x01\x28\xae\x4d\xe6\x8a\xc9\x5d\xf5\xe3\x29\xc3\x60\x71\x7b\xd3\x49\xf2\x6b\x87\x25\x28\x49\x2c\xa7\xc9\x4c\x2c\x1e\x1e\xf5\x6b\x74\xdb\xb6\x5c\x2a\xc3\x51\x98\x1f\xdb\x31\xd0\x6c\x77\xa4",
+ "\xe2\x9e\x68\x43\x9a\xec\xde\x56\xf5\x29\x7f\xb9\x35\xdc\x7d\xbe\x63\xd6\x1c\xe3\x60\xa1\x96\x29\x19\x5b\xd8\xaa",
+ 69 },
+ { GCRY_MD_SHA3_224,
+ "\x94\xf7\xca\x8e\x1a\x54\x23\x4c\x6d\x53\xcc\x73\x4b\xb3\xd3\x15\x0c\x8b\xa8\xc5\xf8\x80\xea\xb8\xd2\x5f\xed\x13\x79\x3a\x97\x01\xeb\xe3\x20\x50\x92\x86\xfd\x8e\x42\x2e\x93\x1d\x99\xc9\x8d\xa4\xdf\x7e\x70\xae\x44\x7b\xab\x8c\xff\xd9\x23\x82\xd8\xa7\x77\x60\xa2\x59\xfc\x4f\xbd\x72",
+ "\x5d\x21\x64\xda\x84\xe7\x70\x7c\xd1\xe7\x89\x71\x1a\x66\x4a\xb2\xeb\xcf\x66\xeb\xa8\x99\xa9\x09\xa1\xd0\xcb\xec",
+ 70 },
+ { GCRY_MD_SHA3_224,
+ "\x13\xbd\x28\x11\xf6\xed\x2b\x6f\x04\xff\x38\x95\xac\xee\xd7\xbe\xf8\xdc\xd4\x5e\xb1\x21\x79\x1b\xc1\x94\xa0\xf8\x06\x20\x6b\xff\xc3\xb9\x28\x1c\x2b\x30\x8b\x1a\x72\x9c\xe0\x08\x11\x9d\xd3\x06\x6e\x93\x78\xac\xdc\xc5\x0a\x98\xa8\x2e\x20\x73\x88\x00\xb6\xcd\xdb\xe5\xfe\x96\x94\xad\x6d",
+ "\xfa\x26\x3b\x09\x3e\xa3\xf9\x6b\x52\xdb\x62\x51\xea\x25\xa5\x25\x4a\xda\x5b\x54\xd4\x76\xcb\x07\x94\xd3\x88\x89",
+ 71 },
+ { GCRY_MD_SHA3_224,
+ "\x1e\xed\x9c\xba\x17\x9a\x00\x9e\xc2\xec\x55\x08\x77\x3d\xd3\x05\x47\x7c\xa1\x17\xe6\xd5\x69\xe6\x6b\x5f\x64\xc6\xbc\x64\x80\x1c\xe2\x5a\x84\x24\xce\x4a\x26\xd5\x75\xb8\xa6\xfb\x10\xea\xd3\xfd\x19\x92\xed\xdd\xee\xc2\xeb\xe7\x15\x0d\xc9\x8f\x63\xad\xc3\x23\x7e\xf5\x7b\x91\x39\x7a\xa8\xa7",
+ "\xd8\x03\xe3\x20\xa9\x86\x5e\xbf\x35\x55\xe8\xa3\xe3\x13\x47\x68\xa2\xee\x1b\x3e\x59\xfa\x15\xf3\x5c\x2e\xc5\x50",
+ 72 },
+ { GCRY_MD_SHA3_224,
+ "\xba\x5b\x67\xb5\xec\x3a\x3f\xfa\xe2\xc1\x9d\xd8\x17\x6a\x2e\xf7\x5c\x0c\xd9\x03\x72\x5d\x45\xc9\xcb\x70\x09\xa9\x00\xc0\xb0\xca\x7a\x29\x67\xa9\x5a\xe6\x82\x69\xa6\xdb\xf8\x46\x6c\x7b\x68\x44\xa1\xd6\x08\xac\x66\x1f\x7e\xff\x00\x53\x8e\x32\x3d\xb5\xf2\xc6\x44\xb7\x8b\x2d\x48\xde\x1a\x08\xaa",
+ "\x10\x29\x25\xb6\x3b\x3e\x93\x95\xf8\x81\x24\xc3\xbf\xa7\x77\xf2\x9a\x5b\x41\xc1\x3b\x62\xad\xd7\xc2\x71\xcd\x6e",
+ 73 },
+ { GCRY_MD_SHA3_224,
+ "\x0e\xfa\x26\xac\x56\x73\x16\x7d\xca\xca\xb8\x60\x93\x2e\xd6\x12\xf6\x5f\xf4\x9b\x80\xfa\x9a\xe6\x54\x65\xe5\x54\x2c\xb6\x20\x75\xdf\x1c\x5a\xe5\x4f\xba\x4d\xb8\x07\xbe\x25\xb0\x70\x03\x3e\xfa\x22\x3b\xdd\x5b\x1d\x3c\x94\xc6\xe1\x90\x9c\x02\xb6\x20\xd4\xb1\xb3\xa6\xc9\xfe\xd2\x4d\x70\x74\x96\x04",
+ "\x6c\x4e\x83\xcd\x92\x58\x20\x5f\x3c\x2b\xcf\x64\x14\x9f\x4a\xcd\xce\xe7\x74\x2c\xb2\xd3\x60\x38\x53\x71\x71\xbd",
+ 74 },
+ { GCRY_MD_SHA3_224,
+ "\xbb\xfd\x93\x3d\x1f\xd7\xbf\x59\x4a\xc7\xf4\x35\x27\x7d\xc1\x7d\x8d\x5a\x5b\x8e\x4d\x13\xd9\x6d\x2f\x64\xe7\x71\xab\xbd\x51\xa5\xa8\xae\xa7\x41\xbe\xcc\xbd\xdb\x17\x7b\xce\xa0\x52\x43\xeb\xd0\x03\xcf\xde\xae\x87\x7c\xca\x4d\xa9\x46\x05\xb6\x76\x91\x91\x9d\x8b\x03\x3f\x77\xd3\x84\xca\x01\x59\x3c\x1b",
+ "\xc7\x4c\x9e\xbb\x2e\xf9\xa9\x82\x2a\x62\x28\xbd\x11\x86\xdc\xc4\x41\x1b\xc5\x9e\xc9\x38\xdf\x27\xe5\x4b\x08\x15",
+ 75 },
+ { GCRY_MD_SHA3_224,
+ "\x90\x07\x89\x99\xfd\x3c\x35\xb8\xaf\xbf\x40\x66\xcb\xde\x33\x58\x91\x36\x5f\x0f\xc7\x5c\x12\x86\xcd\xd8\x8f\xa5\x1f\xab\x94\xf9\xb8\xde\xf7\xc9\xac\x58\x2a\x5d\xbc\xd9\x58\x17\xaf\xb7\xd1\xb4\x8f\x63\x70\x4e\x19\xc2\xba\xa4\xdf\x34\x7f\x48\xd4\xa6\xd6\x03\x01\x3c\x23\xf1\xe9\x61\x1d\x59\x5e\xba\xc3\x7c",
+ "\xd2\x34\x20\xf9\x98\x5d\x66\xf0\x97\xd4\x3a\x0f\xb2\x43\x41\x49\xd2\xb3\x3f\x21\xb5\xba\xd6\xcf\xc2\x50\xe0\x72",
+ 76 },
+ { GCRY_MD_SHA3_224,
+ "\x64\x10\x5e\xca\x86\x35\x15\xc2\x0e\x7c\xfb\xaa\x0a\x0b\x88\x09\x04\x61\x64\xf3\x74\xd6\x91\xcd\xbd\x65\x08\xaa\xab\xc1\x81\x9f\x9a\xc8\x4b\x52\xba\xfc\x1b\x0f\xe7\xcd\xdb\xc5\x54\xb6\x08\xc0\x1c\x89\x04\xc6\x69\xd8\xdb\x31\x6a\x09\x53\xa4\xc6\x8e\xce\x32\x4e\xc5\xa4\x9f\xfd\xb5\x9a\x1b\xd6\xa2\x92\xaa\x0e",
+ "\x10\x2e\xdd\x2e\x94\x6f\x33\xdd\x7a\xa5\x53\xea\x4c\xe4\xe6\x59\xc7\xb2\x40\xe1\xe2\x8b\xc6\x62\x00\x84\x5d\x87",
+ 77 },
+ { GCRY_MD_SHA3_224,
+ "\xd4\x65\x4b\xe2\x88\xb9\xf3\xb7\x11\xc2\xd0\x20\x15\x97\x8a\x8c\xc5\x74\x71\xd5\x68\x0a\x09\x2a\xa5\x34\xf7\x37\x2c\x71\xce\xaa\xb7\x25\xa3\x83\xc4\xfc\xf4\xd8\xde\xaa\x57\xfc\xa3\xce\x05\x6f\x31\x29\x61\xec\xcf\x9b\x86\xf1\x49\x81\xba\x5b\xed\x6a\xb5\xb4\x49\x8e\x1f\x6c\x82\xc6\xca\xe6\xfc\x14\x84\x5b\x3c\x8a",
+ "\x7c\x8e\xb9\x8b\x73\x38\x40\x3c\x01\x3d\x65\xc0\xb5\xbb\x4b\x5d\x2c\xbf\x53\x9c\xb1\x10\x9c\xf4\x47\xfa\x66\x50",
+ 78 },
+ { GCRY_MD_SHA3_224,
+ "\x12\xd9\x39\x48\x88\x30\x5a\xc9\x6e\x65\xf2\xbf\x0e\x1b\x18\xc2\x9c\x90\xfe\x9d\x71\x4d\xd5\x9f\x65\x1f\x52\xb8\x8b\x30\x08\xc5\x88\x43\x55\x48\x06\x6e\xa2\xfc\x4c\x10\x11\x18\xc9\x1f\x32\x55\x62\x24\xa5\x40\xde\x6e\xfd\xdb\xca\x29\x6e\xf1\xfb\x00\x34\x1f\x5b\x01\xfe\xcf\xc1\x46\xbd\xb2\x51\xb3\xbd\xad\x55\x6c\xd2",
+ "\xc7\xb0\x7d\xe9\x1e\xfc\xe4\x2d\xab\x78\x19\x9e\xe2\xeb\x30\x14\xa4\x94\x99\x42\x36\xa1\x2b\x3d\xe2\x33\x0c\x25",
+ 79 },
+ { GCRY_MD_SHA3_224,
+ "\x87\x1a\x0d\x7a\x5f\x36\xc3\xda\x1d\xfc\xe5\x7a\xcd\x8a\xb8\x48\x7c\x27\x4f\xad\x33\x6b\xc1\x37\xeb\xd6\xff\x46\x58\xb5\x47\xc1\xdc\xfa\xb6\x5f\x03\x7a\xa5\x8f\x35\xef\x16\xaf\xf4\xab\xe7\x7b\xa6\x1f\x65\x82\x6f\x7b\xe6\x81\xb5\xb6\xd5\xa1\xea\x80\x85\xe2\xae\x9c\xd5\xcf\x09\x91\x87\x8a\x31\x1b\x54\x9a\x6d\x6a\xf2\x30",
+ "\x2f\xce\xf2\x59\x4a\xe8\x55\xde\x4f\xc6\x6d\xcc\xc5\x17\xa6\x59\x11\x8b\x3a\x9f\x2e\x5f\xe6\x38\x98\x0a\xdb\xfb",
+ 80 },
+ { GCRY_MD_SHA3_224,
+ "\xe9\x0b\x4f\xfe\xf4\xd4\x57\xbc\x77\x11\xff\x4a\xa7\x22\x31\xca\x25\xaf\x6b\x2e\x20\x6f\x8b\xf8\x59\xd8\x75\x8b\x89\xa7\xcd\x36\x10\x5d\xb2\x53\x8d\x06\xda\x83\xba\xd5\xf6\x63\xba\x11\xa5\xf6\xf6\x1f\x23\x6f\xd5\xf8\xd5\x3c\x5e\x89\xf1\x83\xa3\xce\xc6\x15\xb5\x0c\x7c\x68\x1e\x77\x3d\x10\x9f\xf7\x49\x1b\x5c\xc2\x22\x96\xc5",
+ "\xd4\x58\x73\xf0\x45\x3c\xbf\x38\x15\x6a\x13\x84\xe3\x3e\x5c\x76\x58\x8b\x7b\xfb\x48\xa7\x09\xb3\x94\x3d\x91\x86",
+ 81 },
+ { GCRY_MD_SHA3_224,
+ "\xe7\x28\xde\x62\xd7\x58\x56\x50\x0c\x4c\x77\xa4\x28\x61\x2c\xd8\x04\xf3\x0c\x3f\x10\xd3\x6f\xb2\x19\xc5\xca\x0a\xa3\x07\x26\xab\x19\x0e\x5f\x3f\x27\x9e\x07\x33\xd7\x7e\x72\x67\xc1\x7b\xe2\x7d\x21\x65\x0a\x9a\x4d\x1e\x32\xf6\x49\x62\x76\x38\xdb\xad\xa9\x70\x2c\x7c\xa3\x03\x26\x9e\xd1\x40\x14\xb2\xf3\xcf\x8b\x89\x4e\xac\x85\x54",
+ "\x35\x43\xad\xd5\xb7\xed\xfc\x83\xaf\xe7\xc1\xf2\xd5\x51\x40\xae\xdb\x85\x83\x04\x62\x81\x09\xfd\x07\x7b\x38\x60",
+ 82 },
+ { GCRY_MD_SHA3_224,
+ "\x63\x48\xf2\x29\xe7\xb1\xdf\x3b\x77\x0c\x77\x54\x4e\x51\x66\xe0\x81\x85\x0f\xa1\xc6\xc8\x81\x69\xdb\x74\xc7\x6e\x42\xeb\x98\x3f\xac\xb2\x76\xad\x6a\x0d\x1f\xa7\xb5\x0d\x3e\x3b\x6f\xcd\x79\x9e\xc9\x74\x70\x92\x0a\x7a\xbe\xd4\x7d\x28\x8f\xf8\x83\xe2\x4c\xa2\x1c\x7f\x80\x16\xb9\x3b\xb9\xb9\xe0\x78\xbd\xb9\x70\x3d\x2b\x78\x1b\x61\x6e",
+ "\x36\x78\x4f\x11\x49\x58\xd8\xb5\xb6\x25\xdd\x89\xa4\xe3\x97\x3a\x11\x3e\x5d\x16\x10\xdf\xa5\x5b\x4f\xb4\x5a\xec",
+ 83 },
+ { GCRY_MD_SHA3_224,
+ "\x4b\x12\x7f\xde\x5d\xe7\x33\xa1\x68\x0c\x27\x90\x36\x36\x27\xe6\x3a\xc8\xa3\xf1\xb4\x70\x7d\x98\x2c\xae\xa2\x58\x65\x5d\x9b\xf1\x8f\x89\xaf\xe5\x41\x27\x48\x2b\xa0\x1e\x08\x84\x55\x94\xb6\x71\x30\x6a\x02\x5c\x9a\x5c\x5b\x6f\x93\xb0\xa3\x95\x22\xdc\x87\x74\x37\xbe\x5c\x24\x36\xcb\xf3\x00\xce\x7a\xb6\x74\x79\x34\xfc\xfc\x30\xae\xaa\xf6",
+ "\x41\x87\xfe\xae\xd4\xfb\xd3\xd5\x05\xa9\x6a\x8d\x60\x66\x8a\x88\x17\x2e\x4f\x7c\x84\x51\xa4\xa6\x80\x2c\x57\x47",
+ 84 },
+ { GCRY_MD_SHA3_224,
+ "\x08\x46\x1f\x00\x6c\xff\x4c\xc6\x4b\x75\x2c\x95\x72\x87\xe5\xa0\xfa\xab\xc0\x5c\x9b\xff\x89\xd2\x3f\xd9\x02\xd3\x24\xc7\x99\x03\xb4\x8f\xcb\x8f\x8f\x4b\x01\xf3\xe4\xdd\xb4\x83\x59\x3d\x25\xf0\x00\x38\x66\x98\xf5\xad\xe7\xfa\xad\xe9\x61\x5f\xdc\x50\xd3\x27\x85\xea\x51\xd4\x98\x94\xe4\x5b\xaa\x3d\xc7\x07\xe2\x24\x68\x8c\x64\x08\xb6\x8b\x11",
+ "\x6e\x47\x66\xdb\x4e\x9d\x11\x02\xce\xe6\xdf\xe0\xae\x22\x21\x32\x1b\x9c\x0f\xe7\x07\xf0\xa7\x82\x5d\x75\x57\xec",
+ 85 },
+ { GCRY_MD_SHA3_224,
+ "\x68\xc8\xf8\x84\x9b\x12\x0e\x6e\x0c\x99\x69\xa5\x86\x6a\xf5\x91\xa8\x29\xb9\x2f\x33\xcd\x9a\x4a\x31\x96\x95\x7a\x14\x8c\x49\x13\x8e\x1e\x2f\x5c\x76\x19\xa6\xd5\xed\xeb\xe9\x95\xac\xd8\x1e\xc8\xbb\x9c\x7b\x9c\xfc\xa6\x78\xd0\x81\xea\x9e\x25\xa7\x5d\x39\xdb\x04\xe1\x8d\x47\x59\x20\xce\x82\x8b\x94\xe7\x22\x41\xf2\x4d\xb7\x25\x46\xb3\x52\xa0\xe4",
+ "\xe1\xfc\x97\x2b\xfb\x29\x41\x85\xf1\x98\x0c\xa2\x93\x86\x55\xfb\x58\x3e\x81\x2a\xd3\xd6\x4f\xa5\xa4\xcf\x70\x3e",
+ 86 },
+ { GCRY_MD_SHA3_224,
+ "\xb8\xd5\x64\x72\x95\x4e\x31\xfb\x54\xe2\x8f\xca\x74\x3f\x84\xd8\xdc\x34\x89\x1c\xb5\x64\xc6\x4b\x08\xf7\xb7\x16\x36\xde\xbd\x64\xca\x1e\xdb\xdb\xa7\xfc\x5c\x3e\x40\x04\x9c\xe9\x82\xbb\xa8\xc7\xe0\x70\x30\x34\xe3\x31\x38\x46\x95\xe9\xde\x76\xb5\x10\x4f\x2f\xbc\x45\x35\xec\xbe\xeb\xc3\x3b\xc2\x7f\x29\xf1\x8f\x6f\x27\xe8\x02\x3b\x0f\xbb\x6f\x56\x3c",
+ "\xf6\xf2\x8e\x3b\x65\xb6\x84\xc9\xd9\x50\x60\x61\x98\x00\x46\x06\x13\x90\xcc\xde\x24\x58\xa2\x0f\x9b\x08\x6b\xe5",
+ 87 },
+ { GCRY_MD_SHA3_224,
+ "\x0d\x58\xac\x66\x5f\xa8\x43\x42\xe6\x0c\xef\xee\x31\xb1\xa4\xea\xcd\xb0\x92\xf1\x22\xdf\xc6\x83\x09\x07\x7a\xed\x1f\x3e\x52\x8f\x57\x88\x59\xee\x9e\x4c\xef\xb4\xa7\x28\xe9\x46\x32\x49\x27\xb6\x75\xcd\x4f\x4a\xc8\x4f\x64\xdb\x3d\xac\xfe\x85\x0c\x1d\xd1\x87\x44\xc7\x4c\xec\xcd\x9f\xe4\xdc\x21\x40\x85\x10\x8f\x40\x4e\xab\x6d\x8f\x45\x2b\x54\x42\xa4\x7d",
+ "\xf6\x86\xd2\xb1\x38\x6b\x02\xb0\x8f\x6b\x02\xbd\x5d\x50\x20\x6d\x5e\x13\x84\x40\xcb\x0d\x93\xeb\xcc\x3b\x32\xa7",
+ 88 },
+ { GCRY_MD_SHA3_224,
+ "\x17\x55\xe2\xd2\xe5\xd1\xc1\xb0\x15\x64\x56\xb5\x39\x75\x3f\xf4\x16\x65\x1d\x44\x69\x8e\x87\x00\x2d\xcf\x61\xdc\xfa\x2b\x4e\x72\xf2\x64\xd9\xad\x59\x1d\xf1\xfd\xee\x7b\x41\xb2\xeb\x00\x28\x3c\x5a\xeb\xb3\x41\x13\x23\xb6\x72\xea\xa1\x45\xc5\x12\x51\x85\x10\x4f\x20\xf3\x35\x80\x4b\x02\x32\x5b\x6d\xea\x65\x60\x3f\x34\x9f\x4d\x5d\x8b\x78\x2d\xd3\x46\x9c\xcd",
+ "\x46\x48\x33\x75\xd1\x12\xfc\x2b\xe7\xf6\x11\xbe\x4b\x98\xdf\xad\xa3\x88\x92\xc4\x3c\xef\xa5\x86\x72\x6b\x48\xbb",
+ 89 },
+ { GCRY_MD_SHA3_224,
+ "\xb1\x80\xde\x1a\x61\x11\x11\xee\x75\x84\xba\x2c\x4b\x02\x05\x98\xcd\x57\x4a\xc7\x7e\x40\x4e\x85\x3d\x15\xa1\x01\xc6\xf5\xa2\xe5\xc8\x01\xd7\xd8\x5d\xc9\x52\x86\xa1\x80\x4c\x87\x0b\xb9\xf0\x0f\xd4\xdc\xb0\x3a\xa8\x32\x82\x75\x15\x88\x19\xdc\xad\x72\x53\xf3\xe3\xd2\x37\xae\xaa\x79\x79\x26\x8a\x5d\xb1\xc6\xce\x08\xa9\xec\x7c\x25\x79\x78\x3c\x8a\xfc\x1f\x91\xa7",
+ "\xe1\xe9\xad\x56\x8a\xe5\xb0\xd9\x73\x14\x00\xba\x4f\xc7\xdf\x03\x21\xa0\x4e\xa4\x13\x93\xba\x69\x79\xc7\x17\x9c",
+ 90 },
+ { GCRY_MD_SHA3_224,
+ "\xcf\x35\x83\xcb\xdf\xd4\xcb\xc1\x70\x63\xb1\xe7\xd9\x0b\x02\xf0\xe6\xe2\xee\x05\xf9\x9d\x77\xe2\x4e\x56\x03\x92\x53\x5e\x47\xe0\x50\x77\x15\x7f\x96\x81\x35\x44\xa1\x70\x46\x91\x4f\x9e\xfb\x64\x76\x2a\x23\xcf\x7a\x49\xfe\x52\xa0\xa4\xc0\x1c\x63\x0c\xfe\x87\x27\xb8\x1f\xb9\x9a\x89\xff\x7c\xc1\x1d\xca\x51\x73\x05\x7e\x04\x17\xb8\xfe\x7a\x9e\xfb\xa6\xd9\x5c\x55\x5f",
+ "\x13\x3f\x31\xd9\xfb\xc1\xb2\xa3\x3f\x1c\x98\xbf\xe2\x1e\x12\x9e\x07\x16\xa6\x9e\xe2\x74\x08\x74\x3f\xff\x17\xac",
+ 91 },
+ { GCRY_MD_SHA3_224,
+ "\x07\x2f\xc0\x23\x40\xef\x99\x11\x5b\xad\x72\xf9\x2c\x01\xe4\xc0\x93\xb9\x59\x9f\x6c\xfc\x45\xcb\x38\x0e\xe6\x86\xcb\x5e\xb0\x19\xe8\x06\xab\x9b\xd5\x5e\x63\x4a\xb1\x0a\xa6\x2a\x95\x10\xcc\x06\x72\xcd\x3e\xdd\xb5\x89\xc7\xdf\x2b\x67\xfc\xd3\x32\x9f\x61\xb1\xa4\x44\x1e\xca\x87\xa3\x3c\x8f\x55\xda\x4f\xbb\xad\x5c\xf2\xb2\x52\x7b\x8e\x98\x3b\xb3\x1a\x2f\xad\xec\x75\x23",
+ "\x31\x32\x8f\x04\xca\x64\xe8\x52\x1a\x36\xa8\x94\x3c\x33\xce\xb9\x5b\xe1\xb9\x08\x0f\x45\x33\xd6\xda\x07\x60\x6d",
+ 92 },
+ { GCRY_MD_SHA3_224,
+ "\x76\xee\xcf\x95\x6a\x52\x64\x9f\x87\x75\x28\x14\x6d\xe3\x3d\xf2\x49\xcd\x80\x0e\x21\x83\x0f\x65\xe9\x0f\x0f\x25\xca\x9d\x65\x40\xfd\xe4\x06\x03\x23\x0e\xca\x67\x60\xf1\x13\x9c\x7f\x26\x8d\xeb\xa2\x06\x06\x31\xee\xa9\x2b\x1f\xff\x05\xf9\x3f\xd5\x57\x2f\xbe\x29\x57\x9e\xcd\x48\xbc\x3a\x8d\x6c\x2e\xb4\xa6\xb2\x6e\x38\xd6\xc5\xfb\xf2\xc0\x80\x44\xae\xea\x47\x0a\x8f\x2f\x26",
+ "\xad\xd3\x74\xb1\xd2\x79\x46\x9c\x08\xe7\xb2\x7a\xe3\xff\x1b\x04\xc3\xd0\xfb\x3e\xf6\xe5\x9a\xa3\xaf\x86\x66\x0b",
+ 93 },
+ { GCRY_MD_SHA3_224,
+ "\x7a\xdc\x0b\x66\x93\xe6\x1c\x26\x9f\x27\x8e\x69\x44\xa5\xa2\xd8\x30\x09\x81\xe4\x00\x22\xf8\x39\xac\x64\x43\x87\xbf\xac\x90\x86\x65\x00\x85\xc2\xcd\xc5\x85\xfe\xa4\x7b\x9d\x2e\x52\xd6\x5a\x2b\x29\xa7\xdc\x37\x04\x01\xef\x5d\x60\xdd\x0d\x21\xf9\xe2\xb9\x0f\xae\x91\x93\x19\xb1\x4b\x8c\x55\x65\xb0\x42\x3c\xef\xb8\x27\xd5\xf1\x20\x33\x02\xa9\xd0\x15\x23\x49\x8a\x4d\xb1\x03\x74",
+ "\xfe\xd7\xfd\xe8\x94\xd9\x2c\xc3\xbb\x68\xfc\xc3\x96\xb5\xeb\x00\xc4\x15\x6f\x04\xfc\x9c\xed\x99\xd1\x2c\xfa\x5b",
+ 94 },
+ { GCRY_MD_SHA3_224,
+ "\xe1\xff\xfa\x98\x26\xcc\xe8\xb8\x6b\xcc\xef\xb8\x79\x4e\x48\xc4\x6c\xdf\x37\x20\x13\xf7\x82\xec\xed\x1e\x37\x82\x69\xb7\xbe\x2b\x7b\xf5\x13\x74\x09\x22\x61\xae\x12\x0e\x82\x2b\xe6\x85\xf2\xe7\xa8\x36\x64\xbc\xfb\xe3\x8f\xe8\x63\x3f\x24\xe6\x33\xff\xe1\x98\x8e\x1b\xc5\xac\xf5\x9a\x58\x70\x79\xa5\x7a\x91\x0b\xda\x60\x06\x0e\x85\xb5\xf5\xb6\xf7\x76\xf0\x52\x96\x39\xd9\xcc\xe4\xbd",
+ "\x17\xfc\x03\x27\xde\x47\x4c\x78\xf5\x38\xb4\xf3\x98\x16\x74\xff\x47\x0a\xa4\x2e\xf3\xb8\x2c\x0c\xc3\x4d\xe6\xda",
+ 95 },
+ { GCRY_MD_SHA3_224,
+ "\x69\xf9\xab\xba\x65\x59\x2e\xe0\x1d\xb4\xdc\xe5\x2d\xba\xb9\x0b\x08\xfc\x04\x19\x36\x02\x79\x2e\xe4\xda\xa2\x63\x03\x3d\x59\x08\x15\x87\xb0\x9b\xbe\x49\xd0\xb4\x9c\x98\x25\xd2\x28\x40\xb2\xff\x5d\x9c\x51\x55\xf9\x75\xf8\xf2\xc2\xe7\xa9\x0c\x75\xd2\xe4\xa8\x04\x0f\xe3\x9f\x63\xbb\xaf\xb4\x03\xd9\xe2\x8c\xc3\xb8\x6e\x04\xe3\x94\xa9\xc9\xe8\x06\x5b\xd3\xc8\x5f\xa9\xf0\xc7\x89\x16\x00",
+ "\x88\xfe\xfb\xe8\x99\x5e\x29\x6a\x9d\xee\x4d\xa2\xb4\x14\xd5\xa7\xe1\x34\x04\x56\x39\xa6\xb1\x76\xc2\xd7\x36\xed",
+ 96 },
+ { GCRY_MD_SHA3_224,
+ "\x38\xa1\x0a\x35\x2c\xa5\xae\xdf\xa8\xe1\x9c\x64\x78\x7d\x8e\x9c\x3a\x75\xdb\xf3\xb8\x67\x4b\xfa\xb2\x9b\x5d\xbf\xc1\x5a\x63\xd1\x0f\xae\x66\xcd\x1a\x6e\x6d\x24\x52\xd5\x57\x96\x7e\xaa\xd8\x9a\x4c\x98\x44\x97\x87\xb0\xb3\x16\x4c\xa5\xb7\x17\xa9\x3f\x24\xeb\x0b\x50\x6c\xeb\x70\xcb\xbc\xb8\xd7\x2b\x2a\x72\x99\x3f\x90\x9a\xad\x92\xf0\x44\xe0\xb5\xa2\xc9\xac\x9c\xb1\x6a\x0c\xa2\xf8\x1f\x49",
+ "\xc0\x02\x73\x2f\x6f\x38\xab\x83\x82\x89\x21\xf5\xfc\xb4\xa8\xce\x1f\xc5\x61\xb0\xe9\xfa\x21\x4c\x5f\xf0\x21\x92",
+ 97 },
+ { GCRY_MD_SHA3_224,
+ "\x6d\x8c\x6e\x44\x9b\xc1\x36\x34\xf1\x15\x74\x9c\x24\x8c\x17\xcd\x14\x8b\x72\x15\x7a\x2c\x37\xbf\x89\x69\xea\x83\xb4\xd6\xba\x8c\x0e\xe2\x71\x1c\x28\xee\x11\x49\x5f\x43\x04\x95\x96\x52\x0c\xe4\x36\x00\x4b\x02\x6b\x6c\x1f\x72\x92\xb9\xc4\x36\xb0\x55\xcb\xb7\x2d\x53\x0d\x86\x0d\x12\x76\xa1\x50\x2a\x51\x40\xe3\xc3\xf5\x4a\x93\x66\x3e\x4d\x20\xed\xec\x32\xd2\x84\xe2\x55\x64\xf6\x24\x95\x5b\x52",
+ "\x44\xe9\x00\x2f\x9d\x97\xd9\x8b\xb4\x39\xaf\xc3\x61\xf9\x3b\xb9\x59\x52\x3e\x73\x13\x6a\x2c\x65\xb2\xe2\xb0\x66",
+ 98 },
+ { GCRY_MD_SHA3_224,
+ "\x6e\xfc\xbc\xaf\x45\x1c\x12\x9d\xbe\x00\xb9\xce\xf0\xc3\x74\x9d\x3e\xe9\xd4\x1c\x7b\xd5\x00\xad\xe4\x0c\xdc\x65\xde\xdb\xbb\xad\xb8\x85\xa5\xb1\x4b\x32\xa0\xc0\xd0\x87\x82\x52\x01\xe3\x03\x28\x8a\x73\x38\x42\xfa\x7e\x59\x9c\x0c\x51\x4e\x07\x8f\x05\xc8\x21\xc7\xa4\x49\x8b\x01\xc4\x00\x32\xe9\xf1\x87\x2a\x1c\x92\x5f\xa1\x7c\xe2\x53\xe8\x93\x5e\x4c\x3c\x71\x28\x22\x42\xcb\x71\x6b\x20\x89\xcc\xc1",
+ "\x2b\xff\x16\xcb\xa9\xe5\x07\x62\xd2\x28\x8e\xb7\x80\x07\x84\x62\xc0\x86\xf4\xcb\xf5\x94\x79\xf5\x38\x7a\x0b\x27",
+ 99 },
+ { GCRY_MD_SHA3_224,
+ "\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce",
+ "\x5e\xfd\xc3\xca\xa2\x2e\xe2\xc2\xeb\x63\x2d\x4c\x66\x45\xce\x3e\xc6\x39\x60\xdf\xd6\x9a\x04\xbb\xe0\x11\x56\xc5",
+ 100 },
+ { GCRY_MD_SHA3_224,
+ "\xa8\x73\xe0\xc6\x7c\xa6\x39\x02\x6b\x66\x83\x00\x8f\x7a\xa6\x32\x4d\x49\x79\x55\x0e\x9b\xce\x06\x4c\xa1\xe1\xfb\x97\xa3\x0b\x14\x7a\x24\xf3\xf6\x66\xc0\xa7\x2d\x71\x34\x8e\xde\x70\x1c\xf2\xd1\x7e\x22\x53\xc3\x4d\x1e\xc3\xb6\x47\xdb\xce\xf2\xf8\x79\xf4\xeb\x88\x1c\x48\x30\xb7\x91\x37\x8c\x90\x1e\xb7\x25\xea\x5c\x17\x23\x16\xc6\xd6\x06\xe0\xaf\x7d\xf4\xdf\x7f\x76\xe4\x90\xcd\x30\xb2\xba\xdf\x45\x68\x5f",
+ "\xe8\xfb\x64\xa7\x43\x87\xc9\xa3\xe1\xac\x4a\xbc\x82\xd3\x59\x1b\x6b\x34\x9f\x2e\x5c\xde\x65\x84\xd8\xd7\xc3\x71",
+ 101 },
+ { GCRY_MD_SHA3_224,
+ "\x00\x69\x17\xb6\x4f\x9d\xcd\xf1\xd2\xd8\x7c\x8a\x61\x73\xb6\x4f\x65\x87\x16\x8e\x80\xfa\xa8\x0f\x82\xd8\x4f\x60\x30\x1e\x56\x1e\x31\x2d\x9f\xbc\xe6\x2f\x39\xa6\xfb\x47\x6e\x01\xe9\x25\xf2\x6b\xcc\x91\xde\x62\x14\x49\xbe\x65\x04\xc5\x04\x83\x0a\xae\x39\x40\x96\xc8\xfc\x76\x94\x65\x10\x51\x36\x5d\x4e\xe9\x07\x01\x01\xec\x9b\x68\x08\x6f\x2e\xa8\xf8\xab\x7b\x81\x1e\xa8\xad\x93\x4d\x5c\x9b\x62\xc6\x0a\x47\x71",
+ "\xdb\x22\x4b\xcc\xf5\xca\x86\xdf\xba\x3e\xa3\x72\xe2\x26\x97\x50\xb5\x32\x40\x9e\xa0\x04\xe8\x2d\x4b\x58\x35\xe8",
+ 102 },
+ { GCRY_MD_SHA3_224,
+ "\xf1\x3c\x97\x2c\x52\xcb\x3c\xc4\xa4\xdf\x28\xc9\x7f\x2d\xf1\x1c\xe0\x89\xb8\x15\x46\x6b\xe8\x88\x63\x24\x3e\xb3\x18\xc2\xad\xb1\xa4\x17\xcb\x10\x41\x30\x85\x98\x54\x17\x20\x19\x7b\x9b\x1c\xb5\xba\x23\x18\xbd\x55\x74\xd1\xdf\x21\x74\xaf\x14\x88\x41\x49\xba\x9b\x2f\x44\x6d\x60\x9d\xf2\x40\xce\x33\x55\x99\x95\x7b\x8e\xc8\x08\x76\xd9\xa0\x85\xae\x08\x49\x07\xbc\x59\x61\xb2\x0b\xf5\xf6\xca\x58\xd5\xda\xb3\x8a\xdb",
+ "\x4e\x28\x86\x7d\xce\xf3\xa7\xb7\x59\xca\x24\xd8\x10\x7b\xeb\x0c\xbf\x9d\xb0\xf1\x0a\x3c\x41\x0a\x9b\x4b\xa8\xc8",
+ 103 },
+ { GCRY_MD_SHA3_224,
+ "\xe3\x57\x80\xeb\x97\x99\xad\x4c\x77\x53\x5d\x4d\xdb\x68\x3c\xf3\x3e\xf3\x67\x71\x53\x27\xcf\x4c\x4a\x58\xed\x9c\xbd\xcd\xd4\x86\xf6\x69\xf8\x01\x89\xd5\x49\xa9\x36\x4f\xa8\x2a\x51\xa5\x26\x54\xec\x72\x1b\xb3\xaa\xb9\x5d\xce\xb4\xa8\x6a\x6a\xfa\x93\x82\x6d\xb9\x23\x51\x7e\x92\x8f\x33\xe3\xfb\xa8\x50\xd4\x56\x60\xef\x83\xb9\x87\x6a\xcc\xaf\xa2\xa9\x98\x7a\x25\x4b\x13\x7c\x6e\x14\x0a\x21\x69\x1e\x10\x69\x41\x38\x48",
+ "\x5c\x0c\x2d\xf1\x3a\x1f\xd6\x76\x2b\x6e\x50\xfb\x3e\x08\x0e\x64\x9c\x3a\x7a\x8d\xda\x41\x5c\x42\xfb\x63\x71\x36",
+ 104 },
+ { GCRY_MD_SHA3_224,
+ "\x64\xec\x02\x1c\x95\x85\xe0\x1f\xfe\x6d\x31\xbb\x50\xd4\x4c\x79\xb6\x99\x3d\x72\x67\x81\x63\xdb\x47\x49\x47\xa0\x53\x67\x46\x19\xd1\x58\x01\x6a\xdb\x24\x3f\x5c\x8d\x50\xaa\x92\xf5\x0a\xb3\x6e\x57\x9f\xf2\xda\xbb\x78\x0a\x2b\x52\x93\x70\xda\xa2\x99\x20\x7c\xfb\xcd\xd3\xa9\xa2\x50\x06\xd1\x9c\x4f\x1f\xe3\x3e\x4b\x1e\xae\xc3\x15\xd8\xc6\xee\x1e\x73\x06\x23\xfd\x19\x41\x87\x5b\x92\x4e\xb5\x7d\x6d\x0c\x2e\xdc\x4e\x78\xd6",
+ "\x36\xf5\x63\x0e\xc2\x82\x9b\x0f\xba\xd8\x4f\x15\x09\x32\xe4\x66\x47\xed\xcc\x45\x4e\x06\xb2\x31\x66\x66\x1d\x60",
+ 105 },
+ { GCRY_MD_SHA3_224,
+ "\x59\x54\xba\xb5\x12\xcf\x32\x7d\x66\xb5\xd9\xf2\x96\x18\x00\x80\x40\x26\x24\xad\x76\x28\x50\x6b\x55\x5e\xea\x83\x82\x56\x23\x24\xcf\x45\x2f\xba\x4a\x21\x30\xde\x3e\x16\x5d\x11\x83\x1a\x27\x0d\x9c\xb9\x7c\xe8\xc2\xd3\x2a\x96\xf5\x0d\x71\x60\x0b\xb4\xca\x26\x8c\xf9\x8e\x90\xd6\x49\x6b\x0a\x66\x19\xa5\xa8\xc6\x3d\xb6\xd8\xa0\x63\x4d\xfc\x6c\x7e\xc8\xea\x9c\x00\x6b\x6c\x45\x6f\x1b\x20\xcd\x19\xe7\x81\xaf\x20\x45\x4a\xc8\x80",
+ "\xda\xc2\x59\x4b\xcd\x35\x7e\x63\x92\x8a\x21\xe9\x83\x48\xf2\x7d\x0f\xa2\xc7\x0e\xb0\x7c\x7e\x8e\x93\xd6\xd8\x4e",
+ 106 },
+ { GCRY_MD_SHA3_224,
+ "\x03\xd9\xf9\x2b\x2c\x56\x57\x09\xa5\x68\x72\x4a\x0a\xff\x90\xf8\xf3\x47\xf4\x3b\x02\x33\x8f\x94\xa0\x3e\xd3\x2e\x6f\x33\x66\x6f\xf5\x80\x2d\xa4\xc8\x1b\xdc\xe0\xd0\xe8\x6c\x04\xaf\xd4\xed\xc2\xfc\x8b\x41\x41\xc2\x97\x5b\x6f\x07\x63\x9b\x19\x94\xc9\x73\xd9\xa9\xaf\xce\x3d\x9d\x36\x58\x62\x00\x34\x98\x51\x3b\xfa\x16\x6d\x26\x29\xe3\x14\xd9\x74\x41\x66\x7b\x00\x74\x14\xe7\x39\xd7\xfe\xbf\x0f\xe3\xc3\x2c\x17\xaa\x18\x8a\x86\x83",
+ "\x24\x97\x0d\xf3\xcf\x8c\x9e\x30\xdc\xbe\x66\x18\x17\xff\x74\x53\x8a\xd4\x3b\xc9\x0b\x14\x9e\xd7\xca\xb7\x81\x1b",
+ 107 },
+ { GCRY_MD_SHA3_224,
+ "\xf3\x1e\x8b\x4f\x9e\x06\x21\xd5\x31\xd2\x2a\x38\x0b\xe5\xd9\xab\xd5\x6f\xae\xc5\x3c\xbd\x39\xb1\xfa\xb2\x30\xea\x67\x18\x44\x40\xe5\xb1\xd1\x54\x57\xbd\x25\xf5\x62\x04\xfa\x91\x7f\xa4\x8e\x66\x90\x16\xcb\x48\xc1\xff\xc1\xe1\xe4\x52\x74\xb3\xb4\x73\x79\xe0\x0a\x43\x84\x3c\xf8\x60\x1a\x55\x51\x41\x1e\xc1\x25\x03\xe5\xaa\xc4\x3d\x86\x76\xa1\xb2\x29\x7e\xc7\xa0\x80\x0d\xbf\xee\x04\x29\x2e\x93\x7f\x21\xc0\x05\xf1\x74\x11\x47\x30\x41",
+ "\xad\x9b\xf4\x20\xd2\xb5\x70\xeb\xe7\x92\x3a\x76\xb2\x53\xf1\x56\xf3\x51\x37\x12\x95\x5b\xcb\xb9\xa8\x73\x94\xdb",
+ 108 },
+ { GCRY_MD_SHA3_224,
+ "\x75\x8e\xa3\xfe\xa7\x38\x97\x3d\xb0\xb8\xbe\x7e\x59\x9b\xbe\xf4\x51\x93\x73\xd6\xe6\xdc\xd7\x19\x5e\xa8\x85\xfc\x99\x1d\x89\x67\x62\x99\x27\x59\xc2\xa0\x90\x02\x91\x2f\xb0\x8e\x0c\xb5\xb7\x6f\x49\x16\x2a\xeb\x8c\xf8\x7b\x17\x2c\xf3\xad\x19\x02\x53\xdf\x61\x2f\x77\xb1\xf0\xc5\x32\xe3\xb5\xfc\x99\xc2\xd3\x1f\x8f\x65\x01\x16\x95\xa0\x87\xa3\x5e\xe4\xee\xe5\xe3\x34\xc3\x69\xd8\xee\x5d\x29\xf6\x95\x81\x5d\x86\x6d\xa9\x9d\xf3\xf7\x94\x03",
+ "\x2f\x60\x92\x82\x63\xfe\x1d\x5f\xa5\x13\x6d\xa8\xde\x1d\x2c\x3b\x60\xbd\x4b\x70\x0a\x3e\x2c\x25\x6e\x95\x36\xef",
+ 109 },
+ { GCRY_MD_SHA3_224,
+ "\x47\xc6\xe0\xc2\xb7\x49\x48\x46\x59\x21\x86\x88\x04\xf0\xf7\xbd\x50\xdd\x32\x35\x83\xdc\x78\x4f\x99\x8a\x93\xcd\x1c\xa4\xc6\xef\x84\xd4\x1d\xc8\x1c\x2c\x40\xf3\x4b\x5b\xee\x6a\x93\x86\x7b\x3b\xdb\xa0\x05\x2c\x5f\x59\xe6\xf3\x65\x79\x18\xc3\x82\xe7\x71\xd3\x31\x09\x12\x2c\xc8\xbb\x0e\x1e\x53\xc4\xe3\xd1\x3b\x43\xce\x44\x97\x0f\x5e\x0c\x07\x9d\x2a\xd7\xd7\xa3\x54\x9c\xd7\x57\x60\xc2\x1b\xb1\x5b\x44\x75\x89\xe8\x6e\x8d\x76\xb1\xe9\xce\xd2",
+ "\xbf\xb4\x0f\x7e\x7f\x81\xf2\xfe\xc7\x64\x4e\x08\xfb\xc9\x9c\x76\x8a\xdc\x63\x14\xb8\xcc\xd8\x33\x33\x2f\x1b\xf8",
+ 110 },
+ { GCRY_MD_SHA3_224,
+ "\xf6\x90\xa1\x32\xab\x46\xb2\x8e\xdf\xa6\x47\x92\x83\xd6\x44\x4e\x37\x1c\x64\x59\x10\x8a\xfd\x9c\x35\xdb\xd2\x35\xe0\xb6\xb6\xff\x4c\x4e\xa5\x8e\x75\x54\xbd\x00\x24\x60\x43\x3b\x21\x64\xca\x51\xe8\x68\xf7\x94\x7d\x7d\x7a\x0d\x79\x2e\x4a\xbf\x0b\xe5\xf4\x50\x85\x3c\xc4\x0d\x85\x48\x5b\x2b\x88\x57\xea\x31\xb5\xea\x6e\x4c\xcf\xa2\xf3\xa7\xef\x33\x80\x06\x6d\x7d\x89\x79\xfd\xac\x61\x8a\xad\x3d\x7e\x88\x6d\xea\x4f\x00\x5a\xe4\xad\x05\xe5\x06\x5f",
+ "\x19\x0e\x9f\xda\x8a\x7d\x78\x34\x3f\xf2\x4a\xde\x9f\xee\x69\x65\x0c\x76\x31\xad\x63\x29\xd1\x7d\x4b\xd5\x75\xdb",
+ 111 },
+ { GCRY_MD_SHA3_224,
+ "\x58\xd6\xa9\x9b\xc6\x45\x88\x24\xb2\x56\x91\x67\x70\xa8\x41\x70\x40\x72\x1c\xcc\xfd\x4b\x79\xea\xcd\x8b\x65\xa3\x76\x7c\xe5\xba\x7e\x74\x10\x4c\x98\x5a\xc5\x6b\x8c\xc9\xae\xbd\x16\xfe\xbd\x4c\xda\x5a\xdb\x13\x0b\x0f\xf2\x32\x9c\xc8\xd6\x11\xeb\x14\xda\xc2\x68\xa2\xf9\xe6\x33\xc9\x9d\xe3\x39\x97\xfe\xa4\x1c\x52\xa7\xc5\xe1\x31\x7d\x5b\x5d\xae\xd3\x5e\xba\x7d\x5a\x60\xe4\x5d\x1f\xa7\xea\xab\xc3\x5f\x5c\x2b\x0a\x0f\x23\x79\x23\x19\x53\x32\x2c\x4e",
+ "\xe2\x6c\xd2\x0b\x87\x08\x3c\xb9\xf2\x46\xd2\x16\xe3\xda\x51\xef\x7c\x55\x19\xb4\x83\xdb\x43\x9d\x37\x25\x6d\xbe",
+ 112 },
+ { GCRY_MD_SHA3_224,
+ "\xbe\xfa\xb5\x74\x39\x6d\x7f\x8b\x67\x05\xe2\xd5\xb5\x8b\x2c\x1c\x82\x0b\xb2\x4e\x3f\x4b\xae\x3e\x8f\xbc\xd3\x6d\xbf\x73\x4e\xe1\x4e\x5d\x6a\xb9\x72\xae\xdd\x35\x40\x23\x54\x66\xe8\x25\x85\x0e\xe4\xc5\x12\xea\x97\x95\xab\xfd\x33\xf3\x30\xd9\xfd\x7f\x79\xe6\x2b\xbb\x63\xa6\xea\x85\xde\x15\xbe\xae\xea\x6f\x8d\x20\x4a\x28\x95\x60\x59\xe2\x63\x2d\x11\x86\x1d\xfb\x0e\x65\xbc\x07\xac\x8a\x15\x93\x88\xd5\xc3\x27\x7e\x22\x72\x86\xf6\x5f\xf5\xe5\xb5\xae\xc1",
+ "\x6c\xaf\x80\x7f\x6a\xbc\x1a\x77\x21\xa5\xf2\x09\xfc\x09\xfd\x00\x47\x4b\x9e\x2a\x77\xef\x7b\x57\xe1\x32\x02\x71",
+ 113 },
+ { GCRY_MD_SHA3_224,
+ "\x8e\x58\x14\x4f\xa9\x17\x9d\x68\x64\x78\x62\x2c\xe4\x50\xc7\x48\x26\x0c\x95\xd1\xba\x43\xb8\xf9\xb5\x9a\xbe\xca\x8d\x93\x48\x8d\xa7\x34\x63\xef\x40\x19\x8b\x4d\x16\xfb\x0b\x07\x07\x20\x13\x47\xe0\x50\x6f\xf1\x9d\x01\xbe\xa0\xf4\x2b\x8a\xf9\xe7\x1a\x1f\x1b\xd1\x68\x78\x10\x69\xd4\xd3\x38\xfd\xef\x00\xbf\x41\x9f\xbb\x00\x30\x31\xdf\x67\x1f\x4a\x37\x97\x95\x64\xf6\x92\x82\xde\x9c\x65\x40\x78\x47\xdd\x0d\xa5\x05\xab\x16\x41\xc0\x2d\xea\x4f\x0d\x83\x49\x86",
+ "\x64\xcd\x52\x91\xa1\xa0\x80\x7b\xa7\xc1\x41\x03\xa0\xf4\x6c\x63\x67\x95\xf8\xf8\xd3\xa1\x2e\x59\xe8\x8d\x9c\x51",
+ 114 },
+ { GCRY_MD_SHA3_224,
+ "\xb5\x5c\x10\xea\xe0\xec\x68\x4c\x16\xd1\x34\x63\xf2\x92\x91\xbf\x26\xc8\x2e\x2f\xa0\x42\x2a\x99\xc7\x1d\xb4\xaf\x14\xdd\x9c\x7f\x33\xed\xa5\x2f\xd7\x3d\x01\x7c\xc0\xf2\xdb\xe7\x34\xd8\x31\xf0\xd8\x20\xd0\x6d\x5f\x89\xda\xcc\x48\x57\x39\x14\x4f\x8c\xfd\x47\x99\x22\x3b\x1a\xff\x90\x31\xa1\x05\xcb\x6a\x02\x9b\xa7\x1e\x6e\x58\x67\xd8\x5a\x55\x49\x91\xc3\x8d\xf3\xc9\xef\x8c\x1e\x1e\x9a\x76\x30\xbe\x61\xca\xab\xca\x69\x28\x0c\x39\x9c\x1f\xb7\xa1\x2d\x12\xae\xfc",
+ "\x29\x49\x12\x56\xa8\x0b\xf1\xa9\x32\x53\x48\xb5\x84\x1e\xdc\x72\x6f\xa8\xa5\x31\x17\x26\x8c\x47\xf7\x4b\x5e\x49",
+ 115 },
+ { GCRY_MD_SHA3_224,
+ "\x2e\xee\xa6\x93\xf5\x85\xf4\xed\x6f\x6f\x88\x65\xbb\xae\x47\xa6\x90\x8a\xec\xd7\xc4\x29\xe4\xbe\xc4\xf0\xde\x1d\x0c\xa0\x18\x3f\xa2\x01\xa0\xcb\x14\xa5\x29\xb7\xd7\xac\x0e\x6f\xf6\x60\x7a\x32\x43\xee\x9f\xb1\x1b\xcf\x3e\x23\x04\xfe\x75\xff\xcd\xdd\x6c\x5c\x2e\x2a\x4c\xd4\x5f\x63\xc9\x62\xd0\x10\x64\x50\x58\xd3\x65\x71\x40\x4a\x6d\x2b\x4f\x44\x75\x54\x34\xd7\x69\x98\xe8\x34\x09\xc3\x20\x5a\xa1\x61\x5d\xb4\x40\x57\xdb\x99\x12\x31\xd2\xcb\x42\x62\x45\x74\xf5\x45",
+ "\xa5\x23\x44\x9b\x77\x0a\x8d\xe3\xb3\x9c\xd4\x46\x04\x61\x49\xfe\xae\xe3\x27\xd6\xd5\xb3\x99\x29\xb9\xaa\xc9\x15",
+ 116 },
+ { GCRY_MD_SHA3_224,
+ "\xda\xb1\x1d\xc0\xb0\x47\xdb\x04\x20\xa5\x85\xf5\x6c\x42\xd9\x31\x75\x56\x28\x52\x42\x84\x99\xf6\x6a\x0d\xb8\x11\xfc\xdd\xda\xb2\xf7\xcd\xff\xed\x15\x43\xe5\xfb\x72\x11\x0b\x64\x68\x6b\xc7\xb6\x88\x7a\x53\x8a\xd4\x4c\x05\x0f\x1e\x42\x63\x1b\xc4\xec\x8a\x9f\x2a\x04\x71\x63\xd8\x22\xa3\x89\x89\xee\x4a\xab\x01\xb4\xc1\xf1\x61\xb0\x62\xd8\x73\xb1\xcf\xa3\x88\xfd\x30\x15\x14\xf6\x22\x24\x15\x7b\x9b\xef\x42\x3c\x77\x83\xb7\xaa\xc8\xd3\x0d\x65\xcd\x1b\xba\x8d\x68\x9c\x2d",
+ "\xab\xb2\xfc\xe2\x13\xce\x16\x4c\x94\xab\x7a\x76\x3c\x21\xf6\x38\xa3\xbb\x8d\x72\xf8\x02\xde\xad\xac\xc0\x23\xae",
+ 117 },
+ { GCRY_MD_SHA3_224,
+ "\x42\xe9\x9a\x2f\x80\xae\xe0\xe0\x01\x27\x9a\x24\x34\xf7\x31\xe0\x1d\x34\xa4\x4b\x1a\x81\x01\x72\x69\x21\xc0\x59\x0c\x30\xf3\x12\x0e\xb8\x30\x59\xf3\x25\xe8\x94\xa5\xac\x95\x9d\xca\x71\xce\x22\x14\x79\x99\x16\x42\x4e\x85\x9d\x27\xd7\x89\x43\x7b\x9d\x27\x24\x0b\xf8\xc3\x5a\xdb\xaf\xce\xcc\x32\x2b\x48\xaa\x20\x5b\x29\x39\x62\xd8\x58\x65\x2a\xba\xcb\xd5\x88\xbc\xf6\xcb\xc3\x88\xd0\x99\x3b\xd6\x22\xf9\x6e\xd5\x46\x14\xc2\x5b\x6a\x9a\xa5\x27\x58\x9e\xaa\xff\xcf\x17\xdd\xf7",
+ "\xc4\x0d\x96\x9f\x72\x18\xd7\x1b\x90\x4c\x4e\x4e\xac\xeb\x04\x73\xba\x0a\x2e\x73\x39\x64\x9d\xa5\xdf\xeb\x89\x38",
+ 118 },
+ { GCRY_MD_SHA3_224,
+ "\x3c\x9b\x46\x45\x0c\x0f\x2c\xae\x8e\x38\x23\xf8\xbd\xb4\x27\x7f\x31\xb7\x44\xce\x2e\xb1\x70\x54\xbd\xdc\x6d\xff\x36\xaf\x7f\x49\xfb\x8a\x23\x20\xcc\x3b\xdf\x8e\x0a\x2e\xa2\x9a\xd3\xa5\x5d\xe1\x16\x5d\x21\x9a\xde\xdd\xb5\x17\x52\x53\xe2\xd1\x48\x9e\x9b\x6f\xdd\x02\xe2\xc3\xd3\xa4\xb5\x4d\x60\xe3\xa4\x73\x34\xc3\x79\x13\xc5\x69\x53\x78\xa6\x69\xe9\xb7\x2d\xec\x32\xaf\x54\x34\xf9\x3f\x46\x17\x6e\xbf\x04\x4c\x47\x84\x46\x7c\x70\x04\x70\xd0\xc0\xb4\x0c\x8a\x08\x8c\x81\x58\x16",
+ "\x2e\xb2\x8f\xdf\x45\x8d\x4f\xec\xb5\xb4\x41\xd9\x10\xb5\x76\xf6\x30\xe6\x66\xbb\xf3\x0a\xac\x90\xab\x64\x42\x5b",
+ 119 },
+ { GCRY_MD_SHA3_224,
+ "\xd1\xe6\x54\xb7\x7c\xb1\x55\xf5\xc7\x79\x71\xa6\x4d\xf9\xe5\xd3\x4c\x26\xa3\xca\xd6\xc7\xf6\xb3\x00\xd3\x9d\xeb\x19\x10\x09\x46\x91\xad\xaa\x09\x5b\xe4\xba\x5d\x86\x69\x0a\x97\x64\x28\x63\x5d\x55\x26\xf3\xe9\x46\xf7\xdc\x3b\xd4\xdb\xc7\x89\x99\xe6\x53\x44\x11\x87\xa8\x1f\x9a\xdc\xd5\xa3\xc5\xf2\x54\xbc\x82\x56\xb0\x15\x8f\x54\x67\x3d\xcc\x12\x32\xf6\xe9\x18\xeb\xfc\x6c\x51\xce\x67\xea\xeb\x04\x2d\x9f\x57\xee\xc4\xbf\xe9\x10\xe1\x69\xaf\x78\xb3\xde\x48\xd1\x37\xdf\x4f\x28\x40",
+ "\xa3\x38\x7b\x2f\xa2\x3a\x13\xbf\xae\x77\x89\x5f\x1f\x93\x93\x5a\x07\x10\xee\x3a\x02\x7f\xf0\xd6\x39\x9d\x8e\xcc",
+ 120 },
+ { GCRY_MD_SHA3_224,
+ "\x62\x6f\x68\xc1\x8a\x69\xa6\x59\x01\x59\xa9\xc4\x6b\xe0\x3d\x59\x65\x69\x8f\x2d\xac\x3d\xe7\x79\xb8\x78\xb3\xd9\xc4\x21\xe0\xf2\x1b\x95\x5a\x16\xc7\x15\xc1\xec\x1e\x22\xce\x3e\xb6\x45\xb8\xb4\xf2\x63\xf6\x06\x60\xea\x30\x28\x98\x1e\xeb\xd6\xc8\xc3\xa3\x67\x28\x5b\x69\x1c\x8e\xe5\x69\x44\xa7\xcd\x12\x17\x99\x7e\x1d\x9c\x21\x62\x0b\x53\x6b\xdb\xd5\xde\x89\x25\xff\x71\xde\xc6\xfb\xc0\x66\x24\xab\x6b\x21\xe3\x29\x81\x3d\xe9\x0d\x1e\x57\x2d\xfb\x89\xa1\x81\x20\xc3\xf6\x06\x35\x5d\x25",
+ "\x75\x75\x5f\x46\xc2\xfc\x86\xbd\x4a\xae\x75\x91\x9c\x6c\xa5\xb1\xa7\x37\x5e\x46\x6c\xa3\x17\x0f\x70\xee\xe4\x90",
+ 121 },
+ { GCRY_MD_SHA3_224,
+ "\x65\x1a\x6f\xb3\xc4\xb8\x0c\x7c\x68\xc6\x01\x16\x75\xe6\x09\x4e\xb5\x6a\xbf\x5f\xc3\x05\x73\x24\xeb\xc6\x47\x78\x25\x06\x1f\x9f\x27\xe7\xa9\x46\x33\xab\xd1\xfa\x59\x8a\x74\x6e\x4a\x57\x7c\xaf\x52\x4c\x52\xec\x17\x88\x47\x1f\x92\xb8\xc3\x7f\x23\x79\x5c\xa1\x9d\x55\x9d\x44\x6c\xab\x16\xcb\xcd\xce\x90\xb7\x9f\xa1\x02\x6c\xee\x77\xbf\x4a\xb1\xb5\x03\xc5\xb9\x4c\x22\x56\xad\x75\xb3\xea\xc6\xfd\x5d\xcb\x96\xac\xa4\xb0\x3a\x83\x4b\xfb\x4e\x9a\xf9\x88\xce\xcb\xf2\xae\x59\x7c\xb9\x09\x79\x40",
+ "\x71\x84\xc6\x9e\xe1\xc4\x3f\xd5\x64\x10\x2c\xd6\x8e\xf8\x98\xd5\xd0\xd8\x26\x4b\x9b\x0d\x04\x46\x91\xbc\x18\xaf",
+ 122 },
+ { GCRY_MD_SHA3_224,
+ "\x8a\xaf\x07\x2f\xce\x8a\x2d\x96\xbc\x10\xb3\xc9\x1c\x80\x9e\xe9\x30\x72\xfb\x20\x5c\xa7\xf1\x0a\xbd\x82\xec\xd8\x2c\xf0\x40\xb1\xbc\x49\xea\x13\xd1\x85\x78\x15\xc0\xe9\x97\x81\xde\x3a\xdb\xb5\x44\x3c\xe1\xc8\x97\xe5\x51\x88\xce\xaf\x22\x1a\xa9\x68\x16\x38\xde\x05\xae\x1b\x32\x29\x38\xf4\x6b\xce\x51\x54\x3b\x57\xec\xdb\x4c\x26\x62\x72\x25\x9d\x17\x98\xde\x13\xbe\x90\xe1\x0e\xfe\xc2\xd0\x74\x84\xd9\xb2\x1a\x38\x70\xe2\xaa\x9e\x06\xc2\x1a\xa2\xd0\xc9\xcf\x42\x00\x80\xa8\x0a\x91\xde\xe1\x6f",
+ "\xf5\x0c\xf7\x8f\xf4\x65\x13\xc9\x05\x39\x9c\xc2\x51\x06\x81\xa9\x0c\xe0\x89\xfc\xed\x40\xfb\xc9\xcf\x21\x8c\xa4",
+ 123 },
+ { GCRY_MD_SHA3_224,
+ "\x53\xf9\x18\xfd\x00\xb1\x70\x1b\xd5\x04\xf8\xcd\xea\x80\x3a\xcc\xa2\x1a\xc1\x8c\x56\x4a\xb9\x0c\x2a\x17\xda\x59\x2c\x7d\x69\x68\x8f\x65\x80\x57\x53\x95\x55\x1e\x8c\xd3\x3e\x0f\xef\x08\xca\x6e\xd4\x58\x8d\x4d\x14\x0b\x3e\x44\xc0\x32\x35\x5d\xf1\xc5\x31\x56\x4d\x7f\x48\x35\x75\x33\x44\x34\x5a\x67\x81\xe1\x1c\xd5\xe0\x95\xb7\x3d\xf5\xf8\x2c\x8a\xe3\xad\x00\x87\x79\x36\x89\x66\x71\xe9\x47\xcc\x52\xe2\xb2\x9d\xcd\x46\x3d\x90\xa0\xc9\x92\x91\x28\xda\x22\x2b\x5a\x21\x14\x50\xbb\xc0\xe0\x24\x48\xe2",
+ "\xf2\xaa\xbe\x18\xd7\xb4\xdd\x8e\x4d\xc0\xac\x8d\xcf\x4e\x90\x19\xc7\xc9\xaf\x33\xd4\xb9\x52\xda\x41\x21\x9f\xe5",
+ 124 },
+ { GCRY_MD_SHA3_224,
+ "\xa6\x45\x99\xb8\xa6\x1b\x5c\xce\xc9\xe6\x7a\xed\x69\x44\x74\x59\xc8\xda\x3d\x1e\xc6\xc7\xc7\xc8\x2a\x74\x28\xb9\xb5\x84\xfa\x67\xe9\x0f\x68\xe2\xc0\x0f\xbb\xed\x46\x13\x66\x6e\x51\x68\xda\x4a\x16\xf3\x95\xf7\xa3\xc3\x83\x2b\x3b\x13\x4b\xfc\x9c\xba\xa9\x5d\x2a\x0f\xe2\x52\xf4\x4a\xc6\x68\x1e\xb6\xd4\x0a\xb9\x1c\x1d\x02\x82\xfe\xd6\x70\x1c\x57\x46\x3d\x3c\x5f\x2b\xb8\xc6\xa7\x30\x1f\xb4\x57\x6a\xa3\xb5\xf1\x55\x10\xdb\x89\x56\xff\x77\x47\x8c\x26\xa7\xc0\x9b\xea\x7b\x39\x8c\xfc\x83\x50\x3f\x53\x8e",
+ "\xac\x5d\x00\xd1\x77\xe7\x1d\x7b\x9a\x97\x27\x0e\x62\x00\xe4\xd3\xd0\x78\x51\xeb\x2e\x58\xb1\x2b\xe0\xbe\xed\x95",
+ 125 },
+ { GCRY_MD_SHA3_224,
+ "\x0e\x3a\xb0\xe0\x54\x73\x9b\x00\xcd\xb6\xa8\x7b\xd1\x2c\xae\x02\x4b\x54\xcb\x5e\x55\x0e\x6c\x42\x53\x60\xc2\xe8\x7e\x59\x40\x1f\x5e\xc2\x4e\xf0\x31\x48\x55\xf0\xf5\x6c\x47\x69\x5d\x56\xa7\xfb\x14\x17\x69\x3a\xf2\xa1\xed\x52\x91\xf2\xfe\xe9\x5f\x75\xee\xd5\x4a\x1b\x1c\x2e\x81\x22\x6f\xbf\xf6\xf6\x3a\xde\x58\x49\x11\xc7\x19\x67\xa8\xeb\x70\x93\x3b\xc3\xf5\xd1\x5b\xc9\x1b\x5c\x26\x44\xd9\x51\x6d\x3c\x3a\x8c\x15\x4e\xe4\x8e\x11\x8b\xd1\x44\x2c\x04\x3c\x7a\x0d\xba\x5a\xc5\xb1\xd5\x36\x0a\xae\x5b\x90\x65",
+ "\xcb\x79\x79\xb4\xc6\xc2\x82\x6c\xde\xf7\xe1\xaa\xda\x85\xf8\xc4\x54\x6d\xd5\x9d\x29\xfc\x0a\xea\x44\x4f\x80\x77",
+ 126 },
+ { GCRY_MD_SHA3_224,
+ "\xa6\x2f\xc5\x95\xb4\x09\x6e\x63\x36\xe5\x3f\xcd\xfc\x8d\x1c\xc1\x75\xd7\x1d\xac\x9d\x75\x0a\x61\x33\xd2\x31\x99\xea\xac\x28\x82\x07\x94\x4c\xea\x6b\x16\xd2\x76\x31\x91\x5b\x46\x19\xf7\x43\xda\x2e\x30\xa0\xc0\x0b\xbd\xb1\xbb\xb3\x5a\xb8\x52\xef\x3b\x9a\xec\x6b\x0a\x8d\xcc\x6e\x9e\x1a\xba\xa3\xad\x62\xac\x0a\x6c\x5d\xe7\x65\xde\x2c\x37\x11\xb7\x69\xe3\xfd\xe4\x4a\x74\x01\x6f\xff\x82\xac\x46\xfa\x8f\x17\x97\xd3\xb2\xa7\x26\xb6\x96\xe3\xde\xa5\x53\x04\x39\xac\xee\x3a\x45\xc2\xa5\x1b\xc3\x2d\xd0\x55\x65\x0b",
+ "\xf9\xd8\xcc\xf6\x68\x46\x93\xc4\x0c\x81\xeb\xbd\x00\x6c\x49\x98\x4f\xba\xf3\xa2\xb2\xe9\x05\xab\xe6\x07\x65\xdd",
+ 127 },
+ { GCRY_MD_SHA3_224,
+ "\x2b\x6d\xb7\xce\xd8\x66\x5e\xbe\x9d\xeb\x08\x02\x95\x21\x84\x26\xbd\xaa\x7c\x6d\xa9\xad\xd2\x08\x89\x32\xcd\xff\xba\xa1\xc1\x41\x29\xbc\xcd\xd7\x0f\x36\x9e\xfb\x14\x92\x85\x85\x8d\x2b\x1d\x15\x5d\x14\xde\x2f\xdb\x68\x0a\x8b\x02\x72\x84\x05\x51\x82\xa0\xca\xe2\x75\x23\x4c\xc9\xc9\x28\x63\xc1\xb4\xab\x66\xf3\x04\xcf\x06\x21\xcd\x54\x56\x5f\x5b\xff\x46\x1d\x3b\x46\x1b\xd4\x0d\xf2\x81\x98\xe3\x73\x25\x01\xb4\x86\x0e\xad\xd5\x03\xd2\x6d\x6e\x69\x33\x8f\x4e\x04\x56\xe9\xe9\xba\xf3\xd8\x27\xae\x68\x5f\xb1\xd8\x17",
+ "\xed\x1f\x63\x87\xa7\xbe\x09\x02\x77\xb6\x5a\x5f\xcd\x70\x40\xc7\xbe\x0e\xea\xf0\xfd\x7f\x14\x96\x80\x97\x87\x3b",
+ 128 },
+ { GCRY_MD_SHA3_224,
+ "\x10\xdb\x50\x9b\x2c\xdc\xab\xa6\xc0\x62\xae\x33\xbe\x48\x11\x6a\x29\xeb\x18\xe3\x90\xe1\xbb\xad\xa5\xca\x0a\x27\x18\xaf\xbc\xd2\x34\x31\x44\x01\x06\x59\x48\x93\x04\x3c\xc7\xf2\x62\x52\x81\xbf\x7d\xe2\x65\x58\x80\x96\x6a\x23\x70\x5f\x0c\x51\x55\xc2\xf5\xcc\xa9\xf2\xc2\x14\x2e\x96\xd0\xa2\xe7\x63\xb7\x06\x86\xcd\x42\x1b\x5d\xb8\x12\xda\xce\xd0\xc6\xd6\x50\x35\xfd\xe5\x58\xe9\x4f\x26\xb3\xe6\xdd\xe5\xbd\x13\x98\x0c\xc8\x02\x92\xb7\x23\x01\x3b\xd0\x33\x28\x45\x84\xbf\xf2\x76\x57\x87\x1b\x0c\xf0\x7a\x84\x9f\x4a\xe2",
+ "\x0a\x27\xce\x69\x73\xcb\x22\xa8\xb1\x00\x57\xa8\xe7\xa6\x54\x05\x8b\x71\xe6\xd8\xc6\x9c\x65\x34\x15\xff\x0c\x81",
+ 129 },
+ { GCRY_MD_SHA3_224,
+ "\x93\x34\xde\x60\xc9\x97\xbd\xa6\x08\x61\x01\xa6\x31\x4f\x64\xe4\x45\x8f\x5f\xf9\x45\x0c\x50\x9d\xf0\x06\xe8\xc5\x47\x98\x3c\x65\x1c\xa9\x78\x79\x17\x5a\xab\xa0\xc5\x39\xe8\x2d\x05\xc1\xe0\x2c\x48\x09\x75\xcb\xb3\x01\x18\x12\x10\x61\xb1\xeb\xac\x4f\x8d\x9a\x37\x81\xe2\xdb\x6b\x18\x04\x2e\x01\xec\xf9\x01\x7a\x64\xa0\xe5\x74\x47\xec\x7f\xcb\xe6\xa7\xf8\x25\x85\xf7\x40\x3e\xe2\x22\x3d\x52\xd3\x7b\x4b\xf4\x26\x42\x86\x13\xd6\xb4\x25\x79\x80\x97\x2a\x0a\xca\xb5\x08\xa7\x62\x0c\x1c\xb2\x8e\xb4\xe9\xd3\x0f\xc4\x13\x61\xec",
+ "\xbe\x3b\xe4\x99\x80\xf4\x3f\xb6\x59\x8b\xe9\x21\xd7\xd8\xfd\xa1\xf3\x97\xf6\x05\xd9\x70\x8c\x5d\x12\x5c\x4e\x9f",
+ 130 },
+ { GCRY_MD_SHA3_224,
+ "\xe8\x8a\xb0\x86\x89\x16\x93\xaa\x53\x5c\xeb\x20\xe6\x4c\x7a\xb9\x7c\x7d\xd3\x54\x8f\x37\x86\x33\x98\x97\xa5\xf0\xc3\x90\x31\x54\x9c\xa8\x70\x16\x6e\x47\x77\x43\xcc\xfb\xe0\x16\xb4\x42\x8d\x89\x73\x8e\x42\x6f\x5f\xfe\x81\x62\x61\x37\xf1\x7a\xec\xff\x61\xb7\x2d\xbe\xe2\xdc\x20\x96\x18\x80\xcf\xe2\x81\xdf\xab\x5e\xe3\x8b\x19\x21\x88\x14\x50\xe1\x60\x32\xde\x5e\x4d\x55\xad\x8d\x4f\xca\x60\x97\x21\xb0\x69\x2b\xac\x79\xbe\x5a\x06\xe1\x77\xfe\x8c\x80\xc0\xc8\x35\x19\xfb\x33\x47\xde\x9f\x43\xd5\x56\x1c\xb8\x10\x7b\x9b\x5e\xdc",
+ "\x93\x21\x37\xbf\x2c\xd3\x2d\xdf\xd3\xba\x80\xc5\x25\x26\x87\x30\xb6\xf7\x45\x86\x01\xb5\x29\x6a\xeb\x32\x51\x83",
+ 131 },
+ { GCRY_MD_SHA3_224,
+ "\xfd\x19\xe0\x1a\x83\xeb\x6e\xc8\x10\xb9\x45\x82\xcb\x8f\xbf\xa2\xfc\xb9\x92\xb5\x36\x84\xfb\x74\x8d\x22\x64\xf0\x20\xd3\xb9\x60\xcb\x1d\x6b\x8c\x34\x8c\x2b\x54\xa9\xfc\xea\x72\x33\x0c\x2a\xaa\x9a\x24\xec\xdb\x00\xc4\x36\xab\xc7\x02\x36\x1a\x82\xbb\x88\x28\xb8\x53\x69\xb8\xc7\x2e\xce\x00\x82\xfe\x06\x55\x71\x63\x89\x9c\x2a\x0e\xfa\x46\x6c\x33\xc0\x43\x43\xa8\x39\x41\x70\x57\x39\x9a\x63\xa3\x92\x9b\xe1\xee\x48\x05\xd6\xce\x3e\x5d\x0d\x09\x67\xfe\x90\x04\x69\x6a\x56\x63\xf4\xca\xc9\x17\x90\x06\xa2\xce\xb7\x55\x42\xd7\x5d\x68",
+ "\x79\x66\x98\xce\x24\xef\xcd\xa8\x21\x4d\x16\x11\x38\xf3\xc7\xda\x6d\x76\x15\xe4\xcf\x1d\xac\x63\xb6\x99\x41\xf9",
+ 132 },
+ { GCRY_MD_SHA3_224,
+ "\x59\xae\x20\xb6\xf7\xe0\xb3\xc7\xa9\x89\xaf\xb2\x83\x24\xa4\x0f\xca\x25\xd8\x65\x1c\xf1\xf4\x6a\xe3\x83\xef\x6d\x84\x41\x58\x7a\xa1\xc0\x4c\x3e\x3b\xf8\x8e\x81\x31\xce\x61\x45\xcf\xb8\x97\x3d\x96\x1e\x84\x32\xb2\x02\xfa\x5a\xf3\xe0\x9d\x62\x5f\xaa\xd8\x25\xbc\x19\xda\x9b\x5c\x6c\x20\xd0\x2a\xbd\xa2\xfc\xc5\x8b\x5b\xd3\xfe\x50\x7b\xf2\x01\x26\x3f\x30\x54\x38\x19\x51\x0c\x12\xbc\x23\xe2\xdd\xb4\xf7\x11\xd0\x87\xa8\x6e\xdb\x1b\x35\x53\x13\x36\x3a\x2d\xe9\x96\xb8\x91\x02\x5e\x14\x70\x36\x08\x74\x01\xcc\xf3\xca\x78\x15\xbf\x3c\x49",
+ "\xb2\x16\x93\x0e\x15\x8d\x65\xfb\x1f\xf4\x24\xf9\xea\xb6\xcd\x28\x99\x62\x31\xef\x5e\xe1\xd6\x5d\xbe\x29\xd3\x70",
+ 133 },
+ { GCRY_MD_SHA3_224,
+ "\x77\xee\x80\x4b\x9f\x32\x95\xab\x23\x62\x79\x8b\x72\xb0\xa1\xb2\xd3\x29\x1d\xce\xb8\x13\x98\x96\x35\x58\x30\xf3\x4b\x3b\x32\x85\x61\x53\x1f\x80\x79\xb7\x9a\x6e\x99\x80\x70\x51\x50\x86\x64\x02\xfd\xc1\x76\xc0\x58\x97\xe3\x59\xa6\xcb\x1a\x7a\xb0\x67\x38\x3e\xb4\x97\x18\x2a\x7e\x5a\xef\x70\x38\xe4\xc9\x6d\x13\x3b\x27\x82\x91\x74\x17\xe3\x91\x53\x5b\x5e\x1b\x51\xf4\x7d\x8e\xd7\xe4\xd4\x02\x5f\xe9\x8d\xc8\x7b\x9c\x16\x22\x61\x4b\xff\x3d\x10\x29\xe6\x8e\x37\x2d\xe7\x19\x80\x38\x57\xca\x52\x06\x7c\xdd\xaa\xd9\x58\x95\x1c\xb2\x06\x8c\xc6",
+ "\xaf\x6c\x67\x6a\x62\x28\x8b\x2d\x25\xa8\x62\xf8\x86\x6b\x26\x2a\x74\xe3\xd2\xa0\xd4\x14\xb9\x66\xce\x60\x1e\x14",
+ 134 },
+ { GCRY_MD_SHA3_224,
+ "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+ "\x41\x8c\x83\xeb\x01\x88\x1b\x4f\x38\x54\x46\x65\x20\x1d\xd0\x5c\x93\x9c\xa0\x47\xd3\x18\x34\xf6\x37\x34\x23\x42",
+ 135 },
+ { GCRY_MD_SHA3_224,
+ "\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",
+ "\x64\xd7\x88\x17\x71\x4f\xe0\x52\x72\xd3\x80\x5e\x6e\x19\x05\x6b\x16\x49\x03\x6c\xdc\xd5\x09\x4f\xd1\xcc\x89\x0a",
+ 136 },
+ { GCRY_MD_SHA3_224,
+ "\x04\x41\x0e\x31\x08\x2a\x47\x58\x4b\x40\x6f\x05\x13\x98\xa6\xab\xe7\x4e\x4d\xa5\x9b\xb6\xf8\x5e\x6b\x49\xe8\xa1\xf7\xf2\xca\x00\xdf\xba\x54\x62\xc2\xcd\x2b\xfd\xe8\xb6\x4f\xb2\x1d\x70\xc0\x83\xf1\x13\x18\xb5\x6a\x52\xd0\x3b\x81\xca\xc5\xee\xc2\x9e\xb3\x1b\xd0\x07\x8b\x61\x56\x78\x6d\xa3\xd6\xd8\xc3\x30\x98\xc5\xc4\x7b\xb6\x7a\xc6\x4d\xb1\x41\x65\xaf\x65\xb4\x45\x44\xd8\x06\xdd\xe5\xf4\x87\xd5\x37\x3c\x7f\x97\x92\xc2\x99\xe9\x68\x6b\x7e\x58\x21\xe7\xc8\xe2\x45\x83\x15\xb9\x96\xb5\x67\x7d\x92\x6d\xac\x57\xb3\xf2\x2d\xa8\x73\xc6\x01\x01\x6a\x0d",
+ "\x2c\x4e\x7c\x53\x7d\x0e\x2a\xf2\x26\x1a\x66\x9b\xc2\x4b\xd0\xdf\x16\xd2\xc7\x2a\x7f\x98\xd7\xa5\xef\x6a\x81\x50",
+ 137 },
+ { GCRY_MD_SHA3_224,
+ "\x8b\x81\xe9\xba\xdd\xe0\x26\xf1\x4d\x95\xc0\x19\x97\x70\x24\xc9\xe1\x3d\xb7\xa5\xcd\x21\xf9\xe9\xfc\x49\x1d\x71\x61\x64\xbb\xac\xdc\x70\x60\xd8\x82\x61\x5d\x41\x14\x38\xae\xa0\x56\xc3\x40\xcd\xf9\x77\x78\x8f\x6e\x17\xd1\x18\xde\x55\x02\x68\x55\xf9\x32\x70\x47\x2d\x1f\xd1\x8b\x9e\x7e\x81\x2b\xae\x10\x7e\x0d\xfd\xe7\x06\x33\x01\xb7\x1f\x6c\xfe\x4e\x22\x5c\xab\x3b\x23\x29\x05\xa5\x6e\x99\x4f\x08\xee\x28\x91\xba\x92\x2d\x49\xc3\xda\xfe\xb7\x5f\x7c\x69\x75\x0c\xb6\x7d\x82\x2c\x96\x17\x6c\x46\xbd\x8a\x29\xf1\x70\x13\x73\xfb\x09\xa1\xa6\xe3\xc7\x15\x8f",
+ "\xdf\x1f\xcb\x80\xab\x38\x0c\xa3\x3b\xdb\x61\xf9\x6a\xda\xb3\x34\x93\x7e\x19\x0f\x03\xc1\xb7\x8b\x21\x9e\x50\xf8",
+ 138 },
+ { GCRY_MD_SHA3_224,
+ "\xfa\x6e\xed\x24\xda\x66\x66\xa2\x22\x08\x14\x6b\x19\xa5\x32\xc2\xec\x9b\xa9\x4f\x09\xf1\xde\xf1\xe7\xfc\x13\xc3\x99\xa4\x8e\x41\xac\xc2\xa5\x89\xd0\x99\x27\x62\x96\x34\x8f\x39\x62\x53\xb5\x7c\xb0\xe4\x02\x91\xbd\x28\x27\x73\x65\x6b\x6e\x0d\x8b\xea\x1c\xda\x08\x4a\x37\x38\x81\x6a\x84\x04\x85\xfc\xf3\xfb\x30\x7f\x77\x7f\xa5\xfe\xac\x48\x69\x5c\x2a\xf4\x76\x97\x20\x25\x8c\x77\x94\x3f\xb4\x55\x6c\x36\x2d\x9c\xba\x8b\xf1\x03\xae\xb9\x03\x4b\xaa\x8e\xa8\xbf\xb9\xc4\xf8\xe6\x74\x2c\xe0\xd5\x2c\x49\xea\x8e\x97\x4f\x33\x96\x12\xe8\x30\xe9\xe7\xa9\xc2\x90\x65",
+ "\x0d\xd7\x7a\xda\x38\x4c\xab\x6a\x7a\xce\xd1\x9c\xfc\x80\x48\xc2\x56\x6d\x43\x03\xe2\x01\x0c\x98\xd1\x6a\x05\x16",
+ 139 },
+ { GCRY_MD_SHA3_224,
+ "\x9b\xb4\xaf\x1b\x4f\x09\xc0\x71\xce\x3c\xaf\xa9\x2e\x4e\xb7\x3c\xe8\xa6\xf5\xd8\x2a\x85\x73\x34\x40\x36\x8d\xee\x4e\xb1\xcb\xc7\xb5\x5a\xc1\x50\x77\x3b\x6f\xe4\x7d\xbe\x03\x6c\x45\x58\x2e\xd6\x7e\x23\xf4\xc7\x45\x85\xda\xb5\x09\xdf\x1b\x83\x61\x05\x64\x54\x56\x42\xb2\xb1\xec\x46\x3e\x18\x04\x8f\xc2\x34\x77\xc6\xb2\xaa\x03\x55\x94\xec\xd3\x37\x91\xaf\x6a\xf4\xcb\xc2\xa1\x16\x6a\xba\x8d\x62\x8c\x57\xe7\x07\xf0\xb0\xe8\x70\x7c\xaf\x91\xcd\x44\xbd\xb9\x15\xe0\x29\x6e\x01\x90\xd5\x6d\x33\xd8\xdd\xe1\x0b\x5b\x60\x37\x78\x38\x97\x3c\x1d\x94\x3c\x22\xed\x33\x5e",
+ "\xb2\x56\xd0\xd6\xb6\xd6\xa7\x2e\x11\x3d\x10\x5a\xd9\x60\x1c\x91\x93\x3d\x53\xb2\x0a\x30\xd8\xe2\xcf\x33\xf9\x6d",
+ 140 },
+ { GCRY_MD_SHA3_224,
+ "\x21\x67\xf0\x21\x18\xcc\x62\x04\x3e\x90\x91\xa6\x47\xca\xdb\xed\x95\x61\x1a\x52\x1f\xe0\xd6\x4e\x85\x18\xf1\x6c\x80\x8a\xb2\x97\x72\x55\x98\xae\x29\x68\x80\xa7\x73\x60\x7a\x79\x8f\x7c\x3c\xfc\xe8\x0d\x25\x1e\xbe\xc6\x88\x50\x15\xf9\xab\xf7\xea\xab\xae\x46\x79\x8f\x82\xcb\x59\x26\xde\x5c\x23\xf4\x4a\x3f\x9f\x95\x34\xb3\xc6\xf4\x05\xb5\x36\x4c\x2f\x8a\x8b\xdc\x5c\xa4\x9c\x74\x9b\xed\x8c\xe4\xba\x48\x89\x70\x62\xae\x84\x24\xca\x6d\xde\x5f\x55\xc0\xe4\x2a\x95\xd1\xe2\x92\xca\x54\xfb\x46\xa8\x4f\xbc\x9c\xd8\x7f\x2d\x0c\x9e\x74\x48\xde\x30\x43\xae\x22\xfd\xd2\x29",
+ "\xb9\x5f\x72\x51\x25\x46\xe4\xaf\x68\x59\x31\x24\x67\x17\xbc\x48\x2b\xfe\x92\x27\x89\xa2\x6e\xef\x01\xbd\xe8\x2d",
+ 141 },
+ { GCRY_MD_SHA3_224,
+ "\x94\xb7\xfa\x0b\xc1\xc4\x4e\x94\x9b\x1d\x76\x17\xd3\x1b\x47\x20\xcb\xe7\xca\x57\xc6\xfa\x4f\x40\x94\xd4\x76\x15\x67\xe3\x89\xec\xc6\x4f\x69\x68\xe4\x06\x4d\xf7\x0d\xf8\x36\xa4\x7d\x0c\x71\x33\x36\xb5\x02\x8b\x35\x93\x0d\x29\xeb\x7a\x7f\x9a\x5a\xf9\xad\x5c\xf4\x41\x74\x5b\xae\xc9\xbb\x01\x4c\xee\xff\x5a\x41\xba\x5c\x1c\xe0\x85\xfe\xb9\x80\xba\xb9\xcf\x79\xf2\x15\x8e\x03\xef\x7e\x63\xe2\x9c\x38\xd7\x81\x6a\x84\xd4\xf7\x1e\x0f\x54\x8b\x7f\xc3\x16\x08\x5a\xe3\x8a\x06\x0f\xf9\xb8\xde\xc3\x6f\x91\xad\x9e\xbc\x0a\x5b\x6c\x33\x8c\xbb\x8f\x66\x59\xd3\x42\xa2\x43\x68\xcf",
+ "\x62\x82\x38\xa9\x53\x27\x27\xcc\x83\xf8\xfd\xce\xd1\x1d\x13\x8a\x17\xee\xe4\x82\x2c\x5d\x35\x49\x15\x7d\x6d\x5e",
+ 142 },
+ { GCRY_MD_SHA3_224,
+ "\xea\x40\xe8\x3c\xb1\x8b\x3a\x24\x2c\x1e\xcc\x6c\xcd\x0b\x78\x53\xa4\x39\xda\xb2\xc5\x69\xcf\xc6\xdc\x38\xa1\x9f\x5c\x90\xac\xbf\x76\xae\xf9\xea\x37\x42\xff\x3b\x54\xef\x7d\x36\xeb\x7c\xe4\xff\x1c\x9a\xb3\xbc\x11\x9c\xff\x6b\xe9\x3c\x03\xe2\x08\x78\x33\x35\xc0\xab\x81\x37\xbe\x5b\x10\xcd\xc6\x6f\xf3\xf8\x9a\x1b\xdd\xc6\xa1\xee\xd7\x4f\x50\x4c\xbe\x72\x90\x69\x0b\xb2\x95\xa8\x72\xb9\xe3\xfe\x2c\xee\x9e\x6c\x67\xc4\x1d\xb8\xef\xd7\xd8\x63\xcf\x10\xf8\x40\xfe\x61\x8e\x79\x36\xda\x3d\xca\x5c\xa6\xdf\x93\x3f\x24\xf6\x95\x4b\xa0\x80\x1a\x12\x94\xcd\x8d\x7e\x66\xdf\xaf\xec",
+ "\xab\x0f\xd3\x08\x59\x05\x74\xd6\xf6\x13\x02\x32\xd9\xfa\xfa\x9f\xfc\xfe\xa7\x85\x79\xa6\xa8\xf6\x7c\x59\x04\x20",
+ 143 },
+ { GCRY_MD_SHA3_224,
+ "\x15\x7d\x5b\x7e\x45\x07\xf6\x6d\x9a\x26\x74\x76\xd3\x38\x31\xe7\xbb\x76\x8d\x4d\x04\xcc\x34\x38\xda\x12\xf9\x01\x02\x63\xea\x5f\xca\xfb\xde\x25\x79\xdb\x2f\x6b\x58\xf9\x11\xd5\x93\xd5\xf7\x9f\xb0\x5f\xe3\x59\x6e\x3f\xa8\x0f\xf2\xf7\x61\xd1\xb0\xe5\x70\x80\x05\x5c\x11\x8c\x53\xe5\x3c\xdb\x63\x05\x52\x61\xd7\xc9\xb2\xb3\x9b\xd9\x0a\xcc\x32\x52\x0c\xbb\xdb\xda\x2c\x4f\xd8\x85\x6d\xbc\xee\x17\x31\x32\xa2\x67\x91\x98\xda\xf8\x30\x07\xa9\xb5\xc5\x15\x11\xae\x49\x76\x6c\x79\x2a\x29\x52\x03\x88\x44\x4e\xbe\xfe\x28\x25\x6f\xb3\x3d\x42\x60\x43\x9c\xba\x73\xa9\x47\x9e\xe0\x0c\x63",
+ "\xd5\x13\x42\x00\xdc\x98\xf4\xca\x48\x0c\xd2\x4d\x24\x49\x77\x37\x25\x2b\x55\x97\x7a\xe5\xa8\x69\xba\x27\x08\x9d",
+ 144 },
+ { GCRY_MD_SHA3_224,
+ "\x83\x6b\x34\xb5\x15\x47\x6f\x61\x3f\xe4\x47\xa4\xe0\xc3\xf3\xb8\xf2\x09\x10\xac\x89\xa3\x97\x70\x55\xc9\x60\xd2\xd5\xd2\xb7\x2b\xd8\xac\xc7\x15\xa9\x03\x53\x21\xb8\x67\x03\xa4\x11\xdd\xe0\x46\x6d\x58\xa5\x97\x69\x67\x2a\xa6\x0a\xd5\x87\xb8\x48\x1d\xe4\xbb\xa5\x52\xa1\x64\x57\x79\x78\x95\x01\xec\x53\xd5\x40\xb9\x04\x82\x1f\x32\xb0\xbd\x18\x55\xb0\x4e\x48\x48\xf9\xf8\xcf\xe9\xeb\xd8\x91\x1b\xe9\x57\x81\xa7\x59\xd7\xad\x97\x24\xa7\x10\x2d\xbe\x57\x67\x76\xb7\xc6\x32\xbc\x39\xb9\xb5\xe1\x90\x57\xe2\x26\x55\x2a\x59\x94\xc1\xdb\xb3\xb5\xc7\x87\x1a\x11\xf5\x53\x70\x11\x04\x4c\x53",
+ "\x49\x4c\xbc\x9b\x64\x9e\x48\xec\x5a\xd7\x36\x4a\xeb\x9c\x8e\xdf\x4a\x4f\x40\x07\x89\xef\x20\x3f\x7b\x81\x8a\x44",
+ 145 },
+ { GCRY_MD_SHA3_224,
+ "\xcc\x77\x84\xa4\x91\x2a\x7a\xb5\xad\x36\x20\xaa\xb2\x9b\xa8\x70\x77\xcd\x3c\xb8\x36\x36\xad\xc9\xf3\xdc\x94\xf5\x1e\xdf\x52\x1b\x21\x61\xef\x10\x8f\x21\xa0\xa2\x98\x55\x79\x81\xc0\xe5\x3c\xe6\xce\xd4\x5b\xdf\x78\x2c\x1e\xf2\x00\xd2\x9b\xab\x81\xdd\x64\x60\x58\x69\x64\xed\xab\x7c\xeb\xdb\xbe\xc7\x5f\xd7\x92\x50\x60\xf7\xda\x2b\x85\x3b\x2b\x08\x95\x88\xfa\x0f\x8c\x16\xec\x64\x98\xb1\x4c\x55\xdc\xee\x33\x5c\xb3\xa9\x1d\x69\x8e\x4d\x39\x3a\xb8\xe8\xea\xc0\x82\x5f\x8a\xde\xbe\xee\x19\x6d\xf4\x12\x05\xc0\x11\x67\x4e\x53\x42\x6c\xaa\x45\x3f\x8d\xe1\xcb\xb5\x79\x32\xb0\xb7\x41\xd4\xc6",
+ "\x7f\xf8\xa2\x8a\xb1\x20\x74\x10\x2a\xef\x3e\xfb\x89\x04\x28\x4b\x61\x72\x37\x32\x2a\x2b\xf7\x01\xc9\xfc\xfe\xfc",
+ 146 },
+ { GCRY_MD_SHA3_224,
+ "\x76\x39\xb4\x61\xff\xf2\x70\xb2\x45\x5a\xc1\xd1\xaf\xce\x78\x29\x44\xae\xa5\xe9\x08\x7e\xb4\xa3\x9e\xb9\x6b\xb5\xc3\xba\xaf\x0e\x86\x8c\x85\x26\xd3\x40\x4f\x94\x05\xe7\x9e\x77\xbf\xac\x5f\xfb\x89\xbf\x19\x57\xb5\x23\xe1\x7d\x34\x1d\x73\x23\xc3\x02\xea\x70\x83\x87\x2d\xd5\xe8\x70\x56\x94\xac\xdd\xa3\x6d\x5a\x1b\x89\x5a\xaa\x16\xec\xa6\x10\x4c\x82\x68\x85\x32\xc8\xbf\xe1\x79\x0b\x5d\xc9\xf4\xec\x5f\xe9\x5b\xae\xd3\x7e\x1d\x28\x7b\xe7\x10\x43\x1f\x1e\x5e\x8e\xe1\x05\xbc\x42\xed\x37\xd7\x4b\x1e\x55\x98\x4b\xf1\xc0\x9f\xe6\xa1\xfa\x13\xef\x3b\x96\xfa\xea\xed\x6a\x2a\x19\x50\xa1\x21\x53",
+ "\x50\xcd\xbe\xab\x4b\xba\xa0\x86\x1f\x3e\x36\x4a\xf5\x20\xf9\xd8\xb5\x4e\x79\xe3\x87\x1a\xbc\xa7\xbb\xb2\xba\xe5",
+ 147 },
+ { GCRY_MD_SHA3_224,
+ "\xeb\x65\x13\xfc\x61\xb3\x0c\xfb\xa5\x8d\x4d\x7e\x80\xf9\x4d\x14\x58\x90\x90\xcf\x1d\x80\xb1\xdf\x2e\x68\x08\x8d\xc6\x10\x49\x59\xba\x0d\x58\x3d\x58\x5e\x95\x78\xab\x0a\xec\x0c\xf3\x6c\x48\x43\x5e\xb5\x2e\xd9\xab\x4b\xbc\xe7\xa5\xab\xe6\x79\xc9\x7a\xe2\xdb\xe3\x5e\x8c\xc1\xd4\x5b\x06\xdd\xa3\xcf\x41\x86\x65\xc5\x7c\xbe\xe4\xbb\xb4\x7f\xa4\xca\xf7\x8f\x4e\xe6\x56\xfe\xc2\x37\xfe\x4e\xeb\xba\xfa\x20\x6e\x1e\xf2\xbd\x0e\xe4\xae\x71\xbd\x0e\x9b\x2f\x54\xf9\x1d\xaa\xdf\x1f\xeb\xfd\x70\x32\x38\x1d\x63\x6b\x73\x3d\xcb\x3b\xf7\x6f\xb1\x4e\x23\xaf\xf1\xf6\x8e\xd3\xdb\xcf\x75\xc9\xb9\x9c\x6f\x26",
+ "\x29\xb6\xb5\x23\xc8\x2f\x49\x90\x78\xc7\x36\x30\xba\x38\x22\x7b\xbd\x08\xef\x1a\x2d\x67\xb4\x25\xc0\x58\xde\xf5",
+ 148 },
+ { GCRY_MD_SHA3_224,
+ "\x15\x94\xd7\x4b\xf5\xdd\xe4\x44\x26\x5d\x4c\x04\xda\xd9\x72\x1f\xf3\xe3\x4c\xbf\x62\x2d\xaf\x34\x1f\xe1\x6b\x96\x43\x1f\x6c\x4d\xf1\xf7\x60\xd3\x4f\x29\x6e\xb9\x7d\x98\xd5\x60\xad\x52\x86\xfe\xc4\xdc\xe1\x72\x4f\x20\xb5\x4f\xd7\xdf\x51\xd4\xbf\x13\x7a\xdd\x65\x6c\x80\x54\x6f\xb1\xbf\x51\x6d\x62\xee\x82\xba\xa9\x92\x91\x0e\xf4\xcc\x18\xb7\x0f\x3f\x86\x98\x27\x6f\xcf\xb4\x4e\x0e\xc5\x46\xc2\xc3\x9c\xfd\x8e\xe9\x10\x34\xff\x93\x03\x05\x8b\x42\x52\x46\x2f\x86\xc8\x23\xeb\x15\xbf\x48\x1e\x6b\x79\xcc\x3a\x02\x21\x85\x95\xb3\x65\x8e\x8b\x37\x38\x2b\xd5\x04\x8e\xae\xd5\xfd\x02\xc3\x79\x44\xe7\x3b",
+ "\x93\xce\x0c\x8d\x43\x55\x30\x0d\x4e\x63\xd6\x59\x91\x29\xde\xa7\x42\x0e\x5b\x60\x9d\xbb\x35\xbe\x43\x2b\x12\xb5",
+ 149 },
+ { GCRY_MD_SHA3_224,
+ "\x4c\xfa\x12\x78\x90\x30\x26\xf6\x6f\xed\xd4\x13\x74\x55\x8b\xe1\xb5\x85\xd0\x3c\x5c\x55\xda\xc9\x43\x61\xdf\x28\x6d\x4b\xd3\x9c\x7c\xb8\x03\x7e\xd3\xb2\x67\xb0\x7c\x34\x66\x26\x44\x9d\x0c\xc5\xb0\xdd\x2c\xf2\x21\xf7\xe4\xc3\x44\x9a\x4b\xe9\x99\x85\xd2\xd5\xe6\x7b\xff\x29\x23\x35\x7d\xde\xab\x5a\xbc\xb4\x61\x9f\x3a\x3a\x57\xb2\xcf\x92\x8a\x02\x2e\xb2\x76\x76\xc6\xcf\x80\x56\x89\x00\x4f\xca\x4d\x41\xea\x6c\x2d\x0a\x47\x89\xc7\x60\x5f\x7b\xb8\x38\xdd\x88\x3b\x3a\xd3\xe6\x02\x7e\x77\x5b\xcf\x26\x28\x81\x42\x80\x99\xc7\xff\xf9\x5b\x14\xc0\x95\xea\x13\x0e\x0b\x99\x38\xa5\xe2\x2f\xc5\x26\x50\xf5\x91",
+ "\xd0\x28\x96\xd9\x57\xb5\x99\x86\x9f\x2b\x2a\x49\x92\xa4\x9e\xef\x7a\xb1\x30\x8f\x45\x6c\x78\xc8\x09\xbd\xac\x88",
+ 150 },
+ { GCRY_MD_SHA3_224,
+ "\xd3\xe6\x5c\xb9\x2c\xfa\x79\x66\x2f\x6a\xf4\x93\xd6\x96\xa0\x7c\xcf\x32\xaa\xad\xcc\xef\xf0\x6e\x73\xe8\xd9\xf6\xf9\x09\x20\x9e\x66\x71\x5d\x6e\x97\x87\x88\xc4\x9e\xfb\x90\x87\xb1\x70\xec\xf3\xaa\x86\xd2\xd4\xd1\xa0\x65\xae\x0e\xfc\x89\x24\xf3\x65\xd6\x76\xb3\xcb\x9e\x2b\xec\x91\x8f\xd9\x6d\x0b\x43\xde\xe8\x37\x27\xc9\xa9\x3b\xf5\x6c\xa2\xb2\xe5\x9a\xdb\xa8\x56\x96\x54\x6a\x81\x50\x67\xfc\x7a\x78\x03\x96\x29\xd4\x94\x8d\x15\x7e\x7b\x0d\x82\x6d\x1b\xf8\xe8\x12\x37\xba\xb7\x32\x13\x12\xfd\xaa\x4d\x52\x17\x44\xf9\x88\xdb\x6f\xdf\x04\x54\x9d\x0f\xdc\xa3\x93\xd6\x39\xc7\x29\xaf\x71\x6e\x9c\x8b\xba\x48",
+ "\x18\x1e\x23\x01\xf6\x29\xa5\x69\x27\x1b\xb7\x40\xd3\x2b\x1d\x3b\xd2\x5a\xcb\x17\x9e\x9a\xeb\xef\x98\x00\x9e\xd4",
+ 151 },
+ { GCRY_MD_SHA3_224,
+ "\x84\x2c\xc5\x83\x50\x45\x39\x62\x2d\x7f\x71\xe7\xe3\x18\x63\xa2\xb8\x85\xc5\x6a\x0b\xa6\x2d\xb4\xc2\xa3\xf2\xfd\x12\xe7\x96\x60\xdc\x72\x05\xca\x29\xa0\xdc\x0a\x87\xdb\x4d\xc6\x2e\xe4\x7a\x41\xdb\x36\xb9\xdd\xb3\x29\x3b\x9a\xc4\xba\xae\x7d\xf5\xc6\xe7\x20\x1e\x17\xf7\x17\xab\x56\xe1\x2c\xad\x47\x6b\xe4\x96\x08\xad\x2d\x50\x30\x9e\x7d\x48\xd2\xd8\xde\x4f\xa5\x8a\xc3\xcf\xea\xfe\xee\x48\xc0\xa9\xee\xc8\x84\x98\xe3\xef\xc5\x1f\x54\xd3\x00\xd8\x28\xdd\xdc\xcb\x9d\x0b\x06\xdd\x02\x1a\x29\xcf\x5c\xb5\xb2\x50\x69\x15\xbe\xb8\xa1\x19\x98\xb8\xb8\x86\xe0\xf9\xb7\xa8\x0e\x97\xd9\x1a\x7d\x01\x27\x0f\x9a\x77\x17",
+ "\x5c\xd0\x17\xb2\x69\xa6\x36\x6c\x78\x9d\x9c\xec\xae\xf3\xee\x9c\x35\x75\x18\x1a\x08\x42\x66\xd7\x8a\x02\x8d\xb7",
+ 152 },
+ { GCRY_MD_SHA3_224,
+ "\x6c\x4b\x0a\x07\x19\x57\x3e\x57\x24\x86\x61\xe9\x8f\xeb\xe3\x26\x57\x1f\x9a\x1c\xa8\x13\xd3\x63\x85\x31\xae\x28\xb4\x86\x0f\x23\xc3\xa3\xa8\xac\x1c\x25\x00\x34\xa6\x60\xe2\xd7\x1e\x16\xd3\xac\xc4\xbf\x9c\xe2\x15\xc6\xf1\x5b\x1c\x0f\xc7\xe7\x7d\x3d\x27\x15\x7e\x66\xda\x9c\xee\xc9\x25\x8f\x8f\x2b\xf9\xe0\x2b\x4a\xc9\x37\x93\xdd\x6e\x29\xe3\x07\xed\xe3\x69\x5a\x0d\xf6\x3c\xbd\xc0\xfc\x66\xfb\x77\x08\x13\xeb\x14\x9c\xa2\xa9\x16\x91\x1b\xee\x49\x02\xc4\x7c\x78\x02\xe6\x9e\x40\x5f\xe3\xc0\x4c\xeb\x55\x22\x79\x2a\x55\x03\xfa\x82\x9f\x70\x72\x72\x22\x66\x21\xf7\xc4\x88\xa7\x69\x8c\x0d\x69\xaa\x56\x1b\xe9\xf3\x78",
+ "\xac\x28\x0a\x21\x1c\x98\xa0\x7f\x6f\xcb\xb7\x19\xf2\x50\xe3\xe5\xa6\xba\x2c\x93\xa8\x33\x97\x6c\x9f\x31\x47\xeb",
+ 153 },
+ { GCRY_MD_SHA3_224,
+ "\x51\xb7\xdb\xb7\xce\x2f\xfe\xb4\x27\xa9\x1c\xcf\xe5\x21\x8f\xd4\x0f\x9e\x0b\x7e\x24\x75\x6d\x4c\x47\xcd\x55\x60\x60\x08\xbd\xc2\x7d\x16\x40\x09\x33\x90\x6f\xd9\xf3\x0e\xff\xdd\x48\x80\x02\x2d\x08\x11\x55\x34\x2a\xf3\xfb\x6c\xd5\x36\x72\xab\x7f\xb5\xb3\xa3\xbc\xbe\x47\xbe\x1f\xd3\xa2\x27\x8c\xae\x8a\x5f\xd6\x1c\x14\x33\xf7\xd3\x50\x67\x5d\xd2\x18\x03\x74\x6c\xad\xca\x57\x41\x30\xf0\x12\x00\x02\x4c\x63\x40\xab\x0c\xc2\xcf\x74\xf2\x23\x46\x69\xf3\x4e\x90\x09\xef\x2e\xb9\x48\x23\xd6\x2b\x31\x40\x7f\x4b\xa4\x6f\x1a\x1e\xec\x41\x64\x1e\x84\xd7\x77\x27\xb5\x9e\x74\x6b\x8a\x67\x1b\xef\x93\x6f\x05\xbe\x82\x07\x59\xfa",
+ "\xc2\x84\xc9\x30\x8a\x28\xb6\xd2\x9c\xca\xa7\x85\x3f\x8c\x41\xba\xdc\xdd\xbc\x1a\xa4\xe9\x94\x81\xa6\xee\x2f\x4d",
+ 154 },
+ { GCRY_MD_SHA3_224,
+ "\x83\x59\x9d\x93\xf5\x56\x1e\x82\x1b\xd0\x1a\x47\x23\x86\xbc\x2f\xf4\xef\xbd\x4a\xed\x60\xd5\x82\x1e\x84\xaa\xe7\x4d\x80\x71\x02\x98\x10\xf5\xe2\x86\xf8\xf1\x76\x51\xcd\x27\xda\x07\xb1\xeb\x43\x82\xf7\x54\xcd\x1c\x95\x26\x87\x83\xad\x09\x22\x0f\x55\x02\x84\x03\x70\xd4\x94\xbe\xb1\x71\x24\x22\x0f\x6a\xfc\xe9\x1e\xc8\xa0\xf5\x52\x31\xf9\x65\x24\x33\xe5\xce\x34\x89\xb7\x27\x71\x6c\xf4\xae\xba\x7d\xcd\xa2\x0c\xd2\x9a\xa9\xa8\x59\x20\x12\x53\xf9\x48\xdd\x94\x39\x5a\xba\x9e\x38\x52\xbd\x1d\x60\xdd\xa7\xae\x5d\xc0\x45\xb2\x83\xda\x00\x6e\x1c\xba\xd8\x3c\xc1\x32\x92\xa3\x15\xdb\x55\x53\x30\x5c\x62\x8d\xd0\x91\x14\x65\x97",
+ "\x3d\x9a\x97\x9b\x34\xd4\x55\x69\xe1\xc9\x8d\x09\xdc\x62\xd0\x36\x16\xc0\x25\x1c\x41\xa8\xb9\x01\x38\x75\x0f\x1e",
+ 155 },
+ { GCRY_MD_SHA3_224,
+ "\x2b\xe9\xbf\x52\x6c\x9d\x5a\x75\xd5\x65\xdd\x11\xef\x63\xb9\x79\xd0\x68\x65\x9c\x7f\x02\x6c\x08\xbe\xa4\xaf\x16\x1d\x85\xa4\x62\xd8\x0e\x45\x04\x0e\x91\xf4\x16\x5c\x07\x4c\x43\xac\x66\x13\x80\x31\x1a\x8c\xbe\xd5\x9c\xc8\xe4\xc4\x51\x8e\x80\xcd\x2c\x78\xab\x1c\xab\xf6\x6b\xff\x83\xea\xb3\xa8\x01\x48\x55\x03\x07\x31\x09\x50\xd0\x34\xa6\x28\x6c\x93\xa1\xec\xe8\x92\x9e\x63\x85\xc5\xe3\xbb\x6e\xa8\xa7\xc0\xfb\x6d\x63\x32\xe3\x20\xe7\x1c\xc4\xeb\x46\x2a\x2a\x62\xe2\xbf\xe0\x8f\x0c\xca\xd9\x3e\x61\xbe\xdb\x5d\xd0\xb7\x86\xa7\x28\xab\x66\x6f\x07\xe0\x57\x6d\x18\x9c\x92\xbf\x9f\xb2\x0d\xca\x49\xac\x2d\x39\x56\xd4\x73\x85\xe2",
+ "\x8d\xdc\x9f\x1e\x0f\x94\xc1\x24\x7a\x67\xd6\x11\x9a\x91\x69\x76\x2c\x6c\x7f\x1e\xc7\xf6\x11\xd6\x13\x53\xab\x30",
+ 156 },
+ { GCRY_MD_SHA3_224,
+ "\xca\x76\xd3\xa1\x25\x95\xa8\x17\x68\x26\x17\x00\x68\x48\x67\x55\x47\xd3\xe8\xf5\x0c\x22\x10\xf9\xaf\x90\x6c\x0e\x7c\xe5\x0b\x44\x60\x18\x6f\xe7\x04\x57\xa9\xe8\x79\xe7\x9f\xd4\xd1\xa6\x88\xc7\x0a\x34\x73\x61\xc8\x47\xba\x0d\xd6\xaa\x52\x93\x6e\xaf\x8e\x58\xa1\xbe\x2f\x5c\x1c\x70\x4e\x20\x14\x6d\x36\x6a\xeb\x38\x53\xbe\xd9\xde\x9b\xef\xe9\x56\x9a\xc8\xaa\xea\x37\xa9\xfb\x71\x39\xa1\xa1\xa7\xd5\xc7\x48\x60\x5a\x8d\xef\xb2\x97\x86\x9e\xbe\xdd\x71\xd6\x15\xa5\xda\x23\x49\x6d\x11\xe1\x1a\xbb\xb1\x26\xb2\x06\xfa\x0a\x77\x97\xee\x7d\xe1\x17\x98\x60\x12\xd0\x36\x2d\xce\xf7\x75\xc2\xfe\x14\x5a\xda\x6b\xda\x1c\xcb\x32\x6b\xf6\x44",
+ "\x46\xed\xa2\x62\x2d\x49\xb9\x14\x8b\x40\xb6\x01\x4c\x75\xa4\x08\x6e\xb9\xdd\x47\x40\xf0\xdd\x59\x1a\xca\x53\xb2",
+ 157 },
+ { GCRY_MD_SHA3_224,
+ "\xf7\x6b\x85\xdc\x67\x42\x10\x25\xd6\x4e\x93\x09\x6d\x1d\x71\x2b\x7b\xaf\x7f\xb0\x01\x71\x6f\x02\xd3\x3b\x21\x60\xc2\xc8\x82\xc3\x10\xef\x13\xa5\x76\xb1\xc2\xd3\x0e\xf8\xf7\x8e\xf8\xd2\xf4\x65\x00\x71\x09\xaa\xd9\x3f\x74\xcb\x9e\x7d\x7b\xef\x7c\x95\x90\xe8\xaf\x3b\x26\x7c\x89\xc1\x5d\xb2\x38\x13\x8c\x45\x83\x3c\x98\xcc\x4a\x47\x1a\x78\x02\x72\x3e\xf4\xc7\x44\xa8\x53\xcf\x80\xa0\xc2\x56\x8d\xd4\xed\x58\xa2\xc9\x64\x48\x06\xf4\x21\x04\xce\xe5\x36\x28\xe5\xbd\xf7\xb6\x3b\x0b\x33\x8e\x93\x1e\x31\xb8\x7c\x24\xb1\x46\xc6\xd0\x40\x60\x55\x67\xce\xef\x59\x60\xdf\x9e\x02\x2c\xb4\x69\xd4\xc7\x87\xf4\xcb\xa3\xc5\x44\xa1\xac\x91\xf9\x5f",
+ "\x57\xcf\xa1\x37\x96\x8c\x39\xea\xa1\x25\x33\x04\x4b\x82\x65\xbb\x90\x3e\xc1\x6c\x8d\x17\xb6\xcf\x1f\x10\x6c\x57",
+ 158 },
+ { GCRY_MD_SHA3_224,
+ "\x25\xb8\xc9\xc0\x32\xea\x6b\xcd\x73\x3f\xfc\x87\x18\xfb\xb2\xa5\x03\xa4\xea\x8f\x71\xde\xa1\x17\x61\x89\xf6\x94\x30\x4f\x0f\xf6\x8e\x86\x2a\x81\x97\xb8\x39\x95\x75\x49\xef\x24\x3a\x52\x79\xfc\x26\x46\xbd\x4c\x00\x9b\x6d\x1e\xde\xbf\x24\x73\x81\x97\xab\xb4\xc9\x92\xf6\xb1\xdc\x9b\xa8\x91\xf5\x70\x87\x9a\xcc\xd5\xa6\xb1\x86\x91\xa9\x3c\x7d\x0a\x8d\x38\xf9\x5b\x63\x9c\x1d\xae\xb4\x8c\x4c\x2f\x15\xcc\xf5\xb9\xd5\x08\xf8\x33\x3c\x32\xde\x78\x78\x1b\x41\x85\x0f\x26\x1b\x85\x5c\x4b\xeb\xcc\x12\x5a\x38\x0c\x54\xd5\x01\xc5\xd3\xbd\x07\xe6\xb5\x21\x02\x11\x60\x88\xe5\x3d\x76\x58\x3b\x01\x61\xe2\xa5\x8d\x07\x78\xf0\x91\x20\x6a\xab\xd5\xa1",
+ "\x87\x30\xc2\x19\xe1\x9d\x9d\x37\xcb\x7a\x63\xa4\xdd\xd5\x5e\x84\xdc\xb0\x23\x6e\xf7\xc8\x82\x8b\x2a\x23\xc9\xb9",
+ 159 },
+ { GCRY_MD_SHA3_224,
+ "\x21\xcf\xdc\x2a\x7c\xcb\x7f\x33\x1b\x3d\x2e\xef\xff\x37\xe4\x8a\xd9\xfa\x9c\x78\x8c\x3f\x3c\x20\x0e\x01\x73\xd9\x99\x63\xe1\xcb\xca\x93\x62\x3b\x26\x4e\x92\x03\x94\xae\x48\xbb\x4c\x3a\x5b\xb9\x6f\xfb\xc8\xf0\xe5\x3f\x30\xe2\x29\x56\xad\xab\xc2\x76\x5f\x57\xfb\x76\x1e\x14\x7e\xcb\xf8\x56\x75\x33\xdb\x6e\x50\xc8\xa1\xf8\x94\x31\x0a\x94\xed\xf8\x06\xdd\x8c\xa6\xa0\xe1\x41\xc0\xfa\x7c\x9f\xae\x6c\x6a\xe6\x5f\x18\xc9\x3a\x85\x29\xe6\xe5\xb5\x53\xbf\x55\xf2\x5b\xe2\xe8\x0a\x98\x82\xbd\x37\xf1\x45\xfe\xcb\xeb\x3d\x44\x7a\x3c\x4e\x46\xc2\x15\x24\xcc\x55\xcd\xd6\x2f\x52\x1a\xb9\x2a\x8b\xa7\x2b\x89\x79\x96\xc4\x9b\xb2\x73\x19\x8b\x7b\x1c\x9e",
+ "\x61\xc0\x1f\xb4\xa0\x10\xf3\x19\xd1\x93\xcb\x6d\x36\x06\x37\x51\x95\x0a\x1a\x8f\x93\x53\x9b\xea\x32\xf8\x4e\xa1",
+ 160 },
+ { GCRY_MD_SHA3_224,
+ "\x4e\x45\x2b\xa4\x21\x27\xdc\xc9\x56\xef\x4f\x8f\x35\xdd\x68\xcb\x22\x5f\xb7\x3b\x5b\xc7\xe1\xec\x5a\x89\x8b\xba\x29\x31\x56\x3e\x74\xfa\xff\x3b\x67\x31\x4f\x24\x1e\xc4\x9f\x4a\x70\x61\xe3\xbd\x02\x13\xae\x82\x6b\xab\x38\x0f\x1f\x14\xfa\xab\x8b\x0e\xfd\xdd\x5f\xd1\xbb\x49\x37\x38\x53\xa0\x8f\x30\x55\x3d\x5a\x55\xcc\xbb\xb8\x15\x3d\xe4\x70\x4f\x29\xca\x2b\xde\xef\x04\x19\x46\x8e\x05\xdd\x51\x55\x7c\xcc\x80\xc0\xa9\x61\x90\xbb\xcc\x4d\x77\xec\xff\x21\xc6\x6b\xdf\x48\x64\x59\xd4\x27\xf9\x86\x41\x0f\x88\x3a\x80\xa5\xbc\xc3\x2c\x20\xf0\x47\x8b\xb9\xa9\x7a\x12\x6f\xc5\xf9\x54\x51\xe4\x0f\x29\x2a\x46\x14\x93\x0d\x05\x4c\x85\x1a\xcd\x01\x9c\xcf",
+ "\x14\x59\x04\x4d\xf9\xc2\x6f\x5e\x24\x0f\x6a\x6b\x93\x80\x73\x4c\xad\x84\xb6\x59\x2f\xc9\x69\x3d\xdd\x9f\x97\x4e",
+ 161 },
+ { GCRY_MD_SHA3_224,
+ "\xfa\x85\x67\x1d\xf7\xda\xdf\x99\xa6\xff\xee\x97\xa3\xab\x99\x91\x67\x1f\x56\x29\x19\x50\x49\x88\x04\x97\x48\x78\x67\xa6\xc4\x46\xb6\x00\x87\xfa\xc9\xa0\xf2\xfc\xc8\xe3\xb2\x4e\x97\xe4\x23\x45\xb9\x3b\x5f\x7d\x36\x91\x82\x9d\x3f\x8c\xcd\x4b\xb3\x64\x11\xb8\x5f\xc2\x32\x8e\xb0\xc5\x1c\xb3\x15\x1f\x70\x86\x0a\xd3\x24\x6c\xe0\x62\x3a\x8d\xc8\xb3\xc4\x9f\x95\x8f\x86\x90\xf8\xe3\x86\x0e\x71\xeb\x2b\x14\x79\xa5\xce\xa0\xb3\xf8\xbe\xfd\x87\xac\xaf\x53\x62\x43\x5e\xae\xcc\xb5\x2f\x38\x61\x7b\xc6\xc5\xc2\xc6\xe2\x69\xea\xd1\xfb\xd6\x9e\x94\x1d\x4a\xd2\x01\x2d\xa2\xc5\xb2\x1b\xcf\xbf\x98\xe4\xa7\x7a\xb2\xaf\x1f\x3f\xda\x32\x33\xf0\x46\xd3\x8f\x1d\xc8",
+ "\xeb\x5c\xc0\x01\x73\x23\x98\x51\xf3\x96\x0e\xda\xc3\x36\x00\x51\x09\x18\x9d\xfc\x04\xb2\x9c\xa4\xcd\xde\x5b\xc1",
+ 162 },
+ { GCRY_MD_SHA3_224,
+ "\xe9\x08\x47\xae\x67\x97\xfb\xc0\xb6\xb3\x6d\x6e\x58\x8c\x0a\x74\x3d\x72\x57\x88\xca\x50\xb6\xd7\x92\x35\x2e\xa8\x29\x4f\x5b\xa6\x54\xa1\x53\x66\xb8\xe1\xb2\x88\xd8\x4f\x51\x78\x24\x08\x27\x97\x5a\x76\x3b\xc4\x5c\x7b\x04\x30\xe8\xa5\x59\xdf\x44\x88\x50\x5e\x00\x9c\x63\xda\x99\x4f\x14\x03\xf4\x07\x95\x82\x03\xce\xbb\x6e\x37\xd8\x9c\x94\xa5\xea\xcf\x60\x39\xa3\x27\xf6\xc4\xdb\xbc\x7a\x2a\x30\x7d\x97\x6a\xa3\x9e\x41\xaf\x65\x37\x24\x3f\xc2\x18\xdf\xa6\xab\x4d\xd8\x17\xb6\xa3\x97\xdf\x5c\xa6\x91\x07\xa9\x19\x87\x99\xed\x24\x86\x41\xb6\x3b\x42\xcb\x4c\x29\xbf\xdd\x79\x75\xac\x96\xed\xfc\x27\x4a\xc5\x62\xd0\x47\x4c\x60\x34\x7a\x07\x8c\xe4\xc2\x5e\x88",
+ "\xa6\x40\xd4\x84\x13\x90\xf4\x7d\xc4\x7d\x4b\xfc\xf1\x30\xfc\xf5\x1c\x5f\x2d\x49\x1f\x91\xc1\x33\x74\xce\x59\x65",
+ 163 },
+ { GCRY_MD_SHA3_224,
+ "\xf6\xd5\xc2\xb6\xc9\x39\x54\xfc\x62\x76\x02\xc0\x0c\x4c\xa9\xa7\xd3\xed\x12\xb2\x71\x73\xf0\xb2\xc9\xb0\xe4\xa5\x93\x93\x98\xa6\x65\xe6\x7e\x69\xd0\xb1\x2f\xb7\xe4\xce\xb2\x53\xe8\x08\x3d\x1c\xeb\x72\x4a\xc0\x7f\x00\x9f\x09\x4e\x42\xf2\xd6\xf2\x12\x94\x89\xe8\x46\xea\xff\x07\x00\xa8\xd4\x45\x3e\xf4\x53\xa3\xed\xdc\x18\xf4\x08\xc7\x7a\x83\x27\x56\x17\xfa\xbc\x4e\xa3\xa2\x83\x3a\xa7\x34\x06\xc0\xe9\x66\x27\x60\x79\xd3\x8e\x8e\x38\x53\x9a\x70\xe1\x94\xcc\x55\x13\xaa\xa4\x57\xc6\x99\x38\x3f\xd1\x90\x0b\x1e\x72\xbd\xfb\x83\x5d\x1f\xd3\x21\xb3\x7b\xa8\x05\x49\xb0\x78\xa4\x9e\xa0\x81\x52\x86\x9a\x91\x8c\xa5\x7f\x5b\x54\xed\x71\xe4\xfd\x3a\xc5\xc0\x67\x29",
+ "\x85\xbb\x3e\xd9\x8c\x48\x08\xd8\xf6\x7c\x72\x2c\x91\x19\xc5\x4e\x65\x43\xb2\x9e\x57\xbd\x4f\xb5\xcb\xc8\x78\xc7",
+ 164 },
+ { GCRY_MD_SHA3_224,
+ "\xcf\x85\x62\xb1\xbe\xd8\x98\x92\xd6\x7d\xda\xaf\x3d\xee\xb2\x82\x46\x45\x6e\x97\x23\x26\xdb\xcd\xb5\xcf\x3f\xb2\x89\xac\xa0\x1e\x68\xda\x5d\x59\x89\x6e\x3a\x61\x65\x35\x8b\x07\x1b\x30\x4d\x6a\xb3\xd0\x18\x94\x4b\xe5\x04\x9d\x5e\x0e\x2b\xb8\x19\xac\xf6\x7a\x60\x06\x11\x10\x89\xe6\x76\x71\x32\xd7\x2d\xd8\x5b\xed\xdc\xbb\x2d\x64\x49\x6d\xb0\xcc\x92\x95\x5a\xb4\xc6\x23\x4f\x1e\xea\x24\xf2\xd5\x14\x83\xf2\xe2\x09\xe4\x58\x9b\xf9\x51\x9f\xac\x51\xb4\xd0\x61\xe8\x01\x12\x5e\x60\x5f\x80\x93\xbb\x69\x97\xbc\x16\x3d\x55\x15\x96\xfe\x4a\xb7\xcf\xae\x8f\xb9\xa9\x0f\x69\x80\x48\x0c\xe0\xc2\x29\xfd\x16\x75\x40\x9b\xd7\x88\x35\x4d\xaf\x31\x62\x40\xcf\xe0\xaf\x93\xeb",
+ "\x50\xb7\xd0\xac\xb9\x32\x11\xe0\xfc\x93\x5f\x97\x0b\xc4\x3a\x00\xbe\x82\x9d\x6b\x3c\x13\x7d\x4a\x7e\x3b\x2b\xc1",
+ 165 },
+ { GCRY_MD_SHA3_224,
+ "\x2a\xce\x31\xab\xb0\xa2\xe3\x26\x79\x44\xd2\xf7\x5e\x15\x59\x98\x5d\xb7\x35\x4c\x6e\x60\x5f\x18\xdc\x84\x70\x42\x3f\xca\x30\xb7\x33\x1d\x9b\x33\xc4\xa4\x32\x67\x83\xd1\xca\xae\x1b\x4f\x07\x06\x0e\xff\x97\x8e\x47\x46\xbf\x0c\x7e\x30\xcd\x61\x04\x0b\xd5\xec\x27\x46\xb2\x98\x63\xeb\x7f\x10\x3e\xbd\xa6\x14\xc4\x29\x1a\x80\x5b\x6a\x4c\x82\x14\x23\x05\x64\xa0\x55\x7b\xc7\x10\x2e\x0b\xd3\xed\x23\x71\x92\x52\xf7\x43\x5d\x64\xd2\x10\xee\x2a\xaf\xc5\x85\xbe\x90\x3f\xa4\x1e\x19\x68\xc5\x0f\xd5\xd5\x36\x79\x26\xdf\x7a\x05\xe3\xa4\x2c\xf0\x7e\x65\x6f\xf9\x2d\xe7\x3b\x03\x6c\xf8\xb1\x98\x98\xc0\xcb\x34\x55\x7c\x0c\x12\xc2\xd8\xb8\x4e\x91\x18\x1a\xf4\x67\xbc\x75\xa9\xd1",
+ "\x7c\xdc\x17\x82\xb3\x9f\xc0\xee\xb1\xf8\x74\xd9\x7c\x88\x05\x1c\xf1\x05\x08\xe0\x87\x5f\xa1\x73\xac\x41\xcc\x8e",
+ 166 },
+ { GCRY_MD_SHA3_224,
+ "\x0d\x8d\x09\xae\xd1\x9f\x10\x13\x96\x9c\xe5\xe7\xeb\x92\xf8\x3a\x20\x9a\xe7\x6b\xe3\x1c\x75\x48\x44\xea\x91\x16\xce\xb3\x9a\x22\xeb\xb6\x00\x30\x17\xbb\xcf\x26\x55\x5f\xa6\x62\x41\x85\x18\x7d\xb8\xf0\xcb\x35\x64\xb8\xb1\xc0\x6b\xf6\x85\xd4\x7f\x32\x86\xed\xa2\x0b\x83\x35\x8f\x59\x9d\x20\x44\xbb\xf0\x58\x3f\xab\x8d\x78\xf8\x54\xfe\x0a\x59\x61\x83\x23\x0c\x5e\xf8\xe5\x44\x26\x75\x0e\xaf\x2c\xc4\xe2\x9d\x3b\xdd\x03\x7e\x73\x4d\x86\x3c\x2b\xd9\x78\x9b\x4c\x24\x30\x96\x13\x8f\x76\x72\xc2\x32\x31\x4e\xff\xdf\xc6\x51\x34\x27\xe2\xda\x76\x91\x6b\x52\x48\x93\x3b\xe3\x12\xeb\x5d\xde\x4c\xf7\x08\x04\xfb\x25\x8a\xc5\xfb\x82\xd5\x8d\x08\x17\x7a\xc6\xf4\x75\x60\x17\xff\xf5",
+ "\xee\x5d\x50\x8a\x4e\x75\x90\x01\x93\xe9\x9a\x04\xb8\xd8\x38\xa1\x8d\xed\xfc\xc4\x31\xe7\xaf\x31\x82\xa4\x7d\xd6",
+ 167 },
+ { GCRY_MD_SHA3_224,
+ "\xc3\x23\x6b\x73\xde\xb7\x66\x2b\xf3\xf3\xda\xa5\x8f\x13\x7b\x35\x8b\xa6\x10\x56\x0e\xf7\x45\x57\x85\xa9\xbe\xfd\xb0\x35\xa0\x66\xe9\x07\x04\xf9\x29\xbd\x96\x89\xce\xf0\xce\x3b\xda\x5a\xcf\x44\x80\xbc\xeb\x8d\x09\xd1\x0b\x09\x8a\xd8\x50\x0d\x9b\x60\x71\xdf\xc3\xa1\x4a\xf6\xc7\x75\x11\xd8\x1e\x3a\xa8\x84\x49\x86\xc3\xbe\xa6\xf4\x69\xf9\xe0\x21\x94\xc9\x28\x68\xcd\x5f\x51\x64\x62\x56\x79\x8f\xf0\x42\x49\x54\xc1\x43\x4b\xdf\xed\x9f\xac\xb3\x90\xb0\x7d\x34\x2e\x99\x29\x36\xe0\xf8\x8b\xfd\x0e\x88\x4a\x0d\xdb\x67\x9d\x05\x47\xcc\xde\xc6\x38\x42\x85\xa4\x54\x29\xd1\x15\xac\x7d\x23\x5a\x71\x72\x42\x02\x1d\x1d\xc3\x56\x41\xf5\xf0\xa4\x8e\x84\x45\xdb\xa5\x8e\x6c\xb2\xc8\xea",
+ "\x59\x42\xba\x8b\x58\xa3\x55\xf2\xae\xf0\x7e\x29\xf8\xf9\x97\x13\x01\xe8\x77\xfa\x32\xd7\x02\x5d\xf5\x52\xb1\xeb",
+ 168 },
+ { GCRY_MD_SHA3_224,
+ "\xb3\x9f\xeb\x82\x83\xea\xdc\x63\xe8\x18\x4b\x51\xdf\x5a\xe3\xfd\x41\xaa\xc8\xa9\x63\xbb\x0b\xe1\xcd\x08\xaa\x58\x67\xd8\xd9\x10\xc6\x69\x22\x1e\x73\x24\x33\x60\x64\x6f\x65\x53\xd1\xca\x05\xa8\x4e\x8d\xc0\xde\x05\xb6\x41\x9e\xc3\x49\xca\x99\x44\x80\x19\x3d\x01\xc9\x25\x25\xf3\xfb\x3d\xce\xfb\x08\xaf\xc6\xd2\x69\x47\xbd\xbb\xfd\x85\x19\x3f\x53\xb5\x06\x09\xc6\x14\x09\x05\xc5\x3a\x66\x86\xb5\x8e\x53\xa3\x19\xa5\x7b\x96\x23\x31\xed\xe9\x81\x49\xaf\x3d\xe3\x11\x8a\x81\x9d\xa4\xd7\x67\x06\xa0\x42\x4b\x4e\x1d\x29\x10\xb0\xed\x26\xaf\x61\xd1\x50\xeb\xcb\x46\x59\x5d\x42\x66\xa0\xbd\x7f\x65\x1b\xa4\x7d\x0c\x7f\x17\x9c\xa2\x85\x45\x00\x7d\x92\xe8\x41\x9d\x48\xfd\xfb\xd7\x44\xce",
+ "\x29\x24\x0a\x9e\x97\x38\x88\xb9\x8a\x3a\x83\x69\x33\x85\x5d\x41\xd8\xab\xb6\xc3\x80\x6a\x62\x6c\x3d\xf1\x8f\x6c",
+ 169 },
+ { GCRY_MD_SHA3_224,
+ "\xa9\x83\xd5\x4f\x50\x38\x03\xe8\xc7\x99\x9f\x4e\xdb\xbe\x82\xe9\x08\x4f\x42\x21\x43\xa9\x32\xdd\xdd\xc4\x7a\x17\xb0\xb7\x56\x4a\x7f\x37\xa9\x9d\x07\x86\xe9\x94\x76\x42\x8d\x29\xe2\x9d\x3c\x19\x7a\x72\xbf\xab\x13\x42\xc1\x2a\x0f\xc4\x78\x7f\xd7\x01\x7d\x7a\x61\x74\x04\x9e\xa4\x3b\x57\x79\x16\x9e\xf7\x47\x2b\xdb\xbd\x94\x1d\xcb\x82\xfc\x73\xaa\xc4\x5a\x8a\x94\xc9\xf2\xbd\x34\x77\xf6\x1f\xd3\xb7\x96\xf0\x2a\x1b\x82\x64\xa2\x14\xc6\xfe\xa7\x4b\x70\x51\xb2\x26\xc7\x22\x09\x9e\xc7\x88\x3a\x46\x2b\x83\xb6\xaf\xdd\x40\x09\x24\x8b\x8a\x23\x7f\x60\x5f\xe5\xa0\x8f\xe7\xd8\xb4\x53\x21\x42\x1e\xbb\xa6\x7b\xd7\x0a\x0b\x00\xdd\xbf\x94\xba\xab\x7f\x35\x9d\x5d\x1e\xea\x10\x5f\x28\xdc\xfb",
+ "\x9a\xf1\x78\xb1\xdd\x3c\xef\xc9\x62\x27\xa2\x89\x17\x5b\xb6\x1d\x9f\x6b\x0b\x35\x2d\x78\x04\xf5\xe0\x7e\xa4\x5d",
+ 170 },
+ { GCRY_MD_SHA3_224,
+ "\xe4\xd1\xc1\x89\x7a\x0a\x86\x6c\xe5\x64\x63\x5b\x74\x22\x2f\x96\x96\xbf\x2c\x7f\x64\x0d\xd7\x8d\x7e\x2a\xca\x66\xe1\xb6\x1c\x64\x2b\xb0\x3e\xa7\x53\x6a\xae\x59\x78\x11\xe9\xbf\x4a\x7b\x45\x3e\xde\x31\xf9\x7b\x46\xa5\xf0\xef\x51\xa0\x71\xa2\xb3\x91\x8d\xf1\x6b\x15\x25\x19\xae\x37\x76\xf9\xf1\xed\xab\x4c\x2a\x37\x7c\x32\x92\xe9\x64\x08\x35\x9d\x36\x13\x84\x4d\x5e\xb3\x93\x00\x02\x83\xd5\xad\x34\x01\xa3\x18\xb1\x2f\xd1\x47\x4b\x86\x12\xf2\xbb\x50\xfb\x6a\x8b\x9e\x02\x3a\x54\xd7\xdd\xe2\x8c\x43\xd6\xd8\x85\x4c\x8d\x9d\x11\x55\x93\x5c\x19\x98\x11\xdb\xfc\x87\xe9\xe0\x07\x2e\x90\xeb\x88\x68\x1c\xc7\x52\x97\x14\xf8\xfb\x8a\x2c\x9d\x88\x56\x7a\xdf\xb9\x74\xee\x20\x5a\x9b\xf7\xb8\x48",
+ "\xf5\x43\xb4\xd4\x23\xea\xac\x86\x33\x8b\xb6\xd8\xc6\x18\x1a\xd6\xdc\x0a\x25\x73\x39\x53\xce\xd7\xeb\x83\x77\xf3",
+ 171 },
+ { GCRY_MD_SHA3_224,
+ "\xb1\x0c\x59\x72\x3e\x3d\xca\xdd\x6d\x75\xdf\x87\xd0\xa1\x58\x0e\x73\x13\x3a\x9b\x7d\x00\xcb\x95\xec\x19\xf5\x54\x70\x27\x32\x3b\xe7\x51\x58\xb1\x1f\x80\xb6\xe1\x42\xc6\xa7\x85\x31\x88\x6d\x90\x47\xb0\x8e\x55\x1e\x75\xe6\x26\x1e\x79\x78\x53\x66\xd7\x02\x4b\xd7\xcd\x9c\xf3\x22\xd9\xbe\x7d\x57\xfb\x66\x10\x69\xf2\x48\x1c\x7b\xb7\x59\xcd\x71\xb4\xb3\x6c\xa2\xbc\x2d\xf6\xd3\xa3\x28\xfa\xeb\xdb\x99\x5a\x97\x94\xa8\xd7\x21\x55\xed\x55\x1a\x1f\x87\xc8\x0b\xf6\x05\x9b\x43\xfc\x76\x49\x00\xb1\x8a\x1c\x24\x41\xf7\x48\x77\x43\xcf\x84\xe5\x65\xf6\x1f\x8d\xd2\xec\xe6\xb6\xcc\xc9\x44\x40\x49\x19\x7a\xaa\xf5\x3e\x92\x6f\xbe\xe3\xbf\xca\x8b\xe5\x88\xec\x77\xf2\x9d\x21\x1b\xe8\x9d\xe1\x8b\x15\xf6",
+ "\x77\xb4\x07\x9e\xee\x9d\x9e\x3f\xda\x05\x1e\xe0\xca\x43\x0b\x4d\xf0\x11\xd0\x56\x61\x2c\x1a\xf4\x46\xa1\x87\xc2",
+ 172 },
+ { GCRY_MD_SHA3_224,
+ "\xdb\x11\xf6\x09\xba\xba\x7b\x0c\xa6\x34\x92\x6b\x1d\xd5\x39\xc8\xcb\xad\xa2\x49\x67\xd7\xad\xd4\xd9\x87\x6f\x77\xc2\xd8\x0c\x0f\x4d\xce\xfb\xd7\x12\x15\x48\x37\x35\x82\x70\x5c\xca\x24\x95\xbd\x2a\x43\x71\x6f\xe6\x4e\xd2\x6d\x05\x9c\xfb\x56\x6b\x33\x64\xbd\x49\xee\x07\x17\xbd\xd9\x81\x0d\xd1\x4d\x8f\xad\x80\xdb\xbd\xc4\xca\xfb\x37\xcc\x60\xfb\x0f\xe2\xa8\x0f\xb4\x54\x1b\x8c\xa9\xd5\x9d\xce\x45\x77\x38\xa9\xd3\xd8\xf6\x41\xaf\x8c\x3f\xd6\xda\x16\x2d\xc1\x6f\xc0\x1a\xac\x52\x7a\x4a\x02\x55\xb4\xd2\x31\xc0\xbe\x50\xf4\x4f\x0d\xb0\xb7\x13\xaf\x03\xd9\x68\xfe\x7f\x0f\x61\xed\x08\x24\xc5\x5c\x4b\x52\x65\x54\x8f\xeb\xd6\xaa\xd5\xc5\xee\xdf\x63\xef\xe7\x93\x48\x9c\x39\xb8\xfd\x29\xd1\x04\xce",
+ "\x98\x7d\x30\x12\x0c\x9a\xa4\x96\x46\x50\xa6\xa7\x30\xe9\x9c\x86\xf7\xfb\xdd\xb4\xea\x8d\x6b\x48\x15\xee\x4e\xbf",
+ 173 },
+ { GCRY_MD_SHA3_224,
+ "\xbe\xbd\x4f\x1a\x84\xfc\x8b\x15\xe4\x45\x2a\x54\xbd\x02\xd6\x9e\x30\x4b\x7f\x32\x61\x6a\xad\xd9\x05\x37\x93\x71\x06\xae\x4e\x28\xde\x9d\x8a\xab\x02\xd1\x9b\xc3\xe2\xfd\xe1\xd6\x51\x55\x9e\x29\x64\x53\xe4\xdb\xa9\x43\x70\xa1\x4d\xbb\xb2\xd1\xd4\xe2\x02\x23\x02\xee\x90\xe2\x08\x32\x1e\xfc\xd8\x52\x8a\xd8\x9e\x46\xdc\x83\x9e\xa9\xdf\x61\x8e\xa8\x39\x4a\x6b\xff\x30\x8e\x77\x26\xba\xe0\xc1\x9b\xcd\x4b\xe5\x2d\xa6\x25\x8e\x2e\xf4\xe9\x6a\xa2\x12\x44\x42\x9f\x49\xef\x5c\xb4\x86\xd7\xff\x35\xca\xc1\xba\xcb\x7e\x95\x71\x19\x44\xbc\xcb\x2a\xb3\x47\x00\xd4\x2d\x1e\xb3\x8b\x5d\x53\x6b\x94\x73\x48\xa4\x58\xed\xe3\xdc\x6b\xd6\xec\x54\x7b\x1b\x0c\xae\x5b\x25\x7b\xe3\x6a\x71\x24\xe1\x06\x0c\x17\x0f\xfa",
+ "\x46\x19\x33\x59\x39\x7b\xc3\xea\xcd\x69\xbf\xf4\x10\x20\x35\x83\x38\x2d\xe9\x3e\xcc\x4d\x80\xdc\xfb\x4f\xc5\x1d",
+ 174 },
+ { GCRY_MD_SHA3_224,
+ "\x5a\xca\x56\xa0\x3a\x13\x78\x4b\xdc\x32\x89\xd9\x36\x4f\x79\xe2\xa8\x5c\x12\x27\x6b\x49\xb9\x2d\xb0\xad\xaa\x4f\x20\x6d\x50\x28\xf2\x13\xf6\x78\xc3\x51\x0e\x11\x1f\x9d\xc4\xc1\xc1\xf8\xb6\xac\xb1\x7a\x64\x13\xaa\x22\x76\x07\xc5\x15\xc6\x2a\x73\x38\x17\xba\x5e\x76\x2c\xc6\x74\x8e\x7e\x0d\x68\x72\xc9\x84\xd7\x23\xc9\xbb\x3b\x11\x7e\xb8\x96\x31\x85\x30\x0a\x80\xbf\xa6\x5c\xde\x49\x5d\x70\xa4\x6c\x44\x85\x86\x05\xfc\xcb\xed\x08\x6c\x2b\x45\xce\xf9\x63\xd3\x32\x94\xdb\xe9\x70\x6b\x13\xaf\x22\xf1\xb7\xc4\xcd\x5a\x00\x1c\xfe\xc2\x51\xfb\xa1\x8e\x72\x2c\x6e\x1c\x4b\x11\x66\x91\x8b\x4f\x6f\x48\xa9\x8b\x64\xb3\xc0\x7f\xc8\x6a\x6b\x17\xa6\xd0\x48\x0a\xb7\x9d\x4e\x64\x15\xb5\x20\xf1\xc4\x84\xd6\x75\xb1",
+ "\x0b\xc2\x91\x07\xc7\xe2\x5d\x44\xf8\xce\x83\xa4\x15\xb1\xde\x5d\xf3\x8a\x67\x19\x76\x96\x06\x76\x2b\x71\x92\xc2",
+ 175 },
+ { GCRY_MD_SHA3_224,
+ "\xa5\xaa\xd0\xe4\x64\x6a\x32\xc8\x5c\xfc\xac\x73\xf0\x2f\xc5\x30\x0f\x19\x82\xfa\xbb\x2f\x21\x79\xe2\x83\x03\xe4\x47\x85\x40\x94\xcd\xfc\x85\x43\x10\xe5\xc0\xf6\x09\x93\xce\xff\x54\xd8\x4d\x6b\x46\x32\x3d\x93\x0a\xdb\x07\xc1\x75\x99\xb3\x5b\x50\x5f\x09\xe7\x84\xbc\xa5\x98\x5e\x01\x72\x25\x77\x97\xfb\x53\x64\x9e\x2e\x97\x23\xef\xd1\x68\x65\xc3\x1b\x5c\x3d\x51\x13\xb5\x8b\xb0\xbf\xc8\x92\x0f\xab\xdd\xa0\x86\xd7\x53\x7e\x66\xd7\x09\xd0\x50\xbd\x14\xd0\xc9\x60\x87\x3f\x15\x6f\xad\x5b\x3d\x38\x40\xcd\xfc\xdc\x9b\xe6\xaf\x51\x9d\xb2\x62\xa2\x7f\x40\x89\x6a\xb2\x5c\xc3\x9f\x96\x98\x4d\x65\x06\x11\xc0\xd5\xa3\x08\x0d\x5b\x3a\x1b\xf1\x86\xab\xd4\x29\x56\x58\x8b\x3b\x58\xcd\x94\x89\x70\xd2\x98\x77\x60\x60",
+ "\xb4\x85\x64\x4c\x32\x28\x3b\x28\x01\x79\xf7\xc9\x71\x43\x50\xf0\xb3\xac\xfd\x7c\x45\xa2\x47\xbf\x3b\x6c\xdb\x07",
+ 176 },
+ { GCRY_MD_SHA3_224,
+ "\x06\xcb\xbe\x67\xe9\x4a\x97\x82\x03\xea\xd6\xc0\x57\xa1\xa5\xb0\x98\x47\x8b\x4b\x4c\xbe\xf5\xa9\x7e\x93\xc8\xe4\x2f\x55\x72\x71\x35\x75\xfc\x2a\x88\x45\x31\xd7\x62\x2f\x8f\x87\x93\x87\xa8\x59\xa8\x0f\x10\xef\x02\x70\x8c\xd8\xf7\x41\x3a\xb3\x85\xaf\xc3\x57\x67\x8b\x95\x78\xc0\xeb\xf6\x41\xef\x07\x6a\x1a\x30\xf1\xf7\x53\x79\xe9\xdc\xb2\xa8\x85\xbd\xd2\x95\x90\x5e\xe8\x0c\x01\x68\xa6\x2a\x95\x97\xd1\x0c\xf1\x2d\xd2\xd8\xce\xe4\x66\x45\xc7\xe5\xa1\x41\xf6\xe0\xe2\x3a\xa4\x82\xab\xe5\x66\x1c\x16\xe6\x9e\xf1\xe2\x83\x71\xe2\xe2\x36\xc3\x59\xba\x4e\x92\xc2\x56\x26\xa7\xb7\xff\x13\xf6\xea\x4a\xe9\x06\xe1\xcf\xe1\x63\xe9\x17\x19\xb1\xf7\x50\xa9\x6c\xbd\xe5\xfb\xc9\x53\xd9\xe5\x76\xcd\x21\x6a\xfc\x90\x32\x3a",
+ "\xf3\x84\x54\x24\x99\xef\xd2\x33\x81\xde\xbc\xd9\x12\x4c\x53\x9c\x40\xbf\xa7\x0e\x51\x72\x80\xf5\x6a\x09\x20\xe1",
+ 177 },
+ { GCRY_MD_SHA3_224,
+ "\xf1\xc5\x28\xcf\x77\x39\x87\x47\x07\xd4\xd8\xad\x5b\x98\xf7\xc7\x71\x69\xde\x0b\x57\x18\x8d\xf2\x33\xb2\xdc\x8a\x5b\x31\xed\xa5\xdb\x42\x91\xdd\x9f\x68\xe6\xba\xd3\x7b\x8d\x7f\x6c\x9c\x00\x44\xb3\xbf\x74\xbb\xc3\xd7\xd1\x79\x8e\x13\x87\x09\xb0\xd7\x5e\x7c\x59\x3d\x3c\xcc\xdc\x1b\x20\xc7\x17\x4b\x4e\x69\x2a\xdd\x82\x0a\xce\x26\x2d\x45\xcc\xfa\xe2\x07\x7e\x87\x87\x96\x34\x71\x68\x06\x0a\x16\x2e\xcc\xa8\xc3\x8c\x1a\x88\x35\x0b\xd6\x3b\xb5\x39\x13\x4f\x70\x0f\xd4\xad\xdd\x59\x59\xe2\x55\x33\x7d\xaa\x06\xbc\x86\x35\x8f\xab\xcb\xef\xdf\xb5\xbc\x88\x97\x83\xd8\x43\xc0\x8a\xad\xc6\xc4\xf6\xc3\x6f\x65\xf1\x56\xe8\x51\xc9\xa0\xf9\x17\xe4\xa3\x67\xb5\xad\x93\xd8\x74\x81\x2a\x1d\xe6\xa7\xb9\x3c\xd5\x3a\xd9\x72\x32",
+ "\xd1\x2e\x38\x84\xbc\x8c\xf9\x17\x5d\x17\x78\xe8\xa3\xaa\xa1\x19\xe4\xa8\x97\x73\x8f\x8d\x81\xb1\x27\x8b\xc4\x48",
+ 178 },
+ { GCRY_MD_SHA3_224,
+ "\x9d\x9f\x3a\x7e\xcd\x51\xb4\x1f\x65\x72\xfd\x0d\x08\x81\xe3\x03\x90\xdf\xb7\x80\x99\x1d\xae\x7d\xb3\xb4\x76\x19\x13\x47\x18\xe6\xf9\x87\x81\x0e\x54\x26\x19\xdf\xaa\x7b\x50\x5c\x76\xb7\x35\x0c\x64\x32\xd8\xbf\x1c\xfe\xbd\xf1\x06\x9b\x90\xa3\x5f\x0d\x04\xcb\xdf\x13\x0b\x0d\xfc\x78\x75\xf4\xa4\xe6\x2c\xdb\x8e\x52\x5a\xad\xd7\xce\x84\x25\x20\xa4\x82\xac\x18\xf0\x94\x42\xd7\x83\x05\xfe\x85\xa7\x4e\x39\xe7\x60\xa4\x83\x74\x82\xed\x2f\x43\x7d\xd1\x3b\x2e\xc1\x04\x2a\xfc\xf9\xde\xcd\xc3\xe8\x77\xe5\x0f\xf4\x10\x6a\xd1\x0a\x52\x52\x30\xd1\x19\x20\x32\x4a\x81\x09\x4d\xa3\x1d\xea\xb6\x47\x6a\xa4\x2f\x20\xc8\x48\x43\xcf\xc1\xc5\x85\x45\xee\x80\x35\x2b\xdd\x37\x40\xdd\x6a\x16\x79\x2a\xe2\xd8\x6f\x11\x64\x1b\xb7\x17\xc2",
+ "\xd8\xa3\x48\x26\x4d\x48\x04\x5d\x44\x82\xf3\xfe\x00\x2c\x1a\x1f\x36\xd4\xdf\x0d\x5e\x47\xfa\xc5\x12\x5c\x79\x47",
+ 179 },
+ { GCRY_MD_SHA3_224,
+ "\x51\x79\x88\x87\x24\x81\x9f\xba\xd3\xaf\xa9\x27\xd3\x57\x77\x96\x66\x0e\x6a\x81\xc5\x2d\x98\xe9\x30\x32\x61\xd5\xa4\xa8\x32\x32\xf6\xf7\x58\x93\x4d\x50\xaa\x83\xff\x9e\x20\xa5\x92\x6d\xfe\xba\xac\x49\x52\x9d\x00\x6e\xb9\x23\xc5\xae\x50\x48\xed\x54\x4e\xc4\x71\xed\x71\x91\xed\xf4\x63\x63\x38\x38\x24\xf9\x15\x76\x9b\x3e\x68\x80\x94\xc6\x82\xb0\x21\x51\xe5\xee\x01\xe5\x10\xb4\x31\xc8\x86\x5a\xff\x8b\x6b\x6f\x2f\x59\xcb\x6d\x12\x9d\xa7\x9e\x97\xc6\xd2\xb8\xfa\x6c\x6d\xa3\xf6\x03\x19\x9d\x2d\x1b\xca\xb5\x47\x68\x2a\x81\xcd\x6c\xf6\x5f\x65\x51\x12\x13\x91\xd7\x8b\xcc\x23\xb5\xbd\x0e\x92\x2e\xc6\xd8\xbf\x97\xc9\x52\xe8\x4d\xd2\x8a\xef\x90\x9a\xba\x31\xed\xb9\x03\xb2\x8f\xbf\xc3\x3b\x77\x03\xcd\x99\x62\x15\xa1\x12\x38",
+ "\x68\x65\x46\x4c\x6a\x23\x0b\x4b\xf6\x4b\xa3\x3b\xf9\x74\x59\xd1\xd2\x2d\xaf\xb1\x9e\x08\xf4\xb7\xda\xce\x02\xff",
+ 180 },
+ { GCRY_MD_SHA3_224,
+ "\x57\x6e\xf3\x52\x0d\x30\xb7\xa4\x89\x9b\x8c\x0d\x5e\x35\x9e\x45\xc5\x18\x9a\xdd\x10\x0e\x43\xbe\x42\x9a\x02\xfb\x3d\xe5\xff\x4f\x8f\xd0\xe7\x9d\x96\x63\xac\xca\x72\xcd\x29\xc9\x45\x82\xb1\x92\x92\xa5\x57\xc5\xb1\x31\x52\x97\xd1\x68\xfb\xb5\x4e\x9e\x2e\xcd\x13\x80\x9c\x2b\x5f\xce\x99\x8e\xdc\x65\x70\x54\x5e\x14\x99\xdb\xe7\xfb\x74\xd4\x7c\xd7\xf3\x58\x23\xb2\x12\xb0\x5b\xf3\xf5\xa7\x9c\xaa\x34\x22\x4f\xdd\x67\x0d\x33\x5f\xcb\x10\x6f\x5d\x92\xc3\x94\x6f\x44\xd3\xaf\xcb\xae\x2e\x41\xac\x55\x4d\x8e\x67\x59\xf3\x32\xb7\x6b\xe8\x9a\x03\x24\xaa\x12\xc5\x48\x2d\x1e\xa3\xee\x89\xde\xd4\x93\x6f\x3e\x3c\x08\x04\x36\xf5\x39\xfa\x13\x7e\x74\xc6\xd3\x38\x9b\xdf\x5a\x45\x07\x4c\x47\xbc\x7b\x20\xb0\x94\x84\x07\xa6\x6d\x85\x5e\x2f",
+ "\x19\xd3\x3c\xd3\x54\xa1\x3a\xb2\xa4\x40\x44\x15\x4b\xd8\x65\xf1\x17\xef\x8a\x88\x7f\xbd\x05\x70\xa8\xa4\xca\x80",
+ 181 },
+ { GCRY_MD_SHA3_224,
+ "\x0d\xf2\x15\x2f\xa4\xf4\x35\x7c\x87\x41\x52\x9d\xd7\x7e\x78\x39\x25\xd3\xd7\x6e\x95\xba\xfa\x2b\x54\x2a\x2c\x33\xf3\xd1\xd1\x17\xd1\x59\xcf\x47\x3f\x82\x31\x03\x56\xfe\xe4\xc9\x0a\x9e\x50\x5e\x70\xf8\xf2\x48\x59\x65\x63\x68\xba\x09\x38\x1f\xa2\x45\xeb\x6c\x3d\x76\x3f\x30\x93\xf0\xc8\x9b\x97\x2e\x66\xb5\x3d\x59\x40\x6d\x9f\x01\xae\xa0\x7f\x8b\x3b\x61\x5c\xac\x4e\xe4\xd0\x5f\x54\x2e\x7d\x0d\xab\x45\xd6\x7c\xcc\xcd\x3a\x60\x6c\xcb\xeb\x31\xea\x1f\xa7\x00\x5b\xa0\x71\x76\xe6\x0d\xab\x7d\x78\xf6\x81\x0e\xf0\x86\xf4\x2f\x08\xe5\x95\xf0\xec\x21\x73\x72\xb9\x89\x70\xcc\x63\x21\x57\x6d\x92\xce\x38\xf7\xc3\x97\xa4\x03\xba\xda\x15\x48\xd2\x05\xc3\x43\xac\x09\xde\xca\x86\x32\x53\x73\xc3\xb7\x6d\x9f\x32\x02\x8f\xea\x8e\xb3\x25\x15",
+ "\xe4\x38\xae\x41\x53\x46\x3b\x33\x3a\xe4\xfe\x57\xbf\x13\x15\x05\xc8\xc0\x4a\x53\x4a\x39\xa2\x05\x74\x15\x5e\x49",
+ 182 },
+ { GCRY_MD_SHA3_224,
+ "\x3e\x15\x35\x0d\x87\xd6\xeb\xb5\xc8\xad\x99\xd4\x25\x15\xcf\xe1\x79\x80\x93\x3c\x7a\x8f\x6b\x8b\xbb\xf0\xa6\x37\x28\xce\xfa\xad\x20\x52\x62\x3c\x0b\xd5\x93\x18\x39\x11\x2a\x48\x63\x3f\xb3\xc2\x00\x4e\x07\x49\xc8\x7a\x41\xb2\x6a\x8b\x48\x94\x55\x39\xd1\xff\x41\xa4\xb2\x69\x46\x2f\xd1\x99\xbf\xec\xd4\x53\x74\x75\x6f\x55\xa9\x11\x6e\x92\x09\x3a\xc9\x94\x51\xae\xfb\x2a\xf9\xfd\x32\xd6\xd7\xf5\xfb\xc7\xf7\xa5\x40\xd5\x09\x7c\x09\x6e\xbc\x3b\x3a\x72\x15\x41\xde\x07\x3a\x1c\xc0\x2f\x7f\xb0\xfb\x1b\x93\x27\xfb\x0b\x12\x18\xca\x49\xc9\x48\x7a\xb5\x39\x66\x22\xa1\x3a\xe5\x46\xc9\x7a\xbd\xef\x6b\x56\x38\x0d\xda\x70\x12\xa8\x38\x40\x91\xb6\x65\x6d\x0a\xb2\x72\xd3\x63\xce\xa7\x81\x63\xff\x76\x5c\xdd\x13\xab\x17\x38\xb9\x40\xd1\x6c\xae",
+ "\x45\x47\x96\xc7\x21\x9c\x6f\x7e\x88\x50\x8d\xfc\x13\x66\x8b\x81\x74\x82\x11\xbd\x01\x6d\x84\xb5\x92\x93\xb4\x45",
+ 183 },
+ { GCRY_MD_SHA3_224,
+ "\xc3\x8d\x6b\x0b\x75\x7c\xb5\x52\xbe\x40\x94\x0e\xce\x00\x09\xef\x3b\x0b\x59\x30\x7c\x14\x51\x68\x6f\x1a\x22\x70\x29\x22\x80\x0d\x58\xbc\xe7\xa6\x36\xc1\x72\x7e\xe5\x47\xc0\x1b\x21\x47\x79\xe8\x98\xfc\x0e\x56\x0f\x8a\xe7\xf6\x1b\xef\x4d\x75\xea\xa6\x96\xb9\x21\xfd\x6b\x73\x5d\x17\x15\x35\xe9\xed\xd2\x67\xc1\x92\xb9\x98\x80\xc8\x79\x97\x71\x10\x02\x00\x90\x95\xd8\xa7\xa4\x37\xe2\x58\x10\x4a\x41\xa5\x05\xe5\xef\x71\xe5\x61\x3d\xdd\x20\x08\x19\x5f\x0c\x57\x4e\x6b\xa3\xfe\x40\x09\x9c\xfa\x11\x6e\x5f\x1a\x2f\xa8\xa6\xda\x04\xba\xdc\xb4\xe2\xd5\xd0\xde\x31\xfd\xc4\x80\x08\x91\xc4\x57\x81\xa0\xaa\xc7\xc9\x07\xb5\x6d\x63\x1f\xca\x5c\xe8\xb2\xcd\xe6\x20\xd1\x1d\x17\x77\xed\x9f\xa6\x03\x54\x1d\xe7\x94\xdd\xc5\x75\x8f\xcd\x5f\xad\x78\xc0",
+ "\xce\x15\x8a\xed\x6e\xd3\xc9\xd4\x43\x2e\x24\x22\xaf\x8d\x25\x5a\xb1\xf3\x89\x8f\x6f\x5b\x5c\x5a\x14\x78\x55\x2c",
+ 184 },
+ { GCRY_MD_SHA3_224,
+ "\x8d\x2d\xe3\xf0\xb3\x7a\x63\x85\xc9\x07\x39\x80\x5b\x17\x00\x57\xf0\x91\xcd\x0c\x7a\x0b\xc9\x51\x54\x0f\x26\xa5\xa7\x5b\x3e\x69\x46\x31\xbb\x64\xc7\x63\x5e\xed\x31\x6f\x51\x31\x8e\x9d\x8d\xe1\x3c\x70\xa2\xab\xa0\x4a\x14\x83\x68\x55\xf3\x5e\x48\x05\x28\xb7\x76\xd0\xa1\xe8\xa2\x3b\x54\x7c\x8b\x8d\x6a\x0d\x09\xb2\x41\xd3\xbe\x93\x77\x16\x0c\xca\x4e\x67\x93\xd0\x0a\x51\x5d\xc2\x99\x2c\xb7\xfc\x74\x1d\xac\xa1\x71\x43\x1d\xa9\x9c\xce\x6f\x77\x89\xf1\x29\xe2\xac\x5c\xf6\x5b\x40\xd7\x03\x03\x5c\xd2\x18\x5b\xb9\x36\xc8\x20\x02\xda\xf8\xcb\xc2\x7a\x7a\x9e\x55\x4b\x06\x19\x66\x30\x44\x6a\x6f\x0a\x14\xba\x15\x5e\xd2\x6d\x95\xbd\x62\x7b\x72\x05\xc0\x72\xd0\x2b\x60\xdb\x0f\xd7\xe4\x9e\xa0\x58\xc2\xe0\xba\x20\x2d\xaf\xf0\xde\x91\xe8\x45\xcf\x79",
+ "\xa0\xa2\x1d\x95\xe6\x40\xf1\x3b\x25\x65\x24\x84\xe2\x44\xbe\x1b\x37\x3e\x9b\x06\x09\xb6\x85\xef\xce\x48\x10\x7a",
+ 185 },
+ { GCRY_MD_SHA3_224,
+ "\xc4\x64\xbb\xda\xd2\x75\xc5\x0d\xcd\x98\x3b\x65\xad\x10\x19\xb9\xff\x85\xa1\xe7\x1c\x80\x7f\x32\x04\xbb\x2c\x92\x1d\xc3\x1f\xbc\xd8\xc5\xfc\x45\x86\x8a\xe9\xef\x85\xb6\xc9\xb8\x3b\xba\x2a\x5a\x82\x22\x01\xed\x68\x58\x6e\xc5\xec\x27\xfb\x28\x57\xa5\xd1\xa2\xd0\x9d\x09\x11\x5f\x22\xdc\xc3\x9f\xe6\x1f\x5e\x1b\xa0\xff\x6e\x8b\x4a\xcb\x4c\x6d\xa7\x48\xbe\x7f\x3f\x08\x39\x73\x93\x94\xff\x7f\xa8\xe3\x9f\x7f\x7e\x84\xa3\x3c\x38\x66\x87\x5c\x01\xbc\xb1\x26\x3c\x94\x05\xd9\x19\x08\xe9\xe0\xb5\x0e\x74\x59\xfa\xbb\x63\xd8\xc6\xbb\xb7\x3d\x8e\x34\x83\xc0\x99\xb5\x5b\xc3\x0f\xf0\x92\xff\x68\xb6\xad\xed\xfd\x47\x7d\x63\x57\x0c\x9f\x55\x15\x84\x7f\x36\xe2\x4b\xa0\xb7\x05\x55\x71\x30\xce\xc5\x7e\xba\xd1\xd0\xb3\x1a\x37\x8e\x91\x89\x4e\xe2\x6e\x3a\x04",
+ "\xca\x8c\xb1\x35\x9f\x0b\x05\xe2\xff\x94\x14\xcc\xe0\xde\x6d\x2c\xb4\xd0\x5b\x08\x35\x4c\x21\x19\xa8\x73\x42\xca",
+ 186 },
+ { GCRY_MD_SHA3_224,
+ "\x8b\x8d\x68\xbb\x8a\x75\x73\x2f\xe2\x72\x81\x5a\x68\xa1\xc9\xc5\xaa\x31\xb4\x1d\xed\xc8\x49\x3e\x76\x52\x5d\x1d\x01\x3d\x33\xce\xbd\x9e\x21\xa5\xbb\x95\xdb\x26\x16\x97\x6a\x8c\x07\xfc\xf4\x11\xf5\xf6\xbc\x6f\x7e\x0b\x57\xac\xa7\x8c\xc2\x79\x0a\x6f\x9b\x89\x88\x58\xac\x9c\x79\xb1\x65\xff\x24\xe6\x66\x77\x53\x1e\x39\xf5\x72\xbe\x5d\x81\xeb\x32\x64\x52\x41\x81\x11\x5f\x32\x78\x02\x57\xbf\xb9\xae\xec\x6a\xf1\x2a\xf2\x8e\x58\x7c\xac\x06\x8a\x1a\x29\x53\xb5\x9a\xd6\x80\xf4\xc2\x45\xb2\xe3\xec\x36\xf5\x99\x40\xd3\x7e\x1d\x3d\xb3\x8e\x13\xed\xb2\x9b\x5c\x0f\x40\x4f\x6f\xf8\x7f\x80\xfc\x8b\xe7\xa2\x25\xff\x22\xfb\xb9\xc8\xb6\xb1\xd7\x33\x0c\x57\x84\x0d\x24\xbc\x75\xb0\x6b\x80\xd3\x0d\xad\x68\x06\x54\x4d\x51\x0a\xf6\xc4\x78\x5e\x82\x3a\xc3\xe0\xb8",
+ "\x0d\xdd\xd1\x52\xcf\x06\x3f\x0f\x50\x5b\x51\x8e\xb8\xdb\x75\x57\x04\xf4\x5c\x97\x35\x78\x0e\xc3\xa8\x98\xa9\x23",
+ 187 },
+ { GCRY_MD_SHA3_224,
+ "\x6b\x01\x87\x10\x44\x6f\x36\x8e\x74\x21\xf1\xbc\x0c\xcf\x56\x2d\x9c\x18\x43\x84\x6b\xc8\xd9\x8d\x1c\x9b\xf7\xd9\xd6\xfc\xb4\x8b\xfc\x3b\xf8\x3b\x36\xd4\x4c\x4f\xa9\x34\x30\xaf\x75\xcd\x19\x0b\xde\x36\xa7\xf9\x2f\x86\x7f\x58\xa8\x03\x90\x0d\xf8\x01\x81\x50\x38\x4d\x85\xd8\x21\x32\xf1\x23\x00\x6a\xc2\xae\xba\x58\xe0\x2a\x03\x7f\xe6\xaf\xbd\x65\xec\xa7\xc4\x49\x77\xdd\x3d\xc7\x4f\x48\xb6\xe7\xa1\xbf\xd5\xcc\x4d\xcf\x24\xe4\xd5\x2e\x92\xbd\x44\x55\x84\x8e\x49\x28\xb0\xea\xc8\xb7\x47\x6f\xe3\xcc\x03\xe8\x62\xaa\x4d\xff\x44\x70\xdb\xfe\xd6\xde\x48\xe4\x10\xf2\x50\x96\x48\x7e\xcf\xc3\x2a\x27\x27\x7f\x3f\x50\x23\xb2\x72\x5a\xde\x46\x1b\x13\x55\x88\x95\x54\xa8\x83\x6c\x9c\xf5\x3b\xd7\x67\xf5\x73\x7d\x55\x18\x4e\xea\x1a\xb3\xf5\x3e\xdd\x09\x76\xc4\x85",
+ "\x57\x39\x7b\xb1\xf8\x47\x11\x64\x1e\x94\xf4\x13\xf5\xd7\x35\x56\xb9\x6b\xa5\xcf\xe1\x5f\x70\x95\x28\x62\x6d\x07",
+ 188 },
+ { GCRY_MD_SHA3_224,
+ "\xc9\x53\x4a\x24\x71\x4b\xd4\xbe\x37\xc8\x8a\x3d\xa1\x08\x2e\xda\x7c\xab\xd1\x54\xc3\x09\xd7\xbd\x67\x0d\xcc\xd9\x5a\xa5\x35\x59\x44\x63\x05\x8a\x29\xf7\x90\x31\xd6\xec\xaa\x9f\x67\x5d\x12\x11\xe9\x35\x9b\xe8\x26\x69\xa7\x9c\x85\x5e\xa8\xd8\x9d\xd3\x8c\x2c\x76\x1d\xdd\x0e\xc0\xce\x9e\x97\x59\x74\x32\xe9\xa1\xbe\xae\x06\x2c\xdd\x71\xed\xfd\xfd\x46\x41\x19\xbe\x9e\x69\xd1\x8a\x7a\x7f\xd7\xce\x0e\x21\x06\xf0\xc8\xb0\xab\xf4\x71\x5e\x2c\xa4\x8e\xf9\xf4\x54\xdc\x20\x3c\x96\x65\x66\x53\xb7\x27\x08\x35\x13\xf8\xef\xb8\x6e\x49\xc5\x13\xbb\x75\x8b\x3b\x05\x2f\xe2\x1f\x1c\x05\xbb\x33\xc3\x71\x29\xd6\xcc\x81\xf1\xae\xf6\xad\xc4\x5b\x0e\x88\x27\xa8\x30\xfe\x54\x5c\xf5\x7d\x09\x55\x80\x2c\x11\x7d\x23\xcc\xb5\x5e\xa2\x8f\x95\xc0\xd8\xc2\xf9\xc5\xa2\x42\xb3\x3f",
+ "\x68\xf6\xac\x42\x89\xfd\x52\x14\x26\x31\x30\x83\x0f\xda\x4d\xa6\x01\xb8\x8b\x1f\x85\x33\xea\xc0\x7a\x03\x38\xd9",
+ 189 },
+ { GCRY_MD_SHA3_224,
+ "\x07\x90\x6c\x87\x29\x7b\x86\x7a\xbf\x45\x76\xe9\xf3\xcc\x7f\x82\xf2\x2b\x15\x4a\xfc\xbf\x29\x3b\x93\x19\xf1\xb0\x58\x4d\xa6\xa4\x0c\x27\xb3\x2e\x0b\x1b\x7f\x41\x2c\x4f\x1b\x82\x48\x0e\x70\xa9\x23\x5b\x12\xec\x27\x09\x0a\x5a\x33\x17\x5a\x2b\xb2\x8d\x8a\xdc\x47\x5c\xef\xe3\x3f\x78\x03\xf8\xce\x27\x96\x72\x17\x38\x1f\x02\xe6\x7a\x3b\x4f\x84\xa7\x1f\x1c\x52\x28\xe0\xc2\xad\x97\x13\x73\xf6\xf6\x72\x62\x4f\xce\xa8\xd1\xa9\xf8\x51\x70\xfa\xd3\x0f\xa0\xbb\xd2\x50\x35\xc3\xb4\x1a\x61\x75\xd4\x67\x99\x8b\xd1\x21\x5f\x6f\x38\x66\xf5\x38\x47\xf9\xcf\x68\xef\x3e\x2f\xbb\x54\xbc\x99\x4d\xe2\x30\x2b\x82\x9c\x5e\xea\x68\xec\x44\x1f\xcb\xaf\xd7\xd1\x6a\xe4\xfe\x9f\xff\x98\xbf\x00\xe5\xbc\x2a\xd5\x4d\xd9\x1f\xf9\xfd\xa4\xdd\x77\xb6\xc7\x54\xa9\x19\x55\xd1\xfb\xaa\xd0",
+ "\xf1\x45\xc4\x52\x12\x39\x28\x94\xe7\xf1\xc4\xe5\x27\x28\x47\x0f\x8a\x2d\x96\x15\x14\x86\x99\x90\xef\xbe\x82\x32",
+ 190 },
+ { GCRY_MD_SHA3_224,
+ "\x58\x8e\x94\xb9\x05\x4a\xbc\x21\x89\xdf\x69\xb8\xba\x34\x34\x1b\x77\xcd\xd5\x28\xe7\x86\x0e\x5d\xef\xca\xa7\x9b\x0c\x9a\x45\x2a\xd4\xb8\x2a\xa3\x06\xbe\x84\x53\x6e\xb7\xce\xdc\xbe\x05\x8d\x7b\x84\xa6\xae\xf8\x26\xb0\x28\xb8\xa0\x27\x1b\x69\xac\x36\x05\xa9\x63\x5e\xa9\xf5\xea\x0a\xa7\x00\xf3\xeb\x78\x35\xbc\x54\x61\x1b\x92\x29\x64\x30\x0c\x95\x3e\xfe\x74\x91\xe3\x67\x7c\x2c\xeb\xe0\x82\x2e\x95\x6c\xd1\x64\x33\xb0\x2c\x68\xc4\xa2\x32\x52\xc3\xf9\xe1\x51\xa4\x16\xb4\x96\x32\x57\xb7\x83\xe0\x38\xf6\xb4\xd5\xc9\xf1\x10\xf8\x71\x65\x2c\x7a\x64\x9a\x7b\xce\xdc\xbc\xcc\x6f\x2d\x07\x25\xbb\x90\x3c\xc1\x96\xba\x76\xc7\x6a\xa9\xf1\x0a\x19\x0b\x1d\x11\x68\x99\x3b\xaa\x9f\xfc\x96\xa1\x65\x52\x16\x77\x34\x58\xbe\xc7\x2b\x0e\x39\xc9\xf2\xc1\x21\x37\x8f\xea\xb4\xe7\x6a",
+ "\x38\xce\x71\x00\xe9\x2e\xe4\xb6\x5c\xc8\x31\x91\x5a\x06\xcf\xc2\x10\x19\x90\xcb\x68\xe1\x00\x4f\x7e\x90\x17\xd4",
+ 191 },
+ { GCRY_MD_SHA3_224,
+ "\x08\x95\x9a\x7e\x4b\xaa\xe8\x74\x92\x88\x13\x36\x40\x71\x19\x4e\x29\x39\x77\x2f\x20\xdb\x7c\x31\x57\x07\x89\x87\xc5\x57\xc2\xa6\xd5\xab\xe6\x8d\x52\x0e\xef\x3d\xc4\x91\x69\x2e\x1e\x21\xbc\xd8\x80\xad\xeb\xf6\x3b\xb4\x21\x3b\x50\x89\x7f\xa0\x05\x25\x6e\xd4\x1b\x56\x90\xf7\x8f\x52\x85\x5c\x8d\x91\x68\xa4\xb6\x66\xfc\xe2\xda\x2b\x45\x6d\x7a\x7e\x7c\x17\xab\x5f\x2f\xb1\xee\x90\xb7\x9e\x69\x87\x12\xe9\x63\x71\x59\x83\xfd\x07\x64\x1a\xe4\xb4\xe9\xdc\x73\x20\x3f\xac\x1a\xe1\x1f\xa1\xf8\xc7\x94\x1f\xcc\x82\xea\xb2\x47\xad\xdb\x56\xe2\x63\x84\x47\xe9\xd6\x09\xe6\x10\xb6\x0c\xe0\x86\x65\x6a\xae\xbf\x1d\xa3\xc8\xa2\x31\xd7\xd9\x4e\x2f\xd0\xaf\xe4\x6b\x39\x1f\xf1\x4a\x72\xea\xeb\x3f\x44\xad\x4d\xf8\x58\x66\xde\xf4\x3d\x47\x81\xa0\xb3\x57\x8b\xc9\x96\xc8\x79\x70\xb1\x32",
+ "\xbd\x63\xca\x84\xda\xc8\xbc\x58\x6d\x0f\x0b\xe3\x52\xdb\xbb\xa1\xf4\xcb\x43\x0d\xea\xa8\x11\x9b\x8d\xa1\x3c\x06",
+ 192 },
+ { GCRY_MD_SHA3_224,
+ "\xcb\x2a\x23\x4f\x45\xe2\xec\xd5\x86\x38\x95\xa4\x51\xd3\x89\xa3\x69\xaa\xb9\x9c\xfe\xf0\xd5\xc9\xff\xca\x1e\x6e\x63\xf7\x63\xb5\xc1\x4f\xb9\xb4\x78\x31\x3c\x8e\x8c\x0e\xfe\xb3\xac\x95\x00\xcf\x5f\xd9\x37\x91\xb7\x89\xe6\x7e\xac\x12\xfd\x03\x8e\x25\x47\xcc\x8e\x0f\xc9\xdb\x59\x1f\x33\xa1\xe4\x90\x7c\x64\xa9\x22\xdd\xa2\x3e\xc9\x82\x73\x10\xb3\x06\x09\x85\x54\xa4\xa7\x8f\x05\x02\x62\xdb\x5b\x54\x5b\x15\x9e\x1f\xf1\xdc\xa6\xeb\x73\x4b\x87\x23\x43\xb8\x42\xc5\x7e\xaf\xcf\xda\x84\x05\xee\xdb\xb4\x8e\xf3\x2e\x99\x69\x6d\x13\x59\x79\x23\x5c\x3a\x05\x36\x4e\x37\x1c\x2d\x76\xf1\x90\x2f\x1d\x83\x14\x6d\xf9\x49\x5c\x0a\x6c\x57\xd7\xbf\x9e\xe7\x7e\x80\xf9\x78\x7a\xee\x27\xbe\x1f\xe1\x26\xcd\xc9\xef\x89\x3a\x4a\x7d\xcb\xbc\x36\x7e\x40\xfe\x4e\x1e\xe9\x0b\x42\xea\x25\xaf\x01",
+ "\x7e\xe4\xea\xea\x61\x27\xc6\x8e\xfc\xe6\x69\x91\xb8\xf0\x85\x1f\xe0\x72\xdf\x3b\x1e\x0b\x5d\x07\xe3\xa4\xbe\x06",
+ 193 },
+ { GCRY_MD_SHA3_224,
+ "\xd1\x6b\xea\xdf\x02\xab\x1d\x4d\xc6\xf8\x8b\x8c\x45\x54\xc5\x1e\x86\x6d\xf8\x30\xb8\x9c\x06\xe7\x86\xa5\xf8\x75\x7e\x89\x09\x31\x0a\xf5\x1c\x84\x0e\xfe\x8d\x20\xb3\x53\x31\xf4\x35\x5d\x80\xf7\x32\x95\x97\x46\x53\xdd\xd6\x20\xcd\xde\x47\x30\xfb\x6c\x8d\x0d\x2d\xcb\x2b\x45\xd9\x2d\x4f\xbd\xb5\x67\xc0\xa3\xe8\x6b\xd1\xa8\xa7\x95\xaf\x26\xfb\xf2\x9f\xc6\xc6\x59\x41\xcd\xdb\x09\x0f\xf7\xcd\x23\x0a\xc5\x26\x8a\xb4\x60\x6f\xcc\xba\x9e\xde\xd0\xa2\xb5\xd0\x14\xee\x0c\x34\xf0\xb2\x88\x1a\xc0\x36\xe2\x4e\x15\x1b\xe8\x9e\xeb\x6c\xd9\xa7\xa7\x90\xaf\xcc\xff\x23\x4d\x7c\xb1\x1b\x99\xeb\xf5\x8c\xd0\xc5\x89\xf2\x0b\xda\xc4\xf9\xf0\xe2\x8f\x75\xe3\xe0\x4e\x5b\x3d\xeb\xce\x60\x7a\x49\x6d\x84\x8d\x67\xfa\x7b\x49\x13\x2c\x71\xb8\x78\xfd\x55\x57\xe0\x82\xa1\x8e\xca\x1f\xbd\xa9\x4d\x4b",
+ "\x7f\x3e\xe5\x78\xb0\x41\x06\x87\xea\xf5\x36\xf9\xec\x7d\x65\x4b\x75\xf5\x04\xc1\x04\xb7\x87\x93\xc4\xcf\x90\xd5",
+ 194 },
+ { GCRY_MD_SHA3_224,
+ "\x8f\x65\xf6\xbc\x59\xa8\x57\x05\x01\x6e\x2b\xae\x7f\xe5\x79\x80\xde\x31\x27\xe5\xab\x27\x5f\x57\x3d\x33\x4f\x73\xf8\x60\x31\x06\xec\x35\x53\x01\x66\x08\xef\x2d\xd6\xe6\x9b\x24\xbe\x0b\x71\x13\xbf\x6a\x76\x0b\xa6\xe9\xce\x1c\x48\xf9\xe1\x86\x01\x2c\xf9\x6a\x1d\x48\x49\xd7\x5d\xf5\xbb\x83\x15\x38\x7f\xd7\x8e\x9e\x15\x3e\x76\xf8\xba\x7e\xc6\xc8\x84\x98\x10\xf5\x9f\xb4\xbb\x9b\x00\x43\x18\x21\x0b\x37\xf1\x29\x95\x26\x86\x6f\x44\x05\x9e\x01\x7e\x22\xe9\x6c\xbe\x41\x86\x99\xd0\x14\xc6\xea\x01\xc9\xf0\x03\x8b\x10\x29\x98\x84\xdb\xec\x31\x99\xbb\x05\xad\xc9\x4e\x95\x5a\x15\x33\x21\x9c\x11\x15\xfe\xd0\xe5\xf2\x12\x28\xb0\x71\xf4\x0d\xd5\x7c\x42\x40\xd9\x8d\x37\xb7\x3e\x41\x2f\xe0\xfa\x47\x03\x12\x0d\x7c\x0c\x67\x97\x2e\xd2\x33\xe5\xde\xb3\x00\xa2\x26\x05\x47\x2f\xa3\xa3\xba\x86",
+ "\xc9\xc2\x63\x96\xe5\x60\xcd\x1e\x68\x24\xd9\xe5\x6e\x17\x9f\xcc\x8a\xac\x4c\x0d\x93\x2f\x76\x32\xba\x59\x4d\x4c",
+ 195 },
+ { GCRY_MD_SHA3_224,
+ "\x84\x89\x1e\x52\xe0\xd4\x51\x81\x32\x10\xc3\xfd\x63\x5b\x39\xa0\x3a\x6b\x7a\x73\x17\xb2\x21\xa7\xab\xc2\x70\xdf\xa9\x46\xc4\x26\x69\xaa\xcb\xbb\xdf\x80\x1e\x15\x84\xf3\x30\xe2\x8c\x72\x98\x47\xea\x14\x15\x2b\xd6\x37\xb3\xd0\xf2\xb3\x8b\x4b\xd5\xbf\x9c\x79\x1c\x58\x80\x62\x81\x10\x3a\x3e\xab\xba\xed\xe5\xe7\x11\xe5\x39\xe6\xa8\xb2\xcf\x29\x7c\xf3\x51\xc0\x78\xb4\xfa\x8f\x7f\x35\xcf\x61\xbe\xbf\x88\x14\xbf\x24\x8a\x01\xd4\x1e\x86\xc5\x71\x5e\xa4\x0c\x63\xf7\x37\x53\x79\xa7\xeb\x1d\x78\xf2\x76\x22\xfb\x46\x8a\xb7\x84\xaa\xab\xa4\xe5\x34\xa6\xdf\xd1\xdf\x6f\xa1\x55\x11\x34\x1e\x72\x5e\xd2\xe8\x7f\x98\x73\x7c\xcb\x7b\x6a\x6d\xfa\xe4\x16\x47\x74\x72\xb0\x46\xbf\x18\x11\x18\x7d\x15\x1b\xfa\x9f\x7b\x2b\xf9\xac\xdb\x23\xa3\xbe\x50\x7c\xdf\x14\xcf\xdf\x51\x7d\x2c\xb5\xfb\x9e\x4a\xb6",
+ "\xef\x30\x65\x2e\x3c\x6e\xa4\xec\x21\x44\x72\xbf\x96\xe5\xf3\x0d\xca\x1d\x31\xa7\x8e\xb4\x22\x73\x46\x15\xea\xf1",
+ 196 },
+ { GCRY_MD_SHA3_224,
+ "\xfd\xd7\xa9\x43\x3a\x3b\x4a\xfa\xbd\x7a\x3a\x5e\x34\x57\xe5\x6d\xeb\xf7\x8e\x84\xb7\xa0\xb0\xca\x0e\x8c\x6d\x53\xbd\x0c\x2d\xae\x31\xb2\x70\x0c\x61\x28\x33\x4f\x43\x98\x1b\xe3\xb2\x13\xb1\xd7\xa1\x18\xd5\x9c\x7e\x6b\x64\x93\xa8\x6f\x86\x6a\x16\x35\xc1\x28\x59\xcf\xb9\xad\x17\x46\x0a\x77\xb4\x52\x2a\x5c\x18\x83\xc3\xd6\xac\xc8\x6e\x61\x62\x66\x7e\xc4\x14\xe9\xa1\x04\xaa\x89\x20\x53\xa2\xb1\xd7\x21\x65\xa8\x55\xba\xcd\x8f\xaf\x80\x34\xa5\xdd\x9b\x71\x6f\x47\xa0\x81\x8c\x09\xbb\x6b\xaf\x22\xaa\x50\x3c\x06\xb4\xca\x26\x1f\x55\x77\x61\x98\x9d\x2a\xfb\xd8\x8b\x6a\x67\x8a\xd1\x28\xaf\x68\x67\x21\x07\xd0\xf1\xfc\x73\xc5\xca\x74\x04\x59\x29\x7b\x32\x92\xb2\x81\xe9\x3b\xce\xb7\x61\xbd\xe7\x22\x1c\x3a\x55\x70\x8e\x5e\xc8\x44\x72\xcd\xdc\xaa\x84\xec\xf2\x37\x23\xcc\x09\x91\x35\x5c\x62\x80",
+ "\x5a\x96\x4b\xf3\x8e\xb3\x47\x68\x42\x20\xa3\xe8\x3e\xb1\xef\xcb\x64\x1c\x8f\x91\x1c\xb0\x68\xa7\x74\xb2\x5b\x8c",
+ 197 },
+ { GCRY_MD_SHA3_224,
+ "\x70\xa4\x0b\xfb\xef\x92\x27\x7a\x1a\xad\x72\xf6\xb7\x9d\x01\x77\x19\x7c\x4e\xbd\x43\x26\x68\xcf\xec\x05\xd0\x99\xac\xcb\x65\x10\x62\xb5\xdf\xf1\x56\xc0\xb2\x73\x36\x68\x7a\x94\xb2\x66\x79\xcf\xdd\x9d\xaf\x7a\xd2\x04\x33\x8d\xd9\xc4\xd1\x41\x14\x03\x3a\x5c\x22\x5b\xd1\x1f\x21\x7b\x5f\x47\x32\xda\x16\x7e\xe3\xf9\x39\x26\x2d\x40\x43\xfc\x9c\xba\x92\x30\x3b\x7b\x5e\x96\xae\xa1\x2a\xdd\xa6\x48\x59\xdf\x4b\x86\xe9\xee\x0b\x58\xe3\x90\x91\xe6\xb1\x88\xb4\x08\xac\x94\xe1\x29\x4a\x89\x11\x24\x5e\xe3\x61\xe6\x0e\x60\x1e\xff\x58\xd1\xd3\x76\x39\xf3\x75\x3b\xec\x80\xeb\xb4\xef\xde\x25\x81\x74\x36\x07\x66\x23\xfc\x65\x41\x5f\xe5\x1d\x1b\x02\x80\x36\x6d\x12\xc5\x54\xd8\x67\x43\xf3\xc3\xb6\x57\x2e\x40\x03\x61\xa6\x07\x26\x13\x14\x41\xba\x49\x3a\x83\xfb\xe9\xaf\xda\x90\xf7\xaf\x1a\xe7\x17\x23\x8d",
+ "\x07\x41\x36\x65\xed\xcb\x8a\x35\x02\x18\x74\x98\x49\x10\xb4\x98\xcf\x74\x82\x30\x50\x64\x02\x43\xae\x7c\x84\xcd",
+ 198 },
+ { GCRY_MD_SHA3_224,
+ "\x74\x35\x6e\x44\x9f\x4b\xf8\x64\x4f\x77\xb1\x4f\x4d\x67\xcb\x6b\xd9\xc1\xf5\xae\x35\x76\x21\xd5\xb8\x14\x7e\x56\x2b\x65\xc6\x65\x85\xca\xf2\xe4\x91\xb4\x85\x29\xa0\x1a\x34\xd2\x26\xd4\x36\x95\x91\x53\x81\x53\x80\xd5\x68\x9e\x30\xb3\x53\x57\xcd\xac\x6e\x08\xd3\xf2\xb0\xe8\x8e\x20\x06\x00\xd6\x2b\xd9\xf5\xea\xf4\x88\xdf\x86\xa4\x47\x0e\xa2\x27\x00\x61\x82\xe4\x48\x09\x00\x98\x68\xc4\xc2\x80\xc4\x3d\x7d\x64\xa5\x26\x8f\xa7\x19\x07\x49\x60\x08\x7b\x3a\x6a\xbc\x83\x78\x82\xf8\x82\xc8\x37\x83\x45\x35\x92\x93\x89\xa1\x2b\x2c\x78\x18\x7e\x2e\xa0\x7e\xf8\xb8\xee\xf2\x7d\xc8\x50\x02\xc3\xae\x35\xf1\xa5\x0b\xee\x6a\x1c\x48\xba\x7e\x17\x5f\x33\x16\x67\x0b\x27\x98\x34\x72\xaa\x6a\x61\xee\xd0\xa6\x83\xa3\x9e\xe3\x23\x08\x06\x20\xea\x44\xa9\xf7\x44\x11\xae\x5c\xe9\x90\x30\x52\x8f\x9a\xb4\x9c\x79\xf2",
+ "\xfc\xc9\xea\xd1\x60\x83\x2f\x5f\x0f\xaf\xed\x63\x81\xaf\xd5\x7f\xe1\x33\x5f\xbf\xb0\x5b\x7f\xb1\xf0\x07\x5d\x37",
+ 199 },
+ { GCRY_MD_SHA3_224,
+ "\x8c\x37\x98\xe5\x1b\xc6\x84\x82\xd7\x33\x7d\x3a\xbb\x75\xdc\x9f\xfe\x86\x07\x14\xa9\xad\x73\x55\x1e\x12\x00\x59\x86\x0d\xde\x24\xab\x87\x32\x72\x22\xb6\x4c\xf7\x74\x41\x5a\x70\xf7\x24\xcd\xf2\x70\xde\x3f\xe4\x7d\xda\x07\xb6\x1c\x9e\xf2\xa3\x55\x1f\x45\xa5\x58\x48\x60\x24\x8f\xab\xde\x67\x6e\x1c\xd7\x5f\x63\x55\xaa\x3e\xae\xab\xe3\xb5\x1d\xc8\x13\xd9\xfb\x2e\xaa\x4f\x0f\x1d\x9f\x83\x4d\x7c\xad\x9c\x7c\x69\x5a\xe8\x4b\x32\x93\x85\xbc\x0b\xef\x89\x5b\x9f\x1e\xdf\x44\xa0\x3d\x4b\x41\x0c\xc2\x3a\x79\xa6\xb6\x2e\x4f\x34\x6a\x5e\x8d\xd8\x51\xc2\x85\x79\x95\xdd\xbf\x5b\x2d\x71\x7a\xeb\x84\x73\x10\xe1\xf6\xa4\x6a\xc3\xd2\x6a\x7f\x9b\x44\x98\x5a\xf6\x56\xd2\xb7\xc9\x40\x6e\x8a\x9e\x8f\x47\xdc\xb4\xef\x6b\x83\xca\xac\xf9\xae\xfb\x61\x18\xbf\xcf\xf7\xe4\x4b\xef\x69\x37\xeb\xdd\xc8\x91\x86\x83\x9b\x77",
+ "\xec\x5c\x6d\xb6\x0b\x08\x34\xfb\x2e\x0e\x71\x06\xae\xea\xfb\x9e\x61\x4b\xe0\x93\xc8\x47\x01\x82\x14\xd8\xa5\xdb",
+ 200 },
+ { GCRY_MD_SHA3_224,
+ "\xfa\x56\xbf\x73\x0c\x4f\x83\x95\x87\x51\x89\xc1\x0c\x4f\xb2\x51\x60\x57\x57\xa8\xfe\xcc\x31\xf9\x73\x7e\x3c\x25\x03\xb0\x26\x08\xe6\x73\x1e\x85\xd7\xa3\x83\x93\xc6\x7d\xe5\x16\xb8\x53\x04\x82\x4b\xfb\x13\x5e\x33\xbf\x22\xb3\xa2\x3b\x91\x3b\xf6\xac\xd2\xb7\xab\x85\x19\x8b\x81\x87\xb2\xbc\xd4\x54\xd5\xe3\x31\x8c\xac\xb3\x2f\xd6\x26\x1c\x31\xae\x7f\x6c\x54\xef\x6a\x7a\x2a\x4c\x9f\x3e\xcb\x81\xce\x35\x55\xd4\xf0\xad\x46\x6d\xd4\xc1\x08\xa9\x03\x99\xd7\x00\x41\x99\x7c\x3b\x25\x34\x5a\x96\x53\xf3\xc9\xa6\x71\x1a\xb1\xb9\x1d\x6a\x9d\x22\x16\x44\x2d\xa2\xc9\x73\xcb\xd6\x85\xee\x76\x43\xbf\xd7\x73\x27\xa2\xf7\xae\x9c\xb2\x83\x62\x0a\x08\x71\x6d\xfb\x46\x2e\x5c\x1d\x65\x43\x2c\xa9\xd5\x6a\x90\xe8\x11\x44\x3c\xd1\xec\xb8\xf0\xde\x17\x9c\x9c\xb4\x8b\xa4\xf6\xfe\xc3\x60\xc6\x6f\x25\x2f\x6e\x64\xed\xc9\x6b",
+ "\x0d\x5f\x6d\xe1\x6b\x7c\xbb\xa4\x9c\x28\x65\x4f\x2a\xe9\x81\x63\x25\x7e\x7b\x6b\x50\x0a\x38\x01\xee\xf0\x73\x3f",
+ 201 },
+ { GCRY_MD_SHA3_224,
+ "\xb6\x13\x4f\x9c\x3e\x91\xdd\x80\x00\x74\x0d\x00\x9d\xd8\x06\x24\x08\x11\xd5\x1a\xb1\x54\x6a\x97\x4b\xcb\x18\xd3\x44\x64\x2b\xaa\x5c\xd5\x90\x3a\xf8\x4d\x58\xec\x5b\xa1\x73\x01\xd5\xec\x0f\x10\xcc\xd0\x50\x9c\xbb\x3f\xd3\xff\xf9\x17\x2d\x19\x3a\xf0\xf7\x82\x25\x2f\xd1\x33\x8c\x72\x44\xd4\x0e\x0e\x42\x36\x22\x75\xb2\x2d\x01\xc4\xc3\x38\x9f\x19\xdd\x69\xbd\xf9\x58\xeb\xe2\x8e\x31\xa4\xff\xe2\xb5\xf1\x8a\x87\x83\x1c\xfb\x70\x95\xf5\x8a\x87\xc9\xfa\x21\xdb\x72\xba\x26\x93\x79\xb2\xdc\x23\x84\xb3\xda\x95\x3c\x79\x25\x76\x1f\xed\x32\x46\x20\xac\xea\x43\x5e\x52\xb4\x24\xa7\x72\x3f\x6a\x23\x57\x37\x41\x57\xa3\x4c\xd8\x25\x23\x51\xc2\x5a\x1b\x23\x28\x26\xce\xfe\x1b\xd3\xe7\x0f\xfc\x15\xa3\x1e\x7c\x05\x98\x21\x9d\x7f\x00\x43\x62\x94\xd1\x18\x91\xb8\x24\x97\xbc\x78\xaa\x53\x63\x89\x2a\x24\x95\xdf\x8c\x1e\xef",
+ "\x7b\x7e\x1f\xc4\xd3\x83\x3e\xd8\x7f\xd1\x66\xf9\x09\xf5\xc2\x56\x6d\xc0\xe9\x5b\x17\xac\x83\x4f\x1e\x9e\x3d\xad",
+ 202 },
+ { GCRY_MD_SHA3_224,
+ "\xc9\x41\xcd\xb9\xc2\x8a\xb0\xa7\x91\xf2\xe5\xc8\xe8\xbb\x52\x85\x06\x26\xaa\x89\x20\x5b\xec\x3a\x7e\x22\x68\x23\x13\xd1\x98\xb1\xfa\x33\xfc\x72\x95\x38\x13\x54\x85\x87\x58\xae\x6c\x8e\xc6\xfa\xc3\x24\x5c\x6e\x45\x4d\x16\xfa\x2f\x51\xc4\x16\x6f\xab\x51\xdf\x27\x28\x58\xf2\xd6\x03\x77\x0c\x40\x98\x7f\x64\x44\x2d\x48\x7a\xf4\x9c\xd5\xc3\x99\x1c\xe8\x58\xea\x2a\x60\xda\xb6\xa6\x5a\x34\x41\x49\x65\x93\x39\x73\xac\x24\x57\x08\x9e\x35\x91\x60\xb7\xcd\xed\xc4\x2f\x29\xe1\x0a\x91\x92\x17\x85\xf6\xb7\x22\x4e\xe0\xb3\x49\x39\x3c\xdc\xff\x61\x51\xb5\x0b\x37\x7d\x60\x95\x59\x92\x3d\x09\x84\xcd\xa6\x00\x08\x29\xb9\x16\xab\x68\x96\x69\x3e\xf6\xa2\x19\x9b\x3c\x22\xf7\xdc\x55\x00\xa1\x5b\x82\x58\x42\x0e\x31\x4c\x22\x2b\xc0\x00\xbc\x4e\x54\x13\xe6\xdd\x82\xc9\x93\xf8\x33\x0f\x5c\x6d\x1b\xe4\xbc\x79\xf0\x8a\x1a\x0a\x46",
+ "\xc6\xac\x9d\x54\x64\x85\x5e\x5c\x2f\x83\xf2\xa5\x6f\x9a\x99\x21\x37\xda\x47\xec\x05\xc5\x41\x29\x5f\x8c\x43\xe7",
+ 203 },
+ { GCRY_MD_SHA3_224,
+ "\x44\x99\xef\xff\xac\x4b\xce\xa5\x27\x47\xef\xd1\xe4\xf2\x0b\x73\xe4\x87\x58\xbe\x91\x5c\x88\xa1\xff\xe5\x29\x9b\x0b\x00\x58\x37\xa4\x6b\x2f\x20\xa9\xcb\x3c\x6e\x64\xa9\xe3\xc5\x64\xa2\x7c\x0f\x1c\x6a\xd1\x96\x03\x73\x03\x6e\xc5\xbf\xe1\xa8\xfc\x6a\x43\x5c\x21\x85\xed\x0f\x11\x4c\x50\xe8\xb3\xe4\xc7\xed\x96\xb0\x6a\x03\x68\x19\xc9\x46\x3e\x86\x4a\x58\xd6\x28\x6f\x78\x5e\x32\xa8\x04\x44\x3a\x56\xaf\x0b\x4d\xf6\xab\xc5\x7e\xd5\xc2\xb1\x85\xdd\xee\x84\x89\xea\x08\x0d\xee\xee\x66\xaa\x33\xc2\xe6\xda\xb3\x62\x51\xc4\x02\x68\x2b\x68\x24\x82\x1f\x99\x8c\x32\x16\x31\x64\x29\x8e\x1f\xaf\xd3\x1b\xab\xbc\xff\xb5\x94\xc9\x18\x88\xc6\x21\x90\x79\xd9\x07\xfd\xb4\x38\xed\x89\x52\x9d\x6d\x96\x21\x2f\xd5\x5a\xbe\x20\x39\x9d\xbe\xfd\x34\x22\x48\x50\x74\x36\x93\x1c\xde\xad\x49\x6e\xb6\xe4\xa8\x03\x58\xac\xc7\x86\x47\xd0\x43",
+ "\x4e\xe2\xf9\x3c\x18\x97\x4d\x97\x8d\xd3\xa1\xcb\xf8\xb1\xda\xc4\x73\x80\x70\x67\xb8\x80\x7d\x02\x61\x82\xb9\x01",
+ 204 },
+ { GCRY_MD_SHA3_224,
+ "\xee\xcb\xb8\xfd\xfa\x4d\xa6\x21\x70\xfd\x06\x72\x7f\x69\x7d\x81\xf8\x3f\x60\x1f\xf6\x1e\x47\x81\x05\xd3\xcb\x75\x02\xf2\xc8\x9b\xf3\xe8\xf5\x6e\xdd\x46\x9d\x04\x98\x07\xa3\x88\x82\xa7\xee\xfb\xc8\x5f\xc9\xa9\x50\x95\x2e\x9f\xa8\x4b\x8a\xfe\xbd\x3c\xe7\x82\xd4\xda\x59\x80\x02\x82\x7b\x1e\xb9\x88\x82\xea\x1f\x0a\x8f\x7a\xa9\xce\x01\x3a\x6e\x9b\xc4\x62\xfb\x66\xc8\xd4\xa1\x8d\xa2\x14\x01\xe1\xb9\x33\x56\xeb\x12\xf3\x72\x5b\x6d\xb1\x68\x4f\x23\x00\xa9\x8b\x9a\x11\x9e\x5d\x27\xff\x70\x4a\xff\xb6\x18\xe1\x27\x08\xe7\x7e\x6e\x5f\x34\x13\x9a\x5a\x41\x13\x1f\xd1\xd6\x33\x6c\x27\x2a\x8f\xc3\x70\x80\xf0\x41\xc7\x13\x41\xbe\xe6\xab\x55\x0c\xb4\xa2\x0a\x6d\xdb\x6a\x8e\x02\x99\xf2\xb1\x4b\xc7\x30\xc5\x4b\x8b\x1c\x1c\x48\x7b\x49\x4b\xdc\xcf\xd3\xa5\x35\x35\xab\x2f\x23\x15\x90\xbf\x2c\x40\x62\xfd\x2a\xd5\x8f\x90\x6a\x2d\x0d",
+ "\xd6\x4a\xee\x17\xed\x8e\x2b\x85\xe6\xb0\x97\xdb\x49\x55\x4d\x35\x6f\x03\x2a\x34\xa1\x5b\x7e\x84\x4e\xc8\xd8\x89",
+ 205 },
+ { GCRY_MD_SHA3_224,
+ "\xe6\x4f\x3e\x4a\xce\x5c\x84\x18\xd6\x5f\xec\x2b\xc5\xd2\xa3\x03\xdd\x45\x80\x34\x73\x6e\x3b\x0d\xf7\x19\x09\x8b\xe7\xa2\x06\xde\xaf\x52\xd6\xba\x82\x31\x6c\xaf\x33\x0e\xf8\x52\x37\x51\x88\xcd\xe2\xb3\x9c\xc9\x4a\xa4\x49\x57\x8a\x7e\x2a\x8e\x3f\x5a\x9d\x68\xe8\x16\xb8\xd1\x68\x89\xfb\xc0\xeb\xf0\x93\x9d\x04\xf6\x30\x33\xae\x9a\xe2\xbd\xab\x73\xb8\x8c\x26\xd6\xbd\x25\xee\x46\x0e\xe1\xef\x58\xfb\x0a\xfa\x92\xcc\x53\x9f\x8c\x76\xd3\xd0\x97\xe7\xa6\xa6\x3e\xbb\x9b\x58\x87\xed\xf3\xcf\x07\x60\x28\xc5\xbb\xd5\xb9\xdb\x32\x11\x37\x1a\xd3\xfe\x12\x1d\x4e\x9b\xf4\x42\x29\xf4\xe1\xec\xf5\xa0\xf9\xf0\xeb\xa4\xd5\xce\xb7\x28\x78\xab\x22\xc3\xf0\xeb\x5a\x62\x53\x23\xac\x66\xf7\x06\x1f\x4a\x81\xfa\xc8\x34\x47\x1e\x0c\x59\x55\x3f\x10\x84\x75\xfe\x29\x0d\x43\xe6\xa0\x55\xae\x3e\xe4\x6f\xb6\x74\x22\xf8\x14\xa6\x8c\x4b\xe3\xe8\xc9",
+ "\x1b\xdd\xc9\x2b\xe8\x9a\x67\x2c\x1b\xd9\x56\xb4\x50\xb9\xd7\xb4\x7b\x4b\xb0\xbc\x58\xac\x51\xf1\x5f\x7e\x05\x4d",
+ 206 },
+ { GCRY_MD_SHA3_224,
+ "\xd2\xcb\x2d\x73\x30\x33\xf9\xe9\x13\x95\x31\x28\x08\x38\x3c\xc4\xf0\xca\x97\x4e\x87\xec\x68\x40\x0d\x52\xe9\x6b\x3f\xa6\x98\x4a\xc5\x8d\x9a\xd0\x93\x8d\xde\x5a\x97\x30\x08\xd8\x18\xc4\x96\x07\xd9\xde\x22\x84\xe7\x61\x8f\x1b\x8a\xed\x83\x72\xfb\xd5\x2e\xd5\x45\x57\xaf\x42\x20\xfa\xc0\x9d\xfa\x84\x43\x01\x16\x99\xb9\x7d\x74\x3f\x8f\x2b\x1a\xef\x35\x37\xeb\xb4\x5d\xcc\x9e\x13\xdf\xb4\x38\x42\x8e\xe1\x90\xa4\xef\xdb\x3c\xae\xb7\xf3\x93\x31\x17\xbf\x63\xab\xdc\x7e\x57\xbe\xb4\x17\x1c\x7e\x1a\xd2\x60\xab\x05\x87\x80\x6c\x4d\x13\x7b\x63\x16\xb5\x0a\xbc\x9c\xce\x0d\xff\x3a\xca\xda\x47\xbb\xb8\x6b\xe7\x77\xe6\x17\xbb\xe5\x78\xff\x45\x19\x84\x4d\xb3\x60\xe0\xa9\x6c\x67\x01\x29\x0e\x76\xbb\x95\xd2\x6f\x0f\x80\x4c\x8a\x4f\x27\x17\xea\xc4\xe7\xde\x9f\x2c\xff\x3b\xbc\x55\xa1\x7e\x77\x6c\x0d\x02\x85\x60\x32\xa6\xcd\x10\xad\x28\x38",
+ "\x0c\x8a\xc2\x40\x17\x0c\x65\x46\xde\xbf\x4b\xfb\x5b\x38\xf8\xf3\x0e\xa5\xdc\x6e\xf8\x6c\x16\x6e\x8e\x13\x6d\x6b",
+ 207 },
+ { GCRY_MD_SHA3_224,
+ "\xf2\x99\x89\x55\x61\x3d\xd4\x14\xcc\x11\x1d\xf5\xce\x30\xa9\x95\xbb\x79\x2e\x26\x0b\x0e\x37\xa5\xb1\xd9\x42\xfe\x90\x17\x1a\x4a\xc2\xf6\x6d\x49\x28\xd7\xad\x37\x7f\x4d\x05\x54\xcb\xf4\xc5\x23\xd2\x1f\x6e\x5f\x37\x9d\x6f\x4b\x02\x8c\xdc\xb9\xb1\x75\x8d\x3b\x39\x66\x32\x42\xff\x3c\xb6\xed\xe6\xa3\x6a\x6f\x05\xdb\x3b\xc4\x1e\x0d\x86\x1b\x38\x4b\x6d\xec\x58\xbb\x09\x6d\x0a\x42\x2f\xd5\x42\xdf\x17\x5e\x1b\xe1\x57\x1f\xb5\x2a\xe6\x6f\x2d\x86\xa2\xf6\x82\x4a\x8c\xfa\xac\xba\xc4\xa7\x49\x2a\xd0\x43\x3e\xeb\x15\x45\x4a\xf8\xf3\x12\xb3\xb2\xa5\x77\x75\x0e\x3e\xfb\xd3\x70\xe8\xa8\xca\xc1\x58\x25\x81\x97\x1f\xba\x3b\xa4\xbd\x0d\x76\xe7\x18\xda\xcf\x84\x33\xd3\x3a\x59\xd2\x87\xf8\xcc\x92\x23\x4e\x7a\x27\x10\x41\xb5\x26\xe3\x89\xef\xb0\xe4\x0b\x6a\x18\xb3\xaa\xf6\x58\xe8\x2e\xd1\xc7\x86\x31\xfd\x23\xb4\xc3\xeb\x27\xc3\xfa\xec\x86\x85",
+ "\x2f\xd9\xfd\xfd\x24\x4b\x0a\x73\x42\xf8\x86\xb8\x7b\x3d\xdd\xce\x54\xc8\x87\x0f\xb2\x6a\x71\xa8\xf6\x52\x02\x31",
+ 208 },
+ { GCRY_MD_SHA3_224,
+ "\x44\x77\x97\xe2\x89\x9b\x72\xa3\x56\xba\x55\xbf\x4d\xf3\xac\xca\x6c\xdb\x10\x41\xeb\x47\x7b\xd1\x83\x4a\x9f\x9a\xcb\xc3\x40\xa2\x94\xd7\x29\xf2\xf9\x7d\xf3\xa6\x10\xbe\x0f\xf1\x5e\xdb\x9c\x6d\x5d\xb4\x16\x44\xb9\x87\x43\x60\x14\x0f\xc6\x4f\x52\xaa\x03\xf0\x28\x6c\x8a\x64\x06\x70\x06\x7a\x84\xe0\x17\x92\x6a\x70\x43\x8d\xb1\xbb\x36\x1d\xef\xee\x73\x17\x02\x14\x25\xf8\x82\x1d\xef\x26\xd1\xef\xd7\x7f\xc8\x53\xb8\x18\x54\x5d\x05\x5a\xdc\x92\x84\x79\x6e\x58\x3c\x76\xe6\xfe\x74\xc9\xac\x25\x87\xaa\x46\xaa\x8f\x88\x04\xf2\xfe\xb5\x83\x6c\xc4\xb3\xab\xab\xab\x84\x29\xa5\x78\x3e\x17\xd5\x99\x9f\x32\x24\x2e\xb5\x9e\xf3\x0c\xd7\xad\xab\xc1\x6d\x72\xdb\xdb\x09\x76\x23\x04\x7c\x98\x98\x9f\x88\xd1\x4e\xaf\x02\xa7\x21\x2b\xe1\x6e\xc2\xd0\x79\x81\xaa\xa9\x99\x49\xdd\xf8\x9e\xcd\x90\x33\x3a\x77\xbc\x4e\x19\x88\xa8\x2a\xbf\x7c\x7c\xaf\x32\x91",
+ "\x1b\x6b\xe1\x9d\x72\x19\x9b\xf7\x5f\xd4\x07\x5e\x54\x97\x5a\xfa\x04\x33\xb9\xbf\x51\x5b\xd3\x00\xce\x54\x3d\x41",
+ 209 },
+ { GCRY_MD_SHA3_224,
+ "\x9f\x2c\x18\xad\xe9\xb3\x80\xc7\x84\xe1\x70\xfb\x76\x3e\x9a\xa2\x05\xf6\x43\x03\x06\x7e\xb1\xbc\xea\x93\xdf\x5d\xac\x4b\xf5\xa2\xe0\x0b\x78\x19\x5f\x80\x8d\xf2\x4f\xc7\x6e\x26\xcb\x7b\xe3\x1d\xc3\x5f\x08\x44\xcd\xed\x15\x67\xbb\xa2\x98\x58\xcf\xfc\x97\xfb\x29\x01\x03\x31\xb0\x1d\x6a\x3f\xb3\x15\x9c\xc1\xb9\x73\xd2\x55\xda\x98\x43\xe3\x4a\x0a\x40\x61\xca\xbd\xb9\xed\x37\xf2\x41\xbf\xab\xb3\xc2\x0d\x32\x74\x3f\x40\x26\xb5\x9a\x4c\xcc\x38\x5a\x23\x01\xf8\x3c\x0b\x0a\x19\x0b\x0f\x2d\x01\xac\xb8\xf0\xd4\x11\x11\xe1\x0f\x2f\x4e\x14\x93\x79\x27\x55\x99\xa5\x2d\xc0\x89\xb3\x5f\xdd\x52\x34\xb0\xcf\xb7\xb6\xd8\xae\xbd\x56\x3c\xa1\xfa\x65\x3c\x5c\x02\x1d\xfd\x6f\x59\x20\xe6\xf1\x8b\xfa\xfd\xbe\xcb\xf0\xab\x00\x28\x13\x33\xed\x50\xb9\xa9\x99\x54\x9c\x1c\x8f\x8c\x63\xd7\x62\x6c\x48\x32\x2e\x97\x91\xd5\xff\x72\x29\x40\x49\xbd\xe9\x1e\x73\xf8",
+ "\xa4\x6b\x89\xb6\x4b\x0c\x79\x30\xdd\x45\xf5\xb2\x58\x2f\xd7\x9c\x7a\xd9\x0a\x58\xc9\x4c\x52\xf9\xbf\xa5\x5c\xfc",
+ 210 },
+ { GCRY_MD_SHA3_224,
+ "\xae\x15\x9f\x3f\xa3\x36\x19\x00\x2a\xe6\xbc\xce\x8c\xbb\xdd\x7d\x28\xe5\xed\x9d\x61\x53\x45\x95\xc4\xc9\xf4\x3c\x40\x2a\x9b\xb3\x1f\x3b\x30\x1c\xbf\xd4\xa4\x3c\xe4\xc2\x4c\xd5\xc9\x84\x9c\xc6\x25\x9e\xca\x90\xe2\xa7\x9e\x01\xff\xba\xc0\x7b\xa0\xe1\x47\xfa\x42\x67\x6a\x1d\x66\x85\x70\xe0\x39\x63\x87\xb5\xbc\xd5\x99\xe8\xe6\x6a\xae\xd1\xb8\xa1\x91\xc5\xa4\x75\x47\xf6\x13\x73\x02\x1f\xa6\xde\xad\xcb\x55\x36\x3d\x23\x3c\x24\x44\x0f\x2c\x73\xdb\xb5\x19\xf7\xc9\xfa\x5a\x89\x62\xef\xd5\xf6\x25\x2c\x04\x07\xf1\x90\xdf\xef\xad\x70\x7f\x3c\x70\x07\xd6\x9f\xf3\x6b\x84\x89\xa5\xb6\xb7\xc5\x57\xe7\x9d\xd4\xf5\x0c\x06\x51\x1f\x59\x9f\x56\xc8\x96\xb3\x5c\x91\x7b\x63\xba\x35\xc6\xff\x80\x92\xba\xf7\xd1\x65\x8e\x77\xfc\x95\xd8\xa6\xa4\x3e\xeb\x4c\x01\xf3\x3f\x03\x87\x7f\x92\x77\x4b\xe8\x9c\x11\x14\xdd\x53\x1c\x01\x1e\x53\xa3\x4d\xc2\x48\xa2\xf0\xe6",
+ "\x21\xf0\xd8\x85\x53\x87\x24\x1d\x71\xa7\x12\xe5\xf5\x68\x2c\x15\x6b\x9f\xd2\xaa\x62\x84\x29\x47\x18\x85\x3f\x0a",
+ 211 },
+ { GCRY_MD_SHA3_224,
+ "\x3b\x8e\x97\xc5\xff\xc2\xd6\xa4\x0f\xa7\xde\x7f\xce\xfc\x90\xf3\xb1\x2c\x94\x0e\x7a\xb4\x15\x32\x1e\x29\xee\x69\x2d\xfa\xc7\x99\xb0\x09\xc9\x9d\xcd\xdb\x70\x8f\xce\x5a\x17\x8c\x5c\x35\xee\x2b\x86\x17\x14\x3e\xdc\x4c\x40\xb4\xd3\x13\x66\x1f\x49\xab\xdd\x93\xce\xa7\x9d\x11\x75\x18\x80\x54\x96\xfe\x6a\xcf\x29\x2c\x4c\x2a\x1f\x76\xb4\x03\xa9\x7d\x7c\x39\x9d\xaf\x85\xb4\x6a\xd8\x4e\x16\x24\x6c\x67\xd6\x83\x67\x57\xbd\xe3\x36\xc2\x90\xd5\xd4\x01\xe6\xc1\x38\x6a\xb3\x27\x97\xaf\x6b\xb2\x51\xe9\xb2\xd8\xfe\x75\x4c\x47\x48\x2b\x72\xe0\xb3\x94\xea\xb7\x69\x16\x12\x6f\xd6\x8e\xa7\xd6\x5e\xb9\x3d\x59\xf5\xb4\xc5\xac\x40\xf7\xc3\xb3\x7e\x7f\x36\x94\xf2\x94\x24\xc2\x4a\xf8\xc8\xf0\xef\x59\xcd\x9d\xbf\x1d\x28\xe0\xe1\x0f\x79\x9a\x6f\x78\xca\xd1\xd4\x5b\x9d\xb3\xd7\xde\xe4\xa7\x05\x9a\xbe\x99\x18\x27\x14\x98\x3b\x9c\x9d\x44\xd7\xf5\x64\x35\x96\xd4\xf3",
+ "\x82\xee\x85\x54\x1d\x7a\x5b\x2a\x2b\x29\x00\x03\xc3\xee\x46\x57\x4d\x58\xa7\xdd\xd5\x4f\xbc\x21\x0f\x8f\xea\x57",
+ 212 },
+ { GCRY_MD_SHA3_224,
+ "\x34\x34\xec\x31\xb1\x0f\xaf\xdb\xfe\xec\x0d\xd6\xbd\x94\xe8\x0f\x7b\xa9\xdc\xa1\x9e\xf0\x75\xf7\xeb\x01\x75\x12\xaf\x66\xd6\xa4\xbc\xf7\xd1\x6b\xa0\x81\x9a\x18\x92\xa6\x37\x2f\x9b\x35\xbc\xc7\xca\x81\x55\xee\x19\xe8\x42\x8b\xc2\x2d\x21\x48\x56\xed\x5f\xa9\x37\x4c\x3c\x09\xbd\xe1\x69\x60\x2c\xc2\x19\x67\x9f\x65\xa1\x56\x6f\xc7\x31\x6f\x4c\xc3\xb6\x31\xa1\x8f\xb4\x44\x9f\xa6\xaf\xa1\x6a\x3d\xb2\xbc\x42\x12\xef\xf5\x39\xc6\x7c\xf1\x84\x68\x08\x26\x53\x55\x89\xc7\x11\x1d\x73\xbf\xfc\xe4\x31\xb4\xc4\x04\x92\xe7\x63\xd9\x27\x95\x60\xaa\xa3\x8e\xb2\xdc\x14\xa2\x12\xd7\x23\xf9\x94\xa1\xfe\x65\x6f\xf4\xdd\x14\x55\x1c\xe4\xe7\xc6\x21\xb2\xaa\x56\x04\xa1\x00\x01\xb2\x87\x8a\x89\x7a\x28\xa0\x80\x95\xc3\x25\xe1\x0a\x26\xd2\xfb\x1a\x75\xbf\xd6\x4c\x25\x03\x09\xbb\x55\xa4\x4f\x23\xbb\xac\x0d\x55\x16\xa1\xc6\x87\xd3\xb4\x1e\xf2\xfb\xbf\x9c\xc5\x6d\x47\x39",
+ "\x27\x8d\xd8\xa3\xf3\x20\x81\x91\xcf\xf6\x58\xb8\xd6\xdb\x35\xe1\x33\xa1\x6e\x47\xaa\x37\x5e\xdb\x92\xc6\xa7\x37",
+ 213 },
+ { GCRY_MD_SHA3_224,
+ "\x7c\x79\x53\xd8\x1c\x8d\x20\x8f\xd1\xc9\x76\x81\xd4\x8f\x49\xdd\x00\x34\x56\xde\x60\x47\x5b\x84\x07\x0e\xf4\x84\x7c\x33\x3b\x74\x57\x5b\x1f\xc8\xd2\xa1\x86\x96\x44\x85\xa3\xb8\x63\x4f\xea\xa3\x59\x5a\xaa\x1a\x2f\x45\x95\xa7\xd6\xb6\x15\x35\x63\xde\xe3\x1b\xba\xc4\x43\xc8\xa3\x3e\xed\x6d\x5d\x95\x6a\x98\x0a\x68\x36\x6c\x25\x27\xb5\x50\xee\x95\x02\x50\xdf\xb6\x91\xea\xcb\xd5\xd5\x6a\xe1\x4b\x97\x06\x68\xbe\x17\x4c\x89\xdf\x2f\xea\x43\xae\x52\xf1\x31\x42\x63\x9c\x88\x4f\xd6\x2a\x36\x83\xc0\xc3\x79\x2f\x0f\x24\xab\x13\x18\xbc\xb2\x7e\x21\xf4\x73\x7f\xab\x62\xc7\x7e\xa3\x8b\xc8\xfd\x1c\xf4\x1f\x7d\xab\x64\xc1\x3f\xeb\xe7\x15\x2b\xf5\xbb\x7a\xb5\xa7\x8f\x53\x46\xd4\x3c\xc7\x41\xcb\x6f\x72\xb7\xb8\x98\x0f\x26\x8b\x68\xbf\x62\xab\xdf\xb1\x57\x7a\x52\x43\x8f\xe1\x4b\x59\x14\x98\xcc\x95\xf0\x71\x22\x84\x60\xc7\xc5\xd5\xce\xb4\xa7\xbd\xe5\x88\xe7\xf2\x1c",
+ "\xb5\x05\x27\x71\x1c\x04\x7d\xef\x70\xb1\x7c\xf2\x0f\x97\x0b\xed\x79\xc1\xc1\xb9\x52\x75\xc2\x78\x4c\x39\x03\xde",
+ 214 },
+ { GCRY_MD_SHA3_224,
+ "\x7a\x6a\x4f\x4f\xdc\x59\xa1\xd2\x23\x38\x1a\xe5\xaf\x49\x8d\x74\xb7\x25\x2e\xcf\x59\xe3\x89\xe4\x91\x30\xc7\xea\xee\x62\x6e\x7b\xd9\x89\x7e\xff\xd9\x20\x17\xf4\xcc\xde\x66\xb0\x44\x04\x62\xcd\xed\xfd\x35\x2d\x81\x53\xe6\xa4\xc8\xd7\xa0\x81\x2f\x70\x1c\xc7\x37\xb5\x17\x8c\x25\x56\xf0\x71\x11\x20\x0e\xb6\x27\xdb\xc2\x99\xca\xa7\x92\xdf\xa5\x8f\x35\x93\x52\x99\xfa\x3a\x35\x19\xe9\xb0\x31\x66\xdf\xfa\x15\x91\x03\xff\xa3\x5e\x85\x77\xf7\xc0\xa8\x6c\x6b\x46\xfe\x13\xdb\x8e\x2c\xdd\x9d\xcf\xba\x85\xbd\xdd\xcc\xe0\xa7\xa8\xe1\x55\xf8\x1f\x71\x2d\x8e\x9f\xe6\x46\x15\x3d\x3d\x22\xc8\x11\xbd\x39\xf8\x30\x43\x3b\x22\x13\xdd\x46\x30\x19\x41\xb5\x92\x93\xfd\x0a\x33\xe2\xb6\x3a\xdb\xd9\x52\x39\xbc\x01\x31\x5c\x46\xfd\xb6\x78\x87\x5b\x3c\x81\xe0\x53\xa4\x0f\x58\x1c\xfb\xec\x24\xa1\x40\x4b\x16\x71\xa1\xb8\x8a\x6d\x06\x12\x02\x29\x51\x8f\xb1\x3a\x74\xca\x0a\xc5\xae",
+ "\xf7\x7c\xb5\x27\x52\x12\xc9\x2f\xa0\xda\xd9\x21\xb6\x5f\x50\x81\x48\x22\xe3\xd6\xd5\x84\xc8\x95\x28\x99\x0f\x02",
+ 215 },
+ { GCRY_MD_SHA3_224,
+ "\xd9\xfa\xa1\x4c\xeb\xe9\xb7\xde\x55\x1b\x6c\x07\x65\x40\x9a\x33\x93\x85\x62\x01\x3b\x5e\x8e\x0e\x1e\x0a\x64\x18\xdf\x73\x99\xd0\xa6\xa7\x71\xfb\x81\xc3\xca\x9b\xd3\xbb\x8e\x29\x51\xb0\xbc\x79\x25\x25\xa2\x94\xeb\xd1\x08\x36\x88\x80\x6f\xe5\xe7\xf1\xe1\x7f\xd4\xe3\xa4\x1d\x00\xc8\x9e\x8f\xcf\x4a\x36\x3c\xae\xdb\x1a\xcb\x55\x8e\x3d\x56\x2f\x13\x02\xb3\xd8\x3b\xb8\x86\xed\x27\xb7\x60\x33\x79\x81\x31\xda\xb0\x5b\x42\x17\x38\x1e\xaa\xa7\xba\x15\xec\x82\x0b\xb5\xc1\x3b\x51\x6d\xd6\x40\xea\xec\x5a\x27\xd0\x5f\xdf\xca\x0f\x35\xb3\xa5\x31\x21\x46\x80\x6b\x4c\x02\x75\xbc\xd0\xaa\xa3\xb2\x01\x7f\x34\x69\x75\xdb\x56\x6f\x9b\x4d\x13\x7f\x4e\xe1\x06\x44\xc2\xa2\xda\x66\xde\xec\xa5\x34\x2e\x23\x64\x95\xc3\xc6\x28\x05\x28\xbf\xd3\x2e\x90\xaf\x4c\xd9\xbb\x90\x8f\x34\x01\x2b\x52\xb4\xbc\x56\xd4\x8c\xc8\xa6\xb5\x9b\xab\x01\x49\x88\xea\xbd\x12\xe1\xa0\xa1\xc2\xe1\x70\xe7",
+ "\x76\xca\x9e\x68\x5d\xfa\xdc\x67\x57\x6d\x44\xe8\xc1\xa8\x2e\x8c\xf7\xe9\x2f\xb0\xa8\x1f\xe4\x9e\x21\x10\x8e\x09",
+ 216 },
+ { GCRY_MD_SHA3_224,
+ "\x2d\x84\x27\x43\x3d\x0c\x61\xf2\xd9\x6c\xfe\x80\xcf\x1e\x93\x22\x65\xa1\x91\x36\x5c\x3b\x61\xaa\xa3\xd6\xdc\xc0\x39\xf6\xba\x2a\xd5\x2a\x6a\x8c\xc3\x0f\xc1\x0f\x70\x5e\x6b\x77\x05\x10\x59\x77\xfa\x49\x6c\x1c\x70\x8a\x27\x7a\x12\x43\x04\xf1\xfc\x40\x91\x1e\x74\x41\xd1\xb5\xe7\x7b\x95\x1a\xad\x7b\x01\xfd\x5d\xb1\xb3\x77\xd1\x65\xb0\x5b\xbf\x89\x80\x42\xe3\x96\x60\xca\xf8\xb2\x79\xfe\x52\x29\xd1\xa8\xdb\x86\xc0\x99\x9e\xd6\x5e\x53\xd0\x1c\xcb\xc4\xb4\x31\x73\xcc\xf9\x92\xb3\xa1\x45\x86\xf6\xba\x42\xf5\xfe\x30\xaf\xa8\xae\x40\xc5\xdf\x29\x96\x6f\x93\x46\xda\x5f\x8b\x35\xf1\x6a\x1d\xe3\xab\x6d\xe0\xf4\x77\xd8\xd8\x66\x09\x18\x06\x0e\x88\xb9\xb9\xe9\xca\x6a\x42\x07\x03\x3b\x87\xa8\x12\xdb\xf5\x54\x4d\x39\xe4\x88\x20\x10\xf8\x2b\x6c\xe0\x05\xf8\xe8\xff\x6f\xe3\xc3\x80\x6b\xc2\xb7\x3c\x2b\x83\xaf\xb7\x04\x34\x56\x29\x30\x4f\x9f\x86\x35\x87\x12\xe9\xfa\xe3\xca\x3e",
+ "\xab\xd3\x13\xbc\x70\xb7\xfa\xb0\xeb\xc1\x67\xd7\x39\xb5\x4c\x97\x38\x9e\x75\x2e\xe1\xa3\x13\xb1\x26\x73\xf5\x1c",
+ 217 },
+ { GCRY_MD_SHA3_224,
+ "\x5e\x19\xd9\x78\x87\xfc\xaa\xc0\x38\x7e\x22\xc6\xf8\x03\xc3\x4a\x3d\xac\xd2\x60\x41\x72\x43\x3f\x7a\x8a\x7a\x52\x6c\xa4\xa2\xa1\x27\x1e\xcf\xc5\xd5\xd7\xbe\x5a\xc0\xd8\x5d\x92\x10\x95\x35\x0d\xfc\x65\x99\x7d\x44\x3c\x21\xc8\x09\x4e\x0a\x3f\xef\xd2\x96\x1b\xcb\x94\xae\xd0\x32\x91\xae\x31\x0c\xcd\xa7\x5d\x8a\xce\x4b\xc7\xd8\x9e\x7d\x3e\x5d\x16\x50\xbd\xa5\xd6\x68\xb8\xb5\x0b\xfc\x8e\x60\x8e\x18\x4f\x4d\x3a\x9a\x2b\xad\xc4\xff\x5f\x07\xe0\xc0\xbc\x8a\x9f\x2e\x0b\x2a\x26\xfd\x6d\x8c\x55\x00\x08\xfa\xaa\xb7\x5f\xd7\x1a\xf2\xa4\x24\xbe\xc9\xa7\xcd\x9d\x83\xfa\xd4\xc8\xe9\x31\x91\x15\x65\x6a\x87\x17\xd3\xb5\x23\xa6\x8f\xf8\x00\x42\x58\xb9\x99\x0e\xd3\x62\x30\x84\x61\x80\x4b\xa3\xe3\xa7\xe9\x2d\x8f\x2f\xfa\xe5\xc2\xfb\xa5\x5b\xa5\xa3\xc2\x7c\x0a\x2f\x71\xbd\x71\x1d\x2f\xe1\x79\x9c\x2a\xdb\x31\xb2\x00\x03\x54\x81\xe9\xee\x5c\x4a\xdf\x2a\xb9\xc0\xfa\x50\xb2\x39\x75\xcf",
+ "\xf7\x9f\x63\x56\x32\x8c\x58\x0b\x81\x1f\xea\x81\xc5\xed\x90\xa3\x03\xca\xf3\x4a\x09\xbe\xb1\x43\xbe\x45\x0d\x42",
+ 218 },
+ { GCRY_MD_SHA3_224,
+ "\xc8\xe9\x76\xab\x46\x38\x90\x93\x87\xce\x3b\x8d\x4e\x51\x0c\x32\x30\xe5\x69\x0e\x02\xc4\x50\x93\xb1\xd2\x97\x91\x0a\xbc\x48\x1e\x56\xee\xa0\xf2\x96\xf9\x83\x79\xdf\xc9\x08\x0a\xf6\x9e\x73\xb2\x39\x9d\x1c\x14\x3b\xee\x80\xae\x13\x28\x16\x2c\xe1\xba\x7f\x6a\x83\x74\x67\x9b\x20\xaa\xcd\x38\x0e\xb4\xe6\x13\x82\xc9\x99\x98\x70\x4d\x62\x70\x1a\xfa\x91\x4f\x9a\x27\x05\xcd\xb0\x65\x88\x5f\x50\xd0\x86\xc3\xeb\x57\x53\x70\x0c\x38\x71\x18\xbb\x14\x2f\x3e\x6d\xa1\xe9\x88\xdf\xb3\x1a\xc7\x5d\x73\x68\x93\x1e\x45\xd1\x39\x1a\x27\x4b\x22\xf8\x3c\xeb\x07\x2f\x9b\xca\xbc\x0b\x21\x66\x85\xbf\xd7\x89\xf5\x02\x39\x71\x02\x4b\x18\x78\xa2\x05\x44\x25\x22\xf9\xea\x7d\x87\x97\xa4\x10\x2a\x3d\xf4\x17\x03\x76\x82\x51\xfd\x5e\x01\x7c\x85\xd1\x20\x0a\x46\x41\x18\xaa\x35\x65\x4e\x7c\xa3\x9f\x3c\x37\x5b\x8e\xf8\xcb\xe7\x53\x4d\xbc\x64\xbc\x20\xbe\xfb\x41\x7c\xf6\x0e\xc9\x2f\x63\xd9\xee\x73\x97",
+ "\x29\x9d\x62\xf8\xdf\x5e\xad\xe6\x87\x18\x83\xb0\x33\xb8\x30\xa9\x95\x2a\x74\xb1\x2f\x3d\x55\xaf\x79\x8c\x69\x97",
+ 219 },
+ { GCRY_MD_SHA3_224,
+ "\x71\x45\xfa\x12\x4b\x74\x29\xa1\xfc\x22\x31\x23\x7a\x94\x9b\xa7\x20\x1b\xcc\x18\x22\xd3\x27\x2d\xe0\x05\xb6\x82\x39\x81\x96\xc2\x5f\x7e\x5c\xc2\xf2\x89\xfb\xf4\x44\x15\xf6\x99\xcb\x7f\xe6\x75\x77\x91\xb1\x44\x34\x10\x23\x4a\xe0\x61\xed\xf6\x23\x35\x9e\x2b\x4e\x32\xc1\x9b\xf8\x84\x50\x43\x2d\xd0\x1c\xaa\x5e\xb1\x6a\x1d\xc3\x78\xf3\x91\xca\x5e\x3c\x4e\x5f\x35\x67\x28\xbd\xdd\x49\x75\xdb\x7c\x89\x0d\xa8\xbb\xc8\x4c\xc7\x3f\xf2\x44\x39\x4d\x0d\x48\x95\x49\x78\x76\x5e\x4a\x00\xb5\x93\xf7\x0f\x2c\xa0\x82\x67\x3a\x26\x1e\xd8\x8d\xbc\xef\x11\x27\x72\x8d\x8c\xd8\x9b\xc2\xc5\x97\xe9\x10\x2c\xed\x60\x10\xf6\x5f\xa7\x5a\x14\xeb\xe4\x67\xfa\x57\xce\x3b\xd4\x94\x8b\x68\x67\xd7\x4a\x9d\xf5\xc0\xec\x6f\x53\x0c\xbf\x2e\xe6\x1c\xe6\xf0\x6b\xc8\xf2\x86\x4d\xff\x55\x83\x77\x6b\x31\xdf\x8c\x7f\xfc\xb6\x14\x28\xa5\x6b\xf7\xbd\x37\x18\x8b\x4a\x51\x23\xbb\xf3\x38\x39\x3a\xf4\x6e\xda\x85\xe6",
+ "\x82\xba\x2b\x8d\x65\xe1\x4f\xda\xc5\x1f\x60\x9f\x88\x88\x81\xdb\x80\x70\xa0\xb7\x0d\x78\x92\xc0\x09\xa1\xad\x28",
+ 220 },
+ { GCRY_MD_SHA3_224,
+ "\x7f\xdf\xad\xcc\x9d\x29\xba\xd2\x3a\xe0\x38\xc6\xc6\x5c\xda\x1a\xef\x75\x72\x21\xb8\x87\x2e\xd3\xd7\x5f\xf8\xdf\x7d\xa0\x62\x7d\x26\x6e\x22\x4e\x81\x2c\x39\xf7\x98\x3e\x45\x58\xbf\xd0\xa1\xf2\xbe\xf3\xfe\xb5\x6b\xa0\x91\x20\xef\x76\x29\x17\xb9\xc0\x93\x86\x79\x48\x54\x7a\xee\x98\x60\x0d\x10\xd8\x7b\x20\x10\x68\x78\xa8\xd2\x2c\x64\x37\x8b\xf6\x34\xf7\xf7\x59\x00\xc0\x39\x86\xb0\x77\xb0\xbf\x8b\x74\x0a\x82\x44\x7b\x61\xb9\x9f\xee\x53\x76\xc5\xeb\x66\x80\xec\x9e\x30\x88\xf0\xbd\xd0\xc5\x68\x83\x41\x3d\x60\xc1\x35\x7d\x3c\x81\x19\x50\xe5\x89\x0e\x76\x00\x10\x3c\x91\x63\x41\xb8\x0c\x74\x3c\x6a\x85\x2b\x7b\x4f\xb6\x0c\x3b\xa2\x1f\x3b\xc1\x5b\x83\x82\x43\x7a\x68\x45\x47\x79\xcf\x3c\xd7\xf9\xf9\x0c\xcc\x8e\xf2\x8d\x0b\x70\x65\x35\xb1\xe4\x10\x8e\xb5\x62\x7b\xb4\x5d\x71\x9c\xb0\x46\x83\x9a\xee\x31\x1c\xa1\xab\xdc\x83\x19\xe0\x50\xd6\x79\x72\xcb\x35\xa6\xb1\x60\x1b\x25\xdb\xf4\x87",
+ "\xf8\xe5\x21\x8d\xb0\x87\xd3\x8b\x1c\x77\x32\x47\xfc\x22\x70\x4c\x1f\xbd\xb2\x0b\x15\x00\xe2\x6a\xfa\x0b\x75\x72",
+ 221 },
+ { GCRY_MD_SHA3_224,
+ "\x98\x86\x38\x21\x9f\xd3\x09\x54\x21\xf8\x26\xf5\x6e\x4f\x09\xe3\x56\x29\x6b\x62\x8c\x3c\xe6\x93\x0c\x9f\x2e\x75\x8f\xd1\xa8\x0c\x82\x73\xf2\xf6\x1e\x4d\xaa\xe6\x5c\x4f\x11\x0d\x3e\x7c\xa0\x96\x5a\xc7\xd2\x4e\x34\xc0\xdc\x4b\xa2\xd6\xff\x0b\xf5\xbb\xe9\x3b\x35\x85\xf3\x54\xd7\x54\x3c\xb5\x42\xa1\xaa\x54\x67\x4d\x37\x50\x77\xf2\xd3\x60\xa8\xf4\xd4\x2f\x3d\xb1\x31\xc3\xb7\xab\x73\x06\x26\x7b\xa1\x07\x65\x98\x64\xa9\x0c\x8c\x90\x94\x60\xa7\x36\x21\xd1\xf5\xd9\xd3\xfd\x95\xbe\xb1\x9b\x23\xdb\x1c\xb6\xc0\xd0\xfb\xa9\x1d\x36\x89\x15\x29\xb8\xbd\x82\x63\xca\xa1\xba\xb5\x6a\x4a\xff\xae\xd4\x49\x62\xdf\x09\x6d\x8d\x5b\x1e\xb8\x45\xef\x31\x18\x8b\x3e\x10\xf1\xaf\x81\x1a\x13\xf1\x56\xbe\xb7\xa2\x88\xaa\xe5\x93\xeb\xd1\x47\x1b\x62\x4a\xa1\xa7\xc6\xad\xf0\x1e\x22\x00\xb3\xd7\x2d\x88\xa3\xae\xd3\x10\x0c\x88\x23\x1e\x41\xef\xc3\x76\x90\x6f\x0b\x58\x0d\xc8\x95\xf0\x80\xfd\xa5\x74\x1d\xb1\xcb",
+ "\xfa\x60\x2f\x09\xb2\x8f\x86\x79\x77\x1e\x9c\x39\x66\x03\x2b\x80\xfa\x2f\x0f\x33\xe8\x4f\x3e\xd6\x9b\xe7\xae\x9c",
+ 222 },
+ { GCRY_MD_SHA3_224,
+ "\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",
+ "\xc8\xd7\x56\x88\x89\xdd\x6f\xcb\xc3\xb8\x87\x4e\xd7\x90\x51\x87\x5d\x3c\xe2\x91\x02\xdf\x0c\x5d\xac\x8a\xeb\x8a",
+ 223 },
+ { GCRY_MD_SHA3_224,
+ "\x47\xb8\x21\x6a\xa0\xfb\xb5\xd6\x79\x66\xf2\xe8\x2c\x17\xc0\x7a\xa2\xd6\x32\x7e\x96\xfc\xd8\x3e\x3d\xe7\x33\x36\x89\xf3\xee\x79\x99\x4a\x1b\xf4\x50\x82\xc4\xd7\x25\xed\x8d\x41\x20\x5c\xb5\xbc\xdf\x5c\x34\x1f\x77\xfa\xcb\x1d\xa4\x6a\x5b\x9b\x2c\xbc\x49\xea\xdf\x78\x6b\xcd\x88\x1f\x37\x1a\x95\xfa\x17\xdf\x73\xf6\x06\x51\x9a\xea\x0f\xf7\x9d\x5a\x11\x42\x7b\x98\xee\x7f\x13\xa5\xc0\x06\x37\xe2\x85\x41\x34\x69\x10\x59\x83\x91\x21\xfe\xa9\xab\xe2\xcd\x1b\xcb\xbb\xf2\x7c\x74\xca\xf3\x67\x8e\x05\xbf\xb1\xc9\x49\x89\x7e\xa0\x1f\x56\xff\xa4\xda\xfb\xe8\x64\x46\x11\x68\x5c\x61\x7a\x32\x06\xc7\xa7\x03\x6e\x4a\xc8\x16\x79\x9f\x69\x3d\xaf\xe7\xf1\x9f\x30\x3c\xe4\xeb\xa0\x9d\x21\xe0\x36\x10\x20\x1b\xfc\x66\x5b\x72\x40\x0a\x54\x7a\x1e\x00\xfa\x9b\x7a\xd8\xd8\x4f\x84\xb3\x4a\xef\x11\x85\x15\xe7\x4d\xef\x11\xb9\x18\x8b\xd1\xe1\xf9\x7d\x9a\x12\xc3\x01\x32\xec\x28\x06\x33\x9b\xda\xda\xcd\xa2\xfd\x8b\x78",
+ "\xd8\x3b\x06\xd5\x09\xd3\x32\x16\x40\x87\xc0\xc3\xfa\x50\xb2\x26\x4c\xb2\x7f\x66\xd7\x46\xb0\x47\x01\x66\xcb\xc2",
+ 224 },
+ { GCRY_MD_SHA3_224,
+ "\x8c\xff\x1f\x67\xfe\x53\xc0\x98\x89\x6d\x91\x36\x38\x9b\xd8\x88\x18\x16\xcc\xab\x34\x86\x2b\xb6\x7a\x65\x6e\x3d\x98\x89\x6f\x3c\xe6\xff\xd4\xda\x73\x97\x58\x09\xfc\xdf\x96\x66\x76\x0d\x6e\x56\x1c\x55\x23\x8b\x20\x5d\x80\x49\xc1\xce\xde\xef\x37\x4d\x17\x35\xda\xa5\x33\x14\x7b\xfa\x96\x0b\x2c\xce\x4a\x4f\x25\x41\x76\xbb\x4d\x1b\xd1\xe8\x96\x54\x43\x2b\x8d\xbe\x1a\x13\x5c\x42\x11\x5b\x39\x4b\x02\x48\x56\xa2\xa8\x3d\xc8\x5d\x67\x82\xbe\x4b\x44\x42\x39\x56\x7c\xce\xc4\xb1\x84\xd4\x54\x8e\xae\x3f\xf6\xa1\x92\xf3\x43\x29\x2b\xa2\xe3\x2a\x0f\x26\x7f\x31\xcc\x26\x71\x9e\xb8\x52\x45\xd4\x15\xfb\x89\x7a\xc2\xda\x43\x3e\xe9\x1a\x99\x42\x4c\x9d\x7f\x17\x66\xa4\x41\x71\xd1\x65\x10\x01\xc3\x8f\xc7\x92\x94\xac\xcc\x68\xce\xb5\x66\x5d\x36\x21\x84\x54\xd3\xba\x16\x9a\xe0\x58\xa8\x31\x33\x8c\x17\x74\x36\x03\xf8\x1e\xe1\x73\xbf\xc0\x92\x74\x64\xf9\xbd\x72\x8d\xee\x94\xc6\xae\xab\x7a\xae\x6e\xe3\xa6\x27\xe8",
+ "\x38\x61\x47\xb0\xcf\x23\x65\x34\x6e\x98\x46\xd3\xf3\xa7\xdc\xee\xb6\xe3\x66\x5b\xa7\xd1\x59\x3c\x08\xb2\xb5\x82",
+ 225 },
+ { GCRY_MD_SHA3_224,
+ "\xea\xcd\x07\x97\x1c\xff\x9b\x99\x39\x90\x3f\x8c\x1d\x8c\xbb\x5d\x4d\xb1\xb5\x48\xa8\x5d\x04\xe0\x37\x51\x4a\x58\x36\x04\xe7\x87\xf3\x29\x92\xbf\x21\x11\xb9\x7a\xc5\xe8\xa9\x38\x23\x35\x52\x73\x13\x21\x52\x2a\xb5\xe8\x58\x35\x61\x26\x0b\x7d\x13\xeb\xee\xf7\x85\xb2\x3a\x41\xfd\x85\x76\xa6\xda\x76\x4a\x8e\xd6\xd8\x22\xd4\x95\x7a\x54\x5d\x52\x44\x75\x6c\x18\xaa\x80\xe1\xaa\xd4\xd1\xf9\xc2\x0d\x25\x9d\xee\x17\x11\xe2\xcc\x8f\xd0\x13\x16\x9f\xb7\xcc\x4c\xe3\x8b\x36\x2f\x8e\x09\x36\xae\x91\x98\xb7\xe8\x38\xdc\xea\x4f\x7a\x5b\x94\x29\xbb\x3f\x6b\xbc\xf2\xdc\x92\x56\x5e\x36\x76\xc1\xc5\xe6\xeb\x3d\xd2\xa0\xf8\x6a\xa2\x3e\xdd\x3d\x08\x91\xf1\x97\x44\x76\x92\x79\x4b\x3d\xfa\x26\x96\x11\xad\x97\xf7\x2b\x79\x56\x02\xb4\xfd\xb1\x98\xf3\xfd\x3e\xb4\x1b\x41\x50\x64\x25\x6e\x34\x5e\x8d\x8c\x51\xc5\x55\xdc\x8a\x21\x90\x4a\x9b\x0f\x1a\xd0\xef\xfa\xb7\x78\x6a\xac\x2d\xa3\xb1\x96\x50\x7e\x9f\x33\xca\x35\x64\x27",
+ "\xa6\x9c\x0c\x18\xa7\x12\x40\x8d\x8f\xa2\x38\x9a\xca\xbc\x3b\xf6\xf6\x41\x2f\x69\x78\x3e\x9f\x37\x96\x0d\x0b\x56",
+ 226 },
+ { GCRY_MD_SHA3_224,
+ "\x23\xac\x4e\x9a\x42\xc6\xef\x45\xc3\x33\x6c\xe6\xdf\xc2\xff\x7d\xe8\x88\x4c\xd2\x3d\xc9\x12\xfe\xf0\xf7\x75\x6c\x09\xd3\x35\xc1\x89\xf3\xad\x3a\x23\x69\x7a\xbd\xa8\x51\xa8\x18\x81\xa0\xc8\xcc\xaf\xc9\x80\xab\x2c\x70\x25\x64\xc2\xbe\x15\xfe\x4c\x4b\x9f\x10\xdf\xb2\x24\x8d\x0d\x0c\xb2\xe2\x88\x7f\xd4\x59\x8a\x1d\x4a\xcd\xa8\x97\x94\x4a\x2f\xfc\x58\x0f\xf9\x27\x19\xc9\x5c\xf2\xaa\x42\xdc\x58\x46\x74\xcb\x5a\x9b\xc5\x76\x5b\x9d\x6d\xdf\x57\x89\x79\x1d\x15\xf8\xdd\x92\x5a\xa1\x2b\xff\xaf\xbc\xe6\x08\x27\xb4\x90\xbb\x7d\xf3\xdd\xa6\xf2\xa1\x43\xc8\xbf\x96\xab\xc9\x03\xd8\x3d\x59\xa7\x91\xe2\xd6\x28\x14\xa8\x9b\x80\x80\xa2\x80\x60\x56\x8c\xf2\x4a\x80\xae\x61\x17\x9f\xe8\x4e\x0f\xfa\xd0\x03\x88\x17\x8c\xb6\xa6\x17\xd3\x7e\xfd\x54\xcc\x01\x97\x0a\x4a\x41\xd1\xa8\xd3\xdd\xce\x46\xed\xbb\xa4\xab\x7c\x90\xad\x56\x53\x98\xd3\x76\xf4\x31\x18\x9c\xe8\xc1\xc3\x3e\x13\x2f\xea\xe6\xa8\xcd\x17\xa6\x1c\x63\x00\x12",
+ "\x06\x99\xfd\x35\x41\x6d\x83\x79\x1d\xc8\xe6\x56\xf2\x27\x18\xb0\x9d\xa9\xe3\xdf\x6e\x7f\x37\xa2\x50\xe2\x2d\xcd",
+ 227 },
+ { GCRY_MD_SHA3_224,
+ "\x01\x72\xdf\x73\x22\x82\xc9\xd4\x88\x66\x9c\x35\x8e\x34\x92\x26\x0c\xbe\x91\xc9\x5c\xfb\xc1\xe3\xfe\xa6\xc4\xb0\xec\x12\x9b\x45\xf2\x42\xac\xe0\x9f\x15\x2f\xc6\x23\x4e\x1b\xee\x8a\xab\x8c\xd5\x6e\x8b\x48\x6e\x1d\xcb\xa9\xc0\x54\x07\xc2\xf9\x5d\xa8\xd8\xf1\xc0\xaf\x78\xee\x2e\xd8\x2a\x3a\x79\xec\x0c\xb0\x70\x93\x96\xee\x62\xaa\xdb\x84\xf8\xa4\xee\x8a\x7c\xcc\xa3\xc1\xee\x84\xe3\x02\xa0\x9e\xa8\x02\x20\x4a\xfe\xcf\x04\x09\x7e\x67\xd0\xf8\xe8\xa9\xd2\x65\x11\x26\xc0\xa5\x98\xa3\x70\x81\xe4\x2d\x16\x8b\x0a\xe8\xa7\x19\x51\xc5\x24\x25\x9e\x4e\x20\x54\xe5\x35\xb7\x79\x67\x9b\xda\xde\x56\x6f\xe5\x57\x00\x85\x86\x18\xe6\x26\xb4\xa0\xfa\xf8\x95\xbc\xce\x90\x11\x50\x4a\x49\xe0\x5f\xd5\x61\x27\xea\xe3\xd1\xf8\x91\x7a\xfb\x54\x8e\xca\xda\xbd\xa1\x02\x01\x11\xfe\xc9\x31\x4c\x41\x34\x98\xa3\x60\xb0\x86\x40\x54\x9a\x22\xcb\x23\xc7\x31\xac\xe7\x43\x25\x2a\x82\x27\xa0\xd2\x68\x9d\x4c\x60\x01\x60\x66\x78\xdf\xb9\x21",
+ "\xbf\x6a\x35\x98\xa1\x5e\x28\xb7\x76\x22\x9f\x4d\x12\x4d\x40\x3f\xad\x9d\x0f\xbc\x2b\x76\x68\xc9\x5d\x8b\x50\x46",
+ 228 },
+ { GCRY_MD_SHA3_224,
+ "\x38\x75\xb9\x24\x0c\xf3\xe0\xa8\xb5\x9c\x65\x85\x40\xf2\x6a\x70\x1c\xf1\x88\x49\x6e\x2c\x21\x74\x78\x8b\x12\x6f\xd2\x94\x02\xd6\xa7\x54\x53\xba\x06\x35\x28\x4d\x08\x83\x5f\x40\x05\x1a\x2a\x96\x83\xdc\x92\xaf\xb9\x38\x37\x19\x19\x12\x31\x17\x03\x79\xba\x6f\x4a\xdc\x81\x6f\xec\xbb\x0f\x9c\x44\x6b\x78\x5b\xf5\x20\x79\x68\x41\xe5\x88\x78\xb7\x3c\x58\xd3\xeb\xb0\x97\xce\x47\x61\xfd\xea\xbe\x15\xde\x2f\x31\x9d\xfb\xaf\x17\x42\xcd\xeb\x38\x95\x59\xc7\x88\x13\x1a\x67\x93\xe1\x93\x85\x66\x61\x37\x6c\x81\xce\x95\x68\xda\x19\xaa\x69\x25\xb4\x7f\xfd\x77\xa4\x3c\x7a\x0e\x75\x8c\x37\xd6\x92\x54\x90\x9f\xf0\xfb\xd4\x15\xef\x8e\xb9\x37\xbc\xd4\x9f\x91\x46\x8b\x49\x97\x4c\x07\xdc\x81\x9a\xbd\x67\x39\x5d\xb0\xe0\x58\x74\xff\x83\xdd\xda\xb8\x95\x34\x4a\xbd\x0e\x71\x11\xb2\xdf\x9e\x58\xd7\x6d\x85\xad\x98\x10\x6b\x36\x29\x58\x26\xbe\x04\xd4\x35\x61\x55\x95\x60\x5e\x4b\x4b\xb8\x24\xb3\x3c\x4a\xfe\xb5\xe7\xbb\x0d\x19\xf9\x09",
+ "\x56\xf8\xe9\xf6\x9a\x39\x9e\x52\x89\x96\xc4\x63\xd6\x5f\x20\xdb\x41\x40\x65\x33\xc7\xdf\x2b\xa1\xaf\xa2\x49\x4a",
+ 229 },
+ { GCRY_MD_SHA3_224,
+ "\x74\x7c\xc1\xa5\x9f\xef\xba\x94\xa9\xc7\x5b\xa8\x66\xc3\x0d\xc5\xc1\xcb\x0c\x0f\x8e\x93\x61\xd9\x84\x84\x95\x6d\xd5\xd1\xa4\x0f\x61\x84\xaf\xbe\x3d\xac\x9f\x76\x02\x8d\x1c\xae\xcc\xfb\xf6\x91\x99\xc6\xce\x2b\x4c\x09\x2a\x3f\x4d\x2a\x56\xfe\x5a\x33\xa0\x07\x57\xf4\xd7\xde\xe5\xdf\xb0\x52\x43\x11\xa9\x7a\xe0\x66\x8a\x47\x97\x1b\x95\x76\x6e\x2f\x6d\xd4\x8c\x3f\x57\x84\x1f\x91\xf0\x4a\x00\xad\x5e\xa7\x0f\x2d\x47\x9a\x26\x20\xdc\x5c\xd7\x8e\xaa\xb3\xa3\xb0\x11\x71\x9b\x7e\x78\xd1\x9d\xdf\x70\xd9\x42\x37\x98\xaf\x77\x51\x7e\xbc\x55\x39\x2f\xcd\x01\xfc\x60\x0d\x8d\x46\x6b\x9e\x7a\x7a\x85\xbf\x33\xf9\xcc\x54\x19\xe9\xbd\x87\x4d\xdf\xd6\x09\x81\x15\x0d\xda\xf8\xd7\xfe\xba\xa4\x37\x4f\x08\x72\xa5\x62\x8d\x31\x80\x00\x31\x1e\x2f\x56\x55\x36\x5a\xd4\xd4\x07\xc2\x0e\x5c\x04\xdf\x17\xa2\x22\xe7\xde\xec\x79\xc5\xab\x11\x16\xd8\x57\x2f\x91\xcd\x06\xe1\xcc\xc7\xce\xd5\x37\x36\xfc\x86\x7f\xd4\x9e\xce\xbe\x6b\xf8\x08\x2e\x8a",
+ "\x99\x04\xd5\x7d\xed\xb9\x35\x42\x7f\x23\x5a\x00\x09\x61\x22\x35\xf1\x4e\x94\x26\xb2\x18\xe0\x28\xf8\x7b\x3c\x0c",
+ 230 },
+ { GCRY_MD_SHA3_224,
+ "\x57\xaf\x97\x1f\xcc\xae\xc9\x74\x35\xdc\x2e\xc9\xef\x04\x29\xbc\xed\xc6\xb6\x47\x72\x9e\xa1\x68\x85\x8a\x6e\x49\xac\x10\x71\xe7\x06\xf4\xa5\xa6\x45\xca\x14\xe8\xc7\x74\x6d\x65\x51\x16\x20\x68\x2c\x90\x6c\x8b\x86\xec\x90\x1f\x3d\xde\xd4\x16\x7b\x3f\x00\xb0\x6c\xbf\xac\x6a\xee\x37\x28\x05\x1b\x3e\x5f\xf1\x0b\x4f\x9e\xd8\xbd\x0b\x8d\xa9\x43\x03\xc8\x33\x75\x5b\x3c\xa3\xae\xdd\xf0\xb5\x4b\xc8\xd6\x63\x21\x38\xb5\xd2\x5b\xab\x03\xd1\x7b\x34\x58\xa9\xd7\x82\x10\x80\x06\xf5\xbb\x7d\xe7\x5b\x5c\x0b\xa8\x54\xb4\x23\xd8\xbb\x80\x1e\x70\x1e\x99\xdc\x4f\xea\xad\x59\xbc\x1c\x71\x12\x45\x3b\x04\xd3\x3e\xa3\x63\x56\x39\xfb\x80\x2c\x73\xc2\xb7\x1d\x58\xa5\x6b\xbd\x67\x1b\x18\xfe\x34\xed\x2e\x3d\xca\x38\x82\x7d\x63\xfd\xb1\xd4\xfb\x32\x85\x40\x50\x04\xb2\xb3\xe2\x60\x81\xa8\xff\x08\xcd\x6d\x2b\x08\xf8\xe7\xb7\xe9\x0a\x2a\xb1\xed\x7a\x41\xb1\xd0\x12\x85\x22\xc2\xf8\xbf\xf5\x6a\x7f\xe6\x79\x69\x42\x2c\xe8\x39\xa9\xd4\x60\x8f\x03",
+ "\xff\x70\x13\x67\x9a\xb2\xbe\x65\xae\xdd\x09\x73\x9f\x56\xf8\xdd\x00\x72\x73\x8b\x86\xe7\x1a\x24\x70\x47\x6c\x8c",
+ 231 },
+ { GCRY_MD_SHA3_224,
+ "\x04\xe1\x6d\xed\xc1\x22\x79\x02\xba\xaf\x33\x2d\x3d\x08\x92\x36\x01\xbd\xd6\x4f\x57\x3f\xaa\x1b\xb7\x20\x19\x18\xcf\xe1\x6b\x1e\x10\x15\x1d\xae\x87\x5d\xa0\xc0\xd6\x3c\x59\xc3\xdd\x05\x0c\x4c\x6a\x87\x40\x11\xb0\x18\x42\x1a\xfc\x46\x23\xab\x03\x81\x83\x1b\x2d\xa2\xa8\xba\x42\xc9\x6e\x4f\x70\x86\x4a\xc4\x4e\x10\x6f\x94\x31\x10\x51\xe7\x4c\x77\xc1\x29\x1b\xf5\xdb\x95\x39\xe6\x95\x67\xbf\x6a\x11\xcf\x69\x32\xbb\xba\xd3\x3f\x89\x46\xbf\x58\x14\xc0\x66\xd8\x51\x63\x3d\x1a\x51\x35\x10\x03\x9b\x34\x99\x39\xbf\xd4\x2b\x85\x8c\x21\x82\x7c\x8f\xf0\x5f\x1d\x09\xb1\xb0\x76\x5d\xc7\x8a\x13\x5b\x5c\xa4\xdf\xba\x08\x01\xbc\xad\xdf\xa1\x75\x62\x3c\x8b\x64\x7e\xac\xfb\x44\x44\xb8\x5a\x44\xf7\x38\x90\x60\x7d\x06\xd5\x07\xa4\xf8\x39\x36\x58\x78\x86\x69\xf6\xef\x4d\xeb\x58\xd0\x8c\x50\xca\x07\x56\xd5\xe2\xf4\x9d\x1a\x7a\xd7\x3e\x0f\x0b\x3d\x3b\x5f\x09\x0a\xcf\x62\x2b\x18\x78\xc5\x91\x33\xe4\xa8\x48\xe0\x51\x53\x59\x2e\xa8\x1c\x6f\xbf",
+ "\x9d\xfb\x6a\x85\x4a\x33\x91\x4e\xae\x15\x96\xdc\xd2\xbe\x36\x3a\x96\xe7\xe0\x88\xbe\x52\x0f\x60\xe5\xa6\x5c\x7f",
+ 232 },
+ { GCRY_MD_SHA3_224,
+ "\x7c\x81\x5c\x38\x4e\xee\x0f\x28\x8e\xce\x27\xcc\xed\x52\xa0\x16\x03\x12\x7b\x07\x9c\x00\x73\x78\xbc\x5d\x1e\x6c\x5e\x9e\x6d\x1c\x73\x57\x23\xac\xbb\xd5\x80\x1a\xc4\x98\x54\xb2\xb5\x69\xd4\x47\x2d\x33\xf4\x0b\xbb\x88\x82\x95\x62\x45\xc3\x66\xdc\x35\x82\xd7\x16\x96\xa9\x7a\x4e\x19\x55\x7e\x41\xe5\x4d\xee\x48\x2a\x14\x22\x90\x05\xf9\x3a\xfd\x2c\x4a\x7d\x86\x14\xd1\x0a\x97\xa9\xdf\xa0\x7f\x7c\xd9\x46\xfa\x45\x26\x30\x63\xdd\xd2\x9d\xb8\xf9\xe3\x4d\xb6\x0d\xaa\x32\x68\x4f\x00\x72\xea\x2a\x94\x26\xec\xeb\xfa\x52\x39\xfb\x67\xf2\x9c\x18\xcb\xaa\x2a\xf6\xed\x4b\xf4\x28\x39\x36\x82\x3a\xc1\x79\x01\x64\xfe\xc5\x45\x7a\x9c\xba\x7c\x76\x7c\xa5\x93\x92\xd9\x4c\xab\x74\x48\xf5\x0e\xb3\x4e\x9a\x93\xa8\x00\x27\x47\x1c\xe5\x97\x36\xf0\x99\xc8\x86\xde\xa1\xab\x4c\xba\x4d\x89\xf5\xfc\x7a\xe2\xf2\x1c\xcd\x27\xf6\x11\xec\xa4\x62\x6b\x2d\x08\xdc\x22\x38\x2e\x92\xc1\xef\xb2\xf6\xaf\xdc\x8f\xdc\x3d\x21\x72\x60\x4f\x50\x35\xc4\x6b\x81\x97\xd3",
+ "\xc2\x7e\x80\xc3\x73\xb2\x16\x70\x3d\x3d\x9e\x67\x22\x3c\xfc\x54\x97\xc3\xe7\x44\x55\xd4\x9b\x04\x9a\xe3\xf5\xf4",
+ 233 },
+ { GCRY_MD_SHA3_224,
+ "\xe2\x9d\x50\x51\x58\xdb\xdd\x93\x7d\x9e\x3d\x21\x45\x65\x8e\xe6\xf5\x99\x2a\x2f\xc7\x90\xf4\xf6\x08\xd9\xcd\xb4\x4a\x09\x1d\x5b\x94\xb8\x8e\x81\xfa\xc4\xfd\xf5\xc4\x94\x42\xf1\x3b\x91\x1c\x55\x88\x64\x69\x62\x95\x51\x18\x9e\xaf\xf6\x24\x88\xf1\xa4\x79\xb7\xdb\x11\xa1\x56\x0e\x19\x8d\xdc\xcc\xcf\x50\x15\x90\x93\x42\x5f\xf7\xf1\xcb\x8d\x1d\x12\x46\xd0\x97\x87\x64\x08\x7d\x6b\xac\x25\x70\x26\xb0\x90\xef\xae\x8c\xec\x5f\x22\xb6\xf2\x1c\x59\xac\xe1\xac\x73\x86\xf5\xb8\x83\x7c\xa6\xa1\x2b\x6f\xbf\x55\x34\xdd\x05\x60\xef\x05\xca\x78\x10\x4d\x3b\x94\x3d\xdb\x22\x0f\xea\xec\x89\xaa\x5e\x69\x2a\x00\xf8\x22\xa2\xab\x9a\x2f\xe6\x03\x50\xd7\x5e\x7b\xe1\x6f\xf2\x52\x6d\xc6\x43\x87\x25\x02\xd0\x1f\x42\xf1\x88\xab\xed\x0a\x6e\x9a\x6f\x5f\xd0\xd1\xce\x7d\x57\x55\xc9\xff\xa6\x6b\x0a\xf0\xb2\x0b\xd8\x06\xf0\x8e\x06\x15\x66\x90\xd8\x1a\xc8\x11\x77\x8c\xa3\xda\xc2\xc2\x49\xb9\x60\x02\x01\x7f\xce\x93\xe5\x07\xe3\xb9\x53\xac\xf9\x99\x64\xb8\x47",
+ "\x3a\x18\x96\x30\xf5\x3c\x56\x7b\x1c\x18\x25\x79\x4d\x50\xde\xf9\x01\xa0\x0e\x7f\x37\x28\xec\xf2\xbb\xe0\x0d\x90",
+ 234 },
+ { GCRY_MD_SHA3_224,
+ "\xd8\x55\x88\x69\x6f\x57\x6e\x65\xec\xa0\x15\x5f\x39\x5f\x0c\xfa\xcd\x83\xf3\x6a\x99\x11\x1e\xd5\x76\x8d\xf2\xd1\x16\xd2\x12\x1e\x32\x35\x7b\xa4\xf5\x4e\xde\x92\x7f\x18\x9f\x29\x7d\x3a\x97\xfa\xd4\xe9\xa0\xf5\xb4\x1d\x8d\x89\xdd\x7f\xe2\x01\x56\x79\x9c\x2b\x7b\x6b\xf9\xc9\x57\xba\x0d\x67\x63\xf5\xc3\xbc\x51\x29\x74\x7b\xbb\x53\x65\x2b\x49\x29\x0c\xff\x1c\x87\xe2\xcd\xf2\xc4\xb9\x5d\x8a\xae\xe0\x9b\xc8\xfb\xfa\x68\x83\xe6\x2d\x23\x78\x85\x81\x04\x91\xbf\xc1\x01\xf1\xd8\xc6\x36\xe3\xd0\xed\xe8\x38\xad\x05\xc2\x07\xa3\xdf\x4f\xad\x76\x45\x29\x79\xeb\x99\xf2\x9a\xfa\xec\xed\xd1\xc6\x3b\x8d\x36\xcf\x37\x84\x54\xa1\xbb\x67\xa7\x41\xc7\x7a\xc6\xb6\xb3\xf9\x5f\x4f\x02\xb6\x4d\xab\xc1\x54\x38\x61\x3e\xa4\x97\x50\xdf\x42\xee\x90\x10\x1f\x11\x5a\xa9\xab\xb9\xff\x64\x32\x4d\xde\x9d\xab\xbb\x01\x05\x4e\x1b\xd6\xb4\xbc\xdc\x79\x30\xa4\x4c\x23\x00\xd8\x7c\xa7\x8c\x06\x92\x4d\x03\x23\xad\x78\x87\xe4\x6c\x90\xe8\xc4\xd1\x00\xac\xd9\xee\xd2\x1e",
+ "\x25\x85\xbd\x8d\x91\x58\xd6\x95\x2b\xee\x95\xb0\x04\xf5\xfe\xd7\x0f\xaf\x06\x1b\x68\xab\x2d\x6a\x40\x46\x9b\xe7",
+ 235 },
+ { GCRY_MD_SHA3_224,
+ "\x3a\x12\xf8\x50\x8b\x40\xc3\x2c\x74\x49\x2b\x66\x32\x33\x75\xdc\xfe\x49\x18\x4c\x78\xf7\x31\x79\xf3\x31\x4b\x79\xe6\x33\x76\xb8\xac\x68\x3f\x5a\x51\xf1\x53\x4b\xd7\x29\xb0\x2b\x04\xd0\x02\xf5\x5c\xbd\x8e\x8f\xc9\xb5\xec\x1e\xa6\xbb\xe6\xa0\xd0\xe7\x43\x15\x18\xe6\xba\x45\xd1\x24\x03\x5f\x9d\x3d\xce\x0a\x8b\xb7\xbf\x14\x30\xa9\xf6\x57\xe0\xb4\xea\x9f\x20\xeb\x20\xc7\x86\xa5\x81\x81\xa1\xe2\x0a\x96\xf1\x62\x8f\x87\x28\xa1\x3b\xdf\x7a\x4b\x4b\x32\xfc\x8a\xa7\x05\x4c\xc4\x88\x1a\xe7\xfa\x19\xaf\xa6\x5c\x6c\x3e\xe1\xb3\xad\xe3\x19\x2a\xf4\x20\x54\xa8\xa9\x11\xb8\xec\x18\x26\x86\x5d\x46\xd9\x3f\x1e\x7c\x5e\x2b\x78\x13\xc9\x2a\x50\x6e\x53\x88\x6f\x3d\x47\x01\xbb\x93\xd2\xa6\x81\xad\x10\x9c\x84\x59\x04\xbb\x86\x1a\xf8\xaf\x06\x46\xb6\xe3\x99\xb3\x8b\x61\x40\x51\xd3\x4f\x68\x42\x56\x3a\x0f\x37\xec\x00\xcb\x3d\x86\x5f\xc5\xd7\x46\xc4\x98\x7d\xe2\xa6\x50\x71\x10\x08\x83\xa2\xa9\xc7\xa2\xbf\xe1\xe2\xdd\x60\x3d\x9e\xa2\x4d\xc7\xc5\xfd\x06\xbe",
+ "\x7e\x64\xf3\xc5\x89\x5d\x05\x86\xcc\x5b\x54\x3b\x27\xde\x1b\x66\xa9\x35\x17\x1e\x2e\x7f\x3c\xa4\x8d\xd3\x71\x8e",
+ 236 },
+ { GCRY_MD_SHA3_224,
+ "\x18\x61\xed\xce\x46\xfa\x5a\xd1\x7e\x1f\xf1\xde\xae\x08\x4d\xec\x58\x0f\x97\xd0\xa6\x78\x85\xdf\xe8\x34\xb9\xdf\xac\x1a\xe0\x76\x74\x2c\xe9\xe2\x67\x51\x2c\xa5\x1f\x6d\xf5\xa4\x55\xaf\x0c\x5f\xd6\xab\xf9\x4a\xce\xa1\x03\xa3\x37\x0c\x35\x44\x85\xa7\x84\x6f\xb8\x4f\x3a\xc7\xc2\x90\x4b\x5b\x2f\xbf\x22\x70\x02\xce\x51\x21\x33\xbb\x7e\x1c\x4e\x50\x05\x7b\xfd\x1e\x44\xdb\x33\xc7\xcd\xb9\x69\xa9\x9e\x28\x4b\x18\x4f\x50\xa1\x4b\x06\x8a\x1f\xc5\x00\x9d\x9b\x29\x8d\xbe\x92\x23\x95\x72\xa7\x62\x7a\xac\x02\xab\xe8\xf3\xe3\xb4\x73\x41\x7f\x36\xd4\xd2\x50\x5d\x16\xb7\x57\x7f\x45\x26\xc9\xd9\x4a\x27\x0a\x2d\xfe\x45\x0d\x06\xda\x8f\x6f\xa9\x56\x87\x9a\x0a\x55\xcf\xe9\x9e\x74\x2e\xa5\x55\xea\x47\x7b\xa3\xe9\xb4\x4c\xcd\x50\x8c\x37\x54\x23\x61\x1a\xf9\x2e\x55\x34\x5d\xc2\x15\x77\x9b\x2d\x51\x19\xeb\xa4\x9c\x71\xd4\x9b\x9f\xe3\xf1\x56\x9f\xa2\x4e\x5c\xa3\xe3\x32\xd0\x42\x42\x2a\x8b\x81\x58\xd3\xec\x66\xa8\x00\x12\x97\x6f\x31\xff\xdf\x30\x5f\x0c\x9c\x5e",
+ "\x0f\x83\x77\x08\xe0\x10\x37\x5a\xf8\x7f\x75\x41\x5e\xd6\x99\x88\xfe\x60\xeb\x2f\x26\x69\xad\x05\x1f\xa9\x97\x27",
+ 237 },
+ { GCRY_MD_SHA3_224,
+ "\x08\xd0\xff\xde\x3a\x6e\x4e\xf6\x56\x08\xea\x67\x2e\x48\x30\xc1\x29\x43\xd7\x18\x7c\xcf\xf0\x8f\x49\x41\xcf\xc1\x3e\x54\x5f\x3b\x9c\x7a\xd5\xee\xbb\xe2\xb0\x16\x42\xb4\x86\xca\xf8\x55\xc2\xc7\x3f\x58\xc1\xe4\xe3\x39\x1d\xa8\xe2\xd6\x3d\x96\xe1\x5f\xd8\x49\x53\xae\x5c\x23\x19\x11\xb0\x0a\xd6\x05\x0c\xd7\xaa\xfd\xaa\xc9\xb0\xf6\x63\xae\x6a\xab\x45\x51\x9d\x0f\x53\x91\xa5\x41\x70\x7d\x47\x90\x34\xe7\x3a\x6a\xd8\x05\xae\x35\x98\x09\x6a\xf0\x78\xf1\x39\x33\x01\x49\x3d\x66\x3d\xd7\x1f\x83\x86\x9c\xa2\x7b\xa5\x08\xb7\xe9\x1e\x81\xe1\x28\xc1\x71\x6d\xc3\xac\xfe\x30\x84\xb2\x20\x1e\x04\xcf\x80\x06\x61\x7e\xec\xf1\xb6\x40\x47\x4a\x5d\x45\xcf\xde\x9f\x4d\x3e\xf9\x2d\x6d\x05\x5b\x90\x98\x92\x19\x4d\x8a\x82\x18\xdb\x6d\x82\x03\xa8\x42\x61\xd2\x00\xd7\x14\x73\xd7\x48\x8f\x34\x27\x41\x6b\x68\x96\xc1\x37\xd4\x55\xf2\x31\x07\x1c\xac\xbc\x86\xe0\x41\x5a\xb8\x8a\xec\x84\x1d\x96\xb7\xb8\xaf\x41\xe0\x5b\xb4\x61\xa4\x06\x45\xbf\x17\x66\x01\xf1\xe7\x60\xde\x5f",
+ "\xc7\x9d\xe3\x97\x78\x59\x38\x10\xc0\x35\x83\xd5\x96\x2b\x36\xe0\x4f\x34\x36\x53\x07\x47\x66\xd1\x57\xa1\x59\x93",
+ 238 },
+ { GCRY_MD_SHA3_224,
+ "\xd7\x82\xab\xb7\x2a\x5b\xe3\x39\x27\x57\xbe\x02\xd3\xe4\x5b\xe6\xe2\x09\x9d\x6f\x00\x0d\x04\x2c\x8a\x54\x3f\x50\xed\x6e\xbc\x05\x5a\x7f\x13\x3b\x0d\xd8\xe9\xbc\x34\x85\x36\xed\xca\xae\x2e\x12\xec\x18\xe8\x83\x7d\xf7\xa1\xb3\xc8\x7e\xc4\x6d\x50\xc2\x41\xde\xe8\x20\xfd\x58\x61\x97\x55\x2d\xc2\x0b\xee\xa5\x0f\x44\x5a\x07\xa3\x8f\x17\x68\xa3\x9e\x2b\x2f\xf0\x5d\xdd\xed\xf7\x51\xf1\xde\xf6\x12\xd2\xe4\xd8\x10\xda\xa3\xa0\xcc\x90\x45\x16\xf9\xa4\x3a\xf6\x60\x31\x53\x85\x17\x8a\x52\x9e\x51\xf8\xaa\xe1\x41\x80\x8c\x8b\xc5\xd7\xb6\x0c\xac\x26\xbb\x98\x4a\xc1\x89\x0d\x04\x36\xef\x78\x04\x26\xc5\x47\xe9\x4a\x7b\x08\xf0\x1a\xcb\xfc\x4a\x38\x25\xea\xe0\x4f\x52\x0a\x90\x16\xf2\xfb\x8b\xf5\x16\x5e\xd1\x27\x36\xfc\x71\xe3\x6a\x49\xa7\x36\x14\x73\x9e\xaa\x3e\xc8\x34\x06\x9b\x1b\x40\xf1\x35\x0c\x2b\x3a\xb8\x85\xc0\x2c\x64\x0b\x9f\x76\x86\xed\x5f\x99\x52\x7e\x41\xcf\xcd\x79\x6f\xe4\xc2\x56\xc9\x17\x31\x86\xc2\x26\x16\x9f\xf2\x57\x95\x4e\xbd\xa8\x1c\x0e\x5f\x99",
+ "\x95\xcc\x81\x1c\xc5\x65\x21\xa4\x0e\x3c\xed\x8d\x9a\x23\x0e\x21\x01\xe8\x06\x1f\xb0\x1e\x38\x8b\x99\x64\xbf\x29",
+ 239 },
+ { GCRY_MD_SHA3_224,
+ "\x5f\xce\x81\x09\xa3\x58\x57\x0e\x40\x98\x3e\x11\x84\xe5\x41\x83\x3b\xb9\x09\x1e\x28\x0f\x25\x8c\xfb\x14\x43\x87\xb0\x5d\x19\x0e\x43\x1c\xb1\x9b\xaa\x67\x27\x3b\xa0\xc5\x8a\xbe\x91\x30\x8e\x18\x44\xdc\xd0\xb3\x67\x8b\xaa\x42\xf3\x35\xf2\xfa\x05\x26\x7a\x02\x40\xb3\xc7\x18\xa5\x94\x2b\x3b\x3e\x3b\xfa\x98\xa5\x5c\x25\xa1\x46\x6e\x8d\x7a\x60\x37\x22\xcb\x2b\xbf\x03\xaf\xa5\x4c\xd7\x69\xa9\x9f\x31\x07\x35\xee\x5a\x05\xda\xe2\xc2\x2d\x39\x7b\xd9\x56\x35\xf5\x8c\x48\xa6\x7f\x90\xe1\xb7\x3a\xaf\xcd\x3f\x82\x11\x7f\x01\x66\x65\x78\x38\x69\x10\x05\xb1\x8d\xa6\xf3\x41\xd6\xe9\x0f\xc1\xcd\xb3\x52\xb3\x0f\xae\x45\xd3\x48\x29\x4e\x50\x1b\x63\x25\x2d\xe1\x47\x40\xf2\xb8\x5a\xe5\x29\x9d\xde\xc3\x17\x2d\xe8\xb6\xd0\xba\x21\x9a\x20\xa2\x3b\xb5\xe1\x0f\xf4\x34\xd3\x9d\xb3\xf5\x83\x30\x5e\x9f\x5c\x03\x9d\x98\x56\x9e\x37\x7b\x75\xa7\x0a\xb8\x37\xd1\xdf\x26\x9b\x8a\x4b\x56\x6f\x40\xbb\x91\xb5\x77\x45\x5f\xd3\xc3\x56\xc9\x14\xfa\x06\xb9\xa7\xce\x24\xc7\x31\x7a\x17\x2d",
+ "\x2e\xbe\x13\xf1\x2e\xc4\x3e\x3f\x6b\x05\x06\xd7\xab\x21\x6e\x1c\x31\x13\x94\xf7\xc8\x9d\x69\xa9\x20\xcd\x00\xc0",
+ 240 },
+ { GCRY_MD_SHA3_224,
+ "\x61\x72\xf1\x97\x1a\x6e\x1e\x4e\x61\x70\xaf\xba\xd9\x5d\x5f\xec\x99\xbf\x69\xb2\x4b\x67\x4b\xc1\x7d\xd7\x80\x11\x61\x5e\x50\x2d\xe6\xf5\x6b\x86\xb1\xa7\x1d\x3f\x43\x48\x08\x72\x18\xac\x7b\x7d\x09\x30\x29\x93\xbe\x27\x2e\x4a\x59\x19\x68\xae\xf1\x8a\x12\x62\xd6\x65\x61\x0d\x10\x70\xee\x91\xcc\x8d\xa3\x6e\x1f\x84\x1a\x69\xa7\xa6\x82\xc5\x80\xe8\x36\x94\x1d\x21\xd9\x09\xa3\xaf\xc1\xf0\xb9\x63\xe1\xca\x5a\xb1\x93\xe1\x24\xa1\xa5\x3d\xf1\xc5\x87\x47\x0e\x58\x81\xfb\x54\xda\xe1\xb0\xd8\x40\xf0\xc8\xf9\xd1\xb0\x4c\x64\x5b\xa1\x04\x1c\x7d\x8d\xbf\x22\x03\x0a\x62\x3a\xa1\x56\x38\xb3\xd9\x9a\x2c\x40\x0f\xf7\x6f\x32\x52\x07\x9a\xf8\x8d\x2b\x37\xf3\x5e\xe6\x6c\x1a\xd7\x80\x1a\x28\xd3\xd3\x88\xac\x45\x0b\x97\xd5\xf0\xf7\x9e\x45\x41\x75\x53\x56\xb3\xb1\xa5\x69\x6b\x02\x3f\x39\xab\x7a\xb5\xf2\x8d\xf4\x20\x29\x36\xbc\x97\x39\x3b\x93\xbc\x91\x5c\xb1\x59\xea\x1b\xd7\xa0\xa4\x14\xcb\x4b\x7a\x1a\xc3\xaf\x68\xf5\x0d\x79\xf0\xc9\xc7\x31\x4e\x75\x0f\x7d\x02\xfa\xa5\x8b\xfa",
+ "\x82\x01\x01\xf5\x43\x5d\x86\xe1\x9b\xec\x58\xed\x0e\x1c\x7e\x63\x0f\xe8\x2d\xd9\x2d\x77\x04\xe4\x14\x80\x2a\x16",
+ 241 },
+ { GCRY_MD_SHA3_224,
+ "\x56\x68\xec\xd9\x9d\xfb\xe2\x15\xc4\x11\x83\x98\xac\x9c\x9e\xaf\x1a\x14\x33\xfa\xb4\xcc\xdd\x39\x68\x06\x47\x52\xb6\x25\xea\x94\x47\x31\xf7\x5d\x48\xa2\x7d\x04\x7d\x67\x54\x7f\x14\xdd\x0f\xfa\xa5\x5f\xa5\xe2\x9f\x7a\xf0\xd1\x61\xd8\x5e\xaf\xc4\xf2\x02\x9b\x71\x7c\x91\x8e\xab\x9d\x30\x45\x43\x29\x0b\xdb\xa7\x15\x8b\x68\x02\x0c\x0b\xa4\xe0\x79\xbc\x95\xb5\xbc\x0f\xc0\x44\xa9\x92\xb9\x4b\x4c\xcd\x3b\xd6\x6d\x0e\xab\xb5\xdb\xba\xb9\x04\xd6\x2e\x00\x75\x2c\x4e\x3b\x00\x91\xd7\x73\xbc\xf4\xc1\x4b\x43\x77\xda\x3e\xff\xf8\x24\xb1\xcb\x2f\xa0\x1b\x32\xd1\xe4\x6c\x90\x9e\x62\x6e\xd2\xda\xe9\x20\xf4\xc7\xdb\xeb\x63\x5b\xc7\x54\xfa\xcb\xd8\xd4\x9b\xeb\xa3\xf2\x3c\x1c\x41\xcc\xbf\xcd\x0e\xe0\xc1\x14\xe6\x97\x37\xf5\x59\x7c\x0b\xf1\xd8\x59\xf0\xc7\x67\xe1\x80\x02\xae\x8e\x39\xc2\x62\x61\xff\xde\x29\x20\xd3\xd0\xba\xf0\xe9\x06\x13\x86\x96\xcf\xe5\xb7\xe3\x2b\x60\x0f\x45\xdf\x3a\xaa\x39\x93\x2f\x3a\x7d\xf9\x5b\x60\xfa\x87\x12\xa2\x27\x1f\xca\xf3\x91\x1c\xe7\xb5\x11\xb1",
+ "\xb1\xcf\x54\xf5\x1f\x81\xfd\xb5\xb6\x49\xbb\x61\x15\x12\x61\x49\x29\x62\x78\xbf\xf3\xd5\x39\x5c\xf5\xf1\x12\xd4",
+ 242 },
+ { GCRY_MD_SHA3_224,
+ "\x03\xd6\x25\x48\x83\x54\xdf\x30\xe3\xf8\x75\xa6\x8e\xdf\xcf\x34\x0e\x83\x66\xa8\xe1\xab\x67\xf9\xd5\xc5\x48\x6a\x96\x82\x9d\xfa\xc0\x57\x82\x89\x08\x2b\x2a\x62\x11\x7e\x1c\xf4\x18\xb4\x3b\x90\xe0\xad\xc8\x81\xfc\x6a\xe8\x10\x5c\x88\x8e\x9e\xcd\x21\xae\xa1\xc9\xae\x1a\x40\x38\xdf\xd1\x73\x78\xfe\xd7\x1d\x02\xae\x49\x20\x87\xd7\xcd\xcd\x98\xf7\x46\x85\x52\x27\x96\x7c\xb1\xab\x47\x14\x26\x1e\xe3\xbe\xad\x3f\x4d\xb1\x18\x32\x9d\x3e\xbe\xf4\xbc\x48\xa8\x75\xc1\x9b\xa7\x63\x96\x6d\xa0\xeb\xea\x80\x0e\x01\xb2\xf5\x0b\x00\xe9\xdd\x4c\xac\xa6\xdc\xb3\x14\xd0\x01\x84\xef\x71\xea\x23\x91\xd7\x60\xc9\x50\x71\x0d\xb4\xa7\x0f\x92\x12\xff\xc5\x48\x61\xf9\xdc\x75\x2c\xe1\x88\x67\xb8\xad\x0c\x48\xdf\x84\x66\xef\x72\x31\xe7\xac\x56\x7f\x0e\xb5\x50\x99\xe6\x22\xeb\xb8\x6c\xb2\x37\x52\x01\x90\xa6\x1c\x66\xad\x34\xf1\xf4\xe2\x89\xcb\x32\x82\xae\x3e\xaa\xc6\x15\x2e\xd2\x4d\x2c\x92\xba\xe5\xa7\x65\x82\x52\xa5\x3c\x49\xb7\xb0\x2d\xfe\x54\xfd\xb2\xe9\x00\x74\xb6\xcf\x31\x0a\xc6\x61",
+ "\xb6\x02\x72\x2d\x1b\x9f\x31\xb9\xc5\x09\x1e\x0f\xf7\x20\xf1\xd1\xa8\xa5\x1e\xb6\xf9\x5e\xd3\xb4\x12\xde\x06\x3d",
+ 243 },
+ { GCRY_MD_SHA3_224,
+ "\x2e\xdc\x28\x2f\xfb\x90\xb9\x71\x18\xdd\x03\xaa\xa0\x3b\x14\x5f\x36\x39\x05\xe3\xcb\xd2\xd5\x0e\xcd\x69\x2b\x37\xbf\x00\x01\x85\xc6\x51\xd3\xe9\x72\x6c\x69\x0d\x37\x73\xec\x1e\x48\x51\x0e\x42\xb1\x77\x42\xb0\xb0\x37\x7e\x7d\xe6\xb8\xf5\x5e\x00\xa8\xa4\xdb\x47\x40\xce\xe6\xdb\x08\x30\x52\x9d\xd1\x96\x17\x50\x1d\xc1\xe9\x35\x9a\xa3\xbc\xf1\x47\xe0\xa7\x6b\x3a\xb7\x0c\x49\x84\xc1\x3e\x33\x9e\x68\x06\xbb\x35\xe6\x83\xaf\x85\x27\x09\x36\x70\x85\x9f\x3d\x8a\x0f\xc7\xd4\x93\xbc\xba\x6b\xb1\x2b\x5f\x65\xe7\x1e\x70\x5c\xa5\xd6\xc9\x48\xd6\x6e\xd3\xd7\x30\xb2\x6d\xb3\x95\xb3\x44\x77\x37\xc2\x6f\xad\x08\x9a\xa0\xad\x0e\x30\x6c\xb2\x8b\xf0\xac\xf1\x06\xf8\x9a\xf3\x74\x5f\x0e\xc7\x2d\x53\x49\x68\xcc\xa5\x43\xcd\x2c\xa5\x0c\x94\xb1\x45\x67\x43\x25\x4e\x35\x8c\x13\x17\xc0\x7a\x07\xbf\x2b\x0e\xca\x43\x8a\x70\x93\x67\xfa\xfc\x89\xa5\x72\x39\x02\x8f\xc5\xfe\xcf\xd5\x3b\x8e\xf9\x58\xef\x10\xee\x06\x08\xb7\xf5\xcb\x99\x23\xad\x97\x05\x8e\xc0\x67\x70\x0c\xc7\x46\xc1\x27\xa6\x1e\xe3",
+ "\x13\x68\x45\x4e\x84\x9f\x2d\x22\x99\x07\x7f\x40\x82\x6b\x40\x72\xe6\xfe\xe4\x9b\x20\x62\xcb\x8e\x3b\x45\x23\xc9",
+ 244 },
+ { GCRY_MD_SHA3_224,
+ "\x90\xb2\x8a\x6a\xa1\xfe\x53\x39\x15\xbc\xb8\xe8\x1e\xd6\xca\xcd\xc1\x09\x62\xb7\xff\x82\x47\x4f\x84\x5e\xeb\x86\x97\x76\x00\xcf\x70\xb0\x7b\xa8\xe3\x79\x61\x41\xee\x34\x0e\x3f\xce\x84\x2a\x38\xa5\x0a\xfb\xe9\x03\x01\xa3\xbd\xcc\x59\x1f\x2e\x7d\x9d\xe5\x3e\x49\x55\x25\x56\x0b\x90\x8c\x89\x24\x39\x99\x0a\x2c\xa2\x67\x9c\x55\x39\xff\xdf\x63\x67\x77\xad\x9c\x1c\xde\xf8\x09\xcd\xa9\xe8\xdc\xdb\x45\x1a\xbb\x9e\x9c\x17\xef\xa4\x37\x9a\xbd\x24\xb1\x82\xbd\x98\x1c\xaf\xc7\x92\x64\x0a\x18\x3b\x61\x69\x43\x01\xd0\x4c\x5b\x3e\xaa\xd6\x94\xa6\xbd\x4c\xc0\x6e\xf5\xda\x8f\xa2\x3b\x4f\xa2\xa6\x45\x59\xc5\xa6\x83\x97\x93\x00\x79\xd2\x50\xc5\x1b\xcf\x00\xe2\xb1\x6a\x6c\x49\x17\x14\x33\xb0\xaa\xdf\xd8\x02\x31\x27\x65\x60\xb8\x04\x58\xdd\x77\x08\x9b\x7a\x1b\xbc\xc9\xe7\xe4\xb9\xf8\x81\xea\xcd\x6c\x92\xc4\x31\x83\x48\xa1\x3f\x49\x14\xeb\x27\x11\x5a\x1c\xfc\x5d\x16\xd7\xfd\x94\x95\x4c\x35\x32\xef\xac\xa2\xca\xb0\x25\x10\x3b\x2d\x02\xc6\xfd\x71\xda\x3a\x77\xf4\x17\xd7\x93\x26\x85\x88\x8a",
+ "\x57\x65\xb7\x05\x74\xf9\x33\x41\xc1\xcc\x4a\xcb\x34\xf6\x45\xb5\xd9\x7b\x81\xd4\xce\x8f\x38\xc3\x86\x2f\x6c\x19",
+ 245 },
+ { GCRY_MD_SHA3_224,
+ "\x29\x69\x44\x7d\x17\x54\x90\xf2\xaa\x9b\xb0\x55\x01\x4d\xbe\xf2\xe6\x85\x4c\x95\xf8\xd6\x09\x50\xbf\xe8\xc0\xbe\x8d\xe2\x54\xc2\x6b\x2d\x31\xb9\xe4\xde\x9c\x68\xc9\xad\xf4\x9e\x4e\xe9\xb1\xc2\x85\x09\x67\xf2\x9f\x5d\x08\x73\x84\x83\xb4\x17\xbb\x96\xb2\xa5\x6f\x0c\x8a\xca\x63\x2b\x55\x20\x59\xc5\x9a\xac\x3f\x61\xf7\xb4\x5c\x96\x6b\x75\xf1\xd9\x93\x1f\xf4\xe5\x96\x40\x63\x78\xce\xe9\x1a\xaa\x72\x6a\x3a\x84\xc3\x3f\x37\xe9\xcd\xbe\x62\x6b\x57\x45\xa0\xb0\x60\x64\xa8\xa8\xd5\x6e\x53\xaa\xf1\x02\xd2\x3d\xd9\xdf\x0a\x3f\xdf\x7a\x63\x85\x09\xa6\x76\x1a\x33\xfa\x42\xfa\x8d\xdb\xd8\xe1\x61\x59\xc9\x30\x08\xb5\x37\x65\x01\x9c\x3f\x0e\x9f\x10\xb1\x44\xce\x2a\xc5\x7f\x5d\x72\x97\xf9\xc9\x94\x9e\x4f\xf6\x8b\x70\xd3\x39\xf8\x75\x01\xce\x85\x50\xb7\x72\xf3\x2c\x6d\xa8\xad\x2c\xe2\x10\x0a\x89\x5d\x8b\x08\xfa\x1e\xea\xd7\xc3\x76\xb4\x07\x70\x97\x03\xc5\x10\xb5\x0f\x87\xe7\x3e\x43\xf8\xe7\x34\x8f\x87\xc3\x83\x2a\x54\x7e\xf2\xbb\xe5\x79\x9a\xbe\xdc\xf5\xe1\xf3\x72\xea\x80\x92\x33\xf0\x06",
+ "\xb8\xfb\x31\x82\x45\xb4\x04\x22\x22\xb4\x06\x3a\x05\x3f\x15\xda\x6b\x89\x4f\x22\x73\x6f\x3f\x9e\x26\xf7\x21\x75",
+ 246 },
+ { GCRY_MD_SHA3_224,
+ "\x72\x16\x45\x63\x3a\x44\xa2\xc7\x8b\x19\x02\x4e\xae\xcf\x58\x57\x5a\xb2\x3c\x27\x19\x08\x33\xc2\x68\x75\xdc\x0f\x0d\x50\xb4\x6a\xea\x9c\x34\x3d\x82\xea\x7d\x5b\x3e\x50\xec\x70\x05\x45\xc6\x15\xda\xea\xea\x64\x72\x6a\x0f\x05\x60\x75\x76\xdc\xd3\x96\xd8\x12\xb0\x3f\xb6\x55\x1c\x64\x10\x87\x85\x6d\x05\x0b\x10\xe6\xa4\xd5\x57\x7b\x82\xa9\x8a\xfb\x89\xce\xe8\x59\x4c\x9d\xc1\x9e\x79\xfe\xff\x03\x82\xfc\xfd\x12\x7f\x1b\x80\x3a\x4b\x99\x46\xf4\xac\x9a\x43\x78\xe1\xe6\xe0\x41\xb1\x38\x9a\x53\xe3\x45\x0c\xd3\x2d\x9d\x29\x41\xb0\xcb\xab\xdb\x50\xda\x8e\xa2\x51\x31\x45\x16\x4c\x3a\xb6\xbc\xbd\x25\x1c\x44\x8d\x2d\x4b\x08\x7a\xc5\x7a\x59\xc2\x28\x5d\x56\x4f\x16\xda\x4e\xd5\xe6\x07\xed\x97\x95\x92\x14\x6f\xfb\x0e\xf3\xf3\xdb\x30\x8f\xb3\x42\xdf\x5e\xb5\x92\x4a\x48\x25\x6f\xc7\x63\x14\x1a\x27\x88\x14\xc8\x2d\x6d\x63\x48\x57\x75\x45\x87\x0a\xe3\xa8\x3c\x72\x30\xac\x02\xa1\x54\x0f\xe1\x79\x8f\x7e\xf0\x9e\x33\x5a\x86\x5a\x2a\xe0\x94\x9b\x21\xe4\xf7\x48\xfb\x8a\x51\xf4\x47\x50\xe2\x13\xa8\xfb",
+ "\x35\x36\x22\xe9\x2c\x79\x07\xf5\x56\x3b\xaf\x8f\x4e\x7a\xf0\xc2\xf8\x72\xf4\xfb\x58\x3b\x01\xaf\x9e\xb3\xd9\x07",
+ 247 },
+ { GCRY_MD_SHA3_224,
+ "\x6b\x86\x0d\x39\x72\x5a\x14\xb4\x98\xbb\x71\x45\x74\xb4\xd3\x7c\xa7\x87\x40\x47\x68\xf6\x4c\x64\x8b\x17\x51\xb3\x53\xac\x92\xba\xc2\xc3\xa2\x8e\xa9\x09\xfd\xf0\x42\x33\x36\x40\x1a\x02\xe6\x3e\xc2\x43\x25\x30\x0d\x82\x3b\x68\x64\xbb\x70\x1f\x9d\x7c\x7a\x1f\x8e\xc9\xd0\xae\x35\x84\xaa\x6d\xd6\x2e\xa1\x99\x7c\xd8\x31\xb4\xba\xbd\x9a\x4d\xa5\x09\x32\xd4\xef\xda\x74\x5c\x61\xe4\x13\x08\x90\xe1\x56\xae\xe6\x11\x37\x16\xda\xf9\x57\x64\x22\x2a\x91\x18\x7d\xb2\xef\xfe\xa4\x9d\x5d\x05\x96\x10\x2d\x61\x9b\xd2\x6a\x61\x6b\xbf\xda\x83\x35\x50\x5f\xbb\x0d\x90\xb4\xc1\x80\xd1\xa2\x33\x5b\x91\x53\x8e\x16\x68\xf9\xf9\x64\x27\x90\xb4\xe5\x5f\x9c\xab\x0f\xe2\xbd\xd2\x93\x5d\x00\x1e\xe6\x41\x9a\xba\xb5\x45\x78\x80\xd0\xdb\xff\x20\xed\x87\x58\xf4\xc2\x0f\xe7\x59\xef\xb3\x31\x41\xcf\x0e\x89\x25\x87\xfe\x81\x87\xe5\xfb\xc5\x77\x86\xb7\xe8\xb0\x89\x61\x2c\x93\x6d\xfc\x03\xd2\x7e\xfb\xbe\x7c\x86\x73\xf1\x60\x6b\xd5\x1d\x5f\xf3\x86\xf4\xa7\xab\x68\xed\xf5\x9f\x38\x5e\xb1\x29\x1f\x11\x7b\xfe\x71\x73\x99",
+ "\x87\x21\x5a\xf7\x3d\x5c\xde\x98\xb3\x55\x47\x9a\xfb\x82\xa5\x11\x18\x0b\x7d\xc3\xd5\x34\x2c\x88\xe1\x33\xae\xd8",
+ 248 },
+ { GCRY_MD_SHA3_224,
+ "\x6a\x01\x83\x0a\xf3\x88\x9a\x25\x18\x32\x44\xde\xcb\x50\x8b\xd0\x12\x53\xd5\xb5\x08\xab\x49\x0d\x31\x24\xaf\xbf\x42\x62\x6b\x2e\x70\x89\x4e\x9b\x56\x2b\x28\x8d\x0a\x24\x50\xcf\xac\xf1\x4a\x0d\xda\xe5\xc0\x47\x16\xe5\xa0\x08\x2c\x33\x98\x1f\x60\x37\xd2\x3d\x5e\x04\x5e\xe1\xef\x22\x83\xfb\x8b\x63\x78\xa9\x14\xc5\xd9\x44\x16\x27\xa7\x22\xc2\x82\xff\x45\x2e\x25\xa7\xea\x60\x8d\x69\xce\xe4\x39\x3a\x07\x25\xd1\x79\x63\xd0\x34\x26\x84\xf2\x55\x49\x6d\x8a\x18\xc2\x96\x11\x45\x31\x51\x30\x54\x93\x11\xfc\x07\xf0\x31\x2f\xb7\x8e\x60\x77\x33\x4f\x87\xea\xa8\x73\xbe\xe8\xaa\x95\x69\x89\x96\xeb\x21\x37\x5e\xb2\xb4\xef\x53\xc1\x44\x01\x20\x7d\xeb\x45\x68\x39\x8e\x5d\xd9\xa7\xcf\x97\xe8\xc9\x66\x3e\x23\x33\x4b\x46\x91\x2f\x83\x44\xc1\x9e\xfc\xf8\xc2\xba\x6f\x04\x32\x5f\x1a\x27\xe0\x62\xb6\x2a\x58\xd0\x76\x6f\xc6\xdb\x4d\x2c\x6a\x19\x28\x60\x4b\x01\x75\xd8\x72\xd1\x6b\x79\x08\xeb\xc0\x41\x76\x11\x87\xcc\x78\x55\x26\xc2\xa3\x87\x3f\xea\xc3\xa6\x42\xbb\x39\xf5\x35\x15\x50\xaf\x97\x70\xc3\x28\xaf\x7b",
+ "\x25\xae\x85\x2d\xba\x36\xb8\xd5\x8a\x94\xdd\x5c\xfd\x83\x45\x14\x1f\xf5\x7e\x7d\xb7\xd7\x81\x6c\x4f\x72\x52\xbb",
+ 249 },
+ { GCRY_MD_SHA3_224,
+ "\xb3\xc5\xe7\x4b\x69\x93\x3c\x25\x33\x10\x6c\x56\x3b\x4c\xa2\x02\x38\xf2\xb6\xe6\x75\xe8\x68\x1e\x34\xa3\x89\x89\x47\x85\xbd\xad\xe5\x96\x52\xd4\xa7\x3d\x80\xa5\xc8\x5b\xd4\x54\xfd\x1e\x9f\xfd\xad\x1c\x38\x15\xf5\x03\x8e\x9e\xf4\x32\xaa\xc5\xc3\xc4\xfe\x84\x0c\xc3\x70\xcf\x86\x58\x0a\x60\x11\x77\x8b\xbe\xda\xf5\x11\xa5\x1b\x56\xd1\xa2\xeb\x68\x39\x4a\xa2\x99\xe2\x6d\xa9\xad\xa6\xa2\xf3\x9b\x9f\xaf\xf7\xfb\xa4\x57\x68\x9b\x9c\x1a\x57\x7b\x2a\x1e\x50\x5f\xdf\x75\xc7\xa0\xa6\x4b\x1d\xf8\x1b\x3a\x35\x60\x01\xbf\x0d\xf4\xe0\x2a\x1f\xc5\x9f\x65\x1c\x9d\x58\x5e\xc6\x22\x4b\xb2\x79\xc6\xbe\xba\x29\x66\xe8\x88\x2d\x68\x37\x60\x81\xb9\x87\x46\x8e\x7a\xed\x1e\xf9\x0e\xbd\x09\x0a\xe8\x25\x79\x5c\xdc\xa1\xb4\xf0\x9a\x97\x9c\x8d\xfc\x21\xa4\x8d\x8a\x53\xcd\xbb\x26\xc4\xdb\x54\x7f\xc0\x6e\xfe\x2f\x98\x50\xed\xd2\x68\x5a\x46\x61\xcb\x49\x11\xf1\x65\xd4\xb6\x3e\xf2\x5b\x87\xd0\xa9\x6d\x3d\xff\x6a\xb0\x75\x89\x99\xaa\xd2\x14\xd0\x7b\xd4\xf1\x33\xa6\x73\x4f\xde\x44\x5f\xe4\x74\x71\x1b\x69\xa9\x8f\x7e\x2b",
+ "\xec\xe0\x39\x44\x18\xf0\x66\xf5\x50\x23\x79\x75\x51\xe0\x6f\x6a\x7d\x16\x45\x68\x2a\xa4\xd9\xdd\x75\xaf\x8e\x76",
+ 250 },
+ { GCRY_MD_SHA3_224,
+ "\x83\xaf\x34\x27\x9c\xcb\x54\x30\xfe\xbe\xc0\x7a\x81\x95\x0d\x30\xf4\xb6\x6f\x48\x48\x26\xaf\xee\x74\x56\xf0\x07\x1a\x51\xe1\xbb\xc5\x55\x70\xb5\xcc\x7e\xc6\xf9\x30\x9c\x17\xbf\x5b\xef\xdd\x7c\x6b\xa6\xe9\x68\xcf\x21\x8a\x2b\x34\xbd\x5c\xf9\x27\xab\x84\x6e\x38\xa4\x0b\xbd\x81\x75\x9e\x9e\x33\x38\x10\x16\xa7\x55\xf6\x99\xdf\x35\xd6\x60\x00\x7b\x5e\xad\xf2\x92\xfe\xef\xb7\x35\x20\x7e\xbf\x70\xb5\xbd\x17\x83\x4f\x7b\xfa\x0e\x16\xcb\x21\x9a\xd4\xaf\x52\x4a\xb1\xea\x37\x33\x4a\xa6\x64\x35\xe5\xd3\x97\xfc\x0a\x06\x5c\x41\x1e\xbb\xce\x32\xc2\x40\xb9\x04\x76\xd3\x07\xce\x80\x2e\xc8\x2c\x1c\x49\xbc\x1b\xec\x48\xc0\x67\x5e\xc2\xa6\xc6\xf3\xed\x3e\x5b\x74\x1d\x13\x43\x70\x95\x70\x7c\x56\x5e\x10\xd8\xa2\x0b\x8c\x20\x46\x8f\xf9\x51\x4f\xcf\x31\xb4\x24\x9c\xd8\x2d\xce\xe5\x8c\x0a\x2a\xf5\x38\xb2\x91\xa8\x7e\x33\x90\xd7\x37\x19\x1a\x07\x48\x4a\x5d\x3f\x3f\xb8\xc8\xf1\x5c\xe0\x56\xe5\xe5\xf8\xfe\xbe\x5e\x1f\xb5\x9d\x67\x40\x98\x0a\xa0\x6c\xa8\xa0\xc2\x0f\x57\x12\xb4\xcd\xe5\xd0\x32\xe9\x2a\xb8\x9f\x0a\xe1",
+ "\x84\xa4\xbd\x2e\x3f\xa2\x6c\x4f\xb0\x1f\xe8\x19\x53\x39\x8f\x5b\x4b\x57\x04\x94\x43\x54\xb5\x1b\x88\x7f\xd9\x90",
+ 251 },
+ { GCRY_MD_SHA3_224,
+ "\xa7\xed\x84\x74\x9c\xcc\x56\xbb\x1d\xfb\xa5\x71\x19\xd2\x79\xd4\x12\xb8\xa9\x86\x88\x6d\x81\x0f\x06\x7a\xf3\x49\xe8\x74\x9e\x9e\xa7\x46\xa6\x0b\x03\x74\x26\x36\xc4\x64\xfc\x1e\xe2\x33\xac\xc5\x2c\x19\x83\x91\x46\x92\xb6\x43\x09\xed\xfd\xf2\x9f\x1a\xb9\x12\xec\x3e\x8d\xa0\x74\xd3\xf1\xd2\x31\x51\x1f\x57\x56\xf0\xb6\xee\xad\x3e\x89\xa6\xa8\x8f\xe3\x30\xa1\x0f\xac\xe2\x67\xbf\xfb\xfc\x3e\x30\x90\xc7\xfd\x9a\x85\x05\x61\xf3\x63\xad\x75\xea\x88\x1e\x72\x44\xf8\x0f\xf5\x58\x02\xd5\xef\x7a\x1a\x4e\x7b\x89\xfc\xfa\x80\xf1\x6d\xf5\x4d\x1b\x05\x6e\xe6\x37\xe6\x96\x4b\x9e\x0f\xfd\x15\xb6\x19\x6b\xdd\x7d\xb2\x70\xc5\x6b\x47\x25\x14\x85\x34\x8e\x49\x81\x3b\x4e\xb9\xed\x12\x2a\x01\xb3\xea\x45\xad\x5e\x1a\x92\x9d\xf6\x1d\x5c\x0f\x3e\x77\xe1\xfd\xc3\x56\xb6\x38\x83\xa6\x0e\x9c\xbb\x9f\xc3\xe0\x0c\x2f\x32\xdb\xd4\x69\x65\x98\x83\xf6\x90\xc6\x77\x2e\x33\x5f\x61\x7b\xc3\x3f\x16\x1d\x6f\x69\x84\x25\x2e\xe1\x2e\x62\xb6\x00\x0a\xc5\x23\x1e\x0c\x9b\xc6\x5b\xe2\x23\xd8\xdf\xd9\x4c\x50\x04\xa1\x01\xaf\x9f\xd6\xc0\xfb",
+ "\x17\x0c\x41\x38\x63\xd9\xf4\xe8\xc0\xb8\x7a\x85\x32\x41\x6b\x10\xa6\x9c\x34\x8d\x3a\x14\x46\x58\xea\xee\xf0\xed",
+ 252 },
+ { GCRY_MD_SHA3_224,
+ "\xa6\xfe\x30\xdc\xfc\xda\x1a\x32\x9e\x82\xab\x50\xe3\x2b\x5f\x50\xeb\x25\xc8\x73\xc5\xd2\x30\x58\x60\xa8\x35\xae\xce\xe6\x26\x4a\xa3\x6a\x47\x42\x99\x22\xc4\xb8\xb3\xaf\xd0\x0d\xa1\x60\x35\x83\x0e\xdb\x89\x78\x31\xc4\xe7\xb0\x0f\x2c\x23\xfc\x0b\x15\xfd\xc3\x0d\x85\xfb\x70\xc3\x0c\x43\x1c\x63\x8e\x1a\x25\xb5\x1c\xaf\x1d\x7e\x8b\x05\x0b\x7f\x89\xbf\xb3\x0f\x59\xf0\xf2\x0f\xec\xff\x3d\x63\x9a\xbc\x42\x55\xb3\x86\x8f\xc4\x5d\xd8\x1e\x47\xeb\x12\xab\x40\xf2\xaa\xc7\x35\xdf\x5d\x1d\xc1\xad\x99\x7c\xef\xc4\xd8\x36\xb8\x54\xce\xe9\xac\x02\x90\x00\x36\xf3\x86\x7f\xe0\xd8\x4a\xff\xf3\x7b\xde\x33\x08\xc2\x20\x6c\x62\xc4\x74\x33\x75\x09\x41\x08\x87\x7c\x73\xb8\x7b\x25\x46\xfe\x05\xea\x13\x7b\xed\xfc\x06\xa2\x79\x62\x74\x09\x9a\x0d\x55\x4d\xa8\xf7\xd7\x22\x3a\x48\xcb\xf3\x1b\x7d\xec\xaa\x1e\xbc\x8b\x14\x57\x63\xe3\x67\x31\x68\xc1\xb1\xb7\x15\xc1\xcd\x99\xec\xd3\xdd\xb2\x38\xb0\x60\x49\x88\x5e\xca\xd9\x34\x7c\x24\x36\xdf\xf3\x2c\x77\x1f\x34\xa3\x85\x87\xa4\x4a\x82\xc5\xd3\xd1\x37\xa0\x3c\xaa\x27\xe6\x6c\x8f\xf6",
+ "\xd8\xc2\x57\xdb\x76\x53\x6f\x7e\xf1\xdc\xfb\x24\x97\x6e\xb7\x16\xd9\x49\x1c\xd8\x65\x1e\x02\x54\xe7\xc4\xa5\xbb",
+ 253 },
+ { GCRY_MD_SHA3_224,
+ "\x83\x16\x7f\xf5\x37\x04\xc3\xaa\x19\xe9\xfb\x33\x03\x53\x97\x59\xc4\x6d\xd4\x09\x1a\x52\xdd\xae\x9a\xd8\x64\x08\xb6\x93\x35\x98\x9e\x61\x41\x4b\xc2\x0a\xb4\xd0\x12\x20\xe3\x52\x41\xef\xf5\xc9\x52\x2b\x07\x9f\xba\x59\x76\x74\xc8\xd7\x16\xfe\x44\x1e\x56\x61\x10\xb6\x21\x15\x31\xce\xcc\xf8\xfd\x06\xbc\x8e\x51\x1d\x00\x78\x5e\x57\x78\x8e\xd9\xa1\xc5\xc7\x35\x24\xf0\x18\x30\xd2\xe1\x14\x8c\x92\xd0\xed\xc9\x71\x13\xe3\xb7\xb5\xcd\x30\x49\x62\x7a\xbd\xb8\xb3\x9d\xd4\xd6\x89\x0e\x0e\xe9\x19\x93\xf9\x2b\x03\x35\x4a\x88\xf5\x22\x51\xc5\x46\xe6\x44\x34\xd9\xc3\xd7\x45\x44\xf2\x3f\xb9\x3e\x5a\x2d\x2f\x1f\xb1\x55\x45\xb4\xe1\x36\x7c\x97\x33\x5b\x02\x91\x94\x4c\x8b\x73\x0a\xd3\xd4\x78\x92\x73\xfa\x44\xfb\x98\xd7\x8a\x36\xc3\xc3\x76\x4a\xbe\xea\xc7\xc5\x69\xc1\xe4\x3a\x35\x2e\x5b\x77\x0c\x35\x04\xf8\x70\x90\xde\xe0\x75\xa1\xc4\xc8\x5c\x0c\x39\xcf\x42\x1b\xdc\xc6\x15\xf9\xef\xf6\xcb\x4f\xe6\x46\x80\x04\xae\xce\x5f\x30\xe1\xec\xc6\xdb\x22\xad\x99\x39\xbb\x2b\x0c\xcc\x96\x52\x1d\xfb\xf4\xae\x00\x8b\x5b\x46\xbc\x00\x6e",
+ "\xf8\x1d\x8e\xe4\x08\x69\xbb\x38\xa1\x3a\x4f\x75\x58\x8f\xa3\x30\x80\x68\xdd\x1c\xdc\x27\x26\x7d\x66\xfa\xc1\x98",
+ 254 },
+ { GCRY_MD_SHA3_224,
+ "\x3a\x3a\x81\x9c\x48\xef\xde\x2a\xd9\x14\xfb\xf0\x0e\x18\xab\x6b\xc4\xf1\x45\x13\xab\x27\xd0\xc1\x78\xa1\x88\xb6\x14\x31\xe7\xf5\x62\x3c\xb6\x6b\x23\x34\x67\x75\xd3\x86\xb5\x0e\x98\x2c\x49\x3a\xdb\xbf\xc5\x4b\x9a\x3c\xd3\x83\x38\x23\x36\xa1\xa0\xb2\x15\x0a\x15\x35\x8f\x33\x6d\x03\xae\x18\xf6\x66\xc7\x57\x3d\x55\xc4\xfd\x18\x1c\x29\xe6\xcc\xfd\xe6\x3e\xa3\x5f\x0a\xdf\x58\x85\xcf\xc0\xa3\xd8\x4a\x2b\x2e\x4d\xd2\x44\x96\xdb\x78\x9e\x66\x31\x70\xce\xf7\x47\x98\xaa\x1b\xbc\xd4\x57\x4e\xa0\xbb\xa4\x04\x89\xd7\x64\xb2\xf8\x3a\xad\xc6\x6b\x14\x8b\x4a\x0c\xd9\x52\x46\xc1\x27\xd5\x87\x1c\x4f\x11\x41\x86\x90\xa5\xdd\xf0\x12\x46\xa0\xc8\x0a\x43\xc7\x00\x88\xb6\x18\x36\x39\xdc\xfd\xa4\x12\x5b\xd1\x13\xa8\xf4\x9e\xe2\x3e\xd3\x06\xfa\xac\x57\x6c\x3f\xb0\xc1\xe2\x56\x67\x1d\x81\x7f\xc2\x53\x4a\x52\xf5\xb4\x39\xf7\x2e\x42\x4d\xe3\x76\xf4\xc5\x65\xcc\xa8\x23\x07\xdd\x9e\xf7\x6d\xa5\xb7\xc4\xeb\x7e\x08\x51\x72\xe3\x28\x80\x7c\x02\xd0\x11\xff\xbf\x33\x78\x53\x78\xd7\x9d\xc2\x66\xf6\xa5\xbe\x6b\xb0\xe4\xa9\x2e\xce\xeb\xae\xb1",
+ "\x94\x68\x9e\xa9\xf3\x47\xdd\xa8\xdd\x79\x8a\x85\x86\x05\x86\x87\x43\xc6\xbd\x03\xa6\xa6\x5c\x60\x85\xd5\x2b\xed",
+ 255 },
diff --git a/comm/third_party/libgcrypt/tests/sha3-256.h b/comm/third_party/libgcrypt/tests/sha3-256.h
new file mode 100644
index 0000000000..f787b63bd3
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/sha3-256.h
@@ -0,0 +1,1025 @@
+/* Generated from https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHA3-256.txt */
+ { 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",
+ 0 },
+ { GCRY_MD_SHA3_256,
+ "\xcc",
+ "\x67\x70\x35\x39\x1c\xd3\x70\x12\x93\xd3\x85\xf0\x37\xba\x32\x79\x62\x52\xbb\x7c\xe1\x80\xb0\x0b\x58\x2d\xd9\xb2\x0a\xaa\xd7\xf0",
+ 1 },
+ { GCRY_MD_SHA3_256,
+ "\x41\xfb",
+ "\x39\xf3\x1b\x6e\x65\x3d\xfc\xd9\xca\xed\x26\x02\xfd\x87\xf6\x1b\x62\x54\xf5\x81\x31\x2f\xb6\xee\xec\x4d\x71\x48\xfa\x2e\x72\xaa",
+ 2 },
+ { GCRY_MD_SHA3_256,
+ "\x1f\x87\x7c",
+ "\xbc\x22\x34\x5e\x4b\xd3\xf7\x92\xa3\x41\xcf\x18\xac\x07\x89\xf1\xc9\xc9\x66\x71\x2a\x50\x1b\x19\xd1\xb6\x63\x2c\xcd\x40\x8e\xc5",
+ 3 },
+ { GCRY_MD_SHA3_256,
+ "\xc1\xec\xfd\xfc",
+ "\xc5\x85\x9b\xe8\x25\x60\xcc\x87\x89\x13\x3f\x7c\x83\x4a\x6e\xe6\x28\xe3\x51\xe5\x04\xe6\x01\xe8\x05\x9a\x06\x67\xff\x62\xc1\x24",
+ 4 },
+ { GCRY_MD_SHA3_256,
+ "\x21\xf1\x34\xac\x57",
+ "\x55\xbd\x92\x24\xaf\x4e\xed\x0d\x12\x11\x49\xe3\x7f\xf4\xd7\xdd\x5b\xe2\x4b\xd9\xfb\xe5\x6e\x01\x71\xe8\x7d\xb7\xa6\xf4\xe0\x6d",
+ 5 },
+ { GCRY_MD_SHA3_256,
+ "\xc6\xf5\x0b\xb7\x4e\x29",
+ "\xae\x0c\xbc\x75\x7d\x4a\xb0\x88\xe1\x72\xab\xfd\x87\x46\x28\x99\x50\xf9\x2d\x38\xa2\x52\x95\x65\x8d\xbf\x74\x4b\x56\x35\xaf\x04",
+ 6 },
+ { GCRY_MD_SHA3_256,
+ "\x11\x97\x13\xcc\x83\xee\xef",
+ "\xe3\x40\xc9\xa4\x43\x73\xef\xcc\x21\x2f\x3c\xb6\x6a\x04\x7a\xc3\x4c\x87\xff\x1c\x58\xc4\xa1\x4b\x16\xa2\xbf\xc3\x46\x98\xbb\x1d",
+ 7 },
+ { GCRY_MD_SHA3_256,
+ "\x4a\x4f\x20\x24\x84\x51\x25\x26",
+ "\xba\x4f\xb0\x09\xd5\x7a\x5c\xeb\x85\xfc\x64\xd5\x4e\x5c\x55\xa5\x58\x54\xb4\x1c\xc4\x7a\xd1\x52\x94\xbc\x41\xf3\x21\x65\xdf\xba",
+ 8 },
+ { GCRY_MD_SHA3_256,
+ "\x1f\x66\xab\x41\x85\xed\x9b\x63\x75",
+ "\xb9\x88\x6e\xf9\x05\xc8\xbd\xd2\x72\xed\xa8\x29\x88\x65\xe0\x76\x98\x69\xf1\xc9\x64\x46\x0d\x1a\xa9\xd7\xa0\xc6\x87\x70\x7c\xcd",
+ 9 },
+ { GCRY_MD_SHA3_256,
+ "\xee\xd7\x42\x22\x27\x61\x3b\x6f\x53\xc9",
+ "\xfa\xb8\xf8\x8d\x31\x91\xe2\x1a\x72\x5b\x21\xc6\x3a\x02\xca\xd3\xfa\x7c\x45\x0e\xf8\x58\x4b\x94\xcf\xa3\x82\xf3\x93\x42\x24\x55",
+ 10 },
+ { GCRY_MD_SHA3_256,
+ "\xea\xee\xd5\xcd\xff\xd8\x9d\xec\xe4\x55\xf1",
+ "\x93\x63\xac\xd3\xf4\x8b\xb9\x1a\x89\x98\xaa\x0e\x8d\xf7\x5c\x97\x17\x70\xa1\x6a\x71\xe7\xd2\x33\x44\x09\x73\x4c\xd7\xd0\xa9\xee",
+ 11 },
+ { GCRY_MD_SHA3_256,
+ "\x5b\xe4\x3c\x90\xf2\x29\x02\xe4\xfe\x8e\xd2\xd3",
+ "\x16\x93\x2f\x6f\x65\xde\xaa\xd5\x78\x0e\x25\xab\x41\x0c\x66\xb0\xe4\x19\x8e\xba\x9f\x4e\xd1\xa2\x5e\xe2\x4f\x78\x79\xfa\xef\xe2",
+ 12 },
+ { GCRY_MD_SHA3_256,
+ "\xa7\x46\x27\x32\x28\x12\x2f\x38\x1c\x3b\x46\xe4\xf1",
+ "\x1c\x28\x10\x0e\x0e\xf5\x06\x71\xc7\xea\x3e\x02\x4f\xa3\xba\x9d\xa2\xeb\xdd\xb4\xde\x26\x4c\x3a\x24\x26\xc3\x6a\xd3\xf9\x1c\x61",
+ 13 },
+ { GCRY_MD_SHA3_256,
+ "\x3c\x58\x71\xcd\x61\x9c\x69\xa6\x3b\x54\x0e\xb5\xa6\x25",
+ "\x81\x83\xbe\x48\x75\xfa\xb7\xec\x5f\x99\xed\x94\xf5\xf9\x00\xcf\x1d\x6b\x95\x3d\x8f\x71\xe1\xe7\xcc\x00\x86\x87\x98\x0e\x61\x3a",
+ 14 },
+ { GCRY_MD_SHA3_256,
+ "\xfa\x22\x87\x4b\xcc\x06\x88\x79\xe8\xef\x11\xa6\x9f\x07\x22",
+ "\x3b\x1a\x6d\x21\xfe\x44\x69\x1d\xac\x4e\xb7\xc5\x93\xa6\xd8\x52\x3c\xb6\x06\xe6\x3c\xf0\x0e\x94\xd7\x11\xa5\x74\x24\x8d\xac\xa5",
+ 15 },
+ { GCRY_MD_SHA3_256,
+ "\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76",
+ "\x2c\x7e\x7c\xb3\x56\xfd\xc6\x8e\xc8\x92\x7e\x49\x9d\x2a\x6b\xae\x2b\x78\x18\x17\x91\x9c\x82\x9e\xbb\xe8\x22\x5b\xae\xd4\x69\x67",
+ 16 },
+ { GCRY_MD_SHA3_256,
+ "\x82\xe1\x92\xe4\x04\x3d\xdc\xd1\x2e\xcf\x52\x96\x9d\x0f\x80\x7e\xed",
+ "\xc7\xb1\x2e\xff\x69\x2d\x84\x21\x10\xcc\x39\xac\x60\x61\x67\x07\xac\xb3\xf9\xb0\xf1\xcb\x36\x1b\x94\x57\x7e\xfc\x52\x9c\xa2\x6c",
+ 17 },
+ { GCRY_MD_SHA3_256,
+ "\x75\x68\x3d\xcb\x55\x61\x40\xc5\x22\x54\x3b\xb6\xe9\x09\x8b\x21\xa2\x1e",
+ "\x49\x3e\xba\xeb\xc0\x47\x76\xf4\xe0\x67\x55\x5a\xfa\x09\xb5\x8c\x85\x0f\xdf\x1b\x0e\x22\xd4\xbf\x00\x6c\xe4\x1c\x09\x1d\xc7\x62",
+ 18 },
+ { GCRY_MD_SHA3_256,
+ "\x06\xe4\xef\xe4\x50\x35\xe6\x1f\xaa\xf4\x28\x7b\x4d\x8d\x1f\x12\xca\x97\xe5",
+ "\x1d\x01\xf3\x12\x0e\xcf\xbd\xd2\x8d\xce\x44\x31\x76\x66\xcf\x86\x4f\x52\x39\x1b\x9e\xca\x38\x43\xdb\x45\x66\x7c\x2e\x0a\x98\xad",
+ 19 },
+ { GCRY_MD_SHA3_256,
+ "\xe2\x61\x93\x98\x9d\x06\x56\x8f\xe6\x88\xe7\x55\x40\xae\xa0\x67\x47\xd9\xf8\x51",
+ "\x2c\x1e\x61\xe5\xd4\x52\x03\xf2\x7b\x86\xf1\x29\x3a\x80\xba\xb3\x41\x92\xda\xf4\x2b\x86\x23\xb1\x20\x05\xb2\xfb\x1c\x18\xac\xb1",
+ 20 },
+ { GCRY_MD_SHA3_256,
+ "\xd8\xdc\x8f\xde\xfb\xdc\xe9\xd4\x4e\x4c\xba\xfe\x78\x44\x7b\xae\x3b\x54\x36\x10\x2a",
+ "\xad\x0e\x3f\x29\x76\x70\x67\xe9\x29\xd1\xce\xcd\x95\x58\x2d\xf8\xf2\xa9\xbe\xb9\x2e\xaa\x27\xee\xb3\x15\xf6\x20\x36\x5a\x92\x44",
+ 21 },
+ { GCRY_MD_SHA3_256,
+ "\x57\x08\x5f\xd7\xe1\x42\x16\xab\x10\x2d\x83\x17\xb0\xcb\x33\x8a\x78\x6d\x5f\xc3\x2d\x8f",
+ "\x2b\x4e\xb5\xde\x20\xe8\x60\x74\xca\xbb\x55\xbf\xa6\x3a\x5c\x8c\x6a\xe1\x56\x79\x30\x20\x61\x84\x5b\x9c\xf2\x33\xe1\x7c\x90\x6b",
+ 22 },
+ { GCRY_MD_SHA3_256,
+ "\xa0\x54\x04\xdf\x5d\xbb\x57\x69\x7e\x2c\x16\xfa\x29\xde\xfa\xc8\xab\x35\x60\xd6\x12\x6f\xa0",
+ "\x6a\xe0\x4c\x6c\x6f\x36\x51\xf1\xf6\x4c\x0a\xd6\x97\x33\x99\x0b\x41\x74\x7c\x93\xf8\x7a\xcb\x81\x3b\xb2\x5b\xb1\xfc\x0e\xff\x07",
+ 23 },
+ { GCRY_MD_SHA3_256,
+ "\xae\xcb\xb0\x27\x59\xf7\x43\x3d\x6f\xcb\x06\x96\x3c\x74\x06\x1c\xd8\x3b\x5b\x3f\xfa\x6f\x13\xc6",
+ "\x40\xf9\xf5\x5b\xc5\x5d\xa4\x66\xbc\x3d\xc1\xf8\x98\x35\xa6\x40\x94\x57\x2d\xe7\x3d\x64\xed\x66\x46\xa1\xd3\xb6\x67\xbe\x70\xa9",
+ 24 },
+ { GCRY_MD_SHA3_256,
+ "\xaa\xfd\xc9\x24\x3d\x3d\x4a\x09\x65\x58\xa3\x60\xcc\x27\xc8\xd8\x62\xf0\xbe\x73\xdb\x5e\x88\xaa\x55",
+ "\xc6\x4b\xec\xf7\xb7\x5f\xc8\x85\xd5\x85\x39\x24\xf2\xb7\xd3\x7a\xbc\xef\xd3\xda\x12\x6b\xb8\x17\x69\x7e\x1a\x09\x15\x2b\x1e\xbe",
+ 25 },
+ { GCRY_MD_SHA3_256,
+ "\x7b\xc8\x48\x67\xf6\xf9\xe9\xfd\xc3\xe1\x04\x6c\xae\x3a\x52\xc7\x7e\xd4\x85\x86\x0e\xe2\x60\xe3\x0b\x15",
+ "\x57\xd4\x6a\x6b\xc8\xfa\xb3\x36\x01\x53\x8d\xad\x27\xf9\x8c\x66\x44\x30\x32\xcc\x39\x12\x43\x4c\x28\xeb\x88\xd0\xaf\x44\xc5\x2c",
+ 26 },
+ { GCRY_MD_SHA3_256,
+ "\xfa\xc5\x23\x57\x5a\x99\xec\x48\x27\x9a\x7a\x45\x9e\x98\xff\x90\x19\x18\xa4\x75\x03\x43\x27\xef\xb5\x58\x43",
+ "\x7c\x95\x65\x03\xd5\xb4\xdb\xb7\x64\xff\x8e\x66\xfa\x74\xce\x0f\x91\x32\xda\x90\xea\x35\x43\xf6\x69\xc9\xdd\x08\xe4\x13\xe3\x3c",
+ 27 },
+ { GCRY_MD_SHA3_256,
+ "\x0f\x8b\x2d\x8f\xcf\xd9\xd6\x8c\xff\xc1\x7c\xcf\xb1\x17\x70\x9b\x53\xd2\x64\x62\xa3\xf3\x46\xfb\x7c\x79\xb8\x5e",
+ "\x6d\xe1\x64\xa9\x62\x6d\x5a\x4f\x54\xd8\x54\xac\x15\x89\x94\xf3\x5a\x8e\x36\x2e\xcc\x75\x3f\x55\x18\x27\x90\x93\x4a\x2e\x0d\x06",
+ 28 },
+ { GCRY_MD_SHA3_256,
+ "\xa9\x63\xc3\xe8\x95\xff\x5a\x0b\xe4\x82\x44\x00\x51\x8d\x81\x41\x2f\x87\x5f\xa5\x05\x21\xe2\x6e\x85\xea\xc9\x0c\x04",
+ "\xb7\x60\x31\x2b\xd1\xb2\x79\xfc\x67\x24\x79\xd2\x1c\x5e\xd3\x49\xe5\xfe\x96\xf0\x89\x40\x23\x7b\x45\x15\x45\x27\x21\xc4\x9a\x16",
+ 29 },
+ { GCRY_MD_SHA3_256,
+ "\x03\xa1\x86\x88\xb1\x0c\xc0\xed\xf8\x3a\xdf\x0a\x84\x80\x8a\x97\x18\x38\x3c\x40\x70\xc6\xc4\xf2\x95\x09\x86\x99\xac\x2c",
+ "\x94\xfc\x25\x5d\xe4\xef\x19\xc0\xda\x4b\x09\xb2\xe2\xfa\xc2\x1f\x20\x04\x8b\x46\xf1\x7c\x30\x68\x5a\xbe\x40\xd5\xc7\x43\xf3\x75",
+ 30 },
+ { GCRY_MD_SHA3_256,
+ "\x84\xfb\x51\xb5\x17\xdf\x6c\x5a\xcc\xb5\xd0\x22\xf8\xf2\x8d\xa0\x9b\x10\x23\x2d\x42\x32\x0f\xfc\x32\xdb\xec\xc3\x83\x5b\x29",
+ "\x39\xa4\xa0\xff\xc4\x60\x36\x98\xae\x0a\x4f\x3d\x24\xb1\xbc\x42\xac\x7a\x2d\x7d\x92\x3e\x7a\x5d\x60\x24\x53\xe8\x2d\x53\x23\xc5",
+ 31 },
+ { GCRY_MD_SHA3_256,
+ "\x9f\x2f\xcc\x7c\x90\xde\x09\x0d\x6b\x87\xcd\x7e\x97\x18\xc1\xea\x6c\xb2\x11\x18\xfc\x2d\x5d\xe9\xf9\x7e\x5d\xb6\xac\x1e\x9c\x10",
+ "\x2f\x1a\x5f\x71\x59\xe3\x4e\xa1\x9c\xdd\xc7\x0e\xbf\x9b\x81\xf1\xa6\x6d\xb4\x06\x15\xd7\xea\xd3\xcc\x1f\x1b\x95\x4d\x82\xa3\xaf",
+ 32 },
+ { GCRY_MD_SHA3_256,
+ "\xde\x8f\x1b\x3f\xaa\x4b\x70\x40\xed\x45\x63\xc3\xb8\xe5\x98\x25\x31\x78\xe8\x7e\x4d\x0d\xf7\x5e\x4f\xf2\xf2\xde\xdd\x5a\x0b\xe0\x46",
+ "\x1c\x57\xfe\x0e\x38\xcd\x3a\x12\x4e\xaa\x6c\xd8\x7f\x70\xa0\x79\xbc\xcc\x07\x3a\x34\x1e\x8c\x0e\xb1\x97\x6f\xb3\xa3\xf7\xb7\x74",
+ 33 },
+ { GCRY_MD_SHA3_256,
+ "\x62\xf1\x54\xec\x39\x4d\x0b\xc7\x57\xd0\x45\xc7\x98\xc8\xb8\x7a\x00\xe0\x65\x5d\x04\x81\xa7\xd2\xd9\xfb\x58\xd9\x3a\xed\xc6\x76\xb5\xa0",
+ "\xa9\x05\x60\x3b\x18\x6e\xf4\xf2\xd5\xb2\xd1\xbc\xfd\xa5\x04\xc6\x8e\xd5\xeb\x9b\x0c\x7b\x7e\xa2\xa0\x01\x57\x5f\x5a\xa6\x9e\x68",
+ 34 },
+ { GCRY_MD_SHA3_256,
+ "\xb2\xdc\xfe\x9f\xf1\x9e\x2b\x23\xce\x7d\xa2\xa4\x20\x7d\x3e\x5e\xc7\xc6\x11\x2a\x8a\x22\xae\xc9\x67\x5a\x88\x63\x78\xe1\x4e\x5b\xfb\xad\x4e",
+ "\xff\xfd\x39\xf7\xc4\x51\x78\x8e\xb0\x31\x6f\x42\x9e\xa0\xa7\xc0\xac\x80\x91\x65\x7a\xca\x28\xf1\x56\x0e\xd5\x77\x5e\x8c\x4c\x12",
+ 35 },
+ { GCRY_MD_SHA3_256,
+ "\x47\xf5\x69\x7a\xc8\xc3\x14\x09\xc0\x86\x88\x27\x34\x7a\x61\x3a\x35\x62\x04\x1c\x63\x3c\xf1\xf1\xf8\x68\x65\xa5\x76\xe0\x28\x35\xed\x2c\x24\x92",
+ "\x6f\x55\xbe\xcd\x16\x8e\x09\x39\xba\x2f\xa0\x90\x25\x7b\x17\x27\xfc\x66\x49\x1a\x44\x49\x32\x79\xa5\xbe\xac\xb9\xe3\x43\x53\x24",
+ 36 },
+ { GCRY_MD_SHA3_256,
+ "\x51\x2a\x6d\x29\x2e\x67\xec\xb2\xfe\x48\x6b\xfe\x92\x66\x09\x53\xa7\x54\x84\xff\x4c\x4f\x2e\xca\x2b\x0a\xf0\xed\xcd\xd4\x33\x9c\x6b\x2e\xe4\xe5\x42",
+ "\x84\x64\x9b\xff\xcd\x48\x52\x7b\x92\x88\xe8\xda\x5f\x52\xfb\xab\x26\x04\xdc\x5a\x91\xc4\xb0\xb8\x7d\x47\x7d\xbd\x7b\x40\xb6\xae",
+ 37 },
+ { GCRY_MD_SHA3_256,
+ "\x97\x3c\xf2\xb4\xdc\xf0\xbf\xa8\x72\xb4\x11\x94\xcb\x05\xbb\x4e\x16\x76\x0a\x18\x40\xd8\x34\x33\x01\x80\x25\x76\x19\x7e\xc1\x9e\x2a\x14\x93\xd8\xf4\xfb",
+ "\xd4\x05\x5b\x4e\x3e\x2a\xea\x1c\x67\xcc\x99\xfd\x40\x9d\x57\x4e\x53\xe1\xe2\x96\xcf\x9e\xef\x73\xc4\x72\xab\x92\xa6\xcb\x66\x09",
+ 38 },
+ { GCRY_MD_SHA3_256,
+ "\x80\xbe\xeb\xcd\x2e\x3f\x8a\x94\x51\xd4\x49\x99\x61\xc9\x73\x1a\xe6\x67\xcd\xc2\x4e\xa0\x20\xce\x3b\x9a\xa4\xbb\xc0\xa7\xf7\x9e\x30\xa9\x34\x46\x7d\xa4\xb0",
+ "\x56\x94\xca\x2f\x3b\x99\x62\x22\x6a\x87\x16\x3a\xb3\x83\x25\xbc\xdc\x89\x8a\x73\x2d\xfe\xb2\xc3\x6d\xb4\xeb\x88\x61\x6b\x87\x41",
+ 39 },
+ { GCRY_MD_SHA3_256,
+ "\x7a\xba\xa1\x2e\xc2\xa7\x34\x76\x74\xe4\x44\x14\x0a\xe0\xfb\x65\x9d\x08\xe1\xc6\x6d\xec\xd8\xd6\xea\xe9\x25\xfa\x45\x1d\x65\xf3\xc0\x30\x8e\x29\x44\x6b\x8e\xd3",
+ "\x8c\xf2\x87\xad\x03\xab\x4a\x74\x08\x66\x20\xcf\xa4\xcc\xe7\x4f\x48\xfa\x5c\xdb\x15\xec\x02\xb1\xf7\x21\x73\x6a\x4f\x84\x9e\x60",
+ 40 },
+ { GCRY_MD_SHA3_256,
+ "\xc8\x8d\xee\x99\x27\x67\x9b\x8a\xf4\x22\xab\xcb\xac\xf2\x83\xb9\x04\xff\x31\xe1\xca\xc5\x8c\x78\x19\x80\x9f\x65\xd5\x80\x7d\x46\x72\x3b\x20\xf6\x7b\xa6\x10\xc2\xb7",
+ "\xc5\xd5\xaf\x22\xa4\xdf\x9a\xcd\x0c\x05\x6f\xa3\x0d\x8e\x24\x0b\x67\x9a\x20\xd4\xd2\x63\x02\x60\xf7\x79\xff\x81\x5c\xa8\x2d\x7d",
+ 41 },
+ { GCRY_MD_SHA3_256,
+ "\x01\xe4\x3f\xe3\x50\xfc\xec\x45\x0e\xc9\xb1\x02\x05\x3e\x6b\x5d\x56\xe0\x98\x96\xe0\xdd\xd9\x07\x4f\xe1\x38\xe6\x03\x82\x10\x27\x0c\x83\x4c\xe6\xea\xdc\x2b\xb8\x6b\xf6",
+ "\x0a\xc7\x52\x79\xad\xff\x65\x66\x04\x64\x55\x0a\x28\x3f\xec\xd4\xe0\x61\x0d\x88\xf3\x55\x74\xc3\xd7\xac\x5d\x22\x26\x2a\x2f\xe8",
+ 42 },
+ { GCRY_MD_SHA3_256,
+ "\x33\x70\x23\x37\x0a\x48\xb6\x2e\xe4\x35\x46\xf1\x7c\x4e\xf2\xbf\x8d\x7e\xcd\x1d\x49\xf9\x0b\xab\x60\x4b\x83\x9c\x2e\x6e\x5b\xd2\x15\x40\xd2\x9b\xa2\x7a\xb8\xe3\x09\xa4\xb7",
+ "\x81\x91\x7a\xe2\x90\xdb\xba\x17\x28\x9a\x8a\x67\xe5\xc2\xe8\xb1\x2d\x3d\xde\x0e\xfe\x9f\x99\x01\x98\xa1\x76\x3f\xf4\xf3\xdd\xa7",
+ 43 },
+ { GCRY_MD_SHA3_256,
+ "\x68\x92\x54\x0f\x96\x4c\x8c\x74\xbd\x2d\xb0\x2c\x0a\xd8\x84\x51\x0c\xb3\x8a\xfd\x44\x38\xaf\x31\xfc\x91\x27\x56\xf3\xef\xec\x6b\x32\xb5\x8e\xbc\x38\xfc\x2a\x6b\x91\x35\x96\xa8",
+ "\x13\x8e\x75\xe7\x2f\xdd\xd9\x27\xe5\x91\x31\x5a\xf8\xd3\xab\xa2\x80\xef\xa3\x62\x30\xa3\x30\x9a\x97\xbc\xde\x5a\x78\xc3\x15\x89",
+ 44 },
+ { GCRY_MD_SHA3_256,
+ "\xf5\x96\x1d\xfd\x2b\x1f\xff\xfd\xa4\xff\xbf\x30\x56\x0c\x16\x5b\xfe\xda\xb8\xce\x0b\xe5\x25\x84\x5d\xeb\x8d\xc6\x10\x04\xb7\xdb\x38\x46\x72\x05\xf5\xdc\xfb\x34\xa2\xac\xfe\x96\xc0",
+ "\x21\xbc\xda\xd3\xfe\xf3\xe5\xb8\x59\xcb\x09\x12\xa2\x99\x1e\xfa\x66\x1b\xad\x81\x27\x47\x29\x2e\xf0\xf7\x9a\x8f\xcc\x6b\x4e\x98",
+ 45 },
+ { GCRY_MD_SHA3_256,
+ "\xca\x06\x1a\x2e\xb6\xce\xed\x88\x81\xce\x20\x57\x17\x2d\x86\x9d\x73\xa1\x95\x1e\x63\xd5\x72\x61\x38\x4b\x80\xce\xb5\x45\x1e\x77\xb0\x6c\xf0\xf5\xa0\xea\x15\xca\x90\x7e\xe1\xc2\x7e\xba",
+ "\x8d\x6f\xd9\xc5\x59\xb0\xb4\x94\x8f\x91\x33\x79\x16\x08\x4c\x00\x82\xa1\x6a\x07\x55\xb0\xa0\x08\x11\x09\x6e\x97\x3e\x48\xb3\xc8",
+ 46 },
+ { GCRY_MD_SHA3_256,
+ "\x17\x43\xa7\x72\x51\xd6\x92\x42\x75\x0c\x4f\x11\x40\x53\x2c\xd3\xc3\x3f\x9b\x5c\xcd\xf7\x51\x4e\x85\x84\xd4\xa5\xf9\xfb\xd7\x30\xbc\xf8\x4d\x0d\x47\x26\x36\x4b\x9b\xf9\x5a\xb2\x51\xd9\xbb",
+ "\x1d\xd2\x3a\xe7\xaa\xdd\x61\xe7\x12\xbd\xd8\x2b\xd6\x0a\x70\xdd\x9d\x66\xc9\xfd\x79\xdb\xfd\x86\x69\xe3\xea\xab\xf7\x90\x1c\xdc",
+ 47 },
+ { GCRY_MD_SHA3_256,
+ "\xd8\xfa\xba\x1f\x51\x94\xc4\xdb\x5f\x17\x6f\xab\xff\xf8\x56\x92\x4e\xf6\x27\xa3\x7c\xd0\x8c\xf5\x56\x08\xbb\xa8\xf1\xe3\x24\xd7\xc7\xf1\x57\x29\x8e\xab\xc4\xdc\xe7\xd8\x9c\xe5\x16\x24\x99\xf9",
+ "\x34\xf8\x60\x7e\xc1\x0c\x09\x2c\x1b\xa0\xb6\x56\x5c\xe6\x19\x70\x62\xc4\xe1\xa3\x5a\x8e\x8c\x72\x3e\x48\xa2\xd2\x41\x6c\x37\x90",
+ 48 },
+ { GCRY_MD_SHA3_256,
+ "\xbe\x96\x84\xbe\x70\x34\x08\x60\x37\x3c\x9c\x48\x2b\xa5\x17\xe8\x99\xfc\x81\xba\xaa\x12\xe5\xc6\xd7\x72\x79\x75\xd1\xd4\x1b\xa8\xbe\xf7\x88\xcd\xb5\xcf\x46\x06\xc9\xc1\xc7\xf6\x1a\xed\x59\xf9\x7d",
+ "\x19\xa8\x57\x7f\xc9\x0f\xae\x5d\x6a\x6b\x2e\x0c\x1f\xf1\x55\x51\x55\x02\xcf\xa1\x75\x70\x29\xc0\x9b\xeb\xbf\xa2\x63\xd9\xa3\x63",
+ 49 },
+ { GCRY_MD_SHA3_256,
+ "\x7e\x15\xd2\xb9\xea\x74\xca\x60\xf6\x6c\x8d\xfa\xb3\x77\xd9\x19\x8b\x7b\x16\xde\xb6\xa1\xba\x0e\xa3\xc7\xee\x20\x42\xf8\x9d\x37\x86\xe7\x79\xcf\x05\x3c\x77\x78\x5a\xa9\xe6\x92\xf8\x21\xf1\x4a\x7f\x51",
+ "\x9d\x9d\xbb\x4c\xe7\xd0\x1d\x00\x9e\x72\xa6\x60\x51\xac\xc1\x68\x05\xe4\x9f\x59\x8c\xbe\x43\x0c\x5d\x4c\x22\xa8\x81\xa6\x4b\x3f",
+ 50 },
+ { GCRY_MD_SHA3_256,
+ "\x9a\x21\x9b\xe4\x37\x13\xbd\x57\x80\x15\xe9\xfd\xa6\x6c\x0f\x2d\x83\xca\xc5\x63\xb7\x76\xab\x9f\x38\xf3\xe4\xf7\xef\x22\x9c\xb4\x43\x30\x4f\xba\x40\x1e\xfb\x2b\xdb\xd7\xec\xe9\x39\x10\x22\x98\x65\x1c\x86",
+ "\x13\xf0\xd9\x51\xb6\x44\x81\x13\x54\x66\xcf\xcc\xbe\x52\x41\x8c\xc1\xd0\x3f\xb1\x6b\x5b\x69\x6c\x35\xd7\x24\xf6\xf5\x5c\xbb\x6d",
+ 51 },
+ { GCRY_MD_SHA3_256,
+ "\xc8\xf2\xb6\x93\xbd\x0d\x75\xef\x99\xca\xeb\xdc\x22\xad\xf4\x08\x8a\x95\xa3\x54\x2f\x63\x72\x03\xe2\x83\xbb\xc3\x26\x87\x80\xe7\x87\xd6\x8d\x28\xcc\x38\x97\x45\x2f\x6a\x22\xaa\x85\x73\xcc\xeb\xf2\x45\x97\x2a",
+ "\xfb\x2f\xe7\xb0\x0b\x75\xc4\x23\x05\xcf\x31\xde\x14\xd9\x8f\x90\x4e\x8c\x46\xdc\x57\xbb\x6f\x94\xc2\x82\xca\x8c\x13\xdc\x45\xdb",
+ 52 },
+ { GCRY_MD_SHA3_256,
+ "\xec\x0f\x99\x71\x10\x16\xc6\xa2\xa0\x7a\xd8\x0d\x16\x42\x75\x06\xce\x6f\x44\x10\x59\xfd\x26\x94\x42\xba\xaa\x28\xc6\xca\x03\x7b\x22\xee\xac\x49\xd5\xd8\x94\xc0\xbf\x66\x21\x9f\x2c\x08\xe9\xd0\xe8\xab\x21\xde\x52",
+ "\xd5\x4c\xbf\x7d\x5c\x80\xae\x11\xa0\xd0\xba\xd4\xe9\x5a\xb1\x8b\x5f\x07\xc9\x70\x62\x1f\x39\x36\x44\x7a\x48\xee\xf8\x18\xd0\x6e",
+ 53 },
+ { GCRY_MD_SHA3_256,
+ "\x0d\xc4\x51\x81\x33\x7c\xa3\x2a\x82\x22\xfe\x7a\x3b\xf4\x2f\xc9\xf8\x97\x44\x25\x9c\xff\x65\x35\x04\xd6\x05\x1f\xe8\x4b\x1a\x7f\xfd\x20\xcb\x47\xd4\x69\x6c\xe2\x12\xa6\x86\xbb\x9b\xe9\xa8\xab\x1c\x69\x7b\x6d\x6a\x33",
+ "\xff\x05\x0a\x45\xad\xee\xf4\xcf\xc7\xd9\x64\x10\x2b\xa8\x77\xc8\x03\x20\xa3\x77\x94\x89\x3e\x68\x65\x96\x5e\xc2\x54\x7c\xd4\xc9",
+ 54 },
+ { GCRY_MD_SHA3_256,
+ "\xde\x28\x6b\xa4\x20\x6e\x8b\x00\x57\x14\xf8\x0f\xb1\xcd\xfa\xeb\xde\x91\xd2\x9f\x84\x60\x3e\x4a\x3e\xbc\x04\x68\x6f\x99\xa4\x6c\x9e\x88\x0b\x96\xc5\x74\x82\x55\x82\xe8\x81\x2a\x26\xe5\xa8\x57\xff\xc6\x57\x9f\x63\x74\x2f",
+ "\x1b\xc1\xbc\xc7\x0f\x63\x89\x58\xdb\x10\x06\xaf\x37\xb0\x2e\xbd\x89\x54\xec\x59\xb3\xac\xba\xd1\x2e\xac\xed\xbc\x5b\x21\xe9\x08",
+ 55 },
+ { GCRY_MD_SHA3_256,
+ "\xee\xbc\xc1\x80\x57\x25\x2c\xbf\x3f\x9c\x07\x0f\x1a\x73\x21\x33\x56\xd5\xd4\xbc\x19\xac\x2a\x41\x1e\xc8\xcd\xee\xe7\xa5\x71\xe2\xe2\x0e\xaf\x61\xfd\x0c\x33\xa0\xff\xeb\x29\x7d\xdb\x77\xa9\x7f\x0a\x41\x53\x47\xdb\x66\xbc\xaf",
+ "\xf7\xbd\xe2\x39\xad\x08\x7a\xa7\xda\xbe\x42\xcc\x4d\x3c\x49\x38\x0a\x02\x6c\xd2\x39\xa7\xfa\xaf\x34\xa2\x23\x34\x69\xa4\x4a\x4d",
+ 56 },
+ { GCRY_MD_SHA3_256,
+ "\x41\x6b\x5c\xdc\x9f\xe9\x51\xbd\x36\x1b\xd7\xab\xfc\x12\x0a\x50\x54\x75\x8e\xba\x88\xfd\xd6\x8f\xd8\x4e\x39\xd3\xb0\x9a\xc2\x54\x97\xd3\x6b\x43\xcb\xe7\xb8\x5a\x6a\x3c\xeb\xda\x8d\xb4\xe5\x54\x9c\x3e\xe5\x1b\xb6\xfc\xb6\xac\x1e",
+ "\xef\x84\x5a\xac\x2a\xaf\x0a\x79\x31\x08\x20\x4f\xf3\x80\xe0\xa3\x0f\x25\x58\xe7\xac\xde\x45\x31\xab\x22\xf8\xec\x79\xe2\x6a\x69",
+ 57 },
+ { GCRY_MD_SHA3_256,
+ "\x5c\x5f\xaf\x66\xf3\x2e\x0f\x83\x11\xc3\x2e\x8d\xa8\x28\x4a\x4e\xd6\x08\x91\xa5\xa7\xe5\x0f\xb2\x95\x6b\x3c\xba\xa7\x9f\xc6\x6c\xa3\x76\x46\x0e\x10\x04\x15\x40\x1f\xc2\xb8\x51\x8c\x64\x50\x2f\x18\x7e\xa1\x4b\xfc\x95\x03\x75\x97\x05",
+ "\x26\xdb\x51\x4e\x01\xe0\x34\xc6\x78\xb6\x36\xd4\x0b\xa3\x67\xda\x2f\x37\xf6\x70\x78\xbb\x57\x6f\xf2\xb8\x55\x9b\x35\x17\x48\x4d",
+ 58 },
+ { GCRY_MD_SHA3_256,
+ "\x71\x67\xe1\xe0\x2b\xe1\xa7\xca\x69\xd7\x88\x66\x6f\x82\x3a\xe4\xee\xf3\x92\x71\xf3\xc2\x6a\x5c\xf7\xce\xe0\x5b\xca\x83\x16\x10\x66\xdc\x2e\x21\x7b\x33\x0d\xf8\x21\x10\x37\x99\xdf\x6d\x74\x81\x0e\xed\x36\x3a\xdc\x4a\xb9\x9f\x36\x04\x6a",
+ "\x5d\xbd\x4b\x55\x84\x63\x19\x62\x11\x46\x5c\x1f\xc3\x24\x01\xfc\x2d\x8e\x41\xeb\xc5\xe6\xba\xdd\x1d\x8f\x7c\x4f\x09\x0f\x72\x8f",
+ 59 },
+ { GCRY_MD_SHA3_256,
+ "\x2f\xda\x31\x1d\xbb\xa2\x73\x21\xc5\x32\x95\x10\xfa\xe6\x94\x8f\x03\x21\x0b\x76\xd4\x3e\x74\x48\xd1\x68\x9a\x06\x38\x77\xb6\xd1\x4c\x4f\x6d\x0e\xaa\x96\xc1\x50\x05\x13\x71\xf7\xdd\x8a\x41\x19\xf7\xda\x5c\x48\x3c\xc3\xe6\x72\x3c\x01\xfb\x7d",
+ "\x35\x5c\x79\xfd\x6e\x6f\xa8\x8e\xd4\x02\xb6\x97\x9f\xde\x1e\xd8\x05\x49\x8a\xbe\xb1\x01\xf4\x23\x1b\x5d\x64\xd1\x43\x9d\x55\x2d",
+ 60 },
+ { GCRY_MD_SHA3_256,
+ "\x95\xd1\x47\x4a\x5a\xab\x5d\x24\x22\xac\xa6\xe4\x81\x18\x78\x33\xa6\x21\x2b\xd2\xd0\xf9\x14\x51\xa6\x7d\xd7\x86\xdf\xc9\x1d\xfe\xd5\x1b\x35\xf4\x7e\x1d\xeb\x8a\x8a\xb4\xb9\xcb\x67\xb7\x01\x79\xcc\x26\xf5\x53\xae\x7b\x56\x99\x69\xce\x15\x1b\x8d",
+ "\x3d\x9c\x9b\xf0\x9d\x88\x21\x1c\x7e\x00\x56\x11\x2d\x07\x3e\xe8\x5d\x00\xac\xaa\x4d\xa7\xa6\x68\xfa\x01\x7b\x32\x73\xcd\x4d\x4b",
+ 61 },
+ { GCRY_MD_SHA3_256,
+ "\xc7\x1b\xd7\x94\x1f\x41\xdf\x04\x4a\x29\x27\xa8\xff\x55\xb4\xb4\x67\xc3\x3d\x08\x9f\x09\x88\xaa\x25\x3d\x29\x4a\xdd\xbd\xb3\x25\x30\xc0\xd4\x20\x8b\x10\xd9\x95\x98\x23\xf0\xc0\xf0\x73\x46\x84\x00\x6d\xf7\x9f\x70\x99\x87\x0f\x6b\xf5\x32\x11\xa8\x8d",
+ "\x67\x98\x0d\x28\xe2\xe6\x58\xe7\xa2\x4a\x25\x93\xa2\x81\x67\xa1\x3d\x90\x7d\x06\xf4\x77\x29\xd4\x7c\xa4\xfe\x17\x72\xf8\xb3\xdf",
+ 62 },
+ { GCRY_MD_SHA3_256,
+ "\xf5\x7c\x64\x00\x6d\x9e\xa7\x61\x89\x2e\x14\x5c\x99\xdf\x1b\x24\x64\x08\x83\xda\x79\xd9\xed\x52\x62\x85\x9d\xcd\xa8\xc3\xc3\x2e\x05\xb0\x3d\x98\x4f\x1a\xb4\xa2\x30\x24\x2a\xb6\xb7\x8d\x36\x8d\xc5\xaa\xa1\xe6\xd3\x49\x8d\x53\x37\x1e\x84\xb0\xc1\xd4\xba",
+ "\xa8\xdf\x6b\x76\xdf\x41\x99\x4f\x75\x93\xf1\xa8\x19\x67\xe7\x7e\xe1\x80\xe3\x11\x83\xd1\xc4\xa5\x69\xdb\x85\x4e\x61\xe9\x9b\x05",
+ 63 },
+ { GCRY_MD_SHA3_256,
+ "\xe9\x26\xae\x8b\x0a\xf6\xe5\x31\x76\xdb\xff\xcc\x2a\x6b\x88\xc6\xbd\x76\x5f\x93\x9d\x3d\x17\x8a\x9b\xde\x9e\xf3\xaa\x13\x1c\x61\xe3\x1c\x1e\x42\xcd\xfa\xf4\xb4\xdc\xde\x57\x9a\x37\xe1\x50\xef\xbe\xf5\x55\x5b\x4c\x1c\xb4\x04\x39\xd8\x35\xa7\x24\xe2\xfa\xe7",
+ "\x27\xa6\x44\x1e\xe9\x39\xb4\x6e\x2c\x37\x8d\x7a\xfe\xb0\xe8\x91\xc4\x7a\x28\x12\x0e\x48\x8e\xff\x0a\xb7\x1a\xf0\x87\x88\xce\xb3",
+ 64 },
+ { GCRY_MD_SHA3_256,
+ "\x16\xe8\xb3\xd8\xf9\x88\xe9\xbb\x04\xde\x9c\x96\xf2\x62\x78\x11\xc9\x73\xce\x4a\x52\x96\xb4\x77\x2c\xa3\xee\xfe\xb8\x0a\x65\x2b\xdf\x21\xf5\x0d\xf7\x9f\x32\xdb\x23\xf9\xf7\x3d\x39\x3b\x2d\x57\xd9\xa0\x29\x7f\x7a\x2f\x2e\x79\xcf\xda\x39\xfa\x39\x3d\xf1\xac\x00",
+ "\xc4\xbb\x06\x73\x83\x00\x2d\xb4\x4c\xa7\x73\x91\x8b\xb7\x41\x04\xb6\x04\xa5\x83\xe1\x2b\x06\xbe\x56\xc2\x70\xf8\xb4\x35\x12\xf2",
+ 65 },
+ { GCRY_MD_SHA3_256,
+ "\xfc\x42\x4e\xeb\x27\xc1\x8a\x11\xc0\x1f\x39\xc5\x55\xd8\xb7\x8a\x80\x5b\x88\xdb\xa1\xdc\x2a\x42\xed\x5e\x2c\x0e\xc7\x37\xff\x68\xb2\x45\x6d\x80\xeb\x85\xe1\x17\x14\xfa\x3f\x8e\xab\xfb\x90\x6d\x3c\x17\x96\x4c\xb4\xf5\xe7\x6b\x29\xc1\x76\x5d\xb0\x3d\x91\xbe\x37\xfc",
+ "\xae\x77\x39\x15\xca\x64\x2d\x80\x41\x33\x30\xc9\xe0\xee\x9b\xd0\x66\x53\xc0\x02\x3c\x5c\x02\x77\x10\x0f\x3b\x15\x26\xea\xa5\x1d",
+ 66 },
+ { GCRY_MD_SHA3_256,
+ "\xab\xe3\x47\x2b\x54\xe7\x27\x34\xbd\xba\x7d\x91\x58\x73\x64\x64\x25\x1c\x4f\x21\xb3\x3f\xbb\xc9\x2d\x7f\xac\x9a\x35\xc4\xe3\x32\x2f\xf0\x1d\x23\x80\xcb\xaa\x4e\xf8\xfb\x07\xd2\x1a\x21\x28\xb7\xb9\xf5\xb6\xd9\xf3\x4e\x13\xf3\x9c\x7f\xfc\x2e\x72\xe4\x78\x88\x59\x9b\xa5",
+ "\x1c\xf9\xd6\xce\x9c\xb6\x58\x55\x6b\x76\xcd\x7e\xba\x3e\x51\x39\x36\x99\xad\x50\x0b\x1a\xb3\xf5\x61\x72\x74\x8d\xb7\xf5\x96\x67",
+ 67 },
+ { GCRY_MD_SHA3_256,
+ "\x36\xf9\xf0\xa6\x5f\x2c\xa4\x98\xd7\x39\xb9\x44\xd6\xef\xf3\xda\x5e\xbb\xa5\x7e\x7d\x9c\x41\x59\x8a\x2b\x0e\x43\x80\xf3\xcf\x4b\x47\x9e\xc2\x34\x8d\x01\x5f\xfe\x62\x56\x27\x35\x11\x15\x4a\xfc\xf3\xb4\xb4\xbf\x09\xd6\xc4\x74\x4f\xdd\x0f\x62\xd7\x50\x79\xd4\x40\x70\x6b\x05",
+ "\x8d\x60\xe8\x89\xe2\xb1\x02\x0d\xad\x4b\x52\x33\x01\xf5\xf6\xbb\xab\x6c\x78\x1a\xf2\x76\x08\x5a\xf6\x76\x55\x46\xfc\xfb\x95\xac",
+ 68 },
+ { GCRY_MD_SHA3_256,
+ "\xab\xc8\x77\x63\xca\xe1\xca\x98\xbd\x8c\x5b\x82\xca\xba\x54\xac\x83\x28\x6f\x87\xe9\x61\x01\x28\xae\x4d\xe6\x8a\xc9\x5d\xf5\xe3\x29\xc3\x60\x71\x7b\xd3\x49\xf2\x6b\x87\x25\x28\x49\x2c\xa7\xc9\x4c\x2c\x1e\x1e\xf5\x6b\x74\xdb\xb6\x5c\x2a\xc3\x51\x98\x1f\xdb\x31\xd0\x6c\x77\xa4",
+ "\xdd\x4f\xf4\xb5\x30\x55\x2f\x48\xaf\x9a\x75\x30\xa6\x46\x48\x19\xed\x1a\x5b\x73\x30\x84\xf7\x09\xe4\x1d\xaf\x1a\xcb\x35\xec\xfd",
+ 69 },
+ { GCRY_MD_SHA3_256,
+ "\x94\xf7\xca\x8e\x1a\x54\x23\x4c\x6d\x53\xcc\x73\x4b\xb3\xd3\x15\x0c\x8b\xa8\xc5\xf8\x80\xea\xb8\xd2\x5f\xed\x13\x79\x3a\x97\x01\xeb\xe3\x20\x50\x92\x86\xfd\x8e\x42\x2e\x93\x1d\x99\xc9\x8d\xa4\xdf\x7e\x70\xae\x44\x7b\xab\x8c\xff\xd9\x23\x82\xd8\xa7\x77\x60\xa2\x59\xfc\x4f\xbd\x72",
+ "\x7a\xc8\xd4\xbb\x53\xfc\x43\x4d\xd8\x71\x2d\xae\xfe\xb4\x74\x66\x8f\x54\x14\x18\xe6\xf6\x17\xdb\xa5\x23\xd8\x39\x2e\xb0\x76\x6e",
+ 70 },
+ { GCRY_MD_SHA3_256,
+ "\x13\xbd\x28\x11\xf6\xed\x2b\x6f\x04\xff\x38\x95\xac\xee\xd7\xbe\xf8\xdc\xd4\x5e\xb1\x21\x79\x1b\xc1\x94\xa0\xf8\x06\x20\x6b\xff\xc3\xb9\x28\x1c\x2b\x30\x8b\x1a\x72\x9c\xe0\x08\x11\x9d\xd3\x06\x6e\x93\x78\xac\xdc\xc5\x0a\x98\xa8\x2e\x20\x73\x88\x00\xb6\xcd\xdb\xe5\xfe\x96\x94\xad\x6d",
+ "\xf7\xb0\xe1\x5a\x63\x23\x2a\x2b\x80\x0b\x23\xb3\x11\xd3\x57\x61\x7d\xdf\xd1\x29\x3e\x1f\xfe\x3f\x77\x26\x92\xad\xe3\x42\x71\x52",
+ 71 },
+ { GCRY_MD_SHA3_256,
+ "\x1e\xed\x9c\xba\x17\x9a\x00\x9e\xc2\xec\x55\x08\x77\x3d\xd3\x05\x47\x7c\xa1\x17\xe6\xd5\x69\xe6\x6b\x5f\x64\xc6\xbc\x64\x80\x1c\xe2\x5a\x84\x24\xce\x4a\x26\xd5\x75\xb8\xa6\xfb\x10\xea\xd3\xfd\x19\x92\xed\xdd\xee\xc2\xeb\xe7\x15\x0d\xc9\x8f\x63\xad\xc3\x23\x7e\xf5\x7b\x91\x39\x7a\xa8\xa7",
+ "\xb3\xd0\x5a\xf7\xe8\xc4\x06\xa7\xc2\x70\x92\x23\x79\x1d\x3f\x5f\x4b\x31\x29\x32\x99\x93\x22\x00\x53\xa3\x62\x93\xac\x2b\x0e\x06",
+ 72 },
+ { GCRY_MD_SHA3_256,
+ "\xba\x5b\x67\xb5\xec\x3a\x3f\xfa\xe2\xc1\x9d\xd8\x17\x6a\x2e\xf7\x5c\x0c\xd9\x03\x72\x5d\x45\xc9\xcb\x70\x09\xa9\x00\xc0\xb0\xca\x7a\x29\x67\xa9\x5a\xe6\x82\x69\xa6\xdb\xf8\x46\x6c\x7b\x68\x44\xa1\xd6\x08\xac\x66\x1f\x7e\xff\x00\x53\x8e\x32\x3d\xb5\xf2\xc6\x44\xb7\x8b\x2d\x48\xde\x1a\x08\xaa",
+ "\x6c\x47\xe2\xea\x4b\xa2\x9e\x17\x79\x2d\xef\xc4\xb7\x07\x75\x4c\x46\x64\xbd\xe1\x51\x68\xa5\x10\x0b\xf8\x81\xec\x7c\x02\xb2\x58",
+ 73 },
+ { GCRY_MD_SHA3_256,
+ "\x0e\xfa\x26\xac\x56\x73\x16\x7d\xca\xca\xb8\x60\x93\x2e\xd6\x12\xf6\x5f\xf4\x9b\x80\xfa\x9a\xe6\x54\x65\xe5\x54\x2c\xb6\x20\x75\xdf\x1c\x5a\xe5\x4f\xba\x4d\xb8\x07\xbe\x25\xb0\x70\x03\x3e\xfa\x22\x3b\xdd\x5b\x1d\x3c\x94\xc6\xe1\x90\x9c\x02\xb6\x20\xd4\xb1\xb3\xa6\xc9\xfe\xd2\x4d\x70\x74\x96\x04",
+ "\x82\xa6\x6b\xed\x66\x8d\xcc\x14\xaf\x12\xc1\x4c\x97\x6c\xe6\x50\x04\x9e\x9d\x1d\x99\x69\xb8\x3d\x1d\xd3\xb6\xf1\xc0\x7d\x25\x2b",
+ 74 },
+ { GCRY_MD_SHA3_256,
+ "\xbb\xfd\x93\x3d\x1f\xd7\xbf\x59\x4a\xc7\xf4\x35\x27\x7d\xc1\x7d\x8d\x5a\x5b\x8e\x4d\x13\xd9\x6d\x2f\x64\xe7\x71\xab\xbd\x51\xa5\xa8\xae\xa7\x41\xbe\xcc\xbd\xdb\x17\x7b\xce\xa0\x52\x43\xeb\xd0\x03\xcf\xde\xae\x87\x7c\xca\x4d\xa9\x46\x05\xb6\x76\x91\x91\x9d\x8b\x03\x3f\x77\xd3\x84\xca\x01\x59\x3c\x1b",
+ "\x2f\x21\xd0\x7d\x7b\x10\x68\x3b\x9a\xc7\xa6\x3e\x9f\xcc\x70\xcf\x9f\x88\x7c\xb9\x05\xf9\xbf\xf5\x33\x25\x51\x28\x8b\x28\x85\x24",
+ 75 },
+ { GCRY_MD_SHA3_256,
+ "\x90\x07\x89\x99\xfd\x3c\x35\xb8\xaf\xbf\x40\x66\xcb\xde\x33\x58\x91\x36\x5f\x0f\xc7\x5c\x12\x86\xcd\xd8\x8f\xa5\x1f\xab\x94\xf9\xb8\xde\xf7\xc9\xac\x58\x2a\x5d\xbc\xd9\x58\x17\xaf\xb7\xd1\xb4\x8f\x63\x70\x4e\x19\xc2\xba\xa4\xdf\x34\x7f\x48\xd4\xa6\xd6\x03\x01\x3c\x23\xf1\xe9\x61\x1d\x59\x5e\xba\xc3\x7c",
+ "\x80\x20\x2f\x01\xe7\x14\x0d\xb4\xfe\xe4\x90\xdc\xc5\x0a\xfa\xfd\xf6\xa4\x8c\xa3\x3d\x36\x2c\x78\x75\xb8\xe8\xdb\x9c\x9d\x06\x55",
+ 76 },
+ { GCRY_MD_SHA3_256,
+ "\x64\x10\x5e\xca\x86\x35\x15\xc2\x0e\x7c\xfb\xaa\x0a\x0b\x88\x09\x04\x61\x64\xf3\x74\xd6\x91\xcd\xbd\x65\x08\xaa\xab\xc1\x81\x9f\x9a\xc8\x4b\x52\xba\xfc\x1b\x0f\xe7\xcd\xdb\xc5\x54\xb6\x08\xc0\x1c\x89\x04\xc6\x69\xd8\xdb\x31\x6a\x09\x53\xa4\xc6\x8e\xce\x32\x4e\xc5\xa4\x9f\xfd\xb5\x9a\x1b\xd6\xa2\x92\xaa\x0e",
+ "\xb2\x33\x0a\x18\x90\x47\xe3\x11\x74\x79\xa2\xf2\x0b\x34\x07\xa7\xd1\x19\xe4\xad\x43\x1f\xe0\x6f\xf1\xff\x2a\x10\x6f\x2a\xb3\xa2",
+ 77 },
+ { GCRY_MD_SHA3_256,
+ "\xd4\x65\x4b\xe2\x88\xb9\xf3\xb7\x11\xc2\xd0\x20\x15\x97\x8a\x8c\xc5\x74\x71\xd5\x68\x0a\x09\x2a\xa5\x34\xf7\x37\x2c\x71\xce\xaa\xb7\x25\xa3\x83\xc4\xfc\xf4\xd8\xde\xaa\x57\xfc\xa3\xce\x05\x6f\x31\x29\x61\xec\xcf\x9b\x86\xf1\x49\x81\xba\x5b\xed\x6a\xb5\xb4\x49\x8e\x1f\x6c\x82\xc6\xca\xe6\xfc\x14\x84\x5b\x3c\x8a",
+ "\xbb\x9b\x9b\xb6\x85\xc2\x41\xf8\xd6\x3f\xdb\xf0\xdb\xaa\xbc\xef\x70\x75\xad\xd7\xba\x40\x5a\x2f\xff\xe7\xad\x5b\x23\xe0\x21\xc7",
+ 78 },
+ { GCRY_MD_SHA3_256,
+ "\x12\xd9\x39\x48\x88\x30\x5a\xc9\x6e\x65\xf2\xbf\x0e\x1b\x18\xc2\x9c\x90\xfe\x9d\x71\x4d\xd5\x9f\x65\x1f\x52\xb8\x8b\x30\x08\xc5\x88\x43\x55\x48\x06\x6e\xa2\xfc\x4c\x10\x11\x18\xc9\x1f\x32\x55\x62\x24\xa5\x40\xde\x6e\xfd\xdb\xca\x29\x6e\xf1\xfb\x00\x34\x1f\x5b\x01\xfe\xcf\xc1\x46\xbd\xb2\x51\xb3\xbd\xad\x55\x6c\xd2",
+ "\xf8\x31\x6a\x36\x7a\xa0\x31\x6d\xa3\x56\x2f\x31\x9d\x52\x2e\x81\xf4\xa8\xbd\x2e\x21\x08\xd2\x53\x21\x26\xf4\xa9\x03\x70\x4b\xa3",
+ 79 },
+ { GCRY_MD_SHA3_256,
+ "\x87\x1a\x0d\x7a\x5f\x36\xc3\xda\x1d\xfc\xe5\x7a\xcd\x8a\xb8\x48\x7c\x27\x4f\xad\x33\x6b\xc1\x37\xeb\xd6\xff\x46\x58\xb5\x47\xc1\xdc\xfa\xb6\x5f\x03\x7a\xa5\x8f\x35\xef\x16\xaf\xf4\xab\xe7\x7b\xa6\x1f\x65\x82\x6f\x7b\xe6\x81\xb5\xb6\xd5\xa1\xea\x80\x85\xe2\xae\x9c\xd5\xcf\x09\x91\x87\x8a\x31\x1b\x54\x9a\x6d\x6a\xf2\x30",
+ "\x89\xe3\xeb\xd0\x2b\x22\x9c\xd7\x59\x61\x2a\x55\x21\xd8\x67\xab\x2a\x15\x94\xbc\x0b\x1f\xe6\xa7\x8b\x79\x54\xcc\xc8\x4c\xaf\x03",
+ 80 },
+ { GCRY_MD_SHA3_256,
+ "\xe9\x0b\x4f\xfe\xf4\xd4\x57\xbc\x77\x11\xff\x4a\xa7\x22\x31\xca\x25\xaf\x6b\x2e\x20\x6f\x8b\xf8\x59\xd8\x75\x8b\x89\xa7\xcd\x36\x10\x5d\xb2\x53\x8d\x06\xda\x83\xba\xd5\xf6\x63\xba\x11\xa5\xf6\xf6\x1f\x23\x6f\xd5\xf8\xd5\x3c\x5e\x89\xf1\x83\xa3\xce\xc6\x15\xb5\x0c\x7c\x68\x1e\x77\x3d\x10\x9f\xf7\x49\x1b\x5c\xc2\x22\x96\xc5",
+ "\x2e\x7c\xc8\x75\x30\x5e\xa6\xbb\x9c\x2f\xc7\x70\xb9\xd8\x4f\xd9\x3b\x96\x40\x5d\xf9\xb9\x33\x07\xf6\xb5\xde\x26\xe1\x35\x72\x4c",
+ 81 },
+ { GCRY_MD_SHA3_256,
+ "\xe7\x28\xde\x62\xd7\x58\x56\x50\x0c\x4c\x77\xa4\x28\x61\x2c\xd8\x04\xf3\x0c\x3f\x10\xd3\x6f\xb2\x19\xc5\xca\x0a\xa3\x07\x26\xab\x19\x0e\x5f\x3f\x27\x9e\x07\x33\xd7\x7e\x72\x67\xc1\x7b\xe2\x7d\x21\x65\x0a\x9a\x4d\x1e\x32\xf6\x49\x62\x76\x38\xdb\xad\xa9\x70\x2c\x7c\xa3\x03\x26\x9e\xd1\x40\x14\xb2\xf3\xcf\x8b\x89\x4e\xac\x85\x54",
+ "\xec\xab\x75\xf2\x8a\x72\x84\x29\xcb\x43\x3e\xc1\x33\x10\xd1\xb8\x50\xcc\xf5\x22\xc3\x8d\x2f\xa6\xdf\xa4\x89\x96\x3d\x6d\x6c\xa7",
+ 82 },
+ { GCRY_MD_SHA3_256,
+ "\x63\x48\xf2\x29\xe7\xb1\xdf\x3b\x77\x0c\x77\x54\x4e\x51\x66\xe0\x81\x85\x0f\xa1\xc6\xc8\x81\x69\xdb\x74\xc7\x6e\x42\xeb\x98\x3f\xac\xb2\x76\xad\x6a\x0d\x1f\xa7\xb5\x0d\x3e\x3b\x6f\xcd\x79\x9e\xc9\x74\x70\x92\x0a\x7a\xbe\xd4\x7d\x28\x8f\xf8\x83\xe2\x4c\xa2\x1c\x7f\x80\x16\xb9\x3b\xb9\xb9\xe0\x78\xbd\xb9\x70\x3d\x2b\x78\x1b\x61\x6e",
+ "\x02\x1c\x94\x59\xd1\x45\x1f\x3d\xa4\xc0\x7c\x02\x9a\x86\x81\x94\x5c\x87\xc5\xbe\xbc\x6c\x30\xda\x1d\x95\xc5\xc4\x9d\x8a\xb9\x5c",
+ 83 },
+ { GCRY_MD_SHA3_256,
+ "\x4b\x12\x7f\xde\x5d\xe7\x33\xa1\x68\x0c\x27\x90\x36\x36\x27\xe6\x3a\xc8\xa3\xf1\xb4\x70\x7d\x98\x2c\xae\xa2\x58\x65\x5d\x9b\xf1\x8f\x89\xaf\xe5\x41\x27\x48\x2b\xa0\x1e\x08\x84\x55\x94\xb6\x71\x30\x6a\x02\x5c\x9a\x5c\x5b\x6f\x93\xb0\xa3\x95\x22\xdc\x87\x74\x37\xbe\x5c\x24\x36\xcb\xf3\x00\xce\x7a\xb6\x74\x79\x34\xfc\xfc\x30\xae\xaa\xf6",
+ "\x46\x42\xe2\x16\x22\xf1\x5b\x09\xb9\x41\x36\x59\x68\x01\x16\xbf\x2f\x96\xca\xc2\x38\x4b\x8c\x79\xf1\x32\x8d\x5d\xd3\x6d\x7a\x01",
+ 84 },
+ { GCRY_MD_SHA3_256,
+ "\x08\x46\x1f\x00\x6c\xff\x4c\xc6\x4b\x75\x2c\x95\x72\x87\xe5\xa0\xfa\xab\xc0\x5c\x9b\xff\x89\xd2\x3f\xd9\x02\xd3\x24\xc7\x99\x03\xb4\x8f\xcb\x8f\x8f\x4b\x01\xf3\xe4\xdd\xb4\x83\x59\x3d\x25\xf0\x00\x38\x66\x98\xf5\xad\xe7\xfa\xad\xe9\x61\x5f\xdc\x50\xd3\x27\x85\xea\x51\xd4\x98\x94\xe4\x5b\xaa\x3d\xc7\x07\xe2\x24\x68\x8c\x64\x08\xb6\x8b\x11",
+ "\x8d\xaa\x47\xc3\x57\x21\x57\x26\x6a\xd0\x27\x6d\x59\x26\xaf\xf2\x87\x2f\x06\xb0\xcd\x7b\x97\x4a\x80\xd7\xa6\x82\x7d\x41\xd7\x82",
+ 85 },
+ { GCRY_MD_SHA3_256,
+ "\x68\xc8\xf8\x84\x9b\x12\x0e\x6e\x0c\x99\x69\xa5\x86\x6a\xf5\x91\xa8\x29\xb9\x2f\x33\xcd\x9a\x4a\x31\x96\x95\x7a\x14\x8c\x49\x13\x8e\x1e\x2f\x5c\x76\x19\xa6\xd5\xed\xeb\xe9\x95\xac\xd8\x1e\xc8\xbb\x9c\x7b\x9c\xfc\xa6\x78\xd0\x81\xea\x9e\x25\xa7\x5d\x39\xdb\x04\xe1\x8d\x47\x59\x20\xce\x82\x8b\x94\xe7\x22\x41\xf2\x4d\xb7\x25\x46\xb3\x52\xa0\xe4",
+ "\x34\x53\x65\x23\x2c\xe9\xaf\xc6\x55\xdc\xe4\xba\xc2\x3f\x43\xc8\xac\xbd\xf9\x01\x6d\x4b\xc2\x34\x4b\xe8\xd3\x96\xa4\x91\x9c\x34",
+ 86 },
+ { GCRY_MD_SHA3_256,
+ "\xb8\xd5\x64\x72\x95\x4e\x31\xfb\x54\xe2\x8f\xca\x74\x3f\x84\xd8\xdc\x34\x89\x1c\xb5\x64\xc6\x4b\x08\xf7\xb7\x16\x36\xde\xbd\x64\xca\x1e\xdb\xdb\xa7\xfc\x5c\x3e\x40\x04\x9c\xe9\x82\xbb\xa8\xc7\xe0\x70\x30\x34\xe3\x31\x38\x46\x95\xe9\xde\x76\xb5\x10\x4f\x2f\xbc\x45\x35\xec\xbe\xeb\xc3\x3b\xc2\x7f\x29\xf1\x8f\x6f\x27\xe8\x02\x3b\x0f\xbb\x6f\x56\x3c",
+ "\xf5\x2e\x10\x2e\x57\x29\x38\x78\xc2\x8f\x29\xde\xb4\x77\x92\x32\x4f\xe4\x55\xa6\x2f\xa7\x44\x1a\xab\xcc\x16\xa9\xcf\xc4\x0f\xfa",
+ 87 },
+ { GCRY_MD_SHA3_256,
+ "\x0d\x58\xac\x66\x5f\xa8\x43\x42\xe6\x0c\xef\xee\x31\xb1\xa4\xea\xcd\xb0\x92\xf1\x22\xdf\xc6\x83\x09\x07\x7a\xed\x1f\x3e\x52\x8f\x57\x88\x59\xee\x9e\x4c\xef\xb4\xa7\x28\xe9\x46\x32\x49\x27\xb6\x75\xcd\x4f\x4a\xc8\x4f\x64\xdb\x3d\xac\xfe\x85\x0c\x1d\xd1\x87\x44\xc7\x4c\xec\xcd\x9f\xe4\xdc\x21\x40\x85\x10\x8f\x40\x4e\xab\x6d\x8f\x45\x2b\x54\x42\xa4\x7d",
+ "\x2b\x89\xaa\x88\xb1\xb7\xf9\xf8\xea\x46\x1c\x4c\x5c\xae\x48\x29\x12\x5f\x45\xf5\x69\x7d\xea\xdb\x8d\xb2\xe9\x64\x52\x4c\x0d\x91",
+ 88 },
+ { GCRY_MD_SHA3_256,
+ "\x17\x55\xe2\xd2\xe5\xd1\xc1\xb0\x15\x64\x56\xb5\x39\x75\x3f\xf4\x16\x65\x1d\x44\x69\x8e\x87\x00\x2d\xcf\x61\xdc\xfa\x2b\x4e\x72\xf2\x64\xd9\xad\x59\x1d\xf1\xfd\xee\x7b\x41\xb2\xeb\x00\x28\x3c\x5a\xeb\xb3\x41\x13\x23\xb6\x72\xea\xa1\x45\xc5\x12\x51\x85\x10\x4f\x20\xf3\x35\x80\x4b\x02\x32\x5b\x6d\xea\x65\x60\x3f\x34\x9f\x4d\x5d\x8b\x78\x2d\xd3\x46\x9c\xcd",
+ "\x3f\x30\x92\x36\x59\x82\xc0\xb4\x27\x80\x55\xbe\xee\x90\x32\xff\x9d\x10\x60\xe0\x3c\x3b\x08\x7e\x1a\x61\x97\xde\xfc\x70\x7e\x1a",
+ 89 },
+ { GCRY_MD_SHA3_256,
+ "\xb1\x80\xde\x1a\x61\x11\x11\xee\x75\x84\xba\x2c\x4b\x02\x05\x98\xcd\x57\x4a\xc7\x7e\x40\x4e\x85\x3d\x15\xa1\x01\xc6\xf5\xa2\xe5\xc8\x01\xd7\xd8\x5d\xc9\x52\x86\xa1\x80\x4c\x87\x0b\xb9\xf0\x0f\xd4\xdc\xb0\x3a\xa8\x32\x82\x75\x15\x88\x19\xdc\xad\x72\x53\xf3\xe3\xd2\x37\xae\xaa\x79\x79\x26\x8a\x5d\xb1\xc6\xce\x08\xa9\xec\x7c\x25\x79\x78\x3c\x8a\xfc\x1f\x91\xa7",
+ "\x3c\x74\xaa\xe2\xf3\x40\xa2\x41\x78\xcb\xab\x51\x00\x4c\xba\x1a\xac\x3d\x91\x13\x3c\x30\x07\x15\xea\x82\xc1\x77\x26\x9c\x05\x56",
+ 90 },
+ { GCRY_MD_SHA3_256,
+ "\xcf\x35\x83\xcb\xdf\xd4\xcb\xc1\x70\x63\xb1\xe7\xd9\x0b\x02\xf0\xe6\xe2\xee\x05\xf9\x9d\x77\xe2\x4e\x56\x03\x92\x53\x5e\x47\xe0\x50\x77\x15\x7f\x96\x81\x35\x44\xa1\x70\x46\x91\x4f\x9e\xfb\x64\x76\x2a\x23\xcf\x7a\x49\xfe\x52\xa0\xa4\xc0\x1c\x63\x0c\xfe\x87\x27\xb8\x1f\xb9\x9a\x89\xff\x7c\xc1\x1d\xca\x51\x73\x05\x7e\x04\x17\xb8\xfe\x7a\x9e\xfb\xa6\xd9\x5c\x55\x5f",
+ "\x01\x57\xc4\xba\x44\x61\x8d\xed\x11\xe9\x80\x0a\xfa\x07\xa0\xd5\xb6\xc7\x11\xfc\x16\xa5\x76\xc5\xed\xb7\x1c\x4c\xc6\x89\x4f\x82",
+ 91 },
+ { GCRY_MD_SHA3_256,
+ "\x07\x2f\xc0\x23\x40\xef\x99\x11\x5b\xad\x72\xf9\x2c\x01\xe4\xc0\x93\xb9\x59\x9f\x6c\xfc\x45\xcb\x38\x0e\xe6\x86\xcb\x5e\xb0\x19\xe8\x06\xab\x9b\xd5\x5e\x63\x4a\xb1\x0a\xa6\x2a\x95\x10\xcc\x06\x72\xcd\x3e\xdd\xb5\x89\xc7\xdf\x2b\x67\xfc\xd3\x32\x9f\x61\xb1\xa4\x44\x1e\xca\x87\xa3\x3c\x8f\x55\xda\x4f\xbb\xad\x5c\xf2\xb2\x52\x7b\x8e\x98\x3b\xb3\x1a\x2f\xad\xec\x75\x23",
+ "\x8d\x53\xdb\xa1\x07\xaa\xac\xb8\x42\x2d\x66\x67\xf6\x77\x88\x39\xf8\x96\x5f\x8e\x4c\x8f\x4a\x85\x12\x84\xcc\x91\x16\x8a\x90\x30",
+ 92 },
+ { GCRY_MD_SHA3_256,
+ "\x76\xee\xcf\x95\x6a\x52\x64\x9f\x87\x75\x28\x14\x6d\xe3\x3d\xf2\x49\xcd\x80\x0e\x21\x83\x0f\x65\xe9\x0f\x0f\x25\xca\x9d\x65\x40\xfd\xe4\x06\x03\x23\x0e\xca\x67\x60\xf1\x13\x9c\x7f\x26\x8d\xeb\xa2\x06\x06\x31\xee\xa9\x2b\x1f\xff\x05\xf9\x3f\xd5\x57\x2f\xbe\x29\x57\x9e\xcd\x48\xbc\x3a\x8d\x6c\x2e\xb4\xa6\xb2\x6e\x38\xd6\xc5\xfb\xf2\xc0\x80\x44\xae\xea\x47\x0a\x8f\x2f\x26",
+ "\x51\x63\xf0\x22\x33\xe3\x32\xad\x9b\xe3\x2c\x23\x46\xc9\xfc\xfe\x39\xaf\xa5\xfb\xe9\xbc\x1c\xfe\xb9\x2f\x49\x20\x15\x5b\x20\xec",
+ 93 },
+ { GCRY_MD_SHA3_256,
+ "\x7a\xdc\x0b\x66\x93\xe6\x1c\x26\x9f\x27\x8e\x69\x44\xa5\xa2\xd8\x30\x09\x81\xe4\x00\x22\xf8\x39\xac\x64\x43\x87\xbf\xac\x90\x86\x65\x00\x85\xc2\xcd\xc5\x85\xfe\xa4\x7b\x9d\x2e\x52\xd6\x5a\x2b\x29\xa7\xdc\x37\x04\x01\xef\x5d\x60\xdd\x0d\x21\xf9\xe2\xb9\x0f\xae\x91\x93\x19\xb1\x4b\x8c\x55\x65\xb0\x42\x3c\xef\xb8\x27\xd5\xf1\x20\x33\x02\xa9\xd0\x15\x23\x49\x8a\x4d\xb1\x03\x74",
+ "\xfa\xaf\x0e\x95\x21\x7c\xa4\xb1\x56\x87\x51\xef\x2e\x4c\xd3\x41\xd9\xec\x33\xe1\x66\x00\xbf\x09\xb9\x2c\x6f\x1a\x6d\xf8\x4d\x2e",
+ 94 },
+ { GCRY_MD_SHA3_256,
+ "\xe1\xff\xfa\x98\x26\xcc\xe8\xb8\x6b\xcc\xef\xb8\x79\x4e\x48\xc4\x6c\xdf\x37\x20\x13\xf7\x82\xec\xed\x1e\x37\x82\x69\xb7\xbe\x2b\x7b\xf5\x13\x74\x09\x22\x61\xae\x12\x0e\x82\x2b\xe6\x85\xf2\xe7\xa8\x36\x64\xbc\xfb\xe3\x8f\xe8\x63\x3f\x24\xe6\x33\xff\xe1\x98\x8e\x1b\xc5\xac\xf5\x9a\x58\x70\x79\xa5\x7a\x91\x0b\xda\x60\x06\x0e\x85\xb5\xf5\xb6\xf7\x76\xf0\x52\x96\x39\xd9\xcc\xe4\xbd",
+ "\xb2\xc1\x75\xd9\xd9\x2a\xaa\x9e\xe7\x26\x72\xf9\x95\xb8\xdf\xd2\xda\xaf\x65\x55\xa0\x32\x7a\x50\x82\x18\xa9\xb4\x47\xf0\x0b\xe8",
+ 95 },
+ { GCRY_MD_SHA3_256,
+ "\x69\xf9\xab\xba\x65\x59\x2e\xe0\x1d\xb4\xdc\xe5\x2d\xba\xb9\x0b\x08\xfc\x04\x19\x36\x02\x79\x2e\xe4\xda\xa2\x63\x03\x3d\x59\x08\x15\x87\xb0\x9b\xbe\x49\xd0\xb4\x9c\x98\x25\xd2\x28\x40\xb2\xff\x5d\x9c\x51\x55\xf9\x75\xf8\xf2\xc2\xe7\xa9\x0c\x75\xd2\xe4\xa8\x04\x0f\xe3\x9f\x63\xbb\xaf\xb4\x03\xd9\xe2\x8c\xc3\xb8\x6e\x04\xe3\x94\xa9\xc9\xe8\x06\x5b\xd3\xc8\x5f\xa9\xf0\xc7\x89\x16\x00",
+ "\xfb\x53\x88\x12\x23\x06\xd3\x7c\xee\x79\x0c\xad\x1d\x3c\xdd\xba\x8e\x9a\x93\xd5\xf9\xd7\x82\x88\xb0\x52\x48\x27\x39\xc8\x83\xfd",
+ 96 },
+ { GCRY_MD_SHA3_256,
+ "\x38\xa1\x0a\x35\x2c\xa5\xae\xdf\xa8\xe1\x9c\x64\x78\x7d\x8e\x9c\x3a\x75\xdb\xf3\xb8\x67\x4b\xfa\xb2\x9b\x5d\xbf\xc1\x5a\x63\xd1\x0f\xae\x66\xcd\x1a\x6e\x6d\x24\x52\xd5\x57\x96\x7e\xaa\xd8\x9a\x4c\x98\x44\x97\x87\xb0\xb3\x16\x4c\xa5\xb7\x17\xa9\x3f\x24\xeb\x0b\x50\x6c\xeb\x70\xcb\xbc\xb8\xd7\x2b\x2a\x72\x99\x3f\x90\x9a\xad\x92\xf0\x44\xe0\xb5\xa2\xc9\xac\x9c\xb1\x6a\x0c\xa2\xf8\x1f\x49",
+ "\x1c\x2f\x8d\x41\x8f\xf6\x71\x8b\x18\xdd\x4c\x75\x6d\xcc\x8e\xd0\xf4\x75\x5e\x8c\x22\x49\x7a\x6c\xc1\x9f\x8d\x7a\xe7\xfd\x2d\xa7",
+ 97 },
+ { GCRY_MD_SHA3_256,
+ "\x6d\x8c\x6e\x44\x9b\xc1\x36\x34\xf1\x15\x74\x9c\x24\x8c\x17\xcd\x14\x8b\x72\x15\x7a\x2c\x37\xbf\x89\x69\xea\x83\xb4\xd6\xba\x8c\x0e\xe2\x71\x1c\x28\xee\x11\x49\x5f\x43\x04\x95\x96\x52\x0c\xe4\x36\x00\x4b\x02\x6b\x6c\x1f\x72\x92\xb9\xc4\x36\xb0\x55\xcb\xb7\x2d\x53\x0d\x86\x0d\x12\x76\xa1\x50\x2a\x51\x40\xe3\xc3\xf5\x4a\x93\x66\x3e\x4d\x20\xed\xec\x32\xd2\x84\xe2\x55\x64\xf6\x24\x95\x5b\x52",
+ "\x7e\xa8\x11\x6e\x64\x34\xc1\xca\xa0\x49\x06\x9d\xbb\xd9\xb6\xf0\xe9\xdc\x6c\xdf\xd6\xa8\x89\x34\x3d\x3b\x26\x52\x80\x30\x78\xfc",
+ 98 },
+ { GCRY_MD_SHA3_256,
+ "\x6e\xfc\xbc\xaf\x45\x1c\x12\x9d\xbe\x00\xb9\xce\xf0\xc3\x74\x9d\x3e\xe9\xd4\x1c\x7b\xd5\x00\xad\xe4\x0c\xdc\x65\xde\xdb\xbb\xad\xb8\x85\xa5\xb1\x4b\x32\xa0\xc0\xd0\x87\x82\x52\x01\xe3\x03\x28\x8a\x73\x38\x42\xfa\x7e\x59\x9c\x0c\x51\x4e\x07\x8f\x05\xc8\x21\xc7\xa4\x49\x8b\x01\xc4\x00\x32\xe9\xf1\x87\x2a\x1c\x92\x5f\xa1\x7c\xe2\x53\xe8\x93\x5e\x4c\x3c\x71\x28\x22\x42\xcb\x71\x6b\x20\x89\xcc\xc1",
+ "\x73\x6d\x88\x87\x51\xfa\xac\x4d\x8e\x78\xb4\x5b\x95\xab\xb1\x5d\x40\xd9\x8d\x80\x38\xc7\x22\x5b\xe0\xf5\x23\xd5\x43\x9e\xa5\xb6",
+ 99 },
+ { GCRY_MD_SHA3_256,
+ "\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce",
+ "\x90\xe1\x0b\x1c\xa8\xd3\x52\x79\x4d\x7d\xbd\x7b\xae\x41\x0b\xef\x25\xf0\xec\x7d\x08\x0e\x05\x3f\x48\x67\x42\x37\xe3\x3e\xa4\x5f",
+ 100 },
+ { GCRY_MD_SHA3_256,
+ "\xa8\x73\xe0\xc6\x7c\xa6\x39\x02\x6b\x66\x83\x00\x8f\x7a\xa6\x32\x4d\x49\x79\x55\x0e\x9b\xce\x06\x4c\xa1\xe1\xfb\x97\xa3\x0b\x14\x7a\x24\xf3\xf6\x66\xc0\xa7\x2d\x71\x34\x8e\xde\x70\x1c\xf2\xd1\x7e\x22\x53\xc3\x4d\x1e\xc3\xb6\x47\xdb\xce\xf2\xf8\x79\xf4\xeb\x88\x1c\x48\x30\xb7\x91\x37\x8c\x90\x1e\xb7\x25\xea\x5c\x17\x23\x16\xc6\xd6\x06\xe0\xaf\x7d\xf4\xdf\x7f\x76\xe4\x90\xcd\x30\xb2\xba\xdf\x45\x68\x5f",
+ "\x8a\x0a\x8d\x6d\x55\xcc\xcb\xe0\x5e\xc7\x4d\xc2\x73\xb1\x6d\x66\xc9\xb9\x00\x66\x65\xee\xcb\x5b\x60\x23\xd2\xea\x39\xc6\x45\x54",
+ 101 },
+ { GCRY_MD_SHA3_256,
+ "\x00\x69\x17\xb6\x4f\x9d\xcd\xf1\xd2\xd8\x7c\x8a\x61\x73\xb6\x4f\x65\x87\x16\x8e\x80\xfa\xa8\x0f\x82\xd8\x4f\x60\x30\x1e\x56\x1e\x31\x2d\x9f\xbc\xe6\x2f\x39\xa6\xfb\x47\x6e\x01\xe9\x25\xf2\x6b\xcc\x91\xde\x62\x14\x49\xbe\x65\x04\xc5\x04\x83\x0a\xae\x39\x40\x96\xc8\xfc\x76\x94\x65\x10\x51\x36\x5d\x4e\xe9\x07\x01\x01\xec\x9b\x68\x08\x6f\x2e\xa8\xf8\xab\x7b\x81\x1e\xa8\xad\x93\x4d\x5c\x9b\x62\xc6\x0a\x47\x71",
+ "\x12\x28\x95\xd6\x3a\xa6\x03\x0f\xc8\xf2\x39\x40\xc5\x28\xe7\xa5\xd9\xc7\xfb\x17\x0a\x79\xfe\x7b\xc4\x23\x60\xce\x50\xe2\x5b\x7a",
+ 102 },
+ { GCRY_MD_SHA3_256,
+ "\xf1\x3c\x97\x2c\x52\xcb\x3c\xc4\xa4\xdf\x28\xc9\x7f\x2d\xf1\x1c\xe0\x89\xb8\x15\x46\x6b\xe8\x88\x63\x24\x3e\xb3\x18\xc2\xad\xb1\xa4\x17\xcb\x10\x41\x30\x85\x98\x54\x17\x20\x19\x7b\x9b\x1c\xb5\xba\x23\x18\xbd\x55\x74\xd1\xdf\x21\x74\xaf\x14\x88\x41\x49\xba\x9b\x2f\x44\x6d\x60\x9d\xf2\x40\xce\x33\x55\x99\x95\x7b\x8e\xc8\x08\x76\xd9\xa0\x85\xae\x08\x49\x07\xbc\x59\x61\xb2\x0b\xf5\xf6\xca\x58\xd5\xda\xb3\x8a\xdb",
+ "\x3e\x04\xee\x53\x95\x05\xc5\x2d\x81\x4c\xab\x3c\x5c\xdd\x7d\xf2\xd6\xee\xe6\x27\xea\x44\x18\x81\x53\xea\x6b\x8c\x8b\xe5\xf6\xc2",
+ 103 },
+ { GCRY_MD_SHA3_256,
+ "\xe3\x57\x80\xeb\x97\x99\xad\x4c\x77\x53\x5d\x4d\xdb\x68\x3c\xf3\x3e\xf3\x67\x71\x53\x27\xcf\x4c\x4a\x58\xed\x9c\xbd\xcd\xd4\x86\xf6\x69\xf8\x01\x89\xd5\x49\xa9\x36\x4f\xa8\x2a\x51\xa5\x26\x54\xec\x72\x1b\xb3\xaa\xb9\x5d\xce\xb4\xa8\x6a\x6a\xfa\x93\x82\x6d\xb9\x23\x51\x7e\x92\x8f\x33\xe3\xfb\xa8\x50\xd4\x56\x60\xef\x83\xb9\x87\x6a\xcc\xaf\xa2\xa9\x98\x7a\x25\x4b\x13\x7c\x6e\x14\x0a\x21\x69\x1e\x10\x69\x41\x38\x48",
+ "\xe3\x60\xb4\x24\xa5\xc0\x67\x04\xd1\x48\x35\x2e\x04\xf4\x65\x1f\x8d\x3b\x38\x5c\x01\xf2\x4f\xda\x09\xd2\x66\xd4\xed\x7f\xf6\x62",
+ 104 },
+ { GCRY_MD_SHA3_256,
+ "\x64\xec\x02\x1c\x95\x85\xe0\x1f\xfe\x6d\x31\xbb\x50\xd4\x4c\x79\xb6\x99\x3d\x72\x67\x81\x63\xdb\x47\x49\x47\xa0\x53\x67\x46\x19\xd1\x58\x01\x6a\xdb\x24\x3f\x5c\x8d\x50\xaa\x92\xf5\x0a\xb3\x6e\x57\x9f\xf2\xda\xbb\x78\x0a\x2b\x52\x93\x70\xda\xa2\x99\x20\x7c\xfb\xcd\xd3\xa9\xa2\x50\x06\xd1\x9c\x4f\x1f\xe3\x3e\x4b\x1e\xae\xc3\x15\xd8\xc6\xee\x1e\x73\x06\x23\xfd\x19\x41\x87\x5b\x92\x4e\xb5\x7d\x6d\x0c\x2e\xdc\x4e\x78\xd6",
+ "\x0d\x3b\xec\xb9\xe1\xb4\xae\x1f\x15\xc9\xee\x98\x73\x2b\x47\x96\xe9\x9f\xd7\x99\xf7\x6e\xd7\x33\x2a\x68\xab\x36\xc7\x7a\x1e\xf9",
+ 105 },
+ { GCRY_MD_SHA3_256,
+ "\x59\x54\xba\xb5\x12\xcf\x32\x7d\x66\xb5\xd9\xf2\x96\x18\x00\x80\x40\x26\x24\xad\x76\x28\x50\x6b\x55\x5e\xea\x83\x82\x56\x23\x24\xcf\x45\x2f\xba\x4a\x21\x30\xde\x3e\x16\x5d\x11\x83\x1a\x27\x0d\x9c\xb9\x7c\xe8\xc2\xd3\x2a\x96\xf5\x0d\x71\x60\x0b\xb4\xca\x26\x8c\xf9\x8e\x90\xd6\x49\x6b\x0a\x66\x19\xa5\xa8\xc6\x3d\xb6\xd8\xa0\x63\x4d\xfc\x6c\x7e\xc8\xea\x9c\x00\x6b\x6c\x45\x6f\x1b\x20\xcd\x19\xe7\x81\xaf\x20\x45\x4a\xc8\x80",
+ "\x3a\xad\xd7\xe2\x08\x6d\x38\x38\x32\x48\x9a\xa3\x08\x8e\x90\x3f\x5c\x6f\xa8\xe3\x8d\xf2\xcf\x87\x6e\x0b\x4d\xcd\xdc\xa5\xc9\x23",
+ 106 },
+ { GCRY_MD_SHA3_256,
+ "\x03\xd9\xf9\x2b\x2c\x56\x57\x09\xa5\x68\x72\x4a\x0a\xff\x90\xf8\xf3\x47\xf4\x3b\x02\x33\x8f\x94\xa0\x3e\xd3\x2e\x6f\x33\x66\x6f\xf5\x80\x2d\xa4\xc8\x1b\xdc\xe0\xd0\xe8\x6c\x04\xaf\xd4\xed\xc2\xfc\x8b\x41\x41\xc2\x97\x5b\x6f\x07\x63\x9b\x19\x94\xc9\x73\xd9\xa9\xaf\xce\x3d\x9d\x36\x58\x62\x00\x34\x98\x51\x3b\xfa\x16\x6d\x26\x29\xe3\x14\xd9\x74\x41\x66\x7b\x00\x74\x14\xe7\x39\xd7\xfe\xbf\x0f\xe3\xc3\x2c\x17\xaa\x18\x8a\x86\x83",
+ "\x71\x5c\xed\x57\x76\xa8\x02\xeb\x8e\xe0\x2c\x9d\x46\x54\x3f\xf4\x6f\xe7\xa9\xcd\x19\x2f\xa7\xd4\xff\xb6\xe8\x14\x27\xfe\x1b\x71",
+ 107 },
+ { GCRY_MD_SHA3_256,
+ "\xf3\x1e\x8b\x4f\x9e\x06\x21\xd5\x31\xd2\x2a\x38\x0b\xe5\xd9\xab\xd5\x6f\xae\xc5\x3c\xbd\x39\xb1\xfa\xb2\x30\xea\x67\x18\x44\x40\xe5\xb1\xd1\x54\x57\xbd\x25\xf5\x62\x04\xfa\x91\x7f\xa4\x8e\x66\x90\x16\xcb\x48\xc1\xff\xc1\xe1\xe4\x52\x74\xb3\xb4\x73\x79\xe0\x0a\x43\x84\x3c\xf8\x60\x1a\x55\x51\x41\x1e\xc1\x25\x03\xe5\xaa\xc4\x3d\x86\x76\xa1\xb2\x29\x7e\xc7\xa0\x80\x0d\xbf\xee\x04\x29\x2e\x93\x7f\x21\xc0\x05\xf1\x74\x11\x47\x30\x41",
+ "\xdd\xe6\x1f\x8b\xe2\x5b\x8b\x23\xe1\x21\x2c\x1c\x0b\x8a\x85\xa0\xd0\x2d\x85\x48\xbb\x17\xd3\x77\x13\x3e\x3c\x06\xdd\xb5\x8c\xa2",
+ 108 },
+ { GCRY_MD_SHA3_256,
+ "\x75\x8e\xa3\xfe\xa7\x38\x97\x3d\xb0\xb8\xbe\x7e\x59\x9b\xbe\xf4\x51\x93\x73\xd6\xe6\xdc\xd7\x19\x5e\xa8\x85\xfc\x99\x1d\x89\x67\x62\x99\x27\x59\xc2\xa0\x90\x02\x91\x2f\xb0\x8e\x0c\xb5\xb7\x6f\x49\x16\x2a\xeb\x8c\xf8\x7b\x17\x2c\xf3\xad\x19\x02\x53\xdf\x61\x2f\x77\xb1\xf0\xc5\x32\xe3\xb5\xfc\x99\xc2\xd3\x1f\x8f\x65\x01\x16\x95\xa0\x87\xa3\x5e\xe4\xee\xe5\xe3\x34\xc3\x69\xd8\xee\x5d\x29\xf6\x95\x81\x5d\x86\x6d\xa9\x9d\xf3\xf7\x94\x03",
+ "\x05\x9f\x2b\xed\xf4\xa6\xee\xfb\x95\xfc\x5c\x0a\xe1\x75\x56\xce\x8b\xdd\xc5\xe1\x88\x0f\xab\x2f\x68\x8a\x03\xa4\x6b\xb2\x8c\x5f",
+ 109 },
+ { GCRY_MD_SHA3_256,
+ "\x47\xc6\xe0\xc2\xb7\x49\x48\x46\x59\x21\x86\x88\x04\xf0\xf7\xbd\x50\xdd\x32\x35\x83\xdc\x78\x4f\x99\x8a\x93\xcd\x1c\xa4\xc6\xef\x84\xd4\x1d\xc8\x1c\x2c\x40\xf3\x4b\x5b\xee\x6a\x93\x86\x7b\x3b\xdb\xa0\x05\x2c\x5f\x59\xe6\xf3\x65\x79\x18\xc3\x82\xe7\x71\xd3\x31\x09\x12\x2c\xc8\xbb\x0e\x1e\x53\xc4\xe3\xd1\x3b\x43\xce\x44\x97\x0f\x5e\x0c\x07\x9d\x2a\xd7\xd7\xa3\x54\x9c\xd7\x57\x60\xc2\x1b\xb1\x5b\x44\x75\x89\xe8\x6e\x8d\x76\xb1\xe9\xce\xd2",
+ "\x12\x5b\x0e\xe7\x87\x0a\x6f\x7e\xb4\xfd\x96\x5d\x9e\x0b\x90\xd7\x9f\xff\xbc\x54\xa2\x01\x8f\x4c\x68\x22\x46\x82\xf3\x60\x3f\x3f",
+ 110 },
+ { GCRY_MD_SHA3_256,
+ "\xf6\x90\xa1\x32\xab\x46\xb2\x8e\xdf\xa6\x47\x92\x83\xd6\x44\x4e\x37\x1c\x64\x59\x10\x8a\xfd\x9c\x35\xdb\xd2\x35\xe0\xb6\xb6\xff\x4c\x4e\xa5\x8e\x75\x54\xbd\x00\x24\x60\x43\x3b\x21\x64\xca\x51\xe8\x68\xf7\x94\x7d\x7d\x7a\x0d\x79\x2e\x4a\xbf\x0b\xe5\xf4\x50\x85\x3c\xc4\x0d\x85\x48\x5b\x2b\x88\x57\xea\x31\xb5\xea\x6e\x4c\xcf\xa2\xf3\xa7\xef\x33\x80\x06\x6d\x7d\x89\x79\xfd\xac\x61\x8a\xad\x3d\x7e\x88\x6d\xea\x4f\x00\x5a\xe4\xad\x05\xe5\x06\x5f",
+ "\x9a\x78\xe0\xb5\xa3\x4c\xbf\x17\x16\xf1\x4c\xf7\xb6\x7e\xfd\xc4\x54\x0a\x75\xcc\x64\x65\x38\xa1\x1a\x8e\xfd\x9d\x7c\xd7\x52\x9f",
+ 111 },
+ { GCRY_MD_SHA3_256,
+ "\x58\xd6\xa9\x9b\xc6\x45\x88\x24\xb2\x56\x91\x67\x70\xa8\x41\x70\x40\x72\x1c\xcc\xfd\x4b\x79\xea\xcd\x8b\x65\xa3\x76\x7c\xe5\xba\x7e\x74\x10\x4c\x98\x5a\xc5\x6b\x8c\xc9\xae\xbd\x16\xfe\xbd\x4c\xda\x5a\xdb\x13\x0b\x0f\xf2\x32\x9c\xc8\xd6\x11\xeb\x14\xda\xc2\x68\xa2\xf9\xe6\x33\xc9\x9d\xe3\x39\x97\xfe\xa4\x1c\x52\xa7\xc5\xe1\x31\x7d\x5b\x5d\xae\xd3\x5e\xba\x7d\x5a\x60\xe4\x5d\x1f\xa7\xea\xab\xc3\x5f\x5c\x2b\x0a\x0f\x23\x79\x23\x19\x53\x32\x2c\x4e",
+ "\x42\x30\x5a\x25\x1a\x80\x09\xed\xfd\x62\xc7\xd9\x19\x10\xb9\x6b\x9b\x5d\xd8\xfd\xa5\xb1\x32\x6f\xe4\x1e\xf6\xee\xf9\x78\xd1\xbe",
+ 112 },
+ { GCRY_MD_SHA3_256,
+ "\xbe\xfa\xb5\x74\x39\x6d\x7f\x8b\x67\x05\xe2\xd5\xb5\x8b\x2c\x1c\x82\x0b\xb2\x4e\x3f\x4b\xae\x3e\x8f\xbc\xd3\x6d\xbf\x73\x4e\xe1\x4e\x5d\x6a\xb9\x72\xae\xdd\x35\x40\x23\x54\x66\xe8\x25\x85\x0e\xe4\xc5\x12\xea\x97\x95\xab\xfd\x33\xf3\x30\xd9\xfd\x7f\x79\xe6\x2b\xbb\x63\xa6\xea\x85\xde\x15\xbe\xae\xea\x6f\x8d\x20\x4a\x28\x95\x60\x59\xe2\x63\x2d\x11\x86\x1d\xfb\x0e\x65\xbc\x07\xac\x8a\x15\x93\x88\xd5\xc3\x27\x7e\x22\x72\x86\xf6\x5f\xf5\xe5\xb5\xae\xc1",
+ "\x6b\x9e\x8f\x3e\x82\xea\x17\x4e\xbc\x88\xa5\x3c\x5d\xed\x06\x27\x1d\x38\xf7\x9e\x9c\xec\x57\x1a\x9d\x19\x5e\xf5\x49\x10\x2e\xb8",
+ 113 },
+ { GCRY_MD_SHA3_256,
+ "\x8e\x58\x14\x4f\xa9\x17\x9d\x68\x64\x78\x62\x2c\xe4\x50\xc7\x48\x26\x0c\x95\xd1\xba\x43\xb8\xf9\xb5\x9a\xbe\xca\x8d\x93\x48\x8d\xa7\x34\x63\xef\x40\x19\x8b\x4d\x16\xfb\x0b\x07\x07\x20\x13\x47\xe0\x50\x6f\xf1\x9d\x01\xbe\xa0\xf4\x2b\x8a\xf9\xe7\x1a\x1f\x1b\xd1\x68\x78\x10\x69\xd4\xd3\x38\xfd\xef\x00\xbf\x41\x9f\xbb\x00\x30\x31\xdf\x67\x1f\x4a\x37\x97\x95\x64\xf6\x92\x82\xde\x9c\x65\x40\x78\x47\xdd\x0d\xa5\x05\xab\x16\x41\xc0\x2d\xea\x4f\x0d\x83\x49\x86",
+ "\x35\x8d\xe4\xc1\xed\x30\xf4\x8b\x08\x4f\x96\x1f\x65\x3f\xeb\xc6\x93\x18\xf9\x38\x83\x61\x2d\x5a\x04\xb9\x13\x9a\x14\xec\x70\x2e",
+ 114 },
+ { GCRY_MD_SHA3_256,
+ "\xb5\x5c\x10\xea\xe0\xec\x68\x4c\x16\xd1\x34\x63\xf2\x92\x91\xbf\x26\xc8\x2e\x2f\xa0\x42\x2a\x99\xc7\x1d\xb4\xaf\x14\xdd\x9c\x7f\x33\xed\xa5\x2f\xd7\x3d\x01\x7c\xc0\xf2\xdb\xe7\x34\xd8\x31\xf0\xd8\x20\xd0\x6d\x5f\x89\xda\xcc\x48\x57\x39\x14\x4f\x8c\xfd\x47\x99\x22\x3b\x1a\xff\x90\x31\xa1\x05\xcb\x6a\x02\x9b\xa7\x1e\x6e\x58\x67\xd8\x5a\x55\x49\x91\xc3\x8d\xf3\xc9\xef\x8c\x1e\x1e\x9a\x76\x30\xbe\x61\xca\xab\xca\x69\x28\x0c\x39\x9c\x1f\xb7\xa1\x2d\x12\xae\xfc",
+ "\x4a\x7b\xd1\x8a\xe1\x0e\xb9\x45\x89\x24\xaa\x5c\xa0\x0d\x3f\x63\x4a\xb9\x75\x36\x28\x10\x7f\x15\xff\x2b\xf2\x4c\xcd\x3b\x94\xf4",
+ 115 },
+ { GCRY_MD_SHA3_256,
+ "\x2e\xee\xa6\x93\xf5\x85\xf4\xed\x6f\x6f\x88\x65\xbb\xae\x47\xa6\x90\x8a\xec\xd7\xc4\x29\xe4\xbe\xc4\xf0\xde\x1d\x0c\xa0\x18\x3f\xa2\x01\xa0\xcb\x14\xa5\x29\xb7\xd7\xac\x0e\x6f\xf6\x60\x7a\x32\x43\xee\x9f\xb1\x1b\xcf\x3e\x23\x04\xfe\x75\xff\xcd\xdd\x6c\x5c\x2e\x2a\x4c\xd4\x5f\x63\xc9\x62\xd0\x10\x64\x50\x58\xd3\x65\x71\x40\x4a\x6d\x2b\x4f\x44\x75\x54\x34\xd7\x69\x98\xe8\x34\x09\xc3\x20\x5a\xa1\x61\x5d\xb4\x40\x57\xdb\x99\x12\x31\xd2\xcb\x42\x62\x45\x74\xf5\x45",
+ "\x98\x89\xe4\xb3\xb1\x29\x4a\x01\x55\x6f\xa9\xde\x6a\x6a\x50\x8a\x9a\x76\x3d\x51\x33\xfd\xcd\x49\x37\xb6\xbb\x23\xca\x3e\x19\x01",
+ 116 },
+ { GCRY_MD_SHA3_256,
+ "\xda\xb1\x1d\xc0\xb0\x47\xdb\x04\x20\xa5\x85\xf5\x6c\x42\xd9\x31\x75\x56\x28\x52\x42\x84\x99\xf6\x6a\x0d\xb8\x11\xfc\xdd\xda\xb2\xf7\xcd\xff\xed\x15\x43\xe5\xfb\x72\x11\x0b\x64\x68\x6b\xc7\xb6\x88\x7a\x53\x8a\xd4\x4c\x05\x0f\x1e\x42\x63\x1b\xc4\xec\x8a\x9f\x2a\x04\x71\x63\xd8\x22\xa3\x89\x89\xee\x4a\xab\x01\xb4\xc1\xf1\x61\xb0\x62\xd8\x73\xb1\xcf\xa3\x88\xfd\x30\x15\x14\xf6\x22\x24\x15\x7b\x9b\xef\x42\x3c\x77\x83\xb7\xaa\xc8\xd3\x0d\x65\xcd\x1b\xba\x8d\x68\x9c\x2d",
+ "\x3d\x02\xb4\x19\x85\xbd\xd1\x83\x5c\xb4\x74\xfb\x36\x4c\x25\xc2\xcc\xa9\xda\x0e\xd2\xfb\xba\xb7\x55\x24\xb4\x10\x90\x38\x15\xb9",
+ 117 },
+ { GCRY_MD_SHA3_256,
+ "\x42\xe9\x9a\x2f\x80\xae\xe0\xe0\x01\x27\x9a\x24\x34\xf7\x31\xe0\x1d\x34\xa4\x4b\x1a\x81\x01\x72\x69\x21\xc0\x59\x0c\x30\xf3\x12\x0e\xb8\x30\x59\xf3\x25\xe8\x94\xa5\xac\x95\x9d\xca\x71\xce\x22\x14\x79\x99\x16\x42\x4e\x85\x9d\x27\xd7\x89\x43\x7b\x9d\x27\x24\x0b\xf8\xc3\x5a\xdb\xaf\xce\xcc\x32\x2b\x48\xaa\x20\x5b\x29\x39\x62\xd8\x58\x65\x2a\xba\xcb\xd5\x88\xbc\xf6\xcb\xc3\x88\xd0\x99\x3b\xd6\x22\xf9\x6e\xd5\x46\x14\xc2\x5b\x6a\x9a\xa5\x27\x58\x9e\xaa\xff\xcf\x17\xdd\xf7",
+ "\x1c\xd9\x20\x39\xbe\x45\x80\xc6\x86\x79\x6d\x59\x00\xee\xd4\x31\xeb\xad\x6e\xa5\x66\xe9\x24\x4e\x76\xba\x68\x73\xef\xcb\x49\xab",
+ 118 },
+ { GCRY_MD_SHA3_256,
+ "\x3c\x9b\x46\x45\x0c\x0f\x2c\xae\x8e\x38\x23\xf8\xbd\xb4\x27\x7f\x31\xb7\x44\xce\x2e\xb1\x70\x54\xbd\xdc\x6d\xff\x36\xaf\x7f\x49\xfb\x8a\x23\x20\xcc\x3b\xdf\x8e\x0a\x2e\xa2\x9a\xd3\xa5\x5d\xe1\x16\x5d\x21\x9a\xde\xdd\xb5\x17\x52\x53\xe2\xd1\x48\x9e\x9b\x6f\xdd\x02\xe2\xc3\xd3\xa4\xb5\x4d\x60\xe3\xa4\x73\x34\xc3\x79\x13\xc5\x69\x53\x78\xa6\x69\xe9\xb7\x2d\xec\x32\xaf\x54\x34\xf9\x3f\x46\x17\x6e\xbf\x04\x4c\x47\x84\x46\x7c\x70\x04\x70\xd0\xc0\xb4\x0c\x8a\x08\x8c\x81\x58\x16",
+ "\x68\x0c\x70\xb2\x43\x16\x3b\xe6\xe5\x8e\xd3\xb8\xe2\xd8\x5e\x68\x94\xe5\xe8\x95\x01\xc4\x44\xc8\xc0\xa2\xd7\x76\xac\xad\x85\x99",
+ 119 },
+ { GCRY_MD_SHA3_256,
+ "\xd1\xe6\x54\xb7\x7c\xb1\x55\xf5\xc7\x79\x71\xa6\x4d\xf9\xe5\xd3\x4c\x26\xa3\xca\xd6\xc7\xf6\xb3\x00\xd3\x9d\xeb\x19\x10\x09\x46\x91\xad\xaa\x09\x5b\xe4\xba\x5d\x86\x69\x0a\x97\x64\x28\x63\x5d\x55\x26\xf3\xe9\x46\xf7\xdc\x3b\xd4\xdb\xc7\x89\x99\xe6\x53\x44\x11\x87\xa8\x1f\x9a\xdc\xd5\xa3\xc5\xf2\x54\xbc\x82\x56\xb0\x15\x8f\x54\x67\x3d\xcc\x12\x32\xf6\xe9\x18\xeb\xfc\x6c\x51\xce\x67\xea\xeb\x04\x2d\x9f\x57\xee\xc4\xbf\xe9\x10\xe1\x69\xaf\x78\xb3\xde\x48\xd1\x37\xdf\x4f\x28\x40",
+ "\xd6\x5e\x82\x3d\x2c\xe4\xef\xfb\x9b\x27\xdb\xbf\x6e\xfc\xda\x73\x8a\xd1\x52\xfb\xb1\x2d\x21\x08\xd2\xec\x6d\x05\x0a\x3f\xb2\x95",
+ 120 },
+ { GCRY_MD_SHA3_256,
+ "\x62\x6f\x68\xc1\x8a\x69\xa6\x59\x01\x59\xa9\xc4\x6b\xe0\x3d\x59\x65\x69\x8f\x2d\xac\x3d\xe7\x79\xb8\x78\xb3\xd9\xc4\x21\xe0\xf2\x1b\x95\x5a\x16\xc7\x15\xc1\xec\x1e\x22\xce\x3e\xb6\x45\xb8\xb4\xf2\x63\xf6\x06\x60\xea\x30\x28\x98\x1e\xeb\xd6\xc8\xc3\xa3\x67\x28\x5b\x69\x1c\x8e\xe5\x69\x44\xa7\xcd\x12\x17\x99\x7e\x1d\x9c\x21\x62\x0b\x53\x6b\xdb\xd5\xde\x89\x25\xff\x71\xde\xc6\xfb\xc0\x66\x24\xab\x6b\x21\xe3\x29\x81\x3d\xe9\x0d\x1e\x57\x2d\xfb\x89\xa1\x81\x20\xc3\xf6\x06\x35\x5d\x25",
+ "\xce\x6d\x2d\xd8\xd5\x44\x1f\xc1\x5b\x88\x8f\xed\x72\x06\x1e\x12\x91\x25\x43\x1b\xed\xea\x32\xe0\x0e\xe0\xa7\x65\x5c\x06\xc3\x58",
+ 121 },
+ { GCRY_MD_SHA3_256,
+ "\x65\x1a\x6f\xb3\xc4\xb8\x0c\x7c\x68\xc6\x01\x16\x75\xe6\x09\x4e\xb5\x6a\xbf\x5f\xc3\x05\x73\x24\xeb\xc6\x47\x78\x25\x06\x1f\x9f\x27\xe7\xa9\x46\x33\xab\xd1\xfa\x59\x8a\x74\x6e\x4a\x57\x7c\xaf\x52\x4c\x52\xec\x17\x88\x47\x1f\x92\xb8\xc3\x7f\x23\x79\x5c\xa1\x9d\x55\x9d\x44\x6c\xab\x16\xcb\xcd\xce\x90\xb7\x9f\xa1\x02\x6c\xee\x77\xbf\x4a\xb1\xb5\x03\xc5\xb9\x4c\x22\x56\xad\x75\xb3\xea\xc6\xfd\x5d\xcb\x96\xac\xa4\xb0\x3a\x83\x4b\xfb\x4e\x9a\xf9\x88\xce\xcb\xf2\xae\x59\x7c\xb9\x09\x79\x40",
+ "\x28\x07\x13\xc0\xfa\x71\x60\x28\x9f\xbf\xee\x5a\xa5\x80\xad\x82\x51\x28\x39\x15\x3d\xae\x47\xde\x0d\x15\x43\x84\xa4\xd8\xb3\xed",
+ 122 },
+ { GCRY_MD_SHA3_256,
+ "\x8a\xaf\x07\x2f\xce\x8a\x2d\x96\xbc\x10\xb3\xc9\x1c\x80\x9e\xe9\x30\x72\xfb\x20\x5c\xa7\xf1\x0a\xbd\x82\xec\xd8\x2c\xf0\x40\xb1\xbc\x49\xea\x13\xd1\x85\x78\x15\xc0\xe9\x97\x81\xde\x3a\xdb\xb5\x44\x3c\xe1\xc8\x97\xe5\x51\x88\xce\xaf\x22\x1a\xa9\x68\x16\x38\xde\x05\xae\x1b\x32\x29\x38\xf4\x6b\xce\x51\x54\x3b\x57\xec\xdb\x4c\x26\x62\x72\x25\x9d\x17\x98\xde\x13\xbe\x90\xe1\x0e\xfe\xc2\xd0\x74\x84\xd9\xb2\x1a\x38\x70\xe2\xaa\x9e\x06\xc2\x1a\xa2\xd0\xc9\xcf\x42\x00\x80\xa8\x0a\x91\xde\xe1\x6f",
+ "\x72\x1f\xd8\x72\x69\x6f\x21\xde\xaa\x95\x95\xc0\xce\xe7\xbc\x07\x24\x96\x01\x92\x7c\x96\xa6\x58\x26\xb4\x88\x7c\xdb\xa1\xae\x96",
+ 123 },
+ { GCRY_MD_SHA3_256,
+ "\x53\xf9\x18\xfd\x00\xb1\x70\x1b\xd5\x04\xf8\xcd\xea\x80\x3a\xcc\xa2\x1a\xc1\x8c\x56\x4a\xb9\x0c\x2a\x17\xda\x59\x2c\x7d\x69\x68\x8f\x65\x80\x57\x53\x95\x55\x1e\x8c\xd3\x3e\x0f\xef\x08\xca\x6e\xd4\x58\x8d\x4d\x14\x0b\x3e\x44\xc0\x32\x35\x5d\xf1\xc5\x31\x56\x4d\x7f\x48\x35\x75\x33\x44\x34\x5a\x67\x81\xe1\x1c\xd5\xe0\x95\xb7\x3d\xf5\xf8\x2c\x8a\xe3\xad\x00\x87\x79\x36\x89\x66\x71\xe9\x47\xcc\x52\xe2\xb2\x9d\xcd\x46\x3d\x90\xa0\xc9\x92\x91\x28\xda\x22\x2b\x5a\x21\x14\x50\xbb\xc0\xe0\x24\x48\xe2",
+ "\xb5\x3a\xf8\x62\x0b\x39\xca\xd2\xd6\x98\xa1\x76\xa0\x70\xae\xaa\x9f\xb6\x7b\xd0\x33\x5c\x34\x85\xa3\xb6\xc7\x3a\x71\xdc\x5c\x5c",
+ 124 },
+ { GCRY_MD_SHA3_256,
+ "\xa6\x45\x99\xb8\xa6\x1b\x5c\xce\xc9\xe6\x7a\xed\x69\x44\x74\x59\xc8\xda\x3d\x1e\xc6\xc7\xc7\xc8\x2a\x74\x28\xb9\xb5\x84\xfa\x67\xe9\x0f\x68\xe2\xc0\x0f\xbb\xed\x46\x13\x66\x6e\x51\x68\xda\x4a\x16\xf3\x95\xf7\xa3\xc3\x83\x2b\x3b\x13\x4b\xfc\x9c\xba\xa9\x5d\x2a\x0f\xe2\x52\xf4\x4a\xc6\x68\x1e\xb6\xd4\x0a\xb9\x1c\x1d\x02\x82\xfe\xd6\x70\x1c\x57\x46\x3d\x3c\x5f\x2b\xb8\xc6\xa7\x30\x1f\xb4\x57\x6a\xa3\xb5\xf1\x55\x10\xdb\x89\x56\xff\x77\x47\x8c\x26\xa7\xc0\x9b\xea\x7b\x39\x8c\xfc\x83\x50\x3f\x53\x8e",
+ "\x78\xa1\x8b\xf0\xa5\x2e\x6f\x77\xf1\x5f\x7f\xfe\x4c\xa3\xc9\x99\xe5\x7e\x1c\x3f\x6b\xf1\x09\x50\x58\x1f\x40\x34\x50\xed\xb7\x97",
+ 125 },
+ { GCRY_MD_SHA3_256,
+ "\x0e\x3a\xb0\xe0\x54\x73\x9b\x00\xcd\xb6\xa8\x7b\xd1\x2c\xae\x02\x4b\x54\xcb\x5e\x55\x0e\x6c\x42\x53\x60\xc2\xe8\x7e\x59\x40\x1f\x5e\xc2\x4e\xf0\x31\x48\x55\xf0\xf5\x6c\x47\x69\x5d\x56\xa7\xfb\x14\x17\x69\x3a\xf2\xa1\xed\x52\x91\xf2\xfe\xe9\x5f\x75\xee\xd5\x4a\x1b\x1c\x2e\x81\x22\x6f\xbf\xf6\xf6\x3a\xde\x58\x49\x11\xc7\x19\x67\xa8\xeb\x70\x93\x3b\xc3\xf5\xd1\x5b\xc9\x1b\x5c\x26\x44\xd9\x51\x6d\x3c\x3a\x8c\x15\x4e\xe4\x8e\x11\x8b\xd1\x44\x2c\x04\x3c\x7a\x0d\xba\x5a\xc5\xb1\xd5\x36\x0a\xae\x5b\x90\x65",
+ "\xa7\xf0\x15\x1e\xee\x6b\x21\xfe\x82\x7e\x69\x25\x6d\x56\x0e\x1e\xa8\xd9\x39\xb8\x09\x62\xfc\x7f\xa8\x61\x0a\xc1\x89\x40\x2a\xd2",
+ 126 },
+ { GCRY_MD_SHA3_256,
+ "\xa6\x2f\xc5\x95\xb4\x09\x6e\x63\x36\xe5\x3f\xcd\xfc\x8d\x1c\xc1\x75\xd7\x1d\xac\x9d\x75\x0a\x61\x33\xd2\x31\x99\xea\xac\x28\x82\x07\x94\x4c\xea\x6b\x16\xd2\x76\x31\x91\x5b\x46\x19\xf7\x43\xda\x2e\x30\xa0\xc0\x0b\xbd\xb1\xbb\xb3\x5a\xb8\x52\xef\x3b\x9a\xec\x6b\x0a\x8d\xcc\x6e\x9e\x1a\xba\xa3\xad\x62\xac\x0a\x6c\x5d\xe7\x65\xde\x2c\x37\x11\xb7\x69\xe3\xfd\xe4\x4a\x74\x01\x6f\xff\x82\xac\x46\xfa\x8f\x17\x97\xd3\xb2\xa7\x26\xb6\x96\xe3\xde\xa5\x53\x04\x39\xac\xee\x3a\x45\xc2\xa5\x1b\xc3\x2d\xd0\x55\x65\x0b",
+ "\x0a\x09\xc4\xb1\x8f\x51\x17\xf0\xe4\x5d\x43\xe2\x35\xbb\x14\xe5\x5b\x16\x2e\x99\xeb\x37\x44\x16\x51\x96\xd0\x4a\x85\x42\x29\xf9",
+ 127 },
+ { GCRY_MD_SHA3_256,
+ "\x2b\x6d\xb7\xce\xd8\x66\x5e\xbe\x9d\xeb\x08\x02\x95\x21\x84\x26\xbd\xaa\x7c\x6d\xa9\xad\xd2\x08\x89\x32\xcd\xff\xba\xa1\xc1\x41\x29\xbc\xcd\xd7\x0f\x36\x9e\xfb\x14\x92\x85\x85\x8d\x2b\x1d\x15\x5d\x14\xde\x2f\xdb\x68\x0a\x8b\x02\x72\x84\x05\x51\x82\xa0\xca\xe2\x75\x23\x4c\xc9\xc9\x28\x63\xc1\xb4\xab\x66\xf3\x04\xcf\x06\x21\xcd\x54\x56\x5f\x5b\xff\x46\x1d\x3b\x46\x1b\xd4\x0d\xf2\x81\x98\xe3\x73\x25\x01\xb4\x86\x0e\xad\xd5\x03\xd2\x6d\x6e\x69\x33\x8f\x4e\x04\x56\xe9\xe9\xba\xf3\xd8\x27\xae\x68\x5f\xb1\xd8\x17",
+ "\xb7\xd0\x31\xaa\x69\xb7\xb4\xd2\x6a\x35\xb8\x96\xd7\x61\x31\x4f\x1d\x61\xeb\x12\xdc\xc1\xe7\x2a\xaf\x61\xb9\xcd\x48\x00\x3a\xf9",
+ 128 },
+ { GCRY_MD_SHA3_256,
+ "\x10\xdb\x50\x9b\x2c\xdc\xab\xa6\xc0\x62\xae\x33\xbe\x48\x11\x6a\x29\xeb\x18\xe3\x90\xe1\xbb\xad\xa5\xca\x0a\x27\x18\xaf\xbc\xd2\x34\x31\x44\x01\x06\x59\x48\x93\x04\x3c\xc7\xf2\x62\x52\x81\xbf\x7d\xe2\x65\x58\x80\x96\x6a\x23\x70\x5f\x0c\x51\x55\xc2\xf5\xcc\xa9\xf2\xc2\x14\x2e\x96\xd0\xa2\xe7\x63\xb7\x06\x86\xcd\x42\x1b\x5d\xb8\x12\xda\xce\xd0\xc6\xd6\x50\x35\xfd\xe5\x58\xe9\x4f\x26\xb3\xe6\xdd\xe5\xbd\x13\x98\x0c\xc8\x02\x92\xb7\x23\x01\x3b\xd0\x33\x28\x45\x84\xbf\xf2\x76\x57\x87\x1b\x0c\xf0\x7a\x84\x9f\x4a\xe2",
+ "\xec\x08\x58\xc9\xd0\x17\xa2\xd3\x72\x7c\xaa\xde\x7e\x48\x72\x68\x4f\x17\xb8\x22\xca\xfe\xcd\xa4\x45\xa1\x5c\xf3\x0f\xac\x8c\xf0",
+ 129 },
+ { GCRY_MD_SHA3_256,
+ "\x93\x34\xde\x60\xc9\x97\xbd\xa6\x08\x61\x01\xa6\x31\x4f\x64\xe4\x45\x8f\x5f\xf9\x45\x0c\x50\x9d\xf0\x06\xe8\xc5\x47\x98\x3c\x65\x1c\xa9\x78\x79\x17\x5a\xab\xa0\xc5\x39\xe8\x2d\x05\xc1\xe0\x2c\x48\x09\x75\xcb\xb3\x01\x18\x12\x10\x61\xb1\xeb\xac\x4f\x8d\x9a\x37\x81\xe2\xdb\x6b\x18\x04\x2e\x01\xec\xf9\x01\x7a\x64\xa0\xe5\x74\x47\xec\x7f\xcb\xe6\xa7\xf8\x25\x85\xf7\x40\x3e\xe2\x22\x3d\x52\xd3\x7b\x4b\xf4\x26\x42\x86\x13\xd6\xb4\x25\x79\x80\x97\x2a\x0a\xca\xb5\x08\xa7\x62\x0c\x1c\xb2\x8e\xb4\xe9\xd3\x0f\xc4\x13\x61\xec",
+ "\x71\xe1\xd6\x10\xb5\x76\x06\x3f\x2b\x12\xf6\x91\x22\x0b\xea\xdf\x50\x6b\xec\x0a\x3a\x08\x6b\xbe\x58\x64\xfb\x54\xf9\x3d\xb5\x56",
+ 130 },
+ { GCRY_MD_SHA3_256,
+ "\xe8\x8a\xb0\x86\x89\x16\x93\xaa\x53\x5c\xeb\x20\xe6\x4c\x7a\xb9\x7c\x7d\xd3\x54\x8f\x37\x86\x33\x98\x97\xa5\xf0\xc3\x90\x31\x54\x9c\xa8\x70\x16\x6e\x47\x77\x43\xcc\xfb\xe0\x16\xb4\x42\x8d\x89\x73\x8e\x42\x6f\x5f\xfe\x81\x62\x61\x37\xf1\x7a\xec\xff\x61\xb7\x2d\xbe\xe2\xdc\x20\x96\x18\x80\xcf\xe2\x81\xdf\xab\x5e\xe3\x8b\x19\x21\x88\x14\x50\xe1\x60\x32\xde\x5e\x4d\x55\xad\x8d\x4f\xca\x60\x97\x21\xb0\x69\x2b\xac\x79\xbe\x5a\x06\xe1\x77\xfe\x8c\x80\xc0\xc8\x35\x19\xfb\x33\x47\xde\x9f\x43\xd5\x56\x1c\xb8\x10\x7b\x9b\x5e\xdc",
+ "\x72\xa8\xa7\x49\x33\x09\x08\x0a\xcc\xca\x2a\x2a\x21\xd6\x41\xf2\xb9\x68\x5b\x73\x62\xbe\x49\x6d\xc7\xbc\x33\x06\x59\xf8\xcf\xe1",
+ 131 },
+ { GCRY_MD_SHA3_256,
+ "\xfd\x19\xe0\x1a\x83\xeb\x6e\xc8\x10\xb9\x45\x82\xcb\x8f\xbf\xa2\xfc\xb9\x92\xb5\x36\x84\xfb\x74\x8d\x22\x64\xf0\x20\xd3\xb9\x60\xcb\x1d\x6b\x8c\x34\x8c\x2b\x54\xa9\xfc\xea\x72\x33\x0c\x2a\xaa\x9a\x24\xec\xdb\x00\xc4\x36\xab\xc7\x02\x36\x1a\x82\xbb\x88\x28\xb8\x53\x69\xb8\xc7\x2e\xce\x00\x82\xfe\x06\x55\x71\x63\x89\x9c\x2a\x0e\xfa\x46\x6c\x33\xc0\x43\x43\xa8\x39\x41\x70\x57\x39\x9a\x63\xa3\x92\x9b\xe1\xee\x48\x05\xd6\xce\x3e\x5d\x0d\x09\x67\xfe\x90\x04\x69\x6a\x56\x63\xf4\xca\xc9\x17\x90\x06\xa2\xce\xb7\x55\x42\xd7\x5d\x68",
+ "\xaf\x19\xe9\x88\xd3\x7e\x25\x77\xda\x4f\x43\x46\x37\x89\xb7\x36\x25\xd3\x54\xfc\xcc\xbd\x10\xcd\x2c\x61\xfb\xdc\x8b\xb0\x18\x27",
+ 132 },
+ { GCRY_MD_SHA3_256,
+ "\x59\xae\x20\xb6\xf7\xe0\xb3\xc7\xa9\x89\xaf\xb2\x83\x24\xa4\x0f\xca\x25\xd8\x65\x1c\xf1\xf4\x6a\xe3\x83\xef\x6d\x84\x41\x58\x7a\xa1\xc0\x4c\x3e\x3b\xf8\x8e\x81\x31\xce\x61\x45\xcf\xb8\x97\x3d\x96\x1e\x84\x32\xb2\x02\xfa\x5a\xf3\xe0\x9d\x62\x5f\xaa\xd8\x25\xbc\x19\xda\x9b\x5c\x6c\x20\xd0\x2a\xbd\xa2\xfc\xc5\x8b\x5b\xd3\xfe\x50\x7b\xf2\x01\x26\x3f\x30\x54\x38\x19\x51\x0c\x12\xbc\x23\xe2\xdd\xb4\xf7\x11\xd0\x87\xa8\x6e\xdb\x1b\x35\x53\x13\x36\x3a\x2d\xe9\x96\xb8\x91\x02\x5e\x14\x70\x36\x08\x74\x01\xcc\xf3\xca\x78\x15\xbf\x3c\x49",
+ "\xf1\xe9\xb9\xce\xf2\xb3\x7e\x4e\xc3\xa0\xfc\xd5\xef\xf5\xbf\x7e\x3d\x49\x10\x0a\xeb\xf0\x18\xdc\x92\xfb\x6a\x40\xe4\x29\x77\x04",
+ 133 },
+ { GCRY_MD_SHA3_256,
+ "\x77\xee\x80\x4b\x9f\x32\x95\xab\x23\x62\x79\x8b\x72\xb0\xa1\xb2\xd3\x29\x1d\xce\xb8\x13\x98\x96\x35\x58\x30\xf3\x4b\x3b\x32\x85\x61\x53\x1f\x80\x79\xb7\x9a\x6e\x99\x80\x70\x51\x50\x86\x64\x02\xfd\xc1\x76\xc0\x58\x97\xe3\x59\xa6\xcb\x1a\x7a\xb0\x67\x38\x3e\xb4\x97\x18\x2a\x7e\x5a\xef\x70\x38\xe4\xc9\x6d\x13\x3b\x27\x82\x91\x74\x17\xe3\x91\x53\x5b\x5e\x1b\x51\xf4\x7d\x8e\xd7\xe4\xd4\x02\x5f\xe9\x8d\xc8\x7b\x9c\x16\x22\x61\x4b\xff\x3d\x10\x29\xe6\x8e\x37\x2d\xe7\x19\x80\x38\x57\xca\x52\x06\x7c\xdd\xaa\xd9\x58\x95\x1c\xb2\x06\x8c\xc6",
+ "\xdd\x3e\xbe\x0c\xca\x0c\xad\x3a\xf7\x2a\xf7\x3f\xb4\x9d\x40\xdb\xdc\xc4\xb1\xf1\xff\x46\x5c\xca\xef\xe6\x72\xf7\x79\x92\xac\xa0",
+ 134 },
+ { GCRY_MD_SHA3_256,
+ "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+ "\xa1\x9e\xee\x92\xbb\x20\x97\xb6\x4e\x82\x3d\x59\x77\x98\xaa\x18\xbe\x9b\x7c\x73\x6b\x80\x59\xab\xfd\x67\x79\xac\x35\xac\x81\xb5",
+ 135 },
+ { GCRY_MD_SHA3_256,
+ "\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",
+ "\xdf\x67\x3f\x41\x05\x37\x9f\xf6\xb7\x55\xee\xab\x20\xce\xb0\xdc\x77\xb5\x28\x63\x64\xfe\x16\xc5\x9c\xc8\xa9\x07\xaf\xf0\x77\x32",
+ 136 },
+ { GCRY_MD_SHA3_256,
+ "\x04\x41\x0e\x31\x08\x2a\x47\x58\x4b\x40\x6f\x05\x13\x98\xa6\xab\xe7\x4e\x4d\xa5\x9b\xb6\xf8\x5e\x6b\x49\xe8\xa1\xf7\xf2\xca\x00\xdf\xba\x54\x62\xc2\xcd\x2b\xfd\xe8\xb6\x4f\xb2\x1d\x70\xc0\x83\xf1\x13\x18\xb5\x6a\x52\xd0\x3b\x81\xca\xc5\xee\xc2\x9e\xb3\x1b\xd0\x07\x8b\x61\x56\x78\x6d\xa3\xd6\xd8\xc3\x30\x98\xc5\xc4\x7b\xb6\x7a\xc6\x4d\xb1\x41\x65\xaf\x65\xb4\x45\x44\xd8\x06\xdd\xe5\xf4\x87\xd5\x37\x3c\x7f\x97\x92\xc2\x99\xe9\x68\x6b\x7e\x58\x21\xe7\xc8\xe2\x45\x83\x15\xb9\x96\xb5\x67\x7d\x92\x6d\xac\x57\xb3\xf2\x2d\xa8\x73\xc6\x01\x01\x6a\x0d",
+ "\xd5\x24\x32\xcf\x3b\x6b\x4b\x94\x9a\xa8\x48\xe0\x58\xdc\xd6\x2d\x73\x5e\x01\x77\x27\x92\x22\xe7\xac\x0a\xf8\x50\x47\x62\xfa\xa0",
+ 137 },
+ { GCRY_MD_SHA3_256,
+ "\x8b\x81\xe9\xba\xdd\xe0\x26\xf1\x4d\x95\xc0\x19\x97\x70\x24\xc9\xe1\x3d\xb7\xa5\xcd\x21\xf9\xe9\xfc\x49\x1d\x71\x61\x64\xbb\xac\xdc\x70\x60\xd8\x82\x61\x5d\x41\x14\x38\xae\xa0\x56\xc3\x40\xcd\xf9\x77\x78\x8f\x6e\x17\xd1\x18\xde\x55\x02\x68\x55\xf9\x32\x70\x47\x2d\x1f\xd1\x8b\x9e\x7e\x81\x2b\xae\x10\x7e\x0d\xfd\xe7\x06\x33\x01\xb7\x1f\x6c\xfe\x4e\x22\x5c\xab\x3b\x23\x29\x05\xa5\x6e\x99\x4f\x08\xee\x28\x91\xba\x92\x2d\x49\xc3\xda\xfe\xb7\x5f\x7c\x69\x75\x0c\xb6\x7d\x82\x2c\x96\x17\x6c\x46\xbd\x8a\x29\xf1\x70\x13\x73\xfb\x09\xa1\xa6\xe3\xc7\x15\x8f",
+ "\x07\xe6\x57\x54\xd6\x2e\x01\xb9\xa0\x49\xd1\x5d\xec\x0d\x09\xc0\x2f\x47\x9c\xa2\xae\xb4\xb1\x8e\x37\x07\x0b\x20\xf8\x5a\x1b\x26",
+ 138 },
+ { GCRY_MD_SHA3_256,
+ "\xfa\x6e\xed\x24\xda\x66\x66\xa2\x22\x08\x14\x6b\x19\xa5\x32\xc2\xec\x9b\xa9\x4f\x09\xf1\xde\xf1\xe7\xfc\x13\xc3\x99\xa4\x8e\x41\xac\xc2\xa5\x89\xd0\x99\x27\x62\x96\x34\x8f\x39\x62\x53\xb5\x7c\xb0\xe4\x02\x91\xbd\x28\x27\x73\x65\x6b\x6e\x0d\x8b\xea\x1c\xda\x08\x4a\x37\x38\x81\x6a\x84\x04\x85\xfc\xf3\xfb\x30\x7f\x77\x7f\xa5\xfe\xac\x48\x69\x5c\x2a\xf4\x76\x97\x20\x25\x8c\x77\x94\x3f\xb4\x55\x6c\x36\x2d\x9c\xba\x8b\xf1\x03\xae\xb9\x03\x4b\xaa\x8e\xa8\xbf\xb9\xc4\xf8\xe6\x74\x2c\xe0\xd5\x2c\x49\xea\x8e\x97\x4f\x33\x96\x12\xe8\x30\xe9\xe7\xa9\xc2\x90\x65",
+ "\x17\xa4\x61\xb8\xee\x50\x7a\xbc\xfe\xd5\x1a\x50\xef\x14\x89\x13\x09\xfe\x40\x2c\x56\x9d\x94\x39\x4c\xa7\xa3\x03\x1b\xef\xcd\x50",
+ 139 },
+ { GCRY_MD_SHA3_256,
+ "\x9b\xb4\xaf\x1b\x4f\x09\xc0\x71\xce\x3c\xaf\xa9\x2e\x4e\xb7\x3c\xe8\xa6\xf5\xd8\x2a\x85\x73\x34\x40\x36\x8d\xee\x4e\xb1\xcb\xc7\xb5\x5a\xc1\x50\x77\x3b\x6f\xe4\x7d\xbe\x03\x6c\x45\x58\x2e\xd6\x7e\x23\xf4\xc7\x45\x85\xda\xb5\x09\xdf\x1b\x83\x61\x05\x64\x54\x56\x42\xb2\xb1\xec\x46\x3e\x18\x04\x8f\xc2\x34\x77\xc6\xb2\xaa\x03\x55\x94\xec\xd3\x37\x91\xaf\x6a\xf4\xcb\xc2\xa1\x16\x6a\xba\x8d\x62\x8c\x57\xe7\x07\xf0\xb0\xe8\x70\x7c\xaf\x91\xcd\x44\xbd\xb9\x15\xe0\x29\x6e\x01\x90\xd5\x6d\x33\xd8\xdd\xe1\x0b\x5b\x60\x37\x78\x38\x97\x3c\x1d\x94\x3c\x22\xed\x33\x5e",
+ "\xa0\x3c\x6b\x5b\x51\xae\x4a\xa0\x09\x12\xaf\x1c\xfb\x6c\x7b\x96\x0e\xf5\x80\x36\x15\x64\x97\xcc\x56\x7b\x13\x69\x14\x9a\x59\x49",
+ 140 },
+ { GCRY_MD_SHA3_256,
+ "\x21\x67\xf0\x21\x18\xcc\x62\x04\x3e\x90\x91\xa6\x47\xca\xdb\xed\x95\x61\x1a\x52\x1f\xe0\xd6\x4e\x85\x18\xf1\x6c\x80\x8a\xb2\x97\x72\x55\x98\xae\x29\x68\x80\xa7\x73\x60\x7a\x79\x8f\x7c\x3c\xfc\xe8\x0d\x25\x1e\xbe\xc6\x88\x50\x15\xf9\xab\xf7\xea\xab\xae\x46\x79\x8f\x82\xcb\x59\x26\xde\x5c\x23\xf4\x4a\x3f\x9f\x95\x34\xb3\xc6\xf4\x05\xb5\x36\x4c\x2f\x8a\x8b\xdc\x5c\xa4\x9c\x74\x9b\xed\x8c\xe4\xba\x48\x89\x70\x62\xae\x84\x24\xca\x6d\xde\x5f\x55\xc0\xe4\x2a\x95\xd1\xe2\x92\xca\x54\xfb\x46\xa8\x4f\xbc\x9c\xd8\x7f\x2d\x0c\x9e\x74\x48\xde\x30\x43\xae\x22\xfd\xd2\x29",
+ "\x14\xc6\x9c\x5e\xab\xde\xfc\x9e\x3a\x14\x61\xa3\x79\xec\x92\xc3\x2b\xc6\xb6\x90\x71\x02\x9c\xb3\x65\x51\x59\xdb\x1a\x52\x51\xa7",
+ 141 },
+ { GCRY_MD_SHA3_256,
+ "\x94\xb7\xfa\x0b\xc1\xc4\x4e\x94\x9b\x1d\x76\x17\xd3\x1b\x47\x20\xcb\xe7\xca\x57\xc6\xfa\x4f\x40\x94\xd4\x76\x15\x67\xe3\x89\xec\xc6\x4f\x69\x68\xe4\x06\x4d\xf7\x0d\xf8\x36\xa4\x7d\x0c\x71\x33\x36\xb5\x02\x8b\x35\x93\x0d\x29\xeb\x7a\x7f\x9a\x5a\xf9\xad\x5c\xf4\x41\x74\x5b\xae\xc9\xbb\x01\x4c\xee\xff\x5a\x41\xba\x5c\x1c\xe0\x85\xfe\xb9\x80\xba\xb9\xcf\x79\xf2\x15\x8e\x03\xef\x7e\x63\xe2\x9c\x38\xd7\x81\x6a\x84\xd4\xf7\x1e\x0f\x54\x8b\x7f\xc3\x16\x08\x5a\xe3\x8a\x06\x0f\xf9\xb8\xde\xc3\x6f\x91\xad\x9e\xbc\x0a\x5b\x6c\x33\x8c\xbb\x8f\x66\x59\xd3\x42\xa2\x43\x68\xcf",
+ "\x3c\xbe\x06\x88\x7c\x8a\xe3\x60\xe9\x57\xeb\x08\xca\x57\x78\x34\xc4\x57\xfa\xdf\x41\x8d\x0c\xb7\x39\x67\xfa\x82\x7a\x22\xa4\xd7",
+ 142 },
+ { GCRY_MD_SHA3_256,
+ "\xea\x40\xe8\x3c\xb1\x8b\x3a\x24\x2c\x1e\xcc\x6c\xcd\x0b\x78\x53\xa4\x39\xda\xb2\xc5\x69\xcf\xc6\xdc\x38\xa1\x9f\x5c\x90\xac\xbf\x76\xae\xf9\xea\x37\x42\xff\x3b\x54\xef\x7d\x36\xeb\x7c\xe4\xff\x1c\x9a\xb3\xbc\x11\x9c\xff\x6b\xe9\x3c\x03\xe2\x08\x78\x33\x35\xc0\xab\x81\x37\xbe\x5b\x10\xcd\xc6\x6f\xf3\xf8\x9a\x1b\xdd\xc6\xa1\xee\xd7\x4f\x50\x4c\xbe\x72\x90\x69\x0b\xb2\x95\xa8\x72\xb9\xe3\xfe\x2c\xee\x9e\x6c\x67\xc4\x1d\xb8\xef\xd7\xd8\x63\xcf\x10\xf8\x40\xfe\x61\x8e\x79\x36\xda\x3d\xca\x5c\xa6\xdf\x93\x3f\x24\xf6\x95\x4b\xa0\x80\x1a\x12\x94\xcd\x8d\x7e\x66\xdf\xaf\xec",
+ "\xe5\x8a\x94\x7e\x98\xd6\xdd\x7e\x93\x2d\x2f\xe0\x2d\x99\x92\xe6\x11\x8c\x0c\x2c\x60\x6b\xdc\xda\x06\xe7\x94\x3d\x2c\x95\xe0\xe5",
+ 143 },
+ { GCRY_MD_SHA3_256,
+ "\x15\x7d\x5b\x7e\x45\x07\xf6\x6d\x9a\x26\x74\x76\xd3\x38\x31\xe7\xbb\x76\x8d\x4d\x04\xcc\x34\x38\xda\x12\xf9\x01\x02\x63\xea\x5f\xca\xfb\xde\x25\x79\xdb\x2f\x6b\x58\xf9\x11\xd5\x93\xd5\xf7\x9f\xb0\x5f\xe3\x59\x6e\x3f\xa8\x0f\xf2\xf7\x61\xd1\xb0\xe5\x70\x80\x05\x5c\x11\x8c\x53\xe5\x3c\xdb\x63\x05\x52\x61\xd7\xc9\xb2\xb3\x9b\xd9\x0a\xcc\x32\x52\x0c\xbb\xdb\xda\x2c\x4f\xd8\x85\x6d\xbc\xee\x17\x31\x32\xa2\x67\x91\x98\xda\xf8\x30\x07\xa9\xb5\xc5\x15\x11\xae\x49\x76\x6c\x79\x2a\x29\x52\x03\x88\x44\x4e\xbe\xfe\x28\x25\x6f\xb3\x3d\x42\x60\x43\x9c\xba\x73\xa9\x47\x9e\xe0\x0c\x63",
+ "\xa9\x36\xfb\x9a\xf8\x7f\xb6\x78\x57\xb3\xea\xd5\xc7\x62\x26\xad\x84\xda\x47\x67\x8f\x3c\x2f\xfe\x5a\x39\xfd\xb5\xf7\xe6\x3f\xfb",
+ 144 },
+ { GCRY_MD_SHA3_256,
+ "\x83\x6b\x34\xb5\x15\x47\x6f\x61\x3f\xe4\x47\xa4\xe0\xc3\xf3\xb8\xf2\x09\x10\xac\x89\xa3\x97\x70\x55\xc9\x60\xd2\xd5\xd2\xb7\x2b\xd8\xac\xc7\x15\xa9\x03\x53\x21\xb8\x67\x03\xa4\x11\xdd\xe0\x46\x6d\x58\xa5\x97\x69\x67\x2a\xa6\x0a\xd5\x87\xb8\x48\x1d\xe4\xbb\xa5\x52\xa1\x64\x57\x79\x78\x95\x01\xec\x53\xd5\x40\xb9\x04\x82\x1f\x32\xb0\xbd\x18\x55\xb0\x4e\x48\x48\xf9\xf8\xcf\xe9\xeb\xd8\x91\x1b\xe9\x57\x81\xa7\x59\xd7\xad\x97\x24\xa7\x10\x2d\xbe\x57\x67\x76\xb7\xc6\x32\xbc\x39\xb9\xb5\xe1\x90\x57\xe2\x26\x55\x2a\x59\x94\xc1\xdb\xb3\xb5\xc7\x87\x1a\x11\xf5\x53\x70\x11\x04\x4c\x53",
+ "\x3a\x65\x4b\x88\xf8\x80\x86\xc2\x75\x1e\xda\xe6\xd3\x92\x48\x14\x3c\xf6\x23\x5c\x6b\x0b\x79\x69\x34\x2c\x45\xa3\x51\x94\xb6\x7e",
+ 145 },
+ { GCRY_MD_SHA3_256,
+ "\xcc\x77\x84\xa4\x91\x2a\x7a\xb5\xad\x36\x20\xaa\xb2\x9b\xa8\x70\x77\xcd\x3c\xb8\x36\x36\xad\xc9\xf3\xdc\x94\xf5\x1e\xdf\x52\x1b\x21\x61\xef\x10\x8f\x21\xa0\xa2\x98\x55\x79\x81\xc0\xe5\x3c\xe6\xce\xd4\x5b\xdf\x78\x2c\x1e\xf2\x00\xd2\x9b\xab\x81\xdd\x64\x60\x58\x69\x64\xed\xab\x7c\xeb\xdb\xbe\xc7\x5f\xd7\x92\x50\x60\xf7\xda\x2b\x85\x3b\x2b\x08\x95\x88\xfa\x0f\x8c\x16\xec\x64\x98\xb1\x4c\x55\xdc\xee\x33\x5c\xb3\xa9\x1d\x69\x8e\x4d\x39\x3a\xb8\xe8\xea\xc0\x82\x5f\x8a\xde\xbe\xee\x19\x6d\xf4\x12\x05\xc0\x11\x67\x4e\x53\x42\x6c\xaa\x45\x3f\x8d\xe1\xcb\xb5\x79\x32\xb0\xb7\x41\xd4\xc6",
+ "\x19\xa3\xcb\x3e\x85\x51\xf0\x8f\xbb\xa5\xdb\x61\x4e\x26\x8f\x63\xd1\xf6\xa0\xc3\x68\x9b\xbe\x97\x3d\x59\xd3\x5b\xb4\xf4\x55\xd0",
+ 146 },
+ { GCRY_MD_SHA3_256,
+ "\x76\x39\xb4\x61\xff\xf2\x70\xb2\x45\x5a\xc1\xd1\xaf\xce\x78\x29\x44\xae\xa5\xe9\x08\x7e\xb4\xa3\x9e\xb9\x6b\xb5\xc3\xba\xaf\x0e\x86\x8c\x85\x26\xd3\x40\x4f\x94\x05\xe7\x9e\x77\xbf\xac\x5f\xfb\x89\xbf\x19\x57\xb5\x23\xe1\x7d\x34\x1d\x73\x23\xc3\x02\xea\x70\x83\x87\x2d\xd5\xe8\x70\x56\x94\xac\xdd\xa3\x6d\x5a\x1b\x89\x5a\xaa\x16\xec\xa6\x10\x4c\x82\x68\x85\x32\xc8\xbf\xe1\x79\x0b\x5d\xc9\xf4\xec\x5f\xe9\x5b\xae\xd3\x7e\x1d\x28\x7b\xe7\x10\x43\x1f\x1e\x5e\x8e\xe1\x05\xbc\x42\xed\x37\xd7\x4b\x1e\x55\x98\x4b\xf1\xc0\x9f\xe6\xa1\xfa\x13\xef\x3b\x96\xfa\xea\xed\x6a\x2a\x19\x50\xa1\x21\x53",
+ "\xca\x8c\xfb\x13\x97\x3f\xf8\x59\x7d\x6a\xaa\x80\x6b\xd3\x2e\x82\xf4\xea\x68\xba\xc3\xfb\x54\x3f\x26\x68\x7d\xe4\xb9\xcb\xe8\xbd",
+ 147 },
+ { GCRY_MD_SHA3_256,
+ "\xeb\x65\x13\xfc\x61\xb3\x0c\xfb\xa5\x8d\x4d\x7e\x80\xf9\x4d\x14\x58\x90\x90\xcf\x1d\x80\xb1\xdf\x2e\x68\x08\x8d\xc6\x10\x49\x59\xba\x0d\x58\x3d\x58\x5e\x95\x78\xab\x0a\xec\x0c\xf3\x6c\x48\x43\x5e\xb5\x2e\xd9\xab\x4b\xbc\xe7\xa5\xab\xe6\x79\xc9\x7a\xe2\xdb\xe3\x5e\x8c\xc1\xd4\x5b\x06\xdd\xa3\xcf\x41\x86\x65\xc5\x7c\xbe\xe4\xbb\xb4\x7f\xa4\xca\xf7\x8f\x4e\xe6\x56\xfe\xc2\x37\xfe\x4e\xeb\xba\xfa\x20\x6e\x1e\xf2\xbd\x0e\xe4\xae\x71\xbd\x0e\x9b\x2f\x54\xf9\x1d\xaa\xdf\x1f\xeb\xfd\x70\x32\x38\x1d\x63\x6b\x73\x3d\xcb\x3b\xf7\x6f\xb1\x4e\x23\xaf\xf1\xf6\x8e\xd3\xdb\xcf\x75\xc9\xb9\x9c\x6f\x26",
+ "\x9a\xe6\x70\xfa\x85\xab\x5c\x6b\x3b\xc7\x67\x97\xcf\x24\xcd\x38\x51\x10\x70\x81\x37\xb6\xf8\xef\xd8\xd1\xa2\x1c\x39\x88\x1c\x18",
+ 148 },
+ { GCRY_MD_SHA3_256,
+ "\x15\x94\xd7\x4b\xf5\xdd\xe4\x44\x26\x5d\x4c\x04\xda\xd9\x72\x1f\xf3\xe3\x4c\xbf\x62\x2d\xaf\x34\x1f\xe1\x6b\x96\x43\x1f\x6c\x4d\xf1\xf7\x60\xd3\x4f\x29\x6e\xb9\x7d\x98\xd5\x60\xad\x52\x86\xfe\xc4\xdc\xe1\x72\x4f\x20\xb5\x4f\xd7\xdf\x51\xd4\xbf\x13\x7a\xdd\x65\x6c\x80\x54\x6f\xb1\xbf\x51\x6d\x62\xee\x82\xba\xa9\x92\x91\x0e\xf4\xcc\x18\xb7\x0f\x3f\x86\x98\x27\x6f\xcf\xb4\x4e\x0e\xc5\x46\xc2\xc3\x9c\xfd\x8e\xe9\x10\x34\xff\x93\x03\x05\x8b\x42\x52\x46\x2f\x86\xc8\x23\xeb\x15\xbf\x48\x1e\x6b\x79\xcc\x3a\x02\x21\x85\x95\xb3\x65\x8e\x8b\x37\x38\x2b\xd5\x04\x8e\xae\xd5\xfd\x02\xc3\x79\x44\xe7\x3b",
+ "\xe3\x2d\xf6\x21\x8b\xa7\x5f\xd4\x78\x8a\x7e\x57\x27\xa7\xd6\x8c\x58\x29\xc4\x93\x46\x68\x3f\xc2\x13\xe4\x33\xaf\x3d\xba\x5a\xb5",
+ 149 },
+ { GCRY_MD_SHA3_256,
+ "\x4c\xfa\x12\x78\x90\x30\x26\xf6\x6f\xed\xd4\x13\x74\x55\x8b\xe1\xb5\x85\xd0\x3c\x5c\x55\xda\xc9\x43\x61\xdf\x28\x6d\x4b\xd3\x9c\x7c\xb8\x03\x7e\xd3\xb2\x67\xb0\x7c\x34\x66\x26\x44\x9d\x0c\xc5\xb0\xdd\x2c\xf2\x21\xf7\xe4\xc3\x44\x9a\x4b\xe9\x99\x85\xd2\xd5\xe6\x7b\xff\x29\x23\x35\x7d\xde\xab\x5a\xbc\xb4\x61\x9f\x3a\x3a\x57\xb2\xcf\x92\x8a\x02\x2e\xb2\x76\x76\xc6\xcf\x80\x56\x89\x00\x4f\xca\x4d\x41\xea\x6c\x2d\x0a\x47\x89\xc7\x60\x5f\x7b\xb8\x38\xdd\x88\x3b\x3a\xd3\xe6\x02\x7e\x77\x5b\xcf\x26\x28\x81\x42\x80\x99\xc7\xff\xf9\x5b\x14\xc0\x95\xea\x13\x0e\x0b\x99\x38\xa5\xe2\x2f\xc5\x26\x50\xf5\x91",
+ "\x02\x81\x73\xe3\xc6\xc3\x92\xe5\xd1\x3a\xf7\x48\xf3\x78\x8d\x43\x44\x9b\xc5\xdd\x59\x53\x12\x4e\xa5\xed\xf3\x93\x02\x75\xf6\x65",
+ 150 },
+ { GCRY_MD_SHA3_256,
+ "\xd3\xe6\x5c\xb9\x2c\xfa\x79\x66\x2f\x6a\xf4\x93\xd6\x96\xa0\x7c\xcf\x32\xaa\xad\xcc\xef\xf0\x6e\x73\xe8\xd9\xf6\xf9\x09\x20\x9e\x66\x71\x5d\x6e\x97\x87\x88\xc4\x9e\xfb\x90\x87\xb1\x70\xec\xf3\xaa\x86\xd2\xd4\xd1\xa0\x65\xae\x0e\xfc\x89\x24\xf3\x65\xd6\x76\xb3\xcb\x9e\x2b\xec\x91\x8f\xd9\x6d\x0b\x43\xde\xe8\x37\x27\xc9\xa9\x3b\xf5\x6c\xa2\xb2\xe5\x9a\xdb\xa8\x56\x96\x54\x6a\x81\x50\x67\xfc\x7a\x78\x03\x96\x29\xd4\x94\x8d\x15\x7e\x7b\x0d\x82\x6d\x1b\xf8\xe8\x12\x37\xba\xb7\x32\x13\x12\xfd\xaa\x4d\x52\x17\x44\xf9\x88\xdb\x6f\xdf\x04\x54\x9d\x0f\xdc\xa3\x93\xd6\x39\xc7\x29\xaf\x71\x6e\x9c\x8b\xba\x48",
+ "\x97\x45\x0f\xc4\x6f\x2e\x5d\xf8\xf8\x16\x23\xb1\xcc\xa4\x3f\xa5\x0f\x51\xea\x73\x5e\x44\x21\xd7\xdf\xf6\x63\x14\xd8\xe2\x11\xbc",
+ 151 },
+ { GCRY_MD_SHA3_256,
+ "\x84\x2c\xc5\x83\x50\x45\x39\x62\x2d\x7f\x71\xe7\xe3\x18\x63\xa2\xb8\x85\xc5\x6a\x0b\xa6\x2d\xb4\xc2\xa3\xf2\xfd\x12\xe7\x96\x60\xdc\x72\x05\xca\x29\xa0\xdc\x0a\x87\xdb\x4d\xc6\x2e\xe4\x7a\x41\xdb\x36\xb9\xdd\xb3\x29\x3b\x9a\xc4\xba\xae\x7d\xf5\xc6\xe7\x20\x1e\x17\xf7\x17\xab\x56\xe1\x2c\xad\x47\x6b\xe4\x96\x08\xad\x2d\x50\x30\x9e\x7d\x48\xd2\xd8\xde\x4f\xa5\x8a\xc3\xcf\xea\xfe\xee\x48\xc0\xa9\xee\xc8\x84\x98\xe3\xef\xc5\x1f\x54\xd3\x00\xd8\x28\xdd\xdc\xcb\x9d\x0b\x06\xdd\x02\x1a\x29\xcf\x5c\xb5\xb2\x50\x69\x15\xbe\xb8\xa1\x19\x98\xb8\xb8\x86\xe0\xf9\xb7\xa8\x0e\x97\xd9\x1a\x7d\x01\x27\x0f\x9a\x77\x17",
+ "\xab\x4e\x5a\x70\x39\x05\x77\xf8\xae\x26\x0d\x53\xcb\x0e\x70\x91\x4f\x8b\x93\x98\xab\xaa\x84\x1f\x78\x07\xf1\x47\x60\x46\xc6\x4f",
+ 152 },
+ { GCRY_MD_SHA3_256,
+ "\x6c\x4b\x0a\x07\x19\x57\x3e\x57\x24\x86\x61\xe9\x8f\xeb\xe3\x26\x57\x1f\x9a\x1c\xa8\x13\xd3\x63\x85\x31\xae\x28\xb4\x86\x0f\x23\xc3\xa3\xa8\xac\x1c\x25\x00\x34\xa6\x60\xe2\xd7\x1e\x16\xd3\xac\xc4\xbf\x9c\xe2\x15\xc6\xf1\x5b\x1c\x0f\xc7\xe7\x7d\x3d\x27\x15\x7e\x66\xda\x9c\xee\xc9\x25\x8f\x8f\x2b\xf9\xe0\x2b\x4a\xc9\x37\x93\xdd\x6e\x29\xe3\x07\xed\xe3\x69\x5a\x0d\xf6\x3c\xbd\xc0\xfc\x66\xfb\x77\x08\x13\xeb\x14\x9c\xa2\xa9\x16\x91\x1b\xee\x49\x02\xc4\x7c\x78\x02\xe6\x9e\x40\x5f\xe3\xc0\x4c\xeb\x55\x22\x79\x2a\x55\x03\xfa\x82\x9f\x70\x72\x72\x22\x66\x21\xf7\xc4\x88\xa7\x69\x8c\x0d\x69\xaa\x56\x1b\xe9\xf3\x78",
+ "\x81\x18\xf2\xc1\x57\xdf\x12\x50\xdb\x43\xb3\x11\x83\xf4\x42\xf8\x9b\x32\x2e\x49\x69\x18\x83\x8c\x5b\x66\x8f\x96\x47\xac\x6d\x6b",
+ 153 },
+ { GCRY_MD_SHA3_256,
+ "\x51\xb7\xdb\xb7\xce\x2f\xfe\xb4\x27\xa9\x1c\xcf\xe5\x21\x8f\xd4\x0f\x9e\x0b\x7e\x24\x75\x6d\x4c\x47\xcd\x55\x60\x60\x08\xbd\xc2\x7d\x16\x40\x09\x33\x90\x6f\xd9\xf3\x0e\xff\xdd\x48\x80\x02\x2d\x08\x11\x55\x34\x2a\xf3\xfb\x6c\xd5\x36\x72\xab\x7f\xb5\xb3\xa3\xbc\xbe\x47\xbe\x1f\xd3\xa2\x27\x8c\xae\x8a\x5f\xd6\x1c\x14\x33\xf7\xd3\x50\x67\x5d\xd2\x18\x03\x74\x6c\xad\xca\x57\x41\x30\xf0\x12\x00\x02\x4c\x63\x40\xab\x0c\xc2\xcf\x74\xf2\x23\x46\x69\xf3\x4e\x90\x09\xef\x2e\xb9\x48\x23\xd6\x2b\x31\x40\x7f\x4b\xa4\x6f\x1a\x1e\xec\x41\x64\x1e\x84\xd7\x77\x27\xb5\x9e\x74\x6b\x8a\x67\x1b\xef\x93\x6f\x05\xbe\x82\x07\x59\xfa",
+ "\x73\x6e\x30\xac\xcc\x55\x59\x18\x84\x12\xc7\x97\xa1\xa5\xbe\x61\xd1\xf9\x0f\x14\x94\x01\xf6\x31\x59\x79\x44\x15\x5a\x85\xfa\xf7",
+ 154 },
+ { GCRY_MD_SHA3_256,
+ "\x83\x59\x9d\x93\xf5\x56\x1e\x82\x1b\xd0\x1a\x47\x23\x86\xbc\x2f\xf4\xef\xbd\x4a\xed\x60\xd5\x82\x1e\x84\xaa\xe7\x4d\x80\x71\x02\x98\x10\xf5\xe2\x86\xf8\xf1\x76\x51\xcd\x27\xda\x07\xb1\xeb\x43\x82\xf7\x54\xcd\x1c\x95\x26\x87\x83\xad\x09\x22\x0f\x55\x02\x84\x03\x70\xd4\x94\xbe\xb1\x71\x24\x22\x0f\x6a\xfc\xe9\x1e\xc8\xa0\xf5\x52\x31\xf9\x65\x24\x33\xe5\xce\x34\x89\xb7\x27\x71\x6c\xf4\xae\xba\x7d\xcd\xa2\x0c\xd2\x9a\xa9\xa8\x59\x20\x12\x53\xf9\x48\xdd\x94\x39\x5a\xba\x9e\x38\x52\xbd\x1d\x60\xdd\xa7\xae\x5d\xc0\x45\xb2\x83\xda\x00\x6e\x1c\xba\xd8\x3c\xc1\x32\x92\xa3\x15\xdb\x55\x53\x30\x5c\x62\x8d\xd0\x91\x14\x65\x97",
+ "\x95\x99\xde\xec\xcc\x69\x8a\x24\xa4\x61\xa7\x41\x9e\x91\x93\x9c\x74\x16\x13\xf4\xce\x88\x7d\xba\x89\xdc\x7e\x32\x7c\x51\xf5\xbf",
+ 155 },
+ { GCRY_MD_SHA3_256,
+ "\x2b\xe9\xbf\x52\x6c\x9d\x5a\x75\xd5\x65\xdd\x11\xef\x63\xb9\x79\xd0\x68\x65\x9c\x7f\x02\x6c\x08\xbe\xa4\xaf\x16\x1d\x85\xa4\x62\xd8\x0e\x45\x04\x0e\x91\xf4\x16\x5c\x07\x4c\x43\xac\x66\x13\x80\x31\x1a\x8c\xbe\xd5\x9c\xc8\xe4\xc4\x51\x8e\x80\xcd\x2c\x78\xab\x1c\xab\xf6\x6b\xff\x83\xea\xb3\xa8\x01\x48\x55\x03\x07\x31\x09\x50\xd0\x34\xa6\x28\x6c\x93\xa1\xec\xe8\x92\x9e\x63\x85\xc5\xe3\xbb\x6e\xa8\xa7\xc0\xfb\x6d\x63\x32\xe3\x20\xe7\x1c\xc4\xeb\x46\x2a\x2a\x62\xe2\xbf\xe0\x8f\x0c\xca\xd9\x3e\x61\xbe\xdb\x5d\xd0\xb7\x86\xa7\x28\xab\x66\x6f\x07\xe0\x57\x6d\x18\x9c\x92\xbf\x9f\xb2\x0d\xca\x49\xac\x2d\x39\x56\xd4\x73\x85\xe2",
+ "\xbe\x0d\x87\x16\x06\xa4\xc1\x29\xce\xf6\x16\xf4\x38\x60\x0d\x5c\xbc\x0e\x9f\x49\xd2\xad\xc8\xa8\x65\x71\xc1\x92\x36\x1c\x3f\x4f",
+ 156 },
+ { GCRY_MD_SHA3_256,
+ "\xca\x76\xd3\xa1\x25\x95\xa8\x17\x68\x26\x17\x00\x68\x48\x67\x55\x47\xd3\xe8\xf5\x0c\x22\x10\xf9\xaf\x90\x6c\x0e\x7c\xe5\x0b\x44\x60\x18\x6f\xe7\x04\x57\xa9\xe8\x79\xe7\x9f\xd4\xd1\xa6\x88\xc7\x0a\x34\x73\x61\xc8\x47\xba\x0d\xd6\xaa\x52\x93\x6e\xaf\x8e\x58\xa1\xbe\x2f\x5c\x1c\x70\x4e\x20\x14\x6d\x36\x6a\xeb\x38\x53\xbe\xd9\xde\x9b\xef\xe9\x56\x9a\xc8\xaa\xea\x37\xa9\xfb\x71\x39\xa1\xa1\xa7\xd5\xc7\x48\x60\x5a\x8d\xef\xb2\x97\x86\x9e\xbe\xdd\x71\xd6\x15\xa5\xda\x23\x49\x6d\x11\xe1\x1a\xbb\xb1\x26\xb2\x06\xfa\x0a\x77\x97\xee\x7d\xe1\x17\x98\x60\x12\xd0\x36\x2d\xce\xf7\x75\xc2\xfe\x14\x5a\xda\x6b\xda\x1c\xcb\x32\x6b\xf6\x44",
+ "\x4d\x30\x60\x0c\x60\xed\x94\xa0\xd2\xbc\xc1\x75\x71\xa1\x9b\xd0\x17\x0c\xda\xca\xc7\x8d\x04\x21\xe0\xbb\xae\x2a\x36\xa4\x8b\x6d",
+ 157 },
+ { GCRY_MD_SHA3_256,
+ "\xf7\x6b\x85\xdc\x67\x42\x10\x25\xd6\x4e\x93\x09\x6d\x1d\x71\x2b\x7b\xaf\x7f\xb0\x01\x71\x6f\x02\xd3\x3b\x21\x60\xc2\xc8\x82\xc3\x10\xef\x13\xa5\x76\xb1\xc2\xd3\x0e\xf8\xf7\x8e\xf8\xd2\xf4\x65\x00\x71\x09\xaa\xd9\x3f\x74\xcb\x9e\x7d\x7b\xef\x7c\x95\x90\xe8\xaf\x3b\x26\x7c\x89\xc1\x5d\xb2\x38\x13\x8c\x45\x83\x3c\x98\xcc\x4a\x47\x1a\x78\x02\x72\x3e\xf4\xc7\x44\xa8\x53\xcf\x80\xa0\xc2\x56\x8d\xd4\xed\x58\xa2\xc9\x64\x48\x06\xf4\x21\x04\xce\xe5\x36\x28\xe5\xbd\xf7\xb6\x3b\x0b\x33\x8e\x93\x1e\x31\xb8\x7c\x24\xb1\x46\xc6\xd0\x40\x60\x55\x67\xce\xef\x59\x60\xdf\x9e\x02\x2c\xb4\x69\xd4\xc7\x87\xf4\xcb\xa3\xc5\x44\xa1\xac\x91\xf9\x5f",
+ "\x3b\xd6\xfb\x72\x76\x4f\x7a\xd4\x39\x1b\x7b\x40\xae\xa4\x24\xab\xd5\xf5\x56\x1a\xc5\x6f\x9e\x07\x2c\x75\x3d\x60\x90\xfa\x4b\xfb",
+ 158 },
+ { GCRY_MD_SHA3_256,
+ "\x25\xb8\xc9\xc0\x32\xea\x6b\xcd\x73\x3f\xfc\x87\x18\xfb\xb2\xa5\x03\xa4\xea\x8f\x71\xde\xa1\x17\x61\x89\xf6\x94\x30\x4f\x0f\xf6\x8e\x86\x2a\x81\x97\xb8\x39\x95\x75\x49\xef\x24\x3a\x52\x79\xfc\x26\x46\xbd\x4c\x00\x9b\x6d\x1e\xde\xbf\x24\x73\x81\x97\xab\xb4\xc9\x92\xf6\xb1\xdc\x9b\xa8\x91\xf5\x70\x87\x9a\xcc\xd5\xa6\xb1\x86\x91\xa9\x3c\x7d\x0a\x8d\x38\xf9\x5b\x63\x9c\x1d\xae\xb4\x8c\x4c\x2f\x15\xcc\xf5\xb9\xd5\x08\xf8\x33\x3c\x32\xde\x78\x78\x1b\x41\x85\x0f\x26\x1b\x85\x5c\x4b\xeb\xcc\x12\x5a\x38\x0c\x54\xd5\x01\xc5\xd3\xbd\x07\xe6\xb5\x21\x02\x11\x60\x88\xe5\x3d\x76\x58\x3b\x01\x61\xe2\xa5\x8d\x07\x78\xf0\x91\x20\x6a\xab\xd5\xa1",
+ "\x66\x89\xbb\x25\xba\xee\x0c\x58\x2f\x8f\x1b\x0c\x87\x07\x3b\xe3\x66\x64\x4d\xa8\x59\x31\x3b\xec\xf4\x46\x43\x5d\x2f\x6e\x89\x9e",
+ 159 },
+ { GCRY_MD_SHA3_256,
+ "\x21\xcf\xdc\x2a\x7c\xcb\x7f\x33\x1b\x3d\x2e\xef\xff\x37\xe4\x8a\xd9\xfa\x9c\x78\x8c\x3f\x3c\x20\x0e\x01\x73\xd9\x99\x63\xe1\xcb\xca\x93\x62\x3b\x26\x4e\x92\x03\x94\xae\x48\xbb\x4c\x3a\x5b\xb9\x6f\xfb\xc8\xf0\xe5\x3f\x30\xe2\x29\x56\xad\xab\xc2\x76\x5f\x57\xfb\x76\x1e\x14\x7e\xcb\xf8\x56\x75\x33\xdb\x6e\x50\xc8\xa1\xf8\x94\x31\x0a\x94\xed\xf8\x06\xdd\x8c\xa6\xa0\xe1\x41\xc0\xfa\x7c\x9f\xae\x6c\x6a\xe6\x5f\x18\xc9\x3a\x85\x29\xe6\xe5\xb5\x53\xbf\x55\xf2\x5b\xe2\xe8\x0a\x98\x82\xbd\x37\xf1\x45\xfe\xcb\xeb\x3d\x44\x7a\x3c\x4e\x46\xc2\x15\x24\xcc\x55\xcd\xd6\x2f\x52\x1a\xb9\x2a\x8b\xa7\x2b\x89\x79\x96\xc4\x9b\xb2\x73\x19\x8b\x7b\x1c\x9e",
+ "\x26\x28\xdd\xc7\x75\x82\x08\xaa\x9f\x1e\x49\x49\x72\x24\xeb\x26\x8c\x6d\x2b\xcd\xaa\xb4\x82\x0d\xe9\xc1\x6a\x65\xc6\xf6\x01\x7a",
+ 160 },
+ { GCRY_MD_SHA3_256,
+ "\x4e\x45\x2b\xa4\x21\x27\xdc\xc9\x56\xef\x4f\x8f\x35\xdd\x68\xcb\x22\x5f\xb7\x3b\x5b\xc7\xe1\xec\x5a\x89\x8b\xba\x29\x31\x56\x3e\x74\xfa\xff\x3b\x67\x31\x4f\x24\x1e\xc4\x9f\x4a\x70\x61\xe3\xbd\x02\x13\xae\x82\x6b\xab\x38\x0f\x1f\x14\xfa\xab\x8b\x0e\xfd\xdd\x5f\xd1\xbb\x49\x37\x38\x53\xa0\x8f\x30\x55\x3d\x5a\x55\xcc\xbb\xb8\x15\x3d\xe4\x70\x4f\x29\xca\x2b\xde\xef\x04\x19\x46\x8e\x05\xdd\x51\x55\x7c\xcc\x80\xc0\xa9\x61\x90\xbb\xcc\x4d\x77\xec\xff\x21\xc6\x6b\xdf\x48\x64\x59\xd4\x27\xf9\x86\x41\x0f\x88\x3a\x80\xa5\xbc\xc3\x2c\x20\xf0\x47\x8b\xb9\xa9\x7a\x12\x6f\xc5\xf9\x54\x51\xe4\x0f\x29\x2a\x46\x14\x93\x0d\x05\x4c\x85\x1a\xcd\x01\x9c\xcf",
+ "\xdf\x44\x89\x36\xee\x72\xd9\xfe\x6c\xcf\xb3\x7d\x18\x3a\xaf\xdd\xc7\x90\x8e\x01\x62\x71\xaf\xa8\x1e\xc0\x83\xa1\x0a\x14\x4f\x5d",
+ 161 },
+ { GCRY_MD_SHA3_256,
+ "\xfa\x85\x67\x1d\xf7\xda\xdf\x99\xa6\xff\xee\x97\xa3\xab\x99\x91\x67\x1f\x56\x29\x19\x50\x49\x88\x04\x97\x48\x78\x67\xa6\xc4\x46\xb6\x00\x87\xfa\xc9\xa0\xf2\xfc\xc8\xe3\xb2\x4e\x97\xe4\x23\x45\xb9\x3b\x5f\x7d\x36\x91\x82\x9d\x3f\x8c\xcd\x4b\xb3\x64\x11\xb8\x5f\xc2\x32\x8e\xb0\xc5\x1c\xb3\x15\x1f\x70\x86\x0a\xd3\x24\x6c\xe0\x62\x3a\x8d\xc8\xb3\xc4\x9f\x95\x8f\x86\x90\xf8\xe3\x86\x0e\x71\xeb\x2b\x14\x79\xa5\xce\xa0\xb3\xf8\xbe\xfd\x87\xac\xaf\x53\x62\x43\x5e\xae\xcc\xb5\x2f\x38\x61\x7b\xc6\xc5\xc2\xc6\xe2\x69\xea\xd1\xfb\xd6\x9e\x94\x1d\x4a\xd2\x01\x2d\xa2\xc5\xb2\x1b\xcf\xbf\x98\xe4\xa7\x7a\xb2\xaf\x1f\x3f\xda\x32\x33\xf0\x46\xd3\x8f\x1d\xc8",
+ "\x2b\xb4\xce\xc2\x2a\x4f\xec\xd8\x3f\xbb\xba\xd1\xe3\x83\x53\x43\xe3\x6c\x6c\xb6\x6c\x26\x96\x4a\x43\x2e\xc4\xc7\x0f\x3e\x17\xb4",
+ 162 },
+ { GCRY_MD_SHA3_256,
+ "\xe9\x08\x47\xae\x67\x97\xfb\xc0\xb6\xb3\x6d\x6e\x58\x8c\x0a\x74\x3d\x72\x57\x88\xca\x50\xb6\xd7\x92\x35\x2e\xa8\x29\x4f\x5b\xa6\x54\xa1\x53\x66\xb8\xe1\xb2\x88\xd8\x4f\x51\x78\x24\x08\x27\x97\x5a\x76\x3b\xc4\x5c\x7b\x04\x30\xe8\xa5\x59\xdf\x44\x88\x50\x5e\x00\x9c\x63\xda\x99\x4f\x14\x03\xf4\x07\x95\x82\x03\xce\xbb\x6e\x37\xd8\x9c\x94\xa5\xea\xcf\x60\x39\xa3\x27\xf6\xc4\xdb\xbc\x7a\x2a\x30\x7d\x97\x6a\xa3\x9e\x41\xaf\x65\x37\x24\x3f\xc2\x18\xdf\xa6\xab\x4d\xd8\x17\xb6\xa3\x97\xdf\x5c\xa6\x91\x07\xa9\x19\x87\x99\xed\x24\x86\x41\xb6\x3b\x42\xcb\x4c\x29\xbf\xdd\x79\x75\xac\x96\xed\xfc\x27\x4a\xc5\x62\xd0\x47\x4c\x60\x34\x7a\x07\x8c\xe4\xc2\x5e\x88",
+ "\x14\x62\xf2\xea\x1c\x35\x80\xc0\xa2\xe8\xc0\xb3\x0c\x27\xa6\x08\xd8\x2c\xd7\x07\xf6\xd1\xa0\xaa\xd5\xcc\x7c\x3d\x1b\x8d\x6c\x30",
+ 163 },
+ { GCRY_MD_SHA3_256,
+ "\xf6\xd5\xc2\xb6\xc9\x39\x54\xfc\x62\x76\x02\xc0\x0c\x4c\xa9\xa7\xd3\xed\x12\xb2\x71\x73\xf0\xb2\xc9\xb0\xe4\xa5\x93\x93\x98\xa6\x65\xe6\x7e\x69\xd0\xb1\x2f\xb7\xe4\xce\xb2\x53\xe8\x08\x3d\x1c\xeb\x72\x4a\xc0\x7f\x00\x9f\x09\x4e\x42\xf2\xd6\xf2\x12\x94\x89\xe8\x46\xea\xff\x07\x00\xa8\xd4\x45\x3e\xf4\x53\xa3\xed\xdc\x18\xf4\x08\xc7\x7a\x83\x27\x56\x17\xfa\xbc\x4e\xa3\xa2\x83\x3a\xa7\x34\x06\xc0\xe9\x66\x27\x60\x79\xd3\x8e\x8e\x38\x53\x9a\x70\xe1\x94\xcc\x55\x13\xaa\xa4\x57\xc6\x99\x38\x3f\xd1\x90\x0b\x1e\x72\xbd\xfb\x83\x5d\x1f\xd3\x21\xb3\x7b\xa8\x05\x49\xb0\x78\xa4\x9e\xa0\x81\x52\x86\x9a\x91\x8c\xa5\x7f\x5b\x54\xed\x71\xe4\xfd\x3a\xc5\xc0\x67\x29",
+ "\x61\x7b\x41\x2e\xd6\x4f\x56\xd6\xdb\x36\xb7\xe5\x2e\xad\x61\x8d\x95\xa0\x91\xd6\x50\x52\xc3\xf3\x76\xa5\x32\xd8\xbb\xda\xf7\xc7",
+ 164 },
+ { GCRY_MD_SHA3_256,
+ "\xcf\x85\x62\xb1\xbe\xd8\x98\x92\xd6\x7d\xda\xaf\x3d\xee\xb2\x82\x46\x45\x6e\x97\x23\x26\xdb\xcd\xb5\xcf\x3f\xb2\x89\xac\xa0\x1e\x68\xda\x5d\x59\x89\x6e\x3a\x61\x65\x35\x8b\x07\x1b\x30\x4d\x6a\xb3\xd0\x18\x94\x4b\xe5\x04\x9d\x5e\x0e\x2b\xb8\x19\xac\xf6\x7a\x60\x06\x11\x10\x89\xe6\x76\x71\x32\xd7\x2d\xd8\x5b\xed\xdc\xbb\x2d\x64\x49\x6d\xb0\xcc\x92\x95\x5a\xb4\xc6\x23\x4f\x1e\xea\x24\xf2\xd5\x14\x83\xf2\xe2\x09\xe4\x58\x9b\xf9\x51\x9f\xac\x51\xb4\xd0\x61\xe8\x01\x12\x5e\x60\x5f\x80\x93\xbb\x69\x97\xbc\x16\x3d\x55\x15\x96\xfe\x4a\xb7\xcf\xae\x8f\xb9\xa9\x0f\x69\x80\x48\x0c\xe0\xc2\x29\xfd\x16\x75\x40\x9b\xd7\x88\x35\x4d\xaf\x31\x62\x40\xcf\xe0\xaf\x93\xeb",
+ "\x82\xc5\x41\xea\x5c\xb1\x5d\x1a\x41\x25\xf5\x36\x82\x59\x38\xc2\x35\x8e\xec\x2b\xdd\xc5\xd1\xcc\x40\x42\xde\x3a\xf0\x36\xca\x55",
+ 165 },
+ { GCRY_MD_SHA3_256,
+ "\x2a\xce\x31\xab\xb0\xa2\xe3\x26\x79\x44\xd2\xf7\x5e\x15\x59\x98\x5d\xb7\x35\x4c\x6e\x60\x5f\x18\xdc\x84\x70\x42\x3f\xca\x30\xb7\x33\x1d\x9b\x33\xc4\xa4\x32\x67\x83\xd1\xca\xae\x1b\x4f\x07\x06\x0e\xff\x97\x8e\x47\x46\xbf\x0c\x7e\x30\xcd\x61\x04\x0b\xd5\xec\x27\x46\xb2\x98\x63\xeb\x7f\x10\x3e\xbd\xa6\x14\xc4\x29\x1a\x80\x5b\x6a\x4c\x82\x14\x23\x05\x64\xa0\x55\x7b\xc7\x10\x2e\x0b\xd3\xed\x23\x71\x92\x52\xf7\x43\x5d\x64\xd2\x10\xee\x2a\xaf\xc5\x85\xbe\x90\x3f\xa4\x1e\x19\x68\xc5\x0f\xd5\xd5\x36\x79\x26\xdf\x7a\x05\xe3\xa4\x2c\xf0\x7e\x65\x6f\xf9\x2d\xe7\x3b\x03\x6c\xf8\xb1\x98\x98\xc0\xcb\x34\x55\x7c\x0c\x12\xc2\xd8\xb8\x4e\x91\x18\x1a\xf4\x67\xbc\x75\xa9\xd1",
+ "\x68\x4b\xb7\x93\x24\x33\x21\x8c\x61\x6f\x05\x90\xb0\x39\xce\xfa\xc9\x72\x82\x84\x70\x64\x7d\x15\x91\xce\xac\x88\x9c\x89\x32\x72",
+ 166 },
+ { GCRY_MD_SHA3_256,
+ "\x0d\x8d\x09\xae\xd1\x9f\x10\x13\x96\x9c\xe5\xe7\xeb\x92\xf8\x3a\x20\x9a\xe7\x6b\xe3\x1c\x75\x48\x44\xea\x91\x16\xce\xb3\x9a\x22\xeb\xb6\x00\x30\x17\xbb\xcf\x26\x55\x5f\xa6\x62\x41\x85\x18\x7d\xb8\xf0\xcb\x35\x64\xb8\xb1\xc0\x6b\xf6\x85\xd4\x7f\x32\x86\xed\xa2\x0b\x83\x35\x8f\x59\x9d\x20\x44\xbb\xf0\x58\x3f\xab\x8d\x78\xf8\x54\xfe\x0a\x59\x61\x83\x23\x0c\x5e\xf8\xe5\x44\x26\x75\x0e\xaf\x2c\xc4\xe2\x9d\x3b\xdd\x03\x7e\x73\x4d\x86\x3c\x2b\xd9\x78\x9b\x4c\x24\x30\x96\x13\x8f\x76\x72\xc2\x32\x31\x4e\xff\xdf\xc6\x51\x34\x27\xe2\xda\x76\x91\x6b\x52\x48\x93\x3b\xe3\x12\xeb\x5d\xde\x4c\xf7\x08\x04\xfb\x25\x8a\xc5\xfb\x82\xd5\x8d\x08\x17\x7a\xc6\xf4\x75\x60\x17\xff\xf5",
+ "\x50\x8b\x2a\xf3\x76\xba\x64\x67\xcf\x98\x2c\x76\x7c\x84\x8d\x2b\xda\x8d\x06\x8a\x53\x41\x6f\x07\x4a\x0c\x98\xc4\x73\xd0\x2f\x6b",
+ 167 },
+ { GCRY_MD_SHA3_256,
+ "\xc3\x23\x6b\x73\xde\xb7\x66\x2b\xf3\xf3\xda\xa5\x8f\x13\x7b\x35\x8b\xa6\x10\x56\x0e\xf7\x45\x57\x85\xa9\xbe\xfd\xb0\x35\xa0\x66\xe9\x07\x04\xf9\x29\xbd\x96\x89\xce\xf0\xce\x3b\xda\x5a\xcf\x44\x80\xbc\xeb\x8d\x09\xd1\x0b\x09\x8a\xd8\x50\x0d\x9b\x60\x71\xdf\xc3\xa1\x4a\xf6\xc7\x75\x11\xd8\x1e\x3a\xa8\x84\x49\x86\xc3\xbe\xa6\xf4\x69\xf9\xe0\x21\x94\xc9\x28\x68\xcd\x5f\x51\x64\x62\x56\x79\x8f\xf0\x42\x49\x54\xc1\x43\x4b\xdf\xed\x9f\xac\xb3\x90\xb0\x7d\x34\x2e\x99\x29\x36\xe0\xf8\x8b\xfd\x0e\x88\x4a\x0d\xdb\x67\x9d\x05\x47\xcc\xde\xc6\x38\x42\x85\xa4\x54\x29\xd1\x15\xac\x7d\x23\x5a\x71\x72\x42\x02\x1d\x1d\xc3\x56\x41\xf5\xf0\xa4\x8e\x84\x45\xdb\xa5\x8e\x6c\xb2\xc8\xea",
+ "\x55\xe2\x28\xbc\xbd\xa7\x06\x16\x42\xd0\x04\x37\x3d\x4e\x64\x07\xb7\x2a\x37\x38\x1d\x1b\xef\xfc\xbf\xbf\x9f\x5f\x6e\xa0\x93\xea",
+ 168 },
+ { GCRY_MD_SHA3_256,
+ "\xb3\x9f\xeb\x82\x83\xea\xdc\x63\xe8\x18\x4b\x51\xdf\x5a\xe3\xfd\x41\xaa\xc8\xa9\x63\xbb\x0b\xe1\xcd\x08\xaa\x58\x67\xd8\xd9\x10\xc6\x69\x22\x1e\x73\x24\x33\x60\x64\x6f\x65\x53\xd1\xca\x05\xa8\x4e\x8d\xc0\xde\x05\xb6\x41\x9e\xc3\x49\xca\x99\x44\x80\x19\x3d\x01\xc9\x25\x25\xf3\xfb\x3d\xce\xfb\x08\xaf\xc6\xd2\x69\x47\xbd\xbb\xfd\x85\x19\x3f\x53\xb5\x06\x09\xc6\x14\x09\x05\xc5\x3a\x66\x86\xb5\x8e\x53\xa3\x19\xa5\x7b\x96\x23\x31\xed\xe9\x81\x49\xaf\x3d\xe3\x11\x8a\x81\x9d\xa4\xd7\x67\x06\xa0\x42\x4b\x4e\x1d\x29\x10\xb0\xed\x26\xaf\x61\xd1\x50\xeb\xcb\x46\x59\x5d\x42\x66\xa0\xbd\x7f\x65\x1b\xa4\x7d\x0c\x7f\x17\x9c\xa2\x85\x45\x00\x7d\x92\xe8\x41\x9d\x48\xfd\xfb\xd7\x44\xce",
+ "\x05\x23\xc0\x9b\xbc\xff\xe4\x18\xd3\xfc\xd2\x2c\x6a\xbf\x95\xab\xfb\x38\xf9\x4c\xe5\x56\x2b\x8b\xfc\xd2\xee\xa9\xfb\x72\x90\x41",
+ 169 },
+ { GCRY_MD_SHA3_256,
+ "\xa9\x83\xd5\x4f\x50\x38\x03\xe8\xc7\x99\x9f\x4e\xdb\xbe\x82\xe9\x08\x4f\x42\x21\x43\xa9\x32\xdd\xdd\xc4\x7a\x17\xb0\xb7\x56\x4a\x7f\x37\xa9\x9d\x07\x86\xe9\x94\x76\x42\x8d\x29\xe2\x9d\x3c\x19\x7a\x72\xbf\xab\x13\x42\xc1\x2a\x0f\xc4\x78\x7f\xd7\x01\x7d\x7a\x61\x74\x04\x9e\xa4\x3b\x57\x79\x16\x9e\xf7\x47\x2b\xdb\xbd\x94\x1d\xcb\x82\xfc\x73\xaa\xc4\x5a\x8a\x94\xc9\xf2\xbd\x34\x77\xf6\x1f\xd3\xb7\x96\xf0\x2a\x1b\x82\x64\xa2\x14\xc6\xfe\xa7\x4b\x70\x51\xb2\x26\xc7\x22\x09\x9e\xc7\x88\x3a\x46\x2b\x83\xb6\xaf\xdd\x40\x09\x24\x8b\x8a\x23\x7f\x60\x5f\xe5\xa0\x8f\xe7\xd8\xb4\x53\x21\x42\x1e\xbb\xa6\x7b\xd7\x0a\x0b\x00\xdd\xbf\x94\xba\xab\x7f\x35\x9d\x5d\x1e\xea\x10\x5f\x28\xdc\xfb",
+ "\xdc\xbc\x25\x82\x41\xad\xed\x37\x99\x99\x6c\x2a\xd6\xed\x0e\x3d\x74\xcf\xcc\x67\x74\x9d\x34\x80\xb2\xa9\xa7\x8e\x5f\x8a\xff\x82",
+ 170 },
+ { GCRY_MD_SHA3_256,
+ "\xe4\xd1\xc1\x89\x7a\x0a\x86\x6c\xe5\x64\x63\x5b\x74\x22\x2f\x96\x96\xbf\x2c\x7f\x64\x0d\xd7\x8d\x7e\x2a\xca\x66\xe1\xb6\x1c\x64\x2b\xb0\x3e\xa7\x53\x6a\xae\x59\x78\x11\xe9\xbf\x4a\x7b\x45\x3e\xde\x31\xf9\x7b\x46\xa5\xf0\xef\x51\xa0\x71\xa2\xb3\x91\x8d\xf1\x6b\x15\x25\x19\xae\x37\x76\xf9\xf1\xed\xab\x4c\x2a\x37\x7c\x32\x92\xe9\x64\x08\x35\x9d\x36\x13\x84\x4d\x5e\xb3\x93\x00\x02\x83\xd5\xad\x34\x01\xa3\x18\xb1\x2f\xd1\x47\x4b\x86\x12\xf2\xbb\x50\xfb\x6a\x8b\x9e\x02\x3a\x54\xd7\xdd\xe2\x8c\x43\xd6\xd8\x85\x4c\x8d\x9d\x11\x55\x93\x5c\x19\x98\x11\xdb\xfc\x87\xe9\xe0\x07\x2e\x90\xeb\x88\x68\x1c\xc7\x52\x97\x14\xf8\xfb\x8a\x2c\x9d\x88\x56\x7a\xdf\xb9\x74\xee\x20\x5a\x9b\xf7\xb8\x48",
+ "\xcb\xe8\x31\x8e\x7b\x2f\xe7\x2b\xfc\xd2\x53\x0c\xcc\xec\xea\x40\x18\xb1\x58\x7f\x48\x3b\x73\xf5\x0c\xe5\xe8\x4c\xed\x65\xe0\x93",
+ 171 },
+ { GCRY_MD_SHA3_256,
+ "\xb1\x0c\x59\x72\x3e\x3d\xca\xdd\x6d\x75\xdf\x87\xd0\xa1\x58\x0e\x73\x13\x3a\x9b\x7d\x00\xcb\x95\xec\x19\xf5\x54\x70\x27\x32\x3b\xe7\x51\x58\xb1\x1f\x80\xb6\xe1\x42\xc6\xa7\x85\x31\x88\x6d\x90\x47\xb0\x8e\x55\x1e\x75\xe6\x26\x1e\x79\x78\x53\x66\xd7\x02\x4b\xd7\xcd\x9c\xf3\x22\xd9\xbe\x7d\x57\xfb\x66\x10\x69\xf2\x48\x1c\x7b\xb7\x59\xcd\x71\xb4\xb3\x6c\xa2\xbc\x2d\xf6\xd3\xa3\x28\xfa\xeb\xdb\x99\x5a\x97\x94\xa8\xd7\x21\x55\xed\x55\x1a\x1f\x87\xc8\x0b\xf6\x05\x9b\x43\xfc\x76\x49\x00\xb1\x8a\x1c\x24\x41\xf7\x48\x77\x43\xcf\x84\xe5\x65\xf6\x1f\x8d\xd2\xec\xe6\xb6\xcc\xc9\x44\x40\x49\x19\x7a\xaa\xf5\x3e\x92\x6f\xbe\xe3\xbf\xca\x8b\xe5\x88\xec\x77\xf2\x9d\x21\x1b\xe8\x9d\xe1\x8b\x15\xf6",
+ "\x8c\xea\x29\x60\x08\x70\x48\xe6\xe6\xd4\x7e\x31\x55\x4f\x30\x5f\xcc\x81\xe0\x3e\x90\xba\x8f\x83\x32\xdd\x86\xc6\xb6\xb3\x8e\x03",
+ 172 },
+ { GCRY_MD_SHA3_256,
+ "\xdb\x11\xf6\x09\xba\xba\x7b\x0c\xa6\x34\x92\x6b\x1d\xd5\x39\xc8\xcb\xad\xa2\x49\x67\xd7\xad\xd4\xd9\x87\x6f\x77\xc2\xd8\x0c\x0f\x4d\xce\xfb\xd7\x12\x15\x48\x37\x35\x82\x70\x5c\xca\x24\x95\xbd\x2a\x43\x71\x6f\xe6\x4e\xd2\x6d\x05\x9c\xfb\x56\x6b\x33\x64\xbd\x49\xee\x07\x17\xbd\xd9\x81\x0d\xd1\x4d\x8f\xad\x80\xdb\xbd\xc4\xca\xfb\x37\xcc\x60\xfb\x0f\xe2\xa8\x0f\xb4\x54\x1b\x8c\xa9\xd5\x9d\xce\x45\x77\x38\xa9\xd3\xd8\xf6\x41\xaf\x8c\x3f\xd6\xda\x16\x2d\xc1\x6f\xc0\x1a\xac\x52\x7a\x4a\x02\x55\xb4\xd2\x31\xc0\xbe\x50\xf4\x4f\x0d\xb0\xb7\x13\xaf\x03\xd9\x68\xfe\x7f\x0f\x61\xed\x08\x24\xc5\x5c\x4b\x52\x65\x54\x8f\xeb\xd6\xaa\xd5\xc5\xee\xdf\x63\xef\xe7\x93\x48\x9c\x39\xb8\xfd\x29\xd1\x04\xce",
+ "\x44\xe2\x76\x99\x1e\x53\x82\xbd\x7e\xb5\xad\xcf\x1f\x79\x36\x28\x04\xd3\x46\xbe\xdf\xc6\x91\x6f\x4d\xca\x4b\x57\x24\x0e\x9c\x99",
+ 173 },
+ { GCRY_MD_SHA3_256,
+ "\xbe\xbd\x4f\x1a\x84\xfc\x8b\x15\xe4\x45\x2a\x54\xbd\x02\xd6\x9e\x30\x4b\x7f\x32\x61\x6a\xad\xd9\x05\x37\x93\x71\x06\xae\x4e\x28\xde\x9d\x8a\xab\x02\xd1\x9b\xc3\xe2\xfd\xe1\xd6\x51\x55\x9e\x29\x64\x53\xe4\xdb\xa9\x43\x70\xa1\x4d\xbb\xb2\xd1\xd4\xe2\x02\x23\x02\xee\x90\xe2\x08\x32\x1e\xfc\xd8\x52\x8a\xd8\x9e\x46\xdc\x83\x9e\xa9\xdf\x61\x8e\xa8\x39\x4a\x6b\xff\x30\x8e\x77\x26\xba\xe0\xc1\x9b\xcd\x4b\xe5\x2d\xa6\x25\x8e\x2e\xf4\xe9\x6a\xa2\x12\x44\x42\x9f\x49\xef\x5c\xb4\x86\xd7\xff\x35\xca\xc1\xba\xcb\x7e\x95\x71\x19\x44\xbc\xcb\x2a\xb3\x47\x00\xd4\x2d\x1e\xb3\x8b\x5d\x53\x6b\x94\x73\x48\xa4\x58\xed\xe3\xdc\x6b\xd6\xec\x54\x7b\x1b\x0c\xae\x5b\x25\x7b\xe3\x6a\x71\x24\xe1\x06\x0c\x17\x0f\xfa",
+ "\x80\x89\x1a\x08\x6a\xf3\x85\x02\x50\x68\x79\x9f\x19\x24\x11\xc6\x89\xcc\x4e\x0d\x9a\x59\xf3\xf4\x1d\xbb\x02\xa3\x43\xf1\xa7\x59",
+ 174 },
+ { GCRY_MD_SHA3_256,
+ "\x5a\xca\x56\xa0\x3a\x13\x78\x4b\xdc\x32\x89\xd9\x36\x4f\x79\xe2\xa8\x5c\x12\x27\x6b\x49\xb9\x2d\xb0\xad\xaa\x4f\x20\x6d\x50\x28\xf2\x13\xf6\x78\xc3\x51\x0e\x11\x1f\x9d\xc4\xc1\xc1\xf8\xb6\xac\xb1\x7a\x64\x13\xaa\x22\x76\x07\xc5\x15\xc6\x2a\x73\x38\x17\xba\x5e\x76\x2c\xc6\x74\x8e\x7e\x0d\x68\x72\xc9\x84\xd7\x23\xc9\xbb\x3b\x11\x7e\xb8\x96\x31\x85\x30\x0a\x80\xbf\xa6\x5c\xde\x49\x5d\x70\xa4\x6c\x44\x85\x86\x05\xfc\xcb\xed\x08\x6c\x2b\x45\xce\xf9\x63\xd3\x32\x94\xdb\xe9\x70\x6b\x13\xaf\x22\xf1\xb7\xc4\xcd\x5a\x00\x1c\xfe\xc2\x51\xfb\xa1\x8e\x72\x2c\x6e\x1c\x4b\x11\x66\x91\x8b\x4f\x6f\x48\xa9\x8b\x64\xb3\xc0\x7f\xc8\x6a\x6b\x17\xa6\xd0\x48\x0a\xb7\x9d\x4e\x64\x15\xb5\x20\xf1\xc4\x84\xd6\x75\xb1",
+ "\x77\xdd\xf0\x34\xb7\xdf\xd6\xb2\x92\xaa\x3b\x0c\x1e\x55\x2f\x47\xb1\xd8\xc2\x30\x78\x04\x2c\xc5\x8b\xb3\xdd\x47\x20\xb9\xee\x4d",
+ 175 },
+ { GCRY_MD_SHA3_256,
+ "\xa5\xaa\xd0\xe4\x64\x6a\x32\xc8\x5c\xfc\xac\x73\xf0\x2f\xc5\x30\x0f\x19\x82\xfa\xbb\x2f\x21\x79\xe2\x83\x03\xe4\x47\x85\x40\x94\xcd\xfc\x85\x43\x10\xe5\xc0\xf6\x09\x93\xce\xff\x54\xd8\x4d\x6b\x46\x32\x3d\x93\x0a\xdb\x07\xc1\x75\x99\xb3\x5b\x50\x5f\x09\xe7\x84\xbc\xa5\x98\x5e\x01\x72\x25\x77\x97\xfb\x53\x64\x9e\x2e\x97\x23\xef\xd1\x68\x65\xc3\x1b\x5c\x3d\x51\x13\xb5\x8b\xb0\xbf\xc8\x92\x0f\xab\xdd\xa0\x86\xd7\x53\x7e\x66\xd7\x09\xd0\x50\xbd\x14\xd0\xc9\x60\x87\x3f\x15\x6f\xad\x5b\x3d\x38\x40\xcd\xfc\xdc\x9b\xe6\xaf\x51\x9d\xb2\x62\xa2\x7f\x40\x89\x6a\xb2\x5c\xc3\x9f\x96\x98\x4d\x65\x06\x11\xc0\xd5\xa3\x08\x0d\x5b\x3a\x1b\xf1\x86\xab\xd4\x29\x56\x58\x8b\x3b\x58\xcd\x94\x89\x70\xd2\x98\x77\x60\x60",
+ "\x23\xd2\x68\x8d\x86\x7a\x18\x04\x0e\x82\xf7\x87\x6a\xcf\x04\xdc\x3a\x9c\x01\x40\xfe\xdd\x93\xeb\xe7\xad\xf9\x20\xb2\xf8\x3d\xa4",
+ 176 },
+ { GCRY_MD_SHA3_256,
+ "\x06\xcb\xbe\x67\xe9\x4a\x97\x82\x03\xea\xd6\xc0\x57\xa1\xa5\xb0\x98\x47\x8b\x4b\x4c\xbe\xf5\xa9\x7e\x93\xc8\xe4\x2f\x55\x72\x71\x35\x75\xfc\x2a\x88\x45\x31\xd7\x62\x2f\x8f\x87\x93\x87\xa8\x59\xa8\x0f\x10\xef\x02\x70\x8c\xd8\xf7\x41\x3a\xb3\x85\xaf\xc3\x57\x67\x8b\x95\x78\xc0\xeb\xf6\x41\xef\x07\x6a\x1a\x30\xf1\xf7\x53\x79\xe9\xdc\xb2\xa8\x85\xbd\xd2\x95\x90\x5e\xe8\x0c\x01\x68\xa6\x2a\x95\x97\xd1\x0c\xf1\x2d\xd2\xd8\xce\xe4\x66\x45\xc7\xe5\xa1\x41\xf6\xe0\xe2\x3a\xa4\x82\xab\xe5\x66\x1c\x16\xe6\x9e\xf1\xe2\x83\x71\xe2\xe2\x36\xc3\x59\xba\x4e\x92\xc2\x56\x26\xa7\xb7\xff\x13\xf6\xea\x4a\xe9\x06\xe1\xcf\xe1\x63\xe9\x17\x19\xb1\xf7\x50\xa9\x6c\xbd\xe5\xfb\xc9\x53\xd9\xe5\x76\xcd\x21\x6a\xfc\x90\x32\x3a",
+ "\x2d\xf6\x66\xfc\x5d\x4e\xad\x1c\x3b\x10\xb9\xf8\xd4\xbb\x81\xae\xa4\xf9\x3d\x38\x73\xd5\xce\x5c\xfb\xac\x4b\x69\x43\x5e\x1b\x7c",
+ 177 },
+ { GCRY_MD_SHA3_256,
+ "\xf1\xc5\x28\xcf\x77\x39\x87\x47\x07\xd4\xd8\xad\x5b\x98\xf7\xc7\x71\x69\xde\x0b\x57\x18\x8d\xf2\x33\xb2\xdc\x8a\x5b\x31\xed\xa5\xdb\x42\x91\xdd\x9f\x68\xe6\xba\xd3\x7b\x8d\x7f\x6c\x9c\x00\x44\xb3\xbf\x74\xbb\xc3\xd7\xd1\x79\x8e\x13\x87\x09\xb0\xd7\x5e\x7c\x59\x3d\x3c\xcc\xdc\x1b\x20\xc7\x17\x4b\x4e\x69\x2a\xdd\x82\x0a\xce\x26\x2d\x45\xcc\xfa\xe2\x07\x7e\x87\x87\x96\x34\x71\x68\x06\x0a\x16\x2e\xcc\xa8\xc3\x8c\x1a\x88\x35\x0b\xd6\x3b\xb5\x39\x13\x4f\x70\x0f\xd4\xad\xdd\x59\x59\xe2\x55\x33\x7d\xaa\x06\xbc\x86\x35\x8f\xab\xcb\xef\xdf\xb5\xbc\x88\x97\x83\xd8\x43\xc0\x8a\xad\xc6\xc4\xf6\xc3\x6f\x65\xf1\x56\xe8\x51\xc9\xa0\xf9\x17\xe4\xa3\x67\xb5\xad\x93\xd8\x74\x81\x2a\x1d\xe6\xa7\xb9\x3c\xd5\x3a\xd9\x72\x32",
+ "\xaf\x0c\x54\x74\x52\x80\x32\xe2\x62\x9b\x8f\xbb\x0e\x34\x40\x5f\x7f\x25\x1d\x41\xe7\x3b\x56\x67\xbe\x3c\x07\xcc\xb2\xc1\xc9\x53",
+ 178 },
+ { GCRY_MD_SHA3_256,
+ "\x9d\x9f\x3a\x7e\xcd\x51\xb4\x1f\x65\x72\xfd\x0d\x08\x81\xe3\x03\x90\xdf\xb7\x80\x99\x1d\xae\x7d\xb3\xb4\x76\x19\x13\x47\x18\xe6\xf9\x87\x81\x0e\x54\x26\x19\xdf\xaa\x7b\x50\x5c\x76\xb7\x35\x0c\x64\x32\xd8\xbf\x1c\xfe\xbd\xf1\x06\x9b\x90\xa3\x5f\x0d\x04\xcb\xdf\x13\x0b\x0d\xfc\x78\x75\xf4\xa4\xe6\x2c\xdb\x8e\x52\x5a\xad\xd7\xce\x84\x25\x20\xa4\x82\xac\x18\xf0\x94\x42\xd7\x83\x05\xfe\x85\xa7\x4e\x39\xe7\x60\xa4\x83\x74\x82\xed\x2f\x43\x7d\xd1\x3b\x2e\xc1\x04\x2a\xfc\xf9\xde\xcd\xc3\xe8\x77\xe5\x0f\xf4\x10\x6a\xd1\x0a\x52\x52\x30\xd1\x19\x20\x32\x4a\x81\x09\x4d\xa3\x1d\xea\xb6\x47\x6a\xa4\x2f\x20\xc8\x48\x43\xcf\xc1\xc5\x85\x45\xee\x80\x35\x2b\xdd\x37\x40\xdd\x6a\x16\x79\x2a\xe2\xd8\x6f\x11\x64\x1b\xb7\x17\xc2",
+ "\x9b\xbe\xf7\xa7\x53\x91\x35\x4a\x38\x8a\xaa\x7c\xa0\x35\xdc\x62\xd3\x23\x1b\x80\x09\x1b\xb7\x74\x8f\x76\xe5\x2d\x8e\x9f\x20\xf0",
+ 179 },
+ { GCRY_MD_SHA3_256,
+ "\x51\x79\x88\x87\x24\x81\x9f\xba\xd3\xaf\xa9\x27\xd3\x57\x77\x96\x66\x0e\x6a\x81\xc5\x2d\x98\xe9\x30\x32\x61\xd5\xa4\xa8\x32\x32\xf6\xf7\x58\x93\x4d\x50\xaa\x83\xff\x9e\x20\xa5\x92\x6d\xfe\xba\xac\x49\x52\x9d\x00\x6e\xb9\x23\xc5\xae\x50\x48\xed\x54\x4e\xc4\x71\xed\x71\x91\xed\xf4\x63\x63\x38\x38\x24\xf9\x15\x76\x9b\x3e\x68\x80\x94\xc6\x82\xb0\x21\x51\xe5\xee\x01\xe5\x10\xb4\x31\xc8\x86\x5a\xff\x8b\x6b\x6f\x2f\x59\xcb\x6d\x12\x9d\xa7\x9e\x97\xc6\xd2\xb8\xfa\x6c\x6d\xa3\xf6\x03\x19\x9d\x2d\x1b\xca\xb5\x47\x68\x2a\x81\xcd\x6c\xf6\x5f\x65\x51\x12\x13\x91\xd7\x8b\xcc\x23\xb5\xbd\x0e\x92\x2e\xc6\xd8\xbf\x97\xc9\x52\xe8\x4d\xd2\x8a\xef\x90\x9a\xba\x31\xed\xb9\x03\xb2\x8f\xbf\xc3\x3b\x77\x03\xcd\x99\x62\x15\xa1\x12\x38",
+ "\xb1\x08\x45\x7a\x6b\xd3\x31\xbe\x43\xc9\xfe\x1e\x2a\x02\xe8\xc7\x44\xc2\xbc\xc9\x27\xa9\xc3\xc4\x86\xf1\x10\xdc\xcf\x90\x7f\x6b",
+ 180 },
+ { GCRY_MD_SHA3_256,
+ "\x57\x6e\xf3\x52\x0d\x30\xb7\xa4\x89\x9b\x8c\x0d\x5e\x35\x9e\x45\xc5\x18\x9a\xdd\x10\x0e\x43\xbe\x42\x9a\x02\xfb\x3d\xe5\xff\x4f\x8f\xd0\xe7\x9d\x96\x63\xac\xca\x72\xcd\x29\xc9\x45\x82\xb1\x92\x92\xa5\x57\xc5\xb1\x31\x52\x97\xd1\x68\xfb\xb5\x4e\x9e\x2e\xcd\x13\x80\x9c\x2b\x5f\xce\x99\x8e\xdc\x65\x70\x54\x5e\x14\x99\xdb\xe7\xfb\x74\xd4\x7c\xd7\xf3\x58\x23\xb2\x12\xb0\x5b\xf3\xf5\xa7\x9c\xaa\x34\x22\x4f\xdd\x67\x0d\x33\x5f\xcb\x10\x6f\x5d\x92\xc3\x94\x6f\x44\xd3\xaf\xcb\xae\x2e\x41\xac\x55\x4d\x8e\x67\x59\xf3\x32\xb7\x6b\xe8\x9a\x03\x24\xaa\x12\xc5\x48\x2d\x1e\xa3\xee\x89\xde\xd4\x93\x6f\x3e\x3c\x08\x04\x36\xf5\x39\xfa\x13\x7e\x74\xc6\xd3\x38\x9b\xdf\x5a\x45\x07\x4c\x47\xbc\x7b\x20\xb0\x94\x84\x07\xa6\x6d\x85\x5e\x2f",
+ "\xa6\x11\x09\x83\x8d\xfa\x5b\x14\x6d\xf4\xe6\xc3\xbd\xbc\x7a\x47\x7b\xe3\x6b\x62\x28\xeb\xd9\x10\x25\x01\x2a\xf4\xcc\x0e\xb4\x09",
+ 181 },
+ { GCRY_MD_SHA3_256,
+ "\x0d\xf2\x15\x2f\xa4\xf4\x35\x7c\x87\x41\x52\x9d\xd7\x7e\x78\x39\x25\xd3\xd7\x6e\x95\xba\xfa\x2b\x54\x2a\x2c\x33\xf3\xd1\xd1\x17\xd1\x59\xcf\x47\x3f\x82\x31\x03\x56\xfe\xe4\xc9\x0a\x9e\x50\x5e\x70\xf8\xf2\x48\x59\x65\x63\x68\xba\x09\x38\x1f\xa2\x45\xeb\x6c\x3d\x76\x3f\x30\x93\xf0\xc8\x9b\x97\x2e\x66\xb5\x3d\x59\x40\x6d\x9f\x01\xae\xa0\x7f\x8b\x3b\x61\x5c\xac\x4e\xe4\xd0\x5f\x54\x2e\x7d\x0d\xab\x45\xd6\x7c\xcc\xcd\x3a\x60\x6c\xcb\xeb\x31\xea\x1f\xa7\x00\x5b\xa0\x71\x76\xe6\x0d\xab\x7d\x78\xf6\x81\x0e\xf0\x86\xf4\x2f\x08\xe5\x95\xf0\xec\x21\x73\x72\xb9\x89\x70\xcc\x63\x21\x57\x6d\x92\xce\x38\xf7\xc3\x97\xa4\x03\xba\xda\x15\x48\xd2\x05\xc3\x43\xac\x09\xde\xca\x86\x32\x53\x73\xc3\xb7\x6d\x9f\x32\x02\x8f\xea\x8e\xb3\x25\x15",
+ "\x4f\x0f\x30\xc8\x90\xb0\xab\x40\x49\x61\x15\x85\x73\x53\x8f\xe9\xa2\xb2\x34\xb9\x4a\x09\x91\xf2\x6d\x5e\xa0\x4f\xdd\xc9\xc5\x65",
+ 182 },
+ { GCRY_MD_SHA3_256,
+ "\x3e\x15\x35\x0d\x87\xd6\xeb\xb5\xc8\xad\x99\xd4\x25\x15\xcf\xe1\x79\x80\x93\x3c\x7a\x8f\x6b\x8b\xbb\xf0\xa6\x37\x28\xce\xfa\xad\x20\x52\x62\x3c\x0b\xd5\x93\x18\x39\x11\x2a\x48\x63\x3f\xb3\xc2\x00\x4e\x07\x49\xc8\x7a\x41\xb2\x6a\x8b\x48\x94\x55\x39\xd1\xff\x41\xa4\xb2\x69\x46\x2f\xd1\x99\xbf\xec\xd4\x53\x74\x75\x6f\x55\xa9\x11\x6e\x92\x09\x3a\xc9\x94\x51\xae\xfb\x2a\xf9\xfd\x32\xd6\xd7\xf5\xfb\xc7\xf7\xa5\x40\xd5\x09\x7c\x09\x6e\xbc\x3b\x3a\x72\x15\x41\xde\x07\x3a\x1c\xc0\x2f\x7f\xb0\xfb\x1b\x93\x27\xfb\x0b\x12\x18\xca\x49\xc9\x48\x7a\xb5\x39\x66\x22\xa1\x3a\xe5\x46\xc9\x7a\xbd\xef\x6b\x56\x38\x0d\xda\x70\x12\xa8\x38\x40\x91\xb6\x65\x6d\x0a\xb2\x72\xd3\x63\xce\xa7\x81\x63\xff\x76\x5c\xdd\x13\xab\x17\x38\xb9\x40\xd1\x6c\xae",
+ "\x85\x45\x9c\xfb\x02\x89\x59\x9c\xdd\x67\xc4\x73\xa0\xba\x6d\xa6\x16\xc6\x08\xe3\x67\xf5\x8c\x50\xa0\x35\x62\x42\x4d\xcf\x1d\x06",
+ 183 },
+ { GCRY_MD_SHA3_256,
+ "\xc3\x8d\x6b\x0b\x75\x7c\xb5\x52\xbe\x40\x94\x0e\xce\x00\x09\xef\x3b\x0b\x59\x30\x7c\x14\x51\x68\x6f\x1a\x22\x70\x29\x22\x80\x0d\x58\xbc\xe7\xa6\x36\xc1\x72\x7e\xe5\x47\xc0\x1b\x21\x47\x79\xe8\x98\xfc\x0e\x56\x0f\x8a\xe7\xf6\x1b\xef\x4d\x75\xea\xa6\x96\xb9\x21\xfd\x6b\x73\x5d\x17\x15\x35\xe9\xed\xd2\x67\xc1\x92\xb9\x98\x80\xc8\x79\x97\x71\x10\x02\x00\x90\x95\xd8\xa7\xa4\x37\xe2\x58\x10\x4a\x41\xa5\x05\xe5\xef\x71\xe5\x61\x3d\xdd\x20\x08\x19\x5f\x0c\x57\x4e\x6b\xa3\xfe\x40\x09\x9c\xfa\x11\x6e\x5f\x1a\x2f\xa8\xa6\xda\x04\xba\xdc\xb4\xe2\xd5\xd0\xde\x31\xfd\xc4\x80\x08\x91\xc4\x57\x81\xa0\xaa\xc7\xc9\x07\xb5\x6d\x63\x1f\xca\x5c\xe8\xb2\xcd\xe6\x20\xd1\x1d\x17\x77\xed\x9f\xa6\x03\x54\x1d\xe7\x94\xdd\xc5\x75\x8f\xcd\x5f\xad\x78\xc0",
+ "\x55\x39\xd2\xe5\x2a\x5a\x1b\xb3\xc2\x46\xb0\x15\x83\x56\xe2\xb2\x78\x2f\xc1\x3c\x10\x24\x89\x37\xa0\xc4\xa4\x0b\x09\x1f\x62\x47",
+ 184 },
+ { GCRY_MD_SHA3_256,
+ "\x8d\x2d\xe3\xf0\xb3\x7a\x63\x85\xc9\x07\x39\x80\x5b\x17\x00\x57\xf0\x91\xcd\x0c\x7a\x0b\xc9\x51\x54\x0f\x26\xa5\xa7\x5b\x3e\x69\x46\x31\xbb\x64\xc7\x63\x5e\xed\x31\x6f\x51\x31\x8e\x9d\x8d\xe1\x3c\x70\xa2\xab\xa0\x4a\x14\x83\x68\x55\xf3\x5e\x48\x05\x28\xb7\x76\xd0\xa1\xe8\xa2\x3b\x54\x7c\x8b\x8d\x6a\x0d\x09\xb2\x41\xd3\xbe\x93\x77\x16\x0c\xca\x4e\x67\x93\xd0\x0a\x51\x5d\xc2\x99\x2c\xb7\xfc\x74\x1d\xac\xa1\x71\x43\x1d\xa9\x9c\xce\x6f\x77\x89\xf1\x29\xe2\xac\x5c\xf6\x5b\x40\xd7\x03\x03\x5c\xd2\x18\x5b\xb9\x36\xc8\x20\x02\xda\xf8\xcb\xc2\x7a\x7a\x9e\x55\x4b\x06\x19\x66\x30\x44\x6a\x6f\x0a\x14\xba\x15\x5e\xd2\x6d\x95\xbd\x62\x7b\x72\x05\xc0\x72\xd0\x2b\x60\xdb\x0f\xd7\xe4\x9e\xa0\x58\xc2\xe0\xba\x20\x2d\xaf\xf0\xde\x91\xe8\x45\xcf\x79",
+ "\x6d\x63\x41\x92\x07\xb9\x9d\x4d\xb1\xad\xd7\x95\xd8\x52\xa8\xda\xac\x11\xb7\x89\xaf\x0c\x7d\x63\x53\x03\x6c\xb2\x3f\x64\x28\xb4",
+ 185 },
+ { GCRY_MD_SHA3_256,
+ "\xc4\x64\xbb\xda\xd2\x75\xc5\x0d\xcd\x98\x3b\x65\xad\x10\x19\xb9\xff\x85\xa1\xe7\x1c\x80\x7f\x32\x04\xbb\x2c\x92\x1d\xc3\x1f\xbc\xd8\xc5\xfc\x45\x86\x8a\xe9\xef\x85\xb6\xc9\xb8\x3b\xba\x2a\x5a\x82\x22\x01\xed\x68\x58\x6e\xc5\xec\x27\xfb\x28\x57\xa5\xd1\xa2\xd0\x9d\x09\x11\x5f\x22\xdc\xc3\x9f\xe6\x1f\x5e\x1b\xa0\xff\x6e\x8b\x4a\xcb\x4c\x6d\xa7\x48\xbe\x7f\x3f\x08\x39\x73\x93\x94\xff\x7f\xa8\xe3\x9f\x7f\x7e\x84\xa3\x3c\x38\x66\x87\x5c\x01\xbc\xb1\x26\x3c\x94\x05\xd9\x19\x08\xe9\xe0\xb5\x0e\x74\x59\xfa\xbb\x63\xd8\xc6\xbb\xb7\x3d\x8e\x34\x83\xc0\x99\xb5\x5b\xc3\x0f\xf0\x92\xff\x68\xb6\xad\xed\xfd\x47\x7d\x63\x57\x0c\x9f\x55\x15\x84\x7f\x36\xe2\x4b\xa0\xb7\x05\x55\x71\x30\xce\xc5\x7e\xba\xd1\xd0\xb3\x1a\x37\x8e\x91\x89\x4e\xe2\x6e\x3a\x04",
+ "\xd2\x09\x0d\xae\x0f\xc2\x01\xb2\xb9\xc0\x3d\xd4\x82\xa8\xeb\x1f\xfd\x3c\xf7\x0c\x55\xf9\x8d\x6f\x39\xa4\x1b\x8b\xda\xc2\x7a\x17",
+ 186 },
+ { GCRY_MD_SHA3_256,
+ "\x8b\x8d\x68\xbb\x8a\x75\x73\x2f\xe2\x72\x81\x5a\x68\xa1\xc9\xc5\xaa\x31\xb4\x1d\xed\xc8\x49\x3e\x76\x52\x5d\x1d\x01\x3d\x33\xce\xbd\x9e\x21\xa5\xbb\x95\xdb\x26\x16\x97\x6a\x8c\x07\xfc\xf4\x11\xf5\xf6\xbc\x6f\x7e\x0b\x57\xac\xa7\x8c\xc2\x79\x0a\x6f\x9b\x89\x88\x58\xac\x9c\x79\xb1\x65\xff\x24\xe6\x66\x77\x53\x1e\x39\xf5\x72\xbe\x5d\x81\xeb\x32\x64\x52\x41\x81\x11\x5f\x32\x78\x02\x57\xbf\xb9\xae\xec\x6a\xf1\x2a\xf2\x8e\x58\x7c\xac\x06\x8a\x1a\x29\x53\xb5\x9a\xd6\x80\xf4\xc2\x45\xb2\xe3\xec\x36\xf5\x99\x40\xd3\x7e\x1d\x3d\xb3\x8e\x13\xed\xb2\x9b\x5c\x0f\x40\x4f\x6f\xf8\x7f\x80\xfc\x8b\xe7\xa2\x25\xff\x22\xfb\xb9\xc8\xb6\xb1\xd7\x33\x0c\x57\x84\x0d\x24\xbc\x75\xb0\x6b\x80\xd3\x0d\xad\x68\x06\x54\x4d\x51\x0a\xf6\xc4\x78\x5e\x82\x3a\xc3\xe0\xb8",
+ "\xc9\xe8\xf9\x6b\xa7\x5e\xaf\x37\x1d\xca\x35\xdc\x69\x13\x8e\xca\x8c\xb3\xf2\x82\x3f\x3b\xe5\x51\xd9\xdc\x8a\xa6\xa4\xed\x41\x69",
+ 187 },
+ { GCRY_MD_SHA3_256,
+ "\x6b\x01\x87\x10\x44\x6f\x36\x8e\x74\x21\xf1\xbc\x0c\xcf\x56\x2d\x9c\x18\x43\x84\x6b\xc8\xd9\x8d\x1c\x9b\xf7\xd9\xd6\xfc\xb4\x8b\xfc\x3b\xf8\x3b\x36\xd4\x4c\x4f\xa9\x34\x30\xaf\x75\xcd\x19\x0b\xde\x36\xa7\xf9\x2f\x86\x7f\x58\xa8\x03\x90\x0d\xf8\x01\x81\x50\x38\x4d\x85\xd8\x21\x32\xf1\x23\x00\x6a\xc2\xae\xba\x58\xe0\x2a\x03\x7f\xe6\xaf\xbd\x65\xec\xa7\xc4\x49\x77\xdd\x3d\xc7\x4f\x48\xb6\xe7\xa1\xbf\xd5\xcc\x4d\xcf\x24\xe4\xd5\x2e\x92\xbd\x44\x55\x84\x8e\x49\x28\xb0\xea\xc8\xb7\x47\x6f\xe3\xcc\x03\xe8\x62\xaa\x4d\xff\x44\x70\xdb\xfe\xd6\xde\x48\xe4\x10\xf2\x50\x96\x48\x7e\xcf\xc3\x2a\x27\x27\x7f\x3f\x50\x23\xb2\x72\x5a\xde\x46\x1b\x13\x55\x88\x95\x54\xa8\x83\x6c\x9c\xf5\x3b\xd7\x67\xf5\x73\x7d\x55\x18\x4e\xea\x1a\xb3\xf5\x3e\xdd\x09\x76\xc4\x85",
+ "\x23\x3b\x0b\xc2\x81\x43\xc3\x2a\x66\x8b\x0a\xb5\xd7\x6b\xe5\x71\x2c\x03\x87\x05\x6f\xb0\xe7\x9f\x2c\x2f\x7f\x1c\x31\xe4\xa8\x6a",
+ 188 },
+ { GCRY_MD_SHA3_256,
+ "\xc9\x53\x4a\x24\x71\x4b\xd4\xbe\x37\xc8\x8a\x3d\xa1\x08\x2e\xda\x7c\xab\xd1\x54\xc3\x09\xd7\xbd\x67\x0d\xcc\xd9\x5a\xa5\x35\x59\x44\x63\x05\x8a\x29\xf7\x90\x31\xd6\xec\xaa\x9f\x67\x5d\x12\x11\xe9\x35\x9b\xe8\x26\x69\xa7\x9c\x85\x5e\xa8\xd8\x9d\xd3\x8c\x2c\x76\x1d\xdd\x0e\xc0\xce\x9e\x97\x59\x74\x32\xe9\xa1\xbe\xae\x06\x2c\xdd\x71\xed\xfd\xfd\x46\x41\x19\xbe\x9e\x69\xd1\x8a\x7a\x7f\xd7\xce\x0e\x21\x06\xf0\xc8\xb0\xab\xf4\x71\x5e\x2c\xa4\x8e\xf9\xf4\x54\xdc\x20\x3c\x96\x65\x66\x53\xb7\x27\x08\x35\x13\xf8\xef\xb8\x6e\x49\xc5\x13\xbb\x75\x8b\x3b\x05\x2f\xe2\x1f\x1c\x05\xbb\x33\xc3\x71\x29\xd6\xcc\x81\xf1\xae\xf6\xad\xc4\x5b\x0e\x88\x27\xa8\x30\xfe\x54\x5c\xf5\x7d\x09\x55\x80\x2c\x11\x7d\x23\xcc\xb5\x5e\xa2\x8f\x95\xc0\xd8\xc2\xf9\xc5\xa2\x42\xb3\x3f",
+ "\xb7\x9b\x5f\x81\x82\xd3\xfb\x4a\xba\xb6\x3e\x7c\xb2\x6a\x8e\x08\x65\xae\x8d\x79\xbd\x4c\x51\x4a\xd8\x91\x7d\x5e\xcb\x7f\xed\x8f",
+ 189 },
+ { GCRY_MD_SHA3_256,
+ "\x07\x90\x6c\x87\x29\x7b\x86\x7a\xbf\x45\x76\xe9\xf3\xcc\x7f\x82\xf2\x2b\x15\x4a\xfc\xbf\x29\x3b\x93\x19\xf1\xb0\x58\x4d\xa6\xa4\x0c\x27\xb3\x2e\x0b\x1b\x7f\x41\x2c\x4f\x1b\x82\x48\x0e\x70\xa9\x23\x5b\x12\xec\x27\x09\x0a\x5a\x33\x17\x5a\x2b\xb2\x8d\x8a\xdc\x47\x5c\xef\xe3\x3f\x78\x03\xf8\xce\x27\x96\x72\x17\x38\x1f\x02\xe6\x7a\x3b\x4f\x84\xa7\x1f\x1c\x52\x28\xe0\xc2\xad\x97\x13\x73\xf6\xf6\x72\x62\x4f\xce\xa8\xd1\xa9\xf8\x51\x70\xfa\xd3\x0f\xa0\xbb\xd2\x50\x35\xc3\xb4\x1a\x61\x75\xd4\x67\x99\x8b\xd1\x21\x5f\x6f\x38\x66\xf5\x38\x47\xf9\xcf\x68\xef\x3e\x2f\xbb\x54\xbc\x99\x4d\xe2\x30\x2b\x82\x9c\x5e\xea\x68\xec\x44\x1f\xcb\xaf\xd7\xd1\x6a\xe4\xfe\x9f\xff\x98\xbf\x00\xe5\xbc\x2a\xd5\x4d\xd9\x1f\xf9\xfd\xa4\xdd\x77\xb6\xc7\x54\xa9\x19\x55\xd1\xfb\xaa\xd0",
+ "\xf6\x80\x19\x8d\xe2\x94\x3d\x20\xe9\xd8\x09\xfd\x83\x12\xd6\x74\xc9\xa2\x50\xda\x22\xba\x6e\x92\x0e\x40\x8f\x6f\x2c\x0e\x07\x39",
+ 190 },
+ { GCRY_MD_SHA3_256,
+ "\x58\x8e\x94\xb9\x05\x4a\xbc\x21\x89\xdf\x69\xb8\xba\x34\x34\x1b\x77\xcd\xd5\x28\xe7\x86\x0e\x5d\xef\xca\xa7\x9b\x0c\x9a\x45\x2a\xd4\xb8\x2a\xa3\x06\xbe\x84\x53\x6e\xb7\xce\xdc\xbe\x05\x8d\x7b\x84\xa6\xae\xf8\x26\xb0\x28\xb8\xa0\x27\x1b\x69\xac\x36\x05\xa9\x63\x5e\xa9\xf5\xea\x0a\xa7\x00\xf3\xeb\x78\x35\xbc\x54\x61\x1b\x92\x29\x64\x30\x0c\x95\x3e\xfe\x74\x91\xe3\x67\x7c\x2c\xeb\xe0\x82\x2e\x95\x6c\xd1\x64\x33\xb0\x2c\x68\xc4\xa2\x32\x52\xc3\xf9\xe1\x51\xa4\x16\xb4\x96\x32\x57\xb7\x83\xe0\x38\xf6\xb4\xd5\xc9\xf1\x10\xf8\x71\x65\x2c\x7a\x64\x9a\x7b\xce\xdc\xbc\xcc\x6f\x2d\x07\x25\xbb\x90\x3c\xc1\x96\xba\x76\xc7\x6a\xa9\xf1\x0a\x19\x0b\x1d\x11\x68\x99\x3b\xaa\x9f\xfc\x96\xa1\x65\x52\x16\x77\x34\x58\xbe\xc7\x2b\x0e\x39\xc9\xf2\xc1\x21\x37\x8f\xea\xb4\xe7\x6a",
+ "\xa1\x90\xdd\x73\x55\x60\x86\xea\x70\xbc\x31\x02\x2d\x6a\x4f\x95\xd8\x9d\xc0\x99\xe2\x03\x0c\x19\x31\x1c\xc8\x98\x82\x81\x27\x8f",
+ 191 },
+ { GCRY_MD_SHA3_256,
+ "\x08\x95\x9a\x7e\x4b\xaa\xe8\x74\x92\x88\x13\x36\x40\x71\x19\x4e\x29\x39\x77\x2f\x20\xdb\x7c\x31\x57\x07\x89\x87\xc5\x57\xc2\xa6\xd5\xab\xe6\x8d\x52\x0e\xef\x3d\xc4\x91\x69\x2e\x1e\x21\xbc\xd8\x80\xad\xeb\xf6\x3b\xb4\x21\x3b\x50\x89\x7f\xa0\x05\x25\x6e\xd4\x1b\x56\x90\xf7\x8f\x52\x85\x5c\x8d\x91\x68\xa4\xb6\x66\xfc\xe2\xda\x2b\x45\x6d\x7a\x7e\x7c\x17\xab\x5f\x2f\xb1\xee\x90\xb7\x9e\x69\x87\x12\xe9\x63\x71\x59\x83\xfd\x07\x64\x1a\xe4\xb4\xe9\xdc\x73\x20\x3f\xac\x1a\xe1\x1f\xa1\xf8\xc7\x94\x1f\xcc\x82\xea\xb2\x47\xad\xdb\x56\xe2\x63\x84\x47\xe9\xd6\x09\xe6\x10\xb6\x0c\xe0\x86\x65\x6a\xae\xbf\x1d\xa3\xc8\xa2\x31\xd7\xd9\x4e\x2f\xd0\xaf\xe4\x6b\x39\x1f\xf1\x4a\x72\xea\xeb\x3f\x44\xad\x4d\xf8\x58\x66\xde\xf4\x3d\x47\x81\xa0\xb3\x57\x8b\xc9\x96\xc8\x79\x70\xb1\x32",
+ "\x21\x16\x60\x64\xc5\x2b\x58\x8c\x1e\xc7\xea\x6d\xf1\x90\x5a\x2b\x59\xba\xd4\x99\xb4\x70\xf3\x08\xa2\x6b\x6e\x35\x4d\xdf\xe5\x8f",
+ 192 },
+ { GCRY_MD_SHA3_256,
+ "\xcb\x2a\x23\x4f\x45\xe2\xec\xd5\x86\x38\x95\xa4\x51\xd3\x89\xa3\x69\xaa\xb9\x9c\xfe\xf0\xd5\xc9\xff\xca\x1e\x6e\x63\xf7\x63\xb5\xc1\x4f\xb9\xb4\x78\x31\x3c\x8e\x8c\x0e\xfe\xb3\xac\x95\x00\xcf\x5f\xd9\x37\x91\xb7\x89\xe6\x7e\xac\x12\xfd\x03\x8e\x25\x47\xcc\x8e\x0f\xc9\xdb\x59\x1f\x33\xa1\xe4\x90\x7c\x64\xa9\x22\xdd\xa2\x3e\xc9\x82\x73\x10\xb3\x06\x09\x85\x54\xa4\xa7\x8f\x05\x02\x62\xdb\x5b\x54\x5b\x15\x9e\x1f\xf1\xdc\xa6\xeb\x73\x4b\x87\x23\x43\xb8\x42\xc5\x7e\xaf\xcf\xda\x84\x05\xee\xdb\xb4\x8e\xf3\x2e\x99\x69\x6d\x13\x59\x79\x23\x5c\x3a\x05\x36\x4e\x37\x1c\x2d\x76\xf1\x90\x2f\x1d\x83\x14\x6d\xf9\x49\x5c\x0a\x6c\x57\xd7\xbf\x9e\xe7\x7e\x80\xf9\x78\x7a\xee\x27\xbe\x1f\xe1\x26\xcd\xc9\xef\x89\x3a\x4a\x7d\xcb\xbc\x36\x7e\x40\xfe\x4e\x1e\xe9\x0b\x42\xea\x25\xaf\x01",
+ "\x05\x1e\x19\x90\x64\x64\xec\x7f\xdc\x3d\x37\xee\x3b\xce\xf6\x34\x38\xec\x5e\xdb\xea\x5a\xa2\x02\xa2\x4b\x7f\x71\x90\xb6\x89\xe0",
+ 193 },
+ { GCRY_MD_SHA3_256,
+ "\xd1\x6b\xea\xdf\x02\xab\x1d\x4d\xc6\xf8\x8b\x8c\x45\x54\xc5\x1e\x86\x6d\xf8\x30\xb8\x9c\x06\xe7\x86\xa5\xf8\x75\x7e\x89\x09\x31\x0a\xf5\x1c\x84\x0e\xfe\x8d\x20\xb3\x53\x31\xf4\x35\x5d\x80\xf7\x32\x95\x97\x46\x53\xdd\xd6\x20\xcd\xde\x47\x30\xfb\x6c\x8d\x0d\x2d\xcb\x2b\x45\xd9\x2d\x4f\xbd\xb5\x67\xc0\xa3\xe8\x6b\xd1\xa8\xa7\x95\xaf\x26\xfb\xf2\x9f\xc6\xc6\x59\x41\xcd\xdb\x09\x0f\xf7\xcd\x23\x0a\xc5\x26\x8a\xb4\x60\x6f\xcc\xba\x9e\xde\xd0\xa2\xb5\xd0\x14\xee\x0c\x34\xf0\xb2\x88\x1a\xc0\x36\xe2\x4e\x15\x1b\xe8\x9e\xeb\x6c\xd9\xa7\xa7\x90\xaf\xcc\xff\x23\x4d\x7c\xb1\x1b\x99\xeb\xf5\x8c\xd0\xc5\x89\xf2\x0b\xda\xc4\xf9\xf0\xe2\x8f\x75\xe3\xe0\x4e\x5b\x3d\xeb\xce\x60\x7a\x49\x6d\x84\x8d\x67\xfa\x7b\x49\x13\x2c\x71\xb8\x78\xfd\x55\x57\xe0\x82\xa1\x8e\xca\x1f\xbd\xa9\x4d\x4b",
+ "\x18\xfe\x66\xc0\xcd\x09\x5c\x9c\xc8\x11\xf5\x41\x0b\x5c\xfd\xc1\xb1\x52\xae\x3c\xab\x0c\x33\x28\x97\x4e\x7d\x4b\xbe\xb4\x00\x53",
+ 194 },
+ { GCRY_MD_SHA3_256,
+ "\x8f\x65\xf6\xbc\x59\xa8\x57\x05\x01\x6e\x2b\xae\x7f\xe5\x79\x80\xde\x31\x27\xe5\xab\x27\x5f\x57\x3d\x33\x4f\x73\xf8\x60\x31\x06\xec\x35\x53\x01\x66\x08\xef\x2d\xd6\xe6\x9b\x24\xbe\x0b\x71\x13\xbf\x6a\x76\x0b\xa6\xe9\xce\x1c\x48\xf9\xe1\x86\x01\x2c\xf9\x6a\x1d\x48\x49\xd7\x5d\xf5\xbb\x83\x15\x38\x7f\xd7\x8e\x9e\x15\x3e\x76\xf8\xba\x7e\xc6\xc8\x84\x98\x10\xf5\x9f\xb4\xbb\x9b\x00\x43\x18\x21\x0b\x37\xf1\x29\x95\x26\x86\x6f\x44\x05\x9e\x01\x7e\x22\xe9\x6c\xbe\x41\x86\x99\xd0\x14\xc6\xea\x01\xc9\xf0\x03\x8b\x10\x29\x98\x84\xdb\xec\x31\x99\xbb\x05\xad\xc9\x4e\x95\x5a\x15\x33\x21\x9c\x11\x15\xfe\xd0\xe5\xf2\x12\x28\xb0\x71\xf4\x0d\xd5\x7c\x42\x40\xd9\x8d\x37\xb7\x3e\x41\x2f\xe0\xfa\x47\x03\x12\x0d\x7c\x0c\x67\x97\x2e\xd2\x33\xe5\xde\xb3\x00\xa2\x26\x05\x47\x2f\xa3\xa3\xba\x86",
+ "\xbd\xb4\x26\x38\x92\x11\x99\xd6\x04\x29\x4b\x55\x78\xce\xba\xcc\xdf\x13\x2e\x1d\x7a\xf7\x67\x5b\x77\x68\xe5\x05\x53\xfc\xb6\x04",
+ 195 },
+ { GCRY_MD_SHA3_256,
+ "\x84\x89\x1e\x52\xe0\xd4\x51\x81\x32\x10\xc3\xfd\x63\x5b\x39\xa0\x3a\x6b\x7a\x73\x17\xb2\x21\xa7\xab\xc2\x70\xdf\xa9\x46\xc4\x26\x69\xaa\xcb\xbb\xdf\x80\x1e\x15\x84\xf3\x30\xe2\x8c\x72\x98\x47\xea\x14\x15\x2b\xd6\x37\xb3\xd0\xf2\xb3\x8b\x4b\xd5\xbf\x9c\x79\x1c\x58\x80\x62\x81\x10\x3a\x3e\xab\xba\xed\xe5\xe7\x11\xe5\x39\xe6\xa8\xb2\xcf\x29\x7c\xf3\x51\xc0\x78\xb4\xfa\x8f\x7f\x35\xcf\x61\xbe\xbf\x88\x14\xbf\x24\x8a\x01\xd4\x1e\x86\xc5\x71\x5e\xa4\x0c\x63\xf7\x37\x53\x79\xa7\xeb\x1d\x78\xf2\x76\x22\xfb\x46\x8a\xb7\x84\xaa\xab\xa4\xe5\x34\xa6\xdf\xd1\xdf\x6f\xa1\x55\x11\x34\x1e\x72\x5e\xd2\xe8\x7f\x98\x73\x7c\xcb\x7b\x6a\x6d\xfa\xe4\x16\x47\x74\x72\xb0\x46\xbf\x18\x11\x18\x7d\x15\x1b\xfa\x9f\x7b\x2b\xf9\xac\xdb\x23\xa3\xbe\x50\x7c\xdf\x14\xcf\xdf\x51\x7d\x2c\xb5\xfb\x9e\x4a\xb6",
+ "\xcb\xd8\x82\x09\xb5\x30\x01\x8a\x85\x6c\x5c\x23\x21\xd7\xe4\x85\x51\x1c\xa1\x51\x36\x61\xf1\xfd\xe1\xfa\x06\xf4\x60\x3d\xe1\x17",
+ 196 },
+ { GCRY_MD_SHA3_256,
+ "\xfd\xd7\xa9\x43\x3a\x3b\x4a\xfa\xbd\x7a\x3a\x5e\x34\x57\xe5\x6d\xeb\xf7\x8e\x84\xb7\xa0\xb0\xca\x0e\x8c\x6d\x53\xbd\x0c\x2d\xae\x31\xb2\x70\x0c\x61\x28\x33\x4f\x43\x98\x1b\xe3\xb2\x13\xb1\xd7\xa1\x18\xd5\x9c\x7e\x6b\x64\x93\xa8\x6f\x86\x6a\x16\x35\xc1\x28\x59\xcf\xb9\xad\x17\x46\x0a\x77\xb4\x52\x2a\x5c\x18\x83\xc3\xd6\xac\xc8\x6e\x61\x62\x66\x7e\xc4\x14\xe9\xa1\x04\xaa\x89\x20\x53\xa2\xb1\xd7\x21\x65\xa8\x55\xba\xcd\x8f\xaf\x80\x34\xa5\xdd\x9b\x71\x6f\x47\xa0\x81\x8c\x09\xbb\x6b\xaf\x22\xaa\x50\x3c\x06\xb4\xca\x26\x1f\x55\x77\x61\x98\x9d\x2a\xfb\xd8\x8b\x6a\x67\x8a\xd1\x28\xaf\x68\x67\x21\x07\xd0\xf1\xfc\x73\xc5\xca\x74\x04\x59\x29\x7b\x32\x92\xb2\x81\xe9\x3b\xce\xb7\x61\xbd\xe7\x22\x1c\x3a\x55\x70\x8e\x5e\xc8\x44\x72\xcd\xdc\xaa\x84\xec\xf2\x37\x23\xcc\x09\x91\x35\x5c\x62\x80",
+ "\xf0\xc4\xc1\x37\x4f\x33\xa9\x1d\xc6\x57\xf8\xa3\xfa\x51\x76\x3c\xbd\x0f\xba\x1c\xaf\xdd\x2c\x59\x5e\xd3\x02\xaa\xb1\xab\x75\xa9",
+ 197 },
+ { GCRY_MD_SHA3_256,
+ "\x70\xa4\x0b\xfb\xef\x92\x27\x7a\x1a\xad\x72\xf6\xb7\x9d\x01\x77\x19\x7c\x4e\xbd\x43\x26\x68\xcf\xec\x05\xd0\x99\xac\xcb\x65\x10\x62\xb5\xdf\xf1\x56\xc0\xb2\x73\x36\x68\x7a\x94\xb2\x66\x79\xcf\xdd\x9d\xaf\x7a\xd2\x04\x33\x8d\xd9\xc4\xd1\x41\x14\x03\x3a\x5c\x22\x5b\xd1\x1f\x21\x7b\x5f\x47\x32\xda\x16\x7e\xe3\xf9\x39\x26\x2d\x40\x43\xfc\x9c\xba\x92\x30\x3b\x7b\x5e\x96\xae\xa1\x2a\xdd\xa6\x48\x59\xdf\x4b\x86\xe9\xee\x0b\x58\xe3\x90\x91\xe6\xb1\x88\xb4\x08\xac\x94\xe1\x29\x4a\x89\x11\x24\x5e\xe3\x61\xe6\x0e\x60\x1e\xff\x58\xd1\xd3\x76\x39\xf3\x75\x3b\xec\x80\xeb\xb4\xef\xde\x25\x81\x74\x36\x07\x66\x23\xfc\x65\x41\x5f\xe5\x1d\x1b\x02\x80\x36\x6d\x12\xc5\x54\xd8\x67\x43\xf3\xc3\xb6\x57\x2e\x40\x03\x61\xa6\x07\x26\x13\x14\x41\xba\x49\x3a\x83\xfb\xe9\xaf\xda\x90\xf7\xaf\x1a\xe7\x17\x23\x8d",
+ "\xf2\x15\x7c\x16\x5e\xeb\xdf\xd0\x44\x51\xe9\xe6\xcf\x0b\x11\x2b\xb1\x48\xeb\x9c\x40\xe8\xb2\x42\x7e\xe8\xea\x57\xe6\x0d\x5d\xd6",
+ 198 },
+ { GCRY_MD_SHA3_256,
+ "\x74\x35\x6e\x44\x9f\x4b\xf8\x64\x4f\x77\xb1\x4f\x4d\x67\xcb\x6b\xd9\xc1\xf5\xae\x35\x76\x21\xd5\xb8\x14\x7e\x56\x2b\x65\xc6\x65\x85\xca\xf2\xe4\x91\xb4\x85\x29\xa0\x1a\x34\xd2\x26\xd4\x36\x95\x91\x53\x81\x53\x80\xd5\x68\x9e\x30\xb3\x53\x57\xcd\xac\x6e\x08\xd3\xf2\xb0\xe8\x8e\x20\x06\x00\xd6\x2b\xd9\xf5\xea\xf4\x88\xdf\x86\xa4\x47\x0e\xa2\x27\x00\x61\x82\xe4\x48\x09\x00\x98\x68\xc4\xc2\x80\xc4\x3d\x7d\x64\xa5\x26\x8f\xa7\x19\x07\x49\x60\x08\x7b\x3a\x6a\xbc\x83\x78\x82\xf8\x82\xc8\x37\x83\x45\x35\x92\x93\x89\xa1\x2b\x2c\x78\x18\x7e\x2e\xa0\x7e\xf8\xb8\xee\xf2\x7d\xc8\x50\x02\xc3\xae\x35\xf1\xa5\x0b\xee\x6a\x1c\x48\xba\x7e\x17\x5f\x33\x16\x67\x0b\x27\x98\x34\x72\xaa\x6a\x61\xee\xd0\xa6\x83\xa3\x9e\xe3\x23\x08\x06\x20\xea\x44\xa9\xf7\x44\x11\xae\x5c\xe9\x90\x30\x52\x8f\x9a\xb4\x9c\x79\xf2",
+ "\x08\x36\xab\xbf\x77\xef\x78\xe1\x62\xde\x8f\xb6\x64\xb9\x99\x6d\x5a\x03\x91\x9b\x74\x1e\xb4\xa3\xf0\x2e\x7b\x97\x82\x65\x69\xfa",
+ 199 },
+ { GCRY_MD_SHA3_256,
+ "\x8c\x37\x98\xe5\x1b\xc6\x84\x82\xd7\x33\x7d\x3a\xbb\x75\xdc\x9f\xfe\x86\x07\x14\xa9\xad\x73\x55\x1e\x12\x00\x59\x86\x0d\xde\x24\xab\x87\x32\x72\x22\xb6\x4c\xf7\x74\x41\x5a\x70\xf7\x24\xcd\xf2\x70\xde\x3f\xe4\x7d\xda\x07\xb6\x1c\x9e\xf2\xa3\x55\x1f\x45\xa5\x58\x48\x60\x24\x8f\xab\xde\x67\x6e\x1c\xd7\x5f\x63\x55\xaa\x3e\xae\xab\xe3\xb5\x1d\xc8\x13\xd9\xfb\x2e\xaa\x4f\x0f\x1d\x9f\x83\x4d\x7c\xad\x9c\x7c\x69\x5a\xe8\x4b\x32\x93\x85\xbc\x0b\xef\x89\x5b\x9f\x1e\xdf\x44\xa0\x3d\x4b\x41\x0c\xc2\x3a\x79\xa6\xb6\x2e\x4f\x34\x6a\x5e\x8d\xd8\x51\xc2\x85\x79\x95\xdd\xbf\x5b\x2d\x71\x7a\xeb\x84\x73\x10\xe1\xf6\xa4\x6a\xc3\xd2\x6a\x7f\x9b\x44\x98\x5a\xf6\x56\xd2\xb7\xc9\x40\x6e\x8a\x9e\x8f\x47\xdc\xb4\xef\x6b\x83\xca\xac\xf9\xae\xfb\x61\x18\xbf\xcf\xf7\xe4\x4b\xef\x69\x37\xeb\xdd\xc8\x91\x86\x83\x9b\x77",
+ "\x84\x97\x0c\x79\x31\x6e\x89\xb7\x0e\x2b\x18\x6a\x69\xdb\x1a\x4c\x3e\x33\xc7\xa3\x76\xb4\x5c\x1b\x79\xbd\x34\x6d\xd3\x3e\xf4\xce",
+ 200 },
+ { GCRY_MD_SHA3_256,
+ "\xfa\x56\xbf\x73\x0c\x4f\x83\x95\x87\x51\x89\xc1\x0c\x4f\xb2\x51\x60\x57\x57\xa8\xfe\xcc\x31\xf9\x73\x7e\x3c\x25\x03\xb0\x26\x08\xe6\x73\x1e\x85\xd7\xa3\x83\x93\xc6\x7d\xe5\x16\xb8\x53\x04\x82\x4b\xfb\x13\x5e\x33\xbf\x22\xb3\xa2\x3b\x91\x3b\xf6\xac\xd2\xb7\xab\x85\x19\x8b\x81\x87\xb2\xbc\xd4\x54\xd5\xe3\x31\x8c\xac\xb3\x2f\xd6\x26\x1c\x31\xae\x7f\x6c\x54\xef\x6a\x7a\x2a\x4c\x9f\x3e\xcb\x81\xce\x35\x55\xd4\xf0\xad\x46\x6d\xd4\xc1\x08\xa9\x03\x99\xd7\x00\x41\x99\x7c\x3b\x25\x34\x5a\x96\x53\xf3\xc9\xa6\x71\x1a\xb1\xb9\x1d\x6a\x9d\x22\x16\x44\x2d\xa2\xc9\x73\xcb\xd6\x85\xee\x76\x43\xbf\xd7\x73\x27\xa2\xf7\xae\x9c\xb2\x83\x62\x0a\x08\x71\x6d\xfb\x46\x2e\x5c\x1d\x65\x43\x2c\xa9\xd5\x6a\x90\xe8\x11\x44\x3c\xd1\xec\xb8\xf0\xde\x17\x9c\x9c\xb4\x8b\xa4\xf6\xfe\xc3\x60\xc6\x6f\x25\x2f\x6e\x64\xed\xc9\x6b",
+ "\x06\xed\x2e\xbc\x41\x9d\x05\x39\x49\xe8\x8c\xc9\xc0\x40\xb1\xeb\xce\x74\x37\x5a\xd0\xce\x09\xc0\xcd\x4d\x56\x2c\x62\xf8\x49\x7d",
+ 201 },
+ { GCRY_MD_SHA3_256,
+ "\xb6\x13\x4f\x9c\x3e\x91\xdd\x80\x00\x74\x0d\x00\x9d\xd8\x06\x24\x08\x11\xd5\x1a\xb1\x54\x6a\x97\x4b\xcb\x18\xd3\x44\x64\x2b\xaa\x5c\xd5\x90\x3a\xf8\x4d\x58\xec\x5b\xa1\x73\x01\xd5\xec\x0f\x10\xcc\xd0\x50\x9c\xbb\x3f\xd3\xff\xf9\x17\x2d\x19\x3a\xf0\xf7\x82\x25\x2f\xd1\x33\x8c\x72\x44\xd4\x0e\x0e\x42\x36\x22\x75\xb2\x2d\x01\xc4\xc3\x38\x9f\x19\xdd\x69\xbd\xf9\x58\xeb\xe2\x8e\x31\xa4\xff\xe2\xb5\xf1\x8a\x87\x83\x1c\xfb\x70\x95\xf5\x8a\x87\xc9\xfa\x21\xdb\x72\xba\x26\x93\x79\xb2\xdc\x23\x84\xb3\xda\x95\x3c\x79\x25\x76\x1f\xed\x32\x46\x20\xac\xea\x43\x5e\x52\xb4\x24\xa7\x72\x3f\x6a\x23\x57\x37\x41\x57\xa3\x4c\xd8\x25\x23\x51\xc2\x5a\x1b\x23\x28\x26\xce\xfe\x1b\xd3\xe7\x0f\xfc\x15\xa3\x1e\x7c\x05\x98\x21\x9d\x7f\x00\x43\x62\x94\xd1\x18\x91\xb8\x24\x97\xbc\x78\xaa\x53\x63\x89\x2a\x24\x95\xdf\x8c\x1e\xef",
+ "\xcf\x90\x60\xaf\x3e\x4e\xd4\x73\x16\xac\xf5\x1e\x5b\x92\x12\x3c\xdc\x48\x27\xbd\x4a\xef\x99\x15\x88\xdc\xd8\x07\x8b\x9e\xea\x40",
+ 202 },
+ { GCRY_MD_SHA3_256,
+ "\xc9\x41\xcd\xb9\xc2\x8a\xb0\xa7\x91\xf2\xe5\xc8\xe8\xbb\x52\x85\x06\x26\xaa\x89\x20\x5b\xec\x3a\x7e\x22\x68\x23\x13\xd1\x98\xb1\xfa\x33\xfc\x72\x95\x38\x13\x54\x85\x87\x58\xae\x6c\x8e\xc6\xfa\xc3\x24\x5c\x6e\x45\x4d\x16\xfa\x2f\x51\xc4\x16\x6f\xab\x51\xdf\x27\x28\x58\xf2\xd6\x03\x77\x0c\x40\x98\x7f\x64\x44\x2d\x48\x7a\xf4\x9c\xd5\xc3\x99\x1c\xe8\x58\xea\x2a\x60\xda\xb6\xa6\x5a\x34\x41\x49\x65\x93\x39\x73\xac\x24\x57\x08\x9e\x35\x91\x60\xb7\xcd\xed\xc4\x2f\x29\xe1\x0a\x91\x92\x17\x85\xf6\xb7\x22\x4e\xe0\xb3\x49\x39\x3c\xdc\xff\x61\x51\xb5\x0b\x37\x7d\x60\x95\x59\x92\x3d\x09\x84\xcd\xa6\x00\x08\x29\xb9\x16\xab\x68\x96\x69\x3e\xf6\xa2\x19\x9b\x3c\x22\xf7\xdc\x55\x00\xa1\x5b\x82\x58\x42\x0e\x31\x4c\x22\x2b\xc0\x00\xbc\x4e\x54\x13\xe6\xdd\x82\xc9\x93\xf8\x33\x0f\x5c\x6d\x1b\xe4\xbc\x79\xf0\x8a\x1a\x0a\x46",
+ "\x63\xe4\x07\x30\x0f\x99\xff\x23\x60\xf0\x2a\xae\x0a\xda\x35\xf6\xc1\xa9\x0a\xed\x2c\x63\x28\x2b\x23\xa7\x99\x0b\xae\x30\x72\x54",
+ 203 },
+ { GCRY_MD_SHA3_256,
+ "\x44\x99\xef\xff\xac\x4b\xce\xa5\x27\x47\xef\xd1\xe4\xf2\x0b\x73\xe4\x87\x58\xbe\x91\x5c\x88\xa1\xff\xe5\x29\x9b\x0b\x00\x58\x37\xa4\x6b\x2f\x20\xa9\xcb\x3c\x6e\x64\xa9\xe3\xc5\x64\xa2\x7c\x0f\x1c\x6a\xd1\x96\x03\x73\x03\x6e\xc5\xbf\xe1\xa8\xfc\x6a\x43\x5c\x21\x85\xed\x0f\x11\x4c\x50\xe8\xb3\xe4\xc7\xed\x96\xb0\x6a\x03\x68\x19\xc9\x46\x3e\x86\x4a\x58\xd6\x28\x6f\x78\x5e\x32\xa8\x04\x44\x3a\x56\xaf\x0b\x4d\xf6\xab\xc5\x7e\xd5\xc2\xb1\x85\xdd\xee\x84\x89\xea\x08\x0d\xee\xee\x66\xaa\x33\xc2\xe6\xda\xb3\x62\x51\xc4\x02\x68\x2b\x68\x24\x82\x1f\x99\x8c\x32\x16\x31\x64\x29\x8e\x1f\xaf\xd3\x1b\xab\xbc\xff\xb5\x94\xc9\x18\x88\xc6\x21\x90\x79\xd9\x07\xfd\xb4\x38\xed\x89\x52\x9d\x6d\x96\x21\x2f\xd5\x5a\xbe\x20\x39\x9d\xbe\xfd\x34\x22\x48\x50\x74\x36\x93\x1c\xde\xad\x49\x6e\xb6\xe4\xa8\x03\x58\xac\xc7\x86\x47\xd0\x43",
+ "\x42\x77\x41\x57\x0d\x5e\x21\x59\x0e\x50\x45\xa8\x45\x02\x16\x36\x5b\xa9\x5c\x2e\x72\x45\x5a\x3d\xbd\x69\x4f\x13\x15\x5d\xe1\xb7",
+ 204 },
+ { GCRY_MD_SHA3_256,
+ "\xee\xcb\xb8\xfd\xfa\x4d\xa6\x21\x70\xfd\x06\x72\x7f\x69\x7d\x81\xf8\x3f\x60\x1f\xf6\x1e\x47\x81\x05\xd3\xcb\x75\x02\xf2\xc8\x9b\xf3\xe8\xf5\x6e\xdd\x46\x9d\x04\x98\x07\xa3\x88\x82\xa7\xee\xfb\xc8\x5f\xc9\xa9\x50\x95\x2e\x9f\xa8\x4b\x8a\xfe\xbd\x3c\xe7\x82\xd4\xda\x59\x80\x02\x82\x7b\x1e\xb9\x88\x82\xea\x1f\x0a\x8f\x7a\xa9\xce\x01\x3a\x6e\x9b\xc4\x62\xfb\x66\xc8\xd4\xa1\x8d\xa2\x14\x01\xe1\xb9\x33\x56\xeb\x12\xf3\x72\x5b\x6d\xb1\x68\x4f\x23\x00\xa9\x8b\x9a\x11\x9e\x5d\x27\xff\x70\x4a\xff\xb6\x18\xe1\x27\x08\xe7\x7e\x6e\x5f\x34\x13\x9a\x5a\x41\x13\x1f\xd1\xd6\x33\x6c\x27\x2a\x8f\xc3\x70\x80\xf0\x41\xc7\x13\x41\xbe\xe6\xab\x55\x0c\xb4\xa2\x0a\x6d\xdb\x6a\x8e\x02\x99\xf2\xb1\x4b\xc7\x30\xc5\x4b\x8b\x1c\x1c\x48\x7b\x49\x4b\xdc\xcf\xd3\xa5\x35\x35\xab\x2f\x23\x15\x90\xbf\x2c\x40\x62\xfd\x2a\xd5\x8f\x90\x6a\x2d\x0d",
+ "\xb5\xe6\x0a\x01\x9e\x84\x14\xd4\x70\xae\x70\x27\x38\xbc\x35\x8f\x1c\x80\xbb\x6f\xf7\xbd\xe4\xf2\xdb\xb5\x6c\x29\x9c\x76\x4b\x16",
+ 205 },
+ { GCRY_MD_SHA3_256,
+ "\xe6\x4f\x3e\x4a\xce\x5c\x84\x18\xd6\x5f\xec\x2b\xc5\xd2\xa3\x03\xdd\x45\x80\x34\x73\x6e\x3b\x0d\xf7\x19\x09\x8b\xe7\xa2\x06\xde\xaf\x52\xd6\xba\x82\x31\x6c\xaf\x33\x0e\xf8\x52\x37\x51\x88\xcd\xe2\xb3\x9c\xc9\x4a\xa4\x49\x57\x8a\x7e\x2a\x8e\x3f\x5a\x9d\x68\xe8\x16\xb8\xd1\x68\x89\xfb\xc0\xeb\xf0\x93\x9d\x04\xf6\x30\x33\xae\x9a\xe2\xbd\xab\x73\xb8\x8c\x26\xd6\xbd\x25\xee\x46\x0e\xe1\xef\x58\xfb\x0a\xfa\x92\xcc\x53\x9f\x8c\x76\xd3\xd0\x97\xe7\xa6\xa6\x3e\xbb\x9b\x58\x87\xed\xf3\xcf\x07\x60\x28\xc5\xbb\xd5\xb9\xdb\x32\x11\x37\x1a\xd3\xfe\x12\x1d\x4e\x9b\xf4\x42\x29\xf4\xe1\xec\xf5\xa0\xf9\xf0\xeb\xa4\xd5\xce\xb7\x28\x78\xab\x22\xc3\xf0\xeb\x5a\x62\x53\x23\xac\x66\xf7\x06\x1f\x4a\x81\xfa\xc8\x34\x47\x1e\x0c\x59\x55\x3f\x10\x84\x75\xfe\x29\x0d\x43\xe6\xa0\x55\xae\x3e\xe4\x6f\xb6\x74\x22\xf8\x14\xa6\x8c\x4b\xe3\xe8\xc9",
+ "\xc9\x86\xbd\xae\x9b\x13\xfb\xc9\x27\x93\x61\x9e\x49\x70\xab\xc3\x33\x98\xf2\xb5\xa5\x7a\x6c\xbb\x40\xa6\x22\x59\x2e\x26\x95\xdf",
+ 206 },
+ { GCRY_MD_SHA3_256,
+ "\xd2\xcb\x2d\x73\x30\x33\xf9\xe9\x13\x95\x31\x28\x08\x38\x3c\xc4\xf0\xca\x97\x4e\x87\xec\x68\x40\x0d\x52\xe9\x6b\x3f\xa6\x98\x4a\xc5\x8d\x9a\xd0\x93\x8d\xde\x5a\x97\x30\x08\xd8\x18\xc4\x96\x07\xd9\xde\x22\x84\xe7\x61\x8f\x1b\x8a\xed\x83\x72\xfb\xd5\x2e\xd5\x45\x57\xaf\x42\x20\xfa\xc0\x9d\xfa\x84\x43\x01\x16\x99\xb9\x7d\x74\x3f\x8f\x2b\x1a\xef\x35\x37\xeb\xb4\x5d\xcc\x9e\x13\xdf\xb4\x38\x42\x8e\xe1\x90\xa4\xef\xdb\x3c\xae\xb7\xf3\x93\x31\x17\xbf\x63\xab\xdc\x7e\x57\xbe\xb4\x17\x1c\x7e\x1a\xd2\x60\xab\x05\x87\x80\x6c\x4d\x13\x7b\x63\x16\xb5\x0a\xbc\x9c\xce\x0d\xff\x3a\xca\xda\x47\xbb\xb8\x6b\xe7\x77\xe6\x17\xbb\xe5\x78\xff\x45\x19\x84\x4d\xb3\x60\xe0\xa9\x6c\x67\x01\x29\x0e\x76\xbb\x95\xd2\x6f\x0f\x80\x4c\x8a\x4f\x27\x17\xea\xc4\xe7\xde\x9f\x2c\xff\x3b\xbc\x55\xa1\x7e\x77\x6c\x0d\x02\x85\x60\x32\xa6\xcd\x10\xad\x28\x38",
+ "\x22\x4c\x7f\xc8\xa0\xec\x38\x95\xe8\x96\x9c\xe7\xc7\xf7\xec\xaa\x54\xfe\x2e\xec\x9a\xb3\x12\x07\x26\x10\x6f\x22\xaa\x29\x75\x41",
+ 207 },
+ { GCRY_MD_SHA3_256,
+ "\xf2\x99\x89\x55\x61\x3d\xd4\x14\xcc\x11\x1d\xf5\xce\x30\xa9\x95\xbb\x79\x2e\x26\x0b\x0e\x37\xa5\xb1\xd9\x42\xfe\x90\x17\x1a\x4a\xc2\xf6\x6d\x49\x28\xd7\xad\x37\x7f\x4d\x05\x54\xcb\xf4\xc5\x23\xd2\x1f\x6e\x5f\x37\x9d\x6f\x4b\x02\x8c\xdc\xb9\xb1\x75\x8d\x3b\x39\x66\x32\x42\xff\x3c\xb6\xed\xe6\xa3\x6a\x6f\x05\xdb\x3b\xc4\x1e\x0d\x86\x1b\x38\x4b\x6d\xec\x58\xbb\x09\x6d\x0a\x42\x2f\xd5\x42\xdf\x17\x5e\x1b\xe1\x57\x1f\xb5\x2a\xe6\x6f\x2d\x86\xa2\xf6\x82\x4a\x8c\xfa\xac\xba\xc4\xa7\x49\x2a\xd0\x43\x3e\xeb\x15\x45\x4a\xf8\xf3\x12\xb3\xb2\xa5\x77\x75\x0e\x3e\xfb\xd3\x70\xe8\xa8\xca\xc1\x58\x25\x81\x97\x1f\xba\x3b\xa4\xbd\x0d\x76\xe7\x18\xda\xcf\x84\x33\xd3\x3a\x59\xd2\x87\xf8\xcc\x92\x23\x4e\x7a\x27\x10\x41\xb5\x26\xe3\x89\xef\xb0\xe4\x0b\x6a\x18\xb3\xaa\xf6\x58\xe8\x2e\xd1\xc7\x86\x31\xfd\x23\xb4\xc3\xeb\x27\xc3\xfa\xec\x86\x85",
+ "\xfa\xf5\xe3\xb7\xa6\x46\x29\xff\xee\xe0\x7a\x67\xed\x77\xa3\xa4\xf6\x7f\x18\xc9\x38\x1f\xe9\xb1\x9f\x6e\xe6\x01\xf5\xfb\x99\xaf",
+ 208 },
+ { GCRY_MD_SHA3_256,
+ "\x44\x77\x97\xe2\x89\x9b\x72\xa3\x56\xba\x55\xbf\x4d\xf3\xac\xca\x6c\xdb\x10\x41\xeb\x47\x7b\xd1\x83\x4a\x9f\x9a\xcb\xc3\x40\xa2\x94\xd7\x29\xf2\xf9\x7d\xf3\xa6\x10\xbe\x0f\xf1\x5e\xdb\x9c\x6d\x5d\xb4\x16\x44\xb9\x87\x43\x60\x14\x0f\xc6\x4f\x52\xaa\x03\xf0\x28\x6c\x8a\x64\x06\x70\x06\x7a\x84\xe0\x17\x92\x6a\x70\x43\x8d\xb1\xbb\x36\x1d\xef\xee\x73\x17\x02\x14\x25\xf8\x82\x1d\xef\x26\xd1\xef\xd7\x7f\xc8\x53\xb8\x18\x54\x5d\x05\x5a\xdc\x92\x84\x79\x6e\x58\x3c\x76\xe6\xfe\x74\xc9\xac\x25\x87\xaa\x46\xaa\x8f\x88\x04\xf2\xfe\xb5\x83\x6c\xc4\xb3\xab\xab\xab\x84\x29\xa5\x78\x3e\x17\xd5\x99\x9f\x32\x24\x2e\xb5\x9e\xf3\x0c\xd7\xad\xab\xc1\x6d\x72\xdb\xdb\x09\x76\x23\x04\x7c\x98\x98\x9f\x88\xd1\x4e\xaf\x02\xa7\x21\x2b\xe1\x6e\xc2\xd0\x79\x81\xaa\xa9\x99\x49\xdd\xf8\x9e\xcd\x90\x33\x3a\x77\xbc\x4e\x19\x88\xa8\x2a\xbf\x7c\x7c\xaf\x32\x91",
+ "\xa8\xa9\x8e\x6b\x3a\x00\x5f\xcb\x31\x9f\xee\x58\xc5\x45\x7d\x04\xb6\x9d\x59\xf5\x38\x73\xf6\xfc\xc6\x06\x5d\x68\xf8\x80\x83\x3f",
+ 209 },
+ { GCRY_MD_SHA3_256,
+ "\x9f\x2c\x18\xad\xe9\xb3\x80\xc7\x84\xe1\x70\xfb\x76\x3e\x9a\xa2\x05\xf6\x43\x03\x06\x7e\xb1\xbc\xea\x93\xdf\x5d\xac\x4b\xf5\xa2\xe0\x0b\x78\x19\x5f\x80\x8d\xf2\x4f\xc7\x6e\x26\xcb\x7b\xe3\x1d\xc3\x5f\x08\x44\xcd\xed\x15\x67\xbb\xa2\x98\x58\xcf\xfc\x97\xfb\x29\x01\x03\x31\xb0\x1d\x6a\x3f\xb3\x15\x9c\xc1\xb9\x73\xd2\x55\xda\x98\x43\xe3\x4a\x0a\x40\x61\xca\xbd\xb9\xed\x37\xf2\x41\xbf\xab\xb3\xc2\x0d\x32\x74\x3f\x40\x26\xb5\x9a\x4c\xcc\x38\x5a\x23\x01\xf8\x3c\x0b\x0a\x19\x0b\x0f\x2d\x01\xac\xb8\xf0\xd4\x11\x11\xe1\x0f\x2f\x4e\x14\x93\x79\x27\x55\x99\xa5\x2d\xc0\x89\xb3\x5f\xdd\x52\x34\xb0\xcf\xb7\xb6\xd8\xae\xbd\x56\x3c\xa1\xfa\x65\x3c\x5c\x02\x1d\xfd\x6f\x59\x20\xe6\xf1\x8b\xfa\xfd\xbe\xcb\xf0\xab\x00\x28\x13\x33\xed\x50\xb9\xa9\x99\x54\x9c\x1c\x8f\x8c\x63\xd7\x62\x6c\x48\x32\x2e\x97\x91\xd5\xff\x72\x29\x40\x49\xbd\xe9\x1e\x73\xf8",
+ "\xc8\x9f\x2b\x34\x61\x27\xea\xb9\xe2\x80\x95\xdc\x44\x91\x8c\x1a\x1a\xae\xae\x04\x86\x1c\x1d\xd0\x14\x4a\x1e\xe0\x7f\x82\x3c\x18",
+ 210 },
+ { GCRY_MD_SHA3_256,
+ "\xae\x15\x9f\x3f\xa3\x36\x19\x00\x2a\xe6\xbc\xce\x8c\xbb\xdd\x7d\x28\xe5\xed\x9d\x61\x53\x45\x95\xc4\xc9\xf4\x3c\x40\x2a\x9b\xb3\x1f\x3b\x30\x1c\xbf\xd4\xa4\x3c\xe4\xc2\x4c\xd5\xc9\x84\x9c\xc6\x25\x9e\xca\x90\xe2\xa7\x9e\x01\xff\xba\xc0\x7b\xa0\xe1\x47\xfa\x42\x67\x6a\x1d\x66\x85\x70\xe0\x39\x63\x87\xb5\xbc\xd5\x99\xe8\xe6\x6a\xae\xd1\xb8\xa1\x91\xc5\xa4\x75\x47\xf6\x13\x73\x02\x1f\xa6\xde\xad\xcb\x55\x36\x3d\x23\x3c\x24\x44\x0f\x2c\x73\xdb\xb5\x19\xf7\xc9\xfa\x5a\x89\x62\xef\xd5\xf6\x25\x2c\x04\x07\xf1\x90\xdf\xef\xad\x70\x7f\x3c\x70\x07\xd6\x9f\xf3\x6b\x84\x89\xa5\xb6\xb7\xc5\x57\xe7\x9d\xd4\xf5\x0c\x06\x51\x1f\x59\x9f\x56\xc8\x96\xb3\x5c\x91\x7b\x63\xba\x35\xc6\xff\x80\x92\xba\xf7\xd1\x65\x8e\x77\xfc\x95\xd8\xa6\xa4\x3e\xeb\x4c\x01\xf3\x3f\x03\x87\x7f\x92\x77\x4b\xe8\x9c\x11\x14\xdd\x53\x1c\x01\x1e\x53\xa3\x4d\xc2\x48\xa2\xf0\xe6",
+ "\xe7\xa8\x1a\xcb\xef\x35\xd7\xb2\x4b\x70\x65\x49\xb4\x1a\xbd\x82\x62\x8c\xcf\xf9\xac\xf4\x1f\x2c\x8a\xdd\x28\x74\x36\x88\xae\x01",
+ 211 },
+ { GCRY_MD_SHA3_256,
+ "\x3b\x8e\x97\xc5\xff\xc2\xd6\xa4\x0f\xa7\xde\x7f\xce\xfc\x90\xf3\xb1\x2c\x94\x0e\x7a\xb4\x15\x32\x1e\x29\xee\x69\x2d\xfa\xc7\x99\xb0\x09\xc9\x9d\xcd\xdb\x70\x8f\xce\x5a\x17\x8c\x5c\x35\xee\x2b\x86\x17\x14\x3e\xdc\x4c\x40\xb4\xd3\x13\x66\x1f\x49\xab\xdd\x93\xce\xa7\x9d\x11\x75\x18\x80\x54\x96\xfe\x6a\xcf\x29\x2c\x4c\x2a\x1f\x76\xb4\x03\xa9\x7d\x7c\x39\x9d\xaf\x85\xb4\x6a\xd8\x4e\x16\x24\x6c\x67\xd6\x83\x67\x57\xbd\xe3\x36\xc2\x90\xd5\xd4\x01\xe6\xc1\x38\x6a\xb3\x27\x97\xaf\x6b\xb2\x51\xe9\xb2\xd8\xfe\x75\x4c\x47\x48\x2b\x72\xe0\xb3\x94\xea\xb7\x69\x16\x12\x6f\xd6\x8e\xa7\xd6\x5e\xb9\x3d\x59\xf5\xb4\xc5\xac\x40\xf7\xc3\xb3\x7e\x7f\x36\x94\xf2\x94\x24\xc2\x4a\xf8\xc8\xf0\xef\x59\xcd\x9d\xbf\x1d\x28\xe0\xe1\x0f\x79\x9a\x6f\x78\xca\xd1\xd4\x5b\x9d\xb3\xd7\xde\xe4\xa7\x05\x9a\xbe\x99\x18\x27\x14\x98\x3b\x9c\x9d\x44\xd7\xf5\x64\x35\x96\xd4\xf3",
+ "\xd8\x12\x49\x14\x3a\x69\xea\x1c\x9d\xc1\x68\xb5\x5f\xfe\x06\xd4\x6d\x0f\xbc\x00\x70\x65\x11\x03\x53\xd7\x6c\x6c\xce\x4f\xfe\x66",
+ 212 },
+ { GCRY_MD_SHA3_256,
+ "\x34\x34\xec\x31\xb1\x0f\xaf\xdb\xfe\xec\x0d\xd6\xbd\x94\xe8\x0f\x7b\xa9\xdc\xa1\x9e\xf0\x75\xf7\xeb\x01\x75\x12\xaf\x66\xd6\xa4\xbc\xf7\xd1\x6b\xa0\x81\x9a\x18\x92\xa6\x37\x2f\x9b\x35\xbc\xc7\xca\x81\x55\xee\x19\xe8\x42\x8b\xc2\x2d\x21\x48\x56\xed\x5f\xa9\x37\x4c\x3c\x09\xbd\xe1\x69\x60\x2c\xc2\x19\x67\x9f\x65\xa1\x56\x6f\xc7\x31\x6f\x4c\xc3\xb6\x31\xa1\x8f\xb4\x44\x9f\xa6\xaf\xa1\x6a\x3d\xb2\xbc\x42\x12\xef\xf5\x39\xc6\x7c\xf1\x84\x68\x08\x26\x53\x55\x89\xc7\x11\x1d\x73\xbf\xfc\xe4\x31\xb4\xc4\x04\x92\xe7\x63\xd9\x27\x95\x60\xaa\xa3\x8e\xb2\xdc\x14\xa2\x12\xd7\x23\xf9\x94\xa1\xfe\x65\x6f\xf4\xdd\x14\x55\x1c\xe4\xe7\xc6\x21\xb2\xaa\x56\x04\xa1\x00\x01\xb2\x87\x8a\x89\x7a\x28\xa0\x80\x95\xc3\x25\xe1\x0a\x26\xd2\xfb\x1a\x75\xbf\xd6\x4c\x25\x03\x09\xbb\x55\xa4\x4f\x23\xbb\xac\x0d\x55\x16\xa1\xc6\x87\xd3\xb4\x1e\xf2\xfb\xbf\x9c\xc5\x6d\x47\x39",
+ "\xaa\x8b\xbd\x48\x12\x14\x22\x11\x21\x27\x63\xbf\x8e\xe4\xd6\xe0\xaa\xda\xfe\x5e\x52\x8a\xea\x1f\xb1\xbe\x11\x88\x06\xe4\x9f\x66",
+ 213 },
+ { GCRY_MD_SHA3_256,
+ "\x7c\x79\x53\xd8\x1c\x8d\x20\x8f\xd1\xc9\x76\x81\xd4\x8f\x49\xdd\x00\x34\x56\xde\x60\x47\x5b\x84\x07\x0e\xf4\x84\x7c\x33\x3b\x74\x57\x5b\x1f\xc8\xd2\xa1\x86\x96\x44\x85\xa3\xb8\x63\x4f\xea\xa3\x59\x5a\xaa\x1a\x2f\x45\x95\xa7\xd6\xb6\x15\x35\x63\xde\xe3\x1b\xba\xc4\x43\xc8\xa3\x3e\xed\x6d\x5d\x95\x6a\x98\x0a\x68\x36\x6c\x25\x27\xb5\x50\xee\x95\x02\x50\xdf\xb6\x91\xea\xcb\xd5\xd5\x6a\xe1\x4b\x97\x06\x68\xbe\x17\x4c\x89\xdf\x2f\xea\x43\xae\x52\xf1\x31\x42\x63\x9c\x88\x4f\xd6\x2a\x36\x83\xc0\xc3\x79\x2f\x0f\x24\xab\x13\x18\xbc\xb2\x7e\x21\xf4\x73\x7f\xab\x62\xc7\x7e\xa3\x8b\xc8\xfd\x1c\xf4\x1f\x7d\xab\x64\xc1\x3f\xeb\xe7\x15\x2b\xf5\xbb\x7a\xb5\xa7\x8f\x53\x46\xd4\x3c\xc7\x41\xcb\x6f\x72\xb7\xb8\x98\x0f\x26\x8b\x68\xbf\x62\xab\xdf\xb1\x57\x7a\x52\x43\x8f\xe1\x4b\x59\x14\x98\xcc\x95\xf0\x71\x22\x84\x60\xc7\xc5\xd5\xce\xb4\xa7\xbd\xe5\x88\xe7\xf2\x1c",
+ "\x40\x89\xb1\x81\xdf\x5e\xca\x5f\x14\xda\xb1\x05\x7a\xaa\xee\xca\xba\x15\xf2\x00\xfd\xda\x0d\xe4\x93\x57\xd6\x19\x6f\xaa\xb4\x4b",
+ 214 },
+ { GCRY_MD_SHA3_256,
+ "\x7a\x6a\x4f\x4f\xdc\x59\xa1\xd2\x23\x38\x1a\xe5\xaf\x49\x8d\x74\xb7\x25\x2e\xcf\x59\xe3\x89\xe4\x91\x30\xc7\xea\xee\x62\x6e\x7b\xd9\x89\x7e\xff\xd9\x20\x17\xf4\xcc\xde\x66\xb0\x44\x04\x62\xcd\xed\xfd\x35\x2d\x81\x53\xe6\xa4\xc8\xd7\xa0\x81\x2f\x70\x1c\xc7\x37\xb5\x17\x8c\x25\x56\xf0\x71\x11\x20\x0e\xb6\x27\xdb\xc2\x99\xca\xa7\x92\xdf\xa5\x8f\x35\x93\x52\x99\xfa\x3a\x35\x19\xe9\xb0\x31\x66\xdf\xfa\x15\x91\x03\xff\xa3\x5e\x85\x77\xf7\xc0\xa8\x6c\x6b\x46\xfe\x13\xdb\x8e\x2c\xdd\x9d\xcf\xba\x85\xbd\xdd\xcc\xe0\xa7\xa8\xe1\x55\xf8\x1f\x71\x2d\x8e\x9f\xe6\x46\x15\x3d\x3d\x22\xc8\x11\xbd\x39\xf8\x30\x43\x3b\x22\x13\xdd\x46\x30\x19\x41\xb5\x92\x93\xfd\x0a\x33\xe2\xb6\x3a\xdb\xd9\x52\x39\xbc\x01\x31\x5c\x46\xfd\xb6\x78\x87\x5b\x3c\x81\xe0\x53\xa4\x0f\x58\x1c\xfb\xec\x24\xa1\x40\x4b\x16\x71\xa1\xb8\x8a\x6d\x06\x12\x02\x29\x51\x8f\xb1\x3a\x74\xca\x0a\xc5\xae",
+ "\xde\xbf\x59\xbb\x23\x3d\x05\x54\x98\x53\x80\x4f\xc6\x78\x40\x82\x1b\xd5\x80\x2f\x87\xfc\x8a\x91\x5b\x71\x0d\x3e\x82\x07\x09\x50",
+ 215 },
+ { GCRY_MD_SHA3_256,
+ "\xd9\xfa\xa1\x4c\xeb\xe9\xb7\xde\x55\x1b\x6c\x07\x65\x40\x9a\x33\x93\x85\x62\x01\x3b\x5e\x8e\x0e\x1e\x0a\x64\x18\xdf\x73\x99\xd0\xa6\xa7\x71\xfb\x81\xc3\xca\x9b\xd3\xbb\x8e\x29\x51\xb0\xbc\x79\x25\x25\xa2\x94\xeb\xd1\x08\x36\x88\x80\x6f\xe5\xe7\xf1\xe1\x7f\xd4\xe3\xa4\x1d\x00\xc8\x9e\x8f\xcf\x4a\x36\x3c\xae\xdb\x1a\xcb\x55\x8e\x3d\x56\x2f\x13\x02\xb3\xd8\x3b\xb8\x86\xed\x27\xb7\x60\x33\x79\x81\x31\xda\xb0\x5b\x42\x17\x38\x1e\xaa\xa7\xba\x15\xec\x82\x0b\xb5\xc1\x3b\x51\x6d\xd6\x40\xea\xec\x5a\x27\xd0\x5f\xdf\xca\x0f\x35\xb3\xa5\x31\x21\x46\x80\x6b\x4c\x02\x75\xbc\xd0\xaa\xa3\xb2\x01\x7f\x34\x69\x75\xdb\x56\x6f\x9b\x4d\x13\x7f\x4e\xe1\x06\x44\xc2\xa2\xda\x66\xde\xec\xa5\x34\x2e\x23\x64\x95\xc3\xc6\x28\x05\x28\xbf\xd3\x2e\x90\xaf\x4c\xd9\xbb\x90\x8f\x34\x01\x2b\x52\xb4\xbc\x56\xd4\x8c\xc8\xa6\xb5\x9b\xab\x01\x49\x88\xea\xbd\x12\xe1\xa0\xa1\xc2\xe1\x70\xe7",
+ "\x0f\xdb\xa1\xc7\x9f\x55\xf2\x33\xa1\x21\x7f\x52\x2d\x6c\x81\xf7\x77\xf3\x30\xfa\xdb\x56\x5e\x11\x71\xf3\x9e\x17\x88\x91\x33\x42",
+ 216 },
+ { GCRY_MD_SHA3_256,
+ "\x2d\x84\x27\x43\x3d\x0c\x61\xf2\xd9\x6c\xfe\x80\xcf\x1e\x93\x22\x65\xa1\x91\x36\x5c\x3b\x61\xaa\xa3\xd6\xdc\xc0\x39\xf6\xba\x2a\xd5\x2a\x6a\x8c\xc3\x0f\xc1\x0f\x70\x5e\x6b\x77\x05\x10\x59\x77\xfa\x49\x6c\x1c\x70\x8a\x27\x7a\x12\x43\x04\xf1\xfc\x40\x91\x1e\x74\x41\xd1\xb5\xe7\x7b\x95\x1a\xad\x7b\x01\xfd\x5d\xb1\xb3\x77\xd1\x65\xb0\x5b\xbf\x89\x80\x42\xe3\x96\x60\xca\xf8\xb2\x79\xfe\x52\x29\xd1\xa8\xdb\x86\xc0\x99\x9e\xd6\x5e\x53\xd0\x1c\xcb\xc4\xb4\x31\x73\xcc\xf9\x92\xb3\xa1\x45\x86\xf6\xba\x42\xf5\xfe\x30\xaf\xa8\xae\x40\xc5\xdf\x29\x96\x6f\x93\x46\xda\x5f\x8b\x35\xf1\x6a\x1d\xe3\xab\x6d\xe0\xf4\x77\xd8\xd8\x66\x09\x18\x06\x0e\x88\xb9\xb9\xe9\xca\x6a\x42\x07\x03\x3b\x87\xa8\x12\xdb\xf5\x54\x4d\x39\xe4\x88\x20\x10\xf8\x2b\x6c\xe0\x05\xf8\xe8\xff\x6f\xe3\xc3\x80\x6b\xc2\xb7\x3c\x2b\x83\xaf\xb7\x04\x34\x56\x29\x30\x4f\x9f\x86\x35\x87\x12\xe9\xfa\xe3\xca\x3e",
+ "\xed\x45\xa0\x6e\x95\xa6\x53\x92\x70\xb0\x22\x90\xd7\x10\x05\xf0\x1c\x55\xba\x07\x74\x14\xc3\xbc\xdb\x37\x95\x37\xe6\xdb\xef\xc9",
+ 217 },
+ { GCRY_MD_SHA3_256,
+ "\x5e\x19\xd9\x78\x87\xfc\xaa\xc0\x38\x7e\x22\xc6\xf8\x03\xc3\x4a\x3d\xac\xd2\x60\x41\x72\x43\x3f\x7a\x8a\x7a\x52\x6c\xa4\xa2\xa1\x27\x1e\xcf\xc5\xd5\xd7\xbe\x5a\xc0\xd8\x5d\x92\x10\x95\x35\x0d\xfc\x65\x99\x7d\x44\x3c\x21\xc8\x09\x4e\x0a\x3f\xef\xd2\x96\x1b\xcb\x94\xae\xd0\x32\x91\xae\x31\x0c\xcd\xa7\x5d\x8a\xce\x4b\xc7\xd8\x9e\x7d\x3e\x5d\x16\x50\xbd\xa5\xd6\x68\xb8\xb5\x0b\xfc\x8e\x60\x8e\x18\x4f\x4d\x3a\x9a\x2b\xad\xc4\xff\x5f\x07\xe0\xc0\xbc\x8a\x9f\x2e\x0b\x2a\x26\xfd\x6d\x8c\x55\x00\x08\xfa\xaa\xb7\x5f\xd7\x1a\xf2\xa4\x24\xbe\xc9\xa7\xcd\x9d\x83\xfa\xd4\xc8\xe9\x31\x91\x15\x65\x6a\x87\x17\xd3\xb5\x23\xa6\x8f\xf8\x00\x42\x58\xb9\x99\x0e\xd3\x62\x30\x84\x61\x80\x4b\xa3\xe3\xa7\xe9\x2d\x8f\x2f\xfa\xe5\xc2\xfb\xa5\x5b\xa5\xa3\xc2\x7c\x0a\x2f\x71\xbd\x71\x1d\x2f\xe1\x79\x9c\x2a\xdb\x31\xb2\x00\x03\x54\x81\xe9\xee\x5c\x4a\xdf\x2a\xb9\xc0\xfa\x50\xb2\x39\x75\xcf",
+ "\x37\xe7\xcf\x6a\x9a\x31\xb0\x98\x2b\x24\x79\x43\x2b\x78\x38\x65\x77\x41\xb0\xee\x79\xad\xda\x1b\x28\x75\x50\xeb\x32\x5c\x78\xcc",
+ 218 },
+ { GCRY_MD_SHA3_256,
+ "\xc8\xe9\x76\xab\x46\x38\x90\x93\x87\xce\x3b\x8d\x4e\x51\x0c\x32\x30\xe5\x69\x0e\x02\xc4\x50\x93\xb1\xd2\x97\x91\x0a\xbc\x48\x1e\x56\xee\xa0\xf2\x96\xf9\x83\x79\xdf\xc9\x08\x0a\xf6\x9e\x73\xb2\x39\x9d\x1c\x14\x3b\xee\x80\xae\x13\x28\x16\x2c\xe1\xba\x7f\x6a\x83\x74\x67\x9b\x20\xaa\xcd\x38\x0e\xb4\xe6\x13\x82\xc9\x99\x98\x70\x4d\x62\x70\x1a\xfa\x91\x4f\x9a\x27\x05\xcd\xb0\x65\x88\x5f\x50\xd0\x86\xc3\xeb\x57\x53\x70\x0c\x38\x71\x18\xbb\x14\x2f\x3e\x6d\xa1\xe9\x88\xdf\xb3\x1a\xc7\x5d\x73\x68\x93\x1e\x45\xd1\x39\x1a\x27\x4b\x22\xf8\x3c\xeb\x07\x2f\x9b\xca\xbc\x0b\x21\x66\x85\xbf\xd7\x89\xf5\x02\x39\x71\x02\x4b\x18\x78\xa2\x05\x44\x25\x22\xf9\xea\x7d\x87\x97\xa4\x10\x2a\x3d\xf4\x17\x03\x76\x82\x51\xfd\x5e\x01\x7c\x85\xd1\x20\x0a\x46\x41\x18\xaa\x35\x65\x4e\x7c\xa3\x9f\x3c\x37\x5b\x8e\xf8\xcb\xe7\x53\x4d\xbc\x64\xbc\x20\xbe\xfb\x41\x7c\xf6\x0e\xc9\x2f\x63\xd9\xee\x73\x97",
+ "\x37\x37\x04\xf6\x41\xfa\xf2\xb9\x18\xe2\x2e\x91\x42\xab\xf6\xb4\xac\x71\xb6\x88\x3a\xc4\xd7\xa0\x75\xf6\x26\xe9\x47\x83\x7d\x3f",
+ 219 },
+ { GCRY_MD_SHA3_256,
+ "\x71\x45\xfa\x12\x4b\x74\x29\xa1\xfc\x22\x31\x23\x7a\x94\x9b\xa7\x20\x1b\xcc\x18\x22\xd3\x27\x2d\xe0\x05\xb6\x82\x39\x81\x96\xc2\x5f\x7e\x5c\xc2\xf2\x89\xfb\xf4\x44\x15\xf6\x99\xcb\x7f\xe6\x75\x77\x91\xb1\x44\x34\x10\x23\x4a\xe0\x61\xed\xf6\x23\x35\x9e\x2b\x4e\x32\xc1\x9b\xf8\x84\x50\x43\x2d\xd0\x1c\xaa\x5e\xb1\x6a\x1d\xc3\x78\xf3\x91\xca\x5e\x3c\x4e\x5f\x35\x67\x28\xbd\xdd\x49\x75\xdb\x7c\x89\x0d\xa8\xbb\xc8\x4c\xc7\x3f\xf2\x44\x39\x4d\x0d\x48\x95\x49\x78\x76\x5e\x4a\x00\xb5\x93\xf7\x0f\x2c\xa0\x82\x67\x3a\x26\x1e\xd8\x8d\xbc\xef\x11\x27\x72\x8d\x8c\xd8\x9b\xc2\xc5\x97\xe9\x10\x2c\xed\x60\x10\xf6\x5f\xa7\x5a\x14\xeb\xe4\x67\xfa\x57\xce\x3b\xd4\x94\x8b\x68\x67\xd7\x4a\x9d\xf5\xc0\xec\x6f\x53\x0c\xbf\x2e\xe6\x1c\xe6\xf0\x6b\xc8\xf2\x86\x4d\xff\x55\x83\x77\x6b\x31\xdf\x8c\x7f\xfc\xb6\x14\x28\xa5\x6b\xf7\xbd\x37\x18\x8b\x4a\x51\x23\xbb\xf3\x38\x39\x3a\xf4\x6e\xda\x85\xe6",
+ "\xee\x59\x94\xb3\xd3\x2b\xda\xe5\x8e\x72\x56\x6f\xc2\x4b\x88\x64\x61\x21\x7f\xdd\x72\x73\xe1\x60\x8f\x0b\x29\x26\xb7\x92\x35\x46",
+ 220 },
+ { GCRY_MD_SHA3_256,
+ "\x7f\xdf\xad\xcc\x9d\x29\xba\xd2\x3a\xe0\x38\xc6\xc6\x5c\xda\x1a\xef\x75\x72\x21\xb8\x87\x2e\xd3\xd7\x5f\xf8\xdf\x7d\xa0\x62\x7d\x26\x6e\x22\x4e\x81\x2c\x39\xf7\x98\x3e\x45\x58\xbf\xd0\xa1\xf2\xbe\xf3\xfe\xb5\x6b\xa0\x91\x20\xef\x76\x29\x17\xb9\xc0\x93\x86\x79\x48\x54\x7a\xee\x98\x60\x0d\x10\xd8\x7b\x20\x10\x68\x78\xa8\xd2\x2c\x64\x37\x8b\xf6\x34\xf7\xf7\x59\x00\xc0\x39\x86\xb0\x77\xb0\xbf\x8b\x74\x0a\x82\x44\x7b\x61\xb9\x9f\xee\x53\x76\xc5\xeb\x66\x80\xec\x9e\x30\x88\xf0\xbd\xd0\xc5\x68\x83\x41\x3d\x60\xc1\x35\x7d\x3c\x81\x19\x50\xe5\x89\x0e\x76\x00\x10\x3c\x91\x63\x41\xb8\x0c\x74\x3c\x6a\x85\x2b\x7b\x4f\xb6\x0c\x3b\xa2\x1f\x3b\xc1\x5b\x83\x82\x43\x7a\x68\x45\x47\x79\xcf\x3c\xd7\xf9\xf9\x0c\xcc\x8e\xf2\x8d\x0b\x70\x65\x35\xb1\xe4\x10\x8e\xb5\x62\x7b\xb4\x5d\x71\x9c\xb0\x46\x83\x9a\xee\x31\x1c\xa1\xab\xdc\x83\x19\xe0\x50\xd6\x79\x72\xcb\x35\xa6\xb1\x60\x1b\x25\xdb\xf4\x87",
+ "\x6a\x58\x4f\x9f\x4a\xcd\x8f\xc8\xe1\x5d\xac\xd3\x26\x29\x1f\xe9\x31\x1c\x20\x98\x72\x25\xc5\x1c\xf4\x25\x1e\x52\xb4\x7f\xa2\x23",
+ 221 },
+ { GCRY_MD_SHA3_256,
+ "\x98\x86\x38\x21\x9f\xd3\x09\x54\x21\xf8\x26\xf5\x6e\x4f\x09\xe3\x56\x29\x6b\x62\x8c\x3c\xe6\x93\x0c\x9f\x2e\x75\x8f\xd1\xa8\x0c\x82\x73\xf2\xf6\x1e\x4d\xaa\xe6\x5c\x4f\x11\x0d\x3e\x7c\xa0\x96\x5a\xc7\xd2\x4e\x34\xc0\xdc\x4b\xa2\xd6\xff\x0b\xf5\xbb\xe9\x3b\x35\x85\xf3\x54\xd7\x54\x3c\xb5\x42\xa1\xaa\x54\x67\x4d\x37\x50\x77\xf2\xd3\x60\xa8\xf4\xd4\x2f\x3d\xb1\x31\xc3\xb7\xab\x73\x06\x26\x7b\xa1\x07\x65\x98\x64\xa9\x0c\x8c\x90\x94\x60\xa7\x36\x21\xd1\xf5\xd9\xd3\xfd\x95\xbe\xb1\x9b\x23\xdb\x1c\xb6\xc0\xd0\xfb\xa9\x1d\x36\x89\x15\x29\xb8\xbd\x82\x63\xca\xa1\xba\xb5\x6a\x4a\xff\xae\xd4\x49\x62\xdf\x09\x6d\x8d\x5b\x1e\xb8\x45\xef\x31\x18\x8b\x3e\x10\xf1\xaf\x81\x1a\x13\xf1\x56\xbe\xb7\xa2\x88\xaa\xe5\x93\xeb\xd1\x47\x1b\x62\x4a\xa1\xa7\xc6\xad\xf0\x1e\x22\x00\xb3\xd7\x2d\x88\xa3\xae\xd3\x10\x0c\x88\x23\x1e\x41\xef\xc3\x76\x90\x6f\x0b\x58\x0d\xc8\x95\xf0\x80\xfd\xa5\x74\x1d\xb1\xcb",
+ "\x4f\x92\x83\x9c\xdd\xb0\xdf\x31\xd1\x6a\x0d\xb5\x3b\xbe\x07\x69\x8a\x7c\x19\x12\xd5\x59\x0d\x21\x15\x5d\x45\xdb\x1b\x48\xca\xb4",
+ 222 },
+ { GCRY_MD_SHA3_256,
+ "\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",
+ "\xea\xfd\x66\x1f\x34\x3a\xe8\x34\xc6\x21\xe0\x74\xac\x69\x03\xa2\xe3\xe6\x32\x4f\x36\x5b\x34\x32\xdf\xfa\x73\x2f\x47\x7a\xc1\x29",
+ 223 },
+ { GCRY_MD_SHA3_256,
+ "\x47\xb8\x21\x6a\xa0\xfb\xb5\xd6\x79\x66\xf2\xe8\x2c\x17\xc0\x7a\xa2\xd6\x32\x7e\x96\xfc\xd8\x3e\x3d\xe7\x33\x36\x89\xf3\xee\x79\x99\x4a\x1b\xf4\x50\x82\xc4\xd7\x25\xed\x8d\x41\x20\x5c\xb5\xbc\xdf\x5c\x34\x1f\x77\xfa\xcb\x1d\xa4\x6a\x5b\x9b\x2c\xbc\x49\xea\xdf\x78\x6b\xcd\x88\x1f\x37\x1a\x95\xfa\x17\xdf\x73\xf6\x06\x51\x9a\xea\x0f\xf7\x9d\x5a\x11\x42\x7b\x98\xee\x7f\x13\xa5\xc0\x06\x37\xe2\x85\x41\x34\x69\x10\x59\x83\x91\x21\xfe\xa9\xab\xe2\xcd\x1b\xcb\xbb\xf2\x7c\x74\xca\xf3\x67\x8e\x05\xbf\xb1\xc9\x49\x89\x7e\xa0\x1f\x56\xff\xa4\xda\xfb\xe8\x64\x46\x11\x68\x5c\x61\x7a\x32\x06\xc7\xa7\x03\x6e\x4a\xc8\x16\x79\x9f\x69\x3d\xaf\xe7\xf1\x9f\x30\x3c\xe4\xeb\xa0\x9d\x21\xe0\x36\x10\x20\x1b\xfc\x66\x5b\x72\x40\x0a\x54\x7a\x1e\x00\xfa\x9b\x7a\xd8\xd8\x4f\x84\xb3\x4a\xef\x11\x85\x15\xe7\x4d\xef\x11\xb9\x18\x8b\xd1\xe1\xf9\x7d\x9a\x12\xc3\x01\x32\xec\x28\x06\x33\x9b\xda\xda\xcd\xa2\xfd\x8b\x78",
+ "\x3d\xce\xc6\x69\xc5\xd0\x17\x6b\x1b\xdc\x00\x27\x28\xd2\x42\xc5\x87\xdd\xa0\x3b\x3a\xbf\xa6\x07\x45\x23\xd3\xfa\xef\x48\x20\xbe",
+ 224 },
+ { GCRY_MD_SHA3_256,
+ "\x8c\xff\x1f\x67\xfe\x53\xc0\x98\x89\x6d\x91\x36\x38\x9b\xd8\x88\x18\x16\xcc\xab\x34\x86\x2b\xb6\x7a\x65\x6e\x3d\x98\x89\x6f\x3c\xe6\xff\xd4\xda\x73\x97\x58\x09\xfc\xdf\x96\x66\x76\x0d\x6e\x56\x1c\x55\x23\x8b\x20\x5d\x80\x49\xc1\xce\xde\xef\x37\x4d\x17\x35\xda\xa5\x33\x14\x7b\xfa\x96\x0b\x2c\xce\x4a\x4f\x25\x41\x76\xbb\x4d\x1b\xd1\xe8\x96\x54\x43\x2b\x8d\xbe\x1a\x13\x5c\x42\x11\x5b\x39\x4b\x02\x48\x56\xa2\xa8\x3d\xc8\x5d\x67\x82\xbe\x4b\x44\x42\x39\x56\x7c\xce\xc4\xb1\x84\xd4\x54\x8e\xae\x3f\xf6\xa1\x92\xf3\x43\x29\x2b\xa2\xe3\x2a\x0f\x26\x7f\x31\xcc\x26\x71\x9e\xb8\x52\x45\xd4\x15\xfb\x89\x7a\xc2\xda\x43\x3e\xe9\x1a\x99\x42\x4c\x9d\x7f\x17\x66\xa4\x41\x71\xd1\x65\x10\x01\xc3\x8f\xc7\x92\x94\xac\xcc\x68\xce\xb5\x66\x5d\x36\x21\x84\x54\xd3\xba\x16\x9a\xe0\x58\xa8\x31\x33\x8c\x17\x74\x36\x03\xf8\x1e\xe1\x73\xbf\xc0\x92\x74\x64\xf9\xbd\x72\x8d\xee\x94\xc6\xae\xab\x7a\xae\x6e\xe3\xa6\x27\xe8",
+ "\x4b\xdf\x73\x1b\xbb\x3d\x0e\x2a\xb0\xeb\x3d\x97\x21\x23\xa7\xa0\xa0\x85\xe8\xa9\x8a\xc6\xaf\x8a\xdb\xd3\x35\xb3\x72\x75\xdd\xff",
+ 225 },
+ { GCRY_MD_SHA3_256,
+ "\xea\xcd\x07\x97\x1c\xff\x9b\x99\x39\x90\x3f\x8c\x1d\x8c\xbb\x5d\x4d\xb1\xb5\x48\xa8\x5d\x04\xe0\x37\x51\x4a\x58\x36\x04\xe7\x87\xf3\x29\x92\xbf\x21\x11\xb9\x7a\xc5\xe8\xa9\x38\x23\x35\x52\x73\x13\x21\x52\x2a\xb5\xe8\x58\x35\x61\x26\x0b\x7d\x13\xeb\xee\xf7\x85\xb2\x3a\x41\xfd\x85\x76\xa6\xda\x76\x4a\x8e\xd6\xd8\x22\xd4\x95\x7a\x54\x5d\x52\x44\x75\x6c\x18\xaa\x80\xe1\xaa\xd4\xd1\xf9\xc2\x0d\x25\x9d\xee\x17\x11\xe2\xcc\x8f\xd0\x13\x16\x9f\xb7\xcc\x4c\xe3\x8b\x36\x2f\x8e\x09\x36\xae\x91\x98\xb7\xe8\x38\xdc\xea\x4f\x7a\x5b\x94\x29\xbb\x3f\x6b\xbc\xf2\xdc\x92\x56\x5e\x36\x76\xc1\xc5\xe6\xeb\x3d\xd2\xa0\xf8\x6a\xa2\x3e\xdd\x3d\x08\x91\xf1\x97\x44\x76\x92\x79\x4b\x3d\xfa\x26\x96\x11\xad\x97\xf7\x2b\x79\x56\x02\xb4\xfd\xb1\x98\xf3\xfd\x3e\xb4\x1b\x41\x50\x64\x25\x6e\x34\x5e\x8d\x8c\x51\xc5\x55\xdc\x8a\x21\x90\x4a\x9b\x0f\x1a\xd0\xef\xfa\xb7\x78\x6a\xac\x2d\xa3\xb1\x96\x50\x7e\x9f\x33\xca\x35\x64\x27",
+ "\x47\xf9\x04\xfe\xea\x60\x72\x25\xca\xb2\xe3\xc5\x27\x48\x87\x89\x64\xbf\xed\xcf\xe0\x68\x72\x7d\xe6\x10\xf6\x34\x21\x36\x7b\xcf",
+ 226 },
+ { GCRY_MD_SHA3_256,
+ "\x23\xac\x4e\x9a\x42\xc6\xef\x45\xc3\x33\x6c\xe6\xdf\xc2\xff\x7d\xe8\x88\x4c\xd2\x3d\xc9\x12\xfe\xf0\xf7\x75\x6c\x09\xd3\x35\xc1\x89\xf3\xad\x3a\x23\x69\x7a\xbd\xa8\x51\xa8\x18\x81\xa0\xc8\xcc\xaf\xc9\x80\xab\x2c\x70\x25\x64\xc2\xbe\x15\xfe\x4c\x4b\x9f\x10\xdf\xb2\x24\x8d\x0d\x0c\xb2\xe2\x88\x7f\xd4\x59\x8a\x1d\x4a\xcd\xa8\x97\x94\x4a\x2f\xfc\x58\x0f\xf9\x27\x19\xc9\x5c\xf2\xaa\x42\xdc\x58\x46\x74\xcb\x5a\x9b\xc5\x76\x5b\x9d\x6d\xdf\x57\x89\x79\x1d\x15\xf8\xdd\x92\x5a\xa1\x2b\xff\xaf\xbc\xe6\x08\x27\xb4\x90\xbb\x7d\xf3\xdd\xa6\xf2\xa1\x43\xc8\xbf\x96\xab\xc9\x03\xd8\x3d\x59\xa7\x91\xe2\xd6\x28\x14\xa8\x9b\x80\x80\xa2\x80\x60\x56\x8c\xf2\x4a\x80\xae\x61\x17\x9f\xe8\x4e\x0f\xfa\xd0\x03\x88\x17\x8c\xb6\xa6\x17\xd3\x7e\xfd\x54\xcc\x01\x97\x0a\x4a\x41\xd1\xa8\xd3\xdd\xce\x46\xed\xbb\xa4\xab\x7c\x90\xad\x56\x53\x98\xd3\x76\xf4\x31\x18\x9c\xe8\xc1\xc3\x3e\x13\x2f\xea\xe6\xa8\xcd\x17\xa6\x1c\x63\x00\x12",
+ "\x32\x49\x37\x60\x7d\x9f\x16\xaf\x81\x57\x01\x74\x9f\x03\x77\xb3\x28\x1a\xf9\xc5\xbb\x56\x5d\x6f\x2b\x96\x11\x53\x2b\x6b\xf0\x44",
+ 227 },
+ { GCRY_MD_SHA3_256,
+ "\x01\x72\xdf\x73\x22\x82\xc9\xd4\x88\x66\x9c\x35\x8e\x34\x92\x26\x0c\xbe\x91\xc9\x5c\xfb\xc1\xe3\xfe\xa6\xc4\xb0\xec\x12\x9b\x45\xf2\x42\xac\xe0\x9f\x15\x2f\xc6\x23\x4e\x1b\xee\x8a\xab\x8c\xd5\x6e\x8b\x48\x6e\x1d\xcb\xa9\xc0\x54\x07\xc2\xf9\x5d\xa8\xd8\xf1\xc0\xaf\x78\xee\x2e\xd8\x2a\x3a\x79\xec\x0c\xb0\x70\x93\x96\xee\x62\xaa\xdb\x84\xf8\xa4\xee\x8a\x7c\xcc\xa3\xc1\xee\x84\xe3\x02\xa0\x9e\xa8\x02\x20\x4a\xfe\xcf\x04\x09\x7e\x67\xd0\xf8\xe8\xa9\xd2\x65\x11\x26\xc0\xa5\x98\xa3\x70\x81\xe4\x2d\x16\x8b\x0a\xe8\xa7\x19\x51\xc5\x24\x25\x9e\x4e\x20\x54\xe5\x35\xb7\x79\x67\x9b\xda\xde\x56\x6f\xe5\x57\x00\x85\x86\x18\xe6\x26\xb4\xa0\xfa\xf8\x95\xbc\xce\x90\x11\x50\x4a\x49\xe0\x5f\xd5\x61\x27\xea\xe3\xd1\xf8\x91\x7a\xfb\x54\x8e\xca\xda\xbd\xa1\x02\x01\x11\xfe\xc9\x31\x4c\x41\x34\x98\xa3\x60\xb0\x86\x40\x54\x9a\x22\xcb\x23\xc7\x31\xac\xe7\x43\x25\x2a\x82\x27\xa0\xd2\x68\x9d\x4c\x60\x01\x60\x66\x78\xdf\xb9\x21",
+ "\xb9\x84\xc2\xd6\xb6\xfd\xc2\x85\x74\xaa\xd5\x51\xfc\x16\xb6\x8f\x85\xbf\x6c\xc4\x80\xa1\x5c\x12\x8a\xe5\x61\x65\x61\xd4\x67\x21",
+ 228 },
+ { GCRY_MD_SHA3_256,
+ "\x38\x75\xb9\x24\x0c\xf3\xe0\xa8\xb5\x9c\x65\x85\x40\xf2\x6a\x70\x1c\xf1\x88\x49\x6e\x2c\x21\x74\x78\x8b\x12\x6f\xd2\x94\x02\xd6\xa7\x54\x53\xba\x06\x35\x28\x4d\x08\x83\x5f\x40\x05\x1a\x2a\x96\x83\xdc\x92\xaf\xb9\x38\x37\x19\x19\x12\x31\x17\x03\x79\xba\x6f\x4a\xdc\x81\x6f\xec\xbb\x0f\x9c\x44\x6b\x78\x5b\xf5\x20\x79\x68\x41\xe5\x88\x78\xb7\x3c\x58\xd3\xeb\xb0\x97\xce\x47\x61\xfd\xea\xbe\x15\xde\x2f\x31\x9d\xfb\xaf\x17\x42\xcd\xeb\x38\x95\x59\xc7\x88\x13\x1a\x67\x93\xe1\x93\x85\x66\x61\x37\x6c\x81\xce\x95\x68\xda\x19\xaa\x69\x25\xb4\x7f\xfd\x77\xa4\x3c\x7a\x0e\x75\x8c\x37\xd6\x92\x54\x90\x9f\xf0\xfb\xd4\x15\xef\x8e\xb9\x37\xbc\xd4\x9f\x91\x46\x8b\x49\x97\x4c\x07\xdc\x81\x9a\xbd\x67\x39\x5d\xb0\xe0\x58\x74\xff\x83\xdd\xda\xb8\x95\x34\x4a\xbd\x0e\x71\x11\xb2\xdf\x9e\x58\xd7\x6d\x85\xad\x98\x10\x6b\x36\x29\x58\x26\xbe\x04\xd4\x35\x61\x55\x95\x60\x5e\x4b\x4b\xb8\x24\xb3\x3c\x4a\xfe\xb5\xe7\xbb\x0d\x19\xf9\x09",
+ "\x91\xa5\xb9\xfc\x2d\xcc\x5f\xae\xda\x57\xd2\xe7\xa4\x1e\x92\x2d\xc3\x2d\x57\x2a\xeb\xdf\x6d\x54\xcb\x8c\x3a\xe4\x24\x5e\x85\x65",
+ 229 },
+ { GCRY_MD_SHA3_256,
+ "\x74\x7c\xc1\xa5\x9f\xef\xba\x94\xa9\xc7\x5b\xa8\x66\xc3\x0d\xc5\xc1\xcb\x0c\x0f\x8e\x93\x61\xd9\x84\x84\x95\x6d\xd5\xd1\xa4\x0f\x61\x84\xaf\xbe\x3d\xac\x9f\x76\x02\x8d\x1c\xae\xcc\xfb\xf6\x91\x99\xc6\xce\x2b\x4c\x09\x2a\x3f\x4d\x2a\x56\xfe\x5a\x33\xa0\x07\x57\xf4\xd7\xde\xe5\xdf\xb0\x52\x43\x11\xa9\x7a\xe0\x66\x8a\x47\x97\x1b\x95\x76\x6e\x2f\x6d\xd4\x8c\x3f\x57\x84\x1f\x91\xf0\x4a\x00\xad\x5e\xa7\x0f\x2d\x47\x9a\x26\x20\xdc\x5c\xd7\x8e\xaa\xb3\xa3\xb0\x11\x71\x9b\x7e\x78\xd1\x9d\xdf\x70\xd9\x42\x37\x98\xaf\x77\x51\x7e\xbc\x55\x39\x2f\xcd\x01\xfc\x60\x0d\x8d\x46\x6b\x9e\x7a\x7a\x85\xbf\x33\xf9\xcc\x54\x19\xe9\xbd\x87\x4d\xdf\xd6\x09\x81\x15\x0d\xda\xf8\xd7\xfe\xba\xa4\x37\x4f\x08\x72\xa5\x62\x8d\x31\x80\x00\x31\x1e\x2f\x56\x55\x36\x5a\xd4\xd4\x07\xc2\x0e\x5c\x04\xdf\x17\xa2\x22\xe7\xde\xec\x79\xc5\xab\x11\x16\xd8\x57\x2f\x91\xcd\x06\xe1\xcc\xc7\xce\xd5\x37\x36\xfc\x86\x7f\xd4\x9e\xce\xbe\x6b\xf8\x08\x2e\x8a",
+ "\x97\xdc\xa1\x05\x0a\x46\x5b\x60\xe9\x1e\xbe\x26\xe2\x9a\xdb\x5a\x28\x6a\x05\x82\xee\xe2\xe8\x9b\x8b\x90\x19\x54\x29\x3f\x61\x46",
+ 230 },
+ { GCRY_MD_SHA3_256,
+ "\x57\xaf\x97\x1f\xcc\xae\xc9\x74\x35\xdc\x2e\xc9\xef\x04\x29\xbc\xed\xc6\xb6\x47\x72\x9e\xa1\x68\x85\x8a\x6e\x49\xac\x10\x71\xe7\x06\xf4\xa5\xa6\x45\xca\x14\xe8\xc7\x74\x6d\x65\x51\x16\x20\x68\x2c\x90\x6c\x8b\x86\xec\x90\x1f\x3d\xde\xd4\x16\x7b\x3f\x00\xb0\x6c\xbf\xac\x6a\xee\x37\x28\x05\x1b\x3e\x5f\xf1\x0b\x4f\x9e\xd8\xbd\x0b\x8d\xa9\x43\x03\xc8\x33\x75\x5b\x3c\xa3\xae\xdd\xf0\xb5\x4b\xc8\xd6\x63\x21\x38\xb5\xd2\x5b\xab\x03\xd1\x7b\x34\x58\xa9\xd7\x82\x10\x80\x06\xf5\xbb\x7d\xe7\x5b\x5c\x0b\xa8\x54\xb4\x23\xd8\xbb\x80\x1e\x70\x1e\x99\xdc\x4f\xea\xad\x59\xbc\x1c\x71\x12\x45\x3b\x04\xd3\x3e\xa3\x63\x56\x39\xfb\x80\x2c\x73\xc2\xb7\x1d\x58\xa5\x6b\xbd\x67\x1b\x18\xfe\x34\xed\x2e\x3d\xca\x38\x82\x7d\x63\xfd\xb1\xd4\xfb\x32\x85\x40\x50\x04\xb2\xb3\xe2\x60\x81\xa8\xff\x08\xcd\x6d\x2b\x08\xf8\xe7\xb7\xe9\x0a\x2a\xb1\xed\x7a\x41\xb1\xd0\x12\x85\x22\xc2\xf8\xbf\xf5\x6a\x7f\xe6\x79\x69\x42\x2c\xe8\x39\xa9\xd4\x60\x8f\x03",
+ "\x6d\x03\x3d\x85\xda\xed\x33\x66\xd5\xf7\xd5\xe4\xf0\x3b\x3d\x05\xb6\x57\x78\xee\xea\x07\x4b\x0c\x68\x3c\xff\xcd\x6f\x51\xd5\xbd",
+ 231 },
+ { GCRY_MD_SHA3_256,
+ "\x04\xe1\x6d\xed\xc1\x22\x79\x02\xba\xaf\x33\x2d\x3d\x08\x92\x36\x01\xbd\xd6\x4f\x57\x3f\xaa\x1b\xb7\x20\x19\x18\xcf\xe1\x6b\x1e\x10\x15\x1d\xae\x87\x5d\xa0\xc0\xd6\x3c\x59\xc3\xdd\x05\x0c\x4c\x6a\x87\x40\x11\xb0\x18\x42\x1a\xfc\x46\x23\xab\x03\x81\x83\x1b\x2d\xa2\xa8\xba\x42\xc9\x6e\x4f\x70\x86\x4a\xc4\x4e\x10\x6f\x94\x31\x10\x51\xe7\x4c\x77\xc1\x29\x1b\xf5\xdb\x95\x39\xe6\x95\x67\xbf\x6a\x11\xcf\x69\x32\xbb\xba\xd3\x3f\x89\x46\xbf\x58\x14\xc0\x66\xd8\x51\x63\x3d\x1a\x51\x35\x10\x03\x9b\x34\x99\x39\xbf\xd4\x2b\x85\x8c\x21\x82\x7c\x8f\xf0\x5f\x1d\x09\xb1\xb0\x76\x5d\xc7\x8a\x13\x5b\x5c\xa4\xdf\xba\x08\x01\xbc\xad\xdf\xa1\x75\x62\x3c\x8b\x64\x7e\xac\xfb\x44\x44\xb8\x5a\x44\xf7\x38\x90\x60\x7d\x06\xd5\x07\xa4\xf8\x39\x36\x58\x78\x86\x69\xf6\xef\x4d\xeb\x58\xd0\x8c\x50\xca\x07\x56\xd5\xe2\xf4\x9d\x1a\x7a\xd7\x3e\x0f\x0b\x3d\x3b\x5f\x09\x0a\xcf\x62\x2b\x18\x78\xc5\x91\x33\xe4\xa8\x48\xe0\x51\x53\x59\x2e\xa8\x1c\x6f\xbf",
+ "\x01\xeb\xbb\x73\x41\x0e\xeb\xac\x66\x5c\x3b\x40\x06\x3d\x00\x1f\x43\xdb\xe9\xd1\x72\x2e\xb3\x23\xfe\x08\x76\x3d\x7f\xf0\x61\x6c",
+ 232 },
+ { GCRY_MD_SHA3_256,
+ "\x7c\x81\x5c\x38\x4e\xee\x0f\x28\x8e\xce\x27\xcc\xed\x52\xa0\x16\x03\x12\x7b\x07\x9c\x00\x73\x78\xbc\x5d\x1e\x6c\x5e\x9e\x6d\x1c\x73\x57\x23\xac\xbb\xd5\x80\x1a\xc4\x98\x54\xb2\xb5\x69\xd4\x47\x2d\x33\xf4\x0b\xbb\x88\x82\x95\x62\x45\xc3\x66\xdc\x35\x82\xd7\x16\x96\xa9\x7a\x4e\x19\x55\x7e\x41\xe5\x4d\xee\x48\x2a\x14\x22\x90\x05\xf9\x3a\xfd\x2c\x4a\x7d\x86\x14\xd1\x0a\x97\xa9\xdf\xa0\x7f\x7c\xd9\x46\xfa\x45\x26\x30\x63\xdd\xd2\x9d\xb8\xf9\xe3\x4d\xb6\x0d\xaa\x32\x68\x4f\x00\x72\xea\x2a\x94\x26\xec\xeb\xfa\x52\x39\xfb\x67\xf2\x9c\x18\xcb\xaa\x2a\xf6\xed\x4b\xf4\x28\x39\x36\x82\x3a\xc1\x79\x01\x64\xfe\xc5\x45\x7a\x9c\xba\x7c\x76\x7c\xa5\x93\x92\xd9\x4c\xab\x74\x48\xf5\x0e\xb3\x4e\x9a\x93\xa8\x00\x27\x47\x1c\xe5\x97\x36\xf0\x99\xc8\x86\xde\xa1\xab\x4c\xba\x4d\x89\xf5\xfc\x7a\xe2\xf2\x1c\xcd\x27\xf6\x11\xec\xa4\x62\x6b\x2d\x08\xdc\x22\x38\x2e\x92\xc1\xef\xb2\xf6\xaf\xdc\x8f\xdc\x3d\x21\x72\x60\x4f\x50\x35\xc4\x6b\x81\x97\xd3",
+ "\x8d\x3a\x49\xcb\x57\x2a\xb9\x9c\x9b\xf0\x23\x13\x66\xbb\x01\x7c\x9a\xdf\x25\x47\x9d\x35\x44\x3a\x97\x1e\x45\x78\x7e\x73\x8c\xe5",
+ 233 },
+ { GCRY_MD_SHA3_256,
+ "\xe2\x9d\x50\x51\x58\xdb\xdd\x93\x7d\x9e\x3d\x21\x45\x65\x8e\xe6\xf5\x99\x2a\x2f\xc7\x90\xf4\xf6\x08\xd9\xcd\xb4\x4a\x09\x1d\x5b\x94\xb8\x8e\x81\xfa\xc4\xfd\xf5\xc4\x94\x42\xf1\x3b\x91\x1c\x55\x88\x64\x69\x62\x95\x51\x18\x9e\xaf\xf6\x24\x88\xf1\xa4\x79\xb7\xdb\x11\xa1\x56\x0e\x19\x8d\xdc\xcc\xcf\x50\x15\x90\x93\x42\x5f\xf7\xf1\xcb\x8d\x1d\x12\x46\xd0\x97\x87\x64\x08\x7d\x6b\xac\x25\x70\x26\xb0\x90\xef\xae\x8c\xec\x5f\x22\xb6\xf2\x1c\x59\xac\xe1\xac\x73\x86\xf5\xb8\x83\x7c\xa6\xa1\x2b\x6f\xbf\x55\x34\xdd\x05\x60\xef\x05\xca\x78\x10\x4d\x3b\x94\x3d\xdb\x22\x0f\xea\xec\x89\xaa\x5e\x69\x2a\x00\xf8\x22\xa2\xab\x9a\x2f\xe6\x03\x50\xd7\x5e\x7b\xe1\x6f\xf2\x52\x6d\xc6\x43\x87\x25\x02\xd0\x1f\x42\xf1\x88\xab\xed\x0a\x6e\x9a\x6f\x5f\xd0\xd1\xce\x7d\x57\x55\xc9\xff\xa6\x6b\x0a\xf0\xb2\x0b\xd8\x06\xf0\x8e\x06\x15\x66\x90\xd8\x1a\xc8\x11\x77\x8c\xa3\xda\xc2\xc2\x49\xb9\x60\x02\x01\x7f\xce\x93\xe5\x07\xe3\xb9\x53\xac\xf9\x99\x64\xb8\x47",
+ "\xfb\xb5\xa0\xab\x1a\x3b\x4c\x4f\xa5\x6a\xdb\x1c\x95\x31\xeb\x99\x79\xc5\x54\x90\x30\x53\x01\x3c\x20\xfe\xfd\x3f\x57\xb5\xcc\xdb",
+ 234 },
+ { GCRY_MD_SHA3_256,
+ "\xd8\x55\x88\x69\x6f\x57\x6e\x65\xec\xa0\x15\x5f\x39\x5f\x0c\xfa\xcd\x83\xf3\x6a\x99\x11\x1e\xd5\x76\x8d\xf2\xd1\x16\xd2\x12\x1e\x32\x35\x7b\xa4\xf5\x4e\xde\x92\x7f\x18\x9f\x29\x7d\x3a\x97\xfa\xd4\xe9\xa0\xf5\xb4\x1d\x8d\x89\xdd\x7f\xe2\x01\x56\x79\x9c\x2b\x7b\x6b\xf9\xc9\x57\xba\x0d\x67\x63\xf5\xc3\xbc\x51\x29\x74\x7b\xbb\x53\x65\x2b\x49\x29\x0c\xff\x1c\x87\xe2\xcd\xf2\xc4\xb9\x5d\x8a\xae\xe0\x9b\xc8\xfb\xfa\x68\x83\xe6\x2d\x23\x78\x85\x81\x04\x91\xbf\xc1\x01\xf1\xd8\xc6\x36\xe3\xd0\xed\xe8\x38\xad\x05\xc2\x07\xa3\xdf\x4f\xad\x76\x45\x29\x79\xeb\x99\xf2\x9a\xfa\xec\xed\xd1\xc6\x3b\x8d\x36\xcf\x37\x84\x54\xa1\xbb\x67\xa7\x41\xc7\x7a\xc6\xb6\xb3\xf9\x5f\x4f\x02\xb6\x4d\xab\xc1\x54\x38\x61\x3e\xa4\x97\x50\xdf\x42\xee\x90\x10\x1f\x11\x5a\xa9\xab\xb9\xff\x64\x32\x4d\xde\x9d\xab\xbb\x01\x05\x4e\x1b\xd6\xb4\xbc\xdc\x79\x30\xa4\x4c\x23\x00\xd8\x7c\xa7\x8c\x06\x92\x4d\x03\x23\xad\x78\x87\xe4\x6c\x90\xe8\xc4\xd1\x00\xac\xd9\xee\xd2\x1e",
+ "\x6b\x3d\xcc\x7a\xc6\xa5\xcb\x85\xb6\x7f\xc7\x1b\x40\x55\xd3\x79\x81\x34\xde\xef\x26\xfd\x3e\xb0\x3a\x04\x2e\x0d\xaa\x35\xcc\x85",
+ 235 },
+ { GCRY_MD_SHA3_256,
+ "\x3a\x12\xf8\x50\x8b\x40\xc3\x2c\x74\x49\x2b\x66\x32\x33\x75\xdc\xfe\x49\x18\x4c\x78\xf7\x31\x79\xf3\x31\x4b\x79\xe6\x33\x76\xb8\xac\x68\x3f\x5a\x51\xf1\x53\x4b\xd7\x29\xb0\x2b\x04\xd0\x02\xf5\x5c\xbd\x8e\x8f\xc9\xb5\xec\x1e\xa6\xbb\xe6\xa0\xd0\xe7\x43\x15\x18\xe6\xba\x45\xd1\x24\x03\x5f\x9d\x3d\xce\x0a\x8b\xb7\xbf\x14\x30\xa9\xf6\x57\xe0\xb4\xea\x9f\x20\xeb\x20\xc7\x86\xa5\x81\x81\xa1\xe2\x0a\x96\xf1\x62\x8f\x87\x28\xa1\x3b\xdf\x7a\x4b\x4b\x32\xfc\x8a\xa7\x05\x4c\xc4\x88\x1a\xe7\xfa\x19\xaf\xa6\x5c\x6c\x3e\xe1\xb3\xad\xe3\x19\x2a\xf4\x20\x54\xa8\xa9\x11\xb8\xec\x18\x26\x86\x5d\x46\xd9\x3f\x1e\x7c\x5e\x2b\x78\x13\xc9\x2a\x50\x6e\x53\x88\x6f\x3d\x47\x01\xbb\x93\xd2\xa6\x81\xad\x10\x9c\x84\x59\x04\xbb\x86\x1a\xf8\xaf\x06\x46\xb6\xe3\x99\xb3\x8b\x61\x40\x51\xd3\x4f\x68\x42\x56\x3a\x0f\x37\xec\x00\xcb\x3d\x86\x5f\xc5\xd7\x46\xc4\x98\x7d\xe2\xa6\x50\x71\x10\x08\x83\xa2\xa9\xc7\xa2\xbf\xe1\xe2\xdd\x60\x3d\x9e\xa2\x4d\xc7\xc5\xfd\x06\xbe",
+ "\x5d\x1d\xba\x8f\x15\x84\xac\x3f\x36\xb3\xac\x92\x5e\xc1\x3a\xc2\x84\x01\x3b\x96\x64\x96\x5a\xb6\x26\x5b\x94\x24\x66\xb5\xd8\xec",
+ 236 },
+ { GCRY_MD_SHA3_256,
+ "\x18\x61\xed\xce\x46\xfa\x5a\xd1\x7e\x1f\xf1\xde\xae\x08\x4d\xec\x58\x0f\x97\xd0\xa6\x78\x85\xdf\xe8\x34\xb9\xdf\xac\x1a\xe0\x76\x74\x2c\xe9\xe2\x67\x51\x2c\xa5\x1f\x6d\xf5\xa4\x55\xaf\x0c\x5f\xd6\xab\xf9\x4a\xce\xa1\x03\xa3\x37\x0c\x35\x44\x85\xa7\x84\x6f\xb8\x4f\x3a\xc7\xc2\x90\x4b\x5b\x2f\xbf\x22\x70\x02\xce\x51\x21\x33\xbb\x7e\x1c\x4e\x50\x05\x7b\xfd\x1e\x44\xdb\x33\xc7\xcd\xb9\x69\xa9\x9e\x28\x4b\x18\x4f\x50\xa1\x4b\x06\x8a\x1f\xc5\x00\x9d\x9b\x29\x8d\xbe\x92\x23\x95\x72\xa7\x62\x7a\xac\x02\xab\xe8\xf3\xe3\xb4\x73\x41\x7f\x36\xd4\xd2\x50\x5d\x16\xb7\x57\x7f\x45\x26\xc9\xd9\x4a\x27\x0a\x2d\xfe\x45\x0d\x06\xda\x8f\x6f\xa9\x56\x87\x9a\x0a\x55\xcf\xe9\x9e\x74\x2e\xa5\x55\xea\x47\x7b\xa3\xe9\xb4\x4c\xcd\x50\x8c\x37\x54\x23\x61\x1a\xf9\x2e\x55\x34\x5d\xc2\x15\x77\x9b\x2d\x51\x19\xeb\xa4\x9c\x71\xd4\x9b\x9f\xe3\xf1\x56\x9f\xa2\x4e\x5c\xa3\xe3\x32\xd0\x42\x42\x2a\x8b\x81\x58\xd3\xec\x66\xa8\x00\x12\x97\x6f\x31\xff\xdf\x30\x5f\x0c\x9c\x5e",
+ "\x89\xc6\xc8\x6d\xb0\xa8\x89\xaa\x67\xd8\xcb\x08\x5f\x9f\x43\x12\x64\x59\x72\xd9\x77\xc5\xb9\x52\xd9\xf6\x24\x3d\x7d\x3b\xe4\xd5",
+ 237 },
+ { GCRY_MD_SHA3_256,
+ "\x08\xd0\xff\xde\x3a\x6e\x4e\xf6\x56\x08\xea\x67\x2e\x48\x30\xc1\x29\x43\xd7\x18\x7c\xcf\xf0\x8f\x49\x41\xcf\xc1\x3e\x54\x5f\x3b\x9c\x7a\xd5\xee\xbb\xe2\xb0\x16\x42\xb4\x86\xca\xf8\x55\xc2\xc7\x3f\x58\xc1\xe4\xe3\x39\x1d\xa8\xe2\xd6\x3d\x96\xe1\x5f\xd8\x49\x53\xae\x5c\x23\x19\x11\xb0\x0a\xd6\x05\x0c\xd7\xaa\xfd\xaa\xc9\xb0\xf6\x63\xae\x6a\xab\x45\x51\x9d\x0f\x53\x91\xa5\x41\x70\x7d\x47\x90\x34\xe7\x3a\x6a\xd8\x05\xae\x35\x98\x09\x6a\xf0\x78\xf1\x39\x33\x01\x49\x3d\x66\x3d\xd7\x1f\x83\x86\x9c\xa2\x7b\xa5\x08\xb7\xe9\x1e\x81\xe1\x28\xc1\x71\x6d\xc3\xac\xfe\x30\x84\xb2\x20\x1e\x04\xcf\x80\x06\x61\x7e\xec\xf1\xb6\x40\x47\x4a\x5d\x45\xcf\xde\x9f\x4d\x3e\xf9\x2d\x6d\x05\x5b\x90\x98\x92\x19\x4d\x8a\x82\x18\xdb\x6d\x82\x03\xa8\x42\x61\xd2\x00\xd7\x14\x73\xd7\x48\x8f\x34\x27\x41\x6b\x68\x96\xc1\x37\xd4\x55\xf2\x31\x07\x1c\xac\xbc\x86\xe0\x41\x5a\xb8\x8a\xec\x84\x1d\x96\xb7\xb8\xaf\x41\xe0\x5b\xb4\x61\xa4\x06\x45\xbf\x17\x66\x01\xf1\xe7\x60\xde\x5f",
+ "\xac\x02\x43\x2a\x55\x41\xc2\x62\x38\xc6\xf9\x9f\xad\xb2\xb2\x3b\x5f\xfc\xad\x8f\x04\xbd\x4c\x3b\x9a\x66\x20\xca\xb1\x26\x6e\x6b",
+ 238 },
+ { GCRY_MD_SHA3_256,
+ "\xd7\x82\xab\xb7\x2a\x5b\xe3\x39\x27\x57\xbe\x02\xd3\xe4\x5b\xe6\xe2\x09\x9d\x6f\x00\x0d\x04\x2c\x8a\x54\x3f\x50\xed\x6e\xbc\x05\x5a\x7f\x13\x3b\x0d\xd8\xe9\xbc\x34\x85\x36\xed\xca\xae\x2e\x12\xec\x18\xe8\x83\x7d\xf7\xa1\xb3\xc8\x7e\xc4\x6d\x50\xc2\x41\xde\xe8\x20\xfd\x58\x61\x97\x55\x2d\xc2\x0b\xee\xa5\x0f\x44\x5a\x07\xa3\x8f\x17\x68\xa3\x9e\x2b\x2f\xf0\x5d\xdd\xed\xf7\x51\xf1\xde\xf6\x12\xd2\xe4\xd8\x10\xda\xa3\xa0\xcc\x90\x45\x16\xf9\xa4\x3a\xf6\x60\x31\x53\x85\x17\x8a\x52\x9e\x51\xf8\xaa\xe1\x41\x80\x8c\x8b\xc5\xd7\xb6\x0c\xac\x26\xbb\x98\x4a\xc1\x89\x0d\x04\x36\xef\x78\x04\x26\xc5\x47\xe9\x4a\x7b\x08\xf0\x1a\xcb\xfc\x4a\x38\x25\xea\xe0\x4f\x52\x0a\x90\x16\xf2\xfb\x8b\xf5\x16\x5e\xd1\x27\x36\xfc\x71\xe3\x6a\x49\xa7\x36\x14\x73\x9e\xaa\x3e\xc8\x34\x06\x9b\x1b\x40\xf1\x35\x0c\x2b\x3a\xb8\x85\xc0\x2c\x64\x0b\x9f\x76\x86\xed\x5f\x99\x52\x7e\x41\xcf\xcd\x79\x6f\xe4\xc2\x56\xc9\x17\x31\x86\xc2\x26\x16\x9f\xf2\x57\x95\x4e\xbd\xa8\x1c\x0e\x5f\x99",
+ "\xf5\x5a\xa0\x1d\xea\xb1\x21\x48\xe3\x57\x59\xdb\x81\x8f\x10\x59\x35\x11\x65\xe9\xe6\xf9\x3d\x34\x2f\x0a\xbf\xca\x10\x2e\x08\x01",
+ 239 },
+ { GCRY_MD_SHA3_256,
+ "\x5f\xce\x81\x09\xa3\x58\x57\x0e\x40\x98\x3e\x11\x84\xe5\x41\x83\x3b\xb9\x09\x1e\x28\x0f\x25\x8c\xfb\x14\x43\x87\xb0\x5d\x19\x0e\x43\x1c\xb1\x9b\xaa\x67\x27\x3b\xa0\xc5\x8a\xbe\x91\x30\x8e\x18\x44\xdc\xd0\xb3\x67\x8b\xaa\x42\xf3\x35\xf2\xfa\x05\x26\x7a\x02\x40\xb3\xc7\x18\xa5\x94\x2b\x3b\x3e\x3b\xfa\x98\xa5\x5c\x25\xa1\x46\x6e\x8d\x7a\x60\x37\x22\xcb\x2b\xbf\x03\xaf\xa5\x4c\xd7\x69\xa9\x9f\x31\x07\x35\xee\x5a\x05\xda\xe2\xc2\x2d\x39\x7b\xd9\x56\x35\xf5\x8c\x48\xa6\x7f\x90\xe1\xb7\x3a\xaf\xcd\x3f\x82\x11\x7f\x01\x66\x65\x78\x38\x69\x10\x05\xb1\x8d\xa6\xf3\x41\xd6\xe9\x0f\xc1\xcd\xb3\x52\xb3\x0f\xae\x45\xd3\x48\x29\x4e\x50\x1b\x63\x25\x2d\xe1\x47\x40\xf2\xb8\x5a\xe5\x29\x9d\xde\xc3\x17\x2d\xe8\xb6\xd0\xba\x21\x9a\x20\xa2\x3b\xb5\xe1\x0f\xf4\x34\xd3\x9d\xb3\xf5\x83\x30\x5e\x9f\x5c\x03\x9d\x98\x56\x9e\x37\x7b\x75\xa7\x0a\xb8\x37\xd1\xdf\x26\x9b\x8a\x4b\x56\x6f\x40\xbb\x91\xb5\x77\x45\x5f\xd3\xc3\x56\xc9\x14\xfa\x06\xb9\xa7\xce\x24\xc7\x31\x7a\x17\x2d",
+ "\x7c\x0b\xda\x7c\xb4\x2d\xad\xbd\x03\x7f\x50\xa5\xf2\x7e\x3a\xb5\xda\x25\x8d\x46\x70\xf1\xbe\xa9\x01\x54\xc8\x7c\x98\x13\x6b\xa1",
+ 240 },
+ { GCRY_MD_SHA3_256,
+ "\x61\x72\xf1\x97\x1a\x6e\x1e\x4e\x61\x70\xaf\xba\xd9\x5d\x5f\xec\x99\xbf\x69\xb2\x4b\x67\x4b\xc1\x7d\xd7\x80\x11\x61\x5e\x50\x2d\xe6\xf5\x6b\x86\xb1\xa7\x1d\x3f\x43\x48\x08\x72\x18\xac\x7b\x7d\x09\x30\x29\x93\xbe\x27\x2e\x4a\x59\x19\x68\xae\xf1\x8a\x12\x62\xd6\x65\x61\x0d\x10\x70\xee\x91\xcc\x8d\xa3\x6e\x1f\x84\x1a\x69\xa7\xa6\x82\xc5\x80\xe8\x36\x94\x1d\x21\xd9\x09\xa3\xaf\xc1\xf0\xb9\x63\xe1\xca\x5a\xb1\x93\xe1\x24\xa1\xa5\x3d\xf1\xc5\x87\x47\x0e\x58\x81\xfb\x54\xda\xe1\xb0\xd8\x40\xf0\xc8\xf9\xd1\xb0\x4c\x64\x5b\xa1\x04\x1c\x7d\x8d\xbf\x22\x03\x0a\x62\x3a\xa1\x56\x38\xb3\xd9\x9a\x2c\x40\x0f\xf7\x6f\x32\x52\x07\x9a\xf8\x8d\x2b\x37\xf3\x5e\xe6\x6c\x1a\xd7\x80\x1a\x28\xd3\xd3\x88\xac\x45\x0b\x97\xd5\xf0\xf7\x9e\x45\x41\x75\x53\x56\xb3\xb1\xa5\x69\x6b\x02\x3f\x39\xab\x7a\xb5\xf2\x8d\xf4\x20\x29\x36\xbc\x97\x39\x3b\x93\xbc\x91\x5c\xb1\x59\xea\x1b\xd7\xa0\xa4\x14\xcb\x4b\x7a\x1a\xc3\xaf\x68\xf5\x0d\x79\xf0\xc9\xc7\x31\x4e\x75\x0f\x7d\x02\xfa\xa5\x8b\xfa",
+ "\xf6\x0c\x53\xba\x21\x32\x29\x3b\x88\x1f\x05\x13\xe7\xab\x47\xfe\x97\x46\xed\x4a\x6a\xc9\xca\xde\x61\xe6\xd8\x02\xd5\x87\x23\x72",
+ 241 },
+ { GCRY_MD_SHA3_256,
+ "\x56\x68\xec\xd9\x9d\xfb\xe2\x15\xc4\x11\x83\x98\xac\x9c\x9e\xaf\x1a\x14\x33\xfa\xb4\xcc\xdd\x39\x68\x06\x47\x52\xb6\x25\xea\x94\x47\x31\xf7\x5d\x48\xa2\x7d\x04\x7d\x67\x54\x7f\x14\xdd\x0f\xfa\xa5\x5f\xa5\xe2\x9f\x7a\xf0\xd1\x61\xd8\x5e\xaf\xc4\xf2\x02\x9b\x71\x7c\x91\x8e\xab\x9d\x30\x45\x43\x29\x0b\xdb\xa7\x15\x8b\x68\x02\x0c\x0b\xa4\xe0\x79\xbc\x95\xb5\xbc\x0f\xc0\x44\xa9\x92\xb9\x4b\x4c\xcd\x3b\xd6\x6d\x0e\xab\xb5\xdb\xba\xb9\x04\xd6\x2e\x00\x75\x2c\x4e\x3b\x00\x91\xd7\x73\xbc\xf4\xc1\x4b\x43\x77\xda\x3e\xff\xf8\x24\xb1\xcb\x2f\xa0\x1b\x32\xd1\xe4\x6c\x90\x9e\x62\x6e\xd2\xda\xe9\x20\xf4\xc7\xdb\xeb\x63\x5b\xc7\x54\xfa\xcb\xd8\xd4\x9b\xeb\xa3\xf2\x3c\x1c\x41\xcc\xbf\xcd\x0e\xe0\xc1\x14\xe6\x97\x37\xf5\x59\x7c\x0b\xf1\xd8\x59\xf0\xc7\x67\xe1\x80\x02\xae\x8e\x39\xc2\x62\x61\xff\xde\x29\x20\xd3\xd0\xba\xf0\xe9\x06\x13\x86\x96\xcf\xe5\xb7\xe3\x2b\x60\x0f\x45\xdf\x3a\xaa\x39\x93\x2f\x3a\x7d\xf9\x5b\x60\xfa\x87\x12\xa2\x27\x1f\xca\xf3\x91\x1c\xe7\xb5\x11\xb1",
+ "\x1c\x66\xb9\xa7\xc5\x0e\xd7\x7d\x17\x9a\x0c\x43\x7d\x58\x90\xc9\x83\x5a\x13\xf9\x0a\x73\xa0\x13\x32\xab\x07\x31\xa4\x1a\x11\x5e",
+ 242 },
+ { GCRY_MD_SHA3_256,
+ "\x03\xd6\x25\x48\x83\x54\xdf\x30\xe3\xf8\x75\xa6\x8e\xdf\xcf\x34\x0e\x83\x66\xa8\xe1\xab\x67\xf9\xd5\xc5\x48\x6a\x96\x82\x9d\xfa\xc0\x57\x82\x89\x08\x2b\x2a\x62\x11\x7e\x1c\xf4\x18\xb4\x3b\x90\xe0\xad\xc8\x81\xfc\x6a\xe8\x10\x5c\x88\x8e\x9e\xcd\x21\xae\xa1\xc9\xae\x1a\x40\x38\xdf\xd1\x73\x78\xfe\xd7\x1d\x02\xae\x49\x20\x87\xd7\xcd\xcd\x98\xf7\x46\x85\x52\x27\x96\x7c\xb1\xab\x47\x14\x26\x1e\xe3\xbe\xad\x3f\x4d\xb1\x18\x32\x9d\x3e\xbe\xf4\xbc\x48\xa8\x75\xc1\x9b\xa7\x63\x96\x6d\xa0\xeb\xea\x80\x0e\x01\xb2\xf5\x0b\x00\xe9\xdd\x4c\xac\xa6\xdc\xb3\x14\xd0\x01\x84\xef\x71\xea\x23\x91\xd7\x60\xc9\x50\x71\x0d\xb4\xa7\x0f\x92\x12\xff\xc5\x48\x61\xf9\xdc\x75\x2c\xe1\x88\x67\xb8\xad\x0c\x48\xdf\x84\x66\xef\x72\x31\xe7\xac\x56\x7f\x0e\xb5\x50\x99\xe6\x22\xeb\xb8\x6c\xb2\x37\x52\x01\x90\xa6\x1c\x66\xad\x34\xf1\xf4\xe2\x89\xcb\x32\x82\xae\x3e\xaa\xc6\x15\x2e\xd2\x4d\x2c\x92\xba\xe5\xa7\x65\x82\x52\xa5\x3c\x49\xb7\xb0\x2d\xfe\x54\xfd\xb2\xe9\x00\x74\xb6\xcf\x31\x0a\xc6\x61",
+ "\x48\xa0\x0b\xa2\x24\xac\x55\x58\xf4\x1a\x79\xf5\x21\x37\xdb\x91\x82\xa9\x3f\x10\x45\xd4\x37\x89\xe5\x91\x3d\x7b\xe4\x04\x08\xc2",
+ 243 },
+ { GCRY_MD_SHA3_256,
+ "\x2e\xdc\x28\x2f\xfb\x90\xb9\x71\x18\xdd\x03\xaa\xa0\x3b\x14\x5f\x36\x39\x05\xe3\xcb\xd2\xd5\x0e\xcd\x69\x2b\x37\xbf\x00\x01\x85\xc6\x51\xd3\xe9\x72\x6c\x69\x0d\x37\x73\xec\x1e\x48\x51\x0e\x42\xb1\x77\x42\xb0\xb0\x37\x7e\x7d\xe6\xb8\xf5\x5e\x00\xa8\xa4\xdb\x47\x40\xce\xe6\xdb\x08\x30\x52\x9d\xd1\x96\x17\x50\x1d\xc1\xe9\x35\x9a\xa3\xbc\xf1\x47\xe0\xa7\x6b\x3a\xb7\x0c\x49\x84\xc1\x3e\x33\x9e\x68\x06\xbb\x35\xe6\x83\xaf\x85\x27\x09\x36\x70\x85\x9f\x3d\x8a\x0f\xc7\xd4\x93\xbc\xba\x6b\xb1\x2b\x5f\x65\xe7\x1e\x70\x5c\xa5\xd6\xc9\x48\xd6\x6e\xd3\xd7\x30\xb2\x6d\xb3\x95\xb3\x44\x77\x37\xc2\x6f\xad\x08\x9a\xa0\xad\x0e\x30\x6c\xb2\x8b\xf0\xac\xf1\x06\xf8\x9a\xf3\x74\x5f\x0e\xc7\x2d\x53\x49\x68\xcc\xa5\x43\xcd\x2c\xa5\x0c\x94\xb1\x45\x67\x43\x25\x4e\x35\x8c\x13\x17\xc0\x7a\x07\xbf\x2b\x0e\xca\x43\x8a\x70\x93\x67\xfa\xfc\x89\xa5\x72\x39\x02\x8f\xc5\xfe\xcf\xd5\x3b\x8e\xf9\x58\xef\x10\xee\x06\x08\xb7\xf5\xcb\x99\x23\xad\x97\x05\x8e\xc0\x67\x70\x0c\xc7\x46\xc1\x27\xa6\x1e\xe3",
+ "\x24\x0a\x85\xea\xf7\xf3\x01\x6c\x19\x2a\xd5\xe1\x7e\x5f\x93\xb6\x43\xfe\x3e\xdb\xa7\x19\xf4\x23\x69\x3a\x34\xda\x37\x84\x82\x7a",
+ 244 },
+ { GCRY_MD_SHA3_256,
+ "\x90\xb2\x8a\x6a\xa1\xfe\x53\x39\x15\xbc\xb8\xe8\x1e\xd6\xca\xcd\xc1\x09\x62\xb7\xff\x82\x47\x4f\x84\x5e\xeb\x86\x97\x76\x00\xcf\x70\xb0\x7b\xa8\xe3\x79\x61\x41\xee\x34\x0e\x3f\xce\x84\x2a\x38\xa5\x0a\xfb\xe9\x03\x01\xa3\xbd\xcc\x59\x1f\x2e\x7d\x9d\xe5\x3e\x49\x55\x25\x56\x0b\x90\x8c\x89\x24\x39\x99\x0a\x2c\xa2\x67\x9c\x55\x39\xff\xdf\x63\x67\x77\xad\x9c\x1c\xde\xf8\x09\xcd\xa9\xe8\xdc\xdb\x45\x1a\xbb\x9e\x9c\x17\xef\xa4\x37\x9a\xbd\x24\xb1\x82\xbd\x98\x1c\xaf\xc7\x92\x64\x0a\x18\x3b\x61\x69\x43\x01\xd0\x4c\x5b\x3e\xaa\xd6\x94\xa6\xbd\x4c\xc0\x6e\xf5\xda\x8f\xa2\x3b\x4f\xa2\xa6\x45\x59\xc5\xa6\x83\x97\x93\x00\x79\xd2\x50\xc5\x1b\xcf\x00\xe2\xb1\x6a\x6c\x49\x17\x14\x33\xb0\xaa\xdf\xd8\x02\x31\x27\x65\x60\xb8\x04\x58\xdd\x77\x08\x9b\x7a\x1b\xbc\xc9\xe7\xe4\xb9\xf8\x81\xea\xcd\x6c\x92\xc4\x31\x83\x48\xa1\x3f\x49\x14\xeb\x27\x11\x5a\x1c\xfc\x5d\x16\xd7\xfd\x94\x95\x4c\x35\x32\xef\xac\xa2\xca\xb0\x25\x10\x3b\x2d\x02\xc6\xfd\x71\xda\x3a\x77\xf4\x17\xd7\x93\x26\x85\x88\x8a",
+ "\x2a\xa9\xd0\xa1\xd9\xb9\xb6\x91\xb4\xb8\x64\x1e\x68\xd4\x54\xd2\xd9\xc3\x4c\xe4\x3a\x5b\x55\xdd\x57\x59\x07\x16\xb8\xa4\x6c\xf7",
+ 245 },
+ { GCRY_MD_SHA3_256,
+ "\x29\x69\x44\x7d\x17\x54\x90\xf2\xaa\x9b\xb0\x55\x01\x4d\xbe\xf2\xe6\x85\x4c\x95\xf8\xd6\x09\x50\xbf\xe8\xc0\xbe\x8d\xe2\x54\xc2\x6b\x2d\x31\xb9\xe4\xde\x9c\x68\xc9\xad\xf4\x9e\x4e\xe9\xb1\xc2\x85\x09\x67\xf2\x9f\x5d\x08\x73\x84\x83\xb4\x17\xbb\x96\xb2\xa5\x6f\x0c\x8a\xca\x63\x2b\x55\x20\x59\xc5\x9a\xac\x3f\x61\xf7\xb4\x5c\x96\x6b\x75\xf1\xd9\x93\x1f\xf4\xe5\x96\x40\x63\x78\xce\xe9\x1a\xaa\x72\x6a\x3a\x84\xc3\x3f\x37\xe9\xcd\xbe\x62\x6b\x57\x45\xa0\xb0\x60\x64\xa8\xa8\xd5\x6e\x53\xaa\xf1\x02\xd2\x3d\xd9\xdf\x0a\x3f\xdf\x7a\x63\x85\x09\xa6\x76\x1a\x33\xfa\x42\xfa\x8d\xdb\xd8\xe1\x61\x59\xc9\x30\x08\xb5\x37\x65\x01\x9c\x3f\x0e\x9f\x10\xb1\x44\xce\x2a\xc5\x7f\x5d\x72\x97\xf9\xc9\x94\x9e\x4f\xf6\x8b\x70\xd3\x39\xf8\x75\x01\xce\x85\x50\xb7\x72\xf3\x2c\x6d\xa8\xad\x2c\xe2\x10\x0a\x89\x5d\x8b\x08\xfa\x1e\xea\xd7\xc3\x76\xb4\x07\x70\x97\x03\xc5\x10\xb5\x0f\x87\xe7\x3e\x43\xf8\xe7\x34\x8f\x87\xc3\x83\x2a\x54\x7e\xf2\xbb\xe5\x79\x9a\xbe\xdc\xf5\xe1\xf3\x72\xea\x80\x92\x33\xf0\x06",
+ "\x58\xc4\x69\xe1\xa7\x68\x35\xcc\x1a\x89\x7b\x88\x5b\x1b\x2a\x33\xb0\xaa\xbc\xe4\xcf\xbb\x65\x52\x3d\x2e\x0d\x08\xd6\xd1\xa4\x13",
+ 246 },
+ { GCRY_MD_SHA3_256,
+ "\x72\x16\x45\x63\x3a\x44\xa2\xc7\x8b\x19\x02\x4e\xae\xcf\x58\x57\x5a\xb2\x3c\x27\x19\x08\x33\xc2\x68\x75\xdc\x0f\x0d\x50\xb4\x6a\xea\x9c\x34\x3d\x82\xea\x7d\x5b\x3e\x50\xec\x70\x05\x45\xc6\x15\xda\xea\xea\x64\x72\x6a\x0f\x05\x60\x75\x76\xdc\xd3\x96\xd8\x12\xb0\x3f\xb6\x55\x1c\x64\x10\x87\x85\x6d\x05\x0b\x10\xe6\xa4\xd5\x57\x7b\x82\xa9\x8a\xfb\x89\xce\xe8\x59\x4c\x9d\xc1\x9e\x79\xfe\xff\x03\x82\xfc\xfd\x12\x7f\x1b\x80\x3a\x4b\x99\x46\xf4\xac\x9a\x43\x78\xe1\xe6\xe0\x41\xb1\x38\x9a\x53\xe3\x45\x0c\xd3\x2d\x9d\x29\x41\xb0\xcb\xab\xdb\x50\xda\x8e\xa2\x51\x31\x45\x16\x4c\x3a\xb6\xbc\xbd\x25\x1c\x44\x8d\x2d\x4b\x08\x7a\xc5\x7a\x59\xc2\x28\x5d\x56\x4f\x16\xda\x4e\xd5\xe6\x07\xed\x97\x95\x92\x14\x6f\xfb\x0e\xf3\xf3\xdb\x30\x8f\xb3\x42\xdf\x5e\xb5\x92\x4a\x48\x25\x6f\xc7\x63\x14\x1a\x27\x88\x14\xc8\x2d\x6d\x63\x48\x57\x75\x45\x87\x0a\xe3\xa8\x3c\x72\x30\xac\x02\xa1\x54\x0f\xe1\x79\x8f\x7e\xf0\x9e\x33\x5a\x86\x5a\x2a\xe0\x94\x9b\x21\xe4\xf7\x48\xfb\x8a\x51\xf4\x47\x50\xe2\x13\xa8\xfb",
+ "\x6c\x8d\xf8\x1b\x1e\x1e\xd7\x0a\x54\x13\x36\x80\x18\xdb\x96\x28\xb0\xe0\xb4\x56\x34\x23\xc0\x51\xa5\x4d\x00\x0a\xad\xde\x0c\x06",
+ 247 },
+ { GCRY_MD_SHA3_256,
+ "\x6b\x86\x0d\x39\x72\x5a\x14\xb4\x98\xbb\x71\x45\x74\xb4\xd3\x7c\xa7\x87\x40\x47\x68\xf6\x4c\x64\x8b\x17\x51\xb3\x53\xac\x92\xba\xc2\xc3\xa2\x8e\xa9\x09\xfd\xf0\x42\x33\x36\x40\x1a\x02\xe6\x3e\xc2\x43\x25\x30\x0d\x82\x3b\x68\x64\xbb\x70\x1f\x9d\x7c\x7a\x1f\x8e\xc9\xd0\xae\x35\x84\xaa\x6d\xd6\x2e\xa1\x99\x7c\xd8\x31\xb4\xba\xbd\x9a\x4d\xa5\x09\x32\xd4\xef\xda\x74\x5c\x61\xe4\x13\x08\x90\xe1\x56\xae\xe6\x11\x37\x16\xda\xf9\x57\x64\x22\x2a\x91\x18\x7d\xb2\xef\xfe\xa4\x9d\x5d\x05\x96\x10\x2d\x61\x9b\xd2\x6a\x61\x6b\xbf\xda\x83\x35\x50\x5f\xbb\x0d\x90\xb4\xc1\x80\xd1\xa2\x33\x5b\x91\x53\x8e\x16\x68\xf9\xf9\x64\x27\x90\xb4\xe5\x5f\x9c\xab\x0f\xe2\xbd\xd2\x93\x5d\x00\x1e\xe6\x41\x9a\xba\xb5\x45\x78\x80\xd0\xdb\xff\x20\xed\x87\x58\xf4\xc2\x0f\xe7\x59\xef\xb3\x31\x41\xcf\x0e\x89\x25\x87\xfe\x81\x87\xe5\xfb\xc5\x77\x86\xb7\xe8\xb0\x89\x61\x2c\x93\x6d\xfc\x03\xd2\x7e\xfb\xbe\x7c\x86\x73\xf1\x60\x6b\xd5\x1d\x5f\xf3\x86\xf4\xa7\xab\x68\xed\xf5\x9f\x38\x5e\xb1\x29\x1f\x11\x7b\xfe\x71\x73\x99",
+ "\x10\x8f\xff\x41\xd5\xbc\xf6\x54\x07\x1b\x44\x14\xe6\x66\xfd\xeb\xbe\x87\x8c\x30\x9d\x6d\xdc\x90\xaf\xaf\x5c\x61\xdf\x85\x59\xf0",
+ 248 },
+ { GCRY_MD_SHA3_256,
+ "\x6a\x01\x83\x0a\xf3\x88\x9a\x25\x18\x32\x44\xde\xcb\x50\x8b\xd0\x12\x53\xd5\xb5\x08\xab\x49\x0d\x31\x24\xaf\xbf\x42\x62\x6b\x2e\x70\x89\x4e\x9b\x56\x2b\x28\x8d\x0a\x24\x50\xcf\xac\xf1\x4a\x0d\xda\xe5\xc0\x47\x16\xe5\xa0\x08\x2c\x33\x98\x1f\x60\x37\xd2\x3d\x5e\x04\x5e\xe1\xef\x22\x83\xfb\x8b\x63\x78\xa9\x14\xc5\xd9\x44\x16\x27\xa7\x22\xc2\x82\xff\x45\x2e\x25\xa7\xea\x60\x8d\x69\xce\xe4\x39\x3a\x07\x25\xd1\x79\x63\xd0\x34\x26\x84\xf2\x55\x49\x6d\x8a\x18\xc2\x96\x11\x45\x31\x51\x30\x54\x93\x11\xfc\x07\xf0\x31\x2f\xb7\x8e\x60\x77\x33\x4f\x87\xea\xa8\x73\xbe\xe8\xaa\x95\x69\x89\x96\xeb\x21\x37\x5e\xb2\xb4\xef\x53\xc1\x44\x01\x20\x7d\xeb\x45\x68\x39\x8e\x5d\xd9\xa7\xcf\x97\xe8\xc9\x66\x3e\x23\x33\x4b\x46\x91\x2f\x83\x44\xc1\x9e\xfc\xf8\xc2\xba\x6f\x04\x32\x5f\x1a\x27\xe0\x62\xb6\x2a\x58\xd0\x76\x6f\xc6\xdb\x4d\x2c\x6a\x19\x28\x60\x4b\x01\x75\xd8\x72\xd1\x6b\x79\x08\xeb\xc0\x41\x76\x11\x87\xcc\x78\x55\x26\xc2\xa3\x87\x3f\xea\xc3\xa6\x42\xbb\x39\xf5\x35\x15\x50\xaf\x97\x70\xc3\x28\xaf\x7b",
+ "\x75\x1e\xaa\xaf\xa4\xae\xc8\xac\xd2\x66\x06\xd6\x43\x9c\x55\xb5\xc6\x6e\xc7\xdb\x80\x75\x79\xed\xc6\x89\x94\xb3\x00\xf7\xa0\x77",
+ 249 },
+ { GCRY_MD_SHA3_256,
+ "\xb3\xc5\xe7\x4b\x69\x93\x3c\x25\x33\x10\x6c\x56\x3b\x4c\xa2\x02\x38\xf2\xb6\xe6\x75\xe8\x68\x1e\x34\xa3\x89\x89\x47\x85\xbd\xad\xe5\x96\x52\xd4\xa7\x3d\x80\xa5\xc8\x5b\xd4\x54\xfd\x1e\x9f\xfd\xad\x1c\x38\x15\xf5\x03\x8e\x9e\xf4\x32\xaa\xc5\xc3\xc4\xfe\x84\x0c\xc3\x70\xcf\x86\x58\x0a\x60\x11\x77\x8b\xbe\xda\xf5\x11\xa5\x1b\x56\xd1\xa2\xeb\x68\x39\x4a\xa2\x99\xe2\x6d\xa9\xad\xa6\xa2\xf3\x9b\x9f\xaf\xf7\xfb\xa4\x57\x68\x9b\x9c\x1a\x57\x7b\x2a\x1e\x50\x5f\xdf\x75\xc7\xa0\xa6\x4b\x1d\xf8\x1b\x3a\x35\x60\x01\xbf\x0d\xf4\xe0\x2a\x1f\xc5\x9f\x65\x1c\x9d\x58\x5e\xc6\x22\x4b\xb2\x79\xc6\xbe\xba\x29\x66\xe8\x88\x2d\x68\x37\x60\x81\xb9\x87\x46\x8e\x7a\xed\x1e\xf9\x0e\xbd\x09\x0a\xe8\x25\x79\x5c\xdc\xa1\xb4\xf0\x9a\x97\x9c\x8d\xfc\x21\xa4\x8d\x8a\x53\xcd\xbb\x26\xc4\xdb\x54\x7f\xc0\x6e\xfe\x2f\x98\x50\xed\xd2\x68\x5a\x46\x61\xcb\x49\x11\xf1\x65\xd4\xb6\x3e\xf2\x5b\x87\xd0\xa9\x6d\x3d\xff\x6a\xb0\x75\x89\x99\xaa\xd2\x14\xd0\x7b\xd4\xf1\x33\xa6\x73\x4f\xde\x44\x5f\xe4\x74\x71\x1b\x69\xa9\x8f\x7e\x2b",
+ "\x90\xc2\xd5\xf8\xe2\x6b\x0b\xdd\xea\x71\x90\x64\xbb\x02\xa6\x24\x2f\x2c\xc5\xa4\x29\x36\xb1\x4f\xe1\x7f\x86\x1b\x47\xb7\xe1\x86",
+ 250 },
+ { GCRY_MD_SHA3_256,
+ "\x83\xaf\x34\x27\x9c\xcb\x54\x30\xfe\xbe\xc0\x7a\x81\x95\x0d\x30\xf4\xb6\x6f\x48\x48\x26\xaf\xee\x74\x56\xf0\x07\x1a\x51\xe1\xbb\xc5\x55\x70\xb5\xcc\x7e\xc6\xf9\x30\x9c\x17\xbf\x5b\xef\xdd\x7c\x6b\xa6\xe9\x68\xcf\x21\x8a\x2b\x34\xbd\x5c\xf9\x27\xab\x84\x6e\x38\xa4\x0b\xbd\x81\x75\x9e\x9e\x33\x38\x10\x16\xa7\x55\xf6\x99\xdf\x35\xd6\x60\x00\x7b\x5e\xad\xf2\x92\xfe\xef\xb7\x35\x20\x7e\xbf\x70\xb5\xbd\x17\x83\x4f\x7b\xfa\x0e\x16\xcb\x21\x9a\xd4\xaf\x52\x4a\xb1\xea\x37\x33\x4a\xa6\x64\x35\xe5\xd3\x97\xfc\x0a\x06\x5c\x41\x1e\xbb\xce\x32\xc2\x40\xb9\x04\x76\xd3\x07\xce\x80\x2e\xc8\x2c\x1c\x49\xbc\x1b\xec\x48\xc0\x67\x5e\xc2\xa6\xc6\xf3\xed\x3e\x5b\x74\x1d\x13\x43\x70\x95\x70\x7c\x56\x5e\x10\xd8\xa2\x0b\x8c\x20\x46\x8f\xf9\x51\x4f\xcf\x31\xb4\x24\x9c\xd8\x2d\xce\xe5\x8c\x0a\x2a\xf5\x38\xb2\x91\xa8\x7e\x33\x90\xd7\x37\x19\x1a\x07\x48\x4a\x5d\x3f\x3f\xb8\xc8\xf1\x5c\xe0\x56\xe5\xe5\xf8\xfe\xbe\x5e\x1f\xb5\x9d\x67\x40\x98\x0a\xa0\x6c\xa8\xa0\xc2\x0f\x57\x12\xb4\xcd\xe5\xd0\x32\xe9\x2a\xb8\x9f\x0a\xe1",
+ "\x32\x98\xa9\x5c\xfe\x59\xb9\xd6\xca\xb9\x9c\x36\xdc\x13\x24\x19\x4c\x09\xf9\x7f\x08\x94\x4a\x02\xd9\x57\x4b\xbc\xa3\x18\x6b\x41",
+ 251 },
+ { GCRY_MD_SHA3_256,
+ "\xa7\xed\x84\x74\x9c\xcc\x56\xbb\x1d\xfb\xa5\x71\x19\xd2\x79\xd4\x12\xb8\xa9\x86\x88\x6d\x81\x0f\x06\x7a\xf3\x49\xe8\x74\x9e\x9e\xa7\x46\xa6\x0b\x03\x74\x26\x36\xc4\x64\xfc\x1e\xe2\x33\xac\xc5\x2c\x19\x83\x91\x46\x92\xb6\x43\x09\xed\xfd\xf2\x9f\x1a\xb9\x12\xec\x3e\x8d\xa0\x74\xd3\xf1\xd2\x31\x51\x1f\x57\x56\xf0\xb6\xee\xad\x3e\x89\xa6\xa8\x8f\xe3\x30\xa1\x0f\xac\xe2\x67\xbf\xfb\xfc\x3e\x30\x90\xc7\xfd\x9a\x85\x05\x61\xf3\x63\xad\x75\xea\x88\x1e\x72\x44\xf8\x0f\xf5\x58\x02\xd5\xef\x7a\x1a\x4e\x7b\x89\xfc\xfa\x80\xf1\x6d\xf5\x4d\x1b\x05\x6e\xe6\x37\xe6\x96\x4b\x9e\x0f\xfd\x15\xb6\x19\x6b\xdd\x7d\xb2\x70\xc5\x6b\x47\x25\x14\x85\x34\x8e\x49\x81\x3b\x4e\xb9\xed\x12\x2a\x01\xb3\xea\x45\xad\x5e\x1a\x92\x9d\xf6\x1d\x5c\x0f\x3e\x77\xe1\xfd\xc3\x56\xb6\x38\x83\xa6\x0e\x9c\xbb\x9f\xc3\xe0\x0c\x2f\x32\xdb\xd4\x69\x65\x98\x83\xf6\x90\xc6\x77\x2e\x33\x5f\x61\x7b\xc3\x3f\x16\x1d\x6f\x69\x84\x25\x2e\xe1\x2e\x62\xb6\x00\x0a\xc5\x23\x1e\x0c\x9b\xc6\x5b\xe2\x23\xd8\xdf\xd9\x4c\x50\x04\xa1\x01\xaf\x9f\xd6\xc0\xfb",
+ "\x1c\x41\x72\x92\x8c\xb1\x0e\x16\xab\x3c\xdb\x33\xf8\x15\x10\x3b\x00\x0a\x6c\x7d\x62\x37\x6c\xad\x29\xaf\x03\xf4\xb2\xb0\xe1\x03",
+ 252 },
+ { GCRY_MD_SHA3_256,
+ "\xa6\xfe\x30\xdc\xfc\xda\x1a\x32\x9e\x82\xab\x50\xe3\x2b\x5f\x50\xeb\x25\xc8\x73\xc5\xd2\x30\x58\x60\xa8\x35\xae\xce\xe6\x26\x4a\xa3\x6a\x47\x42\x99\x22\xc4\xb8\xb3\xaf\xd0\x0d\xa1\x60\x35\x83\x0e\xdb\x89\x78\x31\xc4\xe7\xb0\x0f\x2c\x23\xfc\x0b\x15\xfd\xc3\x0d\x85\xfb\x70\xc3\x0c\x43\x1c\x63\x8e\x1a\x25\xb5\x1c\xaf\x1d\x7e\x8b\x05\x0b\x7f\x89\xbf\xb3\x0f\x59\xf0\xf2\x0f\xec\xff\x3d\x63\x9a\xbc\x42\x55\xb3\x86\x8f\xc4\x5d\xd8\x1e\x47\xeb\x12\xab\x40\xf2\xaa\xc7\x35\xdf\x5d\x1d\xc1\xad\x99\x7c\xef\xc4\xd8\x36\xb8\x54\xce\xe9\xac\x02\x90\x00\x36\xf3\x86\x7f\xe0\xd8\x4a\xff\xf3\x7b\xde\x33\x08\xc2\x20\x6c\x62\xc4\x74\x33\x75\x09\x41\x08\x87\x7c\x73\xb8\x7b\x25\x46\xfe\x05\xea\x13\x7b\xed\xfc\x06\xa2\x79\x62\x74\x09\x9a\x0d\x55\x4d\xa8\xf7\xd7\x22\x3a\x48\xcb\xf3\x1b\x7d\xec\xaa\x1e\xbc\x8b\x14\x57\x63\xe3\x67\x31\x68\xc1\xb1\xb7\x15\xc1\xcd\x99\xec\xd3\xdd\xb2\x38\xb0\x60\x49\x88\x5e\xca\xd9\x34\x7c\x24\x36\xdf\xf3\x2c\x77\x1f\x34\xa3\x85\x87\xa4\x4a\x82\xc5\xd3\xd1\x37\xa0\x3c\xaa\x27\xe6\x6c\x8f\xf6",
+ "\xf5\xcf\xb4\xdf\x3f\x7c\x5a\x77\x8f\x38\xa3\xb4\x3b\x26\x47\x9a\x0e\x8a\x49\x03\x0c\x59\xac\x19\xfb\x0c\xfa\x80\x60\x81\xca\x4a",
+ 253 },
+ { GCRY_MD_SHA3_256,
+ "\x83\x16\x7f\xf5\x37\x04\xc3\xaa\x19\xe9\xfb\x33\x03\x53\x97\x59\xc4\x6d\xd4\x09\x1a\x52\xdd\xae\x9a\xd8\x64\x08\xb6\x93\x35\x98\x9e\x61\x41\x4b\xc2\x0a\xb4\xd0\x12\x20\xe3\x52\x41\xef\xf5\xc9\x52\x2b\x07\x9f\xba\x59\x76\x74\xc8\xd7\x16\xfe\x44\x1e\x56\x61\x10\xb6\x21\x15\x31\xce\xcc\xf8\xfd\x06\xbc\x8e\x51\x1d\x00\x78\x5e\x57\x78\x8e\xd9\xa1\xc5\xc7\x35\x24\xf0\x18\x30\xd2\xe1\x14\x8c\x92\xd0\xed\xc9\x71\x13\xe3\xb7\xb5\xcd\x30\x49\x62\x7a\xbd\xb8\xb3\x9d\xd4\xd6\x89\x0e\x0e\xe9\x19\x93\xf9\x2b\x03\x35\x4a\x88\xf5\x22\x51\xc5\x46\xe6\x44\x34\xd9\xc3\xd7\x45\x44\xf2\x3f\xb9\x3e\x5a\x2d\x2f\x1f\xb1\x55\x45\xb4\xe1\x36\x7c\x97\x33\x5b\x02\x91\x94\x4c\x8b\x73\x0a\xd3\xd4\x78\x92\x73\xfa\x44\xfb\x98\xd7\x8a\x36\xc3\xc3\x76\x4a\xbe\xea\xc7\xc5\x69\xc1\xe4\x3a\x35\x2e\x5b\x77\x0c\x35\x04\xf8\x70\x90\xde\xe0\x75\xa1\xc4\xc8\x5c\x0c\x39\xcf\x42\x1b\xdc\xc6\x15\xf9\xef\xf6\xcb\x4f\xe6\x46\x80\x04\xae\xce\x5f\x30\xe1\xec\xc6\xdb\x22\xad\x99\x39\xbb\x2b\x0c\xcc\x96\x52\x1d\xfb\xf4\xae\x00\x8b\x5b\x46\xbc\x00\x6e",
+ "\x06\xab\x8f\xdb\xe4\xdc\xe9\x35\xe4\x20\x03\xc1\x7f\xf6\x0b\xa2\x36\xf4\x3a\x84\x39\x95\xb7\xfe\xf3\xa2\x9d\xfe\x0c\x82\xf1\xd4",
+ 254 },
+ { GCRY_MD_SHA3_256,
+ "\x3a\x3a\x81\x9c\x48\xef\xde\x2a\xd9\x14\xfb\xf0\x0e\x18\xab\x6b\xc4\xf1\x45\x13\xab\x27\xd0\xc1\x78\xa1\x88\xb6\x14\x31\xe7\xf5\x62\x3c\xb6\x6b\x23\x34\x67\x75\xd3\x86\xb5\x0e\x98\x2c\x49\x3a\xdb\xbf\xc5\x4b\x9a\x3c\xd3\x83\x38\x23\x36\xa1\xa0\xb2\x15\x0a\x15\x35\x8f\x33\x6d\x03\xae\x18\xf6\x66\xc7\x57\x3d\x55\xc4\xfd\x18\x1c\x29\xe6\xcc\xfd\xe6\x3e\xa3\x5f\x0a\xdf\x58\x85\xcf\xc0\xa3\xd8\x4a\x2b\x2e\x4d\xd2\x44\x96\xdb\x78\x9e\x66\x31\x70\xce\xf7\x47\x98\xaa\x1b\xbc\xd4\x57\x4e\xa0\xbb\xa4\x04\x89\xd7\x64\xb2\xf8\x3a\xad\xc6\x6b\x14\x8b\x4a\x0c\xd9\x52\x46\xc1\x27\xd5\x87\x1c\x4f\x11\x41\x86\x90\xa5\xdd\xf0\x12\x46\xa0\xc8\x0a\x43\xc7\x00\x88\xb6\x18\x36\x39\xdc\xfd\xa4\x12\x5b\xd1\x13\xa8\xf4\x9e\xe2\x3e\xd3\x06\xfa\xac\x57\x6c\x3f\xb0\xc1\xe2\x56\x67\x1d\x81\x7f\xc2\x53\x4a\x52\xf5\xb4\x39\xf7\x2e\x42\x4d\xe3\x76\xf4\xc5\x65\xcc\xa8\x23\x07\xdd\x9e\xf7\x6d\xa5\xb7\xc4\xeb\x7e\x08\x51\x72\xe3\x28\x80\x7c\x02\xd0\x11\xff\xbf\x33\x78\x53\x78\xd7\x9d\xc2\x66\xf6\xa5\xbe\x6b\xb0\xe4\xa9\x2e\xce\xeb\xae\xb1",
+ "\xc1\x1f\x35\x22\xa8\xfb\x7b\x35\x32\xd8\x0b\x6d\x40\x02\x3a\x92\xb4\x89\xad\xda\xd9\x3b\xf5\xd6\x4b\x23\xf3\x5e\x96\x63\x52\x1c",
+ 255 },
diff --git a/comm/third_party/libgcrypt/tests/sha3-384.h b/comm/third_party/libgcrypt/tests/sha3-384.h
new file mode 100644
index 0000000000..6733ca37d8
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/sha3-384.h
@@ -0,0 +1,1025 @@
+/* Generated from https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHA3-384.txt */
+ { 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",
+ 0 },
+ { GCRY_MD_SHA3_384,
+ "\xcc",
+ "\x5e\xe7\xf3\x74\x97\x3c\xd4\xbb\x3d\xc4\x1e\x30\x81\x34\x67\x98\x49\x7f\xf6\xe3\x6c\xb9\x35\x22\x81\xdf\xe0\x7d\x07\xfc\x53\x0c\xa9\xad\x8e\xf7\xaa\xd5\x6e\xf5\xd4\x1b\xe8\x3d\x5e\x54\x38\x07",
+ 1 },
+ { GCRY_MD_SHA3_384,
+ "\x41\xfb",
+ "\x1d\xd8\x16\x09\xdc\xc2\x90\xef\xfd\x7a\xc0\xa9\x5d\x4a\x20\x82\x15\x80\xe5\x6b\xd5\x0d\xbd\x84\x39\x20\x65\x0b\xe7\xa8\x0a\x17\x19\x57\x7d\xa3\x37\xcf\xdf\x86\xe5\x1c\x76\x4c\xaa\x2e\x10\xbd",
+ 2 },
+ { GCRY_MD_SHA3_384,
+ "\x1f\x87\x7c",
+ "\x14\xf6\xf4\x86\xfb\x98\xed\x46\xa4\xa1\x98\x04\x0d\xa8\x07\x9e\x79\xe4\x48\xda\xac\xeb\xe9\x05\xfb\x4c\xf0\xdf\x86\xef\x2a\x71\x51\xf6\x2f\xe0\x95\xbf\x85\x16\xeb\x06\x77\xfe\x60\x77\x34\xe2",
+ 3 },
+ { GCRY_MD_SHA3_384,
+ "\xc1\xec\xfd\xfc",
+ "\xd9\x2b\xbd\x60\x4b\xdd\x24\xb9\x88\x95\x08\xf8\x55\x8b\x13\xe9\x65\x95\xac\x90\xbc\x8a\x44\x1d\xaf\x9b\x51\xd6\xab\xc1\x4f\xfd\x08\x35\xfb\x93\x66\xe3\x91\x25\x04\x26\x4c\xe8\x7e\x42\x1c\xb8",
+ 4 },
+ { GCRY_MD_SHA3_384,
+ "\x21\xf1\x34\xac\x57",
+ "\xe2\x48\xd6\xff\x34\x2d\x35\xa3\x0e\xc2\x30\xba\x51\xcd\xb1\x61\x02\x5d\x6f\x1c\x25\x1a\xca\x6a\xe3\x53\x1f\x06\x82\xc1\x64\xa1\xfc\x07\x25\xb1\xbe\xff\x80\x8a\x20\x0c\x13\x15\x57\xa2\x28\x09",
+ 5 },
+ { GCRY_MD_SHA3_384,
+ "\xc6\xf5\x0b\xb7\x4e\x29",
+ "\xd6\xdd\x2e\xd0\x8c\x1f\x64\x48\x57\xa1\x5d\xaf\xaf\x80\x53\x8b\xee\x59\x72\x78\xc9\xab\xe0\x47\xbf\xba\xbf\xb8\xb1\xfc\xb7\x54\x3e\x80\xae\x9f\x71\x43\xd0\x0f\x4d\xaa\xf3\x9b\x13\x8a\xb3\xff",
+ 6 },
+ { GCRY_MD_SHA3_384,
+ "\x11\x97\x13\xcc\x83\xee\xef",
+ "\x49\xca\x1e\xb8\xd7\x1d\x1f\xdc\x7a\x72\xda\xa3\x20\xc8\xf9\xca\x54\x36\x71\xc2\xcb\x8f\xe9\xb2\x63\x8a\x84\x16\xdf\x50\xa7\x90\xa5\x0d\x0b\xb6\xb8\x87\x41\xd7\x81\x6d\x60\x61\xf4\x6a\xea\x89",
+ 7 },
+ { GCRY_MD_SHA3_384,
+ "\x4a\x4f\x20\x24\x84\x51\x25\x26",
+ "\x89\xdb\xf4\xc3\x9b\x8f\xb4\x6f\xdf\x0a\x69\x26\xce\xc0\x35\x5a\x4b\xdb\xf9\xc6\xa4\x46\xe1\x40\xb7\xc8\xbd\x08\xff\x6f\x48\x9f\x20\x5d\xaf\x8e\xff\xe1\x60\xf4\x37\xf6\x74\x91\xef\x89\x7c\x23",
+ 8 },
+ { GCRY_MD_SHA3_384,
+ "\x1f\x66\xab\x41\x85\xed\x9b\x63\x75",
+ "\xd6\x15\x46\x41\xd7\xd9\xdf\x62\xf0\xce\xdc\x2b\xd6\x4e\xe8\x24\x12\xb3\xa8\x0f\x6e\xac\xe7\xc4\x5f\x97\x03\x37\x33\x79\x00\x7e\xab\xf5\x92\xd2\xd2\x11\x6e\x09\x3d\xc3\x3d\xcb\xba\x46\x49\xe9",
+ 9 },
+ { GCRY_MD_SHA3_384,
+ "\xee\xd7\x42\x22\x27\x61\x3b\x6f\x53\xc9",
+ "\x2e\xe5\xdf\x25\x91\xcf\xc4\xcb\x1e\x1d\x0b\xd8\xb2\x87\x27\xf0\xfa\x53\x59\xa7\x5f\x78\x19\xa9\x2a\x3c\xb8\x0d\xdb\x57\x08\xe4\x70\x51\x77\xb9\x81\x39\x6b\x48\x18\xd1\x1e\x3c\xa6\x15\xec\x93",
+ 10 },
+ { GCRY_MD_SHA3_384,
+ "\xea\xee\xd5\xcd\xff\xd8\x9d\xec\xe4\x55\xf1",
+ "\x78\x6c\x3f\x73\xfb\x09\x2b\xe1\x84\xfc\x2b\x19\xf5\x92\x0f\x3d\x94\xf2\x5d\x45\x23\x16\x5a\xe8\x2f\x9b\x39\xb2\xc7\x24\xfd\x62\xdc\x9a\x32\x63\x09\x1a\x23\x9d\x5e\xf1\xad\x56\x2d\xd4\xfd\x26",
+ 11 },
+ { GCRY_MD_SHA3_384,
+ "\x5b\xe4\x3c\x90\xf2\x29\x02\xe4\xfe\x8e\xd2\xd3",
+ "\x79\x18\x81\x39\xec\x2c\xad\x8d\x19\x7d\x30\x8b\x80\x6c\xf3\x83\x78\x2c\x29\xa8\xc2\x7e\xe2\x9c\x5e\x31\x42\x5b\x2d\xd1\x8b\x2f\x5f\x49\x1f\xbf\xb3\x8d\x70\x78\xf5\x85\x10\x12\x5c\x06\x4a\x0a",
+ 12 },
+ { GCRY_MD_SHA3_384,
+ "\xa7\x46\x27\x32\x28\x12\x2f\x38\x1c\x3b\x46\xe4\xf1",
+ "\x0c\x82\xb8\xc7\x5c\x5d\x54\x0e\x7d\x62\x49\x28\x28\x1f\xba\x8b\x8d\x0b\x15\x83\xd7\x4f\x3f\x0e\xa4\xf2\x00\xf1\xce\x54\x75\x14\x9c\x28\x2e\x05\xdb\x69\x5d\xc6\x7b\xaf\x42\xde\xff\xdc\x3f\x55",
+ 13 },
+ { GCRY_MD_SHA3_384,
+ "\x3c\x58\x71\xcd\x61\x9c\x69\xa6\x3b\x54\x0e\xb5\xa6\x25",
+ "\x83\x0d\x23\x25\xc0\x01\x62\x3e\xdf\xea\x97\xea\x1d\x0e\x65\x98\x2d\x4e\xd7\xab\xb8\xe6\x4e\xa6\x1c\x85\xe9\xbc\x18\x82\xd1\x1f\xc4\x15\x3c\x30\xbe\x63\xfc\x66\xf5\xfb\xce\x74\xbb\x39\x45\x96",
+ 14 },
+ { GCRY_MD_SHA3_384,
+ "\xfa\x22\x87\x4b\xcc\x06\x88\x79\xe8\xef\x11\xa6\x9f\x07\x22",
+ "\x1d\xbe\x1b\xc6\x0a\x9c\x6f\xbe\x10\xa7\x27\xe2\xa6\xd3\x97\x93\x0d\x54\x7a\xd2\xc3\x90\x28\x69\x48\xc3\x16\x7e\xe7\x7f\xf6\xe2\x75\xec\x84\x31\xc5\xad\x4b\x4e\x4e\x5a\xe6\x7a\x4b\xc8\x8d\x05",
+ 15 },
+ { GCRY_MD_SHA3_384,
+ "\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76",
+ "\xfe\xee\x2e\xf3\x32\x51\x52\x84\xe0\xba\x24\x7c\x62\xf2\x64\x19\x90\x44\xd0\x38\x77\xc5\x8e\x54\xb5\x1a\x62\xe3\x9e\x91\xc2\x7a\xaa\xe3\x84\x83\x7e\xb9\xd4\x79\xb4\xc0\x30\x8c\xfc\x6b\x77\x9b",
+ 16 },
+ { GCRY_MD_SHA3_384,
+ "\x82\xe1\x92\xe4\x04\x3d\xdc\xd1\x2e\xcf\x52\x96\x9d\x0f\x80\x7e\xed",
+ "\x18\x88\xe9\x53\x72\x7c\xb8\x37\xde\x40\xc6\x98\x69\x56\x0c\x20\x72\x9c\x50\x63\x8e\x45\x61\xb3\x85\x93\x7b\xfc\x4c\x29\x7e\x78\x9e\xa6\xc0\x3e\xfc\xf2\xdf\x32\x90\xb1\xfd\x36\xbe\x26\x8c\x32",
+ 17 },
+ { GCRY_MD_SHA3_384,
+ "\x75\x68\x3d\xcb\x55\x61\x40\xc5\x22\x54\x3b\xb6\xe9\x09\x8b\x21\xa2\x1e",
+ "\x30\xde\x7b\x54\x42\x65\x42\x2c\xe6\x89\xe6\x67\xf4\x84\x98\xf4\x55\xe8\xbf\x10\x55\x65\x3f\x21\x29\x4e\xad\x7d\x2e\x89\x8b\x05\xfa\x75\xee\xca\x46\xdc\x25\x75\xc4\x75\xc4\x80\xaa\x49\xca\x62",
+ 18 },
+ { GCRY_MD_SHA3_384,
+ "\x06\xe4\xef\xe4\x50\x35\xe6\x1f\xaa\xf4\x28\x7b\x4d\x8d\x1f\x12\xca\x97\xe5",
+ "\x04\x1b\x7c\x89\xbd\x4b\x58\x2a\x7d\x20\xe5\x79\xc6\xfd\xb1\x8b\xa0\xc1\x25\x1d\xab\xac\xc6\x87\xaf\x44\x8e\xb4\x91\x51\xbb\xc0\x4a\xdc\xb8\x1d\x79\x7d\x4b\xc5\x1f\x03\xbf\xff\x23\x0f\xfc\xc6",
+ 19 },
+ { GCRY_MD_SHA3_384,
+ "\xe2\x61\x93\x98\x9d\x06\x56\x8f\xe6\x88\xe7\x55\x40\xae\xa0\x67\x47\xd9\xf8\x51",
+ "\xea\xf7\x51\xee\x6e\x75\xaa\x2c\x56\x45\x3f\x31\x6c\x01\x9b\xda\x7d\x7a\xe1\xfd\xa0\x3b\x79\xac\x41\x3b\xb1\xf2\x84\x0d\x58\xaa\xaa\xc7\x7f\x2d\xc1\x06\xd2\x2f\x1a\x71\x15\x7f\x9f\x84\x1c\x4b",
+ 20 },
+ { GCRY_MD_SHA3_384,
+ "\xd8\xdc\x8f\xde\xfb\xdc\xe9\xd4\x4e\x4c\xba\xfe\x78\x44\x7b\xae\x3b\x54\x36\x10\x2a",
+ "\x16\xc4\xa7\xf7\xe8\xba\x7e\xa1\x3c\x59\x57\x6b\xe6\x02\xf8\x85\xe2\x1b\xe7\xc3\x4b\x3a\xc0\x5c\xac\x42\x62\xba\xad\x8a\xa3\xf9\x5b\xd9\x26\x0f\x13\xf0\x85\x50\xce\x33\x1e\xc7\x73\xba\x75\x8c",
+ 21 },
+ { GCRY_MD_SHA3_384,
+ "\x57\x08\x5f\xd7\xe1\x42\x16\xab\x10\x2d\x83\x17\xb0\xcb\x33\x8a\x78\x6d\x5f\xc3\x2d\x8f",
+ "\x51\x19\xa4\xfc\x11\xda\xf2\xef\x5d\xeb\x7a\xeb\x35\x54\x91\x62\xd9\xaf\xc8\x27\x39\x2a\x88\x68\xe7\xf8\x59\x4a\x5c\x19\x4d\x9c\x8f\x6a\x43\x0c\xb3\x86\xb8\xd8\x25\xcc\x6d\xab\x4e\xdb\x74\x2a",
+ 22 },
+ { GCRY_MD_SHA3_384,
+ "\xa0\x54\x04\xdf\x5d\xbb\x57\x69\x7e\x2c\x16\xfa\x29\xde\xfa\xc8\xab\x35\x60\xd6\x12\x6f\xa0",
+ "\xa9\x1f\x01\x70\x45\x7e\x78\xb3\xbb\x15\xb0\xbd\xc0\xff\x4e\xfe\x8d\x73\x13\xd2\x72\x5d\x8e\x8d\xb8\x75\xbc\xaf\xbc\x11\x31\x41\x26\x55\x9f\x45\xe8\x6e\x78\x13\x6e\xb2\x14\xff\x02\x76\x4c\xab",
+ 23 },
+ { GCRY_MD_SHA3_384,
+ "\xae\xcb\xb0\x27\x59\xf7\x43\x3d\x6f\xcb\x06\x96\x3c\x74\x06\x1c\xd8\x3b\x5b\x3f\xfa\x6f\x13\xc6",
+ "\x98\xfe\x81\x74\x6c\xcf\x7c\xfe\x55\x71\xd6\xd8\xb0\x99\x43\xec\xae\x44\xf6\x06\x44\x4f\x9d\xab\xf1\xa5\x7f\xe4\xe8\x71\xf6\x96\x22\x66\xd1\x86\x52\xfd\x4e\xeb\xdb\xe4\x92\xcf\xc5\xb2\xb2\x1f",
+ 24 },
+ { GCRY_MD_SHA3_384,
+ "\xaa\xfd\xc9\x24\x3d\x3d\x4a\x09\x65\x58\xa3\x60\xcc\x27\xc8\xd8\x62\xf0\xbe\x73\xdb\x5e\x88\xaa\x55",
+ "\x3d\xd9\x05\x4c\x10\x5c\x40\x79\x8d\xf4\x5c\xfb\x58\x80\xf9\x7a\x95\x36\xfa\x7b\xd1\x3f\x1d\x81\x6b\x8e\xe8\x87\xfc\xba\xfc\x10\x2a\x7d\x4b\xde\x9f\xe6\xe2\x65\x53\x8e\xec\x25\x25\xb5\x0d\x89",
+ 25 },
+ { GCRY_MD_SHA3_384,
+ "\x7b\xc8\x48\x67\xf6\xf9\xe9\xfd\xc3\xe1\x04\x6c\xae\x3a\x52\xc7\x7e\xd4\x85\x86\x0e\xe2\x60\xe3\x0b\x15",
+ "\xde\xcd\x77\x8b\x89\xb4\x29\x50\x72\xdb\xf9\x86\x89\xe2\xeb\x60\x66\xe4\x06\x35\x6e\xa4\xb7\xca\xd5\x50\x01\x9f\x4a\x2a\xbb\x25\x16\x3e\x95\x71\xd0\xad\xb9\xad\xc6\xa8\x02\xb7\xe0\x3c\x15\x2c",
+ 26 },
+ { GCRY_MD_SHA3_384,
+ "\xfa\xc5\x23\x57\x5a\x99\xec\x48\x27\x9a\x7a\x45\x9e\x98\xff\x90\x19\x18\xa4\x75\x03\x43\x27\xef\xb5\x58\x43",
+ "\x37\xf1\x4b\x31\x7d\x46\xbd\xb3\xe5\xdd\x6f\x68\x98\x6a\x08\xa0\x98\xc4\x6b\x9d\x85\xd1\xf2\x54\xa1\x78\x78\xc0\x08\xf9\x79\x26\xc8\xa1\x3c\x38\x38\x72\x1c\xfe\x3a\x58\x07\x6f\x39\x92\xf2\x6c",
+ 27 },
+ { GCRY_MD_SHA3_384,
+ "\x0f\x8b\x2d\x8f\xcf\xd9\xd6\x8c\xff\xc1\x7c\xcf\xb1\x17\x70\x9b\x53\xd2\x64\x62\xa3\xf3\x46\xfb\x7c\x79\xb8\x5e",
+ "\x64\x1a\x7a\xf1\x3b\x88\x9d\x1a\x0f\x1a\xa3\xe4\xe4\xff\x8c\xc5\x90\x3c\x47\xe1\xa5\x2b\xde\xa2\x57\xd8\x0e\x37\xe5\x96\x56\x4a\xb3\x3e\xea\xd0\x67\x17\xcd\xb6\xb7\x06\xcb\x69\x86\x29\x3d\x4f",
+ 28 },
+ { GCRY_MD_SHA3_384,
+ "\xa9\x63\xc3\xe8\x95\xff\x5a\x0b\xe4\x82\x44\x00\x51\x8d\x81\x41\x2f\x87\x5f\xa5\x05\x21\xe2\x6e\x85\xea\xc9\x0c\x04",
+ "\x12\x2b\x8b\x86\x10\x3f\xe3\xc1\x8f\xf2\x81\x78\xa2\x56\xac\xb0\xca\xb8\x51\x83\x38\xd2\xcb\xa6\x97\xe3\xf5\x60\xec\xfe\xe0\x9b\x02\x4b\x97\xd8\xd1\xf6\x96\x32\xad\x1f\x2c\x5f\x56\x28\xd3\xef",
+ 29 },
+ { GCRY_MD_SHA3_384,
+ "\x03\xa1\x86\x88\xb1\x0c\xc0\xed\xf8\x3a\xdf\x0a\x84\x80\x8a\x97\x18\x38\x3c\x40\x70\xc6\xc4\xf2\x95\x09\x86\x99\xac\x2c",
+ "\xf3\x5a\x29\x2e\x19\x70\x07\xe2\x8c\xe6\x52\xa0\x67\x17\x3f\x36\x59\xc5\x1b\x70\x43\x8a\xa9\xe4\x33\x08\x1d\x3d\xf7\x1b\x4a\x11\xe3\xf3\xbe\x5a\xf3\x2e\x2c\x08\xd2\x3a\x0b\x44\xe3\x0b\x0b\xdf",
+ 30 },
+ { GCRY_MD_SHA3_384,
+ "\x84\xfb\x51\xb5\x17\xdf\x6c\x5a\xcc\xb5\xd0\x22\xf8\xf2\x8d\xa0\x9b\x10\x23\x2d\x42\x32\x0f\xfc\x32\xdb\xec\xc3\x83\x5b\x29",
+ "\x2e\xa5\x96\xb4\x46\xd5\xcc\xd8\xf0\x92\x7a\x2e\x37\x90\x91\x1e\x00\xf1\xf5\x2c\xfb\xfc\x41\xf1\x22\x90\xcb\xac\xd1\xc9\x03\xc7\x4d\xee\xf8\x40\xfd\x13\x98\xe1\x2e\xe8\x63\xac\xd9\x2b\xae\xbf",
+ 31 },
+ { GCRY_MD_SHA3_384,
+ "\x9f\x2f\xcc\x7c\x90\xde\x09\x0d\x6b\x87\xcd\x7e\x97\x18\xc1\xea\x6c\xb2\x11\x18\xfc\x2d\x5d\xe9\xf9\x7e\x5d\xb6\xac\x1e\x9c\x10",
+ "\xba\xae\x7a\xae\xd4\xfb\xf4\x2f\x93\x16\xc7\xe8\xf7\x22\xee\xb0\x6a\x59\x8b\x50\x9f\x18\x4b\x22\xfb\xd5\xa8\x1c\x93\xd9\x5f\xff\x71\x1f\x5d\xe9\x08\x47\xb3\x24\x8b\x6d\xf7\x6c\xab\xce\x07\xee",
+ 32 },
+ { GCRY_MD_SHA3_384,
+ "\xde\x8f\x1b\x3f\xaa\x4b\x70\x40\xed\x45\x63\xc3\xb8\xe5\x98\x25\x31\x78\xe8\x7e\x4d\x0d\xf7\x5e\x4f\xf2\xf2\xde\xdd\x5a\x0b\xe0\x46",
+ "\x32\xcf\xc8\xa1\x8a\x71\x16\xd4\xb9\x02\x90\x51\x94\x18\x08\xc3\xb3\x32\xef\xdb\x13\x2c\x51\x5f\x91\x10\xe1\x9b\x83\x54\x35\x5d\x94\x61\x6c\x99\x65\xbc\x2d\x1f\x24\x89\xf8\x45\x2a\xf7\xfb\x2f",
+ 33 },
+ { GCRY_MD_SHA3_384,
+ "\x62\xf1\x54\xec\x39\x4d\x0b\xc7\x57\xd0\x45\xc7\x98\xc8\xb8\x7a\x00\xe0\x65\x5d\x04\x81\xa7\xd2\xd9\xfb\x58\xd9\x3a\xed\xc6\x76\xb5\xa0",
+ "\x73\x44\x3e\xa3\x8a\x88\x01\x39\x5c\x04\x4e\x3c\xbe\xcd\x45\xdd\x62\xd6\xe3\x04\xc5\x44\x0f\xa9\xfe\x96\x51\xa4\x38\xc0\x10\xa7\x67\x12\x75\x9b\xe2\x06\x81\xf1\x41\x66\x61\xe7\x46\xe5\xeb\x77",
+ 34 },
+ { GCRY_MD_SHA3_384,
+ "\xb2\xdc\xfe\x9f\xf1\x9e\x2b\x23\xce\x7d\xa2\xa4\x20\x7d\x3e\x5e\xc7\xc6\x11\x2a\x8a\x22\xae\xc9\x67\x5a\x88\x63\x78\xe1\x4e\x5b\xfb\xad\x4e",
+ "\x6e\x82\xf4\x60\x66\x0f\x3d\x2c\xc3\x3a\xa5\x9a\x37\xf3\x25\xee\xd0\x13\x3f\xe2\x9a\x9c\xb4\x28\xa3\xc2\x25\x72\xb6\xbf\x6c\x5d\xa2\xd0\xd4\x64\x5c\x49\x13\x56\x53\xa0\x49\x79\x5d\x4e\x2a\xd0",
+ 35 },
+ { GCRY_MD_SHA3_384,
+ "\x47\xf5\x69\x7a\xc8\xc3\x14\x09\xc0\x86\x88\x27\x34\x7a\x61\x3a\x35\x62\x04\x1c\x63\x3c\xf1\xf1\xf8\x68\x65\xa5\x76\xe0\x28\x35\xed\x2c\x24\x92",
+ "\x22\x91\x60\xa6\x1c\xf2\x84\x2b\x37\xea\x85\x78\x8b\xb1\xce\x82\x94\xde\xd9\xea\xd2\x66\x35\x9d\x61\xdf\x3d\x6d\xf9\x8e\xe1\x55\xed\x03\xab\x1a\x51\xd6\x29\x1b\x41\x68\x0a\x00\x55\x32\x98\xeb",
+ 36 },
+ { GCRY_MD_SHA3_384,
+ "\x51\x2a\x6d\x29\x2e\x67\xec\xb2\xfe\x48\x6b\xfe\x92\x66\x09\x53\xa7\x54\x84\xff\x4c\x4f\x2e\xca\x2b\x0a\xf0\xed\xcd\xd4\x33\x9c\x6b\x2e\xe4\xe5\x42",
+ "\xf5\xd8\x38\xde\xdf\x07\xac\x3a\x56\x46\x22\x1a\xdc\x6c\xa5\x90\x45\x97\x6d\xf9\xc3\x33\x67\xfd\xaa\x0b\xe3\xaf\xc5\x7e\xef\x0d\x43\x4e\xe9\x2c\xd6\x18\xb3\xfa\x26\xc7\xea\xbd\x18\xd7\x87\x72",
+ 37 },
+ { GCRY_MD_SHA3_384,
+ "\x97\x3c\xf2\xb4\xdc\xf0\xbf\xa8\x72\xb4\x11\x94\xcb\x05\xbb\x4e\x16\x76\x0a\x18\x40\xd8\x34\x33\x01\x80\x25\x76\x19\x7e\xc1\x9e\x2a\x14\x93\xd8\xf4\xfb",
+ "\xd4\x1a\x32\x4a\x17\x39\xbb\xcf\xc9\x83\xa2\xb2\x50\x75\x0a\x11\x17\xe5\x7b\xd2\x65\x12\xcc\x5d\xca\x70\x66\xd8\xb9\x72\xad\x9e\xb0\xbb\x3c\x7e\x36\xb9\xb8\x4f\xc0\xe8\x12\x9b\x69\xcd\x38\x47",
+ 38 },
+ { GCRY_MD_SHA3_384,
+ "\x80\xbe\xeb\xcd\x2e\x3f\x8a\x94\x51\xd4\x49\x99\x61\xc9\x73\x1a\xe6\x67\xcd\xc2\x4e\xa0\x20\xce\x3b\x9a\xa4\xbb\xc0\xa7\xf7\x9e\x30\xa9\x34\x46\x7d\xa4\xb0",
+ "\x17\x0d\x73\xba\xf7\x7e\xae\x7a\x85\x2a\x1b\xb1\x9b\xa6\x66\x5f\x9e\xf4\x25\xa6\x6f\x26\x49\xe9\x59\xb5\xca\xa8\x2d\x01\xfd\xb8\x9c\x8c\x7f\xa6\xf4\x07\x02\xf7\xc3\x39\x1b\x14\x6f\x6f\xa3\x3e",
+ 39 },
+ { GCRY_MD_SHA3_384,
+ "\x7a\xba\xa1\x2e\xc2\xa7\x34\x76\x74\xe4\x44\x14\x0a\xe0\xfb\x65\x9d\x08\xe1\xc6\x6d\xec\xd8\xd6\xea\xe9\x25\xfa\x45\x1d\x65\xf3\xc0\x30\x8e\x29\x44\x6b\x8e\xd3",
+ "\xa8\xf4\xa6\x0a\x8f\xf5\xb3\xeb\xb4\xea\xdb\x9c\x46\xf1\xf4\x03\xab\x7f\xf6\x32\xc7\xa1\x1f\x80\xfc\x91\x53\x85\x8b\x48\x42\x91\xb3\x93\x67\x13\x07\x69\x55\x20\x7d\x0c\x7e\x19\x64\xdc\x13\x46",
+ 40 },
+ { GCRY_MD_SHA3_384,
+ "\xc8\x8d\xee\x99\x27\x67\x9b\x8a\xf4\x22\xab\xcb\xac\xf2\x83\xb9\x04\xff\x31\xe1\xca\xc5\x8c\x78\x19\x80\x9f\x65\xd5\x80\x7d\x46\x72\x3b\x20\xf6\x7b\xa6\x10\xc2\xb7",
+ "\x58\x15\xd7\x8a\xca\x96\x00\x63\x22\x39\xb7\xce\x83\x85\xd7\xe8\x37\xf8\x83\x85\x76\x01\xef\xb7\x8f\x9c\x2d\xac\x9a\x96\xae\x0b\xfd\x10\x75\x26\xf2\x68\xd0\x6f\xb4\x22\x7d\x47\x74\xa9\xe7\x27",
+ 41 },
+ { GCRY_MD_SHA3_384,
+ "\x01\xe4\x3f\xe3\x50\xfc\xec\x45\x0e\xc9\xb1\x02\x05\x3e\x6b\x5d\x56\xe0\x98\x96\xe0\xdd\xd9\x07\x4f\xe1\x38\xe6\x03\x82\x10\x27\x0c\x83\x4c\xe6\xea\xdc\x2b\xb8\x6b\xf6",
+ "\xa5\xd9\x1b\x01\x65\x0d\x24\xb4\x75\x3f\x41\x87\x1f\xa7\x00\xe9\x97\xd5\xf1\xef\x9c\x06\xd8\xf9\xb3\xa9\xb2\xd3\x18\x71\x64\x08\xe1\x56\x6b\xb0\x4b\x49\xb8\x4e\x77\xf5\xf7\x3d\x8f\x64\x05\x41",
+ 42 },
+ { GCRY_MD_SHA3_384,
+ "\x33\x70\x23\x37\x0a\x48\xb6\x2e\xe4\x35\x46\xf1\x7c\x4e\xf2\xbf\x8d\x7e\xcd\x1d\x49\xf9\x0b\xab\x60\x4b\x83\x9c\x2e\x6e\x5b\xd2\x15\x40\xd2\x9b\xa2\x7a\xb8\xe3\x09\xa4\xb7",
+ "\xc7\xba\x06\x68\x81\xdb\x93\x1e\x9c\x67\x4d\x74\xce\x23\x09\xb3\x00\x2c\x6d\x5b\xc2\x20\x56\xc4\x54\x26\x1c\xdb\xc5\xd9\x3f\xe3\x10\xea\xdd\x75\x5e\x41\xfb\x1d\x78\x9f\xdb\x9a\x73\xfd\xa2\x8f",
+ 43 },
+ { GCRY_MD_SHA3_384,
+ "\x68\x92\x54\x0f\x96\x4c\x8c\x74\xbd\x2d\xb0\x2c\x0a\xd8\x84\x51\x0c\xb3\x8a\xfd\x44\x38\xaf\x31\xfc\x91\x27\x56\xf3\xef\xec\x6b\x32\xb5\x8e\xbc\x38\xfc\x2a\x6b\x91\x35\x96\xa8",
+ "\xa5\x2c\xa3\x41\x3b\xb8\x39\x34\xb1\xea\xd4\x68\x6f\x63\x9b\x90\xc5\xee\x3c\xb5\xbe\x7e\x29\xa1\xa5\x29\x3c\x86\x84\x41\xd7\x9b\xe2\xef\x24\x6b\x42\x7f\xfc\xf0\x56\x8d\x4d\x01\xbe\x54\xff\x0d",
+ 44 },
+ { GCRY_MD_SHA3_384,
+ "\xf5\x96\x1d\xfd\x2b\x1f\xff\xfd\xa4\xff\xbf\x30\x56\x0c\x16\x5b\xfe\xda\xb8\xce\x0b\xe5\x25\x84\x5d\xeb\x8d\xc6\x10\x04\xb7\xdb\x38\x46\x72\x05\xf5\xdc\xfb\x34\xa2\xac\xfe\x96\xc0",
+ "\x13\xe6\x05\x54\xfa\x18\xce\xf8\x7c\xea\xbe\x14\x75\x41\x88\x6d\x97\xc2\xfb\x5f\x40\xf1\x63\xd9\x53\x30\x6d\x2a\x26\xb0\x13\xb3\x3c\xb2\x02\xd7\x8a\xef\x49\xfd\x47\xe7\xec\x1c\x74\x59\x20\xcd",
+ 45 },
+ { GCRY_MD_SHA3_384,
+ "\xca\x06\x1a\x2e\xb6\xce\xed\x88\x81\xce\x20\x57\x17\x2d\x86\x9d\x73\xa1\x95\x1e\x63\xd5\x72\x61\x38\x4b\x80\xce\xb5\x45\x1e\x77\xb0\x6c\xf0\xf5\xa0\xea\x15\xca\x90\x7e\xe1\xc2\x7e\xba",
+ "\xe4\xe0\x3c\xcb\xa9\x2b\xbd\x28\x18\x2d\x00\x5f\x69\xde\x4e\x71\xc6\x1c\x62\xcd\x32\x3d\xec\xfb\x2a\xdd\xbe\xef\xf7\xee\x74\x93\x3a\xa7\xa1\x67\xe4\xe1\xdb\xb3\xdf\x7e\x5c\x91\x18\x4f\x2d\x88",
+ 46 },
+ { GCRY_MD_SHA3_384,
+ "\x17\x43\xa7\x72\x51\xd6\x92\x42\x75\x0c\x4f\x11\x40\x53\x2c\xd3\xc3\x3f\x9b\x5c\xcd\xf7\x51\x4e\x85\x84\xd4\xa5\xf9\xfb\xd7\x30\xbc\xf8\x4d\x0d\x47\x26\x36\x4b\x9b\xf9\x5a\xb2\x51\xd9\xbb",
+ "\x9b\x26\xe9\xbf\x13\xb6\xfc\x33\xfd\x33\x5d\xf9\x76\xc8\xe1\xb7\x81\xc8\x00\x89\x5e\xbd\x72\xe3\x4f\x96\xeb\x87\x5b\x41\xf0\x4a\xae\xe8\x25\xcd\x8f\x0e\xb6\xc4\x3d\x80\x3f\x4e\x6e\xf6\x88\xa9",
+ 47 },
+ { GCRY_MD_SHA3_384,
+ "\xd8\xfa\xba\x1f\x51\x94\xc4\xdb\x5f\x17\x6f\xab\xff\xf8\x56\x92\x4e\xf6\x27\xa3\x7c\xd0\x8c\xf5\x56\x08\xbb\xa8\xf1\xe3\x24\xd7\xc7\xf1\x57\x29\x8e\xab\xc4\xdc\xe7\xd8\x9c\xe5\x16\x24\x99\xf9",
+ "\xa1\x27\xfe\xfc\xdd\x24\x0f\x76\x2c\xce\x3f\x5f\x15\x51\xfc\x7e\x1c\xde\xbc\x79\x50\xd1\xcd\x94\xc6\x88\x8f\x49\x0c\xb2\x28\x5a\x10\xfd\x0e\xe7\x97\xb1\x68\xc5\xca\x47\x61\xfa\x23\x2a\xaf\x05",
+ 48 },
+ { GCRY_MD_SHA3_384,
+ "\xbe\x96\x84\xbe\x70\x34\x08\x60\x37\x3c\x9c\x48\x2b\xa5\x17\xe8\x99\xfc\x81\xba\xaa\x12\xe5\xc6\xd7\x72\x79\x75\xd1\xd4\x1b\xa8\xbe\xf7\x88\xcd\xb5\xcf\x46\x06\xc9\xc1\xc7\xf6\x1a\xed\x59\xf9\x7d",
+ "\xfe\xb5\xa2\x4e\xdb\x05\xbe\xf8\x46\xb0\xa1\xf3\xf4\x8d\xa2\x12\xdf\xc2\xd0\xba\xc7\x46\x89\x0d\x4a\xd7\x2f\xbe\x3a\x7b\x4f\xf8\xe2\xb5\x42\xb8\x27\x77\x94\x67\x12\x22\x71\xb1\xe0\xdf\x2b\xd2",
+ 49 },
+ { GCRY_MD_SHA3_384,
+ "\x7e\x15\xd2\xb9\xea\x74\xca\x60\xf6\x6c\x8d\xfa\xb3\x77\xd9\x19\x8b\x7b\x16\xde\xb6\xa1\xba\x0e\xa3\xc7\xee\x20\x42\xf8\x9d\x37\x86\xe7\x79\xcf\x05\x3c\x77\x78\x5a\xa9\xe6\x92\xf8\x21\xf1\x4a\x7f\x51",
+ "\x8d\xa4\xf3\xd1\xa1\x31\x97\x17\x1b\x02\xe1\xcc\xb0\x7b\xf5\x1c\xdb\xab\xd8\x33\xfd\xc3\xc3\x79\x7a\x11\x3c\xfa\x5c\x71\x79\x57\x82\xc4\x7c\xe3\x6c\x38\x9f\xba\xd4\x61\xd0\xd5\xb5\x9c\xa6\x84",
+ 50 },
+ { GCRY_MD_SHA3_384,
+ "\x9a\x21\x9b\xe4\x37\x13\xbd\x57\x80\x15\xe9\xfd\xa6\x6c\x0f\x2d\x83\xca\xc5\x63\xb7\x76\xab\x9f\x38\xf3\xe4\xf7\xef\x22\x9c\xb4\x43\x30\x4f\xba\x40\x1e\xfb\x2b\xdb\xd7\xec\xe9\x39\x10\x22\x98\x65\x1c\x86",
+ "\xd1\x9f\xe4\xa5\xf9\x3b\xcd\x48\x3d\xaa\x7a\xf8\xcb\x63\x68\x07\x96\x2d\x40\xaf\x9a\x50\x7d\xc4\xfa\x4e\x1f\xd4\x80\xa6\xe8\xfa\x3c\x25\xfa\x30\xeb\x6b\x74\x97\x9e\xe4\x56\xc1\x64\x4a\x5c\x1d",
+ 51 },
+ { GCRY_MD_SHA3_384,
+ "\xc8\xf2\xb6\x93\xbd\x0d\x75\xef\x99\xca\xeb\xdc\x22\xad\xf4\x08\x8a\x95\xa3\x54\x2f\x63\x72\x03\xe2\x83\xbb\xc3\x26\x87\x80\xe7\x87\xd6\x8d\x28\xcc\x38\x97\x45\x2f\x6a\x22\xaa\x85\x73\xcc\xeb\xf2\x45\x97\x2a",
+ "\x63\xff\x30\x53\xac\xe6\x87\xfb\x91\x07\x0c\xa7\xfc\x6a\x51\xc2\x59\xe1\x3d\xa8\xac\x0d\xd7\x41\xab\x36\xd1\xfa\x93\x0e\x3b\xb9\xac\x6a\x1f\xad\x65\x4f\x72\x38\xcf\xc4\x48\x5c\x5f\x9f\x82\x52",
+ 52 },
+ { GCRY_MD_SHA3_384,
+ "\xec\x0f\x99\x71\x10\x16\xc6\xa2\xa0\x7a\xd8\x0d\x16\x42\x75\x06\xce\x6f\x44\x10\x59\xfd\x26\x94\x42\xba\xaa\x28\xc6\xca\x03\x7b\x22\xee\xac\x49\xd5\xd8\x94\xc0\xbf\x66\x21\x9f\x2c\x08\xe9\xd0\xe8\xab\x21\xde\x52",
+ "\x39\xdd\xe0\x2a\x31\x9b\x5e\x86\x9f\x4c\x51\xa1\xd3\x0f\xf4\xd4\xd8\x8e\xbe\x50\x4c\x54\xf1\x55\xaa\x5f\xad\x33\x16\x40\x4f\xdb\xd1\x91\x80\x74\xd3\x5d\x14\xba\xc8\x8d\x6f\x35\x91\x08\xa1\xdc",
+ 53 },
+ { GCRY_MD_SHA3_384,
+ "\x0d\xc4\x51\x81\x33\x7c\xa3\x2a\x82\x22\xfe\x7a\x3b\xf4\x2f\xc9\xf8\x97\x44\x25\x9c\xff\x65\x35\x04\xd6\x05\x1f\xe8\x4b\x1a\x7f\xfd\x20\xcb\x47\xd4\x69\x6c\xe2\x12\xa6\x86\xbb\x9b\xe9\xa8\xab\x1c\x69\x7b\x6d\x6a\x33",
+ "\x19\x59\x37\x8f\x32\x11\x7e\x58\xc0\x14\x11\x60\xe1\x6f\xac\xfe\x33\x65\x90\x19\x6b\xe8\x05\xd1\x49\xeb\x5a\xee\xa6\x41\xf9\xbb\x11\x9b\x3e\xdd\xfe\xfd\x81\x77\x01\xc8\x2d\x2f\x52\x8b\x82\x3e",
+ 54 },
+ { GCRY_MD_SHA3_384,
+ "\xde\x28\x6b\xa4\x20\x6e\x8b\x00\x57\x14\xf8\x0f\xb1\xcd\xfa\xeb\xde\x91\xd2\x9f\x84\x60\x3e\x4a\x3e\xbc\x04\x68\x6f\x99\xa4\x6c\x9e\x88\x0b\x96\xc5\x74\x82\x55\x82\xe8\x81\x2a\x26\xe5\xa8\x57\xff\xc6\x57\x9f\x63\x74\x2f",
+ "\x7b\x17\x2a\x9b\xb3\x11\xb1\x37\x5e\x15\xec\xe1\xc1\xe8\xf0\x92\xbe\xcf\xaf\xec\x9f\x31\x44\xe9\x3f\x59\x6e\xb7\xe6\xab\xfb\x34\xfc\xed\xb0\x8e\xda\x78\x83\xeb\xbf\x40\x03\x8b\x7a\x75\x4f\x9f",
+ 55 },
+ { GCRY_MD_SHA3_384,
+ "\xee\xbc\xc1\x80\x57\x25\x2c\xbf\x3f\x9c\x07\x0f\x1a\x73\x21\x33\x56\xd5\xd4\xbc\x19\xac\x2a\x41\x1e\xc8\xcd\xee\xe7\xa5\x71\xe2\xe2\x0e\xaf\x61\xfd\x0c\x33\xa0\xff\xeb\x29\x7d\xdb\x77\xa9\x7f\x0a\x41\x53\x47\xdb\x66\xbc\xaf",
+ "\x6b\xa3\x2e\xca\xaa\x0a\xa9\xc5\x9e\x72\x17\x3f\x2a\x78\x16\xac\x51\xf3\x13\xc4\x67\xa0\x17\x19\x0d\xb9\x83\x2c\x63\x11\xec\x23\xb8\xd5\x6b\x7b\x22\x0f\xa0\x9a\x90\x81\x96\x2e\xfe\xd5\x18\x3e",
+ 56 },
+ { GCRY_MD_SHA3_384,
+ "\x41\x6b\x5c\xdc\x9f\xe9\x51\xbd\x36\x1b\xd7\xab\xfc\x12\x0a\x50\x54\x75\x8e\xba\x88\xfd\xd6\x8f\xd8\x4e\x39\xd3\xb0\x9a\xc2\x54\x97\xd3\x6b\x43\xcb\xe7\xb8\x5a\x6a\x3c\xeb\xda\x8d\xb4\xe5\x54\x9c\x3e\xe5\x1b\xb6\xfc\xb6\xac\x1e",
+ "\x55\xfd\xf2\xec\x27\xd3\x34\xb5\xb5\x9e\xfb\x9b\x6d\x51\x8e\x25\xbe\x0f\x5f\xf6\x37\x9f\x7b\x97\x94\x5f\x3e\x12\x35\xec\x70\x29\x5b\x39\xeb\xea\xbf\x70\xfc\xaf\x1e\x61\xed\xb1\xc2\x1a\x4c\x06",
+ 57 },
+ { GCRY_MD_SHA3_384,
+ "\x5c\x5f\xaf\x66\xf3\x2e\x0f\x83\x11\xc3\x2e\x8d\xa8\x28\x4a\x4e\xd6\x08\x91\xa5\xa7\xe5\x0f\xb2\x95\x6b\x3c\xba\xa7\x9f\xc6\x6c\xa3\x76\x46\x0e\x10\x04\x15\x40\x1f\xc2\xb8\x51\x8c\x64\x50\x2f\x18\x7e\xa1\x4b\xfc\x95\x03\x75\x97\x05",
+ "\xd5\x1a\x3f\x33\x91\x9f\xe5\xda\x0e\xfe\xa6\xed\xad\x20\x1f\x01\xfa\x84\x16\xc3\x85\xa8\x9d\x96\xdf\x74\x3d\x24\x3a\x6a\xab\xa5\xb7\x69\x0d\x18\x7b\x95\xca\xff\xda\xcd\x1e\x85\xf5\x6b\x81\x3b",
+ 58 },
+ { GCRY_MD_SHA3_384,
+ "\x71\x67\xe1\xe0\x2b\xe1\xa7\xca\x69\xd7\x88\x66\x6f\x82\x3a\xe4\xee\xf3\x92\x71\xf3\xc2\x6a\x5c\xf7\xce\xe0\x5b\xca\x83\x16\x10\x66\xdc\x2e\x21\x7b\x33\x0d\xf8\x21\x10\x37\x99\xdf\x6d\x74\x81\x0e\xed\x36\x3a\xdc\x4a\xb9\x9f\x36\x04\x6a",
+ "\xf1\xd6\xe8\xf9\x5c\x49\x7d\x5b\xea\xfb\x42\x15\xe0\x7c\xdb\x59\xe0\xe3\x70\x9c\xf5\x61\x61\x8f\x67\xe3\x01\x93\x1d\x20\x4c\x6c\xe4\x77\xe0\xf7\x50\x09\x95\x84\xb6\x45\xe2\xf7\x18\x65\x08\x13",
+ 59 },
+ { GCRY_MD_SHA3_384,
+ "\x2f\xda\x31\x1d\xbb\xa2\x73\x21\xc5\x32\x95\x10\xfa\xe6\x94\x8f\x03\x21\x0b\x76\xd4\x3e\x74\x48\xd1\x68\x9a\x06\x38\x77\xb6\xd1\x4c\x4f\x6d\x0e\xaa\x96\xc1\x50\x05\x13\x71\xf7\xdd\x8a\x41\x19\xf7\xda\x5c\x48\x3c\xc3\xe6\x72\x3c\x01\xfb\x7d",
+ "\xb1\xd3\x47\xd0\x57\xcc\xd7\x28\x67\xb1\x2b\xf0\x0b\xf5\x11\xf8\x7d\xef\xcd\x0f\xa6\xad\xad\xaf\x4b\xb1\xad\x79\x0f\x06\xec\xbb\x1f\x44\x88\xa0\x31\x9b\x05\xc4\x6a\x78\x74\x85\x73\x70\xce\x76",
+ 60 },
+ { GCRY_MD_SHA3_384,
+ "\x95\xd1\x47\x4a\x5a\xab\x5d\x24\x22\xac\xa6\xe4\x81\x18\x78\x33\xa6\x21\x2b\xd2\xd0\xf9\x14\x51\xa6\x7d\xd7\x86\xdf\xc9\x1d\xfe\xd5\x1b\x35\xf4\x7e\x1d\xeb\x8a\x8a\xb4\xb9\xcb\x67\xb7\x01\x79\xcc\x26\xf5\x53\xae\x7b\x56\x99\x69\xce\x15\x1b\x8d",
+ "\x4f\x19\x2e\xdf\xa5\x4f\xec\xe6\x4a\xc0\xb3\xec\x9e\x12\x0b\x29\x1a\xde\x99\x94\x88\x05\xa8\x7b\xbb\x04\x94\x7e\x92\x8b\xb5\xeb\xa8\x7e\x2e\xe5\x99\x96\x0c\x43\x6e\xa7\xc7\x88\x41\x87\xe7\x8c",
+ 61 },
+ { GCRY_MD_SHA3_384,
+ "\xc7\x1b\xd7\x94\x1f\x41\xdf\x04\x4a\x29\x27\xa8\xff\x55\xb4\xb4\x67\xc3\x3d\x08\x9f\x09\x88\xaa\x25\x3d\x29\x4a\xdd\xbd\xb3\x25\x30\xc0\xd4\x20\x8b\x10\xd9\x95\x98\x23\xf0\xc0\xf0\x73\x46\x84\x00\x6d\xf7\x9f\x70\x99\x87\x0f\x6b\xf5\x32\x11\xa8\x8d",
+ "\x75\xe2\x3f\xed\x3b\x59\xdb\x6b\x1d\x33\x78\xb7\xe8\x77\x26\x42\xcb\xbf\xf7\x71\x0d\x8a\x91\xb2\x49\xbb\x6c\x68\xe3\x84\xcd\x41\x6f\x19\xac\x1e\x8e\xd9\x2b\x71\xd0\xca\x30\x3d\x24\x7e\xe9\xbd",
+ 62 },
+ { GCRY_MD_SHA3_384,
+ "\xf5\x7c\x64\x00\x6d\x9e\xa7\x61\x89\x2e\x14\x5c\x99\xdf\x1b\x24\x64\x08\x83\xda\x79\xd9\xed\x52\x62\x85\x9d\xcd\xa8\xc3\xc3\x2e\x05\xb0\x3d\x98\x4f\x1a\xb4\xa2\x30\x24\x2a\xb6\xb7\x8d\x36\x8d\xc5\xaa\xa1\xe6\xd3\x49\x8d\x53\x37\x1e\x84\xb0\xc1\xd4\xba",
+ "\xc8\xd1\xe6\xbe\x54\x85\xfc\x13\xbf\x43\x3f\x11\xa5\x80\xab\xbe\x89\xb1\x2a\x66\xd0\xe5\xcb\x14\x1e\x1d\x62\xcd\xc6\xa3\x67\x72\x57\x93\xfb\x25\x84\x0b\x36\xcb\x70\x03\xf2\xe7\xdf\x3e\x5f\x2f",
+ 63 },
+ { GCRY_MD_SHA3_384,
+ "\xe9\x26\xae\x8b\x0a\xf6\xe5\x31\x76\xdb\xff\xcc\x2a\x6b\x88\xc6\xbd\x76\x5f\x93\x9d\x3d\x17\x8a\x9b\xde\x9e\xf3\xaa\x13\x1c\x61\xe3\x1c\x1e\x42\xcd\xfa\xf4\xb4\xdc\xde\x57\x9a\x37\xe1\x50\xef\xbe\xf5\x55\x5b\x4c\x1c\xb4\x04\x39\xd8\x35\xa7\x24\xe2\xfa\xe7",
+ "\x42\x3b\xa1\x34\xd3\xbc\xb5\xe4\x40\xac\x83\x37\x2c\x7e\xdd\xba\x3a\xe3\xbd\xdf\x12\x22\xf5\x05\xc1\x9c\xde\x24\x6a\xd7\x6a\x2b\x0d\x07\x23\x9a\x54\xe1\xd0\x93\x4c\x9b\x3d\x29\xd4\x9e\x5f\xbd",
+ 64 },
+ { GCRY_MD_SHA3_384,
+ "\x16\xe8\xb3\xd8\xf9\x88\xe9\xbb\x04\xde\x9c\x96\xf2\x62\x78\x11\xc9\x73\xce\x4a\x52\x96\xb4\x77\x2c\xa3\xee\xfe\xb8\x0a\x65\x2b\xdf\x21\xf5\x0d\xf7\x9f\x32\xdb\x23\xf9\xf7\x3d\x39\x3b\x2d\x57\xd9\xa0\x29\x7f\x7a\x2f\x2e\x79\xcf\xda\x39\xfa\x39\x3d\xf1\xac\x00",
+ "\x66\x2c\x48\x51\xd3\x11\xa7\x86\xde\x4c\xda\x7e\x9e\xa1\xef\xf0\xbf\xa4\x62\x76\x1f\xf6\xcf\x80\x4e\x59\x1e\xd9\xa1\x5b\x0d\xc9\x3a\x2b\xb6\xa6\xcf\xfd\xc8\xd7\xd2\x3a\x23\x3a\x52\xc8\x6e\xad",
+ 65 },
+ { GCRY_MD_SHA3_384,
+ "\xfc\x42\x4e\xeb\x27\xc1\x8a\x11\xc0\x1f\x39\xc5\x55\xd8\xb7\x8a\x80\x5b\x88\xdb\xa1\xdc\x2a\x42\xed\x5e\x2c\x0e\xc7\x37\xff\x68\xb2\x45\x6d\x80\xeb\x85\xe1\x17\x14\xfa\x3f\x8e\xab\xfb\x90\x6d\x3c\x17\x96\x4c\xb4\xf5\xe7\x6b\x29\xc1\x76\x5d\xb0\x3d\x91\xbe\x37\xfc",
+ "\x5f\x54\xb1\xda\xfa\x67\xed\x9b\x49\x81\x25\xe0\x64\xf0\xb0\x7f\x54\xe7\x54\xe3\xf3\x07\x20\xdd\x4a\x47\x1e\x9b\xb6\xe3\x07\xf0\x5f\xb6\x9b\xc8\x1d\x39\x1f\x50\x3c\x95\xc3\xbb\x67\x1e\x69\x73",
+ 66 },
+ { GCRY_MD_SHA3_384,
+ "\xab\xe3\x47\x2b\x54\xe7\x27\x34\xbd\xba\x7d\x91\x58\x73\x64\x64\x25\x1c\x4f\x21\xb3\x3f\xbb\xc9\x2d\x7f\xac\x9a\x35\xc4\xe3\x32\x2f\xf0\x1d\x23\x80\xcb\xaa\x4e\xf8\xfb\x07\xd2\x1a\x21\x28\xb7\xb9\xf5\xb6\xd9\xf3\x4e\x13\xf3\x9c\x7f\xfc\x2e\x72\xe4\x78\x88\x59\x9b\xa5",
+ "\xa2\x1b\x55\xde\xd8\xfe\x41\xfb\x2b\x19\x3f\xa4\x90\x42\x0a\x8b\x62\xfc\xae\x9a\x18\x5d\xa8\x5e\x25\x3d\xae\xfe\x85\x27\x0b\x69\x04\xba\x4e\xcc\x76\xbb\x51\x28\x92\x6f\xff\x9d\x79\xf7\x28\xad",
+ 67 },
+ { GCRY_MD_SHA3_384,
+ "\x36\xf9\xf0\xa6\x5f\x2c\xa4\x98\xd7\x39\xb9\x44\xd6\xef\xf3\xda\x5e\xbb\xa5\x7e\x7d\x9c\x41\x59\x8a\x2b\x0e\x43\x80\xf3\xcf\x4b\x47\x9e\xc2\x34\x8d\x01\x5f\xfe\x62\x56\x27\x35\x11\x15\x4a\xfc\xf3\xb4\xb4\xbf\x09\xd6\xc4\x74\x4f\xdd\x0f\x62\xd7\x50\x79\xd4\x40\x70\x6b\x05",
+ "\x34\x1b\xe5\x67\x7a\x05\xee\xd8\x16\xa2\x19\x66\x9d\x68\x0b\xbf\x18\x5b\x31\xcf\x3e\xb0\xd2\x89\xf9\x02\x10\xfb\x1a\x79\x40\xd9\xbf\xf4\x90\x93\x20\xae\x4e\x3b\x72\x74\xe5\xbe\x47\x9c\x46\xf1",
+ 68 },
+ { GCRY_MD_SHA3_384,
+ "\xab\xc8\x77\x63\xca\xe1\xca\x98\xbd\x8c\x5b\x82\xca\xba\x54\xac\x83\x28\x6f\x87\xe9\x61\x01\x28\xae\x4d\xe6\x8a\xc9\x5d\xf5\xe3\x29\xc3\x60\x71\x7b\xd3\x49\xf2\x6b\x87\x25\x28\x49\x2c\xa7\xc9\x4c\x2c\x1e\x1e\xf5\x6b\x74\xdb\xb6\x5c\x2a\xc3\x51\x98\x1f\xdb\x31\xd0\x6c\x77\xa4",
+ "\xd7\x0f\x78\x89\x4e\x29\x2b\x07\x5a\x0f\xe5\x6f\xb9\x52\xb2\xce\x87\xa9\x4c\xa0\x29\x34\x71\x59\xfb\xb1\x2b\x22\x10\x3d\xd4\xdc\x4c\x26\x5b\x7a\xe8\x89\x50\xcc\xa8\x9c\x40\xb5\x31\x43\x7a\xa4",
+ 69 },
+ { GCRY_MD_SHA3_384,
+ "\x94\xf7\xca\x8e\x1a\x54\x23\x4c\x6d\x53\xcc\x73\x4b\xb3\xd3\x15\x0c\x8b\xa8\xc5\xf8\x80\xea\xb8\xd2\x5f\xed\x13\x79\x3a\x97\x01\xeb\xe3\x20\x50\x92\x86\xfd\x8e\x42\x2e\x93\x1d\x99\xc9\x8d\xa4\xdf\x7e\x70\xae\x44\x7b\xab\x8c\xff\xd9\x23\x82\xd8\xa7\x77\x60\xa2\x59\xfc\x4f\xbd\x72",
+ "\x89\xbd\x6b\x7c\xc9\xad\xdd\xff\xe4\x6b\xf8\x5c\x56\xb8\xce\x66\xe1\xb1\xb4\x69\x69\xb1\x97\xad\xbf\x2e\x34\xb7\x05\x9d\x8b\xb0\x5f\x9f\x53\xbd\x1a\x58\xa7\xe0\xa6\x6e\x5e\xf2\x08\xbf\x56\x95",
+ 70 },
+ { GCRY_MD_SHA3_384,
+ "\x13\xbd\x28\x11\xf6\xed\x2b\x6f\x04\xff\x38\x95\xac\xee\xd7\xbe\xf8\xdc\xd4\x5e\xb1\x21\x79\x1b\xc1\x94\xa0\xf8\x06\x20\x6b\xff\xc3\xb9\x28\x1c\x2b\x30\x8b\x1a\x72\x9c\xe0\x08\x11\x9d\xd3\x06\x6e\x93\x78\xac\xdc\xc5\x0a\x98\xa8\x2e\x20\x73\x88\x00\xb6\xcd\xdb\xe5\xfe\x96\x94\xad\x6d",
+ "\xae\x65\x1e\xf5\x0a\x20\xb0\xf4\x96\xf1\x04\xf5\x6f\x84\x52\x06\xed\x54\x4b\x28\xd0\x37\x4c\xbb\x77\x91\x46\xdf\xf2\xea\x58\x94\xeb\x29\x30\x1f\xe3\x38\x72\xf9\xb2\x99\xa7\x9c\x0c\x0f\x28\xc4",
+ 71 },
+ { GCRY_MD_SHA3_384,
+ "\x1e\xed\x9c\xba\x17\x9a\x00\x9e\xc2\xec\x55\x08\x77\x3d\xd3\x05\x47\x7c\xa1\x17\xe6\xd5\x69\xe6\x6b\x5f\x64\xc6\xbc\x64\x80\x1c\xe2\x5a\x84\x24\xce\x4a\x26\xd5\x75\xb8\xa6\xfb\x10\xea\xd3\xfd\x19\x92\xed\xdd\xee\xc2\xeb\xe7\x15\x0d\xc9\x8f\x63\xad\xc3\x23\x7e\xf5\x7b\x91\x39\x7a\xa8\xa7",
+ "\xa8\x42\x91\x8d\xfb\xbf\x3b\xff\xcc\xc5\x27\xb6\xdd\x2c\x0d\xf4\xeb\x3f\x10\x0f\x06\x92\x72\x7d\xa7\x7d\xaf\x44\xa6\x54\x87\x60\x13\xb3\x70\x31\xc4\x93\xac\x18\x95\x00\x03\xee\xbd\x10\x7a\x29",
+ 72 },
+ { GCRY_MD_SHA3_384,
+ "\xba\x5b\x67\xb5\xec\x3a\x3f\xfa\xe2\xc1\x9d\xd8\x17\x6a\x2e\xf7\x5c\x0c\xd9\x03\x72\x5d\x45\xc9\xcb\x70\x09\xa9\x00\xc0\xb0\xca\x7a\x29\x67\xa9\x5a\xe6\x82\x69\xa6\xdb\xf8\x46\x6c\x7b\x68\x44\xa1\xd6\x08\xac\x66\x1f\x7e\xff\x00\x53\x8e\x32\x3d\xb5\xf2\xc6\x44\xb7\x8b\x2d\x48\xde\x1a\x08\xaa",
+ "\x20\xd1\x6c\xc6\xaf\x5b\x4d\x5a\xec\xce\xad\x09\xf3\x00\xb1\xdc\x1d\xa9\x3a\x60\x83\x70\xee\x0b\x2c\xf1\x5c\x31\x65\x08\xb5\xef\x8c\x9b\xe2\x7d\x0f\x72\x88\x61\x7b\x1e\x52\x9f\xc2\x93\x20\x38",
+ 73 },
+ { GCRY_MD_SHA3_384,
+ "\x0e\xfa\x26\xac\x56\x73\x16\x7d\xca\xca\xb8\x60\x93\x2e\xd6\x12\xf6\x5f\xf4\x9b\x80\xfa\x9a\xe6\x54\x65\xe5\x54\x2c\xb6\x20\x75\xdf\x1c\x5a\xe5\x4f\xba\x4d\xb8\x07\xbe\x25\xb0\x70\x03\x3e\xfa\x22\x3b\xdd\x5b\x1d\x3c\x94\xc6\xe1\x90\x9c\x02\xb6\x20\xd4\xb1\xb3\xa6\xc9\xfe\xd2\x4d\x70\x74\x96\x04",
+ "\x69\xa3\xbb\x36\xf5\x2e\xb6\x50\xc6\xe8\x24\x2d\xb0\x56\x59\x57\x3a\xf8\x11\xa1\xa5\xdb\x90\x8f\x77\x3d\x65\xe7\x4d\x32\x7f\x5b\x65\x30\x3d\xd0\xdd\x9b\xd0\x7f\xf1\x00\xd0\x50\xe4\x6f\xe9\x7d",
+ 74 },
+ { GCRY_MD_SHA3_384,
+ "\xbb\xfd\x93\x3d\x1f\xd7\xbf\x59\x4a\xc7\xf4\x35\x27\x7d\xc1\x7d\x8d\x5a\x5b\x8e\x4d\x13\xd9\x6d\x2f\x64\xe7\x71\xab\xbd\x51\xa5\xa8\xae\xa7\x41\xbe\xcc\xbd\xdb\x17\x7b\xce\xa0\x52\x43\xeb\xd0\x03\xcf\xde\xae\x87\x7c\xca\x4d\xa9\x46\x05\xb6\x76\x91\x91\x9d\x8b\x03\x3f\x77\xd3\x84\xca\x01\x59\x3c\x1b",
+ "\xd2\x39\xf2\xfa\x16\x75\xa1\xa0\x31\xe2\xf6\xe8\xa5\x3d\x6e\x2f\x37\xd0\x81\xcd\xb0\x29\x72\x7b\x3a\xcb\xdd\x7c\xbf\xc7\xd3\x58\x1b\xde\x8d\x30\x68\xaa\x9a\x30\x0a\xe1\x2b\x72\x45\x12\x45\x08",
+ 75 },
+ { GCRY_MD_SHA3_384,
+ "\x90\x07\x89\x99\xfd\x3c\x35\xb8\xaf\xbf\x40\x66\xcb\xde\x33\x58\x91\x36\x5f\x0f\xc7\x5c\x12\x86\xcd\xd8\x8f\xa5\x1f\xab\x94\xf9\xb8\xde\xf7\xc9\xac\x58\x2a\x5d\xbc\xd9\x58\x17\xaf\xb7\xd1\xb4\x8f\x63\x70\x4e\x19\xc2\xba\xa4\xdf\x34\x7f\x48\xd4\xa6\xd6\x03\x01\x3c\x23\xf1\xe9\x61\x1d\x59\x5e\xba\xc3\x7c",
+ "\x2f\x8d\x74\x7d\xdf\x64\x32\x02\x97\xb4\x4f\x85\x47\xef\x42\xfc\xe7\x8a\x48\xf0\xa5\x9a\x18\xdb\x1c\xfb\x9f\x43\xc0\x49\x62\x8f\x97\xc0\xbb\x93\xad\xaa\xb9\x61\x71\x55\x27\x24\x24\xf7\x40\x27",
+ 76 },
+ { GCRY_MD_SHA3_384,
+ "\x64\x10\x5e\xca\x86\x35\x15\xc2\x0e\x7c\xfb\xaa\x0a\x0b\x88\x09\x04\x61\x64\xf3\x74\xd6\x91\xcd\xbd\x65\x08\xaa\xab\xc1\x81\x9f\x9a\xc8\x4b\x52\xba\xfc\x1b\x0f\xe7\xcd\xdb\xc5\x54\xb6\x08\xc0\x1c\x89\x04\xc6\x69\xd8\xdb\x31\x6a\x09\x53\xa4\xc6\x8e\xce\x32\x4e\xc5\xa4\x9f\xfd\xb5\x9a\x1b\xd6\xa2\x92\xaa\x0e",
+ "\x71\x4b\xe6\xf2\xf9\x34\xe0\xb6\xfd\x69\xe3\x92\xd9\x9a\xcc\x98\x59\x2b\x01\x5e\x48\xa1\x63\x72\x62\xf9\x92\x86\x50\x2b\x06\x77\x47\x83\xbb\x9f\x37\x1c\x76\x0c\x3e\xb7\x8a\xea\xdf\xbd\x0d\xf0",
+ 77 },
+ { GCRY_MD_SHA3_384,
+ "\xd4\x65\x4b\xe2\x88\xb9\xf3\xb7\x11\xc2\xd0\x20\x15\x97\x8a\x8c\xc5\x74\x71\xd5\x68\x0a\x09\x2a\xa5\x34\xf7\x37\x2c\x71\xce\xaa\xb7\x25\xa3\x83\xc4\xfc\xf4\xd8\xde\xaa\x57\xfc\xa3\xce\x05\x6f\x31\x29\x61\xec\xcf\x9b\x86\xf1\x49\x81\xba\x5b\xed\x6a\xb5\xb4\x49\x8e\x1f\x6c\x82\xc6\xca\xe6\xfc\x14\x84\x5b\x3c\x8a",
+ "\x22\xa4\x1b\x11\x74\x64\xf7\xf4\x96\x82\xe8\x13\x9a\x0d\x5b\xd2\x3f\xe0\x0d\x11\x90\xb1\xb4\x19\xf2\x7b\x49\x0b\x72\x9b\x56\xbb\xa9\xde\x64\x9d\xd7\xc9\x88\xb6\xb3\x08\x03\x86\x61\xe1\xc3\x62",
+ 78 },
+ { GCRY_MD_SHA3_384,
+ "\x12\xd9\x39\x48\x88\x30\x5a\xc9\x6e\x65\xf2\xbf\x0e\x1b\x18\xc2\x9c\x90\xfe\x9d\x71\x4d\xd5\x9f\x65\x1f\x52\xb8\x8b\x30\x08\xc5\x88\x43\x55\x48\x06\x6e\xa2\xfc\x4c\x10\x11\x18\xc9\x1f\x32\x55\x62\x24\xa5\x40\xde\x6e\xfd\xdb\xca\x29\x6e\xf1\xfb\x00\x34\x1f\x5b\x01\xfe\xcf\xc1\x46\xbd\xb2\x51\xb3\xbd\xad\x55\x6c\xd2",
+ "\x77\x78\x0f\x36\x46\xd2\x88\x29\x17\x90\xf2\xa5\xf4\xaa\x9c\x98\xa6\x4a\x11\x15\x30\x69\x94\xcd\x65\xc7\x62\x0d\xde\x06\xd3\x51\x17\xce\x4b\x79\xda\xe0\x8b\x5b\x4e\x79\x84\x59\x01\x09\x41\xbb",
+ 79 },
+ { GCRY_MD_SHA3_384,
+ "\x87\x1a\x0d\x7a\x5f\x36\xc3\xda\x1d\xfc\xe5\x7a\xcd\x8a\xb8\x48\x7c\x27\x4f\xad\x33\x6b\xc1\x37\xeb\xd6\xff\x46\x58\xb5\x47\xc1\xdc\xfa\xb6\x5f\x03\x7a\xa5\x8f\x35\xef\x16\xaf\xf4\xab\xe7\x7b\xa6\x1f\x65\x82\x6f\x7b\xe6\x81\xb5\xb6\xd5\xa1\xea\x80\x85\xe2\xae\x9c\xd5\xcf\x09\x91\x87\x8a\x31\x1b\x54\x9a\x6d\x6a\xf2\x30",
+ "\x5c\xed\x3b\x73\x68\x58\x2d\xd6\xde\xbf\xe4\x1d\x6a\xff\xd8\x2b\x72\x89\x4b\x51\xff\x4c\x4a\xcc\xba\x09\xc5\x95\xb3\x6e\x23\xe3\x47\xab\x4b\xaa\xb0\xe5\x19\x1d\x86\xe2\x6e\x65\x96\xd6\x2e\x23",
+ 80 },
+ { GCRY_MD_SHA3_384,
+ "\xe9\x0b\x4f\xfe\xf4\xd4\x57\xbc\x77\x11\xff\x4a\xa7\x22\x31\xca\x25\xaf\x6b\x2e\x20\x6f\x8b\xf8\x59\xd8\x75\x8b\x89\xa7\xcd\x36\x10\x5d\xb2\x53\x8d\x06\xda\x83\xba\xd5\xf6\x63\xba\x11\xa5\xf6\xf6\x1f\x23\x6f\xd5\xf8\xd5\x3c\x5e\x89\xf1\x83\xa3\xce\xc6\x15\xb5\x0c\x7c\x68\x1e\x77\x3d\x10\x9f\xf7\x49\x1b\x5c\xc2\x22\x96\xc5",
+ "\x14\x10\xef\x9a\xbb\x8d\x98\xb1\xc6\x5e\x11\x3a\x61\x91\x5b\x0e\x69\x33\xbc\x59\xda\x31\xc8\xfc\xc3\x9b\x71\x65\xe7\x15\x91\x91\x84\x37\x5d\x82\x2a\x07\xc7\x78\xf6\x34\x31\xbe\x2a\xee\xcd\x99",
+ 81 },
+ { GCRY_MD_SHA3_384,
+ "\xe7\x28\xde\x62\xd7\x58\x56\x50\x0c\x4c\x77\xa4\x28\x61\x2c\xd8\x04\xf3\x0c\x3f\x10\xd3\x6f\xb2\x19\xc5\xca\x0a\xa3\x07\x26\xab\x19\x0e\x5f\x3f\x27\x9e\x07\x33\xd7\x7e\x72\x67\xc1\x7b\xe2\x7d\x21\x65\x0a\x9a\x4d\x1e\x32\xf6\x49\x62\x76\x38\xdb\xad\xa9\x70\x2c\x7c\xa3\x03\x26\x9e\xd1\x40\x14\xb2\xf3\xcf\x8b\x89\x4e\xac\x85\x54",
+ "\x33\x0e\xd5\x1b\x04\x54\x71\xde\xa8\xcf\xf2\x65\x10\xd6\x84\x94\x61\x1e\xcf\xd6\x14\xd4\x9e\x5a\x9c\xc8\x84\x6a\x13\x25\x19\xbb\xcf\x49\x90\x76\x91\xac\x5a\xcc\xfc\x05\x28\xda\x0c\x14\xd4\x9e",
+ 82 },
+ { GCRY_MD_SHA3_384,
+ "\x63\x48\xf2\x29\xe7\xb1\xdf\x3b\x77\x0c\x77\x54\x4e\x51\x66\xe0\x81\x85\x0f\xa1\xc6\xc8\x81\x69\xdb\x74\xc7\x6e\x42\xeb\x98\x3f\xac\xb2\x76\xad\x6a\x0d\x1f\xa7\xb5\x0d\x3e\x3b\x6f\xcd\x79\x9e\xc9\x74\x70\x92\x0a\x7a\xbe\xd4\x7d\x28\x8f\xf8\x83\xe2\x4c\xa2\x1c\x7f\x80\x16\xb9\x3b\xb9\xb9\xe0\x78\xbd\xb9\x70\x3d\x2b\x78\x1b\x61\x6e",
+ "\x38\x71\x11\xa2\x06\xfc\x64\x88\xf7\x8d\x41\x78\x68\x86\xa9\xe5\xec\x9f\x73\xe1\x13\x1d\x92\xf2\x90\xf6\x85\x12\x32\x0a\x40\x8d\x5f\x63\xea\xa5\xab\xa3\x2d\x98\x53\xeb\x11\xb5\xb0\x88\x7e\x62",
+ 83 },
+ { GCRY_MD_SHA3_384,
+ "\x4b\x12\x7f\xde\x5d\xe7\x33\xa1\x68\x0c\x27\x90\x36\x36\x27\xe6\x3a\xc8\xa3\xf1\xb4\x70\x7d\x98\x2c\xae\xa2\x58\x65\x5d\x9b\xf1\x8f\x89\xaf\xe5\x41\x27\x48\x2b\xa0\x1e\x08\x84\x55\x94\xb6\x71\x30\x6a\x02\x5c\x9a\x5c\x5b\x6f\x93\xb0\xa3\x95\x22\xdc\x87\x74\x37\xbe\x5c\x24\x36\xcb\xf3\x00\xce\x7a\xb6\x74\x79\x34\xfc\xfc\x30\xae\xaa\xf6",
+ "\x78\x57\x3f\x5d\x07\x52\x00\xd3\x82\x31\x94\xa7\x1e\x55\x88\x0f\x4f\xe7\x84\x89\x23\x4d\xbf\x3d\xf3\xe3\x73\x4c\xbc\xae\x8d\xc1\xd8\xc1\xae\x95\xf9\xef\xa9\x90\x3d\xc4\xc4\x58\x1b\x59\xdd\xde",
+ 84 },
+ { GCRY_MD_SHA3_384,
+ "\x08\x46\x1f\x00\x6c\xff\x4c\xc6\x4b\x75\x2c\x95\x72\x87\xe5\xa0\xfa\xab\xc0\x5c\x9b\xff\x89\xd2\x3f\xd9\x02\xd3\x24\xc7\x99\x03\xb4\x8f\xcb\x8f\x8f\x4b\x01\xf3\xe4\xdd\xb4\x83\x59\x3d\x25\xf0\x00\x38\x66\x98\xf5\xad\xe7\xfa\xad\xe9\x61\x5f\xdc\x50\xd3\x27\x85\xea\x51\xd4\x98\x94\xe4\x5b\xaa\x3d\xc7\x07\xe2\x24\x68\x8c\x64\x08\xb6\x8b\x11",
+ "\xfd\xfe\x4f\x1b\x03\x47\x33\xc2\xc9\x4a\x7b\x36\xe2\xb5\x27\x74\xa9\x5c\x2b\xde\x22\xfc\xdd\xfc\xef\x52\xf7\xfe\xf7\xc6\x7f\x08\xe2\xf7\xb9\xb8\x96\x7e\x44\x7f\x76\xef\x91\x96\x0d\xa7\x62\x88",
+ 85 },
+ { GCRY_MD_SHA3_384,
+ "\x68\xc8\xf8\x84\x9b\x12\x0e\x6e\x0c\x99\x69\xa5\x86\x6a\xf5\x91\xa8\x29\xb9\x2f\x33\xcd\x9a\x4a\x31\x96\x95\x7a\x14\x8c\x49\x13\x8e\x1e\x2f\x5c\x76\x19\xa6\xd5\xed\xeb\xe9\x95\xac\xd8\x1e\xc8\xbb\x9c\x7b\x9c\xfc\xa6\x78\xd0\x81\xea\x9e\x25\xa7\x5d\x39\xdb\x04\xe1\x8d\x47\x59\x20\xce\x82\x8b\x94\xe7\x22\x41\xf2\x4d\xb7\x25\x46\xb3\x52\xa0\xe4",
+ "\x48\xd6\x6a\x41\x65\xaa\x54\x52\x8e\xce\x89\xbd\x9a\xa0\x0e\xab\x19\x6f\x32\xdf\xdc\x4d\x76\xf2\x36\x65\x58\x35\x52\x7a\xaa\x16\x42\xe6\xbf\x4e\xdf\x24\xf0\x30\xf5\xee\xef\x07\xfa\x40\xf5\xd2",
+ 86 },
+ { GCRY_MD_SHA3_384,
+ "\xb8\xd5\x64\x72\x95\x4e\x31\xfb\x54\xe2\x8f\xca\x74\x3f\x84\xd8\xdc\x34\x89\x1c\xb5\x64\xc6\x4b\x08\xf7\xb7\x16\x36\xde\xbd\x64\xca\x1e\xdb\xdb\xa7\xfc\x5c\x3e\x40\x04\x9c\xe9\x82\xbb\xa8\xc7\xe0\x70\x30\x34\xe3\x31\x38\x46\x95\xe9\xde\x76\xb5\x10\x4f\x2f\xbc\x45\x35\xec\xbe\xeb\xc3\x3b\xc2\x7f\x29\xf1\x8f\x6f\x27\xe8\x02\x3b\x0f\xbb\x6f\x56\x3c",
+ "\x3c\x25\x75\x37\x2c\xe1\xf3\x80\xa6\xe6\x6b\xb0\x75\xfb\xae\x98\xfc\x2e\x6d\x3d\x26\x7a\x20\xff\x03\x13\xab\xc3\xde\x25\x2e\x03\xfd\x5b\xdf\xa8\xbc\x2b\x79\xfc\x87\x4c\xcd\xa4\xab\xdb\xb4\xa6",
+ 87 },
+ { GCRY_MD_SHA3_384,
+ "\x0d\x58\xac\x66\x5f\xa8\x43\x42\xe6\x0c\xef\xee\x31\xb1\xa4\xea\xcd\xb0\x92\xf1\x22\xdf\xc6\x83\x09\x07\x7a\xed\x1f\x3e\x52\x8f\x57\x88\x59\xee\x9e\x4c\xef\xb4\xa7\x28\xe9\x46\x32\x49\x27\xb6\x75\xcd\x4f\x4a\xc8\x4f\x64\xdb\x3d\xac\xfe\x85\x0c\x1d\xd1\x87\x44\xc7\x4c\xec\xcd\x9f\xe4\xdc\x21\x40\x85\x10\x8f\x40\x4e\xab\x6d\x8f\x45\x2b\x54\x42\xa4\x7d",
+ "\x0e\xe6\xae\xca\x8d\xd8\x0b\x74\x22\x5a\xc4\x88\x2e\x2b\xc1\xe6\x81\x9c\x9b\x94\xf0\xd0\xbc\x0a\x1e\x21\xaa\xbf\x4b\x11\xcb\x74\xdb\x47\x34\xbc\x8d\x11\x79\xd7\xdc\xef\x53\x5b\xe9\xf3\xda\x28",
+ 88 },
+ { GCRY_MD_SHA3_384,
+ "\x17\x55\xe2\xd2\xe5\xd1\xc1\xb0\x15\x64\x56\xb5\x39\x75\x3f\xf4\x16\x65\x1d\x44\x69\x8e\x87\x00\x2d\xcf\x61\xdc\xfa\x2b\x4e\x72\xf2\x64\xd9\xad\x59\x1d\xf1\xfd\xee\x7b\x41\xb2\xeb\x00\x28\x3c\x5a\xeb\xb3\x41\x13\x23\xb6\x72\xea\xa1\x45\xc5\x12\x51\x85\x10\x4f\x20\xf3\x35\x80\x4b\x02\x32\x5b\x6d\xea\x65\x60\x3f\x34\x9f\x4d\x5d\x8b\x78\x2d\xd3\x46\x9c\xcd",
+ "\x80\x27\xe5\x04\x49\x23\xf8\xee\xe1\xdf\x18\x48\x65\xcd\x97\xb6\x35\xa7\x8d\xa1\x99\xfd\x80\xad\x3d\x34\x3a\x5a\xe0\x3d\x1b\x16\x5e\x58\xd1\xb0\xbd\x09\x3e\xf9\x16\xa1\x6d\x66\x41\xbd\xa1\x7c",
+ 89 },
+ { GCRY_MD_SHA3_384,
+ "\xb1\x80\xde\x1a\x61\x11\x11\xee\x75\x84\xba\x2c\x4b\x02\x05\x98\xcd\x57\x4a\xc7\x7e\x40\x4e\x85\x3d\x15\xa1\x01\xc6\xf5\xa2\xe5\xc8\x01\xd7\xd8\x5d\xc9\x52\x86\xa1\x80\x4c\x87\x0b\xb9\xf0\x0f\xd4\xdc\xb0\x3a\xa8\x32\x82\x75\x15\x88\x19\xdc\xad\x72\x53\xf3\xe3\xd2\x37\xae\xaa\x79\x79\x26\x8a\x5d\xb1\xc6\xce\x08\xa9\xec\x7c\x25\x79\x78\x3c\x8a\xfc\x1f\x91\xa7",
+ "\x79\x68\x18\xe0\x47\x91\x3d\x5a\xfb\x4a\xe4\xc5\xb7\xc5\xd5\xef\x69\x9a\x3a\x9e\xbe\xfb\x44\x46\x2e\xe8\xfe\x60\x3c\xa5\x62\x89\x73\x36\x9e\x4a\x9d\x8e\x10\x11\x5f\xdd\x75\xc8\x97\x07\xa8\xf9",
+ 90 },
+ { GCRY_MD_SHA3_384,
+ "\xcf\x35\x83\xcb\xdf\xd4\xcb\xc1\x70\x63\xb1\xe7\xd9\x0b\x02\xf0\xe6\xe2\xee\x05\xf9\x9d\x77\xe2\x4e\x56\x03\x92\x53\x5e\x47\xe0\x50\x77\x15\x7f\x96\x81\x35\x44\xa1\x70\x46\x91\x4f\x9e\xfb\x64\x76\x2a\x23\xcf\x7a\x49\xfe\x52\xa0\xa4\xc0\x1c\x63\x0c\xfe\x87\x27\xb8\x1f\xb9\x9a\x89\xff\x7c\xc1\x1d\xca\x51\x73\x05\x7e\x04\x17\xb8\xfe\x7a\x9e\xfb\xa6\xd9\x5c\x55\x5f",
+ "\x1e\x96\xef\xf6\x2e\x9f\x46\x4b\x48\x02\x97\x2f\xda\xc7\x7c\x3e\xa1\x13\x1b\x28\x22\x61\x9d\x2c\x5d\x86\x3e\x35\x7d\x09\x45\xc1\x7f\x93\xed\xe6\x6a\xf0\x5d\x46\xe6\x3c\x28\x57\xa5\x4f\x67\xf4",
+ 91 },
+ { GCRY_MD_SHA3_384,
+ "\x07\x2f\xc0\x23\x40\xef\x99\x11\x5b\xad\x72\xf9\x2c\x01\xe4\xc0\x93\xb9\x59\x9f\x6c\xfc\x45\xcb\x38\x0e\xe6\x86\xcb\x5e\xb0\x19\xe8\x06\xab\x9b\xd5\x5e\x63\x4a\xb1\x0a\xa6\x2a\x95\x10\xcc\x06\x72\xcd\x3e\xdd\xb5\x89\xc7\xdf\x2b\x67\xfc\xd3\x32\x9f\x61\xb1\xa4\x44\x1e\xca\x87\xa3\x3c\x8f\x55\xda\x4f\xbb\xad\x5c\xf2\xb2\x52\x7b\x8e\x98\x3b\xb3\x1a\x2f\xad\xec\x75\x23",
+ "\x4c\xc4\x1c\x2f\xb7\xd7\x1d\xa1\xad\x36\xd1\x80\x29\xf7\x55\xda\xf3\x42\xe7\x32\xec\x31\xf0\xc0\x6e\x27\x09\x13\x07\x71\x8a\xcb\x53\xfa\x11\x3a\xe5\x08\xdf\x38\xb8\xc9\x68\x34\xde\x33\xf9\xf1",
+ 92 },
+ { GCRY_MD_SHA3_384,
+ "\x76\xee\xcf\x95\x6a\x52\x64\x9f\x87\x75\x28\x14\x6d\xe3\x3d\xf2\x49\xcd\x80\x0e\x21\x83\x0f\x65\xe9\x0f\x0f\x25\xca\x9d\x65\x40\xfd\xe4\x06\x03\x23\x0e\xca\x67\x60\xf1\x13\x9c\x7f\x26\x8d\xeb\xa2\x06\x06\x31\xee\xa9\x2b\x1f\xff\x05\xf9\x3f\xd5\x57\x2f\xbe\x29\x57\x9e\xcd\x48\xbc\x3a\x8d\x6c\x2e\xb4\xa6\xb2\x6e\x38\xd6\xc5\xfb\xf2\xc0\x80\x44\xae\xea\x47\x0a\x8f\x2f\x26",
+ "\x9a\x8d\x4b\x56\x04\x21\xc8\x29\x91\xbd\xfc\xa0\x89\x8a\x29\xa5\x9b\xdb\x09\xd2\x0f\x8a\x5b\x27\x90\x96\x72\x3b\xab\x38\x27\x89\xf0\x81\xea\xd5\x0d\x27\x3e\xca\x43\x6c\x52\x6a\xba\x6d\x5c\xfc",
+ 93 },
+ { GCRY_MD_SHA3_384,
+ "\x7a\xdc\x0b\x66\x93\xe6\x1c\x26\x9f\x27\x8e\x69\x44\xa5\xa2\xd8\x30\x09\x81\xe4\x00\x22\xf8\x39\xac\x64\x43\x87\xbf\xac\x90\x86\x65\x00\x85\xc2\xcd\xc5\x85\xfe\xa4\x7b\x9d\x2e\x52\xd6\x5a\x2b\x29\xa7\xdc\x37\x04\x01\xef\x5d\x60\xdd\x0d\x21\xf9\xe2\xb9\x0f\xae\x91\x93\x19\xb1\x4b\x8c\x55\x65\xb0\x42\x3c\xef\xb8\x27\xd5\xf1\x20\x33\x02\xa9\xd0\x15\x23\x49\x8a\x4d\xb1\x03\x74",
+ "\x36\x7c\xb3\xfe\x03\xa3\xcb\xb5\x0f\xae\x1f\xe7\xea\x88\x3a\x0a\xe5\x3c\xbe\x77\x2f\x70\x9d\xc5\x50\x5f\x3c\x90\x75\x64\xc0\x8f\xc4\x97\x07\xcf\xf9\x63\x9b\x25\xc7\x46\xb6\x03\x9f\xf4\x8a\xe9",
+ 94 },
+ { GCRY_MD_SHA3_384,
+ "\xe1\xff\xfa\x98\x26\xcc\xe8\xb8\x6b\xcc\xef\xb8\x79\x4e\x48\xc4\x6c\xdf\x37\x20\x13\xf7\x82\xec\xed\x1e\x37\x82\x69\xb7\xbe\x2b\x7b\xf5\x13\x74\x09\x22\x61\xae\x12\x0e\x82\x2b\xe6\x85\xf2\xe7\xa8\x36\x64\xbc\xfb\xe3\x8f\xe8\x63\x3f\x24\xe6\x33\xff\xe1\x98\x8e\x1b\xc5\xac\xf5\x9a\x58\x70\x79\xa5\x7a\x91\x0b\xda\x60\x06\x0e\x85\xb5\xf5\xb6\xf7\x76\xf0\x52\x96\x39\xd9\xcc\xe4\xbd",
+ "\xbb\xbd\x05\xd6\x9d\x7a\x08\x2f\xcd\xa8\xed\x53\x5d\x7e\x4e\x5d\xe1\x37\x7b\xd9\x1e\x72\xd4\x2d\xc9\x52\x95\xc9\xdb\x78\x01\x69\xe2\xf9\x62\x0e\xc7\xa5\xaf\xf9\x59\xff\x2d\x94\x6f\xd2\x0a\x72",
+ 95 },
+ { GCRY_MD_SHA3_384,
+ "\x69\xf9\xab\xba\x65\x59\x2e\xe0\x1d\xb4\xdc\xe5\x2d\xba\xb9\x0b\x08\xfc\x04\x19\x36\x02\x79\x2e\xe4\xda\xa2\x63\x03\x3d\x59\x08\x15\x87\xb0\x9b\xbe\x49\xd0\xb4\x9c\x98\x25\xd2\x28\x40\xb2\xff\x5d\x9c\x51\x55\xf9\x75\xf8\xf2\xc2\xe7\xa9\x0c\x75\xd2\xe4\xa8\x04\x0f\xe3\x9f\x63\xbb\xaf\xb4\x03\xd9\xe2\x8c\xc3\xb8\x6e\x04\xe3\x94\xa9\xc9\xe8\x06\x5b\xd3\xc8\x5f\xa9\xf0\xc7\x89\x16\x00",
+ "\xbe\x8b\xec\x0c\x2e\xc7\x21\xe0\xc3\x26\x03\x7c\xe8\x6a\x15\x18\xfb\x39\x5c\x3a\x98\x02\xde\x01\xc3\xe2\x34\x26\x8e\xbb\x9a\xc9\xa3\x9a\x6e\x40\x4f\x25\xfb\x7f\xeb\xdc\xf1\xf7\xf2\x5d\xc0\x83",
+ 96 },
+ { GCRY_MD_SHA3_384,
+ "\x38\xa1\x0a\x35\x2c\xa5\xae\xdf\xa8\xe1\x9c\x64\x78\x7d\x8e\x9c\x3a\x75\xdb\xf3\xb8\x67\x4b\xfa\xb2\x9b\x5d\xbf\xc1\x5a\x63\xd1\x0f\xae\x66\xcd\x1a\x6e\x6d\x24\x52\xd5\x57\x96\x7e\xaa\xd8\x9a\x4c\x98\x44\x97\x87\xb0\xb3\x16\x4c\xa5\xb7\x17\xa9\x3f\x24\xeb\x0b\x50\x6c\xeb\x70\xcb\xbc\xb8\xd7\x2b\x2a\x72\x99\x3f\x90\x9a\xad\x92\xf0\x44\xe0\xb5\xa2\xc9\xac\x9c\xb1\x6a\x0c\xa2\xf8\x1f\x49",
+ "\x2a\xee\xaf\x29\x2a\xd6\x25\x22\x1b\xa7\x9a\x62\x12\x17\xfd\x1b\x3f\x89\x78\xba\x83\xfe\x7f\xf1\x3b\x38\x57\x4f\xcf\xaf\xfb\xd2\x07\x29\x88\x54\xb6\xf9\xc2\x7d\x66\x77\x49\x42\x04\x22\x1f\xda",
+ 97 },
+ { GCRY_MD_SHA3_384,
+ "\x6d\x8c\x6e\x44\x9b\xc1\x36\x34\xf1\x15\x74\x9c\x24\x8c\x17\xcd\x14\x8b\x72\x15\x7a\x2c\x37\xbf\x89\x69\xea\x83\xb4\xd6\xba\x8c\x0e\xe2\x71\x1c\x28\xee\x11\x49\x5f\x43\x04\x95\x96\x52\x0c\xe4\x36\x00\x4b\x02\x6b\x6c\x1f\x72\x92\xb9\xc4\x36\xb0\x55\xcb\xb7\x2d\x53\x0d\x86\x0d\x12\x76\xa1\x50\x2a\x51\x40\xe3\xc3\xf5\x4a\x93\x66\x3e\x4d\x20\xed\xec\x32\xd2\x84\xe2\x55\x64\xf6\x24\x95\x5b\x52",
+ "\x9a\x17\x61\xc5\x75\x9c\xe6\x7c\x9c\x09\x3e\xc5\xc8\x31\xc1\xff\x7c\xab\x64\xac\x7c\x80\x02\x06\x6e\xdc\xae\xd0\x44\xde\xf5\x7c\xea\x3e\xf6\xbe\x98\x57\x83\x63\xd2\xce\x3d\x1f\x5b\xa4\x48\xf8",
+ 98 },
+ { GCRY_MD_SHA3_384,
+ "\x6e\xfc\xbc\xaf\x45\x1c\x12\x9d\xbe\x00\xb9\xce\xf0\xc3\x74\x9d\x3e\xe9\xd4\x1c\x7b\xd5\x00\xad\xe4\x0c\xdc\x65\xde\xdb\xbb\xad\xb8\x85\xa5\xb1\x4b\x32\xa0\xc0\xd0\x87\x82\x52\x01\xe3\x03\x28\x8a\x73\x38\x42\xfa\x7e\x59\x9c\x0c\x51\x4e\x07\x8f\x05\xc8\x21\xc7\xa4\x49\x8b\x01\xc4\x00\x32\xe9\xf1\x87\x2a\x1c\x92\x5f\xa1\x7c\xe2\x53\xe8\x93\x5e\x4c\x3c\x71\x28\x22\x42\xcb\x71\x6b\x20\x89\xcc\xc1",
+ "\x4a\x24\xa1\xaf\x68\xdb\x65\xc3\x97\x74\x31\xee\x81\x09\x2c\x77\x6f\x7c\xb3\x3d\x6f\x08\x94\x01\x00\xea\x24\x0a\x2d\x1f\x86\x23\xa4\x1d\x07\xce\x99\x37\xbc\xbe\xc8\xca\x10\x72\xa1\xa7\x8e\x8b",
+ 99 },
+ { GCRY_MD_SHA3_384,
+ "\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce",
+ "\x92\x8e\x94\xd1\x9f\xc6\x00\x65\xa5\xef\x7e\x48\x01\x83\x87\xc8\x0f\x2d\x35\x0f\x30\x6d\x0f\x61\x01\x73\x71\x9d\x5c\x87\x4d\x4a\x8a\xcc\x34\x0f\xea\xd4\xbe\x35\x7e\x1f\x78\x12\x41\x98\xad\x77",
+ 100 },
+ { GCRY_MD_SHA3_384,
+ "\xa8\x73\xe0\xc6\x7c\xa6\x39\x02\x6b\x66\x83\x00\x8f\x7a\xa6\x32\x4d\x49\x79\x55\x0e\x9b\xce\x06\x4c\xa1\xe1\xfb\x97\xa3\x0b\x14\x7a\x24\xf3\xf6\x66\xc0\xa7\x2d\x71\x34\x8e\xde\x70\x1c\xf2\xd1\x7e\x22\x53\xc3\x4d\x1e\xc3\xb6\x47\xdb\xce\xf2\xf8\x79\xf4\xeb\x88\x1c\x48\x30\xb7\x91\x37\x8c\x90\x1e\xb7\x25\xea\x5c\x17\x23\x16\xc6\xd6\x06\xe0\xaf\x7d\xf4\xdf\x7f\x76\xe4\x90\xcd\x30\xb2\xba\xdf\x45\x68\x5f",
+ "\x78\xa1\x8d\x62\xf8\xa7\xef\xf5\xc6\xdd\x75\xb8\xcb\x07\x3f\xd3\x0e\xe6\x8c\x87\x8c\x2e\xc5\x8a\xad\x1c\x5d\xd0\xeb\x0a\xe4\x36\x98\xa6\x17\xbb\x0c\x67\x0f\xce\x2a\xa0\x98\xe0\xad\xf4\x25\xb2",
+ 101 },
+ { GCRY_MD_SHA3_384,
+ "\x00\x69\x17\xb6\x4f\x9d\xcd\xf1\xd2\xd8\x7c\x8a\x61\x73\xb6\x4f\x65\x87\x16\x8e\x80\xfa\xa8\x0f\x82\xd8\x4f\x60\x30\x1e\x56\x1e\x31\x2d\x9f\xbc\xe6\x2f\x39\xa6\xfb\x47\x6e\x01\xe9\x25\xf2\x6b\xcc\x91\xde\x62\x14\x49\xbe\x65\x04\xc5\x04\x83\x0a\xae\x39\x40\x96\xc8\xfc\x76\x94\x65\x10\x51\x36\x5d\x4e\xe9\x07\x01\x01\xec\x9b\x68\x08\x6f\x2e\xa8\xf8\xab\x7b\x81\x1e\xa8\xad\x93\x4d\x5c\x9b\x62\xc6\x0a\x47\x71",
+ "\xee\xeb\x56\xc3\xe5\x4f\xa8\x33\xb9\x85\xef\xa5\x92\x3c\x3f\x02\x25\xf4\x19\x66\x4c\xed\xd8\x98\xc7\x9f\x64\xd7\x2d\x2a\xd4\xb1\x25\xa3\x8b\xe0\x20\x18\x46\xc4\x42\xea\xf0\x05\x1d\x51\x6d\xc9",
+ 102 },
+ { GCRY_MD_SHA3_384,
+ "\xf1\x3c\x97\x2c\x52\xcb\x3c\xc4\xa4\xdf\x28\xc9\x7f\x2d\xf1\x1c\xe0\x89\xb8\x15\x46\x6b\xe8\x88\x63\x24\x3e\xb3\x18\xc2\xad\xb1\xa4\x17\xcb\x10\x41\x30\x85\x98\x54\x17\x20\x19\x7b\x9b\x1c\xb5\xba\x23\x18\xbd\x55\x74\xd1\xdf\x21\x74\xaf\x14\x88\x41\x49\xba\x9b\x2f\x44\x6d\x60\x9d\xf2\x40\xce\x33\x55\x99\x95\x7b\x8e\xc8\x08\x76\xd9\xa0\x85\xae\x08\x49\x07\xbc\x59\x61\xb2\x0b\xf5\xf6\xca\x58\xd5\xda\xb3\x8a\xdb",
+ "\x0a\x83\x4e\x11\x1b\x4e\x84\x0e\x78\x7c\x19\x74\x84\x65\xa4\x7d\x88\xb3\xf0\xf3\xda\xaf\x15\xdb\x25\x53\x6b\xdc\x60\x78\xfa\x9c\x05\xe6\xc9\x53\x83\x02\x74\x22\x39\x68\x84\x7d\xa8\xbf\xd2\x0d",
+ 103 },
+ { GCRY_MD_SHA3_384,
+ "\xe3\x57\x80\xeb\x97\x99\xad\x4c\x77\x53\x5d\x4d\xdb\x68\x3c\xf3\x3e\xf3\x67\x71\x53\x27\xcf\x4c\x4a\x58\xed\x9c\xbd\xcd\xd4\x86\xf6\x69\xf8\x01\x89\xd5\x49\xa9\x36\x4f\xa8\x2a\x51\xa5\x26\x54\xec\x72\x1b\xb3\xaa\xb9\x5d\xce\xb4\xa8\x6a\x6a\xfa\x93\x82\x6d\xb9\x23\x51\x7e\x92\x8f\x33\xe3\xfb\xa8\x50\xd4\x56\x60\xef\x83\xb9\x87\x6a\xcc\xaf\xa2\xa9\x98\x7a\x25\x4b\x13\x7c\x6e\x14\x0a\x21\x69\x1e\x10\x69\x41\x38\x48",
+ "\xd1\xc0\xfa\x85\xc8\xd1\x83\xbe\xff\x99\xad\x9d\x75\x2b\x26\x3e\x28\x6b\x47\x7f\x79\xf0\x71\x0b\x01\x03\x17\x01\x73\x97\x81\x33\x44\xb9\x9d\xaf\x3b\xb7\xb1\xbc\x5e\x8d\x72\x2b\xac\x85\x94\x3a",
+ 104 },
+ { GCRY_MD_SHA3_384,
+ "\x64\xec\x02\x1c\x95\x85\xe0\x1f\xfe\x6d\x31\xbb\x50\xd4\x4c\x79\xb6\x99\x3d\x72\x67\x81\x63\xdb\x47\x49\x47\xa0\x53\x67\x46\x19\xd1\x58\x01\x6a\xdb\x24\x3f\x5c\x8d\x50\xaa\x92\xf5\x0a\xb3\x6e\x57\x9f\xf2\xda\xbb\x78\x0a\x2b\x52\x93\x70\xda\xa2\x99\x20\x7c\xfb\xcd\xd3\xa9\xa2\x50\x06\xd1\x9c\x4f\x1f\xe3\x3e\x4b\x1e\xae\xc3\x15\xd8\xc6\xee\x1e\x73\x06\x23\xfd\x19\x41\x87\x5b\x92\x4e\xb5\x7d\x6d\x0c\x2e\xdc\x4e\x78\xd6",
+ "\x6a\xed\xcf\x44\x26\xb2\x48\x3c\x0d\x0d\x04\x69\x5b\xcc\x05\x2b\xed\xd0\x4f\xa4\xd1\x7a\x1b\xbb\x27\x97\xf6\x27\x2f\xa4\x76\xbf\xc1\x38\xe4\x09\x14\x09\xfe\xb1\xac\x0e\x8b\xff\x35\x0a\x66\x63",
+ 105 },
+ { GCRY_MD_SHA3_384,
+ "\x59\x54\xba\xb5\x12\xcf\x32\x7d\x66\xb5\xd9\xf2\x96\x18\x00\x80\x40\x26\x24\xad\x76\x28\x50\x6b\x55\x5e\xea\x83\x82\x56\x23\x24\xcf\x45\x2f\xba\x4a\x21\x30\xde\x3e\x16\x5d\x11\x83\x1a\x27\x0d\x9c\xb9\x7c\xe8\xc2\xd3\x2a\x96\xf5\x0d\x71\x60\x0b\xb4\xca\x26\x8c\xf9\x8e\x90\xd6\x49\x6b\x0a\x66\x19\xa5\xa8\xc6\x3d\xb6\xd8\xa0\x63\x4d\xfc\x6c\x7e\xc8\xea\x9c\x00\x6b\x6c\x45\x6f\x1b\x20\xcd\x19\xe7\x81\xaf\x20\x45\x4a\xc8\x80",
+ "\xac\xb7\x01\x3c\xe7\x51\x24\x38\x81\x87\xdc\x0e\x74\x30\xcb\x74\xa3\x14\xd6\x01\xb6\xc8\xd7\xa7\xde\x5c\xf0\x31\x97\xa8\x4f\x78\x74\xff\x05\x88\x08\x57\x5c\xb2\xf1\x01\x85\xf5\x61\xbb\x06\xb1",
+ 106 },
+ { GCRY_MD_SHA3_384,
+ "\x03\xd9\xf9\x2b\x2c\x56\x57\x09\xa5\x68\x72\x4a\x0a\xff\x90\xf8\xf3\x47\xf4\x3b\x02\x33\x8f\x94\xa0\x3e\xd3\x2e\x6f\x33\x66\x6f\xf5\x80\x2d\xa4\xc8\x1b\xdc\xe0\xd0\xe8\x6c\x04\xaf\xd4\xed\xc2\xfc\x8b\x41\x41\xc2\x97\x5b\x6f\x07\x63\x9b\x19\x94\xc9\x73\xd9\xa9\xaf\xce\x3d\x9d\x36\x58\x62\x00\x34\x98\x51\x3b\xfa\x16\x6d\x26\x29\xe3\x14\xd9\x74\x41\x66\x7b\x00\x74\x14\xe7\x39\xd7\xfe\xbf\x0f\xe3\xc3\x2c\x17\xaa\x18\x8a\x86\x83",
+ "\xf9\x47\x46\x9d\xb7\x12\xea\x26\xf2\x5f\x70\x9f\xf7\x87\x91\x36\xea\x2a\x79\xe0\xa2\xd0\xed\x5e\xe4\xad\xf0\xe1\x67\xf1\x06\xbc\x41\x0c\x93\xae\x1d\x98\x6e\xc2\x11\xe0\xfd\x9a\x40\x74\x18\x57",
+ 107 },
+ { GCRY_MD_SHA3_384,
+ "\xf3\x1e\x8b\x4f\x9e\x06\x21\xd5\x31\xd2\x2a\x38\x0b\xe5\xd9\xab\xd5\x6f\xae\xc5\x3c\xbd\x39\xb1\xfa\xb2\x30\xea\x67\x18\x44\x40\xe5\xb1\xd1\x54\x57\xbd\x25\xf5\x62\x04\xfa\x91\x7f\xa4\x8e\x66\x90\x16\xcb\x48\xc1\xff\xc1\xe1\xe4\x52\x74\xb3\xb4\x73\x79\xe0\x0a\x43\x84\x3c\xf8\x60\x1a\x55\x51\x41\x1e\xc1\x25\x03\xe5\xaa\xc4\x3d\x86\x76\xa1\xb2\x29\x7e\xc7\xa0\x80\x0d\xbf\xee\x04\x29\x2e\x93\x7f\x21\xc0\x05\xf1\x74\x11\x47\x30\x41",
+ "\x65\x98\x9b\xf4\xeb\xbf\x4c\x21\xb3\xdd\x34\x55\x1d\x3f\x61\x67\x91\x02\x36\x67\x1b\xb7\xf3\x48\xdc\x55\x2a\xdb\x80\x28\xa4\x68\xfa\x40\xef\x4a\x8c\x12\x27\xa1\xa4\x1c\x28\x10\x5e\x64\xac\x20",
+ 108 },
+ { GCRY_MD_SHA3_384,
+ "\x75\x8e\xa3\xfe\xa7\x38\x97\x3d\xb0\xb8\xbe\x7e\x59\x9b\xbe\xf4\x51\x93\x73\xd6\xe6\xdc\xd7\x19\x5e\xa8\x85\xfc\x99\x1d\x89\x67\x62\x99\x27\x59\xc2\xa0\x90\x02\x91\x2f\xb0\x8e\x0c\xb5\xb7\x6f\x49\x16\x2a\xeb\x8c\xf8\x7b\x17\x2c\xf3\xad\x19\x02\x53\xdf\x61\x2f\x77\xb1\xf0\xc5\x32\xe3\xb5\xfc\x99\xc2\xd3\x1f\x8f\x65\x01\x16\x95\xa0\x87\xa3\x5e\xe4\xee\xe5\xe3\x34\xc3\x69\xd8\xee\x5d\x29\xf6\x95\x81\x5d\x86\x6d\xa9\x9d\xf3\xf7\x94\x03",
+ "\xb7\x7a\x69\xe3\x73\xaf\x0f\x73\x3c\xda\xd3\x99\xc9\xb1\x26\x42\xa0\x46\xe1\xa7\x89\x3d\x33\x82\x94\x3a\x83\x67\xd3\x77\x40\xdf\x53\x91\x6f\x6d\xaf\x90\x51\x7b\x39\x62\x1c\x14\x34\x37\x54\xa2",
+ 109 },
+ { GCRY_MD_SHA3_384,
+ "\x47\xc6\xe0\xc2\xb7\x49\x48\x46\x59\x21\x86\x88\x04\xf0\xf7\xbd\x50\xdd\x32\x35\x83\xdc\x78\x4f\x99\x8a\x93\xcd\x1c\xa4\xc6\xef\x84\xd4\x1d\xc8\x1c\x2c\x40\xf3\x4b\x5b\xee\x6a\x93\x86\x7b\x3b\xdb\xa0\x05\x2c\x5f\x59\xe6\xf3\x65\x79\x18\xc3\x82\xe7\x71\xd3\x31\x09\x12\x2c\xc8\xbb\x0e\x1e\x53\xc4\xe3\xd1\x3b\x43\xce\x44\x97\x0f\x5e\x0c\x07\x9d\x2a\xd7\xd7\xa3\x54\x9c\xd7\x57\x60\xc2\x1b\xb1\x5b\x44\x75\x89\xe8\x6e\x8d\x76\xb1\xe9\xce\xd2",
+ "\x3d\x14\xb6\xfa\xe6\x15\x6e\x78\x76\x36\x78\x97\xa4\x92\x69\x18\x1e\xa5\x8c\xc3\xca\x96\x21\xc0\xf8\x1d\x6a\x5f\xb6\xf6\x15\x68\x0d\x90\x9b\x29\xf6\xaf\x7e\x62\xfa\xd0\x4d\x70\x04\x6b\xe9\x97",
+ 110 },
+ { GCRY_MD_SHA3_384,
+ "\xf6\x90\xa1\x32\xab\x46\xb2\x8e\xdf\xa6\x47\x92\x83\xd6\x44\x4e\x37\x1c\x64\x59\x10\x8a\xfd\x9c\x35\xdb\xd2\x35\xe0\xb6\xb6\xff\x4c\x4e\xa5\x8e\x75\x54\xbd\x00\x24\x60\x43\x3b\x21\x64\xca\x51\xe8\x68\xf7\x94\x7d\x7d\x7a\x0d\x79\x2e\x4a\xbf\x0b\xe5\xf4\x50\x85\x3c\xc4\x0d\x85\x48\x5b\x2b\x88\x57\xea\x31\xb5\xea\x6e\x4c\xcf\xa2\xf3\xa7\xef\x33\x80\x06\x6d\x7d\x89\x79\xfd\xac\x61\x8a\xad\x3d\x7e\x88\x6d\xea\x4f\x00\x5a\xe4\xad\x05\xe5\x06\x5f",
+ "\x45\x6a\xd0\x19\x08\xe1\x87\xca\x2c\xe9\xe7\xa4\xda\xed\x87\x88\xc9\x09\xe9\xbc\x97\x4e\xfd\x1c\x9a\x44\xac\x36\xdb\x9b\x6d\xa9\x85\xc9\x47\xc7\xe0\xa4\x7a\xb2\x7b\xf1\x0c\xd7\x60\xfa\x48\xaf",
+ 111 },
+ { GCRY_MD_SHA3_384,
+ "\x58\xd6\xa9\x9b\xc6\x45\x88\x24\xb2\x56\x91\x67\x70\xa8\x41\x70\x40\x72\x1c\xcc\xfd\x4b\x79\xea\xcd\x8b\x65\xa3\x76\x7c\xe5\xba\x7e\x74\x10\x4c\x98\x5a\xc5\x6b\x8c\xc9\xae\xbd\x16\xfe\xbd\x4c\xda\x5a\xdb\x13\x0b\x0f\xf2\x32\x9c\xc8\xd6\x11\xeb\x14\xda\xc2\x68\xa2\xf9\xe6\x33\xc9\x9d\xe3\x39\x97\xfe\xa4\x1c\x52\xa7\xc5\xe1\x31\x7d\x5b\x5d\xae\xd3\x5e\xba\x7d\x5a\x60\xe4\x5d\x1f\xa7\xea\xab\xc3\x5f\x5c\x2b\x0a\x0f\x23\x79\x23\x19\x53\x32\x2c\x4e",
+ "\xc2\x6b\xda\xc4\x54\xe1\xad\xc0\xd0\x90\xd0\xc5\x25\x4a\x29\x96\x66\x11\xb6\x67\x30\x14\xcb\xac\xa2\x4d\x26\xb6\xf6\x3e\xc7\xe8\xf9\x93\xba\x3d\xf7\xdf\x89\x77\x0e\x90\x2d\x5f\x65\x74\xf6\xa8",
+ 112 },
+ { GCRY_MD_SHA3_384,
+ "\xbe\xfa\xb5\x74\x39\x6d\x7f\x8b\x67\x05\xe2\xd5\xb5\x8b\x2c\x1c\x82\x0b\xb2\x4e\x3f\x4b\xae\x3e\x8f\xbc\xd3\x6d\xbf\x73\x4e\xe1\x4e\x5d\x6a\xb9\x72\xae\xdd\x35\x40\x23\x54\x66\xe8\x25\x85\x0e\xe4\xc5\x12\xea\x97\x95\xab\xfd\x33\xf3\x30\xd9\xfd\x7f\x79\xe6\x2b\xbb\x63\xa6\xea\x85\xde\x15\xbe\xae\xea\x6f\x8d\x20\x4a\x28\x95\x60\x59\xe2\x63\x2d\x11\x86\x1d\xfb\x0e\x65\xbc\x07\xac\x8a\x15\x93\x88\xd5\xc3\x27\x7e\x22\x72\x86\xf6\x5f\xf5\xe5\xb5\xae\xc1",
+ "\x1d\x85\xbf\x9a\xa2\xb6\xdc\xc3\x10\x5e\x7d\x7f\x91\x06\x9f\x01\xe4\xc9\x98\xd6\xf0\x3b\x77\x65\x0d\x75\x83\x9d\x65\xa7\xa0\x49\x19\x6f\xd9\x35\xaf\xef\xfd\xeb\x65\x7b\xc8\xf9\x6b\x7c\x17\xb5",
+ 113 },
+ { GCRY_MD_SHA3_384,
+ "\x8e\x58\x14\x4f\xa9\x17\x9d\x68\x64\x78\x62\x2c\xe4\x50\xc7\x48\x26\x0c\x95\xd1\xba\x43\xb8\xf9\xb5\x9a\xbe\xca\x8d\x93\x48\x8d\xa7\x34\x63\xef\x40\x19\x8b\x4d\x16\xfb\x0b\x07\x07\x20\x13\x47\xe0\x50\x6f\xf1\x9d\x01\xbe\xa0\xf4\x2b\x8a\xf9\xe7\x1a\x1f\x1b\xd1\x68\x78\x10\x69\xd4\xd3\x38\xfd\xef\x00\xbf\x41\x9f\xbb\x00\x30\x31\xdf\x67\x1f\x4a\x37\x97\x95\x64\xf6\x92\x82\xde\x9c\x65\x40\x78\x47\xdd\x0d\xa5\x05\xab\x16\x41\xc0\x2d\xea\x4f\x0d\x83\x49\x86",
+ "\x08\x5c\xfa\x58\x1c\xf3\xf4\xf1\x94\x16\xbe\xe3\xed\x5a\xc2\x54\x46\x62\xaa\x51\xbd\xf1\xd2\xe3\x48\xd9\xbc\xc2\x73\x43\x48\x7d\xf2\x0b\x18\xd9\xf6\xfb\x64\x56\x58\x68\x50\x4a\x68\x05\xd1\x76",
+ 114 },
+ { GCRY_MD_SHA3_384,
+ "\xb5\x5c\x10\xea\xe0\xec\x68\x4c\x16\xd1\x34\x63\xf2\x92\x91\xbf\x26\xc8\x2e\x2f\xa0\x42\x2a\x99\xc7\x1d\xb4\xaf\x14\xdd\x9c\x7f\x33\xed\xa5\x2f\xd7\x3d\x01\x7c\xc0\xf2\xdb\xe7\x34\xd8\x31\xf0\xd8\x20\xd0\x6d\x5f\x89\xda\xcc\x48\x57\x39\x14\x4f\x8c\xfd\x47\x99\x22\x3b\x1a\xff\x90\x31\xa1\x05\xcb\x6a\x02\x9b\xa7\x1e\x6e\x58\x67\xd8\x5a\x55\x49\x91\xc3\x8d\xf3\xc9\xef\x8c\x1e\x1e\x9a\x76\x30\xbe\x61\xca\xab\xca\x69\x28\x0c\x39\x9c\x1f\xb7\xa1\x2d\x12\xae\xfc",
+ "\x37\x60\x88\xf0\x90\x39\xca\xa4\x0b\xf1\x9f\xf5\xe5\xf1\x93\xfc\x9e\xcb\x61\x16\xa0\xac\xb3\x23\x7a\xaa\xb6\xcd\x80\x7b\xd7\xaf\x45\xd8\x04\xd8\x37\xa1\x8d\x2b\xd9\xa8\xc3\xda\xa3\xa1\xd1\x53",
+ 115 },
+ { GCRY_MD_SHA3_384,
+ "\x2e\xee\xa6\x93\xf5\x85\xf4\xed\x6f\x6f\x88\x65\xbb\xae\x47\xa6\x90\x8a\xec\xd7\xc4\x29\xe4\xbe\xc4\xf0\xde\x1d\x0c\xa0\x18\x3f\xa2\x01\xa0\xcb\x14\xa5\x29\xb7\xd7\xac\x0e\x6f\xf6\x60\x7a\x32\x43\xee\x9f\xb1\x1b\xcf\x3e\x23\x04\xfe\x75\xff\xcd\xdd\x6c\x5c\x2e\x2a\x4c\xd4\x5f\x63\xc9\x62\xd0\x10\x64\x50\x58\xd3\x65\x71\x40\x4a\x6d\x2b\x4f\x44\x75\x54\x34\xd7\x69\x98\xe8\x34\x09\xc3\x20\x5a\xa1\x61\x5d\xb4\x40\x57\xdb\x99\x12\x31\xd2\xcb\x42\x62\x45\x74\xf5\x45",
+ "\xcd\x40\xb3\x5f\xbd\x90\xb0\x4d\x06\x41\xf7\x10\x88\xf7\xc6\x15\x9d\x8e\xb1\x6d\xe8\xaa\xe0\x9f\x35\x58\x77\xa0\x33\x3b\x53\x15\x0b\x81\xd3\x6c\x5c\x24\x46\xbf\x5a\xc4\x62\xef\x84\xd4\xe5\x72",
+ 116 },
+ { GCRY_MD_SHA3_384,
+ "\xda\xb1\x1d\xc0\xb0\x47\xdb\x04\x20\xa5\x85\xf5\x6c\x42\xd9\x31\x75\x56\x28\x52\x42\x84\x99\xf6\x6a\x0d\xb8\x11\xfc\xdd\xda\xb2\xf7\xcd\xff\xed\x15\x43\xe5\xfb\x72\x11\x0b\x64\x68\x6b\xc7\xb6\x88\x7a\x53\x8a\xd4\x4c\x05\x0f\x1e\x42\x63\x1b\xc4\xec\x8a\x9f\x2a\x04\x71\x63\xd8\x22\xa3\x89\x89\xee\x4a\xab\x01\xb4\xc1\xf1\x61\xb0\x62\xd8\x73\xb1\xcf\xa3\x88\xfd\x30\x15\x14\xf6\x22\x24\x15\x7b\x9b\xef\x42\x3c\x77\x83\xb7\xaa\xc8\xd3\x0d\x65\xcd\x1b\xba\x8d\x68\x9c\x2d",
+ "\xdb\x14\x44\x24\x00\x59\x78\x71\xfa\x56\xd1\x0f\x53\xbe\x7b\xb4\x00\x2c\x44\x62\x4c\x44\xe8\x9c\x99\xb9\x51\x22\x67\x6a\x76\xff\x28\x84\x02\x85\x23\x9e\x2e\x4f\xbf\xb7\x51\xe4\x17\x95\x77\xd8",
+ 117 },
+ { GCRY_MD_SHA3_384,
+ "\x42\xe9\x9a\x2f\x80\xae\xe0\xe0\x01\x27\x9a\x24\x34\xf7\x31\xe0\x1d\x34\xa4\x4b\x1a\x81\x01\x72\x69\x21\xc0\x59\x0c\x30\xf3\x12\x0e\xb8\x30\x59\xf3\x25\xe8\x94\xa5\xac\x95\x9d\xca\x71\xce\x22\x14\x79\x99\x16\x42\x4e\x85\x9d\x27\xd7\x89\x43\x7b\x9d\x27\x24\x0b\xf8\xc3\x5a\xdb\xaf\xce\xcc\x32\x2b\x48\xaa\x20\x5b\x29\x39\x62\xd8\x58\x65\x2a\xba\xcb\xd5\x88\xbc\xf6\xcb\xc3\x88\xd0\x99\x3b\xd6\x22\xf9\x6e\xd5\x46\x14\xc2\x5b\x6a\x9a\xa5\x27\x58\x9e\xaa\xff\xcf\x17\xdd\xf7",
+ "\x45\x09\xad\xb6\x17\x7b\xc6\xde\xbc\xa7\xe3\x69\x48\xf0\x70\x01\x15\x9a\x57\xec\x8c\xca\x2b\x76\xc7\x70\x73\x5c\x5b\xcc\xc6\x79\xda\x6a\xb4\xe6\x4d\x91\x5d\x0e\x1a\x75\x4c\x3f\xda\x11\xb5\x24",
+ 118 },
+ { GCRY_MD_SHA3_384,
+ "\x3c\x9b\x46\x45\x0c\x0f\x2c\xae\x8e\x38\x23\xf8\xbd\xb4\x27\x7f\x31\xb7\x44\xce\x2e\xb1\x70\x54\xbd\xdc\x6d\xff\x36\xaf\x7f\x49\xfb\x8a\x23\x20\xcc\x3b\xdf\x8e\x0a\x2e\xa2\x9a\xd3\xa5\x5d\xe1\x16\x5d\x21\x9a\xde\xdd\xb5\x17\x52\x53\xe2\xd1\x48\x9e\x9b\x6f\xdd\x02\xe2\xc3\xd3\xa4\xb5\x4d\x60\xe3\xa4\x73\x34\xc3\x79\x13\xc5\x69\x53\x78\xa6\x69\xe9\xb7\x2d\xec\x32\xaf\x54\x34\xf9\x3f\x46\x17\x6e\xbf\x04\x4c\x47\x84\x46\x7c\x70\x04\x70\xd0\xc0\xb4\x0c\x8a\x08\x8c\x81\x58\x16",
+ "\x19\x3a\xf7\x1b\xdd\x22\x8a\xb3\xe8\xae\x50\xe1\xb1\xcb\xf1\x98\x4b\x0a\xf9\x2a\xac\x5a\x71\xcb\xe6\x18\xaf\xd4\x18\x7d\xed\x6b\x46\x14\x11\xa3\x9e\x72\xea\x4e\x21\x3f\xe0\xa5\x23\x1c\x49\x8d",
+ 119 },
+ { GCRY_MD_SHA3_384,
+ "\xd1\xe6\x54\xb7\x7c\xb1\x55\xf5\xc7\x79\x71\xa6\x4d\xf9\xe5\xd3\x4c\x26\xa3\xca\xd6\xc7\xf6\xb3\x00\xd3\x9d\xeb\x19\x10\x09\x46\x91\xad\xaa\x09\x5b\xe4\xba\x5d\x86\x69\x0a\x97\x64\x28\x63\x5d\x55\x26\xf3\xe9\x46\xf7\xdc\x3b\xd4\xdb\xc7\x89\x99\xe6\x53\x44\x11\x87\xa8\x1f\x9a\xdc\xd5\xa3\xc5\xf2\x54\xbc\x82\x56\xb0\x15\x8f\x54\x67\x3d\xcc\x12\x32\xf6\xe9\x18\xeb\xfc\x6c\x51\xce\x67\xea\xeb\x04\x2d\x9f\x57\xee\xc4\xbf\xe9\x10\xe1\x69\xaf\x78\xb3\xde\x48\xd1\x37\xdf\x4f\x28\x40",
+ "\x3e\x41\x95\x69\xa4\x19\x7b\xb7\x1b\xaf\x41\x6b\x38\x77\x2e\xed\xd9\xc1\xd5\xa3\x25\x21\x11\x60\x9f\x0f\xf8\xa1\x8a\x74\x9d\x5a\x56\x14\x3a\x14\x92\x5a\x82\xcd\x35\xc4\x44\x00\xa4\x9a\xfd\xfb",
+ 120 },
+ { GCRY_MD_SHA3_384,
+ "\x62\x6f\x68\xc1\x8a\x69\xa6\x59\x01\x59\xa9\xc4\x6b\xe0\x3d\x59\x65\x69\x8f\x2d\xac\x3d\xe7\x79\xb8\x78\xb3\xd9\xc4\x21\xe0\xf2\x1b\x95\x5a\x16\xc7\x15\xc1\xec\x1e\x22\xce\x3e\xb6\x45\xb8\xb4\xf2\x63\xf6\x06\x60\xea\x30\x28\x98\x1e\xeb\xd6\xc8\xc3\xa3\x67\x28\x5b\x69\x1c\x8e\xe5\x69\x44\xa7\xcd\x12\x17\x99\x7e\x1d\x9c\x21\x62\x0b\x53\x6b\xdb\xd5\xde\x89\x25\xff\x71\xde\xc6\xfb\xc0\x66\x24\xab\x6b\x21\xe3\x29\x81\x3d\xe9\x0d\x1e\x57\x2d\xfb\x89\xa1\x81\x20\xc3\xf6\x06\x35\x5d\x25",
+ "\x62\x15\xc0\x70\xd0\xcb\x38\x8a\x13\x47\x66\x03\x5c\x4b\xa9\x51\x43\xe6\x08\xd1\x5c\xaf\x74\x27\x96\x30\x4f\xfa\x1a\x62\xe5\x56\x60\xab\x9a\xb1\xf6\x53\x8b\x4a\xf1\xf3\xea\x89\xbe\x7d\x51\xff",
+ 121 },
+ { GCRY_MD_SHA3_384,
+ "\x65\x1a\x6f\xb3\xc4\xb8\x0c\x7c\x68\xc6\x01\x16\x75\xe6\x09\x4e\xb5\x6a\xbf\x5f\xc3\x05\x73\x24\xeb\xc6\x47\x78\x25\x06\x1f\x9f\x27\xe7\xa9\x46\x33\xab\xd1\xfa\x59\x8a\x74\x6e\x4a\x57\x7c\xaf\x52\x4c\x52\xec\x17\x88\x47\x1f\x92\xb8\xc3\x7f\x23\x79\x5c\xa1\x9d\x55\x9d\x44\x6c\xab\x16\xcb\xcd\xce\x90\xb7\x9f\xa1\x02\x6c\xee\x77\xbf\x4a\xb1\xb5\x03\xc5\xb9\x4c\x22\x56\xad\x75\xb3\xea\xc6\xfd\x5d\xcb\x96\xac\xa4\xb0\x3a\x83\x4b\xfb\x4e\x9a\xf9\x88\xce\xcb\xf2\xae\x59\x7c\xb9\x09\x79\x40",
+ "\x0e\x27\xab\xad\x85\x25\x5a\x66\x21\x77\x22\xb7\xd4\xe0\x32\xbf\x29\xf6\x38\xba\xe9\x65\xb9\x9f\x8e\xaf\x30\x90\x71\xff\x8c\x10\x7f\x5b\x6b\xbb\x6a\xb1\x98\x52\x28\xe6\x97\xde\x60\x59\x5d\xf6",
+ 122 },
+ { GCRY_MD_SHA3_384,
+ "\x8a\xaf\x07\x2f\xce\x8a\x2d\x96\xbc\x10\xb3\xc9\x1c\x80\x9e\xe9\x30\x72\xfb\x20\x5c\xa7\xf1\x0a\xbd\x82\xec\xd8\x2c\xf0\x40\xb1\xbc\x49\xea\x13\xd1\x85\x78\x15\xc0\xe9\x97\x81\xde\x3a\xdb\xb5\x44\x3c\xe1\xc8\x97\xe5\x51\x88\xce\xaf\x22\x1a\xa9\x68\x16\x38\xde\x05\xae\x1b\x32\x29\x38\xf4\x6b\xce\x51\x54\x3b\x57\xec\xdb\x4c\x26\x62\x72\x25\x9d\x17\x98\xde\x13\xbe\x90\xe1\x0e\xfe\xc2\xd0\x74\x84\xd9\xb2\x1a\x38\x70\xe2\xaa\x9e\x06\xc2\x1a\xa2\xd0\xc9\xcf\x42\x00\x80\xa8\x0a\x91\xde\xe1\x6f",
+ "\xab\x9f\xd5\x1b\x3a\xa4\xcd\x94\x4a\xbb\x6c\xdb\x06\x37\x08\xb2\xd1\x20\x3d\x65\xa1\xa2\xeb\xb4\x8e\x0c\x19\x72\x2a\x18\xb9\xef\x54\xd7\xa1\x1f\x76\x84\x46\x2b\x99\x5b\x6d\x38\xcd\xdc\x04\x63",
+ 123 },
+ { GCRY_MD_SHA3_384,
+ "\x53\xf9\x18\xfd\x00\xb1\x70\x1b\xd5\x04\xf8\xcd\xea\x80\x3a\xcc\xa2\x1a\xc1\x8c\x56\x4a\xb9\x0c\x2a\x17\xda\x59\x2c\x7d\x69\x68\x8f\x65\x80\x57\x53\x95\x55\x1e\x8c\xd3\x3e\x0f\xef\x08\xca\x6e\xd4\x58\x8d\x4d\x14\x0b\x3e\x44\xc0\x32\x35\x5d\xf1\xc5\x31\x56\x4d\x7f\x48\x35\x75\x33\x44\x34\x5a\x67\x81\xe1\x1c\xd5\xe0\x95\xb7\x3d\xf5\xf8\x2c\x8a\xe3\xad\x00\x87\x79\x36\x89\x66\x71\xe9\x47\xcc\x52\xe2\xb2\x9d\xcd\x46\x3d\x90\xa0\xc9\x92\x91\x28\xda\x22\x2b\x5a\x21\x14\x50\xbb\xc0\xe0\x24\x48\xe2",
+ "\x03\x94\x53\x25\xac\x50\xe5\x6b\xc8\xb5\x15\x57\x65\x29\xab\xaa\x9a\x22\xbc\x2a\x7c\xed\x91\x42\xa7\x5c\xe9\x39\xa3\x88\xaf\x00\x22\xa4\xe7\x5a\x33\x96\x4b\xbb\x35\x80\x56\x4e\x0a\xf8\x09\xd3",
+ 124 },
+ { GCRY_MD_SHA3_384,
+ "\xa6\x45\x99\xb8\xa6\x1b\x5c\xce\xc9\xe6\x7a\xed\x69\x44\x74\x59\xc8\xda\x3d\x1e\xc6\xc7\xc7\xc8\x2a\x74\x28\xb9\xb5\x84\xfa\x67\xe9\x0f\x68\xe2\xc0\x0f\xbb\xed\x46\x13\x66\x6e\x51\x68\xda\x4a\x16\xf3\x95\xf7\xa3\xc3\x83\x2b\x3b\x13\x4b\xfc\x9c\xba\xa9\x5d\x2a\x0f\xe2\x52\xf4\x4a\xc6\x68\x1e\xb6\xd4\x0a\xb9\x1c\x1d\x02\x82\xfe\xd6\x70\x1c\x57\x46\x3d\x3c\x5f\x2b\xb8\xc6\xa7\x30\x1f\xb4\x57\x6a\xa3\xb5\xf1\x55\x10\xdb\x89\x56\xff\x77\x47\x8c\x26\xa7\xc0\x9b\xea\x7b\x39\x8c\xfc\x83\x50\x3f\x53\x8e",
+ "\x59\x12\x69\x10\xa3\x46\x2e\x3b\x7a\xc2\x28\x92\xf6\x37\xd8\x7d\x90\x68\x6b\xc0\xa9\xbb\xd4\xa3\x2e\x2c\x4c\x71\xa1\x68\xba\x68\x5f\x21\x84\x56\x0e\x12\x5d\xb3\xdc\x23\xd9\x0b\x9e\x82\x0f\x1a",
+ 125 },
+ { GCRY_MD_SHA3_384,
+ "\x0e\x3a\xb0\xe0\x54\x73\x9b\x00\xcd\xb6\xa8\x7b\xd1\x2c\xae\x02\x4b\x54\xcb\x5e\x55\x0e\x6c\x42\x53\x60\xc2\xe8\x7e\x59\x40\x1f\x5e\xc2\x4e\xf0\x31\x48\x55\xf0\xf5\x6c\x47\x69\x5d\x56\xa7\xfb\x14\x17\x69\x3a\xf2\xa1\xed\x52\x91\xf2\xfe\xe9\x5f\x75\xee\xd5\x4a\x1b\x1c\x2e\x81\x22\x6f\xbf\xf6\xf6\x3a\xde\x58\x49\x11\xc7\x19\x67\xa8\xeb\x70\x93\x3b\xc3\xf5\xd1\x5b\xc9\x1b\x5c\x26\x44\xd9\x51\x6d\x3c\x3a\x8c\x15\x4e\xe4\x8e\x11\x8b\xd1\x44\x2c\x04\x3c\x7a\x0d\xba\x5a\xc5\xb1\xd5\x36\x0a\xae\x5b\x90\x65",
+ "\xd3\x23\x9a\x33\xba\xa5\x5b\x0f\x21\x16\x9e\x0f\xde\x61\x14\xb0\x81\x06\xba\xf3\xf4\xba\x0c\xa1\x9d\x7b\x5c\xf4\x40\x30\x05\x7a\xc6\x72\xce\x52\x9e\xb0\xf3\xbd\xa3\x68\x19\x96\x78\x19\xaa\xfa",
+ 126 },
+ { GCRY_MD_SHA3_384,
+ "\xa6\x2f\xc5\x95\xb4\x09\x6e\x63\x36\xe5\x3f\xcd\xfc\x8d\x1c\xc1\x75\xd7\x1d\xac\x9d\x75\x0a\x61\x33\xd2\x31\x99\xea\xac\x28\x82\x07\x94\x4c\xea\x6b\x16\xd2\x76\x31\x91\x5b\x46\x19\xf7\x43\xda\x2e\x30\xa0\xc0\x0b\xbd\xb1\xbb\xb3\x5a\xb8\x52\xef\x3b\x9a\xec\x6b\x0a\x8d\xcc\x6e\x9e\x1a\xba\xa3\xad\x62\xac\x0a\x6c\x5d\xe7\x65\xde\x2c\x37\x11\xb7\x69\xe3\xfd\xe4\x4a\x74\x01\x6f\xff\x82\xac\x46\xfa\x8f\x17\x97\xd3\xb2\xa7\x26\xb6\x96\xe3\xde\xa5\x53\x04\x39\xac\xee\x3a\x45\xc2\xa5\x1b\xc3\x2d\xd0\x55\x65\x0b",
+ "\x38\xa1\x15\x81\xd8\x74\xa5\x74\x92\x9c\x51\xf8\xdc\xc9\xe5\x01\x90\x07\x43\x86\x4a\xec\x3a\xc0\x88\x9e\x62\xc1\x07\x1c\xa5\xf8\xb6\xcc\xf9\xc0\xbd\xb3\xbb\x36\x59\x16\xeb\x43\x40\x97\x3d\xc7",
+ 127 },
+ { GCRY_MD_SHA3_384,
+ "\x2b\x6d\xb7\xce\xd8\x66\x5e\xbe\x9d\xeb\x08\x02\x95\x21\x84\x26\xbd\xaa\x7c\x6d\xa9\xad\xd2\x08\x89\x32\xcd\xff\xba\xa1\xc1\x41\x29\xbc\xcd\xd7\x0f\x36\x9e\xfb\x14\x92\x85\x85\x8d\x2b\x1d\x15\x5d\x14\xde\x2f\xdb\x68\x0a\x8b\x02\x72\x84\x05\x51\x82\xa0\xca\xe2\x75\x23\x4c\xc9\xc9\x28\x63\xc1\xb4\xab\x66\xf3\x04\xcf\x06\x21\xcd\x54\x56\x5f\x5b\xff\x46\x1d\x3b\x46\x1b\xd4\x0d\xf2\x81\x98\xe3\x73\x25\x01\xb4\x86\x0e\xad\xd5\x03\xd2\x6d\x6e\x69\x33\x8f\x4e\x04\x56\xe9\xe9\xba\xf3\xd8\x27\xae\x68\x5f\xb1\xd8\x17",
+ "\x8f\xd0\x19\x09\x38\x1e\xb7\x13\x80\x34\x19\x36\x1d\x8e\x82\xe9\x24\x76\xa0\x8e\xdc\xc2\x25\xbb\x8a\x13\x5d\x21\x5c\xb4\x8d\x07\xb0\x74\x62\x4f\xcf\x2e\x73\xe6\x66\xdb\xa5\x93\x34\x71\x98\x39",
+ 128 },
+ { GCRY_MD_SHA3_384,
+ "\x10\xdb\x50\x9b\x2c\xdc\xab\xa6\xc0\x62\xae\x33\xbe\x48\x11\x6a\x29\xeb\x18\xe3\x90\xe1\xbb\xad\xa5\xca\x0a\x27\x18\xaf\xbc\xd2\x34\x31\x44\x01\x06\x59\x48\x93\x04\x3c\xc7\xf2\x62\x52\x81\xbf\x7d\xe2\x65\x58\x80\x96\x6a\x23\x70\x5f\x0c\x51\x55\xc2\xf5\xcc\xa9\xf2\xc2\x14\x2e\x96\xd0\xa2\xe7\x63\xb7\x06\x86\xcd\x42\x1b\x5d\xb8\x12\xda\xce\xd0\xc6\xd6\x50\x35\xfd\xe5\x58\xe9\x4f\x26\xb3\xe6\xdd\xe5\xbd\x13\x98\x0c\xc8\x02\x92\xb7\x23\x01\x3b\xd0\x33\x28\x45\x84\xbf\xf2\x76\x57\x87\x1b\x0c\xf0\x7a\x84\x9f\x4a\xe2",
+ "\x5d\x7d\xc5\xfc\x9d\xe8\x8b\x1c\x0c\x46\xaa\x6d\x49\x27\x35\x05\xff\x7a\x76\xa1\x79\xe3\x1a\xb5\xd9\x76\xa6\x9d\x89\xb8\x3d\xfa\x6d\xea\xe9\xe1\xb9\x34\x40\xec\x05\x5d\xe1\xcc\x82\x4d\x6b\x15",
+ 129 },
+ { GCRY_MD_SHA3_384,
+ "\x93\x34\xde\x60\xc9\x97\xbd\xa6\x08\x61\x01\xa6\x31\x4f\x64\xe4\x45\x8f\x5f\xf9\x45\x0c\x50\x9d\xf0\x06\xe8\xc5\x47\x98\x3c\x65\x1c\xa9\x78\x79\x17\x5a\xab\xa0\xc5\x39\xe8\x2d\x05\xc1\xe0\x2c\x48\x09\x75\xcb\xb3\x01\x18\x12\x10\x61\xb1\xeb\xac\x4f\x8d\x9a\x37\x81\xe2\xdb\x6b\x18\x04\x2e\x01\xec\xf9\x01\x7a\x64\xa0\xe5\x74\x47\xec\x7f\xcb\xe6\xa7\xf8\x25\x85\xf7\x40\x3e\xe2\x22\x3d\x52\xd3\x7b\x4b\xf4\x26\x42\x86\x13\xd6\xb4\x25\x79\x80\x97\x2a\x0a\xca\xb5\x08\xa7\x62\x0c\x1c\xb2\x8e\xb4\xe9\xd3\x0f\xc4\x13\x61\xec",
+ "\x3d\x6b\xba\x14\x5d\x7e\x69\xdb\xbb\x0f\x09\x9d\x47\xa1\xf2\x13\x8d\x4a\x00\xf2\x6b\x07\xc6\x2c\xf3\x84\x71\xf0\xfb\x9c\xa0\x22\xc6\x1f\x7a\x76\x90\x13\xa9\xbd\x8d\x5d\x87\xd8\xe0\x1d\x9b\x4d",
+ 130 },
+ { GCRY_MD_SHA3_384,
+ "\xe8\x8a\xb0\x86\x89\x16\x93\xaa\x53\x5c\xeb\x20\xe6\x4c\x7a\xb9\x7c\x7d\xd3\x54\x8f\x37\x86\x33\x98\x97\xa5\xf0\xc3\x90\x31\x54\x9c\xa8\x70\x16\x6e\x47\x77\x43\xcc\xfb\xe0\x16\xb4\x42\x8d\x89\x73\x8e\x42\x6f\x5f\xfe\x81\x62\x61\x37\xf1\x7a\xec\xff\x61\xb7\x2d\xbe\xe2\xdc\x20\x96\x18\x80\xcf\xe2\x81\xdf\xab\x5e\xe3\x8b\x19\x21\x88\x14\x50\xe1\x60\x32\xde\x5e\x4d\x55\xad\x8d\x4f\xca\x60\x97\x21\xb0\x69\x2b\xac\x79\xbe\x5a\x06\xe1\x77\xfe\x8c\x80\xc0\xc8\x35\x19\xfb\x33\x47\xde\x9f\x43\xd5\x56\x1c\xb8\x10\x7b\x9b\x5e\xdc",
+ "\xfb\xce\xf8\x0d\xd0\x6e\x7e\x0b\x3b\x7a\x54\x85\xca\x5b\xc2\xb3\x88\xcb\x91\xa2\x89\x0f\x18\x1c\x85\x7b\x3e\x0a\xbe\xfd\x60\x65\x49\x9d\x82\xdd\x55\xf3\xfc\xd1\x7e\x35\x1c\x0a\x36\x36\xb8\x59",
+ 131 },
+ { GCRY_MD_SHA3_384,
+ "\xfd\x19\xe0\x1a\x83\xeb\x6e\xc8\x10\xb9\x45\x82\xcb\x8f\xbf\xa2\xfc\xb9\x92\xb5\x36\x84\xfb\x74\x8d\x22\x64\xf0\x20\xd3\xb9\x60\xcb\x1d\x6b\x8c\x34\x8c\x2b\x54\xa9\xfc\xea\x72\x33\x0c\x2a\xaa\x9a\x24\xec\xdb\x00\xc4\x36\xab\xc7\x02\x36\x1a\x82\xbb\x88\x28\xb8\x53\x69\xb8\xc7\x2e\xce\x00\x82\xfe\x06\x55\x71\x63\x89\x9c\x2a\x0e\xfa\x46\x6c\x33\xc0\x43\x43\xa8\x39\x41\x70\x57\x39\x9a\x63\xa3\x92\x9b\xe1\xee\x48\x05\xd6\xce\x3e\x5d\x0d\x09\x67\xfe\x90\x04\x69\x6a\x56\x63\xf4\xca\xc9\x17\x90\x06\xa2\xce\xb7\x55\x42\xd7\x5d\x68",
+ "\x33\x8a\xac\xba\xc8\xac\x5b\xcc\x13\xfa\xfc\x0e\xc6\xd2\xec\xf4\xa8\x71\xf9\xb0\x9d\x7b\x1b\xc5\xbd\x6f\x8d\x7c\x9d\xd1\x35\x4b\x8e\x28\xc6\x81\x58\xa3\x65\x51\xdd\xda\xb8\xb6\x84\x57\x9e\xe1",
+ 132 },
+ { GCRY_MD_SHA3_384,
+ "\x59\xae\x20\xb6\xf7\xe0\xb3\xc7\xa9\x89\xaf\xb2\x83\x24\xa4\x0f\xca\x25\xd8\x65\x1c\xf1\xf4\x6a\xe3\x83\xef\x6d\x84\x41\x58\x7a\xa1\xc0\x4c\x3e\x3b\xf8\x8e\x81\x31\xce\x61\x45\xcf\xb8\x97\x3d\x96\x1e\x84\x32\xb2\x02\xfa\x5a\xf3\xe0\x9d\x62\x5f\xaa\xd8\x25\xbc\x19\xda\x9b\x5c\x6c\x20\xd0\x2a\xbd\xa2\xfc\xc5\x8b\x5b\xd3\xfe\x50\x7b\xf2\x01\x26\x3f\x30\x54\x38\x19\x51\x0c\x12\xbc\x23\xe2\xdd\xb4\xf7\x11\xd0\x87\xa8\x6e\xdb\x1b\x35\x53\x13\x36\x3a\x2d\xe9\x96\xb8\x91\x02\x5e\x14\x70\x36\x08\x74\x01\xcc\xf3\xca\x78\x15\xbf\x3c\x49",
+ "\xff\xc9\x8d\x84\xc2\x68\xbd\x09\xca\xd0\x9c\xd7\xb4\xbf\x9d\x35\xed\xe9\x7e\xc5\x58\x85\xe8\x39\xe5\x57\xd2\x1e\xcc\x0e\x28\xa8\x55\x00\x03\x86\xe6\x8f\xaa\xe3\xe6\x4a\x19\xb4\x43\xb2\x58\x7d",
+ 133 },
+ { GCRY_MD_SHA3_384,
+ "\x77\xee\x80\x4b\x9f\x32\x95\xab\x23\x62\x79\x8b\x72\xb0\xa1\xb2\xd3\x29\x1d\xce\xb8\x13\x98\x96\x35\x58\x30\xf3\x4b\x3b\x32\x85\x61\x53\x1f\x80\x79\xb7\x9a\x6e\x99\x80\x70\x51\x50\x86\x64\x02\xfd\xc1\x76\xc0\x58\x97\xe3\x59\xa6\xcb\x1a\x7a\xb0\x67\x38\x3e\xb4\x97\x18\x2a\x7e\x5a\xef\x70\x38\xe4\xc9\x6d\x13\x3b\x27\x82\x91\x74\x17\xe3\x91\x53\x5b\x5e\x1b\x51\xf4\x7d\x8e\xd7\xe4\xd4\x02\x5f\xe9\x8d\xc8\x7b\x9c\x16\x22\x61\x4b\xff\x3d\x10\x29\xe6\x8e\x37\x2d\xe7\x19\x80\x38\x57\xca\x52\x06\x7c\xdd\xaa\xd9\x58\x95\x1c\xb2\x06\x8c\xc6",
+ "\x47\x14\x65\x89\x0c\x3b\x9c\x03\xed\xfb\xf0\xf6\x88\x3d\x56\x57\x40\xba\xda\x3b\x76\x28\xad\x6a\x27\xf7\x29\xc3\x5c\x1a\x86\x66\x95\x3e\x8b\x99\xd2\xc8\x9e\xde\x0b\xd2\xd5\xd7\x0f\xde\xf1\x1b",
+ 134 },
+ { GCRY_MD_SHA3_384,
+ "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+ "\x0f\x8b\xa7\x21\x4d\xe0\xe3\xa9\xe1\x3c\x28\x2b\xfa\x09\xce\xa7\x82\xc3\x1c\x05\x2f\x51\x6d\x0a\xaa\x40\x3d\x97\x71\x6e\x0d\x08\xb1\xf7\xf9\xbb\x40\x85\xb5\x55\x74\x0c\x81\x3c\x4e\xce\x1b\x90",
+ 135 },
+ { GCRY_MD_SHA3_384,
+ "\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",
+ "\xca\xd2\xd2\x8f\xbd\xcc\x3a\x5d\x71\xfb\x3a\xdc\xee\xc5\x23\x13\xad\x41\xd4\xff\x1f\x91\x5c\xaa\x34\xee\x12\x78\x39\xdb\xf2\xe9\xa7\xb0\x6e\x1c\x4e\xcd\x62\x55\x92\x6c\x16\xc0\x6e\x51\xef\xd0",
+ 136 },
+ { GCRY_MD_SHA3_384,
+ "\x04\x41\x0e\x31\x08\x2a\x47\x58\x4b\x40\x6f\x05\x13\x98\xa6\xab\xe7\x4e\x4d\xa5\x9b\xb6\xf8\x5e\x6b\x49\xe8\xa1\xf7\xf2\xca\x00\xdf\xba\x54\x62\xc2\xcd\x2b\xfd\xe8\xb6\x4f\xb2\x1d\x70\xc0\x83\xf1\x13\x18\xb5\x6a\x52\xd0\x3b\x81\xca\xc5\xee\xc2\x9e\xb3\x1b\xd0\x07\x8b\x61\x56\x78\x6d\xa3\xd6\xd8\xc3\x30\x98\xc5\xc4\x7b\xb6\x7a\xc6\x4d\xb1\x41\x65\xaf\x65\xb4\x45\x44\xd8\x06\xdd\xe5\xf4\x87\xd5\x37\x3c\x7f\x97\x92\xc2\x99\xe9\x68\x6b\x7e\x58\x21\xe7\xc8\xe2\x45\x83\x15\xb9\x96\xb5\x67\x7d\x92\x6d\xac\x57\xb3\xf2\x2d\xa8\x73\xc6\x01\x01\x6a\x0d",
+ "\x5b\x19\x2e\xba\xb4\x72\x15\xa8\xe9\xfb\x8e\x4d\x56\x1b\x22\x0b\x1d\xc3\x67\x07\xa3\xf0\x85\xf7\xbb\x01\x75\x33\x5c\x39\x32\x51\xe3\x46\x7f\x94\x55\x70\x42\x0c\x74\x33\x65\xd0\xf0\x9b\x9e\x09",
+ 137 },
+ { GCRY_MD_SHA3_384,
+ "\x8b\x81\xe9\xba\xdd\xe0\x26\xf1\x4d\x95\xc0\x19\x97\x70\x24\xc9\xe1\x3d\xb7\xa5\xcd\x21\xf9\xe9\xfc\x49\x1d\x71\x61\x64\xbb\xac\xdc\x70\x60\xd8\x82\x61\x5d\x41\x14\x38\xae\xa0\x56\xc3\x40\xcd\xf9\x77\x78\x8f\x6e\x17\xd1\x18\xde\x55\x02\x68\x55\xf9\x32\x70\x47\x2d\x1f\xd1\x8b\x9e\x7e\x81\x2b\xae\x10\x7e\x0d\xfd\xe7\x06\x33\x01\xb7\x1f\x6c\xfe\x4e\x22\x5c\xab\x3b\x23\x29\x05\xa5\x6e\x99\x4f\x08\xee\x28\x91\xba\x92\x2d\x49\xc3\xda\xfe\xb7\x5f\x7c\x69\x75\x0c\xb6\x7d\x82\x2c\x96\x17\x6c\x46\xbd\x8a\x29\xf1\x70\x13\x73\xfb\x09\xa1\xa6\xe3\xc7\x15\x8f",
+ "\xdf\x6f\x80\xb6\xd5\x6c\xff\xa8\x54\x5a\x27\xa2\x45\xa5\x0e\x6c\x2d\x11\x7f\xc3\x59\x8f\x46\x5b\x6c\xd7\x85\x60\xf4\xb3\xc7\xd2\x12\x3f\x28\xf6\x7c\xa9\xe6\x5b\xfe\x0b\x7f\x56\x6c\x57\xb9\xef",
+ 138 },
+ { GCRY_MD_SHA3_384,
+ "\xfa\x6e\xed\x24\xda\x66\x66\xa2\x22\x08\x14\x6b\x19\xa5\x32\xc2\xec\x9b\xa9\x4f\x09\xf1\xde\xf1\xe7\xfc\x13\xc3\x99\xa4\x8e\x41\xac\xc2\xa5\x89\xd0\x99\x27\x62\x96\x34\x8f\x39\x62\x53\xb5\x7c\xb0\xe4\x02\x91\xbd\x28\x27\x73\x65\x6b\x6e\x0d\x8b\xea\x1c\xda\x08\x4a\x37\x38\x81\x6a\x84\x04\x85\xfc\xf3\xfb\x30\x7f\x77\x7f\xa5\xfe\xac\x48\x69\x5c\x2a\xf4\x76\x97\x20\x25\x8c\x77\x94\x3f\xb4\x55\x6c\x36\x2d\x9c\xba\x8b\xf1\x03\xae\xb9\x03\x4b\xaa\x8e\xa8\xbf\xb9\xc4\xf8\xe6\x74\x2c\xe0\xd5\x2c\x49\xea\x8e\x97\x4f\x33\x96\x12\xe8\x30\xe9\xe7\xa9\xc2\x90\x65",
+ "\xce\x97\xe9\xdf\x08\x78\x9d\x84\x15\x1a\x95\xc8\x13\x4f\x0d\xb7\x4e\x5d\x4e\x07\x6e\x0c\x15\x96\x68\x25\xc3\x71\xb7\x9b\x31\x92\xfd\x7c\x9c\x6b\xda\xe8\x6b\x77\x58\x04\xb5\x36\x3d\x11\x52\xc7",
+ 139 },
+ { GCRY_MD_SHA3_384,
+ "\x9b\xb4\xaf\x1b\x4f\x09\xc0\x71\xce\x3c\xaf\xa9\x2e\x4e\xb7\x3c\xe8\xa6\xf5\xd8\x2a\x85\x73\x34\x40\x36\x8d\xee\x4e\xb1\xcb\xc7\xb5\x5a\xc1\x50\x77\x3b\x6f\xe4\x7d\xbe\x03\x6c\x45\x58\x2e\xd6\x7e\x23\xf4\xc7\x45\x85\xda\xb5\x09\xdf\x1b\x83\x61\x05\x64\x54\x56\x42\xb2\xb1\xec\x46\x3e\x18\x04\x8f\xc2\x34\x77\xc6\xb2\xaa\x03\x55\x94\xec\xd3\x37\x91\xaf\x6a\xf4\xcb\xc2\xa1\x16\x6a\xba\x8d\x62\x8c\x57\xe7\x07\xf0\xb0\xe8\x70\x7c\xaf\x91\xcd\x44\xbd\xb9\x15\xe0\x29\x6e\x01\x90\xd5\x6d\x33\xd8\xdd\xe1\x0b\x5b\x60\x37\x78\x38\x97\x3c\x1d\x94\x3c\x22\xed\x33\x5e",
+ "\x89\xbf\x88\x9f\xbd\x7a\x38\x42\x90\xd3\xb1\xd5\x27\x09\xdb\xa6\x86\x35\x1e\x53\x93\x76\x30\xb7\xc7\xf0\x1b\xcd\xda\x19\xb1\x51\x7d\x31\x7d\x65\xe7\x99\xe6\x86\xc7\x1a\x0a\xb4\xd6\x5b\x60\xb8",
+ 140 },
+ { GCRY_MD_SHA3_384,
+ "\x21\x67\xf0\x21\x18\xcc\x62\x04\x3e\x90\x91\xa6\x47\xca\xdb\xed\x95\x61\x1a\x52\x1f\xe0\xd6\x4e\x85\x18\xf1\x6c\x80\x8a\xb2\x97\x72\x55\x98\xae\x29\x68\x80\xa7\x73\x60\x7a\x79\x8f\x7c\x3c\xfc\xe8\x0d\x25\x1e\xbe\xc6\x88\x50\x15\xf9\xab\xf7\xea\xab\xae\x46\x79\x8f\x82\xcb\x59\x26\xde\x5c\x23\xf4\x4a\x3f\x9f\x95\x34\xb3\xc6\xf4\x05\xb5\x36\x4c\x2f\x8a\x8b\xdc\x5c\xa4\x9c\x74\x9b\xed\x8c\xe4\xba\x48\x89\x70\x62\xae\x84\x24\xca\x6d\xde\x5f\x55\xc0\xe4\x2a\x95\xd1\xe2\x92\xca\x54\xfb\x46\xa8\x4f\xbc\x9c\xd8\x7f\x2d\x0c\x9e\x74\x48\xde\x30\x43\xae\x22\xfd\xd2\x29",
+ "\x5d\x40\xe3\x92\xc2\xe5\xb2\x9c\x80\xc2\xd7\x60\xa9\x3a\xa1\xe1\x93\x47\x2d\x7e\xe5\x9e\x20\x3d\xd4\x78\xfe\x24\xc5\xa6\x26\x4e\x28\x73\xaf\x31\xab\xde\x81\x82\x78\x62\x90\x1a\xe5\x95\x71\xbb",
+ 141 },
+ { GCRY_MD_SHA3_384,
+ "\x94\xb7\xfa\x0b\xc1\xc4\x4e\x94\x9b\x1d\x76\x17\xd3\x1b\x47\x20\xcb\xe7\xca\x57\xc6\xfa\x4f\x40\x94\xd4\x76\x15\x67\xe3\x89\xec\xc6\x4f\x69\x68\xe4\x06\x4d\xf7\x0d\xf8\x36\xa4\x7d\x0c\x71\x33\x36\xb5\x02\x8b\x35\x93\x0d\x29\xeb\x7a\x7f\x9a\x5a\xf9\xad\x5c\xf4\x41\x74\x5b\xae\xc9\xbb\x01\x4c\xee\xff\x5a\x41\xba\x5c\x1c\xe0\x85\xfe\xb9\x80\xba\xb9\xcf\x79\xf2\x15\x8e\x03\xef\x7e\x63\xe2\x9c\x38\xd7\x81\x6a\x84\xd4\xf7\x1e\x0f\x54\x8b\x7f\xc3\x16\x08\x5a\xe3\x8a\x06\x0f\xf9\xb8\xde\xc3\x6f\x91\xad\x9e\xbc\x0a\x5b\x6c\x33\x8c\xbb\x8f\x66\x59\xd3\x42\xa2\x43\x68\xcf",
+ "\x7c\x63\xa0\xdc\x1c\x39\xcf\x4f\xab\x2d\x22\xf6\x2c\x1b\x00\x75\x7a\xa4\xb8\x9e\xd0\xd7\x12\x8d\xa2\x43\xd9\x08\x2a\xd0\xc7\x87\x84\xac\x24\xdf\x34\xf5\xab\x30\x37\x5f\x1d\x58\x1e\x74\x20\xbd",
+ 142 },
+ { GCRY_MD_SHA3_384,
+ "\xea\x40\xe8\x3c\xb1\x8b\x3a\x24\x2c\x1e\xcc\x6c\xcd\x0b\x78\x53\xa4\x39\xda\xb2\xc5\x69\xcf\xc6\xdc\x38\xa1\x9f\x5c\x90\xac\xbf\x76\xae\xf9\xea\x37\x42\xff\x3b\x54\xef\x7d\x36\xeb\x7c\xe4\xff\x1c\x9a\xb3\xbc\x11\x9c\xff\x6b\xe9\x3c\x03\xe2\x08\x78\x33\x35\xc0\xab\x81\x37\xbe\x5b\x10\xcd\xc6\x6f\xf3\xf8\x9a\x1b\xdd\xc6\xa1\xee\xd7\x4f\x50\x4c\xbe\x72\x90\x69\x0b\xb2\x95\xa8\x72\xb9\xe3\xfe\x2c\xee\x9e\x6c\x67\xc4\x1d\xb8\xef\xd7\xd8\x63\xcf\x10\xf8\x40\xfe\x61\x8e\x79\x36\xda\x3d\xca\x5c\xa6\xdf\x93\x3f\x24\xf6\x95\x4b\xa0\x80\x1a\x12\x94\xcd\x8d\x7e\x66\xdf\xaf\xec",
+ "\xed\x08\x5d\x83\x0a\xfd\x2d\x8f\x79\x62\x72\x81\xc2\xa8\x16\x3c\x39\x1f\xec\x2c\x58\x26\x8f\x66\xf7\x4c\xff\x97\x51\xbb\x29\xe0\xd0\x71\xea\x8f\xd2\xfc\xf9\x43\x02\x0d\x0a\xd7\x58\x28\x1b\xfd",
+ 143 },
+ { GCRY_MD_SHA3_384,
+ "\x15\x7d\x5b\x7e\x45\x07\xf6\x6d\x9a\x26\x74\x76\xd3\x38\x31\xe7\xbb\x76\x8d\x4d\x04\xcc\x34\x38\xda\x12\xf9\x01\x02\x63\xea\x5f\xca\xfb\xde\x25\x79\xdb\x2f\x6b\x58\xf9\x11\xd5\x93\xd5\xf7\x9f\xb0\x5f\xe3\x59\x6e\x3f\xa8\x0f\xf2\xf7\x61\xd1\xb0\xe5\x70\x80\x05\x5c\x11\x8c\x53\xe5\x3c\xdb\x63\x05\x52\x61\xd7\xc9\xb2\xb3\x9b\xd9\x0a\xcc\x32\x52\x0c\xbb\xdb\xda\x2c\x4f\xd8\x85\x6d\xbc\xee\x17\x31\x32\xa2\x67\x91\x98\xda\xf8\x30\x07\xa9\xb5\xc5\x15\x11\xae\x49\x76\x6c\x79\x2a\x29\x52\x03\x88\x44\x4e\xbe\xfe\x28\x25\x6f\xb3\x3d\x42\x60\x43\x9c\xba\x73\xa9\x47\x9e\xe0\x0c\x63",
+ "\x29\x12\x47\x52\xcc\xd4\xac\x72\x4a\x9c\x3d\x53\xb0\xb3\x52\xaf\x2d\xbd\x76\x72\x9f\x8c\x5c\x64\x8b\x1e\x9d\x77\x81\x9f\x32\xe2\xa7\xde\x0e\x15\x28\x64\x78\xa2\x4d\xf9\xbb\x37\x0f\x85\x5c\x1c",
+ 144 },
+ { GCRY_MD_SHA3_384,
+ "\x83\x6b\x34\xb5\x15\x47\x6f\x61\x3f\xe4\x47\xa4\xe0\xc3\xf3\xb8\xf2\x09\x10\xac\x89\xa3\x97\x70\x55\xc9\x60\xd2\xd5\xd2\xb7\x2b\xd8\xac\xc7\x15\xa9\x03\x53\x21\xb8\x67\x03\xa4\x11\xdd\xe0\x46\x6d\x58\xa5\x97\x69\x67\x2a\xa6\x0a\xd5\x87\xb8\x48\x1d\xe4\xbb\xa5\x52\xa1\x64\x57\x79\x78\x95\x01\xec\x53\xd5\x40\xb9\x04\x82\x1f\x32\xb0\xbd\x18\x55\xb0\x4e\x48\x48\xf9\xf8\xcf\xe9\xeb\xd8\x91\x1b\xe9\x57\x81\xa7\x59\xd7\xad\x97\x24\xa7\x10\x2d\xbe\x57\x67\x76\xb7\xc6\x32\xbc\x39\xb9\xb5\xe1\x90\x57\xe2\x26\x55\x2a\x59\x94\xc1\xdb\xb3\xb5\xc7\x87\x1a\x11\xf5\x53\x70\x11\x04\x4c\x53",
+ "\xfa\xea\xb5\x68\x7f\x39\xec\x98\x94\xc5\xcc\xff\xb5\x7e\x82\xa8\x4b\xbb\x7d\x49\x3c\xc6\xaf\xc0\x3d\x07\xac\x7b\x4f\x18\x1e\x61\x63\x9b\x9a\x47\x71\xc9\x99\x85\xed\x7f\xa1\x77\x3e\x1c\xa3\xf4",
+ 145 },
+ { GCRY_MD_SHA3_384,
+ "\xcc\x77\x84\xa4\x91\x2a\x7a\xb5\xad\x36\x20\xaa\xb2\x9b\xa8\x70\x77\xcd\x3c\xb8\x36\x36\xad\xc9\xf3\xdc\x94\xf5\x1e\xdf\x52\x1b\x21\x61\xef\x10\x8f\x21\xa0\xa2\x98\x55\x79\x81\xc0\xe5\x3c\xe6\xce\xd4\x5b\xdf\x78\x2c\x1e\xf2\x00\xd2\x9b\xab\x81\xdd\x64\x60\x58\x69\x64\xed\xab\x7c\xeb\xdb\xbe\xc7\x5f\xd7\x92\x50\x60\xf7\xda\x2b\x85\x3b\x2b\x08\x95\x88\xfa\x0f\x8c\x16\xec\x64\x98\xb1\x4c\x55\xdc\xee\x33\x5c\xb3\xa9\x1d\x69\x8e\x4d\x39\x3a\xb8\xe8\xea\xc0\x82\x5f\x8a\xde\xbe\xee\x19\x6d\xf4\x12\x05\xc0\x11\x67\x4e\x53\x42\x6c\xaa\x45\x3f\x8d\xe1\xcb\xb5\x79\x32\xb0\xb7\x41\xd4\xc6",
+ "\xe4\xe3\x52\xb1\xd2\xd9\x87\xa3\x7c\x83\x16\x29\xfe\x0c\x6a\xb9\xea\xb2\xc3\x5e\x40\x1d\x1b\x5f\x44\x3a\xdc\x54\xa9\x6e\xf3\xc9\x1d\x08\x76\xcc\xf4\x6a\xde\xf8\x19\xc4\x60\x36\x91\x36\xda\x87",
+ 146 },
+ { GCRY_MD_SHA3_384,
+ "\x76\x39\xb4\x61\xff\xf2\x70\xb2\x45\x5a\xc1\xd1\xaf\xce\x78\x29\x44\xae\xa5\xe9\x08\x7e\xb4\xa3\x9e\xb9\x6b\xb5\xc3\xba\xaf\x0e\x86\x8c\x85\x26\xd3\x40\x4f\x94\x05\xe7\x9e\x77\xbf\xac\x5f\xfb\x89\xbf\x19\x57\xb5\x23\xe1\x7d\x34\x1d\x73\x23\xc3\x02\xea\x70\x83\x87\x2d\xd5\xe8\x70\x56\x94\xac\xdd\xa3\x6d\x5a\x1b\x89\x5a\xaa\x16\xec\xa6\x10\x4c\x82\x68\x85\x32\xc8\xbf\xe1\x79\x0b\x5d\xc9\xf4\xec\x5f\xe9\x5b\xae\xd3\x7e\x1d\x28\x7b\xe7\x10\x43\x1f\x1e\x5e\x8e\xe1\x05\xbc\x42\xed\x37\xd7\x4b\x1e\x55\x98\x4b\xf1\xc0\x9f\xe6\xa1\xfa\x13\xef\x3b\x96\xfa\xea\xed\x6a\x2a\x19\x50\xa1\x21\x53",
+ "\x6c\x28\x8f\xe4\xa7\x4f\x0e\xd1\xb3\x6d\x12\xf2\xdb\x69\x7f\xbc\x44\x01\x7b\xb5\x7d\x38\xc9\xeb\xd4\x5f\x5a\x8b\x4f\xeb\x59\x14\x80\x60\xae\x4b\xa1\xff\xa1\x62\xe1\x0e\x69\x16\xce\xa1\xa7\x94",
+ 147 },
+ { GCRY_MD_SHA3_384,
+ "\xeb\x65\x13\xfc\x61\xb3\x0c\xfb\xa5\x8d\x4d\x7e\x80\xf9\x4d\x14\x58\x90\x90\xcf\x1d\x80\xb1\xdf\x2e\x68\x08\x8d\xc6\x10\x49\x59\xba\x0d\x58\x3d\x58\x5e\x95\x78\xab\x0a\xec\x0c\xf3\x6c\x48\x43\x5e\xb5\x2e\xd9\xab\x4b\xbc\xe7\xa5\xab\xe6\x79\xc9\x7a\xe2\xdb\xe3\x5e\x8c\xc1\xd4\x5b\x06\xdd\xa3\xcf\x41\x86\x65\xc5\x7c\xbe\xe4\xbb\xb4\x7f\xa4\xca\xf7\x8f\x4e\xe6\x56\xfe\xc2\x37\xfe\x4e\xeb\xba\xfa\x20\x6e\x1e\xf2\xbd\x0e\xe4\xae\x71\xbd\x0e\x9b\x2f\x54\xf9\x1d\xaa\xdf\x1f\xeb\xfd\x70\x32\x38\x1d\x63\x6b\x73\x3d\xcb\x3b\xf7\x6f\xb1\x4e\x23\xaf\xf1\xf6\x8e\xd3\xdb\xcf\x75\xc9\xb9\x9c\x6f\x26",
+ "\xe1\xb6\xda\xc3\xf1\x38\xb5\xf3\x36\xf1\xf7\x58\x94\xf8\x25\xff\xc1\x97\x83\x6c\x92\xbf\x35\x9b\x55\xbb\x2a\x78\x23\x9f\x24\xf9\xc4\xaa\x1e\x06\x3c\x9c\x2b\x27\x3b\x9c\xfa\x76\x6f\xbf\xba\xe5",
+ 148 },
+ { GCRY_MD_SHA3_384,
+ "\x15\x94\xd7\x4b\xf5\xdd\xe4\x44\x26\x5d\x4c\x04\xda\xd9\x72\x1f\xf3\xe3\x4c\xbf\x62\x2d\xaf\x34\x1f\xe1\x6b\x96\x43\x1f\x6c\x4d\xf1\xf7\x60\xd3\x4f\x29\x6e\xb9\x7d\x98\xd5\x60\xad\x52\x86\xfe\xc4\xdc\xe1\x72\x4f\x20\xb5\x4f\xd7\xdf\x51\xd4\xbf\x13\x7a\xdd\x65\x6c\x80\x54\x6f\xb1\xbf\x51\x6d\x62\xee\x82\xba\xa9\x92\x91\x0e\xf4\xcc\x18\xb7\x0f\x3f\x86\x98\x27\x6f\xcf\xb4\x4e\x0e\xc5\x46\xc2\xc3\x9c\xfd\x8e\xe9\x10\x34\xff\x93\x03\x05\x8b\x42\x52\x46\x2f\x86\xc8\x23\xeb\x15\xbf\x48\x1e\x6b\x79\xcc\x3a\x02\x21\x85\x95\xb3\x65\x8e\x8b\x37\x38\x2b\xd5\x04\x8e\xae\xd5\xfd\x02\xc3\x79\x44\xe7\x3b",
+ "\x6e\x07\xb5\x9e\x93\xb2\x24\x75\x63\x3b\x5b\xa1\xaa\x68\x91\x11\x9c\xff\x69\x06\x97\xac\x67\x9e\x93\x49\xe8\x69\x4c\x65\x40\x74\xd9\x65\xf0\xc3\x2f\xf5\x17\xb1\x0e\xe8\xf6\x99\x3f\x6e\x46\x46",
+ 149 },
+ { GCRY_MD_SHA3_384,
+ "\x4c\xfa\x12\x78\x90\x30\x26\xf6\x6f\xed\xd4\x13\x74\x55\x8b\xe1\xb5\x85\xd0\x3c\x5c\x55\xda\xc9\x43\x61\xdf\x28\x6d\x4b\xd3\x9c\x7c\xb8\x03\x7e\xd3\xb2\x67\xb0\x7c\x34\x66\x26\x44\x9d\x0c\xc5\xb0\xdd\x2c\xf2\x21\xf7\xe4\xc3\x44\x9a\x4b\xe9\x99\x85\xd2\xd5\xe6\x7b\xff\x29\x23\x35\x7d\xde\xab\x5a\xbc\xb4\x61\x9f\x3a\x3a\x57\xb2\xcf\x92\x8a\x02\x2e\xb2\x76\x76\xc6\xcf\x80\x56\x89\x00\x4f\xca\x4d\x41\xea\x6c\x2d\x0a\x47\x89\xc7\x60\x5f\x7b\xb8\x38\xdd\x88\x3b\x3a\xd3\xe6\x02\x7e\x77\x5b\xcf\x26\x28\x81\x42\x80\x99\xc7\xff\xf9\x5b\x14\xc0\x95\xea\x13\x0e\x0b\x99\x38\xa5\xe2\x2f\xc5\x26\x50\xf5\x91",
+ "\x19\xeb\x2e\x15\x26\x2a\x83\x95\x38\x84\x6f\x72\x52\x67\x69\x71\x20\x79\x13\x27\x9b\x9a\xe9\xb6\xba\x36\x50\xd8\xf3\xa8\xe5\x58\xb1\x3c\x35\xb3\x1f\x1a\xb7\x42\x9e\x37\x62\x55\x33\x8c\x4a\xa2",
+ 150 },
+ { GCRY_MD_SHA3_384,
+ "\xd3\xe6\x5c\xb9\x2c\xfa\x79\x66\x2f\x6a\xf4\x93\xd6\x96\xa0\x7c\xcf\x32\xaa\xad\xcc\xef\xf0\x6e\x73\xe8\xd9\xf6\xf9\x09\x20\x9e\x66\x71\x5d\x6e\x97\x87\x88\xc4\x9e\xfb\x90\x87\xb1\x70\xec\xf3\xaa\x86\xd2\xd4\xd1\xa0\x65\xae\x0e\xfc\x89\x24\xf3\x65\xd6\x76\xb3\xcb\x9e\x2b\xec\x91\x8f\xd9\x6d\x0b\x43\xde\xe8\x37\x27\xc9\xa9\x3b\xf5\x6c\xa2\xb2\xe5\x9a\xdb\xa8\x56\x96\x54\x6a\x81\x50\x67\xfc\x7a\x78\x03\x96\x29\xd4\x94\x8d\x15\x7e\x7b\x0d\x82\x6d\x1b\xf8\xe8\x12\x37\xba\xb7\x32\x13\x12\xfd\xaa\x4d\x52\x17\x44\xf9\x88\xdb\x6f\xdf\x04\x54\x9d\x0f\xdc\xa3\x93\xd6\x39\xc7\x29\xaf\x71\x6e\x9c\x8b\xba\x48",
+ "\xf4\xda\x80\xb2\x6f\xb5\xe6\xf7\xe5\xdf\xe4\x71\x28\xee\xe0\x95\xd4\x6d\x9a\xce\xfb\xe7\x6f\x74\xef\xbc\x8a\x1a\xd6\x8e\x84\x56\x63\x4e\x93\x76\x02\x56\x48\xef\x7a\x33\x50\x29\x9f\x36\x6e\x29",
+ 151 },
+ { GCRY_MD_SHA3_384,
+ "\x84\x2c\xc5\x83\x50\x45\x39\x62\x2d\x7f\x71\xe7\xe3\x18\x63\xa2\xb8\x85\xc5\x6a\x0b\xa6\x2d\xb4\xc2\xa3\xf2\xfd\x12\xe7\x96\x60\xdc\x72\x05\xca\x29\xa0\xdc\x0a\x87\xdb\x4d\xc6\x2e\xe4\x7a\x41\xdb\x36\xb9\xdd\xb3\x29\x3b\x9a\xc4\xba\xae\x7d\xf5\xc6\xe7\x20\x1e\x17\xf7\x17\xab\x56\xe1\x2c\xad\x47\x6b\xe4\x96\x08\xad\x2d\x50\x30\x9e\x7d\x48\xd2\xd8\xde\x4f\xa5\x8a\xc3\xcf\xea\xfe\xee\x48\xc0\xa9\xee\xc8\x84\x98\xe3\xef\xc5\x1f\x54\xd3\x00\xd8\x28\xdd\xdc\xcb\x9d\x0b\x06\xdd\x02\x1a\x29\xcf\x5c\xb5\xb2\x50\x69\x15\xbe\xb8\xa1\x19\x98\xb8\xb8\x86\xe0\xf9\xb7\xa8\x0e\x97\xd9\x1a\x7d\x01\x27\x0f\x9a\x77\x17",
+ "\xbd\xba\x78\x38\xa1\xe7\xa6\x01\xd5\x59\xf4\x9e\xc1\x32\x3b\x7c\x5f\xab\xe1\xe1\x09\xfd\xca\xff\x3f\x78\x65\xf9\xaf\x41\x96\xab\xbf\x60\xac\x12\x30\x97\xa7\xb8\x60\xfe\x43\x86\x84\x35\x5e\xb0",
+ 152 },
+ { GCRY_MD_SHA3_384,
+ "\x6c\x4b\x0a\x07\x19\x57\x3e\x57\x24\x86\x61\xe9\x8f\xeb\xe3\x26\x57\x1f\x9a\x1c\xa8\x13\xd3\x63\x85\x31\xae\x28\xb4\x86\x0f\x23\xc3\xa3\xa8\xac\x1c\x25\x00\x34\xa6\x60\xe2\xd7\x1e\x16\xd3\xac\xc4\xbf\x9c\xe2\x15\xc6\xf1\x5b\x1c\x0f\xc7\xe7\x7d\x3d\x27\x15\x7e\x66\xda\x9c\xee\xc9\x25\x8f\x8f\x2b\xf9\xe0\x2b\x4a\xc9\x37\x93\xdd\x6e\x29\xe3\x07\xed\xe3\x69\x5a\x0d\xf6\x3c\xbd\xc0\xfc\x66\xfb\x77\x08\x13\xeb\x14\x9c\xa2\xa9\x16\x91\x1b\xee\x49\x02\xc4\x7c\x78\x02\xe6\x9e\x40\x5f\xe3\xc0\x4c\xeb\x55\x22\x79\x2a\x55\x03\xfa\x82\x9f\x70\x72\x72\x22\x66\x21\xf7\xc4\x88\xa7\x69\x8c\x0d\x69\xaa\x56\x1b\xe9\xf3\x78",
+ "\x96\xdf\xe9\x99\x6b\xff\xa5\xe5\xd8\x3c\x39\xb1\x1f\x47\xf1\x2d\x11\x21\x0f\x7d\x43\x00\xb7\x18\x0d\x18\x91\xea\xaa\x7f\xe4\x80\x9f\x94\x89\xb1\xe2\x40\x7f\xf8\x7f\xb2\x62\x8d\xdf\x1f\xc0\x20",
+ 153 },
+ { GCRY_MD_SHA3_384,
+ "\x51\xb7\xdb\xb7\xce\x2f\xfe\xb4\x27\xa9\x1c\xcf\xe5\x21\x8f\xd4\x0f\x9e\x0b\x7e\x24\x75\x6d\x4c\x47\xcd\x55\x60\x60\x08\xbd\xc2\x7d\x16\x40\x09\x33\x90\x6f\xd9\xf3\x0e\xff\xdd\x48\x80\x02\x2d\x08\x11\x55\x34\x2a\xf3\xfb\x6c\xd5\x36\x72\xab\x7f\xb5\xb3\xa3\xbc\xbe\x47\xbe\x1f\xd3\xa2\x27\x8c\xae\x8a\x5f\xd6\x1c\x14\x33\xf7\xd3\x50\x67\x5d\xd2\x18\x03\x74\x6c\xad\xca\x57\x41\x30\xf0\x12\x00\x02\x4c\x63\x40\xab\x0c\xc2\xcf\x74\xf2\x23\x46\x69\xf3\x4e\x90\x09\xef\x2e\xb9\x48\x23\xd6\x2b\x31\x40\x7f\x4b\xa4\x6f\x1a\x1e\xec\x41\x64\x1e\x84\xd7\x77\x27\xb5\x9e\x74\x6b\x8a\x67\x1b\xef\x93\x6f\x05\xbe\x82\x07\x59\xfa",
+ "\x79\xcf\x2a\x30\x17\xf8\x26\x93\xc0\xa5\x31\xa3\x67\x18\x6d\x05\x5f\xce\x63\x08\x1e\xdf\x98\x0c\x6a\x0b\x96\x7b\x6e\xcc\xe7\x5d\x63\x5b\x98\x48\x5e\x9b\x6b\x28\x5b\x08\x33\x6f\xf3\x4e\x61\xc9",
+ 154 },
+ { GCRY_MD_SHA3_384,
+ "\x83\x59\x9d\x93\xf5\x56\x1e\x82\x1b\xd0\x1a\x47\x23\x86\xbc\x2f\xf4\xef\xbd\x4a\xed\x60\xd5\x82\x1e\x84\xaa\xe7\x4d\x80\x71\x02\x98\x10\xf5\xe2\x86\xf8\xf1\x76\x51\xcd\x27\xda\x07\xb1\xeb\x43\x82\xf7\x54\xcd\x1c\x95\x26\x87\x83\xad\x09\x22\x0f\x55\x02\x84\x03\x70\xd4\x94\xbe\xb1\x71\x24\x22\x0f\x6a\xfc\xe9\x1e\xc8\xa0\xf5\x52\x31\xf9\x65\x24\x33\xe5\xce\x34\x89\xb7\x27\x71\x6c\xf4\xae\xba\x7d\xcd\xa2\x0c\xd2\x9a\xa9\xa8\x59\x20\x12\x53\xf9\x48\xdd\x94\x39\x5a\xba\x9e\x38\x52\xbd\x1d\x60\xdd\xa7\xae\x5d\xc0\x45\xb2\x83\xda\x00\x6e\x1c\xba\xd8\x3c\xc1\x32\x92\xa3\x15\xdb\x55\x53\x30\x5c\x62\x8d\xd0\x91\x14\x65\x97",
+ "\x0e\xd3\xca\x16\x20\xce\x3a\x92\x3a\x22\xe9\xd1\x3b\xbf\x75\x43\xac\xee\x05\xf6\x6b\x67\xe6\xd6\xf4\x35\xbc\x51\x3f\x46\x98\x94\x9c\x27\x52\x80\x68\xf8\x92\xf0\x87\x19\x16\xfe\x2d\x04\x33\xc3",
+ 155 },
+ { GCRY_MD_SHA3_384,
+ "\x2b\xe9\xbf\x52\x6c\x9d\x5a\x75\xd5\x65\xdd\x11\xef\x63\xb9\x79\xd0\x68\x65\x9c\x7f\x02\x6c\x08\xbe\xa4\xaf\x16\x1d\x85\xa4\x62\xd8\x0e\x45\x04\x0e\x91\xf4\x16\x5c\x07\x4c\x43\xac\x66\x13\x80\x31\x1a\x8c\xbe\xd5\x9c\xc8\xe4\xc4\x51\x8e\x80\xcd\x2c\x78\xab\x1c\xab\xf6\x6b\xff\x83\xea\xb3\xa8\x01\x48\x55\x03\x07\x31\x09\x50\xd0\x34\xa6\x28\x6c\x93\xa1\xec\xe8\x92\x9e\x63\x85\xc5\xe3\xbb\x6e\xa8\xa7\xc0\xfb\x6d\x63\x32\xe3\x20\xe7\x1c\xc4\xeb\x46\x2a\x2a\x62\xe2\xbf\xe0\x8f\x0c\xca\xd9\x3e\x61\xbe\xdb\x5d\xd0\xb7\x86\xa7\x28\xab\x66\x6f\x07\xe0\x57\x6d\x18\x9c\x92\xbf\x9f\xb2\x0d\xca\x49\xac\x2d\x39\x56\xd4\x73\x85\xe2",
+ "\x69\xa2\x7b\xbf\x08\x0e\x01\x55\x92\x89\x3d\x3b\x55\xd1\x95\x7d\x26\x77\x84\x56\x99\x23\xa4\x66\x16\x5a\x6f\xb1\x29\x61\x3d\x8e\xa6\xf6\x10\xf3\x76\x0e\x34\x9d\x46\xb0\x92\x77\xcb\x85\x45\x46",
+ 156 },
+ { GCRY_MD_SHA3_384,
+ "\xca\x76\xd3\xa1\x25\x95\xa8\x17\x68\x26\x17\x00\x68\x48\x67\x55\x47\xd3\xe8\xf5\x0c\x22\x10\xf9\xaf\x90\x6c\x0e\x7c\xe5\x0b\x44\x60\x18\x6f\xe7\x04\x57\xa9\xe8\x79\xe7\x9f\xd4\xd1\xa6\x88\xc7\x0a\x34\x73\x61\xc8\x47\xba\x0d\xd6\xaa\x52\x93\x6e\xaf\x8e\x58\xa1\xbe\x2f\x5c\x1c\x70\x4e\x20\x14\x6d\x36\x6a\xeb\x38\x53\xbe\xd9\xde\x9b\xef\xe9\x56\x9a\xc8\xaa\xea\x37\xa9\xfb\x71\x39\xa1\xa1\xa7\xd5\xc7\x48\x60\x5a\x8d\xef\xb2\x97\x86\x9e\xbe\xdd\x71\xd6\x15\xa5\xda\x23\x49\x6d\x11\xe1\x1a\xbb\xb1\x26\xb2\x06\xfa\x0a\x77\x97\xee\x7d\xe1\x17\x98\x60\x12\xd0\x36\x2d\xce\xf7\x75\xc2\xfe\x14\x5a\xda\x6b\xda\x1c\xcb\x32\x6b\xf6\x44",
+ "\xe9\xc8\x83\x01\x40\x62\x96\x69\xa1\xdc\x5c\x8e\xe2\x7b\xe6\x69\xb7\x12\x2f\x4d\xc8\x82\x24\x63\x5c\xde\x33\x4a\xd9\x96\x15\xf3\xfd\xc4\x86\x9e\x56\x26\x3e\x3c\x7f\x44\x20\x73\x6f\x71\x4e\x26",
+ 157 },
+ { GCRY_MD_SHA3_384,
+ "\xf7\x6b\x85\xdc\x67\x42\x10\x25\xd6\x4e\x93\x09\x6d\x1d\x71\x2b\x7b\xaf\x7f\xb0\x01\x71\x6f\x02\xd3\x3b\x21\x60\xc2\xc8\x82\xc3\x10\xef\x13\xa5\x76\xb1\xc2\xd3\x0e\xf8\xf7\x8e\xf8\xd2\xf4\x65\x00\x71\x09\xaa\xd9\x3f\x74\xcb\x9e\x7d\x7b\xef\x7c\x95\x90\xe8\xaf\x3b\x26\x7c\x89\xc1\x5d\xb2\x38\x13\x8c\x45\x83\x3c\x98\xcc\x4a\x47\x1a\x78\x02\x72\x3e\xf4\xc7\x44\xa8\x53\xcf\x80\xa0\xc2\x56\x8d\xd4\xed\x58\xa2\xc9\x64\x48\x06\xf4\x21\x04\xce\xe5\x36\x28\xe5\xbd\xf7\xb6\x3b\x0b\x33\x8e\x93\x1e\x31\xb8\x7c\x24\xb1\x46\xc6\xd0\x40\x60\x55\x67\xce\xef\x59\x60\xdf\x9e\x02\x2c\xb4\x69\xd4\xc7\x87\xf4\xcb\xa3\xc5\x44\xa1\xac\x91\xf9\x5f",
+ "\x4d\xf0\x60\x27\x61\x05\xbf\x00\x2f\x8e\x9f\x3f\x08\xd5\xb5\x1f\x7c\x2a\xdf\xe5\xaa\xb9\xa1\xa6\x83\xc0\x53\xe0\x45\xc8\x9a\x88\x30\x28\xb1\x09\x34\x61\x36\x82\x62\xea\x85\xf5\x23\x9a\xc7\xb1",
+ 158 },
+ { GCRY_MD_SHA3_384,
+ "\x25\xb8\xc9\xc0\x32\xea\x6b\xcd\x73\x3f\xfc\x87\x18\xfb\xb2\xa5\x03\xa4\xea\x8f\x71\xde\xa1\x17\x61\x89\xf6\x94\x30\x4f\x0f\xf6\x8e\x86\x2a\x81\x97\xb8\x39\x95\x75\x49\xef\x24\x3a\x52\x79\xfc\x26\x46\xbd\x4c\x00\x9b\x6d\x1e\xde\xbf\x24\x73\x81\x97\xab\xb4\xc9\x92\xf6\xb1\xdc\x9b\xa8\x91\xf5\x70\x87\x9a\xcc\xd5\xa6\xb1\x86\x91\xa9\x3c\x7d\x0a\x8d\x38\xf9\x5b\x63\x9c\x1d\xae\xb4\x8c\x4c\x2f\x15\xcc\xf5\xb9\xd5\x08\xf8\x33\x3c\x32\xde\x78\x78\x1b\x41\x85\x0f\x26\x1b\x85\x5c\x4b\xeb\xcc\x12\x5a\x38\x0c\x54\xd5\x01\xc5\xd3\xbd\x07\xe6\xb5\x21\x02\x11\x60\x88\xe5\x3d\x76\x58\x3b\x01\x61\xe2\xa5\x8d\x07\x78\xf0\x91\x20\x6a\xab\xd5\xa1",
+ "\x81\x6a\xa6\xdb\x9b\x66\x32\x88\xe5\xf9\x32\xf0\xfe\xaf\xf0\xee\x78\x75\xc3\xb3\xe6\xfb\xac\x0c\xdd\xc4\x58\xbd\x64\x63\x71\x96\x9c\xf5\x0d\x2d\x09\x42\xfc\xc7\x40\x35\x73\xb0\x1b\x05\xb4\x55",
+ 159 },
+ { GCRY_MD_SHA3_384,
+ "\x21\xcf\xdc\x2a\x7c\xcb\x7f\x33\x1b\x3d\x2e\xef\xff\x37\xe4\x8a\xd9\xfa\x9c\x78\x8c\x3f\x3c\x20\x0e\x01\x73\xd9\x99\x63\xe1\xcb\xca\x93\x62\x3b\x26\x4e\x92\x03\x94\xae\x48\xbb\x4c\x3a\x5b\xb9\x6f\xfb\xc8\xf0\xe5\x3f\x30\xe2\x29\x56\xad\xab\xc2\x76\x5f\x57\xfb\x76\x1e\x14\x7e\xcb\xf8\x56\x75\x33\xdb\x6e\x50\xc8\xa1\xf8\x94\x31\x0a\x94\xed\xf8\x06\xdd\x8c\xa6\xa0\xe1\x41\xc0\xfa\x7c\x9f\xae\x6c\x6a\xe6\x5f\x18\xc9\x3a\x85\x29\xe6\xe5\xb5\x53\xbf\x55\xf2\x5b\xe2\xe8\x0a\x98\x82\xbd\x37\xf1\x45\xfe\xcb\xeb\x3d\x44\x7a\x3c\x4e\x46\xc2\x15\x24\xcc\x55\xcd\xd6\x2f\x52\x1a\xb9\x2a\x8b\xa7\x2b\x89\x79\x96\xc4\x9b\xb2\x73\x19\x8b\x7b\x1c\x9e",
+ "\x12\x5b\x51\xc2\x53\x39\x16\x77\xc5\x9c\x03\x32\xc6\xa1\x3d\x07\xde\x55\xea\xb8\x08\x57\x59\x3f\x08\x39\xa5\x6f\xa6\x78\xc5\xe2\xf7\xcb\x2f\x93\x4a\xbe\x5e\x58\x87\x80\x4a\xab\x5d\x8f\x13\xe1",
+ 160 },
+ { GCRY_MD_SHA3_384,
+ "\x4e\x45\x2b\xa4\x21\x27\xdc\xc9\x56\xef\x4f\x8f\x35\xdd\x68\xcb\x22\x5f\xb7\x3b\x5b\xc7\xe1\xec\x5a\x89\x8b\xba\x29\x31\x56\x3e\x74\xfa\xff\x3b\x67\x31\x4f\x24\x1e\xc4\x9f\x4a\x70\x61\xe3\xbd\x02\x13\xae\x82\x6b\xab\x38\x0f\x1f\x14\xfa\xab\x8b\x0e\xfd\xdd\x5f\xd1\xbb\x49\x37\x38\x53\xa0\x8f\x30\x55\x3d\x5a\x55\xcc\xbb\xb8\x15\x3d\xe4\x70\x4f\x29\xca\x2b\xde\xef\x04\x19\x46\x8e\x05\xdd\x51\x55\x7c\xcc\x80\xc0\xa9\x61\x90\xbb\xcc\x4d\x77\xec\xff\x21\xc6\x6b\xdf\x48\x64\x59\xd4\x27\xf9\x86\x41\x0f\x88\x3a\x80\xa5\xbc\xc3\x2c\x20\xf0\x47\x8b\xb9\xa9\x7a\x12\x6f\xc5\xf9\x54\x51\xe4\x0f\x29\x2a\x46\x14\x93\x0d\x05\x4c\x85\x1a\xcd\x01\x9c\xcf",
+ "\x13\x0c\x4b\x06\xa5\x5f\x11\xc8\x0c\x41\x60\x8a\xdf\xd7\xb4\xce\x87\x95\x87\x1b\xcf\x16\x90\x0f\x20\xd2\x75\x1e\x12\x3b\x41\xd3\xb2\x04\x8f\xd0\x52\x67\xc2\xf9\x65\x3e\xce\x36\x30\xbd\xd3\x30",
+ 161 },
+ { GCRY_MD_SHA3_384,
+ "\xfa\x85\x67\x1d\xf7\xda\xdf\x99\xa6\xff\xee\x97\xa3\xab\x99\x91\x67\x1f\x56\x29\x19\x50\x49\x88\x04\x97\x48\x78\x67\xa6\xc4\x46\xb6\x00\x87\xfa\xc9\xa0\xf2\xfc\xc8\xe3\xb2\x4e\x97\xe4\x23\x45\xb9\x3b\x5f\x7d\x36\x91\x82\x9d\x3f\x8c\xcd\x4b\xb3\x64\x11\xb8\x5f\xc2\x32\x8e\xb0\xc5\x1c\xb3\x15\x1f\x70\x86\x0a\xd3\x24\x6c\xe0\x62\x3a\x8d\xc8\xb3\xc4\x9f\x95\x8f\x86\x90\xf8\xe3\x86\x0e\x71\xeb\x2b\x14\x79\xa5\xce\xa0\xb3\xf8\xbe\xfd\x87\xac\xaf\x53\x62\x43\x5e\xae\xcc\xb5\x2f\x38\x61\x7b\xc6\xc5\xc2\xc6\xe2\x69\xea\xd1\xfb\xd6\x9e\x94\x1d\x4a\xd2\x01\x2d\xa2\xc5\xb2\x1b\xcf\xbf\x98\xe4\xa7\x7a\xb2\xaf\x1f\x3f\xda\x32\x33\xf0\x46\xd3\x8f\x1d\xc8",
+ "\x3e\xa0\xfa\x3f\xc0\x35\xea\x40\xcb\xbe\x9a\x3c\x1c\x6f\x7e\x5a\x43\x7b\xa2\x0f\x26\x73\x6f\x28\x95\xf8\x1d\x53\xbe\xc9\x2a\x18\x6e\x74\x76\x29\x10\xc4\xaa\x62\x56\x53\x73\xd3\x8b\x28\xd5\xfd",
+ 162 },
+ { GCRY_MD_SHA3_384,
+ "\xe9\x08\x47\xae\x67\x97\xfb\xc0\xb6\xb3\x6d\x6e\x58\x8c\x0a\x74\x3d\x72\x57\x88\xca\x50\xb6\xd7\x92\x35\x2e\xa8\x29\x4f\x5b\xa6\x54\xa1\x53\x66\xb8\xe1\xb2\x88\xd8\x4f\x51\x78\x24\x08\x27\x97\x5a\x76\x3b\xc4\x5c\x7b\x04\x30\xe8\xa5\x59\xdf\x44\x88\x50\x5e\x00\x9c\x63\xda\x99\x4f\x14\x03\xf4\x07\x95\x82\x03\xce\xbb\x6e\x37\xd8\x9c\x94\xa5\xea\xcf\x60\x39\xa3\x27\xf6\xc4\xdb\xbc\x7a\x2a\x30\x7d\x97\x6a\xa3\x9e\x41\xaf\x65\x37\x24\x3f\xc2\x18\xdf\xa6\xab\x4d\xd8\x17\xb6\xa3\x97\xdf\x5c\xa6\x91\x07\xa9\x19\x87\x99\xed\x24\x86\x41\xb6\x3b\x42\xcb\x4c\x29\xbf\xdd\x79\x75\xac\x96\xed\xfc\x27\x4a\xc5\x62\xd0\x47\x4c\x60\x34\x7a\x07\x8c\xe4\xc2\x5e\x88",
+ "\x7c\x1f\x1a\x46\xe4\x09\x04\x6b\x5a\x31\x47\x67\xe8\xb7\xe7\xb1\xd9\xa9\x29\x31\x44\x3c\x5d\x02\xa5\x81\x37\x1b\x38\x0a\xfa\x18\x67\xe5\x54\xc3\xf7\xdf\x2e\x45\x57\xac\xfd\x9f\x8e\x23\x0c\x44",
+ 163 },
+ { GCRY_MD_SHA3_384,
+ "\xf6\xd5\xc2\xb6\xc9\x39\x54\xfc\x62\x76\x02\xc0\x0c\x4c\xa9\xa7\xd3\xed\x12\xb2\x71\x73\xf0\xb2\xc9\xb0\xe4\xa5\x93\x93\x98\xa6\x65\xe6\x7e\x69\xd0\xb1\x2f\xb7\xe4\xce\xb2\x53\xe8\x08\x3d\x1c\xeb\x72\x4a\xc0\x7f\x00\x9f\x09\x4e\x42\xf2\xd6\xf2\x12\x94\x89\xe8\x46\xea\xff\x07\x00\xa8\xd4\x45\x3e\xf4\x53\xa3\xed\xdc\x18\xf4\x08\xc7\x7a\x83\x27\x56\x17\xfa\xbc\x4e\xa3\xa2\x83\x3a\xa7\x34\x06\xc0\xe9\x66\x27\x60\x79\xd3\x8e\x8e\x38\x53\x9a\x70\xe1\x94\xcc\x55\x13\xaa\xa4\x57\xc6\x99\x38\x3f\xd1\x90\x0b\x1e\x72\xbd\xfb\x83\x5d\x1f\xd3\x21\xb3\x7b\xa8\x05\x49\xb0\x78\xa4\x9e\xa0\x81\x52\x86\x9a\x91\x8c\xa5\x7f\x5b\x54\xed\x71\xe4\xfd\x3a\xc5\xc0\x67\x29",
+ "\x2a\xd2\x38\x17\x00\x2c\x8f\x00\x89\xd4\x23\x76\x0f\x55\x69\xeb\x67\xcb\xee\xd2\xf0\xf2\xaa\x12\xf8\xed\xe7\x85\x6e\xe2\x2a\xa6\xeb\x68\x4f\x86\xae\x91\x74\x1a\x4a\xa3\xc8\x0a\xc9\x7c\x4a\x0b",
+ 164 },
+ { GCRY_MD_SHA3_384,
+ "\xcf\x85\x62\xb1\xbe\xd8\x98\x92\xd6\x7d\xda\xaf\x3d\xee\xb2\x82\x46\x45\x6e\x97\x23\x26\xdb\xcd\xb5\xcf\x3f\xb2\x89\xac\xa0\x1e\x68\xda\x5d\x59\x89\x6e\x3a\x61\x65\x35\x8b\x07\x1b\x30\x4d\x6a\xb3\xd0\x18\x94\x4b\xe5\x04\x9d\x5e\x0e\x2b\xb8\x19\xac\xf6\x7a\x60\x06\x11\x10\x89\xe6\x76\x71\x32\xd7\x2d\xd8\x5b\xed\xdc\xbb\x2d\x64\x49\x6d\xb0\xcc\x92\x95\x5a\xb4\xc6\x23\x4f\x1e\xea\x24\xf2\xd5\x14\x83\xf2\xe2\x09\xe4\x58\x9b\xf9\x51\x9f\xac\x51\xb4\xd0\x61\xe8\x01\x12\x5e\x60\x5f\x80\x93\xbb\x69\x97\xbc\x16\x3d\x55\x15\x96\xfe\x4a\xb7\xcf\xae\x8f\xb9\xa9\x0f\x69\x80\x48\x0c\xe0\xc2\x29\xfd\x16\x75\x40\x9b\xd7\x88\x35\x4d\xaf\x31\x62\x40\xcf\xe0\xaf\x93\xeb",
+ "\xd3\x49\x74\x75\x9c\x6a\x4a\xa9\xd1\xa4\xed\x3d\xe3\x41\xa2\xba\x02\x2d\xf1\x27\xbe\x92\xeb\x0b\xbc\x19\x00\xeb\x5a\xc7\xb8\xaf\xe9\x09\xb5\x2d\xa5\x71\x46\x68\xc3\xc4\xb7\xdb\x93\x9f\x24\x36",
+ 165 },
+ { GCRY_MD_SHA3_384,
+ "\x2a\xce\x31\xab\xb0\xa2\xe3\x26\x79\x44\xd2\xf7\x5e\x15\x59\x98\x5d\xb7\x35\x4c\x6e\x60\x5f\x18\xdc\x84\x70\x42\x3f\xca\x30\xb7\x33\x1d\x9b\x33\xc4\xa4\x32\x67\x83\xd1\xca\xae\x1b\x4f\x07\x06\x0e\xff\x97\x8e\x47\x46\xbf\x0c\x7e\x30\xcd\x61\x04\x0b\xd5\xec\x27\x46\xb2\x98\x63\xeb\x7f\x10\x3e\xbd\xa6\x14\xc4\x29\x1a\x80\x5b\x6a\x4c\x82\x14\x23\x05\x64\xa0\x55\x7b\xc7\x10\x2e\x0b\xd3\xed\x23\x71\x92\x52\xf7\x43\x5d\x64\xd2\x10\xee\x2a\xaf\xc5\x85\xbe\x90\x3f\xa4\x1e\x19\x68\xc5\x0f\xd5\xd5\x36\x79\x26\xdf\x7a\x05\xe3\xa4\x2c\xf0\x7e\x65\x6f\xf9\x2d\xe7\x3b\x03\x6c\xf8\xb1\x98\x98\xc0\xcb\x34\x55\x7c\x0c\x12\xc2\xd8\xb8\x4e\x91\x18\x1a\xf4\x67\xbc\x75\xa9\xd1",
+ "\x0f\xb3\x8a\xe2\x33\x52\x0d\x4f\x57\x46\x94\x63\xe1\xe6\x8d\x55\x18\xea\x4e\x96\x57\x55\xc0\x3a\xd4\x58\xdd\x28\x5a\xfb\x2d\xf5\x18\xc3\xd3\x89\xbd\x36\x1c\xbd\xce\x46\xb6\x54\x63\x1a\x18\xc2",
+ 166 },
+ { GCRY_MD_SHA3_384,
+ "\x0d\x8d\x09\xae\xd1\x9f\x10\x13\x96\x9c\xe5\xe7\xeb\x92\xf8\x3a\x20\x9a\xe7\x6b\xe3\x1c\x75\x48\x44\xea\x91\x16\xce\xb3\x9a\x22\xeb\xb6\x00\x30\x17\xbb\xcf\x26\x55\x5f\xa6\x62\x41\x85\x18\x7d\xb8\xf0\xcb\x35\x64\xb8\xb1\xc0\x6b\xf6\x85\xd4\x7f\x32\x86\xed\xa2\x0b\x83\x35\x8f\x59\x9d\x20\x44\xbb\xf0\x58\x3f\xab\x8d\x78\xf8\x54\xfe\x0a\x59\x61\x83\x23\x0c\x5e\xf8\xe5\x44\x26\x75\x0e\xaf\x2c\xc4\xe2\x9d\x3b\xdd\x03\x7e\x73\x4d\x86\x3c\x2b\xd9\x78\x9b\x4c\x24\x30\x96\x13\x8f\x76\x72\xc2\x32\x31\x4e\xff\xdf\xc6\x51\x34\x27\xe2\xda\x76\x91\x6b\x52\x48\x93\x3b\xe3\x12\xeb\x5d\xde\x4c\xf7\x08\x04\xfb\x25\x8a\xc5\xfb\x82\xd5\x8d\x08\x17\x7a\xc6\xf4\x75\x60\x17\xff\xf5",
+ "\xcb\x8f\x1c\xc9\xeb\x72\x46\x51\x76\xb9\x7b\x62\x26\xa8\x7e\x69\xd7\x7c\x65\x19\x01\x14\xcc\xe1\xf8\x30\xa3\xdf\xef\xa5\xa8\xa2\x78\xd5\xcf\x59\x4b\x17\x3a\xc5\x8c\x06\xec\x74\x95\x8f\xf8\xc6",
+ 167 },
+ { GCRY_MD_SHA3_384,
+ "\xc3\x23\x6b\x73\xde\xb7\x66\x2b\xf3\xf3\xda\xa5\x8f\x13\x7b\x35\x8b\xa6\x10\x56\x0e\xf7\x45\x57\x85\xa9\xbe\xfd\xb0\x35\xa0\x66\xe9\x07\x04\xf9\x29\xbd\x96\x89\xce\xf0\xce\x3b\xda\x5a\xcf\x44\x80\xbc\xeb\x8d\x09\xd1\x0b\x09\x8a\xd8\x50\x0d\x9b\x60\x71\xdf\xc3\xa1\x4a\xf6\xc7\x75\x11\xd8\x1e\x3a\xa8\x84\x49\x86\xc3\xbe\xa6\xf4\x69\xf9\xe0\x21\x94\xc9\x28\x68\xcd\x5f\x51\x64\x62\x56\x79\x8f\xf0\x42\x49\x54\xc1\x43\x4b\xdf\xed\x9f\xac\xb3\x90\xb0\x7d\x34\x2e\x99\x29\x36\xe0\xf8\x8b\xfd\x0e\x88\x4a\x0d\xdb\x67\x9d\x05\x47\xcc\xde\xc6\x38\x42\x85\xa4\x54\x29\xd1\x15\xac\x7d\x23\x5a\x71\x72\x42\x02\x1d\x1d\xc3\x56\x41\xf5\xf0\xa4\x8e\x84\x45\xdb\xa5\x8e\x6c\xb2\xc8\xea",
+ "\x87\x77\x6d\x70\x22\xdc\x18\x59\x2b\x57\x8c\x53\x4e\x2f\xcf\x57\x94\x6e\x0f\x74\xc4\x7d\xf8\x56\x12\xf8\x9c\x65\x93\xfd\x50\xa9\xe4\x45\xc0\x48\xd6\xcd\xa9\xa1\xd1\xd1\x0e\xa3\xb3\xc9\x73\xd0",
+ 168 },
+ { GCRY_MD_SHA3_384,
+ "\xb3\x9f\xeb\x82\x83\xea\xdc\x63\xe8\x18\x4b\x51\xdf\x5a\xe3\xfd\x41\xaa\xc8\xa9\x63\xbb\x0b\xe1\xcd\x08\xaa\x58\x67\xd8\xd9\x10\xc6\x69\x22\x1e\x73\x24\x33\x60\x64\x6f\x65\x53\xd1\xca\x05\xa8\x4e\x8d\xc0\xde\x05\xb6\x41\x9e\xc3\x49\xca\x99\x44\x80\x19\x3d\x01\xc9\x25\x25\xf3\xfb\x3d\xce\xfb\x08\xaf\xc6\xd2\x69\x47\xbd\xbb\xfd\x85\x19\x3f\x53\xb5\x06\x09\xc6\x14\x09\x05\xc5\x3a\x66\x86\xb5\x8e\x53\xa3\x19\xa5\x7b\x96\x23\x31\xed\xe9\x81\x49\xaf\x3d\xe3\x11\x8a\x81\x9d\xa4\xd7\x67\x06\xa0\x42\x4b\x4e\x1d\x29\x10\xb0\xed\x26\xaf\x61\xd1\x50\xeb\xcb\x46\x59\x5d\x42\x66\xa0\xbd\x7f\x65\x1b\xa4\x7d\x0c\x7f\x17\x9c\xa2\x85\x45\x00\x7d\x92\xe8\x41\x9d\x48\xfd\xfb\xd7\x44\xce",
+ "\x83\xf4\x44\x21\x47\xfe\xfc\x8e\x5b\xad\x3e\x9e\xe4\xc6\x66\x1a\x77\x1a\xe8\xc8\x74\x58\xab\x67\x15\x3d\xec\xd3\x5d\xaf\x67\x56\xee\xf2\x8e\x4a\xe7\x2e\x65\xeb\xfa\xe0\x88\x86\xa6\xe7\x73\xe0",
+ 169 },
+ { GCRY_MD_SHA3_384,
+ "\xa9\x83\xd5\x4f\x50\x38\x03\xe8\xc7\x99\x9f\x4e\xdb\xbe\x82\xe9\x08\x4f\x42\x21\x43\xa9\x32\xdd\xdd\xc4\x7a\x17\xb0\xb7\x56\x4a\x7f\x37\xa9\x9d\x07\x86\xe9\x94\x76\x42\x8d\x29\xe2\x9d\x3c\x19\x7a\x72\xbf\xab\x13\x42\xc1\x2a\x0f\xc4\x78\x7f\xd7\x01\x7d\x7a\x61\x74\x04\x9e\xa4\x3b\x57\x79\x16\x9e\xf7\x47\x2b\xdb\xbd\x94\x1d\xcb\x82\xfc\x73\xaa\xc4\x5a\x8a\x94\xc9\xf2\xbd\x34\x77\xf6\x1f\xd3\xb7\x96\xf0\x2a\x1b\x82\x64\xa2\x14\xc6\xfe\xa7\x4b\x70\x51\xb2\x26\xc7\x22\x09\x9e\xc7\x88\x3a\x46\x2b\x83\xb6\xaf\xdd\x40\x09\x24\x8b\x8a\x23\x7f\x60\x5f\xe5\xa0\x8f\xe7\xd8\xb4\x53\x21\x42\x1e\xbb\xa6\x7b\xd7\x0a\x0b\x00\xdd\xbf\x94\xba\xab\x7f\x35\x9d\x5d\x1e\xea\x10\x5f\x28\xdc\xfb",
+ "\x51\x35\x81\x59\x07\x4d\x96\x0c\x0b\x9d\x73\xd5\xf1\x2a\xfd\xaf\xb8\xf5\xd7\x90\x5b\xda\x62\x37\x9a\x6e\x0d\x67\x27\xd0\x3e\xfd\x26\xee\xa5\x1b\x43\x43\x68\xe2\xe5\x66\xcb\x47\x47\xd0\xba\x35",
+ 170 },
+ { GCRY_MD_SHA3_384,
+ "\xe4\xd1\xc1\x89\x7a\x0a\x86\x6c\xe5\x64\x63\x5b\x74\x22\x2f\x96\x96\xbf\x2c\x7f\x64\x0d\xd7\x8d\x7e\x2a\xca\x66\xe1\xb6\x1c\x64\x2b\xb0\x3e\xa7\x53\x6a\xae\x59\x78\x11\xe9\xbf\x4a\x7b\x45\x3e\xde\x31\xf9\x7b\x46\xa5\xf0\xef\x51\xa0\x71\xa2\xb3\x91\x8d\xf1\x6b\x15\x25\x19\xae\x37\x76\xf9\xf1\xed\xab\x4c\x2a\x37\x7c\x32\x92\xe9\x64\x08\x35\x9d\x36\x13\x84\x4d\x5e\xb3\x93\x00\x02\x83\xd5\xad\x34\x01\xa3\x18\xb1\x2f\xd1\x47\x4b\x86\x12\xf2\xbb\x50\xfb\x6a\x8b\x9e\x02\x3a\x54\xd7\xdd\xe2\x8c\x43\xd6\xd8\x85\x4c\x8d\x9d\x11\x55\x93\x5c\x19\x98\x11\xdb\xfc\x87\xe9\xe0\x07\x2e\x90\xeb\x88\x68\x1c\xc7\x52\x97\x14\xf8\xfb\x8a\x2c\x9d\x88\x56\x7a\xdf\xb9\x74\xee\x20\x5a\x9b\xf7\xb8\x48",
+ "\x3e\xce\xa8\xca\xf0\xd8\xef\xa4\x2d\x54\xac\x5e\xf3\x6e\x62\x42\x37\xd9\xf5\x50\x8e\xd6\xfc\xb6\x43\x4d\x67\xf3\xfb\x78\x8c\x53\x8c\x63\x57\x98\xf5\x2b\x2f\x07\x3a\x4a\x73\x76\xfd\x31\xc4\xa3",
+ 171 },
+ { GCRY_MD_SHA3_384,
+ "\xb1\x0c\x59\x72\x3e\x3d\xca\xdd\x6d\x75\xdf\x87\xd0\xa1\x58\x0e\x73\x13\x3a\x9b\x7d\x00\xcb\x95\xec\x19\xf5\x54\x70\x27\x32\x3b\xe7\x51\x58\xb1\x1f\x80\xb6\xe1\x42\xc6\xa7\x85\x31\x88\x6d\x90\x47\xb0\x8e\x55\x1e\x75\xe6\x26\x1e\x79\x78\x53\x66\xd7\x02\x4b\xd7\xcd\x9c\xf3\x22\xd9\xbe\x7d\x57\xfb\x66\x10\x69\xf2\x48\x1c\x7b\xb7\x59\xcd\x71\xb4\xb3\x6c\xa2\xbc\x2d\xf6\xd3\xa3\x28\xfa\xeb\xdb\x99\x5a\x97\x94\xa8\xd7\x21\x55\xed\x55\x1a\x1f\x87\xc8\x0b\xf6\x05\x9b\x43\xfc\x76\x49\x00\xb1\x8a\x1c\x24\x41\xf7\x48\x77\x43\xcf\x84\xe5\x65\xf6\x1f\x8d\xd2\xec\xe6\xb6\xcc\xc9\x44\x40\x49\x19\x7a\xaa\xf5\x3e\x92\x6f\xbe\xe3\xbf\xca\x8b\xe5\x88\xec\x77\xf2\x9d\x21\x1b\xe8\x9d\xe1\x8b\x15\xf6",
+ "\xa8\x87\x6f\xe4\x65\x2a\xcf\x72\xdc\xc8\xfd\x51\x33\xe5\xd4\xca\x4e\x37\x66\xab\x98\x7c\xf6\x6e\xae\x5e\x37\x70\xe2\x52\xd2\xfd\x2a\x89\x05\x25\x01\x66\x23\xee\x69\x06\x46\x90\x82\x8c\x72\x7b",
+ 172 },
+ { GCRY_MD_SHA3_384,
+ "\xdb\x11\xf6\x09\xba\xba\x7b\x0c\xa6\x34\x92\x6b\x1d\xd5\x39\xc8\xcb\xad\xa2\x49\x67\xd7\xad\xd4\xd9\x87\x6f\x77\xc2\xd8\x0c\x0f\x4d\xce\xfb\xd7\x12\x15\x48\x37\x35\x82\x70\x5c\xca\x24\x95\xbd\x2a\x43\x71\x6f\xe6\x4e\xd2\x6d\x05\x9c\xfb\x56\x6b\x33\x64\xbd\x49\xee\x07\x17\xbd\xd9\x81\x0d\xd1\x4d\x8f\xad\x80\xdb\xbd\xc4\xca\xfb\x37\xcc\x60\xfb\x0f\xe2\xa8\x0f\xb4\x54\x1b\x8c\xa9\xd5\x9d\xce\x45\x77\x38\xa9\xd3\xd8\xf6\x41\xaf\x8c\x3f\xd6\xda\x16\x2d\xc1\x6f\xc0\x1a\xac\x52\x7a\x4a\x02\x55\xb4\xd2\x31\xc0\xbe\x50\xf4\x4f\x0d\xb0\xb7\x13\xaf\x03\xd9\x68\xfe\x7f\x0f\x61\xed\x08\x24\xc5\x5c\x4b\x52\x65\x54\x8f\xeb\xd6\xaa\xd5\xc5\xee\xdf\x63\xef\xe7\x93\x48\x9c\x39\xb8\xfd\x29\xd1\x04\xce",
+ "\x6a\x09\x73\x57\x36\x78\x0f\x19\x9d\x75\xc6\x09\x03\xaa\x24\xd7\xf8\xaa\x17\x51\x66\x90\x85\x4f\x75\x22\xef\x0b\xbf\x47\xd4\x1c\xbd\xc8\xbd\xb2\xcb\x2f\x3c\x55\x96\x51\x05\x39\x67\x76\x07\xe9",
+ 173 },
+ { GCRY_MD_SHA3_384,
+ "\xbe\xbd\x4f\x1a\x84\xfc\x8b\x15\xe4\x45\x2a\x54\xbd\x02\xd6\x9e\x30\x4b\x7f\x32\x61\x6a\xad\xd9\x05\x37\x93\x71\x06\xae\x4e\x28\xde\x9d\x8a\xab\x02\xd1\x9b\xc3\xe2\xfd\xe1\xd6\x51\x55\x9e\x29\x64\x53\xe4\xdb\xa9\x43\x70\xa1\x4d\xbb\xb2\xd1\xd4\xe2\x02\x23\x02\xee\x90\xe2\x08\x32\x1e\xfc\xd8\x52\x8a\xd8\x9e\x46\xdc\x83\x9e\xa9\xdf\x61\x8e\xa8\x39\x4a\x6b\xff\x30\x8e\x77\x26\xba\xe0\xc1\x9b\xcd\x4b\xe5\x2d\xa6\x25\x8e\x2e\xf4\xe9\x6a\xa2\x12\x44\x42\x9f\x49\xef\x5c\xb4\x86\xd7\xff\x35\xca\xc1\xba\xcb\x7e\x95\x71\x19\x44\xbc\xcb\x2a\xb3\x47\x00\xd4\x2d\x1e\xb3\x8b\x5d\x53\x6b\x94\x73\x48\xa4\x58\xed\xe3\xdc\x6b\xd6\xec\x54\x7b\x1b\x0c\xae\x5b\x25\x7b\xe3\x6a\x71\x24\xe1\x06\x0c\x17\x0f\xfa",
+ "\x83\xfc\x2b\x91\xab\x81\xd4\xb1\x53\x63\xf1\x5e\x53\xbf\x63\x90\x63\xba\xc5\x55\x02\xb4\x42\x1c\xf9\xa5\x3b\xca\xb9\xff\x47\xfd\x77\xde\x5a\xc6\x93\x4f\x67\xa4\x12\xea\x19\x10\xfa\xd6\x77\x68",
+ 174 },
+ { GCRY_MD_SHA3_384,
+ "\x5a\xca\x56\xa0\x3a\x13\x78\x4b\xdc\x32\x89\xd9\x36\x4f\x79\xe2\xa8\x5c\x12\x27\x6b\x49\xb9\x2d\xb0\xad\xaa\x4f\x20\x6d\x50\x28\xf2\x13\xf6\x78\xc3\x51\x0e\x11\x1f\x9d\xc4\xc1\xc1\xf8\xb6\xac\xb1\x7a\x64\x13\xaa\x22\x76\x07\xc5\x15\xc6\x2a\x73\x38\x17\xba\x5e\x76\x2c\xc6\x74\x8e\x7e\x0d\x68\x72\xc9\x84\xd7\x23\xc9\xbb\x3b\x11\x7e\xb8\x96\x31\x85\x30\x0a\x80\xbf\xa6\x5c\xde\x49\x5d\x70\xa4\x6c\x44\x85\x86\x05\xfc\xcb\xed\x08\x6c\x2b\x45\xce\xf9\x63\xd3\x32\x94\xdb\xe9\x70\x6b\x13\xaf\x22\xf1\xb7\xc4\xcd\x5a\x00\x1c\xfe\xc2\x51\xfb\xa1\x8e\x72\x2c\x6e\x1c\x4b\x11\x66\x91\x8b\x4f\x6f\x48\xa9\x8b\x64\xb3\xc0\x7f\xc8\x6a\x6b\x17\xa6\xd0\x48\x0a\xb7\x9d\x4e\x64\x15\xb5\x20\xf1\xc4\x84\xd6\x75\xb1",
+ "\x77\xc0\x48\x0b\x91\xf3\x2e\xf8\x09\xd8\xc2\x3a\xb2\x36\x58\x1f\x0b\xca\x8b\x94\x47\xa4\xd3\x62\x28\x05\x2b\x3a\xbb\x6a\xb6\x9c\x61\xd1\x9d\x72\x04\x86\xa3\xff\x49\x7a\x46\x73\xb8\x4c\xb9\x51",
+ 175 },
+ { GCRY_MD_SHA3_384,
+ "\xa5\xaa\xd0\xe4\x64\x6a\x32\xc8\x5c\xfc\xac\x73\xf0\x2f\xc5\x30\x0f\x19\x82\xfa\xbb\x2f\x21\x79\xe2\x83\x03\xe4\x47\x85\x40\x94\xcd\xfc\x85\x43\x10\xe5\xc0\xf6\x09\x93\xce\xff\x54\xd8\x4d\x6b\x46\x32\x3d\x93\x0a\xdb\x07\xc1\x75\x99\xb3\x5b\x50\x5f\x09\xe7\x84\xbc\xa5\x98\x5e\x01\x72\x25\x77\x97\xfb\x53\x64\x9e\x2e\x97\x23\xef\xd1\x68\x65\xc3\x1b\x5c\x3d\x51\x13\xb5\x8b\xb0\xbf\xc8\x92\x0f\xab\xdd\xa0\x86\xd7\x53\x7e\x66\xd7\x09\xd0\x50\xbd\x14\xd0\xc9\x60\x87\x3f\x15\x6f\xad\x5b\x3d\x38\x40\xcd\xfc\xdc\x9b\xe6\xaf\x51\x9d\xb2\x62\xa2\x7f\x40\x89\x6a\xb2\x5c\xc3\x9f\x96\x98\x4d\x65\x06\x11\xc0\xd5\xa3\x08\x0d\x5b\x3a\x1b\xf1\x86\xab\xd4\x29\x56\x58\x8b\x3b\x58\xcd\x94\x89\x70\xd2\x98\x77\x60\x60",
+ "\x78\x14\x66\xe2\x57\xd2\xfa\x59\x4e\x39\xdc\x22\x0a\x26\x0c\x74\x78\xd2\x15\x8b\xb7\x0e\x42\x6f\x9e\x95\x87\xf5\xa5\x1a\x7c\x29\xfd\xc7\xaf\x23\xe7\xab\x9c\x77\x4e\x33\xc0\x8a\xb3\x8c\xed\xb7",
+ 176 },
+ { GCRY_MD_SHA3_384,
+ "\x06\xcb\xbe\x67\xe9\x4a\x97\x82\x03\xea\xd6\xc0\x57\xa1\xa5\xb0\x98\x47\x8b\x4b\x4c\xbe\xf5\xa9\x7e\x93\xc8\xe4\x2f\x55\x72\x71\x35\x75\xfc\x2a\x88\x45\x31\xd7\x62\x2f\x8f\x87\x93\x87\xa8\x59\xa8\x0f\x10\xef\x02\x70\x8c\xd8\xf7\x41\x3a\xb3\x85\xaf\xc3\x57\x67\x8b\x95\x78\xc0\xeb\xf6\x41\xef\x07\x6a\x1a\x30\xf1\xf7\x53\x79\xe9\xdc\xb2\xa8\x85\xbd\xd2\x95\x90\x5e\xe8\x0c\x01\x68\xa6\x2a\x95\x97\xd1\x0c\xf1\x2d\xd2\xd8\xce\xe4\x66\x45\xc7\xe5\xa1\x41\xf6\xe0\xe2\x3a\xa4\x82\xab\xe5\x66\x1c\x16\xe6\x9e\xf1\xe2\x83\x71\xe2\xe2\x36\xc3\x59\xba\x4e\x92\xc2\x56\x26\xa7\xb7\xff\x13\xf6\xea\x4a\xe9\x06\xe1\xcf\xe1\x63\xe9\x17\x19\xb1\xf7\x50\xa9\x6c\xbd\xe5\xfb\xc9\x53\xd9\xe5\x76\xcd\x21\x6a\xfc\x90\x32\x3a",
+ "\x51\xbe\xbf\xb5\xaa\xfe\x77\x7f\x39\x0e\x28\x51\xb7\xeb\x9a\xa3\x80\x91\x94\xfe\x3b\xa1\x68\x9a\xbe\xe7\xe4\x3d\x44\xa5\x87\x4e\x0c\x25\x27\x93\xdf\xd4\x2c\x12\x70\xc6\x3c\x40\x7a\xef\x67\x80",
+ 177 },
+ { GCRY_MD_SHA3_384,
+ "\xf1\xc5\x28\xcf\x77\x39\x87\x47\x07\xd4\xd8\xad\x5b\x98\xf7\xc7\x71\x69\xde\x0b\x57\x18\x8d\xf2\x33\xb2\xdc\x8a\x5b\x31\xed\xa5\xdb\x42\x91\xdd\x9f\x68\xe6\xba\xd3\x7b\x8d\x7f\x6c\x9c\x00\x44\xb3\xbf\x74\xbb\xc3\xd7\xd1\x79\x8e\x13\x87\x09\xb0\xd7\x5e\x7c\x59\x3d\x3c\xcc\xdc\x1b\x20\xc7\x17\x4b\x4e\x69\x2a\xdd\x82\x0a\xce\x26\x2d\x45\xcc\xfa\xe2\x07\x7e\x87\x87\x96\x34\x71\x68\x06\x0a\x16\x2e\xcc\xa8\xc3\x8c\x1a\x88\x35\x0b\xd6\x3b\xb5\x39\x13\x4f\x70\x0f\xd4\xad\xdd\x59\x59\xe2\x55\x33\x7d\xaa\x06\xbc\x86\x35\x8f\xab\xcb\xef\xdf\xb5\xbc\x88\x97\x83\xd8\x43\xc0\x8a\xad\xc6\xc4\xf6\xc3\x6f\x65\xf1\x56\xe8\x51\xc9\xa0\xf9\x17\xe4\xa3\x67\xb5\xad\x93\xd8\x74\x81\x2a\x1d\xe6\xa7\xb9\x3c\xd5\x3a\xd9\x72\x32",
+ "\xfc\xdf\x00\x32\xf3\x4b\xa6\xc4\x2d\x67\x9b\x18\x2d\x07\xb1\x0f\x4d\xff\x21\x89\xb0\xa5\xef\x66\x42\xfb\xb7\x1b\x16\xf9\x10\xe3\x24\x0e\xd9\xb5\x02\xb1\xc6\xb3\x95\xbe\xe7\x4a\xd0\xfb\x41\x91",
+ 178 },
+ { GCRY_MD_SHA3_384,
+ "\x9d\x9f\x3a\x7e\xcd\x51\xb4\x1f\x65\x72\xfd\x0d\x08\x81\xe3\x03\x90\xdf\xb7\x80\x99\x1d\xae\x7d\xb3\xb4\x76\x19\x13\x47\x18\xe6\xf9\x87\x81\x0e\x54\x26\x19\xdf\xaa\x7b\x50\x5c\x76\xb7\x35\x0c\x64\x32\xd8\xbf\x1c\xfe\xbd\xf1\x06\x9b\x90\xa3\x5f\x0d\x04\xcb\xdf\x13\x0b\x0d\xfc\x78\x75\xf4\xa4\xe6\x2c\xdb\x8e\x52\x5a\xad\xd7\xce\x84\x25\x20\xa4\x82\xac\x18\xf0\x94\x42\xd7\x83\x05\xfe\x85\xa7\x4e\x39\xe7\x60\xa4\x83\x74\x82\xed\x2f\x43\x7d\xd1\x3b\x2e\xc1\x04\x2a\xfc\xf9\xde\xcd\xc3\xe8\x77\xe5\x0f\xf4\x10\x6a\xd1\x0a\x52\x52\x30\xd1\x19\x20\x32\x4a\x81\x09\x4d\xa3\x1d\xea\xb6\x47\x6a\xa4\x2f\x20\xc8\x48\x43\xcf\xc1\xc5\x85\x45\xee\x80\x35\x2b\xdd\x37\x40\xdd\x6a\x16\x79\x2a\xe2\xd8\x6f\x11\x64\x1b\xb7\x17\xc2",
+ "\x92\xaa\xdc\x02\xbb\x97\x95\xa4\x8b\x03\x10\x34\xee\x6a\xb8\x73\xdf\x48\x1d\x23\x29\x32\xfb\x5f\xd6\xc3\x76\x2e\x50\xe5\x8d\xa4\x6d\x1f\x5e\x5e\x87\x45\x97\xf1\x5c\x83\x12\x7f\x0a\x30\x42\xb1",
+ 179 },
+ { GCRY_MD_SHA3_384,
+ "\x51\x79\x88\x87\x24\x81\x9f\xba\xd3\xaf\xa9\x27\xd3\x57\x77\x96\x66\x0e\x6a\x81\xc5\x2d\x98\xe9\x30\x32\x61\xd5\xa4\xa8\x32\x32\xf6\xf7\x58\x93\x4d\x50\xaa\x83\xff\x9e\x20\xa5\x92\x6d\xfe\xba\xac\x49\x52\x9d\x00\x6e\xb9\x23\xc5\xae\x50\x48\xed\x54\x4e\xc4\x71\xed\x71\x91\xed\xf4\x63\x63\x38\x38\x24\xf9\x15\x76\x9b\x3e\x68\x80\x94\xc6\x82\xb0\x21\x51\xe5\xee\x01\xe5\x10\xb4\x31\xc8\x86\x5a\xff\x8b\x6b\x6f\x2f\x59\xcb\x6d\x12\x9d\xa7\x9e\x97\xc6\xd2\xb8\xfa\x6c\x6d\xa3\xf6\x03\x19\x9d\x2d\x1b\xca\xb5\x47\x68\x2a\x81\xcd\x6c\xf6\x5f\x65\x51\x12\x13\x91\xd7\x8b\xcc\x23\xb5\xbd\x0e\x92\x2e\xc6\xd8\xbf\x97\xc9\x52\xe8\x4d\xd2\x8a\xef\x90\x9a\xba\x31\xed\xb9\x03\xb2\x8f\xbf\xc3\x3b\x77\x03\xcd\x99\x62\x15\xa1\x12\x38",
+ "\x0d\x0c\xcd\xbf\xeb\x0a\x93\x3f\x21\x1e\xaa\x94\xeb\x45\x29\x00\x32\x43\x40\x50\x5c\xcf\x8d\xb7\xad\x93\xe9\x76\x27\x1f\x81\x2f\xb8\x90\x78\x05\xf6\x31\x3d\x0b\x09\x31\xf5\xc9\x20\x3b\xdb\xa5",
+ 180 },
+ { GCRY_MD_SHA3_384,
+ "\x57\x6e\xf3\x52\x0d\x30\xb7\xa4\x89\x9b\x8c\x0d\x5e\x35\x9e\x45\xc5\x18\x9a\xdd\x10\x0e\x43\xbe\x42\x9a\x02\xfb\x3d\xe5\xff\x4f\x8f\xd0\xe7\x9d\x96\x63\xac\xca\x72\xcd\x29\xc9\x45\x82\xb1\x92\x92\xa5\x57\xc5\xb1\x31\x52\x97\xd1\x68\xfb\xb5\x4e\x9e\x2e\xcd\x13\x80\x9c\x2b\x5f\xce\x99\x8e\xdc\x65\x70\x54\x5e\x14\x99\xdb\xe7\xfb\x74\xd4\x7c\xd7\xf3\x58\x23\xb2\x12\xb0\x5b\xf3\xf5\xa7\x9c\xaa\x34\x22\x4f\xdd\x67\x0d\x33\x5f\xcb\x10\x6f\x5d\x92\xc3\x94\x6f\x44\xd3\xaf\xcb\xae\x2e\x41\xac\x55\x4d\x8e\x67\x59\xf3\x32\xb7\x6b\xe8\x9a\x03\x24\xaa\x12\xc5\x48\x2d\x1e\xa3\xee\x89\xde\xd4\x93\x6f\x3e\x3c\x08\x04\x36\xf5\x39\xfa\x13\x7e\x74\xc6\xd3\x38\x9b\xdf\x5a\x45\x07\x4c\x47\xbc\x7b\x20\xb0\x94\x84\x07\xa6\x6d\x85\x5e\x2f",
+ "\xfe\xf6\xb1\xf2\x7b\x0c\xeb\xc4\x56\x85\x88\xe6\x27\xd2\x8d\xd5\x69\xa5\x8a\x8f\x9a\x51\xa1\xd2\x88\x7b\x40\xf5\x54\x7b\x2c\x67\xc7\x19\x17\xbe\x99\x8d\x19\x87\xac\x78\xe9\x07\x7c\xc7\x90\xab",
+ 181 },
+ { GCRY_MD_SHA3_384,
+ "\x0d\xf2\x15\x2f\xa4\xf4\x35\x7c\x87\x41\x52\x9d\xd7\x7e\x78\x39\x25\xd3\xd7\x6e\x95\xba\xfa\x2b\x54\x2a\x2c\x33\xf3\xd1\xd1\x17\xd1\x59\xcf\x47\x3f\x82\x31\x03\x56\xfe\xe4\xc9\x0a\x9e\x50\x5e\x70\xf8\xf2\x48\x59\x65\x63\x68\xba\x09\x38\x1f\xa2\x45\xeb\x6c\x3d\x76\x3f\x30\x93\xf0\xc8\x9b\x97\x2e\x66\xb5\x3d\x59\x40\x6d\x9f\x01\xae\xa0\x7f\x8b\x3b\x61\x5c\xac\x4e\xe4\xd0\x5f\x54\x2e\x7d\x0d\xab\x45\xd6\x7c\xcc\xcd\x3a\x60\x6c\xcb\xeb\x31\xea\x1f\xa7\x00\x5b\xa0\x71\x76\xe6\x0d\xab\x7d\x78\xf6\x81\x0e\xf0\x86\xf4\x2f\x08\xe5\x95\xf0\xec\x21\x73\x72\xb9\x89\x70\xcc\x63\x21\x57\x6d\x92\xce\x38\xf7\xc3\x97\xa4\x03\xba\xda\x15\x48\xd2\x05\xc3\x43\xac\x09\xde\xca\x86\x32\x53\x73\xc3\xb7\x6d\x9f\x32\x02\x8f\xea\x8e\xb3\x25\x15",
+ "\xe9\x95\x77\x32\xe7\xda\xb6\x45\x50\xf0\x03\xee\x6d\x03\x53\xae\x89\xbd\xc6\xd6\x9d\x05\x76\x60\x24\xcf\xf1\x89\xe4\xfc\x8f\xaa\x41\xdb\x72\x95\x4e\x8e\x5a\xc0\xb2\x92\x65\xc8\xf7\x85\xe7\x37",
+ 182 },
+ { GCRY_MD_SHA3_384,
+ "\x3e\x15\x35\x0d\x87\xd6\xeb\xb5\xc8\xad\x99\xd4\x25\x15\xcf\xe1\x79\x80\x93\x3c\x7a\x8f\x6b\x8b\xbb\xf0\xa6\x37\x28\xce\xfa\xad\x20\x52\x62\x3c\x0b\xd5\x93\x18\x39\x11\x2a\x48\x63\x3f\xb3\xc2\x00\x4e\x07\x49\xc8\x7a\x41\xb2\x6a\x8b\x48\x94\x55\x39\xd1\xff\x41\xa4\xb2\x69\x46\x2f\xd1\x99\xbf\xec\xd4\x53\x74\x75\x6f\x55\xa9\x11\x6e\x92\x09\x3a\xc9\x94\x51\xae\xfb\x2a\xf9\xfd\x32\xd6\xd7\xf5\xfb\xc7\xf7\xa5\x40\xd5\x09\x7c\x09\x6e\xbc\x3b\x3a\x72\x15\x41\xde\x07\x3a\x1c\xc0\x2f\x7f\xb0\xfb\x1b\x93\x27\xfb\x0b\x12\x18\xca\x49\xc9\x48\x7a\xb5\x39\x66\x22\xa1\x3a\xe5\x46\xc9\x7a\xbd\xef\x6b\x56\x38\x0d\xda\x70\x12\xa8\x38\x40\x91\xb6\x65\x6d\x0a\xb2\x72\xd3\x63\xce\xa7\x81\x63\xff\x76\x5c\xdd\x13\xab\x17\x38\xb9\x40\xd1\x6c\xae",
+ "\x98\xd7\x3b\x35\x55\xf0\x03\x05\x8f\x7b\x5a\x14\x5d\x89\xfa\xec\x46\xc1\x70\x99\xa3\x54\xef\x38\x34\xa2\x01\x42\xdb\xd5\x0a\x0e\x80\x54\x59\x8c\xe7\x94\x1b\xf5\xdd\x4d\xf7\xcc\xf2\x18\xf0\x2f",
+ 183 },
+ { GCRY_MD_SHA3_384,
+ "\xc3\x8d\x6b\x0b\x75\x7c\xb5\x52\xbe\x40\x94\x0e\xce\x00\x09\xef\x3b\x0b\x59\x30\x7c\x14\x51\x68\x6f\x1a\x22\x70\x29\x22\x80\x0d\x58\xbc\xe7\xa6\x36\xc1\x72\x7e\xe5\x47\xc0\x1b\x21\x47\x79\xe8\x98\xfc\x0e\x56\x0f\x8a\xe7\xf6\x1b\xef\x4d\x75\xea\xa6\x96\xb9\x21\xfd\x6b\x73\x5d\x17\x15\x35\xe9\xed\xd2\x67\xc1\x92\xb9\x98\x80\xc8\x79\x97\x71\x10\x02\x00\x90\x95\xd8\xa7\xa4\x37\xe2\x58\x10\x4a\x41\xa5\x05\xe5\xef\x71\xe5\x61\x3d\xdd\x20\x08\x19\x5f\x0c\x57\x4e\x6b\xa3\xfe\x40\x09\x9c\xfa\x11\x6e\x5f\x1a\x2f\xa8\xa6\xda\x04\xba\xdc\xb4\xe2\xd5\xd0\xde\x31\xfd\xc4\x80\x08\x91\xc4\x57\x81\xa0\xaa\xc7\xc9\x07\xb5\x6d\x63\x1f\xca\x5c\xe8\xb2\xcd\xe6\x20\xd1\x1d\x17\x77\xed\x9f\xa6\x03\x54\x1d\xe7\x94\xdd\xc5\x75\x8f\xcd\x5f\xad\x78\xc0",
+ "\x37\x95\xde\x49\x0f\x43\xb9\x89\x99\x47\xc1\xc3\x05\xc3\x0e\x26\x33\x1b\xa0\xe6\x11\xdc\xe7\x96\x11\x72\xb2\xe4\x29\x99\x32\x14\x7b\xc9\xe2\x41\xc3\x2e\x61\xfa\x96\x4d\x4f\x43\x6e\xcc\xfd\x37",
+ 184 },
+ { GCRY_MD_SHA3_384,
+ "\x8d\x2d\xe3\xf0\xb3\x7a\x63\x85\xc9\x07\x39\x80\x5b\x17\x00\x57\xf0\x91\xcd\x0c\x7a\x0b\xc9\x51\x54\x0f\x26\xa5\xa7\x5b\x3e\x69\x46\x31\xbb\x64\xc7\x63\x5e\xed\x31\x6f\x51\x31\x8e\x9d\x8d\xe1\x3c\x70\xa2\xab\xa0\x4a\x14\x83\x68\x55\xf3\x5e\x48\x05\x28\xb7\x76\xd0\xa1\xe8\xa2\x3b\x54\x7c\x8b\x8d\x6a\x0d\x09\xb2\x41\xd3\xbe\x93\x77\x16\x0c\xca\x4e\x67\x93\xd0\x0a\x51\x5d\xc2\x99\x2c\xb7\xfc\x74\x1d\xac\xa1\x71\x43\x1d\xa9\x9c\xce\x6f\x77\x89\xf1\x29\xe2\xac\x5c\xf6\x5b\x40\xd7\x03\x03\x5c\xd2\x18\x5b\xb9\x36\xc8\x20\x02\xda\xf8\xcb\xc2\x7a\x7a\x9e\x55\x4b\x06\x19\x66\x30\x44\x6a\x6f\x0a\x14\xba\x15\x5e\xd2\x6d\x95\xbd\x62\x7b\x72\x05\xc0\x72\xd0\x2b\x60\xdb\x0f\xd7\xe4\x9e\xa0\x58\xc2\xe0\xba\x20\x2d\xaf\xf0\xde\x91\xe8\x45\xcf\x79",
+ "\xe9\xf2\x89\xe6\x71\x54\x1f\xec\x45\x99\x91\x5a\x0d\x99\x35\xbf\x5c\x20\xa1\x2c\x20\x3b\xcd\xe8\x8a\x46\xea\xf5\xca\xb2\xd4\x37\xf9\xfc\xde\xf6\x7b\x98\x76\x8b\xb8\x0c\x9a\x87\x4b\x3f\x46\xc7",
+ 185 },
+ { GCRY_MD_SHA3_384,
+ "\xc4\x64\xbb\xda\xd2\x75\xc5\x0d\xcd\x98\x3b\x65\xad\x10\x19\xb9\xff\x85\xa1\xe7\x1c\x80\x7f\x32\x04\xbb\x2c\x92\x1d\xc3\x1f\xbc\xd8\xc5\xfc\x45\x86\x8a\xe9\xef\x85\xb6\xc9\xb8\x3b\xba\x2a\x5a\x82\x22\x01\xed\x68\x58\x6e\xc5\xec\x27\xfb\x28\x57\xa5\xd1\xa2\xd0\x9d\x09\x11\x5f\x22\xdc\xc3\x9f\xe6\x1f\x5e\x1b\xa0\xff\x6e\x8b\x4a\xcb\x4c\x6d\xa7\x48\xbe\x7f\x3f\x08\x39\x73\x93\x94\xff\x7f\xa8\xe3\x9f\x7f\x7e\x84\xa3\x3c\x38\x66\x87\x5c\x01\xbc\xb1\x26\x3c\x94\x05\xd9\x19\x08\xe9\xe0\xb5\x0e\x74\x59\xfa\xbb\x63\xd8\xc6\xbb\xb7\x3d\x8e\x34\x83\xc0\x99\xb5\x5b\xc3\x0f\xf0\x92\xff\x68\xb6\xad\xed\xfd\x47\x7d\x63\x57\x0c\x9f\x55\x15\x84\x7f\x36\xe2\x4b\xa0\xb7\x05\x55\x71\x30\xce\xc5\x7e\xba\xd1\xd0\xb3\x1a\x37\x8e\x91\x89\x4e\xe2\x6e\x3a\x04",
+ "\x88\xc2\x3b\xe0\x40\xbe\x64\xd2\x3a\xee\x8d\x7e\xe9\x62\x22\x8a\x6f\x07\x83\x1b\x0e\x05\xfb\xe2\xf2\x5f\x07\x72\x9f\x00\xc2\xc6\x17\xeb\x69\x75\xf5\x7b\x3f\x17\xdd\x54\x0e\x8e\xbc\xa6\x54\xa9",
+ 186 },
+ { GCRY_MD_SHA3_384,
+ "\x8b\x8d\x68\xbb\x8a\x75\x73\x2f\xe2\x72\x81\x5a\x68\xa1\xc9\xc5\xaa\x31\xb4\x1d\xed\xc8\x49\x3e\x76\x52\x5d\x1d\x01\x3d\x33\xce\xbd\x9e\x21\xa5\xbb\x95\xdb\x26\x16\x97\x6a\x8c\x07\xfc\xf4\x11\xf5\xf6\xbc\x6f\x7e\x0b\x57\xac\xa7\x8c\xc2\x79\x0a\x6f\x9b\x89\x88\x58\xac\x9c\x79\xb1\x65\xff\x24\xe6\x66\x77\x53\x1e\x39\xf5\x72\xbe\x5d\x81\xeb\x32\x64\x52\x41\x81\x11\x5f\x32\x78\x02\x57\xbf\xb9\xae\xec\x6a\xf1\x2a\xf2\x8e\x58\x7c\xac\x06\x8a\x1a\x29\x53\xb5\x9a\xd6\x80\xf4\xc2\x45\xb2\xe3\xec\x36\xf5\x99\x40\xd3\x7e\x1d\x3d\xb3\x8e\x13\xed\xb2\x9b\x5c\x0f\x40\x4f\x6f\xf8\x7f\x80\xfc\x8b\xe7\xa2\x25\xff\x22\xfb\xb9\xc8\xb6\xb1\xd7\x33\x0c\x57\x84\x0d\x24\xbc\x75\xb0\x6b\x80\xd3\x0d\xad\x68\x06\x54\x4d\x51\x0a\xf6\xc4\x78\x5e\x82\x3a\xc3\xe0\xb8",
+ "\x6c\x42\xde\xe6\x1c\xd9\x7c\x50\xf5\x34\x0c\xf4\xdc\x4f\x7e\x31\x9f\xb5\xfa\xc7\xa2\x6b\x41\xde\xe6\x6d\x78\x98\x04\xbd\x1f\xef\x1e\xf2\x91\x16\x43\xc9\xc1\xe2\xc0\x48\x5c\x97\x9b\x36\xd9\x27",
+ 187 },
+ { GCRY_MD_SHA3_384,
+ "\x6b\x01\x87\x10\x44\x6f\x36\x8e\x74\x21\xf1\xbc\x0c\xcf\x56\x2d\x9c\x18\x43\x84\x6b\xc8\xd9\x8d\x1c\x9b\xf7\xd9\xd6\xfc\xb4\x8b\xfc\x3b\xf8\x3b\x36\xd4\x4c\x4f\xa9\x34\x30\xaf\x75\xcd\x19\x0b\xde\x36\xa7\xf9\x2f\x86\x7f\x58\xa8\x03\x90\x0d\xf8\x01\x81\x50\x38\x4d\x85\xd8\x21\x32\xf1\x23\x00\x6a\xc2\xae\xba\x58\xe0\x2a\x03\x7f\xe6\xaf\xbd\x65\xec\xa7\xc4\x49\x77\xdd\x3d\xc7\x4f\x48\xb6\xe7\xa1\xbf\xd5\xcc\x4d\xcf\x24\xe4\xd5\x2e\x92\xbd\x44\x55\x84\x8e\x49\x28\xb0\xea\xc8\xb7\x47\x6f\xe3\xcc\x03\xe8\x62\xaa\x4d\xff\x44\x70\xdb\xfe\xd6\xde\x48\xe4\x10\xf2\x50\x96\x48\x7e\xcf\xc3\x2a\x27\x27\x7f\x3f\x50\x23\xb2\x72\x5a\xde\x46\x1b\x13\x55\x88\x95\x54\xa8\x83\x6c\x9c\xf5\x3b\xd7\x67\xf5\x73\x7d\x55\x18\x4e\xea\x1a\xb3\xf5\x3e\xdd\x09\x76\xc4\x85",
+ "\x72\x01\x50\xfd\x5a\x1c\xf9\x4a\x42\xf9\x22\xef\xcb\xb7\x23\xff\x94\x8f\x74\xca\x6d\x0a\x3f\x39\x9a\xc5\x4d\xa8\xb3\xbc\x07\xf3\x9e\x6e\x29\x79\xc1\x6c\x87\x58\x66\xcf\x2f\x58\x4c\xa7\xf2\xdb",
+ 188 },
+ { GCRY_MD_SHA3_384,
+ "\xc9\x53\x4a\x24\x71\x4b\xd4\xbe\x37\xc8\x8a\x3d\xa1\x08\x2e\xda\x7c\xab\xd1\x54\xc3\x09\xd7\xbd\x67\x0d\xcc\xd9\x5a\xa5\x35\x59\x44\x63\x05\x8a\x29\xf7\x90\x31\xd6\xec\xaa\x9f\x67\x5d\x12\x11\xe9\x35\x9b\xe8\x26\x69\xa7\x9c\x85\x5e\xa8\xd8\x9d\xd3\x8c\x2c\x76\x1d\xdd\x0e\xc0\xce\x9e\x97\x59\x74\x32\xe9\xa1\xbe\xae\x06\x2c\xdd\x71\xed\xfd\xfd\x46\x41\x19\xbe\x9e\x69\xd1\x8a\x7a\x7f\xd7\xce\x0e\x21\x06\xf0\xc8\xb0\xab\xf4\x71\x5e\x2c\xa4\x8e\xf9\xf4\x54\xdc\x20\x3c\x96\x65\x66\x53\xb7\x27\x08\x35\x13\xf8\xef\xb8\x6e\x49\xc5\x13\xbb\x75\x8b\x3b\x05\x2f\xe2\x1f\x1c\x05\xbb\x33\xc3\x71\x29\xd6\xcc\x81\xf1\xae\xf6\xad\xc4\x5b\x0e\x88\x27\xa8\x30\xfe\x54\x5c\xf5\x7d\x09\x55\x80\x2c\x11\x7d\x23\xcc\xb5\x5e\xa2\x8f\x95\xc0\xd8\xc2\xf9\xc5\xa2\x42\xb3\x3f",
+ "\xfa\x6f\x90\x93\x58\x43\xd4\xf5\x8e\x77\xca\xbe\x4b\xa6\x62\xb4\xfa\xbc\x17\x32\x72\x5f\xaf\x95\x2e\xee\xd7\x0f\xa0\xaa\xd6\xa9\x8f\xe6\x7f\x3b\x67\x36\xa1\xc8\xf7\xc5\xbe\xd4\xd9\xb0\x17\xe0",
+ 189 },
+ { GCRY_MD_SHA3_384,
+ "\x07\x90\x6c\x87\x29\x7b\x86\x7a\xbf\x45\x76\xe9\xf3\xcc\x7f\x82\xf2\x2b\x15\x4a\xfc\xbf\x29\x3b\x93\x19\xf1\xb0\x58\x4d\xa6\xa4\x0c\x27\xb3\x2e\x0b\x1b\x7f\x41\x2c\x4f\x1b\x82\x48\x0e\x70\xa9\x23\x5b\x12\xec\x27\x09\x0a\x5a\x33\x17\x5a\x2b\xb2\x8d\x8a\xdc\x47\x5c\xef\xe3\x3f\x78\x03\xf8\xce\x27\x96\x72\x17\x38\x1f\x02\xe6\x7a\x3b\x4f\x84\xa7\x1f\x1c\x52\x28\xe0\xc2\xad\x97\x13\x73\xf6\xf6\x72\x62\x4f\xce\xa8\xd1\xa9\xf8\x51\x70\xfa\xd3\x0f\xa0\xbb\xd2\x50\x35\xc3\xb4\x1a\x61\x75\xd4\x67\x99\x8b\xd1\x21\x5f\x6f\x38\x66\xf5\x38\x47\xf9\xcf\x68\xef\x3e\x2f\xbb\x54\xbc\x99\x4d\xe2\x30\x2b\x82\x9c\x5e\xea\x68\xec\x44\x1f\xcb\xaf\xd7\xd1\x6a\xe4\xfe\x9f\xff\x98\xbf\x00\xe5\xbc\x2a\xd5\x4d\xd9\x1f\xf9\xfd\xa4\xdd\x77\xb6\xc7\x54\xa9\x19\x55\xd1\xfb\xaa\xd0",
+ "\x4e\x28\x32\xfe\xe2\x90\xd1\x91\x7c\x15\xb3\x18\x93\xf6\x57\x8c\x12\x99\x44\x5b\x99\xbc\x48\x70\x8e\x13\x34\x8a\x11\xeb\x2f\x27\xfe\x21\x7a\x63\xf5\x32\x58\x37\x93\xd1\x8c\xde\xcc\xaa\x78\xb9",
+ 190 },
+ { GCRY_MD_SHA3_384,
+ "\x58\x8e\x94\xb9\x05\x4a\xbc\x21\x89\xdf\x69\xb8\xba\x34\x34\x1b\x77\xcd\xd5\x28\xe7\x86\x0e\x5d\xef\xca\xa7\x9b\x0c\x9a\x45\x2a\xd4\xb8\x2a\xa3\x06\xbe\x84\x53\x6e\xb7\xce\xdc\xbe\x05\x8d\x7b\x84\xa6\xae\xf8\x26\xb0\x28\xb8\xa0\x27\x1b\x69\xac\x36\x05\xa9\x63\x5e\xa9\xf5\xea\x0a\xa7\x00\xf3\xeb\x78\x35\xbc\x54\x61\x1b\x92\x29\x64\x30\x0c\x95\x3e\xfe\x74\x91\xe3\x67\x7c\x2c\xeb\xe0\x82\x2e\x95\x6c\xd1\x64\x33\xb0\x2c\x68\xc4\xa2\x32\x52\xc3\xf9\xe1\x51\xa4\x16\xb4\x96\x32\x57\xb7\x83\xe0\x38\xf6\xb4\xd5\xc9\xf1\x10\xf8\x71\x65\x2c\x7a\x64\x9a\x7b\xce\xdc\xbc\xcc\x6f\x2d\x07\x25\xbb\x90\x3c\xc1\x96\xba\x76\xc7\x6a\xa9\xf1\x0a\x19\x0b\x1d\x11\x68\x99\x3b\xaa\x9f\xfc\x96\xa1\x65\x52\x16\x77\x34\x58\xbe\xc7\x2b\x0e\x39\xc9\xf2\xc1\x21\x37\x8f\xea\xb4\xe7\x6a",
+ "\x1f\xb9\x7d\x6f\x42\x48\x0e\x9f\x13\xc9\x34\xc4\xa8\x74\x87\x7a\x80\x8f\x1d\x73\x31\x4c\x54\x4d\x85\x70\xc0\x74\x9f\x20\xfa\x35\xf5\x3a\x0c\x0b\xda\x1f\x10\xd1\xa1\x0a\x02\x9a\xbb\xb5\x0b\xc7",
+ 191 },
+ { GCRY_MD_SHA3_384,
+ "\x08\x95\x9a\x7e\x4b\xaa\xe8\x74\x92\x88\x13\x36\x40\x71\x19\x4e\x29\x39\x77\x2f\x20\xdb\x7c\x31\x57\x07\x89\x87\xc5\x57\xc2\xa6\xd5\xab\xe6\x8d\x52\x0e\xef\x3d\xc4\x91\x69\x2e\x1e\x21\xbc\xd8\x80\xad\xeb\xf6\x3b\xb4\x21\x3b\x50\x89\x7f\xa0\x05\x25\x6e\xd4\x1b\x56\x90\xf7\x8f\x52\x85\x5c\x8d\x91\x68\xa4\xb6\x66\xfc\xe2\xda\x2b\x45\x6d\x7a\x7e\x7c\x17\xab\x5f\x2f\xb1\xee\x90\xb7\x9e\x69\x87\x12\xe9\x63\x71\x59\x83\xfd\x07\x64\x1a\xe4\xb4\xe9\xdc\x73\x20\x3f\xac\x1a\xe1\x1f\xa1\xf8\xc7\x94\x1f\xcc\x82\xea\xb2\x47\xad\xdb\x56\xe2\x63\x84\x47\xe9\xd6\x09\xe6\x10\xb6\x0c\xe0\x86\x65\x6a\xae\xbf\x1d\xa3\xc8\xa2\x31\xd7\xd9\x4e\x2f\xd0\xaf\xe4\x6b\x39\x1f\xf1\x4a\x72\xea\xeb\x3f\x44\xad\x4d\xf8\x58\x66\xde\xf4\x3d\x47\x81\xa0\xb3\x57\x8b\xc9\x96\xc8\x79\x70\xb1\x32",
+ "\x86\xb3\xc8\x1a\xa3\x98\xc8\x81\x9a\xfc\x4f\x28\x2d\xfb\xce\x24\xf4\x19\x2b\x25\x30\xc2\x67\xa7\x83\x73\xd2\x53\xc3\x5c\x1d\xcc\x4f\x40\x83\x55\x29\x56\x3f\xd4\x2a\x33\xfd\x2c\xbd\x68\x05\x15",
+ 192 },
+ { GCRY_MD_SHA3_384,
+ "\xcb\x2a\x23\x4f\x45\xe2\xec\xd5\x86\x38\x95\xa4\x51\xd3\x89\xa3\x69\xaa\xb9\x9c\xfe\xf0\xd5\xc9\xff\xca\x1e\x6e\x63\xf7\x63\xb5\xc1\x4f\xb9\xb4\x78\x31\x3c\x8e\x8c\x0e\xfe\xb3\xac\x95\x00\xcf\x5f\xd9\x37\x91\xb7\x89\xe6\x7e\xac\x12\xfd\x03\x8e\x25\x47\xcc\x8e\x0f\xc9\xdb\x59\x1f\x33\xa1\xe4\x90\x7c\x64\xa9\x22\xdd\xa2\x3e\xc9\x82\x73\x10\xb3\x06\x09\x85\x54\xa4\xa7\x8f\x05\x02\x62\xdb\x5b\x54\x5b\x15\x9e\x1f\xf1\xdc\xa6\xeb\x73\x4b\x87\x23\x43\xb8\x42\xc5\x7e\xaf\xcf\xda\x84\x05\xee\xdb\xb4\x8e\xf3\x2e\x99\x69\x6d\x13\x59\x79\x23\x5c\x3a\x05\x36\x4e\x37\x1c\x2d\x76\xf1\x90\x2f\x1d\x83\x14\x6d\xf9\x49\x5c\x0a\x6c\x57\xd7\xbf\x9e\xe7\x7e\x80\xf9\x78\x7a\xee\x27\xbe\x1f\xe1\x26\xcd\xc9\xef\x89\x3a\x4a\x7d\xcb\xbc\x36\x7e\x40\xfe\x4e\x1e\xe9\x0b\x42\xea\x25\xaf\x01",
+ "\xa6\xbf\x54\x8a\xb1\x9f\xf6\x0d\x6a\x87\x29\xfa\x62\xfd\xc9\xb5\x92\x37\x84\x37\x39\xaf\xff\x87\x72\x33\xed\x37\x4b\xcf\x70\xa0\x17\x12\x69\x74\xc2\xd1\xa3\x22\x2d\x8d\x90\x6b\xe8\x50\xa2\x5d",
+ 193 },
+ { GCRY_MD_SHA3_384,
+ "\xd1\x6b\xea\xdf\x02\xab\x1d\x4d\xc6\xf8\x8b\x8c\x45\x54\xc5\x1e\x86\x6d\xf8\x30\xb8\x9c\x06\xe7\x86\xa5\xf8\x75\x7e\x89\x09\x31\x0a\xf5\x1c\x84\x0e\xfe\x8d\x20\xb3\x53\x31\xf4\x35\x5d\x80\xf7\x32\x95\x97\x46\x53\xdd\xd6\x20\xcd\xde\x47\x30\xfb\x6c\x8d\x0d\x2d\xcb\x2b\x45\xd9\x2d\x4f\xbd\xb5\x67\xc0\xa3\xe8\x6b\xd1\xa8\xa7\x95\xaf\x26\xfb\xf2\x9f\xc6\xc6\x59\x41\xcd\xdb\x09\x0f\xf7\xcd\x23\x0a\xc5\x26\x8a\xb4\x60\x6f\xcc\xba\x9e\xde\xd0\xa2\xb5\xd0\x14\xee\x0c\x34\xf0\xb2\x88\x1a\xc0\x36\xe2\x4e\x15\x1b\xe8\x9e\xeb\x6c\xd9\xa7\xa7\x90\xaf\xcc\xff\x23\x4d\x7c\xb1\x1b\x99\xeb\xf5\x8c\xd0\xc5\x89\xf2\x0b\xda\xc4\xf9\xf0\xe2\x8f\x75\xe3\xe0\x4e\x5b\x3d\xeb\xce\x60\x7a\x49\x6d\x84\x8d\x67\xfa\x7b\x49\x13\x2c\x71\xb8\x78\xfd\x55\x57\xe0\x82\xa1\x8e\xca\x1f\xbd\xa9\x4d\x4b",
+ "\xba\x7d\x3b\x6a\xf5\x96\x6c\x8c\x27\x23\xb1\x31\x88\x20\x50\x5d\x04\x0d\xa8\x10\x12\x6a\xbc\x3e\x65\x08\x8d\xc4\x21\xe4\x6d\x3e\x54\xdd\x31\x77\x7c\x53\x9a\xe0\x83\xb7\xb8\xa4\xe2\x30\x38\x36",
+ 194 },
+ { GCRY_MD_SHA3_384,
+ "\x8f\x65\xf6\xbc\x59\xa8\x57\x05\x01\x6e\x2b\xae\x7f\xe5\x79\x80\xde\x31\x27\xe5\xab\x27\x5f\x57\x3d\x33\x4f\x73\xf8\x60\x31\x06\xec\x35\x53\x01\x66\x08\xef\x2d\xd6\xe6\x9b\x24\xbe\x0b\x71\x13\xbf\x6a\x76\x0b\xa6\xe9\xce\x1c\x48\xf9\xe1\x86\x01\x2c\xf9\x6a\x1d\x48\x49\xd7\x5d\xf5\xbb\x83\x15\x38\x7f\xd7\x8e\x9e\x15\x3e\x76\xf8\xba\x7e\xc6\xc8\x84\x98\x10\xf5\x9f\xb4\xbb\x9b\x00\x43\x18\x21\x0b\x37\xf1\x29\x95\x26\x86\x6f\x44\x05\x9e\x01\x7e\x22\xe9\x6c\xbe\x41\x86\x99\xd0\x14\xc6\xea\x01\xc9\xf0\x03\x8b\x10\x29\x98\x84\xdb\xec\x31\x99\xbb\x05\xad\xc9\x4e\x95\x5a\x15\x33\x21\x9c\x11\x15\xfe\xd0\xe5\xf2\x12\x28\xb0\x71\xf4\x0d\xd5\x7c\x42\x40\xd9\x8d\x37\xb7\x3e\x41\x2f\xe0\xfa\x47\x03\x12\x0d\x7c\x0c\x67\x97\x2e\xd2\x33\xe5\xde\xb3\x00\xa2\x26\x05\x47\x2f\xa3\xa3\xba\x86",
+ "\x48\xca\x59\x12\xc1\x11\xdb\x66\x7a\x77\xbe\x7c\x77\xf8\x41\xe8\xb3\x71\x30\x24\x83\x77\xa1\x9c\xd2\xfa\x3c\xd2\xee\xc4\x8b\x33\x7c\xfe\x07\xc2\x90\xf2\x69\x0a\xd4\x9e\x79\xce\x3a\x9f\x9e\x53",
+ 195 },
+ { GCRY_MD_SHA3_384,
+ "\x84\x89\x1e\x52\xe0\xd4\x51\x81\x32\x10\xc3\xfd\x63\x5b\x39\xa0\x3a\x6b\x7a\x73\x17\xb2\x21\xa7\xab\xc2\x70\xdf\xa9\x46\xc4\x26\x69\xaa\xcb\xbb\xdf\x80\x1e\x15\x84\xf3\x30\xe2\x8c\x72\x98\x47\xea\x14\x15\x2b\xd6\x37\xb3\xd0\xf2\xb3\x8b\x4b\xd5\xbf\x9c\x79\x1c\x58\x80\x62\x81\x10\x3a\x3e\xab\xba\xed\xe5\xe7\x11\xe5\x39\xe6\xa8\xb2\xcf\x29\x7c\xf3\x51\xc0\x78\xb4\xfa\x8f\x7f\x35\xcf\x61\xbe\xbf\x88\x14\xbf\x24\x8a\x01\xd4\x1e\x86\xc5\x71\x5e\xa4\x0c\x63\xf7\x37\x53\x79\xa7\xeb\x1d\x78\xf2\x76\x22\xfb\x46\x8a\xb7\x84\xaa\xab\xa4\xe5\x34\xa6\xdf\xd1\xdf\x6f\xa1\x55\x11\x34\x1e\x72\x5e\xd2\xe8\x7f\x98\x73\x7c\xcb\x7b\x6a\x6d\xfa\xe4\x16\x47\x74\x72\xb0\x46\xbf\x18\x11\x18\x7d\x15\x1b\xfa\x9f\x7b\x2b\xf9\xac\xdb\x23\xa3\xbe\x50\x7c\xdf\x14\xcf\xdf\x51\x7d\x2c\xb5\xfb\x9e\x4a\xb6",
+ "\x4b\x38\x49\xb0\x91\x6d\xd4\x45\xb1\x85\x6e\x1b\x90\x8c\x41\x4c\x75\x2d\x28\x0d\xe2\x18\x3d\xd1\xf0\x19\x3e\x73\xfd\x1b\xc0\x21\x98\x59\x95\x02\x39\x1e\x8c\xa4\x8d\x65\xe6\x10\xd6\xed\xcd\x8e",
+ 196 },
+ { GCRY_MD_SHA3_384,
+ "\xfd\xd7\xa9\x43\x3a\x3b\x4a\xfa\xbd\x7a\x3a\x5e\x34\x57\xe5\x6d\xeb\xf7\x8e\x84\xb7\xa0\xb0\xca\x0e\x8c\x6d\x53\xbd\x0c\x2d\xae\x31\xb2\x70\x0c\x61\x28\x33\x4f\x43\x98\x1b\xe3\xb2\x13\xb1\xd7\xa1\x18\xd5\x9c\x7e\x6b\x64\x93\xa8\x6f\x86\x6a\x16\x35\xc1\x28\x59\xcf\xb9\xad\x17\x46\x0a\x77\xb4\x52\x2a\x5c\x18\x83\xc3\xd6\xac\xc8\x6e\x61\x62\x66\x7e\xc4\x14\xe9\xa1\x04\xaa\x89\x20\x53\xa2\xb1\xd7\x21\x65\xa8\x55\xba\xcd\x8f\xaf\x80\x34\xa5\xdd\x9b\x71\x6f\x47\xa0\x81\x8c\x09\xbb\x6b\xaf\x22\xaa\x50\x3c\x06\xb4\xca\x26\x1f\x55\x77\x61\x98\x9d\x2a\xfb\xd8\x8b\x6a\x67\x8a\xd1\x28\xaf\x68\x67\x21\x07\xd0\xf1\xfc\x73\xc5\xca\x74\x04\x59\x29\x7b\x32\x92\xb2\x81\xe9\x3b\xce\xb7\x61\xbd\xe7\x22\x1c\x3a\x55\x70\x8e\x5e\xc8\x44\x72\xcd\xdc\xaa\x84\xec\xf2\x37\x23\xcc\x09\x91\x35\x5c\x62\x80",
+ "\x02\xc9\x08\x20\xd5\xfa\x9a\x91\x07\x29\x91\xe8\x7b\xfe\xec\x7f\x18\x31\x5f\x8c\xa1\x90\x8e\xdb\xf1\x98\x86\xc4\xca\x5b\xd5\x4a\xb9\xec\x96\xa6\xab\x7b\x81\x5b\x58\x53\x8f\x08\x88\x67\x03\x0f",
+ 197 },
+ { GCRY_MD_SHA3_384,
+ "\x70\xa4\x0b\xfb\xef\x92\x27\x7a\x1a\xad\x72\xf6\xb7\x9d\x01\x77\x19\x7c\x4e\xbd\x43\x26\x68\xcf\xec\x05\xd0\x99\xac\xcb\x65\x10\x62\xb5\xdf\xf1\x56\xc0\xb2\x73\x36\x68\x7a\x94\xb2\x66\x79\xcf\xdd\x9d\xaf\x7a\xd2\x04\x33\x8d\xd9\xc4\xd1\x41\x14\x03\x3a\x5c\x22\x5b\xd1\x1f\x21\x7b\x5f\x47\x32\xda\x16\x7e\xe3\xf9\x39\x26\x2d\x40\x43\xfc\x9c\xba\x92\x30\x3b\x7b\x5e\x96\xae\xa1\x2a\xdd\xa6\x48\x59\xdf\x4b\x86\xe9\xee\x0b\x58\xe3\x90\x91\xe6\xb1\x88\xb4\x08\xac\x94\xe1\x29\x4a\x89\x11\x24\x5e\xe3\x61\xe6\x0e\x60\x1e\xff\x58\xd1\xd3\x76\x39\xf3\x75\x3b\xec\x80\xeb\xb4\xef\xde\x25\x81\x74\x36\x07\x66\x23\xfc\x65\x41\x5f\xe5\x1d\x1b\x02\x80\x36\x6d\x12\xc5\x54\xd8\x67\x43\xf3\xc3\xb6\x57\x2e\x40\x03\x61\xa6\x07\x26\x13\x14\x41\xba\x49\x3a\x83\xfb\xe9\xaf\xda\x90\xf7\xaf\x1a\xe7\x17\x23\x8d",
+ "\x75\x96\x75\x01\xff\x78\x1e\xfc\x3c\x9d\x59\x71\x79\xc8\xcc\xae\xe4\x37\x3d\x9b\xf6\xaa\x6a\x5b\xed\x51\x18\x30\x3e\xdc\x8b\x74\x78\xa4\x7f\x2c\xea\xf0\xa6\xb5\xb7\x22\x4e\x53\xd5\xf1\xcd\xb3",
+ 198 },
+ { GCRY_MD_SHA3_384,
+ "\x74\x35\x6e\x44\x9f\x4b\xf8\x64\x4f\x77\xb1\x4f\x4d\x67\xcb\x6b\xd9\xc1\xf5\xae\x35\x76\x21\xd5\xb8\x14\x7e\x56\x2b\x65\xc6\x65\x85\xca\xf2\xe4\x91\xb4\x85\x29\xa0\x1a\x34\xd2\x26\xd4\x36\x95\x91\x53\x81\x53\x80\xd5\x68\x9e\x30\xb3\x53\x57\xcd\xac\x6e\x08\xd3\xf2\xb0\xe8\x8e\x20\x06\x00\xd6\x2b\xd9\xf5\xea\xf4\x88\xdf\x86\xa4\x47\x0e\xa2\x27\x00\x61\x82\xe4\x48\x09\x00\x98\x68\xc4\xc2\x80\xc4\x3d\x7d\x64\xa5\x26\x8f\xa7\x19\x07\x49\x60\x08\x7b\x3a\x6a\xbc\x83\x78\x82\xf8\x82\xc8\x37\x83\x45\x35\x92\x93\x89\xa1\x2b\x2c\x78\x18\x7e\x2e\xa0\x7e\xf8\xb8\xee\xf2\x7d\xc8\x50\x02\xc3\xae\x35\xf1\xa5\x0b\xee\x6a\x1c\x48\xba\x7e\x17\x5f\x33\x16\x67\x0b\x27\x98\x34\x72\xaa\x6a\x61\xee\xd0\xa6\x83\xa3\x9e\xe3\x23\x08\x06\x20\xea\x44\xa9\xf7\x44\x11\xae\x5c\xe9\x90\x30\x52\x8f\x9a\xb4\x9c\x79\xf2",
+ "\x29\x83\x87\xba\x8a\x3e\xb8\x8e\xe3\x6b\x42\x06\xe5\x41\x93\xbc\x58\x57\xf2\xa3\x03\xce\x41\xdf\xf7\xc3\xbd\x53\xef\x7e\xe3\xd3\x4a\xe7\xe0\xc7\x14\x31\x1a\x7b\xd8\xd2\x55\x02\xca\xb4\x14\xb7",
+ 199 },
+ { GCRY_MD_SHA3_384,
+ "\x8c\x37\x98\xe5\x1b\xc6\x84\x82\xd7\x33\x7d\x3a\xbb\x75\xdc\x9f\xfe\x86\x07\x14\xa9\xad\x73\x55\x1e\x12\x00\x59\x86\x0d\xde\x24\xab\x87\x32\x72\x22\xb6\x4c\xf7\x74\x41\x5a\x70\xf7\x24\xcd\xf2\x70\xde\x3f\xe4\x7d\xda\x07\xb6\x1c\x9e\xf2\xa3\x55\x1f\x45\xa5\x58\x48\x60\x24\x8f\xab\xde\x67\x6e\x1c\xd7\x5f\x63\x55\xaa\x3e\xae\xab\xe3\xb5\x1d\xc8\x13\xd9\xfb\x2e\xaa\x4f\x0f\x1d\x9f\x83\x4d\x7c\xad\x9c\x7c\x69\x5a\xe8\x4b\x32\x93\x85\xbc\x0b\xef\x89\x5b\x9f\x1e\xdf\x44\xa0\x3d\x4b\x41\x0c\xc2\x3a\x79\xa6\xb6\x2e\x4f\x34\x6a\x5e\x8d\xd8\x51\xc2\x85\x79\x95\xdd\xbf\x5b\x2d\x71\x7a\xeb\x84\x73\x10\xe1\xf6\xa4\x6a\xc3\xd2\x6a\x7f\x9b\x44\x98\x5a\xf6\x56\xd2\xb7\xc9\x40\x6e\x8a\x9e\x8f\x47\xdc\xb4\xef\x6b\x83\xca\xac\xf9\xae\xfb\x61\x18\xbf\xcf\xf7\xe4\x4b\xef\x69\x37\xeb\xdd\xc8\x91\x86\x83\x9b\x77",
+ "\x27\xce\xf6\x5d\x1a\xec\xb7\x05\x1b\xad\x55\xda\x0d\x60\x1b\xc9\xd7\xa1\x6d\x93\x8a\x57\x15\x37\x4a\x43\x10\x9d\xd4\x1b\x5c\x27\xd2\x6c\x91\xcb\x44\xe4\xb4\x70\x02\xd9\xb9\x0a\xba\x05\x84\xd1",
+ 200 },
+ { GCRY_MD_SHA3_384,
+ "\xfa\x56\xbf\x73\x0c\x4f\x83\x95\x87\x51\x89\xc1\x0c\x4f\xb2\x51\x60\x57\x57\xa8\xfe\xcc\x31\xf9\x73\x7e\x3c\x25\x03\xb0\x26\x08\xe6\x73\x1e\x85\xd7\xa3\x83\x93\xc6\x7d\xe5\x16\xb8\x53\x04\x82\x4b\xfb\x13\x5e\x33\xbf\x22\xb3\xa2\x3b\x91\x3b\xf6\xac\xd2\xb7\xab\x85\x19\x8b\x81\x87\xb2\xbc\xd4\x54\xd5\xe3\x31\x8c\xac\xb3\x2f\xd6\x26\x1c\x31\xae\x7f\x6c\x54\xef\x6a\x7a\x2a\x4c\x9f\x3e\xcb\x81\xce\x35\x55\xd4\xf0\xad\x46\x6d\xd4\xc1\x08\xa9\x03\x99\xd7\x00\x41\x99\x7c\x3b\x25\x34\x5a\x96\x53\xf3\xc9\xa6\x71\x1a\xb1\xb9\x1d\x6a\x9d\x22\x16\x44\x2d\xa2\xc9\x73\xcb\xd6\x85\xee\x76\x43\xbf\xd7\x73\x27\xa2\xf7\xae\x9c\xb2\x83\x62\x0a\x08\x71\x6d\xfb\x46\x2e\x5c\x1d\x65\x43\x2c\xa9\xd5\x6a\x90\xe8\x11\x44\x3c\xd1\xec\xb8\xf0\xde\x17\x9c\x9c\xb4\x8b\xa4\xf6\xfe\xc3\x60\xc6\x6f\x25\x2f\x6e\x64\xed\xc9\x6b",
+ "\x4a\xc9\xbd\xfd\x9f\x71\x7d\x01\x59\x89\x08\xba\x45\x76\x27\xd3\xaf\x7c\x81\x23\xf7\x11\x0d\xd7\xfd\xb4\x0e\x91\xee\x6c\xac\x20\x1a\x8b\x72\x8a\x38\x4e\x66\x38\x90\x84\x7d\xfd\x4d\xe7\xfa\x76",
+ 201 },
+ { GCRY_MD_SHA3_384,
+ "\xb6\x13\x4f\x9c\x3e\x91\xdd\x80\x00\x74\x0d\x00\x9d\xd8\x06\x24\x08\x11\xd5\x1a\xb1\x54\x6a\x97\x4b\xcb\x18\xd3\x44\x64\x2b\xaa\x5c\xd5\x90\x3a\xf8\x4d\x58\xec\x5b\xa1\x73\x01\xd5\xec\x0f\x10\xcc\xd0\x50\x9c\xbb\x3f\xd3\xff\xf9\x17\x2d\x19\x3a\xf0\xf7\x82\x25\x2f\xd1\x33\x8c\x72\x44\xd4\x0e\x0e\x42\x36\x22\x75\xb2\x2d\x01\xc4\xc3\x38\x9f\x19\xdd\x69\xbd\xf9\x58\xeb\xe2\x8e\x31\xa4\xff\xe2\xb5\xf1\x8a\x87\x83\x1c\xfb\x70\x95\xf5\x8a\x87\xc9\xfa\x21\xdb\x72\xba\x26\x93\x79\xb2\xdc\x23\x84\xb3\xda\x95\x3c\x79\x25\x76\x1f\xed\x32\x46\x20\xac\xea\x43\x5e\x52\xb4\x24\xa7\x72\x3f\x6a\x23\x57\x37\x41\x57\xa3\x4c\xd8\x25\x23\x51\xc2\x5a\x1b\x23\x28\x26\xce\xfe\x1b\xd3\xe7\x0f\xfc\x15\xa3\x1e\x7c\x05\x98\x21\x9d\x7f\x00\x43\x62\x94\xd1\x18\x91\xb8\x24\x97\xbc\x78\xaa\x53\x63\x89\x2a\x24\x95\xdf\x8c\x1e\xef",
+ "\xf0\x3f\xa0\x3e\x4c\xf9\xc2\x34\x43\xd7\xdb\xdb\xb6\x6d\x9a\xbb\xaf\xef\xb6\x50\x01\x43\xff\x0b\xfb\x5d\x7d\x6c\xa2\xbf\x1d\x7c\xd0\x43\xa7\xba\x7e\xfb\x48\xf1\x5e\xbc\x68\xd1\xf9\x45\x98\xe7",
+ 202 },
+ { GCRY_MD_SHA3_384,
+ "\xc9\x41\xcd\xb9\xc2\x8a\xb0\xa7\x91\xf2\xe5\xc8\xe8\xbb\x52\x85\x06\x26\xaa\x89\x20\x5b\xec\x3a\x7e\x22\x68\x23\x13\xd1\x98\xb1\xfa\x33\xfc\x72\x95\x38\x13\x54\x85\x87\x58\xae\x6c\x8e\xc6\xfa\xc3\x24\x5c\x6e\x45\x4d\x16\xfa\x2f\x51\xc4\x16\x6f\xab\x51\xdf\x27\x28\x58\xf2\xd6\x03\x77\x0c\x40\x98\x7f\x64\x44\x2d\x48\x7a\xf4\x9c\xd5\xc3\x99\x1c\xe8\x58\xea\x2a\x60\xda\xb6\xa6\x5a\x34\x41\x49\x65\x93\x39\x73\xac\x24\x57\x08\x9e\x35\x91\x60\xb7\xcd\xed\xc4\x2f\x29\xe1\x0a\x91\x92\x17\x85\xf6\xb7\x22\x4e\xe0\xb3\x49\x39\x3c\xdc\xff\x61\x51\xb5\x0b\x37\x7d\x60\x95\x59\x92\x3d\x09\x84\xcd\xa6\x00\x08\x29\xb9\x16\xab\x68\x96\x69\x3e\xf6\xa2\x19\x9b\x3c\x22\xf7\xdc\x55\x00\xa1\x5b\x82\x58\x42\x0e\x31\x4c\x22\x2b\xc0\x00\xbc\x4e\x54\x13\xe6\xdd\x82\xc9\x93\xf8\x33\x0f\x5c\x6d\x1b\xe4\xbc\x79\xf0\x8a\x1a\x0a\x46",
+ "\x9c\x77\x9d\x98\x1f\x9b\x7e\x49\x1f\xf8\x68\xbe\x22\xb3\x7f\xa9\xdf\x72\xde\x55\x67\x2a\x02\x26\xa8\x21\xb2\x9c\x04\x5d\xf4\xff\x78\x8f\xa7\x27\x1d\x55\x7e\xf6\x02\x5e\xea\x25\x58\x09\xf2\x41",
+ 203 },
+ { GCRY_MD_SHA3_384,
+ "\x44\x99\xef\xff\xac\x4b\xce\xa5\x27\x47\xef\xd1\xe4\xf2\x0b\x73\xe4\x87\x58\xbe\x91\x5c\x88\xa1\xff\xe5\x29\x9b\x0b\x00\x58\x37\xa4\x6b\x2f\x20\xa9\xcb\x3c\x6e\x64\xa9\xe3\xc5\x64\xa2\x7c\x0f\x1c\x6a\xd1\x96\x03\x73\x03\x6e\xc5\xbf\xe1\xa8\xfc\x6a\x43\x5c\x21\x85\xed\x0f\x11\x4c\x50\xe8\xb3\xe4\xc7\xed\x96\xb0\x6a\x03\x68\x19\xc9\x46\x3e\x86\x4a\x58\xd6\x28\x6f\x78\x5e\x32\xa8\x04\x44\x3a\x56\xaf\x0b\x4d\xf6\xab\xc5\x7e\xd5\xc2\xb1\x85\xdd\xee\x84\x89\xea\x08\x0d\xee\xee\x66\xaa\x33\xc2\xe6\xda\xb3\x62\x51\xc4\x02\x68\x2b\x68\x24\x82\x1f\x99\x8c\x32\x16\x31\x64\x29\x8e\x1f\xaf\xd3\x1b\xab\xbc\xff\xb5\x94\xc9\x18\x88\xc6\x21\x90\x79\xd9\x07\xfd\xb4\x38\xed\x89\x52\x9d\x6d\x96\x21\x2f\xd5\x5a\xbe\x20\x39\x9d\xbe\xfd\x34\x22\x48\x50\x74\x36\x93\x1c\xde\xad\x49\x6e\xb6\xe4\xa8\x03\x58\xac\xc7\x86\x47\xd0\x43",
+ "\x2c\x0b\xc5\x4a\x67\xb0\x0a\xd7\x03\xfc\x59\x57\x51\x07\x4c\x4e\x44\x7e\xfd\xe0\x0c\xaa\xf8\xc8\xfc\xad\xf5\x76\x8c\x33\x0b\x6c\x7f\x19\x18\xf0\x44\xf5\xc5\xc5\x58\x10\xd0\x78\x53\x4a\x7b\xb3",
+ 204 },
+ { GCRY_MD_SHA3_384,
+ "\xee\xcb\xb8\xfd\xfa\x4d\xa6\x21\x70\xfd\x06\x72\x7f\x69\x7d\x81\xf8\x3f\x60\x1f\xf6\x1e\x47\x81\x05\xd3\xcb\x75\x02\xf2\xc8\x9b\xf3\xe8\xf5\x6e\xdd\x46\x9d\x04\x98\x07\xa3\x88\x82\xa7\xee\xfb\xc8\x5f\xc9\xa9\x50\x95\x2e\x9f\xa8\x4b\x8a\xfe\xbd\x3c\xe7\x82\xd4\xda\x59\x80\x02\x82\x7b\x1e\xb9\x88\x82\xea\x1f\x0a\x8f\x7a\xa9\xce\x01\x3a\x6e\x9b\xc4\x62\xfb\x66\xc8\xd4\xa1\x8d\xa2\x14\x01\xe1\xb9\x33\x56\xeb\x12\xf3\x72\x5b\x6d\xb1\x68\x4f\x23\x00\xa9\x8b\x9a\x11\x9e\x5d\x27\xff\x70\x4a\xff\xb6\x18\xe1\x27\x08\xe7\x7e\x6e\x5f\x34\x13\x9a\x5a\x41\x13\x1f\xd1\xd6\x33\x6c\x27\x2a\x8f\xc3\x70\x80\xf0\x41\xc7\x13\x41\xbe\xe6\xab\x55\x0c\xb4\xa2\x0a\x6d\xdb\x6a\x8e\x02\x99\xf2\xb1\x4b\xc7\x30\xc5\x4b\x8b\x1c\x1c\x48\x7b\x49\x4b\xdc\xcf\xd3\xa5\x35\x35\xab\x2f\x23\x15\x90\xbf\x2c\x40\x62\xfd\x2a\xd5\x8f\x90\x6a\x2d\x0d",
+ "\x2d\xb1\x9c\xa5\x57\x72\x3c\xd3\xc1\x7e\x7d\x81\x40\xca\x30\x1a\x5a\x2c\xb7\x7e\x3f\x1f\x59\x5f\x5b\x85\x0a\x78\x94\x3c\x7f\x36\xfc\x37\x05\x6d\xcf\x2b\xad\xb9\x0d\xda\x77\xbf\xa9\x69\xc0\xaa",
+ 205 },
+ { GCRY_MD_SHA3_384,
+ "\xe6\x4f\x3e\x4a\xce\x5c\x84\x18\xd6\x5f\xec\x2b\xc5\xd2\xa3\x03\xdd\x45\x80\x34\x73\x6e\x3b\x0d\xf7\x19\x09\x8b\xe7\xa2\x06\xde\xaf\x52\xd6\xba\x82\x31\x6c\xaf\x33\x0e\xf8\x52\x37\x51\x88\xcd\xe2\xb3\x9c\xc9\x4a\xa4\x49\x57\x8a\x7e\x2a\x8e\x3f\x5a\x9d\x68\xe8\x16\xb8\xd1\x68\x89\xfb\xc0\xeb\xf0\x93\x9d\x04\xf6\x30\x33\xae\x9a\xe2\xbd\xab\x73\xb8\x8c\x26\xd6\xbd\x25\xee\x46\x0e\xe1\xef\x58\xfb\x0a\xfa\x92\xcc\x53\x9f\x8c\x76\xd3\xd0\x97\xe7\xa6\xa6\x3e\xbb\x9b\x58\x87\xed\xf3\xcf\x07\x60\x28\xc5\xbb\xd5\xb9\xdb\x32\x11\x37\x1a\xd3\xfe\x12\x1d\x4e\x9b\xf4\x42\x29\xf4\xe1\xec\xf5\xa0\xf9\xf0\xeb\xa4\xd5\xce\xb7\x28\x78\xab\x22\xc3\xf0\xeb\x5a\x62\x53\x23\xac\x66\xf7\x06\x1f\x4a\x81\xfa\xc8\x34\x47\x1e\x0c\x59\x55\x3f\x10\x84\x75\xfe\x29\x0d\x43\xe6\xa0\x55\xae\x3e\xe4\x6f\xb6\x74\x22\xf8\x14\xa6\x8c\x4b\xe3\xe8\xc9",
+ "\x71\xe5\xdd\x07\x55\xcf\x8b\x82\xbc\x79\xae\xd6\xfb\x61\xc9\xe4\xff\x83\x61\xc9\xaf\xc5\xad\x98\x08\x08\xa8\xbc\x48\x0e\x09\xd5\x9b\x23\x40\x74\x47\x28\x51\x08\x07\x14\xe0\x27\x5c\xe7\x2d\xc5",
+ 206 },
+ { GCRY_MD_SHA3_384,
+ "\xd2\xcb\x2d\x73\x30\x33\xf9\xe9\x13\x95\x31\x28\x08\x38\x3c\xc4\xf0\xca\x97\x4e\x87\xec\x68\x40\x0d\x52\xe9\x6b\x3f\xa6\x98\x4a\xc5\x8d\x9a\xd0\x93\x8d\xde\x5a\x97\x30\x08\xd8\x18\xc4\x96\x07\xd9\xde\x22\x84\xe7\x61\x8f\x1b\x8a\xed\x83\x72\xfb\xd5\x2e\xd5\x45\x57\xaf\x42\x20\xfa\xc0\x9d\xfa\x84\x43\x01\x16\x99\xb9\x7d\x74\x3f\x8f\x2b\x1a\xef\x35\x37\xeb\xb4\x5d\xcc\x9e\x13\xdf\xb4\x38\x42\x8e\xe1\x90\xa4\xef\xdb\x3c\xae\xb7\xf3\x93\x31\x17\xbf\x63\xab\xdc\x7e\x57\xbe\xb4\x17\x1c\x7e\x1a\xd2\x60\xab\x05\x87\x80\x6c\x4d\x13\x7b\x63\x16\xb5\x0a\xbc\x9c\xce\x0d\xff\x3a\xca\xda\x47\xbb\xb8\x6b\xe7\x77\xe6\x17\xbb\xe5\x78\xff\x45\x19\x84\x4d\xb3\x60\xe0\xa9\x6c\x67\x01\x29\x0e\x76\xbb\x95\xd2\x6f\x0f\x80\x4c\x8a\x4f\x27\x17\xea\xc4\xe7\xde\x9f\x2c\xff\x3b\xbc\x55\xa1\x7e\x77\x6c\x0d\x02\x85\x60\x32\xa6\xcd\x10\xad\x28\x38",
+ "\x51\xf9\x51\xb8\xf1\x01\x3b\xa9\xbc\xed\x90\x47\x8e\x24\x8c\xd8\x9d\x4d\xeb\xc6\xa1\x9c\xeb\x6e\xf8\x1b\xa1\xa5\xd8\xd3\x33\x9d\x42\x6d\x50\xa9\x4c\x7c\xe3\xd1\x43\xc4\x5d\xec\xce\xf9\x49\x65",
+ 207 },
+ { GCRY_MD_SHA3_384,
+ "\xf2\x99\x89\x55\x61\x3d\xd4\x14\xcc\x11\x1d\xf5\xce\x30\xa9\x95\xbb\x79\x2e\x26\x0b\x0e\x37\xa5\xb1\xd9\x42\xfe\x90\x17\x1a\x4a\xc2\xf6\x6d\x49\x28\xd7\xad\x37\x7f\x4d\x05\x54\xcb\xf4\xc5\x23\xd2\x1f\x6e\x5f\x37\x9d\x6f\x4b\x02\x8c\xdc\xb9\xb1\x75\x8d\x3b\x39\x66\x32\x42\xff\x3c\xb6\xed\xe6\xa3\x6a\x6f\x05\xdb\x3b\xc4\x1e\x0d\x86\x1b\x38\x4b\x6d\xec\x58\xbb\x09\x6d\x0a\x42\x2f\xd5\x42\xdf\x17\x5e\x1b\xe1\x57\x1f\xb5\x2a\xe6\x6f\x2d\x86\xa2\xf6\x82\x4a\x8c\xfa\xac\xba\xc4\xa7\x49\x2a\xd0\x43\x3e\xeb\x15\x45\x4a\xf8\xf3\x12\xb3\xb2\xa5\x77\x75\x0e\x3e\xfb\xd3\x70\xe8\xa8\xca\xc1\x58\x25\x81\x97\x1f\xba\x3b\xa4\xbd\x0d\x76\xe7\x18\xda\xcf\x84\x33\xd3\x3a\x59\xd2\x87\xf8\xcc\x92\x23\x4e\x7a\x27\x10\x41\xb5\x26\xe3\x89\xef\xb0\xe4\x0b\x6a\x18\xb3\xaa\xf6\x58\xe8\x2e\xd1\xc7\x86\x31\xfd\x23\xb4\xc3\xeb\x27\xc3\xfa\xec\x86\x85",
+ "\x21\x0e\xbc\x15\x56\xe3\x1a\x27\xea\xf6\x0a\x5f\xe3\xe1\x81\x13\x5c\x5e\xa1\x17\xe3\xff\x21\xaf\x2d\x04\xbe\xab\x9a\x24\x3f\xff\xf6\x32\xe3\xd7\x77\x8f\x9a\x6d\x03\x04\xc1\xac\xf3\x65\x9a\x3c",
+ 208 },
+ { GCRY_MD_SHA3_384,
+ "\x44\x77\x97\xe2\x89\x9b\x72\xa3\x56\xba\x55\xbf\x4d\xf3\xac\xca\x6c\xdb\x10\x41\xeb\x47\x7b\xd1\x83\x4a\x9f\x9a\xcb\xc3\x40\xa2\x94\xd7\x29\xf2\xf9\x7d\xf3\xa6\x10\xbe\x0f\xf1\x5e\xdb\x9c\x6d\x5d\xb4\x16\x44\xb9\x87\x43\x60\x14\x0f\xc6\x4f\x52\xaa\x03\xf0\x28\x6c\x8a\x64\x06\x70\x06\x7a\x84\xe0\x17\x92\x6a\x70\x43\x8d\xb1\xbb\x36\x1d\xef\xee\x73\x17\x02\x14\x25\xf8\x82\x1d\xef\x26\xd1\xef\xd7\x7f\xc8\x53\xb8\x18\x54\x5d\x05\x5a\xdc\x92\x84\x79\x6e\x58\x3c\x76\xe6\xfe\x74\xc9\xac\x25\x87\xaa\x46\xaa\x8f\x88\x04\xf2\xfe\xb5\x83\x6c\xc4\xb3\xab\xab\xab\x84\x29\xa5\x78\x3e\x17\xd5\x99\x9f\x32\x24\x2e\xb5\x9e\xf3\x0c\xd7\xad\xab\xc1\x6d\x72\xdb\xdb\x09\x76\x23\x04\x7c\x98\x98\x9f\x88\xd1\x4e\xaf\x02\xa7\x21\x2b\xe1\x6e\xc2\xd0\x79\x81\xaa\xa9\x99\x49\xdd\xf8\x9e\xcd\x90\x33\x3a\x77\xbc\x4e\x19\x88\xa8\x2a\xbf\x7c\x7c\xaf\x32\x91",
+ "\xf5\xf6\x59\xf6\x99\x9b\xad\x8c\xdc\x77\xc4\x29\x01\xa8\xd6\x4c\x1f\xa8\x27\xf7\x84\x89\x85\x13\x61\x40\xbf\x5d\x4b\x3b\xbb\x3d\x96\x4d\x2d\x81\x56\xf9\xfd\x02\xb6\xd3\x82\xbc\x84\x10\xa8\x8e",
+ 209 },
+ { GCRY_MD_SHA3_384,
+ "\x9f\x2c\x18\xad\xe9\xb3\x80\xc7\x84\xe1\x70\xfb\x76\x3e\x9a\xa2\x05\xf6\x43\x03\x06\x7e\xb1\xbc\xea\x93\xdf\x5d\xac\x4b\xf5\xa2\xe0\x0b\x78\x19\x5f\x80\x8d\xf2\x4f\xc7\x6e\x26\xcb\x7b\xe3\x1d\xc3\x5f\x08\x44\xcd\xed\x15\x67\xbb\xa2\x98\x58\xcf\xfc\x97\xfb\x29\x01\x03\x31\xb0\x1d\x6a\x3f\xb3\x15\x9c\xc1\xb9\x73\xd2\x55\xda\x98\x43\xe3\x4a\x0a\x40\x61\xca\xbd\xb9\xed\x37\xf2\x41\xbf\xab\xb3\xc2\x0d\x32\x74\x3f\x40\x26\xb5\x9a\x4c\xcc\x38\x5a\x23\x01\xf8\x3c\x0b\x0a\x19\x0b\x0f\x2d\x01\xac\xb8\xf0\xd4\x11\x11\xe1\x0f\x2f\x4e\x14\x93\x79\x27\x55\x99\xa5\x2d\xc0\x89\xb3\x5f\xdd\x52\x34\xb0\xcf\xb7\xb6\xd8\xae\xbd\x56\x3c\xa1\xfa\x65\x3c\x5c\x02\x1d\xfd\x6f\x59\x20\xe6\xf1\x8b\xfa\xfd\xbe\xcb\xf0\xab\x00\x28\x13\x33\xed\x50\xb9\xa9\x99\x54\x9c\x1c\x8f\x8c\x63\xd7\x62\x6c\x48\x32\x2e\x97\x91\xd5\xff\x72\x29\x40\x49\xbd\xe9\x1e\x73\xf8",
+ "\xb1\x51\xbf\x98\xc5\x2f\x63\xf2\x94\xa4\xb1\xe9\x90\xc8\x6c\xb7\x3c\x4b\xdd\x47\x6b\x25\xc1\x38\xca\x66\xb2\xba\x08\x44\x75\x40\xb0\xa7\x87\xdf\xdd\xaa\x3d\x38\xaf\x44\xca\x8e\xbb\xed\x74\xd8",
+ 210 },
+ { GCRY_MD_SHA3_384,
+ "\xae\x15\x9f\x3f\xa3\x36\x19\x00\x2a\xe6\xbc\xce\x8c\xbb\xdd\x7d\x28\xe5\xed\x9d\x61\x53\x45\x95\xc4\xc9\xf4\x3c\x40\x2a\x9b\xb3\x1f\x3b\x30\x1c\xbf\xd4\xa4\x3c\xe4\xc2\x4c\xd5\xc9\x84\x9c\xc6\x25\x9e\xca\x90\xe2\xa7\x9e\x01\xff\xba\xc0\x7b\xa0\xe1\x47\xfa\x42\x67\x6a\x1d\x66\x85\x70\xe0\x39\x63\x87\xb5\xbc\xd5\x99\xe8\xe6\x6a\xae\xd1\xb8\xa1\x91\xc5\xa4\x75\x47\xf6\x13\x73\x02\x1f\xa6\xde\xad\xcb\x55\x36\x3d\x23\x3c\x24\x44\x0f\x2c\x73\xdb\xb5\x19\xf7\xc9\xfa\x5a\x89\x62\xef\xd5\xf6\x25\x2c\x04\x07\xf1\x90\xdf\xef\xad\x70\x7f\x3c\x70\x07\xd6\x9f\xf3\x6b\x84\x89\xa5\xb6\xb7\xc5\x57\xe7\x9d\xd4\xf5\x0c\x06\x51\x1f\x59\x9f\x56\xc8\x96\xb3\x5c\x91\x7b\x63\xba\x35\xc6\xff\x80\x92\xba\xf7\xd1\x65\x8e\x77\xfc\x95\xd8\xa6\xa4\x3e\xeb\x4c\x01\xf3\x3f\x03\x87\x7f\x92\x77\x4b\xe8\x9c\x11\x14\xdd\x53\x1c\x01\x1e\x53\xa3\x4d\xc2\x48\xa2\xf0\xe6",
+ "\x47\xd7\x4f\xdd\x9a\x19\xa5\x38\x93\x13\x61\x06\x43\xfa\x85\x9f\xf0\xbd\x7b\x58\x3b\x09\x9f\xdd\xb9\xc9\x80\xdc\xc0\x00\xaf\xeb\x63\x9d\xd9\x90\x71\xea\x31\x97\x6d\xa3\x5b\x7b\xc9\x49\xbd\x4e",
+ 211 },
+ { GCRY_MD_SHA3_384,
+ "\x3b\x8e\x97\xc5\xff\xc2\xd6\xa4\x0f\xa7\xde\x7f\xce\xfc\x90\xf3\xb1\x2c\x94\x0e\x7a\xb4\x15\x32\x1e\x29\xee\x69\x2d\xfa\xc7\x99\xb0\x09\xc9\x9d\xcd\xdb\x70\x8f\xce\x5a\x17\x8c\x5c\x35\xee\x2b\x86\x17\x14\x3e\xdc\x4c\x40\xb4\xd3\x13\x66\x1f\x49\xab\xdd\x93\xce\xa7\x9d\x11\x75\x18\x80\x54\x96\xfe\x6a\xcf\x29\x2c\x4c\x2a\x1f\x76\xb4\x03\xa9\x7d\x7c\x39\x9d\xaf\x85\xb4\x6a\xd8\x4e\x16\x24\x6c\x67\xd6\x83\x67\x57\xbd\xe3\x36\xc2\x90\xd5\xd4\x01\xe6\xc1\x38\x6a\xb3\x27\x97\xaf\x6b\xb2\x51\xe9\xb2\xd8\xfe\x75\x4c\x47\x48\x2b\x72\xe0\xb3\x94\xea\xb7\x69\x16\x12\x6f\xd6\x8e\xa7\xd6\x5e\xb9\x3d\x59\xf5\xb4\xc5\xac\x40\xf7\xc3\xb3\x7e\x7f\x36\x94\xf2\x94\x24\xc2\x4a\xf8\xc8\xf0\xef\x59\xcd\x9d\xbf\x1d\x28\xe0\xe1\x0f\x79\x9a\x6f\x78\xca\xd1\xd4\x5b\x9d\xb3\xd7\xde\xe4\xa7\x05\x9a\xbe\x99\x18\x27\x14\x98\x3b\x9c\x9d\x44\xd7\xf5\x64\x35\x96\xd4\xf3",
+ "\x9b\x80\x91\x98\xdc\xce\x24\x17\x5e\x33\x09\x83\x31\xd3\xa4\x02\xa8\x21\xae\x93\x26\xe7\x27\x75\xaa\xe3\x4d\x1a\x9b\xb5\x3d\x2b\x57\x86\x39\x05\xcf\xd6\x05\x43\xbb\xc4\x2b\x45\x40\x07\xc3\x15",
+ 212 },
+ { GCRY_MD_SHA3_384,
+ "\x34\x34\xec\x31\xb1\x0f\xaf\xdb\xfe\xec\x0d\xd6\xbd\x94\xe8\x0f\x7b\xa9\xdc\xa1\x9e\xf0\x75\xf7\xeb\x01\x75\x12\xaf\x66\xd6\xa4\xbc\xf7\xd1\x6b\xa0\x81\x9a\x18\x92\xa6\x37\x2f\x9b\x35\xbc\xc7\xca\x81\x55\xee\x19\xe8\x42\x8b\xc2\x2d\x21\x48\x56\xed\x5f\xa9\x37\x4c\x3c\x09\xbd\xe1\x69\x60\x2c\xc2\x19\x67\x9f\x65\xa1\x56\x6f\xc7\x31\x6f\x4c\xc3\xb6\x31\xa1\x8f\xb4\x44\x9f\xa6\xaf\xa1\x6a\x3d\xb2\xbc\x42\x12\xef\xf5\x39\xc6\x7c\xf1\x84\x68\x08\x26\x53\x55\x89\xc7\x11\x1d\x73\xbf\xfc\xe4\x31\xb4\xc4\x04\x92\xe7\x63\xd9\x27\x95\x60\xaa\xa3\x8e\xb2\xdc\x14\xa2\x12\xd7\x23\xf9\x94\xa1\xfe\x65\x6f\xf4\xdd\x14\x55\x1c\xe4\xe7\xc6\x21\xb2\xaa\x56\x04\xa1\x00\x01\xb2\x87\x8a\x89\x7a\x28\xa0\x80\x95\xc3\x25\xe1\x0a\x26\xd2\xfb\x1a\x75\xbf\xd6\x4c\x25\x03\x09\xbb\x55\xa4\x4f\x23\xbb\xac\x0d\x55\x16\xa1\xc6\x87\xd3\xb4\x1e\xf2\xfb\xbf\x9c\xc5\x6d\x47\x39",
+ "\x93\xc9\x83\x45\x01\xfc\x72\x85\x08\xa1\x5e\xb9\x20\x5e\x67\x89\x83\xf3\xbd\xb0\xba\x44\x7e\xe7\x39\xae\x50\x82\xdb\x37\xf2\xf2\xd4\x85\x08\x81\x30\xe0\xb1\xcb\xf0\x03\x9d\x18\xbd\xf4\x29\xf7",
+ 213 },
+ { GCRY_MD_SHA3_384,
+ "\x7c\x79\x53\xd8\x1c\x8d\x20\x8f\xd1\xc9\x76\x81\xd4\x8f\x49\xdd\x00\x34\x56\xde\x60\x47\x5b\x84\x07\x0e\xf4\x84\x7c\x33\x3b\x74\x57\x5b\x1f\xc8\xd2\xa1\x86\x96\x44\x85\xa3\xb8\x63\x4f\xea\xa3\x59\x5a\xaa\x1a\x2f\x45\x95\xa7\xd6\xb6\x15\x35\x63\xde\xe3\x1b\xba\xc4\x43\xc8\xa3\x3e\xed\x6d\x5d\x95\x6a\x98\x0a\x68\x36\x6c\x25\x27\xb5\x50\xee\x95\x02\x50\xdf\xb6\x91\xea\xcb\xd5\xd5\x6a\xe1\x4b\x97\x06\x68\xbe\x17\x4c\x89\xdf\x2f\xea\x43\xae\x52\xf1\x31\x42\x63\x9c\x88\x4f\xd6\x2a\x36\x83\xc0\xc3\x79\x2f\x0f\x24\xab\x13\x18\xbc\xb2\x7e\x21\xf4\x73\x7f\xab\x62\xc7\x7e\xa3\x8b\xc8\xfd\x1c\xf4\x1f\x7d\xab\x64\xc1\x3f\xeb\xe7\x15\x2b\xf5\xbb\x7a\xb5\xa7\x8f\x53\x46\xd4\x3c\xc7\x41\xcb\x6f\x72\xb7\xb8\x98\x0f\x26\x8b\x68\xbf\x62\xab\xdf\xb1\x57\x7a\x52\x43\x8f\xe1\x4b\x59\x14\x98\xcc\x95\xf0\x71\x22\x84\x60\xc7\xc5\xd5\xce\xb4\xa7\xbd\xe5\x88\xe7\xf2\x1c",
+ "\xc0\xad\x8c\x3e\x7e\xa5\x95\x10\x4d\x4b\xc0\xa0\x8d\xcb\xc8\x50\x42\xed\x50\xdd\x8d\x9b\x01\xab\x47\xc9\xf0\x66\xf9\x1a\xd3\xbf\xfe\xde\x41\x07\xf1\xeb\x1f\x5b\x61\xca\x7d\x40\x91\xd6\x83\x27",
+ 214 },
+ { GCRY_MD_SHA3_384,
+ "\x7a\x6a\x4f\x4f\xdc\x59\xa1\xd2\x23\x38\x1a\xe5\xaf\x49\x8d\x74\xb7\x25\x2e\xcf\x59\xe3\x89\xe4\x91\x30\xc7\xea\xee\x62\x6e\x7b\xd9\x89\x7e\xff\xd9\x20\x17\xf4\xcc\xde\x66\xb0\x44\x04\x62\xcd\xed\xfd\x35\x2d\x81\x53\xe6\xa4\xc8\xd7\xa0\x81\x2f\x70\x1c\xc7\x37\xb5\x17\x8c\x25\x56\xf0\x71\x11\x20\x0e\xb6\x27\xdb\xc2\x99\xca\xa7\x92\xdf\xa5\x8f\x35\x93\x52\x99\xfa\x3a\x35\x19\xe9\xb0\x31\x66\xdf\xfa\x15\x91\x03\xff\xa3\x5e\x85\x77\xf7\xc0\xa8\x6c\x6b\x46\xfe\x13\xdb\x8e\x2c\xdd\x9d\xcf\xba\x85\xbd\xdd\xcc\xe0\xa7\xa8\xe1\x55\xf8\x1f\x71\x2d\x8e\x9f\xe6\x46\x15\x3d\x3d\x22\xc8\x11\xbd\x39\xf8\x30\x43\x3b\x22\x13\xdd\x46\x30\x19\x41\xb5\x92\x93\xfd\x0a\x33\xe2\xb6\x3a\xdb\xd9\x52\x39\xbc\x01\x31\x5c\x46\xfd\xb6\x78\x87\x5b\x3c\x81\xe0\x53\xa4\x0f\x58\x1c\xfb\xec\x24\xa1\x40\x4b\x16\x71\xa1\xb8\x8a\x6d\x06\x12\x02\x29\x51\x8f\xb1\x3a\x74\xca\x0a\xc5\xae",
+ "\xaa\x8d\xaa\x02\xab\xcb\xc5\xa4\xb3\x00\x3b\xff\x5c\xbc\x2c\x84\x59\x4c\x5a\x0f\x84\xbd\x44\x9a\x1a\x56\xbe\x59\x56\x6e\x13\xec\x68\x03\x01\x0d\x42\x2a\x4c\x24\x4b\x99\x81\x2f\x45\x37\xc9\x3d",
+ 215 },
+ { GCRY_MD_SHA3_384,
+ "\xd9\xfa\xa1\x4c\xeb\xe9\xb7\xde\x55\x1b\x6c\x07\x65\x40\x9a\x33\x93\x85\x62\x01\x3b\x5e\x8e\x0e\x1e\x0a\x64\x18\xdf\x73\x99\xd0\xa6\xa7\x71\xfb\x81\xc3\xca\x9b\xd3\xbb\x8e\x29\x51\xb0\xbc\x79\x25\x25\xa2\x94\xeb\xd1\x08\x36\x88\x80\x6f\xe5\xe7\xf1\xe1\x7f\xd4\xe3\xa4\x1d\x00\xc8\x9e\x8f\xcf\x4a\x36\x3c\xae\xdb\x1a\xcb\x55\x8e\x3d\x56\x2f\x13\x02\xb3\xd8\x3b\xb8\x86\xed\x27\xb7\x60\x33\x79\x81\x31\xda\xb0\x5b\x42\x17\x38\x1e\xaa\xa7\xba\x15\xec\x82\x0b\xb5\xc1\x3b\x51\x6d\xd6\x40\xea\xec\x5a\x27\xd0\x5f\xdf\xca\x0f\x35\xb3\xa5\x31\x21\x46\x80\x6b\x4c\x02\x75\xbc\xd0\xaa\xa3\xb2\x01\x7f\x34\x69\x75\xdb\x56\x6f\x9b\x4d\x13\x7f\x4e\xe1\x06\x44\xc2\xa2\xda\x66\xde\xec\xa5\x34\x2e\x23\x64\x95\xc3\xc6\x28\x05\x28\xbf\xd3\x2e\x90\xaf\x4c\xd9\xbb\x90\x8f\x34\x01\x2b\x52\xb4\xbc\x56\xd4\x8c\xc8\xa6\xb5\x9b\xab\x01\x49\x88\xea\xbd\x12\xe1\xa0\xa1\xc2\xe1\x70\xe7",
+ "\xca\xeb\x4f\x82\x9a\x92\x56\x79\x41\x6f\x7c\xb1\x77\xed\x4c\x99\x72\x1b\x85\x1a\xb5\x9d\x52\x97\x9b\xfe\xc6\xd2\xaa\xa1\xe6\x02\xf4\x31\x0b\x15\x62\x4f\x9d\x7b\xf2\xd3\x51\xdb\x73\xbf\xb5\xea",
+ 216 },
+ { GCRY_MD_SHA3_384,
+ "\x2d\x84\x27\x43\x3d\x0c\x61\xf2\xd9\x6c\xfe\x80\xcf\x1e\x93\x22\x65\xa1\x91\x36\x5c\x3b\x61\xaa\xa3\xd6\xdc\xc0\x39\xf6\xba\x2a\xd5\x2a\x6a\x8c\xc3\x0f\xc1\x0f\x70\x5e\x6b\x77\x05\x10\x59\x77\xfa\x49\x6c\x1c\x70\x8a\x27\x7a\x12\x43\x04\xf1\xfc\x40\x91\x1e\x74\x41\xd1\xb5\xe7\x7b\x95\x1a\xad\x7b\x01\xfd\x5d\xb1\xb3\x77\xd1\x65\xb0\x5b\xbf\x89\x80\x42\xe3\x96\x60\xca\xf8\xb2\x79\xfe\x52\x29\xd1\xa8\xdb\x86\xc0\x99\x9e\xd6\x5e\x53\xd0\x1c\xcb\xc4\xb4\x31\x73\xcc\xf9\x92\xb3\xa1\x45\x86\xf6\xba\x42\xf5\xfe\x30\xaf\xa8\xae\x40\xc5\xdf\x29\x96\x6f\x93\x46\xda\x5f\x8b\x35\xf1\x6a\x1d\xe3\xab\x6d\xe0\xf4\x77\xd8\xd8\x66\x09\x18\x06\x0e\x88\xb9\xb9\xe9\xca\x6a\x42\x07\x03\x3b\x87\xa8\x12\xdb\xf5\x54\x4d\x39\xe4\x88\x20\x10\xf8\x2b\x6c\xe0\x05\xf8\xe8\xff\x6f\xe3\xc3\x80\x6b\xc2\xb7\x3c\x2b\x83\xaf\xb7\x04\x34\x56\x29\x30\x4f\x9f\x86\x35\x87\x12\xe9\xfa\xe3\xca\x3e",
+ "\xfc\x1f\xc7\xf1\x9f\x6c\x9d\x0a\xd1\x46\x2b\x24\xc1\x21\xc8\x9b\x01\xb4\xe0\x83\xed\xad\x02\xa8\xdb\xde\xb9\x90\xd9\x8c\xaf\xe0\xaf\xe0\x1e\x2e\xba\x64\x68\x72\xcd\x81\x6b\x52\x03\xee\x8a\x87",
+ 217 },
+ { GCRY_MD_SHA3_384,
+ "\x5e\x19\xd9\x78\x87\xfc\xaa\xc0\x38\x7e\x22\xc6\xf8\x03\xc3\x4a\x3d\xac\xd2\x60\x41\x72\x43\x3f\x7a\x8a\x7a\x52\x6c\xa4\xa2\xa1\x27\x1e\xcf\xc5\xd5\xd7\xbe\x5a\xc0\xd8\x5d\x92\x10\x95\x35\x0d\xfc\x65\x99\x7d\x44\x3c\x21\xc8\x09\x4e\x0a\x3f\xef\xd2\x96\x1b\xcb\x94\xae\xd0\x32\x91\xae\x31\x0c\xcd\xa7\x5d\x8a\xce\x4b\xc7\xd8\x9e\x7d\x3e\x5d\x16\x50\xbd\xa5\xd6\x68\xb8\xb5\x0b\xfc\x8e\x60\x8e\x18\x4f\x4d\x3a\x9a\x2b\xad\xc4\xff\x5f\x07\xe0\xc0\xbc\x8a\x9f\x2e\x0b\x2a\x26\xfd\x6d\x8c\x55\x00\x08\xfa\xaa\xb7\x5f\xd7\x1a\xf2\xa4\x24\xbe\xc9\xa7\xcd\x9d\x83\xfa\xd4\xc8\xe9\x31\x91\x15\x65\x6a\x87\x17\xd3\xb5\x23\xa6\x8f\xf8\x00\x42\x58\xb9\x99\x0e\xd3\x62\x30\x84\x61\x80\x4b\xa3\xe3\xa7\xe9\x2d\x8f\x2f\xfa\xe5\xc2\xfb\xa5\x5b\xa5\xa3\xc2\x7c\x0a\x2f\x71\xbd\x71\x1d\x2f\xe1\x79\x9c\x2a\xdb\x31\xb2\x00\x03\x54\x81\xe9\xee\x5c\x4a\xdf\x2a\xb9\xc0\xfa\x50\xb2\x39\x75\xcf",
+ "\x84\x80\x3e\x50\xde\xc9\x01\xff\x93\x0c\x8a\x76\xeb\xc1\xf9\x8e\xc7\x28\x74\xde\xef\x0d\x24\x90\x20\xb1\xdb\xeb\x4e\xa7\xd8\xc7\xda\x47\x61\xed\xe0\x77\x15\x84\x60\xe0\x54\xa7\xf7\x1d\x19\x94",
+ 218 },
+ { GCRY_MD_SHA3_384,
+ "\xc8\xe9\x76\xab\x46\x38\x90\x93\x87\xce\x3b\x8d\x4e\x51\x0c\x32\x30\xe5\x69\x0e\x02\xc4\x50\x93\xb1\xd2\x97\x91\x0a\xbc\x48\x1e\x56\xee\xa0\xf2\x96\xf9\x83\x79\xdf\xc9\x08\x0a\xf6\x9e\x73\xb2\x39\x9d\x1c\x14\x3b\xee\x80\xae\x13\x28\x16\x2c\xe1\xba\x7f\x6a\x83\x74\x67\x9b\x20\xaa\xcd\x38\x0e\xb4\xe6\x13\x82\xc9\x99\x98\x70\x4d\x62\x70\x1a\xfa\x91\x4f\x9a\x27\x05\xcd\xb0\x65\x88\x5f\x50\xd0\x86\xc3\xeb\x57\x53\x70\x0c\x38\x71\x18\xbb\x14\x2f\x3e\x6d\xa1\xe9\x88\xdf\xb3\x1a\xc7\x5d\x73\x68\x93\x1e\x45\xd1\x39\x1a\x27\x4b\x22\xf8\x3c\xeb\x07\x2f\x9b\xca\xbc\x0b\x21\x66\x85\xbf\xd7\x89\xf5\x02\x39\x71\x02\x4b\x18\x78\xa2\x05\x44\x25\x22\xf9\xea\x7d\x87\x97\xa4\x10\x2a\x3d\xf4\x17\x03\x76\x82\x51\xfd\x5e\x01\x7c\x85\xd1\x20\x0a\x46\x41\x18\xaa\x35\x65\x4e\x7c\xa3\x9f\x3c\x37\x5b\x8e\xf8\xcb\xe7\x53\x4d\xbc\x64\xbc\x20\xbe\xfb\x41\x7c\xf6\x0e\xc9\x2f\x63\xd9\xee\x73\x97",
+ "\x05\x58\x6b\xcb\x80\x77\xe1\x9f\x3f\x43\x01\x52\x16\xd6\x23\xb1\x43\x9c\x49\xec\xdd\x3c\x53\x25\x55\x53\xe9\x13\x3f\xd1\xa9\x00\x88\x91\x52\x0d\x2e\xeb\xe5\x68\x4c\x54\x60\x28\xca\x2c\xdd\xfe",
+ 219 },
+ { GCRY_MD_SHA3_384,
+ "\x71\x45\xfa\x12\x4b\x74\x29\xa1\xfc\x22\x31\x23\x7a\x94\x9b\xa7\x20\x1b\xcc\x18\x22\xd3\x27\x2d\xe0\x05\xb6\x82\x39\x81\x96\xc2\x5f\x7e\x5c\xc2\xf2\x89\xfb\xf4\x44\x15\xf6\x99\xcb\x7f\xe6\x75\x77\x91\xb1\x44\x34\x10\x23\x4a\xe0\x61\xed\xf6\x23\x35\x9e\x2b\x4e\x32\xc1\x9b\xf8\x84\x50\x43\x2d\xd0\x1c\xaa\x5e\xb1\x6a\x1d\xc3\x78\xf3\x91\xca\x5e\x3c\x4e\x5f\x35\x67\x28\xbd\xdd\x49\x75\xdb\x7c\x89\x0d\xa8\xbb\xc8\x4c\xc7\x3f\xf2\x44\x39\x4d\x0d\x48\x95\x49\x78\x76\x5e\x4a\x00\xb5\x93\xf7\x0f\x2c\xa0\x82\x67\x3a\x26\x1e\xd8\x8d\xbc\xef\x11\x27\x72\x8d\x8c\xd8\x9b\xc2\xc5\x97\xe9\x10\x2c\xed\x60\x10\xf6\x5f\xa7\x5a\x14\xeb\xe4\x67\xfa\x57\xce\x3b\xd4\x94\x8b\x68\x67\xd7\x4a\x9d\xf5\xc0\xec\x6f\x53\x0c\xbf\x2e\xe6\x1c\xe6\xf0\x6b\xc8\xf2\x86\x4d\xff\x55\x83\x77\x6b\x31\xdf\x8c\x7f\xfc\xb6\x14\x28\xa5\x6b\xf7\xbd\x37\x18\x8b\x4a\x51\x23\xbb\xf3\x38\x39\x3a\xf4\x6e\xda\x85\xe6",
+ "\xa2\x00\xd8\xef\x3d\x12\x0b\x91\x75\x61\xed\xc8\x42\x0b\xde\x02\x2b\x3a\xce\x79\x29\x25\xc8\xfa\xbf\x25\xad\x9b\x0f\xa6\x76\xd2\x26\x0a\xbd\x80\x98\xf3\x83\xc0\xf9\x30\x43\xd5\xd3\xf5\x6c\x47",
+ 220 },
+ { GCRY_MD_SHA3_384,
+ "\x7f\xdf\xad\xcc\x9d\x29\xba\xd2\x3a\xe0\x38\xc6\xc6\x5c\xda\x1a\xef\x75\x72\x21\xb8\x87\x2e\xd3\xd7\x5f\xf8\xdf\x7d\xa0\x62\x7d\x26\x6e\x22\x4e\x81\x2c\x39\xf7\x98\x3e\x45\x58\xbf\xd0\xa1\xf2\xbe\xf3\xfe\xb5\x6b\xa0\x91\x20\xef\x76\x29\x17\xb9\xc0\x93\x86\x79\x48\x54\x7a\xee\x98\x60\x0d\x10\xd8\x7b\x20\x10\x68\x78\xa8\xd2\x2c\x64\x37\x8b\xf6\x34\xf7\xf7\x59\x00\xc0\x39\x86\xb0\x77\xb0\xbf\x8b\x74\x0a\x82\x44\x7b\x61\xb9\x9f\xee\x53\x76\xc5\xeb\x66\x80\xec\x9e\x30\x88\xf0\xbd\xd0\xc5\x68\x83\x41\x3d\x60\xc1\x35\x7d\x3c\x81\x19\x50\xe5\x89\x0e\x76\x00\x10\x3c\x91\x63\x41\xb8\x0c\x74\x3c\x6a\x85\x2b\x7b\x4f\xb6\x0c\x3b\xa2\x1f\x3b\xc1\x5b\x83\x82\x43\x7a\x68\x45\x47\x79\xcf\x3c\xd7\xf9\xf9\x0c\xcc\x8e\xf2\x8d\x0b\x70\x65\x35\xb1\xe4\x10\x8e\xb5\x62\x7b\xb4\x5d\x71\x9c\xb0\x46\x83\x9a\xee\x31\x1c\xa1\xab\xdc\x83\x19\xe0\x50\xd6\x79\x72\xcb\x35\xa6\xb1\x60\x1b\x25\xdb\xf4\x87",
+ "\xa8\x90\x5d\x1e\x9f\x4f\xc9\x6f\x2d\x76\x9d\x31\xc9\xa1\x20\xde\x43\xa0\xb2\x01\x15\xc8\xd1\x7b\xf0\x31\x32\x06\xeb\x9c\xd8\x7a\xe4\x1d\xf2\xd4\x44\xc9\xd7\x5f\x93\x66\x99\x82\x63\xd6\x1c\x07",
+ 221 },
+ { GCRY_MD_SHA3_384,
+ "\x98\x86\x38\x21\x9f\xd3\x09\x54\x21\xf8\x26\xf5\x6e\x4f\x09\xe3\x56\x29\x6b\x62\x8c\x3c\xe6\x93\x0c\x9f\x2e\x75\x8f\xd1\xa8\x0c\x82\x73\xf2\xf6\x1e\x4d\xaa\xe6\x5c\x4f\x11\x0d\x3e\x7c\xa0\x96\x5a\xc7\xd2\x4e\x34\xc0\xdc\x4b\xa2\xd6\xff\x0b\xf5\xbb\xe9\x3b\x35\x85\xf3\x54\xd7\x54\x3c\xb5\x42\xa1\xaa\x54\x67\x4d\x37\x50\x77\xf2\xd3\x60\xa8\xf4\xd4\x2f\x3d\xb1\x31\xc3\xb7\xab\x73\x06\x26\x7b\xa1\x07\x65\x98\x64\xa9\x0c\x8c\x90\x94\x60\xa7\x36\x21\xd1\xf5\xd9\xd3\xfd\x95\xbe\xb1\x9b\x23\xdb\x1c\xb6\xc0\xd0\xfb\xa9\x1d\x36\x89\x15\x29\xb8\xbd\x82\x63\xca\xa1\xba\xb5\x6a\x4a\xff\xae\xd4\x49\x62\xdf\x09\x6d\x8d\x5b\x1e\xb8\x45\xef\x31\x18\x8b\x3e\x10\xf1\xaf\x81\x1a\x13\xf1\x56\xbe\xb7\xa2\x88\xaa\xe5\x93\xeb\xd1\x47\x1b\x62\x4a\xa1\xa7\xc6\xad\xf0\x1e\x22\x00\xb3\xd7\x2d\x88\xa3\xae\xd3\x10\x0c\x88\x23\x1e\x41\xef\xc3\x76\x90\x6f\x0b\x58\x0d\xc8\x95\xf0\x80\xfd\xa5\x74\x1d\xb1\xcb",
+ "\x88\x24\x9a\xf8\x4a\x7f\x1e\x49\xd1\x44\x86\x9a\x3d\x4f\xe8\xaa\x6e\x1a\x48\x74\xee\x46\x7b\xc9\x9e\x9c\x33\xe2\x10\x5a\xf2\xd0\x97\x41\x7d\x6b\x78\x53\x79\x25\x39\x2d\xb2\xc5\xcb\x1e\x0b\x92",
+ 222 },
+ { GCRY_MD_SHA3_384,
+ "\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",
+ "\xc4\x61\x22\xd0\x0b\x61\xe7\x9d\xf0\x25\xa4\xd5\x25\xb8\xa6\x02\xc7\xac\x00\x43\x04\xa9\x93\x87\x2e\x3a\x8a\xa3\x7f\xc0\xe8\xea\xae\x5f\xad\x9a\x22\x0c\x5c\x6a\xfb\xd5\xa4\x78\x36\x80\x01\x3a",
+ 223 },
+ { GCRY_MD_SHA3_384,
+ "\x47\xb8\x21\x6a\xa0\xfb\xb5\xd6\x79\x66\xf2\xe8\x2c\x17\xc0\x7a\xa2\xd6\x32\x7e\x96\xfc\xd8\x3e\x3d\xe7\x33\x36\x89\xf3\xee\x79\x99\x4a\x1b\xf4\x50\x82\xc4\xd7\x25\xed\x8d\x41\x20\x5c\xb5\xbc\xdf\x5c\x34\x1f\x77\xfa\xcb\x1d\xa4\x6a\x5b\x9b\x2c\xbc\x49\xea\xdf\x78\x6b\xcd\x88\x1f\x37\x1a\x95\xfa\x17\xdf\x73\xf6\x06\x51\x9a\xea\x0f\xf7\x9d\x5a\x11\x42\x7b\x98\xee\x7f\x13\xa5\xc0\x06\x37\xe2\x85\x41\x34\x69\x10\x59\x83\x91\x21\xfe\xa9\xab\xe2\xcd\x1b\xcb\xbb\xf2\x7c\x74\xca\xf3\x67\x8e\x05\xbf\xb1\xc9\x49\x89\x7e\xa0\x1f\x56\xff\xa4\xda\xfb\xe8\x64\x46\x11\x68\x5c\x61\x7a\x32\x06\xc7\xa7\x03\x6e\x4a\xc8\x16\x79\x9f\x69\x3d\xaf\xe7\xf1\x9f\x30\x3c\xe4\xeb\xa0\x9d\x21\xe0\x36\x10\x20\x1b\xfc\x66\x5b\x72\x40\x0a\x54\x7a\x1e\x00\xfa\x9b\x7a\xd8\xd8\x4f\x84\xb3\x4a\xef\x11\x85\x15\xe7\x4d\xef\x11\xb9\x18\x8b\xd1\xe1\xf9\x7d\x9a\x12\xc3\x01\x32\xec\x28\x06\x33\x9b\xda\xda\xcd\xa2\xfd\x8b\x78",
+ "\xab\xa0\xee\x3c\x16\xd3\xdc\x75\x3f\x6e\x46\x6c\x33\xa9\x98\xa7\x32\x82\xc0\xdb\xea\xf5\x13\x24\x97\x9a\x58\x43\x76\x36\x88\x6e\x55\x21\xb5\x67\xc9\xa6\x2d\x40\x5e\xe5\x58\xff\xeb\xae\x91\xbc",
+ 224 },
+ { GCRY_MD_SHA3_384,
+ "\x8c\xff\x1f\x67\xfe\x53\xc0\x98\x89\x6d\x91\x36\x38\x9b\xd8\x88\x18\x16\xcc\xab\x34\x86\x2b\xb6\x7a\x65\x6e\x3d\x98\x89\x6f\x3c\xe6\xff\xd4\xda\x73\x97\x58\x09\xfc\xdf\x96\x66\x76\x0d\x6e\x56\x1c\x55\x23\x8b\x20\x5d\x80\x49\xc1\xce\xde\xef\x37\x4d\x17\x35\xda\xa5\x33\x14\x7b\xfa\x96\x0b\x2c\xce\x4a\x4f\x25\x41\x76\xbb\x4d\x1b\xd1\xe8\x96\x54\x43\x2b\x8d\xbe\x1a\x13\x5c\x42\x11\x5b\x39\x4b\x02\x48\x56\xa2\xa8\x3d\xc8\x5d\x67\x82\xbe\x4b\x44\x42\x39\x56\x7c\xce\xc4\xb1\x84\xd4\x54\x8e\xae\x3f\xf6\xa1\x92\xf3\x43\x29\x2b\xa2\xe3\x2a\x0f\x26\x7f\x31\xcc\x26\x71\x9e\xb8\x52\x45\xd4\x15\xfb\x89\x7a\xc2\xda\x43\x3e\xe9\x1a\x99\x42\x4c\x9d\x7f\x17\x66\xa4\x41\x71\xd1\x65\x10\x01\xc3\x8f\xc7\x92\x94\xac\xcc\x68\xce\xb5\x66\x5d\x36\x21\x84\x54\xd3\xba\x16\x9a\xe0\x58\xa8\x31\x33\x8c\x17\x74\x36\x03\xf8\x1e\xe1\x73\xbf\xc0\x92\x74\x64\xf9\xbd\x72\x8d\xee\x94\xc6\xae\xab\x7a\xae\x6e\xe3\xa6\x27\xe8",
+ "\x28\xb3\x71\x25\xf2\x33\xba\x8d\x52\x7e\x52\x84\xa1\x6e\x6e\xfe\x9a\xe8\x4d\x3e\xbc\x6e\xe4\xc8\x8a\xee\x0a\xb1\x65\xc1\x11\xa3\x2f\xf2\xcd\xcc\x42\x13\xac\x32\x67\xb0\x54\x6d\xc0\xd7\x4c\x84",
+ 225 },
+ { GCRY_MD_SHA3_384,
+ "\xea\xcd\x07\x97\x1c\xff\x9b\x99\x39\x90\x3f\x8c\x1d\x8c\xbb\x5d\x4d\xb1\xb5\x48\xa8\x5d\x04\xe0\x37\x51\x4a\x58\x36\x04\xe7\x87\xf3\x29\x92\xbf\x21\x11\xb9\x7a\xc5\xe8\xa9\x38\x23\x35\x52\x73\x13\x21\x52\x2a\xb5\xe8\x58\x35\x61\x26\x0b\x7d\x13\xeb\xee\xf7\x85\xb2\x3a\x41\xfd\x85\x76\xa6\xda\x76\x4a\x8e\xd6\xd8\x22\xd4\x95\x7a\x54\x5d\x52\x44\x75\x6c\x18\xaa\x80\xe1\xaa\xd4\xd1\xf9\xc2\x0d\x25\x9d\xee\x17\x11\xe2\xcc\x8f\xd0\x13\x16\x9f\xb7\xcc\x4c\xe3\x8b\x36\x2f\x8e\x09\x36\xae\x91\x98\xb7\xe8\x38\xdc\xea\x4f\x7a\x5b\x94\x29\xbb\x3f\x6b\xbc\xf2\xdc\x92\x56\x5e\x36\x76\xc1\xc5\xe6\xeb\x3d\xd2\xa0\xf8\x6a\xa2\x3e\xdd\x3d\x08\x91\xf1\x97\x44\x76\x92\x79\x4b\x3d\xfa\x26\x96\x11\xad\x97\xf7\x2b\x79\x56\x02\xb4\xfd\xb1\x98\xf3\xfd\x3e\xb4\x1b\x41\x50\x64\x25\x6e\x34\x5e\x8d\x8c\x51\xc5\x55\xdc\x8a\x21\x90\x4a\x9b\x0f\x1a\xd0\xef\xfa\xb7\x78\x6a\xac\x2d\xa3\xb1\x96\x50\x7e\x9f\x33\xca\x35\x64\x27",
+ "\x25\x89\x88\xe5\x4d\x66\xe0\xc5\x3b\x26\x3b\xa6\x8d\x9e\x3a\xa4\x7d\x27\x8d\xf8\x7c\x51\x21\x9c\xce\x6f\x25\x47\x28\x1e\xa6\x58\x15\x40\xe2\x8c\x1d\x7e\x06\x92\x54\x79\x1f\x0d\x38\x5e\xa6\x94",
+ 226 },
+ { GCRY_MD_SHA3_384,
+ "\x23\xac\x4e\x9a\x42\xc6\xef\x45\xc3\x33\x6c\xe6\xdf\xc2\xff\x7d\xe8\x88\x4c\xd2\x3d\xc9\x12\xfe\xf0\xf7\x75\x6c\x09\xd3\x35\xc1\x89\xf3\xad\x3a\x23\x69\x7a\xbd\xa8\x51\xa8\x18\x81\xa0\xc8\xcc\xaf\xc9\x80\xab\x2c\x70\x25\x64\xc2\xbe\x15\xfe\x4c\x4b\x9f\x10\xdf\xb2\x24\x8d\x0d\x0c\xb2\xe2\x88\x7f\xd4\x59\x8a\x1d\x4a\xcd\xa8\x97\x94\x4a\x2f\xfc\x58\x0f\xf9\x27\x19\xc9\x5c\xf2\xaa\x42\xdc\x58\x46\x74\xcb\x5a\x9b\xc5\x76\x5b\x9d\x6d\xdf\x57\x89\x79\x1d\x15\xf8\xdd\x92\x5a\xa1\x2b\xff\xaf\xbc\xe6\x08\x27\xb4\x90\xbb\x7d\xf3\xdd\xa6\xf2\xa1\x43\xc8\xbf\x96\xab\xc9\x03\xd8\x3d\x59\xa7\x91\xe2\xd6\x28\x14\xa8\x9b\x80\x80\xa2\x80\x60\x56\x8c\xf2\x4a\x80\xae\x61\x17\x9f\xe8\x4e\x0f\xfa\xd0\x03\x88\x17\x8c\xb6\xa6\x17\xd3\x7e\xfd\x54\xcc\x01\x97\x0a\x4a\x41\xd1\xa8\xd3\xdd\xce\x46\xed\xbb\xa4\xab\x7c\x90\xad\x56\x53\x98\xd3\x76\xf4\x31\x18\x9c\xe8\xc1\xc3\x3e\x13\x2f\xea\xe6\xa8\xcd\x17\xa6\x1c\x63\x00\x12",
+ "\xf6\xa9\x39\x9b\x48\x2a\x3a\x5e\xa6\xfe\x79\xa2\xdb\x7b\xae\x7e\x58\x8c\x9b\x7d\xa0\x3d\xd8\x5c\x12\x01\x12\xfd\xbc\x23\x43\x50\x52\x9a\x1f\x37\xab\xbe\xbe\xb7\x70\x29\x9e\x14\x1e\xea\x7b\xa3",
+ 227 },
+ { GCRY_MD_SHA3_384,
+ "\x01\x72\xdf\x73\x22\x82\xc9\xd4\x88\x66\x9c\x35\x8e\x34\x92\x26\x0c\xbe\x91\xc9\x5c\xfb\xc1\xe3\xfe\xa6\xc4\xb0\xec\x12\x9b\x45\xf2\x42\xac\xe0\x9f\x15\x2f\xc6\x23\x4e\x1b\xee\x8a\xab\x8c\xd5\x6e\x8b\x48\x6e\x1d\xcb\xa9\xc0\x54\x07\xc2\xf9\x5d\xa8\xd8\xf1\xc0\xaf\x78\xee\x2e\xd8\x2a\x3a\x79\xec\x0c\xb0\x70\x93\x96\xee\x62\xaa\xdb\x84\xf8\xa4\xee\x8a\x7c\xcc\xa3\xc1\xee\x84\xe3\x02\xa0\x9e\xa8\x02\x20\x4a\xfe\xcf\x04\x09\x7e\x67\xd0\xf8\xe8\xa9\xd2\x65\x11\x26\xc0\xa5\x98\xa3\x70\x81\xe4\x2d\x16\x8b\x0a\xe8\xa7\x19\x51\xc5\x24\x25\x9e\x4e\x20\x54\xe5\x35\xb7\x79\x67\x9b\xda\xde\x56\x6f\xe5\x57\x00\x85\x86\x18\xe6\x26\xb4\xa0\xfa\xf8\x95\xbc\xce\x90\x11\x50\x4a\x49\xe0\x5f\xd5\x61\x27\xea\xe3\xd1\xf8\x91\x7a\xfb\x54\x8e\xca\xda\xbd\xa1\x02\x01\x11\xfe\xc9\x31\x4c\x41\x34\x98\xa3\x60\xb0\x86\x40\x54\x9a\x22\xcb\x23\xc7\x31\xac\xe7\x43\x25\x2a\x82\x27\xa0\xd2\x68\x9d\x4c\x60\x01\x60\x66\x78\xdf\xb9\x21",
+ "\xc0\xf9\x57\xe5\x2e\x40\xf9\xb8\xea\x94\x5d\x40\x77\x92\x86\xf7\x25\x7a\xd4\x63\xa9\x34\xb0\x49\xdf\x40\xc3\x1d\x35\x47\xae\xf4\x1a\xea\x2d\xd9\x81\xfd\x25\x79\x32\x72\x29\xb5\x4e\xe0\x4e\x66",
+ 228 },
+ { GCRY_MD_SHA3_384,
+ "\x38\x75\xb9\x24\x0c\xf3\xe0\xa8\xb5\x9c\x65\x85\x40\xf2\x6a\x70\x1c\xf1\x88\x49\x6e\x2c\x21\x74\x78\x8b\x12\x6f\xd2\x94\x02\xd6\xa7\x54\x53\xba\x06\x35\x28\x4d\x08\x83\x5f\x40\x05\x1a\x2a\x96\x83\xdc\x92\xaf\xb9\x38\x37\x19\x19\x12\x31\x17\x03\x79\xba\x6f\x4a\xdc\x81\x6f\xec\xbb\x0f\x9c\x44\x6b\x78\x5b\xf5\x20\x79\x68\x41\xe5\x88\x78\xb7\x3c\x58\xd3\xeb\xb0\x97\xce\x47\x61\xfd\xea\xbe\x15\xde\x2f\x31\x9d\xfb\xaf\x17\x42\xcd\xeb\x38\x95\x59\xc7\x88\x13\x1a\x67\x93\xe1\x93\x85\x66\x61\x37\x6c\x81\xce\x95\x68\xda\x19\xaa\x69\x25\xb4\x7f\xfd\x77\xa4\x3c\x7a\x0e\x75\x8c\x37\xd6\x92\x54\x90\x9f\xf0\xfb\xd4\x15\xef\x8e\xb9\x37\xbc\xd4\x9f\x91\x46\x8b\x49\x97\x4c\x07\xdc\x81\x9a\xbd\x67\x39\x5d\xb0\xe0\x58\x74\xff\x83\xdd\xda\xb8\x95\x34\x4a\xbd\x0e\x71\x11\xb2\xdf\x9e\x58\xd7\x6d\x85\xad\x98\x10\x6b\x36\x29\x58\x26\xbe\x04\xd4\x35\x61\x55\x95\x60\x5e\x4b\x4b\xb8\x24\xb3\x3c\x4a\xfe\xb5\xe7\xbb\x0d\x19\xf9\x09",
+ "\x77\x9e\xec\xf3\x93\x11\x31\x80\x51\xbf\x73\xc4\x41\xfb\x79\x97\x08\x91\x20\x49\xe2\x8d\xf3\xfa\xdd\xe4\x49\xe4\xcd\x82\x0c\xc4\xca\x1b\xd0\xf8\x51\x39\x27\xd9\xa6\x4f\x5d\x34\xfa\xab\xa0\x39",
+ 229 },
+ { GCRY_MD_SHA3_384,
+ "\x74\x7c\xc1\xa5\x9f\xef\xba\x94\xa9\xc7\x5b\xa8\x66\xc3\x0d\xc5\xc1\xcb\x0c\x0f\x8e\x93\x61\xd9\x84\x84\x95\x6d\xd5\xd1\xa4\x0f\x61\x84\xaf\xbe\x3d\xac\x9f\x76\x02\x8d\x1c\xae\xcc\xfb\xf6\x91\x99\xc6\xce\x2b\x4c\x09\x2a\x3f\x4d\x2a\x56\xfe\x5a\x33\xa0\x07\x57\xf4\xd7\xde\xe5\xdf\xb0\x52\x43\x11\xa9\x7a\xe0\x66\x8a\x47\x97\x1b\x95\x76\x6e\x2f\x6d\xd4\x8c\x3f\x57\x84\x1f\x91\xf0\x4a\x00\xad\x5e\xa7\x0f\x2d\x47\x9a\x26\x20\xdc\x5c\xd7\x8e\xaa\xb3\xa3\xb0\x11\x71\x9b\x7e\x78\xd1\x9d\xdf\x70\xd9\x42\x37\x98\xaf\x77\x51\x7e\xbc\x55\x39\x2f\xcd\x01\xfc\x60\x0d\x8d\x46\x6b\x9e\x7a\x7a\x85\xbf\x33\xf9\xcc\x54\x19\xe9\xbd\x87\x4d\xdf\xd6\x09\x81\x15\x0d\xda\xf8\xd7\xfe\xba\xa4\x37\x4f\x08\x72\xa5\x62\x8d\x31\x80\x00\x31\x1e\x2f\x56\x55\x36\x5a\xd4\xd4\x07\xc2\x0e\x5c\x04\xdf\x17\xa2\x22\xe7\xde\xec\x79\xc5\xab\x11\x16\xd8\x57\x2f\x91\xcd\x06\xe1\xcc\xc7\xce\xd5\x37\x36\xfc\x86\x7f\xd4\x9e\xce\xbe\x6b\xf8\x08\x2e\x8a",
+ "\x3d\x64\x95\xeb\x3d\xa4\xe8\x1d\x34\x70\xa0\x50\xf4\x16\xe2\xc8\xab\xf6\x57\xa2\x6d\x4f\xd6\x4a\xf3\x57\x35\xb5\x78\x2b\x61\x1f\xb7\x98\xa7\x2f\xe7\xa6\x1c\xe7\x9d\x04\x96\xf6\x96\x54\xcc\x80",
+ 230 },
+ { GCRY_MD_SHA3_384,
+ "\x57\xaf\x97\x1f\xcc\xae\xc9\x74\x35\xdc\x2e\xc9\xef\x04\x29\xbc\xed\xc6\xb6\x47\x72\x9e\xa1\x68\x85\x8a\x6e\x49\xac\x10\x71\xe7\x06\xf4\xa5\xa6\x45\xca\x14\xe8\xc7\x74\x6d\x65\x51\x16\x20\x68\x2c\x90\x6c\x8b\x86\xec\x90\x1f\x3d\xde\xd4\x16\x7b\x3f\x00\xb0\x6c\xbf\xac\x6a\xee\x37\x28\x05\x1b\x3e\x5f\xf1\x0b\x4f\x9e\xd8\xbd\x0b\x8d\xa9\x43\x03\xc8\x33\x75\x5b\x3c\xa3\xae\xdd\xf0\xb5\x4b\xc8\xd6\x63\x21\x38\xb5\xd2\x5b\xab\x03\xd1\x7b\x34\x58\xa9\xd7\x82\x10\x80\x06\xf5\xbb\x7d\xe7\x5b\x5c\x0b\xa8\x54\xb4\x23\xd8\xbb\x80\x1e\x70\x1e\x99\xdc\x4f\xea\xad\x59\xbc\x1c\x71\x12\x45\x3b\x04\xd3\x3e\xa3\x63\x56\x39\xfb\x80\x2c\x73\xc2\xb7\x1d\x58\xa5\x6b\xbd\x67\x1b\x18\xfe\x34\xed\x2e\x3d\xca\x38\x82\x7d\x63\xfd\xb1\xd4\xfb\x32\x85\x40\x50\x04\xb2\xb3\xe2\x60\x81\xa8\xff\x08\xcd\x6d\x2b\x08\xf8\xe7\xb7\xe9\x0a\x2a\xb1\xed\x7a\x41\xb1\xd0\x12\x85\x22\xc2\xf8\xbf\xf5\x6a\x7f\xe6\x79\x69\x42\x2c\xe8\x39\xa9\xd4\x60\x8f\x03",
+ "\xf8\x18\x8e\xaf\xd0\xe2\xf9\xc7\xf4\x4e\x70\xb3\x8d\xb1\xfe\x3e\x12\xb1\x46\x97\x39\xca\x6a\x13\xed\x5a\x86\x61\x67\x3a\x31\x82\x96\xff\xaf\x8d\x37\xf6\xfc\xec\x22\xa2\xd0\x0e\xee\x2a\xbe\xba",
+ 231 },
+ { GCRY_MD_SHA3_384,
+ "\x04\xe1\x6d\xed\xc1\x22\x79\x02\xba\xaf\x33\x2d\x3d\x08\x92\x36\x01\xbd\xd6\x4f\x57\x3f\xaa\x1b\xb7\x20\x19\x18\xcf\xe1\x6b\x1e\x10\x15\x1d\xae\x87\x5d\xa0\xc0\xd6\x3c\x59\xc3\xdd\x05\x0c\x4c\x6a\x87\x40\x11\xb0\x18\x42\x1a\xfc\x46\x23\xab\x03\x81\x83\x1b\x2d\xa2\xa8\xba\x42\xc9\x6e\x4f\x70\x86\x4a\xc4\x4e\x10\x6f\x94\x31\x10\x51\xe7\x4c\x77\xc1\x29\x1b\xf5\xdb\x95\x39\xe6\x95\x67\xbf\x6a\x11\xcf\x69\x32\xbb\xba\xd3\x3f\x89\x46\xbf\x58\x14\xc0\x66\xd8\x51\x63\x3d\x1a\x51\x35\x10\x03\x9b\x34\x99\x39\xbf\xd4\x2b\x85\x8c\x21\x82\x7c\x8f\xf0\x5f\x1d\x09\xb1\xb0\x76\x5d\xc7\x8a\x13\x5b\x5c\xa4\xdf\xba\x08\x01\xbc\xad\xdf\xa1\x75\x62\x3c\x8b\x64\x7e\xac\xfb\x44\x44\xb8\x5a\x44\xf7\x38\x90\x60\x7d\x06\xd5\x07\xa4\xf8\x39\x36\x58\x78\x86\x69\xf6\xef\x4d\xeb\x58\xd0\x8c\x50\xca\x07\x56\xd5\xe2\xf4\x9d\x1a\x7a\xd7\x3e\x0f\x0b\x3d\x3b\x5f\x09\x0a\xcf\x62\x2b\x18\x78\xc5\x91\x33\xe4\xa8\x48\xe0\x51\x53\x59\x2e\xa8\x1c\x6f\xbf",
+ "\x7d\x83\xc3\xf2\x26\x5c\x90\xfe\xf4\xbc\x6b\xd0\xd1\x7a\x21\x8f\x0e\x19\x64\x89\xcb\x2d\x84\x55\xbb\xee\x80\xab\x98\x9f\xfe\xa4\x6d\xe7\x53\x34\x6e\xdb\xd5\xc8\x84\x48\xfe\xdb\x0d\x4a\xad\x4d",
+ 232 },
+ { GCRY_MD_SHA3_384,
+ "\x7c\x81\x5c\x38\x4e\xee\x0f\x28\x8e\xce\x27\xcc\xed\x52\xa0\x16\x03\x12\x7b\x07\x9c\x00\x73\x78\xbc\x5d\x1e\x6c\x5e\x9e\x6d\x1c\x73\x57\x23\xac\xbb\xd5\x80\x1a\xc4\x98\x54\xb2\xb5\x69\xd4\x47\x2d\x33\xf4\x0b\xbb\x88\x82\x95\x62\x45\xc3\x66\xdc\x35\x82\xd7\x16\x96\xa9\x7a\x4e\x19\x55\x7e\x41\xe5\x4d\xee\x48\x2a\x14\x22\x90\x05\xf9\x3a\xfd\x2c\x4a\x7d\x86\x14\xd1\x0a\x97\xa9\xdf\xa0\x7f\x7c\xd9\x46\xfa\x45\x26\x30\x63\xdd\xd2\x9d\xb8\xf9\xe3\x4d\xb6\x0d\xaa\x32\x68\x4f\x00\x72\xea\x2a\x94\x26\xec\xeb\xfa\x52\x39\xfb\x67\xf2\x9c\x18\xcb\xaa\x2a\xf6\xed\x4b\xf4\x28\x39\x36\x82\x3a\xc1\x79\x01\x64\xfe\xc5\x45\x7a\x9c\xba\x7c\x76\x7c\xa5\x93\x92\xd9\x4c\xab\x74\x48\xf5\x0e\xb3\x4e\x9a\x93\xa8\x00\x27\x47\x1c\xe5\x97\x36\xf0\x99\xc8\x86\xde\xa1\xab\x4c\xba\x4d\x89\xf5\xfc\x7a\xe2\xf2\x1c\xcd\x27\xf6\x11\xec\xa4\x62\x6b\x2d\x08\xdc\x22\x38\x2e\x92\xc1\xef\xb2\xf6\xaf\xdc\x8f\xdc\x3d\x21\x72\x60\x4f\x50\x35\xc4\x6b\x81\x97\xd3",
+ "\xfc\xc5\xfc\xfe\xf5\xba\x87\x4a\x31\x7b\x73\xc9\xb1\xb4\xcf\x68\x77\x37\x3d\x41\xf0\xb8\x08\x0a\x5d\x4f\x02\x1e\x0d\x67\xf3\xb9\xf8\xcc\xaa\xcf\xd4\x24\x4f\xc1\x0b\xa5\x8b\x3a\x47\x0d\xb4\x8b",
+ 233 },
+ { GCRY_MD_SHA3_384,
+ "\xe2\x9d\x50\x51\x58\xdb\xdd\x93\x7d\x9e\x3d\x21\x45\x65\x8e\xe6\xf5\x99\x2a\x2f\xc7\x90\xf4\xf6\x08\xd9\xcd\xb4\x4a\x09\x1d\x5b\x94\xb8\x8e\x81\xfa\xc4\xfd\xf5\xc4\x94\x42\xf1\x3b\x91\x1c\x55\x88\x64\x69\x62\x95\x51\x18\x9e\xaf\xf6\x24\x88\xf1\xa4\x79\xb7\xdb\x11\xa1\x56\x0e\x19\x8d\xdc\xcc\xcf\x50\x15\x90\x93\x42\x5f\xf7\xf1\xcb\x8d\x1d\x12\x46\xd0\x97\x87\x64\x08\x7d\x6b\xac\x25\x70\x26\xb0\x90\xef\xae\x8c\xec\x5f\x22\xb6\xf2\x1c\x59\xac\xe1\xac\x73\x86\xf5\xb8\x83\x7c\xa6\xa1\x2b\x6f\xbf\x55\x34\xdd\x05\x60\xef\x05\xca\x78\x10\x4d\x3b\x94\x3d\xdb\x22\x0f\xea\xec\x89\xaa\x5e\x69\x2a\x00\xf8\x22\xa2\xab\x9a\x2f\xe6\x03\x50\xd7\x5e\x7b\xe1\x6f\xf2\x52\x6d\xc6\x43\x87\x25\x02\xd0\x1f\x42\xf1\x88\xab\xed\x0a\x6e\x9a\x6f\x5f\xd0\xd1\xce\x7d\x57\x55\xc9\xff\xa6\x6b\x0a\xf0\xb2\x0b\xd8\x06\xf0\x8e\x06\x15\x66\x90\xd8\x1a\xc8\x11\x77\x8c\xa3\xda\xc2\xc2\x49\xb9\x60\x02\x01\x7f\xce\x93\xe5\x07\xe3\xb9\x53\xac\xf9\x99\x64\xb8\x47",
+ "\x9b\x33\x6b\x4c\x2b\x53\x0f\x65\xc0\x1a\xf3\xf0\xa4\x6c\xf1\xb6\x26\xd5\xdb\xf1\xb2\xe5\x0f\x79\x0b\x9f\x34\xcc\xa3\x67\x31\x5f\xdf\xbf\x7d\x96\x19\xcd\xa4\xda\x22\xe3\x9f\x93\x15\x30\x38\x16",
+ 234 },
+ { GCRY_MD_SHA3_384,
+ "\xd8\x55\x88\x69\x6f\x57\x6e\x65\xec\xa0\x15\x5f\x39\x5f\x0c\xfa\xcd\x83\xf3\x6a\x99\x11\x1e\xd5\x76\x8d\xf2\xd1\x16\xd2\x12\x1e\x32\x35\x7b\xa4\xf5\x4e\xde\x92\x7f\x18\x9f\x29\x7d\x3a\x97\xfa\xd4\xe9\xa0\xf5\xb4\x1d\x8d\x89\xdd\x7f\xe2\x01\x56\x79\x9c\x2b\x7b\x6b\xf9\xc9\x57\xba\x0d\x67\x63\xf5\xc3\xbc\x51\x29\x74\x7b\xbb\x53\x65\x2b\x49\x29\x0c\xff\x1c\x87\xe2\xcd\xf2\xc4\xb9\x5d\x8a\xae\xe0\x9b\xc8\xfb\xfa\x68\x83\xe6\x2d\x23\x78\x85\x81\x04\x91\xbf\xc1\x01\xf1\xd8\xc6\x36\xe3\xd0\xed\xe8\x38\xad\x05\xc2\x07\xa3\xdf\x4f\xad\x76\x45\x29\x79\xeb\x99\xf2\x9a\xfa\xec\xed\xd1\xc6\x3b\x8d\x36\xcf\x37\x84\x54\xa1\xbb\x67\xa7\x41\xc7\x7a\xc6\xb6\xb3\xf9\x5f\x4f\x02\xb6\x4d\xab\xc1\x54\x38\x61\x3e\xa4\x97\x50\xdf\x42\xee\x90\x10\x1f\x11\x5a\xa9\xab\xb9\xff\x64\x32\x4d\xde\x9d\xab\xbb\x01\x05\x4e\x1b\xd6\xb4\xbc\xdc\x79\x30\xa4\x4c\x23\x00\xd8\x7c\xa7\x8c\x06\x92\x4d\x03\x23\xad\x78\x87\xe4\x6c\x90\xe8\xc4\xd1\x00\xac\xd9\xee\xd2\x1e",
+ "\xca\xc4\x42\x22\x7f\x10\xc4\x93\x5d\x42\xc2\x91\x40\x43\x16\x78\x90\xc3\xee\x1f\x45\x56\xd3\x8d\x20\x76\x7e\x84\x02\xae\xc4\xd7\x01\x11\xf2\x03\x42\x76\xe9\x0f\x28\x10\x2d\xe6\x34\xe2\x6a\xfd",
+ 235 },
+ { GCRY_MD_SHA3_384,
+ "\x3a\x12\xf8\x50\x8b\x40\xc3\x2c\x74\x49\x2b\x66\x32\x33\x75\xdc\xfe\x49\x18\x4c\x78\xf7\x31\x79\xf3\x31\x4b\x79\xe6\x33\x76\xb8\xac\x68\x3f\x5a\x51\xf1\x53\x4b\xd7\x29\xb0\x2b\x04\xd0\x02\xf5\x5c\xbd\x8e\x8f\xc9\xb5\xec\x1e\xa6\xbb\xe6\xa0\xd0\xe7\x43\x15\x18\xe6\xba\x45\xd1\x24\x03\x5f\x9d\x3d\xce\x0a\x8b\xb7\xbf\x14\x30\xa9\xf6\x57\xe0\xb4\xea\x9f\x20\xeb\x20\xc7\x86\xa5\x81\x81\xa1\xe2\x0a\x96\xf1\x62\x8f\x87\x28\xa1\x3b\xdf\x7a\x4b\x4b\x32\xfc\x8a\xa7\x05\x4c\xc4\x88\x1a\xe7\xfa\x19\xaf\xa6\x5c\x6c\x3e\xe1\xb3\xad\xe3\x19\x2a\xf4\x20\x54\xa8\xa9\x11\xb8\xec\x18\x26\x86\x5d\x46\xd9\x3f\x1e\x7c\x5e\x2b\x78\x13\xc9\x2a\x50\x6e\x53\x88\x6f\x3d\x47\x01\xbb\x93\xd2\xa6\x81\xad\x10\x9c\x84\x59\x04\xbb\x86\x1a\xf8\xaf\x06\x46\xb6\xe3\x99\xb3\x8b\x61\x40\x51\xd3\x4f\x68\x42\x56\x3a\x0f\x37\xec\x00\xcb\x3d\x86\x5f\xc5\xd7\x46\xc4\x98\x7d\xe2\xa6\x50\x71\x10\x08\x83\xa2\xa9\xc7\xa2\xbf\xe1\xe2\xdd\x60\x3d\x9e\xa2\x4d\xc7\xc5\xfd\x06\xbe",
+ "\x05\xe3\xfb\x83\xee\x8d\x60\x98\x74\xd5\x93\x52\x83\x70\x2f\x29\xe5\xe8\x96\xbb\x09\x0c\x48\x03\x34\x89\x29\x59\x89\xc4\x5d\xd2\xc0\x6f\x5b\xd5\x58\xb6\xbc\x78\x6a\xb1\x25\x1f\x75\x66\x4b\x06",
+ 236 },
+ { GCRY_MD_SHA3_384,
+ "\x18\x61\xed\xce\x46\xfa\x5a\xd1\x7e\x1f\xf1\xde\xae\x08\x4d\xec\x58\x0f\x97\xd0\xa6\x78\x85\xdf\xe8\x34\xb9\xdf\xac\x1a\xe0\x76\x74\x2c\xe9\xe2\x67\x51\x2c\xa5\x1f\x6d\xf5\xa4\x55\xaf\x0c\x5f\xd6\xab\xf9\x4a\xce\xa1\x03\xa3\x37\x0c\x35\x44\x85\xa7\x84\x6f\xb8\x4f\x3a\xc7\xc2\x90\x4b\x5b\x2f\xbf\x22\x70\x02\xce\x51\x21\x33\xbb\x7e\x1c\x4e\x50\x05\x7b\xfd\x1e\x44\xdb\x33\xc7\xcd\xb9\x69\xa9\x9e\x28\x4b\x18\x4f\x50\xa1\x4b\x06\x8a\x1f\xc5\x00\x9d\x9b\x29\x8d\xbe\x92\x23\x95\x72\xa7\x62\x7a\xac\x02\xab\xe8\xf3\xe3\xb4\x73\x41\x7f\x36\xd4\xd2\x50\x5d\x16\xb7\x57\x7f\x45\x26\xc9\xd9\x4a\x27\x0a\x2d\xfe\x45\x0d\x06\xda\x8f\x6f\xa9\x56\x87\x9a\x0a\x55\xcf\xe9\x9e\x74\x2e\xa5\x55\xea\x47\x7b\xa3\xe9\xb4\x4c\xcd\x50\x8c\x37\x54\x23\x61\x1a\xf9\x2e\x55\x34\x5d\xc2\x15\x77\x9b\x2d\x51\x19\xeb\xa4\x9c\x71\xd4\x9b\x9f\xe3\xf1\x56\x9f\xa2\x4e\x5c\xa3\xe3\x32\xd0\x42\x42\x2a\x8b\x81\x58\xd3\xec\x66\xa8\x00\x12\x97\x6f\x31\xff\xdf\x30\x5f\x0c\x9c\x5e",
+ "\x6e\x46\x3c\x7f\xb5\xcf\x43\x6b\x14\x44\x92\x1a\xfe\x76\xd2\xfa\x4e\x7a\x23\xed\xfc\x9d\x49\x6a\xf1\xdc\x7e\x78\xa0\x17\x3d\x79\x7e\xff\x80\xf2\xbb\x32\xcf\xd3\x4d\xaf\x56\x33\xc4\xe6\xbc\xd6",
+ 237 },
+ { GCRY_MD_SHA3_384,
+ "\x08\xd0\xff\xde\x3a\x6e\x4e\xf6\x56\x08\xea\x67\x2e\x48\x30\xc1\x29\x43\xd7\x18\x7c\xcf\xf0\x8f\x49\x41\xcf\xc1\x3e\x54\x5f\x3b\x9c\x7a\xd5\xee\xbb\xe2\xb0\x16\x42\xb4\x86\xca\xf8\x55\xc2\xc7\x3f\x58\xc1\xe4\xe3\x39\x1d\xa8\xe2\xd6\x3d\x96\xe1\x5f\xd8\x49\x53\xae\x5c\x23\x19\x11\xb0\x0a\xd6\x05\x0c\xd7\xaa\xfd\xaa\xc9\xb0\xf6\x63\xae\x6a\xab\x45\x51\x9d\x0f\x53\x91\xa5\x41\x70\x7d\x47\x90\x34\xe7\x3a\x6a\xd8\x05\xae\x35\x98\x09\x6a\xf0\x78\xf1\x39\x33\x01\x49\x3d\x66\x3d\xd7\x1f\x83\x86\x9c\xa2\x7b\xa5\x08\xb7\xe9\x1e\x81\xe1\x28\xc1\x71\x6d\xc3\xac\xfe\x30\x84\xb2\x20\x1e\x04\xcf\x80\x06\x61\x7e\xec\xf1\xb6\x40\x47\x4a\x5d\x45\xcf\xde\x9f\x4d\x3e\xf9\x2d\x6d\x05\x5b\x90\x98\x92\x19\x4d\x8a\x82\x18\xdb\x6d\x82\x03\xa8\x42\x61\xd2\x00\xd7\x14\x73\xd7\x48\x8f\x34\x27\x41\x6b\x68\x96\xc1\x37\xd4\x55\xf2\x31\x07\x1c\xac\xbc\x86\xe0\x41\x5a\xb8\x8a\xec\x84\x1d\x96\xb7\xb8\xaf\x41\xe0\x5b\xb4\x61\xa4\x06\x45\xbf\x17\x66\x01\xf1\xe7\x60\xde\x5f",
+ "\x90\x45\x7e\x3d\x33\xfc\xe1\x03\x42\x00\x56\xa1\xc7\x12\x44\x1e\x04\x85\x6b\x17\xcf\x37\xa4\xe1\x33\x84\x1e\x6d\x9a\x94\x4b\x5e\xbe\xf9\x8c\xb1\xc1\xcc\xd5\x75\x63\x2c\xd3\xb5\xc1\x77\x66\x9e",
+ 238 },
+ { GCRY_MD_SHA3_384,
+ "\xd7\x82\xab\xb7\x2a\x5b\xe3\x39\x27\x57\xbe\x02\xd3\xe4\x5b\xe6\xe2\x09\x9d\x6f\x00\x0d\x04\x2c\x8a\x54\x3f\x50\xed\x6e\xbc\x05\x5a\x7f\x13\x3b\x0d\xd8\xe9\xbc\x34\x85\x36\xed\xca\xae\x2e\x12\xec\x18\xe8\x83\x7d\xf7\xa1\xb3\xc8\x7e\xc4\x6d\x50\xc2\x41\xde\xe8\x20\xfd\x58\x61\x97\x55\x2d\xc2\x0b\xee\xa5\x0f\x44\x5a\x07\xa3\x8f\x17\x68\xa3\x9e\x2b\x2f\xf0\x5d\xdd\xed\xf7\x51\xf1\xde\xf6\x12\xd2\xe4\xd8\x10\xda\xa3\xa0\xcc\x90\x45\x16\xf9\xa4\x3a\xf6\x60\x31\x53\x85\x17\x8a\x52\x9e\x51\xf8\xaa\xe1\x41\x80\x8c\x8b\xc5\xd7\xb6\x0c\xac\x26\xbb\x98\x4a\xc1\x89\x0d\x04\x36\xef\x78\x04\x26\xc5\x47\xe9\x4a\x7b\x08\xf0\x1a\xcb\xfc\x4a\x38\x25\xea\xe0\x4f\x52\x0a\x90\x16\xf2\xfb\x8b\xf5\x16\x5e\xd1\x27\x36\xfc\x71\xe3\x6a\x49\xa7\x36\x14\x73\x9e\xaa\x3e\xc8\x34\x06\x9b\x1b\x40\xf1\x35\x0c\x2b\x3a\xb8\x85\xc0\x2c\x64\x0b\x9f\x76\x86\xed\x5f\x99\x52\x7e\x41\xcf\xcd\x79\x6f\xe4\xc2\x56\xc9\x17\x31\x86\xc2\x26\x16\x9f\xf2\x57\x95\x4e\xbd\xa8\x1c\x0e\x5f\x99",
+ "\xe5\xfc\x73\xc7\x00\x28\xd1\xb8\x2a\x9a\xa9\x76\xd3\x4f\x5f\xc7\x29\x16\x83\x90\x27\x03\x8e\x79\xdf\x2e\x29\x14\x9e\x86\x1f\x09\xa4\x1a\x82\x03\xce\x92\x22\x03\xf7\x10\x96\x4b\x4f\x5b\xec\x2e",
+ 239 },
+ { GCRY_MD_SHA3_384,
+ "\x5f\xce\x81\x09\xa3\x58\x57\x0e\x40\x98\x3e\x11\x84\xe5\x41\x83\x3b\xb9\x09\x1e\x28\x0f\x25\x8c\xfb\x14\x43\x87\xb0\x5d\x19\x0e\x43\x1c\xb1\x9b\xaa\x67\x27\x3b\xa0\xc5\x8a\xbe\x91\x30\x8e\x18\x44\xdc\xd0\xb3\x67\x8b\xaa\x42\xf3\x35\xf2\xfa\x05\x26\x7a\x02\x40\xb3\xc7\x18\xa5\x94\x2b\x3b\x3e\x3b\xfa\x98\xa5\x5c\x25\xa1\x46\x6e\x8d\x7a\x60\x37\x22\xcb\x2b\xbf\x03\xaf\xa5\x4c\xd7\x69\xa9\x9f\x31\x07\x35\xee\x5a\x05\xda\xe2\xc2\x2d\x39\x7b\xd9\x56\x35\xf5\x8c\x48\xa6\x7f\x90\xe1\xb7\x3a\xaf\xcd\x3f\x82\x11\x7f\x01\x66\x65\x78\x38\x69\x10\x05\xb1\x8d\xa6\xf3\x41\xd6\xe9\x0f\xc1\xcd\xb3\x52\xb3\x0f\xae\x45\xd3\x48\x29\x4e\x50\x1b\x63\x25\x2d\xe1\x47\x40\xf2\xb8\x5a\xe5\x29\x9d\xde\xc3\x17\x2d\xe8\xb6\xd0\xba\x21\x9a\x20\xa2\x3b\xb5\xe1\x0f\xf4\x34\xd3\x9d\xb3\xf5\x83\x30\x5e\x9f\x5c\x03\x9d\x98\x56\x9e\x37\x7b\x75\xa7\x0a\xb8\x37\xd1\xdf\x26\x9b\x8a\x4b\x56\x6f\x40\xbb\x91\xb5\x77\x45\x5f\xd3\xc3\x56\xc9\x14\xfa\x06\xb9\xa7\xce\x24\xc7\x31\x7a\x17\x2d",
+ "\xb0\xa1\xbb\xa9\x12\xda\xa6\xd8\x0e\xdc\x65\x19\xb5\x01\xb6\x29\x45\x63\x94\xd7\xbd\xa2\x4d\x46\xaf\xc9\xfc\x1d\x93\xa0\xb5\x96\x2f\xa4\xf9\x52\x14\x27\x32\x90\xd3\x2b\x3e\xae\xff\x6f\x9d\xfe",
+ 240 },
+ { GCRY_MD_SHA3_384,
+ "\x61\x72\xf1\x97\x1a\x6e\x1e\x4e\x61\x70\xaf\xba\xd9\x5d\x5f\xec\x99\xbf\x69\xb2\x4b\x67\x4b\xc1\x7d\xd7\x80\x11\x61\x5e\x50\x2d\xe6\xf5\x6b\x86\xb1\xa7\x1d\x3f\x43\x48\x08\x72\x18\xac\x7b\x7d\x09\x30\x29\x93\xbe\x27\x2e\x4a\x59\x19\x68\xae\xf1\x8a\x12\x62\xd6\x65\x61\x0d\x10\x70\xee\x91\xcc\x8d\xa3\x6e\x1f\x84\x1a\x69\xa7\xa6\x82\xc5\x80\xe8\x36\x94\x1d\x21\xd9\x09\xa3\xaf\xc1\xf0\xb9\x63\xe1\xca\x5a\xb1\x93\xe1\x24\xa1\xa5\x3d\xf1\xc5\x87\x47\x0e\x58\x81\xfb\x54\xda\xe1\xb0\xd8\x40\xf0\xc8\xf9\xd1\xb0\x4c\x64\x5b\xa1\x04\x1c\x7d\x8d\xbf\x22\x03\x0a\x62\x3a\xa1\x56\x38\xb3\xd9\x9a\x2c\x40\x0f\xf7\x6f\x32\x52\x07\x9a\xf8\x8d\x2b\x37\xf3\x5e\xe6\x6c\x1a\xd7\x80\x1a\x28\xd3\xd3\x88\xac\x45\x0b\x97\xd5\xf0\xf7\x9e\x45\x41\x75\x53\x56\xb3\xb1\xa5\x69\x6b\x02\x3f\x39\xab\x7a\xb5\xf2\x8d\xf4\x20\x29\x36\xbc\x97\x39\x3b\x93\xbc\x91\x5c\xb1\x59\xea\x1b\xd7\xa0\xa4\x14\xcb\x4b\x7a\x1a\xc3\xaf\x68\xf5\x0d\x79\xf0\xc9\xc7\x31\x4e\x75\x0f\x7d\x02\xfa\xa5\x8b\xfa",
+ "\xfc\xe4\x63\x78\x98\xba\x0c\xbd\x9d\x7b\x63\x6f\xeb\xdd\xc0\x2a\x43\x59\x01\xcb\xbe\xf8\xbf\x76\xd3\xe8\x66\xd9\x7d\x55\x35\x4b\x71\xfc\x12\xe6\x7a\x09\xe7\x93\xd7\x49\x31\x6d\x71\x4f\xe0\x8c",
+ 241 },
+ { GCRY_MD_SHA3_384,
+ "\x56\x68\xec\xd9\x9d\xfb\xe2\x15\xc4\x11\x83\x98\xac\x9c\x9e\xaf\x1a\x14\x33\xfa\xb4\xcc\xdd\x39\x68\x06\x47\x52\xb6\x25\xea\x94\x47\x31\xf7\x5d\x48\xa2\x7d\x04\x7d\x67\x54\x7f\x14\xdd\x0f\xfa\xa5\x5f\xa5\xe2\x9f\x7a\xf0\xd1\x61\xd8\x5e\xaf\xc4\xf2\x02\x9b\x71\x7c\x91\x8e\xab\x9d\x30\x45\x43\x29\x0b\xdb\xa7\x15\x8b\x68\x02\x0c\x0b\xa4\xe0\x79\xbc\x95\xb5\xbc\x0f\xc0\x44\xa9\x92\xb9\x4b\x4c\xcd\x3b\xd6\x6d\x0e\xab\xb5\xdb\xba\xb9\x04\xd6\x2e\x00\x75\x2c\x4e\x3b\x00\x91\xd7\x73\xbc\xf4\xc1\x4b\x43\x77\xda\x3e\xff\xf8\x24\xb1\xcb\x2f\xa0\x1b\x32\xd1\xe4\x6c\x90\x9e\x62\x6e\xd2\xda\xe9\x20\xf4\xc7\xdb\xeb\x63\x5b\xc7\x54\xfa\xcb\xd8\xd4\x9b\xeb\xa3\xf2\x3c\x1c\x41\xcc\xbf\xcd\x0e\xe0\xc1\x14\xe6\x97\x37\xf5\x59\x7c\x0b\xf1\xd8\x59\xf0\xc7\x67\xe1\x80\x02\xae\x8e\x39\xc2\x62\x61\xff\xde\x29\x20\xd3\xd0\xba\xf0\xe9\x06\x13\x86\x96\xcf\xe5\xb7\xe3\x2b\x60\x0f\x45\xdf\x3a\xaa\x39\x93\x2f\x3a\x7d\xf9\x5b\x60\xfa\x87\x12\xa2\x27\x1f\xca\xf3\x91\x1c\xe7\xb5\x11\xb1",
+ "\x2b\x54\x71\xfa\xe3\x80\x58\x52\xf4\xcf\x39\x54\x1f\x8a\x0a\x37\x74\x81\x8f\x79\xfe\x50\x47\x6e\x22\x5d\x89\xb6\x2e\x43\xbe\x32\x55\xe9\x6d\x19\xcb\xc3\x34\xae\xf0\x41\x92\x84\x0f\x07\x5c\x7d",
+ 242 },
+ { GCRY_MD_SHA3_384,
+ "\x03\xd6\x25\x48\x83\x54\xdf\x30\xe3\xf8\x75\xa6\x8e\xdf\xcf\x34\x0e\x83\x66\xa8\xe1\xab\x67\xf9\xd5\xc5\x48\x6a\x96\x82\x9d\xfa\xc0\x57\x82\x89\x08\x2b\x2a\x62\x11\x7e\x1c\xf4\x18\xb4\x3b\x90\xe0\xad\xc8\x81\xfc\x6a\xe8\x10\x5c\x88\x8e\x9e\xcd\x21\xae\xa1\xc9\xae\x1a\x40\x38\xdf\xd1\x73\x78\xfe\xd7\x1d\x02\xae\x49\x20\x87\xd7\xcd\xcd\x98\xf7\x46\x85\x52\x27\x96\x7c\xb1\xab\x47\x14\x26\x1e\xe3\xbe\xad\x3f\x4d\xb1\x18\x32\x9d\x3e\xbe\xf4\xbc\x48\xa8\x75\xc1\x9b\xa7\x63\x96\x6d\xa0\xeb\xea\x80\x0e\x01\xb2\xf5\x0b\x00\xe9\xdd\x4c\xac\xa6\xdc\xb3\x14\xd0\x01\x84\xef\x71\xea\x23\x91\xd7\x60\xc9\x50\x71\x0d\xb4\xa7\x0f\x92\x12\xff\xc5\x48\x61\xf9\xdc\x75\x2c\xe1\x88\x67\xb8\xad\x0c\x48\xdf\x84\x66\xef\x72\x31\xe7\xac\x56\x7f\x0e\xb5\x50\x99\xe6\x22\xeb\xb8\x6c\xb2\x37\x52\x01\x90\xa6\x1c\x66\xad\x34\xf1\xf4\xe2\x89\xcb\x32\x82\xae\x3e\xaa\xc6\x15\x2e\xd2\x4d\x2c\x92\xba\xe5\xa7\x65\x82\x52\xa5\x3c\x49\xb7\xb0\x2d\xfe\x54\xfd\xb2\xe9\x00\x74\xb6\xcf\x31\x0a\xc6\x61",
+ "\xd4\xd3\xb4\x98\x78\xae\xc7\x2e\x2e\x7f\xaf\xb6\x87\xda\x7e\xfe\x24\x2c\xb6\x0a\xdf\x5c\x65\xc5\x77\xc4\x44\xcf\xc9\x5a\x2a\x2e\xc6\x70\x00\x0c\x8a\x78\x89\x8a\x07\x40\x0e\x35\x02\xd7\x3f\x27",
+ 243 },
+ { GCRY_MD_SHA3_384,
+ "\x2e\xdc\x28\x2f\xfb\x90\xb9\x71\x18\xdd\x03\xaa\xa0\x3b\x14\x5f\x36\x39\x05\xe3\xcb\xd2\xd5\x0e\xcd\x69\x2b\x37\xbf\x00\x01\x85\xc6\x51\xd3\xe9\x72\x6c\x69\x0d\x37\x73\xec\x1e\x48\x51\x0e\x42\xb1\x77\x42\xb0\xb0\x37\x7e\x7d\xe6\xb8\xf5\x5e\x00\xa8\xa4\xdb\x47\x40\xce\xe6\xdb\x08\x30\x52\x9d\xd1\x96\x17\x50\x1d\xc1\xe9\x35\x9a\xa3\xbc\xf1\x47\xe0\xa7\x6b\x3a\xb7\x0c\x49\x84\xc1\x3e\x33\x9e\x68\x06\xbb\x35\xe6\x83\xaf\x85\x27\x09\x36\x70\x85\x9f\x3d\x8a\x0f\xc7\xd4\x93\xbc\xba\x6b\xb1\x2b\x5f\x65\xe7\x1e\x70\x5c\xa5\xd6\xc9\x48\xd6\x6e\xd3\xd7\x30\xb2\x6d\xb3\x95\xb3\x44\x77\x37\xc2\x6f\xad\x08\x9a\xa0\xad\x0e\x30\x6c\xb2\x8b\xf0\xac\xf1\x06\xf8\x9a\xf3\x74\x5f\x0e\xc7\x2d\x53\x49\x68\xcc\xa5\x43\xcd\x2c\xa5\x0c\x94\xb1\x45\x67\x43\x25\x4e\x35\x8c\x13\x17\xc0\x7a\x07\xbf\x2b\x0e\xca\x43\x8a\x70\x93\x67\xfa\xfc\x89\xa5\x72\x39\x02\x8f\xc5\xfe\xcf\xd5\x3b\x8e\xf9\x58\xef\x10\xee\x06\x08\xb7\xf5\xcb\x99\x23\xad\x97\x05\x8e\xc0\x67\x70\x0c\xc7\x46\xc1\x27\xa6\x1e\xe3",
+ "\xfe\x1c\x21\x43\xf2\x95\x78\x19\xdf\x9c\x9d\xd0\x5d\x00\x4b\xe0\xe5\x57\xee\xd8\xc5\xa2\xb7\xce\x45\x7d\x58\x56\x13\x2b\x1c\x43\xee\xce\xc3\x6a\xd7\x04\xa9\x30\xa8\x54\x85\xa3\x4c\x38\x60\xfe",
+ 244 },
+ { GCRY_MD_SHA3_384,
+ "\x90\xb2\x8a\x6a\xa1\xfe\x53\x39\x15\xbc\xb8\xe8\x1e\xd6\xca\xcd\xc1\x09\x62\xb7\xff\x82\x47\x4f\x84\x5e\xeb\x86\x97\x76\x00\xcf\x70\xb0\x7b\xa8\xe3\x79\x61\x41\xee\x34\x0e\x3f\xce\x84\x2a\x38\xa5\x0a\xfb\xe9\x03\x01\xa3\xbd\xcc\x59\x1f\x2e\x7d\x9d\xe5\x3e\x49\x55\x25\x56\x0b\x90\x8c\x89\x24\x39\x99\x0a\x2c\xa2\x67\x9c\x55\x39\xff\xdf\x63\x67\x77\xad\x9c\x1c\xde\xf8\x09\xcd\xa9\xe8\xdc\xdb\x45\x1a\xbb\x9e\x9c\x17\xef\xa4\x37\x9a\xbd\x24\xb1\x82\xbd\x98\x1c\xaf\xc7\x92\x64\x0a\x18\x3b\x61\x69\x43\x01\xd0\x4c\x5b\x3e\xaa\xd6\x94\xa6\xbd\x4c\xc0\x6e\xf5\xda\x8f\xa2\x3b\x4f\xa2\xa6\x45\x59\xc5\xa6\x83\x97\x93\x00\x79\xd2\x50\xc5\x1b\xcf\x00\xe2\xb1\x6a\x6c\x49\x17\x14\x33\xb0\xaa\xdf\xd8\x02\x31\x27\x65\x60\xb8\x04\x58\xdd\x77\x08\x9b\x7a\x1b\xbc\xc9\xe7\xe4\xb9\xf8\x81\xea\xcd\x6c\x92\xc4\x31\x83\x48\xa1\x3f\x49\x14\xeb\x27\x11\x5a\x1c\xfc\x5d\x16\xd7\xfd\x94\x95\x4c\x35\x32\xef\xac\xa2\xca\xb0\x25\x10\x3b\x2d\x02\xc6\xfd\x71\xda\x3a\x77\xf4\x17\xd7\x93\x26\x85\x88\x8a",
+ "\x4d\x1f\x62\x66\x88\xe6\x89\x9b\x5f\xcc\xd4\x7f\xaa\xb4\x5e\x96\xc6\x1e\x16\x98\x69\xca\xbe\xf4\x02\x83\xb2\x41\x8d\xfb\x28\x88\xfb\x80\xcc\x9f\x2c\x52\x64\x97\xc5\x0c\x52\x44\x78\x4f\x19\x5c",
+ 245 },
+ { GCRY_MD_SHA3_384,
+ "\x29\x69\x44\x7d\x17\x54\x90\xf2\xaa\x9b\xb0\x55\x01\x4d\xbe\xf2\xe6\x85\x4c\x95\xf8\xd6\x09\x50\xbf\xe8\xc0\xbe\x8d\xe2\x54\xc2\x6b\x2d\x31\xb9\xe4\xde\x9c\x68\xc9\xad\xf4\x9e\x4e\xe9\xb1\xc2\x85\x09\x67\xf2\x9f\x5d\x08\x73\x84\x83\xb4\x17\xbb\x96\xb2\xa5\x6f\x0c\x8a\xca\x63\x2b\x55\x20\x59\xc5\x9a\xac\x3f\x61\xf7\xb4\x5c\x96\x6b\x75\xf1\xd9\x93\x1f\xf4\xe5\x96\x40\x63\x78\xce\xe9\x1a\xaa\x72\x6a\x3a\x84\xc3\x3f\x37\xe9\xcd\xbe\x62\x6b\x57\x45\xa0\xb0\x60\x64\xa8\xa8\xd5\x6e\x53\xaa\xf1\x02\xd2\x3d\xd9\xdf\x0a\x3f\xdf\x7a\x63\x85\x09\xa6\x76\x1a\x33\xfa\x42\xfa\x8d\xdb\xd8\xe1\x61\x59\xc9\x30\x08\xb5\x37\x65\x01\x9c\x3f\x0e\x9f\x10\xb1\x44\xce\x2a\xc5\x7f\x5d\x72\x97\xf9\xc9\x94\x9e\x4f\xf6\x8b\x70\xd3\x39\xf8\x75\x01\xce\x85\x50\xb7\x72\xf3\x2c\x6d\xa8\xad\x2c\xe2\x10\x0a\x89\x5d\x8b\x08\xfa\x1e\xea\xd7\xc3\x76\xb4\x07\x70\x97\x03\xc5\x10\xb5\x0f\x87\xe7\x3e\x43\xf8\xe7\x34\x8f\x87\xc3\x83\x2a\x54\x7e\xf2\xbb\xe5\x79\x9a\xbe\xdc\xf5\xe1\xf3\x72\xea\x80\x92\x33\xf0\x06",
+ "\xa0\x63\xd7\x78\xb0\xa2\xa1\x1d\x3a\x9c\xba\x42\x5e\xe5\x93\x8f\xca\xa6\xe2\xbf\x1f\x30\xa6\x65\xfa\x81\x16\x01\x44\x4d\x57\x49\xaf\xa1\x87\x66\xdb\x5f\x04\x26\xc5\xb8\x39\x22\x38\xb7\x86\x2e",
+ 246 },
+ { GCRY_MD_SHA3_384,
+ "\x72\x16\x45\x63\x3a\x44\xa2\xc7\x8b\x19\x02\x4e\xae\xcf\x58\x57\x5a\xb2\x3c\x27\x19\x08\x33\xc2\x68\x75\xdc\x0f\x0d\x50\xb4\x6a\xea\x9c\x34\x3d\x82\xea\x7d\x5b\x3e\x50\xec\x70\x05\x45\xc6\x15\xda\xea\xea\x64\x72\x6a\x0f\x05\x60\x75\x76\xdc\xd3\x96\xd8\x12\xb0\x3f\xb6\x55\x1c\x64\x10\x87\x85\x6d\x05\x0b\x10\xe6\xa4\xd5\x57\x7b\x82\xa9\x8a\xfb\x89\xce\xe8\x59\x4c\x9d\xc1\x9e\x79\xfe\xff\x03\x82\xfc\xfd\x12\x7f\x1b\x80\x3a\x4b\x99\x46\xf4\xac\x9a\x43\x78\xe1\xe6\xe0\x41\xb1\x38\x9a\x53\xe3\x45\x0c\xd3\x2d\x9d\x29\x41\xb0\xcb\xab\xdb\x50\xda\x8e\xa2\x51\x31\x45\x16\x4c\x3a\xb6\xbc\xbd\x25\x1c\x44\x8d\x2d\x4b\x08\x7a\xc5\x7a\x59\xc2\x28\x5d\x56\x4f\x16\xda\x4e\xd5\xe6\x07\xed\x97\x95\x92\x14\x6f\xfb\x0e\xf3\xf3\xdb\x30\x8f\xb3\x42\xdf\x5e\xb5\x92\x4a\x48\x25\x6f\xc7\x63\x14\x1a\x27\x88\x14\xc8\x2d\x6d\x63\x48\x57\x75\x45\x87\x0a\xe3\xa8\x3c\x72\x30\xac\x02\xa1\x54\x0f\xe1\x79\x8f\x7e\xf0\x9e\x33\x5a\x86\x5a\x2a\xe0\x94\x9b\x21\xe4\xf7\x48\xfb\x8a\x51\xf4\x47\x50\xe2\x13\xa8\xfb",
+ "\x47\x0e\xe6\xd3\x51\x57\x84\x68\x90\xa0\x1b\x38\x09\xeb\x92\x3c\xc4\x5d\xff\xf2\xfc\xa2\x82\x6f\x45\x83\x25\x46\x6c\x98\x3b\x1c\x64\xbe\xa3\x8b\xca\xec\xa9\x21\xc9\x0d\xd0\x04\x32\xec\xcf\x89",
+ 247 },
+ { GCRY_MD_SHA3_384,
+ "\x6b\x86\x0d\x39\x72\x5a\x14\xb4\x98\xbb\x71\x45\x74\xb4\xd3\x7c\xa7\x87\x40\x47\x68\xf6\x4c\x64\x8b\x17\x51\xb3\x53\xac\x92\xba\xc2\xc3\xa2\x8e\xa9\x09\xfd\xf0\x42\x33\x36\x40\x1a\x02\xe6\x3e\xc2\x43\x25\x30\x0d\x82\x3b\x68\x64\xbb\x70\x1f\x9d\x7c\x7a\x1f\x8e\xc9\xd0\xae\x35\x84\xaa\x6d\xd6\x2e\xa1\x99\x7c\xd8\x31\xb4\xba\xbd\x9a\x4d\xa5\x09\x32\xd4\xef\xda\x74\x5c\x61\xe4\x13\x08\x90\xe1\x56\xae\xe6\x11\x37\x16\xda\xf9\x57\x64\x22\x2a\x91\x18\x7d\xb2\xef\xfe\xa4\x9d\x5d\x05\x96\x10\x2d\x61\x9b\xd2\x6a\x61\x6b\xbf\xda\x83\x35\x50\x5f\xbb\x0d\x90\xb4\xc1\x80\xd1\xa2\x33\x5b\x91\x53\x8e\x16\x68\xf9\xf9\x64\x27\x90\xb4\xe5\x5f\x9c\xab\x0f\xe2\xbd\xd2\x93\x5d\x00\x1e\xe6\x41\x9a\xba\xb5\x45\x78\x80\xd0\xdb\xff\x20\xed\x87\x58\xf4\xc2\x0f\xe7\x59\xef\xb3\x31\x41\xcf\x0e\x89\x25\x87\xfe\x81\x87\xe5\xfb\xc5\x77\x86\xb7\xe8\xb0\x89\x61\x2c\x93\x6d\xfc\x03\xd2\x7e\xfb\xbe\x7c\x86\x73\xf1\x60\x6b\xd5\x1d\x5f\xf3\x86\xf4\xa7\xab\x68\xed\xf5\x9f\x38\x5e\xb1\x29\x1f\x11\x7b\xfe\x71\x73\x99",
+ "\xa8\xf0\xa3\xc8\x9c\xf7\xe5\x6a\xcc\x18\xac\xe1\x63\x8b\xcf\x13\x30\x94\xfd\x9f\x75\xf0\x56\x77\xc3\xcd\x0e\xd3\x61\x4a\x59\x3c\xbc\xeb\x09\xc7\x8c\x86\xe3\x50\xfd\x07\xff\x44\x29\xa6\xa1\x65",
+ 248 },
+ { GCRY_MD_SHA3_384,
+ "\x6a\x01\x83\x0a\xf3\x88\x9a\x25\x18\x32\x44\xde\xcb\x50\x8b\xd0\x12\x53\xd5\xb5\x08\xab\x49\x0d\x31\x24\xaf\xbf\x42\x62\x6b\x2e\x70\x89\x4e\x9b\x56\x2b\x28\x8d\x0a\x24\x50\xcf\xac\xf1\x4a\x0d\xda\xe5\xc0\x47\x16\xe5\xa0\x08\x2c\x33\x98\x1f\x60\x37\xd2\x3d\x5e\x04\x5e\xe1\xef\x22\x83\xfb\x8b\x63\x78\xa9\x14\xc5\xd9\x44\x16\x27\xa7\x22\xc2\x82\xff\x45\x2e\x25\xa7\xea\x60\x8d\x69\xce\xe4\x39\x3a\x07\x25\xd1\x79\x63\xd0\x34\x26\x84\xf2\x55\x49\x6d\x8a\x18\xc2\x96\x11\x45\x31\x51\x30\x54\x93\x11\xfc\x07\xf0\x31\x2f\xb7\x8e\x60\x77\x33\x4f\x87\xea\xa8\x73\xbe\xe8\xaa\x95\x69\x89\x96\xeb\x21\x37\x5e\xb2\xb4\xef\x53\xc1\x44\x01\x20\x7d\xeb\x45\x68\x39\x8e\x5d\xd9\xa7\xcf\x97\xe8\xc9\x66\x3e\x23\x33\x4b\x46\x91\x2f\x83\x44\xc1\x9e\xfc\xf8\xc2\xba\x6f\x04\x32\x5f\x1a\x27\xe0\x62\xb6\x2a\x58\xd0\x76\x6f\xc6\xdb\x4d\x2c\x6a\x19\x28\x60\x4b\x01\x75\xd8\x72\xd1\x6b\x79\x08\xeb\xc0\x41\x76\x11\x87\xcc\x78\x55\x26\xc2\xa3\x87\x3f\xea\xc3\xa6\x42\xbb\x39\xf5\x35\x15\x50\xaf\x97\x70\xc3\x28\xaf\x7b",
+ "\xc8\xa9\xa2\x44\x64\xf2\x1b\x13\x3e\xbe\x20\xba\x42\x1a\x81\xee\x34\xdc\xea\xcd\x5f\x04\xdc\xfb\x66\xd2\x19\xf7\xf4\x14\x56\x33\x69\x2c\x57\x2b\x63\x00\x78\x34\xa4\x06\xec\xfb\x93\x8a\x14\xf6",
+ 249 },
+ { GCRY_MD_SHA3_384,
+ "\xb3\xc5\xe7\x4b\x69\x93\x3c\x25\x33\x10\x6c\x56\x3b\x4c\xa2\x02\x38\xf2\xb6\xe6\x75\xe8\x68\x1e\x34\xa3\x89\x89\x47\x85\xbd\xad\xe5\x96\x52\xd4\xa7\x3d\x80\xa5\xc8\x5b\xd4\x54\xfd\x1e\x9f\xfd\xad\x1c\x38\x15\xf5\x03\x8e\x9e\xf4\x32\xaa\xc5\xc3\xc4\xfe\x84\x0c\xc3\x70\xcf\x86\x58\x0a\x60\x11\x77\x8b\xbe\xda\xf5\x11\xa5\x1b\x56\xd1\xa2\xeb\x68\x39\x4a\xa2\x99\xe2\x6d\xa9\xad\xa6\xa2\xf3\x9b\x9f\xaf\xf7\xfb\xa4\x57\x68\x9b\x9c\x1a\x57\x7b\x2a\x1e\x50\x5f\xdf\x75\xc7\xa0\xa6\x4b\x1d\xf8\x1b\x3a\x35\x60\x01\xbf\x0d\xf4\xe0\x2a\x1f\xc5\x9f\x65\x1c\x9d\x58\x5e\xc6\x22\x4b\xb2\x79\xc6\xbe\xba\x29\x66\xe8\x88\x2d\x68\x37\x60\x81\xb9\x87\x46\x8e\x7a\xed\x1e\xf9\x0e\xbd\x09\x0a\xe8\x25\x79\x5c\xdc\xa1\xb4\xf0\x9a\x97\x9c\x8d\xfc\x21\xa4\x8d\x8a\x53\xcd\xbb\x26\xc4\xdb\x54\x7f\xc0\x6e\xfe\x2f\x98\x50\xed\xd2\x68\x5a\x46\x61\xcb\x49\x11\xf1\x65\xd4\xb6\x3e\xf2\x5b\x87\xd0\xa9\x6d\x3d\xff\x6a\xb0\x75\x89\x99\xaa\xd2\x14\xd0\x7b\xd4\xf1\x33\xa6\x73\x4f\xde\x44\x5f\xe4\x74\x71\x1b\x69\xa9\x8f\x7e\x2b",
+ "\x91\xba\xda\x31\xb5\x7a\x4b\xf3\xd2\xeb\x19\xa3\x4f\xf9\x21\xdb\x10\xbd\x64\x06\x19\x14\x86\xd2\x5d\x5c\xa4\xde\x5e\x00\xb5\xe2\x81\x5d\xae\x74\x10\x64\xe5\xb8\x77\xac\x57\x51\x1b\x94\x9f\x91",
+ 250 },
+ { GCRY_MD_SHA3_384,
+ "\x83\xaf\x34\x27\x9c\xcb\x54\x30\xfe\xbe\xc0\x7a\x81\x95\x0d\x30\xf4\xb6\x6f\x48\x48\x26\xaf\xee\x74\x56\xf0\x07\x1a\x51\xe1\xbb\xc5\x55\x70\xb5\xcc\x7e\xc6\xf9\x30\x9c\x17\xbf\x5b\xef\xdd\x7c\x6b\xa6\xe9\x68\xcf\x21\x8a\x2b\x34\xbd\x5c\xf9\x27\xab\x84\x6e\x38\xa4\x0b\xbd\x81\x75\x9e\x9e\x33\x38\x10\x16\xa7\x55\xf6\x99\xdf\x35\xd6\x60\x00\x7b\x5e\xad\xf2\x92\xfe\xef\xb7\x35\x20\x7e\xbf\x70\xb5\xbd\x17\x83\x4f\x7b\xfa\x0e\x16\xcb\x21\x9a\xd4\xaf\x52\x4a\xb1\xea\x37\x33\x4a\xa6\x64\x35\xe5\xd3\x97\xfc\x0a\x06\x5c\x41\x1e\xbb\xce\x32\xc2\x40\xb9\x04\x76\xd3\x07\xce\x80\x2e\xc8\x2c\x1c\x49\xbc\x1b\xec\x48\xc0\x67\x5e\xc2\xa6\xc6\xf3\xed\x3e\x5b\x74\x1d\x13\x43\x70\x95\x70\x7c\x56\x5e\x10\xd8\xa2\x0b\x8c\x20\x46\x8f\xf9\x51\x4f\xcf\x31\xb4\x24\x9c\xd8\x2d\xce\xe5\x8c\x0a\x2a\xf5\x38\xb2\x91\xa8\x7e\x33\x90\xd7\x37\x19\x1a\x07\x48\x4a\x5d\x3f\x3f\xb8\xc8\xf1\x5c\xe0\x56\xe5\xe5\xf8\xfe\xbe\x5e\x1f\xb5\x9d\x67\x40\x98\x0a\xa0\x6c\xa8\xa0\xc2\x0f\x57\x12\xb4\xcd\xe5\xd0\x32\xe9\x2a\xb8\x9f\x0a\xe1",
+ "\xf3\x10\xe8\x09\x51\xc7\xbb\x63\x95\xca\x16\x8a\xae\x7e\xc4\x2d\xef\xf6\xc4\xcd\x3f\x5b\xe9\xc8\xb4\x9b\x85\xb4\x05\xf7\x31\x91\x1a\xe8\x26\x7f\xfe\xbd\x54\x3d\xbd\xf4\x09\xec\x20\xa8\x58\xd2",
+ 251 },
+ { GCRY_MD_SHA3_384,
+ "\xa7\xed\x84\x74\x9c\xcc\x56\xbb\x1d\xfb\xa5\x71\x19\xd2\x79\xd4\x12\xb8\xa9\x86\x88\x6d\x81\x0f\x06\x7a\xf3\x49\xe8\x74\x9e\x9e\xa7\x46\xa6\x0b\x03\x74\x26\x36\xc4\x64\xfc\x1e\xe2\x33\xac\xc5\x2c\x19\x83\x91\x46\x92\xb6\x43\x09\xed\xfd\xf2\x9f\x1a\xb9\x12\xec\x3e\x8d\xa0\x74\xd3\xf1\xd2\x31\x51\x1f\x57\x56\xf0\xb6\xee\xad\x3e\x89\xa6\xa8\x8f\xe3\x30\xa1\x0f\xac\xe2\x67\xbf\xfb\xfc\x3e\x30\x90\xc7\xfd\x9a\x85\x05\x61\xf3\x63\xad\x75\xea\x88\x1e\x72\x44\xf8\x0f\xf5\x58\x02\xd5\xef\x7a\x1a\x4e\x7b\x89\xfc\xfa\x80\xf1\x6d\xf5\x4d\x1b\x05\x6e\xe6\x37\xe6\x96\x4b\x9e\x0f\xfd\x15\xb6\x19\x6b\xdd\x7d\xb2\x70\xc5\x6b\x47\x25\x14\x85\x34\x8e\x49\x81\x3b\x4e\xb9\xed\x12\x2a\x01\xb3\xea\x45\xad\x5e\x1a\x92\x9d\xf6\x1d\x5c\x0f\x3e\x77\xe1\xfd\xc3\x56\xb6\x38\x83\xa6\x0e\x9c\xbb\x9f\xc3\xe0\x0c\x2f\x32\xdb\xd4\x69\x65\x98\x83\xf6\x90\xc6\x77\x2e\x33\x5f\x61\x7b\xc3\x3f\x16\x1d\x6f\x69\x84\x25\x2e\xe1\x2e\x62\xb6\x00\x0a\xc5\x23\x1e\x0c\x9b\xc6\x5b\xe2\x23\xd8\xdf\xd9\x4c\x50\x04\xa1\x01\xaf\x9f\xd6\xc0\xfb",
+ "\xcf\xd0\x5e\x08\x09\x94\xfc\x6d\x7a\xef\x2d\x8c\x6e\x44\xd8\xa5\xe9\x0f\x5a\x23\x16\x76\xe0\xfa\xe0\xd2\xb8\xce\x16\x2c\xa9\xd0\x67\x12\x58\x0c\x99\x99\x7a\x77\x09\xa0\x61\x80\xdd\x42\xfb\x91",
+ 252 },
+ { GCRY_MD_SHA3_384,
+ "\xa6\xfe\x30\xdc\xfc\xda\x1a\x32\x9e\x82\xab\x50\xe3\x2b\x5f\x50\xeb\x25\xc8\x73\xc5\xd2\x30\x58\x60\xa8\x35\xae\xce\xe6\x26\x4a\xa3\x6a\x47\x42\x99\x22\xc4\xb8\xb3\xaf\xd0\x0d\xa1\x60\x35\x83\x0e\xdb\x89\x78\x31\xc4\xe7\xb0\x0f\x2c\x23\xfc\x0b\x15\xfd\xc3\x0d\x85\xfb\x70\xc3\x0c\x43\x1c\x63\x8e\x1a\x25\xb5\x1c\xaf\x1d\x7e\x8b\x05\x0b\x7f\x89\xbf\xb3\x0f\x59\xf0\xf2\x0f\xec\xff\x3d\x63\x9a\xbc\x42\x55\xb3\x86\x8f\xc4\x5d\xd8\x1e\x47\xeb\x12\xab\x40\xf2\xaa\xc7\x35\xdf\x5d\x1d\xc1\xad\x99\x7c\xef\xc4\xd8\x36\xb8\x54\xce\xe9\xac\x02\x90\x00\x36\xf3\x86\x7f\xe0\xd8\x4a\xff\xf3\x7b\xde\x33\x08\xc2\x20\x6c\x62\xc4\x74\x33\x75\x09\x41\x08\x87\x7c\x73\xb8\x7b\x25\x46\xfe\x05\xea\x13\x7b\xed\xfc\x06\xa2\x79\x62\x74\x09\x9a\x0d\x55\x4d\xa8\xf7\xd7\x22\x3a\x48\xcb\xf3\x1b\x7d\xec\xaa\x1e\xbc\x8b\x14\x57\x63\xe3\x67\x31\x68\xc1\xb1\xb7\x15\xc1\xcd\x99\xec\xd3\xdd\xb2\x38\xb0\x60\x49\x88\x5e\xca\xd9\x34\x7c\x24\x36\xdf\xf3\x2c\x77\x1f\x34\xa3\x85\x87\xa4\x4a\x82\xc5\xd3\xd1\x37\xa0\x3c\xaa\x27\xe6\x6c\x8f\xf6",
+ "\x8f\xa2\x6d\xd5\xa5\x4b\xf9\x4a\x03\x7a\x16\x5e\xc5\xce\x3e\xd8\x61\x47\xa0\x8d\xcf\xe3\xb4\x88\x18\xb0\xc0\xbe\xee\xfa\x33\xb1\x45\x32\x3b\x59\x8f\x76\x1d\xe2\xb6\x39\xd0\x51\x27\xf1\xcf\x3e",
+ 253 },
+ { GCRY_MD_SHA3_384,
+ "\x83\x16\x7f\xf5\x37\x04\xc3\xaa\x19\xe9\xfb\x33\x03\x53\x97\x59\xc4\x6d\xd4\x09\x1a\x52\xdd\xae\x9a\xd8\x64\x08\xb6\x93\x35\x98\x9e\x61\x41\x4b\xc2\x0a\xb4\xd0\x12\x20\xe3\x52\x41\xef\xf5\xc9\x52\x2b\x07\x9f\xba\x59\x76\x74\xc8\xd7\x16\xfe\x44\x1e\x56\x61\x10\xb6\x21\x15\x31\xce\xcc\xf8\xfd\x06\xbc\x8e\x51\x1d\x00\x78\x5e\x57\x78\x8e\xd9\xa1\xc5\xc7\x35\x24\xf0\x18\x30\xd2\xe1\x14\x8c\x92\xd0\xed\xc9\x71\x13\xe3\xb7\xb5\xcd\x30\x49\x62\x7a\xbd\xb8\xb3\x9d\xd4\xd6\x89\x0e\x0e\xe9\x19\x93\xf9\x2b\x03\x35\x4a\x88\xf5\x22\x51\xc5\x46\xe6\x44\x34\xd9\xc3\xd7\x45\x44\xf2\x3f\xb9\x3e\x5a\x2d\x2f\x1f\xb1\x55\x45\xb4\xe1\x36\x7c\x97\x33\x5b\x02\x91\x94\x4c\x8b\x73\x0a\xd3\xd4\x78\x92\x73\xfa\x44\xfb\x98\xd7\x8a\x36\xc3\xc3\x76\x4a\xbe\xea\xc7\xc5\x69\xc1\xe4\x3a\x35\x2e\x5b\x77\x0c\x35\x04\xf8\x70\x90\xde\xe0\x75\xa1\xc4\xc8\x5c\x0c\x39\xcf\x42\x1b\xdc\xc6\x15\xf9\xef\xf6\xcb\x4f\xe6\x46\x80\x04\xae\xce\x5f\x30\xe1\xec\xc6\xdb\x22\xad\x99\x39\xbb\x2b\x0c\xcc\x96\x52\x1d\xfb\xf4\xae\x00\x8b\x5b\x46\xbc\x00\x6e",
+ "\x28\x3f\xd6\x1d\x1e\x50\x57\x2e\xf4\x03\xbf\x9c\x55\x4d\x76\xd6\x94\xa5\x4f\x90\x2c\x49\x79\x5d\x1c\xf5\x06\xf0\xee\x26\x3e\x7b\xa9\x94\xf7\x2b\xdc\x47\x32\x53\x1f\xa7\x19\x42\x57\xf2\xdf\xda",
+ 254 },
+ { GCRY_MD_SHA3_384,
+ "\x3a\x3a\x81\x9c\x48\xef\xde\x2a\xd9\x14\xfb\xf0\x0e\x18\xab\x6b\xc4\xf1\x45\x13\xab\x27\xd0\xc1\x78\xa1\x88\xb6\x14\x31\xe7\xf5\x62\x3c\xb6\x6b\x23\x34\x67\x75\xd3\x86\xb5\x0e\x98\x2c\x49\x3a\xdb\xbf\xc5\x4b\x9a\x3c\xd3\x83\x38\x23\x36\xa1\xa0\xb2\x15\x0a\x15\x35\x8f\x33\x6d\x03\xae\x18\xf6\x66\xc7\x57\x3d\x55\xc4\xfd\x18\x1c\x29\xe6\xcc\xfd\xe6\x3e\xa3\x5f\x0a\xdf\x58\x85\xcf\xc0\xa3\xd8\x4a\x2b\x2e\x4d\xd2\x44\x96\xdb\x78\x9e\x66\x31\x70\xce\xf7\x47\x98\xaa\x1b\xbc\xd4\x57\x4e\xa0\xbb\xa4\x04\x89\xd7\x64\xb2\xf8\x3a\xad\xc6\x6b\x14\x8b\x4a\x0c\xd9\x52\x46\xc1\x27\xd5\x87\x1c\x4f\x11\x41\x86\x90\xa5\xdd\xf0\x12\x46\xa0\xc8\x0a\x43\xc7\x00\x88\xb6\x18\x36\x39\xdc\xfd\xa4\x12\x5b\xd1\x13\xa8\xf4\x9e\xe2\x3e\xd3\x06\xfa\xac\x57\x6c\x3f\xb0\xc1\xe2\x56\x67\x1d\x81\x7f\xc2\x53\x4a\x52\xf5\xb4\x39\xf7\x2e\x42\x4d\xe3\x76\xf4\xc5\x65\xcc\xa8\x23\x07\xdd\x9e\xf7\x6d\xa5\xb7\xc4\xeb\x7e\x08\x51\x72\xe3\x28\x80\x7c\x02\xd0\x11\xff\xbf\x33\x78\x53\x78\xd7\x9d\xc2\x66\xf6\xa5\xbe\x6b\xb0\xe4\xa9\x2e\xce\xeb\xae\xb1",
+ "\x12\x8d\xc6\x11\x76\x2b\xe9\xb1\x35\xb3\x73\x94\x84\xcf\xaa\xdc\xa7\x48\x1d\x68\x51\x4f\x3d\xfd\x6f\x5d\x78\xbb\x18\x63\xae\x68\x13\x08\x35\xcd\xc7\x06\x1a\x7e\xd9\x64\xb3\x2f\x1d\xb7\x5e\xe1",
+ 255 },
diff --git a/comm/third_party/libgcrypt/tests/sha3-512.h b/comm/third_party/libgcrypt/tests/sha3-512.h
new file mode 100644
index 0000000000..b91e7b2ab9
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/sha3-512.h
@@ -0,0 +1,1025 @@
+/* Generated from https://raw.githubusercontent.com/gvanas/KeccakCodePackage/master/TestVectors/ShortMsgKAT_SHA3-512.txt */
+ { 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",
+ 0 },
+ { GCRY_MD_SHA3_512,
+ "\xcc",
+ "\x39\x39\xfc\xc8\xb5\x7b\x63\x61\x25\x42\xda\x31\xa8\x34\xe5\xdc\xc3\x6e\x2e\xe0\xf6\x52\xac\x72\xe0\x26\x24\xfa\x2e\x5a\xde\xec\xc7\xdd\x6b\xb3\x58\x02\x24\xb4\xd6\x13\x87\x06\xfc\x6e\x80\x59\x7b\x52\x80\x51\x23\x0b\x00\x62\x1c\xc2\xb2\x29\x99\xea\xa2\x05",
+ 1 },
+ { GCRY_MD_SHA3_512,
+ "\x41\xfb",
+ "\xaa\x09\x28\x65\xa4\x06\x94\xd9\x17\x54\xdb\xc7\x67\xb5\x20\x2c\x54\x6e\x22\x68\x77\x14\x7a\x95\xcb\x8b\x4c\x8f\x87\x09\xfe\x8c\xd6\x90\x52\x56\xb0\x89\xda\x37\x89\x6e\xa5\xca\x19\xd2\xcd\x9a\xb9\x4c\x71\x92\xfc\x39\xf7\xcd\x4d\x59\x89\x75\xa3\x01\x3c\x69",
+ 2 },
+ { GCRY_MD_SHA3_512,
+ "\x1f\x87\x7c",
+ "\xcb\x20\xdc\xf5\x49\x55\xf8\x09\x11\x11\x68\x8b\xec\xce\xf4\x8c\x1a\x2f\x0d\x06\x08\xc3\xa5\x75\x16\x37\x51\xf0\x02\xdb\x30\xf4\x0f\x2f\x67\x18\x34\xb2\x2d\x20\x85\x91\xcf\xaf\x1f\x5e\xcf\xe4\x3c\x49\x86\x3a\x53\xb3\x22\x5b\xdf\xd7\xc6\x59\x1b\xa7\x65\x8b",
+ 3 },
+ { GCRY_MD_SHA3_512,
+ "\xc1\xec\xfd\xfc",
+ "\xd4\xb4\xbd\xfe\xf5\x6b\x82\x1d\x36\xf4\xf7\x0a\xb0\xd2\x31\xb8\xd0\xc9\x13\x46\x38\xfd\x54\xc4\x63\x09\xd1\x4f\xad\xa9\x2a\x28\x40\x18\x6e\xed\x54\x15\xad\x7c\xf3\x96\x9b\xdf\xbf\x2d\xaf\x8c\xca\x76\xab\xfe\x54\x9b\xe6\x57\x8c\x6f\x41\x43\x61\x7a\x4f\x1a",
+ 4 },
+ { GCRY_MD_SHA3_512,
+ "\x21\xf1\x34\xac\x57",
+ "\x58\x42\x19\xa8\x4e\x87\x96\x07\x6b\xf1\x17\x8b\x14\xb9\xd1\xe2\xf9\x6a\x4b\x4e\xf1\x1f\x10\xcc\x51\x6f\xbe\x1a\x29\x63\x9d\x6b\xa7\x4f\xb9\x28\x15\xf9\xe3\xc5\x19\x2e\xd4\xdc\xa2\x0a\xea\x5b\x10\x9d\x52\x23\x7c\x99\x56\x40\x1f\xd4\x4b\x22\x1f\x82\xab\x37",
+ 5 },
+ { GCRY_MD_SHA3_512,
+ "\xc6\xf5\x0b\xb7\x4e\x29",
+ "\x43\x45\xb9\x2a\x2a\xb7\xea\xdb\x6a\x24\xee\x1d\x17\x5a\xc2\x58\xcc\xf2\xf6\x94\xac\x09\xec\x9d\x47\x39\x9e\x4d\x96\xf6\x1f\x30\xb3\x22\xc5\x43\x8c\x51\xba\xcd\x0d\x59\x7d\x00\x47\x1a\x41\xed\x8e\x9c\x9f\x14\x6b\xbc\x80\x7e\x6b\xc3\x85\xf8\x50\xfb\xab\xfe",
+ 6 },
+ { GCRY_MD_SHA3_512,
+ "\x11\x97\x13\xcc\x83\xee\xef",
+ "\x50\x08\x1c\x93\xbf\x73\xec\xc5\x4a\x5f\xfe\x43\xfc\x14\xf8\xba\xee\xdb\xe7\xda\x03\x02\xac\x98\x4c\x9e\x66\x83\x89\x88\x6b\xd0\x64\xba\xb2\x6d\xdc\xb6\x16\xeb\x4e\x0e\x72\x60\x42\xb1\x9f\x3f\xd5\x0b\xdd\x0d\x2c\x5b\x34\x89\x2e\x00\xe6\xf3\x99\xde\x25\x4f",
+ 7 },
+ { GCRY_MD_SHA3_512,
+ "\x4a\x4f\x20\x24\x84\x51\x25\x26",
+ "\x15\x0d\x78\x7d\x6e\xb4\x96\x70\xc2\xa4\xcc\xd1\x7e\x6c\xce\x7a\x04\xc1\xfe\x30\xfc\xe0\x3d\x1e\xf2\x50\x17\x52\xd9\x2a\xe0\x4c\xb3\x45\xfd\x42\xe5\x10\x38\xc8\x3b\x2b\x4f\x8f\xd4\x38\xd1\xb4\xb5\x5c\xc5\x88\xc6\xb9\x13\x13\x2f\x1a\x65\x8f\xb1\x22\xcb\x52",
+ 8 },
+ { GCRY_MD_SHA3_512,
+ "\x1f\x66\xab\x41\x85\xed\x9b\x63\x75",
+ "\xa1\x3c\x95\x1c\x6c\x51\xf2\x36\xa0\x19\x7a\x29\xa8\x99\x4b\x1c\x72\x94\xe1\x7b\xa5\x18\xed\x10\x29\xd6\xf5\x4a\xd7\x39\xd8\x76\x59\x20\x28\x1b\xbb\x85\x4d\x16\xfb\xb6\x0e\x03\x85\xaf\xd6\xe6\xe4\x33\xe6\x3a\xaa\x77\xe7\x3b\x8b\xee\x7f\xde\x56\x9d\x68\x75",
+ 9 },
+ { GCRY_MD_SHA3_512,
+ "\xee\xd7\x42\x22\x27\x61\x3b\x6f\x53\xc9",
+ "\x5a\x56\x6f\xb1\x81\xbe\x53\xa4\x10\x92\x75\x53\x7d\x80\xe5\xfd\x0f\x31\x4d\x68\x88\x45\x29\xca\x66\xb8\xb0\xe9\xf2\x40\xa6\x73\xb6\x4b\x28\xff\xfe\x4c\x1e\xc4\xa5\xce\xf0\xf4\x30\x22\x9c\x57\x57\xeb\xd1\x72\xb4\xb0\xb6\x8a\x81\xd8\xc5\x8a\x9e\x96\xe1\x64",
+ 10 },
+ { GCRY_MD_SHA3_512,
+ "\xea\xee\xd5\xcd\xff\xd8\x9d\xec\xe4\x55\xf1",
+ "\x7c\x77\xe3\x0e\xce\x98\xef\x88\x96\x44\x58\x68\x3c\x5e\x02\x87\xb5\x89\x6e\x16\x6c\xcc\xa7\x1d\x2b\xfd\x8d\x8b\xbc\x6d\x6f\xe5\x89\xa0\x22\x5e\xb1\xd6\xaa\x7b\x22\x0f\x14\x10\xc9\xa9\xec\x06\x72\xcc\xdd\xaa\x17\x32\xc3\xe2\x87\x7f\xb5\xd2\x32\xc2\xa4\x28",
+ 11 },
+ { GCRY_MD_SHA3_512,
+ "\x5b\xe4\x3c\x90\xf2\x29\x02\xe4\xfe\x8e\xd2\xd3",
+ "\xf5\xdf\x59\x52\x92\x4e\x93\x33\x30\xbd\x5b\xd7\x62\x7a\x62\xc3\x67\x2f\x24\xa4\x99\x1d\xad\xaf\x78\x81\x6e\x02\x37\x69\xc9\x1d\x19\x10\x53\x7f\x9c\x19\xfc\xde\x60\xfa\x6d\xe9\x27\x98\x2d\xd5\xf5\x97\x0f\x74\xe3\x0f\x2b\x04\x0f\x67\x34\x8a\x33\x94\xc4\x8c",
+ 12 },
+ { GCRY_MD_SHA3_512,
+ "\xa7\x46\x27\x32\x28\x12\x2f\x38\x1c\x3b\x46\xe4\xf1",
+ "\x80\xa1\x31\x7e\xc5\x34\xed\x48\xd8\xa8\x13\xe0\xbc\xa0\xce\xe0\x4f\x70\x5a\x2f\x86\x35\x23\x06\xa9\x32\xed\xc5\x48\xb9\xa8\xf1\xcf\x79\xf9\x50\x27\xf4\x3b\xda\xda\x82\x13\x44\x9c\x54\xf6\x8f\x4d\xd8\x00\xb1\x5c\x4a\xba\xd8\x7a\xd7\xa3\xb3\x71\xa7\xc9\x18",
+ 13 },
+ { GCRY_MD_SHA3_512,
+ "\x3c\x58\x71\xcd\x61\x9c\x69\xa6\x3b\x54\x0e\xb5\xa6\x25",
+ "\x54\xc2\x74\xc3\xdd\xf2\x6d\x82\x4f\x5f\xdf\xcb\x34\x9a\x60\x08\x90\x05\x7e\xb2\xe2\x02\x22\x45\xcb\xb8\xbd\xc0\xd2\x24\x0c\xfa\x83\x48\xf0\x21\x91\xfa\xbc\x0e\x10\xf9\x28\x71\x85\x21\x1c\x9f\x56\x91\x32\xee\x6d\xde\x4c\x39\x66\x68\xb4\xbb\x50\xae\xfc\x3f",
+ 14 },
+ { GCRY_MD_SHA3_512,
+ "\xfa\x22\x87\x4b\xcc\x06\x88\x79\xe8\xef\x11\xa6\x9f\x07\x22",
+ "\x00\x76\x72\x36\xa7\x35\x25\x51\xb2\x83\xa8\xec\xf4\xc7\x92\x74\xf8\xc4\xce\xa5\x53\xab\x43\xfc\x71\xcf\x22\xfb\x2f\x68\x65\xad\x02\xc8\x8b\xf0\x09\x2f\x21\x30\x57\x34\x0c\x85\xa5\x31\x8f\x62\xf4\x99\x1c\x00\xc6\x3c\xb0\x55\x8c\xbc\xf1\x3d\x6d\x84\xe7\x3d",
+ 15 },
+ { GCRY_MD_SHA3_512,
+ "\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76",
+ "\x00\x16\x18\x37\x2e\x75\x14\x7a\xf9\x0c\x0c\xf1\x6c\x3b\xbd\xaa\x06\x9d\xdb\xc6\x24\x83\xb3\x92\xd0\x28\xde\xd4\x9f\x75\x08\x4a\x5d\xfc\xc5\x3a\xec\xd9\xf5\x7d\xdb\xb7\x3d\xaa\x04\x1f\xd7\x10\x89\xd8\xfb\x5e\xdf\x6c\xfa\xf6\xf1\xe4\xe2\x5a\xd3\xde\x26\x6c",
+ 16 },
+ { GCRY_MD_SHA3_512,
+ "\x82\xe1\x92\xe4\x04\x3d\xdc\xd1\x2e\xcf\x52\x96\x9d\x0f\x80\x7e\xed",
+ "\x96\x44\xe3\xc9\x0b\x67\xe2\x21\x24\xe9\x6d\xfe\xdc\xe5\x3d\x33\xc4\x60\xf1\x32\x86\x8f\x09\x75\xd1\x8b\x22\xcf\xd5\x9f\x63\x7d\xd8\x5a\xa4\x05\xe3\x98\x08\xa4\x55\x70\xa4\x98\xc0\xb8\xf2\xcb\xa5\x9f\x8e\x14\x37\xea\xef\x89\xf2\x0b\x88\x29\x8a\xdf\xa2\xde",
+ 17 },
+ { GCRY_MD_SHA3_512,
+ "\x75\x68\x3d\xcb\x55\x61\x40\xc5\x22\x54\x3b\xb6\xe9\x09\x8b\x21\xa2\x1e",
+ "\x47\x39\x99\x43\x90\x72\x8f\x4a\x93\x8d\xf7\xb3\x20\x1c\xd6\x37\x71\x85\x84\x53\xf0\xff\x1d\xde\x9a\x2b\x9c\x38\xa2\x7a\x0f\x6c\x86\x84\x60\xd0\x0e\xe0\x3d\xdc\xb0\xf0\x63\xf5\xf8\xbb\x7c\xb0\x95\x9b\x7a\x22\x22\x59\xda\x0f\x2c\x57\xfa\x40\x0b\x50\x98\x5b",
+ 18 },
+ { GCRY_MD_SHA3_512,
+ "\x06\xe4\xef\xe4\x50\x35\xe6\x1f\xaa\xf4\x28\x7b\x4d\x8d\x1f\x12\xca\x97\xe5",
+ "\xaf\x69\xa4\x65\x27\xc1\x71\x17\xe6\xdf\xf3\x2c\xba\x28\x9e\xdd\xd1\xee\xcd\xa1\x3e\x53\x13\xe4\x66\x78\xeb\x80\x06\xe7\x63\x98\x54\xc3\x97\x0d\xfe\xb4\xd9\x07\xdb\x11\x51\xc1\xc5\xee\x25\xca\x6f\x19\x5b\x09\xca\x5a\x5c\xc9\x7a\x4d\x64\xac\x4c\x75\x57\x8e",
+ 19 },
+ { GCRY_MD_SHA3_512,
+ "\xe2\x61\x93\x98\x9d\x06\x56\x8f\xe6\x88\xe7\x55\x40\xae\xa0\x67\x47\xd9\xf8\x51",
+ "\x19\x1c\xef\x1c\x6a\xa0\x09\xb1\xab\xa6\x74\xbe\x2b\x3f\x0d\xa4\x18\xfd\xf9\xe6\xa7\xec\xf2\xbe\x42\xac\x14\xf7\xd6\xe0\x73\x31\x42\x51\x33\xa8\x3b\x4e\x01\x61\xcc\x7d\xeb\xf9\xdc\xd7\xfe\x37\x87\xdc\xb6\x62\x2a\x38\x47\x51\x89\xed\xfe\x1d\xe6\xb0\x53\xd6",
+ 20 },
+ { GCRY_MD_SHA3_512,
+ "\xd8\xdc\x8f\xde\xfb\xdc\xe9\xd4\x4e\x4c\xba\xfe\x78\x44\x7b\xae\x3b\x54\x36\x10\x2a",
+ "\xa6\x0d\x75\x87\x42\x4b\x72\x42\xd9\x3b\xcc\xe5\x15\xf1\xc7\x5a\xe2\xbe\x77\x10\xf7\x2e\xd3\xf4\xe5\xea\x8b\xc2\xba\x8d\x64\x09\x9f\xe4\x2b\x88\xa2\x95\xe1\x2f\xda\xfa\xb4\x41\xd7\x72\xc4\xa9\xa7\xd7\x94\xb2\x77\x88\xed\xea\x27\x15\x71\xa0\x43\x05\xf2\x53",
+ 21 },
+ { GCRY_MD_SHA3_512,
+ "\x57\x08\x5f\xd7\xe1\x42\x16\xab\x10\x2d\x83\x17\xb0\xcb\x33\x8a\x78\x6d\x5f\xc3\x2d\x8f",
+ "\x09\xfc\xad\x97\xea\x3c\xb6\xb7\xfc\x61\x58\x0d\xe0\x96\x8d\x23\x80\x06\xb7\xe7\x1f\x0b\xd5\x8a\xba\x2a\xa9\xd4\xad\xb8\x55\xd7\x60\x6e\x76\x32\x13\x8c\xcc\x0a\xa0\x65\xca\x0b\x92\x42\x22\x62\xe0\x29\xda\x17\xd7\x3c\xd3\x01\x1f\xf2\x85\x70\x6c\x7f\xc1\xae",
+ 22 },
+ { GCRY_MD_SHA3_512,
+ "\xa0\x54\x04\xdf\x5d\xbb\x57\x69\x7e\x2c\x16\xfa\x29\xde\xfa\xc8\xab\x35\x60\xd6\x12\x6f\xa0",
+ "\xf6\x1f\xaa\xb0\x80\xcf\x9a\x5f\x75\x40\x7b\x08\x1a\x03\xde\xf4\xf4\x9a\x60\x1a\x2b\xb8\x32\xe8\xc6\x40\x1b\xe0\xc9\x8b\x3c\xeb\x3f\x75\xc9\x22\xa9\x1b\xd5\x06\x0b\x32\x17\xf7\x37\x40\x4e\xf4\x61\x2b\x9a\x00\x9b\x69\xca\x64\x8b\x1e\x37\xb2\xed\x49\x22\x9d",
+ 23 },
+ { GCRY_MD_SHA3_512,
+ "\xae\xcb\xb0\x27\x59\xf7\x43\x3d\x6f\xcb\x06\x96\x3c\x74\x06\x1c\xd8\x3b\x5b\x3f\xfa\x6f\x13\xc6",
+ "\x51\xde\x0a\x62\x2f\xc6\xfc\x70\x2c\x7c\x2d\xb5\xcc\xb0\x5c\xa0\xdd\xf7\x92\x98\x6e\x44\xb4\xd3\x36\xa7\xa5\xda\xf1\x9a\x20\xa3\x71\xd9\xbf\x7d\xde\x82\x2e\xcd\xd0\xa4\xce\x28\xe4\xa0\xb4\x6f\xe5\x1a\x2a\xab\xef\xa7\x86\x58\x07\xef\x3d\x3b\x18\x87\xf1\x4d",
+ 24 },
+ { GCRY_MD_SHA3_512,
+ "\xaa\xfd\xc9\x24\x3d\x3d\x4a\x09\x65\x58\xa3\x60\xcc\x27\xc8\xd8\x62\xf0\xbe\x73\xdb\x5e\x88\xaa\x55",
+ "\x62\x86\xc3\xdb\x87\xd3\xb4\x5c\xfd\x4d\xe8\x5a\x7a\xdd\x18\xe0\x7a\xe2\x2f\x1f\x0f\x46\x75\xe1\xd4\xe1\xfc\x77\x63\x37\x34\xd7\x96\x28\x18\xa9\xf3\xb9\x6b\x37\xfe\x77\x4f\xc2\x6d\xea\x78\x74\x85\x31\x7b\x96\x22\x27\x5f\x63\xa7\xdd\x6d\x62\xd6\x50\xd3\x07",
+ 25 },
+ { GCRY_MD_SHA3_512,
+ "\x7b\xc8\x48\x67\xf6\xf9\xe9\xfd\xc3\xe1\x04\x6c\xae\x3a\x52\xc7\x7e\xd4\x85\x86\x0e\xe2\x60\xe3\x0b\x15",
+ "\x81\x46\xc4\x3a\x0f\xfe\x48\x18\x72\x14\x2f\x56\xa9\xce\xa4\x43\x32\xed\xc7\x6b\x4e\x99\xc2\xbd\xc3\x9d\x7f\x80\xb2\xa6\xb5\x54\xc7\x59\x8f\x09\x85\x5b\xf7\xab\xc5\xe6\xc0\x48\xbe\x76\xf5\xf3\x69\xeb\xb2\x88\x4e\x6e\x37\xf1\x86\xe8\x71\x9d\xf3\xd5\x23\xe4",
+ 26 },
+ { GCRY_MD_SHA3_512,
+ "\xfa\xc5\x23\x57\x5a\x99\xec\x48\x27\x9a\x7a\x45\x9e\x98\xff\x90\x19\x18\xa4\x75\x03\x43\x27\xef\xb5\x58\x43",
+ "\x4b\x86\xfb\xf9\xdf\xb6\x76\x7e\xb6\x60\xaf\x9c\x30\x98\x3e\xd6\x5b\x6f\xd0\x51\x24\x7a\xb5\x47\x67\xdf\xb4\x95\x30\xeb\x3c\x01\x01\x4e\xb2\x6d\xf6\x3e\x53\x6c\xf5\x5e\x0b\xce\x2f\x62\x65\x4f\xb2\xfc\xe3\x83\x9b\x4b\xfd\x30\x15\x70\xb1\xab\x79\x4d\xf6\x7d",
+ 27 },
+ { GCRY_MD_SHA3_512,
+ "\x0f\x8b\x2d\x8f\xcf\xd9\xd6\x8c\xff\xc1\x7c\xcf\xb1\x17\x70\x9b\x53\xd2\x64\x62\xa3\xf3\x46\xfb\x7c\x79\xb8\x5e",
+ "\x21\x13\x2f\xc1\x1f\x60\x40\xad\x49\x3d\x62\x70\x27\xc7\x52\xce\x29\x81\x65\x89\xde\x7b\xe7\x85\x62\x91\x4b\x63\xd1\xa9\x21\x98\x03\xdd\xbd\x96\x73\xaa\x74\x9f\x37\xff\x4d\x6e\x1b\x5a\xe2\xa1\x26\x33\xba\x8b\x0c\x99\x94\xe0\x31\xeb\xf6\xc4\x2e\x58\xa7\x93",
+ 28 },
+ { GCRY_MD_SHA3_512,
+ "\xa9\x63\xc3\xe8\x95\xff\x5a\x0b\xe4\x82\x44\x00\x51\x8d\x81\x41\x2f\x87\x5f\xa5\x05\x21\xe2\x6e\x85\xea\xc9\x0c\x04",
+ "\x8a\x53\x74\xd9\x2f\xf9\xa5\x8e\x04\x51\xe6\x09\xaa\x5c\x0c\x5c\x17\x2b\xb2\x06\x8c\x80\x56\x2d\x03\x24\xf9\xcb\x6a\x03\x74\x36\x91\x0c\x65\x93\xf9\x50\xc4\x43\x74\xb4\xe5\xbf\x6f\x6d\x3a\x43\x6e\xce\x6d\xaa\xeb\x56\xd1\x47\xd8\xcd\x83\x9c\xca\x35\xea\xc3",
+ 29 },
+ { GCRY_MD_SHA3_512,
+ "\x03\xa1\x86\x88\xb1\x0c\xc0\xed\xf8\x3a\xdf\x0a\x84\x80\x8a\x97\x18\x38\x3c\x40\x70\xc6\xc4\xf2\x95\x09\x86\x99\xac\x2c",
+ "\x71\x02\x5d\x08\x9a\x39\xd2\x73\x27\xc4\x6c\x27\xbd\x4e\x75\x65\xdd\xbf\x9c\x28\x6f\x18\x5a\x08\x17\x86\x01\xc3\xba\xb4\x66\x7f\x36\x8a\x3a\x8b\xdd\xac\xf2\x5b\x2b\x0a\xa5\xc9\xe0\xcd\x6c\x87\xdc\x32\xc8\x54\x02\x7a\x89\x54\xb5\xc6\xaf\xd3\xa8\x50\x97\xac",
+ 30 },
+ { GCRY_MD_SHA3_512,
+ "\x84\xfb\x51\xb5\x17\xdf\x6c\x5a\xcc\xb5\xd0\x22\xf8\xf2\x8d\xa0\x9b\x10\x23\x2d\x42\x32\x0f\xfc\x32\xdb\xec\xc3\x83\x5b\x29",
+ "\xdc\x29\xeb\x71\x30\x81\x2a\x65\x2a\xf3\xff\x9b\x77\x62\x96\x84\x63\x45\x02\xea\x66\x67\xe7\xe9\xf8\x00\x90\xec\x2a\x9d\x69\x0c\x8c\x9a\x78\x64\x5f\xb0\x4d\x9c\xd2\x69\xe7\x06\xee\x2c\x96\xe7\x42\x07\xfb\xbd\xa5\x59\xdc\x28\x5c\x9b\xc5\x2f\x15\xa2\x56\xca",
+ 31 },
+ { GCRY_MD_SHA3_512,
+ "\x9f\x2f\xcc\x7c\x90\xde\x09\x0d\x6b\x87\xcd\x7e\x97\x18\xc1\xea\x6c\xb2\x11\x18\xfc\x2d\x5d\xe9\xf9\x7e\x5d\xb6\xac\x1e\x9c\x10",
+ "\xb0\x87\xc9\x04\x21\xae\xbf\x87\x91\x16\x47\xde\x9d\x46\x5c\xbd\xa1\x66\xb6\x72\xec\x47\xcc\xd4\x05\x4a\x71\x35\xa1\xef\x88\x5e\x79\x03\xb5\x2c\x3f\x2c\x3f\xe7\x22\xb1\xc1\x69\x29\x7a\x91\xb8\x24\x28\x95\x6a\x02\xc6\x31\xa2\x24\x0f\x12\x16\x2c\x7b\xc7\x26",
+ 32 },
+ { GCRY_MD_SHA3_512,
+ "\xde\x8f\x1b\x3f\xaa\x4b\x70\x40\xed\x45\x63\xc3\xb8\xe5\x98\x25\x31\x78\xe8\x7e\x4d\x0d\xf7\x5e\x4f\xf2\xf2\xde\xdd\x5a\x0b\xe0\x46",
+ "\xd2\xa9\x5c\x6f\xc0\xf3\x9c\x8f\x7a\x86\xc4\xdd\x62\x61\xa7\x9c\x94\x0f\xcb\x31\x3b\xcf\xba\x9b\xf7\x15\x27\xf5\xbc\x70\xef\x82\x7c\xd9\x7d\xfa\x18\x28\x0e\x5d\xde\xe5\xcc\xbc\x1d\x63\xce\x88\xce\x2b\xcd\xd8\x2d\xab\x61\x0f\x79\x86\x7a\x7c\x20\xb1\x1e\x4f",
+ 33 },
+ { GCRY_MD_SHA3_512,
+ "\x62\xf1\x54\xec\x39\x4d\x0b\xc7\x57\xd0\x45\xc7\x98\xc8\xb8\x7a\x00\xe0\x65\x5d\x04\x81\xa7\xd2\xd9\xfb\x58\xd9\x3a\xed\xc6\x76\xb5\xa0",
+ "\xaf\x8c\x0f\xbd\x72\xb3\xf8\x07\xdb\x95\xc9\x23\x1b\xc4\xe9\x31\x53\xdc\x66\x08\xb2\x2f\x47\x07\x31\x6a\xab\x3d\x69\xaf\x0e\x63\x29\x1b\x56\x9f\x11\x8b\x5c\x9e\x69\x3c\x5b\xac\x46\x30\xc4\xa9\x23\xa4\x74\x35\x81\x24\x6a\xd3\x44\x6d\xda\x4f\x90\x76\xfd\xdb",
+ 34 },
+ { GCRY_MD_SHA3_512,
+ "\xb2\xdc\xfe\x9f\xf1\x9e\x2b\x23\xce\x7d\xa2\xa4\x20\x7d\x3e\x5e\xc7\xc6\x11\x2a\x8a\x22\xae\xc9\x67\x5a\x88\x63\x78\xe1\x4e\x5b\xfb\xad\x4e",
+ "\xbf\xc7\xd9\x68\xd4\x53\x42\x06\x98\x07\xc5\xf1\xb9\x64\x25\xcf\xff\xe9\x9e\xd1\x36\xd4\x76\x65\xe9\x02\xe0\x26\xc1\x18\x70\x1b\xb7\xc3\xe7\xfd\x69\x17\x85\x11\x5c\xfd\xb2\xef\x23\x5a\x66\xbc\xc1\x38\x4a\x1d\x08\x8b\x8c\xca\x90\xd9\xd5\x60\x91\x35\x49\xde",
+ 35 },
+ { GCRY_MD_SHA3_512,
+ "\x47\xf5\x69\x7a\xc8\xc3\x14\x09\xc0\x86\x88\x27\x34\x7a\x61\x3a\x35\x62\x04\x1c\x63\x3c\xf1\xf1\xf8\x68\x65\xa5\x76\xe0\x28\x35\xed\x2c\x24\x92",
+ "\x9a\x34\x85\x40\xab\x66\x9c\xdd\x89\x14\x42\x6f\xbb\xad\x19\x2b\xa0\xdb\x16\x58\x3e\x8d\x4e\x86\x7b\x66\xcc\x78\xc6\x49\x6e\x4d\x83\xdd\xbf\x7b\x97\x2b\x06\x68\xdf\x79\x03\xb0\xfe\x9a\xb8\x2b\x65\x15\x3f\x94\x7c\xf2\xaf\x25\x91\x12\x1c\x9d\x1a\x78\xe5\x15",
+ 36 },
+ { GCRY_MD_SHA3_512,
+ "\x51\x2a\x6d\x29\x2e\x67\xec\xb2\xfe\x48\x6b\xfe\x92\x66\x09\x53\xa7\x54\x84\xff\x4c\x4f\x2e\xca\x2b\x0a\xf0\xed\xcd\xd4\x33\x9c\x6b\x2e\xe4\xe5\x42",
+ "\xff\xdb\x64\x9d\x1a\xa7\xff\x26\x9b\x9b\xb0\xae\x61\x92\xf7\xbc\xbc\x06\x61\x25\x28\xdf\x0e\x68\x52\x1d\x5c\x89\x1e\x9b\xba\x12\x92\x71\xa0\x7d\xc5\x63\x93\xbb\x21\x21\x8f\x5e\x2f\xb9\x2c\xff\xf8\x33\x43\x20\x66\xaa\x63\x80\xf3\x55\x7a\x07\x48\xe6\x5b\x33",
+ 37 },
+ { GCRY_MD_SHA3_512,
+ "\x97\x3c\xf2\xb4\xdc\xf0\xbf\xa8\x72\xb4\x11\x94\xcb\x05\xbb\x4e\x16\x76\x0a\x18\x40\xd8\x34\x33\x01\x80\x25\x76\x19\x7e\xc1\x9e\x2a\x14\x93\xd8\xf4\xfb",
+ "\x96\x65\x80\x8d\x39\xb4\xbe\xcf\xdd\x9a\xa8\x02\x0a\x0a\x72\xcf\xd4\xf8\x23\xa1\x5d\x67\x0d\x51\x27\x8a\x4a\xe9\x55\x07\xe1\x60\x20\xae\xde\xd6\xe6\xc0\xe2\xda\xb0\xba\xd8\x90\xa9\xe7\x55\x24\x03\xd2\xaa\x8d\x1e\xbc\x0b\x8e\xae\xc9\xa3\xa8\xdb\xb2\xa9\xef",
+ 38 },
+ { GCRY_MD_SHA3_512,
+ "\x80\xbe\xeb\xcd\x2e\x3f\x8a\x94\x51\xd4\x49\x99\x61\xc9\x73\x1a\xe6\x67\xcd\xc2\x4e\xa0\x20\xce\x3b\x9a\xa4\xbb\xc0\xa7\xf7\x9e\x30\xa9\x34\x46\x7d\xa4\xb0",
+ "\x7a\xba\x6b\x9f\x8f\x18\xd9\xd7\x2b\x88\x3e\xb9\x88\xa5\xf4\xff\xcc\x02\x17\xa3\xda\x31\x6a\xff\x11\xb3\x89\x76\xe9\x0b\x07\x36\xcb\x00\x0f\x52\x2d\xbf\x2d\xdc\xbb\x61\xba\x4b\xf4\x4c\x35\x6e\xc5\xb4\x6f\xc8\x6a\x51\x33\xf9\x71\xa9\x4f\xe2\xa9\x98\x32\x60",
+ 39 },
+ { GCRY_MD_SHA3_512,
+ "\x7a\xba\xa1\x2e\xc2\xa7\x34\x76\x74\xe4\x44\x14\x0a\xe0\xfb\x65\x9d\x08\xe1\xc6\x6d\xec\xd8\xd6\xea\xe9\x25\xfa\x45\x1d\x65\xf3\xc0\x30\x8e\x29\x44\x6b\x8e\xd3",
+ "\x58\x9c\x46\x62\x5a\x6a\xc9\xa2\xc9\xc9\xa8\x84\xf4\x27\xc3\xc0\x32\x88\x7a\xe5\x3a\x69\x93\x2b\x72\xe1\xe3\x79\x6b\xb9\x56\x89\x29\xd1\x63\x39\x5a\x3a\xa8\xb2\xab\x23\xc5\x64\x93\x7c\xd7\x29\x20\x6d\x9b\x62\xcc\x60\x35\x3b\x68\xa6\x9a\x73\x96\x16\xeb\x35",
+ 40 },
+ { GCRY_MD_SHA3_512,
+ "\xc8\x8d\xee\x99\x27\x67\x9b\x8a\xf4\x22\xab\xcb\xac\xf2\x83\xb9\x04\xff\x31\xe1\xca\xc5\x8c\x78\x19\x80\x9f\x65\xd5\x80\x7d\x46\x72\x3b\x20\xf6\x7b\xa6\x10\xc2\xb7",
+ "\xf7\xcd\x87\x37\xa1\xab\x36\xb3\x76\x12\xe5\x7d\x1e\x5a\x3d\x4a\x26\x9d\x18\xcf\x2c\xb7\x64\x4a\x12\x54\x0e\x3b\x18\x46\x31\x79\x4e\xc1\xa1\xda\x11\x8a\x10\x9a\xef\x51\x4d\xb3\x59\x0f\xe2\x7b\xe0\x75\x2e\xc0\x82\x6a\xca\xf4\x58\xfb\x0a\x75\x4b\xdc\x51\xf1",
+ 41 },
+ { GCRY_MD_SHA3_512,
+ "\x01\xe4\x3f\xe3\x50\xfc\xec\x45\x0e\xc9\xb1\x02\x05\x3e\x6b\x5d\x56\xe0\x98\x96\xe0\xdd\xd9\x07\x4f\xe1\x38\xe6\x03\x82\x10\x27\x0c\x83\x4c\xe6\xea\xdc\x2b\xb8\x6b\xf6",
+ "\xb2\x1b\xde\xde\x48\x4c\xa1\x8f\x67\x20\x58\x66\x7c\xb2\xf2\xdc\x92\x2c\x44\x35\x1e\x95\xc2\xcd\xa7\x5a\xf7\xe4\x55\x77\xbf\x50\xe3\xf2\x03\x13\x9f\x62\x62\x27\x9a\xdf\xc3\x22\x1b\x94\xa0\x72\x64\x1f\x8b\xdb\x55\xdc\xc0\x2f\x21\xd0\x87\x9e\xb5\xe7\x46\x6a",
+ 42 },
+ { GCRY_MD_SHA3_512,
+ "\x33\x70\x23\x37\x0a\x48\xb6\x2e\xe4\x35\x46\xf1\x7c\x4e\xf2\xbf\x8d\x7e\xcd\x1d\x49\xf9\x0b\xab\x60\x4b\x83\x9c\x2e\x6e\x5b\xd2\x15\x40\xd2\x9b\xa2\x7a\xb8\xe3\x09\xa4\xb7",
+ "\xdb\x56\x26\x5b\x93\x46\x96\x8a\x39\x0e\x98\x41\xd5\xb7\x87\x8a\x15\x8b\xae\xd9\x46\x06\x8e\x80\x8e\x45\x67\x35\xa6\x7e\x49\x22\x0f\xab\x66\x23\x9d\x5d\x50\x6d\xd7\x5a\x58\xf2\xc5\x6e\x25\xc9\xc1\x05\xa3\x82\x7c\x14\x34\xc6\x72\x55\xcf\xc9\x10\x1a\x5d\x09",
+ 43 },
+ { GCRY_MD_SHA3_512,
+ "\x68\x92\x54\x0f\x96\x4c\x8c\x74\xbd\x2d\xb0\x2c\x0a\xd8\x84\x51\x0c\xb3\x8a\xfd\x44\x38\xaf\x31\xfc\x91\x27\x56\xf3\xef\xec\x6b\x32\xb5\x8e\xbc\x38\xfc\x2a\x6b\x91\x35\x96\xa8",
+ "\x4c\x82\x5f\xd9\xa7\x95\xcc\xd2\x0a\x08\x92\xda\x15\x72\xb9\xb1\xf7\x0b\xa0\x5f\xf2\xd2\xda\x3a\x47\x26\xa7\x4f\x9a\xb5\x32\x3c\xcb\xc4\x29\x04\x59\xc1\xbb\x46\xf0\xa1\xe1\xff\xc3\x57\xff\x47\x66\xf4\xf4\x87\x9d\xaa\x91\xd3\x1e\xca\x98\x6a\xa3\x0c\x7b\x00",
+ 44 },
+ { GCRY_MD_SHA3_512,
+ "\xf5\x96\x1d\xfd\x2b\x1f\xff\xfd\xa4\xff\xbf\x30\x56\x0c\x16\x5b\xfe\xda\xb8\xce\x0b\xe5\x25\x84\x5d\xeb\x8d\xc6\x10\x04\xb7\xdb\x38\x46\x72\x05\xf5\xdc\xfb\x34\xa2\xac\xfe\x96\xc0",
+ "\x84\x45\xa0\x57\x66\xa3\x0d\xdd\x00\x80\x58\x9f\x8e\x8c\xbf\x7e\xc5\x9f\xb7\xa3\xce\x73\xc0\x20\x97\x91\xb1\x9c\xf7\x12\xcf\x16\x35\xd6\x3c\x83\x56\x82\x22\x72\x30\x9c\x6b\x9f\x01\x63\x70\x88\x87\x8d\xbf\xfb\xed\xb2\x6d\x2a\x56\x61\x85\x22\x5c\x4d\xa5\x6b",
+ 45 },
+ { GCRY_MD_SHA3_512,
+ "\xca\x06\x1a\x2e\xb6\xce\xed\x88\x81\xce\x20\x57\x17\x2d\x86\x9d\x73\xa1\x95\x1e\x63\xd5\x72\x61\x38\x4b\x80\xce\xb5\x45\x1e\x77\xb0\x6c\xf0\xf5\xa0\xea\x15\xca\x90\x7e\xe1\xc2\x7e\xba",
+ "\x2d\xc2\x51\x65\xcf\x31\x7e\xd7\xde\x2b\x4f\x2f\xd0\x99\x5d\x77\x85\x97\x8c\xa8\x58\x1e\xa8\x03\x3e\x91\x2f\x2e\x44\xee\x61\x3d\xeb\xfc\x55\x35\xc4\x8d\x63\x83\x8f\x32\x5d\x14\x16\xb9\x18\x0c\x20\xbd\xe8\x26\x14\x50\x4b\x71\x61\xf9\x86\x05\x30\xec\xa7\x0c",
+ 46 },
+ { GCRY_MD_SHA3_512,
+ "\x17\x43\xa7\x72\x51\xd6\x92\x42\x75\x0c\x4f\x11\x40\x53\x2c\xd3\xc3\x3f\x9b\x5c\xcd\xf7\x51\x4e\x85\x84\xd4\xa5\xf9\xfb\xd7\x30\xbc\xf8\x4d\x0d\x47\x26\x36\x4b\x9b\xf9\x5a\xb2\x51\xd9\xbb",
+ "\xcb\x61\x10\xa0\x2d\x7c\xa6\x36\x46\x3f\x6e\x35\x02\xcc\xf0\x17\x3b\x00\x04\x82\xc7\xe0\x02\xad\x92\x77\xc1\xd1\x03\x17\xbd\xde\xbc\x3d\xa7\xf9\x1d\x01\x73\xe3\xe2\xf9\x55\x2b\xdf\xde\xa4\xdd\x1a\xfb\xf7\x50\x8b\x09\x6a\xab\x18\x04\x92\x1e\x95\x75\x4e\x78",
+ 47 },
+ { GCRY_MD_SHA3_512,
+ "\xd8\xfa\xba\x1f\x51\x94\xc4\xdb\x5f\x17\x6f\xab\xff\xf8\x56\x92\x4e\xf6\x27\xa3\x7c\xd0\x8c\xf5\x56\x08\xbb\xa8\xf1\xe3\x24\xd7\xc7\xf1\x57\x29\x8e\xab\xc4\xdc\xe7\xd8\x9c\xe5\x16\x24\x99\xf9",
+ "\x7e\xf3\xa2\x89\x4c\x6e\xcb\xc4\x20\x1b\x15\x34\x8f\x90\x67\x15\x15\xac\xcb\xa3\xc8\x16\x66\x21\xf8\x64\xa9\x18\x4b\xf0\x8c\x3f\x5a\x89\x5f\x6b\x59\x9d\x3c\xb4\x1f\x20\xa8\xa1\xdf\x25\xae\x84\xf1\xa6\xd7\xc8\xde\x74\xfb\x7c\xef\x48\xf7\xe9\x6f\xde\x8d\x43",
+ 48 },
+ { GCRY_MD_SHA3_512,
+ "\xbe\x96\x84\xbe\x70\x34\x08\x60\x37\x3c\x9c\x48\x2b\xa5\x17\xe8\x99\xfc\x81\xba\xaa\x12\xe5\xc6\xd7\x72\x79\x75\xd1\xd4\x1b\xa8\xbe\xf7\x88\xcd\xb5\xcf\x46\x06\xc9\xc1\xc7\xf6\x1a\xed\x59\xf9\x7d",
+ "\x39\xc7\xae\x0f\x80\x12\x9d\x9d\x29\x80\xa6\x24\x6e\x2b\x6f\x10\xa3\x9e\xfa\xfd\x69\x4d\xed\x12\xa6\x08\x95\x09\xd9\x5e\xce\x50\x6d\xc3\x8c\x0a\x9d\xe4\x87\xd9\xd4\x01\xdb\x1f\x15\x19\x34\x04\x91\x10\x69\x53\x3b\xca\xe4\xc4\x8c\x53\xf2\x7b\xee\x3c\xe0\xac",
+ 49 },
+ { GCRY_MD_SHA3_512,
+ "\x7e\x15\xd2\xb9\xea\x74\xca\x60\xf6\x6c\x8d\xfa\xb3\x77\xd9\x19\x8b\x7b\x16\xde\xb6\xa1\xba\x0e\xa3\xc7\xee\x20\x42\xf8\x9d\x37\x86\xe7\x79\xcf\x05\x3c\x77\x78\x5a\xa9\xe6\x92\xf8\x21\xf1\x4a\x7f\x51",
+ "\x9b\x8a\x7d\x2f\x85\x19\xad\x6d\xc3\xd2\xbc\x5b\x69\x6b\x35\x4c\x5a\x8b\x47\x96\x40\x2c\xe1\x24\x2c\x52\x63\x8e\xea\x68\x93\xa1\x26\x98\x20\xa6\x42\xbc\x9e\xfe\x56\xcd\x7e\x26\xdc\x46\xe9\x7a\x7f\xc5\x8f\xaf\x3f\x1a\x7a\x25\xf8\x6e\xcd\xc1\xf2\xf1\x7e\x64",
+ 50 },
+ { GCRY_MD_SHA3_512,
+ "\x9a\x21\x9b\xe4\x37\x13\xbd\x57\x80\x15\xe9\xfd\xa6\x6c\x0f\x2d\x83\xca\xc5\x63\xb7\x76\xab\x9f\x38\xf3\xe4\xf7\xef\x22\x9c\xb4\x43\x30\x4f\xba\x40\x1e\xfb\x2b\xdb\xd7\xec\xe9\x39\x10\x22\x98\x65\x1c\x86",
+ "\xb5\xce\xef\x23\xf5\x6b\xe8\x07\xb6\x16\xc7\xfd\xa4\x86\x7a\x1d\x12\xd0\xa1\x68\x45\x45\x9f\xc7\x04\xce\x63\x1a\xd3\x27\x9a\xb2\x22\xdc\xa7\xad\xda\xe5\x95\xd2\x89\xcb\xa8\x99\x6d\x46\x65\x5f\xa9\xb6\xbe\x58\x70\x03\x02\xe6\x55\xc5\x1c\x82\x5f\x31\xbb\x2e",
+ 51 },
+ { GCRY_MD_SHA3_512,
+ "\xc8\xf2\xb6\x93\xbd\x0d\x75\xef\x99\xca\xeb\xdc\x22\xad\xf4\x08\x8a\x95\xa3\x54\x2f\x63\x72\x03\xe2\x83\xbb\xc3\x26\x87\x80\xe7\x87\xd6\x8d\x28\xcc\x38\x97\x45\x2f\x6a\x22\xaa\x85\x73\xcc\xeb\xf2\x45\x97\x2a",
+ "\x14\x3d\x02\x4f\xa7\x5c\x8d\x46\x27\x35\x89\xb8\xf7\x84\x32\xd4\x9e\xf1\x41\x78\xe4\xaa\xa2\x7d\xc3\x66\xc9\xcb\x78\x7f\x24\xb7\x3f\x41\x97\xa7\x22\xf1\x30\x31\x18\x1a\x6f\xa6\xe4\xf6\x61\x27\x89\x3d\xa7\xb2\x3a\x57\x9b\xb9\x3f\xe7\xd7\x37\xa4\x19\x40\x93",
+ 52 },
+ { GCRY_MD_SHA3_512,
+ "\xec\x0f\x99\x71\x10\x16\xc6\xa2\xa0\x7a\xd8\x0d\x16\x42\x75\x06\xce\x6f\x44\x10\x59\xfd\x26\x94\x42\xba\xaa\x28\xc6\xca\x03\x7b\x22\xee\xac\x49\xd5\xd8\x94\xc0\xbf\x66\x21\x9f\x2c\x08\xe9\xd0\xe8\xab\x21\xde\x52",
+ "\x0f\x48\xd0\x08\xdd\x3a\xa6\x30\xe8\x26\x16\x58\xa5\x5b\x56\x5b\x67\x73\x99\x24\x26\xb0\x85\x92\xb4\xc1\xd7\x7a\x58\xb0\x67\xf0\x5e\x25\x97\x4e\x50\x16\x28\xa2\xdb\x63\x2f\x2d\xdd\xd7\x36\x73\x11\x9a\xda\x56\x74\xd0\xce\x92\xc7\xaa\x90\x8b\x9e\x9c\x43\x5e",
+ 53 },
+ { GCRY_MD_SHA3_512,
+ "\x0d\xc4\x51\x81\x33\x7c\xa3\x2a\x82\x22\xfe\x7a\x3b\xf4\x2f\xc9\xf8\x97\x44\x25\x9c\xff\x65\x35\x04\xd6\x05\x1f\xe8\x4b\x1a\x7f\xfd\x20\xcb\x47\xd4\x69\x6c\xe2\x12\xa6\x86\xbb\x9b\xe9\xa8\xab\x1c\x69\x7b\x6d\x6a\x33",
+ "\x29\x74\x98\x63\x9f\xc7\xaa\x41\x52\x65\x4e\x46\x8e\x08\xf2\x9a\xff\xd7\x06\x1d\x44\xe3\xf5\x32\xbe\x4b\xac\x16\x9c\x87\x7a\x2e\xa7\xb4\xd7\x0d\x6b\xc0\xf6\x78\xbe\x08\xaa\x06\x42\x58\xef\x57\x11\x13\x10\xd1\x3b\x88\x97\x12\xd0\x65\x30\xb6\x90\x84\x1d\xbe",
+ 54 },
+ { GCRY_MD_SHA3_512,
+ "\xde\x28\x6b\xa4\x20\x6e\x8b\x00\x57\x14\xf8\x0f\xb1\xcd\xfa\xeb\xde\x91\xd2\x9f\x84\x60\x3e\x4a\x3e\xbc\x04\x68\x6f\x99\xa4\x6c\x9e\x88\x0b\x96\xc5\x74\x82\x55\x82\xe8\x81\x2a\x26\xe5\xa8\x57\xff\xc6\x57\x9f\x63\x74\x2f",
+ "\x1b\x6d\xa1\x61\x51\xfc\xd1\x83\x83\x37\x26\x83\x48\x01\x19\xa3\x04\x79\x6b\x2a\x5e\x54\xf7\xed\xc6\xc7\xbc\x86\x81\x73\x59\xe7\x3f\x6f\xc5\x58\x7c\x77\xbf\xc7\x1b\x56\xec\x67\x90\x5f\xa7\xf1\x51\x93\xf9\xf1\x3c\xfa\x19\x0b\xc7\xb0\x55\x03\xa5\x78\x2c\x8a",
+ 55 },
+ { GCRY_MD_SHA3_512,
+ "\xee\xbc\xc1\x80\x57\x25\x2c\xbf\x3f\x9c\x07\x0f\x1a\x73\x21\x33\x56\xd5\xd4\xbc\x19\xac\x2a\x41\x1e\xc8\xcd\xee\xe7\xa5\x71\xe2\xe2\x0e\xaf\x61\xfd\x0c\x33\xa0\xff\xeb\x29\x7d\xdb\x77\xa9\x7f\x0a\x41\x53\x47\xdb\x66\xbc\xaf",
+ "\xb2\xf4\x09\x35\xe7\xc9\x01\x88\x14\xc4\xe2\x72\x1d\x9b\x5a\xee\xed\x33\x70\x69\x03\x78\xe4\x72\xbd\x29\xf2\x27\x44\x2c\xa4\x94\x2b\x06\x18\x9c\x34\x6f\xda\x49\x81\x23\xec\xe5\x90\x18\xe4\x2c\x8b\x7e\xe3\x81\x91\xf9\x77\x89\xb4\xaa\x93\x22\x3a\x8d\x80\xef",
+ 56 },
+ { GCRY_MD_SHA3_512,
+ "\x41\x6b\x5c\xdc\x9f\xe9\x51\xbd\x36\x1b\xd7\xab\xfc\x12\x0a\x50\x54\x75\x8e\xba\x88\xfd\xd6\x8f\xd8\x4e\x39\xd3\xb0\x9a\xc2\x54\x97\xd3\x6b\x43\xcb\xe7\xb8\x5a\x6a\x3c\xeb\xda\x8d\xb4\xe5\x54\x9c\x3e\xe5\x1b\xb6\xfc\xb6\xac\x1e",
+ "\xc8\xd2\x42\xfb\x5f\xf1\xc6\xcd\x11\xa0\x40\xae\xaf\x35\xcc\x09\xe3\x55\xa9\x75\xe0\x4d\xed\x1d\x83\x41\x87\x8b\xed\x5d\xff\x8b\xbb\xd1\xb6\x9f\x4d\x12\x2c\xe5\x33\x09\xac\x08\x75\x3b\x95\xd2\xa5\x77\x21\xdf\xd1\x2e\x70\xa8\xef\x12\xe1\x1e\x16\xde\x0f\xd9",
+ 57 },
+ { GCRY_MD_SHA3_512,
+ "\x5c\x5f\xaf\x66\xf3\x2e\x0f\x83\x11\xc3\x2e\x8d\xa8\x28\x4a\x4e\xd6\x08\x91\xa5\xa7\xe5\x0f\xb2\x95\x6b\x3c\xba\xa7\x9f\xc6\x6c\xa3\x76\x46\x0e\x10\x04\x15\x40\x1f\xc2\xb8\x51\x8c\x64\x50\x2f\x18\x7e\xa1\x4b\xfc\x95\x03\x75\x97\x05",
+ "\xd1\xd5\xd5\xdd\x7d\x19\x6b\x87\xbe\x4a\x38\xf2\xd9\xb4\xa6\x9d\xf9\xdf\xe0\xa6\xe8\xce\x71\xb0\x8c\xf2\x2c\x7f\x67\x0e\xcf\x27\x3e\xaf\x39\x5d\x12\xfc\x63\xe1\x74\x1d\xef\x11\x3c\xc7\x10\x49\x70\x19\x4a\x7c\x7c\x80\x7e\x53\x19\xd7\xbb\x70\x2f\x20\xb5\x68",
+ 58 },
+ { GCRY_MD_SHA3_512,
+ "\x71\x67\xe1\xe0\x2b\xe1\xa7\xca\x69\xd7\x88\x66\x6f\x82\x3a\xe4\xee\xf3\x92\x71\xf3\xc2\x6a\x5c\xf7\xce\xe0\x5b\xca\x83\x16\x10\x66\xdc\x2e\x21\x7b\x33\x0d\xf8\x21\x10\x37\x99\xdf\x6d\x74\x81\x0e\xed\x36\x3a\xdc\x4a\xb9\x9f\x36\x04\x6a",
+ "\xd8\x12\x47\x0b\x2d\x13\x5b\x6e\x1b\xc0\xc8\x5d\xc0\x65\x2b\xf9\xf6\xc2\xf9\xee\x70\x7a\x2e\x66\x71\x81\xcc\x9f\x68\x9b\xc7\xdf\x9c\xc9\x99\xb0\x87\x16\x86\x8a\xfa\xc7\x82\x44\xb1\x51\xb7\x25\xa0\x27\xd9\x25\x0a\xb7\xa0\x73\xa4\x69\xe7\xf0\x9b\xdb\x0b\x55",
+ 59 },
+ { GCRY_MD_SHA3_512,
+ "\x2f\xda\x31\x1d\xbb\xa2\x73\x21\xc5\x32\x95\x10\xfa\xe6\x94\x8f\x03\x21\x0b\x76\xd4\x3e\x74\x48\xd1\x68\x9a\x06\x38\x77\xb6\xd1\x4c\x4f\x6d\x0e\xaa\x96\xc1\x50\x05\x13\x71\xf7\xdd\x8a\x41\x19\xf7\xda\x5c\x48\x3c\xc3\xe6\x72\x3c\x01\xfb\x7d",
+ "\x20\x3e\xf6\xbb\x51\x32\xa9\xd4\x4e\xae\x93\xc7\x20\x2b\x14\x69\xc2\xc2\xb9\x37\x06\xd0\xa3\x1b\x29\x22\x3c\x41\x1a\x39\x55\x0f\x60\xf3\x9b\x95\x56\xfd\x04\x0b\xfb\x5f\x9f\x70\x99\x31\x3b\x88\x74\xc8\xed\x67\x7c\xfc\x5f\x93\xd9\xa2\x94\x1a\x9b\x01\x39\xde",
+ 60 },
+ { GCRY_MD_SHA3_512,
+ "\x95\xd1\x47\x4a\x5a\xab\x5d\x24\x22\xac\xa6\xe4\x81\x18\x78\x33\xa6\x21\x2b\xd2\xd0\xf9\x14\x51\xa6\x7d\xd7\x86\xdf\xc9\x1d\xfe\xd5\x1b\x35\xf4\x7e\x1d\xeb\x8a\x8a\xb4\xb9\xcb\x67\xb7\x01\x79\xcc\x26\xf5\x53\xae\x7b\x56\x99\x69\xce\x15\x1b\x8d",
+ "\x23\xbe\xad\x09\x70\x7a\x77\xb2\x95\xfd\x22\xfe\x00\x12\x82\x33\x8c\x2d\x36\x83\x02\xa0\x5f\xb1\x14\xba\x2a\x01\x2c\x4d\xef\xcf\x06\xf3\x88\x7d\x6d\xb7\xa0\xa1\xde\x04\xbc\x39\x9b\xde\x92\xd6\xbe\x71\x90\x4a\x9a\xa7\xb9\x2b\xed\xfa\x02\x03\xf1\xd8\xb0\x6f",
+ 61 },
+ { GCRY_MD_SHA3_512,
+ "\xc7\x1b\xd7\x94\x1f\x41\xdf\x04\x4a\x29\x27\xa8\xff\x55\xb4\xb4\x67\xc3\x3d\x08\x9f\x09\x88\xaa\x25\x3d\x29\x4a\xdd\xbd\xb3\x25\x30\xc0\xd4\x20\x8b\x10\xd9\x95\x98\x23\xf0\xc0\xf0\x73\x46\x84\x00\x6d\xf7\x9f\x70\x99\x87\x0f\x6b\xf5\x32\x11\xa8\x8d",
+ "\x93\xa8\xdb\x85\x77\x4b\x32\x10\x90\x80\x1d\xf4\xdc\x3c\xc7\x5e\x94\xaf\x63\xff\x6d\xcf\x50\xbd\x21\x0e\x5b\x65\xfb\x35\xe1\xbe\xae\xde\xd5\x56\x02\xeb\x32\x38\x07\x26\x02\x98\x34\x98\x2d\x77\xb4\x34\xe9\x41\x79\xd0\xa3\xee\x10\x59\x34\x59\x10\xee\x1d\xcc",
+ 62 },
+ { GCRY_MD_SHA3_512,
+ "\xf5\x7c\x64\x00\x6d\x9e\xa7\x61\x89\x2e\x14\x5c\x99\xdf\x1b\x24\x64\x08\x83\xda\x79\xd9\xed\x52\x62\x85\x9d\xcd\xa8\xc3\xc3\x2e\x05\xb0\x3d\x98\x4f\x1a\xb4\xa2\x30\x24\x2a\xb6\xb7\x8d\x36\x8d\xc5\xaa\xa1\xe6\xd3\x49\x8d\x53\x37\x1e\x84\xb0\xc1\xd4\xba",
+ "\x3b\x7d\x98\xff\x31\x52\xb2\x02\x4a\xad\x4f\xa0\xb4\x0d\xc6\x42\xe8\x42\xd4\x53\x30\x5e\xce\xf2\x78\x57\x4e\x38\x61\x72\xf3\xc1\x64\xe4\xef\xb9\xc2\x95\x1a\x23\xfc\x73\xd8\x3c\x16\xb4\x90\x0f\xb9\x2a\xeb\x8e\xfe\x06\xb5\x8f\x91\x8b\xc4\xa4\x81\xe4\xc2\x38",
+ 63 },
+ { GCRY_MD_SHA3_512,
+ "\xe9\x26\xae\x8b\x0a\xf6\xe5\x31\x76\xdb\xff\xcc\x2a\x6b\x88\xc6\xbd\x76\x5f\x93\x9d\x3d\x17\x8a\x9b\xde\x9e\xf3\xaa\x13\x1c\x61\xe3\x1c\x1e\x42\xcd\xfa\xf4\xb4\xdc\xde\x57\x9a\x37\xe1\x50\xef\xbe\xf5\x55\x5b\x4c\x1c\xb4\x04\x39\xd8\x35\xa7\x24\xe2\xfa\xe7",
+ "\xeb\x50\x67\xbf\x76\x2a\x29\x1c\xf2\x58\xad\x69\xa8\x16\xa0\xb0\x89\xe0\xbd\x44\xf8\xe5\xb7\x4c\xf6\x0b\xce\x64\x73\x4e\x59\x85\x3c\xcb\x8d\x09\x1c\xd2\xe3\x3f\x90\xaa\x06\x3f\xb7\x94\x2c\xf5\x96\x5d\x45\x92\x00\x14\x4c\x1a\x08\x01\xab\xd6\x9a\x9a\x09\x4a",
+ 64 },
+ { GCRY_MD_SHA3_512,
+ "\x16\xe8\xb3\xd8\xf9\x88\xe9\xbb\x04\xde\x9c\x96\xf2\x62\x78\x11\xc9\x73\xce\x4a\x52\x96\xb4\x77\x2c\xa3\xee\xfe\xb8\x0a\x65\x2b\xdf\x21\xf5\x0d\xf7\x9f\x32\xdb\x23\xf9\xf7\x3d\x39\x3b\x2d\x57\xd9\xa0\x29\x7f\x7a\x2f\x2e\x79\xcf\xda\x39\xfa\x39\x3d\xf1\xac\x00",
+ "\xb0\xe2\x3d\x60\x0b\xa4\x21\x5f\x79\xd5\x00\x47\xbb\xfe\xd5\x0d\xf7\xd6\xe7\x69\x51\x4d\x79\x6a\xfd\x16\x6d\xee\xca\x88\xbd\x1c\xbe\x0a\xfc\x72\xa4\x1e\x03\x17\xa2\x23\x22\x5b\x4f\x58\x82\xf7\x23\xaf\xcb\xa3\xaf\x7c\x45\x7e\xb5\x25\x94\x6d\xa6\xc5\x3b\xb0",
+ 65 },
+ { GCRY_MD_SHA3_512,
+ "\xfc\x42\x4e\xeb\x27\xc1\x8a\x11\xc0\x1f\x39\xc5\x55\xd8\xb7\x8a\x80\x5b\x88\xdb\xa1\xdc\x2a\x42\xed\x5e\x2c\x0e\xc7\x37\xff\x68\xb2\x45\x6d\x80\xeb\x85\xe1\x17\x14\xfa\x3f\x8e\xab\xfb\x90\x6d\x3c\x17\x96\x4c\xb4\xf5\xe7\x6b\x29\xc1\x76\x5d\xb0\x3d\x91\xbe\x37\xfc",
+ "\x83\x02\x10\x62\x11\x7d\xa9\x93\x27\xe5\x21\xd7\xc9\x13\x31\x20\x8b\xf3\xf0\xa9\x72\xa6\xc7\x55\xec\xa4\x67\x60\xc0\x98\x48\x71\xfe\x03\x72\x4a\x51\xfb\x54\x41\xc3\xcd\xd3\xd2\x4f\xa1\xb8\x12\x75\x10\xd6\xa4\x2c\xfe\x18\xb0\x8e\x80\x96\xed\x70\x2e\xf3\x3c",
+ 66 },
+ { GCRY_MD_SHA3_512,
+ "\xab\xe3\x47\x2b\x54\xe7\x27\x34\xbd\xba\x7d\x91\x58\x73\x64\x64\x25\x1c\x4f\x21\xb3\x3f\xbb\xc9\x2d\x7f\xac\x9a\x35\xc4\xe3\x32\x2f\xf0\x1d\x23\x80\xcb\xaa\x4e\xf8\xfb\x07\xd2\x1a\x21\x28\xb7\xb9\xf5\xb6\xd9\xf3\x4e\x13\xf3\x9c\x7f\xfc\x2e\x72\xe4\x78\x88\x59\x9b\xa5",
+ "\xbc\xa9\xf0\x6b\x6b\x9a\xb8\xf7\x6c\x4f\x3d\xbe\x67\x7d\x5b\x4b\x31\x03\x42\x36\x44\x48\x4c\x77\xcd\xd8\xc5\xdd\x6c\x1a\x0b\xf7\x17\xc7\x6e\x83\xda\x9b\x2b\x4e\xdf\xe4\xcc\x13\x3c\x1f\xc8\x63\x96\xe8\xc3\xa9\xe4\x2f\xdd\x20\x51\x9f\xca\xa1\x99\x69\x18\x9f",
+ 67 },
+ { GCRY_MD_SHA3_512,
+ "\x36\xf9\xf0\xa6\x5f\x2c\xa4\x98\xd7\x39\xb9\x44\xd6\xef\xf3\xda\x5e\xbb\xa5\x7e\x7d\x9c\x41\x59\x8a\x2b\x0e\x43\x80\xf3\xcf\x4b\x47\x9e\xc2\x34\x8d\x01\x5f\xfe\x62\x56\x27\x35\x11\x15\x4a\xfc\xf3\xb4\xb4\xbf\x09\xd6\xc4\x74\x4f\xdd\x0f\x62\xd7\x50\x79\xd4\x40\x70\x6b\x05",
+ "\xdc\xdf\x76\x17\xf7\x9d\xa8\x47\x5b\x3a\x4d\xb1\x30\x6c\x9c\xaf\x87\xf1\xae\x85\xec\x97\x72\x18\x92\xd8\xe2\x0d\x0e\x54\xec\x82\xee\x7a\x0f\x2d\x17\xf2\x1a\x61\xae\xcd\x89\xa6\xc4\xcf\x50\x19\xd7\xb8\x07\x74\x47\xef\xe0\x3d\xef\x52\x08\x01\x0a\x8a\x1e\x84",
+ 68 },
+ { GCRY_MD_SHA3_512,
+ "\xab\xc8\x77\x63\xca\xe1\xca\x98\xbd\x8c\x5b\x82\xca\xba\x54\xac\x83\x28\x6f\x87\xe9\x61\x01\x28\xae\x4d\xe6\x8a\xc9\x5d\xf5\xe3\x29\xc3\x60\x71\x7b\xd3\x49\xf2\x6b\x87\x25\x28\x49\x2c\xa7\xc9\x4c\x2c\x1e\x1e\xf5\x6b\x74\xdb\xb6\x5c\x2a\xc3\x51\x98\x1f\xdb\x31\xd0\x6c\x77\xa4",
+ "\x9b\x8c\x71\x42\x18\x0f\x0e\xd8\x53\x59\xb6\xd1\x86\xae\x05\xb7\x7b\x2d\xb7\xc3\xe1\xf0\x66\x39\x2e\x73\x3b\x7e\xef\xfd\x7c\x11\xf7\xa6\xc0\xc5\x70\x27\x3a\x1f\x3f\xea\x1a\x09\x29\xd0\x17\xc7\xa4\xfa\x00\x17\x5b\x5a\xba\x76\x86\x1b\xca\x7e\xe8\x06\x45\x8b",
+ 69 },
+ { GCRY_MD_SHA3_512,
+ "\x94\xf7\xca\x8e\x1a\x54\x23\x4c\x6d\x53\xcc\x73\x4b\xb3\xd3\x15\x0c\x8b\xa8\xc5\xf8\x80\xea\xb8\xd2\x5f\xed\x13\x79\x3a\x97\x01\xeb\xe3\x20\x50\x92\x86\xfd\x8e\x42\x2e\x93\x1d\x99\xc9\x8d\xa4\xdf\x7e\x70\xae\x44\x7b\xab\x8c\xff\xd9\x23\x82\xd8\xa7\x77\x60\xa2\x59\xfc\x4f\xbd\x72",
+ "\x3a\xb7\x3a\x0a\x75\xb9\x97\xc0\xee\x83\x29\xc3\x3e\x6e\xf1\x38\x9e\x98\x21\x71\x18\x67\xf7\x75\xaf\x29\x51\x7e\xdf\xfb\xe4\x10\xd0\x37\x14\x3c\x64\x31\xfd\xed\x3d\x8c\xe7\x28\x08\x6c\x35\x12\xe9\x4f\x03\x8b\x92\x43\xb5\x0c\xb8\x20\xdc\x24\x45\x53\x5d\x91",
+ 70 },
+ { GCRY_MD_SHA3_512,
+ "\x13\xbd\x28\x11\xf6\xed\x2b\x6f\x04\xff\x38\x95\xac\xee\xd7\xbe\xf8\xdc\xd4\x5e\xb1\x21\x79\x1b\xc1\x94\xa0\xf8\x06\x20\x6b\xff\xc3\xb9\x28\x1c\x2b\x30\x8b\x1a\x72\x9c\xe0\x08\x11\x9d\xd3\x06\x6e\x93\x78\xac\xdc\xc5\x0a\x98\xa8\x2e\x20\x73\x88\x00\xb6\xcd\xdb\xe5\xfe\x96\x94\xad\x6d",
+ "\xde\xf4\xab\x6c\xda\x88\x39\x72\x9a\x03\xe0\x00\x84\x66\x04\xb1\x7f\x03\xc5\xd5\xd7\xec\x23\xc4\x83\x67\x0a\x13\xe1\x15\x73\xc1\xe9\x34\x7a\x63\xec\x69\xa5\xab\xb2\x13\x05\xf9\x38\x2e\xcd\xaa\xab\xc6\x85\x0f\x92\x84\x0e\x86\xf8\x8f\x4d\xab\xfc\xd9\x3c\xc0",
+ 71 },
+ { GCRY_MD_SHA3_512,
+ "\x1e\xed\x9c\xba\x17\x9a\x00\x9e\xc2\xec\x55\x08\x77\x3d\xd3\x05\x47\x7c\xa1\x17\xe6\xd5\x69\xe6\x6b\x5f\x64\xc6\xbc\x64\x80\x1c\xe2\x5a\x84\x24\xce\x4a\x26\xd5\x75\xb8\xa6\xfb\x10\xea\xd3\xfd\x19\x92\xed\xdd\xee\xc2\xeb\xe7\x15\x0d\xc9\x8f\x63\xad\xc3\x23\x7e\xf5\x7b\x91\x39\x7a\xa8\xa7",
+ "\xa3\xe1\x68\xb0\xd6\xc1\x43\xee\x9e\x17\xea\xe9\x29\x30\xb9\x7e\x66\x00\x35\x6b\x73\xae\xbb\x5d\x68\x00\x5d\xd1\xd0\x74\x94\x45\x1a\x37\x05\x2f\x7b\x39\xff\x03\x0c\x1a\xe1\xd7\xef\xc4\xe0\xc3\x66\x7e\xb7\xa7\x6c\x62\x7e\xc1\x43\x54\xc4\xf6\xa7\x96\xe2\xc6",
+ 72 },
+ { GCRY_MD_SHA3_512,
+ "\xba\x5b\x67\xb5\xec\x3a\x3f\xfa\xe2\xc1\x9d\xd8\x17\x6a\x2e\xf7\x5c\x0c\xd9\x03\x72\x5d\x45\xc9\xcb\x70\x09\xa9\x00\xc0\xb0\xca\x7a\x29\x67\xa9\x5a\xe6\x82\x69\xa6\xdb\xf8\x46\x6c\x7b\x68\x44\xa1\xd6\x08\xac\x66\x1f\x7e\xff\x00\x53\x8e\x32\x3d\xb5\xf2\xc6\x44\xb7\x8b\x2d\x48\xde\x1a\x08\xaa",
+ "\x63\x57\x41\xb3\x7f\x66\xcd\x5c\xe4\xdb\xd1\xf7\x8a\xcc\xd9\x07\xf9\x61\x46\xe7\x70\xb2\x39\x04\x6a\xfb\x91\x81\x91\x0b\x61\x2d\x0e\x65\x84\x1f\xf8\x66\x80\x6e\xed\x83\xc3\xae\x70\x12\xfc\x55\xe4\x2c\x3f\xfc\x9c\x6e\x3d\x03\xce\x28\x70\x44\x2f\x29\x3a\xb4",
+ 73 },
+ { GCRY_MD_SHA3_512,
+ "\x0e\xfa\x26\xac\x56\x73\x16\x7d\xca\xca\xb8\x60\x93\x2e\xd6\x12\xf6\x5f\xf4\x9b\x80\xfa\x9a\xe6\x54\x65\xe5\x54\x2c\xb6\x20\x75\xdf\x1c\x5a\xe5\x4f\xba\x4d\xb8\x07\xbe\x25\xb0\x70\x03\x3e\xfa\x22\x3b\xdd\x5b\x1d\x3c\x94\xc6\xe1\x90\x9c\x02\xb6\x20\xd4\xb1\xb3\xa6\xc9\xfe\xd2\x4d\x70\x74\x96\x04",
+ "\xd6\x29\x9a\x21\xcb\x1b\x31\xf0\xa6\xeb\x67\xd8\x2d\x4e\x73\x82\x49\x01\x3b\x75\xc9\xbc\xb4\xa4\xfe\x41\x90\x36\xa6\x04\x3a\x71\x03\xe9\xca\x9b\x7d\x25\x75\x91\x77\xc4\xb6\x40\x01\x37\x70\x93\xcf\x39\xf3\x5c\x9b\x16\x25\xc6\x81\x93\x69\xfa\x37\x5f\xa4\x9d",
+ 74 },
+ { GCRY_MD_SHA3_512,
+ "\xbb\xfd\x93\x3d\x1f\xd7\xbf\x59\x4a\xc7\xf4\x35\x27\x7d\xc1\x7d\x8d\x5a\x5b\x8e\x4d\x13\xd9\x6d\x2f\x64\xe7\x71\xab\xbd\x51\xa5\xa8\xae\xa7\x41\xbe\xcc\xbd\xdb\x17\x7b\xce\xa0\x52\x43\xeb\xd0\x03\xcf\xde\xae\x87\x7c\xca\x4d\xa9\x46\x05\xb6\x76\x91\x91\x9d\x8b\x03\x3f\x77\xd3\x84\xca\x01\x59\x3c\x1b",
+ "\x07\xf0\xa1\x84\x73\x4b\xa4\xbb\x72\x1f\x36\xd7\xb1\xb3\x83\xf6\xbf\x99\xcd\x5f\x75\x94\x1e\xcf\x1f\xf2\xb3\x25\xf0\x3a\xf9\x70\xd1\xdb\x1f\x03\x59\x75\x70\x20\x93\xf5\x9a\x76\x10\xbf\x05\x4d\x12\x01\x7e\xcd\x61\x09\x17\x7c\xf0\x61\xab\x14\x96\xf8\x78\x60",
+ 75 },
+ { GCRY_MD_SHA3_512,
+ "\x90\x07\x89\x99\xfd\x3c\x35\xb8\xaf\xbf\x40\x66\xcb\xde\x33\x58\x91\x36\x5f\x0f\xc7\x5c\x12\x86\xcd\xd8\x8f\xa5\x1f\xab\x94\xf9\xb8\xde\xf7\xc9\xac\x58\x2a\x5d\xbc\xd9\x58\x17\xaf\xb7\xd1\xb4\x8f\x63\x70\x4e\x19\xc2\xba\xa4\xdf\x34\x7f\x48\xd4\xa6\xd6\x03\x01\x3c\x23\xf1\xe9\x61\x1d\x59\x5e\xba\xc3\x7c",
+ "\x89\x07\x0b\x8b\x1e\x32\x2c\xcf\x9d\x63\x07\xed\xc1\x1f\xc3\x4e\x13\x87\x4c\x49\x77\xda\x9f\x60\x35\xd0\x6f\xaf\x64\x7d\x7f\x7d\x54\xb8\x25\x0b\x54\x17\x44\x29\x8a\xac\xd4\xc5\x4d\x9b\x41\xb4\x08\x5d\xd3\x5c\x49\x1a\x46\x1d\x50\x4b\xdb\x42\xfc\x12\xf0\x3c",
+ 76 },
+ { GCRY_MD_SHA3_512,
+ "\x64\x10\x5e\xca\x86\x35\x15\xc2\x0e\x7c\xfb\xaa\x0a\x0b\x88\x09\x04\x61\x64\xf3\x74\xd6\x91\xcd\xbd\x65\x08\xaa\xab\xc1\x81\x9f\x9a\xc8\x4b\x52\xba\xfc\x1b\x0f\xe7\xcd\xdb\xc5\x54\xb6\x08\xc0\x1c\x89\x04\xc6\x69\xd8\xdb\x31\x6a\x09\x53\xa4\xc6\x8e\xce\x32\x4e\xc5\xa4\x9f\xfd\xb5\x9a\x1b\xd6\xa2\x92\xaa\x0e",
+ "\x6c\x3f\xbe\x32\x55\x64\x45\xda\xd4\x30\xcf\x15\xfe\x12\x43\xb6\xab\x44\x34\x9e\xec\x2b\xe1\x13\x2b\x06\x80\xe5\xed\xf0\xb0\x8b\x55\xf1\xab\xe4\x73\x43\x9c\x5e\x07\x50\x13\x29\x96\x19\x5f\xd1\x20\xc2\x67\xb9\x10\x0c\x47\x77\x7b\x33\x91\x32\xec\x34\xcc\x80",
+ 77 },
+ { GCRY_MD_SHA3_512,
+ "\xd4\x65\x4b\xe2\x88\xb9\xf3\xb7\x11\xc2\xd0\x20\x15\x97\x8a\x8c\xc5\x74\x71\xd5\x68\x0a\x09\x2a\xa5\x34\xf7\x37\x2c\x71\xce\xaa\xb7\x25\xa3\x83\xc4\xfc\xf4\xd8\xde\xaa\x57\xfc\xa3\xce\x05\x6f\x31\x29\x61\xec\xcf\x9b\x86\xf1\x49\x81\xba\x5b\xed\x6a\xb5\xb4\x49\x8e\x1f\x6c\x82\xc6\xca\xe6\xfc\x14\x84\x5b\x3c\x8a",
+ "\x6a\xe3\xe6\x56\xcf\x94\xdb\x10\xae\x3c\x18\x53\x62\xa6\x62\x5c\xec\x53\xe0\xba\x4d\xc7\xd1\x60\x8a\x3f\x2f\xca\x3c\x4f\x31\xf8\x9f\xe1\xb0\x6f\xe9\xca\x34\x5e\x3f\x5e\x96\x7a\x3e\xbc\xf6\xa1\xa1\x6e\x24\x52\x1d\x5c\x46\x90\xd9\xb6\x42\x48\x3a\xc7\xa8\x96",
+ 78 },
+ { GCRY_MD_SHA3_512,
+ "\x12\xd9\x39\x48\x88\x30\x5a\xc9\x6e\x65\xf2\xbf\x0e\x1b\x18\xc2\x9c\x90\xfe\x9d\x71\x4d\xd5\x9f\x65\x1f\x52\xb8\x8b\x30\x08\xc5\x88\x43\x55\x48\x06\x6e\xa2\xfc\x4c\x10\x11\x18\xc9\x1f\x32\x55\x62\x24\xa5\x40\xde\x6e\xfd\xdb\xca\x29\x6e\xf1\xfb\x00\x34\x1f\x5b\x01\xfe\xcf\xc1\x46\xbd\xb2\x51\xb3\xbd\xad\x55\x6c\xd2",
+ "\xad\xa8\xe7\x8c\xe3\xe6\xd4\x47\xba\x2b\x7d\xcf\x98\x71\x8f\xe7\xd4\x3b\x38\xd6\x81\x17\xe5\x77\x9a\x41\xed\xd8\xfa\x72\x19\x8e\x3b\x3c\x1c\x02\x15\x92\x5b\xc9\xd0\x07\xfd\x2c\x35\x5e\xdd\x66\x8a\x0c\x27\xef\x0f\xf8\x9f\x76\xcf\x85\x36\x3d\x4c\x9e\xe0\x01",
+ 79 },
+ { GCRY_MD_SHA3_512,
+ "\x87\x1a\x0d\x7a\x5f\x36\xc3\xda\x1d\xfc\xe5\x7a\xcd\x8a\xb8\x48\x7c\x27\x4f\xad\x33\x6b\xc1\x37\xeb\xd6\xff\x46\x58\xb5\x47\xc1\xdc\xfa\xb6\x5f\x03\x7a\xa5\x8f\x35\xef\x16\xaf\xf4\xab\xe7\x7b\xa6\x1f\x65\x82\x6f\x7b\xe6\x81\xb5\xb6\xd5\xa1\xea\x80\x85\xe2\xae\x9c\xd5\xcf\x09\x91\x87\x8a\x31\x1b\x54\x9a\x6d\x6a\xf2\x30",
+ "\x35\x69\xd9\xa0\x8d\xfb\x00\x01\xbe\x71\x39\x40\xc4\x64\xc1\x19\xf5\xa4\xc1\xb9\xff\x97\xd8\x29\x7d\x04\xc7\xb2\xdc\xe2\xd6\x84\xae\xe1\x64\x43\xc3\x2e\x5b\xb2\x35\x5a\xc8\xa3\x36\x24\x9d\x1b\xaa\xea\xb4\xfb\xd0\x4a\xb9\x82\xd6\xb1\x78\xdd\x0a\x5b\x5b\xc8",
+ 80 },
+ { GCRY_MD_SHA3_512,
+ "\xe9\x0b\x4f\xfe\xf4\xd4\x57\xbc\x77\x11\xff\x4a\xa7\x22\x31\xca\x25\xaf\x6b\x2e\x20\x6f\x8b\xf8\x59\xd8\x75\x8b\x89\xa7\xcd\x36\x10\x5d\xb2\x53\x8d\x06\xda\x83\xba\xd5\xf6\x63\xba\x11\xa5\xf6\xf6\x1f\x23\x6f\xd5\xf8\xd5\x3c\x5e\x89\xf1\x83\xa3\xce\xc6\x15\xb5\x0c\x7c\x68\x1e\x77\x3d\x10\x9f\xf7\x49\x1b\x5c\xc2\x22\x96\xc5",
+ "\x13\x43\xe3\xcd\x16\x2d\x79\x86\x43\x1b\xab\xe6\x63\x83\xb8\x40\x29\x66\x56\x91\xe3\x6c\xaf\x97\xcd\xac\xa1\x7e\xe9\xe9\x7d\x74\x20\x1d\x2a\x82\x8d\x72\xe9\xfb\xbd\x5e\x07\x83\x1d\x90\xf0\x9e\xaf\x3c\x86\x3b\xd1\x02\xcd\xb1\xed\xeb\xc8\xad\x58\xa5\x3e\xce",
+ 81 },
+ { GCRY_MD_SHA3_512,
+ "\xe7\x28\xde\x62\xd7\x58\x56\x50\x0c\x4c\x77\xa4\x28\x61\x2c\xd8\x04\xf3\x0c\x3f\x10\xd3\x6f\xb2\x19\xc5\xca\x0a\xa3\x07\x26\xab\x19\x0e\x5f\x3f\x27\x9e\x07\x33\xd7\x7e\x72\x67\xc1\x7b\xe2\x7d\x21\x65\x0a\x9a\x4d\x1e\x32\xf6\x49\x62\x76\x38\xdb\xad\xa9\x70\x2c\x7c\xa3\x03\x26\x9e\xd1\x40\x14\xb2\xf3\xcf\x8b\x89\x4e\xac\x85\x54",
+ "\xbb\xa0\x1d\xbe\xa9\x66\x0f\x9c\x2a\xd7\x44\x60\xb6\x7a\x82\x44\x07\x01\xeb\x99\x51\x43\xff\xcf\x74\x34\xb5\xd2\xde\x4e\x35\xc8\x2c\xc7\x57\xdf\x77\x6d\x46\x19\x9d\xd8\xe7\x35\x5a\xeb\x1f\x42\xa8\x8f\x6f\x0b\xb5\x0f\xd2\x39\xc7\x38\x98\x15\x6e\x4d\xdb\xbc",
+ 82 },
+ { GCRY_MD_SHA3_512,
+ "\x63\x48\xf2\x29\xe7\xb1\xdf\x3b\x77\x0c\x77\x54\x4e\x51\x66\xe0\x81\x85\x0f\xa1\xc6\xc8\x81\x69\xdb\x74\xc7\x6e\x42\xeb\x98\x3f\xac\xb2\x76\xad\x6a\x0d\x1f\xa7\xb5\x0d\x3e\x3b\x6f\xcd\x79\x9e\xc9\x74\x70\x92\x0a\x7a\xbe\xd4\x7d\x28\x8f\xf8\x83\xe2\x4c\xa2\x1c\x7f\x80\x16\xb9\x3b\xb9\xb9\xe0\x78\xbd\xb9\x70\x3d\x2b\x78\x1b\x61\x6e",
+ "\x32\x68\xbc\x24\xe2\x93\x92\xdd\xa1\x67\x7b\x7a\x3c\xe3\x11\x19\x94\x48\x2d\x17\xba\xd1\xc1\x50\xac\x88\x5f\x1d\x29\xc3\x08\x65\x7c\x69\xfd\x4f\x7c\xe5\x96\x7d\x04\xfc\xcb\x92\x0d\xac\xb0\x0d\x0c\xe0\x95\x36\xee\x92\xa6\x66\x4c\xb2\x0e\x69\x2d\x91\xd8\xce",
+ 83 },
+ { GCRY_MD_SHA3_512,
+ "\x4b\x12\x7f\xde\x5d\xe7\x33\xa1\x68\x0c\x27\x90\x36\x36\x27\xe6\x3a\xc8\xa3\xf1\xb4\x70\x7d\x98\x2c\xae\xa2\x58\x65\x5d\x9b\xf1\x8f\x89\xaf\xe5\x41\x27\x48\x2b\xa0\x1e\x08\x84\x55\x94\xb6\x71\x30\x6a\x02\x5c\x9a\x5c\x5b\x6f\x93\xb0\xa3\x95\x22\xdc\x87\x74\x37\xbe\x5c\x24\x36\xcb\xf3\x00\xce\x7a\xb6\x74\x79\x34\xfc\xfc\x30\xae\xaa\xf6",
+ "\xec\x13\xe3\x90\xfa\x65\xfd\xc1\x10\x54\xe3\x2c\x9f\x5b\xf5\xe6\xe9\x7f\xbc\x34\xc2\x80\x89\x34\x6f\xf2\x2d\x97\x62\xbe\xbf\x6a\x14\xfa\x7f\x9c\x2e\x66\x43\xd1\xed\x7e\xc6\x92\x5d\x0f\xa2\x09\x8f\x81\x49\x05\x8e\x99\xd0\x2a\xd5\xcb\x61\xb4\xcc\xba\x64\x67",
+ 84 },
+ { GCRY_MD_SHA3_512,
+ "\x08\x46\x1f\x00\x6c\xff\x4c\xc6\x4b\x75\x2c\x95\x72\x87\xe5\xa0\xfa\xab\xc0\x5c\x9b\xff\x89\xd2\x3f\xd9\x02\xd3\x24\xc7\x99\x03\xb4\x8f\xcb\x8f\x8f\x4b\x01\xf3\xe4\xdd\xb4\x83\x59\x3d\x25\xf0\x00\x38\x66\x98\xf5\xad\xe7\xfa\xad\xe9\x61\x5f\xdc\x50\xd3\x27\x85\xea\x51\xd4\x98\x94\xe4\x5b\xaa\x3d\xc7\x07\xe2\x24\x68\x8c\x64\x08\xb6\x8b\x11",
+ "\x6f\xd5\xa3\x34\xd4\xb7\xf9\xc7\x2a\x8d\xb1\x29\x2c\xc8\xf1\x9b\xf2\xa0\x0f\x5c\x22\x6c\x16\x36\x24\x80\x24\x72\x3c\xb8\x76\x07\x0a\x96\x57\xf4\x8a\xb3\xb1\xd4\x22\x92\x02\xb7\xbb\xc6\x40\x53\xa4\x8c\x3f\xf6\xb9\x3a\xb1\x1a\x2a\xf3\x23\x77\x21\xc9\xcc\x09",
+ 85 },
+ { GCRY_MD_SHA3_512,
+ "\x68\xc8\xf8\x84\x9b\x12\x0e\x6e\x0c\x99\x69\xa5\x86\x6a\xf5\x91\xa8\x29\xb9\x2f\x33\xcd\x9a\x4a\x31\x96\x95\x7a\x14\x8c\x49\x13\x8e\x1e\x2f\x5c\x76\x19\xa6\xd5\xed\xeb\xe9\x95\xac\xd8\x1e\xc8\xbb\x9c\x7b\x9c\xfc\xa6\x78\xd0\x81\xea\x9e\x25\xa7\x5d\x39\xdb\x04\xe1\x8d\x47\x59\x20\xce\x82\x8b\x94\xe7\x22\x41\xf2\x4d\xb7\x25\x46\xb3\x52\xa0\xe4",
+ "\x01\x6c\x80\xcb\xab\xed\x07\xc5\x0f\x2c\x1b\x67\x7c\x43\xe5\x2d\xe8\xd1\x17\x51\xe5\x4e\x59\x6e\x0c\x04\xb3\x83\x7a\x7e\x34\xa9\xff\x5d\x2e\x98\xe7\xc5\x81\x82\x87\x9c\x15\x84\x7d\x18\xdc\xe8\x8e\xa9\x00\x33\x7b\xc4\x48\x11\x2e\x98\xce\x11\x18\x82\x0c\x58",
+ 86 },
+ { GCRY_MD_SHA3_512,
+ "\xb8\xd5\x64\x72\x95\x4e\x31\xfb\x54\xe2\x8f\xca\x74\x3f\x84\xd8\xdc\x34\x89\x1c\xb5\x64\xc6\x4b\x08\xf7\xb7\x16\x36\xde\xbd\x64\xca\x1e\xdb\xdb\xa7\xfc\x5c\x3e\x40\x04\x9c\xe9\x82\xbb\xa8\xc7\xe0\x70\x30\x34\xe3\x31\x38\x46\x95\xe9\xde\x76\xb5\x10\x4f\x2f\xbc\x45\x35\xec\xbe\xeb\xc3\x3b\xc2\x7f\x29\xf1\x8f\x6f\x27\xe8\x02\x3b\x0f\xbb\x6f\x56\x3c",
+ "\xa4\xe8\x5f\xf8\x64\x82\xc1\x0c\x6a\xaa\xbc\x79\xa5\x73\xcb\xf8\x9a\x0a\x92\x71\x10\xd7\x55\xf2\x2b\x52\x9b\xd7\xcf\x3f\x6c\xc6\xcb\x98\x61\xe5\x09\x65\x72\x42\xa7\x8b\x0c\x0a\xf7\x8f\xf9\x7a\xbc\xc1\xa8\x38\x82\x70\xd6\xc8\xd3\x02\xd4\x5c\x9b\xa5\x84\x04",
+ 87 },
+ { GCRY_MD_SHA3_512,
+ "\x0d\x58\xac\x66\x5f\xa8\x43\x42\xe6\x0c\xef\xee\x31\xb1\xa4\xea\xcd\xb0\x92\xf1\x22\xdf\xc6\x83\x09\x07\x7a\xed\x1f\x3e\x52\x8f\x57\x88\x59\xee\x9e\x4c\xef\xb4\xa7\x28\xe9\x46\x32\x49\x27\xb6\x75\xcd\x4f\x4a\xc8\x4f\x64\xdb\x3d\xac\xfe\x85\x0c\x1d\xd1\x87\x44\xc7\x4c\xec\xcd\x9f\xe4\xdc\x21\x40\x85\x10\x8f\x40\x4e\xab\x6d\x8f\x45\x2b\x54\x42\xa4\x7d",
+ "\xb9\x7a\xfb\x77\xd3\x9f\x89\x04\xae\x8a\x51\x29\xa7\xdd\xc8\xec\x92\x90\xac\x40\x35\x6e\x1b\x53\xdd\x05\x7f\xa7\x58\x4b\xa3\x1a\xfa\xf9\xef\x5b\x65\x70\x97\xfc\x11\x5e\xaa\x33\xe7\xed\xe3\x6d\xd0\x08\x32\xd6\x77\xeb\xd0\x7c\x34\xb0\x71\xe7\x35\x80\xdd\x3a",
+ 88 },
+ { GCRY_MD_SHA3_512,
+ "\x17\x55\xe2\xd2\xe5\xd1\xc1\xb0\x15\x64\x56\xb5\x39\x75\x3f\xf4\x16\x65\x1d\x44\x69\x8e\x87\x00\x2d\xcf\x61\xdc\xfa\x2b\x4e\x72\xf2\x64\xd9\xad\x59\x1d\xf1\xfd\xee\x7b\x41\xb2\xeb\x00\x28\x3c\x5a\xeb\xb3\x41\x13\x23\xb6\x72\xea\xa1\x45\xc5\x12\x51\x85\x10\x4f\x20\xf3\x35\x80\x4b\x02\x32\x5b\x6d\xea\x65\x60\x3f\x34\x9f\x4d\x5d\x8b\x78\x2d\xd3\x46\x9c\xcd",
+ "\xab\x2f\xc5\x9a\x43\xa2\x66\x6c\x92\x06\xb9\x31\x74\x79\x28\x5e\x66\x0b\x67\x0c\x6f\x11\x1f\x99\x95\x56\xe8\x15\x1e\x0e\xb8\xd1\x2b\xc8\x2c\x9a\x7e\x7b\x3f\x8d\x6f\x38\x2a\x8d\x96\x77\x5e\xa4\x17\xf7\x54\xff\x55\x2e\x1b\xac\x27\x1f\xbd\x08\x24\x0f\x1b\x86",
+ 89 },
+ { GCRY_MD_SHA3_512,
+ "\xb1\x80\xde\x1a\x61\x11\x11\xee\x75\x84\xba\x2c\x4b\x02\x05\x98\xcd\x57\x4a\xc7\x7e\x40\x4e\x85\x3d\x15\xa1\x01\xc6\xf5\xa2\xe5\xc8\x01\xd7\xd8\x5d\xc9\x52\x86\xa1\x80\x4c\x87\x0b\xb9\xf0\x0f\xd4\xdc\xb0\x3a\xa8\x32\x82\x75\x15\x88\x19\xdc\xad\x72\x53\xf3\xe3\xd2\x37\xae\xaa\x79\x79\x26\x8a\x5d\xb1\xc6\xce\x08\xa9\xec\x7c\x25\x79\x78\x3c\x8a\xfc\x1f\x91\xa7",
+ "\x0a\x67\x3a\xf8\x4e\x2d\x23\x17\xb8\x0a\x87\x3b\xfe\x38\xb2\x52\x87\x27\x08\xb3\x8a\xf9\xb9\x56\xe3\x55\x4a\xc2\xdc\xe2\xf7\x7c\x81\x55\x93\xd9\x99\x30\xe7\xaa\x66\x6c\x57\xb5\x97\x30\x71\x2e\x5c\x4a\x9b\x57\x84\x9e\xdd\xd7\x12\xa3\x78\x04\x0e\xb8\x24\xd8",
+ 90 },
+ { GCRY_MD_SHA3_512,
+ "\xcf\x35\x83\xcb\xdf\xd4\xcb\xc1\x70\x63\xb1\xe7\xd9\x0b\x02\xf0\xe6\xe2\xee\x05\xf9\x9d\x77\xe2\x4e\x56\x03\x92\x53\x5e\x47\xe0\x50\x77\x15\x7f\x96\x81\x35\x44\xa1\x70\x46\x91\x4f\x9e\xfb\x64\x76\x2a\x23\xcf\x7a\x49\xfe\x52\xa0\xa4\xc0\x1c\x63\x0c\xfe\x87\x27\xb8\x1f\xb9\x9a\x89\xff\x7c\xc1\x1d\xca\x51\x73\x05\x7e\x04\x17\xb8\xfe\x7a\x9e\xfb\xa6\xd9\x5c\x55\x5f",
+ "\x1d\x34\x64\x54\x63\xeb\xbd\x93\x2c\x73\x0e\x59\x3d\x9c\x10\x8a\xa8\x68\x07\xdb\x67\x85\xf0\x5c\x4c\xe8\x0f\x3e\x83\x02\xf8\x7e\xfb\xcc\xb1\xab\x88\x4e\x25\xf1\xdc\xd5\x48\x5d\x38\x55\x02\x99\x5e\x7a\xbe\x2e\xf1\x1b\xd3\x46\x9e\x03\x6d\x7e\xb9\x3b\x4f\x39",
+ 91 },
+ { GCRY_MD_SHA3_512,
+ "\x07\x2f\xc0\x23\x40\xef\x99\x11\x5b\xad\x72\xf9\x2c\x01\xe4\xc0\x93\xb9\x59\x9f\x6c\xfc\x45\xcb\x38\x0e\xe6\x86\xcb\x5e\xb0\x19\xe8\x06\xab\x9b\xd5\x5e\x63\x4a\xb1\x0a\xa6\x2a\x95\x10\xcc\x06\x72\xcd\x3e\xdd\xb5\x89\xc7\xdf\x2b\x67\xfc\xd3\x32\x9f\x61\xb1\xa4\x44\x1e\xca\x87\xa3\x3c\x8f\x55\xda\x4f\xbb\xad\x5c\xf2\xb2\x52\x7b\x8e\x98\x3b\xb3\x1a\x2f\xad\xec\x75\x23",
+ "\x3f\x57\xfa\x91\x5a\x78\x2e\x3c\xc6\x98\x15\xba\x21\x9f\x42\xaa\x2c\x22\x2c\xd7\xf3\x09\xf1\x0a\xf8\x43\x38\x4b\x3d\x39\x39\xaa\x0b\x92\xdd\x95\x71\x68\x6c\x79\x61\xe0\x6b\xfe\xe8\x18\x12\x7f\xc5\xb5\xf3\x2c\x67\xf4\xaa\x2a\xf1\x0d\x4f\xa3\x8f\x65\xe9\x0d",
+ 92 },
+ { GCRY_MD_SHA3_512,
+ "\x76\xee\xcf\x95\x6a\x52\x64\x9f\x87\x75\x28\x14\x6d\xe3\x3d\xf2\x49\xcd\x80\x0e\x21\x83\x0f\x65\xe9\x0f\x0f\x25\xca\x9d\x65\x40\xfd\xe4\x06\x03\x23\x0e\xca\x67\x60\xf1\x13\x9c\x7f\x26\x8d\xeb\xa2\x06\x06\x31\xee\xa9\x2b\x1f\xff\x05\xf9\x3f\xd5\x57\x2f\xbe\x29\x57\x9e\xcd\x48\xbc\x3a\x8d\x6c\x2e\xb4\xa6\xb2\x6e\x38\xd6\xc5\xfb\xf2\xc0\x80\x44\xae\xea\x47\x0a\x8f\x2f\x26",
+ "\x15\x13\x82\xca\x35\xfb\x20\xb8\x95\xa9\xdc\x07\x4d\x68\x7f\x2f\x33\x5e\xaf\x57\x45\x6d\x35\x7a\x68\x5e\xf7\x52\xda\x59\x17\x4d\x3f\x23\x9a\xa9\xe0\x4f\x14\x21\x38\xd9\x41\x3b\x21\x90\x46\x65\xef\x4d\xf2\xf6\x3e\x66\x3b\x49\x03\x83\x66\x04\x81\xf7\x83\x62",
+ 93 },
+ { GCRY_MD_SHA3_512,
+ "\x7a\xdc\x0b\x66\x93\xe6\x1c\x26\x9f\x27\x8e\x69\x44\xa5\xa2\xd8\x30\x09\x81\xe4\x00\x22\xf8\x39\xac\x64\x43\x87\xbf\xac\x90\x86\x65\x00\x85\xc2\xcd\xc5\x85\xfe\xa4\x7b\x9d\x2e\x52\xd6\x5a\x2b\x29\xa7\xdc\x37\x04\x01\xef\x5d\x60\xdd\x0d\x21\xf9\xe2\xb9\x0f\xae\x91\x93\x19\xb1\x4b\x8c\x55\x65\xb0\x42\x3c\xef\xb8\x27\xd5\xf1\x20\x33\x02\xa9\xd0\x15\x23\x49\x8a\x4d\xb1\x03\x74",
+ "\x23\xaa\x4b\x74\xc5\x4e\x8f\x45\x00\x54\xb6\xab\xdb\xc6\xf6\xc3\xe4\x43\x66\xaf\xce\xc0\x99\xb1\x55\x77\x5d\xe0\x40\xbf\x3b\x9c\xdd\x0b\x87\x5f\x9d\x49\x0f\xaa\x69\x4f\x18\xcc\xbf\xfe\xc6\xca\xb7\xde\x57\xa5\x9e\xc6\x32\x72\x40\xac\x59\xd6\x2d\x50\xb2\x1c",
+ 94 },
+ { GCRY_MD_SHA3_512,
+ "\xe1\xff\xfa\x98\x26\xcc\xe8\xb8\x6b\xcc\xef\xb8\x79\x4e\x48\xc4\x6c\xdf\x37\x20\x13\xf7\x82\xec\xed\x1e\x37\x82\x69\xb7\xbe\x2b\x7b\xf5\x13\x74\x09\x22\x61\xae\x12\x0e\x82\x2b\xe6\x85\xf2\xe7\xa8\x36\x64\xbc\xfb\xe3\x8f\xe8\x63\x3f\x24\xe6\x33\xff\xe1\x98\x8e\x1b\xc5\xac\xf5\x9a\x58\x70\x79\xa5\x7a\x91\x0b\xda\x60\x06\x0e\x85\xb5\xf5\xb6\xf7\x76\xf0\x52\x96\x39\xd9\xcc\xe4\xbd",
+ "\x36\x05\xce\xc1\x6a\x7a\xa8\xb2\x52\x54\x79\xfc\xc1\x29\x54\x11\xb6\xa9\x52\xdc\xe2\x33\xc9\xac\xc8\x56\xd6\xd1\x7c\x98\x12\xc9\x20\x17\x85\x00\xcd\x00\x28\xb5\x99\x8d\x07\x04\x6c\x6a\x5c\xf3\x98\xee\x1e\xc9\x7d\xf9\x18\x2c\x33\xfc\xa8\x66\x47\x86\x18\x78",
+ 95 },
+ { GCRY_MD_SHA3_512,
+ "\x69\xf9\xab\xba\x65\x59\x2e\xe0\x1d\xb4\xdc\xe5\x2d\xba\xb9\x0b\x08\xfc\x04\x19\x36\x02\x79\x2e\xe4\xda\xa2\x63\x03\x3d\x59\x08\x15\x87\xb0\x9b\xbe\x49\xd0\xb4\x9c\x98\x25\xd2\x28\x40\xb2\xff\x5d\x9c\x51\x55\xf9\x75\xf8\xf2\xc2\xe7\xa9\x0c\x75\xd2\xe4\xa8\x04\x0f\xe3\x9f\x63\xbb\xaf\xb4\x03\xd9\xe2\x8c\xc3\xb8\x6e\x04\xe3\x94\xa9\xc9\xe8\x06\x5b\xd3\xc8\x5f\xa9\xf0\xc7\x89\x16\x00",
+ "\xc5\xa5\x26\xd7\x58\x16\xd4\x1b\x53\xbf\x16\x4b\x04\x67\xe0\xb8\x0a\x99\x84\xd1\x83\x0e\xdb\x9d\x49\xf7\xec\x3e\xcf\xef\xb0\x1a\x2c\x82\x4a\x0f\x64\x57\x53\xaa\x46\x3d\x56\x7c\xb2\x78\x2a\xfc\xb2\xb2\xc2\x10\x2e\xa6\x64\xc5\x69\x98\xf7\x90\x62\x63\x6f\xc1",
+ 96 },
+ { GCRY_MD_SHA3_512,
+ "\x38\xa1\x0a\x35\x2c\xa5\xae\xdf\xa8\xe1\x9c\x64\x78\x7d\x8e\x9c\x3a\x75\xdb\xf3\xb8\x67\x4b\xfa\xb2\x9b\x5d\xbf\xc1\x5a\x63\xd1\x0f\xae\x66\xcd\x1a\x6e\x6d\x24\x52\xd5\x57\x96\x7e\xaa\xd8\x9a\x4c\x98\x44\x97\x87\xb0\xb3\x16\x4c\xa5\xb7\x17\xa9\x3f\x24\xeb\x0b\x50\x6c\xeb\x70\xcb\xbc\xb8\xd7\x2b\x2a\x72\x99\x3f\x90\x9a\xad\x92\xf0\x44\xe0\xb5\xa2\xc9\xac\x9c\xb1\x6a\x0c\xa2\xf8\x1f\x49",
+ "\xb2\x39\x94\x1a\x31\x10\x0a\xb1\xb2\x4a\xf2\xd1\xfe\xf1\x49\xdb\xa3\x00\x10\x5a\x31\xb7\x2a\x8f\x21\x7e\x30\x6a\x06\x02\xd7\x22\xcc\xd5\x93\xa2\x3e\x65\x39\xd3\xe4\x19\x5a\x7e\x12\xca\x19\xae\x2b\xae\x8b\x83\x99\xf7\xa9\xd5\x0d\xb3\x02\x16\xe9\x73\xf2\xbf",
+ 97 },
+ { GCRY_MD_SHA3_512,
+ "\x6d\x8c\x6e\x44\x9b\xc1\x36\x34\xf1\x15\x74\x9c\x24\x8c\x17\xcd\x14\x8b\x72\x15\x7a\x2c\x37\xbf\x89\x69\xea\x83\xb4\xd6\xba\x8c\x0e\xe2\x71\x1c\x28\xee\x11\x49\x5f\x43\x04\x95\x96\x52\x0c\xe4\x36\x00\x4b\x02\x6b\x6c\x1f\x72\x92\xb9\xc4\x36\xb0\x55\xcb\xb7\x2d\x53\x0d\x86\x0d\x12\x76\xa1\x50\x2a\x51\x40\xe3\xc3\xf5\x4a\x93\x66\x3e\x4d\x20\xed\xec\x32\xd2\x84\xe2\x55\x64\xf6\x24\x95\x5b\x52",
+ "\xd6\xab\x0d\x0b\x41\x6d\x1b\xbc\x85\x47\x9f\x98\x50\x58\x57\x61\xb9\x17\x75\xa6\x03\x07\xaf\xac\xf7\x09\x43\xfe\xb5\x86\x57\x74\x0f\xe3\x5d\xc7\x60\xab\x9c\xfa\x67\x2c\x6b\x55\x52\xaa\x67\xbf\xa1\xf0\xd6\xa6\xf9\x43\xb3\x91\x2c\x22\x9b\x8e\x01\x55\xc0\x02",
+ 98 },
+ { GCRY_MD_SHA3_512,
+ "\x6e\xfc\xbc\xaf\x45\x1c\x12\x9d\xbe\x00\xb9\xce\xf0\xc3\x74\x9d\x3e\xe9\xd4\x1c\x7b\xd5\x00\xad\xe4\x0c\xdc\x65\xde\xdb\xbb\xad\xb8\x85\xa5\xb1\x4b\x32\xa0\xc0\xd0\x87\x82\x52\x01\xe3\x03\x28\x8a\x73\x38\x42\xfa\x7e\x59\x9c\x0c\x51\x4e\x07\x8f\x05\xc8\x21\xc7\xa4\x49\x8b\x01\xc4\x00\x32\xe9\xf1\x87\x2a\x1c\x92\x5f\xa1\x7c\xe2\x53\xe8\x93\x5e\x4c\x3c\x71\x28\x22\x42\xcb\x71\x6b\x20\x89\xcc\xc1",
+ "\xbc\x0a\x28\x45\x03\x68\xc2\x88\x01\x3e\x2e\xb1\x19\x6e\x58\x93\x3c\xe0\x58\x69\xcb\x55\xfa\x2b\xda\x61\xd9\xd9\x2f\x83\xb9\x03\xe5\x9d\xde\x0b\x92\x7c\xa6\xdb\xc4\x6f\x5a\xf2\xeb\x7e\x88\x31\xe8\x66\x88\x88\xbf\xea\x46\xd7\x8f\x4d\x27\x48\x18\xd5\x63\x28",
+ 99 },
+ { GCRY_MD_SHA3_512,
+ "\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce",
+ "\x78\x20\xa2\x00\x56\xdf\x74\x1e\x19\xff\x4d\x15\x06\x63\x48\x8c\xf8\x6f\x93\x63\x53\xe9\x9e\x25\xb9\x32\x20\xf5\x23\x0b\xfb\xc1\x33\x63\xb4\x58\xd6\xdb\x92\xf9\xd2\x11\xd7\x05\x36\x2b\x01\x78\x2e\xc1\x18\xac\xfe\x53\xba\xe4\xc6\xac\x2c\x7e\x5d\x01\x11\xfb",
+ 100 },
+ { GCRY_MD_SHA3_512,
+ "\xa8\x73\xe0\xc6\x7c\xa6\x39\x02\x6b\x66\x83\x00\x8f\x7a\xa6\x32\x4d\x49\x79\x55\x0e\x9b\xce\x06\x4c\xa1\xe1\xfb\x97\xa3\x0b\x14\x7a\x24\xf3\xf6\x66\xc0\xa7\x2d\x71\x34\x8e\xde\x70\x1c\xf2\xd1\x7e\x22\x53\xc3\x4d\x1e\xc3\xb6\x47\xdb\xce\xf2\xf8\x79\xf4\xeb\x88\x1c\x48\x30\xb7\x91\x37\x8c\x90\x1e\xb7\x25\xea\x5c\x17\x23\x16\xc6\xd6\x06\xe0\xaf\x7d\xf4\xdf\x7f\x76\xe4\x90\xcd\x30\xb2\xba\xdf\x45\x68\x5f",
+ "\x09\x84\xa4\x32\x86\xa3\xcb\x22\xfb\x59\xf7\x88\x0e\x11\x4e\x23\xe3\xad\x3b\x0d\x43\x02\x5f\x39\x87\xd0\xaa\x6f\xa8\xe5\x3e\x60\x66\xf8\x0f\x47\x69\x24\x1d\xcd\x06\x24\x31\xc7\xf6\x71\x2c\x57\xc6\xe3\x27\x5e\xd3\xf2\xbc\x59\x1d\xb6\xdc\x20\xe5\xbe\x09\x53",
+ 101 },
+ { GCRY_MD_SHA3_512,
+ "\x00\x69\x17\xb6\x4f\x9d\xcd\xf1\xd2\xd8\x7c\x8a\x61\x73\xb6\x4f\x65\x87\x16\x8e\x80\xfa\xa8\x0f\x82\xd8\x4f\x60\x30\x1e\x56\x1e\x31\x2d\x9f\xbc\xe6\x2f\x39\xa6\xfb\x47\x6e\x01\xe9\x25\xf2\x6b\xcc\x91\xde\x62\x14\x49\xbe\x65\x04\xc5\x04\x83\x0a\xae\x39\x40\x96\xc8\xfc\x76\x94\x65\x10\x51\x36\x5d\x4e\xe9\x07\x01\x01\xec\x9b\x68\x08\x6f\x2e\xa8\xf8\xab\x7b\x81\x1e\xa8\xad\x93\x4d\x5c\x9b\x62\xc6\x0a\x47\x71",
+ "\xa6\x30\x04\x97\xf6\x50\x85\x9c\xd7\x44\x67\x98\x85\xcd\x54\x37\xa6\x4c\xc3\x96\x15\x74\xdc\xce\x65\xe1\x61\x16\x16\xa9\xf9\x71\x90\xf3\x91\x30\xba\x53\x20\x94\xbd\x62\x46\x4d\x0b\x8b\x52\x29\x7a\x2c\x9c\x27\x9b\x2c\x98\x60\xc0\x72\xcd\x44\x44\x9a\x9c\xdf",
+ 102 },
+ { GCRY_MD_SHA3_512,
+ "\xf1\x3c\x97\x2c\x52\xcb\x3c\xc4\xa4\xdf\x28\xc9\x7f\x2d\xf1\x1c\xe0\x89\xb8\x15\x46\x6b\xe8\x88\x63\x24\x3e\xb3\x18\xc2\xad\xb1\xa4\x17\xcb\x10\x41\x30\x85\x98\x54\x17\x20\x19\x7b\x9b\x1c\xb5\xba\x23\x18\xbd\x55\x74\xd1\xdf\x21\x74\xaf\x14\x88\x41\x49\xba\x9b\x2f\x44\x6d\x60\x9d\xf2\x40\xce\x33\x55\x99\x95\x7b\x8e\xc8\x08\x76\xd9\xa0\x85\xae\x08\x49\x07\xbc\x59\x61\xb2\x0b\xf5\xf6\xca\x58\xd5\xda\xb3\x8a\xdb",
+ "\xe2\x05\x28\x84\xd1\x12\x23\x88\x07\xc0\x2c\x13\x52\x47\xf7\x6e\x0e\x39\x4b\xd6\x58\x3b\xa8\x3e\xd2\x73\x1c\xf6\x8f\x05\x72\x76\x27\x2b\x89\x1a\x76\x1c\xde\xc6\xd8\xad\x2e\x3f\x33\xe8\x6a\xe9\xd9\xa2\x34\x68\x2b\xce\x7a\x53\x81\x62\x35\x69\x2d\x2c\xf8\x21",
+ 103 },
+ { GCRY_MD_SHA3_512,
+ "\xe3\x57\x80\xeb\x97\x99\xad\x4c\x77\x53\x5d\x4d\xdb\x68\x3c\xf3\x3e\xf3\x67\x71\x53\x27\xcf\x4c\x4a\x58\xed\x9c\xbd\xcd\xd4\x86\xf6\x69\xf8\x01\x89\xd5\x49\xa9\x36\x4f\xa8\x2a\x51\xa5\x26\x54\xec\x72\x1b\xb3\xaa\xb9\x5d\xce\xb4\xa8\x6a\x6a\xfa\x93\x82\x6d\xb9\x23\x51\x7e\x92\x8f\x33\xe3\xfb\xa8\x50\xd4\x56\x60\xef\x83\xb9\x87\x6a\xcc\xaf\xa2\xa9\x98\x7a\x25\x4b\x13\x7c\x6e\x14\x0a\x21\x69\x1e\x10\x69\x41\x38\x48",
+ "\xff\x6a\x7d\x0e\xfe\xa4\x5e\x5f\x0a\xbc\xb1\x73\xfc\xe2\xbe\x76\xb5\x2d\x0f\x3f\xc3\x63\xaf\xe3\x1d\x21\x94\x72\x74\x2d\x73\xe5\x6c\xee\x2a\xb9\x1a\x94\xd4\x13\x35\xc4\xfa\x25\xcb\xdd\x6e\xbd\x1a\x08\x76\x37\xca\xa2\x50\x99\xd5\xa9\xd6\x06\x93\xcf\x62\xb9",
+ 104 },
+ { GCRY_MD_SHA3_512,
+ "\x64\xec\x02\x1c\x95\x85\xe0\x1f\xfe\x6d\x31\xbb\x50\xd4\x4c\x79\xb6\x99\x3d\x72\x67\x81\x63\xdb\x47\x49\x47\xa0\x53\x67\x46\x19\xd1\x58\x01\x6a\xdb\x24\x3f\x5c\x8d\x50\xaa\x92\xf5\x0a\xb3\x6e\x57\x9f\xf2\xda\xbb\x78\x0a\x2b\x52\x93\x70\xda\xa2\x99\x20\x7c\xfb\xcd\xd3\xa9\xa2\x50\x06\xd1\x9c\x4f\x1f\xe3\x3e\x4b\x1e\xae\xc3\x15\xd8\xc6\xee\x1e\x73\x06\x23\xfd\x19\x41\x87\x5b\x92\x4e\xb5\x7d\x6d\x0c\x2e\xdc\x4e\x78\xd6",
+ "\x41\x83\xf9\x67\x59\xe7\xc0\x62\x8f\x2f\xc8\x19\x79\x27\x4f\x42\x11\x1a\x43\xbd\x5d\xbb\x36\x85\xbb\x21\x70\x4c\xe6\xb0\xed\x3d\x16\x4d\xec\xf2\x8a\x3a\x99\x1b\x30\x3e\x1d\x7b\x86\xe2\xb1\x75\xba\x89\x94\x5a\x85\x24\xf9\xc9\x31\x8f\x12\xb1\x60\xa1\xe4\xd1",
+ 105 },
+ { GCRY_MD_SHA3_512,
+ "\x59\x54\xba\xb5\x12\xcf\x32\x7d\x66\xb5\xd9\xf2\x96\x18\x00\x80\x40\x26\x24\xad\x76\x28\x50\x6b\x55\x5e\xea\x83\x82\x56\x23\x24\xcf\x45\x2f\xba\x4a\x21\x30\xde\x3e\x16\x5d\x11\x83\x1a\x27\x0d\x9c\xb9\x7c\xe8\xc2\xd3\x2a\x96\xf5\x0d\x71\x60\x0b\xb4\xca\x26\x8c\xf9\x8e\x90\xd6\x49\x6b\x0a\x66\x19\xa5\xa8\xc6\x3d\xb6\xd8\xa0\x63\x4d\xfc\x6c\x7e\xc8\xea\x9c\x00\x6b\x6c\x45\x6f\x1b\x20\xcd\x19\xe7\x81\xaf\x20\x45\x4a\xc8\x80",
+ "\x94\x0c\x6f\x0b\xac\xf1\x1e\x4b\x04\x5f\x43\x20\x03\xf8\x89\x27\x87\x09\xf9\xc3\xd8\xe4\x20\xc9\xa1\x71\x55\xf5\x7e\x77\x6d\x72\xb4\x30\x6b\xba\x4a\xdf\x72\x17\x08\xf6\xef\x45\x74\x44\xab\x12\x23\x83\x72\xe2\x07\xab\x41\xd5\xef\x5a\x68\x52\x9e\xd0\xb2\x6c",
+ 106 },
+ { GCRY_MD_SHA3_512,
+ "\x03\xd9\xf9\x2b\x2c\x56\x57\x09\xa5\x68\x72\x4a\x0a\xff\x90\xf8\xf3\x47\xf4\x3b\x02\x33\x8f\x94\xa0\x3e\xd3\x2e\x6f\x33\x66\x6f\xf5\x80\x2d\xa4\xc8\x1b\xdc\xe0\xd0\xe8\x6c\x04\xaf\xd4\xed\xc2\xfc\x8b\x41\x41\xc2\x97\x5b\x6f\x07\x63\x9b\x19\x94\xc9\x73\xd9\xa9\xaf\xce\x3d\x9d\x36\x58\x62\x00\x34\x98\x51\x3b\xfa\x16\x6d\x26\x29\xe3\x14\xd9\x74\x41\x66\x7b\x00\x74\x14\xe7\x39\xd7\xfe\xbf\x0f\xe3\xc3\x2c\x17\xaa\x18\x8a\x86\x83",
+ "\x17\x2f\x0c\x68\x03\x10\x37\x51\x56\x91\x1c\x07\xb1\x81\x9f\x0b\x9d\x12\x45\x14\xec\x2c\x37\x50\xcb\x2e\x39\x92\x6a\x28\xa4\x63\x6a\xb7\xec\xdc\xdd\x9d\x6a\x96\x0d\x16\xc8\x64\xdd\x58\x56\x45\xd8\x7f\x14\x5c\x5b\x31\x53\x81\xf3\x56\x65\x6d\x61\x7f\xe9\x7d",
+ 107 },
+ { GCRY_MD_SHA3_512,
+ "\xf3\x1e\x8b\x4f\x9e\x06\x21\xd5\x31\xd2\x2a\x38\x0b\xe5\xd9\xab\xd5\x6f\xae\xc5\x3c\xbd\x39\xb1\xfa\xb2\x30\xea\x67\x18\x44\x40\xe5\xb1\xd1\x54\x57\xbd\x25\xf5\x62\x04\xfa\x91\x7f\xa4\x8e\x66\x90\x16\xcb\x48\xc1\xff\xc1\xe1\xe4\x52\x74\xb3\xb4\x73\x79\xe0\x0a\x43\x84\x3c\xf8\x60\x1a\x55\x51\x41\x1e\xc1\x25\x03\xe5\xaa\xc4\x3d\x86\x76\xa1\xb2\x29\x7e\xc7\xa0\x80\x0d\xbf\xee\x04\x29\x2e\x93\x7f\x21\xc0\x05\xf1\x74\x11\x47\x30\x41",
+ "\x41\x0d\xba\xa5\xe3\x45\x3f\x2d\xaf\xce\x13\x5d\xc0\x14\xf2\x8f\xbf\x69\x3c\x84\xeb\x7d\x4b\xec\xb8\x0a\x3d\xb3\x2e\x16\xe8\x90\x62\xb3\xff\x59\xc1\xdf\xdf\xab\x32\xd8\x4d\x20\x28\x46\x32\xa2\xac\x7f\x8f\x88\xd4\xb7\x02\x3f\x87\x94\x63\xba\x18\xff\x65\x53",
+ 108 },
+ { GCRY_MD_SHA3_512,
+ "\x75\x8e\xa3\xfe\xa7\x38\x97\x3d\xb0\xb8\xbe\x7e\x59\x9b\xbe\xf4\x51\x93\x73\xd6\xe6\xdc\xd7\x19\x5e\xa8\x85\xfc\x99\x1d\x89\x67\x62\x99\x27\x59\xc2\xa0\x90\x02\x91\x2f\xb0\x8e\x0c\xb5\xb7\x6f\x49\x16\x2a\xeb\x8c\xf8\x7b\x17\x2c\xf3\xad\x19\x02\x53\xdf\x61\x2f\x77\xb1\xf0\xc5\x32\xe3\xb5\xfc\x99\xc2\xd3\x1f\x8f\x65\x01\x16\x95\xa0\x87\xa3\x5e\xe4\xee\xe5\xe3\x34\xc3\x69\xd8\xee\x5d\x29\xf6\x95\x81\x5d\x86\x6d\xa9\x9d\xf3\xf7\x94\x03",
+ "\xf9\x3a\x09\x91\x59\xc3\x96\x17\xb7\x5b\x18\x8d\x52\x7f\xc4\xdb\x28\x7c\xbb\x4f\xdd\xdb\xa5\xad\x4d\xcb\x4c\xff\xc4\xdc\x59\x76\x2b\xbc\x41\xa5\x8d\x3a\x78\x8e\xae\x15\x2a\xea\x02\x4b\xc4\xcc\x4f\x29\xfc\x7b\x8a\xb6\x80\x65\xa6\x86\x50\xa0\x4b\x51\x81\x8a",
+ 109 },
+ { GCRY_MD_SHA3_512,
+ "\x47\xc6\xe0\xc2\xb7\x49\x48\x46\x59\x21\x86\x88\x04\xf0\xf7\xbd\x50\xdd\x32\x35\x83\xdc\x78\x4f\x99\x8a\x93\xcd\x1c\xa4\xc6\xef\x84\xd4\x1d\xc8\x1c\x2c\x40\xf3\x4b\x5b\xee\x6a\x93\x86\x7b\x3b\xdb\xa0\x05\x2c\x5f\x59\xe6\xf3\x65\x79\x18\xc3\x82\xe7\x71\xd3\x31\x09\x12\x2c\xc8\xbb\x0e\x1e\x53\xc4\xe3\xd1\x3b\x43\xce\x44\x97\x0f\x5e\x0c\x07\x9d\x2a\xd7\xd7\xa3\x54\x9c\xd7\x57\x60\xc2\x1b\xb1\x5b\x44\x75\x89\xe8\x6e\x8d\x76\xb1\xe9\xce\xd2",
+ "\x05\xe6\x99\x84\xee\x99\xaa\x2b\xc8\x51\x08\x3a\xa4\x4e\xe5\x6f\xee\xf8\x6c\x45\x88\x88\x67\xcd\xcd\xd0\xc7\xa8\x04\x90\x80\xae\x78\x58\xb9\x3c\x19\x95\x3a\x88\x1b\xe5\xc0\x36\xbd\x8f\xe8\x36\x28\xc2\xe3\xaa\x99\x39\xa2\x88\xb4\xac\x4b\xc2\x87\x6c\x2f\xbc",
+ 110 },
+ { GCRY_MD_SHA3_512,
+ "\xf6\x90\xa1\x32\xab\x46\xb2\x8e\xdf\xa6\x47\x92\x83\xd6\x44\x4e\x37\x1c\x64\x59\x10\x8a\xfd\x9c\x35\xdb\xd2\x35\xe0\xb6\xb6\xff\x4c\x4e\xa5\x8e\x75\x54\xbd\x00\x24\x60\x43\x3b\x21\x64\xca\x51\xe8\x68\xf7\x94\x7d\x7d\x7a\x0d\x79\x2e\x4a\xbf\x0b\xe5\xf4\x50\x85\x3c\xc4\x0d\x85\x48\x5b\x2b\x88\x57\xea\x31\xb5\xea\x6e\x4c\xcf\xa2\xf3\xa7\xef\x33\x80\x06\x6d\x7d\x89\x79\xfd\xac\x61\x8a\xad\x3d\x7e\x88\x6d\xea\x4f\x00\x5a\xe4\xad\x05\xe5\x06\x5f",
+ "\xbe\x22\xf3\xe2\x53\xc2\x56\x3c\x33\x53\xe6\x93\xd2\xd5\xa6\x5d\xc6\xba\xc2\xcb\xcd\xa8\xe4\x3e\x85\x84\xf9\xd8\x51\xe6\x02\xd4\x37\x49\x36\x40\x3f\xd6\x88\xf0\x13\x5e\x36\x3d\xe8\x09\x9f\x24\x9d\xd2\x1c\x61\x69\x5c\x10\x9c\x27\xed\x5f\x4f\x4c\x18\x08\xbf",
+ 111 },
+ { GCRY_MD_SHA3_512,
+ "\x58\xd6\xa9\x9b\xc6\x45\x88\x24\xb2\x56\x91\x67\x70\xa8\x41\x70\x40\x72\x1c\xcc\xfd\x4b\x79\xea\xcd\x8b\x65\xa3\x76\x7c\xe5\xba\x7e\x74\x10\x4c\x98\x5a\xc5\x6b\x8c\xc9\xae\xbd\x16\xfe\xbd\x4c\xda\x5a\xdb\x13\x0b\x0f\xf2\x32\x9c\xc8\xd6\x11\xeb\x14\xda\xc2\x68\xa2\xf9\xe6\x33\xc9\x9d\xe3\x39\x97\xfe\xa4\x1c\x52\xa7\xc5\xe1\x31\x7d\x5b\x5d\xae\xd3\x5e\xba\x7d\x5a\x60\xe4\x5d\x1f\xa7\xea\xab\xc3\x5f\x5c\x2b\x0a\x0f\x23\x79\x23\x19\x53\x32\x2c\x4e",
+ "\x1d\x18\x36\xc4\xe2\xc3\xeb\x27\xa7\x4a\x9c\xd6\x00\xc0\x64\x39\x1b\xd9\xed\xd4\x54\x64\xa5\x79\x51\x82\xc8\x79\x47\x48\xba\x51\xa3\x45\xc6\xfa\xe2\xb9\x1f\x57\x58\x40\x1e\x4f\x42\x7d\x50\xb6\x88\x2b\x1d\xf0\x97\x79\x76\xc2\xc9\x43\x2c\x1a\x9b\x3a\xe0\x3f",
+ 112 },
+ { GCRY_MD_SHA3_512,
+ "\xbe\xfa\xb5\x74\x39\x6d\x7f\x8b\x67\x05\xe2\xd5\xb5\x8b\x2c\x1c\x82\x0b\xb2\x4e\x3f\x4b\xae\x3e\x8f\xbc\xd3\x6d\xbf\x73\x4e\xe1\x4e\x5d\x6a\xb9\x72\xae\xdd\x35\x40\x23\x54\x66\xe8\x25\x85\x0e\xe4\xc5\x12\xea\x97\x95\xab\xfd\x33\xf3\x30\xd9\xfd\x7f\x79\xe6\x2b\xbb\x63\xa6\xea\x85\xde\x15\xbe\xae\xea\x6f\x8d\x20\x4a\x28\x95\x60\x59\xe2\x63\x2d\x11\x86\x1d\xfb\x0e\x65\xbc\x07\xac\x8a\x15\x93\x88\xd5\xc3\x27\x7e\x22\x72\x86\xf6\x5f\xf5\xe5\xb5\xae\xc1",
+ "\xcb\x0d\x33\xc1\x73\xc7\x65\xbb\xa3\x71\x4d\x56\xa4\xcf\x48\xfd\x63\x20\xab\x8c\x53\x17\xe7\xab\x1a\x46\x47\x2a\xfb\x75\x62\x32\xcd\x27\xf5\x14\x73\xdc\xf9\xbd\x7d\xac\x1a\xa7\xf6\x69\x35\x3f\xd8\xf3\xd2\x7d\x17\xd3\xfe\x3e\xb3\x38\x68\x76\xec\xa3\x8a\x85",
+ 113 },
+ { GCRY_MD_SHA3_512,
+ "\x8e\x58\x14\x4f\xa9\x17\x9d\x68\x64\x78\x62\x2c\xe4\x50\xc7\x48\x26\x0c\x95\xd1\xba\x43\xb8\xf9\xb5\x9a\xbe\xca\x8d\x93\x48\x8d\xa7\x34\x63\xef\x40\x19\x8b\x4d\x16\xfb\x0b\x07\x07\x20\x13\x47\xe0\x50\x6f\xf1\x9d\x01\xbe\xa0\xf4\x2b\x8a\xf9\xe7\x1a\x1f\x1b\xd1\x68\x78\x10\x69\xd4\xd3\x38\xfd\xef\x00\xbf\x41\x9f\xbb\x00\x30\x31\xdf\x67\x1f\x4a\x37\x97\x95\x64\xf6\x92\x82\xde\x9c\x65\x40\x78\x47\xdd\x0d\xa5\x05\xab\x16\x41\xc0\x2d\xea\x4f\x0d\x83\x49\x86",
+ "\xb5\x79\xad\x0c\x75\x0b\x91\xe0\x67\x1b\xb7\xf0\x48\x2a\x51\x98\x35\xd1\x55\xae\x1a\x4d\xb9\x21\x12\xe6\x6f\xbd\x15\x88\x35\xe0\xc2\x9e\x2f\x12\x2a\x8c\x54\xc5\x30\xf9\x26\x33\xf6\xec\x7b\x22\x2c\xa3\xce\xd4\x5b\x4b\x5a\x24\x42\x6d\x99\xc5\x9c\x1b\x66\x09",
+ 114 },
+ { GCRY_MD_SHA3_512,
+ "\xb5\x5c\x10\xea\xe0\xec\x68\x4c\x16\xd1\x34\x63\xf2\x92\x91\xbf\x26\xc8\x2e\x2f\xa0\x42\x2a\x99\xc7\x1d\xb4\xaf\x14\xdd\x9c\x7f\x33\xed\xa5\x2f\xd7\x3d\x01\x7c\xc0\xf2\xdb\xe7\x34\xd8\x31\xf0\xd8\x20\xd0\x6d\x5f\x89\xda\xcc\x48\x57\x39\x14\x4f\x8c\xfd\x47\x99\x22\x3b\x1a\xff\x90\x31\xa1\x05\xcb\x6a\x02\x9b\xa7\x1e\x6e\x58\x67\xd8\x5a\x55\x49\x91\xc3\x8d\xf3\xc9\xef\x8c\x1e\x1e\x9a\x76\x30\xbe\x61\xca\xab\xca\x69\x28\x0c\x39\x9c\x1f\xb7\xa1\x2d\x12\xae\xfc",
+ "\x68\x9c\x87\x8d\x8a\x44\xc7\x9e\xaf\x05\x79\xdc\x96\xc0\xe7\xfe\x7d\x33\x49\x1f\x59\xa6\x05\x8b\xee\x60\xe1\x4b\x80\x06\xbd\xf6\xa6\x07\x0b\x2b\x6d\x3b\xb6\xd7\xc3\x1c\xca\xe0\x9e\xc4\x03\xdf\x49\xdd\x12\xba\x72\xc8\x53\x2a\x8e\x47\x6b\x4b\x41\x5d\x83\x69",
+ 115 },
+ { GCRY_MD_SHA3_512,
+ "\x2e\xee\xa6\x93\xf5\x85\xf4\xed\x6f\x6f\x88\x65\xbb\xae\x47\xa6\x90\x8a\xec\xd7\xc4\x29\xe4\xbe\xc4\xf0\xde\x1d\x0c\xa0\x18\x3f\xa2\x01\xa0\xcb\x14\xa5\x29\xb7\xd7\xac\x0e\x6f\xf6\x60\x7a\x32\x43\xee\x9f\xb1\x1b\xcf\x3e\x23\x04\xfe\x75\xff\xcd\xdd\x6c\x5c\x2e\x2a\x4c\xd4\x5f\x63\xc9\x62\xd0\x10\x64\x50\x58\xd3\x65\x71\x40\x4a\x6d\x2b\x4f\x44\x75\x54\x34\xd7\x69\x98\xe8\x34\x09\xc3\x20\x5a\xa1\x61\x5d\xb4\x40\x57\xdb\x99\x12\x31\xd2\xcb\x42\x62\x45\x74\xf5\x45",
+ "\x4e\x4d\xc4\x9e\x41\x4c\x79\x4a\x4b\x6d\x8d\x20\x93\xfe\xab\x46\xd9\x13\x21\xcf\xd0\x89\xb1\xfd\x8c\xb5\x15\x4f\x3e\x34\x26\x45\xf6\x23\x3a\x92\x16\xdb\x04\xf0\x80\xe5\xaf\x8b\x15\x6e\x78\x2a\xd1\x6e\x0b\x15\xd8\x14\x17\x3e\x78\xfc\xf5\xe7\xcf\x8e\xa5\x1f",
+ 116 },
+ { GCRY_MD_SHA3_512,
+ "\xda\xb1\x1d\xc0\xb0\x47\xdb\x04\x20\xa5\x85\xf5\x6c\x42\xd9\x31\x75\x56\x28\x52\x42\x84\x99\xf6\x6a\x0d\xb8\x11\xfc\xdd\xda\xb2\xf7\xcd\xff\xed\x15\x43\xe5\xfb\x72\x11\x0b\x64\x68\x6b\xc7\xb6\x88\x7a\x53\x8a\xd4\x4c\x05\x0f\x1e\x42\x63\x1b\xc4\xec\x8a\x9f\x2a\x04\x71\x63\xd8\x22\xa3\x89\x89\xee\x4a\xab\x01\xb4\xc1\xf1\x61\xb0\x62\xd8\x73\xb1\xcf\xa3\x88\xfd\x30\x15\x14\xf6\x22\x24\x15\x7b\x9b\xef\x42\x3c\x77\x83\xb7\xaa\xc8\xd3\x0d\x65\xcd\x1b\xba\x8d\x68\x9c\x2d",
+ "\x2c\x8f\x45\x6f\x90\x91\x51\x7c\xaf\xa9\xdf\x1d\x09\xee\x62\x1e\xdf\xeb\x2c\x00\xda\xb9\x44\x35\x5d\x59\x2d\xfd\xa1\x28\xf8\x37\x22\x85\x78\xe3\x96\x5d\x37\x67\x95\x9d\x3c\xdd\xe4\xe7\xb6\x7e\x02\x24\x1f\x28\xc5\x41\x7e\x33\xea\x74\xe3\x90\x32\xf9\x38\xea",
+ 117 },
+ { GCRY_MD_SHA3_512,
+ "\x42\xe9\x9a\x2f\x80\xae\xe0\xe0\x01\x27\x9a\x24\x34\xf7\x31\xe0\x1d\x34\xa4\x4b\x1a\x81\x01\x72\x69\x21\xc0\x59\x0c\x30\xf3\x12\x0e\xb8\x30\x59\xf3\x25\xe8\x94\xa5\xac\x95\x9d\xca\x71\xce\x22\x14\x79\x99\x16\x42\x4e\x85\x9d\x27\xd7\x89\x43\x7b\x9d\x27\x24\x0b\xf8\xc3\x5a\xdb\xaf\xce\xcc\x32\x2b\x48\xaa\x20\x5b\x29\x39\x62\xd8\x58\x65\x2a\xba\xcb\xd5\x88\xbc\xf6\xcb\xc3\x88\xd0\x99\x3b\xd6\x22\xf9\x6e\xd5\x46\x14\xc2\x5b\x6a\x9a\xa5\x27\x58\x9e\xaa\xff\xcf\x17\xdd\xf7",
+ "\x3a\xe1\x84\x02\xad\x41\x23\xaf\x1a\xd8\x68\x45\x05\x91\xc4\x6f\x66\x43\x1d\x42\x2a\x29\xd9\x32\xdf\x94\xaf\x9a\xb3\xe2\x56\xf8\x06\x57\x5b\x3e\xb0\xd2\x4e\xdc\x75\x31\x72\x5e\x03\x36\x84\x7b\x2e\x57\x1a\xe6\x67\xb6\x19\xa9\xd7\x9a\x3e\x16\x89\x48\xaf\x5d",
+ 118 },
+ { GCRY_MD_SHA3_512,
+ "\x3c\x9b\x46\x45\x0c\x0f\x2c\xae\x8e\x38\x23\xf8\xbd\xb4\x27\x7f\x31\xb7\x44\xce\x2e\xb1\x70\x54\xbd\xdc\x6d\xff\x36\xaf\x7f\x49\xfb\x8a\x23\x20\xcc\x3b\xdf\x8e\x0a\x2e\xa2\x9a\xd3\xa5\x5d\xe1\x16\x5d\x21\x9a\xde\xdd\xb5\x17\x52\x53\xe2\xd1\x48\x9e\x9b\x6f\xdd\x02\xe2\xc3\xd3\xa4\xb5\x4d\x60\xe3\xa4\x73\x34\xc3\x79\x13\xc5\x69\x53\x78\xa6\x69\xe9\xb7\x2d\xec\x32\xaf\x54\x34\xf9\x3f\x46\x17\x6e\xbf\x04\x4c\x47\x84\x46\x7c\x70\x04\x70\xd0\xc0\xb4\x0c\x8a\x08\x8c\x81\x58\x16",
+ "\x6f\x3e\x12\x94\xb6\x7d\x87\x51\x65\xfd\x09\xdd\x49\x3d\xd5\x59\x24\xe9\xe2\x8e\x53\xaf\xa2\xda\x80\x91\x6d\x7d\x54\xe1\x9c\x17\x05\x12\x1d\x61\x7e\x53\xf5\x6e\xba\x47\x67\xd6\x43\x5e\x98\x6f\xee\xae\xb9\x65\xec\x49\x56\xfd\x3c\x02\xde\x12\x88\xfb\xc6\x61",
+ 119 },
+ { GCRY_MD_SHA3_512,
+ "\xd1\xe6\x54\xb7\x7c\xb1\x55\xf5\xc7\x79\x71\xa6\x4d\xf9\xe5\xd3\x4c\x26\xa3\xca\xd6\xc7\xf6\xb3\x00\xd3\x9d\xeb\x19\x10\x09\x46\x91\xad\xaa\x09\x5b\xe4\xba\x5d\x86\x69\x0a\x97\x64\x28\x63\x5d\x55\x26\xf3\xe9\x46\xf7\xdc\x3b\xd4\xdb\xc7\x89\x99\xe6\x53\x44\x11\x87\xa8\x1f\x9a\xdc\xd5\xa3\xc5\xf2\x54\xbc\x82\x56\xb0\x15\x8f\x54\x67\x3d\xcc\x12\x32\xf6\xe9\x18\xeb\xfc\x6c\x51\xce\x67\xea\xeb\x04\x2d\x9f\x57\xee\xc4\xbf\xe9\x10\xe1\x69\xaf\x78\xb3\xde\x48\xd1\x37\xdf\x4f\x28\x40",
+ "\xaa\x33\x98\xbc\x7d\xae\xb4\xf2\x2c\xa6\xd1\x93\x7b\x0c\x60\x97\xa4\x9a\xdb\x6d\xbc\x03\xfc\x0f\x52\x26\xa6\x44\xf2\x17\x29\x6b\xf5\x57\x47\x26\x9b\x86\x1f\xc7\xb2\x2b\xc5\x95\x6c\xe3\xd8\xda\x28\xe9\xf2\x5d\x8c\x95\x99\xbc\x65\x3c\xd0\xee\x0c\x85\x24\x73",
+ 120 },
+ { GCRY_MD_SHA3_512,
+ "\x62\x6f\x68\xc1\x8a\x69\xa6\x59\x01\x59\xa9\xc4\x6b\xe0\x3d\x59\x65\x69\x8f\x2d\xac\x3d\xe7\x79\xb8\x78\xb3\xd9\xc4\x21\xe0\xf2\x1b\x95\x5a\x16\xc7\x15\xc1\xec\x1e\x22\xce\x3e\xb6\x45\xb8\xb4\xf2\x63\xf6\x06\x60\xea\x30\x28\x98\x1e\xeb\xd6\xc8\xc3\xa3\x67\x28\x5b\x69\x1c\x8e\xe5\x69\x44\xa7\xcd\x12\x17\x99\x7e\x1d\x9c\x21\x62\x0b\x53\x6b\xdb\xd5\xde\x89\x25\xff\x71\xde\xc6\xfb\xc0\x66\x24\xab\x6b\x21\xe3\x29\x81\x3d\xe9\x0d\x1e\x57\x2d\xfb\x89\xa1\x81\x20\xc3\xf6\x06\x35\x5d\x25",
+ "\x8b\xcb\xbe\x36\xdb\xe3\x05\xfb\xb5\x58\xea\x46\x72\x1d\x25\xde\x7a\xab\x78\x98\xe5\x83\xe8\xbd\xf2\x67\x01\x22\x43\x87\xc5\x24\xc6\x83\x47\x5c\x24\x2c\x7d\xe0\x90\x60\x8a\x4f\x17\x66\x3d\x21\x72\x76\xf9\x4f\x41\x88\xb9\x42\xa0\x30\x39\xb5\xe3\x8d\x6a\xe3",
+ 121 },
+ { GCRY_MD_SHA3_512,
+ "\x65\x1a\x6f\xb3\xc4\xb8\x0c\x7c\x68\xc6\x01\x16\x75\xe6\x09\x4e\xb5\x6a\xbf\x5f\xc3\x05\x73\x24\xeb\xc6\x47\x78\x25\x06\x1f\x9f\x27\xe7\xa9\x46\x33\xab\xd1\xfa\x59\x8a\x74\x6e\x4a\x57\x7c\xaf\x52\x4c\x52\xec\x17\x88\x47\x1f\x92\xb8\xc3\x7f\x23\x79\x5c\xa1\x9d\x55\x9d\x44\x6c\xab\x16\xcb\xcd\xce\x90\xb7\x9f\xa1\x02\x6c\xee\x77\xbf\x4a\xb1\xb5\x03\xc5\xb9\x4c\x22\x56\xad\x75\xb3\xea\xc6\xfd\x5d\xcb\x96\xac\xa4\xb0\x3a\x83\x4b\xfb\x4e\x9a\xf9\x88\xce\xcb\xf2\xae\x59\x7c\xb9\x09\x79\x40",
+ "\x47\x82\xdf\xca\xb6\x50\xe7\xa8\xda\xe9\xa0\x10\xcb\x00\x2d\xd0\x37\x3b\xfb\xd3\x12\x47\xfa\x98\x60\x87\x6d\x7f\xff\xd2\xd5\x7c\x35\x5f\x20\x54\xcb\x2e\xfe\xb4\x5c\x58\x71\xf2\x84\xf4\x6b\x02\x57\x98\x34\x4a\x37\x19\xef\xab\x34\xd1\x51\x52\xdd\x0b\xbc\x6c",
+ 122 },
+ { GCRY_MD_SHA3_512,
+ "\x8a\xaf\x07\x2f\xce\x8a\x2d\x96\xbc\x10\xb3\xc9\x1c\x80\x9e\xe9\x30\x72\xfb\x20\x5c\xa7\xf1\x0a\xbd\x82\xec\xd8\x2c\xf0\x40\xb1\xbc\x49\xea\x13\xd1\x85\x78\x15\xc0\xe9\x97\x81\xde\x3a\xdb\xb5\x44\x3c\xe1\xc8\x97\xe5\x51\x88\xce\xaf\x22\x1a\xa9\x68\x16\x38\xde\x05\xae\x1b\x32\x29\x38\xf4\x6b\xce\x51\x54\x3b\x57\xec\xdb\x4c\x26\x62\x72\x25\x9d\x17\x98\xde\x13\xbe\x90\xe1\x0e\xfe\xc2\xd0\x74\x84\xd9\xb2\x1a\x38\x70\xe2\xaa\x9e\x06\xc2\x1a\xa2\xd0\xc9\xcf\x42\x00\x80\xa8\x0a\x91\xde\xe1\x6f",
+ "\xa4\xd5\x38\xe4\x49\xe2\xb3\xeb\xf9\xaa\xfc\x88\xd2\x9e\x51\x4b\xa0\xd2\xc8\xde\x27\x06\xf3\xf6\xfa\x5a\x2c\x4f\x95\xf5\xdb\x5b\xab\x59\xc1\xa6\x9c\x16\xe4\x85\x9a\x19\x73\x0a\xbb\x2e\x6b\xf0\x61\x52\x44\x5e\xda\x80\xe3\xbe\x5c\xe6\x52\x02\x3e\xa5\x7e\x5e",
+ 123 },
+ { GCRY_MD_SHA3_512,
+ "\x53\xf9\x18\xfd\x00\xb1\x70\x1b\xd5\x04\xf8\xcd\xea\x80\x3a\xcc\xa2\x1a\xc1\x8c\x56\x4a\xb9\x0c\x2a\x17\xda\x59\x2c\x7d\x69\x68\x8f\x65\x80\x57\x53\x95\x55\x1e\x8c\xd3\x3e\x0f\xef\x08\xca\x6e\xd4\x58\x8d\x4d\x14\x0b\x3e\x44\xc0\x32\x35\x5d\xf1\xc5\x31\x56\x4d\x7f\x48\x35\x75\x33\x44\x34\x5a\x67\x81\xe1\x1c\xd5\xe0\x95\xb7\x3d\xf5\xf8\x2c\x8a\xe3\xad\x00\x87\x79\x36\x89\x66\x71\xe9\x47\xcc\x52\xe2\xb2\x9d\xcd\x46\x3d\x90\xa0\xc9\x92\x91\x28\xda\x22\x2b\x5a\x21\x14\x50\xbb\xc0\xe0\x24\x48\xe2",
+ "\x87\x32\xd2\x43\xf1\xb3\x34\x9f\x90\x0d\xf4\x30\x65\x9b\x9a\xb9\xed\x99\xf6\x26\xad\x35\xcb\x20\x84\xb5\x7d\x60\xe5\xa5\xb4\x72\x13\xad\x21\x38\x59\xcd\x40\x96\x4c\x5a\x26\x7c\x23\x6d\x0e\x38\x16\x75\x25\xf7\x78\xe6\x7e\x37\xd4\xf6\x23\xa8\x88\x41\x28\xed",
+ 124 },
+ { GCRY_MD_SHA3_512,
+ "\xa6\x45\x99\xb8\xa6\x1b\x5c\xce\xc9\xe6\x7a\xed\x69\x44\x74\x59\xc8\xda\x3d\x1e\xc6\xc7\xc7\xc8\x2a\x74\x28\xb9\xb5\x84\xfa\x67\xe9\x0f\x68\xe2\xc0\x0f\xbb\xed\x46\x13\x66\x6e\x51\x68\xda\x4a\x16\xf3\x95\xf7\xa3\xc3\x83\x2b\x3b\x13\x4b\xfc\x9c\xba\xa9\x5d\x2a\x0f\xe2\x52\xf4\x4a\xc6\x68\x1e\xb6\xd4\x0a\xb9\x1c\x1d\x02\x82\xfe\xd6\x70\x1c\x57\x46\x3d\x3c\x5f\x2b\xb8\xc6\xa7\x30\x1f\xb4\x57\x6a\xa3\xb5\xf1\x55\x10\xdb\x89\x56\xff\x77\x47\x8c\x26\xa7\xc0\x9b\xea\x7b\x39\x8c\xfc\x83\x50\x3f\x53\x8e",
+ "\x97\xdc\x26\x06\xe1\x4f\x7b\xff\xf1\xfc\xa4\x97\x96\x5e\x36\xca\xa3\xa8\x1c\xfd\x64\x59\xd0\x25\x45\x29\xf6\x4d\xa4\x0f\xfe\x74\x42\xc0\x8a\x15\x1d\x6c\xee\x3b\x46\xbf\x34\x14\xe8\x01\x10\xa0\xf7\x1e\xee\x44\xd7\x94\x00\x27\xde\xe9\x0e\x91\x9e\x49\x8d\x65",
+ 125 },
+ { GCRY_MD_SHA3_512,
+ "\x0e\x3a\xb0\xe0\x54\x73\x9b\x00\xcd\xb6\xa8\x7b\xd1\x2c\xae\x02\x4b\x54\xcb\x5e\x55\x0e\x6c\x42\x53\x60\xc2\xe8\x7e\x59\x40\x1f\x5e\xc2\x4e\xf0\x31\x48\x55\xf0\xf5\x6c\x47\x69\x5d\x56\xa7\xfb\x14\x17\x69\x3a\xf2\xa1\xed\x52\x91\xf2\xfe\xe9\x5f\x75\xee\xd5\x4a\x1b\x1c\x2e\x81\x22\x6f\xbf\xf6\xf6\x3a\xde\x58\x49\x11\xc7\x19\x67\xa8\xeb\x70\x93\x3b\xc3\xf5\xd1\x5b\xc9\x1b\x5c\x26\x44\xd9\x51\x6d\x3c\x3a\x8c\x15\x4e\xe4\x8e\x11\x8b\xd1\x44\x2c\x04\x3c\x7a\x0d\xba\x5a\xc5\xb1\xd5\x36\x0a\xae\x5b\x90\x65",
+ "\xde\x59\x78\xea\xce\x4e\x51\xf7\xd2\x89\xf2\xbe\xfb\xec\xb3\xaa\xc8\xe9\xca\xd4\x8f\xa0\xf7\x31\x0c\x67\x3d\x52\xbb\xca\xee\xbd\xe4\x9c\xb5\xa7\x6d\x33\x4d\x6d\xfd\xd5\x1a\xc1\xab\x24\xe9\xe1\xcd\xc9\x15\x06\x9d\xbd\xdb\x3d\x2e\x30\xb0\xb0\xc2\x6b\x3e\xe1",
+ 126 },
+ { GCRY_MD_SHA3_512,
+ "\xa6\x2f\xc5\x95\xb4\x09\x6e\x63\x36\xe5\x3f\xcd\xfc\x8d\x1c\xc1\x75\xd7\x1d\xac\x9d\x75\x0a\x61\x33\xd2\x31\x99\xea\xac\x28\x82\x07\x94\x4c\xea\x6b\x16\xd2\x76\x31\x91\x5b\x46\x19\xf7\x43\xda\x2e\x30\xa0\xc0\x0b\xbd\xb1\xbb\xb3\x5a\xb8\x52\xef\x3b\x9a\xec\x6b\x0a\x8d\xcc\x6e\x9e\x1a\xba\xa3\xad\x62\xac\x0a\x6c\x5d\xe7\x65\xde\x2c\x37\x11\xb7\x69\xe3\xfd\xe4\x4a\x74\x01\x6f\xff\x82\xac\x46\xfa\x8f\x17\x97\xd3\xb2\xa7\x26\xb6\x96\xe3\xde\xa5\x53\x04\x39\xac\xee\x3a\x45\xc2\xa5\x1b\xc3\x2d\xd0\x55\x65\x0b",
+ "\x33\xab\xca\x29\xa8\xa7\x09\x4c\xfb\x10\xbe\x4a\x80\xe8\x1f\x80\x01\xeb\xb9\x33\xc0\xd4\xb9\x8a\x69\x5b\x22\xab\x55\x3f\x94\xf0\x76\x46\xab\xce\x6a\xdf\x49\x18\x17\xd1\x7b\x78\xc4\x07\x47\xd5\x6f\xaf\x88\xa6\x13\x13\x8c\xa0\xe5\x96\x63\x6c\x67\x23\x97\xb4",
+ 127 },
+ { GCRY_MD_SHA3_512,
+ "\x2b\x6d\xb7\xce\xd8\x66\x5e\xbe\x9d\xeb\x08\x02\x95\x21\x84\x26\xbd\xaa\x7c\x6d\xa9\xad\xd2\x08\x89\x32\xcd\xff\xba\xa1\xc1\x41\x29\xbc\xcd\xd7\x0f\x36\x9e\xfb\x14\x92\x85\x85\x8d\x2b\x1d\x15\x5d\x14\xde\x2f\xdb\x68\x0a\x8b\x02\x72\x84\x05\x51\x82\xa0\xca\xe2\x75\x23\x4c\xc9\xc9\x28\x63\xc1\xb4\xab\x66\xf3\x04\xcf\x06\x21\xcd\x54\x56\x5f\x5b\xff\x46\x1d\x3b\x46\x1b\xd4\x0d\xf2\x81\x98\xe3\x73\x25\x01\xb4\x86\x0e\xad\xd5\x03\xd2\x6d\x6e\x69\x33\x8f\x4e\x04\x56\xe9\xe9\xba\xf3\xd8\x27\xae\x68\x5f\xb1\xd8\x17",
+ "\x4f\xab\x45\x80\x6b\x46\x28\x06\x84\x58\xb5\xd0\xa2\xd4\xbf\x10\x1b\x8b\xfc\x92\x76\xef\x86\xad\x5d\x88\x37\x65\xc4\x3f\x72\xce\x8a\x5f\x7b\x4c\x5b\x53\x5a\x91\x51\x30\xbb\x18\x5e\x69\x9a\xb6\x22\x28\x01\x4e\x54\xdf\x79\x0c\x0e\x93\xaa\xdb\xe7\xe3\x9e\x19",
+ 128 },
+ { GCRY_MD_SHA3_512,
+ "\x10\xdb\x50\x9b\x2c\xdc\xab\xa6\xc0\x62\xae\x33\xbe\x48\x11\x6a\x29\xeb\x18\xe3\x90\xe1\xbb\xad\xa5\xca\x0a\x27\x18\xaf\xbc\xd2\x34\x31\x44\x01\x06\x59\x48\x93\x04\x3c\xc7\xf2\x62\x52\x81\xbf\x7d\xe2\x65\x58\x80\x96\x6a\x23\x70\x5f\x0c\x51\x55\xc2\xf5\xcc\xa9\xf2\xc2\x14\x2e\x96\xd0\xa2\xe7\x63\xb7\x06\x86\xcd\x42\x1b\x5d\xb8\x12\xda\xce\xd0\xc6\xd6\x50\x35\xfd\xe5\x58\xe9\x4f\x26\xb3\xe6\xdd\xe5\xbd\x13\x98\x0c\xc8\x02\x92\xb7\x23\x01\x3b\xd0\x33\x28\x45\x84\xbf\xf2\x76\x57\x87\x1b\x0c\xf0\x7a\x84\x9f\x4a\xe2",
+ "\x5f\x0b\xfb\x41\x46\x91\x0c\xf0\xc3\x20\x36\x4b\x6a\xd8\xa0\x2b\x09\x66\x22\x9a\xb2\x67\x6d\x96\x70\xf0\xdd\x24\x1e\x81\x04\xdb\x02\x79\x7e\xef\xea\x0b\x9c\xab\xbe\x90\xa4\x47\x57\xb0\x33\x75\x59\x25\xb2\xfc\xcf\x3a\x00\x05\x4f\x9a\xe8\xfb\xce\xf7\x52\xa8",
+ 129 },
+ { GCRY_MD_SHA3_512,
+ "\x93\x34\xde\x60\xc9\x97\xbd\xa6\x08\x61\x01\xa6\x31\x4f\x64\xe4\x45\x8f\x5f\xf9\x45\x0c\x50\x9d\xf0\x06\xe8\xc5\x47\x98\x3c\x65\x1c\xa9\x78\x79\x17\x5a\xab\xa0\xc5\x39\xe8\x2d\x05\xc1\xe0\x2c\x48\x09\x75\xcb\xb3\x01\x18\x12\x10\x61\xb1\xeb\xac\x4f\x8d\x9a\x37\x81\xe2\xdb\x6b\x18\x04\x2e\x01\xec\xf9\x01\x7a\x64\xa0\xe5\x74\x47\xec\x7f\xcb\xe6\xa7\xf8\x25\x85\xf7\x40\x3e\xe2\x22\x3d\x52\xd3\x7b\x4b\xf4\x26\x42\x86\x13\xd6\xb4\x25\x79\x80\x97\x2a\x0a\xca\xb5\x08\xa7\x62\x0c\x1c\xb2\x8e\xb4\xe9\xd3\x0f\xc4\x13\x61\xec",
+ "\xd3\x8e\xf3\xb1\x2e\xaa\x0b\xf6\x2a\x75\xb6\xb6\x3c\xff\x3c\x9e\xf1\x71\xde\x1b\x75\xf5\xd0\x26\x29\x36\x5b\xcf\xe6\x5b\xa7\xdd\xd3\x0f\xce\xf7\xfe\xbb\x82\xf1\x9f\x9b\xed\xcc\x1c\xc4\xc6\x79\xb4\x29\x2e\xa6\x2c\x2a\x90\xa7\x56\x2d\xa9\xa1\x31\x8f\xe2\x78",
+ 130 },
+ { GCRY_MD_SHA3_512,
+ "\xe8\x8a\xb0\x86\x89\x16\x93\xaa\x53\x5c\xeb\x20\xe6\x4c\x7a\xb9\x7c\x7d\xd3\x54\x8f\x37\x86\x33\x98\x97\xa5\xf0\xc3\x90\x31\x54\x9c\xa8\x70\x16\x6e\x47\x77\x43\xcc\xfb\xe0\x16\xb4\x42\x8d\x89\x73\x8e\x42\x6f\x5f\xfe\x81\x62\x61\x37\xf1\x7a\xec\xff\x61\xb7\x2d\xbe\xe2\xdc\x20\x96\x18\x80\xcf\xe2\x81\xdf\xab\x5e\xe3\x8b\x19\x21\x88\x14\x50\xe1\x60\x32\xde\x5e\x4d\x55\xad\x8d\x4f\xca\x60\x97\x21\xb0\x69\x2b\xac\x79\xbe\x5a\x06\xe1\x77\xfe\x8c\x80\xc0\xc8\x35\x19\xfb\x33\x47\xde\x9f\x43\xd5\x56\x1c\xb8\x10\x7b\x9b\x5e\xdc",
+ "\x60\xc9\x5c\x27\x4f\x99\xb8\x64\x3a\x18\x63\x44\xbc\x01\xd1\x27\x90\x10\xbe\x55\xd1\xbe\x76\xf4\xe6\xf9\x19\xf6\xb5\x4d\x33\x5e\xe0\xe1\xca\x92\x13\x3f\x3d\x7a\x25\x20\xcd\x82\xc4\x00\x0e\x15\xef\xed\x8d\x8a\x66\xf3\x1b\x16\xb0\x97\x7c\x63\xde\x1b\xeb\x05",
+ 131 },
+ { GCRY_MD_SHA3_512,
+ "\xfd\x19\xe0\x1a\x83\xeb\x6e\xc8\x10\xb9\x45\x82\xcb\x8f\xbf\xa2\xfc\xb9\x92\xb5\x36\x84\xfb\x74\x8d\x22\x64\xf0\x20\xd3\xb9\x60\xcb\x1d\x6b\x8c\x34\x8c\x2b\x54\xa9\xfc\xea\x72\x33\x0c\x2a\xaa\x9a\x24\xec\xdb\x00\xc4\x36\xab\xc7\x02\x36\x1a\x82\xbb\x88\x28\xb8\x53\x69\xb8\xc7\x2e\xce\x00\x82\xfe\x06\x55\x71\x63\x89\x9c\x2a\x0e\xfa\x46\x6c\x33\xc0\x43\x43\xa8\x39\x41\x70\x57\x39\x9a\x63\xa3\x92\x9b\xe1\xee\x48\x05\xd6\xce\x3e\x5d\x0d\x09\x67\xfe\x90\x04\x69\x6a\x56\x63\xf4\xca\xc9\x17\x90\x06\xa2\xce\xb7\x55\x42\xd7\x5d\x68",
+ "\x93\x85\xd0\xed\x9e\x73\x49\x8e\x24\xb8\xc6\xe7\x46\xa1\xc6\xbe\x80\x11\xee\x30\xfc\xac\x9b\xa1\x72\x24\xee\x20\x12\x37\x85\x22\xc7\x8f\x87\x37\xa2\x24\x62\x1f\xba\x19\xc4\x20\x40\xc5\xc7\xf3\x8a\xc0\x7b\x40\xe0\xe7\x5e\xbc\x59\xd1\x79\x75\xee\x85\xd6\x55",
+ 132 },
+ { GCRY_MD_SHA3_512,
+ "\x59\xae\x20\xb6\xf7\xe0\xb3\xc7\xa9\x89\xaf\xb2\x83\x24\xa4\x0f\xca\x25\xd8\x65\x1c\xf1\xf4\x6a\xe3\x83\xef\x6d\x84\x41\x58\x7a\xa1\xc0\x4c\x3e\x3b\xf8\x8e\x81\x31\xce\x61\x45\xcf\xb8\x97\x3d\x96\x1e\x84\x32\xb2\x02\xfa\x5a\xf3\xe0\x9d\x62\x5f\xaa\xd8\x25\xbc\x19\xda\x9b\x5c\x6c\x20\xd0\x2a\xbd\xa2\xfc\xc5\x8b\x5b\xd3\xfe\x50\x7b\xf2\x01\x26\x3f\x30\x54\x38\x19\x51\x0c\x12\xbc\x23\xe2\xdd\xb4\xf7\x11\xd0\x87\xa8\x6e\xdb\x1b\x35\x53\x13\x36\x3a\x2d\xe9\x96\xb8\x91\x02\x5e\x14\x70\x36\x08\x74\x01\xcc\xf3\xca\x78\x15\xbf\x3c\x49",
+ "\x74\x87\x16\x4d\x40\x88\x74\xaf\xdf\x07\xeb\xda\xde\x8c\x62\xe7\x56\x14\x7b\xea\xb3\x23\x8b\x87\x38\xae\xed\x92\x7f\x54\xfe\x6d\x33\xaf\x39\x17\xd4\xe1\x81\xb5\x0c\xbc\x88\xa3\x79\xc7\x35\x85\xf9\xfb\xa4\xc1\xb6\x7b\x4b\xe4\x49\x00\x4e\xa0\xf6\x6d\x11\xad",
+ 133 },
+ { GCRY_MD_SHA3_512,
+ "\x77\xee\x80\x4b\x9f\x32\x95\xab\x23\x62\x79\x8b\x72\xb0\xa1\xb2\xd3\x29\x1d\xce\xb8\x13\x98\x96\x35\x58\x30\xf3\x4b\x3b\x32\x85\x61\x53\x1f\x80\x79\xb7\x9a\x6e\x99\x80\x70\x51\x50\x86\x64\x02\xfd\xc1\x76\xc0\x58\x97\xe3\x59\xa6\xcb\x1a\x7a\xb0\x67\x38\x3e\xb4\x97\x18\x2a\x7e\x5a\xef\x70\x38\xe4\xc9\x6d\x13\x3b\x27\x82\x91\x74\x17\xe3\x91\x53\x5b\x5e\x1b\x51\xf4\x7d\x8e\xd7\xe4\xd4\x02\x5f\xe9\x8d\xc8\x7b\x9c\x16\x22\x61\x4b\xff\x3d\x10\x29\xe6\x8e\x37\x2d\xe7\x19\x80\x38\x57\xca\x52\x06\x7c\xdd\xaa\xd9\x58\x95\x1c\xb2\x06\x8c\xc6",
+ "\x0f\x41\xab\x2d\x10\xc5\x1e\x28\x63\x8d\xad\x17\x86\x55\xf1\x60\xb2\xf7\x53\xdb\x44\xee\xd6\xce\x41\x04\x69\x3c\xc4\xa9\x38\xd8\x87\x61\x77\x74\xaf\xec\xb3\x3b\x89\x0e\xe7\xfc\x57\x76\x56\xce\x16\x8e\xea\x42\xc6\x04\xd1\x52\xb9\x52\xc9\xb7\x72\xc9\xb5\x30",
+ 134 },
+ { GCRY_MD_SHA3_512,
+ "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+ "\x75\x75\xa1\xfb\x4f\xc9\xa8\xf9\xc0\x46\x6b\xd5\xfc\xa4\x96\xd1\xcb\x78\x69\x67\x73\xa2\x12\xa5\xf6\x2d\x02\xd1\x4e\x32\x59\xd1\x92\xa8\x7e\xba\x44\x07\xdd\x83\x89\x35\x27\x33\x14\x07\xb6\xda\xda\xad\x92\x0d\xbc\x46\x48\x9b\x67\x74\x93\xce\x5f\x20\xb5\x95",
+ 135 },
+ { GCRY_MD_SHA3_512,
+ "\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",
+ "\x2e\x29\x37\x65\x02\x2d\x48\x99\x6c\xe8\xef\xf0\xbe\x54\xe8\x7e\xfb\x94\xa1\x4c\x72\xde\x5a\xcd\x10\xd0\xeb\x5e\xce\x02\x9c\xad\xfa\x3b\xa1\x7a\x40\xb2\xff\xa2\x16\x39\x91\xb1\x77\x86\xe5\x1c\xab\xa7\x9e\x5e\x0f\xfd\x34\xcf\x08\x5e\x2a\x09\x8b\xe8\xba\xcb",
+ 136 },
+ { GCRY_MD_SHA3_512,
+ "\x04\x41\x0e\x31\x08\x2a\x47\x58\x4b\x40\x6f\x05\x13\x98\xa6\xab\xe7\x4e\x4d\xa5\x9b\xb6\xf8\x5e\x6b\x49\xe8\xa1\xf7\xf2\xca\x00\xdf\xba\x54\x62\xc2\xcd\x2b\xfd\xe8\xb6\x4f\xb2\x1d\x70\xc0\x83\xf1\x13\x18\xb5\x6a\x52\xd0\x3b\x81\xca\xc5\xee\xc2\x9e\xb3\x1b\xd0\x07\x8b\x61\x56\x78\x6d\xa3\xd6\xd8\xc3\x30\x98\xc5\xc4\x7b\xb6\x7a\xc6\x4d\xb1\x41\x65\xaf\x65\xb4\x45\x44\xd8\x06\xdd\xe5\xf4\x87\xd5\x37\x3c\x7f\x97\x92\xc2\x99\xe9\x68\x6b\x7e\x58\x21\xe7\xc8\xe2\x45\x83\x15\xb9\x96\xb5\x67\x7d\x92\x6d\xac\x57\xb3\xf2\x2d\xa8\x73\xc6\x01\x01\x6a\x0d",
+ "\xbe\x8e\x14\xb6\x75\x7f\xfe\x53\xc9\xb7\x5f\x6d\xde\x9a\x7b\x6c\x40\x47\x40\x41\xde\x83\xd4\xa6\x06\x45\xa8\x26\xd7\xaf\x1a\xbe\x1e\xef\xcb\x7b\x74\xb6\x2c\xa6\xa5\x14\xe5\xf2\x69\x7d\x58\x5b\xfe\xce\xce\x12\x93\x1b\xbe\x1d\x4e\xd7\xeb\xf7\xb0\xbe\x66\x0e",
+ 137 },
+ { GCRY_MD_SHA3_512,
+ "\x8b\x81\xe9\xba\xdd\xe0\x26\xf1\x4d\x95\xc0\x19\x97\x70\x24\xc9\xe1\x3d\xb7\xa5\xcd\x21\xf9\xe9\xfc\x49\x1d\x71\x61\x64\xbb\xac\xdc\x70\x60\xd8\x82\x61\x5d\x41\x14\x38\xae\xa0\x56\xc3\x40\xcd\xf9\x77\x78\x8f\x6e\x17\xd1\x18\xde\x55\x02\x68\x55\xf9\x32\x70\x47\x2d\x1f\xd1\x8b\x9e\x7e\x81\x2b\xae\x10\x7e\x0d\xfd\xe7\x06\x33\x01\xb7\x1f\x6c\xfe\x4e\x22\x5c\xab\x3b\x23\x29\x05\xa5\x6e\x99\x4f\x08\xee\x28\x91\xba\x92\x2d\x49\xc3\xda\xfe\xb7\x5f\x7c\x69\x75\x0c\xb6\x7d\x82\x2c\x96\x17\x6c\x46\xbd\x8a\x29\xf1\x70\x13\x73\xfb\x09\xa1\xa6\xe3\xc7\x15\x8f",
+ "\x6c\x7e\x64\xee\x0d\x82\x60\x73\xd4\xf4\x4b\xcf\x15\x86\xa8\x3b\xac\xf3\xe2\xe1\x38\xdf\xdb\x65\xb8\xb8\xb3\x5f\xd7\xda\xe3\x00\xea\x6e\x32\xc6\x24\x5c\xca\x27\xc6\x74\xfe\xb2\x19\x67\x55\x94\x5a\xb7\xc5\xdc\xe9\x9e\xab\x91\x58\xa7\x55\x18\xac\x27\xc4\x31",
+ 138 },
+ { GCRY_MD_SHA3_512,
+ "\xfa\x6e\xed\x24\xda\x66\x66\xa2\x22\x08\x14\x6b\x19\xa5\x32\xc2\xec\x9b\xa9\x4f\x09\xf1\xde\xf1\xe7\xfc\x13\xc3\x99\xa4\x8e\x41\xac\xc2\xa5\x89\xd0\x99\x27\x62\x96\x34\x8f\x39\x62\x53\xb5\x7c\xb0\xe4\x02\x91\xbd\x28\x27\x73\x65\x6b\x6e\x0d\x8b\xea\x1c\xda\x08\x4a\x37\x38\x81\x6a\x84\x04\x85\xfc\xf3\xfb\x30\x7f\x77\x7f\xa5\xfe\xac\x48\x69\x5c\x2a\xf4\x76\x97\x20\x25\x8c\x77\x94\x3f\xb4\x55\x6c\x36\x2d\x9c\xba\x8b\xf1\x03\xae\xb9\x03\x4b\xaa\x8e\xa8\xbf\xb9\xc4\xf8\xe6\x74\x2c\xe0\xd5\x2c\x49\xea\x8e\x97\x4f\x33\x96\x12\xe8\x30\xe9\xe7\xa9\xc2\x90\x65",
+ "\x58\x42\xd4\xda\x2c\x30\x9d\x9b\x2a\xa7\xcf\xae\x70\x22\x62\xf7\x70\xa8\xe6\x46\x62\x0d\x65\xc1\x72\x71\x41\x6e\x9d\x79\x81\xff\x93\xd2\x28\xcd\x60\xdc\x1c\xc1\x69\x21\x02\x0d\x84\x1e\x43\x9e\x87\xf0\x85\xe5\x03\xd4\x66\xc9\x04\xab\xf8\xcd\xd5\xec\xca\xa9",
+ 139 },
+ { GCRY_MD_SHA3_512,
+ "\x9b\xb4\xaf\x1b\x4f\x09\xc0\x71\xce\x3c\xaf\xa9\x2e\x4e\xb7\x3c\xe8\xa6\xf5\xd8\x2a\x85\x73\x34\x40\x36\x8d\xee\x4e\xb1\xcb\xc7\xb5\x5a\xc1\x50\x77\x3b\x6f\xe4\x7d\xbe\x03\x6c\x45\x58\x2e\xd6\x7e\x23\xf4\xc7\x45\x85\xda\xb5\x09\xdf\x1b\x83\x61\x05\x64\x54\x56\x42\xb2\xb1\xec\x46\x3e\x18\x04\x8f\xc2\x34\x77\xc6\xb2\xaa\x03\x55\x94\xec\xd3\x37\x91\xaf\x6a\xf4\xcb\xc2\xa1\x16\x6a\xba\x8d\x62\x8c\x57\xe7\x07\xf0\xb0\xe8\x70\x7c\xaf\x91\xcd\x44\xbd\xb9\x15\xe0\x29\x6e\x01\x90\xd5\x6d\x33\xd8\xdd\xe1\x0b\x5b\x60\x37\x78\x38\x97\x3c\x1d\x94\x3c\x22\xed\x33\x5e",
+ "\xf8\xb2\x45\x27\xb5\xc8\x4c\xa9\xa7\x02\xdb\x2f\x53\x5f\x78\xed\x03\x23\xc2\x93\x2a\x25\x5d\xb2\x4f\x87\x25\x51\xca\x7f\x5c\x04\x82\xb3\x69\x0c\x62\xee\xc8\xad\x69\x30\x8d\xb2\xd7\x23\x08\xc4\xd6\x15\xcd\xe3\x83\x5b\x39\xb4\xf6\xff\x11\x54\x66\xf3\x27\x63",
+ 140 },
+ { GCRY_MD_SHA3_512,
+ "\x21\x67\xf0\x21\x18\xcc\x62\x04\x3e\x90\x91\xa6\x47\xca\xdb\xed\x95\x61\x1a\x52\x1f\xe0\xd6\x4e\x85\x18\xf1\x6c\x80\x8a\xb2\x97\x72\x55\x98\xae\x29\x68\x80\xa7\x73\x60\x7a\x79\x8f\x7c\x3c\xfc\xe8\x0d\x25\x1e\xbe\xc6\x88\x50\x15\xf9\xab\xf7\xea\xab\xae\x46\x79\x8f\x82\xcb\x59\x26\xde\x5c\x23\xf4\x4a\x3f\x9f\x95\x34\xb3\xc6\xf4\x05\xb5\x36\x4c\x2f\x8a\x8b\xdc\x5c\xa4\x9c\x74\x9b\xed\x8c\xe4\xba\x48\x89\x70\x62\xae\x84\x24\xca\x6d\xde\x5f\x55\xc0\xe4\x2a\x95\xd1\xe2\x92\xca\x54\xfb\x46\xa8\x4f\xbc\x9c\xd8\x7f\x2d\x0c\x9e\x74\x48\xde\x30\x43\xae\x22\xfd\xd2\x29",
+ "\x08\xc6\xe3\x93\x8d\xe4\x81\x71\xa9\x96\x46\xbd\x09\x0b\x7d\x53\xff\x42\x2a\xe6\x3f\x99\x85\x00\x32\xbd\x13\x1a\xc7\xbd\xfb\xa8\xf8\x34\x66\xad\x31\xfa\xd3\x16\x9d\x8a\x32\x0f\xd9\x54\x8b\xdf\xf2\xc4\x0b\xa2\x0e\x0d\x03\x1a\x80\x54\x01\x9c\x40\xed\x26\x62",
+ 141 },
+ { GCRY_MD_SHA3_512,
+ "\x94\xb7\xfa\x0b\xc1\xc4\x4e\x94\x9b\x1d\x76\x17\xd3\x1b\x47\x20\xcb\xe7\xca\x57\xc6\xfa\x4f\x40\x94\xd4\x76\x15\x67\xe3\x89\xec\xc6\x4f\x69\x68\xe4\x06\x4d\xf7\x0d\xf8\x36\xa4\x7d\x0c\x71\x33\x36\xb5\x02\x8b\x35\x93\x0d\x29\xeb\x7a\x7f\x9a\x5a\xf9\xad\x5c\xf4\x41\x74\x5b\xae\xc9\xbb\x01\x4c\xee\xff\x5a\x41\xba\x5c\x1c\xe0\x85\xfe\xb9\x80\xba\xb9\xcf\x79\xf2\x15\x8e\x03\xef\x7e\x63\xe2\x9c\x38\xd7\x81\x6a\x84\xd4\xf7\x1e\x0f\x54\x8b\x7f\xc3\x16\x08\x5a\xe3\x8a\x06\x0f\xf9\xb8\xde\xc3\x6f\x91\xad\x9e\xbc\x0a\x5b\x6c\x33\x8c\xbb\x8f\x66\x59\xd3\x42\xa2\x43\x68\xcf",
+ "\x69\x78\xad\x4b\xc4\xf0\xfc\x44\xc3\x5c\x66\x91\xca\x46\x62\x7d\x84\x0b\xaa\x57\x2d\xe9\xb0\x21\x66\x73\xc9\x88\x19\x71\x91\xcd\xf8\x12\xcf\x21\x92\x0e\x05\x2c\xc9\xce\x1d\x50\x7d\x1b\xa7\xdb\x6f\x15\x1d\x01\x62\x0a\xda\x70\x2d\xc6\x37\xbf\x90\x80\x9c\x19",
+ 142 },
+ { GCRY_MD_SHA3_512,
+ "\xea\x40\xe8\x3c\xb1\x8b\x3a\x24\x2c\x1e\xcc\x6c\xcd\x0b\x78\x53\xa4\x39\xda\xb2\xc5\x69\xcf\xc6\xdc\x38\xa1\x9f\x5c\x90\xac\xbf\x76\xae\xf9\xea\x37\x42\xff\x3b\x54\xef\x7d\x36\xeb\x7c\xe4\xff\x1c\x9a\xb3\xbc\x11\x9c\xff\x6b\xe9\x3c\x03\xe2\x08\x78\x33\x35\xc0\xab\x81\x37\xbe\x5b\x10\xcd\xc6\x6f\xf3\xf8\x9a\x1b\xdd\xc6\xa1\xee\xd7\x4f\x50\x4c\xbe\x72\x90\x69\x0b\xb2\x95\xa8\x72\xb9\xe3\xfe\x2c\xee\x9e\x6c\x67\xc4\x1d\xb8\xef\xd7\xd8\x63\xcf\x10\xf8\x40\xfe\x61\x8e\x79\x36\xda\x3d\xca\x5c\xa6\xdf\x93\x3f\x24\xf6\x95\x4b\xa0\x80\x1a\x12\x94\xcd\x8d\x7e\x66\xdf\xaf\xec",
+ "\x3a\x8e\x93\x8c\x45\xf3\xf1\x77\x99\x12\x96\xb2\x45\x65\xd9\xa6\x60\x55\x16\x61\x5d\x96\xa0\x62\xc8\xbe\x53\xa0\xd6\xc5\xa6\x48\x7b\xe3\x5d\x2a\x8f\x3c\xf6\x62\x0d\x0c\x2d\xba\x2c\x56\x0d\x68\x29\x5f\x28\x4b\xe7\xf8\x2f\x3b\x92\x91\x90\x33\xc9\xce\x5d\x80",
+ 143 },
+ { GCRY_MD_SHA3_512,
+ "\x15\x7d\x5b\x7e\x45\x07\xf6\x6d\x9a\x26\x74\x76\xd3\x38\x31\xe7\xbb\x76\x8d\x4d\x04\xcc\x34\x38\xda\x12\xf9\x01\x02\x63\xea\x5f\xca\xfb\xde\x25\x79\xdb\x2f\x6b\x58\xf9\x11\xd5\x93\xd5\xf7\x9f\xb0\x5f\xe3\x59\x6e\x3f\xa8\x0f\xf2\xf7\x61\xd1\xb0\xe5\x70\x80\x05\x5c\x11\x8c\x53\xe5\x3c\xdb\x63\x05\x52\x61\xd7\xc9\xb2\xb3\x9b\xd9\x0a\xcc\x32\x52\x0c\xbb\xdb\xda\x2c\x4f\xd8\x85\x6d\xbc\xee\x17\x31\x32\xa2\x67\x91\x98\xda\xf8\x30\x07\xa9\xb5\xc5\x15\x11\xae\x49\x76\x6c\x79\x2a\x29\x52\x03\x88\x44\x4e\xbe\xfe\x28\x25\x6f\xb3\x3d\x42\x60\x43\x9c\xba\x73\xa9\x47\x9e\xe0\x0c\x63",
+ "\xfe\x45\x28\x98\x74\x87\x97\x20\xce\x2a\x84\x4a\xe3\x4b\xb7\x35\x22\x77\x5d\xcb\x60\x19\xdc\xd2\x2b\x88\x85\x99\x46\x72\xa0\x88\x9c\x69\xe8\x11\x5c\x64\x1d\xc8\xb8\x3e\x39\xf7\x31\x18\x15\xa1\x64\xdc\x46\xe0\xba\x2f\xca\x34\x4d\x86\xd4\xbc\x2e\xf2\x53\x2c",
+ 144 },
+ { GCRY_MD_SHA3_512,
+ "\x83\x6b\x34\xb5\x15\x47\x6f\x61\x3f\xe4\x47\xa4\xe0\xc3\xf3\xb8\xf2\x09\x10\xac\x89\xa3\x97\x70\x55\xc9\x60\xd2\xd5\xd2\xb7\x2b\xd8\xac\xc7\x15\xa9\x03\x53\x21\xb8\x67\x03\xa4\x11\xdd\xe0\x46\x6d\x58\xa5\x97\x69\x67\x2a\xa6\x0a\xd5\x87\xb8\x48\x1d\xe4\xbb\xa5\x52\xa1\x64\x57\x79\x78\x95\x01\xec\x53\xd5\x40\xb9\x04\x82\x1f\x32\xb0\xbd\x18\x55\xb0\x4e\x48\x48\xf9\xf8\xcf\xe9\xeb\xd8\x91\x1b\xe9\x57\x81\xa7\x59\xd7\xad\x97\x24\xa7\x10\x2d\xbe\x57\x67\x76\xb7\xc6\x32\xbc\x39\xb9\xb5\xe1\x90\x57\xe2\x26\x55\x2a\x59\x94\xc1\xdb\xb3\xb5\xc7\x87\x1a\x11\xf5\x53\x70\x11\x04\x4c\x53",
+ "\xaf\xf6\x1c\x6e\x11\xb9\x8e\x55\xac\x21\x3b\x1a\x0b\xc7\xde\x04\x05\x22\x1a\xc5\xef\xb1\x22\x98\x42\xe4\x61\x4f\x4a\x02\x9c\x9b\xd1\x4a\x0e\xd7\xfd\x99\xaf\x36\x81\x42\x9f\x3f\x30\x9f\xdb\x53\x16\x6a\xa9\xa3\xcd\x9f\x1f\x12\x23\xd0\x4b\x4a\x90\x15\xe9\x4a",
+ 145 },
+ { GCRY_MD_SHA3_512,
+ "\xcc\x77\x84\xa4\x91\x2a\x7a\xb5\xad\x36\x20\xaa\xb2\x9b\xa8\x70\x77\xcd\x3c\xb8\x36\x36\xad\xc9\xf3\xdc\x94\xf5\x1e\xdf\x52\x1b\x21\x61\xef\x10\x8f\x21\xa0\xa2\x98\x55\x79\x81\xc0\xe5\x3c\xe6\xce\xd4\x5b\xdf\x78\x2c\x1e\xf2\x00\xd2\x9b\xab\x81\xdd\x64\x60\x58\x69\x64\xed\xab\x7c\xeb\xdb\xbe\xc7\x5f\xd7\x92\x50\x60\xf7\xda\x2b\x85\x3b\x2b\x08\x95\x88\xfa\x0f\x8c\x16\xec\x64\x98\xb1\x4c\x55\xdc\xee\x33\x5c\xb3\xa9\x1d\x69\x8e\x4d\x39\x3a\xb8\xe8\xea\xc0\x82\x5f\x8a\xde\xbe\xee\x19\x6d\xf4\x12\x05\xc0\x11\x67\x4e\x53\x42\x6c\xaa\x45\x3f\x8d\xe1\xcb\xb5\x79\x32\xb0\xb7\x41\xd4\xc6",
+ "\x26\x41\x0e\x1a\x0d\x1e\x36\x59\x43\x8d\xdd\xb2\x95\x3e\xb3\xaa\x08\x2c\xeb\x02\xa3\x27\xfa\x00\x98\x57\x4d\x89\xf9\x23\x6f\x5d\xff\x9c\x17\xde\xf3\x7f\x6c\xe4\xb5\xdc\x1e\xe5\xf2\x3f\x57\x8f\xe1\x91\xee\x8b\x51\xf1\xb8\x03\x4b\xcb\xbb\xb7\xb6\xa5\x00\xa5",
+ 146 },
+ { GCRY_MD_SHA3_512,
+ "\x76\x39\xb4\x61\xff\xf2\x70\xb2\x45\x5a\xc1\xd1\xaf\xce\x78\x29\x44\xae\xa5\xe9\x08\x7e\xb4\xa3\x9e\xb9\x6b\xb5\xc3\xba\xaf\x0e\x86\x8c\x85\x26\xd3\x40\x4f\x94\x05\xe7\x9e\x77\xbf\xac\x5f\xfb\x89\xbf\x19\x57\xb5\x23\xe1\x7d\x34\x1d\x73\x23\xc3\x02\xea\x70\x83\x87\x2d\xd5\xe8\x70\x56\x94\xac\xdd\xa3\x6d\x5a\x1b\x89\x5a\xaa\x16\xec\xa6\x10\x4c\x82\x68\x85\x32\xc8\xbf\xe1\x79\x0b\x5d\xc9\xf4\xec\x5f\xe9\x5b\xae\xd3\x7e\x1d\x28\x7b\xe7\x10\x43\x1f\x1e\x5e\x8e\xe1\x05\xbc\x42\xed\x37\xd7\x4b\x1e\x55\x98\x4b\xf1\xc0\x9f\xe6\xa1\xfa\x13\xef\x3b\x96\xfa\xea\xed\x6a\x2a\x19\x50\xa1\x21\x53",
+ "\x50\x15\xda\x2a\x2e\x16\x61\xd3\xa5\x2a\x65\xd1\x9f\x02\x93\x30\x29\x83\x9f\x72\x71\x7a\x77\xb5\x04\x51\x98\x66\x50\x93\xf9\x44\xcf\xf8\x5e\x09\x4d\x41\x83\x96\xa5\x1c\x57\x41\x57\xee\xd9\xfb\x6b\xdd\x4e\xca\x53\x27\x8f\xab\x62\xaf\x69\x9b\x53\xc8\x2f\x58",
+ 147 },
+ { GCRY_MD_SHA3_512,
+ "\xeb\x65\x13\xfc\x61\xb3\x0c\xfb\xa5\x8d\x4d\x7e\x80\xf9\x4d\x14\x58\x90\x90\xcf\x1d\x80\xb1\xdf\x2e\x68\x08\x8d\xc6\x10\x49\x59\xba\x0d\x58\x3d\x58\x5e\x95\x78\xab\x0a\xec\x0c\xf3\x6c\x48\x43\x5e\xb5\x2e\xd9\xab\x4b\xbc\xe7\xa5\xab\xe6\x79\xc9\x7a\xe2\xdb\xe3\x5e\x8c\xc1\xd4\x5b\x06\xdd\xa3\xcf\x41\x86\x65\xc5\x7c\xbe\xe4\xbb\xb4\x7f\xa4\xca\xf7\x8f\x4e\xe6\x56\xfe\xc2\x37\xfe\x4e\xeb\xba\xfa\x20\x6e\x1e\xf2\xbd\x0e\xe4\xae\x71\xbd\x0e\x9b\x2f\x54\xf9\x1d\xaa\xdf\x1f\xeb\xfd\x70\x32\x38\x1d\x63\x6b\x73\x3d\xcb\x3b\xf7\x6f\xb1\x4e\x23\xaf\xf1\xf6\x8e\xd3\xdb\xcf\x75\xc9\xb9\x9c\x6f\x26",
+ "\xb2\x78\x28\xcf\xeb\xcf\x4d\x89\x6e\xab\xf1\xf8\x4d\x07\x98\x27\xb7\xdc\xc7\xf3\x08\xa2\x04\x76\x47\x4d\xe5\x18\x82\x9a\x89\xaa\xc3\xdc\x50\x27\x2c\xfa\x97\x6b\x0b\x58\x19\xc4\x5c\x9e\xef\xc5\x1b\x87\xa2\x7d\x11\xc9\xe5\xf9\x57\x91\x21\x12\x5a\x88\x75\x42",
+ 148 },
+ { GCRY_MD_SHA3_512,
+ "\x15\x94\xd7\x4b\xf5\xdd\xe4\x44\x26\x5d\x4c\x04\xda\xd9\x72\x1f\xf3\xe3\x4c\xbf\x62\x2d\xaf\x34\x1f\xe1\x6b\x96\x43\x1f\x6c\x4d\xf1\xf7\x60\xd3\x4f\x29\x6e\xb9\x7d\x98\xd5\x60\xad\x52\x86\xfe\xc4\xdc\xe1\x72\x4f\x20\xb5\x4f\xd7\xdf\x51\xd4\xbf\x13\x7a\xdd\x65\x6c\x80\x54\x6f\xb1\xbf\x51\x6d\x62\xee\x82\xba\xa9\x92\x91\x0e\xf4\xcc\x18\xb7\x0f\x3f\x86\x98\x27\x6f\xcf\xb4\x4e\x0e\xc5\x46\xc2\xc3\x9c\xfd\x8e\xe9\x10\x34\xff\x93\x03\x05\x8b\x42\x52\x46\x2f\x86\xc8\x23\xeb\x15\xbf\x48\x1e\x6b\x79\xcc\x3a\x02\x21\x85\x95\xb3\x65\x8e\x8b\x37\x38\x2b\xd5\x04\x8e\xae\xd5\xfd\x02\xc3\x79\x44\xe7\x3b",
+ "\x42\xfc\x06\xdc\xf9\x9b\x4e\x80\x4b\xb3\x49\x10\x1b\x46\xd6\xa6\xa7\x36\x6e\x47\x55\x54\x06\xea\x55\x42\x48\xba\xef\x52\xe1\x7a\xfa\x40\x82\x9f\x57\x09\xd0\x7f\xf4\x07\x88\x1d\xf1\x06\xf1\x56\xca\x73\x56\x22\xb0\xf0\x51\xd8\xc3\x72\xf6\xe8\x11\xcd\xae\x25",
+ 149 },
+ { GCRY_MD_SHA3_512,
+ "\x4c\xfa\x12\x78\x90\x30\x26\xf6\x6f\xed\xd4\x13\x74\x55\x8b\xe1\xb5\x85\xd0\x3c\x5c\x55\xda\xc9\x43\x61\xdf\x28\x6d\x4b\xd3\x9c\x7c\xb8\x03\x7e\xd3\xb2\x67\xb0\x7c\x34\x66\x26\x44\x9d\x0c\xc5\xb0\xdd\x2c\xf2\x21\xf7\xe4\xc3\x44\x9a\x4b\xe9\x99\x85\xd2\xd5\xe6\x7b\xff\x29\x23\x35\x7d\xde\xab\x5a\xbc\xb4\x61\x9f\x3a\x3a\x57\xb2\xcf\x92\x8a\x02\x2e\xb2\x76\x76\xc6\xcf\x80\x56\x89\x00\x4f\xca\x4d\x41\xea\x6c\x2d\x0a\x47\x89\xc7\x60\x5f\x7b\xb8\x38\xdd\x88\x3b\x3a\xd3\xe6\x02\x7e\x77\x5b\xcf\x26\x28\x81\x42\x80\x99\xc7\xff\xf9\x5b\x14\xc0\x95\xea\x13\x0e\x0b\x99\x38\xa5\xe2\x2f\xc5\x26\x50\xf5\x91",
+ "\x0c\xa8\x9c\x9b\x72\x73\xde\x38\x4f\xf3\x3f\x1b\xac\xbb\x85\x05\x62\x8c\x4d\x3e\x30\x35\x0b\x33\x53\x61\x56\x3a\xd4\x16\xad\xa5\x23\x12\x2d\x37\xac\xbe\xc5\x77\x21\xf7\xbc\x5d\x9b\x04\x9e\x1f\x4f\xe3\xc4\xcf\xe0\x47\xe3\x3a\x0e\x44\x8e\xf5\xd5\x53\x6c\xf0",
+ 150 },
+ { GCRY_MD_SHA3_512,
+ "\xd3\xe6\x5c\xb9\x2c\xfa\x79\x66\x2f\x6a\xf4\x93\xd6\x96\xa0\x7c\xcf\x32\xaa\xad\xcc\xef\xf0\x6e\x73\xe8\xd9\xf6\xf9\x09\x20\x9e\x66\x71\x5d\x6e\x97\x87\x88\xc4\x9e\xfb\x90\x87\xb1\x70\xec\xf3\xaa\x86\xd2\xd4\xd1\xa0\x65\xae\x0e\xfc\x89\x24\xf3\x65\xd6\x76\xb3\xcb\x9e\x2b\xec\x91\x8f\xd9\x6d\x0b\x43\xde\xe8\x37\x27\xc9\xa9\x3b\xf5\x6c\xa2\xb2\xe5\x9a\xdb\xa8\x56\x96\x54\x6a\x81\x50\x67\xfc\x7a\x78\x03\x96\x29\xd4\x94\x8d\x15\x7e\x7b\x0d\x82\x6d\x1b\xf8\xe8\x12\x37\xba\xb7\x32\x13\x12\xfd\xaa\x4d\x52\x17\x44\xf9\x88\xdb\x6f\xdf\x04\x54\x9d\x0f\xdc\xa3\x93\xd6\x39\xc7\x29\xaf\x71\x6e\x9c\x8b\xba\x48",
+ "\x78\xc5\x9a\x8c\xdf\x4d\x1d\x07\xa6\x6b\xb2\xfa\xa7\xff\xa2\x11\x2d\x5c\x0f\xca\xbf\x7e\x35\x89\xe9\x76\x23\xbd\xb9\x22\xaf\x9a\xf2\x49\x18\xc2\xcc\xfc\xe2\xb8\x80\xbf\x64\x14\x5c\x70\xdc\x9a\x4f\xde\x78\xfd\xf0\x91\x8d\xd2\xce\x5f\xea\x9c\xf9\x9a\xcd\x41",
+ 151 },
+ { GCRY_MD_SHA3_512,
+ "\x84\x2c\xc5\x83\x50\x45\x39\x62\x2d\x7f\x71\xe7\xe3\x18\x63\xa2\xb8\x85\xc5\x6a\x0b\xa6\x2d\xb4\xc2\xa3\xf2\xfd\x12\xe7\x96\x60\xdc\x72\x05\xca\x29\xa0\xdc\x0a\x87\xdb\x4d\xc6\x2e\xe4\x7a\x41\xdb\x36\xb9\xdd\xb3\x29\x3b\x9a\xc4\xba\xae\x7d\xf5\xc6\xe7\x20\x1e\x17\xf7\x17\xab\x56\xe1\x2c\xad\x47\x6b\xe4\x96\x08\xad\x2d\x50\x30\x9e\x7d\x48\xd2\xd8\xde\x4f\xa5\x8a\xc3\xcf\xea\xfe\xee\x48\xc0\xa9\xee\xc8\x84\x98\xe3\xef\xc5\x1f\x54\xd3\x00\xd8\x28\xdd\xdc\xcb\x9d\x0b\x06\xdd\x02\x1a\x29\xcf\x5c\xb5\xb2\x50\x69\x15\xbe\xb8\xa1\x19\x98\xb8\xb8\x86\xe0\xf9\xb7\xa8\x0e\x97\xd9\x1a\x7d\x01\x27\x0f\x9a\x77\x17",
+ "\xcf\x4d\x52\xd2\x02\x72\xde\x01\x4d\x36\x73\x10\x77\x52\x87\xee\x5e\x5c\xb3\x4c\xf9\xaf\x78\xe6\x5d\x1d\x1f\xe7\xfb\x1f\x13\xb6\x2d\xd9\xb8\x3c\x38\x2b\xaa\x6a\xb4\xf6\x94\x94\x78\xc8\x59\x8f\xef\x78\xe8\xd5\x35\x31\x1f\xc1\x98\x08\xcb\x75\xe2\x2d\xad\xed",
+ 152 },
+ { GCRY_MD_SHA3_512,
+ "\x6c\x4b\x0a\x07\x19\x57\x3e\x57\x24\x86\x61\xe9\x8f\xeb\xe3\x26\x57\x1f\x9a\x1c\xa8\x13\xd3\x63\x85\x31\xae\x28\xb4\x86\x0f\x23\xc3\xa3\xa8\xac\x1c\x25\x00\x34\xa6\x60\xe2\xd7\x1e\x16\xd3\xac\xc4\xbf\x9c\xe2\x15\xc6\xf1\x5b\x1c\x0f\xc7\xe7\x7d\x3d\x27\x15\x7e\x66\xda\x9c\xee\xc9\x25\x8f\x8f\x2b\xf9\xe0\x2b\x4a\xc9\x37\x93\xdd\x6e\x29\xe3\x07\xed\xe3\x69\x5a\x0d\xf6\x3c\xbd\xc0\xfc\x66\xfb\x77\x08\x13\xeb\x14\x9c\xa2\xa9\x16\x91\x1b\xee\x49\x02\xc4\x7c\x78\x02\xe6\x9e\x40\x5f\xe3\xc0\x4c\xeb\x55\x22\x79\x2a\x55\x03\xfa\x82\x9f\x70\x72\x72\x22\x66\x21\xf7\xc4\x88\xa7\x69\x8c\x0d\x69\xaa\x56\x1b\xe9\xf3\x78",
+ "\x33\xd6\x32\xe4\x03\xc9\xf9\xa9\x34\x9b\x28\xaa\x48\x21\xa1\x2b\x1d\xb5\x57\xd8\x92\x80\x03\xd3\x0c\x57\xd7\x01\xcf\xf1\xc4\x9b\xac\x94\x72\xce\xcf\xf4\x50\xe4\xd9\x1d\x36\xc6\xcd\x78\x22\x17\x90\xef\xf6\xf0\xfb\xf4\x98\x03\x40\x14\xcb\xba\xce\x5d\xcf\x09",
+ 153 },
+ { GCRY_MD_SHA3_512,
+ "\x51\xb7\xdb\xb7\xce\x2f\xfe\xb4\x27\xa9\x1c\xcf\xe5\x21\x8f\xd4\x0f\x9e\x0b\x7e\x24\x75\x6d\x4c\x47\xcd\x55\x60\x60\x08\xbd\xc2\x7d\x16\x40\x09\x33\x90\x6f\xd9\xf3\x0e\xff\xdd\x48\x80\x02\x2d\x08\x11\x55\x34\x2a\xf3\xfb\x6c\xd5\x36\x72\xab\x7f\xb5\xb3\xa3\xbc\xbe\x47\xbe\x1f\xd3\xa2\x27\x8c\xae\x8a\x5f\xd6\x1c\x14\x33\xf7\xd3\x50\x67\x5d\xd2\x18\x03\x74\x6c\xad\xca\x57\x41\x30\xf0\x12\x00\x02\x4c\x63\x40\xab\x0c\xc2\xcf\x74\xf2\x23\x46\x69\xf3\x4e\x90\x09\xef\x2e\xb9\x48\x23\xd6\x2b\x31\x40\x7f\x4b\xa4\x6f\x1a\x1e\xec\x41\x64\x1e\x84\xd7\x77\x27\xb5\x9e\x74\x6b\x8a\x67\x1b\xef\x93\x6f\x05\xbe\x82\x07\x59\xfa",
+ "\x95\x4c\x70\x9a\xbc\xb0\xbb\x88\x15\x92\xd9\x3f\x5c\x24\x63\xce\x8c\x06\x0a\xd1\xdf\x30\x53\x30\x2e\xa7\xb1\x9f\x2b\x47\xbc\xf0\xfe\x35\x9a\x83\x2f\x9a\x86\x5a\x8d\x3d\xbd\x3b\xe5\x98\xdf\xd6\xd0\xfc\x1c\x57\x4e\xca\x0a\xec\x78\xd8\xe3\x28\x83\x99\xbe\x05",
+ 154 },
+ { GCRY_MD_SHA3_512,
+ "\x83\x59\x9d\x93\xf5\x56\x1e\x82\x1b\xd0\x1a\x47\x23\x86\xbc\x2f\xf4\xef\xbd\x4a\xed\x60\xd5\x82\x1e\x84\xaa\xe7\x4d\x80\x71\x02\x98\x10\xf5\xe2\x86\xf8\xf1\x76\x51\xcd\x27\xda\x07\xb1\xeb\x43\x82\xf7\x54\xcd\x1c\x95\x26\x87\x83\xad\x09\x22\x0f\x55\x02\x84\x03\x70\xd4\x94\xbe\xb1\x71\x24\x22\x0f\x6a\xfc\xe9\x1e\xc8\xa0\xf5\x52\x31\xf9\x65\x24\x33\xe5\xce\x34\x89\xb7\x27\x71\x6c\xf4\xae\xba\x7d\xcd\xa2\x0c\xd2\x9a\xa9\xa8\x59\x20\x12\x53\xf9\x48\xdd\x94\x39\x5a\xba\x9e\x38\x52\xbd\x1d\x60\xdd\xa7\xae\x5d\xc0\x45\xb2\x83\xda\x00\x6e\x1c\xba\xd8\x3c\xc1\x32\x92\xa3\x15\xdb\x55\x53\x30\x5c\x62\x8d\xd0\x91\x14\x65\x97",
+ "\xa3\x37\x06\x2f\x5e\x5c\x9c\x35\x34\x1a\x51\x22\x4f\x2a\x59\xe6\xcf\x91\x9a\x63\xbf\x59\xa6\xcf\xce\x26\x11\x94\xbb\xd6\x60\xf2\x8c\x29\x48\xd0\x3c\xdc\xe5\xc7\xc1\x51\xec\x05\xb4\x2a\xad\xd8\x30\x51\xa1\x6a\x62\xf0\xc7\xdf\x39\xaa\xa4\xef\xc8\x2c\xe4\xd3",
+ 155 },
+ { GCRY_MD_SHA3_512,
+ "\x2b\xe9\xbf\x52\x6c\x9d\x5a\x75\xd5\x65\xdd\x11\xef\x63\xb9\x79\xd0\x68\x65\x9c\x7f\x02\x6c\x08\xbe\xa4\xaf\x16\x1d\x85\xa4\x62\xd8\x0e\x45\x04\x0e\x91\xf4\x16\x5c\x07\x4c\x43\xac\x66\x13\x80\x31\x1a\x8c\xbe\xd5\x9c\xc8\xe4\xc4\x51\x8e\x80\xcd\x2c\x78\xab\x1c\xab\xf6\x6b\xff\x83\xea\xb3\xa8\x01\x48\x55\x03\x07\x31\x09\x50\xd0\x34\xa6\x28\x6c\x93\xa1\xec\xe8\x92\x9e\x63\x85\xc5\xe3\xbb\x6e\xa8\xa7\xc0\xfb\x6d\x63\x32\xe3\x20\xe7\x1c\xc4\xeb\x46\x2a\x2a\x62\xe2\xbf\xe0\x8f\x0c\xca\xd9\x3e\x61\xbe\xdb\x5d\xd0\xb7\x86\xa7\x28\xab\x66\x6f\x07\xe0\x57\x6d\x18\x9c\x92\xbf\x9f\xb2\x0d\xca\x49\xac\x2d\x39\x56\xd4\x73\x85\xe2",
+ "\x43\xe9\xd0\xea\x8e\x52\x6e\x83\x23\x4d\x7b\x63\xd8\x24\x4c\x7e\x7b\x12\xae\x2a\xcc\x80\x82\xf9\x86\x36\x72\x68\xf1\x01\x56\x57\x43\x00\x17\x28\x73\x84\x5b\x20\x7a\x72\x52\x62\x42\x46\xe7\xd3\x2c\xe0\xf7\x28\x2e\x00\xc4\x55\x2f\x61\x80\xf3\x4e\x59\x0e\x2e",
+ 156 },
+ { GCRY_MD_SHA3_512,
+ "\xca\x76\xd3\xa1\x25\x95\xa8\x17\x68\x26\x17\x00\x68\x48\x67\x55\x47\xd3\xe8\xf5\x0c\x22\x10\xf9\xaf\x90\x6c\x0e\x7c\xe5\x0b\x44\x60\x18\x6f\xe7\x04\x57\xa9\xe8\x79\xe7\x9f\xd4\xd1\xa6\x88\xc7\x0a\x34\x73\x61\xc8\x47\xba\x0d\xd6\xaa\x52\x93\x6e\xaf\x8e\x58\xa1\xbe\x2f\x5c\x1c\x70\x4e\x20\x14\x6d\x36\x6a\xeb\x38\x53\xbe\xd9\xde\x9b\xef\xe9\x56\x9a\xc8\xaa\xea\x37\xa9\xfb\x71\x39\xa1\xa1\xa7\xd5\xc7\x48\x60\x5a\x8d\xef\xb2\x97\x86\x9e\xbe\xdd\x71\xd6\x15\xa5\xda\x23\x49\x6d\x11\xe1\x1a\xbb\xb1\x26\xb2\x06\xfa\x0a\x77\x97\xee\x7d\xe1\x17\x98\x60\x12\xd0\x36\x2d\xce\xf7\x75\xc2\xfe\x14\x5a\xda\x6b\xda\x1c\xcb\x32\x6b\xf6\x44",
+ "\xf7\xda\x8d\x1e\x49\xd0\xd9\x64\x40\x0e\xe4\x0f\x9c\x88\xe0\x70\x25\xa8\xb0\xb0\x0c\xad\xc6\x24\xa6\x3e\x2e\xa8\x5b\x15\x98\xe2\x2c\x88\x02\xbe\x0c\x1f\xf3\x68\x51\x95\x49\xa7\x52\xe0\x25\x46\x09\x3d\x3b\x98\x4e\x24\x60\x0b\xa2\xab\x7c\x79\x2b\x9e\x07\x4a",
+ 157 },
+ { GCRY_MD_SHA3_512,
+ "\xf7\x6b\x85\xdc\x67\x42\x10\x25\xd6\x4e\x93\x09\x6d\x1d\x71\x2b\x7b\xaf\x7f\xb0\x01\x71\x6f\x02\xd3\x3b\x21\x60\xc2\xc8\x82\xc3\x10\xef\x13\xa5\x76\xb1\xc2\xd3\x0e\xf8\xf7\x8e\xf8\xd2\xf4\x65\x00\x71\x09\xaa\xd9\x3f\x74\xcb\x9e\x7d\x7b\xef\x7c\x95\x90\xe8\xaf\x3b\x26\x7c\x89\xc1\x5d\xb2\x38\x13\x8c\x45\x83\x3c\x98\xcc\x4a\x47\x1a\x78\x02\x72\x3e\xf4\xc7\x44\xa8\x53\xcf\x80\xa0\xc2\x56\x8d\xd4\xed\x58\xa2\xc9\x64\x48\x06\xf4\x21\x04\xce\xe5\x36\x28\xe5\xbd\xf7\xb6\x3b\x0b\x33\x8e\x93\x1e\x31\xb8\x7c\x24\xb1\x46\xc6\xd0\x40\x60\x55\x67\xce\xef\x59\x60\xdf\x9e\x02\x2c\xb4\x69\xd4\xc7\x87\xf4\xcb\xa3\xc5\x44\xa1\xac\x91\xf9\x5f",
+ "\xd9\xa4\x27\x61\xf9\x80\xc7\x8c\x36\xcf\x54\xc4\x20\x7b\x0a\x62\x95\x4e\x15\xa9\x07\xa7\xce\xa1\x49\xb3\x7a\x4e\x0a\x63\x76\x20\x2f\xf8\xf1\x2e\x16\xeb\xad\x3a\xec\xc7\xff\x3a\x9d\x6a\xd0\x93\xb0\x68\xdf\xe2\x72\xe3\xb9\x64\x6b\x1a\xed\xc0\x49\x61\xdc\x81",
+ 158 },
+ { GCRY_MD_SHA3_512,
+ "\x25\xb8\xc9\xc0\x32\xea\x6b\xcd\x73\x3f\xfc\x87\x18\xfb\xb2\xa5\x03\xa4\xea\x8f\x71\xde\xa1\x17\x61\x89\xf6\x94\x30\x4f\x0f\xf6\x8e\x86\x2a\x81\x97\xb8\x39\x95\x75\x49\xef\x24\x3a\x52\x79\xfc\x26\x46\xbd\x4c\x00\x9b\x6d\x1e\xde\xbf\x24\x73\x81\x97\xab\xb4\xc9\x92\xf6\xb1\xdc\x9b\xa8\x91\xf5\x70\x87\x9a\xcc\xd5\xa6\xb1\x86\x91\xa9\x3c\x7d\x0a\x8d\x38\xf9\x5b\x63\x9c\x1d\xae\xb4\x8c\x4c\x2f\x15\xcc\xf5\xb9\xd5\x08\xf8\x33\x3c\x32\xde\x78\x78\x1b\x41\x85\x0f\x26\x1b\x85\x5c\x4b\xeb\xcc\x12\x5a\x38\x0c\x54\xd5\x01\xc5\xd3\xbd\x07\xe6\xb5\x21\x02\x11\x60\x88\xe5\x3d\x76\x58\x3b\x01\x61\xe2\xa5\x8d\x07\x78\xf0\x91\x20\x6a\xab\xd5\xa1",
+ "\xbb\x65\xd8\x94\x34\x13\xce\xf8\x9f\xdb\x05\xb3\x5a\x55\xec\x75\x03\xe4\x54\x6a\x50\xfc\x3e\xcc\x82\x5d\xab\xc1\xa1\xda\xe6\xc7\x71\xbb\x19\x7f\x32\x36\x25\x87\x7e\x0b\xcc\xaa\x41\x25\x3c\x99\xb6\x69\x29\x76\xb9\x9f\xc6\x87\xb0\xb6\xb3\xe9\xaa\xb4\x78\xc4",
+ 159 },
+ { GCRY_MD_SHA3_512,
+ "\x21\xcf\xdc\x2a\x7c\xcb\x7f\x33\x1b\x3d\x2e\xef\xff\x37\xe4\x8a\xd9\xfa\x9c\x78\x8c\x3f\x3c\x20\x0e\x01\x73\xd9\x99\x63\xe1\xcb\xca\x93\x62\x3b\x26\x4e\x92\x03\x94\xae\x48\xbb\x4c\x3a\x5b\xb9\x6f\xfb\xc8\xf0\xe5\x3f\x30\xe2\x29\x56\xad\xab\xc2\x76\x5f\x57\xfb\x76\x1e\x14\x7e\xcb\xf8\x56\x75\x33\xdb\x6e\x50\xc8\xa1\xf8\x94\x31\x0a\x94\xed\xf8\x06\xdd\x8c\xa6\xa0\xe1\x41\xc0\xfa\x7c\x9f\xae\x6c\x6a\xe6\x5f\x18\xc9\x3a\x85\x29\xe6\xe5\xb5\x53\xbf\x55\xf2\x5b\xe2\xe8\x0a\x98\x82\xbd\x37\xf1\x45\xfe\xcb\xeb\x3d\x44\x7a\x3c\x4e\x46\xc2\x15\x24\xcc\x55\xcd\xd6\x2f\x52\x1a\xb9\x2a\x8b\xa7\x2b\x89\x79\x96\xc4\x9b\xb2\x73\x19\x8b\x7b\x1c\x9e",
+ "\x54\x0d\xf2\x21\x80\xb6\x9b\x9a\x83\x30\x66\x19\xb2\xca\x8c\xd8\xe0\x7a\x34\xbb\xeb\x22\x19\xac\x7c\xf8\x8b\x46\x8a\x94\x7c\x44\x48\x48\x9b\x30\x3b\xd6\x55\x06\xc9\xe1\xce\x59\x34\x8a\x9d\x86\x3a\xab\x51\x54\x84\x8e\x95\xb5\x38\x97\x83\xf6\xf5\xfb\x6a\xd8",
+ 160 },
+ { GCRY_MD_SHA3_512,
+ "\x4e\x45\x2b\xa4\x21\x27\xdc\xc9\x56\xef\x4f\x8f\x35\xdd\x68\xcb\x22\x5f\xb7\x3b\x5b\xc7\xe1\xec\x5a\x89\x8b\xba\x29\x31\x56\x3e\x74\xfa\xff\x3b\x67\x31\x4f\x24\x1e\xc4\x9f\x4a\x70\x61\xe3\xbd\x02\x13\xae\x82\x6b\xab\x38\x0f\x1f\x14\xfa\xab\x8b\x0e\xfd\xdd\x5f\xd1\xbb\x49\x37\x38\x53\xa0\x8f\x30\x55\x3d\x5a\x55\xcc\xbb\xb8\x15\x3d\xe4\x70\x4f\x29\xca\x2b\xde\xef\x04\x19\x46\x8e\x05\xdd\x51\x55\x7c\xcc\x80\xc0\xa9\x61\x90\xbb\xcc\x4d\x77\xec\xff\x21\xc6\x6b\xdf\x48\x64\x59\xd4\x27\xf9\x86\x41\x0f\x88\x3a\x80\xa5\xbc\xc3\x2c\x20\xf0\x47\x8b\xb9\xa9\x7a\x12\x6f\xc5\xf9\x54\x51\xe4\x0f\x29\x2a\x46\x14\x93\x0d\x05\x4c\x85\x1a\xcd\x01\x9c\xcf",
+ "\x06\x2e\x4a\x11\xa7\x9f\xdb\x9c\xbc\x3a\x0e\x4c\x5f\x98\x75\xca\xaa\x56\x8b\xc7\x13\x06\x6e\x02\xd2\xa9\xca\x4d\x27\x88\x6c\xe2\x3f\x70\x08\x3a\x2b\xf4\xd0\xe7\xc5\x5b\x12\x0f\xe6\xd1\x97\x20\x3d\xc1\xc2\xfd\x34\x69\x11\x2a\x08\x83\x67\x27\x85\x9e\x1f\x83",
+ 161 },
+ { GCRY_MD_SHA3_512,
+ "\xfa\x85\x67\x1d\xf7\xda\xdf\x99\xa6\xff\xee\x97\xa3\xab\x99\x91\x67\x1f\x56\x29\x19\x50\x49\x88\x04\x97\x48\x78\x67\xa6\xc4\x46\xb6\x00\x87\xfa\xc9\xa0\xf2\xfc\xc8\xe3\xb2\x4e\x97\xe4\x23\x45\xb9\x3b\x5f\x7d\x36\x91\x82\x9d\x3f\x8c\xcd\x4b\xb3\x64\x11\xb8\x5f\xc2\x32\x8e\xb0\xc5\x1c\xb3\x15\x1f\x70\x86\x0a\xd3\x24\x6c\xe0\x62\x3a\x8d\xc8\xb3\xc4\x9f\x95\x8f\x86\x90\xf8\xe3\x86\x0e\x71\xeb\x2b\x14\x79\xa5\xce\xa0\xb3\xf8\xbe\xfd\x87\xac\xaf\x53\x62\x43\x5e\xae\xcc\xb5\x2f\x38\x61\x7b\xc6\xc5\xc2\xc6\xe2\x69\xea\xd1\xfb\xd6\x9e\x94\x1d\x4a\xd2\x01\x2d\xa2\xc5\xb2\x1b\xcf\xbf\x98\xe4\xa7\x7a\xb2\xaf\x1f\x3f\xda\x32\x33\xf0\x46\xd3\x8f\x1d\xc8",
+ "\x9e\x1c\x6e\xe0\xc4\x7b\x2d\x2c\xb7\x7f\x60\x2c\xab\x53\xac\x4c\x69\xc6\x97\x78\x29\x78\x94\x55\x41\x96\xcb\x58\x06\x03\x32\xc9\xfd\x89\x23\xf4\x5c\x4b\x8e\xc2\x6e\x16\xa5\xd0\x4e\x63\x07\xfb\x99\x85\x0a\x45\x40\xea\x83\xe3\xf2\x62\x6f\x33\x43\xe9\x72\x25",
+ 162 },
+ { GCRY_MD_SHA3_512,
+ "\xe9\x08\x47\xae\x67\x97\xfb\xc0\xb6\xb3\x6d\x6e\x58\x8c\x0a\x74\x3d\x72\x57\x88\xca\x50\xb6\xd7\x92\x35\x2e\xa8\x29\x4f\x5b\xa6\x54\xa1\x53\x66\xb8\xe1\xb2\x88\xd8\x4f\x51\x78\x24\x08\x27\x97\x5a\x76\x3b\xc4\x5c\x7b\x04\x30\xe8\xa5\x59\xdf\x44\x88\x50\x5e\x00\x9c\x63\xda\x99\x4f\x14\x03\xf4\x07\x95\x82\x03\xce\xbb\x6e\x37\xd8\x9c\x94\xa5\xea\xcf\x60\x39\xa3\x27\xf6\xc4\xdb\xbc\x7a\x2a\x30\x7d\x97\x6a\xa3\x9e\x41\xaf\x65\x37\x24\x3f\xc2\x18\xdf\xa6\xab\x4d\xd8\x17\xb6\xa3\x97\xdf\x5c\xa6\x91\x07\xa9\x19\x87\x99\xed\x24\x86\x41\xb6\x3b\x42\xcb\x4c\x29\xbf\xdd\x79\x75\xac\x96\xed\xfc\x27\x4a\xc5\x62\xd0\x47\x4c\x60\x34\x7a\x07\x8c\xe4\xc2\x5e\x88",
+ "\xf1\x8f\x0b\x07\x2a\x6b\xf6\x08\xa6\xc7\x42\x0e\x89\x1b\xe3\x79\x5a\x6d\x19\xba\x3e\x12\x76\xc8\x26\xf1\xae\x77\x5c\xf1\x25\xe4\x28\xae\x1a\x39\x7c\xfd\x07\x4b\xe0\xcd\x24\xf7\x10\x0f\x51\x80\x0f\x14\x47\x1c\xcf\x4f\x48\x5a\x65\x71\xe2\xb3\x2e\x02\x61\x1f",
+ 163 },
+ { GCRY_MD_SHA3_512,
+ "\xf6\xd5\xc2\xb6\xc9\x39\x54\xfc\x62\x76\x02\xc0\x0c\x4c\xa9\xa7\xd3\xed\x12\xb2\x71\x73\xf0\xb2\xc9\xb0\xe4\xa5\x93\x93\x98\xa6\x65\xe6\x7e\x69\xd0\xb1\x2f\xb7\xe4\xce\xb2\x53\xe8\x08\x3d\x1c\xeb\x72\x4a\xc0\x7f\x00\x9f\x09\x4e\x42\xf2\xd6\xf2\x12\x94\x89\xe8\x46\xea\xff\x07\x00\xa8\xd4\x45\x3e\xf4\x53\xa3\xed\xdc\x18\xf4\x08\xc7\x7a\x83\x27\x56\x17\xfa\xbc\x4e\xa3\xa2\x83\x3a\xa7\x34\x06\xc0\xe9\x66\x27\x60\x79\xd3\x8e\x8e\x38\x53\x9a\x70\xe1\x94\xcc\x55\x13\xaa\xa4\x57\xc6\x99\x38\x3f\xd1\x90\x0b\x1e\x72\xbd\xfb\x83\x5d\x1f\xd3\x21\xb3\x7b\xa8\x05\x49\xb0\x78\xa4\x9e\xa0\x81\x52\x86\x9a\x91\x8c\xa5\x7f\x5b\x54\xed\x71\xe4\xfd\x3a\xc5\xc0\x67\x29",
+ "\x28\x59\xa3\x16\x5f\x38\xcb\x59\xde\x42\x75\x65\x8b\xba\xe9\xa0\xad\x64\x7d\x97\x2c\xf9\x8f\xa0\xee\xc4\xc0\x7e\xe7\x5d\x57\x6d\xbf\x9f\x5d\xd1\x9a\x88\x1d\xb4\xe4\xf7\xdb\x31\xec\x0d\x77\x16\x59\x11\x32\x9c\xbe\x8a\x46\xd1\x4d\x3e\xa7\xfd\xcb\x8a\x5c\x80",
+ 164 },
+ { GCRY_MD_SHA3_512,
+ "\xcf\x85\x62\xb1\xbe\xd8\x98\x92\xd6\x7d\xda\xaf\x3d\xee\xb2\x82\x46\x45\x6e\x97\x23\x26\xdb\xcd\xb5\xcf\x3f\xb2\x89\xac\xa0\x1e\x68\xda\x5d\x59\x89\x6e\x3a\x61\x65\x35\x8b\x07\x1b\x30\x4d\x6a\xb3\xd0\x18\x94\x4b\xe5\x04\x9d\x5e\x0e\x2b\xb8\x19\xac\xf6\x7a\x60\x06\x11\x10\x89\xe6\x76\x71\x32\xd7\x2d\xd8\x5b\xed\xdc\xbb\x2d\x64\x49\x6d\xb0\xcc\x92\x95\x5a\xb4\xc6\x23\x4f\x1e\xea\x24\xf2\xd5\x14\x83\xf2\xe2\x09\xe4\x58\x9b\xf9\x51\x9f\xac\x51\xb4\xd0\x61\xe8\x01\x12\x5e\x60\x5f\x80\x93\xbb\x69\x97\xbc\x16\x3d\x55\x15\x96\xfe\x4a\xb7\xcf\xae\x8f\xb9\xa9\x0f\x69\x80\x48\x0c\xe0\xc2\x29\xfd\x16\x75\x40\x9b\xd7\x88\x35\x4d\xaf\x31\x62\x40\xcf\xe0\xaf\x93\xeb",
+ "\x92\x81\xbd\x03\xfe\x95\x54\x5e\x53\x21\xa9\x1a\x0a\xd8\xfa\x75\xa0\x05\xb9\x28\xc8\x34\x50\xdf\x65\x74\x19\x87\x0c\x4e\x98\x0e\x32\x48\x4f\xcf\x1f\x59\x87\x02\xed\x20\x40\x4f\xec\xe4\x8a\x2e\xe9\xdb\xcf\x22\x12\x06\x54\xae\x40\x29\x51\x60\x5b\xed\x19\x7e",
+ 165 },
+ { GCRY_MD_SHA3_512,
+ "\x2a\xce\x31\xab\xb0\xa2\xe3\x26\x79\x44\xd2\xf7\x5e\x15\x59\x98\x5d\xb7\x35\x4c\x6e\x60\x5f\x18\xdc\x84\x70\x42\x3f\xca\x30\xb7\x33\x1d\x9b\x33\xc4\xa4\x32\x67\x83\xd1\xca\xae\x1b\x4f\x07\x06\x0e\xff\x97\x8e\x47\x46\xbf\x0c\x7e\x30\xcd\x61\x04\x0b\xd5\xec\x27\x46\xb2\x98\x63\xeb\x7f\x10\x3e\xbd\xa6\x14\xc4\x29\x1a\x80\x5b\x6a\x4c\x82\x14\x23\x05\x64\xa0\x55\x7b\xc7\x10\x2e\x0b\xd3\xed\x23\x71\x92\x52\xf7\x43\x5d\x64\xd2\x10\xee\x2a\xaf\xc5\x85\xbe\x90\x3f\xa4\x1e\x19\x68\xc5\x0f\xd5\xd5\x36\x79\x26\xdf\x7a\x05\xe3\xa4\x2c\xf0\x7e\x65\x6f\xf9\x2d\xe7\x3b\x03\x6c\xf8\xb1\x98\x98\xc0\xcb\x34\x55\x7c\x0c\x12\xc2\xd8\xb8\x4e\x91\x18\x1a\xf4\x67\xbc\x75\xa9\xd1",
+ "\x6c\xa7\x02\x3e\x20\x73\x56\x24\xe8\x39\x95\xa9\xe8\xae\xba\x66\xb9\xbc\x8d\x0a\x30\xdf\x67\x10\x8e\xff\x8a\xed\xeb\x3b\x3c\xa4\x84\x45\x7b\xd0\x27\x7c\x25\x52\xcb\xc7\xd6\x3d\xc8\x7e\xb5\x56\xf2\x19\x9c\x54\xea\x73\xba\xe6\x47\x76\x4d\xe1\x84\x89\xb1\xf1",
+ 166 },
+ { GCRY_MD_SHA3_512,
+ "\x0d\x8d\x09\xae\xd1\x9f\x10\x13\x96\x9c\xe5\xe7\xeb\x92\xf8\x3a\x20\x9a\xe7\x6b\xe3\x1c\x75\x48\x44\xea\x91\x16\xce\xb3\x9a\x22\xeb\xb6\x00\x30\x17\xbb\xcf\x26\x55\x5f\xa6\x62\x41\x85\x18\x7d\xb8\xf0\xcb\x35\x64\xb8\xb1\xc0\x6b\xf6\x85\xd4\x7f\x32\x86\xed\xa2\x0b\x83\x35\x8f\x59\x9d\x20\x44\xbb\xf0\x58\x3f\xab\x8d\x78\xf8\x54\xfe\x0a\x59\x61\x83\x23\x0c\x5e\xf8\xe5\x44\x26\x75\x0e\xaf\x2c\xc4\xe2\x9d\x3b\xdd\x03\x7e\x73\x4d\x86\x3c\x2b\xd9\x78\x9b\x4c\x24\x30\x96\x13\x8f\x76\x72\xc2\x32\x31\x4e\xff\xdf\xc6\x51\x34\x27\xe2\xda\x76\x91\x6b\x52\x48\x93\x3b\xe3\x12\xeb\x5d\xde\x4c\xf7\x08\x04\xfb\x25\x8a\xc5\xfb\x82\xd5\x8d\x08\x17\x7a\xc6\xf4\x75\x60\x17\xff\xf5",
+ "\xa9\x65\xe6\x99\xc1\xff\xae\xe3\x69\xb3\x65\x1c\x3a\x31\x85\x82\xae\x32\x9a\xe5\x1e\x6c\xcf\xb5\x27\x5f\x58\xf7\x48\xce\xdb\x8f\x6b\x84\x34\xfa\xc4\xa1\x13\x5a\xd9\xb5\x55\xaa\x8c\xc1\xff\x99\xa2\x22\x0c\xbe\x83\xbf\xc1\xc3\x74\xff\xc9\x27\xbb\x00\xab\xd3",
+ 167 },
+ { GCRY_MD_SHA3_512,
+ "\xc3\x23\x6b\x73\xde\xb7\x66\x2b\xf3\xf3\xda\xa5\x8f\x13\x7b\x35\x8b\xa6\x10\x56\x0e\xf7\x45\x57\x85\xa9\xbe\xfd\xb0\x35\xa0\x66\xe9\x07\x04\xf9\x29\xbd\x96\x89\xce\xf0\xce\x3b\xda\x5a\xcf\x44\x80\xbc\xeb\x8d\x09\xd1\x0b\x09\x8a\xd8\x50\x0d\x9b\x60\x71\xdf\xc3\xa1\x4a\xf6\xc7\x75\x11\xd8\x1e\x3a\xa8\x84\x49\x86\xc3\xbe\xa6\xf4\x69\xf9\xe0\x21\x94\xc9\x28\x68\xcd\x5f\x51\x64\x62\x56\x79\x8f\xf0\x42\x49\x54\xc1\x43\x4b\xdf\xed\x9f\xac\xb3\x90\xb0\x7d\x34\x2e\x99\x29\x36\xe0\xf8\x8b\xfd\x0e\x88\x4a\x0d\xdb\x67\x9d\x05\x47\xcc\xde\xc6\x38\x42\x85\xa4\x54\x29\xd1\x15\xac\x7d\x23\x5a\x71\x72\x42\x02\x1d\x1d\xc3\x56\x41\xf5\xf0\xa4\x8e\x84\x45\xdb\xa5\x8e\x6c\xb2\xc8\xea",
+ "\x4b\x44\xec\x2d\x18\x48\xd0\xec\x43\xab\x07\x93\x39\x0d\x24\x53\x5f\x33\x28\xad\x23\xc5\xf8\xfc\x43\xf5\x57\x9b\xd1\x6d\x84\xbb\xa0\x8b\x23\x3b\x0b\x5e\x24\xe2\x2b\xf6\xca\x2d\xef\xea\xca\x16\xbb\x98\xf8\xcd\xea\xf2\x6e\xec\xf2\xfc\x94\xaf\xe4\x60\x4c\xf4",
+ 168 },
+ { GCRY_MD_SHA3_512,
+ "\xb3\x9f\xeb\x82\x83\xea\xdc\x63\xe8\x18\x4b\x51\xdf\x5a\xe3\xfd\x41\xaa\xc8\xa9\x63\xbb\x0b\xe1\xcd\x08\xaa\x58\x67\xd8\xd9\x10\xc6\x69\x22\x1e\x73\x24\x33\x60\x64\x6f\x65\x53\xd1\xca\x05\xa8\x4e\x8d\xc0\xde\x05\xb6\x41\x9e\xc3\x49\xca\x99\x44\x80\x19\x3d\x01\xc9\x25\x25\xf3\xfb\x3d\xce\xfb\x08\xaf\xc6\xd2\x69\x47\xbd\xbb\xfd\x85\x19\x3f\x53\xb5\x06\x09\xc6\x14\x09\x05\xc5\x3a\x66\x86\xb5\x8e\x53\xa3\x19\xa5\x7b\x96\x23\x31\xed\xe9\x81\x49\xaf\x3d\xe3\x11\x8a\x81\x9d\xa4\xd7\x67\x06\xa0\x42\x4b\x4e\x1d\x29\x10\xb0\xed\x26\xaf\x61\xd1\x50\xeb\xcb\x46\x59\x5d\x42\x66\xa0\xbd\x7f\x65\x1b\xa4\x7d\x0c\x7f\x17\x9c\xa2\x85\x45\x00\x7d\x92\xe8\x41\x9d\x48\xfd\xfb\xd7\x44\xce",
+ "\x73\x16\x9f\x0b\xe2\x64\x56\x5e\x45\xfb\x8f\x46\x65\x75\x3e\x55\xf2\x40\x84\x6e\xb0\xd4\x81\xce\xf0\x27\x4e\x4a\x3d\x85\x95\x21\x76\x7d\x9f\x67\x5c\x06\x28\xdd\xce\x15\x52\x67\xba\x68\x6f\x21\x42\x80\x57\x13\xf2\x0c\x4c\x25\xe0\xb2\x43\x98\xc6\x5e\x34\x80",
+ 169 },
+ { GCRY_MD_SHA3_512,
+ "\xa9\x83\xd5\x4f\x50\x38\x03\xe8\xc7\x99\x9f\x4e\xdb\xbe\x82\xe9\x08\x4f\x42\x21\x43\xa9\x32\xdd\xdd\xc4\x7a\x17\xb0\xb7\x56\x4a\x7f\x37\xa9\x9d\x07\x86\xe9\x94\x76\x42\x8d\x29\xe2\x9d\x3c\x19\x7a\x72\xbf\xab\x13\x42\xc1\x2a\x0f\xc4\x78\x7f\xd7\x01\x7d\x7a\x61\x74\x04\x9e\xa4\x3b\x57\x79\x16\x9e\xf7\x47\x2b\xdb\xbd\x94\x1d\xcb\x82\xfc\x73\xaa\xc4\x5a\x8a\x94\xc9\xf2\xbd\x34\x77\xf6\x1f\xd3\xb7\x96\xf0\x2a\x1b\x82\x64\xa2\x14\xc6\xfe\xa7\x4b\x70\x51\xb2\x26\xc7\x22\x09\x9e\xc7\x88\x3a\x46\x2b\x83\xb6\xaf\xdd\x40\x09\x24\x8b\x8a\x23\x7f\x60\x5f\xe5\xa0\x8f\xe7\xd8\xb4\x53\x21\x42\x1e\xbb\xa6\x7b\xd7\x0a\x0b\x00\xdd\xbf\x94\xba\xab\x7f\x35\x9d\x5d\x1e\xea\x10\x5f\x28\xdc\xfb",
+ "\x9e\x1c\x19\x6c\xb7\x3d\x1e\xfa\x28\x8d\x63\x90\x2c\x64\xce\x1a\x34\x0b\xcd\xb8\x19\x7f\x4a\xfe\xcb\x11\x18\xda\xdd\x0d\x07\x6b\x5f\xb7\xf6\xf8\x09\x66\x6c\xc5\x8d\x2a\x8c\x1a\x68\xc6\x5d\x0e\x91\x55\x4c\x41\xd0\x83\xf5\x6d\x7b\x3d\xd3\x7d\xf1\xb6\xc4\x94",
+ 170 },
+ { GCRY_MD_SHA3_512,
+ "\xe4\xd1\xc1\x89\x7a\x0a\x86\x6c\xe5\x64\x63\x5b\x74\x22\x2f\x96\x96\xbf\x2c\x7f\x64\x0d\xd7\x8d\x7e\x2a\xca\x66\xe1\xb6\x1c\x64\x2b\xb0\x3e\xa7\x53\x6a\xae\x59\x78\x11\xe9\xbf\x4a\x7b\x45\x3e\xde\x31\xf9\x7b\x46\xa5\xf0\xef\x51\xa0\x71\xa2\xb3\x91\x8d\xf1\x6b\x15\x25\x19\xae\x37\x76\xf9\xf1\xed\xab\x4c\x2a\x37\x7c\x32\x92\xe9\x64\x08\x35\x9d\x36\x13\x84\x4d\x5e\xb3\x93\x00\x02\x83\xd5\xad\x34\x01\xa3\x18\xb1\x2f\xd1\x47\x4b\x86\x12\xf2\xbb\x50\xfb\x6a\x8b\x9e\x02\x3a\x54\xd7\xdd\xe2\x8c\x43\xd6\xd8\x85\x4c\x8d\x9d\x11\x55\x93\x5c\x19\x98\x11\xdb\xfc\x87\xe9\xe0\x07\x2e\x90\xeb\x88\x68\x1c\xc7\x52\x97\x14\xf8\xfb\x8a\x2c\x9d\x88\x56\x7a\xdf\xb9\x74\xee\x20\x5a\x9b\xf7\xb8\x48",
+ "\x0c\x42\x9c\xc1\x64\x25\x3c\x09\x53\x86\x68\x13\x5c\x94\x36\xfd\xbc\x79\xda\x8e\x1f\xbe\x92\xe7\xbb\xc6\xeb\x30\x62\x75\x91\xe7\x34\x7c\xcb\x43\xf7\xae\xc2\xd3\x7f\xf3\xda\xbc\xfc\x9f\xa0\xc8\x06\x29\x93\x7c\x0c\x17\x7c\x1c\x7e\xd0\xfc\x76\xa1\x5d\xf0\x75",
+ 171 },
+ { GCRY_MD_SHA3_512,
+ "\xb1\x0c\x59\x72\x3e\x3d\xca\xdd\x6d\x75\xdf\x87\xd0\xa1\x58\x0e\x73\x13\x3a\x9b\x7d\x00\xcb\x95\xec\x19\xf5\x54\x70\x27\x32\x3b\xe7\x51\x58\xb1\x1f\x80\xb6\xe1\x42\xc6\xa7\x85\x31\x88\x6d\x90\x47\xb0\x8e\x55\x1e\x75\xe6\x26\x1e\x79\x78\x53\x66\xd7\x02\x4b\xd7\xcd\x9c\xf3\x22\xd9\xbe\x7d\x57\xfb\x66\x10\x69\xf2\x48\x1c\x7b\xb7\x59\xcd\x71\xb4\xb3\x6c\xa2\xbc\x2d\xf6\xd3\xa3\x28\xfa\xeb\xdb\x99\x5a\x97\x94\xa8\xd7\x21\x55\xed\x55\x1a\x1f\x87\xc8\x0b\xf6\x05\x9b\x43\xfc\x76\x49\x00\xb1\x8a\x1c\x24\x41\xf7\x48\x77\x43\xcf\x84\xe5\x65\xf6\x1f\x8d\xd2\xec\xe6\xb6\xcc\xc9\x44\x40\x49\x19\x7a\xaa\xf5\x3e\x92\x6f\xbe\xe3\xbf\xca\x8b\xe5\x88\xec\x77\xf2\x9d\x21\x1b\xe8\x9d\xe1\x8b\x15\xf6",
+ "\x70\x01\x12\xfa\x90\xa1\xa2\xfd\x03\x9a\x41\xb6\x48\x54\x01\x63\x4e\x75\x78\x40\xe4\x22\xae\xb4\xa2\x36\x63\x49\x58\x19\x2f\xfb\x2f\x2d\xdf\xa2\x25\x3f\xc1\xec\xb2\x11\xc7\xe0\x36\x09\x8b\x71\x4e\x62\xf7\xbf\x2b\x69\x75\xb1\xe9\x5f\xaa\x9b\x8d\x02\xa7\x3a",
+ 172 },
+ { GCRY_MD_SHA3_512,
+ "\xdb\x11\xf6\x09\xba\xba\x7b\x0c\xa6\x34\x92\x6b\x1d\xd5\x39\xc8\xcb\xad\xa2\x49\x67\xd7\xad\xd4\xd9\x87\x6f\x77\xc2\xd8\x0c\x0f\x4d\xce\xfb\xd7\x12\x15\x48\x37\x35\x82\x70\x5c\xca\x24\x95\xbd\x2a\x43\x71\x6f\xe6\x4e\xd2\x6d\x05\x9c\xfb\x56\x6b\x33\x64\xbd\x49\xee\x07\x17\xbd\xd9\x81\x0d\xd1\x4d\x8f\xad\x80\xdb\xbd\xc4\xca\xfb\x37\xcc\x60\xfb\x0f\xe2\xa8\x0f\xb4\x54\x1b\x8c\xa9\xd5\x9d\xce\x45\x77\x38\xa9\xd3\xd8\xf6\x41\xaf\x8c\x3f\xd6\xda\x16\x2d\xc1\x6f\xc0\x1a\xac\x52\x7a\x4a\x02\x55\xb4\xd2\x31\xc0\xbe\x50\xf4\x4f\x0d\xb0\xb7\x13\xaf\x03\xd9\x68\xfe\x7f\x0f\x61\xed\x08\x24\xc5\x5c\x4b\x52\x65\x54\x8f\xeb\xd6\xaa\xd5\xc5\xee\xdf\x63\xef\xe7\x93\x48\x9c\x39\xb8\xfd\x29\xd1\x04\xce",
+ "\x90\x1c\x6d\x85\x50\x9f\x01\xa4\x7e\xa2\xe2\x79\x2a\x5d\xb7\x28\xea\x39\xe5\x70\x3e\xed\xea\xe4\x13\x65\xed\xf1\x0a\x86\x6b\x92\x2b\x10\x93\xe5\x2e\x68\x7e\x31\x2d\xb1\x29\xda\x1f\x05\x3e\xf6\x84\x8c\xb0\xb3\x14\xc9\xa3\xa9\x99\xeb\x3e\x75\xe1\x4c\x9c\xc2",
+ 173 },
+ { GCRY_MD_SHA3_512,
+ "\xbe\xbd\x4f\x1a\x84\xfc\x8b\x15\xe4\x45\x2a\x54\xbd\x02\xd6\x9e\x30\x4b\x7f\x32\x61\x6a\xad\xd9\x05\x37\x93\x71\x06\xae\x4e\x28\xde\x9d\x8a\xab\x02\xd1\x9b\xc3\xe2\xfd\xe1\xd6\x51\x55\x9e\x29\x64\x53\xe4\xdb\xa9\x43\x70\xa1\x4d\xbb\xb2\xd1\xd4\xe2\x02\x23\x02\xee\x90\xe2\x08\x32\x1e\xfc\xd8\x52\x8a\xd8\x9e\x46\xdc\x83\x9e\xa9\xdf\x61\x8e\xa8\x39\x4a\x6b\xff\x30\x8e\x77\x26\xba\xe0\xc1\x9b\xcd\x4b\xe5\x2d\xa6\x25\x8e\x2e\xf4\xe9\x6a\xa2\x12\x44\x42\x9f\x49\xef\x5c\xb4\x86\xd7\xff\x35\xca\xc1\xba\xcb\x7e\x95\x71\x19\x44\xbc\xcb\x2a\xb3\x47\x00\xd4\x2d\x1e\xb3\x8b\x5d\x53\x6b\x94\x73\x48\xa4\x58\xed\xe3\xdc\x6b\xd6\xec\x54\x7b\x1b\x0c\xae\x5b\x25\x7b\xe3\x6a\x71\x24\xe1\x06\x0c\x17\x0f\xfa",
+ "\x4c\xc9\xa6\x1f\xfe\x08\x98\x44\x17\x71\x2b\x80\xf9\x62\x36\x5a\xf3\x6e\xd6\x6a\x8a\xab\x2a\x78\x8d\x22\xa5\xc6\xb2\x39\x62\xd2\x35\x84\x63\x8e\x71\x2e\x91\x83\xc0\xa2\x71\x38\x3d\xb0\x87\x7f\x72\x2d\x39\x91\x16\xf9\xbe\xf7\x9a\x56\xab\x09\x6e\xf2\x17\x49",
+ 174 },
+ { GCRY_MD_SHA3_512,
+ "\x5a\xca\x56\xa0\x3a\x13\x78\x4b\xdc\x32\x89\xd9\x36\x4f\x79\xe2\xa8\x5c\x12\x27\x6b\x49\xb9\x2d\xb0\xad\xaa\x4f\x20\x6d\x50\x28\xf2\x13\xf6\x78\xc3\x51\x0e\x11\x1f\x9d\xc4\xc1\xc1\xf8\xb6\xac\xb1\x7a\x64\x13\xaa\x22\x76\x07\xc5\x15\xc6\x2a\x73\x38\x17\xba\x5e\x76\x2c\xc6\x74\x8e\x7e\x0d\x68\x72\xc9\x84\xd7\x23\xc9\xbb\x3b\x11\x7e\xb8\x96\x31\x85\x30\x0a\x80\xbf\xa6\x5c\xde\x49\x5d\x70\xa4\x6c\x44\x85\x86\x05\xfc\xcb\xed\x08\x6c\x2b\x45\xce\xf9\x63\xd3\x32\x94\xdb\xe9\x70\x6b\x13\xaf\x22\xf1\xb7\xc4\xcd\x5a\x00\x1c\xfe\xc2\x51\xfb\xa1\x8e\x72\x2c\x6e\x1c\x4b\x11\x66\x91\x8b\x4f\x6f\x48\xa9\x8b\x64\xb3\xc0\x7f\xc8\x6a\x6b\x17\xa6\xd0\x48\x0a\xb7\x9d\x4e\x64\x15\xb5\x20\xf1\xc4\x84\xd6\x75\xb1",
+ "\xb3\x6e\xa5\x6b\xb6\xbf\x80\xd9\x1d\x5a\x60\x5f\x84\x09\xae\x6b\x7d\x87\x9e\xc4\x08\x15\xb3\x5c\x66\x4c\xc6\xb0\x1b\xf6\xc7\x18\xad\x46\x4f\x15\xc3\x4d\xd1\x31\x5a\x79\xa5\x45\x6b\x6c\x3f\x8e\xd8\x9e\x60\x39\x0b\xc7\x1e\xf7\x47\xe1\x2c\xdc\x77\x70\x62\x45",
+ 175 },
+ { GCRY_MD_SHA3_512,
+ "\xa5\xaa\xd0\xe4\x64\x6a\x32\xc8\x5c\xfc\xac\x73\xf0\x2f\xc5\x30\x0f\x19\x82\xfa\xbb\x2f\x21\x79\xe2\x83\x03\xe4\x47\x85\x40\x94\xcd\xfc\x85\x43\x10\xe5\xc0\xf6\x09\x93\xce\xff\x54\xd8\x4d\x6b\x46\x32\x3d\x93\x0a\xdb\x07\xc1\x75\x99\xb3\x5b\x50\x5f\x09\xe7\x84\xbc\xa5\x98\x5e\x01\x72\x25\x77\x97\xfb\x53\x64\x9e\x2e\x97\x23\xef\xd1\x68\x65\xc3\x1b\x5c\x3d\x51\x13\xb5\x8b\xb0\xbf\xc8\x92\x0f\xab\xdd\xa0\x86\xd7\x53\x7e\x66\xd7\x09\xd0\x50\xbd\x14\xd0\xc9\x60\x87\x3f\x15\x6f\xad\x5b\x3d\x38\x40\xcd\xfc\xdc\x9b\xe6\xaf\x51\x9d\xb2\x62\xa2\x7f\x40\x89\x6a\xb2\x5c\xc3\x9f\x96\x98\x4d\x65\x06\x11\xc0\xd5\xa3\x08\x0d\x5b\x3a\x1b\xf1\x86\xab\xd4\x29\x56\x58\x8b\x3b\x58\xcd\x94\x89\x70\xd2\x98\x77\x60\x60",
+ "\x8e\xcb\x8f\x62\x2d\xab\x70\x87\xe9\xa9\x5c\xd0\x34\x11\x92\xfe\xa6\xb1\xc9\x56\xdf\x9a\xd3\xde\xd8\x23\x94\x8b\x78\x49\xc4\xf3\x15\x0c\x95\x59\x52\x09\x53\xeb\xde\x98\xed\x76\xf6\xe4\x3b\xfe\x4f\xb2\x5f\xda\x71\x25\x25\xc6\xd3\xda\xa8\x03\x23\xbe\x8e\x4a",
+ 176 },
+ { GCRY_MD_SHA3_512,
+ "\x06\xcb\xbe\x67\xe9\x4a\x97\x82\x03\xea\xd6\xc0\x57\xa1\xa5\xb0\x98\x47\x8b\x4b\x4c\xbe\xf5\xa9\x7e\x93\xc8\xe4\x2f\x55\x72\x71\x35\x75\xfc\x2a\x88\x45\x31\xd7\x62\x2f\x8f\x87\x93\x87\xa8\x59\xa8\x0f\x10\xef\x02\x70\x8c\xd8\xf7\x41\x3a\xb3\x85\xaf\xc3\x57\x67\x8b\x95\x78\xc0\xeb\xf6\x41\xef\x07\x6a\x1a\x30\xf1\xf7\x53\x79\xe9\xdc\xb2\xa8\x85\xbd\xd2\x95\x90\x5e\xe8\x0c\x01\x68\xa6\x2a\x95\x97\xd1\x0c\xf1\x2d\xd2\xd8\xce\xe4\x66\x45\xc7\xe5\xa1\x41\xf6\xe0\xe2\x3a\xa4\x82\xab\xe5\x66\x1c\x16\xe6\x9e\xf1\xe2\x83\x71\xe2\xe2\x36\xc3\x59\xba\x4e\x92\xc2\x56\x26\xa7\xb7\xff\x13\xf6\xea\x4a\xe9\x06\xe1\xcf\xe1\x63\xe9\x17\x19\xb1\xf7\x50\xa9\x6c\xbd\xe5\xfb\xc9\x53\xd9\xe5\x76\xcd\x21\x6a\xfc\x90\x32\x3a",
+ "\x51\x92\x15\xda\x34\xac\xfc\xd6\x2d\xd6\x17\xec\xd5\x97\x83\x65\x41\x7d\x57\xc2\x67\x1a\x7b\x48\x65\x5b\x89\xf4\x48\xb2\x3b\x12\x8d\x3a\xd0\x49\x10\xa1\xbb\xbd\xc0\x0e\x95\x4a\x1e\x49\x76\x51\x76\xa8\xac\xa4\xc3\x7d\x56\xab\xf0\xe0\xb7\x2e\x33\x1a\x8d\x7c",
+ 177 },
+ { GCRY_MD_SHA3_512,
+ "\xf1\xc5\x28\xcf\x77\x39\x87\x47\x07\xd4\xd8\xad\x5b\x98\xf7\xc7\x71\x69\xde\x0b\x57\x18\x8d\xf2\x33\xb2\xdc\x8a\x5b\x31\xed\xa5\xdb\x42\x91\xdd\x9f\x68\xe6\xba\xd3\x7b\x8d\x7f\x6c\x9c\x00\x44\xb3\xbf\x74\xbb\xc3\xd7\xd1\x79\x8e\x13\x87\x09\xb0\xd7\x5e\x7c\x59\x3d\x3c\xcc\xdc\x1b\x20\xc7\x17\x4b\x4e\x69\x2a\xdd\x82\x0a\xce\x26\x2d\x45\xcc\xfa\xe2\x07\x7e\x87\x87\x96\x34\x71\x68\x06\x0a\x16\x2e\xcc\xa8\xc3\x8c\x1a\x88\x35\x0b\xd6\x3b\xb5\x39\x13\x4f\x70\x0f\xd4\xad\xdd\x59\x59\xe2\x55\x33\x7d\xaa\x06\xbc\x86\x35\x8f\xab\xcb\xef\xdf\xb5\xbc\x88\x97\x83\xd8\x43\xc0\x8a\xad\xc6\xc4\xf6\xc3\x6f\x65\xf1\x56\xe8\x51\xc9\xa0\xf9\x17\xe4\xa3\x67\xb5\xad\x93\xd8\x74\x81\x2a\x1d\xe6\xa7\xb9\x3c\xd5\x3a\xd9\x72\x32",
+ "\x0d\x1c\x1a\xd4\xe1\xcf\xef\xee\x85\x4c\x4a\x73\x9a\x03\x42\xe3\x9d\x70\x0d\xba\xf4\x89\x19\x78\xd7\xc8\x39\xe8\x7c\x68\x07\x17\xd6\x3a\xb4\xaa\x1e\xd7\xeb\x65\x7c\xed\x9f\x8d\x2c\xf4\x72\x04\x26\x2e\x60\x96\x10\x84\x2f\xc5\xb2\x19\xac\xff\x7e\xb1\x88\xc4",
+ 178 },
+ { GCRY_MD_SHA3_512,
+ "\x9d\x9f\x3a\x7e\xcd\x51\xb4\x1f\x65\x72\xfd\x0d\x08\x81\xe3\x03\x90\xdf\xb7\x80\x99\x1d\xae\x7d\xb3\xb4\x76\x19\x13\x47\x18\xe6\xf9\x87\x81\x0e\x54\x26\x19\xdf\xaa\x7b\x50\x5c\x76\xb7\x35\x0c\x64\x32\xd8\xbf\x1c\xfe\xbd\xf1\x06\x9b\x90\xa3\x5f\x0d\x04\xcb\xdf\x13\x0b\x0d\xfc\x78\x75\xf4\xa4\xe6\x2c\xdb\x8e\x52\x5a\xad\xd7\xce\x84\x25\x20\xa4\x82\xac\x18\xf0\x94\x42\xd7\x83\x05\xfe\x85\xa7\x4e\x39\xe7\x60\xa4\x83\x74\x82\xed\x2f\x43\x7d\xd1\x3b\x2e\xc1\x04\x2a\xfc\xf9\xde\xcd\xc3\xe8\x77\xe5\x0f\xf4\x10\x6a\xd1\x0a\x52\x52\x30\xd1\x19\x20\x32\x4a\x81\x09\x4d\xa3\x1d\xea\xb6\x47\x6a\xa4\x2f\x20\xc8\x48\x43\xcf\xc1\xc5\x85\x45\xee\x80\x35\x2b\xdd\x37\x40\xdd\x6a\x16\x79\x2a\xe2\xd8\x6f\x11\x64\x1b\xb7\x17\xc2",
+ "\x0a\x5d\x9e\xf4\x0b\xa2\xb9\x8e\xdb\xd7\x91\x8c\xc6\x77\x94\x83\xa1\xa0\x0b\xd9\x4c\xc1\xe1\x49\x54\x95\xca\xf6\xcd\x47\xc6\x23\x95\x71\xc3\x82\x8f\x45\x65\xa0\xd5\x37\x86\x78\x1d\x71\x2c\x10\xef\x73\x33\x22\x7f\x65\x19\x74\x62\x88\x87\xd4\x42\xa5\xef\x9d",
+ 179 },
+ { GCRY_MD_SHA3_512,
+ "\x51\x79\x88\x87\x24\x81\x9f\xba\xd3\xaf\xa9\x27\xd3\x57\x77\x96\x66\x0e\x6a\x81\xc5\x2d\x98\xe9\x30\x32\x61\xd5\xa4\xa8\x32\x32\xf6\xf7\x58\x93\x4d\x50\xaa\x83\xff\x9e\x20\xa5\x92\x6d\xfe\xba\xac\x49\x52\x9d\x00\x6e\xb9\x23\xc5\xae\x50\x48\xed\x54\x4e\xc4\x71\xed\x71\x91\xed\xf4\x63\x63\x38\x38\x24\xf9\x15\x76\x9b\x3e\x68\x80\x94\xc6\x82\xb0\x21\x51\xe5\xee\x01\xe5\x10\xb4\x31\xc8\x86\x5a\xff\x8b\x6b\x6f\x2f\x59\xcb\x6d\x12\x9d\xa7\x9e\x97\xc6\xd2\xb8\xfa\x6c\x6d\xa3\xf6\x03\x19\x9d\x2d\x1b\xca\xb5\x47\x68\x2a\x81\xcd\x6c\xf6\x5f\x65\x51\x12\x13\x91\xd7\x8b\xcc\x23\xb5\xbd\x0e\x92\x2e\xc6\xd8\xbf\x97\xc9\x52\xe8\x4d\xd2\x8a\xef\x90\x9a\xba\x31\xed\xb9\x03\xb2\x8f\xbf\xc3\x3b\x77\x03\xcd\x99\x62\x15\xa1\x12\x38",
+ "\xea\x83\xde\x9a\xe0\x57\x70\x1f\x6e\xc6\x8f\xf6\x7e\x92\xe0\x33\x4c\x18\xeb\xb7\x9a\xf1\x95\x3c\x25\x14\x40\x8d\x58\xe6\x9f\x10\x54\x41\x64\x2a\x1d\x5b\x7d\x60\x10\xf7\xcb\x15\xd1\x31\xdd\x53\x18\x55\xca\x33\x7a\x7b\x0b\x79\x4f\xa6\xd6\x92\x3f\x01\x7a\xfa",
+ 180 },
+ { GCRY_MD_SHA3_512,
+ "\x57\x6e\xf3\x52\x0d\x30\xb7\xa4\x89\x9b\x8c\x0d\x5e\x35\x9e\x45\xc5\x18\x9a\xdd\x10\x0e\x43\xbe\x42\x9a\x02\xfb\x3d\xe5\xff\x4f\x8f\xd0\xe7\x9d\x96\x63\xac\xca\x72\xcd\x29\xc9\x45\x82\xb1\x92\x92\xa5\x57\xc5\xb1\x31\x52\x97\xd1\x68\xfb\xb5\x4e\x9e\x2e\xcd\x13\x80\x9c\x2b\x5f\xce\x99\x8e\xdc\x65\x70\x54\x5e\x14\x99\xdb\xe7\xfb\x74\xd4\x7c\xd7\xf3\x58\x23\xb2\x12\xb0\x5b\xf3\xf5\xa7\x9c\xaa\x34\x22\x4f\xdd\x67\x0d\x33\x5f\xcb\x10\x6f\x5d\x92\xc3\x94\x6f\x44\xd3\xaf\xcb\xae\x2e\x41\xac\x55\x4d\x8e\x67\x59\xf3\x32\xb7\x6b\xe8\x9a\x03\x24\xaa\x12\xc5\x48\x2d\x1e\xa3\xee\x89\xde\xd4\x93\x6f\x3e\x3c\x08\x04\x36\xf5\x39\xfa\x13\x7e\x74\xc6\xd3\x38\x9b\xdf\x5a\x45\x07\x4c\x47\xbc\x7b\x20\xb0\x94\x84\x07\xa6\x6d\x85\x5e\x2f",
+ "\x66\x51\xc2\x5d\x33\xd1\x0b\x72\x53\x5f\x1d\xb2\x6a\x1d\xfe\x2e\xb9\x9c\xdd\x50\x54\x48\x01\x85\x89\xb5\xb8\x8b\x7c\xab\x63\xeb\x43\x9c\x31\xa4\x74\xc6\xf1\x19\x1d\xf1\x4e\xfc\x7d\x06\x65\xcc\x7b\x82\xa7\xdc\x54\xa7\xc6\xb0\xc2\xfd\x1f\x75\xc3\x0d\x68\x72",
+ 181 },
+ { GCRY_MD_SHA3_512,
+ "\x0d\xf2\x15\x2f\xa4\xf4\x35\x7c\x87\x41\x52\x9d\xd7\x7e\x78\x39\x25\xd3\xd7\x6e\x95\xba\xfa\x2b\x54\x2a\x2c\x33\xf3\xd1\xd1\x17\xd1\x59\xcf\x47\x3f\x82\x31\x03\x56\xfe\xe4\xc9\x0a\x9e\x50\x5e\x70\xf8\xf2\x48\x59\x65\x63\x68\xba\x09\x38\x1f\xa2\x45\xeb\x6c\x3d\x76\x3f\x30\x93\xf0\xc8\x9b\x97\x2e\x66\xb5\x3d\x59\x40\x6d\x9f\x01\xae\xa0\x7f\x8b\x3b\x61\x5c\xac\x4e\xe4\xd0\x5f\x54\x2e\x7d\x0d\xab\x45\xd6\x7c\xcc\xcd\x3a\x60\x6c\xcb\xeb\x31\xea\x1f\xa7\x00\x5b\xa0\x71\x76\xe6\x0d\xab\x7d\x78\xf6\x81\x0e\xf0\x86\xf4\x2f\x08\xe5\x95\xf0\xec\x21\x73\x72\xb9\x89\x70\xcc\x63\x21\x57\x6d\x92\xce\x38\xf7\xc3\x97\xa4\x03\xba\xda\x15\x48\xd2\x05\xc3\x43\xac\x09\xde\xca\x86\x32\x53\x73\xc3\xb7\x6d\x9f\x32\x02\x8f\xea\x8e\xb3\x25\x15",
+ "\xa7\x54\x65\x22\x47\xf7\x28\x5c\xe2\xdd\x8a\x10\x03\x5c\x69\x96\x1e\x4f\x9c\x02\x5e\x1f\xd0\x87\xcb\xd3\x12\x6e\x04\x9a\x9e\x83\x2c\x3f\x3a\x49\x1f\xcd\xe3\x38\xb8\xc0\x19\x46\xcd\xd7\xde\xc3\x2a\x8f\xd7\xed\x1c\xb3\x04\x5b\xca\xf3\x39\x89\x05\xb1\xbb\x42",
+ 182 },
+ { GCRY_MD_SHA3_512,
+ "\x3e\x15\x35\x0d\x87\xd6\xeb\xb5\xc8\xad\x99\xd4\x25\x15\xcf\xe1\x79\x80\x93\x3c\x7a\x8f\x6b\x8b\xbb\xf0\xa6\x37\x28\xce\xfa\xad\x20\x52\x62\x3c\x0b\xd5\x93\x18\x39\x11\x2a\x48\x63\x3f\xb3\xc2\x00\x4e\x07\x49\xc8\x7a\x41\xb2\x6a\x8b\x48\x94\x55\x39\xd1\xff\x41\xa4\xb2\x69\x46\x2f\xd1\x99\xbf\xec\xd4\x53\x74\x75\x6f\x55\xa9\x11\x6e\x92\x09\x3a\xc9\x94\x51\xae\xfb\x2a\xf9\xfd\x32\xd6\xd7\xf5\xfb\xc7\xf7\xa5\x40\xd5\x09\x7c\x09\x6e\xbc\x3b\x3a\x72\x15\x41\xde\x07\x3a\x1c\xc0\x2f\x7f\xb0\xfb\x1b\x93\x27\xfb\x0b\x12\x18\xca\x49\xc9\x48\x7a\xb5\x39\x66\x22\xa1\x3a\xe5\x46\xc9\x7a\xbd\xef\x6b\x56\x38\x0d\xda\x70\x12\xa8\x38\x40\x91\xb6\x65\x6d\x0a\xb2\x72\xd3\x63\xce\xa7\x81\x63\xff\x76\x5c\xdd\x13\xab\x17\x38\xb9\x40\xd1\x6c\xae",
+ "\xfc\x11\x27\xf6\x65\x0f\x32\x63\x84\x53\xab\x77\x3f\x5c\xe6\x0f\x9f\x61\x65\xbc\x99\x28\xef\xf1\x8c\x7a\x32\x81\x54\x0c\x7a\x61\x5d\x2d\x62\xa9\x2e\x55\x7d\x4a\x1e\xc1\x22\x9e\x84\x81\x9d\x2d\xbf\x06\xce\xd4\xde\x0f\xf9\x00\x40\xec\xb9\x61\xd6\x78\xe1\x81",
+ 183 },
+ { GCRY_MD_SHA3_512,
+ "\xc3\x8d\x6b\x0b\x75\x7c\xb5\x52\xbe\x40\x94\x0e\xce\x00\x09\xef\x3b\x0b\x59\x30\x7c\x14\x51\x68\x6f\x1a\x22\x70\x29\x22\x80\x0d\x58\xbc\xe7\xa6\x36\xc1\x72\x7e\xe5\x47\xc0\x1b\x21\x47\x79\xe8\x98\xfc\x0e\x56\x0f\x8a\xe7\xf6\x1b\xef\x4d\x75\xea\xa6\x96\xb9\x21\xfd\x6b\x73\x5d\x17\x15\x35\xe9\xed\xd2\x67\xc1\x92\xb9\x98\x80\xc8\x79\x97\x71\x10\x02\x00\x90\x95\xd8\xa7\xa4\x37\xe2\x58\x10\x4a\x41\xa5\x05\xe5\xef\x71\xe5\x61\x3d\xdd\x20\x08\x19\x5f\x0c\x57\x4e\x6b\xa3\xfe\x40\x09\x9c\xfa\x11\x6e\x5f\x1a\x2f\xa8\xa6\xda\x04\xba\xdc\xb4\xe2\xd5\xd0\xde\x31\xfd\xc4\x80\x08\x91\xc4\x57\x81\xa0\xaa\xc7\xc9\x07\xb5\x6d\x63\x1f\xca\x5c\xe8\xb2\xcd\xe6\x20\xd1\x1d\x17\x77\xed\x9f\xa6\x03\x54\x1d\xe7\x94\xdd\xc5\x75\x8f\xcd\x5f\xad\x78\xc0",
+ "\x43\xc2\x1b\xcc\xac\x7a\xce\xe8\xed\x43\x7b\x87\x4e\xd7\xcd\xf2\x0e\xa2\xe9\xdc\x98\xab\x82\x12\x46\x10\xdc\x4f\x84\x16\x24\x8b\x51\x30\x90\x45\xcd\xfb\xce\x92\xef\xa9\xe5\x6c\x5b\x36\xd6\xe5\xd2\x75\x80\x31\x9c\xe6\x9c\x22\xe5\xd6\xc8\x7e\x55\x1e\xed\x4a",
+ 184 },
+ { GCRY_MD_SHA3_512,
+ "\x8d\x2d\xe3\xf0\xb3\x7a\x63\x85\xc9\x07\x39\x80\x5b\x17\x00\x57\xf0\x91\xcd\x0c\x7a\x0b\xc9\x51\x54\x0f\x26\xa5\xa7\x5b\x3e\x69\x46\x31\xbb\x64\xc7\x63\x5e\xed\x31\x6f\x51\x31\x8e\x9d\x8d\xe1\x3c\x70\xa2\xab\xa0\x4a\x14\x83\x68\x55\xf3\x5e\x48\x05\x28\xb7\x76\xd0\xa1\xe8\xa2\x3b\x54\x7c\x8b\x8d\x6a\x0d\x09\xb2\x41\xd3\xbe\x93\x77\x16\x0c\xca\x4e\x67\x93\xd0\x0a\x51\x5d\xc2\x99\x2c\xb7\xfc\x74\x1d\xac\xa1\x71\x43\x1d\xa9\x9c\xce\x6f\x77\x89\xf1\x29\xe2\xac\x5c\xf6\x5b\x40\xd7\x03\x03\x5c\xd2\x18\x5b\xb9\x36\xc8\x20\x02\xda\xf8\xcb\xc2\x7a\x7a\x9e\x55\x4b\x06\x19\x66\x30\x44\x6a\x6f\x0a\x14\xba\x15\x5e\xd2\x6d\x95\xbd\x62\x7b\x72\x05\xc0\x72\xd0\x2b\x60\xdb\x0f\xd7\xe4\x9e\xa0\x58\xc2\xe0\xba\x20\x2d\xaf\xf0\xde\x91\xe8\x45\xcf\x79",
+ "\x89\x39\x34\xb8\xc6\x30\xa9\xbf\x71\x3c\x64\xff\xd1\x12\x8e\xac\x75\xd1\xce\xfd\xef\x66\x42\xfb\x27\xf2\x0c\xb5\x66\x94\xc2\xfa\x8b\xa6\xef\xcf\x3e\x0e\x56\xc7\x78\x9c\xfa\xac\x6b\x2f\x7b\x24\x7d\xea\x83\x67\xff\xd2\x69\xe7\x4b\x9c\xdf\xb0\x53\x70\x31\xea",
+ 185 },
+ { GCRY_MD_SHA3_512,
+ "\xc4\x64\xbb\xda\xd2\x75\xc5\x0d\xcd\x98\x3b\x65\xad\x10\x19\xb9\xff\x85\xa1\xe7\x1c\x80\x7f\x32\x04\xbb\x2c\x92\x1d\xc3\x1f\xbc\xd8\xc5\xfc\x45\x86\x8a\xe9\xef\x85\xb6\xc9\xb8\x3b\xba\x2a\x5a\x82\x22\x01\xed\x68\x58\x6e\xc5\xec\x27\xfb\x28\x57\xa5\xd1\xa2\xd0\x9d\x09\x11\x5f\x22\xdc\xc3\x9f\xe6\x1f\x5e\x1b\xa0\xff\x6e\x8b\x4a\xcb\x4c\x6d\xa7\x48\xbe\x7f\x3f\x08\x39\x73\x93\x94\xff\x7f\xa8\xe3\x9f\x7f\x7e\x84\xa3\x3c\x38\x66\x87\x5c\x01\xbc\xb1\x26\x3c\x94\x05\xd9\x19\x08\xe9\xe0\xb5\x0e\x74\x59\xfa\xbb\x63\xd8\xc6\xbb\xb7\x3d\x8e\x34\x83\xc0\x99\xb5\x5b\xc3\x0f\xf0\x92\xff\x68\xb6\xad\xed\xfd\x47\x7d\x63\x57\x0c\x9f\x55\x15\x84\x7f\x36\xe2\x4b\xa0\xb7\x05\x55\x71\x30\xce\xc5\x7e\xba\xd1\xd0\xb3\x1a\x37\x8e\x91\x89\x4e\xe2\x6e\x3a\x04",
+ "\xb4\xcb\x58\xd8\x49\x79\x78\x91\x6d\xc3\x62\xd3\x7a\xde\x12\xc7\xa0\xd8\xfe\x3b\x08\xb3\x70\x65\x9b\x27\x21\x82\x91\xe0\x4e\xf3\x43\x09\x5a\x91\x88\x7b\x04\x09\x84\xcb\x80\xb0\xc8\x61\x1f\xd1\x2c\x18\xea\xd3\x7b\x95\x32\x0d\x59\xed\xdb\x32\x11\x3e\x42\xa4",
+ 186 },
+ { GCRY_MD_SHA3_512,
+ "\x8b\x8d\x68\xbb\x8a\x75\x73\x2f\xe2\x72\x81\x5a\x68\xa1\xc9\xc5\xaa\x31\xb4\x1d\xed\xc8\x49\x3e\x76\x52\x5d\x1d\x01\x3d\x33\xce\xbd\x9e\x21\xa5\xbb\x95\xdb\x26\x16\x97\x6a\x8c\x07\xfc\xf4\x11\xf5\xf6\xbc\x6f\x7e\x0b\x57\xac\xa7\x8c\xc2\x79\x0a\x6f\x9b\x89\x88\x58\xac\x9c\x79\xb1\x65\xff\x24\xe6\x66\x77\x53\x1e\x39\xf5\x72\xbe\x5d\x81\xeb\x32\x64\x52\x41\x81\x11\x5f\x32\x78\x02\x57\xbf\xb9\xae\xec\x6a\xf1\x2a\xf2\x8e\x58\x7c\xac\x06\x8a\x1a\x29\x53\xb5\x9a\xd6\x80\xf4\xc2\x45\xb2\xe3\xec\x36\xf5\x99\x40\xd3\x7e\x1d\x3d\xb3\x8e\x13\xed\xb2\x9b\x5c\x0f\x40\x4f\x6f\xf8\x7f\x80\xfc\x8b\xe7\xa2\x25\xff\x22\xfb\xb9\xc8\xb6\xb1\xd7\x33\x0c\x57\x84\x0d\x24\xbc\x75\xb0\x6b\x80\xd3\x0d\xad\x68\x06\x54\x4d\x51\x0a\xf6\xc4\x78\x5e\x82\x3a\xc3\xe0\xb8",
+ "\x35\xc3\xf8\xf0\xdc\x28\x60\x8e\xc9\x42\xcb\x62\x87\x48\x22\x19\xb4\x2b\x2e\xbc\xba\xd9\x2b\x4c\x34\xe7\x7e\x21\xb7\xd9\x3b\x0e\x85\xeb\xf4\x83\xdb\x2d\x4a\x97\x9c\x48\xe5\x8f\x74\x6a\xc3\xdc\xf5\x63\xca\x7e\x1b\x29\x40\x37\x1d\x8d\x83\xbf\x07\x95\xec\x45",
+ 187 },
+ { GCRY_MD_SHA3_512,
+ "\x6b\x01\x87\x10\x44\x6f\x36\x8e\x74\x21\xf1\xbc\x0c\xcf\x56\x2d\x9c\x18\x43\x84\x6b\xc8\xd9\x8d\x1c\x9b\xf7\xd9\xd6\xfc\xb4\x8b\xfc\x3b\xf8\x3b\x36\xd4\x4c\x4f\xa9\x34\x30\xaf\x75\xcd\x19\x0b\xde\x36\xa7\xf9\x2f\x86\x7f\x58\xa8\x03\x90\x0d\xf8\x01\x81\x50\x38\x4d\x85\xd8\x21\x32\xf1\x23\x00\x6a\xc2\xae\xba\x58\xe0\x2a\x03\x7f\xe6\xaf\xbd\x65\xec\xa7\xc4\x49\x77\xdd\x3d\xc7\x4f\x48\xb6\xe7\xa1\xbf\xd5\xcc\x4d\xcf\x24\xe4\xd5\x2e\x92\xbd\x44\x55\x84\x8e\x49\x28\xb0\xea\xc8\xb7\x47\x6f\xe3\xcc\x03\xe8\x62\xaa\x4d\xff\x44\x70\xdb\xfe\xd6\xde\x48\xe4\x10\xf2\x50\x96\x48\x7e\xcf\xc3\x2a\x27\x27\x7f\x3f\x50\x23\xb2\x72\x5a\xde\x46\x1b\x13\x55\x88\x95\x54\xa8\x83\x6c\x9c\xf5\x3b\xd7\x67\xf5\x73\x7d\x55\x18\x4e\xea\x1a\xb3\xf5\x3e\xdd\x09\x76\xc4\x85",
+ "\xb9\x0e\x0c\xc6\xbc\x53\x18\x2c\x4f\x2d\x17\xaa\x51\x39\x1c\x82\x50\xc3\x03\x2a\x12\xda\xf2\xfc\xc6\x41\xb4\x9a\xa8\x1e\xd9\x44\x94\x03\x56\x7b\x75\xd4\x12\x13\x76\xdd\x8c\xc2\xd2\xbd\xba\xfa\x45\x63\x08\xad\x7c\x0c\x13\xba\x85\x61\x9d\x75\x35\x07\x27\xe3",
+ 188 },
+ { GCRY_MD_SHA3_512,
+ "\xc9\x53\x4a\x24\x71\x4b\xd4\xbe\x37\xc8\x8a\x3d\xa1\x08\x2e\xda\x7c\xab\xd1\x54\xc3\x09\xd7\xbd\x67\x0d\xcc\xd9\x5a\xa5\x35\x59\x44\x63\x05\x8a\x29\xf7\x90\x31\xd6\xec\xaa\x9f\x67\x5d\x12\x11\xe9\x35\x9b\xe8\x26\x69\xa7\x9c\x85\x5e\xa8\xd8\x9d\xd3\x8c\x2c\x76\x1d\xdd\x0e\xc0\xce\x9e\x97\x59\x74\x32\xe9\xa1\xbe\xae\x06\x2c\xdd\x71\xed\xfd\xfd\x46\x41\x19\xbe\x9e\x69\xd1\x8a\x7a\x7f\xd7\xce\x0e\x21\x06\xf0\xc8\xb0\xab\xf4\x71\x5e\x2c\xa4\x8e\xf9\xf4\x54\xdc\x20\x3c\x96\x65\x66\x53\xb7\x27\x08\x35\x13\xf8\xef\xb8\x6e\x49\xc5\x13\xbb\x75\x8b\x3b\x05\x2f\xe2\x1f\x1c\x05\xbb\x33\xc3\x71\x29\xd6\xcc\x81\xf1\xae\xf6\xad\xc4\x5b\x0e\x88\x27\xa8\x30\xfe\x54\x5c\xf5\x7d\x09\x55\x80\x2c\x11\x7d\x23\xcc\xb5\x5e\xa2\x8f\x95\xc0\xd8\xc2\xf9\xc5\xa2\x42\xb3\x3f",
+ "\x99\x49\x73\x55\xae\x17\x91\x79\x9d\x11\x53\x6c\x73\x60\x5c\xdd\x14\x96\xc7\x4e\x3e\x93\x0b\x62\x72\xa1\x03\xc3\xaa\x8c\x98\x4d\x2d\x74\xb0\x1a\xe7\x2c\x94\xf2\xa4\xd3\xa0\x69\xea\xc6\xe0\x09\x84\xd2\x1e\xae\x3d\xd7\xb3\x2a\xd0\x82\xb3\x96\x60\x10\x93\xba",
+ 189 },
+ { GCRY_MD_SHA3_512,
+ "\x07\x90\x6c\x87\x29\x7b\x86\x7a\xbf\x45\x76\xe9\xf3\xcc\x7f\x82\xf2\x2b\x15\x4a\xfc\xbf\x29\x3b\x93\x19\xf1\xb0\x58\x4d\xa6\xa4\x0c\x27\xb3\x2e\x0b\x1b\x7f\x41\x2c\x4f\x1b\x82\x48\x0e\x70\xa9\x23\x5b\x12\xec\x27\x09\x0a\x5a\x33\x17\x5a\x2b\xb2\x8d\x8a\xdc\x47\x5c\xef\xe3\x3f\x78\x03\xf8\xce\x27\x96\x72\x17\x38\x1f\x02\xe6\x7a\x3b\x4f\x84\xa7\x1f\x1c\x52\x28\xe0\xc2\xad\x97\x13\x73\xf6\xf6\x72\x62\x4f\xce\xa8\xd1\xa9\xf8\x51\x70\xfa\xd3\x0f\xa0\xbb\xd2\x50\x35\xc3\xb4\x1a\x61\x75\xd4\x67\x99\x8b\xd1\x21\x5f\x6f\x38\x66\xf5\x38\x47\xf9\xcf\x68\xef\x3e\x2f\xbb\x54\xbc\x99\x4d\xe2\x30\x2b\x82\x9c\x5e\xea\x68\xec\x44\x1f\xcb\xaf\xd7\xd1\x6a\xe4\xfe\x9f\xff\x98\xbf\x00\xe5\xbc\x2a\xd5\x4d\xd9\x1f\xf9\xfd\xa4\xdd\x77\xb6\xc7\x54\xa9\x19\x55\xd1\xfb\xaa\xd0",
+ "\xc9\x82\x65\x39\x6f\x32\x78\xfc\x53\x21\x25\xde\xd0\x97\xa6\x85\x1f\xc5\xbf\x37\xca\x32\xec\x26\xf4\x3e\x64\x87\x42\x41\x30\x9f\x56\x8a\x21\x71\x19\xba\x98\x4c\x54\x09\x9f\x88\x99\xac\x94\xb7\x90\x0a\x4d\xd9\xd3\x87\x7e\x18\x37\x1f\x5d\xaf\xd1\x92\x1f\x08",
+ 190 },
+ { GCRY_MD_SHA3_512,
+ "\x58\x8e\x94\xb9\x05\x4a\xbc\x21\x89\xdf\x69\xb8\xba\x34\x34\x1b\x77\xcd\xd5\x28\xe7\x86\x0e\x5d\xef\xca\xa7\x9b\x0c\x9a\x45\x2a\xd4\xb8\x2a\xa3\x06\xbe\x84\x53\x6e\xb7\xce\xdc\xbe\x05\x8d\x7b\x84\xa6\xae\xf8\x26\xb0\x28\xb8\xa0\x27\x1b\x69\xac\x36\x05\xa9\x63\x5e\xa9\xf5\xea\x0a\xa7\x00\xf3\xeb\x78\x35\xbc\x54\x61\x1b\x92\x29\x64\x30\x0c\x95\x3e\xfe\x74\x91\xe3\x67\x7c\x2c\xeb\xe0\x82\x2e\x95\x6c\xd1\x64\x33\xb0\x2c\x68\xc4\xa2\x32\x52\xc3\xf9\xe1\x51\xa4\x16\xb4\x96\x32\x57\xb7\x83\xe0\x38\xf6\xb4\xd5\xc9\xf1\x10\xf8\x71\x65\x2c\x7a\x64\x9a\x7b\xce\xdc\xbc\xcc\x6f\x2d\x07\x25\xbb\x90\x3c\xc1\x96\xba\x76\xc7\x6a\xa9\xf1\x0a\x19\x0b\x1d\x11\x68\x99\x3b\xaa\x9f\xfc\x96\xa1\x65\x52\x16\x77\x34\x58\xbe\xc7\x2b\x0e\x39\xc9\xf2\xc1\x21\x37\x8f\xea\xb4\xe7\x6a",
+ "\xfc\x03\xbe\x19\x3a\x5e\xd0\xe6\xb3\x50\x26\x61\xc2\xd9\xe4\xe2\xa5\x03\xcf\x3f\xdb\x23\x15\x26\xa9\x0c\x3c\x4c\x26\x08\x9c\x78\x7e\xe6\xcb\xf5\x0d\x90\xaf\x61\xc1\x7c\x5d\xf0\xb2\x9c\x37\x3b\x42\x67\x40\xcd\x0d\x6f\xc3\x70\xde\x64\xeb\x21\x64\xbb\xae\xb2",
+ 191 },
+ { GCRY_MD_SHA3_512,
+ "\x08\x95\x9a\x7e\x4b\xaa\xe8\x74\x92\x88\x13\x36\x40\x71\x19\x4e\x29\x39\x77\x2f\x20\xdb\x7c\x31\x57\x07\x89\x87\xc5\x57\xc2\xa6\xd5\xab\xe6\x8d\x52\x0e\xef\x3d\xc4\x91\x69\x2e\x1e\x21\xbc\xd8\x80\xad\xeb\xf6\x3b\xb4\x21\x3b\x50\x89\x7f\xa0\x05\x25\x6e\xd4\x1b\x56\x90\xf7\x8f\x52\x85\x5c\x8d\x91\x68\xa4\xb6\x66\xfc\xe2\xda\x2b\x45\x6d\x7a\x7e\x7c\x17\xab\x5f\x2f\xb1\xee\x90\xb7\x9e\x69\x87\x12\xe9\x63\x71\x59\x83\xfd\x07\x64\x1a\xe4\xb4\xe9\xdc\x73\x20\x3f\xac\x1a\xe1\x1f\xa1\xf8\xc7\x94\x1f\xcc\x82\xea\xb2\x47\xad\xdb\x56\xe2\x63\x84\x47\xe9\xd6\x09\xe6\x10\xb6\x0c\xe0\x86\x65\x6a\xae\xbf\x1d\xa3\xc8\xa2\x31\xd7\xd9\x4e\x2f\xd0\xaf\xe4\x6b\x39\x1f\xf1\x4a\x72\xea\xeb\x3f\x44\xad\x4d\xf8\x58\x66\xde\xf4\x3d\x47\x81\xa0\xb3\x57\x8b\xc9\x96\xc8\x79\x70\xb1\x32",
+ "\xfb\x9c\x3a\x91\x83\xb6\xd2\x51\xbf\x61\xfa\xf1\x84\x34\x55\xcb\x9c\x1b\xe3\x5e\xab\xdc\x13\x1d\x5b\xf3\x8e\x98\x33\x79\x34\x96\x82\x91\xe9\xd6\xdc\x10\x43\x74\xbc\x23\x4f\xf2\x2c\xc2\x3c\xd6\xf3\x38\xe7\xa3\xb0\x19\xcd\xc9\xdf\x6e\x37\x50\xb6\xb0\x1f\xde",
+ 192 },
+ { GCRY_MD_SHA3_512,
+ "\xcb\x2a\x23\x4f\x45\xe2\xec\xd5\x86\x38\x95\xa4\x51\xd3\x89\xa3\x69\xaa\xb9\x9c\xfe\xf0\xd5\xc9\xff\xca\x1e\x6e\x63\xf7\x63\xb5\xc1\x4f\xb9\xb4\x78\x31\x3c\x8e\x8c\x0e\xfe\xb3\xac\x95\x00\xcf\x5f\xd9\x37\x91\xb7\x89\xe6\x7e\xac\x12\xfd\x03\x8e\x25\x47\xcc\x8e\x0f\xc9\xdb\x59\x1f\x33\xa1\xe4\x90\x7c\x64\xa9\x22\xdd\xa2\x3e\xc9\x82\x73\x10\xb3\x06\x09\x85\x54\xa4\xa7\x8f\x05\x02\x62\xdb\x5b\x54\x5b\x15\x9e\x1f\xf1\xdc\xa6\xeb\x73\x4b\x87\x23\x43\xb8\x42\xc5\x7e\xaf\xcf\xda\x84\x05\xee\xdb\xb4\x8e\xf3\x2e\x99\x69\x6d\x13\x59\x79\x23\x5c\x3a\x05\x36\x4e\x37\x1c\x2d\x76\xf1\x90\x2f\x1d\x83\x14\x6d\xf9\x49\x5c\x0a\x6c\x57\xd7\xbf\x9e\xe7\x7e\x80\xf9\x78\x7a\xee\x27\xbe\x1f\xe1\x26\xcd\xc9\xef\x89\x3a\x4a\x7d\xcb\xbc\x36\x7e\x40\xfe\x4e\x1e\xe9\x0b\x42\xea\x25\xaf\x01",
+ "\xf7\x96\x5b\x71\x19\x86\x36\xf1\x62\xd5\xa4\xe0\x8d\x73\xe8\xc8\xa9\xac\x1a\xdd\xbd\xfd\x7c\x18\x0c\x48\x9c\xca\x73\x60\xb3\xfe\xe3\xa4\x28\x61\x54\x46\x0b\xf8\x67\x92\x3b\x34\x8b\xfe\x32\xe7\x9d\x91\x39\xa0\xcb\x52\xc4\x6f\xa2\x07\x85\xfa\xea\xe0\xa8\xbc",
+ 193 },
+ { GCRY_MD_SHA3_512,
+ "\xd1\x6b\xea\xdf\x02\xab\x1d\x4d\xc6\xf8\x8b\x8c\x45\x54\xc5\x1e\x86\x6d\xf8\x30\xb8\x9c\x06\xe7\x86\xa5\xf8\x75\x7e\x89\x09\x31\x0a\xf5\x1c\x84\x0e\xfe\x8d\x20\xb3\x53\x31\xf4\x35\x5d\x80\xf7\x32\x95\x97\x46\x53\xdd\xd6\x20\xcd\xde\x47\x30\xfb\x6c\x8d\x0d\x2d\xcb\x2b\x45\xd9\x2d\x4f\xbd\xb5\x67\xc0\xa3\xe8\x6b\xd1\xa8\xa7\x95\xaf\x26\xfb\xf2\x9f\xc6\xc6\x59\x41\xcd\xdb\x09\x0f\xf7\xcd\x23\x0a\xc5\x26\x8a\xb4\x60\x6f\xcc\xba\x9e\xde\xd0\xa2\xb5\xd0\x14\xee\x0c\x34\xf0\xb2\x88\x1a\xc0\x36\xe2\x4e\x15\x1b\xe8\x9e\xeb\x6c\xd9\xa7\xa7\x90\xaf\xcc\xff\x23\x4d\x7c\xb1\x1b\x99\xeb\xf5\x8c\xd0\xc5\x89\xf2\x0b\xda\xc4\xf9\xf0\xe2\x8f\x75\xe3\xe0\x4e\x5b\x3d\xeb\xce\x60\x7a\x49\x6d\x84\x8d\x67\xfa\x7b\x49\x13\x2c\x71\xb8\x78\xfd\x55\x57\xe0\x82\xa1\x8e\xca\x1f\xbd\xa9\x4d\x4b",
+ "\x53\x37\x47\x74\x87\xa0\xaf\x43\xeb\x7b\x99\x52\x93\xca\x2b\xef\x6e\xab\x24\x32\xb1\x33\x3d\xca\xea\xd7\x06\x44\x06\xe2\x28\x61\xfc\xea\x62\x3f\xd8\xb8\x5b\x30\x46\x57\x87\x35\x2a\x36\xc9\x43\x61\x0f\x14\x58\xfd\x22\xe3\xf5\x5d\xdd\x19\x5a\x6a\xca\xa3\x74",
+ 194 },
+ { GCRY_MD_SHA3_512,
+ "\x8f\x65\xf6\xbc\x59\xa8\x57\x05\x01\x6e\x2b\xae\x7f\xe5\x79\x80\xde\x31\x27\xe5\xab\x27\x5f\x57\x3d\x33\x4f\x73\xf8\x60\x31\x06\xec\x35\x53\x01\x66\x08\xef\x2d\xd6\xe6\x9b\x24\xbe\x0b\x71\x13\xbf\x6a\x76\x0b\xa6\xe9\xce\x1c\x48\xf9\xe1\x86\x01\x2c\xf9\x6a\x1d\x48\x49\xd7\x5d\xf5\xbb\x83\x15\x38\x7f\xd7\x8e\x9e\x15\x3e\x76\xf8\xba\x7e\xc6\xc8\x84\x98\x10\xf5\x9f\xb4\xbb\x9b\x00\x43\x18\x21\x0b\x37\xf1\x29\x95\x26\x86\x6f\x44\x05\x9e\x01\x7e\x22\xe9\x6c\xbe\x41\x86\x99\xd0\x14\xc6\xea\x01\xc9\xf0\x03\x8b\x10\x29\x98\x84\xdb\xec\x31\x99\xbb\x05\xad\xc9\x4e\x95\x5a\x15\x33\x21\x9c\x11\x15\xfe\xd0\xe5\xf2\x12\x28\xb0\x71\xf4\x0d\xd5\x7c\x42\x40\xd9\x8d\x37\xb7\x3e\x41\x2f\xe0\xfa\x47\x03\x12\x0d\x7c\x0c\x67\x97\x2e\xd2\x33\xe5\xde\xb3\x00\xa2\x26\x05\x47\x2f\xa3\xa3\xba\x86",
+ "\x28\xab\x5c\x62\x98\xa6\x02\xae\x51\xee\xec\x40\x80\x24\x5f\x7c\xa1\x0f\x9a\x8c\x30\x4f\x22\xb5\xaa\x88\xd0\xe4\x92\x26\xc0\x1c\x2f\xd3\xcc\x5d\x8e\x99\x30\x97\x67\x81\x6e\x4f\x6d\x52\x71\x98\x76\x06\x54\x95\xdd\xb6\x1d\xd1\x13\xcf\xff\x06\xb1\x1d\x86\x04",
+ 195 },
+ { GCRY_MD_SHA3_512,
+ "\x84\x89\x1e\x52\xe0\xd4\x51\x81\x32\x10\xc3\xfd\x63\x5b\x39\xa0\x3a\x6b\x7a\x73\x17\xb2\x21\xa7\xab\xc2\x70\xdf\xa9\x46\xc4\x26\x69\xaa\xcb\xbb\xdf\x80\x1e\x15\x84\xf3\x30\xe2\x8c\x72\x98\x47\xea\x14\x15\x2b\xd6\x37\xb3\xd0\xf2\xb3\x8b\x4b\xd5\xbf\x9c\x79\x1c\x58\x80\x62\x81\x10\x3a\x3e\xab\xba\xed\xe5\xe7\x11\xe5\x39\xe6\xa8\xb2\xcf\x29\x7c\xf3\x51\xc0\x78\xb4\xfa\x8f\x7f\x35\xcf\x61\xbe\xbf\x88\x14\xbf\x24\x8a\x01\xd4\x1e\x86\xc5\x71\x5e\xa4\x0c\x63\xf7\x37\x53\x79\xa7\xeb\x1d\x78\xf2\x76\x22\xfb\x46\x8a\xb7\x84\xaa\xab\xa4\xe5\x34\xa6\xdf\xd1\xdf\x6f\xa1\x55\x11\x34\x1e\x72\x5e\xd2\xe8\x7f\x98\x73\x7c\xcb\x7b\x6a\x6d\xfa\xe4\x16\x47\x74\x72\xb0\x46\xbf\x18\x11\x18\x7d\x15\x1b\xfa\x9f\x7b\x2b\xf9\xac\xdb\x23\xa3\xbe\x50\x7c\xdf\x14\xcf\xdf\x51\x7d\x2c\xb5\xfb\x9e\x4a\xb6",
+ "\x2a\xee\xac\x01\x5d\x93\x24\x5f\x6b\xf7\x27\xcd\x18\x28\x94\x09\x7b\x90\x2c\xd4\x07\xd7\xe0\xdd\x06\xda\x1a\x63\xf4\x45\x1c\x65\x7f\xf3\x9f\x92\x5e\x7c\x8a\x89\x4a\xe5\x93\xd1\x1e\xbc\x2d\x5d\x1d\xe3\xd9\xa1\x80\x18\x80\x67\x19\x27\x7d\x99\x3f\x7f\xab\xed",
+ 196 },
+ { GCRY_MD_SHA3_512,
+ "\xfd\xd7\xa9\x43\x3a\x3b\x4a\xfa\xbd\x7a\x3a\x5e\x34\x57\xe5\x6d\xeb\xf7\x8e\x84\xb7\xa0\xb0\xca\x0e\x8c\x6d\x53\xbd\x0c\x2d\xae\x31\xb2\x70\x0c\x61\x28\x33\x4f\x43\x98\x1b\xe3\xb2\x13\xb1\xd7\xa1\x18\xd5\x9c\x7e\x6b\x64\x93\xa8\x6f\x86\x6a\x16\x35\xc1\x28\x59\xcf\xb9\xad\x17\x46\x0a\x77\xb4\x52\x2a\x5c\x18\x83\xc3\xd6\xac\xc8\x6e\x61\x62\x66\x7e\xc4\x14\xe9\xa1\x04\xaa\x89\x20\x53\xa2\xb1\xd7\x21\x65\xa8\x55\xba\xcd\x8f\xaf\x80\x34\xa5\xdd\x9b\x71\x6f\x47\xa0\x81\x8c\x09\xbb\x6b\xaf\x22\xaa\x50\x3c\x06\xb4\xca\x26\x1f\x55\x77\x61\x98\x9d\x2a\xfb\xd8\x8b\x6a\x67\x8a\xd1\x28\xaf\x68\x67\x21\x07\xd0\xf1\xfc\x73\xc5\xca\x74\x04\x59\x29\x7b\x32\x92\xb2\x81\xe9\x3b\xce\xb7\x61\xbd\xe7\x22\x1c\x3a\x55\x70\x8e\x5e\xc8\x44\x72\xcd\xdc\xaa\x84\xec\xf2\x37\x23\xcc\x09\x91\x35\x5c\x62\x80",
+ "\xd0\xa1\x19\x61\x7b\x7e\x30\xc2\xa8\x5e\xcb\xb3\xbb\xf3\x25\xdd\xd5\x89\x43\x1c\x8c\x2e\x2f\x9f\xc6\xe3\x24\xa6\xed\x8b\xaf\x11\x87\x0a\x80\x55\x6c\xc0\x68\x8f\xee\x4d\xb7\x0f\x22\xb9\x42\x4b\x4f\x37\xa0\xf1\xe7\xea\x31\x46\x84\xda\x31\xbf\x47\x3b\x3f\x34",
+ 197 },
+ { GCRY_MD_SHA3_512,
+ "\x70\xa4\x0b\xfb\xef\x92\x27\x7a\x1a\xad\x72\xf6\xb7\x9d\x01\x77\x19\x7c\x4e\xbd\x43\x26\x68\xcf\xec\x05\xd0\x99\xac\xcb\x65\x10\x62\xb5\xdf\xf1\x56\xc0\xb2\x73\x36\x68\x7a\x94\xb2\x66\x79\xcf\xdd\x9d\xaf\x7a\xd2\x04\x33\x8d\xd9\xc4\xd1\x41\x14\x03\x3a\x5c\x22\x5b\xd1\x1f\x21\x7b\x5f\x47\x32\xda\x16\x7e\xe3\xf9\x39\x26\x2d\x40\x43\xfc\x9c\xba\x92\x30\x3b\x7b\x5e\x96\xae\xa1\x2a\xdd\xa6\x48\x59\xdf\x4b\x86\xe9\xee\x0b\x58\xe3\x90\x91\xe6\xb1\x88\xb4\x08\xac\x94\xe1\x29\x4a\x89\x11\x24\x5e\xe3\x61\xe6\x0e\x60\x1e\xff\x58\xd1\xd3\x76\x39\xf3\x75\x3b\xec\x80\xeb\xb4\xef\xde\x25\x81\x74\x36\x07\x66\x23\xfc\x65\x41\x5f\xe5\x1d\x1b\x02\x80\x36\x6d\x12\xc5\x54\xd8\x67\x43\xf3\xc3\xb6\x57\x2e\x40\x03\x61\xa6\x07\x26\x13\x14\x41\xba\x49\x3a\x83\xfb\xe9\xaf\xda\x90\xf7\xaf\x1a\xe7\x17\x23\x8d",
+ "\x1c\x88\x78\x98\x85\xdc\xcc\x9a\xe8\x10\x29\xac\xf0\xb6\xc9\xd0\x83\xcd\xb9\x77\x4c\x34\x5f\x1c\x75\x5e\x54\xc4\x5e\x9a\xf6\x3a\x70\xdc\x2a\xba\xef\xeb\x1a\xd4\x16\xf1\xbd\x3d\x9b\x69\xd4\xc4\x40\x4d\x22\xc8\x5e\x63\x6a\x47\x03\x76\x9c\x01\x12\xb5\x50\xb8",
+ 198 },
+ { GCRY_MD_SHA3_512,
+ "\x74\x35\x6e\x44\x9f\x4b\xf8\x64\x4f\x77\xb1\x4f\x4d\x67\xcb\x6b\xd9\xc1\xf5\xae\x35\x76\x21\xd5\xb8\x14\x7e\x56\x2b\x65\xc6\x65\x85\xca\xf2\xe4\x91\xb4\x85\x29\xa0\x1a\x34\xd2\x26\xd4\x36\x95\x91\x53\x81\x53\x80\xd5\x68\x9e\x30\xb3\x53\x57\xcd\xac\x6e\x08\xd3\xf2\xb0\xe8\x8e\x20\x06\x00\xd6\x2b\xd9\xf5\xea\xf4\x88\xdf\x86\xa4\x47\x0e\xa2\x27\x00\x61\x82\xe4\x48\x09\x00\x98\x68\xc4\xc2\x80\xc4\x3d\x7d\x64\xa5\x26\x8f\xa7\x19\x07\x49\x60\x08\x7b\x3a\x6a\xbc\x83\x78\x82\xf8\x82\xc8\x37\x83\x45\x35\x92\x93\x89\xa1\x2b\x2c\x78\x18\x7e\x2e\xa0\x7e\xf8\xb8\xee\xf2\x7d\xc8\x50\x02\xc3\xae\x35\xf1\xa5\x0b\xee\x6a\x1c\x48\xba\x7e\x17\x5f\x33\x16\x67\x0b\x27\x98\x34\x72\xaa\x6a\x61\xee\xd0\xa6\x83\xa3\x9e\xe3\x23\x08\x06\x20\xea\x44\xa9\xf7\x44\x11\xae\x5c\xe9\x90\x30\x52\x8f\x9a\xb4\x9c\x79\xf2",
+ "\xf5\x2d\x7d\xd7\xff\x24\x8a\x1b\xca\x7b\x71\x4f\x14\xa7\x9d\xf5\x76\x6f\xd6\x7c\x00\x31\xa4\x71\xcc\x50\x9f\x35\x16\xd7\xc3\x48\xc3\x3f\x7d\x4b\x1c\xa3\x31\xb9\x32\x38\x96\xb7\x07\x4e\x10\xa8\x91\xce\xa8\x51\xf9\xac\x20\x24\x58\x12\xb8\xcf\xaa\x55\x63\x52",
+ 199 },
+ { GCRY_MD_SHA3_512,
+ "\x8c\x37\x98\xe5\x1b\xc6\x84\x82\xd7\x33\x7d\x3a\xbb\x75\xdc\x9f\xfe\x86\x07\x14\xa9\xad\x73\x55\x1e\x12\x00\x59\x86\x0d\xde\x24\xab\x87\x32\x72\x22\xb6\x4c\xf7\x74\x41\x5a\x70\xf7\x24\xcd\xf2\x70\xde\x3f\xe4\x7d\xda\x07\xb6\x1c\x9e\xf2\xa3\x55\x1f\x45\xa5\x58\x48\x60\x24\x8f\xab\xde\x67\x6e\x1c\xd7\x5f\x63\x55\xaa\x3e\xae\xab\xe3\xb5\x1d\xc8\x13\xd9\xfb\x2e\xaa\x4f\x0f\x1d\x9f\x83\x4d\x7c\xad\x9c\x7c\x69\x5a\xe8\x4b\x32\x93\x85\xbc\x0b\xef\x89\x5b\x9f\x1e\xdf\x44\xa0\x3d\x4b\x41\x0c\xc2\x3a\x79\xa6\xb6\x2e\x4f\x34\x6a\x5e\x8d\xd8\x51\xc2\x85\x79\x95\xdd\xbf\x5b\x2d\x71\x7a\xeb\x84\x73\x10\xe1\xf6\xa4\x6a\xc3\xd2\x6a\x7f\x9b\x44\x98\x5a\xf6\x56\xd2\xb7\xc9\x40\x6e\x8a\x9e\x8f\x47\xdc\xb4\xef\x6b\x83\xca\xac\xf9\xae\xfb\x61\x18\xbf\xcf\xf7\xe4\x4b\xef\x69\x37\xeb\xdd\xc8\x91\x86\x83\x9b\x77",
+ "\xa8\xae\xe4\x2a\x77\xc9\xb6\x38\x7d\xc9\x73\x19\x58\x19\x59\xd9\xbd\x87\x8d\x06\x14\x87\xfd\x06\x9a\xca\x04\xd6\xf8\x4d\x34\x7e\x23\x58\x7a\x6c\x7c\x56\x32\x9b\x2d\xf8\x8c\x56\xc7\x10\x0e\xd5\x1a\xce\x5b\x5f\x77\x8d\x65\x47\x8f\x05\x9c\xaf\xd6\xc0\x98\xfd",
+ 200 },
+ { GCRY_MD_SHA3_512,
+ "\xfa\x56\xbf\x73\x0c\x4f\x83\x95\x87\x51\x89\xc1\x0c\x4f\xb2\x51\x60\x57\x57\xa8\xfe\xcc\x31\xf9\x73\x7e\x3c\x25\x03\xb0\x26\x08\xe6\x73\x1e\x85\xd7\xa3\x83\x93\xc6\x7d\xe5\x16\xb8\x53\x04\x82\x4b\xfb\x13\x5e\x33\xbf\x22\xb3\xa2\x3b\x91\x3b\xf6\xac\xd2\xb7\xab\x85\x19\x8b\x81\x87\xb2\xbc\xd4\x54\xd5\xe3\x31\x8c\xac\xb3\x2f\xd6\x26\x1c\x31\xae\x7f\x6c\x54\xef\x6a\x7a\x2a\x4c\x9f\x3e\xcb\x81\xce\x35\x55\xd4\xf0\xad\x46\x6d\xd4\xc1\x08\xa9\x03\x99\xd7\x00\x41\x99\x7c\x3b\x25\x34\x5a\x96\x53\xf3\xc9\xa6\x71\x1a\xb1\xb9\x1d\x6a\x9d\x22\x16\x44\x2d\xa2\xc9\x73\xcb\xd6\x85\xee\x76\x43\xbf\xd7\x73\x27\xa2\xf7\xae\x9c\xb2\x83\x62\x0a\x08\x71\x6d\xfb\x46\x2e\x5c\x1d\x65\x43\x2c\xa9\xd5\x6a\x90\xe8\x11\x44\x3c\xd1\xec\xb8\xf0\xde\x17\x9c\x9c\xb4\x8b\xa4\xf6\xfe\xc3\x60\xc6\x6f\x25\x2f\x6e\x64\xed\xc9\x6b",
+ "\x4b\x96\x1c\x4b\xb6\x03\x5e\x7b\xdd\xa2\xe1\xa3\xb6\xf9\xcd\x52\xd1\x78\x98\x66\x04\x4c\x4a\x92\x56\x93\xbe\xa8\x8f\x65\xd0\x46\x23\x8b\xbe\xb4\xe7\xd3\xb0\x60\xe4\x72\x88\x04\x14\x07\x39\x2b\x29\x1a\xe6\x10\xba\x70\xd6\xb4\xd6\x4e\x74\xe7\xa7\xd0\x25\x6f",
+ 201 },
+ { GCRY_MD_SHA3_512,
+ "\xb6\x13\x4f\x9c\x3e\x91\xdd\x80\x00\x74\x0d\x00\x9d\xd8\x06\x24\x08\x11\xd5\x1a\xb1\x54\x6a\x97\x4b\xcb\x18\xd3\x44\x64\x2b\xaa\x5c\xd5\x90\x3a\xf8\x4d\x58\xec\x5b\xa1\x73\x01\xd5\xec\x0f\x10\xcc\xd0\x50\x9c\xbb\x3f\xd3\xff\xf9\x17\x2d\x19\x3a\xf0\xf7\x82\x25\x2f\xd1\x33\x8c\x72\x44\xd4\x0e\x0e\x42\x36\x22\x75\xb2\x2d\x01\xc4\xc3\x38\x9f\x19\xdd\x69\xbd\xf9\x58\xeb\xe2\x8e\x31\xa4\xff\xe2\xb5\xf1\x8a\x87\x83\x1c\xfb\x70\x95\xf5\x8a\x87\xc9\xfa\x21\xdb\x72\xba\x26\x93\x79\xb2\xdc\x23\x84\xb3\xda\x95\x3c\x79\x25\x76\x1f\xed\x32\x46\x20\xac\xea\x43\x5e\x52\xb4\x24\xa7\x72\x3f\x6a\x23\x57\x37\x41\x57\xa3\x4c\xd8\x25\x23\x51\xc2\x5a\x1b\x23\x28\x26\xce\xfe\x1b\xd3\xe7\x0f\xfc\x15\xa3\x1e\x7c\x05\x98\x21\x9d\x7f\x00\x43\x62\x94\xd1\x18\x91\xb8\x24\x97\xbc\x78\xaa\x53\x63\x89\x2a\x24\x95\xdf\x8c\x1e\xef",
+ "\xc0\x51\x5b\x65\xb6\x40\xb3\xff\xd0\xa1\x58\x2a\x54\xf4\xc8\xfb\x35\xc1\x09\xb7\xfb\x47\x26\x66\xe0\x43\xd3\xc0\x0a\xe3\xe0\xe0\xfa\x15\x6c\x4c\xef\xb4\x6b\x5b\x7b\x4c\x0e\x48\x06\x23\xe1\xa2\x60\x18\xbd\xae\xdc\x3e\x27\xd9\xc0\xd4\x4c\x3e\x1d\x86\x20\x15",
+ 202 },
+ { GCRY_MD_SHA3_512,
+ "\xc9\x41\xcd\xb9\xc2\x8a\xb0\xa7\x91\xf2\xe5\xc8\xe8\xbb\x52\x85\x06\x26\xaa\x89\x20\x5b\xec\x3a\x7e\x22\x68\x23\x13\xd1\x98\xb1\xfa\x33\xfc\x72\x95\x38\x13\x54\x85\x87\x58\xae\x6c\x8e\xc6\xfa\xc3\x24\x5c\x6e\x45\x4d\x16\xfa\x2f\x51\xc4\x16\x6f\xab\x51\xdf\x27\x28\x58\xf2\xd6\x03\x77\x0c\x40\x98\x7f\x64\x44\x2d\x48\x7a\xf4\x9c\xd5\xc3\x99\x1c\xe8\x58\xea\x2a\x60\xda\xb6\xa6\x5a\x34\x41\x49\x65\x93\x39\x73\xac\x24\x57\x08\x9e\x35\x91\x60\xb7\xcd\xed\xc4\x2f\x29\xe1\x0a\x91\x92\x17\x85\xf6\xb7\x22\x4e\xe0\xb3\x49\x39\x3c\xdc\xff\x61\x51\xb5\x0b\x37\x7d\x60\x95\x59\x92\x3d\x09\x84\xcd\xa6\x00\x08\x29\xb9\x16\xab\x68\x96\x69\x3e\xf6\xa2\x19\x9b\x3c\x22\xf7\xdc\x55\x00\xa1\x5b\x82\x58\x42\x0e\x31\x4c\x22\x2b\xc0\x00\xbc\x4e\x54\x13\xe6\xdd\x82\xc9\x93\xf8\x33\x0f\x5c\x6d\x1b\xe4\xbc\x79\xf0\x8a\x1a\x0a\x46",
+ "\x45\xc5\x84\x56\x4d\x9e\x0b\x82\x39\xcc\x12\x84\x93\x9b\xa4\x07\xa8\xe5\xe9\x81\x69\x1e\xab\x6a\x04\xd9\x35\x4c\x9c\x85\x5e\x40\x0b\x30\x37\x15\x11\x22\xce\xd2\x37\x63\x6e\x61\xa7\xff\x29\x05\xe0\x21\x3a\x6d\x07\x30\x6c\x45\x9e\x21\x89\xe3\xe6\xa9\xe0\xb8",
+ 203 },
+ { GCRY_MD_SHA3_512,
+ "\x44\x99\xef\xff\xac\x4b\xce\xa5\x27\x47\xef\xd1\xe4\xf2\x0b\x73\xe4\x87\x58\xbe\x91\x5c\x88\xa1\xff\xe5\x29\x9b\x0b\x00\x58\x37\xa4\x6b\x2f\x20\xa9\xcb\x3c\x6e\x64\xa9\xe3\xc5\x64\xa2\x7c\x0f\x1c\x6a\xd1\x96\x03\x73\x03\x6e\xc5\xbf\xe1\xa8\xfc\x6a\x43\x5c\x21\x85\xed\x0f\x11\x4c\x50\xe8\xb3\xe4\xc7\xed\x96\xb0\x6a\x03\x68\x19\xc9\x46\x3e\x86\x4a\x58\xd6\x28\x6f\x78\x5e\x32\xa8\x04\x44\x3a\x56\xaf\x0b\x4d\xf6\xab\xc5\x7e\xd5\xc2\xb1\x85\xdd\xee\x84\x89\xea\x08\x0d\xee\xee\x66\xaa\x33\xc2\xe6\xda\xb3\x62\x51\xc4\x02\x68\x2b\x68\x24\x82\x1f\x99\x8c\x32\x16\x31\x64\x29\x8e\x1f\xaf\xd3\x1b\xab\xbc\xff\xb5\x94\xc9\x18\x88\xc6\x21\x90\x79\xd9\x07\xfd\xb4\x38\xed\x89\x52\x9d\x6d\x96\x21\x2f\xd5\x5a\xbe\x20\x39\x9d\xbe\xfd\x34\x22\x48\x50\x74\x36\x93\x1c\xde\xad\x49\x6e\xb6\xe4\xa8\x03\x58\xac\xc7\x86\x47\xd0\x43",
+ "\x13\x67\x23\x35\x08\x57\xe0\x37\x56\xf0\x2e\x60\x45\x1a\x28\xe7\x11\x61\x19\x27\xb8\x13\x6d\xcf\xf3\xe5\x67\xdc\x61\x8f\xf3\x6b\x31\x00\x73\x7c\x97\x81\xb9\xc8\x4a\x57\x67\x45\xc1\xe6\xbe\x03\x0d\xac\x88\x03\xa7\x14\x64\xaf\x39\xdb\x94\xd0\x02\x53\xaf\x3e",
+ 204 },
+ { GCRY_MD_SHA3_512,
+ "\xee\xcb\xb8\xfd\xfa\x4d\xa6\x21\x70\xfd\x06\x72\x7f\x69\x7d\x81\xf8\x3f\x60\x1f\xf6\x1e\x47\x81\x05\xd3\xcb\x75\x02\xf2\xc8\x9b\xf3\xe8\xf5\x6e\xdd\x46\x9d\x04\x98\x07\xa3\x88\x82\xa7\xee\xfb\xc8\x5f\xc9\xa9\x50\x95\x2e\x9f\xa8\x4b\x8a\xfe\xbd\x3c\xe7\x82\xd4\xda\x59\x80\x02\x82\x7b\x1e\xb9\x88\x82\xea\x1f\x0a\x8f\x7a\xa9\xce\x01\x3a\x6e\x9b\xc4\x62\xfb\x66\xc8\xd4\xa1\x8d\xa2\x14\x01\xe1\xb9\x33\x56\xeb\x12\xf3\x72\x5b\x6d\xb1\x68\x4f\x23\x00\xa9\x8b\x9a\x11\x9e\x5d\x27\xff\x70\x4a\xff\xb6\x18\xe1\x27\x08\xe7\x7e\x6e\x5f\x34\x13\x9a\x5a\x41\x13\x1f\xd1\xd6\x33\x6c\x27\x2a\x8f\xc3\x70\x80\xf0\x41\xc7\x13\x41\xbe\xe6\xab\x55\x0c\xb4\xa2\x0a\x6d\xdb\x6a\x8e\x02\x99\xf2\xb1\x4b\xc7\x30\xc5\x4b\x8b\x1c\x1c\x48\x7b\x49\x4b\xdc\xcf\xd3\xa5\x35\x35\xab\x2f\x23\x15\x90\xbf\x2c\x40\x62\xfd\x2a\xd5\x8f\x90\x6a\x2d\x0d",
+ "\xc0\xf7\x71\x3a\xa0\x21\xa0\x45\x25\xf7\x51\x72\x2a\x9a\xe5\xc4\xc7\x93\x4d\x0a\x28\x6f\x1f\xb0\x58\x23\xd8\x6a\x96\x25\x1c\x04\xde\xcd\x96\x0d\x8d\x4d\x66\xe2\xc5\x65\xe6\x20\x7a\x49\x61\x2e\x1e\xfd\xe3\x86\x53\x68\x54\xb6\xab\x9a\x48\x07\xb0\xa1\x45\xbe",
+ 205 },
+ { GCRY_MD_SHA3_512,
+ "\xe6\x4f\x3e\x4a\xce\x5c\x84\x18\xd6\x5f\xec\x2b\xc5\xd2\xa3\x03\xdd\x45\x80\x34\x73\x6e\x3b\x0d\xf7\x19\x09\x8b\xe7\xa2\x06\xde\xaf\x52\xd6\xba\x82\x31\x6c\xaf\x33\x0e\xf8\x52\x37\x51\x88\xcd\xe2\xb3\x9c\xc9\x4a\xa4\x49\x57\x8a\x7e\x2a\x8e\x3f\x5a\x9d\x68\xe8\x16\xb8\xd1\x68\x89\xfb\xc0\xeb\xf0\x93\x9d\x04\xf6\x30\x33\xae\x9a\xe2\xbd\xab\x73\xb8\x8c\x26\xd6\xbd\x25\xee\x46\x0e\xe1\xef\x58\xfb\x0a\xfa\x92\xcc\x53\x9f\x8c\x76\xd3\xd0\x97\xe7\xa6\xa6\x3e\xbb\x9b\x58\x87\xed\xf3\xcf\x07\x60\x28\xc5\xbb\xd5\xb9\xdb\x32\x11\x37\x1a\xd3\xfe\x12\x1d\x4e\x9b\xf4\x42\x29\xf4\xe1\xec\xf5\xa0\xf9\xf0\xeb\xa4\xd5\xce\xb7\x28\x78\xab\x22\xc3\xf0\xeb\x5a\x62\x53\x23\xac\x66\xf7\x06\x1f\x4a\x81\xfa\xc8\x34\x47\x1e\x0c\x59\x55\x3f\x10\x84\x75\xfe\x29\x0d\x43\xe6\xa0\x55\xae\x3e\xe4\x6f\xb6\x74\x22\xf8\x14\xa6\x8c\x4b\xe3\xe8\xc9",
+ "\xfe\x1c\xb6\x7d\x77\xfb\x46\x3f\x77\x74\x7f\xed\x29\x2a\x98\x9a\x34\x10\x44\xa8\xb6\x5f\xa1\xdf\x14\x41\xaa\x41\xa5\xc7\x95\x91\x66\x26\xe0\xe4\x79\xfd\x0b\xa7\xf9\xb1\xdc\x15\xfe\xd2\x45\xb9\x95\x98\xd3\x53\x59\x83\x4e\x8f\xd2\x5c\xf1\x96\x85\x21\x9b\xe2",
+ 206 },
+ { GCRY_MD_SHA3_512,
+ "\xd2\xcb\x2d\x73\x30\x33\xf9\xe9\x13\x95\x31\x28\x08\x38\x3c\xc4\xf0\xca\x97\x4e\x87\xec\x68\x40\x0d\x52\xe9\x6b\x3f\xa6\x98\x4a\xc5\x8d\x9a\xd0\x93\x8d\xde\x5a\x97\x30\x08\xd8\x18\xc4\x96\x07\xd9\xde\x22\x84\xe7\x61\x8f\x1b\x8a\xed\x83\x72\xfb\xd5\x2e\xd5\x45\x57\xaf\x42\x20\xfa\xc0\x9d\xfa\x84\x43\x01\x16\x99\xb9\x7d\x74\x3f\x8f\x2b\x1a\xef\x35\x37\xeb\xb4\x5d\xcc\x9e\x13\xdf\xb4\x38\x42\x8e\xe1\x90\xa4\xef\xdb\x3c\xae\xb7\xf3\x93\x31\x17\xbf\x63\xab\xdc\x7e\x57\xbe\xb4\x17\x1c\x7e\x1a\xd2\x60\xab\x05\x87\x80\x6c\x4d\x13\x7b\x63\x16\xb5\x0a\xbc\x9c\xce\x0d\xff\x3a\xca\xda\x47\xbb\xb8\x6b\xe7\x77\xe6\x17\xbb\xe5\x78\xff\x45\x19\x84\x4d\xb3\x60\xe0\xa9\x6c\x67\x01\x29\x0e\x76\xbb\x95\xd2\x6f\x0f\x80\x4c\x8a\x4f\x27\x17\xea\xc4\xe7\xde\x9f\x2c\xff\x3b\xbc\x55\xa1\x7e\x77\x6c\x0d\x02\x85\x60\x32\xa6\xcd\x10\xad\x28\x38",
+ "\x40\x43\xcd\xd3\xf0\xea\x79\x3e\x49\xa8\xec\x38\x2f\x80\x71\xf6\x02\x0b\x52\x9c\xf8\xc8\x2e\x96\x94\x29\x11\x7b\x36\x21\x29\xb7\x68\x9d\x3f\x1e\xa7\xff\x77\xee\x50\x26\x3c\xec\xda\xc5\xa4\x3a\xa2\xae\xe9\x7c\xf3\xe6\x65\xcc\xf5\x35\xf6\xde\x65\xad\x01\x00",
+ 207 },
+ { GCRY_MD_SHA3_512,
+ "\xf2\x99\x89\x55\x61\x3d\xd4\x14\xcc\x11\x1d\xf5\xce\x30\xa9\x95\xbb\x79\x2e\x26\x0b\x0e\x37\xa5\xb1\xd9\x42\xfe\x90\x17\x1a\x4a\xc2\xf6\x6d\x49\x28\xd7\xad\x37\x7f\x4d\x05\x54\xcb\xf4\xc5\x23\xd2\x1f\x6e\x5f\x37\x9d\x6f\x4b\x02\x8c\xdc\xb9\xb1\x75\x8d\x3b\x39\x66\x32\x42\xff\x3c\xb6\xed\xe6\xa3\x6a\x6f\x05\xdb\x3b\xc4\x1e\x0d\x86\x1b\x38\x4b\x6d\xec\x58\xbb\x09\x6d\x0a\x42\x2f\xd5\x42\xdf\x17\x5e\x1b\xe1\x57\x1f\xb5\x2a\xe6\x6f\x2d\x86\xa2\xf6\x82\x4a\x8c\xfa\xac\xba\xc4\xa7\x49\x2a\xd0\x43\x3e\xeb\x15\x45\x4a\xf8\xf3\x12\xb3\xb2\xa5\x77\x75\x0e\x3e\xfb\xd3\x70\xe8\xa8\xca\xc1\x58\x25\x81\x97\x1f\xba\x3b\xa4\xbd\x0d\x76\xe7\x18\xda\xcf\x84\x33\xd3\x3a\x59\xd2\x87\xf8\xcc\x92\x23\x4e\x7a\x27\x10\x41\xb5\x26\xe3\x89\xef\xb0\xe4\x0b\x6a\x18\xb3\xaa\xf6\x58\xe8\x2e\xd1\xc7\x86\x31\xfd\x23\xb4\xc3\xeb\x27\xc3\xfa\xec\x86\x85",
+ "\x73\x92\xbd\x44\x5f\x58\xcd\x5d\x7d\x3c\xa9\x85\x79\xcb\xaa\x9a\x94\x37\xd0\xc9\x5e\x79\x32\xb4\x00\x41\x17\xf2\x07\xf8\xaa\x39\x15\x6b\xc4\x25\x37\xb0\xc7\x90\x15\x0d\x44\x3c\x2d\x68\xc2\xc4\x3e\x36\x2d\xf9\xd0\x19\x60\x17\x97\x16\x2e\x63\x07\x69\x36\xc3",
+ 208 },
+ { GCRY_MD_SHA3_512,
+ "\x44\x77\x97\xe2\x89\x9b\x72\xa3\x56\xba\x55\xbf\x4d\xf3\xac\xca\x6c\xdb\x10\x41\xeb\x47\x7b\xd1\x83\x4a\x9f\x9a\xcb\xc3\x40\xa2\x94\xd7\x29\xf2\xf9\x7d\xf3\xa6\x10\xbe\x0f\xf1\x5e\xdb\x9c\x6d\x5d\xb4\x16\x44\xb9\x87\x43\x60\x14\x0f\xc6\x4f\x52\xaa\x03\xf0\x28\x6c\x8a\x64\x06\x70\x06\x7a\x84\xe0\x17\x92\x6a\x70\x43\x8d\xb1\xbb\x36\x1d\xef\xee\x73\x17\x02\x14\x25\xf8\x82\x1d\xef\x26\xd1\xef\xd7\x7f\xc8\x53\xb8\x18\x54\x5d\x05\x5a\xdc\x92\x84\x79\x6e\x58\x3c\x76\xe6\xfe\x74\xc9\xac\x25\x87\xaa\x46\xaa\x8f\x88\x04\xf2\xfe\xb5\x83\x6c\xc4\xb3\xab\xab\xab\x84\x29\xa5\x78\x3e\x17\xd5\x99\x9f\x32\x24\x2e\xb5\x9e\xf3\x0c\xd7\xad\xab\xc1\x6d\x72\xdb\xdb\x09\x76\x23\x04\x7c\x98\x98\x9f\x88\xd1\x4e\xaf\x02\xa7\x21\x2b\xe1\x6e\xc2\xd0\x79\x81\xaa\xa9\x99\x49\xdd\xf8\x9e\xcd\x90\x33\x3a\x77\xbc\x4e\x19\x88\xa8\x2a\xbf\x7c\x7c\xaf\x32\x91",
+ "\x9f\xf0\xf0\xd7\x0c\xa0\x76\xca\x44\xc3\x53\xa3\xc6\x78\xc2\x09\x5c\x89\xf6\x19\xbb\x53\xec\x9c\xb4\x88\x8e\x2f\x14\xe5\x0f\xbc\x14\x6a\x7b\x52\x13\x56\x36\x9f\x1b\x9d\x56\x65\x83\x6e\x45\xd5\x40\x0f\x98\x56\xcc\x6d\xa3\xb3\xaf\xe6\xf3\xb0\x47\x1f\xc9\xc6",
+ 209 },
+ { GCRY_MD_SHA3_512,
+ "\x9f\x2c\x18\xad\xe9\xb3\x80\xc7\x84\xe1\x70\xfb\x76\x3e\x9a\xa2\x05\xf6\x43\x03\x06\x7e\xb1\xbc\xea\x93\xdf\x5d\xac\x4b\xf5\xa2\xe0\x0b\x78\x19\x5f\x80\x8d\xf2\x4f\xc7\x6e\x26\xcb\x7b\xe3\x1d\xc3\x5f\x08\x44\xcd\xed\x15\x67\xbb\xa2\x98\x58\xcf\xfc\x97\xfb\x29\x01\x03\x31\xb0\x1d\x6a\x3f\xb3\x15\x9c\xc1\xb9\x73\xd2\x55\xda\x98\x43\xe3\x4a\x0a\x40\x61\xca\xbd\xb9\xed\x37\xf2\x41\xbf\xab\xb3\xc2\x0d\x32\x74\x3f\x40\x26\xb5\x9a\x4c\xcc\x38\x5a\x23\x01\xf8\x3c\x0b\x0a\x19\x0b\x0f\x2d\x01\xac\xb8\xf0\xd4\x11\x11\xe1\x0f\x2f\x4e\x14\x93\x79\x27\x55\x99\xa5\x2d\xc0\x89\xb3\x5f\xdd\x52\x34\xb0\xcf\xb7\xb6\xd8\xae\xbd\x56\x3c\xa1\xfa\x65\x3c\x5c\x02\x1d\xfd\x6f\x59\x20\xe6\xf1\x8b\xfa\xfd\xbe\xcb\xf0\xab\x00\x28\x13\x33\xed\x50\xb9\xa9\x99\x54\x9c\x1c\x8f\x8c\x63\xd7\x62\x6c\x48\x32\x2e\x97\x91\xd5\xff\x72\x29\x40\x49\xbd\xe9\x1e\x73\xf8",
+ "\xa9\x81\xfa\xa9\xd3\xca\xc4\x92\xb2\xfa\x07\x8d\x11\x58\xf8\x12\x48\xdf\x8d\xb3\x6a\xcb\xd5\xba\xd3\xa6\xc6\x33\xbb\xe5\x00\xeb\x48\x1d\x29\x37\xbe\xee\x9a\x76\xc8\x4e\xdc\xdf\xa0\xf9\x97\xed\xce\x70\x8f\x07\x85\x14\x22\xa7\x59\x7e\x24\x63\xfc\x19\x12\xcd",
+ 210 },
+ { GCRY_MD_SHA3_512,
+ "\xae\x15\x9f\x3f\xa3\x36\x19\x00\x2a\xe6\xbc\xce\x8c\xbb\xdd\x7d\x28\xe5\xed\x9d\x61\x53\x45\x95\xc4\xc9\xf4\x3c\x40\x2a\x9b\xb3\x1f\x3b\x30\x1c\xbf\xd4\xa4\x3c\xe4\xc2\x4c\xd5\xc9\x84\x9c\xc6\x25\x9e\xca\x90\xe2\xa7\x9e\x01\xff\xba\xc0\x7b\xa0\xe1\x47\xfa\x42\x67\x6a\x1d\x66\x85\x70\xe0\x39\x63\x87\xb5\xbc\xd5\x99\xe8\xe6\x6a\xae\xd1\xb8\xa1\x91\xc5\xa4\x75\x47\xf6\x13\x73\x02\x1f\xa6\xde\xad\xcb\x55\x36\x3d\x23\x3c\x24\x44\x0f\x2c\x73\xdb\xb5\x19\xf7\xc9\xfa\x5a\x89\x62\xef\xd5\xf6\x25\x2c\x04\x07\xf1\x90\xdf\xef\xad\x70\x7f\x3c\x70\x07\xd6\x9f\xf3\x6b\x84\x89\xa5\xb6\xb7\xc5\x57\xe7\x9d\xd4\xf5\x0c\x06\x51\x1f\x59\x9f\x56\xc8\x96\xb3\x5c\x91\x7b\x63\xba\x35\xc6\xff\x80\x92\xba\xf7\xd1\x65\x8e\x77\xfc\x95\xd8\xa6\xa4\x3e\xeb\x4c\x01\xf3\x3f\x03\x87\x7f\x92\x77\x4b\xe8\x9c\x11\x14\xdd\x53\x1c\x01\x1e\x53\xa3\x4d\xc2\x48\xa2\xf0\xe6",
+ "\x89\x02\x5c\x13\xbc\x6b\x61\xa1\xbf\xad\xb1\xd3\x7d\x67\x6e\x49\xe6\x75\x4e\x9d\xfc\x00\xd5\x2c\x5e\xf1\x3b\xa5\x7c\x84\x5d\x14\xac\x75\xd5\xae\x6f\x06\x71\x40\x28\x10\x3c\x34\x24\x71\x7f\x4c\x2f\xbf\x6d\x88\xd0\x55\x69\x09\x87\x62\x0a\xc5\xb4\x40\x57\x6a",
+ 211 },
+ { GCRY_MD_SHA3_512,
+ "\x3b\x8e\x97\xc5\xff\xc2\xd6\xa4\x0f\xa7\xde\x7f\xce\xfc\x90\xf3\xb1\x2c\x94\x0e\x7a\xb4\x15\x32\x1e\x29\xee\x69\x2d\xfa\xc7\x99\xb0\x09\xc9\x9d\xcd\xdb\x70\x8f\xce\x5a\x17\x8c\x5c\x35\xee\x2b\x86\x17\x14\x3e\xdc\x4c\x40\xb4\xd3\x13\x66\x1f\x49\xab\xdd\x93\xce\xa7\x9d\x11\x75\x18\x80\x54\x96\xfe\x6a\xcf\x29\x2c\x4c\x2a\x1f\x76\xb4\x03\xa9\x7d\x7c\x39\x9d\xaf\x85\xb4\x6a\xd8\x4e\x16\x24\x6c\x67\xd6\x83\x67\x57\xbd\xe3\x36\xc2\x90\xd5\xd4\x01\xe6\xc1\x38\x6a\xb3\x27\x97\xaf\x6b\xb2\x51\xe9\xb2\xd8\xfe\x75\x4c\x47\x48\x2b\x72\xe0\xb3\x94\xea\xb7\x69\x16\x12\x6f\xd6\x8e\xa7\xd6\x5e\xb9\x3d\x59\xf5\xb4\xc5\xac\x40\xf7\xc3\xb3\x7e\x7f\x36\x94\xf2\x94\x24\xc2\x4a\xf8\xc8\xf0\xef\x59\xcd\x9d\xbf\x1d\x28\xe0\xe1\x0f\x79\x9a\x6f\x78\xca\xd1\xd4\x5b\x9d\xb3\xd7\xde\xe4\xa7\x05\x9a\xbe\x99\x18\x27\x14\x98\x3b\x9c\x9d\x44\xd7\xf5\x64\x35\x96\xd4\xf3",
+ "\x15\x45\xd8\x33\x48\x36\xf7\x43\x6f\x77\xf2\x15\x32\xf5\xd3\x05\x8e\x35\x1d\xb8\x35\x7e\xfc\x1e\x08\x95\x83\xa0\xc4\x0a\xd3\xa6\xaf\x5f\x2f\xee\x79\x3d\x3f\xe1\xb4\x72\x1f\x68\x17\xa3\x73\x49\x9b\x20\x91\x2a\x35\xc4\x60\x9f\xa9\xd8\x4b\xd2\x74\xe9\x78\xfc",
+ 212 },
+ { GCRY_MD_SHA3_512,
+ "\x34\x34\xec\x31\xb1\x0f\xaf\xdb\xfe\xec\x0d\xd6\xbd\x94\xe8\x0f\x7b\xa9\xdc\xa1\x9e\xf0\x75\xf7\xeb\x01\x75\x12\xaf\x66\xd6\xa4\xbc\xf7\xd1\x6b\xa0\x81\x9a\x18\x92\xa6\x37\x2f\x9b\x35\xbc\xc7\xca\x81\x55\xee\x19\xe8\x42\x8b\xc2\x2d\x21\x48\x56\xed\x5f\xa9\x37\x4c\x3c\x09\xbd\xe1\x69\x60\x2c\xc2\x19\x67\x9f\x65\xa1\x56\x6f\xc7\x31\x6f\x4c\xc3\xb6\x31\xa1\x8f\xb4\x44\x9f\xa6\xaf\xa1\x6a\x3d\xb2\xbc\x42\x12\xef\xf5\x39\xc6\x7c\xf1\x84\x68\x08\x26\x53\x55\x89\xc7\x11\x1d\x73\xbf\xfc\xe4\x31\xb4\xc4\x04\x92\xe7\x63\xd9\x27\x95\x60\xaa\xa3\x8e\xb2\xdc\x14\xa2\x12\xd7\x23\xf9\x94\xa1\xfe\x65\x6f\xf4\xdd\x14\x55\x1c\xe4\xe7\xc6\x21\xb2\xaa\x56\x04\xa1\x00\x01\xb2\x87\x8a\x89\x7a\x28\xa0\x80\x95\xc3\x25\xe1\x0a\x26\xd2\xfb\x1a\x75\xbf\xd6\x4c\x25\x03\x09\xbb\x55\xa4\x4f\x23\xbb\xac\x0d\x55\x16\xa1\xc6\x87\xd3\xb4\x1e\xf2\xfb\xbf\x9c\xc5\x6d\x47\x39",
+ "\xaf\xaf\x20\x1b\xa3\x53\x31\x6c\x1a\x7b\x81\x0f\x12\x0c\xff\x94\x1b\xb6\x58\xb0\x76\x3e\xef\x59\x43\x34\x03\xd8\x31\x3b\x8f\x00\xbf\x18\x17\x78\x98\xae\x71\x90\x7d\x3b\x52\x4e\x68\xbb\x02\x8e\xa1\x44\x28\x66\x85\x61\x11\xb1\x20\x89\xbc\xbe\xd1\x77\xfd\x46",
+ 213 },
+ { GCRY_MD_SHA3_512,
+ "\x7c\x79\x53\xd8\x1c\x8d\x20\x8f\xd1\xc9\x76\x81\xd4\x8f\x49\xdd\x00\x34\x56\xde\x60\x47\x5b\x84\x07\x0e\xf4\x84\x7c\x33\x3b\x74\x57\x5b\x1f\xc8\xd2\xa1\x86\x96\x44\x85\xa3\xb8\x63\x4f\xea\xa3\x59\x5a\xaa\x1a\x2f\x45\x95\xa7\xd6\xb6\x15\x35\x63\xde\xe3\x1b\xba\xc4\x43\xc8\xa3\x3e\xed\x6d\x5d\x95\x6a\x98\x0a\x68\x36\x6c\x25\x27\xb5\x50\xee\x95\x02\x50\xdf\xb6\x91\xea\xcb\xd5\xd5\x6a\xe1\x4b\x97\x06\x68\xbe\x17\x4c\x89\xdf\x2f\xea\x43\xae\x52\xf1\x31\x42\x63\x9c\x88\x4f\xd6\x2a\x36\x83\xc0\xc3\x79\x2f\x0f\x24\xab\x13\x18\xbc\xb2\x7e\x21\xf4\x73\x7f\xab\x62\xc7\x7e\xa3\x8b\xc8\xfd\x1c\xf4\x1f\x7d\xab\x64\xc1\x3f\xeb\xe7\x15\x2b\xf5\xbb\x7a\xb5\xa7\x8f\x53\x46\xd4\x3c\xc7\x41\xcb\x6f\x72\xb7\xb8\x98\x0f\x26\x8b\x68\xbf\x62\xab\xdf\xb1\x57\x7a\x52\x43\x8f\xe1\x4b\x59\x14\x98\xcc\x95\xf0\x71\x22\x84\x60\xc7\xc5\xd5\xce\xb4\xa7\xbd\xe5\x88\xe7\xf2\x1c",
+ "\x3f\xb4\xf2\x1a\x23\x19\x73\xd2\x24\x7f\x20\x6d\x47\xb1\x9e\xe1\x55\x16\x47\xfd\x4d\x4f\x21\xfb\xcd\x6f\x65\x35\x77\xc1\xac\x69\xea\xe4\xdb\x43\x2c\x02\x34\xac\xbe\x17\xb2\xce\xd0\x23\x8a\x56\xac\xc3\x4d\x7b\xb8\x2f\xbc\x19\x09\x03\x03\x5b\x7c\x53\x88\x57",
+ 214 },
+ { GCRY_MD_SHA3_512,
+ "\x7a\x6a\x4f\x4f\xdc\x59\xa1\xd2\x23\x38\x1a\xe5\xaf\x49\x8d\x74\xb7\x25\x2e\xcf\x59\xe3\x89\xe4\x91\x30\xc7\xea\xee\x62\x6e\x7b\xd9\x89\x7e\xff\xd9\x20\x17\xf4\xcc\xde\x66\xb0\x44\x04\x62\xcd\xed\xfd\x35\x2d\x81\x53\xe6\xa4\xc8\xd7\xa0\x81\x2f\x70\x1c\xc7\x37\xb5\x17\x8c\x25\x56\xf0\x71\x11\x20\x0e\xb6\x27\xdb\xc2\x99\xca\xa7\x92\xdf\xa5\x8f\x35\x93\x52\x99\xfa\x3a\x35\x19\xe9\xb0\x31\x66\xdf\xfa\x15\x91\x03\xff\xa3\x5e\x85\x77\xf7\xc0\xa8\x6c\x6b\x46\xfe\x13\xdb\x8e\x2c\xdd\x9d\xcf\xba\x85\xbd\xdd\xcc\xe0\xa7\xa8\xe1\x55\xf8\x1f\x71\x2d\x8e\x9f\xe6\x46\x15\x3d\x3d\x22\xc8\x11\xbd\x39\xf8\x30\x43\x3b\x22\x13\xdd\x46\x30\x19\x41\xb5\x92\x93\xfd\x0a\x33\xe2\xb6\x3a\xdb\xd9\x52\x39\xbc\x01\x31\x5c\x46\xfd\xb6\x78\x87\x5b\x3c\x81\xe0\x53\xa4\x0f\x58\x1c\xfb\xec\x24\xa1\x40\x4b\x16\x71\xa1\xb8\x8a\x6d\x06\x12\x02\x29\x51\x8f\xb1\x3a\x74\xca\x0a\xc5\xae",
+ "\x0b\x1c\x53\xe6\x86\x67\x31\x4b\x5f\x3f\x0f\x30\xe2\x5c\x62\x2b\x1a\x86\xd1\x07\x01\xd4\xa0\x47\x3f\xd4\x0f\x22\xc5\x0a\xcb\x47\xd6\x3e\xaf\xa5\x82\xa2\xfb\xe5\x45\x3a\x3f\x73\xbf\xbc\xa9\x23\x68\x0f\x4c\x2c\x7f\x99\xc9\x83\x88\xc0\x7d\xdd\x7a\xff\x2c\x6e",
+ 215 },
+ { GCRY_MD_SHA3_512,
+ "\xd9\xfa\xa1\x4c\xeb\xe9\xb7\xde\x55\x1b\x6c\x07\x65\x40\x9a\x33\x93\x85\x62\x01\x3b\x5e\x8e\x0e\x1e\x0a\x64\x18\xdf\x73\x99\xd0\xa6\xa7\x71\xfb\x81\xc3\xca\x9b\xd3\xbb\x8e\x29\x51\xb0\xbc\x79\x25\x25\xa2\x94\xeb\xd1\x08\x36\x88\x80\x6f\xe5\xe7\xf1\xe1\x7f\xd4\xe3\xa4\x1d\x00\xc8\x9e\x8f\xcf\x4a\x36\x3c\xae\xdb\x1a\xcb\x55\x8e\x3d\x56\x2f\x13\x02\xb3\xd8\x3b\xb8\x86\xed\x27\xb7\x60\x33\x79\x81\x31\xda\xb0\x5b\x42\x17\x38\x1e\xaa\xa7\xba\x15\xec\x82\x0b\xb5\xc1\x3b\x51\x6d\xd6\x40\xea\xec\x5a\x27\xd0\x5f\xdf\xca\x0f\x35\xb3\xa5\x31\x21\x46\x80\x6b\x4c\x02\x75\xbc\xd0\xaa\xa3\xb2\x01\x7f\x34\x69\x75\xdb\x56\x6f\x9b\x4d\x13\x7f\x4e\xe1\x06\x44\xc2\xa2\xda\x66\xde\xec\xa5\x34\x2e\x23\x64\x95\xc3\xc6\x28\x05\x28\xbf\xd3\x2e\x90\xaf\x4c\xd9\xbb\x90\x8f\x34\x01\x2b\x52\xb4\xbc\x56\xd4\x8c\xc8\xa6\xb5\x9b\xab\x01\x49\x88\xea\xbd\x12\xe1\xa0\xa1\xc2\xe1\x70\xe7",
+ "\xd8\x36\xd0\xce\x3a\x28\xad\x71\xc3\xa8\x76\x79\x6b\xf6\x5a\xab\x83\x8d\x84\xe4\x80\x2e\xd4\x9a\xc0\x44\x84\xae\x06\xaa\x08\xed\x31\xde\xb5\xc3\x8c\x10\x22\xf0\xac\xee\xd4\x9c\xb5\x8e\x38\xd3\xaa\xb0\x9e\xfe\xce\xd9\x34\x9f\xdc\x33\x37\x92\x51\x25\x98\x26",
+ 216 },
+ { GCRY_MD_SHA3_512,
+ "\x2d\x84\x27\x43\x3d\x0c\x61\xf2\xd9\x6c\xfe\x80\xcf\x1e\x93\x22\x65\xa1\x91\x36\x5c\x3b\x61\xaa\xa3\xd6\xdc\xc0\x39\xf6\xba\x2a\xd5\x2a\x6a\x8c\xc3\x0f\xc1\x0f\x70\x5e\x6b\x77\x05\x10\x59\x77\xfa\x49\x6c\x1c\x70\x8a\x27\x7a\x12\x43\x04\xf1\xfc\x40\x91\x1e\x74\x41\xd1\xb5\xe7\x7b\x95\x1a\xad\x7b\x01\xfd\x5d\xb1\xb3\x77\xd1\x65\xb0\x5b\xbf\x89\x80\x42\xe3\x96\x60\xca\xf8\xb2\x79\xfe\x52\x29\xd1\xa8\xdb\x86\xc0\x99\x9e\xd6\x5e\x53\xd0\x1c\xcb\xc4\xb4\x31\x73\xcc\xf9\x92\xb3\xa1\x45\x86\xf6\xba\x42\xf5\xfe\x30\xaf\xa8\xae\x40\xc5\xdf\x29\x96\x6f\x93\x46\xda\x5f\x8b\x35\xf1\x6a\x1d\xe3\xab\x6d\xe0\xf4\x77\xd8\xd8\x66\x09\x18\x06\x0e\x88\xb9\xb9\xe9\xca\x6a\x42\x07\x03\x3b\x87\xa8\x12\xdb\xf5\x54\x4d\x39\xe4\x88\x20\x10\xf8\x2b\x6c\xe0\x05\xf8\xe8\xff\x6f\xe3\xc3\x80\x6b\xc2\xb7\x3c\x2b\x83\xaf\xb7\x04\x34\x56\x29\x30\x4f\x9f\x86\x35\x87\x12\xe9\xfa\xe3\xca\x3e",
+ "\x61\xb8\xa7\x52\x0d\xab\x4d\x39\x50\x44\xb1\xa9\xcc\xc4\xf5\x26\x3e\xda\xe0\x32\x57\x67\xe3\xd2\xa0\xef\x22\x59\x33\xa8\x1f\x7e\x37\x96\x28\x08\x70\xdb\xda\xb8\x45\x7d\x58\x5c\x41\x06\x31\x5b\x53\x76\x53\xdc\x3d\x77\xe9\x15\x10\x0f\x42\x1d\xb3\x9f\x43\xb3",
+ 217 },
+ { GCRY_MD_SHA3_512,
+ "\x5e\x19\xd9\x78\x87\xfc\xaa\xc0\x38\x7e\x22\xc6\xf8\x03\xc3\x4a\x3d\xac\xd2\x60\x41\x72\x43\x3f\x7a\x8a\x7a\x52\x6c\xa4\xa2\xa1\x27\x1e\xcf\xc5\xd5\xd7\xbe\x5a\xc0\xd8\x5d\x92\x10\x95\x35\x0d\xfc\x65\x99\x7d\x44\x3c\x21\xc8\x09\x4e\x0a\x3f\xef\xd2\x96\x1b\xcb\x94\xae\xd0\x32\x91\xae\x31\x0c\xcd\xa7\x5d\x8a\xce\x4b\xc7\xd8\x9e\x7d\x3e\x5d\x16\x50\xbd\xa5\xd6\x68\xb8\xb5\x0b\xfc\x8e\x60\x8e\x18\x4f\x4d\x3a\x9a\x2b\xad\xc4\xff\x5f\x07\xe0\xc0\xbc\x8a\x9f\x2e\x0b\x2a\x26\xfd\x6d\x8c\x55\x00\x08\xfa\xaa\xb7\x5f\xd7\x1a\xf2\xa4\x24\xbe\xc9\xa7\xcd\x9d\x83\xfa\xd4\xc8\xe9\x31\x91\x15\x65\x6a\x87\x17\xd3\xb5\x23\xa6\x8f\xf8\x00\x42\x58\xb9\x99\x0e\xd3\x62\x30\x84\x61\x80\x4b\xa3\xe3\xa7\xe9\x2d\x8f\x2f\xfa\xe5\xc2\xfb\xa5\x5b\xa5\xa3\xc2\x7c\x0a\x2f\x71\xbd\x71\x1d\x2f\xe1\x79\x9c\x2a\xdb\x31\xb2\x00\x03\x54\x81\xe9\xee\x5c\x4a\xdf\x2a\xb9\xc0\xfa\x50\xb2\x39\x75\xcf",
+ "\xb8\x47\xb2\x92\x81\x8e\x80\x0b\xaa\x41\x5c\x25\x21\xa8\x15\x8a\x6a\xb7\x49\x93\x4d\xb6\x93\xd0\xd2\xe4\x61\x3c\xda\xe6\x0b\xd5\x60\x75\xcf\x2c\x29\xf5\x87\xdc\x35\x30\x16\x41\x90\xbc\x2c\x02\xd9\x7c\xa3\x23\x47\xfa\x2a\xa4\x31\xe5\x11\xbb\x7d\x1c\x87\xe8",
+ 218 },
+ { GCRY_MD_SHA3_512,
+ "\xc8\xe9\x76\xab\x46\x38\x90\x93\x87\xce\x3b\x8d\x4e\x51\x0c\x32\x30\xe5\x69\x0e\x02\xc4\x50\x93\xb1\xd2\x97\x91\x0a\xbc\x48\x1e\x56\xee\xa0\xf2\x96\xf9\x83\x79\xdf\xc9\x08\x0a\xf6\x9e\x73\xb2\x39\x9d\x1c\x14\x3b\xee\x80\xae\x13\x28\x16\x2c\xe1\xba\x7f\x6a\x83\x74\x67\x9b\x20\xaa\xcd\x38\x0e\xb4\xe6\x13\x82\xc9\x99\x98\x70\x4d\x62\x70\x1a\xfa\x91\x4f\x9a\x27\x05\xcd\xb0\x65\x88\x5f\x50\xd0\x86\xc3\xeb\x57\x53\x70\x0c\x38\x71\x18\xbb\x14\x2f\x3e\x6d\xa1\xe9\x88\xdf\xb3\x1a\xc7\x5d\x73\x68\x93\x1e\x45\xd1\x39\x1a\x27\x4b\x22\xf8\x3c\xeb\x07\x2f\x9b\xca\xbc\x0b\x21\x66\x85\xbf\xd7\x89\xf5\x02\x39\x71\x02\x4b\x18\x78\xa2\x05\x44\x25\x22\xf9\xea\x7d\x87\x97\xa4\x10\x2a\x3d\xf4\x17\x03\x76\x82\x51\xfd\x5e\x01\x7c\x85\xd1\x20\x0a\x46\x41\x18\xaa\x35\x65\x4e\x7c\xa3\x9f\x3c\x37\x5b\x8e\xf8\xcb\xe7\x53\x4d\xbc\x64\xbc\x20\xbe\xfb\x41\x7c\xf6\x0e\xc9\x2f\x63\xd9\xee\x73\x97",
+ "\x95\xed\x6d\x85\x67\x77\x4e\x66\x40\x4f\xc3\x2b\x7a\x01\xe1\xc6\x25\xfc\x83\x22\xab\x9b\xe0\xcd\x7c\x93\x67\x31\x63\x8b\x04\xc0\x97\x48\x97\x3d\x95\x66\x5a\x35\xb2\x18\xd1\x53\x14\x11\xf3\xaa\x5e\x5c\x47\xe6\x5d\x85\x7a\x43\x78\x3e\x2b\xd3\xc9\xd2\x90\x05",
+ 219 },
+ { GCRY_MD_SHA3_512,
+ "\x71\x45\xfa\x12\x4b\x74\x29\xa1\xfc\x22\x31\x23\x7a\x94\x9b\xa7\x20\x1b\xcc\x18\x22\xd3\x27\x2d\xe0\x05\xb6\x82\x39\x81\x96\xc2\x5f\x7e\x5c\xc2\xf2\x89\xfb\xf4\x44\x15\xf6\x99\xcb\x7f\xe6\x75\x77\x91\xb1\x44\x34\x10\x23\x4a\xe0\x61\xed\xf6\x23\x35\x9e\x2b\x4e\x32\xc1\x9b\xf8\x84\x50\x43\x2d\xd0\x1c\xaa\x5e\xb1\x6a\x1d\xc3\x78\xf3\x91\xca\x5e\x3c\x4e\x5f\x35\x67\x28\xbd\xdd\x49\x75\xdb\x7c\x89\x0d\xa8\xbb\xc8\x4c\xc7\x3f\xf2\x44\x39\x4d\x0d\x48\x95\x49\x78\x76\x5e\x4a\x00\xb5\x93\xf7\x0f\x2c\xa0\x82\x67\x3a\x26\x1e\xd8\x8d\xbc\xef\x11\x27\x72\x8d\x8c\xd8\x9b\xc2\xc5\x97\xe9\x10\x2c\xed\x60\x10\xf6\x5f\xa7\x5a\x14\xeb\xe4\x67\xfa\x57\xce\x3b\xd4\x94\x8b\x68\x67\xd7\x4a\x9d\xf5\xc0\xec\x6f\x53\x0c\xbf\x2e\xe6\x1c\xe6\xf0\x6b\xc8\xf2\x86\x4d\xff\x55\x83\x77\x6b\x31\xdf\x8c\x7f\xfc\xb6\x14\x28\xa5\x6b\xf7\xbd\x37\x18\x8b\x4a\x51\x23\xbb\xf3\x38\x39\x3a\xf4\x6e\xda\x85\xe6",
+ "\x98\x35\x07\x93\xfc\x15\x40\xae\x72\x75\x7c\x2d\x1b\xa0\xfa\x34\xdf\x19\x23\xc9\x87\xf3\x65\x75\x27\x88\xe3\xc6\x59\x31\x74\x6c\x36\xd1\x3f\xd2\x93\xdb\x8e\xa1\xb6\x37\x48\x72\xcc\xf7\x4e\x9b\x0c\xff\x67\xc6\xde\xbb\x42\x63\x39\x0c\xd9\x6e\x2b\xdd\x86\x4f",
+ 220 },
+ { GCRY_MD_SHA3_512,
+ "\x7f\xdf\xad\xcc\x9d\x29\xba\xd2\x3a\xe0\x38\xc6\xc6\x5c\xda\x1a\xef\x75\x72\x21\xb8\x87\x2e\xd3\xd7\x5f\xf8\xdf\x7d\xa0\x62\x7d\x26\x6e\x22\x4e\x81\x2c\x39\xf7\x98\x3e\x45\x58\xbf\xd0\xa1\xf2\xbe\xf3\xfe\xb5\x6b\xa0\x91\x20\xef\x76\x29\x17\xb9\xc0\x93\x86\x79\x48\x54\x7a\xee\x98\x60\x0d\x10\xd8\x7b\x20\x10\x68\x78\xa8\xd2\x2c\x64\x37\x8b\xf6\x34\xf7\xf7\x59\x00\xc0\x39\x86\xb0\x77\xb0\xbf\x8b\x74\x0a\x82\x44\x7b\x61\xb9\x9f\xee\x53\x76\xc5\xeb\x66\x80\xec\x9e\x30\x88\xf0\xbd\xd0\xc5\x68\x83\x41\x3d\x60\xc1\x35\x7d\x3c\x81\x19\x50\xe5\x89\x0e\x76\x00\x10\x3c\x91\x63\x41\xb8\x0c\x74\x3c\x6a\x85\x2b\x7b\x4f\xb6\x0c\x3b\xa2\x1f\x3b\xc1\x5b\x83\x82\x43\x7a\x68\x45\x47\x79\xcf\x3c\xd7\xf9\xf9\x0c\xcc\x8e\xf2\x8d\x0b\x70\x65\x35\xb1\xe4\x10\x8e\xb5\x62\x7b\xb4\x5d\x71\x9c\xb0\x46\x83\x9a\xee\x31\x1c\xa1\xab\xdc\x83\x19\xe0\x50\xd6\x79\x72\xcb\x35\xa6\xb1\x60\x1b\x25\xdb\xf4\x87",
+ "\xc2\x49\x3d\x60\xe1\xef\xa6\xb4\x72\x93\x3e\xde\x64\xd1\xf4\x9e\xff\x77\x36\x35\xf6\x6c\x64\x54\xe5\x7e\x47\x93\x5a\x0f\x4c\x5b\x94\x54\x8d\xa5\xc3\x69\xbd\xac\x71\x46\xe5\x4f\x01\x7c\x3f\xd6\x74\xce\x32\xf8\xd9\x51\x51\xc7\xcb\xc3\xe3\xbb\xa3\xeb\xe0\xd3",
+ 221 },
+ { GCRY_MD_SHA3_512,
+ "\x98\x86\x38\x21\x9f\xd3\x09\x54\x21\xf8\x26\xf5\x6e\x4f\x09\xe3\x56\x29\x6b\x62\x8c\x3c\xe6\x93\x0c\x9f\x2e\x75\x8f\xd1\xa8\x0c\x82\x73\xf2\xf6\x1e\x4d\xaa\xe6\x5c\x4f\x11\x0d\x3e\x7c\xa0\x96\x5a\xc7\xd2\x4e\x34\xc0\xdc\x4b\xa2\xd6\xff\x0b\xf5\xbb\xe9\x3b\x35\x85\xf3\x54\xd7\x54\x3c\xb5\x42\xa1\xaa\x54\x67\x4d\x37\x50\x77\xf2\xd3\x60\xa8\xf4\xd4\x2f\x3d\xb1\x31\xc3\xb7\xab\x73\x06\x26\x7b\xa1\x07\x65\x98\x64\xa9\x0c\x8c\x90\x94\x60\xa7\x36\x21\xd1\xf5\xd9\xd3\xfd\x95\xbe\xb1\x9b\x23\xdb\x1c\xb6\xc0\xd0\xfb\xa9\x1d\x36\x89\x15\x29\xb8\xbd\x82\x63\xca\xa1\xba\xb5\x6a\x4a\xff\xae\xd4\x49\x62\xdf\x09\x6d\x8d\x5b\x1e\xb8\x45\xef\x31\x18\x8b\x3e\x10\xf1\xaf\x81\x1a\x13\xf1\x56\xbe\xb7\xa2\x88\xaa\xe5\x93\xeb\xd1\x47\x1b\x62\x4a\xa1\xa7\xc6\xad\xf0\x1e\x22\x00\xb3\xd7\x2d\x88\xa3\xae\xd3\x10\x0c\x88\x23\x1e\x41\xef\xc3\x76\x90\x6f\x0b\x58\x0d\xc8\x95\xf0\x80\xfd\xa5\x74\x1d\xb1\xcb",
+ "\x70\xd7\xba\x65\x85\xcd\x2e\xf9\x1b\xb2\x61\x02\x5f\x9d\xcc\x80\xf8\x35\x9c\x9d\xc3\x0c\x7c\x29\x61\xf0\xd1\xf6\x05\x7b\x9c\x44\xe3\xaa\x67\xa4\xbc\x00\xf1\x37\x88\x6e\x3c\xf1\x31\x6d\x75\xf8\xeb\xf6\x51\xc7\x9d\xf9\xa9\x9c\xab\xd0\x38\x30\x08\x37\x20\x16",
+ 222 },
+ { GCRY_MD_SHA3_512,
+ "\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",
+ "\xb5\x0d\x0d\xa9\xb3\xdb\x15\x45\xcc\x1d\x2f\x35\x46\x5c\x74\xd0\x75\x43\xb3\x56\x42\x49\xf1\x2c\x54\x6a\x08\x79\x7e\xea\x73\x32\x6c\xe6\x24\x20\x3a\x3d\x25\xc9\x2c\xe6\x36\xbc\xce\x86\xda\x9c\xb9\xf3\x9b\xc7\x55\xec\x0f\x39\xc0\x90\xa0\xe8\xa7\x2d\xa7\x0b",
+ 223 },
+ { GCRY_MD_SHA3_512,
+ "\x47\xb8\x21\x6a\xa0\xfb\xb5\xd6\x79\x66\xf2\xe8\x2c\x17\xc0\x7a\xa2\xd6\x32\x7e\x96\xfc\xd8\x3e\x3d\xe7\x33\x36\x89\xf3\xee\x79\x99\x4a\x1b\xf4\x50\x82\xc4\xd7\x25\xed\x8d\x41\x20\x5c\xb5\xbc\xdf\x5c\x34\x1f\x77\xfa\xcb\x1d\xa4\x6a\x5b\x9b\x2c\xbc\x49\xea\xdf\x78\x6b\xcd\x88\x1f\x37\x1a\x95\xfa\x17\xdf\x73\xf6\x06\x51\x9a\xea\x0f\xf7\x9d\x5a\x11\x42\x7b\x98\xee\x7f\x13\xa5\xc0\x06\x37\xe2\x85\x41\x34\x69\x10\x59\x83\x91\x21\xfe\xa9\xab\xe2\xcd\x1b\xcb\xbb\xf2\x7c\x74\xca\xf3\x67\x8e\x05\xbf\xb1\xc9\x49\x89\x7e\xa0\x1f\x56\xff\xa4\xda\xfb\xe8\x64\x46\x11\x68\x5c\x61\x7a\x32\x06\xc7\xa7\x03\x6e\x4a\xc8\x16\x79\x9f\x69\x3d\xaf\xe7\xf1\x9f\x30\x3c\xe4\xeb\xa0\x9d\x21\xe0\x36\x10\x20\x1b\xfc\x66\x5b\x72\x40\x0a\x54\x7a\x1e\x00\xfa\x9b\x7a\xd8\xd8\x4f\x84\xb3\x4a\xef\x11\x85\x15\xe7\x4d\xef\x11\xb9\x18\x8b\xd1\xe1\xf9\x7d\x9a\x12\xc3\x01\x32\xec\x28\x06\x33\x9b\xda\xda\xcd\xa2\xfd\x8b\x78",
+ "\x83\x75\x2a\x88\xc9\x15\xd4\x19\x32\x96\x72\x5d\xec\xc5\x0c\x9c\x05\xd2\x5d\x6b\xbd\x9a\xf2\xe0\xef\x06\x28\x6e\xcf\xee\x96\x1d\xe9\x59\xbe\xdb\xb1\x30\x70\x4d\x43\x2c\x2b\xc8\x99\x30\x20\x8f\x45\x0e\x0a\x02\x26\x61\x72\x40\x43\xd2\x68\xcb\x24\xe7\xfc\x47",
+ 224 },
+ { GCRY_MD_SHA3_512,
+ "\x8c\xff\x1f\x67\xfe\x53\xc0\x98\x89\x6d\x91\x36\x38\x9b\xd8\x88\x18\x16\xcc\xab\x34\x86\x2b\xb6\x7a\x65\x6e\x3d\x98\x89\x6f\x3c\xe6\xff\xd4\xda\x73\x97\x58\x09\xfc\xdf\x96\x66\x76\x0d\x6e\x56\x1c\x55\x23\x8b\x20\x5d\x80\x49\xc1\xce\xde\xef\x37\x4d\x17\x35\xda\xa5\x33\x14\x7b\xfa\x96\x0b\x2c\xce\x4a\x4f\x25\x41\x76\xbb\x4d\x1b\xd1\xe8\x96\x54\x43\x2b\x8d\xbe\x1a\x13\x5c\x42\x11\x5b\x39\x4b\x02\x48\x56\xa2\xa8\x3d\xc8\x5d\x67\x82\xbe\x4b\x44\x42\x39\x56\x7c\xce\xc4\xb1\x84\xd4\x54\x8e\xae\x3f\xf6\xa1\x92\xf3\x43\x29\x2b\xa2\xe3\x2a\x0f\x26\x7f\x31\xcc\x26\x71\x9e\xb8\x52\x45\xd4\x15\xfb\x89\x7a\xc2\xda\x43\x3e\xe9\x1a\x99\x42\x4c\x9d\x7f\x17\x66\xa4\x41\x71\xd1\x65\x10\x01\xc3\x8f\xc7\x92\x94\xac\xcc\x68\xce\xb5\x66\x5d\x36\x21\x84\x54\xd3\xba\x16\x9a\xe0\x58\xa8\x31\x33\x8c\x17\x74\x36\x03\xf8\x1e\xe1\x73\xbf\xc0\x92\x74\x64\xf9\xbd\x72\x8d\xee\x94\xc6\xae\xab\x7a\xae\x6e\xe3\xa6\x27\xe8",
+ "\x72\x88\x42\x4b\xa8\x55\xa7\x6c\x74\x80\xb6\x06\xf8\xf3\x2e\x94\x39\x67\x99\xba\xb8\xbb\x3f\xc8\xfd\x21\xd1\x80\x96\x6c\x64\x97\x10\x71\xe2\x64\x56\x22\x52\x4e\xc7\xd1\x64\x5e\xea\x7b\x7c\x1f\xa2\x1f\x7f\x5b\x6b\x90\xf3\xe5\xbe\xb9\x92\x22\xf0\x5e\xa9\x05",
+ 225 },
+ { GCRY_MD_SHA3_512,
+ "\xea\xcd\x07\x97\x1c\xff\x9b\x99\x39\x90\x3f\x8c\x1d\x8c\xbb\x5d\x4d\xb1\xb5\x48\xa8\x5d\x04\xe0\x37\x51\x4a\x58\x36\x04\xe7\x87\xf3\x29\x92\xbf\x21\x11\xb9\x7a\xc5\xe8\xa9\x38\x23\x35\x52\x73\x13\x21\x52\x2a\xb5\xe8\x58\x35\x61\x26\x0b\x7d\x13\xeb\xee\xf7\x85\xb2\x3a\x41\xfd\x85\x76\xa6\xda\x76\x4a\x8e\xd6\xd8\x22\xd4\x95\x7a\x54\x5d\x52\x44\x75\x6c\x18\xaa\x80\xe1\xaa\xd4\xd1\xf9\xc2\x0d\x25\x9d\xee\x17\x11\xe2\xcc\x8f\xd0\x13\x16\x9f\xb7\xcc\x4c\xe3\x8b\x36\x2f\x8e\x09\x36\xae\x91\x98\xb7\xe8\x38\xdc\xea\x4f\x7a\x5b\x94\x29\xbb\x3f\x6b\xbc\xf2\xdc\x92\x56\x5e\x36\x76\xc1\xc5\xe6\xeb\x3d\xd2\xa0\xf8\x6a\xa2\x3e\xdd\x3d\x08\x91\xf1\x97\x44\x76\x92\x79\x4b\x3d\xfa\x26\x96\x11\xad\x97\xf7\x2b\x79\x56\x02\xb4\xfd\xb1\x98\xf3\xfd\x3e\xb4\x1b\x41\x50\x64\x25\x6e\x34\x5e\x8d\x8c\x51\xc5\x55\xdc\x8a\x21\x90\x4a\x9b\x0f\x1a\xd0\xef\xfa\xb7\x78\x6a\xac\x2d\xa3\xb1\x96\x50\x7e\x9f\x33\xca\x35\x64\x27",
+ "\xe9\x39\x93\x76\xd8\x9c\x4d\xd4\x46\x4e\x45\x82\x5f\x43\x02\xcd\xcc\xd4\xc4\x1d\xb4\xe8\x95\x1b\xe1\x7b\xcc\x64\x51\x85\x83\x32\x39\x8b\x7e\x4e\x7f\x5e\xee\x68\x30\xc7\x15\x45\x1e\x4a\xac\xdb\x17\x9d\xd5\x24\x7b\xa6\xd5\x72\x8c\xbd\x40\x60\xae\xb7\x7c\xb9",
+ 226 },
+ { GCRY_MD_SHA3_512,
+ "\x23\xac\x4e\x9a\x42\xc6\xef\x45\xc3\x33\x6c\xe6\xdf\xc2\xff\x7d\xe8\x88\x4c\xd2\x3d\xc9\x12\xfe\xf0\xf7\x75\x6c\x09\xd3\x35\xc1\x89\xf3\xad\x3a\x23\x69\x7a\xbd\xa8\x51\xa8\x18\x81\xa0\xc8\xcc\xaf\xc9\x80\xab\x2c\x70\x25\x64\xc2\xbe\x15\xfe\x4c\x4b\x9f\x10\xdf\xb2\x24\x8d\x0d\x0c\xb2\xe2\x88\x7f\xd4\x59\x8a\x1d\x4a\xcd\xa8\x97\x94\x4a\x2f\xfc\x58\x0f\xf9\x27\x19\xc9\x5c\xf2\xaa\x42\xdc\x58\x46\x74\xcb\x5a\x9b\xc5\x76\x5b\x9d\x6d\xdf\x57\x89\x79\x1d\x15\xf8\xdd\x92\x5a\xa1\x2b\xff\xaf\xbc\xe6\x08\x27\xb4\x90\xbb\x7d\xf3\xdd\xa6\xf2\xa1\x43\xc8\xbf\x96\xab\xc9\x03\xd8\x3d\x59\xa7\x91\xe2\xd6\x28\x14\xa8\x9b\x80\x80\xa2\x80\x60\x56\x8c\xf2\x4a\x80\xae\x61\x17\x9f\xe8\x4e\x0f\xfa\xd0\x03\x88\x17\x8c\xb6\xa6\x17\xd3\x7e\xfd\x54\xcc\x01\x97\x0a\x4a\x41\xd1\xa8\xd3\xdd\xce\x46\xed\xbb\xa4\xab\x7c\x90\xad\x56\x53\x98\xd3\x76\xf4\x31\x18\x9c\xe8\xc1\xc3\x3e\x13\x2f\xea\xe6\xa8\xcd\x17\xa6\x1c\x63\x00\x12",
+ "\xcc\xea\x44\x7e\xfe\x6f\x8b\x06\xac\x42\x07\x62\x80\x37\x76\x35\xf5\xfd\x07\x67\xf4\xaf\x8b\x24\x5f\xe6\x3b\x79\xfe\x49\x74\xe9\x15\x67\x44\xe6\x0e\x98\xd1\x20\x18\x21\x4c\x39\xf8\xa8\x26\xd5\x06\xd0\xd5\x94\x86\x45\xe9\xf8\x83\xc2\x08\xd3\x7d\x92\x7a\x41",
+ 227 },
+ { GCRY_MD_SHA3_512,
+ "\x01\x72\xdf\x73\x22\x82\xc9\xd4\x88\x66\x9c\x35\x8e\x34\x92\x26\x0c\xbe\x91\xc9\x5c\xfb\xc1\xe3\xfe\xa6\xc4\xb0\xec\x12\x9b\x45\xf2\x42\xac\xe0\x9f\x15\x2f\xc6\x23\x4e\x1b\xee\x8a\xab\x8c\xd5\x6e\x8b\x48\x6e\x1d\xcb\xa9\xc0\x54\x07\xc2\xf9\x5d\xa8\xd8\xf1\xc0\xaf\x78\xee\x2e\xd8\x2a\x3a\x79\xec\x0c\xb0\x70\x93\x96\xee\x62\xaa\xdb\x84\xf8\xa4\xee\x8a\x7c\xcc\xa3\xc1\xee\x84\xe3\x02\xa0\x9e\xa8\x02\x20\x4a\xfe\xcf\x04\x09\x7e\x67\xd0\xf8\xe8\xa9\xd2\x65\x11\x26\xc0\xa5\x98\xa3\x70\x81\xe4\x2d\x16\x8b\x0a\xe8\xa7\x19\x51\xc5\x24\x25\x9e\x4e\x20\x54\xe5\x35\xb7\x79\x67\x9b\xda\xde\x56\x6f\xe5\x57\x00\x85\x86\x18\xe6\x26\xb4\xa0\xfa\xf8\x95\xbc\xce\x90\x11\x50\x4a\x49\xe0\x5f\xd5\x61\x27\xea\xe3\xd1\xf8\x91\x7a\xfb\x54\x8e\xca\xda\xbd\xa1\x02\x01\x11\xfe\xc9\x31\x4c\x41\x34\x98\xa3\x60\xb0\x86\x40\x54\x9a\x22\xcb\x23\xc7\x31\xac\xe7\x43\x25\x2a\x82\x27\xa0\xd2\x68\x9d\x4c\x60\x01\x60\x66\x78\xdf\xb9\x21",
+ "\x7e\x03\xfc\xe3\xb6\x7e\xbb\x28\x30\x88\x23\xf5\x6a\xa9\x3d\xbb\x4d\x9e\xfd\xbd\x93\x30\x0d\x97\xb1\xf9\x9e\xfc\xb8\x2c\x36\x84\xc5\xa5\xa5\xaa\x64\xe7\xa3\x4c\x69\xb8\x93\x99\xca\xb0\x5f\x22\xe8\xe8\x86\x07\xb8\x63\x33\x6e\x4c\xbf\x8c\xf6\xe7\x4b\x98\xc1",
+ 228 },
+ { GCRY_MD_SHA3_512,
+ "\x38\x75\xb9\x24\x0c\xf3\xe0\xa8\xb5\x9c\x65\x85\x40\xf2\x6a\x70\x1c\xf1\x88\x49\x6e\x2c\x21\x74\x78\x8b\x12\x6f\xd2\x94\x02\xd6\xa7\x54\x53\xba\x06\x35\x28\x4d\x08\x83\x5f\x40\x05\x1a\x2a\x96\x83\xdc\x92\xaf\xb9\x38\x37\x19\x19\x12\x31\x17\x03\x79\xba\x6f\x4a\xdc\x81\x6f\xec\xbb\x0f\x9c\x44\x6b\x78\x5b\xf5\x20\x79\x68\x41\xe5\x88\x78\xb7\x3c\x58\xd3\xeb\xb0\x97\xce\x47\x61\xfd\xea\xbe\x15\xde\x2f\x31\x9d\xfb\xaf\x17\x42\xcd\xeb\x38\x95\x59\xc7\x88\x13\x1a\x67\x93\xe1\x93\x85\x66\x61\x37\x6c\x81\xce\x95\x68\xda\x19\xaa\x69\x25\xb4\x7f\xfd\x77\xa4\x3c\x7a\x0e\x75\x8c\x37\xd6\x92\x54\x90\x9f\xf0\xfb\xd4\x15\xef\x8e\xb9\x37\xbc\xd4\x9f\x91\x46\x8b\x49\x97\x4c\x07\xdc\x81\x9a\xbd\x67\x39\x5d\xb0\xe0\x58\x74\xff\x83\xdd\xda\xb8\x95\x34\x4a\xbd\x0e\x71\x11\xb2\xdf\x9e\x58\xd7\x6d\x85\xad\x98\x10\x6b\x36\x29\x58\x26\xbe\x04\xd4\x35\x61\x55\x95\x60\x5e\x4b\x4b\xb8\x24\xb3\x3c\x4a\xfe\xb5\xe7\xbb\x0d\x19\xf9\x09",
+ "\x6a\x45\x7a\xe7\x4f\x89\xc4\x2b\xbd\x2b\xd2\xeb\xff\xfb\xd7\x1f\x03\x6f\xf7\xb7\x6c\x4a\xfd\xdf\xfb\xd5\x2f\x32\xe5\x88\xa9\x54\x3c\xed\x09\xda\x9a\x3e\x13\x0a\xc1\xa1\x9e\xf1\xac\xb2\xfa\x68\xac\x41\x91\x7e\xd6\xba\xd3\x7a\x60\x98\x2b\x16\xb5\xeb\x4f\xf3",
+ 229 },
+ { GCRY_MD_SHA3_512,
+ "\x74\x7c\xc1\xa5\x9f\xef\xba\x94\xa9\xc7\x5b\xa8\x66\xc3\x0d\xc5\xc1\xcb\x0c\x0f\x8e\x93\x61\xd9\x84\x84\x95\x6d\xd5\xd1\xa4\x0f\x61\x84\xaf\xbe\x3d\xac\x9f\x76\x02\x8d\x1c\xae\xcc\xfb\xf6\x91\x99\xc6\xce\x2b\x4c\x09\x2a\x3f\x4d\x2a\x56\xfe\x5a\x33\xa0\x07\x57\xf4\xd7\xde\xe5\xdf\xb0\x52\x43\x11\xa9\x7a\xe0\x66\x8a\x47\x97\x1b\x95\x76\x6e\x2f\x6d\xd4\x8c\x3f\x57\x84\x1f\x91\xf0\x4a\x00\xad\x5e\xa7\x0f\x2d\x47\x9a\x26\x20\xdc\x5c\xd7\x8e\xaa\xb3\xa3\xb0\x11\x71\x9b\x7e\x78\xd1\x9d\xdf\x70\xd9\x42\x37\x98\xaf\x77\x51\x7e\xbc\x55\x39\x2f\xcd\x01\xfc\x60\x0d\x8d\x46\x6b\x9e\x7a\x7a\x85\xbf\x33\xf9\xcc\x54\x19\xe9\xbd\x87\x4d\xdf\xd6\x09\x81\x15\x0d\xda\xf8\xd7\xfe\xba\xa4\x37\x4f\x08\x72\xa5\x62\x8d\x31\x80\x00\x31\x1e\x2f\x56\x55\x36\x5a\xd4\xd4\x07\xc2\x0e\x5c\x04\xdf\x17\xa2\x22\xe7\xde\xec\x79\xc5\xab\x11\x16\xd8\x57\x2f\x91\xcd\x06\xe1\xcc\xc7\xce\xd5\x37\x36\xfc\x86\x7f\xd4\x9e\xce\xbe\x6b\xf8\x08\x2e\x8a",
+ "\x91\xb8\xcd\x79\x5d\x1a\x68\x28\x60\x1e\x00\xdb\x0c\x91\xff\x9a\x6f\x83\x74\x44\xf5\x3f\xcf\x89\xe9\x90\xb8\x8f\x5f\x3e\x34\xeb\x49\x0e\x72\xa1\x79\x5f\xab\x84\xf7\x8d\xa3\xf7\xaf\xc8\x98\x96\xc7\xcd\xe5\x86\x5d\x1b\xcd\x74\xd5\x63\x9e\x49\x03\xc6\x83\xfe",
+ 230 },
+ { GCRY_MD_SHA3_512,
+ "\x57\xaf\x97\x1f\xcc\xae\xc9\x74\x35\xdc\x2e\xc9\xef\x04\x29\xbc\xed\xc6\xb6\x47\x72\x9e\xa1\x68\x85\x8a\x6e\x49\xac\x10\x71\xe7\x06\xf4\xa5\xa6\x45\xca\x14\xe8\xc7\x74\x6d\x65\x51\x16\x20\x68\x2c\x90\x6c\x8b\x86\xec\x90\x1f\x3d\xde\xd4\x16\x7b\x3f\x00\xb0\x6c\xbf\xac\x6a\xee\x37\x28\x05\x1b\x3e\x5f\xf1\x0b\x4f\x9e\xd8\xbd\x0b\x8d\xa9\x43\x03\xc8\x33\x75\x5b\x3c\xa3\xae\xdd\xf0\xb5\x4b\xc8\xd6\x63\x21\x38\xb5\xd2\x5b\xab\x03\xd1\x7b\x34\x58\xa9\xd7\x82\x10\x80\x06\xf5\xbb\x7d\xe7\x5b\x5c\x0b\xa8\x54\xb4\x23\xd8\xbb\x80\x1e\x70\x1e\x99\xdc\x4f\xea\xad\x59\xbc\x1c\x71\x12\x45\x3b\x04\xd3\x3e\xa3\x63\x56\x39\xfb\x80\x2c\x73\xc2\xb7\x1d\x58\xa5\x6b\xbd\x67\x1b\x18\xfe\x34\xed\x2e\x3d\xca\x38\x82\x7d\x63\xfd\xb1\xd4\xfb\x32\x85\x40\x50\x04\xb2\xb3\xe2\x60\x81\xa8\xff\x08\xcd\x6d\x2b\x08\xf8\xe7\xb7\xe9\x0a\x2a\xb1\xed\x7a\x41\xb1\xd0\x12\x85\x22\xc2\xf8\xbf\xf5\x6a\x7f\xe6\x79\x69\x42\x2c\xe8\x39\xa9\xd4\x60\x8f\x03",
+ "\x76\x35\xd7\x9c\x1b\x32\xe4\x93\x4e\xb0\x09\x0c\x6d\x46\xc0\xb2\x40\xf6\x26\xc7\x7d\x84\xf8\xea\xbf\x57\x1b\xa8\xfd\xe9\x24\xf4\xa1\xcf\x45\x67\x04\xb1\x01\xf6\x67\xf9\x12\xde\xdb\xbc\xbe\xff\x21\x80\xa4\x19\xa6\x8c\x7b\x79\x0b\xa6\x06\xe6\x60\x2d\x51\x15",
+ 231 },
+ { GCRY_MD_SHA3_512,
+ "\x04\xe1\x6d\xed\xc1\x22\x79\x02\xba\xaf\x33\x2d\x3d\x08\x92\x36\x01\xbd\xd6\x4f\x57\x3f\xaa\x1b\xb7\x20\x19\x18\xcf\xe1\x6b\x1e\x10\x15\x1d\xae\x87\x5d\xa0\xc0\xd6\x3c\x59\xc3\xdd\x05\x0c\x4c\x6a\x87\x40\x11\xb0\x18\x42\x1a\xfc\x46\x23\xab\x03\x81\x83\x1b\x2d\xa2\xa8\xba\x42\xc9\x6e\x4f\x70\x86\x4a\xc4\x4e\x10\x6f\x94\x31\x10\x51\xe7\x4c\x77\xc1\x29\x1b\xf5\xdb\x95\x39\xe6\x95\x67\xbf\x6a\x11\xcf\x69\x32\xbb\xba\xd3\x3f\x89\x46\xbf\x58\x14\xc0\x66\xd8\x51\x63\x3d\x1a\x51\x35\x10\x03\x9b\x34\x99\x39\xbf\xd4\x2b\x85\x8c\x21\x82\x7c\x8f\xf0\x5f\x1d\x09\xb1\xb0\x76\x5d\xc7\x8a\x13\x5b\x5c\xa4\xdf\xba\x08\x01\xbc\xad\xdf\xa1\x75\x62\x3c\x8b\x64\x7e\xac\xfb\x44\x44\xb8\x5a\x44\xf7\x38\x90\x60\x7d\x06\xd5\x07\xa4\xf8\x39\x36\x58\x78\x86\x69\xf6\xef\x4d\xeb\x58\xd0\x8c\x50\xca\x07\x56\xd5\xe2\xf4\x9d\x1a\x7a\xd7\x3e\x0f\x0b\x3d\x3b\x5f\x09\x0a\xcf\x62\x2b\x18\x78\xc5\x91\x33\xe4\xa8\x48\xe0\x51\x53\x59\x2e\xa8\x1c\x6f\xbf",
+ "\xdd\xd0\xc5\x21\xed\x60\xc5\x5f\x65\xba\xe2\x41\xa9\x07\x2d\x7f\x6f\x6c\xca\x7f\x64\x62\x4e\xc9\x2c\x03\x7b\xf8\xbc\x16\xf0\x60\x2e\x75\xee\x46\x87\x9a\xf4\x1f\x3e\xff\x5c\xe2\x35\x90\x5f\x38\x56\xa0\x31\xc3\xcc\x90\xa4\x85\x1f\x4c\xd8\x46\x3a\xae\x6d\xe8",
+ 232 },
+ { GCRY_MD_SHA3_512,
+ "\x7c\x81\x5c\x38\x4e\xee\x0f\x28\x8e\xce\x27\xcc\xed\x52\xa0\x16\x03\x12\x7b\x07\x9c\x00\x73\x78\xbc\x5d\x1e\x6c\x5e\x9e\x6d\x1c\x73\x57\x23\xac\xbb\xd5\x80\x1a\xc4\x98\x54\xb2\xb5\x69\xd4\x47\x2d\x33\xf4\x0b\xbb\x88\x82\x95\x62\x45\xc3\x66\xdc\x35\x82\xd7\x16\x96\xa9\x7a\x4e\x19\x55\x7e\x41\xe5\x4d\xee\x48\x2a\x14\x22\x90\x05\xf9\x3a\xfd\x2c\x4a\x7d\x86\x14\xd1\x0a\x97\xa9\xdf\xa0\x7f\x7c\xd9\x46\xfa\x45\x26\x30\x63\xdd\xd2\x9d\xb8\xf9\xe3\x4d\xb6\x0d\xaa\x32\x68\x4f\x00\x72\xea\x2a\x94\x26\xec\xeb\xfa\x52\x39\xfb\x67\xf2\x9c\x18\xcb\xaa\x2a\xf6\xed\x4b\xf4\x28\x39\x36\x82\x3a\xc1\x79\x01\x64\xfe\xc5\x45\x7a\x9c\xba\x7c\x76\x7c\xa5\x93\x92\xd9\x4c\xab\x74\x48\xf5\x0e\xb3\x4e\x9a\x93\xa8\x00\x27\x47\x1c\xe5\x97\x36\xf0\x99\xc8\x86\xde\xa1\xab\x4c\xba\x4d\x89\xf5\xfc\x7a\xe2\xf2\x1c\xcd\x27\xf6\x11\xec\xa4\x62\x6b\x2d\x08\xdc\x22\x38\x2e\x92\xc1\xef\xb2\xf6\xaf\xdc\x8f\xdc\x3d\x21\x72\x60\x4f\x50\x35\xc4\x6b\x81\x97\xd3",
+ "\xc8\x4c\x03\x56\x4d\x02\x4f\x90\x56\x00\x01\xca\x4c\xef\x86\x7a\xf7\x79\x99\x94\x3e\x31\x3c\xa1\x73\x28\x75\x6c\x43\xd2\xfe\x31\xcf\x98\x81\x2d\x3a\x7a\xab\x15\x35\xc2\x8e\xd2\x9d\x69\x2d\xb4\x82\x4e\x8d\x6d\xce\x06\xc9\x99\x4d\xbc\xbe\x0f\x82\x63\x3f\xbe",
+ 233 },
+ { GCRY_MD_SHA3_512,
+ "\xe2\x9d\x50\x51\x58\xdb\xdd\x93\x7d\x9e\x3d\x21\x45\x65\x8e\xe6\xf5\x99\x2a\x2f\xc7\x90\xf4\xf6\x08\xd9\xcd\xb4\x4a\x09\x1d\x5b\x94\xb8\x8e\x81\xfa\xc4\xfd\xf5\xc4\x94\x42\xf1\x3b\x91\x1c\x55\x88\x64\x69\x62\x95\x51\x18\x9e\xaf\xf6\x24\x88\xf1\xa4\x79\xb7\xdb\x11\xa1\x56\x0e\x19\x8d\xdc\xcc\xcf\x50\x15\x90\x93\x42\x5f\xf7\xf1\xcb\x8d\x1d\x12\x46\xd0\x97\x87\x64\x08\x7d\x6b\xac\x25\x70\x26\xb0\x90\xef\xae\x8c\xec\x5f\x22\xb6\xf2\x1c\x59\xac\xe1\xac\x73\x86\xf5\xb8\x83\x7c\xa6\xa1\x2b\x6f\xbf\x55\x34\xdd\x05\x60\xef\x05\xca\x78\x10\x4d\x3b\x94\x3d\xdb\x22\x0f\xea\xec\x89\xaa\x5e\x69\x2a\x00\xf8\x22\xa2\xab\x9a\x2f\xe6\x03\x50\xd7\x5e\x7b\xe1\x6f\xf2\x52\x6d\xc6\x43\x87\x25\x02\xd0\x1f\x42\xf1\x88\xab\xed\x0a\x6e\x9a\x6f\x5f\xd0\xd1\xce\x7d\x57\x55\xc9\xff\xa6\x6b\x0a\xf0\xb2\x0b\xd8\x06\xf0\x8e\x06\x15\x66\x90\xd8\x1a\xc8\x11\x77\x8c\xa3\xda\xc2\xc2\x49\xb9\x60\x02\x01\x7f\xce\x93\xe5\x07\xe3\xb9\x53\xac\xf9\x99\x64\xb8\x47",
+ "\xb4\x56\x31\x91\x67\x51\x91\xed\x4d\x61\x07\xe5\x2f\xa1\x5a\xdc\x9d\x70\x64\x23\x58\xd8\xc3\xe3\x4d\xf1\x02\x74\xe2\x5d\x37\x3f\xd8\xd1\x9e\x92\x47\x2b\x82\x3e\x28\xbb\xdd\x1d\x54\x1a\x95\xfd\xdd\x0d\x43\xc7\x9f\xcb\x3b\xa1\x8a\x7e\xc0\x38\xd3\xef\x69\xa6",
+ 234 },
+ { GCRY_MD_SHA3_512,
+ "\xd8\x55\x88\x69\x6f\x57\x6e\x65\xec\xa0\x15\x5f\x39\x5f\x0c\xfa\xcd\x83\xf3\x6a\x99\x11\x1e\xd5\x76\x8d\xf2\xd1\x16\xd2\x12\x1e\x32\x35\x7b\xa4\xf5\x4e\xde\x92\x7f\x18\x9f\x29\x7d\x3a\x97\xfa\xd4\xe9\xa0\xf5\xb4\x1d\x8d\x89\xdd\x7f\xe2\x01\x56\x79\x9c\x2b\x7b\x6b\xf9\xc9\x57\xba\x0d\x67\x63\xf5\xc3\xbc\x51\x29\x74\x7b\xbb\x53\x65\x2b\x49\x29\x0c\xff\x1c\x87\xe2\xcd\xf2\xc4\xb9\x5d\x8a\xae\xe0\x9b\xc8\xfb\xfa\x68\x83\xe6\x2d\x23\x78\x85\x81\x04\x91\xbf\xc1\x01\xf1\xd8\xc6\x36\xe3\xd0\xed\xe8\x38\xad\x05\xc2\x07\xa3\xdf\x4f\xad\x76\x45\x29\x79\xeb\x99\xf2\x9a\xfa\xec\xed\xd1\xc6\x3b\x8d\x36\xcf\x37\x84\x54\xa1\xbb\x67\xa7\x41\xc7\x7a\xc6\xb6\xb3\xf9\x5f\x4f\x02\xb6\x4d\xab\xc1\x54\x38\x61\x3e\xa4\x97\x50\xdf\x42\xee\x90\x10\x1f\x11\x5a\xa9\xab\xb9\xff\x64\x32\x4d\xde\x9d\xab\xbb\x01\x05\x4e\x1b\xd6\xb4\xbc\xdc\x79\x30\xa4\x4c\x23\x00\xd8\x7c\xa7\x8c\x06\x92\x4d\x03\x23\xad\x78\x87\xe4\x6c\x90\xe8\xc4\xd1\x00\xac\xd9\xee\xd2\x1e",
+ "\xa3\x0b\xd8\x0c\xb3\xac\xb3\xbf\xa7\xe0\x37\xa3\xd0\xd2\x50\x09\x74\xd7\x19\x57\xf6\x81\x35\x13\x30\x20\xc3\x2e\xb4\xd6\x88\xf1\x32\xd0\xfb\x04\x5b\xe0\x27\xf1\x24\xb3\xd9\x35\xcb\x88\x9e\x3c\xbc\x4a\x4a\x42\x00\x26\xbb\x2a\xc2\xa4\xb1\xb1\x5c\x57\xbb\x64",
+ 235 },
+ { GCRY_MD_SHA3_512,
+ "\x3a\x12\xf8\x50\x8b\x40\xc3\x2c\x74\x49\x2b\x66\x32\x33\x75\xdc\xfe\x49\x18\x4c\x78\xf7\x31\x79\xf3\x31\x4b\x79\xe6\x33\x76\xb8\xac\x68\x3f\x5a\x51\xf1\x53\x4b\xd7\x29\xb0\x2b\x04\xd0\x02\xf5\x5c\xbd\x8e\x8f\xc9\xb5\xec\x1e\xa6\xbb\xe6\xa0\xd0\xe7\x43\x15\x18\xe6\xba\x45\xd1\x24\x03\x5f\x9d\x3d\xce\x0a\x8b\xb7\xbf\x14\x30\xa9\xf6\x57\xe0\xb4\xea\x9f\x20\xeb\x20\xc7\x86\xa5\x81\x81\xa1\xe2\x0a\x96\xf1\x62\x8f\x87\x28\xa1\x3b\xdf\x7a\x4b\x4b\x32\xfc\x8a\xa7\x05\x4c\xc4\x88\x1a\xe7\xfa\x19\xaf\xa6\x5c\x6c\x3e\xe1\xb3\xad\xe3\x19\x2a\xf4\x20\x54\xa8\xa9\x11\xb8\xec\x18\x26\x86\x5d\x46\xd9\x3f\x1e\x7c\x5e\x2b\x78\x13\xc9\x2a\x50\x6e\x53\x88\x6f\x3d\x47\x01\xbb\x93\xd2\xa6\x81\xad\x10\x9c\x84\x59\x04\xbb\x86\x1a\xf8\xaf\x06\x46\xb6\xe3\x99\xb3\x8b\x61\x40\x51\xd3\x4f\x68\x42\x56\x3a\x0f\x37\xec\x00\xcb\x3d\x86\x5f\xc5\xd7\x46\xc4\x98\x7d\xe2\xa6\x50\x71\x10\x08\x83\xa2\xa9\xc7\xa2\xbf\xe1\xe2\xdd\x60\x3d\x9e\xa2\x4d\xc7\xc5\xfd\x06\xbe",
+ "\x4a\x58\x09\xe4\x57\xf5\x4d\x9c\x7e\x82\x09\xf6\xc4\x82\xd5\x2a\x4e\xfe\x6d\x8a\x20\xc4\xc6\xfb\xa8\x36\x87\x29\x49\x29\x23\x2d\x25\xcd\x7b\xf5\x11\xd8\xe6\xfb\xf2\x72\xe9\x83\xf0\x7d\x04\x4f\x87\x23\x09\x8d\x7a\x38\x1f\x04\xe9\x57\xb0\x78\x70\x87\xef\x02",
+ 236 },
+ { GCRY_MD_SHA3_512,
+ "\x18\x61\xed\xce\x46\xfa\x5a\xd1\x7e\x1f\xf1\xde\xae\x08\x4d\xec\x58\x0f\x97\xd0\xa6\x78\x85\xdf\xe8\x34\xb9\xdf\xac\x1a\xe0\x76\x74\x2c\xe9\xe2\x67\x51\x2c\xa5\x1f\x6d\xf5\xa4\x55\xaf\x0c\x5f\xd6\xab\xf9\x4a\xce\xa1\x03\xa3\x37\x0c\x35\x44\x85\xa7\x84\x6f\xb8\x4f\x3a\xc7\xc2\x90\x4b\x5b\x2f\xbf\x22\x70\x02\xce\x51\x21\x33\xbb\x7e\x1c\x4e\x50\x05\x7b\xfd\x1e\x44\xdb\x33\xc7\xcd\xb9\x69\xa9\x9e\x28\x4b\x18\x4f\x50\xa1\x4b\x06\x8a\x1f\xc5\x00\x9d\x9b\x29\x8d\xbe\x92\x23\x95\x72\xa7\x62\x7a\xac\x02\xab\xe8\xf3\xe3\xb4\x73\x41\x7f\x36\xd4\xd2\x50\x5d\x16\xb7\x57\x7f\x45\x26\xc9\xd9\x4a\x27\x0a\x2d\xfe\x45\x0d\x06\xda\x8f\x6f\xa9\x56\x87\x9a\x0a\x55\xcf\xe9\x9e\x74\x2e\xa5\x55\xea\x47\x7b\xa3\xe9\xb4\x4c\xcd\x50\x8c\x37\x54\x23\x61\x1a\xf9\x2e\x55\x34\x5d\xc2\x15\x77\x9b\x2d\x51\x19\xeb\xa4\x9c\x71\xd4\x9b\x9f\xe3\xf1\x56\x9f\xa2\x4e\x5c\xa3\xe3\x32\xd0\x42\x42\x2a\x8b\x81\x58\xd3\xec\x66\xa8\x00\x12\x97\x6f\x31\xff\xdf\x30\x5f\x0c\x9c\x5e",
+ "\xa7\x90\x16\xc3\x4b\xee\x41\xab\x5c\xb1\x02\x78\x47\x8a\x5b\x55\xd0\x7c\x2e\x08\x31\x83\x5d\xde\x6f\x8f\xf8\xda\xfa\xc3\x7a\x5f\x88\xfb\xa0\x7c\xce\xff\xe3\x58\x49\xdb\xd1\x23\xb0\x6d\xf2\x33\x5b\x00\x26\x45\xd0\x78\xfe\x1b\x08\x84\x3c\x25\x7a\x1b\xbe\x56",
+ 237 },
+ { GCRY_MD_SHA3_512,
+ "\x08\xd0\xff\xde\x3a\x6e\x4e\xf6\x56\x08\xea\x67\x2e\x48\x30\xc1\x29\x43\xd7\x18\x7c\xcf\xf0\x8f\x49\x41\xcf\xc1\x3e\x54\x5f\x3b\x9c\x7a\xd5\xee\xbb\xe2\xb0\x16\x42\xb4\x86\xca\xf8\x55\xc2\xc7\x3f\x58\xc1\xe4\xe3\x39\x1d\xa8\xe2\xd6\x3d\x96\xe1\x5f\xd8\x49\x53\xae\x5c\x23\x19\x11\xb0\x0a\xd6\x05\x0c\xd7\xaa\xfd\xaa\xc9\xb0\xf6\x63\xae\x6a\xab\x45\x51\x9d\x0f\x53\x91\xa5\x41\x70\x7d\x47\x90\x34\xe7\x3a\x6a\xd8\x05\xae\x35\x98\x09\x6a\xf0\x78\xf1\x39\x33\x01\x49\x3d\x66\x3d\xd7\x1f\x83\x86\x9c\xa2\x7b\xa5\x08\xb7\xe9\x1e\x81\xe1\x28\xc1\x71\x6d\xc3\xac\xfe\x30\x84\xb2\x20\x1e\x04\xcf\x80\x06\x61\x7e\xec\xf1\xb6\x40\x47\x4a\x5d\x45\xcf\xde\x9f\x4d\x3e\xf9\x2d\x6d\x05\x5b\x90\x98\x92\x19\x4d\x8a\x82\x18\xdb\x6d\x82\x03\xa8\x42\x61\xd2\x00\xd7\x14\x73\xd7\x48\x8f\x34\x27\x41\x6b\x68\x96\xc1\x37\xd4\x55\xf2\x31\x07\x1c\xac\xbc\x86\xe0\x41\x5a\xb8\x8a\xec\x84\x1d\x96\xb7\xb8\xaf\x41\xe0\x5b\xb4\x61\xa4\x06\x45\xbf\x17\x66\x01\xf1\xe7\x60\xde\x5f",
+ "\x60\x3f\x7b\x09\x56\x56\x34\xd4\x41\x0b\x57\x4a\x4d\xc9\xea\x46\x74\x37\x96\x45\x17\xe5\xef\xa5\x1a\x36\x2a\x30\xe8\xc6\x32\xc5\x51\x62\xa3\x35\x1b\xb5\x53\x2e\x40\x94\x8a\xa9\xa1\xe3\xa8\x78\x6c\x04\x22\xae\xc3\xec\x33\x8c\x7f\x4b\x57\x67\x92\x00\x45\x2b",
+ 238 },
+ { GCRY_MD_SHA3_512,
+ "\xd7\x82\xab\xb7\x2a\x5b\xe3\x39\x27\x57\xbe\x02\xd3\xe4\x5b\xe6\xe2\x09\x9d\x6f\x00\x0d\x04\x2c\x8a\x54\x3f\x50\xed\x6e\xbc\x05\x5a\x7f\x13\x3b\x0d\xd8\xe9\xbc\x34\x85\x36\xed\xca\xae\x2e\x12\xec\x18\xe8\x83\x7d\xf7\xa1\xb3\xc8\x7e\xc4\x6d\x50\xc2\x41\xde\xe8\x20\xfd\x58\x61\x97\x55\x2d\xc2\x0b\xee\xa5\x0f\x44\x5a\x07\xa3\x8f\x17\x68\xa3\x9e\x2b\x2f\xf0\x5d\xdd\xed\xf7\x51\xf1\xde\xf6\x12\xd2\xe4\xd8\x10\xda\xa3\xa0\xcc\x90\x45\x16\xf9\xa4\x3a\xf6\x60\x31\x53\x85\x17\x8a\x52\x9e\x51\xf8\xaa\xe1\x41\x80\x8c\x8b\xc5\xd7\xb6\x0c\xac\x26\xbb\x98\x4a\xc1\x89\x0d\x04\x36\xef\x78\x04\x26\xc5\x47\xe9\x4a\x7b\x08\xf0\x1a\xcb\xfc\x4a\x38\x25\xea\xe0\x4f\x52\x0a\x90\x16\xf2\xfb\x8b\xf5\x16\x5e\xd1\x27\x36\xfc\x71\xe3\x6a\x49\xa7\x36\x14\x73\x9e\xaa\x3e\xc8\x34\x06\x9b\x1b\x40\xf1\x35\x0c\x2b\x3a\xb8\x85\xc0\x2c\x64\x0b\x9f\x76\x86\xed\x5f\x99\x52\x7e\x41\xcf\xcd\x79\x6f\xe4\xc2\x56\xc9\x17\x31\x86\xc2\x26\x16\x9f\xf2\x57\x95\x4e\xbd\xa8\x1c\x0e\x5f\x99",
+ "\x10\x18\x69\x2d\x53\x0c\x55\xba\xa5\x80\xae\x1e\x73\x84\x35\x11\x00\xd4\x63\x7c\xd3\x38\x69\xc7\x1e\x60\x76\xa3\xd4\xe3\x10\xd9\x64\xb8\x1d\x59\x3e\x89\x71\x88\x45\xac\x7a\x89\xe8\xad\x50\x73\x50\x64\x27\xc6\xc8\xf7\xfa\xdf\xa0\xc5\xdc\x3c\xfa\xa5\xd9\x24",
+ 239 },
+ { GCRY_MD_SHA3_512,
+ "\x5f\xce\x81\x09\xa3\x58\x57\x0e\x40\x98\x3e\x11\x84\xe5\x41\x83\x3b\xb9\x09\x1e\x28\x0f\x25\x8c\xfb\x14\x43\x87\xb0\x5d\x19\x0e\x43\x1c\xb1\x9b\xaa\x67\x27\x3b\xa0\xc5\x8a\xbe\x91\x30\x8e\x18\x44\xdc\xd0\xb3\x67\x8b\xaa\x42\xf3\x35\xf2\xfa\x05\x26\x7a\x02\x40\xb3\xc7\x18\xa5\x94\x2b\x3b\x3e\x3b\xfa\x98\xa5\x5c\x25\xa1\x46\x6e\x8d\x7a\x60\x37\x22\xcb\x2b\xbf\x03\xaf\xa5\x4c\xd7\x69\xa9\x9f\x31\x07\x35\xee\x5a\x05\xda\xe2\xc2\x2d\x39\x7b\xd9\x56\x35\xf5\x8c\x48\xa6\x7f\x90\xe1\xb7\x3a\xaf\xcd\x3f\x82\x11\x7f\x01\x66\x65\x78\x38\x69\x10\x05\xb1\x8d\xa6\xf3\x41\xd6\xe9\x0f\xc1\xcd\xb3\x52\xb3\x0f\xae\x45\xd3\x48\x29\x4e\x50\x1b\x63\x25\x2d\xe1\x47\x40\xf2\xb8\x5a\xe5\x29\x9d\xde\xc3\x17\x2d\xe8\xb6\xd0\xba\x21\x9a\x20\xa2\x3b\xb5\xe1\x0f\xf4\x34\xd3\x9d\xb3\xf5\x83\x30\x5e\x9f\x5c\x03\x9d\x98\x56\x9e\x37\x7b\x75\xa7\x0a\xb8\x37\xd1\xdf\x26\x9b\x8a\x4b\x56\x6f\x40\xbb\x91\xb5\x77\x45\x5f\xd3\xc3\x56\xc9\x14\xfa\x06\xb9\xa7\xce\x24\xc7\x31\x7a\x17\x2d",
+ "\xe3\xc0\xea\xff\xc3\x56\x7b\xd7\x2c\xc0\x21\x50\xa7\x5f\x32\xdd\xe5\x3d\xe2\x65\x2c\x53\x13\xeb\x3e\x97\x01\x8a\xdd\xdf\x62\x9d\xa0\x1d\x97\xd0\xa9\xe2\x51\x94\x51\xa7\x29\x2f\x5d\xe0\x0e\xe4\x45\x6f\xe6\xe4\xf1\x4f\x96\xd5\xde\x7e\x6f\x17\x4e\xdb\x28\xc4",
+ 240 },
+ { GCRY_MD_SHA3_512,
+ "\x61\x72\xf1\x97\x1a\x6e\x1e\x4e\x61\x70\xaf\xba\xd9\x5d\x5f\xec\x99\xbf\x69\xb2\x4b\x67\x4b\xc1\x7d\xd7\x80\x11\x61\x5e\x50\x2d\xe6\xf5\x6b\x86\xb1\xa7\x1d\x3f\x43\x48\x08\x72\x18\xac\x7b\x7d\x09\x30\x29\x93\xbe\x27\x2e\x4a\x59\x19\x68\xae\xf1\x8a\x12\x62\xd6\x65\x61\x0d\x10\x70\xee\x91\xcc\x8d\xa3\x6e\x1f\x84\x1a\x69\xa7\xa6\x82\xc5\x80\xe8\x36\x94\x1d\x21\xd9\x09\xa3\xaf\xc1\xf0\xb9\x63\xe1\xca\x5a\xb1\x93\xe1\x24\xa1\xa5\x3d\xf1\xc5\x87\x47\x0e\x58\x81\xfb\x54\xda\xe1\xb0\xd8\x40\xf0\xc8\xf9\xd1\xb0\x4c\x64\x5b\xa1\x04\x1c\x7d\x8d\xbf\x22\x03\x0a\x62\x3a\xa1\x56\x38\xb3\xd9\x9a\x2c\x40\x0f\xf7\x6f\x32\x52\x07\x9a\xf8\x8d\x2b\x37\xf3\x5e\xe6\x6c\x1a\xd7\x80\x1a\x28\xd3\xd3\x88\xac\x45\x0b\x97\xd5\xf0\xf7\x9e\x45\x41\x75\x53\x56\xb3\xb1\xa5\x69\x6b\x02\x3f\x39\xab\x7a\xb5\xf2\x8d\xf4\x20\x29\x36\xbc\x97\x39\x3b\x93\xbc\x91\x5c\xb1\x59\xea\x1b\xd7\xa0\xa4\x14\xcb\x4b\x7a\x1a\xc3\xaf\x68\xf5\x0d\x79\xf0\xc9\xc7\x31\x4e\x75\x0f\x7d\x02\xfa\xa5\x8b\xfa",
+ "\x19\x2a\xe7\xa0\xf7\xa8\x16\xfd\x3d\x40\x20\xbd\xdc\xf2\xaa\xf5\x2a\x64\xe6\x38\x4d\xca\x52\x7f\x33\xaf\x4e\xe6\x90\x99\xdc\xa9\x7b\x89\x0a\x99\xcf\xab\x9d\x90\x4a\x35\xf2\x70\x78\x56\x69\x6c\x30\xc6\x43\x2d\xf7\x0a\x6c\xef\x70\x4b\xb2\x68\x05\x5a\x6d\x07",
+ 241 },
+ { GCRY_MD_SHA3_512,
+ "\x56\x68\xec\xd9\x9d\xfb\xe2\x15\xc4\x11\x83\x98\xac\x9c\x9e\xaf\x1a\x14\x33\xfa\xb4\xcc\xdd\x39\x68\x06\x47\x52\xb6\x25\xea\x94\x47\x31\xf7\x5d\x48\xa2\x7d\x04\x7d\x67\x54\x7f\x14\xdd\x0f\xfa\xa5\x5f\xa5\xe2\x9f\x7a\xf0\xd1\x61\xd8\x5e\xaf\xc4\xf2\x02\x9b\x71\x7c\x91\x8e\xab\x9d\x30\x45\x43\x29\x0b\xdb\xa7\x15\x8b\x68\x02\x0c\x0b\xa4\xe0\x79\xbc\x95\xb5\xbc\x0f\xc0\x44\xa9\x92\xb9\x4b\x4c\xcd\x3b\xd6\x6d\x0e\xab\xb5\xdb\xba\xb9\x04\xd6\x2e\x00\x75\x2c\x4e\x3b\x00\x91\xd7\x73\xbc\xf4\xc1\x4b\x43\x77\xda\x3e\xff\xf8\x24\xb1\xcb\x2f\xa0\x1b\x32\xd1\xe4\x6c\x90\x9e\x62\x6e\xd2\xda\xe9\x20\xf4\xc7\xdb\xeb\x63\x5b\xc7\x54\xfa\xcb\xd8\xd4\x9b\xeb\xa3\xf2\x3c\x1c\x41\xcc\xbf\xcd\x0e\xe0\xc1\x14\xe6\x97\x37\xf5\x59\x7c\x0b\xf1\xd8\x59\xf0\xc7\x67\xe1\x80\x02\xae\x8e\x39\xc2\x62\x61\xff\xde\x29\x20\xd3\xd0\xba\xf0\xe9\x06\x13\x86\x96\xcf\xe5\xb7\xe3\x2b\x60\x0f\x45\xdf\x3a\xaa\x39\x93\x2f\x3a\x7d\xf9\x5b\x60\xfa\x87\x12\xa2\x27\x1f\xca\xf3\x91\x1c\xe7\xb5\x11\xb1",
+ "\x6b\xcd\x7e\x7c\x35\x9f\xdd\x93\xa5\x6d\x79\xf9\x7f\xc2\xd5\x34\x61\x9f\x14\xfe\x44\x3a\xc8\xc9\xe0\x42\xc5\x10\x5f\xba\xf2\x77\x77\x18\xde\x07\x42\x4a\x62\x33\x3f\xfd\x43\xa5\x01\xa8\x54\x44\x49\xa7\xca\xc3\xc8\xd8\x21\xe3\x80\xb0\xcb\x81\x72\xb9\x49\x3b",
+ 242 },
+ { GCRY_MD_SHA3_512,
+ "\x03\xd6\x25\x48\x83\x54\xdf\x30\xe3\xf8\x75\xa6\x8e\xdf\xcf\x34\x0e\x83\x66\xa8\xe1\xab\x67\xf9\xd5\xc5\x48\x6a\x96\x82\x9d\xfa\xc0\x57\x82\x89\x08\x2b\x2a\x62\x11\x7e\x1c\xf4\x18\xb4\x3b\x90\xe0\xad\xc8\x81\xfc\x6a\xe8\x10\x5c\x88\x8e\x9e\xcd\x21\xae\xa1\xc9\xae\x1a\x40\x38\xdf\xd1\x73\x78\xfe\xd7\x1d\x02\xae\x49\x20\x87\xd7\xcd\xcd\x98\xf7\x46\x85\x52\x27\x96\x7c\xb1\xab\x47\x14\x26\x1e\xe3\xbe\xad\x3f\x4d\xb1\x18\x32\x9d\x3e\xbe\xf4\xbc\x48\xa8\x75\xc1\x9b\xa7\x63\x96\x6d\xa0\xeb\xea\x80\x0e\x01\xb2\xf5\x0b\x00\xe9\xdd\x4c\xac\xa6\xdc\xb3\x14\xd0\x01\x84\xef\x71\xea\x23\x91\xd7\x60\xc9\x50\x71\x0d\xb4\xa7\x0f\x92\x12\xff\xc5\x48\x61\xf9\xdc\x75\x2c\xe1\x88\x67\xb8\xad\x0c\x48\xdf\x84\x66\xef\x72\x31\xe7\xac\x56\x7f\x0e\xb5\x50\x99\xe6\x22\xeb\xb8\x6c\xb2\x37\x52\x01\x90\xa6\x1c\x66\xad\x34\xf1\xf4\xe2\x89\xcb\x32\x82\xae\x3e\xaa\xc6\x15\x2e\xd2\x4d\x2c\x92\xba\xe5\xa7\x65\x82\x52\xa5\x3c\x49\xb7\xb0\x2d\xfe\x54\xfd\xb2\xe9\x00\x74\xb6\xcf\x31\x0a\xc6\x61",
+ "\x1f\xcd\x1e\x38\xab\x03\xc7\x50\x36\x6c\xf8\x6d\xd7\x2e\xc3\xbf\x22\xf5\xbb\xf7\xfe\xa0\x14\x9d\x31\xb6\xa6\x7b\x68\xb5\x37\xb5\x9b\xa3\x79\x17\xfd\x88\xce\xd9\xaa\x8d\x29\x41\xa6\x5f\x55\x2b\x79\x28\xb3\x78\x5c\x66\xd6\x40\xf3\xb7\x4a\xf0\x39\xed\x18\xce",
+ 243 },
+ { GCRY_MD_SHA3_512,
+ "\x2e\xdc\x28\x2f\xfb\x90\xb9\x71\x18\xdd\x03\xaa\xa0\x3b\x14\x5f\x36\x39\x05\xe3\xcb\xd2\xd5\x0e\xcd\x69\x2b\x37\xbf\x00\x01\x85\xc6\x51\xd3\xe9\x72\x6c\x69\x0d\x37\x73\xec\x1e\x48\x51\x0e\x42\xb1\x77\x42\xb0\xb0\x37\x7e\x7d\xe6\xb8\xf5\x5e\x00\xa8\xa4\xdb\x47\x40\xce\xe6\xdb\x08\x30\x52\x9d\xd1\x96\x17\x50\x1d\xc1\xe9\x35\x9a\xa3\xbc\xf1\x47\xe0\xa7\x6b\x3a\xb7\x0c\x49\x84\xc1\x3e\x33\x9e\x68\x06\xbb\x35\xe6\x83\xaf\x85\x27\x09\x36\x70\x85\x9f\x3d\x8a\x0f\xc7\xd4\x93\xbc\xba\x6b\xb1\x2b\x5f\x65\xe7\x1e\x70\x5c\xa5\xd6\xc9\x48\xd6\x6e\xd3\xd7\x30\xb2\x6d\xb3\x95\xb3\x44\x77\x37\xc2\x6f\xad\x08\x9a\xa0\xad\x0e\x30\x6c\xb2\x8b\xf0\xac\xf1\x06\xf8\x9a\xf3\x74\x5f\x0e\xc7\x2d\x53\x49\x68\xcc\xa5\x43\xcd\x2c\xa5\x0c\x94\xb1\x45\x67\x43\x25\x4e\x35\x8c\x13\x17\xc0\x7a\x07\xbf\x2b\x0e\xca\x43\x8a\x70\x93\x67\xfa\xfc\x89\xa5\x72\x39\x02\x8f\xc5\xfe\xcf\xd5\x3b\x8e\xf9\x58\xef\x10\xee\x06\x08\xb7\xf5\xcb\x99\x23\xad\x97\x05\x8e\xc0\x67\x70\x0c\xc7\x46\xc1\x27\xa6\x1e\xe3",
+ "\xf3\x9e\xf0\x62\x6d\x3f\xbd\x9c\xd4\x35\xa9\x3e\x7e\xee\x41\xe4\xa2\xff\x53\x62\xf5\x6c\x98\x8b\x20\x87\x0a\x3b\xef\xa5\x04\x70\xdc\x5f\xab\xe3\x98\x95\xc0\x76\x12\x89\xfa\xfd\x91\x47\xab\xab\x02\x56\x1f\x30\x0d\x0c\xeb\x9a\x73\x2e\x14\xca\x88\x7c\xaf\x18",
+ 244 },
+ { GCRY_MD_SHA3_512,
+ "\x90\xb2\x8a\x6a\xa1\xfe\x53\x39\x15\xbc\xb8\xe8\x1e\xd6\xca\xcd\xc1\x09\x62\xb7\xff\x82\x47\x4f\x84\x5e\xeb\x86\x97\x76\x00\xcf\x70\xb0\x7b\xa8\xe3\x79\x61\x41\xee\x34\x0e\x3f\xce\x84\x2a\x38\xa5\x0a\xfb\xe9\x03\x01\xa3\xbd\xcc\x59\x1f\x2e\x7d\x9d\xe5\x3e\x49\x55\x25\x56\x0b\x90\x8c\x89\x24\x39\x99\x0a\x2c\xa2\x67\x9c\x55\x39\xff\xdf\x63\x67\x77\xad\x9c\x1c\xde\xf8\x09\xcd\xa9\xe8\xdc\xdb\x45\x1a\xbb\x9e\x9c\x17\xef\xa4\x37\x9a\xbd\x24\xb1\x82\xbd\x98\x1c\xaf\xc7\x92\x64\x0a\x18\x3b\x61\x69\x43\x01\xd0\x4c\x5b\x3e\xaa\xd6\x94\xa6\xbd\x4c\xc0\x6e\xf5\xda\x8f\xa2\x3b\x4f\xa2\xa6\x45\x59\xc5\xa6\x83\x97\x93\x00\x79\xd2\x50\xc5\x1b\xcf\x00\xe2\xb1\x6a\x6c\x49\x17\x14\x33\xb0\xaa\xdf\xd8\x02\x31\x27\x65\x60\xb8\x04\x58\xdd\x77\x08\x9b\x7a\x1b\xbc\xc9\xe7\xe4\xb9\xf8\x81\xea\xcd\x6c\x92\xc4\x31\x83\x48\xa1\x3f\x49\x14\xeb\x27\x11\x5a\x1c\xfc\x5d\x16\xd7\xfd\x94\x95\x4c\x35\x32\xef\xac\xa2\xca\xb0\x25\x10\x3b\x2d\x02\xc6\xfd\x71\xda\x3a\x77\xf4\x17\xd7\x93\x26\x85\x88\x8a",
+ "\x81\xe8\xb5\x9d\xdc\xd2\x48\x11\xb4\x05\xf7\x52\x9d\xa1\x25\xf0\xdc\x19\xae\x21\xe8\x79\x5c\xe9\xe6\x69\x2d\xab\x64\x5b\x79\x59\x44\x6a\xdc\xaa\x30\x61\xdc\x46\x42\xa5\x1d\x8a\x56\x2e\xfb\x03\xa7\x68\x0a\xf0\xf5\x2c\x01\x40\x6d\x5c\x21\x3e\xaa\xc6\xbe\x55",
+ 245 },
+ { GCRY_MD_SHA3_512,
+ "\x29\x69\x44\x7d\x17\x54\x90\xf2\xaa\x9b\xb0\x55\x01\x4d\xbe\xf2\xe6\x85\x4c\x95\xf8\xd6\x09\x50\xbf\xe8\xc0\xbe\x8d\xe2\x54\xc2\x6b\x2d\x31\xb9\xe4\xde\x9c\x68\xc9\xad\xf4\x9e\x4e\xe9\xb1\xc2\x85\x09\x67\xf2\x9f\x5d\x08\x73\x84\x83\xb4\x17\xbb\x96\xb2\xa5\x6f\x0c\x8a\xca\x63\x2b\x55\x20\x59\xc5\x9a\xac\x3f\x61\xf7\xb4\x5c\x96\x6b\x75\xf1\xd9\x93\x1f\xf4\xe5\x96\x40\x63\x78\xce\xe9\x1a\xaa\x72\x6a\x3a\x84\xc3\x3f\x37\xe9\xcd\xbe\x62\x6b\x57\x45\xa0\xb0\x60\x64\xa8\xa8\xd5\x6e\x53\xaa\xf1\x02\xd2\x3d\xd9\xdf\x0a\x3f\xdf\x7a\x63\x85\x09\xa6\x76\x1a\x33\xfa\x42\xfa\x8d\xdb\xd8\xe1\x61\x59\xc9\x30\x08\xb5\x37\x65\x01\x9c\x3f\x0e\x9f\x10\xb1\x44\xce\x2a\xc5\x7f\x5d\x72\x97\xf9\xc9\x94\x9e\x4f\xf6\x8b\x70\xd3\x39\xf8\x75\x01\xce\x85\x50\xb7\x72\xf3\x2c\x6d\xa8\xad\x2c\xe2\x10\x0a\x89\x5d\x8b\x08\xfa\x1e\xea\xd7\xc3\x76\xb4\x07\x70\x97\x03\xc5\x10\xb5\x0f\x87\xe7\x3e\x43\xf8\xe7\x34\x8f\x87\xc3\x83\x2a\x54\x7e\xf2\xbb\xe5\x79\x9a\xbe\xdc\xf5\xe1\xf3\x72\xea\x80\x92\x33\xf0\x06",
+ "\x63\x42\x4b\x09\x06\x9f\xbd\x2d\x0f\xac\x00\x80\x5a\xad\x07\xfd\x56\xe3\x0b\xb8\x11\x6b\x54\x76\xae\x90\xbf\x6a\xce\xc8\x4c\x3b\x45\x36\x8a\x9e\xbb\x7f\xce\xa8\xd6\x59\x65\xf5\x25\x14\xa2\xa5\x9a\x06\xe6\xe0\x6b\x07\xdc\x6a\xee\x7f\x75\x6b\xfc\x18\x8e\x25",
+ 246 },
+ { GCRY_MD_SHA3_512,
+ "\x72\x16\x45\x63\x3a\x44\xa2\xc7\x8b\x19\x02\x4e\xae\xcf\x58\x57\x5a\xb2\x3c\x27\x19\x08\x33\xc2\x68\x75\xdc\x0f\x0d\x50\xb4\x6a\xea\x9c\x34\x3d\x82\xea\x7d\x5b\x3e\x50\xec\x70\x05\x45\xc6\x15\xda\xea\xea\x64\x72\x6a\x0f\x05\x60\x75\x76\xdc\xd3\x96\xd8\x12\xb0\x3f\xb6\x55\x1c\x64\x10\x87\x85\x6d\x05\x0b\x10\xe6\xa4\xd5\x57\x7b\x82\xa9\x8a\xfb\x89\xce\xe8\x59\x4c\x9d\xc1\x9e\x79\xfe\xff\x03\x82\xfc\xfd\x12\x7f\x1b\x80\x3a\x4b\x99\x46\xf4\xac\x9a\x43\x78\xe1\xe6\xe0\x41\xb1\x38\x9a\x53\xe3\x45\x0c\xd3\x2d\x9d\x29\x41\xb0\xcb\xab\xdb\x50\xda\x8e\xa2\x51\x31\x45\x16\x4c\x3a\xb6\xbc\xbd\x25\x1c\x44\x8d\x2d\x4b\x08\x7a\xc5\x7a\x59\xc2\x28\x5d\x56\x4f\x16\xda\x4e\xd5\xe6\x07\xed\x97\x95\x92\x14\x6f\xfb\x0e\xf3\xf3\xdb\x30\x8f\xb3\x42\xdf\x5e\xb5\x92\x4a\x48\x25\x6f\xc7\x63\x14\x1a\x27\x88\x14\xc8\x2d\x6d\x63\x48\x57\x75\x45\x87\x0a\xe3\xa8\x3c\x72\x30\xac\x02\xa1\x54\x0f\xe1\x79\x8f\x7e\xf0\x9e\x33\x5a\x86\x5a\x2a\xe0\x94\x9b\x21\xe4\xf7\x48\xfb\x8a\x51\xf4\x47\x50\xe2\x13\xa8\xfb",
+ "\x1e\x70\x9f\xb3\x50\x1f\xa8\x18\xf5\x7e\x70\xc3\x65\xdb\x45\xcc\xf2\xeb\x8a\x8f\xa6\x6d\xe9\xb5\xf2\x11\xd6\xf0\xcc\x97\x22\xad\xe9\x63\xc9\x65\xad\x5f\x69\x37\xba\x62\xed\xc2\xd8\x98\x38\x43\xe0\xf3\x67\x9d\x9c\x97\xb3\x0c\xd5\x4f\x24\x09\xdd\xa5\xf4\x74",
+ 247 },
+ { GCRY_MD_SHA3_512,
+ "\x6b\x86\x0d\x39\x72\x5a\x14\xb4\x98\xbb\x71\x45\x74\xb4\xd3\x7c\xa7\x87\x40\x47\x68\xf6\x4c\x64\x8b\x17\x51\xb3\x53\xac\x92\xba\xc2\xc3\xa2\x8e\xa9\x09\xfd\xf0\x42\x33\x36\x40\x1a\x02\xe6\x3e\xc2\x43\x25\x30\x0d\x82\x3b\x68\x64\xbb\x70\x1f\x9d\x7c\x7a\x1f\x8e\xc9\xd0\xae\x35\x84\xaa\x6d\xd6\x2e\xa1\x99\x7c\xd8\x31\xb4\xba\xbd\x9a\x4d\xa5\x09\x32\xd4\xef\xda\x74\x5c\x61\xe4\x13\x08\x90\xe1\x56\xae\xe6\x11\x37\x16\xda\xf9\x57\x64\x22\x2a\x91\x18\x7d\xb2\xef\xfe\xa4\x9d\x5d\x05\x96\x10\x2d\x61\x9b\xd2\x6a\x61\x6b\xbf\xda\x83\x35\x50\x5f\xbb\x0d\x90\xb4\xc1\x80\xd1\xa2\x33\x5b\x91\x53\x8e\x16\x68\xf9\xf9\x64\x27\x90\xb4\xe5\x5f\x9c\xab\x0f\xe2\xbd\xd2\x93\x5d\x00\x1e\xe6\x41\x9a\xba\xb5\x45\x78\x80\xd0\xdb\xff\x20\xed\x87\x58\xf4\xc2\x0f\xe7\x59\xef\xb3\x31\x41\xcf\x0e\x89\x25\x87\xfe\x81\x87\xe5\xfb\xc5\x77\x86\xb7\xe8\xb0\x89\x61\x2c\x93\x6d\xfc\x03\xd2\x7e\xfb\xbe\x7c\x86\x73\xf1\x60\x6b\xd5\x1d\x5f\xf3\x86\xf4\xa7\xab\x68\xed\xf5\x9f\x38\x5e\xb1\x29\x1f\x11\x7b\xfe\x71\x73\x99",
+ "\x5b\x9f\x0c\x54\x46\x27\xfa\xad\xea\x82\x82\x5a\x56\x9d\xa3\x3a\x75\xc5\xda\x6c\xc1\x69\x92\x6d\xe0\x55\x6a\x73\x7e\x4d\xaa\x07\xab\xf1\xdc\x3d\xb0\x70\x4f\x5d\x67\xfc\xbc\x4c\xb6\x2a\xac\x44\x2e\xce\xc8\x67\xa2\xc1\x68\x46\xf1\xd5\x3d\x20\x5c\xb8\x72\xac",
+ 248 },
+ { GCRY_MD_SHA3_512,
+ "\x6a\x01\x83\x0a\xf3\x88\x9a\x25\x18\x32\x44\xde\xcb\x50\x8b\xd0\x12\x53\xd5\xb5\x08\xab\x49\x0d\x31\x24\xaf\xbf\x42\x62\x6b\x2e\x70\x89\x4e\x9b\x56\x2b\x28\x8d\x0a\x24\x50\xcf\xac\xf1\x4a\x0d\xda\xe5\xc0\x47\x16\xe5\xa0\x08\x2c\x33\x98\x1f\x60\x37\xd2\x3d\x5e\x04\x5e\xe1\xef\x22\x83\xfb\x8b\x63\x78\xa9\x14\xc5\xd9\x44\x16\x27\xa7\x22\xc2\x82\xff\x45\x2e\x25\xa7\xea\x60\x8d\x69\xce\xe4\x39\x3a\x07\x25\xd1\x79\x63\xd0\x34\x26\x84\xf2\x55\x49\x6d\x8a\x18\xc2\x96\x11\x45\x31\x51\x30\x54\x93\x11\xfc\x07\xf0\x31\x2f\xb7\x8e\x60\x77\x33\x4f\x87\xea\xa8\x73\xbe\xe8\xaa\x95\x69\x89\x96\xeb\x21\x37\x5e\xb2\xb4\xef\x53\xc1\x44\x01\x20\x7d\xeb\x45\x68\x39\x8e\x5d\xd9\xa7\xcf\x97\xe8\xc9\x66\x3e\x23\x33\x4b\x46\x91\x2f\x83\x44\xc1\x9e\xfc\xf8\xc2\xba\x6f\x04\x32\x5f\x1a\x27\xe0\x62\xb6\x2a\x58\xd0\x76\x6f\xc6\xdb\x4d\x2c\x6a\x19\x28\x60\x4b\x01\x75\xd8\x72\xd1\x6b\x79\x08\xeb\xc0\x41\x76\x11\x87\xcc\x78\x55\x26\xc2\xa3\x87\x3f\xea\xc3\xa6\x42\xbb\x39\xf5\x35\x15\x50\xaf\x97\x70\xc3\x28\xaf\x7b",
+ "\x93\x0a\xb4\x2a\x9f\x5f\x5b\xc5\xf2\x22\x2c\x74\x8f\x24\x78\xa0\x0f\x40\xc3\xb6\xd6\x48\x7d\x6d\x7e\xd0\xd7\x11\x00\xf4\x0f\xcb\xb2\xc6\x65\x66\xea\x26\xad\x0a\x41\x76\x29\xf5\xa6\x1d\xca\x41\x1c\xcd\x21\xf7\x36\x7d\x30\x8f\x3b\x1b\x24\x90\x18\x24\xfa\x9b",
+ 249 },
+ { GCRY_MD_SHA3_512,
+ "\xb3\xc5\xe7\x4b\x69\x93\x3c\x25\x33\x10\x6c\x56\x3b\x4c\xa2\x02\x38\xf2\xb6\xe6\x75\xe8\x68\x1e\x34\xa3\x89\x89\x47\x85\xbd\xad\xe5\x96\x52\xd4\xa7\x3d\x80\xa5\xc8\x5b\xd4\x54\xfd\x1e\x9f\xfd\xad\x1c\x38\x15\xf5\x03\x8e\x9e\xf4\x32\xaa\xc5\xc3\xc4\xfe\x84\x0c\xc3\x70\xcf\x86\x58\x0a\x60\x11\x77\x8b\xbe\xda\xf5\x11\xa5\x1b\x56\xd1\xa2\xeb\x68\x39\x4a\xa2\x99\xe2\x6d\xa9\xad\xa6\xa2\xf3\x9b\x9f\xaf\xf7\xfb\xa4\x57\x68\x9b\x9c\x1a\x57\x7b\x2a\x1e\x50\x5f\xdf\x75\xc7\xa0\xa6\x4b\x1d\xf8\x1b\x3a\x35\x60\x01\xbf\x0d\xf4\xe0\x2a\x1f\xc5\x9f\x65\x1c\x9d\x58\x5e\xc6\x22\x4b\xb2\x79\xc6\xbe\xba\x29\x66\xe8\x88\x2d\x68\x37\x60\x81\xb9\x87\x46\x8e\x7a\xed\x1e\xf9\x0e\xbd\x09\x0a\xe8\x25\x79\x5c\xdc\xa1\xb4\xf0\x9a\x97\x9c\x8d\xfc\x21\xa4\x8d\x8a\x53\xcd\xbb\x26\xc4\xdb\x54\x7f\xc0\x6e\xfe\x2f\x98\x50\xed\xd2\x68\x5a\x46\x61\xcb\x49\x11\xf1\x65\xd4\xb6\x3e\xf2\x5b\x87\xd0\xa9\x6d\x3d\xff\x6a\xb0\x75\x89\x99\xaa\xd2\x14\xd0\x7b\xd4\xf1\x33\xa6\x73\x4f\xde\x44\x5f\xe4\x74\x71\x1b\x69\xa9\x8f\x7e\x2b",
+ "\x08\x20\x39\x43\xc5\x82\x10\xd3\xf8\x27\x58\x27\x2b\xef\xbb\x92\x34\xfe\x91\x34\x09\xa0\x79\x44\x64\x59\x59\xb1\xa6\xaf\x2f\x43\x63\xab\xd7\x45\x12\x32\x62\x3d\xaa\x8e\x65\xc8\x7f\x34\x93\x9c\x14\x06\x08\x95\x0f\xbd\xbb\xe8\x3d\x66\x40\x79\x44\xf5\x42\x3a",
+ 250 },
+ { GCRY_MD_SHA3_512,
+ "\x83\xaf\x34\x27\x9c\xcb\x54\x30\xfe\xbe\xc0\x7a\x81\x95\x0d\x30\xf4\xb6\x6f\x48\x48\x26\xaf\xee\x74\x56\xf0\x07\x1a\x51\xe1\xbb\xc5\x55\x70\xb5\xcc\x7e\xc6\xf9\x30\x9c\x17\xbf\x5b\xef\xdd\x7c\x6b\xa6\xe9\x68\xcf\x21\x8a\x2b\x34\xbd\x5c\xf9\x27\xab\x84\x6e\x38\xa4\x0b\xbd\x81\x75\x9e\x9e\x33\x38\x10\x16\xa7\x55\xf6\x99\xdf\x35\xd6\x60\x00\x7b\x5e\xad\xf2\x92\xfe\xef\xb7\x35\x20\x7e\xbf\x70\xb5\xbd\x17\x83\x4f\x7b\xfa\x0e\x16\xcb\x21\x9a\xd4\xaf\x52\x4a\xb1\xea\x37\x33\x4a\xa6\x64\x35\xe5\xd3\x97\xfc\x0a\x06\x5c\x41\x1e\xbb\xce\x32\xc2\x40\xb9\x04\x76\xd3\x07\xce\x80\x2e\xc8\x2c\x1c\x49\xbc\x1b\xec\x48\xc0\x67\x5e\xc2\xa6\xc6\xf3\xed\x3e\x5b\x74\x1d\x13\x43\x70\x95\x70\x7c\x56\x5e\x10\xd8\xa2\x0b\x8c\x20\x46\x8f\xf9\x51\x4f\xcf\x31\xb4\x24\x9c\xd8\x2d\xce\xe5\x8c\x0a\x2a\xf5\x38\xb2\x91\xa8\x7e\x33\x90\xd7\x37\x19\x1a\x07\x48\x4a\x5d\x3f\x3f\xb8\xc8\xf1\x5c\xe0\x56\xe5\xe5\xf8\xfe\xbe\x5e\x1f\xb5\x9d\x67\x40\x98\x0a\xa0\x6c\xa8\xa0\xc2\x0f\x57\x12\xb4\xcd\xe5\xd0\x32\xe9\x2a\xb8\x9f\x0a\xe1",
+ "\xa2\x4d\xd6\xa5\x03\x33\xf2\x89\xc1\x75\xcd\x4e\xc1\x85\xda\x99\x06\xe3\x8c\x28\x7a\x33\x9d\xc4\xde\xfa\xfd\x71\xb2\xea\x32\xa6\xf6\xae\xfe\x75\x8e\x25\xfc\x8f\x04\x3e\x80\x6f\x1b\x2e\xe0\x19\xe1\x3b\x85\x53\x6c\xd3\xef\xaa\x2a\x9b\x59\x94\xfc\xae\x47\x88",
+ 251 },
+ { GCRY_MD_SHA3_512,
+ "\xa7\xed\x84\x74\x9c\xcc\x56\xbb\x1d\xfb\xa5\x71\x19\xd2\x79\xd4\x12\xb8\xa9\x86\x88\x6d\x81\x0f\x06\x7a\xf3\x49\xe8\x74\x9e\x9e\xa7\x46\xa6\x0b\x03\x74\x26\x36\xc4\x64\xfc\x1e\xe2\x33\xac\xc5\x2c\x19\x83\x91\x46\x92\xb6\x43\x09\xed\xfd\xf2\x9f\x1a\xb9\x12\xec\x3e\x8d\xa0\x74\xd3\xf1\xd2\x31\x51\x1f\x57\x56\xf0\xb6\xee\xad\x3e\x89\xa6\xa8\x8f\xe3\x30\xa1\x0f\xac\xe2\x67\xbf\xfb\xfc\x3e\x30\x90\xc7\xfd\x9a\x85\x05\x61\xf3\x63\xad\x75\xea\x88\x1e\x72\x44\xf8\x0f\xf5\x58\x02\xd5\xef\x7a\x1a\x4e\x7b\x89\xfc\xfa\x80\xf1\x6d\xf5\x4d\x1b\x05\x6e\xe6\x37\xe6\x96\x4b\x9e\x0f\xfd\x15\xb6\x19\x6b\xdd\x7d\xb2\x70\xc5\x6b\x47\x25\x14\x85\x34\x8e\x49\x81\x3b\x4e\xb9\xed\x12\x2a\x01\xb3\xea\x45\xad\x5e\x1a\x92\x9d\xf6\x1d\x5c\x0f\x3e\x77\xe1\xfd\xc3\x56\xb6\x38\x83\xa6\x0e\x9c\xbb\x9f\xc3\xe0\x0c\x2f\x32\xdb\xd4\x69\x65\x98\x83\xf6\x90\xc6\x77\x2e\x33\x5f\x61\x7b\xc3\x3f\x16\x1d\x6f\x69\x84\x25\x2e\xe1\x2e\x62\xb6\x00\x0a\xc5\x23\x1e\x0c\x9b\xc6\x5b\xe2\x23\xd8\xdf\xd9\x4c\x50\x04\xa1\x01\xaf\x9f\xd6\xc0\xfb",
+ "\xcd\x1e\xd5\xff\xf6\xfa\x3d\x45\x38\x72\x51\x0b\x6b\x27\x12\xec\x9c\x6e\xba\x95\x43\x73\x4d\x88\x51\x1e\xd4\x75\x90\x5e\x12\x3e\xd6\xef\x66\x24\xf2\x20\x44\x5f\xe8\x9c\x25\x7a\x9f\x9c\x51\x66\xa2\x77\x2e\xf7\x68\xb5\x0e\x92\x90\xfb\x1d\x47\x61\xec\xa6\xc8",
+ 252 },
+ { GCRY_MD_SHA3_512,
+ "\xa6\xfe\x30\xdc\xfc\xda\x1a\x32\x9e\x82\xab\x50\xe3\x2b\x5f\x50\xeb\x25\xc8\x73\xc5\xd2\x30\x58\x60\xa8\x35\xae\xce\xe6\x26\x4a\xa3\x6a\x47\x42\x99\x22\xc4\xb8\xb3\xaf\xd0\x0d\xa1\x60\x35\x83\x0e\xdb\x89\x78\x31\xc4\xe7\xb0\x0f\x2c\x23\xfc\x0b\x15\xfd\xc3\x0d\x85\xfb\x70\xc3\x0c\x43\x1c\x63\x8e\x1a\x25\xb5\x1c\xaf\x1d\x7e\x8b\x05\x0b\x7f\x89\xbf\xb3\x0f\x59\xf0\xf2\x0f\xec\xff\x3d\x63\x9a\xbc\x42\x55\xb3\x86\x8f\xc4\x5d\xd8\x1e\x47\xeb\x12\xab\x40\xf2\xaa\xc7\x35\xdf\x5d\x1d\xc1\xad\x99\x7c\xef\xc4\xd8\x36\xb8\x54\xce\xe9\xac\x02\x90\x00\x36\xf3\x86\x7f\xe0\xd8\x4a\xff\xf3\x7b\xde\x33\x08\xc2\x20\x6c\x62\xc4\x74\x33\x75\x09\x41\x08\x87\x7c\x73\xb8\x7b\x25\x46\xfe\x05\xea\x13\x7b\xed\xfc\x06\xa2\x79\x62\x74\x09\x9a\x0d\x55\x4d\xa8\xf7\xd7\x22\x3a\x48\xcb\xf3\x1b\x7d\xec\xaa\x1e\xbc\x8b\x14\x57\x63\xe3\x67\x31\x68\xc1\xb1\xb7\x15\xc1\xcd\x99\xec\xd3\xdd\xb2\x38\xb0\x60\x49\x88\x5e\xca\xd9\x34\x7c\x24\x36\xdf\xf3\x2c\x77\x1f\x34\xa3\x85\x87\xa4\x4a\x82\xc5\xd3\xd1\x37\xa0\x3c\xaa\x27\xe6\x6c\x8f\xf6",
+ "\xcf\xaa\x0e\xb1\xc9\xf0\x2c\x04\x69\xee\xfb\x31\xa1\xa5\x3c\xa1\xa4\x76\x5f\x78\xec\x17\x1c\xf1\x5d\xa7\xd5\xc5\x12\x81\x7b\x8b\xf7\xd7\xcd\x7b\x14\x16\xb3\xde\x2b\xba\x05\xed\xfb\x0b\x49\x34\x95\xac\x21\x07\xa4\xb6\x86\xd5\xdd\x8d\x6a\xd4\x1b\x4a\xa3\xd7",
+ 253 },
+ { GCRY_MD_SHA3_512,
+ "\x83\x16\x7f\xf5\x37\x04\xc3\xaa\x19\xe9\xfb\x33\x03\x53\x97\x59\xc4\x6d\xd4\x09\x1a\x52\xdd\xae\x9a\xd8\x64\x08\xb6\x93\x35\x98\x9e\x61\x41\x4b\xc2\x0a\xb4\xd0\x12\x20\xe3\x52\x41\xef\xf5\xc9\x52\x2b\x07\x9f\xba\x59\x76\x74\xc8\xd7\x16\xfe\x44\x1e\x56\x61\x10\xb6\x21\x15\x31\xce\xcc\xf8\xfd\x06\xbc\x8e\x51\x1d\x00\x78\x5e\x57\x78\x8e\xd9\xa1\xc5\xc7\x35\x24\xf0\x18\x30\xd2\xe1\x14\x8c\x92\xd0\xed\xc9\x71\x13\xe3\xb7\xb5\xcd\x30\x49\x62\x7a\xbd\xb8\xb3\x9d\xd4\xd6\x89\x0e\x0e\xe9\x19\x93\xf9\x2b\x03\x35\x4a\x88\xf5\x22\x51\xc5\x46\xe6\x44\x34\xd9\xc3\xd7\x45\x44\xf2\x3f\xb9\x3e\x5a\x2d\x2f\x1f\xb1\x55\x45\xb4\xe1\x36\x7c\x97\x33\x5b\x02\x91\x94\x4c\x8b\x73\x0a\xd3\xd4\x78\x92\x73\xfa\x44\xfb\x98\xd7\x8a\x36\xc3\xc3\x76\x4a\xbe\xea\xc7\xc5\x69\xc1\xe4\x3a\x35\x2e\x5b\x77\x0c\x35\x04\xf8\x70\x90\xde\xe0\x75\xa1\xc4\xc8\x5c\x0c\x39\xcf\x42\x1b\xdc\xc6\x15\xf9\xef\xf6\xcb\x4f\xe6\x46\x80\x04\xae\xce\x5f\x30\xe1\xec\xc6\xdb\x22\xad\x99\x39\xbb\x2b\x0c\xcc\x96\x52\x1d\xfb\xf4\xae\x00\x8b\x5b\x46\xbc\x00\x6e",
+ "\x2b\xe7\x1e\xe9\xac\xe2\xdb\xcf\xd4\x3d\x6d\x02\x0c\x07\x24\x45\x54\xda\xc8\xa2\xcf\x15\x71\xd0\xfa\x1d\x00\x49\x33\x73\x9e\x89\x78\x32\x30\x56\x79\x7e\x04\xc3\x33\xf5\xbf\x18\x7e\x64\xf1\xd8\x81\xe5\x02\x67\x25\x67\xf2\x04\xde\x0e\x73\xce\x26\xe7\x19\x0d",
+ 254 },
+ { GCRY_MD_SHA3_512,
+ "\x3a\x3a\x81\x9c\x48\xef\xde\x2a\xd9\x14\xfb\xf0\x0e\x18\xab\x6b\xc4\xf1\x45\x13\xab\x27\xd0\xc1\x78\xa1\x88\xb6\x14\x31\xe7\xf5\x62\x3c\xb6\x6b\x23\x34\x67\x75\xd3\x86\xb5\x0e\x98\x2c\x49\x3a\xdb\xbf\xc5\x4b\x9a\x3c\xd3\x83\x38\x23\x36\xa1\xa0\xb2\x15\x0a\x15\x35\x8f\x33\x6d\x03\xae\x18\xf6\x66\xc7\x57\x3d\x55\xc4\xfd\x18\x1c\x29\xe6\xcc\xfd\xe6\x3e\xa3\x5f\x0a\xdf\x58\x85\xcf\xc0\xa3\xd8\x4a\x2b\x2e\x4d\xd2\x44\x96\xdb\x78\x9e\x66\x31\x70\xce\xf7\x47\x98\xaa\x1b\xbc\xd4\x57\x4e\xa0\xbb\xa4\x04\x89\xd7\x64\xb2\xf8\x3a\xad\xc6\x6b\x14\x8b\x4a\x0c\xd9\x52\x46\xc1\x27\xd5\x87\x1c\x4f\x11\x41\x86\x90\xa5\xdd\xf0\x12\x46\xa0\xc8\x0a\x43\xc7\x00\x88\xb6\x18\x36\x39\xdc\xfd\xa4\x12\x5b\xd1\x13\xa8\xf4\x9e\xe2\x3e\xd3\x06\xfa\xac\x57\x6c\x3f\xb0\xc1\xe2\x56\x67\x1d\x81\x7f\xc2\x53\x4a\x52\xf5\xb4\x39\xf7\x2e\x42\x4d\xe3\x76\xf4\xc5\x65\xcc\xa8\x23\x07\xdd\x9e\xf7\x6d\xa5\xb7\xc4\xeb\x7e\x08\x51\x72\xe3\x28\x80\x7c\x02\xd0\x11\xff\xbf\x33\x78\x53\x78\xd7\x9d\xc2\x66\xf6\xa5\xbe\x6b\xb0\xe4\xa9\x2e\xce\xeb\xae\xb1",
+ "\x6e\x8b\x8b\xd1\x95\xbd\xd5\x60\x68\x9a\xf2\x34\x8b\xdc\x74\xab\x7c\xd0\x5e\xd8\xb9\xa5\x77\x11\xe9\xbe\x71\xe9\x72\x6f\xda\x45\x91\xfe\xe1\x22\x05\xed\xac\xaf\x82\xff\xbb\xaf\x16\xdf\xf9\xe7\x02\xa7\x08\x86\x20\x80\x16\x6c\x2f\xf6\xba\x37\x9b\xc7\xff\xc2",
+ 255 },
diff --git a/comm/third_party/libgcrypt/tests/stopwatch.h b/comm/third_party/libgcrypt/tests/stopwatch.h
new file mode 100644
index 0000000000..696e3005b7
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/stopwatch.h
@@ -0,0 +1,113 @@
+/* stopwatch.h - Helper code for timing
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <time.h>
+#ifdef _WIN32
+# include <winsock2.h>
+# include <windows.h>
+#else
+# include <sys/times.h>
+#endif
+
+
+#ifdef _WIN32
+struct
+{
+ FILETIME creation_time, exit_time, kernel_time, user_time;
+} started_at, stopped_at;
+#else
+static clock_t started_at, stopped_at;
+#endif
+
+
+static void
+start_timer (void)
+{
+#ifdef _WIN32
+#ifdef __MINGW32CE__
+ GetThreadTimes (GetCurrentThread (),
+ &started_at.creation_time, &started_at.exit_time,
+ &started_at.kernel_time, &started_at.user_time);
+#else
+ GetProcessTimes (GetCurrentProcess (),
+ &started_at.creation_time, &started_at.exit_time,
+ &started_at.kernel_time, &started_at.user_time);
+#endif
+ stopped_at = started_at;
+#else
+ struct tms tmp;
+
+ times (&tmp);
+ started_at = stopped_at = tmp.tms_utime;
+#endif
+}
+
+static void
+stop_timer (void)
+{
+#ifdef _WIN32
+#ifdef __MINGW32CE__
+ GetThreadTimes (GetCurrentThread (),
+ &stopped_at.creation_time, &stopped_at.exit_time,
+ &stopped_at.kernel_time, &stopped_at.user_time);
+#else
+ GetProcessTimes (GetCurrentProcess (),
+ &stopped_at.creation_time, &stopped_at.exit_time,
+ &stopped_at.kernel_time, &stopped_at.user_time);
+#endif
+#else
+ struct tms tmp;
+
+ times (&tmp);
+ stopped_at = tmp.tms_utime;
+#endif
+}
+
+static const char *
+elapsed_time (unsigned int divisor)
+{
+ static char buf[50];
+#if _WIN32
+ unsigned long long t1, t2, t;
+
+ t1 = (((unsigned long long)started_at.kernel_time.dwHighDateTime << 32)
+ + started_at.kernel_time.dwLowDateTime);
+ t1 += (((unsigned long long)started_at.user_time.dwHighDateTime << 32)
+ + started_at.user_time.dwLowDateTime);
+ t2 = (((unsigned long long)stopped_at.kernel_time.dwHighDateTime << 32)
+ + stopped_at.kernel_time.dwLowDateTime);
+ t2 += (((unsigned long long)stopped_at.user_time.dwHighDateTime << 32)
+ + stopped_at.user_time.dwLowDateTime);
+ t = ((t2 - t1)/divisor)/10000;
+ if (divisor != 1)
+ snprintf (buf, sizeof buf, "%5.1fms", (double)t );
+ else
+ snprintf (buf, sizeof buf, "%5.0fms", (double)t );
+#else
+ if (divisor != 1)
+ snprintf (buf, sizeof buf, "%5.1fms",
+ ((((double) (stopped_at - started_at)/(double)divisor)
+ /CLOCKS_PER_SEC)*10000000));
+ else
+ snprintf (buf, sizeof buf, "%5.0fms",
+ (((double) (stopped_at - started_at)/CLOCKS_PER_SEC)*10000000));
+#endif
+ return buf;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-common.h b/comm/third_party/libgcrypt/tests/t-common.h
new file mode 100644
index 0000000000..e356c39ab2
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-common.h
@@ -0,0 +1,198 @@
+/* t-common.h - Common code for the tests.
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * This file is part of libgpg-error.
+ *
+ * libgpg-error 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.
+ *
+ * libgpg-error 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+
+#include "../src/gcrypt.h"
+
+#ifndef PGM
+# error Macro PGM not defined.
+#endif
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+# error config.h not included
+#endif
+
+/* A couple of useful macros. */
+#ifndef DIM
+# define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#endif
+#define DIMof(type,member) DIM(((type *)0)->member)
+#define xmalloc(a) gcry_xmalloc ((a))
+#define xcalloc(a,b) gcry_xcalloc ((a),(b))
+#define xstrdup(a) gcry_xstrdup ((a))
+#define xfree(a) gcry_free ((a))
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define xmalloc(a) gcry_xmalloc ((a))
+#define xcalloc(a,b) gcry_xcalloc ((a),(b))
+#define xstrdup(a) gcry_xstrdup ((a))
+#define xfree(a) gcry_free ((a))
+#define pass() do { ; } while (0)
+
+
+/* Standard global variables. */
+static const char *wherestr;
+static int verbose;
+static int debug;
+static int error_count;
+static int die_on_error;
+
+/* If we have a decent libgpg-error we can use some gcc attributes. */
+#ifdef GPGRT_ATTR_NORETURN
+static void die (const char *format, ...)
+ GPGRT_ATTR_UNUSED GPGRT_ATTR_NR_PRINTF(1,2);
+static void fail (const char *format, ...)
+ GPGRT_ATTR_UNUSED GPGRT_ATTR_PRINTF(1,2);
+static void info (const char *format, ...) \
+ GPGRT_ATTR_UNUSED GPGRT_ATTR_PRINTF(1,2);
+#endif /*GPGRT_ATTR_NORETURN*/
+
+
+/* Reporting functions. */
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr ;
+
+ /* Avoid warning. */
+ (void) debug;
+
+ fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+ flockfile (stderr);
+#endif
+ fprintf (stderr, "%s: ", PGM);
+ if (wherestr)
+ fprintf (stderr, "%s: ", wherestr);
+ va_start (arg_ptr, format) ;
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ if (*format && format[strlen(format)-1] != '\n')
+ putc ('\n', stderr);
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stderr);
+#endif
+ exit (1);
+}
+
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+ flockfile (stderr);
+#endif
+ fprintf (stderr, "%s: ", PGM);
+ if (wherestr)
+ fprintf (stderr, "%s: ", wherestr);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ if (*format && format[strlen(format)-1] != '\n')
+ putc ('\n', stderr);
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stderr);
+#endif
+ if (die_on_error)
+ exit (1);
+ error_count++;
+ if (error_count >= 50)
+ die ("stopped after 50 errors.");
+}
+
+
+static void
+info (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ if (!verbose)
+ return;
+#ifdef HAVE_FLOCKFILE
+ flockfile (stderr);
+#endif
+ fprintf (stderr, "%s: ", PGM);
+ if (wherestr)
+ fprintf (stderr, "%s: ", wherestr);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ if (*format && format[strlen(format)-1] != '\n')
+ putc ('\n', stderr);
+ va_end (arg_ptr);
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stderr);
+#endif
+}
+
+
+/* Convenience macro for initializing gcrypt with error checking. */
+#define xgcry_control(cmd) \
+ do { \
+ gcry_error_t err__ = gcry_control cmd; \
+ if (err__) \
+ die ("line %d: gcry_control (%s) failed: %s", \
+ __LINE__, #cmd, gcry_strerror (err__)); \
+ } while (0)
+
+
+/* Split a string into colon delimited fields A pointer to each field
+ * is stored in ARRAY. Stop splitting at ARRAYSIZE fields. The
+ * function modifies STRING. The number of parsed fields is returned.
+ * Note that leading and trailing spaces are not removed from the fields.
+ * Example:
+ *
+ * char *fields[2];
+ * if (split_fields (string, fields, DIM (fields)) < 2)
+ * return // Not enough args.
+ * foo (fields[0]);
+ * foo (fields[1]);
+ */
+#ifdef NEED_EXTRA_TEST_SUPPORT
+static int
+split_fields_colon (char *string, char **array, int arraysize)
+{
+ int n = 0;
+ char *p, *pend;
+
+ p = string;
+ do
+ {
+ if (n == arraysize)
+ break;
+ array[n++] = p;
+ pend = strchr (p, ':');
+ if (!pend)
+ break;
+ *pend++ = 0;
+ p = pend;
+ }
+ while (*p);
+
+ return n;
+}
+#endif /*NEED_EXTRA_TEST_SUPPORT*/
diff --git a/comm/third_party/libgcrypt/tests/t-convert.c b/comm/third_party/libgcrypt/tests/t-convert.c
new file mode 100644
index 0000000000..4450a9e3fe
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-convert.c
@@ -0,0 +1,534 @@
+/* t-convert.c - Tests for mpi print and scna functions
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#define PGM "t-convert"
+#include "t-common.h"
+
+
+static void
+showhex (const char *prefix, const void *buffer, size_t buflen)
+{
+ const unsigned char *s;
+
+ if (!verbose)
+ return;
+ fprintf (stderr, "%s: %s ", PGM, prefix);
+ for (s= buffer; buflen; buflen--, s++)
+ fprintf (stderr, "%02x", *s);
+ putc ('\n', stderr);
+}
+
+
+/* Allocate a bit string consisting of '0' and '1' from the MPI A. Do
+ not return any leading zero bits. Caller needs to gcry_free the
+ result. */
+static char *
+mpi2bitstr_nlz (gcry_mpi_t a)
+{
+ char *p, *buf;
+ size_t length = gcry_mpi_get_nbits (a);
+
+ if (!length)
+ {
+ buf = p = xmalloc (3);
+ *p++ = ' ';
+ *p++ = '0';
+ }
+ else
+ {
+ buf = p = xmalloc (length + 1 + 1);
+ *p++ = gcry_mpi_is_neg (a)? '-':' ';
+ while (length-- > 1)
+ *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
+ *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
+ }
+ *p = 0;
+ return buf;
+}
+
+
+static void
+showmpi (const char *prefix, gcry_mpi_t a)
+{
+ char *bitstr;
+
+ if (!verbose)
+ return;
+ bitstr = mpi2bitstr_nlz (a);
+ fprintf (stderr, "%s: %s%s\n", PGM, prefix, bitstr);
+ xfree (bitstr);
+}
+
+
+/* Check that mpi_print does not return a negative zero. */
+static void
+negative_zero (void)
+{
+ gpg_error_t err;
+ gcry_mpi_t a;
+ char *buf;
+ void *bufaddr = &buf;
+ struct { const char *name; enum gcry_mpi_format format; } fmts[] =
+ {
+ { "STD", GCRYMPI_FMT_STD },
+ { "PGP", GCRYMPI_FMT_PGP },
+ { "SSH", GCRYMPI_FMT_SSH },
+ { "HEX", GCRYMPI_FMT_HEX },
+ { "USG", GCRYMPI_FMT_USG },
+ { NULL, 0 }
+ };
+ int i;
+
+ if (debug)
+ info ("negative zero printing\n");
+
+ a = gcry_mpi_new (0);
+ for (i=0; fmts[i].name; i++)
+ {
+ err = gcry_mpi_aprint (fmts[i].format, bufaddr, NULL, a);
+ if (err)
+ fail ("error printing a zero as %s: %s\n",
+ fmts[i].name,gpg_strerror (err) );
+ else
+ gcry_free (buf);
+ }
+
+ /* With the current version of libgcrypt the next two statements
+ should set a to -0. */
+ gcry_mpi_sub_ui (a, a, 1);
+ gcry_mpi_add_ui (a, a, 1);
+
+ for (i=0; fmts[i].name; i++)
+ {
+ err = gcry_mpi_aprint (fmts[i].format, bufaddr, NULL, a);
+ if (err)
+ fail ("error printing a negative zero as %s: %s\n",
+ fmts[i].name,gpg_strerror (err) );
+ else
+ gcry_free (buf);
+ }
+
+ gcry_mpi_release (a);
+}
+
+
+static void
+check_formats (void)
+{
+ static struct {
+ int value;
+ struct {
+ const char *hex;
+ size_t stdlen;
+ const char *std;
+ size_t sshlen;
+ const char *ssh;
+ size_t usglen;
+ const char *usg;
+ size_t pgplen;
+ const char *pgp;
+ } a;
+ } data[] = {
+ { 0, { "00",
+ 0, "",
+ 4, "\x00\x00\x00\x00",
+ 0, "",
+ 2, "\x00\x00"}
+ },
+ { 1, { "01",
+ 1, "\x01",
+ 5, "\x00\x00\x00\x01\x01",
+ 1, "\x01",
+ 3, "\x00\x01\x01" }
+ },
+ { 2, { "02",
+ 1, "\x02",
+ 5, "\x00\x00\x00\x01\x02",
+ 1, "\x02",
+ 3, "\x00\x02\x02" }
+ },
+ { 127, { "7F",
+ 1, "\x7f",
+ 5, "\x00\x00\x00\x01\x7f",
+ 1, "\x7f",
+ 3, "\x00\x07\x7f" }
+ },
+ { 128, { "0080",
+ 2, "\x00\x80",
+ 6, "\x00\x00\x00\x02\x00\x80",
+ 1, "\x80",
+ 3, "\x00\x08\x80" }
+ },
+ { 129, { "0081",
+ 2, "\x00\x81",
+ 6, "\x00\x00\x00\x02\x00\x81",
+ 1, "\x81",
+ 3, "\x00\x08\x81" }
+ },
+ { 255, { "00FF",
+ 2, "\x00\xff",
+ 6, "\x00\x00\x00\x02\x00\xff",
+ 1, "\xff",
+ 3, "\x00\x08\xff" }
+ },
+ { 256, { "0100",
+ 2, "\x01\x00",
+ 6, "\x00\x00\x00\x02\x01\x00",
+ 2, "\x01\x00",
+ 4, "\x00\x09\x01\x00" }
+ },
+ { 257, { "0101",
+ 2, "\x01\x01",
+ 6, "\x00\x00\x00\x02\x01\x01",
+ 2, "\x01\x01",
+ 4, "\x00\x09\x01\x01" }
+ },
+ { -1, { "-01",
+ 1, "\xff",
+ 5, "\x00\x00\x00\x01\xff",
+ 1,"\x01" }
+ },
+ { -2, { "-02",
+ 1, "\xfe",
+ 5, "\x00\x00\x00\x01\xfe",
+ 1, "\x02" }
+ },
+ { -127, { "-7F",
+ 1, "\x81",
+ 5, "\x00\x00\x00\x01\x81",
+ 1, "\x7f" }
+ },
+ { -128, { "-0080",
+ 1, "\x80",
+ 5, "\x00\x00\x00\x01\x80",
+ 1, "\x80" }
+ },
+ { -129, { "-0081",
+ 2, "\xff\x7f",
+ 6, "\x00\x00\x00\x02\xff\x7f",
+ 1, "\x81" }
+ },
+ { -255, { "-00FF",
+ 2, "\xff\x01",
+ 6, "\x00\x00\x00\x02\xff\x01",
+ 1, "\xff" }
+ },
+ { -256, { "-0100",
+ 2, "\xff\x00",
+ 6, "\x00\x00\x00\x02\xff\x00",
+ 2, "\x01\x00" }
+ },
+ { -257, { "-0101",
+ 2, "\xfe\xff",
+ 6, "\x00\x00\x00\x02\xfe\xff",
+ 2, "\x01\x01" }
+ },
+ { 65535, { "00FFFF",
+ 3, "\x00\xff\xff",
+ 7, "\x00\x00\x00\x03\x00\xff\xff",
+ 2, "\xff\xff",
+ 4, "\x00\x10\xff\xff" }
+ },
+ { 65536, { "010000",
+ 3, "\x01\00\x00",
+ 7, "\x00\x00\x00\x03\x01\x00\x00",
+ 3, "\x01\x00\x00",
+ 5, "\x00\x11\x01\x00\x00 "}
+ },
+ { 65537, { "010001",
+ 3, "\x01\00\x01",
+ 7, "\x00\x00\x00\x03\x01\x00\x01",
+ 3, "\x01\x00\x01",
+ 5, "\x00\x11\x01\x00\x01" }
+ },
+ { -65537, { "-010001",
+ 3, "\xfe\xff\xff",
+ 7, "\x00\x00\x00\x03\xfe\xff\xff",
+ 3, "\x01\x00\x01" }
+ },
+ { -65536, { "-010000",
+ 3, "\xff\x00\x00",
+ 7, "\x00\x00\x00\x03\xff\x00\x00",
+ 3, "\x01\x00\x00" }
+ },
+ { -65535, { "-00FFFF",
+ 3, "\xff\x00\x01",
+ 7, "\x00\x00\x00\x03\xff\x00\x01",
+ 2, "\xff\xff" }
+ }
+ };
+ gpg_error_t err;
+ gcry_mpi_t a, b;
+ char *buf;
+ void *bufaddr = &buf;
+ int idx;
+ size_t buflen;
+
+ a = gcry_mpi_new (0);
+ for (idx=0; idx < DIM(data); idx++)
+ {
+ if (debug)
+ info ("print test %d\n", data[idx].value);
+
+ if (data[idx].value < 0)
+ {
+ gcry_mpi_set_ui (a, -data[idx].value);
+ gcry_mpi_neg (a, a);
+ }
+ else
+ gcry_mpi_set_ui (a, data[idx].value);
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+ if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "HEX", gpg_strerror (err));
+ else
+ {
+ if (strcmp (buf, data[idx].a.hex))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "HEX", "wrong result");
+ info ("expected: '%s'\n", data[idx].a.hex);
+ info (" got: '%s'\n", buf);
+ }
+ gcry_free (buf);
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_STD, bufaddr, &buflen, a);
+ if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "STD", gpg_strerror (err));
+ else
+ {
+ if (buflen != data[idx].a.stdlen
+ || memcmp (buf, data[idx].a.std, data[idx].a.stdlen))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "STD", "wrong result");
+ showhex ("expected:", data[idx].a.std, data[idx].a.stdlen);
+ showhex (" got:", buf, buflen);
+ }
+ gcry_free (buf);
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_SSH, bufaddr, &buflen, a);
+ if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "SSH", gpg_strerror (err));
+ else
+ {
+ if (buflen != data[idx].a.sshlen
+ || memcmp (buf, data[idx].a.ssh, data[idx].a.sshlen))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "SSH", "wrong result");
+ showhex ("expected:", data[idx].a.ssh, data[idx].a.sshlen);
+ showhex (" got:", buf, buflen);
+ }
+ gcry_free (buf);
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufaddr, &buflen, a);
+ if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "USG", gpg_strerror (err));
+ else
+ {
+ if (buflen != data[idx].a.usglen
+ || memcmp (buf, data[idx].a.usg, data[idx].a.usglen))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "USG", "wrong result");
+ showhex ("expected:", data[idx].a.usg, data[idx].a.usglen);
+ showhex (" got:", buf, buflen);
+ }
+ gcry_free (buf);
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_PGP, bufaddr, &buflen, a);
+ if (gcry_mpi_is_neg (a))
+ {
+ if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "PGP", "Expected error not returned");
+ }
+ else if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "PGP", gpg_strerror (err));
+ else
+ {
+ if (buflen != data[idx].a.pgplen
+ || memcmp (buf, data[idx].a.pgp, data[idx].a.pgplen))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "PGP", "wrong result");
+ showhex ("expected:", data[idx].a.pgp, data[idx].a.pgplen);
+ showhex (" got:", buf, buflen);
+ }
+ gcry_free (buf);
+ }
+ }
+
+
+ /* Now for the other direction. */
+ for (idx=0; idx < DIM(data); idx++)
+ {
+ if (debug)
+ info ("scan test %d\n", data[idx].value);
+
+ if (data[idx].value < 0)
+ {
+ gcry_mpi_set_ui (a, -data[idx].value);
+ gcry_mpi_neg (a, a);
+ }
+ else
+ gcry_mpi_set_ui (a, data[idx].value);
+
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_HEX, data[idx].a.hex, 0, &buflen);
+ if (err)
+ fail ("error scanning value %d from %s: %s\n",
+ data[idx].value, "HEX", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_cmp (a, b))
+ {
+ fail ("error scanning value %d from %s: %s\n",
+ data[idx].value, "HEX", "wrong result");
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_STD,
+ data[idx].a.std, data[idx].a.stdlen, &buflen);
+ if (err)
+ fail ("error scanning value %d as %s: %s\n",
+ data[idx].value, "STD", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_cmp (a, b) || data[idx].a.stdlen != buflen)
+ {
+ fail ("error scanning value %d from %s: %s (%lu)\n",
+ data[idx].value, "STD", "wrong result",
+ (long unsigned int)buflen);
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_SSH,
+ data[idx].a.ssh, data[idx].a.sshlen, &buflen);
+ if (err)
+ fail ("error scanning value %d as %s: %s\n",
+ data[idx].value, "SSH", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_cmp (a, b) || data[idx].a.sshlen != buflen)
+ {
+ fail ("error scanning value %d from %s: %s (%lu)\n",
+ data[idx].value, "SSH", "wrong result",
+ (long unsigned int)buflen);
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_USG,
+ data[idx].a.usg, data[idx].a.usglen, &buflen);
+ if (err)
+ fail ("error scanning value %d as %s: %s\n",
+ data[idx].value, "USG", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_is_neg (a))
+ gcry_mpi_neg (b, b);
+ if (gcry_mpi_cmp (a, b) || data[idx].a.usglen != buflen)
+ {
+ fail ("error scanning value %d from %s: %s (%lu)\n",
+ data[idx].value, "USG", "wrong result",
+ (long unsigned int)buflen);
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+
+ /* Negative values are not supported by PGP, thus we don't have
+ an samples. */
+ if (!gcry_mpi_is_neg (a))
+ {
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_PGP,
+ data[idx].a.pgp, data[idx].a.pgplen, &buflen);
+ if (err)
+ fail ("error scanning value %d as %s: %s\n",
+ data[idx].value, "PGP", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_cmp (a, b) || data[idx].a.pgplen != buflen)
+ {
+ fail ("error scanning value %d from %s: %s (%lu)\n",
+ data[idx].value, "PGP", "wrong result",
+ (long unsigned int)buflen);
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+ }
+ }
+
+ gcry_mpi_release (a);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ negative_zero ();
+ check_formats ();
+
+ info ("All tests completed. Errors: %d\n", error_count);
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-cv25519.c b/comm/third_party/libgcrypt/tests/t-cv25519.c
new file mode 100644
index 0000000000..0de50a02de
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-cv25519.c
@@ -0,0 +1,650 @@
+/* t-cv25519.c - Check the cv25519 crypto
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "stopwatch.h"
+
+#define PGM "t-cv25519"
+#include "t-common.h"
+#define N_TESTS 18
+
+
+static void
+print_mpi (const char *text, gcry_mpi_t a)
+{
+ gcry_error_t err;
+ char *buf;
+ void *bufaddr = &buf;
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+ if (err)
+ fprintf (stderr, "%s: [error printing number: %s]\n",
+ text, gpg_strerror (err));
+ else
+ {
+ fprintf (stderr, "%s: %s\n", text, 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);
+}
+
+
+/* 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 returns NULL 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))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+static void
+reverse_buffer (unsigned char *buffer, unsigned int length)
+{
+ unsigned int tmp, i;
+
+ for (i=0; i < length/2; i++)
+ {
+ tmp = buffer[i];
+ buffer[i] = buffer[length-1-i];
+ buffer[length-1-i] = tmp;
+ }
+}
+
+
+/*
+ * Test X25519 functionality through higher layer crypto routines.
+ *
+ * Input: K (as hex string), U (as hex string), R (as hex string)
+ *
+ * where R is expected result of X25519 (K, U).
+ *
+ * It calls gcry_pk_encrypt with Curve25519 private key and let
+ * it compute X25519.
+ */
+static void
+test_cv_hl (int testno, const char *k_str, const char *u_str,
+ const char *result_str)
+{
+ gpg_error_t err;
+ void *buffer = NULL;
+ size_t buflen;
+ gcry_sexp_t s_pk = NULL;
+ gcry_mpi_t mpi_k = NULL;
+ gcry_sexp_t s_data = NULL;
+ gcry_sexp_t s_result = NULL;
+ gcry_sexp_t s_tmp = NULL;
+ unsigned char *res = NULL;
+ size_t res_len;
+
+ if (verbose > 1)
+ info ("Running test %d\n", testno);
+
+ if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "k", "invalid hex string");
+ goto leave;
+ }
+
+ reverse_buffer (buffer, buflen);
+ if ((err = gcry_mpi_scan (&mpi_k, GCRYMPI_FMT_USG, buffer, buflen, NULL)))
+ {
+ fail ("error converting MPI for test %d: %s", testno, gpg_strerror (err));
+ goto leave;
+ }
+
+ if ((err = gcry_sexp_build (&s_data, NULL, "%m", mpi_k)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "data", gpg_strerror (err));
+ goto leave;
+ }
+
+ xfree (buffer);
+ if (!(buffer = hex2buffer (u_str, &buflen)) || buflen != 32)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "u", "invalid hex string");
+ goto leave;
+ }
+
+ /*
+ * The procedure of decodeUCoordinate will be done internally
+ * by _gcry_ecc_mont_decodepoint. So, we just put the little-endian
+ * binary to build S-exp.
+ *
+ * We could add the prefix 0x40, but libgcrypt also supports
+ * format with no prefix. So, it is OK not to put the prefix.
+ */
+ if ((err = gcry_sexp_build (&s_pk, NULL,
+ "(public-key"
+ " (ecc"
+ " (curve \"Curve25519\")"
+ " (flags djb-tweak)"
+ " (q%b)))", (int)buflen, buffer)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "pk", gpg_strerror (err));
+ goto leave;
+ }
+
+ xfree (buffer);
+ buffer = NULL;
+
+ if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk)))
+ fail ("gcry_pk_encrypt failed for test %d: %s", testno,
+ gpg_strerror (err));
+
+ s_tmp = gcry_sexp_find_token (s_result, "s", 0);
+ if (!s_tmp || !(res = gcry_sexp_nth_buffer (s_tmp, 1, &res_len)))
+ fail ("gcry_pk_encrypt failed for test %d: %s", testno, "missing value");
+ else
+ {
+ char *r, *r0;
+ int i;
+
+ /* To skip the prefix 0x40, for-loop start with i=1 */
+ r0 = r = xmalloc (2*(res_len)+1);
+ if (!r0)
+ {
+ fail ("memory allocation for test %d", testno);
+ goto leave;
+ }
+
+ for (i=1; i < res_len; i++, r += 2)
+ snprintf (r, 3, "%02x", res[i]);
+ if (strcmp (result_str, r0))
+ {
+ fail ("gcry_pk_encrypt failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", result_str);
+ info (" got: '%s'", r0);
+ }
+ xfree (r0);
+ }
+
+ leave:
+ xfree (res);
+ gcry_mpi_release (mpi_k);
+ gcry_sexp_release (s_tmp);
+ gcry_sexp_release (s_result);
+ gcry_sexp_release (s_data);
+ gcry_sexp_release (s_pk);
+ xfree (buffer);
+}
+
+/*
+ * Test X25519 functionality through the API for X25519.
+ *
+ * Input: K (as hex string), U (as hex string), R (as hex string)
+ *
+ * where R is expected result of X25519 (K, U).
+ *
+ */
+static void
+test_cv_x25519 (int testno, const char *k_str, const char *u_str,
+ const char *result_str)
+{
+ gpg_error_t err;
+ void *scalar = NULL;
+ void *point = NULL;
+ size_t buflen;
+ unsigned char result[32];
+ char result_hex[65];
+ int i;
+ int algo = GCRY_ECC_CURVE25519;
+ unsigned int keylen;
+
+ if (verbose > 1)
+ info ("Running test %d\n", testno);
+
+ if (!(keylen = gcry_ecc_get_algo_keylen (algo)))
+ {
+ fail ("error getting keylen for test %d", testno);
+ goto leave;
+ }
+
+ if (keylen != 32)
+ {
+ fail ("error invalid keylen for test %d", testno);
+ goto leave;
+ }
+
+ if (!(scalar = hex2buffer (k_str, &buflen)) || buflen != keylen)
+ {
+ fail ("error of input for test %d, %s: %s",
+ testno, "k", "invalid hex string");
+ goto leave;
+ }
+
+ if (!(point = hex2buffer (u_str, &buflen)) || buflen != keylen)
+ {
+ fail ("error of input for test %d, %s: %s",
+ testno, "u", "invalid hex string");
+ goto leave;
+ }
+
+ if ((err = gcry_ecc_mul_point (algo, result, scalar, point)))
+ fail ("gcry_ecc_mul_point failed for test %d: %s", testno,
+ gpg_strerror (err));
+
+ for (i=0; i < keylen; i++)
+ snprintf (&result_hex[i*2], 3, "%02x", result[i]);
+
+ if (strcmp (result_str, result_hex))
+ {
+ fail ("gcry_ecc_mul_point failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", result_str);
+ info (" got: '%s'", result_hex);
+ }
+
+ leave:
+ xfree (scalar);
+ xfree (point);
+}
+
+static void
+test_cv (int testno, const char *k_str, const char *u_str,
+ const char *result_str)
+{
+ test_cv_hl (testno, k_str, u_str, result_str);
+ test_cv_x25519 (testno, k_str, u_str, result_str);
+}
+
+/*
+ * Test iterative X25519 computation through lower layer MPI routines.
+ *
+ * Input: K (as hex string), ITER, R (as hex string)
+ *
+ * where R is expected result of iterating X25519 by ITER times.
+ *
+ */
+static void
+test_it (int testno, const char *k_str, int iter, const char *result_str)
+{
+ gcry_ctx_t ctx;
+ gpg_error_t err;
+ void *buffer = NULL;
+ size_t buflen;
+ gcry_mpi_t mpi_k = NULL;
+ gcry_mpi_t mpi_x = NULL;
+ gcry_mpi_point_t P = NULL;
+ gcry_mpi_point_t Q;
+ int i;
+ gcry_mpi_t mpi_kk = NULL;
+
+ if (verbose > 1)
+ info ("Running test %d: iteration=%d\n", testno, iter);
+
+ gcry_mpi_ec_new (&ctx, NULL, "Curve25519");
+ Q = gcry_mpi_point_new (0);
+
+ if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32)
+ {
+ fail ("error scanning MPI for test %d, %s: %s",
+ testno, "k", "invalid hex string");
+ goto leave;
+ }
+ reverse_buffer (buffer, buflen);
+ if ((err = gcry_mpi_scan (&mpi_x, GCRYMPI_FMT_USG, buffer, buflen, NULL)))
+ {
+ fail ("error scanning MPI for test %d, %s: %s",
+ testno, "x", gpg_strerror (err));
+ goto leave;
+ }
+
+ xfree (buffer);
+ buffer = NULL;
+
+ P = gcry_mpi_point_set (NULL, mpi_x, NULL, GCRYMPI_CONST_ONE);
+
+ mpi_k = gcry_mpi_copy (mpi_x);
+ if (debug)
+ print_mpi ("k", mpi_k);
+
+ for (i = 0; i < iter; i++)
+ {
+ /*
+ * Another variant of decodeScalar25519 thing.
+ */
+ mpi_kk = gcry_mpi_set (mpi_kk, mpi_k);
+ gcry_mpi_set_bit (mpi_kk, 254);
+ gcry_mpi_clear_bit (mpi_kk, 255);
+ gcry_mpi_clear_bit (mpi_kk, 0);
+ gcry_mpi_clear_bit (mpi_kk, 1);
+ gcry_mpi_clear_bit (mpi_kk, 2);
+
+ gcry_mpi_ec_mul (Q, mpi_kk, P, ctx);
+
+ P = gcry_mpi_point_set (P, mpi_k, NULL, GCRYMPI_CONST_ONE);
+ gcry_mpi_ec_get_affine (mpi_k, NULL, Q, ctx);
+
+ if (debug)
+ print_mpi ("k", mpi_k);
+ }
+
+ {
+ unsigned char res[32];
+ char *r, *r0;
+
+ gcry_mpi_print (GCRYMPI_FMT_USG, res, 32, NULL, mpi_k);
+ reverse_buffer (res, 32);
+
+ r0 = r = xmalloc (65);
+ if (!r0)
+ {
+ fail ("memory allocation for test %d", testno);
+ goto leave;
+ }
+
+ for (i=0; i < 32; i++, r += 2)
+ snprintf (r, 3, "%02x", res[i]);
+
+ if (strcmp (result_str, r0))
+ {
+ fail ("curv25519 failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", result_str);
+ info (" got: '%s'", r0);
+ }
+ xfree (r0);
+ }
+
+ leave:
+ gcry_mpi_release (mpi_kk);
+ gcry_mpi_release (mpi_k);
+ gcry_mpi_point_release (P);
+ gcry_mpi_release (mpi_x);
+ xfree (buffer);
+ gcry_mpi_point_release (Q);
+ gcry_ctx_release (ctx);
+}
+
+/*
+ * X-coordinate of generator of the Curve25519.
+ */
+#define G_X "0900000000000000000000000000000000000000000000000000000000000000"
+
+/*
+ * Test Diffie-Hellman in RFC-7748.
+ *
+ * Note that it's not like the ECDH of OpenPGP, where we use
+ * ephemeral public key.
+ */
+static void
+test_dh (int testno, const char *a_priv_str, const char *a_pub_str,
+ const char *b_priv_str, const char *b_pub_str,
+ const char *result_str)
+{
+ /* Test A for private key corresponds to public key. */
+ test_cv (testno, a_priv_str, G_X, a_pub_str);
+ /* Test B for private key corresponds to public key. */
+ test_cv (testno, b_priv_str, G_X, b_pub_str);
+ /* Test DH with A's private key and B's public key. */
+ test_cv (testno, a_priv_str, b_pub_str, result_str);
+ /* Test DH with B's private key and A's public key. */
+ test_cv (testno, b_priv_str, a_pub_str, result_str);
+}
+
+
+static void
+check_cv25519 (void)
+{
+ int ntests;
+
+ info ("Checking Curve25519.\n");
+
+ ntests = 0;
+
+ /*
+ * Values are cited from RFC-7748: 5.2. Test Vectors.
+ * Following two tests are for the first type test.
+ */
+ test_cv (1,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c",
+ "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552");
+ ntests++;
+ test_cv (2,
+ "4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d",
+ "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493",
+ "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957");
+ ntests++;
+
+ /*
+ * Additional test. Value is from second type test.
+ */
+ test_cv (3,
+ G_X,
+ G_X,
+ "422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079");
+ ntests++;
+
+ /*
+ * Following two tests are for the second type test,
+ * with one iteration and 1,000 iterations. (1,000,000 iterations
+ * takes too long.)
+ */
+ test_it (4,
+ G_X,
+ 1,
+ "422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079");
+ ntests++;
+
+ test_it (5,
+ G_X,
+ 1000,
+ "684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51");
+ ntests++;
+
+ /*
+ * Last test is from: 6. Diffie-Hellman, 6.1. Curve25519
+ */
+ test_dh (6,
+ /* Alice's private key, a */
+ "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a",
+ /* Alice's public key, X25519(a, 9) */
+ "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a",
+ /* Bob's private key, b */
+ "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb",
+ /* Bob's public key, X25519(b, 9) */
+ "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f",
+ /* Their shared secret, K */
+ "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742");
+ ntests++;
+
+ /* Seven tests which results 0. */
+ test_cv (7,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ test_cv (8,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "0100000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ test_cv (9,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800",
+ "0000000000000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ test_cv (10,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157",
+ "0000000000000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ test_cv (11,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+ "0000000000000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ test_cv (12,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+ "0000000000000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ test_cv (13,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+ "0000000000000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ /* Five tests which resulted 0 if decodeUCoordinate didn't change MSB. */
+ test_cv (14,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "cdeb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880",
+ "7ce548bc4919008436244d2da7a9906528fe3a6d278047654bd32d8acde9707b");
+ ntests++;
+
+ test_cv (15,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "4c9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7",
+ "e17902e989a034acdf7248260e2c94cdaf2fe1e72aaac7024a128058b6189939");
+ ntests++;
+
+ test_cv (16,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "d9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "ea6e6ddf0685c31e152d5818441ac9ac8db1a01f3d6cb5041b07443a901e7145");
+ ntests++;
+
+ test_cv (17,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "daffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "845ddce7b3a9b3ee01a2f1fd4282ad293310f7a232cbc5459fb35d94bccc9d05");
+ ntests++;
+
+ test_cv (18,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "6989e2cb1cea159acf121b0af6bf77493189c9bd32c2dac71669b540f9488247");
+ ntests++;
+
+ if (ntests != N_TESTS)
+ fail ("did %d tests but expected %d", ntests, N_TESTS);
+ else if ((ntests % 256))
+ show_note ("%d tests done\n", ntests);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: " PGM " [options]\n"
+ "Options:\n"
+ " --verbose print timings etc.\n"
+ " --debug flyswatter\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ }
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ start_timer ();
+ check_cv25519 ();
+ stop_timer ();
+
+ info ("All tests completed in %s. Errors: %d\n",
+ elapsed_time (1), error_count);
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-ed25519.c b/comm/third_party/libgcrypt/tests/t-ed25519.c
new file mode 100644
index 0000000000..a5271c25d6
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-ed25519.c
@@ -0,0 +1,497 @@
+/* t-ed25519.c - Check the Ed25519 crypto
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "stopwatch.h"
+
+#define PGM "t-ed25519"
+#include "t-common.h"
+#define N_TESTS 1026
+
+static int sign_with_pk;
+static int no_verify;
+static int custom_data_file;
+
+
+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_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ fprintf (stderr, "%s: ", PGM);
+ if (prefix)
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = xmalloc (size);
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+ gcry_free (buf);
+}
+
+
+/* Prepend FNAME with the srcdir environment variable's value and
+ * return an allocated filename. */
+char *
+prepend_srcdir (const char *fname)
+{
+ static const char *srcdir;
+ char *result;
+
+ if (!srcdir && !(srcdir = getenv ("srcdir")))
+ srcdir = ".";
+
+ result = xmalloc (strlen (srcdir) + 1 + strlen (fname) + 1);
+ strcpy (result, srcdir);
+ strcat (result, "/");
+ strcat (result, fname);
+ return result;
+}
+
+
+/* Read next line but skip over empty and comment lines. Caller must
+ xfree the result. */
+static char *
+read_textline (FILE *fp, int *lineno)
+{
+ char line[4096];
+ char *p;
+
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return NULL;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ ++*lineno;
+ p = strchr (line, '\n');
+ if (!p)
+ die ("input line %d not terminated or too long\n", *lineno);
+ *p = 0;
+ for (p--;p > line && my_isascii (*p) && isspace (*p); p--)
+ *p = 0;
+ }
+ while (!*line || *line == '#');
+ /* if (debug) */
+ /* info ("read line: '%s'\n", line); */
+ return xstrdup (line);
+}
+
+
+/* Copy the data after the tag to BUFFER. BUFFER will be allocated as
+ needed. */
+static void
+copy_data (char **buffer, const char *line, int lineno)
+{
+ const char *s;
+
+ xfree (*buffer);
+ *buffer = NULL;
+
+ s = strchr (line, ':');
+ if (!s)
+ {
+ fail ("syntax error at input line %d", lineno);
+ return;
+ }
+ for (s++; my_isascii (*s) && isspace (*s); s++)
+ ;
+ *buffer = xstrdup (s);
+}
+
+
+/* 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 returns NULL 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))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static void
+hexdowncase (char *string)
+{
+ char *p;
+
+ for (p=string; *p; p++)
+ if (my_isascii (*p))
+ *p = tolower (*p);
+}
+
+
+static void
+one_test (int testno, const char *sk, const char *pk,
+ const char *msg, const char *sig)
+{
+ gpg_error_t err;
+ int i;
+ char *p;
+ void *buffer = NULL;
+ void *buffer2 = NULL;
+ size_t buflen, buflen2;
+ gcry_sexp_t s_tmp, s_tmp2;
+ gcry_sexp_t s_sk = NULL;
+ gcry_sexp_t s_pk = NULL;
+ gcry_sexp_t s_msg= NULL;
+ gcry_sexp_t s_sig= NULL;
+ unsigned char *sig_r = NULL;
+ unsigned char *sig_s = NULL;
+ char *sig_rs_string = NULL;
+ size_t sig_r_len, sig_s_len;
+
+ if (verbose > 1)
+ info ("Running test %d\n", testno);
+
+ if (!(buffer = hex2buffer (sk, &buflen)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "sk", "invalid hex string");
+ goto leave;
+ }
+ if (!(buffer2 = hex2buffer (pk, &buflen2)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "pk", "invalid hex string");
+ goto leave;
+ }
+ if (sign_with_pk)
+ err = gcry_sexp_build (&s_sk, NULL,
+ "(private-key"
+ " (ecc"
+ " (curve \"Ed25519\")"
+ " (flags eddsa)"
+ " (q %b)"
+ " (d %b)))",
+ (int)buflen2, buffer2,
+ (int)buflen, buffer);
+ else
+ err = gcry_sexp_build (&s_sk, NULL,
+ "(private-key"
+ " (ecc"
+ " (curve \"Ed25519\")"
+ " (flags eddsa)"
+ " (d %b)))",
+ (int)buflen, buffer);
+ if (err)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "sk", gpg_strerror (err));
+ goto leave;
+ }
+
+ if ((err = gcry_sexp_build (&s_pk, NULL,
+ "(public-key"
+ " (ecc"
+ " (curve \"Ed25519\")"
+ " (flags eddsa)"
+ " (q %b)))", (int)buflen2, buffer2)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "pk", gpg_strerror (err));
+ goto leave;
+ }
+
+ xfree (buffer);
+ if (!(buffer = hex2buffer (msg, &buflen)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "msg", "invalid hex string");
+ goto leave;
+ }
+ if ((err = gcry_sexp_build (&s_msg, NULL,
+ "(data"
+ " (flags eddsa)"
+ " (hash-algo sha512)"
+ " (value %b))", (int)buflen, buffer)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "msg", gpg_strerror (err));
+ goto leave;
+ }
+
+ if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk)))
+ fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err));
+ if (debug)
+ show_sexp ("sig=", s_sig);
+
+ s_tmp2 = NULL;
+ s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+ if (s_tmp)
+ {
+ s_tmp2 = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_tmp2, "eddsa", 0);
+ if (s_tmp)
+ {
+ gcry_sexp_release (s_tmp2);
+ s_tmp2 = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_tmp2, "r", 0);
+ if (s_tmp)
+ {
+ sig_r = gcry_sexp_nth_buffer (s_tmp, 1, &sig_r_len);
+ gcry_sexp_release (s_tmp);
+ }
+ s_tmp = gcry_sexp_find_token (s_tmp2, "s", 0);
+ if (s_tmp)
+ {
+ sig_s = gcry_sexp_nth_buffer (s_tmp, 1, &sig_s_len);
+ gcry_sexp_release (s_tmp);
+ }
+ }
+ }
+ gcry_sexp_release (s_tmp2); s_tmp2 = NULL;
+
+ if (!sig_r || !sig_s)
+ fail ("gcry_pk_sign failed for test %d: %s", testno, "r or s missing");
+ else
+ {
+ sig_rs_string = xmalloc (2*(sig_r_len + sig_s_len)+1);
+ p = sig_rs_string;
+ *p = 0;
+ for (i=0; i < sig_r_len; i++, p += 2)
+ snprintf (p, 3, "%02x", sig_r[i]);
+ for (i=0; i < sig_s_len; i++, p += 2)
+ snprintf (p, 3, "%02x", sig_s[i]);
+ if (strcmp (sig_rs_string, sig))
+ {
+ fail ("gcry_pk_sign failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", sig);
+ info (" got: '%s'", sig_rs_string);
+ }
+ }
+
+ if (!no_verify)
+ if ((err = gcry_pk_verify (s_sig, s_msg, s_pk)))
+ fail ("gcry_pk_verify failed for test %d: %s",
+ testno, gpg_strerror (err));
+
+
+ leave:
+ gcry_sexp_release (s_sig);
+ gcry_sexp_release (s_sk);
+ gcry_sexp_release (s_pk);
+ gcry_sexp_release (s_msg);
+ xfree (buffer);
+ xfree (buffer2);
+ xfree (sig_r);
+ xfree (sig_s);
+ xfree (sig_rs_string);
+}
+
+
+static void
+check_ed25519 (const char *fname)
+{
+ FILE *fp;
+ int lineno, ntests;
+ char *line;
+ int testno;
+ char *sk, *pk, *msg, *sig;
+
+ info ("Checking Ed25519.\n");
+
+ fp = fopen (fname, "r");
+ if (!fp)
+ die ("error opening '%s': %s\n", fname, strerror (errno));
+
+ testno = 0;
+ sk = pk = msg = sig = NULL;
+ lineno = ntests = 0;
+ while ((line = read_textline (fp, &lineno)))
+ {
+ if (!strncmp (line, "TST:", 4))
+ testno = atoi (line+4);
+ else if (!strncmp (line, "SK:", 3))
+ copy_data (&sk, line, lineno);
+ else if (!strncmp (line, "PK:", 3))
+ copy_data (&pk, line, lineno);
+ else if (!strncmp (line, "MSG:", 4))
+ copy_data (&msg, line, lineno);
+ else if (!strncmp (line, "SIG:", 4))
+ copy_data (&sig, line, lineno);
+ else
+ fail ("unknown tag at input line %d", lineno);
+
+ xfree (line);
+ if (testno && sk && pk && msg && sig)
+ {
+ hexdowncase (sig);
+ one_test (testno, sk, pk, msg, sig);
+ ntests++;
+ if (!(ntests % 256))
+ show_note ("%d of %d tests done\n", ntests, N_TESTS);
+ xfree (pk); pk = NULL;
+ xfree (sk); sk = NULL;
+ xfree (msg); msg = NULL;
+ xfree (sig); sig = NULL;
+ }
+
+ }
+ xfree (pk);
+ xfree (sk);
+ xfree (msg);
+ xfree (sig);
+
+ if (ntests != N_TESTS && !custom_data_file)
+ fail ("did %d tests but expected %d", ntests, N_TESTS);
+ else if ((ntests % 256))
+ show_note ("%d tests done\n", ntests);
+
+ fclose (fp);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ char *fname = NULL;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: " PGM " [options]\n"
+ "Options:\n"
+ " --verbose print timings etc.\n"
+ " --debug flyswatter\n"
+ " --sign-with-pk also use the public key for signing\n"
+ " --no-verify skip the verify test\n"
+ " --data FNAME take test data from file FNAME\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--sign-with-pk"))
+ {
+ sign_with_pk = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--no-verify"))
+ {
+ no_verify = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--data"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ xfree (fname);
+ fname = xstrdup (*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+
+ }
+
+ if (!fname)
+ fname = prepend_srcdir ("t-ed25519.inp");
+ else
+ custom_data_file = 1;
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ /* Ed25519 isn't supported in fips mode */
+ if (gcry_fips_mode_active())
+ return 77;
+
+ start_timer ();
+ check_ed25519 (fname);
+ stop_timer ();
+
+ xfree (fname);
+
+ info ("All tests completed in %s. Errors: %d\n",
+ elapsed_time (1), error_count);
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-ed25519.inp b/comm/third_party/libgcrypt/tests/t-ed25519.inp
new file mode 100644
index 0000000000..e13566f826
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-ed25519.inp
@@ -0,0 +1,6172 @@
+# t-ed25519.inp - 1024 test data sets
+# This has been taken from
+# http://ed25519.cr.yp.to/python/sign.input
+# which distributed them as public domain.
+# For our use converted using this script:
+# awk -F: 'BEGIN {n=1} { print "TST: " n; n++; \
+# print "SK: " substr($1,0,64); print "PK: " $2;\
+# print "MSG: " $3; print "SIG: " substr($4,0,128); print ""}'
+#
+# The PK appended to the SK and the MSG appended to the SIG have been
+# stripped. A few additional tests have been added to the 1024
+# original tests.
+
+TST: 1
+SK: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
+PK: d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
+MSG:
+SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
+
+TST: 2
+SK: 4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb
+PK: 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c
+MSG: 72
+SIG: 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00
+
+TST: 3
+SK: c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7
+PK: fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025
+MSG: af82
+SIG: 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a
+
+TST: 4
+SK: 0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9
+PK: e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057
+MSG: cbc77b
+SIG: d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00c
+
+TST: 5
+SK: 6df9340c138cc188b5fe4464ebaa3f7fc206a2d55c3434707e74c9fc04e20ebb
+PK: c0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7
+MSG: 5f4c8989
+SIG: 124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c07
+
+TST: 6
+SK: b780381a65edf8b78f6945e8dbec7941ac049fd4c61040cf0c324357975a293c
+PK: e253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01
+MSG: 18b6bec097
+SIG: b2fc46ad47af464478c199e1f8be169f1be6327c7f9a0a6689371ca94caf04064a01b22aff1520abd58951341603faed768cf78ce97ae7b038abfe456aa17c09
+
+TST: 7
+SK: 78ae9effe6f245e924a7be63041146ebc670dbd3060cba67fbc6216febc44546
+PK: fbcfbfa40505d7f2be444a33d185cc54e16d615260e1640b2b5087b83ee3643d
+MSG: 89010d855972
+SIG: 6ed629fc1d9ce9e1468755ff636d5a3f40a5d9c91afd93b79d241830f7e5fa29854b8f20cc6eecbb248dbd8d16d14e99752194e4904d09c74d639518839d2300
+
+TST: 8
+SK: 691865bfc82a1e4b574eecde4c7519093faf0cf867380234e3664645c61c5f79
+PK: 98a5e3a36e67aaba89888bf093de1ad963e774013b3902bfab356d8b90178a63
+MSG: b4a8f381e70e7a
+SIG: 6e0af2fe55ae377a6b7a7278edfb419bd321e06d0df5e27037db8812e7e3529810fa5552f6c0020985ca17a0e02e036d7b222a24f99b77b75fdd16cb05568107
+
+TST: 9
+SK: 3b26516fb3dc88eb181b9ed73f0bcd52bcd6b4c788e4bcaf46057fd078bee073
+PK: f81fb54a825fced95eb033afcd64314075abfb0abd20a970892503436f34b863
+MSG: 4284abc51bb67235
+SIG: d6addec5afb0528ac17bb178d3e7f2887f9adbb1ad16e110545ef3bc57f9de2314a5c8388f723b8907be0f3ac90c6259bbe885ecc17645df3db7d488f805fa08
+
+TST: 10
+SK: edc6f5fbdd1cee4d101c063530a30490b221be68c036f5b07d0f953b745df192
+PK: c1a49c66e617f9ef5ec66bc4c6564ca33de2a5fb5e1464062e6d6c6219155efd
+MSG: 672bf8965d04bc5146
+SIG: 2c76a04af2391c147082e33faacdbe56642a1e134bd388620b852b901a6bc16ff6c9cc9404c41dea12ed281da067a1513866f9d964f8bdd24953856c50042901
+
+TST: 11
+SK: 4e7d21fb3b1897571a445833be0f9fd41cd62be3aa04040f8934e1fcbdcacd45
+PK: 31b2524b8348f7ab1dfafa675cc538e9a84e3fe5819e27c12ad8bbc1a36e4dff
+MSG: 33d7a786aded8c1bf691
+SIG: 28e4598c415ae9de01f03f9f3fab4e919e8bf537dd2b0cdf6e79b9e6559c9409d9151a4c40f083193937627c369488259e99da5a9f0a87497fa6696a5dd6ce08
+
+TST: 12
+SK: a980f892db13c99a3e8971e965b2ff3d41eafd54093bc9f34d1fd22d84115bb6
+PK: 44b57ee30cdb55829d0a5d4f046baef078f1e97a7f21b62d75f8e96ea139c35f
+MSG: 3486f68848a65a0eb5507d
+SIG: 77d389e599630d934076329583cd4105a649a9292abc44cd28c40000c8e2f5ac7660a81c85b72af8452d7d25c070861dae91601c7803d656531650dd4e5c4100
+
+TST: 13
+SK: 5b5a619f8ce1c66d7ce26e5a2ae7b0c04febcd346d286c929e19d0d5973bfef9
+PK: 6fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257
+MSG: 5a8d9d0a22357e6655f9c785
+SIG: 0f9ad9793033a2fa06614b277d37381e6d94f65ac2a5a94558d09ed6ce922258c1a567952e863ac94297aec3c0d0c8ddf71084e504860bb6ba27449b55adc40e
+
+TST: 14
+SK: 940c89fe40a81dafbdb2416d14ae469119869744410c3303bfaa0241dac57800
+PK: a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd
+MSG: b87d3813e03f58cf19fd0b6395
+SIG: d8bb64aad8c9955a115a793addd24f7f2b077648714f49c4694ec995b330d09d640df310f447fd7b6cb5c14f9fe9f490bcf8cfadbfd2169c8ac20d3b8af49a0c
+
+TST: 15
+SK: 9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738
+PK: cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291
+MSG: 55c7fa434f5ed8cdec2b7aeac173
+SIG: 6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06
+
+TST: 16
+SK: d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300
+PK: fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5
+MSG: 0a688e79be24f866286d4646b5d81c
+SIG: f68d04847e5b249737899c014d31c805c5007a62c0a10d50bb1538c5f35503951fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00
+
+TST: 17
+SK: 0a47d10452ae2febec518a1c7c362890c3fc1a49d34b03b6467d35c904a8362d
+PK: 34e5a8508c4743746962c066e4badea2201b8ab484de5c4f94476ccd2143955b
+MSG: c942fa7ac6b23ab7ff612fdc8e68ef39
+SIG: 2a3d27dc40d0a8127949a3b7f908b3688f63b7f14f651aacd715940bdbe27a0809aac142f47ab0e1e44fa490ba87ce5392f33a891539caf1ef4c367cae54500c
+
+TST: 18
+SK: f8148f7506b775ef46fdc8e8c756516812d47d6cfbfa318c27c9a22641e56f17
+PK: 0445e456dacc7d5b0bbed23c8200cdb74bdcb03e4c7b73f0a2b9b46eac5d4372
+MSG: 7368724a5b0efb57d28d97622dbde725af
+SIG: 3653ccb21219202b8436fb41a32ba2618c4a133431e6e63463ceb3b6106c4d56e1d2ba165ba76eaad3dc39bffb130f1de3d8e6427db5b71938db4e272bc3e20b
+
+TST: 19
+SK: 77f88691c4eff23ebb7364947092951a5ff3f10785b417e918823a552dab7c75
+PK: 74d29127f199d86a8676aec33b4ce3f225ccb191f52c191ccd1e8cca65213a6b
+MSG: bd8e05033f3a8bcdcbf4beceb70901c82e31
+SIG: fbe929d743a03c17910575492f3092ee2a2bf14a60a3fcacec74a58c7334510fc262db582791322d6c8c41f1700adb80027ecabc14270b703444ae3ee7623e0a
+
+TST: 20
+SK: ab6f7aee6a0837b334ba5eb1b2ad7fcecfab7e323cab187fe2e0a95d80eff132
+PK: 5b96dca497875bf9664c5e75facf3f9bc54bae913d66ca15ee85f1491ca24d2c
+MSG: 8171456f8b907189b1d779e26bc5afbb08c67a
+SIG: 73bca64e9dd0db88138eedfafcea8f5436cfb74bfb0e7733cf349baa0c49775c56d5934e1d38e36f39b7c5beb0a836510c45126f8ec4b6810519905b0ca07c09
+
+TST: 21
+SK: 8d135de7c8411bbdbd1b31e5dc678f2ac7109e792b60f38cd24936e8a898c32d
+PK: 1ca281938529896535a7714e3584085b86ef9fec723f42819fc8dd5d8c00817f
+MSG: 8ba6a4c9a15a244a9c26bb2a59b1026f21348b49
+SIG: a1adc2bc6a2d980662677e7fdff6424de7dba50f5795ca90fdf3e96e256f3285cac71d3360482e993d0294ba4ec7440c61affdf35fe83e6e04263937db93f105
+
+TST: 22
+SK: 0e765d720e705f9366c1ab8c3fa84c9a44370c06969f803296884b2846a652a4
+PK: 7fae45dd0a05971026d410bc497af5be7d0827a82a145c203f625dfcb8b03ba8
+MSG: 1d566a6232bbaab3e6d8804bb518a498ed0f904986
+SIG: bb61cf84de61862207c6a455258bc4db4e15eea0317ff88718b882a06b5cf6ec6fd20c5a269e5d5c805bafbcc579e2590af414c7c227273c102a10070cdfe80f
+
+TST: 23
+SK: db36e326d676c2d19cc8fe0c14b709202ecfc761d27089eb6ea4b1bb021ecfa7
+PK: 48359b850d23f0715d94bb8bb75e7e14322eaf14f06f28a805403fbda002fc85
+MSG: 1b0afb0ac4ba9ab7b7172cddc9eb42bba1a64bce47d4
+SIG: b6dcd09989dfbac54322a3ce87876e1d62134da998c79d24b50bd7a6a797d86a0e14dc9d7491d6c14a673c652cfbec9f962a38c945da3b2f0879d0b68a921300
+
+TST: 24
+SK: c89955e0f7741d905df0730b3dc2b0ce1a13134e44fef3d40d60c020ef19df77
+PK: fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c
+MSG: 507c94c8820d2a5793cbf3442b3d71936f35fe3afef316
+SIG: 7ef66e5e86f2360848e0014e94880ae2920ad8a3185a46b35d1e07dea8fa8ae4f6b843ba174d99fa7986654a0891c12a794455669375bf92af4cc2770b579e0c
+
+TST: 25
+SK: 4e62627fc221142478aee7f00781f817f662e3b75db29bb14ab47cf8e84104d6
+PK: b1d39801892027d58a8c64335163195893bfc1b61dbeca3260497e1f30371107
+MSG: d3d615a8472d9962bb70c5b5466a3d983a4811046e2a0ef5
+SIG: 836afa764d9c48aa4770a4388b654e97b3c16f082967febca27f2fc47ddfd9244b03cfc729698acf5109704346b60b230f255430089ddc56912399d1122de70a
+
+TST: 26
+SK: 6b83d7da8908c3e7205b39864b56e5f3e17196a3fc9c2f5805aad0f5554c142d
+PK: d0c846f97fe28585c0ee159015d64c56311c886eddcc185d296dbb165d2625d6
+MSG: 6ada80b6fa84f7034920789e8536b82d5e4678059aed27f71c
+SIG: 16e462a29a6dd498685a3718b3eed00cc1598601ee47820486032d6b9acc9bf89f57684e08d8c0f05589cda2882a05dc4c63f9d0431d6552710812433003bc08
+
+TST: 27
+SK: 19a91fe23a4e9e33ecc474878f57c64cf154b394203487a7035e1ad9cd697b0d
+PK: 2bf32ba142ba4622d8f3e29ecd85eea07b9c47be9d64412c9b510b27dd218b23
+MSG: 82cb53c4d5a013bae5070759ec06c3c6955ab7a4050958ec328c
+SIG: 881f5b8c5a030df0f75b6634b070dd27bd1ee3c08738ae349338b3ee6469bbf9760b13578a237d5182535ede121283027a90b5f865d63a6537dca07b44049a0f
+
+TST: 28
+SK: 1d5b8cb6215c18141666baeefcf5d69dad5bea9a3493dddaa357a4397a13d4de
+PK: 94d23d977c33e49e5e4992c68f25ec99a27c41ce6b91f2bfa0cd8292fe962835
+MSG: a9a8cbb0ad585124e522abbfb40533bdd6f49347b55b18e8558cb0
+SIG: 3acd39bec8c3cd2b44299722b5850a0400c1443590fd4861d59aae7496acb3df73fc3fdf7969ae5f50ba47dddc435246e5fd376f6b891cd4c2caf5d614b6170c
+
+TST: 29
+SK: 6a91b3227c472299089bdce9356e726a40efd840f11002708b7ee55b64105ac2
+PK: 9d084aa8b97a6b9bafa496dbc6f76f3306a116c9d917e681520a0f914369427e
+MSG: 5cb6f9aa59b80eca14f6a68fb40cf07b794e75171fba96262c1c6adc
+SIG: f5875423781b66216cb5e8998de5d9ffc29d1d67107054ace3374503a9c3ef811577f269de81296744bd706f1ac478caf09b54cdf871b3f802bd57f9a6cb9101
+
+TST: 30
+SK: 93eaa854d791f05372ce72b94fc6503b2ff8ae6819e6a21afe825e27ada9e4fb
+PK: 16cee8a3f2631834c88b670897ff0b08ce90cc147b4593b3f1f403727f7e7ad5
+MSG: 32fe27994124202153b5c70d3813fdee9c2aa6e7dc743d4d535f1840a5
+SIG: d834197c1a3080614e0a5fa0aaaa808824f21c38d692e6ffbd200f7dfb3c8f44402a7382180b98ad0afc8eec1a02acecf3cb7fde627b9f18111f260ab1db9a07
+
+TST: 31
+SK: 941cac69fb7b1815c57bb987c4d6c2ad2c35d5f9a3182a79d4ba13eab253a8ad
+PK: 23be323c562dfd71ce65f5bba56a74a3a6dfc36b573d2f94f635c7f9b4fd5a5b
+MSG: bb3172795710fe00054d3b5dfef8a11623582da68bf8e46d72d27cece2aa
+SIG: 0f8fad1e6bde771b4f5420eac75c378bae6db5ac6650cd2bc210c1823b432b48e016b10595458ffab92f7a8989b293ceb8dfed6c243a2038fc06652aaaf16f02
+
+TST: 32
+SK: 1acdbb793b0384934627470d795c3d1dd4d79cea59ef983f295b9b59179cbb28
+PK: 3f60c7541afa76c019cf5aa82dcdb088ed9e4ed9780514aefb379dabc844f31a
+MSG: 7cf34f75c3dac9a804d0fcd09eba9b29c9484e8a018fa9e073042df88e3c56
+SIG: be71ef4806cb041d885effd9e6b0fbb73d65d7cdec47a89c8a994892f4e55a568c4cc78d61f901e80dbb628b86a23ccd594e712b57fa94c2d67ec26634878507
+
+TST: 33
+SK: 8ed7a797b9cea8a8370d419136bcdf683b759d2e3c6947f17e13e2485aa9d420
+PK: b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9
+MSG: a750c232933dc14b1184d86d8b4ce72e16d69744ba69818b6ac33b1d823bb2c3
+SIG: 04266c033b91c1322ceb3446c901ffcf3cc40c4034e887c9597ca1893ba7330becbbd8b48142ef35c012c6ba51a66df9308cb6268ad6b1e4b03e70102495790b
+
+TST: 34
+SK: f2ab396fe8906e3e5633e99cabcd5b09df0859b516230b1e0450b580b65f616c
+PK: 8ea074245159a116aa7122a25ec16b891d625a68f33660423908f6bdc44f8c1b
+MSG: 5a44e34b746c5fd1898d552ab354d28fb4713856d7697dd63eb9bd6b99c280e187
+SIG: a06a23d982d81ab883aae230adbc368a6a9977f003cebb00d4c2e4018490191a84d3a282fdbfb2fc88046e62de43e15fb575336b3c8b77d19ce6a009ce51f50c
+
+TST: 35
+SK: 550a41c013f79bab8f06e43ad1836d51312736a9713806fafe6645219eaa1f9d
+PK: af6b7145474dc9954b9af93a9cdb34449d5b7c651c824d24e230b90033ce59c0
+MSG: 8bc4185e50e57d5f87f47515fe2b1837d585f0aae9e1ca383b3ec908884bb900ff27
+SIG: 16dc1e2b9fa909eefdc277ba16ebe207b8da5e91143cde78c5047a89f681c33c4e4e3428d5c928095903a811ec002d52a39ed7f8b3fe1927200c6dd0b9ab3e04
+
+TST: 36
+SK: 19ac3e272438c72ddf7b881964867cb3b31ff4c793bb7ea154613c1db068cb7e
+PK: f85b80e050a1b9620db138bfc9e100327e25c257c59217b601f1f6ac9a413d3f
+MSG: 95872d5f789f95484e30cbb0e114028953b16f5c6a8d9f65c003a83543beaa46b38645
+SIG: ea855d781cbea4682e350173cb89e8619ccfddb97cdce16f9a2f6f6892f46dbe68e04b12b8d88689a7a31670cdff409af98a93b49a34537b6aa009d2eb8b4701
+
+TST: 37
+SK: ca267de96c93c238fafb1279812059ab93ac03059657fd994f8fa5a09239c821
+PK: 017370c879090a81c7f272c2fc80e3aac2bc603fcb379afc98691160ab745b26
+MSG: e05f71e4e49a72ec550c44a3b85aca8f20ff26c3ee94a80f1b431c7d154ec9603ee02531
+SIG: ac957f82335aa7141e96b59d63e3ccee95c3a2c47d026540c2af42dc9533d5fd81827d1679ad187aeaf37834915e75b147a9286806c8017516ba43dd051a5e0c
+
+TST: 38
+SK: 3dff5e899475e7e91dd261322fab09980c52970de1da6e2e201660cc4fce7032
+PK: f30162bac98447c4042fac05da448034629be2c6a58d30dfd578ba9fb5e3930b
+MSG: 938f0e77621bf3ea52c7c4911c5157c2d8a2a858093ef16aa9b107e69d98037ba139a3c382
+SIG: 5efe7a92ff9623089b3e3b78f352115366e26ba3fb1a416209bc029e9cadccd9f4affa333555a8f3a35a9d0f7c34b292cae77ec96fa3adfcaadee2d9ced8f805
+
+TST: 39
+SK: 9a6b847864e70cfe8ba6ab22fa0ca308c0cc8bec7141fbcaa3b81f5d1e1cfcfc
+PK: 34ad0fbdb2566507a81c2b1f8aa8f53dccaa64cc87ada91b903e900d07eee930
+MSG: 838367471183c71f7e717724f89d401c3ad9863fd9cc7aa3cf33d3c529860cb581f3093d87da
+SIG: 2ab255169c489c54c732232e37c87349d486b1eba20509dbabe7fed329ef08fd75ba1cd145e67b2ea26cb5cc51cab343eeb085fe1fd7b0ec4c6afcd9b979f905
+
+TST: 40
+SK: 575be07afca5d063c238cd9b8028772cc49cda34471432a2e166e096e2219efc
+PK: 94e5eb4d5024f49d7ebf79817c8de11497dc2b55622a51ae123ffc749dbb16e0
+MSG: 33e5918b66d33d55fe717ca34383eae78f0af82889caf6696e1ac9d95d1ffb32cba755f9e3503e
+SIG: 58271d44236f3b98c58fd7ae0d2f49ef2b6e3affdb225aa3ba555f0e11cc53c23ad19baf24346590d05d7d5390582082cf94d39cad6530ab93d13efb39279506
+
+TST: 41
+SK: 15ffb45514d43444d61fcb105e30e135fd268523dda20b82758b179423110441
+PK: 1772c5abc2d23fd2f9d1c3257be7bc3c1cd79cee40844b749b3a7743d2f964b8
+MSG: da9c5559d0ea51d255b6bd9d7638b876472f942b330fc0e2b30aea68d77368fce4948272991d257e
+SIG: 6828cd7624e793b8a4ceb96d3c2a975bf773e5ff6645f353614058621e58835289e7f31f42dfe6af6d736f2644511e320c0fa698582a79778d18730ed3e8cb08
+
+TST: 42
+SK: fe0568642943b2e1afbfd1f10fe8df87a4236bea40dce742072cb21886eec1fa
+PK: 299ebd1f13177dbdb66a912bbf712038fdf73b06c3ac020c7b19126755d47f61
+MSG: c59d0862ec1c9746abcc3cf83c9eeba2c7082a036a8cb57ce487e763492796d47e6e063a0c1feccc2d
+SIG: d59e6dfcc6d7e3e2c58dec81e985d245e681acf6594a23c59214f7bed8015d813c7682b60b3583440311e72a8665ba2c96dec23ce826e160127e18132b030404
+
+TST: 43
+SK: 5ecb16c2df27c8cf58e436a9d3affbd58e9538a92659a0f97c4c4f994635a8ca
+PK: da768b20c437dd3aa5f84bb6a077ffa34ab68501c5352b5cc3fdce7fe6c2398d
+MSG: 56f1329d9a6be25a6159c72f12688dc8314e85dd9e7e4dc05bbecb7729e023c86f8e0937353f27c7ede9
+SIG: 1c723a20c6772426a670e4d5c4a97c6ebe9147f71bb0a415631e44406e290322e4ca977d348fe7856a8edc235d0fe95f7ed91aefddf28a77e2c7dbfd8f552f0a
+
+TST: 44
+SK: d599d637b3c30a82a9984e2f758497d144de6f06b9fba04dd40fd949039d7c84
+PK: 6791d8ce50a44689fc178727c5c3a1c959fbeed74ef7d8e7bd3c1ab4da31c51f
+MSG: a7c04e8ba75d0a03d8b166ad7a1d77e1b91c7aaf7befdd99311fc3c54a684ddd971d5b3211c3eeaff1e54e
+SIG: ebf10d9ac7c96108140e7def6fe9533d727646ff5b3af273c1df95762a66f32b65a09634d013f54b5dd6011f91bc336ca8b355ce33f8cfbec2535a4c427f8205
+
+TST: 45
+SK: 30ab8232fa7018f0ce6c39bd8f782fe2e159758bb0f2f4386c7f28cfd2c85898
+PK: ecfb6a2bd42f31b61250ba5de7e46b4719afdfbc660db71a7bd1df7b0a3abe37
+MSG: 63b80b7956acbecf0c35e9ab06b914b0c7014fe1a4bbc0217240c1a33095d707953ed77b15d211adaf9b97dc
+SIG: 9af885344cc7239498f712df80bc01b80638291ed4a1d28baa5545017a72e2f65649ccf9603da6eb5bfab9f5543a6ca4a7af3866153c76bf66bf95def615b00c
+
+TST: 46
+SK: 0ddcdc872c7b748d40efe96c2881ae189d87f56148ed8af3ebbbc80324e38bdd
+PK: 588ddadcbcedf40df0e9697d8bb277c7bb1498fa1d26ce0a835a760b92ca7c85
+MSG: 65641cd402add8bf3d1d67dbeb6d41debfbef67e4317c35b0a6d5bbbae0e034de7d670ba1413d056f2d6f1de12
+SIG: c179c09456e235fe24105afa6e8ec04637f8f943817cd098ba95387f9653b2add181a31447d92d1a1ddf1ceb0db62118de9dffb7dcd2424057cbdff5d41d0403
+
+TST: 47
+SK: 89f0d68299ba0a5a83f248ae0c169f8e3849a9b47bd4549884305c9912b46603
+PK: aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832
+MSG: 4f1846dd7ad50e545d4cfbffbb1dc2ff145dc123754d08af4e44ecc0bc8c91411388bc7653e2d893d1eac2107d05
+SIG: 2c691fa8d487ce20d5d2fa41559116e0bbf4397cf5240e152556183541d66cf753582401a4388d390339dbef4d384743caa346f55f8daba68ba7b9131a8a6e0b
+
+TST: 48
+SK: 0a3c1844e2db070fb24e3c95cb1cc6714ef84e2ccd2b9dd2f1460ebf7ecf13b1
+PK: 72e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01
+MSG: 4c8274d0ed1f74e2c86c08d955bde55b2d54327e82062a1f71f70d536fdc8722cdead7d22aaead2bfaa1ad00b82957
+SIG: 87f7fdf46095201e877a588fe3e5aaf476bd63138d8a878b89d6ac60631b3458b9d41a3c61a588e1db8d29a5968981b018776c588780922f5aa732ba6379dd05
+
+TST: 49
+SK: c8d7a8818b98dfdb20839c871cb5c48e9e9470ca3ad35ba2613a5d3199c8ab23
+PK: 90d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f
+MSG: 783e33c3acbdbb36e819f544a7781d83fc283d3309f5d3d12c8dcd6b0b3d0e89e38cfd3b4d0885661ca547fb9764abff
+SIG: fa2e994421aef1d5856674813d05cbd2cf84ef5eb424af6ecd0dc6fdbdc2fe605fe985883312ecf34f59bfb2f1c9149e5b9cc9ecda05b2731130f3ed28ddae0b
+
+TST: 50
+SK: b482703612d0c586f76cfcb21cfd2103c957251504a8c0ac4c86c9c6f3e429ff
+PK: fd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad
+MSG: 29d77acfd99c7a0070a88feb6247a2bce9984fe3e6fbf19d4045042a21ab26cbd771e184a9a75f316b648c6920db92b87b
+SIG: 58832bdeb26feafc31b46277cf3fb5d7a17dfb7ccd9b1f58ecbe6feb979666828f239ba4d75219260ecac0acf40f0e5e2590f4caa16bbbcd8a155d347967a607
+
+TST: 51
+SK: 84e50dd9a0f197e3893c38dbd91fafc344c1776d3a400e2f0f0ee7aa829eb8a2
+PK: 2c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea
+MSG: f3992cde6493e671f1e129ddca8038b0abdb77bb9035f9f8be54bd5d68c1aeff724ff47d29344391dc536166b8671cbbf123
+SIG: 69e6a4491a63837316e86a5f4ba7cd0d731ecc58f1d0a264c67c89befdd8d3829d8de13b33cc0bf513931715c7809657e2bfb960e5c764c971d733746093e500
+
+TST: 52
+SK: b322d46577a2a991a4d1698287832a39c487ef776b4bff037a05c7f1812bdeec
+PK: eb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f
+MSG: 19f1bf5dcf1750c611f1c4a2865200504d82298edd72671f62a7b1471ac3d4a30f7de9e5da4108c52a4ce70a3e114a52a3b3c5
+SIG: c7b55137317ca21e33489ff6a9bfab97c855dc6f85684a70a9125a261b56d5e6f149c5774d734f2d8debfc77b721896a8267c23768e9badb910eef83ec258802
+
+TST: 53
+SK: 960cab5034b9838d098d2dcbf4364bec16d388f6376d73a6273b70f82bbc98c0
+PK: 5e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a
+MSG: f8b21962447b0a8f2e4279de411bea128e0be44b6915e6cda88341a68a0d818357db938eac73e0af6d31206b3948f8c48a447308
+SIG: 27d4c3a1811ef9d4360b3bdd133c2ccc30d02c2f248215776cb07ee4177f9b13fc42dd70a6c2fed8f225c7663c7f182e7ee8eccff20dc7b0e1d5834ec5b1ea01
+
+TST: 54
+SK: eb77b2638f23eebc82efe45ee9e5a0326637401e663ed029699b21e6443fb48e
+PK: 9ef27608961ac711de71a6e2d4d4663ea3ecd42fb7e4e8627c39622df4af0bbc
+MSG: 99e3d00934003ebafc3e9fdb687b0f5ff9d5782a4b1f56b9700046c077915602c3134e22fc90ed7e690fddd4433e2034dcb2dc99ab
+SIG: 18dc56d7bd9acd4f4daa78540b4ac8ff7aa9815f45a0bba370731a14eaabe96df8b5f37dbf8eae4cb15a64b244651e59d6a3d6761d9e3c50f2d0cbb09c05ec06
+
+TST: 55
+SK: b625aa89d3f7308715427b6c39bbac58effd3a0fb7316f7a22b99ee5922f2dc9
+PK: 65a99c3e16fea894ec33c6b20d9105e2a04e2764a4769d9bbd4d8bacfeab4a2e
+MSG: e07241dbd3adbe610bbe4d005dd46732a4c25086ecb8ec29cd7bca116e1bf9f53bfbf3e11fa49018d39ff1154a06668ef7df5c678e6a
+SIG: 01bb901d83b8b682d3614af46a807ba2691358feb775325d3423f549ff0aa5757e4e1a74e9c70f9721d8f354b319d4f4a1d91445c870fd0ffb94fed64664730d
+
+TST: 56
+SK: b1c9f8bd03fe82e78f5c0fb06450f27dacdf716434db268275df3e1dc177af42
+PK: 7fc88b1f7b3f11c629be671c21621f5c10672fafc8492da885742059ee6774cf
+MSG: 331da7a9c1f87b2ac91ee3b86d06c29163c05ed6f8d8a9725b471b7db0d6acec7f0f702487163f5eda020ca5b493f399e1c8d308c3c0c2
+SIG: 4b229951ef262f16978f7914bc672e7226c5f8379d2778c5a2dc0a2650869f7acfbd0bcd30fdb0619bb44fc1ae5939b87cc318133009c20395b6c7eb98107701
+
+TST: 57
+SK: 6d8cdb2e075f3a2f86137214cb236ceb89a6728bb4a200806bf3557fb78fac69
+PK: 57a04c7a5113cddfe49a4c124691d46c1f9cdc8f343f9dcb72a1330aeca71fda
+MSG: 7f318dbd121c08bfddfeff4f6aff4e45793251f8abf658403358238984360054f2a862c5bb83ed89025d2014a7a0cee50da3cb0e76bbb6bf
+SIG: a6cbc947f9c87d1455cf1a708528c090f11ecee4855d1dbaadf47454a4de55fa4ce84b36d73a5b5f8f59298ccf21992df492ef34163d87753b7e9d32f2c3660b
+
+TST: 58
+SK: 47adc6d6bf571ee9570ca0f75b604ac43e303e4ab339ca9b53cacc5be45b2ccb
+PK: a3f527a1c1f17dfeed92277347c9f98ab475de1755b0ab546b8a15d01b9bd0be
+MSG: ce497c5ff5a77990b7d8f8699eb1f5d8c0582f70cb7ac5c54d9d924913278bc654d37ea227590e15202217fc98dac4c0f3be2183d133315739
+SIG: 4e8c318343c306adbba60c92b75cb0569b9219d8a86e5d57752ed235fc109a43c2cf4e942cacf297279fbb28675347e08027722a4eb7395e00a17495d32edf0b
+
+TST: 59
+SK: 3c19b50b0fe47961719c381d0d8da9b9869d312f13e3298b97fb22f0af29cbbe
+PK: 0f7eda091499625e2bae8536ea35cda5483bd16a9c7e416b341d6f2c83343612
+MSG: 8ddcd63043f55ec3bfc83dceae69d8f8b32f4cdb6e2aebd94b4314f8fe7287dcb62732c9052e7557fe63534338efb5b6254c5d41d2690cf5144f
+SIG: efbd41f26a5d62685516f882b6ec74e0d5a71830d203c231248f26e99a9c6578ec900d68cdb8fa7216ad0d24f9ecbc9ffa655351666582f626645395a31fa704
+
+TST: 60
+SK: 34e1e9d539107eb86b393a5ccea1496d35bc7d5e9a8c5159d957e4e5852b3eb0
+PK: 0ecb2601d5f7047428e9f909883a12420085f04ee2a88b6d95d3d7f2c932bd76
+MSG: a6d4d0542cfe0d240a90507debacabce7cbbd48732353f4fad82c7bb7dbd9df8e7d9a16980a45186d8786c5ef65445bcc5b2ad5f660ffc7c8eaac0
+SIG: 32d22904d3e7012d6f5a441b0b4228064a5cf95b723a66b048a087ecd55920c31c204c3f2006891a85dd1932e3f1d614cfd633b5e63291c6d8166f3011431e09
+
+TST: 61
+SK: 49dd473ede6aa3c866824a40ada4996c239a20d84c9365e4f0a4554f8031b9cf
+PK: 788de540544d3feb0c919240b390729be487e94b64ad973eb65b4669ecf23501
+MSG: 3a53594f3fba03029318f512b084a071ebd60baec7f55b028dc73bfc9c74e0ca496bf819dd92ab61cd8b74be3c0d6dcd128efc5ed3342cba124f726c
+SIG: d2fde02791e720852507faa7c3789040d9ef86646321f313ac557f4002491542dd67d05c6990cdb0d495501fbc5d5188bfbb84dc1bf6098bee0603a47fc2690f
+
+TST: 62
+SK: 331c64da482b6b551373c36481a02d8136ecadbb01ab114b4470bf41607ac571
+PK: 52a00d96a3148b4726692d9eff89160ea9f99a5cc4389f361fed0bb16a42d521
+MSG: 20e1d05a0d5b32cc8150b8116cef39659dd5fb443ab15600f78e5b49c45326d9323f2850a63c3808859495ae273f58a51e9de9a145d774b40ba9d753d3
+SIG: 22c99aa946ead39ac7997562810c01c20b46bd610645bd2d56dcdcbaacc5452c74fbf4b8b1813b0e94c30d808ce5498e61d4f7ccbb4cc5f04dfc6140825a9600
+
+TST: 63
+SK: 5c0b96f2af8712122cf743c8f8dc77b6cd5570a7de13297bb3dde1886213cce2
+PK: 0510eaf57d7301b0e1d527039bf4c6e292300a3a61b4765434f3203c100351b1
+MSG: 54e0caa8e63919ca614b2bfd308ccfe50c9ea888e1ee4446d682cb5034627f97b05392c04e835556c31c52816a48e4fb196693206b8afb4408662b3cb575
+SIG: 06e5d8436ac7705b3a90f1631cdd38ec1a3fa49778a9b9f2fa5ebea4e7d560ada7dd26ff42fafa8ba420323742761aca6904940dc21bbef63ff72daab45d430b
+
+TST: 64
+SK: de84f2435f78dedb87da18194ff6a336f08111150def901c1ac418146eb7b54a
+PK: d3a92bbaa4d63af79c2226a7236e6427428df8b362427f873023b22d2f5e03f2
+MSG: 205135ec7f417c858072d5233fb36482d4906abd60a74a498c347ff248dfa2722ca74e879de33169fadc7cd44d6c94a17d16e1e630824ba3e0df22ed68eaab
+SIG: 471ebc973cfdaceec07279307368b73be35bc6f8d8312b70150567369096706dc471126c3576f9f0eb550df5ac6a525181110029dd1fc11174d1aaced48d630f
+
+TST: 65
+SK: ba4d6e67b2ce67a1e44326494044f37a442f3b81725bc1f9341462718b55ee20
+PK: f73fa076f84b6db675a5fda5ad67e351a41e8e7f29add16809ca010387e9c6cc
+MSG: 4bafdac9099d4057ed6dd08bcaee8756e9a40f2cb9598020eb95019528409bbea38b384a59f119f57297bfb2fa142fc7bb1d90dbddde772bcde48c5670d5fa13
+SIG: 57b9d2a711207f837421bae7dd48eaa18eab1a9a70a0f1305806fee17b458f3a0964b302d1834d3e0ac9e8496f000b77f0083b41f8a957e632fbc7840eee6a06
+
+TST: 66
+SK: 0d131c45aea6f3a4e1b9a2cf60c55104587efaa846b222bf0a7b74ce7a3f63b6
+PK: 3c6729dbe93b499c4e614a2f21beb729438d498e1ac8d14cbad9717a5dbd97cd
+MSG: b4291d08b88fb2f7b8f99d0dce40079fcbab718bbd8f4e8eabc3c1428b6a071fb2a3c8eba1cacccfa871b365c708bef2685bc13e6b80bc14a5f249170ffc56d014
+SIG: a9c5ee86fb06d9e46b379c32dda7c92c9c13db274dc24116fbdd878696045488cc75a52fff67d1a5113d06e333ac67ff664b3f2a405fa1d14dd5bbb97409b606
+
+TST: 67
+SK: a75e3b6b4170e444781be4eeac3e0fdaa4b4356f705486bcb071a325ae071fba
+PK: 993d38a7d72f0aee15ff6f4fdc37ca7724fd1373a3766b275dbc77e647980e0a
+MSG: 4037866f6548b01cc6bcf3a940e3945aa2d188b4b7f182aa77ec4d6b0428ab5b84d85df192a5a38ada089d76fa26bf67736a7041a5eb8f0c5719eb396693c45160f8
+SIG: a5db4d3d3329abe3697959e6b5947ea8601b03ef8e1d6fe202144931272ca0a09b5eb0f390572ea7ef03c6131e9de5f16bf0b034244f7e104ff5311bbf663a0d
+
+TST: 68
+SK: bcbcf561ecc05a41c7d7e55e696d32ce39b4d03c1f5f3f3a8927fe5e62e844b2
+PK: 4ddf53fad6a7a9ed30f3afecca136fd7843b72c243090891ae4021a32cadff1a
+MSG: 6f6716b6784740980aebc3248807e31c1286ac7b681c00b66c88ff7a336d441fa5c3eb256d20cf6d1ac92ccfe4be6dcc41b1aff846d360c243001cabdfbf1a9b240455
+SIG: 9ff15115f6661f3211d7a40764967629ba6a5263951bdc3c6a4c90d070f7be00024b80d83b6bc27587fcff5f5ccc0eb3cde1497cf56895147a063f61f08adf0b
+
+TST: 69
+SK: 210532805fa9cc9be916d213cac374e3cd6fc2602a544d0c1ce29d30105d69ab
+PK: 10699e499be99e2b11b98f6f86b67cdc4ccf69f3c53ce094875647d2d0d0ecc5
+MSG: 9fc4d28cfd25e6c0c5e724e19ca39d71e53bf4aa2796c54c3351f108fc70f2611a62e0ab90af6ade5216788e9eb2a873059b1e79d7d59debd68f2d4d80ffe31bf74b928c
+SIG: 4c2d31d5bbc42e026dc1e079ecc4dd072c5d2cce65e3db8d8a1dd9057faa0371727f727231a0f060fa27097533b6db3b8f6252f2793d75662caadf5f0fcc710e
+
+TST: 70
+SK: 185d64b69479e0ba0a5844a10ad84125ba11c4b40d63eda2c57afc7e019c8e0c
+PK: a5764f6398a5ae2266a38f9714533c4bbd8d07826f63e204cbac374b0acef1bd
+MSG: 4a0824fe70d4315413d0a0cafbf4f5fe117d5e07e1c3a4effb9d0ae91490234878ccf6792a91f68c6a520de16071f08abe35dc5ea428f1957b663371ce24c609dd55b8f493
+SIG: 43e0387da5ba09a190f6e7b2680578d889769bcc445e5ef571b492871c155c5b9f620bfacfbf2df1fd87444604b71b2e237baaa7ee2093ede4a601edf883e307
+
+TST: 71
+SK: cfa9d9164b3c4f6f722635d2066cd7ea5e5533d2c74f8add669c371faa476426
+PK: 41169a66f9a63f285782a6c2db81cc3f70b3ada21a68c84745c88a74c3b0a2de
+MSG: 757621b1675db7cacef7f2782587ff3af51a3ef2f4bcf9279c4ce94002e1f00424bf0eb621982cc85cb4d171e564a0c2f6e3567a1aae2cddb7e9b25f47dc20a51050542969ca
+SIG: 01d7c9b5701af71e2f4877ffc9b7b5305f52816d4458e37e41c7719fac1d76a01fff3f50fe1a5875ccc3fb70001c947a33fc8b207de13572ccdb8ba98933ab01
+
+TST: 72
+SK: 1acb4a256c2f8993ca24de1e0014606d668b5e756032d269f1d24d351c8eea4a
+PK: cbbdcd8cbc885ab43a057e5f9579f1161954159e7b562ea26cd9a43c88d3f96d
+MSG: c46a6d61aa0aed1c1d8547a70b89b7196475d5a4870881b1ecd0f0cb9c745f8a2adc8024e2dc55b53aa5d383a81aabc1a47e8d07d00b7f0b56ceddbfb1f424bb5c02184678a666
+SIG: 05aa76f7fe51892303d78914715995e7d768ff7714ce270f175e56af17ae018d3fa939f5f620de82bcd1549687b205c7871203e624238c4e309fab7f92fbaa05
+
+TST: 73
+SK: ace3c46424823622979fc3a84a7da69c1d527d8312e8fb018375bd3a96c29c18
+PK: 937cf34136d9e1cce0de11b12c70cbfb7455448421e92c82e7c40934bff8c676
+MSG: a9f137bc9021bf105aee25be21cd9ee5b3547cf10cc5f98476fb588bd70e2d6d6b0834e842e4ee94303cf96b09c1715381b36e14a491b80f895ea421b8ec2b1d3c187e02935c5526
+SIG: feb8896dd3fe6001ffea171b37b788a69f7f850193a63406f56376dd263d099aef80ece67e2c43f40eca462c6b71e79406b18db74ae5d49844e3b132bc2a1307
+
+TST: 74
+SK: 88f681934e33c35c07dc6e5a832942ae3d59903ccde2f76ccb7587cea7ec41b6
+PK: 6a4e8aa5adb63d22fd7b14a26fdb03b7c8aa6ccd5a196f2c54b0465adb5092e1
+MSG: 6e8bac1f853b81fef94707e18cc61c6f0a9cbc2a41d078dcc83fc0229c7f8dbe6dbdd90854b1f1ae2b9f2b120b86a8786b4e78ce23ab86baaf88754af0f3d88881dae0bc5261bfd038
+SIG: 45b27bf1b9eac06b62b686f6d546563b2dfe5b175dbef32bf78c35a16c958a9d4f26d291de9bb2066c0a286113cc09172d40a36d4cbd951708860226eb30cd05
+
+TST: 75
+SK: 48050a6e0158f6ad253412e4497cff62d5ee555edffe59e4dc401522813295ce
+PK: 975e010abb9a3e56659137b0506057f283982f886ca172c7bc2c500ed9bd26c1
+MSG: ed6eec29fb7049dff707f0a4426ebc8f5b350e95870b9d6198c8139e9c3e1e409937d1a858a0dea482a5cb1a854ed3b5a9397acb63bff6b64039ef2eb1159e99858310bbbd86125c3e0e
+SIG: 7216ab60c35168187d0fce4753c86e80058d540b76bf95843a5898841060a99a44de6f439625a3f6365f59c377bf45909bbfef5c50b25f3194e5fbd34ea5e706
+
+TST: 76
+SK: 18d13d0c00e8e3386a5cfb30a9e79fe88b1861ed2d1201eb170038e194770403
+PK: a4afc833401876090d9b880c41267d68cbbeeaa38afb20884e27328f3b7f535e
+MSG: 910f6c272dd97931ac47310d244cadb43251365e02ba9f6a5b3c3226be9d7d3a74a2ba4906e8e71a4bf3d3556ebdfc666cd6b12f20c4a00834b88fbb244575199286b0b9344cf334aff007
+SIG: 033988154c5d79d2510be83e778015dfe2fb85b8111f7ec139918b5400e3d656ee80a9f5c9072b5b467a5cc5a57cc8ad1062b5bff10862d9d369dde2cc966701
+
+TST: 77
+SK: 4adc8c28646a93a817293a14d29b48e2c6d712a68993547a5c5e4d1452acbc3a
+PK: 7f40473628f23fc0dff0021afd487740d4916a9122e6c97d36433e5ebf04f88c
+MSG: 09fb5501f1688f80a0ab9e22d778ae130acaf74d7f5185b4da198c6b9edac4302e2b753e578766e17d4056dc40d95cf4ca8bcc6565795e97d68bcda79fa77c493397716356164caab5d19cfd
+SIG: 6d3b4e90ec408311f9b15b9253d3d95c5d152620c260d56302555a8804a5104ba5e8d29ee108e764a64219297298ab7674bbca784dee28773b34e185a386c208
+
+TST: 78
+SK: f26e1c84697a4908151b447dcf6c7c7a38b04081db9e7c7738e6fec900bed0c1
+PK: a86e1422c1235ff8e1aa083470d5e42288cb007ab50e795dd0b4ff87394966c4
+MSG: 54ed47606a1487c2f900cefb6e899dbaf6c31cc88ebe3558b83b93f6d422c31e888e48e520eeaedd7e554a9cd40c2c519d533b6144cee484c389e976b1e4022b50e7dbb87ead7e541a2004daf7
+SIG: 44f3344b9566c9dfd22d6198e1cbf95d9e28f2982fc7f166ab25dda30c46f768c558e0394fb9ab3e1d4db4cf487c17641a13f3f48939e0c64827a75103c57406
+
+TST: 79
+SK: cc0c33f3a86f5a17d30c186ce0f3b740bafa5fe3c7090f143541e2b2c1e534bc
+PK: 967a71c7cf9b82cc78cbe109104d8b438a8d1fd71d260d029046a9a4526866ff
+MSG: 1944e5e155d75e0d0be92e1be14cec370ad13791f2bfd40f271214e94fcf213c71bc20d7ce0c7584421ac4efc451883cc3f4956f21f73a4216720438bc38ff2cfdf3709905a50a9d94b1d9e7932b
+SIG: e277b3dd655c33ff75fa920af1fcc859401e6c7a6ef4c6bfbfac5069638f19ca115baf13c09c82af793facb6abd0cd58e8481b08c1b68ad7a2665c4a614a2806
+
+TST: 80
+SK: f0bc979375a7073068dba7f6c094db6598b4e45df7d549583c22fded8048fa2e
+PK: b42b6c57a78f1d90090a7181ab2ae09f426cbc2be96eb2cf27abc70d7d32a4b3
+MSG: 27ab3049b5c6351f6cfe38b13a059f5037257ee3d65d6079656856edc876ea081fd8a9480466f8839478088466f51ecbfaf2d65def25f0c4dd8d08588202812232f57945df8a6fa161ed8c0343b583
+SIG: 19dbc3027f9fae707deb76f588f9fd07aa8eae29bd4e1d04c2c984388286b3b122248a6c03ed67eca35df4db3dc1e4237f267892518497d9552a21de19b5140f
+
+TST: 81
+SK: 3022975f298c0ad5ddbe90954f20e63ae0c0d2704cf13c221f5b3720af4dba32
+PK: b845bce38e26ab027b8247463d437a71bbddca2a2381d81fad4c297df9140bd5
+MSG: 9aa19a595d989378cdc06891887ef5f9c246e5f83c0b658710673e4e7db760c76354c4f5d1e90db04a23b4fb434c69384593d010e312b11d299c9f97482de887cecfe82ea723bca79a1bd64d03ef19ee
+SIG: ae14a860fad0051b3eb72b3721a82f7b9546b2867261e2b7b638979e2561bdeb89b600768f82450a66c8b0481283fa21cb6c53bde350effb68a7d1114bfdb203
+
+TST: 82
+SK: 0f710b6c481f71449589753312ef64932b4652ebe0e07597f7da1c4f3dcffb80
+PK: 6973ff2932ccddfc1d16c4c0da50c8b29fe6452d1ee84d52064ebf3d628d403e
+MSG: 85d85744ad55e9ef9a65ca91e85c8a4f80e4c58f8e4e9354e833986098b7d9fe9fdc0dedb0d75d2539fba00034fc0c2e84344d1edaa09d4f63d5546d67803dd6b54ddcc0b1d3f2582dd75289e31de42e69
+SIG: 02a8d26aee11420fb4f09d1163e14b867df7c6f6c8f8dc7a78034659f0401cad0aa90397efdd0704b798db1936503026e2a1adc297e27974d4be312a3753f804
+
+TST: 83
+SK: 7a05f121f60112dd16fee8c91bc2a11479f4b67ee33456042c8de167fc588017
+PK: b3b05be989cea7197505d4b54335e5e1d77a4b52ba7282604bbc1cf6c4e87a6c
+MSG: d9c59e8cc4ede537be2122ab492a5b915a9b0a114b2ade356fc0457ef98722d5f567b86211e28369d14168ec4a3c804076e154adc70a668cf64a20d13cf190d115cd688d036e46938251df4964dc3517b10c
+SIG: d30ce8a322b450a2fb1afd329cec8559ccf112bd83965f9ec4736270a0914e061196bf5209778c9f8ccf39c4668bbf0e1363f81afe45dd74e80d5875ddbf6f01
+
+TST: 84
+SK: bf381f8dfb5d0c6d64e416ac23e0d0fcb86ebb899b1d146abd911b92a7808eb6
+PK: 863fad8d1f1bc630a15f6fe8ecefe6b4497b60b21ae8830da46742045fef156f
+MSG: 8654f2f5c6dcd2cfcbb6ed8d2bc5fb5fec53e3effb0de65aac507fa56c897732395aa09946d3b6586a92edd6dc99315e1ba74c6a0247c4ba7760b948eb3c0932d9fe1f0e9fea6eb61a548a9ab48ffdf1547329
+SIG: 99b75378738fcac8067669e8509b5d2607e1ef76af9004e13fe5d3932df60b168216f58565340fa4d638055a89044ee7d45e2bd082a53382289a34700648980e
+
+TST: 85
+SK: 36983241a0a8e60ce02a61b3fafab15a7313a5a270d015b9c9ec070dc42deeda
+PK: 6647984d42b9a5b3b1afa3b7f8f49d4c2b05e38984e99cea8fd68235d2ae4627
+MSG: cebb9e404451818253c0392a4554ee7323c5d5b8b226775700b806ed5b91337916ea7ecbc3d4103fc65e5372ae7e5f9ba2d8f5aee24ccf6e631ae20c4af9b5f728cdf89e8189def1a5b3d35347aa203525ea1d2e
+SIG: ee37df8af422f91f85dfe43efe79f62378068ccdbaf3916eecbc3adfed0508bdebaf5ce06b3bc279f78087f0db8db3c6823edfb32c12217830be723d8872b30c
+
+TST: 86
+SK: d06899f93a408dacb41c969718346f1e289bb5ea65e283ff79c705a074517c35
+PK: 46bf2a08a076c47d7f11b733f8141c355363ed85d7def26ba6a0ce15ac5f2be8
+MSG: 0864c39ac4fda8eb9048597bd40be0401021fd2dd3a3390a8facce984b260a13fa2c7cfc00d192fadf134a0ad5a181ee89eff0c795eaa0fbfe2f3b26115d07168db42ed21a51303b1958e4a42dc065b22ce48f17a6
+SIG: 6f89de92a66bc5f4144339124950bdf588144cb372f6736245351c9476becc59a258f9a933ffff2bef4b46cd1057395225799fd09dede6823db0e325dbc8140d
+
+TST: 87
+SK: eebca7966970ee9f2cc4d74c6f1d8e0ebff7c45aebad349fb9f86df628dfff0e
+PK: 89101e0309f767e64ae9c98c4a5d8d2328fb3ef262d082f49b64ca209e1990f6
+MSG: 0fac790adb9f59e5cb0ddcb2b667172f2a21034d93bcaddf188606fa9e776db33a8fcc6bd7f5567883fc0de351aa9afaa36d2075b1ba853bada849b8661d5c8154e7b0afea656dd15e01a9c5ba21589b02f8fc5481c2
+SIG: 7d447ee5328c9fe7f11936cc42998754a56cd1d2a6951af4fee7c4a8eb319d4923707c793c55d79067f822d5b16bb5776e38dffabc67237a916a81a63339b003
+
+TST: 88
+SK: 3820b6b15939d0afe18c9cb3d9a2a08f167dd458eb6c7e3f1558b0c6db4c6890
+PK: 80b85c6559fea8b400e1999cc5bfed507ad7fc294cd9ba0ce2dd2584a91089b0
+MSG: 3e5ad92d44b40e8614d8087c9c743de0c0861a07f1f5146d71cac2f3740024e841cc2d46027cf5d261d3ee7c1875b39551017b5fb1468114fc3e098a899cdbd558b39f098e156b6e9801ebcdd65fed56dbfcaf2c8c787b
+SIG: 823ee2c0c8d87faa0ec0141e9ce08b51e57c839792d1fbd97a967207fd415849ebfb5dadb5a1dc2c0a8b7fc63fc354857b8c90c44720e13f45cd01e7aa23140c
+
+TST: 89
+SK: 0d20fa4a37ff30c4dcc3e44ea7ac501137e5807e9781330ac310982cc3d39dbd
+PK: 67bb0a01bc8617b491eff1a326c1c70f7d0c5b95a5ad48241aedce1c6f0883cf
+MSG: 35e0f4b4a517f9c7aa4514f03e6d65f19b27c62cc069f6bf07dd6378bd6afe2b766560006cbd5730a00919ed11191fb0c8dac56e153fc1cea4bdce5046cccb717759a4083e1c16f740763264cc804de0d0e1a4b5a23067af
+SIG: deab12ed82ba94b469ca98b66fa20444b4b7881c4f0f853409c9a1504a5b2b6d7860f26ada6bf73459b9cdb573c8017121338efa60f4148086d7a3a8ed59bb07
+
+TST: 90
+SK: bee161881d819b370d240d509ba46b06fb828e20310d9f6b309780703e98927b
+PK: 10854380de89162bfb9f7835a2716a3a6e0265671b250b389d01c3bcc03736b8
+MSG: 5a6fe599b6b09b05c0ba6a622df3a92b3d376d24d04ea85ebe767bc2ec4d14e83e6937dc0b914b4809fdb607906841a6fd1dcdf61aaea8f9bb81b2ccaa32df412989ae53646680a71a211c8440eab0f1aec5e4fc00e6a2c96d
+SIG: b07d072eb3831fae8a06effa9201797496dce126b8e11fef2fa07f664dc5cf3d4bf9c38a8b3c09fb5f14fa2deb219e7d852fdd27c7ba32d309942f2746dfe404
+
+TST: 91
+SK: 70150e9516164a3d7b7e8b6f255b65cac9f07459b32d11bb94b3d277208abc99
+PK: 2328bec8e40351047882e8b43bc1ab085386fa47987e46ea87608814c5da713c
+MSG: 77be8eceaab431a13c2a28d0d1556489d8c392fd7ae41157f7caf082cb54e45f08626be0076be844d38fde901a5eab0e8832d69dac22fb8507fb8ec4faf7c88fd26da308461afe385987972b5e760a34a5e18b9a82b4aaa529b7
+SIG: eda3f5033ea7953a0d583c6457522e84ad78445304d48e577d4d69e8641febe15248d8d90ce0944a8f801d39099bc77494bac4ce2a20b38369c6adfb71e03d0f
+
+TST: 92
+SK: 3f87fcfdb421422a9c5fb98268313c15128c78844ef9eb3b3713fa77b6718903
+PK: 533ec59228374bd03a4699e3a8896b86182fcf8fc3085fdb8f5c4671524d6fe0
+MSG: c00fed2d689468bcbacccd446e8d8f299e2a86925e62e59709afaf4857469ff1e006d00fa3e18a3615f8f06b6ebdff785dde58851d2c239038a0c344dce985bd1fc8deb4779ae5f8932e2f9ed5990b6472dbe4e6fef6917657e0b5
+SIG: f6519d7edb6134111974033f03b8d89e9c76caec8965a8e17cd45fff19de2615d73eccdb4a6664a8f0e23adf98988e96251bf26eb7a4ccaac1079f0a772f9b05
+
+TST: 93
+SK: 44ceef044ff998d4abeaaf374eb41d086718b63097b1e35f89634c14897132ea
+PK: e83c86677d03ed3a5e8c95f41f0b325ff4333702f2ff6936f57ff30aa31485c7
+MSG: 8d3e2dec4644c7b51633b13e6375ca42ff9138465f43d7800c7313199f67c9cf1b520b1820bd630ecf1c992e2767b38eb5bbc441a4ab8d317db441db35a0fe3abe7a9e4541881c2d7b1a2612306959815d1da41267d9649dd4494ace
+SIG: 554552d6b790d421d06b0a67f8e002ad7a1ed01c06cf00cbeaec2a268bda29f1183f0ceafc625fa5fdb847dc86fae1a20406e459d4a0177cb515220a568e0800
+
+TST: 94
+SK: 98ef2a44d4c8476dff05aa78dcf9c6dc086cb2f622a06745d60cbf223faaba66
+PK: 42fdb1daa39f0159119beec1bedf6f0394b26a2a29bd1fde081eccdadecc226a
+MSG: c8b5fcfc3c18c7d95957b668e91c731d50c7fcea4f9575bbf784625870e238df546e2cb1a19d2808dd5b230d3871fdec16100ee1fbf9b722fa3744a750a3b396b05f9c21b8c0f61ead57a78c5ecf72b579cfe88a3f404c8acf524f9ab9
+SIG: ab5e8724a3e6ff76058cfb214d574e04d05574ecdd4ffe8c07c7af396e882687c5d79ef1e62fbb4c5f1bd06b9bd897826edde0d111d918e8ef961ff2a00d7700
+
+TST: 95
+SK: 93a8c792a239c931917c114824a0174f8bc4ebbf98af8c7e321e0f5bea4015ec
+PK: 9b2eaa8a9c2c25ff4f6e13bb12bae5d06fda0eb1105fafae5880ff168740bb74
+MSG: 901bf4e041caf16e04f2ffde8d6fe97e93d0900f6bc0fc09a9a0179d137b4b7788e57eb92766a9c634f35adb5c2988af1e86208f461998f59cfec99204b484fbcad3951e7ee4405523705d9739b44307db03f713fda78db421ef3121b3ba
+SIG: cfe32c4435d911d772dc0727e78d689d0164c5069597cb441b22c1d26236479f1afd7089121b9ab4f61bbb1fae1ab42f7635a92a53784d7170916b703aa5cc09
+
+TST: 96
+SK: 7001fa0c4404c28aa5b5fcff30a961f21a22f5b85a9e382e07aea8a8924d0ec1
+PK: daebb63c4d8f40ceba8ec35e3dd946a6b75bc74fcb29ade7b55eee3cc3aea5ca
+MSG: 44f48cfb02f08777a57873855f96be4c0291323f2739b275d90757a15472e5750436e0107408fe3026c00625689983f990eba9becbfce403ccd56356ad2741fd21445dfb23d76112e578b3395cf9d960955f1da8f399ca286f21390e25a59a
+SIG: 64eac9ce87460618636b41fd2decc1673bfc48c5f479dfacb51e86686407374b1d10bf65d6d7474214d7770c9e5c7f806c80d53d48b720870e5e78f32e3a7e05
+
+TST: 97
+SK: 3adce3a3d3fbc977dd4b300a74749f13a3b04a5d73a2cd75a994e3195efebdac
+PK: 6ff19b1f18d64851d5c74845c6407f0bf596a52e385e020127e83e54cff5ac19
+MSG: fe6c1a31068e332d12aab37d99406568deaa36bdb277cee55304633bd0a267a850e203bb3fabe5110bcc1ca4316698ab1cf00f0b0f1d97ef2180887f0ec0991e8c1111f0c0e1d2b712433ad2b3071bd66e1d81f7fa47bb4bb31ac0f059bb3cb8
+SIG: 7dda89f85b40539f5ad8c6de4953f7094a715b63dda30ec7cf65a785ceae5fc688707ee00be682cecbe7ee37d8fc39ee6d83c64409681708a0898a183b288a06
+
+TST: 98
+SK: 14803c1f23a47fcdd35e5d146e20ca630cd712c047d5330b652e31857acbc9e8
+PK: 36f2d5bd6d8324fa6e9db7f7d854ebe48c0e6299998122e9d44b8adbef54f093
+MSG: 555983679d026e5354b4cc055ae1bc14653c7281ec722372f3feb778e841da821b3d0b8ee7a9a9129ea06824be8379fbbdcb0748f423721ccb172a1bafa1d5ae9fc1c51e93d41dd551c3086079b620286c1c40c1223bbcbb76722e92ca21d8410a
+SIG: 07a7de6ce97664b3ea0928e1385c3309be08a47cbf4daa9186a1b948c86fbba39c4efcfcb7a0a3866bc94c6788ffe6be0d4972e56d0c3292d1cc6e25447b9904
+
+TST: 99
+SK: 1a61154d3472cd96b328ee674beb4fc86763a969fb410494e0678414e31a46a6
+PK: 7576d93ac85d0fc61f258c55cf90bd87a635099c0e810ed0b937258d13b42559
+MSG: 64c565efbcb8b9528ed47253f3c6a4035db781d6f0976b5e5ba8447d4ed54b04105293ef4c000d8b2e1b5b75e727e5d2a077743b50d183b491764801a2504d16ee6d7d8ac4fe40e6bfc2a8129c7285a5ac691c35e642ed162cf7fbc64516733a23b3
+SIG: ada1666c9c3b8284b8a21c4f2618ef0808a646f3f10941e470f738e1785e2de9fdd9c8cb526f945c7a8c6994f151b7d066581b1d755307947c62befc8ab7070f
+
+TST: 100
+SK: f215d34fe2d757cff9cf5c05430994de587987ce45cb0459f61ec6c825c62259
+PK: 1ed506485b09a6450be7c9337d9fe87ef99c96f8bd11cd631ca160d0fd73067e
+MSG: fbed2a7df418ec0e8036312ec239fcee6ef97dc8c2df1f2e14adee287808b788a6072143b851d975c8e8a0299df846b19113e38cee83da71ea8e9bd6f57bdcd3557523f4feb616caa595aea01eb0b3d490b99b525ea4fbb9258bc7fbb0deea8f568cb2
+SIG: cbef65b6f3fd580969fc3340cfae4f7c99df1340cce54626183144ef468871634b0a5c0033534108e1c67c0dc99d3014f01084e98c95e1014b309b1dbb2e6704
+
+TST: 101
+SK: 8c9f95083075a43fe426d19f1e87719b40043de88eb0ee971f70e10c7694ce4e
+PK: e91d167aa3ebc23e70aab45dabe905e416262f910e2a955dd8619efc74c24e85
+MSG: b69d70e860f55c427ef2a71df36e05bbc43bb2e06463aa5de34419c6a614eea6695335a87526c1226488d842891d0574df343c9c1e17aed6958ecee87474221eb77a599ecb059344c0d052c0002a66e5a6013185af69a01ba5dbc660d36cae235f67fe0e
+SIG: cac555222dafec76a0b47b9d2c586b3b3b9b3b9c8364beb3cae1e8dd7f1ae9dd74f22b8dd4ad2b290f81351a415a99f030f10778be4cda85d1d353331e70f109
+
+TST: 102
+SK: d7eb1fba424feed100777eedb4874bf20810ad686b67e31d27ecf610609a33f5
+PK: a25acb11a6c825713a085fa754692886a87d07fb9be1a53eb961728bb66c9060
+MSG: a1d0f81e3d59089cc2b19e07d2fce43db4cf171faa642f3b0bbde77ae3d53af5c02bf8fc12ffb4e57f7c8a015d6c2d178944fae9f7c8fc969d4b77bea51876ae99d59e94ad2456e0ed72c52cf4e5340da17c44dbff86457a519b6fffe269066290d629fe69
+SIG: 2bf719682b07cc5ecc0480f37e9d123ff6f44c26e6958e59f080466f9cd373a16500daf123dc3f1334774bfc9fa84503b16dbf21a815c1ada6ebef4920461702
+
+TST: 103
+SK: 4f6aeb35fce14fbcbb9aa8a4f6451bf95b98df047fa8c43f1ead3b404d3f928f
+PK: bf66a9edd09481db8444a176c8ce0578d2934f0cdc9734e86fcaac05bf3330f1
+MSG: 2dfbb3f59e19ea17d44a5bde4ad227a1a351dda17af840ee0a75da21a5cca89b6d1c567c333e9cc910e2157e05e86ad5d931145064594c47baeea8663a34649c43e90eb95ca10f7d51597b378a722f1f704adf9f22e9f885b89d1f938006a2efcdb42aaff5e3
+SIG: 6adb07e364f2a455cb05867abc511acd9d658977f0cacafc92828e7b724f6bbf98bf0bfb29f4e5e6c74738d4fdd816d9252407ae4f3afc574c4f00614824e203
+
+TST: 104
+SK: ef4a6762b400975204ccc13abb47344015454906850ff14940cbb83aa22414ae
+PK: eaca450996f50cfaf2bd7f9d7fa7087f09ad49664206a80bc2e5bbbb85bb668e
+MSG: a4b63eaed5a64a94f2cad212ce2ae71092fd3ea744f5bd89562b2fc2a6c9e4d7aa27add56264a5a55016610be6c19ff7d4989e9504740853012715a79ece9e12c301b3317c7d9b6730db862a4a1d28058e0f8b5ddd9738c7c62ea572cfe59eae08e2b8b6593b58
+SIG: 02697d44cad862f1daf5708205f450d408525b10c01ffd06cfee80374f3db16fa9a49c19a9844b345f2f9559ea74aab173baa078c54370a5166700c6dafb780a
+
+TST: 105
+SK: 55017e5f61f0c5bafbcde6f849f42a31e5e7a878c1d3f9126fc569fd417ea9f2
+PK: 66914f74ed932fc881ff0166683f675a7c28a926fddd6469cdb3f28e6dec42cc
+MSG: 2fc84a0998fa6e168a866410bb68105df249a28cfc76604be94fd7dffff2fc1dedd220199465575e8df860190f16aca4084169be16c6ba32eb67042ffd4f230316a26b2624a42f8f90ad57f6916486fa91fd94ed68aded4e632430ef719446979bfaf345409c387f
+SIG: b1a5e7c49b8fc6b4331e0416ce7e4ed59edd56300b802e0d72abca4a6fcb876c03bf331579124ae0d3fe43f7898bc87e93fc2da3970fc8638957d18c6613c808
+
+TST: 106
+SK: 0553fba866942341217cf278ac57cb21acd09d9916cc6af0ac46941ea139d545
+PK: 840c66e57c2d4f52a4a2796d2a53c5709b96a628c2e063fe6efd47f283ef5e82
+MSG: c1fae6262a0e98a6b1235fcb62283b7f0a097f9d002416d318fefc60c5a1584f900ad0ab26ccfae0d6d84aa9aa2df16d4c117ea2724676cb866d4870a872fc829a7c2a5d21ba83340adb339a34c5184c7f5ead0f077289b33677ed6a1ba34be1994e25763bd1d9faec
+SIG: bc3364c152ee5c808ac340f49ea2cc404e93517121220cce6f7c30a22500e41bcdb6e820480f8fccdd22ff9ad96da532802f431e94240fb83d4bceaa09b92b0d
+
+TST: 107
+SK: 7a5ac602de19f3c21040bcddbff42f6aee6f95c1b093868f48e50482dbf4f9c7
+PK: fbb6c7531cda21e7d17ea903c4d14be6c68b4ca803a16bd87120f5aaf7dce1d4
+MSG: bd1685419279eb81e4cf3c909031f0f09c5ffae7e2ce6ba9d96c2bce87b8ba0dd763231001e532c7ddd62103abf701288e19dd8f5302e8f5d31b64cc339bd8b7a95550c8a116fd486948772bd5af8dfd46001c59767b0d6bdce383a7078992d1022fbcaf90710687b9aa
+SIG: 84101dd4b5e8ca3ed98c1e8a06e11d7e424b0d12ca714ee7374b64c29d51a2021cc77ac75389d9b0a646a447623d7d04d1241866b0ca6edd1b7ac015666b700d
+
+TST: 108
+SK: 50414cf549bcc55b5b6b75ea3782b2ea7c087b6a0106175e469ca2cc764aeb01
+PK: d0f30c12e997f96e7aeecd1bff6a012ec388ebf8f3f4af664804d1638e4c346a
+MSG: 75ad77e8c54b0b05fb2d162e7cadb8a7528081b863f76a441b374469413e5714edf54f800496af0157c17e425583414d4361f2134171c0b87c22ce6820a4850ab49d99a9badce9e36110e7f3060118b3590f82b43771e9fbb081afe62227e024d98de6cdec028d7c49490d
+SIG: b309800160de43a63a89a0acb8a6050059589b3eaecac20b256fece438042f69415d8a56883ee3836d3134a7fc1de64fa8c8cecc3ce27589f606058820857a0c
+
+TST: 109
+SK: 93cb00d8fe9c9777a683631f39ba0f48761482cf1c366bd863cf715101532555
+PK: 87e94a1ea5258d61180cb828590ff1418a87d01e702686ba8abc2692c8dc3c91
+MSG: 88d8538d31867813d88fef7228d49a7e950d738396f116dda1025f7913547c5d1dc5677a6de4b4a5880507b361780b61b43f7795263db22ff341645f2f5914fd6088c2811211ed4756ac019a6035d66e3170c1d82bfaa30596b396b3260cc1d10d413dd47ebe6daa0c30dc42
+SIG: 09824fa2dfbc4d6ef76a9e4145961116769130553b3edffa50d04f39b8b79facbd237acf71354a53a6e5fee754e823b0b290f9619320a13d561269a221639f03
+
+TST: 110
+SK: 2b4cae380e95ce694c26ac7957447347f98e31b4bf02d744e131529071e2301d
+PK: e6fc705a79c98e115b4e28d3aa1506b74ee74276c5fc1109a7f4d89c6fafb889
+MSG: e0b8250e27b7c0291dbc47a6da6f1268987afdf0a1e90be69bcbc4370865217830d5208693be7b7045099a22ea27f952eb3f79a9a0f1b5a87b19367790788d34c219c2e2a6b834020fb4fd149dc56b544fddbb42071a162fc7cb33c146cac05a31b183e9daadc616f3af449b17
+SIG: 555e45656ba9cfbf5155d0e52576e5197abbbc9dd233993eec2a1ee7f6a86409c0b71b0a661978ff5e0acdc9463dc449906f474f8e79bb86168bf70741e34b02
+
+TST: 111
+SK: b56491e54999bb5a1715ebfa2feb14a545a3a43c2fdfd4be0c95fc11819ad695
+PK: cd42bf414f9bfc72ec069882a800557cdf31bc3464fb102c310e6dbd3ae20863
+MSG: eb4418ba30683ec7959bdb1ec7b263f83e81f054ddcdbe0a6738ca7763e246935bac419026c22bfbdd1236336cc16107c53513e3ddf34e120846962c3bdd54f5ad5749597208f15a8bb56667baa895f08340db89b85c435e770931928d8abc99262f839aedd9be2aa138c9259adf
+SIG: e3be3e71a89852df3cffd72d68207869dd3eceb49b1f029493eccbb932444ebe8c8c6db5f0a5a67e2194408df9841913a5ac1a606896419a668f4f47c56c2b08
+
+TST: 112
+SK: 6579c247dd2cd02ba2f7d7a950a330752681e92c0dc62984bbea279ea521c381
+PK: 0b087bea1a1b3d15805cb604f4bb8d68edde274faf521fe6df50c55f8ad4a70d
+MSG: df7c552ffc89374b9571a6024a8d0471d7eb6be8dfca6f4166b581b65479015a0568129074cc04d6342c758ca18f7987dec536b7033d5f9681504340e20986f027b8cf1f263be76db3525d173422950ea8dceddc585640918aa9d25ca89cba701c2020153873f46108c772cb388d55
+SIG: eccaf801ae0a912e21c6b83a5f0e4e88d4b2713459ff93449fc0b21a9f416050113cbae4e814d20c0a798f76d2f9d326ed83959ea02abdc1ab350a467123f709
+
+TST: 113
+SK: 18fba60c5026f3c9dd7aedc04209d5260361de400e190aeb60169e05a3367c9f
+PK: dfff347f3dd255530bf7fb34d02ba486d112bb46e950e2ef80e517014cc95734
+MSG: 34f08a804d7829cc3914f000ce1a3288acce2149c8a02086b9f67afccd83a178b0bcfd4970c056997da7dc3d47562f16663cedc52f82d710850cf4050379efdac23bee17c330a383ad137f788473b2b0723603b6deb1fdbf6c523fc948a0ccc4ff100fb946d874c1f990436ae8c4f3b2
+SIG: 4bc011e40f0f59c618f6bbe230b6f7bc2f50e3617c7faab7f4c21cb84f77eba994cb7c2a1bf10b01bb20084497fdf0a6ab5d9bcd22c4a2c5a78f79926825940f
+
+TST: 114
+SK: 073cc15b0536285933b2be39253cf4fd696b81610f5dd3adac2e9cbf338ef2f6
+PK: 00b551d371544375dac5c4e96cd1f0215207e8e166a1fe49d5b0a51ac18443ec
+MSG: c285362bc8ef628f7aedf654231ee51acdf2cf69a886b942bb9bfed8155105d9209ded2af24f169ad5fcd451370f5827a85111c7a52e032c5038617c0c0170e2a6c231dc401d12062edb186036114e38793b79089077581b9783f40007103ef17472491c00e7138aecc5084d3c85010470
+SIG: 3aa52a83062a8f28a5d6b7607f484b66cc374896b766123126333c579581316c742806f627b5bc55cad705cc1d4782b044080c8ac840f38c0c50d35e345c7803
+
+TST: 115
+SK: fd894a1e8232203b289505d5c68c68791ffc0e54f2a87530fbba5b3a3f2caf00
+PK: e95ab565945c7ae5d533df5d0cccc7e9abbc838e20a0b61c930f5d41d81a6fe7
+MSG: 2669624a94f2c44a05b7dc3ebf93e58a4bf3a01c273657e7e7878976f6b6ea737fa3f22cc8365b8b220c007d5b642726a408fe2fab69ebb3bd072b349f4dc3377ee7cc752934254215d23989bd3cd02ce999adec9784993f4c19940815f39c9e229247f5205c36cba44e714266369289b4a7
+SIG: f51102219e8804be713e556df4e4afa2f8866fe86541a1c2a0934d24c3c9beb280a70dd8d527fe8b7e0b948214d5f2f9638619914b72d55dc198b0229a848708
+
+TST: 116
+SK: 18ef464e28f87ffcfa4d3a9c09a22910951b8c719fdacdb56de62c4b406df00c
+PK: c5064c9d43ee2da75b06bb09c77267dbd0d39128f1cdc6bfa451a03e93af4a70
+MSG: 9c825707d9358365ab9d38f7e728d628aa722a4f1a20a38e47c999fff8fc32417fbe072f96eb6a0e11e4da9b6de9615445280e93c77a3634d3d2c6879856c248f9800f60a0d38dc1cea8b7f31f286cb0374827b4c6ba144a6694f2b908ead68d18340124cb59cf1701863bd4f3efc709f3627a
+SIG: d1e7f16e8e597d428adea65591d551b54b667aff2020c464f7f4e53c4773f70433249a3c71b4d11c89c3faa892809227b9f29ef4f7f5d020d4674d4021359405
+
+TST: 117
+SK: c911bdf2f9e7cc5fff35c96e15cc12eafd05ab0db31f649f7408acd0cada76e0
+PK: de44696cd6bd2cbe9b11a0ef18b88164801a969d5e06ed453eb4008cce9a5725
+MSG: 76c471241d17192984b00362696e4d9d4d2b7f839c2064117e50a1598f3a1172b16c55e5396866084752024f3a7eb68bb3ffdb80979a0af6d0f6af26b6f0bc0c0384433bcfd44c75eb654a8a8225cb9c4a7fb3c824c3af6125fd46db287e70492d154632cb8f62432659d958d6281d04a54f5f5f
+SIG: d584b5da371ae4f5c9859b25f70dc56c1b7b4e02d1ae6636283b1b7b11217afdcdf65d1b49ca2c8ef17966e9bc65f10c310b77bb5df7aff5ec1b379a2ce55d0d
+
+TST: 118
+SK: d3703299c41db36d77dd3a49541f3fb21d0b2bad1f6e074affd96f1c40d0f927
+PK: 862c5ef616a5f066fd87758a56ab45056fea4bd33f008be24f7b540e095e148e
+MSG: ac92edbe22257bb06d94aa950e62d18ca2ac0a8fc106000d2231f8a13b8d7a209ccd8cc49a6cd68a7f36c02fb8f728d15595167f0ba8cfe95c8a1e435f327513014ac428b75d4f72e7c834dd70e1a448f1847d3498475f74e3d9334dc7dcc4fed72bf6c7fe3b1d4f53d429616f1df44f19733158b6
+SIG: df28277121eac44630084cce75917ae9f6bec65af5572dc30719bde661cf696b85b8672dd4983cab30bd05cc3a119d7db9babd522d7b3a6bcf3886ecd25e080f
+
+TST: 119
+SK: d411cd33576d0efe9ec413ccdaabd4fcbafec01a3af4b3cbe34f8b05ef8b59ba
+PK: e870344df98dd3a8702c4519bf9e8b35a9d189e746f7203dbbf9bbfab22d6f63
+MSG: 11d2c2a7f0190988126696431b4bbcd90ab7b56a32da6404ae446aa762a4ddc66094971538eeb85bde0470a510be0d6d85780ee730a9854138728ae6816162268da852858eaed4ec74c7ac62e6e7096dc002df0bdf5fa40da565b41d181a3f0ad0c5e0b976743e315d9db8ed4160abe69c13a2b3f09a
+SIG: 83460d15461d6717710bafd6a47a1eaa900a80f2bf8b8aae2468773614ee84bd628c9717476368ef3640cf760acac83ad60232a76963b7d52588b11dc004d70d
+
+TST: 120
+SK: e10a2f1380c3e4720e8a8707a9bcb25a0f58270d7059cd7626c7153447edfb87
+PK: a3c717acab366a40b51187bbf35b2d15e97cfeacd7349c06ef1c91ac93e90656
+MSG: 135212a9cf00d0a05220be7323bfa4a5ba7fc5465514007702121a9c92e46bd473062f00841af83cb7bc4b2cd58dc4d5b151244cc8293e795796835ed36822c6e09893ec991b38ada4b21a06e691afa887db4e9d7b1d2afc65ba8d2f5e6926ff53d2d44d55fa095f3fad62545c714f0f3f59e4bfe91af8
+SIG: 094bf6f953ca0eb77df45129b7bf10d192cf6ddeae94ad6202b8eacfbec119e5291578fe64a084ae600fe07efdb8a782610dbdb0b49eb5f2a46c432355552f01
+
+TST: 121
+SK: b2e697b3d3efec976ef3369530c792717bdbb428d9ed0c11ec0ea9b2e5f39f82
+PK: c4d2e4b3c236d6c9b8c74fa384612c4710d83aa16ad7ef01fbb7421d4fb3f0f6
+MSG: 7b436232ac2111a84059510c48362588fcb7383426be5e6f62f372e4f7cca83c81c2357f9b54f4a15291065b6d41aad1ea93cffa776b9acaa58afe2b51644b97af9a3e53f84e40aa6d86051e6914cd039d4170a9a526dd69955ff507c33f74e2176591fb0b3cd7f00ee418f2c258a9981cccee72f01c8430
+SIG: 5047fa38197b8328e78dd8a10e966afb7bd3d43608280f1c257d25ca43bc1c06e94a5747ab6215ece54cdeff8c56567d70d2f91f9ec8c260aa1080a6ab5a7a02
+
+TST: 122
+SK: 19a679a7a905a1e2b3038e6e418b3da97c3089c7cd351ea07bc8d1af64eacc46
+PK: 19f08361f469b4ae1e0ceb94f47a7de7317410a92dd013b16ae0d0532fa4b3ef
+MSG: 980c7b4d2939061ac7b9ba441117a19485661781a4083067c55acf93026c082a93cc124f095e1b4f2c3f6c135412a5096228e8a071e8b4b668ba9d9644ea9f4dabfc54a9856c3e965e6363395ab709037dda229baf927cd01f9af5e039afc42f3cec634f5d832d2ab7c7cad3ad7b8cf27ebdac698431ad8236
+SIG: 4347b7b4f7c3c4dd315b8384a0b0caeed84bdabe24b2915f12512dfd04770fc996a1bfb729afef9edd611447081a5330617eaea1c1dab1bf13cea8997204910c
+
+TST: 123
+SK: f03b8363ee5b0eef7018a49bc02adf731da54ee50a7f03b88a29a2082b189c43
+PK: 31287ef5a2e64104ab7790b312f35c7ad4af6beb0d7ceb8a58f36a54ce272c3e
+MSG: 24191b5464b35ac7bcf4a375f033efba8943b09b9ff0fc403ca7aae702a3cbf396c5131bc008132cf5f12910d586dc1db9c084574a96babee95642f922371c0382ec0402a26feb142e4146bbd3360c2b36834fe45af5e2868d4d56fdd504cebf0c2d7f5791b4429417c8b65a98e0b15c466c137f410524fce737
+SIG: e8fa967e6afadf6a877d87e5f5c52bb634b75a7804199a2bc9d027b63a35654d9ddd06830455641dbfb49edce42e20e7d4104a071c2cbbec23018c297ced9908
+
+TST: 124
+SK: 11086b0d11e415ab1ce02aaf8f0621b54430f6fb135c74f40d38e8c64737064b
+PK: 7166dfbc691eb8c201114ba0d1a2c7b87f7a1fd8d0b36058b0d7dcabe1ae30da
+MSG: 4b5b2936c5e360a38455503721078f8adb404a7ee7ecc14801dc87a67a152b769569fbeac0afa25a2070a1686b900ac1633d499808cdb2e81ce3916d5a3c04d19c5bb2699a662b8aba4af94d390bac7ccc8ec910ed2acdf86ebb71adb601877885eef3c91662fc30738e352cc74353ccf8d8edeefacc042c10a0e5
+SIG: e907459d5adcd0d0c36418581f19d0eebda7138ebd9faa0b262201f458c856310bb77f4c7de922495dcfe8b248eda2ad0df6a73f47bbfb894baa7d8869875802
+
+TST: 125
+SK: efce7667a8ef91228caed14eb477a345e5e8239234080848760ed0970713fa86
+PK: 9193055a84df1eacca28ce2a08c2a07a50f04c024ecf1fe4a47d2efbaf63ed58
+MSG: aa1bc80d7bcc1d94a23a57cedf5027482477dc46b86890bc0e5ac29ae6c91bbc43130348797305f75543580a8a069b348a7bd8fc3e015230b7c1940c7f80a82b12900910dbcf0630da03f081d44c7f955d4a1172f56ecc7c5ac646696bffdf4eb6d88bdd9cc3843528b72583abb3bad02e56ef7646eed5139551cdeb
+SIG: e5a63124db1696b64140b6e9612fa9587b3eef710109398d44ba0ca63c0ebad06f0a6c8994ea34b3a2af91a89bf41ae614d7727d716fd42f8b92e1ac64fdbf03
+
+TST: 126
+SK: 88fccaa96ad884d1165be71dd0c4f5f8f4421c60fbfa498bfee9b967462443bd
+PK: c75cb0e0237b45b8656eea9f3d1a9d4acd01a103aa269bb24fd54122fd81f2ac
+MSG: 9d0eac98556bfa8672c35705d1d61ac4d0fca19dc0d993015877857d27fd80f74acace666c563485d81e53603a6aef40875fa551cc105f2cc10b39694679cdf4a6b073bc88645fc51a36da179d3d1e3c7722454c5e73577c61aa7d148c4ba50ea46c56a1c3b3b3c470f93100494e08bc5514ac763a85483c42c7cdc27c
+SIG: 27d3a197cc9994212063bce8d799e77b6853b7355ebe369bcf1889a418a82caa3a7987a663f621defe86b3ac4ad44faeed16c9116ace28fccf915557fa779903
+
+TST: 127
+SK: 670b30626fe367d8b45f43733d6f25b37eccbcb551963f0ac8b666b48041c72d
+PK: 65aa4c6d4ba0ab34bc75b39f09527ca6f2425f52415cdffdf2dff273f8ea612c
+MSG: d00bcca7e184d10e1f1fe420b50639e1d5deba52a751236e68c59bb4bff9802f5fc165ed42fd6d534670a7c6fb60e4307d947915a248bf2f93465c2cb44d8f453d2c015afbc8ed58818ea51726a25177930e9ea192ef4514f4bb0eb4e0f5d4ae3c46e357c81187f7ed174733fff959c3f9fae6486cfa1356a95699211de5
+SIG: 1b6b4377d2b98e0f9d24ae8dfe30e2396e2004380d3431488e5843cf8d2d7a0070ab21f8a3b51ce84d2f4ba209f739f922bebf798096693f5622873d79ae6f04
+
+TST: 128
+SK: 813c4daed67a190d68bb635d73af6da74f32fdf7c48cca6e59262946b8e8c71f
+PK: a2095457d7697020e2b884d95a96578c2a900a7666ac0dc7bd38f1931d7945d8
+MSG: ce54cb0450e689a0dbef785308b3177472fcd6d38203e58a0590b31fa253f9ea590be5368a922de88b63450102684443fb8189e601282003323b89c81e92eaef2b5ddc4a55c53fa3cfad4160248b3c286ff80d31d161b7b8dee713552b56f1507fb72eadfa89054e9d1600ac874c4b0a961004eb6d0d4bfd2ecb9c734f00ba
+SIG: b446574ff6a4bd2b572e487c4ab443ca641075168aa4e1092f71f30bdb068ce46a395efee1ee660b9fac26d54109722c15cdb791bfb87fff63c6596ad4f2270c
+
+TST: 129
+SK: 8400962bb769f63868cae5a3fec8db6a9c8d3f1c846c8dceeb642b6946efa8e3
+PK: 98be21001993a7eb1a1277ff74c15504183d25fdfcc05f0d4dea892f6e301890
+MSG: f7e67d982a2ff93ecda4087152b4864c943b1ba7021f5407043ccb4253d348c27b9283acb26c194fd1cbb79e6afc32ff686b55b0b3617218dcf39316b4b66b3c8c0d67267a86db8adf3750801bcf9327d4c25441b96197832b4cde0eac3ff22892a2f0bc17c2c213c02377a333e308ed271658049383b7e2e57b6b8b125512e0
+SIG: 0ad71b0025f3d9a50db338414d6d670e7799b7270a8444f6ae7f12ae7eb71bd03ffd3c4f36631f69fdcc4061468ff582ede495243ef1361a3b3295fa813ba205
+
+TST: 130
+SK: 6288722035d1ea699bc7cfdf18d89625423180b683fa74639f4f30f15359cc85
+PK: e17faa019572861a064e1bc571256dea1468f3a48590a89138aaa85925080cd7
+MSG: 8b6caacac51d8949fb86acbcb1b99d859ff67c64147bc1216909dcab07ee6ef09f403863327394689dc34abc778fcb5c1f5091acf5a08f9d842211d1ae2eb40be9bb8d6679077471547a6c71ff77b519d4b7108e32bc46251c60dee8e332b6229316e6d57c22ab826ff1bc33f2b0213807c19280af110fd26ee27468201cff49cb
+SIG: 9dec92b6e89adbe8f4e1b5e93ac4fcf957de7d1970a226770ec4eda647c8e3b3dffb2731a39e16e4a0119d3662a937e560522491ec7a1696be04c076b12e3501
+
+TST: 131
+SK: 13038a3a65ef32759a9cd903acb554b252de00e7cdb77bbed1970b20680ee17b
+PK: b6a308e67f9b46c66499456ab5cd135cb2fe84a32eb045358626604da4122c8f
+MSG: ddf00b4033a2a088022dabe93356432f50ddc6c6e1a659dc1a93124a4c2ffffd182765a2f56c43ea0bfd8de8015060889ae6941c3f3e255d4421a1c36201be846a2738a71f120cad598ca8527d70ff8d5a0993b55cb5153517110a41962daff42250158f2096d1ddaf7186e50298cbe51fcb429cbea411293f8a7bd9cf069fa237e4
+SIG: 5261558ecc3c98ff36351f42f504cad4a32ffda5a744560960b4c106e4492f02e20478887afee4f770f05597a7e388caceae805ae351e0e45e8e578e6a6ff20c
+
+TST: 132
+SK: b9de5b063d3ca3a773f114941b2e4227c07511c0f5c06017b9c8845018f23432
+PK: 5295243c8646e096674dda15979b322b9dd0faf27d024a0ed5771334e1179ed2
+MSG: 9493cc23896b84096046ae1053afe39499e9424254b366fe143f4da321e2dc9e4784208e12a542d899828dde7eff625a7f12416990c2841ffb095bf94c0c610e5a663918b689031ccd6b519349d04de1c212ca2a9d7abf52e1b4fd467bb665b6919ef8f91617e205565bf56647e5f8d508ea200a84467f8fa122e74bc3b9979f1174e5
+SIG: 92ba760d14d1415cfaf218ca847014088ae51ad821113a6f8630356f7ba85c005e2330f1066d0df464806052a4174610050462f3e013d702e7c77185a032580b
+
+TST: 133
+SK: 8ff0297cc08842b5e67552ec2843e04353a34d74ef89b8565d97205b74ca133a
+PK: 0f7ef98c5ba4af984dfb77bc4e537b2b39e6273bb3e7b95fe1b7e6781952bd4a
+MSG: 2bdc3a486c5e4ea62dcfec8a9d4fcf9ea9490dbcc715615d58490a72ce833fa22387ca50a0052508cf0aff1ca727f0fed46ffa7d3c8e23c5bb01d47e90ff06d3858a557d9926481579daf4384aea50e96ec615d2a3bf3c1122f1f24dd6ed98a5de421883589c213998ca5432373e68bbbe89428ca9885d0593d5e6215116b8266386452b
+SIG: 0783737f706e6ff36614f850074fca1f485f24fcde2a28af544f37abd69b7a581defd8c771b031e108d19d788c74c5f20bb3f1c21cd92be317bacd8f650b4905
+
+TST: 134
+SK: 050d553d282dca3269c83c181768ec067b81c9fe0c94f2a0ebbb0c942d0fcd7c
+PK: 63e230b003c53a5672e832ff7f24430be223e497de840233f595a3e200c7127e
+MSG: 15e13b8c01004f6aa5b236dbb281677f746d81e548e0aa80f0e414521521d856cd694e7c9152bb5e43776b60f6b560ed1ad3e4b390dbf3e46ef9257443f39c149e0240a02d021e1e3d7d046b26fd004eee7ca16a8059e126c74cb3f2194db47bf60465ecef5c704d2e2c75e2e50060ea2a31cb72b7b3c6b1b5ec72ab38004085281a22fe86
+SIG: 3f0e83765b31bbe8e1fb92e9678d6cde571a03ba7f1dcc1128461f708525457f4e0e2353aa2b598c063ff1bffdac916b5a2200655156904b0585577a1628560d
+
+TST: 135
+SK: 69497cd7b4e868cfa0328d92bd6052d772b2767395c14595b279851a9cdd31aa
+PK: 5d276d626e230d18e7bcd61141cb93c90ef0f79e01321212d838ec71457b1aac
+MSG: 53cd080a0c61f1a093d3b3a74571c296303f363b4107edbe880b7aa9dfe44ab5d5dc5f74be9c8d876f04d754653491ab51b135fc953f71287b62ff41b67c742bd3445671a9d4f2dc174ca1b0335f78627a0dd4b30650504178039e7393638510ffe84091b57298d3ac9001c367c1452fbcb33dc54a5dc316fb2a5270764a2ac820a0b63fbdc6
+SIG: beafa58340960908e8d86e40329e3a4523fc7be770addb86e34c3772f84cd9fb338d1f3b65bfcdb09f35c6da36d1a3adf8f91f1ffd5782cc830206433a08410d
+
+TST: 136
+SK: 2165a486b612bbff529cd00346964a3cb8cdcffa51dc3d524dd5adc5ac936d68
+PK: 7ebc839a465e14f5892476e4a13b3988f83b3cd27ef79e193f86fa16f34a1ce1
+MSG: b728da7a36167c6085bd2d962cf63959facd95c9ad4542028afba90ec9c6c0760bdae935429c3feb3933e2f00042c672ad2cd7348d92bc33f81751e294ae9171b945b193144ef8acb9a1bd9abf0475ce0d0ac789b200c32e9c9a2736b168369ce5f97b1e8d2e7900e1a759178441f1fc430564ae129bae7857740511a668f32c0a3b077a9d8b19
+SIG: 7ec6fba56ba52460a1b4f2738689c1883dda9aaffc8bde17cb6029bdce3a0ebe2fffda55939b70bbd07fdbf6fc5cda87fed8ba58575f894a366e45e5705eea09
+
+TST: 137
+SK: 1c64ad63dd147034598e128f7406ec0530746ea1c5b72ecf79e888065486fa1b
+PK: baa6bcc1c3d8d3b11ffc1587adddc58bfd96c2b992b6c6f59fcc50ccbcdd0eb9
+MSG: 9ebd8e337893bb053ef2b9e3269df54848494f03cd63576b33e64b1080be4be015264a403fb9602bbf90ca19b241a9b66863909b9008ce1b2ffcf236efa4c2668f0f47db9ff5fa157d9cb605412be7dd8b07ea878cccae6bf50f935b86d19e1b648b69e528553a56d8afb78221ad53307b7a4ec8d2fd4861b55dc5dae8e93ef387fbbe0b4ce7f788
+SIG: 7477e54158f13b7128c0a110ca6b65f42514fb70cd5cf28a8b1cc6110ea06fcf94290da13f85a11c2351d3bbccbb4c64e0215d6d0f0099e7f27bc94e949b150b
+
+TST: 138
+SK: 55abbc5dac4128134dc8c6018a213ed4b60fcc8e90cbd41db2d21eda5373e936
+PK: 251afaa2646926b2a371f2a09d5865b98c9a5eb6ca047cd0d8ee36e5e0416974
+MSG: 47010e1398ad55fabe371dd8648f768d90df4b965a3b396100b303b40a17518bed6d86b09f734ab7c10b5f3a01b53deec5f8534b70c79f3f29b284fdec486f22f44c22ccd5c6463594415267baa611f70b1b316caa1b68b5e0e99b31c5bb0ce13679a23c31a63999698164cbf37d103ba92490188be59937f123043ec786efe3d411f9b0623a6ad972
+SIG: f6a61c2e661a9eb7bde182e38ec99af985f61698a5d7fa430d16e3f1a93709b75522320de48afcc595ab209122ae0ce132cdf4b0391746e7ff341177570c8108
+
+TST: 139
+SK: f2dcf4a1a0d46ddb2d72f8fdd80bbec5b7dea5913da4966c2f4d12c261f0bf98
+PK: d39570a25ca59f2257f93f96600df4f63e684bf63ae8dffd914e4629c3d5095f
+MSG: 3b00e808fca4c11651d853d6b90f952ccf5647e102d4ee0ad7a5d181d5b4258c523cd39e3d9825298d84c8cba09f43dbba119988222c76059caf17b4bf9931c45e617448aeade151181497b24552367e52bc45ac79088806d3368207aafefd3057845dce819d5aaaa77b218e2aed3da76d40c1f07699f8172e4a5c803f7a2aceb9a47a8952e1b2f053f2
+SIG: 42882a811dad2d851885e4cbe9044708d91a86f15dfa1d66c3eb304314531f3015208c711b9bdbc5fb233951e569b59d34e415eec4b37ffd374d412c9a360d0c
+
+TST: 140
+SK: 2246bfb06155859e10a748ff8f5919ad5d1daab756f01057b790d07474775f4f
+PK: fa6349b62dc8c6a2feeef6ffc33ae085c649795c1c9d9898e75c13ae1625db34
+MSG: 63ee1c7bbb15cebe1c22532d481682754bdaf58b8bc997ae30a34c9d23c33f1690c346ab0a7365ff62457424b6105f8421eca0ce3c630acfeb9a1cc416390edf4920e22b2367e9fb5d2ab25bee56da03ea55e3f57882d48b89229314d734cb83c79f4e17ee64bae6f7addbe9b525fcd03a91409a2dde907751db8cc97e08d0ea89c4d18718d26d0b897b64
+SIG: 2be4915a352f7785483046d8ae9625b8b63257af57c073691256ee076d6e1b972a101f551c705d3f96157c33b56ea049be4af4dc561cbe3c1ec5072d7f134e07
+
+TST: 141
+SK: c088a3dd2cb8bd5d684db8538dc22473b6f014f64fe86af168b4bb01b90a1dd0
+PK: aad615a9c28759f03d373abe666691dead8b84f9b8b50a67f8f0aa4a701580d1
+MSG: 74906ae05a5af8e9968b6feb498569d6345a24f9711befb136e6c3b5ed49339e59a7938b4ba1a118f169b9ace0f7842a26a645f14c0ad22ebbcda93e67e4c348efc3d9ecbb1419e6262d0436a58ea82c2202389065ccf67c4f550e45b5f6a12a6c011b2e0a30101d5c62328bbf99c8c95563a6e33bdd9cce72b1f720139c2fd3e04913146ae5bac5288e0e3e
+SIG: 3bb459d1ac575a180c1728d8b8924970492a0c8d2a378c29d1d41785c8379a58e2ba3606785e1c5da29e5527552bc6dc89a2b69c27fe51ed253a9f3b565b2700
+
+TST: 142
+SK: 45667d1e7b5910979c4a328317968371c864d564a661c5cce557c9ecc61bab9e
+PK: edcdf5e1a170e00c8c687e7e9c18f9893b5fe495cd2977ceb7f446c0149aa9d3
+MSG: cd66cec476c87c8dbf47ec91dac48fb5b42db1282a573e0a5cf0b91768986608e1d7ebd05f5251bcf8b47a17093229acefbd44beb21c0c0c928dd3cd3f8966ecce6910331c508ea76baf904d8c21f6c17c2c58d00afd3259b8bf794c146b12b995cddd1c4289c5be3168ebd616b384c281ce1b38a10e1807808853c681a640a009b4d2acd7934f8c6d07578161
+SIG: 6de668f1ca6f292814625289a0808020c87c89ac94f5b0508e557bdf8000a5ca808f021c9679b50ee2f320064c95a464a8439379828c3b76cfa766455e128c0b
+
+TST: 143
+SK: 24897428ae6546d85b3190ebe3f1f7bf7c712528ac851a588b07d5c8f94eecd1
+PK: 5f348fe3ea5b2c023d0af7ede60e55f91aa55199699da15a11c3791d68d710bd
+MSG: 5201d9725f1dffa1863fa4d84c301861141acdfb64be1fbfdd5b9386db20ef394099eebcfdfecc62c6268607a84d55c55cd0efdc372ecf3067343e7b0731c2685461e24b953f99949e59ba3e67ed0f0848313793962a292c459814c5e28690ec1f45171f1abab86fdd14568b00caf48581115ee5ea83b000282fbbf0c0b2a1116039a35cfa3f201422207a3d4948
+SIG: 1b5e75def49f51d6b2de008c71fc1a909bd42ca813298dce4eeef717815d7a6c078c2f3d9a3fce1ab5b3ad8ef8d45cdf2eb4901c32eea2d5e018dcf2833cad0c
+
+TST: 144
+SK: 7b04aca7cf926216cb960a3890786339d0a615967680190123fda3b60c6aeb11
+PK: cdbc3e70e4e8fd13d0cce2852a3b9372c3a6160cd6deaba90f9b3022f70c91f9
+MSG: 1cb09624b1f14a0260c7f56d8c60b5fe45837114232551ef5966386e0c2b441b75cfdb8df2185785d22cf526fa9df7fd45d9d83881b66c1feee0913e238121eedbb7ab504da0bee8998016684535031991f11bfcd9b95690aad2d19bd6a9de1844ed1362302df4217230b25c0552ce277534c650cae526577f25d8b1fe9f9febca2c814670d4805b21adef852daf94
+SIG: 25d2d361751d52b4fe66ea18e4b9866bde3d121a7312fd9e28a1e295e087e3176c94c874a2e81600f24c4654f43d1b67d47b64822648590ce5ce44f3b5ddc502
+
+TST: 145
+SK: ea73bf64a1a97877c3c3e7ca4644b71aaa66314c8f1b66bafaebd5edfb888bcd
+PK: caac93902e5764ade47294edd51faa14620940c668b5c1c392a6928325d4c3fd
+MSG: 362eec68b912852786bb4f9afff9ecf7cb28c9de6b18422a8ca940b0d7e6dcb83aa44be0afb5f1806d43f0e31d71f922f853615a26e287a27f08a04fbce3d45a0c6c311d4b7cb17e425bbeb0a6b410b5d6dbb7ac11df9850a131a691e3b60b0b214ebe044106e982433287595267b031b5d4a09262ded8934fdfdf964d868ef9a2c842f804eafddefcb71d9f16a59bf8
+SIG: bd86cb9c70a055279a86a9e64870988b8a7345c3cd2948a0fabcfb38abce3c420b4d5521618e11d2de827d9de569f6bc3be66aad40636cdaa64760ded3b7c209
+
+TST: 146
+SK: b8123c116b33bad0dcbc2c4dc06a3d66850dab360cdb5a033c14895c4ee31bfb
+PK: bdca151ba32c6bb31531b05fdf86c6d78c8cd1935611d5ff111a0f00635b1885
+MSG: 7970f6666634548c848bb52338817b26a4d0ca68df3d28afff207c2d028067a18e4c9543025f5b0228aa691e5088513151a94494e15d1f54210328e0df159b352c30aaa7a844f18a9f4c395dcbb3fb9fcfbed1103e0706fbf9c35fe2666848fa35dc2cf5227ebee89e7d3bcfae2721b25fdec3d3174ea7ce267a55dd61d58201e96bda303cf418edf6e32fb92f5dc1a0b1
+SIG: 9cf13eba3dcc37b8fc70ccb2327436b9f08855e726aa7ed82bd5cb7df45fdf9ec1f96afad193f47572d770444b65b74a37cc034fc514cb3f91b2d8ada5b02006
+
+TST: 147
+SK: b18e1d0045995ec3d010c387ccfeb984d783af8fbb0f40fa7db126d889f6dadd
+PK: 77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb
+MSG: 916c7d1d268fc0e77c1bef238432573c39be577bbea0998936add2b50a653171ce18a542b0b7f96c1691a3be6031522894a8634183eda38798a0c5d5d79fbd01dd04a8646d71873b77b221998a81922d8105f892316369d5224c9983372d2313c6b1f4556ea26ba49d46e8b561e0fc76633ac9766e68e21fba7edca93c4c7460376d7f3ac22ff372c18f613f2ae2e856af40
+SIG: 6bd710a368c1249923fc7a1610747403040f0cc30815a00f9ff548a896bbda0b4eb2ca19ebcf917f0f34200a9edbad3901b64ab09cc5ef7b9bcc3c40c0ff7509
+
+TST: 148
+SK: 93649c63910b35718e48c590d261c48e4ef8336613f6aa077b462676b3ba8829
+PK: 06a685898b855212ebc289915d105a4320d620d85771b8c6b15bf10a1be6e9b8
+MSG: 2cd1a951056c9ebae1399b6bd2d82c0ae277856290d06920ac56cac8fb42435101c72aa9c08dd2d12426325562c2f0a49cd821b11b939aafa593b4095c021bcb4827b107b9664d68282888bc4a44af3e3bdc861be6af309044c3daab57b77023dc902d47ebc326f9bdd02dbc02cd540ff81b2ddf7cf679a41193dfe5f8c8ca1aaefc41ef740280d9823e30a354717c8431f5d8
+SIG: 6274f2d4f431d5affefa35e7cf584a599017193da99094ca908b75acb608d1bf981857be93a7dafb0fadb3ff0906f48a5ee950456f782c2d605b14095ba0ff0f
+
+TST: 149
+SK: 1c15cbeb89362d69476a2aa4a5f3ef2089cf87286349e0dfe0e72d9e3e5a66c7
+PK: 13a882a1064182582c211847e19b4dac59722c9ffd34826d96f33113400fac7a
+MSG: 091c9b9b116ae83d23d01a6295211785d446b6228dd687ddf79bd0d5a4daa8c79d2cbfc37365f1f285e361738123e34e2bcbfc664ce1253a11d9e4a7982e58cf9468e1017ea14d2cc6d0865d40fde8cb560241e96ac1617c791f0ca7c6410cadf328611b18aef333d8350ac497f0a4ae2d03fdf0e23e426d34f4514780d1474e113583541f3c043672057172618cb2059eaaed56
+SIG: 5998b2808adfdeeaebe2c3eac026d3f825f9c7f2af97ca324fbd57aac1bedff78a8ee621d037ee3ad2a712e9a009c58ea3e6f2a828f74b86da275a44a4b1e50b
+
+TST: 150
+SK: 11241ffdf34ae8ab875475e94c6cc3291f0b8820dc85e20f32fc53b24ae68978
+PK: 09c045e4bd5137314c0ec1d031faf914910c45a4676f5a3cd8f581bcccb03c97
+MSG: 3b89deccb7023e4b2b7aff2c3951870af413a9b04dd86ac78b7c8fd887492d8dde49d8fda149edd54781ae2b508030d14416a9a38bed2b9aebbbb20250b3c931acd4e32fbeeec5a26501beab7268d144fce8951a101c4b5178166fbb5927b1dfb1e1ce90d1d123068e3f472c888fdb01fdf70e7f8de9b0adb284b7119f55354316f84ed090030f9c2662061ca48447cc0aef964126
+SIG: 72ce9f91be2e66cfc90f952595946ffc90bfce53087d49e5dd7c087f3faa8f18f2356de971e4429d985a99194b4f92ced3ef47cd7114379e0b3267a9f8b1e706
+
+TST: 151
+SK: 3bdb162465eaceff98d69c86f70039c517d168aefe6bb101b4f769a86b17c972
+PK: d76cb7be74328289fd1c64be747cca5bb30295dfaccd0f2e43f51703fd5d3683
+MSG: fbf368feaeba87918b1b8c7b8a26832be6e7fc1cbdb8902519281a0654ec73de0bb07101a9d603f745d4ec2357aee9870cb19a56cb44fbd9c91fc34752612fbd83d6fc1a16bf8a85a215d0148e4af37d298467e5cc486b131352ce092182ce8284159a3812b30bacbff595863811bf9a30a9da494565c3ac1814430018ea0eeed39cdbca27f93140e46949db570bfa2ed4f4073f8833
+SIG: 6f1362a402063791f950984f544928e616a4ef79bbeb6854e9615aab9cdbaec483fb9a04bf22de5d97a15bda2d390483c7f61dbee07bb5141fc173b1aa47650d
+
+TST: 152
+SK: d5efe51d5cd8e108bd922fc0ea126190a94628ffa53c433a518022792ddc78ef
+PK: 426b01cc61ff5e0e724da1d3b297f5325c18c62f64d5eb48d4a5216a8e9a4073
+MSG: 9d17bcfe2dfc742f411cb53a94f359c001abf096c741f34af48679f281e7ce6bbd9e87709fc0728a563db2b9cf8ea4fbdcc344c1848e653ce970c6ce29de2ccd520300649adcddfc753971f846aac1ba42ae4528952d94980aa7c6cfa2142907647f894ae974a74d59035a73ef56a10b6612624809520190ace661c3a47095e0322efd781d50d1163598f2da32f31bc9c4f913d1b14861
+SIG: 2306f58fcd4cff2222d81b05a475532b8b19dc67e6d78ddb4205a3b7621cc5aef0b393d5d24dd96c88ccbc53a3208da323be4587d5ec067c820f0723aa44e90e
+
+TST: 153
+SK: 18af89025ebfa76bd557cfb2dff148245214641fd5bda159f73da04b08e87c88
+PK: 0c584459b9ebcccad587b272160bc60b27f4f772b4321de7723afef577edc7b4
+MSG: e82f46652ab914af535d8fb720b557ac95018d9f2a3fcce85771bb40ab14cb9a986e096f3afe5bee829dfd8b97335c536ac971a21655af16a2f8fdba183a4e18564c21492956537a419abbbbb02a4bbdc01481f5c6e658ecf3c34f011ad846f5edcd4939195df85e41303fb9a88fdfbd704396f7559a327318b952b3e60ce8ddde56378579232faf950c78e7f0b17c3b8dece36b788a8473
+SIG: 26bb0882297c2c08a752d3981145dcde55893a11df77f8aa4c19d0b9ed6e5220ed12e9fac3af13d0f0c71568f4a547d30114a6599a236806c4beee6765284408
+
+TST: 154
+SK: 0c93d99815fff8fe22b9e45aa02b3e6445ce1d6bf5a65dce3da107aa1055940e
+PK: 4d27a47b0fc80800d84d244eebb1deb4436d97633a83e67125ad52ea01685057
+MSG: 11e877de58c134eaf4c9f1b53c3dc451d3c055f16b09622725b279768512fe10a7adb0765b689ec21d5b6efaa19f1b9d36254df0a9367f441b26bdb90b28cbc403e5074082fa1fed58e140dac97aeaf483e2c13f3cc560abffaba05b763feedb51e60698151cf56efdf1d37d6ce0564486210f052e937f2ea26f63efa5d247ff188329bb1aa83ce3f4f35a3d7dec14599e5feb7b6d5fe4296a
+SIG: 7dc4467abcf6431adb7ccfe868eac8cd8a615a0ff65f6a9e338375b1aae3c49a126c9eba79426d1641c6b97c3e92c194e5ee4431efa2439fd450f2cd018c8700
+
+TST: 155
+SK: 989e99945635192c023cc5186fc25bbaef47240775d15a56195d88cd07c3748e
+PK: ca0beafdf731d89301f7723c5bb7e5a1c3ff3eab27c97d711bcd76e42054bee4
+MSG: c48414f5c757d03c523ef3f3b8510771b0ff3b4b97de279625d349ec185a29927a66b9593ba19338c2f5e4131f1ac07ea46d2c1b6e4ab5229280b2e2bb9d140d1ef7af7b1692bf2d097b80f811adcfa95d5cbf9eee92a1641c552b4be4a0d734f0afd470b9d7f4e45778951e21fc534f200a128b96adb8373f10cecec2dac2996a062fb3c294315965a9d5d7b077c4b013c64a38429769d23eab
+SIG: aef756bfb8a7266e17d15f3f11ee50ed25be420e95a0742271ebd12294e2cb96ead083b8ff0b829d2edeb14da86e402ef25e6d4a5a7958c184ed10c176cb570b
+
+TST: 156
+SK: 6bdbbe06d9f4219eea6403a357b25e561992fae0f0f614561dd86d23de415a43
+PK: ed52dd1cce32d9b485e0940746421d36b9fde6cdf0211545b634044d4b3cb8f1
+MSG: 582ada13d69293e49bbd461032dfea1ca2025b52e013a33a0387fcfc5f7c0b8ec955982607fc901e1b7f636a9d371e1f91fe476bdd44856e275d67efa14238164354c231124c84de8f5b89d5a58ea6744b4d3b3d7906905233cce694a64d696f5a7024fc9033b1ce390899a3b441a48e53c7c9b30ba12e7d61f35f15e658c7cc4407e2f689ea8a55d01bf5dbacb11954754f920f09dbd48409bbb5
+SIG: 950206605b0f417c90843e2c8d8e66c828bb10b99b36eeeee8caf2e0e5484d93fe02bf533405f4bb74a50e5585fa0daef4821f0301d01b46321baa31e1f08d03
+
+TST: 157
+SK: d761c8c5a9601b9145b7d051249b004107e452e563100c6c788038c9ee8adad7
+PK: e6488775d6407efc7b2bca890a7fc62266fc54cdac893343b4f59a196d948898
+MSG: 84ead5eabd2fd4b7c79a9a928ab8ee0a16a5fd667a057f8a254663d56daae156d1a49affb2996137b9d8b340e635732f9d2b4c60218442541e72d2b00e1ee7a73c3f67caa499fa9d070b57d076dcde96b0764723c3c659c7a00c1b78b15ccc2223890b51067fc81e23e9458ab0683ba626a53d0c3793a58a9857bb44b3bd85bb6ce53a85694e7f53cc1bd46d50eda37d81f5381b513d1f38339d291b
+SIG: 7ab78b64e6db359a2dc8302e1092ed66fa736b536253a1cd90fdb8c10efd78300225e191963599ba549cc859209df0ff61cd069b03d254e6e7d76c798440f907
+
+TST: 158
+SK: c5e0c7a7bb8b7ca07bf0a05ea67eff6deebfe3714ee3e1a227f4dc8e242a2fa0
+PK: 5135efcd9052bec57a4431caabe82680eec0a33afd59b30203b280ba12be485c
+MSG: 3770a6786652c4b78a043edce07f3e204d81997c42afc22331f75a5494a826d7cb69ab4314a473721058a1839981d5b7022d0cd8670377daf3320476d25b9f559561d66ee0a709fe17361e2a52898f5753c4fb43bd0c98b368f512adc09cd927c6622676926d8c2d91a14aca32f226f70036c1c858bcffc2b59f54c1c37bf81eb52ecb3f00da602c94361b52a5afddbfd7e05036e377503050333be512
+SIG: 2e7fdeb3484d0a5e8dce94448979496b0642cabc3733a51f8c3c5c51c19ae319018da91091c2385f2f4e9a59edbca2abd0d085ee40d3f0d42061a5a9832a370c
+
+TST: 159
+SK: 11bb4748d2547e6196be823c9be7aa18150c204b12ca8d73c1bd46b11a54b475
+PK: efeb42da28d764966403dd300d9f9451b258ab1c80df06fe5943153f5301cccb
+MSG: f4b765b258ba35b427525c7f10a46f0bccd357ec1ad52a5b139417a9d3894c512d89eb88e681b1f30aac4c115ccf36545e83f37834c82e8300cc1eb289af4375968c29c0ffefb40e156c20c0432669ac8dc0a83c13b1e855a84ad0133c40c82c87ee1e7dd4084d741c80de8a7a9f7759e843a562099c4d7df875352039ff4d3824651386c97759ff7dba52064e6d3112e080819aee8ce723a1a2aa464d8a
+SIG: 44c58da49d2365d27029d1eebb3bebf7c032d858aa07e0756b1c26a5412d22691176031341ad37d7bb7843289eb39db491584c1b2a1da2e4a2649c2293826606
+
+TST: 160
+SK: 7452a00156d794edebff4adb1f7a7eec26217fef67c3d268352b2b5460a7dc25
+PK: 5f4dc338cfbd384b5f1c14c226701446b52b1e3e2a3cba1a40ee2825080d1de6
+MSG: 8c4ee2867656e33f5269414d77b42d8e4750dba93c418bacca10938cc3b570c6603d52c2344488607b2f934f6d269fcb2ad966219b1ab11472f42c672ce20592490ec5baf6a2d2fc8a3ee35374b1902fdefc7870b1b626fa46b12b6cee241f601a9b3fe4c50812e573e6752ce2c7644e3367a6a6b77758d8e4934b58af23abae8fecac25edd734030ee7cf39907e3eed8186a19a807103a9fc49d38f4c8460
+SIG: a8f9fa24a3dea1022e73f0d88b1c37d06d0f0b20bbff0ecdb4a40c86d7e475617c03570a7419d74ba0f1327096bf19f0d0cf9f51d483112f26922378682f4807
+
+TST: 161
+SK: 880ef106733f04e76195eba280b3fadda0f25dcf96a6a99c8ccf842c68afdae5
+PK: 70cee33d41c728ce7b141931e6e8524567d7601eb79f67fdcd07b9d682c650f0
+MSG: f4f38d077f2b03da821bd36fde673d666e52f4832e1c0dcfeef049328acb7bd71ad2bfc49c123516e196c470df0847b3848a45a2c69bea03e2afa7e58205b63b523814fc8e242f059c69ff7e40f97be8125b70a54fdaf35aeafac79114a7b419e6bb9e70bf07adb559819600dc25e51b4b700d27ca5472a0e7cbbfd14e099faa3a72002da538cbe45d621ef0d5252ba29d83f8b3ec8389c9ceb6c6b2e8d8a20f
+SIG: ff6caedd8a468aa07d4c6e7131bbda76182ba958649376e711f44c7bbacba6077bea878ba5949cdeeef05cfd4983b0057d275ea3e18c32659468c30c47ac8f0b
+
+TST: 162
+SK: a2d88f37ecc2b2c05dd6cb3159962c5f646a9815b2fb37791fc7b606e2913ed5
+PK: 58dd67d7a15d4ca0341a4c869566cad8c4ee16e583a10b4824173b08290d92d1
+MSG: d1b87e9e886dfbbdc8ca8ab9010ecf9bbaf23f72ab3cbe769db1d43c2a474a81651c464e9fb92734634641c9485a0239b3110771e7f75e05252e4d8f4c0aa1ba08626d7e96317c20acde2ad99b23bdadfd6f17468eb402ec5eefa57b47caf972b3dd21d89f0e2989ff87d51ed2e2d639c1644e698cbe0221b8e179f3cfb04a20cb2470216a6882fb4ff799e11536cf64219f0c075176bc7cf0f6c5b7925fcd6155
+SIG: ccf2400cd673e1effd20161d7b68a5fb87c1e99d3635d78c2da1b509fac33346c069163a6c46c7826a48bbbd03b05e6e2351fa62bf89bf7ccf9a9024bd157d07
+
+TST: 163
+SK: 42aafd0ae26df1e7aa0276860d752783af97280439bb23eae46e3f84caac78de
+PK: daa2350adb55dba9df7d7af5101998fe515d311c3cba3eeab9138233190c3b4e
+MSG: 72131b80ad599b6f5ff698547d16e7499d71275e4e9b30526a5aac0b0c8b14fa4a540cfb1145fc004418bcd318c1a70e6269a3fb69baed86f363f5b8f97f569c20d4f4990e7bb4d0c39921268d636ed0554bd62acfcacd3b8e030217aafac3044c037e0f94da18c6b9a0932c3c5875d3a93fbdadcf67964eec9ec2be69b48f020f6c9874de5f8a5167b5ee024a2c2efd0cdcd2acd8c1f787814141e30b38b163175b
+SIG: 116143650b6c133d617859db2429c2913579790b2197d7b7b1b4962b328721032ceeca58b2d56439e233bb84dc525e284ff8df2bde1db4986fafd21b3d7d6a0a
+
+TST: 164
+SK: b69c33b11ba67841c3d4e6f9234e35370a28b47662ac560b27c078b66ab1b021
+PK: 9df68e9acf67379261744db5d1e377892f2b692ed5a38b37073c04de5d226737
+MSG: f9ea126d3ab21961aa2433900a3982b83e0ef86d52d13440afa4817f9b822fb582cc3932bf450d4677c9188181fe7526ad6fe5abc61d0ae759f215013c0b2b41064cb6278ba7e39e2f4c10d6cc9605b3869e169d7da42e88eb857870fe6118bb02bc08c8055f0c189b62f79fb146b4c543aa30cc0cd57f037e9ef7a63711f66e6f2878931702202702614277d513f0850b758549336b30cf40ab8bd460e60e12deed04
+SIG: 24368fee5bd848b4c661a3be4f310cfc436e79ec4a78501b81095fe51614231b6ca1ab1269996ad2e98e299781af8e29804b24fe5679ca3ba650c5c4cc58ce01
+
+TST: 165
+SK: 7b63613f6dae01cdcd5e6b37686971cd8d8a99542f6329a12854a9d8ff8105ac
+PK: 72ec43faf34d8730177d1f0743c74c20bf72c2394b8a7d471ffe2a04ab00811c
+MSG: 1816488f1fc83e1ed5911637dd42ba2077657dfe1ae422ad0aee59df9dd56a2763c2dd0ef61a12bb825b0dac1eda5fbb691c5ed58f3fb325050b4563a4042099982fffa5d6ed742d95823da8e1787cf746ef63b3fbb0e88a6c0beae4f7318366936b4917f507336068b194680900a7bf4a6fb69a5c387b97e31bc7f9be53c2a89e3651ce1de41b10e921b206ebf32e5621ef8081616dcd7a2059437efad014bb8e2c8221
+SIG: 76f50b2b9c2ad97bfb9499ee41928ac072da5e8bc71d0212550942332b62e70c8bfe1c722542394688decd917aec8f95353e1d72624b70ebed5d17f6c5497702
+
+TST: 166
+SK: 3558d3a74395bdcba560e2c45a91960cec6cb3edbcd30e722f7f055210f37b51
+PK: 534f43eba403a84f25967c152d93a0175ec8293e6f4375319eadf957401fbbd2
+MSG: be75444f9ce6be1d83af622a8c478d510127db56f1de6eb8a5126522b09fdc6ca0862cec0b8b2aafa31c17a2cc477da533d276a1ae4f8e0759d6afa0b17411b5170b52f20547c72f3e88d48cb456fe625b62feb0f81317edf1ec09ece534b9f500d4e1b1bda2db21982aa95094226ee9f5b0a65da83f91121c96b3b4010ae7826c9e80636cba00f70c3c8a279b01b95294cb850f91709f4376662a580b15ac2981afe9f854
+SIG: b365b5561a13a54517cf90d88b35eb0967d6d58414b8c1547e693159e01378563654c50fb42323f09dd78ffe28056ddfa54febf44891e8a741b6a1687d728605
+
+TST: 167
+SK: a35b92f244063a19bb5e3ed4d699ed2069607116d2bd08113f0d8373613f35b7
+PK: 7ec93601864ee4995a4f7abcd3dfc101e9e7f369e63de1ae68a07aa7f075b329
+MSG: 65cd36dae0168d69974f95f09dd9a59db799f911e1a15b85a00893b8c9a3d48a2f58ac126bfaa0a606c05d94701d273abf7d68817f2c71b1c541795c4f6095e26c9dff803f032f75663fd1698edd97ff3a0e72e1b7c9948b08bacb5f7de502b2fea67ca2fef190d60eae92d15158da444a49d2e9d5a573e8e177e8bbf7e6c49f907136e71d2a66cb07636d48768ff417c8beccf4323181fefb3124e434049ea45dd5019e40b4
+SIG: a23dbe3757e478dbc84d3db3a933b0428cedb6b01b86d8d73f3959878dae6f0588f505cd4d39f2ab4677b64805d629652a22529825c3a91d043749fc71f03706
+
+TST: 168
+SK: 72d4a564ca15499b5e4e75d8ac0f28217d32114a0c649a7c8eaadd0cc78c520b
+PK: c766bd73837c4faa5215502f1efc90c003f711bbef55170091028a34493408a9
+MSG: 6c7e7b62eb244a45d78436e2970dcd6c0f7db82297a86140ea58dd22c2195adbc956d4c4ec05354b21efe24cfcfe10e17622368848180d2c4680cc215e8ceea6cce222161f1e092239253b9746f7887df2425ab5a880bdba98153be786dc838cbeca016b1d06524bd6bfba809a8bb37adab15d42415f86ec0358365ea87b8150b05441d9d49846871485caae6de359736c27189736d8f1765f3e5c5f6b92168396390bee94cfbd
+SIG: 8fc4f179330b642dd86ca9362651b83b006d8375ccef811d3c6706f91594651df2769953723046ccb9bfe66a667e0d11fc3ea2d8226234fdd5164765260f7b05
+
+TST: 169
+SK: 2e5aaab298e66c2dc1d77ea7421ff895255f9d900db0450d63f9f79c1a7013cf
+PK: 0381f3f19045719b9e8ceb562f0e965dc07b09f371a963a281c749c2532f654a
+MSG: 3df0e54c711e3132d7ae953deb7b66869ee531ee40b63ce693206cdb2f4bda0a2569e913ac3e6532c5d9648efd4627780fb8a31d107e033f054d19ed8b7c49dc407d2e949de25f99307221d35843f6d5eb7de5cdf41b91dbbf34cb6c9c530021014b56abc44ac2300313615608a7b4a235e99c14cef8050887032209488b9eaeaa82c09405fc75bec94dd42d6ff1b599a63ee5742f3364093ac92cabab3035822aa867ae56dcc99d
+SIG: 7c7430305b361a9e35b2780c4d4408071b2130931d39830ec8d313aafbc83a65dae19cb747d9d1c4ce3f359cc824ea8c92f66a42b8614e7848b884ac8aa4ae02
+
+TST: 170
+SK: b636a02448003543db864b40b5d8d6dd9ad611624c9b0fc6890c51ea5592c790
+PK: 1ef360495968e56e6d3fe740b1c84c4e4490ed682deb4305afd596efb280223b
+MSG: 4aa85aac25034f614ed44f7adcdbeeec25fcc2a9eea32ab6a8699506f7a1cad3bc892e9dce934e75b0a8cd14642b778599286cfd8f50a9e4f2edf9f9d6291a2e2979cf1806b93ed8c9a78fae199b2854a03ec406ab3f720835ee263fbbc91cb4ef0758d775fc784c7d5b251ac8937919a9e67be88c9e44cf2ec7f560269aa0f1113d91b84401db15a3c48c7dacff4939ee01babb982fb95625c6c3ad78749060551bfde8cce4fb8a29
+SIG: d4ba80300d5cb51353c03f28c44fd0a424ffe1e40d78ed7bb1133e8fe4e187505293b20a391da962c6a8ac0acec9c67226af3b6195dabe39b3662294da3e0e09
+
+TST: 171
+SK: 5ca0543c71f568a00eedf50a9520f4c15b526e3fb0da816c29ea3d50b2f62a12
+PK: d4a2933ce19454e331b5280100209a6ce8e569f993c2acab51dbe864c5cb2563
+MSG: 4ef8496978d28c10abd54a26356ee55921ceb350dd4b742c4161fbeba8a1601f8ad0484b21a8cf5a294fac00ec8a6f59e3362e47bfae1e28a2e6d017c5caa75fb0f48482808037ca21476954d778ff1a0586da3ef69d6cef6d2d8df4ae7a85442a1e46c998cf407a6ad4c5463a43c248f3b6937fdbc845b60c6d85e0563cc16ba9675d364f525f669aaac95f428bb58205099f9e4a6dbbd0151fb65babe123e5393ad64026935cb488aa
+SIG: 436823eeff3edce5d8587d68e5473ef3d8dc9465b558b6e8e7cd3137eccc80b4c4e806edf13619d8e717e69f48d7061b68de02c8209be1f7ac26ba8edf606d02
+
+TST: 172
+SK: 5f87117da9bbb6091c94da6b230b7d8f6de0ed2a076413b92eacdc43abbc6897
+PK: aa786a146226832aa73c434b0edc2d41d2558f820ab8f87e09e6cda91072b9b6
+MSG: 2297c40a2e8365bae4c5f0630c50b13bdd9ad9770a5d9a9451d00874b023d25ecd468b96571b2f16dcb1b0d3d756c1f044fcddd1c51f27727a0369c9cf25bd6aa59551b5b07cf8f807d92b159198639704740fe6eda0f26dba7e75d4530b2800f03fb6aa677d84df75d68d4fbb64ad21001e3fc87b609b9c251e8ccb12bbca927447e2054e07688eb8a20521a52249e7b943bed60e6a93c01e3eb621f0460c18a690b6f6b66edc6e8743a6
+SIG: 0f19e6ea0c05f38185c01c2d6477995daf5065ba9d80173fa6bb23a774dc88b3aae879d8a62471d2d304cc3dc66278a7abcb0bb0771cd278e11e7b932e9f9b0f
+
+TST: 173
+SK: b53a644c92ba2dc7108b16833f09ad5917846437225a773d32d79c97733c0a58
+PK: 515818c69c0e0a1706b04143842f3e9e271448fbaf3a899119c32f42566ffd33
+MSG: 13036daaee45fcfde0c53e06d05aa9c01ea94a67e86c6c538ccb283b368daf7078d3fbab580c76ecf82b4e9660f068dcbb500b80595017c5be3c448fbd8a17d97c5643197890e167b35345bf65e75b82c8d65229f2f60aae2772581bc99c49d416bc3d78746ef830f1af944f4a6715ab4ffb01591bac2857f1a9c9d1700888780006a31607338f7af7bedf6efe0b57299ac915526fe5e1e101298708c6e61b84220afe95b53f895987456152
+SIG: 13d2cbac7976ad27f0bf669ad588efb2c91bab8507d57fb16bfea9caff2b0964e75625c4d808d7bbb78c5b464edffe4949ecfbc8b95ff6fdb1bdca2742068100
+
+TST: 174
+SK: d27c9eafcf88151990bb5b2fa8443e709b5fd8d78d233803322dc86d93d93295
+PK: 08e0eff529776714686196d817fdf71eb5b6e8326516ef489bfe186ac5c5bf6d
+MSG: 77c35bda32a5967d8b302fa7a47583ceab89c9a609a667b753155fa6996f8631d0ebedfe0ac364c77e85ba37311f0de57a0dc2c1e9e400d58b424a322e1d5771e0a9fd9502ad0232ce544f07d8c66e7c3147f8607ac6189bb69066f2fad631185f457f467eba33228ecc40e894a77b571698a9bfac841a54eac5219da99c6a9125c469a22fe81f3b951433896f19ce39b373fd7e5c7b650a5ef2365ae7510b0da5e49d7c07073cf166a98387e8
+SIG: c254e371445633137442eefe40ad4a82e69b1ebf48a685a2bc6ffbac126d228487b2e3537c97ef7410342091962e50c0cb85de7b39ceb41ac4078d40f3407106
+
+TST: 175
+SK: 70213d3a79c65d6dbba542a3679635003a682af5fa58de6b0d65bfa24184901c
+PK: 4402fb92cc1249dd1ae1690f03b3ec4f1e9bdab0de5bfd289f10296830fd403e
+MSG: cd6e1cd9c90f566de043d75d7244ecfdb38e8bde2f9a6cd5a4fdac72b5ede6af62d981918c5e610a38789274fa10e527f85fad209b76ca1c281ad5890f9c96d35de522f1ddccb539b8798a0067acdd45b6e344a5d9a97731f545ffa4b17b875c67b48e9d4c4ba72c98a4505583fdbf1e12f22b5a7a494746cc9b6c1b571906c67fcc883a9c15a3806875b659e5816b4276c3190e25cc1ac3de47bf99c49965388f54f3ef8eb569906c6008e5fbbd
+SIG: 5b6ce2774d400ecea8a808f5fd0a797ffc6116752376cd7bfa3b2cca3a84d5593f5c03ad3eec1d89532275c47b7ce2a0e9c59cc4028a8a65e5bb9097ea71c208
+
+TST: 176
+SK: 5d540b3b14f0c0175c047eaf026c9070659ef13e9d28e0c5c516a428269b14eb
+PK: 1d2d4d551a57c6fb2b04181049d4039d575cf80c0bc6ec7033067f27309344de
+MSG: e4c9e8706898cad4ac68d73c130efa04a54f8ca25919ea6bfaa54c8c720ced854c5e9509102c7b885aeddffbd1b7f2c5922583677ac9eea9a108c7e83e8871aed5a084f5440b0f391ad7ffc6bab4574af1b96770f4370e8e988e85ecb1a8d6034fc3d7f49f7422023b9dab5d0c16beab5f5d37b0a4d7de197ad87cd4ff8ce78eb12e1daf739d8b47ab380abe9093356db5b59717751a49e1948472fdacc259ffffc8c1dbae592607d4ec71cc6a8f6b
+SIG: 32527da755312889935dd5ee91b1bb117a5d377dd23ef5b7e15baffae9a54391a3fd234bdce073e098c58d05bf195b4c3cc63972383ba4b51072971aebcb620d
+
+TST: 177
+SK: ca41769caf1717b4e45c93c121dc82a534fbc6ec0986662c3222d71492bd1176
+PK: af3f89f6187dbcf9217750c67ef89ed47b039f9eb062ffec9df64ab52b0b45cb
+MSG: 9de8476c5813848ab1451537841cc178002181a2182af305b12e5f7c3b1d56b22cf46ae6276d1826ec0a8c9a7d9f68083b7225bbfaefce82b3b64594052a7700f309233a79fffdfccc5c21400c91cc0e418d5141d486b5219901d6dd2447c1f7b7cf5a0879e70e1dd658d0f2ecf31ebeee11a5c74440c63b9d8b45318c3465d7ff03365edd0385edf80d4fded51f0f7533ee4099f19e93bc9d08dadcd13485db239522ffc81e2c051f8796d62e979fcf
+SIG: 5cda872f7ed6d7c90218ac10bee8e214f3b34d15d25c39255ec9e6b0177aa3cb7368d11cb8ed6ff5cf0c04281d06bc4272b8bc09c23f6f4cd5a810ddc7b9c103
+
+TST: 178
+SK: fedd63ffd4cfbf618894962e121a9025eea318a80a1adf169d6490445d2e02a0
+PK: 542f2244bdb7d84b87e628a8e6a12f17bf74a9a6d0ea46c595dbfdc680c04b26
+MSG: 2e2ae584641be03dd48f9c618077aeaa18212a4241f0c0194ed23e370d741a3ae11a5fec3b040c16eafa4ac8d18abaa7ce8f286967337189f0495ffdd61995cde31dd8dfc3df5700b57a7a29980e9c823fee85d61451176729e72787c6109b47359b93dfd62e1e5a2d642c057242dae500a94ca1a93bc57be1ade76fe4501c0f6377ed0e9246179aecdd9946b671e8190e1ed23f966e96409b948222d8ea5839de904fc51348073b8f40edbd9b4a4b2275
+SIG: ed59d9e23dec3494b0fbc5d10cd02bab86b3eb35abbf9e4d4a926479f134583a44ce72dc4122aca377a4072b7156462b74e8df46b686698636836ef203179c07
+
+TST: 179
+SK: 38f2184eaa553656ee2902706bcec4acb5af25157ca0f6a2d48de85285fa3bc0
+PK: 7ff03fb4c82e9c15d659df424b3e73ed1d78006f3e0b79eb64d98c13aec6ba37
+MSG: c2df77c9e479f61983b6c7483ef93fb85a103b213923926523065ebff2257e85427e05cdc27582ef6c16be353a3b250372d6370eecb6c8962917eb656f2641690189d172a111051557abc2494e32cab65ed0633affe92408b55c4ed8af65e2c5e7aab887a3cc8d28c52e9e1336d0b7bb3fe2cd843e7fa1680342f8a4aafa02c4ab252f08c3d46d5f00fd01484263ee635284f6db26d6298de5b0dd238da40a8d2a93376da0302783a0e3be23d9e7f990d25b
+SIG: 4a6413c2c87f2b3856a8decbce493adeae0c69c94134707fb0f18f3049fd3e3d051abdb9d4bee253c6107c02d57ad7cc9f3101db660afac2b7981938e9564f01
+
+TST: 180
+SK: 8bfca48462d2536f74b84f6af59f5d8582ff8f7ec28745d672e72eb72e79d3e9
+PK: 9d10d275c3d3fe459f7fe2901bce389191cc8483c0f51140d9c62b08fade81bb
+MSG: 81ee4cb9c45da691dacd7dd09aff59737267bb55c3ade1ba32c17b7d0d2d0c6079c39d5fd5b29ba5f9c1762097709843eee5612bd20bc8185bf64d5c934184e13624e6f877a2a5dda15c0df62afbb97057cc91cac9a18406a0e0109cc39b2e3f812e227a4062d5ef81c92c22a7dc797c845d71eb6ea9e42ec8417fba90a96d2bb1439418330b4bb2f99c6d63d304a0e506dca9653e5de0dd56e309db1a76a0faabab163774f000088cef3d1b7a6cf661d2e1d9
+SIG: 44d77e439ef6ca5eb940c60ff8732ddc16269ea023bb2613bd447eba7fd69851226c4819ce8d44985a49f3f41ac7af33c47ffe5f89304a3256e445f8d686e307
+
+TST: 181
+SK: d7480d4272bcb1557b1bbee04915c126a52ca6d6a8bb5314a0e1a52b59bfc99c
+PK: 99c839d36d8f5b8652618ed7b0fe9ec3d94efff4c453c540631476a5979bbbe0
+MSG: 615cc19f942017365ba8bfa256ceccc85ee289a1c34bb1442acc0716c7fc2caeb76a9de19adec106371e47a30d2e1239ce1f7dca25526d604bdd647659d942bcbac368911349c3b946a97da10a42dbcf3c73416d2e6ba22bd29d9f705672e9e338944cef01ad21f009742e07bcd888ca31e1ee953e8c1b1fd954b7dcf1a0b1d5a069065a66cb721adc020f4efe1abdd16742746939285780d753137ae0140bb410fb6ce33676c27aeec593a88cbc73afd9f40511
+SIG: e04dc8442d352173e931818e290858de85688a4649ea3e3c3ae74edaa54ad01b64622ad8a090b6ad60adfd01881882828d39078bb5b2714fd3ea8397a342fd04
+
+TST: 182
+SK: 3c2d3650735b41ef9006bb45e4be2e0aa5cde851aeac421ee9c1b492d87aa18a
+PK: 3e46ddce298844fcafa00a1b47eaf3de70596df1bbee3c809d1be7dd94080e34
+MSG: 1425d8d218da1a10a80b6a9c3c2750efe41657984abd5100f451ba949db01046b7126be8402334ed57528bac05622553a86b726722695a8fb331d8565417c4ff0f251a320ad06dedbb750def35d521c3c4cd571a45ada8450653d5e81fe0beb53aaae787b3eb653c2381ed55aaf2590ee5ed8b6626f1c4b0430a54f39658624e6635fefc98fee8fc3e1cc7ff3dd420de9da11a62fcae0e0cb454fc6f7df03954291d26202f1b188b657b3bae07389449b75e67422f
+SIG: 3f2af01ad5377ac39040d41a41e36e7b93fa7235b841791f432ecd7f91a3b21ab7196c883ad5a7db446f6c06672460f3f63ef863d9432be9caeabb79e87e2208
+
+TST: 183
+SK: 74965996268cdc4c09220bd31ce07b217a03826ee981fa89f3a2359ced095ef1
+PK: 4096d027c1c5ee4cbfc04b9d534174029fdb50cf5610d3021ef933b4caf33985
+MSG: 45b2f064615bf774fce97f51c464685d7b3e4fefff9231240a719b3b0621cd4ad83305675cd6eaaebff791000b0b1fa31d82d8181b7fe57c5e00cec56ff9022e9ce8db66356e408e3ee262fe627789e65535ef1a63e8fec933be3dee34d2facdb8928cc456abf2f3e8cab47eff1ca42e8b0e48d2c73e7bcc5de3f1056fc523dfef6b0023f32889ed394eeda032abf6bcaadaa7f3ee74118760ab6d91df528bdc5807972c85fa7cb56e387d7332e779e52d0dd7db0cfb
+SIG: 8c6628344317a63aca6f78cfaea965b3aa5522ce914195141c08870a1b8dacf34b79c7abc693cd9e5ebe1a2e86f0332d2048db3cbdef01687962d6df249e3800
+
+TST: 184
+SK: 0abf069c08b2691c3a26f79dc8ed05cb71d220ff78f3a5c5780ae9da18e45643
+PK: 9ef3b5cc016cc82dbdda705766aa448bd61fa1aaf1170efe9149daa9fe64a1ae
+MSG: 0d055291b2e861eae19ea0fb2069d8c9eef4f1347f3576d78411ae7c0b1c1caf31fde736dc8accacb662df76b620b62ce90b9f92c83309128621d057cf845805949088e938ddbc3d41c5e5541fec8298687ad2f79acda01aa215d25821436eac9d268716d4cd6050260cb4ef6aada4835e073a845821ff211ae2baadceb6e57f06f88345edbf93bfdf54fb74123b57c0fb4a79608d8db6740889e15733507799f7a1fd3017bcd77b28a2bb6c91ecd154e9c5a5ffa0eb62
+SIG: c7566fb3b4d8def667e040f276d3ed98d36dff460126a75b4cc2100386bb01c642f6d8de7e649be6e0818b08d77ce60f4ee5e7717a50884bdee02034ecf1cd0c
+
+TST: 185
+SK: f3fd5ec5e230b6dad1ac3d3aebadc7863ff89de2a1317f424d15989a3efb0afd
+PK: f99e5d5eeeaed1205cfb5c2cc4e5e9f6b4e7f64129f860104ca6244eb9feb564
+MSG: 71f28973ed3df05945fa0bdb23e9beca651d3ee6bf9fa45ffdc6061e42fa2e8d76235f0e9e2daa65e52631fc3bead33da055bb492e4758e598a030a33b3c40b34371459b233ccc043cccc3a3cbce549e20e0b2b43305b64aec661aadba6556b17d76e3bbed62c4a4eac4f88603996752d2363c8d4a2789d128f6e959945c68c30146d194ccb6839ec65344601652c18b0074e2bc7668311697d960c7066597924d704d02a0193fafbfdf571ee0dfe414dc2f52896912bc32
+SIG: 44b0124663adb0c73aed49f73403461fcb19111b0ba17aa996566f477e37d524b0e1f107612fc52a7c767b181fbf4d629bddc08f30584dec6124c5d39d423102
+
+TST: 186
+SK: 738f1310a4e08f917a0a5c1fbaf4ef72f95ee62fcded50868a3daf98856a448d
+PK: 42272c2c8b08470ee5dd8af8849c01b7508d3a3c65b0330e695c841d5dccb2f5
+MSG: f0e7ef6782d04c6943b19eb66ff6226b736e3b0940c09bb126bfc4c4ca7a5e7016c286b7bfd73aa6a79a96031bc81cb5da68cec71a6a0d39780cbe6a0cd4774d3aa06a881610444a8c9d19102294e5f635187aa6f48d11912c7094b38833028d570cb110db60625bb1bdc37affa25ea3c8f8dbfc2514f4365c62b2989a66d27c80384e74ae5fba8c1c2af9c72c4971e64fa6a1dc2517b31ea57ccb0815a7fe2da0f146caa08431d25d151662d9d26e95229d0c62823664123c
+SIG: ce1e3577b6a21016b9dd0b517baa0ccb107bc199b8bbaef68f950c8ed58013c853b4d338eedc675079ab1390462ffefa6a959b043f8b5651c6ca375ce0b4a403
+
+TST: 187
+SK: 8841d22aded69c131ef5ee0a10ab0a9b77cb754ede8d257a5372726e2b499c6e
+PK: 715ecca63681bc6e9e31d18848902f4d96feaf43b95d008642903b1763bc9fb8
+MSG: 087ca6be2a950c024b3e7467fe00a7d364555d5dc6770f5ebd260642525bd3c0f965db36d7b229a57421eec64e4d991cdde59123034470553f4eb0be81ad2936c8ca26bcab4e5d79040e29798728601684a468323cf3baae4d948d0a1fd905effe16dc44642088df53f6388bc480edf4aa207d0ed161eda345712b4c00cb05fcf635ec2588785bfb8a27cdc28996a1db3e6787023393c075d83c9038fed7899c55fec307de3249c14bda49e8b895860942c36d640bb893779142
+SIG: bb2bab7003f1311be9b8c883fc4fd528adfd51a9c99db3dca8da0fca958da19a10eb22332667b1a0065d3dbc0d06269a1259b6a890484aa2143a52695f145b0a
+
+TST: 188
+SK: c02135e7b65aac72f63c32bf5bef5b68c7f3b8ed56208e59e4752070e9d07095
+PK: dcf600f244037a75203ae11ac316e8dbe9986f0dce23473939334bf5cea48b0d
+MSG: 86d9491350d2566e708ed356185d610c73465b2a5c7012919958af2cf76af995230d360de400b7137170dd0835f10fcbec224ee4e42c7d1cebb7f580fea8ed6223163bacdd1923a572cbb6dc26ca8b17ade68c6d2808c4ca1eca28eae9a145f68d4079d8d59d140e958228e7e99520e342dbd7457a9159740f48bdc27b93bdabeba465cbf0c8df5ef2c0f9386eebe656f5d749d5f9147f525266910d7b80396a90be5cc188a9a945f93e753fc99bafa18ee0a6dff79bf8484898ef
+SIG: dd5cbae479eb5e229574c21ec3bed911113a57a1916d3313457515d55cc5b6e6ebc52c93f821d13988dbba8df5096d55ff9c39e7f9d561cb58930c96a7a5d60b
+
+TST: 189
+SK: 154a47eba1b8c38362ea61faeb0c0ad7e61e412a3cba4688af0db2a487208b1c
+PK: 16de2c894a50cbd4ca90419a4ca64942cb14bd335c5d3f4a53e239c280bda725
+MSG: bf607e8b6e14d9c8acd96815af0c035ac73c4104c93786ccc1c9f859395dd781900320ebf356aa991cdc9f503fcee9f83675888a7d592002d2a54a573a96994b3fa865538c617ed8ad1ff62018288a674f449be0aab5222f74c4fd475ed6a8dfb27f45287b22b2b6c3bd15179f267d157d7d8a4159679be85b25c2bb2ba850aaed9ae3ae571be4f75836329cf36f412c1c80f1413b7661eab4a8e11b6024244fc62323ff02e38aceb1737bd474bf1e98015dbc788b027bbe217cf4e7
+SIG: f4b6eb1a8d950e887fd2f30f70a23b41871495bfa5b8a4ad3996cd9bf51eb742e07f4c4d2da4b01ab087367a50e2b65b3cef514e40d837540b8c89966485910f
+
+TST: 190
+SK: d3028431ce2eef73bd940ab84ca29f13fb26436aa25e1b7bf26cb33f17fdf817
+PK: 63df203e2860bac4d352e722c1c91fe3776e1cbcae8553a4f19890260bf0e457
+MSG: 086335d61275d168eaac0540477f50d4b15f9e50b9be693921ed54a9941bc40643cda62e1d805d0250a81146bd5fe2d39e81444d21e2b21b031c111306cacbf52717f6fb4cd3416f1215f8dddcedd2f0096b0fcfa0a6cc2cde7a2bab7f1e32790b5361df3671424cc722f231bf71895bcdcb7b22ee074e8fb4a9678504e735366c172f07637b7a93149bb21f38883378a1db273fc23239e35337f9ce566d8ddf3b3133cad7f2ce81edb503ce1d27c5a657160b78dca9aeaea379be9c85
+SIG: ce9729a96c3ed28943b27839c73382ecd572960c1f9e90c5eff9dd499ff48f17d25edd1268effe41ee6a81ce48d84de513df9c41442621b2f5491e346be18c04
+
+TST: 191
+SK: ee8985dc27504440a8758d4c53e4225215797a00cd8631d59bd93bc66f373d5e
+PK: cd647bb065693d486589156a9fa261437534dc86f46f72d0a800399a7af010f7
+MSG: f2220485addfebce02a833aca33381d1df917ed609950ed24f85e3b02b2b994b4d939784e332f41064c8b4a2630ab36961742aa1cffdcb08c144eeaedeafd48b5dbe96bf24350e14fd68286bc08eeaef8bc6ad9e195d1484afcd30afa8ced4848126d56c81b43c27a5dbbdec1a50c11062ce21c61d860c25a862fbb75c3bd51c8dc07636668669bbf751eacaccb3b51d2c0d4140316cfce2eb18d2908cecd5a188679bc5f5de290f548e7ebc57d41b589a24ce88ee48d97e8d0c7c769960
+SIG: 5bd60ad5e9bad9932ca9c75f231a76889ae7a8b864b91d1fcba5c5d4bfa1d92838adb974842a0710779b3e3094044909e92c7cf046ce519f4c68e8f19ec03c02
+
+TST: 192
+SK: 80dfe2bf7387bad4654eb076f8dae9595163e40127f5df492dad7df04c7221c4
+PK: d1783ceeb9cf8e4d07764c473fa4061b8274397103f2076d703249d758b8fbd5
+MSG: aa09d784bb09dc999931ebb4c00e424cefeca104818d8eaf0661f09728ad025ef47393210571f17404e9aa6d8cbd5fd88cd7dfb8e2e8a108c05de206f3408234a3b463dbe71a07d05587324524b7326ee79d3348ddbed7871b86fcb488031dc9ea93f6b8d7fda6239348a562444faf1e72d31af35443e9df53e762f3e56b48668f9784b3368ab278a48ef4546a26cfad0d0a5161698f26ee8d34fc2b3d6dfb93b009ac296f6afe487ee335eac9f02cfcae5fcbd1a16ba4e71be1b112562fc2
+SIG: 27279e3cdcb03ef557a5defc2f6c58128a6dc3f8b0385958014e709c1f61b0ae6b403576f0e454d5e4c64c173138ee4bbd5fe7b60d06c5abe23fe99ee3b46a00
+
+TST: 193
+SK: da1f868542cd7cce7a5ca3fa3c24081b4d2344b21a157f0264a347132d19659d
+PK: cb3a25a53f272ea813804468d6500e96a1eaf822705b7790a8ac3e98cc4e524b
+MSG: c6987ef380d5d0e74196443aaa3a32356cbc02636c5a4b6d62a8114b2111bc1abddd9e44b3672c18b58d4ef591af4562e020049f8e1274688e1f8e5296d2f9252e7fc84cd1d0c58e98f0f160530aa22c871eef652e71974ce91b4a65fc25fd09fa1b6c32086e98ec708d9abcb1d9cc8e1a089ed8db2206ee9570236ad69b3de6821862fd2c70cd83a32a68b0486229553d928de48d03a104e87381964abea76683976d527c84163a12eee0a55986cf1431e9c86cba8182ca94689bacd165fbce
+SIG: 75c517ade4f08d7746305743d1a776c3c55eb5eedfdfcb5eb1d5634a1bdaf7a4b8d24187d6c8850e3ced6567a03c4c59389a4cf47114ce5473160f230546e60d
+
+TST: 194
+SK: f13daec0ef33ddd133c7d244d10fd27ddb23705280ff5f1815f0f656d836fe84
+PK: 2dc7f1367de672c51e005c74f876f982593996873acba079292734c209c2b111
+MSG: ec02ff1804b2b309af3158b66272a14a3aad83c41a719846f7088ca9792af575c78913c432759f0b9a748bdc5568496e41658cc1cdb8da6c91d07c3ec2f4af504249b996aa00c0071cdfa793f82d0ec5d267262f518fc029b88e20b6201fb9e05abd3f9524c5da2fa8978ff2efd48120cf00822d1bee90df816125d8edc0cfb5de66d16be63896a412a62b031b7118ac13fe2c9faa6b1a3342f9ccf7884166cf489a84de26b5ce5b21856a3af289bc6622c0aab9f2142d393f5d4b236779dbb066
+SIG: db771833f7fdbacdab2b5cc80eed50afdf13783b7fe5e903d5dbb4c2e535316a6eef4c34f004d2b9a4e2700bd6e2acdd564c3c80cc68a303f5fb091cb4340f0a
+
+TST: 195
+SK: 42dc16c57fb6f128945fa101e05bbf548ef7d97726b692fe404069cc57ccefa0
+PK: 0a1ba5df523996f954b34ddcfabad3f3dee21a5fa7a4ce322d216bd8ccaf438c
+MSG: f2714c23a3a6fc11ad15c980b7350fc84217877661188055ff750d82c49c5fef7bc8e6aac574a1b79a3f26d16969c0f406eeab3e9e12850a55709745e30dffa62a69dfb2b64b3c1bd2bc3586e26d4eea714d2a7b71cf79fb8ffbf2aaad00ca3e4f2b6f503cc1fef2eab3656fb44f8d62a8db8ab58f394693949eea57fafecf005f6ebf1287dba4d2d623c02ea171f567e526add20709ebcab962f83d98ef668ebd01ef20488b3665e3a446fbfb13d34050942c749bb2dffc766367fd452e68e5b0c6
+SIG: c75977e83bcfe9df7292a860ed972555b5c24416fd4b7ee3285388fa5b1447608e4a347813cfe093512a7651e422e9867db7b97c0b0867f0b8c7b7f4f02c310d
+
+TST: 196
+SK: 90b455c6bb9cec83e137357065339d030525d0ea7f5b923a2d5972c3c12aa37b
+PK: 5cef038c16bfa4b4c923a0fe70cd7f25c8bc837fdf5a7efb9d95f21b96be925a
+MSG: c62cfdb9d21eee6be47f30727aaee51f0703789a431d32228533350217a93a18900669c95956f3f2ae90dc745a71e18340d058d16b4c6fe33b64af8dad973fe5dc02e8520705c7a8bb3ccbe1838c6c249337f9b6a4c0e1f8a4e5d103196fa79998923d0422e9d079a72cc2a8f86d659031a607d4cca0b947b3abeeeef64c28da420d05de665a5510fe55f77598ecad7faa0ac284800b53829394c4ae90be66678ff04ab46da265ae06402d8c83cad84d61a051de0260559888e779f74b72a5d71c132f
+SIG: c9345eec2c4a0aec732386494a69a3fce8b8a1be366bbed1659f131fe97cc037fb1b7c1b68b0f3023945d20090a0cd2c1553a47faec4d66fd816ce121168f309
+
+TST: 197
+SK: dc185c2ba0b378dfe5dda510c32feff535ca2e8a02434b326e0158bc878e8848
+PK: 33d6cc05a434e419280d5864a1af209a2c676814b70f72f8141ac7e0573ee63e
+MSG: e276b11912cca5a84bba650c172aef3a4d5f91ac722913bb891a3ab0424ab07ea709cb8bba3a3d11f82f51c2af0162a82f7219ce27b35a30507d536a930817e40f85a22a5a432b94d192c3c8911777cfdb7fe937a67502770d6d75753d3ae88229e08f1ed23b4328d862ac61863c063ea9848f8ab96a0213d7b936c48fe754836c98487859d199b3d940392716a1d569e6c0cb1ba918932cf88525e256c8abb11aaf0b454655d5db55713cebba287ae202651ac872bfc80feaa7e00d47c0be38e658f7c5
+SIG: f1e44514d2ecbcc8d1a7e84bf584ce731835e9894f88974f098d456b60718f575ef4d8062f2182504250cf83bb2af2a79b1f58a6a97bd98da467132d7bec2f05
+
+TST: 198
+SK: 90721c43bc366f24bf4e8c993e138024682f1029dba35abeb0d60c7fa710021c
+PK: 7c63a2f13b7b220a0bb752e3800753b8b6b32669378ce131bb77a9a8d230e9ae
+MSG: 651c9617cac958c7edd4a5f3fedfb83dc971abfbb69a31e898cca8472ef068034a6d2376ee0e72d0a9bfee275796c3795adac8ebe1d12b66ec268f6b75fa3941154f99e223faf2cbab5b92e2b3ba7b79be7700ef9dba69253cce5356b0c4e74703cfcafdb5546850b46232675c90c02d5e426d33d60cebf0c7930182379dbb007f536163c8ddbbd3157bb2da62340133f00ae2682ec6baa6416b5a01521cc10e04695295f2e5b94c05f00383ffe954830797f6df823172532f98165fe314ab325929af8385
+SIG: d2064a6d6c99c6c3f152d2d435f24e34b5459b082ef11e944a77ff54ddf9862737ecb2ac8d54207d36c51ad41f36490a111ba80e126bfecb09def6accbdf880e
+
+TST: 199
+SK: 9cec246758e412e7378b4579eafe9fac5a25d5405f9270b5d7e543414ec3d5da
+PK: 975a9e6a152caebb2f9dd0deb76dd922b6dc77055dda03fbae9e7c685d073aa1
+MSG: 17ec9bd47add6ccfbd787af0d9013e9cc979aaf850e09426d3b28edfd71296eb31ff8b21c5fe7be050f536324c3ec48850e0b508a36bb4cb7e754b327183a1b394d88a7941d1ce8dac62a5d8291874d78485e51f29ed05865a206e52ecb12c5d107d4ff96f25d3c5d181d2c4ba6463600db1cca32857fcf597cbdfb2fda2708a8aba281b43c3d28c4a4e7983361509f61a1074e6f0ad6101c7b567ee4078e9839c47f46531b729ff0efeef7c9d1a8d833d9c0f42812a34187c3a778c165c09d6459c9c7ceaa2
+SIG: 9bad1e3b1279ef658f4d071644c63ae2b7a780357e9dc426f1650ec0634dfc520f8eda9dc8f10aa7324c5942d2347ff8802bd90e95fcec313352cdae64f32a04
+
+TST: 200
+SK: d1403f63202e080525843bde255eeb6b6783c1caae9d6ed00ba60805bed1941f
+PK: 238aea3ad6d6f27783e70516bbfcca4770366b50ed0fe6a4e966b53af121a721
+MSG: c4f17d442fba4ca0df8dc1d0628d7d7f36b60b5758d7c13b80b8f97a62124d96a23b279565495a8accab5997115b13a4ba220a73957eb7930520acbbfb6f54cf68726b6450c6ffa9470b055ea262914e2bc612633f1ac3d0618a23dff188a733d76bcbcc460f52ab61e19938f9c8caaa792c208d1f6c754728905fda51d881a347a53da744d3baadc0a76c474c558680269095f9084a74471d5c09ffc29141b5bfaf4954dfacbca663d037b17ebf9559882233e5ca5a8bf75cca4fc9c5a4109f32e145f3853b17
+SIG: 8e60e73c063816795e29f5d64ece1159f1b5d5021a6f8f655e261a4d0026f5b94ff2923250499d995298480512e4126276aa4a226d015a95827b3ce692e23302
+
+TST: 201
+SK: bdf6bdc31ab0b5313784483abeca6ea5e9cdc68f81b21f350d09c3907bb9b6a1
+PK: 03627712b755e5069fb9ab8f9e899724029a7f268af9398821eeec9360c9285b
+MSG: 90a66aafa5642a98e79f0d88147080167b11e4466518f195cddd8940d12ee4918d31a6d4cb77d0bf5af29983bbe5085610a79daf0c75a78ccbcffbbdab2189c394ae24e265bd8c55fd3f4098e1b175577549518e7a4dcf7452086dd1278dd58ea4c0aa690e917951ef39fcff60cbfa1e90910bab5374928d4722f702bf5ad6028ffda6541fa5ba1a3779ec78b0a95fe3850c748b6c8f42f330ec79541a52a1cf57db72df4f92ce7f748aeef1af33bc5ae0a82c89dff216f23aec168a7dbb510aa632daabcc971b3f
+SIG: 38fac603ed246f833f1c0fd4585698b0a71305eff0d14a0049b3cef073bd036dd451b3dabadaaeaea2aeaf83d395746f4e86866ada971cbe482edb0419332f0e
+
+TST: 202
+SK: 57b3b14ace1cd0cd603e6328bd219ee7d9d094487fa668f28aeec02b43c909a7
+PK: 24e6b6395f97ea0e237186d469b71923d2113adf403beeeb4a2d27909aaf3eda
+MSG: b2e0dedd802eed996dbd5836bf8688b0d1201bf5442ff9bbd351aeefe1a0c21fea2b5c9fe5edee47e921099b05aedaa80367c1ce08821d783a5b64cf059c0f4335083986a5a6ecff8c84fd40e0ba5dd5e5d2f01112a84ce5cf8e0db78beb182d9139c0b0f3e0060a3fa73869e96423f170df9af1cb9c35566d87dff542223f6d439bdb54729d366aff637b0f36a5d14b15d612bd03076cc4d04c1f25b3ba84e0d1fe474e5718d1a17d5a488465662ee4c3f664b4c9274b649d78cea4e85243f3713239048a908ce3e1
+SIG: fc79fdc6d090887a61e43c6b9187b657d2e4d9cbafd6e7caeb7ebdea842825b78fb949d2c49a0cf38b6c73296d82c8ddeb1fe2d40aaddd7964da68acf8c66f0e
+
+TST: 203
+SK: 018a2c3deea50ab506751f9c2adaadfd9e2192121609931684eb265e193e7f89
+PK: af410bdddefc644ef12c9899ff71b9e1d0dfa3d69d8c2cd676c1916b34591cfd
+MSG: cf7813efac12ad1c7c7322ccbe54aa0e9a8ba4fd4345b06e4ce7a35c8b1cd5e3f7f0688533849ba2cf4c75b6f20926a1194a72df0e1b1b34456a2133112d006722fe811d5e40c4121159ded88990c0ac2bfd34f35af4f07cc402e9a381a675d03fec7ec438c4ad9d929aec8f242def023c993c9e8ba18c7428e88fde68a4711e506d7969f63c8e0bc83ff0de4e1336106c05e09d5922400e8a81bf54885667899785882b70f20dd8fb1e75f5855b765a256da4341bf23ea0ffa18aadda381816946001045669c8d04df0
+SIG: 7a44e6a31932dee6dc2d8394e29a6551d13e6c6ffdfa218fa5b998668d8439db5e05379fbfa0da5b563ed966435ae2c54e3ad16e1a9fca1f5a157a080704ab03
+
+TST: 204
+SK: bea445e9b6d3f21235912cd6c42ec0577297ca20a10357880c2b846dd8e2cc77
+PK: 024174966221699ea4b0a37e517ff9b16598ae4d4e83bfa3ca50bc616841f595
+MSG: 4743c7c099ab815927b3674d0054b6de59af2811abc2cf7fde08f62929185adc238fadd5e75ae3ba0036ff565a79405b424f6552331e2789d9709ac1ecbd839aa1e91c854817597958cc4bd91d07377507c2c8d3c006cfeb6c0a6c5a50eee115e21153dd198ea0a3aff62b7075d5a461788783f050e659c572963d7a59e5afaa2b9c501f43c6ac08ab4797c4566d22b93cdf65a99a2a1d638e79f72b5f4631fe5e9e5f968f6db7a1880df51d8febc14942672f8ea6fc3a72814a44d66d148420a69000f68c330de5b80fc6
+SIG: 6964b9c5903e74e99328acef036558eecd3369150a52e2cbad4bbb97d461b3dfc6b3e8455813a4f4bdca46302e02e683ecea1820171c538e54c3de6c954aa407
+
+TST: 205
+SK: 6447540ed7be0a11c2a8de793d83c6e244983db18d78ec9d75f1729c92e0fdf1
+PK: 391212c8edc4d334a5bec860ef0f5ebb5ec44e8bb51c0f6741998959b2b379fc
+MSG: a4381c7638c48799e9b5c43f67fc3aa3cbb5ec4234f37e70ccccced1627a57683d1e53f4e0883d8b462bf83f1308630368c89b491533ddb8c9a5b9e8155002fdd581a9a5be0e430b9086a6beac4720210f87b14e862d97e5cc69286786a7586723f231ef0e3e1b932dbba3a18a0cb221cb07f80e6a8e1300056c13e702b23bfb3250ec7cc864d5c7ec5786240709c56024ea6be5f7b15a4fa5555e39a744a1dc557df5b948db220b3d5745746691dacb4421641cdcc12e7ec0450293f19ec57b09cff135847aabe446a61332
+SIG: 3ab5f88e2f7276b5b6583dffba5639993a905dbf9b88ceeaaaae3335800e4a5f10f83da6d6225a8dbe99ae80075009dd508786b3975113db478e14ba101bee0f
+
+TST: 206
+SK: 0c587a811add88b994458c3c808ac4e3a83afab26d4cff5c961b9df0b5c83344
+PK: 06783b0cdcc5028c5638bd748f0bc76f7e94d1aa2015ca948738a3500460aca0
+MSG: f56dc6b76076325b2126ed11d1f09decef9d15c31d0e90cdb1a27e089cc56329f6ec3f665eb6739ec5678b3f37ee1fb37deb9e240092b7a88fd25525acd55e294eb1046f9b1b69a847eb9ceb7b1593b9f6978ef618c15de4e059ecc3bfda3297a19c2df202adf72155cf21eabd03948df15198e8a68b0884f93ad5e36eb0983cca30e45a8b4b5fb8136fdea8a3341dd7877540a557debf7530cc33aeeef6271c3f0af6d09787e815f2f1dd25ce4d2fd09ffa9f53081b469c500da4d44180c04eb1869329cbf2d823187e831c24
+SIG: 33b4f4274f20008a721d1e8d054a2b4e95327e38bb07b33c4bee7e1ce020a442fb2627eda3b7ac93cd3ab0b12b99935a1a9233111604da4acffb5315b907120b
+
+TST: 207
+SK: 66cf401a2142fcf4a8018046cf4140bca18d76ef6266e7a024757df172a5d653
+PK: 67d48dfd23743cc2ca40e4dfd6b8cc5d84be82dd2b1120cc476e6af6f25ecc98
+MSG: daa8efb3fd41f12fbc55bd60464157a26d718632d882aedb6bf98e47dd2337879e0b46452e062e6dfbff3e7bca7289e4ef6b3f41d4b03bdc2c842afe97f3029883ed45f6054dde9690649abb2b8dc28f5fe8cecf80fc1ea411bfc40bbf4fd20b218cf47ea8ee118d4d5aefa5c1bfa08a8fb1b30d6de0977cd15e50292c501f2e71ce2740ff828b8432da5a594bab5223760b64792ed3a69dd75e2829234943656513df1a17a2a067a9a8eaa64e19569f46939d34b99271ae50a47d7dbca3620c81255b0e1fd1f3cec851f1b11b35
+SIG: d6b0e80e60bc1b29ab8f74808fc460847795ccb887bac0ecaa8e135297a85097712b24b0a1fbaf7a67c5d530a47d0643fc8702c059d215fb112dbe475e5bca0d
+
+TST: 208
+SK: 5dbf885aa598e895571f5f65090b72323e9d70b0f58110687afbbc383afedcac
+PK: fa17eba76e3bc3ea6dab3a5b120dc5ecb9ae6f00138f7d36dda9268bc4722174
+MSG: 1e0b6cf15ce03337179c02d65408df5be9200c3782b6004af94ea4decb257999d6fdff301d11d00c98c372fac0d026cb56dfefe3def7eb99ac68d6968e17124d8446f53e8d2d3dd890d37a23c7e0b83a484b3c93bddf6c118e0281959d27bd87d37e843d5785f4a40771398494e6c4322fbb675c1d479321032148f7fe52564ddf7ae7ac269d0cd2e552fec589aeae0fb93fe3eeaef0856096cf4f6b3497e7235cc8494d810a0b46c5eac87f187e505bb7764f8045c9541983f7b025698009a23d9df0bd1a473cbee4cf5e9488ecbc
+SIG: e1429dab2e42cd035b7fc602efd6baf94706f16eaf2f8b5fed329239e875605fb172f5dd9ae2bc2eb42eb474567e292f5206e82e694bca0d6d433b867634cb0d
+
+TST: 209
+SK: 84b3aedd4797a565c351de7dfa0700b9ff7c4d7291c8808d8a8ae505cdd22590
+PK: d7ad72caa7c22209ec4678d11d5590a6cb28a07117fe5aef57b50751583201a5
+MSG: 532567ffa53b5c0fcd29c39499d2e78ecd20e63123499240e775088b394dc65c8baaa0fe8f6aa7e70181f9e10add8b4a8beb0b2ec38a43309f100cd4be91c6f48e79dc0aee93a15c9403773b354a8d42ed48d8f276230fa6de5ada501ee0a653b4458f0ecf6d5b3c33e2141c662f6ea055f741e54586917d2e0c4eb2b56621f9665fef3246f0bd800b533e3bc615c4021f8d0e2ad233a11e7736c493acc31faee76a097dc40db9efc22446eacf1cc18f51fd10236a2f942d0a53c3ce209108b5938c0a9e536b89ef0ad6b405a10f22c3
+SIG: 9220f0edaaaee1b876350dbe9266061767b86296c351d4cac99d07cd612c6efb24f8f9b0b975f95c42c5b6afedc892f87efedd39d5160294c27658bdcf42850b
+
+TST: 210
+SK: 6950bfcf480b98ea18a2d5ae5ba6e7668f4c283ff2711357740ffe32cf25819a
+PK: 8e4c6f233f7b86321c9d6799bac28aafcd2503d7aa0a7bded8722727fbbcaeb8
+MSG: a401b922aba57ee0c6ac1c8f1b48296a8562eef137526893886a08306e2203667788618b939864467a31f16edce152a42c25546b640ea8bed189a4f89886a37f106911eae1f50081bf795e70c6504437d2a80cb839479ecbb87c129bcc5fe31d716ef978c206d7f08a793466594f4d75e215bb6374596f8e7d00eea724780943e89bd3863c951bbd24efee23c97c2c797c7fafbf8f2c8b43f37a5f881129a09573fa7a034a285e80dc4ba4bc9564a4dcedeb33167e0b30c5a00b9a109a2231cfa0012b29b2b3450b892eccef0808e503f8
+SIG: 94de5df7a25ecd70205d40bc9499fc7cd7136568060a419a93be6e318664bb6dfce60e2d4e633f7ec148fe4f834ed277c1fec4c4e2a86f44c4589c817888db00
+
+TST: 211
+SK: 61b260f5b848b271ef48e5a56d297432d89f2ab85bd538fa668870d0560220e5
+PK: 6086fe8735f399f1af2e395e0fdfb5629ebcb04b6ed4a54a9e47052c6e8191d4
+MSG: 2826295d79945f675476bc4d45ef800d80b1f0398e4be60e3de4571ed108df989f032de6c2345d9948d677927ea0b8cf1a5ca36fd5f23c25dc0d2ab5bd565a54af46fd97d338d770e3a7b47efb54c07a1664707771eb4e37d9d70ba779251dcdcd3bf6d1248adec53f787259c4d594d5fd4ced8e3db7621d4965d48298178124931a3d0cd269b2d53b7cd261b96d370c5d9693c8ad133ed58945ee3540e10625d924aeba9bdafc656100aab276fa996b1db477bf85ea559081d5b4c7307dc1595654aca82f7b6d2ddaf7357c15a4d7d8b908
+SIG: 9828fec8ff5cf85a98f450770b5bdb4b80daca44379d8f53c91c348e22df64ac48f2b6e2a7b3b642bc8193a194316229e69447ed241cd423d83b6fe7b2d44b00
+
+TST: 212
+SK: 936dc1cef6a310747f350088055a39aa762d9a4b52c8c8e4c682794380c2725c
+PK: 03b31800412df4d56f1532c05828c0b72528a67a781bef4c06c1fb6ff2ce324b
+MSG: eb58fe86c4ef349c29ae6fb04f10850e38c6823dbe64a09a5bf1e0ce600d394efa6fb96ed6a8f2c9d4bec05e6a5ebd5a1bf4d0c51db934e57b79e5c6a879d975197dbb10475f65c7f8a8c6a77a420384b5062a2740f1401740ee0f5e043aad7a2a2b4260c5d907f705edaf65b0e375dfc7b00bd660db6147f2ebe870a0ee18dc2ba3c92b0b76fae2b90932cdb6c149e46f3feecf4c26f0441f3a9e006678aecff8ccaecaeda73a18a68ac988b62e83a9bb5188aede38df77a9a164abbdd9d58e52a6caf7222389f198e85fbf966236dcdbd4c1
+SIG: 3f994b8ef528f6421c6a6a22e977ade5cee887263de38b719acd12d469bfd8c3f68e7ac07d2fae80a2092778df0b463537ad3a0551997a3d5b51f832d9c8230b
+
+TST: 213
+SK: f89eed09dec551361fa46f375973d4fbfa5c5c12f1b5e5abf45cfa05ff31a340
+PK: 3e0efdca3919fa10d4a849cef1de428851bd08efd248594fd89cdeb9deee43b0
+MSG: 4cf9773da05fd322fc147be900ef5cf256c88afdad4b08c230dfc8981fb69f476f7d45ef7c9006bc10032ba53436ac22843e0d76289cf68f9818fa64031d4b40955059aa69110915889f5e22732a1343912581ab3b11a3bae7a471359508596575f888160beef966e5708f0e3147eacfcec1caa3ef240c5e0a14c186546c8eeb64658350b1affc0cfd2ac213af670afca7bbc9dddd28a465b586e69c388cd73478d68efb322bdf86d9213011e711b2b95fefa7bb9b5939761706aa7121024906420bddf1d8800a4338d938fa137cf27e9ffc51c6
+SIG: 897e6f2797c3f326d2cdb1d2673d360631f063304580ff5b4eb43d39ad6851834c9cf891d9f0905bf8de075f7635dfca601adc0f14e7b2c76f7571bfa468ed0c
+
+TST: 214
+SK: 400796ef60c5cf4084dee1801c4a1975e482e70aef961cd42e2fd5a3fa1a0fbe
+PK: f47da38128f2d012cc5797571d479c83e7d8a3409802f9a7d976c27067cbbe43
+MSG: c473325e785b27df4471eefb9ebebd6461d570800181100ff36caf3c38f67c1921b157ec8e6126f955aebd90ea3fe5385f8042cd704b27cc1d6978c0e2a296695f5ef97b7c2e16ae4ff4d063c688d7f46e964e1f0a00503f357345977683d6e4c3423d56bdb6ce864b6987e085e83e70c7c1a14e0e413f592a72a71e017d505b64c24f1a1a6b813e064e6e0cf8bd4571d0ff2f267a6a13e0cd430463b6ca3b88f0cd40b0fb83d5bedf6f7d47e170e87d0a750093693eda232a6daf98125727b9588ecb894ae373bae3a445a106306469a4c2cd77ff
+SIG: 84d3aa3f361844396754d80d9fa05b8b2fa4abf3a0f36b639bee9cfb5c8530a3a9cc34677f92a913c41e800f2e8041f7666d07ed85f16a57d817b1241fc5ee04
+
+TST: 215
+SK: 6703a6232c5e2e65e0ab3b92e2aaf9f5fbd33fb46988047d6f4d0ff5387fa029
+PK: 047cffca8b7b11ac6eacc0eaa0c5b73c75b9c637956973af9d97b2dd5b605d6f
+MSG: a26b30a769197932a3a62854968d760151612366778dc994576a2e0e0355496b46200e506948a0d102b6651b2e7334ca6c6eaef8bca44b425970a0b37d6bde0da9d3c1b9f51cbb25bc335cd6fa928a74f2c0dc2c6e99d37a12863a474d4df43aad35415ffcaa24d8c29f914572ab2abec3892db49e679c5ea220c2f519a7d033ac1a2c5a467869e30eda3d2635ca863431473f958d552bdc5582352c290d0ce4fa9cfd0ad42799c227ec90b7c9e5db9f5a7b6d569212eed94d323326805f2b3a0010d6c11eb4107c8283037652f50dc067b6dc81f4db
+SIG: cae96879e5b603be866609d4a053bfa12a51378e99b2a2812e4789267d8f32f473243f8af74b9be73f47dea50f0d165ebf49458b73e53d88580c191a182d1904
+
+TST: 216
+SK: e0e72f8f178633626733bcbda2ad2a50e653890f15359b6c22fc7345ad333109
+PK: d13cee540d84b5667d516fe7ec7239bf8da91546ee791f84edd8ffcf3a083e76
+MSG: 791fd613c1095292c8a4a2c86b47ae026155b8465b607dbb416477ef79a297c9d7758ce34af9dcbf1c68474f30909fbe74b7ba429632f2403aad832b486b72c23054ad42f7653a9ddb456cc791f348886a7ae5dcec7c0ba815f7a93a10fe331e903b970f7b5028be49d14bc5620d63792672b98b9488c67ae16646693e112047f0ac8921ff561c92dd0596d32df0a6e507ac1b07de516c98428d570a37db9bcd7c7e61c6948ab3fe91250dd1d5bd671275df9a972f22c2ba36804747aec1ea2416c1f41ab87befde31629b2d43317ce41cda03626286c0
+SIG: 14552171b95245ac0f0e5a6e7a2f541721068db650c6dada04c28cab7c49195f6436712144cb31913c562e30c39d8a8549fb64ffea81c7445143b5f23286da05
+
+TST: 217
+SK: 544dafd9960d829756c6d4b3eadd44375fe78051876bf978a381b0decaaa8096
+PK: ae4f6425c1b67ccb77f9aacfea28eaef769c8cacee035205cdcd787e8d07629d
+MSG: 447fe7344cad1fae09d6a7d05f09d503c1b3d3d5dfa584810c35bc41e4955693706154e2d751b2f1b525e1a14547ba7f8b232088a6fc922702d93a11cd82949c27bed645dc351fb4c1242cf41d01575412e792aed214531d94fd66e03dd32e972fd77f6947a353e1ae5e00f5a6ca77992472f096b6e7475fe534e913a77bcb0d681fdfb3a7a0dcb56d274df4aa109d4a8a37794a9276f50006696ff12ca4d0254039df0fb3f72a960da05c9872f2e33ee81d1cf7a6f48bbce0aa18c7c0f06ba55e67689e0af587b500eab79cc7f9640bca104b7fbf31f08e
+SIG: a2ae117c8de4ca6d6fe75e466023bd550c26fedd3e74ca13adb625f272e175f14d5df550ace7d82288efefabf96311a123bee23889ad3711bff2b8087946bf0e
+
+TST: 218
+SK: bfbcd867027a199978d53e359d70318fc78c7cc7bb5c7996ba797c8554f3f0f0
+PK: 7c5ae3bab9201199dfbe74b7d1ec157125bdbaa4520f501da3f248579dc6c22d
+MSG: 117fae13e78777b6219f020214c1b87c57046d1c09ce82ee2b5629898d9b0de74a15cfe99f80548ba913d7036c56285a4cba493b52d2cb70d6365ace3da12b1f34a2778af36ef52ab82ede04cacaf2793f5f89831e3b205a9ee4c1d6fbdab4ba4d9fae65dd79a5fe76b4b39a3092cc7148d211e85ee82ab463d34dcee9061d9c21ded2051bbd50b413f0e21a0e48d1ffa8dcae240b3495be25d93151b57aa271ab99aa708ca28080cab4804fcefa929f5f1ef3f4c6c0fbfb40bef7ea1b509b36ba1260323512379d7bc3fdbb5d3faac9b00e21f12ea1ca2e29
+SIG: e48615b65633e61993b0aaa1fafb74b9629c384fd592bd735fa1f62c5cad11291fcd8c2e91a50bfe0b03b43502fff3a5c382b9c2821907efc34da5ba054af00e
+
+TST: 219
+SK: df2df8a9d66d5638cdee09324e7b10f8ed29ab91387e3147b7dc03f7cd800508
+PK: 5c042e157fb7fb12d4d4fef2847141ecfb57c1253e14eaf3004d6513f52fe625
+MSG: 21576615c9346a63dccf0c50ecbd7c6d72ad452cfed43ea73202cc7a98576056b9664b54622905a1e7221720730ac685d3bd3977ec3959d446bfa941e725b6fe16afe5432c4b4bdee7aa0fd8030948ed6fcba7c0bdb40c2e517da97456e74e1f93d5ed676de0f4a8b0aea449404bd15b6da79dc1b813965fe5572410d76f5b5eac663050570311dc9842b6fbf8806aec03151715cacf7f21802e8bf5e98a89c0d7d0d098b73c6efc09962e36b4e030c1a64b5d349f5f2042c74428671e4a2c7fea0caee2422d85c4fcddfed32213859a69955d4e3ebb7e1b2022
+SIG: 9a1074531ed43d07bffc7f2b6c13b8838fc75cba02c7d1ec7ba38bca3cef20dc9badf3a3064a2c93b1842441420b6a8d421a960d70dfb7c70eec295f21f83f0a
+
+TST: 220
+SK: e8ee065f9907f1efa2daecb23a0425f353094da02bc2c931f0a587efc0d13de1
+PK: c72651b7fb7ac0337a172977496fd7f2a72aea889385835e563c6b6053a32dc1
+MSG: a2f0c1373473a305d8f1d99138b06b9a9694ffaa8a88222de9f729bee1305175dfb17001cc77f67b6d40c90c1a28fb226c11286db4a13e45e69211242bcdd01cb6e2c454e76c0cab881b4d2d9d3ab100a5d61d1725d866e4fdb66d93d77f5b308693b9b5a333e57fa25d1e5d2e38df6e4e9ec84159bbee1ffea926836a0101c91483bd5bc88a6f1cc4d4e7f008ad08453a0123429dd335781c7cbf8d685a8999ed1177607004a13c4cb5ea4908c542607d3f2cd6690cf1f2a7455bbd38f538f07a103964317efbcee37eb46931c027cf153ef86e43d78281ebd710
+SIG: a510dff42d4559a19a7bf0fe0bea53d3e1f22dfa6be55039895e12a5d07da5f2e37713ccb2eb216011628f6983f871fee286e66fff4be7582c961a1ed7568404
+
+TST: 221
+SK: c72e67d8c3fec004ff618718a9099eb8ad7b06ff3b8c542a7e8b9847313475e1
+PK: 4eb002d3cceb188c6658fec51cb479a65264ac555c75cdc2249cf1ce3defc16d
+MSG: a8f34135c0132ec95b64b0cbf51d66900143370406791fbb55f2b8ca953cc74a46e08b002fa2da21b951b8871f7a29bc6d38790afc66a329c397d9f9250bae0e30ae3426e08d8ead0179a3b313c908839192f289a3f3b6e960b4c5cebef0a09daa9c7a15c19d4ebc6fc2ac3cd02232e832b234edd7965d687bfeb758f70fa7963841b7859bb97c971bd557bc8769524ac4c6eeb3579793334b522d176bc62f86b4d5c0d4017036d2b6bd4e4384416ef8263139691a8606170d73c93d6417dcc1a08a537c9ed4400471a46f52907b46b10a8b6889dbb4647a8bbc7149
+SIG: 2d7bab8ebda7fca5bb3c25f51dc51b73e6ff6a3bb1b52acc7811a7d2595cd6fdaf730494418e2f57efdc5617b066fd7b6207680d94fb8c43d3d4740b41cb6901
+
+TST: 222
+SK: 696450b557ec3c94cf1af1326475634aa81def3814ff30a02ba7f2044b59c0fe
+PK: 8584773c566b0eed3f43281705b575a434e47d6cf6b251b89803fef53534cb29
+MSG: cc257829f30a5f90dfdbc247d42e388738b76c41ef8a82a5e0225ddf1e386d77080b3b9df86c54b85cdf2c32f367aba0c3b6bf888a5a6903529b6aeb4d5407a10180149114130228fc4356ccf366b77be89796a9e71a0c693f31e584a4f143097ba370363b67b2f2e2fd8d6fe8b4e8dbf0d7dcc1a8360041158aa2aff7e2a325b8e518f193a28bae05e3d52b26621af402026d7f250e86dcee301a58b631eadf4527e958f02a61587f0bb516cefac009fe51052fff53336dbd94e7266d3b43caba8a1b38e5d871c2a24a4c412fff3f7a9a52a8ab23bac9791b2b5a669a
+SIG: ce8b0a5779f4f5f401e84d65927a0c28df829e95d09bfa97111b8700078ff894cf7277e34a716144d55306fc9e2f64cd287583cc8003be0e8faf26af7640140e
+
+TST: 223
+SK: a8dd35f054fb6ff6f0ab094a0d3d1c262832181df35ccd5192545ebd6a9cf529
+PK: ca412338d3814b886d964b71925e1aabb3ffd07834dbe7dc512568882b53e4a3
+MSG: 55a7ad9132d63ac161e7adb132b9189fdd84c361c1e4f5419a6df73df4d7aeb29a8dc4bf01490d4f484e2d12077517f5fc7ad0bdeda20a6cb0227942290b08c3fe33ab9b2135bc38a6579a54bd982f7d1417ce867117aea918dbd3dd476e7eb5b5d3c3e48a864a2f942a31501aa2b29b53b80513c95d6a411844f0dedf16a29ac267d331e53bdc2539bfcf32dc9b5d640f1231e2cafb0ae94bb5189426863364262efb47b5b5ccdbbc93324216a799b6f50d3704f15ed59af6cc7d910cf062d1be632dca5df213d487d8564f2b2bd7d818bba27c364013d92d7f72625462
+SIG: fa709fbc8382af83d11812618dfaca452eab83e4c53fe9e5858467d07b6767e17975c1e06393d6dde15a34d9473d1cf4d6d8c2d57394520080fac4e43448be07
+
+TST: 224
+SK: ae1d2c6b171be24c2e413d364dcda97fa476aaf9123d3366b0be03a142fe6e7d
+PK: d437f57542c681dd543487408ec7a44bd42a5fd545ce2f4c8297d67bb0b3aa7b
+MSG: 9e6c2fc76e30f17cd8b498845da44f22d55bec150c6130b411c6339d14b39969ab1033be687569a991a06f70b2a8a6931a777b0e4be6723cd75e5aa7532813ef50b3d37271640fa2fb287c0355257641ea935c851c0b6ac68be72c88dfc5856fb53543fb377b0dbf64808afcc4274aa456855ad28f61267a419bc72166b9ca73cd3bb79bf7dd259baa75911440974b68e8ba95a78cbbe1cb6ad807a33a1cce2f406ff7bcbd058b44a311b38ab4d4e61416c4a74d883d6a6a794abd9cf1c039028bf1b20e3d4990aae86f32bf06cd8349a7a884cce0165e36a0640e987b9d51
+SIG: 909008f3fcfff43988aee1314b15b1822caaa8dab120bd452af494e08335b44a94c313c4b145eadd5166eaac034e29b7e6ac7941d5961fc49d260e1c4820b00e
+
+TST: 225
+SK: 0265a7944baccfebf417b87ae1e6df2ff2a544ffb58225a08e092be03f026097
+PK: 63d327615ea0139be0740b618aff1acfa818d4b0c2cfeaf0da93cdd5245fb5a9
+MSG: 874ed712a2c41c26a2d9527c55233fde0a4ffb86af8e8a1dd0a820502c5a26932bf87ee0de72a8874ef2eebf83384d443f7a5f46a1233b4fb514a2469981824894f325bf86aa0fe1217153d40f3556c43a8ea9269444e149fb70e9415ae0766c565d93d1d6368f9a23a0ad76f9a09dbf79634aa97178677734d04ef1a5b3f87ce1ee9fc5a9ac4e7a72c9d7d31ec89e28a845d2e1103c15d6410ce3c723b0cc2209f698aa9fa288bbbecfd9e5f89cdcb09d3c215feb47a58b71ea70e2abead67f1b08ea6f561fb93ef05232eedabfc1c7702ab039bc465cf57e207f1093fc8208
+SIG: b6c445b7eddca5935c61708d44ea5906bd19cc54224eae3c8e46ce99f5cbbd341f26623938f5fe04070b1b02e71fbb7c78a90c0dda66cb143fab02e6a0bae306
+
+TST: 226
+SK: 6bce4dfd53bfa5506f2f554d2d994a0dc40cafcdec7e1be050006e5c5a4b38a1
+PK: c890023728d8397070291771e65e034d34d4aae5e247653e4ff4c074591da702
+MSG: 3239190747ee33d40bf870ac9ad49d88ee320f63c05257e8ab2c60306597ce76d1f1e792ab6a65caa544fbec20892fd4960594f31b3763ef07d4982eae4a2dbf3377dcc1e3f95e46ed39b7f0222f04bb5c3b434c8f9f310de9f122a29f8241e81e206549ae628d2b8ad768972c98847c1188ad04c835356378bef79cd126869405b129fdbdc3bc489cbd1399505dadef7617b5be5da173d3e80e5838c99e349276242729e0219bd7476ae5c4f81a12878fb483a6c0e9b0df2962eb0bf00157782cf768a1b71c010169ee8522def0024ad7e45775a290639c53aaf48198c42de75c
+SIG: 99ae6782ff27646c27f61e23636ae1881521cfa5ed256f70bce7ce00b68280ce8e0c82aa765afb8b5a1ff2fe42c57441e458e443dc8b123477ae33d884888c0b
+
+TST: 227
+SK: 17861a8d4154acd4fa9c8fc947c1886c11290be222872ff4f8cd25939e4d1361
+PK: 43773f4449065eaebaf8937baf758560b0c4d2de46977839b3b873d5d7d5fd8f
+MSG: 184df5ea3215ebe180390b0ff042ba2381155a038dc732f76a01c7e70f82d1ccc9de9a0596b3fee447209c992684f643df21f4cf9d179262790e8623e42472dc351997e6da189c07e1e8882c07f86c6337ec0113912cf92215c8de1982b8fc57bfabc55a3e8736f73610429d97feb51d794f505d0c5a0b3abd48ef7f55a628f90b8567a1c15ea9d190d7bf4ec2bc9334ada6cb92808dfc2064836fcfa46b96fd7a5d6f4b054dab09b73595feb89ed005b9ec9d3188121de69696d64e7c7bbdfc1c469faf148c38a7785970afe1acd06a92c99478fe44974e3bb2095e4467e9b2e996
+SIG: a5ee024ccdbdd4c21a24709ec53dccb7ee17626dd00a093d0884f5b45c4c9d1691840151c33c8aa07b69b34e16f61647ebe793ae4daa70cff48e6ab42ffdbc00
+
+TST: 228
+SK: 0a84baa54f11cf17090fec61f3f9401508a3a03887aca1a7939394b1ee40a925
+PK: 309a73c62d23d740f2e93c18587ac15e7ec480d25ac0794e10f8cd461cc2b130
+MSG: fe70017b14678b0d3ad03e183d6f53314378379ab3da65b3511257b3d54086e86f2031139021391af9d72085ff7c3dc8c1e2d91e53333855423d0f785e2cc5f8b7799fcf1b70e6becb788e53e9020f2995ddb0c383a1f81038fc3d543ce0a38c9c288a9bc4077f4277dcc6c5642263fcfe19688005a603f57675d2434f3ed1f46d32f14eaeb073e83ee7086da2fb67659d3fb68c62320b7727b3b8ea006576bc2c7e6b5f1ecefa8b92e70c92c88951d0c12d91de801c38b7ca5a0a04b4c3429aba86386e96e06afd20d4c5c2fe2b9b4273eb05201a79273abdbeb37ed1830d226b6bdb
+SIG: 4d870bd53af8f13f214d9934ec903ac48284092cd9b162a44ccec851fa942de715ccda07b7991d712723e7a4d5b4f0374ab85ac3867e0b53ebc46b530f9fed05
+
+TST: 229
+SK: 38379423dafdbf25e19d7231bddd80b4cefcfe2aed932584dfa0cc3c9f9232de
+PK: 597e81dcee9448b77de6829e7921c8a390535d89a0849430aed66364ee140d8b
+MSG: 36125ca66668802906237e63a2fe5ae610f11a7cf92520d19e6690a3adfafd5d07a784bc1a0e185273d11d340d5eff901597dedf450c4699d43f3fb168d557f6c9c03077c3cdc370d34832ccdf2a8e3d75796490ed0242899d25ddf44bfc66f329cf4c45168703c31bc9202d890f3969ffd3ac35a12818dca751ceb8808fe81efa26a5e0d200c5ec1d94a5097ea74b6498fe288f30c48d727e9d3d35c8e12d85420702556f2861484ffd09b4f12265cc9abafeb82cf590028895a7d050ff57ccf5f28022d016ab4094b062e48b66fd36d1e19626e5215efa40fb7e3b7062f81e954830c9
+SIG: d8b50a88aed6f2a96d082213adf8b2519f6a0bbd30dd3cb0f3fd3ce1c643fc029946cd43462ed22513f1d65fca24bde3818166baa86daa798792afafe0c1a10a
+
+TST: 230
+SK: f925d274aaf1fe1a21656237385e97f7783e78090c5d4217fece7057c80f426d
+PK: 3b0fc370be3a4b19a88ab998c59504ffb59a87606338e673df5b3fab4d9bfb8d
+MSG: 143caafa5f62b13e43dffa49d420fa99f771b1926d40d6cb2bbb427f27b6c266eb3deb2d8bbbd47b8214ad40251cb1907ad65eb94193e54ad85c6700b4189e80f1cc0154c63ed151a8bbbd30e01637ca58e70aa3ee52ef75d0873078a405014f786eb2d77b7f4422f927823e475e05b24245f9068a67f14f4f3cfb1eb30bfede7b3262230ced9e31361db19636b2c12fdf1b9c14510acd5bc18c0ddf7635e003503e6f71e1c365cdfb4c65ee75b4de0694af87076374d631e6c4b8e240fa51dab5e1f80ca2a06c49f42ea09e0475defb184d9cde9f58f959e64092aac8f2027e468126f2fb
+SIG: 79549a317d10a0be322a94a151ad11e77efc4836cc8006a85081273d7602a638963a9caf19c3edf1e25fad1e9d68701a71dea727da6a5c5bcac9339589224b05
+
+TST: 231
+SK: 971f806be6f07d41be8830ff8dae704b08638ad6cff722d8432538127b769625
+PK: af6ac98dce2078a6c73f6097bab63f205caf6953afa284d042bd50a4fce96cb4
+MSG: 013455d049aa54ed995fbd94e6369955495395e4438822259b1060e9a34779042a1a69211f6ea2077399dd234806ba0b353cd79a57e1c49b250ab27106dcde576ecfa115eae461febb12d2da25ffcf17b715f8d95c2f0c425d5a81f700115b70d49e1cfe49fcaa14fa205e28ec85247f1a6e7128bf3bb3060dc08464bda6538540d0ac472093e5a0720fde2f3dc4788e0e9b0dbfe2a2b5f1a0f3f80de984025b15c65af77f671e1c5e2840444de5c7eda025e6dc1a3ff16e26cc54cdeed56be73f9b01ab2b1bc16c8ef58a5b76dd47287807e5c50f0d7c0a5b8120dfde645a012c5cf11491bc
+SIG: 2037a0a7674b84ff27d0b22f62b4bac65e2dc0f5fdc899feb7800f25c29981dee641c5a50f8b9410970b49d2d53658c89ee16961dccf5391a6918f2a84eada0b
+
+TST: 232
+SK: 2bb0652f8fff6901991148c68a3267877271006ae9589149bb206850cdf52fb0
+PK: c03b77be983e74a234c1986496b292e139992eb7529e70b3afad7ae4fdcf8a66
+MSG: b923ca67e396d8656fa3dbce8289a38bd3c128cefb30efc1862bb944b4507805419824ce2b83d690ef4cf107492817143bf64c024989af1a7d2e1f5ac97874f86bb0d3773ff840f514d9a1394a3959b011d3a6b816a3fae5de17b2a9ff349863d27fbbb50cca734108751000d6358ca0647a93eb49e2e7af06287d48f2c09d5c1c73e4d8f77ea2bcaa7356795b26728719bed5ffdb821578bd5d66bf92edaf8b238b2bbd7d1e2c30a787f901a33d0a76669a9c3c7f2b552ccb8349c7ded5e1a46170cf28e359e2fdd54b05a562f528c68a56974df82d466637c8e53246a7217e4386801e0e3266
+SIG: 4e158deaaec3d88941296af2d27341012b0241d4e0f46e435e375c9875e89f5e32c057b527bc3411af096a77bfceb45b983efe455e3f03155d6bc7b0acc8e60c
+
+TST: 233
+SK: db9b812cb3c7c03b977f487d3d65ccd9cd2f3dee11602067dbfb72b589ff3f79
+PK: ffa038ad8c3b378ce75d65844d08e3d6a92d194a1b7862e9d9720d20679b2944
+MSG: a70092c7697cd4a209567c38ba7fb71aa8f15e5827a20876923943fd6adc659c9867ac6f58a61dc7cec3d362411682000c1a9ad1295eb8b70f242d86b5865eb76b87e3f2c6941d2612ee3bcde8f19765566733152ef54e95690943285f78b375f4036585d4739deedeef6d946db61ca458ef4f650da963c385e29dfdee415fe495845f55197a870f8cdeb5a010ba6bbb32bf1a588cc774d4890184c4b2924a5b8073313bce226585f1adfc229c90bc6cc9d212e62f05d33bedac961d77cf8c2620e451de817f8c1bb16a2c59ff804b635a73a8cf8c181b3f9401c3b643d18a2f706ea9cae47071a6
+SIG: a628a77421b2abab576eed35d2ee3d14561b21fa14a6e2fac263c3eadd79f2fc0669f9429b910b8422b4b29ac026a42e98d181be3507c5ed7c748a1fdcf1d807
+
+TST: 234
+SK: ce379bbe2fa8abcba51c7a7543de5b7180771b3c44bc6b41892e7b88979bab90
+PK: 7f3cff89f41babf4fa64cba33a5bb17f413bbf2a1e112b50a8e9b1f821d849bf
+MSG: 001a74f095c814d3beed67a8d15fc18efe235dc3f6457812a4039b7a46fe9a0e9de81a7a4e5fbab5ebe9e1e4801bd11b45c9f7ad0636a09bff42164be5749a04c02f0ab61f0ecfdfef799b827da6a274c8d3b39f2e3805a6791287eedb2314d3f842b558b9b489afe1ed37bbbcfc5e60a431d5ac60b39e946d903d6bf6b140e12c7e07f9ed7ac46a3999c6245c8ab1bdb21879a317a3dcd257a5c4f349b7f59e4e43d62d9f1cd16f518f1ca6cad37e2cb20f2598c4134291c6b8a98aae5247e26eefb76aa38c9c8231c17e9dbf271cec80fba5b4a834bd9be81ea841637aa9cdd4c4bf26d7ad24ca3c
+SIG: da98dfb189385b2c853b6cf375738046a8f27ef27974abcecea1db02989b951fe433a6ce1e225b3fa82032fe060a7d3f6c183fd1157f791a064b407650571600
+
+TST: 235
+SK: 2b2ee809d647023e7b77fc541f44875a35fa941d37f7c5b21fd34934d2391935
+PK: 2c29d53e1bf2c7879d73d20ba88ca07a0b216d7f6d05d93663a65c3d9e10633a
+MSG: c4147d64ebfda41a1be5977262958104e940c3876bcd5b6956acfdec32c660914d62623c210663cb2cbe6249d7f5274991c60e950e8e2809049953c69581d2469f4fe982c7434fedd9d4e00ae08896d62cc1fb984dd233150cc2483e159cff4097df8c036bb633003abbfbe18c8fa79b5a22270838123fc9be39b8892c80384a385028c1a81ec58c8f21060e78afd2c04bfd2d30ca3977c6edad518cc1e2004cdc14bf3d15f5f528e5af277fa182275870e5c012f5f82fb1afd04edde4578ddd2160a1a3dbc050e80bdd811bc88ead79bf93f010cd0fd4433d0bc348dacfd0947cceda62bfa49711d013
+SIG: 12d90685775572c9eabc9be2574ca9ae66f0e652e578b21736cd6e654f7c6b1545883d56bf760ccfc3cf87544e0004c798061257e130030cb997a788369a9a05
+
+TST: 236
+SK: 4ea18d6b4af8053b885ec188be48deb86ffb2a69a4cec86637bbd7b41b807c46
+PK: e5986059976233ed77382c3d9959f34e317962696553e86ed1e5902c4bedd167
+MSG: e9c89a1a1119373206ce40ede3b89a82f89462a1dee9e789e9845eec21f571c0faefd430ad338e4a72c047a39a4259580387fb9aacaddc36a2b51e7b60a87ca1321ff806794cd6dd4549a4df45c2dae3e539c4d7d06b6e6e9f466ffca2fa4978ce3dc792e44a6283880cd138a75a226f985da41ffdc0e32a5a85c85fe9a43ae78fcfe57f4dd7540a6dd3924a49ab39eb69950d421151d96b1e4fd3935890f634cd52a73a755f5c2fb72f9cd5a2e67ea930915e133b47cf6b7c10a9d889c6af6b5f1f4f51094d27fbba228ac2268b344027fd49e426343cc0134399b4b510aaea50234df42c37fa1c4f4d0e
+SIG: 27570c002a487d000ca3928b83cb4319722c46dfb4cca260de790ec0e3c1932688f87362952818b54f51bc7aeeb263f960bc0da8964bf312ef93e81f06c80b04
+
+TST: 237
+SK: fc1b75d17d3807217351d2aa40d9b04f525b89ed3f5fcdb311bec2aec5cb7ece
+PK: 55e484e774a4392a9d6eeff835a8fbb232cf6276a89c74fc0d1bb2045a8b21be
+MSG: d031bd11da308097e3beb6ffdb2600ee6a193ca6d8324501c972b1a25166fa7a369f5bc882ea45612cf02580254d21b40b0363237e835dae2656c1b7f4736e88be53d6b119c07f5729bbd82f67de03588322879243c5990a7e61f56907b24171a57cbb0bbefba2316277af9326f9cbf3538bcbf6780be41825a2ca774b41bdb1cd5c608851ec2339eb2f4feeddaa891a6326b29d97d7fbf311e3bb749c5d4c058dcc14f452f9334991e271c16d6508c818633927f429804ca7a38170f1b9f6bd73ed675e11e8c0d321fac912730b4ba2f7c428534adcaa4dad314c55807e6c642d494c6b2f0e8cd129775cc0
+SIG: 9a68d151fea3909893359e60b96b68b2a3e2946f2b47b875398a1e39eb01463d35eae7d976f833a762b51f2726ee0dccad5ce3600564fd9dd58c23807fdffd05
+
+TST: 238
+SK: 0d0bf4d42ef810b179eb841771de6dbde76361caf894e42a14b1e09787ea3e06
+PK: 7171510b43fc17efa80b15e320b1b0a408332542e0d36e4ab9a649cd941b5aed
+MSG: 8e2179975d0a8e5a69fe875a3cb1e79aec49c3853e30dd0320fe3ebfb638b82f89ad1643036b37e56e0b55e0a9e22a4e283d7a27485ce9102db6787d6628b77913e10896774e495c26e8bab26e7f9a94d29aaa36aec9c26ad3f50e5d8c0b7698bb5f01b876d0d65fcf5e9e32cd7b89829ed05b0b8f63a93858985bc9569fce429fd37a211abed650f585c3b55900443b6c5d6e8a48ba67deeed07b76e969fc88430fce2709c0bb5ce926ab7f44e0cd79f4ec359ef76748883fcc3d026edd06c8b9cba54b990d30aa41f1448a10893fb0539280c599d42361433a34cdafd8ebdd92efb9c38a36daf4c74060c696
+SIG: 24446bdf03416a4d08614466fb851db50e91a623cacd1b0b35660f3cf933200e15308708da3499a5ad25f0f0306b7942762e20a765b7ca9b901c750b3a95320a
+
+TST: 239
+SK: 57b5194d26abe4ab2116c0f03d23dbe116d48825a25e77d64648b43692ae25bf
+PK: 499c02dbad2a4eab3b6ff1aba3944b91c3f273a382c548a6f3a19c83f0a86724
+MSG: b4813c9d13215fe9f63a78ff7ac95173eb810b4613f0f48d6876b2bd3b2c72bc7d98cb1ac32bc41ca47f09896f79204ecfb8264ce8f3c3e76dc124da8ddc6e0dfc1e13b5a529f20c82613fb9a82e5f5d77326a861faedabc7325c59af33dae6744025e649774fc4f79134bf9f6e3d5875dd91bc8a14cc36a66283d01d8d108c13327eca53057ba50bf210c19f139de6494982646198a1246c271b0a368c10aab95cd8961235d742df4545be68bd010dc0db23b673e623609e420ee76b1056c520f9ce8fbe8ee1863df97d17b7174636c3a2b612295091948810d1d4b8a5843760a2887dc55ef512af041ec54fad3
+SIG: 4c7345960c8fd48a7dead71dbd61908468efa865a135568c8f9ca0055483468617a7e335840f57c6cd8f2c9805cd47a9d7cdfde53da8ef4f1adbb6f698aaf100
+
+TST: 240
+SK: 068d27b21e2acfcc19c3e9673dd44142d98aacae894930e20ca067439e749a79
+PK: e22ddd396f955bb90e284776aa76e921e50699d0ca8914a9b7b841eb5ff47d6d
+MSG: 1c6815423d1a2c5ebe8828d1646527c17b2006e547f016b5350f010d79b13df4fb8c6ed57ba9c26c3cb0e0a64178b650a3ea5444a4fad5b20a3eb8caa702634011cf7892a0727b6e8150b0770429a37a8a0bb3a7edb891a7c90240bc0360b14e6dd770a990b31b31f33ddbf653988f82742e5eec31b27368eb0e4f1ecf4d676f49214a520d1e5b2bbb59ac2e13267e07a0cbacbed9f94d7473ed697828b0928fcc616ee02e51fcd8db4d8f7533b7b139a05e06f9e0eae32993e3025aef0590b3fbb4292a3ac40765e8584ead00266acdcbdde1457a03b7d57bd5c9e64fb06b64a50f35f0a1ec34b6ddbde767b96ffd
+SIG: 0c173c488ad001cbb9c43d7b30a7c071a2fdb08cf7f37daf71d7ae7128dc0d43f0f095b2929c54b773ed4a1f0bf0dc4f364f0601e8d5ae062f5b78c05bfbc702
+
+TST: 241
+SK: a34d52563159e0723e9f3fd133bd96e20adae623f8c798013bc36b441489bdc2
+PK: 1fb658e645de6d3efdb083a73fbd592fcd4b800e03c7bd681aeae6576bfbbe2f
+MSG: 1d215f85c089f35f307a746c66c7c1e41d6ba37730d759e6e5622d6c6a198e40f63d37873b715df7518b3c6bb5e95a467726b97c9a0f8f5dfcdbfd1e0de357661ddeab555042b945fd899fad6d382d7917da9e12dfbda0d69900b3975165a73d0ac9de01fd3048b8fe5f0b90be67e03dc22f653a0a13eb4b0b753f3f3bbf787369ebd8bf5e00eb78bf0b3515a91e68b1d5fc6920bf4f4259f8a730efc7f1016d501ef6fb7cb8366fc8e716cfa50ea8b203cca1a316707e0b0fc57eafce82d62f7ff3ae04ac8fd041b55b19a352a69e6d4b79d0e650175168e34fa3358eac816cecf2c8dd1bf2a589113e91bb818f91f8
+SIG: 5fab5a7140d47873684305aa6353d3862f5fc13e54a40c9563cceac8f74008c6c445631fa864e0f1c345b5954f80056aeba25662b78827b5e8e3a9437813720f
+
+TST: 242
+SK: 58dfe768bf52118494b29975154cf452bd9746dc7de1d6bcd18ee6a05acfd858
+PK: 0f1476c6cc2a1b4764af75805e77341f14a0d8b09c6a5b2ea287fd517c3fa6b9
+MSG: 609794201c4f6faf488790d61dbff3f41b328c5b0695cbe9aa8a136d72b4977b21b500f216e9f32168ada8c13bff25327647e30d8a244d74d88303abc90b7f71aa07ca04d17bc8a0167d6e63fb88baa1dab81d50f1e91f46f5af77f2e8408b826336a35052efffdf4af79596af1bb2259f83c1bc109cfdc3dd50fd96d310f27ea4c6c7690f21815ea92bd79389680cfe3ed40c80181190688d24222d9a1ed52ce6a16b41dbd9107eb6d2e3594e4494d75dd7c089e3b26ffd00d1003c92c4c39ae5382ef9291491a880ca4ec3ac2b86e66719b92b6f7cea2cb0bbb1cf624d0d1abeae556e5f73909dd546277037ec972fd4
+SIG: 977137a38af44f4b262abff7e07282433c58926d562fbc6180bde6cd9497861fb6d955cf383d999fa1037b8b1754ce888c9ffc1560a451d0e9db8d74d2940604
+
+TST: 243
+SK: 5a63ef9bd7dbf0e89fef155983659e8a0a6ca002bc42fad5a45af8e0281923f4
+PK: e632f4dc994231cc1790c21afadaa977a589b0eb0da19fcb2792911b15ecf8af
+MSG: 796bc8361c6e8eec39838b24f53971e820f82361e0510eb4def1db2512387d6bf35bbdfa318879209435d6887b1410b3ebc1455f91f985e0fab1ce1c505c455576bca03539d048ad3a0ed1f11c73bac6809e2ea147975bee27c65261aca117df0fae7008e2c3c130bec5533ab89351c2140c9d1a62bdf688629787f954e1c610cbb75edb86209d7c357cd06ef41931dd5dfd1c7d407fa4ee1ef29393beab5713173802cce2d56229cfa76b601662c4d9a84a4936c52abb1981378b717eb55cb604a68d34f03b219f32226ca0e669348a2d8d2453930eb6e9c2bf66fa4e92c75136e148cdb034130d3f646382e1c71579ac70
+SIG: 75461f99650c0368058113a15ba16bd2337b2e633da38112878c4834fac9ba2e307c866c02af79bea33659614cbb4465c57ec3effd4c478ae38a34a05cf1ed07
+
+TST: 244
+SK: 8b2f06141e401163f90f674b04dc90dcb6dd3386419339662ecb0dffadf2500b
+PK: 54da934a659119198553fd4566b660d8d610adc3290cb84829c894148cf3f67e
+MSG: 1deb25d43458690323a7d26a26695090993474f467c6fde5ddb34da945be3cea2f6b75652ae21cbc4fd22763a1b45583e1c3e88bbb5fea2049b7336c91159988c01526824ca3bef16b362b9202b8b9754185bd61bea8f539aadf4a1ab135fbc31d2a8e33178073106cbbc02d4cd0d3c8feaa8eb733084356251795afbd78ac3c4f8a3ba19aed755c646f35569c7a6c675b6d6918e834969aca03f71a2e72ccb17003bb75b62e852aaf58b3baea89bcd64a32eb14a6b9e10de48971e53d0e9ac99a78f42de0382ef0e80ed3cfa343f35e4a9983b9aeed986d3a57f47e5e46d40e9d677302809a2d37e4ec011f051b4d031ed600
+SIG: d68e3750dc56432397401c98ff1529db9ed48fea246dd4ed383ec74c1a463aeb784c87b1fda8bbce970fc97aa9807ddbe95d41fb022ea68c1e311654fa1da207
+
+TST: 245
+SK: dc649fbb1bee0a44814d6d9e9080d5d90c1fc173ab5fefed826a74723a774e0a
+PK: 0214c89f3867ad2e8870e50f8c2a6254986d9c220e3338411300cd9c6404d4b1
+MSG: 328700a8ae581c1edc4e2c00c78bf4606097f9bd75aade205a243c5fd7434d6222da937e2881a2e3c574356d4d5679301da99e11cf749c27921c8caa2ab2a564d87c5df8ecf1a72b680184824f6986022e3fc98bd2a21c3455abf1154954fb30c89882947b02f35af7b1bfad05237d242e2b74832fc536196f2e59d1acd0c1db6f1943d0f6043bbd6a769083ed66ba0e05a50feb0acf72b6c16ba9af039afb7fe2a4aaeb4d06181c5a1878689e67a3f5d0ad39e794d6239a7e0a12ce820c5be60fd5f1dd79702f49d02b79755fe873f5785c72f74625cd7e2428262597d31482c2c0508801fd96319d61b91ba253a5e722f414cf
+SIG: 0e0c5e4e184375da4ef7e2a2e4888050cd84e2fe21d08e84a852db2be3fbc372c472de0954dcd1dc11aec493c569f40fc6f77f03ee524fb06ec40faa1d6cc10f
+
+TST: 246
+SK: 39b8062da43e64e1676765d62c7fb8e0a99c4fd417d6f7e3319bb13044205f3b
+PK: 6227cefe88ea4fb27b37b5f797778bd72fdafeadccd9aeb67ad437ce08fba6a8
+MSG: 740af679e3069fad059fa4825fa41c59fbd484aa649303c27c4f7a94711c5b713b2a6b8987859e2271a6a71eb0b4a15abde4f5168f6cb9dbdc6a27a2a13d52c9720896a1f4ce3a5345ee793b6cc3ad80d7d58163d5455b9cbd073e2b7adbff95590c7172271bd91fefdbd01657ee1750651036cdc3560b444ca2184bf4f3ea89fc973aab6fb4a8ee5704bbe5a71c99fa3b5ef0d0396249758297699ae202b819690dc7ac4692770346907845e2210d5363adeec03f0fc7761b7e0ec0fea1bcf6b04fc54b3e4c40d19b8fa649ac8479e8f80730c0c94e9f4a1ad506f2bcab0c49540f6decaa77b3d657dc38a02b28a977ece482545a
+SIG: c5f626490c0ef4e1efc3edeb0cbc3f7de267057fb7b6eb8f0c813584965bc5c421feedf54241cae001ec6d5e25c9b1fba0385e5dbd95a06ec1d8ae519144960d
+
+TST: 247
+SK: 52f4675d8ccd0eb909df0a516648db26fa033ba41d43fc3845896d456e14265f
+PK: f39e7dafc97b0a84dcbf7fa14a9403ee1fa92b85e5a7e5d05f031b44ddf1f794
+MSG: 74427110857cb4af0a3342c2b52997bce1a0db6405c74e9651c5b85979acb071e567fe70412c4e0d8c9fa421914f6a62f2ae420b7b2f4cf80c90574221222288b65867eaa66e7e0a0557a26c549f9a7a4e70838ba4074b4cd7a9d758b378b88dd49441df802a444dcbc30624933b59922f33c20f019fe78ee24b8fba79a682f388505ac9c97f4eb87c611880026b4c23306b865173f5d716abc6cd9a9906db3430136f754129c443b20c42be2fbcbcd44034d714f58a4ba8e756607a02b608ef49648f2ad0cea99e7ab30a8dd7814004f725f49301d7b304dcda625c296d928cb581736ab739c86b469241a8259351fd37b4780a9993
+SIG: 4bf668827a720af68898a06ea7b44545a34ca896ecf311feea47e0686d911fadaa03118997153c65361fea15de9bb891b8909872045508ffad0cd9eab21a9702
+
+TST: 248
+SK: bad73c9fda4ceb9da6c701c2a6e2efc0467afa0a74f8750c52cf1fd4c8e7489a
+PK: bb0f027a9035376e1aa3206c3d774475e351f5767ef86ef48a72c037c24cce62
+MSG: 74b966cb780771aee63d734df3756702d1d5fdeddf32136c6358b836318a4f984fe71e7716adddbd649eba44cd4282e0055d8c1ed2d35123d66e5a98f1c0838ded563b9a20eb8007538fc7b0713e7e485e3c28f6ebc421a29dce2524db7f29205761036ada62e5b0b7d5b7f294ff17f338232fa5fd42b6f7253304092d848f50735248595da0f7ef28e568e9916bfc56d7ed0d811b59d5d891ae43e1b198071306bf525c678c6343998005fbb7869d1c40f8cac807fe2ef03f3d5b933f58978ef2906fccf7444a2936e63d928c690926c9c994ed3d666263e956fdfea27764bc5f74125bc46bc102dd3e5ff93b5e123e4b38bdef697e15
+SIG: 197d6b6cc88a98c06dfca0c01225edfe38a0b2289f29f8a44ec0816a952d585e2d59b5b08de100c0606296ccf5e92a99e093623144b8b22db87d929225546005
+
+TST: 249
+SK: 707327a431dba77639b3966b2bc095f8eedf57f7a200e3b0077ce420389c92fe
+PK: ee2496910864189fdaa3c7757eb3cda9ab1e70fc9e7f71a38a0bfc845931c95a
+MSG: 32ef31b64eee700fca2ab21a267f8d9d3bdc689c7538fe959bf713fa995db2c0ad36dde430a8417d437b72c74e26dbe31d93701d4617fe51825cff7a544fc9f44e4345e14b4b11e15f26ffc2af8035f3f970e4dda44c0ebc0363c2b56fde218663bf78839092538fc2f39153d4eb29da0c1a08aa966601cc68ca96e993b01b173a261b2ef327650382f568fe944855b0f4fd9d15e752ac74dcfd37b3786fffcef23339c21e9270dce8891dd5eeeba9608fdc7b6fbcc99fa1b5903daa0968e1b691d19d06f215ded047ef9d76610f5de220f5041b313faf9e96c9fd7db54b5225726af435f9cbd9fd87ab40ce8f2c6940b55f0faae87850ca
+SIG: fb99029feca387a5d765961e361d7172b98b7e0f11290bb1e5b57b51bc2123d0bce29020392a4fec9ae6a72c4c386cea1857cb8f9c50aa9a76d7f1687fcf2900
+
+TST: 250
+SK: 6aa5c9f008f990473ba4a6286a416614026661f11e1a24efa81ac35852d1d070
+PK: 605ac9b4dbdd5033d6c828bfafa93c0039440aa11ca724ae834043e07bd032d5
+MSG: b5165d3963f6e6f9ea5657e9f07ff3a321eb338f9a8c3d3c42306b2b278978b31c623a631be3b04c41edfdeddf538e1b765bc8785401c1af29d0467a64411c497395d755dca03ae3272f4bc1fb1918dcc1ed6f04d6498404a8ce1409d447f570a4359522cc54629202ebe507ab693843141bd5ea0573b20f321a483ff383a46897f5926fe0b8afc25572707b63eeed283532928a4144196497942c572ac547605139256b0aa0eaf04db1a256012ed453b173ee19ad6e9b1af3f45ff3044a641f8c8eb0ac7bb45abbded47286b2a069d3908694ee06f2fbd0ef605a7911026ea9ea3c4913f38c04d8b69565a7027867ab3092d05f4cfb18fc7c
+SIG: 9756303b90655e935251032ab19cfc95ca1c2a2c3ea28b033bd47066cbd4c7d8982a8b9886f1b9cd02e88a65564da8dcc34f308ba9f10144ba469c2efa49e004
+
+TST: 251
+SK: 8efb8b79742be21e6d31de678bc81450ba8621082cd6f0003e22861e2291c481
+PK: 33381e356c4fd386a3f7b969afd9f5c00d2067b698b3f1f00f3784202d3084cf
+MSG: 6b750325d3a0f08a147700b51a9b3725571094818ed69d1f761013eb86f323f73c49f5e439877c2783b336d1f1a674ef3e431fc1ae0180082df5fca69f848139fe6ab6739a0592ebd6d4705c7f0136b22189a11d60d4d3c9bc80fe7d7c00952d5742f9c0c2121fe792df133f221db991fc960ee64b9d32e0178e542bce8efa8d03ac8026cd77ba8bf0b24215b9faed2eaec920e925d5ec46fff6bde725e91c8280e4ada232a5433ae9680ebb53eb55553147c93370574854896154514299c093219a111dca4e637ad5001338c6d4d5ee9098c65832f7af835bcb622128423036c79a5737738a7539f8d4a6b8b221b56d1401aeb74d4571bc009d
+SIG: 923005cb4848402aa8f9d5da74030b009444924c214ad600ddbab4c153a6ff022b53cf6364cd7ee99bef34fe144da964edfc38a0ba633312650ebf0e55a06009
+
+TST: 252
+SK: ed046d688b2b0a1bc3daf2119dd321a607b16d2a2d1d963add1209c665b5ccba
+PK: 8734f1ffcbd71cfde290017ea6253e580d59e65b541b46521f5e5ec1451eaec6
+MSG: b9cc90fd8de2a141f95116db3b04be83e98522597ec2174964245180b9a473767d6d470a217db5ff5a1ab777e1e28a0b16975e2bacb873020444b47ed8326421b90ebb503688f090c11b3b13617c5c5052c297a41e2893775e34d59ada49d994c0e4a9f5220e9f0315a67705a3ec08af0dc724b5cf67ff34fada8ba7109ed2b5a8907bb403fb1a838b4b059f18c792d7bfec05dee0c9cbbf1753409d7db3aceaf47b4c61398497b0eca6c1f8ac08a7ea1eb9c40bc4e92e888212f7d9ee14fdb73158160944ff9bcdfef1a7469cc70f9474e5f24dfffea585f09eaaab4be2afebbe8e6cf86d35680dc5d1b92913e848256ec736316fd0a2142063b0
+SIG: 721bfd4776cfba13330fd37269e979c1d7b6ce54a51b82f456e137378e582f192a12089da5aba76a7b161813dce56b72892a35330c94f7ff21d09cf09e553504
+
+TST: 253
+SK: 76ac8e570a39b3a0232c45497537fb2155acec3617865ed1df210f00b49d1b8d
+PK: 312a3ad899ae6a25507ae6e4524e10b63a6e7ae53d9cffd39cf28521d93533d6
+MSG: 53ced9db2b479e59d3ed643f7cc3784c24b8bd4c63206c72e23fa850028899a41ce1a8bdc003f12b7c29972c9a08bcd231fe0e1a0fef0bafbfa4e0e027d72004075ba37d490eb9964e783bb98f9e503e9c1fd3d23fb0017cc7c7a9f86d171f041e2355d8c5e6229d34c7eeacb6358cf3060d5d265bae2004a558878659a30dfed5f2ec788b4e14397b5d00c29db5d4ebf16639a8df292a3d24f6983cbca760d903e976f5b698642ba1fed49e79c38f4bb3946efccc9d6aefad336d558f78e4f205422e10384a4e531e75807efb389d2af4cab43825fb87f196a9080769fe7585782970a6918affe10d20d629b705845597418d699de3f1de854f94bd
+SIG: cf03f525913c44303b2f80079393c21c1158146ecf99636f5d97adfdd9f35839804c23804cbf1e553cfd4b73f689a9143aec298f8276e1e4ee0891f1ba75de04
+
+TST: 254
+SK: f64a66ba0f0819f3001416c220bf52d860130a19764aa8ab38d15b2aa75ac022
+PK: 8125253cd337e00d45b45079b585349561e5f542a81f6d2fcfd985c10feab2af
+MSG: 8072862ed0ab35921db5ec2cba8e6aedb0441fdf47491006c01e6456ad70fae3c4152dcfbfdbb8f0fddec5e96b12bf67989ba96793f4861a11b63909ce8d19b8ca64a544b31ce051fbc88e062806d9965cbd2967b01614e86b532fbf59843218dc9c19c80315f044731719371092a3da38878bc4cf77de972e860466b8fc45e465dc3d0ebf94bdea60ef0b9891ced41b997b11b31ee4167db60c9cfc8b85beacfe223cc1829213774085d7c06d2b2e632cc21cd9660df47c4fa918bdd596ddf622dcb652642b67527ba8ed15a819a8e21f48d7ee70247f5200e37c259dffd17eec8c232f970cb03182fe3964132993f6ecb7c4db18ccef390c9eb3639e
+SIG: 4de6f5250822d7c9d5bb98582500b5c085f541ebdc450ed1acaf83684827ed1dc77147aae4b19e14a7dc5bbe1f1e4f5771d8a6e4f2351739afb08c806d558701
+
+TST: 255
+SK: 8439b1d60aa48460135eb1002cc112792995079a77e6e8ab020b9abaca8920b4
+PK: eadc3e0c5bddbc3052c3b2f8b0a94566c2b2c879ed17034ac0e6a45f2b3e32d2
+MSG: 5419f6d24eb46635d4a7f8eab803cfd0d04de092afbd86f2a6961a8d1eb8c0d197ba55ee08c991822a5aa702bae0337abd5ca7faa15e1f1ae369946e9b81216c0f5fc22bbd4433c3de93c5caa2741683bbd0e1a78df28dda19174101876334d40339659f021ae766162c6cc5421b79cf9d5c090ed4af07ec84493035bd0b2421b533684295bbe76a70fec596ef8c89c5c9dda3c33b7735d2d2f20b28f1a5402e72d04ba291dd59f14af08adf56eeb086d769c6bec3451891372345fd6bd02dcf95e803af0353150e182e323aaf683e036d9a135d2e6f98cb4d327e2ce7d54247f3592ed067b4ce7627174f996f28165c9c11f07e5ee9cee63851c6b68ea2
+SIG: 62da81e16440821b593b6ee6540e15d1aea75d23e0a1bbfedc808c9548f87e8bbf36915a39a74716f645cca5714d170af907576d4f3705e543d2adddc5ff2303
+
+TST: 256
+SK: 3a046397f0afc072bc7f907c74d38fd1b9afdf27e14a3534768b0dd2df3a1c22
+PK: 99cd70ef3be342493393872f54c47deaa081021892d11a3268f3145ed4f3abe5
+MSG: f08ddef46cc6c34179820c9861375172fddf774f8dc3f7d64aa432da8e5fae644c0a8a9e6908517d505debd612868ac6daf95cd7e1699750022ccd4b88dbae2bbf73546ee4b835d319a842dae8b9ed683323f31e5cc57919bc9dbe3bcfffb2ada48072697ff4a7d310c91adbca81faf26a0eb7bb0c404ac9d8dfec63e9c64e2f420c07d323b7c0dc3b73507283aeb1cee51db4e1a83a692c7c1ea398f6f30940fab85e2138d4b85aa4e231e5424f5b064ed026f0ccb99d1c85a9eb15f5934a11359d411cf94ae8ffa3361a224f46bab852d184a248b4c31fe3a7e7f5134c051031a9f328a7be4a7cbbb1d8d863a400fd2d58daa44f1b9d8e9ddf961ce6322f
+SIG: 5024ce60257965687080c5b1fc7d1301c32aa6fcc835497d9cb23a74a6ca2724f55353c1b757827ca5440c9ef8f8c1050913e20aabec35c497b56041b5deb209
+
+TST: 257
+SK: 124f7416a80453e4cf1cd7b5e050a9761418258bf7d27beb7f23238c4540be2d
+PK: 0da34ab173990150df7399b6bcddba93c6dbcbf4d176941cb5071e8734c5dc92
+MSG: 9dcb9873ff054db11d0a9b19de6885ffba7f0e681cf7fb8f6cd950c48328d1f919ca46054eeee6c9e57843ebdda7b24bc3503c4d612abb1a314f39f58221d2b54dc755acca7969740e7fa8b1a9523b8c7379fd395253f4e6cd054ee24b75613c3581d49e19246a7b3be1cecb334be44f3d626fe3b7b269e628d44580c20636eba2642f2744b959e65757d0ee601843f188e95d17253fef567068a5405a3a9e677fea3d7d55f7ead19a3f30c5f985671b55fa120cb9d05f471b6e1e8d779a2c803a19e6d0d7cd507887ed647c2a95483f933991ed45ae301a2b0e954a5703d248c78810aa0b199cc2bebb2f1d71cc40487dbd42eee0f745f7d285685b1fb31b15
+SIG: b0572104aa69e529e3465a6fd28f404a4ec20276a993b1725eb8c5f650b4a216f1871b24e368cc46cd1ee0174cda1b5e4ae2200aa9fc44522d975a9c51814908
+
+TST: 258
+SK: 25d13b3837601b07a975693e5a33d5337c34c1127fe4c27490612aaf7f642e9a
+PK: 3a07cd68ee2692d51cfad1a80e7763b18a043c74f4e1b01edc55ba9a9e07795a
+MSG: 115b3220b45ca8f36c7ff5b53887d47e669b78dac13b98cc7aaca5c2e19fce81ec8617ca410e11c9a9118a668453b329ffb718eaec739172f0a849a0848192a5bdea18ab4f60d8d1a0d338952d77b2cc13efe83c76e8dd58803b1d8b3c9729ef102b20835b7de872bef3010f15a4caddf07cf7bdd222d84b174bc21527cffb1b7ffde81e281d30cb7bce25ea3dffb6ea1fbb06cb70569a95ed1a07e97ca42de70aa218159efd608fa9b0896e0b58518a322f251d133e58c8fc1428ab0a170ed845c75fb403f1ffb97d2d2a6d4f277911d326c1cabbb8516cbc17908ab81ff8d79af44611ea1d05879c1ec81d06936e0f4a0aef6d5748e181d30ec25236597a973d
+SIG: 20cbf08392fea6a99cf446a95c199caa0c0f9813cc217b8d228e2ed90bab95ea92cd73ac95834764d33e42243c80a7603491c8d3e49ac715fd8a5b9e4789bb03
+
+TST: 259
+SK: 7b3a76decaea60c41e95b05877a7da82064c27278c8d7df5f0bb95f0ad2d0435
+PK: f80db5c28721b1c611bd87eb145a98bbf383b068045df2458d1a6fda099f7fc2
+MSG: 375fadaedd9cac49b64e1574028046069f4c83654c8a7011abdb64db16b47fa311798172f9072217b0a6a43e5df6ffcc1154bcec1c68e1d35ec05880d012ce76e4cebf301bb2ec983d00b4a0540c937ff1c6df9441c61bdb3be8e0c7c11a35d49b6f55c381269a0e768efbd453447fe48b75ac39646ca82eca7d149304423491871c10dbcfc5973a57fab8371c30cbc4e90becc0b67152226ee177b4ff368ec879b391eb95e36dcbb07b2c16ba395545d4529f727b1a11ef65d120976b7ccc86af4bd204cb9489c921e43ba5e850cfe59899f1c1ec4aa5c92b6dac6914b1952b53dcb540b409231381568987bb2236bc40895df3f17eab7c0274f2244f958612e88e
+SIG: 2cd26fb3c4f7440a72affe93564f6f6559adb15cc7a2ba10879fb7d67e47d4ebd02fe4823698a5fbd4a907fd69184c255a170e5f1747fce968102dc219b50d02
+
+TST: 260
+SK: 5ff8d4052608eb033a5e94b603ce384d8452f60a26498b9112567f3410c18666
+PK: c4900de24d9af2482763109926af7c481380fabcda9440c1a53ea1cdc27e6568
+MSG: 138c60557c2e9008afc03d45bec71f961149a0835926751c8ff3935c7d652d83e1b0b1da7d5bbe0b8e171a4e49aae06fd8a9deff78dcde4d25b1aa899998a0f99e1df6f9337a3ea2f24b76c317a7014db4e5283191795a70d8821d217846490f958701d39dc2c8ce47d928938874d87b3558989bc77af820979a351eef9594aa5b94f3341eded4ea20b08c3e7c5610d43267818dfac0a87ddf527fbce8512bbf85b66c9bb5d62f0fe84048f23b19604a5c8d82b1f25a8da02731feb2ecae489b8475f7bd326ddf1a08189e46c08cf50538c2a363e2f4eb2c01a204c7ffbc0b981adc0fd997aafdf2a222ee84c309f6e95ec7de4fa85d4768d5c003165028225e22e09e
+SIG: b737d4e5be27deb6d87729c636dff7a406c013f313c38cf683fe14f75a3b3005d9535d7e5815c8f8b37c51d6927111c979f7d9d81a347aa9cc09ed4e6c18e90f
+
+TST: 261
+SK: eedefc1757e3a7e5ed3946dbedc396a362f683d2c51b0b9f60765d4bfc5134de
+PK: a9872bc2192fc02b189ceed403ab9f270a032a835fdebfaf1c9d6934ed8304bc
+MSG: b194db73f994cbdc3cbe630ba72c47c2249bc0592ab547942b1d1b882b44f5b3855e568bdddf92ef05022d88fcfc294e76b64a00e9c74355373763e49a4ebc47243d48a9ad588994a518f80f8615c2b31da587a53e529d435a8697350dfcde02d20cce7d5eeefe3f5ab2aac601259cda38538a1b8301f9832e75ab90f8a932f267eac181003965d5266f206180c6c380ece803577ccb46176bf607159486f24259747e2ca6fb1912db7b78a973b2846387c1208030ee1f400d0c5b5e8bde9635ae55638ba17c734de8638bb85dfcd76629a7f9f40d6ab954d55bf8575fc9c9a595097e0893db5a7b8a6c455ecbd3d22d725e19de2941f467f9eb93d66a0e2bbdbf92ed1c
+SIG: d5bea8ea9a5fe9ed6d2bf839930c0c6cd5039e988f551fdedb5437e1c1af0ed7b3897c035711c3c51926be8d1b32024d5cd582f5f8369ad84d18b12502652f07
+
+TST: 262
+SK: 09d22bbaa5956cfacbbf9fd5510975128686c40c6ea96b89ef4c0f0c649bcd7f
+PK: e559ea8acbdc61b6709a7d83ae15849a6c78b203923dd0a299239ee4886930ba
+MSG: 1c26a0f3a1a5b2d7d5b297af8a6a689d7c62a25267e197d23becd2f2b816c4de92fbdaffb941c3fc8db7a84335a84cfbc92cb3ac806ed58df16b6b8e119a48df4f27c71e931a5938e7d002734885e13a258a15b6e1136efba72f1d096b689f7618f49c968063e8f991fa0b55601e430eee13492a1b09413eb23813591a7a9f070cc396ca9d1facdd4f4ce37c40f7245f55035e10fad6b85b5f01a1daacc0df94069f7de8f6467f96d1fb98648e8a0520a8cd723c98e9dc2dd4b2934d8228f0ae1a415bd3a7cda38d7a9983ce1af6f8c970a2a591635fe12b917536ef815eaf1a3138d70ce70a794264d7c986d9ee3290445f15a9248f2765271e5a992196ae331abd4164bf
+SIG: e65275c4328a70ad62408ed7fb1728be87a73a814fee8ebd94f2665c71bc66ab0c1b07a600b30bc081a74c536857c20610384be268d9af3e3ecddd3eb0c14c0c
+
+TST: 263
+SK: 77826ed351a3f09254ae5692885d774cb3f24410a4809fd90f8a00da9aee9903
+PK: 3eac8f41ee73e6ef136821f7957a1c27e15638d0e3916e6caac6fb7beb7bcfb0
+MSG: 1ff06c0b3999cecb1900a47d267beafbb35d93d14cb2c8925e3e3fe5d967586925ee4baa41998edd0103205810aad5c0bbdc77874476810246d13089a64db576424fae0bed9664a42a491147d1ee3b9c3b1ba4875be15462392540f9978d9a4630ba4c525499751a45efc299ec7d73b17f9ad275ee71a687e72690d7320242d2dc2bd4d5c5cf0f17a465185dcf60f8efff53903f20b0c2ab2192d44368f2f2fb36048af071f7aa857b14ad1d11461205bebe17e02be2e3ccb6092821885c4e0d4811be3f45b1fea088453e022432f562562b43a355cb56270cedb6c2c42dbf9be850e77192fdc65cfd36834be988dbe9a93e2518c138b090fb9da827cb1c91c8fe52fe7c57f7
+SIG: 977adccdb829b40bbd8e53856a783db346a39dff62041a2972d29009f1c9ff81b8ad54cb901e497c1d3021b50b6c69ee73558fd7be05d625f5727f9af2ce8702
+
+TST: 264
+SK: 99a99531c3cd6e3e9c900a9eeb26267e72f09d11b651a897ebb79be016f64c6e
+PK: 9bf9f8b48a2728e02608fc19899d219656839d1cc1e9a8984df674ec26662f41
+MSG: 7a89c0c1952fdc4298dcaea854efc134656be147e9e8e82fc9a449059d80570f75676b81c4a94f76a968200cdeb0988c73f59afc72ad4c3103e19fe63b7e95e140b5cb2efc7b97a6ffbb6c298ddace3be6d2ed3d598b8bdf0c2fe6c97602142a76e978514c196c1b9a88efdc1925fc506155cff9a2f21ab634e2b93e96928a5d8f7ce4cb7326d9689469242ba9c6a01b77496badef87578f5a17284e900a72df141c6199b0e71ab5da4375037617ec6196d4f4e23ae2916a72d0fce796022305ac9fbbbbe4705b340e42b78e1c02bb1001860cdcaf71ed89255dd56cc0b31c59d4596dcef84e22234be562bd801e94111d83a78064c90f9d82fce91f68abb03c73b6bd8d7e02d4
+SIG: 0e89da5d949cf2bf40c7e17c2d0f9ceabc88a092eb4d49cfbfeab7c8bff43245c67b9e2e92f9bcb9b34b3fcf8b01fa2ea7a9649f814c3aa98b3dd04540c31d09
+
+TST: 265
+SK: aa58403e763bac405db065eb11eb6be3e3b6cf00ec4a222b52bff4b6e3d156ac
+PK: 167f9b9a4665f93f5d7d3016ace6fbd13420b2e51e72bde59eedf26993b66cae
+MSG: 3baa0998ff02b32b90b51f9a840c7b5c5870cfb1810a9b0f77b55909d47ad335147a991c29fbebfc592e9307175c1964129a2d5efc6215807453bcd726969781222bcad1c99a49748b9ee667c4d0c82889e2f50064c115dbd8fb483d72ab0ccadf76bddb2dc727dbc3fa5c4624c283d8921c8aa4425110dcdd69c05e5ed59b359625eeaaec1e27eafe9d9a5ce736c3f9c527ea547818b9bca6811be4cc15058a6f5b683303b80c90c94a83b8b15869713a66b1e0f656331b286d1ef7698834ab3e138417aad6bb3ab3bd9fc78761a482dfc654f3f8628c8d9fc16018898f1641e8622bd272e38d41706cb9cebe6ee5e173576bf61bb1188cf2f39c62220bba88fcb4de4898b25b04
+SIG: 64b598ca5b8f9ae742e46ee0d8c1aaf31458b50c25d267a677e44be5b755f14d51801a30399bfcc38d14071aa0ae93da825a581ab6c20725a0a910b4735dfa0b
+
+TST: 266
+SK: 1044ee3708c0b0e909a8cb2ba2cd0af8d28a5de01d962e826087fb232df7b2d2
+PK: 46d241ea0c702c1889d44655824629b67284d4e644a48fa45455d27ac5f62529
+MSG: b8a445455fb66e17e3143d35204c9ea93474eebeef93963ee5c1d377ca217acd4ca63e5755da08fbffdbd4352bf165193896c8d6f76bb4cd3bc2d3a476a4e320824a1210ce74d0014d747f111eec310c5c89ed4d0850e811f80a8bb28dcaf6f411df83e2c1dfd90c4ad23561454eb5d756b63b4ea7f37dc5d466c16ef70d11190c4f5316fe2aa8597440e88bbebaeb35ea5f04f07b0339264158ef909ad5163bfc248cd724133e274f812695f290e57176a96b9393d07bb310299f5d2a6b6dd1dabcb51bf29c5afa7ebb0701c6c84767ac137793091fe0ed6e47d780628a32c84f83e00e9c16742a523ecb63c24f4a338ed299a06194924f44c5a5d3c937ff9b0945982ad24a2d1c79
+SIG: 7d6bed7f87d090abe013c31e1203903bac9c93445d06c7b53d31d15f970d88647a7ed2c3a63050ba19d68043aadd18bd861de1ac4715b8e828b2b16f8a92b001
+
+TST: 267
+SK: 95dd1a5e658fa6c8d42507b3e5b8edb5baeca62deb00fc5d4dca8e1ab5835e59
+PK: 3a5323dd1e07f323bb6d83e9c2db92a29f62e2e003ee0deacd7e2e4e030d8d27
+MSG: 9b7afd48c474604c26367531556840c388668b0f3840063dfc9869ad5b901274b931293d04f3c8e8f7f8eab815a641d7c351284e8bb0437ac551bb29438964e6a7c7ba772344b333f9eda5a77568c8931ddcaf21e32e07b10bf4820fb859bcf87b81c4bff426f24a4d468f2e9aeda8f17d939709970db11df76247e98a39eb8b38f5949f349f2ae05ab48c018517c48fa0205dc7f1566453e105e48c52eb455c0c40802f797b3eefb1e2f3b1f84315aed5b0711c6499a691b74b91f12ef70f76c4c05c1aa1a993e2f3e528ab343dd2368162f4036a61a13a88045dcdefa85d68532275bcf5b8f5f00efdea999a95783175d9ee95a925d48a544934d8c6b262225b6ebea35415dd44df1f
+SIG: d02a7523dcbd29576ba809b531037774df41734a41175813119c6a6a788cd9b8ad780865678667699ae66d010919a966a051c08163df67a977ee6e220d0dc30f
+
+TST: 268
+SK: 1abc0b9aa01dc57ca53efe7380962b1a88d50a964f5cd98640982c74393f2926
+PK: 8d4fd14394d7c1405700306983fbf76ea9f171b15a6b56612a1feb1cbdae5dd5
+MSG: da2dd940d5e1db6e80bf7e2b782e7e745cd4fd252e981517975887dd05ac77ed837d082961575efedf301fdf24b70718b991b8d92bdd2e6bee17c8aa4bc694a727bcfc78fd85195c42caf883a2c38d161cadd79cfda9a39110e1264d30bd4c5c4a5876777f233b071b1b0b408935f0468954cc744af8063b004ede56cd981c4dd5608abffeaec9e58f3fafaa671467804b7fa2558f4f95174201f183d80a5914065fed53115b41ebc338f78df050053b8a4e75ea7c6fdc354dad27bfd8a2e66fcd7ae2f587d24be0d4a33da30a220e51bc05fa4e412b959fd95d89ea6ec0162516c096a9433a9e7cf599c928bd5305c2173bf7493ed0c1c603cd03f082cce44237a79ffd8be9a672c2ebaa
+SIG: f738af2d3e290b3d23d9aff7414bfc5ffa47235dc053687a8ba5c8541b8511f781566cdaa130e0677db55fa8be9d81a092cb58923a8628494d2f62d95c167100
+
+TST: 269
+SK: cbffce2c9bd3e23e406e5f66e632dcfa726654d29a955cec983173235fa359d0
+PK: 49653edd64a55f7cd40eaf3f8e72eb96dbcdee398f34817f2c95867949710b14
+MSG: 1ffde6826e4f0c24a7961f191e74cc0bbc928e3f1aec3efab32765c2501cbc1620e7ee6f61fccfb00cfca9fb98143b529bcc8c3d0fdf89ee7c342f101815fabf7deaf9f302a288fe175826d590d99ee6fd92da74f9596b783c0e7d47d711a32f39ea4165e5212431441b498c6b70db3b09d1f4e4a14a6bae39da5088bb85b3285ce9df2f90681af2c74dece439aeb91e1c1b0712eddbee8d72569828f37cb720c509d02aec476070484e9b16ec7179947ac96caf0e1be8b6b74f372d7235fe6e3999df733bccd482dfe2e631f56b582667dce5e3121763adfacf3b18cf2095f7394dee4927fc2bea6b5824d90cd59e854ec5872b4551b02efaba5ad54a9b7a8f6de5d7cda5825b325b076ded
+SIG: e7ced4fa2a7dff73f1068bbad0ec9a1109043c97a62effa148876f0969ed4dc608e28bce797af3b82532c94dec4d6811b7f563679129facf17bb73d69375eb05
+
+TST: 270
+SK: 9f91231497484cab39b9e20f861181d397908577bbb2968242d071bca4813ffb
+PK: 8824bc6cd6a6f15a5f41668f2b3bae8fc4967383078d08b51d6d1b2b93a1071f
+MSG: 21d4fbc98163c3fb6e09f775c2ab7b18b18792340bafedacb49605622e3c08aa3b2b8d0e0902f361aa1c0f652e2732b10a0c5c6a05098996b588267cc8951a78b5d431e7222bbb508eeef1b5e8b8d01d3991e18dddc6ca8d222ef177ce62938d1810eecf06f4738b28f440946ccad2a12e39d38611bed3a39f93419a179ec2b1b52d5fe5c80c23b84d8803755f5146092cc199b4bdcea5bcf2037bd53ff6346694155f027d8ce2baffe30a5666596c00783aaeade9c77fc8637942ece017d6484c2899b1918d3a480bd5157678d4772d271f9b99768ee1bcc46b2489ae87cd030f47d1333c7672cb902cb4f5fe746e853de57940ba2264d3e629644d653a5b7af78ce64a993f36250f8cb7cb45
+SIG: 0a1c706dd8a13077ab18386c65fa97cf9dfc43542d1846ecbddeb7b3c93f3c66f3ccd0447aacdd4dad8fbf736c4ff9dbdb62bfc14d8883e385bce9bac56a350c
+
+TST: 271
+SK: 1e2bd5487c5f5ced461f604dccb4e78eb91608f0b821f5afc4e3e534f7960392
+PK: ef825475cf2051a2017ae532f077d96774347d2767ea7b45f9c1b860ab993506
+MSG: 1dbbbb13cdad88854b809ceded273343d306a8deabf3ff02c9cec6f002b8e9e10ef5d1b0f5711f33267aa91c171b61e960f740457b81d751a473f44f750a080cab80af7ccca7dffcfac9ee4c39dc85cbdf51259ccd3470d9bad3ad30f4ee5dbd4fac6bd5c6c4df7311a470044695a7e1a7e18572207588afa57eebcd4d575b6d424457ee92465ce1863e3c677cf875fdb98d4078ebe7144260807052577144cb8e0359aa42ad155d79dae3deb99c4632c191c799cbfe587d954787068d663bdfc0fab1334f1876bf498c4db5c53db7b0204ed5a521c62f09eaca8d0189f3b394143f29c421cb5c8d07bd751baf4cbe3bf4be1701df4b2207dfb2904d84f4dbda51cba576d5a5bb16efe698edd608
+SIG: 4d33c96a2e3a5db7391adf65c1cc3565fe76eeafd0b5c7abb0b492a0b51e1fa33639946a243b2ddef357552298ce0aa95eac6fbfe660988271877eb2a7da1806
+
+TST: 272
+SK: f78db14d6d1a643dd7735baf2635321244e7ec8ca72c5c38c98c809db9cb5a55
+PK: 5414f75f52f3864afb0c79c2c5c1d06b4bce400fbddf17fe9cfb2a8bac47a0dd
+MSG: 05caf1b8edc3b173fbc1ed29b95e2bf06d814ba2407d4b31c728d04ec273d25394423ac7d4fff2ca36ee90273093c756e2bd13c96d4a3dc7f5be1759fcd328eb66c5882b58fa4588e5b2a3713a4154a2340d0b06ad019601b0e028e497f898256b028af95cd8168df5e58a57cd1ebfc0a0c91ced61dbb480aca7df8dca91eb16e98007cd2cd1a2045b0e4477d12d5a4072f365426567c9d61577f3485c8f46605e7f475ef04a3948f60dba8c5508d14bfddb9b11dd044ef2d84c16b9a9038d8e78eda43b91297df35f4361a383b41d49677a687d5b344ad1ab0fc73017b3bebf32306fb3fd7b3d5071f3ab5f6e49aa15540cad6503bea7784cf9421801ce1385839893362a97fae121300d6783af0f
+SIG: d7cbd4181f67712007b7f0e18452e0a024464d9dc9b5ff9cf669d1b91169d7573262f83336b97c861bfab3fcf669223ce8caf319f21d23f1fa331a2d89b6ca0b
+
+TST: 273
+SK: 7dfa328e90a1b849c219e3da832df9ed77448234f0d89ea5d17a3d64e7883daf
+PK: e30ce6fd5f5800389a70cd117364f59945afb180f229927360b06b4835f8dc91
+MSG: e5e495d663f47236714532687a24308f942ca9c33e088f7f106a5a723518cacbbef4a68c939a6950b2dc2589f82d354e575272d42b1383d315ab8a20aa0cdc9d4df678ab3b26612b5dca66e71f9f3fa7d9e731dc481e2bc7127cea3b6203ca6cd8162e90886a73dc46c83ddefc4b9e2d53d29dd387c624e08bd8d53be928a40a9aa8ae8b1c8d0fb6a7bd6dce5f62315b7a2181f627f256bbe7e2a95bf464e6132204c174209629840235b2c39913301a4b40325d118d384bc7ac028cd4f12702e161191b149e4209058a55122bbb8b22b24683ba4f8e2e6ccfc08dc8c8b1bcfb6d60bd8f062196933df319ab16906d085730eba1720d4b02c67daf38cce6aba38e25d68ef95b2f521913a1d77d5eb650
+SIG: 1c61d53b872f8cde598609682c79f6c5df007c513a71cfb3a06dcb82d85c4b00ccc40b00e59f595393088b4cd0432855c67a207da71f87e72c409b3e50279507
+
+TST: 274
+SK: 6ce13d3c2ec71fed83131a69d5d030314ab49e6565ef68163fff09ac5d9b47e7
+PK: 9c7b1118fab91e0e7b192a23d95fb877cb7936cc6c8a330592f48e6784edc292
+MSG: 10bbc311eb2a765e0167ff37618ff70e13f02d7b0617ae4ac06befbbe149c972a994f680ca4dc9a92ec7efa53997fad356b9ff4ebdee629541d1f4dea62ed0d2494f9ccfdf07a9310491f61c4b3e2700b4a3c668d678329a38c2eff9d8cba431fb959e7f7655bd0fbd77d53bbbc2eb8dc51dd718ed98728a181686be122b844d3da331e329d3959b5923f7734325a021026e2754e17a15108be801465ad958dbcf21df890cfe5d5b883ca43c61cedccbdb58b849ea75374f1e918e803e577a5dc7a1c17936eccfcd3481bd2b1eb075b83237ca6f3c07c19e9af9731267be82d4898eee96ebc900d48b059d51b0dd415b1c890660a88d25f5c5f35d8e45e523e0ce3336923ab43670e35c5057d56c758876
+SIG: 608b2bf6f6da05c2ac5bbfd795a2ac32c79c74153f9431dea59768ff4c225e3b693b645a506766b860850ee97ea43032b05b69e56767e8eb9d1918df9afba805
+
+TST: 275
+SK: d45ee69a5f1a7cfdd0343f8770d1c6bc026f067a70dbe839a86f2aa068c33f81
+PK: fc8d9fb0e4f34793090755e0328096e01e281ea351b8d95cd9116e131a5ca54e
+MSG: eb5ed8ab79cbfe61c25981b9d1d6b70f10b60194b4161fe17d11aff1767994aa0813e9ece2f4c5d531b99e8adf1888c30a63893eb451aaf55acd5a52ad8c401faa88d6eacf3e49470566114fd0c6a274e9544846b0ae9bfa124d7951eb26715e19253ff7edc8a70965776f23ce46031e034a200723ba3d11e11d353d7e7cd84aede267ff64bed418cb9f28c61cd0f63b6ce2ecae14b20bc6bdaed8c428bad18be4b7d66338364acd8042a8256f258a69969b8d3ca2eab3aea3706e5f21c3b1efcc254a824bb4e7ea7aba8827c8eb82786c665aa973821931ff990a63fd34a74a6d8c22a882b0b935152ccb36fcc76f4eca65d67c8680942f75dfad073439c0916065e83877f7ba209303f33548d9e40d4a6b
+SIG: 156c51c5f915d89b8d1400350f8f217a5c02e2629ede9f4a30b6e71d1ea7a953cc6db31ba5c778c269920b649fb4221c6d38cf2cea2a7de3ad423e04faaa0607
+
+TST: 276
+SK: 8a76eaab3a21ec5a975c8b9e197a989e8e030899eb45d78968d0fb697b92e46d
+PK: 2d9c813d2d81e2730b0d17d8512bb8b5d33f436cabaa13e141ca1cb785014344
+MSG: c6c78f2e2080461aed9f12b4f77c989b19716780fab60e6ecb9793b4bc7ed69e5f70fa6bdba16e9bd3194969eea6665abfd630deeefa3d717b6d254dd24bc97dde21f0f29f9ed34b8bd7a013380f4f82c984fdbd95af9805b744bcd952c5a71fbb57d11f411c18cc30bc3594f7ad8228cb6099394a1b6b0a818581bdf93cce58f3a4a23e55db3e69ca9d60cfb3a907fb68329e2ffb6c65f1e828d28127109c9e9fb70160f2ef82a2ee9f9bd170c51e13fd3fc1866b22c79fe6d5101217979dbe2724dcad8a9bc69acc42c112dc697bd271eea550e9e50406bfd28245b83b8f012d34db6dbdd55ae6e575745c153d6e7534901027eadc2fcc33a5287ddbca6d3aeab8972294dc6c712b9942547277340e7ad19e
+SIG: fceecca4b014fecd90b921b0fa3b15aeaa4e62caa1fb22729c70269232c33cef0d0aeea66432c128afb9a3646bc7f03a12774da8758398c2a0dcce0bbbf6740a
+
+TST: 277
+SK: 18a8f93648cdcf47133630af1e11c0ceea3de07327314c96580df775597d7a9c
+PK: 2912f41ab4c87e3937a03331802cba87716b4eea14b9fba6f546d0ac2c0973df
+MSG: 592093ac7cd671d6070b0027edac1fb015cc205d78bb603f378eb9f8aa388ca830db3cb23420c7e852db0b55241eb88a02cc627aa94143be439aab4bf2634757470406e842f20eb10f0700e3c2da364f588a8000f23850c12ce976f326d2df1bac13e95020b412b175bf74bd7ebbacf3ae55c0daebb5c010bf804feee1d7d49fae050bea55996f53cfe1f15a0cf20727db4ee311c260bad9682d7b965e27a9491f471d4a473aff646c7d424d5a0bdcbb8a0233f4b3060dd04c98ec98dfd05ec7247884e2d8e152d4ae52b3d5865d9efd6706a60e088e1e7c9f624510abc7a2045a2c7a7588e2535e73191dd5cf05421563f556a13e8236670343cd5ba4d466e245c4ee3b5a41e70c9a0f5e6ea2c559ebe61ba81e
+SIG: 3b77394cd69f8b45d00cfe3a79a7900628a56518b379ed8a11581fc3a376e5d66807df11e70904f696c741d21d139310fa1b89a93bdc4d2c3997991f5220ee00
+
+TST: 278
+SK: 206cd2b8114aae188d81862ccec4cb92c4ef5fc78c24435a19f9ed9b8a22f47e
+PK: 97a67ac2811f529456df532737d76bed7e387da83bd55459372fdfb27ffacff3
+MSG: 480c4800f68c79f5dfc0c3666c0ac429b30fe0c5fe848750db2171380b80c8e9fec0a054b16d08674cefe2f64ec28bb6b0596b35235575f189bee259aca766c222ac0a46cf2af75774da4e34a0b54fc2ac49ec8bedf4887cd9b7be4fdb7f686902ddfab04627e26ea2dc3d97d62a4b1546180218ed8fa113334819b5275cc54afdee44309008596507971675e6d8b8a8edec4718f2d4bd735213cbbd18791faa8054174907a7ac17d7143a4757e493beeec4849d0b836f18bb2b3c9016f25af47fb96199251720549f15d149503d41095e25f26209daac39154485c3ded7cb1a8c3e83a52f5a06ec09cf83df00726b7968f64c0cbae299512fb438560f04b3b644346f938ac8e90486614cd844b54eae078bf678b3
+SIG: 73a40d9da08fb98ea25b67e721557a1a51225294d316b53149af895fa4d63cb4a3f56f688566ef6da42fd2941dffa06d497aa902165d50213a6214116299a90c
+
+TST: 279
+SK: 59b144a708abec972729a04a6c13f0ea020b4ed4a48298023a568958c21215ec
+PK: c4f4720092ed6179a082ae4d6145df3771786efca9bd9bb79c9f6667d2cb56b3
+MSG: 3857bd260b8aad9d073f06765d37fe893a3f53e23de866ddac33495a39ad33ee9e9d5c22502bc1c4b5470d0e3f3a585223fe4cb93cc4ad2b5ba6d78826a53fc0253dc580a2018cc9ff1cfedbd3ac0b53292deefbc14e589acf496cb5f7670130fdbb6cf38d208953c015a0474675b724bd109f7cb89c33016751fe7aa785d099d09ab20dd5258cd764ac8daf343ce4790ead0863af43121aa527a37a11628f47869668f8eac00d80b6bf9906663d7a2899c1cb678cd7b3eb3bc80226b8b13b6e46877f38f07c3d9c86d3368baac4a6f6b93ccebcec9811474b6a6a4da5c3a5966571eed05edcc0e3fe7cd15915c91f44eee8c149ae451f375518a79fb600a971a39b9433dfa19f91931b1932275747c262eedcbd27f1
+SIG: 1a80850fcbd6e643c6ba8eb684dbef7df015159228daedcf0604709186054db185aa7baacb09d6caad01638eff8e468735a60124de0c5376e94340e541a98007
+
+TST: 280
+SK: 8d1621eeab83270de857335c665bbf5726e3722225fd016e23bf90ab47aeec3d
+PK: becdbc024dae6a94ed4e29c80f2aff796aed8feb2c1b3790a8c72d7b048a2c61
+MSG: 97facddc82cccccf788c31b3305e93eba956f89613e6e53542b043267fee544c2b0a8ae8886a31b9d321a63c27623baefea840b2a8af5b2330193ffb5baf873c335528afeae2160163c851c5a2e58154a1b0569c2d1366c0710437623b0e08c686e54fc279ed4c45f3e856868375f78224c777b13d75de10d79173552425d15a561904155f2117b2f14713eb0b04648a3bdeb3302167d1973e788a06cb00d48ccb269fa71af8ba68eae55dbbfd9594d5c2b4dc13ae0321718561acdf67dc8cfcc25bc46bb66e096a1941d9335207d3f7d11e8904904fabe3a50a3883e7078047df252f38b67cd28a6ac45c7d7a1d2a1de8d45747cf09301e01cdafd0cd99a6e91b704d509fce692fbdef2f71a5ce0b35bc15c65f876824
+SIG: e08d6caa5f39327d6e6652ed74dd1a37844b979f5cce747a606f5679f4898bbb7643df7e931b54a2b40ebdefe83003f61ca0f11112f023c6a3e8cc18cafe5f0d
+
+TST: 281
+SK: f2735d50ee3a9a65b58c8acf551663e98809ec406f73e3e7f4e73bc4ea923874
+PK: df48a5b94a07af3c2c99b8388762243233c850dc175317d602638e5b86ab49ed
+MSG: ae31e94e7197e4e4d0239348025ed6681e513ce1a6e0aa0e5b979373912150ef113e50ef0569c483f7568c4bbc4703c5dacaa80a0de4e738383fa1f10d6d4071a31b99e6485143972316c86522e37c6887a1c307b29b0dd6f9f1b438310af9d8d7346fb41f9b2dd2e80b14c45eb87d4ed48e37a5260b52257b3e99787a13c55392ba930c08e0240e960def0c29b8550745cf149dee53a5d174ec065d2d6677dee1fc42057062c34e27ea5dbcdb861b9f670c6032c7846cec8e87a7c9520e27967b0186ee71b77ed6d029bbdd70949cec4a709329fa37fee002490cc1bc4c2df6f763f9858f33d750c5b505a67e237063c0486f9456d3c620d9ac7c98f1381de0effe41c18259504a150d68a6a28b0a3eea803b855315c9e0
+SIG: 6942a7696417efaa591b95e11f02d763bef5279b932a8e2a7cbb9f583695c14ce5cc556bec66799b33cb592da4df2735f9eef2c3ceca4362164b6cc93da4e105
+
+TST: 282
+SK: cad9d21a01c7e1d15df2fbd79c516eb8c3401e9fe28467cc7b21679d4e331a3d
+PK: a7b55c15d6790b40536fcae5ad2892cd66b18689f499c1fdeea66d4a7df39424
+MSG: 70702bf19c919f9836defd7b846fd9992d8b7eb2e106aeb71e60a31b4ea25a41b212dc7de7c91cbd613d58d0595db833cfe7e50584f25569602c7744fa675d156d0f63cd2b7c089c8a00686a437169826a12dc485b38c068a8007142e5163747011a07a415683622ab1e23ce577c732ba14f401fbc3043e0693a9205c19a92298a3d9b08fb7afafae0a9f016bc750ee631a5f5da5db6f9ba2692c74caaaeb4d097e90e3c02d2e3a7fb3aa000040b7c17b74564e646bea16bad611ebc0859a3828804ab4f5cfba417d254515ca3620a3ad683c46ca6267bb49539bb30e369087e67438e9489562750dccba3aa0b1b0a6c267032d20c2adb75e68df1123b5259bfe4eac6cadca6778138a37318adb30e8d669f3bc9692cc74b68
+SIG: 31927d01db9f2472f4df6f63c18ebd83c2b1aaf88d580e848854df8cba6395d3da7bd6bb9edc1fce1c7d7e1360558fcddfa93915be076efb8ea2dc5ea7b20d0a
+
+TST: 283
+SK: d9be842255e9a16b0a51a8674218cee7cd9a8bdf343508397f4ddb05f3fa0082
+PK: 7931bc6dfa3324943aab183d1285515919399ffe0b710677f0915d3a5be51e92
+MSG: ac6c55b134663e41f02a6dcb8549eaa1c013f59658d81d812f95b74009513723671945e1324f90f8a3f971369181b587bab45665f788d663ab78140c5a22c1c18d4afedc7448a748afe5bf2387003c1d65ab18482ef98922b470da80ad14c944951ce4aed37390cce79a8e01b24c7dfc1141c0eca2c7f773ed4b11806a34615513486e4ee11af08078a1b4054cf9880298608dd9b3faa1a242a452fe511604b3102c313d14cc27c6f0f8471d94555317eaa264cdf52c69e18f461e47903d21298716b172ee9cb178f08ff2d3c9c162121c2ed21d8734b2f0630d399146cbf76e028a143f2bf7bb50af0f57b9ba8021d264b00c6662f84c86cb6d5952b3d241f7dc3e700c96616cbcfb0d0e753ffd5d21ee320e65e97e25cb8609
+SIG: c93845658c9560d2c0e28f282adbd4652bafd3bb2edec17c94878f7b94d3c77afec906ed292a8dfbf5f8e7c118e8f2ca33dda7909d9b695b8ff5a1c0e97ac807
+
+TST: 284
+SK: cfc48cc6f65811fe7d7bba85d1cd84858fd6f7edd638f4f552363ee7685f69ca
+PK: d29c10694c5e8e3f3447ed78d34dbd74a2b301373ba871b5850c333dff7bf8d0
+MSG: 8e7defb9d16d036bd642cf226e32773e605361c5ec4b951255788db0a042c63e5a4367d61524f10e6258991325a39ab6b03612260c3fe3df20b34202d34395bd4ed40bd61373df781a4c8bcfbd15301060f07437732333d8e49736322dee6b22438e787d8856b70c26ec57d6dade9c3c28e27220c5670e393544ed095937298dc3adc73865f777e90037bdef834716476d78f4e6cb4961a4c68a8a836338a9f5da179c4d5e93c3f70dd35eec709653dd8de37996b12056d4eefcb4b6b3c13ba984d832275c4386ebf4a8ff7f078be3d428c1e0d9b162381f06a5b7bb12704003d91f25d1d8fd43626ce70fff59d2927768a76bf7f9ef76ff95489f38edcd1c9e9b8a8b0ef66c32805776d5ae9fbd84a7af4fa6563ec70ac5733a44
+SIG: 80c5d51e96d1cac8efd3459825e79c1e9f65af701d1d29e1f95b036707113b77984b7b3350f04077333c957f8fbc7d9b040c362651417b9899027cd33edb1103
+
+TST: 285
+SK: 15c9f7c4d84a5a479041952e6a8cac24e76fd2d275c197e6b521929b43ba6c5d
+PK: 8633c1829d29091df71fd5c0ef640572e4b64974cd097dbebbcddeba041647c0
+MSG: 11730dd45dda80d84d080d92e9bddaeea6878e4a0b3b512d9ea733808e1cef51d49048d6c78116a4bde3c64aceaa52beca86b331ab59e9185c70286a02bb5dd04f5c7f4e9c7e445e77458565f159c783dfd4d976a910e937789d2141d416ed3a7f608d26737a86b20b624e3c36af18d25c7d59b8d7427ec6c4d3d438d7ae0949dd7d748c1ffd6f28e8285d440422d22a3761202e9584f5cdb3504547aa4b685730c982cba213de08020a5e4e46a95fac4b481bea0b630abd030ddd335a20fe2cf7094aef4813956991913c6821f4b5410df4f133fe63e22c08092a0a65972722a27ae42011a807c327b417237c540114eecb9f0e96cda5dcf0246f1d2717f49b9cea9dc6a3da9b396f0270529226f5dcba6499918a6c289fe055fec8
+SIG: 1e36bea5a583767ebd80306cab233155b7b42814b43473cf45cdc5039c939744a9694b87220daf4ccd29f25cea405e7c08db2ef17f3f034dbb49cff60283e306
+
+TST: 286
+SK: 6d2d0d823f294746b9a5512e14e73c1d855b5e4bca65fe817729810cc5ef840d
+PK: 1b6480a6a90dfb472984855cef6f1ab31eb7b3f13c8ac00fa556d20b53e5ae17
+MSG: 8772721f72eaf7f73040c068a7c3753bffca7dc2d0930c6525f425e6005c25cd4c0ff5095c9c61a5d8a1967b8c86010c884e509e6b1670f79046e22979ebd354734090d3ada21435c1f8254f7b5222cd5564f064e977640366449f4e5008f870f9c4840565bf4fb5f574c9774ba2568e71a9ccd82ffc59b694f26e7de4ce2e3fd880a0eef387931333ede00dcb065e6d0f79591a2aa956df1948a265cb95750d8a233b15c288a05487c515663f93e740fb1570fbe4bd80c68e8d9297345a8a01cdbd88f4a39bed9c5ef09f144bce5de568bf3733bc53b2039a29cb3e194501adc1c10e86383aac8b0f85c67a6689bbe1470a392476313439ca88d98c021c0eaec25fb2f9a160ce5c786170be0238fb8785dd33bfa9059a6c3702d0de05
+SIG: b515f49eb32ad478692df88f07b7802c6e0e5327aa08a6366e4cb1d1e26f9e65fc81abebe2215d649100f27598273a412b624e842d8130403797e57dec975a0a
+
+TST: 287
+SK: c0cf799af7395bf27bafa36cab437045e39c903bf807548319ce44f287494fbb
+PK: afbf550ca290c905bdd92fc8831ebe3dfeb6daae4f56005253cc50951e50edc2
+MSG: dbe65780e968de9e40ffb57cf59a60fd93b3f9a5e7d8ed5180adbc578ca1bc48bd9fb60a1324c9c2c1141479a0dcf0f1d07e84936526df42333c0d773e3fed9e4038de5b95ad905c92cbe040487bf55e10e1edb429a0ecc4e0e8d00a988a9cd53e2eb372f4fc4cd9537b269ba3a23cefbc8df6476e75434b81d93e8891bf417c82e363f3e4abf80a4f73aca84ac7df6337f536d63d939d92cba64be742221116069ef251abba0b00af01718bb580ddbeb79973ef10a68b4d0fa023d6ebd3079d6b32a1aa20a21e9202f27590c3f0c0cc253073c3f822aac459d39f50758b70c00710a3c98438416508522e512adaa0afd503a7ceb04fb94a4a932ce80cd5a7f11bb861263f58e5749d542a110de7c7689dfcb0c51afa9d54a58ff89f3f67
+SIG: 5bba01a4c7b25542d06912de70aa1e220423fdf8338a9e693395cb6f0dc1fbfd018e3c77e50aef90a9080f30f1f5792b2431078fe6e3e00464245e17cd8dc107
+
+TST: 288
+SK: cdaa50e8527dc7a50fb37e28fa8b9568c37e8567e0b499997b9aed676180c3b0
+PK: 7c56e164510268c182b423747904f1d3a5809330f6e1b29266ec46e73be1550f
+MSG: 94fcfbaaa303dece7b908f874cc5f095061f1754bb35780db666b63ab8290811bf1c521a7f8f785ea270dfb39d0d6ed95ab71955a11ffaeaa268e081ff3e4f2425b41880a987151e678e89111350942d820c3eec36212426663be175e5286b4ad1cc804e3e3a03b9fa3e82838ebbc2615a645f2ca1468ac4a1cdbe523761e83f4381b0c8550ae5e8c8cd1fda57191436e27cb883bc64be86a9dc6110ef3401d88a7debd1b701d9c257a6826cf01e9e2922e3ae577f2834275fb0ecda80ed8cf1801e0bc5e01e26a77c48bdf46a5c4894d22ab53e741827e24bed5f0750ffad05e53f1d5e61dfd316b191d9797ef713131a8b430abe3fac5f3c4a2ca021878b15adc8c5f542114260e687a9d199d230c4e0d3fc696993b59ccfa3ffa9d8d2fb
+SIG: 137bd10a50ef609384fe668768fb871de741ca0f53ff8477d7ebfa90aafd5e2681fdf1b89250463c15db8e17a58825fe9427de089c34de13cd07bba18d4aa40d
+
+TST: 289
+SK: 0fdea9bee6288f947e0adbdda4dfb2baa03891af25024a5e138ac77984d00507
+PK: 70abd86430d7e8d63209c8b373ec4e4b79e989e6725facefbade3c7574d23cd0
+MSG: cf72c1a180a2bc37d8478d9a7a39acf03bf2a50790f7902f81121222d31d3ec916f4f24cef9d7c41dc021b0e8487bb892e47305e54520303e89b30b263dac4a9ba375d46c40fcf400535c959d2b746a7fc970cf65b472e84b5f1d0ebadcfa1aed6fc47facce16a366a3b1d6e516813c1960975f8f2b43042fb4eeaabe63c6f65db45ddb7db888a19a9d7ba6ca479fcd70c5d1e970f12c14f4d24fb7e2f357bd3a94aa1b868ccc0847f2eef21853e253bafbf07c4e6176a1ef077167841ebbe5629337157f39f75c71d21e7e96c51a1b16fa8dc60f0b1279fcda2641fc8591e3c492f15bf83caf1d95b2cd91332f1b4202fe72862ca2ea2ef92c11db831d82f8fc3d41fe29a76c211a758e2f71bd89d2c6610f201429f348d56e10e3b7af53e27
+SIG: 80c42dd5df03b285a86ac95ce6669f786a978a813a9d7b8c6a23de76fbd09bdb66c5dd1cc9f1a176cba388d5051764a32fa27f0028ba4898068bd01a3ee17208
+
+TST: 290
+SK: 03d5e466f8298ab5438a30976d1322a7215a642dd5fb4c3f8519409a7522f092
+PK: 4b3ed4db080e2a452e16912c14504424920a60975604e4f379258d1c8b193d6f
+MSG: 1b47b70013cb53e1f8f4971e0f39563ce87edbc2cedd99e5a35585df8b00a852f7b9c97c7e4a5465fc5605ae8c5c36570a99201a7ad6031287ef0c7b2ba6e57b056d0fc8d6ca43bf6cbdab098934b403197b525d22d45e6b29c78f8d6183e41ffe197dae25ba22b06669ae05badd7e1da6932a7d054cbab3f54e5146223ad8671231bc16fe62679bd2817a6b80e653998c4949f81ff53b6173163e11da3e6d3c76d84c713225b4173d6bf06a85b6988a48be4359cb515503ca563f4353f8e7d45e4d94462c89a04a00f1b3b0ca6422d5db029c507d464834a20c78a713661d84edffc496d69282619894437b4487954cbea2aa7261e6a62b6851154a5d25fb6b4f09c59473d385ce03e91ba865eab66c58c0abb0b7a78e4be927e55460ccd70d82
+SIG: 6d7e4658f26f337c98e03f13542e2f39440ff7bf8d88f3f6dfa4d64948cd96b79051492fc28f65f2cc0d23a0c4d5e2307bb1c47e11e53b371f091b69f80dbd05
+
+TST: 291
+SK: 76cc18a1dafffa100586c06a7b40f79c35fe558c339c2999a5f43875cfade03e
+PK: 4b9da8d2f137dc6c857a99a5998dd89dd5f05971a21e8c776670eb47bc1270a5
+MSG: 4522b1d82373f7a318221e7e57617503ddf44fd53997522a1d963c85b708d0b245de372ad52ec7f54f6213d271f7c91d5a1d36d134db389df0b081a06bc0c7a4875f724092793172c9115641c6d054f1d992e0fae4df58695f0ea3449d7a4b3a8857e19803fe49b6d52c9ff3746a574a2756956579f9fb809a0edec92c55e95ffefa3d05f165822f464a21999f29691f6744ac5a3ee49017880645e837edebfd2e0f24997f041145a72e2376ada283186ca2b836362977195baee30a3acc81b243f3ee376a2c4764c783667a4b1177e7951d3e3c7be4f1bd7ae8c60fd5fb0fd91f0c1c14d0d2327e8f20d92c0dfcc53870e9d99fdbf9dd9a17e882509ae7baa8653e39edc8ee569000d624cb93a0754a798d1f811f6a0ef5501a17bcf25fd0f91626
+SIG: db74751c66e6b1866044dd9ae99f19e6334f179e79d8b8e0c8cd71d22cefb9eab7e3e7a9c2da225f2a9d93a313d1cbf1b7fe2597b8d702bf3017a6a6bc7b7b06
+
+TST: 292
+SK: 71ad980d58ad8e7d33306689358936a372d5190b24ec7f9bde749cb81150efda
+PK: fd35a75fe5abc20104691a24a4659440b55aeaea902ac3be274af27aa8312869
+MSG: e87ae073ff5dcc5485a19940e4e3ff263a0618a9025ad4032dfb36d171ce881f71c18a49210eb45819806142e2f00db3041835bf2c3bccf1dba02b8b5a5bdaf8fea316c0623dd48a564ec166f037d587c8c01684e5e5c0ba9dba4d23b49a0309244e282a51408622edb05704747e0cdeec976893777071098972c113a8ab639c31f1613233ee460eea8a8c10e1e6e152214529878cf1adaeaf78cf19bac71361815bf57955498fab4f0f2b7586c86f9f4c2ddf8972f9b9e0eb636d84bcc14385b2d038be55a963702efe225a50bdd0c4da92a2a6a09100ea04a211d396458dceb4487116837d139eb0f122538ed3986ad0af4da2dffc89f3269ca88538086e691e5beae9581e7c63d8e612da2c47f74dde1d94951eadb0df60c3897d2a3095c506093b
+SIG: 81670b1029e481e9ff3c171f05c16861c846ee79cdf2e21e3bf952bcfac97565f2b1dcedf69d2e7eb35caf5662e8bc671fbb96756a63a596264d1b7f4af97e06
+
+TST: 293
+SK: 61594e24e75f996b4fb6b3e563f6a4f9915cfa65ddb199b01fed7f8ed7824ecb
+PK: 8627d2141579cd2521aa076800ac354b9e3a47d71cedc8547434268225e33005
+MSG: bc01b08c7caa236100a012a726477d0ec389dbfadac73d5106424c5d1f3d1cef1695cfd93a7062ec8bf1067047854920162f651357bedf1cd5a92ec29bdb5dff716e8f6025515a9549ba36cdc35ced7c5c0c368e6cd92f2f10ae146a20728c374bba509641ce88cb42fff0cedfd9fd67f310f9d01a3f3690eb21db17bce67ae35c4cd24c209f09f044759d8d5a7d248e2bd966524ba8c0c28974726b43bd05de843433cc400598922974623d9acbfdc761c4c04375a952ce54caffaa96acff6d9dc278742af476e1865cb8c20d13d1c1900863bca231e44c6b0d47cb41d510f7958f48f304d03da033484a3e1f273faf6983375b7d3be03d8a0a002def6365beb2fa8ccf1a94987adcd33d0da1177fc5159b6e56d004301e921dbc12ec0a73f413cf2c48
+SIG: 6302b3ff2710be306c92b9aae30d23c3d4beff394e63201e6ad11713345c4fcb5cc8d3dd10adfb82bb11a189ce7ec3e4222727624fc17881c14788d2710e1608
+
+TST: 294
+SK: 54e6bbfbf8c06ff2c066318c2ebf03d506547bf43c2d7a5d4df305a3032b7138
+PK: 3b71aa1def666d9188f403f82ed30454aba5bc9f470f6eb988da187c92523284
+MSG: 0318d7cb4805af9821dd3f914b0e076fea04a7d2db3a59a00affead3325a2be40c1f87f53276a8552604f228b976e288b9be906a7bd25b2ffab8a8af5d0f6e08786fd034e2fe1eb7ee033979860dd1e5327287e9e615f5dc5a960f17026b56842fc8d44cad002edc8501cfb956001502e4ddc81a7700d9c0be88eb4aaa64a6cbc39de82f13c11086de1a4270d3af97284bac1caef1d3edaa1071666bd83b2ede3962d98b9d93497ddfd8e97dab3089950cf30ed11db77ad1437a0af5889d8efc44e612420e3907267df3acff4bd3fb6e8ca5badf8e72f9de39528653058524456a81da5f84982afac34bef5f71e91f8f90938a6f5f1f287716de56a0946d261e87bc775ce189e41a77baede7320a3c608fc971e55d0a773c4d848d428637f11b4e4460390c
+SIG: 3df4d09079f830e3f982283681ba37b50f3c73de2c5d22a291358ebb1fb854e510f63f9a48e9fff7fd8311302ea3e969394e6d49c9e3182054942f6a744cee03
+
+TST: 295
+SK: 6862061be0de9dfd998118204b2b98db3ce7d7e819dbc10794af0ab2b06e8434
+PK: 9c5f7c2265dde1b25e4f27ec71580d52dc89f2c3a712bc1ad5d6d69e711e08d4
+MSG: 1740dde8434a0d689925679b0c180300cdbd0cf6a89ad8fde34653316cee4c571a4105c9e9e0284238fef2c38a09157c5db94340571b390adfb69ff4c0dc5053253a679d42cc1f1bf1ff429229ea0a5044c6f79564e0dd287f53f015b83187d9ad27d91039af062c437b1575a0eab6aeb8aa0d27b27665d6dea9041ff9963a3118b3298a8544e3fd69ac6877e3e4052fe4422bf03560b2c57ec531ee8b5ff53c28dbde35bb45c35077636e6f841b59d7eb77bc7791b6093858a3a80a3aa6d778dbf53db9d06119c50b71c791c0495c576d1b59d396873ed871485352c8299a359da5ee9d7f36ed1455f89851a30851bea719685aecd08f25562609dd106630735277e1d6519bb1687de8b8c68b9671452edbb3491da264cdfa0017c512d2769759cb925fb664
+SIG: 965edb34e8ab8bc3204a3201d22186372de4242600297cfdb57aa1df074ec50ddf10105e9d4c89a266c34db7772aa94cba946429e68ba62bf9a0ac90f5f05b02
+
+TST: 296
+SK: b2250bbcb268d2477c8312b1900fd99982baa29a68974fbf8778a1228dc97550
+PK: 44aa8df1181674b05ade980f7eddbaf3bd7422a920287cb2d2db59a063eebf74
+MSG: 7ef0ae1336a6fab37f99da5fa7d0dec7409c072623ead84f241d53d0596b461705fb1b3c537d36b89e8960febb4cdc0d427ce2fc1be58dbbce151e35acd8b6ace40a19822914a4bd8c4af632f136418ac49b184d55193ebcc32d0d798709b1a8fe294fba8a1fe72d976b4400d4a393242311b0f8cc994e89475b0038ae5d8914938e8f6e87c6f50b9d656c45d7b14231efed97f3c90668913670bf5be2efd5c270c7cbaf01e8572e9800978dfe2e10a2fc0440b855629bf9cd409ea941cb69226cac771b15ea77c0326848806ff8d2e201e6e26cd5f45430dadcff8f59c321c1c9c6a29b94882935447d3e6c2e8804b1161576bdf0320fe53c307d9cde426077a7677cde3c1bc83e18e60a0c4ee6dccd877c213a8e4cca640ee04929804570ae1f96157c04357a
+SIG: f2b8d92ed51ebd1000bf9dd3411a9fa9e7aee54c4c86e24ad0f9ad5c55643a12d680019ca03f216bd4bd32c9ce1cd8a528c3ffaa5d5b1dc91a4be56f0e2c5e06
+
+TST: 297
+SK: b809361f55cfe8137fbda880fc62cbe44c216e141893346302b336045de21878
+PK: fd23e42ff06644ead347abcc1b3e03b0e88593b61254981dd8ae59454e61b3e0
+MSG: 17ace197d083aaf1726f53e5ef81b5a8c09222f260ee5f1f5404ab78d900d489688449b843bad3c498aac6d80b4639b76e6e81c55276a6f9c7cecd70b71aaaf2018ef76c0e30154aae86a5c86d4e8d0e4ec68cc427060bd56514f7238086bbef5bfca1f5671b18041838fd013572443dba48fbdd95ca740b0daa4327164a1e34677249708f77bd793e7caa6638b5dc9fbe6f0dfd4120209097209c93cedfaf21b6bf59ca6e99e6209639444f0e827bbcc0a61c3a237ca22a283213223ab658e712c7556238d3a5fe31722d65f5706ef6d64d73232d3043220f14e5cfd3c2c83a83d68e20274b6f96b29de040cec8475030b6a8a87d29808dd381795c3d22acf5dc193b720d95a752d9f123c209ffba004e48dd06dd8c9e172bc9e087d80bc5216c0b0b6e77031241
+SIG: b5b5950d3772d2eef88e1b0f5df5ffae2f2103885e71446d346fbb5daef94967a6b7b6e4be885110065876c665b7812de46ad31ec3bfcbeaee13ed0c1e0b300e
+
+TST: 298
+SK: eeef8074c2eb9a1cee2f2d3bb05325546a9fb7cbe44b599461fc5885f5fd9cac
+PK: 9b892941a0573b7a1673ef480f081168d9b7496a81f9177dc427ca1f84cbbf7d
+MSG: 9ae39feade905affcbedd2e72a6f2429b3d1108e5bc1a9dbaf490a6299bccd94acc413adacc918b14afa85c78bc168cc00740c3da0e08183915f79b7fe3868ce2a7e886b32ad45009805bfb81b8c07b3b1022420c0f009b889d7fc22fd1997ae34198438ca94778575122fcaaf96e6502c33a75a129a2d0dbb073d93820d9c96683db318990be3fef4cafc890afbd9b1504c7439a08a065e7814ee4f9b6f57ee16baed3f0e3aa35dd23d3528a458919ad77048b4e2e6172346be249a50af02bc6c853304c208ae0ba02771262a0d8a465f71fa0635e53eb2ef0a847d56a0bcd7dd3fe077c92bcdca3069a4a682a2859928315ce3eb445c6072a71492ee82e172a20be0b648b756e6c775376f0c7c3df8e64288089c2f81ce9593c6e08bb1cc1b27fcbd392fc7952c55
+SIG: 6f7101984fd6892e2144b7d45619830caeb6713bfab4eebbe217c5becd249bd9d752eb76e9fa995e7c71ff7df86bb260cdda173ff5deec6af204b7dde011de09
+
+TST: 299
+SK: 61faeb15f857f6557862c8b8c7ef41f80545520996fcc1127b8c2491822201ae
+PK: 60a290c0fc425a0874673d94f9bb1400f9dacde9954f9f5b05dd48ab747a3950
+MSG: 253b566eccb563bd6e480c69739b8e372519a3437254e0e5029cac86c71638f2df2a6cf9e56db2569934deba90db75547e3671747df64d6f2aaf3c110fa67a7094ccbe4cc5355f0d43235136ee26dbe37f4225d3bbfe245595280585fb548f894e86c516102580291fa7a02859557fb98eb588870828b0990ae9d74f3831da58946bc7a5ce1ba498b4e8be8989a3b50d7e8789f56b8b4fecbc2a33bfa3ef591a0fbcd932fa93e19f3a812ae5e4e3b4b242be7705a5874af73be310b0058266a378f23c1348524715b0ccc18d6634b23636c316ba6a1dd2fd5092c06716a717b54d0eb9fc7f636f85bbf225a2cf035b4b7cfddd75351682c0576c6b3ba5a1c0b25ec594e7709dd09a0079772ff3acc67fb6c1b37bb3742b726e77e80561d9ab73160b73362581da5b9c7f
+SIG: 31f90f50b2dc705f1d92f12ca9975d76f1b2826ada3cc185b0ed6c83860777bd8c489b59855a91f64839d49ba467985abb376c47a4908b271b8f77c58d01fd04
+
+TST: 300
+SK: e6b9cd4da07cb34f30391cf68f0d87c7cfcf68f810ffa40f9739c95deb037f71
+PK: 569ede0f04630b43a04c5a66b6a5636b766c75965984a7477e15491960fdd864
+MSG: 69def0523afda696f8448f9c1143abc26533e68695a090df0d9e43d0c0eff43583e6f709d2043c815fbb3f96ba2b0dc3be6fecad5dd38148788e4a0385a9fe7a921fcb8ccee0e4d3aed4bc3d216d84b414f9580b02820c03d92e675e685c4b5851f363bb4df97b417c3fd90022eeafa20dfbe82964f2ff073d255758fbe567c76b2c35e2b09f8a8d7afa32c6f5ad01bc3ebf6e210606db038ecb6820ce1ea4dd529fc1adfbc2a138565ac6d0f4a4109bdd47b8aa6ef4b8bede454680d1dbdb75fe1eb2e548d5de7cb6d792fef3aa0d8480a6030b30f104d7e76b58e9f476ebf2cc832923b50c50c111c3515fc518852323426ca778a596d3195da8585d8c3aa92083313a6e6585b70c98b185b472798a61cde77e62ec272f14b0d9eb4f22f9c7c05817da6fdefe7879a584
+SIG: 1e375c94bd809ca0cdd02f89ecec4e437732dd20a0a84b254eae889d8070e682d113b0be22e41e6cdc3be877680e7eeb7f0995e6622dc0b434fb0949dd994b0c
+
+TST: 301
+SK: 4d9044f17b5a0977dc5aa9916a924300a244a1ef7f060277ad4978351ea64291
+PK: ab9c0692a606b2567c19c30f9faa3b4cfe72fb237077767b76d3b2ae1490a6d4
+MSG: 7c8c7189af67327af1c6dd2c30e975f190e3b38d008b4585167e0d450740d46734587f6d208784245cc5cb062a2a277f17ebb2746f9bdf4a8237ca479ab0a430177e19ed7dd3622576b14cdc08282214fe5ee4d76b43c16ac90864c51be8aed45d7b980df7917f290fdf795846465f27fcb7e5730637944f0577c92f32375e995bc0cda9d7196f2c0c1ac8b80d12a0439963ebd2254c347703575816e7964c13d44d629280c312ea265344de38f3b18d9150f8f924afb44b6bfb9eda513d59e65e2ef18666e6c2a21c4018665befe92cae581d3cb14e23e97d830002cb90931ae0210068af394ebe351be5b817f3674bfbf40049030e4fe505d34a1d502a2c50d8e638e926c230676b7edefb6bec77b1c0ce609325287ba5fdd7a9976987bd07fc6a4344956ebf818f08586c
+SIG: 6fa48aea4d5b9af65af964cdb709443a11fa84f7d44acddab16e04a6fcefb27ae33c05b36da13c23de517d6e6ac574a03ea630ba4fbb958131129aa7f1354c01
+
+TST: 302
+SK: 75ad76bb4c0c229a5adc79e444b13f88a96459862c8cf0ba498d0c996af94a7a
+PK: f074dd2b9c1c309105ec951bb5812a91ddb54023b3809ab379c56af0461af617
+MSG: 0ca8c1c74128d74e9d0a7bf8964291d074917f2f9920efb911520567642a50a615abcbd00aed4abbfef1a983cce333e1d0df3e6404fb9043c6803914cd5fffbc66a0790c7878a24089a571f895662a1d18be3f01ff97fb3323334b6f5baf96551448e4090d033c464294d09133b151d5b5c6321b50e2241de0ef6f882889ccf4ad3540d5a1e3f7548fb13be71c16516606e79d0449c2a08e5dc23148843c84e97ed24069161c8e75208f33e95b3e10d1d49a2faef9d986ab62809f62ad39c7cc871f375a4f5a6faf104d7e11b890cfb0589902685216ec07cb8e8e9e7a7c43635e23212b69ca3b7ed54f0b97949e3d9a6662f8e4b3ab09cd495294c331c047d86ee785ff658bcd7fcf9c480605ce05e810068d60fc9b26b5f063eb9000d2657a5094284ac80f1375d0b66d6f5f
+SIG: 0c4643a8be6dc22f4beb6bcc70c6172ec7608378653cb4e99f3ae795eadf4e982a297609ca7938f5df632b095628cb75062d3d51fc0f3323bfa7b22ec4d47205
+
+TST: 303
+SK: adc6e9b2e103b62c24ad4346410e83a1a0bd253e4abf77911850c6d9666e09f9
+PK: fce316e33c910821beeddd634bedc58ee57999a76ece384605283b99b543b78b
+MSG: 8cccd98ebbf2439ffdfac41687638faa444e1ca4b63d13e898eaa8355492f28813ab813fd01510e112be106b2045d30f63335d248904d521de181abac03e3d2cb2d16c44b3b012a0c51f9901aef9056c724d7a2c6b2acb0a07555940e4c6e21154890611adeb6489f461d3e5ecd1af5a4d2b0adaf41747436eb414757a8fe4775674e3c6e5de4569d6fc6c788e10905eba32c270a393e6f721a765294e2ac99a9b6e534d3df08d1db97d602ac3195cb0b77f5bd4acaf737fadd6991f0688abc74918047574eac28289739a664e0e0e20574a2c25fde49d14539db1cedd4a9204a70acff0a62c8f25cd768ffab15c4db316840a4d1bc92e212670be07c5bdcf537590607dfbbbb4d9f98b89da0b4df7d88f3eca4814d16bfa20c8d2fa94f9f259f2ee2d3a83c9e4171b1a262c4b99
+SIG: cb017d6d2682c9854366259aa35f30d491cfaa930998c297dbddc6aded5b3d401cf76d80d8a2764de131718b6e0c481d7196bc72579716b0c0f6ff053e68c50c
+
+TST: 304
+SK: 37fc1beda4060b6c57883ddba0776c2bcf5ac28a651326021cca97723730fbb0
+PK: 7bd7bf1c99dc82e06f08bb454d8fb288a57927e07ff1b12af15ee2c12fbb6b3d
+MSG: 3dfcac0265a024a83cb932674489a163aac314bf3d969f27596e451733b99deba5eeb779210baf95bf545a1ae6b8a915860693ee890f939320e06a844483d18c6a1bcd03c638bb7d1fe2a82eb448a311b1302ea6428f54a39f45a4d560be1557a2b254c45c137f45cc68356836e21bed0b7f73a518ce09db0be393927c339bf2a4b5987539404ce650284de12e3b553b262efe23848332ccfdc35e791a0ab43f139c71ed0fcb2d173bb377ee46b1a9dca9277e77df855f2830251e31e26acd86763c8d7eac22c882fc174f2b5e75ca6ad1ade03f942bb2a13bf541906159158c68363c7480c5b27a99320f8283a2699d4369c071c50dbd90b7792e4772efbc0b195bce84cc4dcfff7072a48968db69f9feddd0f9ced659eb5db7167f35f988cec114887dcbfdf27d02d300b3e1abec
+SIG: a01dd65fada27039f168b123419d8abfbda48c572ece24fda06e1a5ec31e084f4ee1cbf9961e88ed51e189fcb7f5f235de1e5b28d08f2bfca190b0f019ecc207
+
+TST: 305
+SK: 8d42f4ddd2bbd2b827b0a0d31d8f758ebd13a1b9b3712228948ca610bb8858e5
+PK: b7354898794f9db0a8af6eeafcdbdf011d3fbef0212ad938a4a4ad27ab16ebbf
+MSG: e3a2bebc0496d8974a8f4061880369314ed9e440c1b77e26fe5071ce694ffd2136db0c4d5e880e6000083a75c90d3cf72b9cf5a2b1a9002c2701a2ff59b0699a8f42d79dd8a5fb71a8125453d91fb80080a3f0a16584282f17ec7dfdc2e5c69c4d9bdf484d55944dae273f211cfb76ad37da45871365439af35eea1fbecd4ca679b59b5e01bacf49c7f4e5efaa406ba1daeb085482af5ded89dc6885ffbe3d14d2931b83897e28ad06e5564e2789baea81bd932aa279fe8e324b9a8ef111c2abe2f137d4bb50d8ab76cebc0bd982a23919751ad4d49e88eb14173d3310289a872317e4a451e88d54320891870f15b2d53324430877a9fb5b49bb929f211c5b89764dd9c3a595a1451e9f85a238540002566e53a99ed1e6ddc9b4853f455edb4cf1980d56bbdc1313a36e76ea9cbb048a
+SIG: 70764be39c6dca0f067abe1eca490fda951fd4e9499695266e270b9b05eae706ca8d1ca6a92d7c488ec6ad8ba11457a42a5e31702a9c2bce892dc40535c09f01
+
+TST: 306
+SK: b62de5a1acfe4ca2d1f0c132afcbdae66fb29a02f297fbc2407fadbbf2454200
+PK: b63b2d0bf355f7b6d0bac07403411c40afbbb2f707503b3fc2cee8a1c7d0a838
+MSG: e659e51d7b193c4b8e2b3ed73a9d7557ed2bab6153883ab723592f730a914567142b3fa435db3219f83a542dc7a4bd805af666ea865b853146f8e3a9fe870711f90d12b0693492af2a1edf99a16458f781f1266ec437a5296a822ca9d69ce844b5c59097a2a56f3eb8fd273a636116db774300922d45b744657a692f5e8bfbcb06d2422818aeb51e7cda68acfbeda16e7c79580dcccde24e8e3d601b16e063b43a6d0d1407552f7504f5be19882e4ffe32344f5f473e73a8f6ed37b0d8d9e5e0a0dc9828395bcbd8f3a4e3124869249d058be0e045de0b1e12b1c83ba0aa227c95b82bf742c3eac0152b33e6d19be8b33a35bf705daab10622a90aed022ea6e439ed50a9308437929924ba3ab111ad0caa6feb0a6eb165824ebdb0866571efc07e5222ed8686b14d9270bf76b945d52014
+SIG: 5cdb00e98de73eab480be42f8a8a6163809a0d37101b6a5a4eed6a0c92030d09a5562c729080ce6f6594c8fafb1f594772db7a90a9e7da15896e82f70569390d
+
+TST: 307
+SK: 9732059d7bf0200f5f30412430336be4ef1e3cae62938ad08729ce3ba714cfd4
+PK: 0de8425f5e30b2b8aebb8072009a30cf0411c3c8238f4e4208760c56c33e434f
+MSG: 1a13e7ab603b48eb896fe17173fb31950b0dcd5a35ffdbe1371c7a5bfba593317589d9652d88797729180b8d0e515abfe6548f160421e537d5c94aef2b34c7ebb097420003bc0f361b423e7e14630a803c118202540049f68c9cf46fae0368d162e400d77bb4523cf6c753b975c245bc99ed2f413a9d06c2da6ce0cc0987b6406b809e8eb319033d2de9131dee3b1b7b5c95d653ced8fccf998da1768511eca4d3c5f735adab96503b3551803e4922635095ef811be4c08a6cbac917cbe6cd91a4ae5a330ccec0e8e815371217a3de62f2d2d61466219833f33447132f4d43350c58cbaf422475edb128c56d80a495726b1fdbc56551eb72d0f4fec26ba8bff5eed6774b85039a5292834b5d1cc1b09ba0a3954d29323673f5e71276a12ac4c579355bf1ecca48e6a716b9fcecdc565c51b9
+SIG: fba1749b641dd4df34664bc43c00468c7d75e84afad72de473fd1e9c87da15ea604fc2549a1a867fa80850e9c2a59cd99053886760a8d9764b84dd672676720d
+
+TST: 308
+SK: 9c7f6f379e3857007e2ac6324cbbced57ac9eee4477813f83a81fc8cefa964d5
+PK: a54ba396d687634d3eccf41c5782494f5f10a521a1e5d388523d80eeba5b0b2b
+MSG: 3f2d3072fe7383e541551ea9abdbaeae6a464ae6b9f0ba786a441b2d08da5bcada3c5424dc6931d6b39523e2de0a0c2e4e6b5b8cda925e5eac938416a2c51bf13d49531d7ec7114b1c82feaf90f3f87591e397d02702f8ec1b30d99f5be7d2203e4fe4db2ea47e7b4589d8ac506248d7347466edbc96ea32bf3a6ea7502dd60c9e84902715ab2c6ca68f5b00e1d909d83aa6ab662d8aea870ecd861fec69f2eec0ae677d2995b0ed688faa8ef78244e0d1195697b07122ceaa11f5a6ea58fbdfa2e2ec2df9d18693ae96d47127556e91f0864982c13419b04a63f208e730d26951882aefe001bca3408bd9862748c6cc876c28cac3bb2eb3395818c2091e0fbd7a0b4468c6b0d00cd008c11c3c3ad01080a1f5a40ae2e4b0c3a071efc8e1d1ba6ace6d4df0ff19829b0c680b3aeb759177ed34
+SIG: 65685f9ca5982e15a22ba3c83a0348348482dfae57cea178f0780c057baebe4af632f984540a26019a7fb34253c9ece7ff308ada233ce0686347ab5b21ce570b
+
+TST: 309
+SK: a478f35abb73727b6be6ee5e56eec323c9517882fd6919360ebbbf5d5cb8b83a
+PK: 7a6e266a54d135dda0009ccda8a94a4712ae5cb14761e8436e97c4b7814d8e8c
+MSG: 0173a34050b43748061ff8f5a3d7c43b6360847786e8bb75e536fb47b645b214f221ba24d83d28bc025024663e534f90f6e83a93d8bddeda2cd8808155652a908c437c2db6f3ed4912f57ca5b97928a73be964af59df4439854bb006fc295a87b7b72239c7fadfec40715509d98579daadfb8d524b4cec6620705efd4104c297144aea722974e12c5ecee5391ef2d93ac2b124e4ac496147c8b70363585d7078ccc53e2ae593350bc25548a0542526ab00afe477a0f4b27397c72bc74a8a8ab156e62b8bb47c3fbb4b34913e459687476bf33142c614702107ffe2cc01e25fa30275e1e2e63cea9168e4a47c02de097d4d853b27675c5bb330b94a974ead85e2bdee8ee17cbb5653346658df2f91f6bd739491dd71988b3a976a3e2e7a9d137410f4acba9feb5f11798c9a43b6adce14365a7c6d
+SIG: 9d16fd40b9f8dd9b4a1a8c6d703b9fccbb940b1e0ae77a5970374af0cf726f4479fd30d7dff5cf53494d9a296ab6b9e46ea6c136b4db2c71c21b97c1c8254d0a
+
+TST: 310
+SK: ffe825148c0959b3a68de86ad8e8af7fa5e078f363dc124213c90020da0c9089
+PK: 139152a0bd22962dd919ae3e0b1620e03c033c2ad0a3979ec6bcd1705e23d598
+MSG: f125780d0cd088530f0c87b70bd42ebab56adb5ad4345f929ae5deae07fb55322153a8f023d38843bf5d6a93fe993eee71bc2ee563b25a50918f03efdb5dbf7269add69ded3e66953895620d9b6cf46ba2348f8d66d7f092235e378c1e3edfebeb78084bc8dea013f9933aae14a041948276d01f1cb5834b0e590e13d931d19292bb1d8041ff2fe2e1171a2e0b9a059821d0924dde7f3b1bb59813f5e3c63520aafb8801ba62c7097d4d8cf437a568a7f0087c6ea0fce6e568c4883f1cd12c749d06a6feb278f1086a8b04769921f78a9959062ab06f98ee80c2c7854ffa760f86a89ee1a51266053d195e61bb1dbd18dd89ff394e408ace0f641a395d56118ea72b7d8adf78b1655ecece7e8250e8a3a91cb8fca0d9ce0baf8980a387c5ed4318663280e5b4531f3187c47eaea7c329728ddd0e40
+SIG: fe4e89ee31786c0a3d3de3649bb93f0b8aef1caf5a832ec5e4067810705adddf539b8f4e05ad08cf3479e45b42c96528f6d59a4625703ddbf15b63093965d80d
+
+TST: 311
+SK: 49aff421a7cd12722aa84c48c1fb1c5f8d9e277d0a99ecbc9348c3aaa74be422
+PK: 88d2c26266f493bc67578ca0b1f51160cf0fdb6a09a906db9faa686f11f8208d
+MSG: 70a1ac144b75fda75586a79c36fd39cce5f5cae2e6375852d3b62a9630336a293ea6d2ac6e5b57da21ef364a595bb0750f5bf4d2b320676423870e4b8e0869601f16680619048c4ede276da69f205a70176e25ea04bd089763e709ba343fc8831e52044eabf9441e6997f8ba1aeb9ef0f491170667a7f5fc9627cbd0551b76be27283a4b0c5f667846688226a115ee8020df08042b19b59fe551316a6cb6916860b9ecd74154b4051038a17352372ec14d3c957d2ef50ff786189a8aeb9c08f45eeb5eb8b040339974aa9798c425d7becb228c447a6d0b3cef271893e0f7076e223a7e87c6a3d270a033bc97a4565edce0aa91ffc3f7801775a6f29b230245bd71fa034353de372395d1bfcbdebba081330f7c076be99c2cf4867f15b78d52f46fc7391c9cb95e5d64643baffe72a8e3a650667fbb3e
+SIG: 749181284df05dbe5974b91782a1a76ea08642cb0f0c98db586c575c210cdc8b651bd34b757ae38e4b6be9465235bd0eca430e26c3eede561c6e824dfa200e0a
+
+TST: 312
+SK: 703a6e2b62d0090c61d8659b6a963e03c9d62c1b38f7d70e5f9ff05590cd0360
+PK: 370c21de6ef2fab534ada999869c90bc9b92ccbf249b79d39d95441d1ede210a
+MSG: d42a1756e84df4b4e9773f86f7674a2cd78e71e40aa8f644e6702dfbc2c2c5ca90fc242e9cb0099cc8f2c2d3136baafc0ff695482fdacdef9f565610b6e1900722f435c6385b35e9f6c436ca037e03f64e2233dffa58db3b91cc1daa0bb0c54c8a43e469d2cff7fa2bf8f5d1d877931089c82ed89aba42f2ee2b86e445cfd09f4cd78b35191bf467e784eef75dc987e046d37d4d4e8e9bbe14af80d03a1f40898384b9d3279fac9c57fd9c7eecbe19a5acc15033b84e07fd0e409bdbd5a57f65641183a6c0a8ec426d1f1d223166ff0a1900b2e92b7d85835d019d17775e5093ccd126f90f63cb7d15cbeb531324219cd64ded6714b21a65371af07210dfdf0e4e58ddc7d59f4cfa65c421d814ee2c9bf6dbf64873d579b09ee5dcedd733063e039ac9a5f9ca4c2525a4cc8e984da7185e2d64fad81c8a
+SIG: e5fd64da028800c6ceed068a5e596f1621c70a8cb138b31b32647eb4b07bd2ecc5942c18844f367033f67398e314ba2c7ccf299c069787777025d845f2aad60e
+
+TST: 313
+SK: 76849c188e3edd0ff5f8fb874dc0456645518445e41a7d6833e616c3c48c9868
+PK: d670e2ea07db60c22ab79a93ebf49d22a6245ee3af07b3be584eda694c37729e
+MSG: 1eccb0bc8eca3ab5bee68c5f8caa34536766c705f50827db7ac375d4fe30b58ffb7e2fe490cc71a8ff86c006d6174d05793ab8a55dd51b06de417bc0ac452cdc7cfb0bb00362b6765d20db23eb1848027064a1d9091d3b10ed776f28b76768bdfc08f0bc511f76faeba76cfc4cb5c83dc9ebe8a8d79edca923eccd524009cafedc90e3ad87d1392e1fccf4e60ccab95dc0ab54bf44245a007a96d46634b1b2965b829c3d7daa765972b54a7b365b6f34d77d7176acd8d894f6b417091b6c00edb7a4e81379988bfcecb692e9c3c4310a7e240e5c1063cde113f22a684a50a112ff47d3898812efb92637072b86163ad89316d221195acbfad0a03a1fbc2d967fe83f84c8459fccd490b9c5b3e55d27e9484e943c417f2128d73701da28f49fd3683f33a39cdee234bd305b9491e2f3eb621be3dd1dbbb31b
+SIG: 7141399d51daa6eb4519bf3f01b233920fa908fefa612f0cd7d5af8a9a3c44190e3f6384a8d14d37c97030ef5018cf8aee8aeb1569a73d84862a59b7df72fe09
+
+TST: 314
+SK: 83ae48ad70da0bb3cdf87481ee2c0c8571c2ca986712f8bc2329e9a3e33383c5
+PK: b785309000df95f5a04f7d89c4113301057adaeeb29bcd28d99371b537bba2f6
+MSG: b7521d3f71c679fa7037fe7488a641f6b97c49454acc8e36b903d8f9ebb54d89cb56efd19e04ba6a7c8f48a7d3ec9decd3f1cd0faf6e978118e6adce9c6c6be63c6a6a1ae21651828479a46bc9a0f7943040f940a0d470c8e577c5d575cb53c1bf3ab1feb050dcb6fef0ba4447f299fdb9f27ecb0714ecfefd74bad7b122a462c24a209848a03389074578c5bdc36396d809b0f14018da64917e6bf87ef405c8f3e333ff9c3baf6339667620794bb4743f0514b5de7d7fdd947a7e3501ee88efad159e33a1072fbb99c7c71e9d13a502d5a07c4f817eeb7f0c5319aa41a96d5ff4f15a73c29b571fe211090e172c8db518624612a5c371a9d7cef6de35ebef96e88e1a78af3bd5dd35251ab54d73718f3e70d2d59021531dc73184f0fc69c2e92965844ec27c1c02af5e9a3469de355db2256e0ec2a4eba30a
+SIG: 43332351d3fb7b45fcf37c607d442ea80dbda2cb69c2884f424e65ea3a331ed8472d4368405cb736b2d6685ad782e239fe833ed789a2923185166f608342ee05
+
+TST: 315
+SK: 39e56a65623a0aebade0da12ce1df378bc924073f73a549effaebc465d1a78e2
+PK: 83da8ad50bad09eb3e94c725df3cc3a119736adc859ca1a10503f48ff2fec596
+MSG: a96dc2ea3fa1351492a4619d9194681f8ec400a97158244482653838ccb7e156a82d564368f83a6ee1be46bc34b817200e8464c3d12b5ef2c50b19565b881c4c3d4563fb947eb47c3ee9c1ee7853269874455bfacba305f307d1ac5309eeae5c07fa5c4d428edbc8b9528c4415243a9ef580aff8fcfb12000a71fceee89de97f90279529bcc822ed3cb34c82ba5fec15f4945663636d67b5feceacc31d25f98aea07f7800d5a1034251cb91dd0963ec2c1a54773a4d96c18357f8d101de58e932f8c6cdde8e3cfcef5a7443fdba7b78320403c0196844724a612183e34bdd808ce7b958861ca37115730eaede1fd0baabe976efefd0365fdf926776c536f47ff80de5c18291bb7e9f1b913ffd1d94468b789752fae6ca897c0cca53ef1e731d00c8bdbe8929ea6b1dce1f31a20688d37b0f3a2b4153b306bdba1
+SIG: 398e8260011f57d8ac8c58d5457bc652c7414aaf6fb2f426b7899056605c0afc28392423b2b571f5e6c3c7f6d60245e53ebd03bdc5ad3c1ad8738cb32214d00f
+
+TST: 316
+SK: 4b9921852f409a323ae38175e8d76a211fc4d9c654178eea3baa7a767a6fda06
+PK: 4c723e436b6bd97f44af52503b21cc50d5f6ad6cfc8288345dde8054e995582e
+MSG: 3f33d8fb83e68741090a37bedd745cf141aaaed8c92ffa742a52561777885805ace14246ab98a8cb598c9ce3de9b29bae5fa04b1cf828de11aff80a7ef8a3a38aede4f3c3563a25d049badcad5ed7e47fdbba6e111307eebe9ef4906bc989728b76e84afe808e6653b271e21104aa665f1898dd2aab23090e22b4e344a2616fbd8ee4ad8ed8108395eba817fbd14fec5c17dcf56b8220856b2b833e091407d5089b35ddf34b86ff7dc9fde52b21ef12176ef3370b7f3a0a8cb1b058a51aefff3d279d80f51a68bfb592587b45c5c63a7e4d625b887de486a118316c3b6a238575f92ac5b1c94c3f5dbbd96686000d6d39cccd558d420e4d447a8cbc4bc7b8c6a03af0f0034fb3518d93800f0f713e4b13732e16ada51801d7e559cf839d1058f64955698311399345416850dddcc5601a684fd09e6afd3944f5e19
+SIG: cbf1f1642df950eb71fd09590d34c265922c58bd8026bba3fc0e594a6bb1f2b90da3dc1d5f6b6d5b405a896d1dbb71b8685c4dfc444acaffe65ab8331789f507
+
+TST: 317
+SK: 1bff652a2c8309a393ac11da3aa97fb078bb284ed5e1b8ccc983652ef8556cd0
+PK: aaabdc091fc3682354201744e9b73fd2a6cfb281914bf2c70ec3dc1dec7216b0
+MSG: 48d02698a97bdcb3ef078dcfcf5750005f1702d300e7e89bc436e381113401f852b8b4acff60ffbd4ab46d202168d98b8735e79cb350e35b070ff6bdcafd954b551969b6b1a70c9131ebd40d96140291d8d2b091540a8b18d8e5465915c25dbc6b5c9a687942533c372c8b4e95a953677169b950edd3464375cd43132ff9bd541ee22bd418ce23195f65d8b289f633ec8d71e1a801b06c3c827f627e723d2199100ce73e8e4a4440e778317a474910793b47b10ffb55db7f281c7d7a033bd80048b82673b87cf95e99422ba628688f3c971890ca15d12f572fa1977a17307069da304ead3026eb01042668890d17008cd1e92c46cbe9c857e7193de3aba3911e4f86fe0a1698ab7cdb9251a8424b2848b96ad81ea239d365fdea92ea5c0473d0a6bb1e371356bdfad2d0350336d3e1947c936fd0c25195445011731b
+SIG: 93c9c33493fc64172d51e16a0a1cd729a0d99e3cb864e89a42987f39dd8cd26545fdfe37581911e803677da4c55b0a683ddf62b728f8f30685ae58f628ebe609
+
+TST: 318
+SK: 002fdd1f7641793ab064bb7aa848f762e7ec6e332ffc26eeacda141ae33b1783
+PK: 77d1d8ebacd13f4e2f8a40e28c4a63bc9ce3bfb69716334bcb28a33eb134086c
+MSG: 5ac1dfc324f43e6cb79a87ab0470fa857b51fb944982e19074ca44b1e40082c1d07b92efa7ea55ad42b7c027e0b9e33756d95a2c1796a7c2066811dc41858377d4b835c1688d638884cd2ad8970b74c1a54aadd27064163928a77988b24403aa85af82ceab6b728e554761af7175aeb99215b7421e4474c04d213e01ff03e3529b11077cdf28964b8c49c5649e3a46fa0a09dcd59dcad58b9b922a83210acd5e65065531400234f5e40cddcf9804968e3e9ac6f5c44af65001e158067fc3a660502d13fa8874fa93332138d9606bc41b4cee7edc39d753dae12a873941bb357f7e92a4498847d6605456cb8c0b425a47d7d3ca37e54e903a41e6450a35ebe5237c6f0c1bbbc1fd71fb7cd893d189850295c199b7d88af26bc8548975fda1099ffefee42a52f3428ddff35e0173d3339562507ac5d2c45bbd2c19cfe89b
+SIG: 0df3aa0d0999ad3dc580378f52d152700d5b3b057f56a66f92112e441e1cb9123c66f18712c87efe22d2573777296241216904d7cdd7d5ea433928bd2872fa0c
+
+TST: 319
+SK: 25b0f0bb3dcb422a6f3c6c220eaadb11dbfe489c2d455b276cefe8cba057f9f3
+PK: fe03c9c4394adc74b13f47654bead8bc855958b4194fdab2097ac1b157933c05
+MSG: 54d99f969efa8870fc20fa9a962bb372619c324439728af3139c2a07e8c1b29c1e4eedc2d40ba722f63ce37670362af6f5202add668c4fb4d62fa8bacbc7d07ff3bd38c15a01064259cc34134861632967460541a99b8d5182bf59347b5a59879aa3b091a1f3e04135bd6301be5226d4895e5e9c2b15e48e5ecdf44129e6122853a606fc118466fa720b5ab165635c3bde04d74289274fa03547accbde780e1fa0bf2c56f8436a53e73878a424a29aa9de385dba419ae6a5d12e004276152b58d325b302400a55333c38cde4908ae1d0121cbeca950809c543314277c1485e68d9f9c0a962d1b1e0dda1d4a52b56f8308a80b92acc9f4ebc3ed45d91a129da8675621af676703def3b84113183b2e3a8c56157f243f13980f3d1756fea7668c91503d35c839a2120c79ec954fb546d7b542f987289534ffdef62d47fd5ec
+SIG: da50d5242bf51c3951780cafd926d67bdf5640d5d3bb08433831d56e48e2592a1c375968bb4d2fbea56145abf2d82991363b1565fa1effe214011a686e39950e
+
+TST: 320
+SK: bf5ba5d6a49dd5ef7b4d5d7d3e4ecc505c01f6ccee4c54b5ef7b40af6a454140
+PK: 1be034f813017b900d8990af45fad5b5214b573bd303ef7a75ef4b8c5c5b9842
+MSG: 16152c2e037b1c0d3219ced8e0674aee6b57834b55106c5344625322da638ecea2fc9a424a05ee9512d48fcf75dd8bd4691b3c10c28ec98ee1afa5b863d1c36795ed18105db3a9aabd9d2b4c1747adbaf1a56ffcc0c533c1c0faef331cdb79d961fa39f880a1b8b1164741822efb15a7259a465bef212855751fab66a897bfa211abe0ea2f2e1cd8a11d80e142cde1263eec267a3138ae1fcf4099db0ab53d64f336f4bcd7a363f6db112c0a2453051a0006f813aaf4ae948a2090619374fa58052409c28ef76225687df3cb2d1b0bfb43b09f47f1232f790e6d8dea759e57942099f4c4bd3390f28afc2098244961465c643fc8b29766af2bcbc5440b86e83608cfc937be98bb4827fd5e6b689adc2e26513db531076a6564396255a09975b7034dac06461b255642e3a7ed75fa9fc265011f5f6250382a84ac268d63ba64
+SIG: 279cace6fdaf3945e3837df474b28646143747632bede93e7a66f5ca291d2c24978512ca0cb8827c8c322685bd605503a5ec94dbae61bbdcae1e49650602bc07
+
+TST: 321
+SK: 65de297b70cbe80980500af0561a24db50001000125f4490366d8300d3128592
+PK: ba8e2ad929bdcea538741042b57f2067d3153707a453770db9f3c4ca75504d24
+MSG: 131d8f4c2c94b153565b86592e770c987a443461b39aa2408b29e213ab057affc598b583739d6603a83fef0afc514721db0e76f9bd1b72b98c565cc8881af5747c0ba6f58c53dd2377da6c0d3aa805620cc4e75d52aabcba1f9b2849e08bd1b6b92e6f06615b814519606a02dc65a8609f5b29e9c2af5a894f7116ef28cfd1e7b76b64061732f7a5a3f8aa4c2e569e627a3f9749aa597be49d6b94436c352dd5fa7b83c92d2610faa32095ca302152d91a3c9776750e758ee8e9e402c6f5385eaa5df23850e54beb1be437a416c7115ed6aa6de13b55482532787e0bee34b83f3084406765635497c931b62a0518f1fbc2b891dc7262c7c6b67eda594fa530d74c9329bad5be94c287fbcde53aa80272b83322613d9368e5904076fdbcc88b2c0e59c10b02c448e00d1b3e7a9c9640feffb9523a8a60e1d83f04a4b8df69153b
+SIG: 7a9b736b01cc92a3349f1a3c32dbd91959825394ff443c567405e899c8185ce8fad9500e1fce89d95a6253c00477435acf04bff993de1b00495def0834ee1f07
+
+TST: 322
+SK: 0826e7333324e7ec8c764292f6015d4670e9b8d7c4a89e8d909e8ef435d18d15
+PK: ffb2348ca8a018058be71d1512f376f91e8b0d552581254e107602217395e662
+MSG: 7f9e3e2f03c9df3d21b990f5a4af8295734afe783accc34fb1e9b8e95a0fd837af7e05c13cda0de8fadac9205265a0792b52563bdc2fee766348befcc56b88bbb95f154414fb186ec436aa62ea6fcabb11c017a9d2d15f67e595980e04c9313bc94fbc8c1134c2f40332bc7e311ac1ce11b505f8572ada7fbe196fba822d9a914492fa7185e9f3bea4687200a524c673a1cdf87eb3a140dcdb6a8875613488a2b00adf7175341c1c257635fa1a53a3e21d60c228399eea0991f112c60f653d7148e2c5ceb98f940831f070db1084d79156cc82c46bc9b8e884f3fa81be2da4cdda46bcaa24cc461f76ee647bb0f0f8c15ac5daa795b945e6f85bb310362e48d8095c782c61c52b481b4b002ad06ea74b8d306eff71abf21db710a8913cbe48332be0a0b3f31e0c7a6eba85ce33f357c7aeccd30bfb1a6574408b66fe404d31c3c5
+SIG: 4bac7fabec8724d81ab09ae130874d70b5213492104372f601ae5abb10532799373c4dad215876441f474e2c006be37c3c8f5f6f017d0870414fd276a8f42808
+
+TST: 323
+SK: 00ad6227977b5f38ccda994d928bba9086d2daeb013f8690db986648b90c1d45
+PK: 91a4ea005752b92cbebf99a8a5cbecd240ae3f016c44ad141b2e57ddc773dc8e
+MSG: cb5bc5b98b2efce43543e91df041e0dbb53ed8f67bf0f197c52b2211e7a45e2e1ec818c1a80e10abf6a43535f5b79d974d8ae28a2295c0a6521763b607d5103c6aef3b2786bd5afd7563695660684337bc3090739fb1cd53a9d644139b6d4caec75bda7f2521fbfe676ab45b98cb317aa7ca79fc54a3d7c578466a6aa64e434e923465a7f211aa0c61681bb8486e90206a25250d3fdae6fb03299721e99e2a914910d91760089b5d281e131e6c836bc2de08f7e02c48d323c647e9536c00ec1039201c0362618c7d47aa8e7b9715ffc439987ae1d31154a6198c5aa11c128f4082f556c99baf103ecadc3b2f3b2ec5b469623bc03a53caf3814b16300aedbda538d676d1f607102639db2a62c446707ce6469bd873a0468225be88b0aef5d4020459b94b32fe2b0133e92e7ba54dd2a5397ed85f966ab39ed0730cca8e7dacb8a336
+SIG: dc501db79fd782bc88cae792557d5d273f9ba560c7d90037fe84ac879d684f612a77452c4443e95c07b8be192c35769b17bbdfca42280de796d92119d833670d
+
+TST: 324
+SK: 1521c6dbd6f724de73eaf7b56264f01035c04e01c1f3eb3cbe83efd26c439ada
+PK: 2f61a26ffb68ba4f6e141529dc2617e8531c7151404808093b4fa7fedaea255d
+MSG: 3e3c7c490788e4b1d42f5cbcae3a9930bf617ebdff447f7be2ac2ba7cd5bcfc015760963e6fe5b956fb7cdb35bd5a17f5429ca664f437f08753a741c2bc8692b71a9115c582a25b2f74d329854d60b7817c079b3523aaff8793c2f72fff8cd10592c54e738df1d6452fb72da131c6731ea5c953c62ea177ac1f4735e5154477387109afae15f3ed6eeb08606e28c81d4386f03b9376924b6ef8d221ee29547f82a7ede48e1dc17723e3d42171eeaf96ac84bedc2a01dd86f4d085734fd69f91b5263e439083ff0318536adff4147308e3aafd1b58bb74f6fb0214a46fdcd3524f18df5a719ce57319e791b4ea606b499bfa57a60e707f94e18f1fed22f91bc79e6364a843f9cbf93825c465e9cae9072bc9d3ec4471f21ab2f7e99a633f587aac3db78ae9666a89a18008dd61d60218554411a65740ffd1ae3adc06595e3b7876407b6
+SIG: a817ed23ec398a128601c1832dc6af7643bf3a5f517bcc579450fdb4759028f4966164125f6ebd0d6bf86ff298a39c766d0c21fdb0cbfdf81cd0eb1f03cd8a08
+
+TST: 325
+SK: 17e5f0a8f34751babc5c723ecf339306992f39ea065ac140fcbc397d2dd32c4b
+PK: 4f1e23cc0f2f69c88ef9162ab5f8c59fb3b8ab2096b77e782c63c07c8c4f2b60
+MSG: c0fad790024019bd6fc08a7a92f5f2ac35cf6432e2eaa53d482f6e1204935336cb3ae65a63c24d0ec6539a10ee18760f2f520537774cdec6e96b55536011daa8f8bcb9cdaf6df5b34648448ac7d7cb7c6bd80d67fbf330f8765297766046a925ab52411d1604c3ed6a85173040125658a32cf4c854ef2813df2be6f3830e5eee5a6163a83ca8849f612991a31e9f88028e50bf8535e11755fad029d94cf25959f6695d09c1ba4315d40f7cf51b3f8166d02faba7511ecd8b1dded5f10cd6843455cff707ed225396c61d0820d20ada70d0c3619ff679422061c9f7c76e97d5a37af61fd62212d2dafc647ebbb979e61d9070ec03609a07f5fc57d119ae64b7a6ef92a5afae660a30ed48d702cc3128c633b4f19060a0578101729ee979f790f45bdbb5fe1a8a62f01a61a31d61af07030450fa0417323e9407bc76e73130e7c69d62e6a7
+SIG: efe2cb63fe7b4fc98946dc82fb6998e741ed9ce6b9c1a93bb45bc0a7d8396d7405282b43fe363ba5b23589f8e1fae130e157ce888cd72d053d0cc19d257a4300
+
+TST: 326
+SK: 0cd7aa7d605e44d5ffb97966b2cb93c189e4c5a85db87fad7ab8d62463c59b59
+PK: 4889855fe4116b4913927f47f2273bf559c3b394a983631a25ae597033185e46
+MSG: 28a55dda6cd0844b6577c9d6da073a4dc35cbc98ac158ab54cf88fd20cc87e83c4bba2d74d82ce0f4854ec4db513de400465aaa5eee790bc84f16337072d3a91cde40d6e0df1ba0cc0645f5d5cbbb642381d7b9e211d25267a8acf77d1edb69c3a630f5b133d24f046a81bf22ff03b31d8447e12c3f7b77114a70cbd20bbd08b0b3827a6bbcf90409e344447a7fbc59bdd97d729071f8d71dcc33e6ef2cbab1d411edf13734db1dd9703276f5eb2d6aa2cb8952dd6712bfae809ce08c3aa502b8135713fac0a9c25b1d45b6a5831e02421bba65b81a596efa24b0576bd1dc7fdfb49be762875e81bd540722bc06140b9aa2ef7b84a801e41ded68d4546ac4873d9e7ced649b64fadaf0b5c4b6eb8d036315233f4326ca01e03393050cd027c24f67303fb846bd2c6b3dba06bed0d59a36289d24bd648f7db0b3a81346612593e3ddd18c557
+SIG: bf9115fd3d02706e398d4bf3b02a82674ff3041508fd39d29f867e501634b9261f516a794f98738d7c7013a3f2f858ffdd08047fb6bf3dddfb4b4f4cbeef3003
+
+TST: 327
+SK: 33371d9e892f9875052ac8e325ba505e7477c1ace24ba7822643d43d0acef3de
+PK: 35929bded27c249c87d8b8d82f59260a575327b546c3a167c69f5992d5b8e006
+MSG: 27a32efba28204be59b7ff5fe488ca158a91d5986091ecc4458b49e090dd37cbfede7c0f46186fabcbdff78d2844155808efffd873ed9c9261526e04e4f7050b8d7bd267a0fe3d5a449378d54a4febbd2f26824338e2aaaf35a32ff0f62504bda5c2e44abc63159f336cf25e6bb40ddb7d8825dff18fd51fc01951eaedcd33707007e1203ca58b4f7d242f8166a907e099932c001bfb1ec9a61e0ef2da4e8446af208201315d69681710d425d2400c387d7b9df321a4aec602b9c656c3e2310bff8756d18b802134b15604f4edc111149a9879e31241dd34f702f4c349617b13529769a772f5e52a89c098e0dca5920667893a250061b17991626eb9319298685be46b6a8b68422444fa5a36bcf3a687e2eccb9322c87dc80165da898930850b98fc863cada1aa99c6d61c451b9ccf4874c7f0e75b0a0c602f044812c71765adaf02025395b0
+SIG: 985ca446ddc007827cc8f2852cbd8115ef8c5975e9d7ce96d74dfed859aa14a4c15254006bea5e08359efe2625d715e0897ee5a16f151203be5010418637de05
+
+TST: 328
+SK: beedb8073df58f8c1bffbdbd77ec7decb2c82a9babecefc0331507bdc2c2a7e7
+PK: b27e908b805e296fc30d2e474b060cd50c0f6f520b3671712183bd89d4e733e9
+MSG: 35ca57f0f915e5209d54ea4b871ffb585354df1b4a4a1796fbe4d6227d3e1aba5171ed0391a79e83e24d82fdafd15c17b28bf6c94d618c74d65264e58faaacd2902872fdd0efa22e8d2d7ce8e3b8197f0c3615b0a385235fa9fd8e4564ee6e6b1650b4cfb94d872c805c32d4f3a18f966461d3adbb605fa525884f8eb197627396ba4d995d78ac02948a0eaabb58519b9a8e2e7985cd1de2c71d8918d96a0168660ce17cddf364e3ec0d4bd90f2104751a1927ee1d23f3e7a69840ed040b00e5f6e4866ec58813149cc382aebf6162608c79574d553f47230e924a0ef1ebf55d8e1a52abb62a2d7ac86027c7c03cc83fa1949da29e2f3037ab986fd2fffe650e3149babae5a50b1ee9696f3babec72e29697c82422814d272085500fd837fe3c7a973ef4c169af12dd7f02700620bb045bdbf84623f326350570b3cadbc9aea4200b28287e17ab
+SIG: 8c890cccadc7760e1e82e43c44b3dc0b685a48b479ae13cc0a6b0557d0fb1cbabba63d2a96843412ea8d36c50acbf52b92cfb2dce49dc48af6ddcf8ee47a8608
+
+TST: 329
+SK: 9184ef618816832592bc8eb35f4ffd4ff98dfbf7776c90f2aad212ce7e03351e
+PK: 687b7726010d9bde2c90e573cd2a2a702ff28c4a2af70afc7315c94d575601e5
+MSG: 729eb7e54a9d00c58617af18c345b8dc6e5b4e0f57de2f3c02e54a2ec8f1425ec2e240775b5ab0c10f84ac8bafda4584f7e21c655faecd8030a98906bd68398f26b5d58d92b6cf045e9bd9743c74c9a342ec61ce57f37b981eac4d8bf034608866e985bb68686a68b4a2af88b992a2a6d2dc8ce88bfb0a36cf28bbab7024abfa2bea53313b66c906f4f7cf66970f540095bd0104aa4924dd82e15413c22679f847e48cd0c7ec1f677e005fec0177fbd5c559fc39add613991fbaeae4d24d39d309ef74647f8192cc4c62d0642028c76a1b951f6bc9639deb91ecc08be6043f2109705a42c7eae712649d91d96ccbbfb63d8d0dd6dd112160f61361ecdc6793929ca9aef9ab56944a6fa4a7df1e279eaf58ce8323a9cf62c94279fff7440fbc936baa61489c999330badcb9fc0e184bc5093f330cbb242f71fb378738fea10511dd438364d7f76bcc
+SIG: b3c24e75132c563475422d5ea412b5c1e8e6e5ea1c08ead1393c412da134c9a1638284ea7e2ca032fe3d3e32a9066a8c8839903f6ef46e966bb5e492d8c2aa00
+
+TST: 330
+SK: 354e13152ee1fe748a1252204c6527bdc1b1eb2eb53678150e6359924708d812
+PK: d45ff6c5fb83e7bb9669aa8960deb7dbc665c988439b6c9ef672c6811dc8bcf6
+MSG: 8e5fccf66b1ba6169cb685733d9d0e0190361c90bcab95c163285a97fe356d2bdcde3c9380268805a384d063da09ccd9969cc3ff7431e60a8e9f869cd62faa0e356151b280bc526e577c2c538c9a724dc48bf88b70321d7e1eeedb3c4af706748c942e67bdabdb41bec2977b1523069e31e29b76300288f88a51b384b80cc2526f1679340ddec3881f5cd28b0378d9cd0a812b68dd3f68f7a23e1b54bee7466ac765cf38df04d67441dfa498c4bffc52045fa6d2dbcdbfa33dfaa77644ffccef0decdb6790c70a0d734ec287cc338cb5a909c0055189301169c4f7702c05c0911a27b16ef9ed934fa6a0ca7b13e413523422535647968030edc40cd73e7d6b345b7581f438316d68e3cd292b846d3f4f7c4862bc7e6b3fb89a27f6f60cd7db2e34ec9aae1013fe37acff8ad888cb9a593ef5e621eae5186c58b31dcfde22870e336d33f440f6b8d49a
+SIG: de2b46e65f3decef34332e500f2e11306fbdcf1be85a1c1ee68ba3045dcec2c7be608d22927da1f44c0e2083ae622cf3c29d893887994efcfa2ca594f5051f03
+
+TST: 331
+SK: 7ff62d4b3c4d99d342d4bb401d726b21e99f4ef592149fc311b68761f5567ff6
+PK: 7fdfdb9eca29d3f01d9486d7e112ce03aa37b91326a4283b9c03999c5eda099a
+MSG: 99c44c796572a4823fc6c3807730839173774c05dbfc1492ed0d00509a95a1de37274b3135ed0456a1718e576597dc13f2a2ab37a45c06cbb4a2d22afad4d5f3d90ab3d8da4dcdaa06d44f2219088401c5dceee26055c4782f78d7d63a380608e1bef89eeef338c2f0897da106fafce2fb2ebc5db669c7c172c9cfe77d3109d239fe5d005c8ee751511b5a88317c729b0d8b70b52f6bd3cda2fe865c77f36e4f1b635f336e036bd718bec90ee78a802811510c4058c1ba364017253aa842922e1dd7d7a0f0fc9c69e43fc4eaeffaaf1ae5fa5d2d73b43079617baba030923fe5b13d2c1c4fe6fac3f2db74e2020a734b6121a0302fce820ba0580ce6135348fdf0632e0008df03ee112168f5cfa0037a26a1f69b1f1317edf2a3ab367455a77e00691215d7aa3133c2159d3da2b134cf04f0defbf07a6064011e64dd14d4f8f064356655428804c2771a
+SIG: 058f79927fbf6178724815c7b11c63baaa90bcc15d7272be082f8a9141861c816433055f6cf6491424853f9ec78bb91ace913a93411b4e5ed58bc4ba5715c60a
+
+TST: 332
+SK: 6cabadd03f8a2e6ebab96a74f80e18164e4d1b6baa678f5a82e25604af989aaf
+PK: 2a4a3179564194e00100c18bc35351d8b135bbae5b32b28fce1d7b6766ca4b32
+MSG: 279f78cf3b9ccfc6e1b01e1a82f50ed172e9a8e1e702bb15661dd7dc3a456ff7a7a7fdfb081db3867079630c7f70fd753292ec60ecbf50632e9aa45b996505c66e6dc3c6ae892e21b6a8705e4bbae8f16a3378554b31fdb0139dcd15c96a8a7e4b88756a86d18db5dc74fd7691197dd88e2c7d5df52b049344cdc477c9cd7e89eda99ccfb1d00814d0152b9654df3279372ca5f18b1c946f2894a76b079ddb1c3cd61fbb969aeec9193a6b88fb7d136c07f9821e5c1074b4e93bcaf6fa14d0d1d7e1707589d77ec1337206e53a1f06cc26672ff95c13d5ff444766931ba30a0afdcdadd2098e9c41fd87a3f23cd16dbb0efbf8092ce33e327f42610990e1cee6cb8e54951aa081e69765ae4009aeed758e768de50c23d9a22b4a06dc4d19fc8cbd0cdef4c983461755d0a3b5d6a9c12253e09568339ff7e5f78c5fdf7ec89f9186a621a8c0eed11b67022e
+SIG: 4e65c6c1d493045e8a9250e397c1d1d30ffed24db66a8961aa458f8f0fcb760c39fe8657d7ab8f84000b96d519717cff71f926522c1efec7f8b2624eae55f60c
+
+TST: 333
+SK: 0fa0c32c3ae34be51b92f91945405981a8e202488558a8e220c288c7d6a5532d
+PK: d6aee62bd91fc9453635ffcc02b2f38dcab13285140380580ccdff0865df0492
+MSG: 53f44be0e5997ff07264cb64ba1359e2801def8755e64a2362bddaf597e672d021d34fface6d97e0f2b1f6ae625fd33d3c4f6e9ff7d0c73f1da8defb23f324975e921bb2473258177a16612567edf7d5760f3f3e3a6d26aaabc5fde4e2043f73fa70f128020933b1ba3b6bd69498e9503ea670f1ed880d3651f2e4c59e79cabc86e9b703394294112d5d8e213c317423b525a6df70106a9d658a262028b5f45100cb77d1150d8fe461eed434f241015f3276ad7b09a291b4a7f35e3c30051cbf13b1d4a7fa0c81a50f939e7c49673afdc87883c9e3e61f5a1df03755470fda74bf23ea88676b258a97a280d5f90b52b714b596035bae08c8d0fe6d94f8949559b1f27d7116cf59dd3cfbf18202a09c13f5c4fbc8d97225492887d32870c2297e34debd9876d6d01ac27a16b088b079079f2b20feb02537cda314c43cb2dca371b9df37ed11ec97e1a7a6993a
+SIG: 7e9ab85ee94fe4b35dcb545329a0ef25923de5c9dc23e7df1a7e77ab0dcfb89e03f4e785ca6429cb2b0df50da6230f733f00f33a45c4e576cd40bdb84f1ae001
+
+TST: 334
+SK: 7b06f88026fa86f39fce2426f67cc5996bedd0cfc4b5ebb1b5e3edbb47e080aa
+PK: 3f1469ee6a2e7867e2e9012d402cf5a4861497c01df879a1deb1c539830b58de
+MSG: 71175d4e21721297d9176d817f4e785d9600d923f987fe0b26fd79d33a5ea5d1e818b71f0f92b8c73afddabdcc27f6d16e26aafa874cfd77a00e06c36b041487582bb933760f88b419127345776ea418f83522254fed33819bc5c95f8f8404cc144ebf1486c88515409d3433aaf519d9920f5256e629419e9a95580a35b069b8d25533dfcbc98ad36404a951808e01378c03266326d120046975fde07daef3266caacd821c1403499d7fdf17c033c8d8c3f28f162b5f09dfdaca06285f00c6cb986dfdf5151aa6639608b5b13e78d65a4368585b16138754fbd113835a686cd066c2b89bb0953c24d50e77bf0fc457c1e0fcf5d44da8db9a88f062be3b688d5cdcff1d1c00e81ec9d413882295b341fee8fa427dc109adeb5f284eec202f1bef115bf96b1782d3ccdeb682b69bf92d170c007d5df80e1ed962f677dc24a145a1e4e829e8dec0104e5f78365944
+SIG: 42f133e34e3eb7032a133ed781537ec62e44a5ce8381e5e0bf9e13a914a4b2c757811d6d3b1e86672424ea4230d10f7c610abb7069e61e319b4066a2bd7bc900
+
+TST: 335
+SK: c3f5e149968a24f4de9119531975f443015ccca305d7119ed4749e8bf6d94fc7
+PK: 39aaccdb948a4038538a4588322f806bb129b5876c4bec51271afe4f49690045
+MSG: c46370e37f2e0cadcf93402f1f0cb048f52881ba750b7a43f56ab11ce348732fb57e7f9aaf8dfcbe455e14e983c248d026a27e7f148d5db5a53f94635702b895127771047a876d14107386c5e0ff8933345bbd7a936d990d33efa28c2ec4e4864ffd2ff576f7c88f954cfc1c459e883bb712dae3cdf6632066f1f4d13a509615b3360cadc5a307f23e52a51b40a6feebe0b18d0e9ee4e348f33cd81a8def222f6a59b12861d335bd9af85cc004be46f1d3a424f4870ae9dc587e5a4ade136b9370649348c33ac3bf1febeebffea37085ed59cac9d9e696470b234609e9a10a9d431ff91e69cb5135fd117ff58a36539744ebe70cea6973c00c7a4d57b62f4a7136d731b8e46ff18ec0ed69070031905075d8541d568cfce6eeb76242b7819a7b6a93552111bb88f165527cfa6966d39fcbe0a7dea008e39c7a3e577ab307cd1d0ea326833d52654e172955f3fcd4
+SIG: 5fa2b531677b00b85b0a313cbd479f55f4ab3ec5cfce5e454d2b74176ccc3399c899f9d6b51ed4c1e76185ac9fe730c4b4014044f7041185bc3c85722eb2ea02
+
+TST: 336
+SK: 42305c9302f45ea6f87e26e2208fd94b3c4ad037b1b6c83cf6677aa1096a013c
+PK: 3b97b1f11ce45ba46ffbb25b76bfc5ad7b77f90cc69ed76115dea4029469d587
+MSG: d110828d449198d675e74e8e39439fd15e75bf2cc1f430abfb245836885bafc420f754b89d2fbbf6dd3490792e7a4f766073cfe3b302d089831ace869e2730fde45c2121ec3ef217aa9c43fa7cc7e9ed0a01ad9f1d2fc3613638ca9fc193c98b37455bf5dbf8f38b64708dfdca6c21f0975f1017c5da5f6434bda9f033cec2a631ab50318e017b170b240bf01eb8b36c7e1cb59e7736ac34444208132a8f59e4f313d65d849c6a4fdf13e20ecaee3823e589a171b39b2489497b06e6ff58c2c9f1dc5d3aa3bd10e6443e22d42d07b783f79fd43a46e1cde314b663a95f7246dea131fcd46d1dc333c5454f86b2c4e2e424dea405cc2230d4dcd39a2eab2f92845cf6a7994192063f1202749ef52dcb96f2b79ed6a98118ca0b99ba2285490860eb4c61ab78b9ddc6acc7ad883fa5e96f9d029171223abf7573e36230e0a81f6c1311151473ee264f4b842e923dcb3b
+SIG: 18d05e5d01668e83f40fa3bbee28b388acf318d1b0b5ad668c672f345c8eda14c2f884cd2a9039459ce0810bc5b580fe70d3964a43edb49e73a6ff914bbf040c
+
+TST: 337
+SK: c57a43dcd7bab8516009546918d71ad459b7345efdca8d4f19929875c839d722
+PK: 2083b444236b9ab31d4e00c89d55c6260fee71ac1a47c4b5ba227404d382b82d
+MSG: a4f6d9c281cf81a28a0b9e77499aa24bde96cc1264374491c008294ee0af6f6e4bbb686396f59068d358e30fe9992db0c6f16680a1c71e27a4a907ac607d39bdc3258c7956482fb37996f4beb3e5051b8148019a1c256e2ee999ebc8ce64c54e07fedb4fbd8953ebd93b7d69ce5a0082edd6209d12d3619b4fd2eae916461f72a4ce727157251a19209bbff9fbdbd289436f3fcacc6b4e1318521a47839cba4b14f7d7a21e7b5d6b6a753d5804afcd2b1eb7779b92abab8afa8aa4fa51caec0b85dcd0fc2a0676036d3f56630a831ffeb502861dd89161c708a9c006c73c930ce5b94756426ff18aa112fb4eb9a68500b48d4eedbd4167b6ffd0a11d49443a173ce9d949436748fc0634f06bb08b8f3423f4463dba7b4d199b64df578117f0a2645f0b2a1e2ada27d286f76733f25b82ed1d48a5c3898d4ad621e50ed9060daad40a39532e4d1bf162ce36804d5d4e2d
+SIG: 1edef9bc036971f1fa88edf45393c802e6c1a1631c8a06871a09a320821dce40beca97e53a0361a955a4c6d60b8ca8e400c81340911ccb4f56284041cdbb1804
+
+TST: 338
+SK: 2dddb6b8fd04fa90ece1a709f8418f2e5d0c9c43afe7cfce19e6ad15a73476f7
+PK: 8059de6a7c4776489ecc2e7d707ffce30285bf30a23f78d72db49cfd6ed0d492
+MSG: 474baa590a4cd72d5424e51d8257b3d44325bc4c5063a0033c86ebbe99ed7212184c19944d082a115379dd4cece973faa0bca6485bd25f3744a719e70aa0291e1b5a96e637c140616a98263357c76b6eb0083fe51414e386870d0fdc7dd9abe4ff6fb5bbf1e7b15dac3e08e2615f655c3104ceb32a4cc2c9e9c43cf282d346ac253ccc46b635ae040973b49735720ffb890469a567c5824e0c00d7ccd5509a718092a906461c4d6163eaf422418f5fc6e009fc3f529ac61a2f89bb8e0ed45d940c4c2331ff8d8e1d6d58d417d8fc2656a02e8701aee75aed918724eebe4a2cf4744c5c401e217023df68a6f6a0228bd05a679a697d8de7036b9ed269090d3c65486afb91e27954eb15b964665ede7ad008f12fb3a9d0e69c13b4254f43819e0818a4195f68b8a38ae81f3fcb1879c95ab4cd0ffc38e381089260cca967ace5a085b457ab5eb363852101377570f9ac9e38
+SIG: c634ea7bf72e895a2e796e2834201415b8b45e05e045559284eb9052c0e84f62a5a9f0c9764f7576788c7228b19ef517c195497325a48a9344b147c12fd75509
+
+TST: 339
+SK: 5547f1004baedfce5cfc0850b05302374aad24f6163994ecd751df3af3c10620
+PK: 7ce620787385ee1951ac49a77352ee0d6f8c5cd47df74e9e3216a6324fc7cf7f
+MSG: a6c17eeb5b8066c2cd9a89667317a945a0c7c96996e77ae854c509c6cd0631e922ad04503af87a3c4628adafed7600d071c078a22e7f64bda08a362b38b26ca15006d38acf532d0dedea4177a2d33f06956d80e963848ec791b2762fa99449b4f1a1ed9b3f2580be3ac7d7f52fb14421d6222ba76f807750c6cbb0b16f0895fc73d9dfc587e1a9e5d1e58375fbab705b8f0c1fd7df8b3ad446f2f08459e7ed1af59556fbc966dc249c1cf604f3e677c8a09d4363608774bf3811bef0642748c55c516c7a580fa3499050acb30eed870d0d91174cb623e98c3ad121cf81f04e57d49b008424a98a31eeaaf5f38e000f903d48d215ed52f862d636a5a73607de85760167267efe30f8a26ebc5aa0c09f5b258d3361ca69d1d7ee07b59648179ab2170ec50c07f6616f216872529421a6334a4a1ed3d2671ef47bc9a92afb58314e832db8a9003408a0487503fe4f67770dd4b6
+SIG: 29df3ad589009c667baa5e72dabb4e53cb7876de4e7efe5cc21ead7fa878db57f97c1103ddb39a861eb88653c1d4ec3b4306e4584b47b8bc90423119e7e4af00
+
+TST: 340
+SK: 3dd7203c237aefe9e38a201ff341490179905f9f100828da18fcbe58768b5760
+PK: f067d7b2ff3a957e8373a7d42ef0832bcda84ebf287249a184a212a94c99ea5b
+MSG: db28ed31ac04b0c2decee7a6b24fc9a082cc262ca7ccf2a247d6372ec3e9120ecedb4542ea593fea30335c5ab9dd318a3b4fd5834299cf3f53d9ef46137b273c390ec3c26a0b4470d0d94b77d82cae4b24587837b167bb7f8166710baeb3ee70af797316cb7d05fa57e468ae3f0bd449404d8528808b41fcca62f5e0a2aa5d8f3acab008cc5f6e5ab02777bdcde87f0a10ef06a4bb37fe02c94815cf76bfb8f5cdd865cc26dcb5cf492edfd547b535e2e6a6d8540956dcba62cfea19a9474406e934337e454270e01036ac45793b6b8aceda187a08d56a2ce4e98f42ea375b101a6b9fcb4231d171aa463eeb43586a4b82a387bcddaf71a80fd5c1f7292efc2bd8e70c11eaa817106061b6c461c4883d613cc06c7e2a03f73d90fc55cdc07265eefd36be72270383d6c676cae37c93691f1ae3d927b3a1cd963e4229757ae5231eea73a9f71515628305410ac2593b325cc631
+SIG: 4c036935a96abc0d050d907bedbe9946fb97439f039c742e051ccf09add7df44d17da98c2ca01bdc2424da1e4debf347f8fff48ac8030d2cc07f9575c044be04
+
+TST: 341
+SK: 282775df9ebbd7c5a65f3a2b096e36ee64a8f8ea719da77758739e4e7476111d
+PK: a2b49646033a13937cad6b0e914e3cec54989c252ca5643d076555d8c55e56e0
+MSG: 14cc50c2973ea9d0187a73f71cb9f1ce07e739e049ec2b27e6613c10c26b73a2a966e01ac3be8b505aeaad1485c1c2a3c6c2b00f81b9e5f927b73bfd498601a7622e8544837aad02e72bf72196dc246902e58af253ad7e025e3666d3bfc46b5b02f0eb4a37c9554992abc8651de12fd813177379bb0ce172cd8aaf937f979642bc2ed7c7a430cb14c3cd3101b9f6b91ee3f542acdf017f8c2116297f4564768f4db95dad8a9bcdc8da4d8fb13ef6e2da0b1316d3c8c2f3ed836b35fe2fd33effb409e3bc1b0f85225d2a1de3bfc2d20563946475c4d7ca9fddbaf59ad8f8961d287ae7dd803e7af1fa612329b1bdc04e225600ae731bc01ae0925aed62ac50d46086f3646cf47b072f0d3b044b36f85cec729a8bb2b92883ca4dfb34a8ee8a0273b31af50982bb6131bfa11d55504b1f6f1a0a00438ca26d8ab4f48bcddc9d5a38851abede4151d5b70d720732a00abea2c8b979
+SIG: 15763973859402907d8dcb86adc24a2a168ba3abf2246173d6348afed51ef60b0c0edeff4e10bcef4c6e5778c8bc1f5e9ee0237373445b455155d23de127a202
+
+TST: 342
+SK: 4730a5cf9772d7d6665ba787bea4c95252e6ecd63ec62390547bf100c0a46375
+PK: f9f094f7cc1d40f1926b5b22dce465784468b20ab349bc6d4fdf78d0042bbc5b
+MSG: e7476d2e668420e1b0fadfbaa54286fa7fa890a87b8280e26078152295e1e6e55d1241435cc430a8693bb10cde4643f59cbfcc256f45f5090c909a14c7fc49d37bfc25af11e8f4c83f4c32d4aabf43b20fa382bb6622a1848f8ffc4dff3408bb4ec7c67a35b4cdaee5e279c0fc0a66093a9f36a60fdd65e6334a804e845c8530b6fda363b5640337d027243ccfb3c177f43e717896e46ead7f72ca06aa0ff1e77247121baf48be9a445f729ca1390fc46151cbd33fcbd7373f27a6ba55c92cbf6945b09b44b9a4e5800d403070ae66048997b2197f02181a097e563f9b9acc841139258a258bc610d3bd891637356b2edc8c184c35c65af91aaf7b1c16d74a5f5f862548139254ecf550631d5f8849afdb5b64cf366ff2633a93f3a18c39b5150245fb5f33c9e4e2d94af6963a70b88f9e7e519f8fa2a0f2e3749de883d0e6f052a949d0fc7153a8693f6d801d7352eb2f7a465c0e
+SIG: 552c7347bdfe131646ce0932d82a36d2c1b76d7c30ee890e0592e19f9d18b9a56f48d7a9b68c017da6b550c943af4a907baf317e419fbbc96f6cf4bfad42de00
+
+TST: 343
+SK: 2770aadd1d123e9547832dfb2a837eba089179ef4f23abc4a53f2a714e423ee2
+PK: 3c5fbb07530dd3a20ff35a500e3708926310fed8a899690232b42c15bd86e5dc
+MSG: a5cc2055eba3cf6f0c6332c1f2ab5854870913b03ff7093bc94f335add44332231d9869f027d82efd5f1227144ab56e3222dc3ddccf062d9c1b0c1024d9b416dfa3ee8a7027923003465e0ffaefb75b9f29dc6bcf213adc5e318fd8ba93a7aa5bfb495de9d7c5e1a196cd3a2d7721f8ba785aa9052a1811c7fcc8f93932765059cab9c9b718945895ef26f3ac048d4cabf91a9e6aa83ac14d43156827837914eb763a23cba53f60f150f4b70203ec1833ff105849457a8da7327661fb23a554164e05fcf0146b10674964be6f6aa0acc94c41ad57180e5180d199bd9102f55d740e81789b15671bbd0670e6de5d97e1ae626d8a0ebc32c8fd9d24737274e47d2dd5941a272e72a598928ad109cde937bf248d57f5d2942983c51e2a89f8f054d5c48dfad8fcf1ffa97f7de6a3a43ca15fc6720efaec69f0836d84223f9776d111ec2bbc69b2dfd58be8ca12c072164b718cd7c246d64
+SIG: f267715e9a84c7314f2d5869ef4ab8d2149a13f7e8e1c728c423906293b49ce6283454dd1c7b04741df2eabedc4d6ab1397dc95a679df04d2c17d66c79bb7601
+
+TST: 344
+SK: 4fdab7c1600e70114b11f533242376af7614b4d5da046ac4bedea21d8a361598
+PK: a25c9a94d6e4ecd95a4bd6805f762eb1c457a8d45d243238b1839cbba8f441cc
+MSG: da405890d11a872c119dab5efcbff61e931f38eccca457edc626d3ea29ed4fe3154fafec1444da74343c06ad90ac9d17b511bcb73bb49d90bafb7c7ea800bd58411df1275c3cae71b700a5dab491a4261678587956aa4a219e1ac6dd3fb2cb8c46197218e726dc7ed234526a6b01c0d72cb93ab3f4f38a08e5940b3f61a72ad2789a0532000fac1d2d2e3ad632ac8b62bb3ff5b99d53597bf4d44b19674924df9b3db3d0253f74627ccab30031c85e291c58b5fa9167522a46746fc307036745d4f9817786e5d300e6c5d503125fea01dec3e3fedbf3861ca2627a0518fb2b24e5a7a014178719e9b345f7b249ce3a413280c8deb674f59a25be92a8ab6400c7c52b0728ae34e22b2ec200c1cbaba2ccd8af29249d17af60c36007a722fc80258a7bebab1cdaad7462a8b7588c2f7e27c6d07afcf60117fed11bd6859e75e3b4fcee3981881e95dd116827dd4b369af069d3c8f2676f8a
+SIG: 5075c090cfbeb6b01802af7f4da5aa4f434d5ee2f3530eebb75c85e08621f83edc08aa96693894a4277633ba81e19e9e55af5c495daa5e1a6f8cbb79c01c7207
+
+TST: 345
+SK: 264504604e70d72dc4474dbb34913e9c0f806dfe18c7879a41762a9e4390ec61
+PK: eb2b518ce7dc71c91f3665581651fd03af84c46bf1fed2433222353bc7ec511d
+MSG: 901d70e67ed242f2ec1dda813d4c052cfb31fd00cfe5446bf3b93fdb950f952d94ef9c99d1c264a6b13c3554a264beb97ed20e6b5d66ad84db5d8f1de35c496f947a23270954051f8e4dbe0d3ef9ab3003dd47b859356cecb81c50affa68c15dadb5f864d5e1bb4d3bada6f3aba1c83c438d79a94bfb50b43879e9cef08a2bfb22fad943dbf7683779746e31c486f01fd644905048b112ee258042153f46d1c7772a0624bcd6941e9062cfda75dc8712533f4057335c298038cbca29ebdb560a295a88339692808eb3481fd9735ea414f620c143b2133f57bb64e44778a8ca70918202d157426102e1dfc0a8f7b1ae487b74f02792633154dfe74caa1b7088fda22fa8b9bc354c585f1567706e2955493870f54169e0d7691159df43897961d24a852ea970c514948f3b48f71ee586e72ec78db820f253e08db84f6f312c4333bd0b732fe75883507783e9a1fd4fbab8e5870f9bf7ad58aa
+SIG: eea439a00f7e459b402b835150a779eed171ab971bd1b58dcc7f9386dadd583de8dc69e267121dde41f0f9493d450b16219cdf3c22f09482ce402fe17ca49e08
+
+TST: 346
+SK: 2ca7447a3668b748b1fd3d52d2080d30e34d397bb2846caf8f659ac168788ca5
+PK: ab331cd40a31d0173c0c8c1c17002532807bf89e3edb6d34c2dd8294632b9fbc
+MSG: a82bcd9424bffda0f2f5e9eae17835dbe468f61b785aab82934737a91c5f602cb7c617cdffe87cad726a4972e15a7b8ee147f062d2a5a4d89706b571fa8aa2b95981c78abeaaae86203fa2c0e07297406ea8c27111a86dbe1d5a7c3b7ae930904d9890f6d4abebd1412a73ad5feea64acf065d3e63b5cbe20cf20bbd2d8b94f9053ed5f66633482530124446605918de66455e8cf4b101a127233c4e27d5d55bf95bd3195d0340d43531fc75faf8dded5275bf89750de838fd10c31745be4ca41fa871cb0f9b016706a1a7e3c44bb90ac7a8ad51e272389292fd6c98ad7a069e76e3f5f3e0cc770b9e9b35a765d0d93712d7cdabd17e5d01dd8183af4ad9365db0a0fa41381fce60a081df1c5ab0f8c18f95a7a8b582dfff7f149ea579df0623b33b7508f0c663f01e3a2dcd9dfbee51cc615220fdaffdab51bdae42cb9f7fa9e3b7c69cc8ada5ccd642529ba514fdc54fcf2720b8f5d08b95
+SIG: f93ada15ae9cd2b54f26f86f0c28392aed5eb6b6b44d01a4e33a54e7da37c38e8d53366f73fd85be642e4ec81236d163f0d025e76c8bbdd65d43df49f09c1f01
+
+TST: 347
+SK: 494ea9bcce26885b7d17d1fc114448f239f0ce46e5f247b4c999fa8629692472
+PK: 6901e5efae57536ba5fdd96b59657359065f25d391a1aa8cdc0d38bb5d53c139
+MSG: 3badbfa5f5a8aa2cce0a60e686cdce654d24452f98fd54872e7395b39464380a0e185557ea134d095730864f4254d3dd946970c10c804fcc0899dfa024205be0f80b1c75449523324fe6a0751e47b4ff4822b8c33e9eaf1d1d96e0de3d4acd89696b7fcc03d49f92f82b9725700b350db1a87615369545561b8599f5ea920a310a8bafc0e8d7468cbf6f3820e943594afdd5166e4e3309dddd7694ef67e694f34fc62724ff96ac3364176f34e8a02b4cf569db5b8f77d58512aedabf0bcd1c2df12db3a9473f948c5c3243309aae46c49efd088b60f31a8a72ad7e5a35acc5d89fa66807eb5d3ba9cdf08d4753cb85089ee36f5c96b432b6928352afad58012225d6157f9e3611426df921b6d1d8374628a63031e9ffb90e42ffbba021f174f68503155430152c9155dc98ffa26c4fab065e1f8e4622c2f28a8cb043110b617441140f8e20adc16f799d1d5096b1f50532be5042d21b81ea46c7
+SIG: 548a093a680361b7dc56f14503b55eeec3b3f4fd4ca99d6aedce0830f7f4ae2f7328539b34c48fc9760922333dae9c7c017e7db73b8faa6c06be05e347992b06
+
+TST: 348
+SK: 00d735ebaee75dd579a40dfd82508274d01a1572df99b811d5b01190d82192e4
+PK: ba02517c0fdd3e2614b3f7bf99ed9b492b80edf0495d230f881730ea45bc17c4
+MSG: 59c0b69af95d074c88fdc8f063bfdc31b5f4a9bc9cecdffa8128e01e7c1937dde5eb0570b51b7b5d0a67a3555b4cdce2bca7a31a4fe8e1d03ab32b4035e6dadbf1532059ee01d3d9a7633a0e706a1154cab22a07cd74c06a3cb601244cf3cf35a35c3100ba47f31372a2da65dcff0d7a80a1055d8aa99212e899aad7f02e949e6fee4d3c9cefa85069eaff1f6ad06fc300c871ab82b2bedb934d20875c2a263242cdb7f9be192a8710b24c7ea98d43daec8baa5553c678a38f0e0adf7d3ff2dcc799a1dbad6eab1c3d9458a9db922f02e75cfab9d65c7336dae71895d5bb15cac203f2b38b9996c410f8655ad22d3c091c20b7f926d45e780128f19747462abc5c58932fbb9e0bc62d53868802f1b083f183b8a1f9434986d5cf97c04e2f3e145730cba98779c7fed0cab1c05d5e4653c6c3f6736260bc78ee4372862ffe9e90371d762c7432781f35ced884a4baca05653ef25f25a6f3d5628308
+SIG: dcdc54611937d2bd06cacd9818b3be15ce7425427a75f50d197a337a3b8ba6714ef48866f243bd5ac7415e914517a2c1c5a953f432b99db0e620d64f74eb8505
+
+TST: 349
+SK: 8c34b905440b61911d1d8137c53d46a1a76d4609af973e18eb4c5709295627bb
+PK: b69a8b2fdf5c20e734c2ffb294bc8ae1011d664f11afe7fbc471925cf72fa99d
+MSG: 30b57a389b48a0beb1a48432bff6b314bded79c4a1763a5acb57cea1bfb4c6d016cf090f5bd05bbd114e33ae7c17782dfa264f46c45f8c599c603016fe9ff05b6b5a99e92fe713a4cd5c41b292ed2bb2e9cf33a440542e821ec82cbf665c3f02e3dc337d7fdb58e31b27cb2954541468814698510df18c85c81fad12db11ec6b966f4930da5646b991db97445097da30dab61cda53a41083cb96add19de6c5eec323bca9d3530e38c00b35af7360077601be6ac97f3030f930a27b90fe8b6911bae389065adc15e1882300e2a003274d23182d5efd5ba4b9130c07bd5c65fecb8b5cb7eb38836b318befdfd77de4d6ca0181f77ae5740891683225f549dd8426145c97c5818c319f7ab2d868e1a41ceab64c085116069897bf2ca3667652406155ed0646431b6de1ccc03b4279ae4d326679265dce82048e7298e1f87fcec0768ac0f5d8ff84f7210be54d411af8edea7217f4e59413121e148c60da
+SIG: 3e0b72073dc9375eedcca6c4fc1cd315938a050c92716bd2284f4629a962beec0b7d7cf16ab923d58f5b90d3901a8e5c75c8f17dab9998e007d8c49511973d0e
+
+TST: 350
+SK: 77a83e18c9f000eeff7deeac959ecba2206c0aa39d2f0e2aed5729482a7a0229
+PK: 62b1b316135596bfbca6037ed847c61fb7f09fa36ce90abb7789b86f768b59dd
+MSG: f3d5fa2acaefd858f1df26e03059cdcbc2468ad74afc993d0db9c4cde4113f8d55c7da71d38ba06520531c61fddb5f33d5f0353be2376e580711be45c0a30b1fa01b55e228c6fa35e3f95b67909fc7df3fd464d93d661a926f9d11f7550c17fbcc3496526e8f10e0c8916677b2be5b319b688f21e81aaa9482e5c93e64ce8c437b9c1e14fefed70a3fee568811dc31cadab3d5b220254465336dc4d97a3bd096b5e065e0cfbe82849e2c1905aca486533f0da7a61f1e9a55b8e2a83262deeb59f2b13d3a8aef5700845b83b25ae2183c0ddac0ce42f8d25674cb0d0d220a6de7c1858bb07d59a3372344d944602aa451d2b937db0fe6feca0beba81721fc361ea7509e2b6d397e1c191b56f54ab436d0d27ab4c061bd661ad1a4452387e8735754d07fa7ef4d4548b172582425b299046e6301b5ba6b914418f149cf722e10bde2e0d41700f12c8429fc897b7819da92292240cd45565458c9a7b29c12
+SIG: 1eaad8420ac12c99ac1ff4476678e3cbbe94da6a797f174664d5ee0f641433fb1e7cb2f5613e10805df8654cd8e0d45d96230932bc7f20b04eae836435134309
+
+TST: 351
+SK: 73b03373ef1fd849005ecd6270dd9906f19f4439e40376cdbc520902bc976812
+PK: 663719e08ba3ba1666f6069a3f54991866b18cc6be41991b02eb3026ff9e155f
+MSG: d5c2deaba795c30aba321bc7de6996f0d90e4d05c747fb4dae8f3451895def6e16e72f38eace756f36635f8fb0b72a3a0c1f54663817a94d4fd346f835ab0e657f001a6f2cecb86d0825bd02639254f7f7f38ca99dbb86c64a633f73baf933aae3563281f4005e2d0e7cec9fbde8e588a957e211068be65b3d3d35bf4e8d5bb3478333df9ced9b2abaf48697994a145e9321499fc5ee560f4fbb6849e1ae8eb3d1de0083a21a03f6a6b28176f0130d3895e50e75e3d7d0947a7bc2c5b9ff69895d27791442ba8d0f2180712b567f712ea912f3b0d92c19342e0106ff1d87b46ad33af300b90855ba9769d366e79425d98e4de19905a04577707cbe625b84691781cd26bf62260b4a8bd605f77af6f970e1b3a112e8918344bd0d8d2e41dfd2ce9895b0246e50887aa3a577ff73be4b6ae60feb0ca36f6a5f8171ed209e5c566529c0940d9b4bd744ccee56e54a9a0c6e4da520dd315c2872b02db563703e
+SIG: a40abe98fc69da8a1ff9ff5c2cca93632e975980ee8b82c3c376022d6524ab736d01b072f2b681b5f1cd3ea067012ed6d074e949c42327a366caa9e4750a3c08
+
+TST: 352
+SK: eab179e41ed5c889ffe6aabdc054faf1307c395e46e313e17a14fe01023ffa30
+PK: 86f34746d3f7a01ddbe322f1aca56d22856d38733a3a6900bb08e776450ec803
+MSG: 971095cebe5031530224387c5c31966e389b8566390054cf45264b44e18964b7be52c33c4ffb259af16283438fa15dd66bc7791b7533ef10cb0beab524a6437626f4cc74512851adcc2fb129055a482c61107383fb7c5241831d5551634eef0dc0b8f9053a00971aa8fa1ae0898e4b481b6707e97c0f942040b339d92fc17bbade74675af243d8b2dafb15b1db55d12415b85f3037291930ab61600ba3431f8eb425be4491614728af101e81c091f348bc5ffd1bde6ae6cad5c15b3aa7358078cc4effb54a86e7f0e0c55e4cfe0a54605ed443fdf2aaba016585da617e77341d52889d75dd540d39fe8b7993ed705cfddea0cb0d5a731d6bfcdb816afaff47e963eedebdf241af5593353d6d401a34f029a8cdeb1904cc2caa4f9635cc2ba6b7b1a29da625ffc383be2f5a8f1fa4f39b2d4b4f4c2d8838ce258a04d4a120493fdf07f68c0ffd1c16b768a35c55fea2cac696b5c20efc10865cde8a64627dcd
+SIG: 143cb28027c2f82e375e5f340e7fe6e60ce7bd51000b49c74168af85e26ed2ed630ed2672090164cc54b052da694ebdd21a21b3053f4dcfd7895ea5f6c8aa80d
+
+TST: 353
+SK: fbf146ebd51075570ec51ac410ae9f391db75b610ada6362b4dbd949656cfb66
+PK: be7c2f5b21d746c8ea3245ce6f268e9da74e00fa85c9c475260c68fa1af6361f
+MSG: cd7ad4f17fcff73acc402dc102d09079b29aaf2a0f4b27cf6beeb1e2b23d19ab47deb3ae1becd68861ea279c46691738f4fff47c43047c4f8b56b6bbcc3fde0723d44120dcd307a6310dc4f366b8f3cd52db19b8266a487f7872391c45fe0d3248a7abf2c20022d3769547f683067dcc363cd22fd7cda3cadc15804056f0e2aa2b795008c598be7a961805e6df291ba3041c47ff5640275f46e6ae82092d21abcbcfba11e730216008822de3ce462400596da79f7ae5d1df8389112ad98868fa94fb0546bfe6a67aa8d28c4d32072d2eadd6256255f18c2382e662dfa922a680e06a43622c4871d27d1807f7b2703070c83db8dd929c06038b2183cb8e2b9ec4c778d7ecf9e9ffac77fa7737b055feac2e7982aeeec0b72f1bbca2424e1a844bbac79cb2e7400f81dc449d0560b521a7c16bb4167e6696586058a9b8ed2e5116690b77f2a17e5c0b16a83dcbd2e24552293e258b32ba7f844944379342698627
+SIG: 6768006fe0f201b217dd10eb05d4b82adcfeb2ecfc8373c3308f4150394811eb60491881a2e53d1289d96478e18a64c34b2a19832cdccfd96a2e4a0c469fdc0b
+
+TST: 354
+SK: dff0eb6b426dea2fd33c1d3fc24df9b31b486facb7edb8502954a3e8da99d9fd
+PK: c245085ece69fb9aa560d0c27fdb634f7a840d41d8463660fbe82483b0f3cc3a
+MSG: e7c9e313d86160f4c74aa0ae07369ee22b27f81b3f69097affae28dae48483fb52a5c062306b59610f5cdbff6332b1960cd6f2b8f7b41578c20f0bc9637a0fdfc739d61f699a573f1c1a0b49294506cf4487965e5bb07bbf81803cb3d5cb3829c66c4bee7fc800ede216150934d277dea50edb097b992f11bb669fdf140bf6ae9fec46c3ea32f888fde9d154ea84f01c51265a7d3fef6eefc1ccdbffd1e2c897f05546a3b1ca11d9517cd667c660ec3960f7a8e5e80202a78d3a388b92f5c1dee14ae6acf8e17c841c9557c35a2eeced6e6af6372148e483ccd06c8fe344924e1019fb91cbf7941b9a176a073415867210670410c5dbd0ac4a50e6c0a509ddfdc555f60d696d41c77db8e6c84d5181f872755e64a721b061fcd68c463db4d32c9e01ea501267de22879d7fc12c8ca0379edb45abaa6e64dda2af6d40ccf24fbebad7b5a8d3e52007945ecd3ddc1e3efeb522581ac80e98c863ba0c590a3ed95cd1
+SIG: 6b48b10f545ddb7a89cd5829f4e5b20146cf6bc96e550d06f65de8bdae7ccdded26cd630f86c9266bccf88e924033e04f83a54f8290d7f734cf8673cca8f9703
+
+TST: 355
+SK: 9f32958c7679b90fd5036056a75ec2eb2f56ec1effc7c012461dc89a3a167420
+PK: 1d7269dcb6d1f584e662d4ce251de0aba290ef78b97d448afb1e5333f1976d26
+MSG: a56ba86c71360504087e745c41627092ad6b49a71e9daa5640e1044bf04d4f071ad728779e95d1e2460584e6f0773545da82d4814c9189a120f12f3e3819813e5b240d0f26436f70ee353b4d20cea54a1460b5b8f1008d6f95f3aa2d8f1e908fced50d624e3a096938b9353854b96da463a2798a5a312ec790842c10c446e3350c764bf5c972593b9987bf23256daa8894d47f22e85b97607e66fc08a12c789c4746080368d321bb9015a1155b65523ad8e99bb989b44eac756b0734acd7c6357c70b59743246d1652d91b0f9896965141345b9945cf34980452f3502974edb76b9c785fb0f4395266b055f3b5db8aab68e9d7102a1cd9ee3d142504f0e88b282e603a738e051d98de05d1fcc65b5f7e99c4111cc0aec489abd0ecad311bfc13e7d1653b9c31e81c998037f959d5cd980835aa0e0b09bcbed634391151da02bc01a36c9a5800afb984163a7bb815edbc0226eda0595c724ca9b3f8a71178f0d20a5a
+SIG: 9881a5763bdb259a3fefbba3d957162d6c70b804fa94ab613406a6ec42505b8789465ca1a9a33e1895988842270c55e5bdd5483f6b17b31781b593507a6c1808
+
+TST: 356
+SK: f86d6f766f88b00717b7d6327eb26cf3ceeba5385184426f9cfd8295e2421ff2
+PK: cb1d250504754183704dbe21c323d66f9f9011758f6d8dab6f597b199662145b
+MSG: da8423a6b7a18f20aa1f90ed2331b17b24067c40175bc25d8109e21d87ac00528eb3b2f66a2b52dc7ef2f8cecb75c76099cfa23db8da897043ba1cce31e2dfea46075f5e073203eaeb3d62c84c107b6dab33a14eaf149aa61850c15f5a58d88a15aba9196f9e495e8dbecbcf7e8444f5dd72a08a099d7f6209990b562974ea829ef11d29a920e3a799d0d92cb50d50f817631ab09de97c31e9a05f4d78d649fcd93a83752078ab3bb0e16c564d4fb07ca923c0374ba5bf1eea7e73668e135031feafcbb47cbc2ae30ec16a39b9c337e0a62eecdd80c0b7a04924ac3972da4fa9299c14b5a53d37b08bf02268b3bac9ea9355090eeb04ad87bee0593ba4e4443dda38a97afbf2db9952df63f178f3b4c52bcc132be8d9e26881213abdeb7e1c44c4061548909f0520f0dd7520fc408ea28c2cebc0f53063a2d30570e05350e52b390dd9b67662984847be9ad9b4cd50b069ffd29dd9c62ef14701f8d012a4a70c8431cc
+SIG: ec61c0b292203a8f1d87235ede92b74723c8d23408423773ae50b1e9bc4464e03e446da9dce4c39f6dd159bea26c009ed00120bc36d4a247dc0d24bcefcc110c
+
+TST: 357
+SK: a5b34cefab9479df8389d7e6f6c146aa8affb0bec837f78af64624a145cc344e
+PK: 7b0f4f24d9972bc6fe83826c52716ad1e0d7d19f123858cb3e99fa636ac9631a
+MSG: e21e98af6c2bac70557eb0e864da2c2b4d6c0a39a059d3477251f6178a39676f4749e7fbea623f148a43a8b0fe0610506fa658abd2f5fa39198f2636b724db22d1aebc2ab07b2b6dbffdee8cece81e1af1493ec1964e16bf86ab258ca0feb77e3c8717e44038abe152c14be15660bf93b2d48d92c4ed7074d2494210621bcf204fba88c654d5ffe01e1a53d08f70bb237089dc807216ff6a85dbec3102237d42590778acf6c1dc566d5a2bb9a63bc21c329c272e5965baeeb0fe891de3cc8cbfa8e541a8881df68942e7ff8dc656bd08575f6aaf924a176d663b1a1f43574d11768c701b269561e55438dbebfd443d2115cb933d1cde4a915b54c325c27f499ef02bd012ff1f9a36390922887600fe712bcdc23eb5974a305372ad52951f83f0e58cc49e289841621917f1fcb0235147240dae4cf3b99b6ac6d8de94efe7c4436714508bcd0114c56068ff1b7c16d51bd906437874d6549ab5d8087896872ec8a09d7412
+SIG: 2fbd899d72b6d39e4f45b8b62cbbd5f3c0acb1ad8540913fa585877e91ccfef7bee50a4b0f9fedf5cc1e0d1953ad399c8389a93391e1b7c929af6d6f3b796c08
+
+TST: 358
+SK: ad75c9ce299c4d59393367d77a4c9f8df8dcec765c6dbd25b527fb7669913604
+PK: b9910548fe6312a119c9993eebcfb9dc90030ffb0e4de2b7ccd23cbeb4fef71b
+MSG: 62fc5ab67deb1fee9ab6cca3b88a1df1e589f0fd4a88f4aa7738948761fe84372c5b18e4655220c1d84d52acad32e229a5c756c20fc62fe4b4b4e5fd7077ae4ed5397aa796f2307ceedb6505b39297856f4aeb5e70938e36ee24a0ac7d9868306f6b53910623b7dc89a6672ad738576ed5d88831dd338321c8902bc2061f65e94d452fdfa0dc665cefb92308e52301bd4627006b363d06b775a395914d8c863e95a00d6893f3376134c429f56478145e4456f7a12d65bb2b8965d728cb2ddbb708f7125c237095a92195d92fa727a372f3545ae701f3808fee802c8967a76e8a940e55fb2d810bfb47ada156f0eda1829b159cf05c7f36cf3847d7b21de84c3dc0fe658347f79396a01139a508b60022db1c0e5aeef47e445e66f783e62c96597bdb16f209c08a9132c7573136170ee3ebf24261265a89fb4f10333375e20b33ab7403464f5249461c6853c5fddb9f58af816892910393a7077b799fdc3489720998feea86
+SIG: 6b7ef27bcfbf2b714985033764fccff555e3f5bc44610d6c8c62117cb3831a07f4a8bddb0eaed1d46b0289b15de1aa4dcc17d71be96a09e66ba4dc4627c78705
+
+TST: 359
+SK: 1ced574529b9b416977e92eb39448a8717cac2934a243a5c44fb44b73ccc16da
+PK: 85e167d5f062fee82014f3c8b1beaed8eefb2c22d8649c424b86b21b11eb8bda
+MSG: 1b3b953cce6d15303c61ca707609f70e7250f6c0deba56a8ce522b5986689651cdb848b842b2229661b8eeabfb8570749ed6c2b10a8fbf515053b5ea7d7a9228349e4646f9505e198029fec9ce0f38e4e0ca73625842d64caf8ced070a6e29c743586aa3db6d82993ac71fd38b783162d8fe04ffd0fa5cbc381d0e219c91937df6c973912fc02fda5377312468274c4bee6dca7f79c8b544861ed5babcf5c50e1473491be01708ac7c9ff58f1e40f855497ce9d7cc47b9410f2edd00f6496740243b8d03b2f5fa742b9c630867f77ac42f2b62c14e5ebddc7b647a05fff43670745f2851eff4909f5d27d57ae87f61e965ee60fdf97724c59267f2610b7ad5de919856d64d7c212659ce8656149b6a6d29d8f92b312be50b6e2a431d36ae022b00a6fe360e3af65432899c43be0427e36d21cfec81f21aa53b33db5ed2c37da8f96ac3e7dc67a1de37546cf7de1008c7e1adbe0f34fa7eb2434d94e6a13f4cf86a98d497622f
+SIG: e0303aefe08a77738dcc657afbb9b835ed279613a53c73fdc5ddbfb350e5cff4d6c9bb43dc07c95bf4e23b64c40f8804c7169952e3c8d59a7197241bfed0740f
+
+TST: 360
+SK: f0790d93e2d3b84f61ef4c807147aba410e415e72b71b0d61d01026fed99da3d
+PK: efdf649fb033cf328e0b287796f8a25e9c6e2e871b33c2c21a4028a8a25a4b28
+MSG: 7973e9f32d74805992eb65da0d637335e50eff0ce68ea2d1f3a02de704492b9cfbe7e7ba96fdb42bb821a513d73fc60402e92c855deaed73ffeaf70952029062c833e14ec1b14f144e2207f6a0e727e5a7e3cbab27d5972970f69518a15b093e740cc0ce11bf5248f0826b8a98bde8bf2c7082c97aff158d08371118c89021cc3974ae8f76d86673c3f824b62c79c4b41f40eaa8943738f03300f68cbe175468eb235a9ff0e6537f8714e97e8f08ca444e41191063b5fabd156e85dcf66606b81dad4a95065584b3e0658c20a706eaf4a0777da4d2e0cd2a0fca60109c2b4403db3f03cd4781c1fbb0272202bcb11687808c50cb98f64b7f3fd3d43333bb5a061b9e377090abb1e0a885cb26b73c163e63ff6451ff2f4ec8249c7e152bd03973a1e964e2b5b235281a938399a112a24529e383a560dc50bb1b622ad74ef35658dcb10ffe022568ac3ffae5b465a8ed7643e8561b352ee9944a35d882c712b187788a0abae5a22f
+SIG: 08773a6a78762cbb1e25fcbb29139941bdf16f4e09a1fa08fc701f32f933edd74c0ae983c12a0a5b020b6bcf44bb719dde8ed0781a8298265640e1608c98b301
+
+TST: 361
+SK: 4cb9df7ce6fae9d62ba09e8eb70e4c969bdeafcb5ec7d7024326e6603b0621bf
+PK: 018069dd0eb44055a35cd8c77c37ca9fb1ad2417271385e134b2f4e81f52033c
+MSG: 14627d6ea0e7895460759476dc74c42800ceef994327518151490d9df23067914e44788a12768ccb25471b9c3ba9d14fb436dcba38429b3a0456877763c49175d0e082683e07a9058f3685c6279307b2303d1221b9c29793d8a4877f6df51587384dadf751c5f7bfbd207d519622c37b51ceeee2c20d8269f8cb88d3fe43d6d434d5bbd0e203c1532d97ba552147227496c87f67b50bb76193add0144df1c176657585408362ca2ed04ad62acf1c25e341dfd1498d85b4b1349a8b0b9b02c43523c55853419bfed37d5a2cdf17dfbf1a3bd7759d6ae180f9d27dcd9a8933e29a7c0a30771eea7c2e0fa242925d2336dce585629057d844323964f6d3d11ff0b3f829a3be8c9f0468a6823d8e70ab5a2da21e15fa8b041a29812222e9c30b2bd9a12d1fdee6f87876e8ce81009637a8bb2236129a47ca74289ee4aad429ffe29f47430241ca8cc3848b7200fd6e1470651a9a0a6f72c9033e831df051408a6260f65cbaf6e012b18e
+SIG: e33c07836c537d6bfbd0f4592d6e35b163499ba78dc7ffcec565d04f9a7db781943e29e6ce76763e9baddf57437fd9c6b03239a6e6850e4502a356c2e12c3705
+
+TST: 362
+SK: a136e009d53e5ef59d0946bc175663a86bc0fcd29eadd95cfc9d266037b1e4fb
+PK: 9c1806ec0454f58314eb8397d64287dee386640d8491aba364607688841715a0
+MSG: a49d1c3d49e13c2eda56868a8824aa9f8d2bf72f21955ebafd07b3bdc8e924de20936cee513d8a64a47173a3bd659eff1accff8244b26aae1a0c27fa891bf4d85e8fb1b76a6cab1e7f74c89ee07bb40d714326f09b3fd40632fad208ea816f9072028c14b5b54ecc1c5b7fc809e7e0786e2f11495e76017eb62aa4563f3d00ee84348d9838cd17649f6929a6d206f60e6fc82e0c3464b27e0e6abd22f4469bdfd4cb54f77e329b80f71bf42129ec13c9dfe192adfaa42ee3ddeeda385816fbad5f411938c63b560f4ecd94534be7d98725cd94c99ce492f0f069ba0ec08f877a7812ef27ae19d7a77be63f66bcf8d6cf3a1a61fc9cfef104c7462a21ca7f03afb5bb1ac8c75124b554e8d044b810d95ff8c9dd09a34484d8c4b6c95f95c3c22823f52ce844293724d5259191f1ba0929e2acdbb8b9a7a8adf0c52e78acdfdf057b0985881afbed4dbebdebbdae0a2b63bd4e90f96afdcbbd78f506309f9bdb650013cb73faed73904e
+SIG: bc094ba91c115dee15d753361a75f3f03d6af45c92157e95dbe8d32194b6c5ce72b9dc66f73df12dca0b639f3e791d478616a1f8d7359a42c8eae0dda16b1606
+
+TST: 363
+SK: ff0f1c57dd884fbeea6e2917282b79ba67f8a6851267b9f4636dafda33bd2b5b
+PK: fef6378ad12a7c252fa6eb742b05064b41530ff019dc680ab544c027ea2836e7
+MSG: 522a5e5eff5b5e98fad6878a9d72df6eb318622610a1e1a48183f5590ecef5a6df671b28be91c88cdf7ae2881147fe6c37c28b43f64cf981c455c59e765ce94e1b6491631deaeef6d1da9ebca88643c77f83eae2cfdd2d97f604fe45081d1be5c4ae2d875996b8b6fecd707d3fa219a93ba0488e55247b405e330cfb97d31a1361c9b2084bdb13fb0c058925db8c3c649c9a3e937b533cc6310fa3b16126fb3cc9bb2b35c5c8300015488a30fadca3c8871fa70dfdc7055bf8e631f20c9b2528311e324a7c4edd5462079f3441c9ecf55fa999e731372344fdc0d413e417aaa001a1b2d3d9bc000fec1b02bd7a88a812d9d8a66f9464764c070c93041eefb17ce74eff6d4aff75f0cbf6a789a9ecde74abe33130fca0da853aa7c3313ada3f0ae2f595c6796a93685e729dd18a669d6381825ab3f36a391e7525b2a807a52fa5ec2a030a8cf3b77337ac41fceb580e845eed655a48b547238c2e8137c92f8c27e585caad3106eee3814a
+SIG: d5008486726cce330a29dd7e4d7474d735798201afd1206feb869a112e5b43523c06976761be3cf9b2716378273c94f93572a7d2b8982634e0755c632b449008
+
+TST: 364
+SK: 0bc6af64de5709d3dbc28f7ef6d3fe28b6de529f08f5857ccb910695de454f56
+PK: fb491fc900237bdc7e9a119f27150cd911935cd3628749ff40ef41f3955bc8ac
+MSG: ac7886e4f4172a22c95e8eea37437b375d72accedcee6cc6e816763301a2d8ef4d6f31a2c1d635818b7026a395ce0dafd71c5180893af76b7ea056c972d680eca01dcbdbae6b26f1c5f33fc988b824fbbe00cacc316469a3bae07aa7c8885af7f65f42e75cef94dbb9aab4825143c85070e7716b7612f64ef0b0166011d23eb5654aa098b02d8d71e57c8fa17bff2fe97dc8193177eadc09fb192d80aa92afa98720d4614817ff3c39d3acce18906fa3de09618931d0d7a60c4429cbfa20cf165c947929ac293ae6c06e7e8f25f1264291e3e1c98f5d93e6ecc2389bc60dbbf4a621b132c552a99c95d26d8d1af61138b570a0de4b497ebe8051c7273a98e6e7876d0b327503af3cb2cc4091ce1925cb2f2957f4ec56ee90f8a09dd57d6e83067a356a4cfe65b1b7a4465da2ab133b0efb5e7d4dbb811bcbbde712afbf0f7dd3f326222284b8c74eac7ad6257fa8c632b7da2559a6266e91e0ef90dbb0aa968f75376b693fcaa5da342221
+SIG: dbc7134d1cd6b0813b53352714b6df939498e91cf37c324337d9c088a1b998347d26185b430900412929e4f63e910379fc42e355a4e98f6fee27dafad1957206
+
+TST: 365
+SK: 2f5e83bd5b412e71ae3e9084cd369efcc79bf6037c4b174dfd6a11fb0f5da218
+PK: a22a6da29a5ef6240c49d8896e3a0f1a4281a266c77d383ee6f9d25ffacbb872
+MSG: b766273f060ef3b2ae3340454a391b426bc2e97264f8674553eb00dd6ecfdd59b611d8d662929fec710d0e462020e12cdbf9c1ec8858e85671acf8b7b14424ce92079d7d801e2ad9acac036bc8d2dfaa72aa839bff30c0aa7e414a882c00b645ff9d31bcf5a54382def4d0142efa4f06e823257ff132ee968cdc6738c53f53b84c8df76e9f78dd5056cf3d4d5a80a8f84e3edec48520f2cb4583e708539355ef7aa86fb5a0e87a94dcf14f30a2cca568f139d9ce59eaf459a5c5916cc8f20b26aaf6c7c029379aedb05a07fe585ccac60307c1f58ca9f859157d06d06baa394aace79d51b8cb38cfa2598141e245624e5ab9b9d68731173348905315bf1a5ad61d1e8adaeb810e4e8a86d7c13537b0be860ab2ed35b73399b8808aa91d750f77943f8a8b7e89fdb50728aa3dbbd8a41a6e00756f438c9b9e9d55872df5a9068add8a972b7e43edad9ced2237ca1367be4b7cdb66a54ea12eef129471158610eaf28f99f7f686557dcdf644ea
+SIG: 9f80922bc8db32d0cc43f9936affebe7b2bc35a5d82277cd187b5d50dc7fc4c4832fffa34e9543806b485c04548e7c75429425e14d55d91fc1052efd8667430b
+
+TST: 366
+SK: 722a2da50e42c11a61c9afac7be1a2fed2267d650f8f7d8e5bc706b807c1b91d
+PK: fd0b964562f823721e649c3fedb432a76f91e0aead7c61d35f95ed7726d78589
+MSG: 173e8bb885e1f9081404acac999041d2ecfcb73f945e0db36e631d7cd1ab999eb717f34bf07874bf3d34e2530eb6085f4a9f88ae1b0f7d80f221456a8e9a8890b91a50192deaaacc0a1a615a87841e2c5a9e057957af6e48e78cc86198e32e7aa24dcf6cffa329bc72606d65b11682c8ba736cce22a05785df1146331e41609cf9ca711cf464958297138b58a9073f3bbf06ad8a85d135de66652104d88b49d27ad41e59bcc44c7fab68f53f0502e293ffcabaaf755927dfdffbfde3b35c080b5de4c8b785f4da64ef357bc0d1466a6a96560c3c4f3e3c0b563a003f5f95f237171bce1a001771a04ede7cdd9b8ca770fd36ef90e9fe0000a8d7685fd153cc7282de95920a8f8f0898d00bf0c6c933fe5bb9653ff146c4e2acd1a2e0c23c1244844dacf8652716302c2032f9c114679ed26b3ee3ab4a7b18bc4e3071f0977db57cd0ac68c0727a09b4f125fb64af2850b26c8a484263334e2da902d744737044e79ab1cf5b2f93a022b63d40cd
+SIG: c2695a57172aaa31bd0890f231ca8eeec0287a87172669a899ad0891cea4c47579b50420e791cdec8c182c8a0e8dde21b2480b0cfd8111e28e5603347a352d04
+
+TST: 367
+SK: 5fe9c3960ed5bd374cc94d42357e6a24dc7e3060788f726365defacf13cd12da
+PK: 0ce7b155c8b20ebdaacdc2aa23627e34b1f9ace980650a2530c7607d04814eb4
+MSG: c9490d83d9c3a9370f06c91af001685a02fe49b5ca667733fff189eee853ec1667a6c1b6c787e9244812d2d532866ab74dfc870d6f14033b6bcd39852a3900f8f08cd95a74cb8cbe02b8b8b51e993a06adfebd7fc9854ae5d29f4df9642871d0c5e470d903cfbcbd5adb3275628f28a80bf8c0f0376687dae673bf7a8547e80d4a9855ae2572fc2b205dc8a198016ddc9b50995f5b39f368f540504a551803d6dd5f874828e5541ded052894d9e2dc5e6aa351087e790c0dd5d9c4decb217e4db81c98a184b264e6daeac0f11e074cae2bfc899f54b419c65dcc22664a915fbfffac35cee0f286eb7b144933db933e16c4bcb650d537722489de236373fd8d65fc86118b6def37ca4608bc6ce927b65436ffda7f02bfbf88b045ae7d2c2b45a0b30c8f2a04df953221088c555fe9a5df260982a3d64df194ee952fa9a98c31b96493db6180d13d67c36716f95f8c0bd7a039ad990667ca34a83ac1a18c37dd7c7736aa6b9b6fc2b1ac0ce119ef77
+SIG: 379f9c54c413af0d192e9bc736b29da9d521e7ba7841d309f9bcc1e742ec4308fe9f7ba51e0b22aed487cb4aa3913b9bebfb3aacd38f4039f9bbbebe1ad80002
+
+TST: 368
+SK: ec2fa541ac14b414149c3825eaa7001b795aa1957d4040dda92573904afa7ee4
+PK: 71b363b2408404d7beecdef1e1f511bb6084658b532f7ea63d4e3f5f01c61d31
+MSG: 2749fc7c4a729e0e0ad71b5b74eb9f9c534ebd02ffc9df4374d813bdd1ae4eb87f1350d5fdc563934515771763e6c33b50e64e0cd114573031d2186b6eca4fc802cddc7cc51d92a61345a17f6ac38cc74d84707a5156be9202dee3444652e79bae7f0d31bd17567961f65dd01a8e4bee38331938ce4b2b550691b99a4bc3c072d186df4b3344a5c8fbfbb9fd2f355f6107e410c3d0c798b68d3fb9c6f7ab5fe27e70871e86767698fe35b77ead4e435a9402cc9ed6a2657b059be0a21003c048bbf5e0ebd93cbb2e71e923cf5c728d1758cd817ad74b454a887126d653b95a7f25e5293b768c9fc5a9c35a2372e3741bc90fd66301427b10824bb4b1e9110bfba84c21a40eb8fed4497e91dc3ffd0438c514c0a8cb4cac6ad0256bf11d5aa7a9c7c00b669b015b0bf81425a21413e2ffb6edc0bd78e385c44fd74558e511c2c25fee1fec18d3990b8690300fa711e93d9854668f0187065e76e7113ae763c30ddd86720b5546a6c3c6f1c43bc67b14
+SIG: 84d18d56f964e3776759bba92c510c2b6d574555c3cddade212da90374554991e7d77e278d63e34693e1958078cc3685f8c41c1f5342e351899638ef61211401
+
+TST: 369
+SK: 6132692a5ef27bf476b1e991e6c431a8c764f1aebd470282db3321bb7cb09c20
+PK: 7a2d166184f9e5f73bea454486b041ceb5fc2314a7bd59cb718e79f0ec989d84
+MSG: a9c0861665d8c2de06f9301da70afb27b3024b744c6b38b24259294c97b1d1cb4f0dcf7575a8ed454e2f0980f50313a77363415183fe9677a9eb1e06cb6d34a467cb7b0758d6f55c564b5ba15603e202b18856d89e72a23ab07d8853ff77da7aff1caebd7959f2c710ef31f5078a9f2cdae92641a1cc5f74d0c143ec42afbaa5f378a9e10d5bf74587fa5f49c156233247dafd3929acde888dc684337e40cdc5932e7eb73ffcc90b85c0ad460416691aefbd7efd07b657c350946a0e366b37a6c8089aba5c5fe3bbca064afbe9d47fbc83914af1cb43c2b2efa98e0a43be32ba823202001def36817251b65f9b0506cef6683642a46ed612f8ca81ee97bb04d317b517343ade2b77126d1f02a87b7604c8653b6748cf5488fa6d43df809faa19e69292d38c5d397dd8e20c7af7c5334ec977f5010a0f7cb5b89479ca06db4d12627f067d6c42186a6b1f8742f36ae709ba720e3cd898116666d81b190b9b9d2a72202cb690a03f3310429a71dc048cde
+SIG: eb677f3347e1a1ea929efdf62bf9105a6c8f4993033b4f6d03cb0dbf9c742b270704e383ab7c0676bdb1ad0ce9b16673083c9602ec10ae1dd98e8748b336440b
+
+TST: 370
+SK: f219b2101164aa9723bde3a7346f68a35061c01f9782072580ba32df903ba891
+PK: f66b920d5aa1a6085495a1480539beba01ffe60e6a6388d1b2e8eda23355810e
+MSG: 015577d3e4a0ec1ab25930106343ff35ab4f1e0a8a2d844aadbb70e5fc5348ccb679c2295c51d702aaae7f6273ce70297b26cb7a253a3db94332e86a15b4a64491232791f7a8b082ee2834af30400e804647a532e9c454d2a0a7320130ab6d4d860073a34667ac25b7e5e2747ba9f5c94594fb68377ae260369c40713b4e32f23195bf91d3d7f1a2719bf408aad8d8a347b112e84b118817cb06513344021763035272a7db728a0ccdaa949c61715d0764140b3e8c01d20ff1593c7f2d55c4e82a1c0cb1ea58442bf80a741bca91f58ab0581b498ee9fe3c92ca654148ef75313543d1aff382befe1a93b02190ce0102175158e2071d02bacad8dbe9fb940fcb610c105ad52c80feb1ec4e524f4c0ec7983e9ce696fa4fcf4bf0514b8f0432b17d5448fc426fea2b01ac7b26c2aed769927534da22576fc1bba726e9d65be01b59f60a648ace2fc3e5e275789fa637cbbd84be3d6ac24457a6292cd656c7b569a52ffea7916b8d04b4f4a75be7ac95142f
+SIG: 17f0127ca3bafa5f4ee959cd60f772be87a0034961517e39a0a1d0f4b9e26db1336e60c82b352c4cbacdbbd11771c3774f8cc5a1a795d6e4f4ebd51def36770b
+
+TST: 371
+SK: fc180035aec0f5ede7bda93bf77ade7a81ed06de07ee2e3aa8576be81608610a
+PK: 4f215e948cae243ee3143b80282ad792c780d2a6b75060ca1d290ca1a8e3151f
+MSG: b5e8b01625664b222339e0f05f93a990ba48b56ae65439a17520932df011721e284dbe36f98631c066510098a68d7b692a3863e99d58db76ca5667c8043cb10bd7abbaf506529fbb23a5166be038affdb9a234c4f4fcf43bddd6b8d2ce772dd653ed115c095e232b269dd4888d2368cb1c66be29dd383fca67f66765b296564e37555f0c0e484504c591f006ea8533a12583ad2e48318ff6f324ecaf804b1bae04aa896743e67ef61ca383d58e42acfc6410de30776e3ba262373b9e1441943955101a4e768231ad9c6529eff6118dde5df02f94b8d6df2d99f27863b517243a579e7aaff311ea3a0282e47ca876fabc2280fce7adc984dd0b30885b1650f1471dfcb0522d49fec7d042f32a93bc368f076006ea01ec1c7412bf66f62dc88de2c0b74701a5614e855e9fa728fb1f1171385f96afbde70dea02e9aa94dc21848c26302b50ae91f9693a1864e4e095ae03cdc22ad28a0eb7db596779246712fab5f5da327efec3e79612de0a6ccaa536759b8e
+SIG: a43a71c3a19c35660dae6f31a254b8c0ea3593fc8fca74d13640012b9e9473d4afe070db01e7fb399bf4ca6070e062180011285a67dd6858b761e46c6bd32004
+
+TST: 372
+SK: a2836a65427912122d25dcdfc99d7046fe9b53d5c1bb23617f11890e94ca93ed
+PK: 8c12bda214c8abb2286acffbf8112425040aab9f4d8bb7870b98da0159e882f1
+MSG: 813d6061c56eae0ff53041c0244aa5e29e13ec0f3fb428d4beb8a99e04bca8c41bddb0db945f487efe38f2fc14a628fafa2462f860e4e34250eb4e93f139ab1b74a2614519e41ee2403be427930ab8bc82ec89ceafb60905bd4ddbbd13bdb19654314fc92373140b962e2258e038d71b9ec66b84ef8319e03551cb707e747f6c40ad476fbefdce71f3a7b67a1af1869bc6440686e7e0855e4f369d1d88b8099fba54714678627bba1aff41e7707bc97eddf890b0c08dce3e9800d24c6f61092ce28d481b5dea5c096c55d72f8946009131fb968e2bc8a054d825adab76740dcf0d758c8bf54ff38659e71b32bfe2e615aaabb0f5293085649cf60b9847bc62011ce3878af628984a5840a4ad5dae3702db367da0f8a165fed0517eb5c442b0145330241b97eeca733ba6688b9c129a61cd1236aff0e27bcf98c28b0fbeea55a3d7c7193d644b2749f986bd46af8938e8faaeafbd9cec3612ab005bd7c3eeafe9a31279ca6102560666ba16136ff1452f850adb
+SIG: e6a9a6b436559a4320c45c0c2c4a2aedecb90d416d52c82680ac7330d062aebef3e9ac9f2c5ffa455c9be113013a2b282e5600fd306435ada83b1e48ba2a3605
+
+TST: 373
+SK: f051af426d0c3282fafc8bf912ade1c24211a95ad200e1eef549320e1cb1a252
+PK: fa87955e0ea13dde49d83dc22e63a2bdf1076725c2cc7f93c76511f28e7944f2
+MSG: b48d9f84762b3bcc66e96d76a616fa8fe8e01695251f47cfc1b7b17d60dc9f90d576ef64ee7d388504e2c9079638165a889696471c989a876f8f13b63b58d531fea4dd1229fc631668a047bfae2da281feae1b6de3ebe280abe0a82ee00fbfdc22ce2d10e06a0492ff1404dfc094c40b203bf55721dd787ed4e91d5517aaf58d3bdd35d44a65ae6ba75619b339b650518cefcc17493de27a3b5d41788f87edbde72610f181bf06e208e0eb7cdfe881d91a2d6cc77aa19c0fcf330fedb44675d800eb8cff9505d8887544a503cbe373c4847b19e8f3995726efd6649858595c57ccaf0cbc9eb25de83ba046bc9f1838ac7b8953dd81b81ac0f68d0e9338cb55402552afb6bc16949351b926d151a82efc695e8d7da0dd55099366789718ccbf36030bd2c3c109399be26cdb8b9e2a155f3b2cb1bfa71ab69a23625a4ac118fe91cb2c19788cf52a71d730d576b421d96982a51a2991daec440cda7e6cc3282b8312714278b819bfe2387eb96aa91d40173034f428
+SIG: b8f713578a64466719aceb432fce302a87cf066bf3e102a350616921a840964bfc7e685d8fd17455ac3eb4861edcb8979d35e3a4bd82a078cd707721d733400e
+
+TST: 374
+SK: a103e92672c65f81ea5da1fff1a4038788479e941d503a756f4a755201a57c1d
+PK: ee63a5b69641217acbaf3339da829ec071b9931e5987153514d30140837a7af4
+MSG: b1984e9eec085d524c1eb3b95c89c84ae085be5dc65c326e19025e1210a1d50edbbba5d1370cf15d68d687eb113233e0fba50f9433c7d358773950c67931db8296bbcbecec888e87e71a2f7579fad2fa162b85fb97473c456b9a5ce2956676969c7bf4c45679085b62f2c224fc7f458794273f6d12c5f3e0d06951824d1cca3e2f904559ed28e2868b366d79d94dc98667b9b5924268f3e39b1291e5abe4a758f77019dacbb22bd8196e0a83a5677658836e96ca5635055a1e63d65d036a68d87ac2fd283fdda390319909c5cc7680368848873d597f298e0c6172308030ffd452bb1363617b316ed7cd949a165dc8abb53f991aef3f3e9502c5dfe4756b7c6bfdfe89f5e00febdd6afb0402818f11cf8d1d5864fe9da1b86e39aa935831506cf2400ea7ed75bd9533b23e202fe875d7d9638c89d11cb2d6e6021ae6bd27c7754810d35cd3a61494f27b16fc794e2cd2f0d3453ada933865db78c579571f8fc5c5c6be8eaffce6a852e5b3b1c524c49313d427abcb
+SIG: 2aa2035c2ce5b5e6ae161e168f3ad0d6592bcf2c4a049d3ed342fceb56be9c7cb372027573ae0178e8878ebefca7b030327b8aad41857de58cb78e1a00cbac05
+
+TST: 375
+SK: d47c1b4b9e50cbb71fd07d096d91d87213d44b024373044761c4822f9d9df880
+PK: f4e1cb86c8ca2cfee43e58594a8778436d3ea519704e00c1bbe48bbb1c9454f8
+MSG: 88d7009d51de3d337eef0f215ea66ab830ec5a9e6823761c3b92ad93ea341db92ece67f4ef4ceb84194ae6926c3d014b2d59781f02e0b32f9a611222cb9a5850c6957cb8079ae64e0832a1f05e5d1a3c572f9d08f1437f76bb3b83b52967c3d48c3576848891c9658d4959eb80656d26cdba0810037c8a18318ff122f8aa8985c773cb317efa2f557f1c3896bcb162df5d87681bb787e7813aa2dea3b0c564d646a92861f444ca1407efbac3d12432cbb70a1d0eaffb11741d3718fedee2b83036189a6fc45a52f74fa487c18fd264a7945f6c9e44b011f5d86613f1939b19f4f4fdf53234057be3f005ad64eebf3c8ffb58cb40956c4336df01d4424b706a0e561d601708d12485e21bcb6d799d8d1d044b400064ec0944501406e70253947006cabbdb2dd6bd8cee4497653d9113a44d4de9b68d4c526fca0b9b0c18fe50fb917fdd9a914fb816108a73a6b3fff9e654e69c9cfe02b05c6c1b9d15c4e65cf31018b8100d784633ee1888eee3572aafa6f189ea22d0
+SIG: 627e7ca7e34ed6331d62b9541c1ea9a9292be7b0a65d805e266b5122272a82db7d765acc7e2a290d685804922f91ed04a3c382c03ff21a1768f584413c4e5f00
+
+TST: 376
+SK: fc0c32c5eb6c71ea08dc2b300cbcef18fdde3ea20f68f21733237b4ddaab900e
+PK: 47c37d8a080857eb8777a6c0a9a5c927303faf5c320953b5de48e462e12d0062
+MSG: a7b1e2db6bdd96b3d51475603537a76b42b04d7ebd24fe515a887658e4a352e22109335639a59e2534811f4753b70209d0e4698e9d926088826c14689681ea00fa3a2fcaa0047ced3ef287e6172502b215e56497614d86b4cb26bcd77a2e172509360ee58893d01c0d0fb4d4abfe4dbd8d2a2f54190fa2f731c1ceac6829c3ddc9bfb2ffd70c57ba0c2b22d2326fbfe7390db8809f73547ff47b86c36f2bf7454e678c4f1c0fa870bd0e30bbf3278ec8d0c5e9b64aff0af64babc19b70f4cf9a41cb8f95d3cde24f456ba3571c8f021d38e591dec05cb5d1ca7b48f9da4bd734b069a9fd106500c1f408ab7fe8e4a6e6f3ed64da0ed24b01e33df8475f95fa9ed71d04dd30b3cd823755a3401bf5afae10ee7e18ec6fe637c3793fd434b48d7145130447e00299101052558b506554ec9c399f62941c3f414cbc352caa345b930adecfaddac91ee53d1451a65e06201026325de07c931f69bba868a7c87ee23c604ec6794332917dfe2c5b69669b659706917f71eddf96
+SIG: 6887c6e2b98a82af5ee3dfa7ca2cb25d9c10745620a82956acba85cb57c8ec24279fa42f092359a1b6bbeafba050f14b6288209e6ef7bc1e0a2b872c1138f305
+
+TST: 377
+SK: a8d73d639a23cc6a967ef31bcabb5d063e53e1eab8fcc7cab9bc3a17fde9c2f8
+PK: 8daa9f4c8b1a44691bf44521f2f7ca45dc7fc61f6a4ce6f98faa41c2a74977d1
+MSG: fd1fac3d53313b11acd29f5a83ac11896dab2530fa47865b2295c0d99dd67c36ed8e5fa549150c794c5549efb5c1d69114d5d607b23285b7212afaab57846a54ae67b9e880e07b6586607cecf6d4eed516a3a75511fe367d88eb871e6d71b7d6aa1367a01421b1088fc2d75e44954b73625c52da8a3a183c60be9da6050f59a453caa53520593671728d431877bfaac913a765fb6a56b75290b2a8aaac34afb9217ba1b0d5850ba0fdabf80969def0feee794ceb60614e3368e63ef20e4c32d341ec9b0328ea9fe139207ed7a626ff08943b415233db7cfcc845c9b63121d4ed52ec3748ab6a1f36b2103c7dc7e9303acea4ba8af7a3e07184fb491e891ede84f0dc41cadc3973028e879acd2031afc29a16092868e2c7f539fc1b792edab195a25ab9830661346b39ef53915de4af52c421eaf172e9da76a08c283a52df907f705d7e8599c5baae0c2af380c1bb46f93484a03f28374324b278992b50b7afa02552cafa503f034f8d866e9b720271dd68ccb685a85fffd1
+SIG: c4dcef1a2453939b364b340250c3129431431d5ba3f47670ab07ce680c69bf28b678627c76a6360fc40dc109aa7dea371b825e46134f624572182acf3957e70f
+
+TST: 378
+SK: 79c7dcb7d59a8df6b2b2ba0413059d89680995c20e916da01b8f067dc60cdeb4
+PK: 298743c73918bd556b28f8d4824a09b814752a7aeae7ee04875c53f4d6b108d9
+MSG: 5fe202f5b33b7788810d2508a13b3114d69b8596e6eacda05a04a2eb597fa3279c208b5a5b65daacb699f144e1d660e78e139b578331abec5c3c35334454f03e832c8d6e2984df5d450ecb5d33582a78808a9c78f26ebcd1244ef52e3fa6dca115c1f0cb56e38eae0e5b39f5fd863dffd0b2fb5b958f2d739db312fc667a17b031c4c9f8c5a2ad577984cc4146c437580efd2152173fe0d5782cc2ae9831a8d9a04177256018ff7631e0b0d8a99cb28f008b320421e27a74c31359188663456d85e098c1ebd281701097b6ae5a871e5ccc02058a501416cb91c12cef5be6f1914370e563f1a1b2aa41f4b8ee84cd32a1d509e529787d14a445438d807ecd620e2fa26de0da6426864784d4a28f54103e609283b99ee9b2b699c980bbb7882c3ea68ddc90802ac232f2c8e84291987bf3c5240921b59cfa214969317673d0be7f34b1ca0e15ea73c7175401ce550be106b49e62f8db68695e740e0f3a3556a19f3c8e6b91ac1cc23e863fcd0f0d9eb7047aa631e0d2eb9bcc6b
+SIG: 7b7cbe44c771e4371bae13b0722babcc1064155732962f407cba2acd35381d42210bece822f4681121fd4dab745a1f3077922fba1a78045b712902baccac660e
+
+TST: 379
+SK: b9ced0412593fefed95e94ac965e5b23ff9d4b0e797db02bf497994d3b793e60
+PK: c1629a723189959337f5535201e5d395ba0a03ea8c17660d0f8b6f6e6404bb12
+MSG: 555bb39c1899d57cabe428064c2d925f5fc4cf7059b95fb89a8e9e3a7e426c6c922d9e4d76984ea2383cabb4f2befd89c1f20eaa8a00dbe787cfa70ae2ae6aa90331cbbe580fa5a02184ed05e6c8e89d576af28aeeaf7c4e2500f358a00971a0a75920e854849bf332142975404f598c32e96982043d992bcd1a4fe819bb5634ad03467afc4ce05073f88ba1ba4ae8653a04665cf3f71690fe13343885bc5ebc0e5e62d882f43b7c68900ac9438bf4a81ce90169ec129ee63e2c675a1a5a67e27cc798c48cc23f51078f463b3b7cc14e3bcfd2e9b82c75240934cbdc50c4308f282f193122995606f40135100a291c55afdf8934eb8b61d81421674124dec3b88f9a73110a9e616f5b826b9d343f3ac0e9d7bdf4fd8b648b40f0098b3897a3a1cd65a64570059b8bc5c6743883074c88623c1f5a88c58969e21c692aca236833d3470b3eb09815e1138e9d0650c390eee977422193b00918be8a97cc6199b451b05b5730d1d13358cf74610678f7ac7f7895cc2efc456e03873b
+SIG: f1b797ded8a6942b12626848340fb719fcddafd98f33e2992d357bfdd35933c7ac561e5b2f939464338c5666854ca885c4d046eb2c54e48a1b5ed266ad34de05
+
+TST: 380
+SK: 81da168f02d46bb87cda845da43f8a6cba2c016878d6f49c6f061a60f155a04a
+PK: aff86e98093ca4c71b1b804c5fe451cfdf868250dea30345fa4b89bb09b6a53b
+MSG: 6bc6726a34a64aae76ab08c92b179e54ff5d2e65eb2c6c659ae8703cc245cbc2cf45a12b22c468ae61fd9a6627ad0626c9b1e5af412cb483eaee1db11b29f0a510c13e38020e09ae0eee762537a3e9d1a0c7b033d097fdc1f4f82629a9de9ef38da1cf96a940357d5f2e0e7e8dbc29db728a1e6aad876e5e053113d06420272b87cf0c40dfe03a544de96c7aea13ba0029b57b48d99dcc6a650492d78c4cdd1b28e1a115a7e3e7a7cb21333d4ff80858dfb67782c16354b8716596560d7d8e389eb15a052a0bf5d16eb54fb3e4973ad4984e72a187f5347d5b262c32b1647e42b6a53837096cc78c2a05ce1c6e12493a03f1a667584cb97f4fcd57ee944c65b7eed25f7ae0f3f6cede173fdfacf5af1db143730d18096664914ba4cfc6966f392022781c66a9417ca2680b51f63e4fba424ecfdbc6a2f01787d0e7484f8a8ab390aeaa6d1f7ed325d82feaa1692a4984fae43da87329b045da8f0a4f56b695aa935de152ce0385153720979a2b7006d405fcb0fba09e23b85fd19b
+SIG: 4aaca947e3f22cc8b8588ee030ace8f6b5f5711c2974f20cc18c3b655b07a5bc1366b59a1708032d12cae01ab794f8cbcc1a330874a75035db1d69422d2fc00c
+
+TST: 381
+SK: af2e60da0f29bb1614fc3f193cc353331986b73f3f9a0aec9421b9473d6a4b6a
+PK: c8bfe2835822199c6127b806fabeef0cb9ff59f3c81ff0cb89c556f55106af6a
+MSG: 7dbb77b88bda94f344416a06b096566c6e8b393931a8243a6cab75c361fde7dc536aec40cded83296a89e8c3bef7d787cfc49401a7b9183f138d5000619ff073c05e2f841d6008358f10a2da7dcfac3d4d70c20d2ec34c7b6d5cd1a734d6bbb11c5fd8d2bce32ac810ef82b4188aa8ea3cfc3032233dc0e2600e9db6e18bc22b10044a31c15baceaf5554de89d2a3466807f244414d080ff2963956c6e83c8e144ed0066088b476ddcb564403447d9159f9089aba2b4d5575c4d8ae66fc8690e7349ed40832e6369c024563ec493bfcc0fc9ac787ac841397fe133167283d80c42f006a99d39e82979da3fa9334bd9ede0d14b41b7466bcebbe8171bc804a645d3723274a1b92bf82fd993358744de92441903d436fd47f23d40052a3829367f202f0553b5e49b76c5e03fa6ce7c3cf5eeb21de967bec4dd355925384ebf96697e823762bac4d43a767c241a4cef724a970d00ff3a8ab3b83eed840075c74e90f306e330013260962161e9d0910de183622ce9a6b8d5144280550fc7
+SIG: 50f9f941a8da9f6240f76d2fa3b06dd6b2292ed32d1c05218097d34d8a19dfe553f76ae3c6b4a2ed20852128461540decf418f52d38e64037eec7771bd1afe00
+
+TST: 382
+SK: 605f90b53d8e4a3b48b97d745439f2a0807d83b8502e8e2979f03e8d376ac9fe
+PK: aa3fae4cfa6f6bfd14ba0afa36dcb1a2656f36541ad6b3e67f1794b06360a62f
+MSG: 3bcdcac292ac9519024aaecee2b3e999ff5d3445e9f1eb60940f06b91275b6c5db2722ed4d82fe89605226530f3e6b0737b308cde8956184944f388a80042f6cba274c0f7d1192a0a96b0da6e2d6a61b76518fbee555773a414590a928b4cd545fccf58172f35857120eb96e75c5c8ac9ae3add367d51d34ac403446360ec10f553ea9f14fb2b8b78cba18c3e506b2f04097063a43b2d36431cce02caf11c5a4db8c821752e52985d5af1bfbf4c61572e3fadae3ad424acd81662ea5837a1143b9669391d7b9cfe230cffb3a7bb03f6591c25a4f01c0d2d4aca3e74db1997d3739c851f0327db919ff6e77f6c8a20fdd3e1594e92d01901ab9aef194fc893e70d78c8ae0f480001a515d4f9923ae6278e8927237d05db23e984c92a683882f57b1f1882a74a193ab6912ff241b9ffa662a0d47f29205f084dbde845baaeb5dd36ae6439a437642fa763b57e8dbe84e55813f0151e97e5b9de768b234b8db15c496d4bfcfa1388788972bb50ce030bc6e0ccf4fa7d00d343782f6ba8de0
+SIG: dd0212e63288cbe14a4569b4d891da3c7f92727c5e7f9a801cf9d6827085e7095b669d7d45f882ca5f0745dccd24d87a57181320191e5b7a47c3f7f2dccbd707
+
+TST: 383
+SK: 9e2c3d189838f4dd52ef0832886874c5ca493983ddadc07cbc570af2ee9d6209
+PK: f68d3b81e73557ee1f08bd2d3f46a4718256a0f3cd8d2e03eb8fe882aab65c69
+MSG: 19485f5238ba82eadf5eff14ca75cd42e5d56fea69d5718cfb5b1d40d760899b450e66884558f3f25b7c3de9afc4738d7ac09da5dd4689bbfac07836f5e0be432b1ddcf1b1a075bc9815d0debc865d90bd5a0c5f5604d9b46ace816c57694ecc3d40d8f84df0ede2bc4d577775a027f725de0816f563fa88f88e077720ebb6ac02574604819824db7474d4d0b22cd1bc05768e0fb867ca1c1a7b90b34ab7a41afc66957266ac0c915934aaf31c0cf6927a4f03f23285e6f24afd5813849bb08c203ac2d0336dcbf80d77f6cf7120edfbcdf181db107ec8e00f32449c1d3f5c049a92694b4ea2c6ebe5e2b0f64b5ae50ad3374d246b3270057e724a27cf263b633ab65ecb7f5c266b8007618b10ac9ac83db0febc04fd863d9661ab6e58494766f71b9a867c5a7a4555f667c1af2e54588f162a41ce756407cc4161d607b6e0682980934caa1bef036f7330d9eef01ecc553583fee5994e533a46ca916f60f8b961ae01d20f7abf0df6141b604de733c636b42018cd5f1d1ef4f84cee40fc
+SIG: 38a31b6b465084738262a26c065fe5d9e2886bf9dd35cde05df9bad0cc7db401c750aa19e66090bce25a3c721201e60502c8c10454346648af065eab0ee7d80f
+
+TST: 384
+SK: 31010d1d67eb616348e84792b92d5dc128553cb52f6368159fe7b816cd0e7c37
+PK: 266543d96787ca901fcff06e6e434491ae0970880a5a187d535edb19db5cabeb
+MSG: 39f89a5e7aa530b5463d498f8035b9909d55da527cdbd4de6d228379f089e608a9207a2c5b9c42051a60c8ca3fb97a1c06cd747d9d0739970ceb88ce526f971140ea2ec21f090ba075bf8975faa508b1cc10efa494dc172e6d3d3f3f75dc8e0e96f05c0cccb2f96e911cfa7a2c82c9845018bb1f9d75f82e3dfe1139347b2ac058b014ac93760c90f5567ab5c4eba04b49fb09ddadd305be511dfe05c96ebc86fd67b5d0ab57d85f4fe5e2f0fa9d88a68f0f6b6bc8bb944eb3c0b17557e55d5ea187d922a42813e69057c9b6a7f75e49921b7079e58f8a63719ee3e1ad10cf0e8a70c4f1540218b70494bd029ee02ff9727a7d85d377919ec4051479b70f7cd6767723fe42c1c7899c2b7c1f702dd6b4d13b672d488f34a0e969db79cc2cb2524a948a8de4c5b623ecd90d6e82d97033c125637d1cd8c84803d8fbc012846ffe484f6c02149258f9462fa1e99c307dd0062fe0b6f11eee40c2629ef7c0f6a5107259ea5b9ffb6f29f12c32f7b5228cabc986ab66450af9dcc3da09d0e0b9a4
+SIG: 7b1eb677c3e5e6a8b4ba69fcb7f6b1870e42a8d58958a35c674e2db82107481c4c7b37f0f689d39d9f51e181b17b1108c15a3e27b29df3a4315dcc4faf122205
+
+TST: 385
+SK: 8ff2398cd51f51d4c2c57869a2218b8486822031f400729f4ac4d5909c48bafe
+PK: a5a88704b68677be3d16c3dc0052cfee6e2b30e08609059d4cba52c6d96061fb
+MSG: 993953e47a341188bc592942e1557af29546e4e9368e2f1a5ee9806e2baf66b6190191fc5d2b7e47de37ff054fb2bbb1f031684ada5d607adda3d65433122fa904e0456faa84109bbc517f8ad39660876382adcfed0f7620cf1164622eacd91eb37a8596462ebe9ebe26bdc1e32cc34ad46fb1cea420e73c31215408e6d35425f44a829b132f631a3f6dd4b873a000667e19eb22fffd5903aaa7d4c8fdf21953c3c6178f5f8cb2aa6bff92894ead835888df060a3c9043026e0e2cef275497e7d105df3b644a98f26bf00105c99413ee0af8851954d65ceb8d79ad3071b8bb87f0b19743d2556ffd9819830b6eebf7ecc7e045661f43570ce9fdbbe2d252406fa90d04236f222c429ec16b1287224ada1a532161ae8b481bcab8d47afb3ed0445b3060fd6759179856f4085c1e585fd7c1409799af693cf427bd1d3dc10b5ae3447a8d2a18dc3a12a6860b22175dd5eb53a0950432e2d7aefece8af0ade3d8567743de43690f2d253723c5d7e48bd30d2937593701cecde9154b7665cb611d7d
+SIG: 417a647829c92898e520ff5311daa0a139cd8fffcb25a18e6d9b50cb52cbc35424c39ebbb5d5ac6a6d63f1f53c4df212f7025a8aaef8e36493c874c3ce341a0e
+
+TST: 386
+SK: ef816c8f5ec34ef41f68831d90cd29e52de8973782d003ee4edada2ada2691d6
+PK: 47f9b363a88a45053a05bb72160852bfe8f7dfefc2f37283de346752caf092cc
+MSG: 9593c35cdec535bebb6965da68eab0b646bffcfbd04883bc4cef90d5d01f018c63c9b0ddfb3cef5e786284d5218caaaf060e9288952f16301ed8a4c1bcee256356a0c8bda359fbaa2782b10c86d18e20f7a0ec99b27a0b4dbefc0a262a3bf68fe81444dcae5f693eb0f16e6ee03f8fcbf3a3398146d20ec4d2657761fd0320fee7ea703c49a6a543bc9bba911e7925038710e8c36552d476d6027f58b2c52ba51ad65ea4f039c78f96b889102bb4bdd69b68e9c3d45b5176a2d82b0b95dc321016370dae30c3936515db0464c41774301c74e42d89b8bf4b9c19ed554b12febac0f60ddb3219ccc5603531dbf2eb5f293425d72ccefa0c7f144aba89347b296be87ff18994b4a0c70c930f059303b5dd4c8fe1e6bbc3cd68c6c0d84246dc6e6140a2abd1780b13f1594a6019d1778b7cbb3a3e3a34bfae7297f0b3edc376941c32352a4be314b84a9d8d6d7f1f38a0ad3798020aa2a331a402be9c704484744a730cbdedcb904b6fde708fbd14bfdc29efd461d1d0b5825de0bc79422b69a2722f
+SIG: 65c5d10ea7bfdbb38d55364a9968f82b548224dff3363b2ddcf585163dea27dc63b0563eb1a8dfbee951d3c9b33fcd6bbf0921c3abb21786b229069bd9ca000a
+
+TST: 387
+SK: 45eb0c4dfafa2a7690ef579c095456ceedcd32f0b6144d0c380f87fb744a0b1f
+PK: fc85632c98384b5f9682aed9cd664cf1f48e588be2d568e5c734494df4c712b8
+MSG: 6f66d847405a03d7bd6f8d2897dbdf04e76d7df2d9470a4996b7dd6db88500f8f4f83e960e219a2486e24545add13614550414d827c41a9b08318daf01b15214c64a4266cbf8a5717ada3e62c26729073e16ddbd66f2d520e1e09935de05e4db11c396d477010aec66aafb762e69238d0b9e76b452454bf9e451e76ac79e6990d41b932bc32917093783c91bc9cf0bbe3b514070a1e692ff34fd06b66ea11f39e10af933ee96d8e9b677cb03737e7964eeaa725f121207f9c1b26a96c616df7cb7caef47bda901368ff2ea586e422e65bf21a691bdd2c13e67fff58cfbfed81782049dafa0f727df88623f2f7e8f262daf939542a187b8720a9b6b2b09890e54876b28a43874abbe3bfa981f8138b772c5d51736885f86acac2215a0b010dfc2c6b150845d4f8296252586a3e115f303c3d8a582e20fd2d43f6c446e5d00280ec179823b7fb4c1b0feb94eb4ef1707f5184e3b52461a7562d1f307cb751cdbbf6eae49ffae91862358e74e9548822b8a049fec6bf4c7a99cabbe09206577b657e31f
+SIG: 55851de8e1092f78944f6c6dd95bf07e2dbc8df7f57ad576829b978e3af58a7a8e94ed4dccbc0182467edf0bad4bae7ca84aa9a0c17c61a9e0ddff1d7525d704
+
+TST: 388
+SK: 709d2e199006f5369a7a0bdd34e74dc784be33880ea3c5dd10ed5c94451e7972
+PK: 06f989202ba2cbc9c150be611262aca00c45f012f89fbaf89f8ceccba0b1934a
+MSG: 62f003140fa09e0387d187a0ff96c4563df9f4e28c2282c0183ac3eede1312354921f780fca5361d3068d29949630b7530cd5914ace0468d014b6f53d839b82e38817dbf2d8392c3ce3424eab86a24d804c7acb1ce7acfe0a1cda4393924283105da4a7741196e027550047f85b7a0a01d454124efc0e299f0ef9ad14350543053482261528baa56e65999ac802c00a336267c635106b26403c19f391d53bd82861d6d48a4380b3043aa91d649536881204eccb0de20d43e5a3755b7f600916eccae42a0c9053b462d9417a13d67d778264a896e8eaf90baf66d29e5438a716781123a89fa9b8beef91d965af2f4a1a5bd5d2e2aaf46d5c94b7709cdd38d05feee4bfb76a359077c16bc4be9116e69001271cda565bc19bf47d4f986bd9c0d184cd8a3520ca1bdb4b505aaf7cb4ec9f94789779d30714e79116dd5019d59b28b17dad96f4e2155ad9c61274addc6b638109504e9ed19f4eda5377762648c4098224e3391043e4c2ad591654c9e7f974efdf0b0504b6fa5f646cecf44cd372412372505
+SIG: 629bf97b0c78ee6a9c8759fbea28224e27abbb6cbe4dea5bb797e6e0fe80c913f953e3a9b623352d13acf4ce6250fb029a1e198d72bd5e7402e60e9e48ca3501
+
+TST: 389
+SK: 5151617421aadc9c95a442b45e7ff6de06a2c733b85bd789fbad414ee3c91add
+PK: 14941d559761b30ab0a86d47e0f7d1896b33784527c80af41cb84810cbff9dbf
+MSG: 216e9d40bcdc3b2650188d121c9f8ef29e914facd022fe01b90ed11225f2eb93538e5fcee5ab8045e9199aa76a16bdd0616805660e247fecd7e22821b69b1f8e8a58ac3fb85691d75d5957a1daf53ff9ee6476d7c4bc541e6ad38e3a34ea90fc52a48b9399f92d17c9bb0d7fc3104c55d0efb4ea5b831ff9490b3f79f4d9d699594b741566f2b50a8fc78cc403fa40f5abb6638a32f449a8b3ef029c402f46931ad2bd3e8e683108714c989ae21689e9c444b9f55b81119bb5035bcf73e97ce43a2218c7bc3e430d1e814f34dee057265d3194b9f43875d8381f525f78576e64ce692584faa30fb743a12d1b77614d2e10a6b856b52be27cdb630ba1f0d3a6f8ea9844542e584ea0a2777527d0c52aca949aacda45ad83d16d5c83d663adb79cad6f3e39e990fe282a14c353aa2379d7f06adab74cea021b8983a57f1d0cf703292eb05ece89c53f3a1265610e0c1ea8ddd444d1ffd6bc3d03f0a6e4d0df5c5b8dc1f95d9f5558b118afe6bea0f6c2931363f03ab34e757d49364174f658efbbf38dc177
+SIG: fae4773b334460c77bf01ec6366c4fe61c0cab57d8a4b03909c619e11ee3461c13fa21576f63870e423dd04181e4a7013a7524f246fe33853c674162a7815104
+
+TST: 390
+SK: 38bed445556de74482bf5fec0506f9af330b151e50d4774dfe8591d7b7e0276b
+PK: 4c0f9c49a42f4047bfe6885551c5e4b856cf771a67af3f89dbf602f9db9220f3
+MSG: 0ff0031df0beeff3710c6b763f9b8ec81719bfa1528ce46519adf3d3412d93fb188fd497d5d17091c0f0345960dd0eb0c09fc4005173665d4d97f95c13828bc76b3492b87a4b64253c8b5fa47aa75fa3b86d5abeea8de5959a602289136f60a69b309e773b2255cde19ed2a2e199c33db11c16ade08a319750b851d92c692924fc9859be523431cbe78ec092db1129210ebbeaa7c2a2c000eeb105ca0301a48f3e45fdfb15b275cbab83ca5c99d737a585320e9e3b317179bd86467fa9694fcdb2ac6ad36ed7144843dbc34e423d35afd7d8972a1c43c199a191abd6ceba4936d395c995a3eb13cb057f88a9dc9490fe98845ee5d26a89fb642a2a516dc3056c54d3637213363a8628a42a395d942b954a89e8ef7a744d8ae5adac88c616efaa90e2077205a60baffede5c87bb14dead306229495f698f3e490616966b1636387d0d86183f945b24a9dcfccf4d36722cd12ebb6bd8e78325752afa2b1abd13c4bdbcadd170869136826242acfb721de5ff27ba8aa0c018b225ed3404803ce9fa2d508d8944
+SIG: f702d0d463282fc7fd5f8f9029b89c626cafd83450c3bb9dd8f6589f0c4b4b71f649ea212e5e33487c59c168ea3ad83150f1fcdfe8c53eba65adc2023c25830f
+
+TST: 391
+SK: 055460b32dd04d7f4b2311a89807e073fd556565a4771857d882794130a2fe5d
+PK: 260f8fed4bba30b9e12ad8523fbb6f57f0a7a882550061f1da46fbd8ea442221
+MSG: 7407f96ee3e79c69d36ce1f64e4f188655ea68b947e7e2be97b05ebc6d4439e950276ef3f0e6a03dd48b24f66929b49c1580eb468807e1e7a25eb9b94da340c53f984f8b81603efb61047bf3f14b686d9798003d2f68589a79ebfad54409c71c90ff67c11fbd76cc72c2d145f458e42f88b75d250eadcafe66bf37ffc837b62ff006685b7f85a9d875fc078c82e61fe35d1922527a551dab62f9e477499146bad912203e664c417c3679c02d872abac0032f8cc77f77bfe54d3326fdee9276a48ea4eb251350406882d08c830e7649fe6854558a7513ab2d8d2ac3e5ced8a808d2aee454779edabd1aa63bb19f718f470bdc8451cd9b294941e3497063b1e39b6ca184562fe838cbfeee922de24ddfcf9882c5e615b11bf904817fbd647139db80b4e8feb37f11e1852d7e876db9cb63c94d7ee34192f7200b5bc77a0311ae43b806ebd4c2896c53f58f7ebc1625cb20d7107ef9db0da28788523de991ef6c5866b18d8de83a954d3281e06dbf27c4f2382e08cd0e0f6ebae3f961b77fce5a95a9b0621b756f
+SIG: 23f4f1627fbabd7891d7d8489631c7231d22de71864e262ab4da84ea8a13a60feac4dcfb1812f1200444b775f121d7266d755ce9b6a9ad796559c0a26b516d02
+
+TST: 392
+SK: e9f6d31b936942c526e0f9ec4f5a7ac25fa789e0c434bcd9199d720c743c84c4
+PK: 32126d26e28231c5b585b13f43a01c6fe542946b07d3a91e57d281523f5cb45c
+MSG: e88133f3d17642d5c22779a85316ba0df34c792b4efee49ed7dd93ca3322ef47c72e5b2e4595c77800434b60719adf54e4c1a34c89fa1e27ee8d35a0921f9755ac4a77a6c1684ea0f5c8ee5f759ce59bfe8315800a67aa6c64ddfaac92eabe6c2c613779784b3affafcc620f2a6dc5cb8d8dc7d74aa4d79494678494e5e6394c433c14809ff40c9a592d0d694a81103b44531e1f48bc13965d15af8bf3340488f8cd58f09ae1a6616bf85ac9de7e0c6696aa2f1bec15e17a44da4a84edb4ec6d77247788ba0de3ae12a155cbedc0da2f568eef0b75a877ea5b0c2c0d4bf2c61d468a46faadfaece35fc263a9be9987f4f7f78f05c707784378c7b8f7daf9ac3a122aad39a1677966da9ef286c9e062c4f439ad0bddea26e54b2f7388e238b2a64928450d34564c5a447e7afbbedd1085f1f24c11ae084322d1a32cf8aa473941f00d56b1618213cab3900aa606463d9f800e926f9f42d4b082d8c5ec3a4a025b45f9aadc8bcbd17091b3da49e9453dc55e89b5b5fe6b31f5eddad10b6601572568d8e205d3251a
+SIG: 7e3b1c4c716c808e90b974458915f3b2239c42077119fe270788fae520578bd7da6488044132e1bef23e3b23c34d9c1862744f28fcaecda6cac0fd72b93b6a0f
+
+TST: 393
+SK: 6bf4caaabb96854a38a572f4ce6c7838f7e750118c73f2723582618e2307f838
+PK: 08126373d056f00e54b8d43d77c35f5f919833e90d8aafd6c8246d27917ad091
+MSG: 4776e9d60085481fa537bf295bdabd8b1cf632a8cd40bce6bd325c129f977000e88468ebf2dc158ac0f207212db00fb60b8ec8bae229372e9a6b01530a7ed1bc9d389ec8913f59030d5b54af56ae1ccc28f37cc96a8e53204e92a677766adfaada99b0281f867f61ac9ff7d972ee3ed427d72faae75d4aec01b5ffc37061b6f0f7e5714c4cf30d5b731b0746065f19e4c8922dde642f80fe24a3c8dcb2e5f1c266e2af6c37decf55a2baa54f0d5cf0839370c3e0b4e77a4f36bbb3162014933a4a4ebcae8c60961ac6dcf134f30828d31402ae74e7e8513c9d2ad8ee46b7a9d53a1f87ebfce04f461bded1749b6fc4c4f25793525692d7a0e426c84e06082cc3e6abb51368370cbb106c7a0897f66d92c9739cff9f2706d6a2980ecea3ac4945f0f47e656bd9637777e853d2a839104327dc049ebc34f049d6c2f80eca99db7b418424acef752260d2d427949323997cd9617edf50d441d0088b1d47912e35cf542315265829f383f45860d3b45e735bb2f8586dcf58db4f2acfb4a68853a96eed7b89769d365613
+SIG: d2113f80d6cf928486a250a679d6e74b35ea9d26061fa94d769e1a8fbfa0a734227f55537e4ebff59336db141cf5d6d482a0711f1e9fc72ff70956a11b4fb909
+
+TST: 394
+SK: 5d9585736ab209b0abe8bf74aca4eea4f6d1650b532550a223e044580f8e20de
+PK: e77729edfd2144b2b12078765417fa21f1594f09b269e9b6706802b4f3bdfe85
+MSG: 08693591e6c58a5ead9c85fe8ec58508f81a3467636c2d34fcc1f466e5c6dafdc37c35cbee35589c6997e2b15448132744e5a1e131bb49bf5c2563f87ead3efe01e88cbf24cc1769c78cdfc167e378215b15859c7a28ece70e188fa330267d3fc57b4ace6c1520ec67875067fd33be86f4a1967afb3eb164c797cf28d8072aa69d82afa38374f8e5797c4c28471b7d69f5b9c7b4acdbc19f3c5c5d400808a982a47837aed1b3841d69890eeb31494e10e3e513d12d0ca686c7ce651778092703fef0dcc0214077dfb361251bdea4364dd41b97bceb0fb1475a50e4708f47f7878c74401e9771cc3fceace89169981aa77250850090d181d8358ebba65e290acb0352bece8c579832a601551816d1c05621ccbbee0fbe39ea2f195393199e69c234c2fb1c37e474840860ce609161fcfce2869574be0d38f95e20f4f8725247b9627b46e834905101ac12b934cbf87cb2d190d2f51490a82c4e810eddb81f956a9f36bda497bca506a49ee9cd47fda5b7f2b884a3648cadd12ab61898ada46ecc970f81dc9f876845db
+SIG: e7b08e1d5809fdd8529443d65ada5dd655ea55b5415a011393be7071676486d358e8d2a460ebe075b0e701b24c9e3ab5f2b033592d4de3b7f37fd541f6920909
+
+TST: 395
+SK: 60b142f165114143ca30a604fef51c686436aa1b9afdb266b3e398ccb3c4d855
+PK: eaf6c5a76ca99bf7306498888c3b7a1feae98bf8988d7f2e1547f8f53a4528aa
+MSG: 1815dee1173b78264720d35b7cc2454a000a65fff214e2473e20bc83f3ecde9c04c1e0696ce6e55519dd2a75ce0464bf601adc381e793ecb9f8ce7ab87b6ca2a3e410f639069451978d14873d3390fab8623969713c3dfcd58d86d124073761ee09a652a48767f9646cb726ac454ac9a1bc5faed3026b703982bc2b1e0758210e1d62519230eb2b2f4a486bc55168560c4363df5ff5adfda11ac7ef51b18196c94337c07aef117990f770c0f1e8c0f88eb6ffc40e8ed7c3a80a632db1e7f63b63096e2ac49e57792b31143e2f4faabceae66b27471681c36fc1139007f9b548cdc6e3b8fbbdaba7a8adb843431238bb461ba24f6e09f62c72d6377b4048cb0134c25a5411a20bfcfc13e48d80e36bfb0da7e0185d33f1928636e15dee0e5df8992a16572b13ea8f7cf85cae32d529f66e8f6d2fb2ad0bbfe7199169b2567ba00c781b20a48e1d70df9fa3119cd7e5bbe58884b0b51218940fa815f85625fa203471cee8084780eb0b9356f9f3d4f6df740301d707ef1ffb3519e3f90b8064b98e70f375d071426881718
+SIG: a621f084ea1a36ef812a9755c9afbb53dadaae6b3a53fa8344ca40d3612a268a35fed0fd398ab75bcd639c547937c94155ab1a7a3467dd4bfddfacab1655e908
+
+TST: 396
+SK: 734ba47033c6140232dd4a7a14f1a7743eefe9070bad9662491630cc9d28c1f3
+PK: 2fa5df3026d60742e2aff6b57842c7126846c8a7bbe9266efa7b3f2398c357ea
+MSG: 5d3c659810c3fea52a6df3861e5cdc5b703cc1cef48558c61d8c51d0edea5a1479cfe5063d82ded9ca681e5748887c40ecfb9e1a9a8b7f8509d10776461c3923399693a78189089178d5aabd15f8c846642be47d6d4caf13824edcefb809868fa72ddf035c4de8ef0a9c832264f66f012761ce6955bc3c416e93e29188025ebbb13a553258c1d7c499c9a4aeb10bb36f61d1bb4cec5ae55d175722b9a9696df881951e35200b9653cf6ed4b3d15de087a9d1c319fce8582156bebf3fc91e0e610ff7a15308fd1d2c6069fbbb2947d3110731d245ae2963014bd76dea42db125cecc493c8e9091a76646577729aed4966fce9699fe12e367d665df9e95a9193e1133e143af92f82b66ac7764e5033178690521809a7107d8ae9b88e0ed1f35b1719901b930ad0e1cbce7fb30267b1155204f605f525e49de2988ea7f74be8815177fd976a1bcc126d9c9c135c5b4276d38019c34aefb7a0220f7f5aeff380aed627b070c2c9e21533bb35c08e394c85ae25e6862942599c65dbae5977a584a88180e0c8c71e5a8409e04ef7
+SIG: 9bd074d1d0bd28001baf7d2d4e82435df08c4264d8cbb1c381183c2f01223f79f94923ca178cac75564e16c7f56079088f7ed885de4d509fbc78f438fba3f607
+
+TST: 397
+SK: 45e34d0ef4c196fa6d572b6b1774b5218f7c3291304c13500df7070d90e8039e
+PK: 13a7304dff423359177abafa5e6508d26769ca99cf8af45c383f3ff634406003
+MSG: 3d9ed5c64b75e135df2f5e85300d90f21b363935e2817556fc9311751ba7535477dec8356ec385efb82b414062f35bb6d3edeafde305f9900a25e9813c9ee0237d46409650cdcdb5dfa2301a8e2647f8d3819d86f7b7e3070d33440f82c4054b1ab5edebeb27f95b3c4c6fdd468f21600f03b3494da200bab9293c38d02fc44048e52ff5fd0f7217a04d4ce912a180d1628f368280b6892672e8ff98d4629ac28b60c02a301e6c6026c1b9e9ef21cf0392df225008d5a0e0284b282631ad1710f811615697066c98296519948a7cfed5aeeb454ee7a61cc271bd3d499be17df09d3a0e790ee6b9bd99e1b919bed4a063b8d1a34f1afd2e952b9dfefd770969c8b2fc37977abb0fee6317253a23ecc97578168973334c8f91763ab97f29c49baeee7b35f3ae7f5cd3a4a6e697ef255a3c2ec0c752a3396f69f663ca1fc2b332dfe6c0faf78afe9c68d99571e8e896c5093085e9863a27648a9e58f3a9a84cbbfe2b41ca3633dd5cf6e82cb77cecacad8d78b353f48db42d99c36bcad170ea9e98abb2788c33a3c706268f3631
+SIG: b42c1f925f4baccd129efb109db354aca31c6898f4f451294749a26a6da1677bd3a5c04119e35f47319f20cfdfc08bb4528b21009e00bd41ebc0f46863bed10b
+
+TST: 398
+SK: 888ce2ecceda9ca2b948ac1443c2aedd7595aacf36edaf27255bde7a6991dcc0
+PK: 016e572b4f98417c6ee297abd784ea48226ff4fbf0050a5ade8806e7046d3ba3
+MSG: 5c801a8e664e7660760a25a5e1431a62159fc3f3aa713780ae7cbce23b8564782799bf2be4817ee2921965bab7e1d44833824c1628d42dcee3e46ae42b2816d0a432a1ab0bd21fcf30adb63d8dd76569544343d0035c760522ca68bea72c404edda1e9095ec90f3325681c6de0f4c12d1afbcba2c7871a1b1e1f19c35b0bed9ec2a87c043d36d819396bd5d099e1aa090391297c733f65a8c5d2120c67635316fab25b4d4847a45fc3f76f2e2426dbee4629975062fce14e2189dba27fb1ded2453f001debfaa899c11660612d2ce2ad2f762ea5dee7e71e58adcdcefa79e8e8b27fc4ccf89aabf176b5d34f82dd15d889f9f087dc9ae8a42a72f3b83583616e170637cd1adf38aa6551cbacca3602bdc7ae210c4a446b3af8db2720e549bbedb8bed215ae00f19da29d8fb0b642d27b2d88575f0ee84f3d129eb774d20f537a1c0fdcf717bdebcfe47f8331a341864346fa6a1c6bbfd178819e387a0d5499a68e81cc9f82ad39e31e4dfe71952d5ea5cc8052a3ceed1751f59dc7ecc9742fad144e18dda8d0582e74e39ca8c4
+SIG: 99d83f148a236ebbef1cad88cb3c7694f4986c9250e21c3603a0d941bff199cf77d6ce99efdb20533188d68ad133de033a1fb3468abb706d2b8b4fbac08dfe03
+
+TST: 399
+SK: 617390857dc10cdf82b5c94261f58ce2d44aa2f57d298f08a2d6c74d28147daf
+PK: 89e0c3e0a0f130d1916e0e3849b7286fa2e3ac4c17bd1f716ee5a72f0257fb8d
+MSG: 1fd9e7453eaffd7c9b54055622dde170dd58b71cb945de75351d5fceb1f536bde25158f03786155f953dc207a1708f90d95b15aca0aee3097fdcaae85e4ab1c2cdb705c53e6c2ed21a994b304a75caf2ce4fc7d61f561e74e297397e2cde5cc69056940343aa81375d0af18d17d2f34c0a71dcf1de3c4fc488a14c5fa6b3337a3174b1da7958fb00bd5955148221427c60dba04117c80d2488656dbd5343de891287b50ef4df9825eda76b4977f3acd4ab6d3102fa56878306cd76561491bcfdaa1da567e677f7f03bae5dbf4426c3c4a6c3d082f9178b2efdd2bd49eee97ef4dcf3f0f51bbdeffe5ae6601e28019518f827f02e51f6679b8715978bec3e69d577156dd719959371baf034219fbbd17a2369a8541490f6a02013e33e74f4769be37aefa4defb6bfb3f351c2a261482c2fbec49f85f8445456e8f5a474030cd72d095ef6a622030e1e43a0c5debb034731d2f5e8e4ba3990f077d0c162649d1fa3ea4fe1e81d74aa849e21b059d966cbad4c493ca10bafe7a69243e3c0a6ebfd13d697906303392ba65d4fe06b6a5
+SIG: 63e90a6afbbbb0ee696bfb56efd679d68a9851a8947640a97f41f68edfeadd216ed8698e2e43c820c9044caa7adaab5b76762b681831a9f760476a8443c43c06
+
+TST: 400
+SK: 877d017436369ec2453fed46e977d6acc3a7be60d31395ad6e7ea9e07480e4c9
+PK: 4e65422fed334a55e8b673893eba7c181dd724dda002817b0bae28acdc3f7fc0
+MSG: 4ed3f5bdbd41d0e3b0a8a7fc3752eea496d6141678cbfe06757f61e1a168d761b6da83052f7994950d24626f004fbe9b8c9562e0c955fb3b5c08fd2d3d258393a349030c8e156205b40483038be1959f1cba490a87fe13899e4f3752063b68fe3e1c5071f7db0002f01494b4a3ee2e07992bdd200db4316629ee8a95ca347f0b28d6402a6da8b53e6b32581c3691e11ae9b6e0f0494894e649a92d03eb49c4d6833fa1f54f8dcd91d06936a6e62d491e2cea46dd07d9f02d3254b850bc9749f258a61ad3b9cc24b03287331b85a24143aaf8fcccac5f18bfc72dec75c0233516aa6e4589c78c665a186ed902091df97b0d04e83a2d74d789891aea2cacf813fffb5efaf78dbcd7af54ef55c77b1c4c8ace9e9278adc23d76c779d64b3bbbd1fb33b09836ea64a71e4711e89e8da0f709213342176ae22c6e7852c3973b60d9f98889b442aa48d7bfdfdef64c36c586c4fb2ad2e27ebe479f6d722f069fd6106b0d08975d5f721547c3b9c52f9fc5f45bb45b5b632188e80626518a79056bdc4ee1d2be6c6542a21fadea92c6dfb776
+SIG: 7688f3f2401eacaf2dd88e170ff1c4d7e94822a77f6b550b569e82152bbbb434057e01230b05ce58ee1dee5226b5c7cdbe5a8ade3b9465f59aed74145d14330c
+
+TST: 401
+SK: 4f0b3607d70b0f2698327ef4f1982c5b4b94be78f50c76f43bd642f1f0ede39b
+PK: 942b43089fd031cec0f99e5e550d65307fb6c3e793449fb390ff730fffd7c74b
+MSG: 9f700a1d2560f69d9bc105bc83bff539e4258c0248602013a959b978a19cc273280d90c0178089578b50518e06ad1eab790ffe710c63d78887a95569144f3e58a8837f93dd516fcddd22bc97a7f14411d424b2e8e9aa7c280119ad94ce92533fc7fea6c66248644ac3e1beef2553a6f61e91b9379b0fe0c68b40681455b311f40df0c97f53fc954242c375e7708d61bad9f51296247274fa01a7328fa5009d9995f501ae8683552b11a49d2638116723b1319450a90138d278cd9512b80ca5792ed16c683bef92ec87884c9f07f137dc47a13146e511065c2e1b4b80efde88ae12e29431beb7aee365c16d80506b99afa6a1406edb061766875832dba473e519dd7018f402eb1bb3014b7cee4f02e980b1b17127e7d25dfe0c168c5344f1c90044f827707dca03070e4c43cc460047ff62870f075f34591816e4d07ee302e7b2c2ca9255a35e8adec03530e86a13b1bdfa1498813098f9ba59f8187abcafe21ba09d7c4aaa1ad10a2f28334ab53996147c2459c01b6a10839e0301123d91a35ced7af89afbac7d9cf8ac9a38ceebef83
+SIG: f396a11f2f03c61439684f79001bd4f346a348dcf1d3beb2d3bfe33ea73a5ad4eb97506acfbffb784e77548189cd599f8ccf17355dde80e75024ef2a78d5fa03
+
+TST: 402
+SK: b8a0010c784d8d002a31da11d022d30188a4197a1d5f14ea4c0dab29a2e40668
+PK: 8bdc63e50bede13c91a41e4b4b7857b9e553f484e3c1ec167dc04c281ea86622
+MSG: 5c6ccb298be216808b811e56d972f456b69ad39594eee354701ca6b3e38d1f41a359e5512af98a3a0873265fe5191f4f2ecaf66bee75a3ac0b71a4ddf2a759ebdddbd88a6a1c6fd0fcf7d7cb92a84e3307b4a4f98c710abf4f553dee74f652d2ac64bc30f72bf4354ef7e806a19071a051bcfcfb27e37fddd41eceaec1758e94695c670ef4c5a5902178329db9585c65ef0fa3cd62449bb20b1f13aecfdd1c6cf78c51f568ce9fb85259aad05b38c6b485f6b86076928ddb4e2036f45e7b9c6a7ff24ae1776030e2576825019ab463ebf7103a33072033eacbb5b503f53266afb82f9b2454b8dc057d84f30d9d2cb7c3a31a7dbdfba5b8e49231c231396c47ca042c8e48a1a5e3ec9afe4020595390f9990dfb874e0825ae9ae5e752af63af6fd3e787e75e8d8dc4c66302277ac01b30a18a56cb82c8a7ebdc915b7153255a1fedc492e49660262bb249780d173e1fd20d18c4f6b0b69aa2eca024bf3c80d7d5962cc4a129a7943b27f33cc799a36045541275a2cdb92a40e485ba8b737a04b43d29c3e25f76cb3d93a6b94461f88f5696
+SIG: b3f6cf4c0e0f9074ff2c2c47e163202f1e9d6ee117cf757633e4abe74423aa70008ada1509ec1dc117c1c230e9b23786f3d0f29b73aa284536e9580106a8a70c
+
+TST: 403
+SK: efc86cbe40363abfbb2a4b1fcce5fd6084da96e7e814de71aadf9a618f303625
+PK: 22f295cee727d28d2b9317153e7d9412da1065c1b16ae2a251dd1fb431c62b01
+MSG: 9e4fa45dc026710f6bef4ed0f07c544b0bb0d88fa79e7177d8448bc209d71cfe9743c10af0c9937d72e1819e5b531d661c58c63141ce8662c8839e664db79e16c54d113abb02a75bdf11b3453d071825bc415741e99483546b8e1e6819de53017092e4ef871f1ca0d3508f937828a4667db11ffff9416eebb94bf9b84d654603094834a99ca70b90f562a86823624dfe9cb2f9e88c173f13464d4ce255f222db50dd63ab42465734e75295c064b64cc3f15e6237e37f33d615f7c243e4ba308960cfd4393402525500bb7902970b3931d48b35666a2d4d2ab08fa12af366a004346c9dd93d39fb1b7340f104e51fedbb533605b5ff39cf6d59513f12856dcfa198d793b0fc875cdea0741f1455746d8a19c3e9d928f0021b01c25131811e48c3c75c6f41422a8810c6c81f35b454eeae8cd17cf3f2e6f0bcd9f290984f496578623ab8e2738d2d10840eb91d101cb4a23722b72e3dd185440c3b9f44d46a393a34c187a20d610bb698c50531741efe96323512329800772a408065a7ef8e4e4105eb1f5bf6d3fd6b217fd836d89f53b96f45
+SIG: f8818310228ca76111524ce94bfcb0246ea63508cee9306592b2f77548edefcf76bd1454508ea715042cec169cea5115ab54235cb1097b10702aa38378028e0c
+
+TST: 404
+SK: 33556c60de2f2c9a9303b99add378592060505f8e49861085a4b15f072a7ef28
+PK: 231ec8cd845859f69961275119dbe4f715e5ec5aa98bb8741675b3c2d0c89fee
+MSG: 96af540ea2b1923f5fd0aad321ac032070c2d65ba13d164e75c3469758fcf31bb31655cb3a721f9cb34be2c90c77eb65be37f606d32a917a4cb9a709ac0705229930ef6eb6fdb0fa3c0fd3a90ce171674ee3ed06354bafc3c7075467a57445b80385640447902be39262894b1f64fea58287dc322d19875972a7c8be91d31f021c70eb682fdf11a10f8f582a126e064794838c69fdf64f5b6e8ba59d48b4384f8e9fb5c087cc7738295cd32344ba3b697ee6b6a8b78ee7a9575c97972a4d1bb18486f9037a0f3c6f471a90f86498dbc0df5232c07e8c01b690bee75302992a7a36fb4437c25a8bf5e34cf7d5b55572c700a079848d381364f9946a91eb1603ff3de5ebdd523bd92564818e237a53e8f522deaa2c29b897e961586e100ed0fc0ad70d160934e694027e5c957920bc0546e901be39a84535597e1f280c222267abe97f41205d8171820dd2faafc0699419321a9160f69b99fd41180945b62d2dd105cc7bbe821d28605e098edfa8b2309aeb0534e756377f59937c67463fd87c8b92ab58119cf4ce6c665af572fbae1de4a2cc71
+SIG: e06a7a414457bbbef2bac3775ccad087dacb1fa4bf938894e8c929118e09e678dd19938bc88f43ed0f7d31cc6a0e602c4e4d1fee33d41e74a119fa2d1e4e340f
+
+TST: 405
+SK: 7a5c74314e1183334a4b6226b9a82d70fc2a124e3f87db6a2283ee05b68e34e0
+PK: beae7d3dd97c67f6273bfaa066131fed8ace7f535fe6464e65791c7e5398576c
+MSG: 98bac6724755912992adc2a48b5442376f2d927997a040fb98efe544eb0c8e1866b9616e298d3360316ed976bd946a411fdd3a6b625c0c1a37af0f41cf6569a7884ab8467491a987df3ea7a0b7ebc4692569a34ce3a2ea3503495b2c02d49d7d7db579d13a82cf0cf7a9547a6eaebe68e7267d45a60b8d4772455228cca4036e282e1a1216f34cef7ea68f938270bdb04293c885d005f9f7e638a8b4ead2626c0945174ff2a3e2d6e15a4c0338c09e1260f0928ca9d3499824f3fedc4785da49c5c34a56855e241facc6347a399ddcac4399a8b158198c151461a3b189e58ec1f7efcf2ab2031fb17b6f035ba1f092e9eee2e92c2d6cc2032287f854b41e70fc61c8d11a2e4f0708f02eebd02e8c7e8c7b38a57bfa1a745f3a86c23909f6f89ab16ce7e1813c1d20147f31b4cf2ad0b606fb17e5ac1ab51ef4a7d8093cee9a655f471dc5b146bd1b93e540a3d3d3e2de8105911c10d6ab5ff79c2d06027f7a54561f2071414bd330a8785442251c810e232f83c367f0be7799a93f5238f7f17b5be829fd89123c04833af8b77e5a4363047ceca7
+SIG: c2ab1f6f5114a84f218502582c567b37a8bdbcdf6340fa4622873be89106f0a90b4829505f72129df0ab3d8513268774a34df3ad21ce254b464488addd6c9b04
+
+TST: 406
+SK: da8006adc492ca5dc86c2959437a75deb6120ff787d2ecb9c20c30b52c26bc41
+PK: ff113bf0aa58d546f2385d444ecb7888f8caba43a174a89fd6065f2b7dc17bf0
+MSG: 3eb4324dbc0149d2e7d6df632bb0cbe9a9f6dfa83e227fc07bde1b577b3611fb921c9f8313f068e6295d4913a8196be530f6a01f57c09c028491444b784720e909ea1fb69c1c1dd6304400327b7731b33cc46deb046cdab6ad1b53f1749a0c65cb9a7e376ffa02230f536584aea243c639103adbba764321649d7e0126f82e0b4fd9dcb86c731cbcc517f2016841e916bcd5fde871dc098cd913dc546284d1b2165c63e88f32a2789a500856371b50d22fb8c87d1a3caedcdfd01ee5f870a53c284181d632ec66d48b6bdd5646ac39c9e75338a520212062bc3466ef5c58765570b905f63a93d07f8f1baac3526b016da799f3e9e03a4f7f81355e0f7a76f30a42b807322051b71c626a7a296d75b9d9d1a23bcb13c9ef48a912dc057325d3bcfb3f9fadaf0c249b102aeb854aa3631e34f69ad90c2ab2ed33bacc40b9ed1037fae67cdf799d5a9b43785961127d62f8e0bc1589fd1a06fca2aea7cfc012cbf7b5b207ddc4e677d8ae4aec100045ce36c00b74d1d28250791236dc5dcc1ed313c8c246172666f75217437c6034acd64198cd96df2a
+SIG: 1f5375dcb3ad2baaff956d8554ecb424176be9a6eb9ea54e814e0a73df2a5d848ada26ba8e1805cd51c5e16950c1ff7d4d2764daa6f4c7502fb865cbe55aaf0b
+
+TST: 407
+SK: a284e26b97e538839c808d45bde6f012a354454aef81caa8c55914624f2b7d66
+PK: 5ae46e34695efaf463a4208fc4e35b81f2c63593238a56f2444b850f058c3c5c
+MSG: 9ebfe910b50a5cb719d95b961e5905f00ec7943b55468ab5956692017645b366071f8fbb77eb49ec73ea7d64511405b90de22db98c3eae39c4039c7a133430e8010bdd39a00fd1a528b113dae149cfad3ae340da27dcc507782ecd8929237517afe7463eca2473c7acf6f7aa04efc9f266ae7b6d63bb8cc2a438b344827f0713d1f1736f0cbb65b99353f20355fa0230d4fa707328a8662654e83ad0530a10f9a69e17c099e1e2b5db18e5f6f1dceda5883e8cab79701a5e9089562ed153ad08c674f097c28e4d16633e092969a8f0bdac54527c0ee03bc200e5be612e3d1eabd87091101b4962afa07b310806992f373076d76a58185118137c9d26ee2cd4c618c18283dd19f0e7a089ee37305b6b9518a78d8098436ef62be7d699808acecf67939d61b3e02937cd8c5f1e746d4274334bc9c37fdcba234c166fd712893f3a040832ec5425e57d80f11ef9ca5fbcd6c147fbbf5e2fae746e0ddb605867e3bd050483c3cd1329abe57a60bf88898dc7e80ede0f4517de8fc807e888b621a00f663084ff94b99996628f3b11690a60f0918cb5c9a7ef
+SIG: bf110e2e9cecbc31fa3e0c2438cd1f4321f92cd287005a48528addf76cad8d88bb22719ef91b139562a1511838682674faa9ff7e7ade6c9d573f845036d18905
+
+TST: 408
+SK: cc97a96301ceed0f922731b685bad8ad4f06207be340f5a44fd187f29903ec20
+PK: eb563a7bce12db97f1891d0f610bebd55101a3125ca8dbb50b25a6b5050d3784
+MSG: b9ea3b3df7187ea415a3c335e0834e10f440915b2ad41c71f255d6950a4e9120e4d494fd9e672ce53206fdc417d865897b47ac1054e1ca1068195232d4297435e44e1224e66a912d9d7d182946ff5a9f085bb8ba19c54d16b586a9b30461b6773b93950311e1619886f5a5b3f111aaad094bae31c48f1941080968bd0277bb6fa92eebf324b192df5cc969516c78c7b2d12159b4d1c8eb03160c4cd1907f62ed4b854c569ecc481c08e636f44ed7c390e58b5937d2906b2817bc3769dad9da1b0f79391b55942063055da0d6f249a3e452baddaa032998d7f73398ccd0151bfc92c5e2fdfa9b14855e6b0d3746dce248e219672987252ec747df2747fd3fbd8b714c882d707ee302a904950c34754f85350e1aa3f8ea6293cf01f717cefb6b83a22126df5c4f5698aafd06a2244ad7d01f34017ca0ece6f21040048aba6ca4aeb04325b9402bcd43ab130a105788ac3d7b7da01ea9426dd0ea1933a8189933a6c0c6cd648ea316a7469a5fdc6e7c934d9186586097b55dd51ac487bb80ed11d4df8d33626bbce95e4f13bd49922f00c920223f4cbf93cb
+SIG: ffbdd3244181cdf6034f4a450fdd95dee4971a933f8be022bb0a4106aef39af3055b721881c9b54d1e99b9409096fbe6dc2c9966e3679964bd7ef4c808cabf01
+
+TST: 409
+SK: 679e3e34773abe4ae25cae7d07ccd0eb3b0ec0a35d570257d62570de58ea2516
+PK: 18acffce253b27259579ed9924f479cae312167bcd876edba88b5d1d73c43dbe
+MSG: fb2b648ebb16688244f78b2ee9a273599d56b6198900d438a9e99c191425c72bec4f235847e18e47f57c3cb396655f778921f908580e8e83c96c108b20dd416678021bca259b98518fabb2d3532e4851d9d52add2542c0cb3efa3857a17e512438bc0ec4762e2f9baba429c03e99bec4038e6b0ca42bff5b233b24c333b4caead2de374a87b2ab5d80d6e49e4456329d51ae973bc83d7862f3d315e514481b12854a9dfc09e7d14f0d022c0ba3022578eba8f874deba4aa8c833f2b132861d4d51e50fe9aa4b787bd2f051aac50c375390cbbcfba2002b80ad00cdc12980f8ba8bcb7064afc04d5c4682c1029b10a6d45fe6ecd704245faf598c4659597c5d68a192cc1cd4fa45e84b549e8e5e67daa879ae5a520a6b5550519876a562ac49c6db0aa76ec69bb64dd6b5e1a3af2e131e722e7cdd05be34b5fcc6259aa124ccf814cf5b500d176be28ebc40bb21f03e24ccc131e0f41daa1ca02e6b00c9c53fad1248614e940d4b237760ab7569a767b7515dd2d623e57a2841b7d2441cf43049e4698d2f9c9eae7b2910f6ad65edf9cb2bdbd9b29f606e0d
+SIG: 1a51022628ccbb88eae9b21773c3f830b7b6e5bc36c9903ce70fbcf459d6a1ed8a1dceff5b19269ebf5a6fd3d8958860f554461f0e9fc0e29af9b1fb1744a80b
+
+TST: 410
+SK: 9bfa60923a43ed0c24e2f12f5b86a0716329f93d4d8d3e06238002893278c19a
+PK: fb1c00687781b55b893d6b2f4f49cf5f73d2903c316d1eee75991d983a1868c0
+MSG: a99028b0f4a3aa5e79abef6c0df4a783ef470f1a29ba51eba00f6214e840fe19e5b6dc6021ab599bb2ee3699576015d79a7939af823535b630e3938c723f6e0b9229d46bb3379acdba587c238567e3d89bc3bd3519b727fc694fff1118bf22c8bc8bc82c4df7f5ad38de05fe9f762999ecaa795f3ae630a9a316d26dce9f1568ffa3f22b0295214020b3d3f5337c149568192218132a90709279c01d23baefa669e1c4e42038173f1319c212da144f1c4ea4c52c005cbc0b5bc283e74483a0dca69279deb17ae5b29cfafa7d0063f4e1bc93537efd937e58a8aca737228f937ff2a741890e96c5725da11b45c413a9bbb4180a419987bbf046bfd346295d62f081c76daf2b0e1eb4f6712feebe6f0a92e358e7ddb85896507c340a01f68d1b0f085778b7c44b014aa6673e501796959a17a688db0959058488a7112572f23cf9cdb53b5eb4b45f5953ba0c0c690f86bd75e89a047bebaf847c1dfc345a4f3c7d3beec98b84b0219003e819f5c2adb45f8717903d1f5bd5d71914c56fcabc7a290f9c41699c95584d6a3a16340cb17baa1fc5e5467af7ac3221
+SIG: 55f202efb2a57be8b4e4fd894dcc11a4fc5f8276618ef5cd34a4495adb016a298e6480a35cfc53edb25ff1499fc532a33061cc01a250458aa5e4f7f16f51440d
+
+TST: 411
+SK: 6e3af45e66e22890c3f3c934f523a4d69427976e6e52625f8bad558993963219
+PK: e097364e76ff9f2e1d167f6b20c1bc5830085e7ec993c138f8b1b2175637e741
+MSG: 5cfc2f4b559f8205b39102087617f4d86c7ce6cb251e5f89601dfc88ed28e8d7a670ec0087d2ea5d893021c7044da2899a22d776fe90170e51c203250690d37a294555e74af9234cbf1ad8f22cee8974828a0d09e9554b71ee3bcf880ab98325f706272194eb2e80c701d441b5f8668561b88849f827af703ab0954105fd3c54b3f6ec5493596d0e3bc67818048310c4a3e0c556bc80675f201f9bb9c6538a41d99aa40c886fc431467218d819c23e78498aed0613fa6f973e2211df9fb87f44116f3fe4c26d6cb2fa334c87f78c08ca8c9b9041d83a1230677e0af788598a42e44cfdf6964a4ee80e38402ba67c73a581e552baa2282425cb2ca17ca92edfbf98299102fba761b9b71a5452141bb9c18dd95febc2a782de9ceec08bd2ee3f7f0c1bd8946dba99cf9ea086abafd37c9ca60213f0de17c61ff9c391c9818ed5cd8571778b7dcc13224962386fb8ca14f861e99f3b18edac8a5f130f7bfcd45d045d0ff34c81572a512363d6530f93813e5fb10e9cb8338a7f93800491006f4463e89f0ed4530e5f12df674f598904780ad0812b1e3521fcd0f83e
+SIG: 26ba562e8a4065708207c25e239b780aee38794cf983a37acbb9d557a65ceed3c0da47d17f3e8b8f4eeb1b65a2c182ea6f29623b63bb0f1c72592683b126b901
+
+TST: 412
+SK: 5f1f271844d9ed5a6a6f209a21408daea470f6fd53ba6479d7407105b7de4d65
+PK: 6085d7fb5a9b2ed806c1fd30a2afde760961f7a36b48f4875246e615a2bd9928
+MSG: eed6b4475dc263bd2207fe9d41d48282b713f680f2e037384f18b4bf224347f5e4c4b060b808d412eaabcf733dc39a40c6bda0505ce71fa823bd1b1794847678dc034e7999c16369340bc60c64d09bb9187b2e326055a053f8e505ea4196861471622db0e46f0f8954d8a1f07332da4d8ac55712626009912f8a15a9cd63a74a03c92f246cb63cc73f92e51dad1bc9715b1ed3fe5f2e1b2959b9b71e0e37360eb29536cf797147fab10864d6146c36b82335a0ce931408479c7ede484ff73e2dbfffc6c9227e16d7a23f4d90f15584514c39594e17bfbb295de9d62adadb589dbbe0b06dc8dac5b3bf517b24c1837b39472a6dd38931ffbbff5b763638805b4e22321f7afe92cdf502fb63d109ddcd9e4051ad6f45598532be179523710851d3931e887d02c345c79c489fc106a4ae162f7df71ab90b751da7038a6df7616cfc11887e21068fb9e33be566402be504f3fc2742b881509bd4fe6a0fc722649883f8cb655598a15a1d4c229dd86b5caeb711a028defd431154bba46b48172a4d8cbd45bc90aaf874b6085fa284f5fed655ad6fa17d67b3b9a796fa3e
+SIG: 319bb4deb2178112241b3fb8f46e105c3b8e4ef721eb200d762ef363e2716f2a89f80b5b9e89970890a09892ad6a58808b477e943b3cfa77774a3645bc745f03
+
+TST: 413
+SK: 048ac9ec3ecb30a3b1bfda9b3b79a48c0793b490879e3c8a5e23ee2babcd9b7c
+PK: 946c186feafc3580a58ddd526ff229c04720250f4cf6bde0271eef9b12b1c3f3
+MSG: d68be8ef7b4c7a4289f2b18b16ade97f4e4fa16452976afb581693380cc54de38a07587f32e2d4549f26595fee2393bd062e9b00bae72498e4148c8b882a8840e15b585c82b5c0defb233518409916615deb3a55a5f84e6b3aab93844de3b1e4d86e09f889ac71c324eb12d0fbd861cc31229540e843a34f8d5be47c0ec0d23df43e06813fca309439904c167d1043c0dcd444b004be1ff27b7862b00eba9433b94b0fcdc67521da0c1d5358636c78f530431164dde20a1cf164f51e29b8e63eacdecc869b41392c667664d91680d9ac516af548f09e60564e814e36e0b563dbae55c627ffc14158a56d8eb3609e174381b21de4ba82344466dd577f4d1103c43c27fb83cb833d87afdf7412b4090909b1dde264daddce967f496bf6f17112bf351e417db5953b13b8f0fcccbf30f5bcf376861c12ef20eec89ed23cf384ee78dc6eb40fd5811a7b23927c13e7dc5da3a921b883a9b2b1155970fb0da7d2993dcdfd4343642a9d5a6347e43c193b5793e4453ac1537aa3d04dc9f774e840934881d78a39ba250438c507250eed2f6e07cc953f783d6b72b1cc619981
+SIG: 2ecf5b8a59a8e27d25890a2aa32f4a0673275d539b174afa7b2cebf2e76280dffc338ede85ac8f614039560e2806d9e1e3cf9cce2ceb7874ffe1a7e80cdef40b
+
+TST: 414
+SK: 2f057d20b1678531611f48f003b7d22eba5dbbd7e2dd41b7c79d09071f85e993
+PK: 620fc4eaa34d787df675ccbf7e893204828db92ead17a1165ac7fa1ab42719d8
+MSG: 6e35f6eaa2bfee06ea6f2b2f7ab15fa97c5180958af2e90af918adfb3db8323f447c7bf26dc534997c38b7fc977f642de288cdf253071cacf3564e3b8ed6dce57ddfba9ff783bad2e76df124828fc1031acfadf01a44d41b42161ad9060301c1af1928b9e5b73b9bd21cac60a842b504dc3cc311c522e3bb048bf221444f53ceb08e77e948590e94ed98f1b604cb9eadc93bbe7431c1149b23193ff93e8569f113e1684d8976ecae6f09e0103614be418a472ef55bb8890d72b341cdd7505b50a45522ab63ed791ce8f82feddd7a620a4f6fb1d2fb0ed0c4560d78446d83b3d1b1bb56b366d196020d0624b1fbdb75ce735dd43e8e8df163c44e236993dca341f5132d825d0a4e393a19d38f61e11e0cf392cb9b646ea23c58099824dd8d9fbe26a49e33b23df80607abf19715799c19acc722ed9bcf94a0c29ad24b78b0b035b3241c64cd86edeac810e66745694b5eb1625060edf2d949de0d34f522df2dc60ae694a193f3b82c1d6f83a0cbb840f46c49a3d7d1cf06deaf96c64f8f9e17bd9ad512ae6309c486d9e2a78dceeca473a0421dd1b643c78754271b53ce
+SIG: 30df7b0b1c04fb1efa3517e928d6d57c2ca0d07f4e04ffb1f08b4792c5937dd271ccabdc00dce850afe50af5990f224e8420a681d95f9f7f515afec102efd10e
+
+TST: 415
+SK: 3a3d27970fe2acb6951edd5ca90dda0fc6dd229c0a56df6eb11a9c54d242dbbf
+PK: 564f0dc3dc4720e68e44dd16711e049e6112000098fa62a1b98c288042f7c3bd
+MSG: 4374f61c2cd88a3b8972249bfa79b36ab69e3ed484cc60e5d9541fa7686cf4eed1210c5d0dcf42dd25972501909193ca76ae6eb7f471d8bd0d5fb5a6b431bc3de0e0318d50514524de87c4b83005dfb41245fb1af79b84a97b83d3cac7ad7a53364e2e9b21c97b769bdc57f0703116168380f3cc883689eb4a7fa3b26dbe12bc28f8c40381af64df4b5361d174cf75acbd46428740b0d1322d32bbe94845215966ae588777a8c05336e352306d49278d328e496db65e9ecf6ce6405ed1c893490bc48c13a134e1fb6e80debe6d32fce6ef74783c8d77980a441a26aeb4fd83cc855352cedc188f5279ce211f744a40b23ce7ff24437a1dd3373ec5b290da1f94f43a07a3ffea5b5f67b52c196185bce9e9a858257fcd7a8ebaf9040ed091face5a155aa447fa15e12122d25e8fc36eaee2137c7b3aa30b7e3ff6cc86b6dcb9eaf49c9576f0f462008439cb1a3aba013e897a0faf994cb7d59ede5774bb144774f73ca30e6414a7cc7c74b20c51a1404ddc419ef7624593e9bcfb37c0a762eab68faca5863443e16edb759dbc8788732b9e4f59c11192c3fcc872af55f32d
+SIG: 22eb8ea0507349b6a0ace25cf9180cb08e0357b04502905fbe69b4e21b2bd94e22cfbdb851ae716a5c253c70d5e2b24ea78f35bc213292543d94e14110b24106
+
+TST: 416
+SK: 06d498318da456242b9c3b9ab6d532a128fce044f53882682e9262149c165288
+PK: 413517aa63200a17173209a4b3e78ab9383cb4e39efd6794c46a2d13fafa99c0
+MSG: 3fe30ecd55077a6e50df54bb1bf1248bea4063e3fa755f65fcd1159ee046efd0eb5f2fbb38b5c00947c97dc879b36b9e536192286086d0dc12053610386174a7c56f22a85b73ff208c5944f393236c32415809da036e73cad8fc3c30378064a76afa930a3baae9aa357061a8c5e8e756a9cecf94b72df43facd88fa49cb4948c6368318a6b1e5cff52e587ecdfaefdb69081f28c2d13bf8eab81dbaa5e3728c4317fb793dd196bca0fe54a6c242cf26e2d129ba0d82a2c3a45bc8d1dfd6f54f8da4f5189c91ac214fdabf4c597381b2e5c40cc71fa7051cf2ea93906a37d57df12d5c7e5cd77c907e442566315bae51a2222d62e3f42d1767882637d66a1d5305ab4010a0e49c57def69dcea839e1b76a41135ba952cc424950e8d3aac19e1d93de7757c15ff9997b3d2a8613cd9a164781d1be331799fa6109cef614305a1958f62903c8c9ea0b23ba706d49c54baccc1e63cb4bf14785fc7b062a9800349bdb0bb927260b677b60f10e62c8780f3ebb5eb6ff0360263d457ab52fd1125c9ce046a95d89d287350c804cfd4ff2b2ddd18a9e13519f20b4d1e051af624640f
+SIG: 8250f76dc599c5128787e4f6d3da23173330ce3320dba959bd714cc8cc07c67945d63e75662c075e267460ab7bf561f24faae3b41dbf676899191e3b02b5af0a
+
+TST: 417
+SK: 8e8e1db5b1102e22a95c47af3661469f000a33f13b8b87b115d2452a411f6f39
+PK: 56d7b3169a95c22998ec937925bd7cad13cc65808cd5d34a6c4da870eaf32364
+MSG: b24634fbdd1b7661315d9dc153ba90d66a88622a4158f8bcff25ba9c29e65f297f8e60311800b7331b69fc20c9f85bb7c184bd4086b3a9f9a27102b62362bdb4fa5b201594250fc628fd2e0e0d1be03dcf818c6094c4c29121cb2bf6d908ed8aab427c3771c0c95f0ac1469a0810b603a470282e5980a60729197fe6c20ef681cd1b96932d2058f896ea7416422a7e541f224a5f04253080741c5d4e3eb039db6ba051b4ca5417ce8afdc70214ba4dcc85b623d11e681c6009aee4e6130a83edd0d2c99fb0647e11ede7301ae56b59904ef7025732cde038801ec7e8d90a9a1bba047fe628351b3b89d0bc5ae665a700891f09ebeec05591842adfcc25adc3c71c1ebc4a312e5471be67253b0e9428b0cae37645a0f7ecb89dd79fbd9be2875433667ae07d74a7983c4cea601e72e975c21df993e7fa22a9fabd45455d45e37031558e13a7a4f5f497ea78fb7399f8838c0fd5de4ebb66db290f43a4867d505309f1c1bc27e9fabcbba71302fc1204715ce3fcb0905bfa411c9d1c9ab4a39954e50b8e0cf736c10289563bdfa967553c36cd9e555bc8cc56be594847de9f26f9
+SIG: f6ee5e13cfaa362c8971d5a4a879a7e36966525ccd86c5a48cba08d913ece1a79c4cd146b8e9c65125fbadf17bac1cabcde8fd17cfd68fa1f9c44ea61c08a405
+
+TST: 418
+SK: 3884b8b79abfd3be6c13985eb859ab743f157cd9deb81b2fe97ea4d6173e46f5
+PK: bd7fd9a8def13a542ed2f2fb048886885ba9b5ce59cb7019fb54667986eebc26
+MSG: 12adafe30eaf2b9c7203ca5d44b97ffed4bf6517a49988e4e676c8e314adbdbe23d8f2d3e2b081a7024fa525ab5aae26e60057c101e8f368d3addb9376c4682c1f4224d7f149a8474bb9a8f663ef210e9572ce829da388d8aae72a467141adc153473be3653baaa64b5b1e2e30683f6f06dac2784d5bbf0d082aab47305ed8a8efd0886ce63a179315225d1e4d4ffcf1f24ac2f464cf5ed3a8b6d3998454f1c02cdbf0a444ee2b59ddbe0a174a0d937fa62865088ac647499957d281c6949803a5fbdfdd0dd9e91b6976861f3c5f2126f39aac935be09f4b9715bd4f0d5c55df73a6b9f2c0ad26ce49d822bf85bfa2346f3165b03859a71c3d2a7b86db6e9f2e5d7b169a910eeb7ef38fbdfbbec43a9a25f04bc3acfd3b0691542ab6de9db6f03058f9584024f9918edecd90fbb85735d6dcec5bd593ae63e2cc96553599a310f8f2009ba95371196b4d5b80e7559637f22926778be5e1ccef5126e2443fa939c2a53dddb04961eefd34e538cd8d7f0bec2bff1ef0d3a4bdd358317637f42d595538c1122251a94e963d1f81e7b9aeb164f95da9a4ed7529b845ebc961b27b5c19
+SIG: f4206fcd34502441d54a73323f33a5dbb4c98557319f21246f260ffbbe5844886db567f4b63c47943dbb78fc35657d7c04d4feb042ff8536f672925c319efb09
+
+TST: 419
+SK: ecd519f287ad395052b0b30deac341d2a9df13d6567c891c813a0c9ca52e871e
+PK: 8ee94c588e0b343585fc6748fd1b54b5770c64e9937a56357a48d44ae2f51824
+MSG: aa71be5f557e10c9fb5f091a3a274453947c07a0e25b26f9509224541dff76f4d96effd0d5a41d319bc9321a86667d55cf49432fb5c3e715388f3f106c9174b1610c8f3075d5931c290099385ce9249e235128e907c53390036fbf5da968f8d012336958de90c5e8e6b1016ad43fb57c8e288dafe14e90e64b63791e5cbe557e02df8ac9370642a71faf851075e5565f6f9a267f4f6b454ce4c5474810b804844dda38392939719793246aa47454b9b0e82e9803c09935d0027f3995cca9713069bb31027f7b2af12fe5feec7eeb06843d8296ec5682262a07dae747ed7bc821ec17018d899fd167b36a7e3773b427499d99dc583bbe4b429afa6a26593953f943e4673bdd0d2a844256131603cd0903256f334d4f8ec82de115b6ca5338c75c8baa44b4ba963c7c78510d8de9b2a5852f42f3463c685fb3a6da61a8e0892662d6a250fcaa6fef74d450fc457b9871d08bb5be3011294ac888fce215d535c3b1a43bb47efe3ad25da159191aed55195469c59093ffb24f65d60c4020bfbe647ff5db7ab8a01d5e487b0b1b64ef25da156db142e6ad872a4dc1ee9ba668465265379e
+SIG: e8f51be73fc4e0235aa153a2e1b354e9c5d2d33a11ae0e333478de1d8e6c4456d2e250824c3246ca0e8d6ae3e16677a97344144108c13b959e1daf51cf0fe501
+
+TST: 420
+SK: 193f3c630f0c855b529f34a44e944970f4a6972e6c3859359c2e0c8762ba9eaf
+PK: 3256f2c82e7c801201210140569faf18507e60338c2cc4118bb1ce605b0ebe61
+MSG: 98623f651698085bde02762e8c3321f14da1619b5c3f7c1a568e8c26ff0c62fdcc412475912eb8e8c4b0d30918b8ffeef3509315e58da359cdc2f26bebfb5703953be16b8f3beb1e54a1abee0aebe24e64dbe873402e156f37dfc168eaf8a114ce08a6795d3f64f5151e9a8b8275cc7b49a6b8d8a66b6d4b7632ef80740dc1c1b0a38d1a28f7c1b29fa44541c1aad354d4590c231dae687a2a8fed09e8c1ebbfcc38f347bf06d94577e49ad139f710ed8bb1fd07663c0320846fbb455ab837ef964ae7d4eceea45fd7bd8d509f821e6eb027494efd8dd8e992b88698eec2ebc5e03025be789c18013f201f77aa2d34f5686460e43fb489e08776f98bcde2ceeb9d4fafdffe0375604371ec32f46b81fec474382908e9d250a0ba2780a7d6df407bd2b1eb126748d72511b9b069eb1cd44270f29fe84b9a717751831d04c2818e408f22789376c61c2ca45e32e788ead3a7536bf09da8af4703902f5516a020d89263e93701a2565eef1270418925f35a288e327bab628ac2f0248cfbca3482e265d1621cc343c31f65493f064bad0d7602460715fa486f29426346af53e333b75f5905
+SIG: b12510ac5f2f6d33360cddc67291d6c270fd9ee62dc086b38d932d26473fe9a24efbd4248867ea7e915a30c5bfb3b8b19aa01aa2febf0dac6cfd6638a2ba7e0c
+
+TST: 421
+SK: a88ad0048d38c44cebe735ea3802ca576e37121c7d4d760dfd88de1663064abb
+PK: 14dd8bb306803e5a758ed68ad21d07d88161d50f1c74713777da1209afbaea0b
+MSG: 2ce8bca26178913b1676e90ffefd945bc561982660e2a75d482ff30aaba1ba43f82d2e6b909ec10fc09789ff5cf32a5180b601ea80fadece6d7e7baeef481dc6979e2f658ae0f6d8e416b93298f7d34031bb76f716ed991a16d09a582e58ba4003ac17be8b4469e1a889b2fbb2289e98af1c6d5bbee77756713c0778b0dc446a1f6c48c4d40818ec799905f069bc95341657ca5d02b7a539a13a02cd0376a50e8343c0dc20346de5275b1dcd4ad7af725131ac75e954825d30eaa57a68bb98dfc41cafe5710556647b387d9b7fd4e47651e5138050798f6d40f4ee7120b58f74da94d73cacbfd393d1347388ee00b79b8dbfeb57814121bdda60c627dce147d4d568d79052e97b9a5f3eb5407cc46461a55e18a960d8094a5fea48b6937529cc4ec919cdbedf9185456dc00e8d98ad1537ee10a057f4eec4b81dc60392fc9188d3e561785965092e44317f2a48e36605fc583fc173b05db9dcbc7557d06487390fbbba77af3a014e1ac35139caa1c53a8d17347f178e1c54d0f52b40e91042c93e7e481d792e288fc27e4c2fcf111fe97d9e2337d2fc1c3098f06684a31d55ebf362c027
+SIG: 1341a148da4593c88ebc5a58821eef77f92186390ff633e76207084e7874ccf0eb1f9ec70a3a3f96b58934bcb061ff920124f7e580fa2b0b279583adf9232d0c
+
+TST: 422
+SK: 3f59d6a018f50a822117e5b473609e30cd64920ca1c2750dcb09eaab807a3eac
+PK: 457d0e59c11f348f3bfbdd3f327de78c0a7577c0aeef42d4c1e56700d108808b
+MSG: 7d103a6c6ba2d09087eef2254c1c903f067695a54c4515e4d13bc1fbfb54d6e7a167349c14809976da04a7e58d96b40aac3b2bdd14b9b50322bb11645f05e5e978bc7fbd02492ef88f87d668280fd708373207ff670fcda97df8485d5e46dc3bd04347f4d7527eab2718f7d93d132ba7758218894e75a7deabe693335ba0dc73bf26c288bfe9be8a736d75e5e0eaa7bbe8d0b77abdd5146e0fc9b30db9f07cf4bf36260a1f41410331f8b47c6b38338c6dc9e801ffe1d585f9b7fc31e9778bca3027c232c074cb18e5b72997005ffeee4bf37c8f874b1b246a6345415dacaca7075a60443ac3319236e23cf6b7544740807052114984b8d8f7e857dcc6faec8869cf96b997dfa9af9184ad623f1d90b8ca759b448eabfce18c17cfdf9a3e3312e63e5f084cea904c1c909913cc4b19d044a3720034973c7384949bd6f9ba9256f98cd394c566da83c31180109f16d10347b7e3e9dd6be3bd3c77ff1a7996a078dcf89dcdce2d1b615695f4cc9f8f4f2a08804641bca82662ce88faa53145b6a45955aec8cc2af81cccb5d7c64f9ece1c9983326484a1e5ece4ce36544d63735f7776f21a20
+SIG: d7425ea194a6715c452ec4f6d6c76e6dd374d3ca7ae7a11995d02b942d4a31870dd734c12fca89a8eb0213eb139c14a87a6a33e818603b2e313023fa58737d0e
+
+TST: 423
+SK: a1212b34dbca63b7093612d05dab7b4cc8f7b676a934ad01f659851b3bb44e4e
+PK: ba2fccea9a080591be71268d7e951f250dedc00416e5f3f908db6cc571254925
+MSG: 07c37c46be3c68d05689577aa64a932b906446b29baf12f6174a6b42bbaefd1f1f373e0bccc473ddfcee1a7f21b96a6260ef0aa1f2d8b2959e71d12c953358a2774cc5e6f379a313e435ed69dfd6d4a59adee3cc7ec4bacbdbb3fee5430b73f6051a6096c60e9bc92cc8fa059fac2a93ef7007d64fbe50064964d5a0ad601175cd9caba453f9103b25485545d301f03c5f9f9478bdf9d414bf1dca3b1c1d9daa9971f9e617fbfaf5b02a7fbd5d4fb894c0975c54592b49a0fc85dd0853f30c51502d98fc1ab85a17cc58961aae9764570ba5cbdbc96dfceb8d11da53364b4025fe0b8ba8a353ad23686720169fe973432ffe291a4b11dedda0aac79a5e42620a64587d2059e787013b40ceec599208f66ed0ca6e1be9092ec27db216ee6dadfebc21705bc4a85aee577e57d239af586efeec22cf38d1cfb3cd74dd0d9a3381aa81e6a297e39b819137ad27d475e2bf54aa426dc29c4ca8176df343137a2d79d12ef9aa7be1cf6775e5d8a4430a85c33db61cd2f35187b4f6ea9ebdd753d1c4ef72471159ff07b77870906496249d4278e3f3ca6bcbf37a265b896539190f9a31f1e7b4b65cd1
+SIG: fa93ed6595bc958dc042ce1645167b79e8f6734c46f80f631fd5484908f5e51a22427ee686f564ff982f6ef4d2ca1f0ca5624910cdd63c11a3c2b16d40973c07
+
+TST: 424
+SK: d9682086fe7dda30b87111060193d847566ab94cfd9c97ab6b43e7a8d3f79382
+PK: 8b0b1372d88733ef7233f6379790d1e46e1e07e9d3fb8b0be252ed04c5fa163d
+MSG: e8814be124be3c63cc9adb03af493d442ff20d8b200b20cd249367f417f9a9d893fbbbe85a642be2701d1d1b3cd48a85cf58f159a197273143a578f42e8bcc8b6240f93271900538ffc187c0afc8dbcc492bcd679baaef3af5088434a94586f94b49970bba18f5ea0ebf0d27ee482aa83ad0dd0ee609df59d37f818b2c8d7c15f0f6f544dd4c7e7cb3a16724324f77d58948f8475a60d53e5bd510c17137c99e1cfa515af9bc85569d212a21190729f2817de8c46915e021df70ff6d60215f614fc21139904df3b292b749dc4dea02518b62d15862c92d2a4c996701cdecaed84ab628ee984fc111eecb59e48444efc0d456e2c852518441c3db7630ddd5156249a28730983838ae59ac4cc7110fd6de68101ea5b2ff69fd364e3c9448defefe175bcbe117cc11b4ff7549c33e1025b6b592048a8e31969e818dcc188bb19d7a2440a3baba4eb1b81c45679db46b31bcde7776757d9931ec2063fc6f1fcd761ecc57a7d030a85ea273ef1825b05092ab9645359a444ff7d166b575fac298308d9faa68463d1d0f7b7df8a51c6815d37159adc0b593224a818321d7219f09686cfc952259718dfc
+SIG: 1793e497eb521ca74e35d14a63868cbe9499da2f21b4eb5260340fca3c1feca78dbe5b14ac10f3fa76fa2e71e4c91461aa75977e5e70792670ef7ff0e6a28708
+
+TST: 425
+SK: b52b249a7aeae0fbd94ffcf9a9fde10de61c3f4cbda14b289fe01f82707334ca
+PK: 735163bfcfd54f9d352e1c2f3c0170c95c1842ccc7421623ae0496980cee791c
+MSG: 1d445e8ee36f6e1064ee1281e6b4a4cec50a91c2b667c8305d1e9a5f7b73a3445882581fb0c11e64f6ee92e811f9f2d6c59c6344be7691d116dda493cade51c0ce77372b61a7c4fbb633401333cbf71372ad2f044e992ac035f5879c053004f8223f237a24a409b7894f6ad518e046b8a84c3f4c6260e6169fd944d57fbcf9ba2775f2d60ed772c46ccd63c850b80d587c5208dfb1a25878c02dece3e602e9632fc3c2c79b25ab41034c6e26b869255357a686781dfe6e644beba9b627da1fcb5ec0be497cf188e1ef1af0601bf16b2911fd9ff34f0e97ac95a7fe2cf90ea6ced33ccb0ed1ef2d4160efb07c591a5cb16c70ca1694fb36f2ca19eba52be3d4ad895abcada4b36f0261d65f59e0cfd2a6148a8892ddbb45810db3bf4a9e26e92c15ea2618cfeeb462d8628f254f54d2af27113bab4f9a7d06791811942bdc32f845922d7b2ddba959140928f8c28d98b44e1d19b97fd39cc0f9a5236d349fc835ac492192462e40ac629bebffd2eba72d2788b244bb777ad0f7b7f96f23412399fc1d87a1d087ba089027eabbc05edafee43379e893291331b460bfa7332e0842ec2573393de95306
+SIG: 6f48a9f7f0fa192b66d12175a333612303e180b9fab18edabebcdf6674fdfcc53607089bf980ce35894c2f9babdc4438667ab3297a6248ec0269faa99c724807
+
+TST: 426
+SK: 782a93efe0ef06cb2534330efd0e9684e9969b5258123e490239bf24bf9f6523
+PK: 942fa1406ee2683e29377e49f7ba757cf50ef0723707d4403d2862257045de87
+MSG: 46a4e319a670ac993994a53300c3f79144c2f7fec1116eeeb3621c76ac35da79dbff6e189ca9dbfc9abbda054847b2971b02facebbe926d469eb0a860389ac744162bf6fb13b42cb9bb8c9d72607138e7800121ee0cd633ed535c7ae5f4060bbdd271c9d110abff5e060ea6ee83890b1e92a9256d7b2ba982a3114bb6deffee2696f0a2f9c21aaa5b2defa11aab7076de6e57e86f284bb67f5a49ee685921032c95b74e7e3eac723f175af082c858e0dfa01728c38fbbb4c83581f81ace6c63c6bdaac5620eb9a568e7ebb7b72b3d1a164ef524e7b9f00799ab086715976c14d0df65f7b96bf9ebcda7feeef113422001a03a7633df5e49939a121db899d9b8ac2db4fad0c30cf0b8bdbc9e9802a797c8238e46511ff24068cadcff2448cc0bff92769223348d45d6b6f2c8f1593388c0bbbf44b6ddb50b98cd7f09c730f7de4d008156cb3cde0cab3ad0a58a83954e234a0a8a04b573c9a8e9b929ed38b8b228bf55a3c6e2c6b51f682652fbb708e74640e3313e17b4694d7fdf0111f90608c1b5af422dcdecad9ddb7f50d1bf5bc6378ccaffc3201e6c787b48c443ba240d9d50ff6c0e9df7f1a5b
+SIG: 93e7405a4044510166c8ac264ce3b5ba6665d68bad458712dc93c2c390568d7402ef7d57f549b8a1042f7f69a679aa855f34f801d57d79895deb8deadb352308
+
+TST: 427
+SK: 6fe7bcf7a684423de1076fd76da783423373b381329efd6157424ec4b2655a94
+PK: 7740e91afe45324f8bb990ca2a341279ddaf232c3bb415f178b6092fba195fec
+MSG: 0baf0ad440612b4c5a136c3a42be1ca2b7c319862a44a9fd50c4ee73541c5e6457efa81825b6dd4a72194a2968688bd49e5a8f4c04dbafc2e7884c0c70c208d4e954cd1675da8e74c65c497cf9dc69424965bdcba5de52936f925f62e201f99505d3777beb3c2e08b2ec9a873e5a9c21fb4a2f3e861f3cf4d6b5dcd1c88bcd9163539ac62cd0659f4ef232c2ce57fc77f90285eb350169edc6a806ff50f61c7e0beeebecec63bfc9d3983f5bb4b261c746471fcbf2892c6108970b68db5e43c4504ddae2d0ffffa28b6759ae1128e16f66d492ad61e3722c960f88692be81a9f412890ffa346e702c867dfa259703b73f525074f3227c49cec1b645a103bd4471f33f9f1bac327d7917861d0ad91abee60222ea2a3c8cac052ae9a2cbd90855d733d5319133f9541bd0b61f0995268351e2863c1ca2ca51e3c976383f5c4c11ff410036fd51d5ac56b023ce9029c620f22557019ad9b4264ed4d71b434f4a4d17a7d5769fa1e14a69f7ae419ccf5947f8c7682697116c2405f5a1959c54b48f0872f596ed45964488ddec12bdb636d0b349e749eb66092ff4511fba59b5962cb93cc85515cc86ab0c6b2
+SIG: 9914cc50fef0935efb89b3d64e3c1c3412aed659b90166222c0d13ec1ce3a68ae6281b7efd9d4ec64b82e73e14479f03fbac8fa3abdb41ea4215c4a4d4949d09
+
+TST: 428
+SK: dda48a0d15a29eba9a76305d360e466e72d8040efe2e89c04b6461315a9b8bf4
+PK: 4f5cc36a809416b58e15d24cc57968cb573b76ad90887a8ef36cde7eca400fcc
+MSG: f5ac19b81f2111a0db0ae30d1513ed343e7f57f7f77d65b8ac7ce3a601174baed9bfa136035976f516d5a870f45db1919f1eb1cbecbe88ec32d191e9248821a7e7681fe3abec11584bdb33de1b4ca94891eb66dcb8539ac41163736ccfd69abb83814dd38cd60381318728052a25cb665471058650ccc75756dbee688ab826ecad4ad5a7db57e8f65f1b64abff82dd53334b797ac40228dd817f239d3ee804a19aeac8cfe33eb657ec9ce923d6b388914cfba2e72bfc2bc3d6f985c0d97534db958eede57b16491ffb755c1a58d78ab377faec0d311818e899260e3ebd1ccd29246fa82d0b76622b2c4bc52f549fee72a30f554f331f36d2a74d999ec10a08294f002b4361e590279c2fb1bda4312ccb24d75282ce7c061a0ca5520c74f6f6333b18c4b541cb6c51e01575ba80512ffa7ce0accd22d14027c53aba1f7437835f1114d68e3acf3ff8de94c8e4ef6d3ab312c91d02970157508f54a5816f467a214e9b1284300289e65f365a610a8ea284666cfe5518e435bccd21627501c725f0b8eb5725e0e06e0cef5db201b48ec91ebf878dd57ce8dac7334848a1bc82c18b065955e4f59be3398594dc
+SIG: ce71bc82d531d0f93b57bfdc2f7316cf404ee09af88f33bf806c7cad6b8ffa366236ba74e75c15096ddaa6e3a62a8f5eb1c8c3f6b6c94a6a349fc7c0cbfb190d
+
+TST: 429
+SK: ec57b941adf3ca13e77a780577cfd0df5b49edc85351052da34e99f8a9bf3208
+PK: 2859c071978a04b7f5407b6d22401a78efd0394bb966b9a04da6b5ef819de3fa
+MSG: d2bcbd1bc361ab32c66d72fd48a8e227dc6b8d6b150848ba715ff47dd35c8e49381bb4e2933f42cd26b75b14d9c0039282b62b8556aaa11cd691e828382be306889fc9205137b169d3bf17b7f37693fce286039f03809d7d9d98c8fde46f1101942a279c516706f50191a9112f6a24630e1a26c321e46c9ccc85b6ef942f353a642b9e7ef998c0fce2d3a75b999eeb77f31f9b0813a97e3014c3a86e2558734621a3066dae35845031e35665f1922907dbb739786a8b7658ab60276f2d921d1a51230fc74d19e80184a4f10e9e834abc9a36c429726bc055dc8c063f0eca9c61a8a970bd4bb5f424ee4d04bfc295e3bb1f34becbd9920fe2e77fcf36763f32fc9cfd5e465979c167cabf5a1244b491fc06b8946419046ba516c5b233c414ddefb6da04f2e13daff7a9a0c02a518ede57ad9521de64eddf6f49a9670f632d3f7d42425207d053604fe39d13b9f52c8bc292b0076ea42a560056df25de51ad35881d08543224d7fa5d70b8603ef23ce06339d6cd09e22a95749e50dfbd3b8ad69fd30496b984d1c0a199c8594805f38ba44631a2c59eadc6554d19f9bc98366dfdec2a121d0e4814d2cd3f5871
+SIG: 118e1462126b45b8c6803523755c56dfc4e123e4acbb66ba0ba6fe3e053da4119f5719295e0c82ac64d7c5cb1ac898df263ddfd360f3008d91018b26f6a1730a
+
+TST: 430
+SK: cbfd91d7695c1f270f69246ab3df90edb21401101ca7f8f26c6d00f4dcb7233e
+PK: 513879cf79d2f46df4b85a5c0949eb2116abf981735a303164cbd85adf20b752
+MSG: 264a933f7d0aecbac13eef644b0b53dd53a1280904100dbc1ab87b51148998f9da0b3a0a6337f5e3486c2b7e548d211259397aaa194ee4695bf98c2d5f4487699f7397e5d3a7e6d5f628fbd05497c556a50a4d05e2b712cdbc351068e42af19538901b8825310e343e1a17a1867dde0eb47ddab456d316f3521554937bf808ae4e4bc1c3c5b4756e4a165ad9e8827f5316f748cac6998ed2d2104f268407c135e62f26a922460eab6d851639a00e5f08b34765ea0244f475bbfeac183e3b5bd1aab798522798a08ec6bf2257d4692f5b03cdd0a2133de970603e3251475aad8d934af6b2bfc7a650b91bdec143f8ad254cfa506bbff28a03beb659ef5e5ddffe76e23230c4ccd46310b37dd91fa6aa68167f62a55c8a69f9ed1ec6cdb144dd81ab0bcbd62643420bcae67869f64c0b169f3cdf3c905895b7d35b6fafda25ccf23c3d10de32e7f271e300d39597da8f843722ef08364a5f7a105b9655172df7c82d7374f98264c9cdccb496f2e10fd8262fb1a9a9965b0b841ac0d0e9c1a3d9493ea7aa600205b8f900be0d7abb4d98a06583d2295c276318be28d421982dedd5bfc33b8865d94ef747d626af99
+SIG: f336137dfe6f42a6669b55f74b80b3035a040367f90656fcef0a644c52272ddc39273cd7726010ebcd8a30a05201ab70b8ff97d0288a2cb94cbc49020647390b
+
+TST: 431
+SK: 51a4197ab7686f82f6003a0c32f39d0f2e47555f4e9f8deee75bcb1bd1ef69e5
+PK: 06386df86b61f1f8f4dc45b73edaa841920968bbd131cc5ca1c5294eeed5c8ba
+MSG: 2aedb7e82f1fe4ce469ada48345d006d1b3bff40eb21867f51fce965640c409ec13ad4d52f891bd79066d6b4d944ca868d8986d242b57eccc4c4a488291b159c8de4392be4b86febaa75eac5d22d3c4f8d6bef79adb9b92b4914d5ea07c7f021e2c29f58d07be8a084100bc152d51ca897d7c131644d0895322e9440a8339e1aa390a7f4fcb51ddfb6df48aaf5676337d87ddd85b1d925e1a9c29fe0818f514ef72f747a674946476907a7ca99e9db8d209641057a7f44a317b90974bc86f9617a968a76a6b8387cf5853e608190c1a79f1e1d686e0de22db6cd9aeb8532c5c85cc90b5a018579f28e502a770a4ec675263d0dd781b4fa53c9dbf8098d57b33ae2afbaeb3e68266ad9aab7174ba68c6479883992670ccf3e5ac6a17e65e31e1fdc85e269c80935ef574f20d239568486e7d94a4f724ab7006098b24f3f61587691435c7f29ce4e5ca71b2b1874556433a358c8c5ef3c880843030c2d13d51b78c9bf1a8824e62e111844396f5af2e25c3126ef3626e26efafacf99830aa41212332f378a167233a0b42213afe36d83dc4582a79693b9d571a57712a08b8566d361ac902647afc886603e24283efb
+SIG: 2c072969ff4719212a121938b506c602995b4d02a22e6198d6e87dd6ae076225ac70bb25ef8c0ee81eb6fe953df6b1815949e8ed0506cb012e873cd36cd09b0a
+
+TST: 432
+SK: b1119c36118b7a065a195bfb8b79a5c287e09bd287c2daac5e6b01164c5d737f
+PK: 88f218ecba99e770ed214a8d01a92a10400acaf1f6eed420067e136ee2c0c670
+MSG: 8816b1eb206d5f6dcc2e4cc391d23209006de935e318152e93fc8c2cf08e26432bad9adb3203d898df0a2e7f1f83dc2f3ed3205bec8efcfd31adc1aca5755db9bd4efe54cc17073077de4a3fdd11996e84b6a052f034b41099226c9c272eae12528f16581b91b812850c207144dbff3e850cca848ec2b1dd164744d7b59337d7e3efef008162e680bd4a0899ced60b171f8cbeb48c5158df6cbfdb26240881bd58ebb8b6a079587279679cb5ad82f371b53c8013804c35596c887e436d23926f994e09d98fbb8ce2704174ef38b68262a7f1a712da0ef0dec639606814b3bdcaf253ff31c48e8a752c111bd7101031cc3d38efb0c9c7f19c59081584a0e015ee7c75b10a4c51ff543a30e52d5f94d8188c6b08e9df1e84a4e2c807170ac124a771b99465a0d38b1f1c6330403c82543582c5bb61b220de1b9e0ef69bdae26023181ba4cc077a5f0d425732ace132ae0c6ff0bb18baea83e8877afbe650fe0bd02093f00a7b5365728dcb66fbb881f592945058a5b350665af91c557a547250ad295e68b4fb72457cfb9d5ea1a7b2a39c9ab7d7ace0af5d51669cb6c2c4c07b2256d10e5ffc6b97c660006313c4eb8d
+SIG: 24ec1e54fc7e722d37551d02cf135d33f5d3ff535773e02991ee85ffd3aa29997f9c464470197fee81dce110609f870b27c18dfbcfd9320548525e93148e2205
+
+TST: 433
+SK: cbb587514e0a34ffc34cbc04f28c9b4f6465f1eb225cca19b864876daef37d7f
+PK: 6b705d4677d2d849b6744b1ebed167dbcbf645924b1ff2e6360794bdd0e09788
+MSG: bdf7d17c706796efd3489559b527b1c0584b9022c9cbda3aac5146da340d9cea69f916037cd21b3eb1104348880fd5c5b7c65ff820f7499346016951cb715d8df2b41c88cd3c66105458b7b590c21c1ae2f6ea9ddea7470f25e02027d171e0e574a2bb21642f8f9da508e21d8e7335b5ace5935299407bd1b01bdd1423133ef045234e701f55549434ade94a60be1e1406ca5c758c36799ce1703084476e484fb1740530aee84266d07adfb4cc689f3265133a59cdf992fbb9a4b12defbe241ddbf65d12b2fbddfc05af0fb8de42080775bad29c6b0459841cbb648a9a95e48d6e36ac514480a3deb4b36554d8da620808ae9d47329710d20aaa6e5d7f547d81ad30f84c0e3d239cde5b169d9ddf294832d67a8060ba329c4ef39be94ac46434dd2185931d1231f9b6df878a5af0831e0e9d8a08d08069ded6a961ef7f39fad501ffd17d6d9b7c654653c1f58fcee1a6cd803d2aef166c78ef5514a3276d6998dc7c09a3fa982e427c785aa6a9e256f7ba72d5a6ba33eb46f1f9fe9be2bfc14109f64773c00c063b4d5cb4f4f8a0beca92a9a016c4f540feea9c3a31e313bbcbc2ff5eca9967857f5f8a909a29d7f20d
+SIG: 1274d6f356eb641472b6b9e5b3ce65d2654e6cb87d3a83fb49d0f7da9c44be2b532604465f6089d680d2d94b0edd2b6b2b805c5e84c379efc059673d31007a09
+
+TST: 434
+SK: 8bde3ff61a16995ab9d539f6053219081bcaea1d458ec33684fc1c01fb565bfa
+PK: cd9d782a356e847b7a04c885a9b0907cc33ba97ad5390d4ea5fee5eb198d08b3
+MSG: a1f40ec5807e7a27069a43b1aebff583ef037028c02c859525eb8fa4c3ba95a901ff3aed78c4f87752fb795522f5bf715be7e3defac10fcf17e3fa5c54b20089a472333327252ec945718fb455e3f27ccfdef823d12d406e62a4aeba3cb9d1c61b2b17e49e200a8418f935f26eeb57602c7aa3b3a24f7e6238d3e08d2d609f2eada0332bc8cb12916cb03b0d4f9cd602002586d3e4cc7e0e0381c045ad2e1ee28298ae7fcf0c10f212808565296f158d2c32e8cb28156581af52bfc3470c3c9582138d2255e8426d648ca237d7aad2856f171638558241d8ae3f62ba92db596568edee3ec0ef370f83626aa0445af08f967863660e8fba5a41c8e8ede1c960514a14687a4a81e776ae0e8e777fb0f250d51a83b55f8c1ffdd78df3bdc97ff177afeca046c72d72af924ad0d0ab2bfc11b7f4abded51c3987a8bb94d640c8710e5fc9a4190e8a008363d7419cea17c40dea20ea5156029f3debf05241918f54af5039e2c4cf2ca2e139f60e45cc65595cdf54a67d92b6ac66fc0c5a290495ca57b07ef5750d05f57d87d0c228f7e4e15ad0ba0178730f951c697583481c66cbfcd48032544aa8d50908304bd81940308706
+SIG: 7464df0b67eb90b4b73ff082ad0d60ebfe0660dae97069b52c3727223bf70e29e48711a2bbb438f5f8d8a33bb9c48fe7b628fa8a542ff0b5ae36269d4007a505
+
+TST: 435
+SK: da59bbc523404f07646add7908294977e46645bc8a38bad2809641a23de3b15a
+PK: b22c0f21aa1c2d45f4b2e56cc9b5e02f9e31a2eaa367ecb482f874cbd8e9fe34
+MSG: 097106c3624d774dde2551e0c27e19504e6518cc86369ab26ff810969e7de24abc68b4b53f11d945d49ef078eb4f6ba6bf257ff7b608afdcb30a5c59a756fd77a6c1247f6f2a41100d99fc5206af3bcc6de1d3e4968e28fba0123f6045a1b54d693a42bdfa071b2b914b3c3c0c29b2593d07e8bdc86ca42ac555b7dcd9439df9fbd4bbec730d6327bfae4fc41ed498b4f04a0eb14cee608283aaa6e6aa46676bc88aed5d9939037aad4915661af94bb5f6e653a2cac123287073270e0b13fda1dd4871af6a92f992f539df881712fefb038540d41191123b6b3b4b6ff87ffc929a6be53c6cef02f48f2f0cf2fe64a45fd66025cc2d7ee55ebe2316c000855661165e2a5ba41afc2097957b6fe4c55221204b6fc1f317dd3ba13cac39924026bdb66be4542268875631d277f210107a33767f6d9596e25742d7a90ea791ea4bc9ee84a67fd328b80f791ede96d89663e937f0b755baa9d52bda210cee1db339ff1d3c4b000b653b9bde338049af84364e2177f80dd51e2a1672ee555d6317589f6f1d5abe6c2877358bf94b0b808ff857363fbfbe32e97337e4b8a8c221a9e75962a8dc9b5a3d7ca5f9c9b61c73c1469a72bd
+SIG: 1472459cbbae2cf21ce44a15bae9fc85dca40b8182da7d52cbf56ed538d18e03477c140a3ddd0efba43c96aa92f5f9bcdf3481286ce762a7e2bd1e779ba99b0d
+
+TST: 436
+SK: 40ea82da41fd15b06ffeb99cd616dc6bc8c1b21477ea239466088e2849bf1016
+PK: 5910e580bf412c31a87451d9ddf32b3ab713f9e4a22c590c641c14a5dfbbe0d7
+MSG: a06c4e02b83ab7e191ad818cb8187b52a8da004fe838db333c4e02548db6bdf791444642e57fdbc8594e59d7023280bbae82986f399805434bb072c8a27a2dcd5aa62f065bc58b0621fcd365f6cdbf4d57d577d91150301fa48f182f87e8dca7ce45a7d64845ff434d1bab0534ccc83aa0974e88b38fc2508cefcbbc82135b73b384c80eccb8a09e2873cc07129021d81ce129a9df65e613410af950197dbf9afc28edc4e65c3e84da40d2ef841b886bc44719a5d59db2c6dc776401c895e2b3c83783d7817bba68baff59470d6015bba8d975f0eb712f3b8902912805523aa71c90499de689d31ae44e210b8446f2484727cc491b92a8e8b199d628e1df79a28c561e5a7d882e30787d08fb2d5196ba61196309b3bf0c5824a3548c700003fe9913befe12223150012685e90720e9ec6bc4db607425aec531c4fa36086d3b9be391a3f04635a8077a447a16a6fd89afbb9a72d0d355cb0b22d562f43f59d4e37128b3e2d906c8ae23d0aa599c70d3778a076c1a39728f1d6937bd48b978740850566138d34852b63075e89a8e2280edba6f4ee8f61511e9b768e95c78d197b693b109e88818b486a9dfdb74b4c5550acdfbd5
+SIG: d298fcc9a8ecb76a98d4a71dfb01d276ab2d9670a95bab34cf1d8364516d1ebdb23903460215307125afd09c758e981a452da95c0ac2c0b958c6917e6874190d
+
+TST: 437
+SK: 28bb81a17d4584754d52818cd0f1f21baa777e695844a15122ac05344dddc027
+PK: d5f61d519944d13b84bfa7cd67cb0bea4ef2281efa461f22ade4ba882d11b252
+MSG: 92e84c7a55b0bea03e17cfb65f7085ce3f445b1542bae997de5f092a24ff243380286d137091a598f35e6dae1a1c648f5a494c819dfb240652ff908381f32d70bc513100aca16fe7220295b1c71835f16d9310a9d27a04a980ace297d5af3f7cb7c78b24997ccb41f54ecbab507eb73ea6a3ed470e49590509f5d1e6032a2605db87f4a9b9ec91602583f14e2fe1bdb900ecb8971196b55c0d433489f26be9ca157cbd56572887ba859f39674a8e0ca08f2dbb0f27073551d0b1990685178b1ae9e7885499143d9d72c8571d11e0d85bf58df94e2a74d9b6846557f9125ca0944ce5718d2cbae1672ba02b847c17a6f6b445634d2f0175a75cf6883c62e5b521c57141f218b2fb0994b372a716c4a217434beab75740b8e91c622187d03c85da001e00247312a465225f5d6af232064a427d3018700ded774b9026777a5275fc04754606c86600297bf7b71aaff8b9a746677a3662f3750e81b50166f6237000051ffa15868defdf090057722ae229964a4ea085e0dbc04ce1997722c5bb65d2b47ecb746fd83a9f6a69c81545a9b502f5e76d3130c5afcb1c9af99d918740837ce89d7cd213fef2fd062ce8850f69659e4ad327
+SIG: 9ce45a07dbd28d3f6f1b35630a3fd56f1d548f84ffb1c6ae64b21498ae38e596916e77f79905e609fb1ae0da36138a80f242122167068092cc605796c5669e06
+
+TST: 438
+SK: 24bfd4fc45d5093585678101cf563ab8011fd6430de155f2a425f0633ee3b7cd
+PK: 9cf5c5fc0ccfaeb28a08ba67707b18dc84ea0698ffbdbc169a09c28123e6c2ac
+MSG: ba54128f45be2001dbb060d5dcc47144997415d4294f6eba8dceba4f6cf2234683c4265f88032205296e9b27d68506232d57b688407648f87ceb342052bde9d0065542ff1715c942027e67482af4bc278ff71966fb3f62a2a5323cb1b4bae1e7b8fedcbc73ea05b4076421b0b4fae8bc3337416a17fe124e7ee465ebb38d8792306429d8279a1bd54c37bee8f9c85eebe3afd1f64489d4e53ac5f50657bb6ffb97120744b75d47c6226d5a9c9c264ee3e6a6ded05062ca1006669118454550010919c2633cf086950345e514af3843148e5c64352e69037dfe60d4a8eab3eb8cb54bd39af2f353d5ded2e2bc8b11c09f612e128c6efa41f6eb2c958087be34c6335a43005d11a9d3b5a529c2d1b0642f77afdd8c6b1d6fb2a9dcb65f42f4eca8ea9a054058be8613667610e3eed8d1df0739eca171954117989d1b12189ab57904aa960b0ca85541746385efa985be9d97b5a9029989a9c71498dfabdb813681f57e276b64db491b8f082a885145469a531b7f9f04ca0a2c2f8dff20ccb99c2861f54e5eafa962cc53eaf18d3d5e50d337af485f19975f05930700a8a7253f11f184130d0aee70969d96fe08f216951d9dced52388
+SIG: dc935b60fde44359af8f50ed7f919f483ce3f24e2320c55ba92f3e7617c19bfb54701903ff183b42cbedfef0875f42b12875d36a0aeec73ffd09509d92b28b0d
+
+TST: 439
+SK: 2fc2f9b2050ad7d139273e93e2a0451c7b5cce57599aa6b08d3edc5bb07590c8
+PK: ffe5a17880d718cc7988c2fd9825b03b93450ac1deb8fbd1f1bf3b8f87805954
+MSG: dc1297990cc027d56d1fee265c09bcf207a9583e6bab8d32478228e0bc305b9818154c338ceec34b04c4ade7ac61dcb09bfac8ade00d1f29de317060b8a4daf1987de409ca2c3fe4380088073ccf485e9a69516b5bbb4130f20be69b2dd6a9b465159cca1ac88b328b80c51b66af7f4c50f6228772f28734693ce4805a4163dff14b4d039811ee3fce65935444a6ea9a72d78b915c9c3b766c60b7e0329e43c9c57ede94b91525ce5a075a7297219772ef3c029649b586a95a73bbdf16d8fc20368de4ba44de1064be5826b376be31a86ca478a52efb98f1fa333157719bd6e0da80ed68d0efeafee5a13bcc3b457525258f1f7e031f7b403a461506927b1e6c7d4a0c8d84b5f3dd0eb8bdb13edc2b514a81d088eb077a52c8a831861feee8110e41a325dce206b2d67d25f90ef57e0fde709f3e5a39c04eed31e57c193b283e2da7279ee3f1eed482b3bbcd373902c1df811ac33e1de06429e8f8443f602019650bdc2ee8d7f650036a7a22b8fd88517511229c729a3269b3a3e8fc72b01b5a4b3e33f5272f3ad21629d08b1f717935e9e104add2f0f2033432bec82e2121d98c9c1a58e0daba25536a1be8e5088347f4a14e48d8e3
+SIG: 7aff162a3c0d28dff41715a974af07ecac2132fc18bc43a198fe664659050da19ae22758d52c9cbb94f1358bb02610a8a351c2116279e7245adf69675dfd360a
+
+TST: 440
+SK: 8afe33a0c08aa3487a97df9f01f05b23277df0bb7e4ce39522aec3d17816e467
+PK: d004370e6edc34b3e8818667216f5b226b0ff75a58484c8616e1a866444cab57
+MSG: 86fb741f1b9708929195031aa1645fb709a8ae323fff85e5470194452e11b7b1279194b5e2427ce23e1d749c3ddf910b017e4f2dff86dbe482c91bd994e8493f2e6824bba3bc7d7a845f217ae9760b3cd00226d9ff2616d452751a90c3d0d3c36d4ab4b2520f67288171bd3a34b2eacae8d44c1e153dda1f90bcd3595dad37713b8d340156ea90a4e135951ba7169ac175578b81e97a541ab9bfb76328798d7d631c14df2ad613e9c6e1147a0e84062ddba035859d46bade5fadd9b32b43dad483c6b8023b32391e51ef1520c68c6191326c494423080c623dc4ad0aa074748d826c29644c38986a77002f0cab9068e6c9ec73cc2e0c584b80e0bc375721f7a8fc35317a5e240e8c66092fb6305b012c70e17aeaff13386d5e28d06430ca585b0c85b274e7fcbb63e3423a982579e5a64a0262c41908e55dbe43dac1e5cc1bb7298be428720a12e3b072559ec2675d457aaf8f13252e28aad63c1513f5f239564d363c8505ffa4e50f6648c1cb82bba852bff0acb030cbe73f059dd87bbd7318c5586e708618a4f4c9f3bec3f4f07c609eebb24ba878c6bf1e4f2d0fd1450ab94e31755217786fb15182760ffbe5a267cbe998a4ff90a2
+SIG: 63a8aeac025f2dde9a73286e56c2d62dcb79a241ba0b2e2dbaca8752ed2fc8cc7ab8e6600b67645fb5e818a4e82c29180a6b2c3f58d099cb635ce52bdc157004
+
+TST: 441
+SK: 6dc7ccf329378e8131b6defcd89370301068946336b0b762ac5ea51487dbd39e
+PK: 04e90d275e79df5f2b6ef4a31505aac05a69459baf2c581b3ce3db29f0f1fc14
+MSG: 20cebbe98401ac8934c3e65a5738cb0ec0cdc75fdb09dc96312894b187c0a46d2c38f4855be3eeccdcdcc56d926a8c08ce6e748e2a858f53532e7e5fc5f7014c8c6f86310cc26efef30ae525a5157940ab535ed8e403112b08e35e2bb3dd91a9ae8f772d2aff37d8c40d2b5cc887a6f15050a0f5bcf0360c3a9d12d5918655edc3c13c86ba6f4a2fa3bfcd405ed38f871cf7dff0f75daf2c321084ee9fa81211adb105b25c2288f0f2f7f93ef656b2de190122e7a4bfd4a1bd9893a8485b509ff0bc46cc961051c1db5a12490c7e741922ccc0a665496470276f69c7b77098c1e670af6b9f851252996875eb8035a817fa9be07f2be0bbb12025e0565414c817e9421ac700373893862f24cb165f9a271a64fd2305c6672c46767f8f075be5d2d4079bfadc3956288b0215605311b5bf32f0037b7c5ad502013e82ae3419d9d8f39c545b5888f47106c94d5fd6084d26034a99f5dcbf26a84eb4ee149c62a0410d8c707b1a9b071f74ed23932585072ce6cbd33d4d54ee917916f5dfc64d26a498018438b455739345dd60ae0f4750625915cc829ab6822d6f05f6d2bda0a7bf5601e9a2ed6de960371d17e6f43709c9678ca743adfbdb45
+SIG: 04509db003a1a6ed3fbcec21ac44ec10cc06d79f2714960882170316275df80423a1c1a112d881fc24d2812526079058aa8b608bfc6b5e57632240c636d6eb00
+
+TST: 442
+SK: ccae07d2a021fe3e6ee23836a711b97b04e0a441f169607572731cb08c269488
+PK: a32265e5328a4f49cf06b467a98b9f9d5b997b85dfb7523ca6a0a1d627d32891
+MSG: a4bf8297d0dc5e4c92bd00ad5b9c09b1238b503d619116ef74260378349a9282b41f3f4676a6215e3ce6d02238480a96043b2942b3feed12620b1fa97f7703b3eb683c1601bd2f51825c450df4fd1f33b0bf9c23c03223789e06e24cf136d3b557403a66981f4b777dcfe890d2ba96da4a4742aeeddd6a611d05fc215694a5d89a5de6760b1d9415155044c049cb02291a1514faa2e77d2ae33d44585bdac6365bf481d9c97833937eab636ed65742a0d5973b24d54089b2daf084d5414765105e4eca14aaadd1053338a8470505232e4ac633345c5cdee1e4653d1d93583af11854b1d9b65fc20281838c56df1148f35ccf9bfe2f3f80ab73f5b791cbed2d920644cf0316f0cb5d3662b9120647da56afbeb47a952953bc1a37de857e4b39fd92b632b85159f46cd05b6abc2338d4632d48e9a178860de8f65d9bc23f24507b7c5629e0bdaac067c476c9c3941d86f788944d744852a61da716f95f3b04f0783a562941bcdda439590fd186b2a8ebf19a5a7e4f4a3aaab7a87a434524fbc9799c9931eb8ce4e34e99b608cac94ab7e74495668df136185f487d9fbcb6605ad725345403ec57f3f6db364a87f38fea4b4c271552e9f2e4a1be
+SIG: 0eec754105447f97d4a9cd246c7eede3fd069018f0d01a41dfabca3e90a741835ea4a9d682342267b250fc1c8c547c89632d9f689af536c7929004ded0d96f09
+
+TST: 443
+SK: db5d5f41fddd6768709747ab8239bb4f42a31d34b4fa88824d94bf78d3149264
+PK: 03858ce6b2d24079eead66ca0dfe772ecda9af4d46bc9b5edfdc286b95fe9716
+MSG: 67ee03de45c3e7030db5246ee5b51bf298bba3e4d0934937fc12d9a629604c53c070e30d611999a9cddaf2d9acda6a9f67202b352369d48260eebce0e78e4d5ae54f677521f84a7be0017fab278b2b57275efc5fa57c617186fc1ba49edfbd3308634878d864f2da1583ca8d56ce9fae77c462039abc32d0539c0a60b7bbba5029e9329d275683d9c4ce77d0b908ade98b0e32b4420d9aee2cc10e4be922f9572582dd8967141c1d402e215f20aee0a890e2368e406dea11bd11177f2e038aa2f1a0dff51a128d955d5e5f8d5d0009aaa82440a96864d6c697f910d1df230f467f0e02a2e02bf9e45da95f255410cc5aab8d85f449a5de99aabd44fd763ec14629f3dbab1a247bffb7174648e43b9fb1eb0df5e4109b7a88e05512b20865bad39f9ea79d52f5188e7ca5194405bfb1a09727617f3f6c88192008edbc0c6585dbf261f149dffb593d42716e5a5777f5462beeb1e9a56a2c76e6cb735117cc1183a38d1e00b303d174aa9cf5c731b2c70edd79cc5dc96f4018f1d71d7198bbb7d134cd2ff8c15f9a04280db26a8fa9997eb86b133c022eda15d8ad5e77cc9f62615960bac2f9bbc3ebbd198f72c572b97156fa7fa229a98014e170
+SIG: 5b3d0da7102355486be4d69cfd65886c9d9c8738b293cafb23b2104bfdac8d7d01298eeb18fde3ded6491d41b419cc663752c4e67dbe8986833d20e4ef34180b
+
+TST: 444
+SK: 7f048dfcc2650cda59491d4ce2b2533aecc89cc4b336885194b7ad917db5cd14
+PK: 08001b5d40958bcb270beea9baba3387e3a4b900fc42275657c6c691a2e264f2
+MSG: 917519cdb33519680bcae04faa790771ce7d1397c345f1b03dd7625776f3f195809932618b1c64acd93ad000ead09654a33d14f748b46b67aae0ff12df3cc163280f47cedc16a8579034e49884296772ecbdbb71ca29c166233533c8de54012b412ca13cc258f7c5465d83422f524e4c05f806313478319fd143cf5088e69837697d3615d80a7fa7e7443fca65e753ac1b11d8eff3476636ae02d7a20f4b2388dad684002f5ce957caddd2053d0ed533132a81ca19bb080bd43be932028cb5f6b964f008b5b1c1c5993bc9b5485b22bbef701f0a26a3e675ea31122bbae91d864b54d895afdc79ca58d4fe449213353b149f3143b5144d747c5b4697479ae68528485384044aa2c99ba4b17b184e94982269bde2de0b17705d0bfc46d6906a90edefe89195de6bb8f3fb6a374186c7cd086d13d1b3525a3994dc8020e1a00554ac8a82d6047c5bff5e7f12450f4865da161e1a021fd9be8bd33a32bb54a4ddf874512e74b5cfd3fc3cd9ac11edd878433668e3fcc782b97b6d905adb0ebec42c9254ac90f35822c00f97ff3f0c7c39ed3c7cb3920f5608bb45838bb242a52a8637d7cecdcf489fa183b45451c6c9fcbbbf914f5f7e6b223bcb4675
+SIG: 583370971d24652ad213c42615911938fa9aa3d9b7196940e6eb08151200c7b6729d1eff8f4f0904074dab3ddda6af1e4e562b7d6220c1a562683beab268f80e
+
+TST: 445
+SK: 9feb3df88c494a99849c6fca194201477a2fa7564e29fb06cb44c1154e8cea3a
+PK: c35628ca6ee28ec1c239ddc5bba2a9e09e4846816b143c74dfa2aec1f62551b6
+MSG: 95fb7581bd25ffd442c3ae38a19bea7349c7b7683ba6767e148f0afc15373f67c16d471781202e6da8054ed7fb9ee204cc0f63c210a670a5f9ced4294588196330d31b8e8392bef6b48fe3c92078fae11284b4c3ba20d937e2719de7bf67c00669ad23e61384ebdf8c6e60735428c084fe217fdb4709ccb6083fc0ae4a05273eef739023d34bb73f662dacdf110b6dbd3e74fc1491e8c96596075fae5c36aabe2a0a53052bf77c4462438063aa7bc0c50ab920c9eb288671560ca5ba7af44a53db2e2ff43ca56069ea5517cb214e76faa53dbda100003c4f6175414041be74de22ce155d2281b6f4035be39841afdb96dd89aa808e6865bae62d6bedd919d3e86510b9fa5fedd1977c4131b2b86e0f48d7215eb13d5498ca5d2368f81895ed855a527124657ec9539efe3b2499a3b0b338262f26340e22554c79f4fad2b4e419c70bc1a2107d206456b6368781be4b5e2c54da42d336040fb7ba49c32d752321adcd92986e78bedb226ceac50292089bb579027f702217745afe06a5be136b3998a3604c9ff2acd6fa3f3f71633d3102fbf03047c5486f84c4dc2447d863796383d55f08c981fd4dd7dc1cb72b8ba4435af6abdd74e6f6e6798f1ae2
+SIG: a1c2607835bec1a1d87872fd8ee488d0ae9ed23d49fd6786fc4996725e49b3262118babb4834877c7f78fbeac02df40ab091b8b420dc9951381e3bcda0670502
+
+TST: 446
+SK: bff68955dd6ae0e8ba85ab0d0cdaf04a9f5befd5ef6014f49994a78363dc17f7
+PK: 0ad9493af80b15f07a521ccd674fe9e5212a4a28c17c74f6605ffef78a4aed72
+MSG: d8f5650aa3581c4d39bd1b8afc96c1ad7c4bf723426f9d7fabd1a5c8ac1d2fe54a971fac765e05af6e407d7269bab661b3432292a484f952c11095bbd20a15d77c41f8f3731a504d518ee10cd006c96ee57372de5bea348ec8ba159162170c63e970f1c7a3465a3d592e1d56c6540fbdb60228e340909646320c95f25698cd4896bdff58e2561e3b3d9a73b89747912a1cf467d63e41455fda77477f46fe6937bb0e79d92ccd52e82dba908a05a57c7ecf49554ab44c0b718e3bdd5fc0bf7070d9c58f860591c18bca8b3a9a148a06548e0f01602b1e6f686037c94ff732e155d52d5b0b44703b3d11163e3f56e3b9c1b86476e4dcbfc53fa05984e8c75dd21843cf96f9e494abbae7184aa42736633e3811aeff402b2fcb7d7f702e447241e22a58842fd6d0c03d33ff5b8c792200e173daa7b217e4b2f4433e6c020acce501b9323aa0241144434b08e9d2469139ff67342208900546200fd971a65dbd6db6c21e3ef9172abba1ea9ea2a249addf1a1eaa3ce11938b13e30913cd0dad491fcbb3285ea378b8ef9227f3fa80b586ecfeae137066f8448acdfb78d6d3e9ef4a6b362df4241ad9ae253b8e1597d656e000cea447a02fa4933328609bba0
+SIG: 9319eef740633ada1af0e137644c61fb3e11ba4b01d3c6f25392dc9367872a23be56310d312efcb91bdbab78a75e576ebe9081972415f562db41baf5e2338b07
+
+TST: 447
+SK: 1ba919c066bb56e640c3335968e1d1b5bcc093383e2d7cf8b5fff5c61ec47a77
+PK: 804c90bdc2b3618b01f075e041fa971b83c5b6cfa3b6b3974f3fa43599beacab
+MSG: 87c5c75d8ad07d52acd781d1bb95f78c70e21c2dd66f7aa44234152f98234d128358a8aee98ea903a77b441db1447ae6ff3432ddd4570f7f58036122c1fdcc93cb21573739c19ccaa411508e08de2606f3d8f2db89df6a44a46133d57018462627e22f57ef36d1de024de3d4ae41b752df4821155934b447b2effe512487521be0356832a74ce0e2d8301b79f93175e8b6b961b1df637d8acadc884543c6864f8025ececec7c6e4fe0fecfc40dcd95e8d6ab93ce25595384436b598b73c74b03d49ed5002c0f858cfd9d0df61ede937cc41659d6708b96fc5aaadee109e2a68846baf2c246dfcf3d27c28bd1371e35fc9412631442ee75f38c6e4958070a74f6e6a220f75c7280eab4737d97e37882f3624811675f16caf60cb944bce92e75884c56483c61f26b6371b1b51237621a06543eb4abea7becc4fc31dbb5475b3deb9bb3c8992387104830c6072afe1af244bf681a40329c9b37772b09c5e88e78f7dffbc04549ffa13b4144ddfa538fc4b3300540ad830215e25f11446d289f33122c2c880de3da71c453d7e88f7ca4ea3d1255e82f4bc9e5533dc401c33040e16940b2cf9cf21feaca1c2c6c33337cf75e1884b483bf801536d304089115a0
+SIG: 503eb7ed6de1b776c952f255bbd4bcfb0e48bc70c2cc2f1f72bf6881479040c47524ec542ae13f6005ca5016b58b736a50898dd0569d4d38ad298630d68adb0b
+
+TST: 448
+SK: 9b36247c17710e95261a7d702f57fe81f2971117a50c87920193b386d494ca97
+PK: 29ae39f273e35fb3f611da091600650efbc4fc4d1e7b4c76aced5a83f82634f3
+MSG: e8d9d53ba27e98edd55df3c6b245eacddc8a40e3efb007bc918ec5a869178a170bb4a635b7f8f742e37ad45d14a74344a6b522830a522106eb960daf192dc1e0fd70f16160e122516892d0e2abd0d4ae0f0d2e5adcc99ad55302e251b3e7a4d0cb33774a497049905c33de1fbbc1ad2b6c645295fe416b4d12b232efe0a33cd2ad8732eba1c3cb0eaeb0b2a57fa03ec567ca29210bf6ff9542a766f496fe68058aa983806cbe7ab10a47920bac8248818e54a41551c9a0959e8994cac60fc868ad48b5a24d5f24a7a5a3fd90b847e817ad3dd5d0d6f8de2d204f642483bd53585a92ef925415a9b38fbbf07fc0f35e707569cf488b205453ce5433eba6fde8781af72b52bfbcab85ead385d9d3175e21ad3373ad535cf0e357ed6b5383ef3829a9d5095b87dc9aadbe0ca7abadf33ec3b6ffd6eb94afdcc12e8d66a6fc05acf97368db0f69565dcd8fef4d1e49d7dd4ac053c218f5240c812d4ebba440dc54cacddb1c39329e5bd0c3c80dc3259a80f059f94679aa0794ca0115cc62af25e124cb8a9d4160eace6d22c7b1c44544f81142a19ebb02a9bda6429c50e783db4a07f0219e857c8d3c5655a582831c8eabc3f19b59ad8d2c714adeaf4039d5cf70
+SIG: 035970a672e93f87eb42cc396f6ea7e1b3dd5c5951572826d1075a15c2d7e454df195b51aae8dc61ef7ab895485f64e5989573d98a062e67ae7356fe5c9e3b0f
+
+TST: 449
+SK: 6fede7396c462033189acd23d2f9d02b68898d35f3a01a798fc24d488de93a78
+PK: b34062060b2c20076a98fea939b3b3a50451a5f49f8351c0ad7591dbbebb130f
+MSG: 5abcc14b9d8578de08321de0d415e3d40e9de31e1888137475ce62bc6fbee8fdd03b9d47c7b88bbceb804444490bf6a3ccb7a273261e24004ea67cefa3d5d173576d01e38f76c1e0e515083c97e79914acf2be4160ef9360bbe986b36e9ff93346b0e70691d934e47f8a503fa933ab2a50426947cda8e810c9ebe3b36982f09aee6092739fa2358b613c7f129db0dcbe368bee52f2f7f1dfe3d2434605b5afcf256071717d924fd0803bbd0dd1f9555ce834dac781df4cc7aa19e7f11da9fb99cb9e6b9e1e6fb4f7e8dcb2236c28aeb6cbc55a130e03c1b17a991cca1b794e6c13732d5b0a66f6eba860ecb98555aa4c218d112b116bce238295de142741f687be0b2487f58ffc5c12a0a519f1e23793242ef857ed398a20699d4351453fc2f092762abde34f4da2dbe0ce2aabaf6bc4c0159f3fe1aea16a036f7eaecd629538f3e0eed83c9a4dc1abc238f90daaf489fd61b34d937b6f4607a788baa82061943dbab26c1d384d8d49f99348800bf361f871f5d6cda18f689918cec31ad158f1863d13ffac5405c162c32de06e32994cc4106f95bb4fffdbefe7d629ec7797394609fdbfeadb46927370a11fb38471540f951b93c6eb238668dc006c21660ba2
+SIG: 88a83e2012d209ca03b8ebf6de5bb7ef4ccb5e3df5cac78954aa694930e4de82544ef5083c4892db9f05d77bf63f4fdfce15a4d1c3f85bae8077062bec0e7b07
+
+TST: 450
+SK: d559580134ab050aca446ea7750ef6b371d92d7645ec7635fe7851100bc4e51e
+PK: de5020cd21a8b32339decbedff24664d9580326327aedf09c5ec6b3fe5405226
+MSG: 6842e3190a110eee96c507d4bcb4c548c3a0ed7b1a8ed77dd93b38613b23c73e830b205e62651921ad8296b08d1e1008ad78f2996e3c7f38032e467cffecd77b8525e243cec021f85296afd545d7be1a62568bb0cfcdb90d614ed798bfb7efc655326816a61082251df01613aac88efcea1e0ea2961b8f921ebe1558dee83374a0113a78c55857ce2055bb2c48badbd3d8f4cb19734d00d0604b619073020d72a99a1923e6160a09946567fd4bda66442ef5a7360786d178dae44922f350ce2edc6af73d1bd80dc03ec3ca7005f4109d10c6d4f7d8fa61735110f8dbaedf91a0bad7d7fb5c04d706373c15c645063ff4b4fbd2d559b0afad432d4c496cd8abfea286fa675dc076726ec522b3a3c2f47aecc539f48a792169c4cc8cd41cd2cb6b63ddbc19373ac9691c2bc2f78f22603d5513715a16d4574e7acc4bea6dcd8ca7f19865a49d3664a210dfad290774b10b7188f255b3be4dc8fa86f8da3f73a4e7c929951df30fe66a17c8cee23e4f2ed2063f0b02ab40372cbe54b9a708df7c48a06566d39b19434c6c766987b3ebb00675f44c4b3c1e9f4504e7a9270589c0d0f4cb734235a58ef074cf9decf3601aeeca9f1d8e356cb2db5fce79cbc36143f34b
+SIG: 6fcb1ac9290ab767d59b598c9a24ecdb6c05bb023ec36014a40d908ef0dc378a4528b3760d889a79174e21cae35df45d427ba6ea812bddca16e35a69b5e79f0a
+
+TST: 451
+SK: 9d4ce975547876636fea25437c2880c9aa8ee6b270d1b2da197c8d7f95e7dccc
+PK: bde4993c030477c35890aae82bb5087e914e64b94ffc64e2d7a5a7c919e2d902
+MSG: ea0fa32a4a288811301b9ee533fa351fdfbf6bc1d0555a7402767a3a9198558f74bba7031857995b9f326226f1dd5df107b06342203eb8d40c5f1dc95b4f3f88975aa24af8769e2670c46671bebb7a0f1b7568729aee477e8988af9c749f3202708171fd94b337ae67ed21a6c44174014b0b0eb5ba71c277978d488c24c4a7841309846b4e30a4fbbcfc45078d7e14014114b1ac64f7c33c9ac25ea5626c2c819fbaa2a4de8a2bf5f1365d6b70407e8094f99197ce1f0c35e11a98fbe372414ea2064a3a12d1cd5c8df8fc0e79f5b770b58f477f91976ca0139895120e246baab5a026f2d39c687dc0788334b5c626d52cdebe05eaf30864b413eebdc5581ef00d439276e52f479c9c05b116395826b60490b3ce700cc0027f61e46ca2f6fbc2c9de2e800806550afb06d4a08eac7a758e24582a4d6d428b433d365fc31d4444607afb64f15e370794005a3a2244e666d5d4c38ad2009c769a51cdbf738d235942f412d07feeb73b3657d0b0c91cb5940bad6a706e14edcdc34225b1c1f38b1abecb2adcaf819155a94fe190fd556822d559d9c470854d3a43bfb868dadd6e443d98ee87e4d8284f5cf3a6dafaf295b902836c640511e610ae7d0cb1b1d3d6079fe6
+SIG: be17444cd465a87a971df84eb102f9c7a626a7c4ff7aea51d32c81353d5dbc07393ca03db897d1ff09945c4d91d98c9d91acbdc7cc7f34144d4d69eb04d81f0c
+
+TST: 452
+SK: 0273868232f5be48592cfa05134e8d5554ed1f9a57bc7e3982a330c57e5a7f3a
+PK: f172208782db66d466cbe4f4417f6fc477b7349f2a98db56c03a47227546bc5a
+MSG: f7a1d4614cc64a3bc48f00c6276304f34d4dfd15e0617b93ccef126c5c638c9d9953aabb7df42df4e0aaa7eac96a4b38c7ba758d860c90d05e3d14e479e545f319b0e5a85ad8f0991b43d6e49c24fa060e3e5df95c98d9451ab833e12aa97f404611bba359496265a6db11917d0da5c6a702d0b102de36dd0c98df5b54806ce626bb96374475f68a6060eb350a7d2aae3204b3dfdf9f1e31be81f7170f8a1b9385413ff8f6881e10c1e8da4c88afb50639ab44887aca2abeecedf110d2958c13fd3390d1b96a762d16ce196920ce85f6c415bed545b1445302a6f001eb8d00e97c751887868d481a0b1e4dfa04b6f761086ee8e697b019e017104bafb98fca242e334c6f18f1db5b6f295f05c559361c6831dabc42c2110703f9d1f64e12ddf26a8679854e9f8ef8479e1f12c35447aac02ea7f242e58632cf2fd063fe665070445b80f3dc6a3303bba96e05fa88eec201c5c2d00ca81b8da6969d0a4dd0483b3477d325a71facd6fa2209b48cb4f6525da73c9c05b2d9789b01448e1527e56a09a9bc6136d9837243c2077b925bbb933f8fb1daac963398c5802aeda3bbca8ae3b8f4a9a871f7ea8e2c0ce898c566217b5c06ff55ff9f4fe78398ae7973641eafb521
+SIG: 15e8d8dc7d5d25359d6a10d04ee41918a9c9df4c87be269fa832434d5301db022481bfa395a3e3466f9554ceee0532a8183a0d0550e7d1abe99fc694c6ff9301
+
+TST: 453
+SK: 336a83b55abf4c02e25e540329b5275843c2ecb8df69395b5a5e241bd0d8c10d
+PK: dd60569844570c9f0a82643f446478b5ac6fc542214231a7ca656a92b5fdaa54
+MSG: 9afee8ab482010e29264b406d9b49453d1ce6d550939072182863e4665284ab05d86258e0623b18754c4785238f697f075adfb9e1d31a42e85934ec071ddddecc2e6c2f61334a79526788b4952190716906dde17fba556eea4c8b59727514f6f5615a19ca36da358fae6a6c54f7f4b7a929e31ba7cc71bde7882fa9ffd87300136409caf3ca64eefea616aed58da5dfbf28b668ec1cccffcef6e2e14f8109e9cbf76cfa414f91ac00f48e93eada385dd3d5c16e1a39ea3dd55c761fca361b428f516c05e694fe5c3c345cd94457187a8e604b200a1a0f937ae89f4d6b5421dffcf7ca15f2e2c25378a4113233f7613f4570aa4b909a9135eae4c7b9ead458007ae17126a11d145258af9563db2f7e8925431878b0eeca8affc01ac5913bf5bac4fa3a857c54cc8906d6af77de6b9326b6506151099e87e99b1e819c6fbe082688f34b803d588e416d853169765d62f7e0bdf72c5cd66669a0335562336735e7efb734a2fada327f858bec602d0da08eba4479e7f6dc4def6e4ebdbb730ee91a33445cadc9df52c825ad36149cefbc51ab102033530814bafa7e87961b06367ff896f08ae334a9b1aad703da686706c11a04943ea75e12992dcf6106e372077cd0311029f
+SIG: d263f56d59cb9b2896a947267c2ed78a945bac5abdbf3c14dc3ad092b2308cb9315c464942a0a20b2024511d766e85c936499a149cd0bbb209150a1643265200
+
+TST: 454
+SK: 88409172618b490393db27d960171cbc187eaf4dd8b320b3d2f824980043718f
+PK: ce2e7c5839ef5632a123dc373dc14b1f0505766e9675407604ca7cf54e8d44b2
+MSG: fb3e82f11bc286267e123817ad8864e077d9f7a8e7a163ac7eeaf93d55dd111de8083b66b53ce7bc771fc5071a2d7ac2f85d6fc6adcfcec446e16aa1046df37209ad7a29cf9665b439a54d6f8d942f89bdaa56f2f11260cc95993038b0e8fbdb3214f142e6c90b61a1d2b142076206af30ac35784a6dc15a1e79251a8c7731a1c53978038f8d76d70c6c1cdf529fbdb84d1507dcffdd42873dfa6a8fe6bd6f7fd29c80e4b2f933d2b6c9e62c9457e665472655059b63b618e2a9a8e5b9e41c3646173a892b8e6d4bcad6a62a6fccd3455890b58ec2681a95cc9776a9fce83c54a9ef312a331959c7ef3f79ee576eb7b79469c9234b1eaef609884708fe4bb0efac662da871ba61ddabb3fcbdeb8f635657dd9a5d7311e639a824858b9a9868d3f9384da612c7f2e771a46bd2624c99ea2b6ccbca996c1d9c375554f2a551619ce6d5e6e4d6b844a4dbea83ba732331fcf46572c1fb0e257ce1041b265df02e690a92814bbf3b5ecac69ee998766a02b0d2f908b3c15f952699616f2c07d589198989e6056c16319aab6cf8771902c078046a88b2570c13bc5edeba2ed1e3ba131daf94e6891862bb3de7d1063fe405307a5cd975693e9d58e17c690eeef4a2603cafc68c2b
+SIG: 93b6e29d63945d5c427387d006c7f0b01956a95fc0436ed42b46d0f17b5bb193ea8c0ebbf3d6d13bb539e35c91f3f0f9fa3414a0223c9060bac83653c6fcd906
+
+TST: 455
+SK: e571189b5cd9e788302de3919d850c227dcbb615022e568bdaeb37ac5b2939c5
+PK: edda890f42dd5fbc7316a5fadfbec38556f23f51b8efd2625437f6b5069f1ee5
+MSG: b62c867ad6227435bfa6dab830684e38d196e1f861aade0fd6a7699b6d60901fefb2d799c35c6f3d8bb94deee834403981866bab84946ae9476c75e9f1d3602b42cb2db437bff33a775822f0d6a257d4b75400eba5b8abb314b71fc6b46f8a34e861a9a62abf33de8482f63f9d7169e773a2dcebee03705dac117fd1499b68e7414f51ff9437f253a1d9901ec3b0bba86965a19383655487b58010f804909de1ffb2212c0252ddd9bf2a56ac46bd59c0c34dd59e46598b6babd4e5f3fffde55e48dab0398c22af9e26baddf77275e5f017b35a9b8f8435f9631936b391cb95d7adf35d1d8545a0fd066412d508967bbe9a20245a269e3be2777117e75fbac170dba352be69b254d353b3b2cb3b7e21b721aa9fe044f8916b4b2a6f8c28f8abe66ac92b91323ac73afd93dfbeeaeef26d19bd9f67e99d48cd2ad2d3e55e45d24d54b50f44a39b90e242ebe9b42bebdb230c470bdfde1bc7721c3120008477393dcc2e15fd22b251feb0e18b02883c078aee4fb760655a671dc7b8aadb9a562420a3c2efa2d342e1e0099d951b42242984f594e6914fe282b1ee128735984ef93a669e6ecba26c9fcb9f09f09256645617f1392d35908917cb8d29e0897c7503cddd5de1959686
+SIG: 7f797a31715d7c356f8f1f783700aa9974bb936d661661ad968c7cde1ac9e767be56a2dd49b9230e90110c67c0ed187cb7e75c3053ece844984d296f0d85cb07
+
+TST: 456
+SK: 371744ab63c115613929a343709bb019b7357dff72d2a149f1d0f71d3a201efe
+PK: e58abfad4a13859f0acb05d0e47d59638f7b1b4936100b988d61e6e70e22667d
+MSG: c219de1e8d7ad8df08c49377396fe7c1f2d57bd2170633a00d708faadee180ceba92849a7778506cbb366875bf9124701894cecdb3385147d0671843922a649aff7c435eb5a9c74927503072d0067978716dc80be1545a2dbf5a1c38536e12bd7720c1965d3803a4e8aa55765192a13b705ca1059ded0e806362fc5bbe6c76a1c9674bb853790f7e90af00753e00436da48cd082ead64fddb689890162082f8482924f33acd604640f69927352b43f64402d27a883fa6b72aa70d241dffaa1701a25cf1079358260793875f76a2978e9f9f9d68634eb3f5f01bde1ce49e5921252f949f082795e4eafed7be5b49a9f95edbb4a13532e3f3b3be62e2652231253a20c1d5477e8f4bc57ed76fa19eaf03a11bba429b6496ce76246170e043bc14f2d2f703d968f1deb09388715c37cb4752da8d464e348e0313c8993e24133a7c545284e3c9c907d01b260c4883f9cb3e3dc5b6f7fb6d75536365f2132eaeddab570e7273afac0bff5c9fc0b820f2078e0336052e1fe7bdec86674d0998ec78da1c3f34751f886727695f35eca1304b14734766ab05c1186306ded9db3eef65d3c0456cdae8181afee04b296c6722a88c7ef3088d26f7fe74bc89cf5285c688f027b7e68600486af
+SIG: 5eae4ac72af0174ab256527b7cd337a0e5482e615af068db21dae35a64640742604df73fd4ca02ed9515a5608d73195230fadca7b426f02a2fbfd02061af3600
+
+TST: 457
+SK: 498b6ee6492d53231b3532d193578ba75d6a894e2e530034e21ab8ad8d2c0d1f
+PK: d124665b28facd2d17946a04dfe3d129a4561a2b24eb326d84b62b422e44dbcf
+MSG: 0498a59b87cdae28695547e10863bce804d97de0ac8008f3d5fb652c1757419fdc9e0f9736f4c59a34f21cfc74599fa788fcc10c6730c7df8c3d2c1b6a786d1230b65585719d1cb5c490359b94435d6dd671f54d6e9a19b9b5aaad7e0f233f8797df997828d88cd92ef089ef7dbf1e95277894a2f7c2fd0c8e4dfdfa6d3d14589ff01916dbf9ddd811c2f5e01e94298990a145a6cfc26895614c7c963fef308a4e3856c32dd3e359bc56d2cca496ad199ff1a568d6430ac5cd208e0e2d07803ca523e0d813ad3733ab50bdcadcb988aee758ea50439bf38ee649997604f151c602c82900a8205d8f6f670c8684bf5abb5f75ff29a37eb9bf8105199fbbfb4707e162e64c715270f853e648b0aa26fea0f6db562896bf424a9ffcb292fae85b76cefb8bd5a4b3ce1fb39bd2a50d0c9e6d933e167ff629b8a494f2a9b774eb303c781ea02aff1a8afadc2465cc616968015ed6a5a33c3120b945ed5351981e32fb9fb96b2212dcf8fe9ac56e3cf41dc524f800631020b025919178ce074eef078d6842012a276efa628db54058d1eb5b5b705f1e1818d2df5164baabb0c61956ecdb8c706e562fc4fd64052870530ae425b221f89dd6f90dab882e763e7a7ffa141bbaa8bf7a3f21b0
+SIG: 112f5c6d3bcb3dd99346d32ad69cbfac3e653bef29c68a33f43231f66cea1d0a195427d6e10c0e77c5d55fe2794287ee32e5e22bafbbd8052ad3606b90f94505
+
+TST: 458
+SK: cefcfcd1cff4d8910749279131830b1da19dfc5245f78ca68b8c3c1b622b4551
+PK: 1d394abd1b4ed1aedf966a60efd3ff882140a7e56b428374ecb443289a9c7f00
+MSG: 5ec94ed06fc1257ae9c183ce56271207aca37a23fdb4b0e74ac9307a1bb112e05ed5a5d047c93109e2e59477b03378346422de36714c2961bb9736a513ca3671c603a68c2be7317b1b52a076dae2aff7bc88cd5eea0aa268faaadae539c938bb4fd4b6069b1945eb6af0c9e6c8aa5ee4a4af37e90c67e248e8d27bd7f9589c4d30e905651baf45364fa049957ea5d9b7146ca68204e5e973d0f1c91a1c4bded66115028a71114f0f4f851bd115faeb954e3f71a01470b2481a0098d99f9d74898c8ba0287cc7834155214173d1fcbafcfe9b08250384439476055883833816c9524cfd5744aaa259db7ebd3a6aa20b5a6546dadefd140668eb0eccb5f668db9fc62983df980850c9d19882a17550d5dca3542cd36003a0d03cffb04575a3e8e1d07015c7b30eca9115cd2b72e46dfddf6a4dda1faa2dbdc89000d433f6ec9adc46146d939f32121b99b28983d98b9dde8c3f6e5779f2b0700cb023db13de656e0aed1da2d5c6ba2652343648ad420f6ab9e55a97482a1a22b3bc2ee598629abad9547edb5ff790990564bd871f81b24b12f2bf8dbdfe7a88375fad9ccbd9fc0ba1d3bba5e3c4813c18a0348aad83fb1b82689054d99b4600dd1760d0dcce44757467bec1946406d530
+SIG: 7d83ff66ec79307b1c0c093fda3968a96cf6044f5c802888584018845e7caf2a135ac6f1677e84d22e458e227e4f930209919bc11b12f7aaf2b8c94302d64200
+
+TST: 459
+SK: d107cf26f527db71a206e41d17955321013225bb20f93e12df3dc7399e720ca3
+PK: 186bf453c95dc0a2fd589a78e2c80040b3f6ddf9a6f8681d146036cf2146e8fc
+MSG: 78eb9e13789928a74f360141728ede98389685c836b91fafbf1a7e8c19cfbe21bd3c3d6c6ed83c409ef693f1d735da3fa466497e19f38e30fba2a1023785459070e6e92c1cb7c9bd0c9ba61220157866c3bed2b01e6e6b9b8dd3f0c47c02f181346a0a9b9b5d3d7e18a94d6956855e16e8eaaaab71b10302f35bd8fb1f9b5847304160324926645b0582c2f2f1533a24281461514241db2850ef31c5763b2e3d4fb18fc6d8c1d7e52f7c13392c17e27019ff60008e431f1714370bc0efd9452a61f5c56488d91a185037f1f647f72fa785010d5d78f0a11587ccf66b8088e0e635fff3774193b2edeffd92d6e8a0321128ae64cdb862e631e2ee5ba0da44bbd589dc392b5a113b86a727a8ddb698a334cc668b39b1cde199b88837ca5f00f553f89c622834273641d39bc10c6a24e1eb42587542f03fc1627524ed6b749391f11028706c42364425b2caf20180e1b802c744b49b7bcd9bf7b15c23a0bf1c6965960d341554e1966b6ef82fcfbbe41d1e09d741e309254446777f13c29a67b8bdebc5f7f04d160d60e332e3d0441a0f2f7b192c3e2bdf6dadec2a424f88669806236ee04dea692bd8bb6f91ca0682ece349142575358b9b7be70600b3cb81e1456ba0799fdc01ffd68623
+SIG: 8071d97f324f10358f13ac8c61d424b4f300dd0419571c39e40d99aea5f03140e62ab4c97127ab33e98269966ae1d4557e459bf7f597b313f351a20122f0660e
+
+TST: 460
+SK: af7ea8e41c8937a4ec475ad81371a171d3d0f9fd7519a04c751ed4ad8ff8fef9
+PK: 15dfc71585bac71ef20f374987c555a3f2f07d6b9c787066c10d63cf06e02ab0
+MSG: 05f2263f0245ecb9faeb14e57aca436668308c8125df3116c4ee20501d0cde701b366e2b50a1c5edf484144ce16bfb1f7d26dc4275ea9732e264ba4d4a362b40275ba47377dbc332cb65e2f4c8853894aa878a4c175dc5b3b2a757ff3c8d7de660973b89dadf076e2e4fc76239b7bc752a229d44e000ceb667104cb0746bfcf59d69603ae7fc1bcf11d2e33f61dc497ec1b0bd5e4f1dbef435f2f291f30b00a85e833946c8b10484e4abd7d60bdbb1fe6dff5807a53bb89382153013b70ca08efc91b7e9fc5b5dbbb6af123b57be2e140fc471a45d89fa8284cc27e0a1fe771f55598bbdcf068d506dad0a592179ceca39ee9526f9e4fe47bf2bb14fb1486a677d4d7b99a520545676a0f1fa809049aa2414ae7b817d9a036e5c157886e8341d4e819c092a3b48b3606b03acb727c6c2217d0af30121546a94af6b49caa2a8c9b1786fa0c2a524ec7a023e924b5f8a89a53780c7f8781c5b8e869430caa0e6d0437967e3aed44f45c901cbcf1026fbbd4e3dd9a091ecf8b34f7dd5038e543dc7eb6ad5494efb145cf63ec0d355bb8e172f455d8a6b13dacaaddbc56e47de3cf762a1a738ef092f1436680467b5cd82e9e36e2d2b6842b3bd5dce77180ddaf0b643378e698599dd47f5cdbb
+SIG: c0f1739167274bf91831c74beb645af790459b28bb3f21325365130f409acb66df1d223759a9758e08fd7253737484e285a6fb47404abe2eba5ef249fd025c0a
+
+TST: 461
+SK: 0c57cbfcebde10ede02d1cb01df360d41f2e66a50443d58b5d4f0828c9a18bb7
+PK: c4d761ba189971b9462c61bf46a765f88e2ecaa5bf2211220afb00ac657f7ce5
+MSG: 337703243ab5b4e4d3481ee8dd1f4494507174412658a93988b5c30403a7b7ed8522ceb46fa1ee02753a874ef0675d397c575da0b08caa8cee3393784d0f0db8459837af90b9056df4e38e417f3ad2eb1a100ef207ce2ca6c610018021661e307099f2b7c4ae875991140bdd3f0f99ad2c5d55aacb84cc1cdcd579e08072b6951fd45ed289ac9ff7f0986ac88a4fbb9dc9203d9baf180c90edf937258c9d0a6d48e220f72d250c7f2c777eaa7fb9fa11d50a5798772f9fd976b00599f1f0276f3a2e4d988ae92125467a8dedb7a16f9e3a56e8d00662b3eb67a35b9b60e73bd935077ee238df8f6e833b9a5523386826c1f2917b1c3ec98e0a5fde89c48b1d446da5d0c885fef0e374bff30a997c7bafd5e743c85d0c6aaa6ef10a061211a2327c6d84eb747a56e9bf60fcd5b553b798834d0c5ccadb9d4b54e7237d12c679c193a287bb2f511cd4ee2a2d8549b44b21c11fbe5723381c6c5f784687fd90cebc5b495af9e414f2961b06a1c8433b9aa3292bcff4241c227167f8d1de054ba33ad81da3eb3ec6e40a6e26854af349540171b75d75fb9a8d12937827fd594d317b7a8d9f1c2fcabda56375568c3e9e514c2efffc3878363dcfad9fd95436b022e8772a88cb71e803bf90381962
+SIG: 8af7bbe01b8ab93951d16fca05a9c967d1c52c974bea151ea72e4cebaa20cc783bb61d8d69385cac5bc6d72dbd162beef1fcb5dd0e0a08b48ca0b9f6d9a9880c
+
+TST: 462
+SK: fe7172278364194bcfefb4783142b79f59d5fd978b1e47c314d78d4cb3f61c8a
+PK: 2e82cce47910c7e2a79bc1f419dc3c3df54f23291fc8193e8258ccd2fd38d548
+MSG: 23509451a059969f2b4bdfcee5388957e9456d1fc0cd857e4f4d3c25a4155d5ee91c2053d558062eea6827950de863bc9c3df9672cde8ba741744ebbddb45ec1f4284570fd0aacd07ea58c581be2afc95ae444e678edc2a02439f387cec982ea3a44814a8a302bb3bfe8228d58de039debdf7c2a7eddb4e71ca474f94f7e2bd89dc65b1610733c91fff89bd499f40154a6198fdf5ec7ad3722d925b292196c429499075be0c5b6da9c090c0791a7019eb5e7366be6ce58ab2f04fecd9127c42718047bf47030691521312c0877aa3f36cc5fbc9caae0fde3945d2a868ee2502a3833208eb850a163cfcbf6da9ee6ad9fe067fe241986fe4436d6ae4edc61561938e2a33f4a33db63f69d3f1a8850ed40028869164103488fb795cd82ca067fe1b4897caa49a7ca9a80f3a8151fd13bbb7ff350e8579f565dc1c4a9ca938d27b15b3f858ef45d3dd78b2c358635356315f55a97528ecfec5d11a5b721503107faa406c17034e601474b3b60cf48692e269261158fc353d4df4274381357790b7756087b00cc79e3b9d28a3f2439febf199e64a8b37c91b5a4334e3354e8faf3a361e856c54bdaa43bfdcd6ee6c9f9679588f6069950832348aacba2bfeebacaa2071ddc7d77898ef0f68793cd25
+SIG: f6c2a4296b9a3407c6d7a5679dae8666b503d1a17eacf71df493791b8ff0c0aa8eed36b327a29ab7828f46f22de868b628b1cfd501e8599fa31693b15f61080f
+
+TST: 463
+SK: a951e4e6ba9f1f0b354831c986942448faede37e11b0f247da2706dceef73ac7
+PK: 30362014974bf75c8495c2e271e713d57384384d0a5da88edeea79279c0c58ec
+MSG: 20577dcac89174885eedb062489cd512fa72863ec5438e31e95878b75ce2772aee6290a0ba3c8f642c1d0ef55da8d5bc1484f83bb9876c7a8c0b6b609b94d112a06fc83ce8d2c1e08ed6c735e57b244aad6ecf7075363d565ba47865695c8423510909e0a3db4b61ed7aa67a7471331e83a0c58b8220a6245f65661549c1a12d4c0d50c326fb94917cbd07be51e83fe8bb3e46ca01b0a260daaf1d6abe3703d6a925113bb4d57ea1a48b4c7dbdaa03eea814a4b5f02e1dfb545cc623fe17a3bb18e4373f5f7ec2fb5217d23e4fed54a772e11323e730aad7efca8c464400e7679055fcc125a876ef7b8b9de186e229a7abf191d0c56d91815f67872e957bfbc7634aac403576a58f427bdbb30e8c4b6fc6c447741024ebb503a5a9025124a4887f825a43ee940f210a1bd5ae4f6732d60f95f2b83201c4c6dfe279412d7502a5211f8f48f800db30fc3776c4ed3a38bb4634822c98a6d6dd3233be60e42cca45a3163cc84e9e8da647c0711bc4c6ccd65aa1e972c07404d103e74bcc31a7e2c3eea5ac9257ab428947ab3dd3fb153d90694a4073373c4dd9ceb131154fe877473fd996f424f33e316e4eb02b8c7513be6998e516cbba54d94cd0a435e0ffcc2c0a8ef72b630ec24781066aa5efb9
+SIG: 0278c86a15208d9be5b1e1574761861b8af72ae08d40cdcbec354e65a9c3d0a06b5fcbb297d09bef397462395986c3093eeb22644c003c3078178cdf674e990a
+
+TST: 464
+SK: 38a9b2d49ba8b82f301a5772cea0efc2218455c8b218b22cbaa2aad2d7ad3b35
+PK: 9df5ea1f78f810a521774602bbba4942f0459238966c8bcd21900afbf3d84293
+MSG: 1778167c49b3a44d4a5ba838b7388553b1e13d36ea4f86d30242e1a822a3bbaff5cea63e2ae2a4635be236fef2b8135d14fb621c0bb773c9c17753f80926eb55d0f115bd09a885d844b818c9f04489a331bb5e032b8e58cda36949c5a8d08b55bb8de965e1f90d3b9cfeecfc6ad9a4ee5cb4047e9450acdc64640166a8c069ea849aebddac1ae4afec91ddd17fa5553fa87c56f7e51ec1cd6b5cc23351d057a4ce4a8923c8ae6ac7a8afdcc0881c0e74ebb024ef7296162cb93c68e50bbb074e651ac87dac9ea59d4c3fbf0fe379f3e97a24566ecae54303bcfb6f0cc9f15f6639430e66b19a427849fdfff833df02689e9de44006c903c559183459b9f4a97f54a0f2a28df7b0e9deeda8239d7b516977f5e7d6971b4502e9885f750af8d1a6669e25e77d5f327c77c87a86e0a1872bc96a76060f5f8a0c40cc973bfc7fe6ed9bca78f884e6a2828b94d489d32a0fd337e69db83fb8789afd4e8ef54c22a78c2587468b9ae071bae3b202d3183ad5f0f8e842e5a8de85bfff49e03c8381bca7fd4278ddccaf0134fb5593a395a77a5cbd434593bc4ad0ff4b8400ec674c4ecaf1d57754be0cb2fa9a6441a9abad7b42197ad82e50827e4a4245573a8f0ef87f58228a2867f4b3b834b6635037940a
+SIG: e19e62ac539a9ca251d12d4c71055b0a3f581d19f2682e672404c78ac1f12bbefc91519276a5cbe16f520cf7a7f687a240f0329157c59f50026a58dcdc50fc08
+
+TST: 465
+SK: 9a1717873689a03c112dd6b4d76ae73b89b416a598ceec209e27961e7bb1ee8a
+PK: eecad1e0e4b863291881a8c241db9ccfffe4e55d8b5a42f307b4436acd0649a6
+MSG: e26580470901a07ab0931aa23829802ce04da59fdc2f773bc567f1e65b4f2e2d4a1a6aec1f54158adfce9b099790b503a13d22097ae23ebccf923f3bb1986d6e49111a8cf0d4eb8236bfe0d7c9e93a5efc7feb8e6a9cd1b8d921efa21e449ff49e06c1ccfea31f93e033c3c2a54ddb0f653a09fbd18a70b56315f193e7be56e5168f59563821d4bc3bbb0eaa2048286bbeee5aa3f3e7536cf2b750fd322602bb3847ceca39b75474322d76b1de80fa2eadba152d6f8f020d4d931c53f0a2801224d35deb6ec13b014873e689903607de96d9b7a743a887d2f48daf2ed2eefb202abf6082796981123b966e936dcf3483e2d24d694ecb865fbeb6969f347027fb8b175d24a4c045c0bb4ab5e02ddcbe77d4756c46d137b094473a02307a108340acad9d03bae8403af199cb75cae3162f3815813cc68bf2a5e499e594921149f3bbd214da5137e756521559dc80d9a4b74a0f4943022c7cd5fca42315e0bceeae9069615ce67a04382412313a31d67b346c329ad82e742c0a6ce0a6a02454c113e52022f3cc03fda691ebdfe14c53c8ce5ca9b932ca1a386e3eb4e90a4dc6e8ad8533b5af1aaef5003128655ca64f67fcd97c6ac803002404900bc0fae98463bcc31409f9981748789ade2d07783bc32b
+SIG: 1af8be095538965800d8eff6d723d028d65d0e9c6eb5e9d125bb3b1783f11ef7079a49a807e27ef1260be26a3b231d03b2ae151e49f6f189f15b1c83eab01c02
+
+TST: 466
+SK: 43bd924db8156008c6b3994a8130d427d514db8a613b84dfb0b8e0de6ac30676
+PK: 1b3461c269d5b0062d5df6fa654a2586f647a0684218a06e5e2f7badfb394131
+MSG: 6184e6480c42e96cc877269b16371545ff9523c45ea88e76a1348c68ae7f318b088fe4610928239185b6b55bfa0f43644c4a4c97c56ed77d08b1f4aad2f4aa069994abeca96b7bf81b8064ea4350d8a8b02297a51308b61c57c8f1873c6f97007aca3180429e730a6643f28733547bcf7b9adfe327e85736bd04af7f1d9f4fb84a7f3affdf4e22b574ecb4bc8836b10b8453aeaa5c1bf132248b826cc5230f75e075fac9f037561136e00643d08253e7ad652f702c0d15b6d7d48aa6f8e9b5f5cc146e3f156fb2522751c3710041bd922f37a50377e028b0c4e4bc3465d7c84af6a5fb427acb3b41378b102bda46d8f6f203a5ffcf395d435e93458a0b0a4c2e7782fafe119f769f67058c6677f6d10d9cf5cb8748e1805798ed233f6f930eee0e5075bc58b97af9177fda75d53708beb04dc4f19a43e768074609f14065f48fdad5077ce109bacc357174a6b7956f6e7f32e38415be526370fa58c3c0b31f51e6cd4b2cf27f8bcbc21259d9e5c3b5c2946a9fc1b00d9d15c3b7d80bfd9d05db91d249d3e42d8956682044548d83bda8d5cc9212442f30b45cf4aead80cce9b3512c39c5c737d3f8d747afbab265af5eeef8ca9362ec76e943b0a0d7a39f3db11eca14458a7b592e5e4ff2275dd48b2853
+SIG: d2a05d88d9d543d94d57ec88ae55681750f20b9be9c1e918cdaf457767f2948dd629e94f068edcf3d9927e330234badc3a02fa5ad3d9d85e948cb0b0cb3cd70a
+
+TST: 467
+SK: 8fb086206dd95a2621f598560ccb281f8273c8fc72e23611089baac89d3c3c78
+PK: 20276ef479f4d4523ab77420d424e8819c33c83779ed80c7f666e8f4403f94d7
+MSG: f02903ed4266e849a4485205954fffa8a108c323b7e3f84331043514e48556ab019497233a5a127bff3cd7c97086becef538b3f339d7d06e532dc7325e597ae357f816dea42a6a22c79d22074a2e1ad8023c424b7e096e5ad8897b05ef7d00d30a04aaf2981eddff2b347f1e27e20aabbe7e7a9544978e092b00cce420aba06187374ffbb37b4c22d75f04e57590f610a27347286c298312a6c9b1bdf24fbda8513c4f8356ccf757068ffc11bc65113783a5dde7722faf4ceb19fbb62f40702e2c6e6a8bb49ef40446450c4c59a2990944da4744f6ee770b930c246669813ce5a9f5a47dd80388981bfcc3a56b5be2c4c7e659a2e9182dec0aaafe9031aa3954d4fe7c431196a561a5b78eaba64f3db1b586c53b16f679a84921a642c260e4653a61de108ebde6f7053afa2cb3f3668ede121020dd1bace8418aebac3a5bd5142f105ac26fe49e5fb140c19b22d54a6291dfc954670247881646874defad814995519f6260e9774a8d185c37881b4f2543c4b63fbf1985016ab41c4d728cbc90b3ab876267bed41d0c0902f6b50e8fa906fc4788f7b820467306e0fe9e036a0a00f804f91c3ca718b95ff6d9e2204bc3161bf70fcc17b2964b56bc612e29402d96f50986514bc7d831d58e42793786d5806f
+SIG: a9305e001600d597d05ef671699bf09f0dcc0c44475d3ca31e7ff1bffedc0c67daa1f3b76a035948c59cd87f82453a40950a1c9703c2e7d9280e7303966da301
+
+TST: 468
+SK: afa1b846c210b52300e97696f81b8ea774d1df12e612527c55747f29c1937396
+PK: b609566bbd1947bd7afaceb14389e836227169215fab66851aa5d70d6e2e3b89
+MSG: 4cac1b1f4bd48284dcc9afc8b5955b64b436db704b0335d9755cc1f97477f8d323cb6410ef146ab8a9efb9526d8b62e3bbad1f7295f47ba9f0de958f8ec9b77ab42232437ed974856444cd22e20be35e91813bff4b016f810d0f61d89f6b614db33f34bd09985b593fe3e06e065b7bc6cd39d55c2cfbec7b6d59c0b37dd1d0d35135ab1d1b04f2f30c2f04f4ba2b36582738081cf59190f528363db944ed612931d1d514c6214f9ab92abb1833926183ac52fba2a4551e20e4c0ac959a49ddb167a381e0241d40c086e90e52aca017258975dbab2ba451ee539a718f076a58709c6697418d9c6f13e4d391368bf0e8bd8f2932dd95ceaf7aaca1241147d341a3acd08dc32905483572b89a80cc47231468ab8de359dd525a6257cf196c2ecb82fa8a78aa3a851c7c96ca25bf7ca3dcf3ca21453d0dfd3323d5a422dec84316102f684c359f226bb53779c0b9950939281ef79a58c011993eace085497afa4daf64c9687b0a11aa116cfa7b03936241a5567b646e7e42e9fb592405b8fa3c0a821fc3121b45b1753cec9a83947d211a45499bd63790b87f01472fe566d87696efedbb74ed00048c384ba7f027b3aa4298dc4110349fedf52a96cd05d08bd635771ed4510738d8f07a6021244d1903579a3ea739
+SIG: 98b0c6313cecaf7c82cbdeb3d0280641c61a060f65e563aa93ce18300a9b58272dc8680b485e8cd11cf80fdca868fab365378384a142727f2f844f87cfdf1905
+
+TST: 469
+SK: c85913a6877877131001623ccda9cdc12b9d4043b8a83793c44696632cd6421c
+PK: 9cc67c6948f7bf6e556d0849d3b8d203457a7b61549b36681d754f1dc0841e96
+MSG: 91b5009e83d0f6103399c2d3feec0084973a305bf4176ec782537560472db187a11b4dcb4b2ffb7f0644feb394b28e5bfe97247c4a4a231cf6e916bf99344ccda88a7f5d831d6de3d563dd102eaeb108c5bdce44e0632d17e6fa55b18067df2fa8d200a9869f6aff920c51d46a1ced2d903b1d9b6b075facbf91cd05eb41ad811a8ef40d9118261012c72b8979f15153dbb8561293da9f8b77c8ff14f75387536f0036d1713a72ce8c35b1062f2c6732aebf32936799b51c2cbcd6572413e7dfaab8641a02c150237381cf7a14e22c74c6c20009de7d3b7e69cd1b4584ac2c01babaf973c56b3814bb0089720e41968106cf26509d4aa546fcad5534af303ffca42b16ae6c93ee06bc3cace12e4ec718844bd30d2224cc486d106d1c456bfa165ea0120fab3df2c5ab3a523bbfa789deed44032ab0be86eb7cc09cdb7c07aa948dd5277c3df1d9d1843567dec84f9288e085b05ae4b8af2cea5d9a184d50bef85550c836613d5d3af5f9c2928e6a89660fa62719ebff773e46b77e34bc0470da4d2cdbc7071da758c4d39fe65201c88aaa8e6603d0bbe7c3e9b2d9e41b634682092f147341ad6d667f20c64e81a68d629467a54dd86e1ce12c560a6f9b64512d6f3886cbb9f37c37eb3985c8ac38dd6682f48fe1
+SIG: 01fccfdb1fb6888b0310a913170f7e366816daebe7650d72513d9506e66f7d62208a49ece0af1871497f4541ef605bde711c9e0a1205ef48f26c03dc1ad4af03
+
+TST: 470
+SK: fa1e11dc8364208d8e1cb66a361be7e84c5e368166587d4fdb06aced7f62e17c
+PK: 4d8e6f4b3415df6cedabfb295c1984fd419923c6ac41764e32d22daf372c50fc
+MSG: 294e63bacccb801bbf04c1f19d0aee16f5650a6e8eea6fe41110663ec01532bd4960a527f15eca4af2f4e6b7b0fc340cf97aa234e92cf7d69d50e4009c2496e3ed4d9aff000f9e185275b817d26a0bab69b7f7ee1ea30daec8bcee387ae46b4b299c27bdc06eea63f24dbee955a6c0969037eef91c34321e3c5c972fde993183b7d23f6e019c3e0cac7589ae4a1521af87ea42df8c22c2270ec23d6d140f9cf6d4d52fac1b9d6c8939ef8131cb62a035c5261538bcdfd6db419a55ef9fe5d7a5ac44579de700858d74a3434844f28342c565892722e27f407d7f17b74a5934be915b20c2400643235f8ab5795f324e33c50644a04033542cb3816d770fa899e7311c14301c1bd0f5aa60a2eb3165680c720e1efa8096fc25d2779275f1842b2db53b4da0ad3e59c07540c28460cec1fdd3cdb7a3478b91a9caf9ac891cdf3aeaeeca9a9656ac1307259922fca74c5cc69f7e25c6bf587973a4b7d3e3ac0635b0db22a0093a79076881c71736ee1d4d45f8ed2d29a0671a64e6ca2f7a5ef404b1edeb842034f571b699bc59e5a37df02054e8482bf1e7b77d8e8397da15d89d7355a5dce86b1683a9ac4e406c08a94a6eb00e5ae16d96722972e5c50c7bee4a84d0697bbe67ceb7ef295f06aaea5abba44466be0f67
+SIG: e857db087e28d6750bf54e53797251d8439989576c12da2d9c811a14877c3bd46c4efab861a10eebe7da04c0b0b445c7a390a50c13de36f3a3c7ae0157022c0e
+
+TST: 471
+SK: 24a914ceb499e375e5c66777c1ed2043be56549d5e502a844710364042ba9acb
+PK: 20d21ee764b1f35f94568200d63bd5828aca8c5d3e9047d23f478b925295fa2e
+MSG: 3ff9f66fa2646ec66a1bf933c2b4cc0fbf912b4d6db50534257f97d01e698d05485747de2544e9f5a4a4a075388cf4400ab89b0353ce86198202db3a903767b879a2af9daa155843111af15a2bc35efe41bcc92c8207e00113b04f1303007949ffb6ce8df4b0b34248fedf5d9cb2cee94b812ed58ece2a0ce0454cf14c20e49e09fe664d6e25762e87895932cd5cd32eb6a3abb38ee163078c133e93588791dbf6af499a31ea4453bbcc7a85e406c9848a664052f11113fbb4ffa760dee4c261e396942491119da29a33582f821d4125e0b4162f28beb066031a652d05749aa7244dd4f3d3bb15d268328d6a02fce2501815257f8ad5af4ecbe7cb8ae9661e344f9072318791f3e859091121e08aefca8982eaaf66259d9de4f46a31e716dc033d0f95d1fa936b6c6079b137dd1158d1def113018c73f8ebb9807e0f7415404ea9c78544ace7ce463cd1d1c57e31f4091bc091804cbcddad0e15a40ca91acbe1c6224ed13cafb4df2c84ac9f0c3c9b546007d9dd6e524c467072563d4ac0d700cc1bf30febb334313dae5761745ec0a5e9e8815025958f00fa2e58060d7e9a5f2b727f48699f929c8459930892573f784fef5692518b5ca268e2a73ebead6ebdeb7ec24eac92aa7dcb41b598bd6eff3632d069726291
+SIG: 3ae0cc7bca8d73be83a9b809b13338c12706aaef75c4d1a478178f9dc565514c7529e298043ea78d21a5a09dd04f10ae87441e5686a933c92c75548427ad3a03
+
+TST: 472
+SK: 5532e09b937ffd3d5f4c1d9f1ffcded26ee74d4da075264844690bd9c8613994
+PK: 5093969f377bec3e35f59efda01ab4186c5d2a36740cf022675e01096b1a3f0a
+MSG: add4d7a9ce3f63d1f946e8679065545d8c7bf0a2cc3a4c00b8f142f0945ae362c4c9462a7576a4059d57861662884bd80b96d90d279a952eda952d37d4f95cf0d70da98f4fbaca39e169f9d945d41f872397bbdd5701454303d77d31e86348271da40a1b8f1e57c36fcd803e14fa17716c5631efa01d3a795dc20b2bde36ab73ff6a2d533bc15cce22328713c3c9ccd072c3e450d7f22c0c9f94919752cbfe45ee655d1b53676593cdb448704102631caaa976952eaa1f6c2e876564e420f0c646a0f88365f76415b4085f60a338b29c51633e540f0bf32d4087e7d0fb685be88c7595dc531c99b489584560ad8234b18e39a107cf5d842dabd421e77d26ea5e0f1405ce35fe792714eb4ee1a8017648ac1ae739a33d7b1e089105d1e5add27a62ce64154570340af9eb14e7fdfc2f9a2c2fcfcdac3cc4227763f4d629497479f849216e5d90ec16dfa36b72517f7b5486baee7fda4450c352cffbbae73926c843224f8ce44b38dae53f3ead21890b52a7801075291684fd5910ed86ad33e8a007f6c3f85c16b209293740184f5890874d431cd4e0ea4087c49c3471d789c813c6dc9a78699363a1d87197d3b92c0286689311823f4df22ce8035e75732cdea7f5621f67db0e2a4ca6616193221c0aa3d6de50d85282ee
+SIG: d527ff0d4a219d61f418121206a54ae4985854a310482744486e4d130a7de97c319df8372c82828c936e6a8afd9c5de1828573d8261ae9365b8f237676182402
+
+TST: 473
+SK: eb36511009d37a9c46c4d1374d0bbd0d9981e78cee7d188c5aab983ec239e10c
+PK: b1cc212b4521bbe7b19a7693878a558440eec36205d8439d040a46a9902fbf55
+MSG: ba2466e56c1df77f22b6f0241fc7952ae9bc24756419a9446dd2b49e2cb9df594e5b6c77a95aa5fbd9dc57fec83962c7751eebb4ba218253f916a922a5139663e3203e3be482be379ca151c463d9ada21446135f356994fa5449f084478f5bb4f5ba6145c5158eb7b1c43c32ebea25e09c900f01ef91e92f88c03c76504ace9646016ffc2789559d0f3cc9d00fb61bdc6af7d3940f302e588e04f79f7b3d4b91a5d193a4f8222bfeb69bf0347d98ad81ef99d130ebc7b36b0783394eea92a38ddd5e7480d2add4e4def53eb99c449bff94e4718b09f2ea9b1f2b886594a95c33a69e0333154e440ab34b7b6c1134d8179b6f0c56251a9ad8e1b6b0f9b8a5c97081a7f8fd05d0b0affc82dbddc8b0c0ab7e833f300626d4b973b3f60feac55571e89cda0f2b441ed2faa669a70d556cb48f9b1d1cbce32ede5d166b1143e264b11ea327681cb559edd13c364bd2baf1fd54bb781807bd59c868b0e4795a779e67f0bd0d14b5a6b9e440b57a5823328b59affbd027eda7dd785079c5f02b5e32890b038730986a39a5a9834a3fed868b6f45cbdd28acb2709aff556263864f9ae1e757b3278c288dbe2932825712773e431f7c29329857fdaea798ed93920893631402e6b13bab62b4855461edb94620f2d1751865f445c466
+SIG: 9f583724de552eae82f254ac6e2ed483ec1a07346266735c490920690c1e3fb2a9e9a34194ed6473733b300d4f23c9aec0da5a2022054ca43885a15a2984320e
+
+TST: 474
+SK: 7dbc81902e4eaab3077540f559995c387403cac306d486e959c5eb59e431c0a8
+PK: e03066139082f613448bdbc27fe53aa3f88994c31ddce002e36bbb2963df3ec8
+MSG: dff798b1557b17085a0634371ded5ddf7a5acb996ef9035475e6826336f64ad8b84b882e30badec2b4a711998752f4a1574bc1f89d4325cf2b39861044dd03691e71d07768b5933a3052cc7c81d571a9de061dc19026c2f1e701f2dcf26a88d3401bc99fb81559dca76d8a31a92044a273587d622a08d1cce61c8f948a34ded1acb318881c9b49f6f37c30a65d495b02d5429e7ab4040d8bebeb78794ff736d1511031a6d67a22cdf341b980811c9d775fb19c6478f05ed98430103ea24c0f414d4cc07d860b72dc542ff22d83845a42f8ba45ca7ff3aab0b1e7de2b1094deac08d16eee01969f91bc16fec29ccc061c54db5345ba64842dacc99ee7729468d80a3f095583d8e8012408519d582cc3ff9a2eb7aebaa22db81ffc78ee90ef4ec589dcce87118dab31a6328e409ad5059a5132c82df3cefe2e4014e476f04c3a7018e45267ec5018ecd7bff1dda9267e90666b6b1417e89ddacb5085943befc7ad2f4df5f1ee0af9431aeeb6b24a5515b93dbcf68640f7daf8c961e567d7534900205c3df2184b6ac2da961c4c1d2bc49b4ea96b8154ffd4efffdc5e55a7119cb8af429e85105dffd41fe4a2ebba48168aa05fa7df27c4298735ff868f1496beb4b2ed0b8980c75ffd939ddd1a17e44a44fe3b02795339b08c8d
+SIG: 5b7f652f08f229fda1b0bd759377b3fb726c1b9c9a10ef63426d352dd0869bd54d876c3092f1cd411c3757d3c6b6ea942aa70c3aaeb4217a4c7364d18e76e50f
+
+TST: 475
+SK: 91b095c8a999e03f3ed749cd9f2faacc0076c3b477a87ab5ccd6631738767446
+PK: dad174d359daecca9c6b389ba096452ab5ca91e6383c6d042a284ece16ba97b6
+MSG: 9b0d8b00299852d68bbf497fe603961a485466a99a5484005db73d4e4bad814e8574efd54d648bd5c91ae8483c54b2f998b02e1abd6f401a25526843a5f2a23a97bd589d1f7e1ab14915b1e359a396d352c360ae6584325ae4bb7d624f61255c5c7bf0a67acab46c3b57b34534c0ee8431d260576606cbd84d8d1839e73da6fe4b0b8b78f0f958827c2f1d93ba7a346dcc75cb563dffde26f997598e8b5c2f1617c6fefc9be4b28b5401b0006413a251690d1203aaae4f6d8a3fb21f24009ab3bff13737a8a7e6646c02732d9ec5a4a510469e2d299e4cc1ad6480a482aa956f89ddcccc64a136fb15b876b6ecd88c7c86a4dfc60e666207c604167d163440ca9ab9cf87a5e0f7bbc5517de4dee876c037f8cc9d959c8ff5dbe944ff54cd91a771e29231f8b5f17d61de904c955fe2025dc52ed480fb3cc90f232459c607ef7e2adb52c7482becd67ad2149a4128f984038b58aa90176782393604aac74c18209a3d6a78630c01955a7cece5da8384da3baf63aa2ddf5963fae05ba3b81c6a03d86a00ef78edb4184fdc89b1d6bfeb310fd1b5fcce1e219524a3cfb2e972577f06b1dddeba00865dae4979000c008ad99f3b638cceb8e8c7a0f998d34d92143d81c0e1c096a925ceba65c43003ee18d494d003e9c61f77d65759
+SIG: 64ee9efdb0c2601a835f418520641e436c7dd47c333d9fc30cfbb9e390fe764530654708b40b03581899a9ac870efd766ffbb4637152f8ff277964fe35425209
+
+TST: 476
+SK: 8c568b310ace7d1f0edecefd603a884000544c792565d481c3d3e06e2d82ca96
+PK: 5fa6e267c766736841411072d1983d1900acf01d48c3ce11770b26f78da979f7
+MSG: b59f5fe9bb4ecff9289594721f2647047b0da5e0e4941bbe57c5b722b476723f0ac5970b4111f893bcaa411f28fceb4f585a2a7187018a904b70ef8fe1f6569a54d00ada37b69cb5e9c9d26c16a903518148e04a1b936a32329c94ee1a8fb6b591892c3aff00bf6e44dd0a762babe89d7060c17b90390d23bf9d360a293b8308383086916e1182b1ba4336f001b8d20deae9a029f7e85397a9ae5cf3ca10c7f3875588b8ffabb063c00ca26f580f69edc527a1accf4f41397b33766bcf6d55eb8de081a48c981d05c066617b80d8f6f5e60e59dd9b930bc4d04586403bb868df75933bdd86230e447036c175a10de9bb39953dcb1966a1f11912078e358f48c5b209a636c7f783f4d36a93ad2cc2e3244519078e99de1d5158b3961e0fc5a4f260c25f45f5e8585e601db08ba058d2909a1bf4995f4813460d369503c6873685ebcd3330a130b75f2365fb2a5a34ea63d958a2a867e90552d2cec8c390084be0c108b0fd2d83cb9284db5b842cbb5d0c3f6f1e2603c9c30c0f6a9b118e1a143a15e319fd1b607152b7cc0547497954c1f729199d0b23e53865403b0ad680e9b45369a6aa38d6685abd397f07fbca40627ecaf8d8d30133a6d9d5af009192751c9c45f77c0bc011268800bf552512730e69973c5bf362ab164894bf
+SIG: debdd8e5d3112fd77b394aa0e36e9426bac91df126fa9c317cea7c9d45957cdd96a45ae3ad760413ee1205afd71a29f9c3cb586cd2d7cd1e93bc1652fc34dc04
+
+TST: 477
+SK: 3d09afcee3c432fdfb6bdcead54e3da5b1b4165c50d6d310b7fad787b444d680
+PK: b0d9028c4d1487d293ed585a76bc94fffbafe2c65d980c494e141e4810a35cb9
+MSG: 767165caae0e578f16537e1750be7de87a789a51ff2de11838f564e2580b2391362d2868a5a4708af15d2e2db7b9be39c16adcc1200b34e6b4d4027ddffc1a2a3595e29e855ec5261b20bd55c428b01309badb59e2ca3edb967fc2f4bac0729ddf54fb6c20057bdda9e7af7cbfc092fba865fd3275b9d3bcb0c346b951d170ac9aa650a86df49855d48a1b37ce56c9f27389f5c8b15f5c2c900c4f107c064f603e4f867ef2e9c10a1b74210e6b89bb011793aa85ded43b51b749ba7f70287b6bc1b89434db8b8c8b5d73b214b41e36b528005bfbfe002e21b1006fb9d24babd72106d093e3c7093b3138aea719d69479084647498cd6c9bbb744509cd7da8dd61a627100f03c21e750acb3fcf4631d7c0f618154d2e5fa6656fb76f74c24795047bbce4579eb110643fa98e1f776ca76d7a2b7b7b8678173c773f4be7e182fd24dd76291ac67d9f26a28c5e3cb025c6813a378b383224642b4aefad0c76a6579517b8f360797dd22613ee682b179381950fb71609a5fb5494d2d57dcb00f26d1e72956f4d6672830e05c01b3779677c07ea00953c6b8f0dc204c8dbdccb381bc01b89c5c261db189ab1f54e46bc3edc4de5ad4f0eb29c0a120e437cd8f37ac67d48c7f0e730278708f02b54aee62b72952bc1c0eb437ca8bd5655437
+SIG: 89739fe441ca0ced08a6eb5796e9bdda0e74fb473528fd4907edb659aab44d3343229046716368faf88e85c1644af66ff2dcaf0b17ac93ca13819f3f241dd300
+
+TST: 478
+SK: 41c1a2df9369cdc927164aa5adf7757136abe51395604266334cc5460ad5683e
+PK: 40557834cce8e043580a4272a8804d4f926e88cb10d1df0c5e28b9b67e1b63da
+MSG: b64b14ba77d239e6f81abe060accef85f0442b650c44015efc43a0aa2ba10bf48d3018b1953ddfffbcda5bf3bbe0b6b3e4b0d9a32c6b725bbb231e0a2704471ee8bc1d594f5c54226f5dd9dfa163cfc1452c61f93e4f8139ab4ce4476f07ec933661eae91b6d500bf508ac63e4baaf1ffc8f0007d802e005f1b4fc1c88bee4d5e9e76384f5a7043bd660cce71f3b67f01f6ab844298531aac73a39d045370088855005a09c6d04238ea478dfacad1e6b22b2be4c46b0d59b1eba1f060bf7da5d1566cf1fdb5c543a33926af63f01a0db86e1a6711c473dc795ab283c8d93facfb5701fa2f2f6bb99f9b7e3749b071d58607be44a7089bcb503ec1495b5feedb399961fd3677d7493eaa3b3e9cc5e3642f40d47de9bfee7c20b0e519c4eb4a40f4da446ed6ac7aaca053e759c97dabe0a8ec2f58e7f2f9b2072762f9f794a6a4e36060b8872bd2c18d06a85c2c141a78293773ee8cfbf154b9930cd39da31b497e737a7750c90a13f5aaa147cd0dc4311f2e34941252ef198b0c1f50827e56c9f16f595aced6d2a69346531495a6499774d360766ca9be5ed8881c0db26ed7c5e6ff3a4f9b73cd8b654640dc96bf43bd426a0f28c9b25fa704d62ff0288fcceffaaebd3ea3097bcbbd778420ebc520a417730a1b5b3b8c96cda9f4e177d
+SIG: b8b2752a097196c289849d78f811d9a62fc767278f0c46628b521f62ed2759d74462a175da22403f15020445cae06da3ed61cca6203b7006362a0e198963d20e
+
+TST: 479
+SK: a00611489467122c4c164bfb6a616e6a619b9f83c4367206b85d3fbec38cd62c
+PK: 57ab58babb41dc0da0bcd506059aac9f46eca91cd35a61f1ba049a9ac227f3d9
+MSG: 34db02ed7512bf8c67d359e7203a2ea441e20e729766c15aa00fa249a3518fc29ef8905aa5b4670958c6a460d77b3a80efcb473859bbaff862223eee52fe58acfd3315f150f3c6c27ff48fca76552f98f6585b5e793308bf5976bad6ee327b4a7a313214b9ae04b9651b63cd8d9f5b3bec689e0fd000dd501770dd0e99b8f99eafa09c396a245a4a96e56896a29b24190b1ef11063f39b63ee3a586b07627dd3500c4e170b835dc0ec236fa5a35c44184707565c4a50662d8dbccfff7f9a7a68d021b4af64d532b7c3d2747418c2d717bb6aca6b58747ae4dd5641d826f79a8a315c38211a538a929e5b451f623f4fcbbcacdb86c8752ea13a617ab414ab653eb2e68d5420df7c6df92438168dcf9c066581dfe7b2c468194a23707de4659bd67eb634ff024741c5fc8698fd4dc41fe5dfc6299b7a08e6ffca37109c0210c8f94ea2d3ddc977ffc0b3794fe6ba4337c7aab434a68ac665484ea8243a84b79aa181ee6ab5aa37a32d879725edc018f8552181816d7d272ca8818a7b92e6ee4454d1f7828dd8afba1a790364b4ff28d84e028597353ebbef24837bc319e1ae8f2b0b6a851b489c3e170eef53e065f7032653cd6b46d8e57e4e111b789ba950c4230aba35e569e06615403407bce0369aaab4eafaef0cae109ac4cb838fb6c1
+SIG: c771ba0a3d3c4a7b064bd51ad05c9ff27fd326610fbfa09183039e5edf35472dded8fc2275bbcc5df1bf129860c01a2c1311da602fbaffc8b79c249c9cc95502
+
+TST: 480
+SK: de1634f3460e02898db53298d6d3821c60853adee2d7f3e8edd8b0239a48cfaf
+PK: 9dc1465b3383f37de00ea2d3c70f2c8fac815f0172029c3f579579c984a5895e
+MSG: d10c3e4de7fa2989dba87537e00593d0eed4d75ee65846dab1498b4749d64f40e34b5911c5ce3b53a7e37d2d02bb0dae38ed962a4edc86c00207bee9a8e456eccae8bdf4d87a76746014201af6caffe10566f08d10daaf077160f011feaca25b9c1f6eca9fc53314a80547951754355525257d09a7fdad5bc321b72aa28d1e02d8696d4f9eb0ad3b2196f8bcfaeb1d6148287a3faefef91a7a3e0609c28ce59d0ca14d0b3050dd4f096b7bc2513988ba212128d5026daaa7188846db21c5c1d179ab9487c1a5bd346588127c20398d362d4c759cfab2a677750b9e45676a1e7e092ef02edbf278fb19a58e9bf6c9e996e24edad73f3ce31fa04b6d8533436bf80b4b2f805ed91e7fcda3bc2bab3b2bb157158af0ea8e3f0731dfad459d2e79b6d3715fe7bf1eafc5397593208857e57b7feb2f7387943a8e0913470c161aef4fe205d3637f23177ff26304a4f64eba3fe6f7f272d234a67206a388ddd0366e894eaa4bb05d73a475f1b34ca222bbce1685b1b56e034e43b3c40e81fff79682c19f32aa3f2a895c0709f9f74a4d59d3a49029ecfcb283082b067f1a0d9505750fd867321999484249efa725f52c94c7596206a911f3f505d63f0313254bd445f05be3996b58fe1819af87352e7f0a2ca320d9cc00a5fe77ad41640d50be8436
+SIG: d20506eb846923a0b16ff82fb2c3923b00c1b3bcc6e2f6482fba24807521e8e0223f692e62eac993f498f67102a04fd1acf9c7e3888d857c9a080b8af6361006
+
+TST: 481
+SK: c738ef5f0935281ba625fa4014d4a4d0be7e28fed779a9cf658e21dba43cebc1
+PK: 95799faf706d195e544c76cafddf09d02d1beafc42c9d6c9ead4c1845587d39e
+MSG: 168d0bc5598be02f5443bfe7dfb8829985ca5d282af9cf1b1482602f243d486bd82ba039a0750909e9b3c7d4d5f8b8baf45718af0311854f4d1c7837f31d8ee68d3558e7e51e0c646a4a637596ee90057b01ed0a17daa3950b81ab47ae8b94c17d40746913c46ba1478bfca51b167628fc3ee1e22f2f19d6d8daf93df6540cedb7a859d1a2ba5911ba71766e8b7fce0c0e8663616d0180697d78ce3040d438131982f3f8112acca29ae53e539ff8c9ec4106d132f402018518308485f2aa6c9e8d1e62fed60cb249457db33c6fd1fe07445361f08194a2b5a057cb03cc754e5c7d4a7eea53a7f7d207cacca5e68cafa969a3521dbb810399a17f328ee767cf55926b2bd5f029549d3b464579c42655265398472e1c77cc8dd9aff187f7ac34dd456ace999a736ecca6d405d4922c779c600c47b84c9c1df5e5f8ed3b2811d351339113f8453cca4c4411688cb0388258ebbd1872b83610042249494ed560d4cda6a68455d957e806dd0bdd83004c4ca80774b8a0a1665866f17085014eadb3eae7382fa870deb29dd8c931b53019625740e28392f38575c0e2a9e504fc35bd95df56439a898230a2398cd2225c766ef36f12ae7e49b30a9c0aad469d5895bbf721cc0ff51d840c802d4a7eefba84fe5205a2c2f14011922dde561456f79e6161
+SIG: f44371e6c3391639d457ed14648184809411e80a3201f8811670e500fcad92f300aabf7fc68e440191e881d6c3474efd6d28f09dc44312fcfcb82701ba3c290a
+
+TST: 482
+SK: 5fea38739c61ca83bf7b4ad175a2117627b971a634a305a84fa57fecb8035624
+PK: ddd14b0fc06768d5104c50764bfd3b952352a34007c50d5ddd224ff51afcdf9c
+MSG: 1013c60a73953549e5ed105bdea150b91e60ec39200d43721304bfc8ec439d39609613c2d878044a9da01b26d86d6d65db93d91a137e9c4808a97d4ef286a903f3f1382cc6d1294216b9fafc013c86b9ff68b55a50ea3766e61dc1ce38348e91d62ce732c152d766b9335c68d6cad77be2b4a0cd50b9a1ec632ba55648a6e7e11a14c06853c02aec4809bd147a5ddd9fbc3be9f0c8158d84ab6795d771b42b1814a17a3c7a6ca0f4a8f7b3a0db1c73ba13b16400dfecbd03d216650e4d69704a707246444d5791fa273752f59cb5ae9fd416a5186613d66afdbd1ce691a87bd7d8b67190e9ac687062a080d2ec39fe76ed8335058251872839e85eb62f18ece187caba55b5f7d5edcade01cdc543cc677e50238b89c5635ad5c8fc220f5e0be1bc667d20989753a6d616fa69f8b12940b8ca9e2c48577132d8691b053779a152cbacff3b8b1bd7af692e56c73bbae4634776cfc213c99b9ae458df1befc8c877742664b0a0bb1f6915c8dae3b3f55dd75aba6a3bcc4176b4e3ba03d0c1c04c3c6408778b2b8e5a8a3eb52ed32a7428c00a98a589d8ca9390a210f4a7ac004fa1fe4c6da694f12276e320b41b0b59f75d264a396d450b631ab353f1612709e7a2e6a50d01cb110e53040546dd3b1e11d25732813aa76be5e81fcf7a5773f6815bbd
+SIG: f4e274823f2c396f3a329486aa6410c5ff19266f0770fd04fb14a7602d2b69a4a2b00928e9e1d92389f8033359ed6fb2146467aa154cba597dec6a84173f8d07
+
+TST: 483
+SK: 60f9a14cce5d43fd9aab4ee8cc8379d575949152693bf29a6790b035e42a44de
+PK: bd4a70740d5acabe49f9a2152082fa2025330e6440437f1d047f313de490dca5
+MSG: dd7f44f9eb728ab48de54ecde6b6184bd5ddd8707545a0129f2e905905b55d3e7fd57e28485d258148f6605e2377d5b267d2eaf4cd4b46e454962219868232b6f41f88a797f9cdd5c39ada51a641214fb9db2c2a9b5a5b16e303575318b625cca970b74348727902a1cf268bd16e107113161c8cbc99303c2b9f235541a7b31e433120feba14febe4bcb0f5b936c7edddd0ecfc72c8d38f64cdb6cfc2910bc29a521c50a51abcbc2aabf789de822cb04f5728fee153dd5501b2db59c59f50cab17c29216d66951019e145b36fd7e841bfbb0a328554b44dd7ef51468c3d5b7d3a1f7b9def58d8cf9d9bcafe92c86cf6d6119e98dba6f38ea57e322ddc9c2198d4bbc3b94ea1329db0d458e01c7081b33925a3e287f599a858c50c3a8f18cc2aa634df63e7f10e403adeab2f41db5578790c3b4f041a8b7a4f69cd6e06215df8201ae5b3e1d1d25a0a39bfc3d041a2f98213ef4141245792a76f06d4de25f6467a0e56f2f5cf69400d22117de7b46149554b70c75b9f99484a4f6f035ad3f10e3753cb14f4f398dcf6a64d10cf6c4fac07c91193cc0f54f0de58c6343e9caaa6b4f475ef91a59e083f9f211f5bc8e7e4516b45cf06bf50beb8fc4ab579d86d4a4190eeac748d06e0852c4b9ba8cfc50dd0a037a7bad7fad55af309a5f13d4c91ed3e0
+SIG: 72f54bb8bdd17e9e422cd339631dd39f57355015d4cbd15acab7542efd784a321c1f6125764c0d154045b32e70dc2e03fbfe1117468ac3e73127b5fac8d42102
+
+TST: 484
+SK: a39053c5c58bf31d462b27a620b0b37b8052c6b1c4102b6145663aa15e978718
+PK: 3642ac2a3280dce52ad8dfcfd3709436edc4e7e4ae1b452d9b220780b08679fa
+MSG: f65540d3abeb1ee5ea987062c1b579516d3c29c39cbc6b09d60e18fe274c2befe0f5fe7dbd57c2d5835229bb754ec4341394765776d6a9178c4e6a312cd74bdbaca0e88270628cd84100f472b075f93692830122f00f9bd91ac582836c8bfa714aa48e977003556e1b696df328ef584f413f8ab614760699c4d147c3eea1da0435835c9bf7ad54606f0213eb74a1b476141506ae2cd124cd51d66e7e7e579560576305c5fbe8430be3ebebaacba3f9989dd7d199f5a455a50cdb3755037e1a70674a4fef40b4a3aaf7bd3c95b1ab41bb206211c3a1276d3e37d8a3a5c3d5d0f36ef5b4f3de26b7f20f6b2900716dcc22ab734ebaf1e8d00020e5f019551653b9c2f70a4038dfb2f12d25d6d84e79073a6548fe15e4828fe5de83ac3d8d98b7daf92710482c37f7bd2431a8114c6137657bb177882d8a3c76babf1c671a7055365fe90866167a2d1dbc870be83b3601f09d4a317ae254cac9f98dcc7aead9224cd9c9d8a200abc80a2dd108af28fd46ad7080ae741b50054b9b9a9201efb7838bc4c5c2cc3d76ba0fcc49c46e792c26292b7d0312aff955a9f8edf0c696a70a614f3553ad3869bfde48d26a4d367b6cec057e62a4e548554b48b53ecda790ba7a0ab2e3de587bdc22b02f5947634d73099f547db22ec1bbf82343f9a2ca38bce4eb59be
+SIG: f7383e966cb2309deedf860100183aaefac672ca16d5419cd6422ca70e16b3976f5f165afc2786117c868234ba1109ede031f8979b50e567358bd4f8bd958202
+
+TST: 485
+SK: e0c29df4de45c47539e0896b3a59bc3de6b802fd14dbdc9f25e717ac82c328f3
+PK: a69002b0f5ef354ce3b2d6b8d8ba70ab778432b22f144dc9c2eb92d99d99dd2a
+MSG: 6a37cb4c749c583590c8d849bce3fa657f10009190cad9be41ede19bf2fdb3c562a6101f27bd37f223cab13ced245a1cedf852f551f857aad9727f62c967c0a921df116f48a80a6040b3c723ab5cb594c4507a3d20cd60514e22164a82b74f19dcfdd83c57bc3652375517414af5d18e0a64ccab36699768d07cf40b7063a83e43d5f607964b1bf0840a45ad50abf83dbc849f40e5b4cfb6a3347b29fec50774046a4b50041032aa4d567e8564b3eed1642040682dd8ae7d7179286cf6e1853dc87d27c3e9e60fa47cf8cb2da0181d53eec40614b07331a4fb7028086d0b1ce2e1115b73a162c527bdd7cab5335b863d108be047bdbca112cc6e776bb453c317314388bb9653efb4444bf5cf1ec8da23b711ba71796c0ae02ba1dcc838455078c3897f07e9e13b76e49274c2e207506b00a0b558883aa122b667db9d670508606a3f54320636cd19f973917fb1875f4363e220f1e12398cc6afd79094743338456813a5826ad3f1aba7cd7beab1fe183859c0cc9ef40a5eab912caf515a8d4c3b93d641b7ab3e76b16c12971ace88ff33e5a1ed9b44e45db8f3085dbf070b256b0d7512ee1069432603d73095db8749ca547963bd71a8a684ab8516b146c4187176386afdf6cb1368a3dd8fcb2cfff77056aaf7823f800b266acce72bf643c6d0c28f0ab
+SIG: bb3b8c5c27591fd8b9c5ba489d6b6ee5b0fb4a7b0de51f1639afc673d0e5f75e313aa7e1d0009081dbca7435b687ccd12f64f74a386e772b9e24781b925c8c0c
+
+TST: 486
+SK: 198b5fd1c03827e0994ad5bfee9b5b7be9966c9c3a267e4d7430343767403c67
+PK: 6682c6f1a866b49b2f8ee97f2e532fa91666bf38da1b4dd65543a1777794cbee
+MSG: 3fdaa15c46f25143db972079d7013c7f69a136f45f3f6ba2ced8b828468eb3daa6b50b4f8d3380fec64a0343be116f6f83b6ee64cc4c1b1d08d54fd42029e4285cfc6c6dd5cd181ab533ffcd411f23a1003da94ec9340e2ec71199d678540d5182e139ffcbc505a170b8f07f4a7e694ca92f58320c0a078564ce9de99b0fa8e66b0d822e467a5aeb83567996a48b89db25cade6457794e5414d67e9d4ab7cd6cc2058bb7a513abd709f4caf24bb67ce1c03ab62dbdfe309ec7db0fa3ea7aae8236f259b922d4536115a63bc89acb2051d09e731cbb0df157d9d345bd9109973c2b594f148efc6f3377de5163b7f69869ffef853eaefeb402e23529594fbd65ca05fe4062c529d8e321abc05200cac1e839e87b1fd3fdf021d68cbb3a4142b69cc3af6f632edd65b83f5aa4cb17da5b6ba3fc03edb17c2a3cb5b04836e7660e63c8a0483e243983371dfa9839f9164ad4da0d5953655e3a9518e136da745737c79243c355fc125cbdcc76aec92216846c4574f4f7f298bcde54fd2444ad3025955c100315de5a4e27c333a00284b2f702fdd3de22ac6c240dbc14bf71e62d131b62f2db992473f2f913f60c916ecf57df5f3f021fb330834395b79472caff19fcfa0a271795c76d69b4db3f85b8d2e5c3441965484dcc39aba59b701274f7fc425246856069
+SIG: f454f35b18538f877e5d614a76b5276a27fc0b433f215dc4e963b3f047694c780c515c6ef6fe2db4b009009bc2733aec4fd46e615357cc0bcc9f1f7fc21e3c02
+
+TST: 487
+SK: 4392f7d4fbd68fe154e4ba38ad5207612a0648556056c39ac116ad468f89bd2d
+PK: cbeaef41acac02bf1f780ce934aabd631364b369567be1be28e3906f9db120fa
+MSG: cf1709dc9a0867ee908721b136cb93a84229e83b46204777ca8194d08b7a3ca9c912eb243e5bdabfeed352349d20be801b722af0892238e72edf190e6361f57572781ad3c2590b197357641c805383baa1d4972f76c65448532c110834a0baa8f48863e166b706653708cd4057d3a4f9fcb2ceb4120001277d38c43847d822822b777c2bb4da4015a1c24d416d5062a8718491d855aaa5dbf5579c164d8e524a9f2fa3f22eb09861ffe6ad659fe36eb40431222c22d7137a6cabca8db786e39d81f661afde4e39589b4db4d3c51ca53590a14e115d0afc3a877b839a9638bece80c32c19e51b7532024845f76cfe9bfb2ac05130f6758bf7fe993aa93aa272e4e6bd0c75c14099d43e652a223e5bcd64c362d4b8f4b95e016f9350c7fa74e653525d08011558b2c6e9bf4fdf9dbd5ef9b09bbc846afc2bcbc86c4ccc315f6d1ccd489b0cf8ed0d93f2f532a426265c590ba3a59023347d819d9b281ef85310b05316d46c8a8c0365d068a8708664ea4d77ac0cd150a65a56586babd34b74365bb8fe3e6187262284d64432e4c81ea4c0e57c1d71ae980c7f4d1d871032e188bbf9d1758cdc1dff989f2d1288fef4e205e99e7cbf2cc324b8c93046f476c59d3d0a59db6fe37382dc79c5ec16056ab3934a52f7d2880d0471a377b6a8ae84d56ac22d1d54551c
+SIG: 86e7ccf06e79362d40cdb7fb75a98978bbd334a1db7590367d60849bd53e2fb1a4bdae590d1f47b5490d8702e7c1a87268b8ee9db612de7bdc2e38fa6deb7e05
+
+TST: 488
+SK: 0bea98abe7d63f158390ee668aa050e84a25d2893e49fc83f079f9bba6a55a75
+PK: 22192ec0d32ef9835665a61bc88bcf4e1604637921152c116af503365bf6be42
+MSG: c178e38d4e83ed2be57ce1c3ab64253a8171e610008181fbfc6d752269f7f1c5a9ec62cb27f19ad99ce1f5116a363d96fdc5a42f358b6dbe7cabdfc9f60718e4012c1bb1f842c5560811ba8374a0637747ff92eac21ca65ddeaf43e9989b7de2d432520afee364ecfba4da669ad4893d0bf69f9f81e7df69657be22b92069745f216c242ccd46d02d35616e16c755e0e37f961a6f3637752534f6dfab8805ab759a032a4e7e4c81953325a2f686bb69a029ce4e03becb3605637c5a65b52e331c26c926ed4711a504d3733bb53c97b80eafe4e75ddd9f415362888c3d4d37bae0e63fa11bf755666437d72f58c91d7a2f8cb619b7620a070b26b18b4d50184c5818712110e36d3e2830f6a8576ba57f9cccb8fff4028bf8ef9cb814825bbca827d649547bf6f2bef931704ca7f6df15f780155ed46eaa7ca7d72e22434ca0483bfb2f7902dc787f617eb9bd41ed4520adfd430948c710805a73c1ba5492e96484c4baa7da24c7435c46a052bf3515d33e42dcef517caa45f36c879121078c688dd10d76656a119762b6a834136fa1f8a643224b9224c543cf0470b3f8ee017d620dbdcc84d985154e9d1ae80e5f14387b88a0f6a5c35905aa57fb3abeb0ea6eccddb004474633cc483b56b8a8e20e8f2e09e979aa09893087875c6b117b5f13847ad8fc05604c4
+SIG: 7eb3139b880fdf66376a2090818840049767c837f3ad0036b141667052b33609817ca5e240ed8cdf3ccf3aee29274534594db0b4ccc5c6e5bba3280b873f2901
+
+TST: 489
+SK: c25878b0d1e0925c8f5f04a1e5799080963c413a1399c118afb1687c797f4839
+PK: 13ac2cad41908c255f671f93934ae5d7be325346725c8b40dc39ea80d70ddf34
+MSG: 6856cc7144b6bddcc4b58954d1a2e7101d6584b5d5e719a0aea0fbbdf221c2a2aacbacdc4020c5c8ce681ff7381acd607b0f5239692335700655be2d94c53d7b5148e92a2bc16338c2f4c1a7d1c595af622c240ce579a5e0f5b651bf562518cec8aa2ce4b4aadb1f2fda6cf6295bc37803b5377dab65c9b9a2949fdd49bf9ddc8f96d260ff951bf8e8ccf9827e6869c44bfd973358cefdb010db5e1fe5dbd9f5d2b2ca393c17d446f637059e692d7a91aadcc7689f5f9e1b3052175d9b6b208f9026787fdb66783f45372a24946b1bd1687bf0cfcc8174ebe4d32e43284fc78d7844de0fa22e2065e07528baabaf015cb34d629c3596ad040de31c5620eb266defa7533ac0401998e5673a754365047debfcf7e137a20d16cdd6a5521982f444cfc3429397c641bd7e74a770bb11fcb29483e337bae5169ee82da9a91adf3af67cd814c2825d29018ef035ea86f8de4c7563aaf66e0c75d17ca68f49f0758ec2d9c5179d01aaed7d4515e91a222b0b06fbde4f07a7d9df2de3bcae37ca2c8460c2a6b3749e9bda36d08e66bcc356b390434b4a18cfa45af557dca3d857ff3ad347cfb07e2358c2acfd5cd53b3b0ea2a41ee5c0802fd473db5f30526334da41eb4bc7518383898a0b7507ad4ca289d66c5e2eb75cf255dff312cb1e04eebeb47f2930b90d5e002eb0
+SIG: 06f55198b4191914b74306f38e381316eac40b5b5adb8a312464f67175ecf612e0147b1cef46c2518750a5606bb03bc6467bb9321514f69dcbebce8f69058002
+
+TST: 490
+SK: 0b2ec62763f687593135da1961ef29a288089696d944b265a5f96893cd2d8225
+PK: c1e234fa8bc96d268e7aad028b03f0a911b697715db3a21c2fc7df48ecda8875
+MSG: a83434c68693d5fced91bda10213fcd50c48920b90cee9b73a9c61081a0974933f4fdb0a67e671f8351b0ed5ec0fe7b5fb0c87586fe582ffb1bfa2db5fcedd3302428234b2bb0e726dedf45b13a70cd35ab3e299d13f34503508278c4458eea5b7351b05836bdad5b05f60e445fc65737ae27d2e52df9c39e5da0286392d08fff7ecb7066820fc90fc8a44d5616561c50b52714702302bca5874de85dba045045f9f0e604eb86d6d7fbd775f72ea493b2c4ef7c3be16db2ca7e4d8bd79eb20cfb5f0f6f05336b75cc86d219f3b8f2e91ba7d52b64fdd6a6664f04f2fbab758cdf984168691c32f53e8616b49f76ab7b192b900903082cc89656a9705804cc9b9288a3e42170984f8dc454e0864b9341672686a178c060050178a36c6d906b2ce070d8faaacd9a58c794a5ea4108b4a485c65811c2dca2ee7bb10bffff75d4586b990f43763a16fbc0b48ae1fafb08a9a36fa4326845dba5ba2fbd32bbf66505c5e8657ed0107e3e16144ef31fa6aae72e774097483f5480aa45540568fd08cba0d577768004f58ae9b95be374ed7f0299fe721275e476e0b9ab72dc06ea328384e39bf3ac331c625484312cd9b06b15a2954d33e7aaba6be2261886ca811db96b1143d06dd6e0f3cba7a1ae9b94eaf67771bb2d24e2f94de9c470fcde7bfdb32f410198b5aa9698e32
+SIG: ff701f34b3594de3b80045f429e5e32dd88d6051d4195f1685be783766e80119368f56b3749725b913f1223f87fb0fb24d9dfa0841d6a0e2eb1fddf775c2d205
+
+TST: 491
+SK: 8960d7bee8c6b39ca5934d7cddd16f16b3663e6e03e833c057e2181e4597cb68
+PK: 43409095d4f50f5eddbd5cd4d2012298cb41a40e99492d5a2db08be5377ea183
+MSG: 308d84c7a5f786e563e5c1ea57aab5e555c00997749d15aee35439efa645da2c3967703115c6c63ed7f94785c5478f38467b86e7626e8fffa4d51a2dc45e6df2a35cec99555eabc9f7a93e2e2b689459b4e0c92b351562c417b1997113754ea59e4a91510728ff3071a2bbd1f465a687f67dae955615031a8ad551fe738a260bbc446b48dca1d979051ab5840832e19d473b666217a9183980d6b27e3d3c76d93665ba2393e6ab1a42c3904d4025932d601a202a59a4c49fdb77f0e02868247de5afdfaa1b894208ac00d77c6bb54c6b2a73a47657e44c85137963b57521af20976248eb261482147cdf7a145c3643e29e0588bfdae6a082904853ce5a10d24970ebdfb7f59d5efdd6a5e7e0d287971c846acd54d84dd45468a4110bab6ef8d9a5b4b2426788900b7e1adfe0624344f98fe59ef8a1e6c405b344eb97bb204773744b6a2d8c6e65d17cea07de03b7f0fe49f1a55c33d5f15ce55df7c9561b251c6ac807a92553e1ce917012dccfd69e7dbd038c7eeecae98623f18fbb650e2218a0bc0fff43a75a116448bb7362f527ee6bc8e10761cccf9bcfc0d000f2127b4cc19211d095a0bdaa4e4be4519e6c8445eab9b3144a45cab9996135bf7f75a78d22275900f4ce1f0a9eac136364103062893dad4390422b77e5f5d1d94d7029c6097b35ca64a7a476fcc7
+SIG: 7213dd4a79fd54dec0c548ef42e6cae015be77802bf515cd2582768f72f563ebb2da36af4aaeac56bbffc9932c2e24ec95daff00a5f7a0acab9c8bd3c23bb40c
+
+TST: 492
+SK: ef6b9b51fd4f8586ca62658e042fc09a83b943033526ffc326c65eb3a5fb594b
+PK: 1d6eece805e0887821876b7ed6ed5b0714d646fbecda38764f94c8155e61d004
+MSG: a8f3f19665de2390d5cc52b064b4851273677486d8f5563bb7c95fa94db3356161ee622221f10cbb1fa195aac7231ea716d74b46b37bc85a70dba3dfaa1675217b351199e74a971028f729b7ae2b74ae8c6b3a0679c3e3296802844ad5bba343f6f9f7c4661b4a29b44f17e89e114fb220e984cd980e94c3d2bf9873e0605c92301744a3035ef046bad2666b5c63ebecf93cc140291946c0fa170340ce395092deed79841352fbfee03a927eb458f2a633ed3271652f5b0f9960cdf9015d56fdabd89ee71e259af6eb514b4c1bd4a666f5b5a35c90f35b149457af2944dd0aa8d9b542283a7e5412b775e421d2126f89bebc3ca37f73071621f1321eee52e9690486a33cd7ff9c9967fb65ee4e907b6b852211473d21e9d91a93362ac761760e8c7bbea486c3d605f9e11b86136819a7ab3f32f13ffca16817fed197ff880b4d6d9a808f7f878763a045728df72faaa963e4cb1c09cc2b2da920280c8366b7d18bf8972df16cc23448fbe6b2e6e16cbbf0745129854053189637ce115d2398433c15d6f116a205334824af282fa758494c47868ea8f4dfadc705e861aad2eb8ef3dbbed2a4569e15834a760cce0cbbc84b289e779b988346b9069c744c97ab2bf42b086d2fb0a411f5ce99f0819a3086b4fe9d96c7c9908dce28df1ddd30f3501ddaf78110734f9dcdfec3
+SIG: 71d171071cd0fea1c6a9cfad1f7fd835e85ff906778bc6345a4dec4313ecc2bff755a717ebd912a5e02840ac073842f9bfcaa58913e260e3c73393d36685c70e
+
+TST: 493
+SK: bad47cd4bd89849067cce1e63c3d91e9b787aea8584edb07f3451ef67e7bd79b
+PK: ab0ce9ba1d29bdfb85a0e66b76b5e2e05ff732569e4375ccd75098e9e71d17bf
+MSG: b5a61e19e4863e0bb5f3fab6c4970d878596895521fa1e7f678cafa2de53322fd458a98aa6e35805429f651291b95bd9950e155f3ada0b609159a4abda5990c04bc2e764422fb49ef42f12529ff6f6a82029ff0185662e658f83c546eed09f06b5a68e857cdad0eb9ec4eecbfd88f34bc80990f8644a9bfdde1d9f3a90d557a8b828d5ce06a64e3b238582bb4cbeba30edc49e8122c55e95badcf502cc567869c09e9f46c6ff3f6878986b1de00b72a1858046fcd3a6e9cdaf5b073c56f2025063a2d178bd4c1e8cbc1e6e671aa97fb2cb4cc8a62c20be41c776372c8e7be63b482e6c63fa85d7cffbc1b2820bae1fc128343a1e20fcf1bc3502eee81358cc9a74c72af63530f96a25a604648ff570df1eb89d1fddbab28679ba2e9b41977e9a9c1caecdbfc361a1dd055ec51620a9bbdbbaf718c9cc136d2007710399536d13332485ec38879785e0c9ce9915a80251373990a59bce440326031ab1b458bfa5b8a4793da4ee11ab7af20de2a118c9ae521a417b68207fc885e109d8463e9f022787cc730db0b1faaed257bed901710885b74e994f54f6f2aeb64f0f60b59efbf2e3bb6515424603a113c0b8a31ba3c1e9a9b8118c87ec6949b75f49627ea7b1328889391104d4f4a3892cf00f26a73cda2a40f9b7157afc40667f4a04f647dbf93906b84c9a35164e1bc902
+SIG: e5724a1dd463a97d1222c518c4925d322202d10f04cd078e771e0fb3951dbc1493a234460754c3aae3df93008dbbfb310c99592bede735a4aeab0323a1210d0e
+
+TST: 494
+SK: caba8e0533113a4be173408ba83c0db74260802f9186c391402655acde6015cb
+PK: 2d7bef6164c279fa1028a9788e3e8ee8ac15edcf92a5855062952310b4684547
+MSG: 2413a32bca5ce6e230e565eb858493d5d04e6d2e2a7ab1f89a3b423311676bfa93c67daafd1cfc7109e040bac52cbfe07c28280bb6acf6e3a31073dab2965378dd77f61fe9247135c1a631b79ad668c9ea1cd4112d8d3a064cc21df32aeac7dd718b091fb6915b8bc063bb5815c376e01476312a2e5433417a7a9315d65999b02ff464a474a597e53988773670eca46a6e26cf96e9488e9e6344bc783ddfb535e76bb3b9a603ff4c59c7dbe2d8b6198d5b24490b4ea96c95959ffbf3d8218e760daf20e01e2f36c84bb097115abddee92bed82d16b15a9e192e9893ac638461df507207b0cf595884d8a99fb9c7045f9bff7b73f00ca3fd595a5cec292adb458bd9463be1204d01678d2f4389b8720115fa597c402b4ff694b71ce4f3d330d5e2f3c3ad6d96a9b3439230fc53a44794cda595557c406ca1589bc7be81e2d79636033253fa7bdd600c67fc55936bd96ce0428c3eb97bad1de0a5fbb9b675157de5f18bc62a7c22c9483e2802e679b5b8f89db0fc37f7c7150ad5ac8722ceb999b2435e6997217092336ef1c8a2292dab9a46ff8a9e10d3355765cac9d6598770f4f01ea639125fd031609dd1a507d96280c7d01a3ee987e9b210ec8744cd48c74f8afee961e8ef221f826a1fe6e7df0cb15ad7c7ef4a91f9d0f4c2e1bdea635d275fac8c4bc0601f490dbdbc734
+SIG: ec35ec32c8a4008827e178492b3b8bee22a4954fc6b25f4f225dd7ed23698900de8156756a8edc35c51d10f82b830a2a659676eac911f960244766e0c3c60705
+
+TST: 495
+SK: 9bf3fbc7308b46f6036bade0c3ca199fac662b07f103bf75181d52ba6a58be05
+PK: 2f6ac6fc33bc060c1dc3cb9d1a2b9115845addb16c4b84be37ed33adb3b3d3a8
+MSG: d65e36a6a38195ecb91de3c848b51f639245fa2baba8a6f85947159dec0ed3fae80c5a0f8c66ff24793c89c0c687543bc633547a1f37f730d97012ebbdc7ac339c4890c0856bbfe2ba29b25a7aa6b089c033fecb76db62dd3c00f6421b9e76dd0ea366eb2d4a052ee6cc736e3819191d5ad7a66d2be042cc6539e5f35652b155a727f3888d93f93a9102598f7538a9ab7c777eec79426a6075d6f38d64c485520f6413ff4d358a8a9cbdab01adf4db02adaea26494d1f5d617637f277f8b0e6e7e61e2eeccdd337de2baf0ca264c14c8cb8368000b9c714385f413737d6816e212cae2aecfffc32fd16d46c3ecee6ab074c0d768bdfe99b86cbbc8df9c47cd586d465871268d4a9d1c877236ab78f8859c114e251cabc4be0f8bc25d148c5f543e290745d11803e49f5b53193fe39969c039b3f249b32f2b8598b6acf4ed64d5752bb772ff4ee00ce0f85ecbb4cfc4ce07daf2809868c2903b781e12a274105f06181029e47f2bfb21f49480aa1e444715c0b9ff07ead88975d93585d2ff424832a9783d94906a60f877ae1c85ff15317badca1e61317433c7ce96279b678ec9d174dd0870080b234154f626a53462cfd547842eab8705605b8ee885729ee78d1833aa43f55ac22731989fdeda7dc5fa9c01985f2661e6c7326d346e6db27e6f921fae7c93a2170e10dd0c460bdc
+SIG: 0c3136e01f9bcd99e10d3d124b0cdb0772bec18a864be81bd1daa44d818c3d470dfaa8ab6e9a761cf03f93ef9cc78291096ed6d10c08fa2fba3bac04dde20f0c
+
+TST: 496
+SK: 64e89304a335e903cb36c0bdf1a6412ef368468006b73d3d2d61cb030cc5f8d1
+PK: a180ef3a661c3c479d5f69807c902748e35e7f725121e37a5d91b8bec88d83a6
+MSG: 2f51074d981bdafafb02a40fe826c45f3171c1b3184d8c260b82b8411fc625cb02ccfe755dc29dc7895bf759e61b2450da1a656a38d4f70d2ee748c518c6420306e5f01ec7a0ffe0e9dceb93f6c077b12662881584f98ce6ab945f87fc6d123c45d6cdfd8237a1ce3635b623a79d020df44c74b89ac14a321fbf33a8c0a2559fea1c2b156076b813908f842ebe4c2b949089e52b1ae40dc6e4b2abbc439a0bf72369679aab6f4c00018be147f7c0a67b9679ee88a53819c49f7b675e30a8b5af39661ee8db21010411294968f88e5d604d0d88d76a7e4864fad3a56f5f624ba1b34ea9cb720850aad3bd4f0a882a7d25fbec2bb7ca86da616da96c1562c6d6a1abcc641e1b58b2c178e1c3bc8a3b36ec9e144dd2e75b0bc8c08ccb0d6e3427b0322b3d6ab93f3f60b9cc5b61dad02385a14949f9b87a8e3af1e0e0fab7a9a928c753fc6110444af7ccaf8027ed641b9ed87fa5d8e1f76cae465d57a70dad9ebfdd3ce7576ac4de89d98f42e282ad87ad6a5042577cbbbc4d951e2a8676fedc8cb1b1bdf76c3a38846385a85aa24706c20a8b38465fe2ae0e41f78e614b8e9642fe2471a9015747db976e0c7848c23ff3f417cb05a8d5ef40130adf855c998a62104d7e2fb7c0f9aa2a496075623ced2c0f7eec10147ff9608a8a042ef98117459b93837fd1b8d5ef03978eada74cac
+SIG: 92eb4454814001ecfc18025d6421f64645a5bcbb5cb8fd85c14d772617c503e8be7d3bcf117f5e6801d1c3b96f9090a66ddc67f8cf8ff0f1c125b16b15e2ce07
+
+TST: 497
+SK: 6f634387ca2c0cb167a740d6afd89e2a28f5307184e81cba3c037046a5ede23c
+PK: 011f2a9a111c38f3490cad1685be78eceedc6fac4a3221301c69c84b1ec7b3a7
+MSG: 865c20a94ac3f2e3bd5cb85bec9d33726671fe01f9c537017d59c8d5106e43360bf76fc06186705980c8a87ba3633a4a170426ecc0defb6db2670f5f592533774cda50052ae597d48deacc2637063bfd519f2e79bac81775beccb1ab2f5b39712e2e829469b75a2d2dbd08aa6d24723404b25eb948a4834c55246c8079a82ec64354e8c2388f8c5a616b3cdc371e6263fabc9f6099219e861585fe82a67d610dd1eb5c81c96b5cb354a689fd8aac8db76c433f0cb0b31cf1d855b6a30a3d2a212e9b4f7d7afe619951f98d2f1ba2c101085ba81f49b36037cd6457a7eaa8f4f3bedf68d09fc9fa25a9d754db65360285412d1a6da53788905fcf4efa8a80cd86ca48b845633d8c31c2ae06f16c4c6bbbe9cd1afb59e101be50e03535dd8a65e45bba46d45cb14badfc8e93ab5267f4e492ab1f9a95e61fcab81cbf2bd867a3ec7b4baa189a0f08567075596129dcf9ff1c502d3279e8aa6ce56eaf134582a9e430a5aa8ca10c3da8bc793d0256ad19aea7149f0ea7ea95facfac1c5cfd29d7a3fe1a417975739e14da8edc819900472ca8c69716328e8a299f974edff741aabc1c074a761b3ec8761dda2e7eed7af33ef00409849d415497c5ed5dfaa2259a31d076398170b2d9d210208b4a4c7db8c626d1c533562a1f95489f9819e4985fc4e1d1a707be5e82b005481d86377f424e
+SIG: fd17c618cdbb5d459ea2aca886f0512c623251284aae3a83eb5d7f60da1d9b2ba083c455a5e2583a3cba736e7b961ba19c1cc8dd90745da82a15dfc662e8e10d
+
+TST: 498
+SK: 4b2e1ae60fa5d383baba54edc168b9b05e0d05ee9c181321dbfddd1983959154
+PK: 36c020b18552345619ef8837eb8d5494840e85f46809343b4d6f406125da557d
+MSG: fab98b2bbf86aeb05086812a4b0049a1042abb76df9cd2908755706303efedb1ad21e8bc8d7562349e1e98ce0d752f4b3d99e677368bd08c78fe7425ec3b560e383bd42af6499886c35add80a5828b61d6644d7dc443ba2c06f9bad2eccb983d24458f6ada1b10bb5b77172c5cdd56d273d1e41010b25cf48a7d58d7255702ac12f2a6fe2918466395f460d15236d035ae9410ca86c4605128299faaf09015f1adee7768ee1a8f8ca06d10dd7f95c46fa10253065f9d6f90295908809fd779571be29e0ae66e0bcbdeb7913d2bbb76ac302f3452c55ef199a48eceb0e3596c7b4c0386dae7101ea244a33c4cdc830672df83655b35338052307b94d223cab1af69e07f78e58cbb0cb3c5351e3a6b0c4a927f7562c598d2d3df90569f61db1a3cb0140b56ea02cf7745fbeec2028673d67f1ec5f7daf9715f754a9d8ed46a7a63ef722ee0d5899331b63c974fa880429435767f96254ef46c9968f3fedaafeaf3e8f45634b54f5e0a5fc2d2373ab9e98d9acfe3697e642a18e0dfd9fbc2f094866d401f0a4ca2a456edf6a1a77b9c296c3922067eb3d5a5ca0a77f430e4c8611d8f05a1baac1635ef7ba83dfc69d301949856be4d2c8ab61de29cf39250c5794cbf5750cda95d0468afa2b7f23dba4ef5f5295a3bf4140018b7ed061884444f5bb1b7d239312dd739999536c684456ea06b
+SIG: 2220119e83d69a6a3eed95fa166d1d1128a3f232ca1b78bc94b4d476c4779443614b8772aa2232cb0720a055eb71d8407f3ab19baa1d962c052c84c0bd589608
+
+TST: 499
+SK: b216cebf878024c20dfc86ce4b37bdc47aa28f29203b5b44925065d993a259fe
+PK: c36edbb6254a913f08fe259e238780638f72ec0b3007264bcc60a9e81ee9298f
+MSG: 9c8717cc86fe02480bfd9e922bd76bffee2170c4cb1b13df834ac01d45006086297f1b8a26f2ba674d33e1d162f19367feba97352b7df2e75b309d4b6f8b07cc0eb6777e81e268e02d07f2a08f8f39d5a8320bfc01fc8c9227d2cf05e12891ff4de885a1c93371a0910ba53392aff9ba2eed9a2055977ec4157bd65b34df79372f4d50edbc48924353cfa1692319d88a7a5bb726254c209291e9b1d2c1a6c8236398109c59ed42a0ac9e7633c520734eccfea4fea95a47a8f0a068b4275000439cc97c57871e105cc0790e9dcc9c25d5af7063ffd05c4f3780e7bca4c456d0170da709fc6cb3faa72bdcf562908ae9340aef4d0c8b91f0fbccbcf1cd898b1c716f4f1474c3aa316242abdf6368e57a247ff2fd5ce23d187f694f11e38dfbfbc3d9db20903b4ebb449b9049ee020f6e2f508e8b2b165bad7464dbdd178cbd423233765d371e7ae1c3e878cdb5b824b20cb309867c0e473c067e6744008527b6bc076d077f4867622aeed1c253dbde7c6a76c7015962fb73391698600bb318ffa7b0136ee4ccb07daaf01f40ff9c194f98681f9faef8b6f9e99f95df0080da8966a8ba7a9474c537b92df9799e2fd16f788dad7a7bcc745226e1e6371f52ebcdbd144044ddfe632dfc0a43d3a450923170ebc7ae219e50e078a511bc12ef14cd14b5309f38abd65db2b2a7af2243b229c9fd2e
+SIG: b7389ee78dd9763f9d2892912edcbe3e8a236b8bdc25f44b9cfdc8c47cd58168ab56eb0402a5bd752ac8f4978d2ea2b65d2fa85265966b9f57227ef4a59ae009
+
+TST: 500
+SK: afcecea92439e44a43ed61b673043dcbc4e360f2f30cd07896cda20cb988d4e3
+PK: d231f69235a2e3a1dd5f6c2a9aaf20c03454b9a29f4e3a29ab94689d0d723e50
+MSG: 0b05f89ebb3397947687afbef0ede87cf3810676277037521d952a3bbbbdc8565988a095d8d4f6f59be572d3d821dd789977ef77a2fd7110ceeed9f3756ed8e188267b97a30ef8957c78aea3a2963deca61860545e0c40824881ebb1db10f607e10ddbddce400ea236ba4745aa99a05641976766789ed0da7db55fdab459ebd4b441a6282f7cfd5a20ea06effa335955e5fd29181671bc92c00052f7f75c39277c9a43b787ac9fb1516e996232a509774d1dc21d8c0513f7844b0a5b5f18957581f99044a14223ccda8a284de12fd424265fe57b270215f8fa9ff2bea517934e4800a47d346fb6c361cfbabeffabd9c4164f45156e245c977edb473642c3940be5ad6fd1a7119a7b18e98d6dc843e0d254c93d0146d18e5c62ede1490f89a605eb454f974778cfae20932e95477bd03bcdb97d5bcb76335942e92ee668f231e69c570ac5446d0f774066737fdf49f10ceb1b52d6d8a4639846a3373a7c6f3b4b3159fe2e7af7eee2f0df172d94d255d017651da3009005e5eac3176c09389ee40d70383bd37117eca083598a1801f592d057186e568e247c252be4b14f723ab7ddb97ae9768c2682fd63acc300779fe04e2b88874751346c9e0f97a2a216772ff9625c33bd7e29fed8003a08dbd33b5d17899c943c25e95ad754fb632e047c112af7f7ceba72362e1a3ddd2935aaf7f818a27c
+SIG: a65545cf3df456b28d83a6d94c036a19d0d29fb065edc27e5e93a1f40279897e1c6f25959a725ababc87cf2ae727f3467b79570e902711917191d9cb0d2d660c
+
+TST: 501
+SK: b834c6e0facbff580dd3b23753959a4c2154c219521b3d27035d071f6599bd02
+PK: d1c384715e3b3d02c13e090605534c7db740da2aa560f53200a3ced8beae8cf8
+MSG: 6cf147b1605528a36be75716a14b420bcf067c03f1cfe9c4402f14987fbfc9d3ecc3ccf4f8d2d03a55900b8dc79af3b6e77436f69b1417ad4b68fd44e5e333ed90ea7943fbd1122609ec8ff6bb25e42e9914f5920fc72c4d013b6a9685c996fbd8352aafb184c22d9e47871a5280e4ab7dd6a5cfd10a5994a200f670e0b622a9394d4793d0a420e7d8806cb127c7ac690d45a2e94166cea672bcd982b0e9baad56312d2570ddde7e0b9e7f47136f0481d00f66a2aaca4d1b09d7ce6c5a98a76b68cd97d5793968d667073f8217f9054735340f9b149c0dce845b099e88d0709680f0f77603ff0a2331c558fc36d5f24da9a62d69af5190d21b5c857a1e08f014c6d456468665a7f845c66f9111f9c098c68940efcd87b657070cb9164bc9743aceb7439a0d01c0062a11af2e11349397f5d152872b13c5ab32f51cc58f1475ec82ac671561dcbd343cfb3c5f78d0fc73053c6004b0a4ca3f2043ff4b0c54275c4fcb9cadc6baabe57b1d5acd531e972ef9335136cd1d65512ba1f5b6ccc4b66b4250aafa2967dd4211a2742e0f177d8f4063899f61815cbe6d8fbfcdf74812bd40cc10084e46a99ac128058eaf16a49a24b6ae228ecf0109c52dfc06e37d6a333bcb24aba312164c6c0290485d251280538ce9541c0916640e36d6929dcd9588eb99577f5f6d82bcbb198826267e49f5daff2c0d
+SIG: 0f19b7066d5792328a9800d9d4f8f67d5b089b541226a167dacd439fa485b0025a5dc7f2c7e23fc4a5c6869e7619d356399700c93650e89cd25b90fb9925e304
+
+TST: 502
+SK: 2269a5d8f7ac2cd9048f5f49e349e5c435a159b319fe3b30bfac8d0d505943f4
+PK: 1c817943dc39c24b01da38a487b175482460c609e4726349a9aa7aea9bc0fb34
+MSG: 7153d4d9e641aa61920db0ff4bd537a6d6130a396554cc94537698f9cad16b99eebefa5f2776f2feaff6bd9a6904120c67e0883f6b96bbbb195e95aec753b699bab3d03944c13c72fc84e3f2cbf6296f645549111c93fae1a759bfcd16fc09e60bb9785535ad27da244ef2f857f2de99a6e92188890e452c7f5b9e3a4b968e11743b6fc7faf1275e5360a5468941797894d770fa7da364a337302239fe83ae0b0d084aa12acdc63462524e0eb10fefe81ba96f71f275f3449a3f8db21d58749a38853d39b0ad8e69891bd204dfca8f6c239dc9a0ac27f54db4238d4706df11d607369dc7f704da1d39f2e82af8c283d220c12431f56d803069b4acb77081c031ae3319fc77fca7845097fd727ad0d080895bba23e873d2def8cdc216c3eed61b08761bb9ebce0282cf502aaf6ce7e8c058637958c3ea1b72fe6e8df8d37ac055db6992587fabbdc467f52475644f918863af620492f34680f2056cbcab75e2323626c094759c0e0e99ef19759527250646ad760120ba386699d53934f956b8bbc7395bb496ceb2dd223c7b501b92d36a95f8f0a02eb5ba4dddf166b9b95b4a59e72a30c63cf21e6085751923d54b30281e52a09618e6f023ba0a21675e7f989b8991588c96c2b56a78f5d2945a7baeb6a0c1bbd5d95af3ee830f5809c794a15ab4b5f89dd2be2dfdcd8fe0520fda2b3f02a1ac0155
+SIG: be0fb3308a076a61a4a92a97f6ac55327190e1341d6dd410d86b41bdaf2d3374093ef720bdb77feb7014e0f77d3b809623c7ca53e2ae4b097113e96db77a2d08
+
+TST: 503
+SK: e965b3f257356685c98b42b964a253fc495399cc94b099c2445fc81c759c68e5
+PK: 689f5410c8e0f4d37bc07c85d7cce6c9b63601f9bdafecaa448a5eed64afc8c6
+MSG: 6f20a9ad27e30dac76b30d4c19a5bd6dfd6d049213f4becdd963d72b8b2dad687b003808201d50f7dd6e599ef58ceb6068c545ed99b9e763f9b0ec1db5fcbd7d490a121ecec6bba1eb5edbd6de85364707c55e300c8b16bb2530f70898136689c988591d5391d9cc347d7931061a9b7696e2c9f35bc0d304a81c2cf954d9c3a88a22e1d67bbe0a85308477f62918c25db504e4762f0e3b4246007908ac701779006b77d72510edc69e17d0f6394c77e5551875a446f81233415d0a91a0460b51c413d644e850f8557281c46699e53b22a7c73b068ea38652cff3b0a7b8ba30971eab18fdbbd8739ee1ee0cd5cbfb7d5d41757b6331271fb7809751e203513c9970f66d91bc0ce062f4fcb28be0a699867b79594c6458a0d307acac91f413c4615877dc53e1b018da5cfce1b63f40be1e55274c4374cdfc21524499a683a231adef779d1921440e5d3fdbd5033dc983cfc931abe638c35d5a95869e9fe3d93eb90bd1861f855ce1f608b7bcad6b5e1bd97edc95ed5ddcbcb715d919f5ff77df2da438f7a3a98286dbd5b6e043fc7372f69704f09d865530f4f0edd3300f185b6d73d8716d32d32b1c9ac2ddf4f902d3f216d35a33f368095ded10be94bb53d6f256560fac2f4af0edf5c5c702143777126e7de32d07493932662129ba0e7fc7cfb36fd2ca531646e8cd2211854fc510af3b1e8cafde7a
+SIG: 8d2bc4e1cd256aad8a151dec010dc93a5e5cca58298dec49cbc9c4717b5cfb5460d430be726b0f302cbd926beea19aa3c93aeb452a44f6007af49adf2f05bb04
+
+TST: 504
+SK: bc3b1e0bf8d69ea5b4cbbf10bb33fc955adcbe13fc20af8a10872ce9df39d6bd
+PK: accd2628155919bbc7f9d86f91dafec35c711a78c79ad360eddb88fa8a180b2d
+MSG: 4c73e04abe0819de1f84d70541eb1bb61c4f42920e1f2d1d9e6281a8a2e8b3eb45537d83969027f99ef0ea27ca085b13f9db480f00c02f3fd7429dd567708953bbf3b9e8e2c6ac4d321ff8f9e4a3154723085a54e9c9573cc7350c09f8973f948b08730373597a5fd0349821ae0a3cd6c84992b189128f3490987e1e9ad4f6574ca538fdfd83284c1eb0953f24c08f74932d4364dbbef922542440dae80424a92eaef27c1889bd08c44f9df03a3af30dffb48fae445e625f4d9265cf387a1da35fe4c231504535db72ea81a186805f856ebe6a6a65241432530fe6c960c5f9be6c22957060304e9dd8efbc1e482e7ddbd8af03bf2382899c986d916611e4f27ae52f817ef01b6a141fe4f685d94dc8cd52830043934587704c1e642e8fe56be6d6b85bf4a6feb2b6858f1f007f99d39ea04c9fe5fa7ef1b91f495ed0e7fa4213dd68cea42b6729f95031907e27c44098094386fabfb04ab9b4de3d6861de462312c59b27c76f7b6a4fc71ea0d5daf6b7320521a67e5cb37504976ad73dae2d649feb75e2eadd3401a7f2f36e16dfbfbdb2af5716cba1bce20cd47ce1c1d7be00697001fbbeb4915aa6e5393b5ab20e0f31f5119149a2cb4c4d452c8156113ac7824f84f09aeb81202e8dd3dac0aa89399b5a38b1e218301960a37d52632eeaefe3687455464288eb17d9e19a3a72ed9de32c17be79a3b9
+SIG: 6ef7f0e91f2cc6715f8e5a98574b4400c261a643e0545ff26747f8e1739899d76640b6451c43c1d03a4775b54fcf9bce18ed3fccad338b7764024fdfa2de8201
+
+TST: 505
+SK: 10718fa6e2d7f6ed38fd66cb6dbfa087e8f1e8a8a24fab58d79d7954b8720c3e
+PK: 870d4f666d06fda9f9511b58602eec050d754ea6d8e79cdd19f601c477df1aa0
+MSG: 41259b6eef13d6ffe33cdde799b995c40be782cf978440b66be51c440582abd42f526696bb3cb92265b1ed0e4bba764cae2839830a252635dc80ce5f73d521b3d6ff03ac30e198ad20567e75a34fa825ebf9841508da84cd674236ca7b43de3564c94ab079408fd94137ce3f90a5dd5d3ac39a05ec86715a8f025e4539a7640ab88836f4efbabd5e1652c49ea21613acfe343a880ee5a42f2f9134ef4e3716b16d134a9c4c71c39b3c1a857d3c89439783eef1edd71bf4492d05fd18673a5242ff4187b9de47ad4968da49dba5a6092e95ea27ddfc7448dcf5972d9d228d63e5291ba6e6fbd07e3241f9366ca4976bb04b22d01f0dbae794fa9c1d9029f88a83602b0e0ec55e22c37b201125cadb5341ef73f6da1abbe2b1c475f0750345b1be4259d8c28531ffe7788667c410dac339918c869b00ab80f20bf7990d366f9b3d5e8eb2f48d7ed0e64b85dc9fe3bb998b1eecd1231e902d2d152e09da2d2592bdb32c8cd2e2c489496b2980c03dbb09ec7f8a4ea2c7020f2a0faa657cd6ced48d6da27864cf5e97eea9b3c2f0f34abf8d87bd2adeb60c7272fc4306d955bdc8023d7d3dc2f3dafe9ebe8a8d138965a7f6ce93517cd2099663f67c34552176ddb595ac6ea5609febcf24c7d69d412709e578670a21ac8afccb8bf2b18ff3af7de21dc71d50d60d37b6ed729db04beff7d34b2920d87551ce15
+SIG: e1659186f1f76fe43ac8a11703360fbeff53b5e57b5974aaa08e2575579c27084cf6802e7c206347314475b603197494e7d61fe4b1ee7b78e18d94469352df0c
+
+TST: 506
+SK: c1d4724c6cb1bc6723b2b43034278b3c5b48fed7f8a3cc2318033e7552047351
+PK: c27e392e7c3664b9061ea76d2575dd7c41eaf1da3a65f3a986e0a57f6c40c17e
+MSG: deee99d7a77d4300c17aec1ab323c571c6e9e73a43491a3c7888b76fc03ec43d07af42a05a2aa322d00c8560acef314106b10b9bd12654357ffa26f2390050da63d668c9e2df548f87639e096a35853f82e761fd711d2a265438f5d4db5e32775708150da6cb686a2b4ca211d7f00dc0abcb2ca150e791116a10a5efcff3514dab8ed80a7092c3a015152cb25d9f86ec0d1ca67ddab44d64eeb1f931bfab2ab188956c743db4814808c5cde1b0745b3edd340eb03ffcc80a78f3db310f4f5c20009fc0279c2c1bcb3cedf990bd0e20c6f9fb7515ad6e933b07e99da6ac32b97141187ef63bdb1062e37220a4dcd419d6244cdcc34ea41d0bcbc3138b1d54aefc0190e30b187db073aa7d6cfe04bd3fd2ac00313e3ddd64a181935ca4b8b2a85d36bc27d97b7626767b93ee38def8b6b2c8da9b00263614342faa9d3e738d2713c45ffbeef8c84bcdbc8da4309c8445530f5c617dc866251f548950a14f075aa3117f96e41f899dbe7340b1d90a1352d3b8fb41b79f16a82bc2e4a193b8a7232400996b73b1fc00b2ec1c667577f82824d39fb7f6e7692dcd97b1d8ce94083ca197e9a5d40fadff0b9ac57e9de761c156e6d31d52c332d513e9f58697dcbdd80a5e42c551702c3de7beccc3db845b1a04c8cbd41695ea7428abba89e0dce3e3d9e70230ae9147c2b88559dc695d6809a51ccbc1dd9e089c585f
+SIG: d37a6ec82ed45ca9b4855de9cb942564e883ff70a79b8e712d5f604ec8974de5363ac849cbab28e7aeeff28ed3f2d14b608b3146c2efe0735ad815c7d75a1a01
+
+TST: 507
+SK: 37c070d4a53b13be760635110d1bd4f01920225afabec576faaec910f2926d1a
+PK: 0aa85f2ab1dff895d1fad0c119f2bf57126aab601c528d37698e97702d35f525
+MSG: 10c646447f81ad94d015d86d0d98b2452dca60a47ab35264035e33a0942b954e3e23b91d8123b8593c6af7c8d3ecd290e0e5ee36fd4e53b7be633a6cf027a5ac3f0f679eb1bdd210a38ea6e48b0558e303010af474e7f6df2a4e457699fc38e36938b05ffcaa1b694e32f3d1b2cc5d00cf256f12184c873e519089ec1df15b0dc76e7bfe90780df58136fe597fce894ca563e08efa0f2d4d208bede9a874882873d251baf019fe46d1d6504b3bcd243b795351f34d2e7606aa975528ee50d59efb6ee6992a89b2426956c2ca4247e0df0129852983e9767a8eed1bc7335ffca8d0289f04807f67ca7da971f58db8b9bc9fdbe4f83cfe9a00f1ca584798bc71d851ff7cd6c51b8990aaba4d38b416b92240dfb70ee3c12b5e731057762ef90823fbf683ca06d05c20d3ae2b97a83ebe70ae17afff9d16609d546d8d3c74bc281884894f3d49e083f10ae7c11c1dca0effefcfa6e0f1535081fac3a2819fd2e3265527182ae9d391b232bb7542e68455cd267760db652d19e22fb2ed11cd1305ba8d98c1ebf2d1969b24d64f3e319af74e092006d2a3ff744872a20ebf18d17748ab7110805096ea136bce2f968b205e650b803c531d06775ae5ceea28bb92e9a0edec8951ce2009a88ee1b64d9b9e89f69051203384210a102a44d2d6703173b68507dceadd3bf6510df2a5cefd9c80e4f385b2f9e6215813ed32
+SIG: 9da60cc4a64d07dee1346bd3d3010995ce2738208ab35b34c2a8fd1787ae3a1e207fe784525154fae4f5794cd8503045fea85cf77fd92f6a70cd0c5a52c0810e
+
+TST: 508
+SK: 1126496a582ce58d3d618dd8a3933547aa7a8a30fb54063b8dfdd31671c6c73d
+PK: e10229c623fa8ad8982c3e4c36ff52df0f219b57915b6e980e5fe72ea0962e22
+MSG: 6a4b52d730ddab829b2a179590cbd4c372498e9f439977c0a10dc13c0ae1736eaaff063371434fd0da80360ec5890607d2fae1c9a2e1ab0b7f3d667f5b1b9c418f18b10c9e6fd669d3ebec168efef44163e577a2ebd0f2cb768f80c23188e86069e4d10f410306cedd7a341a61e0f4f3bc25041bc2f922ed073e1e2f1b709c579d10630f33071754d707894a1c62190de18882c564dc4c01dc545dd8966404ed78fa3267a9469f63b6120abb65f9b3ba3eee28d79c2eb4e7020cc6987dfc5c29672f8c0fa3e690d584fe000c64f352610179621bfd5ff3eb30d18f1a0250416db93b1c1e93cf8a3646517560d1cc8fff822b51ef27b200e987b592390753453ef138bd3d29db7cb1b5f45e4795b89c53f49704192752237c6ab274849f9594ee9777f6efe70483129d067f97199d9ae36090703864f7ca4750a6f3b6ff83824c910484394d1e2eceba18446fe4e994ce07433a740ddd05f0e396d482894e6f14acf7b97bae6c7eb88703039fa785d60a3af78b13243a4f88dde1d998617f2e3fa7eafc2f435dd4ac1ea9c238407aa09b4eea8ed434927b406674ac270458cfb3bf29c347f94559613179b9502192321b88e9af0a90e9a4ab9eddaae382e3734d1415ebe32499c34e6fdeaf15b0d9787985e08dfe495460c54f6743d81ff16881e5e30c51f4b092373783f12423c3e1ae8591130a269980caa1cb5c
+SIG: b30eb56ca9b120bf849a3a9d56af033de8a590c9e1240c1e36dbc6cf0a71b78a11ec143fb9959a8f25b57711d6a90a67e01be3a4da2b69394869bb8d64b87e0f
+
+TST: 509
+SK: 9c167aff3b1b788f133d422de8ca9a64316409f9e35bfe22032ec417ae9abc6d
+PK: efb534f0d47c068e77b28a906d95ad8d213a4d4fc1c70542f01e596d57b5f019
+MSG: 68ac0fc2b607ba38e377fae845c808c8f9fa614eb1f31158a9620a937d3e301e85acaa69144bc349a39dfb582041c4a197ae99b4d4d59b7a2ca3d16228b5591cbf57c18a781efd19193c47b16c6023a3a8ba3d668f05a37f1e83b0d7febdd10f63e48ef7a20e015b1c6725d4c300a986c60e3a115469c8e52ba05b51c05d0af40d89fd9ed76f36950aee3c7819898a903cfe0361a91c69100b495141e86ee79d63d17403fb1a1629ef63cb7e9d2720cbfff0002b190bcdc26794124dd38d42bcaa7175405eb0bbcf8e37d65d05a37195b479371fa2bbbb167d91cee88235dd72ea88fc73ce3ce43d33b715f25f192ec215dac124899c5e7586e86340d8cbe53735defbe02e4cc9fde69fb9794d1db72b98c0f19766ee5138bbfa78909aa299b4913c499deaf54b4841d5044829984936700dcf92f36542b2fc7e86441b9925f5d0b78c17a85cfcfcb20b0fd751349c27463abde4d27df74265288713f96dea013b945521808b4996b1b2dc0338b6d236efd6d2b27dafda46ec5fa32b965e8bb5e8bb61bd966edeb774681e0ea8c17b8c99fa7d660f0f66c9bc6d95cbd7dc094724098eb05191b53a3df6566b9c90e0d7dff2943848b61a20d48c22b6d3c958e293d709c8f48110230ff51918562877daf6d920c85a82e07c451fe7ae9759c0a77e97bb298b5d0592a41d08f67a4ed5a1bb41e937b6a68aeb38fd5be9
+SIG: c9ae67fd6415dcbab292fab394ca6c3b7d90ca244dc6a7764e74fd202bf4b2905bd2030e6beb914c3c238db371b1cba6d9261aa392ec871a4b8b12fe9c1c970e
+
+TST: 510
+SK: e9948805eb341b2867479c668fd3532c309941c0ad4cb2e54231756e6a1bdecb
+PK: 5447a8e34d6a640002d8d60bcf1ddc711e4c465c94c34b50bdef358960ff81f1
+MSG: 91cffd7eb1cf6bd4756bce6a30af9dfba26ddd1cce0394c194a3e39cc3d1cbc221b7eb70bea18d29c267457176a3c9e53c18e47d10a67c464505197702e6b2470d38869db5174b158f9992e4435d02246f540258dedd3ce33df582555a681fb76ecaccb1c2989b177e3b7e454aaa529de59bf5a03123d571df2e7f7cb830805c58b74a653bac0e5a888e08dc2236d6cd496aa06d0d67cf3b335e218c49dedad82fc1be9ef20cac61905c30eb132d739b16ca8a8c906619c0e0d8b33985327e36f3d4b8fda387c186cc50443104db761f7ff9301270204a713e58902101fad000ce931647c577fdec148dca95cdc08918ebed037c60332fadf088f036083ebc92e173b7ddcc30c493f27e69cd17a20d30b78f83a72e4f5a747d86d96c5e1bb7a438166204013e2164d6aabc0d562f54015c365c80445607145e5692ee34f6353077fab7452d88ce3eb01d2b3797dc91b341a3a726301516baae18e851f74dfbdf0866bb2376867de55231e362c472c52116544cd4f81e93571c4ec820e7e653f4e21be0a942576c9de91e7d1251683d859de448f822dcf3d2cf55ede2f9c71b6063d1373061f8f5936b698d1384e65459ea2bc26ec96775ef425207432dda0ac1fe28526c5e4559349c3d8df9918230f4044683cc2c1b858d141ab8d0805bb9336067522aa89c810f3eaa7ac2d8dd28c3751225a19ecec8bcca52439946
+SIG: d3dc62d6ce9c766f2abaf9a7fbe09d6bdb07a4747b56080db09beb4a4e804a70d7ddf4119475c7be834f31956f4a71dad029cdf2363dd0365ce22dc27f078003
+
+TST: 511
+SK: b01753efa73bb3de7aa778be7afcbff66a5d3e2c2f8b5aa2b048844050996965
+PK: d0cc6cf109c999fbf6d16f471fafd0232b0a68d4c46406ec7545dbaba8194158
+MSG: 684e612f27eead0d34844cc81ba911c28aaf6d66e71229e8cc3462f7c7a050daa30cb74471150f07dad459b5a91358476c0598255d8a642dd7c0802811bd88e4cac597efe41ebd96cd0f3b5ce72db4be1a3dbd6b84f5446e3da600d3b1d2b460a009bd31cacd98a91518ce33e9a703d404288736ccc43103fc69e67974f31652fa3dadef3337f6c897a3d201303c8f03597b4a87c98f291ccd58a3f1e898332aa5993b47fcb5ddaa1c0868b643742d0e4a4b9cd427038b3b74999bc89ac3484c0ca13f25aae8e78ae1ccee6218accab81a4f694f5324a347629d49b55e4037504a9acc8df58c6841dddcd4fc4347f7b6f1fd9de0564577e6f329ed951a0a6b9124ff63e22eb36d3a8863bc1bf69cea24c605967e7d8948953f27d5c4c75f0849f872a3e3d16d422fa5a11e1b9a74df6f38b90f277d81fce8437a14d99d2bef189d7cac83ddc61377ed348b3c4fc09ec2b9005925d04a71e26d641667bdf549294331c6ea01cd5c0bd1b6a7ecfda20b0f1929582b74697cb262c3927d6b223f4b5f3043aa6eb4571a78e9da11c2b36f64552580caa7b5fa6b90f929e0162e608d1240d7242cd2f47025c03debe059b1dc94770232bc6765148480bb1d9f50da1ee6448cf9c88b19dd459932c06ed811c4a64a12d5938bd1c757bcfaeaee8933fe5fff21763de740482bcf1ba59afdc8fcf873c3d507bb394e32e45f736519
+SIG: 16b7421227ae09130685cbb1a0c60aa57a5e1afe1bbe6bacea0c281bcc8998e6824a772c3208a6b6b4d236695505c9be82700cf93a783985a39e16e377a7410e
+
+TST: 512
+SK: 4f4b20d899366f2f23ee628f229b236cf80f43ba183177c97ee34829546f1742
+PK: c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357
+MSG: db8ef02e3033e6b96a56cab05082fb4695f4a1c916250dd75173f430a10c9468817709d37623346ae8245b42bda0da6b60462ccfdfc75a9ab994e66c9ab9fecdd8599610910affe4f10215cb280bf8f9f2700a444796dae93e06c6bea7d8b4fe1301baa79ccec769368feb2442c7de84f095e6b3bff63d388cbafb2b9809dc38e9b12ebd039c0a57f4d522e91ec8d1f2b8d23a4a0ae059af85393bb0a15f749110f6774a1fd731a6ec213e4ff435daab546d31ed9ec3b6d8cc2edacebf4facc5566556eea92e5b3f2542239b25e28012dd4ef40072eebf83ed2a255181f3a442189d68c6c609f4dfdf3db7d67d087a2fcd6d2dc50bbfed8bfbbfcb74d3c41f02a87865b13b8efcf5c3581257be0aa913f60c370527bde11a475c136a17c5eefeb03f5bff28693ed841e8ed1f7c29102f5599dd444009bcea6a92d5574152458e0caf8a36aa72b5dc4908a6461c9b741453005c8fbcc68113ae184208ee14b835480c6efafed18a76000b38e5858290f4d51f52f096cbe490e1eb5cacb226ec495a55a7fa457843d57fab67f8be7e209334785bdd665d7b63e4daf57b6e78928b603c8c0f9bc85464733b61273ef9e2b8a0cd7c3bf8ee0a6872e34d5a27a625e35eaf7ff5440b8b141af704df70c9c18623bd11209513192505105cd7bcfa5f0d919da706948fbe1f761f315846aa3b4813dd9ba3d81b9204e5409c0382b6eb
+SIG: 0f80ff5d17488fe26f93c543b04ed959b5f0643fc61c7f2c3bc60132ba9c6210c8b250ea5e84d07b01de68bc174414eeeb31fdc2ba6823e231e312a91ededd02
+
+TST: 513
+SK: d2e01d2578b625a7060aabc25765f168c680cef767aa97ca0e5eb3d667474b2a
+PK: 191ac223575424aa354b255b812dd3025d70ed829e0826c01629f9df3545082b
+MSG: 20d5dd699b2853302a6817094d5ea512bdf8534504cb289c602467410740ec7eb8ea6442c80f145935068f9122fdf4a39f2010f33db55b814d97bf2e5872329f1126d4eb95b806ca1973113165b116be8716371f81331779dc79a5cb3942081ab5f207f6b53db0e0038107d63ca97708181982dcb5f3b93010ec6edfb2cfd31cab00090b3c38515f9781769686cb17ab81d54a8b775754d42fbad086b80b28d636f78b7eb77ed9ca35b6843a510f0ad0ac1b20267a000301b3c707a20f0214d59b5b8199c2f9ee25d32060ace3e0f2594650416a00716cd3f98604a5e104b33310fdae94c314013cdca5ba2414409eb7f1901394f007d6fa0a29dbe8ec3df98c393c8d72695877cc9baf491ef30ef7db3371608ca97cc621562520ee581d5d1cdbc78232d6c7e43937b2cc8549e6f1e08df5f2eac844fe0f822b2483ad0a5de33be64089490e77d69800fae2589ee58712ac15a3f19e6ffdbca42fe1894e889b94c04b04240dafb0b2730c236b8cceb2cb97afd1d515dc19d1067fd4aba8ce297fd6d110b35a21bd3c075c577d93fe1df77d648f7119492099b017af44eba09c807f11a4c3f4a11a2fff306a728ba78983323c92a2fd5fcc80c18d423426f823a73fe04094955284293f5f6b3ca4ff1080dbb1e4c6f74c1d935ed21e30094c7de336b82dd8200b0d659583c5bfd5470f9db342e70ec4000742c5640a214e3c2e
+SIG: 87a010394a9f2c904effefca9fb4d5ce13793301a4925ba51db119123a4d730abf764ce065e48d90a79d907d7254c40cc358987a46949e928bbb3cd085dfab06
+
+TST: 514
+SK: 7cd7ec99dd03aede1ff1073ec2ca7010276e947e2aa9b0e65f877e4ccf1b3a14
+PK: e4c39dbe9493176b8213f1422a9de7c74fb6a59190fcdbf637c7ad5ee165c04f
+MSG: a6034aa3c2484923e80e90e5a8e1748350b4f2c3c8319faf1a2e3295150a68e1eeca1bc84954cc89d4731a7f6512af01464fdbce5df68ee8066ad9a2fd21c0835a76559ca1c7449a933bcb15af90223d925ff61cd83eb935698347a57072709a86b4e5a7a626e07a3f2e7e341c7783a540f84aa73e917e867bb80bace6254705a9d1a1185de56e1a4e78aaf539e749b8f765bd052c4cd15b638bf8ecf87d9814606fed5a69f4dae9da47f3806dd90be64fccd3365cbe9e01c588fe65d6b603280740962aa8ddb95a3f4f674c03bc4043092c544595568270a2c2a8aa06e3f67c31998c50b9a58acad00690d3848114cb193293c8ac21016fd996f5c64214064f82167b2c920cd8a839755852ac77c3d90526dd3adb96837cf4e726f34bd02955cbac5b82c92cf4aa8b54bb6e436dae9bf893ef050c6f135a7e62fcd834dac1d2be8b8e59d696131811701c4318bb6e9b5a20bec656fd2ba192e2732f422963bed4a4fd1ec9326398dce290e0848c70ea236c04c7dbb3b67921440c98d72753f6a332eaad59fd0f57742923fb625fef070f34225ea06c2363d123666b99ac7d5e550da1e404e526b5b229cb130b84b1903e431cdb15b33770f5811d49fbd50d60a3474c0c35fc021d8681819ec794cc32a634bc46a955aa0246b4ff1124623cbafb3cb9d3b92a90fde648e414636192952a92291e5f86efddb89ca078aea7717fc7
+SIG: 6f99202770964535e483a0ee01a529442eb321303fa805d475604d7fc728a9103fb7b558b955f4d03719eefaa3b7ed5b0da75710bb98787f5c2282ed66e9f60c
+
+TST: 515
+SK: e3ca3713a2fd412ad5336bc356b77be027d5b70815b3ac2aecd8340ef5f889b1
+PK: 1d516cb8bef116a0c1b6929009933f6eb62c23050745fe7e8d3c631623778111
+MSG: dd99baf295e013eed107ba8af81121aaf1835a3cca24f8e464b4cfcaa3c7bffe6f9536016d1c8cf375038c9327e8e21b004066f5eac0f76a3e8edfb07be8bd2f6bc79c3b456de82595e2c2105bb1b0aaba5eeee1adef752167d633b322ebf8f7cd5fbf59508fdbdbecf25e657a9c7050af26a80a085b0817c6217e39acd54cb9fa09540fc7bdc5226d6a276d492cc8a3dffc2abc6d0b9fb08cbccdd9432e449821a5dc98cfb3a418e539c890fe5a0446b9f81d306700927ade61cfdcc0624f13b5840748774604805731d92e77d5def66be44cc817946f1cd758196cf480f99e7117835c4c87cbd64077a562a80cf11d8ca65be7a94d92b9ddaea997e93f1448577ed6d8436b2f3144692c1fd7d28a03e9274bc9e8669d8575f5de20cfbdbcb04e9f39f3451d7048375e2698e722846cb4f2d19a810c53d4c1a6c3b770fb402df0530e7b2907223fd0899e00cb188ca80c1531b4e37fba176c17a2b8f5a3ddc7a9188d48ffc2b272c3da9c9b89dfe53f2fe7e3672f91d11818491ace140adcae98502e114f4b352b90e2e7fbd333b2459e7f15dd0764c9c34e4cb7cc095500cda035e8e2e4e3c8fd5df5f3aa579a735dd8a9f19ef336fa971114e46618734a4c13d30c81128ca21def47330103d23d80ffe67421a6ccf9f36a93f05603c599ee10b03451f36b2133c187a79ad9e6fdfbb12595ab73bb3e2e2e43030fd37e591cf55d
+SIG: b3857ea61baa9e62838c4e3a996502d3364fe1ec594258355073dd10e497c600befb1f8f233fd6e3b2c87f10dcb7261aaf3481bfd0902605accc900fef84d407
+
+TST: 516
+SK: 29a63dcd48a351771411fddcab46bb071e91498576e8d02f8b6044f5bdd3ed90
+PK: 3923fdcc2a9fe5cabf6e9932e46dbd2b7f3632500f9d95552db2b045bc41166f
+MSG: ff18ca0c204c8386a4aa74ec4573c7b69216b31470daedd96a4f2302116c7955d72dacc88e3714550c09e6f7b9a8586260dc7e63da4c633bae0162e116e5c1797b78d87d47ffeea3d7819df9c852f0ff30936a105d3af5531a8f89549711c14c2d3ee11564e7c8525bd58864009762a05541d8e07ad841a55a6a9a007ef209ccec4b5640babe35651b61df42de4d910ee73a933c0b74e995757e84a99eb034f41807183c90ca4ea8d84cdba478613c8e587cb5f8fb6a055081da6e90220d5d86e34e5f91e488bd12c7a1a6b3c9fce5305e85346658effa810d0e8a2a039db4a4c94965be4011f9d5e5da266233e6c4e18ed4f8a25a57e40a591c7ed590c0f8b1a119c7c9747f691b02196cd18e6945213f1d4c8c9579c6e0a2ac45924128d6d92c8e4c66065320353d48d1d5e13194d905f837078f8dac0b68cf96ae9e70554c14b2fa29b19630e4b0f5d2a767e190efbc5992c709dcc99aa0b5aaf4c49d5513e174fd604236b05b48fcfb55c9af10596927bcfad30bacc99b2e0261f97cf297c177f1929da1f68db9f99ac62ff2de3bb40b186aa7e8c5d6123980d759927a3a07aa208beeb736795ae5b849d5dae5e3573710aaa24e96d5791e2730d0270f5b0a2705ba515d14aa7e6fa6622375377f9aba64d02569a209d33de686e089ec60118e4814ffc6c0778c6427bce2b6b844cfcd5a7ced0e35303f50a0dfe5df5dde1a2f23
+SIG: 12bf629593e2caadc910ec40bfe2b7a62514126b16ba3a438d88e2d21f595aaee8abfa4af2ec870361d0ea04dfc8c6a330fb2841c2d8211a64fa1e7e7d273800
+
+TST: 517
+SK: c7188fdd80f4cd31839ec958671e6dd08b21f9d7528c9159143734f94b169883
+PK: 019752ff829b6859b9058d00c2795e835655440675753f37e85eb7bc5839c4ca
+MSG: 4af5dfe3feaabe7f8fcd38308e0bd385cad3811cbdc79c944ebfe3cd675cf3afbef4542f542975c2e2a6e66e26b32ac3d7e19ef74c39fa2a61c56841c2d8212e2bd7fb49cfb25cc3609a693a6f2b9d4e22e2099f80b777d3d05f33ba7db3c5ab55766ceb1a1322af726c565516ce566329b98fc5dc4cbd93cefb627688c977af9367b5c69659e43cb7ee754711d665c0032ae22934f44c71d31178ef3d9810912874b62fa5e4020e6d5d6458183732c19e2e89685e0464e91a9b1c8d5251e24e5f91813f5019a740a04b5d91cbb8309e5161bba79dcab38239a091f50e099ff819e3a7b5205fe907cdfe9c0dc3ee85e32d7bcd3ce02635e2058388031e317fbf22ab9f39f7f7e3cd1a11a9c1f45f4e1e42d2536c122c591837911847108ceafd990813c2b6344cffc34be37161dd815626900e8fcb85c21afb4f6be8ad01516a31c2a6580315857c6a216735ca991009dbc2ea5034160747a869d5cadb0b47ffbd5d3ac97fdd0526cae6eaa35cff7a16eaf4fb950ca31511346fea6141999a3f754e6281cfba15e8a826932c589c5d247c909d94b4eab7ebcb09077648af065c2d86611eb588453ed7c24780d73c689c8744afd533a86d9ee9e3365732cbd0c351e436f898b7043292097e03e6081a23ac865e19dc8858969b999d01fa65ef200c3f269c818e30b9365ecc683bcfe69c203b4e0ab6fe0bb871e8ecaaae82d3acd35d5b50
+SIG: 35c170dd0c6dc2920a595775d8e2dd65243e9c1bf96ef42779001ed45f01b7dfebd6f6a7dc2d386ef4d2a56779ebe77f54e5aecfda2d54a068476b24dbd78b0c
+
+TST: 518
+SK: 38ba0621704d2155fc2f78555196575de06d80255c35e9dc965b6fe96a4d5389
+PK: 4388f7f68a9effbc366e42d907015604daced1727cd1d89d74adcc789fd7e6e1
+MSG: ed4c2683d644b05b39b048ef1f8b7025f280ca7e8ff72cb7eda99329fb7954b700400705275f20b858cf7e349a3510665b630609c5e2e62069263ab9c55e4123a564dca6348c8a01332075e7a5bec9c20a03807957fefa910e60c35ae579778ce2ce42e6a69a1b647681e43ec4b63bd5fbefabb31712cb3d6419ead78dd41c8a92aaceb63cbfa89d2af39606de010a397e302053a615c16e5e95ad9935c079a0b8103125789471a1e3574f429b29e4d225c7723fbb3cf88cbd73823d9f0b6c7d05d00bdeb0fb0ad3d7132033183e21f6c1e8d8e4c0a3e4f52f5001da687171345c6dc8b42c42a60d1f1ffa8fe3e7bcece59a035878f9d4d81127e22496a49bfcf6bf8b46a80bd562e65255071f9d11a9eb0481f4626d4d71ffc38afe6e358a4b289179cbce9764d86b57ac0a0c827e8ff078813306a1d5fadd32b46a1fbcd789ff8754063eecfe45313beb6601c3a3010e8eb97c8effbd140f1e688311092d273c4defca47da6f1f0825744676f9a280b6c2a814fa47fabc1980d0b37f087a53ca8778f39ffb474ff5f1171b442c76dd008d92182f644a714a0f011e215a78b97af37b33520ebf43372a5ab0cf70dcc1dc2f99d9e4436658f8e07cdf0b9ea4dd6224c209e7521b981ee351c3c2df3a50040527fcd72804176046405db7f6734e85c5d390f520b0c08dcbfa98b8742480d5e46f9be893f6d6614340f8161611d5053df41ce4
+SIG: 42bed6a98786f664715f39bb643c405ae1750056460e700469c810389504c51cffd9e1a94c38f692fb316265316d8f4dc3ad1cdd8a6d5991ef010cd1489d7c09
+
+TST: 519
+SK: ae331fc2a14759b73f1cd965e48514e12b29f63b06ccfc0ad49f36820e57ec72
+PK: 08803d48238eda3f9cebb628530121de00f0f0468c202d88528b8bcec687a903
+MSG: 5716003390e4f5216598a03d7c430dbf495ee3a7557b580632ba59f15198b6180a42469c237db5bc81f29cfaab0aff3c9966309ab06958c9d7126add78e3b32459ff8a0e0bdef874b58e6083668f38ad7d63aae1f12e26a613348f9f03ea5d205f045d78cc8902d47f81e8b52293e70e86c9803d4dacea86c3b67458ae3579bc11113b5490bcf3e1cd4e7979c264d835161fd55efe953b4c26395dd92ca4930920e904fadc0889bb7822b1dfc4452604840df024db0821d2d5e96785a5c37dbfd2c375983283e9b5b43a3207a6a9b833948329d5de41e45008bcbad493de5754dd83decc440e5166edaae0208f000c5f6d9c372153209e5b7578116f89cf2f8b1004d1307ea79ed37480f3194a7e17983a230465ccc30fcc1a62d280fbbaccf006dc4dee0ea796b81accc61a063e2c083daec039bd9a64a77024af82ec1b0898a3154329fdf61673c36e4cc81f7a4126e56290e4b456819bdebf48cb5a40955bab297c2bbcb018adbf24828660a5d12a0613bf3ccb5eeb9a17fb0a0547db8da24d2efb87ba1b843142a75e4ca0b0a333e4a14fab35a62669329ca8753f016ac70cd997e8bc19ee448aeaf0f4bf3ce5230550578ab64c19019446ce2d9c01a03d889a9909860aef76f067c50b61c3d0f12cc8686f5c31bf032a841015cfeff1cfdae94f6b21dae941b335dc821f3284ce31508f5db5c448ffaa3773e9be1a4c85a1c58b009fa3
+SIG: 75f739088877e06dc56daec8f1e4d211b754e3c3edbfa7eda444f18c49b69c5a142db45a0a7650e47d10550ba681ff45dd4463c4ac48bf44b73034bd5659220e
+
+TST: 520
+SK: 82435f39790106b3af72f91f14c928d2465f98cdd10084c4a44d19af71a1927c
+PK: c52a92646f5adb21c6dde0de58786837f8a3414c09aedfc27c812218a7e7239e
+MSG: f3d6c46ac5248d5386b6b68462597d647039f544bb01ac2d1067daaaa397d2dbaf125a1cf8fdf280a6afec324d5311f543688a156c849819bb046b911c42ea3ca01b99808c4d1f3b8b15da3efe2f32523ec3b09c84b48cffd13c17c9e26c912d9c3e9346dfae3fd0c56c8858780782f61a4c4dbfff1e9cb4b362cd8001f9cdfeb1a72082dce9c9ade52effc9744688ac0b86c88266b53d895c17ead9e89ed8d24d40642f3ad3b9bf9bbc4dda7966ef8328289fb31e17c81fd028ef1bd9a1d4c792e86ec2dbdce3f937eecc3eeb5188d325941919bbf75b4388e2399507a3d7fb387502a95f421c85826c1c9176c923e316310a4ba45c8a5ef7557cf87b77020b24f5ba2bfd1228109566307fea65ec015019691217bce69aee16f76249c58bb3e52171cfefd5254e5e0f397169186dc7cd9c1a85c81034e037183d6ea22aee8bb74720d34ac7a5af1e92fb8185ace01d9bf0f0f9006101fcfac8bbad171b437036ef16cdae1881fc3255ca359bba1e94f79f645555950c4783bab0a944f7de8df69258b6afe2b5932217195da245fee12ac343824a0b6403dfe462d43d288db31f99097ec3edc6e76547a3742f03c777efb158f58d4053fa6cc8d68b196af4f9de516fd9fb7a6d5d9ee4a89f9b9bce1e4dee357a1e52c0544cfb35b7092d1aa5a6f7f4c7602610e9c00ef5b8761bc72279ba228a18b8400bd76d5b2bfd7c3c04aac4436dae2e98
+SIG: 1daa44ef06d4c10ddb48678423c5f103a1b568d42b20cc64af110fce9d7679a2dee412b4980585c26c320dbaa601c472defc3c85415daecdd6d2d9eacac85e07
+
+TST: 521
+SK: 1bea7726d912c55ec78b0c161a1ad3c9dd7bc329f85d26f62b92e31d16d83b48
+PK: c9ddb42106ccef4e0ef4794551d21df94a6306872f231663e47e241f77cc3e82
+MSG: b11283b1f0ce549e5804730ac3207ac00332d2aacf9c310d3832d879f9634bd8a58adf199e4b863bb17481d28acb2da0e1557b8336a400f6295625031d09e4df4d319bbc1e8f6e9232d23053bb3ffac4fe2c70ce3077fc0060a5cb4692a1cf0b3e62fe454802ae10b83ded61b6bf454ca75e4cdad5532f20b70654f12ba906f003a8b9e986f15a39419deb2ea1ead7598290eeebf9252b0c27605a7a73a6abebb42271d71a3c197a46bcc8db11d9242842f378364a37eecaa34e982135be34182c69ca8e6e3c8c90e1b4b2b475815a178377ae0165a764c8ba2889b5ab290949d8487a88e0d3d2bc7e2520176aa6ff9ff0c409ff80515f4f0b83c5e82c23fd3326cdd6b76252e7fddcd6e4770978cd503ed2d6b480101167d3f191fed8d6d74d74a2007db1092e46a23ddecddcdb984664047b8dd7cc8a576e1a806f52cb027a9480a95cc44b1e6f2e286e9b7a6bf7b396fa5496b7a5b1c03d9c5c27da1a42990d10b12fb8640e1596f26b366d270ba64f99afffe3fece05a9b0254b208c7997cdb512fc77527954a1cb50fdab1cc9a45162741fd6f9d3fd5f2e382853d7335dba1e6b2959dd86e125e67b53dc8e453c810bc01bf20bce7b618dd5d1ed784106ee06a3ecaf6b3bee0b56833b0b813139c5a696000a449c97906a2fbddc2d9de9406ea282ac4ee5ef8bf3854c74a6b7173dd2f79c7a126f3c7b0433fd4ea26e877a14831dd415a19d
+SIG: f9b04517bd4fd8ef90f2140fc95dc16620d1602ab36c9b165fff3aba978d59767110bb4e07a48f45121447ac0c1abac585d391d4042041898628a2d2dcc2510d
+
+TST: 522
+SK: d01a0ead9d694833283b9cd7299a7bd75fa90b1d2d7884e4557b33c998772a68
+PK: a0f757479ba627efef95d6ec7a931dfac4373df33daaf4ddc4ec6894c8261ed7
+MSG: 7627534e9a83d1e406ab948d30d1da9c6a5db08e0feb7fc5ba5cbf76849ee8add4847ef5ca5a0dae411aca097451cb4c2b498c947097407007640dc19ed938e3b91bf51c9581168df860bd94751668dabd721dc73998400be20c9a563d5051ef70e3546fee673312b52a274041057e70848eb7c5a21644c97e448abd7640207d7cdafcf45da6df3494d3585b0e18ac5ac9081cb7a407a39a877705cbaf79a01b915f736eb025c58b4b5d807fb7b7566c5969787c1d6ca4eba97d509ef7fb3550d21d377eceffcf0eb6681895adbd246ee7bf3c935a006478b832ece46de6118b17e466a27fc2a44a896baae272f9ecf018c65cb50cfbfc8d260994a18a832d971928c449675724585131c871533c9897d8f80f9c0416b718786b10fea8eb5bd813a269a1b677b7a2507a44b713d705086530995e59335ddc2855e847e4f4db06c91f1d54023d8a10f69f9e61bdce4b686fb617bd5030e755cadb1f644e1ddd91619b96ecd605b00198b9a6eddb5a84ebd3692b665979766637c677378c1c77041fd4a6b3555c1dc8a83fe9013bb6106cc18a2b037c9377b7a1a5a5d0dcc54918eaad7e32c880767b26fd2ea2d68b0405f5e074f55a19d8a39ffbb7dc32faee6a7f9532aec8a0776c3ff83ae3a4627738496a371eb9e090b74e0eddecfcd41bed0c0ce581275243472d26da8c998e4b6d6b44fc88ba2ab54642225417120294417805742bdb33b7b122
+SIG: 9a0ff7f35174ec3f66d22a6f06df60e09c8f623a5aca810e23a88d0e6a31cb6f1ce1c1f9dccc9e1484b68dd004ac53597e29ad6ab72e8ce2b75ad5b80eb84803
+
+TST: 523
+SK: df648940b578bc31d2a652965f30391caf06d5f251599a737ce10be55f4a9d0d
+PK: 27de920419c186b01be54279fb8f9be4bb4b2cad75ca7e8f792bfa7bb97c7f41
+MSG: 1ae520beeb4ad0722b43067fa7cd2874abcf34dd9237b4478eae9772aea297a67fb79b33070204baee440b9c87e2fbcbeb76801dddea5e4530d89e11583179939a00a32f811332c52291cc7ac91e5a970cd5aa708b1da26be9fe432a9bbda1319e31e4bcc9f1666a05b5c05b876bfd1f766687ccea4e4482e924329aface5ee52e9879fd69b76e0f7e452ec4713bff216d00c82599d27ca481f73aae136f0875c88a66b1b6f34c50523ab602e9d4ebb7eeb9e043a65e41899d79752a279d2ed46993926f3621e7c32c9a9b3b59d8dd57beca39285434de991cbd2dfcbc5ca62a7779f475d0cef2f3e562f29acd474f3c99ec5bd8de01101bed2e0c9b60e2d70fd432c892fc66f8d4619a911b5625163e9a42bf9ea38586d8e764001564d335411225fcb0a06dc2a82da0779a3c444eb7864201b43ebb72b921f34d3c13089df2f4fac366ff1e3c0b96f93d2b4d726a5ce4d6916d82c78be354a1230c2cf0418c78a1913e454f648cc92c8dd0e184645fe3781d263cff69f5c60b1ebb52005a8b78a515c7e8886ffe054dab428e2e221d9d76aff42654168d833b88178293e1fedd15d46cd609483129c4d2d84432a99d31ffe9bdb566f8c75ce65e18288e4df8c16731a0f3fdde1cca6d8ede0435ff7436ca17d0aeb88e98e8065cbcbfd0ff83043a357cd1b082d1703d461881872cdf741e4f99bd146745ba703974be40f579bf5c4dba5bdb8c941bce
+SIG: 62bc991c45ba9b26bf440116264162c34c88597885e9605083c604b5f5d8fa6f662ba214f76e6cf84e5ec04df1beefc5f25d3a3b72f98b5069831916a6329601
+
+TST: 524
+SK: c8ac234558aa69816b368b77b7cccb5c8d2a33ec53aeef2ce2287143bd98c175
+PK: 5364baf1fdb2c63840b30d4031cf83a2e18e620793bae59d1035c0ede55e528b
+MSG: ce488d26975c1c9328b47fa92e19561330041b23a0e57a4b8bca89eb5f615e73dd7fae69c2380e3212f9b73341c356db75a6256d7a20a97f759d4cba7197178ea724dd932949360e96c50a4b3ba55a953372c397b0969c2b14d3609e0a852d484df70eaab11249ebeb3237921f0a39a55d7dccfef205d94ec80d9e1fd6a2c1efd29844101dfe2c5f668adb7975915dedd086500cee2c1e233e8e48855cc1a6f287d63dce10addd13cac7b7a187efe47e12d1c35bb3974052b23a73668d3e4c87db4841af846e808672c43d0a1522e2965f083951b2b2b0c409548ee6182f0c9850514c9e6c102f54ba4124c92a90274f405891e662f5ebb3771b85783156e9e5836734d09d1baf5b2134c93162eec4be03bd12f603cd27be8b76accc6e8b8bac020cba3479651c9ffa53ce4eb77a77313bc1265ddab803ef7a6563ba6f799d1ef30ef5a0b412965fdac0b9dab842c78ee2cc628e3d7d4061e34ede3797e154b06e8c66cebdf2ded0f81b60f9f5cdda675a435277ba1524557e67f5cefafce929291dce89ecb08a17b67a60c582b487bf2f6169626615f3c2fe3b67388b713d35b9066669960de4db413cd8528ee56ed173e976a3c974ac633a7134cce38319735f857b7d71ba07f477ef85848aa8f39e118118779ed87b4f42aa358a89f7ec844a451e7e8fc0af418b85bc9bf2f26d1ea137d335ec7ee757b70ae2fdd9cc134932f0e5425bf37fb915e79e
+SIG: 32250361df6ed283485f95f3d357a4f1c33a8cf91658327cd453d49c953665510870aa454cfa3b83245220a827d0ec7477f9eceb79c4a29f301f953cc8caac07
+
+TST: 525
+SK: 2c47f2b8b9d2cee9e6f654bc24658f9eaf439c23beaa0a79bf35cc8cd2debaf4
+PK: 444af2f34fd32e5a19f61f87d03e107627a3eeb8bd94d2faeaa348b05dea1980
+MSG: 044c8faa8c8aaf9f2b8186a6b9b33847ec7b452423b22a91743d2e597ecc1e1e22ae60053e9ee6233b044e775920e4e3d66719901325cfdd39bb532f8aa469aab42e9608c21260c04c27413a7a94e466f63c4952e90ef90c12814b3451b1cad7da9147f8409220f6498cc0a67fef4bc04fc06e1d898a5515591e8be0c43d75a6fe425b7cbefb1b91b1bd78b5bec7829056982efdc5be24af6678006adc6f0446202e7ec3a2d6979cb0df7e25d74233914d9c58b81cf55be06967d3a595c1b9672869994cfba67162833a2143aa91cc93acdafa5b45208df3e88ccc01a2a4d220e360098d9154d225a7ca5f2f1e52b1003d106650a77b283b95e4baf1e7336fa9a747a2b3823d360910412e76db725ce1ab1e1d189d0d3abef82d7666bcf1b76669e0643b44f74e90ceafa0c8371b57c58f3b370a547c60958f0fcf461b3150f848c470fa07e29bf5f0d4b59efa5ab0d0341e0451d0abb29d7414cddc46cc6d74cf3dc233d0d1707387bd8c7780ff78e546fb77294d58a5dda5f05c1297e3d1771156d285635bf7ecedb38a9e5e77449804f3899ea46a50266b255aeb52d18e0fa136e535cc9026f678552fa3ee2146081d999685e24bf7807cc47c130436c544d35b4b875bd8afa312ce3ae17cf1c7f5ea1ececb50f95344720cecf088434ff8e0ba044ec19c98ada7782116304cbeac1c3e35f5a4f44313354dc9a40ece5a0f9ad3a2025acef262c5679d64
+SIG: 8554b01d09ed86e61395b91a2b1ee18715c42f9c7e7f0700d79ff9fb5781293d61c558dd5b431c93718dcc0f98fb652b596f18c30f82215e8e63e4f6568c8800
+
+TST: 526
+SK: 887fdb4870681d4fb06a936259f75cae0517f501af646bc07a4d72bee7fb1c73
+PK: c762ebd48b2ce02d06384e38554b825ad322ebea74d259df1547a4d547ce0024
+MSG: c5dc779f3f3fac06dd28e5a67e0e524af5b5dc3b34409657b63dface9471e9a41e1132175a0b569c8fea9d2eef2cf5d5962c7e0b6145a9e7a0c1aa33772044f9c3998c5a8c4886458b4e586f9307608361f511e7ab5092ac41ec76e0586ef5b9c236fcf5ca2fc8dd6aaeb789367f2e7c990932555dc52261e44e49423498b524419183b6c1f1d42c45464eccb0c2f7e25177fe5cd463502b403e06d511fcf9dcb64012e0f20b34c2ea7c004d9e484a7ed81f3260c41c8b1953529f47f71e867843cc3c332ad0366a63817ed12dd4730d3dfdbd7572b9ff798045940dd19fad0c8aea0b4ab61c4016de32799c73aa2b92d2c25ee9b72d46fe8f0693c58775efb05e9e17a5c346a81265d35be69a22d095de186066a5c6d8c07a3d38d002a10e5efdb866da4a9bdd54f5092661b6c2d743f5aeaa4c6c318fb59323903057e49c237b45f67542a4f27caf65b57cfcf88b71203d43d7f95322160f95c232dd10abb113b721ddba2226b063229bb44102336b10bf1656551161249786d454f4e0909d500017f6c7564f733c831af4e5ec94dfd3bf8ff5f3021b70a5ca5d28c6dfb8a2c18a1a662a33359f264d169698c1ab55783faca73bd68c0f79d1d04ae0ecdb52ae761892c02493ff35f3d84f66e236fc58134ad6a77d92254905d773900d9ddf2654c70b46f341dacb4793ca51eede45533eaeeb6e3323bc3e6c85a7940651c4f6f98191c618c891ea4e220ea4
+SIG: 410a5af3c59b7c6bdb214b166cb79d96f830cf98bf52dad7b6ff2979c97fea4fed5ef7d3d49f03097279b9a099226e2a08dd30c60786254e2da8dee240bfc308
+
+TST: 527
+SK: 88b3b463dfc30d015eefbbbdd50e24a1f7277775bcef14a6be6b73c8c5c7303e
+PK: f2b6284c930d4ad32d0ac719040ee7886b34722edf53da801acb5f931969e119
+MSG: 17c317fa6bc90c5532328f02ccfb6c099e6fe1000174f2af3a3a9309428506717c5c4335bdd7c367ff4e448a9c047503afba68fd8f7987237be7f7fbdc6d73f24c6421cab422b3fb25f67b2d71042e71570df2af37bfe5c114211fd5524b6c1c6cc52fabc3cd7fb464cd580bb74071cb300f8c9f8a46208e5aa5ddfea5fe90697aa2f14c607950c98f2312a9e16ef6346a8fd129232733827e1501a660c77c29c56d2fdd1c5597f8bc89aaefe3713734fe82858201891a1147efaf1d78a471f920defc880344553eb716cce3260e86a1bc0be28373a6a066116e8ecb10a0c4a70ca2b5364e119f84aec60deced3a4eff1fe688c5e3e251470ab516fa964a4b6f28368dd1e283597934064dc0c5b5691062cb2e267bd15fd422bcfefb83ccef7aa9a2275ef57e473149988c1578fd18708d2ff69f8e5980aa826a82cab7d8b92bb53bdd46db046ecdfc8cd7ae5ce44f3c5b8c0565b5d3c072c76b95ce900ac3ee5510db0e75d3a4150a98f3ccccc69e930c6ba741dbb0eb9fb3196871ba206a58e0dae39c8d6bb72a82399c4b7b9da38577ac17ff1524d653c0bf33679323ca7eef4e9228729031560ed8f2e5193c640b2f5e608075a2ed61428dfccdc00050ba4b99ed6d1536d5ac1e939674b41d16312ae5b07def1bf53589bed4400602ee11b850330f38aad33ef04170a3905c28b50ecc57dccf4f29d0c00f713d32ffc857956588a6326b9549edb0e4fe6185
+SIG: 825aff71f79303bf4592bd8da4d7d9437ff267976f746437655988ddcf29379465a3b48c9fb0f31cef03e6368861c369b4364fb8e4b0c72e26a9a9dded1c2504
+
+TST: 528
+SK: 427d6e423917896831601b8f4e21561db6108571be009e29dca49a5960ff314b
+PK: 8d9e6360fdef249975df27b3106a71120587722df3270a85a13a8c3bb8c9809e
+MSG: 9c2cc7f2462e09c4c58c2709ab4259885a4e887d9fa531881505aaf203c163fb3a0dc028f4ada60670638d4a9727a39083bedbaced58edb779e1ce6ccdfb428c362bb1db0c1053006bd8f4bef89a1a9de01c774e357f910e5c39b22477555e5f7c0498b5b28f369e5d3fa42ab360e4f451c69f81ba0f3cced43a559db600104278f868796b2c911b3b032b729f4b22ac149dc467a0cae48d19e9d985b42b62549de171ff566e1d1e9bb8e56cfd1ae8f7bddcfd8a2341827dbe89c882ab3e498339ff681c7dc1104de738b480316943109f703d471ab86e4ca4287e4cd74c312ff7d037395606fb25f871e7277078a787d02f31cc9e815be8600a7c47c6fdd82331ae9c496a547bdb235b8a56d53259e6296124a32c3b625d202419d064b9a4e83efa87f13537b4f513b916a84fc866d8a899804c7833eaa019e0d7e0e8075bd6b5cb6ffc766479f3f6e20e481e6ab27bd808ad906cdcc7827430e312f740f275ddf51dd83248fa057c43c9cb77557b2fd9c2d52824ff9e146deac1e6691d450213bc590a49bec72d52e38f6b4dc6cca951eef2184d2425031ad59b242effa68b6c72c54c9dfdb419c02eb43ef3f34d338d2a9dd03a78cfdd014098e249259e77282e0c3fc1010b02a67ff851e9cfd9749c1cd8f06cf462e6ade995ac466fab5c795e9eff13e55b4350b94c7316aa498df9fdee9958047793e3bbb89fb81da85f4b9d43e4b0d43b381b94cdc9a99d06
+SIG: d1c9a01c56e33960f49df37eab963bc5a99f25c600446ce2ca48d9139da5733b718fbf1a987393f6e5823c2d130c7ce60ea3db3543c8854ef12b98d33adde705
+
+TST: 529
+SK: be935209f62dea6012ecda6a6156cd166a4d761150deed456816eaf0ce78a7f6
+PK: d39a89af72293948b13421fb883bbe372af9089c224d42b901979f7e2804e1c0
+MSG: 117f427cb68150cafcfa462c42206141427c4dcea1c8eacc2d30bed1e90207d5ae305e1fc16c54e4c54cc6878cdbedc9f51fe18461ec37c557b115d13c8682c4e15f505296a1760e1e75f5ab27a5c15a1357d2c8c40dd5355f7c82fea5d27e28876358c12e9113ee2983ea6f09c64e06e297dd96b34d9b5ed49fc47a8839549c66b002fe945e8f94e7d2315c50ca4dc098be4b3289812fbea96b47ce604540bde0e5ab0b1bc036be9b6a95e09c81e898640c8f05d60ad94218d0e66ceb85a26b78292220bfd061dd073512923b90c79dcf5a1935fafe8e01ef8bf81b4d37c5a571b50c421f9bd2194bef3586fcb8584877bb7e0481655b05c7b643b1e45b04036272841852e31940ef8f3b6d4feb5df079d176f979c18a11a66d1214e52f687e9063c1c2b7277b685d5c72ad569f7873838f910257a053131c83ebce86e69d736362bebc96bbfa35fcba1cb527e748e5f579929fd40c56b1a51a222e863302705c86f7b54ebfbb9482f7e280f7bec8caf3a6b5671ac30cd1be529288797c013ce56bd186de7dfc1828691425c147c5174a290d80cbd59c19da7adf77918882a7b2a9a64e6d76b48b92f2a266eee6e251d2e817652b88b502de7399782d7529a81d0a363996b9df68b15a7630904c8c246081fa4f09299f15757958e089a901c3564615c0f7cf2752b8b9e521338d836e3dae4ce2374642253c4c9831974e5d8c2842f49007b71775093dfe57f44492f0
+SIG: 08e098a749fce6d12354395878a8be35fe9edf72684dd8281224899b1caea4ed687785dff55a19989e03636e1666386f22c3f443ecf6fd34d599ff3ec2faf101
+
+TST: 530
+SK: 6818c60bb6439ac2eee2d4e128e9d8691d4ad5d363fed7d6577a62b6569994a4
+PK: 7345ec11bccc056fc4effa3e4ef670996aa26a1bb1b83391babc39a1a59601f9
+MSG: b2ae658b3c13c3cdeb1dc993b0f45d63a2ea9abd0b7a04f1f5ce5932806c2ca9b7a204fbf8d066b7f0fe6ae0d1da68c885ee11f6f6db7e8320a2ea650b533851cdd99d903aa0b3faa3c950f702f04e86b4eeb3a1c7bc854b2514fa5b4766d375b4f1ad61075378dd92fd626c2b47e01383ea72987959262c562862b45b7557671413b66614bcc9f7bdb9ee46cbed8965bfa505315090c7204bea89175be5f20802e3deddcbd8dd64cfef7ee6a6e3860ce1e5799df5d810d5ecf32e615d16dff87abd4a636ea17aa4ece5b6b2c046b65b5af749862b45790c39176820b36901be649cf4169df7e923956d96064950c555f45acb94507cfd0c3b33b080785e35c0d2b0addc4c0ad3fb216ac2e601c9c7e617dabda333dae603cc9db1fc62ae4e0e45e3ccdd166a6781e243b7daa138806632f538844ee3d140b7a8bb2b540100778c458e066170705e5fb2c88029098b992c39bc9ff6330bfcfe7752320e6ea0949d2c871aedc187be27fef7db5f72a6a773edde0dc52ae2ed931cb26817b85b1545894d92298aaf87ccbc783e8dd6d16493f56ead2ba852ee9c7d10074406440d2a279abc874f15468dd66a717bace37be7b7055dd9681f8be81329ee7af97e3abc434ac1c93aec582f23fd1ec0fa5aafcf7bfbda00ffa97ae317ae918d349d21a7f4619142ba23dacef7b390ae26a17e2e2962ae27005376b72d4da9e2979653a66325a14617638dbe1a5540b683ac0017
+SIG: 1505967a27b9f86e9242444002a1e3197d74ddcd89659ec5140202aac794b8adc193e7d30f3382642990f6fed7a999cac8c61eaa39b7d90816f1d738744be101
+
+TST: 531
+SK: 6d1da5b483e64b0365990ff09381fb1702fd8ec3a1a369cd52e4c56713a314a5
+PK: 08055c261f26e02a658f66d9ba01fcde53e9ade3edc6bf815e4a6802e1677ab3
+MSG: 79a2c37055f189f3247f1f8cea19b2ea40d858db1f5d1392ee6d411c7802ee23de52ad02811725a94d76675da89a96b5d07abcee233a1a2e1fa324fff9e78a4c196147f8570b0b13713d96aa5d750a15d7cd162e7ba2e75333607dd698eb4773c7e91f7668ff8b62f04640eb12ecf122fce6b832e0d0df928eefd2c2002364af6bb55291d3f54929085be338342f09da73e279c87c8324555819ed57e78d7ac40951d33f65b94aa1e555e92a063d11f1ff7b12694341e3fe444933d01aa36753ed3cdda890bdf95a8205b5d893221991c795ad0a4a946f58d40a453451af214fd465e28d3e2f0a56aa56def8dc04aad35713abfc8bd7856d5a9dc3f60a3f2bd3e6366f1f244e941d6aea892f6a88931fe1c313e09078e90bc6392d490533c9ea3ff6deaf3aadfa8dfdc4e90f64af47589ea65a87acd2199602351d3afc2103196e0394ed523aa799d31e11d34fff546d44f436b34859f9cfbc9ce403de5a9830ec3d453f0d45970f572c144f191b2fbb2d0ea6cc9c8e24d9c0b2183b278072ebb0be2d70d037fd2e8ec18dc4c9b21abdc6a4ce8d4668a220eebd6934f04baf0e88a488d2dfc735a7c5a70dbb0166a21ae011fc6e7da10fc320336271d9eead510a6f7032f2296692be508021bc98c170be4235f7ce31f2bcd6341163683376ae2c5662cb4770c96e018ef1bf47913319c9a09b9e965ab5c3e97bbc756a5666b4567f2cff2d0c3a6a4026158cb9f90f950056
+SIG: a5b8b44a91444c64374b523cb4dcb0cef4ce52408b98126d7e1ae8bdc28cf51470ce4e253e0be62bd68ebf5fa6bce1585eccfa9256c073ee03e54c525bbe2d0a
+
+TST: 532
+SK: 5146f5b7f1baa19fc8cd785c896e0f90f9f659b77b1b9bb4adcab5a6267205e4
+PK: 688a8de64eff33ba6bbe36cdd6a384bb67b3f42636db234ff5efe0b31743c7e6
+MSG: 97bd99f518ee0788d576d99c043b449dfc242ac5eeaec344a19432b345962ec412ce55362b3b851d98119fceb9328347f6fcc68dbf56a2814db09e9385843a931189ea3e72da9d79a45693053c035701dc5551240f95b303fba16f89aa53a43882b0f1381202c78f9c7419899f2351eca95e20bfee76351c48d00499f591da56a99524bb74fe1c834ee91077139f1edf67315c07a3fd97f80b7c276b6cf6b5cc36be363b731217f6319f5129ba7b14d054c8d81d8e3a3f3be62ac31ff62df6a3b2ee2596969b991704b31c689997ab4628bc2660c67872132e85da0c4fcf567965f1254a8f432692a17bb86cb3c1dcbaac939552f09e50ec5b0de2ef85e0ac253a4165655db5b5c49803821d859c60961e061d58278b827dd4d3bc47f1c22de094906bdbbf3badbdde22ba24255855eb86d1d7f37082059311dc0728ebeaf26c4473bad1fa9e614b533b811b6bcb0650c06d879a5245788f3401b46197300774a9aa73cd978c0530c81a53bdb3fc932414b3e30440dc127441eff1605e7fd9ac8c632e82bf1b453d4f33a57e4b67b0b6fcf6ed5555b5f5a300a14a00d0385a33750525b00edb312c6bfdd64edd3b5316d19f958c517634f013b008936d34e9b5e1e9283a5f0fd7783377c0e5090641bb9d338cf3133acd0b971e537904f17af92911afad72ee97f9a8283a16a7e26ab428416c1017dae9b1a99c4c3320ad163bdcfc328bfaf9b8d5d7d26d41d1ef21a5208f01
+SIG: 4bdbd7c64f13e278c23969e7eb386bbe499dbdefc3ff4e30cfac5cf86f216c24c9e6cde20e529d147fb7ea08f2593ad50903b5edbf86b4d28f2eb32ef137f00c
+
+TST: 533
+SK: 5e6fdac9351a637b99f33a264e1287697e2abab0cca16621792484f5606f44c1
+PK: 57e5f88acddc8cde7dd07a3146fb1d4f7a9b6383a8f6b2b8d9b07ebc3fc4dd20
+MSG: 4d6cd3bc2f86266b8bb1b61d0e1caa9bd2d4a180361aef3a18d390b10f7e860f697e247eb6c3e51d3b976bf0ca183d01a69880f15c94b875668ca30dada0895bedd4d705a0e03304d063dea87c7fdec98b89c06f130dd5bd586b54d9ba737826bb405cd8ac8bbc9500acda3c07461d009440af0b2531e72f3ff5016ae2d86d69b87fb273d1e8dd5f6a264beebb2f885996741ffda277a0fbf8ef08f81f22ee5961d9d3fc938362e1ca12004a91d9b5f7a6833a6c22955ac0cda3390671910cbd51e685fe095973e415fc2db8adf10b147ec7080c3b8ebd07d21bb9556da85430a268eed8486b1e31c94313b01649fe91b222f85adee15eb77707d78ffcb660926544d33be9994a297620dc7aed97f392639053f388b0b3aa3bd0ac5b033cb414be520b43df6826b976890d0c53b97b6c92e7d1a1573d0c7494d747e0cad9bd8ea538d62ad59801ad0716f170193e3009d9959c55d2ff64799bd959359abb94ca9723b5ffc24c9507f8c5fd6e88eaae7a70add84d744ccf8b98363788f0bfb1a02522025751e534710d40a2d38a791194eba293fd2046cc14dd3876d168fc6e236cbe146d6369d225bfa67e53979865f78873a9fcf03c186fa8521f0a5545accee80d1e55107221e21f0f2291c143de023e88d7330cc87d4c51ff29a3090605e9739490c1dcee713495f231c2a36b11ab235547fb6328f747336d9b1ef25a8ab99ceda957b2dccee4075b0d03381b94ae18d041ea
+SIG: 987e32e00a8a1632f47b503194355c980cb22adeb326b4e3115ecab04b704d186cd92e3c3ac7b4e2936cbd07cb794ec0cfe91a97872ff2b41376f5f18f55b805
+
+TST: 534
+SK: fcfff0932dc86ea5902a8d33073329960cd8188a075dd0bcdfa8382c20b0e78f
+PK: 0c9205a90bbe7f2d505e17fa3d080b522a1d7a152cad2d85d31b34a0471c0d4c
+MSG: 3d4b76122373e212a346d19a66bbfc4b623292649bd0ce5cf6bb135648bd01db7403b3d0bdd1697ff4e6e908904116754d370c40d700cdb664c46a91dd84a358b9d2381443e60f2c3f5640261b6b858ba8f828b0971f4122b20288a26ba2090ba14fd276360cc68679cd8419ae19c6d4dc7b6614c06df5e5c0510e2cb686de0ebd75e5210a215562589b28c9ccc7d272b98bd4bf93495efe4fc5b78defecfbcaa9fe126bad30e89b3a389b4256f6a48a76c345de5a36a1449f08345b9a5e6a001da1ff9cd433709348e9aefbc78ba52d3ab3b46986935eba8ecf81edc43c5b2e3b5eb38d9a165e9e7f72f617605463bedba973ebfdcdf2b0889c71412f8f850c7a3b5518ecd89d2e25c0c1c30f085a0ffe540ef9c0e88fc7ec4af1948a4e6f7a6e256b307a1127b71ba686efeadca0e4860947cf674fced6caf7310ccbaa8d9047daed30fd5585d41ddeae4df2fed4b6228032c3e4ae2380e87ec6cd72e4d74b8b4c3813fb043389391e9c13f7d33c3aab5a78fc4c6a634c61a70f02a940548da177c65df6ab17cd9683f37ea821c740889d82e88c834e7d5dc11662ea78b13c6a4b6218d31784219a4767595b1a56216525cd68938b22bdb1f8c5a7f1701afeb961888e2e0ec0c838cd620cb7dd8a1493a02cd56b545125e4700c0889fa2644e644a3af531d1cd6bc95e5df9175f137f28408cb699c7ae66f65d1d2930fac57ca8a60e6311a4078488c9ea404948a9debeb9d5e10
+SIG: 37ddd83f98b057b7cb3208a832c58aa90694563c23548d432291380b73591301f274b04cee2ef78c06d96c3d9b7c17521aae1a8ca50d347c09c3cf703bc8830b
+
+TST: 535
+SK: a1e4fcfde044f1bb0e7bbc631a831a8d07e90ae08a966ad627b620b1e28c42cf
+PK: 25560f31168bd4b72552ededd08bb6bf79a94063c1f1e1d304869dd1ce049b95
+MSG: 8c1454d4e08a1401646bf7a8859e8a145e85eeeb40db38ff0169709641212c81b67390749c01a79807f3ccadbbd2256f36ffc180cf9ba44bf4a7612d441c23b2e25d33c48a73e16ce357562758adb00553c3142fb8176b6ae8fb610a60f923b0911814b10f5679936c3677b70e846e218f587567f2019c7d282a107f3cc84763adaec88993c0cc5003e77af60d67db53f8cb727aa6672de004498c3b3e222aa7082d91f98a1a068374c510ff53a5e559cbe2d6c7c3442d7238907c811d58aa7f5a46b8311244f0dbe1b9c0e944dda1d8010864949c59396c6b346a11f3aa866d6bceadfc909038d22efbc8f1dac810a9f2fafcce7c0389eb0a56c0f68cae24ae3ddbdff7116d2fadeb9b0e7509536fdc3b83e71354da6a1aed16887490dc2f4df57bbaa7244528fa3094b99e867581acef906270b2cf4deda6b8fd9dbb79add7bea8f86fcb1f64dfd50e385b4209ec0b1a9f6d2e519068297a2b5c405c216b4a2ed983ff69c59b530effa60c0367051267dd2bbd1e86a9ab5a114dd4f69b540bfabfe97c0403b8fcbb27625761eda3e2ad8e625cfe4b615b7025531a498918c24e02a00e797bbafd14f9d3f6827e390063c436080688d037a6e2993c56d3a8e95f375c10040bf04f030c972623d9e3801c13b4ec8d01cf183855f5935f10ddb2c54c51c80cbed0c24db56e1ed148931d89161c5ea37c2f9787f88ef7330e5dcd0e43d81bfc8bf23ddf7983cc1d733843a33ccb395dfc
+SIG: c8001527bd902c15c3dd5ae18180525b5e8202be66711f82885c8222a15f060092a2a6e2f7d7e980311209191b32b8ade48d3ea98cf245f0fad62c009c5a7108
+
+TST: 536
+SK: bed1bbcae18643d6f6aac34f3d9b6a1478394d02b931cff006d85f21b7dbc747
+PK: 4f528b38185a424c6fdece46511a0c29b7c04b32eb0483abb52d5f8eb6b352eb
+MSG: ff7c6413e618a056de401ee10c40ade3d7c0e6861495d97c2689ec6abb69dd2ae701fdcac8f08331ea5c5f5d805b5789ee5e241ff4ac8b960f4f2b9fef6a727fad86dcd432de9fad6ba45e00aa3687b0ceeb2c0d430b7d5fde63b4f6b982c4f9e03c430abad9044d06dc49e89df481405d8febbb0653e9686948aad2d9072544df9424fd487f4e24ba7f2455ddec4105828c3981bddbb1b7fbdbac155903e960fcd94c0716e736f519867fbc52c51260f571d7edcb081a23550ad8c70bb268864ab276aa2cc2dbf62383bb66030ebe94354174ccec2d2a907578556444507cbf8488bb23c62423a3a98da7cc968f599d3dc84dca3afad7f14ec306e1db534143216aa22ad18074c719570805ea46bc86b71a8ff58e41e73cb29ad5750fcfc9a1c54292b64b47ec9538f53816e36ed0d0c1ae5ead06d477aa975ecebaf62d9023b77e50e7b6d4abdaa485ea34ec766beb1d9ba03c9c067186e2e38266c6e2531e97480214638a2bb31431ac2086797155fc775b3aad8d5a0b904c381edd0c6bc23c66a1904955ed450a9cbd16459c32f5ca354bbc2da7b1a4d814f1b8710aadb2ccc4f397758b7e9d91f3a91e5825ab8682ff5e41702e07841ac7698c3da9f558edd01f86ce2c506bf4c2149ac9c195a59c7dd7d4ecf93c90b4423b4350588d41672cedc8510a7ad53b4b7edcaf23e43e05669d27a1fe97b78730d3fc060bd4edd9872cffb96285351bef148ef783ab392116bd7b907bad
+SIG: 0fc99dd3b9a0e8b1fc6e635af5c64006b67200fe958f53cce1b9b091a4e70669b593f15594bc0842e5576259f9a6859a0db22d740f9f8024b5baf1ef6f958c05
+
+TST: 537
+SK: c718823f43db2217c66ab2899704165d208573de60f33bc0b9338d880f193fb5
+PK: 2940b879b63f2cb1f6e3ef9c9d333ba91770fe18cc5a347fdf12b0efc5ca2ec9
+MSG: 050e6877f65ec726eec701863fab140b994aa1e92a487db1a18701312057db44bfde70911ec26eaa28632d03794d545dfcb2aed4340cab7d092595cd59ed23994043f50ba696e9802bd64990121397286457ae69d76cb8e34d7c1ab245cb07b1b408f2bbbfdf33a1bdd559636702c918f982c2ac0221f7f94db91edefce28118259f89d994dad5bb013c678c1c338b65396b15e8899c169921f278859ce0c856d889b8c63418ebc573d2d625d5b5938839f2b169b6916d8e40dde70d3b72887ad2478ef6fb1284fa0e4fc524e3c6fa1dd22ba6b81def8279f382bcb45048851b17cd659d59409f571fa8a920a20934d9dbe1022d635840965400240f870aceffd5db7c7df08af89e47e1b9e20bb99f96ab073edf53694c7482890e3631340217e687ab27c984b60825169457d435a5409ad8e42da0aa63e20c2bc67bd8b9a267f39673a77f7f3136dc5cb2d24948dbe7bcd7129318c68c6fe95dd4dd4fe942286831ea53352fbb252a1288bcd838921356785d072134cb820f6279cc71461f431be9d3014724321c92fdc576320137705cffb2c23664b705e9be60ae1a190f3e3484f70058e702407b056d7fe5d31cee9c2a6ac6eada3516abc5517256df1243780a03bb00ba00ce248076eeca6fee91d5ef9eb907b801af097f3e9eb256bdcde81efe4baf8189b0399e36f1eaa3ab626617cf3b47dd89caf69c64c5b8f68bd917fe03e4668538460a1be88d9a846cef39934627d474734f
+SIG: 4c9cdb1ad46509560d871d3089afb8734648201b10acc953e8b61f2cce2dbae0fb9b868ac957432b7222dbf7e4cf0bc75309bea360b263abbde188532dda2504
+
+TST: 538
+SK: 2543d166c9f5f7427ff3034ffa8103cb117bf472331a73d9a2f1bc0a02a6ff1b
+PK: 42678cf3857021aa5567706db031e792715ccaf8abb02a042bad17db3d5fa103
+MSG: 746d7abf0bfb2662c25ab5c5e4612c306f16d13e44d0db394a0015676ce609784f0323da1dfa94d2b2f1f6e02444a936d019b143021f73c79df9309e7bdff39daeec4caca00cba4ef31c8310c1a08ef4b36f81c377846b5b90acd411aa671ed7af278a24229b7893c1b415d79888d7637f5cb5c9c6c631ae5ffa29f1340e444096ab533617fdcb80ff81da0a7c6c142ee0fe5ea82f68cc3ea38b56f272b0d80fd5f4f55ca9348c161881435813c3fa9fff66a2ee6d5bd3edba0d2f9aa74b1c44bfd0e64678d3715124963ac575ffb09ee16437da484b3ba58e5aeb8ed8c5c0f47b59908fe580f37ec1de266b295d6be85e62358e9bbdc78964fb837eea29fdb7de86cc56f48bd9a3e6e2be51d8a1dcff3ca4d56ea934c682772bcafb51497be5d0f2a23dd4970c02c44c09ad897b4241acd7d6ab12d8f00c9aadc334b431fec5bb69a285b7550a639ece96952682b7334b68c65152e893b1c8100c694d8c5cfe26ac03c1f3914e65c84f0e777290c76f6acce340bff66da7220f73175e94af52f9f19e61f80dc1f35716b3f48dfa5025c9ebef7382e055830f5bbf15c6f6a95032909c892c0f89c8c15fc3ea40a20ee1a4529b521951df44d9d79d74e0c4c2e0fed849b8785206dbe62bfa2ca21087a912e9b184551659cd8a587e95b04317192596bb0b7fc9f7bbb6ee049c8b02fdd758b4e79882073b71eaab18aa293701c17d55f9ec46c52de1e886b6750fb0fbcd64f4568a210ae451e9
+SIG: 20ea9368a2ccd08bf9cbf48d4a2f7d03f0db08a54b87679cda03e296af9ef378be9b8f04b4065b009da6db016f3df9db64825873e2fb4de30449915cd73c4609
+
+TST: 539
+SK: 85e0a80f3b30c20199d9c1ec662e392fdf1546377343f12471db2a0310a705bd
+PK: 540a3a1d83672e495034cff408e1fbe82e538f0917e8a1c7d17aab58e043d3c6
+MSG: d2802f1596f8383b64edbdc594060bff0e7013d5b7c85d830fae11aeb34dd594959da624e044474c5409c0059673bdc61a671ef5b0b8a26f30100b3b73968d8e4d83a72f25b513448d2f6b6a4475fdf89e31ca9268a30705af3f649e3fe01dde0cf4b29ec2da5436444af091d62730acd4cab608f0df26f088c6b9b9673794f0747dab2ce190f90592009fdce5464b3661b7e8620bad65509a6c752b727a8dc8d3efa584fde0272c451d65a93bece4f59d87dc6fbeb451401e3e2e003c6aca7b3d3f92719150c6778f015aff2a59bfbf2e91b21b0ad6877536eb54567059f587f54d4e2a6fe1fdcdd6a7fdcb8515575bcc3705d77859352fa0b044166e3c318846a5df33563003cb20bc942d30391093e8d583e8e64dec570ee1c4138762f6483898d32e2032bde9bbe07ec2c3eb47d96876f0fc0f024d753ceb34ff8480b4cf576230bb8263dd80eeac662eba31d8a61f309e175f4c0143e28a852b1c3061ce78efbd16a2873dd28198a46ec0a800b30dc8a93b8dbb81a730de450b864dea7680e509d800e82329c261b07e72aa80ee16ec375ddbbb6fe3d8d47b0e3c5a9f23c4d20b724c1df59835d830dd22d10403d8f15c102c4b3769c41666c3ab8c7e80b940d0bbb58652d10a3ffe8d44df1012a3ddc4e1c518d49019f7c5d3d9f95ed93a319746d1e543ffa69edb49bb3439f8a325ac6a0cb4edd65ba60080a0447c674faa72d8aebdb5d2544f2f2d847c72c2dfa6057a690adc5c441a
+SIG: 185ef2246aba2b1a568032c7df93c667799b8a521a6f97321ead5866b4cb9c65b64a1c40b9b6a910e742dc32a7e66d11ea45dbeaacae9f09511b8101f8af0c0c
+
+TST: 540
+SK: 82a2c6493f11ba80e4b8b3b43841be970e2a10a94d2249d8ac6f5414cf5a3cb5
+PK: 4c2ee01cdea07db3635f5d4c1082b92f298deb17d0f905df71b66fb2274eae99
+MSG: 09854d13684950419e0bb16464e09988905c0217183aa1e48adb147bfcc2eb57c2300b0dfc39d4896655a57ae20415408bb5f2c238013955f0a4fc782e0c993fe42cb08cd8cf415ccbd6cf1cee2e8097f04e8f09ae5da5f415b16c2cb30cb2ab6652ba50ebbcae4a59e31fe11e7ef3699ca90aafa586bb242c89cd2e332b2bfa2f8142accaf436f89b6453bb4805a1e7f3ab6270f0daf89389e717d1b70175ec5707c8f512c40ab924c457e9f0914791750dc292bb27d6f63ba8ccf54b90d3eba7f19eb300d9eb8f3b72032ba93037f552b409b580a5f65116faffe0fdfdc6db3881386c3cbc16b67eb25763d7ae3aac0b85aa1e9aa22e4959609d4381e4b6d7159ff3e3b2d37b640f88cfbe4f8a77f8016457228ba6d3af5c4e33125d48bcfcf3678c163b698e52e85617ab1a75ff20c690ab07155ee757598578072d4a09dfc6c6c094ec048567d513ce2b1834e163df1545319d8061e0e57f58ef041b7bffc4966ac1660331b97abbc97be21ae2bc58c6c3274a8adad5fd2c3bc16b92e1f8de877b6a26f0c6ab7162e8aab93af8d85918c13d3e235a273748c62f0d22cb1c93e134a495b1b5ef8f1a1134512d53b7a211263177f7a60bdf474691f224a3b5bac4006db345ca6725f5ee703eca0dea10d712676f63ef3e537e63abd2608cb4fbe200e15f18209153496072908044c95a4e9c5356aae8ed5f0959eac091e227a0b81f5803276b3b3bf4b6865a55fc6782f62ea6d63990f9befe01
+SIG: 68a91d4f8d241c1defbd5ca9e9e1ed8274419506751c967947b10d50118bbfabc765ffd7b31a0167c4fd8b1175332412df19d8aa1a909590861320923dbcb204
+
+TST: 541
+SK: e55b343a0fa1fb747189cb00dbc3a6aa2dcf5b86e57d7693f307420389761153
+PK: 23a14460ea983cf997c782eb4582ab3c8aa6dde53325b977b78e33d2dc5f27aa
+MSG: 36289b5eaff2a85a7c6d575bd15ea594b2fd8510874a469b52109163696d85b68c5b211d2964efdc66e625abe8aafe4cd9220cdb341107ffa8276ed4b370fe376c1482687167dbc8f7b205a3f3301a1664d9072877d9f98b8f69831301df9994717fc88969242391d9b0517d6efb271701eab3f4a9b1204213e8cd13f9d099048b8207562f2e4ebc653cc65e9d5512d65b41022c79b4eb37298769aeaa6efed69e9a8cb445c7012274de62f509f4e4814adcbf4453b4fab85d7c8fd845e00830ef5b7b1e63c67613984caefe915a548e18e505622cb2b39299f427f4d83983ba2aa00d53bee1f59aec8318c5ea345d294252369792762add3e56fcfa6e7797f028c799479045edb2e205eb6dd6ca04eee56f9496d2bf26099357c973835b9936024911e4655d3e22c811c8d4dbd1b04f78973f077523a389b6f28f6f54216142cb93e33d72b4a5052d27e4911e41e6cec7bebe1b0a5113e6b70b479d2abeedf69b7564e5a573b352d16cec890701bb383d3f6656eda0892f8ccc70940f62dbe528a65e31ac538826c138ac66524e331637ba2d37730358e6c732cff8fee940afd22c39ae381e5d8826739b23fdc1b80aea5a62a2cf0ff1525e446cf31046195051d58503eed1befd793eeae1d5d1b62a5c9845157a095cdc08a1d77ba47e84a5a739980f0f5be7aaec9a215b204b4bb7cb1b386ded58d7aaf7285341907c63336ee3e6ef077ad111b974e7504bd989f566fda1b1b59abaa91c78bb40
+SIG: 07266c18650ecf0632e225624ec4c97fc387dc374687a61956dccce72894ee138aabc80cfc90c9eea6dd4c59af4502ee29635a92880786678b14a3931a69f907
+
+TST: 542
+SK: 3973038fa2ef6a278d3c1cff9a225669e465a69d0750503de748c002dbf9278a
+PK: c75e77c78149d9d2dbc263ddf8ac4d654d1ff455cb1897e1c3ce31b94cfe3210
+MSG: 3392e02f3c84661eaf81a5ff04357f212e92361c5c220739d96b4d3d9c22d18df48be6b55126f581601ffe0da63f38e19cbb12726ca0a6aa325567a003a7849d06783992eb9eb92853297d7228dba980b250bb110f63d0b84670e5ecb319cbfd61278f1f4cabf1fcb3f701f12f6ef8d3cc4282fcbe589eb5659503a2ddd8bba38e5eff092dfaf539fd804f21f73a90adf569a00bf9d25a9ad3a63309cc6093142471a478f0b8992286de023c68efd49987ec270bd946f6db48f684f1c2adeee26d68dce95a55e4cb27bc60523080df6ba2b199996b1f1da6920d1559f79bfde9fa1a02deae1480c76f947f9d213fc43bb2880a1b4d03bb14f5b044a0fd83ce0492f49ca3af25211b86faa5735ad7feaf31a1a7491e708b41829d68e32414f68352b71d1cd23c8e12fb02da711484f6ef97528a00d24fcf91d4e06e9badae9a44dbdb3f778041768d863704d736810400e7f2931efb85c8724a593426aa2af1ec5b664f85c2254896fdcf316db0924e11aae8d683e9a021929d0a9d6fecb4594b1b3fbc16b176d29d1efb1819a4a423fbe0ca0559c57e9e5449f14bce91360dafda6a427ce4a0993dd03082ddee066533f6d3bda5660f42fd7757690d670598ec7096f475a01a519950341a831fc9a281c0947a863f1f6e03bba774de77adc23fbe525cae6ccce47a0ec4979e8bec86f332fc6a5736e3b98fb332e9e8244e68a100455e6499ba8dbae98b92ba3d9c6b4ff980343e4c8ef4d5a4aacf8b1a
+SIG: fc0c5453839ea99296fffa501d58366628df89f616766942d5040a056056dab18b4405c04abf9059c30868d79c936cccc84c4fbd6fd30b60f8bcbd7a66404202
+
+TST: 543
+SK: c71cc10ad2d443e025ad0625686b123503e590193a2bc8cc57a7b9b4158de6cb
+PK: fc06acaab53ad08e9762dd11cd2122b31599bd2598ce6f248795e732219c2fc7
+MSG: 2e0846536dc6cce19ccf82dc2d0cd21bd4e1ca7bc317067af8d90ee4818c8518bc3ef960ce112a41d2b9979a282ae13d706a005e0034f06b39ff4b0a5afaed70b561bcceb1bbd2ec19f97448eaed4be620e36a962d878c6f80172b9fad43eed07ff93db9b9ca2262d5a3c229c54e30a45e73660892f048e363f37144ed1921f72992b4d01529870cfe373b7e7cbedaf969269fb70aa783d1e74417c7bae0fe03d951fdb8c71c62e9be7fdd5d233e39f46fed057e49b6f34068459148da3d424161ad2c869508602e9c0bb30bfb88acd5f4dfdffd473503cdfedabc4442b743be075e7c6f610e64ffc2e53187745cd719658fc6e62a5be518437c5bd6a4feba94ae3f44f2f29308e831feefed676909ce5e80c84cbdcac47e47d27c9712a01f6bc5daedc02e6414407e911c0a5a53e5328a5a5fd9f040aa7fb70b79b31cd1b6fd9bd5029040bd22ae222fd2f6870d07f435322639cf3193ca5709b882b07a58f952a9963e568f8c5a584a6b9e275c5c07957a4d2cdaa9f1eb444ed1224bac6563b2f9273e80301d44d50ae383b597213b00da5bf27e5d1fe240cc3bb65aa5030d651b6b5b31761d53ce0c6d74a15dad5479f31c915ccf446659853b89a51a28ee8976853553fd2e02fe7243538d00b4ed07d8b8a80b5c165cd46341ffd8163c555702663a4e6ab2952b7e7443d0f6b123b6946721aa63e87b1155eca8a6a1bc9fd25c6762e52742c86bca1ba9d8370415244f0edfdbe0932b5ca0611509c9
+SIG: 2eb33bc2d5deb7f3a2dcc377b0c6a862134bf3191ec40fc128ac28abf2316ef1401649b8f4cfa1a936de79b532dc043b6d36024b4c37bba29290ac9f449ba60d
+
+TST: 544
+SK: 0a4f5e1670f1e24bfa37b73c994330b36e7daaf930161b78a4a84866ff25e3d5
+PK: 9dcbba903981594c7b677ea8002001d664cff7ce8e5cfae58840cf74aff0d3a9
+MSG: f4b05b3efdcb1d5c07da950c46565528440bb48835ee4c13f43d7a1618de119ebbb259ea7480a5048174faecc1055b32dc01ac7156344321e8eba698f302ee1643b5f04b8e7ecca63b91561ce3514abe7851b6fb17fc943bdc94da308c8e4769fec20fadf4fa8e7f62b6ffb5f170d644ed29355ebd22cb3aa1486b1e367c729dd3f79bcd40ffd08af28cebc8d776e1a483e911d79bc613e09cc621cadeb034dd6f72374771985127f7a3a1aa786a523ae6e34ee433dc30c375987cff50bdcbc997fcd51c94567a67aefb6ef5edf9bdd65964d464be9ebdfb88c0e231b07ff6405c00f82531e961bfc5ead266bcc08718878cafb1d37536f183e48bf38d3f6be900252d1fb419e6a2ac5896039f63c31401fff932ce9814b085ab20416972a2b351c815a62de509674628b0d3566fc9c2e0a9237b93f9bbb2deedf02bff83bf6d868b6399326d4809d0419f31b2f3a481285b94078b47061ce91dad583dd5b13bd010fb30f2495bb70420183a930159e4db193df6acd124423e039a67f15688aec50c5927fb271822aaa66f294bc805d3bc7c8341878a541009f30da99fcc0085079ce7fc55e0011685562abdb3a9471ffde6176300ef5b31e0df609a54a1ee6624070da99c8776891fdf6aa78b4d55b1f5dadfc061add5af00fd3adedb448c559bfff204068043a5d1d6214748628c3ebc5f0224326ca18ef048425da9300133fb695d4f263165ac22f3619d405af271a71a9afb198bf631241d3459b95398
+SIG: dcf353b2b99a4ef45f3fdf6528632e8abdc433342476a8c2b37900404a4e333d387814235757ef7ad03858a0f35d4615e8aba484fd64f1112ec1b1aed2cb640e
+
+TST: 545
+SK: b855c81805c7087410e69f96b0240271dc76c1e4ade38c6a9278e3c94fbea256
+PK: 6adb025a40260f569884b8cab3752b4f255c373e2b424b6287ebb510fa06fff0
+MSG: 85a9bdb70a6c752897e43a91106ee9a99c2ca94ff7b4461a44a39174c17ecd99df46eecd81c3f52513dc9d547dad3721c6d5ee1f8fac0ba5afb3687044739ed535b844008704c09fe1e5d785d4c9c3d0b05889b9c20fc3fd68df12dbeb2c34f6f7ec1c6fb7fa811ff846b5a61fa5fe55379ee63abcd373fed00254ebd06bc8b22f7fbf2f727a5fad88514159e26d78dfdb0957f6efaf51a8e80b585e838b9621d051074a4f5867b4ae2f2ff6d62b85bccec0b4aaa4791637388c0901fd49dcccce7204859f81eefc639fed92280456e69a1509b4b1bd7624447d862c45a0c8b0c5bb2c4ca512cbc037f51b780982b183a5cafa15297585c947a25be8c2240ebfb6868ece5ea2aab2c239c83754c7d594b3725aceef344ba7e6aef49f7f313b0ae82ccacad387a6e9337f05f8c799efe7829b27b4d5b201fd5ae5834351690759f3ea175fd4741be228d807fb54df4a741038faee47edf1f561652598601f27155fc50d9d5011433711c106d4b60785a5cc93b3fdd1dad70c0c8eaa33f1512e35a541745e376c15167fa8f6b3b2c4c3a366fc41497d297357816ae795a804c980e7cbfb0c74d8835d929ae3bb52bab12964566d746bd2c1d132b6233fa34f75e268edee775eb3ce132e6beb2e8d71f0c8762991cde4e26f71439dfa83978f995603861bc0b1d9060bbccaccf86f8745ad96994d5d007d52e83aa5e69412964bdbfbe4780aaa8de41be1298abbe9894c0d57e97fcacc2f9bbd6315d3fcd0eaf82a
+SIG: 3caa813273e753542ffbfeb21bc3e2cf8ca7d920faac7c49dc2aa9911768c7ad43b38b0236db27f3eeae0b1206001e665a607078c522ed7a9dc4688534635900
+
+TST: 546
+SK: 95b9c8a6ef80ebd5cbd47a04ca54387373df4d67a2b475597765ac89fcf93e93
+PK: f2c947b18adc3ea6a23f7abca364b9853ae85a2b0c8c26f0d3173c2732c3c7ff
+MSG: 7855bc392630ccf531d3061606ddfc81a0fd9294c54791b5f9559b6827254aa1f25c540b7d7df3ec9cdf14256629dbcf9b725feb3412ebf35f0ef9379e4131cc77e0f0fb6f7459a738361a99ae4ccb2b60a99fe92bd6c3a53d6f454ee9005bcec5aedcfa82347392efcf1175e578396a8d800daba0f4c2cf4d4913b0528620e3baa0f6d86e0628e47c0ca26df3b0c788c4e16557f7fc28df820c12fbb6ffbfecb9829ddb65ef8d63e90d68fc7194b5b885913f08edee84567647ffa3f0d0d325d082600ce71a2345c77d65bd96252003e5c125a718a07370c31b5708075cf1837c6925635cc68dd1b751e40ab608b0d9d8852c18d3069219ef807b76d288f92c29a93e3d75b5b2e53681671d3ae0145ac03ccad3162e44703b0401d3eb167cd8ddc1e1a5a326b728b1e0c00a94d86de61352a661e40897175d28d341e4d1d9962e35f4de18a54017611ad05359ce08b97bfedbfbe3992ed58ed40f517aab01c0fefe8b63643da1a454152730bf99af8740adf98a77b8d73adb08e609e00ce9b1ccdfef3e9a9b05aa56e0bc79b6bbba80dd8e461af7cb202892d89b2d05a4458ab3fa54b474b8f8f581795d6c2739e59d0fe062400bae2d2d534b340bb8e2615777a9a5615bb2cf437ba525e00e7038f22a57882ac520b333e75c3c92a8b9f0e37f671c94b15dd8182a08d7c143e94e9262b3cc5544c294f5f335c2b28ac119fea00f9634db063993988b5f150579c7cc25b6a1fb0dde94804fa6ef66ff79fb9107
+SIG: 2c8bf543e2a3e00415ee4f107b2f5a6687176f5d521117759ceb561751bcc77d9b08a6a631f6447cd901de96699aebb168bf97500dc54a0543ef14e4b5a08106
+
+TST: 547
+SK: b786ccfb586d43b8c46bb97b96c918731bc2cc119277f123671e30148158d2ed
+PK: 90c7004600f3dce409fdeadc8ed018f9ea263f75160a74ab54f4c2399a90ca78
+MSG: babf48bd55ea91bd0c93b970241b529d9db43d4927fea5f1a1f7082dd6cb50a52b094b3129fcd903a44fec8bfdb5c86c002a2a452887ca25a60eceb5e1f9f5c93dc59423c7afe747c6bf407cacadeccf5d787970cb0617bb3cfe7fd17563d3a0dc91631f71b84be24ae800113750f031d01fd05364b4f27f86f8dc3ad7407e1ae9e768154e3dde58e867129e2474547b408217964844858d056b31c374991b7f161f52f088b806e0f313d68a15c5401ed55b2b77deea586cb054dcd71af2ab6ab11e84b30c539345de3eb43fb7b3a3b48987c3bfa70655d599f2e31d12ad23cc96e86d380bfda812feff3dd3024292916907022891e119bfc3ed9c25546cd19fc992d8a61e6059ca3ce7802af1118756620b87a7242bd83897c94dd5a36ed40fc0f34c2c93110b37d17dd96a22062590bcdb546742ef7218adccc5ad28f4fce6ecf705835f4113d82ea533903aec8c3820fe4b4715f37e20cebc1e71519aa0b240b4840aa4fdcfb52467fedd8f4d1f9bc33ee114f3ef85f5fdb09ca884af388ad3adf84c793f386efe6ff8a46ed81e5d45a37c25cd80f2d7363f43ae45e3772c0df89f11447939806c096ef933a13944f0890d887c2e5bbb6b12ea950b09b8fe425289377352f35f84cc4dcd4d7a449489fa9251c03113489225809cdf3cb63475f10d341709371c6fd4bb7a949483d1bc2b31ddf4d963a07de7ea5c3fee9a0e33f0769f2faa40612a546974bde0b7339179e4124a447bd42879ccda5c8ad1819c53
+SIG: 52ba9658a1a0b3e98ed5209e393e420066a37d3714daa73d5c671d33075a5f5727fe4e081ee0fa3c2133dc953a2da620291371f00ccb57d8792eb596a2ff8101
+
+TST: 548
+SK: dd1a9774f7584d8589b19f92ab6939ac485602fe1644cee2f6f3cd60fbd58400
+PK: 4bea7d0b0f4bd590f9e3579f0c5fa4cef4d60a49d2c437a0aaead9d43a73d4a3
+MSG: e5dc3ed26c1f693cf852465a05e3048b505db5116d9e31592205a9c3d4720bc10b6c20639a0ee2f0e147225b5b19ea511cfba0c21aac10715a2f232f10c2c8aad41112b6b012e75a4155f8c6926253ca2b4ddb7bfe7f86e90a53dbc0cba89e485ceca8fd26e50c7f282a253573cb0a8fa88cc44623e82e8fa2edb6cbc7538ac92c11e4c5b1ea5f68966d15d93c34f396d27572f864382ab76a7be65a557b139766368a207d98bc0c20926370dea27048160363ed85f4099e7cd66d12d0988cfc9e2f16aa565f8f33b39e978c0587371f92db5056317564411bd8a3b6fea09d3487aaf734034918ffed1c9fba7bdec6fe68876fc7360cc5629b92104027fe5759c5ab365354751e7969116c3b9a21b152330a96a9381af730d17822d78ad6ea860006915b5cab447a759372e05d495ebb328e75d248daa02f5d2eb978d2710cf1c5fb824876770e32ca6de2c730564892415bcb53e5981d707add961c5f37fdafa1399af8aea960458d2ca310553f7c9866ccbe8e9d88e08a446872ea66fc308c824514b7dace0334db735e6f14c85b5e619a5d605648a881e876c78dbe0657233d4f7f3bfddf63b445311d6abc476347ec4fb43c8946f9d17c369381d1c564ffcfe2dc7b4726fd57387f0b44db8ef95a0b4e32a7bedf319e53a9e7126c2811f9829d1f4ae9abd9d5f42efef2075f47051c63a4f8202040ec4723686382c6033127c1fbfff4bc82373508752d431dc473f52ddeab0342dc4f5447f8f25738ef65d78556
+SIG: 1959bde0a697a63993ec47d158223739fe65871fa05870d7de0d38086591202a51b174d1c6182808c6ce62631d81dba34ebed4af2f29b06c00a57a3cb6663606
+
+TST: 549
+SK: 66f5ea8cdb95ee1a75e32467d7c83c59447742c85ddd499c43c08673e149053a
+PK: a8ad04b9c144b97fe867374d4fe57d7ec0c249183e43bdfb5d52644e7fbe1df3
+MSG: c0d01dceb0a2d17191101879abb093fb077571b521be7b93a117c696c0872f70ea1139ab628329ee5655fc0aa77e8111d2fc884748c1f267b9eb09dc26f57fc402d61ba36f63f4d589aae63c76eeee15bf0f9e2dcde4e4e3e78fc6c29e3a93f3ff0e9a6e0b356645953890debf62dbeaf4905178d4f0a5a592c19294eeba7c21cf8f1bb3f4512187376de72f1136a48ac2dfaf32d0f37de064592592b6e1bc0c512cf4d2d85d16797853a80933b09c2f7bfb9e54a69e51a8e423a91c3e5fdeb4790533e87a4b1c0e0e23a9db9573ac17ab6ec7014d8b7c4486e15725f8d264eea3050e835ae0ac449db334502a6d97358fa859106ad0f6f4295f2344920adf9355a6949d8d145c25628a46a104ca099bd9dde941119c83820cdc2cb2d09722694901043c37cf0ae879be2030d0373158b9c4b0718298be45f630f6fcdc190f7b2926d87655a18bb797ac50757fcd3655c9e41d5163293d9a13d984f591f75b7e4e5cadb64c4c9fdfef76cab69381d0f60b483f804bb3b33364df8cffacb3c9b13ff4c8d8d4ea40766a7d42d8256c6b1c11c191daba1b8ef21593e47b18858ec19d817358678d8548ff1535d5fcf4414b6a11d34a3742f8d7149fa681383a9408887f1c0a98ed521e72793277824d6f746d49b63d444e312e6d9b986611258196a5b012b88faa29f9a6c67ed25df87b2dbf0dbd2dc3080c5b8d15a37d34729098ed0de92d75807429b2cae5d7283c4e5c9bd196d1ad436c7c34f3c9466e5cb3196b443f4b
+SIG: ec5c7e8392fa8b61bc829681866e45ac8be4b5b7b6a822c1bcd0f2cc2c8c44c33cf83fa42d43a2f1884141b4a59aaff47f9be07e632e2018759324eac9d14900
+
+TST: 550
+SK: ed2558e5c56784bcfb4f4ddea3c0dfbef8d96ff1cabf158ec4abe60aff66999e
+PK: 1edc991012ac6f888fa7e6045777e9ba1d4c03c40292d2da6b722b4ad0a3ed74
+MSG: 2c6433e9bfbf4cfd4e071f15ce6b129d780a4b3de014fac034e0d44ef772e2c8b0d6a3481d7b3ddeb237632673553313deac1efafe3702a7a4411e12bd341e8d8e96c59c5e30c36807a8385a538e9b66907d6a528400bd9f95eedc5216b28fd7437d8f4a029fdbdc7c938e4eb9812fec05ea693229629ace6acc7af6ba4c238e7722f312f7896b004922f7067ede106f8e70154d783fb41291f3c7e2e4826045b5741bcb4a8838f87a32e0049704e9b53234c224ff898a756e529134c1a9bf50fd029819b2238b60b2aec1128f34d21f9d66983bed398659d808b67a2e501b5a1f25f71f0f0c1eb2fea0ab42d82ff3bc9358bb20c27520c144cf2116f4a49cbc61994d2d710546694c4f602dc406e0b0c27e5f5e64667e95c2ec9df2d6529cf53622ea10b956b345ec55b6c39a1e6ed88ae66e5b457179425d1a849037b07c46cf5f363301095837ce811bff4960bf9cbd15201c1b6740bd70102140744c3327aca9d6d6d154936798ac381fa639db436ee8165667d538a6c74a233c124bf604fdad51984c4170b8200d2df73c29bb1e376affc314dde3e86af9d2c2e6c3a6524d321bce93e21fc965564faf77d0cd1accb4d7629485f564c79f4d8a2fdefb465454028c6dd1428042805370743363bb18476a3f2320db2589c72133cf5e29dafb7d07aa69a9b581bab5a83f403eef917afa14b764c39a13c0c5ea7019d2fdfbd7f3f7d40eb63b2a084da921895fe48f4fd594017f82569b467ab901169eb5da9c40171d5f
+SIG: ab9e01166524fd288e5c689e56d730d4983000551030493334a3984e2223dc9f7a5b910c61760c6157990a4c335e348e3a7bc8223e09c10c5e520c8d61aff500
+
+TST: 551
+SK: b72798b811e2338431256d2480fe7a3663acecbbe6e6c1b9191e9d9a22447940
+PK: ce491daad296b55727b09513df02ba5928a371737cd35841e5f735acab7c5df8
+MSG: a5d46298b0790610aedc0970fea2a7075081847266f22f12478b93d7e674c6c517f3c14ed061269d170ac31e2a64f9754a565bac1dd9757322c11132e7bbee5f32818e0e3063ab64e552d09b0fd1757639b9b9d1c770016b677465872b669dd48be038665751674dd2f40a966a26748fd3e5dbfd92265eb936f55b094286c010629904347cb4c526e377470aa96e8169a6f211633807a50030e7ff68e38911b3555e728ed8590b2dc45fea69945cc0c9a3d3e6c954b3e80106a5c91d3d22e89e8c0e1de902058e9cd0f8ce806eac4f893ee0429900fb5487b8fd36dbdcb34f2d54fc6cc74a923951b863da70f1b692bf0438484366cd85eeb880b279f8fca9d3242c558330f1ca57c6a58608cdbc0773e16082bca964ddc40347da8a36b2a9328c2f46609e092fd64b4134eee1d099813e1246489e8ee5b19b3d3b891c28f30b38b6a28ec1d3e9b005dec9c63f8b9813bc1de4aaf995f1779dded15c7a430d70ca46e7cafd4e9a543804446ab0807d64f255e201ef428a474dae8a0a75021b62ad3988ffb81cd8221b243085a0ad046fdc16c67f17b9f81820095953a5b98acbdf93ebcf80bc9c99af5fbffacb61a9251c5aafdb22b1129bfc60c98e0f175263bdf93dc9a08b8efc2e8cdaf0f83d6c49ec901645eac5a4ff63385a6f1af2071897662a372219c9301f545a2ebb8f5917db7f29ca13fc861af38d90c35c03ac9184c122e57b057cde426fd76dca79e25e64dbb41c8414a0450da4905b902ae98d2da4ba792801
+SIG: dcfc6fd47799fec772c2099b3c6437246c3ad07229fc740e05311a206b18b02ecdb026c926f49c6552e347fd35dfde06cb639a797c50612f98e2478a92aaf609
+
+TST: 552
+SK: 1fe7327ea907d3ff179b117811d30193fcba4c347b90657feed98deeecda9ac9
+PK: eef301b16fd7bf3c7b640bf5ee8700ac5a87169eab5f56015b3f499d955e07eb
+MSG: 19a832f26fbb0239f0d9d26a2ebded2403c2a406dd1f68318d677afa64f35043316a5efd729783c7f9d18c09824614652091886cc954be9f9312d4586bf36f3035ac703438b0cfe3dec5077813c710d1447561ab6157bc7ad5eab5b0c0afdcc9db77e66fa8071366829c501096c3d3a938218a6e4207109d1eb81f7d88bd6fbb2aefb1adef3594aae57c46b7b984db9468cd962c6184fb976f0e2aa84152deb1c76aea75ae488442943a80ba7d98a28cb864b5e87cdb284ad6e8d7aadc6b75d69d3bd345783b3ebb676ff95d7b4191e599851c9628835c7c01197e7c8f86f9c8fb49fe3e28458ba9b0236219bd46c28df6532496994ac9ba733c0105a02a269a2be8b7cb40074b881602ef9247052de9d637089188bd4c185ccae258a2ae9856a2cbf8451117683ce341f8096e1d91e874c5cb8a4e0939eb77373a9a0eb791645b8f5460472d669d8014681a5e778706cb5566bbd4727d1716b23c620d228b5d4dc2b352b423931f8a7e8fb59edad8ae42458729861a98e0c850a77ed655e7fcfe4fe36f9772df1ac3c643ad31db5630d571df9fcc9c50de7622108411962bbf72defbf49e997059c7311bd9ddd5b338a9851938d37e7a262108a291e2016803bbeff4f9c776125ceb7e7272b51c7c33461d8089f8408d8dda92506d5002084d4f414d8a4d28d3694c88630e31801990d95271cef47aa5c263f97b7daca1788701436329b5bfaf72653c166db087708130c5c0d78cc4e9064f860680271afe4c409853c2fad675
+SIG: 9c7fdb53fd606bc7c9c223fe9431e1ad009546d00098812a495197f2541e87f8d6f5da22ecefcbb7da56662a7309d10a6c4a4f7f299278d51bbd11e0cc1b8709
+
+TST: 553
+SK: 5f9dcd93fb140610b0e211b39addb1eb87ba97804877afbcc381388cad650845
+PK: 182a237d878c581933332b4178b67ec408b3194d44e4e69392ef800b267c2949
+MSG: c38b874d3ff010fff1a6613bfa134257b24833cb536de3e74992c3cb01fe3bbdeed97dc3c4596fa44061442bd31a9d4aa8c81e34ad9888718206635509b133b1ba69cb1aa0e75c7a1893c080161d26152acef40f6ef4210e952a49828b5cdde804bcb536cdc349a8e831b4b69d3785a76bd9fb27080565972d0b8fbd16f3f960a6bf3ba0c5b9c404967ec1affe59b8c4ecc650fdde1cb06b70595ad4d325da0fab4c5540a7a8d5ebeacc4e99bd0dc96bde82f2bd7d9586308465e55b1cc388d750486bdd5c7264d54f5614d48726d99e44d7778d9ed0323958ab9858e2b25df2bf994ba3e625e2803b6c6931e7a9926f1e61ed862403ce392ab83b7d1b66085dcc06d82dbf176d016d9f44cdcb5072d004591e92d0459ef05a51b8f54ba17251e16621ebb753e5b1590c02d21e40f4b75eee4602860b9741fbbc0d2e385b8daca83cce68c34a99bde6a60d13ba64347d0a38d64b2ade250f38852c4eda2e2e4f303c3de1a8a9d4ab3300c9e63622879fc8537ffc63b18561fa1fff65531241515a62bb9b08b80af37667a601ae04171793cc83b11adf9c30ca9f4dabc7b401e16a1814cfc750248cc2f77e03f9c4334465ff6a2c83cbb56db4b734751043832c4000972ee3232f929f23337eba5e651e34cbddfe68ba219b632e7acdbd4630a031bf1689fbbc7fbbb210dbf25ee87e2ef2b3cbaf8d9ebd8fc92c3a58d3c05b1385a76c87791d7cd3741b71b6c329de9a9d7508a0c156a9521a9020563099a82b8770ae9a944a7e94
+SIG: c1915e052b664797e0d5faadc78f2a009d6fbcfde03f3aaad59b9f4588e7fc3b21990c5208d3d76b4aa95bd934e88d3c98c591930a59de2a056701d9f7577400
+
+TST: 554
+SK: 925ebe04c6eac49b26738d6c1300f31fd4828478cbe97dab18bb889642e1e110
+PK: cd7231b6eb74e1fe9f926f00d8de2c513d49640525b0795cab893d0c8929e3e0
+MSG: e6c0bad23a92ae8b1d85778288157ac6c617c63363341d777870341bb10a8d3dfc89be4f55ad4f64e83bf2499b69fdf72174d2844e6bd289daaa035fec5bf7cf45522119dc7a8c811d79578c5bb0f6d34db507ad1fb6dbfff997b79dacfb3da50a415e350c998c0a02800aa50ffdfe5f4276d8e6bb82ebf047fe48711daf7a893bdc7537bdaedf3dcb4dec5d24586811f59b25b19e83ca61e5592fedc08ca54473cea2ec121baa0e77fb2d9d765657de67980ed57f2f177858b6decf84ff90212d9647f41eed9b9d0ea3d8d621e4bb4041acc5146e96dfcf14ea962d30c8ccb39ea2be958c9b8774451bfeb7ddce716e94923cc85fbd3a3130780e2b3b2bb76da5341912a4e994cafa19bba19732f2ea402d71d3d8a969679b9d104243d9839c69ee9e955e1c60449788d1f4f6651f4bc9b94d73522ec0cf72cacfcf19f1f03ad6232104b55cbb8b5bb1e21344713d482742d6abc5a957174f623b8495272cc1e2b8315e5c80f947f500c83d8544f7cd4f65348949ef4420d7fc831fa4ae2ee18dbba614925ce1d767c177a626c4527a8154b57292186b044cbf92894253b00fd9343f9e697b1412eba43597eb72a669aaa2d77eacb968c20fe19505a38074158621b606f77d97bc6ebe50e7589293db27fc7dfe631a4bee83b22682a77328c36d9d7d1d891d65217cc47864f680dc8b5fd1a01a0f7c34430f77060b691a1ad213d22868e61bbd38f43f0c8b4da68a58318666c099766170c2db766aaf417f556cc9a0a3934e9fcef1
+SIG: 2c4d69bed5ad8b9584d849cf3df2bac72282b5f30de266b14f533ca96e9550c4b854c154bdc17aa880cf001a6454ffafaa2e50178de21216ed126b63f77f2d02
+
+TST: 555
+SK: 4dd3b478ebdc59472bab14a8cdd0c2fdac5723ee04dd8917c7cfe7a536485c77
+PK: 5bccb37e68c234bead49337de208afbaf611811d965859a06d31301247d66acf
+MSG: 1cdbd28556ec44e8705afda92bd5a53f95d8fe8b0ffe463373633316c52274c11edcd61551e3199e494dff6d906a739e7b324303fc47827e56def0bdcc46b816017c712305370263babd2c71be478f41ce30b1df63bedd3b2e6a519c53df515852c4137bc1aca49bf4c4631fd6564657d11cd83ea73cc3d0cf9e3b3c3e7ca99b4f12a9c9b67c8798148e0a0dc1ef8bf58642a14f97a572135514c10b19aabec25a9c6b35aa4034a57aae1b6d05bde2b6330f251d78db0993f0ca4c26386e3489a2092833b8acbbc4f4917fd3093df582fff71ece219d3672455582609c0db8d96a70fc8aed6798de54bfb2b3ee6c5d328db163593f58019f38f339fd3753f896a4a2cca8c1400a77ea391935f34e2639c560860810bbbe4be1d16e012c11490aa84f2964c877c293b300f43d379f3eba9af391dee510856a4ddcf76e0a0ae06a6a7c0f9c5e3fa1b8354fe8977b4ea3b20661491fa4613ba62f556d5d5da8213d0121de2c8725df0aae048ac891abbc06bdcef3c3effdf5a31749476f814db9457945f0d91e14080056be921a16aa964a9298221b157594973e32969993310c8707e19f3143abc4fda7c8ad0160acf031aba652801aa81a016b3137039e27d6738d02800a93a86f9f5585c518dfa9e7d8ac727f37437e56d2788386e11653a04e165169f903972a01484751e7cb38632590ec80d5fce4541601a0e095785a9ee8d359edf26b9946e798da5998cbb736f94eb713463f79f561759bbcb4c4ac693cabf2e1e036b2d0b0879a
+SIG: 5788e79e843bde9ef11a9dfac970196a567c6308c348e5174b387795046d590a47491fd71d97aeaa78c1615971b83490e8592820f9592ac76269b9d2ba702901
+
+TST: 556
+SK: 074d9218c1217e75823c90e010484c2adb88ecccd2bdf0120aa3edffcfcbd4bf
+PK: 3735ad1919033d1617b85bda04b16121da1d861b404154fa961d4946e55ecd83
+MSG: 6b5aa40e9167bfdb847daa7d2786e28e7533e1d6ac53beb6f69b5953795a2bf59bbf7d141926968f50969bad742a4fb579d3250fb1be4c57ebf4f9112c70cd9f72a00db1c8896fe2b5bda7c7030f497c0b001ea25ba0d447f08c36db8b907c2f2abbbb620d3e8a2c66e4171285adcaadd1c14fe239bc595f098396aa8780ffb80fe1446a07001ec234d82abdcd8100793915b0b3f80d84e20e51eabc797806f3be8108a4f437550b06694050a82931ac40c0a48977edf6ced2428d7cfea8205506de86408065d1a19870fa33a7081037b3ee4491b6e7f3d10b14a30c209159a1c81231a35f0365b47d3e0da04a32c95d98333c44f572cdaaa905d069197f6e861b5dfcdfb9db6c7b0d0cb00f37c916a1c4c0b8985b09f334095e1283edfdd4e62a2941099a2b693696604d994311e3d5f6106683e1d7a1c7e53df7b790947a9a801a0ccd484395f6cbfd9ca4d9804f18d52bb0f946d1a89f97a6fb0680a8c4c057b6062b2b9de7c0374879b8a6a6d2c10aef780508eb28bb569a08350944c82f6ef28db2304db697c3ae1af43a500b0b974803e9f46ea2a02e85ed27dda616d24d6db3cc4f5aed8240b1aea3dcf69dee5f14f95e6e72987bbe6189bc2045f0d783a7b47bfc19830bc7f4e798abe90245fbd43f37c3f036d1cbf1e73dcb1d9daa87379b1106973481a215c1f4f46c1603a5d5cd97b7076f1f5dc789aa6a71e72ef54ed328a4ab64340539ffd164d0ec645f322d1bc37112dc08d8c8079d19d37abb2353f48b5c492f806ed2
+SIG: b1f71c3bd1b6bec43337e26dee655a8d5f4a8dad84a51184b775b686fad31d8029e3876927f9576e90c3624875fc0029a5c10a8a0af75d7a880c6844a4a83a00
+
+TST: 557
+SK: d2ea2dff7af0ba2a6bed7f6cc68c0df664a6b10ce801c42ed5bbe617bcc8b84a
+PK: ab44706344026ed35e21982964f7b4dbbbe207fd27c46799701c19a4d88d1d72
+MSG: 03ab5daebc6e70d352977932a03107879bd55dafd0c6ba7ad9697a17b127b3a74a3eaebabd0f8eeebfc0483d63fedde52deb46a3752449c9c4495c51a1c91f57e3ad2e6d01a13d0c470c5291b8e912288340970fbb85787b8b376d72175250e8cd90c07888bfef5ebf5086c8ff2abcdd12d214b9c45d120873b4602e57a6aab0b828d1084dffaa3651ee35662695b7f3433f4ab530c29ac6cc5bb43eccd1b6898b9ef7aec6d5aec68d5c1114bb5df7820966594c994d640891b8f2dc5d25638de43549d86d34306ff3f574575116405b9e8e286ee0cd978a76002c4435feaac6e84eae1654f339a567d8d04fcfa3eb6a04b9adc666021300e9ee5972b3df5d4d0dd4bf7921dc98de82cef2d1b1d61b797fc9968e118484c41342416ddc6adc4ee5d687d94a40ce572f42a2048668c175cf7b1f24c4efd020554fc6f642e14a57baec23e95c2514306d0a6d33648841497eac48eabd96d04731bab08bf5ea9d43e0cf9a37faafa732869d68e7d5fe6954f8a319ef55da1e178e43e84a3b9aa3ad00c29b1d161163df4b79f288e9391d70a2f8813d66622e8ac333fa6aa5311eabec383ba4cc122815de008877efbe6e12c322c975434afad173ebe24203d916d57578bd2bcacc78f6e2564513f8d113a833c2c226eb97ba2e23361a5d02664ab377f964c4300be2d77b62d9240823a09884df307eff3be5664d72d11ad513e1bc5610dbfd1009db39f0cbfe470555ec1b56b871670793d3b704fb06ee950b1ad2a4d7297ca58bbad810c3fad4
+SIG: 9abdb9dd2ab77b6f5e1b91ba0b613f5f360efb500d3fe99290ef7ca14bd2b330f405a4f7dcdaef4923d3111d40bf0320353386f634b40de6f04de9190ad51c08
+
+TST: 558
+SK: 7a60cdf1870460de8ae7781176d5127e71207faf2f210bd4dc547385b667f2f2
+PK: ead67a9cf34d0ff14e79afa46f2dc996e9ac0e3e076322fbb4009767b133f01b
+MSG: 9dc023a525d01ba3513798b738c79162926ebccc0adf1e57ac47c20dea6ce1375c3d2aaa1733b7f0c3bd945c335ff3576112bbdc10b6783ba654e8c61047f2773aa229bf846922a89c6a73d5f1051e8d96ed36d7d6747e063a7ac602f19fc52e021a4bbc28b03514fbd51c7b3fd659f12d547d0592dd09f873c9ecc6439c7e931ad0e4856be31c605def2ed9b5d13c5942b2f325397dac6c9760e9b1bb0c06f713cb920c234bccfee9f0b85dd020f7988f3be1cc66e9e51babe2fee237eb84ec7eff9409aa91c194e30db1e065015955de9746bba03f7edf9a587512409a4161fa77ea62ccf431602dcdcf365ed6bf0aeddd32f7c844e3a34d266e28382f4062fd4d6f8214252104d643a9bfd8071716371ccbb54c8cc8db79add65bcbcea0d080d8402803fe232df70f76577247a63d5583bbd5642767bc63f3c5a7bb3a47eb12984e4541f41fdb55869a08fade66c20f69a5a9de25f6b36ba18ace5b4ac336bb2a8ebf630ad03e8bb8731d01e84b91d024d117459a74892e93d53b61e6b8068e4f04b4181f0387b4567ccd45e1b8718a2d7d787872f3dcf87a15935ad7daaa744ed68a28666a51a10d39fc139cdfe9a6873076f7c425009c38faee135e513207b06e7ba35685f5072da34b6045b57cd5d1b1a1fdf017b8aa8ebd27522bc95e47908734e41722a767905c5ecc30c72481b6c12bf4ace94d5bb3a3155691b7075b40ebf5968fdd903d8fd3cc50b8d6464859b10f755132c6d9b6dad1d6f14c4185b264d3497a4e549877fe946e
+SIG: b2e08142bdd62b786592c091f5fe6a9b7f30ce134c3b236fbc6dfe6734f88270ac58f6d74b4fd99c22451ca465a42c006db25af215ed241af1189627c6050f00
+
+TST: 559
+SK: 3379d25c1117cf802ec79c06575d18e6bece4c7093dd43fdee03685c70b2fa9f
+PK: 8525156fe29fc2fbf661ba50182be20c8998d941493d5933dca4d8b41fb442d5
+MSG: 7acdb39f1226bd3abffa50350a1497d761f8f0aaefbfbbbb925ff563e38976aa172d407b61ffdfb1cd538a4cd000b57818a0bc92c0e0cd0a5abfcf578300f5f4e6cefa267275d17845da7066fd4e18010027960cd395e682ad71af349bbdad5ebaa0f11a7761e19ea1bef6610743164b17141453b472ae2c8f36ce6b080f1c0745352454ce5aeae11c9d75de3c08004265fc4ca80d33b26eae1400dfd8977bf723a616daeb6d42199010b73e193ab72a58bdd248a7f4111ca50c1de646bfea7b4d5baf0f93dd973ee93649e21ec0c6c4fcca8cd6ff69df761612021d85ff1fb2a95337da4805a76d347ee71ef19c0dffb59f15f650293abb9721053f7406905ae683f96c83a3a7447b1afb14e1208c639f37a9750ba21da5552cc204eac453ca036282f7e0961093c39ec118138dcf71cf2d28fb96a24962b52d3393f880653bcba2c9b9d57b77c522f421fcf5ad75fba9cf3389b123aa97521713fff88467deb8c8991d4b57c1438170537cb50cdcc657e50e5c480e12c0d44939b6399944e7c71e186c2abb81fc57348836d5e57b72b224a6b71b6caf721aca73478cb6cf5fb89071ae3a398202dbb38c30812563bb9a23406657a956d305a3449a60cc8641b62175a7170c23bd5a25f0f12e15a7ed91fada6a4a2f0e7b155a3d6485ec03ce6e34df7e216240bb28a2dd732ff790d2286e200b33c29a31a5e19ad2cd02974badc4bc22deb7504c15241fc1060c8acef4fbb25ec7602fce36a27bb87b6e6423e6b4f6e36fc76d125de6be7aef5a
+SIG: 4c36bfc81eef00b9cb3ab514c6d451b993361e09a4be4b5040926feb0e0d9b52f03de468e7bad83f379154bf2c437a71f754f3f40798eeebd62e55f2be771403
+
+TST: 560
+SK: ef38c3fc74f054ae43e8d29d6ba6dc80b5af848270d4af58844d24bcf987414e
+PK: 0ae1478b05fb329965ea0fa928dcbe81a0bdbb6ff66c811671635e4388888051
+MSG: bf290db3dda8763937ae4c83746705327295c2c248068f5ab85c8b5d756f4e3e34062b5549387261476bcbd1e7331990f11910d11f94607c2b71f65b771aacabdc10f42ae918dd2594ac71051c85b330779c47af00a5b98191b56cbcf7efe41a27e87c677168c8abe9496eb2e7abbd0b1604286ed1a1b18d264d733de87d0d3f8055528c4d426d7f8e6ed024a74140abd354007962a2a97a5c2ff976546a8d1ac4924c09223d348ddcd8710a3799f91bb870b3f46d51f1e7f6892d6b08b991748a037a867ecc39ee8d6462a7614488edd3c2ba615ca2e37854889441b13dc835c36b38653f6598616f35783e2e158384bb931c901b703acb3991fb7aa5ba69d9a5bd0570242961a71a52470315e982e341a61c64a619bd16fe8119aae0d7503ce7d7e926146b91c2892f131669d1e39e5b75e9c72452618099a57dc2ee377be65875ee01bb88ed526fc394e2f5c8127a5f69125e67385ef94b1f33ad52629d720e31c02ae0b582339ff0f0bb07ff2b030f48fa7b692716501ad7773ad3151204a2a540fa9436bdd4202a157309ec36cecbe58b33eff557fd33e03fd3eb19009bd7a2dea9efeef8785567aab2a4c98bd1f2a81011b343a9f20c44c577a452fd54ba21029d4706813b2987c76bb242ab2620843c2260b669ad358efee7f9830dc9c7d478a2de4a2cf8c43da770e288e2edbb6d73bcf2ecb023de6b2dcc6b166e87a385eb0adc305665c5bfa57f250fe223ad7ff4518de39c79e87dc101a9faa6821a74442bfcfdf0a9e63a509e2a2e76
+SIG: 1d3ac6b6bf18ab5309148799485b276d20401c6af5f9b2f6032395a3c2f4b673b7140c07cc26f4fc56a5ee00b0746b2a80da6fdad17edd114920101d2c89c30e
+
+TST: 561
+SK: 7e7b39af69380cf44660e2c1ff308334e8250feeb88be0d43aabe5e68b8ef171
+PK: ccef9daed92523533d4a2dab6d2419f6d08604db64ce37e32904ac77b9b4a01c
+MSG: d4a3976dbf8320185667b5a8236640f2ebc9e45e6d5f2a8d92997927dd9bc5db95f44634bd654eefece10d99d92b46715791645004accc6d140f32a1c872e54aa9a7493af94588b7bb400d94d458d43292307c5a1a3882a1c8a6a78d9a945f79d64b3294a28c3d59d82022b009cc4d2da93a16b071c9ab8ee9a3663d72ed344f151d68c666a4b49652d97a46d142a4741127f3c57f1551c40976cd1381a82aeae7bc5adb398720eb433f0899487ed2378446b1a8dc6a33fcd4537a05fb603ec0a90a27532300242b2000108621b65ab000bc06381530f690d7e56f81604dacff1910715040410aa1f944c92dd9bbaa5bd08ea00c8442df94f085eb3de97335b6005e6f84f823d43470ab1c67da12ad449936c6b55f9ffd203dfd6e3f33309e8a9945a59320e66734c79c4814dba5a1c14095c62925a1e1733efd94817a25ef9e479dd9ccde6ca8adb7a8053c1b55134697504af8053d595b844640b61e93168075468450eb5de0358697c104afa6a3796a509c26b4c277c23fff42df146de55e95d0d4b80a7aa177d99227ecb2a0594deedebb9cafb1a458aca8072cc7d77c7175f610ca300efd7af9388346498c22991564500e0b0aa4d2946f18e6f5375a848286f36954c1ca22684c6928c2a25c7fe21aba4a7111d7e05bc8d70b3dcb4f6aaec064845eef5525f85024c2570f3b78698c4bcec0d71aad5378d8819e1fac44ee416370212dbaaae54d2af2939b82cbaae7f42ff485d45b3acc21090f5ba41ec0da309e52ef2838d1de471e0b7cf985
+SIG: 1062a2dc9cd5379675c04f5e21338dcfb77dfbabcedd62b2607100d7649a05e80871e96123214f80f4f73b0d9b06e2d31f56119cea69da2347da84a275b7b207
+
+TST: 562
+SK: a9048af0c20a125f5d39c50f22b805ae742cf64f1fe8dfbe8dfdaa511aaa576f
+PK: 158655db94b15ca72983877b6db231a5843df5dbca2810a7e496fb59ab7104ca
+MSG: 8eef2d9f5d59709959c924f87c22789767393a155d5c87de488cef50b7bf7da870e3adc300aee6603b2ef08764d99d9e7751e5dce92aaa71aa18a69cc823134e8552d959a0dbb41117e0a593c31833b6ec2172ddafaf7848ddd18d28d0d4ed33237ec804f65938aed8e8a3280d42e353d01be0187b1301f83d89849067b04a9031f7e0f33e3416240c53d9265ed0663959971f417cb5f210cdc5aebcb5e1db7dfb82df435876a6e98f415b0df869f0d8851535375645eef70faec744ee0dc3acbcb040f68d502c2c62c8db45ebe54854a4b36f43feb49a6d1c2c2ea79914a7c23c60baaa67cb47b2178e12dce76b004c87b7b8346efadf380b9e1e41f63148da51781d75cec040e4268820211f3c462501d80899894e79d618de42461d785aeace53ae14b79d33501ed5629bbdd07128156db0725f5b4bed593a952947830384f61df00ee0aa099099c3cd9765a9c1c7e8a6a83430b8d9867c8e17920ad0ff64d8cd2ff5f114388ce6d43eec1715d035f022fa97969e1a5dd9f58d896b17c1221c9e6c8555597235eeda6ec41b0c117612b00c5f0ed1816b057363582707a8aa0d98d4d4be5e8fa32d6c9d278221ef3067b8ba1516d9e051d2f68b7d1b151f74a3534e7812c051e5f2b63b3035f8e5703b5f68fd2d65bb7565e8aa67bfd2a12caf0bc5481197a9ff89d77df7a0e9655ef029b43dd906d0b888e313ae9d1c7e9368a01352d00c6680dd0f1f574a5877348a7ea2c0b9e8e2727510bf0c9ef744f369eb3c6c4fc16adeb6e1945be8287d0f30
+SIG: 18a312b20d86ac339a58ef2b852d467c23bb2cb1227cb15338af07fd04b9a711e856ee5b2c82e366c17f861713d1088c1b2144d1c37d05bdc00d739673852000
+
+TST: 563
+SK: f8c9183f23105fad0c6e5103358b583288f9ff6c7dfc91106d07987ff69ce1eb
+PK: 4c79628c958cde0cc3cf686095b8a2f44b7193c616f51b21b670b038ce6f67ff
+MSG: b1d60595323ff3c844874190e1836e4101409cbceae28d5da81fad298fe47f6bdf44745b7cd0d37131c3ec365b92f5a1a69c09fe2d9e81da10cf19d85ff5ff26f9e7db9f0793b25ab26e6a74f44eb8c4f078eb7ad18e65a16210d5c844d3cef75f1daf44eee558f90e524a032b6cae6c8d23367c28ce1c75fc25ac87433977d597533c92ae65f2913a18907ac7d9543df24127743943fefd9cf83ed833f63ec8367233d897bfa12d466d2c4a9ad70d5a672fc10775ea2d204e636de7010788da271df03881a25c8dfa5af73ee559f81b529b35aa127fdc0ee8fd369c7a0436623986aa6407fa67a1420c46f3211ab84f84466dd58bb79508a1feb0a5a5dc3bb0c1b248098262a064f37bb2f019e290c60afaa1206651a2697caacc3ecc02ecfc077f272e8f75cea71c3bc3356d2b5807276f1955001cfe10a61716b4082bd6f84cae4bb0d9a4b75a4b5762f81079f19d7d19eaff8631c924885bd3a64e129f4cf6b79c7a9829665511e9d85c745eb22c1b7cb2a17a49b6285cce37b3de415940328323efe24a1a07ee87468f6510e42dd206fe7f09e3d433fb52156ae348383115648863e45bf6a371b17e70e19f9627d7f0a58b95c6a4788d5fd7862f1612c0347325b797651be30c3e1e60ea4ae60b5745a38b6a9d4eb4935d6f3cb8d71ad3f39adda5e42e2219de0d381909c9cd317dd4379421a2a84268a7ea7180a64c129be1e5e8fcbbf5ed659e9f7e763ce84f630d5407954f9f755750a6dbf9f7660717de8e2adc1e9ac9ee31654d1837cee39795
+SIG: c6a8bc7a0d5c6185b6ecd6033e42321d5c871bf889be72bd54cc0083ed60a470b2cc0fb4682c894c75b0df95f1ecfbba2d5acef3e1aafe54b9f7e803a1d0150a
+
+TST: 564
+SK: 16089a1b932f8d14995688b48dd841edae3da5cfd2cb16555306f3fe8bd3edb9
+PK: 9ecd9fdd7e0b923deff5d887b242585d9d41cd2c7c10f9c345b39f633f4ab903
+MSG: 58500232388d9aa4b5faf85b0233247e717fd16840de9bfd0ef86e01e61302775513e224125e0d20420ea949f6c26425f70077911f9711310cd6fd8bff27cdea11480c73e8f8b3c37641e7e8dd8607c1640218fec80a020928b93d4d557ebe82ec0bb17538867d2cb14d44d3ea727fdd52820b0da944de21cd5da303d776fe99cbc2648365e6a0a98d4db150842661768be84c68507a5c45d207840b033537786cb21dadad5fbab9c5cfc1e3547de550d313631dd4fbb7ca8f71938627608d2ebf655db4325abf3ed504dc183058f9de1e449312d904c846a184a028f364c028b27eb4946427e31c21e1051df364d499f477bf51e7a8893183e5ecf77d513a1a76b1a6fdfb16be90d74be4c4345a4f9f87ee441a1022d67ee844789f21b0c31adcc0d95663cdfb40a895b922dce8069b932c802fd3ab1ef0ce6bffdcc5653b1cd5257e19a0951687e545faf4aa66065a55c4b4191e34e8047d6a4ab52d1b06c369a426ca2d16b51a0271f27f8d744c711fce3aad9d4ac038ee700e4e971b21ca489ff2b8c778a3721adf47c1ae5a41b9a27fa742fd0f18164ef3c26b8ae7d1fa29b7c0cc4683be65025c96537a12d5fcebbd05e930c3693ebbba0a78adf59d8a3b598a348eaa9f47caf531fe449652db5b20d68994e35afec2c25709055a1de26082e3912d497c647720a3f873621456e6a5b9eb613acb43b66d47d0b954c69e8fbf2c5e634c486e5724930e0b56a516940c8cb0e775274deff97cbb7759ce90a2b93e9efaa624e6b38a39849dca1df612736f
+SIG: 7878ab741ebae2747c7897cbb1d105482f37be2f5f91795232cdfbccc526608918e2756ddb7536b3680c162cf8a1ef38a341b9362bfe5d468b4bce21df234f0f
+
+TST: 565
+SK: 94d50915144c7e7dd0f85fef87eddc2206c1569ed1431c8c5a153e32e1cb2fb7
+PK: 3bb098cf160f3aec3170b57d6add4f56739270e4b3a8ef7966ec30619b299102
+MSG: 4d915f27332dd75051719a24ae8d0e9c30da790999e22d9b587ef20321bee4c07d0a12494ffe599f47f96925f5d92517fc3e5f041d0c709f2a9783125eeca6652997201c429aa6f1ce2f07a0d4a0a18cf20b3e9a4f7663ea5262cad8f949411b05ff5c5edd7b30b217d75d8c86c94e5f92c16734374e8cead61b0b27bb4bf5f43a313c1dd5b83e0ea933b6cadfedd7a64aa5dd5b5d02c695ea20e091fdaa72ef4e7ca40f38395be8bf7a255c6d06a632d7d785d9e047f232aa50fa14529f986f9ef9d7b580a03965b0154788822a225bb5ab3438b89a5c28744ab0bc0b2014e5796acb4935a81b02a04632acb88caa7e39e069c7c8e1758291094a53e362fcedaaa583eca766efebf69b38e8cde9ce58e012c60ec88e8c42beadfa838cfe440fa0c01d659c9634576d7d7a2d3a044f99c6e4263d4c0b374a388a2acf38eff29c777e9daa60d598035a7d9edf67a502c3f573207b119cacac3fa71e2a0207c601cc0dd637ef562bacc35c57042738f1f55815a5268082cd6a508292fa29e34e9645d87a1a2b6e58adb7f4a57fbb53e9213ef3dc873f29396258a1ea546fb5952ce343cee9bbb90c1cda72c65a7c8e40312b328e231920c233077dca34d04f9d89daa9a2f43459165fd102ff5643c7175230b39ec7c3c475650ef131609d3220f5a294a403b1e1c42cfa162cd426f0ae43fd6b7ab547a62b7d5f847403c4e5987953877158cfdee23c04f751c7c86d078e824ca63b5e65543e978b6b0cc689ef664412b01b8ff165e7dbde3c099bf4f34ebddcb4c4
+SIG: 59a1ce55f5a6badc1b9391263620542cfcae87a0f2b9502250cfe4bdcbf76c461977c334a48d916edebd56c21ce217c35a6444cfbfd3b11a3d48fa2edb6eb40f
+
+TST: 566
+SK: 0d81926f513db4b25dfa1e52b5dca678f828a61c7c913c828247c2eb0422b7d1
+PK: 0f32411ef91d4e4b6941dfcaab142ef3bec160983993a5262ccf27fadd2af890
+MSG: a93837522f7ec2e93a2e4b4c8b46de926a81ada2d248bcd33b39b6c95fb62a61dbbeda1aa85a21d9b96a08510d8d3a658cf320a10928695999d2c0d605c7f95a12f56a8718507db0f497e3ead613132ab092cbf19d2260358630358d9b26e68d50ddae37c8af0bb7d2741fd2929c21279a78d10e2c5f3c5bf4a42a3617036d54743647765afd8cd910f81b38ced72390630ee68944a37d29c2fecada1cc59ec544075bdbc14c63c6234b884049000c27c73406035604fca8760b49a5e2109ef91285adc4ec48c819d62d948faca90f62cfaef0b07d6fe576d762bfd0eef94cf6b5332c4d422511607f2facc7ac046a59b9617e8383d1029cc91ac592b52084413032be841baa9bf96251a6bda671d4cd4b125da658a4e5a50f4428eebf2614fb0ce5febe80f721a5f4c0325506d27a8d31e33d86253870dd63c08edc7302b280e9b9bdc28beef05c7dcb30d4c162e9be832e1c785e37551218421eec852c4298213b2f27f8f8c706d391b9c69a56db7ce5d81548fca5fed456f2d8afd0b75f79f85868316f4a0921f0c6639926516b3c3e52a9cb22554546ef70e14c77ecbdcd5c0d59a81769b30d5d131f2fb449c996b8de8ac7f8084f8499e1a56f7cd29db6aaefccae8a60e75616a1f702c3bc8deaa1004a8dae0392a59cee54810c6e940eee25fb2e5d573267044b893ffde378fe75ac2613373d84a0ca8187af4a3358e50a994ed03367de645e10390fea4c33bb1a6c0c39858b8db4a69fe894a4223d45af69b36c6117c4dc25de49a63017002ba9ae551ef9
+SIG: e0cb6c71ebf8d705e50cad9f0b8cba3ecf4b9e3793400092aa5b121e7dbbc8bea71df29528ca9b47abf87c198a8dc4e14d5180ce932dd2114a3cdaa5552cc205
+
+TST: 567
+SK: 6c8c53b56bbcb4c0a25dc40c18240b6a5c7576b89dde45ef13fb158ea17f8ed9
+PK: 238e51d6a44fa7ac64268801261ea35b62638a006cc452bddb9f16fc5803060c
+MSG: b60df2944ba015759802d3c587bcfebe521a7e77b9985b761c9676454d24a664af0b0d44225a557512e1c1cd7dd8335c8f6adf928e18f89fd5eedf6f411dcdaf996912e8c3e23d1cb95eca4b9e24e7539c3b98bf3d07ec251392096c19ac5374dcba526132b6d9bb8f6c859ce985d584c7bba5b02a81034b6d8b521bd280e50d77daa2b2413ed679834f8161d5d0573bdd476ac3cd0a3a7d8db45334e89c00ab66bc368a07b423e246434636272aa4e4637a5306b2c3397992781f30238de79ec104acc7200defad960883d391443e70efbd22f1cfceec5112fe9e8e13bb941c083468dd71ffca976cd51ce161793110ef00aff5ee2ccb7706a512b85beb94ac49d19afb6333655cf3aea535a6f9c75e034841e763c5a249b4704e1be78b0ecac6802c343c1b7e7b5770de4c93a3a79c46e6835da8ae5db3838e1796b564a480a4f290b60a1c63a725ff3fef434d2a0b3d8931978742b525c83bae6794ae64193794b370c289ba35ed79d37072a8dcfcadb46d5ffaeeba1bfd4f87d766b504e62b4acdd77446e79ba994d6dbf4765ebd74b0365100da56162c36fe5a95077f6b4265e81796b4a57443782970b96cb4569ba985c55fe3a718380bca39f16624f8e47cc63c1b6fa1bde1aeba9c51f94b702b13108cc1481d42e6fa981e3ebfe064d2dca7420c74595792312ae3fb9101d4b66d9916dfd6c13ae883e661c628228be9794cf60345076db26184b617e272298cd4183f27bd52d40510bb015d2097d4cc76e76c0a62bbfdaf53c7268775bbfbdb8870eb9bab
+SIG: 4bf1e7d49cd4d5c3c1fd4a4bc48ff6b6e52fd9510a411812296996e4fec56be44514c567d1d33477bd5dc083c3958bd95bfe599c153f21ae26252967b7326003
+
+TST: 568
+SK: 69b320fbd4774030a29767a0cc1550d10b749b44d619d41dce1146f7ac80a755
+PK: dc508a79c6b8ab866cd117a5a84dd9d931fda450bec29335344d0d219216d65e
+MSG: 217e33f88622c96f8d092c9e26664fe9efc0d8d2eb59a036fa464cee65ce4489caf903dce17afafbc4f18dc9bbfd6c1a4be7b83485a6ca947defb1d35125d0773962a344a38b6dca9a40c31c1c4eb2d7f6818f978e573d66b990921b92b777471a4f6f05477ebc353ace1d86b00cc251777aaf6af3aa1179bff78df5048e5ef29968670e535483568d6bb16da829568f81c799b9afd4aad6ef085252c0ce3ac01ac21a9ea69bd58eadc66968f55dee386b653f3334efc398ef3c37a38ce93b21f107cc54dec26f53fee5604eb09a36afe6b665b6324a84c7da7b7dd01d9278e472f15a5ce9ff0fd93d0aa0604dd2df8d5bf6a912734ec51de77f0ce099ba11670210a6a206106b0ede2ded858a6bc411e7613e6f80e1aa52c323e30fa849951cc9b776e4cc58c90cfc8f442df64151a7fd4a3dd61a4336da21d03944635d3fd667be741ef45b1f7cb276d9f4de8107de64582f7917c6eab38e0a8890a4bee48bc92617a361cc7b1d25e089453ce0a52544f868dcb3249de761e79df63efa0794e3c4618c554753ee281c52ac8ad78d5338f0dac360a769381bb4a39f190b887b4723806ac4a4f2ff304bc6f9337ab54c866e6ba51df50c43eab52e2b39794c9917e0c31433f03681d2f1d93a0436018caaae20206a3458ad6c037acb511ef128f6dcd05305f07049a13b6c6c3c5b8170f158c8f12d46e160931ba18bd59ae129ec07a0655fa482ebbd3b850d36b832bbb775f538e3c1b3a43ecf94ca630ca15d502813eed3e35e8fd23d2ab638600427d1597cb29da2a5
+SIG: 697d4d897e0e2cc02bc1c2dda57f0dda620b37e861822bb7f1a701935e959ea0d8453f746fb92c087ed65d980eea1d6fdbf23e99b289aae0dcbb128ef836640a
+
+TST: 569
+SK: 66da8b254a37067378f68138afedd66496596a0585524c716bde2b3124c3e7d1
+PK: 85bde28a922ab5eeaa4a6294521a2ccac0ef2303dcdf8c7fee228fb4552012e7
+MSG: 3fae36638837d0edc8dcee517e43c488ed57fa6c9853a745aaedfb109ec1409fb8a2fe51d23e0dd9fbfd94f91c18e6114d808901bf617d2667ceebd205c5c66f5d7534fd2ec33dbfe580ad919f504204eaf242af8700b138cfbe0f372919c06b861a27d720d09df20f4fb7b748e718b0fc486dbdfcb694cb3f1420035ac1be55d31f30f997a043d04708a5c542ee37c0f7fe0b3211d18a87033dcb15c79e6681c4970593d32a13c48f0a3af8bfc136e0f9b56a123b86c4c640b650cb7dee9a89e82aeeee773b5cb032fca41c20c407328bfed29244e46055a83114614d3db56581604b115fba14f618e102a1e16cb036ea69df9275b977a0858118c91a34b9a8519bd0dac3b61434ea088f381ba08bc1583189a4a7c8b6ad18f732d74eff3acef4b6904df58c6469432151372df9327ae71a0f356c94468dcfc2e4a5c0e4ec0b166d90cd465f9260ebd6a7a62ce6c715bcc715be0c7e1f28c4456012d33177a7d4113c9a5a22acfaf2d6b63309078fc1b1baa8f36c7e866c1f972a6500a5eea79201651a7305208b6c93c492bc77cacbc99c9cded179e664a2f4e16938cc26fca8b433eb8012f7b3ad19ba1fb858fe4a00fb3d1f8fd0eddf0c37dcdb2e5d35c2546f22e8c0f8ce90e2df8abf24827a019b2c33fc590bbe712f019287002bc2217c0dc0931dc8ed8f50bb442f8b2de27857362ce5a9fd97f0fd1b2b9251cad2a4aca1a94de2e953902d7228142407443b1d517107648a7bab83074987d0978bc61d419bc84591c969c3d6f4e86fc4738737bc0558755c110a
+SIG: 4082a5bc730fb54b6bd0bcd2a044ed5d3d327dc19ceac8825e629b9e6423cb1c614236f097a6b73d473947cb81c4e270852ee5f13a5b03dc18e1c9c27a9a6802
+
+TST: 570
+SK: 276548290f3e0f900515dc63366c03fe0fc6ee130c21fb60a4df9cf464797cda
+PK: 7e2a3578000a087edcc9e94fde509fc4be05ca0dd090df01ae1121123536f72a
+MSG: f0db442de29a7a1ded550d120002cc12abfff98b1f576d65bde16deaba687e4e0b0d5a8748d7503da2969c64d6a7c28d27b6c93ad257ce32ecdaee375f43fff97c432d453f7196c709c3bdfb7388d4d8eaf139f182940ce17b4552e2d20aed5557ba4d2acbf845730c0a66b45b40950baf6a946437af6c9e3b33a79e04dceae57c2a549542eabd216bf13948d41ffb9483fe29801fc8c1782840deeb3fb4da3192785bca13ed0a9eff57d6136bafbf9dec697b832447b2b6e730fa7f9995bac6b7832eaa09905ee49d465a5ee450f52d1a6d364c618144e886e8ef633dc79d0af893d16b3eeda0fefefd8759f2a0da1930170dd19eb78f0d7a7b74515403375a95bdbcce018bc1edb08d897bb798a95e7e86a52af3d9b8a4a14b0371d63498dcb2016248ebd0be800e9f21d549e5e0e7b4895ca5cb725a0cab27da8a8b1299be38a4260900ae10df5baba11ae2bab7179dd8453969429ccc4d416055f2bcb93c1cac6d7e804cf812df1462f22ee9e833a9769e8e677550402c4094df212fd2c5fcc09a72c7ce0077510073090d0e63db637d43d4c21f8619d34da5db08033f686ce8b8a0821222f95434ac4e6f703094edded6fb1b846e979650979d3c77453f40f7fee7c3e88a96fd1d702e81c2a4f3f3753c7964842dfd9d3958a743da063d1d648e51b210a28ed2487f14d5f1bc6f339b2dd17a661c39736da99e4a4f07360342d237e3813ea3998d66eb31a2d708af065c32b927f757c37a800660674e9717ba58f280eb2aa464fa74402108a5d5662e8d0feaf329687a
+SIG: 88a146261ad111c80fa4299577e710f6859cf0d1ca80e512a552c725b8384037eecf6465ce97585c9d660a41ab9104e5f7c9b2f8ec6fb21f1ddd50d65b9b660e
+
+TST: 571
+SK: 972c0616556ef22c214868fdd822c55739e1f96a93ae83512afda9ca7aa74cd2
+PK: 9e1c6d4107f8ab8161c5db5b88a37ca1de9f4e291367abb1efc84f83f7076953
+MSG: 8689e2f95c8fd50dc44664a18fb1a9f2c8f3ee73c0f9587ee28bfa35c9231c75bfd3d9534174e5ad3fa9f092f259942a0ff0ba2ca2cb59043d192ca8e3c8869bedd2354cbc5ac782d727c0b69407f68d1326df65a60c4d32f87f19a10f3d765ff923434f5511d134d397c4fef6bb1953abfce60827c359aa4b54f912aa8b17b83dcc7e3bcbc505ba046fe57c16dacf4ee2fad538bc06817c9b9d8dbc5f9d9bbf9f4a934f14a42c29e0e2f3a49f46b20ee76cfe20dea1e97450eb6a8fda048168dd827810207f005a3caa93ca11f4ee608a7a9355494313aec8d7075afc94c7cccc75c2319bb458c0ce373e9d007f753b33b52793d58496b2d25cd1dcd7832aac5ddb38f4db19c427219e1a0420ead47ba95ab6d89c65939041cc734c08eb6b476caf7fc76c598d947ff444b10770f62945ae65044f78098299e2626b638a7328d1b7daa5889e8db94bbff2ded62e14463760227c3f326ed493565ddf0a1761b8e4bb7d2410fa0fdbf35684397eefea95895889a0a9dffc5e02c092383b7ce74d2d90939916f26b71afd265f8bec74f0de247c9643905583df3cee23537d6b568c8338ce5fee42f7dd15dad5247f009acbfd5d769b6366959cd0ae150f58f7c80fa10d989ed90119372e5fea5da48a4e8ea9c727875dc4a2005b0dc2e3f697c0ce0a4bdb2f750c04fbc0c27d02dd8286e54c9c3959b6ffbdb1de2affe9e782651e5168a500afed037b3e1790ddd593851a6a6ccca9fffb4a99e27df43818871536ab04f14a06a1c7cb47bed6241ce7430ad3e640a726752fa06a9
+SIG: 54dd06fbb3d7c63f8cdaf783c2d7bac16b4c826e2d1b1807c84e049f64e271b21cfa3e37c344260287805d718806b62c56b47f6d5c508125c9fb5d5ea35fd501
+
+TST: 572
+SK: e0405d37893e89f53811d6d446e1f193f51afa1bbba725f95eb48033424a2509
+PK: 45104d595e443e8ce654de9d655054bf0a99d35613d77d57454ca2d1c899b517
+MSG: df58c4fd0702a20fafa3d1d4fe7d85938b120fc11e8d41b601f0e60e42236a49f126813bd512ee71359061e13eb314d417f56d6d560285fa8991213284c42bc2cef2dc937bdc0b5e9dc2269afab32db30e6849855951cfbc53ecfa01643863e0328995fe850c0db55421bfa564601b8c9db7552c7e6aa7adfa15a58021a84266e9595c65fca4a15fa70f55f5d212c9e277ffb830f4cad1861f3f495a9d672f5691310639c12dcd07e3ef17a23750bcb46b7ad7eac462eb512225f3be7e32f8f4987a11df341166062b43c63ab858a600497667fbb88e93c7e2e0aab41c09c023eb902ec3baf679e25b96e106921a914fd5de200a47889de23e7b65d0ccdf0c29036467a1210c0030309a2d04ec256d5a4d8b97d46a3e15f345b667170803cdacf6cb48add0a13462dd30fa062bd4566641da07d7f61e063686edd96bfe8f97b986b7c0e44249cd2d7317472999b8ee4ea80c902f3b188936712e89d8bf02ce8ae77b6b31abb0632065455ddd9f9d1cd953a4a49aac1a15169e687d4fd3f7c2edfb3aabc3b66155f7d315f8a294faddffdb4951367a0cb870759e85a838af66ba3fc103da2babc3f381696ef8882d85a8278d5fac3a72f16eb119ee9900b1fd986c2a9f94eed8e0d4f273697e4363a975ff6a7b80d5b4ec5355bf63b42b71cd4842401d38b5e00cc97bfda40e456653683bc8e6dade7dcf985a97b0b5776c4d72ca13a1474e4eb2eccfcd428786ddd0246d73a6377a79cb8da720e226c19489bd10cedde74b49fac2cfa207129c6a108aa164be9d809c4d31147360
+SIG: 77ddd491ca662ebffb12f7f492d7fbc1a1b447f6c85998f2f7cc9adce67de63b6eebd08117845a0302f7349714ba9db2af58048b85837d7660ec3debeee2d00f
+
+TST: 573
+SK: 5756e752dff69e3eed848e4a49c7a8baca12154f9431dec35626ef8d75a44514
+PK: 5910ef00a5b354143c46561da62c41aa13d29c18dc6153bf8e502e0114007728
+MSG: eb2190a3219c792b6666b2752733ad9f86fc390155c4b438be196959383b25f3a749530d5a4b15ebe2c18d99178e6d45bb4aa2120f95a352e0406c63ac867248d9efba124231064873c82fe995dd031c7cbc7d15ec191fbb6c474dc4c777e8f457841eb4624841c152d15ede26e78479a6a25ffa335563f1064ef09558b910e2608418820f49554b670c6bab34d1d60984dea50ed6a375f45a74beadfb04bd9300bd594e2e20ea5d3052bb7ddc51a949a0047972682ebe66d38aac62927270de42150d58221d03b8ace3589933487bf23d29c5c2c843aefa2e1ca22f9d1680f80c766d143ce5ecef253a745cb71e72f6504ad911f7cb4a819cd074863a92706929a3142f8db7ac164102ac2ca0d2e19a725e1b5f81f443c73e0484f26a45a3aef84f1f3fa04a4ac695d2dab6efba456a281a3973cc186e680a66df521a4d1f9edf4dfb274a427097bf863281cfb0ed80f8d7676638d6cdac937843efbcfce91de1df6c52b594571b9315600e4b6552defb8437a807ba21298e3d972212ba314692917f40075311acd009395241b9f1b256c515735dc674f8e866d1eeb4c328548aee71231c4c9d5bd22e39de88d19fabf49f0b9869cbf835214b15522a93d3a5007b11f0b50e5228d4eebb4571b35da84f4f687e3f43793d54f3825b37a509ea564bdf217ff4adf6847bbea4316a1dbcc7448ecd5363eaabc128decf054ee1a0ee2d871979f8a63b2692b09f6e986a138e7f68f60aa426a1c9b01a4902e13b17bc8312410c28bed29b601b0fc9f3bc2d223f875251100f869c6b5844
+SIG: 8157d8334ded1a32699b350ac0d4120028cd8ef8189448934850e50ee4999d8fa2cd257646d92fba5d662a823e62208ab4fbe01714a848a0b90b55adcd246902
+
+TST: 574
+SK: b904acb19e5cf872d3640cd18ddf3c0b6657e0117ce659dbf50259015d3fbf32
+PK: e04a8aa56d1818483b10d0a7c919e1d5d8001e35510e1ec62f7114dbe81ae0be
+MSG: 83f4124d5af955139b1bc5441e97c5fac491b4ea911407e15420a0347ed7fa1f8819e36c8ed5740c99d4505a78b619d560749af50b0573510816d61322cda976a5d4ca3205f5f0e60e759a5df1a0bdf36dfe9717906ac57cbfc970ab43b6fa18e6c0006c84fc7254470a0b774727bf5f8e679423a531e41cb5310f9bcbf5a5445ebc39fbd909ce11e97bc2f66a4a1bb6c2f167f2c6e80eb9b8b72df3e8cfd4e51448dc14c0b837f2949693d1d054c8f95bff7f1e364567d034f2223e1594772a43dcfe0597fd6d133b3f2e96ffc5667dd5928f23ec3c750f845993a34e9776159a6830d6fd9013ee7aeaa1fccd69b96df284704fd08888b15b64e2e90d578c5cfc0f95693f6ab65c6947446a857c029c7ca66080b754c7734b78998abe9b7cc6efd09a4418194d88b34ec6c33af630db81de5b99fe65aac8b73362379119c700d107edfc19f270760468ee8e5f155d9a347e57b5930f327a8d11c6674ddd020f9e7d9b761dba5b83a87302f1833e5abd49526d66391e5bf0e35b4453d630bf7d0adbfe501aef81e6c5938f92cb752f5f14d2806f90ae1546051ccc7f913c5d6a38ff3b7b9a23662ef1f00808edb2fa31ecba5c8d3387e87541cd0616edbf3aaa35a537922861f44cbd9f992b8246d9c64c419881701ab43f7fd464210d802ba656d95c0f24a34599b20b1ec20011485cfcb3186b7bcf69d74581a7a3eed6134c4eecd65574a4320d9c57a849c4e78c8a5ce82505004a54f19d4bdc8223401b34946b7d66e47e63cf9d0f57d0945491384bc6868c4b478690e550021df1
+SIG: 9aaf8ac97140d5508d58f5ac82b7fd47e6b1f68a7c78a2ac06f0416ef8e991953f62c47fd5fbc6c1e01bae1c92a33ef52b7efa5f17bb8633bdc1aeebce318f0f
+
+TST: 575
+SK: 8a3501b76953603c9033e3bcbf3ec378d257011a6c50b89762d491eaa72c5e0d
+PK: 778f2019dcd8dbb86c6737cc8dc190c5a04c50b5bf4588bc29fa2a47af252672
+MSG: e609f1224a6a451140cbc0254d432ce5fddd08a8e912f81c412fdfd5182ff6ac2f13c576c8145b15f25b409d853f914409e4e02cefc39d9bef4a2a060498570b2d3a2838c9b0b8e3af4fc37e1915f804a80188585b30b68a3ffb2e960c7320e827d2fe36e6a328cc6e7806348adb0b773b784de529bb6f64751b2105859494fd49db0bc7f62df46b9d7ce676975cc5f43856498436812e04f26fb8b8ab7eba12f1d56722eb82ebfafa4735977a26681cb03fa4bc6951ab9cbdf787e3278f2f57f29e12095f8ca2a178cfa7571337f0274237669f97657d4badb39436d786492580fd55d86be3a0cd17d16057017baaaea00c1e14552159bcabc0e666bad3418e4ec13bfe163be256f0c89bc2344a8ddf99ca8160b189875ad322d90f581325281d5389965c0a7b7bcae2294a3cbe35a4e4e83b54c4276353960fad118532d49b7076f25ad190ab5694914f7108b0ab6969a19128fb0aef00e65a04fc832d07696167b9342b355ec57737ca37cbff3bb31931cb58712a4c468952c6459d567a26e79501e4e31b1b0953537632029e9b490f72e5a6e057ddb4b31756fd9704218b1b8f4dcb5430c025042f47169bfc7c80d71cab8ca07f340afa008abbe2e3a0abe141da8d41ca6bd69d36fdb11a41ce0b72fabc00d97ea605270010b259df8e10dd22dc17c13990a05f0233e3ca856b40971cb3e21c8b3950b13fc84e1f266c2a6fbece88d59725c3cfb2225dbc1ee95b686db704fc937b766f0a9bfe95a42b9010f1229c610d7ede095712c8f0f1fb0047c040a870306cd8dc74c4da51bf
+SIG: a8a309ba52125e76a4a61eb43fd4135c41ab11799b91cc54ffc9c6a20f050cc595b28143c874bdb928beed261d9c0f12aa192e6640bfdad54ba0d478426bce09
+
+TST: 576
+SK: 42b53652d08b5d766e66ad8f3ebf693cfd77907cadd98b5466df77dfa2c637ad
+PK: 88463bb8a4b6388d924cb86209834195435d79d77f8c02f46bbd16d82efe42b3
+MSG: 9ee913c74ee3c5e8c90d64b8ae3a60049fc765e176060bcd1cd09f0eda60bf23badb8a1caac3d66ebc5268146ee4a54e1eb231ed25eff95b90a6e98337a540a3f48449794a4873bfc2e84728966bb7c6ff676a2ff57311c1c25e15fbf3d40e9f25ab5db91fddb7a0ae436c8ec070754b6d743aa1d6048fb5bd7f5b8e4ccad20328389530f11374a489b1d50531a39c9b32b40369626006d264a99eec4fac1341f4e74679457b418e6bbfba233f1ca158f7b29d40d50301f9d92536fdc5c23fe5dee4d6df0ebf13dfa3754a14c856009adea1dda409304c1f60d25330fb10957947a00508f2fd76422eac694cc39fa8ae7fcc77a02fd9ee5f910d93e8aac68f145dd878876ba8eda0a49fcb209c34ea220d4d0605546fc4a809baf010d533e45d17b0e16a46e91ea6fec2cdc5a8b3ec5014b25e92d8e5c928ab06993d4fe23ac8d45c890378dd133f00edb937c071f75cfc13a402e3e429a848652a175c9b6f6eac86f6188a4448a96ce2872e5f65f9bdb87166c9b87a7e958e80bb6566e3fcf871190cf4a867e612cfc1e4371d2b73d2a0ad0aa400ba69e66336233b0f3c52b8a68bca05125601255046e6f49d688d2db85c7b821270516e3c0613f3f23f9c57cb4c8714285cdf95e106a3b5afcaeb81b72f343e87bd92f1581dcf9aa90a024fa4a1048059e30de8ff0d16794dcd745d2b2d534c520f8278538674a934c6f14a8428e3da018a36e45aa5827cf4b15284346fd69363149219bb0d1bc927d8d193c482692f97dc88d8ed337d0c9dc99c7a5e111dced42250d580e20692bb7b88
+SIG: 30c4b99e68ec3351308fbc76d9caf0af6221b596b7017fe10cc633023ba97f023896fe322baa347660610e05fa493d218fa360f18d93e275d1eff666b63db204
+
+TST: 577
+SK: 14cfe00fa7190ae810888ae2bbd0ff6412cf1fd408a308294383a19453b59073
+PK: 4e61afe8c174b6ee1a29fa09cf87b4008139f1070bc8531b6d06f54c9562a4f3
+MSG: bc66f801daa829858e740293d4d2187b8e1a5afba5fd67b10956c65346aca94429d32e4cfb3584ab0e005d0dd742781d47e89447c4e1d81bf7e6154f8f73af03361ad56ea3c06000754b9f327d4edeacc4d348afb54823e1c9d49cd8ff2b19f42021b40d580c39ce3d243661b85421fec915ba9dd2762f850bd208fdbf20ffaba56a468660f17c00fb1c0f4e8527a509dd4eec13360cf6e3cac542b875182f2a7ce7be0a33302fe26d3629629384e35c06789de634e90e964fbda8cbba98111e22e8d0762684266aab76aeba4a380778696814a1e311943cb3505892640c44e3aac4530c50ac604a8d2ccc7ceabffea4aa3d7f48a66dcd7588b80209dbc173f0c663e8fc87a36e892ec9a3ff8f60d2e0d8704e5b6cbb873275151ad4cc0057165031905039651ca10a95c6fda3b27827a657ef9a5fc3eb5b53cac61ddaf5a41704c878570cbc3c41c475b117c05eab0bb196bcb7c43334debd64b9e37450d23f5c10161ec5ab4fccd7cf308e2a9995cc9e578b85e8285a5208b9efd42af9cf2ac2b3b7464254889a2187317e32499709b913953ad46f1c23e1b6b56f024c4a7d48461192c01c56c54c564791ec0a67b61acbf957e6d0d7da8053ed13a41893d767fc5737cd195553da5d5b07065f47d72a35c42b001eb6dbd0f8e77a4b76a6266192647f4155ea11bd1237ba77c87c62bf4b01149fc58bc28f0b5a286485d3717d323964046218e70c7e38b7d5e74ba6b12b022f18197d92c13bca89335c856cbc5756aa3b64ec1f46e396b1161c871cd2dfded1a4ec9192742937c0704531c7
+SIG: f785a46f69bbd099fa011124ba9032c189742c9e001dbb8781d8223345a9569dc144ca694d90245e0e513e88ab023f7f0f99b7416159758dd034e7a89cff3600
+
+TST: 578
+SK: ac0f7f0418de67e348fa6d5686c46d21ca72622ee69eaabe00d5c9075a34f179
+PK: feabde08f00a2b682bce9d45990bf45afc958339dc44106dad33b2c490ef7090
+MSG: e8d0e8325335e0f35a85467beed1e11c6a2078c35ae4a4a10543ede40c1712bc952012d2f8fec105aef7c6c65b3634b4a74b22b498b913507d1f6cfde83858e6830c0af4f464a6899d5c4e279aff36754c21da80a1bbd1dcf46220375b1e112a5a72f1ab6e8f641942f66d9bbdbb179cf0139ea8deb0f4b814f50c513329a1a0e267c4433a233182bc4a2acb2c6d4f00b24094d3bdc0eb81cf37d38260c2107dd9490613d276ee1f72266c6e4acca5249811a0f8a7dae66aedb75c3df4c8ca3cb5d9c567ba541ee5a9140c50587272af34530ab8b08b9ec032eac06039e692630e2d554df77c1a0388b3caaa3be3754a84961fb299e402227158ce363eac26478d479775e5685adbf828bb355e3c89cce241503c15366432ba94cd3cd95479144b636e0de70b3f16d1a3ca518e399009a4c247a7f96367c7146608aacc0014fc35b84af9933f09babb89937abb8ced111891343ddb79f60b78898ab5938f8ba3814bd8002605b1dfd297fa07c475a0d4f8f4451acd707de8af6c0e8818833a3abe5c96d1a8c6c96e2cb63328eba44dd1d34684e412f288e065209d11eb8094d22e4cc802629ccba33926bf1ad36a6285138abee05c5a39a475f3fdd0b3ec8c370cd957a8379ec2cdaf03e895c1ba12b449d6cd8be0f35d99e2b7fbaa92dd54e64e7c35ceb88a71a680527cb373afe14cdd158a0b90bf2daec80d2edbdc3128cd6b63fa532a1c278cdfe0f8ebb4abba5e1a82bc5c3fed15c5795bd9ffb576082cc479fa1b04c5c5afcad269a0f1addfe76042c3a8f1f25377b6cb72ec1614eb6383
+SIG: 7591cf8257bead39a1ad3ba1918d518e6724356bf625a573eae501d1af946c13c290cb63156ec9d362726ee50b39fc0a7a2bbd69d4a81b75932a90f8c7ac7d03
+
+TST: 579
+SK: b5a7c767936380b3e98751cafd3ea89b388a32cf828b321c5bd0cc8dd85baf00
+PK: be7fa65f1f6be51027f8b848db7a8c404961bf1e21a23df23bb8ce05850cdaa1
+MSG: 6b67c795d66fac7bac8442a6c0992cb5758843b3e3939e3c276c6e9008da82007677bf9e67e9ac5a1a0f486beac0d856191fae25a127392bed469bc78deb0c4b893f67f1716d83509077e4a1bfd4136d03152dcc3b76d9524940a6064c669fbf51f6b91034b6d5f2898678a13a2470f6641ec802457c0102c3ebf6345c327e741b80644b3a99bf72b59ab8016f35d25188a085750dc060e5a8d524ae213f078f288c7b34bc41f3ce356bf2dafdd2e0db4fb8d7c2c319f9906005971702e49ca62e8050540d4121d242f2eeab1bd134e60bf11b3ec71f7765a97c0e098455e59d2235d6b37e7c9f5b21fa112c3ba39e4ea200614f58dfb3eb7b836f0bec1ddd438d1422450ae7ded1df9d71e5d9bc8fa3b6e6f78446ce7c79d0bcfb1c2d26c6fece68682dffc60a9c6e0ad05f2a09f21d7523251cb0c3d08efbbf8ac16339d717024d676024c1ee3c1f62c5aeab7fff937c57454df7bd96f9844a2a399958418aaa6f1848bebf7bf1292c24eb5cd8ea56340c5beb2688024a6953275be6efd1b71ba8be6eb77f0c65a7c5111b96c4c1f39cb7aaf83fdaae8d148d7a8af40ae9e651919f7ce28c8b2b6e45e4d3d56fdd54d00c2412790cbd6f80e10819e0b8f37c84fa004988adafccbbc21c63d6bf2e732d9dd63bd49b0412b9674e1e88f6142f7f867f1f26891b22430423cec4db91b61c2abc5c8fbd46b8b93596fc5160683136e21129822796eb5ea088e0a7d8121b25572e3ec37743d1ff6d8d1c3536439a10e84a665f2c75ee73cdc6ffac4cc28724469f7970b47507df3e1b14d477aec2bb20
+SIG: 60e4d23f1f08fce466c9915dded93256b52b327e5f81fbb31d1d10d321c390366ef001fd759aa9d0a55162d5364d918b48c7327e77cf5358bc4319e325cdd608
+
+TST: 580
+SK: e136f398a605d13457848cead07c7286f42e2f28df8c128a3d0bb72b29aacc19
+PK: 6aa5045a66f772a571fe3e42d117efcdf6c49591996186012fa98f7c48e0cda7
+MSG: d328579de4c5372f3b382c48011b2d4c6029f904f3a33e07d083d7e2b03756af2c4c97a2d66c10ec4154d874792042b646e4aae5101d501bd1bf6f511751d0aaf821cd7c0b3ee6d0d7c690a2777fe16bdc7e49b7da4bbb4cce3b618ee9b6f2e3a19240cdb70733b984b1c940ec66960b728cbb874b80643123722db9dbbe88322008931b1c894ef5d21099e63e7c65007acd61784db4994a2fb40c3efe9c47fad63763dde06fa017a26b82e71b9daabc4ff0f6c79b8ca7ccb4dc2031bef1087367c7086974a00566de41a71e11d993abe433569892b8f75d7637993245c884478abe3f95f44b0a4bbedefef8906b75e0d34020ae536455b0e06f9bfee11ec9b8604bac2cc6ebe08c8fd5f5cccccbc1617b7cf69a3c512e1f0bdb585df5e12743061f7c2053bc37144361c0b35fd39d56b1efaf92c610360193ec20598b82858050a6d99e082bcefdbd5318ee5efb3b260f3276f3c73f9c24ce0cda33c7acc50ca5dd61bdb85d793825f6732a6e330ce672ac44fe6b2b9afe6e2e965c02d2a1fe0b57cb1b317c1d313efdc356492fe896fd149dae51c95ccdbb7d11f7d610e0c6e2fd3e57fcfef1c57c7119a0af6c7821fecdb89d80302b49fad41743f3d2d7a075154b3143e51aeb947d4b5e8b7e4ca86fec3e80bd9a786e4e46ed1e6e9f7e0b635266d9fa097aa9e20f32e3d2772d7c1f008bcdd3f92c7283c57790c3622cbad3ca35803c45c869dc377ff36bd7c0e6f1bb892f7329a6e08df1dbebc81dc7b115f852e36ae5d928725fa7c6fb9f28b0fb394f9e38fd87625c5fa23aaba47054e8cfea
+SIG: 75a45c6b9566899829b41ee517b7045a473a4f7a2641439b5d7c5673e00d8f5c066f1291f85deada0502bd16e9709f827d4751f2873862e8219e57746a19a900
+
+TST: 581
+SK: 97b6702e246805dbcfc7fa424a8caabcf262d466a05e0dd2d4e7c374d57d5251
+PK: a716c3d5ce78f4d9c5bee3447ddaf4881c986efdf667ac8977b4fb69b5a7110a
+MSG: eaa86cf76fcb65c6f9fc208ac36f28b200d3b403aca73207461d8d96afa246d7c69d17a7a9bf77f05543563a7d3eca1d4079e22938aba1f6e9e04b49fbc8ed6f63b599730de9979831c02f8cba61e55560d7110d4c6e61679706a7155d5a673c54d16fe4d228c2eca7546faa1339f26d7a0bb4ee339611afdec9a68f5ff5b5d203b600533ad5a3b368c85da11563f098cc26871e7fa99aefd38cc26151db3b0bae38db6a87b6789e5840b10884af511f3ecb3ecbf94ff86fdb905505a8c34b2aa61ff2ec9ec8febd1dfed0965b6fc5b9f8869dc3a47559974a8822996706daefbc6c5bf984ce06b0d32b31cf9d8ad136aed4b052586dce7073b767b234e4a37bebbc393dd2e0f7d155173548c38a1583ef94e0aa84e7fce04fcc9b4e300ad099449a49232abdcf3d1a6e6fcab696f5996f9bd1b9485d074755ac5b4297fee3124c7c03976a40d570beaec2fac992339f885f74d40ed4ac87a4f40cefbc4864f44c3683aa8f1026e2c37aeffcebfdfe24dd0b019c36a79888203004b2ad83e89221f3f636f455bb64e17d1754c7c6dd7fc09a0d65dddded4622fc4f9fba072b45103435e10220a586f15226d2eb377f4064d3ff37cbb4705a1faaf5b348f8c0ef7fd1564d428688f58f3392967cf396a8ff2fd9e7b517b7d6a5ede7440373d8cc1a839900e84d42254283d9699c7ca37e477692a3494008b80444c5cf614cbbc169bfb9296303c645e2ce28d168dc6cbaefae9c73191f57151aa473009d29e1800b10f4c498609ba11520985c78092058696fdbca9c020e2dfb8a043a3de8e452d58cd1ad
+SIG: 90005541dcc1d7ab837f4de5393fadd6a92b26a7d93af3f669e0f1bfd621cbd00c8a23056d2da6786557c828a49be1e4021d99311235ac0d4d56eefc7c953605
+
+TST: 582
+SK: d1528c1406a6e494a02f635305fa74d745c69327fd31b7d2c2623de2c030ed85
+PK: 0cfe369cf93daf6d53ef028ddb9f000443b0972fe2532f83a41ce657c1836ca3
+MSG: abb3673f3fa17a33a7aff76eac54e7687c04bc84f766651a8b24ba22947908b04ca459feb98ace7cab1e7433a6a6beffd8d9504e2991daa0644d61b8b2e45448f54df8813f50c418b48f49e1034e851cbec3ef0a1850ef726733afaf68e1a461041651c138d54e4ef78187af9a7342f7128727f903bf4fc5ef3e40c64ec26f892f59add98fe394765aaa7d09cae81b9f699a9dd8bf2e2fe8e1ec78fc884eaa0d2dbdbfb8c168833ee0d21803cc35dc628d7c07e04404fb60e8c490a8dd34edbcbaaf80ccdae3f7d3739e0e897023eeb5b1a8c00a9673c59258240ddd4420650fe5771f7e28cb2399f5e1e02ad0b6432d9b49608fcf0b1c0d7c412a445255b8badc5321c24c1ac92c79a0baccb9deffed02d12f5536cd595dc66083b33a3603a9d16ecea2bf38c4f2aaf570f30d21162b2efd7e4d5ebf1ecae9588eee36dd9d3d8e3be7bc6d4bc2185622f11d1da7c49c93e623ac56fee7e3706db8313cf926be92e5c8a539fd16b0f438da8e51a51f2d27640356124ef7be2f91ffa1796a91b12301934ddef0c7938a7a45f36f53b6322d9c8f9d275e1cd2c0f129f8ab8d74155b5d9e5c15c015b0b00003b2bddfa0bcfcc693a1dfcb4f53daec126d1669f33f39ad05519ef7c5ce40e6f4573c247a32c4a0162831352f6d558ff5836a5317dbc4515b3df269a8ac76d6436f264b64561e7968b5822108487b045c92d6c6142a1c2855b38beebd642565123cc827cb1831199e6f12a7e4236856b94dad738f69d1106e7735d711f7c6a3a3378041fc7a21103bbf866907d4edddafa0e7f1bb5ffd41a60d64
+SIG: b8399bc3326cba0a93a42497168bf57f9106ee43d39bf0fc86685199dc6e0a13b9c724ef17e7882af8c2eb70f6c9e42dfa2fbf0c1cb5002b58f1086619733e02
+
+TST: 583
+SK: 512340f961f142d1915e85fe4fa0f551f80892e75accce7cd1869e6e2c9e8015
+PK: 0ca02604fa87e2c20506251f0792cd2125856f0ab16d663f2811963b1f2d8172
+MSG: af37b2c7587a8d5bc895cd357746ab03552a0a561a293dc7164e39b6a1333a920bb6daca6006676e99bb7e928f9ea391e54802a8d31596289fb9bfe30000cf52ebf0c124a5895bce3398c1bf5356be82619b8ddc15a77ca922494bdb04f5c2e1b6e8ff77ae749faf2b8a41d822c17c06dfb7a5f9434d8bd715ec8778e80b81d2e8d06298748690c6555283c98bb9b19b9246667bc41046ff98c2c35d161e1f4d69d254ec5a076f25bd5c7e2c98ca3c09d80833962cf9660287884096eb30c46c54174106af4e2979a112f3e8944eaaf7669c40d5afb91a024abbeb14664e308903e4d26d7009446ee2e830ab5eca0dbbc513fb4e04351df2f6741864fb2371b2502be43dc15fc04431fff5eb8d4b68d72462ae322e57ba2d4adddf15a1902c2113aebd3b5d612917c1bb73e708ad5418e7d45e4b7280fc8896ab80853ff5f8e98f26553fc78e30b3b0d727bf6d064a8f32888768c51ebb61b2c600b4028a77060febbb02eb3d201780e74566c86a34031836bce9eada81e5d0f33960cb2df08aff3c974921fc9b7d3aa7c81e9c671ed6d33e7ae5ed03a5417d7e5cd6faac91b54b8f792f48283c60647de3da816ca9756c5bfe1bb8b5979e575401bda34e9cbc4d77e711d6b73b82da19da473b55e8e72d341b2d8503e48609be0fe291444c283669e5deadeaf52aa8ec48da83f5328cc099fb41f82becdd58d04b1d66203d737bed06cf21c97819ac13ed711ca217a57cf7d80ff082aa1a1cf8fea555cd2e47e4ddab5e3f9941ad4f775f49419dcadb5b004b68caf45b27ef49ba14fb52b09f1b185be9f9c7
+SIG: 6bb4d975afaef41ea9ef085a68c568a05da37ef21dad464ed86ac0d4080e7d0129fb023131eca5f7adb2586a18be40562fa2764ca807e670a0596a5c547bc001
+
+TST: 584
+SK: b1b636e957574c21a957a45bd195c6f9fe4cc1c57e84134d39b42e1a84329edb
+PK: 95e77b15dda47caf69b72888dd69961bacbec3bc75353003e8bff0a43ddf4b7a
+MSG: e25d329cad8364d2dec24373e92d9d50fc7abe8fdc3d0b4ee57e1cfa5b7cd58c23be918f05179ba841b61e180034ca7e74d49b0a1a2cebb4be65344c913c46d32652336e6bda4efa3f58730d39a633a14ca3d9a62abb0a7398cc29aff916eeea2e7caac80845562f73d4030f9cab0bf1c6407f5401513ef87fe6dc099dbc5dfc3352911c07af6c523bef4cca78379659e8803f585904ee6ef6fde77366d96d2ccf248a5320d9b8298b2a73363879107a02b47f57213a85203abbca5a4195f8af3e3593ed2fa3504bb76a3e1be24b66d355662932cb67dc88503afaf762bff741ba1cace97ac58bafad5d36c3aa02e0cbe20e5f3dc8092c512eaa9c4943474aad41990076721ad3f53fb08ac22982ed9b15c751a9e23382f6a69c72e6e244e0eb681e6dd228d3774fccb37eb6232f825d169a2ac8b7e18a42cdaa4f2cf05890bb0c598cf8c31f829ef8ca2435bdcceb0e6193ada7841ee692f30aedf88b627311b138ac78b3913e06f7c321cafb39d901dfe17430b1a20bc437a555a578fa31e4b6807954456bd4b04d5d887987bdf04e0f14af3141b24c3a7b9ac75aa32e2fcd2171a12609e15e73094fd09221b4d27090e73219b648bcaabf3807c9280b6c4ad750a468be0e1ad3e6e63016cb5cec3aaddc5689c2955a2a8d5b8984d7c44376fdd94d3f5ff1298f78172b565913704e90e5ac038cb1720e19b080f81b53d6a45d4528530711b63dfe1e4781c24d74aeb2bd8a73fd2a993c5b0891392196ac32c523699960d8b23e01664cf9021d93928050caf97fb985554580e33336a4563247df59ef6cae53
+SIG: 763c7d0d46878e5c7ecf7104fc1f2230e46178a27c75f196169c0279edb01c28fcde3b0d5b8635cfe339fb232774b2206dab8a460ce417abf490bbfa785c0205
+
+TST: 585
+SK: 10ca413d70eb3db6e337f0f11abc075c95859e825f876176076952d2f1888030
+PK: 5028ba38afecc242635f6e353d5f4afd123f860a0425220e966552a057880823
+MSG: ea7faf79f6ff5d78a823a754347134f1b3c3e91ce518fdd633feb4f05d125f05cb54336ef560e92deb685112a5ffcd3dfd3964b2758ce4785f6a34bfeb39784f0aee55955aebd12ddda641d05769f74402f706dad201c44c91081c7d7f65e7aa4246de6dc3ed6496d10f4a412060d493bac9aed5be4f6d74229e3c55eb6876e3bb2ed41fa4504b6670dda8c798f6daa280d1aa72021174f6c01aec49b321d87f53acbcadcc4607d5b1e45d63fc481a6d90576c87c1880b2e8ff3e590a96beee1804768c756beb86bf1de8adc408b1b8d666f74ba28630822f92d18b056ae37ce0293ee61b9e80f33ac269671bd62a4059b24f7c1a440807440d5d538a65458adc8158724b25c12127aa0349e55f6e55bc92078fd1ef274c2aa791905766be394a2628f7bbd1a32da5e487446bbefae88fa6cf3f7b499f131fa19313d13b280adca50f77802d17331b381683b5e7edab99473edd31d77443488214135fd6f26445093e9e2aff7d7e892337fdc8779065d4d97d6d673576794958dbfa6c50b1b13ac39607c1e66ef9629761071155fbca6f36eb02ceeae16367feac07476908c847c9a533ef68c94311fa089ff28fbd87809b0d3876b431d9a18b202f9a4049a0577b8177610dd02e5c520eca955e803c3ad4f50976f7c2ea8aa3ee4836a1985df0a4f16ef46981595419897993560af82651c2b494e680b37802e7537ef68a575c34f8588063ee0197206d9a32bb4890e7c216a4d33feca36b549e532fea68556e7540a4fb169d49fc553b2e6700ae42d9a516e68160acf6b270c77ca5ec26e5ad5dc75c2c393e299
+SIG: 6aec02dc6bdfcb67f0efc1fd31e23e69e371ab3802505b3201a95dd525417ed1a128db4e182cb37c28f62806667099a8ad480b0ac9e94c2a7d5a0e96e2a7360d
+
+TST: 586
+SK: 1f0a10a2cb111917b9a67a2a1f38fb86f8ed52607d1d653a457d7f4718d9a7de
+PK: 70c075b2e94c4c02f45e73044f24399741b161feb6f69eab635417282a4a9368
+MSG: 4f6a434bd5fc77f0f1b7049c91853ccbd89439962a6078a674b867543b6b7d10552ec1758c5283042bd6b4cea88c9520db04746f089cf3a260fb0f33858efd6f680de5b72d9876324ba590299138f85a76f5be0e05e8859c02b23512559c8beafc9cfe901b283e15d16c792eb03b92880f6ff97aa38eeead3f4fd6c0a9214323aa39a1c16515e30dbd08b833ee40a814a28809c870e1d0a62c37932d5408fc6afc63e79a655c5fe3d4026ef09e0299fbde5ab34fceab14130dc4be007e8e6444d7aaaec62c873df77e8010743c31e8757f1eae9edb5597a1b5d84bd77ae7642e1aca99873a152ffde068a8e4ad9240b903332795e40bb32865e5ce034307a6c9fe339a1c93770df5ca46329f6b09419785cbf2847b0c6832837123853ad952653265c5b5740d194e00f23f9e966791f005f8bf55c388c2be9e21538925f8555e0dbd83be073df765af4940e59a3790b9836bab7909e5676fbf1c2126fe226d781a44330cc01d32830ff8ae00b9792e398c2cbb4fb83a1005c245549a89063fbe06c62a48dac43c5101249994e95e37f24c1d8b3bc673538c46055f800db1c0f956869b6b297d990f44f05b50c7ad6b856f46212858471dd0d39372b0db751573ddb6b5b56ba01e371c78fe58dcd1be53112a6a73da9a6bac75d3c39a1a705a36f640fcfad8cd04077594d59685f6e30de71dfd4a44c4e7c04d6ec7c2e8be12785bb05b29b39151d329f587fdc381c2df0cef73fe0e3fd9208d7ccb6e08d02f42d1feed27561d5e323aa148624e552abe87532de15b7f42c22c98e40525b1747cbd758bfb26fd3eed3b
+SIG: a4245aa3395e7bada2bcdf1603147cc5f3f0ba91f40fdad8f6d371c3ebefb4c1501d07875b576f40797806a484c7a3f70569e232b0c99d29ca23a233b68edb0c
+
+TST: 587
+SK: 7f05baacf167583cf2fe9562a506991ed987f68ffb71567c7ccce3fcc59b78b0
+PK: 0dec3952852b96fd75587e97743f9e41c09fbe6ba981bfceb4ebb8892d986a16
+MSG: a27d1eab05150920ded1b1c2578af582b294f7837fe4fb1a3169c25efb70634ba66c7e2991b3e75cc5124826a03e057259b5cb706228780cbc8275c339f8340e402a665032a4ab657827b1c3481f7566d369735b82db7628c022b212730db1e47c9b2d9bc4d81b2342d89c6eafc3e0b6de50d484ccef11238c8e2d240dd595dcef8b2fc57b54ff9a8a74111f61f8a652f20ea012c1ade3e280ecde294c0e35717190162ec6a2265e7e6f3f0704cf8ab1a03e5cc953e2926291ccd4b0590d5c20568f94f9ff0fe2ab78cf9ae2c38bcd491e518f23e9b636f880615fc56078e512d7577e09497c1183453d5081fd4737f280ec5e267c4586b78b70fffdfd730d809df560f2e3772191847bbc3f604fb7f8ca49eed318b5e7d1f2b83a10da0c8594b339b6871a5772dd64168ecc27e240a45c76725e7d55bef37e135e3d9e0e34e36c16e34d77459a552f4074d067a31a3ed2a48cdea4895b10bdf1656f4b7a413c6a088c649fc9d7bc56abf64435491214192a6670cb8b9c917f8e1bc7b2cfce78d28fbc3afc2a50e98213e7e026378e4ea711d151adaaa719beb8974656c10ebc7de46b19ec82951ef46a8c68e7f436e1b3ebedb2d09b0575c9914ead2796b53e0061e212994ac5026aea81ec37c81378f4ccfc467700087968597da38fed52fa48093ae4ba1066c31e3c7d8508095bb45c280120f4aa69a24f3efef1f767985aa1a30e140856f76d1520732878487be53f712dbd7d779e315101588fd7dbdb132f92c27575ac1486f176c790661b0148394e92ffa3ae6f8afb2faa2b7f4fbd0ad91e759a702b3c702b4d
+SIG: 0deed2df82acf4529c408a02931f676bec5cb7ade84ebdcd578f70f971382cf311bb83097300456a558bc4c09d8983ff13493fd611eb66c043bf019bad6f3302
+
+TST: 588
+SK: d00c216426710d194a3d11cfc90a17a86212e7a0e54baa49b0169e57fff83d61
+PK: cfe6ae8903c6c701aa304695c651bfd850331f9ad481633ae370c86d7bd13fb9
+MSG: 82f97841b3ba22dd9a4450837ea7bf8d27a9731470cabb0c2078034bf24e4c1a6290c03f4002b86fa09f07b5209f1f53d0ecf4d9e9223bec125a954551fe8bff718f5e264868e207f701194e41de39971fd385f49a4b4adda911eba55259fc6836653273f656f4af60b20664956d4f2135d90d09e9037d5366a0253444e022c7212af5fd4fccd74237d2885338e2fd721522de6763c2549028c623b9cf387d234ab5e7fcbe5a47c685b79e75a57b09574082a02221df64a2e841618087e722a21bac1ba4f0d7d87bdc510aaa8fbd10757f6c029ca820371fc74c3bc50bd898c55d8167f73ada377aecc91629d64c360c2c241c5cb42e3a518c5dabf0f418b2a7f3d82eefd92026d31e8b8160358eae821f730ecafe7ace647bff8741de2f6a131d11c969e9787cfe6a2fab37bf8d1c7f4a2f364d2f1a76ef046c1843e63ec00cf7920ffaae561e7370b719fc16fcebca3cfdfaba43f4f090c46f477303a660ee88dd4e89bf14b9f804b6fd495cb1412753474a056a0d8931cd9ccbd64f8fcc7a3123467c5d47f690679e8871288093734fd6a1326038658156413696594c134d73887f34ee67609ae8ffb3266c16d87f15345a476f72950c158796a88bbb444f1aa809cad875b85fb9151a0e2eef2e00e80d6b7a9ba406c0519effdd94126232fdf6f1e7b9bbc0362aa77516fdf939e7906aab01307128cf824c102c09b929c9b2d7af8f85b7d7f9a838b2aed0c697e8bdfee66ee016bb1bf35eff6b2f7ef4b91b1fc04fac9f116e2edff40f95c15b77c31ee522f3937c7fa0047d6225e0c8e55e278c8103911feab2b7f4
+SIG: 15c45c194297e887029f49d8bdf9d610dd8c34799e1e9230269e7a58928938cf396a02cd42205490391e1c64353fb06b9f8e9b818a9a361c204a386995bf3b03
+
+TST: 589
+SK: dd123972e628584acc46293b8e4ce2b2dd469cc4ede14ef39521cf08373585b3
+PK: 3522f7ae596eedb217035d95395e448dbd6ffbf42585eaeb307026541c78a651
+MSG: 2b2857f45280173e2e0ef9d594e6083f1dc7a65492975b837def6cadd8c8545031ee9d68369a9393cc7b792feb98040b21f1eb84665f878537ce412e9db680d29fbd8ffc7731eae91a20b47548996204fb06ad740e78f0fc590b6791dc7a0f2659286cc16d02c5117b565836b4b8738cf40e285c69c50e412911292367352dfdaed9982d0f899a23c0ab51812b3ec678f6882ea427cdc93ab4b24824377054aa25d82246653340078cf11d14a51f0e686d7e018b36741668fce7458d169293361dd16b3debbed19e1bef7c36934e20f33a09ad3e82b53ab4e94c255d041898b97737df99584af14e404058d0c93bcae7bbbc06395a2aefbdefa7b2ed17cebd1513fa390fe9a9b0ce68cecc2b9e129b7a29f49b6d18c28bacd3af39dc39ca972f0e0d06855d57c2b5fcac2f79cb8c05799e4f65734668dad6aa7a43a11856e23b1e732d00e5fe3885b7dad42ec18ac8e096a080f7d55070fdcff607bc0b852d8a080d2a7405d59414695f2eb7fb0aca23c8635742f8ae57f13780316e280872374e6929598d028a33c05d831cdabd029493c3cc859fff1a67d56216f02a2295665365887a350a80afaa0c367a74d3701ae88f59d8a9d3a1dce0cfd2eabe2af5065a1c7fca4aadcf8e51e75612a1371b4dc8ffc0c0b9c4fadb2f081e2e032d96818e55737adde3e1ac121f56cc86fb58a0a582692f62ce58acce17aafec7bcb7e44f839258cd4a851fc01344ee9f1bd03eb94344f4778693c171dd2892b2426a8829ab0cfe33a7d4a36eb4017f7fcfd24134ab8a45f23717cd138aa6000172e37b4064dc9b6d1e1ef3af84971d
+SIG: 8965a889d54cd8076d35bc2e12b009d56b0704c894f912a0d1d30720c232fe4404bf3009541e8f3283e89ea86f678afbdf1c21c924b23a52b4ca6d63f48fc203
+
+TST: 590
+SK: 3335ea928117cfeefbeeae146003881bdc8889d6580eed1352370820ad1f584f
+PK: cb20d4fd7561848013111c3e97617f34181d2e7fbcf1bb2a2cd2e8c1775b8b03
+MSG: 0fa7f6a6fca981429b572a6704871bed140dab93ee1992006e9a3bb2e6cc9a09d4c9cf17066b32ff7ef5b6b2e7911178ed7462c4c175603171ca613668b3be193d94c3521e588913b5948b550be99d82d966197d710acfd95914cf3e197536e83e68230dc3d67e67dcdbdee04f0d9c480237ecd28f74338db5f3f697d3d07ff33613bbce542acc9a7fed5d12490b9bfe1d109540f863800dd356da841a45a3cd8a08a945bfa3aa98e1712312c4c0f0d9dd64f6efcf736bd97deafca9dcaa3f06d87f2ed72aeb6a94f3280000c4bf728a01c1862dafd9fc5c7d5a46ec7d3a87af59a11d87f7ff84407d37010e1d946cf225d6b3b1edee2e8bbf1e079e47fb1f66669394fbf2fa68fc56fc89820a6809c251dd62f5b865c547b14fbd3a19504244ffbc7e5240f88d4360f9cacaaf5f82433d3344fcaee0acdeb7beb9c0b3c769eac920ef4f09abc2a2095512045943eccc53b1c03ed24e567f3d7a71977cab9840ce898ee58ed5c73f6adea823394c5c8e3658a6bf5acbbf0055992c312c26c79c5cfbea3860b8764a6d8ffe4491f8a5b8a215e0117a9a68164aee25f8c0bb381195b2400bcb4644ebce1cde5a9a26582cab9dc7f43c33eae350db65aa7dd22a079bdddcf56d848deb0cfa50b3bd732d9da9e8d8ab79e93469de5802b6dff5ac2aa8482bb0b036d8f9d595b8ead94bb8d7418e2ea43192efcbfc05c467bde0a868a516a7c14a889b72c5b73e7d85c2bae902e4e68d1f3ceab2b2773af5bbaee6a00d08063e7833cd4e295347e58f5d1b3397f640c159cc60a674a227b4cd8c10f1dbaed516ccacdd295f11b08147
+SIG: f7c39f9247d22f018999247f0e0005cd63076ccf2fee4163421f86407a41698c405816647351c04e93b54415b62fc03fc8c25e20f7541dab03197dc900b29c0c
+
+TST: 591
+SK: 32a1883eff57a3a7ecdb310221ee83c4de92b722159613ecf816e382437b60b9
+PK: 82dd1a03e5852062ba4a8b6b3b93c5e9c43ff6995bd2aac72606fac85802c682
+MSG: ed2b123b5dd7f5e718e026c79cfa6111924902d189a406ef2b2e56a9ee5573a76ddd1d0629ebcdecf2aaa74e84fcd0208f14eea2e171e7c8608b818feff4dbea52db354227d023250b1f01cb4cc8c52132a98d4acf55a54fee81e094aed66fa0d6b6a200b6b87414402278538b90529a8c603d927eddda97bc4b8cb95d04b5337fa22ceafc8b340c46fef67198d1fd98d89c65cd089e23f53dbdca967798b5cd923205ad511edf706f1225f4648c985e009ef8a2f6a0117cdbe14e75312d8ac1f03d046b37cdee7d69c0f25ccf18145a688a8b3ca8875fe8d90baf86d43969e4d610214f1ac5dbba87a1ef10377e40d7806fd9d23457fc9df29899239fd1d278849681a943ad9c91fd1bbd92b73cb177a878f9059ee07af7a8731613e33d59df3d97796079d5631ed85eb2245106a5ff6a2bca40df5c6e87473b2c08c2212f56fc2933a969a3c958d37c5343ba2760c813a7a5165d231c5feaae62b755df49feca80041a6535f7e03bc48e5f27f9be26ef53673eb7c37a2b64744a6cf17e887734ae010bf40eea03cda212f512fba0585947179640bcc4544b8deb4ead129bc3322800adf98818f99574befd9b0016d4eec81a8e78dc3a2af13cab01649ae2e33d516b9d4208ad6613d8e278c393baa882340ef461ff4f94423d55cf3cedd2a6b56e88365531dd29d68273adbfe369402e6a7cee053da1f100540091a00929252983449024b1c3391110650082f0e7dfddb8edc2042f3c1713c6944ba514ee7407d32bf06c858efec42a78bee97746e5b4879141a13d9fc5cb123b783273b84d57ad3526b7da3c68b839efd23f5f
+SIG: 8309cbe72f804bd9521def5dad4d8bc13886b1d4f662c9bb5b97ba4790f44b801f3195ead0d4ddb660818ecbf9a683cacf85f1dcc9e82c09116d733658091a00
+
+TST: 592
+SK: 22ecef6dabe58c0669b804664973e457c05e4777f781c52522af76b95481a914
+PK: d4784010ef0403eddc5a62d5d45bb243b80b4b9d69c39ca387c6f5cba028640f
+MSG: c535c13d779fc0985973d6bcd552d81734e92bdf10994b00cd4d53ce365fad8c7cfa96206adb62d4567be5e46631323853e38ce4bdc16d7b8f632a3ad9e02619eff37174eac3f0bf2f7a7517d4b82de6aa1af0063819d5e1f9278fb4f24c8cc002afb15f334c04fadb00303013c01667f4932a6c4b97d39cd4a4598506c0bd740ea9f11696357d7d17fe4d75f9d74241a7af71f9d869ef6cd695687c03fc34ad65a68a4888a1a74126cb55cf7da9cb4a6717f6eb88484089d2c5189ae381f25e7b3bc3b23d0c9d9f9cdbbeecfd1e72a05e67bb483a9764d9fc75ad69e4ab1270fb40f3958fea4da559b43980b24681313e8591e68546a3bf76ee34b339709295a8d46fb2432dda2f221812df692895e67cb29cbf6ff4502b439a4e9e43639ec067bc90ae814a293a7bd46968e656787642300a0ff2697e3313f6a418d3d12a5f7c51a4c57b63385f2d2a21d5d1d763fc8d1b93c13435f9e47ee7a425980a6ae6f1a9d007607476783c6d0c7887380f868c65b382d4cc8c04478bbd79a1d9a964b78171d6bcf0b8eec50a06a4ea234d1c23465d3e75b88bc540dade74ed42675b07f7cf078211e907f86d0dc4b978623d9f08738af928695e542ec2980e55a1de49e25247fa0a09678118e3930bc4d24b3214d6dcfb6ebdf4906c928deb37bb9ba29c8de1bb9418db718b2853ba57ad8cae4677addfd18b6c7e8c242621b35c7f0efe8dd5eb26ff75fd5748b1d783f6d68a7d9d56da2c1a978ac25f84fbb2be5568d91e70938221c102aee60409bcbec0c82e12ddb425eeb6ecd11551ecd1d33ddae871ae0c8f24d0d18018732b5e0e
+SIG: 5d0d2af678b3d1b677516d08a79aafd36ec67c14caf5bcdaaeaacc51a14fb805cf2904e8721db271b20df709bee1a4fbfe62565073b2a7e942724461f927930d
+
+TST: 593
+SK: 8de86330b256095e1114b6529bedce182c166f67a91539cebc4bec25add7a4a9
+PK: 33cb054b55bb790ac0f3afdd9a6e7c050efe9006c24f60b8044fd08a5c106c11
+MSG: 39e61e0eccec929c87b8b22d4fd18aeabf42e9ce7b015f2a8cac92a52448a42fed4cbadc085bbb4c03712ae72cfcb800b978350669b0990084f2dab76eca606d1a49fc55c529e1e7dadf39122dd5bd733893858b0523ef62df4f134cf6c26eed02fdbcb30ce474b1ada3f060769f934bbe686ccebd60883ecec9ce3ffb8ac4a0678cdc5b005ae3dba7e4fe8bc045739957d849f69c1474057b428c5425f3cc2516e8bbe3be81afd4e7b575abe88c87f2f03b56f69f9e3b61b3788120daa495ef0e50eb970a645c13d213c7cfb7d0ad555c920a1e5dbcb46797d939fe0401f547bfd17543221a53010de01f25b64519c8f03963e4b9ca58b0113627c05b9608eeaa7b9ae6305c96188160000ee3a7ade96e0b4bde9d0ed6a0ced765d786840a48175a6e090a38af6adeaa1486a9cb5c8c8c9223ee0ae4c6c02691a3547e32582a5b7059d2ee66fa9cd965615c315b476fd861279cd1dd7607743fc5561296312f11e465ca40bce3cf0b1f1d5a30af6087de4de96ce43965a46c4fcca15f281149b5c1a0c88fdbf27409a134ed4f1fb730fa191816ea784d986cc9ec4b694402de1dcca9ccc64fbd07b07e54e931de827a842460ca0bf6b04ebb571fa77787e3884be22f1e402cf2b8a96a5d39770ec4a843036142a0be970bb1ab165a6374dcf43deb8b9830b2c49db9cdfe4b5242e36f95e0c3e077e8d238fa6a8ac0d586bf61b8248fb3a79a270ab22be8a9da055ff3d5bb2d1ca9bc25f7014b96407719de344c3e73b8c114f792075a5c22fdd416154d3494ec3f02fb112ee5737f70704c1b6b07eacbf94562ca7b90dd84d98c3edf
+SIG: 6d01d237dd2bb4188d29bfdec387976a71be7adfbf9e23639b216d0aa0c11932235edccb3b42adcdb6291a0d299aed648de8b1957949b9d1cf2e50493030a40f
+
+TST: 594
+SK: bab5fa49187da1cab1d291900019e6cbafeccd27bf7ecbf1262a700516e7c29f
+PK: f6fb1985ec591f69e3bac807b2eabf263990cdfa09b17809e48e385da065ec21
+MSG: 5cf8ff587e52cccd2984f34791ee6843e77017c3b55ad45c44450965b75d836e78fbd7a1d1729eff6d6d340a903f3cf17d9e2aecaaff2a321fcdde0abcfbbcbcc09f4086f812c46efb01b78343afbe48309f917478455f32000c6a69f79fe211b99f037f5956d72275a7fe7b45296b5f739aa451ff0575bc705885aa5631b0d0850bc2b12c4192435ae5d2f52bc54386497c4a24b8b6db516be09d8ccf1eca785bde97e9be1ac064f094e2afcc307c0e06b4c564cd9a9a95305b37b81f434611dca55caaa031e88495d5dc5a04ff5fafdf0a82a0c03aff1bfbf4ffebae71824e35e751b09270007669860b580035659e23ace76b3b369fa306f2bed95799fafabc2e69c141beb0bacac7eaa347e77be5af3fcdbe7b364a7f9a66d5e17a07df6202fd98c14bfee2ca6f0745651f0c8550f9ffffcafb96ffb3f103e652e78f53916cd6f1dd05b3fe99b34201b07eac2652f5253571fd3822c695d265c7dfdd6c6b14a80b6e87183e6e032e5f2401cd238cdd3769bb6e390823438f5673ea9a479e5c63fe07a07f4e14f57757c4d7d22b35d71c44eaad4873c8eca6f6b21dcfa95520ff9614abf7a0e1885309f2ced3bcdfc319363a2da46ded79a5cc7b6f69383f94ab35c250629cb915d667b6281186754895803e4b95e7418289a6ac3bcdb6e1e7f6f1dc38e77d281914cc404f97cff14fb2c4fd81412d101c1bfb368ce59311e892a8b9cdca86936f3bca7ec79163eddf1cee68f49f1ebaa27ec50f490d61601ca35f8d6ed266054aeb9b199f933bffd6e0050f261b4e13d5ebfe2caa6557c32ddeaeebc2a11f0aa233240da1c7e40f76
+SIG: e316038d6aa15b1c1b61c1a16b36904fe8a289c8d602becc514d99220086b267859f5bf6e9c0863559ac623a56d7532344e8d2f28b3f9df92089708b1b059008
+
+TST: 595
+SK: 74ca122ab60de50cdc04a8e2eda45d9631061bf187d316be5b7cc06f020c483e
+PK: 787defd4fb24a399bd2a4e76dff7d603ed0acb3269813e4df690bbf5b2bc696e
+MSG: a80b46079fa775f8c1a19fa0829be666bdfdca079cad43d70e0842183bc0db95468a539f0db2aea3ab9c7073b45d228a9bde232897a6eb6fc9edf7365e7101ba97c446a519a3649cf527c8a6de7251b92806815ac2fa0082eff75e2582cbca7e1e4da2a446ea233e7cf7cedfb0e2398eb6e11bbaefe3f7ec89f5d73dd34bd47fbcb4d7b22f2aaee373785651841135cd8661a701b21084a316deac3074e24a2e35a0330f7d1479b932f285277c18a441787224fbbe46c62e834a1851ed237998d48dce20ba114d11e941be29d56d02f7370c8f6d6d7e50248dcd8ec89d3b22f4f58778129fafd4bb92ede17714bf022a5bf92be479f18e63852ecdcf8c4211f530dd30f79cbf4bfa5737f0bad3b0106067f41327c3189e6f206f0d4f3c704bf2bd0b161f018fd21cddfb418bac4d52ef02c41c8792e413b04f0836cea1f86c92e5d5703bee2b5c5899e285992024f64e0d16c60ad0fd92547932d0c5cb98d8da22feebdbba8d1de1e7e9bb219a92eb6c1c698d3b33a37f9b8197d26b550febd2601e7a643ea7e1d9e448ae037f629a306ce417aeb79f2e3ca44d8db3848a811f1846811cbcb874f8af09e0fd0173cf175f304115476bf2c6c2d2f332eba534f46aae801c2692c2d2faddfeacc0f1dace440abc2ae5e5a49d578fd7f9de2a841ad6b6769c32b144ceea16d0f3c0cb3a8ee694c38c28073595096c813762cc2c5ec4b0d8d723dd660853278fc72fd6bd9d1272933dd2a38ed9d04b1390ffe4b294a6fffa721ee3bba33a03a149c4a0345265c01ce015e94db419cff7049852ee000048a85758f6d7b1c59c5089ee018ed09b52
+SIG: bcb4b850696011997eb5dfe143f1a3d5628ef1a5407691ee48c79d69abe4d533f817ad7313b5795e46e595f3ae3a9165b1b6fddae86164ffcba376249837f609
+
+TST: 596
+SK: 65eea9ffb75612bde1d9ba3ea4fb5eda0aa6f2556ab15bf1817cee3b95bbba12
+PK: 5b3936dc749b6b9239f15798accafd884c3659ee01b2d17d74fc7da78274e7e6
+MSG: c06936323ce3253cac5ab4f6b83270cd4cfe85d0bf8bac1e1b8d5f0b153f541c8e8ed95f28d5c85a2315cd931b7cf3edae50f92830599162804b1363d3ac0da0abd09751023bddc16288944e616d21d91271978bb782d3ebed7fa61284c7490d27593ca8a3d5b475623307010abc1fbf793a816aaab5e0924dec79d60498965cf7f80ab59fc029f782166755b72b869075434ab606cc870a7c0bc8bf29aee033fa9cc122ed7c8e069b547dbae25901b9e249b41fea0bf8daf3826866bcaed2753b5e91ae937e717b508a0acf4c3b061ff0cb9cfd380e2494500951a662fd4928fc5fcaf6c18e84b1d378e49bd9d59686d087ebd552d07fa9ba816fa5402ca9e7252a648d106cfe6c431cc2a053e2294637cdb99d96abe689edabc5ca070f77c1ecd1d52d5385289f17ced768c3971671b9c0b2f855b8461c1e746c7b38f77896b85afbbedd08375fe922984614dd849fe2cb89ae7149dcd1d37f4936e67b1440be72e009398be6f083bf9611480b592fe2f0118e253db5d2e9e4b4541c11da00f7161a736e5f0bb934208e3ef4e0b9a52258203f060d18a195159e5e268aa28053c834f7bd5db9bd71f507d91370b3ffcabbd4acb3071d3f6d52c349acf35095348cebf5a86f8c59ddc965eff610ac425804c0e2f6be42853f5b46434a2c31d9ac99539bfdc04ecf2fefd04598fa63c139ff6c6d88410e73bd328cc4349ab4bb86f2e2ed7c73de96520ef7730ef38345e0f972a84c5388103687e68c50f9d8c9af903bc632d43204062a4f502e214c07059c2cbef72a54110dbf73e425402d17e978ec199b518cec0310bfbf7d9ad300434a4a
+SIG: baa7113155358c924fed57488a6567f8723850a9f5c03a0d7de85fccd8fb4d17d7753523b00c0d8adb884dc0c8a7a44dc2a60083aa5b3c5b94a8d880f2a94d09
+
+TST: 597
+SK: 08dabd4e5c119ea907ce45f0a7af9e62c0c3f1c9ec61ad10567d79362854c557
+PK: 945406b85d7b32e0b1ab1200b94222de1aaa68624c60bb4716b0bce9df005771
+MSG: 6c4719a5a2a6894835c4ac1ed69159e5ebb5692ad8eaada439f79e96684b36cecfb44b89015631663e0644f6c7ab713989d742da27427253318a52432dfab2121d1e9233ead719e2c86a6be07363d002173f205446ca95fc17b24635827fe315f222408e45e833f29ff08ff31dac583a4bec7076d5cc78cfc94451cbf4f7e2fc5b5ed8070f4ef808be1d8a680ecdff59010f39b1de80bef1719f1e218e0ce0a1e393a566c51764d2370d95a61191d8f7af740dc208fa7831b210670512cd73766e609e9b780021ebb20cc8790d8da5f10f5b6a114a1db88f66766501802d9c366ea3fa6f1b1e1e8b0420943413cc6feab28c6b683cd2b333069c8951bc45e8a13bd522578351c882f7c342fe4331b921f533c92ec04a49b292bc569ddcefcab5727f9b5625b167a902dc896d8bc7d8e99920f5db8dd767839c43e3cdf947080dec954214a6fbbe0487a2f32cd17a6b000370bd414484fb73c510ea0124c6cf0fe56c0846a79bfc59779d3b07a1bd2c7fb7e2d0039f0bd21c8a308fb0f58fdbf94efa0857ac3bdddd86d5763e205ee1b221f060cedb8bc05f031b606cc74dadc5db04232748865a73d6ccddb4d5e930d528348c5be9088bfe34458487a67b19a18eca25c0d3fbe2195eb91707b65d9161ea93eddd64a634b23280195fdb0d1388f6998e1858a45b886999b844e6795d83d31837e4411f71699226de1ba0245608000dcf223dd18359b7c6d459a65dbe66c90f5cb8c09122187a3046a16dd179c3f4373e57cf5ee0eab6a212cc9ed8b54bf37f1d27fbd79848e4ec1f567243ab8740a05149d9602eada920a46d610d3cc823b56498
+SIG: 33adbfcd4ed4fa67c58b5cb59e16987148697812660b3531ff6a21c749b9601660baeee2489b82b4cde132b6e62f2f90d8f9927860aaad25281d03eb17a9520f
+
+TST: 598
+SK: e0f7d00824c5f3701e5517a4abc13e2f2c0b138c836977843bbd1eeffabd968a
+PK: 52fddae3e018a68473b3168d0764cfe274dcc834c90a91fb4fe74b939dd238b1
+MSG: b39e3ac75a221adcced09a8591ac5e2fe15dfed5b919cbaf14c65eb7cd93086ddee3f7472547e66ddc70062b976297d1a3c170ee525c9c53ba93a4c4fdb23572b7ca6ed13853e70db1d72edeb9944bbc354a520e77ae591f318092efd5e66d9c0981c4a4bda98aa4e59045ff9c4b4ca3acb2ffd893201c70b34a77f24eda54549dc84ad134a35532553815888ae3dd9e241ec4ebbff86f8c1e8adbaac4b91afd18228cbbd5dd805acabf0a1e290ce5dda0251adfb37cb714c139b5a3242d88c64484a37655cc8fcbecffa97fbd14d64d512bf8f6305f89c50922de541692158fb547fd539f1e5877cc649495166332ea2b685cfa3f602019df2ab2c25ed96b68745e9ae89c948da11ad8a830df8b00f2e668192dadf2c5620d35c6e81a2853f841e375a0d9fca2d296efce2ac38d40b030b57560ae6e8341339b3d3c2d061164124319598688fca618fc64c9e8f5f831097a053af19d7dbd61218d926742c2e9a42a79cc1b148912722d8cd5ca793a1ad73b5f141b41809c2fc0530b7630e80390c6b338c71868dacc59bf463ffc489016bf67f9c9d5553c1ede17152813fe0b264b65dca1b2b38e4b809f8c9725ac5b1d8d2e56bec9649fe55c7583ff23b043d6f3768628f1f0516337824a5a56b409520a6a6cb77e4f5fc20b9f6899e00ab22db10d182f09b81e94f3ad568a0b81244df3f1855c6ef222a41a51b62a4649bb82690ab65facac0d81d6fe02601170a8db62cbc5ec9955d7711a1c39656a9f6e1fb6bc183d9bea1503531f17362768bb841f9d21f13a2c991e55dff7f2b336e29eb29507638bdcad7bb31c69e909207ebabcc653ff
+SIG: ccdfe18ad6d0b65d086d632f83cc46ff3b3f2c07bb8e769d0fb4e82df8a3873f9aee35fdd18a5783603180a95c9f74ced9db5146afcfbbdd40df29e04201200c
+
+TST: 599
+SK: 6acd939e422226cc5443d4aabf58c11af650cb40b9648b4da38b927bff9a58db
+PK: 4c0b91756b9e206f7863b155ffc5509bb52477ceacd01ca011435153678646cc
+MSG: 8250d531cf2b66aac2b378d54bc57fd329ad5a414a599255898b3c3b45bf9c0d2c77547566b660eecc76a695a2d608abf11a5f6db3e607fd5a21714b0fad5d814c015ebf48bb73ad75da9c03c4af5489e782b6bf7908a1bd528d7ce788a18ba3528e3537aa7bbf75f6524bbd19a5304ba2a4a3ee58c41fec3132ee6501641215eff746d7800c4d33f52be8357e0ee758041d91cfe43c60c3cedc09b0d46d4cfb9ae2a0239b6f33c6941cff35372670eef5c8859ab65b6e9f7ebce32fa15a9a477aecdc9683a1e33a1edcdc90d420a31e78c153d26020871daa4fff28acc3f11a7206788806b6fa023468ea5a3d186d10f0dd567796663ba37c832fe75aae7dccebf319f93600c46a22f57223812ddd0a68d76baf5e27a9fc8bd68cc10b5b5151d62b41f9348e21b715352f2630b617f813b0c28996285904cf294e9c2856b17ba35f9a82198b8214a035e2896d6568be42392ccef32cd4ebfeebf12be0125206bbe89336d3e762991dfab68fc99dc1649b891383db31fab649e628823f4598cb636a38fe1df73e68d7425fc5d2eb55a0fd1bc9f5ceaabd6dd41f23e4f086c692633dc3c4619a97ab0eada171f84adf20ecc8ecd47c51cca3e59dd809b0aeaa730df94be3bacfd8ee888bba9d570850652cd4d5e6c552a57e9f48a2b06aacdc708d84a376fbc6c94ba6bf64a5f018800a7cc851245aedb20378b329acebb2977c1398082b3a0e5e2a9c2484fa301d3037a8224ddcc095b1dbd8a2315b55bf3318c27810efc3d8e25fa7a8789b73a4f55059080b08abb3699b7b8626cb2a780d97cc1ca8032851baf4ed8b64fc4330865f84ccb12a3dae
+SIG: 79995877ed24c791684f2984bdf9609c3f7b576c57d162ee622d4ce8f36d9c5573169d8801216f1c46ffe2f6e2c09048e47d4beb997e9abc4abb129f9b79690a
+
+TST: 600
+SK: 4deff647cbc45ecaedc3f7ddf22c167af24e3d63da22b0e6a5b8439c0f3b1934
+PK: 0c27c9d77ac8c725bb0663933ab30d1aad09cbcf2cd7116c6085a8499f701402
+MSG: d6201ebc21cec1e9bc28f957c9d029cc38f9e85e06dfc90bf297e61f2b73b407d982a66b91e94a24e91d06ab8a5c079d0f69be5788ea8feacebd917291192233862e6acda1e8cf9a48bffb5491dd65af541b6c72af681a81823d98a0abeeb6ba9f95465b8411f99e119cd28479da984259bdf86c9fef3cca34e224691f183cf095037727da9cad29f242f83eb4f736e27fdf67018d711b74c45b2955a6a76ec15330df5bad8030c6b3a88d72f28447652ac8902b5b76cbf6b945ceabfec04a9b8cb30f43d9eb773e6705594f0de1b70f1a20c99fc4b1221f8c81b0bc30da12cd5dea8f4d90f13a811a2cc11a96846aafb4c42a00e9ae7da256a0d22b198afc25cc1041d24e056cf387601d7bf7eb3182d605fe5e63b18d531a5f84e5dbd0184a76c6c467a8263a98b5c005fcb2aaf989f5cbd0a9d903fcfc609d6e57d9c439021cea93e4c4e991f193caf3243770b32578748076b7f4cb97f17c17a79b82253c2423db698cd0a33ab33bb09b0b08cb8ceadca1e29c5de2fc12b2407b6cc5af5ae976dd3ec630d8339b7dd11fa34caac150c7c4791d8c427b0ad92e0529067a88d52011e1e0a18299b969896f8b8360f75c45c496da47b09b450f9822bcbcd43f4293c516802bf747c4abeedfaa3e79cb9103d3770f5607b77516e5b1ce0f64b6eec7bec3c647c006956dc55b6c79f6afb39d1fc3ecf11b974b44aedb72aed1316635083c2124502e5c72d86ecab6ac90243eb39a6aa9cb9480da38e1edb8d28ff90924c05d5d21af5af95957b8020781378711a29d0920acad8ccb39a311693278c9900b470da2bd4c12a01d73962644017b6034713b2a
+SIG: dd5489fde4ba87d1173d4cee0682afdd4bad80dd770ea7d0dcebaf21acc61dd6324aca295ed0e23a915ecfdad50f175ebc516f1be5b6d87d90bbe38622495302
+
+TST: 601
+SK: 5a19bf6c941f394e93bd3625fb81cd9da81c9020b1c531257a7b5957bb079211
+PK: 20e8699d087ce5e8151d28053dce66c23f28081f35bd26819bbe85d38a09d702
+MSG: f721ca3a32c1e81c9c6f46d5e1fb50e7ce2f4e709333ca2b550d5213b6773d670ca59a2b5086a443843ac50813b244c9c9fac6d119698927813512c84fe30a89553010138f91e8176f5cf25789d7281ddb83a246705dccb999c4cd0ae219c645f6d71d451ae1f8d2f9891af8ccce03f438559fb83667b8077fbe435a744af019d6d1399fd2137f5afb8ef3f47bcf735e7c9ed8a54ba0c1c656b6650bb30adb1d57ecd2074639494231a2e9e2f985ed8422ee03cb3fd738c735a1b82806047460ed84f7468c3c64b35db06bc58de4bba463e638a94133df106ac4f470361ccde44157299d225b17798891baf5921986a2bae326dda0b89617c677bd1408ba2748baa67c8a2c5a969bc00cb40dbf490e07e22c913afdde6304a07fc9e60846992456bfb0663a09def68def67a16d29e98c7b55351848a8cf92310c7463c475f249c6f7557fd0d755ca88f877847fe0765756ac34a23f7840d95c3d294e663bb1518b75927c410757e0f5c07c5a7fb215dc7207433ebf791edfcec90e930f8e3ba9dbbb985413c223be87873bd323997581804d8896da386a6e9120050a0eaed31240aa17c7b6694c30cbcc3c6956a6820fc9ab21875533963dc3b0d88358271276c6056528910dd989ae0c330d1798f7d8e7d1184b84a81434325b8c302edf601dc5e6f847fbacbdeeff78c6621d1dafdc239b18b8c1afdcb4b9dabd5d3a92a932ea1599546e625f96d6ec6fb1cccb76b476b330ac59259c634fac9b3fa7de7ae7053773b5befa001b04929f74b71241e1b257696d65a26c1b4ac86b7b1fbd6957fb9b95084ce7d70090f55d44534694305e91769a82941304
+SIG: 2a2fd6054ef4e79b72191a0ccbd2b18aebabe8b9a71861ded98b7cdcb6a6255328bc1aecb0c9335721a9a96ee4b5b43f90d322ecf835f78b264dae6e387bfb04
+
+TST: 602
+SK: b506c01d69746eb4bc6358720e438ad330c88b605aad652f4799573ab0a1aaf9
+PK: 7ac8b68863bd69151583789d864a7357e3a045fa86522a9daa6e26fb79ed6d23
+MSG: f7fc18066ed04b30e633d9865da3214beca60bd796019cd7ecc91866f9ef2446c1fab06d8651be7f101aec7bb84ee21e71ad020215fcfb36f2d11e4579ac39f8e2b1290e3896d522bcf513aaa06771f86ee228cff3a20a1f10c564339589bba9605344c0a6e682ad5ba40d1041941bc46f98b9d09ca17f8f044e983b8a4908933df2263cf78811c24c8f4814354f6f4c68b7ee7b78308293bf78fd0ff122f095c14a73a59797172ae05cfcec19563eb18d2bc5300ed4bf6bdc443ea9b8bc1cbede94cab905eda5a6a931597de402146fac9cf8cd6a8d104669f913fa834001ca4d090fb7949d3109a63c0549b03f151b7117c4f46974ba59c68296edfdde7692ee432acef7610647e0957865e62c1a0cf05659823a55452dd5e471b31c5a49ab05b5aafd5a0e530e896b58cc522ecf19e52ec82fa147f9e385174c7ec33d1d9b86934aeb4f6c5700f7d5eb33ff73c9fc6aa47df51e09229e6ae894e86c818bef065f825971a4cb90adfefb31ebd9d1b79422dc9868f9f74e7a32cd4071efb69b27233e6e5c60dedcd5321c030a46cd26f5602cac747ee4b522d857a3321a03f403a6006250406361e48815afba77ce08903441845ba87225d8b24046745d4065645a1b98410cac48d137cbbb8ab1eba50da9c231e9acf322a6dbec0ef416a446c3b610d93569fdf45aa6cdc1b640d8f301d78693b2826cc6ed468568ad9a0f94aa9b9fb92f7e78d484fdf5d8d45c991e28074dcdd680d3b1f189ef6bdc320ee6e64dd1f80d9264d83042d2c43d83581ef0394b1b5d1f69f3bbbf04b7c808ba34c1580f16f76537b6a7ebd0a1908be9494d3fcaa9871db15750
+SIG: 17a19d2691b7b046d7b19669ad73140db92f0c978c7f61bc3867d92ca9d47580a0380b5901bad82af45f676f74287301980f71871a42261dbe0802950336e60b
+
+TST: 603
+SK: e1ccb80a262ff8af1eda075c972c8e941e77cef57bdb0a82572c28200b493ca3
+PK: 3d37e2a5027effdee07fa511e423b2bc56edcea075b41649766725c6b30a10f4
+MSG: cfdc5497b023afa62a7fe592caa92b875c7705747834002f7784ff166189398815d4e8a7a0038e1fdadddeba51057327ad1960e859cee56526bbb4127b6a5f90d04d08b15eee66c9ccf88b4b7d1ee9d3b8b8c6f42db3c34e59048a15c6041f142c4079368b7b11e29970118b99e5670ae31fccfdff1399142ee06b2e3e2b3c9707dd64119786e2fab47e0bad2cc8b558d963bb48a49ad2c637dd35b25db54bc5a2630222fa2acece9ce12ab0813077f7659f5074429ca6b494331032ae792a599c425ee297451dcf5ee195290312742e647a7795b84dcc664ddae2a1fbf8c4548a37fd82d810e2145f01df1a6d3bcc42a91a10768e091f3d69329a7bad6c072cac6d89afa31c029056d6b62212165cebcd49ac672e3830267af9f28ea319bd042f6c59de4701e58248736c8d976acf93b99d2f4647a547d392447a48dac11181e16b1501a94c9316e5a67c990b35810b4cda0473a6a4e57614215868e2e002c6058b42e4eeec84139dc19edf5f80aeeffa4f5b07e8fd23139edda31899ebe6fee78643ce686b2963a32072bd3b3bba68485a05c2cc0456c3da50c7c8c651a3066d13a3660bd47ab6dfec49e01557a6742896aa4bc6363a797dbad1a409cd4a50911e70ea007af8e9b1bb7e3ab56215a575c90f739c2d48b3b34694b5acdf07980ae528de0621edfac8b8fa84954d56dbb4d03082b984f13e5dbe9c7112ff9716f55053064662ce0fb81ea35f98fd2cd51137a46f64e0c1caf44e5407dc961760b2597f7f9200617d471340cf15176c3da880fe4e0e93a72fb94926faed865dfdc772e185292c1e36b1211781c3e938e3d4f24e29af517a379683
+SIG: fda34b652b79746f897e222d37b77aa250d02c527c4833df80ea41d52189d50700e128b78ee8149c9b19f3abf755acef5348f5fbaf1ceb41c038906ac5946001
+
+TST: 604
+SK: 4fc512efd86e3a63b395eaff1ba011e1590fb9326ad3ffede7876dcc3e9fabdc
+PK: 26c2a22f9bfad90606dc613ff107021fcddbec7237066660b488964349e0c828
+MSG: 07cd1e9bfa38a7d8853465a93c77ab4f30faf914e48bc4763ba07bf96ba808c1f59ad4ce9b7d921fbbc779659d7ca36edb7dd3acf7a29452a845b49fb6543a3b6c5c1c293aff618485a10eea60ee9649ac9d481e6949967d3938b52fe09c36b9ade07581db4eb542a97f5ac8ac73d3eea184722556760cf483090564553061b90a0b6d2dff4707be763937a10594a82b766bb2cf6daa52fa8d7b48f32127c431ad9aaed3bfdeb99ad42118a1b4de7b992134ed9cdad0b5296d197a485e493ecfeca3653ad2ce0f9241aabc096d7c4ba603ba7ddd07a8b257fe523276417073a65fa4434256fd1f239ec1de5da1a0a8c5e686ee14d9dfa438c53b99c954afab2f79e60b7126f2cb58a26e290da1dccfc301f239748ede7bcf1bb7ccb4720e692f57e53e6f59075399e1080ac8aa9a61a568c4c569d36e76a2d7271f2c44de4e363a8c916a4e446b027b64392e90ceabf6b6071bc47a1379b6aa6344763b2a0e7ff7c4a27bff3106721c253e4c1d67c37fa3d7c1ecd055b8e929d52a8e45ed89fb180f74b552fe06f066c7e4318ca2f915946e8320d5806561472fb8ff7fa8072d8e6fd1ce63cf87382f7b9404540c1d406c70b226853677092645ce996922e7345dc07fb7339f9a54ff07352dd2b993063c2c83d1281a4fd178e5a5f80a5b33c229d0578367d44192e9a4d21e9734d3bda083b70f47103fd125177021df3e53d79986efea2dc04f02c0ac278788319ef3a9132e6232ea6db39ca5870855f9592fff6c209ad2f1c29dd168552898979ecff8c81127248f8310515300656129d9b7acbb7ed1e46bc98c04d1a35b18913738e9dde4d2b065f4184242d8
+SIG: 82c824a7d1139ec73ae1d023adf62811441e968287f1a580b859cd66cb33b58e409bdeb2a874bf4c23610bd44f693147f2f7c29d443a905084f3eaafd9330e04
+
+TST: 605
+SK: 0b7dfad05ba665111e1681bdc0bc8ba973767cb85877020a2dbf918325571d9f
+PK: 9505d9e86dcef56c9db76f2862b90e1f2773202f1750405e7ee5aed0fc54f8b9
+MSG: c43fd34bb1424cca4e4dfba75c28be801844446ca089020885c748382547164a9d4a7f9570d3d171ad6981ab50eeee08a4a6c66d7699d23edbe1faaf44660c72f4552d87d265ace8792823474b90a5d7f7401deb9377627f60b036b36e044eb76bf132fddfcc0ef5704a633d845e962b47517f0baa34d3d6e9a8b9f8168bcdc84c6d2b30c6f343e75357f7f2c0039bd254b244d36cd61675581fb834570ed4113a78e606f145a111992c2c6b61c4267628ec87cd88c36a3c84706e44ae96a96e0c8480318546d6ea6a6df18a2b4f19f8360cfbce4e9d1cf1011ffea5633a66619aa4a65cf69be4459617945e4359a9d43260ca1a20f4ed7c1ae5ffff3bd92294ea70abbae0385b0935cd1c0eb5183029c585a0294b7999e32ef7a290fcb095675dc4f601e8f2c96f35b7349a37057509f4ec70c9f50f6011f1f5e6b061c091d11c0ed5dec8ece881aa340508f696d9e9cc7298e6bccd7c210e2ce0ded83592a3cfa13e8078fdb3258b39f1d11cdfe09670c1e60a3910a4fff51c6c7f7d6624f4c93df8888c526f484f9b13e0a7f62964783978684e292679800ed5eb280e287c7e639e85faa53fba2fa2045ce27d8fb308360726550df9752db305f8f06647970d014691999afa97b6193ffcc6d532f4fa69e133a1d10f3047fc00381f4997bb84e5b6cd6028c62132cfc024bfeb980301f29512bbd109d089ace182cf9c2ffab1b17eb00b6eb46ae198da993f5efe7c1dc22d25047c1ee5246517e7f5758f996abd83f13da22c13dd205ee191b55afd4831ef078bb6ea073a625bc97c81296160bbf2559b275cc37ccf01b91fd87d4d99a367aa9978dadd0689f8a6
+SIG: 415adbb2f2b9840577fd1841f9aae252afe8f5a72236017d50db22d228cdee9f5b3e8fe9a17a4d4e98b7341381e8d8625cdcea956d253b74e02dacb84920a009
+
+TST: 606
+SK: 78188df8c754785621e27ae58e100d5080e16e0a15e277051f95f080900ec0d3
+PK: a1bdeee98b0757ba9c2d8409b87424e64e42f9932acfa9bc71fb3f8ca0e11d52
+MSG: cf70cca57feb1beefe985ad5af9d4348d3a46a63de1075381fb3639a044fd6e6091f5db9c94d39be0f13ade6d9a074e67ba706b3a8806295f6b654865728c58ca6e9419d5d043f2110814bbf36fc4070e4d9454965c251202ca395efe3fdbd544feb187e34ca3c80795179552fce9aa804430e5b6c8685341e91d5889fbf3f981904620ffe7013f53b939e17443d614e7e6bb57ad674f3b4b001630526cf7302a7d0afe7dc24d6dadef6feba3f96973aa5b8d6275262e430a82f678696971a8b60e38d3b2bcc170d5bc20302a39c596d27fee39e5da5b10ea9f382299e19819717a718d37d155f13923182b5b7a1c54ca109b22ca8e8b26ca5ca3f3b9062219461bace97e890c94e41ca3d84587fbdf6e240c35ccab71d58477d28168e93372686d42aad324a3f16afe0e9b89ee20e485fe6c864b5013ba88399eeaa159835a8b2bb2f25f579ca3bae675c63da1b50d99d4ed978692e5600233f38ab7e7a5ae0fbf8c0b69cc38bd30eabd977efa05ee2c83514302bd40c4bdce7a4110afbb6579c620e97f8cf2e9bab2dcc7c33f196e57fe761a050122894b7a75a929531996ddaad78de1d4d924cd93a61df227776bc1c39fbb8de1c4438868b6a3a2cd94c07b29e3f6b23cc7e0b63689009d9d0bae1606bafc7a808f2d2fa2562b8dc093842c01fdb840da4860aced3fc525ca334edcf65948bc416f98c450f0012a6107dd7f8ede40e1c48c9e8a565a810b9cfd20356db19f1dbde598921332e0d813f0cb87684370388772ff3cbfcbfa299c198c97bfb9617768a05161f4169ff5de5d9f40062090fb882984d9d5c7aa78eddcb9634e466b8853d512b4a546d7423
+SIG: b94114eda46ccfc22a4471a64d790892e59c5d505618eb0e701392c709613e2d503a5c2b66601e636a3c1c7d49b1ac798d9089b0f9ccd0579bb90634d0bd750e
+
+TST: 607
+SK: 73cb02b0bf26a015da1dc301fc125d7e6c30b63c9e6eee9e065d4e847132c325
+PK: ac9e3dd2ceb9b23e748c04ba7577fedf7ceab9ed87dc430b5fe22eac50950e0d
+MSG: 0a2b61ba35e96e5819b88bfdb28b7ce02e64ae9cf572b21f13552c0db10f3960d44ba3472f43abc4e6295bdf790bd933ba3975fd4465fa3e2fe2db02b6377752223dec98fcb2404f3aba43265a6fa7976b6c6cb6868b881bd6f3d25cd9d6f70e512f8089c8ef26fd58245053779e59c4725aefa26467c9f500e17f3e1573f1a855e9b8b21925ea0527f3ce8d88fb54a47abeed14f399cc2d9f1fe54665fae0a8f0c68872a600046d1dc36397d310ce393fceafe87c17ebe122fdb543aea71085baec98273f41ac96698c150cf911d0e5de2392d84841d01276aefbfe9995e10a6d46efdc2678d456c9f36b2e10114d1187e7aca739037ea51f85fd62a29429ba529cdd8ad91347497487ed7e8709d4776ef68670792d0615bc96da5178d606db63e4e5cb172acfbc1cbe20269350f1b605f35dcd479135bd30fb4b5a39176cff744ddbb306c9e7b4167de0379a6166be5aaa74d7157fac957d88dc57597cfef23eb5108b3ce53fc632dad1b972a29da5de32d20d8ecede67ff00da4a08a0cc1a98bee7a94e3cb32fee94ae25a413544702c37b3e1778a070cdd4840bd39f5f45795192a867863876ed0d130d46e2913935082809f7e15a496710f255d783da3d016a654c15ff5df907a3ccaf37cfe11c8c3d496507d6760c053820f0f594c3d01ca269178aca525ab2821ef55f92d85fe685ea34472ed1398171064d74a422ec91d1a670618fc9f32424bcb11a77f6fb4e2fefd2c4e8a73c452886e931664d1a83bd927329c04d250b83521d7dc13c91cee1ec050e11d42a4b0c8c069b61c4422d3a49c07eff2905b7bc7f4a5b43e6b0d61dfb50e4eea2e90d298a781d05
+SIG: 1a5dd4c891c8e132570187c23b9a1e4b26f05460e875673819396df561c8af0e48333b62c77729d49fc40e174a7f3c21f85ef4d339ceb80bd2e037d803af560e
+
+TST: 608
+SK: db05606356bacf23aff6cddd42b2c694352b5a0fec560aff54d9bd9710efe06a
+PK: 32a5c7cc4909786b48a53f31093f549a9f1730ca6690383fdb5f14c2666e3132
+MSG: 1bc9c2833f37cdf1356fad166768642717701b38a0ab0c2f581a26d222d65ccee4bf0f6dfe64d33bc0239f71d4b82644b01625a1a35fe798676239e0ca779ef23138eebe3bd19de2d8f7c15b4d96f13e51bc633bea5d61225bca1d6339ba53e81f7d8d24c5d60f04ce8c726761d264584f1c7e5b5b6992456c1c76892d6352111e3b926fe025c0009db67ce0ddc7f764e0c9adb0481bc2795484d96373a962a7b74a5596f527a73476498c7823dffa6c8543b07971b5aa271c12255e0918dd73f50c30c9a85ac7c2993dd655da59431263f5914be706374be9c07585c2871328b4dbc39401c95707387e6e069d44b9d8fb058f22e315aa0d5b4f1168fc107962b064f7d845af8e2131951d1cd66dc84dba46d200af4f4c5f51221bc9b2196942f8b40e7ddbc9aeb3d9afc071259513135a016f2866099fa10f4c3b73500bd55c477b2415e10a279ba110d294f3dd1842177d0b4bfb1734dd0ccb7e394b43d16f0b7548362280f434764da57f19ed3e302e5370fba49664c230057433cc647eb27cd2c7c18c7d66906f088246c22f7f790399deb4c5fbb906181769bef5afbe8ad1f5de55be588f52f69c54d4ef5a969a0d995c27407b23edd9243d2499fdf29473b1955c84b3f7cbdcd81b7656ec0be9e0fdb3381356960fd0ca70e7ea74b646fcd313948e6ddb47609476fb6fa4842fa788a0d57be3b0a6ca1819f71614760043ec4904881939968a43b5d1928f84a5919093bc3841588171a9cd390f8fcd61538b54e6ef99770573e1986d150fa96b7a07e1d194af1c0b405500acb3d10e3be647c89862006fa78583e76166842920160eb57f0b2a6edf193c44c5eeacf4
+SIG: 53099b766adf2944b6821374842c25d6e67b0ccde9c637fecb11b8b8b07203e3075732805f4f14aeae73bd62e308b5887d689e29cd89b23a476943110717b100
+
+TST: 609
+SK: 1d139b1ad0c3af1d5b8be31a4ecb878ec667736f7d4fa8363a9809b6d1dabfe3
+PK: 2428cf1deb20fbad1fdc665d825b614122df101fbe1473a79996baf6967434b8
+MSG: 8df2d2df9b984da84433486a813c98c5973a696c11624610b23aa438083464f65a76796615b728c2ed4e60715855afc239450d5bc0911ff2a85230205c6f1349ba5bd87ea6f720db6ba70b77421788e0c654aebc23074c5f41d2290772140d981a6bc4fe709a268e64172a026b270118b4db51ab6a13c99b063186d8d5b338e977eddc6bb5fd7dd57d9845a3c3fe76177d5738dca16a8f9102857500174f23ff4c3bf3c8536f11580ef8514a409f5bbc9c0296f12e3478d4087f95efaa6c636071d21157bf11774bbfe7693306ca7213da4713ebaaab3554edf08011a5ff73da120375aed19628670f28ab24b6f5d5a1d570480f65d3c152bff1b47bf0666929cb7c99d9033faae8534fc35da730b811ebcc25ae10a195aab12c326aa45bf805c62dd4cd5f868623c04a8e1c6aa72f1ea4400c60867dff622f316434f1ec89503c6f9f65c137b4944cbcb35f086c74cceafa2242acca6ffe611c4b5587f5b75ffad349f00bf96e4a580a875b92654069b62eeac0bf78e5aedd71869ee05b9a94e1c98e35a97800a4a21220b039cd5ebbb756d40b4042e2c84a2ae98182511dae8ed3b89f4fa00fb8ed946316459710052ad4c02f63df05d3bb1ace33672151bdf5dab46c7b583db373899d4f035b6c111258b4e5a9e707a11d215e44e68ef1a6f053809aa51bd902e13ca99c1b1cecc83b9c235c710e797d2b1a249b2ea079b5c1674ed7169f1b6e67f1ac77f86b743298969335a772440f7fbfa72513500d84166114a8fd54139464d42b995530d32370b69bffc7589d6dcc97e0bf17856cc3bf4164dbeccc8a881d414d6a62029276c5f8137c0b3c68bc8f4bd4e7cff65ef2
+SIG: dd645e51edab04db31e33172cf27aceeedcc0463a963914a0eac8efd5a34341f6bbc52e042baaf3b40c89a57efb64574e69677fce955246c1fc0f269ef819000
+
+TST: 610
+SK: 4d22e331e0cf6f6a272db4d20687ffb059f1225d81e41123b8c89b074de76a3b
+PK: b1e4cfaeadd67b12d7b9dbfc0f88edd0373f9a88c7fa33fb7f2b1e475eccb61b
+MSG: 9c8e3f5b4d704030e1ba71f02efc4b87d6fffb55bc3d8d03818f915624fcf701c54adfafa2b694b87751cb9f69918c0f050f4c105d5ccb40100b28dfd4f411d591c12019176ac2016bfbfdf0ddf11db8a7e39aa7b9e216f667c0a15fb977eaa9ba3bc455cc58945f3e944b8ac2fbf4d24fe7e1e619cdbeee3e5e12a9a527d28f5fd7cfd9220f1308d897b6d4314a5a0187864a2d621cf1b2844261247bf520bafa9bf226e115681ecd77427980cd12b08c359cecd1de3f5545f807f81ed76302ffd6477f89b958cdf12954cf70c142532993831647eacab0b4807bfdadb4389d7dff2c4ef0ef5a5c61d0df762e2e9080a7181cecd06a53199f0dfef702627adecf5fcd9b3e68c72333161727f871c7d1c43051ff1c921fd53b642238b97880d64e25fac512ab954bedbca540f5b20091ec72e67f88770afc32f2125ca0da4fe87b56aac9177f1f4f67c851725c5e8afe64f664799833fd79100b77ead25838879fff4747aa0d5672ec0a94348134bdbd4bb39b0c67a0cd30602edf4fec6f7af0cc2bdae126cea842dfaa4391dc5ddea938e1792168240c2d8b25352f9f3a644235ce36fefeb6992ad88e287ad2d85bd850396fc2e517a15209f5920ac98c532b1f4d869beb08bb03cf7c91af3ffced68d5fbfef86ff94ece6e2ead3484ce080db17bbe40f1db432ec1650ed24fdd250f3345745c9b7b9198c9109a37261fc5ecbbb12f83a0e1220a1867d45fddfea81dcf75f4ec7fdb5250e57754d6dea270b628a79530ec28b619bca9493e6305cfc4414c1c1de3389e890197c85f28404f3fa96a1e2fd9206b472e8a0a0d32af55606bb083f76a19b8eae3479ae51d98a99a62
+SIG: c366b802f682fcd70525264fb1a3cbcd0ee35ecff5977c2a554da939229f17819a961ea74c3d7a7881ac5c1fa16bf984d9456a1388d3463c4494429b1dc45402
+
+TST: 611
+SK: a5228ff9bbb6f232327eb8d879d7f8b277ca72bae1f9a9d0e260dd90571db4f9
+PK: d82f6a6974f51c8808d9d617f4cec2d8a37eb11a14237c9ab9cf11ebc80ff6c0
+MSG: 1df7a6835e3310983ee7ec731125f5b5cf117af0e36b3685bf54ace1c48c46300560a45e9f9bdd96a0bc4d14e89d4b5721a2caff6618b182edb1202f3d0c5d118d09b61812c010e8b196344541cdeefe5fd1f961c5dd75459555ab72ef2aa7a759a4f3ad3caed44f4c9a8ef95b76ed9a99b55dd8a260ba08010d29ff819f2af3513c1a640d6ccdde4999205f9fca8857115d8b5db9f70a62e5eea0d5af065de153f2ededeec63e15c8e09a92582182ac07d81ca63ca4aa597a2220e70481957d415264e258bc263e1cc36e53478aac5ca01694ccb09b4ffd84739972c7dccf3defeafdede162ab6c58a1df27371e3f5493067fc9e2067e579623c009fc825eef0e010fd1ccf2a8d3fbbb3156f9dfde0c7cbbaf8433098517491b78db9698614ea40e0b1e6a1e36b900453a16ea276f3442bbd27a7ecb981511f5c9209eb096e28588b65b96b50188c0381ff712bc06b2c655cca0751c095d8016251585851e677434dc3efd087a12680fc22e5b8310a10e32caac9b71c876eed31ef09f7fa012ba08dfd2ad68c1e147f50598e550467ef99f295a318faa507ebe776ce55c4da164323c30a5e72dbe027c3ccf96c70197a6fb1b74af133a8be2b03c1b99fd25b3ced51fe3882021a3afd9229f641bc6cad4e1d3cb6ed9b6b68a25f1e1397289981f78924bff24c8dee6a18a0421fa32ae3ab60a0d933a6af4ff704874b09b0739e2f29d8f252d79055f89d3bff10a22c54ac3d8afeece818353a6abe2b7fb8e8e0da5b7ac1cfc985df97580b18211a4e3edff95afdda061547d3ae0406d3286cd305bdfd2c3abf8f74af9a03420e5b03f825e9c53907e13a5812174be42898645149d
+SIG: 97650fae3f59ca76477f2547167749c5830248883225e354ff46c7e381965220d9bef2c2057c7d1990f08bca4cfde877fff2b4aa813d9c4b84fb79eced81ef05
+
+TST: 612
+SK: c04dc09f119d670fb1eae0136fcc06085f290f4ad1aa1ffc9c160ea5cf47f09d
+PK: ff498ce8c9db7867f6d0276452a466724887e6172f6681671b8ae035f5865ea3
+MSG: 1e42297f8aeef29a842e0e21f5dbae068e2c9ddaa6fd348e48881f0d42c50bf0ecf1706b94a5d19817ca02d83e9ab2f99d8bfaaa5c85ad39a150b225ad3eafa067815b74672fe026c3ccc677255440b684a76e128ca2ccc429f152577d25b69f40db582d49479afae680712dc0fd1fe1418839687ca60cdde974140462f96148295df1ce43a977351c77f2f0b09a6b26d6fe965fceae17d7b8620371402428544fdf91690b44e9afc2e9088c83ca48dc8576f628724798dc90323174c44996596502a35df8b982c570a6cb51b9a197d431af33f02b80011567fe50cf45ac111b3d556f8c8ce5ae8c9972f2a9936b1a012b9c339e30c97312b65ea59c100f79d795b8a24b31a0a97dc25cced6b8ff5ae145339a048ca12a579017fae8d5cbcb61d52e314dd7c2e72010c47217b1d06878bf2818ca188e8e307960c1689d7dfc0202973cd29f2f7ba743469e685e0e704b04baca4fab5488448a922eabf40be581c1994d74d13a366ce857fb40a6e05da8553694172cc3fd28062f538250aa8c11f68139e79cd1191ba3314b5cea0864437ed2e4b6fbd75b9ded0987b41c202a58ec0254d9d371a795f1dbecddac112be8d09e2d7b9ca5752f406cffb911ca36450bc05f1ec1ca3ca8d35124d1286c55f10f61334e46ece4183b92219a9dcd0e5e78ef2a76cfe9a9ab3795dfdcb44f63d45f5f48ffb4156133ad2e9950884c5bbd2c1cb8729e40a8787f784969fa880c07ffcc97d5c0d2d488085e9116d7107cd5db16ceccdead55025eea2edee93c1b106427618ee09dc3dad1e05676a2368069c8045c3ebc6c67afa52d59398248efcf15e904c7142304ff61971f4d9bf6460c1d6417
+SIG: 4bd19f3d9c5116ec6ae0024d0f246d2ce250d9e0634a232ba06fd3566aed55cbe59f12332cbad65d4349a9d22e7d6e46d2fbdc71d5c8f9da15dfbf17ba225107
+
+TST: 613
+SK: 6791bd74d3b4620ef5f1ff56406432c26ab646f6d5e9dda6842ed69052275392
+PK: da9915a7552f110faea12d47920a09601443d4000a9c7e218d5ba72b74989fa6
+MSG: 36a20e66bb29155161ad85eefe893b53ac5ade165f089a77190b0c239dec8a201685b076b4ded4a10aa459b980a8cca47d5f8de4d2a662e446d5f7fb70ed9be05db1cceadd130b3346d9409f9d6ef52824c764ac6fb1cd156dbd6a473ae722d0ebb25638c51265a22febbb14967d6dd8253c1d038895c6737f067c8f73c3c1cbe6cda4369632d7f4c9acebe87d0571c81a58cfd72cce4a5cf53a1e75259f4c993e67efc8d9c3576c43af04a5caf33d856f7f2755d3a975ab2b685c6f65680cba9ac879f3a8c9a4765b879c0ade1e4bd0d4a70bb6f92b24d429dc746cc78f84811f076f32c61e3585cc8aade9b0ca15224bfbfe18be10a33643600f6612bf013f0efcca837246a0ee5b03c02f1573624c4a44a90f9e423d4e56061a71d0144f5a887a8cd4a9d6f247904e26795951959da121c83c6c941e2b6b9ab76209ffe9178591ead68230b94ae97df58f9f172428c95067598ac582ffb950840d826630c4625f5deaddec1305203b4db6b945f991ed7cd3d6fabca51e2166adad0aad5117336d52d59422f0135c8fa8cdd0884be73586bf284e5ddddbcb95b411f98568526fbe71a5592b56ad5a7345f2874db1d57beab43e8cc69547520629f0ee76dbf432a376fad28bfc77e14d840f0c02d478f1e2337c23b89e73e5279108b5609b18e80db0de11cfa94ecf7239bcff59c54118e4ede4fbfc0823ae546016f774c52198a963b5545a3489b89df7626fd11ed4658d715a4657994035d403b3370d14eed9718d598db675f042592fea89056544b32e5b9c8062828aaa3cf59cb476ad36db1daa2482227a9b7afbc153ce93253d1b39da95eb96f83128ff2554a547e34eea4a0000
+SIG: b1e8d481065bd5121bb3bf569600bcc26df40c499fbaa954b39a619dc40b9590c31756b8b63f860151694b95765d697b2e1ade0806e92a06c4a559e90fcfa506
+
+TST: 614
+SK: 234ce4d39b5ebabe9a2c1e71970d718138dcb530cfd296023427d892bf88f8a4
+PK: cb73930db421f6d24536837bd0bff6fa75bbd141c98a405d4244a3c424550779
+MSG: 77730cf8c8f96b9187902acff9ff0b21746ccaf0a382a7b343d1c72027ae3c3168a73a6b8f49bc8798141e15c2732b6a6b3f757f8a8e86c7a4bacb39551c54874d6bf716897ee4af13253aa5bb79a192104f44dcb3de960745a8e6aa9880524a629fb510a4ce4cbda7e2957dff1d62e705606a2cc84f91850beaac5e5846e1420bc91dcdd2427b69cfa46ae38a4fef4146eae35f9c22e967cb14a1af9cabf83b180465bed6ef2cda382a84d9994aad655d8952e0fbb0f96fc8089f2e7489497facdcd656a8a451b928c11e7a4075072aafbf17d8f1054c9196288ded3ae21f9afd5810a100d8e4d84c4a35a98b30d3e18524438dd4402dfd8e7675f09d080cd915f14af4372f7ce58384972d5d111079651b2acf39d2a167c6a00b2b17ce0b268791bd2be5178fe0f82d64dacdde377a1e8be9e7d8dfc82b08644537bdc870c5819286fd51f6792dc5f67b54be336d44d54febf81b8df8dec5d8686db12f164d0e8ff1aa2c16bacc9806010ec8e91196597ef06a4cf1707def5067a04889d8e48a9bc2c0bef664f5acd1b4f5bc2da7da43dcb5f963245ba552fd493001d870a9517a179c2f0de85be0c682d057488e35c7816ff4ba529aefd7c66091f206f5f4d75cac8bd209ec2fa55be74af231e2f389dcc2d668bf695ed267c3594bad9efc00217c7a0e9e7b6a56a33079a30e73c3733f2d24efecdde87f72f948d277d6b6d5b035b4c53180d23d66cc0ff17c15dd468585e389d91a4c97fd80110b218a0bf7a5e0353f4609d2cf018a065571001c7888555eedbd3622c3b1769cd13f33374772aa6c8a8f588102017d4ee4e50dcbbdb1d610c32670934a6d9e6d9b784bbfe71862bb38
+SIG: f6d060ed7d18273f18f7a69cd1d8126e478e88a1d7294ff6040846d46107c3e41a423babb2417139fe587d2910271a357fe5bf57c92ee3a7b77533729d0ac20d
+
+TST: 615
+SK: 103d118c7dd65d07e8d5582e45042a75792417c692001ee6bd9a927b2b3d9016
+PK: b45cc94514a6ad672496cd4eb9fdafc1d4a167072c6874dc8ff16d761fb66986
+MSG: 5a8ee079186b51cf4629834de0c6bd7334855039a7631d6887652a7728995972e362c1c409f084f5aaf2986ae3f536be0070c4baf459ef60a015ef9d70dfa3ea96711cbb18e92af50c527d7ed457877a07ab83721518c89f7a864191b1e97433b7c6cd634a832e19891e76c62122a49dbffd83498aa416acccb7737fe75f4fb2c35328e6f6ececaaa42e43dba5bc9689673dab96f0befa3c83eb41d4d887b3a117d055e30bb87fbe7c719472f6c7a4cc45f628f5faddc48ca344f77b733c0e3b9f5079dbd07af3a3847af141719cca2f6a766552b45d0fdcdb9868f2c762b6d4933ba10836f95bff71cb88040024c90534c4d7a95a2303b04c2961012af58bc784a96327bbfed039d0802a05262d8e663b78508e92508bc1f2ea2b9be7580bde10a4d663d0d25b0e973b8c5ded59debf19bb044aff1c60c70ea1aefe85f6d15c2c1b84753b59576a49473d65af3ed941a3d514b5c4522c141bdbeed9cb339695b2e02dc07000867f1bf8ed8cfd3b1afe688fbca80e2f9ba5c0b188a19adaff6686ca0ff0edd444661291fa27ca1fc529429a5d8ff79ed2027c60ffe3b2c03fb8a66a3985417ba4ace7d14fd0e2371edf5d71bc02b9052767c7f72c4e6f3f30e0638276b9c420aa4333095d31313033090582e3ac4d9fd3203120ba2514973ab9d1c7fc42290116b51dae9fd579410ae078ed320a5a1b49aa7b5fefcd756395213af8641e29b0ebb5b83e3780e5d10e9d3d11998148f6c6f86c4d4eb252e28c70fa3a55c43d4d7faafcbcdd45ad2637f215e81549eb8a4cde4715b7107207503a79595060b83ace8feb673b997968469dd9b4ad6a7ea81c6e61810033f3edfc137d974209575c
+SIG: 2fafc13c43afe5054372b923d24f292b283afca3aca3b3e432380684961713c8d23e86b3580495dfbae424b767e4795a0f922f71b50f5d7a369ab8c6e880420c
+
+TST: 616
+SK: 47eee2024dbe09953e981f6986520f666082aa9ef4892dfdfbdbd250d2a1df28
+PK: 9f13cd8ebf5080347975159f360296a7164014d8d069e831dab0332607997cde
+MSG: c133f033cf3bec6cd19212ea47dbecb13f2c6018f9e0878ac884bfb575c0f5d3fc5b4999580eb8acbcaac83ae9ac9b443e6d1cff449c3689b433d50900b2e8b71d00e119c8b875094bdab916adaab75bcc852959d8d759795bbd6b360ee484afe47b1ad28391f25afb8d4e3afe0c5b600498a12833fe2a1a5483df940b173ba0d9d8c4d1321fa4b733334b0f6d878a0e5a76f4f180ac119a82082acb1488e49bbca7a0369c191bd6d0c5d445656821a99ccbc945949eca8136cc6e127d9de92ef64f174a6c04c8b5e52495f0dd674bb5ca128a9209968fd450dce319913fd6a30c3382798163e6585f58ef208be4d0c6a2513a752388397a4ae444838c8466dbc36fbc36ae08bec88eeda131c14d06366b673151454100dea1118150fbe441b1e7826e545d9868242e899f5ea53e434c37936ce6fd06146283e8fbd536480de55a16102c44754bc554d5bc2de2f25e19e567a023df4640e74ff3a49e4dd30e0e2558b3dbc2aab92fdd5e79425ecbc4c699fe1f161965f1d0b45d8bdab52ec9bf7a69d8aa0bd171e755ce7b8d0718f7267afb733efca54b213e6f5adab4c9d76c867fcb69ae05c74bd21516cf342c6161f6fc9eccacf970ebce540cd892bc106c6bd563610298b70968f091bcc6e1f7ab4a5b2c6374a1903f4d3ad5e1bd8643a9c2f878c3d7a4dc49ef3197edbcda7bb91e7e06606087d4e981bfab93a6024977962e45262517f338b6857eec2158a297b2aa91524b677a21aac57be0b63a8074fe54e7a9dc70c5a5c3de728b9c17ec1212ab1130eb17622cd7b22ab6eba9185e8d67be6c47a2e5adc663d4642cc120222e299fe134fd7fcd00adabcfaa642fe2e08dd52e2c3f32
+SIG: 5defae0e173ecc18d5f01ec9291be160d5eabff63fd5423f2bc66e3f6408c196353502dcef21effa4b9c14bf27b687d1b6e86b2a205a89eb35c376a3a325690d
+
+TST: 617
+SK: b6c88b4c90fd19a149d381671953b9b16d428f6361cf503a110477e297f8d2f8
+PK: 8ebfb084f997b2ea7932a2353b2c8b16bd825e1af587a8ebc51a6c45aea343ae
+MSG: 7f4bf4f52173eff072f818d0aa97e6935d8baccf4839663253b2414fe6b1f34cf43ab120155a1a3aea7b4819ddd1031673b8a7a6bd0b9dda4adefe692a56162c646180794264c5122115eb90a6d3054f084302dce3d836ac3de820638bd89a86bf0a4c01547cfdc543d676fe1639ef72c5b845c494e07814cec8a47d03df73be4e33c05afe9a190dda043360496be4cf3a6319da9ab06481677f1a4374d60d3d3b6394f8843c869b0f41a1e81c2b1a54bf5aacbd98207c8dbacb36422a3aa013d5e849e044af928545c046097caf149d970215115dea0b5a85401ff672e02ed40bd0f5a440cd56494053c896c3bd32606349f7cbe7ece2a2230cf236dac59f7817965f3fa80fb48aa30b0b19efa9a96591646bd25e67c185f77e21d6630b288d4e55146b2abc15e95088d936080775618154bbdda115702a2afd6fd5f56b923e188833ec448944d30283e337254242c5812d7245a4e92670bce3546efaed22d274e1e6048b5a0f01efbf895dc42494baf1747185cb1a4b88fdf1e6099baabc6a5ab5a2727b1e248789d170caa2449671a8f6e094c11332ea0ac2afe88132c644ff883d0c499ad76a93df472fa013eaa27ab4dad679d2511b5049c4e98baa2e7b00a534891e290265edb076f7dca8e6fef3f433034a16575f0e53da4577e6b13f0cb0d785870d0d098d5d80f413a268ba84e0431a786923771378cd57b8192258e2633cdbe03cc316a0950970526fd3e09376bcef0d03b7074e59a5a84fc64e795a812156d960567650bb1e1424b3cc9a4d99d57ba858dd1a0cad3532e998146e79264045e28ebbfd75a426b0bb851a244ad6be7bd5765af493dfc44ee378cd04daf3917eef2a6206
+SIG: 7447a20181b02cf1b6ad529569ce437c2a0508116f50205c41e6378b74fe2fc53630aa0dc4b80c31cb26c8f09bf8fab27e3abc8f1f604a5ec06631a84f6f2e06
+
+TST: 618
+SK: 7949a9472f725ce7c68d7ea8fc16e13d9e0e0a58f58c24f9228c88e80264090d
+PK: a370f82833f88b4f5f5310b918e6af93bb724bfbdf3c02c503780b2c83ab6cc6
+MSG: 955386b92dd6bf92601bf81e84d25144b5fc0bcd7d23c76e7deb5f5ba6316bb61a5d8e74185b012967f0a4438b531696deb4b8101089e0c0482adf13c0613191b977f77b0419814147f5da64a1d3beb1275b9849d1297ba8532ae0a647a8ace395ae0ed00f67348c5ee5ea19b5f1c5bd2e622818e8adcba3c17c27987e4e3d6d910a56c7e5149d3f5574fc06009bf4dd3e37cfe3ebda2c2116d366dd88ce5ea72ab387490585443b086e8aa38d11d3820b72c658e463cdb59c5393011d4a8f4cb6a195229304e76239fa5e8c2cbe0f39dcad138a0ecb3c51579ec9a120a51607eefebfa59a44620ea5b1916087ea338533fc132ff2e4a43d052fd08b6b1b24fb672f73c9b9ba20b7c1c41ea24d912de9b555b6e5682b970608ff229ad3086f431f9be190ec39224ba2ed8acb4c8eac8582e23aaa79827c44e248c5ba092ddac0f2f79684aa93fc061073e1821a56afb9bfec952df2719a9c7a403e6a93f7a656d74b61c1d19083f8d3f19e659fa2b718e0bd04b693d63dafb86adbee5d87c75b7d129122f178a0e669eb035ca4d8eb45397f1851264e2cf0a0cdd30720c5e139cd6a573f1fa241cae9425805ac79603e8de350efdb0b9bc95ba7b085c1ed92c12acf53f5d4a1137598008f2a3672c84e5f769a25c7a4a16579d86288774972606e4e7d85263ad217e0dbcf343fe554c109c5d9409b7939073ac55a03420fec289b114a5c54c20b45ea69938533ade7b3ae85e1a783dd97897c3ae8254183cc54045c2a18ecbe521691f2619d9b8f1fb347ca055a7b0b4c24f64d1773e01416441efe159923217a84874b9c4ec265cdaab643908068497812c1af15c188071e78f597fedfce91c5d4c6
+SIG: e02898cc7c30ee01648247497be8a9c6378593dc8820bf7c17ffcd18118af09879a769f539dd9237e96821166634998f946da65e6dbad8271511669e2d6cad02
+
+TST: 619
+SK: d68a5e3c47eedb3099dffc804cf19c5e74bf7bf5f01f54d4d91d7574f3d3dc7c
+PK: 46467fe9ce3acfd0d74346be21c46216db81aece6ce0308fb8dc6386fc3446cf
+MSG: 596c03d0873f572f45c3b16f0ef4b52ad2bf59ec76d3c0e534d62c1f84164ddaa425fb85c9548485b7064677e99d04c39b6eba04c966397ba6a5f4ebaa69a241df95a6e44502509d6350557ebfea60264b62ad7f74d16e5d25d45970cfebeb33e7b1bac3348dd03a8e99133b26bbfd7aa722c2587f72d5526e980da9eebdf108211dae50bbe8c65f9abee69a1bbf84c03e40448babad03d3cf3b7de4887d2b47737702796482d2265c566b0f623b53c8671bd3719edec0ffd5f49b49b072c1564a57f9bab6b92d1f068d756639a4331452e61aa7b218a88b9db77a19fb82f13e9868edb798d5beeca55d1ab095b316225f3f6390f89578f0160428747bcd21be6ae1d86991b48ef80d569250858febf3276bd5de3db65a245c8bdcf1488c4825968945786bed63f3d13f1409363b948560476858b396bce588e40b311ddfc22ad622ca7d1e69561464dda5009e638aa5ec9f4c039293aaec75001ffc68a7cb3ae01874dc7f39d75027f59a28965fc19530c0752fe99b153da7c0e542bda76ca1e10b7ea158efb4d821fbc65e7271ad9941095315447abcad0880a0075dd04b1325c72633acbcb261fcb407c264a34d70bf1f044feead069af5a87dd352f4bd8110fa178adbd8dbf23c6b575cdd5df22cc9a5cdd37d9c8faab81a4cb3fb5c4fe7ff629dbaa9fc06b80c1fb691c28655955cfe5ca44149b150b3cf140d9acacb14313a72c84098de72bacc0272d79ed6617f72dec88e19b84425492a429ec6d2ec08b86346dfbf20ea2a3619e77b6ac64230ebe25fa0067abb5f33ee49adc7c44bda7046d7f224f2e7a4895683fca8684ed6a031844f5786bcda48b5042394487b52402a09907788a1e140
+SIG: 896fc3caba7fd3fc285d5eddddc0120cd46da7c6efabe66b150b002760b8414a89ac9e7f1f7b7c7b33598f61f45718e4ff4ac368ff129614b4fe9219f237b009
+
+TST: 620
+SK: 31e82bc1cc5ced21cdc8bfc2dbbb976b08780afc6944af7e88e50e67874d84f1
+PK: 8df977e2b040acebd3dafd67b87f9216e8c371beced618fef3a496d651a5d7b5
+MSG: 69d461b6b7a866e94cd59a5a23bba4a1276602f042baa850d5b29249d6743ada04d3d938219abbc22ada66a1778197f70bf80b597a8b4ae00bdb876812d3ab4ec011df73341c85053eebcc2df0acfc21548283b553ecde0154828ed5af47571985f89767b005b622c9e7c079dde694e49dc0550c7918cc515c274dbd9c5469d2f18ecd90de664e03ca41e53be20b96e25af40c54ab0f7cbe9e05ca3fa5a37c1aa8ebfb6444a32c496efc68157c69f358c15f6ac09d46efef9a685df7e8dd63b304bd3c638ccf532fe901f11cf97c5b1cbed33c70637c721b0289adf6bb6d87c30479fa926e043074302b76f1157d0a81dec493e87a3c643e7a20b7a41525a38db04e78dae5e7797066bfae2cf448a447e9004cce8e41f0987991fad30311ddaa459a2644f4b941c068c0d6c0771afcf42bf9139a684da298486ecf67523bf8509a45ba5cb8b3864ad22c0c6a828c6db72e371de410b47dac49ae9d3b5702b1739b8d760ce98611c07d88df5f04683808a21afc2e61713fc2c025cb25fcc4ee941841083b22f61e2656fb3b8dad41c262c89d2f17610309f2d5c29589a2df61e55149895032ca981e4557e130a237fc0826fc872529861bbb8328d673f39b58b73d060ec596bf22e7ee081f44e92c02a5677679520e2a2b4d22c77f2b212d5aaf050bf2c141e3e28b8571d4321937426235c7a646d647e3efe183c27b7492565ecacd7f43c67a74453f4780e88711ba2dd4a3941b12ddd3909270fb3debd422436ab6166f08c99c886cc0e8e3cecd0642e44285b8864aa416943c5a186974f464535a870a012861bc2e587149cae971624e61c31d8a507e3ad82773e723bcb75df54bef847a407bcb7b1d57
+SIG: 240702ac6c68d597d222da949d0c47d16b390a477d1fb579e9d8948adf9b3b6a7fd4458ae6385b7e2b684a05b55c63fa6cd087bb90113cbab8e4af142fcf810e
+
+TST: 621
+SK: cc56bc7cdfa611924e72b07f68abc6ca5b85ff8bbacdff406e51ba720d09a866
+PK: 5ffee221ab4d0fe6f4c9346c5e5a4b8a636a6a0badce9667be739f4c9e6733c1
+MSG: 088304f22e1a286062defbebb1827a64b76a14e87015e7f646178777aba79704688d7bf32e1efac97a9fc339810ebd3df93e4ea024686953ed91fa6d2ab6e07ec7811a6d91ca91b098db4725df65846a95b808635a8d0c5fe5ace25f0780e896177bc1bba1cdb4449251c01b482f023862f88e072e79cde5dbd6c1d9ad9c07c606f5df85a6eca2966cbfe0a1673968112f26a317053f167f611af297efa802e0a94b3e1f33a27b73e5597abb224115ebe75e294a1bcdcd979255b0a80265c089aaa7d6bed2e3d0c918f56f4a55f448d863365c6c5846fb9b2b9bb55f6b7c6dff5847b71bfdd4bb5b9bb2e4249bc0243a02ab4d22ba78a43d182195aed78fece84cb1ddaeb9eff68156045b2932e638d7731d0e8b4c9c8c383b0d6d392d21fc640762c87d3692b1810bcc4a42392ff13d45169ecbf0135055093105098c869b68887e934e2b9da5232ac6c9373800f70b64ec64a4aa0ca044c0777ca3a3acaa138c14249672a55b24ddfe4dc357573241e14ad0ac16475a8e3867886d41eea35fe7932ba9aeaa0c86c9eb6db7808049ade7b5cc1a40822c66dea93ad22d44b9e42904b5b83684ae2931fe36c608ff7096f1b09f811b02672804406e08ed9e7745676ce047f0f7f64708e49bb78754720b8aa226f5556abf05b56584645292dad08e2473639a8ce5475e0ce9192f8ba2dd32ce14c91975ab602f7c13538c52952d0396158c7cc6b942be7d923eeb523a73b5b411966d14ac96e5b096a52932a416292eccddb91071c88560e70ecd4fe2fe24d523fafcb98e4021502f4190a0515edcb24019eaca09ec2615a9bfdeb60eb354c84a1f3cec7ffd7e65a5515d47959a4c4ec48d8021b1754ae2bf84
+SIG: 9b86a192b64f4f044ffbf87b41c7ee52f7a721aa320e7bad6425995990315cdd502be4e1116019d131a9218d19614ad95543b1889af0a97ed4d256dc33d76e08
+
+TST: 622
+SK: 7a57f2dda0ad0338ab9a13c9a3497e9c75238c1531589789227cd2749bc6e950
+PK: 6f738dc5e7d9e240c9f4d0c06a5e021747568b69a75d507a2e0be7ea613526c5
+MSG: 8c8575a11d2ff2c238e419ccb00633d04e8b8bd7742901d588dd6a2f00aa12f08ae41dcaa9338f8c47e95312192cf6b245a00ce688a029da56dd1b1deb0d34b5414fe1c21d6b63d06b8534ace8e866c933fd7c5a65eda95a1737a9ecdb17859149ac696951b82c230e8275e96dd02fd455ea675379e67ba63484b6283831fe3ffe52d6ec49b709106705c9d19b859de9fd200887cb44d8fdfe6961fa4ca2340944c764c704491208257e735482af8cb69041dde685241d3fbf46fda057248b8987be1f80b54eb54009f324dc450e886e79f912585b91c9dfafe9012262c471403b1e8b5c31fc5375a1ddf99b68edf9ed70af8594f7d84b2cc4911fe90500c6eebfbac085553550e35bd2e52514e979e7241e9f8e34cdf8513abe72510dff3cfec7e2bc6488641cfd0a65ae0e09ebe99b15b29d45ea67a57aad554d4f8bfce1386ace228839e3a8a534140eec3d37d51be361f5ea1883739f56615f75b055a06a91471be98bc9453783c358382bd0555ae9eb0bdcd66629a611fc1a11c653c82214587dec12ba120e2513070fe69e982f7a80ad159f6a325d977d01d050d116a62a4f8acab6c3d69ff6c878213c60a94845cae106de6c5d6fe2508d94565b7ba75d58d1ad47d76a20defa7568cb7fd66f57cf3774a21d3ffa7d8aa6d86dc284b70e0f17e7630bfc10cd1fc9a8d9c592d39f24a7b5c8e8aff353577e6ac9008690c7a159a7e83be5a6ae8fca9644bddfa37a92b07055f9fac9fa97fb3e8f5f4d917dda5c6dc6ea34b64d302405bc38062e07ce93a1a88aed5fbaf995a09b45b28ad4a6b273dec1413c5404529d825b5edc2e27a390eb7e8c2b43905e116d887ab5fb993dfe150ebdcf817ae62e03
+SIG: 989123761d93563278fd0a78aed64e2de6f4a700fc9a70d2187748ac06d9c2c377d1995f89c7727fe2f120784e4171c42d6353ac3d4e3f620c639c75786c460a
+
+TST: 623
+SK: 32ef6d789a1ea393f1bf9f11de34f57d653c4e77d51e6050fef4e8d7bf183db5
+PK: c1aa181e620f60525c2b17da8d290bae5d339e17eabceab58cd76ae066f41179
+MSG: 11a9c3c1ba7cfb61ad103305c25886de9f8815c6c21f17a8733a024f9497da0540db3603a671aae837dbbba19e19f82ddfc8af855980a70125fc61cd7ffd10777e366e5e9569927af0f245d4f39b3fd0f45879c253401412855e5761905ed6ef318b6a06ea6e9f906f9bd016bcb694a0df65a016bdfe845a09f23e5086c5aaf375efeb86da51239ddc350bac0cdb03b874db1507e6ad4e2c9f46028ca2388363541493b6cb92c1dfcaa3efd68c6b4e91efb46751d23f4c48a973f0a5c7c6fe2a1269d2a69e9fc4ab8ba3b92f796449ba3dc70245ed505cc0eeee1636647a68c7679d0b6d651bba35c29b81478d17ca3685707ad616e6e5604381f84ee52b25ad02fc0dfb85432efb1fecd090c02ad002c1857fced88fdfb2ff26dd0f5018fb47d813581f6508ca637c7365177c513d1ee05879a65c5b676b3aa873a1935c5437eadcb66dfb052a5e7c3e81d44b3daf698f42244ee2ee4b6ed2b7e6e56e61ff9cb45e719fd746198bf2a7de6d25af3bc6c7b0ed8abe3cb389afd84ffa2a230d93bc0c29d5a9419cbff11b7883329921480b5844655d996c7cab29dfb2a3927b82ba7c306c4577b6f8b5dbe2afaf9bf14a8f9554cd01a69a991bf212828de1e63172e833de06698cdb3b28716380314572bf5bcfd34ef52a6fadda87babe6bacdb20ce63c725cb0ff61fe30c1b51dbda2c2625f99dfeb029a3e58cba7d01905111caf42f27025e720e18eeb07dae9155c55aa300e22eb5e94dc7a0a84ee67d91a960ae08ca632dbb1737fc9a43dbcfb3a879eb9fbffd7299338e264bc1237ab6a5bc2a263cfa99e8544439d96331639fe9408e54a350610ff01de3f85799adeb73d82be938074dea858ea636b63abd
+SIG: 88f3a6e0bbaa3e060bc9d91fe2968c61126b20317f59842e4ae48711cdbaf62c6c0207405d1c4849950271f0aaa7593091109e478d13f356964f7dbab729af00
+
+TST: 624
+SK: 0a5525a4598f60992f86ba1ab9eee6e2675622f943284fc0553e4446ac5a4c53
+PK: db60d7ea29f8d60dad33d02ec5f42232057bd1c4bd6180a242cb7ab6f4426781
+MSG: f787321b42c08d4052449a488593d885b4e0c34a5d64149fa8b9c85ee54bcbecb50909b2a86b88258a10e07e8f8c2d068a89fb165a6ace7e64998ba57d89d9bf2b8b38a1f6d8364aee05ce3348bed48b88c2473bf5f2665f51ca073a5305358eaad4365d58b83bc9814e25f54c37cd9b68a808a57d6c2d7d7b6deb5fe20f4f96fe725f8de65c29a4f1ccefd7c2c6f2fc0116d58676acbc58691c79c2b006785a0975a31d8d3c949161596a068aaf2226ab842550e9c0b2610a29531d1f3f7f00826bb6c7dbe04e28ae1b9ff6f888a49d82812f452e1b32740b234ddd9642e18f32ad9a9af7f8952528674a2cda25b4f7ba867007ffa7f78f163db8f36914956bfaecd50f6d1af4ee133275a8eaab94bbc0ae52b6d9b2832634232ec0e8b5f8022d3ef1ead9b79ef9a16564277194f2380d9021e1f17b184b8d3a7a34d15139a39c7728c22e1a3a67a27a6ca4b8a8a0636c6054d0f741f046673619fc6b070e62ff4862f59d269007f3431339637a89f564c0db3d9bcfcd19fc25138ac66d474d80f4ad79f6d1e7844408e88034eeaff4a790338d546bfcd7424c119e211f363cb89c888749346a89d32f023bb6b0366a1ede4325032aa35f52e9df938a5027ebee9688ae480dde1a9c9b42d1a9c08f719223dfae1cfcd49dd1053aaa381c24cc9c7abfcf8f6d86d6af72eef05304412f3db2585aa9e0f3a4f1b6d710d02ab11db1fc90ad4de25d04299f3129c212e9cb73c0047953455bf98ec8fd2674e47b949957deeda018badc9f2f68a1b18ef5c583b095e08dd906da5f220da029b9c400e3ca91c7cbd87f3430c742337f61cf54745b0622bcb90762c6bafef87e1ec888c364fad646c33acc22af5438b84cd5
+SIG: 8fa6b0aeac71132ad882975868f1bdb8c11f1a6c1b9c54594e0e46286ea6c9a5d6d5b0eaeaca9ae3af74e72326b3b6f2eaa893c0ec42a49c56ef514f75c77f01
+
+TST: 625
+SK: 2d5ddffa2e58c90451ea05de47b8c49234e26ced54854e3acef11d8ee6852da7
+PK: 7bfd1c8a4a0bbb4606d2e5bc090f56b20d58f2204b6aed831d3df4d406b47605
+MSG: 4f1c5b4e6fac3baa3e9010f3bf293c779e61fd7bbe05a586f5aaf08026371627a209acd188afb2dbe0311547940559711640f78aea9a62818962f445a8e7ed6fe6c5f49162e7435d1b625b88ba39dab0ad56fd2c0ad6512661362bf78afe5a1416b647f3b88a056c9e7289c9b0cc3afb43402198563493e737b1da052506b6c9306d75ad6693db6d1571f96f6f52990c4df19665a6bb63073fdd9f55596896a2e9c2622f2b0c2cc99ddd1b649fb0318058d74794e38ec657ebc82abd5bedf8b3f4bba3bb6c9935fdf6826502b769046b36d96dc695d7c85404284d2a2ab7fcf3b02f68a1493dd383ca6339fac1cde47f53c5e026d0869faffe40abdb98195230f17d0cfaa533315afdbfe7d1afc3a615b4f75090233a503f8861e32374e1ea9557674231d9d737d477b33ff82ac0b2c0ba93c11fb523e613618ed370524a60f4d4c83694c033606d1d069d544dccd3900c37a3b3363efbcf6697f9f762b33b1294583953fc53773ef56726eeb470ebe92149b73648a16161d494120a318bfb080cc38e4996f4b263ffe78c7877fe13c2fc55219f44260e8f253bdd379d870e6c91048b1d8d4e88b88218b2b049fef53b2ae1f8c921ed2bcb434669e3975dcc3fe4520ca8024842f7ff2ba1e22cfeb5d4c9e435eada601ff183b26364eee1faa59d19e6aa4f0975238496a709e46bf68336b068bd80b346f11faa3817a07d1cbd84382b2102986f295a1398077ba291d6b5f5bd860ec6177273468f0ee0f2591b575c4366e189b224e9ffa35bc78a4aa8c06954fe33d080ffc0b23e209fd0e79421f1bde818a86890cf172236db211657d1003119fe91d4e27c524ccc11fade0a25f57a7a1d677e1da0b9c043d02fca38
+SIG: ced9d61010339c471ddf9fefcaa82d1eab3a2e0e60278553b4dd9f395be58149c91594e5618b0b10bf3aab94f159b530f64463eed66fa2ace54fd92572a06a0e
+
+TST: 626
+SK: 4df5e11dec80ecd882837554fa3135b9d5029df42027aa3b3c929246329fee96
+PK: efd928898fa144c2d1c8334fa2e6b5b6a325a7102a2c344a145541ee9a6c046d
+MSG: fbd6f371b4c8b152c9ce0c6396a77c0fe480bc02007f336ac58fd4addda9d69855ac9e93a45d3e350f41ff502aa1d8fe159ce89b064802a0a1890f6a40a7ef57c6e5e5ed040280df07e7f48fe819be63176710757cb6e440b4f78b5759dce028bf585b3c3feca1cf5981dadadfd27ea124af45ef638542a8617ff49f9470ac2285943c7c3b1163b903955ab99b6eab17f4d49ffa87207abbfc111c4b91f5413dfc9bea31843d115ddeb1da40b45f58f47c417b5e77d5818934e730eba9c4557bbf48cb7fd4e664558af4fb44ee3d94c16e883631f38476f4837db94d54122fa134ca51a525aad5e24b76018fee9a2e8f60e2bb48d24ab8b146f84ffa9820120e7c50d45c0cfbe35c8c31419b078e90712cfe934c3be3a94ff2158873aefe34dc6e36902b1675e1a47cb608dfe960fb4da8d2a8490cc38ebadc73a1003c4941fda8fae944a1de8e3b10ef6d9e67ceec745977d333ac9e71214121ede8892295e27799f206675a9d54ac12159d3a1f954fd0eeffbd30a31904fb2eee77a8aa9dc4ccbbe2851096146a4ce0e81fb9c62498dbd83bf83b55029a5e900086b9531ce3247a98f8654efd8fe7a836431f75daf0868f0108326e23026d2db4a72124ec4e39d4bbf3d846c9f51ca3cc31eb1d02c2ba321e4619f2b659c0bf0fe5c19b213f3c79124f3643f74dd0ff9ce5d27727be6c6958159c164404f43301fe1742e279de9efd441e73e4ea7a842587a79d115d36eca9c03c90ff0d147474109fc20a91d7b3cc22ebcbb8c7f71bd61e8cae47c5050cec1d4849a1d4a8e7a6f845548437706c25331c9e57c2cc6da117f2e5a0f4b368c4cb206265c4178e0655ff675ffc1d4c58eceb9edb4da3ad2c5f62cd13ab48
+SIG: 62545e6c07801fde95b461e2e753c4b6c84c25124eb330a2725989d5e340dcef0c7456d4c7c6a178a221b6328348253db787a9e5510ab9cc278515ae3e58fb01
+
+TST: 627
+SK: 85d32330e2e073a46030ca0ee2df2f8eb874a9fddf5624c8031775111f11eea2
+PK: 6ea7de2ed5ea5cdf50bfffee77f7bd2fcc21d48666bb1f4890c76a69cc7ba4e8
+MSG: ae6107f38ff94ed0327903cbaf6c3e3a3498c47abb2989a8b37b3a19df88c6de790accb4b7258177b9151d1fe04063577d3c3acdb4c929968afdad6f252a67ed4ca89d060f1a4653983f7ab58ddb93e2878fbab0637dbbeb95d25c5986839de2748d9f34027aeebf1d9eb936cb6770e08d45b8095bac9cbb71db14e8a34222b1f2237b9f0bc9766a231a6d102799f7c081d500fbeade603cdcdd7d5b965fbace4be5c2cd932dcf5f6ed31722f41d5a363b34babf3f636fb303824aa701dfe1d3e41263078c1ebbdcb1f73f1245b83e3fa70ab8e3f1413e6b06bdae022b714d60a401d57480dc64e7aac6d3de85fc94d853ca13b7e67415579d5c672123a5af194bee14ae35dc2724ff209f1166638661f881b1194aa4e31b42a527964781591504ba76103f97b7f5520315473ec94bb017a16667b22a8576a7cc2ac0b7756303c756f0ddaae9d0189e6c8de349f91957c72a529e9f7e9b9456524840ba02344f55ad3c11a0b259901439f2655ab9f8c6c8e8e960c057d9c7dafe425c75d4a33b801d4547cd0551a6802a8005dd72424764dcf57e4aa22290ea4f5baac51d7939c05342882ee14380ef2d4704b41949b2282a1e1a3fa7ddea9fe83b9fc51d4eefa2ebac722e4c0a7c599b6925f01b8a2066dc0c26f92196f4f503e887c1e6efb093f1531387bd88c691997b9b89e3cdf7da12d3734183a4b6126be9e0774704b529659b5548f1b87512cc1878ca4ef55990b483c9af6aa97635f4f07949727065abf21e21e32990b1a7d07d74e02d9b07ec639931bf9e2ca3941f2ba6b5ef14dcc2a247d2117e9cb41efa3fcca24716641452beed2f92657c2fb731f0b94e8c892a81bba91f639df43796acd3013ac044f608
+SIG: 414363fead6e59a3438ce5a3a277d62bdd00fa2efac6463dd13fcdded93a7f108ae1f528ffc8ff4eca331dab91ae5b1416e2ddb73b6daf853b03c81e9936560a
+
+TST: 628
+SK: 66590d369984c6f5ad3a89c78ddfca10a0a7657995dc0188b6b57ac3164731a4
+PK: 98873ab13346ee48677c4f8612db31ebd13db58b2b034fd155afa8720f4e93e8
+MSG: 2ec1c6b0829737832c9c798a92eb490b23d334c3bbe627cb582d17a9e42960efcdc7d34750e0b4aa864c204fb8d62b47992e91dbfcfd69f51d937dc06c48c0ad43e8598371cd0e3bbce416bfd44b0944b993aa2993fdea487134cde42277723e0683ec98e69595e9b7b14c8cf9617a1e30ddb8060eacba48d88253b165336108de0cb02ff20f5424b567830869c9b4329c9945f0bf2f3c7acd1e774358930cd890fd9cb864d950935ad8a4a3beccae8f833f6356191371c32633dcf882709b0d98bd807b383aed8d7bb097b6e262ef700c9d768f4b5690e3a1a8f21755d658db2d1bfd2f7071e0caec7c2c5381c5ef5c2c2281c6bcedc867390b90f3b27b0f0f64a33658578a5c0d66e211e6fff6e86488acf82bc0f5e2664b83699046037c0d33d340ff98ed6263354c24273136ff0e4f0f233a6c8254fc0c90764330e3b1057b1e666d5ecd5a2efeaa6a105bfc858431b88ed7fe551eb32ac0af27c66a9803a3bcf87634c66c7066dd0197a3cbd2d6f4e65cfdb8f3daf9f3ca5c4f4e0add45f5541aa18d041f706e4fa87c34e9a223d88572eb50083ee8c7c475df568bc73bd08c0f0deaa374afb1c178d0dddb236e15a8bc2385ed3f52b8761e637887407a20aec3e99ec830dae3167ef0cdb3f3ffd200d83b75b749690b9e25e2171d072ca56f71baecd21f7d45a12c91b2c0fb3fea3b158e54648284bb0095b36244b0b121f9f1384ce9004365e7772fa30828250f51985f1b17b2d2f80a33e8fc6d8565ea15cdaacd42a87bd7c9408b1fe1c770665bdded754bc2ff2ef91b973a86b99f1059c6f227246a698b38541509dd5449fce60d386224183b7dce1b3884f7bae1c2e4eb594510b5ca585279d9041df8817b0619
+SIG: f0db63a1bc7624161ca0063853b2dee45fccd22471e012366f868a4a9c74654e13f1a315ad83916ebfb8dc31a420f83cf645c4c9d16bb4d5d99d23c7b43e2300
+
+TST: 629
+SK: 41cf071f4842ecd494191b8cf28cc0923185ef1b07458a79a59a296d3549822e
+PK: 6dc8e446db1da353b58d0c45d8b4d816ba59e25bb680712d62d6d3dbf78d0698
+MSG: daeb5f0e84f1590bca2b9d9719ef5d1cfa79e0583446332f18e9e4feb0b1f15340297ac9ad6724c85bb16558ea54eb5d702a47248badc6252a804371b74cfe1062d1dba1ec68fd1d4dd029cb55034bbf61068251eff3983636f6debd5727be91993b3e4d0abc96ec196421a47b7893f83986d6c0323f0d19aaf2cde9d3565c104c9d3176ecb5ed5e173fee52b5a0c42b6ab2fcb1ccba9649c2c67c520e9b96cea693df3e58609ad6a0bd522efaaf03858d245dd0a38f84a2fb1020f4dd97c3aeef0e24477d30d256701e900bef26a8a6269ab660d74293a2bf1d20c2cfaebb7c2820f5f5b07453bb69ee769b52391539f0c606d22eb3923ee6f5a1d46050af90f011f851ace76327d3d18c48170a9a25b04b770fd938ef8a30b7bd03391dd36c516b62f0cb78670740e00e69595c418d967253820b754c4fd666e3cce16ee0c94183bbea706fe298e1c99ddb821217ed9008cc8e8b83bc8b819915b07b146fe745024ac3c46116cb4cce5e32ec5d7524a2388d9fe297eb02811af4546fcd5860e14c0d13f03dd75a4249615900078a3c358c5342962bc1beacf68c246821a459ab5321ec9f574f49d10389f40f14ddfc8513ffe3deaa7336035a675fa5858b490c5d247780064adbaf75a76335eec9ab918771b0b1df5147642aef4a166ab172ed601fed210f6c0cffd91869f7490b57e7c65241863e7e8c0a26eba63b5342d0fd8214ac731e1c438d0177115f6a19e0935c7af6bc7dbeb75511d9bd8e63e3e2f47ab0dd1cedd7b180d74a4b44d461197aefdd3620465166a39b45395043ce8874cdd72c602bd3d2eecbad3466b5cb1aa41ae92a8afef2d764cec0c449d27efac437938f280bea9c50a582e57c27f9b3de872f0c
+SIG: 41052bc417b24dc48383966af0143f9c0ba85bbefbdaf791b16a4dad1f570eb80703c0a2cdeb2f7ad6dcd3fa7bdb5c225e869cd8fb278dff0667d38accf3db08
+
+TST: 630
+SK: a2c8e161a8d9d6e888c3d09b0b972737307a2cbd2acd7ccd804d2431ac6c58d2
+PK: 3a325775886732deca406857a8056010aaea2875545ba6f3df30754571386992
+MSG: 83a3bebcac5f28c5433e3c4f1e7bf5d2e4dcd2f5e59dbee0a83b07025715350746f85675f1dfea374aa7d794287b892ef9097ff6d2e122f0a656fba0798cdcfcb3645dfcfd788c740c0fd04520e7a06a02a05829630a2bf0cdfe2ecca009ec44049946bb1d2326ddd61d7ec640bf69eb44fb23cc1ff478c570c75db7e766e35b7c43db73680d1407a94399fb621baf3845745c1c4ed0b9f0b485be2d53c568545ddf18775a837a05d9c9157b084e8cd01fc324f07f116877e4075dba2432c8a7752e9e939586ad93f0c0aa5edac94b8d82e5449997b15b8c8961589c442821aa83b60239ec5f158c3f5e9ec5bea5115d5fed61918e8fcd5bce61c777f20b6bfe803a69c6fc794ab8c57df271da863872a61335b1fa29f4608ff037f712069809ca642a0307c79aa92e10cb893a29d17201a0b6d1b46a7212b3baec9703c0b0392ba6b76e5c9c10f83599b81ea22283f9547aacdaa7f30896d1ff731e11fb9e56ad06030417119805bab63521496c3bb92a12f5e55afcf60ed4217737f3046b16ca506657a6d696d75a6d8e18e9efe2b08c8b1fa0728238e27cfb322166eee4ee76968b777b50ee6a2b804e1e9b46016620132b6588718d978ca2c0026979c400d3c5336751210f0b00d269ec8f4e2f9559e180332dd270e50cc9465c5558936355521bc3c9560fc19ec14242121e6bb2fff8f50337fc264acf1ac1704328334b3b52cba96d9303b1b5db859dae31d80f1711fba251e10b4d122128f9faff6872d0c0b81eef59541f832b0a9df3a4cdd591c87736b1aecf242c275a10c3fd67839dad4ef399b9494ecd77f7ba5b5d4f2ca304e5b22921307cb18fa64aa3d01c4411c8369ccede465ee369ee637d43d28826bf60ddde
+SIG: 560d01b94df11d83347752ff51b3545ef55c5632ae7c8efb11aadd8312def72562e8f5d75ece10ad46bc96c860deece39e634a5f50654d4cdba84a8e6f70240a
+
+TST: 631
+SK: d3d188b390baccd95024526146b82b9184e197e46a9340a0e6ec18bf75be7fc5
+PK: d8f794948aa6986100214e9b7b9024420806b4c67846d5bd506113b353a2ea3d
+MSG: 5e65658e420375433fd7c1f6be678841e58104f10b4c676359d84fce7992f5c57557d738f830b505fa0c2b9eabf8d1a9f81fe8f315d662e2b84ce95299ebf4e503b5e1f7f8cdb668ae733f3d0cdd4c742ab5f272bea4f18d183e8923847662f9a39cd4b14ec76d11032fe573c26201aef66601cec683e34b89afd964e987801c706a85e27bab33701cd109bcf07b27ca67f022c494a04cbe5a9c6d63aad936cdf1a180fd05865198b96f06a78da95799d3aa4df3b170033c69e8fb04288c3546553b579c0ae3938062d3d8421cfa66268529bec0271e53b4ee7d099e7148a802df80fe5eedee1c903ae8ed4d640ead761262dd4014f25f9397ba3f1c08d83a3c485cfb55f89919aa972d6b7e7711be9e30c1eb96a0c3845309fb23dbc75b6991dd6e48cdde90e04f228e8ccf3ba23f2747cfb9d3381a9305f816f26cdde41c0220fad228ff6a8b095c77b6bae8fa3368142724bf1f5e0f6fbca5320c215b6ba86b91e3a8acf750e93fa7eaa65c4f785ef8421a19c1e27bc24b428e08a90242abac9bd4aa03c656f8f46dc40b36152c1bd0def1acfc0da10a2fa1dc3da7ace5a8fd76227bb1a602390fe57afd32efe281f2ea6b2e4d2545cb88d2308d72691c9a52b4ca25231a0107f25d117cc935397621c683bdc8f22e810340f2cbac4ceaa3468665261879f0074200743e0de5f3e58308b98b04b8c7148a4e004e667e832b0084b5f2bdc6fdc959f2fc28a8d31d9a9e78e5d5f9c0b119e5ff1f68f7c0daf0c0f16947cca5b7ced09601e2ebed282ef2bf8fe9a27ed27fc5bcda8aed6c71bee3e7751004472689bbf6d9d07952a242ff870d7c3f5e1ffc2c1f40fc9ab7579b392b554f3dc588c03ab957431fe5d02cbc711ad489fe
+SIG: 16976b267de96e38dddc8478075f6bdd7159e56334b2d2d1920946294f33cd6b7f9c50f8057f496cab5d94bb4dca262f9f0fdf9b1b64741f4b722d32efa82203
+
+TST: 632
+SK: 61917a975cb7ec564c708a565388c57236a66b697dcd5a7f10bae671572ac7f0
+PK: ecc0f0b99276e528f82b42f2efce8579f83e638c6acefd072828c04e434f55af
+MSG: 6e970e0b1c92a7f496a82d8ae80cfd0ccef1d2c799d41728f35ddcd603b421c2a5ab3b489e78f4b62297de437c5ad1a9683ff87fa28eb3cc38ce242af59419f9fd43fcaa54fc398992f8c8e31f2b33dcccd0ee11ba7b388e8d2a36ead067c6beced5890ab7d4a94f55dab92128a0f814c0e68971df57bd5078a7403175c7c2fdd4a52447153ab37456729aee33e5fc93db8e7f480309875ecf6db07ce7f3cac5de49e361275ca50b6b719f4b715b3e30863cbb3b7164ba9eb96ef3304b19ad4d74dce4bd25e77bbbbeff1ee7d1fb55b9c4f7fc4cd9bd55108afcf99c1a41cd6f6b1adb297b106c8ba24e3134f87dd8efe5cf85492291b94d6600958c28b9122fe6e01bd3e329e42d1926b89f7a8c40a49867e5aa3ad749bd98dae7d006b453609e7dae26364d9172be7283330121ed2b4027e0885118743a6ea0cb7dc27409a9b2820bcc242ea10a00937bf849201e0fb6199421f163e9794f2dd4b332014a09d3ee8071da787747f990f5179919027ddff7cab0f55e9afa8eccb16cc2dd3cbbead7ff7ec818c253393f748741f55407f7408ee33a42ae2d6ecb3fb600a71f30ab630606e553b43678e59854f3a2947bcf4ea0fcfedc314d8370d1266395fda3c9105e975952f60e3086bb82481513d6fe8adb4f95efb9a95b66d480d2bb171078cf40684ac69a789c7fb7fa425333d705db00066755df728de02df25bae34f1d7d49caffc51e9ba2b10b98fe4cd9d22b7764ed931edb5f0b554496e995391e0af0b8d1c7a8295a8d15a7c6556d29cb19e0855ca505ad01d2aa30928a84bc48959576d812d9b27b8e88879faa2806c0841360ecd0fe83f5b848fc12f658f1e7f40e561c2e78d3b0125210a92061c2db21ba660e8608ff5
+SIG: 6abb3e377b5c80b74f77219c1a9e096fba0eb68990817acff12dba7f61c77ccf595fb6608552003cead06ca1317c9cd51ac4724b29f40921fb92843376876401
+
+TST: 633
+SK: 7ba25f2797a2836f379d6bbcbe9abf4f2def5e52f72bd9e0b006571022fac2f3
+PK: 6c2ed4e8c0124d5d0540796d3945d1de71aa6969e6abea0f1b0e6fc429c7046f
+MSG: 171a3409878097b3b22b2c00660b46e542c2164c00bbee54554837940e70f03da9916a40f9bde8288f45e47bef7ffe4e557cd4474045e740fd959d984f4ec81da88d44a373c1eda0cfc6b08e351373d3b82ab0902df8063fd908e703e0cbec410ab5cdfeaae00188ce2ad42b8bf04f7daa5f0ee333a6f9311b4ad9810952d5d5a64b20f37e845415fc3cdd616febec50db296fb3f3bb7f6b366bbe52e4897a05617bf7c981a62edcbbbe5da4c39cafa869aa2b2734e6cfed90ed8be75949390ee44566892455b890cf568b945aabb758d3854be6539f3b86bf01d188e48cf2626a0d7d381703be6ed1290dfb947bc2e0f83dbc58703080d7f5b9ef19aef930908f68f0c80010a9401b303a9f6da805bb8a0ed0f39413eefedf919ffd8ea6391bf95d4229604e49457b8e23bec611484cc7f9832dd95bdc3ad177c050f4ab633dcdb3e691f5902873b38cb0720b9113357fe0cfb98a68cccb5d5f0809d59a375cf7b5a275d43c4c34ff68e448526e8e1aad44e20008a232afbcf532a42b50a025a1b2ee4e077eb0125a593d51a200ec20d872c05838ad36aaaeeccc3ed9ef41f6d122670217d5c08f6e13c172194589acc3c59f7ef790c7c85aa6d5eb69d4c89a72f5e7c9246985c1ac0c5d197f76a73e3774839d4aa2096aca190a30f4aac54057b64f358e0e06400c0df2f876412d34484c4344f4d7c866517d3efba4a90fa7144c9ba5db3361db5769403ec81626a511f93e30f8586eadfcafd9a36ecff8d24b42079ada8e579ac30851177bce9038b0e1300072d68efdd723f6355064843275815a66b9d73a1299aa59a1812f6452fb4115ea2b1f9ff4a99690596e3f2022d81ed874dd67e6189ca0e68b9304e993a95b66665e0d074c
+SIG: f1f590a907ba980eb0d648ab4ded5f92faf7cb851d81d858a78fa6b77cbbe12f64d20df52771a7d5e539a152d731e1903d4211fdcfef9a48b46c8fd5394ca009
+
+TST: 634
+SK: d1e1b22de5e04c9be4651dd73995a3666cb5352c65ac7b7051b366fe1ac0c310
+PK: 12fe56f1012d5c12f135ed5982f382ae5f1143bc90e8cb8c93051754551ee90a
+MSG: c7f218b5aa7aae1799625a56c4d7d7b02637e572f1411a6122f113791aa3c628e819602fb4f0335a6123013fa64e9fdc4e4ae497bd169c2fa77bc236129717f462886b410893fa7809cbfdc892223b40ee041ebd4ec7ddab55be6081a1646643a9120baa46289acba15b3b48af3b7adecd69f43eede79d9b1957e1d8c3129e0fa0579d3d395370461b0e1255c9caa94e4725601cb9d0e2d60244d15b64e1f7bc9015590ad0991f12f8267311206e9eb5d16add0ba5218fce5fffe1c9ce5ffe1f731132f4b12cacb02f97451710846b7f824f4fa9e08919266469789c00ce0d94d38fa8fec3f51f2f886e9db09b804470b19ec9e80663f155b4984d2bbd0b2ce99302e06c64444b696e3129fcef34c3dd00f7ab5beda747a3fc6339192b740f3569b67dbd6ffa39e271faa400d9616bff86ec49a659def2e7f5d451f2a2b35e662a6e7cc22f1e5cdcde8a59988135b7e76562743c1e6a099901b3ef97cbff23f209bd7088c2f03245279a1dc78dddc1bb0c1d35100357882126b328d3d94e0871b60be253fd1b6ecf03c1db731d9eed0edf2b2643230780a4d66e99179aad1b82402e55f6d785ebc80f8dd2fd2beb09f31035df62c17f428ed0b2d56508db31e6d2dd5fb69ebeeea3257070cf2fe67d42d28816a55dbae0b185db4421bbfdaefc79c08cdc1accf71642562ec70036da2bbafa4a891954c4ee4049b55c640e91930e39e3ef1018dc1647f26942c6dbdf4d56e41eb2c898c821fac17cc273e8e4aa5608a812cf4b82f96019c252d56e7805298ccbe8ce40b0bd0f933b884c0faf97a958b20408b8a5297cce5527b2ca212806e72a3264457a7fac8662b82ca233e1c7758dc6e4f1b9995863f25f747bcee43b639b1f8f2026d2d2
+SIG: abaab4fa6aeb0a0b34ee0d613a0af049edb4cedbfe9d3bebe9c00618b115b9d1fa524ec3495e1330b0936181eabb14299faccc40eaa8cca57ed324b7a6420c0e
+
+TST: 635
+SK: df294e477b1b91c5ac5b98c330d222d7cd2d53e7d0bc0ca403df4ec75327a274
+PK: 5f0bd22f2f1896d1563b4f6940c7df89efc258c0ff6c2fcd674daf4f59fcdb60
+MSG: 3e42d668409630cbb84812ac7ff1154f70fca8bdff3f1a040fa3af868aa1c4e91508b1aefdf5c3a8b4b077a4d162d2c05bd364fbbe8c5a08314c2e07dffbd6e8dd2e08a0dcc96ea92ddd4c97f79db9425a6c6b34c46043d09a68b7687236a918d21a561610a13ac5e446e0881bb26cc8e28aad1654f867ad82ae33f8f7a78a65be57699475516a1a8746843e93a1a294354624fac04d452ccfbe4fdd92a951aaa07d26676d5cb077a5000d439c124276c0dbcf86e7aa153cc24b5aff677c6badc261c289f4a4ae519b2e2fff312fbf0f5b4c4698f6aedd8fcb1d2348942de3fb73ba27f6db14c2f09180356e5fcae1adf65e22425f8c27f19e989483506e5df57a1b613a22e345038b3ea91c0f78ffff46383f38c72225358a34570d6f664a17454a151613f01cba777f62ec831875ec5e27d257f180b6366cb183107c40f50b01b2b9bf91b3b5549ed931a3537aa41689f72b257a6aa39cdc6fcedf143983be5bffe3ae2b29f82f882122d66a7925f5a710826c0dadb7e4fa4ec079ba2e76dada433f3077cb1ef74613fc5dbf8258b6da7c73c866372457ed500f97f9907e1fc26353c70ba3bd9c36151d46865d2c65986562485cf8421febbe777c73e6cd0026d66d35128b9f8f33264aeb56bd3e4b8d1f5266411ef3b23b76b36d4c9df3c512fd560c2be52ac523c19377ad2adc0e8c309cf5bbf72d9eb85d65a94847d497d8d102424fb84381666ecb1c35a3725d7d9e9284fdebb6b362aa6a9c6fb37aba87357f574c0e63b4497d498ffbb7d0692d784b4b18ce9f9150c146d3d18c382eda04938c69d0778f2902d5235a5652b97cef6d5f60da6bd7ed4ff97cd94d4939caca3b6baa3cfdac04cda95596f467cbc6cbcd9264167743eac1
+SIG: 9945ab73b58562b355dabc4e2b6be7e05f37f89571440ccc32c1a94737095b7866747d21007000a0f0e351114b88e0138b55df44fe72ebe9591410e707fa9d02
+
+TST: 636
+SK: 70c6859f08cf42b4bda9eb62979dffb7cb08eb3dabe93fe94b01384617cf6730
+PK: 401c9e2033e2259fb6383b3e8b9e17b3f2062746bbe648cf484516db0f2f1b06
+MSG: dd0609ea159921395d11fb2da8ea4f747d7f74b58052e01cad40a271fa0bbeed91020f4f0c0846c4f07778a6aa768eb51712294e9e1f32a602b152514f5e6d39f9e08f7a7812bd900c10a91469e47e8a78e54cd4bd7cfededec171ef373f1c4f9bbc2c81402fb14ed0bfac8d043f117d6124521afae0916a510d568acfa3aa3301bc979ac28d551dbbea6ceac4c212aa8c8492b3613ae7395dd4125fc4c25d5b4d99230821d4b17ec2ee6be7d604195a2154333b973526580ca7ef9e30c6c1dd42ef2afe42b11b1aa49b9ccabaca17091eeb380ec5e34ad1e3827cc60dacf144286c7892590bd2671a8dc5f3a702c1de7cd3b42c1b150b09c3e58ef6943b45d89d41df361f1d5c25565591b6ac8deaa73676531f6e5abe5804b0097f8d45ea2939177333cacef12e4b71fe4936bafe00747a8930bcea55b8fd84a01f6df84e7acb931fc7c01ddfd63deec3ad3e69dfa2b73550583d5747eee96c5536368797e247f23f537d79079ab6da314102c7443d41960e3a3d8c359c4a4ec626fcc44e110ea744d417aa850db8ecdbfe340a962db0d8c57dc517be8b40d14de97b1e9e0426447fde0a04e50679c53ba1aa3cdc38c7ede6db6c054b1e9ce7deadaf93ebdd470791535f3ecfabf3416355f7a18a38afe6bfe507ef08c4373a4a69dee1fcb65b1631a0de1488649d0bb2679a9a45f67820b2a4a1e5a548072da7032d172555e788cc9860ebb3c0c359493751b0c2c950a7fcf4803c147f9340fc93d85f1efa57b39081b92d93473fd23516c4950ed4b29a2ed3a042ae3d92a1e52cb709636fc7272fd747208bee2b16d191e4c6deb27672aa34e43914cff2055ca4ee8ba3e1dc58a679c7f7dee2c1d53e28750970f57d85eab1c26b89bb73e0b1
+SIG: 0f03a4f15c339b4f7b88b4e21ad9e3d6bbf3effb7b678ffa500d47383b71a7454f62907b56f59f9b9af6d5b2a0fc1c737a64105195089899f57a2c9dba509e0a
+
+TST: 637
+SK: c5962961815b57cd162403ce08e4105ddb8aae2d3f533fb49cc236b5ff504d6e
+PK: dbade72236ba12d4977ba46c364bb69a887ff402de91d47afa9b93c95be71e7e
+MSG: 4ae4148d79ca9425592aa240bd153424a3bf4ae27395872ce5728ac7613596a77d5ce8565d8d6e1b5935b3906cafe1ff888ebc9815e04a624dfc4c6907b85f6f1a0dbddff62e9151220d474462cb9f13d89d3a93a00ba2b60f7e7ca63da17a6379d673551e790b5911727c906dc94f86d8277546c1564a45573a7743bb8a138cde87b3b2f28e5e245940a51e7c458cf8c5f0a70275962553e0d2390d171db44c2f7a5c9e9f93b90f7a5f54f191b0d875bad7e0beb980c2a3365cd7b9208724f4654418117e16ef7134e3e2794b6f9e80ecabeca3254e704c21b7ad30c5dee017ea2533fcd94251e55ae75a8cc6db6674b39c88ca42006043d6bd9b00ecf64ceafeeb402b1f22fd891f2d11c515c1aba6a2d4c0bd2181a48e43fd1c0af91f9b7b7d37f3dcd9e4c0a759748467d348a8b116df6a4eacf178aecccd3066e92dca45da7a3e319f3771eb3490022193c5b652f045687e1705f2e5691c134be4006353d7ecd0e918d5de0f3b87809fca4acfab94e1148ff7cf07f7cfd0c745dd2be01a24a5e069280698bc3f5400a6dcd08e44595c0388e44833768fc49104ee115bdcb02bfbda179d164ce969936629f2335601b56fe8f785cca3805f0403872c62f73c3ce80563d070e976d8ecc51124e2cace7ee18699047cb0f8fb8d9c59b8a60d12c08a09fce58fd92cd36db6a8e89d118cf88a92dc8a2600bd95f5a8e85db5cdbb249ca812ca209c7618051c4564a3a0e192b7e45992456c87d17412c11adead526ab8db21452f7471d17f2ebc90015450edf4f0a44fb2f4905f74d70275ccd89b93a650473c02a7da0cbc67915ceb7a1ea59fa8884472dc917ee9d246339c5926843ecf53fafdc56a695601a276c23a843e4d30f89c97c9eee6dfc7
+SIG: 8101baef004eb6f5ad4de0979ff36d3439b8212bdc928942e431915b3fd18bc2ad67b26f18941dcb16d2c29191421e779fed622fd9f582644eaadb3fe5c09803
+
+TST: 638
+SK: dee6866c7874c127029e96e025bffd35fcfdf4dc36966c15ee6293368013d379
+PK: 08c94da351bb2bee72e6e196be748807583762c5296e05b1e529c47c6bbacec6
+MSG: f1aa1977f5311b538b940ae442a3abc89aaccdcd0a79380a24258d4a9f1ce638fc2f5ba2e53f8e1fa6176f178d9024a77894c28cad42d629c793d68a02be9411b527acadae7e5c3851babb45b5fece329e29034cd42571083727f35aecad7c9be5954ec64e8f6ecab7cc0590e54156a4e1a45303849f7897e72cf2fbcd84f56c72f941dbb0b09a32e6386fbe18a43bb9bd8b793e4b9edd532103eab54d627117d28139b64e60fb0b81d09001bb2404d925e265babdc69f96b135e9e6ab7febb1ed3075d6aa2abd2bbf9b65fa9b3b7191ef37b633605910ee88f66eada79f00f536d380b82f2f4b5985112de004a56603f4436d8ff300f42bf5acdc7a4bf1ea9d4196c480495bacb0067630fcc000b4f279dd3f30f353276092d152c3f43efdc041deaa0bc5aaaba7f8bbd85e69c13742d678dbb65360aaf7b548a044c0ec60a57af650bc31973f832f961265bc2318f80775afd51f55194c42423f7bf4e0052f98cb206913ffea4886ecd27a4179b13773f947502e181bf1a1f2c62c6f08c20359f06df2b18127043b1070d0194ef5e5bfd37d227984cfb10989f21c71ad0fe3b81227d3a71789455eda383c22f4d2fcc72579f465e066f3d38befc024efef6c2e329649ce434d627367a900d07fe6234235c84656eac5dd0d788cf4cb31871824d66ae4bc89edeba1b36701298453e8da1e69cfb868095c3be6ed2182da1cff4905afd20731ac1ed984164737903c7d8bb0ad16aecf2fae337404fe35664515d93b701e2f878664454c0decd1c6558adace3cdb227507a51606f0a54df8dfaa420205dd57c65242ff24a405ef85c92d602886932b35fabe9c3bcebfc6235639e873fc2dd084c52cd6a7413b831d1cc99931373aabd847620eb69bb0fa
+SIG: b78ebd6d65b175d4bbd3d9a2082a0efe6e991cb2e403521eece00f418f2e956b66907880658b9e8e47699653d159132380d9ce1109af9c2757daf4cdf18c9c0a
+
+TST: 639
+SK: 523623555995baaf2a27adcb1ebafaa802d23ef7abfa9775f2c9bfa07d64e0ac
+PK: d34deae6523e619dd1bfc8f3c4ca4b78b368c0f720035e144c3f2fc105d4ce21
+MSG: 0553e69ef211652d62bf281bfbdd37be22769d819746361c7d65ddd0fad677cc0438b301d1514578e0da58e55f729fa8e66ddeb7f973a818d24ed8fe027b8491179d07773fb5d2bb96aa85d6b3750454e50de91f9b88aee8aa68e6bb53edc66677b41e601a46ab4bb1e656e7fa5f0179933680a6ec9504275e7adf7a3248e63a0fc9c1ea5ae96cd0c65a89a77cec2b1fd8f4537e82c1c488a69a0ef64f58734d9e73478e1d1f123114ef66085e0ba319cb810b66af96d1308b1a2bd92ba2c265aa309ecd5557d402c3802cae8d7e95007fe610c2aa75fc66196c3fadfe997d6d5998e18d260e9da31da9218cbad103cbfc2c7547765d67e81f24ac83022ef51c6cc50864366a35f6b9b9af94e84caa9fd3d767c831f0967a61462fbcfcc803f12e3739039acd5dbe9366f05a33dbeaf360e2ddcbe5c443f80ef2ad62e03c1d5b70cdeab4a7dd41553064c8d152709deff82076b9071192376f51d4c2c71a84e89f2d9401320c2e459b3e243cca7c26fd098c264ac88ef638921d980b0ae9e512d372037d81adc48126d7c9e4b5afa57ec265d401b9653e928afb7dff9b48e295e470d6b52e88b39d0a40cb8eba249f8b13d81113db1d3e01ef75c722f269488e963cc8182704f8ca018e73dc0714e9a9fc79bc4363c28cb3984374f73b2aa8786e74e0159507a29883fe0ed1c600f525885f2f10ea006c39e59b925b765b1ede534257a1f40f2846584f069746b52f5600430a2863d7936095fbc22a6ada674d41b374e2b8b9a19fa712b5944533bb6d6ec43b89d4971b70205a6acd72a899da12618204db0c3e8267b845791693e0ae6a35f14da1f8f4dd174bce0318fb5a00f672ede42304cf04a62760577590f27e2dfa6e5e2795d66053b30af7f1bf
+SIG: b1871729fec83aea0aaa472b700acd094813fb7d57b909e0eaaf21ee931847addedd2be8533d0c305cb9cfe5080e76c2808b6e51c9826290ddb7b94b6f7d580b
+
+TST: 640
+SK: 575f8fb6c7465e92c250caeec1786224bc3eed729e463953a394c9849cba908f
+PK: 71bfa98f5bea790ff183d924e6655cea08d0aafb617f46d23a17a657f0a9b8b2
+MSG: 2cc372e25e53a138793064610e7ef25d9d7422e18e249675a72e79167f43baf452cbacb50182faf80798cc38597a44b307a536360b0bc1030f8397b94cbf147353dd2d671cb8cab219a2d7b9eb828e9635d2eab6eb08182cb03557783fd282aaf7b471747c84acf72debe4514524f8447bafccccec0a840feca9755ff9adb60301c2f25d4e3ba621df5ad72100c45d7a4b91559c725ab56bb29830e35f5a6faf87db23001f11ffba9c0c15440302065827a7d7aaaeab7b446abce333c0d30c3eae9c9da63eb1c0391d4269b12c45b660290611ac29c91dbd80dc6ed302a4d191f2923922f032ab1ac10ca7323b5241c5751c3c004ac39eb1267aa10017ed2dac6c934a250dda8cb06d5be9f563b827bf3c8d95fd7d2a7e7cc3acbee92538bd7ddfba3ab2dc9f791fac76cdf9cd6a6923534cf3e067108f6aa03e320d954085c218038a70cc768b972e49952b9fe171ee1be2a52cd469b8d36b84ee902cd9410db2777192e90070d2e7c56cb6a45f0a839c78c219203b6f1b33cb4504c6a7996427741e6874cf45c5fa5a38765a1ebf1796ce16e63ee509612c40f088cbceffa3affbc13b75a1b9c02c61a180a7e83b17884fe0ec0f2fe57c47e73a22f753eaf50fca655ebb19896b827a3474911c67853c58b4a78fd085a23239b9737ef8a7baff11ddce5f2cae0543f8b45d144ae6918b9a75293ec78ea618cd2cd08c971301cdfa0a9275c1bf441d4c1f878a2e733ce0a33b6ecdacbbf0bdb5c3643fa45a013979cd01396962897421129a88757c0d88b5ac7e44fdbd938ba4bc37de4929d53751fbb43d4e09a80e735244acada8e6749f77787f33763c7472df52934591591fb226c503c8be61a920a7d37eb1686b62216957844c43c484e58745775553
+SIG: 903b484cb24bc503cdced844614073256c6d5aa45f1f9f62c7f22e5649212bc1d6ef9eaa617b6b835a6de2beff2faac83d37a4a5fc5cc3b556f56edde2651f02
+
+TST: 641
+SK: 03749ca20458a35a37a8d7a26f959f0d59f6dc9973fa363c1ff8ca4e638c2cd3
+PK: eaeb94f406bde6a7cf8bde2adf3081f8375b87d9335d496c71d042cd2eaa166c
+MSG: eef5ceebd0445e9c9181aff9c6f2660128fcfb63691a42cfa443d6a649efc5fad8c20803763ee97d1dba08e63e08a2616da05077489f2fa2c56b7534f9402619251fdf9c320de7af109e2fd8b2565ce8a7524c9405ec0f8fcaa7149a6d210efde83b111cf82dc0835cf94f20cdb021b73bd262666555e6d62707b46ee42fa900b4f4f705de33d3dbdc68a88d1a4d0ae933566db6c6237ec8abe1024dac4b7f46d407be16594d9046c7312dda6614d9bcdb01fb8324fc62b8eeaf0abc23cd570e304fca08e88c735e5d31592409ceb583862e6b0a767729f7556fa2c053644d36c8337c0274e749202982fb4a171acac196c02b7f16a8da49071c8ab8076dd5d3abadfe3af82ca85da02dcc1c4a6f2e1930bee2009eee0d971e40dd12175c8d00694f0325a3b3133c0d0bd382a5194fb21422ce67c78a5a6e1537e3b97d5e204e5d195696390f77d19024c1bf6b5125a0cdbf7b9880036181c98e1ac2e5165bd496cf997451a1c12102e66946b1676abd4cbdd2c11673f4f2cd5f3c9a434d747fa05b40fbc72268b4eb2842e4741f51b7709b6accc47fcaf70d9c1c4c35867119d81cb3ff1f16081133f1659aed85f63bc901989e2617fcce153c2978d708fd02449ae4d538d122ddb8527c0a76a102eeff6edb65dba298d3c217f6551814eddeece1aef5f371a54f12bffd6b4961819a0f244ff0d7d8694c14422de9822c13179e4eeb81595079b9dd2ad1e7c39bd303cc44ae3f3634881577a266fd6bb7917812b999dc809dc09c3d7019dacd28e43013a2f9e4f94bb0bf7124ef091783f796397f6463bf1efb39cd46f3790a1d9b6a7c30f149b5e66c2937e39cb9744ddc66ab561bad4e6fa8534d69883822643d63d8bd7b181621a267e955e758d1792b44
+SIG: 78a3877e02bdfd015e7f86a327a48cc3a5230bbdb1243f1a8cf227f78ab5e7680de301a915dc11b336fb5f6566848b42500adb5d673969122ba8f0053cd3060b
+
+TST: 642
+SK: 53cbd6f68cee27b9f7bc059b803b447949bbc9c5d5a38652d7789ca15420dea1
+PK: 6116990b5331e2165f82743f01d8e7bd5d7088b30159833fa7b939cfb1cc04d7
+MSG: 306f8e1df0a4ca78bd77e8e1191c94deaa82648355c2aecb7e82fc56d64c504619247e7cf8943328d11f3db4b1dc148e8ef6f6c3bc355969662a281a65576391242b7bd5a62f8fa7acb604e3a344ae1a9d732a254315f31a0464c1e6587462d29212c40e5ecf061e269aa0b90390ba41040721684bf2aa9582d83066221db60d0f7ae2f149a36e16952704fb1f3a982eac6b4583665c63e5a8996f24a566dd506a33d4ec8a02b2bd34b714c745000c0128a3c89d942506d12f4beb900e2903cdb34b35ca9b6d3ad9b350ac99f41db3acfe7fe55a28c0f006b844c9dc4853fd98535ada79416dca5fee5803a2d9f5d68e6b80539ff302e973f24e9bc88b7c4194117ddb9f932b32d5ec74868a13631ece68814b931421dc890249570341f4b423e86e8ee081b22702f649a6c7a0b7bdf5fb756202bd10b0bb2215c7d6597effd852f0b89abec15ea82257689df81e338254f93e81cbf061729d483eb5cf649805d78ed892dd0bd248ca1e252bea51847e1e82d39af58050dc4afbf9115a3a60493e8c0ba2e86e0898cd0d430891b9eb0a40f87431e25f41538a030f884fab36ad11165d267e8dd94dcb05b93a5ae77969430e1810134e157251b982df343dffae6123a99aa0562d5df72408f1a6e29c4059a5a8aaa4e621528fc63a9cbe1f4c0fef25fe3f8e18157774097a9d91020a9006b6c860ec1ee10d521d203a1f8bb82561296faad4b2203da53b207a459b29c18bc0649332b1807c13ca61acfaf90779febbc7f3242164797e6f572cb15a9be5887343455e26b910c8befee42aeb047f9abe6b3750dbd7de99202a0bb576ce1489e61c1f5d27c6792e63218edbfdb9b3dc515b4254d82c859e52ce6bd7ad296dd0e3709d4c466362f90265e99da7d0b701
+SIG: d82504405ff16ba6443dc482367263a8e200360acaaa83fc4e4b72bd249f16103ec7e5a7e9ca17198f888eaca16b740cc3f5c3b7b617a34b9491c3ed76aab30d
+
+TST: 643
+SK: 8b6574f6d7396981e223a4837bc339c3fd659419845a2121bf85be2e695d860d
+PK: e3811aca70634f5a9ce4b592a17bb5cfda53442422e203cda9504c9d65b263e8
+MSG: a48aacc0495fa0f1259b27865d3d75dc52c2c828ea8c4c2ad78577072fef7270f6a4d582bb7b962f4c3fd149a60a06bc8efd2970ef03148ddf6198b9b695a69fadb5340951cb75398ac51a4fd55430378cd5da8885210bfd2146f95c627632fe8be06de01a7c27b89deefd67efc69c9b5c62b38108f776229143dae660c10cbea3cd4f7ee53dc3692ed01177e4a6f7e424b5666f7f495f2a65602c7d08c5d572234a567cb6c38afd79cab5c4036d62637aefab5588769a448ab4c65e24554bd4158050e09eb58f99ab40777b0356709b7c025ae5ae5422acf87444931ae4d9a8b3d94476881128ba1eb7328fafc75f6b9dacc96d3b6487ddef7c59262dcada426aacb13922935411566235e058372622d885bd0cc04958dcfb17e08fcd7f147e20156c8e26af85530f5511a68db43dafc4e6a23f667df3743eedd71a3f07f76f94d1688afc8463bfa5a439ae311469948e7447064f0b0506f36719c13466a1b98776d967ec58208ba674037303dfc6190da783ff27303b86b5fc3211f01c915e83a6ad0121447911cbe1cf696f618f60236643f2e94e155db657182944c1a43bdc7bd5eaf3481fe1284092cb3789a892bd79a111fd410143cf91ae332860b1d29aa041d177b50d6cc2b9660d328c0f230a3515e6a0d688709c0cd347ad2ff32d61d1e1e9ba76f81e873a6c420f1707f3841db5196cb53f506f0006352c7c44c080f3096801a57a49cfe84205bdd7a9801f843cf26b9558a2db788ef1b237915d587b9ba9779890f61fdc91e03e4f4cdbefe417cc22d522a86adddb53f3747450ab62b576565db32e0cd44276547d9a16653c279659dd4d17ec04827c533e33390fe94f793509256db67531736ab3fcee2a301ac3f0a24d3b108d7e75c32a5aba36d6
+SIG: 2fd0905475a2cec3e76f9909b8afd83beb8daefa77afcda34cb4f11728ef15fc9c1d7f6f6afffc28f3874f913e17980f0e8e3d5ad23951df2b32efaf6219ce0d
+
+TST: 644
+SK: 29b2881b8caadb336e7880c510b80085f4b1221860b301eb4525650752a6d289
+PK: 0c5c44ed29d21bcadee21cbde61a9cdb6d5936009ba2f5b2e777c924ddfb6751
+MSG: 1974a2e2b47949f467a931d1d9dd5ce116e9f5030ad09a8cc728d1aeb148bbf9acf59874da80e708d53c668f2f14d7522071e909808427b2ab5a05f8b94f21505cd26abc53458978c784d479ea6dab105c4f7984a0fb9790e50624f4734b551905aa5ffa60184cd201cf2b26c9795da6e7e08d6a0bc7722400fef94fc21038be89d34bcd14c427b85b6866737196152d4eeb66d05b245ae84bdc7787c14a8bec2eea5360f042433d70794467d47393b93757f331cf2b53c660d71c29582aeea79b12527a28b0c5e110df6f854eead9a2b00d42542ca8276bb8bf988baab8565996fee50cf31b2459c4c50ab475265e83e2285d43fe1f752a55b2dbc49fca04a810f0413bf6bd81b79ac64ee1f89b97bd7d26d62512273e24a6bab2d5f7d2226baaab7b111209bb03733d8a60dfa31a516f4a8c7699d8285c1065159a6c7331c1defb47a30ef5858c50b7d045124a09813d1cfda5c9cc3bb5bfae73c984197f8f857f186c41ab87fb7962b631f4d007cfbee221fc6572784a551194c19777b08e6b596757e7cba7a0e27fe453f90dc59cc08c6472431c020e8dd0917590e79c1f207383afb39076ad24da8ee52486739453a2590e51bfc89b13c2033cfa5f8903cbe9961a8598ba556232869dfab4d56edf4f05e8b77d05871895e63b5351f76cb2d2c8385c109d7306192a25446e4d62dc7d624f0c6673986be0628b2c2d73eb941d35a3433090f59b28a5979d56dbc9fd6973f63647642cd903b0cf7a6acd330d87e2292710de99e0c179ca78929ccaecfaedbf2742414f176b6090c0d59a9db781c9967e28fa4e77d2a082e42f52169167e92d4fdd82e2cc05dd9184c7dfee490a237fdad4dfebc01868e0a4353a2954d090928461821a7a848d1b60817fc3bdefa1
+SIG: 99e996e85a494f1980cb07de9ca6165e7de104d39fe3c3226735c5daa569516fcaf1b6e4dfad0d389b6db0ec8a8f20dd2c602656b5e761c8f3a6558382151909
+
+TST: 645
+SK: 42afe89dac83e7d38996c0dbce0c9874c00927babd77ca8ceac34e564474282b
+PK: a4c5f5e3803f0a03d5c1c906caec9cc6d2851407f1ca29f72a45f233e6656244
+MSG: e710a163ad2885aeb7658eb374f118b76842ec36ef3b010c3c6b9559e8b160c2628ded0b8511eb4907180da4b621e9aa4a322288888a1c09130f69f890597a9293e74f9289bdaa5c91b6fd24aa044ab9fcb3402f7abc48d2ab7b3880a048daa448645ad2ecb55b3caee2d68a8bedb5d1865d5e211de39b0eaf22e5daf10f7168203aa15b85aa47bbd3cc4169cbc1fe80b4700b625871edabcd4fe74a3e965569ce245cfcde4209cc8abcd6797d44185b4f96c0181bbd27008783e9358a5394fe3a34a06871d379da35b20bb57eef9e5524ee7912a6f41b4a1f684c3919cfcdc00f4580baf9e09d316cefa0f465dca5d8eec514e95e5a57bbcd27e41f8119b264ae14a319d8c3859babf1f4a6b6b77e442c861d6ee28ad12b82362e90db0c3672b0e0d9ff58146fd159aa8fa99dc755fc85b90cf9419279c0624b93e75eda0ef7c09695ae93bd7282419377b76ca8bdc0521cfee6f6d729c3adff894687b177ef19529a6bdace70b685c6d7a5d74a08e2a9e724035975c80d18cb369470de7299cbd6b0a27c9232c7eabac86d5093a65ffe0b40d40befe80b68cd9dce1ea1e657e45e9c499d0b690f74455fb47096ed8c18d1517f90442901a6c410b7f6415f20ae48c58ade8d675b6c058df16ae7698fceae95aa771b4cd88a0b3f22c51f98c71c1eb46b264bf97a300ecb1fd26226ad8e87a058cf3e708e260f566b685314045133f4a5e8fbc34561b9a0f1ff9339f55231076b736b6e11524319a272bd4453a0af1493daa09167e84643d207a02fee98fb223b01a99aa5cef2b7001e470f6f94a5dc208edfc0cb8cf3114a919600f061172f0efe039036bf4dddbfd0d45f91443bf26f8e15ed7db8e55f086a4a4583f4bda0f556284dcf71292fe70fcaa8259b9faff3
+SIG: 4fba2d6cc1b7193d3562f8c8bfe6905c829db265a5427c5c265714785b83f69514c5e30e28b56684c82dae2637581bf3f4ef271420bc7e6010613a38fa101a0d
+
+TST: 646
+SK: 10f009aa887d91ced809afe192d78e4799d9037762f4a9d3a429fde0f39f7b7a
+PK: cf5116b921212e9b78829a0263463691c6fbccdc0c118be141c96f8c88053dd3
+MSG: 2edf14d6cd56896eeaa770211c4984bed80eca8d6534d5d510884f55f11f99ffa9f89b586ffe7b1ec7eaab6a9dc1a24a3ee3c7a6ab44ade9917883264ede2f1361be7d7a3817f29dec9581c319f18f95d5be26d9118be678340037a68abfc5efbb9a3f3f3878aae3721ffef5bb6a26c7b1a3a56d2bda6c6e860eb41fd8d8371174d91c74c5eb67c3855c630d641d2e571a9a51c6402cfe1842cef38980cb8d0a64bcc89be3189e6811f47e8f4d0063a5b1601f44fda20c1c4c2fc49cbe27a4137dc4638c2ad2d0a5474747229c568e3805431fa36eeba785f7b97844b5e319fa6a09cc5ae8403474bb91dd896c1ec2bac73d2e505efc62bd502b5ceb08d16e832ec5dc4f98b51b9d0738b9fb28f3abe8966bf22375a0b22c471a9e58e3fd700de15c5296373c1bc9d4640eb7816e1dc9c8ce8619a81183009ec974871e8f0a9772ede0a638b3574bf75d8f55987f3cfa6fec68970bfe00b23b59fb5bf4996ea5d7704fcf2effcc0fd7f3d8e6056008097f26caffd5415a282a276a9b2645e5cab12968872eb052f4d7c10cc7c21d5161818bb44cc856b0de769d559c55df64ad9adc16c0ac65838f660da81386b70b93525ec2f40f6f63f8ea5d4830b9646c46183bb4e6f27047bda2a546bd34bd4db5fb88fd8ab7c75f652e15d5aaa6b46a8acf6e448bf2dd64dee3c105647c7f83ad200d8097c444a158d85a54f0e5dbb12b43de943af1a81856ac969f52a0bd454381bd265041a2691d1a4a0d819fa79092c8803521fa53689ab852f1fbabe00c94b7f682d121cff54391322529c8d5ad7bbb98eafe300ab922f1c89240a1e633cf56a7b02f74a29214e569a057bd585e404d7cd5352041456e6cf90c15342e025670f4fccdf98783b6853214cac3fa808a66c27b653c
+SIG: c37bb7b73b1105be086ff3076972077262df4d7332f608c7b2b9d978d474cbbc271046080035f396ee36479b7a6711c68e2561c741c0ec5fc9eca1734e811f04
+
+TST: 647
+SK: 4578c65a7ca48f2774050a7b0ce7a4fd5ad4e696b2b8af2396164a1c7e1b7bd7
+PK: 15bf9dbd3b8173e6f03dcfd575d909845f038eaa09c5d908fef908a97458b3ef
+MSG: 506f32b96814243e4dd8870a8fd60ddef09bb8c563151070d9bcb2b160a3eabd71a044d71ec93fba95288ed6fe1a7b921651604307d65a45ec5d3f2631ace40e58d53c72e526886e16972f6e0db94d57b55634fd39d55e9bb7f212afab00f7746409267e8d565ff5c2257333c3d04152174fe12de6a57bea057dc219e2fba5f191ed8141c018969de19472d6aaf763f19ec554702bb3dcbe13ca9b23b2418c99e71838a88cf454728cf9208a16c84ea39829b4ba9b4c77e176112bfe1bf35f95c4028c7db80b36faa29d2b89e9e862f31000065f139b3da77d9d868530574b7e391ed97b34f878164f6b8d87b406c7dc7860a5175f920e5a62dc1fc82ed8452543b107360d35d2b4c4239eab466d32bfda34f51037a6fae76f6d8b83e8f7f489dd4c1b49c38f53576e62172c17dee3665fde8cbf015af9665b0f1da2fb77b134f04be271e402f31537c2fc05c2f9b6fc3ffe47de3369133867c69d10e7f537bae4567d468e0f2ed806fe335f939c75994f363ce3b70daa7d5bd2317c833851fd8cc97251ec419023d9d0174d84d5609a6918a1740eb1e309bd127366deb9c5ab12992e9902e015fe58d6adbf52d22a760acd63e1edd8f138e9fb0137188601e1978e7d04fb2ada2b2aee12f49f2836c6842d88cf48c866e3d33fcd269c275c89c25e3669ca90de7b67a7e7a382cb7efa47e9c2bf76571c79a25085ef020487152f06bfa133015a1b8f1c0f6a9f0eae1ba62bf104f1c16ac14e1e96c4ebdf061e0cc7101d38da7e9e0994daf0f322aa3cfef91b616c2d000689ab18ed45268dcd275094f656ba3cf515261024741f7444ab7fc4decce16756032a1be270ff0b0317542ba02662260a376fc912cbb029cac54515f5a551364f6a99ffad0b9cbcd0e693b7a521cb
+SIG: a1c242b45e94fd180f054c7101e55b396568f483db6f0dfc4168b69b59d385814c19eb3075237d1fbb1feebbfea50c56813c8c39c22752e02db7e57f3e3fbf0d
+
+TST: 648
+SK: c21e70c46ede66e68a8873bbc64ba51209303a0ac4fc49b1d83e8193ad46c037
+PK: 9fbf80a42505d2c952f89f4558c3e6d187a7bc1ef446b2e3732343c13b33d200
+MSG: f55aa570ce4fc95f73f51720d254e4695fcdc81aaa040130c7687f039b8ba59ed857ceb29c121025a857feacb4a01f38e01178310ae6e35c998ebf89dd79057b4afc6db340601c81703c87a8c40e5cebb0441df78a6de13a447cb016c65e741bb7df304d83056b72c682c731fac0a0c70b7811ca14a50154613099c2c437521c404b6361de3621f8ea56b08ebfdb07b4f2bb8ba2ecc164336da8efc942766ef0c74dfd3b49e087e9a27ae54a7a2b98281b9af93dc11aa2f09224ab5a730f0218f4a6e1ea4885a77fbd93a1c58277d9e01be73a25cda918fc27dddb453a5da6902ad02ba05775c67e07bea4df86913466744365c1326e0ab5e1254c17967447d591ba5ed1b63a42543b87fed41459a089bceaff219802a87a872a763e692333ce1cc7397825084b2b831e93d80d6737f32980f2f3ae82c62190fe3fa700c5b7329d6d50042bdf831f37548fcc80b11f57cf20f67a3bb651a7beffcc48b70d17eb60f7259cc53bf7ff6080eb2bd0923b0483aa3065a8955f01d23ba80951e0aefd2a9372191572bc52916aa22a2aec393767fafd086839e236fe0460ce6d639c7ce69fe7f9d3aad2130573443570443be6bab93a06a54b8ac29bf33ff9949bc92158e6924b6b68ecda5f6f3aaf42b3d22df6d5e67d5cb3ab71eb8ee0b0e66732e1daca6cd60d9aa74305fcd570076d228d446d5ee542b10488bf8aa988f451faebe74ab669d604d9ddb15106620ea02e8db38ce639b5747812bb9048ee8bf72b1a951a05dffac95417cb43b06dce61ee3da6f2832ee83b2e7288ddd62eeb5893f7f2f6c8090d99e336c9f9069e1815985841bdd505b5f83d895e879593dadee72ceb9765699bf80bd06a5c55331b2545527d0c7caece96584ce3ec7fe02260f20b8a1c0635763ff4
+SIG: 0ae343bb84e3a299078e2434ba220022f3160f968ac04482bf8cad13b423f2670f01fb5f7b32c597520f84607e0f79c075fa7078e6e69d3cec319265d466080b
+
+TST: 649
+SK: f2c10577f7df77f0c1157a8c331a7bd2ae6386670eb65f0fae122331690f828a
+PK: 0d4c340fc231aafb3b6f74b89bcef7eeaa0b04f293ec8544247bfc3f2d57c1e0
+MSG: 38ea1e028a493d1c60ec70749f14d436eb3a2b2de54f213d01a645b580430ecd8ece6b5569cc017a4943e5595c5ed6e48c9443f2fa5eb2227ffe56d211f269bc8f6fa9ee8cd56f6b8470539208afe29ab0a195044d957b31f93e184a9cbef1a14e14f808bbf589ac7770084f998e1b254da59ca6d3e62e7be1790716d2560f015f399cbbce48cfd0391ead1993446f6b2493977d93d7b09a07a79a59ce15dce7a1da9c646f45af2ccad55ba158e638c4a30c5d30e9ac6e3a3339c243426d86491b2d92dac1478e8d74ff0bf149bdb5e09e3fb6b8262eb0687981554ae2cb47196339079da0a1a57239c19bf781f62fdaf4e31560a84317ef030492cf1bb1305ba8518ebaf2b434d3641672c8f6ea2defa696dc7e4f39efc08d288d1c966a6c7148c012eec439f7e12dbab5b87cfa44c9ae1900f8386f24444e1092b23a274c138e95c661e9377e8ad2d1fcaf1939ec9a632a873f7eadbe687b4a033b92a477f2e02e9ed92ce4f95cf170b3901518a062143e56db054df4e4431544785a6dfa24eec0f0de7a699ccf286dadfad85903612250764f25cdea8127d0078d554825ea6e7371c438bc46f29fb8937f8d9a39cf8849052d43ecbff6c4a3762a5f400c1514e85e91384fef9b40f4314e223a9d68c526acc70227d62b8b637a342df113d318202c51edd3c1efd1ff20b1ff078b32068e794d928133037f1e3a34689e629e43fd2b8e88eab50d7e7ab0647014ab5e4ad582006567eff72b5af2dac536892ccc871f8a80b5cb79d90bcc6b77d4cd08f876184ef58c064ae430bb79a6b9e96b0ad87368aa838a8dccffac0cd8ce9ea0d0ec4c4b0f42673416659c984992cf53b1e445431007640d47ece26dee4a2943aa7097dd356cff4754f21ac07f6b3f73c469055512f37aba
+SIG: 60b703115a322ab892c276bfd18f70a9eb0c7323e2c0a6eb5fc7e330b0bc3b07a578a082846264f032c6191d040bd98e5d5a4d4f076fb9062acd36bea40c9102
+
+TST: 650
+SK: 041a97906b5956b9d340f2e0d7a1dcbfefe663e9bb4026f8cc1ae7e2a14de27e
+PK: f382d32e88c3a72c7caddafcf8aa699e21db7a6bf4edd6e49a005aad702e6a79
+MSG: 71a75957411544975a48cf103aa1f8e2ad15244459cdc0e336966eb8b26c97f2169e5d78537037efc077e86f06e05e9c1dc3418288c0a2be6ba34b3a04ab20bae7f3621094b87d78a7eacb864d4078cb4efcbac5add937a2c6012ee1a8b256cc276b65d5e92b4d00b9b11fad884991dec4c1cb9dce1863c8b0a210161ae6b3f8bf9cc4dce4adfdc8ed57d83e95ab9dd2d92658dfbd3afa99e3f8951e2ad74a148f6f597eb2c945c1f1b94461ae0745481fd0edf838c6286035e36f011238875dbba2289d3d6a3942a7f9554c644305244ddb77c117cb4b56237729dde428b8bb42df9ce29e144dfc96cf6c6767b1ee6d053ce4f8bb2056ab7810aa1368a8910f2f69e061c19d8847184fed534f98758d703a76885f91eb752a21954a10c6f6b4da10464ded36b00089f662915421bfdad496753689ccd03b624021080761e68176b10697dac878e4c3db2fd0b28c655335d98016f19f265bb0b2434cb4637844d91ed0ce05ed2591fd998965f83f3197d10eef448850e792032724701da305cb6d794669483fc3dc6f686b183e2999130c8fc0058dcabbc9188f26b2d63ebd6cb1e18a097c7704a59b5e187e0142593b7083f7400afa9b1bf0c1cc6c356bc4334af772e67153b45b331b990920c24eede2c6e323703f52ecd60735b23bf22b81ee775927c37e53dad7596ea65a73bb96775f3b87c8b3c088ec695bc3a7502c0c510f020bf9aca3cbb7a2c011c67ff27d634caf1dcfc58e5e397e6658252272011c8ffdd64230a93241fff68372c4ba85382bbb229309652922db68836631e55be69ab6adb8e4335357fc923efe154afcc222d60d07f56990a3e5a214b227aecff2cd1bb6f0c79ff545f70a616141a9d53f922a02443f7d2a4689c35b095dd394d50bf49f9680a5f7d9
+SIG: a23f032e6692a0e8bfee5b2d30b414cb16c35ad08da31f696d461a02857822c4ef357f0ccf31025a4dc95ced30a994f41edd1d087afcaaf3e8e875708320f80c
+
+TST: 651
+SK: 4bc5e05aa003a4492f4bad102a5390f7cebab3d3eca9152142ad5ef7d84030ae
+PK: 6751d3ad8bb6c64d6a17d7e447a27da22f5f0403f437bac9449f13cc853dd840
+MSG: a8f794db1795667d28d24b70ac2200a6239a34e2438ced1d03f97ed48beb4d6bea67c14338f7736419dcd2a2a7973726572e6afe7edfef22c99be8b069f04f6dc61a13b343c6e585abad2214d85c36f02996fabb46bb91b5176ac708e49a0b053017048fbb55453f2b8208d6678d1a8cf6a1ee9ad7a91e380325635d1e236a6ca1d6cc7f6b59f2a2bf184f5ee451d6799f69ba11a0cd6bc04be8a351a80e725b5fc4563e45bd4749ecbc45205229105b9de73261498527f3d4ecfbb583ff532753d07c38526bb482d171a261b9cf89906a7dea8cbd7e726ba31ea68803a6b004f6dcd19e671950463738cca78bb0dffa3d6457e4aeca657ec649b97ee30e97c8cbe6ce43c2aa9a69958e9dc881e4aa7b3278074e787ace5fb601d7faf7ca5103ecbbd3bd554eb1b066f8296d2cc57e8c8a32e9c0e6a926964d6df2d8645864b322c322f1ca8073cedf2b556711a7a20b77c0a1ed277a9a6ca2c07154e863fef5a404e3e89f0d7f30f218ec4de7a53aeb9c41eeaaf6ce749649c9998fd62bcba2872338e19c94e59dd5e2dd776f53719d21746976932ef11abf7a32ae6b0744665d0e0ce513955a9e68531d8ee4de9a8d35ddfb88eb5a486ad63137e8892fd7c689d4f9e7021b1173bb3752a5eecf2992e3fd4642263c7b3d815c29b466ab69285ffe4b8dafcbf3d01d635553ab7575a7a3471edc7be412d3d01e6fe8e3cdc3fa04d2a7599381e22bba49c5539d79c62b52bb0eca33f74255e41a9526a89289b15f1850d9afa87e6b6fa127101c1a6d88d433e0c86aa60bba8fe7100ed61d5a9d00a00764513eb1c7f5f5c3b3efc4532a36b407fe2d17cfb4e6fcd6049cff3a355623a3a41390ea48f42120d897949111be3d169b2d2ef45bdb894fe20b1a95ef66149427a9d8f80a9b2e
+SIG: a24fee11f7ec6da3e9dfaf6c858ac004b4531abd1c9d3bb64f40dd247f00359350e43b2d4b8fbec5f6b241ecf9f1101485cf418735b05f712018335b20068308
+
+TST: 652
+SK: a3bed9fe2354bd2860149a3db75a85b129cf83e9d73e6317ba7054521933f896
+PK: 5ac03b4f13d91d066b2ce359e9bb1dfb6bfa5afa382fd1ccd72aef1176079f89
+MSG: db853808686d6d21f4c57b541e5ad63394d465e60078643cab1e065c9f306c500078f0cc41ef0f9542b5fe356aec4777ef8a95554c97b6a44099e9bd6404fb0b2e41f91914b074d12237cd442ebd40b51b8bc8bbe437a2c53332d2beb2281bf7324a0cf5b741bbf98d1eb9858be926e915a78e8d314b4144f3d20dfc6cb7f48c23af90f871c6cda90845a41aff1707a87b4e5516f18e8bd7683cfd74070803e888338c9a18f792c8d3a704170ff982bffc9e8ec9ea5d1a62592f1688d4f2b01e11f9f88774c47ac1d58f690bcf288cf8a473d350a8239df9d3a62881dadd338531fdce7615807ce965496d6f35d6c042f0ce7f21efe5ce6425185941ed5636b8ae913a75d21ab9dbdb3c3b6687a45e044938a9f1c13a330ea9761e283e61d4a320e1f559882f34b607fefe32c343174abcdc77b065a92904b42d961db8ed916c01464ffd43f93c1077f1df7ee65031cfe05d780d01d08ee036f22a2b0512193b0c0f3801e0a0208eef245c9e519352d2b0096382f2cba06eb2a01dacf619eabbc883c5d4f2fd7c3423179c0f5ffdaf8cafff5c46b34a09c3c50e2949c06000207d70d37d65a743075fdc2be62d412aa63e363706ca90e6ef44e152ea4dc5c2893ecd08d796d41f172254c3d1d14bb067b53a0897bbd73c9954d9648b2af10d9c2703e38b6c62469f6f958a1ca0a320c12339e90cf768c87b4738c219f8093bff4c2cfd29459f6d3281349378e915a3b0e724c74d2bd7a851ac7c6b48e8afc7124fdcbcab5ff80d1dee30a6c024cb4331972366ebab26bbb9f608caac7e51914df058b9b3745d98c5d27e97105475ec017377e6316198ece4ec5909f04fc27e7b382e66adb62ac8a977f376fd5dae434fb55175249ca1ab6bb02dec0696f089be3454887a0c32361d172bd2
+SIG: 33bc1e0bf1b493e0cfb7ea40480a1423e091f7145745013173787df47a10db24c165d00596fab70e68c94c104e8a7407cf695cd3fbe585b5b176b85ccca4fd08
+
+TST: 653
+SK: 88a24f0df3ae2914df79da50ecf8ecb42f68c7baad3b6c3a2e0cc9c25d09d142
+PK: 12e6603f713b2305358568710018685e141553c47591396fb4259e42dc53b9c9
+MSG: 654e9edc69fe634c2308ba8c46a955e882456286eae3593cae739c44866c0de9edcbbf0db1c44149668467709dc9706298dd2eac3301dabad5bd8e93c5e8a93f194e0fc1d9f376c144c293aefda086b2218f2e9dfd7c2dc52ba33eb229dcf7bb68ce0f876c5fd4e81afd80169f73cf264e5dc0ce16e1b876cd11c7ad89058ee0820c40005d01f119f8be6f1afbe24ca4aedc18e97896827c3ed67fc45630e7903b7fee9c990e361937bf4ea0a4d8d16cf6d9cf0381e9065e3625148f8ae0491a0341d0ff9f727be1f310ca1ec3f0104aa054321784dd24d53c985b28d44082f8e1c108a44109638ff5116edd85aeb86b6ea512a19b602edd9d211070d044af5bedb6c8527ba3491e345bacc130b36960282ae737b85c769274f0f7c588f40e6625b236bdc1a3b87320460eeeada278124b5668874f39f59c2e6aa208c3b6a9b845c4d0a27a0546786fa13e51cc98b73fd7ee327b6215ec6b629f4cc7e4bd3c0a3db78a21fffe24c70438716bc37b8da7c5ff7c3688a90339c22eb50b7c2cd36b68831fd5939175689bd3e22c3881af337ee14435709e351040ef3da955724e51c24a5e2c09f891808393fbf8ef7f1f5f0298deebdcd8d666cbcf3e866c718999ab6b1feec9c47e02e7d63540f89963d542c5d01fb6fc30768968ae81b20c354b4000c132774764d6d443add64f6dd748f5fb5b7f6eba401db4318be993989fcc2577961fa5ad31f6a2a9d6a755285865cd5dc3a88cfb5aba7d923baf78b5d131b4c214df55b6171f45209e21ca6645490d3a3644dda6dc929c7c409576d37164755ef8aaf3dcd4d22775ee7dea0e565bd54727921c649bc51f20c1f68c1fdeac455c67d71a1cb8837f4691448bf0bf044a46f1685fbe22b1e01877f7477d3499408c4c316510ce2e55b98005
+SIG: 1707cc009186bf3f03f7bb9e3cd4cf6b737b7a6baade7fc6c3ff5c1225dbb2baf54f47c85eafa132c31eaca03e6aec1447733facd37149b7c6cf0cd41f611404
+
+TST: 654
+SK: 184d0ce2e9db7f257a8bf4646d16d2c5efc2702ced026b6906d3c8c0118f2261
+PK: e9dab8fd9d94dc9b24cc79c635cc57ce66518982ba3e2447240741bac0730ec5
+MSG: 6a9b876b0bf4189b3cc15f9eb4fbe7932b5577892a22200ce107156853d6d3ca363f025ad7a2d862aadc742d9415bd8d1fca13c9dca3586044e55a8cf5dee1ce564576e3e8e365540546501b34ca675cf200e0771a818c73d37fcda8cb15e48d5a0b9ea3beec0ff6610b2a8a214ca4f7efac0e71381052d9bf3c00c329593474ebd0a687a0b41d144b5e7ab1412b970a74baba4d274bb0dbfdb02b11f7f63964ba6f3ba0ad23341d083b91a4308239e33d50824396126588de72a2390c1c0fc06747c28772f630bf4d143f7a1159f028c093404894e6d16f634635d4fc330f3d7a7313ef756f5d49d8f6205eb1c792a9495da131b43345a0090c12ca56e6adac5be0cbcac3609d69f72415f6c37f3cfb2cf76b3e65f3c93ac92b63f2baa466249075bca69d4c1d1f3ade24ab31effcb90469c24bb410ab4723e1b7e1c88b3a36433563f71a99aad58fe80568f9c102da89bad97963e77d6622483166f3ae261f32a52a86101ebd645f6142c982e2cd3625cf8b46b9b2891246920f697fcaed397cb922c274945167a0e619b0b506377606db045783b0b88ea04e932d21ffc064a12a40ebe9b480f1a2c7ddd395a9b15efdc495c9714f36fa996f79f8eb8efa52d99a24abfef43b32a237c5bc0018da3b162f59b8d3d474e2ce08fa8024c58acc0a99ff614e6cd7fdd9ca4e8f41a1449aa618d03337e8a374d56055b207a9dbe69f5948f901ca7db0410f01aa373d9e0227623599bc212845b006e942fabc582cd726db5c443eb2dffbc9e3e7f0e5cb6744f7ad716050fdf2c60c7c77c253ab745db9c8552655683ea7ea680aa4af34df1325c29b8874b61be23de4ffba25424f4619ec682c26b3a67bda9bc4c94b79a9fc4d82d340495b437a1cbd6b60307cfcb10026f964a017623e33dbf233
+SIG: b1e3bf5fa74d7e442ced9a98d927d8c45e0e64d874f8ea5920a360a4bf42d83ce18a924ac796e1a77d1b0208294b50f822177fdbdd458c74356fcf6bd7945106
+
+TST: 655
+SK: d02bbf70d51351e3b47ad8e5ed263dbf556d1498fa9bd5dbd99fb4269009dced
+PK: 8ce4b59f94ced6ec9614d67d3066d9d3a0df7a46b37b4c1725ef1e57bc68a0d1
+MSG: 554560f7a7fd1ae7758a2fce7d780f6b3f043d3af89d4f19ef573c34997554df243faf2aaab65b2afdd28610d4a51e9a4b464db6db09ebf73b7d24054cc9b12814bb29ee99e1a73bd603898360f9dcf01e670836286f8236ed8cef075f3d563312c16c73fc37eedf252f8f42d30a13e7fba3b165238c7f81eaaeb53190f3ec3b5d63f0ee03e3987e390d1d81e8277e9f6c1ee6ec4ec3fa0d720e9f53f9c26f04aa2ed2b5ef3160895999eace29cf5dc254ad71106bb7e8bc29a5b1d2412593d08194e88e1659a73159a2a22033ab066e8d3d8c3bc86b7b01de81a8c66047b07fe24ed240318ba37ba3efb6cf632604ca4f446a75fd8e70c453f0c60ee16ecaf524e703f47df5c282ca3289b3af61dee4709ee085323b1e5c8a6bc0766201c635031446891f3494e9db20dd4e9e0838249a67e138d13ee2c96f61e771061542aa16ef20d81e3a0f4e4521a6cd6c92fc26feef03b66c70e035cafcc19c96fb9d82918fe197780eff0eda6e2512c56e2a73d77032b768919bea9772f5989c8b6c65c3d1e97a2180cc3a37579da70ce9806ac1285a3eab415c0607d88cb86542eab90b9d2d67fafffcad23a714000ee59ed68c956e81c445428882f97af74db362e45c0d1bd8856eed166e4aec4bfdf95eadb251e2a1ef804852a9ea77d34577fe70831a928b101b60ac613e7ba2e6ba0a94013a64c2f8219fd30bff409099667a786f99327bb03e2f2187f445b46beedab6d325afd904e39543e93f4b6c5443249d744b2d1a43e141e4768bd40aabe4057244e1eadd9daec175719e51a093ace32fe82b2eacb5ecb0da6c1ffe98c8cee7886e301670dff87113efed4282471afb6b8a0fdb505e2e8e7dbc1a08a22e9680bd098bf1275802bdb459413a3b237d7713a1bbf597e6adf2b60eaf823791b3
+SIG: 6e7c66acc954ffd9dd4c1c6335ab4fe79dbbed782c4a47ec30d848d8bb2b4f1069dc62e522a1e8017f54a6345e1728c073af6447856d8c1ed35878b571e5230d
+
+TST: 656
+SK: aa0fdae2a5a4c9c04521913004cd89efbc88b2dadf5abb246f3ca7f6923544af
+PK: bffcb17c35c1304cdd9d624ff69bee60ec7c9ec327d12350d70fac12b47cc25c
+MSG: b14184cfdc4a5f0c7f83f94a832f588507e2d72a89329870078571d208a0c4960c2fdc4c236cf88229981d12b10a1b6884c8650ddaf1d4b2eb981575b1e019fe3f60423676f8856a992cce36d6d0a3d026631c8c1e1ffe34134b296f40842b6df4f86f833e0175bae50e86bf856d1ee79925f434b8bf2c84519f1f5d25386049ce3ca61777e30b700a602d395250b60fc64ac6f8db027e8da8b9550f24ed11a11d9f9f9c5e0af145b8659751ac6b55861f6388a64336b31efe45c0802d76a53486a81eba07314b4d961c141ab34e2f76edac0e6de31422df792af081e769c7ed05da9a5af2fdf36f141769908b700937f0e1068c131f176eb96c67afdbe78f40d86007fbcd47e49e2e4c4ce049936adff1ce3eac42b96b3429b5626b1aa62acde07f45a13ce1bd211f32bd7efe4790c8371ebf87c164477a5c9fa3e78c2f88077b097344cffa031c4429c7f42dca07737850ee7a769b36d0f0625adf120ea23ff4e393a4fdcb6558dbf9b266a032e3b0599b9d6692fcebd815a3897607856325fcd0115dc310db3a8792fbebd399494c8371e585727b3d632414496893d03813ba1f99661bceb9dc18ec5dc27f52670318687769fc678ddc7e40227c200522013f5c0eec0e4781e6fc153a0c2f4f3f95e517c8419924ab39992af8c19465057f134486696ba7fd4651768b4e749ef36f02444617cf97f0a423e4c13b7b66ba2b6c456878b0b50ce2ee5ec564ed8854f782aa1d1c6aa760f2522c7d97b9b1abe0ba810959d7aa403a99375aa3e39a115d1fc6fedd002f3830a50a837dc720329ec0c73d5bfd500385c736838287e19201525d189c3a084cd5a3f359875e3b8325289ced18b63b00ff9cd070c3e67444bd3d8346174085cc45135caa0c67b3226e4a52e9a1c55aed7ec5fade6bf16c19
+SIG: f937298969ca34d97584448907358b0f47841f3023afc7ef7681521c5be0f5e5628a8f607e2f31636ef63646b0e9898a72ad355706d2c8060fbc640efb3d6605
+
+TST: 657
+SK: 7162fef0aca4974b094a6a08054395f877ff9433f1e33e20e88eaa90f938997d
+PK: a280640f139f45c35a4871537eefe6ef9db02de785ee9fd54f805fb57d3746ef
+MSG: c90f450bda1c6efd8d1278debd7ae03e2eac2740a5a963fcf96c504e31d4d6fcc5e2b52a2518d2741c55e9591867b2423228f9c19f33c6f38705c62036d480ff53df12077e38fdb073c673105da1e11619ba5321a71b5f4993234a11948ea110cfa242bc23fac9aae462606e39641ca7147eebba1eec553fce94e53e4e01b073dd780a2ff678b31572ca11ee0877e756bcdb6653e5e1b4cbfb569a9d60e3ee336182dcb9b25d1be6dbf9b5c7146d775585834cabde0278aee5d57c85e983f84d8833a9e15bcc11198e1c1da6ba59282129f1db966f5460c8fb6530fbc3a98a31fc0f4e9b337366eec1dce108c826d49045abfa12ee88797f08f0683fef77edaa3543b91cb118e424d9c408da547431125107d9b0744c2443ce9917e1e328d81850babbc94d920a1d06e524dbb6c23dd82e1787822d71c4cdc409ae85ba4deb581f934748f75e7a769b9d68c4589e594e65cb6c8f4903ffbabd5a326e89441a542f8ac264ccc64e95a8982a710b6c56ff7d10916afc409ea8a41b74679dd6a766f59c52b9305ba733b13c9e811ee13083925f4200682bd05dea339532522970aa149d004a2ea20ff461e9ec0f3b62565c1a106259c836605cc27cadc9515cb9979e89af287c027d75edbf87d5cff63a7fec9bd10e7877ab9bf868d734bd3a2374cef7025cc4dab710e254806685a136ecd03e36770346513a15145b890eeef47b80ea08e46c81d202e533e9a06a38a6f76ef57a9c736ec78d00b808e3ffd9c79b9dc7a2e589907656c932ab8a8b57da1a495ba7452015e7924b5269ab1f67bdb43a35831487ab9002f52d78b134cd3751925aaab0b45c8e6b0f2bf0cc9a4659317108fba9136aabb0921a58fbb9b50e51243f9b531847dc9657e96fbaf7aa698fe6fe44f90590144c70337250c58bc5dd
+SIG: ae161cce95403384b65c6bc9b393eb072564c35f3a6c04fa517ab068bcd23767cc0c8edd92b1a13ae9a9ce4864137fb89c1f37b748cfc9134b6741ba1b22280d
+
+TST: 658
+SK: dea180c91b533aaf736bc5d3c8e474d5e5d475b75b92cde6bd1d10f3b8f55ad4
+PK: 30b20fb320b00e77c4e0a8eb3730af3c0b1c5f5ed9ee2b0562707e4f55c4938b
+MSG: 606144b7d4f96bef7f112b6d41bcb500d2136c134ceda220e24d0f1524eca12c30f2b102c7f378d6bba259c5b4a5ef8ec9309d5c8da7e8d2ded3792aeeea2108f77d66b23045938ed64751f20d48326be2fb99628cfb1873d7dd27581c105ec13249a952a50784b8b34cb3b2c1a004fa8b628a0767fa9abf058d955df85d134a0fc7f4b7d7fb0c8d31bce345dd0a4282145afb2ff19751f2cc3a1caea242baaf538749bf388000e3dc1d739359dfebae64ae1e10fb6fc17cc9fb950535c2de129587a86859b7be36dfe9b6c1141b25e0915c8d4aa1cceae7046b3d7cfa940bc98d4d69fc5a30dde1dee42fb5272281bf8f8e7f3e1a04397fb4f3adefc57532ddbde36833a676e6f39c82aff6bf4832ec971e03be3829c02a203c82d9eb8c1630ee9693f45d26f5f51a3103ca64d468eceac1b29af4c42eb216d76ec8994836b4bec76489ca5070680c2c2eb457210a77c47fdcbf600172073a53f1453bb5c80439c882f0736de40637b4f5ab1f761ff355c6e9bd4abde7560d5fc113c830159a1b77c4e87bc2c69880a40c5805ecc8aaaf57575bccd8177fc6b83569233c0f5ca223ac4013ca106cac2854706aead714fa29f2860a5f9753268a3671d9f59cde6048cf0b8986050f7f549e4fd7557f2fc3fcdccddcefda586a64b3006e5825f27ca31687caf663bd90a05b1152d7c88d7f1051a9d791748651d888a6a12f22d6c8c3f78c2b86eaf5394b4ef7eefb89797b25e542dc93102d021a1d0bed6a7dcdd8102b8f0430a0bc21d904a3c9346c018343dd9937cb35250007a284825db08e9a11fee31cff7a314c48c42d8b314acc27822af03d1954c7cc8bf9ad4e9e98f4ad4efb355288daa8c90de9037e64a7861f5ee43ada9f0fccde34d0bcf50288550f700f215a7944a5380e2a8e3f04f2b4f5
+SIG: d083333fb84e79c9b33e55e8192d571ffc8dc50745b6b5fdd8c44d92a63fd178c4e57c2ab3a1211c0ba2d39da30b06629d8d1cc1d9f2593263d524fa5a2ebc03
+
+TST: 659
+SK: 9daf6dbb7f762966e7a57c2ec1996e9f5b555b9866b8e31deaab4356eb13816e
+PK: f021b55a36d9fbfbf2978bc0df736b289c8241d6435309841a134b07d47ce4ed
+MSG: 544523900daa6778c0391ae4044a51c0c4a5e444133fbd7747d539a744fa60ab5dc54e1819dc8e56899c56efd7ef3da341790ecc49645ef325c6568ae971d30d21bb7f23464f46a24b80d49bb93c6e91de79b24331d0707f43d0665d0197743adff690d615a1c9258777fc47d0217142426a4734892eb622ab8e50bb128ec3a895266a3861a39768bc76096f581fd082df9b7223e85a8afbdb5caa4922af2a014bf8a5cd11e5c5ea93e91cd46d5a1b99b85a2670e321de2e32255afd67fe2c37fd932caca22d241faf4ccefeff58d6bd04cfaf11dedd29c8719ffcb02ef65c5d3eb78b4fc0d170a2e3432cc812f0d041d9760c13c12f7c7f2f84fe5e0f700c10b1a69ca466a70bdeff8dbec7d318fb09ddd827ef61caa6910bbc061cbda2b527ef2e59ed4c17229972f89567d705de9231924b41bb6e7c01fe854264474fa76b1f88cd57eac311171af103d23078424a12675f2fa36c2de0bf53c295feeb3157de958922986e32513dfa33b35e15c394a11c0fcc55b82d6dd0597cddd27ede7de12985a616e64026befb5d690482b3ff22c0dd21f27a086d37a0499ea36fe2c4b5a959d10e9a610cab1fe0d28cf1013dcae63d8fdee0ecbd8b4e19d5d040e2fad7d0413a38e8c4e73552ad46047b5bbdd15c09cc0d34e48b91fdbae2a9d162d4b21ee20a1ef535ea883595bc4951692a67163454c7367f134bf645d48f9969e3d4f0f9eaf4144ce980a0a2e3342c746c2bdc3ccdc2f8a7da57a0e8028782d30af5857d9efb37666df65d7cc384716661e61ff5c09752595e94112ca1a840d6e4f6ec0e55494c5b44f7c0f0d4a99cd70905bf8485561748f4dc0fd7a44a1b139113c38a1e8eb5c7a20f3e952eaea8ce38b207c28ed972718f031f477c6207ce433c515f5ac2840f4974f1f16989626c76bc98
+SIG: 49b6bc46b7abb5694da94215efc4b30eea04ae2e73eb2da8e8c9ef9be2222498b17e13939646c29e32d645584640641590b1bbdbfe24f36c6f694bf87238ee04
+
+TST: 660
+SK: 7186f8d168d9ddf17edbaf0e7b1abcb26da3e4c0272d9879c7fdff6421c4ea50
+PK: 96b4a656232029fc1b8364703cbea7a5d7387518a88ced1a915ec8d886848132
+MSG: a3e6cb6b84cc5cf1fb1a848b4b8ea7cb7c87e0445750c61f9aa5d77deddf949463ecd39bfc71f2610c2a9424847fb76f84c5da1fa10ef718a34566cec1b3e899e7252e8d4d346016498ff119972750061660baed312827583181073d1dc74b76c430ca30d409e4e8439c0fc48c00680629d43ae2a77d69228f7f8a1253af15bd2cb6bb1c1696550c4c790f449869630ab92b9c11cde1f961aa2103ec23f7d9f0fe9c3c4132582efa79a66ae3426e5105b80bfe5e04dc8bb1e38a3110cd72984b3ef02a0ca62ab638cbcfbc8a6b593d2613dc06ec86fee34f6518d4a3fbdc157237174564daeb6674cdc34f4d6537cf81d8aa9bddbf3aeda312daaeee336f9ed8bff81e294bc7d44d25cd787072e6cb414b65fb7a846fc065367ba8e37beffdf0b7ba8f98cdf1eb870f4e8b7130fa3429d2e24bce5994daf1aa65e5f603b631053dc510b2f097e86e9b9b552302757968d0136ee6754c42a32c990add9cb529bc89751dfa4e5e3a0badaf4cc40b6a09507f9fcd24c3ca72259599c6ee58d857b3a189e048902e885a3607426093cb0fab437c0fb0ed2f1e96e9441a7e954fe3ef7646e26a39a07033d0a1555dfeed9a6f57794af3a2abf0057e9f853ae5c30138fd80e2f29c2f4a93ad3145da10a3e31ce9ff9786ac65d86037d98b7aa6d11de8800010e133869eb67a5039b9b8feb6ef903d0cc746412607da725ce2dc6a352109dbc6a5e40b170c23050bc4fb1efa0c34fec00eae3219c29040e8f5978c9384ee915d8c9398dd120d5c3cba38f8526b06197cb2c261dec7d726ae130f9bee17261700e99931fac4b4dca0f758701acbf3707d47df5321130ec10bb3b13078c4dc5de3470f158b57dbeb878b3a8524e0ed2c9547545f0fddf13125e45bb23d6a7b383a187f4c5d54a7b4c83d5957f2cd7e6fbc
+SIG: a9c0499fc216a14532d736365c6355f938f8d8194fa1132848f83e490454d4bbf69269f12259fc6c074c1015e425e4f4f27c029c93334951361a35ad1176540e
+
+TST: 661
+SK: e86e8c62566e15753bd5577eaae7f24105b74055a25629580708bfc83aebf06c
+PK: 8c8ce882d5f76586d8ddccc5579bcc1cdf4cfd7162304cb10e7696026e707f17
+MSG: 12fa631b0e482e9b9d633e94b82d8ab436fe548e5b95da92624623d13f2c70da775ba136c5229c16a0c7a6fa914b2feda564e17219e47370f9515bb1d59de6e9586204d943dc560d73e2e757f7eb39bbc7111bb46bc643c13f602112739bec778d7d4f49d092563d68f5776e430e3b0bf2dc1b01beb3040196da6302908bfe91e0fc38e04c150ef907dc736c445ff21fdbd2dc1eac0a0f5d00a30af028afe2ff61162b758c7da9a776666a112359431c48856a87ca82d3dd1c8af376598635432bf891becbc33a8fda44ce883ea8af4ad8b91a9261ce76b9e939c461fac53ae0f076e82d879aace8f38f120bc9b04d8125ed24bcd779d9d24386b1dd2017ebee8197376e8c36fa3aef8c1e713e2b8bce4966d84888681ba78495fbd1d6cca58626e6854cda606b83d6293d01e8e3e13bbf4aac851d9a1e00d0024e26993b0b3091be7e8061bcbb3cbb2302ceab96897a8e1ff367ec8625693cf31534124a9d5d725bcae001d67bc2111d0ab8111fa1d24e4ed06d63583ce690f2a04626d791d29e3e315a415bf2e853a5f2974c833a3fe2e2909cf669c73c1f59392d30c37f3b9c5a3ddcfd75621fda36e4ba2f16147858f6f206b9a140f1ddc1466c9a53ed73f82490bc95322c955f61d11cb51d5e8a58c6b3cb0fdf0419763201beea93a8512b1405245bfc384155adc5ce778aa74d00a322726465119af79501f040dd0a7a84060001ca89d2fe5e9cf9779a547e3ebd3bf8642990a3690e2b2c3e54cb7eeeeabc242b4dd99274c425a867931c929ca70808601c3908cfd788867d687dc366e976350c9e70584bd390d67eeb7cfea26c42686d3d9620f62f64104ef41ed1d130d79e325938486296b7ab2d2adb78526743e400acb2b7af09628d68cf9475101625c20e1dc051d73c997c952e12812c805b68ff
+SIG: 54d2fd44acf9e209bc7e433372bd73074d07806a77c6ce228e9be994418b00c7ecbcb7ac006c294aec9de668572add517c06b4eb4fe2ff3523bf043df44d3d0d
+
+TST: 662
+SK: a5cab2727e2f131a4d63facee799336663930aa07afda6bd5a8e985a02deb1ea
+PK: ac355f95260fbfea778c55b5af8b3fd1f24d2693da35de4ee508a27ed350391f
+MSG: 483439154dd5e5d109857c24d1c4e7fbbefd2f38651da81289f2ad3d6154306538b82ac7dba9210e740776ede4ccf51d4f63094b03e46ad3aa3c31947d8c36ce6f94e85296bdedcc1ead62eaa1441ecde0a225d0bf02edcacf865014899af66d9808040c2d02000a0f5ce4f1683c1a495276d9c4d728c9ecd6f078db8a0cfc267187238562ab1a1ea2813fb4f12e878e1ba143f4d06a3bc8100c3550118d69dae67b55ed692acf9444daa5c3e3c0a98ee28cf172de0c584c9f2ec9bb6e9b57f572a86ff8729f65f4c65b7feaccaa21720ed79e90618bcafbfd9533da85232b450883aa919f827f04c4a97bf51390d4f8569c191726f44f7e39fb3db73bfc415b6ffca8b91acaad69238572f14b49985ea03c98d7b1d44b3a6554765b19abf9b25274e97e4634e4b0f9e802eb6f743fff950757ee013a6988221881a7443f1f32bccb007e99379c7ca4f906d5fe11cb12f66b53a3d21ac947be0c8150bcd04f1c816b3f0c07c5fbc0905a7136956849da03836daec25c3e1a06ec3aeb205648176f89f4a291fac4f1d3899f56c9065eebb8768b84b31b7cc03108bd0888338d1774994970292d935031fea335d9e7908fe0254889c0b171cfe0af2e6fde7a5ea3de1fdcdae537b6313119c27f772024ef36e45c8b89f26c93d9eea13725e12d810cf9824aea04cb802da7e458e842ca375e3671346e0089dec571be169b0d90966bf368fe3698fd3e72bf16249dd900af6d29ffa48351360f12241714585f7a9b4c7bafc952226735de1462743d78abad0f6711f2495f3313ad4e0ba216b0dea5dc1516a9549f7dfcfeb93e591abeda5ea3c7045906523b40868ca5735d6a3371c3c294c11126d097f4c708e90464c1ad9142fa0bedf07dfc5f4cb67d6ed80f1bfe72683cfb2ad66530dc43d7023f3790ff42d95bd8
+SIG: 138c7a8eca5b5c37158813843c9a904e5f530ad971ee432a44f344f8c64bbfaf102ff41daa5cf722a4bc6640588759b8f36f9c059eab936cc45ed4796394a002
+
+TST: 663
+SK: cb6319613779a4ef66be14144b2840ad0167c03f3b8d04ff592cd1d2d722e330
+PK: 18eb03f0a334b080e1af4399d8376d83c533316dc687cf341f0afab450965299
+MSG: 874a6c81d6db7133a79169760c84d36eea3d42ea0892b7c8dde844a3a6b60aa9f2660726c9c4dd26a01f4ed0dc1c53ba6005463f7ea64a1ec63953bc3d81052a2f1084389a7706df74ed4136082ab5c6e8c7f411df9d3a0f3c40f5a60e2d21a8548e7a25dee34030b3c3e75caa93ddaa9c190cb6deda2413d54e373d4353dba43d39491a2f56c8b36d45016f77d7471691634539e76c4fb41913472b0a23054f548f54b1e7109c8b6521b57ae981d050316a33c49c7116268dcc4b78c2bae53a3ae4dd178bb8b76bb3befe19e41a2cf12cebb71168f971f202461c63f7d6eef107f5b1030edd4e75009e9116c3cd0e8bddc299b41f1a45e784efa646dada64068e9248ec988f232634ad3d5aab19560e830a5bd665457c94295e1af0160fbce272ef4845ddf0c4f24d976f518690ea1f82ff4dfa4813641a67598ea98401e0ff10a0e582e2b90867b4e6232c34ea499c169909a44126f377d8cc1c11905866340efd1e7b077dc7456d59c9b96a124aac3b33bb227441bb7a52e6c3140d7a4f67ca05bbc93c93775b929119a224ed8f39005820f420cc6c530e61e20adca01e939cc031df49cdb1ec8ff493c9efbcad34c57108efd764558966fb1470b0745e6966191a9a9e44581b09faf469f951537203d926bc8a55d080a805181dd7296ed20a818268f755eaa66b082242f4d020f7cd6720890484c01c757fe35d87b5bc906deacc2e3071de4601bcf0dd6b837c433106047fd8ec9bd0e98c9ee806f7ec8c5a10ea2136f1f90f900b853f953f00b076bd1ebd929d08a38bec68d866435047bcb6721e06b64085dc0558c1fa85a2c83b0caf4c816084f10a4c5885295bca15ff7c18e596c62c92ee9921a27c29d195bd282213ff3660b6e7546b4eaa777ce39fc5d20484c71ed6ca06f9b77ab1d872393ab2d10255
+SIG: c1b399cdc198e9a159e684fc26686de660da54cfe312ca7345df0c7d15a35743014410bd2f6cd11eef33a89b3d15cbc17c7a358937fd997205051f9257c25609
+
+TST: 664
+SK: b298adf38a6708f8d18ff1ed96bfbab421540d096c4e4351b92209b5e6aaab65
+PK: 770edf42b8a039c6cab9ba65ebfb135abc2da314a4c309f46a8f325b52d06593
+MSG: 9df4d5d7565d2c052262dd34d6007d86d9c0f07c7089af6119e304f4d8011d7eaad77b3ef70cc280847d59f297202b7e1861aef334bf38de14740e8073c955a851d2cf3dadc3edce15be490eaa845ba553fc6e8746e52915e655af4b86c629d4c522783635d464a2825777d89d7097677ef0e5eeae38537ecb656e3b28dd07358fd9fb2cd462517286659aefc79d374d1d13ed93967c530cdea4f314a0f91d6289b4c7a4279b6f4c4abca33357f69ed84b9119637adb7c18e694cb3c56e73637da910735d43c38aa8086675a06ad370e5726881da5e1a1dc6144d6a62aff7fb0c352d88dc971a3d72d3071e14b47425356af1b019233538261451a99a6cf4a07ce9ab1c3990de6ab8de2116c756105c512b7a3eeb3157b158b321e444e806d890b3890ed9ddc869f1711723bb99a72bdb923d131ba4edbfbb6dae99a5c7b328d310df9a6d1dcd85918962833e89e20f5c5e6333ac861094ae9e799c8641b9baea11a2e0ec234be5930e02880859cdec0d978237cbea5c7c32c111bafdd4bfbffe4fb3485effecd51bd195a71404ca5b59afa252d7b5ff9d030f48c6faadbdba918f21a0cd39af56966dccfa25fb5a5cf9a4b26a7f5441df6e320e34b27393de2ecfbd69a1594909a6c685ec645fcf3048d0148fa38d3e8a64dc3c21ae44da7e46a5ea7936c2ba083689a78ca3ac60b87be6d23ea40f5961583742842e37525a49c5fe8fd15d7b0c9e8fccd07936d19538212f7373dbbf3df7d46adf9d9f5db09524c65b883ae6f6cefa24b19ec48ce28cfa734d9bd6e77837d1a14d6a19d345bfbea559e7e6bfb71ddad83cd8deeab687fe73c057488f8f2b3e2e26d13009f4d23e6619a23c0692af76669217d5ebd46085b398890e5c91fdb4db5ba40e7773d518d3cf00c0a5b5a4b0f1b85d62916a59e5607b7b1eb80
+SIG: e55f8d304122dc175cf0274674fc9dedfec2b5f8a2eeb1e3e7f8e0dfba0dac2d32f4e704ce91cd599184133c3bf1063d2fae63d73acc5772d718d81183318602
+
+TST: 665
+SK: e9cf16d696f63b59e5e25c9ee2d75bb05ed2baa591a7557f9fb129cf983de0ba
+PK: 6d1ae385e80a3955e8d0c593a81f431cd432671e78cdbafe83fe58dbcdb98560
+MSG: a10fea8fc93eccfe2a6b7826079563adf8aa9a666444932200cca9447dd027c5c7204ea62bf8f5e2e39145ac3948ab3f3186887b30bc60233024b483f3f519036a3e94c8d7510a853ac6e20c6e526ee3cdb76de663f67305ad80df2342c8501b4f4a8ee3665a798fc437dd814e4e47e7a466890e0ffa8f510f3e6e19c9c969f70a76e5cf3054d17de459ac8ee99550bd38319f36e433434a926ad68b961e0ca10add4ba992b3650660a2c3c26f5d740a31afb7763f542f723b8a3c92d8ae92a567764efc70530312baabdd3fbbd527fe0fcbca3f6a7064cdde1856e97ab786af7d7022a9d46a338e8e1754afd9adac856a38de2a4c9766dee8dbc709b0671a6a6e6e1e5d12074d22245cd73beeeb1bd8ecfc1e85a21bde253f7c465abc1feaa961c0ff5cff2d896472ae17ab8488e33ffefdb72c105e204f944ada51ee13981a136c0f38426e3e49b0e91841c32794d52f1335dfa637f151c7e40f9b830aed539ac5731b81cde3264d22bead31a6cc68d1a73143b5ba4816139232f3f7f97983f4ecba64c49553be9d6d943f91dfe03d1ee8618cd40d2fb7238a31d1bc38e76a551f9eee22e73a27d7a48b408772ea72c3ed637bb4b168f9d7aead94ea03bc11109901c889927d51cdacf962125962559979d3e4c8e3b5ae582f2dbad4998802856c4df69e8fb54917e2f36bb67a19a26e9a9a9485bce98dbfff0d2b02b9377a9137a734e57b5ce665053017e992677a1aa079240d2cf963cdf9bfea8d460091232daf89801fd75171a6195a5c046815914be1f62868783d6f2cf28af9378d6c6893e75de641111c684727effa31b8bc9b0a01db9c9e81ccd8f4d4e875d4bd90d253f58989a8a52a203a77a496d697986b031e9f699bc6a16cd5f9c36018ebdaa36bad0e014f4cf3b4b746171bf89314e8b72cbd47cc616a
+SIG: 8112ac37eafb749d3f4a1ea1484379df3e383b019c12de8515e349e4f6f998632e30968347a1d15b09da2eb800b03d819d202bd10a6a463bb02b366d6855fe0e
+
+TST: 666
+SK: 238a6d4979321a14a997236f4585046cf7a05c0adc6ba1fdb19ec2a32f62beeb
+PK: 0b4ba674e401665b6790cfda080704cd90e2f3d3efab253ed8dcfbd18e406789
+MSG: 97cd619a2251eda916646431d4cd1598c2d44d06af3e48bd18e3de7fb4bd4f78e00a69eeabde3f82065cfee6cd711f07d22637161ff685f65a7ddf54553197fd31c5c6b71d9e365a941dce4c3e225d19cc633a7e12862cd23ebb7c74a704850f761ac0241be517ce7c360936ce07250d9f2eb2787115eec377e1134dc08f44eb0a2a2a2716f00144a49f012a57b3cd06efeb3fae920f285cffd9a401a0b986594e17b2c9c8fdab835d9f3f5d474be733c1925ee6f09386711066c3fcd645eeb0fbe7054169eb709d4a3f0d16f28a1ff5066c842bc63e359e92485b38757ff46c27f79d0cdcf0e16e97e3c7b7e2178dffd270282dd61205d5854d841f0e3fc0e482cc1ee48552cfe658935b5427c366230aef79aef4021d6fab5f1875cc849e321a75500e9e1ba5dd596b438cf88b235b01a67625c4bf84d0724ae6880a3785e33bd9235fd0f5981804d21cbd633cb180f34456460207a290a254d9fe61063d40634ca3872f0935fa28328795ca41b006a2111fc5932b1e779ce966cc47adb7c0dd987333ba7529a1a4996ce9f56e051981fe1f553e578f43c3ba94beacc93c3e739667c7a7c6fa27e1e081695d20ba705c3f10b20df530cbb0ecb87456501109687019318452785d38e766b3cd35b007d7e3cfe0b2cca8aa6ef7395599dcb9c4d28bcc35c76dfc35343cb1348ba3e962f10ee86f86f5b6d4cae2e8c2b185e3eaa1aeb87bcfcf2fb76cc7fcc6895071b168e8b7f6caa0fd6398e778cc07912ff5d6e61021a8a59ae0352160f56d5488fe2f2acc9403da9a9ffc661c1e9dc5be88c420db0fd77d845dc8dd9d8e58f9961b79afc68624baa86aa643a8a3c7edf71d553cc0d3224a6069ec674f52da29a1cb60c4192301a24347a8aa8326269e0a14780c9583cdff515927fd5bef528f9d23787aeb803d70eb916b
+SIG: 2942f708c0ede4cb0ddef13b85d71d7213e0383dd294f534135fd69cafbcfc0e33090a2a0ca3fa572c72cdf5592de903b1584495ab63998150f2b393a3b3400c
+
+TST: 667
+SK: 59d501393dc5999723810706fad7d6efd163c44710c741c185c27e0425e3c05b
+PK: 8265d43cfb0735b5d7250fcf0fcbd154bfc0eecb13b7ad93b6b02940588b843b
+MSG: 564ed22c172f5c3afbb0b95ad2fc64e4be6d4db1ebb8d399c43a5e16048e7f8732181e5d0eed8e638ef2a55aa0d7b681fe02bb5423af94bd352d3c2ddec0f84760a4112b4fe017cfbc502f9543cfa41fb2aae75a3a081f8c499033d1fae5d9c50cb44dbc63605a54398fbf079852eba86f2fdfc272d0c4179d7c13cbc1c2a3da0b82845cf1a46ebbe31e79b6009733c7bfe7aa4f9ffd719c77dc7d748e492e14ee5e4179bfa9e649cf0d89534186385ee99410051d6656e623438cc7b2e707e48c84915549ae8d67a306c67b106b7a25f45f8e10dd7dd3eaac31f1052257eb6a7576b685cb9e6c1cd0d73c7a3ced5a8dd27308ae00f95eabdae9d1c4aa8934e2424c9328a5228f4f82dd4a66556d8217c5a22b2beb86a2a43413ee5e10f883f2cd6c2e8749b5508842ecae5ffccb796d9633e87ef4a96c0df7ef47b283d096723ba3135bad75b2e19ec04f70a478428ad5d0aac0dd2ab9905913e7e5ade408801d5d3c54d9cf7b8f0f0c5eb054c1475cc210a2c798d8bd89932ff9f360421858053a707b8bbd32055c44b20712a2678a9a6af9e36d04dcff44f431cf1930cd18fc935d2267775c69096725ed89a291dd60e21ac0b0128734072992823ef87b5efa6cc5b050177f55f4cec92a08a65bcadcab9a41c36086370b7b9dd6298ac7b0ae6a09c9710abb4676a8fc87a3651290144b6b30ef4f6fbe5b9ad25237fe0605e3b9f18a7718ac9fca6f325ea55f49a807fb80a2402ae13423080d327758649023798d5728e0dc64ac88a6e2945dbb3e3ffa9fdb4c7b58fba3f5fbd67c686b2971bbd8ba4d275d573eb796eb9146775d8cdcd5fd3eb5a88ea5a930ec3244e6a37c81f6a2554e5ba787f0e45319fe4b8a2ffbfed50770e7827b3e7bc2b44ce512ae6051b6f9f13931ea6acc096b8dcb0196be422484db5fcb299d
+SIG: e646f164cfed8c2e060710dcfbc3e9fa5eb396376813190184e346f52bb0ba5746ccb6b59522b1aff9830f2f98b9e5dafcd832077883c44e8a35388f718bf40c
+
+TST: 668
+SK: 839fb132e69250ca1ad94510087f92ce068769213a19b2a6c89490f1f578807a
+PK: eb586619b44a15379acc4621a2ac71ea58970026c28e2409fc1ba2bd8b236d1d
+MSG: c57232fe32f11e894b437d40456207cc306db48169b20e0781103affe802f5aabe8582952ca8e95745e9940d535e00ff65ab3c64bed3d1173a0f3d70ce4ebe2b50d048bb47164d2a2cd9d95a10cf0d073ed1c41b3de333528ee32968223a0d847cadbb5b69f382164e9a28d23ec9bde9a828e8771c9eb49220af54185508aa073a839195f103bc2f32fe04f951ca45bfbf30d2fb8114056a736addf27ecd9af0f6e5e97e5773c4fa902268c32a151410955f3c76aae255549e0f033f89e1a78f265cbab6beb7516d4badc49cda4588316225b4c85ea9fa99c7d6766e9490c49de59da717f667653530071dd2f0c53e31d8768156feb08faf00db0a04533df97957a84aa46aeb7e36c0b0be69018946f1538a6aea71df536f1442c2444a43a043d046abde1a782b0f4f5c6aa720aa60afed947c0cee477dbec00557b37212d93357ca2b6b6f82715ba0e484f6daf2d0b7a98c033519ce38263586796d5d31cb2bc3d1125bc0ccd329a5c21fd27a218ded607a0e7515b571f192c33f5fba514afe4d458100f3ccba3f38eb430b4fc88faef999fa71eee488228903be29f24df81dc911044e924cdaa017cc7d87e56a6cba8760859bd63dd2d4f581b955ec924a49afb47ca0d63e7826fdc712b4943b739e1857755a33c6503675fddeae062706e34f744fd932648a5608ce608a61995783f3339ca3fe107e1972744bf6d4edafbf47ce021e05821fb124c7083930e68e6f5c32d2d9fc4a884c0bc88404e4cfe3c1a2420d41823a385fb3288db65c89545f6e73f0d8004b2ba12a4e07727523ef085670daffaf41c28a4c1157bdd245e68750dd200e023af90c67561e0fe4ba340c433f755eefabd4b039bfc323dc11adb75aecc448a869c7f2a58b9d8617c64b8f89fc583f8c948e2df0251a6c7d8c738c3b5a42b749ad5e8e986bd8
+SIG: 66437b6bc05e75dd1626c3c4ff1f72e6db381ba1590948f8f16ad4d66e5991659aa84405568cfbc0a77c025e59e43fd53ab9ffabba7b258f78796239f90d4501
+
+TST: 669
+SK: adc1e56c3ac94e6cda0411cbc3ce2af128d185a2a273bdb2af8d7e50fb96b526
+PK: 5dcfec1f9112751564ecb60715ebb2c517b5ec37b2534fd6329924429b7fd5c5
+MSG: d4f959474e0b89e2dcd02066984f88d739dd1134a33309f0a8b7802eaf013303c13515dfeb461ea3d248e998b9a4e54dae5b00190a45e70dc67e98f3d4cf906c214d4f636d2952925e22b1a86a1aabb3a892a9f8ed454f39c63d35b71e87a2da55a8e167ac83a866ad167a17aed183c08518c15e6be34858b4cee2b8427314760fffddd5923854b1747f796e1a5249fb3044894ed646829f654316ee52f4010c8dd321fa1dec397e50145ed9e31686fd5203f7233b8da780acaa91ee0b5b47207866aad85f837e03b4e6f6de8c04acafd707bdc1dd45500ab564801bee9a58ece360d004828baaf523e2f5ab69326a03aabe010878fd43ffaa56872244d7681f1618e623e3d474c73af8b080a61821a574ef2fd752d23b605ec521c19c1550de980c094d05e0238f3e008e6b195abfdd4028ee1ee1d6c66a76f178f0b431e4af44ddccfc5290edff36ece63e8385567013f43a2aebb67e3ef406308c20488a76d58a214f3139d983b19afb12e3283607fd75107bd31feb6256174b7a18aecac9f8562582018b0e6de40535e35bef2b562553885129397562900d3417f98cdd1e29d731ff48933f2952958163ba67d59561811b83772bd05710b6e3cc0434609937507223abb71a6a8c838fecdb1d2d37c95dc806f65f3f9663d99f06e6c0f3c32e95af1dd708e81108636a26b968e98339c74128b6cf671335884ac72f75b637195ea9eca053608996c32ed445410f67fa104b39f0fdf3c9b5c6157b76803756b27f4c3ba1b47f328576248e9bc53e7b8ab0b2ed97c2f9998bcc7dfe39e264aad30c6cfef2b5553ffb5a699aa4bd0eabe438ce0522cc91fe4e72bf7eacba4771ccf63a37aafcadbfbf99dd76b85b80ee075d3a7d1a90a55b7729a5416e5be696bf9fb7f3158cfdb5cfdacdde8172ee1ab9486e24ccead29b457acf43
+SIG: f02e5dbcb68704afad03aca81061dbdb998570049f10ce650ec7a2eff15c793ddf5a272cb683c22c87257c59bdef39efea79bd679556ea1505ed0036cb46040c
+
+TST: 670
+SK: db89df6a23d890b7f00260e81f4ad98fd09440365131e85e22c7951a187b0218
+PK: c96763672ee4a2cc5a93b6a683df9b5de4d9386a790835681d1217d19296bdc8
+MSG: 54c1c5111e08c98245ba4f1318ba1db1dcc74d14a5c98ab9689cba1c802c68bcfc81fd87ffc61caa942f66d7e5157f65538c7e7b33170484b4b6543f3620ff29638b64d4dae7b02221cf7783f187ec4231e6b6946d82762074f09c32781c2f3846de3e8217f6e1b6e0d2b5595d742e2c4e325a2841924044dfcf12b479eb69f1bbd40eabddd1ff54a9184d366dff9d8f2d863e378a41f10cd1dae922cd7fbb2a544e47eabf47ca0a38abba34454919bb9a4ef044bfb97b708c2f7428d68f9c57c0ee7e7925f7a2b5c6e7df82bb2680c862dc7cc68b0f54530e64afe2763d9c7baf45cc6fe612d1f7827739c4411398888f7367c3d4377907acc06a06f93f887226798f48aa5464f601c2c1edda77edfeb9b9b5d5f9cb6fed37900547477fca1d09ab52d63e491feb12fd6dc805a78cee3baade4352982061dea5a2653db8e7607772e834b3a505c16dd6e7c71b911e842eba925d77a33c5c57ce1184098078ca2e6a3f69aa6a14639dc97b4b30c99dc4fa3e2cf63c701c306c5e253c5113854c185ebc8b4798f68d1fd780054d3eed2f394c454304966bddbd12280834ec9b40c1e98bc2d98f4845f6eb44f25315eedb3b79ffca4180c1bddd97d0c9affbac58814937682680076fe5a3babb65d28f2517036c0cfb42f0293eb2acb13949fe91e0ad0678aa243d7734a89d997870bf9a6a584ed6e628163e39d8aa610d46b9285b9e1dd7e8f807fdf5ca2bbf6de5e5e68af7cb7ebd43ecce227cd70c7bf4ee1433edfcfe886614670cdd196343fb91e15416d2f6acbae3eadc030231ee9d2ecc52a88ce8dc7d098e7fac77685b4eb540e3019307143221b8ef77f3632c893d556e0bb743a1963ec15886c8545e87c95cc825f200d0f3cf4f55a3d660a536a23aefcc428a43203485ee84342f5c001ee8404e759017006282ab8ba8903e
+SIG: 80b7fc8b6ae6eece8166b7ea534cb5b214c9ea9973921ed05de40c78e14f162b09e978ca6d86ee434d984b8b0070409dd2ad11b53178e239dab5bc39c7ba460d
+
+TST: 671
+SK: 00e6bb17af3c2df652b34f9abe19f99019074233686c7114e3a0edf08309934f
+PK: 7b8232a66cec2f915aaa7951d29d2b9ee93d321d15b203c51e61e8ce83d187f8
+MSG: 063281e41e8ba9703ed09ef3bf0ea46e4cabdd6ebd769d05dc045d4f990d69fc554130a4e61aa21e2de4c92db48a20a37b1747a7eac5ebb2735a8938197f139fad1497b351ad064c0f18f8faf1fe11f63979a69968e24cf91e58a3ab032669e4efee274f96b58be7d9e391f36fcf0709b2cb2d22694a6ceb17246945ebb3bc7f0f03bf0b08dc9626e3e715c991671d53ebb9ae83a7d08d44f63635c40f8d4817f58de9eb77cb25b2acd6def969ab569e974a8adac11a86b58fe6c10067499fc914dff56902cbc393a71cc25e8f05c03c94f13b84a2b01a58c10dbcbb60ebcee487f529177466299925da50e2da5b5557f0aeee3fd7f47b5c2e3f84cefab4679691394dd122303bb769afb3adfe8358b02b679273b35abdc6402576ccce5e10442a137ef9456939b289ef4e417b1cc6239f7ceedd68f1a8264180e068b4966fd67f2bad6edd8b4a1e8d2b542daf26db831f1fb51eb86ffadeccd9ac3d664f346e7d046c33a572841ea8334e7f2f417a05712a9e334e487fd3ae175455162fe8f49cc026a640c6cf93cf58875052f41cc9820615653ea2d084c896eafe5ad4725579653084994f956d5c94590a2409581b6fc86e40aa58bf6e6057a6f90af3b87aeaf32994a55a54f79bdf3dbbf5ce0ff812e486b0545d9e9c2b0bce0d4c3647b1827262498834e198a3ec70f3b03d6aad2c49eb80b5e2051439225fd9ce9468d69af70a262ee3b8b62a8e5b41346da3012ffb45816b7becb0e79a60bff71636a3e4bb1b35caf195f55117280f787217b3caa2e793726fc5a74d1160dcad868904c197381134ed8c3db3750b7556f69ccce18b77388b58c5b8113e590ad6eac5b91ece5a6705025c80353ceb1ed84aaa1cc48a416bc016aef173bb80b2ba28c57960c6b011b6b495a3f3311e79fe46bdb6a4c381fb9dc4628b0a83023558f1
+SIG: 04b3b8501e396c4a788e14ac49f6174cdb5c855e651203cf68d1efa89aa58678d4d1f303a9877a3786d203c355b09d5286c1ca0df04a89aa06cc3f9d0fd30504
+
+TST: 672
+SK: fbddf6e61e20d806e55917756de60d0c9a99976f646716ff2ff1312c54dd971d
+PK: ac538fabad4380e60e977126e7695eeda5417d85f7d23db21bd0ad111116f05d
+MSG: 3e9953ca55d0cd233b98833eb1bc79d3b55f18c8fa1c42027bca25579153b55da0c5a178b8386956d9a54183b24c91dc4be994847237d3666a0a0130fe19924bc0ee50896c35a2e16a29e2e2acf180bdd9379354687f0ece6882d26e980e686698043bb1b01213aa644a4f8d61f9b613e62eaa3576cea0b0b83f05ce2558ff6356495c45ede4a8f65b814ab8a7309403dfd43cbea90893939b7800aa00232b5f6b7714ebdcd8bcf34a5a7e822ac7b1b099ac615f135f8c351dc41ae5f66d5f9c2600454ca01c009ba6de04162ae5f1f270893ca3907aff7f78e03396e32b622ff340537bf123e55995e9209609330b2eee51127484a40e250700823feb0bc97bb509ff732675dec32ecb635ed92c7d78fe3050200cf1d941d6b388800a8419d96a595eced5ec4efdcb6f987f5472a5c43058d3a3a7bb56d7980365ed43dbc2be48f1d18ce76a89185426fd5c69df7e9291ab7823c23a76941ed3836aac7b58c0d5fb6b636c42471a4d1703516f03e935f31f195450e537b2a07d545ba4b68afb0638c65bb0ffaa0cfd69d7104819796619d483a0245b4fd9017f62a7d3a5fc3b7289d75735f287ca0a951ad58344b2ab7d7df8dbd7922a5abb8d7c2e79147e6d36ee31f930473b0727dcfd58d644d7d70a0ed31ca6a13ed9dbd224492efda19e4f8eed46180fe750f07bbe8e99854d13f58ba968ce3859d61189cd2b667f3b2d0665b574c4bac19d9e37e5b7a80eb334e36810530aa5d1766393f8115a52090c91823428c897a5f35e12a8af2cd4fb13907ca6603a4f76f5c2e02374a8dc3a47c1be6f1d1c8ebc59b36d1cfa0ab23e9b0ae9b0e637eeedb9c66bea62dc630cdefa718239617e3118e5b6deb7c294475282e8abe24fd5a54b786fff9028c5a033384e4bc8014dec8da100a94b178ef88ec357b66d2b9098ab64791696b1a66b
+SIG: 8c9b77aa0f1cf52e8f7a918b21b468e62335911bc59306b30ce77bf692c11059b0ee9c5daaf6839bb81373c61d28d072702b595e4dce28cb993822b24813040b
+
+TST: 673
+SK: 8a55e77bb0c8740b8c2e8ddfdfdb40f27e45fe81fe457111bf1c8730eab616b4
+PK: 9ff1fd0c50eb24f99fe2f7711d52872dfc900380dddcdb86fe6f4a5f350a8743
+MSG: 20fb414e264a954784f112bace7e0474b39cb3c9e53dee0a21f4cf6d4a99b9347ddffbe281a6c230a75d63a72fd05f6db53ea7014ef7709d18ff970f485fe83ba1d37147338aded6da4cfdacc1e69d2f3e0ef362f47b5bcfb78a1e179eb5c5b106c8d82a0a0b290df075ab27436929cde656f02309f95750eb676583262e5f2f69f0ff72a8e057266382269205318740bfe06bf5c2cb4533908ef9f9f2869a75b9533579820e3bc0caffd646171c8286c3a4aba1ff0915d93611205e230f39ff4c4caf3f333e753fce2b71213e53d608415ee17fd48212eedd8840f337101ef0d0b6f7be4bffc06eeefe8066dd27a0541a468831acddc4902e2fefefbed19c308e5621e0bf46bcd538aa13faf04d380759c0e107e912001839dfd0b635440e9638f5377ca8450f350c01129ee33764415c53cb2ffbf968df78b742fd0665e78a34abf4decd1fd386289a1364e64555eec58b0af9a4cd6b36d1d5c611a2846dfb5589344bbbb02560241b74b993a25bef50fb1e7319086e6a23986300834ed2dba98a168721c2f784dfb8d3800d06a054aef14d1772b6c574af2563d193ef2e51bdc62d2abce2eebeada79203498e6686c287f37bd88aeb166f7dffc3e6ad0294117ef6ee9da8479ed8a16fe9be246d266804f29658db75e7a0873be71dc7d407e39fabd66f988b457477427fad8130f09ab665f1597c9046e7373af9a8352a86830cb92a804488700fe6891924fe2a7201733d95e591ee0a1fef1c2636078d370e7ad3b6a944fed2cf2b30aba2d56f3495b2849c03bb614f48bc4e507c395a6c35d3eed4c7be8e680f2d45a310b187eb88cf0e8ed4de7d37246a50a6367b97ee3784322c0b71131a283198da4804de751dcf70c4bad00dd98d873a69dd1a09cf69ddfad7ae603500b6a462258098d8b66b85293594e208829b5228fae2fafc39
+SIG: 8aaeba535c511c31d3f8e95cb077a9a7ec7d08441e5342a6abe0bf2a5d7fc930b43dac3d1e8ef2cb034552eb4d0839bc8bf294551dd2d80c53fd6279351ac20c
+
+TST: 674
+SK: 163b0cb6a12e8f07b0c29d6a63f6a652ce497270b5e46fcf833c99bd843f8c64
+PK: 68a35de4ba6f0f82ecf4b1e0df8e24cb4f18f2103ff04dc1b5333991b6d314ba
+MSG: 56a1603f725be07613058cdb3acdc52354e3bb1ff2bed13f895175b15c8c5a90ffbe46b11a06cfe362dadf7323c940417255aa7aa54312103e71463daa0b5cdaebd0be723c732273e3c3f5bf7aa3519d69df6f4770daa1df8280bb3cd2c714ac030200546579f56c60b91ae11f4cf874a35fc59b354bed80f56e11a6cd62a88ce6b4f6bf39d64ce3d80409825f90162c3d96d10e478607365f7a241e71af980042fec2d68891e0c8a37c58ec4e600fd581e790b0aae8e09f35d4cc1876df434b80eee05369f848fc4930577d1684275888f3259cb47376c5169c9937f855a96a9e748ad0a69ae4ab2f2f1744a392f9acc6209975b784984cb12f98292c36a53221994abc56f9a66dae4560b79356ff47e128c0796a7fb0e0bbc9600af48e49eaa9427cf6eb6620b10cd2c085b0b342004d5b0d3edc11d29242a4638780762c9dc6069b66bd84973b5011961ce56db58bdaf48e6be12ab9ad24416297004d02914b959f54e092f8cd4365fa6ab78ddbff4ce8dad4e2f53a05c0cc499bfb47814a2713551dcd19d447f627576ea4ea4bbda8bae18a6465ced747ea17180b009f01212160482b0433aac68e67644d00f41fdf9990b9e11117634deb139b1a40ad3fce4299a17fe1dd225301c7f8d8010a796dc79c13307d3ff992a88be664d4c886d68ca9e4470cfbe63ebffc424010e372b6922aa95c801d1e9406da4bc188ca82066405bcdb3eafc937629b3263dc7d50ee5278ccec6f11d5517f56bc269c873691e7eb53faeff07564ab46b403f15d9e0e692486ee098e7b51b42813469b8235042233ca3f9c4f8ff24a571f47e0adf9144aea488a2d2dd001e31fc961e05c3e85f0d981407c873158bb0d35bafe4b60422e67551e970165ce3fc599d0fcc92b16ac36a92b2c1dc6b3f033fe310cd196da04a4e639031177cd27d7c2fbec65a00b
+SIG: 17738f5726550780651d60199fda39d9c4768db5917e32393631c54a419d59f18ef960ddd439380dabc314761bd0cdb57cce481e6109fed095dea6e865aa670b
+
+TST: 675
+SK: 8c839381b6a7ce2649c1ea464ae3c2d3fdb1ec666d7b4be4e2a941ab6d6557a7
+PK: 5c724a30c6fb32815343a80ddee6eee544516418ea95e1bac80afc8040d63fc6
+MSG: cbcf89c3548964c38d70fd8f68e8ece36cc39755c971d14d7e056f39b023ef166d17f2438522f010d6d835d886e71f474c6727a4221fd03a7574578289ed5493ac4c0947e3f428d8fe064006a256cef21811d72678f5dfc6ba66ac29ecd1b32ff5557cb08c5f130559217a0413b759c24d83388a2bb9b29b6b91d1f3101ed625211e4d73805193478cf995396c10b1c5affacb00899da04e3cce193b494e2a933c4eebe0a37bfb8f1b8371bde5fda09e804e940f344896a529467adee45a8febf85ab036cab880143be4f59b7741d8e450278b06365578d40b19dcecc6e1ee3da34ab29013fa3af7729272962110e385ab9a022fae4146f89716f7bab9d3dc682f4fac7736d3e08973c685bbb275bbf8f217419e5cae0219eba5166a5de1b11e3f9a908b8ac7e65bcd623f8c18bb024f605dcbacda790d8362957444a95c130a37ee9d563d0cbb4cb2b0ff71591d9390b6c8fc28753a0e402d6487cfac607135927d89267512b34f877057d9271bccc024dfedccc6c32edf75c8b7551cdf80154ee8e08a0cc43044e1036bae017eb48b6502c7a9d60c8b370cf3799c464f964a69ee659501223e789a6497b63496df1ada2e808d2434fc8bb9794e5e2a20bbf4d6925cb3c5bb14842f19200905ba9354e00dc33cff5b42d4e9d9668b34e661d44bef76fefe2ed51f94423a933ac94f1523bf37823a238d616c6b17973441e35f9405a04d99eaa8f504534c8b5fa5e8e335c743bcf21f5d492b7112e00fd8642cb12bfec849df62120dbb06bfc2946a5601e25be75011c6f00c65d35f44a46af9e4f7809e5789a3a61ba0a3b213890497296c81e42e88f0ec0f5defc1f5d39ff2a48b7e3026c9e547202edc7eb738c34ad3a15d373ef82a4c1d181f285a98bd3314c2c1947c9e2c60aca51750ee7f943caf0c4e1e5c7df7291e973b1f936b73707619
+SIG: 5d2110d1d2f3edd683bdfdbea3ffa7cf5528a40b8b3d8d8c9bfd22aeac28bad471666e062f7d38ceda8bb37397a1c5c3f733b537967045706478437d4d187a0a
+
+TST: 676
+SK: aabbb2efedb599424a5f3e08f90fa8826c5c92170be501a1181fe8e8df974e0e
+PK: ce7319ef88b242420666ca697ba8501d274ec4a5dcf844596608b9dd5a8a3acd
+MSG: fcc15cc57970569e9ccfa5a778fc7aed71978a3f5624577b6f57fa3f167ea223ef31764c488d059d06531d016bcb17d544d46977aa241f8e07af4787a0810f98d766460c0841ad81b88f4d5d8164485a1258a94622c5492428d6d575943715766c2b0a865bedba167d5d340edb579c47aa32459b8fc98a79bb0bed1c960b4ccb7f2d4b5681a2a70d505b85b81e3d99672714e4eab41f3ab0ca874f417186feb69ed13fb911f49d1584758b2d18b4673edfae495e68dad513a7ac0d47b2753cb4eda78fb431f04dda8fe8030d7bb4e8dbccb969d7f580d9c1ef935d074d7a41d1f8b9dc45c9a2e4106a5529a98b95529ab0edea0b5722dd686f5a7f3cd8fb2624ab26c42df11f510a103d8a929830ad85f52124e3d5827ba60bfbcd736cb6c590ee777ead7aa2224d7ae46d257a90407247960c9cb03860aeaa7f54c1a8e11160d11bb473065e19b70721c8f072e1909d539e9ac94185904bbbfe54873754ae1ca7bced6f40561af4b505f03ac972a6f0bfa73b5f832fe23b898b2bbb0574a6662ee93b3b360da1ec7e838eb2c77c7cb7fc164f7c4627010489c858900752c92d9d75ad547167e4bdd11a07d28b651aa30f16a850e060dd2882fb820919a398e805eb63699f4ff595f991524731641ece25fb3f8e89ada501192b1eddaecbacc8b898528f2d5b3312694f5ec2dc9142e1513f777a5c833409c171633ff9fa2609d0497f5df4fbf48ef2b77d55e25519d2ee79b5fe9d8fa46000decdb4f25dfb3f2bafb19fbe2cbdac002a359a954bc69bdfe2fb36adfd9a1509f3e3a4c6b1f3f36e7cf80d583d440ff2a144643098974d71493ecb6417c0b8065bd2c21c1e34af09243fb49e9d35297eb0a52d56dd270fea6dc5c080a05599f78581e90fd8cc4cd11a505edde84b892d8953bdbb2379d33aad64658ae20607dd35b0bf3a2637d20c3f86
+SIG: a0b19cfa6c80de77bfcd321030bf8c03893e2b21ace6c6ba1ff7408e6ff07d847e6b2b688d4fd51aa932701db6402ef22322e6e9fc7e320abb4d24e1acc6cf06
+
+TST: 677
+SK: c2e074faa234e99ab20adbbeae11b8109723b708c54586df652b402c35cdd127
+PK: 5e524ece1c696e705a3514dd0082b840795a59c36a96cbc482bff5ab4ef515d1
+MSG: 31290338e46d1cc25ce99cbacc40160341b785823c823c4ab9baee3b612579f1c011716796e56e2693f6ddad43922aa7847cbb4148101651bbe62d50be90825e8eab777aa4b8026dc5385a97d3df76160191f922cdd2f07ba5f85e95f45db22928f90734ff520c44dc8fe3903b4c51cd23e064f01c829ec74fbffe25fd0d369d2765740f43856bd7398a1911ad749836160fd98d04b28ee87e111d40718b5a166f05c9a471a41566557069f7a14de988bbbf6777521fcba6dd65de4c06674a11853af83accb70fb328dd8fd6105a7df5269c9faec8d900147e928d970c36cd834bd6054f70650dface94b7629d16e3703d766ce7638d0ad1e17b77469b958d2ba2a1e631a1635efdcb006ebc6e5d8b9faf7e5fb989dc0896c561a26f3c25f055716b367138ea5da1f81dc72cff7a55afaee5839ef5aa822b2970aa18a8982163bf5eed1b677ccaac1224ff6c6cf256374780ae65803bf5c6e23c80bacd76ec3e2ddd3ab71997506448e19db198efadc9f757491f1b0972c82db29410e1e8bb67bbb23d53563b8807e5e0c2e32ee596b5b4402328f9e179e9ce856d3bd199d58de6c5c252e7a6124d81fc9eeaf23d347d2ab88917aa684450dd58303516c1a4d2bdcdde220c9ae3790f298d7d384b70c2fe258807848fc35320b578b33503b75f38a1df630bd33e6a85a4dd4df9f6e55a6e6867c73801e593e1d591db89ba9a9af0fc292e06fb515ac8a5e8e343a821335575ba48fbaae3fb12deeaaee60f4b3d317ec0a554ddd425c84932c27a7a12f29d6371510783bd75e60e2f6da20052069ed71e695a943182193cb6851a7d2fa3c666c193028015ac8b7e7daa6c5204f77a6232b88b4abffc5362fde7dec36b9d454880849283b1156339ea2e8c3b10e51bfabdf72578c726419a38542cf8649df9a0909f582debad5fd89d8c81f83d9e423e7503
+SIG: 657c3826b3483fd42ab6df869d1b77a8c4df67a6a590c7c6772969e3df3312ae0654fb83847af221935a0512291636ec0595700879ebdba8a1467c53d40c2306
+
+TST: 678
+SK: b9da4e6af07e398ab4d21752a32c8ffa9be0c310d35059fb661bd73afa97e2a8
+PK: f862803c96cc42adc8252884547230b970047b7e5da996260ccc0240ab71a6ec
+MSG: 6b95af0eebb6a08afadaa19621f76a839be80851c6dd315e8276f501995d4ce6d134df5e798ed517a2f0e62aa1d6c98c36ef14bb1e5ddfc98d5a7fcc81140a13c20d2ca0c4b40e6e6a03eed8c899f9d1f792468152199f4b95a432668947a51d7b8e104d8d1f12aacd967e08b08c41c3c8ca3feedaa5b8b63bcec0613864d953d81143ec81425bde29164a0876f23f37ac9ac9473672ce11a08bd5476f6f66d665e9ad617e34eb32ee56ffa459f20d1b9353d7821298545750c6eff3e7d4073dc3185ede0391cce0575f8ba637d800068d9d7e5403ba7038d2db77da144784f2e8ea76aedfe521e7dc6a674ede35579595993fb20d44b4052783f56c8c0bbd0440b69eabde84468dd13c671fb1bbd5cb022c2a4fcf3542d8b3bb518e5adebddc84e714b13be52c56b282b42ac0892a5459281be7160729f4112c7d99df9be5434f823a9ce0501789de1d550ad50bb18c8d89a33668270bff7b91ff118f5cd9909addde90c024a3ad713915174674f28aaa9f94a322baa543738edab4973312b5bfa12155debcee163cfe2b04ac9c122ac8a4e1bc418c14955d9610455bd945e9793b916267c9c5f9e53ac04518926ec98ecb84a4f0445dcb1236c76c3a678c69abe4e92c22971d62217201a1bdf05c04df8420a3de6a917a85e71e2b9725e77b522915d4c9946077637c2d8813f010b9491cf0eddc3d4668cc0f8bc8a683579be543934da2853a16f5715724f779819f44439e1debcaa4270d9b8594ba4c86e1063b3ce479d71a5409bef27ef4e5c1d1c96e8be13865af7bb43f09162ccbc83a2ca9e9b8a2324e6d996575eefed37ef49908185738b8eae43f8adca330c99bc66cc1fd52c530d7371c60869ce42c197dca0ad128b85f61c8758f0d542f3d3298b65e93c6e8a68fa0e9a1d5e8c5fec805b83aff4390e115eb64f3f078a0b9b66c273843fc6c
+SIG: 625e1f42c87434a25d622d80d12532806afb2509332449e696b65e1e5888508f11c4ac25f59b8d94d0bf27e4c8d1867007c408da573082dcf19d15a9d5cccb0c
+
+TST: 679
+SK: 143f7b4247d549f6b7c0917266c50f962c28a2ea24762f537aa06ad15e40b35a
+PK: c9959f90a2d5feacbae2c4c803ded5deab86987637064337aa2a0b0ddef2fd86
+MSG: e274202347a0d057a48bf2a1f6e9f6cb4256079d800374093c020cbf520e5fa27fe996ff07f33ad3b21f74ab0cd93c86475ff37cf622d3f9fa4d13bc99f013e8502b24e46cc87c47e6b2c3662b50e979a0f345b784ff21a8a4d92adc65e86e33b4dbe17f528ccdf5b4864664ba94ffdb7c7d2412b438e6e43fa9668147ee3328224d1f52a3f5b54359b4f7fef69af8f867b478f130a147bea42ed39803bcbc2557bca8c3999f1d24f0a6b03c98846011f9ec74f666417b95020eb1fb2fb88b6312e5008cff03e2d77a26aa532d1780b5077f9e8b828674455d6bc957975f7b2a50e7fd7c1612ce02362efa4c555a1eef68ec34a5c006a6da008a31d4193dc2cc647685ad3cfa3bd7c560b7aed45f0f1a3d1b5b362268de532857055ab9d1d5d858d9ae9a759a51bb9478e8f0ee93c984b576b8b4ab460280be3de205a32f1dc3d572923fb213ac1512d80eb5ad5c18944be77fc17def13a61bbd31bc71acc23d250ec5894ebc214cfec0c1b906516d32d836adc838802e8de30dd76df6e61c1bc438b68d2b025a84f211facf3f1384d2612d0faef5d17131cfe0cfe833fe950e479bc29cbe7fd6da0cce307cf0b1bd92c80e878e432f636ea0cd42480c07e8b8e57e69b2f938b78120f6af4abebf7d4b05cacd6eed854491c029755c4e66338993ed2ac25d19a0c5b40f5e32c8a8b1bce369718186c91d60edff24a8377a9969757599067dd31263a06d6a61154781f29611ab812ff82e813739646263704cd6046357a23c045e2407b7a89508259391314f2fbee49aef0855c6e5e63d912a19df15b11ece34e276dcb88bf2f2e4756358f34a0ee3952b686fcd17578a884176d34ea2916c5d9fcd00eb9e0aa9f2cf0f16e2564bfd28b6ab5968b8448f068320e4187160f8665781b1e2ed9d049e1b54a7d72720ff9d4f073051996a9db6f0c6821c424fa51d
+SIG: c1cfae58515713ea728cfa09090e8942f8df18621ba7090e3a3376c3802775a1ecaf436b184978041ebb75226f970df71d6ad353c0fb465023f9e298f64a7002
+
+TST: 680
+SK: 0d1fe9d8b9a2f04c22bbb0edea3833a0ce43339347531fdb67ed513a13d36b39
+PK: 67c49f410f4853293d0c4d39f4c1b3d6c6103c5cfe20a9a59b53932043517369
+MSG: 64217ac841fd4d6459bfc4a49b8801d6929bf19b408e8a53790ceb51ec341f9b46a351e8c2e59d887e1eaccb914231cdca1d3e5c47d166b4cdb9b58c013c59a3bd283ad10f6bd62c0f15f764ce14f3b265f537c63e73b6c4fa65e06ce1e1f4ae0d11489dd2602f95fc402b7712052abc84bdc778c19f10001b4e0d5fbe463090e83ef438fe068f3bb6fbc2c139af0678ed2a11faa1b9e49aaa4620abfc08439fbfe2c61840769e5fda2677f8e2f0a14564f9f504232a9fc0d9da471e67fbc574c3d56d2aeb937a586ed5583556308a998eb1dc476a014f5a08228dbed95a1208bc1d1f5d76b4e8d0b2434b995ad458e429ee6142a0c971768cc40c40bcb08e9603f09611474471b3859d7fd584219f02657b430e9e56955b3467ac56ff2eab22cc498489036a574120e2db769a3b21500389142c78a87d069f0e2576cafda8cddd7915a9228773d2ac9a075cb387f2a898617213b2cc5059d11941bc4fe58641e7c1750267e53e99c421cb4cf21d098ca2d1f41644f7908983eb174a23a781cf15ef38eb9116eda4123a1522f53b81fb7368e8075fb83859d2cf98d921535a709fafa9873c4a039aae682f7e6286b899257c0924016ca5bf6d3169099211a9a4a6745cdd3198f1337f60928227ce3c7d60960b53dedf011a8940f5c468207a3894bb0872b333ccdec9d5ecd911ecbbb96c9bc4bd4875320e4d3e9c02d9dc76109ec45e61d1cf5ac729f2e34a9647b95bce70b0c633171adaf0dfdb5afba4035b3cce8cb7141ad142bb7add4fc3f961d42d7203754a4e313221d487831e32947da91138ab648b5952ef6956e27aa5d2c175794bf81ef277faa6b905e14502866887d87880606e81b27af01bb263ecf2c5820585ea6ce8d8b391d86fcedadcd11fdbb566fdf147f402010fc35f5157e036146b3736c8a43359127c261f6bf0cad3bd8a34cb1509f7
+SIG: b05725e7371ed0a91ebc89f3c30baa99183763edb4ce34fe901af3731e001cc54f287118915e90365d91aca8feb1708769f9f1d6eef5aa113bee00b5efab2704
+
+TST: 681
+SK: c10b5ac6055a1ddbca28552e5c72ebd05278c92239b2fcd0c1353651a8e559a0
+PK: b2183e1b00816d29305f7468e7e45eed3fd8f23c15b305f9fda93e812d65bc27
+MSG: 3594905f9ea464615f41b87abb9d167337f29d45d97f7a1464ec9f2ee50f90f2e67339874d3f2093be9226107701ec1aab941c4e059f1bb26ce86e148d1d9f0da2a2a0f9829a364fb4f13f58b960d0f8d72323283c4490efdf57878645890ff7bc5065dad6e51dd1e5b9a5075150978b3367f1ba84e45ff1f1276c576e4bc72be8aa8e405fc2b27f8146b999845faaa0595d3cb70e5d3712ed54a0fb3e322d45380b5de3609b967b959bca5a583cc520cdcb7bcbb829aa25d7932095ecb303923c2560afc3fd7324b7b7acd089a9f00c03a73d043dc0cf0ba0d8411e2b1b18d21d2a32a726a53059140f784f7cedf2f33cec66fe4ad5cc9eaccbe4ae10036ac3523bac700a113a98b598e6df0304c6fa3212acc04c4e3c7f6687362ef86d617c6dd483f8d80cea66d1951127428a61c1e155a6850bb2afb7f91c82d73eb2b0543ee8fc1f38e1dcdb3c503ddc9ba0812456a5ce2e11d556487a646974a7bbf86e806c58c68c4269a7c9bbcac0ffef9835b33dc449a75479ecd23f6d149c1e5ea8b69208ff36e5fbd68295550318bfa0d3b1d6c1ad4270bcab0904ae53491f9b1ca502e012eed77c427d49a0962f1055125dd7b53733d8528934b5580dd5fd5bbe854978bae3d25bb4ae944e9065e8e2e07946518a6f548e36e056be824d9e02a7a3eaadd37929f58101cb1853be3d7547f58f49e38b018a748d3f19c48582abbdbe953a8a25ba9d365dea835935899c19fb0b51906aa972c5ac45e99c40b3b76e35d327e321e8ae2306a6eb3d8cb6ec2fa5399add19ea0028a01792c08e27c16cf4f85aaaae72f986b099f9ebe4ad0b25d06d3de44a8bfa52844be4a93944833ce2add51bb554b356a7dc49748dd45ae7ec9e8db426c97a25da5edd3b621e4adbde48197a3314de1c50f4d6002027dd7519dde3e15729e486955ac40d9d66876f90668c689d8ab598
+SIG: 8a9a3217fdf0643aaaa5c8fb2a88a556398859b8feefbcb48ccd88e585a167c94dbb5c0cad24d15bcabbc1edb21f02a8c457c56120a3234ac33577b9af2ddc01
+
+TST: 682
+SK: 061bddab280b0fdcb26bfd9a0fc721f68f88343b5d3983a16b6dfaa5e76969f3
+PK: 815578bba6e7070ebdeca117568bd77ebff9e14cb8bc200c32bd87db1fb37d6c
+MSG: ee76b40cd429eac7bc12839ca2f7cd31f1e0098a39c5fc19805be0331f44799e318d12571f06e2993753a3685cd2a96b2301e20024209adc5adf7479ff90c477c3695abb99bd28579dbc7831a192beed0ce17b038b20764800653af7af024e2a104ed0f3e52d4bbd3e109cf126291f49b0a21be433c1c5a2589ea572997f63d2bb3972d532be35a0471ef0573d795c072b6a8685b95e47b09ea9f475d93bf12bbd77b7d2bf5d5bddf0ae02375371d1d799ea9204be389e6a8e5deedcd49202e92df7c3e761f92ef8d79fa738d2c5bc280ed32879832ff2b026424589cdbd52d15b60f2aa3526b898849a34a85ff1c47dc6554b85ac76aa7935cbf3f7bc80ad009192a875ca209b40feb047cc446968f970da47b8cd67da7eb4e54a0e5ab20cb35bc6fb7f13307ce67eb6204a67ce9bb1d139c1b4bd5dbed58010c87bf831e6522ee182dad945804b767c4df2554f15b9e9afd2599ef258c67a22caeb92a57988006bbc72c104fac7e5413cd3d3b802c83e639eafe212a38bb7ef779af1a94ee137f6c60667bc48f27bf4a22241bc44bb6033836239bd6eaf3e2e223187841e4641b0f4e9ff8d5a41ddbeabb4138f6b585ace0fb6b53dc3c9edc0373b6047f27d835e8e246644fd832ccfe0df25c3d7da187c9fa05420d43455f2d08b571929386b59c6e0e10a35601da899b1b4dc3d95b67dd9a83818b0a318bfdda06464b4a42d3cb985f30ec97d6a2af13291155d60cec57cbd58d5cfcb35c18535e8d299b5b007590892ea949d1b137a62b39a436cd7e5b9f8d1b6938dbaa62c2268d459c6220a3e6fcbf80ba0118acd2342563fbdbc1f7c9dba7ea2c072afc8ae2128e3ebca0644ffd8163e80a1a557d9d39034ccd9dbd12c8855a6f9165b0801839cf6e07a9fba4c64d9c099e15410e290e677031b65cf7deb0079bdadc573cc056d7666d95d033a0b6bdba7ec
+SIG: b83297ccdd6d0098ebf5d132d174de1958311a766bcc4da15f864d801f38e09d613e7aa8c336302735d75be4166d73b0184b0e0bc5ef39edbccb6e0e61afeb0c
+
+TST: 683
+SK: 2cab5bf55ffa914e9ad07622190d343ec55c13cd91b388cb7500ffe06df7c180
+PK: b61e432bb97cbae388a2578a7484998e00e9ad3ddfd6cab8d3a5fc5ba04307c8
+MSG: 2c2d04dc3ad1982359ecd5bc3ee035f3498eedff6104a93c602af2179aeb2cb1f41c5cdb0a77b124f946aa8a824aa3076c2e1acfd48f68070b26276a656b4a4758ab151a6a9c41bd74e09bbd9adcce1e87a0a80d17fd92e85e4bda472c988b6bb1183b7ee59a09d80570466db90dd3749579c4eb19ab75fc152ecdcd68cd1078ef06e593c73516fa8291481a667d3f95bfeb144bab59d6ddc73a2795c1017e09536b3162e4bc58f8ead38957018cfec72badbf22819ab0b406c64730fc73fd9ee61f74187eda91ed4e7993e66884af43ef4c6bf7f7c379e8f0f63dcb8041e26b8b8292b6b6d190e4adf430fa82dd74c57385b919c446db37b5e8767e4a0c95013be89b2bc4e9fd62754a844418400968aed2dd328d7b1dc91e1a2b3009dc7ad140a0686f673168a60e88d80c520fc2dcfc56ca9d4b0c88859099230714dec83d26b4630554dcb9c4901895f78f3834b09766b67a465de8c9490065bf568339243399fdc9d5100324667c5ab28f35c00f6125638e61dab70d1eec48951de0fb3f7b23d3cd982437c63473415bef374a663296f2986b1ae9579b9ffce71ec35eeca116d194f8fba9a45a91bae27ac455db71a6b01a729d0c135fcdcbc23e504a2943c00aa42070519d9cd77ae6754f31eb46a3e5be9eeb3fc8d31ff182da9b087be3462c8459126e862909232fd5f2d89c01815957611e6ae7caa98b6053776a7715c2f93ccf030887030c56c2b8226dae2977995a6d3f1e9d7911a9c9d2a303f0e01f32338efdaf8ee63fc41b25399cffd0b35f7ee5676bd8fd3da2cbee4ae2ea9808d7e73583d99433993146674a4040f42f63d1b3135cc797a8d8f0b88573a32890696cac9439d1e15d196d9090b62b6db7e63c96472d946e668cbda1f4db889300cdcc25e84c9f3857d1d9e53241cf625f3909af1c8aaff4309f68f654b7a15b67711c5b7f9de76775
+SIG: 4cf08f4fabbd06dccbcce2a7a5941fe9afddc4d2d0bc80802e93b12cb135d3acf6511e0fe4113c5e3c5541b27d3a2150a757742ac65f95a9ce6673ff0cd21c0f
+
+TST: 684
+SK: dd7b59a33d970bef62e0e21a7b6e4c30960686f17f49afdb4a9f4e808e355c7f
+PK: 53a0e57277d9bbeecf99c4d138fd66fafcaec7bc5f567f8320800c4e584ff82e
+MSG: 75580367930518168b0a764d0958bec4fc46cf591999eb3737e42a02ea72d210daad53e54a7c2c134a6d478337d2633368548170edef0d85179f3023e1503868a6e5e2775e412ac05f0589d42a377e75aa6b8f5220a7699ae8aff01094ec469d6361d3e8f38615edcda4d2d5289acf73db6456985780c92e07f62c77a909fb6ef598822062bd572bf7058dcb835ef3443d3e47b5c603d92736dd1df26be4b9283b76e321d55ce2b638cde22577ca59c963c2479556c575ccb0d6d18c804e2eb01ff53581eb040ffd2cc46760737a74672ea6bf78058a6a0a1f5ebf56decbf94b54afb23c11d34179bf0976b4158017d407c95a401fa6f9624d77135eae8141ebea9f35d5f51b3ded995c7f70c025b094adef2b071f971155d7796d613a550d09e7f4dfc34517b3f8fa4393286a2b228017daf2e015387e13527f63661d3c13e78e90fb2955eee345739119b791f05b07c8f42a436efcad1ec5ea10f308f8e23ca98bc65a5fd9393efaafe5cdefba81058170cc5493c00cedf254097435d2e2fde55f866bb82dbdfb9154344974866359167b466caa909b91530c9c7ee8c53fa90164bbd0b1fadbdcd08127f19be5033071518d3cf10ae6bd6f9827e1206f5ec095c1986170e8d5d8e72e57d4228701df2a48c954873056cfdfbaafb10e46a0c1f144b1a0eacdd2cb66bb912ac471787dabe48353859120b03403567c415ddb88fc0d7fba4069bbfef406eed724a11abc041e8e7beb663d0dc99dcef3ac6a149007b42dd1f22a77dd52901814325172224a2778f366fb9eb02c812b842a42842561c68f2ac231c26ce9e8b19ae91ebfad3c0e9f66363a13ecd8b897a3d00a26d257648d56c6747441ca1c6ee99f08ddad25d116dfadab0383000d3d7225cf2eff7076b2adab9522292555f3193206786000d42ca34d708dc04284a94d174cc92f102efddf3148c2996916d4
+SIG: 87294d22d4ad0d0814e2d6d5faf55749e9b39803b4d4b7879e60b777c1fc41584fe15135ba1123ff5f200db35a3468dd4d58dad77bd96ee2b888a5a8b18c3204
+
+TST: 685
+SK: d880d2fb06262f57ab8778e33d16b473060978a6549cdbcd5586ba8105f5aca8
+PK: 0de486d2115faf2d547266772e430fd9727bdcace6ecbf2fe23ab60f7b5254b1
+MSG: 114743e82a0993cec9705067abd77c168b53677ede5c159fad36f06fc1a14acd77f883799ed9883f9915aea638ec1741f3f4215855fb5b07df3793bbe5b568eb3594391a9ef5727fab93e57469b37de125b1e9f2e6fe2c3d1a10ecf87b6c0a665c6d460a170eefb9bf716cd8faea9764f579ff34ebfa9c4cfb34706d8dd7c9eb1d10b2df460a46bb5789430bf449158b5824f2a3a7b918b33acf2d9ebe90216d1b7cbf4af770c5db95fc62ff3a3c385c3a8217853b7346634aaf30607288db0c483bd4c222eb332cb89dc4a217e6334a268413a390bb371aec355fbe4c736f7da75f9c887541a2b7d0dac018b6138f021e77266ddece8468452ada39f5e63d0209b9d6dabf975413256dcaa15ac14b6068e177056c7bf0f0f7c884a3402032298cd559a6312039400632327f9c0e763e52798cb177da4475e4b2405c157ca427741108d33ed0b7a3f53438ce6b725c6dd5814af51cfa45dbced557f726db130d55cde7533bc2092d6b699c2c870af282731e18d651ae85b3db4ba02853f8c87fd5e3ab69bc57b08b81f83c239ccf22e817e2ada4d0ad14487ed14612c8b0973ec0650a55f6bf9af4ae9256ad3546a3f67dd35d987ef21909a94c50f0ef0640e755b1c4e1a012af0d31766eeb5df31cd104c64eb62eb4efb139cf305769401d213f96a488d5ee7e3ce32b0192ee8f0831bfbe8fe95de956886b524d3319b73fd56dc60e9f1c72d78155a97c6f43697b20466b3e7aebd357b91696e7348f4599b34f3591eddfce2a7bd849ab16f7b43ebb16e23d6f5210efa30ab3ba8d32c40662b8662fd911544bc2458c6569ef75a9b9df6a0f6d80d658ba86b241ca19ce9a6fcf01d3daa95afb59c3d89a18b948621394327fc5e920a75f98f5e2b3d6c95fd852adf567b6d37c54d2970856a599f749e2c55dac7c23e3fb1a63bb4cc47b8b94f3d589ac4beef0aad4e6292f
+SIG: 4c00a71668d3213c29c7041c5a037edf13c6514bd0ebc880c909caff1506a45d27809fb74e6602ea2aad0f842831b74fb3d6900ccc520652da28368fd90ca30e
+
+TST: 686
+SK: 585871941cc282e333d57bbfc3d4aeda862cfa0a375030cd594b3692848c5f00
+PK: 4f343816cd48050b678d3adf70008877c9fcf5cb662cc4ad2b93864c02090707
+MSG: 651c101b3e2dfef0783ce9f61bd0a8bdc9307ac0488b9dd70cd90a7ed8f179a78935556295b91cc2b97211e3b981b8dafcb3d06b76d0b6eda7fc61945c0ee2652c5ac454256496cb82f98cc1cc92d81893b1082b31b47e6d22a2de609de4ce8d7cc4f4a152c47f410d7fc37d38ccd629a4b33e6221896081797d0753dd4faa8a8b44d6c4677166dfb4d5215446360a3c28d8f68e38ab54608b98821b83c187b5393ad874a76f4f5d729493a1fd74cc7719caea991d229c5d0c8c4c5f89d8e4345f4f52214313410b8c06b3315f45ed0c2f9138ab966aec0a645b6dba76380a539123e0f33b97f3d060394a3053581ffdef3e6d36531166b553a9dde03105c04af697d95e95217fd6dc968bf3b448d5f3a8e4f5ae7edc30ec78b1aea4f0db189a949a122138cdfb5f9693db004baed1a421dc44122f327287f727cf989fcae3cf3be3e3dd9b9f53502cf5d9fb186de791d310d122869c9fc3b695dec1607477f3e149e52b63cfdfb0d983e89af2f75a8f489843ec05c5ea5f0e721acab387c68025f20abe0d27b4ce29f4a64fb7f8e8a332873d3ed121fb493414b8cb0c00ad3ab616c5be5241471adee9f8f46974eae84a4a8ce6fabb7f5d9a6b75a7e670456fcdcd1d982e8f827a4bbb69dec7e3053dfe835b70301b7b763f0004bc906e145542f487b4dba2ed561bd1a20306236af4b36e4068e8c007b9454f8741a5f8f079ec1db8835eb6544290d6adb52a70d7675d85df4a9a1255bfd936c331fe51c0977d124b5a506d29c6eec33caa25d8eb28952d6ffb9d6e3da890382d888796d374607f6643b89e7326d9edc49a0f53bdcb8cc76ffd393a7706522d04170036ccb66330dbac9da7e6168caa88cb62181e55a7b6d521a2115e23e202ee2480b587be4501447979a8d736f9012ecf00e67b31e8104f6e7df08a9683cdc89c03a4e37ee22928d45fa19094e0d6e7b40b
+SIG: 298856e570188aefcad81bb970f076965770c26762fe29e6554dc7afcdb801723bf6c763b4ccd65f4e15d7d8ea38fcf67ea9d28590c79255c1cfeba7b5e45a00
+
+TST: 687
+SK: 0588acd4e09ba90274c8f3d1575b2bf364a776884a9aeb4103415e163ba0bf81
+PK: 3ecae697b425d87e34a1d944098e3d32e2c1ec56c3627df80ba2b8a43ddc1903
+MSG: f828f8c9dad298c5b719daa852b17e762598a70f4ecd16a2fc596eb0263899e983d44edcc7bd240cb07610600ae96aac0dfc3be387b616850899b5cf44e1767ffaca3df38158598424f8071414c704e60b422ad77377fa7f6a8c5d0ebc0235e2d43a984f3adf759eb10447f3c2f6b80d5a11ef41d3a09852c0932a1b9ac23e6f40a167de21041bec8885f9433eb80b95c9785958046cdb7bf147a79947823b4149ae0521d7e5aabc1564fa4044106e2e392e9c344457e9929376ea9b4229c6e7738fe79008d554c429396914c36387f579b46bab146f6a9510eb6f8c85551cbd84c7dc0d0b1c010ccba5963a7f39f181e44dbc98e495aa63c01059cbe6a99b07b449e7759c9af9e0f8d9054a67a348fa19d7f91ec0a4d4f2c7026c3b849259a350417fd86cab2142e4cfe3c0afbf25182a2d52bd2e0bc920e85080832b91b927b62948a67c317eb09091461d493eea5ffc47bf085582968258a3c8dd81a858270bddafe7925684a15ffb51bcfaab931afa465e3090e86be41e3547cba234b85fe7db700496a505002df3ca4eaec7b96278c7d1a77db834a91797bbb826d092aa28b49545ed3b1eda23be11a3f528b955cb0c4fa66e16e957e5704cf319e5f79cc09f2d054e6daf19e2926b11e1e413ff822ca141f7c3d385ae95dd20b346e583cfb0c229ec39cf889a5419cd37bc184ef5fb144622080a302d9d7745c451f7d88242cc26b916a3569abc7d1f216d57797a472bc621761758e840eb8e29bc8efcb7aafc7cf8f4e59330d35ee107496dec6e714b1fa4309837bb47eb3a06b4604dd20733cc0eaac2649e18c07342ef55d19b8d039591ac2869acc34b6c3c1ca3cf263ff84ca43a5f6465ba34888c109013b32bfc0d0d15f5a76cec270ab3ac9a106331312f5a0a84282c3a3d4aea1e7cf53dbf8b240bdd111c34d2a93dfd1258fe9267133f7554dcc21a8f439c165d
+SIG: a111b9706d242cd36d6e8741cbb097b9e2fffa40f43fd6f2d3d91693667332b5f2db5ee3ea20b83291b8405795b74d633d46f475ab7c47617118535b8051d907
+
+TST: 688
+SK: 7d14023eb48bbd437649a241877905a3c932f14640f29a0fb134114e8f33f582
+PK: ea5c11b4b2c5ef4ab706cca3475043c95818eb565a797e33688afeacd68adcca
+MSG: 9001db31f279be505319b8e72bde1199512980df65f0d8a9b4930467413a997b97a362b572a4b44bc940487f18b208ce6ac5c68716d3af1bcef170383b5c4b5c47e44737726f9383bc4f144768bf5cafb4e9dfe39761e6ed478971d1c70e6dab2fd0499dff9293b239d16c960261c68218b9f5b1bee690f0d240c1b3db711f9e821f0809bbeb9aaf249ccb168c67d965562d24f848516140bfd9fc050d4f20da5a1794468a9c0725ea5c669d5c630d9310e5745107dad37261b5d91e38e08512e6f373ec5dcad5ca09072907c8fb7bf3b926c3339490b3f51f7644e73ae2ec01d61be7c6526536b4ffd1ab6849fe0c2f40d3bda2a49e5550b8df979081da85168d0f71582b903677526d1f1b1511e138b684fc46aac8bd80c3def7ee8138190461807c5536125cb0e2c3d083a187c7269cb531ec3678787b32555cf04ab093c9002e7d792b4d933f2e3070f39ac8ccf8d5f5455f12109d8a8aeb4e212fad4a70b147c04a7b918460b1316376e64020859517eb7ee30c290be8b8d6f9673915256c3b04b9d9054b52338e0d360785e46a182844c5c3766aea8ed311b2d481c0b7b2114e418ed17f8debf01a83ff37517024ee9e28e0c90dce6d059ffee413d27cd62783a8b8b5016ad276e39dfd8f8f3ddfc428101818ce507f003eb58c9a5cc8b1aff05aab8f0d7f1d1f6d4b871dbced1f3d2866239752fb13f6e18034bb2b5a6635caa6ecc462e058ebe2fa651d3d0f36e20a31f765e4b958270bd825c6818aac1ad7563135aeedf14a2b6d398b6e34008401b218461820071c5af77846cb9c328190c061d5aa6e0ecde7ef5856b0e6814f833f704096df0825fa4b46dcdacfa27cd87bd7bfeff7f8cae166a3a04d437c7be716c49045c7bd3d1349627c9cbd04c15f00a696e3cffbb45af29122627e7ed33b4249913bec00f0e28aa11298cce8b649081fe3b169b4aaeaca485bda
+SIG: 31339dce23336df5b2b193522aa3dd2d4114a66af1656289c952bc11c9b210f77a54d46161f4e0c52b3013e40b9e9e8427d851325bd71c4d99353eeed751080d
+
+TST: 689
+SK: e8306bada6d55eb188d9f75c815cc914e93c9c7222391c15bbaeaf9354437935
+PK: bf2798b8e554f51e2286c3034a88e577ff23fa32a67244ea8245912e8bf46da4
+MSG: d7043809c3e3dc00b17efd52c9130b11b786f1e257b5e22f81a7faae600bbcdfd518537fe852c642359762fb75e8ad859249e6ab49ce1bb04f2492f2aac35446ba6eb03e76de3abd2d5fc7e6146843add042860a4a16b59bdd7d038378a35e1a04b1217a55710d937e2c9032232ea2cdd1d25a0bff71ef5d3e0c056b29cb92f6df692bde14dfa50e132bebd89e9f1833880b657a781e94ecb603041756e5517d4423c56fadc13e2b318088feddf3b5c83c20b46fddbba92305e48606dab748ce3848b843f4711f370c3ec7d5e19ab4c0ac1ae15aaaf23d65fecedabc08049b9e29113e5761ed9d1c62eb075cabb2674cdbe1e3a889bae4b1dd31b6a5b2ea1b8dedcc3c515edc4467c30231176cd44bec8a057951ab5cd39a9623f8af8473cd27d93302bf8aa624c9c3c5799da1dc494494ef8ff1dbe0187ea5162670b8d098c3a94919398dadf79e6c2491c444392c29cd50d57435063290842bfa0e8530faebc006d6ea7801117e0a3f019ee28fb3792235402e2f69b87a43dc227f9de316029756c3167d64a3a3f6d73160331d5a18eee5b0e6e22a663efdcc8d67af3bced041ea843a5641603ec72efd644e173d199a8c830b2ea5fec0378027c37225afcb604c4cdcf409be1c509c9a377be0d0524107c6d92b5f09a29efb7109295670bb1a1dd3ea008bb79185f09b98f020c43f1439685b96f6199311a090870f0d9b10d495cd410aa95b7e53749be3a6c0fbc729f96cf8564397b09c13514016825f72f14eb93294d7010accfd11f17a6ac8f544263d6038d5c7db29486291b30ea49b6b54cf88826dd252cd9dbb57d841b5a4cf702a3264faa4dccc86ab14daf124ef3d5335a6878d065c6ba29991045765ee5542cc9f5d9f354dcd2c6e0cf7ff3a30f649b5912d971d633578f1e9f263874d0565c247301dcbd15d76211ae2d3d506fc64deb7e042565d438e2bfb249243b7
+SIG: cc6627308e2f424383fa70594f575791600540027a2751619b283affeaebc9c9d29ac6db286dd2c1b596587b878d1df4781d436bb570c1c0f0d33368dc66520b
+
+TST: 690
+SK: 363c1ea7c32ea328a055af7bd8b3bfd204fb0bbd4bf42ffe262f3a5ebd54da55
+PK: 7a83ecca51ef6e5aa043a5ce04d9288add49a277548bd3016b693ffa79a22edc
+MSG: c41c1e1fb75954a0ae0ebc29090b9fc533e693e7c7105cfe40ef526e4e12a7405221f218c7ac019e1d4c92da2853f2d726aa62277924df0c343fc3d47cd5a99a3e279b26a1b13b1f2aa36f7ccb4b54fbef18bd87a55f1bc40ce7b2029145ee7aab391795ac68de6199f50594fc79611b85131c143021f26fa358da0c7c6a65dde076dab488675b722309e5ed9746d18a89309906a7a9df237dd27bd590ccc77c402ef6e19ca63cc86b85160330ee6e1f1f47a2ff807eefadc00963520a1c600a3e45aa7fb2554f47d897bd86d81c3b0877101222fa7850b80ce3bc06c9e58c0c96e32fec8530c9fa1e4163f0ef8456952bf6dd58045a363d61880e9ac976a3603ef77a4c395e6a07e342f6023b8af10225cff240efc0366a799fd86e9d062060d8724033bdf67588cd73ac284de4c6943cf45ee4f75f5937d97d78105f0bbece04d3dcb5e424eff89b773e5d6b4f37efa9a0654cb3ef345278a62d876cfef9a3dcdceb7081441877ebd5fa30c9d954e3684fa476a4f485d426fd3c8c32bea0f9cc20b15e8fdfc3ca4b302c074f508132d15de625c10ae0737811463dcc55fcc4014b20208fffcefa9dd452119b1652de41348f69f2c488f5cc1856d6e78a5cbe3e373dd4598e2d39f876eb94e0b01b21fa9129ef41b639f4e05e69deb1835ed44b9112a6862a5bcea072c6e1b8f0f058f46bac2a845a582d148f17760b9e0a2ba60bbbf3884af94dd4c7ec9db08e9a5bcc6dde1346442ee1f4707d1f79b69ba867f418dc279173f77adbc58ab85ea393b9dc68261900c1caa82d2f50474c42aec911314278c0affa2a6b6c36d1ff88f3b49fb2b7c339d2a7c2b3049f8c0a08d16a9e8df93d130da484bdba6dbec534cd51097a048221106bab48d67f951b7505a1484892b85779c5a3111702124d957acf2dc352ef9ba247bc80e2ce96269ce85e78b9ebda989076dd5ff73e1eb275e5d7
+SIG: 5fd1e5f9922a12f636b72a7d6217091f948a55bcb1826b8fcaf99d26416c7ab1351c10f4093ffd8a2af86914a0a98184ec7e06d2dee87fdc0f4a47f8c63cf501
+
+TST: 691
+SK: db2228ffffa9d2534aef918fb85b821ad360e2d39dec5aeb2db0df02497f9416
+PK: 6d0195777f8105ff523b79c59e3c3081fe89db6f87033f094fa5a940cef84bb4
+MSG: fc07cd99040f13e5a84f94746d6bb868f752b448b62d99593ef29e43cc8245f0470f65552d643220f6719285e15c37a6d174aef76088ccda5f88685b52dae284c65b380da345a2e1af2ed76480d269cb934b4317620b792ebb39b2a678247d6d815f2a5cb9aa560e4bf6deba4c0a0ddc82d0e5a5a65acbc478e1ec6b064d7bb7388a73f6eda30b0b6b73dd8f879263ad1a0348671dcf211cb96ed08ed52f3317da68185d6bb2589dc11d755d47a3b6f6a0386a8594d9570b2e9b0d4b5e13dccd9bb7acbef0ab276a7aebe12931be67f10de267a029895301f5662530ad8ab3d230b3b6d7093acdfbf274757a9078e20c23bc822deffa61005486102c01ab82bdc8cdcf1bb37f9b56d39e50fd5a6895416e767f4e36c1a41778908125b5ca3f92a90da9addff155fb1fd7768808a80f203ed737ef007763bd2fea9ff28c84b43551c9fc438ffc47fcfcf64dc7700613aa8b3af8633ae8b6987437c0aa4781be1e821396c536cb3005d05549b1cba70135afb7fe3068961cad3a1463cc0b5560684e27bba77aef419d823868e0cebad1f1ce0ae902744a152dd29451a17e28a89a7158a1836efce4a3e5c7d1faa4c3875bc46c4d9be22d66d366ac6f59538a00b275b02fac6da755a854081997d5d1d0e6e568a5958cf334c518cd517ab9d73c48d6cbc4ae4eea4353113e7e4a7c05920e686bf07afbfb8dd2ec4f18fa7138e57d332cd7a4228fea73bc09252f24427294ebd3645ee0996c2e851a8aa51a7cd9fc2eab47c0ab213f4f51d216091ed089e4592e9bb0828b858f84f60b93ad84a0a22827cbd27414b781322a04d3960828f638df2834c7f7839d70db126bee5af2ee7559a8ac4c01a6c391396af93fa0608940297ddf8900c5ddb466340ae51c60c7ead762447e76d8bccb573997cf6614d188a0b9a2f56eed9b0f9d463a19787f4092581a65c6bf781b93c56087e54ee1343aab
+SIG: 82189d340bc11ceaa400410e08bae9d901af059125e953786f8a043ddf11f7b2f8e3b617accd78e2939adfabf2d2471fafd6f5bc45b14075b328e34d8075b207
+
+TST: 692
+SK: 66b50f692e395eb83386e027c82ce3fdee3bd899b0d3179db086fbf524f57459
+PK: 448536e982408437ce89674053e3c589c98c095c60021a118178c6261d8810fe
+MSG: 7428a964212bcbe8df7d59e48e923480aa0ee09b910d04efb6903662efc3107ac8fdc0c5f39272740cd877e16cd71c549238c337220ce2f6b5a1fc6f7b0a1cd4ed21d93889081e34fb7fdecf4178bbd431e611e539d900c3d0ac3dc7107b36b41d6d0d5d32c19727f908b6eb367febb352a493581ff128b56c4caf6fb8e09981f0d37957d1282017fbb807614c20f465dc02b0cd969983bd5ae1ebf6578d7ff3ceff320e25562199dee934757cc1f58d5540c41aac1ce4f211f0b8ec4107174030e702bc6a8a9c85c505c9316aefea3e4372242de019b35e2bd3c5a956521971c106a3adbbc13cdc4f7f9d3c58b96a344b4ac3ef6bd8aca6ed9876b43e6497faf7fa4cf27fbcb665730c091e13aaf7e9efe7dd10e14eb19a9200424210ec8b8fba7e69444ce1a9e3a7b26c11f6b7145b6983a7805776484031bff52e81ae769b70a282b094ffb5fb5525dc1a872e207e827a2e11f4ecf7b5308c748a9278ea7bd66188194400430c8cd596ebb87221e536f6afe1f1505d6a59f41d16a2f014e1cfa513f7a69731d7bfdb2affcefe0537d42c796e3fd27e41b7ca72051bef28bb7bde7010dcfed8aa16ef676db6e520c3cef8d6f58a9a2813cff0f7041f87fbfb8431e020ede1d4eaf19e23b983445c5915b54adfb557fc20d0058f40f5e09825dba8d8f20c00f43b3aeebb6157be32ec54627d5d42ab813cf97f095d26db8036c12e82cb963e8001167e61ab393b4cca755ecea869954e323fa5262c5fda3e0be9a51e5af51fa6444824fb837cc67be537a87569c30cf0114d39a03942de4e1cd523355dab1af36080a9a9a548be1c2a7fbe5433772315d283e5156df648bee4b7dcda74f15905d542be54873c15c53ff42acabf8c56f257d764722db4e9c718e12098a3457486a6c947ac2de0af53e82cf950bb37ca29c8dadfa3646db4982af572d39b268c7f96b03ef6b653c87945f29bc5
+SIG: bd13f6362c07078922f30c6330751bf6e7cf42a76916ee653eb17accff1fbbca35258c4cbc582a5e8cc94fd2c7edeb53762f1fc23123d7f4f145409b31cd3802
+
+TST: 693
+SK: 55328be4b370822733ff3989a6a3282d65fe8f207ab7270d7c2e727ca3cfaac4
+PK: 518e02eef52f5aaebde3d108ea79ecadfc4d994ce1953621e54b7b3b121ff8ff
+MSG: 6c24c9afbbf12dcaee6f10e4089252f2c60b2ab93a02c1602fb5de4ce3bd923eb02fe1039fdc15996a446915e767dee0176dddb78e9d6bbf069675775a829dd808d376b0cf7920bf1a66e1303ba52419785f25f28bb33899ebde840c0ab14b919a6580cbaac3a805627b9c4a77baa16f825a9eac2d6d3641651493370e50eee94c74049764365605ab4dac1a030227a330aa178f2f8da377af73f0bb040bac12366e65e0591055f9f23eaca35e9688d837a3c0d99c168fd886acc922cf37a7118ef8a44bb0a4fa4288049309a7dc1bed80621e1063e3e592c0fba42d7398eb15f74028ac15d7ed65a6368a13b7f956d19547eb506ce7ec90734eb949cff1d98ce414f10adcba8c007320018750a71bd36d3b6bfd6127054508e3ef65d99848514d33d68b58e3a4b224f79b6e34dd480340467fe7f025cc88213d808fbb5b91e2e43cf9d950640798659273d47a25f1f0132f6882faadbafba28fee5fa17272c1a9001172b3ab6ff2c315f26c07734405b5ee8b5e4f08e1e3b8aea019467fb071887f191901a21c5976c1ca8aaf0a1d4a2e698e7623e9bbe9ca2a67a153a16f895e6dd9ea924441b4bd0b674552e398b8d970343a9bc776a3a3fc1a8660c5625d6081b5d87f0f8ac9f07ab5abe77cdb8e30d2fd1f6f46525c75dd0dd1ca3281cc89346fb3e6d7388ebee154cb59bd9e95ed6a41d5df668b59ea137868eb120b8a2cfdf4674414fd279699f28b5a5ccc2e2fc802a4c9e0b85b76f20f6bce2a4954886fc402670a71efd261f5dd7bca16884a287c622fd445f68d44151cc0134b229da38daaab81b5c960d57700ca92b26d0b142134ce94b7be6c18610ea2136f8ba8329a2e8c000b8f02fe05bcf72cb71f8c72535ffcd818e38e7992a8f0c32ac62177d1522ae552c60c1ee616b75e4b3442e79657e4a333c0b3d744eaf260d0c336931686a6d668c64fef440052352c2b258cfb65
+SIG: f58db19fd834e15194c3c0f8a6a50ebc4cf074e80ea2e70cdaf1e169bd51ebd0990bad77c4fa208b8dd1e2c8574c01b5f596c8dfa6bb8e6ae3a47ff412e7e209
+
+TST: 694
+SK: 7da05f04e5d38b989b83f72f7ab26c138776758f4f577e49dc73d6013ff43759
+PK: b1de5167f4d330804eec9eb565ef4055f1b64dd95e1c9b27c67ffef91482cca8
+MSG: a6a861d8947c5cd6ad0819602e32ea7681c8f73010eee553e5defbf7982098b5f7b39924bb7959ad64c30326bed560bf51e9983cda5dff4f311eea24cbe68c6106ceac9b843aa4e2ad1b6f8ae1e4f96871fc025be4a616385ff2d4b7f56829abefaf6aacbb780d6cbbc951b6e05a787f885e3325611665ecc924274aa531bc133f62c76cb3ad148f3c9579a815a14200b7648dae0b07b327d3bfccdb6fe3b6cbd70ea65e6c0cc2516a896696d07b2e77713b0bee3b92fb1b6f75b0820a5cb62c5fe6204003943e24857166fbdf571f115d45f42e75901df8b12c32618aacb0d24286c8d30396051fc272aa17f4d2d47461152aacd3faa2b7b208312278e809240592d1d1aa585c56280e66ffd92b5717d0cd1eb9fb7401def879487c374e5c530b6febf911122574d24fe104b4f45c7c601e6c917d3c1882c1ad3c555d8f2ce955b5a10db0d5a8b8ac7a6266b2e6b27ad0ee34f47ad857367d52f7096d4bacef0e46725488424b93b89acd429ffb5ef33a0b081dd09479679196023c3967f44ad41eb1a2395527fd3b79768f1b885f0429b495ab60525691be84650632a2f66cb63ad5bf2f6ae70b668c5a193f7499fc4fc42cf8cb308ce5029a5027babef55d1925ecfba9f27eb6081619ed0df8569fd80e9da104db39b5b8140bfebebd29085440065819deba8d469ae8b3ea6d3bac5891f9a4ddfb7f1f06d13c31a07ee53fb54bc97bd08696394c38e7f3680c0f02f975f469921147a409859097813b4c3fa43d174ac402f1a528cb5fc4b807518432eff33407a111ca3a3d7e9e84135abac8a8f52ea631c86d74a1c6e5749edd1491c0024e7de7fe52856829b72fd13da63a1a2343349df662ab3163536032346e5347f043fff528bf67150922fff2026bab742db9cae7cb2e3c74580719652c28447c5e2098231797ee6ef1231f5792054bc3359a32c86d2f94f85fa7d4a7419dd241ff662a
+SIG: 05f117f9bc3ea55d455e9ef135e92e7665d18070d8f5e375df67be1817ce14357a55e70166f326b77d85243227cf67d8f2e0bf8440cabfb05275b373f1e1190e
+
+TST: 695
+SK: 1b8ec65880edbf039a13e970b15aa67e192aa02ca65cff9ada17d4558f40137d
+PK: 12c1191e4de3bd44d039070153adb7b581f600e9a1dd69aa89f277c7069e76f8
+MSG: 37f18b7f64c5133479d6dae3bef679cdc21ece3f5b579a6a9c3fa2e59e9be87d2009f74e1cfdaccb1ce37d00702369bd169d94fdcf85af9fa3217d27e6ed6d1d8e5df7615e8e37ea55de1fd0b06d77b4c83b929d80586fa0694be72ec8b365ad2cbcdd2b1ad8cf7f036dfa4daa1a9036cdb120432227b1f07b8866b122120309eb914ab84cddeba1dec48ab92636728588fedb3aaad7e7dbb2ac30e63c6f5f90fc6ce62d6d3bd88b0d5aacfa61de9f3267b300917b57a48036ab20c9a05446b8767494af249e7de7bc507a2207cc956f7184555a7d5d8883bb4b3e93f2dcfc57b0da8638658dcdce885d44d9cc68b1d8170a3677cc5e50cbf33d543ebae4477d9239cf83384ec59b4233e8ff3343f06f301877729a53d420bf01c62e66ab7fe55dd87ee823a58fcb87870e1f52e879177cd439c533f5a223e5a3436fe9d6426548dacfc86a0846d3ed23ac042563e887ff46aad005f4e1dee3ee0ee4c27a7251709ae40abc5e256864e4785a4edd8b2adf1bc5b4018e28d0b175867b02d052a6e17e411a3d8beb2a4208b76cc621fd18be148e235d55aa7127706557dec053a13f1a47dfda405b3fe5bd28ef5d348619f51e595ef5055f839efaf110e4901631ac31a02f4f7ee424a3a2c3e00d2602d2cc1e492906eea420a9268238ac6622a08974e5730292e6ed510256efde667e0d9a0ff2213f54120ccd81ffaa6b7cc48141a2b729852af583d26aa51fbde67be4df14e520c2257a73c5c2e3c3d87dfb25361175fd18abd7e99aa09b85f88f19c8d82d45858f3144c5dfb7a49ede45b4efd8710592a3720636e7e889c7e22ad13b2d44bb7e2b47b2963a5fa3f2557b85bc0c693de3d22ef9464f7b814a20a4676ad26fcaa03544c6aad41283095fcd1210aa8cc029ff5a26005a891226c298e94a52aa7133913ec9d22a5b2ac0bc6f15b251d0b93889213cd1b1e5c6fd08f1a8f5cbd4215329a3
+SIG: bff269a35d6c8e552ce716d1638181ce8583b45c0ec593b4e58c40ac76e7f85ca1dafffd68541e623a1e35a7c0972688b25eed72f4da57eca16857a8263caa0b
+
+TST: 696
+SK: e75388026a6a6d6c6d199e362993a5b1044901e18a76c2fac7261a6d1c19a4f3
+PK: b9ce14251c0cdf3bddb206dc6b8b2b7f5b7e4dd1be2ce1863ff18806ae00f1ee
+MSG: b99cdc847211c06642dd111bc5e0beca53a74ffba2e3ac93afb4b0947518e8323527330a4efefbe4bafa00bafecb434ab1e5b7ce65656f7a4fd856aa6c385ed8d7bd6285580d7dd60882e69c19da076909d647de095a80e98ad89b814aadcbbf6f033c49202f656c0910503959cf97cd0fa82d5f6d22fba3389951294c4f7cdc21eb8244bd6560637a5eca62a8eba1f4a933d187a75f86711643af358831c8c16a9a0f09e253b2395e9cb371611eecdd66b4ab521aa94b3f20237eae41cd10c5e21a452d48e748187f354a67adf681b0fe61cdaec94a5eaf01269fceb570d514ff3c55ff1dba2fd2df17f86a8aeb747838113dee94a43b1384cbe133cdf6427e8d122e4e933704da6e26cfcee97fe3f629b60b91b2dd863867fa79801e2b916ec4c0fb62e07159421e657974307a1d02f7f2ed4724a8b521a861f55f35521e8b2e1a84904c428cfc5b6014bb0f8ba8434c2209bd40aca31130db97743333597d2351d5f6811741f62688973bd773d30266fd1efbd89d47a964f9d01997153d087d92696616dd103a934ccbac4c1d142f2075d4e22c3da4a0e973b23863196287b79174fa29755fc6d9b5e100ace0a45975e503b254d3f195c261710910fef106892c08bb296d230cdea9f5a11f91acaa6e7c05e92c281d2b3155fe4480b0aa5e0db41d10e05cfdefa4364051cb755dc72ffa978c00b94a5f212dc691f839b49de97e0139d65e8d73b2b289b26a12c6ccd8edc04adb452af7ff094aa901eaf57651eb1b87b833d0a09b4a4a6462f40664623769e95079f3c962850cc3b401bb0058b8475b10c862f32f300a2b143b3dea269ddcbea7be7dd2426d0d4204eb66a39f1318822dcb9c561398637f4ab8de196768ace74f348c012dd1babec17f5300ffe0d7aaaeafef7db650a8f2f309a9793f52c685c7e1d5133274915784899c481d485c9bd30e99fcdc97d96ef07487da663befe68299df
+SIG: 6d0f83d9c55d84bcf9a86147d9b6ba9ad537832fd0f99dae7e72c8139afcb30c7b24f6b292e32f9847097551b7fbfd510c84e89be98254441457bd08e5f05302
+
+TST: 697
+SK: 5b323fc01a16c45d1064667d2ea4a7ea59d20342562d12fbc598d5aa7300688e
+PK: d4141b455d301642bada2814afcb1620d5eb56d92b1185fe5dadef559625fa71
+MSG: ad24669ef55c540a8ed162ce1d28f01760a60719a0377336eb00b1ecbe6f61601cd564f92c956804f9bed4e1476b94e5ea8cca80cb49a304ef851f7f675abe58e6681dc012ad55e51b021d9828569d0bcc9e0527a3fc03c891d17a90e6337a1ea67f2f08810587693837081e4c08a3d72c536c2140da200ba456c376f61d05651f0c5f395711f41c0d6eae98c906764d1ebef3f9046cb7c8622640fcafafbfb8f62e1cd32c66ee1c55509489a538ab612999e7997b779c6422eff109da4df82920930d8d363d7830908795a3888f25d667e14d155ed44581be430f7973b574e2bc0b134cf139fb4bb01dbda41b67b98147d8012f40677f4b80ce4a534c90adeabf484b21fa994b7a175f8a8b8a4075564478ddb05024580bab038cd9eaa1dfda552fb31229429b614fa1d80c52614e84faa2217f260ff7ccea8c7b06e3d77ff874eb81fc8597e5fcdcec951b5fe64a1af86e73193a882469eb3ba3c382734b2887b419316ea448afc282478c25f7bca18429cbbffd8871177c5ecc7d8aa9a1b9ec87192d29a52539c081c3593332444cbe66872cf3d0e197292b82b0be5fcd858cd6ca48b53ee5b61641bcaaf31d819c7e1cedaf9ee6b07e09caedfb30b9204a1d4ddb70560cbe1eb0c0ec43f1d178201b290819fcdc92c63e0db60fb87dff00e512648c8958a847efc36346073f1a4f1f2317060f1c543e6f01b42485beeb56cab3bab26e6a0ca6935802c762b799159e320f36b5e83d4aca8962aa2c3c2b7a3870e9e04731f3948cf941e21d50964e5d635a35a53e299811b8cadfcb4416c57598a3fd05410910dbc0ea2c78fdb92574997d58796279eaaa78b36dcef1c9a129eeff82399a26d008ffa3bf0418ff7d39b6427f341895024d16e22a0c62a82beba2e2bac23dee18cfcd5db2397f378c5367309082c44eb43cedc15220253a62320399665f71349cc1b944f58c73a10a0bbfd4caf12891e3
+SIG: e2eff607f0227a29d582d69f3458acadd3226fceaac0abbdaed52675c51630073cd3a901707ecf05e893f2c36daaf0cc4901116946b5770dc038125f6d131b09
+
+TST: 698
+SK: be1c112f78cf13aefc5ce7e33764aca4481f9f88b018e122db9f8dac14624605
+PK: ae389936bbf6d16e3c1eeb6474298970866e12ec9c1d6aea2fd9db6b56aa59c4
+MSG: d77f9aeea0fe98ed7fb74d582a402bcb7931474b4a95d523f3fb769fb7097d2be4c6ec1052140163222553aa8f4f89e421730014ec73469720cea967f88b6a48d02a2ddc1a121fdffb8ae127738e293c4d6b1b74ad03844de6bfe821506b3a7a81d19c37a7f01ca481471219efe2a7b92c4bd2ac07743b4975696441714b84d63c549d7a6fb61f16fbcdb72b914d7882d091f9706da38c1a81a1c6a40fbec0d8e238b5d56d460e909f85479f7ad8b119f35455e34010caa7e5d01f38e301ad37e8005f6ed29e4a102db3f61d84093f78c49a9648c977bf4d5b689f71f406f8ad7b9aeb1ae22133a84ce1b278b2cdde465901b23a179d072a80879d0a24d2af197b322a07bf5d40eeab3af12117f13021dfc1681aba5c083f2596e37f1123422bbdca3b2c32cb594f56c325e0c564a1733288053459c62488925cd80e7c944db998c3c7be546bf89d7a511ccdba4b809eee0fc2873dad72b4cf3ba051289bb3f4e9925732e45ae7741058c8fd11599dd843927e3d14598bb83052d33569cfb02af0c88fa7aea4bb46841cd2ddbdf5988fcf325ff104a5dfc4a30d269d2a949730c3613bddd3673b42f6090e6a60e4a253062463a65d7e7fc0030bba769ca344bfa9ac823f58cb5cee8a5fc0ca37228de5a4d93e0ecf7f10821659a2261f7ef1596eda4e411cf3c9669d81de74547ce4bf833eb432f385ce9038fe848a8c96da7f01fd95bea06d1d747c8ae736495bba2285be5c32afea449520cfe8e1ce25f9077ed0ec0f6598a9b8f7386f15358170ccefc3d5ffb009288154de877c2409ae5fd8fef0093f1c36b3a8f547432cd0f62c4033242ad9921a8f11c00f366da9396930a80c997df429a4f5f4e45c7a6d7e02af033186757c73cbe64d2d4e78eaafe27539528035f2cfcf8eaf0a42bd25f88b2fc69e42668fae6677c9ac9091d9d15a41f3ace65d90a0229873dcf254256cca449ed4c17d5435bae4
+SIG: f5fc5acb17e9957ea304f123b650e144c9e4377283509d431da6a2bbd527beb382c9f58745a3e56dcc655bd2ebb7aeefc93edc3f20d8d3c37923031eec0cb407
+
+TST: 699
+SK: bd8523eda899b984230e328875b9672edc9fcd24ea5cc12d7b572da4be01fb7b
+PK: 02b734ebbe88c13bfa95a5d964fc7ef9d395bd6303f065dc4ee17b3ac1548b7b
+MSG: 16c216c9be9f0d4b115410bdfd1593c8e262221ab97a2a395a12198f95c30205b08962d4893118ba9ff99ab1c7a6e1f2f175191070ac945327ad6c470babf7928b07dd788c85b64b712e0aae6c0ea20281e42fd561e83e3fbac67f14000ee56d981d2a2f0b9ca00a9ea47ca2f6fc8dca1035fceb142c3f26f20e3c732207ffff11b79695bdafa415214a4499302326605cf0b8c82f2b11392ecc90cd74a7b411b6d907a3d5c130c879b7cf880f22bbd7f0e95933718e96d7d16caea9f2c39e89b13cd52266273604a96b51d6e34f706735ddd9fca44d09cd86bb7217600e0d34d416ac249f2e41bd0f4abcbd2580adae21d7eba5fa44f39d780f17eb85ccbef58fef903a280d95f8f3210789fa12e120e21b6e8cad917835bbdcc3b07e84693954e23a94f99f937ddb0d4a18d42c3ea8fca7d1ea6ed53a00246f99ea520e6405bd2aa549b06e7da722c1ba74aa1c136e8ea58baaf8d37658693f3e0b44f631dd6d08ffdf4f09189d3035a3f03468e29696ef05e02cc1aabfecbda2301b540cb0eb0a75bcce73db9273a9161a98ad898fcd6579fb7e4b3279544f2e0bd774dd1a8157daa88a70321167703c60a608a4b54216590375e597fe21aea97b52185d0e37a53b6388a707a2bc24acf94425f84f3d56bc9f7ee7412a9e1833ad55b7eae6da581698166383a2eba8b6f53920f517a5c80bd3e03faad4087e3ee8fec9a79a01c779512133d7b6e5f1dec766300dc405cc21a8c583fb73bc90cf24385b086049d3bf20c300983c0b351538dccb227a14fafd23ac4b26be81a2b120cf216fc58354f9dcbf05f66339ad6ddc2cac14677b90e247ebb6c5c229007dc60f374a06d404eb23eb1ec49907c6e881629e1867268ca6fffa59aa3ca8f6c295162b9536c2be22bbe3b72380ef11b61b357a6253100e30a586818ba003fa3ffd1fc919881c05022f94848598f217fea222507220d108a28fc7bc39a8a11c
+SIG: fcfcdb088dcbd0a51bd301e3e1561671935d8b6f719c5d92690640d3c91e775bf4054132efc05a2122fc209db3c3343233ff8aecebd52daa2b3b21eeb15fd102
+
+TST: 700
+SK: 33a85ae150bbf552f41663b21521c296d246dd6cf8195df851c695bd15f4a502
+PK: c8c9c42521008d5efff576c7e4a56083ced9a928da6fd5cf93fda572a5a2d0c0
+MSG: 937e05f2f1fdbd41731553e77cf181b5079758940aee8e92623fb1d5f07128b7d7f17e4842707a562c45ba69264c0f730a821c7db6bf82990dc651269b296c335179113053d6f85bb096b2911165fa3900cb102416487ba8078679c6b336dff38763c08dcd20fa66dda45c575df150d851165a4804973830f436df60b81319f9cfb564c0652896ed5f1849cb3354f50f0012f286e8a30c213528693474004e8504012b945560c074a6a163432cf4ac4ba7175cf26005db7199ee96d893cd1aad3fdf5d57460ef02dda6d3a140825196f3f8e2f37da36b6fdad184f2740f116de758a92917030c5fb80f0262496d2df93c7e276f25da7dbed8eb8dd4c563aba55b82af6ba3a70ca5f858b44a033cfb795604ddee746e7c8ae79d272fb9a2341a2a202df5eac08de75ad80c6580d92b169f2e1318857b1b1421c30f3dd461093de2d345ede7404b72a450de07b16eee68ce62887b6eaa436eee684be75ce0e1f96263e8d8736f9ba000d88e9e5860f328ae1e2dc73099d32fceb1bd2c0123698a49bead190a00ec9a6f87133eddd45316f65eb0d329b07b9a66bb9fe42588bf7b8d06efec1986b82a081ed3f6802e9be73464784559a4f2c097ba14b0bfd5d7e0aff65cb69abd03f8616cd7edf7ec368219edcf893e9ee71dad9f18d79e568265ddc6716223213235bb928e908dea827784cd1af396d590c81f4eacdfcf89c5cac96fa050064a22841ea715f8c89d6d5afbf597a4d005dbc6b13856d335b42a9a82edcb949835cca20b0a23de51cc3aec35566eff0c5ae1ab3751320d2c310495238eda383c38a4163152b8815690b8ff015035d1d00ea4a0d6caf324bb71a664a1bed31480784a68f438caa359e8d2673c857d4b8c0b6c695847b86800ea3d734b5ecc4d52b507ac69b3a6778916016ebc2315f44c90bf0c3e7dae01d49cbc303402bbc634ae1191f3f6fd63d303b0c0be033a47b90f8d3a77f0a44
+SIG: bbe4cd63676e26d675a191151d30db72b5b84d461eec6564af867ab41bae9931147885519ec9d7e6c818743c8ef6d5167b35b421363c09b357367fe8de443a06
+
+TST: 701
+SK: ba9e686204975c3bded4c1e9f74c7e4c7a7e3c9981d01bfca0ad0115c3f0f5c3
+PK: 4990fce6952e8b7d0afcf4bf9dba9bce1bc4815e37511da7c2ad4892581de03a
+MSG: 46bb48952ae58f2bf58f5be8df4f316b50f363ec84eed8f82ff4c04b0692d03aef26e8e1e6c9549a2247d540a6e22feb11e57f4b808a2097e8a7b6b3b7af3769e6d81d64886e6962372f4f39e49cd46c1b5f735f380f7c277d099776ed1aeaa57a359c0aa8c72f40eb91a1bf07ea157f5ddb30409d6e3af98990ce7f30affdac5e22010646dca96a540060fc908a3125b000ad1ed3a0f255cd34f15d7dd1fd681c3c35a1cd652056ecc5264d39aaf72a9bb83a551cc934887ae107afdfef063217270d9596891418bd461bba63de65be067b1b7864fe46484c7c9e96349a7c03a80fa055050aa18ace2a44b4a03c947824172b30e21011159443ca3cefaf696a7aa8f98011260c9436bf48991f41d4d507b96ce7323e531adcf66347c55c8855673a9f2ec89b5c8024460617ec7271773b36d64fc14eb5d82652c53a3031457227093d118fd8eb9384e80229041a96a6493450f97e6736263abf1ecd9e9fb9a4f0f6d667fa824151485edc37b34acf3d8c35f9c1be48b5e96a12af8e2d35c23a03580f211da6316b34c56bee872d47641bca77da640fdbbad5a9ad8ab9dc7957913da734ad37492ba4de8cf136cccdeb6ba3f1bd3f003be7263c4f2a40c33f24ca3339596e6c3428338100ebcc0722d4f50d30b33b912d4e7c1a9fe65f6658a6f239140a62c3261e10392ed1930aa917652d3bd2be4e8a08ab97e145b920abb31ee4bcd5a0d71f638180f61c245823a399a734a4dcde0997880245ed71eb9bc65e3c6fc95ab920b8024c17d44ced0037d04a133c2641782f1d622df45269b491d3fa2a1227579eaa386de3e7de7bc455c6a154eee5727fff0437a20076c5c3b0577cac5b4b6934e269380222461a60f954e48979c0671217f16f7027983034121093186c78705fc27dc92e2eda4116a6bf7d23e0548d62b67b25c41ed06192bc26ef1397bf1601f3a6e2a0e7f661fb0505ee382f27aec2805a3e2117
+SIG: c7d23a58e2fb2a8d4b8ed1e9eae91e1129c2af8bd05f0bd572abebbe0f30825925f0df71cfb7218c686e5548d9427710a690366ba85541c79101a58a10e8af0a
+
+TST: 702
+SK: 5907a8c084043875238edbdcb7832fbba4c05ea3c5f88a96f1fbf950401ec164
+PK: e2f49509d1007f618efe4f1fd67eaa6e2ab18afb2decced5a0b2ba8363789260
+MSG: 433b2478e18fad5cb81067061d225528229778307885475460fbe3137a5b44024894ddbe56fa6ed021496f0786e42bc6c2d2797ea0a6bf355e88115faa55cd92ed42133d9dcda6b9ebf63ce4a994d1a82d2a49267558be54182a6f85112bd12b247adacf1405fc7ec7a015d43ab40b82c677f7f85a0e48197c5b96576199f4c3343ff7654d523a30c43a054c3e464451278034b7f196c366768c628af94fc0ccfc9a2955f9d32338b944780f8e327085b103781868e4fb79d56122d7f3f5ab309e5d634add15da382c0d2358e647182be4de6e9a9e43e6a3a3b8215b204d9507610d461621000fb1893707af7d2595bfef8a8c5c5cd08f309a5fb55e45519aea9b84748ca5c672bfecd30d25651234a3cc319b43dfcefc1a07b55b4aca714c2e7ef9638fe7884a77b22253a01a2229500e9ce10fda73a843c19cc09626d2456c22a9c901881d521f4b15d2f613cb469d304d579223bc5ff73804df6371517ebaa5b677ea910ff1a02a26fafe48fef469ed799bed6d56ce961834a2edc2e23c0d9426eccdcc934f4c220e37815f7c334b7383607d430520946a881a08325b4164979d5e82cd8134d78cec4861c019f6de301c1b9aec52bb982033fb79b2e9731bab2968bc3f93fa5604b893c6028c204c36bb8c6b074be28c964d2849b5bb19d7e0ba24e22a204d4fda83b10131d383f10b136bd0dba39ec26af30e3ffb4dbc0c921f0cc9910715d51c81fe4c62950e855549a17cd73a09ac91e06d461518376d0fcfa123df0a837103458d9ce221808d1f9ef2edc5cd2e6823145b524894ea48526d985eefd3f60679399548e1edeadb5395b43d87044b2bfe7c6037029b346a402227eab81f333e10e77f1dbc06a211d43b82558676c2dcff9082b1dd53368df002de1329af3000b171a6914389bb80ec0c9f3e412a441b800afceb0486709adac66cafeef248839331f5d892197e25420f1e37d7c0247f669f5fcbf0
+SIG: 8c4912c0f885d76c914059505373a64bddd67dd468369ab918f23ea28e04c19177a8d461144f0a8b51d215176cb08bd65301c3c46237b61bb1498ca79d4be70e
+
+TST: 703
+SK: 6020ae273e0e0537bac881d7549d923eb1cc200d49ca65d4be635e39173df9da
+PK: daaf0e699a12a92c16e0ded3eb3450a36311824577e361f05696603300166297
+MSG: 6a8011de09aac00db16ff7e55c2de67d8c9883fcb2040dedbc1e321caba7bb036971530176d1dbbaa927520bdfccbed8840126043edc44cbb7fa3528680e5f1b5664951dc90109aea4b9c336ca043d8221a4c8d2011656bf944efd36ba0a10a4b389196055750b0e388fb52870bbec8c55198131443945c09f3aace3e6915014374073266f34887442d74f468f8d7078bba0bd814cd6dd423c97b56905587b152d1fcfba0eb9fde2112691dafaf4f921562f241b62841001834f6ce36685f82a8faa3b7afad73a5e59bf5f9e713e59163f31dbe696118af33506d2ffea3d9c1556fb152fd2b321c31757d0c3c0f60ee113edac02d67efbb303dce6fa88f7b9746ca110e6a0cd099c0831f53c55c28b6c82af446456b842b2c950a553ee2c765e9729e6b0c546bfc26bd6d42d06b2ed5d4c8cbbc75f2a3ad8129395793d979c031fce7e20b38bd89c9b624748b2013423cebada02cde2052da5664c6c6426cbfc88f84ff602e2e20df9678fbba577a4c134517ee050681151580f7c5c9787b96e55c4075a26f4f8ccffbbb6ea18de1b2cc8c4496b16042770b7ec6eb5429e7ac1891232aa4e47467f4e9a985d80547ecc4c6fd9f59763ede91671f2aa5736a5d148e3a8ffc88e61253a85b0953654958eb2d69401cbeae775f8cb8c3ca42d21693ebe298838df94c1d77b126a1205cc47d50d5367b6f276ec8db6b95324a31e8fd2ed2e43420c4ad02ea277dd948a55193d0f0b4d1cf28386c725975ce5c12d2a6f35673cc22a0694cca4daf6afbfd326d88c1850f834c42ff0e292ba4f13e5ef0774a596d33904c0262d31df2c584a0a4f453f6ae4a88a275f7de79c13ae1a73115be02f425c6f177a1ec4639c42a792809a2b0919ebd321e316001d5b2f84894fcebd50a1dcf44d702b924532fc0e4d3f9ff8486c0ed180eecc3e09e2272a94dc7d24a4e87a931fe2495cbf992c0aae9201e0796298f9363dbac475e8ed
+SIG: b1ba88fed7e5f4b757f3fa4d1ed9b19e498e5d2f5e6cd46e426fe8f039882f1be77ac9e5a9265cbf7e3cd2a9e9926c18199143798da5be47a4086440496ba00f
+
+TST: 704
+SK: 932a200ecee7223f24146283a4048c67a6a2d2fc4ba0f9248bdffd82c6cce3cb
+PK: ec9bfb7a6d04e726fc1ea0c424610dcb7967bf15d6d6626858d411198d40e239
+MSG: df953207048213afb8e2af452c889a21ca136a68c929bdc824f9a89ac596dcb90019a46fb682bcfd962fccb27d00baf8eccaf9d9a7d8183cabd7dfa506f7bafb4935ab045931ff8faeb71631f9ed6bb8f8473ad6290d7cf519db310a4442c461118f67d1a6d103bae6f2697c94b7426d9e02e3cb9522fd0b44aef600c962feff5873d98c2790887b8e88d160824f1bba22017639f8dce68f743480deea1f92aa1fd4135dd06457a60f36b7d7f517d40c94c0dddc2e465847d909b9f68245ff2b421d5919001aae5aef24e02c002da907e8605f160ea6096b580b75cea022d402f7f5fdc464f87f78c7906a01e8e48fb5b35174612b48ac8bc750e0f3aeb0a12f7dfc09b0842c1780a5fd9c54afb9399b9408baaccda20afbe3d682248d7bf1efdef4905a319b0ffb108b753b71cc97e9e21ec9b3dd28cee039d9418a1135f0add092aa66312ea2913300d1cc8916524302bd3d1b09e6b29c6857cbdc56ef4b3f35d8ee677208effa846fdb066b05eb717b4d45120cab72a7db7a7ca846e87b16b69047eb76d8f18da8e1399ec0a8c9c328cbe60e0bf42044d2ebf2818b3c047588452fcd2b3efc1e1009ae07688727db8fb6df2a2fe75d1cf22f32bac09c82a6a3d7eed7d00508cbe5b72460ecfcdd3ee911efe5898dbd8e4ce8591326dd1522f9d255da861bf9eb2a1d5725d7d5d427340341945e7bca8cf2ff8a997450953e77d203683e4b0dafc330e05672d2ecd13a3f442df137044e0f556ffbceffea26cbae26cba6f2568cf39f908489e1a92e76afbf297995da4b2cb1abc9ee1fe4dca5aa838b2fbdc109e89bef3ce5a36e5b2f712ac4c889438248fa5a2150cac6c977b5e0543f4010b7314732fd18e7fd5982e83276519e78725e5a5eeb86f4892084ae52da3849c228c809edbf69a2cc47c478d18719f111d737887c7a2eb3250898db34e5e5076fab9f4a9e6e1929a3480836dea07ba4d63fcefce5543430a8
+SIG: cd1e4bdf4a3e4a31d65254333c8cc4087e4cc40b02e2a347d09a3dde698490c087d7109ad0209c53e987589cbf3ce26412a2b02cb8a3bc93fec75ab5d2c38703
+
+TST: 705
+SK: 5c483e837eb01ed5a4ad5db3792699824df13e576be967d12115c85e0286e628
+PK: fe1aa8b069da56e676ef3a57d9bba88305ea032808ee635273b37c5c635def4e
+MSG: 58d5e2cd899ba985378b3ec33e9a869822b23d5d896a28f424fcd6e4cc28b80d4aaf2de804367efdf5e423b1234d821d63ac05eaed12c73e8e3608af0ddccc8386b7d842b12e60d30cede32553945e7829e9b23f5ccc2e7103a08f2cdd9e75a7b36f5e63720ef0d49b2592bef3740268c89c86a6cbdfe201de0db9985ceb19399c9a1d5bb0586af3c8cdf2713299eb0443a541a47384607243c54a05915058367d3f2db380ed317a8c12c7a63e809c2e84d4acb9d9eef54c6f5af7ab59cb9168b1068f9d2ccd978fe721bad68a669ffedea3e92c76b32e3166658ee3bd0deb1b084194ce35d9a741c57fc2241e68efaa65320b23a1dd19ea8b7ec81e76f1e9163f9592eeee5af8eced0272f33512d0d4ca067f05551b265396e10014783cacac79437b19842de6ab91b9d923bbeb503325bc54869f663e6ea4ae6897701be7e11d16cdfae0eee861862000e7a4160781547e42526af51ba9698d234aaf510da81a0dbf264366153d7a6d5eb3fb08b9bb5ea065c2f5e5b6bb679d2e210b5b40e2bc82f78dc9ab5824b74aadadd89bf8a8b73a0a2f43ac748378921a73a252704a4adbf740cb99c1e1594c37ac9acc19f52315c6a846a57b36128c64d767af44e9c86305bf18ba7cd52680523a3b102fba6fe55567069d2047cbdd9605ea12c8877d399c1e66e33817731f50b84f817d1f0760a40f97468618934105eb00ec50c76db3c53fcf43fe1702907d9a756bcf439f8831d0bfac92e7058fb157be3e591d37eb34165e3c6fc60e72294c083e477626f9001c1d737c290377dfa58ea4ead3028fc762ce8a3afec2e6e132c662df6034ab554f93efac657ad34f6107d347fc5c5e53f3733e178b76014d2f9bbd06ef2dfe60e2083d8865f7f5b2acc025d912e5cf6cda6e798143e9dbbc70a0211d8e4003d78b383d66a6ad29717ca24eddef7df7cd3a7ef652aba5487afe5d026c9b102807294eb27d9824eeb6b40f083de7
+SIG: c17c2fbf8c00bcea3035bf0a62d30229db742cab1199677c7eb4eb0ef5c7b51ad487a4971b631e794a58bb0823cc0fe62610fda6a9e03f8c4c3381cb154cef0b
+
+TST: 706
+SK: b0d0abdd8444e10f293754ac9f16e31bdcdd97b7067128aae8e4d7f11289e2cd
+PK: 1c78cc01bea15352b63c5697f1cfe12ffdd16ddc1d59e77951b6e9408ee228ad
+MSG: aa276cc543fcc62d70a704608d98ce51b645b5c24a640a5df10a5591417d108926df3f0ce1b921033309eb8d8659f489fd6f79aa1bf4882d72ac69cc58d3bce0fa89b16411e9753eb40c6c4d598dc8f4abb0bc48f1370371326c9a86bbc2ac6214478e78a38408bddafaa9592600c49a129c05392f8a7d642b49137a20f3fe9f11ee17cfa3afd2af71565e9c40080b60cd0dbc378eda062c7cbc7fe972bde4509a1de95f14df482f48aacc463cd594f66d648d3794738ad6ab496e2da50b0db2ba7b659185e4587f182e833de750faacddf21af5e0cf4c9af385b04f7be231498ad0b742d5a87c06115db230973a51427f202fa39afb9828b5f03fa327cbd52dfec66d71ea319865dcf6810f1858472d8bea3e447adfb4b60758e86b48133709732d2bcf51c76caa847b6537fcb05bb8c87dc5e9fb022b3260c1d71b149859c9663dbdae6a7bbfd6deb9d123809c241401af10719cf91a6bed16084c444607359ed8f018db111511892b46bdac6c9c613841ded886b9dec06c01e80487e48fbe778e9e97508ffda0577853aabdcaca8b0bab6ce41557aab9631c96d60977e35718b60595273fdba140f5500a8d3576f5a9fc8f3ca4c02c167af2e03d25750b42adb03b1417f2b6d219be5f8429331a26a449b5d4db2b1a09152eea2b25d2df7ef6fe0a32e25fae79360a9aee1511fda8064550937a7130971930c673bb358e5f55951f50b146d85d383f3e01c151ece6c06d836701253280fdcff4e139d3319ab2e2ca71bcc3fa0faf7c702c9c604e5651de4af5700e9ede7258b9bc148d5595cd34170e3e5cf292828390908fda961f2230ac0b8cac64739732706ce2d5e59abd6d5e207bdafea74d28d7a758f2200e4e00a0bcf0306a3cabda47024fabeae488ab5c323715cf3ca7720af9ebbf8582e1158a099d736b569b9d40295817ea2554068bef32442c111ec814c6ed415919ba73526334df30bac666084e5601c2281c
+SIG: 64408bdd2d0fc892a5b62b5acf8e3b3c73c0b5c4fa2a72e39dd608d4937f9332f73e14d08badc6270114d1f1a556cc6ee8488abb907f79ae175c352e9f11ee05
+
+TST: 707
+SK: 498497fdcc6a105891e023ff32d75f7c3748d8c52d87dd3b2775aefd8160a143
+PK: 2d79ae9cee4ac6275b05749c438ebe552b413d873cc07f14f5fa130177214c54
+MSG: be38bc8cdf46190e304ab53dd29c2bc40954fd4c6d2bb990f93b2b5c691fdf0527c260f5066187f2d0f31f43a08b360ea1ed8200651764b8fa49595a1594109e496759ab6623fa33378d800e6117e079e13fe85c81b63ebe247b3df6c1584bc7cffbdfa45f2a2ce7c237aaafef8cbca70bcabce0b847d551f46a7d15ce2a0d3d545abacc5930010c53648887d476e0d13a34fc1c54df09d106ed758deedc761d557a73b2bcdddefba4ed005997b19279b9d2de37d041fe013eef05a2e11c9a234e87cc0e16c0c6da42aaa5bf996417bf64e5b785d67dc32547c1f052178d694cf20f1698589e7ed49be29dd59fd5c01ba1d9f5fb06a75895b7b1e15895097ebde84cad6303aa0a86dbc324747d97245d70c5203be01b06cbde06ae037204d23730cd696189f7ac267cf202179929ce5410e0e3ade513d2201bfd20fefa40b4476f27bf907c762eb7262a5be13cfc047a846d20a9f2311b6469b06ab545f0ec9fc446ea250cd3b73a7b6b960c10ca4c2d6c64a156a18c9fb810e49afd0c36daab8b8b856643a4ccafa9ad886e91e544535b8edda27c90c06ab6bcc53628be18d7d6369ca1801f91c2e0b95f36d702f77234b4100719c059951e45b1f916983934e32b4d4d8f29c0a373f8d8f0918b967865cd0e4beca01327c99d5fded4c1a69ac2d4d9b78ffb8305670021040250cc27737e75df75760fec8b8d30b245654f3c12f1f7cea0bce78ab3693578af3ea61ffccdf9baf7c3ea65b88fc854128126476796892c663bd14518c9918629a1095f614e0492446c3d84b16ec94f7ecadaeb6b659bbb4867b579061714fd5bb0faa4ad6be0ffb3888bea447e4e3438c8f0eae644fbd45a3802dc40ec451b212bd592dacd4da96686dc8b2024257f25e9c830bff795eee85d87a090c1a42321e710555764ed8257c9415c7f224b537558cefdc615129f28350267c01ba0403e07f5c6067f91c85a2c50c866dc4388af38d2160203
+SIG: b0a36a2c934756348eb47c25a32c3f2a5ddbd58fcc72a08c3cead1a2d900335c3001e35bfe1f3fb5a555009ba8e96874494b97e8b09700edcb1f2584b9d0fe03
+
+TST: 708
+SK: d962a6719e5cc7724ca4a1d559536812b4e22aa7bcb13e4fb1722d28e045217c
+PK: a944592dbc7d77039d720256c3fd340d34db892ab13e4812d662e2840c28b6d0
+MSG: a6aa7a190d003ab175332b8f58e7caeb690854d9db56dbb6957b3fb654e2e0da991f3154214204135df1e1104317c9e3c58eedff1fc61aba57744c0c7ef486000a70b2c142ebaddc07ab065e2a855daf198a6803ac24ef3724487c1351ddeda0513913457d76860d78a9b6bc3dba66c40e5fc349a873ad6065ce7d7fdc2cc483b3aefbf2f03dd669bd9cb8f63cee47785cacb09d872c9aeb83e9868405254324037982e08613455d9521d88ea2fda020be730cfc8c07cb0b37614ccba2fa3ec498b815bb5adb996e848b38c015a6a5c752ebdac7b9eed8b69619d8c846b66f7816d1df1ebc21071cef0b251e2eab59827f6d6055084370fd27c203e86a189f1ee11e8403abdcbd1f45341a820525d8637dc484a5185d6551cb882a96b9981a5f1a821f27b656fff90e7f69bf286f752f970ffca5c53e0850b20b94f9431627094acea912a880b749a6f80bb206ccaa746fa70c833c9f323089ce0558c9dc200d5739d1e499634f2c16e54b7f6d7819c47071b60bd54dd0f273a319750fd3c510a49ab56f630c7ce6d8023d97862346859bc0b4d605224969708903760301409c60ab25175611f0be98b23a8cd8ac535e3513bc77e1452193dadf4435e63c3629b666a5ea4c4bad36eacad2601404eabd8d9a07956ec2b4b7bb6336ed75b8df8f16de42c0fcae93652e3c407cbd45e8d413ef51e8542df62512ee793e41358a1de19246c6586b3c1407410421f6e865c75a9f4a6a4788f84a9c781d8f8024bfdbe25bdc7d4b69cbaa7719628c0b07ec2c4a234fff4ac3d4935b9ce4c8a16947abe7951ff8d9ac9215e338fa0fe9124176d17bac1e05592c439868ae5a4f75fd1ea82aa454c20a939deda729a0e19646cebd822049c825c7e31c6efad45e306f2d9f0569e0717331f48004c26ebfe68f3843e90f8067032d21e786c8539e01be3ceac5954a0546c84b734d999456a7c45f8cebaa478e548007f9d3af836f754de4123f2f
+SIG: dfb9b635ac0edf83b7b59d0b8409af475f66fc9946af0b7c63ab8cf5929d4701a1bf66959cde62fbcf59a48ab3bbaf0b9a61b6e00b2181eb934282070a5d5300
+
+TST: 709
+SK: e1d1416518921d07c8c39e2973d8ea1249caa8bf659cc36c7937f84ece7ad4fc
+PK: 48bdcc3f1a5b8058ed9a32ef1cc48cf7a8ab76a6e4519e5a82855241ad6fff8a
+MSG: 3d263de1ab91e8dd7b317f7a27fb60a6e1838c0c793b03abbe7082b6bda0c7c46062262192c88b65c026c174584d29649710429ae44a46140b4c82c8a0b74d56a004f8e2f5c18f84f0464153772f8312633fc6ad28a7d9fb55f7d78cd6488ca58117eaf923fa28875e2b3189893185aa3ccd044d3f110e2e7cabdf6f814b9fdd6733bd5f307a87bc73b6250d5883936deb1db0e0af1be7ab329b5c6bd935bd8f8dc888f0d1c464edbc023cbc080753ee8f799f1072bad1144dfaa615a59e2aedc662e83cb1f8e52096a7ee483bf873b25a0c04c1851a0e87375063aa1a94fa835c052640366b79f735d3286197ab32ebdb5123f6b47ad3f442c44c530a68f8512759e9cf386fba07b8064bc8fe83e245495ec45f8938f8259dc8016205f78d3954442ec1b445d83d95ad1805a5e0e8b3d56b870a20da18d74f26f550a9c7534a4144dcbc1c3cdbbe470cc153905043088facf1d303559de41e96c0ab409bb36dcf38cc9038a6a4908dea82a653195c16f290a7c3ac487636cc5bcb18d15a14ac624c70b6f6462bf249e000cee924018bdf7dde39114cb4f652e122e8744da28b0589e1284d70d9f106de16d073648080e6437ff384e68177d5cb718e2ce3f17ba1e990ae3ce940660130e93750b82e2fb41aa369774568d7cf286725e3c58f63e73f8697aeecc717c5cf1af7ad74f446292c905d84e22b23d4e0d2604bff48fefc40c6204b5e34c042292e53bec9360159a5cd97b2df5786b8f5a292c0b39d14a870a4588e67bd12b2c2f7a4408462851d2aa787971d9315190f42cc588af0d2dcd91f31bb715e9250f1192814f7b8a21fef4517b0cf8bb8a1a1a5f500ee219dfb46132efe8e90bc49093a5559f9681b4fb59e5ba9ef3f05d34eed034c14d77ee95ebd76ffa5af0befcba18fdf932af4854510b75db00a7257b234887d49607dfd16180db516c7a20ccfcaeda6aedfb6a2377fbf31e67b517655db73ca29e118624d6080
+SIG: 4232d2a481084d1196db62f22dc74cf2eaf2db0df05ad7cdde67bfc29bff56cde019ac9f03d81f1827eb1e3b0abe0204ca7f77fa874ab5268354ff08bb7f4800
+
+TST: 710
+SK: 2bf74f004d7d0af73a83ea208cc206723d188f4cf607bcad4b6980268ff21fa7
+PK: 8fdcd99352438beb52f0d1742bae71844512dd0685aaf1c909e38fc4b5aab6cc
+MSG: 898e4303ea5bebd200a5f7562be5f5032640a3f5ccfa764292045a1a368d02aa591077d8f304f74dbdfc280734454ed8c2727aff392c108c526e527e672c5397b2d77c01f7741ef8dcc2510ee841b59dd10f4e1d3ac501af7cbdb85ba31129c262fde1a0c8bc83d6ff944b6bae3fa7fb62587c681d8e342965c5705fd1a6ab39e5a0770ee7798d9fb6c0018a514d53af848db6047cd02db352d5563b53662373b971935a1ac2b7b6361dac6748771813f7749316694961b940ff3805811a49fa27a9ba457ad28848c697050e0188d0773e17fb52194e190a7872a398f31c0f0ae06537a273ffb50c2c816445ab882811922c0621556c46a3a0ec40bfedb411e90b6db1ddd4bbebb57d10df566a63d726a33308514ce3b499d5e526c22b956d8b99913dcb13e437e947b666c41c54d8b3ae2356647e8017ab678386c927219ae7bddc0d821265f9dc4ff3f8ce5be60f8e9defc5ca335068ee29fe8304917b788784a2388a320192f9325d0e6cfffea21e6eaa29e7707f63a9ea4fbb2558e3d0835bab1f52361037ae59e503ee96b9d708a47a3ae4bad113e2a460a269ccf25a0003cb3e68a551864e59840914791126f954788b25b5af5aaf586ebb87fa5f377b4d7d7f84c000dd2cb440e214d38d5ecf70f20e9881828edaa1dbec37093db960686ca123f1ecba6336b37f46cf765be2814b9e6705bc9d6a49318118c7529b37c84ec88d58a8453dcb692c9a36016b948ebe6fb2c1d0adf5f198ee3097a6ff0b8eebbad8b0769330b18689516bc0fe668b0d05e3a584fcf89c49db501d61c2def7ed3722070193a5b683c5087ef274ce6a193dd4a303536c67934b4660a841ee1b446a6892b14d0b0aa3e98fdffd43c797add36583f74c94d0e2d68e2de818d9af200598f0b2beae169c8dfbc4d397e6d1ceb6daa6c9f6bbf4f8311ba26ffb194d44216c51305267074e856a1d6e922780f4798e2f220223fff1dc370c8e34514aba42df51
+SIG: 3eb5b339e191a3b6168545da5fb0ca9be209043919b9c70a07b4a7a3bf64b102f6ffd6d2b02559dc681ed3b9c82297b201dc25c4973880e155e13a29426eb40d
+
+TST: 711
+SK: f5f7d5b73c5a65301b5b4c6710ed12c16e7903177db792ca715e23389d05d83e
+PK: 7c4762e979f0c7e207be1843e2666aca27ea89bff5b61d573c985fc7025e1e28
+MSG: 7c9318d56e63f16535436fa45afe278e74e61881bb468997d0418bc720b630dadb8128b4b65ca6e921e501813df9fe03b4ef0aae8035dd08c5f820ce5df12ee118d9c36d3b151a52c3f96ae1ca4c82fd19da669ddba94febf8eac8c42b447babc8a60b36e803624f7d2047bd8d8a153687f10dc1ca82100b7c87d32370ec8f2671ed7d067cc80587cab8db3a71ce5e406327f763ec1b3c166770a75536630c815fd8267582d1b5051f0f821c02150b2eef349b50590314aa2570793fa64a76ed2ed83d2ba1f9b9f1163154612b49a64ad8d5573c25b1cd37c41a44e3df78f1053d90b068f0d37ae00c4a32b1a3ff874c41da4a7043392f18efe5518d76e88b41ced69e6f4c014f06ebc5146e61e82fae1c49c37c394fea34199ab86c11a4467a374e40255a05d426971430d56cdba25a21ad779cc7f62d22cd87b60f0891bd856a517e14b72a9ac7672e4e8fb374a9758ab0c4e5964aae03228973f173a5d42aef9db33736c3e18d8eec204a1a17b9d04593dea4d804cbc81b9ac5458050495539999a9985487e7ca11c37582ef85c841e8f065ea98fdd6b1c60dea1ec2883521568856a6ebb2749f2072eb43448be0705ed477cf4b2004865217de5fadbe2a0f9d6b84b3fe7f7bf6c77537496246ec796b8ef2c04f68ab5b14fce0c6d287b836227d9f08fa0ee19722f6798a5d8280d107cfc1bd592d9ddc724ea86fc39dc94a394019e3a3de9e0d1c735e862de2bb9525b5fb4bd121212bfaff9ff586ac3c75c5ace746d9ca307f795ff2697f2b41a6346ed23397eb38898691e6f66841637d0ab0d968309e0194002309015416e74472fe32425d45f07c7711918b1e5790f572ce4441042d426033792297b5f81e0809bd9691f0a505e3259fc03c9ff107eb9b48795f49fb09c1bab5659d39ffecbdcc403e3803dc012438c2fb36f683015c5df0482cb7d7fc5757364a0a3c10d0e1259c01fcc4dd5494b5290a694aea3f6fae547ac576f
+SIG: 58fb392f82d5e52ff072cc77efe048f2235250c71125ee821c5f3b393bcf2fa46be4c5d8caf13cb519efe0c2fad9ee231ae9b6fd1fd509c98c69c2d36c753e0e
+
+TST: 712
+SK: 43d4be6de9cb00898e99ddcc2e1530110fa2cbc4376c485e9ca57fd65586d8a3
+PK: 3632ad389be2fab3fba0d804bf6345cd322eddd6a75d8c37fd4b5ba1c9c25e8f
+MSG: d9d55dab0fa6da76b68e841c24d971bac1f79af513d834e426a5d08114ce8b54ce8b7afe016b0fad03ee7450c6c3097173681a4b2eb9f9c179a88e7cc36813f2f5d15f7998afa9fd4e546c73bb42e7f9522be6afabca8c7b64fed0e292e4375f3e1e5fd9fcb539f4e5e543fb6a11a0df321e70084aaabb70a9950ceee3d879c386efca1e59c3cb7c45b560095e7af00ff52f8a1aaa9ccf092f0bb806d97610742ac582a3abbeddf39f49d229d32a1186d021518d74728d13d962635d63baa6743b126bf458fa2ac756fbf88096c8d3340c622390534a743f1864d54deab5e5536372ce5ac93762287414eae158a76bf81df5417cf4c047be3ac1475c517ebd3ac1d1d1bdda11b3f99c18173e030acd51d2b5cf79516509415405077511bdd9cbe17d04f47805e98d0d145e60a5d0e0f453cd9b5c1a24f12b75e8cc34d5e00691ffacbff788fea834d9d779c1e610294dce19170d28160cff909bea5a0aa749401740ea3af51e48b27c2b09f025444276c188c0671a6da94b43d1e525e6a4a8a1a73dfedf12401846ba43068a04092b12912270d2b60df6099779756b8bbb49ece82d55f0f8db1b80fb4b59bba860bd18c75d6c834d69442ae0314cf2399f5392a3c6728c63e5c516c4222aac60f916dd63d1d0517e8eb10bd0e15eb90614deb296403ad15b8c12b9e971ef2f01e59fc35d90c55a8e20e9437dd434b26d5c2c6ec2d53acec17e81e47831dc2de82183d713b59a4d1f46969ddcddaf27f44e5a311aaac39c3d5a97bc90cad712f46f85e6c8fbf5d58d8bc3ec27d310a9eaf2c369cb00649770390a3f988f362efc155f56a146a62650547e9153250701eead1bd01c89462272dfaf0a431af4bd7c3db451ada603233fdad3aa8999aa21e2d3a43b0b56fc6a9124d33598b3737f4e5cb258beda756ad2e17d0691d15d416bb7cb07ec8d8c7af5de80e5b9394e320c4c6e43efaae684ad00f6dd20a8750e959c2f04206fc023aa190c
+SIG: 86ae9325f80b9886c8381f96a18c2120e6db016a0d6ca282ed93ba9b61caec02de88efca8b8e916a4b16a58525a2f68d21e5fbe67db4c4d6209595c4abc32b09
+
+TST: 713
+SK: 7d010d760f24e5a2de34089c9fdb19c33b155b0a37ca455a5e5b1dae7a073176
+PK: 4c877b3c4971fbb551166e214d1c7624c52277903c59a562a80b91a85483fb47
+MSG: 86e2115572bf4c013e6b4b04d0b03e606ee70d929cb8ec36f4e2f355db3b5e1573d658d17bb1a310c16989a16b9558922ee493f359042103c4dc1b40dff7709901fd5830133f42c4651eca008b499ee4f84cd4ec1edaa78256edb62f24021a0076256919e4e2ce0a5a20f921c278cc299159644b5e3a3bbd089dcbbebad3766aea77e9f08ee5f7d4c19d8170bc3de1ba779a769914f965dbde2b61bad214c508186041f76c25be957656f5cfb7334eb838a3cfbc55cfbab67adf1552619941b835cd3e34103b18b49131e82096f05f570b899804bab8b6cbaddbbc02f9f3b559736d99ca7b02d3268fa273996fcf0571977d1cc3008c4ef848970ee350b158c47ec277add4742fa2bcbea9bd5549c7bca038020ece68f188c1ea3a62dd9a073d4c138ca8a9ac0408dcfd46e36bdff73988a58b9617caa08bd41bf3e812e7824f0f7e8146a444f36bf53a1cd892039ccd335f5a2e79745eac96148c2a299947f1b2e328a3789bf13c6d73506f3bdc68ea48abf002270fe4ee9ef9ed6b10c2fbb4ff1275b9d7dd35d8a52e371758574cb466c57b5abc242976befc8d98a0131b9bb846b219e4669186a83c056cd8080661de16b51ce5767b22e9a93242bf8d3205c66a673ce783d1c0d37b6300fbf0d6127940f88f1819c450dcc90543ed794f1fd44e6539febaf19a4cc98870014d7ccad74d1876a123ecd145516c743b4bba62d821ca9a7951e0dfb23f38d9e3a365fd8322f2ee4799e9ff11e1c5c30b55a355c8a5deea81a545e34705ab56d17b1fa06ed76415556702f364808246f863c319f75cdf6bd748438d1a2eaf4206c560bfafc235679ad6049c1a01526fcb9a3ce1b1d39be4df18b15fa0ea55272b17ebdedf6c30498a8a14f2042be1c2cdb09e9ef3846d6659a9f6d673df9afb7eded04b793d9731f0accc41468dc1f3236c99acadee6239c361b8bd7e2d0cfe8bb7c06687e08e76b71ad57a036179f291d096ae2fa0818ef4bf4866
+SIG: 5570613879ae22778bd54f14fb6e8c0256a71f3d79c3e5cd8e41aea8cf773e24d29f1f1b24f8c80d2949e8201465dbde8940b1fab6483b085d418e251014200c
+
+TST: 714
+SK: aaaabb7ce4fffe4dc35747baea2bc5f050bef06ee0c1fd632a067fece1ef4fb5
+PK: 820a2442d5f45f3c791478e098fb3b068da52ec4e8dadec85065c35659f437e0
+MSG: f9d28597a3e2b64ba327ac5cd29f081e74bf461b2eb2d3cfd9d5e92158d21d1d2a47ab50981cb19fe3f8c6fe488249b1c49fb897a0fe21ab5404414fd914875c220f1cbc12f5c38cfba79f7ac303a5231a372b02fad6c8462f8cc49f0f64965b651dccef0bb9608215090849177be47b2d3072944d36e856da185c7b3a689f7edef988338e0963ed31a6b0a80d5cb0b1cccf6f394837aa6f8b2f3da5efbdf4d360d4bf4dd708ce6445587d942b79761ce951b1bb4d9050703618a6d930a80c69576fc4af306a2a56dbd884a05a1e4e9f3136cd0b55ae474bb5d3d0fbc9b0339cec344fdd085c1928101481c68794f5c890137108cea791d21f81683d3e1a9eec66ace5c014d89e69808e5fa83d3812ee680f5a9971681b8adcd4a16e9a4c165b5ef9932c5ed825237fd5037bcbefe4cb11564fa707c8a93290751414891b1edd3313c65f8b91c2e925a3c12a9d3aa45fd5a667b78393c3e39df88a8f0d1148b5311e3d87c4a92e0a3fb915bc90d5558d05b475a8834778aa943ea39b8eaa95ad1832e5916ea3102d7de0b836cde8f3759dbb3b9d56ea817b3e49c983210277c2c7c5b0db187422532fca98a28b3b659c6b815ac126fadbe2f400c73e9d2dedcbbd2d3a365ffad7e666c896e31e61b384ed3a9fcf1290538df11b9474c6281cc592c71c8808868b4292c17ece6b3edf5e3542a70b911593e93f35ecd9729bd8880a24eaf41fbc6574dfe167ec2d0e7ab3df5ec34b8b55d548ab93738a2eeaf21c884c5c8551db2edf2b049f1a2a84fa72ac8978a4c27809f209c1b2195aff504f699856cc4f22d44ebdd0fe50374468d0b1792e574b5110a1f4cd0e221e824a78ddc4845feb46d66d633d23cd23f4b6fbe4c8ce16cd1af61536da5fa67b10ac7555a68c0e0bdbf2f8d72309d995516b8118bf43835d0a01c08ffeba3ea3ed05cd2d54f0eabcda05d0037d52caed3b19374faf73999094f79055924bea9aec4470135f5e8bf183c9d1c9
+SIG: 050ae8aeceec9627b80137357a22962ac8b45048661708d394d0a51aadc381fe8535023d6e1bda0e72b349b50b26da7c3a3085e81e9dd6cf127868fc5baeab01
+
+TST: 715
+SK: e95cc2a4d1193b7539fcbbeaaeed985b6fb902dd0efbd6387457550d0d6a2fea
+PK: 72a1ff1e9bb11c8d88968a7b169637adee438e2263f006dca4fe02fe066cbad3
+MSG: 84267439201b0591db60c0f17a9c15e45409295652d5f55b87fb351967c846a567f5cebaaed1762bff5485f04853ca9269f464094e512df1f02e13e517b1daa58d34caa2d5ff9f9e79bcafb4ce96e8a089258ad61343b446628ebc4f5b2a84d03b72ef3f738589fa13c42519a828299a3faec035037bc10b44e3bdfed9e0870717cbaf31bef8b22c4ea16e8157fcbc63eefa39ed822efd4215c247dda48786277ec030a86c0ef4851d673cfe752d0677883c2c452038970c09bd481714bc3fbecfa4ff2a3c245695d7ecc2f4dec7f5ede04ff6db43e2bb91c066b649ef73fd3be860cb83fa80b074149f431eebb917ec8478da870c11e317703859f9f2f4008a6c7c754b06e1f7d2479689da84e88922f38274985e11ce13cdbdb0f2ece68fb602ade03dd549a362491f4a203ff80744f663c523a026b431aad45c5829e029ad6256d1276fd7b7a12ddbf1727d9e233fb534457370a426e56fb39cf404a3ecbf0c4b50bb522dce981e0830fd8406e6d9725ceb1ddd3a1947937d90e04d768ae1d126e2aeac21b8c9efc54c40961b7f4e9e88025f7e0b9de901ebf0049e741b797997d8db78e9283bbb5f90f35a2c4dee273142ec258c02ad0ecc61cc5c9f12132db28af41c1fb78e524be5327b5ffc35962779fb11ff0c5d3ee0a31ff47e73b1729dfa46e8986b1b89abc88ad06abd5b6f766d23abf642257894ebdfa79e6309f1272374ee9433677ba13e451baa95330e660c8052ae872e0e32e2b2d1286d01a0ab5810424ed8b9405465bdeba03b698384676fe5ea464a03446c4f7cd7b43312ecf151360464571ad28610581fbadb945a1d68181deb403aa56eba0bb840328eee36103c7de073a6879c941c7554c6f6f2a080809eb0e5bd0e130f29a229e930db01fecac2e036bdf0e001e2a8ea3264f8649d5b60c29103f0b49c24c97facaf7e81069a2b26ab3f933f427d81272c6c8b7cd0dfb7c6bbe9c0eaab32bbda2218b9623a2119aab1f3eb
+SIG: 1b8d7cc2adf36cae1631250c82431bd88437163a6349ad96e7a864447e9fee753ac3655c9835b4d1ecbb306c638ba5402ad02ba6d225d96882889fe8d204a604
+
+TST: 716
+SK: 77ad0f942c37f0313e6b0456dabaec81b2d61f6c118ddb29eaf3ac5bf19504d4
+PK: 692d2da5a95f48611a6da89cfb3b3540f6aa0c850d6d98deea870e397fede328
+MSG: 87e6dead2c85549e3d8d2588a0a3360603a624fb65aebbc101bf7f1fec18d0b28fbd5dbaeed38752cdf6355ce8dc84e18ac1a4393d2ab888882c4ff1c9c8137f83bee36336bcbfbb72d5049e0a400874514fdc3633046e89383dded93ca31fde0d898e11e9268d3d5c240666ed5527613da79fb7e49625b44cde78b41c67902eb0216b3a7a3e560e261d71d764aacf15959c17fcd6176fb25e249ee6bb1b3bd7bd90f60b0b0ffa0315a065a24bbae8f255bf298d7e4d44f0b430c415b4fb36cfa6626a83f49a2567f6244f40e923add1d49a72f57b1530f5b379de3a91c2e9a1ac79ab37bc3b9ba73d8828136bcc87d2c01190de5457facd90f369553f7ac521c5672b0867dfa8da3b952ad95b67dab99b4820572f2d4a298e9518637779289c031b793dee859cde7b24add649fff871248a6602d2516279da6058cbb696fa8b1d89a20d2099e646443210483e5d4134e928faeb38a3b508199e0d69bb55ee34774205c0a61205b50b08febeaa401e6e3a51a2bf98efac78b7ae2b852c5395a12c40e2c7dd1b202504b5a7d2f7e4fd4f8610930d2868cba8864339e041da21c0715f41b2b23d14d0b545480bc3bd7d7215cf2f816a3332081ecaa08c0f8b99525251f57231b6750c2dbd1109ac4160486b768324b6bac87ef5a226448c431240328f42cca586be7aff3cbe7605fa341514fccfb966af3d4530e8cd9037a11ce593c2d383e1035a0c2eda098de90d50c5184a9c01b57f26b94dedd1454c340637ecccee70625754a328c65f42645b5e1a5655eef97dfb1c6308edf49fa368d17d17e06adc512b3973ea652ac40a9978e1bb1b2f86c5a9ffbf60dcc4f6bbc98a64f4de65e7ec61721edeb0e5238456f761d2d1293af0de9f793b11d8cadf01a94319a02a4273ffc4d3ffa7b34d74fd2e0b100fca58b5325f907a749193e751d6c116687aee3747b59460d4ef156e72476eae1b8455d76e71b306b98129b72fe1cb5eb405a7c2f4327f3862d4
+SIG: 696bd552dd01db80b3d67d61eeb7ecc56878404ab119442a1c7422992cfa35aea920825d2dafd892ad7eb6825ad999aee5c83b7b507906534f91ace759c5510c
+
+TST: 717
+SK: 29321469ee9f2bb165a069640332b489bf5c3fab682e93dae9d86317bf50c52c
+PK: 96f730f8ef8970268dba0f7570410b6188a1a3c86397740913d53ada262ab87e
+MSG: 9c712c83d54f2e993ca68a9632846004499c5195448ddc491c3a0d2e3a666d6b33098e4864fdf86e619d50f10b7cc6c39b3ff2801a9491f6fa97c5f1c4afa7aeff31d738f9a768a79c73b25577310fb0ad4faf8543a098f859571b6148e8b52926445757d5549fd25a26518531566379d1c274e6c6a9d64132e4ac25ac9af9381bcb885332113f43014a139a81f8d43c8a6ab54c11a5c92e06191c1e51b757ac9f11e3dc15db4486d167ff9f2d65e23e6c96223d9aff8d10d1502cf3dbce5e357e6b12dbe9b7e997c3d0a507d3bae3cfef1ffc8d056ef7dc72ddc1c81e310ad205be16e77f2738354b10b484d3076c27e6b4f166388581f350befe22fbb082b54121ee59ecc7ae5dece89882acf26cb747ffaa3e2d05a696f60fd9e829c709d8f02daf537b2369b891fe6ccbf8dfcdd7f4a364b19985be7edec67ddc1db713c0a90fafa48837772562deacc2d2a0e789e18a8b5b3bd9e083ea92fffc3183d5d414153259b33a4329cfc80824ebcbe044a7e33ab8a24fde54bd9520aea284b0c4c4fa9427d251c0ddd013ecdd8290ef5565f608508e363589e529d84ff0f26f9ecb03052d5897fabc917e56e601b64abfe5a17c3950289d0cdcaf1f6005a9f8106f43e17adcaa2d1e269166762f8054de05135d5d1393d7000a15b87bd68846a89d5bc22863325151aac843f72278ae6f4af72a4e449adb7eae6d436a1ec7e58e59b7b8bb9ef0ddaaa001826f8dcb446479deafd8b8d542041c19a05b1e0ee47b4640910c31930ca4e20b105758ec75f1950356947f6261d0037fe30773a3ece6a96c8d5433333d822c2777ef7ff8be6033345b5055d58f5eb3729af5ae8824f331ee0731c89b20ac118f550427cd958a55f6b1a2888a087bb7db55bfc73b29429b4448dbe9119c45a87339b4497a69a4cf833e8f3770cce5e01faf5e73bbaf627683c0a28c73052fbece203043389dfbfd45495e51dab86a252e5bc1b4b7fe2807e3d0e2363beab51c67fb31
+SIG: 4e1aff8463bca1b7deb1d3773df2e7a06864111b6dc42a62ae98deb2313943b3153ee46696b15c24efc2a808aaba81c78e3dfa4dfb50ca9fe84445ea68bc8e0a
+
+TST: 718
+SK: 04657750497e68152c43ce34a58d2106e64c557cd7a84ef05d9eb82e6bcb05f5
+PK: 3b3a1947b4cbf60b826d609f192dc230aa9b9baf4cd6a6092e495f1d2e47ad62
+MSG: 2948227a890f6f845b775e62c53af3805064a1576446f085d90f8b9a5ed68df1ea393ce479c4414149a9ec5a171036424dff0344b4958f6132298d0e24c926d28ad9d79f98c6e6bcf1c5767606ecd291c6ad47b4f9fb2b0201155ada627b7a1fd5b07419874083059eb52b2f6ec22818b78246228f3fe6355dfda70ebb9bbe73229378736399557ce24b30bf645a14e2256f70019b3336b203fb77c6ec94a7a2634888feead4d72c2391e99e8c8d533fd8a42b08c11f887ab2deb6ebbfe3d251de63536c36cd53422398e544cff87b07a63349fc5085dde93a1bfd7171133a2043981f607522c8133c63428d1b92626c79b7358e7021cf1f412a78afa7cb3f59ffef9279885a5bdb2466acd34cd51580830b8351ebd440a96623907ad1f4b56203f5e159a429e3546ead0c011dbed09028717e3c3dfed39197764d4d245ef228b98044718ef4d8822f21b2c5685038473bf93dc0937451eb02d31a46c8dc7e94c3e8678c83b98a43818f125b528b476aad31d1584ffd48f149e5736e58f94205d3889e567e4dd1eac2fac1f8f4dc540e5322460fb940e12e93c4c98ded1941c1904f967fb4643684c19a4d5c441d60b0e9f40855e523fe7f99107657a68076275bf84b7c69a3f2b3855bc8026ba9b00bc6fe34b99da0631700a67f52b34e1796339887a48305121d53ab4440fc4b5c9bf72394d5ed372ff18ca3f007bd02df651dc3ac438275f1a3e52422b86c4586766a21cd89f805805dbb44fd89fe24fb2c0b40d1b754c335dbaffc3b3bb8bb46c74c36374504042d86789227599862312e99ca89eb504cc3d75d19495aa86b20b2736b121bb2075c88ed4a3fbdaa6b2c3f76d1ff5525d3a2863e4d83c72bfe01e10278809474e1822de2d96283489320029611aa9dffc4829d66869e63494f9aade70b77a7b80fbc93e3de4d935913752d045e13b312c5d082f6242d4985b053b3783eb02c6614963dc0d55d4cbe887bae29cc18979e5e2ea945bcd40d89
+SIG: 7e2eae5a293f418391f6d85a7994b07c452280017ee653bf617a8d5be24cbb5d0efdfb7f7f001312260f344e6fb915ad8d7de9c0519827c05726f9ce2545dd0b
+
+TST: 719
+SK: 8bd99070c50a9fa418ef7f75c00129916a41c86070961ccb2b202be18c2d10d7
+PK: ddd73308fce8ca6552d039428c7a1a94923320a31c0f580d3c235280f03c1830
+MSG: 485f8d680f79ee2d828be7d018a65e0b64b0f0184819863e7110eea8f299a72c4dc87f8ee8a8aeaa81af91dc71adea79fc9797421ccc646e6cd5dd48b4dec1de968693fbce0d0021a3d98d38a8bbc58195e6dfc3b5e1461b2a594103e80a29441d5aaaf889e31cc865141f0c6b2c8c81f721679ea2394ec6e4081ec203c2ea397d9484757a7a0ecd53e652db9df17bea0e32fe8b2cbce0d1d97b961ed74e8e622bcdd3558b7c48695adf18aae6110ea9a339b9da407a9edaf2ab081a681e1832cc215b1f08a67d559a4744af7cd50318c206ee91157582f82eb6c0fc29027b4461c30733b8169d1481322c4860509ba096bacb71a579246751d567540e41431e14f1b46ef16eba276104bc01650d5c4926e47c9c6040784b043cd0aa4854efe8797fd0462d4539f38035aef08b4577c1a9118d004b6d01862f5276776dfef1371864f155ac0f078389c205cf0538d85fa348244d7a422911310ff6c10132b1598bb445c7e2077b763c473d1e7a61a38b64929a648b60b2e543543739224b40fbf6d87f1079c30bc873ac38991d51b89e9d261c4bccb375355c072c1ea20e4ff91d55d9f7544e90d1c6646c59af72424d8aaa8e0aed07b3889d4e450c1209684ce138d0c9da079525f5aa02050af570e4315c2fa8b099b7765bfbb894fad359b8e24804ece052ac22a191705335e98840a624e4cbf3a1a1a327812785b2c0f5d6381457b72fdb633e81938bbb54b8c37cccb5d59c5827c7683a5247544977e984442178d0852906ca6f945c4229eb08ad27e6c275d7b4ec8dc25fb2819337e53ead6c7aa787f91a7dc6ddafd536eefcbdec2c50167be34306a82e16d5d52b3b1be008a7a611274ce2cf8d62e3b900c09943be70ccc77b070637c25061d61be910eef50df18744c33e76f6701e0a8ff6297fa67e4b4108c13756727a9d74bc9e17983eec08f866b7c7ffb37f3ccb0141a80feff6322b2ac62b84ce2797fd98d6ff269a41a0c38482db679862a38cd2
+SIG: b14a7b262012c5909e21d587fb4f29a9093c8e1c2999816a82118fefbf10e68ea898bf0da18ebfd0341ea8f82a1844c8e0dd5306e509b9d0c35b473a7d209507
+
+TST: 720
+SK: 1af4cf6d24ab3782867d96a1c275ceeb022c691a308e6245665d616bf67c2c32
+PK: 19d317ea98d35ba5fa67c12ecfb32750df275d7a45b8e211a7ac47ede7712d9f
+MSG: f445fdcfe28c17bd4427aea5676c0e1280841597e9d66de7d7a71723110939bed00f4ebaf9603d53c9cbf6271be547af29b2a045ec41288a7bb79d662dc210e215957fa84688c916543e5617f560e4d38f73baefc37e11914e47c515067851e8ed21393e13dd19ed9b73d98945fc826a258e957dc083dd8e535c30a54b4266dd71d113ce856b46282a18033627a98e6472ccb463ed3d96fa7b355d3b2c2a2b6010dd14f4ea3965dd87be1c429bdea8300b4b0b44458635b4979f5e3e8eb5c618d4e13e1d688bf88c7e4a3d938e84336d67be68df3435c5c99086321c02e13b4a12524b34e46a0b4d27f30d7ed4f5cecb36deadf09e7efcc755ca667568297914c6bc240627d9d09aacf85415412c0635623453278d9bf0e10eec65fc72affffa9392dc7881d1e5c760a40280f16b1475127b91b69ccb65dc4b35de10f94325c0cbe1c47019a2eaf2b4ba92d785229aacfad1826ebbdebefb7dad4b05f88243e15f279766e3321dd8dba650444d81fb0878767a9c63534bb4ba21285a2416cb8f856d11a96e0a8c8de1e1a75132f1564cd994995690bbed2ee154537fb6f279fb09c8dea6f6afabc62856e3d128fdfa79fc4976193bb9b336861e47b56dc2582393d2e544651ac85bc58e9e6a94dc4c39c4ef72538a14f856cd95c3e2790adee03ab2e52ca0ae471de502cb19e676af35f5f93d840fef9606cbe92d8bc25006105d92344588838842c3be505c7350e351b735e6cc6fb79275b27bd9ebd36ba4d060acee73b5a315ceffab86d06f2168a67065578196a0ed04a4dd71d6734837db083857ab1eb5e0eec4ffbac9544f4ec19bde194df84b1c848341574bf10daee85b8178196fb608123a808171d73ce4206ad65216ad1a5cbde40b19d6ae7f40df97ab8432e2c53a504ed122e25fb7a51c14354ab3928edeb39c29eb246b74a076f89d03504f401bd176b5cffee4b9db097c45764f51aa376704b5a7f210b3f1a905e25d67002f6557ebb749737cda31
+SIG: 7eb46cd0de3155b43747d732f1045d8ef74492ad827a2245bd17102828442e43a0ce7e8b268ed7fd8d3e7b28f072795da3e070f12bc4e23eaef57b853cee880a
+
+TST: 721
+SK: 2aacc8197ff8fae1c1cf3862e3c04a21782951f8e48e40b588f8bc7460c30a03
+PK: 9a1b01e2154f1c36a8e16b79ee7d2d05b8712e0d27a061a6d41d475778b0df8c
+MSG: 5d82752ce5da3180faf4787aedfb19294b4348a1d9202c85398331323e0f42b0835227e68e1156f2d4ba2fe450e6d6ef2b92d89bbbe4096e12ca8397eb2f45e676f1673aa41c959fcd30d5578853b5dbd1c0d5b3a0f0d870eca71ea13390111b258f6548b32f37a05e9744a656fd778d65721965c6d9b328600b45704770e04b099790aa7884f00d7bb7659e337210bdc23eaa71d7b016030aca6223b5569bdfc290811aac409524dccbf9babcbe4bf20946b544317ca6f2f91831c79fb273b6404eb4e61e1f7b106ebd0db9f2b1974d2f031bce25803606552c3441655efcf2c7ea52adcb30993d85f2dda79603e9415a023245a66c07a956933146f53c993c08891808b8166b30721fbd1f8a1b937d14070d786e9eb451f2ab5142f83a60f35d76ad8b81d6a57cf368fc6fcacc0c4758440d9cd595b1b0942a3655e250da983b7241546dcfbe0ae81077650295409ff9e90977fb9960cbf40a2af5177402ba2faf50db6f1a7365cf99e992429e38db43ea83fddc95a648676c0b16bc952b15de99d52f6b5233da4eae1978e8ba25e6235afbc511c76c4c874c9237922b1cef0847d07a80200cbae3c7c81fcbd0d17252ed8c61ad1954fc862e1e04444c32086fee380d1c17541322b9a60da662352e210e9ae215e353296db922339aa17d2173ec31f1c530a24b1f348a31572e1469caac808f9c76ec2731873b803ead3e54ea24bc24499b9704b3bdce81389b9d14d49527c04b3bb9e3ba6d946cea58cf786d4d28b89b41c58274035a86905ad95758c3161366ab93da81e6b4c808364e087daeea4c4c5c2aa6871937c5feaba2149f01f738f45396e66ea8063221e1c81c05255ba564ad440cb5d07cbd4bab941ea593244930bc5c289b3165d3ec8847ebc4b674c0a49f9169adef786d7767bc8f213db7d95c06e99bc11e200055b65eb79adaa01bcd2c85da43ce6370e12e349bf6d475487affdf92e20a3acded1d76f9e83e919e98def195072a50d0c571dd25
+SIG: 647cdd6c1a67290e57676a78113aaadca69ac57b997715c509895b8c5c94e82c0b6aceccf3ba8bd7cf61752b1b19d13b49f15f8bfa046eb442a55cd5bab14202
+
+TST: 722
+SK: ff862156c7eab681c95efff8003e00a14f1f0d505d5507e6e5b39179df9b1cda
+PK: e1b89fb31114ea46107ffd0329f1066428de54708edbecf3ed9d4708cd143fe2
+MSG: b3d1db72a6a985ecd70a2cff6c18c179e217d4f410fd3934969685901bd071bce6c2fb6763e10c6fa16e75a1176066b8ec81ae3a8039e71dc2cdc64a40fd62b7cee7be4ba0332fe45d0b60158652e33f8d3aff3cb4d6b021744d0dd178b1bf0a1cc1d3fe9321be28421eb88263a124f49792d079475a8c555ff5690873514b5d483e53217e0cbb12862b850fe390c8f83008086e649ac904b018350ab49157ee9bcae6c07a4b878b48e25e984fbb4d36b61d689b13468a28d1e387e0e88657f8c8ac9586a6e26cf94dff6f8264e3ff6258865c6dcf857b00147886e175df0432e32f04400e299f21188312b32dfc050e7b7e87eeaa0cbaac6be9937a5e0cc31113de7c8b233e1ce8e5d9c564fbe9f37bbd411df7a5e44e6c7ebb676d85894dccf4865e4dda0cadef2bbc55000b3a29f1f71ef4461ddc3b331d91566534c5d6d84c731376295320f80adc90288f9953554fcdf9213de6a905210d4c8064af91cd98325ef91898d33d70038202e32fb6709ca3d788fecbd1b841fa4e5e9062d64267c35cfd444fb69e2f6047f58b1c2af4cc7e4cac2f890888360592113e96ad3a857ed05eaaba6f9153ef89b93e00e8743733ec472d9b0eec1cd8fa52425c4a26bd7df73a2712bebe51ae3b25eb78db82149031fe7b281af6cb7714edf89de915f3470f153eed7f456243bb90342e190e647f39e046883ce28a892003315ea379429e9582a935eb78963396d136845f86c466e8faf2272f43ffefc2ada5601f8a6b2ac4cc6b92820917f2e0393c8faf982d6c5f4f230e27ce2278a7237747fa85a9c857bf1802c3eae0d235b5ad58497d66a0d3a9baebcc417f1833e9cc4460f975d72858cd118d7aafaf1c878297cacf71ac75676dc1b4fb51c1775810d03537f2d766278b9971bb97d3c49b51feb26d375e0cb9109574a816f84e76fc7ef072d5793c2f65ab2efd9052e6b8569f2805861c31a7344a3c44069a94320d274e271271eafa3bfe64de7537846a01e51fdae0
+SIG: 4b8137042d6784757d4a9c06bc7432f4809b1c6a903542736d9a57668c20845c17d468557085c57fb63213dad3be0fa36a118f7c1aeff2562ff4b8888c26900e
+
+TST: 723
+SK: 582619ab3cf5a3ae776688bf6dbacb36330a35ad7524e49ef663687764cf6ec7
+PK: 2002ea0a38a327e0384aeae468db0f6c8516a69609af9eee93e9ecb94b449c66
+MSG: ca74284f11c56e2598d78a4ecd03b40e017a558176012b26fdf695c3de98a74f8f40a47d7978edc24ee8092bfe5e61596834deed1d9d34a0f5cdaebe3421aa19e012de865b9ee1b73479b2bd1ac982f97ed9c7cd20459c60fbb11e1e2b4eac5db6844c71d72949502bba503acec905adba25f6b119eaf9639fa8abb302dff9932d850cc44c57cf90b2e58a8b5251c126a9e28f5c761b6280e2cddd79cbd68e53ff4a6226d3bd4c961b9b9e4345a2545862c7973866f0420b898e7baea90ea4ee004042ef38a1fd956a72fdf6fd43257da9fdb96680ef4fdf9e943d265cdcf2e52e3201d5408bc6ce10e5700adf12b55ba14aa829d8691c31f24fc4a51ce6faa1f3ef2ead78e5e753446ad3fa4a84c193979aebc8309bad60814f4859b931d70414764491c6c9ed8db673c543d35185cd2888aa21c1a9203427e0ac0b1fe34c0e4a4001e0956c13cb59a3baf87c2109a888a4c9e7aa481767d8020ff35dd7c5ccec7c08e971a7e218138c90546a7ddf36ad114be58557432c2ddf34ced3379f70d4407e5879f9842f381717051b1685aa7ab0ad38541ec168f51cb688f3cd1a019a336c9f4f3f82de785c074867fdc8800fc76fba04c8ad8de10d2e9b430581be44c41ecc8fc8a616314399d18c6479f57e573b22a6ee5ce2dcc08948a0de1f0dd25b65715ab18c70c762fc3d7d600cad63226038509c19ab35b5493eee73a703731ec535c90c6f06d94d3e5f7e51a09f9f8f42c501b8504686365ceee9e0fe001329f303522146717c6a1258d0f157cbea4b5a5e3d13bc907e95fd6e8a71896a02c3106bd26a510051f1b30258ab27f875673b1337ee36b71a376e0f9e7809a67c67d9acc16c251dcb8c926c8e932516d38b7233eac6159c59cad0307c590e7131b62219145aaa355bfb4acb6af0a5500006cdd8b813fe1908602e0874c9622bb37673ba1acba414231667bcc4907ac871f87e6ce3f591c19171057a9f457f5362aeda105d18fb84f7d0f0a7da7ef8da9114
+SIG: fe9701da1aa81c55bac33638f775542b804480f34b7bfc78da9916e5246a604d390bf920c872a77924246ee8d0393b202e7b25b2484f654ac367cb0925ece305
+
+TST: 724
+SK: 2bbd830ce7def3fecea1ecd6ea0ae9c9f4fa8ffc3b1f1938c505051bab40cf7a
+PK: 0fdfed8de3c1eaf891ce37e34cb4a2441cbbae0883383d70de2464850b4a642a
+MSG: 5f1edeaa3c0b2a63311d97f1c54e7e2f687170e6b46e2169cbf56c66f231bfc4a576bd2b8420bf357d3a90f8f32ea1ad9939b467254b66a1df1f5b4cbac63a5c2724260d24d8df8edb58ae247a2591e920b1a420cf8d8539ea57db0dadff1ad3e98c3172d033163cb434a766b0c118a56abdcce79c82af7bac74ed0ea024ac4ce0222d0aa914f432092b1b517804db5918a845e9cca55a87db7c2852f7dd2e48360185cc442c7930afe15dd622cc02bcd1ee778b59705f14333241588a522de24407e8e6e10d5ef3a88e3a3c4438c17f7504674fd7e418cb2f77ad0a56d2386703155e9a401c43ddb51ead5520aa7ba038e7de5331418ad552bdcd185f503a8548f55b6386e4687ca515f7c0eea570983bfb24be16f7b3003fb756e326562f2a32fe65ff844c3984c72e40dd49e4f3ae8c0f819a7939b2e736e381f5823cbc61b2ed01d9b05cf8b14648a48b0d7cbe882ac16cadd8c42aa2c70246347b4d849536a7ac22c720da3cf178725ee557a92c25b12b8b956d3bf4802e9e8a15b5ab754235cca0e5b7e55e4aece45a47e084ce1447440598ef5d4f5fdc2c98a5ad136cffbf87d3cf52f6738cca7948356092078fdf254577f55969a0c65246dac809a2fca1f60a1d929877b9a6540e88a9e6e9155938d22c687e63b387534d385e8961e5886743f95f4a7080d916624517b15336030a46714b168b83d6f9cce0606649c01f0a1d0a2a53f5e378f6aa98c384aafb3eefdb3421fa3ac98a0d3a9c029c2300ae0241067d1a4fc92e438688ea889fcb1a1a9e8634b916c60baa0c18bfcd139bfe3017bfbe16291343ce8605bb7872558c6b5fd56dfd221577edcffaa8bda34d7a11ab8cb278288e5834842676fccffaa9111bced2b3575fdd49621b76e8d129b61700eeab0314ef94d550506a4b8d1ee65508d89d0e99e9336b41d9f74aa4d722114de0f31ecf00b097f53c9aca9c7a285b58a35d70298c5c34f74b4a705308033100349f0c62f9c2ebf7dead0a77b298eb
+SIG: 13ebc979a88710e3c5f345cfbb824813b308a9d5c6dee328bfd235a97de7b326de6c738f96f69831949209996852dd9c098d5808418709f2bf510d46b7f03606
+
+TST: 725
+SK: 1a7a3c2f5481131be5f868456aa2fa90e56d52cb721c7184ebff06fed2fe685d
+PK: 7c2ad0f2a570550326fb50a850835821676de1de127f6de1670299d814f6e3ce
+MSG: c62834d9d55d1a4403e925d0a5b552da174c02f4e945dec338c1bbb2aeb4ff40020ef70ff505205cf881b629960abd62764e5a54f2b5105667b11c7d5b7a4ccc3f488bdddb958a7be9546207e6c4671897c053508e1fd83222130a7933976d2bec614ed8f9b6a6b9f4efb2a58b9d005b943e42f171b709a7313070cb2e068da39cf99922b69e285c82ad97f2d6c77922cae2b5e320e83577c0d088761ec88152c297492978a9d7a3ff67ede44c2a707cf3e2352e232f53c8782ba48928a97f8a36b20a416816e94579b9d7250a29dc8470f63a7058e2d2a99d6f0ccb530df5969505ef5c7844eb167d20f412a508fab1f8cd9c20c5eb9a417a5412b5da6a57135759fab17f6314f68df35b1772421443676f312579af6b1411535ada8f76012b69bbeb60b2897ee6607cb369cdf52f4f6ddf88cdb2630d78896f1361fea22ae634217696ff114fb42dbe4f4346f1be5b57adb384ae7e49b41f74b31b9a62bc69dca16589c634eb9d7c6c94f8ece44b60628f98e1024cf32e3e3dd6dce55a1222532f490d63e6a275281c0f3a6c101891b8d57a45de11de35ebb151c0dcd75e6c050b3cd8babae845c39f66c36c77cde05b683e4fb0103d93e7659335c87fc0e3235b2e82488cdabeb5c5c875808745eea92de86b8efcb63e16d082919aee2e92899cb0bcf1c1421577a4a0d9db09ee1f9feb92a5382103cf7c32cfe463725ae4866daafeda0534c169f8f9be404f3baae123fa768ace46178d4b9bbc5bd7aeec7903b0a5bc57538986ee09e07e32077b3b9de50dd1967a372c385ac886287c18451a64efb37d056f9f4194c08b1e3ec97022267bf0043c13d26b9ce1f53905f6e41b3d99dc81b331909b722666ef2432e6af8a453107531230ce4a1af8eed626da223da76b46507e33d7cdbde02d411040c89a11d95156ed4ac2605b826939c6cf877b4ee736c5da77cf4650a9997a3b9cf46a82ba2bc01333c04478b5c92e2498bd002f013140aedb301b95993d1d750870d988
+SIG: 976160fb5bbdabe5c8962f23babacf0b0ab41c2bb13e9c0d449067b7decc7db4e94e76a71b9c0ac4d6af387a72a8cd73e3bc63b7ed650beebf17424c490bd60d
+
+TST: 726
+SK: 191a1d90321c7f4e7494bb982909a9eb40c3341dd32ae4d96750b7d02966b40f
+PK: 9562d9e213f145c456935b7031c680669f8bbd31a4c2ed3c91c4002a5629e97b
+MSG: 85890db4e2fbce093dde5a80bf8fe09a984b83a49b7ccb5d4b06cdafddd382e4b8a8a50530e82c200612c9d7d8a089bc8aa845c3cfcc38a6195d21c2618c3dba2b570920eccfcd236f17f08d814268f882242ddf0702da8785f407aa8f86fecfa903c48da83f839777eb6b4a2bbf5df7a4da53475af1ffe44b5fe0072b8fbf3d26e6d89ea67d8ac8459492890ada657eb3dc2492b88de175b4bba1a508064d619674aaae2af09d31a5c27c8d5d5a29b03779f4286b8966ce407e6ff692fb942520a9938d69cc70acb06b014b6dfc19834206cf1ac6c448ae6f078025b55f3d827201268a92add9ad178ef76a2989fedc6e39f4ebb9f96c9b8352694fa54fa022019c0ec0012d0d769e2367803f925f175f9fb9cbec4a0c9c1e2c83ea57e6a92a17f555cab934271e72c8cc3215fcb87c20539bf14277b1bfbd6e5880ef953fc75f23c0dd4fcc1e0be340af947de02e877fd5c77dd1df7b414b5c0b40c74956a545a115b0c6993ab233b7e72c822b6b3381bb1fc10875bffe3e2ed1190fa33fc15da083794fcc2c5bf5a07909063cb289a08a2c8a33d343842c2d6a3cfa2a16ca2eafcab7ea100d1c714baabb7149f07e25dee323e780757dfa8016faa7c0626222c365f8f2f6687d1ded234f799cc50d1cd26b4cfa4045917056fc79c3b88b2b1908e372df66dac8734631648349bc37fa34b25fff3b0747b6bc16b94e3e5895e4bbd93d478a6c1f75e4fa30faa922049ed4c50f12f4b312a8974d0fed8d44255dcb2bf0febe47fb3fb8ed9903b5ba4ca18e3cc6762cfa1eaf04dfa944d496e0fe8bb7dc045451396bfaba5485d9d5f391a954c3714253ccd9b19964d4280680720783036b3abfaf2884583ea5bdbcf69d08897ab288314635abb4c2964b71ad9291feb5b61f80e9b0cc07f912a8e5598d5548defe0eea1c448573710aacddb152f93c7c6fd3f7e4ed9f7442a6b900f23c3c544ce5c9ba5f5e92aafd11c9ff5f79c08b9d045fef07970625f62e2f4334a4d664caf7
+SIG: 74cb028dc6b75b37a1daea1cf88465db83a0093fecb22d99ba855e9ab59d05cb22c87d0b09df7c116213baa8f189b2703ff953cd202eb9dea3976ee88f5fa703
+
+TST: 727
+SK: 628563aa3ee2fc611bcff78bfb2a75e9fd8780e87a939499a61beaa6a4b71913
+PK: da20616ee4a41c2ebfdc50ab54953b6d387b06c6def75796b08809565c6cf805
+MSG: 056fb954fbe6a6014fadac1e1a9f56cc08af37348ebaf6920683384efa47626ccddfead2d5e9e8cfff45f7ac63de63f69d12848ce3c0ef1f530ade430f0afd5d8ecfd9ffd60a79746a2c5beedd3e67249982f8b6092ee2d34047af88a81feab5d52b47d5b3f76c2041725f6f813293050aaa834b01a3a58f69aa4a8ca61f5b746f600f3d452c6282ffdca4429b9338967ba3a7266690aec75ebfbf7be98d999b03eddc7292581b0d69e30a0351a151db70412b0bfd43d3baa9d456cb3e0b4fc19cb09e6cadcb6d3f3be5137cc7a8d3219ec2036ec670ed7ec523b1b1c687b5465307882fe38d7472d0ba87a471868309d2f773ff24c87d39c16b708a4ed9af43f74c8d85cfe8ab5406907e941a14970e209c29ff7ed8a2f935ae41709f270d0d08555ef7af2edfe40df399223c785a43e7f3691589e2ea4c036f11d03d7d1eea14f620035325cf2b33baf386393e8a972a7af6cd9b8543b32e2533d1fcc3177fd96d1e13bf8b68deb222f94497265d3ccb345751bd5b669078081998d608ca5fdc134839d4ed2bebb2952fea5a39c6f033c1558f698ce4946e4f6c08af874f27357f870ebeeb2199976ffaefac951f8e17fe7d0821e1b92a90aa4e9defd3fafda052a444476db1ce38a9e176e841189abd8fecde0fbc5cb55f511f5fde07ea97deb39b7aa8dc84a3946a6cf926d39b95c11af9d64d98b807f4704d0a2bda97dad9881ada1bf6636366e60a522b4821047861c7aae2146a02eef6b25d51371a0f17d24bc187dcdd05d541c2f72201427915a3928cd378689103ac50b33f87a47e8cdfa687a5f0af8a56731dabe662f4f2836de0ba8fafd86a3854bca012d7088a00b9854c2d3c708ddf58faa355a89afc2c80f3f5336da01d72a2771a055813fb35330f7d2e01b1d12daa95ed55d3bdc5df7739cbc3ca097a41b6b2bd7f0ff9dd1d8658983ba3ff7920c15f292a1ef9fcada1c607ecb45d3a73c9ffd42f3e16022fdfe12744926395f74fb3111793fa9281821a66a01d
+SIG: c9a6aaa9b4e1cce1b58445725f61f552c8fb45831f03482798f01f663e9983db1a82fd33aba3eccb96226426d50ae17cc51274ce18a38860f40b2f82361b5c03
+
+TST: 728
+SK: 9141f79ed30bf600611a13f367b40396f2ec839c5612bbf1e6e497f83954bc88
+PK: f14eda962640becb66c4d1f1a021110251917b8b1d34828298d32145baf6e5d9
+MSG: 8fecaa7ae9a3d4a4851a66362b366e167b9f4300fdab205654751987f085de61bec9344aa86f5e5c6477514c2804ced7ac0cd0628529a3a1599236ed67bebe1f2e95aa151fe0f3b3011a1d4be9901cafab2f1891904d4bff0128c1d35ececb322b3cc01dacc5ae3dca6914a7d34da8c9657b950f89d1d6aec3299bb690111071fa87282774943d96a4ab7c3d6de7d1bf119363068cc82d45e4b76454c608bc3566b7f9b385cc7eb38ee429afc2da99669fc5c1be82161a1b0c33f7ba9ad4419d2062971901db003bfa23c44714995cb06bfa966e5023aa9346fd375ae2a1e84084314df3f08ce20800c2c2adfbb81366f6b104243d62d5041e7273433f17581bf93f4c6146fa966f638ab07ea16694a7ce305cc609a6e10623ff7f6c7916b6e4dbdebb7b52eca7f0d5187ff664d7c370ed22886aa2671329d928e0a3bea3b4711a128b9aab90266f8651d220b9cc1cbf5b1ce7265931803690d3291c01ead4dbc3329a97e85c4fe1d356608cc9e60b05bc14838a8608279a0061de28ff7b8e81f59c8a8c5523924c4c485e6ea80ac81750bb0e419efc7858cd4af50c8b8c80650facab4d8258f9cafa0310a007cccbc4185c82fd146df1d811879da3650d5716f1004b71d2c7f2bd6503c354589f8602c950a1f5139f811460752880a341116630e4ff84948e74a9eb350d64d8293002200233f209b17d78897c7ce6ce29e29f82d4ad6c61eb79f5739cb668b21a745555c96e19526845e82c6ed2b1c6bdd6364b8fc79ba9a32dbd3f8b975eb923623958ae0daa4ffa139217c00e021f937e9b791c37991a35e5231a1914c045a787432f97b8e2063db105e14da979c1c4cba785210eb02011334b230cfb6831998ccce25386f4f3ba0dce2006e9c3940b4d5a56aaccdcab02718689816360f18852fd1998a99fce9a04da3f5e23af94c6e8a5badfd39304b9e2a376a1f9bac09a85bd042476e26b58ec73f1236d41ab4b4e7a54def9d66a38f8e546de7b388e1e7d6681e5e2a096f160
+SIG: cf202d7f2f9ed117f429502b2a5aff54a7f751d2171515a4d203753446df0ebac86984c88bd42bd1fb8dcb408776722a38f32cceb25f32a25d7393f138eedf0a
+
+TST: 729
+SK: 695c960bbb0dd57ffa36151c85de735154fe5ad5f5fc77d005a0a32011deb30c
+PK: 34125e4e21f789ed0e1180c1f6369c721dcae9859b6f7b04f957e51001eede8a
+MSG: 3706696c7a906690d0d3b71e7e211c7b067168f3a8f1ed984a0a5e6078597662e4e7889d52db0f78e0d5ef0e5f7a0a0f4263b6848b0725caa4b1cea6987409511c8e5e982d3f5b82bb56a4a7947121937f8e105c5a14b53e6c37cc716b1eba922421828b046f6856c44fabf13a7516c62a5ff98568450cee78b140335047bf1ca77e1549a894feeb078045e4641832253bf695485452ec369065a60029a6c9077a379db20485ea2edb6c969547bb2653289bc6e81ffcb84bdbf773ddea4b3750e9a72395d117f644b0e22061d4f3bb7c5b612e4b70395e0779516b46659116902fd0fbcd2340eea45e9c23db2564a5e11dc79e8f4b332a443ec35aad9604fe791252088295e84f65a307312550d9ebf61f367e4a0f2b5623e53ef6bc132825fc24ebee4ebf338cbfb5df69b32d030d447c44f313ba96fe07bbfe5b0166eaecbc619bb6b2e5924010ba3ec150ff6a69fec4ded9c442f98c15e77f319b4843b3b748b5d26089a76c2b834ff93c413e04ca9550cd211ce2d6a583d782575066db6dd33e8d5e8374355d068a5eb96f8b3da8dddfb5baf5c596daaf556a8f2cb5781e5042327f92ae0621eae088b5f013592e77873a81d7e068d7b8337db9f109a835b475e5caf7cea5af3b4ad6d90baaf1c73655ec676747fcdd41775b4fbe3924c3f41d8a737528d12d6156653a22358c6821426b2c0a33e1634c62c7c8385649bc233e7daf9439f09db9bd11ea01e28b77ecbbc4590e29fdcf0fdde152f6478132fe4c3a5b45a7305af6e381cadd72496e66bbb866cea47f7e7d7e63341600af3f49ce9c9e4e37394df5df71dc10cd391fdcb8a193dc98fc19059fa3ac230ec5476bf94d85556ace6e1ba32421bf59dcbe05c5e15d34c6644e27d0a02be97fa8387ee03706f22a8f4b3b4040ad7d3f8a86971a20a09ec81b7696d834c526b8e51cb97d27643f9abf5e29ffd0333f95de15d110c2064ca49467c14ef227f4babf1a55e7b1cda0429cff256be31cf116719a81b9c5fb75fdf64e
+SIG: 4af41c554d990812686c329a875c41ee24b4a7fd7b3d4f8c8d5275f2e7cb242b258b5858a466de595ce2a2177e351c7f08c7fc4e0bf97ec5fb2dcb8252d2c90a
+
+TST: 730
+SK: 25cb17fc33d2bf8384ae4df20c1fad5c35fd765affde04b5256d4de01ca8de14
+PK: b86ca312fe598520c64be5c72f5b23816507f69e070f828e02d2afcfe11bfa01
+MSG: 4b4a71cbf8cbaf57a77d4ea188a6f964840f0d714a5f38a095a13b4e571297a88b792417d16184427f90e043dd8a55b7f1c13e00dfa60516445cbe77068c79c8c35ebeac330c33f1121d05731a8f5132d6480073274641195a75202116fff1c318817178fdd768bbdf105fa069c7a3d143fdf5d17bfad7c0624e5292068fd7bb6d303b4a27cb20a4e61875076787d19fa6f729c94dc0ba9b8c0bfd9866da5cb2e7a2cd2edbdc95ac349e5e5c2172e5a4cf7bd90cabe2c6e2245980bd72d0f6f5479881e8c4c354f68aa72841d0c73b986ba51021203161026ee3d729ddf1a049ffe9eb25439802f03011d144e50b02bd4aca5e5506d32fcf69e32f542544798f4e87f72bdf2433b1ff3259292e1d90812cffd79f6a543270baf24a3c39dd3598e1c661612922522f387d51597692f314c4d5ac4bf1883a614636336a5544d59ff41d1e0dbcf8e6627e7c8085646322dfc20c332cbdf35370d47dcabb802e17ca84780eec661c904d5bfbc240ad6a14a7533f71a27500c61dd3e473983887a86835187abb0df08fa62cda69dce86e21fa5ae954c22eddb60ee3131504a69b50486a17767091883760638a29c38030e1e05fdb28e158633010385a620613cc10d5a5f350955f4a347c65edddb7e25159da8dcc2655928ad6f6d8c4c1abb817d7fef3bae5de0402eddee7b51521ce280a66b796140f56af9bc20e465875ce2628a8a10477ce9b2eacc7d86f88272457bfd443e712526996254380f0135227e9fc151c8695e9cc64d272b256ab95c9a9f568e93716e0e53d29882e3ce74261257a02cd497c37d764d90f7fd478a17a890a8b2ea61ab81f6869b120a2f6484a88c151953391eca445015377b3a5dffe4cfbacfb5bab2c47f654f72a9d19cbc4d29537198405e3a04b4bfe11bcdb5c1f30d9ac02f54849c57aa96f7b56636116f2bb6f2583d9af94c86aff5c137f63ce54e8f0c21b6c25c1f0472a229c90817e6162eac71ccda309a1643bd6312a5263a2efe646dffe79ebd8157a28
+SIG: 8ccb0dbcf7cc03e83e21c57474afd3ad8898097b972ede175acaae48e3ec17b2db06fc82776b0751c0f956fd7196f3d1c96321a6cf3d892415d8f8eeb4a14108
+
+TST: 731
+SK: 49e24d1699833726b18c78ea6568401a971e1ca39dd06d7563ac8b4250d4a9f5
+PK: 71cf05e90d301a6d9fad7f0b38ec8bb044fcfd97c849b04c003625de29be86bb
+MSG: 6d2605f61e1a04b6ae18c2c25ae100dd42a61e664e2db5c34d7ad1f84ac507552b741c2086c17c852babe07a91e129a506ee59edb9ce73be1b1d06d120ec36a1e94c6281054e78ceb1bdeffbcbf4f01051ed381bfc8ad1769f41e240bf6059d9704cacec666611f41e4dd438b7f50242ea86756bb1f81e5942c092129fbc6de4955d28dff35237db30e4a5036a9914c9f84dbd8ccf82ba2b1b3b5554a2b7a74cb0b2a1e1963345286e258dc8e7d56718035f95f313811cfbd852a0f8f49a29ef933e7cda7ed9c7e8b162cdba1a82262cd4df7cf8ea4b586db43dcc1e3764598e9ca46673822baa2ad87fb14b6fdb9e2032d0ca51c26c5ef3d9f79785fac2491cdbf7c399f3cd1774c1a6b1e4a67f5436d80db025f8fb6409e275bd0ed508b5e039ed2e4eec8b0f4d5be99dcafa6a1401252732a65b37c943c07ef3acbcfbb3dc06dad0a88f2f5eb551a3997ad6c6eed95edd9a0af4a288d5e43286b2ac072977c436b7c5ff7ab61c9484f257f58e010c9b6ad41581d742cd19752cde54d2b420d643654e9096a81eb9dcf804c7c2ed0e38d13a5ce39978cdd02b25350945de78feecc0c2c22ffd705c3ba8113265c7b9a7c8ddb59178bd21d7f6c31c6be2c36749ee0f9ab8bc1dcf5da5cb2d2d5962358f71f96ab3792a252a519e415351f43e7e12035b0328f28208cf4be529d299aa5c128c9d5ed575bf90c5350569eaa6f2d5521de1180309f686c97e9ad6fa1ec1dd8627ae8951581cf604b8b917c5ba434a637be1bc8b79f4acaf7795f4e51aabdb885077bc4f3c68fc3318de5823d7e0804ee995b70387950f799353682300d4e797f3cad611b4c562c8640ff2b3fe292916a970fb98c1475c1f4e27b9b33cfe0d3ad932a1ebe6a27fc3b446622954aee1683668c8bd4a3f903be5c77dfdb8e8914cedc51f65fed2d9c4d03e13a668d4c7ea5e31883e1b3db64363e2ac5cc54b54ce69c6ad52f874999b5dd2c5782f03c3d51505df536a1fe0d860d33eabed641a940089f1297dd0f57f
+SIG: a0b6a2af15b6be9e951ef3f32cbd1c6702e8e017fbd315a3f2599c3f1a11865d46e78459a0d7f7be046aae293cad09137ec847e26928106d9aa35e0982b99202
+
+TST: 732
+SK: f8ff97032a34cf9999088058af56ff70b6acb2edf759e131faec8440fdecf6c4
+PK: 5438b4e33f1c5ea112fb1bafef4059bf095a11409b64d46bfb4d25473c1c0874
+MSG: dfb41fb9d53702cb2b9e3ffcad4ea602716f718a7ea33e21843e2a6c052c70c6c51485d72b53a5bb4e34e03e3e1d1a52518eb3e7f18f2a1e1caf78acb2116089bed4c617138e716a91431f2cf644a1210f6d1920d285994264d6466b0d8d2c62638044616f576edc7d0d93cb660131d4bb50875e153640123a96f15b75a5bcee46d5cc5eb1a431c59d2eaddfd5531502feb1551bf7791cd5989d17d10296d01ba3ae3e384c674526cab62a7c24c0ff677de71ca172621a28a85e01eefe07f6eef9c3ecfd7f9498ac42f46a43716f615318a3b28757c3a15f4f1c3822ae7a75c203a298258d753638cf425e15bbc46202b093b8e4f3e670fbb663db2b69c8fb0f625074d85a44d350e042bb1b74021d192997a2c27dd6c8634841d100a0344baed750a39ff5dcd9848dfcf09e5c8c47967b96556e2332ca17d8e42dd8f393a5445a372244600b3001b8fe86c45eafc6e738aa7e117b4a79fa2e6b00f464928d1856c83ecfe87dd34d158f5cb4e4f4d610f59717ec790bd3ff872040b67e8d3939e804e3b5db985a095621cbccd686c0934ece3e27ab2c6ce33fb52b111f48e4f274bdf320d0b02384c83c49e1a041bd2319109c85a06d8048a993357abfd811ac2f38059d077acbc36aa966c028903748625f92e8f79d51bda10f78522977f76ec4e885e49a46c68de09f3da8f86b71ae6423bd29deef1cc6a113eac115a6cde2ccd011fc1c0f0e3427f43c3e96fc4156edf62ddfb7b0836b888bab3c4345055a6c4178e9e22829fd8cfce39b0b8444eb26487cc9dc82606feaadaf4978694e6564f2729c1b13ab37c9072db4e9de940ee5f1d05884ae7fd9d9ec9cb7de56347600a88dea9208a63419fce29ee50055a374a8f22f9ae2be9805a9f47615aa59576b44042ff126a89824e36ad6bc58e06bb90fbeefbae5d6d7d62430f373b6296fbfcd4d6620168353583fbd3d5a292b9572517534e2fb0beef2fa98a464e59103e7a04287f15dad0fac54970e7715078d63ec26362f6fbabcddeaf7
+SIG: 509e9eadfe8dde7914ac20cafc0b0af22b84dd8a210a4812cd8cae39b0a272e53e02246dc8939e9226920336e140b31532d068137a34161e599a8694a95ddf01
+
+TST: 733
+SK: 2e4c39219fc92a538e48e95fbfcfef30f5a21b78940b81053bdad4602b4c9690
+PK: f8eed892176620434c7f0ec53dcff39863109e7ca4d0b3c6c4b56410be01e537
+MSG: c87d1fba9d94a6a5408980fc8083980fd2d252fae540f6eec19ed6746c29e339a1c29f6f53bc23fd6bfa438507eff5daf903403cda707b4dc5e844805d6b1ceb4afff4b232e8e69d7d271f3c067c4854f3d94f27fe325581faca79d1f02a26290ad23af71100c12c09157647ca9da43d7690ddcd94db65e000989c878b75a0ff22d2c70962594c9b0808f27846ccac8567bce5d2e3b7602809f23b59cd718a0805d108f31a632a05b8dfa5035ab9461aeba416009d74fdf9e007202856890d2cff80fa240b978a48270fcb2f473697bcba8e730a55c28761919a23be41da27ffea09e3559caaabf9519ec08e1ffa86817aa3e8874fa816e7718c5b2f344967ba1bc2819c4f045a97b40544ea61d717083ccaf11e9ddc04a3598ef181e7bef4acef45b6551b478a0d7731c4f08ce5802f78258d419017661076d7d6d2ef39e57cf9cd9397dcc5debf64ab82b66159f578316e74cd49f5ad2c6fef83cf08683b9570a946ad4903df4e96ec008e14a501fa9386bdaf2a63993c6c9bdf231fd09ea6f96ef4d4e29a3a3327cbf74ea831054e66ca86680c6ce53b66f9465d06b3fa0798bb6905ae38455934f2fb7e0ba472328989f001308671cccb566d222c72165bb3a744fb98e2210f9620680df3e3cd14a8bd94b5745c0016dda77f059f26053b64cf4523c3d429112fb6b328398bc630a2e906b95a6c5780cfdc0641be4751bebddf7724dc9c27e78d60ed0fd736d5abd88929c1795d473abd2b0320c540475728821867a409a2ff13cc44ce35e5981e9f6b87a28d4fa8b8675e503faefca7c1d7984737871fe919ac414eea265ee31f9f78f521f3f4f8d00c3fb79171f3c6a5dbf5e1ac8bf63b4c3d8d8bc121036e9e55bb702ea6c86e925ec0b984ded2c71f3bfd4932e6c41b582fd02ca59f53ce297445785cc4cac247b0b84e7fa0bcdcf79b3e4a155f9878c1f643be9c42f7a4f27260444505c1845bd53b550a31d7953cc738861f46bdf4870f3a77ace191abd63c45adb153909fb59ab5db9b
+SIG: 394520122bb0a564648a7a8bc8dc73636c517746a3c8a05b901e7252fef0e5023d90991e311b5382d49100e52633c70fe9c26c1450e0603e6d452299af4dae07
+
+TST: 734
+SK: f092e6be8d2d9ad069a3e2b976d244e34c15c28c48d32f5560a54185d1501502
+PK: cfeb3e74e4b5c8356a81757b8f1be4b429fc18fcaf497cbf8d8bc0480ff978f9
+MSG: 2c255fb25d45b086c071e03e525b4d728578fbb6b0c60da941e6bf2a4898b2d5b6988c53302785ab7a3bc4bb2c205acd27d6a4cbdd1a0c0889ded784264cb7c02889c5c7113fc90bbbcd31ff001432c053f971073cf6712f667fce4698776b98cc5444c692abd1288198be5ad5674609f7e139ad1b9ccb943f8dfd9d12c54ecee278341b2ee1277991ca62cd3bfe128d1392964e9588e2f97c321704a3de106188c5eb335aa5a19acc9067b4a94129b9d1a6167c4bbfb56fb97684cbbd720c86869e0020ab0776cdc9954feba862124b073fba8de9ea9a38eacfa003ae4f1cdcbf15c32fb6b970c73115ddffcd4fa3b71846110edec257fcaed6113604f7192572577264b9905ca6aed8daec138403ca41aa954278a5720b267b90ca163a9bdf447eade8deb769a3b49237a73516977c28734555dd234ca7de4999261bc7960f536ba8a35ad3d02c75f1c2bea0a0612e7d49c40397dd6af5ff58bae6a64b6a77e981f92d159e0b2bd205ab157052f47017a3e18aec944d0465ee0017e96148a6129f74d3ccb489fea13a15a9b9aced58c6ee0e6e84e05fdadfae07b334a98fc37f7e511cd5a44e9c74e478d349e30e29aeb46a4df01e4307fe65e1394a758f6ada2fb120225ccd50a49013e6c9f175af90f3fc8c57e7a6a969a916c3f1aacc22f3e01a070cc48e6fd878e2bd073df9ee6f059b98568404fc7eae7d4bf6fa16c0c803c6be84e8b79c67affc8c88cabdeebc1134bb2386e22ba4d2e9e0f3e1ab3a0dac7c80ddeed773cda0c41dc9defa67fea37769cb4a1e1522d7e0b3d7c4638bcd983153d478be5ecf2b6ab1b40124e4222b8caa4647bd50d74d203943ab20938d5f27d908a673674046ce2ef18e858b0a01a7e7530ded0f8cc89ef09b73ca597cf73afbc9a271a4d23c92fe591883c440109c4ef416670b7f2c5905b77f65f56d09d40250356f9b1dbcaf1ee2c0b63696f84d68ddbea160085151a9526274d7b846cceb6c4348098484de3bb723ae5e85276df49f5634130ff905754f
+SIG: 63cd4c0ba3be9397cc0f3c1af348ec4b8a91e42fee675da1d05900b9a86c138f9174eb996bbdf31c4295e0c578ac0f9d537641a2afd5dff93a39c5cd9d3c480b
+
+TST: 735
+SK: 01a247943afe83f036b6b60f23d97774fd23208edc31cf3d8820e9dc63661103
+PK: 8c97a58be0e847c48a6a3987cfe250a8d7b07d97f961f6b7b79e7d8042b8bd7b
+MSG: 08d81495da77f407255cc41a818eefa727e2c47ae411f4b541f01f811d906d55fb1e3c9c484df30565364de9dcb9fea0af66112fe75fd11ae81d2641b547589f8b974a97e7976ed692aad640edd288bd863d11c4ca9836f9d7c115c3d98830d64247cb6f8fb603c6981133552a3204041961bdd83e2f9deba770c0394f9b602a453551074921a3de28321369d7f8ca640c45109e8f522c97ed9f35b9277a350e295931b42e0135e94a92fed363d6cae392f7c45199327e24b4cfa5898ab599ae7bd50bd3a00c0d007e95faf8f2ae103802ca7e53b279184d06905f5748ca8be1f72e668cb83283dd00406491f8b9b4e5a9d4a5438b2fa4371e0b05686f87575baa796e302f08ffc425662750a33a0c9cfaa4b4d7041f9264fed7be4f9fde2cac68a2158236f6ac43047e911f4c4e8bc663fdd50517dfaa8fbcd219dd7a0e9369f43d0dd25b4f0cf930f20b7b7c6db9d5be0c6e1960941a3e04d141c03e5961aa33e9024477d533c995378796bf2292ade922695b14569fc339b3d9085c63fc6e5bef4d990c80333a6b57af478f938e3ee738b1d129bd976afe686128bcac08ccbeb0349b9b537313bc7bf591c65d4a7123ad30bdbe1486b428084748b6507f6f5ef67c26ca862cf726aac140b861ae0dc74bb3c0b489789f17145e9a855a3e2b5daac418d8353733239ef69c7b565b5303eb87bd7f649abf40a2f135a29ed27e3be4c12cd6ddd2e5418a99974383663f5849bf3ce5532bf64a80aa521191d25390bc19a45eed1d3feca1d9fcc0db031bfb48e450be3d4593356d5ba0f31047b457745f21e32ebea3ca6c35f05d78d8c31640b0fecb9401165675c7f9cbb19bc4b5677c2ccedc4e7aafb84184c19199aca0db21cf5067dc3af769bcc629355ff7257a9efd71a6a92d130d35abee6e70605b5cab93c028fac3aa2344ba861ac1e8ce9a4b070c3df740d28c5ece0f1bc31c2d7d1e5ecc76104480939133a18660e4a3e4846b2517be3b8e7afafe078391d8aa8e5c30137e85d94d64a279fbee
+SIG: ed2ced1a4fddb3442a637348179a6a5beedcb44c8e988ca26f78936d2c8db5c516d54b8c4f08d91dd7042ab6ab26d87f230eb2b2156f3ce2994fce7c2b0f100e
+
+TST: 736
+SK: 91fdefcdbc990d3e8eeb60170434da10831b03081f6afd0d7e12b10011e02aef
+PK: c58d3e20b8d47ba455b912572dc840815e3d885fa5917d1da48408b9a9564098
+MSG: 5b0c1a3a95e0ba7474766c9badfae34ab860e0a6c033a22fba721127f5bbeee8e2cbde1a1dfeb18d551c95994d21e3ebc68afae685444a3a4195bc755538903acfa6715592dde256e7a1b4c363eca71ef0f3a48ae3442d50d5661b394096b7ec27bbf52953f3040cd25b78ce475527e0cc59f1ef9ae2e0590431582b2df8141499829a2c5f7bbe3598e4c96cc01ede2f43b65605b488593709c094b5a042b28555fb5227a6d156376f3ff07bd5c8bc6804d39a3282ac5970ba08aebf7542b845f6b5c238c2ce20443f7f7755d75fe4fa16b9644ca3e21d91a9a87c686115748a16c0ae4ae4e16d1c71ae600b39cd25e5633b399fee7ff2e362bed25125c6fd5c7f5ffa2da2353fd35b784a1b1b0319774758b7390c44dcc92fca4201dfe1a37569de05f0664d08b90d6e2badc21b92f9ce872142357b9615080ab7659a246ff0852adb17dfda70cf1754157b13bc032b4c5deb8e1068b4692b93165da35efc9da86acbe6f80f01bbc26f575ec5af5b050e9828afde6c3b78e733eb5a912492f765bcad731b95e3ab8896b61758bf913b9a1568f9c5b46033cf45dcc1750da2066c608dc3d343738e848dc390cd474432e991d7aa2c5b2781421efe55e36b0b42c1f49ae277480b0fc5ff685bb5a31be3a0fa44823816077037548a5c9b0e1cc6c63504a407579a3632b3c96fcd0de5ea1e4d6e87c0caf7b6cae3120db8b1f4615ce6a75a81654f390428b64c213e727eec3ae7f9f42db906f4de1fdadd34a3da2aeb12b4d9a185f4a60cb0c26745f530b481fc976a093ce24a30916af605ee94b08785193a949d569c4b7ef59603bb624360e7b408d98ca509daf5a92a6d4015bdb6f97ad4ff0cf05c8f0cd5476a934426a059f2444446e5864f089e0f0675615910662d7c1e79a6c75fa314b7ba2c643b0d37653eefe593172d1d332c8dd64492eaf104fb1957baa52049442d10b56af8eae8ff82cd8f46a0494bec2fcb9fadf10cf71a6eecd0547dafdc7adbaa4503783f943a46b4ad0e6dd7f2cab55617
+SIG: 510112223b33a5ab1564f7537191cd292a9dbd5a323d7add0584c1b0ad00d0ac7199c3fb758e913ff3d716c2e90dd90d4e8f59951e87ef8b78214a5175c4e608
+
+TST: 737
+SK: ef00b3c181f6327d02256751cb51c2c36c0c0a78076340548f5bc070d86d9e26
+PK: db14cd32588fd741e8f42e5121cc811ad45063f28141e83c668f07d91228f049
+MSG: 7d6abec7a11af67324ce17b1d20bb40c668a219bc95df05e325d86f88795e264d454fc5fa7d9c8aafe77e90a6af6b57453d85b970b552a856ba659ab31bd8a660eb7d3587b453e5c5fc6b79472b26e8ff7dd6db6be3572548b0d754ed4d985b8d9965f88b952fc4fa3b761ccffc35354db0eb9c5a171718a8a5592870213827d3691bae7fd9c63f20503e04319b5e953579de47e3ef8e1628549503cb4f6871ba25db87347080e531a517a8b7221e6ad84dff83256d9ab9a433de871b9cb9c5044589e67206b317a5206aeba96c92fd6094071c644fe52658ded9220cf6abd50e2305a1c90fd66aacfb38eb05eaff6ca5f85f429cd57716eb87739a02b64cffa08c4f685b00310b5b4844920df215a9f24a17613aef85fec94f511dc8a4294eddcea11c08c0b399a23d916383e29adeb98c65d41c705a57f840520fa808d7fd25fdce159f7a084d062974b30132a571242baff4196246d6d757b312e9d608553d2dc53b623b2e95c7538fbc5deb62ba73776d85e5118fa1a302d4d076d99e100f0df119c33fc66cdfe6fd44d71997b78c8f7890c707346056220d1e9de88bc173cf0b76cb302877ec16af46e4c31639f54eedc16da9d9eb0ad95bda545dfc4a732b6da9814136ab1b9392a071b022473b3490557698b77e7447ac8590dcaf4f242ad3dfbc0df716cc0ea753626973df08d935d178e3312fbe2a7ba9c5093c53b9255eaca29b72578e3ba1bdfaf0c9ece21a5dff6ea421524f70fc1904e9a2cf7c518bfcc7e3673ee87ff27e1ca2ac32bcb4091cb34a82a71563ff6a6a15da0ebd5bd10256ce960f4eaa7fe35e128886050d049fec3a4ab16d5b0c107267eae1ab801ea5b91983839da1c488c12f864d7c3a77f2b6ae27d540109f68d78364bb627183bd503917547aaf3b3a1809da02577b3f03a9a3f5af48c8802e297c8bb63db6a86d3ea727a6d7148b3aa444b8d168f38c6c8f24088a49af33177a344adab2cf6e08e0cb0371ed52bdead132f77e7ae3ee5d8fb17afc0a0bb7311b9560b67
+SIG: 139f9cb99b995be6588cddb5051694838f9d82a60761fde304b0027ff86584bf65c73cc6d253e560f65525df04bfe146c83b42269cf3780f8bc392437894ae01
+
+TST: 738
+SK: d071d8c5578d025949932aa6bf6a80b1cc412f106f91574ee24654b445ee9a97
+PK: 9bcbf7d2212fb62cccf8b6c76803a5ea24409da6287efbb8b1f0c7b30ebdd93e
+MSG: 3e8ee70e51e56ef57f6e66b3a884aa04a7b4d4599fb9b43996b393a868093512ea741a0c6a94f40ce49862d2fd1f7551f4647abd8075bc1b742ad40e29a60461301224fe8f7692b14772782b4e896b63fe05abd5ff5314f9ec8075f28d908ccaaace5e905ea7f57a491b99b3591eea54a6b7819167749d38a047620676a1a7af11f485a55b7c879e6850380858c8f45c0c1ccbd7406ed099d84a7471b9350c4ddb28470bf5bf327d5b3c22d899b4c660839e104a0622ae85c84aa9fc7f0a2c7ceb6e691c49c064b5313499683e8e03b2115eda7ddad55a49f9fbe62544f914511cfbec6b84dbde7e80909b45fb10502e2caaa72124fd9456a3872f9592707e9a4c5012daa972eaf65fabe553debe825701efef5c756bb465e966ab68dd52f3dd00a45cf6dc3f19b86bb0db4a86e4669885a074696a67d8ea2118c766ef625f8a98026f9f4a3c5cccf9846fdc90ed93ec7c1f3c7086954fa2f0a4ca96d40184aa57545527a1f965c11d843c90c5a5e08d7c11f2d561004e90574852eb5046aa1ea7b61009fd5dd7d6242a8df58a9e8e555c7f4cdc130d6901bfe6797fdc6c39beecfbbab6625b2e4fb9d8000276d4a94fc6fc1051fefff5adeb724b87090db0a2c697d056664d991fad80dc80fab700b1f1f2ee27734ebc26b2a641c32a0c911b270ac76b0da5c08914971c9112463a70709c0ddac7910016f913f6210086d7255cef11955710f651889c83621dd8a4fcd5366302d6c9b56eefcfac85c14a9478b6d718075428800760515cab5f3d4455e2b970df9fe4be8383d70483bbdd756071f53b2f9c275c7c8512d163518fe555837514c86776c947f29a77570287446b69be40c8d4abbd65ef2507249b5aec33acb7b8bd3f35bc859ba4e37bdb49cf913d93989c4438d2abcfa388cc89d78ac06270656492e7528f29bdfe8cbb9bfa9e73c1da013fc3ce2105657613ff62bb0c3bf4dee3b0d2659c726e7bcd9e97ecce9247d4600dfeaf60444ed862b00ba11e70ea88d4f0b6b539fc9f36bb2a1a9ed2b3
+SIG: 0c297abe0fd8ebcc6b771998755e2c6be07c812b5a80544957063170ca69432e72b60daae322958a2238cd6a462894a387eef65bf96f63f54c085687a502750e
+
+TST: 739
+SK: e9d486c29ae811b942e10d81f0a6716317b842c2c5bfdef55cc432b7fcaeb818
+PK: 43a52d15b9f731d737b1c4dbc32227a480963091d2c6286f482ef1e8367054e5
+MSG: 14fe1ed5bbbd76cc73dc5650bda92de86326e24d2f1f6224ba8568944d6fe3442675db96f1d8498f1634ff9b6e50cba9db4eb0b0b021b2becfce4bef33c4ce0e32c8a98389eca9e059a662d6f037c54aa40c76cdeee85650f089ea56e1383ab0f5c36f6d6645ff7e87667301f944fdc2ed35b0d2c35cb2e4b45636e7498e927f5846b3e1edfbd160a4aef3320c3428496bdaaf7d3ed56ef0b7254ac597be589a70584416300c1adcfba4f22cfd4cd661e1f50f155d172fa5748d296b29cdd7eb8121483ff1d9fe953f9451c7c7a542007285ee7246bc0fdea938814029abce057a0ecb974b12d360eab6afd30797d61445ad2bac7e52bce4346315f78eb87542d59528b2f6c56d66241cb442033f643d3d2a67cb637d8da95d4fd1234b031a3e51723a1d26e6f5ca07987321ad11a90fcc1d4e2b0b896650c3a7518d565529bea806a05d447e08d2a6a3dbf1a36915b2957ca5b40e58b97ad0369735c428bd6d69bd210044b651418d98b059d90c83e46011f41c032c5655a5ef21ac2c8c2bc94be07e45426a7ae5d47b45f27cf4289ca4ddabe08a12b910207dabb34a46ab75ce69b58e7e17664bf3359a8fb68eb032c9eaa6df873829f0e0848553f732e1c3c084b32b7af75074e7bbaa4eb5d7ead7aff97580109b60f4c792f9e2a65137b0aa48175b8115d91305f4c77e2d08e7e8d7e7785c966842c2e350fed4f9e33bf6e184c550b4b06e957414edf52fa079e81973458461fbb9b7d7d34bef150357f432caac3ae9f3dc96eb5a2d123e09eda1702e1d1070177bb220c423c096ec24424385c679be02ef84d09ed102f49cad3b1fd670679a39714ff1d6e4228d8d7d0e19ed0eba132f2128d47baa569a8ecb7bd48a826282f9cfcbf60ddeceaf1d02132c8affed3a03d2340deb787cd649c51c6ecb9ff75d7a7b4ef9b15139cfea2762ab18615197a6b51f6e75dbd04573a2448094d0cdeb0fe4585883ff9b68824a04b83ec91cf84acd6a7446cb1f5ee37d5df80f17cb2bdc3f3122a8faf76ebd06cfe817
+SIG: 65191aa885ddab9f67271879952fc6affe41ca20eb3bcd86673161b03b532694d6dd88908eb1b1eec003cfcbe6146b4538e21df55969912a0d7d8818ad79590d
+
+TST: 740
+SK: e6fa10dbb478e1e36b35dfeb0250f63c08515070ae79b22f047e271708d64f5c
+PK: e02e1f2bd8792ef483481c6d11f7c7c9dbdeecc9859432e7f279e9d173d31164
+MSG: ad3160758d8c08a661525c95280a3718874969859f1cc918e34fec008acf23b8896e8d50c3c0512331dc89780f8b10fc349c675c4cd82a5df8586b43c864448fac00b847b9c98054ab793f63c71aa5e5248e22d069bd3f852a3b8c6e2ac8ef861d90bcd984bfca87583e59e9a7468f29b808dc2fe5302a989d6f2ecde7585cd9be4e4c761c4d4b3eeaf4699f6556ef039af2b80f9407605ac397351dd85595584495baa177b08c88d2ec1fc4e32d1c0b8d7e7ac5839dfb923f09b323e78eceb7e96c0604b01a19e49c9beaf4f25ec4a84c1a08f2380eddc3a7f012184959ccd19ecbbac65eaca155cee9ecfec11e7fee058e174fc4ed7c679f2c15631d4e1527bcdb0e3bb0815ffdffc0c856bef0dc0f5c8237f7098e26bdb69e8782d1ca5111ec3c7edb425dff8032026cba3d2e081b71310db9badad1ad02f1eccc537d874cd18c6bb01221f71ee66250d94cf8ecceaa96d3c57eea2b0a8ec72429d7606488bdf19ec3bb16e50867c7937def09fc783f20a2a5ec99253d6b240df4677dd2d5277b01c5b8e5bd6c7df0874205bc8c2fffdba1314674d31c9b2c9199228e19e0421834c1657d0698286916c7e392f0abd5545b963ac1ffa99721616c23796f85c34a5c664ae81d16b216a5b0cf5bc6b5a908297285d61644128f886f38af9edd25193d7ecc77a79994278da071f54495937feef5a51957527c3eec7cb0b4e8aa7a4e856defd57dd92334151b986aa69ca69260d1e2d7b53c05677ee0d216b28d036252dd3006debe1b6574a25e6b19dfb48fa64316af8fd68d7893b397e7db5780ab27bf8726fff605d3b46d800595b4624bee302c964326034b5234d175dfdcc2ce882e65b3d93a0438f692e9695de1f24c70a79beed25415ec5aaecf3391953b2ffd453a8f0467561a4a47ee144a43fdff83df2bea5f66a722b52abe8613f20c594af0982eb3f04505a52461dd034da86c36ca16217705c04823911d72a24769517633562886f250f2cf788b8f32864a9474f57e62e57de8fdaf959a6b72287440a8
+SIG: c03c470359127e9de3af0e0ed7d3b19faee0ec140b79c299e2cb6dac0a3e7e314141cc854b4596ce4c51c7b0dec8a5c8cf0936205361d5365f4bcc07c4287c07
+
+TST: 741
+SK: 058e3680b8fcc0aa1490089c1124677f98d74b1bfb71ee8663f025f0d946cd20
+PK: ec72ce0e82c6a3b21243d2f00e9e883adbc5cb63b3d936efa50c07cb929148e2
+MSG: e63d14f5bea7a1abb8fee697746c2280dfd0622de7357226cc0742722a3229be126b083e868aeaf07d2fc97adc3342709674193ca281744e850ea15440050aec930e45d7a87b8ac8015c8967c20033a532d29591b135586ce0fdd2e668b5c864b3bde70c7e719ad241931251861933ffbfa96483ff82856748c56dc26e257d692e5134d82fc7191c110d9590d3fc751cd636b0c46f44f8803e59e2f93fa0cbe247a1a625b4bc2c7b1fdceb5a2b22591fa6137c5404dfec6a69639e3f632b5976ab9fe1c63aa3da9d52b044008f3ae44b7c364f085664323a88eb4583e87140f763782bff8819cf741a875d506c929d34bbd43007de4b18f687a758111128b1db86fc5ad2fb9fcad12c9dd28fee5ad10de0739f8efd9bff66f840b11b3f91c5e07c21452cab24242b6e32165cd1e69572bf216e860453dad2fd129c333758580bb7d0f19509745e851463d127a5f9be21fe549cae55d56b8bea80bfafdac10acd838ea8af31c007dc32bfd74082d9110a3e91e61e0357587e4ed32827ade9b6910a988c1d3b2dd22c0ee76ef35fe15e099404a45d4b2acab9123ecc45550a40faf8336b46c630a9080358ff8b8e58af0bccbd35010c1ecc12816655a5eceba95ad3f503a18ec5bece3a33f469dfe917e1c55ef1d81e5a75561e6bbd99c653a6d095b9f387911e40332f6216f956a35cf7d99a9fdd0c44c51e90a564f1c36bf3d40a7faf4ba28b1a120b3205fbac1a98569290be37c58bbd745ce0fb74835270aba2252adaec157dc42461221a2cff687b9e65ceb57c2d77700aea6320486c5b1bec9cc53e7ef9e48fcd1b7783acbe75a6be0267278812dbf3d2576cf7ad3911271acebe0f2c04602a080c8b96c120fd86fda282aa4e1c131fe97c907c15855f87755f511c037befad0f56b39f32a2133a22f3d5a9bec3443f29a694e97fe05e10fb8ef9991302b9e0d84d929a19eb03471f3a8613d39368e15883a7e4970b53cbaf2929d8de431b48b435d7533caa2e36ceab6cddb346e535e515c4b3db76de07d9855414
+SIG: 5734ec50a7f82e48536bdc4370cfef2e150a631dabaf89edcf0fdabe4f5839f4f5fbd8df8ec4a3acd40a8bfb963d1855ff9274dbc33165b5e6d37a239dace903
+
+TST: 742
+SK: 51ba3a4f3d85d1548c2f2494a3511f3b9515663d7e85370fb6150237e9bc980b
+PK: 7749de0210bce06d48f59b95aeb1528fd9b4e52cdde22fb8193bedd5df12817c
+MSG: d18d0cbfc16d0f9b67f2539ad6207cd9217ad5ed0333cddb1041e0ac2bdd920276629652b49cbc9802593ec364ea795abcd1582085f55bc66c48fd3eede618d6369617100eaeccc15f249d6eee5bb2c43c01b0623fe603ceeee49b40fb7c53fc68473673c09b1ac77ea9beb7e8530379a86d69ecd1ff11813fbb88f692f05ef1320742b4fe7e06d5ba71656646cd7500de19bb93d844536603f40bd4aeeaf0c4dbc0acfd202b286b64afb83d4a378dd45ee3c1df6b3ef16b8b1accbc04063250ec47b86ae5a71d1dab38b5eb80d663faa788f8b59a754c0f9c9f6d906252af46ab1fffed276d2388dbe70d96ba6747d1fed4fc0b55293d5f787bda0c0df46a73f4aa7d29e1c9cc85cd043e3dffe057462ca5fe5c6470e739276f8b534c0172e460f340487a569468aa5890cc14f20d67d79c661e87febac6275971c3730807ebf175e0de1049bee67c895e57b71ab8a2f3cf3641fd548d09414f5fc3026a0a35f6ba951673944941cb236f3d1976dc69077d951450e7660316988f6f2a6fbbff3b37ceaa02fd6f0273bd803185a109039c63f2519b983daf6554253bed5497c0b0bdaa0bd4a1fac90026ade3e40c554cff2ccb36990e71556708c5c4039256ffc7337e5fea11f5e90d3e4d93359179116a85c24136ca34835cd34012e4d7ddc7b721c246c73700e276dc2ff9f2770b43c8e80a17f01d32680bae228e6423a880c3fb996ab8d221bc6274ac5fa770d205fc878fba9bbd776a3d79ed77048950f36dc0aa3ccd28e4756a991904ae051b8a4b7de3a1f2ad0fb45a33d0c68225841f8eb65b6a16e95f893591e1aa73a64f0d2ee938ab69adcc8c59518bec501c39f139174bbb00699e1a0f0e0d889aae543a55e6ac56d5204c1ade1f27d82a6a95e14b2d6909dda7bfaa7f487fb61959014b78795cb4639f09f0d329feb35ccf52edc2db721914e423306889a483fee876360ee326335319070c564f3a8b953f52f41513a2260883c38dd978a248604a41bd4bfc9e84184dc9e84d2589f4afff8417824ce5adba
+SIG: 16fb290c913b20eb1c3d7b798249eb8459d4bee8125db2b3f1daab8af9d9a700ed798addd802dfcd297a412593cda7be9979a1f09350e86f698ac3380e341d07
+
+TST: 743
+SK: 7ddec526a4971d8912a6bd43c69f92ed86442b15f42fbabbf2d17eff98993161
+PK: 0dfeffb2762309b4734e4ce2523cf1863149f7e19a7c147ec0899e110ca9d87d
+MSG: e8774a45d4d8f86dda5c08802ba2472ef3c8d36c7f383ac04612a464382e9d6c07d8d35822c53f4388f5153614fefaf46374747b9d4fd446a864769a4cade843c1eab8574319112f0179d2ea9e3c195dc068f0697462b9e07c8794870f8fb8ffc081e4586afbcdba7a4f5925e9fd9ec942d8434733c2ddd5e29bbdfc7342b92868719b544088a48eba4c82f187ddca8f474625a71cf6b7aa5f081c74f7408f53b781636e7e9d29b07fdb6d9c35e5eb382db7a31a8ba516915df8dee9e1ad3f182843683e8d1dc5d8669dbfcf09541a43c0a04613381a5b5e4e71b23c5ad09b8eaa51cb938d0c752cc3d3a10f10b42be8ee7f6bdac8078568434946bbf56da70e7d54157a6efd4846eb155278c94c3888658a7a2f8ea3bac147aa891692ae8b23f1afe71ecfdecaa6c113b5caaaa19398c7dfe73facb4155fd6bac18d5df2129e8b2907ecee151bdd147a7c3e46ea72754de32ceb066d9db1c26e80df3631292b16174cfa6f1d9c0828b849c22d29651a73e910d9275877f464ce9326c6e4ed6b07dcb3a35363c1aa6472e02c5cd855e38aabe965ace9f3f5a4f5de03008694cb90afe416c9d48688de7f75cfe243ff7f41e059310934903db568844508262c899dfa750cd6a2829824ba027aea1b6d0177726a343add4ecdc5f7e6e909ab7de615ef2807f9e7d71ce2f78acff57eba79c3f5e07c8b661c1e3027f8176d28bfef767dd68d4e5d628fec0bfe88799341f306128734fad202aafc9f11123fb3e363d10aee0db5e27a1570dfaee47e24da473b07fee59a6c93f0981dbe325cd8cc2d2ed7dc17166b267c1b110536f2636bba34751a78f7f6298182442d83c123bbee4f50c5b0facff03e7c556ed9e64ca27c4bca5ab0de0d5f9c2cbb54cc2d9473a32df999390ac2ffeed3d4cba34973dcec3fbabafc4d54cae4e7e85d4a6e8afe45cacd71e0f2e6d04b4f9d3bcf43d3fa41e998ccbed0f150d5ca1d5272932d93eca10495c68334fa3268f31de522cb12a7449ffb5cb5e8f1462cd9b51770ccaf58b1e0d82ef929
+SIG: 9e603b015f42871b78eb27523fbb7ce962fca32ae270e8e12dcadd25aa852b891f6fef77b59a546c9a7a7cacb55e1d32adc805ae5f61a69e6764c7c08292eb03
+
+TST: 744
+SK: 0b6590dd7c2f15f94a56e240169363c26732302b9d440b532723002e155d02d9
+PK: cd18e032577c5576f223f3e3d8a1fa8e9a870fef09e9409faf40d7143e52fc44
+MSG: 71fe0fd55d5ed1206f28ee16e419fab6fa66a251fa6b0601da261e429f55b8d5ae3f3c52a17fe1ec734b810ab63aade4447039ca0ae4687c2435f561e46c5b309717ab31e0f64076b2169211572b74e18a1f4525a64fa717a5edf149758129cb04035e7e20ba4005b74809dec644504c2454a77f99b20c5374f3cee7d8c6b68b243cafb30098dce90490fdc3b92f54948f424639e19f8f2020d15513daefadd9e9b12a84761e5ecea088ad561f06209fd4423fcd003fbcd1873ea54963a2fa07c7476b1388f9015d9eac305bea5a3de194f55a17b42d599e5ce62c8b7c19e7e7096137b9d0a65e63c1a3b84538ca65369a20e8822fff5ecb57fc09b4e6845b4f24d4886971ac1ac28c77580ea5672ad14ce4441719c214546d0736cb7ad0bd9fb5b26c6d9c536bf8c857ae42577b36341d392b43323bdae7dfaa491986872a23d827c6ef8b57e7d00feae3834c466400aad1d367823984aa02d2ef492914ae1127e7551b812559378305e4fd52d8bc7e4157ecca451f43ee9f54c82153c7dbfaf7ec35238773051b4e587db136957ec571382b90590b5d1026024580966b7252d2cd3f4f1625c485ba906bff175992188978f2d6274f3a031749ba7e702f56547edc96ec267b84892880d750d7310ebf6db241253cabe4b25a977458c6ffc9e353e62adf05e6efc0fc1ebe89f527705bcc26b701285610d98aa3bf23872b6996d3de480e8d09d783c4a08cd383c9012635aa68978b5006818bbde44f2987479bcb2b711c1beeed27cf09970a164e454f710822eef555c1c7bf9f76d5254ce220c9aaa716847a249488f9cdb44c48f452ab52c40f6d03adc8bf3f197b25e3d127830e74fd81eb14f754205b3a4844c596b6e3a9936ad6fd9e80a16320b381c3ffc7b69eab54536f55abe22c91d898408e880c6dbf0fa5648d517772caa5353b25db6050d753faf198ec1d375de0fa72180a93bab03ded7716cb87505b68ac6a35e73d0fcf34457eff82178952142c7bac9dfd872a9a82f85b24b88fa42d4be0a0ca0b2c70f4c622
+SIG: 642d81acf38cf099a833a74f2d80b85448ec2b1a5ddc64470b213d54b7be6133689a7194f5d89792e16e5df755a4fd9ef4689ea952926e0e4ecb3bd481fd9102
+
+TST: 745
+SK: c6d9acc5175fa2b8965c158c56ba0a5a666ad2c740cd5bb679bba9b1dc509284
+PK: f5cfca211b02fba7720347703bf1631cb308fabcdaa67429527c5b7b676dbaef
+MSG: f245100cd2d31648f5f351bda564c9db4a35820cc30ef651337c4cd888070569d117a934b9c918e5df8b3744dd6620ccbc49f6b3e5782a30339dbb9cbed05dd2b3b8c5bf1546e70af636e6615c48b2c3c2d19fe35420df5314f63c4812b58e82a2a60b1802f38e505ce748017afa977d3f9b1b6bea2192acec73bdce12d65e684da4d8b41fa9a86f11086edc2d5296f67efc53ac84070fde13693eb2318f5a8c3b117c233422adcdd352f328f0ec699a4650c93f9b4a7d795d7fc2622a03d99b64f7b3dc3194f6c3b1b69d9907ce092401073f47a28f4799d229092a1b074129954be80ca4a3e6582ee05c302cacb7431d1ca6a451aaed7278abc7f78575241c2a2eea2e84cbf9a334df402109c028e345473a13af9b008e20bc8cf0bcefbb7aa727ec856e9925b4ddd99deba8f252911a590154b579a8aaa31f07dd5025df5cd8a09f742964cc8c365d8aff4eb1d79f6e5a07dac5f4ede92b4e2e61d34cc2d4f0aaaab037ad5fdb95de6cd5984ebaf7cce7f08d0ca0dbbe483ce3cb35cd790ca0427065a34df7f4c2af86efe9b765713aff257f5c1d54709527ad18ac33abcdeedb208064ebaea4835be4942b8fc666ad1b79b6651309e5ea1da302d7fba2e99f0e6319e82b9905a1ea482ba043b6800b330dc48b3313f59bb2f9e8a7f07eb1800a702745db14c6299a982dad897954445b7d98eb5837fd70bf190c649552c8e86feb7ff5b3ed8e0a06704d4553a3c2dd74f18ea8233ae0a50d914fe08fbcd3a1435fed56a9f3a7effa140fb552ddd21dffff7fa47332ddfc1e5317f4177d5e2f11a06ec84ccfb89b654ea81bd42d7e07a387301d0f40264abbf9f9107b30ede864cc7690c06d2e247a060bb2244ad78ed5c5515a1a2a612d61e3d931e28bc939b4d3435eee4f7331b1f0f85375d82ac9a77c43740032051746dc9269458c147d188d84401954a489cb4fbf9bf84ba7d8f100903ce67831b4054d0f58cd883d542c4933103ff070cdfc9dbb0fcc31efca466e77a33f1a813da6dc0c7c31585e8f4fef1ebf42fbd1
+SIG: 4d2ce707090b0f3f41462fd75bd609a2724fadfe5ca390e313a42cab42868ed6e9a8914dc13909c0d6f61e63712957c76f3bd8b7f55349715a3a317515c07108
+
+TST: 746
+SK: 7dfae416419d7b0d4fc1f823840c3e4bd4adcd4dc2dc17b38637acedacbdbb45
+PK: bc51d7745931317e1e346e2e7c92039181b6bf38ee2f5a44fbe2339c4f952ab9
+MSG: ec843dc4dda6e902e9be31b70f11763b757ab6ce7334dc00764b2d084e9daf2484485984ee28a2830fcb94c541cb469440036731de80ff560f530c9d9e6e1f7d9c4c5bdf50b04f5403c29f76d7e36e00bbea35db1cc60da8d776526266c3324ce7efec6450859609266856d701a47a48dee8bf37409565c7fbfa99a204e5530c971c605b44305d5c7467894114253cf43cddf18b6296dd254a4d96ac7000918186dfd4bf454ed30974c553d0ae151ad4cf540cecaaa0b5948b0985a9c7b6e7815932bac11732fc7d10267f6bf8f1e7c08d650e567b4edd15ae7958410e42f1f537fa732f727a268388321d5344c4e78bb9a74eab9d6abf968965c66693d5f112dd4c14fdfdd96005eaa6757fa2cc1013fe4327ab0999d117f3dbf325b07cd454d4b141991ef7e23db5ee24beda35884aa3704808648aa43cd6256259f7d3db5e055311f253e8b57a4cda5afe0b0adfc364e160ca37e8dec6b95aa6152e5d5da6eb91be0e44ffe8e49533267b7eb795f5f8e0b2c35b29dfbc87585f22bd5b909dfd6a5edc0e3a9d97b0c4f3adc51e969937c08fd65f537aacda8f11275af02c3354542630f3920c393f5c42b9fc633de9d94c72e3f20002349ad0418035b3f25f02ca928e5b2d40a77a1c3e56221f4b9db0c25b096d6e5d0fe758da2c69053e8d086def4edc6e3453783ffc63a4960122d923671a906008bac10561ae6219d2b51d5367bf13ccabf5931b9f186eb109bacde40e1af2b56481e0c6dc6f5c5473f8001cf371919acb40cec5b962ebba80e32d6ebac4806d04d24768c2ad2e3f92a8cbe47754f9bf615953522b263dc24937fbd932c8c459eb8b109443af6c195a59fd2721b0125628f2b8143cf3c128bcec1392efd16b734c10716d96ba7d1f413917ccafa5bf5f83f524fe8406a152115ea770e1745e82e8b51d752b8bd785df48bfc12041bf874fc73afb42ca5d69c6416479ceb4aaa0492b6ff21ee12db2213a4286fd5605c93a7bb8a3b071b0b25fb01d77abbc8771489470a107aadae9f640c24dfd5328f60f4b7d
+SIG: da34b1983e8c55e41fda8ec8abf23b367a0da606c8cdbb1e8b57e0343c0557a5f0e815e7f22f8605ae93b27d03776ac1f7de3d792ea2933ac22d2dc23b323d0c
+
+TST: 747
+SK: 709416074997b9c9af4d37a01139e8a3f9f2ce5d72a57d805e822a81186d017e
+PK: aee110f1f4d46ea60649d786b150052e287a9da60122c47b0908fa8b2ca28a80
+MSG: eddaa369c0e31a1fcc1da46f65362442a0cc21c7dcdd5cd90e0a2ee9f25110812ba114931c868a708607ac16084d79715d13b338c05c6aef7343e7dad282f96fe28193188f0cc893c7dce805fd3a7cd268b72894160b5245fed9fa9943b7c80adb3c2d1a353d8f12df25a31dde7fa385bbec351da66f153032e17756273f8d54e9a3b9ea25ae67d1e9c18cc68be601e3d68282818ce0e7cf88a4d1336453021732f08d9e76cd23637929b0911d5f8614f4842e670c142860afc265c50172b13bfd35ad8fc54b28657da32bac153ba9affc897afb3c721f48caa46240585710b0f2d24d5ff4965d1d10f1a07b06abea6a08e1d6f1500da12c434a6d778c941067108000475ce831bcfe2d0afe40b7419d07059bc0cd8dce4be9587ff29ad8bf0b268ae23ce0da5bb5bf74ff0b2b31b82112a9fd5abd9bfd0a90e6f4723548c6bb2f99dc061ba32eba2d53e6bc79bf441b23fb7460de04e8e8efbcd4d4cc7355de9e3b0861a681b983839d4488e551751f23e9a6e2e4d443273b9e0fe64d8acd1c748b5559438223dd21b5183189e0f3c0e8ed414c0356bab77a654de1a5771462ef14344970a491511a722914f4a89f4f1a827e18cd84479cc92592eadf8de2df824b976dcbd284a3ba64bcdb0df15e8f41c0b2471586b26a06353d905028235c1c6e5c4587222725af083e11e79c943aa444d4aa41218d3e974336e372813e99e2b0c5f0ae810ffed9a7a3d6cb74c5473d990a5911329b8e82ec6bf2bd4321bb487370f8739e7a2a4a53430833d45b9fe3deb93f79fc6a51d563695ecdb97858d213da584434b7c71546aae8d967e1c6d0082b10d4a72de1742e53c4b2f92eb8b5c8c35ab6535ea8100b37924a0a91d2a728d0f5642437aa66c82ab74b5d0745ec08f7705cb81fa079d89ecdc9aa1f8d7d82dc7746d34615343a6925dc318f352a2b45012438424f9098fddf6e61fd1f8fb49da40b3eece89a1af1996de70cd1696cbfd9e301ea5f4437c71ac2a032254c140a90e85fb8ffc4667fa139c1ee9bbf12eed906a967bc0921
+SIG: 8e4b41f097d83614184ba7f52ba2fd9f0565f8a63721ef55f93162826b9f0ac070c0e2864b5ffd8eccc18efad18b2ce84be57c0b4a41c52e20ef37722377c60f
+
+TST: 748
+SK: 3dcb7ae7d9f0f141f1d9f07883635b913ed29fb61d0f741c9afd05a27b045b06
+PK: ae62b7ee1b8db5764dafddd9724acc106d6c0a4d1e85d8906f7584b558f577df
+MSG: 38116a572669070dd5863218c91a77a4ab47553688488c792838509e9aba25067adb7ea4249848009d914ae987a6032348c1c0681cf977a9552dd6bbf4e6ff32acc9fa61cbee25a39307650f8ba6a7ce421ef2f71bccc0958138f9324c86bf2e528fa3e4d1b19f9f2ca5268409b8cc19c62dd979b89697e457ed2d98bd2096f62d3d9e247388795927803e79ab71d4f72f568e945a8a162159d9b84836e4585644d4979f614aada73ad413a83391e9cf880c42ac2a98343b6a82cd2b61581456f6de5ceb24fe46b7625d52ab2c2c324ac74703d15e15f1aeff8055d2f739f7363e16ec1d78be2c6299436c8c8d336bd29271a897a6ec932ed08725be21b28f9aa14eaf4f71853154db14587c930ab3eb0227ad7ffb45b3baa6a999499cc8a6e45b1ab4d0b339782bcd9cfbcf88cf7eae891cc841e9c88a1f6a691f3948a6bc85ba7f4611642e84223c3b178946ddbeddcfcdef4ae4c4e1a814b9b1f02b1eaa824db93f44b27d14206b340465a1cefcf535c63e55c4287224262733d98aaaa154f3ad42cd8546a461ce0d46d886d3461a2150cb45dbe56473ff63d3dc7a2b957b823969f19b5968e8b424c879741926d82c6386753b0fa1f080284e5578942363aadeb21f8e1e8909fa6c380764149bc915b228604efc56d92e4beb720edc74c4d78f925d6cfdf7ba2f14b5623775810d2d07bd388c573e36523f215738e69114dcf8d80f170bfa676e31fb626a7d449ed96647363475970c8c47809709bcb5e7200f2a227c7c8e7b000f30c0bde61d67bd6895361629a36c8fdd5a56b81efbacf15c1b3530a08cded5b1fd457fbd2f03042f56f1b37ed15cdb912fa0298c276725087ee27d3cf2550fe6e8a0330af417f4f5baf03627ed67c5f8323363abac5a1fe34823180e3e0e2080f75bfd91c207cf6baa9a229cf443dd442c5902e0673f3252b8526346585872f6cd366025a56992b70ede39bc8d322f9c22a1dc599e9f0d524cb6d2ea5ae2878ef6bed4b702807f1e1e73ebf290eb6c0eeb85c13716f626aa90d364b4904837ce05
+SIG: 09a1e6fedf971b3edbfaefbeb89aa539ca0b02b37e7ac4ea8920d6d4348ee0cf9a2d5e96fce517c665e7c38368baf24979249a95b70ea7436c00785f16a3ae09
+
+TST: 749
+SK: 297311ddeffec9d2be68ef7b2a20fe2d277e1d8e51648b03572ada27ec1f9f43
+PK: 6a6c28e761640c4008333aae5a3366302e2f4677a953ba482ab6fb4a1d70b447
+MSG: 2652acfc3bdf09a599ec6786bbd94fe577cf578e0263cc68d9f57a6c83458f80acd8a75ef03040a635672b968ff2afdb288d28b9996f6415b2f3175e9ea37aeb05df81812e38a4c976eb92856cedb91a269a46fca5df9bd730fd84452b4bd93577c61f42c14113979882a86a9fe632e4756afd89816fc4670a310503fdaad2db764c3721213c3e60f29c2668d4de8f42b087f25cd56c69a4e48f134f5598cf145be638a5c2318863329061729aac91da6a191fd774880cf9cb555eec15b0044f10e5433fb46a9b8892da8f6d24f142588b70ff0b49200c506b88bed449ad10d3f92c2baeda6bbf58676c5bbc67d31f64fb12e8d5e78876d5c849fc314b2cf8010c510204c8633d0cc31856ec6a114ea8a89c48927b07a31ab842c9b8352d9367345141a99b40049d5c48e7d27cab427adefd1f0fc1136b353cb01c3def91fffee8ad91e88f4bb7d2615c0dcc95344cd01950938ecb14b8446b56a06bf2f2f65fb8735e8a7bc96bb46ce9cac71a88eb8fda5e69d69eb29aa42a016b8583893e9d7277cb1359c5687eedcd599d8a46e6c14963637db04a929f4bc79304ac2dae733b3a839eb74fbe3de5042fd655eaecb15f39b2fe16dad8a6ff8dbc054fed51282a856e9da6316fac6db5d56f77f18da8412eb377e5b1b8f4cb1354ecfe8fe8fd54e62d767a80de04cb7620229a8831dbc9ecd4578ffa2ff06b5445e440d69aabc94c47bd17f22b69f52eeae5cfcd01a5cafe0580072ae9166b95743d68c3564c5a7e46f24bc48a898a1ab2ebe63f36851d2aacfa0c4f32d993771d314e725a43d9805d1371cf723ef161d42e63ffca688d7f0e21ef5b3f9a561a6210702b85fbd1f8ca75389cc7a22739bae4ded93757f1520dc38844a1a88be8e09645059148807b933770878cb8a9ad9211317131e69324532fd0279b83185b628fc2f9e21500384693fa29f26bd1b9c301601367665f05f372dab4e3107726cd3f639ca62bf63a75f77eaa75f7136157ada2374e65fb4fd349b45e25441fd21b13e6911366b97cfb4d6ad522b850adf40c
+SIG: 4bf0b92c6ee4eace5e8eb10370ff9d9c68a5749d59899d04327aaa38f8f825e032e59742b37de23107a3ecdd3f7a0d08122614b78fdd37293c8d05e28f5f7108
+
+TST: 750
+SK: 4db2b58144a8d2d0ec03bb9bc29b4ca893854c80b64afa4af7a9c936935ecb04
+PK: fc5cd750e174ed718bd938fa8ed99a1b9d556ba7670f2a77daf1c720113732a5
+MSG: c8d1dbc936911e122cee18f92b16a39a2eef0823b227f898cdf5842b93d59fc002edb5498a20872e19554ef73999eb3a7b3e2fdd9070e1efa9228e9e93b29a868ae3799e4e572324836b1ad5aa812bf00f845bc217ebbc3fabdc4e1b6e51ef9efac2770aa0a4a11ee52ab956ac6448aa2629cb61dbb1f1edb3bde99b4876da392a6e0b9a0c31849a5890aea9522f56d015a1935015b91bf4c6a0011d2377d671c3d0d753c27f8c76e405d0230f1f4b9b88fcebba1eaf13777235e55324b7d3f81e686109d91ce689530b90d2c5c71dd18772b385d62ccbfd2e089a1b670983f60c21c4455cb9d1a0dcaa74c874e35211f8227ff7c234dff85ec0b07e368cfa50a343578395a14c68f1f89bd4ecbc172ef805e5831ec89475fcc8d685ca9255a77e3ba3c147508ec92d7bcce879af0abdd2416b67b5f50507337914f390bbe0b450b6a2f1159372c4bccea382ce3d6d9fb2515ecf7930059a0552b75f978862bf97e8325af24d1b8ce9512bfc7cef884232042341d82f9b5dad2e502ac6ac795f99dac7fc60e3b8639d0e1500dead4e78aca109957d577a13c1925d7403c1acf989a9de6711e23c67bf8722f551b774cada931b5fd973434e3b7172819883e70c52785e3b49d323d05636641158640dcf6a4c200eb2c13b1beeb2dc360352470d15386e59e6fa60367e5e7f172b21159d5ee7cab0d7f5868239858e2a93550480fe8fb4dcaf4f224c4b2ad5448791632df30e8e5fb998b35ea9aec8c934a4403aef82187ca1abf82a344d00ffb993d9ff3461d6fecdaf5d3b481e0d31153dbf6aed288c8add064e8331550141bd5f7a7e047b8607d846a6bfb72d683446a445114606250d8d2d3a8b9508bb07d4623cdf1788b5499e9cb9a1379849bfa19c9a9f4cd3d9253adffda25f47c811be833b02f3327ebba83730195d614bae6fe4e7a3830815d2af400d20a9417a095e7e8eea1044917cbe512c4018d656e2db67bb989c00e1e507623e8278d729925b84fb5c186a7bac189e6d6ab14fd7b62fdc632bebb5f77cb5cc2f707df4053099
+SIG: 424517aadd853ce3985759a327e7760d9156d3b27345383f0e4ad6661ee4a3724d18d820f6c557f82797beb62d2f085433744f89a2d85293796481862ef8a40f
+
+TST: 751
+SK: c820413c2456747104662ef4dff3ac233ac4b91a76d3c4ea754490bc9b1e291f
+PK: 8993cea2f7f2806c77b3981b54bfa9bf1762151b418e5e725371ca2c04d223ee
+MSG: d2992f83924a594887e6ef13f2ae808fc8639c7b2c994faf0f795e36016dab7700a0ee530170f0b9fe98ab7588ce03bc50c2bae65e052647e756735b35d0b59c964e917d8c83e2f9fecc4cb05564287f0e34c9494005e25b1a8b1b942b54d89035f1b1c3c945fcc84e4a39efa2ca50959b459af74d21b6242e2f56518f70e8679257c089d26c3bb792687c923355b2c18ee2136d40cba45acb64240d9667f39dba3639b6516d4c4947573ef4ced876b5b2ea3489eaea539f557f58da204691a76e29c94b8b0538232c5f7d0bb0fdd016910431354b3e1e7ce62ad436917cd5c315a5be9b971c80f97bc9d5c156ffd64fd4e31da56083e02a0c8fce554db68674cb62700ba951752b829b03c542327412eec9ccc6a50adf47bbee15446682da2fea42048936d763060cd8f539652616dfa808d623ff777b4113652e789ec025b85e04efe8ad4c960b190bf4a5a6324d6f57c1ad22018c83cd7e7e097fc67b80269c13b4dd9701ca98f9876958ba7689c6f6f10a732a64bef22e8b98bd304d5dbf4fb1f9e4ca539a5c4aa619c44d6f58f824b2dbae77b7e83b56db5e5aa7b0ae9ce1cd10a69f04a80f1379eb0c474e4782df0e3ba6a148226bd1a662d95ee2d67c5207333cb1d54176d9e506459479029f31dcace269938f6bc562787841dcfe101f4db60bd66016e1eebb6bfbd9cd83042dd1379a464f405aaae3c11807848cc4f95c3cc6fa92ab4ea5305834eb86b873fa30ed1f7f470bf663f1a70cf9e60ab680cd1dbbd03ac0433b3d4bb482f8b344d46b3aa934b8633f57090bea5fccca6488799835f133f8bcf6e887ca59d19076d6ca19d4e28349051e016b03e9a920f4120fb523d1371d0e38467319543f127ed914b43ad062226a536582db728ccd76e983f11766a8863c2f424f65508dcb26fe0c5a800c35093960a121976e3051e2ef1a2a99c12fb7bd8bc037a439686806eb72017a071a91b3e39c90e86bc335f9bb543b127c9886738cb53806b9cb3c2594c7effc2a5920aa834be65c49f47964e89eec74728de771f3d675de9d1e
+SIG: 7ef70e4a14954d509f117f4bd01b220bcc192d3b5fdfc3482fbbc3b69dc068a7c4761d1bebc2317d6db74f906a155642b0a3c6592bdc72e64eac6f203fb74e02
+
+TST: 752
+SK: 6769cc8e125617c22ce57237a4fca1507f941234661df74328d04ab62ef86c47
+PK: 05112ca60baff79b4916c1bee2b9390c047af08c35ebb3c381b9748d1dd4c4fd
+MSG: 685489739b98564749587ff1ac96ba682da30b40a4de24f54ec8b083dda45333162167cb3f97b2c7314ce7a3f3f3d319ccc35bb6a9f0077d563161e281469cf08968d9dcf7ae5fff830a5db00bc38010e6662d494f3c8647c4f70ce2d29a9da84610a080b5759a3b582052dfde66e4a7fa5fb27f065073fe723d83701d5bac06ca43b46d1e58097670c194a13af8b573a3791a9661557cbc042757ab8add0ef7cf4f35435a4212353fcb3c203c73dbc9d26852d0e91732e3621ce828929cdca4d9192048751922ed225eab2900cff971a2a2d342463648bbb1944319a8ef6d43db62480fbf1d7257d22694539793f25c927917caab25c1193a2d2b23bb5cb8569aefff4f0ca423d19bbd46fc5ef7524ff8cb706ffc47076509c05a8158af77f98df6a9b5cb3244aba4b5c5f9ce597e7d29ba07013dcac1911b6de7113c736a4005c459992979019a45b2dd802a07660909eb4ce205408170d82545dacba8686dbde927dbc9c7d962058e9a95ea66b8dfd3ea435357a93c73948cd355f6ac6552323f17c2a678662bc0e9726ad5a5251dd27647404cbfe61ceaafdcfc08a475ffd87cb7f597e56ac1670409dd9408ae4770420c6e5e6dd8e748fe03a72dc12803d02771d92f47e6e717ccc144fc037275b6f745dd30da1a45d29db6d9073eee5009cfd5462733414a495f349db0b6dbf2cea9ccd57238ed5ee91ad8bc86179ad5695a85a50484e617751de5ef7a7d8a8db950a98a6b7f7dee9d42a5df692fccf555c940dc39cf2eac48cb9d15cda14dd2a7ecc0b76ebec68ad4177d1117e07766c48590d43ca7662868eb9790ac29f4f2392b9a93f89759e7ba546b925bd86f807d8d16c7e637dcc666e90590bf430d986a67f1b0c7c2c94930845869ed8d8adde18fc1887456881b4b26b53dcba7a526f0eca14e8bb689d66f0aa1b253c3dcfcf59540d5d2f5ad617f52c30938a5a92ea385077d75aa4ac07afc2b35fb8c1d5e78eb295fc20fe37c41ac06959d3a1797843ad7056c1b412dd0b480aa3b39bcc20587d9a0fef92c6c950ebc5bb8e142
+SIG: d39d853d2c2c5d21b5871ea5a75c041048d93a47dc599a5fddc0856285ce636fcdfd8564083d06ff284a524bc633cfdfc3b037163d674cb9bb5ba3bc25bed00e
+
+TST: 753
+SK: 1df7acfb963304e51ec471caf181102556783cb7d91ead30bdc2534d078a1488
+PK: 05a31ffc70e4e3569fc2be110c643ad5f087913c7aa476dcd8d6e4bc7ec22d24
+MSG: b0c3eeb57f14606ab7abeab2ee0573843ca22e6db2fdf2c9064cea5198dc5830eb158da8e2daa88857af8b8eefccf0c26c3ec0f330e92cff06bc05a29bfc99f940b61f3cfb2964b337097a6550a3e9a328c85be6f160d2c0a57ff6f1b3c5ffcca89089425ab6be0172e175baf40cf12b24a815f70f29a3a4cd0a6a132f120097752f4bc743ede08f5f21d42f282f7671f7783e27b2a8e2c14692f1e0e5de82855dabf98a1a63976006ffbfe5f5a579b460e26d06bd542842a5f9261bbf260451d2321c508932013cc6e904f79b5e4686d033e12c7bbd7eb1c92379c5ec341bf6457a3f17264a7c278b27501ecaedc361eba844442342b4b10fa94d265865116acf43fcbec965d2ab4bbbe614c4f90ab6b3e0d5383fa04988bfbb260307dde22d84098b6331d155141a927bb78d664b341d2f2a93e291cf79baaecd2612f6b104f3fc81373a7c6a045b5924bf950cd542f7b7accef3aa7d725de053055d951bd768111392596638ae097170f4492ba50a468f8e347763db612d3c7de7e56459b26ee029c630827a353aee73de68d6d72b27afd75d22164527945c7226844fab15b8dcc914349e3141c61316adc894dedcdc843984d9c7feae39db332dc393e9e8961bbde071c3d2858b3cb5f33b164a15616c6fe1bbc24a35f21336d261c5d8cf759e27e22c9101c4aebde3e126cf646ca7b2e03128095c5976bf3f6e491af0f0b640c7310966ac59c59fbc5bfe0548f88ee61ad9ec40c1c06dd29d794c44a3ea22c3d4762622ec1e8b333e45074db93741fda193c911f6db5879e55ee36ef602614ae64a5cde9d8306d22fbc4ae9c881a594bde6796125fcb628b9f3b6fb3ffd511b353f146a27272afd3e5d28b77f58a67f1fd27285c25ecc1ccf64e38d21f3b9ff22e00ee900629ef1a63e713f258883dd911f30c0d398b74bd797149be5e2696722da09d52d4ebf3c673929d298aac34ce05bea08ea9a424e93459c2eb8fc2222c31cc13d803b90a8a70bcd0a30c209211dc2ccc85b0bcd4582c695f58d80bf6ec471a2505f68847a75f6e911fd87
+SIG: b181938de10142f32407b4e786cddde932eb11dbc0bf0e5ac509fae7a5bcc32961fe3448f912c8500fc6db4e1d3262a83c9dbe769bb8c3a761000fe36c0d7104
+
+TST: 754
+SK: 7ed87c36dfdbae60c940a3b325c19fded814d76a544820a32f286a5c0ad71d72
+PK: 3c4ac510b36222c252a2dc1afcb40fb0eb85bca90391196a5883aa2cc912b2df
+MSG: 62d313912abbb006b7774a6737714a349970ce0421112f400463d3db0e2f7f128d7b96939f43c1e7107b5118a77c119683d866b7e3d72ac21f6b4272b4be9289b6556fe31b6051a0b42ed5ea0cf347696d30fb8bff6b8b572719de19a231cc85459a990c37801f0837186cefbb5521569666967cd4243d7307f1b0b24c8e2b9b692317304fbe3dd0a263650191b35216f52916573af90524f91db1a92471d758c92dc6d14d1a4b26f41b40403ca87dcfabdca47b9fc2533578f161f3b0199b5c698e080704b21c9e615269fcd0d40439ed8bc3bdfbc9afb44c11fa89275f0eaaa5d08fa959d6378d0db89910d48f2d86a1ebfc5cbf10eb2d5aadf51bbd8344ff8bbb5b8afe05a45011b5e4b72eb864ad263e8a03a6c7f98aeeb354f730a318aa30fb56d33d80748c98ebec15878ccf3ce822f69d3456843c400dc56b481a95e688b8a4735bf3843f5833dda0efe09e7175b567c661387afd2ebc079a48e34967ec97b927dfa581888f231a98a7ed33103bfa8e8f9ba6513527900b39b86231da7911a2fc935888a75f1129584afff2025249c4188f09052f85687706d05e299144d40de8898b7c8b2dfef0c3708573d8b0563a6bd0a504c0b6745702b1b57121c6f040aff27198948ba69c21253a28d39eba726219beda1f8209fb83e9adb07ad409fbd6d25565889ab45123f9d945ecd7d9ca7028ece092e35fbb7cb3f328126efddac5d859f2b2c6eb090133690e20c17deaf3882685f07e9ed2653b803b9b383b70748a1fa92c86f86d6c47ea87b10b12e363ba508060f47ce2a2f3b6a3eefcd4dacfc71c41f436fe0c2bc34d4baad49574e7443c126a589f6ef7bca44954f0bb28ec7151b0511c23c6bc42d5e85983ec16bb5f50a382d688150a49609cbde5698e86dcbf0212c2292299dc4dcf87429f6cd2eec80948ce867e25c94584cdc64b099029eb854edc26ea21421eff48cf4e41f49e2d89478def06c42bea220a133e50f5c74464c7e73fb1c1a77c507cf6cda85be402b7e6d6d21e810d6d0b5972b9fe77e54e74aee1f3bbfd6e7de6b5c0
+SIG: 579b38124bd0591a597cc9a389127ceaf55156077363edb811d0b65552acfcc677b272942199ca25ab790de6e084603ad1052ec210cf6fcb1417289067ce3c08
+
+TST: 755
+SK: 6a29f81b8d9aa48a1b23364eac8f6a4bdd607a84cfe8e88d90175d80643a58a8
+PK: 4c3be3a2a8425ff31c3a0db4a52a0cb1416ceb48cc3e4c28a4f2284ab3460715
+MSG: 7876a3f4eb69bb7e54e9ff954ebd3b10b93a4c1afeae92fa03c103cb6313a201c5b33a9a7223755cb510e25ec582b54e81b84956f6c53f1f08a63bf0c4a261af450e523fe8f61ddb3c0eeab8751072688801b2a473b71a2e38708da68c2f37925cb05a20c4283b3af97b6f0ba65a5403554375e215d9e3aa1b0f9fdb0f849923edbdaa0ab481c545a5df8f51d1f68b223507ea0eccfaebb5fccf5e3dfa65a44eea504568a88180a060bb06c51557b81e667b4b04e3210fa4c379876c49f3e56bf2be1cf519a7418393d240dc8a224c6c38ac2ab9d8fadfc5362030c7930c3ce7795b147c26c8a28c653429d90a173a86a8b18a009e62aef6eca95d39bdbe45647778a2532a415ae19bad231129127842fe1d0f11fab4a1cf0b17e498cd5952c939e090090287b144895dff00cec8d6aedaf62481a41783e021082ce352063e62811fd99990104d8a46cdcaee2bab458e5247fb023e923330a428c7bcfd20b08f520e8946dd658347352ae0c4be73c3d5eccd11149f3ab7b8052cfd95c35d4164546f5d8f377517a7f432c0d5563a7bcc7bd119d3421dfebaae844599b29b383bb8d5dbf140d9bd47a078b7ae7c6aa87b1e29236c9fcfd654b7f809794cccb261588e18dec6c4046a934067d0dfa03791d03d83b718ac4d24dce785a3028de0c9592dba7c5c5845184afc9c0dfcf94095860f0eb802ebea20178e78b5642e5dd61c33b39769052d9d854dce902f476e21f96c650b463b7bc3d0ff2996b65c57831f8b7c0fb915f4dd7226ac955cbc7dfb03f9b758dd3e0dfce2e0e580c91a30c783ff567b17f12dfd5d3137646e20011cdcaae11102dc716886cbf123c09488b173636abd54e962caeec97d5eb940682e703b730f61562cd14b9e6561b5e93f60cd0e1e86d1a1b4719c5b508242bd6b2d9a548f59bbb875075969ef2032f3196b8aeccc45a44d9dbdaf878ed16f1d855e8918ed65a45ee5c7fa32a1ec6932a159cfb50ffc87be06dfcf7228ae8870ccd357fc656e33fa4b6b8b7d1a7215553cabacc70a39c980b971e51a17ed6318b43b29bb
+SIG: df09cb9b878d3dc9e542dbac28943e28e41dcecb92cb7ea44009885e46499743330561ba1d36aedd467675fdca2baaa4701b6fad979fd839c470d13c82daa905
+
+TST: 756
+SK: ef12df479d983ad96e8ba65330b36d49aadb983164e1c0b452b560ded1d08d60
+PK: f761cf2826927a7cda8cb04faa2c59f8425a8f7d398f76e867021c951f073809
+MSG: e58f34daea755ac4e41333d6f0ed0135f7dbce50309bb1956bc71acb12c77067a647ffd86aa5870c0c0007e8f995a22b88c467de225444544201c557495e253e3319cc5ca376d3e7cc1eb467346e52ad956a6fa733720b17117b5b7585e4d559409aaefa95580f91e502015f497c5cdcb7d4d561f544efa35c1e2a53b72bddeceec2d1050f177d480f687405664dfddec06eee4bd147a912fdbf74f2a95d1fd1e11268694ce4d4ec4fffd6ddb3254d360f236fab4d1a17f8d0d1a511f944692f239639ae03d64facec6538427ab71f7127f4a276f9bc45bba611dfcce6446cc13968976c8bb6d6fe2106d705922dcac956966a76d48f2aff4b86514e39a67e1643fcc321858024e693189833c8ad59b4b625298ebafe64626b480f326f1340723cb3d383f4fccbfc237a3f4c4f7ecf0ba436b32c2fe35179da93111b48cc9ea24202bdc1b2fb60a4319dfd9864470f73f54137206e0bf007f5ae88a88747008a60f4789ad167724f179c02b63aed002573d28a6bcf88e07ce8daea5d5f1acf487b4c5c16c2bfe11231ea5ea763e8f332cc73da1b2f8c198ea8173fd33d4b2ae69e5d4d1aadddf2fd821b85be45151962d1f99df81308618852ad7cf41d72da08a1b39df7d8b994b4ddff37f9dfe8f38ce30e91061d95d58f7ae826b02385272ec09f01a7b3e4b391d09bced665dad69505b419da8481bc3792bf8b8e7ad64b63f245666c8c32fd5c1b1b48c9951e1c21a1eb5f507cff137cfb862c2cc98766e878c930a083828c9d8db18bf16716685f39d6572a8ca8b2a514f77003d4e75bc154aebf14103778f365b1c3f03541ddbd07d6e23e56762d971eb02983e93c4e01ba4b8a2178928c4337d302f31c9ccb75b249a82dc96821e95a03ab6b770df2c3dfdbf1fe9773f8bc1bc5b3afa0440b102578f3d213c8d019cff124f75ce4accc8c667feb27c751a6120074813104e0cd070c9f5e451dccff4c80d71107c975abfac07d4d270c727d8a2fec349b533968e271892d2b62c125fb7974603c305ea3bfa30fb610fc5a23eb68a8406444391a521337
+SIG: 4c8010866d9115f05293b934cac68104cc2c3437568cb9d5c570b1a8bee706603075537033bd708a9c9f3d1e2519a915b1c4ae4ccddfcf0ed0c049d342a02e02
+
+TST: 757
+SK: f731317cf5affe58704c4d9497ae860bbf739d0fd96b7c02efb6777b3c858a19
+PK: d7d638aecce1461e314255aa29d9a6b488aea1396e9682695a470eff23f3ed84
+MSG: 16f51c59e9aefc26b0da5e0085eb2e2f1f856def9725769e3af12f860905ae133f65074da76dbf25c67f6257d2dc66c05f9b31ae177b69929fc183b588c519bca14796a0896d2905fd942d7ab4a3fd9541a5529f729c5851419b5fbef7b134d6762eb97e8a951a8ff52aa0d7e67444d06b07aa55e4eb9ab892f47bfd111df5b62f6f3fd1a5ed84125feebb77da637c05d5265ced113dfe8782dbd1cecd2c6c032b8fa8855b3ae78de74faa5aa20a761463c2a30be66bd38cdec75f8957cb94c113a45d546daf475d89aa1482f8d2803a23c939202015a08e94b132728fbe8f6019d7168a08a5930170e5639d110e4739db85e61e64495944b5423a74ad5a8a0a510612ece655ce18864051525b908e0b19290abe8b1182c48c700d350515fd349956e8087327f30b6fc3f131c2144abb3f0e9ca331172b35064a82811a68e2cf36b43e3ad2e8dfa5b1cef50e2a60293fc5f635c9a9998d8c1ad296e7c78fc0582022d63067186b65e764828cc0f5f7632d5eef863e6c6d90e38ccc87d7b747fac8491d632cf7f54b9a9eed16eebec01b6cc33d2463f7f950d828b55ee3f77cbe974f48948eb757aed4e0dbb00ad95ee01323486eba3c8da886ed7f57bb400d63a1b2ebeaa2e70adf0379e3393001ba626c0dd54b7f0c9a25aae6c9875d4e7622f3ed428fb3124b29c5db9a7ef16ebddd6805f095f5e769823c43f262868ff43e3e0525746d9497af124a01dff61ec718af3b5bb746fcc08aebd16684d456ae7932ff5ed7d6b0f1b25c7adeef598b5d58877590ac1dc05975156796998774081e5b66822a94a6a802c3a2cd9f489e1628aaf4652be1184b0fc7c5ee7f97ce08b9233b4b83d9367be5f4aae9782593a35265154dea4c375c16f0caf6dc4594d2bdbfc3375bb2a0432c482f13941ce2aaab4d83e74d116f5de4ab28f8dc3d1cd19d271e56e10398bd1df5c870fcbf93a7d1df3939547c107bfd90643f6f5001ae7e06397ae1a271bb82a1f38e097bec667466b80ee3e50dd4fc9d5d54f18faf7a5b55a8834594ef0cb7e508bbd28f71fd34235bbfd3
+SIG: 2a4fea98f9240171a1823f2f69352062672e6c6e6652d388a87714d647995df75b6e1ed1746af2adf4e806135d60754e60fea032128e35abc1f1615181125f0b
+
+TST: 758
+SK: 498e5a21a9b0c347ba83a47ac10069457f5783c2e1e6e4640045e594b1c69332
+PK: fb3948c81199569105cc1b7d9ceb3b41a343bb00575538592e0984f4f4710abe
+MSG: e4fbea864aa51190826645d2f772cb0f9eddd3034473fa3177c7af9a5d41e1a73ad5784c7096559fcddb7b7c85891cf24e82c588d74774ffcac0c6b4eebc2f3fa43e9d45f259d67564030cfeeab9236c665b650af0c92c875189f5f9383504b15360a0b9a5a00da31f635b96f6c73ef47b6b06f02811d1d19c2e8e53550ce22e42ec50a1eb2ea2f4cd03c442d4aa436894238ceb1835fe99b240358aa0562c249698a3f123c2c17e591010bd6fdfcbd7dbe70b04520502ece37a9a1dfa1ae3370417b004217a5b8fe9903c9a3b9f4b6d5c46c0ed0c538cec22f2dfcb2a280a42adc489cf2e062912be9928f0c060891e432091177526f1b3a968069d4a57ade828559810ae0360681ff99329fa0f59e7e59cdf87f9f33c40e97031b9f81d48fc12286efbb3d4e5a62ef57bc0d52d533b99c5106aa79cfe1793a908518596c383483ec49ff98ec557bfff7490a46daf6714f2c2c32f57932ca0d730f03f381d69decdbd9a7a6d4afc62406543c8ebe90ac76e6afabdb82492a206a369e04286d313e11107d8cd9b4bf68f815dba4e990b049d79216d3653138342cd118b130f66b006f3d89ac3cf89837048b0f8a62d94051d2eab891ac5f47888879d88e546676d1daeeb4d175d3f04a9d74ffcdd47746016f84ad0d112afb59ad12187e94f22535d77e9e0516fa42185c197ba774b393227f741fe68273f423fb0e0e0474bfdaf2da78aeb1cd5b98c1dc0832124742a4754125fc78b19c559a5b3f7711e068c440cc0469a1cfa5c1864be18735aa8bcd406c4371eb857754d908bf379b91fcb24e34396bf87c19a04a83d59dae71f3f3839829d06221301ef595696e719d56b79520a0e509929833b1d804a6a0ea40400bb45028ce5d36933883e17406e27a8109057b1a1a5e5da210a6921994f467ab41aa8f0d88775a8a8ebb4ec77d7c80e45a7bb422a4c00c90583911465e6b5f0fdcdeab72871ca542e1d1a2ca94df4ed2eabf90ded0045290324a9fffb30145470209f3826580989349199dc5ab8d4a25df7a0529cf91471e30842abfacd44ab781dfc1395
+SIG: 2860830ccd1d41d95076816a398424f7b739c49fdacf5654529da85fe3565584f6aac2614c63f774b61db9081f1410fba8e50ab3b4c39dc06314243f3f0d8e0f
+
+TST: 759
+SK: c24cbf401ad03bd88dcc7b519ecf624db2223e990289309e1e9f1f8f6127c6c9
+PK: a74666f357209f7189903788f107563e50c051c3d40c3f3dad10d3c3cff1e678
+MSG: e7fa359e6a09b2c54aabed3bbabfb72853a805aabcf4d18ddad39f03f34601e55b6ce263c9a3ca6a3e5f1425c821928c61e7f750919bd3af32bcb7b94d459a7a9a35f61c941792e2cc2e4327beb344a841a07f32068af102b3de61eab64ef6d5e69062e393ab5edf6ac9ef7b38d49a01bef0003f421174c8885975c01832899c3135e7a86e5b55d9b1328bb4289b5c40200f49e5523b3c461dc7175e1465022297c3d380f2b1fef39cb82c00fd160f447eb51263fa25b4df0fca41ec0ca2ece7472201af86c3038c49df099a9aefa1f88d0edfd17c0b3c86046629c09454054aa0fb2c6949dd9c130185dfa5d903891e08742cd0429403f57f4052158b2f401da4756854e4aaf024221e37513cf677ee6a0b159f501d377ea32eb71e778004f27203cd6d553fda5d65e1879477046f3ea3d1d75c9d0d30311456709cc7f6ab68c7b0d52be40f04cf655655323285318329e84c6a5b07e0ceed5f78f7f1fa6229bef878793c584728abf4510b7f27794b5942916254c589a09c8e911f0b954211a63699a752147f2a4e1a18956644bea2ca2692ba182280e04a72dd89b0d1268500938f347bf43f2a242ee9b9a6baac9b350d656fb19ec834abe3164440f2d2071fe5e32c8e4cf905539b839ceeca2620fcb2a087f780e6c7f5e05c506888250ea7c856fb30983200aa8f78fc1771054ada0f3fac38ae2f33dc4a4f851b76ed740c0962a76a4de44080dc620a44ad8f23d3462b792ab3afb19cb8a9f4d9e59ad765a771899da8cbec89e5077e85c0c93126376c941bef1f8bb992d3a35f270725846fb252f8b5fbb7567e406a1b53b619769e632b2b4087cd4c276e5d58ff2b56e89edec48ce53a52e329ca1559538f10902c01a85fbb3cd72e6b8291e5fe639bee9d47d34c249a7a07d7a1427a01f63d60984c450bef819b19f65e2614fd9c2fae7b9231a0bca414ed94a5ee7e66327d2a99c84878b7bee087e891f253fa1fece313648c06c45db2d9f3bc8599937b752d38ce5063d0ed9a43ec9d4015893d43bf5b2d1c60478510468968b796f0153789595441722a
+SIG: 581e6c85aec623b62b3d4c9bc9c77759d5492722e252d44c1f8ada9da2ecc67c17083273aa091bbac046ae63c78893152e14d926c41ae35f0e6e3959496b1306
+
+TST: 760
+SK: 8b3dcde4abbf4e6211c4a51c4b026800a8a2a061cb38a2ecc7c9cf113f9270bf
+PK: 514535580f0de359bb0d41f2efddaa04c2ec950119f31634b2c1a32f195f6968
+MSG: 481425027da672b6f26c91b80e55582caef47bb15a2de8fca852221785180b20a7fd6d4907b5881cc1d6e39ab9612cc74d6977e9141f7087bb27ab3084a26285586f8411db1f503adf52dcb25ab8fffd2ec1504c1777b9d6dd4a29e2019e5cbae1b7eb26f95bbe07d90c2f6fb0884a59a8d58dde5116edc3bc349d37c160b27befbe5a5c181ce7256392354d221b58c47eb0bb10929e7421795f4b7a7c275edd08c088568772e993218dd6f3c2cb4ac657a0a3f91f3126b991adf6cbe7d1b19b8cd83be3602ed18f039633fbd2387bda69e2cf0387d8644d97b303fb00639aeee7ae463f6fe1a2c4b89aeba3e9094c11fc29114b20283f287c6dd28cb098dae8dabc48e85bb59c0dc6e78c956605cb7cf06942353e7a22e96f80a37a66f718d9e4db8c52452aa0a35772e81ba2b303205b412dd2bfc15ce9b436f99fbb32126b63ce9cb43199f157d81751a7c4937d13af4c582952b5d606b555b046bf1de06cf39b63a80287371803609a387ee80f3a5d88b9d6219650ed17d3cc183b2c70d5eb94e3bc52aea7aa7f53be0e20b8972f143d8e20162e803edb4aa83d5553fdd553398b0fa176b959cba140d6e980c9251b0fa0b65e908417f82f451ff9f2de6b9ca5e3b5f41ba40d05a54f3dab4886aacca05c9c2798139a4cb33e96a91494749910a17ce8b392fc0fc7762974d79d33db924bfef8655a723776ff87f950fdc568b1e526534541f572723b840663c19188c424f7c489235a424b09fe25c30727ea1cb04953d706d68bfe12100ef6f64c35c6b8de67edf0e3ad014a400e821ea34024321999867b43c82c450184b78f7425cebd7319dc6f65d360665dfbe7c36674dac3a54e96da910c02d3640780b22d512ca0e3ca3587b94ea9fcd7a31b4af69fd6207c68fed25f89921c1cdcdefd1c090204492bff9bbb52e08885829d012bc2dfb4fe8c35e59cd13bcb8ead34193c40b03ee4d825ee1322ff4ef071279574cbaee7c07f14be606b9cd0e261111ef20d9681d76cf78c89a8c397d6b8dc778f4984166ad5df3a81aaf2e6de09f700195ae2c1d4609647
+SIG: 4f3d4d228503017e74a6bb58aafae35c3f37bdee4ff6be2e6240b5082feddb222735e12f31e056fa685447e5384803007ea7910e605c1b78118cd5acc587a606
+
+TST: 761
+SK: d4a7a9524d30a6337c0a0be95ca90591de9888038e3e59e1b25a4181ef946629
+PK: 9fc3ebd139cc5b7c0e05af47bff6619b812815bb01ceec392a3ff0aec3811d2c
+MSG: 171980c03fdf7a727bd5bab3ba0945e6ad5faf0a7f506a56d1d0edd9a306b3158d843266d3091fc1e42281df97559a2201f5bdddfe683d0e1028d1d95b2f313b484c392ffdb1cdf88508afde3d6fd2a12888bacedeb79ff3db40c9ac0ec3fb901b228698adf8d845ff4fce10de55d42436dce930973a34be05d1401f334d4ce8e3a793799eafdb94d0f2ab0950b079e6653eeb499fc7447ccbeeed8dbd5456808cd7a38f9a15a2a9c738d61334cab8ceebbbf4a4814d94c61859178784604e0c2154597e72cf587cd1f5dafe5922051890e76d616d8cd5b05d6478d0626ea83ce808c46143e6fb06b4182d228da8f6d4139eca5b8f3b1b98af68c59b4b5a53c136ee90432aca2bb915529d26367949826233b43e55804b55fc9f215eb0b0b79291465bb34edaeadffabfe6cf41bc07b5dd4d0142f0361f058ee1b3b9fcc196eb9b35b134be3d1d232004489e8f6993f625a63015bcd3f1e87588324858ccfb770dddd894bf297bd763ef5828e21f5c89aa98cfbc1c082dd7fbaa4307bda40b4a758ca8f39f4e4aaed309041268dbcf0af32de0d7fa90a523963b780b6a932cf89499025f0e0d0474c74348947510e6c5ec7c9e05066eeb4a73520c3d927c39ac26ad7596325b2cc47c5e82a775455b7af03120b1cfbfd6ec3fc0c3be6078b00cfdf8342ae8bf147159f50e9d564e2f68306dae3caedd1019f323c478a1e1f67598dd834bd1d1a8733fd7fdd8a876526c531518936edb72d01656b344c7d65ac1cee37ce5997ba48d3f4d064d88057efe9a482d9e00ab5caeb5aca2d660e337bd15487365697956a5e47b02abdc30d8e353fed4e1ac41d2bc2120021143635935c620186a522bde54be0446fbd2dc88b56304b3a64227d0acd5f85a6b6787a3adcf2d7cfc86c634b4d7ab4315b97de9e666cff3ff1b88f3295e7bab9e9fd46fafddb4f5fac51cc0170129c651b4ef4d3950d6942ff020d1668a528bde1da936c0ec1ae09e84f8205861fff491502a872c8154a96e7ea25eda955a7fd2e4b4c7a8d273f60bc74fab7b4968ca6f75daea5040f839fd56c2a980
+SIG: d15788bcd88d1d81b9e61d4fe26ea49e66819a59d2ae4832321b814d5062fadb87807db6852e1d8295e31a291b1e785d01d834895f88f400df8832c1607b5b0c
+
+TST: 762
+SK: d08f4babba3b5365faf738795c9da45db1862cb28b93eb6635d1320da0f4d937
+PK: ef31b454f734e52b3438ee2f1cbc35631b1969de54ac98fe4633f2f500ac8712
+MSG: a394d8854ceb5c43afee1a48926bbd6685aa8aecfdcf854133333974d624bf2f1f9c30f005bbf34cee3afe2b290600eeae6f1dd12a0c346fbb2ab9c916c5d5d80dcd87887875a0ac847678039fdcd3a9793541f5d675143a6abadc3b18f0fef5108c19c2dbfb59710eef9866a4f3f297a09ee48c6803007dd6ba8fd4be841cfb10ff0514c30fc4dd49a3cd43bbd16e460443a11afe649e901d63d89af598aa686b2f607ec11f35e17a798a4213b75a38788da4f27cf2b02caddfe61c3729a87ec6e6b098f68e7aed28a800c484dfa0130401208f986d792f54635add2848e151262a365eb21e2727191e1f700f3bf5c73b0fb4c546d0048a155c18717920fc0425c8c8fa8f167c43a277bb366e0ad702c89bc5aa06fd470943be05cb9e3259787229714c30a4e87b00a633aaf7be6b5875010d12e107c9a5261ca562d67025bea0fe223463edb92ea01cca92c44ff24da9d8a80a6421f3d4135d647d1bb0fd988c46c8a170ceb4f33fff9c0ffb6abad1092c84dfad8290898b249516a292e8da96fd51a81005eecfdebb05933099277d073a480c3f9eb8aa11968c4d8dc0787a9aec3e0527b7fe4c0635411335a1811689e88f6d5ced0d40d6b48b7f2d992952934894153076a8d37372fa00d9cefc5cf8c26adb5acf325a01cd005ab8d474a52d67114078c6516aef804bba19b887a28ed5e46ee9995e5ad3a82fb9cd93283433680921114b4d9af8fcb6b2b535839c36de8df12b17ea6ddcfcb3334ff40e6cf04ccd5ca6403ba0b62b4cb71bbde91d8babda69152c9c93ae769b5529c8d52fd9a6909a15e1a0601a714649c96ec996c1706d1021b97487980d7b2c2a39bbb0e470d8e46ac4aa609a0922c9bdc01612eadeaccd5fa523b2a8d0e62ffe56281647d61fffbbc840535745d144259cc81300fe99dfbffea6b0b9bcd28473982d32e93ed46634a9987906d6f48939d8dfbfb37d33b888db608cb2ffe39a8cf67b72644611c7d32a4a8df612468cd5e5d75fbba79e638aa1daa28c4e0eeb9a637ff8a08b65f7a7612414df76bc7b0b56b5537d666facfddaf65af1
+SIG: acebe4c86fa9fe2c1a5c576ac0501e8ab0f640fa40380536fcf95059d53d4a3555d220ac363587175e4bde163c0d00650a12963d46766c99bb62bf7573e2870c
+
+TST: 763
+SK: 8f474f88cf863c485456a5a2155281ff27b28459f63bc4f1db00e0031064f649
+PK: 43144a329d751d04e07169b779ee920dd029cb445bf376ba3a668572182344a3
+MSG: 840891d948ec19c8c7f7c9d3c4775362a544a0ec97457ab5d14e125dc54b59c8dc9a635e7badb6be73c3a58dc0e9929f2b420d8356d617c3d41bfe69b4e158d4bf08fb17e688d3cf3c948b69b35f0b6db66272a8eb2bd410d6509f6c828b6a20d6586eaf857601ed9d6054799c25320eba8077fe1ae22671b33a1588ff2b235d3c71a27ce5c6c66e18889198d116933676bc4fb0710db7ff1ac2f20ce369bef56b43cd1d406cefdacf00f1f348b8ca7aa614db11a3a640fdb59389d1a6a394755c133f1b019c8308ca5a951e73b810a180f6ff25b29dbbccef4c13a97503393907a2dba096a8ce5c86c0ee6f97c1441b8d6331cba53b19606b421af52f65f9c663e63d3982718f948c6bae961b8e4bf8cd9e31cd09928e4e80616597ccfadcb8a614154933bc37589c85c776e34e5a90660f59a65b5e93ad438842f982d02b041e6dbddf171099f8db70995731a0db8c4625c9bca710805961fb176dae819768fcad7ff9bfce36403ca7f783e7613726d7dc59f24e247cf15068ff3b19c725fad65ea8e8a7f722d528c95fcef1c0cc79d18ef07cee8b011eeabd9921634d76a61a8a3c8931b827e8189881f81f7a175f21fb0378b8188e58bdb2017bef390f1800d9d74f263a81df8e67522d092e775d01e004e7f8d8281ae2c2fdf8c3a445f9eff7fdf13f261a773ddf2dd9cc6ba5585d990c995e6eb89dffd9ff0a9dbb76ce5e10dd0272d5001497881366f5d636a9cceaa283228d3ac614db217ab891d6689dbeb950e1200c3de53bc5da07f1d363dae9be6ec36eda6e687d26290f7abca268a7fa03d9318864eda9a11e3b26140605920ac13adec1b5548c9a7a3215a5876b7e941afa1cb5d7f7f0c11630cd429f3b2b37dc76c6cbea4f3b726aa8a5f8b9f705b05d7e9451956f8af13ce0a85955c7135d64ade5496ea542e70f8da5b573aaf137085dc96c6927099695672668b3c7c6f93c977a4e8e9e770295f20d52dff187f8dbb25ee7e774024eb9be08121ed74b6d5462f4bb7dc2003874caa31bb7595cd93a99ebe1eff928bb5fcb9e9c89dd31d487fc0e20bbe150
+SIG: f61f7807c33e196d0fe182efa4d4516a9815ddd449538bbaa6b86b6901a05f5ddda0601ec90f39f1554779db7a09a60572effd4d128d0d3c2dd4e883574bc60b
+
+TST: 764
+SK: e42b30d49c43c4fad83dd51fdc2a4ac5901327add800b66972c8c70bde180adc
+PK: f734aafaa4dbaf315c258cca8bbc1d4f34e83601109874222aa05589f3a6635f
+MSG: 0d497051861e22d8a9c60e5f7de6c895cba335b2e82e602118ad8342b4d4edaa80f95efbb59cfda1fcc0291725700e8a81bb12a0b8623b1fe2891b8d98f7a84c59fd92f8a7adfc065042f7f4fd7e1a79f55a1d4d5e54e04e672f1c9e4c4cd8d0003f3cd54b76e2163dd737acb2de5c263ac102a48f696b60caf9be39c665cce1e0f3d498553f579061889a5ec5603e4d141cfdede8e7317572cfe76a0f48e4ae06062c9157b5eaac3468938192db4b16105c7364a94432b215a71797fee14c3c9ce2f746ed790302fc41dc492d37d9ef024ab51da3bdaf0f81d9a930aa0e025c04fd71026b6afeb7ed01a91a1efd6c39f5e447c66dd38a7656c613d02126f3585dfaa02df930253f83bd42196463ebc50f8cfc949ed350392e61ceec1309da15a432f80dfe948e261ce6d8421c5459cd21f3ffa2edb500982b2abfa52e82437ca230f609116320d9893eb82a14df72b7736667516fc012b28a03c9dd88ea4308d8ceea44cc604454cdfa2c797615bc0a6b3e0089af0a81be54d1b110a13ab911b452c342800cee2ad239a2b188a7fa875e941daaebcfc88b70ae4b1c575cdb6e6d89448136f60ee81c703c47822d2c0e50c7f1e8b7fc7ebd80789fcd7e06c7e50b5fc8b776e8b9a4cd5905a29069bc3a558d7cabce2af4f310767d5b117e3076b3a0d527175543b2ccea28d5f716fac32efed3d2e0276be44a8956fc8240f2db3397614f2f2da02166694ec6a7feec6ece39d72b64bbc6b476a4f84f8d879380a38488e4d6e58cac0390ae25a5fcb73d47414b4c26bbb9b4cc66e42594bd56d841a360923491d117be2c6eb2320f3c6175e44e27b6653c5dac6fae73600b67960dca50aa855a89e0ff511ea04f143e89f1da028476be4bf6d94c80ff726339e8bcfb7dd9f8cf202259c0acb6276c281e3847c2cc8d2fba84438d2d3c6031f2a7b95c1d8f9f3cc86a5eff65cc011de95ad896858e1f7f6d6b94bf49dfff5de2d7fd71ef108134285f61ae475483442dc90bf013faedf3771c47c5b96dc3cf8e48510060ad8d45fd5461622780d869d4617b57fe3cb5cc0203153aae
+SIG: ff8e076e343c8b73aa453bfee9b2bab6d5c2f74c35e1bad1e52ae777d69f79764083f994368a1ac851a641cd247008a34f3b608962f4dd5109ac71cce978ec02
+
+TST: 765
+SK: 5cb514217482bf42f611fcec36a5286807c2bdbb56967691353f54310e1ad553
+PK: 280699003d5d3e1c05ad10fb10959bbc595cfe213069965cd8cf39dd426a0568
+MSG: 2f57258cca7932e58bed546cb0041115bbad23d18346ef7ab5e3110082b3a9712f6cbe1270e6dc0cea3364a06a5f2f283ec39b63058d34d59979072fcbbd7a5d0f442bbdf082d5bfe2998aeb51bd26127803e5c796c38843200ae2f6e605af312f54fdff17ed1dfaa89d28fa67dce462de4fe25268212b282e222a443e2f31e269054171aa73c719a896cdb7a539dfd1d42991978197d7c4f2d30a641be34bf1380a4f4dc6d9b101636636a496beb357e347c1666516df8eb560a0e0d1e1529ce36a60e00ed278da3802be192342989bb611b4e3cbd9c37e8cce07efc12d29befd7e2f3adb13d28f708d97b63e107482c862956d7ce8dfc2af5cac8d51659267b0bbeddd5efa414ddeabd17b23ca6e843ff49effc82a5d07e36a83b67c2ad7e48eb9990b421c5558009bd6934e86d54a8a6ac4078796e305c7cc810d3f66ea6b9504fe0ae6757c504c5552530a6f8bbb52409be079d8e4a28a6fd7dc8935f8eb9498adc0f23d0807ec86295f4898f5d05e150bdc43aa8b7bdc893a0a684c3063898b6c95e7d56a4c102690438e9df99758a90f47c608dacc4ca240266faba35fa1eb2eaabe288d2c2ad50b6cbf107c002575e91ff472a4417940667be8180173854c93df84464bcd312b7a7ae4dc2b9059fbe6f83f53806425bdff031c6aed6efafd9de8dcd0dfabea8e6fa681e99193fb3c647e442112c9a23f596e65411d8d6bfc3923004ece91ea6deb881111b1dc29943f578981ee8c3bce8525f78565f34b85ff20015feae846f95b18700bc5cdf14b2db6cac69814d63d74bf20329303e5ca9f04731f6881cec6d3abf87f5eac08734faa34cff4d3cd9a4a11d7b12f73253b4dd0a43178f0d3c19c0c40d9ed918dd17646f616af79fdf6194262f0fa4f71b3187dedca48d9cbcc19931a1519677456256ed38354567c3a67571cdf82170a2c85bd2c5e68e05a0f3b93903f191b894f84946f89000568054c1cea9fd0b8bb55019506c54341c24931984548ba458a4d813089896e86a2dc33d94604003f354a7cc941c754aaea24253cbe4cf2147ffec5e7b950cbf28e284481
+SIG: d53ee2e0f0fd657b2052478fd15df1d38fe0e93a5483eb4a6e7de93d02a4cd544d8fdddcea822b71576ed02853d9a6b14e1a548aefe90d92f883792b7f1d8609
+
+TST: 766
+SK: 87d3ba95c40df80069b1797ddf68e866e66d46c51fde60e768a9dbc5c92f57a9
+PK: 2b812b2c9b60ff31975c429a86736dcc17a58d3dc1daa34623a4bbcbe2cc0581
+MSG: e11256f82ad76f3f4a49d7bad3ced8718d36d2f2bb3d31bb61edd1ecbcee6621fd2eeed3e3deb597b149ff71b851f61c8c6819e131f9a2af7673c3f20702acfdc8b8f9064b415c9a3e35568e371d740a38127c1f27b391b45d07045aeaf00a54e5b7fa548afb5f96feb5f5b44f60cd1707e8fa9567f7806e15f6a01aa02077733fe738b08f21efbcf98c19d5b970e6163e5fe8f4800ef9ed22a0f9b5126ff1eb1c7d65019c8b440391927029b813dab7c7e863d48229f8df85394345fcc88a300f60a8d516d877a5a3a7e3c49a9eb06cd9f2665ce2a89022962b1d49592b09c7543da835ce63bc9abb822145762b71cbe150292ce5c8704e5ad34fb4592f972044e43e69f0e1672d6c83cf25aac68efe3d27af2ad34274b9d2b77742d9c6dfbd57f92ff64d3e4c67c541d8502a7d031895af85319a4eae2d254335835eff11e7a3671a6a0d21b72ce1fc2acba1a920183834bc0a4b73f639ffcb0f6b81cd920f2e9420d612166d5682a06060ea0b6fa695fecc7704bbe4b052aa3ec8f720f7d4f32e8aff86b80b8c1cc12764a04874037c3103e9dfecb8f7abcb0e073b23e67ca0a9b1fc72993abf31dbc24a8fee095b3251c22626af5dd1b6d34be5ea06a02ae176c7b8cb9d063501be6f612082889fdbdcbfadc33a0d311b080b8d64e49f16b16dd8edd3b2ed1193a74e5be507609b042727ccf08afb05cc6c50524ef0e2664621dc8b05b15ffa81ab6f7e3c8a5bb3eab1f68e3656c119d969e4144cf3285af23c04dbecc038aefd9183c4e72447b2aaa8315f4696ce6d1ef429ba0e5c3d5ffa7f050be39c7f612f4e10f8ef070df72f8addbeaf3339c1ad8b5fc39a2ecf29a87f82e29a0117baac6625ad5c80cfe759fa1dbcfaa12b374477d80bfcf06796c30f2c39cf0303d00dc56a32d1d039592ddb06c22aa068841c0b46fd48df8fbb7492ccbc590c563c8fecce4263c8c7539218bb97b35711537e988195dbf5bcd5ccaf06faf508470977a5358e6f02608349fbb99a23fbe36b8c97155adc246ad7d93a8c203f75446c83c4342c35ba104ecc67e669db4a95466ee68f458a
+SIG: fa0d12cd53236c41086bea8c0cc60b7764a3ed72bdeb9d1ae5eeacb48811fe529762a2c6f2bb06d9b318218d968f644435497a1bd0d0d8c1612ab8996d98d707
+
+TST: 767
+SK: 7c27ae47072b0c9b9c2c351f1327899895efa536c9c067d0e0ce8e82e6292793
+PK: f9febd121e17db7229b56709021849c35d69fa08b50620e667f842ec7ac782dc
+MSG: 1547876a988d1be714a42fb91cb03763f1913a892ecbd4de2ccf8344d20758b7b6d00259101fe97225b297f87bfe222004325db7f632ceaffbd134c96cbd57e985bec8434f81a4ee6af85c3fade50e4c4ef20cb0393545e4d4a86e1fa39aaf333fe4ded054bfc050a8983a03dd1ecf2b5e9517baf9e1152129a8a75935711edb20af5c8cf9c694a33cee451cd950b2fff08e3158c5cfb7b15cb3e90d46f494b6a108d8888d5ec29a33c066023b497709b2d9401feaf2e74ff26c16d36c39e6517ff954bd98bce7700671988f66e85107644ba2ea007a13018c1c144e3c5bb80db9511fcca4101bf49f8c80ff3ca7d298257cbfea629f83d5e06639d31f639db4b8726cbe224d758829bab10905171c9c0ec370d58031efe4cc5ae72a495acff6cb2ed9eec658ba117088dd3c6ed1df8f9cb10bd4fe0e5e8ad9f5034e34652d98668db15c8533393a6e9ec0870c35666ce54efe2bcb45c34a7230e6a700676349c7b3abf31de7b7b0521f89b30ac4034c2a4ba8218eefdf8d2a5c1f8ed9b701579e47af8a529a95a1ff64d8fdb885c36839b4c5f6d72a99257e8678dccf312754b9d4619beeceb825526de622bd9676fd5f357693abab078b9e03ae21e87ca161e778af77096eaac2d2d32bfec8ec94af7965f61d68ef66a4523c1cc70c9519b0750b3c9eed5aeba9f0a9b7ef52cd4a2de29b395b705fa53f028fa766159f20e75f4d384ec4fd66df06e744c99ac88cb849c285757cc557e2eedd86959da2c1b81f5b2715a6519848901ae4f89d0913c8de57c53dadf2e5e1aa2a9c5f464fc7610e8ef5f5cdd8203a67a93c33a06dab358dc5ae23edfee6334262f47b19b113d6cafedac1b43902539d74fba29aaa7bce68884b72616a0542c9fc69547cd19ae1df01723abdda65e9bfac5da0d04240c6a2175c0062e4e1ed8a5b397afcd4de38e86209272c7a424b5ae8d5a40b484ce1b4704af2831609ad0f36e90e07b2afed01dc05574ad3971723c5b5c1ddd4fc8bd263bcdf568af75e73d8abd1008c9ec712f80ffc65ac34e2a79304eade1d2a1dffec0e4c98c3582468f320bf8f66
+SIG: 327196ddd43bb602d04d1964ccc059ed627cef0a88d8ad91be4931f17c250d5529f552794a3e269d17a63bd32933eb5e519c1d506574770ae4a72964e06f7d00
+
+TST: 768
+SK: 08eddcb5625ae19ffe7b49a7dc829c893c7538b0885e18f98db78c8beb569c26
+PK: 83478b1c58576a0d1834b28d46fb80516d6fb6f9f591694b44352eecd1e7e89a
+MSG: 015b1d3eeb00929ea80bd8687d18286f0adfe645ccf25a22b5061921e2a030fc76d033fb53d0937c69b31c5be49913ca1f2c3dca121b2b87c59b3c84c7ae52af19c6b9fa1bd675fb6dd8b329d5668786dc7883e2d2e8586ff4128b90dee84be0ab54d6813f7a8c6134757173981775de84c4dd39e336f8a4ef8dcadec943e90d421b229c11785fcd3fe963037458e76c820b3bc2c9476001262b261d28b65b489d76b4be2365e4a80fa871b0a53b6a5fb243688235acc5f4774db15d47b42dd6c8d9e12dcb0b5d980dab0f3ad8a496f76e5006c2ca82675ff194caf8070d04bd384f97e583e73cbc4f7f257310a61b1c8062322dce8115f6dd93eee8a93ffa5cab6634116e1ab705fa86c4a8eaa556c6c89dbcad010436bffe451822491f1ea86c20207e4d12dfa362616c589f97107ea5d8bd8a7215c600ffc70b80e2abb15acbe4becca20d72155abc3dbe8e37cfd73f7420f21c9bcd0c3273513b5049670874d5519b3bc1db523c1d7e90c165967c4cb2845a2e8b47b5889254f58a9bbb826f94521cdbd0416f5f18ff78a3fd0d7ab897906264483cde642d8e703fd82e5ae70a9f978f64ee80520554850528581ca9a0b38c196fd166dae5879b3f72f59cde91cca2c8bfaa478b98d624cd34724402de578e5754825ce227d2871b45a5117149515bff81a923246f3b72d07bd458125c70a14d87c3fd13392a3bda6553016e8b2d07bde903cf687b445cfd6f761492eba46522ada84a9615d8da3498b258067269b788e559b659d4b48a87d880d6378be6a88746f35b322b047845aadc523beaff3070f721c3c071eaa319b7a47c1b20d300dc0321909b669e57d39a1ce2fdbeaafac21350ec2d6e6d5b880186c028a861474d5076a4adc5032fec9140787c36806ef79c72e3a19d8c8b70bdaf207295542d96825a5de7dfe108ef574599b8f184c63a5a131db19b3be53f699c10fc4ca7c63f3500211b356a0ac664ddfc1a9252590026395b479be9a5e4758423560b65bbce5bbade493b13d00cf8c1d3b7e9221367e8f0eadab6e6d1b5fffde7b2d741fc2c830224fff7ff14ae5c07
+SIG: ece75322995154b292437e47d38a6a70af37e2020716fde46bfd393b3d369bddb53253b556621cfb34c8a90254e132fd28ecd098433413a21bd3a9798ca1f309
+
+TST: 769
+SK: 2273942db3e5d3221e80d994fd5e1163af55f5455a8e52be852dd3adf762b440
+PK: bc58674e996b6f3e3220b3e94f0067bb0e9b0d97d9e1059cf13997a193ac032a
+MSG: 8aa0509e4b914186ffff07aeb97a04b546272da2f9ea7bfa659a24cb50966c23eb6542e4f22debe33b65769245c4d1b5dcf3e699c70c5c2baad9734e9d1efe5448ab71c8946aecce5268d26f19cf605eb3bf38b0b3322694ac0dcb76b0f946842f6c5c68d763fce74701bd6b78e71c8c3142add4ed46e0969bb9555be03602d562e4c89f3a919940e883a96940542f2779fbf9ec0a285d9d8a72360146e3ffbdb78d210316038d95d6ab757165aa943c033eebb321c05a399569bcf66b4ddb0b2e0e33c4793d817ccff57f99b3189c60d5d7b9419d1ebc943a79d4d8c394566180594f559a80529cc1ba28877af8f5c0503e943cd3aad99811645272dafb49b9b3e6107eb5e5186e1608757126053debcec75dd9565ceea06a1391a8226d1f4593792240ccd97c67a6c2b1344c22c91f42033adef52861f32a4e0712a917879a0b0518b5424bcdc054b44e972ed24d01689f4f27f5f176f0a578ab2d3c0878272e8c08c21582118654124dca39585337c13c1865814caf0996cadfa65be580dee322ebccda704b2280582604067dc3c6b1f7d8a26978a65cffd1ed3196a2b065fb3caa79e6b5b66c13d7bd7d0ec14a3a4d58413f212f471ecaad3a84af35e598a89fb3447d3324f020fbf1b73e2a986e0da16c0183bf92a398c419a0f9f30537bea0df8df2dc53c154e8ea160689e7bb4d729dd8ab90031427aa3945863a85e89652b9353805166f7c0a18c939954b2787c37094f92512722e52b0c976b9e42af4039d2c0578ff14fae1d8c2d1396beb2d6aa6ebd55474a9349867a03f3a99d78780634ab4b35cfe1b87a9133252a698bc407d63842870e22ccf3933620ac0423c3d1f681dd73c01d06c3b941506c98eed9b7868e017b7f99716b0b77f11321e5ab23dbfcfca9350845ee180444c50ff0a9c965fcbf777708e4f34ccc637c6a08d854384f8d3e2516956c151d031bb1cbe712a5ef9ee16619228bd296f2afe582d9953d590d18bb205f70f844c16c0a2d8318037d43dd80f65c6a753f2a8e27c89c83e7ed70c52f7062dfbb1f544aa236b5c704e7b39ce0a55fd46528083ca61
+SIG: 874ddece08f30b30f0d4c8b3ed7c615149b8aa740daa347b55958f1e2119044f695a21069690506448d8e7352b9046511d7f39a5415bb9c57050fc17055c3808
+
+TST: 770
+SK: dbfa45abaa55415238b1287634d5eec402dadf622e270c04a8914ced270a72be
+PK: c0fe323581ea296750797eb5508ca19a583b537fa7df4529f0804a33c1a4bef4
+MSG: e26e8dcb44e641fc20080e95474bd39d716c5afe5a1ffb056d1eaab0c49f8570717db6437a03228a9ad9f4bb0b343b95e16023c0807eb2a15106a6eb12dc76683e69dda3363148c5d7dd9713af6f87a09410ea8f76b6b78a114429bc85f784812fca31acb0309552cc188c6e9697093cf404c6f0f4abe8a1608673fdfa5eb78f65fc1d49cdec4094b1bd234a46e0ec62a4b6d31b829611540127876bff4c173de058cf61004b014a7bdf793dfd6b63c507d2b23e0f56bc2fe6baf637cee40d18992295d848ef498f8a161bd87e60c91f97a91e9ef3f6d97f2b2d2104ba6fddd6c680706273dae87e6eec1af2a45984985069e809e8de32c12889299a32d40f38774599ac3324b7cb0a4ea632c5f910ad87f5adbfa5c3bb20498279fd53c1c267fe0a84773085da266b253cd853df7e963558cb06880780973423c564cd0bcd6b93334c195953d7cd899f8a547d1a1a0a8deff1381b4321574728cf71b96ff209e899daa8f13f41b230e17bffdfdd2a8943aa5d21e5f36e1da07edd6cee92dc48b5b2a7580146a9baf713950ce676255a89e34f8787547d62868db14ba46594da310d7e2d9e7c7dbe17dbd71eb47c56c5721dc96d696470573794809411cdfa276b059d0007c25d74b2a67d38246de11ef46dfe2670926fe4b63656231bc7268bba23f378e84a428c3cbf45cc539678fd467cd33dd0757cfa024e54da1ff54ce820229b778b184be1fa2e8468cc19955940735eaaa884022f6418b0b1f26bccf169f1bcac7d82a35ab6ef847e1dba537dcaff57250a8d1c71facb134cd06b01c45319132745dc488888a1d7761b8486a37e6988a1120bcc1682dbfc89143fc35b46935d8acf6ef3c42f0f4bf679dfd6ff44b6ada26b01a9f89f374c7d2ee48dfe1a410e897cdfd97f626d2668502814400793b3b07c8720bbddc59cb0f9de964ae075b4af3dd4baf6d0e4f94f294e8109d6577c4f8a9c7a5f7d694bf88f1a5ea7eba0a66da6c770c08b3abffc534df219dc3e3323b022e96cc86002b189181a1d2b527d27950b7f425a47da4013778bd00b71105922204921e9dc692c233f7baa04
+SIG: a462a9baa56dc0f7a71bf87b95f48d642022d9d1733ee3683777a3782228ac85fcd83026be4ca97a345b084f50874e9124e16ba17dead4ad85c0e56f16ef1804
+
+TST: 771
+SK: ef64e17a53f7fbcafe3ea4687684a0dadb18d03735a40a53b3edb04907ee6162
+PK: 9186e6bc142961c4d3eb369e9e11578292de5b6af534d423ff240fa26e21a781
+MSG: 6882456cc3d1ad0daa9b88eff0969f15e97b48d051967e1390847225f26ac25559f0246bf7d683fa28ecedad21491d77bd2696fa835d0fd119884fece9d803691b2fd3de17ee087c74007a7de9bc6534bbfe95fd32e97c375f4cb65731aa1e8346bea21be9f2c3dc874af0431906ccbc2c600127f4d3b069eb091d165ec453e672e93cae8b72f03371d8b8a8244ec4ec2e09f31df40206a2b1c84caa1b993cc675fde1c79bd4a7d15974fa29ce2e892c2899cf482c3d9663f6d2a79784f41c1f5866d37c8546f357d564d3c4218dfa6d20b6c282b400fedde52439d472212c5767a35da5201032da8730968b0720e8a604de6c1baa3f4e896ac2614fb1ab6e3f6cf387a8eb2ff8a92147ab349238432e509d829cb75b2c1765c51221848e25afff5f16e4dd0cd5c9f713c4aaab2ce836f8494506b5309dc2b0ae745bb9c4798098fb8641d520a08b02f75ad80dbc2ce29e890b4d72a3ffb2a1cbd538e1229f579c29ae66bca85e0fa08c8647a1abcfe8a49f5e508d4d2495556623d926ce49efa4350aaaab5cec2cd885be1d63475e3bab7c7cdc8d656173b8d45602f4b3d281241d17190327b24c3836b19311a193af86a6768f04852ab06e67c8ead591cdcbf3789c613209cfe03f58c0305f63203b487f7c5fc098877ec98a689c9d35af81e84078d66fe9e4eccbb1cc6c71991c03017bb811f41f07de68fad194146061324f3d0ef217a54cf38f7a625a38869f67d0b7431df937cde349c175ce8b26ac88d39a43e279b018764efa4dd627cbf591f6209c4a5bb19ebfa7c7135592d02e501cae5e6b31c90e72faab47f7dced2c48adf88443b3ede60cefb0d6379d6922ec437f086bad6217d4d4ffef18e22523664bf4e9ca1e65a28c2a7a60c5f6bc906b737c29935f9097463048575befd1a2549dc474b13e68aeecf166043e075aac515540f831b43066cef932e63dcd5b37b61578c35b09e45cc2a8def57103edfc5f649831a8961fe4a4b3721f1d6df4ea9f033881b474300e0f12cb9cd3babdcffbb918dd9bb0e2f5b21033e43023a0d2e66da3ab0f07ee988b16889ca5d51abdc05fde
+SIG: f58f396ba27e067a5fe003e385582ae3490e05957715d704da0da63a6419d2e4f6dc66b7e88e428a6f21b9ea202299a3c36b242b0ea06476ff12d0b6580c0403
+
+TST: 772
+SK: 3347dc47bb3d2e5d0286ac06a54fd921c9e96b6899862a54e5cc8115d3d0ba99
+PK: d00b645d86dbb7e524757ec778c62b7e60d0b6576883338c9b67c2c7e4509268
+MSG: e2f48edf9d643320ab991c8ff9f6aa75fe066e7d88ff1e472a5ac9c518de1fb62983b1007f6422809117bdbe8a0e5787f66bb057d27f129a200b40576e1719cf9e98fcb72af94bb82ee70f3719a2e2cd9b64777cea5e446459874b74bfbf56b2d2526400592a9b45a5cb798092b60a81b71d82f0685fae7f810b52d226adac7ad8a9183f09febee9d25046c0fe306681ace2bff91b3482b0bc30b2021c4341645d675134fe3081c51e5c59e40b375a1434f63b426e30530da9353bb2a9423220434ae59d7b6fdc143f4982eb8cfa7751b75bf3e9c913c73b760b07d395310c59f3b77ebf12ed2d7b03590d3317af17df421e78b0849fd56d945c5696a040fcaa78a93ecc16d5ac3445063611f3013e9a3ae2e1c270dd01a8ffe3e6126bc1e4c95f6547a8651f26b6404e39ee4ce7618918f3f937a52573ec277b771e91ad096fa15c7a340a809b470318a4636423eb4888a12160c4663fce2996d638896c839b2c7ad4b3a9b2e6cb71e912fe39b843c6e0832eca22de938b50ae863e48582c10851232f75e5225b8896b5a470f818b6fa39eb7bb590357678612d25fe1a40ea1b9d71d880909c1bd4ad176cc0ceffdcee7099e7882a7c907e4bec79830c6771acb89944bd54a5165b31870916921b198acd4432e7eed8ce1deb345b107eda760266fcbda3ba5229400a30360a4645ca8db38c3d5f4a8def157bbdbbf2c1fa1dc6b0514a4f5a0364f928381b40f95579a26467f2282a8a255758402ac9ca80e89b9cc6860a34bb3f90c3237657c2129ea48c852b92569e81106bce461e2024454821a917592d1991b5b69f27bbe019977528a2fc01192c56b4aea873cf8c58dfd7cb4b0e917e87a8704c992820f98d77404d3f1d2050c6743f6e93cdb51a61aa6f45b351b26461d1329f3151272ac396234d0d67c178acf91fc510d86429c69a87fdf101155da8d94de6722238a6fb17016862b11d502c667ee9ca0aabe1c20b97789f1867add78b8b87e9ab51934c0b4a16c2cbc4d2efedb79c05b23e0cf789201ac75fe076d315fcbac20ba0d31e4dc616927d6eab1b1c87a1c9c778e4bd285295874
+SIG: 9ab4299b17729344750b69dc6037368c98f47be627fbd9adfd8db39f9964ddb7bc92d674c7be740756396baaeeacbf74947b6191c6ed1f5d32a63df36d542601
+
+TST: 773
+SK: ff15d6e74e28e41d05a8663a702f038d5b8578c4275e772b73ba440bc5f55a06
+PK: 4747e2e9b82637b3844b85f75b59f7136b7fdb1a62e7b70d6aac17b3c5752f2f
+MSG: ce7bf972844f5184ae8eac87b12be9202c7239961dc23cd41ff55b9bfaac0cc06f3f1decfa9571095c8e82b4eb6f8a1c52c8d3deaa61a9aa94e2ecd9ab5b8063f2da6d8015df0a5144fa3a48e305ad9f41eaa11c4d74854374ecbf382e3002579a9a249efa1e1ca04d338447d7f2206703e6cabf5bbd332b42573bcbd3b6f71b7c3bf73d4c774aa01e866841432829d07f96e1f61a20216d968c90e3ed11f663f7d6271622fefcf3ab68f344328515d5cce2ce85e8bf3d1d09043692e1fb8bbddc07a4ab0a3eef8ca6a420e74bff8d3d715596aa821682954fe89629ae27c1bb03b6aa09f36a39a3e37ba98132f4e23888f9f335e7beaa2cb2727acc3d2777309b85295232e54da88ebb6f1053d6de79ac6609852eb93a0a35bc1a7bdc22d628bc86124d696c3f9828b6f8b9aade1a65216177486c252a4b42d90a4e0fea2093489e244d808ef7021a97d5608c0ae1d663c775e8bb9e9a7315f1feb6d129b5a541ea5929a2c633b6d8c3c45441717946cf873e9b4c512180135d54f053abe44c6df39b7b062ef7240162cbd0b851afe5f91536a9499418e8bff4996473d805ebc1ae48da2d0b129e8e8252f1d53c328f32db252de3befbe5f31280121143a8004a4cae631c827409e520e394cd0f8950cd4c3cf3f3dbd4952a4dfe69875f565389061ad0a0cee6b6aff09ceca26d990e896a2aba9f3b26015b63423768684c03ed0de6cee7ac5bbdf9f485c2275cd12aefa8f907b851a02d51c34f121b77f3a56a9ebd1d65ffe89bee381ff2a7480e8968cff25ac8d04e149a9d5027d14b88f8ae2604d2ac22ac67d13e90ada620c2046d28299384d0959fb76e22588796ce427aaeaf4e2a8aaec3e87f84ccd082524c96d766eec66f0bec3e799558145f09d330134f1c63f37053cd4bdc1c37fde97291857551f50ac8e15f06ac1c73daa1e8c5bc9277e3d69cb44a3237ec57dbbccfdf6685ada20b74a1bc6b74ab05690eaf9bd0c4be17042f5cd320cdd613dc08d29af346aa4191ce0b4f85bb2ad7f3bac738a9377ec6b84062cc70fca9ecfbe1f57fe5b2ce7a4f739c81cabcde046451dd61ce1dbc
+SIG: 42c1295fafe26de3ea34926bf1ef80bcafe47b21b90eaed19635ed7538d767cbf3a1e5dedaab82adf75120373e923202f7fda0826784292eba8b238b6cb88304
+
+TST: 774
+SK: 1ed37b610b8b35417d04e59aaadac688ff81f1e507c89b4f400160941908cb8c
+PK: 48e8cbeb1240bdebf0a2d92953aa89b282c49aab2c38ae69044c51515c3300d5
+MSG: 1e6767df97db1cfb4088da7b200d9f59ec8dd4533b83be309f37650031065727cd5202cef48426a5f3a11d50b381f8bc22ff101827359f2d0a610a4f755464a0c891cbd98d2dcb41d9779d288fcf1fea62e52163ae67e90428b86398efa218f1b982081fc513305fd3e8ece7f9acb0e10e001d2ed299a48a80870b3d5d8ab9006309b31591caf0583380073a2db61f45254ab965b5e4672c4bfaa86e336c49278552729fb2da76ffe502ec61e1696c7fc9ef19f7cc2a2775b29700cb384294063a17fed4fc635bc13282a90dad0c00aadbcd569f156a854f8ba9e7d607d20f2e9e5337981161d804644668d064fa63dceb9f5801353d0ab9f41d1d8bdc76c13ab2f023ea01adbc4c8168d939e98f64fd8919384abe76709263c0cd7c3efadc2801cc4abd80a09bb3ed6bb78cd620969cd35c6a3a5d01485ead4c45ebb6ac6a83212a7c76675427b21da8a7a5047b30a6100cda02476c186e6ce40d2768a942c9f87305e9d363b524c0094a9e2e29f585894c0adbfcd60690fc7fb0a9c717cf43b484fd45151b1304169c26921db2276ec05ad22ad166854fd2f94085778c470dc452e5cfa4aee04facb770526e1f248d3d15c27280fdfa1fd2c1044bcbc881c3d99815c97fbea46110be02dab774f3a610e5802abf36a49875c682638e0ae4cc8277c5e9aa7307445e6bbcbe549eec2a45b1597f7447107b62e2cee0a5fc51beae3e1fe9befb1885d9b30f9b4f1f56206dee0d67779c57f484c8c3c899a515a9d1c10f6059840c1c73d3f05bcb88590c52f7da391838dc2e73228f0981c289a4c27f0c757faf7b3b89146e33dafa490d9e0f9275b0cfa6a7710a73831459595bf732112b62fc864ca4c829784a3f16eec4e18f936918a7b9891669e933223f745fda562bc0a4e61e3d14ea45dfc327e2fc0cdfe6f2f97546c90fce82f522291480111a1e6b9388272c0be28d20ed84bb84d49bc199cd599948b8f2039d07827a3f4075d3a67ee572a01379a36213fe116e768b4114e8a4b3134c3818960772d727b0ca6f7c997ca99843b7eb02ffc013971cbe0e6e60d49773f1e8c0b30606131cb10c3e04
+SIG: 8608815e10590d5504874d8999fd6f09626f950be20c912c27c9de6e79b0faf777a533bd5bb667ab513a49458ecd6787a09ec0df6c9c9d6333c5e3ae61ea370a
+
+TST: 775
+SK: 84364478ec94bd25c4bdb82d296229e6dace2b1359d6d21be2b3afcd7bda19c7
+PK: a1814f8ce0fc3b236093a50f468c1316211fe6c52e2345d9f0766b3688a03cad
+MSG: 7bb7293de55f058fb2ec22b687260543dcaa90f140b9f45eddd4bc22e40977e00ed33cd1ef1bba13c1d0990859005569a80767e4864a2cd288c81393e04ad971782e2bc493108cbe80dacf0b7b9cd534988407a4f9327ec8e9c4043284ef6ee5a26a5b417765d3eabb48a007e7c7f32987d70a139ac41678cdf7a55cb80cf9db5eaa45f3de0fbfbadffc40996370e48b1ff5edd97940e750792164836a4a5ac2e3ff53e48a1e556db9ad0c5c0b944f4aee519a2b0a88bb1c1fc7454524cd57aa5350986243d34fc58e24e819ec0b8545d8dfcf6b20311441d3a35d3e71b3e3ecd7884dda8433a405e3d9969000c820a89b95d197841d98ae734a2e81daf6a7dcf56cb2fc26f2165a5f42b86c7e9e5b11161700a1ab9831f3fae58e14208be1bf33b58ecce81b0c6b7e02f88adf9ab030263e2cc9b6e33ebca3f495492e32bfe372537de6c6b87644828f74942a02b007f14c3fc5dbde76333d36d07631b7a9924f717550040697923fa7b9546bfb0217024ea3f252b515b5d64a62c48e027cef6750beda49a02447039b250a0bda07dc062491a662e26874c8d00f80e6cfc8b30f2c3bf7720b57f2615fc478fefaa6d31705b43c5a54f758666b302a8d34953131941b7957730476794d0bd9d2dfa72fd203f22df5ec6bbaace8b9394bebdaeaa561461011b4fca6185c9a38283f5403fdac326d1f734c6a5ded6724d9f384aebd6cabfcbec12abab9820d080732515e0500cf5d3e2f9ef80a4d7646a7da9eff410f507c69873b32d540ec32b283ef3179a4c632b366576dff058faf8c8c70bc69be808982ec1497ae8911b00165a66695f4d3b987e7390b5cf878e35e676541285e4e13dfaeb2f368cb511b778b106a428778a1b8f2a7d2e093519bc9b5188e38c6793e96bd0d30e2a3db9ee1468c3dc87cc365c810f9dbdf01a4b51421f6fc8dfda3a16e2da7ca7159b686a5e167338937882ff715d3e750d958fc9e4b1f0553129299aa8430183e506cd7f2b279076e0e1cca9749cf123ce507fe07ddbbc4dcca6cdb9ef1b833f61d4bff00bec012158f432ceb75b4f2edb1bb84e5ebb9259e09f9625ce3
+SIG: b4c2321ade3c19ed4ed4c639d5a4d6f2be8e2fb13bb7bd625ad6dc87e2c20f93ad6be7b7e42711a878db9d76054bfd7bc25e3774a93da1543c9b4f6633b0be09
+
+TST: 776
+SK: 00db37ad2a195f08a08440d059259e539feb40b474928255e7c94ebc3b05038c
+PK: 04f88bf639e0f71a57d0d0afff5fe97dde3809ff28ec68eb6fc423f4faff4390
+MSG: 5a94f729d30dd8aae2a5c8c28547bf4506295dc61bfead9727746082d43b0f8114c8c18c5edaf2fec7cae819356338f0bf115a17b038acfd7c96ba6262cabd5710fc0efb43d13df4065becbf1b9e279c03ec9bbfed54d9a13fe06a55a3bd05c807858b41e18dbde13b0907d4034132262d9c2f4d2d376e1609ad280de20ba709844dbd12950257f1b07ef8cc3337c01a702693fb4d92d047e698c3a6dd46c4a92a10d4c780e52e5025e09d56535d7eeb9fe7f033e6e9260a68f9d54b6f37cc069656e3bcee06922b349681a8e7751cdecbe1ecb663fbc6f7c861f853dc310f33defa98ee343a68632ec22cafecb7f3212f81e70b71843b9fe8c86a68b5c86f0322d348a76da7f1ba0ca3cd7b6fd15ff89292b3f636cd08cf625c74d5102cabb571a3dba86a1c92f41c7203b44942f5a24625ac37d77e49a57f118238699d807c250d5bf46f7a3cec5779a6e5ae1a6ca160cff37fb3b78388fe9c030c40e7154601081a517fc0aa1802cd3b845b946efe94aa8b9e03f68a80ded0dfbfad4daee40fa838c133841ae8a3ce0d79fa8a2b9434bac5e1da6e0c7193e8dea435a03a85f76184f7ebe2aa749be9413104a178689ba6d27e94fccf61eb3aba0e6a5a63af0ca8f05a35cb63705194e44d9293de3929b0d92be6f8e627c350a83fc9000aa95b93820be9795c80b5662cd7b34822328061356dc580578d1a35b10140dcd248e4853104d2c5b2c13ff683dd5c30794be4a76858af1c0d9af347ce1dcd972ee49aac12bbcd899c9329871d3e7a0683d175779afe35f26a2d248fd780ea851dc4ba6d21f8a171aa6cb8697d9d112161540307cd54f931775d70b33d3b6de1091fc1750531c08fa70f7be38aa110d6746bb565db7b470f900850fbbf1c662fd613e4f3a5689549e3107e9b0f17def7a5bd7fd7596c4d04c7f48c779fc35e09335e1df784084e55d8551d1ff49de5b311cd350f347a0bd2863a2a30e6ea183ad2e3eedebc18dd28c6a596e693dc3389f7d90b713e3a85a62516305a70667fc1fb3cb10e8a955750273943c568e10769cef78199df4450dbc490fef1b304b052221b2db9c44fe00345
+SIG: f4d1c80f5e7b91c5c7a82a682d49ba6fb19d400a299748a0c969bb99816998be634e84da78581b06e3470efec39804fed93d29739f0439a8095ac40d9d385e04
+
+TST: 777
+SK: 6ca1a1482a07f2a6c57f041197b34a5119e68903cf6dfb51711d9550973163c0
+PK: 8034a55e3b6ed799f49e2e703a81f4ac02573c445d765e3069be42f09cbd18ad
+MSG: 08fd8487503c3f3296b6f1b64d6e85906fd5986cf9c5d9fa8a59d92f44e6470af34bcdef336ffdc86456ec7a7b5761f1adea027326630e68abc6b8cd5ddf40b641a259ad024321bf3ef98e7632797149c492d53594752c550dfbc4fa6bf47176f423a2705693947aa90d68ddc8efb6cb9dbecafd2830d04fd93b1e9e7c12b93e0d0f3e2634900f25860ddadbaece1780ff2d3f3d9fb838fd0d5d66f8afb305ff1a1aedca2b974b63e43f5b3cc9dfed1bcf11999176ed9585ac829bc6794ef3acd872e8d2e92608b320f894996a562e1eb177e21be57c22c41ec259a3dff9c7c9491db838d76cf9b0383111598e357f44babebf121bdb24ee9d557b7d5af491a0a0365c90361fe4f7e3d13a17da3a39fd43f690dfb0b2d860cab419f775ab7152cdc8f2afdc50e8d5da5da01706eea2a2ffad4babee8b03da336a4d843d9d7e0a93f36a92e6610a368b63133f05a3fdc55e3e1a440b0f87a53364c1d37242c57a109e6df69345b01c21c1089e790a66f4f3380d3b76ffb420dfe1e6200eace579265a427fbd355514ef953e1a6e968e37021b3c6a290dcd0293da6768dad7c66311633051c0accb0b9165464dfddfded23bd13ef908744f9c2111dc153142d2f10534d893fe0b545fec53fdb3b35b518398b02ab21791fa977e30cf4b404e7a299d3787108b836aa0d59c114f1f36719a7acf85ac994d9cb72306f258f78ac0a3b6c05343e0b7a9aa726e52267edf97f4972f7664f43720ad33ce6e615440e36537cbc569bd6ff94ffdaea51e06029dae78c5b915c537caea6f1504147979b8aaae0bcd9618437ebed0b55efaec320e84c75959a37a260a02d4ef1bb62641520f1a03ddea8c4c1de8d7fac58da408b0ab4757a135f1d075c9f7c99fb99db9427ce9b0d626cb1ac189ad8663d7a714fb5cd1585c3bf99a0aa46d763978d0b12d65c438bbb73feaa51ba26a459e7bea25439466c08613e42540c8c6d54367f221fcce0c5eb6af2faa181ea21521809be75649cf8dee7671db7f948f346cbd0302bf9a06eabc72e2e512b3df885f6daa398f93e36dae2d6a04478121f97787d4cedff6db09aaf10f27b1
+SIG: dd9bdbadd9fdc81ce230288c4a068df07e18b4c7cc51c0ca4811dfbd04765c56bc883240e46e3a42c01d8d2424fbc332b7c5a17bceb1f6e8dad0bfe562cad302
+
+TST: 778
+SK: 2784df91fea1b2d21d713de2edc6652451a0c15954b8656062ea1dedc2445b2a
+PK: 9556db5370f8fb3c7478de03d23df1cda96f2740118efdd3d1a9fa4c3bfe8849
+MSG: 2e3bc54df416741dbe7916ad25f04e48d5a9d77a623e57f9cd61ecb44f09f76833eb2a3e9ab7aa89ff5d2d560c07177d854d7c49cbef492b7f4f7e567de1275124e16ca4a7980162fa0fd162a8e5fd6f35617007034bceec57c8faf7664f4b3baffdea8d8fc2ba22d585e9e2d739f5ffc99b4e0dbe9c3686547ea04815a59c4a25b5f2390668e418ba0fcbdf4c4a51f33905c74fbb830a19f9bc8636dbaaff209995447996d2e5b1c377b4cb87a4e1efe12de34d33599ff397b74017d711edd3e772155be5a4406e74cbe2931ef51359afd51b5b1a7b3ea22ee8eda81476bcc17ea7680f6f3104703b9f2a35cf2627eb741d1a30aa4beef6579ec7d0b07a4ef32abcb4d756970f70a3678e17e6e5731890aebc8c92b956d4b3b5fe2adfd79b211a1883dfc8c9a4b1b9c8c1bb265e1f3dd392445ea59b590a019551f8121849f435b3ac1b29902fc8392554056b93903d5f263b3d540843d6afa75a2ad8304b7690de99a734c3d130b69547b18b09e98cbf252730e4aedb6dc4b58b2243fe55e80939d37b0a59d72226d8a2cc5153095e15994ad62195aa310f2a6426676b661e47b9fcfffa04d6dc625f29f44c7cf620b378a65d238344b380448cd119cc7f373f62cdfad64149906353f3a54107c5dba65e3cc494b0531f4d64749363f230738b2cfeed983520227dd5bc43be59b3268e283216f6e9c75e0c1c71272e54fdb29c7858d287d1efa1917be37c8eeab5e44c3ad7b36e8ac9f66991eb82a5148e5972034ad01c62615a45154579fa50869e7be9876b5656eaad2e43025a62dd134b612d8f4d5ebcf8056e198b713438e8e0e347cafbfcb89e394aa330d4c788d49c658fcfc80b3e0078f0e8e19aa9b8fe8eb0bab93de785d043e0f475aeb60d62e38fb1f8384a00b7a902daee13d2136269e50801b80a65b2f913cfe3ffb365d9aa2fd19372a0b0225695444e4bc54871d108e09c7e1c2b42dcbbacce24ea5bd5bf1fcf4ac697a3fe09a54677b7a8dc8d5eecb86cc792ee9b6fea2de16a473269fdc65dbb73c258c821440407c642f7d3d3f5c708d55332da8343106c19b230a51427f3b771916ae3688b
+SIG: 17d171d946de3516158407e132cc1acecaefd6d092112be653999523e20bd495f7b7f600e8d5a671330d32693d6019c08d2d003b176e6319c35394200e027d0e
+
+TST: 779
+SK: 4bb79236fada3144b68296499ba44ae534074ca94d4b581e5edcfffe13b3ad19
+PK: 0a8399f1e5a423dcf7b25b2fb0ac9e1e9548148bea84d021e0428760e05d58bf
+MSG: ad81abf6937a7acd7f1837f04d3f10e708c61a5fbedeee4db76e1598570384e6efece97c925d2e5c3488cab10b5b52b8a5486e99d8ffe86c1981a1f1d532dcd4d489e5546d86653298e7a5f96e8144552dda8a18e75b5f7355b13541621106e497e51a56d8659d198fe10037e22128afc2714a2cb5a12cc5db0968a343ef918e8769dd6a3e5b9e32aab66cb0239ebe4c17f18218e252eba6162e977049ebac0b38048b3aafb7d4d72263e9212899a3bfe0a69c99e22ac61c5e9612456303d92458b5c502916c34a8ee5cd9a582a52576b6dc9d7d4c642f212998bf3358d4a8c2ea67686e55d489f6a76e6b070e6e995a745326c9aa63630a0033ad30721aa65fac604a6e58c750721a56ca6760c94134d611fab4d354e4f66a29677b1a666601e9da79f213f582037433c07f94d5f0de6aa9faa0b32f7b023fb9fc135a26f97052ac80b39b306aed13926c285419a29b20e2370d8a095b32258fa9893489ee21089c752ec062e120359e2f3515128254c8098cca65a91a022dd057a2c2a1b6b85d137c3c967dcb70aa17a2ff4b37678b382902f0f931ee743fc398ac1b8c10469867308479e40d7f2f04a4b04c4489158488ddb7bec5a47f20ff356d99a1b3e9d0b7fe9b0ad949f298960efa4d9728f8101cf53da3bffdd9524bf440a58b32738d0b6293e853f466ffd42c5607ac9e353ba03efb578cc9963d8aaa9d2e266d1d2ae9296f30c9ef44ec691030d596a401b6cee72a540ef3c42ec0174266ba5401f354adc8e25404437e888b08286939bede308acd30327ebff06270097cc294f0a0f39f9aa3c66585ca47e60c4b8ea36089eb8a9088bb18b0343135bb6a456d2f6a3bf390723e78b42c037c2de2e1432caad3a594021294d43f5b15a2e819dc748e451de40068c8f032f13b4711377012edcd4f11dec1111b12eb6e1b00633818706d7132d991ce20df3b921db2185ee25bb6f5827576ec01ad890f79793baa358c2bbfb6faad11d8cb0d0d2d2b2981fbf4e372349fc6a01c36077b59325f702b380059a65cf2f5ea98d6bdc8152053b85b28c81e413c4cac7e226c13db3267d21830f0e5431102917005
+SIG: 698fab68510db8121a465db77e4f8b586aee895816e63bbf0beb242db4e84c157f4be201ae6564517a870d17f60c858370c01cca17189cb4189e814391d1500d
+
+TST: 780
+SK: afd765e6aac0146d4811ef9597bc3f44763f03378b7be033d6e64ca29decaef9
+PK: 6bb76123d9258922686c53fb6917b9a459cabd30be8c43970d80f5350c2d98ef
+MSG: 183b1092c7904e47a1420317a25d0f59110aa84d6b3419ad456865c43b29e9d1dacf755d9e5cf94c5591d5d912d05ca9a52d015d6e8f5dc94efdce0d7cf5651203b11e5427a9f679429e00414a48eab13fd8e58b87eba39d1025d6a18b2cdcbe147436dbf38a1ce86413ae318765e1bb1df7e2b3be97e90408b11717cf459bcd0f3cac58b4a0d35bffb533e20df37451c11401ce1dab02055c7e08c5ec46390cd617a6b5f22f651830a1112a06ede4c40ab7957851d6c66f171cd16241590900b852a3d019957be1b7bb7acb8923f2a357c3264456cfca9b429d71fecb7edae39b252b4eb610e8c718835699754b8d4124b492488ede62610cce44b59218663b6c9646a14a8417eddbb6f4fbe5a4bbbb482b37a445e3c16b65a141cd3e12a5b2c0481d614d6d208479b9b209b828854dae0ea1eded506555fe18e1854005cf001a8077083498d27fadf118286b53b8974d69fa2825be8ca3d6036a92ca52f91dde6d5b1ffe2888f4d60779fad1fb41d8c0714049af681b755f2d4204eecd09e077210a48a195e72c80e127c3d4875095c6570a1f78095907528cf7746f31d97111c6f4cb25b3741299a7574822d46b6e79ed23c2fe057b3ac7290b460b166ee90a45562effedcc6ba8f4795f7395818db56b6edd59ca2cc4aea1841fd9565becd6c08104cdee26ba9de200773d091bc77a57c547f1a6ba0a2cd717ab32561d7422ea7235adb0cb36bf5cbdf88fcae06630a15647d9a357b4e0e502d273f3796a51e0bc3fedbf7a1e64aad722aac5fd022fa79d60fc707325f127eb1f03868795ccdc0b4cb26f2023d152153a97a260bff11745d2e2cc0bf860d4a6e358a6d8176d2ac178a9ae1a2dc75e8b490408ff7cdf991329f33cb0c05e1e356925087e0b8d96a52351d1d17768eb134cdb21a1546aaedcc687dfa1b22e92fb5241a83677a153445b77d5e703508e2abc588a9f42e5bc710673e4dd8ad703fab2d7db1eb84226c89d8762a709e3e9138a1fa790f2929bff61bc1ea6e8aa1ad0e3887d70a56d4e6547fc606a50d3be3bd6db03663e00ca9e4f24fe8cbfd7d8c9738d6367554b7b601f74190b5970a398
+SIG: 3dc9194d50811419049eaa07b655b7d4064bcb0e7fb5f9e5326b5fc856fc0ab8705973ae1001df55373977dde2d9b81079551414adc71cc852d499b0cf824f07
+
+TST: 781
+SK: eb347145f339edd802785b6fbecd5cb80889ac7ce4ebad2f67076765db939bca
+PK: 994a456eada03020921c3d109c135eb961fcd4a0a400bafd32ca061bbc862543
+MSG: 5b8b31baf88483f095b5d02e17d8b7b46cf46460e64c6b02c56d8dafe34823706cb5c15f338ad9b56586a949711aa7312cc93450d2fb9af4613fc30793a631a55c14e53c0cb15f06116399398c8dd61876c62915f9f9e4cdf8f7d89ade129e6dde7d63671a1863f5da8f42ea64c079ecb9a2c1b1dd9adae60e96b9cbbc7624532aa17975eba17a7af02bfb219aac02b3d4306cd38933a85060cd62ab513a3965b09150a488c92bf7cab0482eee56463f0139009b9fbb3ff4ecae211f428b5bfb8876f004983b90c447846ca4b74566e979bc30c95e99faab69a3ebbfe4da6034c82d63e9c5ccaf8486af3b5e0d381422938b0c22f516955bdc36943173f5832708a33cf52d8875d97fde585b4917e4adecdd1e79856762033af22f254b50ce9d0c700e77a731554fa0113a0c666683f3fdb19e3a426302230b63e33a785ef24a9289455b3b8fc618fffef49c2c6e48fd4bb422f504149de2b4c0355c363408e66da81cbb581552a411e364fe3e4ca96d7072ab072e7568c13d35e41c7825a13a5c68fb9fb5988bbbfb9a0b51165764660cdfa2411f3d42165da187c58edef0105a6db177420543e958d5d5e8a371f7987051c4e1786d018eb3d732c210a861acaf671be95bb63fbc88bf8be7be5390939cd9fb2acf3981dda61b787a7bbd78468e1d32ca46af8fb32a18463c180f524be1da910da5508d42a0051741227c9b62de6d19b33c0bd48067b035859ad9bdc2ddd97befca31e65a886cfc753afc4ff2a7212a89d37c046cdf3999c051ff1396bd99cb54945639eb6462db9ece84077b0b3d6b3df3952dd36756c6dab2abc25a51bf32c1e9cdd0a728a7985f7b7e0d9c1a6f66ce1216373d252daf5958f2e8973fd268fad0efe251ce76fe47bd0a4d0c4f1017949d4c2b16717218e149154ed6fbe56f86d82e19ef0a91631912f2a8f3debb00766b6177802f4b2e79f6e7bfa9c62cfa2f75cdb60492630a85c9b43177d2dd9ba8d0548abe24923ae8443eeadcd0f58a7b82dff50d884003889cb560f7ac53e710a75575362464b1aa43d2a9b22f2bd2162d302faa7452344ce7ade9983687b6c68eca47dddb289b15
+SIG: fdbd15e1e6469df720d9552cb5dd177bcbd292fcda83cd93c88d0114912dc8703109bac0d459ace9957df2293ac16d40d514893556853299b97b4fd4137a3d00
+
+TST: 782
+SK: 3208837d1554b6511adda09cbae565da78439a472a5d1b107ce0a9b1d7757db7
+PK: 9b525e35368a921e3a2e9a35a4de9ea4c436caba27123e5c369e2a6cf5c90ab6
+MSG: 436a3c31763f93d4d546c6d1ecfb7ae45916af754f839dcfe96d6b69c61214d016fc842f56462a3f07f661b2e2505acfaf482a0b0f4f5501eec4b2d2d7d444544de000b990f4363d3f983f5d4e09309752ff579c7320c915951cc3a1e3238c1ba7a19130eabf6a37f5f0bc56e25242f752061f3c63acad992a7501e967deb925b30ed105431e582102fa4f308c2f0683612b56686d52daed6943a7219f3beea2e0a29242e86d5562ffab83b56b263326664e029e961e7017d8e89f5e3e1d10f5932854550ce6e5cd76971fd235cf9c0027d0cfed3315c2cbf18508624d8acf047f9b968f907d9e6f4cfa5e45c80a272c2dbb62c5d4194580dfabedd82cb4d76492344be96ccf5daaf61e6b2b55efdb3f65210a3d6e1f369887ca0ea0d58c3d146ae3cf9b000076884115fa51b5fd66bec0ccbf0d2920196a7d7a38445fbed22dfc7564dc56f60d6e29e592485374c6bd1e5b15931b69ca6ee6b3aa2525c23585f0929f31cbd11fb1a5330216b90ae5a656df7a074cec64e598184f503fb23cc05e65da9ae7e8441f40e2dc26b8b56d2cb523a7c635dc0847d1cd498abf756f5a13ea14f8fab2c410b1a470f49aa8dca4ac0256b11800de0dd0ec42b142c561128d357e783b12f61c668f5e6e06b7b48b7b2254de5bdc1804b723d5fd6a0f4bc7c59e7c5054182613bbd2fa92b4c1da16bc8c97e16bcb0dbf8c92b74899b37f318757140b6c4fd535e2e1e0570a50818cf78fb988e1f4ce40e76e8fe3d697d7a45850f293ce170fd8ab07cf1534ea5ffad34f6fcfa42d0d21a91dfbfe0597c73fd9b9767614ebdfd02c3ac0c49ad10c94be5969ee0808c0a30b2a1eaa90ea43b8575c3056f423cd4b6f34ae51c2223765a9ea21f64573c1a13961321246e3b5349ee048fb62d5fb61b1714391182562b91598360e5f9bf4ac80db246432afb3a43d349650de03d343c2e97a8eefd1bf30c10c25867f53266bd1f0dc14ae1a6be9efdecff67e7d292c6cdfc90d80b886668f04c2a0f5ad7fa17c178b6e9b45a11f4ddfe2d66960a3f75135ad5ed154e513e1a5d138e7371e84d7c92453e6c62dc59b8e1fa93d773a2540d91c257c
+SIG: 709d1ca9ca2f742ab9dd0b049335f544cffb2f1a3693d5f53f8ba083b9b0d86e5208fa8e1e8156c9cc2242775abb7e15af3085868ef457634e9926c404ecf30f
+
+TST: 783
+SK: 4ec6829b43997056d99685389bd53c528de7e5ff2715d65c956619826e3fb5b5
+PK: 7d922d57fdb12792879aec4e8c651463ece064492c721753d22e115509fed706
+MSG: ed26b4130d4ebf3f3861491aa3dd96a4eb69752173fa6c84ca65dfc991c7fe44e02bd61650252a1d23786682ec38c1fee82cc350db7c3c3949a1c935ffebd7baa24f35a393fbd27e7c34c2f9ffda60a18df66c3e465d90ed48fbbad3fa7947dee7e659a3eeadb887f0963f6bdd76c36c11ae46d088ee50bca8187a0a8832db7984b7e27cbe6abf12d2c94f337ec78cb38b26241bd1a3d2f5fa4407fdd80227d2b170144b415978e37201d0fcf43174b9d7b2115d5eb8bcec276a775aea93f2340d4425d34d2047494d917e0dbe37857e6c99859b71c914aad5e54f7b2b033e594e272cc5cfe919f888e55cb6157affcf357246d00b532cc471b92eae0ef7f1e915944c65279315729853da572c809aa09d40365f90875a50d31ca3900da77047c957c8f8bf20ec86bd56f9a954d9988e206b444ca5a4434521bfc9c5f3a8a06147eb07d11dfe1171ec31ff55771588b333eee6215d216c47a8566fbb2b18974646ac5a92c699d77584c0defefd2dfa58fca27199e41ec58a246320b35faab75b97951924226da4ab28f01b47078e712e4fd9f77b251c9667858c28e32ef1cd01fcbe435c542dbad0a84a13cdbb5775e62d811dc690d9555c37f15f91767a561357df106eefe056e7360670650fb818fc6adc59973e9ad5cdcd809807ab56397f3c13948732d98d676f4a4470a95d8b518237e226f0cc5f4765164a5c3ef050714be02a126be8f66546481581b9e94a26aad24c693b7fdbc18acd3ed7cfc47d8ab26745d78e701d0cf05dd844b5b345a29dab684cbc5092ba022e3c582dfc044c3100ad02756697a849822915a16e2a2b810e6815f54421d2f3a6fff588c0d9013c76f33e09beaeef60d8774230e8ce7131289aef2a40686c819fb2040b06124d3d9aa419d56788f17fa7ed9b9b57ceaad1337a0101bea0440cff745ddd9722055d1f9bcfb009ce2c2f41a9e7e86806b872cdc2059bc8ec68f5ee56c4bacf4bbd30ea4c7155864d600c0e2eee73b319bda4372e9c603c772c25890c7610489989475d37a77a4574a2ba55bfd9c9cfd146fb97e6165dcc19559f4f85dfca2f97f3702ed8fa6b3c2a9741974aa07ab6
+SIG: 159ca404f7f74117c5163cf404110949eb57ae2d7662b1ff4178cc6756e90adaeab71b064ce1dff457b2dba7e2dc13c217bcae8a61fcf8ce1487a649c257ff07
+
+TST: 784
+SK: b150a78929ed1eb93269213e1ebc22e2e40a601bdb005499b7beb058917c5340
+PK: 28866b6d1c393cb08e464cf5571440a649e50642380ddf4ffb7ad150485c108e
+MSG: 1bf55d27f9dde6c4f1c0ddd360a25d9493c0ffdca74a7ed5e5a514e95515cda4aad8f45cd6ed7901f8f224a63b38121cbeac2f56dae210dd053750cb207514a8891e245a5d07e7de78a2e3814463f148d2acb7dc71f995c9299ad0d6266cfefc94269657fd47cf5312b92af2750651c479636c9d36aef08f7d1195e7fa1ba3abb5dcb90136b0fb9a37668b87a2db88d1e2b6440d3e6e601e6d4bc10cf1cbdf1d6169c0dc2c4aecdeb6cdd4567d4250b2afa715b166c9467f907d3fa5a6daf200b309c109376830499caf3149001cf3339448ca3d765225d6b3c1cd267cba936e7aa4832539466fd20cbb38323cbb2228a271f2d282561c73ed79a1ad04698e27efe393235f3456c295407da0960f0034d8deefd1c185736fd3eaf1f9a1e32f09174c1fe12720b7c96febdb33e01b1b6a1c637150194be4ffab159e45b24585576846bb64274eca7b39a3ed9357de7b084213024a9e8589263600a2867c2a7cf8b99076a12a07bd7df8d5277bb04ad72e639b77eaca1ec58ef9637e9a2376ba878a457235a06f78fdf0e0d925cb2fd2a38c77188f60372ef6009792424399c9b67928da2e3ba91cbde407e7e876ba98139ed22ca3b983bede0000528796448e4a1055acb2deaa56bc308254c5bd498c275ecedc1357efe1fda01d34d916dd4d8647e5771995a653e0f8a5284cc7bf73157b3349d59e6f920cad6cdd1719f038025c4300e0210ce249faf3c82de1fd1cdabe61c14ecb1df00c5c466aa6a012a9c10dcfe59b7e9d3b155dab6c7b7c1608c1edd51dbdadf6ba5876b5e60fdf7f19e6ef712cd1a7dd3a062a6574a7436b319efb944e4223f542b2502c1ba976be91e05b0f85a09fd793beca883375fb67cd133f5284d89984ff3cafa7e11a9d85e7893232a524ec54b20f975d3c0a1143a0ef41176b7051ea91d40c5f44fd9e100558bf1212a7b891e68b55ca61f4be945266d9a1007a14aaeb68c48e257f0f46310ad16481467ec1773535d5fc084915f5d004ba0dc7591d2123c62207909d84f2b382f5ef12759a95cd3f5189806e273960aee162c00f73e7fa59363957654bb1916b5709bb0a9d040514ae5284951e6b
+SIG: 276dd0962e6ee64f0592441a8af0e5ef8f93bf0baeba20504b9db4f95a00b939ea38def1c797862898cabe9dc4644f0e677e87c0a33b87b6a4d22a807d0e1e02
+
+TST: 785
+SK: 9fc7c49cb8c4f0972d6ed970ae2c6ac337e675425cc8dce730fc41444302935d
+PK: 4782520b06f93344aa766780e54401363dfd7d967cc3bf06488af90920a30f85
+MSG: 82bc2c700db222a4ac914aa2be8fa28e422067f94f3344f5362bebaabed7612b0e464a73a6c456903564b15393485140dd0f3aff90aa6e1661ddf682850d0490afc3d735dea05ba47c85d97e833533514c198b4cf6e66d360ee5bf00e14a3aab1ad0e7b8ab2aacc964d42830c78453df1955bbed1cd68ada3db0ecdb601ad7667d5c5e2fd49e36f7328eaa337dbd6ff70e7898a3f98c159d045a2427ade5333c88fc4afd3819dc82f4daa3c523cb57e35a2a5a725d63d402baef51e51f1ef4f8f9a595c9379c9aba873fb4e765a931da09148aba6ec5b44859b0e81ff9fc229598ac9fbdb0bdbddb5692a52222df52ea387bbbf36ad64d1946bd282e323ff4822ad9da897ff73f01b390cfe2e64de492d55de77f5d7d0060a6872a0183ccba610f53274ccb29ce6dce6a036c5317a1ed2a7c1068c1b246fc1d5881d00de06eb401cff95e6b69148699db13e94bb5b280212dff54c70e56de235a5f1400b5bea56772d060170f1d0657321561e4b49107eb96d9b3bc5adf451c2a524eba4db003b77b632a5d89827a6224cc798e096ba27fb33bf61e3b8eaf18d001ae8eb52f85c90d9e12544803e67ff02047e0d23c22e7f8b980c01c3d4824b2a9a14a2e8f672a7b0ce03bdbb3bd56d754a0964db01ca899d488001508657b7b022ccf042c38fc1949d0e00af4d301d4f00c3dea20e308a0f9dcacb43222b3824144af77be18a504aa8d268b8a5600725e7cc5f3a2e6256a8074d1aebca123ea53a0767a92e1783a4983c5ef3d7dd7f02aa9d1f4f9aac6ce254593f08792014fb867eaf879b88a4efb18e89ba11006ad09d85431cc26575b538d8e7890646c5988647cc105d582907ae625e09cd089f47249e81814da14044c7014e80e7a8e619c7b735f701616b6a3c6f492cdc6ed463e71a3d22291482d90a1de6f097c4ae254876184c562b16575b9d0d19313ed98864f49fe2e1d074a21211b2b2a6d27ddb28611520d5f7123058fd007bb01001def07b792bb05bb741c129c6a36376c3853b8bb4f66b5760c8eb4ecc7306ba3a90c70da47c965f6dccbdb61a7fda18ee967cf8c5f050311092d0fdeeaedd1265defdd660abe70
+SIG: 5c783a860aa668184dd22c4f9a546b5ec96ebad2e4af00f968c688671354e0cc9b572c73bc6f19937a05f1baf3434763965c96e103407f0eb642c5644154290b
+
+TST: 786
+SK: 08bf059b4da9aa7ffc702f5b2304c4f96ca49b7dabb6afb41dc91c0f00c65b78
+PK: a6289ba28e80e8d1a319223e4165dc0bce7352aaf242f70cc968d21d77752832
+MSG: bd4fb28a1dd08b07ba66e17f0c4f21853fefef1c9d20ba7977f154641ea1a18becf6bbb80388886294e0756a3c508ffdfe90b51e1356d112d8cde5ee2cc6332e61d169ccc8cc934994f1bb560fa4660c0b0fd4e8149a225ed4883e68fbb69da7af8a524b17141ccb76b50cd8e1b67d3ce037ded7dfa59bc7c2674226ec7e07b78ea3f782fda3e5f1e9caeab608ca387c304654f801d00e10a7c29f4b0da3e5f89513a98037719a1aef4c2506c177af5451a00757a59f16229c4f4414df51580d48210dabc9377370b6068a88e81d3ad1bed4985155c3600ff48768b903022fe02ae480f2e6329f0bcc91d75f5c6a09fdf77bde90499f3ca395cb20062a0984ad6a0141fd01c2d54dfbb1ee584610640773439a1658d2c9f862f183bfefb033a3be271812f13c78704657e7fb4f850175fcd63d3e4405d192242c21f27c51477f3211a9ce248e892b42fb6d85820f41b897836f20f85a1311534b5c404f8b7a4a0319bc6cecaa57fe4d4f20607c99c2df22fa0676f99d1bd87886c928c4988c6e78c57d758330e6922cbe03c10340253d0dd483792ce75e6cd09d12fbbb041f0205e65ad25ce7c1b24e77ee8d6f915e3bc3e10d09fbd387a84bdaabfd1cedb52c0b1733b5f47088c0d35e0ef458c85414c2b04c2d29f63f77586131ee65530f209b518a0f257a0746bbd5fe0a2e0c388a6c480e1b60714fee1c5941bb4e13f707eac487a9666a723b5793134a268b77597786c3a3193b46d355dd0895fc6216c536a542ffd7d7b08010c86f547a5daa38335a8bfa2655d5f71b4d8807f50c8545c583dd0b690022ee65873aea3e8f1a565f3b0e4e0295fb0d321f5c0b397f2fd0528f86a0d1b707f737b175c69e9e7ae3c84d4b2cf3a38a631aa8032b3e65bb4528f66d0bfd34473ed0101d2a61255b215bc1cbab9a26d2b969324b77c8a5464e5b23df6c5112f9d17c587d95559de212ad241d8b126050e5fddfcc839a7e5aa2fda1ca20c0910d863418f195b38adfcc36e92f2396ac3144b537b30fbe4dde614902f89978b7fb42cd99f13d99c45c734fb82c3259f90b88fd52bdcb88f7eeecdde4c243d880bac7614e15cf8db5993ffa
+SIG: e24765860137689aad50ebeefc8d6db8e936a4cba62ce87a7f580209384a9d7eec9070905f60ad63a7befd7c70f0ae7c8109169aee4e518fcebfaca723c5b207
+
+TST: 787
+SK: dbbd0f7ecb6482cb01c4dbdc3893c0db81e831353a5b01cc75d3b11f2ff3c59c
+PK: 2d4e588d31a384b17858c0d784f6712bafd0b41204cf8f0d57973e59c770d3da
+MSG: e0fff35975eba78da2b0ffcc5c1b663600888e8255cd208f6dce7e88953b7142937389a337ae82f4cfe32fcb34f552a48fa8899e1a659e3ed3d3d290efc9a0f7dedf33e21d048d8d910757037b76e8a7ee9e4eca30f529ddc02ceffc26d64fda7303cc0d8940e9ef59dc983c12ccd1d2717e64d3006af82ab15bb878bb89d1758be44310420638b96a0b5e1e65009d69395d027a5da4a85e901be9aa2c0b3acc508ee18574c1b2fa9bd5d7ae7c7d830712da5cbf26be09a3128470a12a14909a80a266659befda548fd2b22f24c5fdc206ed3a4e75f5320682ed0e4ce817d63d5c7f1ee2b440643355be6542f59dc6c45ab15772f2219a812ef7527642015bc75fe45ba969e8100c268e24ceef9205a83a3f7b5ae800ad06e095b9b139219489793a7bce84ebeb654ab6669e2855ccbeb694dd48651505b959d32a77020b869533e3256d40685a6120bab794485b32e1169256fb188fe76e04e9efa6d10d286ae86d6f1c87e8fc73ad9b59fe0c27ee92a46415b39d786d66325d7fa6fda712f199da554fc1c89944a4e84c196e979a807553718cb81c076e511e609d5cac23d8f45b38b94bcfcf158d0d61602238d52e3ae84c815322f534f254e63389ae155dee2fa93396f0ea499d5d08c2475908c648bddcee591e1337e9421dc5a257ce89ccce4ceea809d7e87134e039db1be598196d3089fdcfa8978e02c1555832da0a72b08ad07cdd072627409c873937b0e835715baaf2608b2395327467cf69a1cdcce6372418383e7b89c8df4d531f585149509ead1e41b6627fea81c7958cb49d2d3c3e2fc691e0b8cf72679c08b8904654531bc4368fb617ac7557d9db8d329d77e48d8fb4de73abe7cb9388274af585f875c0dab793e4353518bb24695342af0f5df5be4e9c7ad215be90e25540da3489717dd3d29254585a45c13e6dcc7e9c8a3a79ff755cbe465b25e23a1da608e1084fec83bff80cfb7442b1460187307acd75e3f2d12843a77094acc32888fbe5f1fc24c615d19a065391d4176474644246b5343da77626a2d483fe204f839328775b71a4cb567273e169640af93dde3eca9116f400e23a7ad3d8fc3a28e565f125d6
+SIG: 96c00361fb71c52305e1ab7707e0465203eb13df3e0655f095fb331942a40b15584143b370a7dd5761fb03c075d04a8348661ccea9ada53365b500087d57ec0c
+
+TST: 788
+SK: 748bb3cd477137bc880ea7c61df25c1dac6ebec9e6c3193d81ffa6f7a81ec667
+PK: 106f28cfedf096454226b3b01fc24ab1c9bbd7f2b0973e56fe2f4c56a0b1475b
+MSG: 00de6d990c84338a398fda5f4a2cca733c56b2a2ea396c2fe667c268e38145878539bd41bc140a2cdfe7e18360411048cca60f35ce510991df261cbf669039d9d25687a07fc0476a41f50eccf38153ee6ae9ffd392b2bec0cc67101ec3696d7a2ec8cbd447b6a6ea063d33ec128ae8b57577dee17b97162563f15e42b55ca4bedbdfb631a9f6262f94ae35bb35f795c35a01dedb4645a73cfa6ed9ee521e4631fb17bbc06ee57316be527427c8aa55c631187462d4b2c8822ca4e18b7a5d4c114c11dc22069bc832656d5f4d39548718c51f5e4fc828f60e37f01307505265acb22d5e8d767b9aa7b866a157c643873e09084a1a404a7bb58ccc4b5a390fd30601c896935e3556f60d2dc6bdffe47da0a687c8ece1241ff6c07d776111ca6598fca968cb6afa0a14a34ab8f54b95d3d8473a174bc725523f8674dfb2b10f874207fee1b08b42da1f58655305a359757aa0251f14138eedbc280cbd385bf4bbf5530114cc43b0474779e204962f8560d4aa423e17e6aecace66c813784f6c898b5b9cb746a9e01fbc6bb5c660f3e138574f59b9745445486c422bc06a10cc8cc9bc56458ef85e0e8a027cb0617d0337ddda50220b22c5c398f5ce05ec32f09b090f7cf6c60f818c6b4c6830983e91c6eadf1eae4d54bde754f75d450ae73129f6c4ff5c4c606f7cadbf4f78a18db2961cc8c8ddab0578cfedfcf95ef0888afd385537d1d0a07648a5ce2522d0633507d77593e1a0366d1ece843de69867d7ac442ba7dad2a90b59d8984e4a946bbe5f172da427638b2b61209041fff50e60ec02ec2c0b1dc4be2edd13e87b64d1d1663114573cf58a17739f463a1c3d6b2123390183b505c8eeffb20539bdfeeb40776d20c459bac4569968fcafe44ea4cd624a84bfccd7876dd7bf55f83ac7040e30f326dce325588e1ba5bc0790265dfdba09839eef571641e8a1234b6cfc3a36a866bd6b92cd71ec74e0d4deb9e74d158201aa502f07c8ba348ac26aaf9b3d070c9a40b52a44e932552b67a2df05a7f0f03c617b48dc2782366a231e0c4e3938a4274b36aa9450ff936be132dcb692838d654c94542c6e047a7f78ba711919f908a15b30b9
+SIG: e13ca8e5ce7c268090908d61cf2f0a3e4572412bf5adfc5addfe88556f148b5fcbe3e1bc65ff16117d35c9d5dc3b117198f884925b4035b2c0de6c402ed47a01
+
+TST: 789
+SK: 393d44dd0ded71fc08477bd25ed0e6629fa7f88f082ebcef091898e5c9e3d5b8
+PK: c52a993b802d84540d275479a1af5e287d19ea13b380fa3068d2f2c68eb97a09
+MSG: 142b6e82501362d55a04b89d541a796863d7783840d34cbdfc516a3c84772f92446f5f0df4c45c6e0dc8ec1e9bb0ff7ec1696a09cd7ae34c10f8e61a9acabd4303f0a9247237621c490e8d9d0fe44482c560d051b82b074ac3d8e49bb2ac715ac4cde3d4709d0ea3afc51bfdef4b656771fbd55f89da9fa6dcaa62cbae561208d98cfa24cb81252b895f6a4a92c8e407af6c1f1ef49d8dde154fbcb1ca457a204b5ea5432e4d71fb7eb24d43f6fe25e7b4c659b0eebc4cbcc8b3cfde07c8f07b18a51570e7163e33b317b61360f9ce08d95de2c3156af1ccc9b55bcf81eabf3c40434046bbe82e02992a2ac8b3b425680a23d934726cb1b7bf26ceb52a39022c00acf425257167b821185f68e3ed17903d8d22275498c39a9e8df884ec00558dcfa43b8a119c2e853b9a0318bbea087f9cec17ca49b70817b8d7c170a8906f3ee9e8f8cb27a1d0f575abfa627e88f08ca4b93c3297c4f317072f421c5e602e2f831dfb82551bdce8d71216f05cf9a2773b90fc93b9d855a91e35ade332a5061fdb82b309bab4f56e2d586a84c67481d1902c261b3f97dc30b184619df9fdfc7a329d061a41df332202133d8eaeeddb4cfcee53536e07aad11553dcf5ed1e949d45355f9ef42c7832b0de7c2f1526fbef86b63649b6b85ae5ca86f0cea6df9c126c1d79489cc3bfc6e8bf0346eb30d01643c010150c5c8d0eb5010a46112215137991085e57493b22e83526b7b172c6c7341c40321e9ceb7c82bfbaa48f3bd8f51372d96d47444ff0d8bb2e5fd26514eb639105e33895fdc41f6df1fbfdcb08466ec2d217fc99fb012fe6540c0c5a5966ed3e66fab1202ab9daffe8e27e8f7462828d662659ea3b2c608cf68e30dbac62ffd8229f4a53f59ae16833b81a159161f19369f60f51c43a217efc5efd6ab7a91fe249c7b8a0c14e9faea533de133849a92447676f6cc18bef4fec7f37319759ce80ea3eac18fa2d9fa02309e1ce93ac6cf4cd2cb2c95f1e2aff7b2a8856405a7b8ebabeb4906d9b9734da9fb5e5d3f322bb5b559fa61ec8f515db9065ab4b91a7a31d5c625061c2fd2bcfe17f94bbde4776302b8aef3d5b52db3bc73ae4a30cc4417acb
+SIG: 84c716e60de67b020cc1a6a24e6549fe56c6d941a8edeae407626666c31cb60dee6be5a71ebd76baf71b75114bccfd37d163a968bbeec1f76972151296c47e07
+
+TST: 790
+SK: 71193640a0a2b22fb22d00a80b33a5514f3d1000034fccd885d8ea8638f0b0f8
+PK: b1d36f723b7086d923119f46759b39fa1e4038c6418c379ba98b5840c7ea5068
+MSG: e0287948bb85a398e6affa2d25fcff8bdb9326f5d14fdeb60549f5fbf0c1816f11cbdd4e90fea039dca60faad1696003f91515c9b272882c95c9a4ab6e2777bd927e7d8442aea6cea619c9b15255fed612b5cc3158fc705bb7a506f4afecf4e34ed517b2c12b8362610e5ea270485cccb3c9aa97ecd6cb19630900f07d94cb293cb6e089a9a77c0194073a7f7177b0230d25763a2ef98d47704cb2c3af4c3c1b495631b4a5b21b2e56bff2ede03ea4fe7cf82917347e3a9d4dbeef37d1cf17615adaa0fd17057969917d478d03ccd8f8b88e5e5acae6732a8161dfb5f7d02123c8d5a565cf4dd98dfc9aaf5a335058a941ca43073f2659615a72fe78c101c41aed07f3bcf980b0a5b3fbafdbbea92fd889cfd53d403278bc15a59aa140c2d773b8889b963dcea365362e426ef4609845c9bce9f8aeb591d1a469b072b41209f5a8b6dc2395ad9060eb2e370978ae3311d1cf0a8f205142d436bab6b95943a97c23e61bd14b2d95672cb9325e9ab1fc9eeeaaccd58b9f4ac1550bdec8449b036039496c5f07a5ed64d5d85171690144db5c81c81cbc4c16718d52c4dfd1958ca5c9c8ba582cd9d706f27a74744c3a05bf1ccd51f1092010d36f1578b578ae0e9ffa47079055ef94fabc9ff72f738bef68461eb3404ccee953f5ee864c974ce70e9037e3388fbaf2889e1366caa0f651e21b339e3d56b9d95ac30b3592a948912c90bf54473cebc467b09a3943dcac4868acb5b35ea691eff4d8cc1cda0c6c0a9c169a4ee10041f35f433fb53d26067b291056b1da69ff46fbea1ca7213659a990d5d5df1406b093da2a33c8df95ab3ce811afb9c98c5bfd7c4e981b3ea94eefd2e2fe95707d89f307fa76828b5c6774950aee80626714256e197dc7da972158c768bbee7fbd169ec15b4bb7be72976dbed3e512766ef22ef3b812bcac4aa3115afe83d31284af8eacea4ee49afd42d9c44fff2d861c08629b55dae00ff674fb028e738b05dcb38aeaa6963cc3faafc7b69245a2a122a96dd2f03a824d72b0fe0dd798df5c4bb75a87324e764a50a5ff52547ada8f8f88e6f38aee49d58ddb012648854cd59d0ec97bc3d58d0ad4491f08590767ceb1
+SIG: a9702a3395acd20d754373095dc61445584d8e571080e179adcba3106bb06a7ce4d460f1261aef8643ab1634f47c9414a32e183a327691e65843dd6c05507207
+
+TST: 791
+SK: bfc9626c91f348fdaf469def2302e9e38f9051e7349e48f850cf352a8331a28b
+PK: 4e8193061c9d65a82bcb25da089b4a80ba41b3dd2f8ed1dc81e1cfd03c849115
+MSG: 2f11f40b2a19f640c0044c7b139680c3c3b69f00ff9f6a4186fd7ded569c1d8c5720f19dd35c7816d08a94c08204e47643e264d425e21cefb83129c909a3d78caf72c46bf1a729765ef4b8ca803fdaf8052ffc6cc4a6b579a160b703b15355c6fcd3b9a2ecbc267e60dd59f6a2b19420e55727a80b0bb64167c83ba0c805deed491d93e723f3b43263d17420b85be86c165c552779db960e0aa9eb4d9f3a164a5a21fab3f509a8f0199a6943c4b223cf9daca7e110e056a81d9ce0e0c02ac265eeac05ecd84448468a4d122b87a3e04c2837e43d212704fd41e7f3d198a2e76beca0e7029c432a0654ecd44f984c5df06741964d8372c86e162a8c5418849b41e571feb83eb42fbbcddb8a082143909eaa5012b979931dc7e3cccb44c791e04b8065ee63f0561da1bbf37bf6503477879cfbaf6d9d7d9a7475553f53535f847a76dc3b2b7a3d1d470bbe17124a88e03fe994ba10c24221e39e3d0ff53c79e2faafa19012d5ef192bc6d5260b66f997b644cf48d99f3899d7c485e684aa1e6e30855cf75c2d80c7a3ee4354fe13c676091c8667373d30e60ff8e09fedef175a1a87395fefa0722bf6c01c6555cff068892afe9486cb1fcc5fb6641e82d87079ba5d7a9c139355d6c14c507dbd594724b55351100965be9e5dbfa7708878c4b29f4d54c217746e326ab2a54f99b881d7da5b11edb08a6d79d885691b1f7085517310b309cf9b1b714aabc5c17a509b140b89b3f9dcee50cab441bf5ad3bbc29990f627406170a7a10f2d47dfc9256154f962308e769a2ab1b2a00e27e327f0d1fa164d1e38ead5ceaae238ba526f54b81b45dea6c8974186b1b6725fa4c83e62f3e254f729871bda4dc444bce78f0903fa318eaac822a95532ab019e9cfc5619e2c2067f258f4375d2e0222ea5bf96a253a2a3fa9eea02c3eeccb028c76bc60d38298b95b9afe66031b1a2a26152fdaa7ef4f837abb51185df8b2ef85ad2c9be6dfba75e37dc7d12e1787fc55f866fd066f12291dff1976afc10da913101e70495d8783348d611b011ec671c0da737bf962cdcc9e4a800b513935a56d084ea64a7d4e8e99ee9440a736132e42c909503c2224a141b25ce
+SIG: 660242c1dcf3291369c65c9d7f89872eab482200e344b296e336a0a2e631fa796024b6e1119c27d52264a49815dd781927a7df467e88b801e684fc602296250e
+
+TST: 792
+SK: 393b769482375b821427a66d16e4f55185b7a3b7338f1a06f67cdfa7e35c541c
+PK: 84afd70678ffa85a9f6574cbcfe3b15d04a9fd15016ff8550a987c4b951c7122
+MSG: 8ae8053e03bebeae544043b8414b385364add1673737cf8ab20193d4aabc8a78e1d69b9c7e52729e69307806e927ce3807b07c68c833c4fcf16db15e7dce604d1798915fd4211689b4864642502d38e91b1997b71823318b69abe5bed6f5e3015bfb22df30db371f2260c5c22eba60df39b3edd3c4d7a1e111cd9b8aa46f67bd0cf3a717af06ec0ce567028e06e4797934ad69b1f5be440ff37a8a034b1533fa946424ac595400ad27d3be76dc89ba9d6c49939a09f2e401c8f20f7f7b4b9e63b9d55201534ab4cc7be885f0432a2c6673d2e765194dffd9b6096dd2b2843918750959a8dde4a3ab407eb2f7e1a49c2597e30805f8480dd0cc8272a320c00aa2b210f576e42577d3aa419703697ca406d43a1a4f99b0733664f6d6b2403cba1bdcc51f541cf24236070570540755c7a8631fcc2f18938fa11bc291155b39d7a762a1ff4dca97b448f70e2d3de447cb08f918ea20cb433fa115e30880c96c8cf5f0ebbcf482309db6dc1fb64e17c04d7cdf7a90f4014d15ae7696b44423b0ba084eed4d3fb28c1efb39828aca2f40ca6df342c20e95f8006b2767a83f50c31fcc1581a09753e78291f0d9931d992ad3604473ceb885ecbe7857cc52ad5585334d1485d022e106b71c29bdfcf23ee8a475df2c090532356a6ffc02232317988a2cbcfbc2a36b4b483cb44510e85599b612596b626572b0996d8a61c0ee3efff1f7c71c05fb5a8d8c5d09d924ebaac8800451c9db2456710a279dfe2d22f6aea9de31801dc742534362b0e810e99e841dbb7f0cf9af1aef542a52c776cc51f287368fbe6ad651fad5787ef77c73535f3dfb3618cc8f0dbb549ddca9b9bf91135a3456001a46215ade388e7ceb9fcdfd0d2d0a0356afbe2cec1c2e78b4d998d4554f4621f1151dd3ffd3ba4c0bc852f311758c5dca425d18ba15a8d67ca401d0e6cf280cb88384a2dad49fae39ba2a77b467b3238aa28cfd137e5c5c0ff9000f8b06a2192e162920692265db24ab6aede535e31c2093be57ebf8805df1788914f3a884f884179015808db4d3020f3e78bc34285d233762e899ebff28428215e244404de291728fbf4124ce5b2435260a8e341180075a5651e6
+SIG: 31f98c0a08fda8e735b57366aa1b83b93dae63b5810c821d99cb39df521feac07f3c410b27ba3307757d6049f22454fb6de9e2c3c2438d68319097d112cfdb07
+
+TST: 793
+SK: 26cbc2510ee6ea390a2cb948a015d131abf4c0954915620b7816aecf4e11da6d
+PK: 145e8dd22b4400289dafb626d95a94c2f3b69c65197717cbdcd85098c5492107
+MSG: 9cebe24b4f8ade86430e279a3c433e4ae17e008852a24f08690cbc3d75e3b7f200da897c25f7483b37637d4bc11008d9224cd581fbc038adada02d271ed2a5d285d843a0f8b79e37945dc35bc264becd804307e1d44218a643e4b59a9311de985d24b4c26fb14603be5dba1839ee0c8d2ede6cb50af67c804519037b1b1663318cfc6e75d0f051dbb5d3eaf3aad1f78ef0cff48d5c55b2fd25db1539d0f02dae9f25148a8d338b97879bbd39df961aa2c396315a2a86cc783581e67ea844acfe8645428a27b8d32ea3064e3bf62dcf58010ec4348862fac25e3d9fcd4e5d65be59905d816dfb964992ba7aceef8c2075a312e5ffc4f9530ea20f77f93e81cf8a019dc3945634364babf79772045a0dbaa77c47a22b77223b704debd2d003f6a5c7bf6b19cd2c49b614fd4d47fd251fe622cb981785c146bdb7c1d2ea02b116923bf98a1afbb7858adf2df938a790ec1f9074adb8d1afb5633fa961a84764010d3bded1c033d25abdb4b00fb05ed7640fae61879df88f0b09e3abd057b9a52108a9bc985fb73a5f29d84d1ca6921b62f1b703c7eeb4815d9dd6d066738db118baf61b0422f388f1bfc9e3a9bed83a1a727dcc266a9988364846807f4d5518bc2edd0ecb3413c26fd0c79b75d8cb5bcd85c06fccea4d03fb8988dff3ed0cc9dbae78d6ae8d5fc4024617a23f52bd615385d4eee08f9134eb3b250c8f822b47d91e8c4d4c29298016e6fc81f1f1099253d7945e0798955da0dde14ebb934ecfaeeabae87883e1cc398067400fe462a2c4e9f232db5cdd61eba949188cf01b238be7ada938f002dc3ae31fdfd425c8d46ea032323aaf20dd3de2507d36bb45fbb91c40969a9e5da20f7f936b0f4b137b62fe2ba3a667bc0362d93fc50d3f2295e167fcbab0fb3a39b7cb024b578f9490f734b28c9ccf7192f183947d5a513efa4916e4d82b2ab4ba7ec2ffba213ce82ad6ed3b10e48553e733c940aa9b9ce71337c6c2805dfb8dd6618b6d4090a3d6cc963ecea26d1cdc2bf5ac999c11276168a931d816469d79083c24081a50dcbd222752385267ce1bfc1db76b1554ad57e34752b7f8983147c116d4a3fae6f6d57e654fedd7378d2b4989ea
+SIG: 6710d0dd00545b444cf714b79144fe79f38cb1c0f5b74248d4f01fe360117a26ffed4a3bf21323b28a393ae9dee07d69e583e316c6a573d37c644a8d62c40506
+
+TST: 794
+SK: b1f59e3c2380d7aa414d0bf90893a38dddfc293859303d16f00d9eae6cb3450e
+PK: 84e3f5f72f19095b0f533848a5a91d0f0743b8e3a3e2f52fcbd7ebe7c5b5a998
+MSG: c6174c9ad3685dd648636017837b8d992200319e9a5a0d26d94d2da75e2c3aff46f42d7b3aba472b7f860b0fe1f695529731fdc8cf0da705d1d09acad04f010837ecef419d57e9ea6cacf168c5215696f471f3caa897607c629d443de099d31753c24677d8d75f4bf17246818b58adc0424b762a191ef39a7076a5ad12614cf54c47eb0908bb866518c5fac1ca2d2e5b657520a2b3695c6fb360f16f4ab357998e4c0e97231d6f89c968dc29ecc1aa91fa0d7543b5d2247b0d85e48743ab7cc815cfdaa82bf68ca6d3e2250bfda27024d61b474c6b8154ac8d1b5a36209782515c1646680d37069b8b4412f951b025a4d543625dd02290bf03c6734613f99b7a4c3af5c5f9e9ac3474465e648423018d40a6adbe88a3301d3d259b04ee44cc0562ee0ded4f5e26ad977ab5631f85768dbce53f616c029a8b8f933e2a9264b1c81f517e9ff58ab9f45a23eeed4204358f8fff0c8f975ef1dfa5776a5f7793bae2f281d7b0cbef240b3fc6be058821ea2b800fffe55a7de0afc93ede9c60c8de005abb9a2c88f4e61e8deb3170f1078a36e2d8f2a58239bdee496e90d137d2110f0ad857a88b3527664f781939e0b2f76634ff9f6c57e1c43f58243171cd862ef4284576172af1f6c3bd37d5d74b28a7a98698bd74e57bbc142e67f703f9d62cde761a02268fecb343fc01418836414f1222ca24bcdd69d005901da2a0f94465e4d4ba68898816bf7e3e4bb79c8ca5997fba9a8df84faa2d24b044c4ea61029a46cba703421e361dfa52caaff3bbaab7fd753f2856d7c083aeb9768da11d821e2d309f7a735c399692dac2f262846b891bf6461af23c8c7ce1d4d9032c3c140f739e5584c36f05eaf4349ff4545f283a4e0fea49430a1b180d0871e3742b88ccb591124fc427ed673b5f27b0b0a6f54af22ba4a6d1c6c1db2a1fcaa6d8a0308b77ef2d0c61bbf51b95f1e8b6abc5041d97b6b6f1b569b3f63cec05cb567aaea106727096ee8a9ea87b8804901f7e88a7409c66f152de9dbfcbe31952e6fd83b2877a775fae425b3851e0eff8792ffb3848f84a65cc317253b272475e717e49e9c6ff6b7859d11bba7c4428c82d1789e0dca5bcadca2fdb259e98
+SIG: 60afc1e991fdd27cc472b9acc9d405b4d2b913089290b311c4fa891ae2eea05671fde7a0ef86557bd867d1c0b747caf35229d6ef528fe3e0d0bcf630380ea90e
+
+TST: 795
+SK: db461b9f707eb2cd7748c44c99562f1302397489353df5f303797fe0d0b58de1
+PK: 635116da8ba5a36a377728e28618e75c5592aecc18e34011c4c42591970b7366
+MSG: 1a2ac8c1b9ea099b831a6812d2b4261309058ea5883d70b1c607b9cd3fdfdb86e79902b0fe89e80ea7c478207674b2d803b0b9ca147ffe62e594f506c796d68997ce482b51a46e49b4a5d858cdeae2c6ec9b694198e6822f0e33ed57bedb0335c7890a72a7ee3c23823be79b7f9471e033c79aeed52e5760fb0ccbb9d38fded8b47383c19103ce44705834c59ddd86f7033948612d6662f516ce4e399ff20363cc7281a69b2d5c307b10b704150184ece32f390d772ccfa78483bb77a9fba84425366984171cc2bb60b0ec6c628d4e9030746dac1cabca60f05683813346a1a5bc14727549795c1c926869e1aa25093d591b43e086e43a04d170d942c4165e1c5ce76c3e64973d9136f9325bee821682f1043e951b02767f3fb458d02449add3e8a66e516fdb1ed580e056e0f78ee33fd9ee3280912fae07fe1ea02527cd001d6f6f2f89ee649f517414d56f57359a846891f0222c321d7e70817995a8cd8e94760b6e74832bab68d55bc4641884221fd29f122d87a9a868b6a6060c87b2382cf7bbdda4cd6aaa1bbc8e6d634ab580c865f5add6a1d54e61a607dc2c37b08a8cba6e610c12cfebef9c989eef3b782acbd1bcec5f04e835ca101298b5e9bdd8813a71b0d469fcf12727d3de1c3f97ddbc6ab2658440dd6421019bc68f356d6f25536865851d92d90fe9969c3b7c35a2e88ce153476ec3973af9359f1677a4caf1cc481c71bd90228ff5fc6dd83b8a699ffe514929f5c95cb4f04b00dd18a2872c41868d3beb76498ddc9234b63f599d7071801db2c2878f7bef4ffddd813226f06db84eb30217a7183082e3c1242bb6d01cd3a6ce27bff16bfbfdd75b7e5104312c49c43aadfcd5b4edba0ff50d2890ca3cd9cca33e4fc694c057c47ebe1c20a4ad115f985dc7442c6f6da7be530b6902289cab9ca139c6b24cb80ffdd782324e602c45910db63d8b5c44ca29d27f56dbf00186ba583c34e16031df357546b3ab9a3dd65e91d7128c939195e646a0f0b89bf5df04ba233d6a12a271f7e04aa45cda99b4a55a21cbbb738515e32c56aac2496232b1008a6761c8045a1fe0f9a3644047b5966a58a600466c1b1d11ddad5aa573c43ebda887e16a05
+SIG: dd049ca79beb9eac325acf44672ff578a968502fe1bcf5ea19d52c0f6778c7f1c7bbf742747907786e608123911a920778d2f9596fe29be7cc28fd009d7c440e
+
+TST: 796
+SK: f5c0a7f8f6584c5d2f2e1d0810e8e86103e4e2d45cf9a721d8c47f67493396a4
+PK: 3c6d6cce49633141078696131a8d84ed823f30664b289af9dd30c6407f6f0313
+MSG: d68abc609a7a0ce256699eb17043defe1eb822c9708f65718a06581fab2110ec2db09213bb9e0f3612ce4a3f8fdbe757a9f0eb2c3eba438a9088b18f6c5caabbe5c82f7a9ab2fecf0f5859d175e139263033742458f82a6f38756cd5bcdf9e0736db2cab20a0cd3f0f1cdbea8556d84909358dd8f69f0dacd49abf8ac1bfe75940d6939e6a55385b5ace7ce1fde120679ab6ea7a89d14268d29ffb46df105bf3909242c6605f3e3e2ab7448937d6db2ba054c7b14f432db41dc18a5b957336b7f52d978ec03e7d5764e9bd2f4b68958d937bf29823b27efb31e25b43925c4dacbe6718a60fea3b3270e7b76b0de0e70f7fa3c12c215ef72b95dc1b5276238179dfc52fc48859649fa582d05a60df68599a1ceea64f6412d3f8498ae2cedb124245883a240bc0851f0e324965be120486e1ea89a0182dfa8eabd3b8fa66a99c51491389f3c83a3cdb4267f3e4dbc98f0c44856b044dc88d90eeee8415bf73de171afe84be9035e0dc4c80cf0422469fe0c9bd1c6aa654a59b5e34eed351cda2871269ac478e8d382e740e9ac7ab4ddc4c0def0aeab797b6f1a427b8e4a8497a0b9797dadcd35c414fd55b783130f6cded38a44c1a89288307eb8425484137a8aedb030d54b616a82e3c5acffb08d6cc1a61745c29afc68a0c1838b139159c5fa6674d66b9e338115aad4b1b4710aa5d9517bcf7e1cb12d4e6a51c11789fdcae9d9bbe78f69a33e52df1833c876b02687a404facad32841cb2d52554e7b8e2209e3f88fd948c1ecf83957c96f43b034beda6c476096bcb09301ad61f8367cc43e156131862b42ece285bec2dcc2d02d094d042a16072eb22ab9888013be82371569400ec1f8ec7e79108c41b853365268fa4cfbc62c4ac12cc98d2ec38a87d6085859567c0f27d6d431a046e88a9815558660705fd05eb06c6c05e5b7d62347ceee27dffed7141540d608cb975075a9644acc6328439f9fa682b226b186154549011c3b0f0ff4f74caa71c1944e4cb836ce851d9b5d9e727c553e3c723cf98c273e5675cab899bb66f4633a76dea357341f983c53d9158ad319ada75408b41c06f26b7435b80dc3bc0aaf22a833ddedcd6785c87d196b0af2c9a43d1
+SIG: d4c30a48c4523b1f84b14b657af8f859755bba6359988b675c6d85ddf35462820da476d84f6c402e65b020d9e8a2c285c16708ae58d1f8dbc65782a898a66508
+
+TST: 797
+SK: 1ab946c0c1aebf9ca37c2f4e2a4b337d5b1ebccd24734c9cb2a1608c881e5757
+PK: 9afc63dfce0d489b40907aeed6dffe4cd8ef5a6ffa22989556445cbf9b3519c2
+MSG: 9bb071b62c04064b0c96e243dd198c39717b25c99448c2c002b84a99204c5a6e23b4b912028675bfdc4df93c5b2fb80881a23e0d44ba18bde99121eee86adc6f842819d6ebc7a288992da3285805a8b8b6fbcd2267b686b3e1bf7960b45f244f852e82492944e3d618bcc4514c17f722ba49aca7f2f3bb4e91f940e9cef015650c3e40b0c855a17c42f11e3a34acc85287dbe0f9093c00373d50c0b3064a5a5f2b1e89206517528295fd871703a8e762b5e76fb9b7473d2149b85b9461f5587ed7e7fc8b50aa09876deeb6e237078502142cec6bddc70140fe1d1f1658d5d3e910fd7036a2f924b499db1756f7c8ce0d5f0d045b39bc81c5c2f1a761f52ff393e0649b8db0bd8854bd026be2c7c3cd63526ba5a80d48335f033832d63376071b6308f05960cb3fc9fac932edd8376dae51f2c661f75b7c6f4ac856753aca62062877609fc4a0ff60670282c05e882d1a035bf9890cab296ac7a8df244c56f490250f020054b8af51be4fc318beba506232bf45e17f5c740cf09d37515a8bc894bc955c8a460877c7854f8be363b21933e16287ae0cb70f222d4e36b8b424975559bb4bfc8dd1d51b3c0faf4a53e302196f9fedb53287d09315dfffa2bc4b3acff137f9a76d6856217f79cbb25433fc97899fd6540f18088e84417e4833e4a91aaba4658ae9ad7f760dd9c5b7191a0d3c05541b83c025a7992138e6d1080da14c2c887c6d670aab374d436c272f9e96f85a9c423379c0d47c46df6de334ea2057158d33231e1426a66d3c70827aad5511b846e03b94923d5f94baf1f8cf11a861373a5b80ad5e317ec2a529e94e636cdc3aa29e5dac205a0c13f68fb198cf9456e6390aead4d9782a1038f6478d339a81bae7af2a04151c2f22e8d39fe071e1a52168d57c84c36293413f8e6ff6934f05e7efad6fa120c8c1c38ad1886a3d00bfc306459203c02cdf4f06652bc8fa0e8b9cc779d43fbb789e7dad5dc99f41d4cc588c1b65426a4e77389edd04977578f8f316bcdd9461d666472cdd276aa569721c65232256ba1cf0e7f5ea55321729bb0e0386a77b865532024696eddef485b7d7b28c1573b9347e414d4261995482e3b312de1331f84e7548607a84
+SIG: bfabdea41810a53f8e527acd66ec106ce2ae1a67ff6a9b522e0f08fbbf1252682cb3a1dcc875601944cb88000f72e13907007903a77cd0db0316d419ac38c204
+
+TST: 798
+SK: 04bb887a8a3184ffc7ea09c9bc7c1f7c3411556a7c7c398cb8b2d98ffd9ee866
+PK: 6ab1e4ae4aa0d38989aeefa805b578806e2e971ac7ac05409958bfe60071f4a7
+MSG: b7ab0c8163f478c6cabf2bbd7ca37cb02456d76e527eea1b0d26db242e37877632985a3e3ca41b52e21d79017bff81ee551ad72af277b410e42af822c608cd69d00bf440b75b787a8c915d70b6c6376c3f67fa64d612a1b449a7e2134d9c23230157d576e06a66a8422a611e2a0f097286c199ea2a162861864bd035076ab20bbae2b4408a2c6433cb23433a889fe6598f47be53bbd2c80f07a8fccb8aae511161e609da4d180acea544811e9449c5dc2250e3e5a0cd41da33a2da632e6038bd86f16d5b7c1be49fc6db499076ca91f7aa028fe38529700b21d072d2b75dcc8b43781d4bc4d3bb584d9da01c3ecc85b1e93fce045dadceea5106468bdfe5f70d66a4fad60e4fb864ec15ea50f6cb797223c8c756f7a1931a39464ebbb9679f6b01687c174eaa32b968b9cface8c167120aa7bd0242f003a0c377702551b30da2488eb2944052934aef4bfe115f0ab7405a3d5fa9bd796b371742bc114a9bf28c5bd25626295ce261a6a83ef60b77d2d32dd7105fc83664aa89765b3f8191eeeed878f2ebff2fb97663a61877c093933bbd0731e63757571b0e37cac99ed01fd214cbd4feb977e856e0a1a7ef0c408c20e0ddaf1fd8f028cfa08c850fa7090dca8cdde0cb6903da18c6290c66a1c0ae0a084bf250c51a9d035e5b16ec616636afb9b5bce36a775fe2175bcc2ee07220834eeb31caee50e9f8063fb1fc8468ae25e3966789a6d8dffe08a6f7a1e6726f93ae7482de0262bb1f8de0c95a99ecb95684d44b3f1a332a18d2cd3dcf253c33d735522f796b651c9a633a8ebe95d02bc0465825ee541a7d927bb5b90a6db5499f8d993ab404b1650b75e792a7c834eb41f0470138b0f578a04c9ba5ad950ac7c9b5d328f3408b645ad9c6bf196dd961445596bc78f284b8914b2a8cf9b7bd3a716d8f144bb6b15d831023713b5e41fda9b587ff9d6cc43c08d35a707f495283e1ace960487e7f02b7543b68a731a29bf3be14b6e9c37174a9f46f561199dbd27b46bfe62243e0c11c0edf13b64f411c8e8eced35d8428f79f10eacffb7234e546413d1eb0fad88c0e938593b43b5ee0e4285d4dddf5295dbf1a3ddbe9f4134dd76d3de70462c2f04fe0aebdf59a
+SIG: cd84f55e5ef4531924c5a2181ec87a64541388c1059406bc07d53157a168e203cc8aa0f0069d53ff58a95b8a8caafdad26363c7d0f8045c4359e97b43602c606
+
+TST: 799
+SK: 9776a467fa1400735412a79b495f9fca078ce1d87a8530d85c26055d3a394488
+PK: c7dbe0e41c0a31c0942793ffd142d8b95cc82e5caa92a379ba23f644edf224da
+MSG: d78553a1b7055b58b213101b1c84c53e164e39c6e9d36db43f30e19e2a125a9a67709eafef964fa5bab7261ddb3a8a0188457dfbf5159c40e51da8208483245781d7131e23a8bee5e506331816b9deeefe6e556e3f0c95c668d1bedb7da635065458ad20467012f59f171352068020ce3c75878693f6437bc4a09f13b9b0f0cddaf1691b872f82008093ebfbe233d0313e72c8632d7d1793f0b81c7688f54470330f04e64860e6446bfc6d96c87569bf182f0f4385af485d4299cac04e06ba473465566c477f07b9db277ab4a9de2fb2ded0a5011cd06d675c0800b34f55bcf3ec72d21ca150c8bf2361287be81efabb96d8688a1dee3f430f06f637dfd06f151464a05c95f5fe76af2e06d0123f6948a26b3be835045aa268cc1be976697107770208a7568f025c2d53c719e524cc369d9b4a337d8fd1ef345b9bca57fbd7b65a6b997cad3fce4cf06f2ca43ebe2986d09682d47c922b2cb7569d98de97a6164f5470eec71ceda520ccec7732bd01689ef81656e9f6d0c58a895558aee863f5469e7ab97915bfe0b80a064c659b183031f7f1a86fb11a9d528c2815dcaa2f0dec3d21a882e106e20493ee0acb7708eaa2912574ae97bb288b41fc0925053a29b0bfbc0ebae8d63cc0b46e3738046c5a202530bcb15b187a72854aa2d8a7a76c89a89a5db46032074e1bd7de77ef2065a08f389d783cf759ebd5a63a44d919f948f560c3e94c4239e274e051a20485a430cbd529f313d9f7ed679a34187b24f8413087a9021e4731730f5f461fc5aad6654dfa1c0504d26124707e63ee57f931b2785908f86b104b3ecb96000251d06ce1fa45e4cd6df91ac15bbf7ca3c3eb8ee0827612a29ecb7a36d5470c40505182fa9ac913570d0c1050d9a43455cb7bdc17d169805f018956f854f8919bbfb719e1867b36a64aabcdb807f48dccc0672f67887450b3f3e958d78499e0d1ab368aa49442e5e8a332bffd44c169ea67629c85724db6f1586b6c6b5be4864dfd53da7c0f7b8bb3573116be5077d332bd12a6300f3a68a89866b479ec2baa277f9f56f6e1d49d741eb322035ff8cb1de85c8dc87ac8e6e4c5d20bfb6d317ab125930c42609be3ae82242a9ef0568858d8
+SIG: e1317ba2a123ae3b29e7b60e8e93beedd7a08451a013695b6dcf358e4034026dc74037afbdd217ff4b148b029138f4bcc8f9836abbae7e6276e9e769dbd8f007
+
+TST: 800
+SK: 09d8122697126dfc7e11685a04123fdfb47ccddb4499d8a3aef418cb65aed7a7
+PK: f8ddb1c00f6e0f4beaa6fc38e5d0a5775ee28c80dbde3f0c7930a33aad7150f3
+MSG: a0d8d8798eba22f56760c30643e9fc6795547ea5f2f2bbd11c0392b2ebf711aca22f0824199fc3188a45bdffde70ece9ab15a5ea89622a5871e0ef7685d10f1274cc195b4fda81f879d1e9bf42f873b20a859c233f9e49adbf057731e11335e9b6d8ed0e069e134ec461ca8890d7b0473c405e8a9d95d15711b12476103762c626d9f2aa5dd519bd825b60b3234ebf651e0d1933371c52bfd8ce33fc36bba328f7f3f2ccc01000a89904af37e4e1e9e15fffab5c2b0c47f37cdcb068db33ac36a5f0d6de1203fbf8949324bd3efda0f9889db00da2317b49fd186999df7fcdc3cb4e1d18faa254561c251178b8d33fdc9dccd8d2d721b93a536ccd3c0e9c856337f195eee7da9a7f6b0a42b7c541c6a68c595bf34704d9fe3a56d2ec8481d577c96ecc08b8e40acdbf050e20c683f39c414e8cbfcf4a0152314c05987a83bde3025b735cca3023abc5feb7e00d0236b4f24b15e679db052c8d2fddb3bef8663a6df819a9815527a1a2f60a0fa4e5078ddc6d435fe89287b30ffdeb5d9ae05d1a8690fbc7590aad57d43d22c12ace2c8196888e354e9f782f5dbb44149e83fb8bbc9da6d89ce206c1e2b6b2b28f933f3e5ff1175a31a8ff5d31e65c8b00c5ba462224a1e09d4f09cb40fc87c36e7d285c774a96976203651828e783628847ac512e5d1c35b35b030171f92396f5ffaff585cead04b6ae210d80707cc6832d98a20d3a947648da2604937fefd25a9fe0fc5cac083ddd7d2075307f4f382664f687dce8c655ded9c12d48ff7601df2a48d37fe214970844c075f2eab002059fc2271e617c9657a01bec1dd38f6c28ba8a617bd30851e3f9dbac904418df1d0215ad45dfc9f02b5c5e9f9bbc6de8b07af0bd1f7fa8922544f12d2a3e1aadff7e9c6b93320c3a61ef33da07eb87b1617f9e77d7702e558bc7d8122e0dfe2ae83e836c5b1a62aa585c0dffe716f7463c0b33da5b1eda556a1ef1e45042c79bdd3ec3cb8863a7bc1b0f7e1c05bd9920f05b4eda86517705ed07f6dca7bb00ae0456e6787d9fae8ede4ecd0bc572eb5cc6d19e891f1bcb229e9409e06574c7df058173cb58c3fdf20f3ff17c3705af62d9b7225c5743f600607f77cbe7d6e7618abc79
+SIG: 18cfaf6dc8e4e8582bcefe0cdc6fcefe6a4a87ea629585f37d2fba446b3aebd452426382da0d491c39cb7d54d273005dc132121568d2ab674520adda7523840d
+
+TST: 801
+SK: 10201bf0084367590de674cc0ed2648ec25d3ba8db40d00ede153398508bc126
+PK: badbd05e5f79e31169f740ba46a58910a1b77705af45717b2af80856457c58c9
+MSG: 7bb1470617d11e45eb602a829ad773ee2bb7e6b88da4c04a7216a450f84993a498cbd3b9254028f2f99fc21a23288bdc1e151a72a9130c3dedda1bbbccd4e6c0f48ae9f35318cbefc959f405045e6e0b5fb2e738f2b765be11b1b6a0f1e8319549d95fa8d1df8167cd4a7717ae1636a9df54d96eaf2d63236900fd11338252a5008d5d480e2b1e9861d1f70688c47eae4689da01a47da3dfb6d2bab3cdf505ee5d801a152c267093d17e9bf7137a6ee7b834d0085500e401c17f3286c1575d1c0100fa9807630c4a990654c1e71a8b715627bb13d442c84a449844c404b872bfbac718a48d0ea0945c77166a53139b0ff0098134764f9ecdb88eabe07ccb2cced4955e08249b2f5770ad41fccd7b5bb372e6c33767e07f5be7d10712de81841b134e193df0776a0fc156ff5d0e96f40a704753e1145e9fa083c4ddeef4416234f6e1a2382c8e5b3ad405458e89d2f493a4d7c29a23de2107485b7f56350124e7e0d695c522b6de7a9247a2924ce6f2863236c10cc21264ad54590d314763ea1a19afacd90eba955870407e8c6365a143a5c1b9a8be5e4a4dcadb72e0d47649bd53abd46b5c6960eae2cab773753cc0e04e99414bc2cb30f48bb54139d066e43e2f0e1a4ae963858bef967df8c84140d2d09202b406d5d85cb7a96cc57f233eb2187ffd02f94e92297b5e69d969d3a5936efe4929144f258bfb39dd0ce26359c4549fc218a0aa54f31bd551b8781acbbf61cb3f732cdaf622c6a69188cf557a3a92ed153e69125a4090ac451536a0e9a63a41782910ffccb4e850021123ffd1f3bf39c73460a65ccfe4dba9bdefb5d5f4da6c469aa1322fa27043238363ee72918688d7ca1c4c2952e430d563256bb86d350a35ee82e01504747f31d02e03aedda546d0f1b2f451b870821602d00e819036ade5a7c7fcd21a6de6af35b1f9632a70af65df6445f6fadfbc0f416755c8246640e56b856b66ddd92a60c03538221dc8fb142ce2dbacdb7425f33cb85d850cc02c315cfc111f6f651dde1bdb67fb208e1f6bde784ddcf7bd18c8051a2e0bbf1018b8f39536c589de65eadc6cf379b77cad13f9089cb323fb2e943d06cdd10705c121134c6548dc53415f8c370ec690
+SIG: f1d996588b298f271e970cebd2a1b339979cd29dddee3645d07fab8ab465dde3e98667ec01ad7f1c0a6592e0697e665c72fd3814dbe189ed5f4e76c794e53809
+
+TST: 802
+SK: c4aa425246b5173f5ef898152eca3d092bb4c2dd02853fcfc7178399f4e2f758
+PK: 29b77a3075f419243c0c1bc39659d73117ac00e55e8de38fe9829a879cc5b8a0
+MSG: 7df978a1f4976838ffed7449a4dc138b604f4b2a4ae689ce75018ebccdab2eaa0b60768f7208257f2b28e7aa09bf6c05888da46fd396d1c803011750e30eb484870c8806977696f12ebb9feeb4caf92a02dbaa22bbff63f842c3ba147bca7c00314278acd0db173569f4e36527958ef6f1002bd3cd01f407a86531edcbd9f31b3a4ab880a4f5b52b42d0d4a1ba66a2098651ae3e6c9151f40273285f7f6a4e81606bf980f689504b42080fdb97c72846fba9047c7e660ba5c6bf126a9a599e2571fa13505af7581bfebc16513f5c94dc71937e6e61b3ea10939b02ea10859f32d7912b9e3806abef6185fcffa68821478005cbfc1d637dd020425620a318074898bdc30931c59ac0c66c4d1238b097cd5b170f084435d4bae48a03d92fd48fc2caa4ffc505f1bca516fbd6e4f888cced982ae0ddb88fc28aa697b7071d015b0acb2809b01d1d9c7e7b53eee6824cc37cce5b6993d88d83eafc2e928a6f147db6eb80b1a69f01605b046bd2fd1d92c5459d6d3398a9caa299ddd0c3ba2e08941307b120cc13992f7003aced14a4a4d923bbb12fc393ffcf920b9f6d4775e94d4a512267fd26a6997c6062b4c9900f9862b9ea0c8d7df19f05c2b604af5b9864fb2754a8073bbbfb18233e6e150f72a525e3a5760fcda7d32a60034f956e3cbd3436c200830b3e7a14571220bcb627d5a4be72c20b23351b2d920602a51c3eb32c1237039dfbff43c987fd8563777f0e5a39f8146c164bdffce44f3b13ee74d64bfdcf9803f03dd0172ac4fa4bf6c7839cb11f3d34baef0e32b54942fc4fa38f473e2966f4911c0e80d76937b25b7632275ba88309635a60df135489208d3e734b672eda7d2ba21579aba8d8860ea764fd67eaf9c38ea7637d1bad57b2f3d782b91e1d5d92ac300bdba7ab9113ce913d0c793c12a9a726e3fcab05cb479977871640630d459e69e81ca5cf56ddb2a0611d61d481c1b8cef3804bd4e5754a61eb49b17ef2b03c83057b5d20d882058c00f54b6cca86be95350dd7bcb25e4c1c4658f45229c8bb9f5cdfcc44795c978e3388d325760106e52be9834bd81ffc5c62486b6f33c27459df178eb946e7a82db9ce0d295b925bb6126dd55c31f49a68dcefc7
+SIG: 5d8545a4be3fd6da2578c2eccb648d83fcfe587133fa7ae4a1cfca9ae6daa49259c952044a85a20b6f5324f827dba2d1a8388c40a928b950913c634fb3092707
+
+TST: 803
+SK: f13cafde6f39b963dca96626862f4fbc5c2e00ddf08beceac7a6e2fca9e1ccf7
+PK: c1b01a91e8ee0b9f19a72e5e7e0aefcfdc44a157474e99feebd0ff552d73b2ac
+MSG: 2bee73b74f1b7622eb096a28d83a819bcec22d9999a32062103d604ae6d78edf8f893895d2220ab75690410c58aab590a98ddff23a94d2350f889e53464200a527d54d62571107b27e574f542ebac249b8e2e3ce08d1bd27bd8d29f2e61243deef0e6938e52ee2992ff2187d7a7f5282edd98fc4985b619acb80aa9d03d6cb84b821106f40d6e5f4c387ab0af6f206615d0a175f7e60ee2755aea34675fdd823eb24109a9bd818ea2d9d9bd199cf8dfe79624b0372ae85e98c60200234bd413f4a62ce68a47b6c9b12857c0d399a448e5a5280e9f22f9b12ea2cd3c68713e77d0a11f3628d8ec5e060639031d3b640021c9c38809dc5f42d2e1c2e2346c86e24eedc5984a115a42de8de7e35c9917539e89885ca916e072afd5d46846b2a935961c2fe28e9eb3c8f896b86fc120cbd3af2aa139c499d29cfc3699db79c14484e9ec257a5f64344b7ad1e3dfb34eee7654c6bf12fd38fbba80fe1762aab57112b3a94e2bee79041d1e88440f85fb72dde68d49e84bced998a2f6335446e4a835e70c5f827fb3ad7823d5fbe3be5f6ec7e434ee524ccd9ff5b7e72a32d091a7e17c8b1ae41a1af31793cce91d84c3622678969c8f517dc26e3cd61d2446912283f9353bb5ad03c111c6233de314c61b831cbf38b04fe58cf44f1d2d0b45f25a6b4e0256859cd5d830fac5ec3c8d76398559e9b26010f5e1da5f25d2200935453ffac5aea51f7e81e72ec8e5f04d2f885c7b45c63f64456cfe231b8cb24aa1620a902639ca78dd391aa4a3d03e11975c8907f964fd55df9bbb140e38d6db93256b4b39c2b7bcbe35b11826bbf8c08f1dcb48edc4bfb70462a35ea8cd8cba79fab8b4c44e73be7ecfa112166f6dcab70d8bb55d8b8428c2da71aaca2fc3d90f3cc5ed01551358d60789b9d571efe10892027fa37404aaf59ec1c2d7111ecc3592467ed1d9b8aba8e229e32d2a00c19db7187fbcb122061961c1fdaca307e9c9c9de972ad51402fa67dc1c2a403b3c5e8b1e246862d6ad6a498db6d761fb566f6065942b60ad4b4309d182bc5154cfc36863185a87e23abaa1d541ab763a4a1066c0a7a8c3d821ae32fd31c8892401046d0a20e91a64779f4bda81120af3fb3486d3fc0a7
+SIG: 6ca9f80a62501faf319fb84af471f676ae3fff85565c97981f1457cbb8c49f97b266316a992db0d42bc502f095a5f2d9a4e1cfac0cc935d3882c8a3a0ea6e10e
+
+TST: 804
+SK: c846344261a34865393834bfaa3a15a3f53ac9e13833b0b287122781b79de392
+PK: ebade0226195ae254b6115e21696a9c65a19d5e040443131c22b89f02f69ab78
+MSG: 5abd13e95b6ee1d5514768282200a14f7d1a571f3468e22efec993463066a37aec8373e5fb499564191f3294a9b30afb5f1a34d4d88abc3e9bc303c1aba05bd8faca90ee35d97ac3dd9106f6fa3ca81a3810eccefa6a209ea3f3fc3049dcb1b003c728f7f6374ca98c582de6db1af760f0a02133ca4a010324304d26a0e50af0d13c134da34a03a41e83ec8f10ea5b859bec1f51b01cabb2d16c1fc52b058f8e5defaede128171c2e026902316f871b35e3292656f0e5b39bbbc81d0c0830e6ac01fac9b4539f47f9acfbd58b7ab9f5a125600f251a271d7bf167f2954ca8e1e0c96e16b06e8307df88bb8e9d57d5ba044f27f3eaff81d9f150554aa7122fd10d11f35d2be2b1624e3e1a1d77fea4c5c7f8b983e945ba8c08dc1545b3e6b2973ad041c44d0617eccc871a3821a9ffea9db7c2b0d055da55de0b35063e4225aee6b225ab2a7906a8ee329d1b3972e0d1f70817c50ccfe9403d12ad62c94923b9aa2d7f85a8dda47be4dcec0dc2b0b58f7ac190ae0579b9b13bbb8b16a31b0ab4d6f2791253ab4751b536b88d3b4937cc3a110aa82a6ffed6853524b66b3effcd2f63c6f9645cea13aa23cd1c99d9ffda4cd3a9c5df45ec74726c3471128b7089fbd82694d2d3f08dc9306c0fc9ce7c801138eb1ecb756e571e9059b75ed03f92a31502fbeb5fec51de9359010c4397d28b65e356e38001d0d51ac9600728c78b5766e0f217938b410e785b4c01e86a3452bcb3884aca47540859cc49b000f0b61fdbe72752574b27a22d4c40413a43b310924b1bb140fc9fdaae266d65930e3f234fe841d82b26176ff86c5d2bd8d965c52d728064ebdf68dc8e4834941801cca0b2f256d4f6c3dd19d35d5362bbf9b8a3a1c863e092689dd2852add488bf42685b11e1e1ad5745d075628d731f91cfd749159e2e1c837f4ef83d80ea1dd9bded5f88018ce1d4b3371f954353f3d894370062c0965d67986dbc481715f42dd2c91607ab8b5f0d89f66e68d73d50d640524d72e69134b887298e5cd8c4b905ba5efa0e9d685214b842f50a2a3983a1af585af2ca43dbcf02c40897ae2e1ab51dbce570345e8e135fb7b4eb0a1d6a0bb5a8a1807e425b2d628360768058e61ad1cfaa2099
+SIG: d5e41b47ad0f3400709770ed43919bafdf24381b661544e51d8b5cee9e97b3676a4c0ffaebb2cbd2db798532b65cf654a5b6c166ef886cb0fbbf4a4f844c440b
+
+TST: 805
+SK: faaf55d3c29714b65c2281e2c22d6134971a2e74008fb94089a773eeeb4483a6
+PK: 39862eac6dd52e381bb34dc196ba8a374dcb7df6cb140fd0cfa6cfa39b8c753f
+MSG: 94e661c25240a89e823d7f5dc0e692eddd1370c35ac44d5a8c8798d0c9aafdf0bbfb549260568dba1c69086bee636be8edccd3cbb27016244d54d7ed2feb7fa64614d45449d7e058e71b306c22e6911c2ac74207bae5a84d0fc247be49d356e5d4353ba5586b6e4b2b97ce9e2377b6eed92c849e676944ae90dc4208e300e19cc91dc26bbdd5a30cfa9281a15efd873066f85af3a26f310623e009804853cc6855903ea64a909897e315e73d312948980ef6289db21a5ebbec8c8efe20d1d53dfaad6d9f4296532e887c37350105a633abc773188751b28c3a08f1b5ee0472de4627e6b61b68278dd51ced6a61ecf38886e45339dc6c60c31e850ef8296ae80f9d31701776eb9af21693f4c52ec062625738d4e3afbf71d1c81fc4846360363ea541a976623a5e4e6b6a67237e9237173f1a1d543302858885714c2a591d0a786282a0285a3711f7bc2b63ca7987e9ae7d02035555cf3b6ad6f71ca98aa928883bf81dd6f86493eaab5637b4dd569d1ee8de6a44bcedb62b9706b1db89e3f05df16310017d89ef3e4bc099b721a5c8d38043d6e4a22cf04009c0fcee6be69937829954941b8b4a1ebf4daea0d774d0782be176c8e591907756c2cf75dea6f7877dd6875b8fe1012f3050cfb1289cf088667e1522eeedc927ac86bfe2c407432b4a813a6a7a5504e999206db1827e25fafd70ced36db3b281b6f7b14ed5baa0572315a939c5bf4abb133d2e7b16d52de20817af055df5f141207734610a0c6eebedafffd9cc9f069b67f9a1c0454be41d54c138be542e5e38cfe2f293f7d2d3df66977acb366a42c19b3185acfa1b363c6131a4a8111c3b1f4fd7ac406d0e69103ba15b8c4bf29bc2ed9c45cfd1d279d8d931444b2b1849252b8a70eed80fd260edf5a3c01b9690160d2311851d21c9302d985986eaeeb3ae2c07c7c7672094f91db0bd50be377e4d1eb07ee76af49dc136a145a11b172f0811fe73d6259be370c4dfcab6f19e4a64b151d0a6db8050c3de2cc325f5c5f6594cf6248eb081209539e08ca3422984e7bf803de3a419b14423f1e5a54224042ce4f05488a6044f4042bd649b1a08ce10c2006ea76efab4641fef2897efd724e6054a3bd1a69e39a4a5e2d502
+SIG: 5b0083f7a82061c65cf6c75640c81c28e8d6d2e87f6d5795c9aa3bb3e390e91990e82db6f07e614f507a560abaa1eca656c678ddcae8198251e6af0b76b88d0d
+
+TST: 806
+SK: 6d7855e30f7a13e237b067144346434bb4b05178c7d88d492e79027c4b0f3cdd
+PK: 7273293828efa349822392dbbab07879577e1a77a6fd6afe33753a9eec88c4af
+MSG: f8b936e793b017580cc0e9cbda2acb6474507f4bca3afc8783ec46eeb82ccd4dd2525676aa6ab5c0dcf7d75f7e0311e6fe6bf27263f8578feb55c5612d1f28e888b76656c41ccd8a70b9bc604b42724fa2bc411d44c31ab68ce84f8393399e34d5408579c2ba2921f2f8d11487aa7e52557feed96757199d3aae6377770154b17f3577c7ac3d8c76cf7461b5e8d42a7185078ed4f862fc57502f615075307b6e103c77c1f6c8bda7aa17e435e21b949af44dff5aa30a62da712fa9966a612ffca14871fd6f860b4a9614012c5369910e0ffd6f0fbd889a9c257c32bdcf90bb80627cb272ecd4599897555955e1fe08cd7ebb21c071be0f48989696cb39aa82ad11baa5d4ac613abf1b6db8a20e686836222833f8b6dd2f0006227be48e8580dcc8de620dacb2f65a693675d6cb45ba5dd1aa70db76bc641d4fb567ecbc7111442e294158be575c71ddc26e94f41266a2fd3a0d435781fc094648fadf5f17cd41ab895821894ec0806b262c393534fe66f21e3783c14a96c88f2e0653fe32e75dce8a463bb97eed6c16f3f3228169abb5b4bf9ea3278c1ff0f86eae71389b6433acd097eefa9e6e05f4955cd517830b8d9870ccb5227415e50f23f6473217a745096470dca93d2b34673c5d6a57ed02c8e0cae119b3f329d8ab6498494c2921bb6f496dd08381e7d39f2db5763b14a2821befcca0a9fd312545de68abf206d12d8e02e73bc7e3cb796e7ee26cc63d741efafc5345f8132951bcfbfddf631fb7cb43ef35b9453c9390eb23b1f9d8b1c72debd24f09a01a9dc60ee6815306188357781af6e1820aa35e4ec121b7ca34d7de7611b246a3e703ed48c7eb03a6fe8f852ee7d32545c9d852d64d5d75930e5f1ebe21a307efa7622edaced6d879026f0f85a9112012803705582269d39f143234df8909ab3d948e76d3daaa24226d9ac601eef277fd2cfc4a19aedf4387a21617b03ec3d3845a38554f5e97036e56ec1ce660df9c062c2c993b77c5ba6a6d05231dae3764183c3e96aa539cfb3415fb163c645b2303b2d6d4bda8ca6c72bc03d5305f9b118e925e27d29ab7dcb196470e6339631b2380744c04d1da348fc0fe274277f82f95bdfb0b64b4cf3b51e571c0ddb3b53ca6
+SIG: 0fe28eadd9e5dd574b3faaea810d44522c8b1bfbb3e3d57ed889faedec91d0e14a86b914c4c766f1bf9b8f18b0db890db6c1b125d57804333619b1e0720a3300
+
+TST: 807
+SK: 7ee4e7e98c6a40f0e74413f24039bd220df1f8c7f015528dbf5284ab9f7c82e2
+PK: 4d5a800f9b22070e016ee23af8a310902b369d589a847f345c2ea2968d6d0924
+MSG: 8fb01373c42e69614aea99af49323785f33861b94e90f565389ebf70e219f5dec732e0010b58f7290530df222ac9c73e1c2e92a5e6061de5590caf9c0d5021d729eaa11541fa1d082160beaf611e7cfdc0ebb315d388e538b4b5028f9b30d3d973347ffd44263eef083b81b21b82eca5756a494b1d81c07de849506d3e3b668797a5c544254d4ebe5cf8171b39f8724cbc4189291b3c53c21ece49a1d739563c65b49025935647a7303ae0ef7f6d24554645a428dbbb42449f5399e36dc787b7d6958a02eebbb836e5e53e26e487239de94d1d250e7943ac0e22d92750a0cf3473be1a6225cbe79545048269f6237ec9f9ec307e8a34b7bb34cd4906e43162a3708f329c5b989d7a7fcde1099a542546fe9c33182ba51b843e96d11c79e91ad21f7170e257fdc2818e12f9168a974c968a4d273fa3ffa9f35ff905980eaad3721cae802bee36210b40b99319bb669982e943b270a4c4d0a92ecb5bba2dd8b40ac3d2f0325c469d5e9d483f5241974010c5c0da335f16e962196c2ef14eb24aafbb311bfd5fa8dc8d2d61e6878ad2cce0dc9939e44522723d427ef32fb43b967f5e44fc665792796f8cf934f01c325d63d583dc3ca9d4fcc757d9178580daef53aa3ab21d2ce435955d1c6d47638c5edb62ff5561693d1cbd10ec9e399a71bf9db1c9969fd59e4eeb31aa59bf39e9f184178def7246ed4b8f4be5badaa5db4af867f4f2ec39a13704202c8784fa168ce96f9cfac71017236275fd857cc3c51a9c7ac256215e14b843f7214dc9f824b91d1a5170d0ef1d37696f93ee966a2b7dece22b4f3afd39c16d601e5ff8408d45c1a6ce71f060976c5be4c042b1b738df9580ba5ae77880a70c0b94f0e1c9f9aa34c090d612d57a9b931f50a125fa35ce40a2cb7faad530f80908c73cb78258afd2631390041d92617e9bf64ce96e8e4ac7f3126d8af8a04c75ffd438769de06f74c2fc20cc8192da353e79061283bba08a8d24e6e4e2e83ba5b08e4275226062148d8a02afad65b6f627cfbd29b71ca18aee5b1f97169bf0228b376f4106b50fd91a38a66211d69ebb4a7af0e1c2217f1ba014d1e0cd17508d58155d163dd9de2fe1c64c7f88d5b553e9ba1e1f25430d7e125b07a8c2ed
+SIG: ac3bfe3adf941c934d3349c492de70d5166be389f955be87c2883f41f2da146c910651a3b452c2d739dc9b531c5745565e69d98359f1d7d93ebd36d70abbf00d
+
+TST: 808
+SK: 1f28d9091d196cba3d4552e5a337a4d8af3f295e629e4ba6fe99703120ae41e0
+PK: 814d34bf28ee6d90f039599041db810f7c9daa918e03e96197414bc9aa31ecdc
+MSG: a69468bc33ebfef0615c643c49dac6e04fdb6cfb8ec45857bbb7a27e528fd631fc3411baee65cc1f94fcc94aed4a4332fa6861e065e06163541709d79728e01be2b140a022c83e7b23b9ed2ad2832169dfc95690913cf3720130657080c9d5a7827e5660757452c5fc3dcd80cc6be098c629226d5466e02b97126be74a1452ee16815095deb42bf06566715028c11825820a8a23c60da2b68dd9a55dad2a29a4964443817c07d776b244b15186819a3bbed414abf4579a3ece3a3dc7b105d0a9dba37b9eaa78be8e46e1698b59b0940b01f38b283c33a9a4b1d4f8144b16eeb5fc0a7af0d081696645a1eab3a787cbcf88fad93dd6cd46d295a879a1775033a98563822ef1f6b69a581e49736c8d701b4453969340521e4ad4bf94b911b0e2d86f34eece4a6385ff1fe63220cd3cc592f36d6c491fa18f7c1404360d2a7753fe073e09a2fc42a4bbea55bc96d7f05c98aed2cc4a9fae8fd4a0197ff01fa7f0046e3c3eb59aaabca313a4ddaa5d20d27c2c5f1ac6d87fd3cb4bd35a1ec75d104f7c367331a3e295e53c4e80bae14b9792d0d526f740d4ff036faf5487967ffabe8e883d3fb0d16faadb28e1285ded41570c0b07c2559b531e0f9254ef88e5b10f64f4839a9a0b6c3c7f1b7850f4ad9bf0999a7f2ae7c45a658ea53036fc70199842b8e49e60f967de1ff3abfff6cd735b7cd8b8f9e248f156f6c6543869eb99823daea88debaf79f01e6521ec63fe72724ee3c822b88b3968b24852091583c49ab3c15fa1f79b18d98f04d9b6841c9a7ca0de2fcc02f95dd649492e8b56a31ec1e244337af6aaaede8bf99fc814ef57c0d5e08c3c7ecc1897980aa169a9926d20698df6930e2110cb460f49390100741095f8ed00412ae696d98efefd290da5f7d0b728d20a1ebfa6bd7d270f281a98c7b1e408435125aa483c6b7d633ff7588a941658f6129544d62945b9b8af71a8c62c0a50076cb8541ba7e4bde4ede441722c6eb9df8cfd0656339e86d226abaea05ea047f6b8307701f6c9a44cc9cb837b8eb62445925e8a8881d2538fcb2b249e4ee8b686ecfb49c4df86401d249aac35841e914004f9455d3fde375d20a01fba27b197a698d384c76505106801627e8336bd2d76d761a8
+SIG: 5be552fa731e836793f6dda895dc9b1e2ccd669de1c843e00ea6fa3c5ebf97a34b26f1f3ac7ff2225ee4a7e430072c13da4066dcdcc05ba2b5f61a6e8d210709
+
+TST: 809
+SK: c64dd20d42627526198a22647690c895b5b45b698f57a69dfbe48dbd426aa470
+PK: 2e01d40416f78acddb34b8445ea4fd0ab3fa9e6643044752213f07c7f0ff43a0
+MSG: 821b9f7c16104b533bd127184fd72ade092b13bbd9aceed29b8d10f16688922d165f8931d53df590fb713b674d805ce0c9d6ce6c43ba6968191d12bfa08a8ce22e8f336b2b491af25d1b1606f930caebe522392a87d42ce7bc167aa7b610597220af31a665353071e8d9e5f42078b9c388bf040258e21f9c3ab38c0427618b2c28d3430df27921bfc58487b3461978bfa8bf586cfe8358e092f8f47466e762451d50164a0d74360f66b4cd3a3575da01da23752430c035da859f577de22290aab4ed7f34d267406ab547eb445cc64df53019427f4eb72bca55397153d01ccf7ec97d7a967d9aff46231d2e2027b38f3b41bd2cb1b798a4ae88abf4896216d315bd5383024259e59742802a911badcf8473db91af319733320cb9521ef9ce437267b6ea17bcafe5d0903b123a35c988f49834f61dd552640a3276da26af17ec21a20296586dd6f4b36c7a4f0b899d70b42af89e29370132edfb72d6834194a1609360b1f1feab89b96b8e8f0f68987c57cce0bab768113718fb1709de2df32177d44085da5efd9da70e1a858c92f245acfee64b71f3eb16e04fc13989e69337999701dd73abc266c9fd4cff91a0fd04fbd8b13b12e6f450385715848e007fa0d463119fd7de6325b640042b654212e0db8da1adebd2a7589f77ee4f752d282ca1119c431b17ad0a021ef2bf95e5ac4704e62d7039d0e651e456d60e63bade401cca77c9a89163174d5022d745abdc76b9ffe2544155235e3063e6e4aeec44ed5d8ab408d966fec12016c130730bbc558732065da800a70cbfb0fccca45d0028cbfd9632ddb2f0ed12edae7b930b106c9d1285a4b870de7507999c74793dd497408719c898abe49f7f33a33e69b50fa5af9480068566d1fddf4482d79704ad8ef11b88b42cc69fce8a557b5ba510e708b9375123038568270de407232e95621e2d04570bec2c41eccfd855b21f0c9bbaa23b5c5815fc888f7fbed482c320ffa1e063e87b55bc8f7eeea374063a9be65f7ed9225bf6ca34cfa311b79f3a258c252e6345ed6ac84748f46807a55d4ba41266169cd262d4f72279ef0caa77ff44933532bd1374756c23ec85f55efe9fc2331f26f881629f80c2692f7f53e4bc6f22efb45457a223f0d1c4
+SIG: deacc8c23218727676d540a23bdad7810211e6d57ad294c37d4b1c9af6b337a53f7880d2bafa73b30508c008426bf8d7c965a1f4a422a1bc7d6ad6226fd19706
+
+TST: 810
+SK: 0f8e9f3526b4faea9276f22a1779e6f82709808f6d0c612adfe32a6e8a061005
+PK: d48c3f0fdef382d1d80313e846fca95e418176bb5dfa9d398c1d2124776f690a
+MSG: 0ccd37c4cfd8e70ca3bb3946d09d70d0f6a4b81d6dfb079d7873748071589880927382f7436a6ef8f51c255473dd01feb52c8edbe4d3255713e68d640f3dcf158f2bfb9fbecf71f0719dfe8ce6b601281ba6c20a56b4f8e7caa4aa9f868fbfc5e4321c22d65f0382c4896bf9bebe3546949e8185a4d817e45b5d1293953821bdd98ec259f64a3de53865b149ea01c8f683ecda61da5dc10e7ebdddfe7484f5eb1031b7916587caa399a06b6fea4c5e6e0be650fbdf06c1036df2cc35f62ea0ea713f52809d77f47c2e55c92392481680b6332056226913b0ce88a6c55a26bdb5b8bab3cf4695a8c522302c4eba37d31ff77e58301bccfc7c7be8580c6342687995f44acd190965ae0d7bf0669592b6ad88743ebb360c73e0484a23d2f9e99e9eb038dcbd87ca9b1a498f1b2d35fedd7f8e1f7fd8ca526486911e076aeab4877bbacf378a2855f9c5ac039130dc690e177d67b244cc8ad032379ef71fe05e9c8613d8f5d6ea3d4e3e47222029cc004253be47f87fb5e3314c4898134b87acf10b2538bad897bdc5012d8f9762c871b653d400fee0ceed5ef6bdd16faf3f0abdbd72cd0a12940546f0995ff14b0f1bd54856ff74c36eb4f22d7287aefdc609998c1f41bcc3bb3a5fa49234f4fa8e929cd0f554b315395dae873c61ca70e0410c2fd5a115d2a6ff1f1c94b27ba450b8194b21f095c61a5f215e3c84f5d43f0e736286d33b8c47814db979f9dc00919846bee685337d99555a24472e6b00b3f4a14311a6c7c904ba5889da6c1ddcc1117580f5fbc41f2b8a4268cf0e9fa5bf412534c9e4052aacb504cb86e2147ab8023d58800b763f9abf9d0440788a51dfe5cbd44230ba5228f1f5960ea3a4e4044d36daf811cbdbec5d696463d8e941f27217563bb44a2118a4f5acd6e794de17e028cbdeefdef2cbf03dd32e7899e65a1cf839f5d90e1f8c364b577fe3105353f66768dbf7af0c521aa8a49f7a22082d88f901498c90b9d7777ed2f9f0e8a552d8a1fa5e9632ed853258c9c215b6dbb4111dcfca554bfbc9bba22f88bc55552c6d862556d741dad59f215e37288346ca7d7fd8c65a380d720caff9efa149f3fda232daa5b12ef11c0af0862bd0229e075a3c6b60ef0bbb3dad7f2908
+SIG: 2f59a2936073913834eb15a0e0bcb9aa804089468f24dd1b2d37a1934ae9ba1020ff64b72eec03268d0a7c012c4e796300f6df7adda01c8bc5e9015ccdee1a00
+
+TST: 811
+SK: fe7cdc7966d0ffb9c76f4a18e7f0bf90690eb76dc3d3d50884648e2e3937d020
+PK: a12ee9812d6af6aa4879fa72bc0a69804ea1a85f9bc4a26a5ba7cfbb914d0dd9
+MSG: dcb91cf155461a60df07eec29d98616ed1728b34efa9e1f7445a9158a8f88d7faaae0e24725aeff263c3f74f0c684f1858f05b6995d2846b6a832f67085a4276d8661aebd3bfcc73181f1f510293b6de5e4bb23ff2dca1df608cb14ae522ac4b51e1f9b973ab8bafcd534e71c57181b11896ee1061fb369ca4d2939d1e57060d9f4db0a5c0b07d52687f157817e63e2fe7ebcc3e7c95efe05b859910c95eede86d14399e616248a28c24c414dbb693af9be435a3a9cdc33e0e2a586918d91b8a85cedd1612d7c1a21792bdd43a915b157e04bb3a44ecbe23fa49cc55daabbeaa155a737f765b8ddb0f3b15d4ecf2cef7054ca73ec87d91752c2e99195cdb1958844f144edab82a97549fc9cec08e8711cff863b63fc231a77f762e5cd9da9d59409252e99ab04c42bc57097e464e3c6a48d80241e6325e3e4094989b34c0e8b32b1a7829d54df32a050ee87d8f7c4fe3e4f4f7049d1feecdbea67108350db4e8edbe3c3ff8ab2a25d147b1c1c5821b0f8c21042d655db831691f59983f27d2ed1d4906c544e24e79be68653c9b229a7fb61ef545bab16e9881cb4d9265e293590a0bc2dc86bad23007ff40c95861923b498241c10d26bf4848f62ba7383f649dc38af1840d0de928a9bfee5e11b51434163a7ab1ed537415f1e93285e3699205720158f9557d8641ed2bf485b8212c8f82668bac3c228e6924c17d0d98f2e6d9234371c4425eb758689fdb0dc1cea1394a2862e87bb38e624c34799168613278225fb5e19c9247ada35554f2c4addbb61d5a502a708127d6efbca8f735090bdfdd88db29fbd14b69ab1262f0c3e26d263a59c5ae4639065383d5250b54cf592bb7adfeaae0d2fe816b6381e86ea2d1c71813cbc3d8fe2d31de7b30fb6ec2294fe4536a36c6a1835a7162ab4bf89d19466119657b0e4645aef503505b4d55df977bd2c90c64406f4970d5cff245b835322a6fbe234e5efbb5ea45e8f0d3973be4aaa2aadaab077d6c9b25bd4494409e93479d2d1507f66bc8bef82999a13c7943b472b9e61ec29debefbf2241423e0faa42c1a338a7a6131ded935ba03a28662e68593368dde54b462f2a5fb746185ff5503e69ba36bf16f71458cdd057e5c17267f67498d652860b465e
+SIG: b52d03fdebcd429737ef70920687211fbb4c04f81e355cec7072c5054175d2ed77f38f466f001422da8fcdf067db1451007cab607f049c2e2607b57d44713c04
+
+TST: 812
+SK: f6c9ab5ea75f294e8e0c07c4c09ed8eea3113bdfc2ef759e20a264571604108d
+PK: b12ff55bd3ec42610eacea28b313a16e19c9e8b47c2b15170991be088d65cf63
+MSG: 71623b39743e39c7e08638806d468a1a8a6f35c2ae388eefc27374bb52538814c4b36c9b8e389ad83183de02a1bbd0325734e4618754092337d3e7dc1256928e3528870ca7f00613a25b71bb15d1d9eaaff9f2269b71c19769e003ce845614b2ec95ed28ca855b5221d4cb80a6ca9466aa33e2510ddff7dce186159da70fc8b1fbac12a26e1fc0942276892ad6e9b003f56959bd313af289e7a0532a664b76b96b919854e0650cb8c52ec4c5fb5053af2f0cf8c0f22a523f9e2c6419df8d0b714ee3776800ebfa70776084667d6dcf541f14cf166262e0f64c4276ae28885e6cfd097b70c0d6186ea5dbd033323c987613da08645de07208bae12a178d8f7f650a25afbd701c85a1ba639ef9f121c40c5c129a4737343386a48183ff3c591389d89ecda526cffb2674f17bb1c23090554b1340849796a6d444460bb419427e93e6585b0f4f065ad87ee6edf54be6188a1dd5ace1364defa561f74e26769c9b291ee7555276501c6a49080da0924f3792c2a728a52007b1c07c95578fedaf403996239e9c55a9a44c3dfcc37cdf03fb485db5a08dff15a7a4f7b7f154742e8431564dc17dbd432e10337c2276fcfd9d70f7c3d570393a0c19f64051c73a870e205584106531d1fd2a1dd1c9d0fce14ffaaa077bb7e260251eed6c62bc6edc2422519440c2244eba384046b0eddaa6cf2c1c7eeebfcd78fcae18b82290552b59c0463dc450618ba67c770dec0e229b8460936ca819562bcb36969c8ff70bf113c11671e00b941355bf01ad54b05cfe2a048b38728cbdd1b49809e1f207aca3098d9942eec47d6c9d413b37c914fedd38acd5ffe496cac757c2ef8b77bd8403d14b1fc98a903fe2b979468233a7f2aed6f8d509d874e1dce05149af9df3fe4595c71e8bc463dee9384d5e0505d2a6b0a2b8a1ed6216aaae9dcc7602487a4c0851fdf09629c1e99118809a9544a6577af9f915d1e65d816220c48c8490fa9b70da422ad6800223d6d8c340f9eab2cc7e149362124a300b40cbb8c0a65da301dbba931ba564f35973ca8bf2d1edb56c194661955b3b68381fa15d4b8dc6ada1a5cebda3a4ccc55123e0057f4f821041937dd549209c82e116570bc908a28e3299a9441443498f74b3cc88e1a62d
+SIG: a7f9d08ba14183ef247f2c25fecc2b83eda6de58022e466ce78fcf50f71ce26162446562eea45d63a21c3b22561fd4680058acb825407a15408f271361a1460f
+
+TST: 813
+SK: 43103df01a48a03c57f32f52d70c6849ee44580b2ab4ee72d548d848134f7ceb
+PK: a3cbe0d64b0560bcb5ae009001e314d9ec907901dd74a804a0059022ed9c6d04
+MSG: 738cbf06d00d4dcd5e5f243a1c18dd5ec20278884695a1cf3bea67bb5b05dd7e60a2a24fd325be6bf46b462873ec907f9de88dc2c762620b7e0ef72765d4bda662454993c828a1746e9ed8d19dff43c4c48527ac845f2186a4ad7c1d992a16245cd573073e0940dceed368110bb5fd0a4c8834ce88a77125b9147393c8b58cb16e5ebdc18244ebfa48baba46973fdcd485b1b2e5f3b0e70992cf1999580638d87f1f5b27c4d7f91decf37de2e734e3195535c631082b3ebaa8ce30a9c2c2db016d7d3547e621618850e22040038d0fe0faea2f9bf510b682c4fd14750e89b4c199ef0c990500543eeeab5f0b507a313199c2a2a0262d6d814cbc0933c592e256c3e29d524b066ea5a4543361a10450e0aa675c61408f307f26ee58969d63278f135b7dcb666b93f2cacfd83873471e974a286b09023f5015fa1aaf18bfbfa5f74385d0df6b9add516ffc0c3113e37e097838646ac93054ff4d9602066744ba3396953fd78168130170bb275c152bdd366f73065c0a7ad7ad00758cb99a7ac1b7809d26dfaac758468201eeb60dea368c33f257afe2f1b4c02e37bafe40f5d7fd40c87d1c56a0cb28e9d28369a3924bcef8b6d999dcf4294dd8c4143d75c6c25b5a4544488dde725248c78d93c15b815b01cbd0f31d1b00ac04837ef85b4003fc96d4457ac5a023623e67b66da4700a0859f83fdccd3c7aae09de09a057e00db44a2a6aacaa21746a49b8224689a5cc1854ba3dc4aa2aa34524e7a5a89d11eea356aaea5ef5fbf542c99f544db940f5086838ee2ab218b8d3f2e107d0b29d4b04830eed79c0768e02c2844b3cba326895f4ab38a3994b83ab30600ff511ccb595992f8cc0d2954807972da365b06fbdab539b2e03598b34e53cfcf93990b97aac1d329783366d451f972b8d8a00b6b8ecdb37279644cec1447c0998ee4f7090f34c9cc8530590cae765360aadb0ab3135004941c92302cbb2b350a14e8f30af5325c2b438005e3a9d4585e63265c327ba725754b33256917fb965ae9f02ed2126b481473dc0e931c2522bf00fe6a2ec95c792247b1e03396112f783070e2fe6c2cb982250d13f2d5460c744fde45323e631cccb540cd725f2c55a7058f230e82b79f366afcbb025b492554395
+SIG: 195447beb1de4a7e36ea89a6ce3c99bcc89411df5e0b15f7ba0b1d110c456abc6b3f5f1da6106ed887864ba56aab466a8a63b335cfcf4c64d65c0e6fb480b401
+
+TST: 814
+SK: f9139e579fa96ebd6287db3babcda60f92e73153566f924cb5de04de4493481e
+PK: c06ce335533af8d8f337f2b38e0aafa2ce9b27223cd9ddc5ef32027f04889b7f
+MSG: b330764ddc628e4ad67aa4982ae86d4581071c193ec3c58f813d7921b84d2a54562bd87417ae1de590a1a48c4ec7d556ad931d65c0543fdf0607c749859ee12f9952020c195cf8746095e1087cc6c3c8ef9d24052560ce813d6139b7a75c8f4b8ea30a9c4ab888d0a6341c99abd35e0903bfe56c93152340c41276d7f24e0912b12a4db3d7ee4484dfa53afc0b1aea1409d1e0328aa1c8604127ca2eb1a5e81bf31f8c7a51c6052c534efe6b3d0ee74ff5a9b11c6157e36477efa9382f5751be8c8c6454c446d6f8dc7e929525cc3de78cb1ba4aba9bd4be152610437582c965eea48cbd4caa6f308f85f4f8d006a042f619200762e1bb9ba422e65475b33a9494298cfbb75a152b36d2a05501807705b952765350cd14141d35d4986692d6c3bcfc6d61df0052a620aab8cc13205e754c16f93eca7920bbea5157ef112f0b64c1054f90a5ddc175a89e29242f57646e74cc885e81a1cc144c3d782d1152a9e4cfe76cb3ffabe7dbe603fb3869eca8699698709cc87fc961c1e299cfca22e3242eae788cff11bfca61026745f4976225b26ee200c4f1910c4b83df5ce46ef487d748d9c4c502141b7874caf41e5a297b248c2bac6990a15b07b4cf810e59287442d9a3696c02e8d7324d3cf730dda540536beb13cfdeae6180dd7484832dfa94e94aa6cba117aae17270f48f93b2f98ae9581718163f4463546c0ae0f279c36b92bee66f1ca2d6a4f726d2dfee0bc11c1d8a1fa62c3cc8aba266b98759286c1068483b2376b403c887fbb657dc0f255dea90dbd23308f7e0e842b498a8dfc7c9cd5aef0e87d56be40d50fc1dd4c0aa7dee55aebe4d6b6a52053962b87b0f2ee09a90816155333d5c57a14724e001bc3ded17843b76e2c47a176339c8defc54b55b2358ae7d01b0f6e08f31216ae90340694168a5a79ee883ea7858007d17c37359c99d6597efe460c1a2f7738ac32c5eb5e39e500c49c0dff9c4659e8c50cc5ca79d8ba4e5972d67225468fba64167a6b2c6f368935c7a049d35d355c7672520d3c9e4e43c671c3cb8dee259047495de0f56dd7191d5bd4bbd29517e364792ff89d33799b6e781c20193f5a316fb40de74fee2acc25e47f512214de3b1e9b382a86929c1573d3724c25017c0e5
+SIG: 051d8d7f0b68d2eec72c81adfcfb31ae8558f60ab63c9f5652a8df638f666f1ebc0c6e0b411953bcda6b5151b2b93a39e3c5330a8573e168792272abd36c810a
+
+TST: 815
+SK: c8ee954db5a11b292ed97764fae6b283051db57dcdc0aa0df5393bb60c112ed3
+PK: 5c2f81824e9975dd7ea353bc66807dedc7610349794e2fc08e5a31e002e3fe07
+MSG: 7ba3fb568315aa81e21f197780edc2c6ea26d8d06a4378912fca2301cf1eab3d803c8469deddf376703ddb7ce06a77dab20e02344fadcc50022ab3c713cd03c1daa93f1c7ea572629f610b5e3c51411bb8c19694bbce903cac4705f9b5dd0f47bc5d0aa3253f908870299027ffbd3449eebad45332b5d0c4f533dbed18a99a2498b9164e245fb65c0afa0b053703a0cf95940ac7a0195d4f7046609cf04371338706b9b1986c0f118175d2cdfce74a6f88659825854e94ece58f5157636d6235b76d32745a2a81a9671a8f86027ba9e01763888fc171cef7c451c36072bc7499839d431cf18cd7c6c9fba3aa712a054328ccd62be4820abd5e782162764611d4539ba2cebdc209b3f4e4b69c3d64073e920d215214fb0fda44185aada5c36127a15ba15ca28a3ad086e9d03366869c60c3fbcebd869d2e40643e833f894803f980a2da7ea4e59ce4d7c06fd2aff087ee7bcfddaa3b32817ce63a63587dbafef380013a6f1ee3734b94ca3df9644dd0434302ecb324afe35f465c9c1c931b27294fc6ee0272de2242ae90d7f2e067027ef8642e8f171ed880ffabce8a20a1b3e339ad4e3f1a9001f20f90026188fde34b217a6e26aaff18422b7f843d0fdda321c319c778f23137f20ccc1bda1890e5bc916a5456d068d37b5acc6347720c56a5a491bc348d6c848a9c8fecfe58c92b1f302fe14919718cd5e78b7fd601d09dc01e6904861e8d68b3c57535b6136676cbc6e839af0dd739db89a7abd913fdf6b00e9ca02602de6ca0afd0913d992fbaa8ff822b9d9b09dda7a29be91910d8fa3caa2a5e518346c167c9f51941cf7353f3f34c1dab33485d0a8c19daf951fd3ef20d0b119d8038df90c114a25a5b93ae40ec44b9a5d2bc1c6517c682500d4cdc197142bec3af8232c071428dc54c0d30454272e7336b0b5888a6e8fecde859e2accb7fb094acc54ffa481f7623d944691f04fb3613a9954980f17e2ad2173d68cf0ec1b67d8a91d6ec82946bcf05cb90681a71627b590238334e3d5ab9da6a089bd72624df9074cdd2309e04dfcae032812fe84f9db882cdeaae69ee5daa5a66ff427fc452edd0769b6aabcc139d0f70af8b97430e644f58a41287a93f631deda82ca0716d79754c5c503e52a665da
+SIG: f3077a75101e121e5c3e77d8ed97b578d239bd421803d3455b5654405a4c586a6092e13a8529bace468a305784b373e433fee4a3df8956befa012fd8a8eed10c
+
+TST: 816
+SK: 6dbc559e4ab193eebf70c5c32d797be00b7311e8e6691da9afcc187291f2501c
+PK: 38a7034476fb9382f1417768c42162951a2636902c3898c029be278ab4c31f31
+MSG: 88ee2365f7cf9de33acd53564968b2dc7f7370b7e7033f4c663a88c25f60f7f711d61908ebf1f5bb72835553c8aa8c8e4fcdecd37978238289bf6ca84876d228217a28d81b0b457c922e91ecba8d3e1d2e6659c2b0aea051b9c2e09c7dfeb51d30ede767570341ffac1ecf0de20c82d1e9ed0775deac72da7c2dec234865dec83f6715e1c3c59de2033cc24d86bc2d31aa16649686ede0dbbd8964c3a64a3dca5588d7248b1f24df8d75f09aac62c07828ca431a3a2d77a60cc93cfa3495cabeb1904ed5b563984e8c20777bac8774108a64eda58fb320244a3add3e3e7a76cd137cfa4a09b6e6e93011ea0ae65171af130711766cd25b3c74ec54c0bdfa02b3120ac29087ebac9837fca65ba971bc4281dd557c500e225ea66c3c3fd52206c19a9f9395463169f8c7a846bd9f834d7f337d0b61fb30bce294f478ae1f1d977e454e433ee8729fb065cce03fb2e435dcbcbfba01537e7a6762e55e7ed22528303704beb5ae381f2e181056f25133273cf17ddf2b06e2d9477f2c09755fc8d9c73cb33100468c64131c686cac79fd384501e50f8b0bee28ba39583f42e4fd3799e24f60da5fd3c779aabf699ffd2321ed045a85bc6424f60fdcc49c1cb31f249a4236c09491768181b921f58602fd415c1edeb26f39324addff14771324737c6720cc92391b949dcb4212bd6931d4de51401e7f953b7b036b223f0af7a8e408b04ea635a23fa0709ba042a5d992954c09d8581dcccf52568ad27a1cc71d18aa2740f621212e7f4c5e5e5e5e4532d9a67ec2773ac21c8a4b002d6524f6182dd371735d2c2abe6c95c281c6fb1e976bc17e383fd52aeaaa9fbd4abb82a2cc65395f8c2cc7d8182a0d250c685cfcba93a951ee7c503c6e3eec236ce33e086c610728737c1c3b3a24252da7f21672d928ebda993a94c458ab990f5d19d80023c36aa16eafcab143f352e97d6409f3249941119bfd9f5f9084724d9ebad383b10f34d33ac830cce9e5cb8aecee6f40301cbbe309fd061534a7d0c3edaaea02a171d8b2349dbeec628520ac334a5bfe28a9d5f4c0d740f7c72d4d72d89a97326a03002d1ef38522bcd37b42847a314bd843ec88d1f2f9d39f57f2f1a13d0140a8847450448c880b3ae76531e95c4392973250
+SIG: 31f16a7caf2b74f65e057c9333a1a2633dac7346338f798510730eb8d5d325fc1080dd5aad5fce0534e9543f3c93586804464af5886e8644129c77ebaa485f01
+
+TST: 817
+SK: c9d416830ae2028f2175d22b614c79198c670cfaa0e7a36150ef0fee21a95ce6
+PK: 6e3eb4d01873072df946f1792f7106330895e7a76dd9ae27f8a988039490fd4b
+MSG: ff9ad4837cd0bb77d6210fdddc755e6c0f1a73c2bcd03f7a5869e7342cfd73cf7086f865561560277bf6c3421a912d67658b1fa97057c496f4be8edcbe18b5ecd08a1e7db25223abda208fa531f4b280aa03b04b60603411d374ba7cbb020bb9a8ce4c0e45a7e132144843c31f8b45c58eb3ea853c2ceb61376e9df81d9778e721adac77b50354937f34372fccd575e88d9d058e43df942f2c43b523c8098e6dd9e6bd21d5a649b472d41e345fcd5efddd49eab30270cd8788404f28516e09d3acc40048b39d3246f757e482e1459c626b799e04d06727137371e120afb9fec39a25f4e6764bf9792fe492ee0f210b57db9ebb9e8ef41b02c7fee9edd4b6174c570de020a391287133fe8ccb41a83f91bd22382b21e1d7ebc2c7e5018ef5142d82637d02620fbc0569cc09c44e911112bbae99064d68d1c69e77c9930b0de030c8c1d748c414059d5e299b7edc08940651894b303a2b32dd2c365a067c9723585594644d3ee8de1a51faea0e650f2124885a94cb99eb903b7d4579bde591497d953930d363dddbdac627b97a91f49682df8e7250a7073d383a7a22cf113f2858ce6b632a2892c4e88aa9a0d289eb57629b008d3b1b6081e6fe5d3c0a6c802189b5f108e766319e15b33eaa5b8ced4027eaec83b4ac68b14b8298bc51cd8eb3809b7a2d684fe32bbd9fab5c918eeb17cc444d73f730d4c8cc057bd3a2f1f0aebb61632934e61702168829cd7e91de81509629d01a8cdefe0d1ac49e21f0c5fbe1b2244827268a0a27357e158bd76884a21e7f1fac1b6272166d5a9f64f9b672989a8762f512bf1df4b2ab699765f2cd8396f476e7f59995dee7d890207eff0fd27263ec232e37cfedfe7c440555d4ca74e52da246c4b83757beafd2ab2a51efe160bb02b98c26d6b2c3f0c1aacb2f3c34a5b2a3b66fee175b787548073d8b5777c6be880bdc196b3374a2154f94d9360f7755ac6815a28af296271e22a8f23543c74955a609125b02a569218011420295ccf0d7356999a5b895cc88483fadf7970cec6c64240f7079fdb15ffc5c4227e53926d278ba0fed3c3993bc86822823dd581a32ab2e3a07f79430224b274eadd845598a7d1d89676aaf23677774b7b0583bcc83599d155d14b09adcf49ed505e8
+SIG: 47faad4e655293eda156b2a1fabbfb7e009fc290aafedbd5652114a47853bc77a8233a2b179f605477d787878cbb15ea6124df8dc57b2ce7be7d18b7162fb50d
+
+TST: 818
+SK: 2d277dd55f57195ec072b47cb1448cb582c835739e6c98ba71ab128f70ce6b79
+PK: dfa92593ef0f0d974a1137830ad13848afef3b810c2a21bf779178ce4b3ab974
+MSG: 14549eddd5f2b7905dda19d74ab207aac6fb3e3df3295d845231ef3aea6e1f04ee033c9038dcb4bd3d5e452c54834d0ff2b7de3f322e5626949cd61d6e890138ff0ea8ad846e8fe887aee15fc48bbe4fba42455f5c17457ae789b405af859611fe1f8746185a65aef2134ea4d8f398d48df7c1bba4304408ae7efb35292409d508dd55ce21de8c28160dc9e877700c763d06b01b8542052d7ddb633554e3584279c796937023c8eac37277be2b8204ff3e0e1031190a01014cf5f5b4d7ad996727f97531e0355b87c9e611525aad079958e9afe2ab10e4a3e7a1b6ba0aff815da2cd81ea9eb9f536986633f316dd06c2503c6b198dc59304807b98b42935f51f637ddb59e233fed566439c1fe96cdaafa49f4412d0c1e654d8c69042470b3a59acb6bf67e40b38a77067d5997b8d35ed61d6eb3cc78b8bdcb9574b1ced9f6f339e9e38f94146ef63f049e6b802bfed2a51ab42e7d489f316ff4d1cd898bcf8505651687440749c0fb7a57dbeff72e64689faa41c07b4ade59933d2fac6d573deb739549eb75f1e6f7385d8c6142894973ed685eb8ed080c2a49f3ac6571161af96635ad057df1486d396773ac8983210978986e1bf21a20806d667a48a555a963221d50614a8976b2eec97512db11a358194492ab5455801baa14a511b26eb0c68289d790523712f2ff8709892695c4db9ad310df8c6ee7bd83c871f05aec33b7ad326f446692a42f7222376246d536a326c4d73eb572feada11b8ac7114f6cb444ca278fcf07b970d2ad465372a687d36b7daac478748ec6a932da20843948efa393097814272e5ca1c73e711973a52683f98c01e55241c154d28e38d3edfade2303a4e7c45c2a7a1c996ee1137af864a98b69809fc9214eea8cf3afe842fee3eb9a9322c3b82fddb05d4d1a2de09c1ce72734453a8dd3a8920d0d0ac96ef778b9e02c6a3f12872e17d3a81ba75fd233baadbe216ea0a58e9dda00840870208ae413540030b3c05e5d0b832df87c8ee7f153487aa11bad9f139c7dd4bcf418f4bcb95bee857d0e96084472387cb39127a947134501963a7071bdb34de6961be2b6b06e403e75918e6f69d08021cf2a8acb80a0111f4d50610c152d39c6621c0578ac689959b1ce6f376f43d18af062e4a
+SIG: 73c1060649a7c014ed01945851b53e285324e60d061c831dda41f033b5658306a1f112327afe93caa921020730aae0069c9a2b45eef55cbb4a5a9cd46cda8008
+
+TST: 819
+SK: 428066c52445726d0ea2007e504637274d84ee232325b505f2c516357f807583
+PK: dd40fe8f67c665613b3c459f6ace8dc28d34e0e77e2f6aa060592819be6a9d68
+MSG: e2796c50d93df812bca41bf2a1e1dd737d8cf6f6b4f76242e39178186758cbae0884e60c6b4aaaddaec9a899a912e5c5b9804d7b0497bab4458c585d4f259222498ce9e80eb6a7979bbed6d52cc38072f745cb2c63e663bc3b9d6caf012a607f6d3b706e1557578717ecbb971aeb7c48e1df95711c550e006993bffba911cb64ad52d517ed18be82369e815819d3175947d4a35b2cc7b9dc6c10051326b3f1dc1edb1b68ba015ff7ca1dc361d8967abcffd3c31f7d6b0cb1396ae541f29759c4130be52ecc11d99261c365bf7cdec781494c5fa0526db4dbbe660a432be56043c66ea07c25627a5f72b78123dcf986ff71ed1affd1659b1393d9621f711dfa63eada383430797058f1566a00052d67ba53c1237b5691de3b039fd4476f1151e5ed5f5a98672fa33a1d854fa01566b33231d46acd7f34b8034479981853764dab87f49844cb62c63d536faca920447d8cd1e8113edbc83e4a6b7815e180cd78b933d9687fd5be99d0518a44662989bc64011124f187d43979994a95e0c903a006c1c0bef1c0f3df1eb700f980c28c3c1e997d0c56d113dae196882b05018fcab314d8117fafbabe7700b932d47c57362b2035eddce2d2ef33641ea90c3ea3fec6ea5b87e161014c4f8214fd03cebf94abe122537a98703239df5821c5ab633f98365cc636e3f1d2f74e0ff8f1fee06a3f73907ee504b310fd5224ad4d05cd23c356df8b34647298c49828725ba5fd60611e829b6337bcc9dcf8e8971cab3ee9c26337d38dfdfa036bf6096b635ac1bd5525ecd377a15272a8ac9bbef133107a42258d8b19ec69dc4261be5300a2d2d5ca99f31efdf259f9d079869a34413779f3028824d747686c460ffc496f2010f403e903e27a87dd075ae0a7f1689416d31bcc15f490caf975c40e715d549903e8bc0f7d9141e020f410f3ca2b2c0797ca0dc8d7392bff243528c7f3be138997185a4b36f45376d9fd70ba20989d2d1a911d4b98d160d2b8de592de2f4c04f35860df320c548440d5e3a346a14d3a63fe485c2889126b7f41d55a6eb23d5620babf8564aa79d156e983f36d9ed498da9ca888d946b53cc4768a5892d52d541526960282524ba6194da65941d1ea30f806bb6d97c7488b93fd0a770a9b15efcd12c5c4694
+SIG: c938829f598b1ff1b8183360d223f43c594730606876a99a3f31b2065d04e6f075d1396b3c8cffb0e1e2eaabda7da5e789ccd1c020835fe3a71dcdb6af03960c
+
+TST: 820
+SK: 3145bc68d82979408e4657b775f150c6d28a324d746ea6de90fd72b17a257982
+PK: c776186ce47f30ad08fa1d2c616a3644665ba54ff730fc2f4db1dba38ddeedca
+MSG: 2ea8dce1487f45d6ff8eb83c54fb7edd76ad6e608bb8daf1a1823da4f4e4e9863173897c197ac65804823bca95091f59e86d63c18dbcdb85743f8893ee694d815601f8f22f4d7df087f0114bb26c3795e1fe4b7f4a8fa31fd9f4ff10fe5dd452c54c5578c752f888213076be467ba30d2e2fbbee877c4be9b6ec4f04021c006f9266311943cab7cea99a2acebb69eec3e618c131f97430075f7975e39f26d5315178b69a1ddf731761051b93fb8df7e0e8b41e82e7f4f75e91d6c890b14ca533e094eb8ea4486d387185966c98295d3f58b17eef6cc3b4d07e93a3d9f4772ee52f18a5bb30aa3972850e658170bddb676f33266c9fd10f5990bad891f0ceb782736b40f01bd86509b06304a96d93da233dbed18afa1818aaf57af9bdbc867b397ff235a83e857224b15065225eec039dd4e2d69a04ee10bea0695041eda59b058ec05f49048ee324d16c4d6107b6ecd04875eb744e9365471b4c5fe6611b261893f9d2b128e135f92e474156b271b3c82e9a7663dad4953d30e10eda0862607dec3372b39970f2a84b12f60e6dae7f31799086d38a7e34948419c1b07f44c2159c86b8c0cfe8747fc2bad5bf475356cfe69de2dc6ad5a519fd65c12564701c05f7c277ecafcf4c87b148df1f9879a9ae443c55aea52138c6fa01ef0c3abb5f2df90a57ab6624178c737b54915b7aa29ea78e8e49ef5a816d8a92c2f81b8a19632779c892d66f753d518c41cccc9e593e50742625bcafa468805c37a21f8e29a6960ddf5c5e5ca14a7b052a7b6015697a0210ed6f0143e6b484c3f5b3b4726c607d07bfb3d54a09c98043f21dcc5cc20bb4754e2e5a73b2f806c2204b72f36ab9e96a62c6277c0ad66be7abffc163b4e8fafceff5e202e5943f4f0e6b92b4ddb953cbb791f83166036938e6c44ad91a596a5573440fb30741e660b6cd5f86ffa746e6e972b805c10b7b7b9a63c0551db8eb4f8400cde2868c0d0d4eb4cf117f8ec4ab9744fc5879dea7f0ef16c291d55c17f08b731b7c65d0c441b63bc8ff5e94904c026a1361dacc80a93a9b9fba3b403617aeb94a568541848011954234aead700f034c47c7def877905255f18bdb9a257ce5bdcf0e17670cdaaf13b1c7e09d58f92a9663af239e22078e180a23ccb6f64d64
+SIG: 24a433337683bc71a6ca3bccd8cc2400c24464fa67714b46515f2a1432712705d570614db6d26bbbd3f0267c1427ca1c2f40dc9a6f1fb0f0fc714a02e24b4708
+
+TST: 821
+SK: 5a25ea5e182d9bf8e930a20b6cf55e24e83862789b3839b1ce9a71e938c42d37
+PK: c981fc36f1a6d5f7d451cd5ef39cd3ab02087fcc6af27dd78ea827497e779e21
+MSG: 214dd1927f2cacd9888714249b85434602ac78453b4af5386eee39295d3d5a2267806eb0cff2c132d364c2420d04e3f6cc0a967bf05a10ffcf1217bbf315e75b98060fd458d67ebaad9380f4adc4dbdf74cbf1c6479202bdd7fed3a946697dc38444d88bfe51d41d7a9b38da60b850c56b48ba984f6a1889514955c0dadb69a8c736cc76cdc49f13f85a8bfb7928ff0a0c0c03f17c74b5e1062d7553fbeb9dd3d5081de1dfd8a6a9976697c6a259bcf7d4bef1c21e0aaf3298b0421b919fddfc1dcb3ec683d86ff3d423d71c8f2d723a42ff68d82e9f391749b82998dcfa112160f52a413a23d95fc42c3bd22384bad77754a710d8b9f84ae0a802fc46509e7f2b07079012b43bfeeab719bde56f00e59b8edf1c472883b1985b2fa699a1ae90cf45d7ac580ceb5f2797def5b8bf4f2b9b3519a727b9f2cd1256a2f076ed2296495b5c2df7887ff89e88e236a14cde6324f43d68d90172b0b88bd28803e999dbedcc501db654544e171ec1f9f32d4d3321d589392e03ca659f96752e1f08a55db553d866985541f5bef84ce2ee323e17d1f7dc164b50515a287d5305fc28c5983b9e5398b2407ae47296fe4a481d22ffb4b865a66b97a6c27935dd8eb86994b79d368363713f101dc37f429eee0fee2441c2dc17bf43924f0c044f143290eaf3f9ee4d946dbe45831a0d83c076e751c14f3b1a7267f5446c188698d2b46d87e6f3b20bb3fdafe24cc096bc312d8678b38a80c3f052a0c96d5ad87a5dd8c133cc9a15be33574cd94308c24dec1a9bdf189ba687199f72ef6709878e10f87bd8a03dc84c8fa96420285898ca3211d8b0ccef64011ec24f38e574da34dab9d2f002105227890f92488c621e5713e47dbcb1a82a6da60d8b2201eb29d494493360ed5a3f4b5225eae7707ee0b4c0407305c16754c7f630fc85c13e4917047bcff3b2a293fe955506c7264ea65bf3a9b25acf343600d8fa0c7c1a290d0271101b7f40b96e7fdaf29def9d9327a5ae05446cb5a6d322453a8b098bcf3aee1f704e14d00be342b8934d19e529218872ea3a2fb2124b52667c01fca5841c66e1e64a1e680e09ba186e04d105186cf6eb728b9d502a66b829fbc992a3881004ecdc80adfd044eda880f8af72a14fb550d7cc74194a945207d
+SIG: a4f35b49d7e198e5d326e353fbb01fa13b6ae260d1e48e30c1b967737a5e79936c97ca2ba799ca34e5e788cea5ac8ed10d5cd15dae53e42432321cc26dc99809
+
+TST: 822
+SK: 42335c30b3f6b359cef5aab6a3ce2858a151b7a4fd78d2fd3ee36fc29d249404
+PK: 301c515a02a4c66bc6401080c6ca7923b7831e3c9a72b55b14027eb2e7b3b152
+MSG: 6da2251e6f559536b09bfafb8160a2e8102d31f8b59324083e5227b20c3e5c3a06e2396768dca3ec76dc7fc0eb3d145e62ed07fc1a8b1b2e347013a0527274d0b234fe725026a9d128f8df20dbfa3b6503818edebd7f24934080945a7e1ea02273fe48b6ed1e83fd168d7973fbb7941b4037d3cda555e0e89c2b943fb1e20765ac7d4fa3777f35a0a8bc118f599c847be3fdb2d8e201ae12a30bdefb034ff24e3e2e701a0d1733734078bd1f9a69bbc667e461211f2c769d29db7c4d62d6b1b92b56f5f18a931a926064b78da146e18b48139b9b39862aec37bcce12cb789429e68ea38112d0b5cce30bd2d26c5f7fd415daf7ca317b3368b7617d4525e5bc97d9461d5d64f6b5d318d0bc3b76f25b0605426909f2aa0cd667a4f0e075b9a9fb2e9a6c82704d8a9f1666844edc32f63a3d4e0fd9fdba30b51b3336b96e9eae392a342de49e9b5fa0f9b90171bde09cf1e946499140008159eb1865563c28394b03a8d7a552271b2876687566b80fd3be2b66332fcad196cab8527c56e21536a141652cdc7fa745b26a331d787b93e5e816d8d851a58f6ac07a5827fcdf472e8685433a40cac0c49aa569319a2e57b41c9998165e69723ba77e5c0423c4b4ca07187bb7442e7d31caacb27700c71ae48cd055ed2fe4da363f44821124cca1bf2e63d9b8abd2fa41b1422f52d558bc5f110c863cc600864984ed259b73cddd5796b32979eddf76a07bc59b7368c48e129ecc0d4535dccee2c3b8e56de50e6f5cc6ea515cd6a0ebdf1ca79aa2794821ad2e109edda450c9fc3c84d8c96bc38d4b437a738f818b4ddcb684383c09b11b36052e9d2f76a61eb4d62049ced5f61662c4b9ecd24a67f4519d46528c5b2eb21005f49c73a3370c68e37ac2b18d481fa10f96714fe05c168df11cda54f14f4937e9fce1f516c0371b36a2c0a050bac7fa5122a6e35ec9c40436585f316e6c911bdfd7db4b80b4306479b82a2b243a52b2d2b62742ed11282790cf6fdc7c9c824364cf25636a855150bddbdf7e640f9f952a947ec7974925e8245068b292101b1f4b2018e85d078c2feef4492349729ad4acb38f1c7c0270b61d3dfd7636c6cbf181e4c8a0e64fa06132553c2b9db7019e3b3c485d8d5b7dfd5f515e4d71ede535ae7f2aaedc23
+SIG: 67b0f17449039e8c797bf913aae6e4f0bb99c74d6d10c973b990ffe03e7ee4ab5b35806db15a98c0846a827e7bcd539cd3bc09dd118ab3e52663a357b1299107
+
+TST: 823
+SK: be6b2babddd2dca1b0e10d12d20a9ce29c6785dac1d60f2edfa94ac2784ba766
+PK: 398f22f0efbf8c38355e4791bf670898951fbbd5518f0e2a605d460023f613f0
+MSG: 5c9295881b7a670669b04cbe0dabd89693b77f7cce0d4a33f52e02eb26959e713d9aef5f95442bdf91728383325202aaccc037477e3666facaf24eac9534879aa3efe18ffc1a5c54e39c7687d0937b2471bab389b646cbe6b3e5d5961ea63bd452b4743344ce4c793374523795c781ee84d511e2941119bad1f4a746ed9dba89c8d0751a6402718635f6e31d9e18681c6956c5373251d35f53baa1987cd448c9031a07f32c8029119de3a91631dede1d933e0fa32629afe1b42eb591c22f87331e93cc083c23f64a6e5e586ff31cc04e423c56ae3f6a73946c48de4d85ab0017ba24456d69b59dca6d403b64b07c40d3b90e1223215e3f7e876c6701111e37e517770887310ca856f009a0d60654835d94e6587a439da5db0a0c37d7c9d37ca1d703e1b3227631adacaa79421a1c439d60349ae57741b7a8ad09ec293123030bf6bac0689e531ca7e72718223f9ea43becb0ee9d9c1ab845ed1cae443e3c5d4a9b1ede6db3417c3ace281143f42d85f599b3b9d3d05fa0ed07c1ec35ffab0305168b4e56e58afa0617f9a86b1b5b201dccb072b4cef0bb7b95c52daeef9d9e7424a5c0f148f9ffe60a5b23e0ff82c730992ac9c17f97f065cf0ad5377eaccb31d8bb923bd260ea119e6fa9bd6983482d70d9219102402dc6a3499193d0c1cd3ed2a66921a98df69b791413f4970bbce04f639af909c64f4560db0af6003dc46219e8ad2b372f8b5f81cfaa041ab71a348c931e8dfdbc409c22d7ee6e07626e104ec6cc7c6a4116177f93af16f124f196dab619b6f698c2d191858e960c2e947b51f3ac4838759c21fef7ebae35da24f55ebda9b9879aea17a6d8d927de487b175fd7faa21438a20923ddbbca72e6726934bd6c21e8118019f65b3810a07fa27b1cba64d0f39f0bfd49dcfafdefe379bdea82f31a9c39f7e81d294337d10f1e9d8b50eba458ce7b753d36968538513eddb0e84534411c4af3f0214610ee3901a0ebf316173ccaf15cd7ee496dbfc2465eb834df62029d621fe911824d7987df2d46346b4dce1ece7d19d55118c037c9955111d07f1fc362c739f1ea5b275c71c0aebf59655e2def16e123b3eb2526c3ca5e83cb24d5b68d7ac40a67593384c563afe0b552adaf60805035be97b80676adeb1576520833
+SIG: 702ab9acbfa75ea2adbe4be2b6847625aeb409eef9596fabe39d2c533a03431e5e579552e8a64fc4fb7d926aa8fffe0640698464c4454ce35fe83ff263051a01
+
+TST: 824
+SK: b1e47ca31c64b68aafafb443512e66787c6592f334aa78fa219a3d93c33a4ab3
+PK: 58119b38e6a148a936bc5f92f4f29b982ff2cca64a5affa14ca1b6a62fe328c4
+MSG: 767ec1b3daf204387f3fd3b20010781afb1f38f614474213287fff11307f5ff5ae7ec945a2b9b4870049d4532f8f61c1a7b5f211fca2e67c374d96219d8ea9de73f0e38704fc94c0e9e72f2e15daba3f88f749b1ed702660db1a352a2667d4dfd4e00a18efa4c6609ee9c9a88adacbbb985d3de8ddd17d4e4eb7cf74a1da91edb390852ea4cb9a424f7fa2229e083033a34059117e5efa7b6613d75e58b702c6cee5d004e8599b97503a5f10c4c4e5b9577371d3d05b2dfbf7cbefe6d092d65cbd405138d9b04c5186235983fab6d4ce85b636276206d74a2ee7db6164dac47cce78f50db99af6ac6e7064c13aab793be87e66289c94a09fb0a31d97971edd74ea9c0ce874d2b7d6c4abaeff07f870225151946a5c476f6b978996b87d8c984606c791287da6bad0aa44b0130be88671a556e2de35c4cb038ee781273530ace0a104c27809aee033c8bf9029d90fe7ba06aaa94e16a52c643dfd92a7624fbbee77a7158b2cc151bd3f61a1a76f32b28489307acf0dd8c26cc4adbbb8de430db4e4f58308b6ab90456111deac2978172fe1fc0ce498088add4c31c21f24279025feb48cbb7a920cff2d28710587af52c844db8a7aeb7df10d43411a3c8eeebb406d6efcb19248887d450b573d90305e1f23753e890511dcc77c740e316ad7f52d4902073db3998e4e4acc4e01885bd1188ecd6165aeded1e778702b6a6a79a94999102df72018f792f8f162007e812aef8f956e123282bbdbd0c35612c2d3473f944c6d76be9e86fffa46ccb1ae13505a4a81f31b8426b8b60de8e8a7c16d1e1665b271434665c442a9c6a977ce986f6993b7439af03b402eeafff1456d151526d9c58f515fd2485e0cbb324a503a8d491344cdb2aff4c41aa8e2ed66e58083bf0d2fbf4877c85a4bcd6b9cbb821242c94147e5fd8b7dd792ad0a28d49d41100b431bb4d8c7833d8505dd9e2649f9ca7051be68712ef3637102036b002649473ce259677d82c6062895e161928b752f13c91a45955e80f007de690edf8a0e5eee4422e162b9d2b4a921d3a64845793aa2229e9c239e57a6b1a90a5254c3512f99345315ac7d3457f9154296c66822abe184d64e572b9c38492958e21b0292675410e7348b2b718a0b7592caee94581a948d2f41fa03c61e
+SIG: dfac86df586ec34c7cfea5d5a6cd1140e50b6bf050f8e41a190ebfd3b1432b95a57d5652dbae8f53e037ae326e7f18cfef7c779f40346f7c0d8644610593f209
+
+TST: 825
+SK: fbd55fa743c3a5910b3857dd0b6aa584f3b238de056b76ab7617aeb52638fef6
+PK: a7a163c4183bd84b756df3c8afdfb9cd5b242352d9499ebdab90785c3bd6db2d
+MSG: bf5252b2aeca1163771f766278768066f21971357ea7996158a8d6e908dd59b59971349fa17882cb9224b972d0ffabe85510dcf25a9f9f9bdefad2f4cadfbbdacc1fca9d948cb5412f474cad23b5b9199bf3c7370641339b750e1f78c2adb460aa5b21b1fa8f97714abb4ed5e9cb51d6de55816618abd3fd2b286bc11c67ba01129373d435b3e7e391ba372614da8322875e46a675b645156024cad2dd13f9a081616bf131a24358894e0efa1d56648ffb42efb54031da7f37d197615155aedb69c4e709c8bbbe7fbfcb598347ac5d0c638407847b281cf116433097f5662158719fcdd37beb489268ce71de7d70ed925f743fc63a715f7eee7549fdb909cc454c988b30ae4d77d62f65a07e2c8f9362385d028a603108c945872f5e1a97419878ed49542e288ef07b5c90f5c4159e162303d080f6ac2b058ddcac60746f9e1c9ec1df8eda42d62738586d3fdd65df55f4374f3294e0868d41ef0bb1fd55e0cbf195bbfcfcde5bdb41fad9a0477e4c90ca27fa8cf503362a33fdeca5a4f0ffea26e8d7e134fad3b1ec3d056055bba5e65d81153ee831873b938df7d2c83c2a52b3c221827f961bd008362232d882a0412a047afdfb8597c865a2aa2c2cf5189934a83ee6b752a626941edce0c20b6f7a69f1cf12f9a331cdfa9eda24c8defa769ccce2ef746c307d8bb04891fcefd49af3e6f96991a7a20f27b6c0af1218be31791d1d0293e081b90af3b92ecb175ec8c789f7a8642e041ec3a61aaefef62a807d1a5054adf8323bed942241623732a2051dc01f9a20a29aa48b3fdf265d0ba6c138fb5793e2875002e7de3f5c3ff7e83ad27d111c848b7e6e2e5ad5f28eb7c363f95f960cbc421336ce985f946b0515b1bdd3a832c3fe903f7b44e20c92ea80826fbf97e2a4fcaf2db1a08698dd62edd0a84589d7462c447b4a896fe00860042496bd51b1925cb79cc3b829016a4c7e62790f8058c546f2145aaaef4d4b1e273ff61300f8008e946b622f60e505f5f6290d51eb997d20fc3fbb3e99edd68ff5cce9e8c283881c364ff215cb50045e60f4a7ee45b6c9d86447f38141d342dbc5308f8c66efc47f7c45f6d25e6564309a862db90f4df331787ecdd89d3aaa46053e29f102624ddfe80e8a3f99287cec19fa83e44d557c0441
+SIG: effb29da6985971c202e2450301d49711bed25fad85f6199d1eb1e71914d964cbe18e34cc3e32872cdec026bd119a41c1c07ca41e82acba62fb0a7c82aed800c
+
+TST: 826
+SK: 5d66ceb7c6e58cac91e288279170e818e787180c6b42dfa168787dd07f809fa4
+PK: efc9b35db81f346198a7acc69f65fdfbf4c22e68dd7612e3b8ec68d378553b8d
+MSG: 94d72f6dec4f7c9206b41510ce71a02955604f3c5de8e447d5871865a75898a4d207a26cf33d10caf05a0b6ed0d389fee9ed49275098a88e1c0d8304e81b4074214c7a5ce157eb2617ef04e1324ba942129faf32c31cb4aae4a5916c750808726856f7180e5797ede44362d747d70cec159d3b6acec63a514c7ef31b2ecd16db7fe68ea9c5ead9d870921800348f695412f3093e61985a31eadb79b59d91dd9a37f8d4ef7a5ddf223d4b24774c2e44e3f271ffb8500d595381b3df2e8e6b79ee65535a519a43eaa5e52b256c2643305e3170cbe57606a0545f8586565cfb75bf5e9564c62af05f15ee6e62afeef8c2c7a9dae235c9edd1d7c25cf49adc033ee7b583f518bc168ea48836b50ffedd2032b3f630cc56daadd513ebda864823610fc67a72b9a7d8117105c1c71d85a96b1d27a441fa1e7c6cf80233a49fe0e76a40278d06e34347d87be77b98ded5e2a3ea1afb13bee1e6cd6ca63be54fcf88a20ccb7a9fc324bf6143201b44483bcc964033dab71cf8f2a591fc050d5724e95aa50d32896eec0f3b34311d2a9934e9f852977e253f15304cae2416c2c4fcd8f1fecc3f1f64bb79759929abb0e8e8f5f7293d691af22abd3b2a6770b0cf144608f2d62cc7e52bfe333b2ed2de39b99afd37e3acf07eda37ddf0df029bff2ec22544b60bd7db238df1975ffa0075a82abd8d6b05b267180b870e21abf36981ae7768de53993b304f1c5453872fdfa8edad45f8001aa0e7342b3b58ec0f389dcbc271fb0f9000628757abba58c057e1a0899f6faf15f3740f3143f5c0b7a9159680de8c557266441b3b01caac12ec278f5a1025df53edb6134c96663a9666ae3baa90fc835111ef051bd912f67967449113b6a85f71df8c6037724eb8fc7d8319bc0385be9b0e99e95f9aedcae8d45a514476f05bcd7235c013ebc3aea9123c67aa6f3b79c85ea5db159eefadfb75a50ac6b95b496b5572581a76112ff6db263fc14c5818aad5bca3b2cb3ac8116d429482781e06f61e7563e6505e51c8ff998bf84aedb5202e2f9ff4c2689820296cc69603091b8b818fbeb2af5f4c57060d98c1a904843a70bf975b3c3ca6031a4cad5b4bbfba7e9b47491ab740d9ebe41d768810cb8cc51a937f7e3b22e3cf07ceae0ce20831495afcdd8c1a98
+SIG: 6ef264abf8b0e5c2d793b2c75279614a39c775eb2bcc0891067abc61f6d644a69ff8f814a30522cca90536f012c6283a76c32b89eee1bd9a4336f4fddac8dc0b
+
+TST: 827
+SK: 62ed8682bd3ab3966eba3bffb775a318a03d99931979e99feb2ddbd69455a0ef
+PK: d32ada178b3ec7700c47dd6d365322033fe431c302b46f8d58798ed83371566b
+MSG: 9eb13bc7facf51a180541ec1dc5f5acb148c8d5eadcd2c4ef068bcdd11b34925eabfafabfe82a284bcbaee1381152af8e5e09f037cf1bb6484ac18e37359bfaa4c87aa07d3d14ed089b053910d1fa473f7bce143e2a59c4daf99b6c6e4e9291d97c864712af3eaba53ce2517a4f75cd7ecf278f34e22b7dffd088fa5ecadc0dd22135e42a536c684f2195d315f6924571e463f5cfc11b9f9d05a7ea11b98a169a1e39360973c50ad45c7491b57138ec050f43cbd5d17eb3fe0013e3d28d526054e07633152246f16554f3054749eea687b9c371b409cd3ecefb111a1d600407344e6d6ec38c60f6e545a92382e46c4d113125dbe5b9826e127f10181a35acfff28ab3764ca7f238ff479fdbc45b7a2ad0ff538c8acd0018d4470febcc6a307651cb5832f326b19241be9867e4eca6ae36f0e2d83fd77b97202b364716e36d1895a36853e7e76e88f62dbbf7726c2180569c66673837ad72ff936cf0e2fdb9ec6afcc79f8829e157f952288f4e00d0410a72253bf605eddceb01440dee5dd32b5a803439f038c06af1c90b27b5fe9843c27ae76609cbf832835c0e3c4bb59976ccede448786d91e438e0775c06a92d0f0b8dc0ef68260f7dd9e6871c4d0c0c09463852615218516f4a6debfdb46273b283382cd9ca744abf9fd439194b8cf1bdbb3175ca9c57a1c373c41fce92bd5fc012b19a0698aef37baf806ae09add8cb972a9ef9a7a5a9b1fd9a41d854c30cca1396140e20c2b98654fe6e511b626a43915b22fb2dad747ba7fe7460d8cebb2006fea19b3284b09c06a6f52f179a32beb56357b929a659f0fe6a26b697033def58ba603f430f74aa35070981db74ccf19190a1fb05144ec0a09a51e54765069730b09a7a2331ffb3de2a7e02c5e184da4013dfe937c371117524f7b210ba60e2692dcdcef36ab227b4c4f02a9f488972b847f0d6b59d02ee54fede8821db6cf731cc8ac895350ac5cd4d6baa3ad036f06f20d10a140c4ad3d10ca985532e3160462773385a2eb5e464d528e1e59c29f66b3de59e9ea28af3f97bfc5589035752a5a5523decd2dff01fc00ff31b30152ff5dafa331c6ab15873af41aa960aace7d2cb4f95c23df44b9e6c6e2f86788a872fd3a5cbe4acc95810daa09dcc1df933465ef040c53d9d959f9dad
+SIG: 3da8d14dc4e71fe6c32ede463788e41b826b4e2160ba10c95f1c8a2749aad8f12e98ae2468303baf6908bdb35ef38a5ecd77741e72ee3a427fd904dae66fcf03
+
+TST: 828
+SK: 4e57f0311fff0e5d538849b1216f695b1a5277941708204db2f0c15b3c73c82a
+PK: e3371fe236ad2f6f42f9e1fa4e1eda2c3e29c36c8ad2218a3c037982f0b579ec
+MSG: 052a1f41ebfd4bf65efb0ec8e74dd7b3065e9c482c49b99262e6dfa8407d9e31ed34d229ba41fc49a94a1309f990a99cb9902fb84f4ede91bb64714564a913d574d4a3c286f0a192a78ce2d55aae5c9fb057ff36120018b2a8b54d98085537ea64aea999d5321c7880b36ab43018ea2c92a5e68350d3de8526e2c8bc9141f4349a18a34f21de0abbf2930987567f0aaf8eb19145580d71306ce8a69e79f8eea26cfa0b8beb49cc5aa2bc77b797d4f8d50326ffb937399e94fdec85e192f1272a80e9a0ebbaf5d01f1b97060802bd4af34c0f7d7e98543f9d66d60e0e6bc0bf9c990be31eea1978ffd16733a8abe49558b3add0dce6defd64dc043f1519b1e9be66e06e41ecab168c8339a85e0b913818644ea7c5334468fd7196a01e1d4ce8dd1e7ee313dd5350b8dce4f5d7a6ac09857c4d3d0f10a3d9062609754592ad1077b2e2096fc9e5b1978c98b5660ddf51b46ede9f9dcd41b2ef44e79f6daff7d3626870e2243cafb2f4367939109ed9c01484b79eaa30a1891ea18f984e161dcdd1bda37134bf6735d2b2149b4898dacbfda61e6002d72a6fc5d21f1098213231132d56df68d6a9bfdf4eddc0524db8fd8f248852049a6825a5edd2360c009af24f0a94c5079ddf6fe796945ff984aac36411ce80d987c6ed67b6b0ddb6d417f6e809991e729d147dd0d21a093241363cf4ef3b8e3ba02d486633b6b217f5493e2e432b8c2e27d00c5b56c9b65f9aed49ce93d77e7d0bf5f92f92f5bb4b595d66f887a4880133f970463ab8b7f3d8c794c0406e88e3eab9ae65f1a185d6e39e2dd6abb8a93d2ac4b9208398dab89dbc07a41a50264026412da022b58f489d4dba31fb882fecb1ff8ca1820dda1865af1551e46cd618b44c4e6eb3037a9333fdccef4b895189e4390e93145d264ca5f45202a3eb2853593feed6c66dbb288ff3a3c0fa832b2aa7e529b5568897b3149402a907e741e1011ce0731c915f91446aa0d5caf0595f1816434fa4576db3bc31e10cc2af33f613f03ca7b9491a0a340525271ab537f62a11a84da01c7f5581ad5738c372b5335bab9b2b9dc2fe91e933304d9401ba8e1ce8dc55c4fb466b3a8ed7f53a122b8381d8f29047d7264d06fb51ec3e70071f2736a4e7e1537a52fa256a04ee86fad27ad2d28a9b3629
+SIG: 4fdc7b6e2827f64ba3c033c7fb6d1b35dd680f532999a0d77aeb276c31bd9e39c670978be47243c113223a57aa10233150678b40db78591c04d08df57a70a209
+
+TST: 829
+SK: 39f0556b1c5dcab387104181bb304de0cf815920b972e871d5f0fb416d8e616a
+PK: d85fb76e78c3d5bb7ca6b05b310191821a4a7d2d9bdf02292cc7aea5642e4819
+MSG: a8d034e170fc22b57a44aa6269ed1f01cba801f398df1adfe7df044d5fa468bbfa8af4749ab50d24d62e313ac0e73a64b4282b74626af2b4a4b54c274e5a6bc280b6dc25dcfe07814c9c816d2f9e36c05b9bfedff7c6b03cddebd4735e0993d3c3fdc6540443c6005e900b4035e1408a85016aa1b89202990e5d84ed9981c29b77206d7c113052a2029812c6ea13aae8be0aca7a3306bf617242298e68becd0d5d16c8887fd1950b7785a46bb022b39f7607cd8913718b3017fc3f86d6933f75eec5191ad1f1989a8d261786f56be4a988370db82961a9fcc953542e51c2e086db0e02b4fc346694abd9059d5b11722647669e7f17b745a60b02f7339fcc99bc35d59fd0b98b60c314abd4bf8aa4b7eae09dd0097acb9189f02cf85a251ac92aaf691b15cd4a33b58d7663abd0b0444333044af5ce20fd71cbaffc0d29835819f49293fc26e7f9787fc368c4d35cae92747f21ca1f3efd87a0d8104199416482d07bfec1281c66f565285bf672d5e7486400660c017555e9fa2bf6a4e7027f0e7e5f443ed658b75b590612abde0d80d1a26cb8bde76b996eff6a74e3dafc59eb1b584f4597a239cd839fa1f1b7bda1a24d150c4e24b91cec01ee53a3ac852a912de195a3c29dd7079aa7e88aa81e9d31b8fccd435eda113c3f82458b7f7933572b776753c92240cc036158a4ba0e56efed53ecb53fc093fead14343485ae5d9105bb163f262514e48be74159c9fabcb71d1a4280d9ed70d7e42b75f7fdadd02d69198f5f465bf604cb4254417bac3714b3a99e6f1acec9e3b3d097f972fbc36f2eda3926d56112d4e9097d89bdc35937b9a3158e7cdd5da401e180d3ede6b1ff02864192eb729781534f4964ddf2af11800d8b5b6d01b209aa3369366c19a28c79a87d2174ec22fb1489a6755c348a996d0aa56e0f60d58e26befa23a86bef4e3529512e30a9d1c5e4885018cb97aeb7c93c5c41caa34236575c226f3b235eddba364e285b6e352707bbb3b339bbf2a63a9cb9bd333a77e79bd58a48e14ce5886ed0cd07c2d165a81b5e6a31a8ae7806bcf2e0c4ec29a967725e577f1741ee68f345f5f7ab0fad31c8b4b18b431c4977d5c584004b45f7cd1961affe8738e24c382610efe998353d7ebaf919b279bbb691c3052b8b2c5f09808ef3a6
+SIG: 0166afed5a8f7c3f7ad6f3fdd2938eff00898eab815c5455ac90fb51f6e1854f0c0753194b7629594cc1271b003431221c574b0c0d19082feeda51b084ae5e03
+
+TST: 830
+SK: bab3ff7a4448d8a03d8acfdb913f77fe77804395c3e54ec235117927e32b50d5
+PK: 54975e35e5b1d0323f2d6fb5c6158bf6654b084f76bbdcfd72349229e8e4a6e8
+MSG: b647b67cf01c2cacc39de5969e199be6d9320167a4cebbf1625950b1e6b7adf5ca24d1349568865fbbfd90f513f05f79f70a63a23873dc7a195d4b285a08f30ee061d0b8e6b4d6bf9b2ecf2c69f3d5a07a6730537cca4a4e4c7ee684702bff883fab8bcaf89311c5498bccb5a0f7c8d49b54f482fffbca6e7da262452ba59a57a6879d81b73cd7adf72a3be28a373cd63310408461c21b907f63e086b292ff02833e8a2f46adbd671d02b03a69aca2e11d287c522a954520442ecefaa905dbfcc8254c58c3954a89bf56cbe01ad5631971eb39eb432a854e691929df7e48b900ca6e740accf578b31795b49a6ca774bd8b993106a9c4948c18714948315990a5f191692420f289328ab713ec19b7ea894d16e6476100871cf3168e4f935b5505d1ed5b0aa29be36fa3a346ac3e76f143c46ca69123b79c36399a0d2ed302772494adf442bbafbc4d01532692c7859df04d2ca78ba55d77fdf3e5ad993786a24cff2199bb49387873cc414b4cf1137abb7e94ae3ddbf97f534a18fc5ae58523a3cc52283dc7b016f31cd6557981c5076c774f303a47c427870e207ed8bd66640ff092db503fa124bfdcf020051dadd106dd245840b31910b8a9060d5986f02b60aa5e33b4d7550912cdc5776c772aac93ae19c73b7ecfca389e627681a8781eb47d84e93460ba891d3ff6eadf8f2a903c383474beaa42b90e032236dcd898d02a40efb44e47ead52b75b09c7da1cd6a2dfd4d1c0452de69f6acac1a68dd78daf972ae260821e2ec522fb5749bebe0adb452bfa4faa1e97911c1299f16568d68eef405f4b1cdacabed59f7b0fbceab719a34b299f58a4ae8154f98f4d9f4f140b1f085006946725e7c29bb0bc6ccf2534497c61d4c1612624a61d70d26c3efb7d7c351848657f7f8eebf8b990747740e6f910c97cef150375765c8c0b3b449c0d09d66f008e67cfa76ea2b6808b6fe632eafe0587f37e36be98dcb17a3f4a15b65a9f6fcf9642b52522077b1fb4cc3c08df4b467ca716db16b737f782cdf387170a5f1f6a7ae0ab3f5b7c585e3b0655a6456a503595ce8eaea2537855e7f0d5061bc29b4e67daa82463c190e9fddd52f8322ddb4e0f26b68778228eb57e1a185b7025da14987d44baa767b22ee7f4c84591032e88ec12eb8c5a4b9e157ec
+SIG: d6b4135fc7acb3d7cdf987896d91b8a90db584d8933a6f3029e3261ec1c390cbacfaafeff443b6da4fdb1d84c64a54560feffa2f1c7a91bde9730222923b6703
+
+TST: 831
+SK: 486c7b436c1d43d6b703512283c166dc863e5a33802f4ea65fc738778902d014
+PK: b5dc947d64337cae82122bd68cc80840596de3be56cbd0c833af3faa3adc3776
+MSG: af036053672dcf3aa26e28ec6aa642ce284b896c69887dfdcf0824515eb0848d9d970ca272df77a86b3ff6ddaf3cbadd3ab6283bc37cdf7a5607d5dfc7cf96329299cc53edbbe657fdfa2ca24467050a0aeb8cffd7d33d543ec2c191cc0bce89ac37d33293b1888ccb76c28adc671a4935a846d907e4add0110febbee5aec80f9d2ff74e2af4fdbebbcf49105a6469d7380006b2ca44364814454e445e36dc0012f339c96854f836442a05a50bec907327f74ba9f6fd790ff0ad3783d297bdcca76460783703eb5f2b1f51b0a740ce7a8f00a387e3636270a971fa8f15b4496730d88add807a7f7e987cd41595a2e7435df5195576a35f5e91b2fcfac94ed5d77663783b61e6671d34838b6b5644fbc1c539fe159b7792db967e8352618ddaca0cde73437b59e7801b49eb4609b10577ca2692dd6f9d5e9d4b5e5e62c5913e7b87e6b347be6153b17199c916a13f8a885b378ef09e13cae4d8b079d7d5cb9094199b0f20533c90083bc3acb2667697eed22e3670abb4a553e995c9dd9594e592391a0004b6556544f35612c4971359577c476382ca53b3f262a5e33ed26eec809f4fdba4898a113675cb6af717db62579f3980b21463be029cb4160fe5d257c46cd6664f9861ac50fe05c144057dce2f8df1532aa7af589f41270601cef06bbe4f35c31c782bb3cfff7d5ab64a14ec417361f1d32cbd38b6bd0e02505d1416302b8505ae2a96e8d5339c346c2b0662d350259c50c5e48795914e6f88e97c811c393bdf9aec7ef82047ca28ee971c175c27e36e109727960ddf1a1b976ab44f4851607bd966808ac46d54003128297f5f4487108d6a02e7a16413d2b75ecb42fddfb669c801d23de50a6f7bf658f753c6b2b3b47c0640105d0a801b32a1943cdc15c886555eb75bb7927b93c35c5be1f98b196caac2dad991b1044ea863944d54d883abc3c6de66ed868ee84bcf9c34ccdb80fcd9cc0402747732cd630bbfa3bbe8b038dc1dbdaf436d9ac00c02d528ece2e791ee312a868feb2f587ca44db5731384fa1831142061b2ead2b80c66bd2fa5dccabe6a25f2a493feaacd231d2f409646b942a578545ea4feea9a73473f79dcf13e0c9f1b49fd8912ec487328045bd0fa228922ee6e973e61f6e93365296578dcc21c361479ee2d24879f2e9b
+SIG: 31f95cbb7463b87528654227bb1397bf1065b4f576808078207dfaf06d124b41f4c318f4a9315a66085b9e568a71e414ed9414517310c699946db0c976285207
+
+TST: 832
+SK: a6e6ad2c379c6fccadb4a49b232a9142618ea30103c33c226ff628bcfd81f426
+PK: f7c4323f5c419d9b3f34a8eb42ae7f1faa2333079030c5d64f9ffb1e9b16002d
+MSG: 2e857676a5bb1c6e9e94507f83c60a67f547c5de9e94566b197a6af6cf4752e93dbdef6b9f66d1febd957e42a7f5ad64ef1dbcc4fe69ae9525d1a4de67054c88f29c0647bacf8b82f321ff99fe9eedc992ed34c1177fc5421227ccac10feb9ced4082f5658da63714723979737e7dcbfe2e8b5d50f91dfca83e7f95f35d1ad8dd51144502f3df672432611f0e766a90dcc2a5739c805d95fe5b041de9d7fb47b4404afc803a3bd4804c7817ebc5bdfef8add9e250b50966ca8939b22b3c6ff936eaa659a240c0c848b810acecf6181e0e4db8e4cf8fcce7de559cbe8afa9db8499570911a3887e850e509cdb70debc3477d12175014f79f81ba113d0b7b335118f85cf59996f806758eb903cc450f52fee102efc01441e9ae5fae74c231dfd85eb6bad17d6b70e938584facb2172cb03bd5ea07b7f0d371ffa351c0ee4efe9ba4a3fd543874655e7d39c53ae86329802e5c385e9283a2973cab8cf7ac7ff0f91d1d48b58abfdad658d812f07881676bd226bfe957d7df30c4130a448354a6b94405a411650a9c8fc851155ec5a8a3e3b67ae0c4b5cb89bb73fc82974be62da73f0e23092937d405ba4af6cab9465ea43a6253f4457082a06ac12b75e88ec684487f9076373fab8892859d8e8ba431423aa805a220cbfda431b32b1e03121f7fd4de18591f2505cc0f5b2b1a7605fbcc63757b07e299fef5a2b7365230c2e92a25962c2e8012ad3fa9ee94882709625ba68c7b213664ae2532b609d7c9aa0e83d493dbce7632f35580e06d3111ced320dd0190441f62d9e35f50de59c272fb00f568a00b0746c33a9bd2490c074b91cddc487ef2e45a0f030e08fdc1817bca8a9ce29d29279e755debc28dfadc3c4d1b458486e3c8d0c4318e7e6f9eb5a3653b3f7c49507077cd5eb81f10b88107cc0f9316932abe9b64e8886d06856a85be63b0c2b475c0afcb0694426860fb24b5c17ab6ab7733d5e641be74fd5f6a1ff18d2f9a42770fb30750f56f4854e38d58aef18a2a61cbfb49ee576ed97737bc28df3268a334175513d97af009cbbcfdfad5039d69bb46f708867d9b3ce0bf2f569e3cfbcf6136f8870d25208b21a3edcb73393dfcd4172c1402c41f36e3f82a4ea6dcd891686ba66e14320aa0e22ba0c1ef033d662cdb860cdfa3a40f6cc532a08
+SIG: 07d9fc244fdab00159ebecc5a00883453f08310171769d297001e877010e3eced9fb60ec91cb4d88e7ba40c530b1f9237978ccd96d5cba9e4fa27e2a0ad9d60c
+
+TST: 833
+SK: 9b6d7e28eb051597324dceb7a18941246725e88d53ab2c34771105330cf1f4ae
+PK: 8872a50b5fe362f8ead1d40e2045f0d40b2e7b50b59d8090bc47ad68ebee09ed
+MSG: d1e1987bff65f62ad67624c6657924f5d673b7824ebe404026c0562ded3143440be637f98c9e01a6afdfa9a47dd49c7cba6e3fd23e4552f7632b14380b27cd3e9606cce350f152ab126bead0a5d3bce4d42092d934c8ca337e987e11d86cfbfbd2acc3223bd16744a927728f485372175cc694df30a73f9d33765ff014ef008d5863210338cc3482cc27ea317eec921b0c568c38ab27c4a564e802b1b94668c651e20a0b55f3a79d215fc3a0d04904010932c4cc68c2a9e7d00e5d38d82df55206bab95cf697bebc7206eedef6fd18d9a20c2cbb285b00efa769a08dab2b3abadf00d198b4f192dd44bcb91431823ae6fdf98458eca39cd29263f0999303e70dc694fe01c53a11c1d1c34c1ee5068a201dbe7e1008d764358968b402aa398549507f7bd1850800e411b1c4e28ddc04a859e179be8ad7e6670e509db027ad7e517e4425954f5a807414a6da267a764e712a998465064982d851a265ea3c4dfb74f992a7cccd9a82687fa61c322c4f589e86b8825213bfa951dae6af354ace18f073995adc95839dac0165511d61753791a53e48e3a8273d44823d2596f2a2db2e5f1ae597221ba7f3ebaf4a7b2888395002bdaff51fa54bfb979de1031404ca7789fe095d4d17f07a35556b10fe8e1417c8a6a631c2ed36cb7a0e6181776289c344814d42131a73b12faa35d77814c681a601374ba71cb9ad5315fad42d3acfc7c1d628810256daf7d8c3c9a2e5bdcfb770082fa638168958523a1c3b035dbc6d5adf26df89a7ccabed3e7dd377c16da841f13c6894d43cebb4e39022f1ccec2274445c78b3adc7bbf70d890b80236cc4468f9569c59a7e33b570e670380d244e4e310e11c392f1e334054b92c8386c161ce04109b037bd628d919dcb62da1435bf94e88b0a8846d486d16778f7a3b880e660f441fdf86e56b8aa0661f55aaece27f9ddaa0e2a22c215b040539726b9853915a1592dffeae32d7b5b67eb6205bb0bd7279f788d5f833c4066780ca0a42d3e4e1aa22bd06bb5eed89b9413771ecab644ca72d1291d00f740901a7311dc036715d23ebd9a59891628f0d87ed489502f06d75bbd11cd1602a35ee7e13335d6a144b08830e669c02e652f3f100d393ef9b4ac05321439bce6ce36ffc5abca890b8796ccb5e16303559c5d9117f0f31d
+SIG: c6dc5ca1e8560015b493afe2666ccf6fefa803d8526c837fe7f123c7991427ab030d7c770e45f6de8481523b94ece97f3f161cf5b8c7aea39f5ad826bf8d0a02
+
+TST: 834
+SK: 7009edd0795096edc4fed55a17ccf484131e608c6d5d6696bf3376e26924959b
+PK: 77574bf069527145e72d3e85ce7d4fcd671a33e0a71e6bf0da7ea471dd6e86a4
+MSG: b12c12470539547c2de6bc4eeac7b63e508ed710f35637d9fdd2dcca322a7a5071dab2b2845e30792806035c9fcdafe2783e3b677d6be5aac70b33910a2b95e8b5d59bda615935a417b7ae19a7853774e89a12aa547b4192979a01ef6ef32a40de79d680057a83a074617ca6501f59e73564927c38b58c19585a2c03659c026e4de3806d6c1ca8958dee47bcb889e76d2c3a9ab5b8b6afb2e842298056567bf9b58957415483336233ef4920fa57f496e1f0348cca20366496fab3a75bf4214ece47a45feaa1392db3f254d96a7f37402c9811140d7358b4ef8f20a298eeef904e37d68f378d33cb96d00c03109fc83fd06a876c92482f61ab7914eb7c2e5e84066e0e91e21e42e9be23df12b5c747973cb86442c32291d3d1ae719b36a62faf3abaa2053a313f625d85c51a5198571915ef8a2b199ba37d25884575ba1b72844cab4328b57fab1ec974ee8ea1df7ca9c78a4d3a03bcb0ab4169bf06a3a438d9566c6c501d8d9ccccb1ac26b4da4ae1a9d8e8b9df662821ad975c9b015fe26f6898d22ab912f0e405a5b27cfd39d657dcd92cdebe6791902713484406dddce71188731e44319381af27daf76792273b8c35251d11b836afe8b3ce9b40273f6915ebe6bc95a75bb941a429209867fba8764bf6c40db6eecb4f21747837cf6ae7fbfe36d5023df7fce2c0c3c57af2898885313c5c4bda35c7da6cb29932fb1991f62bbb080b32e2050619311ae69abb3022d913fa9eabd5d5cb4dc54d75dca638cda9af331c0cf4d2007b6ca39f655a61c01039f12a4b9782bc39aec4d22ef0093388dd7d5b56dfb8a7f9d8669004e2878dd8a6d76857c0845245068fee1c5319631e78d3785165c70afd65299301378551ebf613584c6a7620a0e3b6779f38c0940062497008eb233870868c21cccac239501b63b749a85602c28a095cafc749b0511a6c878edb3b780ea174d07b121e315a826dda6ec8dc54363e2cd2e6305a194825c0ea90efd7a9fd89cd97b99c4300bd3bf9353d82fbcceea71b4ee3f1aae9539b4cce90ca477597c174ef20f4b9f4e62d09a570d3135aabee9551fa60983958c0b7b8c3744553ee14e7f3cd103a19251c99bf6384abb60a76afc6658b80dfc5110adc4c732fe0ee32933fb284828e008887aef80f6f813340446c0217c12ee
+SIG: b701b8f9a434e06d719ad25dcc54060c7986647f44f3884bcb6e5ee1d7a446cc265cec029b537da7f2523326558ac9ba34f4cc2a97cca3452e70562e7a8f5504
+
+TST: 835
+SK: 12fe8e5ce20cafaa3279da7b34aa87752ead679f156128aaefb4afa5db4f2a6f
+PK: e77f44206bb0c4c59a2870cfc2ecac63362deecbe8115de5cb1afc2d9a3d47f1
+MSG: 6b80cc6fbbd332f8c6197cdf2e6dc19a2130faa2ec938ef558b884ba4fa5e113e5b3e4b1aaf51b695f13effe13f77d39cab3c07d04d66d430d9974b1da3d39df1278c00d6bcbfd4bae75b8c076404dbbb83448fb493df67000f97d247e8f23dc081fce992b65a21b35d7bd7fa7dccc54a560afd14b1ec436c10946f6aa59eae1be3ecf311def51e46b6b4d1d080d1784b2334b80cfba72cd931f55ecd298b05dc836ab12d0ad8b5d6e9b1e3cea3d843368eef19f5c14c6bbad9414cc7a4db6a726e4fcaed44440a019fe12a60573403c0e662dc902d1c873ff30c931ba7e43a3b3bf71d5b094ea504971647ca94356f0a53e444b4c008ee5977204221b400deec37fc273452545f8f218be988725bc38c85df212ea73dc0bc7cbbac907982fefad680fbd975c2093a7fe8e6b37c1cced87f81daa57291a5a18476d11a18ec4b5cbce5d55ac9b624b048430f254f671078506e6989df7c09256525039085ab7c130c240004abbb3af6b481cc1a0617e57e388ee4b1f052f34a003fe6bb202cb87d2741bd8e3454ca73d2f612011ecc74d88343510a63c9313ddc36c25d3fb03e188f560bd029c801585ce552988dc55b7d8522a3396c01d5e715ae26c622c64fed5b98e9c559e4aa78d1ed3b7b890d477ec8c50a0ff107a3f83b07bd35e9ce9a08bcfc0f168eec7aa311f71c66a71ceb9d5a2199a14be36865ca8d07e186b1392b9290c578004d584f191c82a53d850890bcc0d12dff840e043dddc2e670c836020924f58c044b218763ca61982bc332d247b2a008ab570b6565a06892a26cfb0853d79da28ef8b910a9329544b792ae4456ba7765066b9d1b4a300210448660ae48b504441017cddd1f6f00938b1072c8ab824adfe8ae34923c82eec754bee1a6550ab1d3da086e3aebbf21169c44469e03bbae0d72ce863457784cfe1dfc276f1afad9ee53ebab5a3c6572eb1cae099a4a5fe19319290e6a1b8b0e7541ed735b3f21b1e2c7509f87fd1fed00007479b3c1bb78432466302d246d8d031996307260a0c41a0e3ecd1e7fd834dac11a13eb036b39c369966fdef394c183e54e7b0cb3d0ceb198bd0e66c00d38db703aace30cbbdab369dfd1d9e514d0968f100c9f07c315089adb3ad02e59c04b9be46e99fbf5a62c6bbecdff5b381e55127824ddb18
+SIG: 04eaf900966e0992d36e3c220a4bd4d82bcc6eb998ed051dbcb9160bcd357409736bcff7e6630e96f5538aeca6ab8b0d0bd82c0cd7c4549917febb9cbada080c
+
+TST: 836
+SK: ee9b6c2e0c9b01472ce32d54d1762ab0303317d76d3aa78f5e08a9024ca1e083
+PK: 016df0f717bcb7adf626958d83bf8aa325c70518c68bc7efd84253b75db08788
+MSG: 772cc25c3b69bb3ff5655664efa478ac414adfaea70ac4a2a887ed3968c54d34dbf1be32cc9a9b5420a4ad3c9a877bc8ccec94ad473aa7a3c7de08a0fdb5ed1e89872be78170be221d279776bbc6ed9c5a67168980d5eaf895e1340f5dfaa3df622d6544b399d74945fd13bb1173621e0561514640137aa7bc9cb7debeff2c626977d447263b7e57d43d69efb230cd25865e4d924828f5e36f964e403e3493f30d6dfea6ca3b781075b5e3b25c05ac50e555f15ba12b0e059bff996484129db6eafd88993d6f0b7ecd15dce2fc99f8b8e43516352ddb461a04b9ff3486452e6aa6a54b2d1062a7714250cd2a88ff6c4c17b6cc6652d8c5ac27d4443aebf3d5fbaaee4521ec76f0413db64421ec8d6949626725fe56160ab307c0e73906c45155efabb47222021f220d32bd3db0712abde2599ea4ff799717811dcdf8182df6716d2a038aee15d778da55ac20f01f25309cead5b5b7b22322e1828ea7c91ae666f2dcd684073148e31bb2247d5f93506ea8085227adc9ae1982e950f006a9da158b9cecff8929761c84f9d976fdcd317ffed36cbf6acda3e50c9b73bd2c8085409d119b64ced7349a2674262a832becb03c2edccac0ec54124e82f810181792da49ea10bd941f9895a06959fde0d3b0ae84c39df05390ab33c36c79ca22e6594d7fc6e3f86922d78eb7f5c25495d822a3b41051b24e57a76fcfc165cde6d096cc7b7e9d055fe864d52942d629a8ac261be1dcd3a21f895f49b67ee47eab7cf1644d571d5ff38c179f5c6a54a3612fb34753412a1b95bf62ff3179804ffbb99051f2b080563a4ae0f27cf996ea8be3bae0a4339dccdff6b6671559266eaff4eff682b8dee89c9d2d45acdbec4aa6cecdbdb1d284609e65efb77bb8f1a51fc4d4568a705fb9c97b2303c1467dff8c8c5ee27559b93ad1c5b9c5c6c7c529fa8c55c75ebb59b2a818aa9bda1e9e79bc66029772f8aea11badd3226565d54fd01bda8cb270e70dc9339b46900b5818e932075be6c28e73a191d02cbdc7454be12387b0d47a1ab14232d2342a6f1518ea97098b815a1ca3f9c70b25722b1bcd7dacda635622fc8e72959f57f767ea563da4c158eef7200109f61416c2e70439923062437b1d082a8c7f4394713c1b7ba0587b841c114475ee3ff059df8cfa12a321d901cb47f5
+SIG: 4b001d9642835d72138d680198e6af70b5de7af015131ea726f4e51b5e8b6d48c2a6ca8e8709cc8222a5047c09a66e518ac5e8b6e53548948261f0701f687308
+
+TST: 837
+SK: a3d23505d07c5f937f13639dbd818e85145234ee7017ecee8636c7ba76ebef5b
+PK: fd7fdb3d022ba36eadfed0daaae5bff04505403f171473e4d361ee8d150a0eb4
+MSG: bc298ed69892904028725e21b114462d89d8c006dc884b178756838af4954ff0f1b79517307a258a0e7681e879ac47d7920230b0cc1d66171eb214d77cd97f617c405e6c2172fc589f1625cc5e1b593110531f6eb53f1e6f486d1964612447750a041fe51b332eb3fbc711616ce35f040442b43163b80b751e21ec1245f12e4883c79d3b413282c69bfc6a465d1e7896bab038dc89b4cfc032fccdfc87b07f06110e1f506acca8157a322543bf1ed8906727f28d0d689bcd7dd3df85935204a904ab3f7a0d99c16e5a542cc2bcdebf5b502dbabe33b972480e02e71a438a1980a8766f108bd8ad51104223994d9bfb3c3a4b7a59238ce2ef7d7288383ffbf291e1602b384af60700d7daf0e8fe60f8caede43db06b3f4c8cfff749aeafa46fc61c49b2d5a41204cf86f049254d809e9498aa9d4cfdb94acb2babfcf786ddfb03691516b3838b0d4f201cb2591edbb0b0f674e1e2820316b72e81b48cc5a6b29338bc36681f8f7dca43ee6c0bd2e402afbf967797516453bc01be86bf42299d1b736a0d97bbc922f5a78af2df42e6f8c28e953f2ceadaffc5e93064041e425ad6975f88c7aadf81c368691a581e885f2a6ba72ed68b8fefbcd6ce368626d44892a20270b5f709c2e34b8335d42eebd67a24df73f45455c41944187b6692f054b2fc9591373f19fc71aa7fa27df6006a1d549bbfae7d3c3eb36e5ab2aaa10aa5538da7ef36c8ff354b6058134004d660a4036321caad00a30b1c498ba3d808c4405ef79618fc2212a7b83396a3d7cedceb863c66374dc469ae183c7ed74b3e70d6374a062de0379b21cf25d3c4c5762115cdfe755545e89ad4052bb0279d938e90de3abf504410caad72b7c29f53d01d9dd7f2ec5e459a04592bdd66416613e6edd004569e0e6c98827b8c1d7002a6d1bf303e18259501dd89f6ee94766d18af810463eb13b2efddf1723af735a88716e1fcb4b7b43cb97e1cc903b2408ef453ada4164786f00845fbfa1ffca5cc3e1c4bd9940e7d99aef919166d058b51453c9c14fb9f3251ec5fe4f153c70a4492dc3496296186f23ad47ebad13c66e68727ce50ba9487f1801890b693efebfc37bb5d95f8af548ec8d6498289e55f9883fc5be84c256d2bc5484938c709820d9b6b8059c0aa4267dde69078e487c8865c0b130a0ca8ca
+SIG: 67a667ee0d6254ca0a8f212582c0cb8b6ed97cc967db021296ad6aa99f0ad3a944978cfdaff13fe5f8c6e88cbd831a5473d0742e3734b3e2df00ff3240a5de02
+
+TST: 838
+SK: 6e265105ee7171d1bd793effd87d1e2c79450d5e188b57be3aa162e2a52528ad
+PK: 1f403c7a755031c13ca63af57635dc6e2c4f23bd6b1d67ca65da68b09943c554
+MSG: f8b9d4b027ebb10ee511819e6e56fb1ba9584018418d82885a38a449086007b8785b5105caf782bf9b36da039cc60e227c7e1614f29b640b1e9b22747eea7a6725614e89e0783ebebbb7ee557ef36b2b46cf6461e5be2ad1d7a7c2711a475ca4fbc33092ba425667e34d090060518f2fec636b049123876ab21c8bd9c50dccb984ca011a02eea020564fa821fc362bfe392aab50c273fc7b5a042188e331621b9d2f743e5c8cf3ab1faffafe2a0004c8ef7cdf5e6dbb5eb544e4289f71a6fd15c638ce29d28efb9c039e477429a3497a83827e76ce77a49816d90b41a8e152f37a09e6340dfe069a4ac6f27dd2eac747fd21e3152088c1b1ecd32ac679927490750488c291785147b63b0b8ff11d189b9049b8a396b6932f85bd6a15eff9f0ce1808411af0f9c8e6e97b814f110bd4df1386a9797dc511f0aab6ab65071d9ea836532cec51b92ca7fbdb8de1c8436658de2eb65edd86044f6c1aba3178647ad678612ee74f046ca3c7fe2f39c09dd2e07df2b4227085fe936e794d22fd5f40a25f08771580ac801d9889f5a76aeae1f0cc4a9e1edbdda3750c74c850524b32f44933fd883b5372bfb7e761e069fe7c1c0e7fbd4a7f58467ea6883f9d5b7f66d386b0499bb6fb5ead89c9a1fd2cceb973e2879b5d03eaa452e16022d59617daa0486f4d4c117807fda8499dfb7a286fd2f71a8eb5fe64065c41e4e1e2362ab4e477969e3a408a247e3a56fc86f2b01ef8d3cdda87258234bc7f25b66907f364b37b6245296c4fdf499f20237f4864852fc5d8cd5d05418be8b13859ee9a43e17e1f57a4c35ea282ed68ebcda6828174245a49c6cb6590eb1f2dcfb007bfa1c32077956da9acbe3ef0723799fdb869d8de30706a9c026814d16a01e033c91b59070dfe445c5b848a516612e5131fe8486921e36b8e7ef157a88822886c681b5da71fea94d957dafec26f4147a3b2ac383a5f47c8585eb17a8ac65790641b4218d755f8bea4d97ae2a45bdcdc23236294d852c95d08406d2e9bd30c326452538c1f5e5004d4a1a82720da32e59dc3ab18ea08a058f791d24418556086c1e4edce8982aa23b118fb266e60b542780a6933add913265512c07b114978d44af73b2030ec47b06fd09dda8c4f1d4e313775468c451f9ee611e9cd4c0845c2501948a7b14ef1d4b5cf
+SIG: b5a83a117a60345a67e4a665f37de722a6ec03913829389959f376ee626477e654ac8d720fc727d4bb8fe1544f5d0b0b850514290b24273c4cd4b73aca4a5300
+
+TST: 839
+SK: c4370d2aaf35acd158fc0d1622a399c99f41b9da4e970b354e5ba05cbe844ca8
+PK: 3545d7d4c95c3db6a54530537afafa4d86ddecf9cc7e66c319ba9f7dd7d07ee7
+MSG: 619f57de2b1dbaee209a825d8ca97f84ee49eb12a0b13dcdd2b3a4ee45e0176d474cf09460c831a8ae1d3f39beebd08808b3ed1761213ba953421860cc07e2db312e680df03e60a6870264abca8fd51301e1c1562023d802ccd5c7d196db39fbb8304b0e59e333164192ecc333387eef69c7a78a5d11258862d6c281b19c0bd336cd3edb2f9faad4021ac2f205c16814b38548433ff9eddfd61133779769dc69afac658afc1d1b416d390ad5b45a1ad5cc4b00b4b278fbe4b59d52e61a6a5fd00241c6cbc382d2d621a3ded002019b330560e361faab28f41d1af9c9c0020f2baf99e8d8ee58e3122202147c0adc57d670c5b380af594cc7ed57b87ec6674ab63f3a9849753b9462aab5de88c948a8b109af4d4954927aac58bee953be0d8d7d71aa11d11f1a87b1477b9170bd735cfc2449f051b82bc59b0bee76a172e8d32670f51ddddb804ad110a565e384cdb76fad04cff67893091e41e69cfdf70ea926c26369a5b6193b19ab0a62558da55ffafeb8789757710644aa19f474be4ada9dc1849b07d5e17b85f921e1016a54aa6095777253a73426fc7864b9955f04907023db207f85dd21a65106cf0d622385870c34c2da9a11e4726395121e4a6761fb522229d9e5cc9dab35aeb87d0d79693c006fde1cfaf116208bba962059cfc0d2d6370aac7748362ee6a0a3ca7bf133ebcfa20f1c4ed8307f800cca7e6c4beaa3fb2ab086125364285c44ed1a737a67cbf3b763c9f8b1427e89dfa96d290e9d4842fe6316afef834cd8cd1fdc1f124ca3fe26266da62e275c0bf7fcc8e5f9bba6c0d38e23fafab1e049481794c14f4a8c53be1c96f769c9b13eaca39a0e49366d2c9ffe8f206360a9d503dec598621112e3776713e7fc0649433e257e503a546059a989da89157d76476005fd90e4b07aaf0db0bc0bc0b67db8dcbadff39374e1afae551634e0e32831ad0e5fa7d5216fa7c644f73e1e8e07238394a416c169aa9d5303f469a5d4074308721ffddeff6559e5adf0c2773b3f5264e7aaa8c2db888e28e815c71069c3b4ce6c29034c0ab3b5c19a80a9d8c2e874813531c422752ad62b3c5a1a3d6c5a5db587270693aa75d5f172eeddf4eb839bd793affb1c796a1df0e442ddf99b780aa41eea0fe6f865bb539ca53aa45db9a856cb75d0151d35edea80f2946d
+SIG: 9febab5ae161d692a6a394500a2890d21c7f0ee26f4640aaba4fe66b90b89edcb80ea4cdcabb4d2c3a5c4154e8ff20d0e237fefd00c7ba9782e1748f6488ac01
+
+TST: 840
+SK: bd3de1a1d164bd6e9be0a6d107f703a6dd914c8667cd341d139f19578d933b16
+PK: 9b024964bdfa852eb2d4144f35b7cdc26781143c2bd7f660233f8b8aa36071ee
+MSG: 1769fcdbf51247ed4c83a00bbbf02f4428da6fceddd0161a02fccd1500970665e1c7630ad22e3d9749c792e71a260cfff6053256e02f5b47bba14b761ae53ca7219ed2801d2d788e26419f36c81ef92c2303683735c8a1756adab6a487923153e435603c96b239553edfdeb093298f7ae7dc90f16a7e5664b9e4c02ba731a23cf2234e250ac9742633a932a948bb83dc3d794d059fedf4ec8618c7433c5d8fe5e62cf07b5768c4d9b261c71536804fe2e7ca7098876521d57677361424e47f1b959237f90710421f5bc4f109f7d489c755e94eefdfb3c85b90ec013181a23bb9535feea4941d0a06a540bd6b588e55b7f35757149ca3e640965e1a0ff7f3c8259259957ff5dab9fb8732eae719b624a4492878179b5a83abe51caf02083d737ceb4fcf042f2e60ba0297ac72b87fe3e14ba5fbc54b48091073896823bfa289ce8e16873b48812c32bfea5ff6bb221d1ea5463d325bbe311e7fd1e783de650b7952eae461d63bc7470522af5b7789f8fc2eb192d2cf776c5c24b44e29cdb0cccb1d90361438e4950ff34dbcb3cb0e81cc45f8d0ff570949f78084e1060ff5594ad516f50f1cb0a765e1c0e038d5943b936e4a8b493354e79abc917bb9271266eeba77a93a657f9ad87b291ac7ea386f5d4fcbc582e72d5c23d92ba944b0064c20e3e2dcf504bcc7c6966c63f2080843600ba313ec27cba95e7ef318168c9067dce86c1ef0d5d9eb7a6158489df32ed58b6931030818f00705a0dc55d3dbf8006a8546641b1865d919bc242202cb3ae300bf8653e3b37894c3dc0e477b9d7c41baf8d3887c2eb59b1e4d50bbb6f1792a1c9367c65cdb450c2dfa2145e611a97ad81cff1fd83c6cf7230947eaff4c21dc1bafb71ec41e5bc72b3745ec3e38bf5930c126d060f0c50a895f009aa18e87f2174f58ab5379a721fd83aad5517fd99dff146edeea61521235e2f1a16ee58303e091be8d579094c1d8a20bc74a550d77c00d087571517a63cd4126933a4f09a070bf8ea4ffb846a9780e9734043bac4c0ff47b1afccf5293ac14bc73ebf67129657e4b8a8b33ddac7b0f4d719d2dc65df6ea0a3f24cf44c8338ed601a3939ca358fc4be13e8ede027539712ca23e3ffba706e8fdd62a074ee0ad7420f78060cc96fb2abf30e9eaa241c0f87ebbe3ec73517596f7c3c5a80c
+SIG: 13cc158fd061792fced156879598251dd01d575b400fe3e39a700863aae8db1f9197fa501c0cf993e44d6ac55180b869838e8ae24b214fa35e244b7a6cff6d0d
+
+TST: 841
+SK: f6ae516a51296fc523cea5f008cfbd09e73f78b6fdd3b69426128041a5604cf9
+PK: 376c82ba7b87aa77418727db33d326ae758bf7a135c10460cd8bf8feb83c2b10
+MSG: 8342f25ac4b17ebad6f79b9a033175c7f28af09e658e8cb98c294f15c3c8342629cb2a3247dfc875b82f5b380c5d11426a2eeb62450bd885650107c68362a3b72ce823f2d15942b7dda301d2fb638f302aa9570b47911dadd3bddbfed554c1c80bd718078b8bd2c9c314a5166f265e8266ee2db357561a5585c414a7840bfae609d7cddde1fade85560f23d638ef3d52e51f5cf313a072c5ea0f817f7281e2cba5c5c8d26c928592b81f0ff8cd18db5a2c41d880d74473863c7bbd0056fa4d4afabd17a3b89d97d3fe5dc06b0f612a1d66423923ba8dfbb8ec8246624d83784eba4f5736ba385e442296c8cb0f1b68e03342b2c6c103346f6dd740e26c3d13caef801d1b2621d89f069391a078d43ae6ff12eeca66bc32637b45f0ac627c2d7bbf8a49d9468175e26885e02821d3a3baa2c3e3a6bb96b57526e224cf3d859f669573cbd5c87393746156f3d1c7a80308dc1f2405bf0d40be1ca73b767dedf4031337c081bfa3ae6e54f6023f42f0cbd87762db55913c707206034010df2aa8753d030f03c267e71a9dd2c6c19de3e1851abfacbbd5dd5bf896fab8e415317b49f1e4096e3da99a5b5d0a3c42daf9de94847c1e53c8818a5b843323f501e3a7fa68df89a5f41f2c62c38d17f250b02a67fae47daf063f558942377ef8a89052f1a215d768f7913a7ec14e98b81e4b2ccf26bacad6f39664afc0e91a3cad691db2bf56a7ab6677b49596db887c97def43508a7a2ec2ab755ec368e2e53d1e16b60fff09c3b52263f0f7c1ea9cc35373197e95c11e6d22fa9d8299c423736f5814f1e798d227518600df6a790358deae38d5639e1983fe018436ea58ba8467548c929efbb16dfea4102253a350fb84d9831c4c2cbcb76e18d7f3e953641ada41421393091e63dfe66de24c99232c7d6a2837a48983cf5b16331ce00050d1c713958ffce5f2e9348c52f53120579a7c9a16008d134838e596129c702fcd21148bdf9174d48e2da0a8a66359edee01c5009ef6742fec41c1acecd03efe1ccc9b130d6e5ac92576a85ccb7cfc7d0e4233106172931a08699790bc41acfbb731adbb26d56b39aaa5b333bc1a10e2c7064ca86119d8c717148f92441af24cd2aa8f57c86ba38a59a100b9276df3827ec7fb4d3faf58be31c6ecafd69cf1c6410a49cd7081ff6e9fc397c2d20
+SIG: 0fe4dd7e1f608ee82b7fe863d1b03a81843ce20c762cd8bb24efd46ba025fff3331d875752ca7220c53dd3c71f2bc1e2c64a2f9c58865a2a244809f4134e5307
+
+TST: 842
+SK: 83f789900f040dc62f4d18784cb64b63c88e8d18001696bbeb4707c469d11a5b
+PK: edfc2bab7e79f40037fe4d9041de48da9aee8f978098d7b0ae17929025e4273d
+MSG: 6c112a20d30657ab5f8c5c04478d6c42d1c6bdef38cd4fe006ac2a57e290ff29287896eea8c30a0139c18fc8c97564563e86c8d34056a6719bfe479d9e87e81b19452331bfa154806882e5039a20c9e954b1fc7c015dcf5815bd7cf7b6357df9280b9bd43f89ffc91945323b5acb2ae00254d4162868d1c83ec6e0fcbe7a8ab9254192149c6bc9e5fe350694165d6638331eb24e3b1390c698c4838378c01b2c61a3ebe2c060b98ba6ee02b519b4eac1e0bcc09b2324ccf5b1a7fe8fd0b1545a9427832abb25744eeb36326be64efed3a7b07d630a21c3081b55261c353287c66c57663a99db466a5dee22746b81c750ef85be51143e221ecdf114fef1b3082ff54fd044bc884bfb3cc5c5335997009867ce9491a80fe696825f99426defab6a49badcde403f58e8317966210747b567754de53076b3ecbf65346cb83905832e16d01b50b93d37eb9bfe20172a31630d25f3217d87d93465fd8ac554cbbb39d982ead7219391234c889f0b92a2e0413d866cac087d628ce31c61c6323ecb8e689555af10de2b656e6aea2cde932e241f6d1f8a9e3316cf13f135acef83a0c0cf22f95ca818e61f92768774c630e0925be99dbd32b499c0fe7d84a42e393287f6f5ce3d0b271f170045a6d48eab316fe17b1858b1ffeee90888f3a37a2480dfd04a4a8629f868b5c0a80ee1f03719f3a47d4095bef10e0234fc300e2af482285d78937968319da94beb6c40e078577c024f3a5cda0084e2f855a9396aaa9ee9bfaf2cc771fe68c40b629e8dcf115ef03e757a2ac9eef073f1bdf9c5a4410031558a6d382b5f16024b151b1c01ee7817413a3c4de9dd6478785b81101df5522430058780207e790f612d78e5705ceed46b0ec075e7c1dc073b17b2b43d72535927bfd271e92e3c93638e40a9601dc2c1ab76d91a4103df657d911c829ee8a5f747f7642f5a915a5f40f630b43039c7d4bd2ad2b32129d94e5b2f03ad4a3d45577eb81f369c9e3e2a4f6a8e41acf8283be58425ea993b8e98eea6330556648618dad98fa255620d836d3c7f29b907895849286167c7181e2caf55c2c184a9a911f8e41cb042e2cd48b0544ea79fe2ef381ebc5b15e39a9b5c6d998faeaaa7773cfec084c0bfaed1bcab963a4ef3d94dbb3dfe724c040ce4d1e2ee7fc2da4b25127ce3a5df693fcf5a6ed1
+SIG: ea6582cc23e0460917f782d964e3bb6dcde0aeeac42cc14919d36ce78aa0afd98072f54c795fbfd7a41d99d70606c28a5dcf19be38a0ce2d09bb8f844c31bf00
+
+TST: 843
+SK: 43bff3cdd5307ed7d25cf96fdbba64ab1811c8bb934e2187ea7ffc018d85e0f2
+PK: 00f1b5d3cac6e56ca5f894d4cdbf9bebd968d24d5effa5058b0e20bb0898f6f1
+MSG: 646f8b34182d5e602b51ca7329347c0e198cb747e4da0a6b80f3f6f9f336f6708d85cb429ab2d6bed35d5013129cd100142cddcee8635179021b3e24922b81aef13c1370286939d63d6b6a4195eda1d812ca518204768f87348c6889552c63d1372cde6a5e9daa7f8445ec8d6130a3f5aef0edeace010b6c7f0b9d24162a8d04454b81d48ea9097bd8df093459719ccb54aa10f51c246aa99c580beaf9c9c5bc60faf0ae5cec7f5137f6c5c144df45d12ee995adccf25a9db81b8558bdfb65830186e7b9d4eed9f6b4d732b1b5822d03eb017c0724f48f87baaae1045d6fdb125c9134064faf18dbed58d8fbaceacd4f097df9b342e5c4a5bc85b29597d4b640f1551c5b624ab21b48e94a9030049be1f05aa851d0827eaf8700dfe147fdcdeedbc98c4f15774f0120fb5970a2f8b21794340b628379a802b9f7c068b0df63193e510fc7b2af97ee38de47929785535528d350d88620610cfdb55d249e38fb73c8287113919ce33267d7db924e4919a44e6e29a90dbe3b7b0d3921163feb5ac105624ed852bece3538e99193300c893345699350a8f99e8c6a41095fc9fc08da07f75711f7df034406de14edd8e22a633a86e4a5a5c975ac5d34891cccfc8543771ffa080e0b45d65ab830a361ac4c426294d3685ea8c26039c71c90fc3fb512be9fc94807d76dbdaf8ffaa4fbf9849d68e8a57d30c4a0b9735c23f08ef2e284458467e15d665362cb646fde6937ecba53091264638357a722425bc62d1e30ec5f0dd8fea26b2ea4a8490035de43f274846fb0cf0209ec7437f3c3d0a560373d034e5fd79e25b6424d9b2c1761632b35a12132521827345c55e4e7142dd6fe94d620fe515c153e8395b5d130c744139b6a92efd37f22ba13fe4c095373550e2e4fcba0325b3ea3b9fe25cc7dd92cbf42e15f4554b77ac27a4a346382ff6100451508d602cf643f60b6ca4286356f21a3110d4e2c8a8962a780fcff439b3aa80499df270fc3e6cad8893348872f0f702f9390000c7f6e0627d2bbb7b7cef5c4da25dadfea8032e5023297a70a658e9ae73bddc3b227a1c11741133f012f0f48fe26446fa67e64720fc8dc97f30d0dd026f6dc2164ead857824a0a7aeb20f115d50d1b65dd5d82e09abe834e8ca88957e39984824955a1a13e3b94a00157186dcdc289e34b678c91cb2a1a
+SIG: a6b56b7686df1dc5f4ed544a4d97e67036195a32b22ecd5d31ea1730e6ed8f810d258b44c08ea45f032b937441b72cd0dc37556fd7874e9fe64f15765c521003
+
+TST: 844
+SK: 063b9025e321e972d653a062be34f99365affdcc98ec9ff43ef422be0f804460
+PK: 10d01a63012ac09956ba9ed61df35bb7afe3658bb3004852e47174bd07dd4de7
+MSG: a7eed29652844ee0049bafb2cf63402971020d7e65c10b91ac5726eea86f40dbc53c3f0abedebaf6cc449b4fea48c015fe4d907b3e5505cff50a121819a2e4a8a296d5751015bbcd7ef6fb7c2727bb000be1342a7d14bca97904edfe8b18ddb63933418327a5af817e95bad74eb790203615d082e71493ead47ccc0901a2ca9f50133c44ef8508d51fb73c616f0147532245822dd102b337a1b2aae2efc72dca7a9419d598a6475233dc1a4ee0ec6d05da12a2b287cb77ffafdde2d0acc28199933e6621eec16ab4245170cf02da80d4922631a23272915165ad88722750035d2a0977bc791d14fb3d8cb02bc77f7c71be5242629a4c9a588dfdde9578494d8baa4e68f5194b8002c8e378a0e833b7c1a96981c4fb05e457ff48260b72493cbcb82ae11673d14cee85288f6370bd4bca9251a7e214c3eb79e7bb6fcebb16c9e056f29b6272743efa6fe8bfd25597ce86898ab3059eb0231c73b5305903fd1319bdf49e599d8bbcd74a8b9767308b61563ccbacd38fc50c83ab44ca759dc9b65b2a4b547c5097f220c1c88b2b0a48f65f91fe78b1501278e1e304de58b4c82a5c399981098a1784eb9042501859f2a93f317e41772fd52f972e51b07ed94d314e1d1af4ed82909a0bef671f54b55db7b70da1f718c8e648aedd6da64b05770526f12bc43f68b95548dac50809a687db97d73f06f47ed08831b60a28e982920632058f0e6c90c0187ff44564f81efd8fd93e327bc6d80b490e088b9a10036c80dcdad49d2be074fbba31e06f7180e5ad1c8823d60966a9ce15503ce60dd40e91eef2359d83d70d98401dde7be3c6b07e57d4e47d04217633d8e263ca348f81fbe9a4a62f45d77c843b6b1ad28466d9dafb1b910b348ed87c686cab292d480c191d187b404a9b1d132ba4e293d3ada99172acc121fe66b845b98b160c5823f601c7758fb26caee85701595b2d52caa2f5688aa2bf2f6c4bb637f8e00f49ab6c26bc6ad89e1367fd28e4917d250893a7b32d39660bde8db49f086fb739e56012c36bea0b26cf6d9357940b00d5a4528f9059aaf08669e5f46c995e60f887b5c4ab88ac7442ed01a14c6a42006baf1f343fefe3e4aca843a324e176b2fe7ec7883d1cbd068bc2fc962ffa60244f654c77ac5650817dc084465545a9230a74826b0c50eb85252a886ff2b1afeaf8
+SIG: 85c81d6b0d8578fa58e13ab391001528b46a1d63a0327c7a4a04087fc668758aa65c01d5a150f935674ef307507e6f4c91e1fc3500b26f649beea87d27563704
+
+TST: 845
+SK: 883cc1381757b0fe0455b77bc9cd0dd464d2b4bf0c7a3c0c2dc775fb78aa3732
+PK: 83a8b669ccd01245ce3b818dcb1b588f86535850e6c710c79217fe439824f3fa
+MSG: ffec293d12ea636ca4c4a0a5e2db15342639c476674d2ebdab4aefd4046b5ddb56aeb210c119afdfb8a89128a34f6d77f261edea0772a2f8db140a2640fd8ecadb0b4792169b6b2810aee2c5cd835288bff493bcebeeea28a7a248c36116540fa71736d66b0a475b5fa92c0d46002fca7a1e69d1b59e81a3a6d4f339769daeb20b5f9d75c4c28f692132d28d3c564c09fe3dcca0359c3c63ec377a33f9ee874d8a789d77c96ac05fdf3ab38b2c8274a902ef8bb7f467fc7e073c77b1db5fc8ef966c120c4dae3fb7f5b74abb990166c812a525d123f76ed512125080a1534f3d8bdccc541fc97590287546096fc880bfcfdd00e65c0ebf4a09fd6476ce1b7c8faaa5a1cc2786719a30d8255811184752a88b08ac9f0ff1d6262f2586940afe1fe45e0b563448a55f3030e4c39c1f3f86a733670380eab088e393de09d1f508d2fbcafc649aeae6b8c30e329ec3fd2829be6db0ab8e637ea1095bdc3df3acc23d3cf705a9542c19e59092ec413a4e2bd5ded28cd34ddb3d32949aa487f1c337d6979cf512622dbfb7da1cbb1c7e5abeea7009e2943ffba2252e1d86eca9d6d5c246cd2e134a3e5dad37efef71ce397adafbd9e72b3f9a86ff0f5d812c46225bebd0703bc5cce9c64582008f7e558c40a3b3522096d1aa2b61bc90cd88c6285d942087d8a4665a0e64d3572f74689b4f24ef400d741b57140613471444decc654af0ffb2edfdf9fdd075098190b34cde28dd166872c6086567a68761cef25da40bd4c3d34fddd72ee565b0b937678ee84349d1160f5f0705f895d0f141ce8f51a1e4fd2dc4704b527a4025a939cb2bb78857eb18d78872edc9ee70e60b2a42700a198f4fff6c31925168be077dc23c322abbca97361fecaa3fcb196e656c128f3982fe11e551a4a0885da60d397d0e40d0d897262f1b4b672f78a2d2adfcdd6e1525c26e7195fb9ac606bb1ba4a9890803b4bd84346ae8d8c7196c90aeccb296a4c3eb4efacbfcb62e383b8a494ac723562d0d8c379187a92e3bda6b1569476aed21aed7a056b4a5826744017cc0060b4d55fa8772b5b1c15f5748ad7298005aecbcbd90a3e5c6159a8674abbba37914415002b5a6ef5df3c649426ea1275a01d80adf490ac546062d93999a6dccacb96a0904ad33d90576dc6a21b672e8ffb06613fb3f14e6cbdde88c2437c9
+SIG: c7cfd5c9fe930d15a11ebb34e3431f489da010eb193edbfa6f23d5d14dd8feabd7880d2d5a5600d38546ce3bc64a86291a1ce31f272ff020df8cb6a0fd4d3a0d
+
+TST: 846
+SK: 5e40a7aabbb0830a9ab0fd79690ee0433901c6cb0676abe4bba06f5bbe58fac2
+PK: 4d4f28fe09c4aabfca01ef6ee7fd6372fb62db61aaee827c43fd1a6d1c259032
+MSG: fd4ec8b34fc6b743813f59e2fd1fefa870f5a970e2eb7516ef7c306f4b823ffee92d601f765d79ca146aba8bc6e79844559935cddc242649c059ecf2db84fdc219366688a88fc25b851c3661e51988c2bf73bb8e3dc16d22415ab1a7b35579daac7325e319157d7da5fee87c93a4dfcbafc92fba7e17cc68e3903733c6c801572d907320b2feb51710e856a1f76f85a7ee1a11e62d2e45a352938dd8cfc2bccb902dea444faaae6d84c5f391e10aef76928a45153db6cd25a2bf353d80d97bf4b3808605e89800d29840ea60978d9ec9b2c302749888f9debc84dd1e2a79aa0b6ba02a039193081bdbff0599a14d918c0c8deac4f60b6e99474ab53011741034fe2a20cff4e0f023424c8e5797768ad53df6d01a24011fa90f0bb1d5069cdb36b450f433110c2c56f34a1de4260914cd4696b14a09c0268b2ae2e98e6b4e992b9125f878f1ac09823170628388f0f6e256259ca786bbe144884cb298cc043d02f5c3dc684f787faf16c10fdd8437a8c3097463bdb99b78030f9474fc5c9951dc7526490586fe1c2db05411341460239d5e8bc53065902b95fba282c27665e869a19dae84606d1726675155d38039b9e55db4d5ceec95cd6d87f85e99dde54a04761e6eada6619da895b654fe3845e8a60f3a3b32483d6d27978af54502b220e478db78cff77a9c97fb79fb5acf56289f381acb10de64c3f23842b12bf5f1b283bd25d48d09128fb55ddae255beb7c66a74cf6f0695a4f828cb29e4afdbb3b42a235d4fdb66b963ac8f68e82b00a1c4500863296247178cfdef803bb7b114f0c03276f671669a087d9228a37ae7b99b061549c1cf8ec17246ea1ee03dbc88bf426416d586572ff10a3145606f2784e4357be4edeec6c3a7bf11bb5b0e90cf50edaf891e51d26357bfc853ce23b299155c82c1031dfa64074d72a09d29720ead6ebbbf75d5738e32cda6b6466a8def6b50a1ed9b865a9a88a08018acb501a4de9db54d0522ce9cec7a06bd9a5f86b0b46c07bf3e7f5a426ff6b4bbe1e00313a5ac2719a959ed44ee0a44bd97da6db2cb971bd68334908949ed850fbf73d0e02049da181cce9c2d9ca1b624c8d87cf904eb821dc7959295da5777920660b43ccc25cd389f157f67fa0390feac97a752c1ac204c21df56bb0f4fc01641b480af2b89b5d16d4a0bcb0a50b82b0e0484
+SIG: 597672ab8d3a60de5456fcc9c38253f5f37b80e74a007c9f6db909d27d0ead162789244994f35b80d61be199c417c7ea901b98cc63fe3c50fc3c6338490fa206
+
+TST: 847
+SK: 3a34136a973480d97006dc279358e6606293d8cbc1a44ee55233af2b5264b90c
+PK: e5effd921be8eec530752fccc576ef0d9bcde4b32cc649d3f7954717562860cc
+MSG: 981c8e1090e396951b072ef8497062020897bf7dd7ad505b4d6dc11b3e1dbcb0da249984a140e164fc2e02b31da39846554aa8905bc8b3df8a76bf60eb5ffcf22c97b671227d249071da8ff6bba75b2f7668cec19a89e6475a12463dabf368b3ca2445bb3035cc00fae85b7072fbcf595401755b8051e6097065ae429f18eeb13ffa6dde59df6f3c206bfd9ce1f8a800c8590a4021d160f66d6740a369ae835617538b5890231f13c5667baf510a606bdaa84b8d10ee6015e12a4c1ec0bd0421a294c51cf63b5d1f058e1153dc425d10cee8b1b084d6c29347e96f0f31b839607d078b79a90ca3d1f063807a463b7c32f45a534498d71d47edc3b17a4dff27fedcffab301f34f1a64c0278a53589349a233af30b1ec1ae410f7b1630c7145ca42c9663f512e8a578267dc95e83289c17032e09782e2fe8e16efb87f03ca03b1195614f89961ca3939d3bdf737221a22d7a18ec30fc126d0ca663e88d6060d04c6a44e5616e556e07d6d4a847f1711cf43717810c70aa4be730278b3bd6555c954dc6edb09db08f0e211803596280f3c7868d2342cc2308eaae4da1913514664b1db962e99c8a8cffe57931f5dfcddbc1cbb36ce1c842e2dddeadfd7e7d0a5048cdcb961b14f35f435e73a683c8ce25c816812566fdf817e0d336ae0bd247328512b2a8567632bf20553d9bd6fe157f220ffb0b46ebae89a70459728a57eed1796256f1bd50b6d547ea3e25fa5913d389a22583e915eb49de35a97b5acc521db0d005c29575e16611a755f21a3a5a82a20aa900a707ce36825492c3ca15395f1700b4afab94daa7a02f1453b1f9a6bd36efb204d928ee1f4dcc860f3a859badc006fb305fa123d4c79b23a20e32295d040a7f8f6caca25d83f71c62e3af7836ef76b93a83d3c3b493af141753da19e4cdcba56617271034b4f4f394c7c6b7d79666f3afb692244f061c69a8881d1b52b8849fb534990ac2391909471ebbb728e29cd20f422354c4309717ebff3efd1833370806d5bfb53ca2da316dacb50ab7fb739673235a1dc53aa8893072d5b91c9f6db83fc4ea41d1eef49ac28afc1ced8f361890ab9f779d193082831cb8c42fb2792bee3b26296b6295eb78a8d853117661624e11f7f57afd6085a7b9123679fdaca1cf2a78d380bc4c360aa7c3cbfde0c0091fe53e2219c070f2f02f1483
+SIG: 425f272212835755adcc0522c6f6e05f68008a3be9ba5974e420c4c5cb56e6c55dec0de347b16caef8bd33b71b44c8357d05b6321d7bf493d25861db487bd603
+
+TST: 848
+SK: cf33e7974d8f0bf899ac5b834c7cf96479ce1cfd453af07f970527f36aa85c1f
+PK: 578f60338b1f041a97d319fecfa30cfaed369303cc00b3ec8c5c99041158e20c
+MSG: e813144bd116f6ac36389217b5171a902f06b7dd7b144df4f9091553c7c7835753a296cbb0d7fab99cef77b61f34a04c8af04e7d5d1f961302de89e2005f299f5a4aa17924617d006693937745539c3048ee36b8c23afec0af9feaa0066c8af8e0a7f09093498210f6d8dcc0aaada5668786910ff7c5b348d4ccd6eeeffa3acd1816d9011a4c4025f6c2fd2c020a10593627520d4dd99e07c62d2dbebe84139e1c7d867c093574fa601e4ee307ac926e5d36b62d7ed84a261588b7e2883c7926612b4cc67e2bb72544a10d6b4929c88ef6c47c2625d2f6816bd73c3bae89d2e0c86171ac4bd080ae555d62740d1d2a761ced86dfc328ecc27ee3db6d404108ef4e0b64906253b4c0a771adefedc8a2c5b53c425a70cd6f63956f7a0a619fdfbfd00aa078418eb4652f8bc6f3c253beec9838b77f9cbe2ef2b8055c5773539e356bd8192606ec101e3f6058b1dd08a68fdbc549dfe6b7725dc2549e8e3f90dc5be3ccfb0a38baf9377cb3f6501d2e15ccb3556a895ccb23f0b6df9fe59311cff55374c3fb3a32981ca26ab426f3663d04e3167e53a537b7589a9fb73679090a205532c132906634334a7e8749793f8c593f3fd6278ce0050383487f3b245067af94881aa1ae968d0caeba5fa5c7be5f4e4b7257518695d89bccdec507b967b4fd64b6893b3ee7803c1d36ea8a02fc426f9afc8e9f24321527ec9844bc3c54a0f7667e034300bbb4fb020f6d5bb954e7b5a3a706a4939db33c154892643476a291d47dc1e6f72ce91d136f11db26b9c9ba736e40df0a15c1a89149996b251dd988b39004e6ef41bdc061db580b7b74de2a651810bd891753b97386d7f8cbdbb6ec386fa2c342f5ef20e6e3a8bb4d5149a7d4de1224dff1d172c87570f776d5ef45959be0938ad79f5d3395cb2721627122887bd7a8983b647797bd41d882641c81431ce8d9b3067adec4cde926c51313f0cf84c5292562dd4908642dd245288484c5568a787d0ced36a352f032da4f7e4de06b11473f650eec65dda99639af2d42d84ee230f4f83623d9c9aaa3b16bda10ddaad25af5c1c10f81c8c51c811a3aa3e3db58a7025e4380e285da474a61ba59173ff042a46a79ab184b070108416f9d6158cf96d0e6db447614a0d9089ebb6aee4ef107be4593d71e79f6798668a740ae4bac5ac7594ecbd5dc82e7d0f9cb
+SIG: 97a5b6d268a5b4175fb06f1f37d0a633519296edc30011c954d8f0b9bbe2641800396c4b35d4b0d7d2a1d17cbbebdc55a809462d6cc19a6fadbe1bd1bae88a01
+
+TST: 849
+SK: 51b1ad0ffc21497a33dbdb85ea2bc1ce3d0c2d95d9461a390973fee377fc75f4
+PK: bad0412575d3801301edee6bc0f276e787357b4122f52de981885851884249cb
+MSG: 7882e86ef3402f6dbc65cce8315b39765faa4b1fc876fad5f8220cb22a7df2e3580eab3a7e8fa7fbb6b59482ca0e364a131396df792a3241a060e44143b6767493c6bf75f187a9643aa11e11eba7b0a80f0a68b9f1b79f75b66cc59d9da77955fd7e8799f99d6eb08f90d318f4efcbfe71159b10a83aa5fd69bb75336f5df296ea060a426c9545df940bc1454efc1f9dc965f1f22d947303fb8ec12407fff6b1dbe47e3421c31764fd90c83ac711d19926e229a064c61fe3676af300a1716fabe4e3842264adb32e0d9c9f5d4a65d0d7b5c3770d737ee13cbed21d7a1da36aaf7ec0f36fcc476f659681e5160a5a1f49e759b9d0fcd4fdb854eccd99172a47d2c4efbe0b3757631df1bae175f0fa74dd048bb6a5fed8430284349da3d67df2a6f7e8269bc79fb2c5d5ed6084e9076f455ab638919046369a446d57fcada7011cc771bf6d874a8e5d23c687747de41dd04bffc717d6128183846eb594b3cb1c1a8aa04f0d7eba53af39cb1d4e6fecf3113bd8422416f4c44037aeee9e0fdc517c48731fd04ee9c99f5dbca3d574509d7baf3288f2c230a02d1703bdb1611cde2a766dac193de167443d20090dc34d29277a86b1e998b245645117e5111f12f14606c55446dd912d3475c19876e19ac536d317876c4b0a2e0f98616129a5683732a42317c5e809dca956b2abb484ada810a15c81cc8562b555da9458f9b44338490230c7404f3d48611f84127e73e277d88c62212d2a3a351fc67665b18d77216230632cbc781288e15cebf3ec33a7205eb22b9abe4cdbc7ddbaaa53640875eb763f522c36cfff2eb23ee586d775286259fa94a44fa7ec015096a2a446b6732b80024267fe3d5d39d1c48509b3ecaa2e24e54de4d61c097b70f753b5af9a6db6f975d25f4f83d06f879e17ef7c509a541444ba3eb6867838090e22dafdbb0eb3b0565be1579ceecded20f544256c7c4ede3b62843c65b0466be6b7e27305b963ca914e3b7d21736118edb3d658d9d76f509db3b9ca2eae28964a4b3b3c384a81a4890ee96fbe934a6f2aec8eeb6cfe59ac9d3bbc1646ba32a1142fee59fed6fb7bbc0498cc27dead413b7b4351ec206343c0ab89fcf87243b1ab450e58ff11a1140a383f196aa3976ce17cf34530f049a1de90e31753cd85e7f1fd5cf20426c9379feb8c31b4bfec35ea5a78953d75c5cf
+SIG: cfb65b6ff0377cef511fd97b90c3ecb80833f142a7cf5022ced30b3fb7862086d01339b8866a238cb070276e1944b5fe32cc409947cb91deb1432c291b60fb0d
+
+TST: 850
+SK: fa2f461ce8c7126218c47c91569e8799797c83368fc842b6e1c22fd52aec70bf
+PK: 6b89b23f1e11a75a53f992f6ca5775008c6e9e7e49c0d8510b0e8369b7a20bcc
+MSG: 799b39802a1827e45c4112fee026034c0e598affce2c550c193fee73f1df8c30c8d3873340088ce859de3471e9d057686c829b5408795e08b3dc7aa3b637c7de9d2172ad0333c1bea861a6232f47f05a10bf5df80815a271256e37e808a0e62f1f07d9e10ebb947d3efabf8a28fa9dccd9a1d599f5fd6165508efd679cf356015058bf4b34118f83aa3e5bc2ce19eca84f718398adbc0a5276cf9d8caffc27e3e6abbe345b0e9ecf89c6771b0e75d408ba2fbb90fcfd70c53f2e4d52ba54d9784cf71c349ef6f14ae4970def6efb5f30e984d6016a196deaec7e04b47619c48bf49dc02f7fef3e13b756174e90d05fcbdd5e13f0e434efd5421b091d517900ed0d5785968862b4bfe5093ab67217180d97554ccd9cc31429326cab42f3f8398060c19db488b5d1c80b29090afd1c6bac3642264800211bc278fcb99dae9dbf49daf1b24ab569dcbb87d4d3547335e35db98400cdfce6790682e93600220ec499245fa4ee15d843831b56cc26418025bf87001605c6691ca6bd40a4e248c309801b76a795ede8ad5308bcb6d1754ab3371f0003bb8c4e4e471954e28b1e9866379f82e1fbacb79d50adddad5b9778b558cddbb0038a5ff3d5c9557b965de3a7082c45a8ecf3e7721eb690b6c71f3d8975d5300f67c4dc4a736846e4ccd26f93463d5bc6f46edc488664be9696be12b02dd104d10cc6b1d82e8117811214a6487d17367e395ade2ef6b26a1783a7e2f245213bc03a755df3ee8ef9f1eff972c6919065cb7b756678d4ddfd193eddc0b42e8689613643146d7428ca37bf31bdf14e31867858f39d2323709eb3b7d7f4e397022378424bdee9bcb74e9d5dfd371f4734998fc18df4cdfb4b5c21c2e50f8d6c15bc14bf4fda6ceb9d8082cae432dfc98bfb3ecd16b8d74f830b642b042875e921b054bd1aaa581f60d718df669f56dc2f10d478997722162e83940e61a1b6e42df2a4a3a7cbcdd611ce96cbcfb5a95cc473231ca13c0609d0ce1ae5ddb5466d6d65eefad9daf2a36901bcc945847da1ed6e2e240e848b231b7d0e1acd06543ec93e768e59985d7e96c8c31fcd1210f0964271e21877525cb134bc3536257dbb11d30a3c4f949fb82ae0c31ccdfe41943251e50aa4355392ac309ef60fc17432a2be4bdb2fcb28607cc45a52b60016bb1d2e23972ff2c2a247d725585b1ef2b15f
+SIG: 84f79d9e8f30e5bb6362239714556b04736fa44465cabaad23beaf5a99fc451ad4ae5a18c7f6f964fa41039216018ec5a2accae1075a6bb3a6ecbc1fca02b904
+
+TST: 851
+SK: 1be2949d51e7208175826213ee6ae3c091172742e88caa02ed0f313ecbe5d910
+PK: d7bf4748d6dded5b57a2abf797facc560b48563dfd9dcff4be522c717a6cfda9
+MSG: 045e2b0ec7bb203a49bdcba941e2b73c23c1fe59a17d21a0124ea24b337f92ab9c923a20576b62d5d0f624e7932c115b5474e0a46a4dc9ec51f6a0ce8d54744d1d52093320e39be203f74a0f5dfac52cf0f995c66df2914b68ad871fbe81525ad2d88ac69933a75aea74ace4e36343ddc06d3208f16d805f5dd786b4daaa166748cfeec5714c85c10478b597ac7f6ae2c98891e38fd414aa811b7621d805eb8fcc46cf4d568a8a92587cbbc1aecc12f10d90ac1e01ae986d14fe82951c682ceac8c925fc6654d838ac9353ae2f93f3c88bf7b82cbc43b1e49e5cebfb1949ade4b22e4bcf1b400c0a8fa8a6fe7670f69fc3faecd4805b8c954c01a540d1a1e788436eae073ae956dae3176905a8f0a3c60fd980dab419d41ec06e5273fbb13db9381f89b663ccc4bd753fd90f14a77b3d81c45dd3561cd1fa0e94d234cef9d7859a2ec942bfc18849d7f2ada3a5d657bc193d2e1491682f1665a534b1ac2083b738be8f9e963f5941ed483c6acc82e959b81b8af02f471c08f5f8b12e10e008192898a4450202af731592e74efe2a948e51d06e44de9b956b7bc9a69b6e74687ab206dec4d35b3173fbc438829d5064bfbcf743c1e2d46f628f2e51c626d8e416d7be6e555a249691abb167f1d92f4fa3392fde24e993ce7ff5c1b8e1577a7c0e73025cc6fcd727a82ef0c129e91e5533e021a3cdbb99d54bf7cdcd3ff119154f3fad9242b6ed350d10372c976ff3a437d097867d9bfba91d84bda55a6bcd6e3641b213a218b3041589c55afbb344de6e97d8c35b5c86cf3be063f901ffeea8cc91069967d2346035a91eb5706a3b53f6d1c34d4d2116706b65c298ec57de82abc4003ce8cc5e0b88ff710dda1dcef6f154277106b83eb46c045b082d113b361d6a625808c9130584dfc96707ef8955907baa61cf88c66b6d1f60581119cb6217a852157336178c685e6ed48526ed5c4e3b7967d51f99df6876a1acfb845c571b898656e5e3bc73980b9bed1198866359c9e9b1efa915f810d1ef8ad6cb3fc21fbfe654306de6ca13a3a6a48e7a13ed8746acbd07f48eb00c36374b1eb4f3f01c19e2e8d37e9fc064b33c0d669bba554ddc6821a77b4089cabdcafc97f60e6050bca444ae8cfc44d93c40ef5318bee6f8cf0c067b85cdddc45974a4eacfc3ef51315ba0f3f62968c7003a7ff444612400b159
+SIG: f41f2ef6595f17660bb2fe93e51fc6fa9c31dadc9db90c3f46607a7fb4800bb75ad96325dc7eab782472b04da6d8e6fe64655dea551fbd5049e876ce5a405f02
+
+TST: 852
+SK: 3b6ba6d5cc9cd6241d8b0097a3722e4d066fea3d560aeab4673e86f1f8ec6026
+PK: 8ca6520717cf363c4ceffa76328a0a166ff83e45ca7d191cc8ef6ca6e5243367
+MSG: 36de930cc8e18860836a0c829d89e963a58bdd9c6b6ef5bc61f75992d2075242dca23e28de205a33dfea861fc44a32628e8e7cdd3ed7ff49ea6a7097e0090cfd9ff5ecab1de822fc0a4c3776dd56c1919204516a94cec5638da1d99e52b866f5ec4162a912edb41c1e92edfc353f6705e1c12cd41cb62ded4ad8157940059bfcf50719d3f2ad00848540ce89f3f9afa610ccba5ecc37e3e2c1534fcb38fcd39a2d14d5b5da6fea24e006654e309047a29cad0ae4da8e708f97a18cad5fbdc9ac84400c532ced548886539edd6c541074790ae4502fdfe9f3273a876a218623a25706a1525e67e57a16d22c21b6a45e2384e287ac4452aec4e063056b4c178ab0e5b2a5bad3f463c472c4ea1f9c1a66e5270473a835094e8f0eef680cd7b20d0e70f4d6c958fee08a9360aa6066888f4dd7ce5ec22259fa0b53fe9271c083c6fcdb7283b09061088c52f71bfdd2777ce0801f41a6c4ce90ef131de1e183cb8949ce323c9eb13a4b0cacf99defdfdb68d5ed1f6891b48e21047668d69de8a80f8e5634ded08736a4fb5410cdea9c72596e36df6841f2eea46850c87473c895540205b0921960ffa5d9d8ffb8e29cde96a3ede015acbc26974004d3e438a85b2e3385f64d1814003941ffd363992d3940c6e6d81ff8e45fced6d36ce198d8ccbefee432a77d8fcadd73fb799f6bafefb51a2da798721c3d465b163ef13e6ecc65e603b2893ee4cc9e1c6d1de7a65cab5cbdf536855e288c3ccda8d2fa3ce10cf49358a2ef4ef076e5bfa91bbcf3d966dfa3dc6e712f1956d4e58aa36e712dd3347169b19c8d44bec5bcb730778fcccc589ed5d350d44c17bde2eebb6f5ec59fb240d67d81aea9267f34f15eee2de3f4fa67391479bdbb430f484370fb0e0895b9ae065bbdd43e230c62ac07184e8b06b24b8b97ec02dc6f37ef61641ed56e3f5eb8d2080b5144ef760b518752e19754792e19343a3855e1e2f7a7dc623517eed2f5d26548a68eb8ffd7bf70f78fd186db634928bb98138f2b8fe84481cc53f5aa35e2666c6325e1d2b8ac5e2df2935b7f6413952d10d6076ffc75bb6af63b29b0b9663bec37247b66b508dde41f2f11b84333559dfac73f761bcda84a48d266073aef1638460849e7a17206a25f6800770b914cc026baf9e3255914e13258441cef35ad1d66833e987ebe4431e6a6bb222cbb65af
+SIG: 788c9f4554ddba5c7d64ba759ec45694ec79fb85e82368a074bdd8df344213a56dd09f334cd9acb941be283d98c4b15dcfecd14e93f6a2e3cb0c1aa2dee7d90b
+
+TST: 853
+SK: dd9987b18f9a922c0f6fea18eb00b896c7a2d3093db3ea31d38421da0de51231
+PK: 573921a955feb6dde41b055c8dacaccd1db7fe9e36b509d3c9e36f9735752324
+MSG: 48162fdc3abf7319c6caab60cb8d0520875cb4ee8a07092783167d4733ffe5204e5febe7d291e9536bdea3df0637159a653e09fd99af661d8300ae741a3e91a8bd85ead05dc7d9e6f929323316edc4ca624ea7818b25bdc061f71492fd22d465ab226fd9a10d8babfc074c686c436c24a3a53f8ff389ce9ca1dbc8907445889241f8fda3a7a3f5024fa8cb0d044bdaf6716d983a6d839814ffe70ddc55bbba11ac97887bdb4dada96565bb075d5fc1d3c5244b9fff77de58729a059a911fb3e0eb164fb8429e265685d14a63233046d20ecf289c55723169a9d63dda0d5255153d9ef4a61b9212f4b820697ae7c308cfab403b2c3431906226e45ce21920df5201609daf830f28ad796005a9bd8eba620cf839c3ba227b963c7bd0914822df2ca03c2254d0cb8acae0d59e4c3e0ec215c836969dcd1d49bfe197e2f3eea3fa8a373b558d0fb9063cf1568e739aad8f09fb437cafb5a272375f436064eee11bd903d3aaeab4e3fdcd36bd2076eea179a4f0d4fbc8df42bf2660f08de7d5c6397cae10b7277458aa6cfa01e8a6737eb126227856646691681c106a157a26aed21b1aaf0ed2766421cfc3d1c7ddfb72fcdf4b8b490fc09ace49aedd7712b21ac56f8601f625563c784306f3b9174addf764e051aadfe12831af9669e62cab121c74df343724429d6c26660271c32f40cf7c2d08bd0afcc728def4135d4eb55b6a3e7629d806864a85b36a32b9b21ac0d39680a2ae4ec4189709178e349497f39399fbc78b3c6cfaca6edea7c33dda3cc11e4384f1583d6cfc6b58f4eaa2bc56aba42f738a429b93580850dee3fd253994f8b0fa66ee8e273decabd532095fb04a4a3c340af0e55b57efab43630fc02ef20b425ca2187e3c6c5e10f12d618fd243a224f6501ebeb9d321c6385b8127ef9cdcd097ce7fa021cf40d21c39912343f67acce1825e3a51b8a718e8c340622fff65fe0053d24aa3351b6a2400185d7aeb88e87ac4a1d394909d49414aefc22ba009aff6962c9217d755694e4d6aa8a5d6a803cebb15de8f541634b6fceb0cac79dda8a18eefbb537e70ffe9aa5a6a6aaf9240fac2eacbfbef01ad6bdf50758780f86a4e488985362d5825011f5e8b66425a616b7e104eb23fe8f100cb0249823662bda3da47a4c3c1ca2f914b25b9738534026047df6d7ff631df2c4131f680e13743c9ccf2
+SIG: 3e9f2b007c0e29ec875995a6309b973deb8baf113ded13f1e0003e9b9bf93916a4dfe47937dadfc78aa663c55f674ec35c3846258f18e7bb93fbba3e826a1f0d
+
+TST: 854
+SK: 38d2ef509f93051f145167737c22e1a5bfe8f4a91eba0bb87c39ce04a89baec6
+PK: 01115f6d89a5daab54f892bb4a4bda1ce5d8f6c9c88a50cee83bd987a2c0ddf7
+MSG: 427b5a01e8597f04fd422f0a662d0be2dfa853ed5f9d3f60ff90f2c5ee08bb59fd03d402b754caf54d0058f5a2cf87af4fef2177d59e18226293fd2af376bc987bf7b320b9d1e249ab9efb75078e6d3df29e03504776354344aa69e72e1ebc52a3c38a4c2a1673b4e974a2e4e12a2e78ea3e3fe50c53630d096da3e2fe8299f71a1b441b4cf0caeb937afa4a0e3915ccab3996c9f6a8f4fd37543e8f75900cfd47175370efb852a5f69d673683f998fdcff85ff8f32baa807066604422027d51a435ddf988ed2fd8eb191f10b46807420008756eb4e300c4099c2d6450bcc6a4e7d0673156b837f0506338f3d1b5734b166ca5cc2f24a4ef026cda2c4ae3105b63ca8570d18546cfacb86042966a00ef52c7299019f68a2df08c8b704e85e713c348d7f1677660e18ebab59bf4e12e6ff2d783d8d5d42aab6ef017b7a1966aee8dc14ddabed49b4b643df4e9b0b60383c7d8b4b88c65a898c1c77d43d6bd68b2a5743f1fedd654dc84496da02ceb69b9b4d3a8e00ccd72e7c75fc50a8dd087e183e6c1f579baebc5c63f2807936791b5fe4847cdcf151774235205cd2d7b8bf4ae8819225ea708b7baac66998f0cbab2c7ddf251f3b1de1017d397692205eea639f12d77beef6c13bb12100ff8906470bc7b21298053be1a61b7b3a499edc310996c8bc0871907ca468e89ed311adca2e2b82930975b3efbbfc03cddf4d948c4765e8c10590882169acddb8f8c36d84c2dac3b798e7abf844712fa458d277c24e814047d742319a834dd9f927a2b4485ef13745f7a60dd6bb337936304c97d3f9f144eb29bb695b8dc31b9d84910611d28d581caa9365d6dff52d410a4ad52bd121729fff52888f4daae1707f6f56dac61ffb9961cda7176af4460a6d5542a20446fb5147fce727204cec6899b9a3d4ff6226bb8a1c78e36fcdd9e50c040d72d0f4007d3fa9aa767e4abd0add62fdbccdeff6721eb259e00a721632006bede0d173d38344dea44f96b67d9a2eea1d2af5f748e8ebdb441bfb4e58e2d42fec740566acf73a303358f7d89c8158cf21fe85b0d4a417ebdc86d0469f6b91c24ad610d486dedc218b2ce7a8b96754723151f0d0076fff9f19d112d9c0592fb8d92c99dcb8ddfaa46fbe0d92df46b8c00ca4345adb69a5aca694a86cf30646451bb17ba6e607a912bf109d5fc2d3e27d00d945600a8a57c
+SIG: dec46253509b11e4b52a6ae4f366b680dffc280d0a044fc0cb790b6e751381461e1e602a89e3b3d3064c407f602f1c22404b6823bd2467549314a00001664a08
+
+TST: 855
+SK: 43bfb3dbe4d9bdaa82b354dd596334e660d76fc0b2eb698993aef3767f1c7c7f
+PK: d00aeceff0ceb832c251d1fe6bcbeaeacbb4113f5281baba4e878f7b95f93f07
+MSG: 3f3eeddcaef4e1662adb66bb1b207d793fcbef815005e82643ed70c9855403dac28b520727a901a532d28b9bd1348db2f8967bbb8c9098b07f570a2eae1ee482640c0b67a52a38612133a15e258ede38cda878ff36ed321dff87cc6a01383ba84067d60af41776acf80a8a4eac77f7d87c37a704a3e2aca1e8815e49fbcab797c856529538be07d51696321f69b09b5dc5a15e5f0e4c22d22837f62ee4c8bc7f25a9487b962cc20f133fcb870ed125cca585d181bd39f9dfa661f19be76da7f65f22fbbc80752aeb39e8d59ed96e14f595d04929402b5029c60cee37c0217bc531d80db341dace3cce76e643aac53887473edc6e19cb39fecf6af424a2066393d1c33fc7b93676d7e6105b9bfc967d1e29afdc4cf15bcafa09c295a6f9deee331ab3b0d493126e2b2fffb42a6b68e79e138db550827262e487a83f37f01dd7922be75e92fcf5d9d4803b3ac2f35da210fb38b263b0ffb6c2708d4b55b757af52077a7e3184d01e82f64d32cce4fdee0f8d4e364bcfb958ebbfdbb622b38b51e930271c7b1b70aa9d4bb3aa4b997c52144d3aa62162573a3a1d9ce46cdbeeb8449f1225c449631e8897521cd0f637b721a1252b8a10ab0be870afbcd89d58b2ebb63211950cad7ab82c8195026b50ea8b77b9e90ed559af4484308851a3a156716853a8ac4ecb8c5cc7d935b0f466124143b1177f05d08b97d1ad542ed2c2465af185e7db42b69cb802a71794a3139883029670c956742aaad7907a71d95985fc1d45b65997b4ec6ce8255de959270afa7de90f2929de63f9b17211d7f1ae820ada9ce3e48649179d60b0149493481f01d459db7dad0526b5bd9f4b3380d25ba2c502ba8fa3c4d4131b4662addefb41827f759fa71d447d5f029245f48c622eb7c68c8e71081f7f789de7a283d2eda83a7d1722a05fb72e1760c24040c4d834def5df5f742e02b30451c893bcf7d771db784cbbdaec876d8ac86743b529a292007ac753c99a5799cc324fe5ebb5448ab554b10d4136974a12542d25c6147c67c5d2336c9db75cba2fd608cd43ab95beacd043a1349cefa828e23b5f0b6e0e2951f3353bb92bfd1f0a49c33fb3cf3799a0b543198ad5d03d263c1a06c35a26ade1518491c8c1d27a2db033808932cd1c47b5a126985acb8d888360eeccfeb3bf51b0d189b4190440404d12fba65d0a7a14c620c555f822
+SIG: a9995523020a0d222bc48f98d05504e3068f304a6d197006cc9c035eeade099e7aa97e90894ead17e8c30b0aa4a98088f038b92244c4b20fde964f8534e8fb03
+
+TST: 856
+SK: 514e070b0190d18cbe981a5a151e7753398a272bcf014813ad379722c36e133d
+PK: 6fbde0474cc4810effa50a07820c965aa00395ff3a5b3e2edd7d356b7d6aef2b
+MSG: 831455762a5d80097bb2845042f4c876e7108535bed683e8c44619d08154a229444b101e3ed7c01507e870941446af978c0f5341d1ac1dd15b14e8966712df19f52feb5103cf62b6632756446cc754df00a3f6dd719968a2cef66c3adfb7d1fc491fbbf3d59294ab34619e176db0d446151e37eaa3daf172406e983d9d23a6b69e92976030f5ac7040ad5114129feaf97af15b2296fae70492dbbeb2b4827687fb798715c9bb2c32557a81d891b897052900707159751f07db074c77f0719671f1766689029a3cddf39df3483cf2b04f71c25de05fc2d02bb48e539eaf1a321646cd80ef2f0ac703f45e7389530800e5d417ccea8a5c086682f04745d50b5dfc8f6edc87a95c7d202a9cfd998714b746920ebbe2335bca1a0171762016f5e4bda89c57d0edc6910c6d22c8f909da3db1352f0c8bd18f3b5aac25f193b89470f976bc4f1affb3c66bc5876c6fe2ac7508533d97bbcf77119d9aae193f07e0b64b461c9c6c3b9d293bd37de3d8e1ab1e8d872cd94e6cf0eb68439fdcd3b25ce8483460bd8b7cce889fb722b4361e118da983ef4a9e45cebc0c1b8229ea53e6f55505f644e09acaa4c4b8cc640b2cd2b312e1c3a2c02669e1f9c06311c78d360009db9e67c39b49d1e5d770c01d284b0a17a41b4e7ca745d665ec07500e4d9fc8ebc1cc6af53a3fc76b0c3f1431d49843f20e182782c82b3b5aae36fe20ca642618068be233d4b5ef9eaeff401536dc593a2bc18344f55ac5d5fc7b3eb506d11cb375330063c620c5334d723c7d1f042816bc4785b35ac0e6f174f736878b7b491658ca67d8fcab538fc6ecd277ead90d954b460da4253a1c3a30b3d8928f69ac9876a2891969fc2d06a668992b8e2115dfe5358a7124ba7ccf421d8054ea043444cdeb40b716dc7a3659a3ca94347293489060e2cf6712a2a6c7b8ad146785fc40ccb9da287830d011d0d24df3e7afbe972d6f417de5cd75f259ea07cafdde205fc0a365135c232cbd7c1bc539fa4b7e1cce35185237c23f80ae97c186d0d3b10503d5984a20ec41c3cd042c28a4c31f9574b06a872bf959ab0add1f5dee14a1e741ef238dfcdec085aa088dcf39a36dda8f2a85ed0d362ccb005d02e5accc092a376dc11a566170d583db35f1de0be3f15908596e9b781ac81be07b9bd2af46c56fb4d9d84276011e4618b7f76f96794cd0fd57ed414b63
+SIG: b6c355c958b5baa7ebe977a93fcf539589a366d40160e4e031b88ab96402c7bd577ff635fc07782423598dca43668124a8b287510e2cfd07a1e8f619f6c8540a
+
+TST: 857
+SK: bc790a7385dd1dddc762e3b20221dc078b6c3da8986d4180940727257cfdcdf1
+PK: c9264626f68fedb5b39c28f030453b54d0d51a98b17721f2611d7f277ef48b81
+MSG: 143dd7bfbff2adc71f5d123d474ea069df14ae923ed9bf8f9891e60bae43f0c9f55537ac9d1ae523ce4ecfd33b20ae445e9c426372050fa5217c1e4fb01353ebf2e32904ef7eefcf72e8023bae06bbb640cf777d5b0e11527bc835493ad6980a157bb2d50be23365e72cbf0b3f209ef0c44a00b41a62262488096cae5a696b4d64cbad34500d41fb4e4bc70f8bf62144d01c2275d6d29f5de75b1721d5046b6829164443ebfd9c1781319d88f54010edc296abbed02b7dad9ba585b552e0005dcca400bf4f459eed7db86ea8612be9e918dfd4e2700c4710083283626fac754417e0087d26ba145dfc45b1c9bf7b4dd70e6c508747ef805c9a02425aebc6421e0deb6a79d89aceeee01ececc9f3ca365383826584c430ebd39ecf0a72866ae0aceca5ad4f0405b67779c04c5de0330614da3470b805d787ce79ac5a696dd6f6b5539b1a651b424cefb19491da6e0889223cc98398b42c00414ff8d6c0627eb97cff20a8cbe7fccb41d810fcfe858ca7475247ef628e84a09d012fe12235b38c1cc9d82e2b69d01d6218cfd48e85f26aeadd195408cdd4c2f806a89041fd0317fb1a7b6209f904270d34e606195047288b0fb11a5722938f67c22b313f7f74b2025c75bcd1ecc5a9add4a640a41f2996eb66e5af196198db58a3fb9938f349f922a24d86f4ed8a96a09a196c24d6d01ed76f3816c05c4f26baca9b9d6dcc79b580dfb75d6c905d480dad76951854bda1caa7f4a819543aed01ae956bf3058fe8b3c7d5d724962f1a6a83143ddad274fda3ad578e98aa967c410ee57575ef01c0258560f0a1fa4b79327796de99420cfd0a415506360f1242ccc58a6880927750dbbff13d7c1b4ed519cda357210f12fb0d1c4d48f0411bd7e058cc4cb93d3c77597e2653ffa282d3c2f128ac33a237af2fcbc9ef9c811f37814ba2b0b85093d0fd18b8c6fb09a43ce52254d23d55f32e1d3242aed1f23d9cf204aa0dfd44a346fe09e55a4a06cf1bef8bbf37ba1f1598a58aef89501ecbac0453543e480ed0adde90c841d95ebd6eb23baa9f70f83c149eab32d0913c79b0993d0e1d3574f0f542e56a20616cfe4a8bd7aaeebe0b083dc2ce0146178c07482a01129bc6fefdc8141c1384894b69cbe2f29da188f7fd4ac341a2df6fd90dee6a446d2746324c75c1ef5b1ace187d3bc16d70559892975d7e47138f0406385ea
+SIG: 6d6bd65f372679fe9d945ff56516333ece0b7a25b15ad2487381670e536f5246775eb39a114db2b9cd50f312b360d9d0bea295dc37b817b332890adb65e4c401
+
+TST: 858
+SK: db3a44df40d255a25cf23f53c45223b7d8f1f1f111ba07406b71e184a8cd0612
+PK: 6b12bd9580ae207a9b0baa8287b8bb86669373ee5e5a625ab4a6ef2d08712597
+MSG: 52dd8ba4fffa344d1e0811d9675c313f9cc0e5a138478691989d2b7f7389025068fa35f74f9aeaf1e95665ecf8d5707f75f65f2256eea93398be59c0d538f5e8584bfbb3a240f5016d7927234cb3eac35b391b8b53f20ed8bae0ba11089694bfeade11071656d4cf18ef2d368192e04e08e3024fc1d2fda6312afca68d10c9c336a0e36850be1a4f35b033a85a2a9549f2673a995f2a9ab4bd46c8fd2d838e64f761713427329c9af5e4211a22ab208aaab80e194cd0f6a502b308fed6c583517801a48ed4330e2faddcd41809c3919b30e84db3c68731031e79857dd9f97ffd12547da7066798074151ec88a5fa963b9d9d83ba2fee135833950ef7bc62b3401ea11bb36f25561bc0522bb02d8dad0543f63d547be77d0a4c9bf65d42f3a276144d2e474e2942f3790221e26fbae7ca91efd85921990835fafb6dc674635c9601821038b52711343d1aa25f1c46ba4e3c6e712bac19e53eae30e5246e4f04ddf2acdbb34163c243677690be0bf2e3fa164870b5e6f536b22fb89e5e8e1d87cdb34044977ed2836e544d7ba493dd42a2b649bcf313c5b39a1dbfff3e7f2a59ade87d3e7b258f58e565fdba3e4d92b1edb8bff54dc49d86c53c030cf58b97ef066d241b540530213905739d8e1aa72ed90f685d3958eaa242b0cbf7a2eb976ee96a63e66786464169a742d457e4d9117c7d66428445a46930c28ba7a2658241805ebe72c78e02035d263a211e590b490cdb84415062eed14f13b8a1a9e77c8d7b75515b18fb85386e4a7e053980d30f4899e83863bee875585887c5f48b516ccb731c4bcaa3df07d04795814096c79d7c5fdc4dabf5e26a4ca1838e0e5d87db71309b81ea7ce461e5e44c7ab2f105ad75c543c1e9179c36a5fa555ec922ffed1b76d25801dd74f80cd0a6ba7bc20db0ad580b7bbb9ddcfd93ad1c5f20f3e27c3ea3a1e71eb74ff5f944cd3b98f6d04529593011c4aecef6dcaa60fb18368cb12b6e391b3f5df765cbabff15898c84796fc2b53fa4900dad034a13b0ce1445adda4ef719be741419e231e92f1f667a32842a42db79bd7a014a809c81596e826273d16fe5d40458242ae10e12e60b3489530c6622b5bb44454f29616e47e9a297ce1ca074137fd9ae13e3ee8edbcf78af265459db1af342dc0b2fc809bda015b5a82b2b7c54efe4e5fc252eb13d66e808936f1910f4c48be0ef7a
+SIG: cc28b5ef4b9773637fae7e5f084b6994aa3598f8f4a65d0bb201d172d861a30149b3338d3c3ab75b32b25595cd8b289630c3376acd10ba2ab26bc1aba900840e
+
+TST: 859
+SK: 77964dad52b579b8966753da3186d1c5e9d33d33a4db38bc0d7a1a6c112c13c2
+PK: fc25125e7829f64234375e52ae9f77ae1013f99df5f9965ad2aa16589596d091
+MSG: c339e718a757f3f3bd1babdd2e00aaa5cd7fc9005ee34b6fdc09d71fbd9c9289ab1dd14dba2cad58cb805116777bd80c85966433ad46f9ca6e54f13dd3ca7e56e47fea41e5488a45ad53bc5d657427e1d7938f5519f1b09f5bdd98aae5ac9643ef78eba4934925339a155dc66828571002097a11a5cee7b51a441b756b0ce65b779afe19da6a18efc145f6090ce770de9e0e91f543270a0985eab475293ccfdd3141c4142e4722233b267499447641235d728bd75cd1adc0db142f7331adddf8c5eea3d576405d869915b560f964e3e0003c91f5e96bffbeeec73e51024ef52c55c6dcb54d58203e62f4ddb6e137eb08e1bf1326018afd1a86cab6c841e0661ce0a1a7ae967f24c1a77fc7ca505f72e5f7936e39c6f4837e2595195a69cd676510a7161a4dc5e318f3d4f3ac0af03f8c4ae5bce39324e9738aea49f002d32d16de2317e95a9f32ee604e13db8038b264cfc17aed29c9debf8191de9e0efc951ad6d54867068cf50a269c37a241f85206788d23143177f659cca66cfce03bc0502255337f16b3dad6f79132abf80ff12b6d2281e637eb6c71f76e2633a114565240eed00fabea9ed8de28c83221f8cb485f512d9008bfc74a366d4c2b4ed172d367e0247cb65098c110282e831df8e9bd4fbd5f4dd2b7f2420c23b85a637aa2262c3cb88405f70730c9ab4c9d0f227ee4fa4ef91efe9a59b3e6d843db879f5650059e99f0e4a0386838e6f9876f67d50f89832dda5f30a9cbfd710134f9b5b54627496aa3a43212b07f03db11d3d4f875d41d1f4ac45969ddef69f81a06d2b0c646c9cd931cf2502fef0dd32abbf0951ed303f5284825934397fc22e78698d35ad81d82256bf9e15400a1091623a9826f1e57792367417ef02586d64e650da9ace2f18aa0a126d867cac4b5d4c91bf5209e5359556386f827083eb53e8b4709fffabe92c61d78ffb5daf10274e242a70091f3f9b9d596c1258c9a63384f4b05b028661222181c0fca965f0a2cb56e4b556d6fbff71b64d9b358da31aa37c74ff5962fb8d96a383d049724c19e249c9edbb2a375b23ce3104da0ec58d2635ba03b55423fa2db7eb349a4fc58a1ef540ee9a02c2e703c68d7f8475f434ddd3200db1f06745791a3acc3160dba50a393447ffeef6dc7b98fb06684cc90fd85203d119dcd8199e4d9a89ae3467ae4bb19fb71cf747029c24096f9a50e
+SIG: 3d1b4b4e820d250be2a8fa971e599e1e98977528b2f930189681a93b05e1a706fc80effa94e929bc43921656897388288a9b29271f37a14be014b873c68fc904
+
+TST: 860
+SK: 5cafd817a4410ccb27121723ef3207c1731a0861945be962714c0ed95038a195
+PK: 4ea086be43ece1c32d08059bbadc9e9a2b2f4f3fe370f1f5ccd7dbdec0aaf303
+MSG: 50b2f05342418046d16a30be4fc62b67daf6c18d2a74242b7cb55ba90ad20b6cafdd60155737c29de48aa5d799fe5495fe59df5a9b8c0a8e5418904763fbad83ea6986651bac31117939cef4e0c79930d52dfd7db43c31addae3cf93e3efc5a916efd0d65fdc30909fa356ccbc5247d7aaa067131b6b4820fd02f8e395f5a9704c9bdd7560a611d62559a8dfe1d2859c52486cc11ed3331992488f417520d920dc73a32d4f08110082500f5a962a306932c6a7802955cedad7abf53b0f19fe4794a31d6b855380284306ccff71a4007859a2328bb19024c43e10d77064d866d9622d142c27354b84ac3b4f8232f7a2f8af6409d5cc757a18ef813dfaf4b9bc040cb006d77f143641aa2036ac7bc928dc96585d9e36c7bc9c564d25f1c2cc0beab9d5f207e84b215f1e7aa6fc328237b79c39923a4e09c7c73dc6b24b1416294d798a4ed5f758336d915a870a7d6b7592b5b88aace2dc5f267bdb491141cbbae2a677407cc0955f961962599304ba0b839671a5c000e920108a05298087e49770aeeeaab3632724cb0fc2285796dc414814fda78a54e67f00a02f77d3ccde1ed9d7b1def14ea1f61910bdf30a1196fc6351b62254d6445e6c90445b16efafe289a2784b92e42b78a4a900c35f55630bbb7762ff9eb7fef7d04c90b9571c4fc760a410dbfc252991d0ba27f2d414fe64eefdff4abc18817c9706c631bfa203821d3b92cb338baaf5d1232b462647954d0902462fb1696e991f07fa9c3dbcf2872960831b4ded92a421cf21b753165ff309efe2ef5438c01270d10c6a03d34f71ebc2dab1da90daa357984d2462bcb35ee3de55c3a55f8b98aec2114f74c84341a64127863c120b5ecad9e329a5756ae4a2555d8492cda835225a8deb3f9c1558f0d425bc172ff7640cc79d97800416fd6294cccc70cd1cf5b6a8e2aa07289bd522bf99dc96c36bfee80e846f5dd746dd4c5003e4bf7d29efeea7508a0161236882c9a82a56aa2c2574669652c630923ab470ddb95d456f7b8e8f07599ba0d1d38bc7f8176e3fdf0209bd6f75d4cc11803afb1856cbc0e91c73730e4fb98f3c948a87d5a7edcc0a6a8ac810ea3eaa6e063cec5f5566cd6dedc537db6d686b8021f6ea825ad7475ec7f1c5dbde45d3ff4b5ee51c0d04f1d74018eb91e5040d01c8b71a4aabbde6094d4afeccb18dfcded73ea75e3b9f8ce167df6209ae
+SIG: 288515fa7259f1eb587fe8a2c403434c46f8d7e75b6d22bb3896566c017d09b698c2c807799c2f65f9cdb4eb58151ccfc48d108061a6b3148432b2bfc1cdab05
+
+TST: 861
+SK: d5cac85521af781f3d5f66862a04b087d0ccdcac926cfe9e747be8d5c2633f78
+PK: 100dcc53039bf05ea0a9f5888212693d4f9e0e752595bbcd020610e0ae213596
+MSG: d5e7dd594909375a4be08e74825d598d535bf46ec084de52b57391c127eff5224ab2d194dfb26633478d02fbda74d1dc5821f791bf962d8dad9e4ef24224891907b0189cccc8b133d3aa2078926daef2898c19c2e0bfe02041a904b9f04be7cb50aed0d962d1add20b40a88ab7abad626cf4da0a78f9f53685501fdfa58543ddf2ea0eea69e7ba160f8a177a25fc21e8a29c661633e30e523b0ec01b2aeee2d426e4aead457488108fe5f569cf6e2fdb68c28f2b3052823577cd934e7b062c8a3424cd4367fb315b744ca35255d7f1af4edc9bc9d8837123d97903b43df367c7d418c79347ffafe7c7b1724bba34ede8d3568db505983ead47f62b56e3618c11db8ff0bf492ac67597d2f96a6f420ff985341b786ad6ceaedd105d0d1563b2d53543d78e7256725d204e82ed3a2e6a6e83df61fc282a62ca06e62174b55bef40a0bdf8d23d1c330c71441485ee85e70ced121eac607f580678163e4bd75c6709ff3b41de80594b9e2f2aa278fefc21d73ee3f72854b958d9a8f63e3d70f7fead8c3dca8e71bf4b9c2a36f212b32eb3292e635580386559ee1a11df15293a0c21cd7360869846ba5b7ba85c994f5b2f9cc50e5eea8e4b3691d886062a18cfb182f1e8b611fe1bc263159cb8a086787c811bea4812530008c70ca0c47e64eb2fbad5b02727a66f2cdd6dde86f5d2a9645a1e9aa66ee0e15b97f5fd229596ee02e661cab9a54eee1b81f98fe256ed6c54feaaa0ba047eea353344f6e5c62be1e9d5c09a2a699411110c56d1949e90c07b1938ba9555ac1be8511b510218d7cde7e1d74a68afb642f81715fe9e6c96c50381ae5a9df306518785dc4dbc3a64f60f245c564b8029512f381b56ee787703426803c80ab1c311f477b891708b59fa748f32debf54d2413771978c265c9b87114adf25b8337aa93b0e632a5b6eda474bec16328159fbed067b00b87add61965492eccc6fd3461c1000e4037ab1e8ac89a8524f78ae09d308ea6c94ff883732b712eec0ef07718d33c011b9398f8cfea733075af331fb3f97cdc1e8c99f6a10725a68c5c58fdd8b0baa50227f34d73d23905203698eaff626654ce83d865108499be6861f6141bfa6219d7ab8b584519199f880cfa1b26d9194d301711c30fb446d6ea764a4310f70e4b859cf95fd44aaf8c1e240e80a71611dbcf52da58edc320311de388d5d9d769eb59be093
+SIG: 5dc03363414eeac0086fb6feba44217cef4c520db61926df680ca602dc11003ce6afbf3d13c8c5b05273d21415e67c14a2ee5d0b1d5352419ab9b39c003a510c
+
+TST: 862
+SK: 159a9eddea5de63403987b5670db6fac98ffe5ec3a6cf01516ee2c70ce3b3be0
+PK: f61f4a04a5a12ccaecfaf44c1c9c1888475a2c89fb02f26bb81ab5f78f4ce3a8
+MSG: d195e5900dd3931481bc012e77bf060aaf31cccb0fe1a6c40eaf286a6166a166b1ea37053426284b920c67fee1d4b9d86fb861cc6edd34e10c52233734d9cd92f5dbf433512ed255ac6b26e56f5c664bccb260692cf49d08363ee94e336acc489600a6aa512a040f10ebf18f7d2cbee9cad14c4ff87377a3263419d8297529401f15337a4c4d2325ed7def763a0d479caa408266834da242f3a16b79a45866b9d9d71a4829317674cff7ae6c8c587ba4d4980e818613d3ad82507a7ab032bbf99c5e9b640371bb41b91e965dc31e8c7d4b3bafd49570527faaa87abbf6416c47b1b1b09d3401253126cb246ae45acf5f100bb1f92f11a5c6c937e0588d8b146b3e4d3c7e5bf57484e984fe3afc4772f24ebf894cdb39837fbd469a921a96ac5af5e070f6c9624c588e9d4fe6ddfeed1f8fe20eb9c460ce6ee38bf471dd56dcf2e3ee998b8e7fdcf612e78a2e7c7173c0160982bedecc2c621e5f6611b4ef2102e32e7c29803a7e25fee151243158a76ee5d8c1bb2e7d8c88871ba433c5e541c2602693d90110be795b523a8fadb605d8e3d7e493fe245d9cc5320d32b85d6135a44b1168729414c2ca21560fb4feecdeef0cf7d8e071274e8856c004033e80013c73af7177c3197816a5032d9059b1b6e4152c386192dd54b90f9d308be98ed7d0ca9d12e8aaf6f9d869386aa9dbb01593d37e72f090124d3455298e9b4c9ec3cae73bb8ee41eb63e38c56133efdbaf449b84e1e491e496f1c70a44d069986ba8818422069061bb6ebcb7b2054e63df381ba03c6a7674abd61050d693d41bfe3ca5046c65ffb06a0749809e58d4c93a9ff69ed30950bde1f99216fff299f22f16b07c254c265ae0b12e313163ccdf5036d49055f9a9667b0b71292bc3b6260cb87568fd267170bc940c33329d729c9e32d0f9180b134bff8ae93b1bfebfa3842fef20bc04a297b00a84a0f428d5f42fab86142996d4ad9efabc49852f8812f3bfb5e57539e2186eb8ae229580bc60448acdef5723c881588b53789f05b91e02289223252d753f79813779ace705e04aed15265d3bdf2a2e4b15654770a275854e64cf44390607a45d7bba9af3e1a2e283067fcd6e633aa2d2403bd81f7c792765510b598412f6bda07b2a945b9f6d46ab2f7c320075bc6b60a80daa44af391f4cd562131bbdd407d66f8db1259bd76fa7e4d5264e145546c942dfe9007
+SIG: 0543712cefa29a220d90f81baa4e4cf77ac65208b2d5ce9fd17ce214ad4a937b7fc5c786413b58051cca3bb8b2eb55657d89572bc50ea2e5ecdc555088491603
+
+TST: 863
+SK: eda0feac0f2afe0174491552487f3962171332b822dc3da426f9a5f62bef7b8d
+PK: eff27cb51f4d39c242f323019a1234818ef2e4cd1bdabc0f2d8d213458dc471a
+MSG: 901119da4ed181aa9e11170b20626e00abf0b548245e3debf94bf5ed50aeefe942b402cc9948947852dedf2b5304017665749cd47c21fc652ee995679ff931e30e94af98b4a98fd44e849e98470fe0a76ce80c61f83fb4e85ba523ee3fd25db000053b49d0930e3b079e866e153f7d86367f23a4c4abc63b3075461e90e4fd896da0492e27d714941e967f52c93ffaec44803f57877d866eb5f8c5281785aa4826792e3964c66590821eea66752074264018a571f5b013b38e152c95c0248ae6036822a67afc9e02694573152b864c56c2f730a08210f85ec46f984a643d516a15fcfaa84840f512047d110e0718d293955f0158257fba0d78eb7df2f0b77e6eeb76db5e71707310e827361cd4e119740e63922db42c2ceb5ee175d50decc7b749fd2325bce1e6a8f710ffcc1e1c9b33c380e52a64daa9585fabe406d9cf24488fe26f3a495fb0ab50e1e2bad82381aa22431099cc8a569813d79c9d78569c0d95da9aad2bfb57758d52a3752752e023d651c9cb66a412a5c80f6ba54793f7ec87b4c598fed2ce24abd7608708895c46727359ffeca6d6c62e10a678caa718b4cd263292cfef535b9fbe2756b7396d697b3146c551e6aac1f5f1c24be9b67a1e2a2aff745301ba6a212217c53d681681bbb401bf4a43656f5d15cde969c1780099a33237eb19a3b8585d6b5dea2fb577845f25ee2a82ccf4b28502f90fe80b8cdcdf2ccf93c434c0e6aa5d8752a44343c2b18d20fe4004c47038659356f87abed5445034d8e2d3d14768f5ef312cf102a9884683bcc0cd8a71e3ec36fbb6334a1bbaed5d2bf10416d82bd6530475380ab6e2577bbc69cebda75faf02ad827b54518213206fd4cd66f252b234aca9eede7e3eeb815ddcd8d519c5d7f5d9d1fb9ca0fa4467990095fa46220c20a2071dfcaad5f024dae3416f7c492d757488c49a2e4df483bc9b80098e0d5d683facb8c960829dff09b303369d46cb57331ff21791ee25d6be7dec7ebaf1b32479a7f514dc647105c944c36f7dbf0a5b589128dbaaa42171d642f25a981ce1f8379f91690b36af774648d5624c08dbd0a90f708716dfab2024dae865b9c49ab27473826cd4a010bfdb52011d8c7cb3f421ca8ca3cd0486889188e67df00fb8c2a643e7adb2f8279f763e5b9a81b6dfc3f721fc5f6849f66736788cc557c4ebc6fc68d6f6ac77bedda8acb362243bda74e7b2
+SIG: 6cbc7e6f5e12145b01687ad9ca6bf6e47f9417c2cefad3fbd68fd65dd74faa9750cba992de4cebcfcd35808cbb3ff12c8d930799af36efe7976bf2fea79e3e0e
+
+TST: 864
+SK: ec059fc6be983c27eca93ddcdcb53af7286255da91e2a56a684f641ec2d09d6e
+PK: ffc6cb751c70071b65ec2ac6b45fd1d55fe836965f80b3e7c784fc704acbdf69
+MSG: d1ac6325a4e690fa79536883d5c20eacb7d964c0178f742c2b23727deb62645af7c81922a0e72e5e30b5839a2ed5e567ec31ce224115b82d2bf251b7393f01b0d03a602bc120ae62af7fbc379dfcf95bbbba984aaba34fe212ac99003328b832c3532d42eee1e1874dc22ad67db6c91dbbfb2b45785dbcd39917d36fb48c1b5d6f38bdda5d28fbba64175575afea46c8ed6757ff30164e0df2e72176e8b6c9db5b5ef390b72f2d4d94e3b66f0d44a7e0f06e89debcdf1363c0e75d50db5bb70190d19f66a39c6f7dba70dfcd4a9fed02c2f1d067e7c788c58fdb3e17a2377ce486ec6582f3ba997bb5f70cd621002956f5131aa3a1617c0cebccd9391de1307c85970a8bc155f519872668450c91488689f53c2c1a7ed53f388cb13a2c3896fe5b7d3a0dc1683f27664c8beaea680c8cc54a90e4c6f99fbf05f2c22df60de9aec80c79b7d66207050667b452d7857f9a8ca723280dac7992e2079267ec3ad911404642c4e326bfb96b43c89434ba4bc78c252f4d4ca8d13a8874c6fc8252ea0b56c6bc786847d4318306e1c652c452585eefd0bd9dd3c148a73ba86eedea945f016713ed7df085d0066689e792dacb2bfc1eb5c824372a26c5e944aa7444ac9773d4a1921e49bdd4f8f6d788c263fee04c7b444c5305edb633e1ffe0ba4ea8da011a62f2bbfef4b895ad3f224c3ba3bff0c95d75750c9bcc66ff8a20b6c24bde7581a7ec3866f8716f781f46dcad45a9ebcb6ed46953368397011735d4b52d00e8db397995dbdb3d4f4254687f04688a268c305b2b1f622cf51b174775bad7f6674adc2e58e05cce865f12d7569c8e9b35bcdf3ccce6330d08ce5340a7c630f27a6c8086b5146b292fcbf50ff6aaaef8848a707b2543c618d17bd976c240bc79d33e004e4953482915e7e6ef94964bdea4e02dd7c2f475235f2b99e43229c9ac3aba0db59ac2da03a9ee4f37dbf247a33e6dfe5be7c7f82584f04a46d49f6621da31b91ac3daa4d68d48a56659b448c0ed365cb4aa0cfd908853df5bbfa88e60e10a5a002c32ab3333f2c39bbf3ee01a4aa60d2d01423e6097dc54305f81a2d93e2f6b4e8b351971cbf2457dc76e1fb89293384798ef28234e9b1a47dedc2336f86b8e13c4aef790f5a11239c747d9d865c9a15adeb071070267e5346256648adc0fa4dbdfd787ca1465fc240a324c3caf2931da41499e275fd4b35f6d08db
+SIG: a7b88e5abf132824bdde77c5f8df94ab26481f6bee660ea162247082a250d390c71d320ad060d8ef341fb69a483294f0d6de726f0c862fa37ea4bc6dab521509
+
+TST: 865
+SK: f16abdbcc0bcc61a1aee3abd8767ab52e5f79999bb77a3976cbc82670dfd2f73
+PK: 10f451719db0fd21376e228a41c3035c8c2bc42e5aaa926fe608878dbb0dc7ab
+MSG: bfacd7dd4eea467dcce404f4a3520a45b94ebaa622197d02d61529d2b3bf273c4ee1fb95a180c8f87de190a2e5ea70b84ae1eb6fd4447d8a3a8ded10f6ede24f0eb92bd30bc65d4871e8f5da08cbe8cd3c0ac64fd5a57a6b064a89d5159b42f8b3e5a1838c9cb19d88106c0773a275cd2a1d609930bf6b30aeca62b97e319bbfa934f4d0a1e6ac80baebcba2d8ea4bed9ca8562b4acb56979bf885324ac40ab4a50bfb9f349049fc75a0e03de4cc43eae3c6a6cffb5f6ae6c94504415e6c7ed3045a932f47fd20b9f3483a77b6d449d8dfd4a638dbf56f03f0f031879059b2fb49767943f46b3872e2de567d5fef80b02925e9863e0f1d31a80f4e6451c325694b80cf1f1918c6e498878edc47c4530cac466f1a294d55df09af4fdc8072adb1bf26ca8c92f912a2b9febc8b97b58c1e9d32c780323052972b6fbd53304c05193caeb67c5bd3e67479725d297dffb06890abf8cd9e42458e168a6118f905b1d53486016f85dcd98dd339e3460533d0b8a49fae6dc1a071725e6ae5f294479ee3bdcaeb74061841fb2608e88a49fd0f3895b18f85b90f7241dd1387710053faa62bae75e9ae39369c1c02de5d19242efa16e11d44a4ba5778ce7722a91cec0bc0a08c069bdfa130d1c6c4b56c6e93542403ccf27684def57def26df86ced571282dc960974618f0a74a0cde35b653cc6e7730431b825ffb9b8aaab3c7a397c992bc2fa23270fb11ee431afd5f9a644483011173993f19485dd3cbdd187bd3d995ebf0031b1b0de4a8de9c14eb6f780e36b8925756b97906a1969d85e967d880e6e7dda42fd3c30019f11d7081071eee6626422836bbed27d46dd0df1feb6610dc859f513c0bc653d70220fe048d2e97c2e06af530e11bdc7029bccc5c92edecef5e4a2e0be2d251f4415dca3e55b3a850f2630b879e4e036ce8633bf20920b68094215929accc7be40c5778bc554e6edd7e54c9e145b2ee07b65d061c11de0e83f381ce4f57c6483f51069363511074c7a577353b45c6eb71199dce5059fd2c4611b054238aaadf2b6ba534bfffc2722ae3e31ff79ae2ebca99cc3507f8a033cf4fea70c52f7db5de442b42b8d41e99012e42ca0e85a9fb6d4f165b330de6383c5726efca2fe971340002f562dc6cb8f2faf0665725e097799d096091864d66a950a5790953ee16b9ea582009218708c4accd81381358a2c689a041d02d786121
+SIG: 33d805290869b8e04ff089faa2d1fab83743bada68ade5b38ae5f0cc58c3374eba43943c1f5110678eb39b4658611822a26d35ffe19e9cfcb9ba9589e4ec3105
+
+TST: 866
+SK: be79d1aeea86e86f398137e62ffd79e50eff9f313f25192f89e52f0b4bbd5d32
+PK: 187dac855ca442fd9a3ddc3289c24eb2d26f7a40fb29d8e74431b25022c3a0cc
+MSG: 6d632a7d3c9be53649d0d1a5eedf519a413b13ac64e9ad854dfa04f2e17329d822be573d9e35ac066f022213a344620bba289f5331695584d1343e815405aeabe3861d63b3a5b92b8cd8eeed2280222abde30a1bccd3f3e411aab922fa1baa097aa5c780d0eaef94ea10fe21f7d639b76d4788aeb5924a9d262dcbc5688a3e43544bec088ca2e0d06d77a71fb641d55226614452b1e0807a9fcd3ca69bf7f25d8041470ceb7b21ead03ec037a1629bd500aa233b59be44978210b6a366f223acfa0797954007b00efb4ffadb5fc92bdb37863e502d7d70681039edf33770df3d1de343dc35f226d5e73944ba0255e2a88ef6c41e472b214567c249594a50878b6731c1aeb5b10fa91fa76a37e1f9f1c00fdbfe3485ded54a009ab6133927115668b59f5115508da9370f6bc92a1185c0d5ca01d291e18c54acfaca738bd71968a342a0cba62e4bb104a5bb379fc83ee1820d1db980253d6cb383e95af15f53c85d175890dde5e4ed03d2d0135e3d60b18293f5b5641ef83c6ece3d52598fc6353686e6f7b09fdec1f6f153672d34b489b48a0db9e42ceda71755481c047016c22534e90c6d201ed7859602636ea77ae8c6734b7c4c5bd99579c508731c7246a29586e406e1d932f6713071d4bea63dc5e2a3761e16024d2c3284f709a1f2ba085ead3200c7046275cb96b61a60b5ac559bc488bd106467c3de50bf5d740d05c9cd701d65b7daea29e64dd5a97adb6b5c82cf7f23017aa7ca1ac9a39e5827eb47e20d359b67c7d4e1a8e3e27c52d33d9303a592623484d797b402cbb458d1ac2ea53e1c4f7abb70cc029554a234574def9bc3b0d3835dc314902e25abb22dfdeddc679a3cc8f07340b15f5762f4407f380342554ed0c62f73b61816ea8c529461e1bf0e9d1c2d5e4c5746336bc0e132873cde0dc2158b54fa1b678a006b4d95eda8a955714273b7cc5cf2add9094d46e49abc096a45f418e2edbe99dd852911688064df7cf061d07aeef42795690f48c9ba19565475d5468a9ef45d7bf75fd71182dd6e640138f182a6a0c6cbbd00c495c4389530ac8e67960eb5c5763f5484eab1c1ab850140da042ba47ed8528800d41787f075fe0d85501a7ab76635d03410d286c0e17db4023a76397468ccb091cc5ac1f6434587913eab922b50ca5567016ddea32fb53255be67f2dcf9ffa85d117f1a655fa70dd3a54cf991531f19130eaa
+SIG: 6dab593bb1d448c974a65c6a0b6fad22b4732632d00489176ef126aa590109e0a723a113107b53e17d690a0d40b0fa336cc87fd5fce8f541accec67f7d1ebc06
+
+TST: 867
+SK: 269952172c3fa976defbf40bd6edd8f15cfd4be10c758e3741d74162d8ea229a
+PK: 4aea57c721e3dcca8239e9ad9b22c19bab8df72c88793b24d8dc47cf9740fcf8
+MSG: 7ccb6a0570c533737b9a534a341a7a96dc76528b997a9b48e6e0fde10f474b27ec989912d176cab742d89a848b3666e9277d695b022fd53a9eb89e88c720399e24ed25db9eb35d6da009e9f024ef8e655165bdef1c0d797c74f019cd591a0442a12d1ca893836ca2628b33e854f3428eec4aa5ed84f4bdd2eef8b6d225caf9496df9edffd735ea54db1bdea883ad5d47eb0bd4a6653f0ab037f040a41517a7741f91e82fdb6fda04f0dfa1bcf8b9b37bf2bfbd87327a636f907fdf968d0189d1a11809c4230ba69d5cbd84f561bcac3ad002e558c5b9b097a01902f29ce3f1ec264153d668c78b845105b9cd2ef3c943531b75aa428f179e4b3418b1d5a4aa7ab1203efa495c8769628eb1063a937b73e4b5cd0cda33dab01a50c64febd975c57a1e841508e8606094d0824fdd96cc6cfa18fa8209b30f0a2a78eac9a767176f573e78c068809b199a69ac6d335d7c920999c40cbad87cf4cc7ca5c644291d75ad7a74bc1e6392d1ce311ecfd2ebc916e39eb6aa3e7d89fb805a27a55f178912b157bc01a055f67aefa78e55c806cbd9c01baf8ef92cad2260b4bb14cfe61782dee5c59972506941c462a4da7eb899531cf996bc98ba3629effe6fcd1706d1b4ee4f2a14e921bd408f30e12e73fb7aa860536b03e77ca937823281a16453fe827935943201e6ec143a67eefa4f94e9abf94f7e3d41b70a82be69ded8a53060c2305f42f62fe6a2f704b67a1e8fddc7d98ba7f3457119b311d449663ed9e320d618dc2368d4950875b9c38c5d8c03104e2e32c4325dedd2bc267e2accb0112018e9c5a8007ccab2f6d7c737792002acb730d72e9f730829ebc42ca564c1d9271bf1869c4d35835589b7431ef7a31a070060fe4a089fb11f2dd3dce65ae0fb45bc3a2860917d933ba2d090569ef5ed43bc2532db879e0f1f225eadcbef1c03d9ed78299e233e4cf07b064a7baac34c5a0c19fc3a5542089f70167be2f85b4a10e778525223be8ffd5cff9648b1005a098b4b3924398fb0bcabcc6edf30c061ece7aea35fe98a9203f8711369530feb5e67bb2d4f59d9c8bc993854dd4747cde399bd0e63740c1cc839ad0f098a38a80beadd648e1436deee60e931e68f52979ce49f301fe39afbb615352091c8b6585fe88447ed6e59a020b2bbe66a9423ae5228c203bfd4847b5181e2c3b4dad83a6d4fa76985eef76adde3b34edbdd28d6a0b4a4ee
+SIG: 3ac80d1e8f68b4058c3a04dad7187373959f26a27002496f8afaaccd8bea0901c54cab87b2a2302e1f3625c2b06c7ebcf3ce96de3afdf00f5194a35e0552c70e
+
+TST: 868
+SK: cc3138e502a5ff6f80d246366e84d65c59f12d4f496397e6eb99b5267b8cbe2a
+PK: 9e2d3e88af7b52ddcf00e6d0c7759c1238b8fb3eb14421fe82c34833437835bd
+MSG: 585ecf2f09eb923df20a8555642a2bc0b68c6a5fcfd6b8401c4a0cbabb4c6e6a206762b7a39f2c5455d7808ebfbed56d6760a431c7d20c2dc6ef1b73caa3c49488e30b1ca2520ad20b26a19700780e5ef3ce0144388d8407b6a70c1cda37db7f12091d892f2e91ad4078bb4db1762e46285a7b664b2ad3a34d26d8a94d64587a84527722ea83cb8aa88984e1489743b4214ea6041aa18e55200954efc7edb319df947efbfc6c8d0fea48a131613465d8f4c49498f2269145c6dae50478052598e1ca3be0e33611571fa384771eee402cc2b1d84836c8f1ad28f2ad23dee9ff1d7e1f2521635874115def4d93e89be76180bc55f761144360a8b222892d64d157ccb5d8f4855dca56701495a0e1002d340a4a46156b9b7fe06b7c0759e0b6df559b691ede78b55af64e7c8dd908b788dd6ba35a902c81dceb3788b615de225afa58a81181ab24a73705ee838b6e863fe1bcc26c1b943239230c27c6b397b23d13de6a02c97f3645da91d413f916473b018a61594b6f51cea44457da1e3dbbba6de16866657e92ef0202718a84ad0333e8336b052b004733e8e95ec13e5f91b3806a98d3db729fb735b8147c4a982a2d5b4efae9c09d0a9bf891cbbc3c8f531e76e4044ec91f4d7c5cf77310e2b2cde2e07ccf3e0a19dd6ae1b3fcb2df42186e9c72922d2d4ce51b306e81b16cfcf8f00d513fbd2c5239b45afc654f6fe21acb7e8a0c9aa87b0b605074df9576a6ddd900aca567617cb79656b3b5ecb9ff68b2f6241ed0d024ac27aa6eb486b69fdc0a0db92096abf86002dec7afd847a006a3f6955b49569053be9f1d0a49b793a5411e5916f418ecab953243553b66e6badc4e909be0ef5cc7c6d27199ec3f21423bc45773fb40b97b61185b57080e8f0b89a3ea57c8444ab27ecf7006a766047eeff54d8556cfed23def1da2cc8aebb48c94e779e8203ae2c902b51de0ede0456fb73fb4d5f514a4cebc47fec3f948469a545c6bc57b4138db34e7cc006de26ef507b54d28147567a8c29ac1ecef5bb84fb99aceb23a20294d74a85ae36b33450668a5c2609d3a93934586ff90c3b6d27329eeef3a754e9a9cbd5617ef3b09397bdc971370766589a12d890050d1651458b3fc533c843bffdf9754d932c4ed7611d4d27c32a087555b5eaa37ae90c4979ef54299c420ab5e29ae2845d4dcf2178920a865175fb9cc0e6b8c524b1ee495805d517bfe0
+SIG: a2700e3895ed0cc2aaf012a40bc7bd0bd29dd79c69c0b4a6edd0530cf3e267c0f82dd84edaf1744dc411d62c0028715258822d7b63d39705612b3fad4b5efb04
+
+TST: 869
+SK: 5c692c681198b172df2fac2aec3fcf7015c2bb6830f2a98e30a396b64af4280e
+PK: 33b169d4ca271040926ea87835e5066f9f05782f087fca7a556f7bf4cba2e886
+MSG: b160ee3a93cf6bc3456e5bd0197c09aa76c2258052f9a34dbc2ed589f8dbe5ff9969a61cfe846b2f6739dc7d4a1496e9ad58605b5a2758ca078c55a9fc1c4eeb5491a84bfd468a2ceb141a773493a9b3ee828b5dde9c00c236ff0156e4e2e45fa07931da68bbd2030a881405c4f78728813a5e04812404c2a19c9b87b1cfe9af95e273ecf9c518c53935f842563b192fae12a73cef085fe19e899e5ba08979e311fb286fbfc7b248aabd40dc61610e1d4fc9806dd21292392db2db40426c5d196a489c5db77e3e9cf0bd041e3c23b5ba1db781a10790be1fe07a2b00ca3af89cbd46efce880e1ef28b0cd79d53b42cd80eaa137eff7df90bcbcf95c9858dc0ccc6d8ca8ae3547bdbf9ff9024f3cf170115eb28bf12b7d3b701460f48d1b4b23d7f6ff72ffdc9a6c52624d15312d7f19ddb6026a15eb54295d331fd79509103bc59a3b6e1ba7ac8c112e4de2817e51c1e16507ba66f2547bc899f69c1207ae5e37bdb0e161b15b612305bc0940f9d1b382a37ec2da639a6ecba1bcdfc51214c3223c11bbab79f3fae3d55e2d4be584fd7601e4e2e558b3be5707115a61f5a815ec24aac18093457bc46c05cfb7a3f2533eadadc9e6c1fe310779e697f683035ce57873df55d791f6d2fb0e2107e6866f839c3a126e9023865ced1bcf6779955af547e1d87eb32a9bf322857fd126b0cdc5d5e904eb76c6706e3c897aefd6e4756fb8aca8170ca5b39669089af1bb141a25d6b8b06034d8b11abf1ff8f8d43375846fa8fa8a34b5f264820744d31149b7d57326c59b1db74131678f634e7232ca5ea5188760a70dc35dc89f8e453b4c65b772c2b6b62768d8373236551baaf24d3c304c41b62c36e6a3383b3a163b73e78d8badb75741e5001d419d30e2ed77c3096e8d8df713b93762c9707bdd0f365a874b9da8ab710495dd56aea93bb77fb222635c63bce9f63af91fac89c66986b8e2176dd451d583394c1907cba1725f06d25d1d0912b3e5c6c7dcd34358fad59dbc6f6b1c2ef33d3ca82f43518fe4ff31378016e578a7bab0b77676ebae0d48d0889d69029d209f283ce8fe0ec23cd832adc12a9c3e3aec2d6036695556d9313f12a899dd59a66bef28ede175f8aaeeeb2942bb90892a04b440d04b66f5eeff61ada72790294ce55c86c6d92785ddd26c7a731603b069c603c92e4fe8ff782544c8e89b40b8b55f90e2a5e9a0f33c7fec77dad8152
+SIG: ad8f379caf41f72dccadc3e915357ab0cd304e10f4120e0dbbfaac01bffaf2be893f70072dc964069181bec17fe0251055b21e23dee4363b27ef1fff67aafe06
+
+TST: 870
+SK: 9d5f85d2e7dfd03bb689d900285fd4461538a5f2710a13ed21c775f6eff6b3ff
+PK: b86797e4be0286ae39e44df0a00c016db4555ef86f2f05d0a3ed89d89a4c3e5e
+MSG: f70b5b053a4672512c24b3168392f6a17dd77d8689c21c86efc25829a1a04fab4f76c8521684d32010455907a26908677b40dc6947d654f2914c30ecee724fa68446b59d091e258fc862411c964d668def83034b627ed416dc190bb5a263a6ff8d559e13b8936225fb4dab4f7bda0468e547e708cb04cebe1e5cfc69f76a1d283f28168286f24ecea5535e4490a0c55567a7345ef953ce426b209a3de3df595e80ee61e572a278ab02219551b73da41984808285a83598a02d9b28671210004e31d8af9242c16f90d5ea8f63a1ff66cfe60ecbe537245fa12a9b154115295806ea2d11f3671782b9af4fa86a1288e123cfd2409a5dc98f41b8f6df299bbcc4bb6447dc03a6d60e9b2c5b8ffc40d983956be97768dd0612d47cbfa7571c9969856c152cd3b473ace0b8a144aac2095c0f72f1d3147152b908ef6626d5222819b20bb3350a46452f675490c2a82150eec40d75b66a325d6e929a905ade1e3160ab950181efc66e59230865d5e599698a8a3ff560c4c601a7a9a5da3b5d89bca93f7cf5bcf5bd5ecff8f1a185c8220e4c77821e62adf95a037f2df7cef43a4c60ac75801e9fccdc5b08eed328dd93100904115645ec1ee085cc778b0f4e46e17298984a702eceb3e15283d820004f74a079520d63a75fae33ec3f4b836469e1aa99ea244af1fb08b00a8c9dfd03308dfc20235ea9c8283f4da47cfbcdbd031a02d164160f2a58986700b19526d41e4d7fd458434d7264bc8eb642e6d8dd2759ce2b85c97b3702e70da71f18edc53e9140a645627e0278e8e70539037484dcd18c62fa330717d6148a0d623ff8b65ea8567ec7fa04c892e3a1ecee96e832f4155074c83cbc93e98cc67f1fa112aa06e9915fa4d2dea931551e7c623aa8a3a7619ea24ff914e264f31fc73dfa8c430ac46ce16dc968c5a4085d5c380d30cdc6f43dee806f38d1df420a065574144737056daa62f0c098c9c52fcc04cca642c45d687345a094613d4a3c6c8788bfa218538ad7ece1bdb6c93924eec4baaa3eb15dc1494d65ffa1a23ff8e985263408fb02bfe39a8c55b300b1a02ed36c6714dd5ab750d47f021f65e08c635f1d6b7baf396cb4f93d56c1ca461bb12e94de7e5d98659a8af0bf019fc42280e111e04800ff80e0c157150e165609454281b20007e3edfaa1ea854465547a006a4c3236411495da166098af2823a459cf100a1f3c92c6390c6066cdbf
+SIG: 176b9592f8c25135292add4daacc9c4faa21d4f49b278480c4e8881c01624df9a37e23e18e84ca32d0d8cb851054222f10a495419f197e7b3d18df0adfb1b307
+
+TST: 871
+SK: 4aaf2d132884f30d1127cf187ee09388b4a5c44a9a9267e6728317398951fb61
+PK: 83727e9257349128559ebf759fdc82122cce76746639c0ada9761f0d60b940b1
+MSG: d73eaf11413bf4d5bccf6a2e809cd6832a51823aa22bd16e09cf56ff045eef2d1adadda50c2ebd67bbc4d70e493c968cb4de4977065d4463300694c9caa57206d6664693d8462c3c576b525cc7acf79f26f9055a1bcfa7d077f45ebe0b2d481ebd63f7340a33e4ab68f1604975ec1dfec45a791a2abb1044d75a4db55adf59b8394ebde6824c21145b00ef3b1b08ed11fd51dda514ed7e21e54dbaf6abb6d9e317fcf9fd375b18764e64ac9be5b08fec3b78abbab1d12a2ab09d559acdc7133fb2e0008e0c114b7cadb4bf763078674d03e9c807bec1e2ca71adcdaa310d587fa56950fc0fb2e979043d50f9ae23fa8f821cd9d6232789d0eeccfc4f47e3ad804e25cf5a425f94377d17874833e6ae3638178c78b79519d64d9793f4504606a0eab68707f6e1f7cccb515be3d1201bcd19f2f0e255c722eab12b43aff8c8c5561125fbca1f6542076a06152eb7e4b0786324c2495e79d79c0a8e295bb2e3dfd05a9033190065a284552a6e736006ace41f97cc434a2512051b727ce5bc9c4a75529ec53dd7d1f126e793857747b5ba8d03155d4555f59e8baf2f0cdba871ac160e7519a852db004f701641a40a422d4c38b6c0c3cc8fbbd05322ddc0001fb867286e296cbd69862cbccc7447038eb30f8a8123b7b31373984702c3be457a4b8c54e6e5280485a2c4ff84521f298ddeb3b3b2bc91f114ddce67030248044469dc06f362f2919a3fece5082375d04080376fe219d9b4575b1cf1c9ec4dcac5749fc778f515dda13fa0d586c264b9bb61503310762c789ca11608d2fee674c70ac4fc6d5ebcf68c4ab89bd84555fc007523c28a7e1dd08a9862044d5245b91a8778ec9ee984a41a9e13b7abd657ae2a46ae860152c644acd95367678ff64cc54006e36614805ed618a7c6d0fd33a908523090841c230af09846d132bb4c6b60e2441f9d3c498714f470f6bc03a80d14a294b565d1d5e781cffcb1304efdbbc7bfeabdedc857acc42e2762bbf97af839a166752da295672817f10dbd472d381f53165555ac8222a78535a86805f1bed422889f206109aa74772edc0bb51e8a9840cf62c92fa635b90cae076dd50e5aed9deac843fa8a6b539988285ff1adabe4c7b83d9e29ac2d94092daafec9f6673689ba9e9252d864d7577aa89505d331fe7809861277002a0b44a96ba6ae4a52b3548bf268e777780c00209b245f8b1417ee5e701a12334ad5
+SIG: 5f11df3906a712a953f47c859806b5237358d08ba95e49f9e530a37165835e9359d9769dc21fbb4d44497b93905bca8d9917c728493fee3acd5b521dbd1e2408
+
+TST: 872
+SK: 4bc7daabc5407c226d1920db4afd21b2a5b3e59b8e9246053f6a1a6afa54e7e7
+PK: dc539885fc7bee002ac5debae16bddbe4b553fa15e81ee798876940f38cfc4c5
+MSG: 6acce99843b241afe6edd5d0ab78d0fb21c8c35aff881389d505f2f1dd91af1eb2ad229254927c7f0ecfb7a8141690573a655d69853d74d0708bf8b1e60a03963028a625b79f3dfea2b113ffcab46f3cfd4a621e8fd8ff0a968143b0ae03ccb6f42e25e2d74dbf515bc358699b635009b01d61fe597f1dc2c35a7ba4555278ee0ea456c7d35fa8757a417924b1d0a8351f226a13ec29d025b42696ec1d9925b769cd59c8e2f9cd3ce4e5c020e051e7a36f3f97c1e8ec71974bc16ac4de4651ad4df2e9c0eed686924224fe6de6c60dd4acc26e0aabd80c21d509d959b80b4353958d00e44c511d23bcf44552608bfa56a9c5ae79de62bb23f11d740f48240c27e101999751f2534742c0a6913ff64b683a18995abc393feb9d57c71f49a080557298cc405d11b7988d7116840c5adaf53bc672b46923cc457c7039940ad4d5bf073c6c886b1339525926d281dbd1a79739b2e36414cbd321b185fc88f18d2f81c809975be9a093644cc559ed2ae5cc0e35cbdd1811f70286057a3f703067edddf5eb1690a7427bb73fe3024ed0db82a5ce8f1716428a76fd292ba99a300c4b2f360da2124617590b10e3b162a6e67dd5d5a59bcca10f610fa064affd55f8483b98a68d076f278abf888a08a014e0ea499180fbc79840ceed13cc6b2458bfab9b0dd7ae9d86461fe215e7c9f63f768cee4a882df0dd84e3eb4f2d7f6b18fa57d8bc7d9afb63c21ac465e7903b9bfb8638a29361f7ebfc6e54e5465a6cef463ae22643ae410258779ca74b70401a9455a4d157d74a7029efe6b519a8c4be696756e045ae4081b77dd6031f0d250fa761e60f859d9063fc105aa0a1a7450af153e705477777c442586df407402ba238752faef74f3345c26a4533be9a61f5fc6bde48e3cba75c04d6f7b333e37006dd0c94fd3b6a130bd6fcdb3c6abe21ca60eb431cc2d8a2ece7169d2dcfce2760825657fd4c26f3c3b830acdfd508011d14764b3be91715571a3183018e0d221fb9532bb2e1711e725a273ae0cc2faccba7d5504929459c992517b05c1ddd03aaccd937b86eb67bc8202d01cab3d489586eea1acca7dc20cd0b6475c258ff673661496a22ea96b89db4bf3fcaae3bb04f67db096a47ff7e1ee239562dc10d40f053944f3d7bcc3ff4c0ff765654ba5ea64f0ea63e45a21d9b12949f14f7ea7074e9b659c5c5d44816842de89698a8fccace43eb6b4135e0b333ac
+SIG: a7a6488839bbae04dec92f96d728c464685d7a96df512b0051163d22538f74546fa986b1b60a6d8cc766a26c6984c9cd2688395898e2b2ae72dc6a2d5a9f750e
+
+TST: 873
+SK: f26af210e3b20173990c7745922cdf9424773abb374d777a512cf5b97b3a000d
+PK: 54586abf041176e06aec5b6010e190916da54a8c4bde288cf24d8c107cb3b730
+MSG: 88e26da35c54884b47146f4e3f014ab65b3d71aa7e3c3391adbeb19ef2e7b9302e281991b261b6a0992e2e89a49f480ca2d8e684b12f9b1509b38f6a7a98a5ddb4c2d869fd0318e98ecd8fd9df491baf99a9294de49e1cf8dd41ee85730af025a701143e4f0c8e3d92d55b59ca7d4a6c89ad760dffc0c2189209508ef6c2214edf9967b17def123d8692c9e4e20b1e98268808704f5f9fe1a6d6055e32c872564bd17edb7359578629017f0c30feab8b504e228923adc7e81ae20a852db0ad676a78e081336d6b0402f9cdc5d5e90128ca945d10515ca0c5ef03f731b1d40a710741d41c1dd1ca16b1060febf2a0532e6f5d7651ef446375ec18090cb8418b8202f25a0389031b307f223c5b5f6afe36a9adc1068f2c6e0ea5b2b6cfeb8dc004f7b829c80439069b81a7bd907477c6135ef282b771f141dbe75a0fa056e06b8a1a1f98c25fa54d14c8fdb42d6502595c59d25bacf1a19adefcc13170f7a4317b6ab610b609d414b0073ea04ac29eb10ee73cd71a4ca60409f8e760e60f939510100d0c8cd76f264bb37811f97aa5299ac0b12d4168ff38ecdfa80b1e5c1b3bbd4d40d3544735df7167eb158a9a9a234d445f1d663ded7171edc68d172c92214b82ef13fe6b8c43aa89b739b4990ae947a34f020a8d8943b0f7a5d61dfa76adde0272e98c1159c0fd8a1de33f2cef8edd32857b2189ed96128057ebdea81f7a3a3dffe1893b5ba877556c90383fa2c5a6fd680e8a67dee4802d90dfe971623a7be22ab3ca56067b1e5c694aa84c19f16d69e284ddfa039c108d0435813812390d8ebc1e50138176f259dc0f26bca13bc943f50d5a3500b18d593574c620fc097ace430fb80728d3a1aa644e504b1009ad67536ceb011f2a357dbd009e4a63f524d5b5957f331567c5b4d185a61df22d7071d31ae92141e199c12289515aed80c91021456bcd45ccc634037dcf69b41d6b1ff53471010d99f187f04654f43622287871fee6dcf5f3023cbd0913d99aff43fa95b32ea2b133b4c9ac4b017b7cf8f9be5086fe92b42cb8dbed5b630bf097c18e2e55c3dd93271e09c2d1cc6af87d83fdef3c3e3c4cbafbea9b60fd5e9cf0011de2e9e26fbf09afeef5c69802a6c46bdf54c145862944173e017e30149ea5c03c7aefa28a9cac7767002ea3fefbdeae5bae005c370dbc064244d5b9be5500a35726a99bc9e8c2752d510e139af225580098c8189aa9c520
+SIG: ce454530b922ba5ea162f1a452e05c00363a49a9db8a569497c00caf1cbea99180770554ed4e3140dfca4555159ebf48ef5d2a50f394aebd782116ed6569a409
+
+TST: 874
+SK: 39bffe007f8df7ce4e56fd176b102b923ba48aeb8269fd0cd520c23a7b236e6c
+PK: 9532636800010b3dd4012e341fcad6d29afad484e6fd736e89d5bc02ba0ac853
+MSG: 7a8c20bf2eff69af8bad6bdfabc7909c58ce746cc4df78b69b33c105ba3bd8da75244758b5172d5c4501bc39970185ee3d437083a9959f81e7665b829a69a5d72e034d351adddceb3d3fff589988df182b46fa53d26e7c9eac062215788f2337bf90f0177d8ca744f95f28fea854593c4362c82e9ded19b904ff99d2bea82432822e52c3da6d462da754ff1f8bd109942df51dba25b7cde838d5f524239f1331f463194e10ff56795b296878feb1f55d43ec7daf0ca5ab3d684b55bb0aa4c720d4b5c2e830c858694d3d0fdbaad0bf67d873182d95b2412fce5e7b00fa6bfc38b132efb96f87bc6c10070a5716ec9b33a2692cdf5bc41c7f737e28c4220317a489b7323d5e20f65d375d769f9e79376fd02d85368671e7e081eb753f888545ebe5c000b2f80143eb358d43185e2f1c294b9f29c8bb91482d4387494aad176deb85540fd005c97d13e6663f09944eb43a46e6236794bf6e21f81d0a42090f9ccef90a6c4807b5ff541300e5934881a8d92196b4cee85d28092a828ea3bfc6b745ad219be9f5e9574117d079e02f4b748e2cc01a32826a3708231914d2772c764119fd99d53ab5b5a2e9d891a48a9aaaacc26338b18248db8ab2d525daf15ff53acbc3aa98d4f2d4a337bbaf6d1be21985a4af600e29bbb42c8d89e6b389c66f42270c3a0b051bdb623881e02f2f4294cec3476386747abae6c7700b8f9b0387cddfb73668fb57693d8474196b33abd12dce59a57cf72ee6cc1ddbaadfb19e90af8131b3a90f9867f4c7e15bdf9e218477016bd0ad3be8dd059671ff656cbd4ed898086de4d423f3dfb270bbf19d9f53f7f6f2d22c6ac9025cbadba442e31d9811e37e847dbd484d80cf743039ffa7048470fbdc6080f6d381dc7e3fa27122df53cc06394ea6fc446e1ba72538733ed3abb685f16dfd5ccf585ae8fbf9954b50f10b7e5432a22b369406a9b7088961f0ae207495ae7185396dccf292dc463f41f376a1ca89eefbae19269152031bfd815288e8b5baf348c4f8ff3dff4fd6d108f871daa352110fa64188b01b8526a845aaed133e456b4c83c4fd4bbb165b4090307e8eb17df176c322520f37599c2105aa8120758394a4222473476764cf0af7c55183eba9683d7270631443f3c51fb8ab0c130ac436ab603ff4f1d8656cdbed229a202b40008ea10b171542f74a70b7bbacc4016b7f636aa89633b7668058f13312f57c5162d18e399e
+SIG: a27cca4b9f5b95ad0e44e4740c15deaeb93f22a9b254ebbd2329365a00966c9f4ec1e55c5894e7bfc23d398d3970b9465e98a8d23e72dae8e350da3531ae6908
+
+TST: 875
+SK: 3c4080cda0fc3c03b614d980f2ff831f5be0e7a981d5381a1618e0b8fd001776
+PK: f1c3269d870402caa43882135d9dbadbbb162dfca0b3dad197e6b8a7ee679a70
+MSG: 0ceebc0e8a47720f25835e2b9acf891bcca4bda38637f363274458baa9e2bbafedd0938f5688734e22ac50fb120f665f6c4c61c6531739b929ac83cd77f8963b754488b9b859c13853637cf025c14e8fdd118faa14cf3930ceb35f104d95441e56489440f62041ef1aa7c4b08b2807e32bb9584b9004d76e76533348506d64f112e1ff6f938f642230bf38af010e41987270248b13635a3567b355bba5b57448c6d13b74f3bebf617915821028fca5defa4ce5424ca191cd54a22944a3d940e4ee2e2ba5d504c85f959b514c4fab41ccb5743d9cb2f9bf33d1d8c2a5869e9f4660c3fb224b39141e3110c9ee8aeb871e14c62c6be38fb9a4568d736810bb9d2073178b6c7e87e3582efc62b53c23c5d46520ba33ffb3a9ca649ef26fe74a3cff6188427326b8c96f74354cb3ecaa611b12cded565e59fe1f8f400097e93ea85951b5b4e9009eea7db937e4349c4e5e00c4456c6c5f4e57411baf4e46e700ac400257765f48dab03e439f76c1499b5108047c830109dce7f740d1393787e29d3716d3c47e755cb828e7d440a971975197ebdb3f9b737ba11f7fd0386a959249017de7234d5e5a9b473bb9583a3742c774ee552a12a1f36eb3f26c885bed22e91c74cf32a8dd3edb08b674bf386ef427727912d57c5fafaa1cfeb740cd52b9dee995e3d0161cd9213f38fd681d538ab8bf97b745f54980030ef8b72696d4e27473fb0f1acd5d0aae0297211680ea0fc59d7b6d51c63292585a1d553d0c8954b42a4bd6fcd3a49575bf5c88953f1f4ea7fe0ed7a579d1697e645e2a61c69d1a56bc605bb04060a2778d509a8aadbf35d94697ccee9d3543dd01281a031f2a0eb3a9eb13ae56ff44fa0aed4f3488747d6af820f3989b7133f449ea56d3a7f731e791b7ed2a5db939bb75352de7daec5066fd57557165adffa631cd3f967c3c7cfc11cc1f14fa23defec3eb0239b45ed601a3a8078ccfc7f8380902a859ee9ce2db795efaca0a01dc0879d506ac97d10704d7757b3ccf3b37c339b42db23782278023e4c2e77d74246c9e544149a55c0c920ebf2986b4c5b4b3572f748c4b15c7f863999bc5132adad09761eb76505019769fb55422f603184e24c0d4f3761987b5c50feafcce53302a3a415e20f56a054803e553bacd242a5e1364aa3b2d7cb3bc1e1b86a47431cbd39695b67f554c4645b7236904094c11aa1b40326ba91b8bf4873e9a4de04e2bf4625972
+SIG: c9d4a4728b8fdd240d9c498aa35de95a4bbd51785b73c8403fdf040dfaed9447efad0069b67c783d4b81d966bef6e3d9a808a0584b98ec2b18322c4c920eb00a
+
+TST: 876
+SK: 45438f91465d74a2825b0f66a35bd7c8d005865479b3dc10a9b56f297d31b926
+PK: f092b5880330871e5aafdd3ceb3850ee7e0941a2a1dc89f4fb4771d75a22f6f2
+MSG: 3071d4b720df1093659967cd4eefef2ef9678475f7dec58fecec1d928deaf802457a1934e60455f496cf4251820ed60a3d8133b624d33af26a262784b5a2fba73cca2aa5e519e1f539584780649864ba5fbc1f011dddac381f8d48d0d60ce8231701173c9d2a307a76302ebc69dcbc930d28431475b516f98f778ed2e1fff272909a272cc3fbb6b31c8041a37cb777e062e49649afad12c1b5f7fcb8065a99e7423362ad16906031265db7e8b89751f8a4a407f2502650fed753e42c8c911e50b94b3800695b0eba7dff06b7a710117e4920d4b1c605a3ebf32e06966716eda14b3042998a3c7a5e9f83542d7dde65e528bed6101deb331deb94cdd46044bef88c097bafd40d6921a7c484c8f96684dc371671d94eee7cbe5d587715314cff0d1877272d8190a90e18bfb321d52bf74705137b2abf9165731767a13adc9c85e0397b47aef96badb2ca7fcb8293b01fd1de316ee1e65f356b9d6e8ea1fdd837bd96081149ea2dcd73c4881f32b7deebc3715e2d7cdb643e0d98f4e846508b04b32439ff14b1164f46846df9afae44464cf550104cd3aab3817540470aaa2ab9559a68b7ff6b1b9c0ce9f5869cbdcdd617090942e353b4c77f09395896becddff1ab7f07586a514d81fb096361557566870f1691983485a80c3413da98b8d19c78e6379f943e5bd5a5697aa33c5e6bfcfb7b8df1e1574ee416fab3c8a7d088b3a057cf865321b74e6103526dd9ad15ca5ad3c0f69718e27081d4b34a7c6d1aab6b96c0a754b989b4940638c9ede3d17bd49f65bf783dc85f1c4b144876cdbdb2282a9564aa81b57092080d6448fb6580ecf09f82a755010d55d4a5e4f305e259dbe99508b479250d80ec17c8760a93e05a29571f6856073022c8706913c46a2efd2e9caae4ffa1b4222e3d70e979e81a71951d7cb830bcbcf901af244f64e4ad9f52fa3b62031e3516da50bc2bce78eb9d61bfedd9b3f57e89355f177db6162bf61da0e454c34288b967c3fb4c341b32d4d13a319869b8e36046f9e338b5f36a1fc1a7eda7d7b0d438e0a75d84bbe4d68c879ada80dde23f7155b532cccf7a63f1bedf84f82f440c9ec3cb0e45f32c92f76438f5b4b910441e6738af3f5d2050d579ee96b88f3b00810ab126ff3a8fefd971044324dd4eb3447dac5b77809cda8c71682549d7cf2dcee340edcf9494aca42901e2c11ed97790af48bcea29521ef0e3d03cdadecdc894dd0756
+SIG: d9287b7fec017f2ea40a14a1f62dca78b02a3d6632df7c60ebd90fc5e492c5c62c43166bf85658fb30a08b57a5813121b80397571a312b6dd11b653920541602
+
+TST: 877
+SK: 72cfcef4c9d6a1986d190311840e55cbafacc8a6eb5ecc72934fda535bdcffb2
+PK: a94464d8cc8f3e43393947649f91c2752327e40daca11a9970c5181eda37d606
+MSG: 66a6cbe88a8ab9a33847797fc480b244e8a2b8ec79e80bc2637753deb36fa3014f843e22a47db0a31778385ec1f455672e0dff6ca21ca4cfd2b989471b7ffc307828138b0ad4e647c2d13cef724469054abd3740245aea4b789e244e95cf9ecfd08a0d13c7ced393332727a7f3d8fbdabd939de28caa41cc96c7081198e22653d94e024a61f5f3dc5aa37fa9adddc96cf169d35062a0a29ba45a539c87a68a3a0304361309d213e614ee8373dafba2a7d6ed7d2ad37704c0946e4d093e2d94d061364cc1231063729103a77ccb501891bbc3185457bbd2869eb63dc60f196f10a38b7b36cb3f643d35ddbf438a44bf0c8f570fad41bdde267f0ffcf1f2f927d626d1b0d980a0ce223f2f0054845afe41d39de5a457219f276c67e69be2d5c9e070131639561c26751fb06435e0e42e2508c5f49cd12b517c9833ff97f5e51e1dceafa9426d3dc52fd1379c64ccaabb26db1af6ded7153628842f0cbdbbbd6aa0cfa5407f409496c06532dbeac94dab9baba0b3c988fa03d36f911d80e49b370b6837037ff249e76d692cd17737e0d07965d33f17042bbcd1e990e040f71936f6fca2542ae33748367787c01bdea75c9a0e66150281c468fe5c73af9e5bec372d5020c3d37fa1035a67e224d095f066a51fe1f681c3073939272f6af7750ed8d18349178ab4a2eeb4e9ca82bb67296e9890f316c9d9495953d68436eb1c1a2fb6a1cca45a8e88a09bdd65a5558025618b36d7f3cb389d2e2ab1ed233228ec92a327978c0adceddb6c9632d3abd7971621713754758e21013a0c3d009b6e3193cc152c57ef73107bd4357d528be40873027bf1840f685536080f12c5ffa93ca629736780e015e86d1909f0d8f372010c9cb72c0989845fc88315e6b9370dc92d3683ef44d3f75fc96c4b0e89e13d682d1988b685713eada842be9d2bbe2a76bba15d38cbafb65c40c2159b0ceeb0d769b9be355540734ff37736c0f0facb95159309365b9646bc4b344fb19a5c1639a88e87317bfb3b5e7b5130fa7d5643ed4da06430c8a0c1858ccf2f9a6e3d62012253f0122dbab4a35475a6f65589b2b095992826e4f1b58fa050b8f95c4feba3fbaadd2c2244ad4abd410139adf4c153cb5e69337af176a7837eeaea99bdcd59385afded34ffba8063a35f4f558e4eeb48f1487b56b1f8d1f73067621cb548c808753e3526a2f2aabde126bea521cf673deafa792ca5bd2212795bd66b86
+SIG: db7270acce78d7fb09080a327941bce7eb145b9e3661866a8683f9a1a3de97fb02b025db9ec76ff32560fe638827742ea2f4ebef6b7cce44f9aaee434fd7c108
+
+TST: 878
+SK: a6337e4d3b1a49b126316778c613516c03ac88c96d92ff5cc7e0c8527cce1a62
+PK: f5eac4fe0ea1a5f236b49da33a24e2f3a83d4b260c54d3416c644e05c838bf51
+MSG: e33430c38c4a40b3c66e20cf3b70e9fea8cc50761f2afe249ec059c07bc3b37e5b94f4a43e310099b19a85f59dff73a7e495c4df31f74780cdef7bd6e47c394c1891ea3052e3ccf5d84bae082d24ba7178ac65d229ad18a84940f6b4dbc596ee63c181b57b5b49698979c18632fa821ca61e35a0d0351fe13d69e06ddcc8d666dca24502177f344e2f440575d39ebfe5e7f10653b65bef291dc813a0434c975de164c1a76bf6fcef98f23181c009b91830b618e4874847d2e21bbdb93f20cd8b1f4baadf99428a22674386a668152b4b9039ff06abcfe334a062f794056172ecbc0794df98271b9acfe4b7da553a87634237630009a05b257c184cbe23d9cd5a038658010f574899f3b2d154d185ee67230913650c3a05b54a2edc243a4287398e376928ea9c6b2cbaf371252540e2b8043fcf556813196ae572c27cfb5a46abb9729af2dcfc29e033dd11f33e86cc6ac3bce6f3f9577d36781a69ed7eaf8c8263a0f18eba0fe8a481f3e15a55599434195f7cb057dd364eaa07dd0dfd266b807f53a2070fd791e872422fd907134f4a8a78a876bdcb031ac860dfe0bb57e105db8287b31a604eb71269be5ba229985ceabc2bdf165ac741650b1f013a66c9bd243d03a8b1c5081381cb92e23f9057771fc07ca32dff1db94f5adfd2f4ff9af31d250dd4f86b22592f60a74575156213f10846c746a920fe39851b32fe4c8b8758765bc5b8b9d5b99263df36f97888053fd10f1d68f577aed559bcfde744bc6511076cafd68944a0ed10552d11344bc7e4d9ef936dacced527433132959b1c7324ad1c4cbc3a1a736b1f02aae8e0611ae23fdd474f5b8ee7056fcb5af6133ecc084bb9f1f50cbdac66244437b4348f4edfe237fc3c3829ab94eb4f14cab1ccd6caee36fadc20a310cf0690622cdca848aed03ff403a6633f4f657994b780dd6048149c3bfbc17889e37d90b1e5420eb3d4596b91ba11bc0229c65d05b93cd7e0454d1f3c6e1e8071983792c4d4368d0778aef4e123335fd2962c657bd0513571a5fce211de62874f27ca10dc15ba2d445f1cf4be5f833cf0b564c022576b98c0a24349b67085f92202675d7dac48b95e3bfd6555a9ecb7c72f08bfec0d220222492fdc9636f036ec4508a365b7b70979f9eb4a7263a8bacb1c1d0155738646cdd46ab9234a170311500d0bae6e55a863bdaa56f51645ad85297a7381f8d20cf96c474d1bb81fce132b14555d1a
+SIG: 781376c9512fa33c457047a1f4f0da3176e60ee47782869b7e9fa5841d964f3c1ad66b70c114b1771c324c83ff6cd997aefccdc59c114db9f2f3ca7d84a7b60f
+
+TST: 879
+SK: 107da98d0ee8e7c00f6d41ec265944ce67ef8c8ffb51f4f11f4e5f1a27fbe805
+PK: 3bec34b161b1bcff009f8cfc50d84ceb6a2d5b203b5238a8aad8a83618b442e7
+MSG: 1a7b7f3e1c7c41492a7ce799efdb2d9dc2f2489c84ae28bb7d084f32eca8fbb066885ac6f2ef7449e71226a82e9f153772a993eb6b6bca6491d26aca5dee98b77a1ddc59922b3145c447de737fafacba5a75f2a80137b5594697220d19617674a69113fdf77c343af2b7e3861b5b7822f58d60089c3ca54c749d27f88379c067598f063939ba8631d1f52dc9ab455045fb360cc2a5b6b0127facfcf5b1b4c33e3f194fc924b854168cb1169ab10997b438b71c80878347be887af44810134b514c806908201a3d3e6d0c56120c4314874dc2944d8444f01bafa34aa62ecef0981545e5d02f4016c0b164fc05ae18f535c31bf20b86f31f7a794aba148984c3ff433dc222c443b5d26c1f66e6c5f19d19cd6eadd4dc94101b2f52b58c9d4590cb10dbc5d6eacd11d42ed09f15bde44ee9271def292f731bf3b4ac6cd127e4884c2cb30b285fc9247638a299e416520624d1ec8d0df2498939c719a9e7bd29a3c5c32a3e8241368d6e4f90fea29dc3a3f147ea9f76c5780e73143f55d3dec7b66341d3f3eac1d98f8e7d4e877509b4438c3a52466d242a10b4c27c4a0db9232dad011414ebfbd57906f1a410207b526b0d1f1b6986b3ebd7550a2b3c15fc2409c7626e0dd330ef6722e3ba48b1d9205652ac194c21473ce258559db511efad3e5d55f2a796d65a6ab97d8631062a593a13aaa095dbc93e6217ced619cb16a57e744355a16b15e77d4979119299bb043e48fa3e615460e164882984a223d418ca95340c5bfcda673fcd13b29f2c47d2f97e3e8c613b6c58df0e62cf23061d6f545b755033fd3dc1405e5fef35a13e015f98b1cc42f71b99681f9681258229a4473d86eabb0c17927941e50c08f34a76b43bcc6d042e5632ef9ccc91b6e6950f5d30f670fb3902c3d409315a40b0821ce8a99a97feca5478bfd782e78767b311f374163f5896b0beb95838e645878c64990385123b61575dd842dc76354bac9c6d5acd9935b609bcccb8463d39225da1afb8911d36e609892dd1723852ab9f82758f3f1e4d28dcf02cb06eed26844aae6882ed44bce44abcd1dfba633418c9f155879c97ab27f8ae238330392be5491a078662daaa02a3d5458b77c549c49be201245e7aaec0d94e5437beca6e5ab046d694e96bf51e04fb44379b2b9b801675fe1477f3e089874a601171d8b68f0202014601a53f812f53e581c3b96312b36b9ee04fff11d9eab4e45148dcc8f0fab1
+SIG: 53252b923ad19cc39784d3a9ae59d62a6300dcc50ac8fd0713cb58844501d8d3805afa0fda64c73ea0f60e6a8b3445bfffe6ca6bfdc87e128baf99bf6268fc09
+
+TST: 880
+SK: 8bc229fc234653b13c924710cb468b8fa9b280e2adb49cb4b36bf59d6fa4a639
+PK: 46146975df6704cbf45320a5e6cb6de813469f3131e61d447bbca1a477a0c557
+MSG: bae2dc7f94ab5ccdcaa8cf49edbef0f6d7aeb1fa8907800533af4492611194e56cef37b1f033303738ae2c3bc4588f5cb3d55f345b9a407e787742a06af0b6ee20dee3dfe9c91d762a3ebd19aed07907bbb91cd776326540ded9f7ff7dda76615f978e9490f406ed2d9116e2093fa785e971b5062d31cb40fff9e3c551a73b20245d46df4d7fd1303a28180172d9a2bf5593c47917b58690917c1fb0e1e2994d1fa97735ae378de6eafd5c1a25abafa3cfd2df7aeabd6e68fc44edf82fc83694e5d841a15b14568b6110be644bf22b71fc47d7f07e1666957d0f87da17f13fcd63c1c2966f687d25dcbd9963f01eff132d5f2b86677816588c123e9457befcced2d3cd1d1bebe8dd8fbb1587e553cbcc4c8762064cd32ef7a1702410f77f15240d7e2bb582c678c0da88ef4522830b143660ac9c434d95772e6eeeed6014ae16824ccdc4df2df64aeb6980b51d118985dcbbd1961f315e6a9433f0b96b1e6351257ead83e05b4cc89c924bf83558ba7d2e7ca37c03179a8f85b831e7217bf4c553838761d32602853b81593b0ebf8e4b9ffaf0ec405b2a83af7de5554daad28b582ee08bd84b375550cae08ae4a5bda71581fc3b7b54498c4e1afb966b4af1d9c843a6b25b34e04cfd9bd2374244f1fe20ec62be3ccfab4edef79ed64e6b71aa9228127c6359ea1c4a8087890896ffa46e0092dec7efbc960a17b770916f954070132e26d98d9774a2acdf809d586df0252f67cfe8d985a3e248db0f90731ace7abd999c746b69648d5c3b4bd61137e08fcc8b2efc5676bcd856a13b362151474c4a1efdedc592cf3ead1ababcd48ee204d27726ad1bda4fe4b09ab51089d016de6ba259ea81807faf211c87e4c9efbf6a4c753e08f780ed55338c0fde14fb99b30722b5594b3abe02047f466242421fb81176c9c4f0fd2b5e7c5a0f65a0c59aa8c3a986087de7ba40baca77bd36ac21ce34e9fe97facc4e298330eece1c8ec623e66a4b0f2342d2c5a02c5f5abddc5ff1f1f2d03c1d4ee9b4b342ed3b1cc26561f3217bf8500e08f027571c53c9232605a53f2bda024e39929163a8e00791ac0656bb0783825e7105ffa9d90969dc094af46f702e85cc11e442b3d5534c1d3275207d6d29a942c358ed5fa07557c3c014cf541f9aaeea6025b41ecdd848512ba25e721e43d329185f8f94892e9e2d5e7cbb99e7ad25f69e5bef732cfceb078611553cc78377375e74e66f1b9d8d20
+SIG: d243b87d1397d594139d83c39acf8501d073bd4be718b4c206980729e720a4c5b0ea91a28ea12604a987e69591c543049f2973bb91c170213c32a64a0fac8204
+
+TST: 881
+SK: 3edb50ff074ef9717f4fb0b6ce252bf4bd049c9083775f529eaf51e975cb3245
+PK: 4bc21fe03e679abbfcd8c5ea2bcc4d838a787d4840c3bc39de4b04c417c768a5
+MSG: 975ece4e81f0015f5ac3044609d0ac3a8df9145b50c42889dd312f563cf6126e36fffaf21eb6b84fbda15aa85c66145f7541e5b41a8e81700be356224fc109327a6919665673534f5c8a4a001750b199dbfd630691af552d4d26a9d9afb33a16af391154124b53426c9f695057b1814fd6d310298af6c830686a4a007a14e0057b72fbad5b803ad353d1c3fdb890a9c81808e89f229187bcb44fee16a4ebcad5eba459b028272a562c05079fa7ae3ecae804a9e8c4f3f315813c5ee0841bbccfe4a95623b517a4b42b2c6d97a3bf26acdbe2e979633f02aac466526a3ebb14da19bc95f2c3fdf6bdb08be8bde97a864c907e918c679ab726f80177145840216b9dc3f981ef17874f08b2fc6611a6346c3da6a55ecfa753c9919f4f19e3c79093bfd78f861598e4666e1cab688e4604d46c9c582eadb92c988f478d160f5a15182b3340201797d0b955282e4a217b50b14b10c9f49067ea3e84e5274dcaec74474c5707c28bba0db8cde3e838d7313c171b85ff2b9a3d2b167e9061f84df3b13bdd08b2d501e53792d68054d048abfe3bce98d978256f2fd2c6c4e76f39688cccf0fe149af9d347e7b040ef241dd5a53eaa5eab35a18c68c754a06b03399bbe56a25268c829a5ba82b28192041d3bd244eb08bf78e76def87cd09f32beac9bb639823b36967a574d8960d1bd03435679d93eddc558063c540b9c2f609fed2e2e3576d19e6209eab466c206791c3aa199623fbae7d3497e80fdd3fcbaf5b89110ed72244234be85cca4b27a09bb70a26ece4eb8dd970a26e5b04361fa50e90380ed65f414c1be9f5064f71429116267edd6976422ad92deb2b804a92e81c9f6522a0f3b5d8ad36b4f87db516a22873e6f27284f2ca360a2f40ff3d8e23dec8ef8a17a43acbb61271a727cb8690d29bb82016736b31026201dd3d388d2c643a73cfbd0a94e20551fb5f8e1ffc39741272aa2308dc8d2133a3fa9cf109796d69d2cc8addc44ae2527781ee993af2a637a872f02aff474a7073f29d9c89507701fecbbfd5101353537eba17c29669dac0427e38e22dfaac91fc20d9e3fee791f462a863bb1908fb1e4204b68880314ddacaaa35a17af5f57a399f1931e78f5a37454fd38c57a68e8d367848a97345189c70077fd1aa0754e703e352618063b9e3faf3b14b5f0b27113633c5d17363741e96a67e816401e8098c17bffe9c6f3587646f40e9fdb6819fd22a743a7a6e10feba11
+SIG: deb3d9fc7b2d86ab4b926f99527970abb51838bcc2919e94cda3371fd0e7693fe37e0c40e1233b09ffa903a034dde287c0237dc594f53abc87844869dce92002
+
+TST: 882
+SK: cda4ba93940aa0c0c3150b3929b95ee7769ce43fd98ecaff9c4a509e736d5c8e
+PK: f4c7a25f1a743daf41417e47e027537f24f481bd1a75e6b1d33ec4c82c55a2d3
+MSG: 3a1d668c6688414896a7697f3c2e431098edfc457e04d2da869568ad5b3310e59e4c727c903cbf1817408802319a8c231b58023dfae494c013af0fdb78c91d5b457f8c47a3dc31d8c8594aa08f146203fa2c28b3dd796a11a97adede6a7a709b5a1918ef1bea83533c783473703356f5beea7fd18ac44ec6890495ed170d03f15b418608a7d9efd52fa10918638051c448d98d5724f567c8c67fd5b6ec8c3d636008b9bae5e8b1e984f8ffb8b64beebd6345a105c1c1083132fd4508d6ac0d4e9145501210e517d9b22478e215b602599f803762dcd5a409b3460e7f340f47ef77281ad2383de08c5b809538aaec922bfca0d6752f147972646d0a8d8340772c871d3b34abc06037de3ab4e37129865d5ba70b6f3cc9a059efb7dddc3882f4fcfe13f448c9bc664888589603ba98683a93b4b3b1014992a55c8e4ea1baf9cc00d1badff5fd7f5da5e307fbd1b4c984e0fa0edec5d30bfef5f477301263b5d752001b85dd52df3b4a7ac23b930a91c0a45765a66488d8eb5901857060067b82378188549288ddc61831e5b6841b344cae2250042219cfb4ace023e691f9e48d006e9a07c67d2468f93593b4afc161c0768b6ceb744c24c923da34af3d5ed577cc7f85d491560f4c0bcbcd1d5e3421bd1ccfafb373d651bd61ed71c09e99f612001704d0c630d8547bd970b66e7f5ce7a014e0ff5a337dc5c56a99f131b9129140eeea39397c48caa9a8086f9fd99150be7ef87b6d4b94b1bd52878bf3bbfcceacc2cc45e8971c3a4d4a3eb86af9874d4fa5e7caa7f45d1553ffbb41645bf0f5e9b29772e3dc081b25b52e1cb7e2167483d54fba690ddb29d5462d2a27a35d85f007adede2a3dd7281f654336afafb7370782b29cad643d9d9db2f05f281b53e133ec30eec09fb0d061b74581a2bd2790b137391f19328880f64c53be700d0faddb70dc165d2d62e671eb9449a2e6e9df2c16d8f49fa4b5b84309f7335133dbe872c5a8fdcfbc4980abfb3c9597d5d667ad2f688c7ab24c9e440298d72b28b0fcde9c6f071bccc93e8ddbba7b60a0b544a2e06c39c6723d4f7dc185c21135fd13a72770b976119e49a1f81ed476be07c443de0b0ee76fbd919389328b3eb8607bc2fe38f85745e28adb7482b701ccc6690e4ae5a9332ea44613179387dc6fc47c1d1ec366035e991e1404323bdbbf535f1c33cf57b6723f13ca6ca329e2aaa4b46b42607339906c7ef49b32db82cdf6a87ad
+SIG: 31048d334af05a4f275ff827544ea296a4a775fa59efa000c57613fa6e5c493c3a9b79e8ce56e7225b0fa326204f0336c213535ae589177a8eaedb6df8b20203
+
+TST: 883
+SK: 217ecd6a7fcc98719210c34cc2e14f5e2d6b5a22f268c14bc4d8a7f2817200c3
+PK: d59191ce282d72fe3ac45878e24bb2f28c409ba05d76ce9bcf22f50b0c778675
+MSG: 9b5337e78fb382f22ea60e03c0bf3ee4700b6978a91ee6acdf6a409e4918d1684881fa1d118c08c9f6f2ca0cab567402c95010e7abdfe848ae79ba249adcb96eae1dfa0843952139cf49b588647895691a2e9880466b7e77e54f6f60815ebfd5e5748f413c0e15f9d576799bcf31284710636f6e9dc7878500796eed80c8af4be2961952ea80bbed1404bd5dae9e6d05fd4f325a3b83cd4528a0869cef84b4d30e02f941d749a8dac97bb3fa839d25739b97ec374536bdea500484a941db9f2299970658d41148295ca0846ca2366238b6201a48b3e447edbea7a4c8f71020142769e15fa72ae5f287140bc5953b8a9a242d205fc019091f2abed0fda47f52d59a0204ce7401c1829b5857b9a0916fcebe2eef991c413acd71b18d8590d6b6d0fb3994302678c29f2b6a53023f9187e46c36790bce73873c545a72beb553294b1ee5d0d0dff239e28ec63b01e4d8fe0d6e69b1601efa2411f0c0601e7e4f65c984f829f0dc2a8421e7f66d9330537151c7243ca524d7a54735c6e344f1fc938eaeea2779c940891d6d01aa55f40cc1adba12e8a67ad9a27fe63fb4f38dc0f01841925718427255bd665d5eb3bc869896db8625204ad4b02f5a22aaeead6e300471fea61dbb1b55c071365c58b1511f38b09a4671bd66b3fedda9c87e43d1ebf301764e18fc0cf16b2d2d67ed239b393ac71968a903c02477fb2df9ef01dbfc3167de7265f891e4fd24d02c63103519b86a7085b1ec2fb419db766bee7a641a4be429614ab89f20f975341072bf04419fb69be7a9ee71a5b49af83ed322bac68a429ff5c5206773be5438b65e53f609729f4f6a21c1333911264d63927017e8136b4725cd1cc964e08ca0933a561e7e3f5987768330e2e54f8d728f59edfe2c91c4f99aef97d18559195a3d8eb315dff96fe276da7137eff93057ac731e06a60a58bd8a9ae8c7cbaff0cb3372c68daa175c428d52f1073a38bf29465d2a7128bb40074006edcb725a831d812864ef43f3b8667c9fb71093a1673049dec05e09169d86fee92df286008ad99065a2929797a913d0233f4d1a95a220bd91c11dd9c45685dcad385780a0c48b9c4ad2d66303e8de4af1db3c04e4a3dd4219fe773f83a8924b0fcbfffcf264abce32832924036bfabba6546b1df4e3f788ed8ad5c2cd92b2641b47090a103cf5bdc46d8b2143174757da801c360a7aa107fac654b34c860bd54f76bbf43c48478df4fe7aa59cf91d
+SIG: a0b169e8e9ce557555e0334a0de7438e553675489ea4ba9cc63a234d00ded8ab6967a3be90ef69e076db9ea3d5ca23b3248dd25991ee1f4d80620bf4db438f0e
+
+TST: 884
+SK: 08d1d06f3ec29eb52293907b705ec56c5ab354fb78673773ae61253094b89e82
+PK: c1b99a87ad15bd46f6c848452af0fa3ccccb5cdf6e348d816e36c5d0fca66e66
+MSG: 120b35573c34914b373051880da27ed241377f0e78972c98d0faebaa767eb7a7c7e7c6fc3405a4336ef95bc5da9225bbd09e9e11f2a1bf142af4e8a0f924d323dd5a49dfe584f090439c08e51511344d470c6200ac7e7ca150d088a91e47c4c9ff74e38a42a332155d8152ae4abd1161adca934c234ce460af8789e53f109d7d31eede0a909bd193fc8d3c2cfec10b143c31476711bbec27e196a54985bc347167acd233508827bad36e548c880642b86a28c6d3404b511da24f11dfaf6a8f46ddcbc9de9e391597669bddfca6560f91acd3459f329bb071dd80dadf35f0e50df5b10f88d267ac9d3062330dd99a6bcfa13187f45c0c214dcde2cdf9c3ba4d59e633a354a4e277c677bbdfa24191179cbcaf05a10d4078d8add93bc9ed8f6c6c499757403655341f904e37d927750c699c269dc90dc26d005625c3f4124bff66feca59d4abff4172ba3df45a874302231030fa783384f50999e3c4baa5eadb451452c888b519272e90f73c6872768e0de20ee2e5f9502f35e49fecc28b75201887fed2818eff545398392f5e5b6876bc556ac13a1903ada1b9d725b04a14204b599ec33d62b7dcaeea8c52877b2cfdc3558a91d2c9157500a3bb6d452e5e2ff093294fc433cbd63465bb191307ed801a15b85dc2ff0bb38312f8b817a436d422cf4607c64ee7035923db6b96a3899910149b0da4aa3e96685d7163aacf9e619dc60813ce4f344f3079b43f187fa31bdacb9a1d7720b939d5bd241b96a177d7b7768ffebf79044cd2956d6f88db1c243a10fede6814852cf404b2cdcfa774076dc125c70a57c6907e99afe39622ae11f557e7d34b39aaaf45f834058d2fe5f15b5eb70ac15a90a3de5850ab1dcb48b06b6ccaa4b42f857e71ec00b8a3d8974b0bea68fa0f665592115b4fa55572cf0b0738641fc868d4a2e714db3ad7219a823d54b7f7c2656ba5c5eebe3594c7db12298c16251d9845bf2f7800b4190b746e21b0c1a5c47a3df9a059ce0956674eb703decb0a0045437da4da10f286d720d1b9df05fb24415d68e065570e6b31503142d03335a807bdca30892edb5f55f8989d9e649659c0744c5433bfb4deeb11c2626a8650e54d4d398ba19b64f68bed06d7fc408f470ac704e2ac922ac1411fee24543e56f2f50b6b08953dc56a7a75edae430a6df28a227adac91ba26f0e198595327739cba303e9aa393ea6618a84f8f503d0056ee8d87e3796e036cc51ccb791deb795
+SIG: 0b8edcb8b15a8cd074c41dc2a1ba29d9648d6acbdc338314707eca6fb4714c99543b4907b9f85e57eecffe0f7a6b7073a80946f8087553f4683109273a604a08
+
+TST: 885
+SK: f0c85c76b1532e89aea975156dddb1d3d066f6409f841bb4410922725f269d86
+PK: fd75fc75c36f83498d8f0827f01d3b457f8bc4d9dc55e4a46274ddf0034fe16f
+MSG: ae2eb018d48dbd4f210b16778b5bd2fd14c94e6bbf2b3ff85518e560ab8d3e72201f433420f00f11bc78e0e9f3720875b2e9dc11e04325b8b3f0d465ddab21511c457d6acad8f2fd5fdc0d2823fe6caa66a191a3b6326b32a16befd64d15b361a41513641bceba26bfe93bdf854a4f8f8a0b29f7e28262e2d6e98aa24ac27f6f7883ac01a74c40cce947ebac70e9fef2a16e6289e468950e391e9e24ef58e88a44377269cebafed8987d220dcae2d8b126b6bf812167d023d9baac950d9db8cf52de6306bd48999610c0a433fa9e1771cb832d4197aa340dd0ccd0744fc6b62f90bd3ebb5308cab5f940e2916423cf0f3bf080c06a94f026910460dda809374e6457f064f178e308e7a1b5af4def319007d041778c3d6a419f51badf87663879302b53ff269df442d0e05c958d5baacceed7f5f8afc811c18900ee3b0f61e5dccfd5dac85332d32ebba371aa2d47a606f59546e4bbb605a74677b19a0fe8e95f9f77c0b8b71d07e983004dc2ab2cb3793a323c108dfa7970da00db198674bd34bf7310767f76a224e07bdbc62b9d078cbc75367e2ebaa2c5d274bf3427f2a0cc5dbef0af4e63ad889e131b12bc8ca32d827f7260b0449d0443fa288440efd1364e3c9849477e73ee0ba4240d492af5ce13c34561b45010c109d842c1fed1be3fa9e184aaa14064f43f6dea0b659c5b97893cf2a433bcfb1d2a87eb564bd9092c2666704731f83e56434b2a4299650c7060f9ff7e8aadcb4593f609188d8b467646cfe95270067a1d35cd759fe581af4e62602c02ef14744143eb424f2d9f33a60288c1b25f08e4b2f5feae06cbcc2b2052bf384e1a6fcd8471ce5e5658d77f40c35c415e2a9e09fb583bb7471258e7c806f3c21822dd10f56a640cdc00128d3ba556ba51dcaab47c3baf9f0197d3663de8d093e83173325def1e83a2f5f5acf12ae09f3ce96cd888034dcbe6147dc5998362a4bc406d28846ab1503c17c94f9afd903c9a58e1cebb4abb4ff6f2a41024e06dcaad14f5b70c1b26e69f96ecf14b8da31c621f9ad4e30aeb982378671f7d1f2c4b572c41bb8830840ac5ddced881f8fff210c3c7f236d8c5f2cfdacda29893302fde15282db540cb543737dd77852569221fddcdd68d87e2402179d3a5a77734c275a1d560a462f40318bb6819837da3d305eb49b38650efdc8fe409d40fb94cd5dc3eb02738f38852f671a0c41414b76fb436f3417b8ef300921c009ebbd7cf8e11
+SIG: 4218fe4c1dce795ca92a49a6f4798eb5412dc825860314ec469fed45de3a7bf8ea55e853a349584bd95a826a585a503fd50bfe4c635ef183d07301367e90100a
+
+TST: 886
+SK: 18e268b15a2501dd4c979dc103ca6a842216132b3b5081d775f88640f89c8041
+PK: b34e19c1e208fb48a885079d9fbf37c74f92710960f832154fab18570cfb4c1d
+MSG: 424bdcf0b256001439d16958fff648cf7a8604af22cfa5b44331b4dc356dff25cc0563da9d640133acb70b6a1176c482dbc9408cd6793d56bc29cc408823d388ed88b24ceb6621dbac0023ee69f76f8296a7395211685b3ceaa995f0355d9aad3d97358f4a379e5920ec545f469621cf768abf55d2a554c949b0ed70187c2205ad032985c9b5b2e4ba57e0b4a47d344512b84bfe9f3aa560fe6ecfc5bdf8c3b41845293573f81ed3b70edc63a30c70cda3f455901313f6d23db309478f03e34e71356d83fa5db9280cc2b4369c3d24dd9038f247596c391e48b2f3f890a141ca1d12077c69344735a59b1dd4076b22e16189991e5f1be4fb7695af90ebea5df286135cec2a6e99aa1dda328e62c0dfb63742202d63624dcc0c5cf1a5df79e2878dbc71fa96576601af22844f545733126af7d3984c3ed252e6a876445c92259fbb470a10569b49e5791fd0182cfe1c3f88297facc8c31a5332f1f4eb4958db13b6c079aa9c949487263403190c83c11a43191ffec6023fb34cfab2525beb546cf9200a96f5854b2f78ecb2d9a53aa9d287a90d4d410a63ada0e975d304d5148353463fa805b4805fb4687ed8857dfce4bc6e80833c8f9a79cd4f029a2d802bfdc819ed0c0ac8f21023287f2b4bafbcc89993fe46d52a9c6246dead617df797d48ee985f0f0df9aa82ea20e0d0db28a254a9a253f39f9cf01e3db8f3ebcf7cb97cec58c4efe031269b4b37e4cbb361f73ab4b4980bd900849538844c52cb3ac7583b8f89653a0de65a8be91582c55239cb8f5d5318a88d160e1c871e5ea7e75f5a69cba8538221ab42ce2a2c4d9c3b7ec857f230d573731133686ae8a7ed640f42f31029489e4e6af2b3ea4c7948ed537c0c5906726c2b625fd5f949e3a7cf3b6e998ec761dd6e2b5171a68749752e721b788c3477fa190cd6ea81d579dce6462d9c662ad8962e79338710cc8d2738a5fb04adfdb3f1432cfd80e2e967da000d83a0fa85abae2952f3f3683e254d868f4bf809eb2e300e7b209734a3c894e966b16088d5ed354bffbffbbf2ec2be93a32a8be5cfa18fa5653012edae5afd8709ca55c0cf23a550d34ca0f32d8f666fb47a12f2b7353a40c5379f75366c13f4ab9f14cf80a94e1f13d8b09b76fd8d14ffa538f31fd8aeb49d33433f4df7c2ca67399579fe99078aa721d6b6fc0c50e8a91fc71ca25eac1376fc671bf6153e720b25c7e97a3d4ef8442ac67acf58b504b67158f913025
+SIG: f2dcfc06ef1d8eccd8e40bdf01307dd19683f214d4f084e6b6934f637278300dbb1889f2d37f53b3aef26fbb3e36bd75985fa7c8ea6ddffa72c8e406f24bb20e
+
+TST: 887
+SK: 3c393f9df1fb0b1eec09b7f270b85982ba0fd5e4b1795e1a7fa99137fee24d7d
+PK: 974fe23730fc17945670fbc1f80b93f94593c8d44bc75d189a6bbfaabaf5dbd9
+MSG: 54d8b8d5fac28cffa77a0916d6333c16edbc8bb74aa06e56dc00e47e3929e40864b8840d912079597eacd81dae43e2785dfc689f3e85f8c66581efc5e853d1faaac744400ab08cbdb5d16146fa60f99905ed84fd2936dd73f4bca2572b7cf5160560ffaa68da7a67e40e08a7bb7aefc4043ebed5fe80a414817edf2c63f62fac0d47446ed0bb584058f4872fecff621559311a270aea37a6296864e8d168bf1e2f55cd3b276edfa612b5d9c3362e618be6e82a6e5f82667924f3d1d3df825f9d23f4d6142d3100dfc70f70603abf3fdadaca69ef6a18ef9092b3c41ec658ab27216fc6147a080acda60a841984ee83f41ac42a80eaac91fffc8228391ef583ab3eddcf876523c20281355300d86c11a4e7c1ade8e50560f43906c9bc8ca5fbf8339fbebd02e33e8518bee5e806b8c10f8277f410664735a2bf556839635492452e6ca079deb9751cfc6797f49bca9613ff2e7fdd3646f7c5236a36bdf0051745e595dc0072fd6651d57627a6004c0f0cfae856bbc28a1231cb839665ff04152ec31c007b3e2ed0a973b24c93149ce701e6fd6539206ae91bec4ce65a89db26c7d38cecb8919f96fb6cb8f6c1939d90fb3f90b887789f29575ab20e0b08bc358153d8c03521dc891870b5f7eedcc1e62bee7da063ae66ff0a4b7d98d1cb758f69743c3db3ae2a2c9be1be094f17cd28f92d8ccbca983c749c75c610f840836e2c430ccdeff0afa54444f12b4a4f002c609451834244c0c07df8e12202a65f94447cd4903acb606d7725a86e4a2343984e679c4af1b3679c755ea50d0abe2fcc0c1c3351a9ee196b4644c424222be99e2fb373f9641e3faebff43170eb03fb8ec4557d151a55fab6c499d444c84be89f2447682de4e6f6353475efcb8fc53256763a948dc75c515fa353545d0cbad29df5e9db5cc457ed3086cffb3d75e846c4e8d88147fcd0d8aa5abab49b5e05c3d7feef637943347ad3f492ee356ef34881cfd85abce8a144ce7761e284e8b8cb08966049047a996e23559f776b1a9f41cba3954108486e2927beb6433a36ff8b2f03aa74b3d209c488e077f924f231e28345942c7dcc2e61d7c9b522b659fcb53662aff3648f66da3e83e59b0daa90b94c515dadab10d5a839cb3a2f1d3cd092de55d995138c3ac0b907af15ac63ec1874114327e21971345ef17031d52617e784da3771439be2e84148bcfea132bde10e6fda547dcbb1c4d8f74ddce1fccf8213e0da6e97b81f75
+SIG: 22333e56410fdcbf84f6a8de741337691684495ba69eff596db9c03a281210881e6c91efa91b2183c0eac916152817a78ca724ba7c8b51bb4caadea9a341eb0e
+
+TST: 888
+SK: f8669c88f1685bbf0480cc9221ac2ead8f551bfa87ecba2fd4ddf3ba3476ebda
+PK: 34723fb8e253ad9c71cefde03628d204e535de479e1048e5188762a1f337fe5f
+MSG: 5b4941beec2241c9fb76d8484f4f3f3ab4ffe8ecc8e7aec76de2ab8c368584d751b0d3feb8a1dc8168cdc694968f66b2a0b052afbf8be3a7d95163e9da9141c59ca55976c292c5c74d31318d6a91e7817c5a8b2f812118cbeba3a13323cd9748bf86ed1a85dd4ebc0df495cfa3d4627434bf14aae8ab6781467a56d965d10e6371989dfa0f6bc0f7859f3771eb9004b34367db2705dbd60fa8f7895c1eadf59f53dab168b4f9363979025501ddd9680debc07cd1ca4a0997876e9211f307d9b7b9d904e48d2861a778b879ad590a9a2f141bd568e3a1bb2494628e9ec0c64255aeea6f0eedca30ad38a1f3ffec3b2b5e942e21940104e914d11a44c00fdd47da3e5513aa8530aee247c95ca66d08a2608c75ba9858da14f9a8a32be713d309e0f584c81ef5be040e0065f07b775ae175dfe2c8b90a88ccda17fa4f21c77eadf5d25b6e404bf004479e05a01ac0042b89937eb278c1c34f33028db780ba3b617918595a39c0fcad674b85c40cac8d345b7ca0bb48a28e66c44d8bb5f27941e40b0e9c7097976c62dfef50c98f17566ccbacc87cb03b94dfdfaf32f1e56ffa639d63611e213cebf54cd0a3e2172d811c0ebd75b1a8646264dd8b1abd46e548972a1b262cd95d511536dddcb49729fe7bd00b3838bd2f20a142640edb1b6e765b65da72e7233261c8892e2f4949bb51f32a1a5a3ee149bea26fdcedb991d2cd126637e2971e9b6f0b785df28a48f301707349423f44e8462289d725498230489df1b51be30f08d7e3250565c6ef824bc53a1ba74a57a25c0686adcb6c825ab1ca70c8a5d46dbbc6fa607461e26d16fe93bb3d3a943a3dc05f30ea6dc8bb12d70821d320f1adf1ceba4be657194f7fccd21990f8629d744601cf52ea6d9405aaa2878f1eec4003b45a4218d8f80bb0f5af047326487752e2b76d68872520bbeae7b309d78282a073fe0b1a1a7a98da23df68caf8c2699b1c7d0f47bd7de2c0bb23369963e68a6974c8e2b595b8293a9f4d98df7e9ae3add2a3f64e83039739642d192204e85e6c48d5d671f6c75a0a8957edbb74187620f2aba99c1c62584c59ac00647e3fb40292b9dc1a3346868553392fd3f11d6dc6f5f2f4e85ee25125cdd644743c7d45281edac6384c77cb98a67d9ae6fc9a0a76b9f6fa696fdf4aceab5f794ee521b1e5a0ee57af53bdf176801b4f45cfb3cae3287234234b77ce21edf8680d68c4a8eecf1b03537ea5699acb562777e42a486fe7cd
+SIG: 3746da6cd8ca108beef06487bee63584f812c8e0695fc863b86e5db132380b62ff8544f6f374825b0e3ea0620ef854c1331114d667df1f9ea776c3963870290d
+
+TST: 889
+SK: ceccc68311fc45b6c2a2f1ff9cdde007ec787fdf25d02ccd2a1cad9de3fb4cff
+PK: 6f804734ef92824180da71e55cf3bf1afef65bcf560962e0b0acbb2d8cca5984
+MSG: bac186d9fe5abda79c3a35a7a3c2eae6ae6ab28247912770c84efd048ebd3aba57c37cf4c6c7f30a79f68a3f76b20cd8c6631fcc96670522080e6b62e887ae6f4436d4caf56943131c52dd282b251cd075f1f7f8e0bdb6bedfc9a0796f5579042b56e69374961b11dfd61b12de2bb7d49bfc509cdb3138f3356a0dded98f5301b7c4a748bf89b23df4f7472ff8b1f505d765c6ff82dbad74b9d7aef22fbcca0b7f35042f9a762bd06902bb21c7f9f7f66bef38901d75012d61d744dee7afd89fc7e908c40685bd440aeda4204d006f26307d82a496963115f90e09f76688291f4a67d6411f76d16617875b2b9982dfdc5ee9b83b9817009319110b5404c63116fb6e9464846fa009555632f076984c15e1f6081733a0d46f2d6a3cebf79ed9020c9dec8df158a3341f39eaa5fcf1cf42a94849b2352c1a1ecd4fb814c20d07dfda312bd4f2f58c1576b4aa315c96c8786a4cfbb736b2d23c38b1d81c4644ea36afa076e055be5917cd7a92350a7ed66a5ab2253f55c4fd1a0d0e6d4edab5f712edb440c06fac8f07e6d73cc90b2ba713d73c73802361ce46a4eb5ed1060c4cf53207d301f0fcd4f0c9d1580db2fc1059d372076438a01192a7f9fd6f7883f56422866fd9f0afe53fdc910afa5a751cbfa377592579165cb56dc3eb4dce67e3db33a981a56b7d9f7bdea74fbaea3478e6ab2c644fd777b8bfa72aa0f0a52198d36e5b634d2c9a11b7fe0ab2f9a40901c5b148a0192e95a170baf7d5350fe01e569542b93485a41971443485faf57f67f56dfe2c58e539c9f9b449c3f91249a10c1a1be7e0b3eabe8ee0bab1f11f89614dced418c62a07a0b59a1370d6531ba177091c6ad595fb59488204f63344736ea1017affbeb753a99786b1eb64510e2e717ec90e02744bc352d3f1b2ab7be0eb65623d04fb3a046ce7f4da697d829828a52c7b043b2a82ec97fb041bf519b4de316f4e2f5b0db62aed0eed95cad4320c1947c35fd8847a5867872883561119c01b0089213d84db99d439f0f6444d8783dd4b64be3577cd461cf753c8e61c912de2e5d7a7e2baefa258975d16ef3117da59a6c893f3339187df3168b89f0fb0b2198bb6f1594bb88f3d610fcec3e36de04ae10328112e6ff74f5a8ce68d407174b4c0691c7602eab1bb10f3c49dd22b8450782deae9a7315e3b88de79cd15e6c9268165ed3a0fb3f89b183e1a212152003f32a2665d37cdd7f6b56c2453e5580c4d21f9983f38798e9b
+SIG: 3c4462aa47010132dbb26311e444727279edade15a4d662cf647f3275cf3253e6de9333830e0517aa5fa7bc2d0e63ea2597a94b0fe92706ecd172c5ec5c7f006
+
+TST: 890
+SK: 7b30b42dc2c670a195fe2af879fc5de374024588fe3de43e2dd50844f48f42be
+PK: 82a2ac6079f212b5eedd0c19e9394fafacd74d716fdefbfc6cb8a7eaf41c0362
+MSG: c6687aefebc5c816d1a33453beca5020d3a97cda1dac5662f0af72bad444e2fd1176a7b04c1bd09d832618209bf3e33e523538d6daa753046e871dd3b3c7acad33e79c1bb7896407865d168d4bc3757bde4f823c08778626f8c71fb7cfcfdf03a82497bd8be7d8f8ef649030b5f36a339459968e246a1e420853dace41ca850a4eeae834ae119610ca4cd0662aac39621586998027ef2f61485c028506714ae09c76399d873e808158578aa59e8212f58865319f9e0d2b8da7ad529e0ac1f1eb435aecfd35f5abb92bea5073496bf4c0bf15baa273bfc5c3104474a2dcf132c333eb36ec2cbf04fa9580b768f5cea7b5617e5880aff63201c274d669743e1bc556b067902eee29d29111288969cffa879fc9cbf66fbf9326d9d925ac4102fa9f1a06081adec079cbc96746d79b63a012ed77d82c9ffd4e3f161f6cea28cc23fac2a543f5b1d0644ec04838327bcc652b858f93ff463f7e949eec8c9db6569a86984f831df6ac6d95f38f46cebb6e6583657facd2108dbcd0af23ab0101a1301beb48a44caccb91094473d7e5a5c88c644fd3420573b678f17b5174cb14e90fac694d1dbc6c9632b5974aef28ac08d720b2ea30440d2afb0493b40db24efbdbf53c430921e52a10b54661e149d165591a7cf91d6508ea472fb3be16395e30312f19b87c47e46804a0fa29b56b5ac950677bc60238b5e99e030b1e552146a0e88c294cfca835c101c55f3423874cc128756e73a5debe8e97fe2166b65cb44642770c6d1d2390af1b0f31b958c830e9ac4fe2f5ad590582fbb892bf949584477ef7bde23f7dd02b63f7c29088a57251009132ffbb78ed14defbefd9fd31fdcab03ba80a23f333983760abad4f16ddf9dd4414f04d00db56ba72d63a3a13d2c442f549fd66c988d2e4601d13b52f77500dd692bec9d6bd3bafa9242fdcfaeb69b98b0b5789b2803840dec637b49af4381ae3fa429fb53461a0c674eb5aa18dbd607a2b77a96d3ab464ecd97492f6de460c9f11b5c1756cb59cb1348dfd77956b71907c54821e303cb8b14906c003e3484be4ea05a6901d69b07485e858f7b471c635f90395b9a3e2247f1ad12b118ffafc7221a57b10e319b61af1c13606a81616ce3f1d62ba932ff4e63e74b84255e3af5210bbd571bda44cbf44b714422cb45c2ef21f98131ba96b7edb9b03e33d7d188d5b8d904cb4136fe269db146988168e7ee245356354f002a5ea8b35a3a99e83a13272274144b33a60ca
+SIG: 0a63b84f46935faf3ea164b00af227b00868a03f5612935e18619a84a2e57b8851d746e63fd9100787f5338d51c1073c2fc5303099e1873e5e3d3e5c036fbe01
+
+TST: 891
+SK: 6656f4d4718157c4bac38ff7abe5eb1f812c0b986d9c014abad5b09aa6c8ee4a
+PK: f3087898e452be9e30aecc4e8ffe0c01169888683f62a45b8da38299014f5b4a
+MSG: 94d9e5e5a7b705d9d976fe71e94d3f7fa7866afbf7ece424f136327799b2b206ce4ef4c3f3e705553afc8fd5c1952a4c16658d4a78afbb9a97f27193c65b65b82e8f3b71515fac82640e0f8a5fb35ae6fc6a3db051a22d4a5300413e6e33d19c2013c2983aca8ad6cec2ce64a814164f061a1a3c5a8610a7650bfb5423d4362ce02206dbe4a6fa826f03b42ac3cd9ea4c651401b3cea82c3993f6af8b2c9e2e6ffe69280ab3f09fbe90dd547ccda9d9e8e8a537b3b360554227ed0709f293198982efb5efb0e73e00042d1a063b57452027dce1a39e4b0068f58b111ec5dc142bf419ad893d54f4260cbde7628f783de8496380306a4eff6d82869104259c94c54ad5aa8b067c42496cb88dd31150ea04d499bfac91f4bb3e68af5af7a568a3e4ce7f170d98601163f4952f1d25e12e00ef0a2d8f111afdb0fafbad2bf8e8b9d49363fca68183617b541270dda4609b2616729ab1b8c42dbdd7bf986af8fba52e733e42ba03c892e1e1ec06a90b163f5a79f6165eb7316972ac1adbfcf1dcab07847ef82c2cab1015dbb50aadc79fe11c832098cacc39820ab085b6963bd42160ed6613bae5e201f17c0fd7f32357ae350ce9cbbe926fa42dcbd422ac1bf09a19ad1f69469e4d1dcb124118ed4522d353c174298650ff88382fa2fdbb286c45b18a9baf6f6763ac20c9ca4767d348c4b8ded630076657b85b14c11ae2737ea29a43515b7f05674a0cd3ed4bf6a3d189ae972218f877cd8aa69499d5a08c99e440694ccaccdf1f642e14e90105bee6d98edeeab3b4f339f300188aec0c16bd64521d9287398e648db94330ed8f6b9ab6c7ad93ffc43e8792e637c61bff7d856e54ef4987384e312cb57017a50eae5952abe19d8999c8c82dfc45798cc17c8d9496bf520ecc5b77fe284915566c45685c304a2acd525ef12c86f38aef554d8a2384737cc4133fb7e2b65c13bef31668a6c2f60eecd8412eeff7f6b605cbe95083e233ec1a7bb36de236c8a71ba2872be946cd3b38935f5da64c8fec8e14f45ccf6124bab7f70567c2f2bfdd56667609572037c76146c991707659b5709b074e3451f921a2df283b96aa26ab476625016f181ad64c9919cf41d714a1a9a5e2bb26baf8770b2eba77b778a332677a7572ee3a2b1dc05f7356bdcae5f55e35329e34caa79430b270c036160dc9fcaab5b254543ac94b24681f17172b6159d16621d7ad0eebd895a1e1d09b916a86fb48e4c91661057eee95c0870ed54
+SIG: 9c2c39915aed6add004e7dd684ee3dcdd10d87a487f677e73c2bce0fca7d508796464150a52a440f5237850a009c72162d9d2985470a33490e66d3c401704c05
+
+TST: 892
+SK: 14383e6e5604c99c248d39be51d164b13442b05e51d78ecd999364221a45036b
+PK: 2fc16138220ab74b3bd446f8a714b58d5463d40d4367925007474c5b9e35d494
+MSG: c4753b7f7a6f6dea2515c6e3d29561506f4f36e0de84999221f228e20bd5128ed93bdb8d1193237d8e294169a2bc448af9dd36066301efb7fe1231353c0623ffe1115debb6905ac6946ee382a27c3c09e1b1f5c11493dba37da0ff6eea75d9fab0ee926d701dac2fc5b7ef578880a5d5eeecadc1f4bcc4cd4ec6f2f14f52a8c164072e6fde5ab2ee9cee0b48e51af055f9fec7c63750fedf72332b23863a1e54c52b461a21506dfdfc63880e22d89c894412666c929821c0e439e745415f717969e6058554d64b947a4fc9d16acae3e49aec08801a09d972f79ead68d529768069735caa742b45a5830581b80ca061a6c1515e3f7d5a9337878c19fc94eef22698ea6c4d05f9ed411b6b8f052b5ff15dc23a64beeaae99f84893de3df940a4e0b8e993930139052d99be47bca8775f8563bd4026b71343d51968f2337528f4c9db8bbd0a298af04b27695d86b7f7ba6c4ccc6273febcd8f75cff266995244fc1fa13d8d843f0bff49cc2d508f4a2b3aad1d95fb22a2bc6ad1b966b0812d99070bba07c923ee4d08107486dc01a06dba6f1d5f105aceade33b166510e427ebbce52a3e7831f0f78a3c6e072608334d8021c338a73cc0c47f19c9fae403b9716d0d15fbdf6466b08f6acce3f50a703b1dea8d826df842ca1ba20d29f4548acfc754cf011f570681b59e4da25385ebd6d5c3adc930529e166ce6705f6010210db106462b3333204e7adadee6606a56206b47eef2074b116e22a615418ec2cdc331f1e19e07e8a37b92d69df0734e085daeeb901ec6e8c35f103f1d86ef0d2a2652b01d183597e4cfdeedfe5df9a7ef66a1c796a37a27113b944dd7ba17c460015ab8ace451c57850ec6c290c54e5113f55e99a8e6e4711e3b7817bf91a5adb37fb9461be6b1b55d586046e42a54c5def4076f1ff6c31b806fc602474356aa2899eae70f5e5abf1f75a7f24c134cde11793bb162e03a583d5be046acc73456d12d509d92f7705768686f6c714a4e57ec88b71398e23e835d6d6547225996b7ed08f3b7443bb17c899409493d0efe8455bec8e8c284a3b149a5b4ca631ea620b1bb817cedaba50b044411849d260a6f2a0d3f2cceec3842719a5ea4fe18dde0d42dcb33ad21e6453325af6f3c009f2bb978d30ceeae9aa4928bf73767cda9292ab893ce5fa3aa4c232163b45c64ed7977779b1c0cafcfc2b9fa084a324f113adeec218b4735b6b464db6d46c2791af3455f1ca5ea1e9a048c051a54dfa0
+SIG: 45e8ed1a751dfc3b9b7bd7a10bf5bdcf8ca461865a490c105f10452941cf87721214bfbf3a35606b7ce35d6f70aaf2d5eadcc0de035e9b2f6d7b862fc2849004
+
+TST: 893
+SK: 59b07263b22c0a38bbc591059594b2bd927e805961dd07e1f94245b23aa2e016
+PK: 0b1e4cf5aff278ec65b405f5108e1b5b18a969ad1f1e6381912c82d698907cba
+MSG: 08ce0d4db5c2aa500a19efbc8dc8549250f7dd46a7a9a5407417b3d51820e4b0d61275583f56f897fd942bdd7311ad6baf738128567af6558d75906a02c4343a9955d59b11088c588dc7dd08f67965c5602a56928dda4ae164293163b517ca17ded04fe4ab2f9789130ae96ab231f07e09015b78f3848cef435db0ad9f35e0fbc9851e3ecfc9fb186d14d8da4dda45d0b3eb3ee4500c101e3194b572140689cd75da1287b254f374e3d93326ae5faf114018ac714bd00375d92a8bb659c32912831f4f20776e9e2c25029f0aff39fddac7241543a0366b84de7b1ff23e8e4dc093df0d2dd5e53e6847948cf3d0ff3f564ad94d9cc00a5ea5b695e408bf50f5bab2f6ea87ba8ad3a1940195cf1bc2b5b34847ad3a5effb8a7823de91ef1633869d1f04643af4d826a59e78b9d186312b3d972263654ac5587b80b717646f31003db81ac70860d3fc8cd3a6a0a0d576d25731ef7b8966263d7a05b55009e8a23dac0f9a21a24b06e13900e444446fdfe56cbc1a026df41066b201b1481e56158926c0c9ea90f0c645aab4bef12d4e072cbfdc3c3d5e0c72cf88f166de048874f3534e040c62b1662821bdd16b0e8582817461cb2689279b446d70c8ac20ad03e598cad4908c52c350d4243ee8aedb87a4af977f7db57cd947b47d6bb51409d80d81f6db03cb9a6a6b79812f470690afc1836a531338094cf26d3c1232fd5605d8f8c55b6f8a2a7ef1e0c78155594b237956d2abad6a9adcd58e11ccd35cc995b9a0aecbf7f5741ac051b04ef6b9744b56fccb46398528bb31fbe84e078843e69bf338898cdef69ad41872395e46b593904825547e00bdaf221f8fa587ea2037ffb9ac9307dd3f8f35ec5386ba966333e2ac8727b0e1b80612d3c7f2cb88baacadfe2163bc38c88842e76a394571d40610e8a297602793763296e3eabf720e984b2edd28cf5c4e0f9a0f76aceba28cc1f1b69ff1d35b4bd3347b7f9a95a4c1ea10734e1c918eb96249d0cc70b477f6f23809bbda901d53f485a71f5086002c1b71efcc41cb1aeb5122a3f3bfc96c51a55d75c02984288be657887854cfa738974bcd5440146f9bb14040de54f5444ad43b79af9bdb24ed6a48eb2fdeed71f31f0ece102e918e95635c7a038633ee348d8b5781652d5059d215ac97f30ea20d277ebbf15246905428a7bec02b8f926315bad6723fd64d71fc95f333364cbe90d4646333c40dda6d1d433b7c195a758dbb4038af5dcc7232d4547f540e394
+SIG: 886da33e3553285ea59c1431b6e86ea49bb68b2e0efd2b157e7791b74f35a2421bb359f3dc1e4ce5f11f73652e03bfc0b429c58f0f2d7418c7c20bce2e2d1901
+
+TST: 894
+SK: 5cc115d839e058cdb6518ee9c161c004d88bd3908d3cf6d52c8f296a1a076b9b
+PK: 1e8f3305bf2fa11b17d92416ab0ea762396d88f2f970ef0b100ed3bf5cc13440
+MSG: 533e49c1d5f33c5ec4be84c619f4ec649c25fd70bdcfe257a63c3373a4d089c89af6eeb7160dd77ab66b1ee7e10850ab4fc1f35132332b53789b2b0140c4f20f97f2142072d624aff7aad324aacd068c035aff52fa712f4e74832de031b2642314d17110dee6fb85762dc30d7e97782fd1fbff7179f00917f55af7503a5b7e23c6eadb65e104f1517b6624c9e5204b3fd29a6585e92ce3a3eee2c5ae177920f7b4ab2cac87d672ab6baac1186d904aea3498534eb5ab23e4ac4c0ddb0d82a5ae531d76549d367628577bac4235e897d9fe205522047d214ff6ccf311c4e397827d97f2868e70ac17d28e334999744d359376a482fdcb414b02b2687b962ee8086e573fe000dc51dee06879c684e25f94cee5e861347e7be7fca549a0f765136a2f4b88fede07024dd2fce1f6d0c0354da1a16ef366b315b3f7233031f979b70eac6e23bf3b349efbd0e4f53f4d5c41fc004276a59670659f6905ef03d2fc098d589fcbc1328282fa22b10db83c5d70865994fd19d760a39d476e02330d2c6d19e742267dd365bbe1fe5c711a95b184508ce48c1c96d7e63990b408d45089be79e32f9cb0162fd1e7d0d19d97d0ae78ff824cc6989486c0bd038352551f37499e9e9826804e9d2624ad0c7b7534560f45fd7d324b8e517e01c9b2743c14979cfd512bc3fe667279b3a277fb463e9d7349b64ffc9fe60884c21e481081ed70e6da5a3539c448971f0d9787289fcb0080f219e99449f8298c42475f87fd10aeb509c530cf6a57748eb8f3562161fa4875ea953f09659c7df7a9950f0317467cb4e5366e196e32f5e2696733a25eacbde49210490762060ea231370d4090429bb06bb867399e8d37bf5d21a0e72147e496cf3b7dd6fe6e5edea9668d802190a91c600e29523f8eb904e48b70412bc10a7020984c5ff0f5f383f214ae594dc85971e480372848d0d7e7cc5c18ff88ba9b262d7884698a41c6c7819c0319fdc6bb07b91dc1694dafe3af37a538bf2b2d8cacb27d24cdc6eadb8c6a2e6b7df8a4654ae937850c890ad930980afcc1492db8a0168cbc9f10657eb48d2ac87f5175d23caed4b5e6f10bbeaa5e33fc5f6418d63ba374ab1a3cbd36b729ddbdaba989d4645e3a66130bae417cad086dadd30843352514c375f2571abaf93e9a0771fa103ae92585b04f55c434769b43d6d22f753f9306036e53524f6f4d9ccbd2c30317a8e899f316149035894da945b76d9082bfee328e7a31b66328ee8b94e068c7
+SIG: 0371c2d64c5ec0c8276ca5ffa615eff42f9efffc58dd8ecfcf67620a9bcb38faf118932bf2cd5b9205fa551334df2a757c597744f791f371fbedd98b21f73405
+
+TST: 895
+SK: 75a503f48ffc221617672519111bf90da39da9eab2e2914fd3755f10f5393668
+PK: f680cc0f6358cdcf537aa71128cfadfc0f3a89c100aa34bcd2427e248b6ed50b
+MSG: 7b01090423236cb4b13c4177fce52a7ff6580588cc2eb5a3f39ff5d0c73e01e01bf7bd74afe4151250c391426ea507271bea1d6d85f0b2fe35c40500f98d0656c6388fc9efba1837db22dfa29d892676f50e575fe89fd29389d09d080bad67ba544cacabf5a7738237c55e2875ed4916302a2b4dc496e74273bf05191137810e50e48195260bab6d81f9c80562ee73ccb9333cd9b61daf5b0038a4e6c5c958a91f68508c1d882519c1aa4ffcc53562463a0ae30163696f84b97ccbd8679820edd3617e7b896eeffe341ec6b5b03f73b625d741c655fe6e82d11d478a7d543ff6c0fa3a3a8c94a616fb847070d1fbdde6010f026b089cd863c3bd29b1c4269f77659e515728890c973be87f0b833ca5af6b4c3133ad4fa4f91655c6adb5b7235c27fe348284f3f13366a6a03ad22b87c6f5584bdeaea48c70325d6e33a475f50511063875192a87edc388089b84395390c2a3ad89a22595dc4a715a42a2c0efdef67b354b34fc75ca98df913e759e51c7f625ddd598ac22d421decb57bebd54220ec6daa5ece769d2e01be7b6bee2ff5a0b06b32d6da1d7bc057e3abfaab242a3f7e6646a159e4f505e4662982b13d0cc1fba91d10309a42dc1087cf10d36e31f170615a0acb508bf683e2de00c87640d304a947bc4971ff3619c72abd83c7b2cbb3464c4040c2662b58508b74680cfa6de06e8d21e3bec8511199312680009071f706b7b133a2487d5745ffadd5dc0eb2b553df440787f011dda37719fa71315e8b291efd77da3ba14fb995f03571a3db522b63c60be5619941699b39222b59d0f23e5eb37ead4b7f750ed4abf4db87c70da665bef4d7a2921b2c99897f2321c9be6075e744c8228639ab736dbeb2beab440c156a39a2efd261db50855e304d9cfeb99141c613558109f21474d272a2d906d4893934aff8e08a4fcee964a5cd00732fd33af29849c8dfca65979421857185cf629f86807a85973d3440a6bf811a58d041387249811ec047e5e8b343b2387d0181e0d0bd461ef10e8164aae357d9b29dc0ace3ec6d743ae3454ab9f842a28d5710217dffe50344e8d932f1801b0e8f966198ef1c9cc6969f34734aa6a63aeaab4339f75d34ffa8acb937ed9c73092a309a9b84a25011e3114c265e4f602337eb699b5a22d572b03e4dad03b0461c00db9679b72fc5b493ef4486f85535d813a58080385afd4e8d871828034334bfe441d18984e4dfcde024403b5ae66cc50a47301b57f9a32f740bdc7ff1d
+SIG: df28e3e630360867864bc41e43fd7ddeb52876dce9b234a3fcc3d8549db0112e176390a685ebd484936e25c08c8a3878a37b3c4e239ad0a0e5019937ffbcd407
+
+TST: 896
+SK: d8aa2a0aa514fd845f7aa66b83c0eabb9c16023abc1695773450b2bb332522f2
+PK: e4e8d6b298248c15fe08f87a3bc6084bf2d64d7f1e4b2d51599e9fad9cc91092
+MSG: 08deb3b832f52d6556f78c3f0abe46f1efe45e3d5d88e7f8edf803670ce4612921749e9ece63fdc9bef2ba483812bb622be744d40404fd6e09c9e1cb7ce19de81a9dadf556352ee89810c76a9b1047ac62b16ebb7da23ddc2d4ab76a020561d02d41b58b94953a23faafddd781b7dca7b7fbee706ec10a73125bf74436056bf3b4f2a0701cfef05bebd3dd8eef306c1ac1b00950881ff05ab5c8248ad1096ac91d526ae59ba0583b27db7d1e390f57a5889e2799a4a1519b15d93dbf0b21d450873c76ba520461e8bb5c83c9012eacd557bea640586efcb869007647d449f91ccd52afe3a89477de7c2b647ecc9bf967fbf5769d74889447d9522d9e8069c3499af6a8a1097a95d3bcc5f83433934484314cb30758b525fe53e90721df5cbe03d96f0d0f98521f01a5fbe57ce8804dbd18f8f5eac8f7dbb58c41789a44433f8a8d1245d2adda8c78d881c65ea661ab178d4fc2634cd6cb514ab6f2543e9112183f3ff73a3f450106b0ee8a347a80cb824ac1f80164e3bb5123698de0e747359ca35acaa3ba0c943beacd7a9bdf8ff73978e9fb002045e8fe5648cc0f9cfa88b0d812e81aa62e0d9c73fe613afd9539bcb615721fb497d62f65c83b87a6d2143f9b1c880ec8671bd42c8de957b1a68ee49226ff717ccc6e74f2eee49c30dea53fec3cd4d90f2cccd8f97c55d5c752454be2ba7b6ff2030be67e0df50c5e883843e71612f2b95359543e2ba1bf2e98debcf5768f2be6fd504d9783ce921a81e09416dbcf2bb655a924b1ef0112d671f084a5b690b0b64a8b9bf50333c359ff3fef199694f9b6292424f00666cef6d06d161a79e3a1b9b9629eea53505f5e36aeadfe0d759672b0ffe498397d90a55d9944b30541a7e1bdac53020640137dc252aef622f3819d36ab498d763e4327ba8580dd9f7e5f47c24cc9928734b7e62112c57e3e0cfedecdcbaccb0c45af8219455ee7223c71e7e20410c5244eb827af2f3935ce4755444747aa945f4c26db3a298519e75fc6bace91529972e8691b694d30aa8b5ec4c1a028d3bd10bd0c8a408fb7d9d703495553ecea598d0622dcc74de489ba7195cdae8d5cff9855921837b528433ee55c0b7090857a0c2784d9310b4825a7993ad9c6f18f83bca5cc6a25047168a8376b062e3a48ea90cad88e331187c2b6f281426f81f78804a895c4ec06c341fe846af4527ea26069dcf61d813fddf0fc43c707350bfb2fc1cffcee7d7ccd7d75f7a465a3d14d57302c146aba3e
+SIG: 146f65d43e715542894b7900a2f8cd4b17d3870a6100e37de005b0db5d8151246de4ee3842d3ebca20a5da22a363a7575e7a55128295f27211484af57cd53109
+
+TST: 897
+SK: de8f1c99e7f8556df20b59b8504cff7c6c5241a8aeeb30b92eab97bf481d0fe9
+PK: e463791d0f567ee73abbf47dd57167a535613b05cd48d92ebc7d24e6ebff9573
+MSG: 38d93e5c9801db901797ec75c6dddc65ae7980de210bed43b33eb44cdc6dc9933fb6bec7421db10f0a59320b9e642a21f1dd235601fcd6c53be4a877f4fed3fa4a0ad4dc6e9b391bcfa434906925ba45ecc5b435d9ab8cfafc394bdcca9b07d5668393446e3400e9039435a1dc78cbc08807a3fb24ca8b19f64ea08b8bf6c20a195b51ff8015f3e7c91d08e4bc62415595a5a882fba651dc3a675187af618249747b4680d1d15a202ea9df48b1c214fd403466fd1a265f2defaf8ed5a6bf0eb08d1864f2a28e9472143c6fd103b6b108c0d1d1363b99f9202d11f02056c279cca315db1ab6d31018458f57ba3316cd2738e80c492d857cb1749925e331c65858b50983cd9838cfd2188a5e8f05b471fd3cddcd30d96901194020f115fb469ab5849006dffa2d543a13b3b506ed65cc457532b8aa3ee31d9d8d9e5298d7ac707ac15b827a578c81d434f84cb1b56120d667b2afe6d1530afddfb966d953be7e32df07de389e2d04b232d3512c7db9358fc944d1b118078e6999e891bbfa4a4329f65d807188b59858c431211b29576f4496138b7c0c128f7bef5f79b0f446fc6b4a0e20bca4c40a83571a36644abffabd49cb585fd064c8e509d9a0fcff462676f0ebcb61cec61e512be6f182abd59e09f642aa619634853482ece8f89800f9c5bcfb841431ca0691ed8d80e0a2fcb797a036897cfb6537586b31c00b7965efddfda72861845026459157f79eba1bcaf6cd41d618aeb1bd8da1be98f0cdc7f2e09b903de49c0c1be91dcc177b298096836dcea4f601dd86691555128325438bd9ccbfc0e777920ae8bbd57634c6104fe69a3a72012a2360b6e552550cffb4e2f0b41fe15537ee0e6f37e7880fb4d12bef6cad266ce58df9816b35960cd0bf8652862ee789ccc31a7efc21a81bda46146b111fcfd94f04856ab61a557b1ff7c8e4ea6d9c4bcdd93b151aa08461c568defb2aefdfce96394dc822d4ef6cc4b9a3e6c332039f6538aa0df8de8126d90c312ff496887486111565534346a7462625d63df69fcb5741906f19e00fc8003f08b95985c38b8674af423ca56de5f881b59c466243a7adbadba29caf57fa777122e61823b4e708182aaf37206d7d5ed051c12a5c0f6b4371043f562cdc029d5e1ba9b2bf5ffbf1f5f523db06feca427db7a08819ffb2d0585242e20da58e320b16b16e448d8be0ef7402d24a7194257133bdc982314d83adbcd12e8af31303426c59ffd8269ce4b987ca9b6f0ffdbb4d1d12
+SIG: 30abc4e4e4b388581e668bd409ee18a6ede81a136c28a2924df5fc00d7c280d97862ae3a67a935ce492364135e659adb5fbabe689816591f49ac5022a387cc09
+
+TST: 898
+SK: 0736f801720a947c5c2f3258ce0d511c3e17e94e37b30adfa52095921171d400
+PK: 4f694255920d0c38de6e72e165c33aee76b1cbf6f4837aa5901475667acd2826
+MSG: 7f87b51f6ead2d4402a3bd3c3769a267ac8e82f779ad7b986dec82cbfc1ea51291884326d9226967cb66a96873184f0e83b3ab25a5ab2fa805fe3a0e7b190a622d461b7830a3f697c831c29ea7c0cd4b68d8e77aa69711cf864dc1d5394f4845e2fbb5076404e09a88b79f05670551bce2ef5468b79d57888b9852a4bb479a4fd0beb681fd523fc5bf4458abbc38ece72e106e00222015a57ebec55bf47513e25c3c4554843bdacbcfe9f1b8d0ae354e48d03fdebdf20d655b5268d8bbbf33b1288910f0444fcd56c0da7b8903362b7e37a864654277cffbe6c60857f0b3514d22a40b9dd2d3fe5caea5507a0de3051bb3a4015fa0fe4c462b98fef2357dcf6b97dc75def382f901f96f4a04a3efc60254200a2c4cdc8a58b25d94e32954eaff1511ac46e3606663b6875f136499da6a769097879a6e0834d564fa7fdb99581183ed0c9d48fd195d7ecd9f4dd4865565fd17a008718dcd76f68a54e516a2b730ed3dba5c2cf40630bbfe7fa03bb7cdd967695495a7c86e2e84cb017ec69601924631595affaa8cfd048d14267c73e54cfa539047e717691e399737fa50cc4844961257c93d7253d23226b7cd0d1bd31f3f0d2d892d073d8c5073c602f61a04d6437c3903eb4a64a01fbcc0c7e159201cdc4aa42ef3b1ff9c78fc275cfb11a05ffed8f9f22d85ba924d8d32231c254d898da7f0679a64cab84026906e9e85f95efd8ee2a1725633f4de2ba67d99aa7f0550af139e9f8c5293786727d82630296d5daa9e830aa1b3b5b302b8b662ac832e9213016ba493a03a28cc3e9540d0d65acddbfe1252b5c16a84a445ce75415c6cd8ab16fe5eef117097d71eb5676b9a95b35882a7c3506bc5d02f03910a63d46846b213c3c9bb2fc34e6c69017d2065a1ad3ce3fd14ab0014f584e57ea9d903e40aceb230a8693fa2e63641c25438ff7a1638760438844cdf001180f5b177be69edf7ef66b39312805214cb17706cefe545be5a77019a5ec52bbf78850fa3d97de2d4d74aa68b58ca812a1b156a0c4001129f067232a6ec91a5ed4270f2a4c6efeee787004770c859e450e837efb04dc998bd273c27a09855e4eca1a22a9b88c17bdbf253a79761070a76817a7f74ff3f07fb718bffa0b4f326f284e62f836832427be82f483373515b9bf59af4a76a57e2f40b91034dd568ec14ac10e2309b87e2922f9cd9fc1a46a47ed3bc7e1b9feb9ee067073fa5dce2a67530526de67ee0e509663c44467eeb59420103ebcdffa709
+SIG: c03c0314851279edcde970c23efa236f235eda960d2c27d3ca946f650c200b4eba04be668ff62eaffa6cea351abdfc54401dccce3dba78004aec9581a2ccf40f
+
+TST: 899
+SK: fa75650491047428d363b5822222122dffb5a9fddc603c33c8a608618375dcf3
+PK: 98c9641fa9dfa8ea13e0d1c716b8679e264be15dd2d4c06ab43cbee47916ee01
+MSG: f54e41b939e37df17c7d6043fded14a915d934e867c345269fdc0177f5bd10c4348f319e0ab9a64cc0b7d4e0c91ca9aadaab2edcba544f14ed2cb539ca8975097d87927095b4ebd490344340061ed93c38167edaa096a230db59624c67fb9a1e1ddac402133f4d47cfc11e2fae6b3f3c5001cba9a8aed90073103240227e716ff71bf68a591ba2ceff2d31b86ef21ab012eccd409ad5c29d659a1b37c4d85505304140fb2c3437a206868b1352c102bbfa3b9a76522a2bfc5406b257696de74ee7d315c8e99caa96bd838006c6da2a4233315a856acb8e80c33168b333551d91d074055734130bd7d14c56811ebabf7d5a250e6072593d9f2f8b97c12a703c2c479cb0b15b7a2775c9dcd2ca4624672368a2e6145467f3be6615f93b8120a0a12da1560663a26a61731966b44b299ebfad2a95c62360f39ce05d9558e305ee23a52fa5ce20f6be5e262aff3a864d5ddabe23ff943f71d5998493d99fe2ac2374b464a69183c3bc4f1ddb883611149d7ddbf1e8380b544335e2b89395054c9f2558dfc56ea93ff14d0f15d2e0bd8937a556387de96e418d8b3a7d666fb190364b2c2190d3c25f1752d5483dcbb5960064f0c87fcf8f313d28781c114a169b690a8701c50d89c77324531c0f849dbad1633d925acd06c16a9cea19a434ebc42aebb1fdb9b0bacc93cec39919943664ea1a958406ff9e4935c92ca7c39708f9cab710a583096b4ed9f48d9e090647240d76eccbaba591f55fe7e36d72c21727acba0f8030954e62bc580b8b670c4457c3403e369ac20e660d662f7f6a414213ea43f7c0105009c1de817adf6ffd9cca3b45a63a822281c6e2772fd7b7809603184b4879b18c887903f0fc8d8e1e2dbf6e772f0b2d9b8a29927acc81714a2256ad8d7b7330527d7dbf8befd82f8c9bb401cf0a90249a64ca6f8833db31bd03b9e7946d06dd04383d7c082d70aeb37ff84c2b057d973b894b4a03ec7bf031aea656a1908488894a4ada3fd7fadf91ede9550d38415f82a09455c0f432fb55987132f00042afd60ea51d1f1c6c1afe0cf87c346e31e63e26f49b137177b2d47ab30f07cea071931274cf010836d683fff3be7134c78b8bfd8b1b8fc2049e18ccb1e18a0a9585a7d8a1e25492608668c96d62a0aca8ef90e048d20378c108d06b03fe3ec4adb27528ae08f7ded9487893ae64ca4b939202aa4c17afe718cdca49ff9616d0cdf8334b6aee2d6d20947ca4bd7df531dd1da99581ff72ea56fe62caa2c95e3587
+SIG: 1effbf9299a1b9354fe1f1dec1766595ea767ab8e4da9bb57b4f69bcbd8cb3d86f768392f59b39fafa8a210a6509fe0d6008d6356111adfb3799c1d559c26309
+
+TST: 900
+SK: e1c12946d221a194f22f2762c0e51cbe3f98b914a47d3dc41a1f45c54370637c
+PK: 10408136a68fc56c7d3b36b7fef122094de081031189cc84a48806aaf6cb9185
+MSG: 870f4cd97cfc0aafada40072312fb54bccc07628714e4962d4bef4eeb5de40a19a246b5b7d52d487b7e52d656f2c6403b916d02e02a6d291c1e1828dd945a583b438528d1c39765a572031ffa916b68321f32e6646f0dcc1c60235ffaa3235f484a5c4978fa3e6bf14301d53e12f4cc52118b1f6f07f5336f5d0a93789bb01d162fb3126dcd756e0642e7e698963c0345911a5cf3c9953f77319426cea2cdeda3efe989ecb63cb9eb8b920de766c4fcf6336e5bc4371a068371fed95c8c2b61ee9b7c3e3831c20bffe8707c0c98be96153c8a873d7f28afca1bf71085ce0e3899eef5591bdd666dc2d07641772d745c51644a260815b208c4dd305f05fe463d0d9d5a9eeff9779f5b1d44f26083078566d0e5ff56b3af0e64cc38708af5a65f654352df10437f1ddf945a0da1f4def6a71a060e0c4adeccaacf85e090f7090370ae24e5238d768a08fe6b4bb5ec497a6603198608415c7c6490048aa36737c08503008aece0f494219ddf89b72ea77171c6d3117089eb88907e8c33fb9e70b0dc281f664b5f965b5d2adb1250710ef2352025fb293395ae1d23ee3b592b4c5f2d55569a5458654ce3fc25dd0e3f7e6757aa7b347c1ffd3ba4d4f2c4b6d36afd59863a32a594e74537ece9b8b1ec269bbc4cb54d76238211f62a98a46a4af662fa81eba6f30f514b866b7942bc173f7211a6c014da14e741327a568623d14b8f835ef1d5d62b2523cfe6a85bc69fa05200deac1568b946a816b75c5d7603174fd4e2f9101a79063791bc3d59297cdc10bdaa663abf3c1be2fda17e4e5ce394e90bd76b1f9e0405f5675b99d638abc2c1b2d8b53a6fd3dc8375855ec54ccbda24e672527723b07bb599db54e38793391cf09ef3b1fd7614990065bbd4a19e8d3d1048253ba4c971c2f98d2b359df509087323aa6905029f5cc5e1a0aaf2f7c0108ddb1a40f562be64e57e695ed21dc7db17d533677ef12fcbbe29f3b237bb6344b1109b32a9462abc3ad3c0710b04f38c6f5952db275e77e2f37e95d55096bbaf3e305d5d743d36595bf0567892c210ac7bae7371d164584785dd890174159b3930a9a6ce3a166dda2383e6e2af28c1bf3192447e90511dcd80ebdf9ee2c9bdeddeeb610558641532d07cd13da61254154cc0fd9d481e3b0a237af2ec26256d4ab219faf15ad2b7e8e57ab726ff2723216a574585e2a639d948c2c4f69eeaad283e3a44ff268eaefd7e66b73ede473a8397c76b48d56cb3ccdabc91a8929cf42998350e0
+SIG: 8fd7fa400c032fcfbc402942fc78637526be97ab82f237bb393ea39e35738c67d75409543a8b3c055f08bf69199af63b6911a482fb4f6580802ec9d2dc3c1106
+
+TST: 901
+SK: 762f06ca01e314715f92c90bbe72a25bf26212c81eb1d1a0dae2c31130f7cdbb
+PK: f9626ffd692731925e5aacfa1bded01aa8f730b772d5e46adbc315565b9bf2c9
+MSG: 9497483a4fba78433b38e9deb8915c750b6da0f78af4a68b62f9fc0391e338873b1d64b1b7f09f12f056a3c91653498ad56e069b8b160887e8e378a76d8b3c667083c0a2b2d2317d3b874857e57862ef0cb70436a9028f0191ccc616e9d7c9bd869808cf094835ff518677b3fb089f4c9d077cc7742405b4863ac7a59645c9cf540d57399da6ae9d07fd19fca95bc8a86d8b8e24e48733f32158fd19a8a1111d1da1f9b580a39c10484616cf2bc0ec29f63f77c85356158e16da594b5a890e55d0b64599b30293e900ed92ad261969e7df4c4b1d0b6024bdceb69067ef486c20fdcd22a10d5da45fbf905ba1e935c96f50afb63571bcff3130684eda0b56e60b26cf4c0ef9938a92768fc8631fe308236b012f92af24a8f6e6ecbe76629bbaf8ffe54cdbe8671de2ba624a7c0f6193bba4110412902bac2990922a9e5a81053cf876a4c805a04c56a8139d3419e454a622d0342bf426e9802c3dc1b4080c75492afe9d7b1545fe086d963541324ff52a48c6bfaea26668b3e01e5236fd45fe54594535c0b23e287ebd1428c8be0ad141600e91cb51e1ea66271a6421fb689e88a0790a651dbd21ee2089b274666f660ca09ce2d60e39e2ee5f03b6eb82d19976966e79900a810f6d5b5c1a548e5064f5c3d8a9f2def0179df99d143fde69b0712c091c29e9b25f40cafd57a024658d7774037610342f3800fd51f49e79a5b3decc112f58d03e3d2958758588bc4b1c6a6cda7bc5f5be183e41513c1f230f3cc364304bf82484b7cf19a002e150f98c5e97c6166ea15b86340b8c5ebe5c1a183e5588e66f55905086313f37a409e89b47db31ae97453edf69fed7be08113071f374b26ec6043f2a0e9cf8bad802abad69e617e76243b3cc034b099d8729ee407a53eb03bdc6410a039504b3b12c819b64545d405c6a4f084921935bdff4130ae629d909626b062676e538eafdffb1d6229c0889d3cddd3365dc3d6536f7248c49317cb50c56fb57855541d6feebac816c9928fa662d0ae80a0f39e570bb7d22416f98f371b64247968951a8a246f74b3061743c9af7684bbb966ae0bd78a810493ea4ccd71174871c82bb652b2748e5bccb0ab6388a50f053a048087fd97eb15c1a21b1ee1825e54aa130d66318aaf661bbb24763577eb37d310e219b0a9bba0375eb9c9b4af8c4b99a3699e0d3266733b6e4e9c534490a1341cb1990ca5b1c847bc8126026fea903a1f549d65af8fe02a9163ff8ea281e7226243e2a153b921851de10f7
+SIG: e842b49e533dbc92998dc078e59793a2c2fa636bdfafdb48934c93cf34797102938d137ab7ead1a0f70e94a67d57ef6a02c9ec77d71f70cc57f1533bec87730e
+
+TST: 902
+SK: c5cc0b95818c4bf38da1d65f021627e9e57d262b02ec6d917a7d46b11c7fe48a
+PK: 457da4ef14519d541edf92cabed9b04d8a2f2afd1510a92f009bb4e8754f1eba
+MSG: d6608bf5ac000ecaf95fc09f9cb7498c518a6e0255586e6337853b1d7d9d7de4dfe1245d59031a317d4e2b6a73c4c3f95b582e72a6420221587bac120fb8ed7348070f2860d85866a09fe756743497f2119bc1bfdf573be35d1091be37f18bcda6741c90d566cc924b72164b749af9a6f40f71d3ea5d8764cdc81714bd7395e5f679973636eff1db1cf0012983f71a2f2b12d45a294e5a389f4cd2483eb39da0df26b736c7af6e41dd35a78e45292c394e34689532888721f863c56db97da1cd10a66a20a670b27fe8ce5568a42b8937790c7be1aa420d203d7a885c1729cd6b8e197189e479d542cbcb9b53656f2b9f539c325c34aa598fd91e7df70f9a74abec467654b1c9a3d14438e7c0836040b793871ecbe9e5f6680ccccd5d4696a87e37e89eab28b6bd679e8fe1627bdc9d373b82f52cd8c49be9bacdc630a32fd12835255a542fb7b12393779d4498aa06a0e7e1a4977939817eb2088af1e19bb0e5aca854c125dc603d835736a03d938051530c9ab1aa3bc779b3bae7450ef57d1b3fc093a37dbe9d1bd6d040f2f8eeba77f7fa88c149f065c7ace33277aa9969c266ea6d85cad62cfaf5508e7032716be684a22856413e0e65e42b6e9e6d865a87363cbb62d5bbb6a3731ddda0fa6ad0293af9893c09a9e743090f2cee2f4437736dd433e2ac7428bdc8c77cb9964355fa4415cc3831d8c7ca5af93d51752e718c6066eca1426a87c29808281a85ac7e0b4044ff6e280e28014b9383d19c9d387d29dc14de433da260784a4944ca76c2fe8a080d0996d9a6c2a3d3a7077280edcee0389aa8e5365d1d9b346eca0947b0ff5265943ccf09939a4b4a8f985f6a5e72723c795da0bc360dce501f673ab6ea8443f129427952453eb72b3a8d0d976c278c5bd1a9853c918e0c240c3c734932953fdb5039fbb04687937c9ff0ab74a16eae212bc6f20e700a77c092d23d2efb580e0c19d65f304129ab8e6cc12e58052257ba09449f30d3d974391afff5633def2f5c4ebd573a9e444bf3a3ddacedf02c05f3cc2e750664a84a1d24c5d28b49670de8a2f2090839483ca38959991a7d3727e21a15e82016c15a09ee71f4f43c0a608b48485c9934a38614794d6291daa39c01c45d3debe579b5823bf3406404b4c80ee6ff342b46b334b0b883b40bfd2f9a53595ab62fd1351ebc88308370497218dfc98ce081407da812a46d6497d7af9ec6d83e1c60eeb712d889dfbed0c805aa11cf817dd8f04396ef871a26112dcb7c0e1d2e68
+SIG: 3ba0af8af127c4584826090ecdaf485ebdf07b82bc499c9a2befca28d49344974addbc8d80a52560e0f3d73ff5cccc72c74b5b47ad2e6de9612d1a00aec92701
+
+TST: 903
+SK: 61fa8677eedaded69b165c8d277c978249663028301df6163e39b06ac2f5625f
+PK: 87339eb57238db2e4e60f3c28a3fd5fb611c65fddc81eed7cf7771df34d92267
+MSG: 02c581dee03f2c603935af5eceecfa677134a3e0aea54fecaf4271fb52951a27b76877ccd49ab486dfc227cf31c9d957cc97306573fc7fe1d31b6c7df3d780f3a05ca6395657a9424342c9c6b703127e038df0792154e30a49476112cb92d0d5a2d22e895752a86edddd912fdc81b1e64a7bb750f099182132ee4823fde845802a944539d412b2a81a15b00071a950504c5b55a71bdb8c5a582639e855e8be241cda1ba6b3b4f64554d17824904cb30cd7efd9ac049e390bb79f53598ef1e8fc27dd7bf599c9028c9ebf92fc3be11df329612a228e0f5684687bf41ff203e97a7686126a39366bdc26d50be025d5187c6ba0666e379be4a80a9e62effcd916d7f98de651e00b97adf5d2d53daa7f8d695a291560755c744482364c4f1fa47ec0b1da161aa388f9597989a97726d3ed2cec82f1a1bbc4ac0be0a00cb4a8db1fb7c14ba05d896348dc0559d2a90beac2041dd77f82d6b12aeb2243ca0f419a57d3ca9c7d25a30ff0e8bb0d945155d1b36ad107b55beaa95b7d5e32003407629f1515f8a7089e2488d0d7544c2f7cc7c7f0985da42840d4368ff4f0fa4fa298e3b7229303aba514ae94e7026535a3f426ffbb4e001cd50ed12f214b3abef96e301635c987b133fc5e6184e7b7572bc3d99a4523cbd5afe593cedf4c9cd02ff2e36237e4ee12ef1a22d16d7cf4c072dced91cdd26ee144cc2bef4950026349e9444784081fe4e0498bc75f72e6818f459bba9049c561316c9f498e7b1a994b0e93055fe73e444cbdf96ac35e9c4e92e6b49e3bc0e99de1716df8eacaeb8d2fd74870044cb39c0e367a1fe32a9bb2974416364e730d5248dfb1df164a8d58caa1005fdc91bac2bc01cc77decc14893ef946fb3c81be0832c72fba372062f8360f4d8e6d5b741cf7032d8d89de2edf4c714a29f75abd8f5ff43ecdd4b7a04d7db0882d16e74473a0fb79db444a78ea44aa2631b8c0d7b0300d55cb6ac485f24c0acc647747c43db3b2a8677baf656fa735a575f1813f3668a2aca9175711b525eb496e9ef9711d75f590c7d9ef99e0f59e8483cbf9f284e3f5a33ee7781e62b8b05551777efe0fbfd19e54b6bbd142944bc2959a82ebd295d23d3443b6ce658c2d579a7637b549520491908e34282ec2716972e6f0353929547ef1537aecc96b2df616148599b09d9b81394a13fe7db86760b1e2a060efd484e8189939ebdf6f21640d89d8e736dee082ad72a0184adedd8df21474c9f526bcfdf7e85658194bb6d942e7f3fe96c23f
+SIG: c04ebd11c3eb09396fe8d68279510a9efee391abee4081f0d275674a304794835aad7f3e345bcf0af8027f97477e79e6792b8f299846ae28cb13bd887537990d
+
+TST: 904
+SK: 7048c6521aefafa4eac6d6c3a702b9525480a66482e4969896757f2cd1ac7d5b
+PK: ed93113c1643a53aa064caa631ceb6e20f6d6ec2fc6c0711cb8a1fe73139af93
+MSG: 53f74c724db1578a1a296a7ccac904a2504dd9005389b4f8d4ea4b6307298fc6dcce98a6bc07280d20364e405a467e736578965269c81461d61fc6b7e4bad68d2b6dd0005850105f0a67bbc6ee223ec1754af4e3b9afa5062d1c1861048f185b128f1a5c0fb25c3919b4833e29e202bc941a905e63c2c05b1014647bd7ede5be9f996615187a3d3bb2c7dc4c28f7053def9b28b29e2331f16296dce8f1ede484caec996702bd9902e52684c812c87440f69bd141c7e00c6947d1fc7c3bdc0bc5506b6ea462e65f9e743b72c007ddc7a377493777d4eb12620ca6c019c8bfc4c29ec8af382fc3eac841021a74e4674ba3e43e5d7b41e3feeb17da00a7ce455a1cec70b0be6e56f85fc37f64cf0733b7e31241de641a8a8e5b91897bc158fe93d102c01d1f5e166d408165fe3fcb13d5304590ab8ef0dc8d5a8c1d8a93fceb854fc1fa36d0cc480cf8512d80bee69b0650a957daed283cd7638155ed773086e86a8ffb198acc7423b5d1a609a175a56b94c96b731851b93a94977101e255f1ce92e232a05e2e3387fcb4dc13a31bee6ee25507322c73c9883080a74c00f803a998dd530a79126bb144ed5574c4b23180e34e099283b4bb1d28822fce3717046ff32ef9e2cdf967e318ea726a2aeec57806643ad4801d3e0da52a1d77bf043f5ae9f3aea9e4bc4fa795d08401085ca94cfc4ce719dabc7b2390d03d294a65b7af9bc39072285b777b2f133dc11a70c0a9f060e10441f40216acb641637a2eadf1f7b8d262fec1b4d0f0f4faa93f3f732cac382d8ac42e178e2244999d764a9d0e981714686eb4924497e56b50157e9939032c9f88eb657cfde44ad34714af4a51324e5e77d0deea99c9f244d2e09ea425820a746d883a0cf4b705c29df8c037448154dc08a4d4337405fb8765823114370b37ed86086ec5f8bd6c72abf13f518430710f597b06108f65b30a483496e2ed81dab10fee947fe04b5485f2e3074049d22284266651ad10dd086aaa5d452e0d1a61129d1e77c663c26d088962b5545645b7a1a8713d51327a7a359b12daadb85a2cd4b5410d5c20267fa766b8c42a84dc42664588879b3eaefd4cc8dc693f98ac205609e570665b01ea4655e39429a7a7e542efb4f7890dbf4e34c6cff07e4d35bd3eeedf5b46280f4a0da0c2e73c94ea81cfeae7f9bd04fe2d45976500f7dcacb0df2a5dc736a823671db679be66cb33c162fd2c74ae71fbf4d2b05af042b3a977f5b944b9fdb6c34424421bcf4f6223768428fa140fd4
+SIG: 7c45703ed3942e44041c7fa1858aa5f1dc381f493a452dfb52708017898f710e31118e331f00aa64cb738836682b7d177e97955c00319abd79a49e0fcd16fe00
+
+TST: 905
+SK: 3e6373b265b96789007ad2a10c309a567638f25587d77e28b0823a4f179ae4fe
+PK: a3234e5d13b03472165036404f6de80e702839500f13d9c985a077d45c69ff45
+MSG: b9d068bbcae7722f828b0f8c98a738e36a7df4c997c724ba27531af34a2f106c7513a44a461a9aa4309bc15c4e0d42759193ea1cdea956bb815985f57867145e9e2c7585fc8d61027e47d2d735e2448af3782909404edeaac0fd73f6045dcdb04f0377758f02204aae3a7220311c0f4723582710cc440c36c9587b5c9ebc4063fea8ca3f43195894f79a365087137282302dbf2e7a0d411ab58b7026ccde198869aa734334c05238e275e3c3ab217083495769e2fad374051452d7f5b1db0e785836d4bd5e2978a3e991af0ff716f43889a07f5df299603621c39e2cdee089985d9e6bf7b2fbd02373ae1b5e9b88f5b54a076e676d7790bfc8f57dcc59ef52850ce992a73ba7bc991deb4dde5eb0b21670b1b3d4b64f36cca8e307098568497d8916f6b5d0e9e89f99f86006f39bd3a810769c8f7801773c9638abcf5e2711b19d1167593acbe85e4161428997a2194dc5e7b7640f0d2c1eb205553be9167ffbc22b7c2e7698f3afa10754cb44d4b1d45b837303b1669073415a22606b50f21f8265e139f2305ac0e0127ae056ce8abeaba20e1d269a2b2e899c49547268a0696ae450dc0267f7f63a8edf074c47d3c2db1da36393737304e6dd4faccdb6ab55e5f8520c3dff5f6beac30ba85b86082351e3ded8400aa57f650c0c33036d65b39b7d2fb6112863d59b72558242e8b045addd357de6fd37a8f6611765c9b5ff19cc4db7e117c65a00458908b0245d04f7908fc73b165dff6e4be4b42032d8cfd7d6f7772c1bfe721d4bcfe2fc527998f34fb4418a1fae1e6c3767c4d0780621f923da1f0a0d3d219c036acfd3709dad4cf24d90bc691d700e6a9c80ccfd10bde8e791c0fea82880c07baaaa311eef79240784f628a7d2a09184e016f81008e77429a8658b153e44e79a98ad248f7fda23b590d646d7c1d841f4927d6e8bc73214d10a7f3c29c8f839a8908d20a74e827af467ac5abf0f1d0ed39cddd969dde9eeb4a4b7527ab3e2475a195e24474a4e36b09052e2dad4a5eb4691e263b8c61bbde87772207e011c4c1e14235fb24e4da438875d18530fef902619dd485d77b545abb56b69c755afe758606971ab97dd3ace1c1a34a33794c8156da799e8224d885e1868f9cb466d802c827cc3e1ecd0ae6e0b01f8f791b12208fcc0fed385b796eb2f2908b58d30b3733f1470f2e2ef12ad43feb72d0816de3c13a8b5a523e14cdf5ff3720bf87769cde7495d226bf38238a825f75a09f6bb9afce516a7bc70114370bbc40f17c7bc
+SIG: f51e0f878a5a709647e85fea839fd566e6f35c8a6185d0c9eb13e0d5b9e6e8aa95c333a8f50632a4d6657b518ce4cfde40b8f5a05b2d9f8441fcc9d2d692d509
+
+TST: 906
+SK: f5e8597eac0ebfa9d385de85a1fbaa35146395b13457b5b14d3670daca6905e7
+PK: ce93e642c2f15084bc83bafdaa196763de2a3c513b0e44f68ddbde378514c441
+MSG: 273341f219ff5cf381c77b2dd226c58f8f33c4527048cb006affef8cee151e300efef629fed21b70451f729292627d1f3f1b5257359ee5a671cf62ae57324940f2d0b15aac76ff398220c08024e29a8cf36504e12a4e96438f42c3da0c000541bc11f091381b0b72b58a92083f446eca1991996878de35081cc4ab90958c96cf5c99796cba7951ee186f26527aede69db304ce2941ba15cc00ba2f1411f208dad45e87bcf638792de0a68624b667297c27a343db4baf34a0228eaf0d1022009b5d068b2534d920302e71310febf0df1bb02c2ef0ad1ae149deadf8c184373c0f7eb6b25695be82d12c71b6c83267d9a233667e77bc205983f8b8d877d85aead3f60e820ffcb17adddd92a7712bbeb34ee71966dafd9907d193dd9d725a31a613d29e32be72132808926d9437477fee25eda610aeb1dce12ea316c6aec6689e501c551923825a34b42c4f0675b86ab26adeea2e60dae6c6d1cdd0cb3c347b16384039a8e3fd6087381387cb4bc72ddb5f25b374859b02e5bb1ba06d3cc69ec44cec4b985c8476e35032e99abf001a1d44ddc6e2889c3c2c3ecaced609b2b2680e00b1efa7e9d26d62f2b3ab36f921044790abbd49360756dcffccf230f66dbb701aa164dad6069aa2b8b3309f2fe44d5e0b25bd556431f0df4c2ea97ae79ed4a57578d66fc6939c57628a90cac97adfa8702a4a1c8965ba1a90262567286664003003533cc9314caf7d3b982e0a432ff5aa4ed5741983d9b54323ac7e299b2b4956c1a2c191557b27d86be714b5b68fcb1d41f78ca5ddb6b53b3dfc8e7d6b3c3db059af9f2dd765ef04b6d16e6737c727aa11f3df3774a3fc96182e282acc3d233eeabf8c72d3f246ae184505288fef39b36766b10dd1bfbfbfa70f97b3c901726d1e0d0a837d11f0123a34abad1a79aabe80b125b128ee160b511848f7f04c49c8d5c2f2041da7d9599c29b1dac8c68077efac3eca58bbc1637aadce21c774fea42d2bcf4a0b9892307e36fa250acee795ad2bfecfbf60319b81663e2a26571946f75a8d969af16b3b57c3ec3e66158aaf42ccf5e58b937aaef613318606603317e5aa318be70f8da3c0c16be6c29e3ec9fef4e46e8ca241d941d58049a063d90afc953ca32e8a50a6473632588ac41eae97f20ce9b741ed41c9a4aa6551fd823ce0c811a5bb5a171c1ea4238a0246811e469cf498b79621c323eba7985344fe11e67499edf4967491aa749f8f3fe39961d76892c93aac3b19fa4b4fc174d7d4d4d8bd6ee475475008
+SIG: 576543fc21ab0a7c5f63b1cff01bf845df91792e7a9750c5508b51665e7f89f17c6ec3355a0aed87db8c77bdb271fbedc714ffadb78b5e0f978116771ba7cf0b
+
+TST: 907
+SK: cdadc5b89cb2b6308a006f2f4e955a91aaf3ba70165f2d444ef1ffebbdaaa221
+PK: 0541415ff5467f28ceac839b13a1766e72c99e6545207d9d5d9697411eb6bca7
+MSG: 911727036db309d6e2e3369e4f17d98d99ec070c33283bb1244efd62e76bd70a69b9723bd2b520472b98aa065924366de780900bcd8b77b50f87c3c36187024bbc59ccf4482c7b4aadb56e2e5ecc0003d989d6afc63ec10242e57482fe39215261d5fc95a0185f95e9540c55f74d696048bca7ab112681a5558ea93c3b1f1cd364659e9433ceeebe054ee713c47760d7ad132a7f3f8fe3d5041b811a26b65efb1f340e181a4ec720ea136b3af3d9e5461dd24370336f10e6354c8c17acf9998544cec0873efa687cb132aecf70aebbc567ba03c536499ef96cc8412e7aaad5bf96422be47cb9413645df2c1703192347dcbb123127455971ae157e9fa2dbff88745a96c658b865e41f55aebf98395005ddcbd5983e6ae02c4fbb5e17916796325f76edf5b64afa4ec5a7418afed23a97efade68b6a5b3145f08a5d3db9c298a512fabdac68562b3f55377ff44b00c1c2f3efd18132da71f971a953a9318c57523361a160f9b7e3b51c524e95dd5ef4568ef18a800775e9d26e07131942d2be4ef22c0cbc13df01c68b1bcd3bce9bd51c4ced652adc4007be43b37c67a5c55ed4029e8ad15def8305c968621aed4cd4bfe079a6f48884d85680392ca92ba6e12fea6f4a056f79d67b19b05f90d684be7d45725f7967c6a467af43b86a6b1b9d9eed3a4248971c76a7ac29c292dfba4d75c5f7ba709a39058e96adf6dbd760d3cef4024bf3edc441efbf1147a2c108bd6f9eb439c1c5c4d3a6ea4ec3d92cef38136188bec9e0b6c0518d8b79ba59c5dcba393aedfdffb0b70d779c2b9765ce4452e7e3b08c4402b1a608320840fbe96d1eb8656eb1c20d9551ddf533b9f15e4eb5783756c53ddd3b14d807f838ac9680f89f1adfb78d68ccb06731a90beac5f0d709d5b88c75437a663cb962d37f96b8e8928477b5611228015d337f049e8b62e4dff8d0bb6cda24a5df9083e348bef12585f5f4c4d3bb3c7e78d550194a45251a0879a1624bf9dd35eb655c3939fea8909f6df395bebd02b68a17a897c9aaddd6e2e20461e303f57cdeb00ae0f23e60a94c19c771d8aa60533b93cedc1b76d2290a01bf43b2725f125befa575154e986c9c6205a1596cbaa2d13470c23422f2df7bece4e6ebd752e9389ae60857b52969d2ddefa9c034f1bf35ae3316304e949c8990820e26e6cffae4b388d1505f923706297f8db556537919ebbe3086023f12f4ded3b11acf2a6d973ddd8eb27b07c580bf448caa5a2ea116c5eaf36f7a6b17a85b3955dc8a44a620d8
+SIG: ffede701eb1829ce2361cda2c8bb63338539d8ad2f6677585531e7bf1d3922382679a1ae84ffeb753fc9754e50c01852f955e3fd609ff64bf05bbe7075cdbe00
+
+TST: 908
+SK: 2ddd79e76064c2e6b322afb0c5c685cdbec62821cdfc0cb14db7d01ba3bf21a5
+PK: f55b4ab64a2582212b96ccac0640e271944a34a286d035833045810e341824bb
+MSG: a56674a1e1f09795251abe54ab43c298208fefc9bb9176fdb23e1e9f60f032647915567ebdcc2b869edb7055f4aba67ecfe7fa19eda45c06047c7a51848be9973251f85ff76f1c59e3654382858c9be123db8a9490c6c9b309b82d1e2ca6f4a07d00120283c6c295644995a96628612b8d6791573518e2556a688a09f149bc846a68bd0ef79279035710031ef0a8fed1dd0bf026125dc6648f86f64309942e18f23b12d1dc68c6f2770ca8b5485b369b0c92007a9461c139fcbb41175f316d4467060ab43d1222f5802404bf63c2df7e004bdc400ca80fe0d2cb68a210fbc3fc0b903209d5476e7a56baefb8fad7f328b72f327113e139414ba6f34e99c2eccde044e7a3ac70c580cd26c7450192ca4c823c7ac5eae876c0d1c8c768c1cb0b7ea41fc9b7d29437bbadab18e0f5ed1defe0cf6c0ebaa6b6d777f4dad9abddbfc0fd6ab5eeea803cfa01c0bd46f65fefa46901abbe0d89104e3bc4aee1f0599c69b67ba545ab9b54f5dee340ac69d88299e86822acddddce601122012f99299774aaf17c964edecb95e1277d462de64e9115a61ad98aa3d22e3ba6f8f1cd69b6b52b83382823f30e966bdad1ff5fc198ae32e9b68055d4392bc7c3df1015f128aee1e4fa3d4999e329f22f0ff6aa778bae0294a1df7436cb16a2bfcd74b463abe7cb4bac5362c89c9d1a378a2cb885cc3b26ab4be881ef1afc14430e10d26539ca358c3676286ad81ce1c9e78592af66f182bb1f7f862fe755bffb5be5c5f2b731c132e2388a76a1a7b1cddf05aed2ac9ec408475271942ccadd32e49d8791edf8b8de117551ce264a60b84105eae87e66f6a401d1322bb21a98e8acd277493254e504004f72c76e7903d2fa38fab717e94ce627947c4ea326bd2575c37310f3b4d843b90fa77d32d9952194150b62f850187a4fdf38466dfa0656c0a2e0b3f07492ac8e37e5d0df95cc89df3085a269291dc2512210d3fe44248d7ab996be099af64c22756666f8dea56c00b90677d1182500dd274fd0769253826d677ab16a557b08b3c52265498d85c4cb2b600ee0481b7c1c476a9daa8b88c71fc21b6f89bfdfece58da9e8d565652e4395bdf4c811b4f4f22d2b9613261f88c604c2974d3e977d140d046e1b6625b7071640d352cb7e7e65d46c613447be8dc5a200aa9acab46afccfebb6b1c31973246c34faaf8d26ea5e83be15718f8fdb0cfc444e2eb60f3659b020161c228e6b9240b7ac394cab812de10515766f22473ecca535594ce528a57cf5dab2eb32ab84
+SIG: a4c396e19dd42e039184cd251188ffa245f0367c69c02d12474e5ca9e5c768a7ee3a3d47eb22d1ac9e04b704a74f416947f3f49a3242594e7b6390e82b60d505
+
+TST: 909
+SK: 3abbdb0ba11aa1063bd26b02c116037862285babd215d240bc9c0926f4ecea81
+PK: b8fc59438f8ce9e3785a473b22c8892c51eac2568c681dcc77b6f0e0799c4e33
+MSG: dccd55f922cd274f6975000adc8d98630c6d752c1202a9dd121048b93945af2b1110967788f99ec028e3d3b4cf82fb07173ea4401e3bb4b07b7b0b24b059a766339532d9df3e31b72c958c119d8dfa15a507af6c5f7e78fe270fa81b9df0f2e4af24bd99fbeb14e0033084d7fbf84ddedfd5ce56751d15908475df8af013d091173c1386b9139426cc6081ea165b8ce48194b8e18a9b91a4631344fe29c8e72818b71fa15c9292d13fdf5f9d18e29bd0291b8138de738fd3a36c35239022368b456f1facba90a0d80d6e311c5f6c6f04677e92373a5fc4738894dbed206c30da341b3b196c947858a6d2adc68aac3f20cfdbe0497961dae33470266d17ec719a59f0586f82f99f1c90ed7005a207219a55edc760f4eb8f2402647f6f77971ff7b634357b6b29bbd7ea05e2e25854e99c620f4b8b64739022ff0b338afef35fb6f41a53629a518eb93d66020fb353aef8dd071e09c916d4704acdf776b38ca9c59f211ff88c430a57e8f1713923b3f30ca86970a14a52db4bcbe60df4bc3cfdf254bf10f8afae87bd61b358f43cc296c0412964c4e00f71213397468517cb01379cb729c7b9e35bd50bdd98c3d3b76297a138b57ceb6c77742df0881d07668c08a630a44e6ed7eb206d6a56440710438a5111424b61aaeece40e900f5e3c457e9d6e31a79ec5b4b42b68e66e199309287cad65336fc7fe43f43cd8c773d3c6580d7217e2cabecd3eabc485c4acf47718c39b02c7858ff347cec7535eddcd4fc815df814569a88ae70f2733a6539f208c79cf4e7c4f9ea241a92e9515171361418a4c2e53c076aaabc47e4c971bd04b100c26282308857e06e7e5fbc4342564fb3b1ea4a17a925e91ee69122321d392b246965b86b54fd5c83fa5c474163f98a9f447d88cb59fe2cdf9f5412fcbeb3effac8976791c6a47b669a2fc55abe8e09e74157efcd1ca78fc10fa687010c6826c6e896ef5cd71d0fe4d1bd07c10dac3b03485edd2569a7eecfbc4e5d2ee2379859e265267bedaad69d93b7c1bd18f27ea42483c7e4100ee05b283039bfb9891d37c467ed83b88c794eab6bab9dc677892650e2d896fbfec1b1cdb721be30b0b8e5358709e165cbe3a182c93bc0a0cea2f8cf3a6257adf764534041202241a5279b668e40125fc094585a3c588aba82b67cd91d483e54300428426863a42364049d7c45a169385aa89bf377f0d32b07809b5871395ec053a257d93e48bbf407eb6091401e256546e31f9fcd24d2c5b333cf65785002f08d548db26ad1f3
+SIG: 981f20055a457525aee5616264e6af42e8b387cb08f8b4a73f9be0b366f1035bb30a1c874894cbece0a846d849b7ecc556585d0d3d395645807ff2a3ca5a590c
+
+TST: 910
+SK: 8a44d6afc6c8eee1bc7d5f69e495b0b18ca7aee007dea7cf0d1714d785a9f4ed
+PK: d4f366b3377fa39b36f9ae14da404e2240490dbd8d796b1ab872dfcb83a59540
+MSG: de80326966536ce94996af2de7a07605cc4fcb9e75ee0a67a1e20932111de9b356d5beeae86cc5f564c10d66e3de95a5b99e844928ea8e77586cf3c10ad3633ddeeb1d9dcf3f94b70bf1ef63d238df204d705c0b174f83282545f5e4075f8d69a48179c29eabf5c1742ef39e1ad963bebbb66fce9491a984651215c2e750e6ee8365766440a84419e52dcf671f1c52eaa2b9902bcca4b37cffdbac8e7e7e6b0a5c8748efbf452df6163f4ca07b61f9a05ec20a2bd633389e670bb5454acd6f3a06335b5da9ec326264e962c7d9d06ce7e9ff04a0a5bbdfaa4c410866a572011651439f2dbce5dee667924ac4934d205496bd1d4df08bd0cb3fd2de73a2ef342ff0091e10e15b3b760a575df93cf1c97c01c5ab11c094bf34878206718f6b285aa5cc5127bd7f988b84a90495306fd9e99d8955e668d1a3ff10f65b7c479fac24119a3c10122d4d18a805b247df168c0a5100169b5572d17012d751a42e83376115e11561c160c15efad76d21f7abb430366475238631f84c88f838b0ac404c913d2fa12450238485c302fc201f44151c19bcbdc1190c12d1540831fb19581cb93172b0d2ff5c65f31caff20f813881f84e5ef9d5c165e096d254cadf895249aab8d4496c940a40f907bd40935a94f5e55b6dd051154100fe331770eff2bad6545619b8a33ef6462a50c0b2c4ed2fba4e4e383ebf2932e6192766a4aad1d6e2b692d9f2bdc23393e8aacfba323b534f84edf2dced7c94d51687daa27198a9144b312b716fe17014a7bed0c14a2438733d555c6564c8c1a3d997ebae7b3de8877af53c1d1a5029158a80aa0c87489fef270cdffe10d34b15c1a9693ae0390243e314cfac06ef6eefebccf43d42eac24ce9879429d2fc7253b3ed175825bc4da0762b4933a98afdb94b06f4fcd2ad3611aa999d7c1c8d852d01dd9e52648455a04eb2330a76fd942c531e514b5ec0728a89d34ca590ea99c88faa20dfb7bbf65654aa6c212beb8ad6bf7c777391cd49c39cf8ab51b95b419e3dfc8d94a93a1ef0223c6de90bf96218d8045bd4952a0d8372a5578c6aafa74ba662e3188e6a6e567e4d2fe8227d0743982a41ebfa0d310fe79fed27041790efd5afac2243e1d150b145015d9deab0eded6394ac36fc5fb201f5204fbd422a3604233015bb0a48a920e2e5e0d4deed672025f23cfba93889597e504c8887add46cfef4024afb8a26eeb7dcddb2397b44a1796367340042137028c3307626816c2931e61ebb6b69edcbcb612c9b181a285301ce46f82f
+SIG: e0727eb72e84d2b82cdbd0a6bd2f49496316aae8351e4902acd5e3cc57346e7ebafdd92a90ded76fd0c6690d68bb2fedd613e44fa222be0126da520acc2c4105
+
+TST: 911
+SK: 8a972dd0f1190c2b9d548f4ba58264bb04826775502a8d5c2b209ee88dcea5fb
+PK: 6d80375f3cf1aab283551df445d17e7d3baf9bcbecbbb267052e02fdb69144d3
+MSG: 30b28948939aa263437e45c5c0254fb20e617ed0f3fa7dace5a0a8e0fe3c1fc4adb2809b61c5e8d92cd2f3de93b173be707bada94240c6262c160e8c782165beef99d0be8ecdad6316dcd734bbb90a66cbd5b1cb4fd8f2226cea948e4df76bbe251d478f5c3fe0d6de4be54f67f502b2804f628b79a550fb1ac483ad2ba16637c4bc9da67fb4f98659c4c4394d16b6d14b3e0b0c1e625d710dcc1c11df5d34147b1ec5a417b9e21f908cfc523d43e3f181c7209cc56bdb5a21628695ed320f8d4c07fd6d84aa03426f21644aaefeeec311c74e9499936047350a9bf5b703962e77ce551336835fc32ccbd2c90ae52e24d47d8dcb987abd121d3f746b5de230f26469603fb0c4a8f6cd7973d7da882ed1d6e4d9c5a46ec2c21940ad3389a186014ee97278e5350988b15ecd9ea7456b3cb55e4d3093f13a875b50d6516378ecaf58d752c6374ed15638409311fcd379d122c8d8c59b86f4e8dc46adb730a933846e0bd248d3608252d970b504c813c6dea9fc88a3de641956dca291204d390b6b39981f8c0a6bcfc31ca0744420662a9b35eb3fc211f810a3e8062500b1e49bdf857665ff32a9ba76194bbb77fb9c15412964244b9865f73ded9f25b49b425aa253d807d9818292763a513ec80747344fba0acfe593cc26b1330bb9ade66c4e88cf1baed6d6e7b750e6c7239d7bcbfa3fbe45405a63b96d5034cc0c07ffc3b50858081d1955e2d2fe5be5fda7a8996943768b055170b7fd52f0a32097fe1b7a94f1bf879a0cbabe10ac9a7cc1f9f55068c48e3ccc065136431018d38d20109dc95d99cc2bbe7c627ab1a8aa5f431613b790c2e6526cf04fdc9e55f51c055f3c2045a675e3a1e54ba409f7aefa7e4aa07a2bbd5e4ab16321a9f099694391fda68a74581e2f1f11dd9a6d524b1b83260db57b72ef29c28c8db5c37fd185b7c2d8455090653af332dbc82bfb0db5dccabfb6b28caa350525cb54cc84e553e1cf3954b612393e7993ff7e8bf5ece3f145094dd7a27cb47f227476f289235251f772b3ba776bb773af0cc5f786a3fb9e931a530cfbd891cb5a5dfe25169ef933cc82c9080f323961a120158e4bbd71134ef1f90108b815c289d4e9a9589ec64c05fbb42a21b23d16e2a64678aecfab65cd9a806c598103d41f7009776317831feddd1c9002d4a92204f97ba9490c61469803072102524b9df519005f98af54d60ca5ba60b55b096a4ac2b16eb9cc81973c3135d3fb6873dd9653800a22bb5d0d6117ca5d916553be39c9a3b511eb3db730
+SIG: bd45b3c045850ebef7b80dd1deab48037b1346c71deaf1e58f2a7b162674f94d1ef3d4239037330bd6335fe4f0149250901f00a8e46be5fa0aaec69de06d7304
+
+TST: 912
+SK: 12380c45a79ade0f483c881aaa3730438b083590f404dc9e601f7615f375a628
+PK: d66fc59ae917f76d24ce8ab8ee03fbcb715d5eea4b08392b591e648591c73c89
+MSG: 684523c2e7fa8b4bd7548c4bacaa8678a330dbbb960632940166b2cc9afc1535c80c112c8dc4ada7629233fe909055237d513e292af15ad7692f115aa092da657532f51899c3f7f5d9d407ed5c163eb3950480a4122a0992981f077bc867f906075407ba9849c4ea0473ce540a796744efa3860378e1b89343e583d0807e5a67c4d5bd7ce64129fe902b8cfabd2c21fa3d2a10e9bf9ea5e5473ae250c9160509972678f9a740e6cadb3b52f502fa616cffae1def893d54e41e54d326464c9f435c63505fb15e3eeaf5021c65dcd010f840aab317c8605dfb1a0c8a3d5549861b69af2c93d86c981df3a51c5bf5785c2f852610e44fa4ff1c7161152e5618384744fe83babf0bcb7561789a023125f6242a183cac9549c932733a868aa182656e2ba0a8c0be106996a85cebf1bdad123b982b4e055510879482021daea9d8f26c588e6cd10126cb3196880356bee8f298bca306ec5699c7576b765087c253a60214010c6ed70d871cfc8738018a0edb57f106b4218d855eab2c91f39f858b3f25905631a0eee29856fd34f7b8c9ba51c1c4c6a735d6c7a13d220d7a566c3f506c72bc7417ab37f0d6d796ffc71df9dc7c6e137da56b7a3e10cf0b1abb3ffb70bc66293b5d75b405ed8bec0d6fcd06925c381168ac188d0b8a1af0839f5bde843b6991e5a5d6cd66fe6b0fde867c086ed43876919a1b7233d8d7e1d2742f61c77d8e5991689c8328676655b76a3750560e75d1c7e85e3c0085059331094bba5710032cf679a525c78b31700e6d91f75294c422489297e1735943e417fcd35580582fdd0239b51146530cc09d83b28f0a1d642220dfb99bad62f39541035081d65d778ddf3239ba0e6fa9914b17b397a534cb8fd3b4ff42a8d8c8ee66153fbb1ff0fa54f7bd03278516e6341af80fcd1fcee70c359d205368ac490d75a354512da46ba7634c15b284b24477808f17633360a4b49fb3bcaa841841cf92417eb24ce482d5a24bfd2dac372231da539a05420002ff7a20c476097da06f59f03314e6059fad88c50c3baac03cefa7cd8211d2461b1660ea6bcf476838c91a10074eb4b40e6e974a945a67f6ee6904231ef04188f1ead5baf35694efe301edc7e866da23b5a6c58f01b2a52cf3ab805edc5c1368626b95b94eb4645b693ec880f2b8117a693afbdcd2482431890f410bc580530fef375879c2e46049ca891a2c3ecd6043ae80d8af346634674c6dfe905997de5d05d62009eeed277502fb5a5a3155eeeeb67348b60d89a34a7812639f541ffe
+SIG: 02b25174a3dd5219ed48b2c94ca212b63a6a3a2597703c07b7f0c965c3c6ac2eb450efe38716a2a28b3f89846b06ebdca4bd09aa581f24e84d80fc10ac1a000a
+
+TST: 913
+SK: d1b3430d4e63aabfa9ef96bcbaf1fa6a9eb5219dd44df3b1a61563dffe1ccb28
+PK: c28a05195245290ecd38535585ce51f3c235c5d650c8c57c2f79bb0ac0e80834
+MSG: 076c0c8762e4bc003c360a12a19598050551d16b4b8da0fb9c4afcc81adbe61995f25cbc28dca420bfa9461054d3ee00ad78183e7f26df6898af9a4d225fcab67c042e9a13525d1f75ff0e3d8da80896b728f3e2db65944ae0717d775990b59e5b70434bd4b3ee452f10ac0610570b38220832968f544d3e4d119b1d4b5015c6cdf4cf220b56b5c0ccd8e398d5e4a58da3b0e2b270a5d39b82abb7f9d27a419018550b6200ae51c84882f086ae7ea5351671b6dd960923ad6befc13409879a8df619bdf6c88a6fe1ecc0f0f3aa219fb61902be48a53df2bc66c56f1c1d17f7e6167d255165f174baa9caf53c73cbbb7cc2c7c087f43abe2aed5a21fe4290b8d67960a8a9cbc2a57abe22654dc184cff9168bb697270375fe88d5c49cf95b06cf9d0dac81fbd9c0d7b82d05ed2c3fd49ccc29404441712545f9a991e4f0ddb62190838296f967299a38607226d8a681f0a8f3c4384fd18b30257c463c0abd0f4f6f1225a51b762d6d0ac7d59cd2efd698b8d13e23d70409f6b07d695c1671cd6f59443b1db0ab35b9dc0640e4c6d1ac50475d28ef94f81790e2e5b2545514b2a49c5c2153459be540890f53bc18e4a16dcb5dcf50f37a95c606fdf48598e52af3179a2048615d93d97e0599b7088c1174bb9f15e37018f99acbce5b1302f8d8ce2ab85437feeb0caa7784dc83c9e7c36fe059906b030a86a3ded0ab9d8b73529d475e661a0808d6d3f0907f8528873f08d5748be1d69712e85262d77bdf13bfd18a5cde6f71462673ab29b1617315a9a6e936a8e81a8e43bd0f6644a5c69eaaac89bdaa99cca803833705e5afa69b3bd1d0252b854650f2199791e6aca7c75a861283216233a2633a6aeff9d301ee5cb4dd72c08a45cdae8f5458c095b22e759c43b49b98e9f4cb33d5dea879449eae73cb874c73594325ebf68c1ed4064b6f61ab2f014a2f19f32e12b33c5eaa8a29204d5eba58dc075072fe399be7d1ab1808208fb408123bdc0b4ab3130f9f706dc3eb194b605e73a32f125ae491285ce6039fb623c38b81d5aba0f5599f6c86e872486b4e9649daffe3a3d06cb073dd3bc6f4e10a18700e45722d78a6b0972dc94d5c7a7b6641757b796075719d7b8ec36a1e796fb5f8fe6f1b79a0859cb4d67cec05ed914cfa32c1ddfe218ef963436c3a1148ac2cf909df7359890657463a4ea25fed59618a0681a1217e22d64ef9d9b4559d0a0f6b3ce8d847930b232301caf44cdf7a3f18a2ac130b92cfd9c03360557b5f7c4775462a1071f70344c718374b
+SIG: 4cb6ff5dd706b1ae816cdbaf9e9e1edc80a66284f94652d50ec14e283b2adc592fd084337144ffa712dc34ce8e610668a65e969f05ceb54786304d0d58d31a08
+
+TST: 914
+SK: 033e003d7aab7bc7fc8ac204c733799ae553c3fec53f10dbf795b5f4b87f1c95
+PK: 682f46f5c056dd45ba0b5a782031f9596a73aa292ca2326beda74a52fc32b716
+MSG: 596aa2c40b3318878938ebc138db274bb38a5201eb7caf875e6c645791dae012bdefd485e6bd9d8499c42a2ae86cf32b18002e76bb582cca0dec4815ded8a1211f8fc8857fce1d57f6151d88787b978fab56bf926b1533e19499e8bb99158cdd6e980f6ba543ae831f9dd134b0fe6d5c24887dc7a8d4781dd9b7fc5dc9464b045cbf9d1ef5036b5bf28b549ac7aa8fafb91adc9feca7a14554d110e310c749e48533f359c70f05fb7aedef136636b8ef7223886539864ee52d34118b4b8b74e08fe6b65896e4b19b6d7c3f2528265585481710d2d74948eb4b1708a50fa74021bda4b361bc68d2a5d202109f8d28d8aa67d78c1136cd2e903c8dfa175af7bd963b73dae495873ccdae62bfef885636dd83550ff9c05c37ba3389d1543685d89483b0c104e7efbb7702c5a0398ac720484c50936835ee9df253f0ef8cbef3e07de969511ccbf87557493a0b972ef0e8e629cf3822db21286ed727661bd31786fca1421106dacdee1caaf49454e854794f704d22a95a4c8e6b1c2feea57e56238c2096f1cc578647fea544d6764482bdf5148879a25f943db16f29021b9ecfe3e090b425c81c7009842e1c7a02d91ca60c1201c3bdae9c5373af03f2f4dbef40de8d9b21fed68dee510de0427234caa1c20a3ae549954834c93373d913b8750f23a03780d7a9454ed6fe51fd2d276b9d4aa32de05e03816e64e9466f4f0e224651428d342cbcc697170a47ef996bdacbce91117ca1f8455b25b2b08443e9914e3d90c489eeaa7731ddea2123d55d67b16683fb7c8236aaa5a1b0fcaf8d170011dbe9aa2857be612cbb85ef69e56831b4dacfbc7a59b465a66dc7412ddb3d6af4ebfd705864e7d4fb99a6ccb48b118368feab02a340c432768de0e067871e9ea808d6d993815829e71f6c042b664995098fee94d543df15e5b16957031bd238bcadbbdcc576affb640303d69c5b250b3a539afd127f7ee2609e52e5154fbdff3e45f9c44066656d561e0f64dff2805df88e30a380530822413a7ab76a1b9a865378d24763069a814002a9a9d03795ca8d2b5bd1090393e9e4b1ff7d7f0eb84e712a018f68c9e384f0a0aef3967879284f409e30d2365086e66952278ca9b6f90e8f69a48d9b28bb4c4ed632abca3af4144da7422bf51992f734731453c7a33e15e59f5308129d6a774a94586f723311179176c0948fff4e30c1b959812cac977cc74347b007940f2fb962a90d66066a6de8801984dee4a532d4b0acd6dcaf06727bab70b3866232234c9100bfdc669f77ca49
+SIG: edb4e020d676fac6a845534880bf6136374a8b7f2c5385bb9ee225381f494efb74a55b413ae0ea70add61bfdfb87fb42d5bc0c5359dddd573d538ae93a6b3609
+
+TST: 915
+SK: ee55fcf70a275c726bd4856683b347decfd422f1826c07a932cb85be9fa4ef3c
+PK: dfcffb5e1553789d56a9f3914bce500d07c5ac311f927854b2cf1e5833c03237
+MSG: b8c845cf7c5485f0622d1ddc17f7a0f6f0fd7074fe194b0e0cd42650cfc817f57f095f8cdfad1ebe0dfbc1bd7617ab4f204e9d55d81a7c8a433940ec6f17c8a8e3d56c1afb0af374bd32d54ef7132d26b89c470c2ab5be16fabb4c75193d6da59ba2fd157e9ea4e0c5c08a5202f5edc6a61701f08bb344ca6455d75d145adb244c534c8cfc623f4d4b6767594b39a7690beeec4df9746a57ffee051454c4278ea43c810ff13cd769615f9d05d4fe4a51583e80c015dcfed9af05f93d054d34ffd939bdd8f0518fa3030a964dc9d80df00f1635824072cdf29bc80259209d50f56fca9fbd6ae1514a671989cea4f6846bc19179097cca40c624d7edbf91fb5b2539ebbd502d3646711430bae423fd115848093318b7d087ef1e3b894bc3b9ea27af853fca8595d36fb7299969162f2ed6a2b55075b2c630802857176dec4cb5acf2b13a35a9949b912bb57d81eb0c8a8adf3cf64cb571bf5f3d71f987d64d74e919a00336e57d35ee4eecfc657000dd5b12995ee1b116591ce58e56de25b29c94829d1d68521b9558e4725ec77039069c0cd17b2a003359e9e1e112c7590176cebce7f001f1d136e818f4818cfd94745afaab56f1a406f97dd9e61b735266d682ad7df26dd70cde0b57fea7db2df832fa88a35f539794884ddc41218403016cb6d5221f3feb5d3aee4a9840a913072d29f8d1a9367bb0bbf545f7dae7c00a0d0c0342231ae462bb742e1498ee584ae6c83f2f1f2d0452bead982268cd3cfde78ff422e226bf7b2af1137757797fb02e5275c34809d54ca9ee2a65275e6e5cffdd20ad1fa1ee0bd8b21e04ce829e02cdb63c48bfcdd86d3a08c59789c9d78e36181defeb7227107275ed6b5ccb127cd72b374e17f5ee0b5e47b4b3e14a8ec6d86bb7507187f28db32b3f3fa1ca13446fe5253ee783645e794272799a863b4fca99e443cbaa05de3c50edf3d5cd7c10529c6c09a0c1453406ac7ecafa9b3a1f369d68f3c618f58efc359df2f3fcd2478b55a41a11f2487e7f70ec293b3eccc700ef444a33d1eae9849c5b76d29afd5a23861aef4f2a7ba3f666301fdeb5d3d8f0dc9ee2e014b24c7465dee3c0964edd49ed49edabb5ca7afb99574d001e5812a085231f241b6b08c73e80fb44bb2adf554f14fd6dce94a6f63623d9c1deb41ad101651a6b67ae5234daae81979fbd823389649a3b0a06c68b80468a991d3007748751fa69281db1b94d6c160a1cab50943cdbb8dea5750906b3c6595bb580dedbfae57464cc7a651d4c51dbb5fa980597d17669
+SIG: 9d8cb2eaf3ff3e0c2bc672e1d255c5b8e80731bff6f6aba517e13354e851080f4a8bb8121b2624244c9ee95c8a092f103703fbe66f9cba100d2e91ed774ac907
+
+TST: 916
+SK: 49c298a2db3d2589c9fe16a4e571e5aa23cbaa777b86470290a3eda7a5d3e96b
+PK: dac523d6374c8ff15fc4ddc713715ac35cf5547fc1b1b2646b63fb41a7f21621
+MSG: 3582eeb0d371df385de88baad380cb0cdb60eab2baebb3c79837753d08e1cb78c0bd76dd1104454956d571ceb7e6b571a5236835d784b50ff66057b13595e7d0c8f25d08ae8b54b6123ba08151ac7db0c56a980f7f0bb39a54b437f54851979986ab1367835e5c4f3a3b3d760d3827e76c568ae7aebbb612e775bddeccd334ac6bcd3253abc29d4b7c3f10362666f6ae75080370a36cba55db3a91cb5789e4d6f9efea4df1dd7730a5e27960d53b5121948cce5af653fff1d5b4e5b0a88c718c49b31c793d88c1cc45ab8da29d05e906cd0594b5f6638c8ec3f1760ba423b5ab1d08a58770afb0f139abd349c1bf160d8902239ce24f19b4e1be095f7ed165f3931e3cbcc307e9fc5c658031228e55cbbeec0d0bcf8f695154a9eed1bef35228789bfc0d238b8372d318328c1339fea08814db8621abca3aeb82098b5aa87bb98f5e40522a0888532c1748453db2d2b3943e4abb312de319aec48cc1c94775972953fb6496b8168937623510cd48c8b247956d3168486c176ae7a4cb384eacfdabfadd9fba30a23b811bd779f3cba54338c28bb3382238ed3b8dd21beab2f5cade28c5e09b31a454808a5348122e3ae3812296f7869c3865c3c9d8fe18bd812f2e60e914975cfe1bef8dbb8097006f0d7cf3fc15eb95c27854b14312b88d528015af69fb7505b8f32703f64eb1c958f046dd251242f8bea7467fc7291d095e9696e11aa45abe7924e856351535aa0773d3d9e61cc9a2d89b5b0774d7645ee1af7eb6fcd440bc69d43edeaaf935fd2a5295ac19a97d70af9298830f81c0a509f242f473372478fa5879fb2cb8511080fc2ecd8259b8c3ce9e8b640761dc7927c32e7f5bae97a8b8ac935662e5f45d14cad6d34affc9a19414c4566f45f977396710894c5399ed4480f18e90957faa76ccb512a2d07573058a95b42fe1810249d1c85ec431a049d1aecb0f118379bdc3f1ee490bc8a054c32c3dac7659966cdb66f995ac403d5e79eb6b25b3f3f65a6ceec220d66c05f8a8a98b80799ba4f2c6dbbb4dfb5862c9a46bca013ebdfaba7494a30ce14606afc0b0f993143fedee7896d9a6bb81499166ed02e94186aaf32187aeb6e282501bca43b57b7efa0939c934bc8fbbd26c44b618335a35c692ff996a5b95d327df9b2a6621b3b0f190db1f36d911d1a663a4ebf9a2854bb4f4061095b69812c82c2ffe3f92e9b44d2ea63169881cae8453d6eef7cf69c25a28b3f8ddc70148ef26721a3c1f2e62d9d10cea42fca3facd74673a4e7f33507364aa286c0f38d7
+SIG: 2a439c73c98117fb2952e2b161f7f3b99e7d39bc697f794075db7b634d29f1ff5724f677f8312ad515b097cca9dfc30e79ee8a7c9dd728bdd45df859c7bde30a
+
+TST: 917
+SK: 823f0c29fbfdd3d1828f3055e9ec01ffd1b5a375118ddd7e4e0c43719f573ff7
+PK: 73125fc83abb8b7c658559fc127393231d03ca5846e0c88118d13d55ca44789d
+MSG: 802c39ce7f2a50bd81622add0df4e0fe03ec3d2d305a45a6165271ed79add243b9a00e52183192feb24c4fdbd22c807ae100efcf165b9c996194e00fa817765ea94a03070e486686b445fcb263ccfe1f5862f3b84b10f390080bfcae447ae0069742b8618fa9575f7e637ad54e834caf0394d745032ce1e255c0273250f1504b37a0add94aa245c7de52c80e05d6e0a96a14410543826a49e9b945626d4e89f55027163d4bd6d0e9bd1a2477f67d3d5668a42e94d8b61193d821e0d1b230fcadc53613b75b02cfb8158456077ebdf5a5f00c3b5b186370cafec4a21c69dce1f01efef23c37ab90f858238aefbe212b556d2f073406559f1a51d84efffdce07b00d01bbf33771cc12c960ac89365a9c82c52343f7603381b89023c1a6e702a5b1e4bd191ea6970b5ea451ea05b59bf83e55f29a1f803212bb2e58f0616333d9114708529e8b6c6081deeb7c299a5a2a53ccd24ed58ffbfe503d80614adb05ca11cf29ded00904ea1239f82ba40c793ebc339775f8b0fe3901f5482e310c793c6e2cf01dc157727af238f49c9862804b047551fd886f4a4899e22a6a65701117a3858055bbfe966e370e733e17efada2859fd8ffa9e01fce5606a255367678f4bd4e21e5da0fef30757f34e389f76b7d57c4e410a002e900e48fb218c8f2778f148fee56965f5b473e25256c23a7af198342cf3ef02b84df2cd5800a461c1b07bda2f42628a68ad29dbb82a470967d7302c993b234136e5bf255e6248b102c2bffb20172371f1ca3e10b0810e8649503546d9a731cf19b083357d4cfecc89bedb53506fe199b670391a620069a3081f253b4d790880aa23b53e97c75dc0c360540e5b0a3efb1accffd137414ff8423d54646fc56ba5f53bd84c7267c2f7ee3e37607544154365f9f85081dd7d2ee75d302275c799ef2427ca6496355dcda1d44e0d977bf68db3006500ae3f400d6a8c7cf47057d4fc87eeecb02116b73eed6ce1fccef6e8fb8aea363b2f6f5322a5f0753f45899537646d58651be9037bf91423c2986f5cc2bcbce4faec903498b40fc2deab6603d6eea585d2720d21bb2722bc05b35aed2bcc0e804fe9d239fafda7ddafe1d7860abb0fb28f4bf2b1fbb62a786e455be024b193b7830be0d558f02c9f3ae31dc107ee9421dc5f0b0f89402b71a4581401536bc47308506d96939a206362744e27dde944f4096a12b5f63dab64d041484d3fd91a62c2f0ef9ae787422eb27fed0802e25f9bc775c4915a837fe3eb7b9d5843e4d8210c6b494b61281637a6be32052
+SIG: fa747b6fe3381ad6bc82a95643c1f4a20b76ba73bff00e635d64202d8b0df03dbc56b0138b3a6d4198ffaf58ccd3d388ed25ebcf770443e41e9d2147950a300b
+
+TST: 918
+SK: 65676633374214c4ac4b7bcea9f1cc84b1b7e79411e310525ace385f4566c1d5
+PK: 0e6ec5801d8bd6b1eb421421a1408f134cf712338e0ffc24cdccdc4f7fa31dbe
+MSG: 9d622c206787694093c6f29f93619f21bb64c039416d20dc708a084a9d2e490cf5658e13d62cb0d21eab00e42d851bc6ec75daf405d2373246eea415e866291babf76497680aaf04425a42552b107d58cd18561c8c9483f740744cbfa6054c1b126f5a76659ac19dddad4ab5a09155d8c050b5354e06a4dd3ee3a6f9c91e8b4c7af2749664e7abe97061589e153c58e27cf299a25f2b530c060731ec0f4366bd1debeb4d4e912e76e508534d433ec48f96b62e150de93963a1b3e6c8091b495a96518ce3d3b9a8dbdc2a13fdd077f2231de8d76f56d9ab1c2f9efabce4638364f8fb2a2c683ca819b703ab453b11d37a69fa4bcb8023980834f7b902ad1819fc029212fdea0abf11dec88c55d68ef87a26dbb15dc3d3dfbcdddd5ed71be86f32c76ee2221d9243683df9516564b26bab5c845d4dfe0adcc7cb9fe1ee2c051af5908ce0cc3a90904dbc0d3680ed4992f46ce25c2ee851c414f0187d893e5c3b0189a7bb6893d683f5e3394cc046299a16a1c1b5695933a89bb13030855b81b3c74685f719de0160575a0ff0a91fd94347b8bcbe125d1d3f9ce772a8126e00f563b3189656d5522c187ab831a7ade7ac06fdcac7f1d45882e51f9bf5b44a2daba4a53dbb31970b4a0f1272fe14087e0c3c7e4542312fe74d767f21e7ea487d5284284f46f20f32c5b16e1e0ac8d796ab2f80b344e7a8d84d5de823a50897752dc549a48fc10bcd436a7a93e97cd05d7830138f323879680c343c16467d264d749bf45e40f39fbc3a00c43b00693b0156768ff2e3f8ad9eb6405022f5cada6694e8a33cdc59c6673c44117244eb03fd7fd675930c294edd2940f5f180953d910c55485b2057ae0c9302f4a8e831a5530e3cbbf6f472224083a952a8390ab00dc0f69dfd880eea2d739d218d6a66f237f10d4401aa758ff8120c0ae2766127849024f5a4cc574a5b02b935966812cd1fb6d79d0c4f59ff80f035a0b109cccb22fb08535b874149edf2a0970c14888427d07d1eafa684a6d3454e49b225184c6b993ec8ddb8b5a35ee45f87f69266d49096a317d86ade27f4529fe72364d0b958007299d9de87d6ff9fb04d573aea46bac8eb764752eb465caaaba689a6460c110730bdd08b1689de7b05de59af9fe244ac363e95c98b669359af9031a3a93ba631abf1f61d20ef7fc6883b4840fc926712e13d874b722f6a79b16070c0311325e9a70fcd86916cfa1da7f9d0563a22fe9bfe854b0c186c8663b061b65bc071e839938d8fdd7cf8f6952a6467fad8e58490ed2b26813301
+SIG: e0b867c9dbda35323433c046e0830c251b4346c5395972286b3a72310ed4526e545dc09d3918f2eb9920bc9b241e9050d848d3830288651591f936d3bae45301
+
+TST: 919
+SK: d2ededcd853206cbf59bd74a25a303fa2d6c3936bb48eb42f6d900cbe80772be
+PK: 2244111e2e769eab81871e06c580178c235c7bf4a52d2ecce11887a9b46c45c8
+MSG: 8070bc0db089a5925446019b7e403c74ec78903e4bd54bc1d08a54a6f0ed75a85b763ff54dc33a2600ccb457fdbaeae548477f6d6947ae26deb71eacd1d2d62282a083843be4e5931d91c93b6282c58807ce8f0d880b1438dad8fdcba8612df73b9faff3a9f7db3005250536aabd98ae027a895e10b5cb7b69875c0f3993af245192f4393e9c4d3405746e311d3a91447fcdbd7306b6020c933bbab9e39d13491625035c9c636efa1739c3588710a879d9e3ce1764616f1082e8dff57559c3f5a5d76dd301124fa489fb949e9e039dd4621bda60f0b86b311e78ed0ab3b528965044b23d78ee2f81061f8edbd6929933d18c0207dec4b5b6b2fa4aca2747cf5b110df00b0c9827bdb3d9db2c7b0328d40d99e1f6b228e40dadae78aeda0289b6a23d4eb5837088e5d88413632ccc22e21a73768c673201e9a8d8dc6eb6f7397fedbd398d26f9692ca72f6d6cf056aaac50ac2f3b266dbe5e7be7a024774578ead585245daaa73e0aaf833c070ba4b2044ccb5e5cd16f9c0ad92ea8448055dd828c79935aa6c0741f9e2b810324fdc6e61e842f94572268bf7d5adfa7ab35b07fb19e7815a8aa5d81130130ac5cda8a4751ee76038c0a6bc2faba4c497e62b9f1f194b8a599b07701814b6dfb7d84bcdd5b7b5bc2249f1d3845eff9ef8cc7328535d70d53c7aa0c7305901de7c4ed2fe1838265d4a417b876adbd88eb933f27c9aa48c8c7e34e48147ccffb2fb61a348fea13ef67cdf2e039e33fd89e2c1ad2a4254e3bf748452aa83efeca46e780ede1d13ff4cc5e7d01ed45eb8c74818d4860af4759a83e148896ab68734395760e00146b793c3e72898aa0b3c5e0c1d3fdf12158d2e8ff1123a3a0c64cf6374a7f44f11a575e48a379181b30a4865cfd022aa983275635ce4f2cc40bfe066067ec4fe241fa047b55270a1ad0776c5f96861014cbf40a0432c559f22d79342b79f8e7042dccfb1cf50f83085f8063fb1887ed2dfc9db7efc96daa0ff2bc4f52335b02112d16392e134c0223de458fc072cc22bf9e7eabc06208180a57e7ce4805ee4e0fc015840998fd568644a0386b3d8e7dda52abf64f7dd00868fc84f036ca8a78e9ba8171ca90267c74e6159acac7af5bf23759abc53d82e793db87fdade1363354ffdcb0bd4cc9213f5c845445fc649b2a1f329f9d41d8a031ab46b472160f03434b4b6bc5a401524d6179ad66f9e221c9067fc87fe4a77e21e8023b6169ebf1090cd556a9be50b9187fe4607c5925e60b414f6a5cbf8afa15ed0eb34b67b4c9c5d54adbe640
+SIG: be3c2b567fe8c208c98e7197117eb01b3c197bdfc858562dc5cd90f8e2c0357042303995baba2f40b7345c56db0b4625580aa8dcc48df6019d23a838ea717202
+
+TST: 920
+SK: b569f7c1aadf56ed1b5fa1b6fad648d0dc544ff8fcd173780de41a7d4de60cb6
+PK: 9effa4aed9c658e4346071434468a0b8a04ecf7841699d63e8887ce205570cea
+MSG: 7c5aa4dc8078aa77e8b3b7fee61084cfad764762f1ef26d8deb7f2f3b186dfc772487550197845fba2f4c23c835b9b58dd0b635c649135137f248f5ef713564de3c966efa5f6db6bea9e30970749f8e872d8d7ae4535b75e176ea0489b915f3471d827eb5b444586488cfc3fa6a45082dacb826495e50a3b5dc6bb930a331f30c385bc3b24ce70b89596db6bfb687d99a581987ca876ea0e757696b3fc03779a658130c410b344edacc4277d44845499d678e1414f15f36e166335189569cef3567ac2e3ab821c91c93274f5c28a5d1f7c1bf5099b10f84ecb13a4e4538f6649bf74f7394b703ef53649d81516cb1db521416065cf9f276ab80c9308897a27dfe37e5e142f1819b8d348df50a046a12888e3b7f2dcc70f5218d15ebb9aa7291a1a92ac445c51d3a53dd691efffcf5a01e876a72aa481eb4f121a072397d8cc93bbc2c9a6c28cc89b11ffc0e910d82d9d6298a367a0e1e3e8c865e4326a319b22666e529f1998f1b3c8efb5fc21cce97040fb6247daa0000ac5554d89e7b27159dd0b1800b760b79c91ef6e970b1e6c5ff42442b1b3ae4d3c439e08ec2f6b94177387ca5c01df6f07f8e34d25edbd49d8b74e31a5e65dec1f8760fa22c00e6fb1cd555be68b0ab43599f0b9f4a54a7ccb062683895d5ef66d24dfb1678cb0d0e8c801d8e5ffe79b9139fc96d118eb39b9c8d4404489325d45b4a3202beadca66f831c68efb815941581930ead29fd5f211b90e7a39f0d4ff48c62a545e28ac2ce29bedc356d92fc00347176d77623e0e1809eff3fe62b75a7d9deb727d86172d14edbf2789a57143c69925c917d433b4683b0693b3cd9e7e377996410727f5e6fb8f5ccd1860a20294ecf33faf97a1e0f85b761447d4761b96e4df1b312bd414cabcf498497b0ead67cd1e5901bbf3a16a8891ccced8a907df88726952d4ab370a6b7df2942cf13615a5bc12b4e106dc3013c68b8fb906399df15f1aa90d56aa974b1d2b28c1a8453b9bf0792a51c97ce8a12afc9341bb4c0c37b12dcb12c639449775d9ac5c2ec49673da5aaf7493ed5f1f2116eaef72bb7fb1e093ede2c26317f4f4b6ad585346205df91a6e96bc66d3064bce952398ffce88071ed9ff2750c65c0c304125ac2cadc4fef71a818732496a84ca574d482d5a3bba20e16dd2fa24d3270f6c60992f7f63e88f52eff6222998eb4416727384375f59f00e47512ee464c3184aceaff3ccfb06bd15c183c5e485926288b997bfaaaecf6ecbbf7d2abf4906df76b1277c5f5a87e6817b1c636e91efd7eccf64f
+SIG: 2e32ba0556bde974d7a19b3b9a1e92f183924c4b74c5d751b5ab3d007967016ec03afe91d742fb22b63e5e55b2fcb6c61a46e9dce7fe9fa30bbf66aef4b85f09
+
+TST: 921
+SK: 323465d0313d1001a261abfd44fe65c38c9a00ca0f20335d6553de492699fc46
+PK: e22f16bd4cc7e94c46ba31961af8c583f9d2718c68f73d85069f608e15ba8766
+MSG: bb1082e1cfdcd29bfca2464d5ce446b5ba654ba58c22538da926b8303cabfd284a7bd5994a786fa66aedf0e15f20c382cdacf3d14557ff7a8267fa04672cacab767008650aa9b4a7c9071c4799f1ffa45ca4d586e02047444c14231943467a3abaefa53959da226eb0c15392019760159697748293c025568783588a3910e78e5ea427c4407a8901061b8b992b82a2df58c04a1b2c5fad11c6b379856c2e0fef8a950de7e0fc22310309e08b132b0cce4fc1ecbf94574a388d4ae36675d3299a951554ebf180eb381e1b5df977d938433891bc478d7681850b9dc9c5c769d405f5d8839fc97361d6cb306c203026cf2e2b3d39849e1f4b1225eb25ef8acd40b006f20c644db650c75d38c0fcdd48f598c7b4a60106e69e19cd712589cedccf50864ea5f9e95e01f1dd85c7514f2c94b28359de4132b88c3ee1d10a80a9fadfb690e3d88641b3168f0b896af8990adbf0e4f8e9d3f9d4cd314e12c3bce0cc8738e0cfc1905be5efa071f710b32f8e5898c60eb1bb8feeb74000560f41cb2ebc32b2600b6980a2a4064dfaa3797ec44cfb72d379f8097379cad67ecdc0c32414fa41c72b1b9e4edf5518cb39fe9092b439af3a4ebd5afe79bedc0ea8bf17479a2821f5e9bd91d7f4aa5e384699523719b6957f82367cd85fea9ded6236a207c94cb373e3393cb4fe11f90a1b8779e4ab4c3466136bf21e2aab78f7d2726db6414fa5c4a3f7313ad2116a6d7ce40aaa1001c2704d5b05ae54c7cc6f567217f1a47bfd0ee738eaea5eadb5371075be076c8750aecefc417ea7bfdaac3cc38bf16cc26df7600e3c7e8e431f2676fc2a8c43a6a14368ba62bb32439a06beac38a047b3745e26f407ad823d6ad1c0b6a44341e15fc9b331214ffc89698211b05133d6d3433b5d59f7ab4d109e54e4c5d6f32fcf7230fa4e2528c861bb21ccc9e310e9497e077ea675510da712b1a5df575c5d1bf7362d071180039aecfaa5c8573c24c0f4ebe81c2f889aed3de5a000be12fe3d0af2dc2cd4240e314a176c553efd5cba798d9ff1e3d4bd9e90bb8113e3849d735afa4af6945cc57d4c378db84f206ef7eab11c637a7f7260f122a97dff6747e9b4c174ed0d64f9efd7fcccf981519ec580a8182547d17968c40151fdf6d54bc57a9115f040fab5c100deb039122b7d2bfd98b6adf38f42b296ea3b378a904259b75d60703b4840b3f5da09620a54776280e9ca9e8cd924aed2b5dd2b49834e581caed5271cd78ce08e4bba49b59cd77c1b6276649148ab7247f97fc0131635de474d3c23493ca98d
+SIG: da3aadb34360b2da0c26542ea71defa8a0bf7fbdae3ee9e11c84084ad05cce7ba7d94de25d8563982616bcdb5bb6395fac4a7e84bc77e21ed36df75dec990b06
+
+TST: 922
+SK: 60ffdbae003fa2794fcabbf8f5b41644fe3a7f44ed6c834193da07a9dc5e2665
+PK: 35b5eb31ab556492578b3dbd6cf1687d1fdb216a725818079663482f221ce421
+MSG: 3f8ff20bb4f00834c80f2ee6893d6f73bf7ace2729601bb26a0fb272a4d0eea1fae1d306ac2c5f32add60135851da27e4f12e64ea5e9e9960b1383b04ce05a98b0414dad971ea98944871d415cc2c46da403976d9f21938958d4ea8c7903b14f2a4485fd69afb24abe102d8fec266fb468b411eb20a339677d88eb31c997b4dc885613f0be7c70daf856a3df92da9602fba2e6749d2f426beef68662d5b0c2fd31321b22b5ec597da5d7e6a288ebd9443c5f39eb87dcf4a5ad9d56c6baf6080996a77936bd87dc3cb42ed4c4d42688a9e193829b761ff320e2a66cc67648e70eea3a1f2f9b9d5b4202fb5a39e9adc609086a9be2a8323ac66931bdf6c504d3336211e46fdefc481fbf17f613dab1fc5c097c92db0609906d78b25a455a3045718efd3e3b14e252b1ae59c7c3893e31913b2c264c0ffc3b606ca1b01dc47ee828a08e46af604e590def44d27aab93a403251fca0772e9df0fab7af0cbc5181efda4da913d8eb6452f6cecbda204bc72d7c990f60ce0dd83c634e912236091b0a6673a7c89ea59308d55bd7e63a8526774cbdd7a1339fac2124c9022abd6fece7f2daedfd87fa683dc0e3ef40806a0ab198769d3a99fe81a99b68600319087afa4ea79d7ee45da9cd40809f4ee8f4e25a0177521ee9dba8b56212e88719bb7367336f4a7bc7122b41a7dfaa2672f92f23403a10c4fb25388c6b20081093d49f3be8a9e1c634ef7ba96b6d523dd6ff613c0a23b60457026cd485ba8db61d80a0dc659d9af42a38cae777fec68e39c52986ff9fc20789c10585107c04047b66ba14e93fb904ea90df7ac9f0154c96f3236acf6dc8b44f554c0cd513193e5dfd87e085ad4b38aa4c5e36b2427722088816ecd2bc3a3dda01e4fb3ff5eec7a6417322ba6a27773d24495a839194a4a582fe5abdb8b5d533a24262589241fc81fdf5e79fd26776428f8e1ce9e926cf272716e7583abfc67a94aae0816c1000a196170bbff1f45e5ed9e267ace1e4d915dce7216c5f404def6fe2bd8b28b2eccf3e2aea0c0d6626390274e47e745ed3a23bcfd21d284c395379dc02080f07936bc154e7b99ee73db188bd2a394e03a01ffe2d1b330ceb72158f958c716a81711dbf65aff8cd12f5dfa53b376ebb8b98f8628f17ef8b2ab9c0bb68412f4e347a633e2f8da1a556d96f4af7211c078079c10541c07dc3722d18dab8fa8bc4925aba5c966f805040322dfbbbe87fbfeb1961f5ccd40a91b997e54315a7eefc3a47bb0c87dc23755ce7227574996f4be7aa344fe0d17b97bc50c5838f99292
+SIG: b8f3e1f3785a2a39bb086ca465c0abf0a3e87443225ac6e966ed9b4531c54a894a9abd01ac31b85757fe75308c9594ff65f97cdd91e8d8a93cf12b9e6dbee90b
+
+TST: 923
+SK: 174e993d9b81f2af67e9ffb8ebd5da417966a9e77f66c65c767738fe8357d07c
+PK: 3bb7386f1b1cbfae553703833ebcbfe2dfff8c899a0792d7ce2322b5ba645a5f
+MSG: a401750afc4837dfe3aacc284a597145dfef02629ef87bd0938d443979df76f29fcd66a5b71ea8ab787277e3056f6ea11b08bd238979f9d3b062538c4d6040a86b6e32047aecc59c2377ad0ea4c40c79ff9fe98c958b2bf25f2fd6342432636f5f7d5bb0d2ecf18183426c73147984d95bbe162e11972ddb78a2a7c345c5c0bbbaba9cf38a2d5dd509a7df8b842874a96e64b5d64f5c41a21d208d14cea7066cf22dee0ca41aa46ab921d4ceec89ec873f77960eda60d9676cfd0dbfaec872c2ade8fba4285aacd527143ae0341d67d0078119653b5d23d46e6ef70264b1b0913870877623716d0f1a59021be74c914b432471a43a29f2b6dbeb6a223e2dbaabb820b4adbe337829e1de0c184dd0d09f9d01d42527e5d40abbdacc8ac0f1b2c5c1cb2f23876d2d1b6b43dfe482f9d45a18f5c22b15f1fe521ef57b08aec6a3033925c7454c93e6319e778ac494fb140ae5f1a31cc832ca2488651004063bcff8fd9ae9266af527f2c31f6acb8f3debd9978ef9df0108e3d50c491990c90dd8ee9d64ea4ebfd711c99d9044ec11342c5383ca39232ed97a07e4dc51db4c1fe947348dffe70a95c99db14751314801f13fa2bf42d867375a08ee9b3b799e0b15278e95e91a8968064d6dfd8f5115438ccb8b516ca0c41dbb19873c6e10a236ecc2dad522f80f01c14e2fa14a0d792b9fc486c6fb0efbdf2130f02df1497db5aba8be61ca70b29388e4eec7e0694a38c0d03c59bb6a2dc3ccd6dde1e29ee2c1b325ac72aa8e6fab9138f8b6f5d324d46af3a3542c8bd87cb04fafc54b5db827de606762a097b622799ca827bda9c1c0bb267eba8254a81c6b858a375b94bd09f39eeb88cb14b8d46e4740dc1ab42a895f86d2c57fc28b07b7f60fc4f8847b8bc8ad83a2481a28f29bca3510ff8bf1dd7581e3357164f4fe920f9de839376de064900dc7f8bcf511dc572e0f0f6a75b929797da41c52eae6fe13750ce351e8767630badf6d7d4eab90cd1904c96c048a9acb213a9e5b864615738a84f222986ac23554cf4ce54e80ab5733c065b80459921dd3d8372d0e8594d4364351bf041c146fa8d23a193eb807ece23f24ab6595e932c9ce1a759bf788914db008e87098dd81465e2610647ac38e088666f60ec5d0e2173320a40cd985f0e00dbc2b4570727483a8c25f6fc1e093bb57ccafd1ca202f2986c7c5540a7c3e10c4a6fc26d1d62c2ca5af8305ceebe42ff96e7dc548214375e8a7f9f712ba8bd875e43ca10cf9b183f0c8519512928538a478cb98259bd8b3e334bcc4635595cad3
+SIG: e607bc9a5360b31da56be1c544c2000284951d8689f4b722bc4673a0c8489b84483ed8e76e297ea046e85b37ba5630585e5375566a187afb5696661e5bfdc10e
+
+TST: 924
+SK: e53715fec9d3b20e9c2991e54b5eb0a8cc81875569c95e22a200136002176004
+PK: 5351899b69b2116bc7f8a8814d1e5b9fc785698bebd9ab14277c3ecc01ef8b1d
+MSG: 8431cd16d5c093775e18c08252c43f95b1017eb711fcaf73e1e00c0cd6f3448744ab9b0e64335518c483ae94deb97677f818f0e81a7490615b7141b9c35f80556e6971cea28e9a32c328cc2669fca5b123cb662debab2b98157764668070e18edf761ae196bd4b244fea7b74984516be2c00739e76e6c4b621cb3983765a20d84778d5a4350b168f6a0f712a9820a85a636faf92c789c428cfd2962ed207c3ac8899c258cac1adb5159f764ba37229c5cbf783fc9aa4d1ea46ecc85fe0961485d4fc5cb21df0012ac9b955373b1422e51afa1c550988862c86133b760aa630fc0acee8989117d1dd96e3e6287b69287c590bdca9cbc8eecef281ee6d1c8d88822bfea5fa0f530f23278093c7c85a0d44c3a77404ee79f1c8368cd7321bf148fda4dcf2eb07e4630ea422587586371780514536b894c524e6b83d5a76a15c83e95ab314e07b34b98cd99e0770b4eb9b3f3f505bae8a06f7f950258d790748107195eb4f6b84840f8c0590727396ed14e3f53239476c4d2a7269b2e1f972fbff33e4724426745ec886a32916295e70d468d06c7dbb5ff9a354e1ac903bb45ca526f08b49a65e82297d8dd3fb25aa428f64345bca9740d9078dac9e1138c921bdd74881673d49d0cd2006811723de287c6c9583e456a01ab1a34dfa1eaa963b71e8bc7fa8a98cad4f941e4b37b60eef923b3294882350b38ea4eac0e9232e93c532db5d7eec8ecfae65e080473078777ddfdd11508a6e59f0ebaa3f60441f82a71a73c84bca06a371ff5c9f77213a2db795d4a8897823d88fd92ae3e057e8bbd80c990af8386bdf26f12d973c8c5ff9ed6f7b2d8e6183cf6e68f3bb898f59a93ec4de3bea605a5d8b15dfab713f3585c48dc9a5768242b33101438030e7044880d17c2ee84f89d26a1f7b1986193f9663c587d50ca9ddf6186a5176afef1adb2481b79254b78d3b34c69790eb28b90b1461170c3d73818376cdf371af0a0feaf14fdf7016ed6e7f08c0c14b52705c86d4f0003b5e45f974c06416ccb5ca3e9d529aa9d415c25a446fa2d69e82f4994e57e922c17c1c342dd7281e410052d9e4aa1b309b7d470d458c663e17ff2500d0bb8e46a9c4367e091caf87ddfc062aae08a65cb9e0eaa71c99459c5e7cb112a2ee98a5e4cbee0dc520f87c3022da6549be1ee70a0a73ad8499c97dd06aa14c9fd8628a92ca6db487322db9598ada1fce28f4b9fc1d3cc39dcf2ed1df3d862d87f55cc1016fb9e73e7cc897b970d5ff35acfeb05c1c89192808aeebfb2cd17cb1c94fab059898fedc2fbd44ccef
+SIG: 3d0adce77a4e046fcb9b49ad5e6c6809c8ac336c733404e5d3f015c9225c3df46ef21ea34cffb3af69974f8b7eab2d23fcd5a1e1753a4023deb3818629a98a0b
+
+TST: 925
+SK: abfd697bfbc5b6ff2bdff3bce1d777e05fbe3ec8b95ce693d623931209313d4f
+PK: a709321a0210cb80ab58bf955ecdeb8aaf9ee4c375f959c53089d437488c082d
+MSG: 896b7ab8413ffe439a2f4487ec49d64e31c74f50ac83f55da61a7003aa716c2a9df6b438e62f53d8f0192f3736324760d7e8c44ac0baca3ae2a6fb93f13d96886799fd2c4551b0ab36f1730855551265a5a3c3c21d9516a237f5dbc1c8e72999b782c5ca41a4f6e9308e64afdee0bf479e546b89c51bc5e4f71e57fb24ce437a8b81b91dc798b5ab36f29afd5b48e81c176ae5edf95371ba3246fb439405bd10eed3678e3ec62307a3b3dc1badba051f16774b85088188c2a9e320a1618d5f26ce94ee2b933c305f6d9584958eea3156c3d1e0ef39a186275ee62c40f3c1acd15d8be6e074351f5349ce3df69517505f45fa06a815c69ca18f450f42b5cf4ebd99268445e0f68104a7deeb0a115b817b99e1a73e0fa9d87db71f8ec94f8708c9bc2e622b963365ebcfb97cfe7332630070e9654eaa60361a45d402dc0ab297665242667fbd9940f6cd33195246a8c2869af759a862d4b641db144d5732366b20636c4027787f558027d76fcbf8432eb93e6d14567df8dbf211daeb5655db10acddd05eca06accee9fda8d3b70ca1e6dc587fa4b78f63cd663ff0243870570f4dcbaa3fb626b4e113bde47d5c9db2b4ba6ec6dbf918ac056949ef3cfcb115561615771a035a43d33ba2651dbeb46348261ce3c4c9f246d23f94dbc2d0c19b921e24c77da5992f1b4bdf2edea499f5411168ac0c12e96f3b15d2e12ac8d7b3ed8d1e07c4267a25d3a3c353a4208b7406278aab9e700f7b206f48e6ea7cc97e554f15c9be349dd91514dbe8d889f2dcbbfa182c9faf5807a69b2e97fa771a6f231a4c7b31d117b8ed0e630cdf13e082bb4f63c3f9acb3553204ccd76e1835c46eec3d43c561bbf17c92214a6db1212b6003cf2cc26c7ae675fcd053b947e722f9e85762ce8a16e4654ec6342fc646e5cab472797eabf658ba4afd142fc8fc4c8f98f23c24dc99847ae8cef0879e1ab3bb8097e4c3529add2d8e8e2c2069210f50ace1ae32a6c8e6384a2bf7d79c66c746149c84ad75a3a176e45e136d94695aed4bfd08b426ea8c4b9379f3742550e1cf5ac84c18174d680e92af2c1874ac1c13d28232de193768e561947cbd6b79e9b99da65cfb74ffb32f7d3d2025c60763dc07f55539b4d253de1e6c25823a6258c7a9ced1501dce2786898a3e05c9bff8fc5b2125d0f471088a134b4873c8d55c0445f6ca396b3d7b4bc2bf5c4d2240da418293af6a3ed853dedd3bf668d937b35aa0c2acbf23766f9f3e96828475ab086496617a6e81d653589b2fe50b7ba8f0cf1e5a44d8d62f08377abfc26297
+SIG: 8c36b5a111c5a8119f2d9db57ebb592dae86ad4bf678c1492e26f3c10fbe03f105cae0dc68b55259b9b5989289db33d95d2ee6b756c760f9d3aa0e68a189de02
+
+TST: 926
+SK: dcfad59fc6b697109e727ff66a5fe93a6a226f631a64e5797ad8d8c8b6358734
+PK: e79f4f511372e355e7e9e0e8b5346fdbcd2df1fc5c3a1890d27fa1fa928d27a6
+MSG: 7d92ddd8133c61c610c1308c23aeaf993884a4e67f7b94bb886dad509869a932ec4a27d410d2c29ca7aeae6f9280cf6c4b067ec751e5e8c39ff444d422ceabae145d42f047453dd402d1797405033409e72cc19f793d5d268fb3fd2c11ea2cb0d70436e18f9e88a01515dc865f6a1eb23690328fd75de26321a38f12197a97201b1d8452944fbc541cb68c77d49515db5326f2b1d0763eda06d250ce2a5e0bbd7d1676d7d41fb3abe88bdbe372f96bf7bb526d6b65a2515e83a577045b5479b38b852fe4ab011cbf21c085ef5f0a7c1bed76572b0f860228067a899f895ae7f6256eb6514087f9d6f5c35596c1f480c73113546cb9cc30f56ab074a9ff28acab7e42650a961da325ac5b6594b81c93250ae7d39267a19c97625407edda0404cbe5a36e959fc820b27ef5cad796c11eaff1c0e2f9d4b3c6491502195de03659b364e4e87b2b2d733ec25e6f9b63d5f69179e0d27bd4aecc8f12a507a91baa48d99b3a426cecebaef37d7361106a8490644309f6eb4d2596443b6b0118b945acecc6443ea61fcd155b54325bc2c31be0250f9482e13fd8eb44e2aed76be812af5453cb7f8632458fc8a02a2f45480d79b06c7dda38b4695d08b5a430504f1ae2275b05c91e799d4470f38abe77736dfa895c197ea4b63c2df18efeb14184837b8ddf48909520d91045b9d9655c225a83173960b4d7cd0d8bae30237557f869708be138ad5246c866c6c059dc597abfd4943237376896736b97b7e0289ef9bbd29477745cb60f46202f1de984f509b1808833f58018cde8c26bef4c005bdca385b05735110ca02e562b50eddff6fde9fbb8d030cedf7031bbeb32b12b242be49fde0160c1fbde99b03c062a1a47062345c92e0b604d080facce9243481529c70597dfd64382cb540691b59b71b094332baf0bbb125b63a446bb97491c0464328cabd7627c46f392f3b124822f2013c6e16d3ca87cc5becf56b0fc6eb2bf9923b3012ba2b61250a633a4d2ee391256c520957382aff970c5d22385c3344c6d4b4561571c96329bf75615297516b9f2ceb9f997a39523aa0f58b488772d82fc0d78c5dd52ecfa6bfac63a76e148088b36f24a88e68385496ddadf3023f72d87c2efa26e877d32f1da97cdb42c8f15718988e428cd02f4d09543bd0bd5b2f409963d0fa373531f78b592bd137eeaea0b4e7f918208e1d59008a8af5058f5d923c4f32df19990f10dd3f0eb206293b2b3443f4a5d2dcc5f7d3bbaf6af43fe45f5dbbe53ecf4bf1b4a13e2d46ef80298d4f01c402e210fcb9ff2084ec03e42008d
+SIG: 052ff79540737456c6a42c41c97d6bf517b8cf289bc78b503dee6a30ef5168b38f75beaca1e14d971f8773e3941bd6df5cb9778dea125a4c4fe0116b70ee840b
+
+TST: 927
+SK: 696dc481f619a9498563c83d0d0e55565c14a07845fe4a66aba2247b113ff8ef
+PK: c9d737abc4a9e73c149eadc195a837899f2cd5019373c30ecaf62e5f8e14b645
+MSG: 2d4b3ad0cc99f983e41f9b48c4a818eff75fcfb93a1229ec2740ed19c107d621df78058de7c2dd7251f5ff454340865f6c86da65831f6672db231726fdfe4b9ee315d93c7244a920df37054c82449d310f892932ddbad94cc9bb39ac8937cc76c96521d3fdc028ba23410b29023e8138fd3f524319884ee5dad0d234c8df661f8824be477e21699f6369b15ff3ffefc151aa555b3c3d76adb45f25672d380d472b3148dabdef4245b68e828562f25cc5b81d9bbb241bca9d1934ea353f95f7dbf3646433e81a354e1e2056b81c15aa1fa8ed7a9d1af99238cd5a5ae9e841c48dc348ae1de7c41aca23328236bc38b47f47c736b257a3078d57d574b647a7fc8c4d01bc50302150d5032bfacb04bb0fd155d94d9206667720e180a645af462459e3326d460da3c48e7572678e1919268d3e4740d62a26f7c8559c1c439b4b0b0c5942a620cfdb93cc68aa15520ff2864269d7a0c155780adc6c188e0b565fb9594319e6f51d15caf6b280e7158f25799407f3ba0dd1ceea64b9326d2cfdef017e1f172f4dde0f7e4613501af01ee0ac30095f48b59590902b1aecfe093413918d835adf962ecf18580d16f9fd4f6fa1098af1d8a2bc24dc86f71d0a61ff150010867d086987b51dd030f50ab6e374b8e01184b3e2b214ab1c7fdfaedbc545e38c3cd2f6982979541fe0ff88bed67506da95727af1a2038f3240ae5bfd30ee09210e00fdcf2a064d5db4614946bda972c670081a6ee6a10b63f673c83c915ca5573e0ed687b0067c400792a9bcc3344e0e43f5df63fed5efa85e9aaf85e4d7a2c53a6c92828e07fe63e2d23f1bdf97d84adc36e9fc95faadf03e06d65a19c5e285effd0ea0cfa839d55a0a0dbf6da28785c77f5c04bfd59974ef3793cdc398df7a1bbc9cfcfc3a51ffa9a20d60c47b245dafa3e44623cd711d7762c50a67d650c7e8c4fd3bebc0c498d2152ab9827c700c7b2861565749b5864fec95b7f6b1994e78d8f85d069cc11f85bed9712f7a9f060b0bf67532e88eb9df3eb4a8d2fbbaa85eda926d81c49fb86e73731b7ed2a1905078513f7ca0fdcc3b1d576e6a60124c44618df1890e169794956cb1ec501ba2049970c8e74cc180064c184468be4f089a3ae2263c855863b62c28313ddf9ca85bf66b08a264155ad7c328238dfe614a07ede9155a09ccaff92292249341baedcbe0e6466e2c76045e46dad2fc899a1782e00998e79a83abfae9b706f707f58e730203e1d2cca028c922beb6d157fa7a98132a921a3da21f2f769bb6c1f5f19e9e85a13b781af141039d514ee107
+SIG: ded5d991935cd1f9390f1e85929ca16dabfc83e65e43272eb1751671aa31930c728555341430ce7c80485de58006427129a4d34fd681d52d840a16bafa153002
+
+TST: 928
+SK: f3f8d62fee3af375669630cbf063bfa930189af136cd7591e24d578d7366bf61
+PK: 4714c604aa95e1828a28367ba78760b5896431683ee996cff96871773291953c
+MSG: e1dd1ffd737ac6dc24b3b9ce3b79e835bf698e931303d809cea1782dc3af63a0d5e67392823d1439e7b6e337b01c8b215434c2782b3be7443cb5c881e5fb6cf3bb244128b4da6a6f42b2bb2cd75129d56418854348c339dcd912b45557a915e9fd7f37916236510cb6c331c140b87d225311600b8d132ac47473839c720f9ff0f9c1dcaa85815a9d27b9758cd91dc5d3e53326fcdfb2730e52be3103957ac89149a4c3004cb6038c0d80fa72ac630d333be5ad4adb585aeb71aef1cdfd57b915fac4f1af78e7a597f8d1ba06672b19c0b65808a8a071ff8409034379589f3d41302d2d39b3318e8c0090fa36cb958857ff5b211c9666e27bc895ab9d006abaf5950a03ff17ea982178a446dda2466f5a40b8f895509e4f4d4a6a2739997fbd4968f89436cee3d8edb8a6da9bd3d55b066490e8339c78935b77883f95b932fa5e6bb7df303be30fa567249fffb473a1e464322d7c103fe8224c7ec57bd39bcd030b96787aebcd20e9ad651cfa2bf04ba70a1cf648e0a5449567202a937a45becbb6fcded30cf9b5c748f882b5dc2a4d65be69fd7d9c381e83d0dc2a34b6dee91220ba906e512fcd63368e2ce733e466b4b82b84fb0c717dc8945caf6d46ac1c2f6418f7729ef4c35e402422d64b1c3ebd1b32a30fc4c5eece7d4408ff679ff01a1c7b03ca517be52e6ae7650f7bad38901e348a5593bc998f7cf2ea97729cb004f561b3b58fe59809a41fd4b3b76660906ad9eda23bf925437ef452b16f540b3b80a35a7093c2734eefe6fa97d881d79ef5b767d9889f118477b73f58a4c0cb15e0ac8101120571ca32ce871f308ad9057a80c828154fb1bc2b201d0cd1006e022d444dc93f1bcf224db74a5b373e153e851854948b6da147b73287cf17d1fb72b4827611103609cab2a1779e9793b9a70820fc6f3828a64c9eac35ef7aa7b17609d8eff8a9e52e4ebcd86b1e14fd140bea47c6b8ddc41e8cd271eb92287cbd0610512242f76a1ef3eac1e4bbbc1adae50034a7a2647e08b2fd20aa93a93cb2ffdebf2e461eccefbbd1fe894ce70adf790173bae96f5a55a1887e9ae09fced1d4306c291c6b19ecac4707e9ef713ea18a7562c6678326228992077a4669734966108000b4144f45a0c3a2863a4c6a3c07632cb93eb197d294884d9ca3dd4b21f39db707f63a7f9a570f7f0feb99b2ca7da7df92a177abcfe86ec661d30bcdcf1522bdb1fe11673258df7e46ef4d326665093156553f28b3563fe7192f72f5f9b3903d79fea04e2c488b465b4978d69f26e05a59d5ed4ef4cab232acfd564fc6
+SIG: 8d6f7ceeb9308b4a303879fc6cfa5ca8e05dfc3defc2b2cd2910dd4b17c94eaee845abe65fd715df05b0128e4316e2334799c6e8fa747ebc8a040c74f5a1480c
+
+TST: 929
+SK: 865a432ecce7e78c42709fc1e531df5e3959132b2b6f318fd1c34521f9a26e3b
+PK: c7a8caf8930b622a501337f92840ed96611a322080fde5e49f0a2f6e33b88283
+MSG: b231b6d2ecde49f513b0df25aafc3e5da45b6a9958d60f5464ca593c03005ecf361ef1696bb6e55d6538e34b38f324c21cea5cc81a0073278bb92727eff81af561802dcef33bec10ad6594e22d9c4418af3988a43ed087b9954bf8d6283e4beae8c096de6606751cbed685846c6630b9528ff364a7c48464113472c9860b3371963c911495a9c628a3e3e47ab0991f10dd1dd33161525262d63bab648819d57d1269e114825c5434e6b2845f42795d4fb083ad79401f2a0761c634a545aec7cdb13b5be449f1d829326378ed1f493fe8c8e9b068cc1dbcf165550b8132c319dac487b87bb22a54cdf60aac71516182a4e69ba083f6e86d1a4f05083a77619ef239f702396d7e46968cc04a3b34df3265ecf16157abe15c642cd7427096d8d40db002d196cab1be304bcf322d9d1a2451b6c11eeaf3e8e3d929f480b6b77804fe84496ca757e04337914ce94475d7990c7457c8e606f8bc207d2d48119c80a6b4a9e07b229226570dcd994989fecc694c6c2fb5975c9a6a9b74e8159c27dd3677dfd5cb651f1e32adfafd810b6e5d5efbace31ae6d9b12191e89398da063f138b7584c58e77e7f9fdd7fb9ef5d68ae49c6ccad28d18bc6009d4187ed1420224a5658aadf135b5a953f2dc3c8bfcaf669ed5da38d0144fd9665e6f0677d3fc8804e21cc25fd5e01a3f3fa83e571eb2f882a7659ce5d864d8bb54072b0986a854f1a7f2d2720df857e6d4219630841b1ccdcfc6726b91bfc17e18c3e3480c23a2c05e4bfeddd4db9ef42388f234fd3e4f3dad666026e2780612374161316afc7665f9411b6c5aa78933b18021c012b084f3244760a4ea1bcf31cc9f5c4044a9bcc75a986707f38f45ac1c7fa139ee95a6d8f16c3c1e12764c4b0b1194c0fc5f7eeff9a848c4050b0e651684719d438aad56019164fae4f48882205ece0b99736791084a753ba7d56e88fceea533566c3a2ca48dd6efc49b27dbf14f2616ced652e13833ab9028ada454431c89b3cb7441fdb8f23e12b60a1a104a2a8cf4a64e878aa26f54e8881a4b151a16a96de8b9807e729396ebe3e3d394f808bd74b7312fe6b84b1312af8a1e4133599d07bdf33db21e016b5c196c1ba3115708f581bb82f4b57a6ca1a529e64d193042c1dc5faa0a03abf53849e1bdefbab64b1cb60fe10a3fc1823a234c45f3b0dce66a46739c01aead12de6f0313c7be71405f3fdc4a507a9d84e8686f6fc92635db0f7856c7373a618a7252c129a7760e2029543d726228c21d00ad4ac52e5b1a6e31200917f15af515859e08f2a79ace67991ed69044
+SIG: 32bb7520e2639c6cca19a2b9836b08f8b083ca33369ddf5f9a877d4c7a9eb05f9c3dc34ed4cfa4b283e51922b094066ce9ffa4d9df621910ca37b0b37fbabb0e
+
+TST: 930
+SK: 2be1f98ce6553c915b6a0933ec0de347b370e29ca294e8005541239f63b430d0
+PK: 7a6f4469c30a63f560f98734fc1906ebd1371ed80125fa3e4c86b43f262cabbc
+MSG: 6268201f932a7cd3f879ae6ab83855a2f50291de784d7d9e9adaa1b9afed6f5aea20240e59fe93e5a7088c95ec8e15745fb8fdeb91df0151c7b4605067561ea08dbf00c4ffe1fd0acf103656a7b54fad0f25ab16b4bda347179ed1cadb7b98be0895e050dcbc379d1fd553e99795928b67a752f8d2ec1b9d66bf6ac997e744dc327f242230f92e79ae312745a5ab6ddec1998fb63dc4f6b05f147222d4b65ace9017dc1bcd675e495f9eabb5f602133f6c72e053e9f4ae30d872d78bf71feba37acc595055c3bea53a05ef0c7f212dcf4e0af838ea2928f4cdc9fdc837da25f26966b2456abea66a5dfb8faa8fa091f7331d5436e98a8d6323cc9e9a91d5a02a49511714849b47454baf99c5f850a08d3d98410e939a9e89b15053825f3e9aee71447416140782e1bf3b0d8b4ff62e77a4a03f710a8ab76cf63592c05c440c8f064770099163c12270f3d5ec9a6bc9715bfffec769611d21fa003c3cc8356c975d37b62b88aabb8597daca196c9648a31d15bb0b86cf070ee01e511ef373b4a44c6a00160a797f2e820b716f5ca64464e4189a00fee978d35bf204f71db1f501f9b6e5dfc821a8af5dbfefd353ad3681f9bc3c22c67cb211b430b6a55f3e73da7c3a07ceb7d2fe254b10c2703ab2e2294dd0d3152dc7b21aab87b150f737a947463fb204175de8543236fbb0da5c7d48c57f61744de6f984aa8e61b970c62d0eeb849da7e89a61222d432079cbcf5f8a2ba930301683c0785c26fdf85da3020874604599ac6c847ec2608658b5788c7b8d3a3744fd5442e24c8eeccd420756bdd8b8a77cfd80589605dced9afda2bdb630a0cb612f739ce617d54ede6ccf36aa31e7e373d8a0fb1b7c9906f76b5f9de8c26891de006eb797ead4a86f7016f34bcde92f94ac3e920ba58d6dff772078d802a94f56cb26bf794fd90ca0ad4f2e7acdc5929bc7364997ded98ca69c573991bb9ab85f235b63e76f77e0ab45e78912389869af21e74e66f7c456b827e670beb0f0726688bb1f9036d38da07d69ea3666f76bd605d82e2dd6387ece6e824a569700f01b195d1a9bdcb0f96ab5c54e06c2119b406bc4888480660418bb4288ea2fda96631b0e1f60ac861d6ccc4c844b647a7d7403bc2d15bafe4af677e856fe0d2b5f663be4e480b38f6b766adcd3d05298ef1398d04d1523a68b91dd31cf5dc4b73decbfd7213f981b207e1f6ef225d7948a1aa17d8d57a112f1d4468d2d28f7ec2e54b74a692c5958022e82031a41b315090ed4d5bd7bd0b451476338f739a7d7031af2d36caa09ffdbb7c396507c75
+SIG: 8e659a3f535a589a5fd2d217cbcb8b777e5af20b234432f7dac29f810a2b4737c5cab10b59dfd0144f3090f5f9e0e667f0e21a9f573fe13b1c28eccbb531a205
+
+TST: 931
+SK: 10bbe6e761a75c935b517f0936fecb9ec6fc215e58130800ea18d1ff442a4f13
+PK: 8643ddf8aa8d9c8a78b6eb699fd20a57f6f18636b06ce69dacdca1267acb3954
+MSG: e8108c6de4133733dc199a73392e226f712c36a24fa91d6fb09f92df218deb2d2830a668fd694b4809d0253507231247c7f258b4d65c56bb69345ef6aa97e7c59e8153775a5a3cf109c4bca9815569da6932e82183425b42d7483c9dbfcbd8eb38c84729571e8ec93982c317716759598c4f6a1b7f8da7306a7815721caf02e70246712314f766be9cb177cd2fa3bda22cd676c5d2e86e8d798fd34f543c9be3129651f273f484f0b9467b140955cd2981ff2603c0bdbb436ac0955a116c5e5fc30425e1fe78f6410f6ef757f604668854bae79bfe22e1a85ce5ee5d6434b4610120ea7e5d3d137ce207514f8534ad9bf392b7dc5355514b59f835466c8eb56f44eddc5bad20cf0b480b2e822a6f46fd95f30f183c7bb3143e4e6100e2dbc9f2bf0d43073e0fe65f01bcce6a1ae401c12541be3ae68cdeac2a4ac71f1663b5fdfc2e50f0e077fb3a0a8b8eeead627c1c3e79dd7361046f7e57c17436c32dc4432f050028cc7aa4408c2d29d1d7998fdcdda32bb32f704dc263db9b8e06c57630870f8bb6ec661fde1b7da94d53b047701a4588478c1c662346741aeac4c25338556a3d848de5b2a23ecea61b776bd0e8037efb8501eff239c7facca6c8367ed7c8adce919fef1a155ae0d5478a98002c95a16fbf4c0ed016ea5d3866fe1de454832a4e9565976b60b3dd2eaf7fee612f2bc040d93975435eebd12f06eb09ecea2c66768308f58c77ac51ed7bd21636fc9cc3fd14870bd06bdf128a81b14792e608c47ea2d535ca7aa21eb8a8a56d76991663a8190a95057d33671e73c7cbce5a98d31ef0d73bd0b163787b7fdcd2ddfc72960f2be320846d4b29080d7aeb5b7ea645a2ad5a59c012bf7b9515d859e1c1472ef8a4d3c95e711af97ae4618efbab3dffe88c9f6af4a09b0e73387e251b77d7bff5214f791862db6988411e2ae2c75bf28d28602a637c26f49c18d309d2fc58a126667ad3c2ec160c99ba40fbdac17e7e4c21a5d507859762eba09c4160df66f5feefe6715a28c5296cf43e5e771f31fce5133be97cab57301b4c9df9cd9a4acf1c33fac946fa1596fa65c8f3658be47a473a62c52181eca183e4246cd624d8783dcce5fdcc1fea173f8071f7074f55897de9bfe84a6c4fdf802d5026b8145e6c8c8950afc5b40fd0356fc55ee17e1f853a4c2fcc34a1369b87d28dc2fd2010f19903aff8e46de04938f4948245d5b425d074acdf2bd80bfc3735cc34a22590f194af9313eef4ab5fde61f1f9b58578638fcb4f2850b2fce6e03db4d0a834848163c4b27e129f5cc74f67f008a2712d1d
+SIG: f0f357410373313b7c6252d6d96600360c23752d431ca8075bcfb772d49cd609b65c9cd838d634d8d9b95d1ee30edecc13e3ca997b2437303f8a33a1ffc83306
+
+TST: 932
+SK: 186dcc7efc5ed7e61ae53dc42093bae8f15dd99f0f033326c576ff756950d06d
+PK: c8d141acb642aa9bfbd543277c2dca8aa9888eeff04543b3789b21f26aeb0f71
+MSG: 974364d6c838842ccc4e749e6afd537170dcd8cc50d66654d105482339cabdf74e32935ee219272ea1684fb93c1fab42b5631839243591bd07d3be949b0dd15e3196df196ba752ad1121ac7112d566944e153a4e0619b3a232241f020be0719f6bec918b26828eb1670ecfc73c66844ea3e404c6a2fc01beb403c9d6ca551ad8a6e71f46647fa6053f0314f8124d8d2bc12cc8fa8db95f2b735375201b816a9cf40f83ee4b8671618032de229ce76271d03d2672a1ae4a288c85dcd27fb8452a8132e9ff29e1e89bf11b1c835192c04b13be14f3cde5d37ce96f1dc2a9ccda0c4d737bca1fa220d21bf360b90515bbd226bb2a6c8d5f2ab018d4084e24ee333ce4e39bcb6b46e7aeb4db9b6c65b244d982823a770f9c62a0bde2cbb7ec36840d455187faff4e488a5c608ebdb7db84d87dad3867e3b0d04b64715e16560a62f1ee03df6183fd5e37555da1972fca062d12bb8420e082dacb8debb9c1438541d0da2464ef7ec52263fb9b9a4c469c83323e4819dfdf4fa0a770c3a709254e05314830e87fbb6736c72d9dabe01a310e91ebbfae767a1fcb62f64fa3ba8d53400d6469ad1ccb811fb9e115f14127b13e8364aa2fe80bbc886a10df1b9cc4ae4601f5461af091f526d272da9b203857a4447eabdef439830496a5759c21de65ba3a3c8b8e939c461332a924852c205c7711f3a68a2367a945def4fbe5f81c60cbb7e394a2a49be9ec2aaeb1f330575979446ad9d0d54abd436f2860f0423426f4bbc26b3b9f650d69b10072d747a39e478f455eaa12c7c6e12bfc4536a3594344bd02b620e3e2b4e0d534089dd7b04fa634804567586c62be0391c7bdb0a9fbc1ef3b33211edbf8ef58c2b7a49d06667959d7e5d44671ee7357a10ba0cb1a445ae5d709ce255e92de715975af94b89d4a29c71f9d88c85b6cd11d8b335bf8f2c658e6dd7c3f6c80ad4d0e5a6c87dba7b5b8a8a47e72f4d1d3c743631df9adfcfa45cee0498d5a44a9f75c83b75b2a3c230ff0767d3888f941ee1b6624dd0e12d06ed1ab8bb135ffd379e9de3788be541aadb2d6a7cc601316f21eb9aaa922f56a8e3526c9bd1177fefc2fbe3e430b628eebd6661e3ba2d631c6a8422c241ecd969972412f74da6b1243bf0fbee8a84d52e40aee3f1e4fc831402c62f3576b22e8e3c3dc4e160bc3b6b9d2ce005853812eafc0a4e25ba712279b00ba3f9130ff36e3ef1971dde7508b2792fe64d475688fc6f3313aadb785302e6b7f9a84f2dbc2f3cf060ee08b463736f836dbb262d329684c208492d17d811221be02b65ee28e11b54692
+SIG: 8945069787c1c676a84a703cae1e0bacaeffd33e91bec3603e1f13fb170e31e6d7049eda2bf627180f456c3f7aabfcd36c49a8c04f8ae6929ec5ada07b657208
+
+TST: 933
+SK: 0705b336c89ca35ffdde0af0f906eacf623c56c3f76738168e76fcd5882df79e
+PK: eaaaf2a15f44b634cef15a638b80207f61099a0796f5d43f3e9d048e6ae796c1
+MSG: 616fe15fccb3310f9ec7456447dadaf8e0a5fb269be169b0c3ea2cfdaaa55d37937fe75b78324ac278a65047e0ae4f327e97effcb7bed91d09da720b0a101be9e96d0ba85b1ff49d8d1df362d3454f0db6825596101c97e5dacad07ec492d30f2d0cb7e7de4e744bb6a6100b754da847411d09aace8d5d410758b83087db4b5e6297979a21fb65af390952c4f936260e72d7c78327b94aa6cd617278b0ce9e1bd3fbed93b69bc64985dde0e2c4357b502f055ee7b0a0388474dae02d6c1a731f87785d753aeb0d9cfdf85002df566fc2507de7ba6fd035bee17a2e808b4a7588c583375c82407a40ae9eebdf94df2fb8cabf17606c439ea70459b212aae4a3f530ecadc5e88e2548fa643c7ddf5063b2e10673e59d07fe906892b67eb58f9388a56b370452e9977755fc04dfbc77da6c05beddebf0365256b52c9aef8a82173b8c89fbd98cea36a8b896fe66d37ca79bec7fbfe958fe89f6765085b335dc770343e230caddfa2833daa662fe8208dd885a6fdf72e36ecf22bbbbcbe79d370650236940bc2e6d4ac74fe4d554c9bc232f07d2af6220d157bd2da6a6612a081b4c9904a2869b137ee3a0856f12b2eb8762db94ed0ba136f23e7fb4bd1fcdee10dd84e2cd3b0a49148ac74db466dbeef81e6a8ce0861102de9b1a3e1dcf5c6b0308a82e3ac7c2283c7cc2f34ffa145b9f74b79904b32b79e960b814aade63a0df0167dcd24ed90a8da7b934c772932f5a478fe2a72f945a13096ec37ce764b581eb89e5f6b2bd7eb88b85a89587774d458c58cd879457973d648ef771c5f1deb27a0cc5b29246ac2fa12d18ddc6b9f9ac9cf146c3f22b1e4499adeefbcd2249740e13a224e7b6b3ef15605e7e74e68d7b72642409b90c4ec161eb24c9b40ff9c7e6e5da98322aca52c46a8ddc190f1cab157c4c7619601a6b33df6a50da661bc75360dff69750d3457409cc0241c3e8c4b3e506d426af52b70231cd6c91260cc431e4ccfd496ca14ceaae1cda78721e16339d52682b6951f966c7da5c6e10d919ae66a9f52dec10867538d3df6d593a32db695a8d7745703516ea56f8c1c8f0ef53bdeb7f53c2d944f511940ccb90624922ac599f4619c3046207d605f6ff94de788d25342229dc8af92b5fdf0dd71df2b446cdf1d9a20524339ee1c31826287ef72781a7a35289f85a15ba57c7fd5d885bd0553ab40805f517e8f1b1b3c4fc6771e6f224bc031124b9c9aeb19c5a96bf1488e1e66c6e88809230c83a74155554a219ec379ae54a9fe79dbede3d576042a635d197f4d818c778755b8b45e513deac88f60425
+SIG: d4a9bae8ecc472c376bab805c2ce0c1c2ed5fc773715468cb1a4934564dacecf438b1dd2ac1b5c5e336a1e20701d5dcf3c8ee3ad223b139fa90a1b552e1b7707
+
+TST: 934
+SK: 95174a0915684cdbb619b055495b00f19282cffc3b05019e6ab709a4a1742bab
+PK: aa8c872d7e10b67f7ff24172c3637e80825a0a71ee0c48863a2acdcbe8da459a
+MSG: 5e1a7400456cad4f9ba86643bc7cbf3b3568dcb522b37055e8c39d3c80f2284238e5727fd7513cc8b31c57ae7b4050aa819fc2360930eb0dd677a5b2c729feb2da3ad79ae7fccdddb6c08446261ec9bbe59c64e99abbc86d3c4835f00fefe527433a501a3b6d572cf5e12a88010b46a472b9bd8691a407c365f9f71634b4d97edfdff06314c0c1b4eb93c7607f1d6fa354659322c284073f42602518c54fdf26ea2c27c80a6dfa20568391ab357282c06b23bedc1df1264b611c1e9cf18aebe249fd8617c6e3ee98c53c0f6f2175c57ef8e206bd3cf105627a9892eb689920213aaeb63d87663dbfa53f0fb281626948296b2dbcdde1c51af862eecf1cfe8a46a2c4b28cfe7130330ad173f87127aacaff43c0bddea48b0038976e662c04b6b04ad03de12462c2765db535049520cc114afdb6c92549b0546a9027d449755beb8d4c17e6a2a475f9676a337b4e866d96325e389a52c16c51e18e0d8103340c8417b2c57a55d042ff5e5fc65df423e0092b0ea88b96a907c95121c547a68061f27bcfb58ce6c07728d4846bdcbf0c625410edf8dea8cb4c9d0bbeefcde19273365f48d75aec07d1c22ccd23068a97c3fe752e87a30118fe2dfd5218b6b125154e0ea386cf239e3137f8ca6d8b746b6a67d508cf8c1ab63e5715e6721eda5c2bc393a493dbd2f9a1fa926b9a59e45a180aeeb02599a8cdd686f889b4852723cb6dbfb5014cab5f658a309a472239360eeaf64fc8203a3c708970e15cbcf136255d96446c39a927031d267d69ecd51d7af6e91fb4aef9d78c3335e9071133cfb8e2129990c64637c7adf1daef2dc26c1163399f3fe1e792338092ef6f8dfaf25730dd2fe8d978f6f770f52b68238176564cee5fbb9850b3b3a04d948460417826eb2eb24fcc5fe35334bb9521e87bc4dbde2ac9e1c98949dc2d29ad279e3884b905268ebd0808bf418257e75e262b4d01b024a6e9aa7bd501dba94ff506394b4b0ae6081ea73030c43a6a91766e80f9f42c0b68b98419ad4eee4e9a728adefbd79e831f70f41e62b43f0bf42b3b2cd53b5589117664bcebc409a7645b1eedda482f6b6895a657ba789b89e502d6998751d6303ded5fa156ee7c7eafe54626d1032c4d7dff977f1dcc86af89b1e646a4afc2427ed02c0af5d32890f95f13f98c1a5b1d9fbb781a9a89b2d790c1465c2d1520926fdf28c17d9ba1587ad761f065d339bdbe38f4133f45bb5978742642f90c065ee4892573f6059f8b4ce2c13e73b891cd05f23731ed9a07e2b8ffdc963b06a510209c329980949f40d8073a013ef843dfcc4a3394
+SIG: 780f40c20fea3b11c9422a43b9a6f79611e7f1f59d1488c15a5fd2d32c07dadc391c38953edf0de48be52da2af335c47b8d2e44ab9d3dfb76ba538b066495208
+
+TST: 935
+SK: 5a84af28a5dfbb3233a12f0837f6e8654e7b0de16b02ab3cd17864431e274667
+PK: 80d4ba789f8a4b2047adafa5ed26cd8c546733292e8bf693cfd17e284efc6871
+MSG: 8aacd1b8a39bf08fd5c918446be576e6a3f27f36111607f27b56a91214e763f9a87fb1d1844898961797644460bff5488c103af605e8740e46588fb93e443c3bb23b92c09870a557653a1f22c218ccbc2f073a272d17a84223ef143f4c7ca258460b798169673da107d71d5356ce9f7559a9b038399951f575c77e5b9d0529578ecaa2e2089266fc526c5d409fbd46bb86841cb554f5bd3c99713b043e404653a7d01344d4db831a217282c4b336405653b85d27a46b259c855cdd85ad6f7aedd835ff5500cc8baf0fb2f0180910c64672b8a8d49d984a78293cf5779c910c3acbbca455a85466e535044f3480262c090fbf4e0b0db4d1ef8759daafdd8d05907482461ff910c437195d5c7fed9d82cb94e7e4ec24da053e47f62b488eb7b244655c7dbb20ed607eed4531449e0780e61cfd574086ffc5dc524283775c44f7547cdab04a51eee4e1b7b65a57573a92484a35900a909f81e415029d22ca937a3acd9e61f8c0e686b2d2ad0377af8ee166e4a20a82aff451e151103e0a1767b271fa9c2b1dd120f805853b3b8a560fc8b9376283b51124324a284a0e9ac49df69f524c8e042df82efbcd16881ec131a15210df73de02943447f22a2ea1dc8bf968298ee97f3ad546d78bc660897e08d2a28b2ba68b54b954f1476451c69207e5dd248ae47ef35694990e6f058bc0017b7495105cc8739066afb11e1f26601942546ae849ff2f56730f1326bbeea640ee178fa247adffefc046494fc7ffc0777d5dbe8a55daee61406fe3c7088d43d9e14da21ca52fd8c160091c8f99a67dad65c64fea9d18b1537d061f5dce879e0bc42648d2eaa02d972185753cb2f6225d8d03bb07f944b10cf4ea22275c3d70848020f30c823b76143acf545999a2cc4b5898d94b4a25efbe5a60331cc009fec0a25bc98947b1b7139e22d23280ff8854a1ec76221b1bf3d108328c8ac463c65263a2d7ca7433482931a1d8fc144bbe9bef678c92e1c2d10921b6ad43a75c53bc075854ed2d99d825f30a5e10d517438e4d4f7113429f1edb387d6bd7aad29274f8d2dc889b7efbeb58686f8d669ceaef92c75ed5307f0c03f5900181ce573c8fa28675205fb1057f626aa230d03e2eaa8cffcde20081475d80b245a1ca6045ba204ab00069079c637fc3fb3e80ca0462e7a4cdd9283ff9008530364816792fdf3b9a4e4dc8379228edcbb154bef387d37760d79afbb736260a1db10138361f24b826dbcd5f0fc9e7830d26d80c52a792189276bce34760fb77be1312ac8cf97d92cbf3d0778028db5e8eae89e0b9bc8778aeb1278f0471cb
+SIG: a0b84ca5af7646e6f62a6935379473fa6e4c27695851fcbdae2917b2dc68d796e278d70cd67fcedf6ca629b881f7c4f2aa2559b20d670611766bd65aa4fef204
+
+TST: 936
+SK: 793ac88d7d3b6fa7f47deec31f68ddccb701820f1b13ddc652f7c6a85b6052a5
+PK: 91b6227acdd183da62c51965c635358b204d683ee06443cbd40e71c1f76ad102
+MSG: ec50afad8ade7405e2c6f5c6247bbbccfb2c17166f7884feae10d90f5d83c4b6f0bf76de2f7897ba1194d6d3449ddb80ae74eb8ed68f049b35c6f21916db4dfc2724dc3af7ad8dd5c44f60d2f49fadd7004da1593093942cae5208bf54cf903bee646905fce2eb2e370d0dca48d820adeab16a3b675e5a4a8e267e34ff96f3122b18de0cad9292ab63d26e5f310fa2168c2966bdb63b0de08626767b379de4633b9f3eda7917281dad661e9f772b844a79e800fd842702446e4aa731757107f3fd6547bf4075963d5fd5f58e80853fc42751dca078a9fa8d5bb3d9a34abcab0293d6ceaec48967a1e6224398cad0f605a3be8e6758ea8f29209d8e4c4ca1893baad91e379ba3b17330c12a5b6f219b384a8ab978bf1b37c3731a1b474b24b5d67d4cec28aac6510b11f2cf21bc16963d51f5538727718fc4e2e5172e3c0cdabc277f0d7037c34ca68f73288848b926bde0cf47abfa66600916946f07651c280a2086b14d52570cc8a4b74358b59c302b9d00e1b498f3bc33ee4ecf2bce2c65ed7e8ba74d35b751d3c99f40861968c2b7f3a5be348c57d93b40ffd051edd7caca6ee6bca721dcba8db8d0064f54d36ec5e8d62a71fd1c90f14924f41c163f007afc6fbbfe8645fa47c3c980246d1b92274385953c5341cd64c34ae9717cc2c37f58359c0a9991c23fe637de6cdf0862f7d0329fe758aa892ad4583b9df2f3337d5be570ba654998ed292f11f01772382a04342fdd99e69e0d97c43f10ac9b96f140a6f83c4729e7a900471f2b1df2401bc5c680422b13b0c8007d63681f66a0595a1c5d3acde5b779426e736bc100c5e6f52608dc391e3ef9b1bb6af13d249b7d32ce0680c368f54d5fe039cfe10130251e4db14c79c8d044060465822990d88093cd736532852e447889db89cc60052996a32a64365c0726051c119eda901de576b334fc7049482392e2620b0a3a13fab1d36fc0a5f23db147fd857b26a698048f8b811e23d722e2e9027ed4124b48dc5e578a7aeb19a1b4f948ee5b46f65b979646e2be074714118baa4bfc15b089a0e06627da46e4bb06aa3c7c5dd648e03c9c2dec3facd95626562f3000883230d2b0a1f8a7478cb77f939a5f188f458d1037b90176664d86ea850b8af5087f86605a77e025ef6c7e6a2a59f006cba189fad933f42c532708109bc1af814819595ffcb95fbf5b7e93a71197e477ee7c04b851c1c36622cdd8e6c860d9ab2cac56d2dc98fa69124f2bb2a6471e1c73b661f071f5d86de7d1deafa4edcdc7bf1f705c56300affd058b9697791419e5fb2a5b7f78ce3401ff550
+SIG: a84f552bf44322a6db245ca006d1cf780c61680fe7429a8947c35f21bc4b44228ba30aea0c744b866459d3b8acad453b06ace247ba69528c6b3bc4b20e75630e
+
+TST: 937
+SK: 89de7442d74ba9385969c9651a88fe28e040d593907dac1a3987418bdfdbad89
+PK: fd3ba9fad320eba45d07b84a497be17d3fc7dd9999c968883cd6ac13b0669b17
+MSG: 9d5272f0b784882b94c76dfb9d460ca495025e0aec5d52ccfffece9f8173c10558266c498525891a97bf3878e33c3de2fc2e52550b431562cbe4a3d011ecc9e77ec36ad38341358c88321c03d08bb426a7d5854171c027ec48d57819a91afd02a618ccbc25e68e5309d047b156e35705373ada2eb831321a203e1bd8f0efecc09618647b41dff22b39d02235f871532f6085e9cc52ec009b33eebcdc267d7767c90c927e154f72f3f48a34956319b293c8a8b3e34efc5f62f2b4e8019b50a08f5ccf95bc831baf40811d87e5edbd2fd5365b26a431ae95800ff381cd62ca40e1866d950dce14f030918abac68e7916ddb95adc1971287874d07eb0edef64296652c48044b0c5521a8d270d53d74ec63b890f3363f9207f6652ae8e7835c3820ad6d9e3633f4bfd5379a44f29d65f3609fe355817dca5518dfe3bd769320a031902e9cf6669c24f88b01eb36995bdb8dbed6ee0c9b7f32295c61ba8905e5598f3c9e1c8bf7264f98293faea17747f88440c31818c433ea3d23c01f4f7e9c3dd3d5f32ec9eacd71a09e3a997381f1cbffdf4b5ba4979deb7b09841afa3b03d1c9311097b862cae11707cbd3a4ae6c8a26a306a687c414a4ea1e812f115f60f70bda7f8fbe7bc2d50cc550bba291d5ec523229a08ed568b5cee18fe6f46782c17cd828801639215bc5e9be4555c9a18009767a6c5c74a8229d2ffaa399d8e64324e884223d5070f735a75d85ff6c94a9fbc2b3651386de5a23cce95c87881c79399ae71f090737e2187fe904aab1d92d6186795c9b46c62a5914f3630fdcbac3bd4b0da4ec3136a1fb2ba40322d7cc4085e167009cf7450fc6a286c2f7951d51aae23b8f33020efb5e3245ba6a3543a2bdec447d51ae00b5e1678b76093cf216b9507c963ebfc024ccd6ef6c78c4572273beaaf55076dc44a224b58615705791965307cefd48672c081bccfbc1d15b062b38b4fba9b9bec956cd14444ee437e7960cc601eddc02f1a76b68574d5f8843150c0b9009934a2bfaf605770c136ba29f3dc7e29597a2480db23e2b2677ec6c51bd301f2b5a39dfda7b477bedd1cdaed10e29d2954629b9876f8ee54e4047369d534cab54aea441dc947eb3f59382b218360572f2659583153c0e2b912cf30c815b26f05853dd30551eecf64b858a441bb8c6db8a9fde77a32a7b46af66f8cb9f35ee0fafb0bd42d9e65b2a9058241a31b8ca1115434237670aab4eff36010ed0371f46595da1bdd579bbb67aadb68e77ad3a38c8f26d2af5a7103ba5f22b42cc12a8c3ce5c921c91cfc0e63df9027d26229b1047cbc18f6b0
+SIG: bab57284d20ee54cc7f9708d717706d8faf6e46332b0691d6f213a8db801155b4e338c1361b592be758501b1821793ae5227cc3ba8df8adfc6ed9acab54cc401
+
+TST: 938
+SK: 2622bd9bbef7ff4a87629ea0153dc4d608c31fa5847988ff500d880681f11372
+PK: 199758a9c3d0ee3eebcbbda3e1ef5455ff46d736bb4ef0c06a739f9ac5848395
+MSG: 891e82122547d61e83b0abaf27c7303f0522a2ec4af44ef0ac196a9978b1c623ef1fa72baf70910a5c51c4f78e0fe9fe37e2439c4795916cfa22ab471a2557cc7ba6b66956063ddeb39c50f14f06348fa66b6064dcffca5043967f05254d577abf22ae8c90000ce2e6a1a8b2e3a6b3abc563ebffb20445f0911cc42a987f8456efba4130e68f01fcdf7bf771fc1d35371a0d75dd5f90002c90b6cbade40d5b23fdb49abacb7219ae27561aa2a879da88df34a8c581f0c67198ffc608fe9195b5555c8ae934c830aae2885bea87487448e11b4f2f172e4d5cfe4fd113f9d2016c24a734512bb918f575e754139718e3d20e790abb942cba3ec8b2db590796dc435f139fc64ddc85a22494ef2bfa1f5c0f1875ea58e84eb374ecf8cec6468b6b09d1e74f1541ed454a2807d3f4053566b0e4e2c6aeced10dc007e9df416f267fcb3fe17b8bace03f0743e0e6d4a48ce76edff60c0e3a308456995413c1076ff37ecf2381a0d4e9e4a913a258d983b9696b5c45af37c8684070e400b8f865a504043f45d78b9713f335aa416a46166410735fb5d82210458d5a08a104d4002ab61188f9df457dd7ed5937ca5077606b418bbc8684a1d525bfa551087640b1d177ca6d4f6471b39b2ce43afbf8285ecd687e438f4425df568ab86fa2316349a1102b4143d71ef4e24f5c530c77afb0100788636440e740675a6174c5f05710b253a411173f9e82ce6e22f4095e7714b8737e147aa0f23191578ffd93823ce4bf91c1d110982a5da0e4b81bd25b9b9c2142a7671ee937c90fd0715ec9afa44d86046898b42f753589d2268d2aaaa985cc90e0f9e827a3923e7716346f4f8931c72821b3eb645daa7452c8afc898d7975545c12da1bdb209045cb00f4bfd5383df01f003680b973440f1a39c9d820959ef6f85bd33639065aefdc8bcfecbd9b9554049738af29f1294639d3915d632995e8faf713ef2ee3c298b5596fa10c99f946ddb32340695df1c194594eaf3778d73c8ba6040c04eb3a4ff8677936b88e0c5f0441480d107d7ac2202b3b694e57ccca6d825e2a07e812ed29b2c20d5c605471579e3edffc223f242c59391db41e98d5f3d6c5b1e32ac8237fcfd1020543a4041e03d92ad3e2ec552914707c77cd01f3e48011444283f0968fa4deeee55c456ed1f877ade04ac8e8d2cb6c85820b4929b25bf31e925435d6bcc50d3e2e9b85102e970d7895c25ade52161a3b6bf501ab01961cb63ed990aeb93eda3828bf04ca52853c7b6b8e9e49e349d69b53be07485f542b7cdd06b527d41dd119c70b564f1a93aec62ae74e6e8f855
+SIG: 4378966b7831def4aecb4989bcaf9cae99461cb9b59d19518cc1ec7b8351bcd1f723aac5f061b38363574ff96ba10e196b1b0531e1183036a425e69c4598040c
+
+TST: 939
+SK: aeb13ccb90c8cbef90d553da3f6901b3d75c13011f024974daf79a1789c8c632
+PK: 5faafeb595f16d338f1c72a9f3e498f38bab69a81b37d2d092b7bf7e505d820d
+MSG: 861a1018d6bdc4805a5c4df87efaa462c68b4bf4065c684c2af131c6377388baee58c6c8f8842362ec6e3bce07c8af55885e82db87a15227800dd33afc5e5fd15701e95f53501b1a6ff83c64e8517149bf3ff011b094a09c673d0fc4a39ee55e69f071177b8aa364e1e256064cf70279cc76695ae49dafcd80ca0a14e1691db946422ec75ab4f7865915a69bd48d89b12adf487d4db9be87cddca211aa88e9bbe849da213989eb0844592ad63e281b2e4afe6a8836006609926c0f787e84f2a95b46b66f0e4555c9483ce2176fc63f7cc9f4f2a22db055aae2e68b30a0da5feb80c2a60ea10dbf67fbbcdbe0be33f2e9c13c469e7768f2ff5960a55eb482ec11d47e154b7c42a5fb756c8ad539b33d125a4a65192c6c9bd576238ca72a73cd179e8cf5cd048ed330213823abbafc3682b2b7f68c5bc46fd09a8cb2a3fd099573ee2e6f28c82e271bb5ef934b0b0c381cfaaec666d717106a874af30aa74125eae9acc2f1f24118cb4e683a731e37e5e464a1ea3d2a53cc0dcad4c17cea9a43e2365f3ae3dd89eb39977420045550745fc267fc7dcc5602e914972a4da6ebeb687f68a0cd7d8b4fdd73722106a8e436b93e5b58f5982acecdecfdb382fe98538261426ba64052557643ce9fec71ea43cf5b6cbadeb4953193ff3ed1a1f922a9af2ec6f338e7fb0affe3d13c33e395873e4a7a7fb044981e05a67197b996b199b43011119363e561d5b8a51784fdff58ab80ed4c49e93f0cf41924f9835efb09f64463b65517b67b15dc3f28ad9a9b2d29468de2c63e62004b6a3fd0c5c2e2aaa6cfa15e4faafa1e2c713e98d3fd25cab9e5170359c8365152b474276ed0037cdf771828e2fb7ccec4895f21adcc5b6887c86e51ad05f255f6e9dad2c41f56b98b7bbbf9fcb6ba8cadfd38ad8c62f92dd87740fa1e1bd170c00b2049c5130fe733f16b1f2c7f00b2ef97b3a95458c53f199d465336d5ff5977806e1afde3eaa246d85cabf7e123481e23929976ed19c40e29ff33d80e7deab19271decd5ee06172b0b0a139bd62a2e7c83a8a65601d0a05d61af9c6032df58001d473e20dd6c6afd78ddbd7cd178e9c271e0572f85982823ce6c402930cf80f5e0c7cda85122a76d1ce021b1e3de2556d1b45ac7b01b59cada25291d638a52a5e7dbcddf96bb1774ab0b077e4b3da5a958fe11dee4a02e69b918ddbfa1c5b3b7dca9f8784bb6b0b9d5a7fee74bb03747f61c2b2f1b492452d3b560b48d39d8721e983752556d44da6b028d9aef8bff9aa379c8e2b0a636d748860abd8e64fc8e96520a34a27f767aa97a8f77b6095218ead
+SIG: 0611b19a7472a443e87e54d7c6647faab1b79a83fd4371c92b975400fd628acfc32577ccbbaf03d88f893c88f2cac784c722a08f387abc319a702c868479650b
+
+TST: 940
+SK: 73872b14762f68dae4fc10dfd6f42d3f9622bf2afe6b34a95649aa387424ee6c
+PK: dfab2ce1ab9981aa7cbf3207350007fa6ce6ca60a2ed7b590f3c2f62922d8f61
+MSG: 433d71781ceab2b47d826e67d39f9b80d2ffd725f8c5aeb40cbe4f9b5f48ef93521ccec604360b9647323190bfef75ac931562d27f4a4e31f46e57bc99fa5158c82e12b737e45c5de9f7dd7c8622d4a7eaadf7202fb49d819c9ad24f8807313c5f37dc20453bdf05c9bf1a3c2117c93e7f3cc8a2542098e8fc1c642fa47b05543657b85f480bc86ec42800bb1422359c7c3e8ff4be598bd54f1dc586acae45a4740622b962742bc86e17cfa63e775354e7707e5079589e8d108b1f11dace0575cb9a6d26b59fce981465d9bc344ea6945a95b862796384fa8170560857457beff95a9b5ac3d6ad282d44929a303026b4bbedd60e2ef055a31f52d7ce8df2ca5d1851c5b167db0809259bb812569074105c734c85d6231273755f3a8b56dc508db5c23dacb7a06167bda51bc01350f016cd41b21e8cc5bc93343a9bb6ea4738c5c84b78fa963c410e433dc598196c22e5b791e12a4b343f7cd47bbb0eb0782bdb1a4e466846a030528eeb89056f73257193adaabc1b229862034878c3258a532548762e29ecc001abd989649da5e144cf35d48699f23bc46c5b34e04a53e72724b2b0b878982575d688e23cbe3a34067f4971e555972ec2908ae5f03e8831ec67755be95687ce6372939e1e2fb6951ec9ecf4bf7d1535431e259f29ad431222b54b65aa7d07cfb5df162a87c4d03481eb441f221d7f58627a14164e7f4c2e3a1d507e899d5358e00829b08cf3aecb8a75b2a31c3185a580e12b13f0642869fffb056723e961aaf6fefe67b4a7c4c93db3fe1f61adcc765569a99c09a3c824ed4a98babeae43efb1f351ba130e22aa97811986be923cc4180a7c4b78bcc140cec15574654aa6d65a06b97ecfa5f3a9355f96e4eeaa7689217b663fba4dab0d99b19c8d8dbf47a157e5d5969a35ef84dff9562edd434e73aee7d0d892dda72a362a22a7e9fa8634a57eebd1a907485ca8921bdc19ee9ee588f395687d3fc8f8c25f2e9576ca60313fbb2c265a99f2cdd5575b1dd530604e9ad6695c9fb35994a8b87d5c8570549a4d329b9fe087069ab7eb0d714a94e19261f86e448f2da9b1cb0c0dbe41d44c3a824783d1bdbd7326051aeb10adab805c5c59d0e83b1c11a2fdd35e444a499ed15dafd83862775f6cdfc67595818407be55ecbf7bf86c73069aace577626a8563536f605042cf7caaf6fc8e3b545b77414df8d9f649b99ee42541da38c3aae627207845b8f414a8074d70868a5c0b07b070c3c653be04076b83cad7b0305d9500aa44455cb860dcc76400af93c3d2efb42ae056f1428b65f122e1c7b9584d814d50ac72efdb
+SIG: 8525c346ca3a6a6c5f65c41778599377659870cb6df9a4a0e55b40c35beba55c8e009e5600b6447dc7402ba27749297e8f9528691856f72d2ad761ed1bc15309
+
+TST: 941
+SK: 67cf27155287be6bfab66215e017c3466322f21e6eb140be4f1bdecf55abfdc1
+PK: d070aab295a8af935727c3be442b251db9e774d2f44b3c2424c52fc89656e169
+MSG: 0ff05297031c892774cb2c01e8ca60ddd0ceacc0b8d591a891e33b19e1be9e363bc6420d6f529f04840b3b08853c835a03e036978b04a4f9ec6be4aef331956190996dea272619f1686d33bef03dbc085a923a0f115b78f653feeb60bb9e45f34fb8be5a4cbb648c7d29956f0d0e96bdd3c8d0649720624cbc2079e84fd6d010241124098459f12af2991d3828770f50b104ea6e5f51fdad30a9b8079d2159e46d64af91d07c10ed19814df2afe660d7d8f2403534e92c62e1ea6d688203bca3d97c2afda83b255520ffe92a33625772513b1fe34fafe32b6a9b8cf994df7e634e686591e5f0073ababc64a89210ba53a4991c11557e0334e6c6a5036c642a318f2295117139085fb34075647006758e32bc00ad109fe803f7ee9f5ec2af4d25c3070abc51cf4d78e13a7ce283d4fb4eb41d3e8ce90238500ae0ceda320ec5922efa10b903748e1e853a3729d24c105439df2f7000123db9b2c01533bbf0d028ebb2fc00dce38ad06328ee9ecd849a6efc3ae884ef6933cfebed055bb2968a0b0676b5729216178c7519ef0788593fc0dcff50d7e0b1ebb3cf49bbd1bfa5c30ea7b88c36e1a1593aef0bb3f9e2091c8589f7414beed8df466a2ed87b2cb5f35f1d31246ceb968609253615d78043517379ee6974a669cb48da6ac2f96d700b7e44a435cfefec402a1e3110e76981924f2601c01dc03546fd4f511649302f0633dfbd25651c5a599c90954489c76a65ec05a7e4cc74616ce25601cc37b804e1f0bcc8651023b12e13568441e8b8ef4c305fcdad3d2b13fa080324b2fd6b61998cf864b658bc7fefcc48a5a7681d7c866c342c7f5d6cf10881522cc710257d25a4c1e352d270e902082ab9541d5900ceffa0914b16b55e0dd3786e98d41720875a148eb4abdb0153856679fb98c0ec485e5f458d635b7861a2b3a8ba5ec2c1444d353980200e5e071808854a268cc76c605c94f37329c36187a41fddf92aabdb4996a0e10b315526afeac80eb2fa32af786a34316b36111ee9352108144d70f7d1723b32f4dbaa82201353411d657713e55e35df78580b1bc08680f0159fa116faf463566aafe8aea69857e72e44ac809ac43f5c45939d85a1a5f4a370a18996c8514a46f34371ef9e5fb204422c934a1d293d101b8c16f99cc073ea366a13a45c437d620d132b74409cbf8b9c075b4163f726aa67e509a24874fc1b1fb6fb7c7355159c02aa13e64badf150356b1841b321f8041e13ed77e8461cfbb8e828488bf517a5d29ff82e7367480a8edddeb5350e7a83423bd0b1c55f7bb424ca04c205723cd5405671e733f391600a
+SIG: c934a3a1aaab78d9269d1e9d13392f72c637bc5de54f04691efc29d473b475025d8d8fe3c523d2d29c41c5f3dec6ca38ce6d68d7ff09b6135ba24d0d32cc1502
+
+TST: 942
+SK: 18c21c0d0de13d4c64497ef0260d66cfd34216981a1b49391ae5cb0e41436e9f
+PK: f7d4dd1e059c36f6d121c0affeb21f0c572b45992f84948b09aafbcd86bb535c
+MSG: 68abca7c166afe063e477b80e37db224e1a235de8fcdeb7f427af67e001247cc5e057182fd9b6db8babaa658cf3b3fe4b0763bf88d67311b1190be834018cf57a332922413764620ace05445ee019a06dff98b238979ad6d30901befa3c64f6bd8c6eb092c2e62841388fd8c4e8419e2778984896737ed90a2cdb21996aef7c21638d6cbe680322d08996597a9e303f6f5f47940f8c5ba5f5f76383e7e18064a3d2dff5fdf95e90c5eb30f4d8d459ee1d506a8cd29cdc69b6754963b84d67494b35305d10d12b9487417b2ce28adcb10b65cc931fb3381ae02e7af79a02bf99e258a56361090e0b71222b3ac60bf2fb7ba832d034f5b6bc6fa663ae741f76d97c1ac32bcb7411507d518d2f6054b578328c5f67f758ac01bfe6f4d35900f50a5dcd30d2f9261b6bbec4c1d1fc18d2a7e70c4d36c21faf8cf94a587c3a0d1a9cde7831ae626775468ddcd40a8ba18f42b34188de5741e1be8307b1084586515ec015e4e371d29443a40b0c069c641d8cee5e4611862987c3e356b1293b0518b4a4c8ea97fc5a4db1f0129abee72fb8092ea35c2dab67573850207b8e82718999ad99c4c839eac14636bd5e4d8436a270dd90b8e321302e52a92d891ff1891542ae2caa0d66e0f661eae37b25b08bb2e0eeec4838009778cd525984380983b2baadd7102a1e356734e41d76183829ea9ab8244c336597ca2d67988f281438467e453f562c67b22d0a4dd9fcb46a5f80d299db5f01f59160a19d74c644fa5a940e32c9d8d983bab7efb0d7c7da4e3fda1cd0d18a4558eb9fe46408aab5085912bf2f46ab63a9354f9027c93691223ffaab8463bac4c4bc3b11abc46ba68717c91780d3f30470dbdd88b3780a194c8a40a2c0a81a4d56dec2d8962c34d2ab73369028e1bfeaa6bb58241ff4f898f80ad3bb1c691b8647f2c6983954c1c77957458eebf1c5055c31693abced05384735a4f741968bd6ac31565cfee71c884c1e29e9e7ae0f7ecd04d463b1dc389c36037e81458dcec61d0764032dd589b92afda2fc9028f41ab53cca2d04ec6a9565955cbcf1a3463989c7139bb902a5921e8b2c99c48e13711f0bcc399259516c81ae942a679d4ba33979eb12fcd2860602e4724b1330f1cd257b5b2891daee8ef4c92fc3bfdb34e532d5870f3805986ac97b503fd85873548e30950000f8a70be51fa757603501f2d30e852efeac4826862aed7f6d20c9a8c8dbe362dfee41893f27e6fd5e91d0e7e3d4fd8155f44fd8ef17af14a848d44a87631aeee751462b2a54087068daeab3ea3289ece6212b3b52ce7a8886df2a727b72a570c2fb9c50341
+SIG: c9c099e21d095afadd4e71c9abf6b7083324776225b587b60a0e6092ecb3d33cff39c67d34776ae99dda754a3c2b3f781135a38c78ed6455aaf0ae0c313b6205
+
+TST: 943
+SK: db9aaee198cd26a52b1181fa3fd92abe425e666d890bf969467dd2ce280ed4a7
+PK: 3c897cafe2b499ecb2e1dd01ea55f3fc88f68c25b64a636b31a1fd1c78f37f3f
+MSG: 47fb621561f8b7eecec6033f2bcb6f43ac68c958dfd2656f52a0c29b4acd44f4304c6bf77eeaa0c5f6d3b22db19699c3dcdede698abde623ec4b2b90910c80ac3af39c550b6dd409e63d77706655a9199cb5c0258f5ba38285ffdc64b8a8f373d1fb29ba87f84ddf5f34d8f140bbc17b3961682df5d0a8f9102e379a9998139dfe40ab8ce753bf5626108237771a7d8e109e9e0afe9b66d0420942e163a4f3c03f71813ee078bd090ac3d0772e2622c259e682552c75b08dd055a4a5eb5e609440bcd3f3a6feb876fd16921520c6cb6884710d2e15cdad6daaeed95962dda21c6788f784917917982e1ccbb5fdd9bdc1769db6b6db57ca354e01a1339d8e77e9dbbb5812fbab6a14c54085c0659599f150e22472470f1e5e672c425f375f9e0d6e8d52fa17b7a8d7a4d7ca3e12f4db53836aed2bebd74589baca8ce9100291bfb7e456db7f2f0a84dc0a7488851366a9a5fea0e3efc74b9cdd4bd97b65abf361393ce1703d8571805ee68a13d3654f03dcecfb77a53430d09496ad73ec01759957e51046aa7396f592338650117ac7b4dd3573eb53d9c9f9dfa62e2369c77af9c0d42f61bae74b287ddfa27b7f1c1be9883a044691d56dc13734ad4ee3a32a9f40e328c500d0fed8ea0510e938f2758004022bcaa6902bda1014b8ae3365272829ed94faba63cb14a36cf81390eca83fc1c627172013261b3993779aa076a5c5d81d90d27062e1a6d90b5cf1005c701917b7adac180cb75bbce0f27f2f180e2cb90140c14cc6009d2d41aab1db9418f91d4cf394002cd70ac9dc11ce865347fa3f56f87c149e2b17d2c72b663a58e3187bb19b9bac2d11483ba12f770ac04dc46d388518fa54dc152e9a9dfbff14f14c61cb375897e30c53e6de42d5e1401dae1b22baaa0e8a41c6af9d0e0b13a91a23d9b7d5552047029a3521946c7120d3d258b3aefcf754d1959487a1fe7743ac7e1cc89e368b197809c3a27317e0ec48d546db1e21eb629a29bc6247cdd4a1371437563edd12faea2c5cb77eededbfc58008fad1f65af35843fa274c734e3fbbaa9cc50d683748b75a485f94d630b032a5f1067d1deb30e9d2218c935c981d01c0c547fd68413136edf4c0c770286e823442e1c513651929213c121c1de700989141ab4af3b3fe7404b4d2a38c530bafb498e64953ce1c0fb7d340e21135bf8afdd8dd65b1b18cf1c8fb9f402b2670400b86ddafb184cc51d5fda273b80c26521f912f3583b4ae301dae151cb55c75703aadef032415227d53e395db6c150a1ee839ad26bae552e1ab736214dc04b0f3c41b7cfbd049681bc84c3d16530768
+SIG: b2e3d9c5d0ff329996bc89d26fb3ac126bded313cbf8df86718638c199e057273d09eb163c6c181fd8bce51f72d4d9d2e84abbe08330773b9fcc2166f140d60e
+
+TST: 944
+SK: a804c33b4d38cb3ce31cf3bac1049e0d4ec63a1a0b7b59fd8a36ee37541656aa
+PK: 6072256d6574a293bd7c221c551c32cf2f7715e19e433a49d9b8b0490e56ef62
+MSG: dbfe307f2aae9e07ec7c4b682106d2c9367b0c4aaa58ae804e0a3904754e6cf8fee73cf9e2d45d0289e5078293dfc469d46ea67026c5aa692d2f2c9fb4ec57cdab4c043ff9ae6185f27a704454e5f53950aabd25c9910474d45af8836862723e0e6a27823d82bcbb68a96052422a1819512e3b43408cf48957ad6ae235b7233df18284749153dfa57de35074a30edfab8a56df28ab2e2940306c221aa55490cc664e14683f30ee615e2d93fdf971f596663465843b3add6392ba3390311ef8dc59f251445d669e10a0061991e113561923aa215244463d8264199ac588924e231e8419d8685f338e599b5f40bf9bd1aece772535bbbcb8f6881c2e800491ab3b57b44b8ae43aeb5c4ae5e7edeb228fedc9f6b9cadea176e134936ded60af1c228734fb00570f2374bbbfa1bb170785805d6b6c701e820952eae45b8c2366113a1dfb2e35852af419b754f9cf7a081c3dde6c8053bf1ce0c85339d5699c422476fc21f26ce75d2a7fed09fc0f4175789847d876c51aa4e0bf7ce842b8308dc7a28c8239520714dc233136e09f557c7ef3e0f83bad63cb28ac616d3928f3837dce1dd58acb8ddbc72e822deee45f00776acc88e00cd3a9db486d92d535a57a0fdc4f903b62e517221c308cba2e30ffe7b91937a99417721f56fe6df44840e9e41136929c0ca3dc28ddf2379e4dcfde83723e2d4c9e23299c056afb31d3e70d085d0a312c5cd570b699dea8717458531348c96f6eb52d7ee61d5660f65e909a14ce1033dc853f2f25d09cf4e40d07eff72e15a390564a2be3c042d89a68660a97ffacec4967a4b618712d7060756520c29ee8d9220ad8615c4fcf3969bd3b2e0947e1f0be7e2d80e0a61480c3166db5582218bb0a8be9848efd41b6ce0cd795c486abb67210beb60cd078b46aeb7f4f485031902bcd7131e00b7035aa2d43fee063f7f30bd570da1dbb65c0ca92a4812632e432778553e35e856caa8218221fd6316ab0869173b38409bcefe6d2db9210f9024173b66dbb92677cbc71c8a1cd583fa6f354d3c93fa8b16c71374f25a00c332f85a8befd540388fb50db9f5d96e4e4e698833ce3d63c10b8eec70a243b9015db459431b62f5668bba60f0704f6bdfe9546ea475cef2ebccba4b7680848e82beff5854e49f65bb773a4922e90f9b8afc7cf818730588ed5aa7b399826aadd54372fcb761458b64de66857f4adacd4c32900cb77136a535d7bbbb554597aecf39ff698b45e6a218df1d2abe615eb8d9e1824c0becce90767899ebfd2c730144b32c74604c0e53e2505bb15d28007a87b9931d6eec0a6cb5b0f96d3194b2423
+SIG: b1b44a142a7c4c3d0bf4661edac5b767005726c14a2769b7c214fb58737ec2e4bc51c3a195d2ba1b74a54eff4c33a90f41ccdefa9e9365fde8dd859fd3978c0a
+
+TST: 945
+SK: f820e6f24a8418b6acda165f29a360f767cdedde8f64d768b95fc2a5f3f404e7
+PK: 79c4b263b2e58f678628d4ea82b175aca230b9a20285c828f94e1ffd63d75b23
+MSG: ab6bd45bb06dfb9069118ff998f3bd393ea8e944979e89e049f2505cd8931b93086b7e9d8ee764e9b447ea4ea12138bb45275a21a19843f75dc5421d61ffd861838e5833825d67162f3259c26447be51dc1802ef5a04ba73b783935706abb42c513b65f2bbc44f83da1061242f2d5e5198f38c10717a86a3a197e7cd9034f636114499037277acb4722c06a91cb2f65e21eb8d22d36ad73b4265f7a7947e00e722bda67043cd1281bcd87e763fc97b54c8f86836cdbf08c9a1f700f4eaed9ea59a6fc1bc0df8c9ec1fc2977cad60f978abc0c8381aa9fb060e3f99378a51b2d9afbef358d55162a38922ebb87d2a3e0f0f4000b1c39b1502e95945e8ac9f4a3ea7c9ddb581a5ec06c00ba87a737084b384faba09c84871ddd67dc1bebb2f7fbd94a5597d019fe629e5bf12bea2e33ca84c680dc5a3989bbf3af9eeece8ab8fc861e3b8bfc1e67e2aee326b37fb9b51cfa0b5f5fc160069b450b704e0fab7fb6c5ab3c40b8f0b3d0930b9112d64b9dacab4dd875f29d8c58c5d2053ad9148ffde22d90bc0d50f5deca68d3ea25c5b4c7688871c0c77dbceeacbd0a4229f4970ec87b34499e278303c06694c30ac68524d11b172794b481273a5dac46122d2472095a563a435d185d5e91da726e74592999cdac688a33f38f7c035588f625dc6ac73d0047ab3d6d12f1ae33d8b62d6d6c6cacff0bdd894b57e318912ac0cf4a534762b2f6d263c935804423ed868cf8cfbb8be8f6d8a714a268a390edc2dd509d2dc96851d1bd43249bd0f69b0c4cb2ff4080d1fd5622bc238dda6e930025d8a2b12b972f9eba17421d4cea642f40ad9ea8547ae59498c3ad1b9a0c34ed8c01aae3bd21ac17743b577f9515cfbdde2704dc57e80f125323d55100b9f697927d431dfe73631b58e52aa6aeb0478bf459552438689fbeb9c60d87aae09954362cd02a2b0b479efd38f17821af39b21926ee02f7d972ad0f54ea6572cc3ebd020b1ee26882533bd19114323815f672ec8c90568730a58e4e1e35f6821219a32b8a6c52ced6f9573d9f3beb28513ba62fb201f7fd41bb10ca34bb1c70f2fd7bb9299a7c5f7f2e0fa1d1af0e9aef5ede7c16950e860ecd61f1842a1a22c9831c0c0d4eda840b088a54520c9b18c76eba9bebcd591381c180d7f86a0e58add92b9b0c8076a7cdcab60dea4c1afb18c8b94b1b392ccfb4dae2711e7d12d2bc7c7825f63992ec3247163c283b1075e32245f69cf47240aef0db43efae86fc1fd3bb99cf5b789f5bcba9504657d9e622a4aa16f01d4d844413124447d6d1a4423e7b55db7e6a31a319f4bacae430a33a9bdd4ef3680
+SIG: f9fd72f321ca2133bf8585908d9ca7b8e336227e3ffb3749a1fbe8c9b1e5d50ef01f9db5f0d2a7c7c1399b97c9044e1bc1adc32b8bea46dad7b8102646960303
+
+TST: 946
+SK: 0a056be039fd55dada441d037361273f206e000a74a05c51c0cbb62743f1f340
+PK: 73140217a493a17866fff5154832273df79d5811543c222a39d056b8c970dbfa
+MSG: a5ab147684e4d4a7bcb5a96fb39818e23f56c2d8a744e9123d62083930ab1d0bb532e68714fcec7e6c41134b6b19ddd867fe635c9ed65393ee39c5e8fab456cb5b32797883f3cd9a0902b9796348ee66c691fb4f2bb14764410657c74ab364567879b6fa0a6f4dafd930d9234cd7834fb9d0eedfbb5a394bf0846ec6969c2ef7ce39e3853895ff5b4da31e54341b4272e4a26049189ff28241ceeffb7d2e1faf4f779fa65cac0f5783c60ae77de30ad4465fdb390d42571eff4a63136349937d6caeefcdae229e2f28cea8abf3ffae3c3eccd90670a4212a2bee1ca6a5b54f094fc3231058f5cb9eceb9993be47027d51c18deca41cddaf4e8bc56a99fd270355ff45971950e3437a198ccc3254168dfc1574080802ee101a617fb604e868f8fa8fb30daeb43074de11f2483d916de5643b7cac23d9340508a3fd621ecd25004356a53554ad3ad7d5d25817ad7c9a610008c67ac16ba4211c42f5dadf86c2c3aed825cf2a9b523bfc03dd7de400c67807e139ea5dbce4ee1f7d318889b01a9f44803c322ac3b61e20e6312d0a03bf9927fa33f04ed7e207b16f26502c2983a3a961f224461fe9b64923b1d09189476ae8d001d0ecaae4df60db35f448bb612f9655a5fb144df11d83aa6936886c304949e59aa46df65c22ce7bf289b3c77c25d896be6d51dee10748261688c8b071c856f9962c66775ddf16083dae06587e32a6361199d72097e383ad7439491b5a563a3e6d58da3d5abb1de84890a36b421ce03d484dfd60039638d46edfb60659e3a25ac6e9a935ad6dad50f927bcc2ff99f9924a5b7995dc23c8f301ccc7769f71c18260904a3dcfb817d2d805cb1f196be8b6ecf352bc296bc3f76ea91353f8cf35bcd2b57eb5942773d6834ac50eeadc7e66461d1da098ccec75ff7205215f52459d97620f9f0289e93911db39b21df818fdf0bed45509244633df01cdddb4b75972fa7ea6f73281cbdbbd1bcb00c3bc1b1728eeae0bba172b131f5d30890a341e6b72f7e89dd4b6db3e79b6927586cf2c8ac38dd14f374d7f5bba9f4353def10ddc94d3d1118c5699e38b6b504918e589efe3f7e973fb40e2ebd057de1385e39d699a8f683b962fae4f3902881f1afbed7c783823558c36d68c6875d166fa243eb2ae14f7e6315a6d2ab4e79ea8e16e69d30edc708f1e7af7adafedcd3168898b331878178c4ba8833d20b3cac9d32b8888cc6783206397470a2e7cc4c9809ff79ceac9dc24ca1438c919c8a415e82f0902b4d9cf4ccd576968d5bee81c5f19c7d57b9bada8eab4756ea270dd26129e6122ee2d615242bc7fabff4f8312e686c8f
+SIG: fab8e5d93d7d46c65ee117c5375e73c9705f8754177fdd46efed4737c28768cc4b95a9c84c529b4b916b28dabd8741183144bcdb483df98af89d8240cf094604
+
+TST: 947
+SK: 220524860cb89ab295bd884f988a57911868693d6b105a80b230f21e57805a7d
+PK: 4ab32bc1566a7677e799734dc84181fbb654b813379180f1dd35aef2d324c12c
+MSG: 024a54ac5e0163b3a4fdd02f5936888ae2f9b74a6414b53c6381173b095a4ddacfc3a69f19167d0f1ae0c120bba7e9fcb7ccfc796d89ea46ef8058866ef6da7d01a6a142ea69d720c4f805ac5405a8012c3c2a8263b5372d59bf7f4099299013d26259dfd5193ece56179777be51b86bd1ce5f1fc9156f2b3a32c09d86bc6132de576102e2f03c716db5366ccbe742aee3552ac3b39d0ec7d4e4e9626bf8ece031d678d3480905c0e338fb7cc026e3e79cf2c2781ac2a5a40df4284e235a0389e928fc63557dc6f199fcec5f361ea24759fa7c5f71978c0ba245e4b03ae435941c86c81a51430c2dc9927e3b0f4ec4eba7c2745b493987154d7da85b67de21c598407fb2a760804ad05bfdfa45a613224b22a08588ccea3cbdf47a198bebf8cfed8649d6d5f3fa501376bdfba4003dac2237dcace5315b7fefb879a89a85bce6da526fc360cbb4fd554ef013f33b7384cd2b22a88577f3a2d366422aae46417ba916e1646e24404a88b5d53ff1aed2a47baf81fcb4286397991394b2ecc39667ac46c2bdb6d023b33db013457c4005d839015d8851f028ac334fb24bbad2902a4d63ae68e0eca7eaea1e856529647baf1412213754ed50af3f436e9bafc1601639b39d3e52a93a898fb6019fd5ed6e7dfc050e7ce5f3d35ceb5067021c0fbdc708d3f26bd60568d1ed2b612b696235d5333318f9a6c987235a7a07f8c6a9354fb8e734763065afcd4d937764a4f037cc7e7e2b93217f1641684fa81b7ff7986a28b38e95b332e74649e83d0ded795c57f24cf276e0143901bafef0f1693fe7cf10904fb0d880d72e44716a7069daaae742cf0ff3ed92f5f7d1e10e049d8df043631ed0ed4c4ac4022d8403cb0421b454cbfb6f48a30e9ee1609ad7b68211977acb33b9c1a1be735814c58f66db5f0b8ac773b1d58d4e6bc45dfd48a294bbd25e92671f56f302f29b50d80431c8f2ea33996257b208e057ea7672cc2d1cd4204b85b2ab509027131359aeb42e3eccdbaecfe2cd3e5a3313266e761194ff69cae9e37e51cc0a54f086dde13cb33118e34fe33c74d735582752d68d21c79e5c3aaea94ba107cb7ee8a70a3f9a01e9808c0aeba6665315b45625840a033a6e2a875495057942ed9bb2ce6e4ee60bed47cd9d584bc24524397a109498ee2a973aad6a29b70a1cfbfe9aa5c7cb9f35f0fa00227f43988d07619b6fb2f6d3bee28e10ee705347015a922e2e88d34fb0ce515b08df3a1b634ff9ec15d0594182c86ebb0db783612a7d19e4b22e822d566245aed72e694c3d101bfa4ca879862e5f99c23a5d66083ce06d87f399aa7888ab83b8664472
+SIG: db1cc0c5db773ec51689be28842fa6791a7d75e29c228ae9593a580e0875b1670f09b03442929a18f1e9414ea34315ff09d91d922ee47f10f71da4ab13b7d901
+
+TST: 948
+SK: 4ef60f0691d737e64d437bfd3398330e55e3c094cf41fc557b0fe0b643909ab8
+PK: 306ab146e5c8cd630f9b48bf8b685db0b6b553ef69686853b6b531960118548c
+MSG: 0a188ac26f3c5d89f3d588374fac5ecf9a467e2165b31d0b0f23501bd22e62bf3555ffba94631de74a6a3c3cf63b03ac1bbb37d233eca5993b0970a0220de8d6c41a970307309a52da0576dc334d806447aa09d0b245eacd0b42c4e19fa3d6fbdc229430eb3c7558af5331c6e7fcc2e552ce35d579073b548dc115bbd27e5a33ce1c47fc8461e391b6d767953487cc52ee673bc4be96569c8557369ebb6e02f79238108c3b5856ee381a79ff464c8f6009fd47e67b4c80201e11e61ab8f59ba5d07b15ace3fb374c64b6b4c345e2b00e9151ab8e1c5c98568bc58dd0812aaa3beee165e7eae58fbde63077203c4fd6e16068d76e3d3a13f1cdd73288bd5e4da44eb119a04c4d32efa2f13e7426a2f41c5623c9b066b1303639b8fcea0d8774cc08045f7e346365ff31d3b1ed99e97bca5f25c92b2843ac585d02193a2fd39466f73aaa989b1fa05b9a157fd0277c5e745d258e027803a524ad94309425c3f4dec31c0efc547752f4c7194cbb272f849a52169c6a078d20ede1432016528477b58c2bdf6063f9447e33837ccb437d8d6b95cf4c44be70c8193ad980a105f3db6f9930bab4678c776342faf170edf74248d3b1ca96f731b9d026d8f0f7c34ed372c1cde176f55f558675cc3180c23902f4ba9508d1c91c3c9e688730327f3f7b637a8fee54373759fcb17c9217ea44ce43691a8f6463640a4a5e151e6254c4ef12623b49394da7cc79452693817d6baea9a0a75876948b1f8d3b717f9ec36753f53263710383b98262ae6354ff2a2283220ad42c5cb2cbbdf12c879513710b16be856f3b1355b36f4b80c017c21be85e96053da050c40312100abb640b873d88fb6ee0d19e9e61b04c970bd1f060dd311bbb9a6e35b985fdca17caee8cd5db637acd90cb8e823255c056018fef5920db640d2201c5eddbd8a9c9474da8def7e1325b3cc436c74f815db1e42b421faab626a4378c2d84261bf649a53b321f598c44bbd3002b06cf7f1fdef84ab35f73ed7dc65096cb1dc0cc0e34c561c8a15cf5279abbed9b16ff24a9744e3f5e649cc9d8884f891c3fb78902031ffe0e0121c72080ad10c247b7c93a9ebb2d84d4f877750d7b3416393d03045226bb7994eea58e272dc18c46b382d1f97b23765fda7a8ce21fc6b98d723ffccd99ac4655cc5d10105a2a5b7c8cfbfb90e27a9a809e41ae640063286405a9be83ac5d2907a45f163c7764b09f99a55593220d6901292b9b5803a0fe71b0e4441cbfef841c33cebc98364d666e5a9f5e7e69a1508e4380ed361345b7248a4c1c1ce08769bc7152ddb332fba176200f5abbae3812f406da72dde5db
+SIG: cbf7cf22081c5f235dba35630fb3f0408fceccefeb28b99d74dbd98c902c7d99ba9ca7fab3747c504cc219f4dd101081f58ce616e29280e362539fe49f34d705
+
+TST: 949
+SK: 197e15dce4c47d734dbce4688a7ad5fe41ebf2aa29a2bddb2bee628429c1bc02
+PK: 30fac323048b0c781a9f63c1ee69f2b9e75a2706d249512a2739607f26db138f
+MSG: fd971d48946b51ffed7b62c5d099c1e56b1358b92235e1010e3f23844ddb73bcee8d2e1c9977353bc96a221c05602931fa16ccc2ab6d0f01c846c2920e99de026dc2897f3d5f3cee174ce751d4a805ee1959a3c69cfd42d7c9afd31fa9b1cf05786d8f9042a4f9f81cf7ac9c1c39b36f1ee95b98cf7ee3f43e2c343733d1d82cc08b2cdeb78d982034085ff4dc6536cd154a790c85c8613ec4e5e1dc377d38a745d938cfb15c8b8aa86121835f2e25e9e6d0de68025d810c3dc9df991dadad39dc6981fdbac1ff9b7a791c3960d8564366e5aa39a9e9c7cbf1d3f0f820d1b90108751ac764dabe05c51c18529da1b0349614668424ab4e936440c4a2513be528539372eee78754589dbe7994faa1f6229124f839950ed0923f4323315ac963bbe4c8e177dac516e7342238f1cdf140befc8acdca3d002b16c1398d868600304c7e9853b23a51b17d9fd06156e1d1d08a28460909fa209ccccc4cecbdb1a46348089115318681a95ae580ab6766041384651cc4e6145103923bdf4a32a93d93eed318791f20805f7ea84b743ee11ead9e4ca03da76ddd249fd4475fc1a353c70a83389bfac52098db066d1029c4effbed864ebe7f107e0103b3a8f3fd1d6ab4360b99e8b140c5ea133e923c392b8e4063aa6e522638f61d7a71c9225897d9f8a1e16cfcc801e7d54104eb10e61a5ae63c5c85a5b29392ab3ab8e5c039f100d0f4600c610e0209436ef2ece4d0bdb0bab437b2db5f3708fddf96660f6fb1a90d6048d395afafa760ccaf15deaa0effeb26ec17681d172c1330f78e78a8736b285f615f15d4f2c313d25f30aee9d1db39f535fcdd0ebc8e71b89ce6b3fcb567cd0fa288f48ed3a759bb2ed200fdc23091502fd9ca651ce5e3422a98335a81d74a65cc1500e9070abb609c1c1f68fc2ca94cdd550f99bcb2d092416b9bd388410b8fe748fb8c9a5ab8615f2ed968f85dcb2727726984beada7a18afdb0c72aa65de7abb7a86f11169a6eadf1c21d614e52c0c8f019747d341a05d85e37bf58d8327e9939c2387c2744edf838563cb37f0b16e8a06fc628a97230506fa4183954dc74815f3be2eb2aff4a13c065f743b7d85de804eb28efe570ed5ecc71aba97f9763b436173247f38e0cf6297209b65128465a382664ced8011fcc3d0e563f155bc63c94dde73c7b17247b8c3a4e8034ebd4364635185ce9c7081dbdbe8545f79d01aa532a0dc52cb790a31fc2ff41acebad27cce9244554db652fa287bae7decbcc8ce9e01d1a88ab412b6c6578203b42dec982b7f3b82314db2cc7c5c3dc1d3d8b17144da7fe60e7a8725fd0a97c610607cf413c72
+SIG: 2c3c8cd299c9060b65999b03a6579bc50ef1fe0d851f23be9cb58f8fb8c672ee086a539ead949e087df091122d26faaad206a5c52fcd58b514d7a935be017908
+
+TST: 950
+SK: 08b5fd4e419d2370c0fcd6c3b92f8db3afd42268f533085d9fce32b522824e34
+PK: cd0da699379e4f9425e84b9757300a51a163f358734cc37a91ff0ea488d29779
+MSG: 3ceeeea30fa401563df36b198b9b59698c10e100a2f30e6f78fe62b92ecac989e8aa09ec760e89cac0a16bde3cac73622a8627efedfa4ec09b873f7e1000e76982910ca0aa4afb1ff5a8448b76f7b0d2a2d52a7f40dedefc68d60ce6622ca080d6698ea6c3bd7210b3b648f53252291494b35a55ff40fa1a631a57c510011a46bfb9e271bae1e78ce6c6ea60c55ba0cce36059bfb01e394556987f744b72aebbdb4b1bdbb3bbaaee1b8b2f3174506a793f0a511b2b569049b30a2e0841424184a48eca9e2d83783ac5b61eb947cbd8bab7ad38b0c68427d8f94ae285190dbb6e0c6d580a25142394be948158d8da83b4f34a8d258b97075632b3c28bfae3105ed1872e356e43aed59397b9110bbf9d8ca2a044d5271e6cc361e14e69a932517683ec81818f02cfa0295e5661cea3e586afc0db41ba95553ee75b200b0f9790111d3757a739e563557aff9b70ca14e87b795437ba91a95dd07ea69a11359f36ca03298e0bfa4f912f64a2924ad901975a2a960ba1be89921b1f5485496b7ea5da6d8a6937ac105bf3760e4876990a0f5c5a634f74cb57df7c172c8a415372e6d903298717499616f8971c68bbece92ea878a18e23f327c3649b6a852ef23b7b3e603cdf80452dbf1be2fb77e814d2525496bb31fb6e4ed2533248b39d5fbe2390a9b6fccaba997e8b49b59836e3e09529ea5e4113eee451c9c6bb26741d0e4c586f53d604c6ea0c0e60db02e5109f3734f51cdd8985afeb3ecaff65e059e312cd50fa349ff28bdc9b70b7f532dbab1df43b03167c1d2e3fa6ee8c9b174a0b2cf8aa9ffa406bf5bd7288780c9c4a6b697949b48638d42079c8c66e14d9b572a210a093eaf1d2f7a703b5cd20adc4f9927a6ea8ea78faa61bc62b3c5cbd3a53252566d043ba556590d9a763be7fea4b20e1e9cfbebfae15439b334dc539b17dada2e434e9c83225b1e8f6beb7d556b47d7f69f7eb7df5ede2eebd84e250b7c9468c21fdc0170ea8df662d6180581f657fe76cef1858b6b02f7325c7219643fba2f7e9963a33322d6504ab91bf10a978fa07b47d5db0be000dcd002bddaf676b77259c9f60ad0b11671cd5777c1e80b13f82eb0fb6a180b5666293a43240862fbfa3978d95311971afab9e1cc8ab14a876b6572ac8a4b7e0b40aaf6b52a1cf4c1ebc6c1c487df5a3cbc4005a0ee329cabc286db10f17d0f1782e07d3324f0c73efbd3c2fb52b71f98ad95db95062d91425e73467bc1e4e9bf552e8a24429d97db1d66dd4d995e5f8d24e9c910b2eb1758ef75525c3d65a3f430a027348820ce3053b6f3af4ec96d0493731c818c6b1a70c250ac686a4fc
+SIG: 42a13756b75c6722485fa3f694041b39b7d7c5fd40ebc06a52e0ff34ce14d8d40fa82a9508b568537d26d0dd7c0a31be710da80aab35196a039b60641db1e101
+
+TST: 951
+SK: 1e85c9e451b7acf801d16bc8268eb42ae85c72c68e9f90927aa0f3b50befd229
+PK: a69d057f4b743811e07ac74561c225be0381c7d5849e6018793701a8cb6c99b5
+MSG: 189ea9c8d9ed14b0de82b44cbdd58757a27c68383fba597761f9e862e08de15b1e44c3db1badbde76980ee39e699629f6fcfef32d36b3393da2ca5a81f959c8b0f1b801b5fa4c47ca39591e612a2435c5bafd77a5c7ab74359210906f47533b1879e2a5af5864d961c8146e25dac772555e042a887261419ab8c9f6f625625481da5b93526a131f37b534a0050a8a462b33f20a7e94b891530b19bf654ee9534c9a8361d03635d8d27d46be7bf84781ad0d42d1e7c4854a49ba1ba458262fe5ea19021b935a6949492d70b605e151989ef2641b2bf81ec4b92020fc7074c2a63229d51a944186a28895e8ea95292c2f872bb21a3149399e23ccd8e2fc4f17a46b59c282c51b58d00266a5c16b1ce350d5485e8d8016dd0a50a5984cc948154cd5ce7cda0ee0ab1d7251bdc70a1785b8e9103917f4b917ab2b494f3483389a2f9237541849ed3bd565cffac9e756db56ef5e23495bc771e88bffa8707ceea5c09becadd059ab889d1df7e887b71a9e6c238378fbe0c3630386616363f207b16c3270d39acded511529992f4e598789121d316135810636baade8a28edc66bbf5ede3f404a70b47d35988be706b4eaa03023a39093d583cd4cd8bf4c74341a028c19d60da31b6a7a034c081a2b030feb3cd2f03d0faabffb58e3fc36c006cfb92947a7de5ba87476c1b051e18283c03e9c6e5a5c3c2777d9a0757372379664e82f8485824fedb70a4bc4e356edd1b5ce0fb6e41de0171621b84fafa00189afa8a6a900b14c70758f7aa4fb82400e0d18ab3cd7e48acfd489cab0e72e719f79a07d066c531a891c55291f2245dbbee44e52b1dfc8727aae387ab9e71994a3854e1add73d9a7965c775521c2f540842276dd309e2f6a341e7f0f37f22bb6627b6e9cb25ba24c6c4f4eb9f5e7622d88da1984e29c5da001039c44042b59351406a41336dd772d497d3fc8aac41172eb5aa6417fe422ec7c150b96b0454ee331247cb1538aeff3eca2d50e53d6d13170a76a0049ea0c05904a6390ed14ce7491e97f754c5222dac4b6118ba381f552e73ea8491e3b7ac949569b569cf2d29a80410e065b5cc4a466bb04eb7a15f596792e8490ba7002ec361571af5d8f57675c956449470a2f9955407367e409a232899553120a277db863e9a82ddabae87b789145ba898df3c28b96fbe3014cd085c6e60ee8831701036d99c5425d58e8bcc9fd9271d46aec1eb955130102eaaab44e0770c30b2b127efb0e5f8a3f7a0ca34ec9984a46011bc26bfde0c0819bb54706b565638b7542dc4b8bf8098dc01f161b3b129618b59aded33cb59ce9189a6762dbae5b0d34b71c8dbf
+SIG: 6c36da9ad6c456343ce642aca454923a52a2844ce5ee58947c8df7bab2ebe467823c5633e530b167d71c47ad9549df05943f99421e17475c4d4f08dedf6f3205
+
+TST: 952
+SK: 51cf868f820eeda0dbd10180f777e6065c93a483c58a778b67e7d842302fb767
+PK: ab088f502fbcf2150e4846b34d2c8097ff013c02a8b97cfcf2b95a1c72df3e24
+MSG: 7c2d8ee82d9abf8aa9c724c75b90990473f131763fe93b30cb04723588621da2a327928b22649fa062cdeabd77761538b2709b8fb7a2006e503509134c929c3011e1d728a57a4e175198075e214253f3f30e01b6e04eabd4de06789558e698b186efe34b32129568b3e8d0d7ea3ff00b3f25a42236893aa8a41b674a0ab5f41e7b28cf5a7cb765e18ead6de6a353a7824a3c49786038d6f4937f3264d6ccf0c0a2465bb693e52b3d1e6eb9ae4cb65d09cff54842e85362857a59f7198a688a3df38513cdd61e21dfd859142c8344a3b8b2a7c7db170f39f87ca3ff8ed427962b2b1a14d122fa2d5aea2a6640117dd258fa0fc54ac6e940bc16d211ec9adf914ab16578f521f655d2127e79e871bf7fa7544719d58ed847850cb27b99eb8f29b16cdcc28b15c1259ab4d589705a406688f605a2ebf58051c43a77c4e01fd6f749d32db4e89f263c2c16de181f0e6bdd0a6a64ffe6f1829444096d9f3e2b67e4bb006650b5929d1f82eb11bbed24e8f1018a7384605a3cf29ab598337939c76a3be861e483c5805ec3cee45e3424847a08558dcc99499fb9382acae56cdc87fbd5b26ff94c86f2e108794383501c8b33366850a76a0dfc0a7cd789a03f01a3e9d9e9ae39fd7245dc29299d24f3b4b167caccd223a99b6b20a3b673dc5f7466d0b2f815098a497ccaf80420168eddbf4da57b8666e9d33c48eb304b4cfcf457cd7659543f6d1e661890f562b43b8b6d1c4dcc077b60bfa533ffab928dbfd955dc5116d770950b690e2106ad52d42c31c22b8848894332b5c699e5c331fb381e5812e7526fdf4b8aa2daaa2ca2cfb9c92111b61cbc3d1eef6c8c6737f05588f04467db8330843acc98dc1a16fbd9d9d94bd8bfde26c3f71dee72b50910c36b240f802a61ca16372f6ffaadb2be4e853c5ed69a3d1f6c7b2de513c53a3fdd0a676f83d09d5c51176047d9200716bf22bae45fe01b3e0c2c51c16e46ad0637f79f9b4d83867704feda9f227831dea263399ca2771a4e78b4df8ac0de6a941eab370b1fdb47daf6642aaeaa63170fa9b3d1e1628f7c4e7cf0ea8b8a8e518cbacef9ade84df032484847ffb61bbd07e8727cc4c25da577b264519b4999fa7c0bc323d4f3f9739f780b9b2c23c77855ee5f6dcc401544d6b64b2770158fdc6c12f4d89beb044e0e85ac7a68d42917b1345114b9a672d1231b2c6c0f969f203531e71bbb4005b103a7dc3a58b5b824a7e01b6eb9f496dfa64d64d8c6777f53aa58d5da046d726f55454c88b6d7d4ab0d2198a89709f118a6b32460b9ebceff3fddc605da77ef3d1ba30fecf07be2f5313f4ee635af5e9561d877e99c
+SIG: e15342a11caf892895e466228863d083b0692f010610748c23df2f11d29475bafce927cafe7f07efb8c347ed5663e73bea89531cedc0c348e79b6e58a7574907
+
+TST: 953
+SK: 543d5f1d4a6e1029b1914138fb1f4659e69456557207406688a2035cbbb2a68a
+PK: 3c83790c3b4553deae4f843b501d26f6167093ee54e279759ffad8cbc061e720
+MSG: fe0057f062fc871324b8bd5d427e9a5276231bd309907e5881d7ae53b1f370c2a43302a16510b46064a30736bac90951f1d9881af62c701483ebb9272ad77212eeb5fcbc7ec228d969f8902732113b98e3bf82dfeadd0de5e765d2870b12d1f9b5a28297c9fdd1495cf87789196a7d644eecd93587dbf20c28eb09da286603c582d2129a657db2d17add3558dde029ce27b88352de3f95aba17e1ed1913722db08a795dfbb70d62a8802724cb0f535f848d052aa3dde9166963a8041fccc4e60bfb11de2bf286eb602a4af842f4d1a340d78bbbcb2857f0c308f44bb101e7bc8b741d506094e27bbafa72428ef666ea6ea16f799b4ee58278f045974d86dc72cf5260d96f9c09b2f1181e1a4500f9283dc677f384ff64e51e89f76582020326c388c08a0fd00de73d5d49c06c0c684191a264fff726d872dc3ae496c7b478cfc61b51714192f76463e3d0aab410ea115e8befedb997ddd169921b3207ea66c1f59450b7623129fd1e2dd3da8f5206391171338ea0ec8ef3c59ed8afc69f3865c29a0723a9bbe95a742681ef9857e81abc80c92d2a718a804f5304fef3c63d799a6ef8782a7db46681d0de3506446982267b2152b0c321869e23cce8c4ebebeaf4aa1ebe9283b692605260ff621b03c10822aa5f6d03bdef49c462a68d471e849e164e3874f6e9f6cb3b5f293eb38ae5245a159ec4261a9bf6b5f7b7615fd339ea12733113ce767f883ae6675417fc770b50bd60e6f20addb29c1f7506233e32a7ebfadabff98cfd09b2b3bbd3eae0069548b9d8987af46ca98eb095bacbd874724ba10f3633aa08ab6ec26494ddf6854309b55d43bdbd29a7556f12dfb23cd0db4eb3937a65c4aed96e87b346555f9fc6897943a0faee65ccf394bd89b381beece25d1ba68f8fe32c23b3354f5be7e3ea3c0dec0f7ec2dd83f92b73058892b638d4c3b7242bb8f55bf087ba45a190a698bae675e0cd5e8446f2b21aeb63d2caea0f679a837e79357308d9f0b8af31f9d08008c39ee8d347528713c8850017a7f4ab98a35c7531940fa7621e67203ee782db3a2faa30f3aa850a5ff7aaed84c00ffd214f2c9261735fac3259d50e03c2652505279d91251927de5e56a8b9064ccf9f45dcbef46e1189ced2bc79e6ff652e69097ace5568bb2d5bef3ce21a25b3f79ee275ea34e621380566d704cd93f24dd9020932cc05218c23b5b22fffa7e99ee7fe457876a5e3364c9a8e8b049cfa20969774f506d1996cbe6ef5a37793ecdb04cfdeaed7dcf79ab278474dd770822d4b36fc68e4b2dd661ef99de01de6eec57fa573ede10fbbd5ac6fd6cd8bb4eee509dbb4610374401
+SIG: 55201194026fd6448b1d52f83ed20ac284e7e77fa92d5295d33825cea3aca47ec7aaca2fc08679f9acfcedb376fda4619be3272c7445e8705c306141cde16c0f
+
+TST: 954
+SK: f8d257fdfcf99796f8ce4d8aade3b225a53c26feecef395b9561d9d587f5a33c
+PK: f66bd4877df78aec04ca7e77732899de06777e698629f29969f8fa9c2f47ab9e
+MSG: 233e1ef901abcb69fb486085d8db0233ff78f37b136f0afe24f7dac1944c3678e74fed58a1ad54835b7dbcb46fff6c3524312273300b6d878a93e0608a4abaca4e3194722bb9e23d17194d8667b84f2db038c24efb8f53409cf5594fddb8bcd61f74cf0726b51c651ce01eb66a59b455f7d8a7d60d3927e0c6c54b138e01925371d2d9d962aa982f5e6085280cc05f356993911fd2039dfc342117970291381d82027db36c799100057d9352b2cd879d9c82af734b7fa297d21149c978aa5e125b20372a9b2e0ed357337efaea1391f3b9ef11e3e5135bb70bdbe32a9bdb7c3c42d5d57cc8dab6811628a01089495cb8a4a76a48296cd8dfafc005ad49d70bb19faca2084a1b6f5e48d23c03fbcf6f106db770f07c33e8e7f4757da904a44dd0e738f3d5733a329375ced74f3c42bfcdbb910100455d6aa7d2e3e3aaa58a829630d376b0b466dc85aac48fe269946a7bc72d91eb37ded2f4a77c684be01093fd12de9d9d83199ccc50959a48d6e9a41427566092f04a0f95ca52372e0762b966ce6232055a4fd757c61b8bad83baef91a3c2772fb32ead8f591ac1e02bbf90a7f6c39079b86fb814cc242e980f0b8b1a2cecb8e6d4e8a5211bf8babf38e829ab9883608bd6d59ea5e836a9b4a4fbeded1bea2ffe977e8cf3615ca4a50fea1f05f1fe53c8eac500323e1f52a806831539957988d79acc7b54f7d02b480c469fd69540fea4bdd68cbdc68cf9c7872fd792591b01e9d9902d8a614f4c21823f23508ffd49ff218bea922ec141eff60da177ccad7d7b9d444f3b03458115f116cc6e37625c39cbadf09362f31d33f4c13c33b6292007f2cafd194f62c643e7a25571564febad7d33e364b633d008b090d7a091358bc69c567b9522b5c1cd01218d38529aebb03d9c2a5eb2285a7176f98c28036f21e19e92b406e94895fa281b35228fbf76e73e1758af1b434a4df98e8cc556b9d83f6b0b7ff52c680f65efe4e00c59b46ce593bf98899805d02b9165b7429849e73953770ae393e4f1f97cb90cd6159cc93952ae8a4d3d56a9a95df7cfabacd4d030d736ea454dfa4b4aed1bcd885d2fbea5ffa2cf2927c137c86be4fe016412628fe7a0a0f02b6b6a9a2168932b943ff8b28dd587e77287790aaaa69a98506c764e6f5ba6338c09f382e1b987d99f14a3e1958cb62ae6705a577f9ffc67306401128741a8d0af03c0aaaf6af06bd88ee4b0af6703e0ea60b0409ace24572fb386e07e9c22c9686bdc66d4fcf3c7461d3833a4c3013243607d4d158217187326df51725a6bc5116e990bef8a5a9579600207206bfc3a6dcf0746ef756fd939e187f668750716c0
+SIG: 9235d44807869816e28e42c81c801ffb121de826c0d33dcc4a4e1c932d5228b639bb294e16090a93d1f6904a7004222fda0a55446d9901c72340007bb45ae103
+
+TST: 955
+SK: 8da9f54da0b6a5a38985b88b71339dc7384cfd5a60bee159c394c22363bc7edd
+PK: 1ac1a8edeb217ae9b3a3de530d24d83e11fb6538cc709b52994fa9c3f1faddc8
+MSG: bd53baba6657d8db8becae6eabffa52b015a5a05fdd2e070647de96f9ca4dd219fe0da608fa0447f46d17c9a358244cd5408596582ccd3cdd0151d6f0923e63d166837845f273fca7af6c89d8d5246175c2167fbb9c2ebf6a7595491f97a9713b02bdf413e209ab22db7dd2b37fc49436918ccebe5746bc64ddd6dce19ec4558c40e0896e21909280cba06d16b72f31d987685d071db8155e99ebcc6c821d92683fdcee08668a5ed58f839d9edafb9f1459d48de8e1bb6f7ce84da0be411c8f7be1b9a24bc5d0fe3a96b02350750a5cb250b49555a487672bdff3c3f784e3fb63c1c97ba6ae43a10e196f188dcc635e214e29df509e5608a5367aa2800c1a96ad936a9e2a579b8592ec13a359336a62788c3ec55c0ffd6a7d49ecb7c682efa308199f708d79d0e8856366d269fab24eb1a075c96c881cab89708ced279230d3f1f3ee173672283eb8d8a824038f648ac437275d75a0e15f71ce56a8aeb771f07a7f32afc9d612a13bd83b7f93990d38fc3f4f4ab8aa9430c65736eb64b16806e995c1ce9dcf4c5544e7b3d01541c5721bb4be4cf0ae382a0c1b169d8e418defd559442acea14b00d705bcfa78be0756a8f377cbf183bf25906874115d8ce4c3ba874102938a4ea16036d91a42c5f8f188655cacb00c88e3a68508816e5e1c31d27180bbba9518a9630726d7d047dd8d2c0401219e14e6badfc9b95b77a6ace9bea71d1b47c218903a115ad029e7f2039ea23cfd1fa6a44d089fcacb678153d674c0e081764995595cb6894895f08e25b984e3a694c92fc7cbe0ffc4697230bcb0ca408c2d7085c11badeb3e6c0e75e6c498db1bec1ed2a3e2445c32b1913a89500f69e7f23f41d62e5c189f39a056cb9fc68a452023a333f75220cb9b94484acac6bbc671f59ffa072b71a1896a1b306e9dc558da0ec20f373e4c355e0c5eccbbf1350c8c07914892c454defcefb717be34d087aeb244a86ff49a6c470afb36b40fe8b71c505a4ff7af2984c65284938ec0e405231521f4810147dc4e373fdab6647b86f79827502fd087e27f310d6b312363113842155c57a32ba03b6cff965530bd795fc292e241c9b6ca085140032efe746f37d57e958421184b8a4c1a6a1e37d45e077319833068ddcb89d38c75beba1a6e8e4052888ec18162dd6ff0c59a2fd0b47f3119195680ffccddf5f76b35f022aa66bd1ac56f1ae333e9b9d046f0b79a892ecc4f8d2f31e17536c4c62a9b5e063dd2dce37d3d0acb42023eb2f2ea329d3876c2386a02276fff9d308abbadb7274301a6962ecaeeb20bef5e36afffc387ca8e185e562b865b49204c17b2a70119b061c29c0fe9004
+SIG: f6dcc2d27baf16c4f4817f87499157d3ac1f84ed398a5e8b0d50f42edd7385cf06337a0236109970b79ca09d7c9831c876a802799421c2abd07587f5eb66160f
+
+TST: 956
+SK: 7a2efd390124d3fbefc54a577106e74b2d1f5dd504c050d0d359e53c0f5c872b
+PK: efc303d922e88f70f38c1a2b920684ef663034a1b23ab9d69b6ce8ed8706f7f7
+MSG: 238fbe9fb35c725c6c1f329248094bc7da1b273edc7699a7e3452b5788d87867defc40a00590e87580d2c0275df5abcce0e1aaa18290bf93b44e5ad9d760dd21f1aaca383178f9fff9130f73187ba9d31ea3604a1cdf3911e14377a0ce8b44189adaa7aac23b6cdc7a425b7ea745508455704f9ad7a8952718c398b421b6e09cb78cb52a1814ee2e9639ec68d361f0a32041d6e7425b4bb33c70196e2400eb812db8506c9f3245bd988fbc891be20cb0691559fc916b57ff96c9b14489e0993cb739a39da246d01a6ebd07583581f250bf480bc44b2c3391542d595e4d399490195f8445df638f34698f1a96ed27b3533e3eb67e8f865865fa9555ed34df11157641a00e6d60cf623fec1a92b87a15d765185fd9055acb38d75c99db4fce7b0e39fdc3f851daf65c7a33f464816931839fefe8e58d9ab742b861873fd229189e59cd4ce8239fc9543f539d2d296114266ea8c6fd152ac6b342e5d1a557ab35cac51e2d1212ee317c4d26716829e25746df17d2a622c243f3ecbb65f57ab0f4270e3d0668a962502245b94c06df0c5e39e353aa842ea080cf502708b1dda2d001824de458d37762af2cdfd5a6d3f35e08a18e14aa7a642c51e4047e637517846df646d07336fb172434e0883e2b77d8ed1c52c9cc636a56a19e57a5f161b92d1dcbfa496f344ae6d4dfdc9569ade457a49091362e5a0cdd81b3753243fdac30a2d27ea026a5e601441ecd5537a7201bdcb7fd58b240d0229fdd9babf112b5694812250e768d7c0ce6ca565ad06ab8f78a5c9950eef538726f576c4bd2e0755c7f983929372a5fe11c73f9e1fa453ab54b5817aad3596756127d84e3119453e8825bb8460d851f1f7e4a2838a2be786b233504a691db0fa22a5f41fe3fd3c9b538b04f409e091809486b28ad0deda7b38a42cefc48de7d8679c03bf877238511820d0770cc8d7b4172377823a0b99149abb8918bfb66d5abfcd10060b05cb4f239dd4281d93483504b731eaf5add515f1f3c3b52b4e3bdaf976a17b3c9ec61bfc8e77116715804532cf2dbf20b7ba5ead85afb952beec2fccff85ff5072ba4ed6b5438ab1520c6ef4b0b26f12e84aedd65ce5c7bbe6acb6772f593a6b4f81ddd9d502746505047c812a0067afceb8dc9bff30d4087f8d5a375eca605a0622784d8fea278cd1a5241ad4b3f1b914f74f73bc36ee7cc82d96efda63a3b6799730f20656c12356c79069b2be6f9b77be101983118823ea66e7c2098fbc72fc9c039dfe30f2daba13c3bdefb8a780beb5cb1b6c286a6b3ef48fd15c66c045ba29f0970413b988d0ea004ab84c93919f04f9bf8caf58c4eb478f358ef8b68
+SIG: c28b34804805d81f7aef784970670edaa417232bcc67da9b51e9c3d74fc4991bde97a06bd53fa00bb440fd5616cd0de6e9b0d19f2f68bfaf9d4c5172c4e5200a
+
+TST: 957
+SK: ef3648cbe73402ab450cd6ec37e545d0cd2c999ecc1fa381a45c660e18533032
+PK: 52a1a45273872676582cc767339926414cd5d03d980cf629dda2d1a205e9830a
+MSG: 6a93378f880cf0ffdb8e07d683cc352e2a1033c450baa0e8c4e16205fd0c02743b0ea064971d911e494713e6d94a02172ed014d506592ec6c70a9c97855246bf3d26f3cf74f493c1b697a0c414160c341412830985430806a0cb3c8475e7e5a973686c24d5ef1be7d0065096feb52eab260b5c488af09270de6decd33fea8589dd1021baf41e3f255fb8fa1916ebd8531eeb2f886bb3b3b04f9af6b276c35923f10d3a0af1e3f58b0d15aed165045f206f3f430abdff09449097e4b26d00a8f9f1e8f7a19f38588124c328ec43a9cfb43d3b2c6bdf6a3c1a102e0e333de1ac214a6df76dab44ba76bf035273b7ff6238ec82483b2d2d9d54291a72270f88933b786cac051d990b3cf740845fed3a67867d7c7c05674e7cb02ca5b7acdfba3852803a3d56c4d5c13bb1d7723467741eac1f2a7acd3a95f3a51610a486fc53a9851628c557d36d8a4cd37aae9c4174dbbdb6bd885cf40b382b8ded24a4522a278fef76c45319067e55286e7b08c603486e38a0acf47edef848ecbe942eceadb8636c833feb882a51a4595e24f607ca3c9da1b2404ce5c747e06264174d64504331709bef30055a5d695e09537c8f8c1e5a3a5db06599e319dfdb28729665273bf868955ea56427f08bacd777f179b302f3f68d04f3f3883d344955b655ddc6d5282b6d4df1d83630210e699178e11f722e9e5cda672892ae9b23e8169cbb548093b83e643eb499d937d28f3811597b6484102f0c8eb8c8888cdac229aebf89086a6495ac551f3bbdf2d1c9a93ed1d3a861eecd9eb839949bfbe6a4f6e6486ededab5229d532b58976d67512f9f71ae79b4145ca2fa497a165f110717666ca3340bbda8df1f82b8c054cf7654c35690168f96277d41c1c236b68198173c6e2b0a208ef83c02a43e473d90686ace75b5bd321b3f54281327a673cad4d4ad3040d48cf493ea231b3fec06f39932d7f70a38428df8fee4370532ae5fb112059f0a1d4fbe11b5a23bb87635429ed33ad1f6148014cbc160d93ca2592053a6e95378d6cd3f50db52be928e4092fe5d2b7095a9566864adfda59fd5f2fb6254bd5917b70fa14699665a37297c983c1bb9efe1c67b413dd1a8530cbf227297a8bbf93a8a02454e8e461ac212b846a70d5d56d6c3a6e65a03be0580219bddec88d4038911fd9574563f33e0f9e6044688d3dd48fac703869aa09d96efee7d6c68071d9922d5e8ed8dc40f1b798f1c580f7859cb84f1e14b5e74ddea16ad5cbeea4c48fbcffd29531accc0633938e3bcb2212676b61ef901e9c831a41774d8317ef35af76990bd24931fde6d407e22e763cf6a5790b23761908eee609637a2c11059
+SIG: f670792942ec414428475638853c42728e86ba12bbe85948b39134cf6e2bd12813e0d83e51e657c90107ad93a4788aa38313fa962f6767a8f7805bde65ca420d
+
+TST: 958
+SK: 2c8ee7fa9ba28ce7049676087b1163b241118d34cdf534aebe8ba59282a62ac2
+PK: 244c24f5ecb2dd1d1463512221325d73c81ee4d8adb8e01e23345caf9ca5353b
+MSG: 07669a8964f06380d2d4982cb6349de550b38cbc35db2ce572de887f663055736faac7ec07c32df60ee2598422bf37e7cf319ab3c9055608ca0c49757d7688e2013b8244f35404f45ac219497fe924de93a58d0f721aed7825f63b2667077c161eb4dd8bf7ddbdbbc19a9eae5978978d5aeb33a06dde18e612e05bdbcae0161aa2389038026429960dda3aa17e967d10773ca49735d8ecd7409be165c09bb0b509691d591c185c93cdeeae95352316544680523821458caccf528ac0454e4cddc6df0d1ea5f1f5cc1eeee05e19a2ad0b6a49736ed8552336fcfcadbd931b0b8e963be05c8e7037388552512b6823583e4a14384cef5029232d3e0bafe466351b4bb3f567545ab41fa46bffafa877a12b38a27abd64f77fbb4db466ff7f706504141d3add0d7372f16fe3d8c69f6299d93966d624a3070eadb8b49f29fab4844c7528a2a40b66987060695caa66b86718c51049acf4cfad3853edb492e368cbd073968ecaa4a1ee6046b5e826e901f4a808c0427c026fe2f7b2e1968667b53a7d36d702f2ff82c642d34919f8e9aaafe462a3d4f92692deac752be348f54cf089dd9cd051846b04b71931e19e89d125864bfa8948ace0eff33c45110569a0df3753f4c58d8002b5bc38102ec2ecf695fafa8916da9002387e44f96dabf8a982c53c9badbc37bde437f146f77d8f7baf12873196b0c36193af55f542d9968aed8069ab9fbcd6814ec472799ad09c730d41eddeca3b6269d31ab523b59547077376345b05f2ae69b4ee728c863d1bc04e9b7d3d0fcceb359cbd0858597af2d6063e253fae2c3f25034c33ed59edd2782868298681caf564db8d19366f34eae85ba73c1e2389b0dd78a9d2caa0f23c9ad5f6cd9f2c4ad5d58946adb718cb83da58e2fcbb6025bef4660a83e0af55e2030802932f2a896a096079b754c99f7b6423b45a86472e6723ef8896c4324c73d34ad58a4c01b38a97c73be5aa7f74a2fa4d0795af6dbfcd6d4eb442a7e204db4ecb1f8a226bdfa21b6eb171c9e59f1a192e23a76c352b04d8a80233985b77a29c020119ce651c7f4183d0e9c19fe18aa1020c25e4589dee34b901bdaf9ff9450c91af3c1db670b477e0ac2107696c9ec0d31d82647b68ea19499fe34a8e2e7b378dc7e75424e8c45645b0c2818e9f885a1c58415bba1c3f2a77549bdc4680dbcd1650c75d0f452a6b208591df0fa6e181da2abfab444621d5f77c2cd79556467246447a89f0aaacad660c9a925ebafbad43c478a3c850a27e01019d88a5b1dc81b5d2e9f740a028ccb72c1acf897ea5ad89e0f9448888d5b15ce6e42977f7a729155a284d118758ac65f3fbb98deb65
+SIG: ca0bb6c12356555f6e1d8f5c8aa7b5e80cd280e8b1b9ba2ec9550f622f482c3a9ad3be03a4c9dfc10d0112b0189de94bffafd7034114e0e0d42c23f32dc81807
+
+TST: 959
+SK: ddd8e9ff855679896a1397b427db8543abe8bb5dd122e3e302ccfce5fdc63e12
+PK: 5a9a312e892a10b98d0dcdd28db3481c3c28add5ad0b194616da4a3df7660109
+MSG: 5e8feec509350d2ee7955b6f3e278278a4cb48ae72b46589e478be59747df5394a169f19e10db53202a6a52320b63a9a2b723fd31aa2db6d58c57332da3178bcf966c53abda35f12daef9edcf399e4a8c5f83d36f44a17d79846bfc96ce690194c219a29892f0367a7ab3844837879e3818db8d70c4e3fba4d28073464df2085951038fea43281b6b606dc8846b30b0763f2ca82bd5021f9117035a77bcd1075477c5f43214334d4d4cedd18f738d676c7b51a185ffa8d04101186a4952bbd8722f53990b60637041e114aeb8ce7111131d4db3fb4d35d995ad8d6650c0c4ccdce9dcc39db188a68785562740626b3ae3e023f40772ded876a45cbef74a058fd78c1a1ff2c2451e111ac1b4b7ee4c81cd76310d4d298fb3c49f5e6401908a630fa85db7471804fe990847f0f759472f593dcf02e113e15e564d30d5984692da55b0b7f2219c4ac1626511acf194dc7026eb9d367a4a2f1dfb515cb2c08da4fe595c85811120cba2ae7b66e67c91fb8fbcb9d99f13e50fd67464d90c8dcf6935523cf6d13fdd10635b9232b7a61dcec9a2b921061410df1de6a45167fb9f6f109dcc08891f203b274a3b68271b3f35e74f94bdced0c5ff8637173a176e7dacc81f2cdc4fb0d52d1dfa7f27b552fd8d87a1c55d6947fd92ed3253f9594db7df17a7fc6a75ecf4faa4d1e21b676b3727d77fbd43fa7be76bfb58fc309e5675f0a859cc47f37b1bf455932d824e86378de7a7e8c40ced22090044dbbf91c70e528eacdef3785ba3c69a3735af6709cd76aab28a6aca6e844974b10b3fb7b0986007a727c2c8fc95b25f31f146b36acd4c537074920aff247de0f179c13ca57790a6a71d62e23321ccc75b7f3b0afa0d03527c9114a7d4e30c1ace6d7712013dee66699af9c561c44ae6198ed39104e6061ae2c45a9a3c74b5d0fbc4a33e8dfe2a8acc9511ef7e6567133f9fe3554284a75a059a649dd24ec04a57730c6d2e9bf114ea58a8994abdb0c1943241572c79ead043ad1c8caaf5c9da53dd05522febc403354d62fe3ff93882df75fb29458d22e6996c35b69faaef2e0c4163886cb3c3d0f60e150d363d6db59fefc626b1bbb1e052a62414c4b7856d72093432b08f821bc784a5a6b0bc2649c2daa508658980d802291e734abaff06afbf2795e4e354d5221dc4f52cc96d6b8cf1808b1a8208db7daa80ab710c56a8b0e9cb8081dee93f5f015f07664463a3dccff7c8ad19923a97e39045bcc4dce0a73d49c56d5e937bd11e61823401c066206e313e60b47537e34704d7d3515559bb9d0532d028e28a57a879fd617cc61f7f776bd6a008cd4f812378ed37f394bb97e6e756da819
+SIG: df849b7bd29745f8becdddf6c9baf094d7a98cc9338c344eca17fde075fda8d1543299f625982317db7b3c773b64f7d1f28692ac453b81d7ec7b7ec3417ace04
+
+TST: 960
+SK: a886f4d3f34e320ec6d5f4caa863f81477df772eff97e64a37a05f4211d190a8
+PK: e9bc96c81e878110268b55def7ea4007a4ef9f54d383d5fb0f6d4343e1010f38
+MSG: 8b831b877bc3a99f613c89cda698b3759d643822b5a88faf3822ecb2ce98f671d7554321b24b74b4e30a663f7a5570ae917f479bda29894b1a8c028c9d193e4e7ac11916dd8e9c3f0ec0ef80bd27fdfeee80c170c78140b24c15271415acf75c26956a4d4bf99d40e861e9078320d097e1259e5ec17b583a95e52430dd8c008ed8c7dd1de1becdd1e6bfec4bf3347a22dd249f3ac307a2945e9137fa4a8c26c8021077239cb324816a8dad32b01ee34a08903098cb9c4245291b903c9627074095249e782813477032ba32ef041a07486eb4478c57b9d532269a4a47cb5e974df7e01096fbe4f1ccd4e663663487974c62cdd94d77716c8479d79f6b6a7d9c155988cf3902fb697424963ec4ec34ff2a35d742c4455a593bacffc4d9699ba7626c76cb1a616253751887f6ffe2be208c713df1ab636d722ea06c1c03a57f2cec0803866cca3335c28bf41c7def81acb38858dc10e59467208624967e2e22d9e5661bb945f9e0517687dc80f9b8fdecc8a97600b6c219a3b23a90b6d18aaace2c78400ff38c8c05967f544b6a606c71ac199eafd07eb5848df1657efb233fbabae63a05638191a0af7484a1bae1581375672c571e264f604225173a54a38dd62ae7130d05dd291ad12354de86a6e113e83f6d668516157b7967020dc6517d8cf42dd7b1a897fe1b4e04553ce26e299980aa5f7ce0179bf4954f01c2a23654e5e9731e1447347fa43aa8b2cbd6d4b2df93fa54af71e5028a6da8c71ef3c50c0de24dcaee785678e92aafabeb233b011f45c1064965085d2547050f21c652aa533afe918aa0f9bdaa2607b873ccd3dbd1d3a8cc62172ceb43b921ef6b25c06b0992e4df2b91e371b0ef2b3947388daec8ec6f7e3867d1f61072af590154fa619a07f87e02bddc7406314270af1c15e8ee88b39c01be602e4f0b52d9a0724e71eddd7fa9134169c5faab915979eea9362d0f1f9160268162dd38db02fcfb41350aa08e1e1409b2288db1fe4a0e586b5910f4de894bf9974f6a4983013a190e7a736d14ec54c3644a3ee958a5bdfbcb6297aba43af6c72746bb135410507d8fdde73a2a48b746f918bef9ed92c5be62dd5523fe14b16d6384ca46ef59b2185fe933383a2c7a9bf02da9d0fd8b0c7d7bde6b439f9960155e345d685d4dc3c71404d656811923aa3c47d4b09a0baef0a12e75b6439ba8135db15865874222cd7aa428f5ca5ce5140e22ff92697f37fc70b5b4c94d3314e6aa16b2146bca4fc94157951fc49245da53f6c43d1bebd894e31a1349884d711b55dbe778ffa727165cf7cb676435866c2d2cb839745ca40166a2f7cfc77a842468b51a8e76575fc9ddfb5f
+SIG: abf283db1f80c54c583b499dbe20aa04248c1dce121f3911677813ac3e011fd159ad0bf76b1aa7cc7b14d7b550848688252acc7fece90487240c3d399dd34308
+
+TST: 961
+SK: 497e3ebd9e4caa81c5a8973d52f1d23f60c134ca53f62a853a0ac043e51cb517
+PK: 71c0ca7cfa05cafabb143d84ae41de83846f42c77caa7a91a2e348397d07d52f
+MSG: e132f9d67b1729389b828a9fae05a67aa57f0ef7e7d4d1ba244dec8704db969565d1cab809e48fc0abf950bcd4a37d97aeace6da546d4914cb5b86d6ab181d831870c309bca616468f2a34d3dfafcdbb7580b0c5d9ff98e2c54ec803be0d3fda1d4b8c0d7709c89e680b008bf9b8d903b5e934b019705fe0b0c8cfbc3c0967843b0a1fa1b3f162776ebe96b740edd64ad7c35b3fd1a085c99d16f5416782de17358587470dd13b5194f20f23232b2f702f10aafcaa59c7066f24c4c471e42fa86c6b9c5c3e1e8f8365f4dd75acb32fffc053c9af41c6fd2efac30ecf6a2dd0085de9b1d8cdc50b1660a866df7767198bd9c87370615d2bca99f77b84d98d7b24c9c20fd7768fd0380d6b37360340d13598047820dced88a8d42d572937b6efa16921a1b2b2d0eb931673070838e611e6c023290d86fe902f14ac3acd029e3397feb97b17166245ab407a766d2e0904424d33cd3d6e2e62a52c65df7cf004d1415c0b430c1127623dab272a2c2e2b43e02b481be928e89954272832be098b502b8b5643c67482f5de4403032581f08afb0aea48868582607bb39198c1bf13a869b63258a75890b69445ffd34564023e47f8b1884a5e49b7d9425f28d5153013fe3755c6cb114db180e60b3dc4adb36a21428128005a772fb57189345565bbd1759813523bad62855e7928eef5880d3bfff1d0ec65c24592335cda47cfcc5b5fa652b47263225224846a209a3dd7766661fca4ccca59c456fc9cc3e1cf804255aa5f397bab199804336bde29e55c6c377d583f082ce64723739e4f024606f906c110d0a5b610e5fed96dab5f08f4cb3cfc40a35557e1a740b8c7c01f7d3279dd9c4e8764c90bc14f4161db5a37f0989b7bd8035f8bea394ea1d6002ce9c34f1e9c52c6a15d15bc5b25c6c15ab00dfd6a5b1bc917af0b1b05fd10d061b3683d75b5f9effb22ae72085be4f6797b58cb0cab561844121f98bfd9583e0bccb70fad76980a7a73b23c70b3fd02f7757c11a3c21d19e05650ffb82b9e0df8a6735d480156f47949d445851baeaa5ee23814a41b25234fb92cc0df1980d023d51b5cf4c31185c118e3ee3c0c0a46e0a2be6f1d3ae452cbb66f0fd91971342da7b1b996589d94096781552195c433caf19c37f9f14fa0ae15ae0b02b939e402034ff81885939d944e604f474f21524389390fdada06e30d69068c8848cf0a951eab25c4912562944f402468187a23239d33632f29123d49b7de13083398dba97dede12f7959b95247a08fc8e4b5399d1c035c0894cc75ae981c2dd4935413bbeb6853fe04655c77d158c1237b3e0deca5636d69e0dbc5acaf72b60c10bb98ccdd60098a03
+SIG: 12740839b3c9f1ba879896dff6d725e84e0443ef96c349eff94dc4833143e5b419804da9db118a9592b1b1ca48af18f75bef1ca468a1a5c74c7ac813bb2cf306
+
+TST: 962
+SK: 85b4d764169128626fd9c782ad6116229edd77631c2bc9b8ee54b36542c149eb
+PK: 6a09897e629bb43704debb6715c9dea5d892b634306440997c3c9e94be8ab547
+MSG: b2a0493d471c3391f7add1e2cf0bfb32ab05dbcb14f6e4f5f3463aa8d99552f433022046d2f8eb763c0171fcb1e74a049ffeb4b8f0100b8210fce856b2e1a8e739d2f93673ef8f8f40498b3081fa1fd785198c6d370e162d41abe83186f2329783408b9b880d00f81d53100b42d27a261f20cdeed19cc58cb8631281d80db1925310e235e44966309b879bdfc232221433bae5cae46690cb527b6779e11f1bd2a56b59c56ed4d94fdf7aa89dfa9bf20dbfa6a4398b98384517e1dd5d2cd9ce524a47362ef32ac792742a129c9e06130876ab5ad5518eabc5e80b022d8fa13e50d55ded589533e6ea32242c1b3fd7e65f80dee720b6d87dcff3e3df04c802d2e914a87a3629c90bb69e0a6f8bbb5ee505f143c9977375adb065c3e3d391f905fa3c336c9da41e4a2320bcf460976fc7eb1fb6c6a3c395dbd1d28a1b09cdb9ae9f9aaee4d9c566a2ac40add870479faf54ad1b7697710b4eb6f7320244b59757d1eac3d922b7a730b1acf0de9a45d4ac879d21fc616ef3965d74345ed70779eb683280cee25bf3739beb6b4cdfa25d202da13a4a673040d97048658b9205479505d0bee4880a73997c70825a6ec5fd9f952e65fa02225445fc3bdf4adea3d4d22551cbaceb3874798d6a33a6663fe3757081d6243dfd7cd2eebf60a3899fa1f8f6c956a3b183f89b9e7d2ca36448584d53aa8b44e65ad3e527f78723fa6f59224298df31d5e8ada567c8d1b11f3b1314755331c1732dc54a12a4356edda47e3c130b325282a354bfe15c3000d207822931794187e0973ab8ef87bf89c354a035a81f45911223563bfd99f90a75e53d010d8929f4f85a5a5a4f9fcc1c78f0a2fc466f5f1c6522cf62a7be37880796e9b3ca0911ecca3f22c3b24d5d9daa6888f89a8f71a15859359cea468ef238ecf646192783a257addade9047e13edd8bcc1fd4177cb20f88d11998d9c7262d648c2bf66fb227b9b3a9ed46962d2257a420f64bead9e28657b521db2e22165287791f3a1bec4c7822a6cabde5ec770188cb74498a4f08e5a3a7639d240ae3f4fd0353c0dda8ae410b9fa7f43feed13e9f13e6c9410a1d24cdfc2c8e64a15a12f75545b0a575713523d4dfa1a47427a8851ba9acccad78b4ef6a185f5c3b001190dd8f37088a000accf448be8d49371d9da2e1cb5ffe07d41a5c22e94660ac37135ac858cb1769cb66e8269fd53358ecacf5dd92c7eb6186b4d4d6130a732dc10bbb2be32f9b1d6951014a635c12d22f0dc5bd5c2a3f96aec62e7777947eaa022812caced33a5bef9ff8835f880367a37b0b76d2dde396c614e1a4721e000c00f161935b14a738a1b70f6ea54255b7951869646212
+SIG: 4a79c442a4c39c62892617ef8e80b40911c4b9d3ff0a5673b57bdb8454ad736769df27c78a4bf7ad566040e747278b11eb65cf9ec7eba866120a3654f4716e00
+
+TST: 963
+SK: 33d477602f296305a6719ea694c044e90d233c2dea85c46abe1920e88c317849
+PK: ff6feea028ec346dd49107bb713fddbb282ebcd034e2eafc7cdb1c5adf926390
+MSG: cfea07a779f1537e498123c676290573efcc5db70245d93dea5c05726f8713d002ae66c1c9690747ca9230b1629d3662ab73d66b949879164b21a35f40cf3799041908ed6f9229ecb390c5f22234e1c5f26b3ab5ba59e78c64969871b428b78516777555af4e89c6fbc193a94695226c6d329991a11bd580d18956089b58a0e42ca35f6c6d2609ade0d0b619d48925c68cd9d2250dff27cf2f0d44448709b679f35bbdce0f496b0a16ca67eaceec258b1aec91775a3a2ee801b1c9a226a6b001926a057a06306727eedae8c577531df04ac09b5b49bcdeabdeb8ac4e8e82cf1e7af835fc611ca7a684b83526042415b1d6652e8634311e194627eae78d011e6f40f645794e36895a23e1bd84883a393ecfe5a248026aea86447059f7a429368f21c89e0145207978b913c80a22d7caf2673f7c76f6c26cf884412e17d0c255430f502bce74e3a310d17f6f4d485da280ed5b5eea6c49ba748d764814b9e3daf6fcc218c2740ca77018f71344519da82ada31e001924fc77679e3e9ff9fab67dd09a61924c821a1fd999f74dfa3f819adb31d15e5ed8aaa52c1bd7cca266711a74dd62104ef3c2bf737fce6942b348a33c3dfd6d92a724b6d5878421aeb230a533fe21c8b2fd3da596a6180a45c986d7ece4cdc8ad681ead69064bbddfc20f3c52125f83395bed1557f67182b9fe99138af3c356c5e652978dd238b761c742f8158e2314b964208330978b0620a13a16d761d52f06e466a4094b65cd6f26854aed6f9a8c2a884a0d0bf4ee587eeb8b602487239a7e58172c809983a8db1c1fc7ce8c48bc8a6fb812d6aa9e83a3ab4ddf7a8d40d3fe00ea16e04062b8aceb9c99eefa41f4f87447828126d0d9c9f8605e8467c5e4d671d5c6d9fa70d747098d941211223b9bcf261938d6704a32d22c61e30f3570a1f5d0998b4791080882aa5623167b63a23f340f0e7c6f9a830a75b74631fa5b57afdb1e6bc22699bb03156675d598353a5d1b55897e4c11061dd145f23e8537c632f75c10df05b25547238574017fe7b64b8e99869157fee35f7ad7e63e99593302929503a96768023b4125ad749dff4b992ee5c2b4f3ada4889e4ae62ec15d2db5969d730db307547f638c3185032b12f75fbb317e47df7b9292ae9e76a2c0a06fcad108cdd235f6e38d967b6379511ff6965c22f2c6680a12b0304eb2b296c99a76c2729d98e0a7824b67f3fe842d6f6ab273e894845b32dc6ddfc7a220f76bd965c69858183c8f357395fc57dc829defaacb5603a757868d5e562f9781ee39e0e94688ad3545b32dd7366b6b047e8d1d3d565997b236e7f7596c5f8d7c1c11bcf4a244620cbd21d559a7c9b3f
+SIG: caa2879895d4f620b9eb5fed22b4562eeb1ad63822968f76ad91076b166c05ee20864d98bbbc6e79dd0362cacf7a21b4cfc230d6355d43120cfffb948b8f6c0e
+
+TST: 964
+SK: 7074568611a66dfca8307cae608bb26995844df435e5300e5b4d7291cc22907f
+PK: ddabddd15eaf83115ddd065d7e220b1efc262a61c52e914347442bde6d002506
+MSG: 6c137423eac790b8e8e418b290e0579c7b86b14aed818de8ce53cea3f340a1a95391f984968f2b4229282a8161c09ab149cdacd66970b4013f52e5e68ea8c9db685b2c53073500e5b35e29ea0ba1f4d159a558d361b06516836cf7b9ea501fa0506b985f036a82d9e084489d3bfed34093e2d6d9edf55785ed35a90ce56c761686cc3ea1a2c76ada5ec8c145d818b047cc516eec5d2d6a93a55592d892e3d5cd10c250c04b049b38fc7ec0f39aba15824007336c2b0f7f81d64d5ca3e29d6fda4c23d9ba65d9fe3cb4e03913697287b46a0b1fccd2624e397ae95c5254bcd88d2c7c8f70fdc8173f64c1de32281ab4184693b48a349e6782bc8992b43c7de7cb9d33929bf95306c2af7e938d8486b386f9fd3f0f7161e0e6862d4f9281446865a1c9be2460efbc20151b06e79d014617d0300e671d48767458596625b76dffc558aa9b40612196ec827e1c6fff518fb7ad4bf8c46fcb278885aa491b77a28995cfb9d79640aad174c6df43938e3f1385205c54595b33dede50143746a1705e7e0b69af4a26c3b76515051892b15ca6e48c3d91fbc75e8fe4a0fe8ed2c26c1073beb70ea38d0927029278406755ae6e11da378653649515e0085b5ea7db3249208e33a6c8b6ae8cd80c9bd6b983e73e9b91dbec091fae995f8032427edec02cad9055eb8b7dbcfa80d4f64f5727a152f11c47e52d753a57b6e5fddf774cea4da910026819c41e32b4f199727e23c54ab5d70142b854a27b04e64cf44af2a8995e1200bd117c7a1674edef59bc53f73adaf638e0773b85b56334aff6e11743e3a3d3614aa8a375b3781ec814cc08e71efa7818519cb24af82c331dfd6ac78ec17fd7174b61021e8cf901a2aaa6adbc902a916b2a2f4f79e551501fbf01df6b8518504c1e94646938bed1a8509c2a38fb6a798a7858f409b0f2fb9b3f4817e568c52d9abfe2168cc3650fc43e0f9975fe29e33aed1a7bf30d8631150790650a3cb78c368f1aea9ac60c5eeb969a45f84aa37366a83977190f41ae421e0c46fda3fa01b926fcef8224fda36df4f8a87701fe79fe0628ef0cc02df2bd783207c7db87119a0369fe16eeb38fdc9fb35d9e195fe14f8c1038208ab97700af79f2e2e05496830207c7da8dbe8e9bb73bc471a43f1be650fa92819aeb5dc7eed7eed8171270d219257d19610b89d2d62d3f5b648e139eedf1ff74be01a5ef1d95f812922601ee92515157c4ecadfa3eef9f2a677c003ca4ab9b2c45472ce55e18f40a21fe1b0d45b50b50c52a0b1a5d7c37d8ebc15e020584d9edd7b56505f82078e0f899389135014c86d1e2ed49f9cd319076943553a312ae05ab333526e136714f09a402b3c8
+SIG: 7f653134c0b90f44a489f0b05fc40707ad9f1398f340b447a3c9861f511c9f1568803b7684a04a898c45154dd486bd50758998e126439378b3f59ff367492a0a
+
+TST: 965
+SK: 7d7ca8e8d3b84344a5e4dea08b338d8faa5ffc119ce566ef656f0f4584775b21
+PK: 0bde34b746d2c5490853064d48c6b4c1cbbc3ee7beff5e8f684c120f315d7e4e
+MSG: 0b727075345d619f5cdc7fc4c43cdc19105811d95d069f81c0a62fe1e1178cf1c35db05e2de87d11ae1a6f53ef38b39bf4ed8fbf56ef017a1d3c15b64fe4b2610bf69bd19ac7afd46a2b87b488b6c78ad456811c1dd6bd4a6b5da698739fd1a14ceb9f27f124b69f6bd16de5537aad80681c5633580394da3b84e9b7a55ebab8522d2d6bf1aa4e7b159cbf4e20b50bfe9c711aa047119f1dad8749260b87639e9c141def62026a990373dcfd99f77b0f5ea6adfd8f594b9ce41064a5ed307bf2d8d17370498ad7f45f9c4dd26c420f450f53623bb6d7f3f46a149d8f135bc2913310fb8f9043d099278bbeba39179fa367b01673e1c953effd2caea7311c47c0372744095b1c8f90eef5f1929db1996cd584f615d56fae3aecac3ee88bd0b296f449cc2713c52da695248faa8e389b05a0bcac69dce9719723194f433b0297eb0859019f141a207ce8ccb59882caa6e18f0b43bdddb90a0a85ffd577d6394a1d80489410f92afb85ba506aa9f3f427445d21224b9cb046c05f1bacd7b749fb7b1024d092e4ee4b30a46edf718470c99491c68f4879d62bfce7046d8138cbb9e7212999a4498b455fc90ac283e935de04df6fc999e4434be11063d6e4ee9e096a87bc716d2c819916c37a4e6298c49945366ec3f500720b06dc99d3d8ac303e6c264e28a7c2d419ec622a97a711544fb1f4735b11f8bb1d7e2c816a156287b4cc0c65aaa280b837737f0a84e36de2df2fc3a50df980918fb9e5834b42ac0e0c7278d7fe8db4dbdeca0141d5fef5dc6151f87b8634c241a8fa0a82717899773ae89f537890b9155a7a05bce47866ec2028a47898d485823a2e992319680eb699b0dd5358f546fc537c73d3a4b223a0941518b6d1e66b27676c1b1fc76a08320524a72e297fce17aa80d8ea7b388a55168e7dadb836e9dee707ed25c0ee4db25bee3c485b39649204efaf2820b2736368fc773ce090c385378002c471b094795cb266d39eb7580d701be4c8916f6b38bfe25fdf36d6c4adafa9ae9864c57bb737b49506ed38d62de60cc0599ec6bb1acf24b1d37d60efdeb7d942c53603a2f0476e9512c938b28d495a6f26a907c396b841aedd8e14ac447b495df1f676daccd5a740c042f5772b7db17f4f1a3a1c8e7c488370e736b51e690fd2ddcb5aa61957a7c7975acb2dcb915d074d744279ea1c4169f868873ac5c20890162c1df9656419975a43d3198e18c309a1eb7c1d87873fb15c6da47f548a01f69bdab9c39ef00d418a6f619dd73d7db45cbb6ad225a2de787ba777bc73d28fc304f10009f4022c2cf84de008d70fcdc8ba7f107c369859e9c90ca8a393b553f26605ffd7230c921490700f
+SIG: d0c3e248a8cb2ddc7e9f21c9c5b009f70ea29da6897cd92c260f047ed68aa1c8b9657f9d826e88f4a512c5003be6406880741263ae7ce6860efe73ad54d48204
+
+TST: 966
+SK: d21fdd7b10e54a8b6be95a0224ad70664dd92112e2683a4fd279c407db3871bb
+PK: f89c272e7d1cc93d69f694dec9cce05ac247734504829c56997413c8958b9330
+MSG: b8644adbef9c7cab9120acedc8e75c433d036ffae0f955be6a488f1f427a68a8902d026e63dd6c9bf9d97de786b31dd4f4c9a4f8a622f1ffc84da6967ca77433c398f4d3f1c4434989b7ac9d0f3b1be0c8b352824f4e7a083f342ec1be1da8fb755242a654880ef298f05979ff026ddcc044860e6757a29cfaa222a3597e38f1779962a41a4c8ce6a65b878199b4d80f4a0390cac19c226eea4b6036e57ad830ecfc00693e2613d3edf465fc8c4fa293fd8cfc36dc8e37bcebabec0349ebd884e1b28bce824e0d55b6d015383801668b34f5ba723d2ac0a264fab2c728608f162de01179259be2ccb0815002fded8e0d78b02807313e910eb3a7337c534e846f9ee155426e4aef643661b0edb44596fddcd0b3e814c137817a422baa40c9053d0386c6ecdb589052594742677c48dcfc8cd4a93667ed4d87646001eda079e8b99d52ba21c5ec5669fedf6f40447a7ff8901db0ef1847d3cacf0198a2f3bd7bcf2dd811a097fc5e5188b03fdf54e517637a14501000d0d35516caf0699402b48f8d8cc3afb17a56132d08237035a0c95490bfe5d7b7fb40178f281e4d872e47a0e955ce9736f3c333a6adf50ad31994eb9f45327facc8c5d113fad4713fe7f198010d42046bbfe68b0daa79dcb8755929be92f9caa150dfbde3fc9e392b2b701c3021c240e4679de41124b1888e5db5a83d05ceaf49eb440dc45026d450bc984b8d6f02850ecb570eee0a3819b12bc26367b5b98e1b141c9b0a9690ea4a3700dad12395f975d11cd77f96368831f21f4e968cc5ba9ef82474038bc7aa26122d218b743041506aebbd1f987959fd160d6eb7d58d4f576f8c0ca8af868e39b5ea87203937e0308acbeae91e10607e44e8ab495bc01dd573fbadc94479ff92082c7bb7513479c70f0407769025d34d72140c25d821f034a39851a93c623b71c9400e942639f28bbd032e1d8d3c059f7c2cd31d7476462d2776035d07880202dbfe9e07d154622d7ac6175a5afa79fed4dcc13712620c41994e11d924308fb2ff3a1eda44c761bc736f345122f02a40ae6f7dbd03d9fe96ee3d7a3b4a5eefbfcc56dc42ef27bd8085176038b9ebae63aa75035275ec34e4185739d636246770acccc6dc620e2fc9156fa9483e0d9cae0e8c463948a3d97ae8dda5966c88f07093292cce22bbda062baafa7fe84d0ba2d2dd295b23458bcaeb2ef742a2ed1c834483cd709385afeadcbc0a9c6a4f387babf7e3dc36c810db209beb66c8666404c661dfe9d32c4c08afc6f3b1257d6484a755f5ac701eb13f87763fee330ffa0422cd80a92038c6f45292bdee5f89e94c7a652197fc1906b48258372449b1081c6b97134c43c89ee2
+SIG: 6d69e83b3e7ed55a85f9fc9d2519da0b0a1eb4daaee991a6651f5c89190c0de72373cd989d46be1367f9daf1b92fed3b52bba54a1e4cca5bc8726ed07f302501
+
+TST: 967
+SK: d336fd8408196d22fb698eb25b7654fda46f5de4c9b4d04950c398b59a44290a
+PK: f3cd96347cea63e500a4c92c3bf215662dd0400784dbf8b595dd3d395f90cc12
+MSG: fb49c19bc4444c28eb2625f31d996d5e36c57fa6fdd772e67b7199cec67eda5451712df7a69dbbd56e7c398796b2001def651c4b9c05ee31d95679535c812a37d31ddb3073199cd704ff7ca2981f7b9c927a7f7d776fb6f609f727e6ea709ce7f43a60793504169a8905d9b23109f0d867966aa3e300c7e11ddedb9cc117b904f62927e48e4d73fe1a6ceccc4ceb08e64ab55f25c98216cec937608ad793146998f14c2985e6c2910df7b1388f9dd863f1e4d7d1621479b8512cdb34e673eb02a48934e39c2d18d70f966d676a2bd75db543d25c5dcdc3ef3b8bc8201848c30961e915d968bdc31946b0d18ede7cb0166dbe1ffeff9439c9c3404af6016c73edeb253d93f562a1a6cdd57898a9b3422587d5f56af3d06b3f6c25751f44460fb3299656dc11227ef4837aabddee400fa53f69e5ced053c76dcecdf0adc9ef80f4b330542ff1fa2df0b8d43cd1c311b1b9955c632c8e5f0491931c04de434df8f7a394e5fef016db2eb7c87b2ac7a4a73043bd7f98ad0a4d453abfb0be8be4cb145742aa56aa5ef2dff12230a510e3b7f82f7847700eeea5905b0289696c4c142bf34bcf81a962d75b8d091055733779335b7fd47a20d17c948ab732947832674371e22e711134f5c919792357f79bf70c4470787528434fc0b4ca093ee92543420d1ca81124f5585317e250821a4f3d8ce0f919de9fbf0127087e676903f6cb39025bcc73a0762954b72e66a6be9b96c97b6f6030bf5ca0bc2727a9a179cf9d9405f3fe18f3492389079a5b65bcb13a0d5ef41c2cd97e702cee4a2feb1e6702bd4c63fe0a4ae994c4287a837bc3f64c2d898857cdb32acd4bd133676e51f77bc7110e3ce52d9204fd2691a6d37078f68e7bcef30fc9c483985822b661119238e40f9cfdcabef2d7b16b059ab24adc05003712bbb128096e37f91bc4c5c81508be27fa0b84940be36bced2e65cd36b39fbdc5ea68614159228ca65c5d8407baf663b528e7d87734c7bc77dc8431a1dd6873cfddfc3e757d9ad1fedd3c798f1fe60e715ee48a6bcbb13b616a89a38e336489d3d6ccb726914112a1bc5d977c9b2a3fac107ad094b038ab75468263c34bda817c056e07a6c56697cb64a0b1f966f6de0bb1c0a71c8a5fe133ba2036d24daccad3fa03b39cd27f832752751055a8155913d040f51dae78d71946ca04d83c7c894c280aaec285543e5fd5e327accca9abef156a13b9571446bd8007ff92dbc0fbaf23a9441b53c1cd740c34c282929101ad2ea8b85d70052991b774e92ff75cc85113e0900b51b863e1f2adaab2dbcf46af479ea248ec2889afbfe737408393a2b1b3301f65c1fac8b676795ab5bf447f05e0daf6776
+SIG: af7e2df7529fd18d1b21b8fd4c0681505918e2511434fe4e4954e743c1cfa45e4109d36c3eecf2e25d209b9b5d25f7cbc380296d647752e30d3bea3b929b0903
+
+TST: 968
+SK: 6573227841f6f92831146c44c0e480cdf544bb876552cc5f9d42f15bdcc044b8
+PK: 192257a54ce5d04c19439fdc9ede18ec856e29870e24d3731fe2224799949b7e
+MSG: 6e7c6b122ab36bd135f69e2b85e7fccefb072c12cf088a3229d876eff532389f0577116f7af29f1195e3828839381380467178b229c5a18d7c4943ec970dd18bce723bd0ca91ffa95563546a324fe0b9bf6c0455d4276039e8d291fc7276aa55a1cd3ea05282654a7f9700adcbc78077c5dd0fc86eced48f4a60ccb76bfb8b4562bac22a02d19e4489394ab9719fc144f5db2ef039b37f3b51d1d657a0cf835d71f1a4af01eb9fd885c604a624cbe910bfde093ad3f0cbfd9a48307329d44234bd01191d56e522d72b54e1fe4733da3aec6827eab3554898e03e577b4e7b9dd3f308e616808d0294499f2886295e54c360199ca83a83ff46195ea3c484a66838d51acbe9611eee036ae281c6793cbd451f9271fb5d25ea7c1899ab5d43ed8b9d067bc56d8d4a15f1dab8d8d95d1b17af64cb18c1147551147addcbdd53fbccd9026f855547131bee95071639f649f2d035a25a3e42e38e22bbf038106ce8bc4ad6768ab92cd57afacd04ee55cf0714b768952dac240b1e9b2835ecf7b0d6c407c82524a923b9f54d1b8f12564a872144efad3f3a7d2397cd1217dc5a9c96e43b2960a8425e97e07a02b0dac90f346b91a346a23ed2bb7fe6919c22dff03f62da7dba176e8ddb22f3f3a668891d3f4e69548d0ac4e71e6d28ed5a67ab5ac611d460b67a201f4f56a5003ca7a7d1cd1db6c10075b09227cb8c5dc1666f8be710b4b7bc2b95ae60da4f64179a50d2f88744361591671d36b7296315f6996439ad79821da8e772dfbf55a90d5d52ef7d76b35ffebd42e3525f4530c54a0f23b4d07c5f5974470e89404d176eeff9ef2333619691c59b7aadd42c296b1d0d328d9a3bd59a54bba93a0c1f1d62418c2190c38174b6abea02db66e818320ec4b8bac1c12f18f30dade27e63c58f9e7caf4bf69b265a2f9d91800861acf479e65ec17e680577e058cb16c109bcf9b2909fce3361a2c2685c10be8540a1222db5ecf0cc4d53a4214b7bf6248adc3a861e34841a3779c46046c5364f1ea91a78c9700d462ecfaae36ba760c1bd6a237c961edf4022cedefe5e937bbed7051ae61b96d08b0487ce0568ff0d32740bbd49ad0db86e09102ab21a915616e9dfddc81ebfb36c903e07a40cd2dd119ff4a50b93fc6fdfc0f36e59e0148fcff3fe8e2cd6d30a9e4b8f015567d118b6274e1ed75b22e44ca9d9dbfc160742cfac581e1a0bf5ff3326bc5f7896b9ca05a811d55e97c834d37a6495cc26cf442bd2d90129895e9cc0ed01e2155293f47a07ab5880c6ca29ed44d9ccbcaada7f3eb60402181488654e04911578b1aa9cdd4b86b0dd2450df3a43081e4110ab58de763924d3c89152e99293e638f9acd8d7
+SIG: 538eace493de53384b1e985bb907c094f8168430dab14d37791be6e78ff3f5a306ec70dcac86d993a4c1f75850786d795f022b79be6a547769e41569c5a9a30a
+
+TST: 969
+SK: a63c1f54b2ca058fed2ee2504b983ff33d570a9baba583c086cefe19f43ec49d
+PK: 329b866bca4194297fc1ad5a0eba0df956699c74ab7da5fa5462bd0661471020
+MSG: 791b86fd587713478f9234ff30cefc123cd7c3eb125fa74e4c6db64e7844f7c85b1686e71ed08d1a6a04e0ebbdff4ab160c976c8ab9b505f6a7eb0a18427e999a8828df10684f8c75b6a6b0a64c0afa4bb22bed1cb9325359cac3b8c508d98bcb0ebcd748dc132f1d6a360a4450d1292a1fefc4e57e4107a223f421e7d14a384b85c18844d0b9eed2ecb81bb74e8a12652d98505795a013116a7076ccb5493d6a711f7637e97a780e74da1b39b15cc7bbde2e6c4d0d3e8300597c836e80bcb8d8081d974e02432eac88368211d3aaae89a14417108e1ff6737083849c625b40d631f6c8357220c7f37380b3b2cc5d0e2df6b4d1196579dbc57b6c9ea0d41f4fa0e556f943c9448ef42fc78df5996648ce2f3de04d8a663f967f3d933d4f65357ab29ba5b6405fb162972578ddbb2367bed143c854c1088de921d79f5a92a854837eb7702e1ba925c6eac23d134ba1bafc5d46de2a1942c7f366f701b0afabb75cb1d808e1a1e4e3ae5de88e8e9989757458bddd8a806c110cc3a733d1d4ac58a405c4d81134fbc24ccde7d5afe420f9f1785f0a5020fafbb2261222508aa0528b7b48b567200958425efcb42934a880b133444bb109f2a954cfa35a2d17cb05ee3f16d06b321a15f91339abeda243ad6c0919fac51e907e053fdeed1cf03003734137793941b8adf9ab6af819c245d6d56f16964c8a75b0756a8cb0ca8c12ac6e6b3942eebec2f868835f81b109db498a4ca2e021fa765608d23d803dedc9e51453fc1d2a6a38a4aab257c0fe7d67d32a541e014b60e1013a92c1b3ad9e6f11be293b246f9a0c6440b0b54fee75fed2fb75cc91ecb32738c495831586a11242d87dcb4883edf6757a50b18843759b98dd0cef4a3fe10d76370ecda8c83fab87eee2656c5f261c340ea91a560d0e2c64289267f0036ba35944800a5a0aef3f1df839a724e181d79b8a3c16f65ae27953c4aae8ccd30ff5acc4b31e4765c68fb38319f10acf89247b5a39b3b08a191754a24aca9596a1f8a70b6e4f03a2004a9086ff6ed07652a926e1e2df7bdccd5bec16e5c4e968364a09abf9ded93df5fca0bcca5c812976e5cfb3c3493fc175d1d92ee8d1c98fb3382b3ab90c5c0e4bdf6a3ac94767b68d47e6b9c244265e3b1ab0623a8f0100273f2c607de89612c72d39be4c0b4d77a3c61368df40b3608652989d1e19c0aaf0e3c253e562c6409fe6448929b33753de162e6de5bd466a5114fc0e5f57102755e29544f03b28d4f78de9a024dd4c4e8c3c2d44115a7ae15edb4f558aa7dba6426e7e372c54f7940bd7714467f8c3a1add3c640189c31660d8cc01d3c5382e42abc104c723f948a804ca853047b6b87b5b6ef4
+SIG: 283359be41290a51e6a7c5d5725ca4ea0a68f14aca14b0f02566dee21f490da3c7e95f7ab739bc35a7f4f232e971aa157657a633eba0e72dc97af32cdb928702
+
+TST: 970
+SK: 5b67a6d7c650dd92ddd036ce7a305bc959a497c5e515a68493035cb3850ee03d
+PK: 4c6fc1640505fb46669f93048f8ef557099f3fd92a53064b163363a31b7f00aa
+MSG: 62ccde31772c57e4853aaf2a8181fdb53fb82790ea6501bfc8f5d4ae8dbd52de42ce2e8961ac1731f4bc085fb561ef09a2442970b6297901aeaa2ee555b7d5e3951c7c351239ddee95ff54f924da95cae7b15ba6a9a1337b8ce4921ed913cd791c1c6941080e548f3c36e845acbfd8d8ce35e2fdc2a2ad6c7e2461bfcbf1aabc55cf0fae428885be5e86533308c9756805219abd7ffc1657b6f4632920a0c10e0e363319d900fcd61e7ddbcd6e762a7db92480c363b2c0640c6bf32d690dd829d8405fa66e4783ebe1cbde9547954a90baad9f774e94549abbff2c1f5caec2bfd28e415d36429d58518c3e17e8699e1989d47b8d627ef9ab4d1e7d120b372c2141304f7fabd0265b8be41f5467f4de9e65c125ee1f27a289c4f7c9a1fbf25bfc2f8d308e7ff52191cb7644c6af204522f2ac87b5f40525fd43d308c8dbc6a861d25db23ee276678a1b6e8e91283be02470482ed6cc9f6e396351d11b1c7e22329c091fe7d368f60653f93b0f6a3f712c20f9d2d8a9a0819872f0c71d7b1c0bc1683a152b484bc21cf556093ab4c0ac16d322ff0bf452e5581e1e7241673884023c7d6e17e2de8059f60e4c18e13bd55fcfee623fd0469c0d0911611d099a257020f2f31bf5078e6e65a135d5bf407620236d6cc759310fa728ff8bb5ec56abbe1a3cd15153f892d958d30d162d01ee665f5b562781d8dcf8428059e5fd225ad78a99ea760fe5d9ee8219c95acb18d05622e10a9b6c67f6d4f6ed11635c5e2e0f85dd5d3cbda65aa423d594a80b40427bc321e0eef9afd2bc8746ab7399ff6d0e1287b661ddc4062d072018f4c10e86cfaed72d9e686ed09d5255d360e3eea2c29b9eaea05fc78c8cdb8c9d4afc7adc6d4aa067b7abfb0a4e940a77580ec206456cb9e9f95f6d565d536e535a167ede8e20ec36081e2fc55aefaf24d227fffe5e6cb03093f443b4c51655d91ca6f275959d1a802adeab44701b31e8b0fd0222c499966c72d1020ad9370e2802be04c9933f6b774f6e8c69fc0bfd315939a127b4e06d0f6f5ede671ce11612126b5187b53329b0a9cb7da3b1ccd67b8c07bab99a662df8ce851f502fc4e1ed1632b6ba555544018f7527e362efc7e3b2ba6f75a1254f428b3b7e0bea69549e7f9c736275550080aee3af5914e3a34be656c77f6b29420e5433f3dff3811f3528208e9d850aa3c29b0f778a2427d5fde30732dfe50443a9c1ad55c72a08ab26ffaf8efb90bcafd3726b00c005c8c0f0dbf2a1353086721e446545b813441194a755fd26b963afd977278d1b10f09001c7ed975403c15cbe7f992ab07b8470c939f866f420f77db779af839700329e0777a6116365d76c36d09d860472a5
+SIG: 0f073c9a586f6f5e08389a2a5e1808e270f0edb6af104496f93757623fea53133a731c445ac23578cd56a3883c08958668631fedf1446ce34f857f90822ba80a
+
+TST: 971
+SK: 2631c8c34d2948ddd5996b4149cefd238ea7452ec22e246124dfa279ccc27db8
+PK: c3906786ffb8a7c27c44c2447f9dde7d666dfe588cfc54f2d25040512a371bc1
+MSG: 6f9bdce1443f2856d4a2f22782835012b7818a0e020dbcc22a821658305f134234d14cea636100ed896c2a8fb0e87048ec6f8b31484f78eb171045add72c85710ec9f9b5d43623417b5653be86e7fbf8b4ff91110a808cb41acf66d436e89a737faea4eff3544960f114b833b0b4ebc2c14070b0bfb7b0057eebb842bd1c1ed458ad3428f8f72a1d1db3c4cb4797a399d47a1e6db74dcb2ee24ae81585cf66ef6d9bd223f0f54bc8c1cec1bb4460bef4ffd32ee805c3ca5ee976ff9c14559f8d756662a2bc19e4c5985406a07305c9950d866c9a79a3e5f6c5969753a170e0fc4cc09c6d87a12b44cdf3be1623159e90cab7a8a3e6f01f268595b021b1ef7d00769477270d5584c912e22a367438277f59df20c5620dd5beaa9bb60bee47f4af527d892957b2d12b678b5279a3f83264654c0a0f8d21e709668f30fb6e68f047d0d9a7c2ae9a28f7cb9dbf18f63fc1661f07d310e540c77631f5bdac5824685d7c9aba0fe1d09407a9662ef18eb3e28fd1e8bc892657bc38243a2e6453bdaeabb2791fc5489521295457ad04180ca871f6318792bd15fd1800ce59dd3ecc7e0b72979267d8183e804fdd45daad84fc4cafeb561ea8d6a74a7cde722d96253ab3e75f0adde02a61fd5e1f59cb1f5f1b2e052643589a9e4be4dd6ee64538cb0b109a113f30a58b3565624043662abe17f60e31e89c36c995e00ae07f56a9118a31aec24ad544bc965811218df827c1730bb904bb79b68613f6c994679b6990d775b5cb32db97194bd81019bea41f3a7eef501bf8491b0ea859388452e3ecbe16aa7d5691510a6606c493e4c293961bf40b4cd300d9d22ea1a7724c078b8bab1fd16504e989b136d9251ac9f1ed94a5e9acbd9c04f8058afe03049aed8ba29fa2e8fb44f8e8c04e8727f399e735e6c1496a91a9b2cd2ab02d43b285e9d7610293b6749df1044b30e2da99a564429a23e68c96fce92b08a00b7b742ba97a62ee58776d7dd565a490071d4b19dc648e03329cc5c825d387eba49e2eff6c4341865c464f13f1beb1827a7f268cc15a982480bf084fe3652c1b0e0b4ad26255859abf1c8a7f9b3bef098a9407fdea0a539eb008fdd749fa0186cc0169d9d9e68fe5e54cac32ce57b5c84c2d805eca39c2dbbdd2e02f7d228826712ff4a61411ca0aeb6f01a1f80ef29eeb071a43222d9497184bd85d9e44b166be97cfd2a732af4a233463d3ab543a7a3c7aec555656568840f4dfea217f6553aa98af324c12b2c3214ee76eec700670af68c8c1f36946efd7ff0933e5453f128e9715fdb3344ac10c4bb7ec8f10ddf5db71f1cf0efe40f75e5b6334ef8cf8429b3291e6e4ce379c178affcbc61030eb896d744d
+SIG: 0adc6fa40ffb81f6ef4e4187554917775cf465e7b5e857f2e1e7f400977106d2377ebc76abb1db924c64867e3c6fe38c0b4fcb1d0f9468e8fb235029a81ce604
+
+TST: 972
+SK: 39769a66f0ca1290fda14375b35c663f6a4b2ab3607179abd99063e2efa2c6a8
+PK: f9fd4c191f38f12190d3285e20c6cee54cfd6ff315300a4efdc8a90e80af4083
+MSG: ff4d8987e3fa36012b7586736b793d659754698cd12b65e5ba9d758cac1649288d20224377283ea5425dec10ab9917d18cd13d1bdf4a769f37044c84faa2a449c689e004c14e005c49da4106ff75ce1303361c6e3e34ccfee75ee9c31cbd06a4bcdbb42fd649be4dfcd664006d6a5f61077c04a6a81db36be86ba42c2951f051aeda64acea496cb924982b9f7d234ac9723fef98a8e12755e326a52fbe35851f411eeb867606d45b513f54526391c554635c180b8fd0ee451afc96e4efd360b61e6baf03dd6d19ba515c31ec1cdd3affffdb27354e3e6b56e9e1a1a1b7d4b57d9d7689bb2fea6c8d3f9ce0df2d9ee919c4230a1f20b85dfefe1ea3d7f77db470e4022429ef609b0ff44946440acb44cd13445bcfa3f20503c26c2fb663c89065fb9334a603eb9ab7152e62629233c44cb00e77716d9b72c84fd1b340634ff1cea347501576100ecb0fd1bb76ae0dff1c2b0948eb71ee2cc31e79d3015d72dbee224a980e0f95a69f793da83a2daa56efe57b2f8ceaac9e55f443ca9e732b48c75fac21c36fa77273c3f34835ffd83c96f00ac6e86cffed08153646c1cea223da9ca360cab97e03b2b6c8fba7c195a39ae52eb2ee864300ae56a10f547f99a3169872249f97774b1798935536f2f5f011ce57613a94fcb7e7286a6d49c10fd929d7671cbb8cf17dfcad4b2485c3d8fd79128721e55d84808763c2afa9c55e3b0cd7bf2f0a66b5e467bec5ee89ad570b60f188b3f7b4a511ff859312ded078d8d0091134fd49bc792d2d7d60b304941c7f23206f99e863b1e2d8c9ecffd2ff0a3a3c754985615a9a92edcead00fe0e05493b198d1f7c90088446bba46038a71f32653b5912b24f43137748b75aec2c15fe4bf5a6f86b8a6cdd9c7447f2ebb0f43b01ca1523e0d496240006ad7ffffafe0df5754b342caff3555d72a27d0b92ca1667665cec43bfb583077a9c1741fa492ce3dc2c7529cded81b8281a3f375948b8a7ced096b2facc25e39029e221b66a53d3979e1f405fd88afc06ec6e4309dc85e69d6ef2b4b49266164a9d9d1c31ee3921127b13381bfb740dd38dc1c7315921f9c2fe58b61b631a7d9fde2dd8a4be3ded0490ae3b8376791955c1c4b4fed00b9f4c38ab7350fc2e37a3150c18162b1faf0337894bc23e74f595e4be33466deab35458be97b4f7565897f06852f71c60fef9101d726b72e0102a97b2ca5211e3806834b0ac1a7df87c2a078df263ef8ba457dc891b7f2e627811ab622b9946f8c6b731f24078d17b06b200c3447f8032aa3e7a243ee422dda2e652fd75713afbce8a59ef8536653a48dcf42a70e7621f9b2802409be1c1a61f32e36789a5c5055e1a8268e9dc438c2e1527
+SIG: 1442dea2807e031159ec6a412d8e07bb3e299308090f218fa7c10a9c5068ef9b64ef11ca9fb92be1d0216b99318ff0f03cb871cd7dd63a38ae1702313e5b250c
+
+TST: 973
+SK: 0c808b066f0c8e8dbb1c23d6c2cedd0be866d8425f241a9285700ea54536cf6d
+PK: 44ee72900450c56ab21f2686d29525d0663e0bdd87725beac5d68baceb69f1d2
+MSG: c945714100581f4e24da11fc0f6c6d0210433f9777525124c55ee072d85d798b705f9d31c8f977db6edfb7a65c78ad2d7d31d6b7b5be40ff1178d303b6839bb0c63210c1d338c103afa0d453eca1bca277d930778ad50802272f03dbe2184fc31ef8ea6abe216997199f7c1b337737968907272aa51bd49c07389c95468cef4fd99ae78ca4542a2bbc0e8aa95214ad1cfff9d5085a434394473b84b74be9bf2f0202ad1ee4616604ca1dd75f4a195342ebbf8fc59f3f79616554dc7bfdd556be437221c10bfad39e119e06045be5fed683d3534fb6cfed33891c96f9c330f28b684f8fbad47c01418eab6ceecc2ed777f4c218a27ac22582392315c53aa7309ec54c6175236e4424dc978465ab628d9544b0be84103eb56f1bafe5e5eaed04c98bfe2e8a2418c6c52a61eace85236b66c7b3b8707ed55641dd9d5da97c99c11cbeb9aa2db147820dc724800a9d80f505fa5af20921cad2435683bb4fc60bddd475f863e2f5950d236399d8d75b404b394a546737f93a62408700b3ab3c1e922b1a859a2915c2d35368815cd45b85b2ac083121ff000f050dcdf415e5275a5c42dae3b15400f3ddaf9339f20a1261a88cd90205639763211152df414a9a6a6218f56b35a2de9e8482449f6da77c9e3d4af0493015a726217f82ac58954fe3e2e34440356b112e06a6f671fb5a6ef4619a6ea7b4e04db3757fb664c396b341ca89001dc1604b51fa9153f9130c1020ff88909287823ab3915ccc85c4e35df6c2f8e6f902be82ba21297fd3835aff5ce02f3c07dc093fcb1aba26e06dfe6f02df79291aaca069ecab9381404c9c3ea1ad409adf292a91e3a582d5a7b68ffbe10a0305248e0967e6df372f281bd192e139979c9866ca8fe1e10e0616dc2d4f85e119e0cb4bfe8cc31d9f5c018b65408524000a3016a23d9914d57e955576e2660b0e0d96c8495a12c3d73122d200b0f0e5ebd446562b08f47934ab499a96991dcf99c96a62880739845d29820150553eae9be0bb41d53d3af01d9867bb4732c90bf6e137316e3b1edcc209a8a09fb062a6ef05f37e57f2c5d1d0cabaf07a8ed7d41455407b096754180aa96d3d96591945dd7a1040a2de60d8e1c054f7854652b732e7a8f5b6474c3baa1840fbe81b1e6b54e201ef0bc8d0f213d7cec1d824d22209ac72525a64b903e773b83f1b68f640279f15053d21ec15ce2ff75922176b7584a16bf1a1f0d636b7942a3d61862f6fd1309972d3141eb769314ca975d020bf02bfddf17d14b60eb786bf9f55989fe473320d4429677e301c682633f813ff26c0a3da92f6d0680616105b0425af338c2ea6153bdd5216fae2afe461e9249c05e32f76ad7c429d92534b686dd1
+SIG: 38c682cedefb13e46b11f7b5f800cc8120d45a83cd8d8dec10c577bb0153d509ba4fdf400998788b706007ce162b96945c7140beee74e19d0743afa4ecfd250a
+
+TST: 974
+SK: 049dac3c977d9df503496b43d76e5540e315001ad57f15ea9f0870cad2d4f9e9
+PK: fc6f4b7eb39a711680f966d468a61abb13a9b6449bb99fda3d12ce1b506d1b4b
+MSG: 7f31e346f68da73716aacb16eea19bb24142dc283e7263ffc3f704a22ae5275a0ef95f0669bae5a54c7feb84bc74873cca0f335d6cff3d8b4a20056c64f5e882cbbbd2ac74207676467e5466ddd56aedf56e097c7f59d945915eb0ebd0c3c83d48888d3e9ede51ad2dd8a0ee1eab4cf87ffa78635afc4d6ef3e87dda3b65565c2985a4ad0acfdfb81cb0e61c67826a6ea0bed4c08aa1a541de60458704ac21ca12f1c8118bb3092c35a40c921e684564562c2c1049dcdc2b8d6a97e3567d356bffb5692a41d89ddda0ec3552152a27577f1cce57d00986dca77edf5e2518158200adf690affb31aaf2b574836839440999f15791cea85342ac94a96c7af7a19e494310ae26675f43c35258e85b6840b99c6b09cfa58d19f1e43a77e397b08c0db1830bca67b39ecd8752da611e0832c6cae7bb8ce74a82e7e7330be5062ed05aa5c84457b007fb5ccdc20a55d54d8e0409c8bd83883d2e029dff26ea5db275dce099e418659a0400f13be9ffdc14e7d645a94677ca846970b7e6ac527fa009a359454b3c49364905189fb49c9bacb650c03cd82875894e3546ba03c32e336fc6516a87676c50d5b80b3054273b157c5d767514e54574b8a101985a8e967e95da8f929800260e08148beee2d7781e9e85d463a94ffefdbb75c28fa8898015680999429cee798b3fd2d96737868a263fba9fb6f4aad56a15c6412ff85e7d3752102daaf25e745fa5f6f174a231fcce8624dd70856f9babcc209144ff6864648dea0d6884566a4c39147805be084e4740bc509309bcb142964bb0cfcf6726a0e04bbf32ae6834732bda0384cea8f4a4849bba0d18646c1c34471896b5bef149f8cab9ec83722b0fb209efe8a04c4a235dc8ddb20acd92765afbf3058740ea70b9c10d9c5aef8606298fe4151593b21f797d92ae9f1e0881b0d271b0d5b10c6ed83c349ec2473fbf2ff780dcd076d8cf0aeafa71fe2b8c5128015f8fbbcfecd5281cd5eacb6fe9ac6eaa6e47d667b9ad4b7e411e6cb7463d567607afbfd0418c4eb06afe847f5e40b499443828d5a273a4a87e46def21a919d73863af0054a099e3adc5450b8e32f51ea52c599a4a2a35351788af7cb71e5c44bcb8df54a601e6ec2c1828b48c4b1ae4463106f10efa5caf3091abf99aaba5252f484d3bbc62bfa6b2a806d23c6331a62fc46bc627679e73ec82dcc08f79143f4b71ecf357ea2f0d74e6d3058e606043f6e8fed704282c16b1f988ffa365cfae9a3cf792e0c5baad70ca7e25776018b5e7f0e9544e1d73f3e5d1e416a5e50fbed296dc1bf4b29a3fbe32efbd7e99c83015d27f535adecf175fc36c1ea4f4423b36dcdc054ba993278e85ac3622d435f5237ba61b49a
+SIG: 7532d1a61a981f303d7c2454354f99540cd484cde9ab337d6f7b51f179220f7fa2073476b41c71529f9836db6b1d0f5a482bbb4c68366176ed14d4d8eefade0d
+
+TST: 975
+SK: f07d61b5ca1c2700cb50f900c26b7c28f6c6940808c7bafff74fca4b11f425d4
+PK: eb243dfacc2dc6435776d554eced8bf92390604b35557cda51fd203eddb493fa
+MSG: c1c67843d69a0e62e7bf71f90206a3d5595ca3c482aaa767e931b0d6c2f4752ab86991f03583bb138e9f72fab58fd602a4b6b29602cf891408af5a1bfd3398c0178c441461e3f49bc81d64c0d97f5ded692c75d4d64dac5d80d63bd4dc5210c1d9350b142ba6e768f150807ab8a86cacdb59d84ddf660be56203c014fba1e0dc16fa6d32694e14b128edd1f6c6ab445a3ad34174fa9e4b01f25b1d5e6eb76983b4295ce4914d3ae48c704a30e554fc1f868b6272eff06da24bfe17e4e0f0fa46bb08ffb907cb61bebe52df311a64cb578b30fd627df11221ae4003a0b0c68e3c6f95a21c8500d41b2c589cc46a139cacff57dcf00759f52e9ca3dabdb1788ab6b38a5048f58e08e05c394f9d3c72113d452b7084c519f86c1689ffdbae506ed8450522cbe43de27aa3bfdd92a91b71e52a3cbf77c1bd2893eabd407a57fe5e146873bfb2043f4a6147df083e54a2208d1925813fa404e4c47406e7728643ebfb0b10142f909ef856fd3a916bc0851543b82a55f8cd529bd21d9e2909d6d7e77bdcea4673e545ff4a67fa37d65f1f63f11d5d0d55974a30abe188335db5dcbd356658f9b77682d96dabb258ea95951a0559aea4064d5ea1680501dcb4228f2c956f81d2101144af74c716bc8bf4296dc3b831725cc17d3bfd9066a29953b2ecd75059435b49a25ac525b4fbab1779022dfb6de525149dcd902ac8a7e21f344f5f0101480692d61608952c71413e30037945e206c5eeadfc3edc4bae0d796ca0c5f56d6ffb3f0969df9df8a794f5dc83a3b2f5c3ab36bb901bcc31551c550c63fa41d6a8d57bdb9b5c65bc610c3a989752ab28a015e7c2f6b2fbf199a76b9750c0d3d592119c8b4022fa45bade2fbb41432679b52acb4608a95c34aa40bffec10bc98f4729dfccb650b2a052dfb068959e648a92d5aa4dd2d17dde67cdf2e6377af0d4ae379607389d7e3596441b9f4222cff6af73b3300270ce54800bd934a9109a02563adc56ae46584451cdaf4a77538157e5870f4ae12dbc81870f5db41a2cb55e00db3d2231628f1727c3acb99ed3acd8b67156a8005a4cc8f3d3555b79a03773a931f14eebce40b9fe46ede5da0881fb220717e418e8b5a0fe5e477e7285c554e859e16441672b489934a3a9eeb88d78fcc5c1db2d1fbdde392773f6c939972ee8fa3189f4e9872b4abdc83b379c0c10e818dcff75c83d6870729284ced41f2ff55a87c960e63d1211f08071293f6ac63f9bdef38fd5919ca90b3f5e25a6c0c664c4ecf831c64e2d4c6e798a98a3a0f7be7a2463eadaa6a2a348f9a494717123cc0a28c0a5eae3f5b585f2cb8cb260c2c503e41578573cd9b7cba1408dca9d860ae4f8c3d3f322a45b58a2c4
+SIG: c19b532b8248563932639701bf15bc015faebb17bb98d871616e1048d64ca5f955f558f63b5353a1576fa1acaef39bcbc9021756df5d1ab3bc741accf9059b04
+
+TST: 976
+SK: 50864a75aa0c69b59350077c204b20757f2b8b6855c37ed721b49f2ac917d6b2
+PK: cff3ebd5ea0c8b5531d9211e2219e4cfe5ded991d8ec424df54cf53c8376f9bd
+MSG: b365f476ac92e76012a7ffd8782af15a3f5ee147f603a367adf2f9724613e8765b037ac0eb1f673736e11363e352ed5ae9eb5a67125ed818900342ae93371c433b91f6021d4be2a052b0da43b3682e7f740ae801d0541057858eb0c9c28d98f03b45e128aaa342c6b602776792aa81241cad06f1338fa0c71757180f588c8301d91c27679b5021cd75d7f6171ee9f8d56e4377679812f6ec5ed46538caed500c1d15f5fc86eaf9ed9cf9a0606b22614faf676462134e3db3582332b483dfa54ca29a5eb0d6bae3380e19d060113453f32bbab7e118627b40bcabf1711bcfeab8957de339436c7088bb883101539a09d3bef088fc1f840764036ffbb33decd12aac57fd26f84823e19553d4d67e000e9436ca323de099bc1ce75ebf5ddccb448cd7a2e4bbd6b32e3f2024f96cc5c7152b8be8ed0bd8e436d324d1ce1dd3cfcc452a28c73a95af8482aa772ae53d5be1292e39d1716b43758fe563c8aa3b74bba5c02d04778d91e3d43dcc72bb7c7b043c05c8745b705ee75b5a4ec7b95b654359fb5e853338219851d40a8afbb4f91ecbb41eb81534196cc0cc9d3eb714396caf045b231722d4486503640419988480a7815808be974287372cfc489965aac5b8095c637581eb910f9055cd1c0a0a3b0b33aca90f7c5b8e6ef683abf0ce53aeba51bec4fc7b427a2347360fca8636d3f1469284f269a9abf0cb1a244a15d6b40465e75cf89092474a8beda033391dd311c499519a08c4f034e71918d7cad41845327c89e7b1e94afb0723782ce5c553ef36791bba63de17d746491894012cebd87b1837a821ef5c624bbc84cc5035f5e70cd9f21b42219a2dce30e0e65c250d0d194d2b52486b03ee66332981a5225174db17e5a8bb4a10ed9c8a445c41442f3bcdb6b4f49e4e1dc87661a7b6e41f35f55dd67bd4cbc6ff58bfbffaffd2c382fcad0cae8f0df9af6acf0940007618a54aee31d932cbd8e8b41ca03821c428a0ef8e58d2435eecd503c54da9c1628f3c749b770519f53bf2d57ed712d075d37337b77a2b10a72d2d590c20d5cec2cacc6c3a8dc113e2d16ef2d1b390ed96e4036acd304e0c7cef9d431f88218aa1f83828dda636b94aa761c7317ecf116cbfc611e5ba6d94c50e994693023bdf2d248ed603f85be73a0008b75adef951dccfa30e42e9f5bb05023ade797506cbf90bb6dce43cf3a1c3141a5cc5fd9a4f3cc557b90e18049b3c130f461e4f32299fa1d1cf9c7f2ea2053565e8160a341cddf99acddd491697fa705124abdab42a5e8fcf048dd9f179384ec92a469aeb11e8bc62b69dbcfcec6681754757e4c5d0fdd9b9cfda49af09b83a5a4a10aed9a4cf7ddfa289209d475ab3318cd4b965e007dce1
+SIG: 177455a71694f12b762fd17e08bdf010a7fc91d19141d7ae2399bd241a998a6a50a9722ac1232c59e4e2aaa828078b2b92f4a54cdf0efebba2c16dbeaf072203
+
+TST: 977
+SK: e55f220fff8079148b254189bb294174f8e2c575e57f39d4bac8165c5e56e769
+PK: 7fd507d03fe1d6e3f911f059597b0e292ea096f5bc851852916bf1217cafdc6c
+MSG: 1e2ce8bf0ea7875df285b1dbd34bbe67307f2e8ac8bc142c3ba314c1642c65a2d62eb2c783f916283ca4ec3e536d3eeb65cfdcc0549ac4f6a45f539ac5df79a6d5768219739d0c9a0cdbb31242296c3312b7ed560043f536cd1de9a9c2b289641a1c2d84f9a68b7c03b8b8567e5dc7138c2cb967c628aa25b2eab434d4490b23507409717cde94da59dc1dc25c7be42a8aa02edcf4d995368e6ba0ee1f953600db98d22de0f8d257020e0a406ee1669bd527b9fe1c611f9be5a3d7528e8b6151670a8663d2ed1a58d3e369bb722a6302d7c172a19bdaf357eedb02279156e3b9034431a7d68a39528eb4023587573eb88f30f94e833e8a23b9d0ac7b5ca87824596bbb0a3d0ca1b16a6878fdf7e2cea34a6ffb95a9ff4e888a97593735b868da75d8707bbfdb1d93eb86a51e2d215f1dd9dcf78388729a3eb0f066ddc941e950c92127198bce63a54868d997029572ffa6f6fea1d3a69164c9996953dc8b6f9dad0635c9b081f55f983340f0814bf5470803090e7997f7ab796c2b15adaf4021d67cffaf6e1ef62867503945c21a329664e08a95a41582300da9bed208444ce6aa12b3f867795c6ee4c4c9257018627361293bd527821a29a339b404a2da4bd9944f877040798bb54abd2d76cbb18df4297f4ce3337f64d20580aa64bdecac376a6a4ff74d0144b2fe74cef82d50a5e6bdd799e55ff69662bac537adcb6881228cb63704500c143a4f4d1db28d4556bee604a399ffd206546597dee92252547f6c657f36841a87d565f6552716c25a21151477bee9ef961855fb1af2da8068f28ce9ff70d5252c7a63a2e14ded6b8977b1d7691a77ed2e57d22ff2e1fc4cdbceb5e805858d903896ea6707e48b345f60e2818b2fcec4dba48caea9efa38279fb83d5b0f46a45e42c41765d0171baacd8d6dda7991314b34e15fd36127c467d1de01c01a3a78a8c1b103bee17a7a0b7ac5576fdc226dd2459773146cf38261417ca19135dbda9bdbe54cd17aa7ddd38fdcac2aba396b365ceae98919f6c5177fc583f5bee3f48704914306aa19ee90e3fd0de5591c669ff35ab16fef38dee187bae1e5aaa566df10544b7d6d4eb00da7ebeb4ecdcc4d8e32b49cbbdc6e66640bdb0f72e05918a05c35d9bff7e0e88f241d7c6c8cb2fedccdf65560af0e7833efe34af790db63189022cfd71fc8acf88860127bd4fbf026bcbe360e33a8995e636d03bb86dfd0198ada959342d8e9c9ed93e23297da98d66a0d4fc965162733bc86541b95a6c9097cb55a973c6fac194e8f8a164274c479c510e62d8a035eb751181b502afb614d8c4467b5445c268dc3dd0abbd577004c0bc47b15fcb801b79359757b5ea89cf8cf77fc6d160e6cd73c4
+SIG: c1023a7068743ec4668f495eb7bd4db58129c11e58299ea87d6facd302bf296a98e298fdb48eddf9c44e79ae8641f734503bb83dc0b31f610df1d1e9d619a705
+
+TST: 978
+SK: d5e3a40671bd45f08842ddc78abe57de3b9ce5646b730d2e59fecf5a7df80f40
+PK: 416c37ae1ad15b632b0ea43932c17637282cd91d5979552e5eebb99a419d5c97
+MSG: 09fe6ffa8bf0942a64921357659dbc6e4f8b63ca3b9ea475ea39d7925290a148d87bb155741dfa28ae1beadc1f3e1ab76737eb5d5ddaded0bb382d7e11ea81a5e7801612696260ba3bd09c80b623f636380aa0208fee0aff70812d5307b27183832343debaa3605ddad17ddd70d611400ddd10d638aa3d6c68a28cf0e97c1dedf6ccd9c731a84ff0405a3a22dcba00ab44d5b21844f14d1374ac0cb1e58df4a90c412563cfe69d882d350f6aafbfa64fa2f9ff826032326780aecf9305d8217c179dbb63c151541232eb65979265d876c4bc4305c02f40bc1d05dbaf7dcf4f7dd9232c17ee0f7a0555f504ba3774548488933e7571eb3f71c4cbb20cc4e4a7322f35ac0e79a59155798dd0f5b3c11319b7d8f3ea79ee3acc68bdb9f37c7d4c8f9caba1ebf8eb7f43b462aefd38e8c0d4c63979cf6631dec31ab5ced3937ef5b2362cb09c71dd096657700fd96bda555e22712f71aec11ae5e91b24bd1649498b8d9f867fb6c41e076080f740d074c2a25572d34e666b6367bf7cbb3dd42a2382dc1973961268605396810a456ac081bbfd3a54b44881fcfc45b4245ee72465b487d07f2ef3f74add71cdfdd16e92fe257d334645b0a9bc7d072613fb9c0cdea9db4c72bc87109e102d7cbaf366ecd67fbe3ded32747307a7aeef61735ad3aa5ce95deecc16a16eb2a0bcc7adc0a11d888032260e7c7ec9e54f5a2531702a7e5dfb87c36ce313a3147588aef962c72fa966d241637c388b83ddec9343bb86343e920b12ce1cc915c83b31e99862690674ea4935a48809d4d279054137546392ad9f08e7b8de61ae73e81e483d3c63b5ae734e18e7a22feed1233d0ca63355f3a48a33067e1a0e1971f36aa929fe0613c21c4aeff9418429c3b072a5984959287a5e5c40be02bd22b9a79c7f3f5359d2bbe493f556dacbb0cb4c293c7d941265e777392d148d68c07a13c8dec8e5d1e1c7f041e8983edddaa4649dac1572a39ae4c6480ca550e2e4462dcc849c1bab781d28a3552b2d98e02e1518e6555340fb76d68db58916d556a7b81563aba81d9a57ae50f04cf5686021847d79b6bb3da8017a60b1c3beefd48d2b3cd39c6f53c08bcc967d93069f562bb36e0c4f4ca6bccc5e57d35903cd800a61785a93770e377f4fe8e9f4b66680984968f9649e105e7a119d97636f3a05caeab1d7ea0bc81334b42d5cc080830ec24d369cf8673a490d59eb4cb08181da39a46d966e23fed8d38a5fabc7e843bcfb015a4474bfd46d4a43ff4a51a9567661e2696db87c3758d3b54ce7846d1391d7f46526ef30844d49320018d749b5d4dfd30d380c6e573fc414d8fefc5d710470756bec00d88ac4afc925d1ede37eaee6004a23ea0ef8b60e48
+SIG: 63de6a981142365a3e592631c8277237809739d1c98f5a1cb2cccd34067d1ca5dc8f2fc63b8ae1a689dcaa291ba6b69b1a6795c579a5db6dccee73f6a420ac0a
+
+TST: 979
+SK: 4ed7048aa1284dbbcc248938b40c35742193597addafdde06413b8d4ccfbe137
+PK: bf841fe444add1f7c3eacdfd0784b4e855d2405f4021cd9d8266071c32c8a273
+MSG: dcff9587d6046c1132be07df26df6382ff92cfc8eb5345c51dd50dd188ee769f10a4de5e8883d116967bea97d3b32bc8aebb9f013d6df952f251c1a312346e72cee135a1bfd76bf3080a35c838b44d755f263d210310fa8d28c4ca52f08cac5b83a8a3b1dfc46d9b752d9fc73649d00bb9ee992650639c225deac1f39b9e803689d19e6d9f8ef4f51f1d11601facf410db648bcc82bf648769a7dd59c6e8a237db239d3f661d7852c426d394a90509526a859b476459dedbe6d89936c0f3989995511d4a576e542cce5e0dd7eeefeb0326d33f25c22ab6e7690633f4c9ed2aadf1d24f94862123a464042cea193a2f0479d39bcd1bbd1c7a0ca7e6258ed3732372f54e0ed5e3f1e2e4d4a04c510bee08d1c6d570cfd63abf14b4eef0b96f39ca29e43c52f2ca3dfd460f66e30235b159aaef2cc156012969fd3d159978d6caa0a94522291f7989d8af10831996137b68d97fc17f6a9bc2845ef3dd47cbc386e8977a8654363412dac3ac51c63817b7c051878dcf458ab3630dd7aef68d270f8da7880a467b3304f5baedfba9173e7efd007c412d17209c56d23968e340b8a0edb41b7e2a4088bec01b532df89b5215813131107b7b474f03c2e47d4317f11c4f5160904304997e76a121a9560235208d79b2dab4f7e196793202c0902ce9c4bfc10b8fe397e35ca0256454662ae878efb0a0a606fac0a952c9f6baaeb2d45b258c617559c0ed2528a88b49aa44ee43035b0d793aad3953c1a5a3463866bc815b1ffce2ff2b65e0fd47dbc15f4e7a06bfabc290fc62090bf7d94853f77c0444a9b90efe77d1ceb4bd39e203bc884011624e6846e2a371058daba63c23f86c42c3e31eaa4bd7d7a42af2d524896e31baa3e20763f85dcfd52775f28072d89f0bd4fae30d0b137ee37ab063ba06fe9d4ec62abb2fea0f81b8cbeefc030080b8026a58fd1867f66be1154e65bfea7dcec55fe32d51fb0b4a8a5a8a044263943d6ac8011c6e6701beec3a88655840c4892d450d312b7652d2514769f23bfd6e7046467df29a287ff3c4c9d0e64e6d9e4edee1b935d07681d47004352886e847b0c6d5762fd45a81a53cce9476c887221aea6c0c82bbf3b297932e5b11e538a3245d63d7b7b091dfa1d7b9a0e2db6698a4c5e9fe931662d7c6ec6d9d5b92bc7e041555df4df0ca11cabc485f9c556138a71745f03b9783bb200b72d233697e8bcf6b4117ee6763d792d7422264852f4f30f8d1890e2ea08098040f7f288e4abe90b63cab2c14373060840ef827ecc846cd560e90a20b8305f463c36ea03884a5df4c25f1ba9ea125952dc091b97516de1d287c0e2bf529775ba6d2f8ede03cb42c1e400ec804a9df08e46f44b5066346e3f7c7a1a8
+SIG: 106a9deb2327f338ccb71bcc94e2fe3d2e973ce6dd8fa7baca808b4111813e3bc3b4d88efa6a00c4710bbfe53196f9ab3a150b1654b908feacf9c13df2d63802
+
+TST: 980
+SK: c7eca83e948576bd9f278fd7b82800a41d92da9b72d5a1ccdbbc65581052568b
+PK: 076b8352dca8031e853c8d9099c2ef579337cc7b2b4c75d1a063ea3ec725b7fd
+MSG: 8d8cefd673855ccd8eb8534c312d338005bb05f5b9507d58859e1e953b0a4d913be759d8edfa92898c6e70a53f81954fc344b4ad6246b0109481ba6f73ae6331abf2df108eb2e85ceb087c1f6fcfc9de2c1f139ba1771b72680302d811ccd0ccd4e0c7feb0132eb20b334e5aabe5f6119fd8947d9e8852e1eb1b74107e174100e3e6df0c3a68130ca6309402594bb50c1c8e2774f13214496a7b1f348385eabfbccbac165a5a2e7d9dea5ffd58b0bd88b49cb331ecb7f4e9d6bae9791ad788e6ab8926c1cc1615deaf4cc400c77a316197bca1904995e1365d1b9702648376116930f6f91166e6148629e75be2d06895f6a8d15d5a94ca69b712f33bcf95be0c1be6902bb78b8a230d7a8560c4d84e2389552a81571aa665c19c2e93b0d43e8c2cbd9e885d7052518b77c47e841d119dc28b65a7504f664271f06c7ff393f825b1e5930d02b9c70035e292411c4aedf66047006970e349dfca7fb41c10fd537e35252e109e3336d7a82a14de5d5540c6fc6571d5774f39b7c403e7b8875ec215877efc6cc8ea48b186b46821ea5ef2ba8bacd40d797e6add06413283145b60462b3503c5b881d79a592955d18afa08969e31457f5b27daec010338ed867f300878fd87ce321880b860a0c64284ca2dc15f5e5310e10e6a73a7ea650ea9d373694da4dd429ae7412ef9b29c83b3b068c74769f431ce0615f9ff4f82baac47b4bce90449ec41c2a2d573d92b92e05631486165bc710ef5840f80dae9f9dd5cffd4ebf5d10746510c5fcbfe62cb9703c0b154c86f10816672497670a3b0150bb4e1b03b3bd544c12a90c3edccd7900ebb5b31c91117cc8281a3c4ed04998e99aed41bb41fce9990a406485b14dbe3bc1a5fcf7719507990da3b0b3c68ad40d8950c0d49ced1019319a3f36aff6caf75d7f9a0933dd3abdd7692a1562f0613fe4a278d5ce4c8dafbb55b2ec2af2b24e8396f587b170c9ca6547508facde73490dfb01eb6657e3f4f272304b70bf047a43a2b58e5568bc52b2c8d4c03219a5a8bd3dc0643185913c0af7411f81b77be2a9bfd5cb26977113d2658a97192b41cf6c7011b0ff6a11cbff3505546322f0bef6097e46b36492b016a4562e092b67c3fccc7780ea274d96d595849f7e2a56d79edcb32d784049fc1324a5beefc24193a66e1cac4a13a811b909583cc910cf08d4b104dbdb8a6f2b21fbc1db1175a1a2356a63d3eea9dbb8537d2c68627543df0d1f8fd8d57a18b0dbd69b920cb9b286e3c07ae44ae2e1beec01cee6ba988b5d1afb99790b1dd910655c43d7f2a3ed3754ba46516d278705559f5741622a9abb5c8f23fa976a9d146948ade6ba6608a35e4e0d330e82e96a2be6c78ad0cd4d8704e57cea146
+SIG: 86996a1b8e495d425277e97cc0830549349bc2b6f3dcda60f3b7d3501b8b50b5b458cda58b436e23c02cd4a22b234813aa9bcc3c61f983c0b7efeca0f1bec20d
+
+TST: 981
+SK: 7b469df9c8f78489ab47cc70a88503f1b8f3d929c33feab1c503f0969a3ac37b
+PK: a814c7e373d0113b90624a8ab2bca5cf53bf528e39fc3d367de154b94bb22f1d
+MSG: 1c0fd7450e29675c93091638c2ac933ca997766e380ec33a92b8a7e1a1ed9821c75fccb5c5f3760e76d0e8810311ddc624ea8742131c1c4308f4178e04d04960693d846c1f51d8773b6deb3443d874b9e2de3b77785185518b2e9ee736c63a39c8212ca8669e161d131b1ab2264fdd72dc5628b11c06f2af9f0789047bdd4ebb5d55899f74dc4e12e7975363f63a8da76b5585c16bb6d55b05fade8713d19cad1a211640262691aac9b437a9ecf89a9246ecdba1ff0bea78494cee15296216ea6bb882479d2437c9494ac7fa4f3015d1d3149d5564d7c11a7e7b614f7d3e9d454f0a05b040a1e06fe7837c2a9da2794d918bffa9e61a0c3f089f6c9f7eeac586e34bf94470d913da41371cacdfc7ee8bd1135655566924eadf096ac030a65902c103b172d12e88f053fc56ee73f31870817083afa802f7668b815ee790f7d40b437a2e6db2f0fb26836b4b2331eba55539614c0fe17240242dd3af7383bcff7d3f47d6544b08720c0a52441f7411935dd4a952d38651a80005fa3eb0eaecc735d290e8bd5e31b740140e136b2c002523d8eb2a0ab5bd687002b3b926f75eb690d1da73ad235892f3b23a756b605a437c00e0621304e810f99e314c4d63e322d9b69815f382ffa1ec6280fc0e641c8a6f6f7f61985bd3567e0f440de9f7621715dacd07428c0090154d59ce6db40169c658ac5bf44b67671fe19e4b5b38aad2d3d4e190a550aad4188352f7981a6d88062502df86791350392d41cefacb24e37bc700cb029190c3b1821477e117d5a462fb3e79133b1073598966f52b63256dbf326ace14db0c80058cf00d689a0a58111af1692744bf791bcbb427a372246e9501a85cd520c61a1e59ee180e8c97192f60fa5d3ab05df8d8551c1ac6ca0a9a012ffeceb3c1f521411edb6509bc278a651e129e96b0adc7aed707221caeac229884413daa10595d22d1db7082125f4f969500a1d48dacdae80f4029c163dcd79ddc6468fcda1637b87ddcf2a3d9b4d299a0e5394df90ed03b62137ba67b9fea8ae1f0d22f91c63a24b5934f74c265c43f1b923db980adfcee8313da520176730ef9736b27e6ba32d17ea69dcac6f4a016edfe2db5a5bb3b64932f7011f1c453bbe88bbac8c7035f93fe39b581fcaa7aaf082fbed004fd1fd5a4e2d9c19716604b19ce199e2169a7be518d5fadd2ac31b95478082ac91306008de4ec0ef4c9f9d6f96d2f66d62fafc2194082808af0d67b9fba0d189b055f061ccac24b27610bfbd5a2232dd6f3c890a9b1266471b322e9e1bf97757bef72abcee93b051fc923cfd4e723be3e17143f38eebb900b5bbcf7304732b9c0a1c5fc9509a693580ae73a4cdfc5fbf20ce81ebc835c6c909d831141b194f6
+SIG: 18faf82d08e1068e9f983d812f05fdb6929d2723db1f77c45a74bb09cff27773b54ce8f43b3015419112e725ea7acda4b23b8120e7b0cf420153e5b03dd06109
+
+TST: 982
+SK: dfecde7a56a18c1f19d80a19a4f1daddd0bcecb01eecad6dfca0f957a914ed7a
+PK: afbaa6e73e85b02b25a4b587ecb8c4dfb79aa9202761efa8d1df2cd0aa6316c4
+MSG: ae6e8ff65ccde6f26484950826b43623058a5efe020bb19b7d8b4e25768b692734fe07c913b9e88126becbf14a0fd0205b39fcc2aec373f8c184c6a9bbbb84449a7ca3b920ada08801dfc66ff19aeb92f2555399a430277ae22d23754eaace3c73846797536dd71a56f4b5842c0f410d1989acac5d805d26572c0f3a64dd2071662212d52fe99e59d966047777f9030fa4fd2ee74b7a7c9f7c34a6dc7e03593a13d64ce62453ee3ca30d84672839f19f1c15d0c45d2755bb394acf4dcb7f7f0711ac40ea46612ea37a7607ad32e818265fab1933f5094e2d03bcfaa5f61667f3b37f00c4c58d9b41b9af3900482b0ffb4fa4376aa040009dec2f4525799cb005f39d74cb2d8dce8c20c2c3f5409703af156cfba28a9d916439cb29f83d2429ce6223519e75e15c7c7fa215119e073fa7974db14f7a01093faa94ad52ab1eadce1a89366ca13adb89066438a2beb73034170aa42d9c2ddb97c14a17c3094376d2a3ffd8095fc4053d91d16e06d27693a1310f01a75111cfeda892c3972a133a09addaa8f74145f88681b6d277964bfe38551a2c619fa3cae394acb29c9410b45e101b1740e8b2aa6febc3a45dadb9d9589d597e57cd947b684cc355246ce6c326dd98cf92b6eea3ba5ab03700622636324dc1222cd748fa07bfd39a1e069809e567141a613e2e8be9dd398ab6beaafd85ff3628ee2aa32d0a57bbacf956190b5c4242eb5b8587d2fdcb0741b9416a05f5fecb1fb2d64788dce783c1f63e60641fce5e1d2b18a9500cd6a1fd335cc1db46ef04752b2d22072e6dfcfcfa569bb25e457afeb63a4fbedc293ad9d1aba4e394aa1097e12b0fc90c89f76df0d6441fa99808b60be07dfcc7f9010bbf9033556d5ee2d448937b783493920f681e4da708671097e199481b8ef0e0150d7c2851df44c545122f9b0e5ba2eeff2d988d56d9bbb55d9896111151a436af065e0cad178a2c9fa8f6974ecdf09adf013300cffedaf4b8791b467ba7933ada5d632db44ed6dcf2aa648917be6337d2e2d206856d08f9ee7b5e2f14ddc6d3ac429215a87923ad32d5dcfee3686316ddd1b27bb193a5fc05c893a939a5b98987366c829e392f485ea15e22cd8f857a134afa98f37215576ddc5aab4f2d10caaf050059a335f24bcdcbac819f66db07aabdfb76271d17bce22cba463a80aa892d0d8e055f948df7f6e6c300daeffd3a236dddcf238fe10666a57c6e3ae7e3673d35578f8b8ea69d3c08e0140afd3ee030b22a372160f908a378f8101b5f5969fea310eed37a00d97302d5c2dbe8cc600075dccd33ad63d265aaf60e241ce311bed7dd5e2745241ae02ae532d15c18886e818138751afc51850e506c6d31a8eef451adfd4b3d266b415a7e
+SIG: b4fde55b916cf60068f19b25351c1410dcf66bfc40f96d1ba2368bc2b9115aaa5b2d1cf0e3dfca02ac902a943e2489a5681bbafed39c6e33211a9cb2ff6e5409
+
+TST: 983
+SK: 07828c580ebf9e1d825a59c3bf35f072ae123355bdcc249eec7f2fc5755e29b5
+PK: 58e5ed85100bbd9b2221afc9c93184330ad59e1385606244bf003b8d2018501b
+MSG: 0edad5cae6ed9843e91c50d934cf55dd658f3d252039cd6c75be4f6b866fb75f35c8f98f1721d7e6d9d98a22e0b4934dcc129261bf6723b2fa7a995e35c4bd79c5816a321607d9dcce39fefa1d55de4e7617548ec385c3de01e366bf50c457a555e932070e2a5a0197b79efbe7006f0cec78b60ebb8fa8781d8eb7326edc30e62d3297a1e0a1117108c46ee5dbefc6594289335e780d55a084f552da3f36d3c4c6178ba74d4decefc5a3b8c47c16f534bdb60895d3d54cd2bb266b399e4d4fb48d7a8cde17f42412560737d3c06e29df524d0cbd3093efca1c8fedcaa124abb27abdac6a29e0e8246abd6f5f531950037f76323aa56cc3fefa603041d55f1929e277e72cda1f96541d2af3e90c0f0e28be196d8f6921f3cd57a7926b860aa1bc403576892a96b93190ae383f631b72802658b2e8451d52a2f45db4f8bc3b0e4e50b6d603a5bdd30c234200ad7debb963f58a4fa20330b3696449445aa371824842fbf326d901dfe3be045452a3740dd160e72733f6e2733525a29a865f6f50d53bf7191c599c876f5c9ca1e3fad7960648e0d471f7d5c01c673f42d659bc3d98dbf07d8febfb995d17f9a02cd6c39f2ddcd0f1d222b9e11f2dd7d3c7518224bb6bfb8b7c58fe8ac105405903a1b9da7516715b7afc38a555e6bbcdbad46e34e576fea34ce35734ed20af5d88eeb1047a2660648bbb113ad9db8c53edb6ed9871a1e44c9ed2df5656fb2b2806ecf03b1eca9eab50a6eaab55b933b2dd1f21d450de9d5cb2232f07a392081b0b4b885d54789e2f75bf2c4cdad878989b1d6dabd9ed23c7c5b0356a7d9e7335290d7c85b966e80184bd07998602886d7076193565c81cccda4cc7d33c85d905b1beb6e8e7418e8acaedf0d9a32a7d29d07cf44d3119d4e7896820b77de64b655e4f148800434af7bdb2a56b25eb94ea39f2169596bb2b11761f082baec08885f4a0eb6c95767135a7f7cd72e743d2dff144dd8bafb1b318006e5876f8e2cb44aa588f906266ac67119c17f5de114e72e42a1fb39944321a111fa795ff7017f2fb8caf482f55d77a80855428ded7ec20acecca83f8d1eb137b588ccb745c105f2b2ca41c3a9f49d3c6e9d7c648b003b9707c906462edad617a8cfbf9bcc6c5fb6fa984325d6582e28f62005383f338df5b38fa9d19c22a2a7ea1d68a92d1d93b7fb0b8f33bc8760f28aeb1439a8b07f3da58ddb155b498cb09c75a5596838a65013e24d5640d0842a7699322cf3ffcb5703f414ffd168860bad3e308b2b5bf3cdf7f363bf9aaf4b3bc424c146c6f5421430f9f476aa34a0c6ee80131fc4d4d970723a2186ae3625e286d17dddc435ccb00831678aba584a62dbff002bead6e11e23c54d33cf3a4b231a908
+SIG: bb09360439a82dee5c7d85779e54c13f88e06d38f4b94960fe17a1ebcaa3ee2f330c649154bbc875a4076cf0bbf7eebf7b8d08d5aa4be7413881245fc2d2b601
+
+TST: 984
+SK: f08ee8daa73e1feb61a88e062dfb1003c8578a0d53bd3bc9e589efb92f68be14
+PK: 76692ce8d116eccb897077edcaafdd3eb44ea1a486b90e49e97f966901015502
+MSG: 64de90044d0e76bc02fcffcb75263667b3bd733b40bfb26c6c52fdb4b0782278cabae41e2129ea4017e94de86087964f66d86207987467a1688f9fab3ffb2f1d0063bf626c941367c12e319ab7ca3020c9b3a7215a19303e2d0e8988791de0d8e1632daa38c7f3e7f6e48ce122143d1e2cb661ba77c69e6a710911644bc110ff58bb00b5290820ce30970e7fde189e140e5c70c783eed53f0e2ac7ecae4f27db81d15b8646faa9c5a3ae2b7f47cd580d7707b002499b4cfeb8c591afdf1cc62af2595c184abcf0b2623a1bae60af7026b28d0540b41526e3020f81b894eb3fe31b72b21a3260dae3210c4ce4fd69e2e5ea0c8632a583262a12b3a8b16c9c1206ad73023037cf30653cb80aa7df8314b0f5bc6e9d5fa00b009d5552d83b7970b5bc4b9984f69d1cca9ce4cb74ddd2d879d37312a0e159d7a6afb77ac585e6b459c551304e1eebfbcab43a10b505924e03ea332f5d020a55c7aa683c541dcf7790a240af079baba94096b46060fd7afe9056ca99e688df280a9be8c8c73e6e6fb052a33eb3328a7f602542fe280c890e3ccaf22c7f34f87b5e5ba784b472b1e1a99347a9e0d240858d1277a5c6b349383fe4fd55cf92e69faad326b8d6db46233026221ee6d0a1c4246533c4a0e5bd172eb8936a9c0d30066538e3eb4ad5cb9877fd861b482b30150a06104161647e01d004d997403ee06726cb97e2e25f18c668eee4c5bf72529803189ee6a7aec238d5906ea5ae10722c9a61a78aea52af33eaac75406b1a60befbaad48476d9ff887fd283eb1655bcc07cf753331436db5b3b13032ff9c3d696380e9f5abf50d3556fda0df0b53897a737ac7a3b87c2a832b0c7273ea9fc54a767f1a812bf0164bf7521630b81b9dd930d92ee2ca28e3203b77bc082ceb37d55edbcb71df0b79236789a25d418cbb95544e2cef33bbdeb27a3f7909c1f498f47135ae9033adf250ad4f6575361e4cfcc9bcf4b90c3ad47a3442297a223cca843d7205ed08a9b87160a6d01b46a7d1c844e8d1f18f618682bfb22955f395b2a5790a51a696499d9e71a501f3fa546de9b10ae47bcee42ba7f869fb9ce4ed7c6453326c034cf05d9f1e3c200701ba752dabbd868521c3d8f80672d42f6cf4564f08cd7b390e6d49dd90090afdb84486ffcaa4e84d88682744dc0a878faa7cd440a8b276710902081f4dc84174619a66ea3a371f95505400d99fa999017710c8e2714be60949d461310f7d43a0dc123516d77d362213f9f75a5a1c393affc49ea151d46a81ffad239f28c07f65f59ea077d9a4d9c752de49b9ef36be60d112d795f588b00ef6e7730dea65e1016da0dd462370e0ba5c660001e457c08b436da2903b62906932084728c81671cbfb079bb29
+SIG: 66dfa4c1575beff2f5a230b28c58c3eea0736df379d75559bc9d37a9579d121c05c373e8484c9747ef4477e80c4b2cb4ddf16ae9fdfa08a07547d107dcea1203
+
+TST: 985
+SK: 272d64de50b1312bee23d7f4cea508a8fccf3e9b324e97b1c8e72502f61fbf45
+PK: 33498c3b712ab9c01ec76b2efe2b83add1e1f2b5eb78f21692323451820cbe10
+MSG: d6260d7eec5d436208e7e737655e0971814270194405e36e39f8f17b649fbc16c0f3d7f2bef5ebc02bb1c4df48e8470a3eae8a3ccaf640abcc094aa91150ff1a8cf1169693ebf5ac0034b9b919ecf17db791dfe5fedc90918b23e54e9004a1ae771c213ed7ed7334434e5bc02c0dda2bd1a876fb824a197bc99613b1409e7052310b0820da71446929ae7cfd3afba042de54578a5bfd94c1544391a3d9acbd5663ef65c6920d78516dec1cd55f6eb7290ba0aaf9a171658200b24a47a071b96fea03c6ca7ed0d6fe675dd63761833d75bc5e58a958582db02a60c6ce0a63f42ba837ae77c17a32705fd9cafa587b555dd4619851079794e24eb44608835a6f4824920d577a270396c9573bc7d82fe2aa0465956613a2c508cf2432337a365e6c984cba917f0cf842af122dc89dea958d418cae44a6e4ed263a415ff994a5ffb2ff13913df214bbfe90a34b247e71ab73f7ff004c23acfd90c767611aa55814c66964168e568ba75bf34903597cdcac78c24bb9f14f5c86a51f364f9ab41e464aee64fa50a1c159cbd850832c504ab42a584a96d5aee082d82c1edda19338160b8dcfa3419b3af64d9cfb104f98f9d35e5394e23228e275c87db50ca867540b880c7af29fbf534294581c22240bcd4d7d2c20ffc36733ada27653d3ae1a8c2203eac626e2e9bb4b52ce523e5adb3b2c10dcf78c2a1e626a16ebfa1bdb8c161493a5aaa2d84bfaa0f2027ffe4e9eaeb332ebda7cbbb677769d78517adf72f823a7f844165a079878d258fd95225c21177837e69c19685a051ca92b120b7d86d78595471ffc42a5e6e6431be7b64f8076458bacd6c72903cc34fc63a40cf3df00eff9d6ee9a8f39d25ead81a8128888b0a1ac0e5e3ad927712c14146adf828770ff958709eb19288e77bb70734881e9e016cd29e7d0899341ff6b297ac796bbde486ec35949f6a32b2ca647385915ecba3b9f0225087145c18d6559d3a31d6f22fc49f8a6315f1d32abeeb7cf2c2c776ea7350fd5ebc0e0f265baccc2697a7c8ca40c135f6cfcb0b58a61431960ffa9065709a961a633d570b73fb4491de52ad0d7b204b6e997b037ede3f7eca820a7cdb2c69ac29148be3523508ae7e4c3d1a717f55a821d14c3b64f08ca9ae49613b115773ef618d321c908bd2156717a434e5089a5948c045c8da8a4bd86ed5fabc6b13466e6deda583207d2ada2b2ab9cb1543df7a3734dfbc6fc428106d4844724a13df42faab18ca89db20ac9bc27b85394667c5a2779ca63ed7ac2b7c0d4122391ee4602d61ea0381764fb72dcc224e65eae2bc4506b0f09e23205d0bb21c77d8287c165e0b42c551579778acb7258a2479d7cf25b902e8d0da429bde36b4590dae96f525481ac8378
+SIG: 33814c6ef375ab963769b2de4a25e7020fcd97f78f8fc93455c4b1c2bd45d4b01e192900e3122265fc552cd5c5f00e931e3a183cca5ba0802dafdebb79ebeb03
+
+TST: 986
+SK: 0c9fe559ad1ed3ba164daceacb023567b2430320b6715de732a03c59c7303130
+PK: e70fc466fb2acd74e099c36e2c22fa51290bdde96df9c31b6dfbfdc2e2c14a40
+MSG: 26ebc648cf8c7965ec6ebe965d9c792bed90655ad440183c6d70ea6467bb8e6f04ec843f333156917bf4c51d0ed0f28b7cd31bc12cf840686b82b0c2c350bbdac805333725d6b69c2ab7f34ee593fa1cccedf3f0642a688fcc1cd98b0987d01f713a2fa6416c961921de0cc2c9ec7a555855e7fcd4c7ddaa14fd91ecb04224e1761b7d6b35f4aa5618a500ca00d1ca2451b5d368afde3a407e783135f39019a5b984e82ac279c05e48c295ebd1563821a0743c52246b5d2b2034e3aeb6ce7c5cf919e74a9c7bbc9e25da30430eb16ecf3837eb38a0f559792a729890ba8310260f8aeb9b5af00eb633c12dee022628ba418d75cf18de2f2e65e49b1a69684d6127ef481ca861ecbce3be86497e65df4c5fcd0817c9716b59f2a263d5e9eb606839f85c5a365837b0fbe2c4274d66cb2c65ed365fabf58f15be52b51cb60118ca4f730d447359f7ef346b750217d47b2e79c86c0c62816a0c7c18a2ce2b688e0cce0d752321e79b423857dac59f8fbeb09411e71669ef9a2643f2e99f387ac183e0b0ac72c59a0c3c18c0de8b010878074acc1a2b39f9df99d9f8f8b52fefe4943c525fd4d06ad878e46608abf27a54bc5006f647db724851db7c4578ae66583dc4bb518ef028890347e8fce0927d7d9af3ab5d0d2d202a4026aa2ea7487962676a603298e7d2e7b90921ee1b52806d71a764e03e25ddd6848f61d46fad3d008e10ee5cd5a3390f9d158a4437ef615fc90ac5bf3a9d682e12c3398ac77680d22cd1a6a56ec3b25cede867edd383159c6164d63e9cd1c956ac7235fffae936166ccd35898e29c9b4ca4e2925da323b6fbf67cfd596c88a1a35a8359851ddcba8f6134a9faa244dcb47e691276ee625cc20adcec21cbe77a3acb9ba72f0c9d3da7e9cd5be3b95990ba54a9f31af171f95aeead3331cb188a5b2c6f539acb48b98b3f7341f60251cb60429ccd9cf32f009205f2753fbbb26aa53174342ad184dab6870c0fb52930119d9f97d8489a60076aadb2e96054ac7cb7f84e13c75bbf9e4d924d2272afef0871915e243ce66fc2a8888513535b10bb4079c806bd949281e28283523d0d210b31ef62a95dcae0cd25290c7edf2c24b432822debe347f1cae945f5728c71b5403ef14e72c3d8342e198b362ee20f809e46aca015f35477ff89ac4b37e6615856f7ea251fbfe13f9065259b0946aaef24943270a854de889780033d63dda5447998a3ed7e506aeb51ea37b681ac3076797acdbfcc27883630adb72260a46af0a60d53f6654566e20d6088cd48e23b28d81f0eed205b92aafd96164d6d3ca3fc8b171804ee9fce7abaed2ea4ddf9cb2b3ae73a70ed63de45e14101428d0a7a226db39ab6cd04374080e6983f018ce93da4c89ac
+SIG: 6cd8aed97d9c62d5fdae597d061c0c2bc37e42df06b8327a468f92b3f438a1e6b6b1ef2be78549a289fd3fc1a6299e5a33d5396cb4fac1e8e9982f0cb3d20d07
+
+TST: 987
+SK: 15d75ad8e4afb12634cc8e600f1a4267ef9584f4c4ac44fffe4b9fcb885c9d2a
+PK: 09d126f017e0169774e8c37ab379263a8075746127c2d11ecb0e4cb454709ff1
+MSG: d1cea2b7e9afc1f0fab890d2700a5ae41e15e7d34d3bf19d0f34d9f9f0ab9812dc7c2a8dc44c8ee7f3788761ecd988ee72c736b62a7cac3cc9b738e938df7787377eb9ffd120d4ff58cf1c0675633f7e83c4b115548f14d2f70c6d482211443a8499599558c14277980fa42a78427907f73a41f5f6693b2f75fe5e7a6ff0a6c3a4e2ed1d0d968d5cc9d6f13d41c3d291396ae7e434e664b2ff243e7f6d88010210078c39b5a576caf409bb4711b3eefc486b67b7ffeae0cbac6a0fbdf5343fb2ae4e057edc8c9d2ed31eae9ec83d2bedd219eb989b2d4419618c2d3ce4490e35fbcad432b0124795f9c5cbdc1eb0c3072b4aa801d26fbcc7b07b8257f5fe47acd9bc587b5657cf07ca545bb568c9e4e73cddf6254e22f78ab2f8064519f8abfd16fcfa90f87687db0c4209be2c6c79a5521f44189678d932c54585700a2437702e56aab588a17cb2cc94c00e87570ef3ac5133d753038aa46510a260c1fe80479bc02eed9a8d1de99354ac2648b48b96ab1b80cca6cae1877f37d70428bb50850e0308db0b423087bf7dde279e096766f2ab3ab2385b0464a5bed7bbd8d457e935e200aaaa8d951570e053076db18a6a62f72b319579884a0826ba2b436371dd218b01a0c5e58d0cd5ff9825e4466fe966df05cc31c803e5212183ddf29cef7fb91648a4f8ee19fd5f8dbd8a56be7abf33659a9224a1e27a1024effdfb88e8806148d0d1780906af1ebe3e5f14363190d88cc6e5089444f125d063155dcf86ca9263f2f5f183c26974fe000b9342d24c781e2058287cb6f3f1e3270c22b7707b8323a5cc8db81aa906bb59d696cb97cc74e359595ffb8373cad3710ea09ea9744c20e9a12e05be5a95f085ac561678d7da432e4c7cb53e1271df5cd5a339d2d7520f1c1848d15071d8c69846b23c5d2432c73890f2eded37c3d2964a4b5b55225888e892f526d1cac31eac356f361c2bf336c462d60c82e82b616f2a519c2f67bf01290369be9b55e9f5c8cec4f2e1b2ab302506c903dc3e7b9c978141dc904b01b1c23d25004399bf8b73d69cd539c79af5e9a0a511eca221078a1ff7b0f604aea84246c3cb32db9381be121767e097bea517bfcd82dfe921379840efb4b6f02a48ecdaf12d2cd38930d4473adf97cd71dc4ea10382f4f5d1dd7562cd4bf5115932f6c4700aa8fe8deca9d5e7277902b8f886529765db2486074b23a19fd4b04356bfa6226c82baf69a087d9ca18823f8e3e68308e16b804c363df5b6307e76240db1ed841b612d65548ddfbe8367da60772c6aff554dc85d041948345e567da9333151858fdf6993273925bfdc7181b5f646d063a8c8f310569b0ed093bd9dff04febf0b41c6dc55169a14a3c862e5416f1e582fdee8fe87dc
+SIG: a8f2f4b9e2072ca9fade37fdd62d8d0242fd4daa09fd856e75f4e343c7260ea677f753a627aed08cb96c444e29bdb5b5385d43843bbe79a3dda36e1e1101c50f
+
+TST: 988
+SK: bf3c0cbbbe20be2acfafb27a3611b48921a728ab17334b8afdee8305178f613b
+PK: 4500a03c3a3fc78ac79d0c6e03dfc27cfc3616a42ed2c8c187886d4e6e0c27fd
+MSG: 8f30ba2f792e9a97f6eafe29f976a48028cb8857b5c798bc2b6168c46444c0ce696070374c5e6a40c3d18a5dc7669fc41db9a81cff759b8ca0159871c3442e8c7512698fa447b5783ee01d1b611449abad237162922b02d1aec5de1d666f17da1613106301d30586d116e2ac09007dd71e8123ede4c5a6a9ac077fe3d93909da628e865870a4e25cb35591675a0690bec4af0281714fe6661bd5c00a27d79f959fb4d4fb1636a6a3575f4f01470663899d737472b096be4db723715367a41a3a4c13f742d908f4d921cfdd156e75868261ba9c10d85874ca2d6c0c9e7295e5662bd916a363c7a796ead617c4251e6794da06c3d08f2fdc3886944a7509e6409c906b593113b4b1f9850132960d9f3a4eeb7386fa592f6193beab8e0ff0f28908a0d548db87bae978b05abbca9b3e96d8795b88077f620f2124e31590eb099e94e0e6e3cd620ae6290f3e2d01467e5bef4fabdef79d9ab9239e753ec4fa0bb110ff1d393fca02243502d7e987991eb76d08f8be7eb2b1ee00c3b68bbf72a623baa15be896b3215ebe8a82313109fc629b0cce6491f813c24970e4ffe6869e40b46b4ed22986d0042155276c230de4c05d678552f2e851cacf5a472157dbb1a99a2b42ff4037f0dc6380672921c909206e80050e61a6b3056b17e3ae835009b20419a3b9846d374892e719f1b35bc1257da93ccc6d8f8fcaa8e609a8d204df108be7193467e7f105935282c3fe6670a5329442ea3edda2376a03a1cfe8723a909c064d30fe9bb0212c33afe2bea30c9143c001da01c7ed504559b97fe2cea09beb9db51900dc136705921e20297845ba72a97aa7c953814571be3f08cef968045a5ac34004f67fbfa54e996b311bd8dc527d89e1d4f53453a6713720101c45a60ee3a05c2ee66f134b5af40e4b70ef37ba3f0afdefc039f342c28af9198251381a1079a5dd035a8c28976c6b7f4db09ea383a3a87f0f851fd331aea7fa4bfcd95631d652fa2f50f1c23ff2bc137a0604e3d9f39ccb965145bca48b06dc8a817547b625effa796d000c3774bad198db1241be7a2c0dc4a4641b9a8cb9cb8c8c3887576f5272c33aaffe45615f51a96fae76cf5125bc69ad0a4038790799b5c2624421a6433dbab39cccb0b1787b5bce289594489d17edb5f9310374807d36c6e6734726bb33004ecae8bb691dcd387601f4ea911b4b90ebff756d7d8d9eb422cbb9aaf7f4772e0a5436430685e57b697454e82eeadce4aba062b77682cf219be1fd9b00f1cb1135a1021349539a4b93ae213f193d2932738ef72920499b7be2a81c9baaed17c54641a5974d27223241e3c6a095226bd237e0591e002b3af0565df3e976420f9764a09ae8bfa2795f8fad7fc687bd2de23d1488f449d8
+SIG: 8f8703bcf4c0329417339eb026f2b72d314d922e9accb5d8bb7eec87e07e6138551672a6132cb4f875508ed3299567b4a74134d2bdf0d857f980861d18be7e01
+
+TST: 989
+SK: 287fafd21374572f57810047d0d98cb1ff3d0120faa4886132245732c1a6ab78
+PK: e8252063f5ad7e95bd05c502a8bc4a17556360869b9de0a3b858938e11117619
+MSG: b3c443e4e5899c16d39e81b4f8074042a904a735074b2795d9ac06b1379ef7618d2a534b6bef81569e60719267bf29cd9d16acc9a174d8026b14b127d0d2d8b4583998895ad7ef72fedc53b8f08a2250100e1f1f0aab48bc7074643488e6b670e1b0727c385a34ff65a0d7e83ba86083b873dff0559209b14b2ac42bf7c572d0c5917ac42e4ae4dae1dd4235795276a076132cfe3e0c350b26580fbb3af81777b93ad95cb7ff17c2d980ce0d492f6d40fa90ba3fcaa21bb68735ee1ef208495ebf7b02276ffa1efc081658bb44cd2761ef5e3e1ca60ec8b5d816d4abacd0bcc80268d8f4df8b3a52049db0157e2b6e81acd6f3f28947c07627955cdac9eaa1de17d4b9daa361fb49782664d7d6d2ca5cec6d14893c3e80b6d16daacffcc0b75937e8bef6f9e112a87f4b035f9036070a2ccc55c2aad939df674f7e4e12685e016ea0e4902aaaafaffe38ddb2f90d9cf78537f61391696ff0330ae8f79a1c1ed5d52b4ee2a62d90fb82d9a48393fa33810b40d0455902d574ff052003e0160c0f47b5e580a078bceef06073dda8b2d1f104a595e90bb6a48eddd865f1cae4f178fe22e75f2f6124a9da0682447112b3db5be8c42472b241e944fd2370c2dc2715c05a41bdbc890c41c65fb08c2f593174391ac880f3cb67d1b74ff802ef962afef7b9f3ea326f9527e7fba698187924b64ccdd0866248c76ee64c79069be0a057b10ae190f38ff5aba844e39331cf1db13c900906bee0d7e7546ef52324e37c590675f139f58f573a494f4ae82c4ec81066a68e2d92900191c47d3062f0f9aaed191137cda9b83cd130e8262960e6244f8f6ef39f15a4fed13cb669edc19f5ce162ceb8d242b9addbfba8772ce74985a5f3720d590a920e1dca75a879b1aa459f7462fff2e95072761b209254fe38c54d833a8e2cb8fc40c598f3c7f7d6c5705715d0308dc30eaa84676d209d7b7b31344756e69a9a4cb4e4a251817a3786fea6728dd60822336b45ae5d47c704b45c4cad38c1e01ab93d141692d55d12fdb9740f1d181582f1c48ce5434860d930f0e7e70edcffb85560a53dba95d57b31e8924137bc2c19e34bb9c9866877174280e80c23978d57795864a7374aef383f3bf6375359bf63564740098461a6c76e8f238913288769a1cb1c95b22c32a9ebb3eceb048ee324cf0d7e85a389b04dedbbcbeef298d0527816085c0c83efaa298546e8390bd1bfe465ec1bafae69ee5218e72caedb9b649cf73eec454a2b484965179672debcf9441363995a8a907de17dc0684f2aea579a2fb4484195db4115ca32e970526dc00a5cacaf588711dbd469ce80bd297c4f41d6fa28a597c6372c0d214960b54598cd8bc849ebdca36d6225b20dec0d031169cebb36eadc3a
+SIG: 6201e30591d36b7b226e36fdf56434c47cd3051837af31313a9917fd02dded2b5bbb4bbc368b3bd15d062045f105b6e7341b15150d36f90087591d839901b801
+
+TST: 990
+SK: 9ad049100851d0f79b711225c98847795acfc3601c14b8a9778d6270cd4c05ed
+PK: e7cacf4f3714543c27a3e9ed833baf3bde4c09563bef59e763fab71fb5e4ff56
+MSG: c284bdd8f8275b49ac808c39045e50e1ed50c8a1afd011afe5db3dda620be8aec37f45605762e225d04111f21b49fcefca3f3d5f813b2020a52c49f95c4ad61ca214618ade7eed6cd8d314dc4c6355955277d457462f03b9fba2e225b1b537cd4b5237505c90d43205e1715c3963ccfbec379e6c1705e08034a31afce646727e78a20eed88aeb0dcdabc5c86e86979e63a5c26c3e2177973b6983cebfeda9f31479361b661763aa7261c0939cad48b71908ea90768bb6c9583d8eaeb9e0338515aca1242626dc6be04ecc4429e4cbb4ff336096192f7501ec471b596a99d4c027582cc69e204b6fbcddf59f5bf7462ddcd5989121fd10f11a0675b6c4e4f6520d27d7c61431ba7d174f57395a0bf72d38c1142736ded6b91e4811c0e8541a6c0d996c5a17dc97db388f721d2357d3c6af5c86b1d5e476ea0ac0b1c11d4387f769039bdf538a0216edd0045ee6dd89eef82a425a83faa1b12807038ca19ebec002e8b3c15344c61cfd1e5f0e3b0273deb37278cf197d8a83b13d992308a51373eb38114c9e45b438780277d1e32f3972962a3e14a8d08db9f09aec3dd32a5b99423e61f5e79944ab57a36f6ec07cc3204f9165ee021ada93e6fecb7ec456aa0288c378a75afd6e9dad6c6f88e959a2cf28bfe56d2e61b2adaecf0d86dd8928bceda26b0540246b7337f5cdcec11fb0c1a59d631fcca19408f9522b68a39f86ef970b883a0f0bd6b7b1415ec9aa043b52e19bac176d67b79e2a5dca8bfd29102ac608e473e9f982c3ec8932d8aa8cd565284491de52f516b9ebfb7dbe1299511ae732c2ad1ee4992b077faffc65f488f1ba215da6979600971196d0ff3a08ad9f00e829c1de1afca10ca476be664aad261889b0eb7aeb6ed8637618900acf481e2d224ec64a6e6cf4fa4df731b7a4feeff2580c99b6d75b4dcd0976965cb2b0b5635227842d08a7d907aaebc2fded8009811dcdd73354921753bc5dec017689335f56d0fb7ae213b41792b1f4eb14a24535977a305b19eb9838dc6b51528b98a39bda06010717a208c347aa158eecdfd9a0472d3b8d920f969e12b65919bda38b461949850cc9cc18d8e3baa8c886d93cd096a209d543ca3375fc4e7d65103cb6424beab44e8bc4a5b62c29a01bcf44dcc61e7675c025dec0724200194bde74d72c02e94a946a752f3608457fd91f292715771487d26cad4e5cf6ef7c6f71627a4daf8a4c9b891c1ee8f04aeaa99fe0c8b4e833b7609066b6132a968890e2695da22b2d857c8c0ad9187c96069e476e27e4632c447ee76714a31d1e5149ecb337ee132f3552da33ab2d6fa9d7e93f68a77cbf191cb06bc22f3470af6d7581e3accbeca0b6feb08a14b9a80c1ef59374ccdc0523c3684504c0104bba22c10
+SIG: fec0af34cbc5cffc56e96dd5ed5968e52cbd4269844fc30e3ab0d3472b5d180c8d1b7690518f41f14438e7f3a83d5e8976cb9a26151fc4149a3298d7e42c0503
+
+TST: 991
+SK: de54e13f9e2cc754546c99b33b3d72f4d1f7715038a9659f33636577bb526adb
+PK: 36338db3326b005e5c61ff782be2eab166d4eb7234a98ea1cd855e1ad535e94c
+MSG: dc4041ad61423a12a0411318a6e62a5ef64a19abe2d9852297be2d4a35eb8670ca36c521531b3038acdaeea2ea01a0b6187862a4e1a89d4b81c5318ed4d67131bc38f841a142a2f6f316dff076939dc0eb81b230fea9881f8f0ff7ed0b293f69b289fe770881fb3710808e8e59e64e190c1e379b9dd348b02c2347d7e20696790b62776a2e825bed6917037cb635c92fbc76b4c5851027e7f13852ee7e7c52573a9030b79f22b60d5869efe680c01664929fe9a06fa333052be1d6af3a0b482c332e18051e78b333839d6cb93d93ebfb277e4268fbeeeeba1e8f96a5c9e328c4267212cac251215bfaa78fd88a87417a80602dcd8828e80400da304e989862d13201082de3530925e0edc2c130a9a419071b31088da6f6ff4056301c129fc2135233628d16d8bf160f6ce86d83cd4e29ae0c73843d70b53056c5af3f3dc561271cb5aff393f0803ade072d9ceb745b6187b28d24696767d5c21f4d4ac58d5bb66c5cadfefb1626ef93f714c782b6ef3ccf4b44ee75f0bb757a25d9b46a9d931a03727d496a22810c634f5c1ae60cbdf2f1ea29b54607cff50d9f8e03a0a4513cf68dfb619773411b6180959a8aac30b2eee4ad327915f60ae52b90e04a9bcef8dc67e71ea10aca553db9895cd8008457d76f02ceb53500211109e89603f304d880aaf02861fe37c9534a9d672d83713cd326c9ab81c353764ca5ad5ac0e7f1ff880fb48acd9cbb949064e21183bc38fb1d90cfe619a8b8fbf5321889bb15c02a53e4d367fc668877b662281c4a2af678f86e691daa8afdcac1b820189fe5c2508ce36edd9c6f8f51575071839439a003352c1573e12768dd6debdf1ed4f94ac79df1ab6a0bc25079c0935477d9149988ec3b8793efcda859acc392ab3fa99493d7ae0a6575b695a1ce076532860287dd498967c46f7add49494c02e744c40280195782e2424476165e72cee23642e51cec432191116aec59b59fcf0a3683b95f760760a20bd67454d8de647c0f9ffc4f90f6e45ac93d802f338299ef280d3bb7a4a89db8c59a12526f2783024c8ade9002f00e3d529b78dcdd4903daf5767a2bed75145396efb69790712de6a5901e6d8c15280182388285021d0e70929215d9f2b799bb92f2ca56f48e8cbba2f19b085845126567cfafa603c2946ea1e7d274554a38bf7d86511f3e474f9fa5cb11105fb52fc68177f3385fe1397be584a70089dc741b4b0095bf7eb2993b418df87b14a1f97926e868df6e568beca2215f2dd7ce8a3c9ee849cb41346c684f7ffef0a792edf433ca99ef34c73f9272a7eb97587c8fce4a5136444737138d53eadf3a84f501bb10456e8e4a4047082c9e1435f576526c2164714d70b3d0a6e9c08a53e323840f4dcfe8f2d19f0be2c88e
+SIG: 37aca8f248394a9e04d06a7da84a7defa39de4da2bcb18d5f64cc34db08651af4abb19fa2a92a7dda56ec9930b81aebd23990511f684c6d15ba595f7d4a2740e
+
+TST: 992
+SK: 8504fbcaaba67683f815499282b6ebd497a81a9156f53e025c2d3ecee0db6559
+PK: e62da86493a0caf52921d5602fbdc3dd3a8436941f6be240b31509681238746d
+MSG: 6c63edbd40a03874ecaef81602cd6850c09f4915b7aaf418258c568364538e8392a8c379838b0c95345bf64c3dbc175853fb641f350f0b53a05a8ec290288c0326d435ff776f8683a273333f9bb2802184ecc53b06b28c2c402a54bf134c1a23299749a6ce2b51a7ba22232148797e993ff258286e947778a8742d3f36cc7842976043fc23da8a97ecb9715fc05fb0f23fa7321ddc1932861631604eba2ef25d8b756ce4733656bfd1e14708923ac7c60a79846136d741973ba5514189720bc0f7774b7bd3574595bde2515031b25b62654b161035778070ace14971df1fe0be4ea1ef55cf8747d3716c1ce707b1a7c8520e6deb334eb186338fc93000768eb2be40c6e0dc3f5df831b32c3a2c33e28898d6762a1522d3d48daee56a0269bddf6cfc9d73f8d178aeccbffef7ce164f98afea224a9b60ede46a95fadc9fc5d94d209c166d9b8de253381ea2248862946b9cf534947455c24458cf56683a0ec47a2c65075c694c7c3d6adf9ae5e8ad31ac769f83aa26e312c5b01a9a09404b15b814baa7666b3e03f06a8d6348ab8ccb9b60a4a4faf86f7135df039d955c07bd92e7b8e327ee6c1b40196a28b4446aa5a9b2b9773ab76e3ce21180f09d6c08d277c6771d67e22d84540fa43b38f634cfc46e5b8c33f15a568a77e4914aad9ab8c9f7fea47f7677c01880b3e85d2d0e3fbd6dc6e99e437ddc736f92b5a2ff2927e0b442142f0897d0b8a19ac203633df413feaf8ef50a5f767bedaf20f1c13f3b89d1e8b7bd18d591f9de116ee34f9824e4ead1ae9da2e8caaef88b29516aa942de77a7467b6fb26a666f30648c715a2ee9f946743b543a4428e0dfd06178e7e93ec6f26e003e058bec14a4aa2e3b8de11295a764cab30b313fcc5743b2fb89962ddc5cdc6aa0d2e4a306e77af76a05a598923f628a85df1cc73ad3bc01c4b979bd7cb296590a88b0a41b445d50a08423e4ed80f1763c716b6c457d845dfaa68d12b0d03c55fde8ae6b2b92bc6322943dbe54c706bc8e5fcee70654b26f3bfd877f5f5339ac182d5417bd4c0735d825bf70e85eab8216edda632ae7e22b3e53d078a8b20b5a7e2385337cf92b3c16b023563e11cb5043b704d37eb5ed9e85fcdc95cf7a6eade40803175a008ef653ac6136f16129abae1137c5823400748a81256254d317cfc939e26ea0cef9f6548db42890c48beb0479103ba089e514118038b1b90943d716f7a8d4cda5983a674b83a002d8ac9c65734a28b77b760c8e3803f8781ea9199f797ce729e06bfffe8c29b20bc85227c09cc05219ff2ba38e18051083732f83cbfccc310756450b261d5be183d9fb44ec18529f2cc9848c40119c607676bc4d9015fd4bd2fc918dc8031ec19a05ff362c184043be7fe066019ac5
+SIG: c0ea074bf9addee2e3350a969e7c569e3aea1a4188ee5af34cb73f388298653d299b5dbd94163fba209e8f7dc2e2634d3a52a02810a88c6152945bc16bbdfb0c
+
+TST: 993
+SK: eac0f06c2c14f37d434bc99897225dd2e3f1ed74aa7442c550339df77d0b7b32
+PK: 43e62055db6e1349c94d89029187882020cbcf9d75e03eb656fa0a15b19002d7
+MSG: 27b7fd0e71adf194cf5407b6771793060de0fca7ca0ae64835c43187408a704f533d5ea0c83a654387ba7db16ed58ec837226df57c1fe6382c5919e92213f6f18cbb5735d178a476af35d390b7cd2556217c530f3a1f8ab2339c1a5e8d969387efd39414b56bb784dfd5eb89b859e1f403a238eca2a941e6db56ac456b73450698d1455ec1e9b39a1e907d6bc7e6cff424a28eed579af16310115b67f5fcf7f8346b3fa0260c6da2e27755aca570babb3d303cc832460c963bfdd5c1ffb2fc19921929dda2a717fbcbeb2b8525761bd660ce4a0f7685285d7fad6115ab09f8e63f5f773914494e20be1b512d1114cce3f0f68c7d94f54857694f22af4c698d782ce837b0c1722bb7313bb2c41f6d3dd1a02877fb4296d8662a9e8625984dc1fd1a9510eba9d643ac58a886a045cd0e53c056a833f968b35d01320e9cc0b435d3f6bfad26f9eb5754d38ddf6d5c4bf615a7644a23f9826bcc976092d82d81d547000de0081b7a40a93fbddac13f7d99708ccdeeb9405cd634ca0748cad2c1d8f164f5d77a4f364ae488bedcf1f20eb954bc8a278af81432417856a900f8f152921afbe17914229a513bd71ab7e661cde129af93e25094c56118ed1f22db644428b474651fe36be82fa3695c41fc8699667e053743b0a41155c31f1e2679c6e8cb9c9d1f5f4b40a320a9fd9f47da9b94211ba601b22a115210d9f559c4496f01732458f49ac34eb386636c8b6c68c7bbc0078ab6f398a624b8bafb1c622958562d231dffd4db096196bb87479e42ea22acbdcde8deb10e311632f02fca14787fd3140569b9428991543ec6e834e10b149f23c74bb99ac7b3799a2096d22e387a712b6f9011ea34c5be4c468581ac62ce662063252e066a9a3b15c9570d065dc1619929f06bc75a3179468bc8a16e3ddc4fe185ceba0a92a546b8675fc1ade56307150c7e4c844f6aa5f1edbfb54ac632ca2b259c32a33ee2867856c3390a6740364cb0dfb976e53d0cc6c42a106a1c26918c8a6a033b2aa3c7f2e4392e79f8eca5b336bac5061d7698a3bfe7c2c292892554030de6ce7c0d06eefc54906f81e0097fcff27d14b9b7994a7970e1a5f5c6b6405dca22033dff0eae138ad899f6ee68120b8f22744b0269a9a8989b6f7e08affae77bca2168ade24058ae68a7f800e02e7c38391baf565dd40b55fa3ab3c247b9ceb4d967471775e663d6a1c6c7e17350bbd6b9a3eb1e484ac2e7a7a5c84f5083e5ace8730de89c47e8dcf8341e40ba345dbd66bae0f7f076a705b1bb7f470e3edfb2b78e4d6359413d18d33280b454a0dbb881d8606726fa9bea272475e79fea6a54cb4c0619541b4e77c170c8616874b954beb8d105b86bd1917e25cfba9267187ee2038b3f0078f4c318b587cf44
+SIG: 45f2803afeb0fc44d3aa965b12659bf502e47295706184b2a1c6f16d050613f596a2001394e00e2a44c46cf6505d5cf5b8ab8412f07eda951a15005e338f3c0e
+
+TST: 994
+SK: e608d5de9797907db6d98e0345d5caf2ad33e0eddebf18b81d61e8373ecfb499
+PK: 60e0c16ada586e3646912a5f2bb318fbc3d50b57d36fabb637696f9d8d4dc761
+MSG: e610fa7d8385c09c78989ed5ef7a230547f013cb7e8ddf31749ffc31cee10ab3efaca3f14ea194510f0985a818ef8b040e10c3a5114de1ac080f14c3d65d3c244f9242f75492cabae800fcfc9bc275ea1f27728c920c258fe7aa73948060299cb87835792edcc072150b73cefeb0d51562e53b46810e27a4d7f6abd32e959f7d731dde01d94bc41ed835efcd42c922437037a87dd366ffad2eecab6abaeb4fcf07392b3ab40cfaefeaa4266bc537671693c9093dabe8a0538cafd12c639a04bd2ba80ce0f29adbfc66bd4637ca0543a53b0e371d0e2e470d31ba360642a45ab4cfe3e790f587f6c5a5583fd15b18997838a200921c1c399c0b16278b7dd6d3aaab6f325b16afdf761a1bbf867de2bdd48615f15b526770ed20d79f0f30714beeeda58f52a3cc0c5a618315e522b9ebe7cd99b65ed532a62e0f0df72764d6ec6d6d1ba40ef40e05426360795d6dd85bb39f7321d3fb06275de096aae4a2fa2293f31b33f4ad4d7c251ac13e8e15c2bfb1f98f4962c54b6ce033b08aa626f2905d463f55b71cbdadecdb3e0b365dae07b170301983aeb83b1e9f2f28cf65419fd6b0a1a9c26cb54b5949f4bc01a98681844b43034c372a453d38f0473d0ddc709d9f49c8753a75b856c7e9775517df574a09a3953bde5daedf8e4a8da9d773a215120e269fa1861133cd4ceaeb91d5cca2606325458e50cb966d14055b22447eb65dc10118da0831df28c3b4ee8b11f0732f1521bb9482b11f5a86b22f18e83dd1d967d3944285e5d63a5a989817ab2418bc7ed891a373846747a12b527c2f44ee0197b946c67e67fa4aa1c29f3379d46fe07d3aab83da17f9d76bedd38436a055e34ca1d3af5a8754d38c17b9ba4e6419cbab515f431a2595954e428c2670fae3bed62b4596179cb59e21108708d071bcf9c621c6dff03d3cdc9202029454013b9d133847f26544811c0169770fdc6fe5638bfd7a720d8b38f7e30a7e6879060b5f28c8ab17b00200713207e8637bff4844d842d9ca788391340198a3fe0172dfa74de1e55adefbc2e9bc7e885476d1b9c055813408a47528434355bf03fdd4e27d8b3461b0fb66ab3e15a879a184457e9ed9ea6c51b663b31edc8c4a3cd454f69d9ce518d1b87888ee3d9dd5416e43e114ac05721352dffc2ca88597377bbc414009b0c2fd369be5ba35a6dce3478b6c11b33c0a33918b6ee5ac4cd4c2f1ca6bd190a000a838da38f53077560335596d1358937793963810a79a21b8d46140e768898dcda88a0faf8ddd0d633847aaea0e030be6455b41e3ede1e2873730eb8481acaa7a519cf9195847a86afa57f9071d44f4af4ca0d343c90c0d22d946146585f00ef3aef57f0f9e55e818c0128ae255dbc3116cf0fe02166d54859decbfdccc
+SIG: 0d8f095e42a2730a3c7bedf42d5c83398b5c0ee9c77c5a61d982291396a9182a0802a37f324bc4fb5d4aa4ed60444b66144bacbc865105d7690f140650691d03
+
+TST: 995
+SK: 0e86872c78620f10cb6dfc463d2c2872c4da660748c9cda01ab1456958afba7f
+PK: de4989989269cabd8f4f409cf1a4d974038b275502273557f312d5553fab93c3
+MSG: a900f3e9c643a5649b076fb69c3b2ac084d52ccbafcdca5a9db1daa70500de9933d23d153f74954e1bd5f57b899fe8a4b134c195412b49833b6e5095a6554eaa6d844b11f1584c85055b87f41c999669046c71aeb5c0453fd6a3c437f815f068987c3868cc07aa2af65819046c307bafb7530de84f7130aea78ef005d5fff52f8deaf1d5e9c326d3217fc55b94f628aa104f6a24a395e62d1b62bd9c0d82436319c5d73e5765435f3ba856a4734fd60ae617f7f0c3ba5722a73366c88a6dfeca85c444639f441f2c55fdc464ecb299eee36d8eae063bb94bb2439da04fa5ebc5092338a5035e480f0834aeee8d711f28c46dc960de1be9df307c18c5c178b26296dc567f15bf60863a36710867e92fd51048865674c2af0c53b2e7a248ae5bd09a49aa030618495f82480c420ae106889bec006278b92272075709fec95487cfb10061e6722b93eebfc0bc587bf7ba5f6692b074f55a98d5c302760b1bf1d09f7e8668479ca6f01eeda2fdaf584ac2058fbf7cf3100d06b8091bfeab51c0c0b1d4ee3a8257f69b1617604fce953bb5f7f271c6a1880ea1b3f66267e2439f34580628917877c66ec0fed76e44e8bb2b91a8806df4baca6cc92889b8805070c9a617f807157530751cc17c47b09eeba94d22b4e547c370ce7a496fcaa3412affffb8c9b4de89b9f121aaec5f544b0c725ec5ee9d4b3476adc9d050edb0fdbaf02ca9e38af15f515015a267292ec9aa5444ed1decd9cd9e1ead6487a0ccef995b1c600a036935838660acab276d8b0e5b07d9f36353214bf80f941ac88cf40a08af917926234112eccdaa162dc99de3e25baff65bb01e49898986332bdc2d705d5aea40f9bc4fbb2806894496038da236e9dc29600c9cedeac3b616cc56d89ec2fa67389666c6c4fe233b639105023e101b874a6330fe573f80ace55d037cc612e6dfd5a6e686f9a83054fc46e15bb6da453d810cf138a178bf039d1e181614ff40cbe6bb3b473663752ea8025ff7f739ee4b67110f968089b2473cd044d48b009d0677f791f54e2df6afdc3acb9e99dd6958a450c0e1b6dd5e97a2cc46298b4f48ac6adaf013d75b2c42072d2ee13f733687ee83c3f70c4fdd9720fd1798c662fef3ba012bedd445c4729f2130484fe77ac1b4c4ddeb81faf60f76e3bd7d21a9a6c57a69a9cd9cc203fc63b59ee84b8915b3c18a5954e227c86ebbb7d4c4c1a08d0c5e467c68a06970751ef584bdd611e1dd1b48900ab354b99cec6e1df3bd4146ea0755350dc11c3a3f600d470a74f475e4feedaf0865276fa8a97713471d0ca9955c713588339dee79656e567e6ab1dbf9830703817ae620929a0684a5caf20fef81a8ee897be7e505ade6496b9aef0272bd8f350860233b338c2e36d3138db69538
+SIG: 2037e97741c3e6409c66fc6782aab389c5d778097ac778999e8576e49ef4f6a0c7730bd9e093dd3c0ae7ec76203380da657147d33a8d9dd65ed00cf76224d601
+
+TST: 996
+SK: 520354d85a87d7c22ca6f784714410ec98bf6a65f803ef9379bdc804359b2349
+PK: d8511ceac2fd661acbffb01ba2741cad889934de6392961bdec6fa46123b7f0f
+MSG: a1d4ad486ebb7c1a0acb8f117013e8e4746789c6244a56c9edfbf1ef37ac1309aaf51c9375fc12cacd6897a4479545f2bf390ab7c0c0e5c592f5506e9938378a11b636bf857029b968547aa506c4a0829a15fd3995fead4f860fd7c623c63e8695436eae55816414778347092f5f4d422bb1b5e5a06966241efec14f1e4fca06639114718c30ebcadd4c6d8abe7fe93b25d17173533954188b1ab03fcb7792cb635ce36e9bdbdde7a561c5f66920d910cb269c8c1c3f593265090072c48932e692a9c738c704897489a715c2b394d5a86f7036a4cac5dcb5b85cfa162156e0bc6bfe02fb4c38608cfb23c92b8b6a3cb46e487d60e0dc97aa2e33e3dada925e4e6612cc5af125e5aca45817a2fd6c3ff10b18938b44bd4dd20d7fccf7f26b40a66f48aaffc9a541e6d37138fc55469868e2d10365eff37fac360fab3dc55437ac2d8fea7474405fb3630f7963d2d45958f909d14830286ff152aa752f510ce980bd5754e3fa32c69924dd95d5c152a737a8fadcfd0a4560e0b114f8e8aaa618d438b9877111da1740ef817c441939ecec799ba16b1b171ca9b649b7d78fa052d1497a507688bede4900abc53a9648da5917035ceffe0da21c25c09b06d6185bdda2d778f7ede6153e3eaff495c9796d4d166d2d2ea418e4a4aa6e678faf0696e752a09e02eaade763070e088e9964919ff4aa4c82f8629a3d5c797c2a64594d206835da0bfa43ccd9ddfcdb6aac4d486e03c84122375939a5270bc1519e0707e51c3f46f1e5c566b33a245fa0c202838472363de9f0edde2e791d82293095f750bff545e6c34739dcc54db0a36ae2e2aa39b07cb4f6a9646240d2d31488f67815b29545d220be929e3339f8281a937e05a8c5c3887e06048ea7b18a48f8d91b1e3af5cab5ceda0ebd71bf54edec203d37165e4c9f9f80461cd29fcd99ddea439693941b5d53ff94379cf642571dd559a11f8f383d943f2255cf715800af776b1045bf19a9c9bb095155dfb646b65f4a280f2a97ef927ddabe24a2f971a8170dd42a089276825cb9148c015aae1e9dadf22c10e7548c59bf6b868b20e86c83a9e7343aec2754ee6225f9fdceaf8e51c40e955bda49c35ded38fa8bcc1e6c8fc9c2412e9104c5c2368b1f9923e010fa2ede911d42b139f4007e3426922ffb6158eca97b47cfc997853512bb9d4ca2f017c2c263dc199f3bf1eb4f1508ef828b0e00db21002736a7f22ec91298194583139ad75f58e21b518daa49a4076c6375faa60891a69e52a656699d8034a7ab7fcbe42175491441fe61b1783e837857522215a5fac5590bed2e9d206606096d3be8ee92873bfc30cab15ce9f9910d01a117f89926cc3afa8d104f799ff38098de28b8ff0f038725c2903b24c1429cea4925249d8781
+SIG: 754e60d3f6f4ab4f5d0ddbb001532009166388487f780b76f60bd0bc9fefabfaab6be2ae7869573a64796ef2846e85e5cdae52db1044fefa796bacf48b968b0d
+
+TST: 997
+SK: 061bcf1aa6fd989897b322e591ccef5454ef4a5adb1a4800f32611cff2b5bc78
+PK: 73c80b734bfc9417d576890c20166da5c7fabd613f75474f7649732e00295be2
+MSG: d63bb9208c1f4c7d43326cf35fa5d83933151804ab891d49b0bdaf429e4c39a321428e0d90aa00318b97e08c7024c912cf388879f3cf974bb253a1e7a4c8eec193bf4c14af6fb9794df0d497850edb04d574c97ed76c702139968401b40eb54394ef4cfaa7e5d3cd943af12192538ddee593c2a24a267afa1371fd77feee2071f4369fbef87976e7ebd81d1e5b31d6e09e02d830357d36bff8596703e4146d0827bec9c0f87b26f31195c96c93b6d8c46767ec1bc6de39f0008a41ff875da050a3f865ab92cbf29c38a280f3bf69f68e92b5f430cdee3501981d0b3d189096e0aeacd64c33102421348812158bb61e51ae936592b2f8f1b910949ef3723258a9b44e4e1bdadf1ae2cfc18e37d2ed0dd1734404b8baa5f393cd56069ecebf7edd7c06cf6c8aa3e8e12fbf946d7b32d8453b6fbb6535526c8fb8fc1d5815560bb31b995df2adbd836add929a56fdd93a1747d93a40c05e129eb6f8583c2921cc9dbdda4225e176db386a02ec40af1032c9b62e95147025f4ac8dd58433b64ac073150c69b9c4154dcbb00344f308113cd9199ccfb5075801c705b8fc43b7c8bc167365e46293d06c4f4835c64ee5d5383f6890ca35a80af917748162df2518ab1468f153629899406cde66ce07fa7d2993dabe0c60089c91892488f3bcaaec408a0cd08c9aa98e0937e02c41ad52d241a99833e3b83f7d3f1b078c31d45c34fa0175abbd0f322b8fd2dc83491da292ad00762e3e577b9eee0aae08729070ac25e33bc94525bc0d2ab59704efec5c0148421a47928d34b1e45ce721ee6447fb082ac400b3e6846d204f7f9db6f0a32b2a69738b3ee9ddbb0dbd7e0f041d7ea53a5d647fb50b39ae24d78c8b07cfc4e052711f0d4639e721d5c36f31b588866712b757108a40cc7abbb9913083303aae05a0f1af0ec6878441a25cf8729aba42a3a94ce9b73888a0f5c9e40c9fc45410f0681fa7f90898562ccb4bbc55f0ab1fe9c70ea66026dda8d7090f7b38edb5aec1557b1166987cd41a7059cdee609b74d8fe06b7059b7724bff53007f7e110462f06ad14d07ee1b4d69ac823bcf576d2fa9e2e8ed7f3198040d471296063137c981adbf364cb20f0a1ad2054472f7cee2527f99809615d2e4b734b06f35deecbd62619663dde81d6e23528b0c97132af0a23bad63d9c08142a26e2743f8618ecfe723b19ffdd0b19abd9a3f4fe210b1e71acdfe38abebe23f7fdef66381cbc75f307e5577235b02e4cd9cfaa15030868ed1453da58f783b7352b04656844c042441efe6a3b4f8fec8f7de80744540c4fc7a107f4e1bfcbd99da25b9746095ddf0125d56da7e7f8603f04d359a088b4c044f936ccb7d8f89ed53cc991a3497ca952094ff3c33046f2609d07b29b633981369cb2f0eecd
+SIG: 5adaa94330a0353712a34dbe973b7518f9a2c713f8aad100251b086ae8de26f6d2b6ccf0528cc5dedca318df19cc7e45deae281e1324b96e32fef45aaf60b10c
+
+TST: 998
+SK: 2e19cd442f22a4a99dffc55e7bf625f89d1344b563f6785313a7eee973b4aa36
+PK: ee3da76a8fcf403a2958d4551da0a72b2e738522b2e6b20fba6aa26b32307357
+MSG: 1bfc5c6aa6a5354fbb861469796348ac6319124da3f10d20d50bbdc7159d41b5abb136c7996a773797122b525e8e2dca1954f6391707301d90f2101b46c7b086efa15877cadcd05812db34b996cb4f531abcd1e98db08a5cf1368e8f4b1109142e9562bd0085ffae5e660f59c930793ebdb6e80b0a2f4f3f59bf9d395c48d26e0a72a60f9d1ff87fd2d7a3f5383aa902adededebc6cd1befd038336162749d91a957ca2e3dd47091c5593113da87c3d66a02c80a6eddb535c48ca1f34a97fd1c95ebc2e570fc8fafe6e5d6546d1f3a9ba8daac334cf47bf117e1280d0ebdf14b0fcdbb43b8d248cc6b61320fdb0449ed5f5de8bab121af0d8554956e6a12016b42677b44367892c3b20afcc2cb9cfb5b100a95b51e8b07da9f51415f4cd7781a313765e20db27f2343e0f719ecea9af026956f3387e9ea7ed0a293759b4a262202807b41309fb80f50185db6a5f8bdca178841bec06addc7610df76017b514bc4142f26a36bf5bacecb012fa41710dd849bef7a7e451432836fe9b3265fd5b59ee40b04dad85cf48f891465a842cd4500a1024eefdf0f554f0ca17ec9f7b715256a9b9dbe27966386d8ac37d3c515896de0f7cdf7cf5b320ff7a8ef6b34ba820aba9066dd253c5b7763777f94b2d6ad8c710221e1137535dff8a1b7565ec81bd8ddeb502e3d58ff8f1fe6e86b8dc15a3aaec688bbbecd4688281db0f818de0f7261ba9cc58c8bc0d02e06632efe7287ad7a84331a824d9287344efaaa74f1fc576d0269430f856a8565265b9d6ef71fe134d2510ab06b60bf3c153b57ecfd2e6342403fe678b5886b6b734b7d3690662b6c8c6f6e250e5af6a8183166ddcd0a17f0cddc8636ef1a68498be50b6599539d46b4cea97130e08f94ca53e884644eda75d23cd2c038a5f17b591e21369378cd3fb5762d1a7c3e66a11ae6e91cbae616ad055e39dc41e154f4fced7b2696d9dc67380bb8eef474e9aa83cec47fafafb941d626564b2075bcc0856da8d6e1b0b8f18baf7513bbd14e491ed517968c4f7241af25098ee8df130b7a34d59736d7836d323fe3f43f508cdcb755895f59a00c804ed164cc33992f3aee962ae9e990b74272eb987b12d90b27314d57400e737d1343e970985c4271060876abcd7049e7c9fe244ff3ef98560995b7482d31bc7c09d9969f7cd41f4e4e252750dc16ccdb29b985314a0b6e749c95f9bd2838d5ac49ee031fd079bec3028dd9dd07db6fa622ad621b3b1e127e8fca37bd146e3cf703e911701b7a16c2d30369c94648ecc03df10d7dd5c0558fa9593425d948727d6860c3a14f811245106616d2a5fa981c6b7f47ec9def65412d132acc6919da4e88597aa9190ca614b218066a0f7b16997ee747c5a09785e50d0a891d95937863d613ceff7
+SIG: 28326b5b978e0dbdab5dde703785a667a7ef439d81ea47e066b089d116c25a34bb633f260d55f45bdf6bcda74803d7624b1927cec18eb1992260beefc399d90e
+
+TST: 999
+SK: 82109099d1eafeed5a85206046491b34d06dcde33f080960287b10fb23ff9f78
+PK: 081cfdf2d758654c41c447e1e6273810f8a738a733afc42294a2b1bbb769efce
+MSG: 84f47dd794977a6c1505ac8c05680c5615a2d5b057e39b04f85e3f9ff04960e0e016685a86eebcecf6fbce5fddcdac1a474c8a0d502c40e10f948646fdac6c81f1ffbb177a2a4963b67825903cde65b5dbe0d8941d546cffa2bf8a8ca8d6c6408530a6290f5d0882f1a1672dbf978e10c5c8af5e0a6239f0655ee7fd9e66963077a0e847137397d1f06999dc6f8a945c6003ea4ea7fd58378acb44ed5780eaa367796beea37ddc236999d012d6a716d7915649cc28e58875647e9f5ac0553c0f544df56469c67081d5e30395f3e960e6a52f0833192c548cd57c926b82db48c361bde70333a370083eaaa068dc2ae452d21ef1331aed190bd3e1289a104cf667834377cf7b5a29774807c3f1ea9e7b28831d0f6c4294785867b137b65028c14f932a1ba8e6f9f59624fe0c396843ea19e46fba09142cf9d42497312f360244032f1e00f38dd0de29f963b5ccc1ef12b2cc6204b994af1f3baf196d9e21e8fa4f097320c64404d0b7d5ab38560ca0655364b0b09cd6dc0f0e05b8c9110364f1424a9672b7efdf7e1f378e234550566dbe13b01578b04153e9c37b553e32a4441bc97e2953bec2e41455510f9802ef948dcbf13faddd722ede573627b258d55e83c0895b22919e4be5ce8d819ce6ad843b2dd09df64004c826c1dde7ce6480a271a858a1db169e1494d4469032bcc1ccd89653198b7c073f76a26a2999b5648cbadc1574c78ead8eece83b91e129c437f9eeec04c807459002e66dcca9bfc2caed9e6c0ba23d2355def75665749430ee92c532a695479fec929174f440ecb61a5ae8b2b7e958920558268978f7fb4da1b38b12014f5d61b0fdd7f6136ba4281b41a3a3cd188052b698765b6f05e41e78373ea830469787a37510993d12f93e96c72d72f4461984f691a41c7d3397ddd5a1b39237d1308864d415fc6c22b63f376cedde37f5252b51ec72e5155f3bdb4fcd5412498bd2e0c1f9850b3a85d1dfd25167a3cd771e8e4c9d868c95a7175e3775f6cef17e4e36497ce9e45532bd7f44b2776e40f91a07ca4fa1b95dbe81cf8f49e46b6c82a6ee4347918a7643b0d9a38857212c693eadacfd37a5f1d91558f5454dcdd05935f290e62d7e65006cd549f6553ce741df44d39644001eb479ca69568ad1f23bba099a41a47294db938731c530af1ceb9217d29bc2705613c1a1fe9c208d0b01ba6f4d9b4c7ba8f021df91ea2d578ce083123e83ba4b9c50407f6666fbe61158b0d1b9577772e3eaff8fb429d0f6d2e384126130f21b449fb1dc170db45af505bd3182678a9b5f9fdff65f0413b672c4786340fcf2522ea7f3d8ade8a059529649dbda9ce51ff05a2a2a3d66d2166bf2c9c6772ba0ef4105e68c055e0213d42c1ee123b3c1217843e6ec575d754df3c90a75
+SIG: b3987f324bc7e776c0f287fa13ad28741695e2e7bce8d143e29fad5d00994758e225fb802100d23fd6ccafee8e0a95bc479be8c23a11319745765b7cd47e7006
+
+TST: 1000
+SK: 65fcbd626d002111334baad4e6a8006e47a1f91397bee6dd6cd7da5a0e0248a4
+PK: 20409a146b42c96beab0b42ea7f2c25193119d0df44dc2bf14d11a32fd733615
+MSG: e4c0947fc8ca78fa8863f4d044499d036e2e7ef8c17e838f2fac02675b7b5381e5f9abceafd0d8886a929d9d9b49fcb73861b29d1518ac5f83f7f8fc26bd1cebc22d873a9a08231406fb032e4866e5f55c7c0441c519041bb2cc73f9226dd5d07eceb660d6c967db23365574bee8fc10222928767713571a71c93a85278d42299a70599ca99326cc86f6d98daac000fdfa710562f481faa020c72a76e2067d154c235a7a4f29708cc544533bd799ed6363eb3b56aa4a6d0e379bbf07600595c23ab1f3f9f1708e0070261bbbf4bfeaf6d6ced4d7ff722c9cc52d9133ea68d495dc9489c3edf6830231351f65cb5272f5396e2c4a1a5c88661a101892249e23d6ce9fdb6a9abf74272c2f59c3d8fd8743cce461126ca0a8b832b4b218336b1ae14da677ba7f1b2cc5ca3c7158f727a9e1b8fdd9edf5c2187fcb83db862ad0c6b39216de3116919556465100ade0a42bd6ba10d95418b69a3e005e9f104589ea5948b2b51bc7b1a9a0749da8f013781bc05c805bb51e187761ac24c76414f668eb45fb0a5024dfe5a5ca06f0403a02e3b2fef7a2c4bcfb1d075d310d5197e659cd14023faec20e045cabcb86b221a1d4827113ff3267a64debe9939004cabac85e5c7461e7e82a975acfae0b6c516a1c605374cfea7d819044efd6d74654424fd5c90ff2574fcd8e007740d975861d0df5259fe43e43639e36e52895439ba2c27c1e889c93094104fe914921bd6f25d3985ab1f22ca557b0e49afc7375243c521c6d5fafe0381ccea828e88e647fd90976b3fbec19fe9adb113c6404bd352bfc000446d21005b5f950ae07e51c768ca3ff6177b2eac50f10dd2e64610fa8ab5788faeee29d129009d7fe46aa3da6b9d86c73065eb5161fbdbdfac5777c4e75452e6e16ae9fd66bb7d9aaa426bcb7a6915f0ff44a1f8ec71394e9352fdf20e02fafe1e0cefe50744c3194956f928f82533755373838dcc1296a891adf641c7382d69b4f5a43d4af7772a4a1ee879292d7a4f32ac35ee121c6c34ca5f98487a941fcb1e65b44d4456127eedb2fcc1c3f48eff9300981e52ac38b496ab8bbce144a85eb9c07638b31fdaa781744bce17e8d93dcdc60afeda488807617f88d6aa54422fd347ddaddeff37a563dbf19974b2a23be300fbfa6c7fc41f84c6905415269f195990b5b4de12668c71c87b504f41124bf94436f333045631518152c5162a2475c40efb6cbdaaf9af428fed325b3a7d94c17520fd89e00ddf08b22adf661f0acd723b3969dc6434ea6f92ef58e8dfae5b0cc2885ba987ea1d16c39b34ef65023009d6345e48e3691a41f02a77b7fe133ea9de7565f157a2078ae988bbb266d22d5fa91a7b263e98ad2dc0731fe5a29025a0cb436864a5a60db257f1e76b5c608f25cdecc87eae6
+SIG: bc78e16ba674e0a7dba57a19094f9733c55d74b9d15f8a44d1bbc0a023f70155de2977111a417eefa8cb30ec12abc8384228167c70982a8206b1ffb72174af01
+
+TST: 1001
+SK: b500768a2823915c4a6848d35f6487d43bd766d2ce0945f8a3ccdb8d82a3892b
+PK: b8cea215a0124eed27005725d897781ea064dcefb21422c8bd2402c56a10571c
+MSG: 0a9fda8b8cfca7a5b05d78116fcee19ab803c1c6010ce11daa8e93a66d12c12e474eb91c2640d97a813d9a830d268868eb2e3770425f10c75840468e669dc7f61d3be2de88ae0e542bc809679113957a14da4eaff549bfde637d7cafdc6aa83994837397f86e4fde86d402fa9aef7f65549a214373e560e6d7a1c2769e0c7d5a0171e7cc00dff36e0429798b53aa621624bda74d6df0bffffbd8fd7bef1a64f36c000782f6ed031af5c2a74a18963598c9ba062392de9602036794b7b5e68c25c93fe7cfad47a7c5b979d476cd513a12bf0307cb1631740042a9fbf3eb0be5170620dafd5f16ed89342c2625d783e74ee0d784bf051943740c88b0bef7bc85e1a6a4a517d492fb737e776699590c93224cd4d9245d4e9371a367c0712f87490f9247c49add9313f277a4d9f26b75aae4ded6a3def85f83fc995910405548af670ed8aaa30524ab829ccb56a5005b58bce868c9e8074f07dd7f3818f299e4e086bed9eab902cf11b398d531b8632e7d523a8f877695f46ccf9ce24e62cab2c7cd0aaee17db52676a4b5058e9c1d7c47bffcb641b0ea2b0944f39a75665a7ef29b7f02a878db823883bdacfb0fbe5dfe5a9bed9fdac7e4142e3eb50d5e840bd0ac0becf4fa97e1fc4827c397a52465d916889954b3701b0fac61159b23092f4685f4788bad35d00da2679ecc54921f1a8647101657ab49477420567aed67c8605930444b5d07927c17eff1f8570cf2af29e719f85ca7849b895549f13dfeca68bbef71e3ce8b6cedd2ff68d32b02caf5951a0b3e6b0bae6a96c02058191f305e090711c46daddcd5aeee769c3a105e9a827bbd195d329231c26238479a9bb0071afb160ef955e874d7a420c56785f44ae0a18c52d8280c5998cf3888feaf89898134bc8d411fc9f6c5768ea7a249729413739e532b643937152cdfb8d2ff87fd48084dd8aeebeaf0f7b10d87b6e4423228c9fc8dc5e3852aa8b8acc545d18f25c55d73da1bb82e3eb376f9ef05b274d7ecb1845d65ca0cd2629f038a2d664d7a69781c84e98de2c209c46efc51162172856649469e673308dcc145eaf783f5cb5b4be7d9fd58ee0974c981a38fea8e31267abfa410e69e46482f5134f3da1ffe381bd69d8d0b78ea909b4af9396dcaff89960a049eda6946616fc27ccf9a9e5ba1a0135764f37719da4d28078185d04d72419c2c70f290d97e1f82b879f71b9e19d504d364cd3ba22cf905250fd37d58e5fe40209f6072a06d8b5ba70196230577877ec46153167a7c7aea270fa1098aba9e3a74acb36a11b09bd07a3b88ea654e268365625b589b2206c710d960f42ea419b7e4e3da4759fcbca50e4bf4cc55cf88f70b3180c805a7045086afa04c6be23223ecae5f82c146d54311d1807c2e4a53f9e0a4482b4e1e
+SIG: e3db47a11e10e788925d14b1e28b54c9fcf9b6acc1df8c14f683a5672fd504dd4a475a3393b3ef8bceac2361dbba3530af25c246c3ec4c05899b517f6cd34f0a
+
+TST: 1002
+SK: 9eb5c9ef13535f808109f4a43cfad5684f80daf02eed5410ac0b0a09a6082d69
+PK: 367eea1ecb4e5eecdf7e471b90bb34f9b7982c8cd66d42555c240b41cd8739db
+MSG: 2d7cb05e61dbae26258e3861c639ef0e1d17fc711a00f335ba3c027137e00708d708c1ff457ff2c65112f7dcd7d02f24d56f072158ea1c71832550a58366fd9197296bbe61aa4d00de18a453ef9174fa81968305c41c3455f42d447a9234f06e13bf8bcaa1babb11695fafdc08f7a584b2ea1f61e9389260ce7335a07de72c8911a58a313f1088dcdf5c8d4c456cba2dcb4f2d156b4943b95bd493ea4fe1a82d4e3ea02aa02972400b5ee17842832d59979fc179f843c44b03eb3c302416d0cdaf11c4ca8a66ccbb6997395edf6fca2ea004cf3486971004a42042af8ece005b94461d86dcde212a2eb1be3b914c783e48ac1ad46cacd73e1eb448368322d2678efcb2abff52093db0f259dce5c1e19a512820f235d6aeaf0e1a723c2c650cff1ee3b6b4f4cc989c0b7d6de3cd7e6daa39bb690710df00a7194c17201f0e81be64b6739e1c1e8176b7e12a353427c067c19314db642e5c76266b640eb1cc0c73f84fc0227e5a96060d814071cde2fed944767b7466f9001dfc223685429bc4e5e48f5c13a63a4e0d826133ad920d11772145ad6e13c93897398a8a401f93dbd103005c7dae44387f3e80b793607d05d2d8bc0d0351a3a452b8ce759c1ad48df7b9ba9e4a17df61fdabb9b577b5cec3e9461fbb5e128155a3c9c89f8f6bebb7322a16678e8ecb98953d958310db1b063448c349f36e168fac484cb3c0d4cb2c251bd92ef8e9262b44093d7e650a7d3bed3791fa88100fee6ef0d5e23d1e9a8099cc0335202a4f106c24777e98f81d26efba15c9ad1541e0adbf1d1d76076b0dfd7b7d6c8b82f9c093468cd196672dc5478e91ce701cdd7b68b353c97111f0429760635762f8683ae970564bceba9120517642e8b3a2baaa85c25b54a943766184904c72d929634ec5f0c28473415f12538906c678fca4e682db4879758492537e7850b9bfef3eb9053b43920d810e55be966aec68c9dd3b62ccf57e8178cb5ef6d16d172a56dd924f00f2d3b5e93aaa92b29fb8336d73e29e59d1c47ea6230cda1d5b03bba5dfdb331feb19443f123d2a03ff4f10eca166c2998588f1e584ed194dd6f73c8aca846631904d9fe4a98b367823e46edba2885129879e9277e150f029b8fa7bd11eab9ce1336777c80b56b3a1f0811adbca0f5b4025a5503c8196661aee90006e9c85bbfa4c5a0e902885c8ce51212ee67f0fe0b6afbc8bad453727543b3c68b890ddaba269d25fc1643f54835136a1a25ba18d916cedd6a47fc07adf6fc69fa508949dc10d9dc5e0261b52f3657170384eccd9c80541354b1ce0f6fb5ed3e8d54af0b5bf0a92835125c7d9bc4f092ff380e5e896fbf302552b14d5b61a224d86e301c7a66a66e4e4329aac0a66b156772374dc1c7168d5b561652f8f4387e4f289b6366a
+SIG: 429ce1fe846d250849eca7d456f8c59f8675b1f4c13f2be41688dfb8ca2a3b24ae29d5b6bf471157bcb6e2ec9d4a26b038e6ec28584cc23f2a03556dbb37e900
+
+TST: 1003
+SK: ef0948e13281f3cf352cbfaf8d89d117768552d5a1548ecbaf37412e97670fac
+PK: 58c2457f5a5e3cfbf47119a87f2aff1918f1e67ae6fa9171d3f41eee07a86872
+MSG: 7ec47f2f1fe3b70a6d1d82c7cd924b4bf9b2029fc12c52a6e1cc06cf5abfc0a442e7cf145c1542b9b135049665711035e3c29a91d4fdaed6127057a812c22cd75ad1879be1d2c6110e79e987524e4e8f27f16eda90cbd4733f111825b516d1067f81eca5e6948576d5bfedb3277c1abc1e60f374d0701b32ccfd6a5e9c8d1659aaf3d0818613613b7e288d845e9aaaba2e3e9b411d501dffe856fd313e9fcc9e7430b9983f20ab4ebf4eb616bd63e2c57743658995ed0a149ae620a395613719b3ed7ced4588d5915d70a2f0c687680ec34fe3e9f72392e189e13a4749d5ca9fac651b92c084c4066fdf98a869223e4e0c9bec5812b5c1900e6e60d3a188d48a74dfd415b5cad2e91ff76df75089d20a755f260756c8f1382a29f7b93726e731071cd477458c6f2022dfad7d4fc7ab2380541864f6b58774f9ae8e5f077c1a8da073c39853eb2fd477220b45a3d92263dc7e14d3bb2b36fca466c7ef8a247538725f2fce5c7221bc751cde1394604f5931d733360ccd47ce087712958180ad84fae713b543f05eef6abc0661433121ed3b4506a1465025316fb8f9d64535cc4538acd4064dd576b0740e1beb13bceaf155543dc89097ca5ca1cffa0ad65a10bcb759354eab8a42de734af909c2feba380d66409f325d5f17af9ca7f8cb4134fd6a2b6a528d9e60d9612b8e8b4062f8e0fad1e7eeb9cbfef6e9738ec7973e1cb2ba2327deca4ea46568f31e12f730e247c1d07029fd4422b298ff2398023b4120a3a425ffb652880c19ea69f3639e0f6df4f00876cc4528e267e81d5943199d0feb6cb4e1baf404bb6f8b39b12dbce9fdc35dc158066e9975ae5bd3b55f2a41a791baf3e8351ec604944790a22c933c80b1590ba197a4706f7f5128682edcd74dd78d435e787c2b76a57b3f4e7d7be2efd26da5f9a829119b01508b7072c7699ce52bb578cc5b1b93661b5172fb84daf1ba364d2cbd80e2c99bca9caea873cc0a1629eac384e9b206842a6e6183387591b4aa34a95fd89b49d8d15d91e21940e17dcaf1eff8a0a47a0d7a95daead82aa3df8204a0cd206924ae510fec8a9c4e8d85d466fdb4dd365dc99336b22ce0b956b5ee0017f29d25ee66fbdcecb0d996ffb97c8defde40a9ff9993193ca8f1685067c19c526e0efed236f8edb8def6c2a03e21952c8612d624e6886a311ffb9e2f15da44abe180d26a14b15f63561e097a730ecabb792c7c235fdd360f571f27ef68677a7d63beb4975982cb199a560f816ee12989445f7f75b83eb278d62825947d84099af2a6ff2eadbbf589b5eb2f72ed114c73151153ae0022bc9564d15c2d5cdbbaabbef638f03095f53eebac9683409ad3060cfb7c7037b9b0befe069c92a02be953388e9ea45d36ddf4f5a8389432ccf504c50808b07f69
+SIG: cc12f69db63a678ec477a605a505c57dc2b810ef85e3e34519cb25c51063aa66355d3f1e2974695866edf6f17171ce37842fbab5075fc895d18ed743c546080c
+
+TST: 1004
+SK: 903f3b5399892e29ccfafbafbd7cc4533c154a625682406c89bf894c889e43f4
+PK: 8fa5ff5b6b26bd67df864046429df124b523005dd89444275c8ab7ebddb6f4db
+MSG: a2c11b5fb884a822fae64da8dcb4452cfd7a04ca6d7a5abc8d8271e93f93449e1feb8e02975f496b9034400d3599ab97aa3997dad1c9ffab5b9f8df4aaa5b840d90d862fff7ff0cf73a60c66150009e01c937bd1af6807b5ba2ef612ee13d6def40bb09c46811a2d4e468e038b323055f9dfbd01829ae2f1a535ef0295ca1ed176e46de996cc87bace45356233211835b6f4757c99bd527e766a5f0b127c8cff8e6d66f8bab86d0000452cd7f67be557788513ec0709b537b007b42016e7a89683469bd8ff8d21eb10c14917d47f2dc4f826324f7c01b24f8dcff04aa6d85095d9ab154ba5c3bd919c9d728dbdc990d19ceb237b452907bdbe21f9f08cddae5be479276709b8ae73f8974c4b113841ad535d6ff6223eea47d185c8e8a65fdee2c2d45800c17cb556eafd676647d9968e55ca9c59232b9770ad10f955fcb5858edf0b7483adc1817c0f8d02240482caa76f43c6d2e96a4ff9591cd7b878ea619ea56d1b588631e7633c5ecb2ba6998398cb06e3cf75aeb3e08dab19632d454ff7dc0e2a41f09737e8ee823d1b9e24dda84a2ce0313cb9fce31cb663c55c05645e63401756e8ad38f5174c02a663d815ad64422ff7727d4fda16e48d4bf8f6602e7260da62330e6878c34764e129afbd552208f6bed4f7cee9b671f488388815d74b4951b8682ce76cfe31e938c470b8f7a45fd63a9691f426a75c58ed3dbce3ae8fd9d10a8352e47cc1b12c9192ac8626d1b384b77a18b986e71a998646c137992b67c4817e346345faf50a2659fdc5cad5c719648efee3847c0ff6bd7095c28b4c5195967c90cf84e1ef68a1ada01f6274ede363fb82e0b549a870245d608cae8234f6d84abeb61b718466093620d85c584ab01eeda091ee8aff1cf67a4675679a1f4003e66aaf43871b88ecda6a16dc5acb05395f2da9df70d3bdb61438e1c3d40981e034627d026ee1d2e79f65cbb8189fcbb3cc8b5c2e7e796b5d2889411d5641fb869c7b0a589c43254f8c5438aaf5ac423832f018d79a51b96f242e2de0c851cc5fc2b206bca4b5be836125aca144bbc38c8c638be0d3bbe025a1be8b3d03d5929baa649c3544a32a915e926a38791b134a971bc52d1b6ca625efb7c2f3bb47ab51d43c8e374d16cda882204b71cafe9093cb6078ef2bdfad59edeaf36d0c1a4dc425b9e718c45185225a9c3084b782bfe163492f8e8482ec9aa073f6901ff3d1117ce917e19122fa67650d858f8f82b37669723c226d721697e7ae3359f5a6b02424ee8794cbeaa641edbbf753b103a5fe158be0ba60d8a212d42f8c5c2af254bf1b9c80df6f1cf09d70793cae1abb4627b1780f1bce7f617ee50f6bd4b083b2fc7cd844afb72380d5cb6b255bf47ea71cad6c6c4df021f81b548f432c18ac366c6aecd03b6c8ce2
+SIG: 495a8f991941c629bd641a67471ab860bfd39b72f23355f7270909d5307c77b1b94bae3ed19450780e9085305f31b1e1683facf0d1fc8840aec77df67aeab302
+
+TST: 1005
+SK: ee81e0fb052e23ad759de6aa9838de98e36d4820dc0e1b7b3ef1141ab9de3340
+PK: 98f3c9880794de64fa269bdf336095e0e01b1a3b375f965b93700bbdf4b96869
+MSG: 28d99e9518b88283c220e76de205d7b6162359b1dfec1fbaab98ec0ef1df8da40b6b7a775e9728450aeb2351fe5c16afda3aec0d71049da4cb7d4c63713a2410abb022f81611cc064587c8047d4383c00c3c562e9ceea35775095391b5f3dda0e373c4a77ff618a28ef68787ebfc3ebcccc5d1ce32ddf43bfce57203da76a8664b3c616a8869282db0b72811b5fd5a2a03a4ff66724b0489ea2e1073d781c3f189115d79ba20a46d1dfaf5b1a5847b2a2e31b2808737569e60b57231e6a99af26f58afeb15770810474812fe4afacf884506b8c314bc6751bb42b4bd6e87d2e5de70fec5f0014c4257b13472a3b0111a7a8cf83b1dc0cf962022cd44468a3ab1f0016b70cafb1d0246acd7053937c9ac40207cf13b50dd15e2a2e15f50a05bca2f28e770262371dacee02e25b2a59658ed90c0600fa265b7de3d44f8ef0721bf39ec4d4eca5888527b778067b1d659c00514c8d7056273a294cbafe45090d069bbd09f92f461e648f3e682882c71576e974debb0cb7e0e8316406660150dabb58e76246614a291c12ce9e0346c02774d4d09cecc23696712fee250c0bb5df7a2a4c43a5563331bcbbf84be3f2eeb0654532e85ec597b53b32f3954ccaf0cd426def91ec4b208416948af27de04d832705897a04c5e24a2e88b20040fd4eca3089fdb918a92e35c4d31da26850b9dd34118c74449a855ff4bc9fff0d1447839654b00417999fa4eb89102133cd320409153584957c10489db4b7244c95907988e83dc821271dc1ab643d6992d0fd820492ae642e24d19a179fa75d9363b321662606fd94a47fdb2e68d3f30c04673f809de0144945ea4d4183d48f175079eed50323c6b192e020e162a3503aa582fb08b403624a23e357eeda08d904386f358c36c64d314c77cd9d4d23d581ee53d81ff97ada019cfcf04eb9dcc1de9b74c3db6b811578bd4f219c5ca48ef4c826b09e6c96d031f65dd48b6e73d0c100586b21df0293a03d2ed7e5009ad025340c21d09060691f5cd8af2ab12f9b860ee87815e1a9f400c2a6f634ea8f9b3425a08d10b3c815367388f4d1be356318ecf9035d0ee975affa859caac28ebccd0599bb2f6f3523661bd178fc9e4cac378bb9dd4716bb06923fd2bbd56c959c42b95d50193f8bf299fcca3b2eea94ec5f98583924c080416e28b54fe57658458b055ce4de8a75fc82715cae91d375cf69281378051bb61fdd7bb0068f63efa6d6e83d8fd4257af80970f4a9e6924b2de0ad966dffe6fa4a113b0e772f1768785b3b42049f76c48ad80f2c67fb0f91a5fc4107912520d8d683c062c3a222bcda7e710bacd478ee88367b6a059a452fd26f114a5acbd6979ba019f7da68ac04a193026bc1c27e4837b1de29cce090e3380d5051a586409e628e3145665bb1d84ecd8
+SIG: f0d873be15cf454c7434deab71de25cfe99e81a48d2dce6a35d1633714df0f8b4029e0582511efc4d06892f672850246bcf070c46fadc2faab44dc435045de00
+
+TST: 1006
+SK: 69d01d829113081cbf5d0c6ef77b21775c8d9b680000056f03c75a7d0a0587d2
+PK: ee8469dd61cf5de400da7d7a479a4418e6772e69ff5330ce5ca77859fe271755
+MSG: 0b9e110f29d19816a17b2c75478f13cee953811a1983014cb7eb0f75526912044c3ea6829780e657f817c5597d4661080d9034c9778722418f2c3aeecaef6b690c5bd3b593701086988e4340aec34e0172758eb24087d03a8f76e7cbca53aaafc4d2155c7532ab54be48872653066fa1fdd54acfe9daaeca356c290e6be63355b6d9fc52eb5e4fccbbc6083507132de485bfae9f42e19712232b716402c23fea74efa69d73c8c2e3a8662b8b65b0fd007741013e1f6e3cfe4345d5c830682fe60021d708e10a9e9f4052ff7a6abf28acb1d6b5fb038eed3f72513c355bbfd5c2274fa85fc4f446974b2d1bc036507a1eb5fcf55dbd44210e538274de808b900bf1c0fcc0241270db8dbdcd88349d67224f087e5f07f699b0bae68b2ebc9a4e27c70d3ac7d996fa7d4dabd568378e3f93905b1c89c652d384c16c2bcb1c9844c38f71bb13e0c6a2ea95b612e390c5f86d248ea531f2ec6f639a402dfaccf37217005344030745d1f1e520cc195dafdd7f295f377b8d614716703836219bb7b09fea7aae9ac33e42dcab65cc6142fcd8ce15e97717fdb33e9538c44f6cd9c1c65db62751f552f870f10142c96f9df1855abb39e42706a563ab154511fdce687c9576f9edc3b4ba55346ce66802fffef4b1b5e12015ce8b57de5458caa0daf341968128584288c2f27cbfb76eab286bac5f66aad0049e0ca60a9014e17901c4130e83ceaeb4c2713e971a235eff995a813ae4ea64a583ffdefdac82ac76eaf4d47c4ac8250fcbafd6b88faeb48015f5b42b5334a50b31d4502ea491da90dce93c08fd56f5c58eedb379166a23762be5e4adeaa6f4ae1c24e0cac4ddca0383458560cdc48b8cd1f42a3ba2f6ffb6077909fcb294ad1ef4a44c22ec4b3987ddbeef325b98ced56815ea7d5fccf5afdfe98e0e6d920f7ada2eb5c91624c76cbba2993a9c7a55021d127a667b39e235df4f81dee7dd142898778dbd92135b70b3acf59f6c29a2c9d4a7006ef11a918b3a2906264a15d6b529308cbc89f85601fc1ea1314d67f7566cf109165c7f92de1a18d70debe024349db3560a6e527e2ac3e06789468704e6b8f1871f16bae9827392b418f1086cc497086ced14b1249d6d8794f23bb8779d418648f2155656a6fda7440c56284d9b2188fa7d1736bccc9cff0be5b1e1f551ff8137ff5966ed9d0f7f01c3dff298e9102ffbd324bfca5ffe0968e66f9d82f487d303934f27f78b28378eb72c38272962a5f735d7392e5d333fd86de167269c17a165b92d31a4880a41e136f718960a919b3d7c4e74cbd73c73f921be513f739affb2e41f80426bb8cfb4564b98fc4de53255ce3f98b4d22ae6fce9190b55bf2c93861c1dcac101b5e16cf09991c5defa33f8d51056d934bb4b477b6520d4c7ae22ea7fb3109de7f4
+SIG: 408cefcf01417e2dc6a8a18284e411657f039250c31278db2819f9eaea4293fbf6831a2801fc1ea6871657b841e173f451b0d575a9379e35857e8c7297fa1404
+
+TST: 1007
+SK: 4b8ed29731f104795e97dee7c8b401a02afaa9a795e613353d2b95001765027a
+PK: f22298210b09fd617fc8b35074ca1801e6075dc92a8f50344b80e85405a038f5
+MSG: cbb5f13a0ef2837b805d3b785109f9f2e0d0a017bfe7692d91ec23ddab7817330bef247fd91ab2c77dd4412519cbd38475ce0cb39b1480092bc738d4152b8a6d55248e3b9f32cdcd15ec5d059ec3c8847554ee47005394974d8eb23592d17f5a396e3c19f8e898370679fef5318c4dd299c6217d6abcc9b61a5b2d0cfef695d170ca20a83d6fd3c666c8fd1c10ad970e2fa6af10ff0ed0cbfe752246d03f3a3c6032dbb319bcfdac4dafc50bc3e6bf595f491dec388b3441b8cee0df91f55cc7807d07f8f541ed7322ffc39d18f89560e4123aec1d77969cf1877786f4cf94b1770b1090655e8c72eecea4572e46f580f963966db2a1085eeabc57bf4a84724b9c8599a433abf58bca804091d3d5e6e5048ec27bf8129b670cc2c88d9cac471859f469b918f3f6d70f7d6663501ffbefef026d79ea70927ccf6075ee5105423321e11aee9ad16f987efbdd00b62aff698e521adf9203b15e9f0f3ad07dcad9ddccaae9b490247f12c311dee6b73b8f9124fdce1299b47fb1914cee7e3a07814e312c3ce56927672c51b3185980cde57f3a759b50bcfc4cb0753b954d97135deb2a0532e98b66f39a7c08cf4d548539e2eb9f422f6649658893a7c3c25a4fc901f8c398b8c72733911a0072ed6bd2f4189389ae10a814f648d71f69c37e8295784428183b93c8013b964a9fef86b48f489316bc222e96b3bd15ff149b96820329551c15e0d095d1569b1e2131c78751565c3041f29785395b97151317f62e3582e407b1649e60d03a8599120a302a4695fa862b4120f94d22ecae72398d2094d108ad2dbc1b959735902142aa5fe6e7996559f6f601448aea02f356f8dcdd144340eb3619f9865bf7672aea326c4e93c99f0ed1f9ed866be15d3af2675f6dd6e296602ca373a815b0be46bc2a3fbba06b8805c731fe08007daa06050961b24d14693a72898ccfb8b8fedc60a4eef8ff79b6dd7592591833b576ef48294e5e0485942e57c119602eddf88b1faea517f2fc2e3d14d246a52cbd71a108c66b6cc4f2d45804a282ecedb1b0ad3dc3b4880ab2ff78b8ddde48f7466c14fed349e95b5053abf1bf0991126031d97547d143c2ae164928b61c0708af8ca3e4f55154d13d75e97db4ba3e69d36e9b37082368c2f721bd3f95126a1e004eb2a1bf268343ae21d2995044a2cadd67ffac9e1538175b3cc44db5d26f1d5cc89ca0e1c1ee8537a8a91d324c2e02e18b9fb9730d6dda55f72d843389693ebfcba7fbe1a0bcffb9aa284f4ae66f44a8b89302983b22736d0c72d6a044e4291624243a4e0ce65d5e5346d67fed3760ddb0c510b50ff3eef0a18a267de730476dd82dff7072cba0984825a004dd4bcd8c37fdaf1f683d1d9380e135a95d24b89fad0be941c548251bec90ccae015bc0567da84b371e50
+SIG: 2345886686eb39b5199caaa9615bc6b4896f076e8bd736c0038a6517f9c2b167e759f37372268a697e9b78605f2ed94725f6905a7900153fc9e8beed31ffae05
+
+TST: 1008
+SK: 080d7f76182ee6bcea894b1e0060558b3b125a3499df3973b8dd6693408ee469
+PK: 4124713d7c2df50f93055730d1b281daec3028cf2c1e4858d128707a23d6deb0
+MSG: ab0a6de2351b9a8498f68272d9a0a7a057365d34efa0fd34cc3bf862e49cdc302b2bd5a30d601a130ec4032f541ae6cb7ba97f84183d2d2581287ca701d7d7a9aba110ce58b946ac0824305df7929f3dd7fc9c8732238637e2b181d6e116c7f66e3226aae3ced1610262da1a0a4aa50a1b9443ec828329e4734d28fc25ab9c1de9b8987e5dc0c8131916c5f18928704a71e80622b1492bf2fec5d4b6dbe415c8af2ce3ef109b34dd5e64d56846f085935a4a5d1073497fb3fb8fb77e8f5d5e3fd00c30652e3c5cde40a335d14e5425ffba942885ed17bd36df506924237e75be84da821950b91424fd9f16c1b2c783e90f8cc2ccc7980ce915c7696b06a586730259e6d14588582bab9d2a39f69e98e7f2ae9bc0c2610d7e0457f26a5d66543be1d65b79c4b7c0d8ee73d0c2b67bf50d8082f006f96d119505873193dfdbd432bb1c9ee0d03ee54cf95d20e91f7f3a069b6256f42159cdc1e600a9a1c2f5a8e467d5c2a9dff8730e6be826fb2a1e6448bfc4fcaaaacdaa7662351faadc91f7caa7737dc82ec3d4b21936bca1bd7ce373ad66264af13241167549318cdd78e563827f85eab20e0b42bc554a712c0051a5010dc2f2c7db85acf6549f9d102c903c1be5a05292c30f21ab1b2b8abcbbf104723c63f0ebc554fbee42020ccb14f443478df77c6aa44db9a57f8fd44d97ea099e4774823ebe123fcf5016a66e837b2f65c1845e681ee2a7059fb1290cd0a933129855cc83c87e0b3bb61e44134addd3637850246cdcdaa29f15c41a3d4dd2c1d760062124333124cf091435fdce711f52316368999befa4c80a39b3750e4e386289e4e2855e97b619b0a25799912408b7d58a4dd9819571e901430f6d555529dd630a1867459b8022d0e0add6ab4f12f60baac75979bbff7f6258d28d6760b1ff243c39e4bbd6cf9bea572a9c082d05adcfd4ccf9fa026f2c904b6e782ed709df7748a307cd2dc3a0fc4123df580cbf49e05ceeabc9f39e57b7f300905d8b310091fb953f3def36deb3e8bf372f5916b51597df024ce85cc4c36eabdc580b5cf152994648f1d7f35fed5cd10f6e2949161a3359b3034d450ea6f61cdf1d5af76d40102b60294f4e49078249026d62fe35fdf224928b0c49ba2b5339ebb192c5ab7f05cdb946e37d671a4a5ef2a5827220b4438cbda05736292806648f5bdd52420fa76b84a6addb1263eb0c500e81566d718d5066026da097054a86631016ddfb706a5677d502ef84aa73b5863bc40fdc42cb7321ac5f00e2928fed7b0418596db4b6151dd6bc6e818f0253552bf13741e69680e966c92c293e13c90f7c9999bd1ec6afe3b4affb47340c89859829feb599db3a8c3d33fc8d45fa5381078ae9f75d85c1496f5fb5addf4e4009b764bcc9118e9275dc7219f281d0d1ef7158
+SIG: 185fb1b6d86dc4444810cf5ec6fef0abdafa2a6fccb45d11cfb54ba16a6843f280d380471002ae0d71508556c78ed5415e42338c161f2b621e74cba4f6a1d402
+
+TST: 1009
+SK: 49846ada7ae684971dd91710799090b37fe5ad561d72a35f2efb405f196ab0ec
+PK: 4d370a8194a3045b09b3bdafa27fb9acd59943a54ae14cbaaa2200eb0f3da71b
+MSG: ab398d94f928b1d42102a3e513ccd1cb10899011039410a8888bba26df1a0372bdba0ce8d854af51e9330a8daa93c10580906a8ac72d294aeb9566fe1c78ba8471c06c4a8a75113b34893f6276ed813292053b956a465d847d2ece86e2da8a9f0fe3db52a5aac746ef96485ef81f1362b5a42eaaee1fbb0646704471a21bf76367beaa07812b3d32adcdedded7539e3a501b83c05b19a49b520ededc9a78a5fc2d5012f1d4e381844e792ed90b0f57bce375c75a658b2c78c6ff7d9efcd4bfa35c4768cbb195e4823d9bbd835a374fa04ca1eaae9c566d8fd5aa7ca5efe0dfc317fffa409ef1022f1c3b376a935af557083e95287b07a98ac6c1b7bd8bb26b60fa7c4bc91973b201b29922b4b9d03dd6882a0bd3b7d9e5b81ee74c36bec665e4343c8c9ad336da3850c9b2697fe1cce29c378622a33c248f448c88f48df0260143b2a342f1ddee74d3b97ca3e1166b156993dad30c49d810d74048bc6d467652004d7edb65c6dac3a2c5d300b97ee3a10a9e14b69f3cad675972962e1f8ed97547adedc47d1cf3471ef3b22fdbf78e34f31a3bb7669c41bd9292c380bce9a42d84bc27ac928b8bfc3c63d20ccdb478df7ddf421fb1cd905ffc4c04786fd9aef06b8938ab8ef522217b2c04515f61a1c312ea83253f8458c0918fcfe874e6e7fb11275db2a2ec79a2d868303233c1b697952a3bfd3ad0a6f6cdd5e72cc9409f7410a40d5b4536dd46eb1611ae86703671b3a0515a0377bea15654ba0a0d1e4e9602632842f2acd4ef993236e993f2650d59923f24e2cd30932d8bf8aeec644472ba46a07881496c92a0135c675aeb0ce6181088db8f156cfe7435cac6c97da637db4a89f51331da13731e741fccc0355542ce11efa69d0538d3ef127aa68745ed3085d29da90dc583701b6b3a70a3ef3e16a924b33203b92396c4b945f127a7888fa05015c0603007566729237cc0782b30c020d9959547feec9f4d676460bfe0c5c19ceabaee0682db8be69135181ec0fdd9f7a66d50bdc379e4a2c598178f9593946aca6405b177fcade0f86421583ed67eba187222a1e44495b3ae544fdca28e2c14485eab0471aaa803c29a9d8a48926764fca1df51407ad33ec17e941e6e2617237a84309873dc71365587bde4274b5dc327ccb1e1e9c857e042ccca8d8552ba288c978cfa0af99d67cd034060628e23525dbca207679ce29690878448553cd38675bce07bf97b9317dc44468b768b158b0c111d63a572235655c40e16597ca059f40c3d8ac5bd61a487c15313846a704a7811b8bc0cee61e34762b6c1b7cea1c46e6087e9a36f89918a258b3fa77620be10c184c3fc39739024e98278fd65b82cad83699f3ad8c6eccbec8b7b1bd7914d3f6c3d02bf40283b1c1f1e98e308beaebbf894b8f5e91bbbc62535f923
+SIG: a5c809d1ca4cfbb3dc70a2a3a1f267c27330420719e3606218a1471cac57cb674b9b42827c5e9a7b25c8139c13dff60bde6c2dbad3a8361197c1fb19d2cd520b
+
+TST: 1010
+SK: 83343e37ad091a85eec370701b81a58f9370a4b0423a070d60f92d8d1809844e
+PK: 50b68bf726eabca53ac6c90d4eac554703712d22105554f05bf79f9d08fcc493
+MSG: c7dadcac5d8795e174b69138912e70ff41e7a725faf385b773ed15098972b30d9b739372d975b480ccfdfc580e2e2ddf5e3c27ee791279ab95e4382b1459dd8d41ae360d4a878846692924feef390c0dbbfa35e4b82d7cbc33ee1581c52bd949385b2ee40263a57da1174bb4acad37cd8ae2a6b45f7a6d6bbef5a798ce85b9e05e7647e334ecfc776378de174c497c0f4075e625af7aed502cd1cf7f588d0d807f02e32f4300f228a50a667b5ad1fbbc17e0b3c57051ddc602f576079f6fc5889b7f2900711334420fc666f66dbaff4126336c353f1e5b564a664537f83786da5c5627745406d7b2fe3233bfd58ef464a06c95cfd0b988a76d053a644bcc159cad53a7c5dbb40eef5cd047056a3f09265b1325699c7d159d5c902440173357ffab8f7a5e389f468c333b782f80170ae90983af153f2e73bd2bef125e3d3868c2ab9ecf03aff76ecbeb18167ca2f711cd565851d7f04ee9d9b01b6d83a7605722620d28c84d6c1af42f6a769258f53c1f66da36666da5caa9bd9e8fbc169211b1aed9c2558f6aaf5b145abc721abb00720194e027035468bde3fe0b88884f4e9b26e771e6c7a0a55ea36fc50dec8cef162f9bba5b4b16105afd6e374e038d5c8587cfd7dd88290b2c9cab45a264d6540ea1416e6e4e74a12f45a2ef13cc8a36e7b0a26b902c3d96e2e2229202e25765694b943373d16e600bd786d955a4b3f1021640c39a0b6c691500281ae0d098cc7f385e18a07e62fa4a101ef5b78551fa29bd15ee0353a1a5ef9b216e8b0fa50750a34162b635a0bc5e5d7230aa19afa128aba6422d38eb77a3f0bb9dd8e4652f12070a37361c3725503c9d22e2face2ea74a7002406247dd86975f07575c9e7c6f41b53b26d5cf52c5acc2c5d98271434e9fa509c6dfbd724372aa5c13451aae393de0a186464f5d337e9f627b4f1c2909467065e89a422ec40ee1d80a133900a62f4e4f7e94eb72615e7ec2996c6c2430c3e957ceae2105a1e90eaeac0d31affa9f57926d71d972a9a2de11258cc1e728599c9fb3872491847e10c67efaef6b696a030ff0533a583bea1d04df25f7eef3a13b8e31aad133857df1b4e5ffbdee37f40f38d224c70ae04ef33b41b02e7191a86656b0d72b2cbb53c4908ca206f75734b27708154fcd8a97429cfd1f2da2429778438003f5b5b9c21d9ed23b8ad8a228eb4f65c24c1c59699a5c90aff773e5c676db362a1930ba16aba76ef8daa42b3eb2ccc45c934d23d4929a7ad9e3ef468b06a4995c80dd236a7bcf3879d8b79467f72b3384c160cc181714e92f2035e7b972a2cc5242d932525eae7c50bd263b0fa09cbd9d6f984b9cf6152d9a133c27843202d1e87fa5a6e1235d9c756bb8e68b05b98da54195223fdf0210253250633c11c5f60b5e67d7eefcaa6c2daa523137
+SIG: 9c6989cbe17e16caa253ffb1a64a106fb01782c99b1722baf1acaa42ae5b36b79b2a2cd8fc91f5ad8923817025a77825a05df8c417ec53c4a3aa1c0efd5bbe0f
+
+TST: 1011
+SK: da013221b2f588af40e211a0f975d44f9d65028160514c396189f27c7b0666ea
+PK: 07117c6b0db5b6fda1edc4396c47c22b54ee0ce5375c3ec633c83afc53ad6ce4
+MSG: bc93ee1ec4728ac636a6248fcc4551c9d15980db8e5f54b0ef075a71970e176a3cb9182e32da7a8c2ac0cd7e595774575f9c83506a606face89512135d032ab05e39fff9c8ca6c25cd5d78ecc3ac323290c9c81626735e190eb5ae345ca7a958409f7743b0b1614916832217c57eee1b4f8e622ac052a93dd5b39d0761e40e9fbd8396f60a3bf6660c5fa99cd8139f68cbe0894e5c67e168cc74b2724e9d91d6000a0cec587a11463f72ee6ed255bd87eb30fd457596f688ca0ea73f30497238de21c93fbb1294db61e4a56089106d1cf7ce5a65ec3d12170ce7840f088a8d0e3aef17e531de478003570258e927f156e7961065afa666af38582b353cc477ba775cae45946d08db75215914da3261b62294e92afb381459c21dda4ea6ed795f79257c094dd608dc8e1b7c40cd29fea222088f65697ea88895d10acea8797360dcbacee269c606600adffdcf9c7c381d0ad6696967d9ff03e61a24906502b295e76f4d0875655b01e6ffcacc8ef01129c72a5846b60ec80017374e75d306403d9eccf26495d298120a0633835c5d1eff17c9c62476f752c89710adfa4d51617b5918173cba722540e388ffbffb966874db00404d06b0ce1139ba74143c76b8f4d33b2116e1cce175173a96fc151ea239bfc20d66fbb6f52a666c0e81cc2b80209106e2480e4111c70e7be4aabb68422f0b8c6ba15c142f82e6c7f378d7800a09eaa4da253c2fd91e1263c6b655bf70255d7e3bb4775523a0a9e7ff03797ee3ffca8a50d10f20d5e5a889ec5e334ef26cf7998b0836f656456888e137f39d3e43e2ce3c6ef540d95d9a20c42cb8ae2d9d0f25a891c363ead9cc423f9a323fe232281fb67f5be1c0784361460468a87e95dfa35d7f0ffa2211be6b5fb32d42ba6518ab6ea93780f431d3006731be4440e712974f74baea419f4022fa2502e1b2398e9386167d93eca92ca60dd7d91fe82324f682d94aa7a86ab034f8a9e952e8fc95bff4dfed6a43313abb92401b30c33c79a7ba3efdbe1628040fbaf443f3f980846fdb283dccd93fab09708b7d54861d74b1fe8f10701f211ba3d390e8a6ae407739646a79a58337a717a872009c2df6761c2425a32a0018aaf9646470cbc87c3a65c0e0effbaa528fe4783c772ab266b8f28268cf14af234b15816d1a3a491af5f297e33d5729715d512c373fef5ecc3f3954a60a2a0f64d829474119ca1a18f10578d04d638d5eeafc371a946f6ce7efbd2acce34e20441cde9a37d5a87dc619b0a727596cd12e15cd9784bb91f1399a59fc0a7a4af68b0d575d93387172973375c465df5d2d5e061a2a9b23b4915a0a8b8c1f0942094af728c8c31145fa7aaf74a21a3b032bb09c392205bf095bda986e5dd6627c1e417f650326dfe3a9c9994c6e0e01276f91f2987d2b85deda965491
+SIG: 10cb52d610e4a81d32869bffce3807e6391f782fcd538b554d09037fda72285b9662b1b1107c408178ac009f0525967388a7d85fa12359d3ce3875037dcf6a04
+
+TST: 1012
+SK: 5a868fb75ea0721f7e86c7bc106d7413c8cf4d033ce14005df23ce4c155bbd27
+PK: 6d1e29f39deda2bbfbb57cb01cb39e58808278e5196ada1c027646f20487d252
+MSG: d5aa11825b99448c80630623d8c746017cfe3de6fa8a0c6ed6627127cfc1f84d4e0a54e6a7d908d3719f1421d1d4c78b3cdd94769ab6033bce979dd90e106802eba9a03295d48f9b9a95d57ee7745402a48023bf3bddd5c6b91c773e491913a38ac3462605cf282deac75742fbd27529276e81dcce8dff9605035e8cf05df6a43db151f0415765bcbd1f1bb668ad6273b891c0dc4f3dba590ea82f8363769b9c77511947117375dc4904d48b88b68a255b28011b11048194093e98207ab1cf756ab8331f8d6f9d5be2e1190573e95e710f2a3501b53aa0825d6c12dcfb94ac80dc1082cb4ad262e6d493adceb6bc19145fbf738df76f2134fa04cbbe44ffc55ffe5f9d3e9bebd159a001aa9bf78892a16538a520823cde5d61e29a56a77ab96e49e300d9865962c7e7fb8bcf5de0b938297c3f4d6f6021e24dfdad9861652f340f421e7af2c71ed9a71587fc753b115549b2f7f7cb29690ea2b158a94cd2bc42e7063d619b939d523e3c237eb1f40810de0b44aa6937863d629edd5575e6c0475261b627473092775c84360011d57c57209c2e875a3f8963e8b241a7aa75ef30c4a718ac4dd466dc7a3e40e5874f157a849ed3a3a9d4aeb7d94df09bb55a0b2bc9f8b695c37179302367606367c5f324828ce75a944f50703a47906a8088f3a11cfe4a854e01f1741252c486337d06b1cc6c6b9b1295431ee07359357b3a78ef5075b65d7fed5eb742e5101598444b46623f89a303acc10c732449513b70dc456a79d37c48e5e726c2f558da0a1c46efbd2d920326a678b8a22f0944be4af55b6c71f453fbae400e6acc04e0e95ca200167e96ee98ea839316da93a12c2d76f11aeebeb78e65ea48f7feebbb137b2ac67eaef02a2d9e6471dd634a037d4f5d35a2f78af41a8ea5af5bc8150a99ed68a6a0ccff2b1d7965d8bc3ef9285ba6421d87c33aad8103a587be01926845bfbddbafc69c4b9252886720d418509f40f3dcf55765dccc3deed8277215e69f056ba31b8a30b50094ea8f144720760c8f8c055cf1a86964ffcbb8ee1bb2181276ea99a7b8e71067fa310ba4471e84279037bc492a55de205548e77b014504ee6664c4988cbb9ed91ff32e2259ed4cfd61a197d0dbc32c68f6549c0d29fc45f36acb26b164de97ccdc37900d93cdbcf9687ef53f1f4da1b1ae4225b884209e81ba4311520477ed4211b09240bd7b825e54739fe25d8624af04b86f6d1106d18170e5064d1a73c1fb1a27b289a948d771a2f6b8b09a635db96c6251c35a1876d369626699416c0e40298a681fdaf5255f58c2557759d8f5df148dec9dbe1ce6df041c36f83e69ccfb4aaca5cb48fa6a85c8ff66061524d8b11bd7ffaed99d0cd45c42010f21d36cc316ca860955635bffaa7d9aac572dccf3153d42ee8a2b12baa57c160bd0ad
+SIG: 38c48dba99a6524a188d5cd78a98e677dd263ef6b4df446b310b3dd89cafddb9b17a65bba8e13968bdc25b1d84b6e2436edf31aa756e3a48726d6f91c808ee0e
+
+TST: 1013
+SK: c54bd3431f2659281d31e93b30787668bcba6e5ee47db46e50deabe3f48c9ed8
+PK: 1eba6eb3f7f24cdf80abf8a19d308c24f1e25ba15970eda7116707b0f12cf932
+MSG: 6f8cdd75e1b856bbbe9cdc25537fdf7e8236cb029acd3984492110d0c30441d42184b5fb183da9f3140378dfa7d74ccc9ef500193cc9579fffa60bd2a8ab9e09581500cf06cd35abc171d9d12c6580d9682f9f49fe36d0a3177238fa50e7eb4c27e460f5e4580a56568a19e03d95b0ff4f4a231824cd2f3442e0ba400bc11b7a989d501f5df35e4301508f72a852014bfbf4001e28095473d9659eed6067baf68f92bef312c09b19aaf7c4fba3d902b9f6cf952eb9b9a53ca8bcbd042d842e9853b672a1d009d823838bebe5637c4c07ed1b1948554b23b32de1d6c116f933b354f28bbb779fa6548c48292b612c7f551a75fbc46c02736bf99e9c8ead56f05ab0427a6ec616e3dcc7757efdb7628d4e96325fe0ae254cef5cb7a704b35a920cb3fa2a03e961daf371821be0b30f19ae4952441e08a7d22f5431390a5be8097fd5797a1a6297664da42c2008d0321060ebe3181eb795a728925808da7867293b7208f377d3a771185e6d2c1c8ce18376fe3c0c1458c7f5be34f428a0d575931074c97cbfce8ad81313ecca73a9f3db434fbad4bbbff502bf7297e17a97a8864211e6789ba192036ea59a34d84ff2a111074c3f2373b10111b5daa789560cb35490954c88ea00c410df850ad00cae2f28e719fb06716988a9bb0bfc6c989d587e5685ae883c2c2e74ddbf915c9856aae8f3288fc625bfb2fe268d74f59f8b7d8363749769169007d5e67b7d0b8c8f5a9d9f9c7b745c0a4294762cbeca42d5384961e921a7efb65da8d1e03b6745cdf308097fb13d64fd2f8c10fa9509eb2d91387f00645ca7d0483b2cd14c206b8d7ae0a3fb7c09bc6843d102adcda19f8bbd851eb683c4435ceb4b3d23d38f56d4d1114eef0fc6f24df52770d8f1f3f82f4720e892b315244ef56c36b23fcd407978524140382e11740fd46fe4299923f52b88b4a9cff4b2b4b23a2e760ad81c78ba876931d9aaa4beed40fb10a799eb30d37f754778bac85bf0631d852be7d74a6431f384a4025c1091421d67a4e9c94c1be3690c6bf81d06bdaf32feabbaf1dc263f273a0b9ed65460baefcefcf6acccda0edd23df9e05128e29d661c4b44bd92d640faa853afd8370e563b40ae0149a1428e06e3dd8e66b79da21cc753ddc476e3d76e2f36f2b6c6bc1b65087d5f86c8ac354711a8c08f3486e479d6ae943f8846332d4e5b4bb2e8257e3083df4f81dd4f0c1ee1d97182166161a18597ee0b959de1c45591abf7c51033d7c66352deeb682e777aeae2fa8d3a77f470db78ddc1b1fc82840c4065776d9bfca9d392d9288ee9132aa3e4f2d19d0d93e01b666f3647abaf225c292419c8a82eba3e11ab103846fcd4935f41241477c0f152b7965ad54bb72bc3de2e0b79d6225e8fa7a6286b5fccbb35822e80c8bfea74cb48a22d241385395c2
+SIG: df4541dff1a9797feb617f98e4b57aa7714131ee8ff545ed5082e3568efd1c399cdc56f5582991eb8785fb33864eef7f553f3e248262ed548a1a6888f92e920e
+
+TST: 1014
+SK: ea60da0179bcaf6b218142b1119046ffe6d85a741b0d166230bc6de3304f6773
+PK: 506b2ebb49bd9b9ff66e6b7b1fab9668cb181b4fb5e4343dddd3f8a9d702031c
+MSG: 612d6ef6e4349ffae516e983e8fa7b52d9fd134282240d95143824bd4aae03234b76a8cd6d4068cf009e481c2685361c755042c4e6ab8703ecbf8f020cf5739a4c2a03c3731e9cf75aee25966153b9711515c6c39afa95f221ac3395b089c97ac9b514e17d55f796a3ecc135faaaee907aab1029647b48ac81749bab26627cf7095d74c2fcee35671c8bb46053f5151b0c2e5dabe0f2d6aa20413305020b2afd9ee3387b2c9ed0bc3fe2902af4100cec23327b0f1e4ca39ef6eaf6fdf5d5acf93fc868536d8cba401769329fbe93effc7ee6bf93a6e588bd551eaa512853952c81b245e5d229d294e41370b867808667887a6f9eba2a8d56a7a704e66b1c02f96e73895f483e44a5c566cb1af26573bfe2afce06b1fb5877e51ef3126a3f210fbf213ed65d5ca46c46ce4aa945bd8ca611e3836250f564f7ea35423982f9705fcd6bef46ae16cb0f6bc912c3f28642b8d87775b818e4e4e8061167899bd27a7e2fb8187ee9917d2d586bf9d499e8fabca83ddf58c7437eaacec4f444fb2bf745dccd8cae38944571dede2037dc41f0818a3d91e3020a7274c6674247876083d0e39746c9684061bf74ad588436ce1b763dbf4bfcf8de6e35c5a7626675c127292b21df3c16f81063322a75f3438886f1f0cebfc1a96f41384cbdd861b04f519ff6a9344d94f3d3a0aba8409dfcf18d01f2b5b455171639eea77dee706ea83dcd2b8b1fc5ec0d740761a5f05f7ec8d87ad1f292a50c8bae0ad32b03419a950d9fe3b3ecc4d8d3aa95e02b51b1831d83eadeaa44238635f9c65efe2f6744a70b9ae41ef15d97908c0533934412f79583d0e9b3d706a128e88fb51eedb65e46d8a2b38bbdd6455554967a8dc0c68bddfeae0f8f72f0b886c3c741fac4f91e5c491dbae9da4594836cf1d9fb6ee130025089aed350ef247bc9887a2050159dded1428ffd9b07b9ec2e3d4bbdc2ddb54e873b63f2475233e19133a14b6658509457008186d6225995a96726b529f44281aa24fefd1cff8f815d93a5986931662290b3ee16833c60f0afcef2cbc000623f3931909ca976a094e2b0fdb7dcf7c485e14988a36f19b66425385f5632cef65d1d3414623ae3ee816e763a5f606466622be6602114502951cf0c097c1648a72e2c43d9afa9689f2c3cfe026cdce3bd1bf9ebf777562ecd8ff1b0d775306d900443f30a843310b8de6a38ff108b723913d7899b9fbe7c3d766ef8bdfb6d8b0b52956cb1cec9936d70b487c01440a842b2fabe38e7b8851a387d358be7ef12a7e4f2b527e83090d67eb013c9c2cfd3de5a1a3f99748a41f4819d9036e500c504c988bfd24f617d6ebdcab2ddeaa61579414f360b469a33a6ded96ba1d8c140c4ffc94990d8adf78cd38780bd68663d1a0ee33f537cdf892d562e82dcd1d912cad38d65567d291406
+SIG: 27fb6b5f06528a64198a3e7d67c738840a8cff4b482b4d524b122d17d2aebcc0389be2c6e28e2cdfc484c18de425db56cdfa561c507cd970602d3a385d3aea0f
+
+TST: 1015
+SK: b62c241878273513e0bf6f33d2104365b2ce9c5a1b786058e9c5b4d1d192f87f
+PK: bbf6fc5198f3fba5ab007f8a632d28d1af865d290fa0a90faa9a9b5b9c13f3fb
+MSG: 26a3c26a5a189cad407cbaa3a6867ac0a26088c75f9d0fa19bd50274cec5755a497109a473284d6fc81ad4b9ec29fa7ec9764fd3099f060e36836552ff2413e3d5095fe0b1a8bfcf67ee06aa9032e7bb3249698047714d281415273c9834ad9eb665a7d97220e72d9ca73f31afa7738675ba3162efefe7479a5bc4bce2e8b7af4741d703dc9bbd60b4cf4b9087f6cf86cf53aed02bf4ca6a18f607cb52a303d78e85ad88fdfc86dcb7187727b03be227745bea744fd006525bc59a4dddab915cef40a8f30802913b7913eaf974336552e2f1456ad803dc58c9b4b18efaf7f7e357e2cd77d138d90080e296d1364a2f324d3e0d6edc20b8bdaa9d2e871f5e7b051fb6fcdb5595f21d3f8de29fb78678fa479eaa32579c784d513ac5f836d954d0d3fc0e5fc8a6eeab90202b4c4a2bec24cf63ea67c470096218cd431e883105fc9c27f9ea77c18eda69bc00a2242bd420f095c9b9a92d956ccc5a8572b057a7fe173eeb2a3166cb2089d113a816462b25805b8abaff5b0b2287c508ec2b8c34b2195c332870d3cc396017a16b9e0da6182d071d3bf363d3f1e7b7da11d711250a58afd74ed3e3158d4718bad4d274bb3444cfc318074b53beba44a2a34ff8eb726e4a1daa911051621651898b887169f62b9c0f4020483ef544f8f572fa6a6640a4cffce976cb7024f847bdc95d1d7ce653505debfc6988ed289dd47a9eb261259e3e65e45fc9d714946935cd8ea13bc6db5eaab9e8b10dae0fdd6979c2035cfb8098252f2205443b808816bf7787b7f1e78bc98a7285e733d45fc4610c20977ca3229889bb8cd2b694ce9e3fe78303af83e106422542fb7961d32eb1d2c5fbe60751674b074773ee0616e02973f6a74a3ae4664a2650915a3e10493b9e66a39fa5c89c61d44735f107d33757ae679b43a8d43a01757ae1f3279e862442e150715550ee82e49c0d4943faf13f22791f0e66f24ac50ab3c003852b21e15b2f006edc2cd6a879c476ab5b352eb1099dad4c50372400faa5498d78c6b857034c25caf7b933faf6bd7c59fa3da57397b603de9cb9d80e51f7997baa462acd537e2c4194c76c7e0be6512bce4d63660b36c7cc46631fb9671ad8c5d28e2f2ee2edce81954421b8a3d9ff6f66699f4bce88bcb8ef192c262a74ab7e191eee9101a28d4b66282b5122093d141c6496c7aba4d352e472ee7440e05af60da0cfc93e303642ba8fb8e5c568687abd63afb3ed6a32b6dae56a7e5d73debaf41d35ca36adb97a22c0adbe718bec1fa51998de9b4b96a79c5b9655b0165d5e1b9a8cc552e8c9329ede58df74c67b2ba1a842fd3e8158c1fea3a99b56a2c2a96207853d26022cec170d7e79944d2f56aab1f191bfd48d725490ca82b8d906f0680e69eeb9575774fb9d604513fbc26f5d303b6885cac0bf8efee0538f92
+SIG: c59039587b38dc141e055a93850104d629e380705b8fc918847c5e2a352da3a02fce7f7199f4ae2b1e2a59483418932e185f7e45b5050c642cecc7e781998507
+
+TST: 1016
+SK: 0f77f77a1c7e04bda8e534f4e3eff9a238cc14876b7e3eca8bede1923a336406
+PK: 1045ea9fe214583a0cdbc494932bc44afeeb080bec485cc234fddcff139cce00
+MSG: 0ecb746dbdb0161421afeb7adea7a37c2ea4408a592c9d781ed6ac6f4ee5cc65d5270e4cf27632f7c5c133d439b78d1f71aa6dd80713d90b151e19121bfa87710e84a4850a3b5b0265ba2603d0716e9b7e1122109c39c6f1027fce18798cbb4f6bc5e4d7aca4704690f5c981510871c313595798338681107f2b5794d46f6e0bde2cd064b3b1fc00ca47188bbbc1f4a0ce305cc6d8a896920eb9ebae579fd3385f8f1f35976288f4c58ffc4760f359b003c872e9a24055355ea9585e951069dca25fd0cc0b9db52aaeaf19d43f2eab4f835603ad12d2dc49b310256b94bed54896a16b69b09cb4c8ff5c23cce5593d87ade2a82ada50859e1544c18618a65c007ef424c9854a175b6e6c0e64b2c8eb8ad4d28b977d68e78169915198975394d3b9b269cab0d3261b2b56cd2cc4bddbd4f1439e0dbe2c9b3f3f7514edac5ebb4622b92a69a840a9028550b221db59ddfb001396f86392a17f08ccb194cd9e1a0081d7dd9cca2357feb8b795e517029f79c82a3be6f9a031dd1af1e79e4982bf8e76b310f9d355efcd5b1efa9f359c17cf3b510d513e8cd5786a0d3445dc59a8433a46488687b0f58b1bd6567c2af4873b51fc845e767e243005192f8f0674f281265a55d76cea322260c932cea6717adb98a2dda8c698e2e89255feb77da7648167bc1e58877feb72d1d14b0c304f07372d955675237c49f7a6dbc915e6814abae6cce4caf9f48087e9dfb282d8f340377c1e29c6731ccc2667da6695b712be0312d865111934f168d5544365ddae27abc64aefbcb322db7d97d90d957a637bd826c227e9eb180b45a431626a6fd890c0e5f4ed7e856474752f80b5aef6e73efdaa6c2c451bd74c1ef466ca3aaa2573bb52cb2b1ca96a1b574403ceae1cf05ffc53430e1e4cd5593bd1ef84bcbfe219f08160d166f2731d99b8d7a32b12991f77775a267ec08297ec512d7b72435632525c04000fb00a793f8b5f8f3747b55359df21b7e2c49f2b0b9ae082afc70a146871370b8d50086de00f9448be8902174ba2cc851fa379dd7031ca457a8869af4b6c2729dac519556b8bb4ab519ef1bb024ea8b7f01771c9aab748e57381a0192a6e398cbe6dd9f367cc7b3354f83b79bcda46b793a4ada85549c8d6bdd6168124362ff908aa1a0cb78aa330c42d5a5d481235acac3a919b969c50987266d404d15d0e706fd9007634f69e13c56ec47133884fcaddc16beeeed19e0cd917aa496367867dfcea274e1a47da774f3c9363021e7c8d6bf8f00053facc11cb68a9d6e1fc2d6d19175d6324ff7ca6c23058b8b693d8fd4e0b51dcbb113543f2fcc0452eb9d967ac0fa9b23e9e0b1da8d83a3c1fc9e9ec971f0f67fc745bb17376bc46245f528cb6e5fee11bcdda867b7f79019cf9db591858230aecb4d1e93d167cd86b42dd879a13fa0e
+SIG: b20b9c4246f0d2970138af7dc9af629b68fbc37df87afdcadcb545c1768376a09c3babc3eb1af3b7519852f75fab1c9c119c662c5877fb2f7299cab57fad3d0e
+
+TST: 1017
+SK: c5a5053477ae31158e7469dd1504867650d46f1589067f5cd881caf25c26cb21
+PK: 70f85db9807b26fcf3e6690b91724f7ae3d20ec3604ab7d6308d9094308b2d59
+MSG: 8571ff3903486a43a6126c323e7b3a74141d1385d4bd703f19e2d1b64b50281d27168ae3e769c6dd9df7d97864fb37822f0021852e3168ab7d845a6545ed0c377d9f7c048a2b96e8dcf445779684a058c2b9c21ac68a0c341d1d6c0981456457458eb7cebf66678740777eca26e01e1c8f53b5d4756cc5f0b90f0c5db05393cd4b8e44f6810caa5a116a33577724395d413af619632a6fed14e215c2f19d105ce2bf1498e6d2ab4f650f61ba5cf6d0c73bbbde98e30429910a4e67dfbc717cb091182d597058b5d765d097e6875831b588aaeb3e7327e856b42fa983fd254ef1f918b043d1dd3d7b7e30b315386eec91e7f94d598f4beb3b27b42f4ee1fbf7afb486bdcc6081ccb867f04111044f4bbbe3c8122edeadefa9d693906e0d6e133bf6f2da6158feedbda024410f12086e7accf1c68e1557f00c14e9c7ea76a5ed1337a054ac2c949c05977e030274f6a4f2a6b30a15c570ec9433f74f47528087c9ce9a6292951c54354996fb283c0dc4cf33c001bc96875ea6e1f46f837ff18dd9545fb9934655342b12c2990b9f1c6ff4d66489d6aedce75c7cb03ac134bfd39b181dfb7f9a97ce737fe570ad5f81345939a6de5a40a33a0e44bf957503d5ca0283512e57fba8a3a6f2c390687b1b7708676e0fd03b7c188d4561c1879163eaf2b596ddd5f3c1f4dadbc139c2164892820b2fe09cbc3d19088076364510254f2b6d410329e70f2e5a945bbacd2ca89bd4b6e1f5e2e1d4f4ed2fe0113bcf32962f00d5c33b1df988402ba0dc8804c1af66ccae2670efa3134c67fc90feed8d8deedccf6a46f22940454af2bb6754cf235ddbb0001c6c741bf874bcd8d41d9dba8162581c3746d7f30e73def69415af5181c149914295122d45982f94943e20b0ffc7fe6ddf19a022e87a52133357a1e80f37f28a4c4a8a61c148dd875c1e8ecdcd840dd863e44d9bcb16b6e5af0147b34a7a9052c8d3f452013d2d354f6803f9eaf6056f3b013c616e47f398819146320a5e3dbdf16843ea29def262cc9a343672cf96bccc6e87e6a6baf0712e6ee89aa60489f17cb72ddc44bad161587d87f54d67cc0a2778497d831088315ffeee3d268c59befe884c3aa0e0ae2296bbb60eac9097cdf8dc0987ceb1742b0586dfce79ec10425b28f4e64520d712e3f46ea83be2de6a1574073bc5c7557b8e25b6411184ea283d8800232c79069421811f883c2994e7b7e2ad9f8dc489c9347724394609c98909a6c26017b50f20d50ccacbde36b76ba646a76dc6a5b0f50649c5658bbdfdd3b5cafc5479a2f48ee51542f23e9fc92132060fd635eff452111cdaf3efbdb7db9e7d4716d0d6011c29118a55d4c1a436abe24e3cbf40235b76dd1923503c5f3598124e2df55a2d1f246e90de4b71645d5175b61b0174e7e57df1285ccf8c86b8382c258079
+SIG: f5191b44bd6cc3ea281771df12549ba2be228b51eb791b9e5ed2815f862aa630b56967cdef8b6af0b9d21ab8c97a6dff681cced9f5019713d4357cb3e54c0d08
+
+TST: 1018
+SK: 05c719cae06e2bb7d87863ab3150272cb2f8c3aa2421912d87f98e7589638ce9
+PK: 90211796fed3d53b81f8feeb1bad1ffc933e5f10d3bc1b36ddf210a47923df03
+MSG: ec241918418e60522042e67339e6649499f31a6c7cf8925f1f61dde894603602ae8bb5f58809821f83344f23cd31e64ec9ffe79a986b7e29e4319a63414316bd6ee20e02a50da44012bd2d6f9f679e88ed0c8bb1e2cad55e565789883345b7546f3d54b1b362b1c650502c019d7313afbc82689b23a3a52d8f1af9f81e188dbdf203fb5300b4225bfb6773337be6750b3db88ce097343f62ee2c118574ef150cbd4c62760c3e43dcbc39218bd6d98565fa389811b1a674f617fd756733dcb567a92dbf3855b57b1f4a46d5b8974b39ac0d0e24d99d2037c04f60d9140f64b07a77d7eaa1ce8a78e844b1dcf0e37424f3f9d253a548561a0375a8d4341297bfedb7048c7935e1481418f9bba9271f9fd6026224e78e055d8a0939fa2fe1dbc0fc7b583e4cff3490e1d0f610b252e30d8497d00e4aacb375f19a4719f79ca1ea583a2f8b1406a4aa5cb55c08b6593b676eb5c34abe89392d62d23308a3348b57affbba7739cde8e1909d3425eeb20926a977d3a94a86e0ba10b386926698827e86b4fd6c6180047c87ec3b31619d05a9df34efd3d76a836962b2ef604d07af0975eb8f3dd22594323802564c929b3f65dacb572b32553d69b31a197690a9bb860b080a77cfbb3c175aafce0146a82a4d06e8c750521b726ef1cb29d021e5915e5e8462ede5395445245c9ae882eec4b1745e11791f7621d3fe702cac1525e1f7b46e1105cdd06da2afde26475dc1f78df8e2d72b0ec3ef7dd956193c996842a432696538cf123d7687211ffcd090b9381eabec879f769aac0d3564e16df794fa24728d7172fd07732eab077ed81c22084f6f781b626dac67428a9ddf3b0db0465251220d18b8bf620464c51a578decccbbaba545ed442cf12c4c66f6cb6e6901ea54aeda236ec45eef886a7ddd2c041caba3a6cee339715b6ce97e765ec3479f3d52824a8194bec2a89647e8c63ff7645ff6d05367c767bc48cc96baf05d6a415b2a5aff9bfb217948fad357b98f47dfed62ff1285eb9f468f0f29edd75adc0c8c2ff6a565edb8edfb48bea03b70c447369c52d881eea0eedb08c315cdf0bfeb979c1c0250946bb100c2866b4169b8cbd44d658f0236e1e9f3aa13bb8e8022a38ce997c94b5baf97e0ba621f7e09671ce638c2a39ee6c6e25a688019dd167675ceaec21c6b42a7c8c476d129dcc693c392a02be91b87437a08a0ebf1a7bd976ba23774766838b8d6024f5bb9b07f3c6b719b4de15b72448048ab70db3d4bea77ba359b51b1ec17dbe8010aef0244a8079ca8b9a2a797f3b1fe047c8dd5cab7fb486829239c4ef6d9a38370d488c47b7c030e49a5500c9abb39a9a5abfe72e918b76384ecaafe1627266cd14e696c09d2512e312582a8a911e7b7bfa04c21819af687f04c5e0cbe9a2ce24d4d3fd12190b253dabc12c63cabfa94
+SIG: ba6eb751371df721b7707a5b3339edb55f138640b97be6334d6cda5191a3ff6367911761882a4a007f161b748cec95b19e995f2858c257cd6169256662301102
+
+TST: 1019
+SK: 5311f3c96101cb8b7abc622bb9326b8f513c2b16d294df797f56dfd8203dda27
+PK: 230b7002f57c79ae2e6bfdb8df30db3e900756b54af3968c670ee2f32bb11e0a
+MSG: 61b15be37c4eb397d9e77e00151a28ed3e86d50a9552bb4850b621763f012e7e77bb5db8f3df7dcf769f2d1d46d8d60bae40c8ca6e25c6410b60078a93fd05902114bd91045c06192c70c42c9f41f8161ca46564ebc21a4bdd8190eba2aeb309823072ec2c0200ce6498f9d72b37b3fb466774326df37ad880d8eddb32af673e45d88eec49b1577b43b8639111c2e0b94187d2d4e0173c000f4c37be845d68810b7889ff2a049f3f9f245ec70f21def97780b611400a83c31a79d93a8e98b608fdcf2488b068fe1ae4217293a9367bb734b5bc7bd8819b377f090b4f8fdbff50799c76880d19133580e1ddfc2b9baaddbab34fc6fdc078014bd1ff739daafe5476f3f79d4dbec216fa7680ee8e84002dcb9ddbc7fc1e1c8ef4f1b2a2081b9282243da6153c1fce0905cf35f83a684c01b04557ec84f7e9a94fc2882e2ff19fea21d2ce6167861ce01df8b8d3c3e8d255610b7af2596cd5cf0016734942cc714c272c05fda9d34723626646a46130182cebcf179ec00a6a173bd8577fa845c44d19c6997944755f2b4e468563a75e9016523b87ddac3eee21bcbca08fcc29546a43cbe0d8d10a0e8ddcba172d1ded150378e18b368c7763913e4b407012fd76a872d2cb04930b8e22b308243d4cc278fdf2e1f940ae89ac891b9e0661aee553937bf350b407070a1bdfc4f7a3787ef399d2caf4ec74439c587376c77be0c3de539d3ac26089765b9be10b9038694636e262d7baa0b3a8941a2015967639f6044c67e59bc81cf2fba704ac0df48da6037405a8e8b8a7ce3c58ef38a883538b247ffe18097af095242b058bdd1e3e245eece0a71b75b97d52f20d6d51bb9766b0da0fc09c8ac2a30fb6e7b32ee06dadf46d7359cc066aa94785d8a882ff097d78a86be2d45600dd3d3060125f01c063e488d5c3efee1bca1e58516455ffcaec1b81ef433876bf09ffa51d6f5018585224579cb67b56ce1c216ec0a883e06c8e1563421ea72b0c10d4bb31e491c2ae2fe8139f249ec927d806ba08db52b1b506669047f0c116ff37ac5ba6cdb1eaaf33fdadb0705c799d35ac6d9c80da90c1438b585ffd59350a2686b1ec35166cb9b69ad0f56586aa03274d782e3f858db64adfbf04d5228a7b1c4a2048bbcdb941153a436d742c38b58b4d7d13c9f1d60e152aa2792349a3d94e7e6b1104aa1b870998c18dd7065654a85281bb6f027faad556b1f532e7a1e22d564069289587a0efc9c1585d135f31233c41f440466e71fe9012e5f9a0d74a7282ee392fb0165db79ff1d3176ed08afe1daa66cfbf4305ae16ac1792334399f71b1917ddec270acff665ea05d184c2c5cd2ccd902b22f9b7195e66a65556ca884ba6f5da04dcd4617f33dc2b44a0ea742aeb2b93f3a41df7957a026797a585ceee814b1975f523d2db5dbb9be0ca649d1d45dcfd
+SIG: 3cbbb2608870dea1efeebb3fbf681e27705c35e4ddeea86c1b342a77dc296b498419808eacbc78855611ffbc9265a74798e51827e6e5d811816d3ca21e8b9c06
+
+TST: 1020
+SK: d290ffd93395bd5fc587d1ab511866e72b371a1735732d9d5c6a18dd465e9363
+PK: fd4aad73b032461ca0aae871ca7016383b2be0169053fdbf6c5914fdd6dd6f92
+MSG: ebd900bc910c5ecc4d97daf7cb5ebb5491500b7ad116e30660950709d8084bb6434c5bea4a8ccc1ed5a801bebb1a117878c03747003e148ed91434832e8966241a7fff22fe1d6d8c3c3ddd7215a1efaf4b07afee1b25673a1439eaac324e895d4be839e976c03ac001254876888ccaaf3912727a60106a87be69247c9e438c31fca8d9c61bae368c83e40901a99700dff839b513ba8dc42d93ce0987a2333470a9f983313f91988659da54039e499cd1af2b8fa0ebe750e24d55c2a5bd1ade3f680092542bd1be0b9735ba393ad5697d241e8e8b28646db27d2fb5a940e8faeaf0b6c9efda88615dec891ce732930813bfbbd0bc5f8210abe843beb5e4f028f49bea34f1e5b09eac4c6662c74fba39de4a9602a9694a85c7c1375fdadfda6a1957fc5b5987a687b03995e51697a1ab5bb6cb11b663c1372fade4c0aca8fbebb4eb54ce7ce36c6904eaf6eab2f34facd8c768c8d36da2397b1a02735aea72cfaad0393410db527a8ab236d4cdabdc888fac6f182148b132614425d390ff036e54855e4203c51203c1f43e37bbf6b9bf27f5b7e7c665151465401ac32cbe9e3350535edf48a7bc3603e2232e938f9a815ac4d1deec991ef9620948441f7a2f4a46e2c400ab914c4be51dcaad8ed8239cbbe977a9f09c02698319d9fe2a8c6eb60b799f29ae7659970d2ebdff3c6cf709bbf6f4bb55b9df4f61a241dec144b5993f087e784b97be1e53608c2e817ce3d9aaf914e6b723f5b4afffd2a6b9fe9d2d73915c7ad1ffb13efcb73c56238195645203984c99aafd0235f73b3f882e073939bf786657280138db05b86fcc9460b385ef4559204ecd81e2f12f5f062aa448dccc82ea8d89466dd1be46f82c4f87bf0db2b878acbb0d9112c8db6f51d35f6d42f749856b99e550b6c454e9e8be4da175f0b5e86be66c979fd878237e57f691f0d2acd028fbffa5b0668775034db1f21ddbe7114ee3dc0b44daca64c5a03a2feeaeabeb7063bfcccc559baf27f1ccb2202fa4d1b2bf44c04b2c2f81f94e281b1a5adc850da1b9479fcabddadea56a115bb5f06cc016f141c0fcb5e83ab248eaec90158d8be647aff12e7eeb5e57dbcc293cb3b6aacb55236d4a839a0620f4762387dd1714df5c135e3d9d6824f93b7c90d3ae38c518d607120c839570413b46b8ccd7370492d8ae5c609e00cf8251e2e7df81e5b4f9c16a5a539f0afcce41bb4362e5eaa5f940a1706f4afb6b14432c81d4ba1a33d322dbf10645ab63737eadc86fe6e0976f763397fb898637595dfd36934792d779e24c2a3f0bacf53e0473c5fda9c61284e4419bdc0eef5d22f4d9bf42e8c04933bb93b53c295d7ac9395abb6dcbd742b1e1bc3b0ea4434ea21b8eca9ae682d3315a41e9c3c3371840761dc59cac45da7e3813e28788dc89de355b5aee088090a38dd39d83e5e4
+SIG: 21704d5e626dcf6a9dcdef935429eb7fb5b257eecd7bf74acb0cd30ecfcf608d0c5b633a4a8a9ba2cc82a21e03355e01d85dae7ecac8896dc15dae0485707104
+
+TST: 1021
+SK: d7fd73d1d229a65894420e4ba734270d5a20758364de897d8555e24197453c19
+PK: 3c22772aec0a0c1559077f2cfd1f2465d4b48495c5d05f1f837c31845f34cad1
+MSG: c9225859d555bc42011af1b4f14998e6e9b0a65e2172713e968380fb6ceedda22e022c51303031d9931ccef2f7bc705c9e215c1d089d488daddaee155c939b6202ca53bfc7f6e88e1529d82fb45e02b5d05a82bbb9db5f415c58ba8bd56cffd92270b24749e56d12c99ae90c7800f54f55254ea42da5dcfbe0e1d989cd2f6897e232df04707b34af75fa7fec33e55ed56aee39c22b045bedd161083bc5514c1f81ca907b7c760317a7fd5a5a02a5d40e2e823e24ad96aef6da8ea982b5161cc39d84aa2ffd9544c11b634037ab0a1c8e36ac63019da1b2d995cb7bd3d62fe574deabccbd0d3ae7a56e5bec91e4ba3f3db8bfea88e67da62e88278a6e3b418dceea0589f25f7dd8ad19dd845089419b472efccc879c172b32ee4a4dbc2e6c2e865bb3b8ca0adcb71fdf89e1973910ef242915f33e236d2f7c8e9f1ee5b07c6e3c25360f8cb1460be87db31a291d4dee34953e75c675bf181bb7a0b7b5c1befdc86ada072a48f6ac755d499bd68d625d8514525cc3ab8f54ce15a871291778de1305d2219361aa30e332a2e069077c5c53457520379d8b90d24bd8a3a7700ff766231cb5697f9ace521a99e896da54c40793bc7c1fb1584bb1c86194d2fb7a4b802f30885e0ee8af88d6886e3a3a4d4c854649cc01abdf35319a0856cc65d092a386f8869625cd0acac087e9351790ccb4a865f651a881c3ebf109072774f940f5aa98a2a2aa3dd36647d0de83001aa7cdc031cc4a4d75dc11ce551676a2ad43a3f6a16a4bc5aee80e5364206087364eb8b2b15fb705380a072d7c8b51995943aa762e8deb4c568cdaa1411ab68f28489e1323bb6156ce2500b06e7793c510a3de29150840bfdb0b2b7b21c2bb8a7746167c929dd0adad44fed8f36e8381b342080b2a7d82a3f81ff72630cb78df91f7b65a44eff6ed64d48afed109dd7a693a1ba8c37e008fcb157e37297d32eba765a6c7193e73bd97647985b16038c74a084a8f25654cd8cd2cdd27ff17334e06adaa058264017a3b2da78e5738a27e350d882f5fae199278d4e50b8badf57c2141dfdc3cff99df5de86fec293c76cb94b6b19ba3034e460f84c280a2e6412fab5698ce890207cababca0a95b5ad533ce114bf71a404a87590d35fa7cedba43131c4ee92344839f25cbfaeb12aeebc8040893951a346bd28fdd167bd20f71a1e59fb60d55e1c567f478f027cf679a37d1d9db867e17bfdd60b347d89d322639d315bb7a2c9134f00ea03a367f305ea4d60dc9d567cf924851e469ea954ed3ea63ea8606f79f077339bfa2b51ae49baa0fb25377821d7c11ef9ad4bb4c0fe489acbab0ef000d618c7af5efd205d68599fcbdd95e28f836e0916f9ff548d0ba17da62536e74646801eeb6122ba32c41073ae04e42c6c1d5d8d22976a56226ddf4b6ac95455fb53099f20215b2ebc907
+SIG: 400c3505f1dfa80df4b26db24c027eb81977f0fb9b5aca524ad51200f4bfb133db834823314195f4edc292d5f530d08556e7809caf2339768aa38029fdbc280f
+
+TST: 1022
+SK: fda7cb084016ba513c7c4f8f7180480bb181e95695ea68737fa34a40ecbdf3ef
+PK: a2de3a0ef97298fd716106e2f3f54513057a40072d234c3518154c1bd12de037
+MSG: c21bb3f8e37befa367c913673101ba30d3b5c74bd8bdb09cd28640012db41120c2bcc4085de2a0f95c9215ddef8cb5fc8d8b1251b41527c67dfaa3f95ba3578391ea5a6629a733095fd0a43fdba40ffe260fff82acee2ebe980e9ececcfe7e10b2ed8c2e6b410d547a1286571df3d701174e579fcf19d3bd8086c0423f37117789f305d9670ad28c99674f52cf64211a081d0c6c3096da2c71bf5f5799a7910e6f38104a37a6557c2daef340814a1f830d593773c6cf48d83ea07294b94eb080b85d6970e28f4051d5066db10e961973a626a826aeaf8a06ec0d566b7e0c4ef60f0c5678fcbb5b2ac63f7bed06448a247b3d427b87086d33573fb2d7228c5c34ea6640eefa9564485a79638e9c97c0af84cfee7ce4a739220c8429e067143953d550668dadc84e7bed9ab070a5943390c611d75b1cb12873a37d9850661a0077bfa9ca9b8b263766c149ff0ee4b4adba25eaf7d7f501f362454256bc1269378ef3359a8ed6b960b86621fa3b613eb132122f49f2eb2ceb6832a3991e961cb0e78b742ef4d65e8de3469666fec7c5b874789571c5c99a2c02a053ff7d2fc90076bafe1f267fa81a3990f27ff14f03000af00c59286cb9bb98e204e90190ae2a50edef049ea92a1f785088f94adf6588fb43bb40fbe2324235cc7e168b80264b069f944f503692c949234d5b76bcffabe29ff9064bd7cbed9e00e5b7fdda4312eb801465f127d0ca68832a7f4ed0eaed8f559c1631cd4d34f0dc414d9fcfe849a91e25f3e0ff013a8cffa806ed8e93d08a1e5a757682ca3d26abc869c76f1c79007d559dfe67e78d8af0195808b0e771c71e64b5716fb36309c25025fae6414c28bbdbd4de597a74996c9da974920d59e6f4c2edfe110ff817fd480a5080978048865712058c5fe7b560b12b67f737ea6e2af9242cf07ad0a8a679f26430046adc3e70664cc9c0ee5abcef6d726b4e04176048b795be12851bdb74003a13204119b86864d6535ba095040a85d9781cf4f3480a304e227f787ad538e68f4bab014179e30d3fdef9eff11bcf471fa3a0bc74b5576f302d3a6b499f11f2ef326ac026c98db10e2741413f322228b3cff0f337ba2f294c78ef73f0e877878f8fc7ff6d10bce66ad6284379b80ca89327d4db0bf14e6d8f01b22ab202b716cc07e3c8866d168a5094bac5a495e73868eedc27222e6444f83bcf65acdc3ec89120bb50e8abfc28b78e6d980c775f4849a0e8cada80240bca245e39966e89a0344df8363a7dcc81b201ce9c753ad544e1124e21020d4c62deda9ed9b9d1f2fb7c54ca7ab09f383bef48cfc6848c271302a10fa687f56e00e0a7d093c927b4fdd8f1bedf6288a0e302848a8012f127a79d2d30a06ce17d94aa6f7f8a1e6eb9d0681c3774f614cc6dbcb2a813f925c6306a630572a83ec109d5f533c0584cb421d919
+SIG: 33614b7a94f75e036534d76e30147eccdd2a04e00cd4704ab6e807d6a2acc1e1d963b8eee0810d412d9d56e54556302b10730c15abf89c29a027303ea88ae701
+
+TST: 1023
+SK: a1ac48aa5ffa3d800819d03b7f62babf291f20904c11a6400e4f45205f103e38
+PK: 0854e0340f814985fb122b78729479e3fde855c211cadeae56f0d4dc0828d5fa
+MSG: d6f124ed752021c10926972a0c26f3b1838b3c7af247c18009a231ecce964bf6698637833f607dca836f8a606c72ae3cb170174447a2cce583f6e244dbc163e215b9820de7496ffc5b7050c48f2830246678cba4dc5caa07c1458563aa2d10dcb7770ef8fede027dd7f20ddc8cc78c3a2e2e958bd18c0006cf8fb82d44e53e1da7aa80fd1006f3b2300c9b079d8a66f1e4a3f47061f9e2f45dae35dc295204b19460ca5707ab57ce215a24c10faab3fa20bccd101e7a7d70077599f3d6725707552129cad757d6514c1b28997e471f94b0fded8fbbd065dead196d2c07d3dfa7b9fb3bae7680f76621200d099eebebbea0e8957df5b5e204ca3e9e2952b8a30f0a131a6867b1381e394b1b444310f076326656cf9341678008e9525147d8d61ce93d3bf53900cab912663717e0987293833d1902d7fb047b997b86026c467d7bb17cf45796738f7a774ac126764ed4eb45124309f4586260176ba465918d48330a9cc18c4ecea0ddaf38946acc0e361dd40a7e9133ceb50e1c317ea42bd0980a72b8ba3d8a6c7693dd5602f374f2664df4ba56df01e882fca42cb4db621f476c76e1ea9fd105911a74b77952d9914a5ac0f98a900c1b2e1a56c4ea8518a9ee47c4ed14d0bd35eca560319c8ea24755d71a4e030850bc4dc60389f325804021204ccebc25fedbd32edd8d8446aa23ce56a85f779e858d36af7c073c115e341f412c660fab800fe74c50e714ee086e2fbc8d7abbf3e98fb40ca27f1f01a9aadd8cc2275c2dd3f76e4c1d81c4b792daecc9fe66044941b8b2918486dd4acb562a7b58ad8c60c21b83cf48aefa7256a1ed809e669811f484364970bc5695089919bc32d28ea752e8e318ceff467f77ae1977c5ffd79c17c2da8bc7f823dd94398683189945f8b79238a4e815b142b866acbdbcb7aea7f143fffb7cc2b4b54bbf361afda913ad6df1e49dfd6b532642e63f55d893a470d40370665cfb74efd3f59cb0ff6006174ca35f53b97c543e08af4bf5bb75ff9031610652a3f6f2a0cfe97e7a521f3d2a289114ded34772b0e49817bde1cb924ff514e2866a09e3ede0782d2c0c98e6814b8c1e778cf8306348c933adb2e472dba09db954ff49648373395a2f0181958feb1ea2834c99532873db5c88eb5289c77e90015203ef502ac8e1c48fa1a06dafa6519d52dae3c5567570dd2434e671927c66363f783156893f138a84c75664b30ae4275112736d53d4f399ddda3d23067c073f521afba1f7be585513c2cec9c8f08d2a22c3c85392cd2ae50f3928251f86b310c69a0f8c4e853ab3f3e8129b0566ef4bbbe80b8c02c8928a4de56c0d119a45bbf5af1808d488852d8a45beb0d683248a4d65de1526b3d1d2ffc1f22215b608468cbc3bd39514b397fc0db0f113dbe6fce4652e82ff895b2b4387e041d7e4e7bde4694769665e81
+SIG: c57e3c091ed24e5e84665bd9bb102db49797df9008f05557fa0d5ad7a295e5e4d2a4716b17f8c91cb12f5abfb1af027fb0411199acc5d285d842a4b65bde4902
+
+TST: 1024
+SK: f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5
+PK: 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
+MSG: 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0
+SIG: 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03
+
+# Now an additional test with the data from test 1 but using an
+# uncompressed public key.
+TST: 1025
+SK: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
+PK: 0455d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7
+MSG:
+SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
+
+# Now an additional test with the data from test 1 but using an
+# compressed prefix.
+TST: 1
+SK: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
+PK: 40d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
+MSG:
+SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
diff --git a/comm/third_party/libgcrypt/tests/t-ed448.c b/comm/third_party/libgcrypt/tests/t-ed448.c
new file mode 100644
index 0000000000..1f445ffc14
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-ed448.c
@@ -0,0 +1,537 @@
+/* t-ed448.c - Check the Ed448 crypto
+ * Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "stopwatch.h"
+
+#define PGM "t-ed448"
+#include "t-common.h"
+#define N_TESTS 11
+
+static int sign_with_pk;
+static int no_verify;
+static int custom_data_file;
+
+
+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_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ fprintf (stderr, "%s: ", PGM);
+ if (prefix)
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = xmalloc (size);
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+ gcry_free (buf);
+}
+
+
+/* Prepend FNAME with the srcdir environment variable's value and
+ * return an allocated filename. */
+char *
+prepend_srcdir (const char *fname)
+{
+ static const char *srcdir;
+ char *result;
+
+ if (!srcdir && !(srcdir = getenv ("srcdir")))
+ srcdir = ".";
+
+ result = xmalloc (strlen (srcdir) + 1 + strlen (fname) + 1);
+ strcpy (result, srcdir);
+ strcat (result, "/");
+ strcat (result, fname);
+ return result;
+}
+
+
+/* Read next line but skip over empty and comment lines. Caller must
+ xfree the result. */
+static char *
+read_textline (FILE *fp, int *lineno)
+{
+ char line[4096];
+ char *p;
+
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return NULL;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ ++*lineno;
+ p = strchr (line, '\n');
+ if (!p)
+ die ("input line %d not terminated or too long\n", *lineno);
+ *p = 0;
+ for (p--;p > line && my_isascii (*p) && isspace (*p); p--)
+ *p = 0;
+ }
+ while (!*line || *line == '#');
+ /* if (debug) */
+ /* info ("read line: '%s'\n", line); */
+ return xstrdup (line);
+}
+
+
+/* Copy the data after the tag to BUFFER. BUFFER will be allocated as
+ needed. */
+static void
+copy_data (char **buffer, const char *line, int lineno)
+{
+ const char *s;
+
+ xfree (*buffer);
+ *buffer = NULL;
+
+ s = strchr (line, ':');
+ if (!s)
+ {
+ fail ("syntax error at input line %d", lineno);
+ return;
+ }
+ for (s++; my_isascii (*s) && isspace (*s); s++)
+ ;
+ *buffer = xstrdup (s);
+}
+
+
+/* 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 returns NULL 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))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static void
+hexdowncase (char *string)
+{
+ char *p;
+
+ for (p=string; *p; p++)
+ if (my_isascii (*p))
+ *p = tolower (*p);
+}
+
+
+static void
+one_test (int testno, int ph, const char *sk, const char *pk,
+ const char *msg, const char *ctx, const char *sig)
+{
+ gpg_error_t err;
+ int i;
+ char *p;
+ void *buffer = NULL;
+ void *buffer2 = NULL;
+ size_t buflen, buflen2;
+ gcry_sexp_t s_tmp, s_tmp2;
+ gcry_sexp_t s_sk = NULL;
+ gcry_sexp_t s_pk = NULL;
+ gcry_sexp_t s_msg= NULL;
+ gcry_sexp_t s_sig= NULL;
+ unsigned char *sig_r = NULL;
+ unsigned char *sig_s = NULL;
+ char *sig_rs_string = NULL;
+ size_t sig_r_len, sig_s_len;
+
+ if (verbose > 1)
+ info ("Running test %d %d\n", testno, ph);
+
+ if (!(buffer = hex2buffer (sk, &buflen)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "sk", "invalid hex string");
+ goto leave;
+ }
+ if (!(buffer2 = hex2buffer (pk, &buflen2)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "pk", "invalid hex string");
+ goto leave;
+ }
+ if (sign_with_pk)
+ err = gcry_sexp_build (&s_sk, NULL,
+ "(private-key"
+ " (ecc"
+ " (curve \"Ed448\")"
+ " (q %b)"
+ " (d %b)))",
+ (int)buflen2, buffer2,
+ (int)buflen, buffer);
+ else
+ err = gcry_sexp_build (&s_sk, NULL,
+ "(private-key"
+ " (ecc"
+ " (curve \"Ed448\")"
+ " (d %b)))",
+ (int)buflen, buffer);
+ if (err)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "sk", gpg_strerror (err));
+ goto leave;
+ }
+
+ if ((err = gcry_sexp_build (&s_pk, NULL,
+ "(public-key"
+ " (ecc"
+ " (curve \"Ed448\")"
+ " (q %b)))", (int)buflen2, buffer2)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "pk", gpg_strerror (err));
+ goto leave;
+ }
+
+ xfree (buffer);
+ if (!(buffer = hex2buffer (msg, &buflen)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "msg", "invalid hex string");
+ goto leave;
+ }
+ if (ctx)
+ {
+ xfree (buffer2);
+ if (!(buffer2 = hex2buffer (ctx, &buflen2)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "ctx", "invalid hex string");
+ goto leave;
+ }
+
+ if ((err = gcry_sexp_build (&s_msg, NULL,
+ ph ?
+ "(data"
+ " (flags prehash)"
+ " (label %b)"
+ " (value %b))"
+ :
+ "(data"
+ " (label %b)"
+ " (value %b))",
+ (int)buflen2, buffer2,
+ (int)buflen, buffer)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "msg", gpg_strerror (err));
+ goto leave;
+ }
+ }
+ else
+ {
+ if ((err = gcry_sexp_build (&s_msg, NULL,
+ ph ?
+ "(data"
+ " (flags prehash)"
+ " (value %b))"
+ :
+ "(data"
+ " (value %b))", (int)buflen, buffer)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "msg", gpg_strerror (err));
+ goto leave;
+ }
+ }
+
+ if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk)))
+ fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err));
+ if (debug)
+ show_sexp ("sig=", s_sig);
+
+ s_tmp2 = NULL;
+ s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+ if (s_tmp)
+ {
+ s_tmp2 = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_tmp2, "eddsa", 0);
+ if (s_tmp)
+ {
+ gcry_sexp_release (s_tmp2);
+ s_tmp2 = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_tmp2, "r", 0);
+ if (s_tmp)
+ {
+ sig_r = gcry_sexp_nth_buffer (s_tmp, 1, &sig_r_len);
+ gcry_sexp_release (s_tmp);
+ }
+ s_tmp = gcry_sexp_find_token (s_tmp2, "s", 0);
+ if (s_tmp)
+ {
+ sig_s = gcry_sexp_nth_buffer (s_tmp, 1, &sig_s_len);
+ gcry_sexp_release (s_tmp);
+ }
+ }
+ }
+ gcry_sexp_release (s_tmp2); s_tmp2 = NULL;
+
+ if (!sig_r || !sig_s)
+ fail ("gcry_pk_sign failed for test %d: %s", testno, "r or s missing");
+ else
+ {
+ sig_rs_string = xmalloc (2*(sig_r_len + sig_s_len)+1);
+ p = sig_rs_string;
+ *p = 0;
+ for (i=0; i < sig_r_len; i++, p += 2)
+ snprintf (p, 3, "%02x", sig_r[i]);
+ for (i=0; i < sig_s_len; i++, p += 2)
+ snprintf (p, 3, "%02x", sig_s[i]);
+ if (strcmp (sig_rs_string, sig))
+ {
+ fail ("gcry_pk_sign failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", sig);
+ info (" got: '%s'", sig_rs_string);
+ }
+ }
+
+ if (!no_verify)
+ if ((err = gcry_pk_verify (s_sig, s_msg, s_pk)))
+ fail ("gcry_pk_verify failed for test %d: %s",
+ testno, gpg_strerror (err));
+
+
+ leave:
+ gcry_sexp_release (s_sig);
+ gcry_sexp_release (s_sk);
+ gcry_sexp_release (s_pk);
+ gcry_sexp_release (s_msg);
+ xfree (buffer);
+ xfree (buffer2);
+ xfree (sig_r);
+ xfree (sig_s);
+ xfree (sig_rs_string);
+}
+
+
+static void
+check_ed448 (const char *fname)
+{
+ FILE *fp;
+ int lineno, ntests;
+ char *line;
+ int testno;
+ int ph;
+ char *sk, *pk, *msg, *ctx, *sig;
+
+ info ("Checking Ed448.\n");
+
+ fp = fopen (fname, "r");
+ if (!fp)
+ die ("error opening '%s': %s\n", fname, strerror (errno));
+
+ testno = 0;
+ ph = 0;
+ sk = pk = msg = ctx = sig = NULL;
+ lineno = ntests = 0;
+ while ((line = read_textline (fp, &lineno)))
+ {
+ if (!strncmp (line, "TST:", 4))
+ testno = atoi (line+4);
+ else if (!strncmp (line, "PH:", 3))
+ ph = atoi (line+3);
+ else if (!strncmp (line, "SK:", 3))
+ copy_data (&sk, line, lineno);
+ else if (!strncmp (line, "PK:", 3))
+ copy_data (&pk, line, lineno);
+ else if (!strncmp (line, "MSG:", 4))
+ copy_data (&msg, line, lineno);
+ else if (!strncmp (line, "CTX:", 4))
+ copy_data (&ctx, line, lineno);
+ else if (!strncmp (line, "SIG:", 4))
+ copy_data (&sig, line, lineno);
+ else
+ fail ("unknown tag at input line %d", lineno);
+
+ xfree (line);
+ if (testno && sk && pk && msg && sig)
+ {
+ hexdowncase (sig);
+ one_test (testno, ph, sk, pk, msg, ctx, sig);
+ ntests++;
+ if (!(ntests % 256))
+ show_note ("%d of %d tests done\n", ntests, N_TESTS);
+ ph = 0;
+ xfree (pk); pk = NULL;
+ xfree (sk); sk = NULL;
+ xfree (msg); msg = NULL;
+ xfree (ctx); ctx = NULL;
+ xfree (sig); sig = NULL;
+ }
+
+ }
+ xfree (pk);
+ xfree (sk);
+ xfree (msg);
+ xfree (ctx);
+ xfree (sig);
+
+ if (ntests != N_TESTS && !custom_data_file)
+ fail ("did %d tests but expected %d", ntests, N_TESTS);
+ else if ((ntests % 256))
+ show_note ("%d tests done\n", ntests);
+
+ fclose (fp);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ char *fname = NULL;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: " PGM " [options]\n"
+ "Options:\n"
+ " --verbose print timings etc.\n"
+ " --debug flyswatter\n"
+ " --sign-with-pk also use the public key for signing\n"
+ " --no-verify skip the verify test\n"
+ " --data FNAME take test data from file FNAME\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--sign-with-pk"))
+ {
+ sign_with_pk = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--no-verify"))
+ {
+ no_verify = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--data"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ xfree (fname);
+ fname = xstrdup (*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+
+ }
+
+ if (!fname)
+ fname = prepend_srcdir ("t-ed448.inp");
+ else
+ custom_data_file = 1;
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ /* Ed448 isn't supported in fips mode */
+ if (gcry_fips_mode_active())
+ return 77;
+
+ start_timer ();
+ check_ed448 (fname);
+ stop_timer ();
+
+ xfree (fname);
+
+ info ("All tests completed in %s. Errors: %d\n",
+ elapsed_time (1), error_count);
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-ed448.inp b/comm/third_party/libgcrypt/tests/t-ed448.inp
new file mode 100644
index 0000000000..a2766f95cf
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-ed448.inp
@@ -0,0 +1,75 @@
+# t-ed448.inp
+# This is from RFC 8032, the section
+#
+# 7.4. Test Vectors for Ed448
+#
+
+TST: 1
+SK: 6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b
+PK: 5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180
+MSG:
+SIG: 533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600
+
+TST: 2
+SK: c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463afbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e
+PK: 43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c0866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480
+MSG: 03
+SIG: 26b8f91727bd62897af15e41eb43c377efb9c610d48f2335cb0bd0087810f4352541b143c4b981b7e18f62de8ccdf633fc1bf037ab7cd779805e0dbcc0aae1cbcee1afb2e027df36bc04dcecbf154336c19f0af7e0a6472905e799f1953d2a0ff3348ab21aa4adafd1d234441cf807c03a00
+
+TST: 3
+SK: c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463afbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e
+PK: 43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c0866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480
+MSG: 03
+CTX: 666f6f
+SIG: d4f8f6131770dd46f40867d6fd5d5055de43541f8c5e35abbcd001b32a89f7d2151f7647f11d8ca2ae279fb842d607217fce6e042f6815ea000c85741de5c8da1144a6a1aba7f96de42505d7a7298524fda538fccbbb754f578c1cad10d54d0d5428407e85dcbc98a49155c13764e66c3c00
+
+TST: 4
+SK: cd23d24f714274e744343237b93290f511f6425f98e64459ff203e8985083ffdf60500553abc0e05cd02184bdb89c4ccd67e187951267eb328
+PK: dcea9e78f35a1bf3499a831b10b86c90aac01cd84b67a0109b55a36e9328b1e365fce161d71ce7131a543ea4cb5f7e9f1d8b00696447001400
+MSG: 0c3e544074ec63b0265e0c
+SIG: 1f0a8888ce25e8d458a21130879b840a9089d999aaba039eaf3e3afa090a09d389dba82c4ff2ae8ac5cdfb7c55e94d5d961a29fe0109941e00b8dbdeea6d3b051068df7254c0cdc129cbe62db2dc957dbb47b51fd3f213fb8698f064774250a5028961c9bf8ffd973fe5d5c206492b140e00
+
+TST: 5
+SK: 258cdd4ada32ed9c9ff54e63756ae582fb8fab2ac721f2c8e676a72768513d939f63dddb55609133f29adf86ec9929dccb52c1c5fd2ff7e21b
+PK: 3ba16da0c6f2cc1f30187740756f5e798d6bc5fc015d7c63cc9510ee3fd44adc24d8e968b6e46e6f94d19b945361726bd75e149ef09817f580
+MSG: 64a65f3cdedcdd66811e2915
+SIG: 7eeeab7c4e50fb799b418ee5e3197ff6bf15d43a14c34389b59dd1a7b1b85b4ae90438aca634bea45e3a2695f1270f07fdcdf7c62b8efeaf00b45c2c96ba457eb1a8bf075a3db28e5c24f6b923ed4ad747c3c9e03c7079efb87cb110d3a99861e72003cbae6d6b8b827e4e6c143064ff3c00
+
+TST: 6
+SK: 7ef4e84544236752fbb56b8f31a23a10e42814f5f55ca037cdcc11c64c9a3b2949c1bb60700314611732a6c2fea98eebc0266a11a93970100e
+PK: b3da079b0aa493a5772029f0467baebee5a8112d9d3a22532361da294f7bb3815c5dc59e176b4d9f381ca0938e13c6c07b174be65dfa578e80
+MSG: 64a65f3cdedcdd66811e2915e7
+SIG: 6a12066f55331b6c22acd5d5bfc5d71228fbda80ae8dec26bdd306743c5027cb4890810c162c027468675ecf645a83176c0d7323a2ccde2d80efe5a1268e8aca1d6fbc194d3f77c44986eb4ab4177919ad8bec33eb47bbb5fc6e28196fd1caf56b4e7e0ba5519234d047155ac727a1053100
+
+TST: 7
+SK: d65df341ad13e008567688baedda8e9dcdc17dc024974ea5b4227b6530e339bff21f99e68ca6968f3cca6dfe0fb9f4fab4fa135d5542ea3f01
+PK: df9705f58edbab802c7f8363cfe5560ab1c6132c20a9f1dd163483a26f8ac53a39d6808bf4a1dfbd261b099bb03b3fb50906cb28bd8a081f00
+MSG: bd0f6a3747cd561bdddf4640a332461a4a30a12a434cd0bf40d766d9c6d458e5512204a30c17d1f50b5079631f64eb3112182da3005835461113718d1a5ef944
+SIG: 554bc2480860b49eab8532d2a533b7d578ef473eeb58c98bb2d0e1ce488a98b18dfde9b9b90775e67f47d4a1c3482058efc9f40d2ca033a0801b63d45b3b722ef552bad3b4ccb667da350192b61c508cf7b6b5adadc2c8d9a446ef003fb05cba5f30e88e36ec2703b349ca229c2670833900
+
+TST: 8
+SK: 2ec5fe3c17045abdb136a5e6a913e32ab75ae68b53d2fc149b77e504132d37569b7e766ba74a19bd6162343a21c8590aa9cebca9014c636df5
+PK: 79756f014dcfe2079f5dd9e718be4171e2ef2486a08f25186f6bff43a9936b9bfe12402b08ae65798a3d81e22e9ec80e7690862ef3d4ed3a00
+MSG: 15777532b0bdd0d1389f636c5f6b9ba734c90af572877e2d272dd078aa1e567cfa80e12928bb542330e8409f3174504107ecd5efac61ae7504dabe2a602ede89e5cca6257a7c77e27a702b3ae39fc769fc54f2395ae6a1178cab4738e543072fc1c177fe71e92e25bf03e4ecb72f47b64d0465aaea4c7fad372536c8ba516a6039c3c2a39f0e4d832be432dfa9a706a6e5c7e19f397964ca4258002f7c0541b590316dbc5622b6b2a6fe7a4abffd96105eca76ea7b98816af0748c10df048ce012d901015a51f189f3888145c03650aa23ce894c3bd889e030d565071c59f409a9981b51878fd6fc110624dcbcde0bf7a69ccce38fabdf86f3bef6044819de11
+SIG: c650ddbb0601c19ca11439e1640dd931f43c518ea5bea70d3dcde5f4191fe53f00cf966546b72bcc7d58be2b9badef28743954e3a44a23f880e8d4f1cfce2d7a61452d26da05896f0a50da66a239a8a188b6d825b3305ad77b73fbac0836ecc60987fd08527c1a8e80d5823e65cafe2a3d00
+
+TST: 9
+SK: 872d093780f5d3730df7c212664b37b8a0f24f56810daa8382cd4fa3f77634ec44dc54f1c2ed9bea86fafb7632d8be199ea165f5ad55dd9ce8
+PK: a81b2e8a70a5ac94ffdbcc9badfc3feb0801f258578bb114ad44ece1ec0e799da08effb81c5d685c0c56f64eecaef8cdf11cc38737838cf400
+MSG: 6ddf802e1aae4986935f7f981ba3f0351d6273c0a0c22c9c0e8339168e675412a3debfaf435ed651558007db4384b650fcc07e3b586a27a4f7a00ac8a6fec2cd86ae4bf1570c41e6a40c931db27b2faa15a8cedd52cff7362c4e6e23daec0fbc3a79b6806e316efcc7b68119bf46bc76a26067a53f296dafdbdc11c77f7777e972660cf4b6a9b369a6665f02e0cc9b6edfad136b4fabe723d2813db3136cfde9b6d044322fee2947952e031b73ab5c603349b307bdc27bc6cb8b8bbd7bd323219b8033a581b59eadebb09b3c4f3d2277d4f0343624acc817804728b25ab797172b4c5c21a22f9c7839d64300232eb66e53f31c723fa37fe387c7d3e50bdf9813a30e5bb12cf4cd930c40cfb4e1fc622592a49588794494d56d24ea4b40c89fc0596cc9ebb961c8cb10adde976a5d602b1c3f85b9b9a001ed3c6a4d3b1437f52096cd1956d042a597d561a596ecd3d1735a8d570ea0ec27225a2c4aaff26306d1526c1af3ca6d9cf5a2c98f47e1c46db9a33234cfd4d81f2c98538a09ebe76998d0d8fd25997c7d255c6d66ece6fa56f11144950f027795e653008f4bd7ca2dee85d8e90f3dc315130ce2a00375a318c7c3d97be2c8ce5b6db41a6254ff264fa6155baee3b0773c0f497c573f19bb4f4240281f0b1f4f7be857a4e59d416c06b4c50fa09e1810ddc6b1467baeac5a3668d11b6ecaa901440016f389f80acc4db977025e7f5924388c7e340a732e554440e76570f8dd71b7d640b3450d1fd5f0410a18f9a3494f707c717b79b4bf75c98400b096b21653b5d217cf3565c9597456f70703497a078763829bc01bb1cbc8fa04eadc9a6e3f6699587a9e75c94e5bab0036e0b2e711392cff0047d0d6b05bd2a588bc109718954259f1d86678a579a3120f19cfb2963f177aeb70f2d4844826262e51b80271272068ef5b3856fa8535aa2a88b2d41f2a0e2fda7624c2850272ac4a2f561f8f2f7a318bfd5caf9696149e4ac824ad3460538fdc25421beec2cc6818162d06bbed0c40a387192349db67a118bada6cd5ab0140ee273204f628aad1c135f770279a651e24d8c14d75a6059d76b96a6fd857def5e0b354b27ab937a5815d16b5fae407ff18222c6d1ed263be68c95f32d908bd895cd76207ae726487567f9a67dad79abec316f683b17f2d02bf07e0ac8b5bc6162cf94697b3c27cd1fea49b27f23ba2901871962506520c392da8b6ad0d99f7013fbc06c2c17a569500c8a7696481c1cd33e9b14e40b82e79a5f5db82571ba97bae3ad3e0479515bb0e2b0f3bfcd1fd33034efc6245eddd7ee2086ddae2600d8ca73e214e8c2b0bdb2b047c6a464a562ed77b73d2d841c4b34973551257713b753632efba348169abc90a68f42611a40126d7cb21b58695568186f7e569d2ff0f9e745d0487dd2eb997cafc5abf9dd102e62ff66cba87
+SIG: e301345a41a39a4d72fff8df69c98075a0cc082b802fc9b2b6bc503f926b65bddf7f4c8f1cb49f6396afc8a70abe6d8aef0db478d4c6b2970076c6a0484fe76d76b3a97625d79f1ce240e7c576750d295528286f719b413de9ada3e8eb78ed573603ce30d8bb761785dc30dbc320869e1a00
+
+TST: 10
+PH: 1
+SK: 833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42ef7822e0d5104127dc05d6dbefde69e3ab2cec7c867c6e2c49
+PK: 259b71c19f83ef77a7abd26524cbdb3161b590a48f7d17de3ee0ba9c52beb743c09428a131d6b1b57303d90d8132c276d5ed3d5d01c0f53880
+MSG: 616263
+SIG: 822f6901f7480f3d5f562c592994d9693602875614483256505600bbc281ae381f54d6bce2ea911574932f52a4e6cadd78769375ec3ffd1b801a0d9b3f4030cd433964b6457ea39476511214f97469b57dd32dbc560a9a94d00bff07620464a3ad203df7dc7ce360c3cd3696d9d9fab90f00
+
+TST: 11
+PH: 1
+SK: 833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42ef7822e0d5104127dc05d6dbefde69e3ab2cec7c867c6e2c49
+PK: 259b71c19f83ef77a7abd26524cbdb3161b590a48f7d17de3ee0ba9c52beb743c09428a131d6b1b57303d90d8132c276d5ed3d5d01c0f53880
+MSG: 616263
+CTX: 666f6f
+SIG: c32299d46ec8ff02b54540982814dce9a05812f81962b649d528095916a2aa481065b1580423ef927ecf0af5888f90da0f6a9a85ad5dc3f280d91224ba9911a3653d00e484e2ce232521481c8658df304bb7745a73514cdb9bf3e15784ab71284f8d0704a608c54a6b62d97beb511d132100
diff --git a/comm/third_party/libgcrypt/tests/t-kdf.c b/comm/third_party/libgcrypt/tests/t-kdf.c
new file mode 100644
index 0000000000..7a48e98ac3
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-kdf.c
@@ -0,0 +1,1292 @@
+/* t-kdf.c - KDF regression tests
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "stopwatch.h"
+#define PGM "t-kdf"
+#include "t-common.h"
+
+
+static void
+dummy_consumer (volatile char *buffer, size_t buflen)
+{
+ (void)buffer;
+ (void)buflen;
+}
+
+
+static void
+bench_s2k (unsigned long s2kcount)
+{
+ gpg_error_t err;
+ const char passphrase[] = "123456789abcdef0";
+ char keybuf[128/8];
+ unsigned int repetitions = 10;
+ unsigned int count;
+ const char *elapsed;
+ int pass = 0;
+
+ again:
+ start_timer ();
+ for (count = 0; count < repetitions; count++)
+ {
+ err = gcry_kdf_derive (passphrase, strlen (passphrase),
+ GCRY_KDF_ITERSALTED_S2K,
+ GCRY_MD_SHA1, "saltsalt", 8, s2kcount,
+ sizeof keybuf, keybuf);
+ if (err)
+ die ("gcry_kdf_derive failed: %s\n", gpg_strerror (err));
+ dummy_consumer (keybuf, sizeof keybuf);
+ }
+ stop_timer ();
+
+ elapsed = elapsed_time (repetitions);
+ if (!pass++)
+ {
+ if (!atoi (elapsed))
+ {
+ repetitions = 10000;
+ goto again;
+ }
+ else if (atoi (elapsed) < 10)
+ {
+ repetitions = 100;
+ goto again;
+ }
+ }
+
+ printf ("%s\n", elapsed);
+}
+
+
+static void
+check_openpgp (void)
+{
+ /* Test vectors manually created with gpg 1.4 derived code: In
+ passphrase.c:hash_passpharse, add this code to the end of the
+ function:
+
+ ===8<===
+ printf ("{\n"
+ " \"");
+ for (i=0; i < pwlen; i++)
+ {
+ if (i && !(i%16))
+ printf ("\"\n \"");
+ printf ("\\x%02x", ((const unsigned char *)pw)[i]);
+ }
+ printf ("\", %d,\n", pwlen);
+
+ printf (" %s, %s,\n",
+ s2k->mode == 0? "GCRY_KDF_SIMPLE_S2K":
+ s2k->mode == 1? "GCRY_KDF_SALTED_S2K":
+ s2k->mode == 3? "GCRY_KDF_ITERSALTED_S2K":"?",
+ s2k->hash_algo == DIGEST_ALGO_MD5 ? "GCRY_MD_MD5" :
+ s2k->hash_algo == DIGEST_ALGO_SHA1 ? "GCRY_MD_SHA1" :
+ s2k->hash_algo == DIGEST_ALGO_RMD160? "GCRY_MD_RMD160" :
+ s2k->hash_algo == DIGEST_ALGO_SHA256? "GCRY_MD_SHA256" :
+ s2k->hash_algo == DIGEST_ALGO_SHA384? "GCRY_MD_SHA384" :
+ s2k->hash_algo == DIGEST_ALGO_SHA512? "GCRY_MD_SHA512" :
+ s2k->hash_algo == DIGEST_ALGO_SHA224? "GCRY_MD_SHA224" : "?");
+
+ if (s2k->mode == 0)
+ printf (" NULL, 0,\n");
+ else
+ {
+ printf (" \"");
+ for (i=0; i < 8; i++)
+ printf ("\\x%02x", (unsigned int)s2k->salt[i]);
+ printf ("\", %d,\n", 8);
+ }
+
+ if (s2k->mode == 3)
+ printf (" %lu,\n", (unsigned long)S2K_DECODE_COUNT(s2k->count));
+ else
+ printf (" 0,\n");
+
+ printf (" %d,\n", (int)dek->keylen);
+
+ printf (" \"");
+ for (i=0; i < dek->keylen; i++)
+ {
+ if (i && !(i%16))
+ printf ("\"\n \"");
+ printf ("\\x%02x", ((unsigned char *)dek->key)[i]);
+ }
+ printf ("\"\n},\n");
+ ===>8===
+
+ Then prepare a file x.inp with utf8 encoding:
+
+ ===8<===
+ 0 aes md5 1024 a
+ 0 aes md5 1024 ab
+ 0 aes md5 1024 abc
+ 0 aes md5 1024 abcd
+ 0 aes md5 1024 abcde
+ 0 aes md5 1024 abcdef
+ 0 aes md5 1024 abcdefg
+ 0 aes md5 1024 abcdefgh
+ 0 aes md5 1024 abcdefghi
+ 0 aes md5 1024 abcdefghijklmno
+ 0 aes md5 1024 abcdefghijklmnop
+ 0 aes md5 1024 abcdefghijklmnopq
+ 0 aes md5 1024 Long_sentence_used_as_passphrase
+ 0 aes md5 1024 With_utf8_umlauts:äüÖß
+ 0 aes sha1 1024 a
+ 0 aes sha1 1024 ab
+ 0 aes sha1 1024 abc
+ 0 aes sha1 1024 abcd
+ 0 aes sha1 1024 abcde
+ 0 aes sha1 1024 abcdef
+ 0 aes sha1 1024 abcdefg
+ 0 aes sha1 1024 abcdefgh
+ 0 aes sha1 1024 abcdefghi
+ 0 aes sha1 1024 abcdefghijklmno
+ 0 aes sha1 1024 abcdefghijklmnop
+ 0 aes sha1 1024 abcdefghijklmnopq
+ 0 aes sha1 1024 abcdefghijklmnopqr
+ 0 aes sha1 1024 abcdefghijklmnopqrs
+ 0 aes sha1 1024 abcdefghijklmnopqrst
+ 0 aes sha1 1024 abcdefghijklmnopqrstu
+ 0 aes sha1 1024 Long_sentence_used_as_passphrase
+ 0 aes256 sha1 1024 Long_sentence_used_as_passphrase
+ 0 aes sha1 1024 With_utf8_umlauts:äüÖß
+ 3 aes sha1 1024 a
+ 3 aes sha1 1024 ab
+ 3 aes sha1 1024 abc
+ 3 aes sha1 1024 abcd
+ 3 aes sha1 1024 abcde
+ 3 aes sha1 1024 abcdef
+ 3 aes sha1 1024 abcdefg
+ 3 aes sha1 1024 abcdefgh
+ 3 aes sha1 1024 abcdefghi
+ 3 aes sha1 1024 abcdefghijklmno
+ 3 aes sha1 1024 abcdefghijklmnop
+ 3 aes sha1 1024 abcdefghijklmnopq
+ 3 aes sha1 1024 abcdefghijklmnopqr
+ 3 aes sha1 1024 abcdefghijklmnopqrs
+ 3 aes sha1 1024 abcdefghijklmnopqrst
+ 3 aes sha1 1024 abcdefghijklmnopqrstu
+ 3 aes sha1 1024 With_utf8_umlauts:äüÖß
+ 3 aes sha1 1024 Long_sentence_used_as_passphrase
+ 3 aes sha1 10240 Long_sentence_used_as_passphrase
+ 3 aes sha1 102400 Long_sentence_used_as_passphrase
+ 3 aes192 sha1 1024 a
+ 3 aes192 sha1 1024 abcdefg
+ 3 aes192 sha1 1024 abcdefghi
+ 3 aes192 sha1 1024 abcdefghi
+ 3 aes192 sha1 1024 Long_sentence_used_as_passphrase
+ 3 aes256 sha1 1024 a
+ 3 aes256 sha1 1024 abcdefg
+ 3 aes256 sha1 1024 abcdefghi
+ 3 aes256 sha1 1024 abcdefghi
+ 3 aes256 sha1 1024 Long_sentence_used_as_passphrase
+ 0 aes sha256 1024 Long_sentence_used_as_passphrase
+ 1 aes sha256 1024 Long_sentence_used_as_passphrase
+ 3 aes sha256 1024 Long_sentence_used_as_passphrase
+ 3 aes sha256 10240 Long_sentence_used_as_passphrase
+ 3 aes sha384 1024 Long_sentence_used_as_passphrase
+ 3 aes sha512 1024 Long_sentence_used_as_passphrase
+ 3 aes256 sha512 1024 Long_sentence_used_as_passphrase
+ 3 3des sha512 1024 Long_sentence_used_as_passphrase
+ ===>8===
+
+ and finally using a proper utf-8 enabled shell, run:
+
+ cat x.inp | while read mode cipher digest count pass dummy; do \
+ ./gpg </dev/null -o /dev/null -c --passphrase "$pass" \
+ --s2k-mode $mode --s2k-digest $digest --s2k-count $count \
+ --cipher-algo $cipher ; done >x.out
+ */
+ static struct {
+ const char *p; /* Passphrase. */
+ size_t plen; /* Length of P. */
+ int algo;
+ int hashalgo;
+ const char *salt;
+ size_t saltlen;
+ unsigned long c; /* Iterations. */
+ int dklen; /* Requested key length. */
+ const char *dk; /* Derived key. */
+ int disabled;
+ } tv[] = {
+ {
+ "\x61", 1,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61"
+ },
+ {
+ "\x61\x62", 2,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x18\x7e\xf4\x43\x61\x22\xd1\xcc\x2f\x40\xdc\x2b\x92\xf0\xeb\xa0"
+ },
+ {
+ "\x61\x62\x63", 3,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72"
+ },
+ {
+ "\x61\x62\x63\x64", 4,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe2\xfc\x71\x4c\x47\x27\xee\x93\x95\xf3\x24\xcd\x2e\x7f\x33\x1f"
+ },
+ {
+ "\x61\x62\x63\x64\x65", 5,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\xab\x56\xb4\xd9\x2b\x40\x71\x3a\xcc\x5a\xf8\x99\x85\xd4\xb7\x86"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66", 6,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe8\x0b\x50\x17\x09\x89\x50\xfc\x58\xaa\xd8\x3c\x8c\x14\x97\x8e"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x7a\xc6\x6c\x0f\x14\x8d\xe9\x51\x9b\x8b\xd2\x64\x31\x2c\x4d\x64"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe8\xdc\x40\x81\xb1\x34\x34\xb4\x51\x89\xa7\x20\xb7\x7b\x68\x18"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x8a\xa9\x9b\x1f\x43\x9f\xf7\x12\x93\xe9\x53\x57\xba\xc6\xfd\x94"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x8a\x73\x19\xdb\xf6\x54\x4a\x74\x22\xc9\xe2\x54\x52\x58\x0e\xa5"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x1d\x64\xdc\xe2\x39\xc4\x43\x7b\x77\x36\x04\x1d\xb0\x89\xe1\xb9"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71", 17,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x9a\x8d\x98\x45\xa6\xb4\xd8\x2d\xfc\xb2\xc2\xe3\x51\x62\xc8\x30"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x35\x2a\xf0\xfc\xdf\xe9\xbb\x62\x16\xfc\x99\x9d\x8d\x58\x05\xcb"
+ },
+ {
+ "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
+ "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x21\xa4\xeb\xd8\xfd\xf0\x59\x25\xd1\x32\x31\xdb\xe7\xf2\x13\x5d"
+ },
+ {
+ "\x61", 1,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x86\xf7\xe4\x37\xfa\xa5\xa7\xfc\xe1\x5d\x1d\xdc\xb9\xea\xea\xea"
+ },
+ {
+ "\x61\x62", 2,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xda\x23\x61\x4e\x02\x46\x9a\x0d\x7c\x7b\xd1\xbd\xab\x5c\x9c\x47"
+ },
+ {
+ "\x61\x62\x63", 3,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c"
+ },
+ {
+ "\x61\x62\x63\x64", 4,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x81\xfe\x8b\xfe\x87\x57\x6c\x3e\xcb\x22\x42\x6f\x8e\x57\x84\x73"
+ },
+ {
+ "\x61\x62\x63\x64\x65", 5,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x03\xde\x6c\x57\x0b\xfe\x24\xbf\xc3\x28\xcc\xd7\xca\x46\xb7\x6e"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66", 6,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x1f\x8a\xc1\x0f\x23\xc5\xb5\xbc\x11\x67\xbd\xa8\x4b\x83\x3e\x5c"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x2f\xb5\xe1\x34\x19\xfc\x89\x24\x68\x65\xe7\xa3\x24\xf4\x76\xec"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x42\x5a\xf1\x2a\x07\x43\x50\x2b\x32\x2e\x93\xa0\x15\xbc\xf8\x68"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xc6\x3b\x19\xf1\xe4\xc8\xb5\xf7\x6b\x25\xc4\x9b\x8b\x87\xf5\x7d"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x29\x38\xdc\xc2\xe3\xaa\x77\x98\x7c\x7e\x5d\x4a\x0f\x26\x96\x67"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x14\xf3\x99\x52\x88\xac\xd1\x89\xe6\xe5\x0a\x7a\xf4\x7e\xe7\x09"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71", 17,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xd8\x3d\x62\x1f\xcd\x2d\x4d\x29\x85\x54\x70\x43\xa7\xa5\xfd\x4d"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72", 18,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe3\x81\xfe\x42\xc5\x7e\x48\xa0\x82\x17\x86\x41\xef\xfd\x1c\xb9"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73", 19,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x89\x3e\x69\xff\x01\x09\xf3\x45\x9c\x42\x43\x01\x3b\x3d\xe8\xb1"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74", 20,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x14\xa2\x3a\xd7\x0f\x2a\x5d\xd7\x25\x57\x5d\xe6\xc4\x3e\x1c\xdd"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74\x75", 21,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xec\xa9\x86\xb9\x5d\x58\x7f\x34\xd7\x1c\xa7\x75\x2a\x4e\x00\x10"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 32,
+ "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f"
+ "\xc3\x7b\x3a\xb2\xef\x4d\x68\xaa\x9c\xd7\xe4\x88\xee\xd1\x5e\x70"
+ },
+ {
+ "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
+ "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe0\x4e\x1e\xe3\xad\x0b\x49\x7c\x7a\x5f\x37\x3b\x4d\x90\x3c\x2e"
+ },
+ {
+ "\x61", 1,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x6d\x47\xe3\x68\x5d\x2c\x36\x16", 8,
+ 1024,
+ 16,
+ "\x41\x9f\x48\x6e\xbf\xe6\xdd\x05\x9a\x72\x23\x17\x44\xd8\xd3\xf3"
+ },
+ {
+ "\x61\x62", 2,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x7c\x34\x78\xfb\x28\x2d\x25\xc7", 8,
+ 1024,
+ 16,
+ "\x0a\x9d\x09\x06\x43\x3d\x4f\xf9\x87\xd6\xf7\x48\x90\xde\xd1\x1c"
+ },
+ {
+ "\x61\x62\x63", 3,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xc3\x16\x37\x2e\x27\xf6\x9f\x6f", 8,
+ 1024,
+ 16,
+ "\xf8\x27\xa0\x07\xc6\xcb\xdd\xf1\xfe\x5c\x88\x3a\xfc\xcd\x84\x4d"
+ },
+ {
+ "\x61\x62\x63\x64", 4,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xf0\x0c\x73\x38\xb7\xc3\xd5\x14", 8,
+ 1024,
+ 16,
+ "\x9b\x5f\x26\xba\x52\x3b\xcd\xd9\xa5\x2a\xef\x3c\x03\x4d\xd1\x52"
+ },
+ {
+ "\x61\x62\x63\x64\x65", 5,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xe1\x7d\xa2\x36\x09\x59\xee\xc5", 8,
+ 1024,
+ 16,
+ "\x94\x9d\x5b\x1a\x5a\x66\x8c\xfa\x8f\x6f\x22\xaf\x8b\x60\x9f\xaf"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66", 6,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xaf\xa7\x0c\x68\xdf\x7e\xaa\x27", 8,
+ 1024,
+ 16,
+ "\xe5\x38\xf4\x39\x62\x27\xcd\xcc\x91\x37\x7f\x1b\xdc\x58\x64\x27"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x40\x57\xb2\x9d\x5f\xbb\x11\x4f", 8,
+ 1024,
+ 16,
+ "\xad\xa2\x33\xd9\xdd\xe0\xfb\x94\x8e\xcc\xec\xcc\xb3\xa8\x3a\x9e"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x38\xf5\x65\xc5\x0f\x8c\x19\x61", 8,
+ 1024,
+ 16,
+ "\xa0\xb0\x3e\x29\x76\xe6\x8f\xa0\xd8\x34\x8f\xa4\x2d\xfd\x65\xee"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xc3\xb7\x99\xcc\xda\x2d\x05\x7b", 8,
+ 1024,
+ 16,
+ "\x27\x21\xc8\x99\x5f\xcf\x20\xeb\xf2\xd9\xff\x6a\x69\xff\xad\xe8"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x7d\xd8\x68\x8a\x1c\xc5\x47\x22", 8,
+ 1024,
+ 16,
+ "\x0f\x96\x7a\x12\x23\x54\xf6\x92\x61\x67\x07\xb4\x68\x17\xb8\xaa"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x8a\x95\xd4\x88\x0b\xb8\xe9\x9d", 8,
+ 1024,
+ 16,
+ "\xcc\xe4\xc8\x82\x53\x32\xf1\x93\x5a\x00\xd4\x7f\xd4\x46\xfa\x07"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71", 17,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xb5\x22\x48\xa6\xc4\xad\x74\x67", 8,
+ 1024,
+ 16,
+ "\x0c\xe3\xe0\xee\x3d\x8f\x35\xd2\x35\x14\x14\x29\x0c\xf1\xe3\x34"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72", 18,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xac\x9f\x04\x63\x83\x0e\x3c\x95", 8,
+ 1024,
+ 16,
+ "\x49\x0a\x04\x68\xa8\x2a\x43\x6f\xb9\x73\x94\xb4\x85\x9a\xaa\x0e"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73", 19,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x03\x6f\x60\x30\x3a\x19\x61\x0d", 8,
+ 1024,
+ 16,
+ "\x15\xe5\x9b\xbf\x1c\xf0\xbe\x74\x95\x1a\xb2\xc4\xda\x09\xcd\x99"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74", 20,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x51\x40\xa5\x57\xf5\x28\xfd\x03", 8,
+ 1024,
+ 16,
+ "\xa6\xf2\x7e\x6b\x30\x4d\x8d\x67\xd4\xa2\x7f\xa2\x57\x27\xab\x96"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74\x75", 21,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x4c\xf1\x10\x11\x04\x70\xd3\x6e", 8,
+ 1024,
+ 16,
+ "\x2c\x50\x79\x8d\x83\x23\xac\xd6\x22\x29\x37\xaf\x15\x0d\xdd\x8f"
+ },
+ {
+ "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
+ "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xfe\x3a\x25\xcb\x78\xef\xe1\x21", 8,
+ 1024,
+ 16,
+ "\x2a\xb0\x53\x08\xf3\x2f\xd4\x6e\xeb\x01\x49\x5d\x87\xf6\x27\xf6"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x04\x97\xd0\x02\x6a\x44\x2d\xde", 8,
+ 1024,
+ 16,
+ "\x57\xf5\x70\x41\xa0\x9b\x8c\x09\xca\x74\xa9\x22\xa5\x82\x2d\x17"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xdd\xf3\x31\x7c\xce\xf4\x81\x26", 8,
+ 10240,
+ 16,
+ "\xc3\xdd\x01\x6d\xaf\xf6\x58\xc8\xd7\x79\xb4\x40\x00\xb5\xe8\x0b"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x95\xd6\x72\x4e\xfb\xe1\xc3\x1a", 8,
+ 102400,
+ 16,
+ "\xf2\x3f\x36\x7f\xb4\x6a\xd0\x3a\x31\x9e\x65\x11\x8e\x2b\x99\x9b"
+ },
+ {
+ "\x61", 1,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x6d\x69\x15\x18\xe4\x13\x42\x82", 8,
+ 1024,
+ 24,
+ "\x28\x0c\x7e\xf2\x31\xf6\x1c\x6b\x5c\xef\x6a\xd5\x22\x64\x97\x91"
+ "\xe3\x5e\x37\xfd\x50\xe2\xfc\x6c"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x9b\x76\x5e\x81\xde\x13\xdf\x15", 8,
+ 1024,
+ 24,
+ "\x91\x1b\xa1\xc1\x7b\x4f\xc3\xb1\x80\x61\x26\x08\xbe\x53\xe6\x50"
+ "\x40\x6f\x28\xed\xc6\xe6\x67\x55"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x7a\xac\xcc\x6e\x15\x56\xbd\xa1", 8,
+ 1024,
+ 24,
+ "\xfa\x7e\x20\x07\xb6\x47\xb0\x09\x46\xb8\x38\xfb\xa1\xaf\xf7\x75"
+ "\x2a\xfa\x77\x14\x06\x54\xcb\x34"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x1c\x68\xf8\xfb\x98\xf7\x8c\x39", 8,
+ 1024,
+ 24,
+ "\xcb\x1e\x86\xf5\xe0\xe4\xfb\xbf\x71\x34\x99\x24\xf4\x39\x8c\xc2"
+ "\x8e\x25\x1c\x4c\x96\x47\x22\xe8"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x10\xa9\x4e\xc1\xa5\xec\x17\x52", 8,
+ 1024,
+ 24,
+ "\x0f\x83\xa2\x77\x92\xbb\xe4\x58\x68\xc5\xf2\x14\x6e\x6e\x2e\x6b"
+ "\x98\x17\x70\x92\x07\x44\xe0\x51"
+ },
+ {
+ "\x61", 1,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xef\x8f\x37\x61\x8f\xab\xae\x4f", 8,
+ 1024,
+ 32,
+ "\x6d\x65\xae\x86\x23\x91\x39\x98\xec\x1c\x23\x44\xb6\x0d\xad\x32"
+ "\x54\x46\xc7\x23\x26\xbb\xdf\x4b\x54\x6e\xd4\xc2\xfa\xc6\x17\x17"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xaa\xfb\xd9\x06\x7d\x7c\x40\xaf", 8,
+ 1024,
+ 32,
+ "\x7d\x10\x54\x13\x3c\x43\x7a\xb3\x54\x1f\x38\xd4\x8f\x70\x0a\x09"
+ "\xe2\xfa\xab\x97\x9a\x70\x16\xef\x66\x68\xca\x34\x2e\xce\xfa\x1f"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x58\x03\x4f\x56\x8b\x97\xd4\x98", 8,
+ 1024,
+ 32,
+ "\xf7\x40\xb1\x25\x86\x0d\x35\x8f\x9f\x91\x2d\xce\x04\xee\x5a\x04"
+ "\x9d\xbd\x44\x23\x4c\xa6\xbb\xab\xb0\xd0\x56\x82\xa9\xda\x47\x16"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x5d\x41\x3d\xa3\xa7\xfc\x5d\x0c", 8,
+ 1024,
+ 32,
+ "\x4c\x7a\x86\xed\x81\x8a\x94\x99\x7d\x4a\xc4\xf7\x1c\xf8\x08\xdb"
+ "\x09\x35\xd9\xa3\x2d\x22\xde\x32\x2d\x74\x38\xe5\xc8\xf2\x50\x6e"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xca\xa7\xdc\x59\xce\x31\xe7\x49", 8,
+ 1024,
+ 32,
+ "\x67\xe9\xd6\x29\x49\x1c\xb6\xa0\x85\xe8\xf9\x8b\x85\x47\x3a\x7e"
+ "\xa7\xee\x89\x52\x6f\x19\x00\x53\x93\x07\x0a\x8b\xb9\xa8\x86\x94"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA256,
+ NULL, 0,
+ 0,
+ 16,
+ "\x88\x36\x78\x6b\xd9\x5a\x62\xff\x47\xd3\xfb\x79\xc9\x08\x70\x56"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SALTED_S2K, GCRY_MD_SHA256,
+ "\x05\x8b\xfe\x31\xaa\xf3\x29\x11", 8,
+ 0,
+ 16,
+ "\xb2\x42\xfe\x5e\x09\x02\xd9\x62\xb9\x35\xf3\xa8\x43\x80\x9f\xb1"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256,
+ "\xd3\x4a\xea\xc9\x97\x1b\xcc\x83", 8,
+ 1024,
+ 16,
+ "\x35\x37\x99\x62\x07\x26\x68\x23\x05\x47\xb2\xa0\x0b\x2b\x2b\x8d"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256,
+ "\x5e\x71\xbd\x00\x5f\x96\xc4\x23", 8,
+ 10240,
+ 16,
+ "\xa1\x6a\xee\xba\xde\x73\x25\x25\xd1\xab\xa0\xc5\x7e\xc6\x39\xa7"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA384,
+ "\xc3\x08\xeb\x17\x62\x08\x89\xef", 8,
+ 1024,
+ 16,
+ "\x9b\x7f\x0c\x81\x6f\x71\x59\x9b\xd5\xf6\xbf\x3a\x86\x20\x16\x33"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
+ "\xe6\x7d\x13\x6b\x39\xe3\x44\x05", 8,
+ 1024,
+ 16,
+ "\xc8\xcd\x4b\xa4\xf3\xf1\xd5\xb0\x59\x06\xf0\xbb\x89\x34\x6a\xad"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
+ "\xed\x7d\x30\x47\xe4\xc3\xf8\xb6", 8,
+ 1024,
+ 32,
+ "\x89\x7a\xef\x70\x97\xe7\x10\xdb\x75\xcc\x20\x22\xab\x7b\xf3\x05"
+ "\x4b\xb6\x2e\x17\x11\x9f\xd6\xeb\xbf\xdf\x4d\x70\x59\xf0\xf9\xe5"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
+ "\xbb\x1a\x45\x30\x68\x62\x6d\x63", 8,
+ 1024,
+ 24,
+ "\xde\x5c\xb8\xd5\x75\xf6\xad\x69\x5b\xc9\xf6\x2f\xba\xeb\xfb\x36"
+ "\x34\xf2\xb8\xee\x3b\x37\x21\xb7"
+ }
+ };
+ int tvidx;
+ gpg_error_t err;
+ unsigned char outbuf[32];
+ int i;
+
+ for (tvidx=0; tvidx < DIM(tv); tvidx++)
+ {
+ if (tv[tvidx].disabled)
+ continue;
+ /* MD5 isn't supported in fips mode */
+ if (gcry_fips_mode_active()
+ && tv[tvidx].hashalgo == GCRY_MD_MD5)
+ continue;
+ if (verbose)
+ fprintf (stderr, "checking S2K test vector %d\n", tvidx);
+ assert (tv[tvidx].dklen <= sizeof outbuf);
+ err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
+ tv[tvidx].algo, tv[tvidx].hashalgo,
+ tv[tvidx].salt, tv[tvidx].saltlen,
+ tv[tvidx].c, tv[tvidx].dklen, outbuf);
+ if (err)
+ fail ("s2k test %d failed: %s\n", tvidx, gpg_strerror (err));
+ else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
+ {
+ fail ("s2k test %d failed: mismatch\n", tvidx);
+ fputs ("got:", stderr);
+ for (i=0; i < tv[tvidx].dklen; i++)
+ fprintf (stderr, " %02x", outbuf[i]);
+ putc ('\n', stderr);
+ }
+ }
+}
+
+
+static void
+check_pbkdf2 (void)
+{
+ /* Test vectors are from RFC-6070. */
+ static struct {
+ const char *p; /* Passphrase. */
+ size_t plen; /* Length of P. */
+ const char *salt;
+ size_t saltlen;
+ int hashalgo;
+ unsigned long c; /* Iterations. */
+ int dklen; /* Requested key length. */
+ const char *dk; /* Derived key. */
+ int disabled;
+ } tv[] = {
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 1,
+ 20,
+ "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
+ "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 2,
+ 20,
+ "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
+ "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 4096,
+ 20,
+ "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
+ "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 16777216,
+ 20,
+ "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
+ "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84",
+ 1 /* This test takes too long. */
+ },
+ {
+ "passwordPASSWORDpassword", 24,
+ "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+ GCRY_MD_SHA1,
+ 4096,
+ 25,
+ "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8"
+ "\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96"
+ "\x4c\xf2\xf0\x70\x38"
+ },
+ {
+ "pass\0word", 9,
+ "sa\0lt", 5,
+ GCRY_MD_SHA1,
+ 4096,
+ 16,
+ "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37"
+ "\xd7\xf0\x34\x25\xe0\xc3"
+ },
+ { /* empty password test, not in RFC-6070 */
+ "", 0,
+ "salt", 4,
+ GCRY_MD_SHA1,
+ 2,
+ 20,
+ "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2"
+ "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_GOSTR3411_CP,
+ 1,
+ 32,
+ "\x73\x14\xe7\xc0\x4f\xb2\xe6\x62\xc5\x43\x67\x42\x53\xf6\x8b\xd0"
+ "\xb7\x34\x45\xd0\x7f\x24\x1b\xed\x87\x28\x82\xda\x21\x66\x2d\x58"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_GOSTR3411_CP,
+ 2,
+ 32,
+ "\x99\x0d\xfa\x2b\xd9\x65\x63\x9b\xa4\x8b\x07\xb7\x92\x77\x5d\xf7"
+ "\x9f\x2d\xb3\x4f\xef\x25\xf2\x74\x37\x88\x72\xfe\xd7\xed\x1b\xb3"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_GOSTR3411_CP,
+ 4096,
+ 32,
+ "\x1f\x18\x29\xa9\x4b\xdf\xf5\xbe\x10\xd0\xae\xb3\x6a\xf4\x98\xe7"
+ "\xa9\x74\x67\xf3\xb3\x11\x16\xa5\xa7\xc1\xaf\xff\x9d\xea\xda\xfe"
+ },
+ /* { -- takes too long (4-5 min) to calculate
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_GOSTR3411_CP,
+ 16777216,
+ 32,
+ "\xa5\x7a\xe5\xa6\x08\x83\x96\xd1\x20\x85\x0c\x5c\x09\xde\x0a\x52"
+ "\x51\x00\x93\x8a\x59\xb1\xb5\xc3\xf7\x81\x09\x10\xd0\x5f\xcd\x97"
+ }, */
+ {
+ "passwordPASSWORDpassword", 24,
+ "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+ GCRY_MD_GOSTR3411_CP,
+ 4096,
+ 40,
+ "\x78\x83\x58\xc6\x9c\xb2\xdb\xe2\x51\xa7\xbb\x17\xd5\xf4\x24\x1f"
+ "\x26\x5a\x79\x2a\x35\xbe\xcd\xe8\xd5\x6f\x32\x6b\x49\xc8\x50\x47"
+ "\xb7\x63\x8a\xcb\x47\x64\xb1\xfd"
+ },
+ {
+ "pass\0word", 9,
+ "sa\0lt", 5,
+ GCRY_MD_GOSTR3411_CP,
+ 4096,
+ 20,
+ "\x43\xe0\x6c\x55\x90\xb0\x8c\x02\x25\x24"
+ "\x23\x73\x12\x7e\xdf\x9c\x8e\x9c\x32\x91"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_STRIBOG512,
+ 1,
+ 64,
+ "\x64\x77\x0a\xf7\xf7\x48\xc3\xb1\xc9\xac\x83\x1d\xbc\xfd\x85\xc2"
+ "\x61\x11\xb3\x0a\x8a\x65\x7d\xdc\x30\x56\xb8\x0c\xa7\x3e\x04\x0d"
+ "\x28\x54\xfd\x36\x81\x1f\x6d\x82\x5c\xc4\xab\x66\xec\x0a\x68\xa4"
+ "\x90\xa9\xe5\xcf\x51\x56\xb3\xa2\xb7\xee\xcd\xdb\xf9\xa1\x6b\x47"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_STRIBOG512,
+ 2,
+ 64,
+ "\x5a\x58\x5b\xaf\xdf\xbb\x6e\x88\x30\xd6\xd6\x8a\xa3\xb4\x3a\xc0"
+ "\x0d\x2e\x4a\xeb\xce\x01\xc9\xb3\x1c\x2c\xae\xd5\x6f\x02\x36\xd4"
+ "\xd3\x4b\x2b\x8f\xbd\x2c\x4e\x89\xd5\x4d\x46\xf5\x0e\x47\xd4\x5b"
+ "\xba\xc3\x01\x57\x17\x43\x11\x9e\x8d\x3c\x42\xba\x66\xd3\x48\xde"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_STRIBOG512,
+ 4096,
+ 64,
+ "\xe5\x2d\xeb\x9a\x2d\x2a\xaf\xf4\xe2\xac\x9d\x47\xa4\x1f\x34\xc2"
+ "\x03\x76\x59\x1c\x67\x80\x7f\x04\x77\xe3\x25\x49\xdc\x34\x1b\xc7"
+ "\x86\x7c\x09\x84\x1b\x6d\x58\xe2\x9d\x03\x47\xc9\x96\x30\x1d\x55"
+ "\xdf\x0d\x34\xe4\x7c\xf6\x8f\x4e\x3c\x2c\xda\xf1\xd9\xab\x86\xc3"
+ },
+ /* { -- takes toooo long
+ "password", 8,
+ "salt", 4,
+ GCRY_MD_STRIBOG512,
+ 16777216,
+ 64,
+ "\x49\xe4\x84\x3b\xba\x76\xe3\x00\xaf\xe2\x4c\x4d\x23\xdc\x73\x92"
+ "\xde\xf1\x2f\x2c\x0e\x24\x41\x72\x36\x7c\xd7\x0a\x89\x82\xac\x36"
+ "\x1a\xdb\x60\x1c\x7e\x2a\x31\x4e\x8c\xb7\xb1\xe9\xdf\x84\x0e\x36"
+ "\xab\x56\x15\xbe\x5d\x74\x2b\x6c\xf2\x03\xfb\x55\xfd\xc4\x80\x71"
+ }, */
+ {
+ "passwordPASSWORDpassword", 24,
+ "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+ GCRY_MD_STRIBOG512,
+ 4096,
+ 100,
+ "\xb2\xd8\xf1\x24\x5f\xc4\xd2\x92\x74\x80\x20\x57\xe4\xb5\x4e\x0a"
+ "\x07\x53\xaa\x22\xfc\x53\x76\x0b\x30\x1c\xf0\x08\x67\x9e\x58\xfe"
+ "\x4b\xee\x9a\xdd\xca\xe9\x9b\xa2\xb0\xb2\x0f\x43\x1a\x9c\x5e\x50"
+ "\xf3\x95\xc8\x93\x87\xd0\x94\x5a\xed\xec\xa6\xeb\x40\x15\xdf\xc2"
+ "\xbd\x24\x21\xee\x9b\xb7\x11\x83\xba\x88\x2c\xee\xbf\xef\x25\x9f"
+ "\x33\xf9\xe2\x7d\xc6\x17\x8c\xb8\x9d\xc3\x74\x28\xcf\x9c\xc5\x2a"
+ "\x2b\xaa\x2d\x3a"
+ },
+ {
+ "pass\0word", 9,
+ "sa\0lt", 5,
+ GCRY_MD_STRIBOG512,
+ 4096,
+ 64,
+ "\x50\xdf\x06\x28\x85\xb6\x98\x01\xa3\xc1\x02\x48\xeb\x0a\x27\xab"
+ "\x6e\x52\x2f\xfe\xb2\x0c\x99\x1c\x66\x0f\x00\x14\x75\xd7\x3a\x4e"
+ "\x16\x7f\x78\x2c\x18\xe9\x7e\x92\x97\x6d\x9c\x1d\x97\x08\x31\xea"
+ "\x78\xcc\xb8\x79\xf6\x70\x68\xcd\xac\x19\x10\x74\x08\x44\xe8\x30"
+ }
+ };
+ int tvidx;
+ gpg_error_t err;
+ unsigned char outbuf[100];
+ int i;
+
+ for (tvidx=0; tvidx < DIM(tv); tvidx++)
+ {
+ if (tv[tvidx].disabled)
+ continue;
+ if (verbose)
+ fprintf (stderr, "checking PBKDF2 test vector %d algo %d\n", tvidx,
+ tv[tvidx].hashalgo);
+ assert (tv[tvidx].dklen <= sizeof outbuf);
+ err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
+ GCRY_KDF_PBKDF2, tv[tvidx].hashalgo,
+ tv[tvidx].salt, tv[tvidx].saltlen,
+ tv[tvidx].c, tv[tvidx].dklen, outbuf);
+ if (err)
+ fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err));
+ else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
+ {
+ fail ("pbkdf2 test %d failed: mismatch\n", tvidx);
+ fputs ("got:", stderr);
+ for (i=0; i < tv[tvidx].dklen; i++)
+ fprintf (stderr, " %02x", outbuf[i]);
+ putc ('\n', stderr);
+ }
+ }
+}
+
+
+static void
+check_scrypt (void)
+{
+ /* Test vectors are from draft-josefsson-scrypt-kdf-01. */
+ static struct {
+ const char *p; /* Passphrase. */
+ size_t plen; /* Length of P. */
+ const char *salt;
+ size_t saltlen;
+ int parm_n; /* CPU/memory cost. */
+ int parm_r; /* blocksize */
+ unsigned long parm_p; /* parallelization. */
+ int dklen; /* Requested key length. */
+ const char *dk; /* Derived key. */
+ int disabled;
+ } tv[] = {
+ {
+ "", 0,
+ "", 0,
+ 16,
+ 1,
+ 1,
+ 64,
+ "\x77\xd6\x57\x62\x38\x65\x7b\x20\x3b\x19\xca\x42\xc1\x8a\x04\x97"
+ "\xf1\x6b\x48\x44\xe3\x07\x4a\xe8\xdf\xdf\xfa\x3f\xed\xe2\x14\x42"
+ "\xfc\xd0\x06\x9d\xed\x09\x48\xf8\x32\x6a\x75\x3a\x0f\xc8\x1f\x17"
+ "\xe8\xd3\xe0\xfb\x2e\x0d\x36\x28\xcf\x35\xe2\x0c\x38\xd1\x89\x06"
+ },
+ {
+ "password", 8,
+ "NaCl", 4,
+ 1024,
+ 8,
+ 16,
+ 64,
+ "\xfd\xba\xbe\x1c\x9d\x34\x72\x00\x78\x56\xe7\x19\x0d\x01\xe9\xfe"
+ "\x7c\x6a\xd7\xcb\xc8\x23\x78\x30\xe7\x73\x76\x63\x4b\x37\x31\x62"
+ "\x2e\xaf\x30\xd9\x2e\x22\xa3\x88\x6f\xf1\x09\x27\x9d\x98\x30\xda"
+ "\xc7\x27\xaf\xb9\x4a\x83\xee\x6d\x83\x60\xcb\xdf\xa2\xcc\x06\x40"
+ },
+ {
+ "pleaseletmein", 13,
+ "SodiumChloride", 14,
+ 16384,
+ 8,
+ 1,
+ 64,
+ "\x70\x23\xbd\xcb\x3a\xfd\x73\x48\x46\x1c\x06\xcd\x81\xfd\x38\xeb"
+ "\xfd\xa8\xfb\xba\x90\x4f\x8e\x3e\xa9\xb5\x43\xf6\x54\x5d\xa1\xf2"
+ "\xd5\x43\x29\x55\x61\x3f\x0f\xcf\x62\xd4\x97\x05\x24\x2a\x9a\xf9"
+ "\xe6\x1e\x85\xdc\x0d\x65\x1e\x40\xdf\xcf\x01\x7b\x45\x57\x58\x87"
+ },
+ {
+ "pleaseletmein", 13,
+ "SodiumChloride", 14,
+ 1048576,
+ 8,
+ 1,
+ 64,
+ "\x21\x01\xcb\x9b\x6a\x51\x1a\xae\xad\xdb\xbe\x09\xcf\x70\xf8\x81"
+ "\xec\x56\x8d\x57\x4a\x2f\xfd\x4d\xab\xe5\xee\x98\x20\xad\xaa\x47"
+ "\x8e\x56\xfd\x8f\x4b\xa5\xd0\x9f\xfa\x1c\x6d\x92\x7c\x40\xf4\xc3"
+ "\x37\x30\x40\x49\xe8\xa9\x52\xfb\xcb\xf4\x5c\x6f\xa7\x7a\x41\xa4",
+ 2 /* Only in debug mode. */
+ }
+ };
+ int tvidx;
+ gpg_error_t err;
+ unsigned char outbuf[64];
+ int i;
+
+ for (tvidx=0; tvidx < DIM(tv); tvidx++)
+ {
+ if (tv[tvidx].disabled && !(tv[tvidx].disabled == 2 && debug))
+ continue;
+ if (verbose)
+ fprintf (stderr, "checking SCRYPT test vector %d\n", tvidx);
+ assert (tv[tvidx].dklen <= sizeof outbuf);
+ err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
+ tv[tvidx].parm_r == 1 ? 41 : GCRY_KDF_SCRYPT,
+ tv[tvidx].parm_n,
+ tv[tvidx].salt, tv[tvidx].saltlen,
+ tv[tvidx].parm_p, tv[tvidx].dklen, outbuf);
+ if (err)
+ fail ("scrypt test %d failed: %s\n", tvidx, gpg_strerror (err));
+ else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
+ {
+ fail ("scrypt test %d failed: mismatch\n", tvidx);
+ fputs ("got:", stderr);
+ for (i=0; i < tv[tvidx].dklen; i++)
+ fprintf (stderr, " %02x", outbuf[i]);
+ putc ('\n', stderr);
+ }
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ unsigned long s2kcount = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: t-kdf [options]"
+ "Options:\n"
+ " --verbose print timinigs etc.\n"
+ " --debug flyswatter\n"
+ " --s2k print the time needed for S2K\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--s2k"))
+ {
+ s2kcount = 1;
+ argc--; argv++;
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'\n", *argv);
+ }
+
+ if (s2kcount)
+ {
+ if (argc != 1)
+ die ("usage: t-kdf --s2k S2KCOUNT\n");
+ s2kcount = strtoul (*argv, NULL, 10);
+ if (!s2kcount)
+ die ("t-kdf: S2KCOUNT must be positive\n");
+ }
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+
+ if (s2kcount)
+ bench_s2k (s2kcount);
+ else
+ {
+ check_openpgp ();
+ check_pbkdf2 ();
+ check_scrypt ();
+ }
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-lock.c b/comm/third_party/libgcrypt/tests/t-lock.c
new file mode 100644
index 0000000000..cacc3835b8
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-lock.c
@@ -0,0 +1,465 @@
+/* t-lock.c - Check the lock functions
+ * Copyright (C) 2014 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 <http://www.gnu.org/licenses/>.
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#if HAVE_PTHREAD
+# include <pthread.h>
+#endif
+
+#define PGM "t-lock"
+
+#include "t-common.h"
+#include "../src/gcrypt-testapi.h"
+
+/* Mingw requires us to include windows.h after winsock2.h which is
+ included by gcrypt.h. */
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+#ifdef _WIN32
+# define THREAD_RET_TYPE DWORD WINAPI
+# define THREAD_RET_VALUE 0
+#else
+# define THREAD_RET_TYPE void *
+# define THREAD_RET_VALUE NULL
+#endif
+
+
+/* Number of threads to run. */
+#define N_NONCE_THREADS 8
+/* Number of interations. */
+#define N_NONCE_ITERATIONS 1000
+/* Requested nonce size. */
+#define NONCE_SIZE 11
+
+
+/* This tests works by having a a couple of accountant threads which do
+ random transactions between accounts and a revision threads which
+ checks that the balance of all accounts is invariant. The idea for
+ this check is due to Bruno Haible. */
+#define N_ACCOUNT 8
+#define ACCOUNT_VALUE 42
+static int account[N_ACCOUNT];
+
+/* Number of transactions done by each accountant. */
+#define N_TRANSACTIONS 1000
+
+/* Number of accountants to run. */
+#define N_ACCOUNTANTS 5
+
+/* Maximum transaction value. A quite low value is used so that we
+ would get an integer overflow. */
+#define MAX_TRANSACTION_VALUE 50
+
+/* Flag to tell the revision thread to finish. */
+static volatile int stop_revision_thread;
+
+
+struct thread_arg_s
+{
+ int no;
+};
+
+
+
+
+#if defined(HAVE_PTHREAD) || defined(_WIN32)
+/* Wrapper functions to access Libgcrypt's internal test lock. */
+static void
+external_lock_test_init (int line)
+{
+ gpg_error_t err;
+
+ err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_INIT);
+ if (err)
+ fail ("init lock failed at %d: %s", line, gpg_strerror (err));
+}
+
+static void
+external_lock_test_lock (int line)
+{
+ gpg_error_t err;
+
+ err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_LOCK);
+ if (err)
+ fail ("taking lock failed at %d: %s", line, gpg_strerror (err));
+}
+
+static void
+external_lock_test_unlock (int line)
+{
+ gpg_error_t err;
+
+ err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_UNLOCK);
+ if (err)
+ fail ("releasing lock failed at %d: %s", line, gpg_strerror (err));
+
+}
+
+static void
+external_lock_test_destroy (int line)
+{
+ gpg_error_t err;
+
+ err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_DESTROY);
+ if (err)
+ fail ("destroying lock failed at %d: %s", line, gpg_strerror (err));
+}
+#endif
+
+
+
+#if defined(HAVE_PTHREAD) || defined(_WIN32)
+/* The nonce thread. We simply request a couple of nonces and
+ return. */
+static THREAD_RET_TYPE
+nonce_thread (void *argarg)
+{
+ struct thread_arg_s *arg = argarg;
+ int i;
+ char nonce[NONCE_SIZE];
+
+ for (i = 0; i < N_NONCE_ITERATIONS; i++)
+ {
+ gcry_create_nonce (nonce, sizeof nonce);
+ if (i && !(i%100))
+ info ("thread %d created %d nonces so far", arg->no, i);
+ }
+
+ gcry_free (arg);
+ return THREAD_RET_VALUE;
+}
+#endif
+
+
+/* To check our locking function we run several threads all accessing
+ the nonce functions. If this function returns we know that there
+ are no obvious deadlocks or failed lock initialization. */
+static void
+check_nonce_lock (void)
+{
+ struct thread_arg_s *arg;
+#ifdef _WIN32
+ HANDLE threads[N_NONCE_THREADS];
+ int i;
+ int rc;
+
+ for (i=0; i < N_NONCE_THREADS; i++)
+ {
+ arg = gcry_xmalloc (sizeof *arg);
+ arg->no = i;
+ threads[i] = CreateThread (NULL, 0, nonce_thread, arg, 0, NULL);
+ if (!threads[i])
+ die ("error creating nonce thread %d: rc=%d",
+ i, (int)GetLastError ());
+ }
+
+ for (i=0; i < N_NONCE_THREADS; i++)
+ {
+ rc = WaitForSingleObject (threads[i], INFINITE);
+ if (rc == WAIT_OBJECT_0)
+ info ("nonce thread %d has terminated", i);
+ else
+ fail ("waiting for nonce thread %d failed: %d",
+ i, (int)GetLastError ());
+ CloseHandle (threads[i]);
+ }
+
+#elif HAVE_PTHREAD
+ pthread_t threads[N_NONCE_THREADS];
+ int rc, i;
+
+ for (i=0; i < N_NONCE_THREADS; i++)
+ {
+ arg = gcry_xmalloc (sizeof *arg);
+ arg->no = i;
+ pthread_create (&threads[i], NULL, nonce_thread, arg);
+ }
+
+ for (i=0; i < N_NONCE_THREADS; i++)
+ {
+ rc = pthread_join (threads[i], NULL);
+ if (rc)
+ fail ("pthread_join failed for nonce thread %d: %s",
+ i, strerror (errno));
+ else
+ info ("nonce thread %d has terminated", i);
+ }
+#else
+ (void)arg;
+#endif /*!_WIN32*/
+}
+
+
+/* Initialize all accounts. */
+static void
+init_accounts (void)
+{
+ int i;
+
+ for (i=0; i < N_ACCOUNT; i++)
+ account[i] = ACCOUNT_VALUE;
+}
+
+
+/* Check that the sum of all accounts matches the initial sum. */
+static void
+check_accounts (void)
+{
+ int i, sum;
+
+ sum = 0;
+ for (i = 0; i < N_ACCOUNT; i++)
+ sum += account[i];
+ if (sum != N_ACCOUNT * ACCOUNT_VALUE)
+ die ("accounts out of balance");
+}
+
+
+static void
+print_accounts (void)
+{
+ int i;
+
+ for (i=0; i < N_ACCOUNT; i++)
+ printf ("account %d: %6d\n", i, account[i]);
+}
+
+
+#if defined(HAVE_PTHREAD) || defined(_WIN32)
+/* Get a a random integer value in the range 0 to HIGH. */
+static unsigned int
+get_rand (int high)
+{
+ return (unsigned int)(1+(int)((double)(high+1)*rand ()/(RAND_MAX+1.0))) - 1;
+}
+
+
+/* Pick a random account. Note that this function is not
+ thread-safe. */
+static int
+pick_account (void)
+{
+ return get_rand (N_ACCOUNT - 1);
+}
+
+
+/* Pick a random value for a transaction. This is not thread-safe. */
+static int
+pick_value (void)
+{
+ return get_rand (MAX_TRANSACTION_VALUE);
+}
+
+
+/* This is the revision department. */
+static THREAD_RET_TYPE
+revision_thread (void *arg)
+{
+ (void)arg;
+
+ while (!stop_revision_thread)
+ {
+ external_lock_test_lock (__LINE__);
+ check_accounts ();
+ external_lock_test_unlock (__LINE__);
+ }
+ return THREAD_RET_VALUE;
+}
+
+
+/* This is one of our accountants. */
+static THREAD_RET_TYPE
+accountant_thread (void *arg)
+{
+ int i;
+ int acc1, acc2;
+ int value;
+
+ (void)arg;
+
+ for (i = 0; i < N_TRANSACTIONS; i++)
+ {
+ external_lock_test_lock (__LINE__);
+ acc1 = pick_account ();
+ acc2 = pick_account ();
+ value = pick_value ();
+ account[acc1] += value;
+ account[acc2] -= value;
+ external_lock_test_unlock (__LINE__);
+ }
+ return THREAD_RET_VALUE;
+}
+#endif
+
+
+static void
+run_test (void)
+{
+#ifdef _WIN32
+ HANDLE rthread;
+ HANDLE athreads[N_ACCOUNTANTS];
+ int i;
+ int rc;
+
+ external_lock_test_init (__LINE__);
+ stop_revision_thread = 0;
+ rthread = CreateThread (NULL, 0, revision_thread, NULL, 0, NULL);
+ if (!rthread)
+ die ("error creating revision thread: rc=%d", (int)GetLastError ());
+
+ for (i=0; i < N_ACCOUNTANTS; i++)
+ {
+ athreads[i] = CreateThread (NULL, 0, accountant_thread, NULL, 0, NULL);
+ if (!athreads[i])
+ die ("error creating accountant thread %d: rc=%d",
+ i, (int)GetLastError ());
+ }
+
+ for (i=0; i < N_ACCOUNTANTS; i++)
+ {
+ rc = WaitForSingleObject (athreads[i], INFINITE);
+ if (rc == WAIT_OBJECT_0)
+ info ("accountant thread %d has terminated", i);
+ else
+ fail ("waiting for accountant thread %d failed: %d",
+ i, (int)GetLastError ());
+ CloseHandle (athreads[i]);
+ }
+ stop_revision_thread = 1;
+
+ rc = WaitForSingleObject (rthread, INFINITE);
+ if (rc == WAIT_OBJECT_0)
+ info ("revision thread has terminated");
+ else
+ fail ("waiting for revision thread failed: %d", (int)GetLastError ());
+ CloseHandle (rthread);
+
+ external_lock_test_destroy (__LINE__);
+#elif HAVE_PTHREAD
+ pthread_t rthread;
+ pthread_t athreads[N_ACCOUNTANTS];
+ int rc, i;
+
+ external_lock_test_init (__LINE__);
+ stop_revision_thread = 0;
+ pthread_create (&rthread, NULL, revision_thread, NULL);
+
+ for (i=0; i < N_ACCOUNTANTS; i++)
+ pthread_create (&athreads[i], NULL, accountant_thread, NULL);
+
+ for (i=0; i < N_ACCOUNTANTS; i++)
+ {
+ rc = pthread_join (athreads[i], NULL);
+ if (rc)
+ fail ("pthread_join failed for accountant thread %d: %s",
+ i, strerror (errno));
+ else
+ info ("accountant thread %d has terminated", i);
+ }
+
+ stop_revision_thread = 1;
+ rc = pthread_join (rthread, NULL);
+ if (rc)
+ fail ("pthread_join failed for the revision thread: %s", strerror (errno));
+ else
+ info ("revision thread has terminated");
+
+ external_lock_test_destroy (__LINE__);
+#endif /*!_WIN32*/
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--help"))
+ {
+ puts (
+"usage: ./t-lock [options]\n"
+"\n"
+"Options:\n"
+" --verbose Show what is going on\n"
+" --debug Flyswatter\n"
+);
+ exit (0);
+ }
+ if (!strcmp (*argv, "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = debug = 1;
+ argc--; argv++;
+ }
+ }
+
+ srand ((unsigned int)time(NULL)*getpid());
+
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch");
+ /* We are using non-public interfaces - check the exact version. */
+ if (strcmp (gcry_check_version (NULL), GCRYPT_VERSION))
+ die ("exact version match failed");
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ check_nonce_lock ();
+
+ init_accounts ();
+ check_accounts ();
+
+ run_test ();
+ check_accounts ();
+
+ /* Run a second time to check deinit code. */
+ run_test ();
+ check_accounts ();
+
+ if (verbose)
+ print_accounts ();
+
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-mpi-bit.c b/comm/third_party/libgcrypt/tests/t-mpi-bit.c
new file mode 100644
index 0000000000..b66809f01e
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-mpi-bit.c
@@ -0,0 +1,362 @@
+/* t-mpi-bit.c - Tests for bit level functions
+ * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#define PGM "t-mpi-bit"
+#include "t-common.h"
+
+
+/* Allocate a bit string consisting of '0' and '1' from the MPI
+ A. Return the LENGTH least significant bits. Caller needs to xfree
+ the result. */
+static char *
+mpi2bitstr (gcry_mpi_t a, size_t length)
+{
+ char *p, *buf;
+
+ buf = p = xmalloc (length+1);
+ while (length--)
+ *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
+ *p = 0;
+
+ return buf;
+}
+
+/* Allocate a bit string consisting of '0' and '1' from the MPI A. Do
+ not return any leading zero bits. Caller needs to xfree the
+ result. */
+static char *
+mpi2bitstr_nlz (gcry_mpi_t a)
+{
+ char *p, *buf;
+ size_t length = gcry_mpi_get_nbits (a);
+
+ if (!length)
+ {
+ buf = p = xmalloc (2);
+ *p++ = '0';
+ }
+ else
+ {
+ buf = p = xmalloc (length + 1);
+ while (length-- > 1)
+ *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
+ *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
+ }
+ *p = 0;
+ return buf;
+}
+
+/* Shift a bit string to the right. */
+static void
+rshiftbitstring (char *string, size_t n)
+{
+ size_t len = strlen (string);
+
+ if (n > len)
+ n = len;
+
+ memmove (string+n, string, len-n);
+ memset (string, '0', n);
+}
+
+/* Shift a bit string to the left. Caller needs to free the result. */
+static char *
+lshiftbitstring (const char *string, size_t n)
+{
+ size_t len = strlen (string);
+ char *result;
+
+ if (len+n+1 < len)
+ die ("internal overflow\n");
+ /* Allocate enough space. */
+ result = xmalloc (len+n+1);
+ for (; *string == '0' && string[1]; string++, len--)
+ ;
+ memcpy (result, string, len);
+ if (*string == '0' && !string[1])
+ n = 0; /* Avoid extra nulls for an only 0 string. */
+ else
+ memset (result+len, '0', n);
+ result[len+n] = 0;
+ return result;
+}
+
+
+/* This is to check a bug reported by bpgcrypt at itaparica.org on
+ 2006-07-31 against libgcrypt 1.2.2. */
+static void
+one_bit_only (int highbit)
+{
+ gcry_mpi_t a;
+ char *result;
+ int i;
+
+ wherestr = "one_bit_only";
+ info ("checking that set_%sbit does only set one bit\n", highbit?"high":"");
+
+ a = gcry_mpi_new (0);
+ gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);
+ gcry_mpi_set_ui (a, 0);
+
+ if (highbit)
+ gcry_mpi_set_highbit (a, 42);
+ else
+ gcry_mpi_set_bit (a, 42);
+ if (!gcry_mpi_test_bit (a, 42))
+ fail ("failed to set a bit\n");
+ gcry_mpi_clear_bit (a, 42);
+ if (gcry_mpi_test_bit (a, 42))
+ fail ("failed to clear a bit\n");
+ result = mpi2bitstr (a, 70);
+ assert (strlen (result) == 70);
+ for (i=0; result[i]; i++)
+ if ( result[i] != '0' )
+ break;
+ if (result[i])
+ fail ("spurious bits detected\n");
+ xfree (result);
+ gcry_mpi_release (a);
+}
+
+/* Check that right shifting actually works for an amount larger than
+ the number of bits per limb. */
+static void
+test_rshift (int pass)
+{
+ gcry_mpi_t a, b;
+ char *result, *result2;
+ int i;
+
+ wherestr = "test_rshift";
+ info ("checking that rshift works as expected (pass %d)\n", pass);
+
+ a = gcry_mpi_new (0);
+ b = gcry_mpi_new (0);
+ gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);
+
+ for (i=0; i < 75; i++)
+ {
+ gcry_mpi_rshift (b, a, i);
+
+ result = mpi2bitstr (b, 72);
+ result2 = mpi2bitstr (a, 72);
+ rshiftbitstring (result2, i);
+ if (strcmp (result, result2))
+ {
+ info ("got =%s\n", result);
+ info ("want=%s\n", result2);
+ fail ("rshift by %d failed\n", i);
+ }
+ xfree (result);
+ xfree (result2);
+ }
+
+ /* Again. This time using in-place operation. */
+ gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);
+
+ for (i=0; i < 75; i++)
+ {
+ gcry_mpi_release (b);
+ b = gcry_mpi_copy (a);
+ gcry_mpi_rshift (b, b, i);
+
+ result = mpi2bitstr (b, 72);
+ result2 = mpi2bitstr (a, 72);
+ rshiftbitstring (result2, i);
+ if (strcmp (result, result2))
+ {
+ info ("got =%s\n", result);
+ info ("want=%s\n", result2);
+ fail ("in-place rshift by %d failed\n", i);
+ }
+ xfree (result2);
+ xfree (result);
+ }
+
+ gcry_mpi_release (b);
+ gcry_mpi_release (a);
+}
+
+/* Check that left shifting works correctly. */
+static void
+test_lshift (int pass)
+{
+ static int size_list[] = {1, 31, 32, 63, 64, 65, 70, 0};
+ int size_idx;
+ gcry_mpi_t a, b;
+ char *tmpstr, *result, *result2;
+ int i;
+
+ wherestr = "test_lshift";
+ info ("checking that lshift works as expected (pass %d)\n", pass);
+
+ for (size_idx=0; size_list[size_idx]; size_idx++)
+ {
+ a = gcry_mpi_new (0);
+ b = gcry_mpi_new (0);
+
+ /* gcry_mpi_randomize rounds up to full bytes, thus we need to
+ use gcry_mpi_clear_highbit to fix that. */
+ gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
+ gcry_mpi_clear_highbit (a, size_list[size_idx]);
+
+ for (i=0; i < 75; i++)
+ {
+ gcry_mpi_lshift (b, a, i);
+
+ result = mpi2bitstr_nlz (b);
+ tmpstr = mpi2bitstr_nlz (a);
+ result2 = lshiftbitstring (tmpstr, i);
+ xfree (tmpstr);
+ if (strcmp (result, result2))
+ {
+ info ("got =%s\n", result);
+ info ("want=%s\n", result2);
+ fail ("lshift by %d failed\n", i);
+ }
+ xfree (result);
+ xfree (result2);
+ }
+
+ /* Again. This time using in-place operation. */
+ gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
+ gcry_mpi_clear_highbit (a, size_list[size_idx]);
+
+ for (i=0; i < 75; i++)
+ {
+ gcry_mpi_release (b);
+ b = gcry_mpi_copy (a);
+ gcry_mpi_lshift (b, b, i);
+
+ result = mpi2bitstr_nlz (b);
+ tmpstr = mpi2bitstr_nlz (a);
+ result2 = lshiftbitstring (tmpstr, i);
+ xfree (tmpstr);
+ if (strcmp (result, result2))
+ {
+ info ("got =%s\n", result);
+ info ("want=%s\n", result2);
+ fail ("in-place lshift by %d failed\n", i);
+ }
+ xfree (result2);
+ xfree (result);
+ }
+
+ gcry_mpi_release (b);
+ gcry_mpi_release (a);
+ }
+}
+
+
+/* Bug fixed on 2014-05-09:
+ a = gcry_mpi_new (1523);
+ gcry_mpi_set_bit (a, 1536);
+ didn't initialized all limbs in A. */
+static void
+set_bit_with_resize (void)
+{
+ gcry_mpi_t a;
+ int i;
+
+ wherestr = "set_bit_with_resize";
+ info ("checking that set_bit initializes all limbs\n");
+
+ a = gcry_mpi_new (1536);
+ gcry_mpi_set_bit (a, 1536);
+
+ if (!gcry_mpi_test_bit (a, 1536))
+ fail ("failed to set a bit\n");
+ for (i=0; i < 1536; i++)
+ {
+ if (gcry_mpi_test_bit (a, i))
+ {
+ fail ("spurious bit detected\n");
+ break;
+ }
+ }
+ if (gcry_mpi_test_bit (a, 1537))
+ fail ("more bits set than expected\n");
+ gcry_mpi_release (a);
+
+ wherestr = "set_highbit_with_resize";
+ info ("checking that set_highbit initializes all limbs\n");
+
+ a = gcry_mpi_new (1536);
+ gcry_mpi_set_highbit (a, 1536);
+
+ if (!gcry_mpi_test_bit (a, 1536))
+ fail ("failed to set a bit\n");
+ for (i=0; i < 1536; i++)
+ {
+ if (gcry_mpi_test_bit (a, i))
+ {
+ fail ("spurious bit detected\n");
+ break;
+ }
+ }
+ if (gcry_mpi_test_bit (a, 1537))
+ fail ("more bits set than expected\n");
+ gcry_mpi_release (a);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int i;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ one_bit_only (0);
+ one_bit_only (1);
+ for (i=0; i < 5; i++)
+ test_rshift (i); /* Run several times due to random initializations. */
+
+ for (i=0; i < 5; i++)
+ test_lshift (i); /* Run several times due to random initializations. */
+
+ set_bit_with_resize ();
+
+ info ("All tests completed. Errors: %d\n", error_count);
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-mpi-point.c b/comm/third_party/libgcrypt/tests/t-mpi-point.c
new file mode 100644
index 0000000000..4e5552906a
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-mpi-point.c
@@ -0,0 +1,1324 @@
+/* t-mpi-point.c - Tests for mpi point functions
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#define PGM "t-mpi-point"
+#include "t-common.h"
+
+static struct
+{
+ const char *desc; /* Description of the curve. */
+ const char *p; /* Order of the prime field. */
+ const char *a, *b; /* The coefficients. */
+ const char *n; /* The order of the base point. */
+ const char *g_x, *g_y; /* Base point. */
+ const char *h; /* Cofactor. */
+} test_curve[] =
+ {
+ {
+ "NIST P-192",
+ "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
+ "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
+ "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
+ "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
+
+ "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
+ "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
+ "0x01"
+ },
+ {
+ "NIST P-224",
+ "0xffffffffffffffffffffffffffffffff000000000000000000000001",
+ "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
+ "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
+ "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
+
+ "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+ "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
+ "0x01"
+ },
+ {
+ "NIST P-256",
+ "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+ "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+ "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+ "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+
+ "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+ "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
+ "0x01"
+ },
+ {
+ "NIST P-384",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+ "ffffffff0000000000000000ffffffff",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+ "ffffffff0000000000000000fffffffc",
+ "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
+ "c656398d8a2ed19d2a85c8edd3ec2aef",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
+ "581a0db248b0a77aecec196accc52973",
+
+ "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
+ "5502f25dbf55296c3a545e3872760ab7",
+ "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
+ "0a60b1ce1d7e819d7a431d7c90ea0e5f",
+ "0x01"
+ },
+ {
+ "NIST P-521",
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
+ "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
+ "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+ "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+
+ "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
+ "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+ "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
+ "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
+ "0x01"
+ },
+ {
+ "Ed25519",
+ "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+ "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC",
+ "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3",
+ "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
+ "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
+ "0x6666666666666666666666666666666666666666666666666666666666666658",
+ "0x08"
+ },
+ { NULL, NULL, NULL, NULL, NULL, NULL }
+ };
+
+/* A sample public key for NIST P-256. */
+static const char sample_p256_q[] =
+ "04"
+ "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E"
+ "E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E";
+static const char sample_p256_q_x[] =
+ "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E";
+static const char sample_p256_q_y[] =
+ "00E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E";
+
+
+/* A sample public key for Ed25519. */
+static const char sample_ed25519_q[] =
+ "04"
+ "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce"
+ "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7";
+static const char sample_ed25519_q_x[] =
+ "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce";
+static const char sample_ed25519_q_y[] =
+ "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7";
+static const char sample_ed25519_q_eddsa[] =
+ "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a";
+static const char sample_ed25519_d[] =
+ "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60";
+
+
+static void
+print_mpi_2 (const char *text, const char *text2, gcry_mpi_t a)
+{
+ gcry_error_t err;
+ char *buf;
+ void *bufaddr = &buf;
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+ if (err)
+ fprintf (stderr, "%s%s: [error printing number: %s]\n",
+ text, text2? text2:"", gpg_strerror (err));
+ else
+ {
+ fprintf (stderr, "%s%s: %s\n", text, text2? text2:"", buf);
+ gcry_free (buf);
+ }
+}
+
+
+static void
+print_mpi (const char *text, gcry_mpi_t a)
+{
+ print_mpi_2 (text, NULL, a);
+}
+
+
+static void
+print_point (const char *text, gcry_mpi_point_t a)
+{
+ gcry_mpi_t x, y, z;
+
+ x = gcry_mpi_new (0);
+ y = gcry_mpi_new (0);
+ z = gcry_mpi_new (0);
+ gcry_mpi_point_get (x, y, z, a);
+ print_mpi_2 (text, ".x", x);
+ print_mpi_2 (text, ".y", y);
+ print_mpi_2 (text, ".z", z);
+ gcry_mpi_release (x);
+ gcry_mpi_release (y);
+ gcry_mpi_release (z);
+}
+
+
+static void
+print_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 gcry_mpi_t
+hex2mpi (const char *string)
+{
+ gpg_error_t err;
+ gcry_mpi_t val;
+
+ err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (err)
+ die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err));
+ return val;
+}
+
+
+/* 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 returns NULL 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))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static gcry_mpi_t
+hex2mpiopa (const char *string)
+{
+ char *buffer;
+ size_t buflen;
+ gcry_mpi_t val;
+
+ buffer = hex2buffer (string, &buflen);
+ if (!buffer)
+ die ("hex2mpiopa '%s' failed: parser error\n", string);
+ val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
+ if (!buffer)
+ die ("hex2mpiopa '%s' failed: set_opaque error\n", string);
+ return val;
+}
+
+
+/* Compare A to B, where B is given as a hex string. */
+static int
+cmp_mpihex (gcry_mpi_t a, const char *b)
+{
+ gcry_mpi_t bval;
+ int res;
+
+ if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+ bval = hex2mpiopa (b);
+ else
+ bval = hex2mpi (b);
+ res = gcry_mpi_cmp (a, bval);
+ gcry_mpi_release (bval);
+ return res;
+}
+
+
+/* Wrapper to emulate the libgcrypt internal EC context allocation
+ function. */
+static gpg_error_t
+ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a)
+{
+ gpg_error_t err;
+ gcry_sexp_t sexp;
+
+ if (p && a)
+ err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m)(a %m))", p, a);
+ else if (p)
+ err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m))", p);
+ else if (a)
+ err = gcry_sexp_build (&sexp, NULL, "(ecdsa (a %m))", a);
+ else
+ err = gcry_sexp_build (&sexp, NULL, "(ecdsa)");
+ if (err)
+ return err;
+ err = gcry_mpi_ec_new (r_ctx, sexp, NULL);
+ gcry_sexp_release (sexp);
+ return err;
+}
+
+
+
+static void
+set_get_point (void)
+{
+ gcry_mpi_point_t point, point2;
+ gcry_mpi_t x, y, z;
+
+ wherestr = "set_get_point";
+ info ("checking point setting functions\n");
+
+ point = gcry_mpi_point_new (0);
+ x = gcry_mpi_set_ui (NULL, 17);
+ y = gcry_mpi_set_ui (NULL, 42);
+ z = gcry_mpi_set_ui (NULL, 11371);
+ gcry_mpi_point_get (x, y, z, point);
+ if (gcry_mpi_cmp_ui (x, 0)
+ || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0))
+ fail ("new point not initialized to (0,0,0)\n");
+ gcry_mpi_point_snatch_get (x, y, z, point);
+ point = NULL;
+ if (gcry_mpi_cmp_ui (x, 0)
+ || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0))
+ fail ("snatch_get failed\n");
+ gcry_mpi_release (x);
+ gcry_mpi_release (y);
+ gcry_mpi_release (z);
+
+ point = gcry_mpi_point_new (0);
+ x = gcry_mpi_set_ui (NULL, 17);
+ y = gcry_mpi_set_ui (NULL, 42);
+ z = gcry_mpi_set_ui (NULL, 11371);
+ gcry_mpi_point_set (point, x, y, z);
+ gcry_mpi_set_ui (x, 23);
+ gcry_mpi_set_ui (y, 24);
+ gcry_mpi_set_ui (z, 25);
+ gcry_mpi_point_get (x, y, z, point);
+ if (gcry_mpi_cmp_ui (x, 17)
+ || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
+ fail ("point_set/point_get failed\n");
+ gcry_mpi_point_snatch_set (point, x, y, z);
+ x = gcry_mpi_new (0);
+ y = gcry_mpi_new (0);
+ z = gcry_mpi_new (0);
+ gcry_mpi_point_get (x, y, z, point);
+ if (gcry_mpi_cmp_ui (x, 17)
+ || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
+ fail ("point_snatch_set/point_get failed\n");
+
+ point2 = gcry_mpi_point_copy (point);
+
+ gcry_mpi_point_get (x, y, z, point2);
+ if (gcry_mpi_cmp_ui (x, 17)
+ || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
+ fail ("point_copy failed (1)\n");
+
+ gcry_mpi_point_release (point);
+
+ gcry_mpi_point_get (x, y, z, point2);
+ if (gcry_mpi_cmp_ui (x, 17)
+ || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
+ fail ("point_copy failed (2)\n");
+
+ gcry_mpi_point_release (point2);
+
+ gcry_mpi_release (x);
+ gcry_mpi_release (y);
+ gcry_mpi_release (z);
+}
+
+
+static void
+context_alloc (void)
+{
+ gpg_error_t err;
+ gcry_ctx_t ctx;
+ gcry_mpi_t p, a;
+
+ wherestr = "context_alloc";
+ info ("checking context functions\n");
+
+ p = gcry_mpi_set_ui (NULL, 1);
+ a = gcry_mpi_set_ui (NULL, 1);
+ err = ec_p_new (&ctx, p, a);
+ if (err)
+ die ("ec_p_new returned an error: %s\n", gpg_strerror (err));
+ gcry_mpi_release (p);
+ gcry_mpi_release (a);
+ gcry_ctx_release (ctx);
+
+ p = NULL;
+ a = gcry_mpi_set_ui (NULL, 0);
+
+ err = ec_p_new (&ctx, p, a);
+ if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
+ fail ("ec_p_new: bad parameter detection failed (1)\n");
+
+ gcry_mpi_release (a);
+ a = NULL;
+ err = ec_p_new (&ctx, p, a);
+ if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
+ fail ("ec_p_new: bad parameter detection failed (2)\n");
+
+}
+
+
+static int
+get_and_cmp_mpi (const char *name, const char *mpistring, const char *desc,
+ gcry_ctx_t ctx)
+{
+ gcry_mpi_t mpi;
+
+ mpi = gcry_mpi_ec_get_mpi (name, ctx, 1);
+ if (!mpi)
+ {
+ fail ("error getting parameter '%s' of curve '%s'\n", name, desc);
+ return 1;
+ }
+ if (debug)
+ print_mpi (name, mpi);
+ if (cmp_mpihex (mpi, mpistring))
+ {
+ fail ("parameter '%s' of curve '%s' does not match\n", name, desc);
+ gcry_mpi_release (mpi);
+ return 1;
+ }
+ gcry_mpi_release (mpi);
+ return 0;
+}
+
+
+static int
+get_and_cmp_point (const char *name,
+ const char *mpi_x_string, const char *mpi_y_string,
+ const char *desc, gcry_ctx_t ctx)
+{
+ gcry_mpi_point_t point;
+ gcry_mpi_t x, y, z;
+ int result = 0;
+
+ point = gcry_mpi_ec_get_point (name, ctx, 1);
+ if (!point)
+ {
+ fail ("error getting point parameter '%s' of curve '%s'\n", name, desc);
+ return 1;
+ }
+ if (debug)
+ print_point (name, point);
+
+ x = gcry_mpi_new (0);
+ y = gcry_mpi_new (0);
+ z = gcry_mpi_new (0);
+ gcry_mpi_point_snatch_get (x, y, z, point);
+ if (cmp_mpihex (x, mpi_x_string))
+ {
+ fail ("x coordinate of '%s' of curve '%s' does not match\n", name, desc);
+ result = 1;
+ }
+ if (cmp_mpihex (y, mpi_y_string))
+ {
+ fail ("y coordinate of '%s' of curve '%s' does not match\n", name, desc);
+ result = 1;
+ }
+ if (cmp_mpihex (z, "01"))
+ {
+ fail ("z coordinate of '%s' of curve '%s' is not 1\n", name, desc);
+ result = 1;
+ }
+ gcry_mpi_release (x);
+ gcry_mpi_release (y);
+ gcry_mpi_release (z);
+ return result;
+}
+
+
+static void
+context_param (void)
+{
+ gpg_error_t err;
+ int idx;
+ gcry_ctx_t ctx = NULL;
+ gcry_mpi_t q, d;
+ gcry_sexp_t keyparam;
+
+ wherestr = "context_param";
+
+ info ("checking standard curves\n");
+ for (idx=0; test_curve[idx].desc; idx++)
+ {
+ /* P-192 and Ed25519 are not supported in fips mode */
+ if (gcry_fips_mode_active())
+ {
+ if (!strcmp(test_curve[idx].desc, "NIST P-192")
+ || !strcmp(test_curve[idx].desc, "Ed25519"))
+ {
+ info ("skipping %s in fips mode\n", test_curve[idx].desc );
+ continue;
+ }
+ }
+
+ gcry_ctx_release (ctx);
+ err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc);
+ if (err)
+ {
+ fail ("can't create context for curve '%s': %s\n",
+ test_curve[idx].desc, gpg_strerror (err));
+ continue;
+ }
+ if (get_and_cmp_mpi ("p", test_curve[idx].p, test_curve[idx].desc, ctx))
+ continue;
+ if (get_and_cmp_mpi ("a", test_curve[idx].a, test_curve[idx].desc, ctx))
+ continue;
+ if (get_and_cmp_mpi ("b", test_curve[idx].b, test_curve[idx].desc, ctx))
+ continue;
+ if (get_and_cmp_mpi ("g.x",test_curve[idx].g_x, test_curve[idx].desc,ctx))
+ continue;
+ if (get_and_cmp_mpi ("g.y",test_curve[idx].g_y, test_curve[idx].desc,ctx))
+ continue;
+ if (get_and_cmp_mpi ("n", test_curve[idx].n, test_curve[idx].desc, ctx))
+ continue;
+ if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y,
+ test_curve[idx].desc, ctx))
+ continue;
+ if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx))
+ continue;
+
+ }
+
+ info ("checking sample public key (nistp256)\n");
+ q = hex2mpi (sample_p256_q);
+ err = gcry_sexp_build (&keyparam, NULL,
+ "(public-key(ecc(curve %s)(q %m)))",
+ "NIST P-256", q);
+ if (err)
+ die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
+ gcry_mpi_release (q);
+
+ /* We can't call gcry_pk_testkey because it is only implemented for
+ private keys. */
+ /* err = gcry_pk_testkey (keyparam); */
+ /* if (err) */
+ /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */
+ /* gpg_strerror (err)); */
+
+ gcry_ctx_release (ctx);
+ err = gcry_mpi_ec_new (&ctx, keyparam, NULL);
+ if (err)
+ fail ("gcry_mpi_ec_new failed for sample public key (nistp256): %s\n",
+ gpg_strerror (err));
+ else
+ {
+ gcry_sexp_t sexp;
+
+ get_and_cmp_mpi ("q", sample_p256_q, "nistp256", ctx);
+ get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "nistp256",
+ ctx);
+
+ /* Delete Q. */
+ err = gcry_mpi_ec_set_mpi ("q", NULL, ctx);
+ if (err)
+ fail ("clearing Q for nistp256 failed: %s\n", gpg_strerror (err));
+ if (gcry_mpi_ec_get_mpi ("q", ctx, 0))
+ fail ("clearing Q for nistp256 did not work\n");
+
+ /* Set Q again. */
+ q = hex2mpi (sample_p256_q);
+ err = gcry_mpi_ec_set_mpi ("q", q, ctx);
+ if (err)
+ fail ("setting Q for nistp256 failed: %s\n", gpg_strerror (err));
+ get_and_cmp_mpi ("q", sample_p256_q, "nistp256(2)", ctx);
+ gcry_mpi_release (q);
+
+ /* Get as s-expression. */
+ err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+ if (err)
+ fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
+ else if (debug)
+ print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
+ gcry_sexp_release (sexp);
+
+ err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
+ if (err)
+ fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n",
+ gpg_strerror (err));
+ else if (debug)
+ print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
+ gcry_sexp_release (sexp);
+
+ err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
+ if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
+ fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
+ gpg_strerror (err));
+ gcry_sexp_release (sexp);
+ }
+
+ /* Skipping Ed25519 if in FIPS mode (it isn't supported) */
+ if (gcry_fips_mode_active())
+ goto cleanup;
+
+ info ("checking sample public key (Ed25519)\n");
+ q = hex2mpi (sample_ed25519_q);
+ gcry_sexp_release (keyparam);
+ err = gcry_sexp_build (&keyparam, NULL,
+ "(public-key(ecc(curve %s)(flags eddsa)(q %m)))",
+ "Ed25519", q);
+ if (err)
+ die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
+ gcry_mpi_release (q);
+
+ /* We can't call gcry_pk_testkey because it is only implemented for
+ private keys. */
+ /* err = gcry_pk_testkey (keyparam); */
+ /* if (err) */
+ /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */
+ /* gpg_strerror (err)); */
+
+ gcry_ctx_release (ctx);
+ err = gcry_mpi_ec_new (&ctx, keyparam, NULL);
+ if (err)
+ fail ("gcry_mpi_ec_new failed for sample public key: %s\n",
+ gpg_strerror (err));
+ else
+ {
+ gcry_sexp_t sexp;
+
+ get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519", ctx);
+ get_and_cmp_point ("q", sample_ed25519_q_x, sample_ed25519_q_y,
+ "Ed25519", ctx);
+ get_and_cmp_mpi ("q@eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx);
+
+ /* Set d to see whether Q is correctly re-computed. */
+ d = hex2mpi (sample_ed25519_d);
+ err = gcry_mpi_ec_set_mpi ("d", d, ctx);
+ if (err)
+ fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err));
+ gcry_mpi_release (d);
+ get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx);
+
+ /* Delete Q by setting d and then clearing d. The clearing is
+ required so that we can check whether Q has been cleared and
+ because further tests only expect a public key. */
+ d = hex2mpi (sample_ed25519_d);
+ err = gcry_mpi_ec_set_mpi ("d", d, ctx);
+ if (err)
+ fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err));
+ gcry_mpi_release (d);
+ err = gcry_mpi_ec_set_mpi ("d", NULL, ctx);
+ if (err)
+ fail ("setting d for Ed25519 failed(2): %s\n", gpg_strerror (err));
+ if (gcry_mpi_ec_get_mpi ("q", ctx, 0))
+ fail ("setting d for Ed25519 did not reset Q\n");
+
+ /* Set Q again. We need to use an opaque MPI here because
+ sample_ed25519_q is in uncompressed format which can only be
+ auto-detected if passed opaque. */
+ q = hex2mpiopa (sample_ed25519_q);
+ err = gcry_mpi_ec_set_mpi ("q", q, ctx);
+ if (err)
+ fail ("setting Q for Ed25519 failed: %s\n", gpg_strerror (err));
+ gcry_mpi_release (q);
+ get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(2)", ctx);
+
+ /* Get as s-expression. */
+ err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+ if (err)
+ fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
+ else if (debug)
+ print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
+ gcry_sexp_release (sexp);
+
+ err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
+ if (err)
+ fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n",
+ gpg_strerror (err));
+ else if (debug)
+ print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
+ gcry_sexp_release (sexp);
+
+ err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
+ if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
+ fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
+ gpg_strerror (err));
+ gcry_sexp_release (sexp);
+
+ }
+
+ cleanup:
+ gcry_ctx_release (ctx);
+ gcry_sexp_release (keyparam);
+}
+
+
+
+
+/* Create a new point from (X,Y,Z) given as hex strings. */
+gcry_mpi_point_t
+make_point (const char *x, const char *y, const char *z)
+{
+ gcry_mpi_point_t point;
+
+ point = gcry_mpi_point_new (0);
+ gcry_mpi_point_snatch_set (point, hex2mpi (x), hex2mpi (y), hex2mpi (z));
+
+ return point;
+}
+
+
+/* This tests checks that the low-level EC API yields the same result
+ as using the high level API. The values have been taken from a
+ test run using the high level API. */
+static void
+basic_ec_math (void)
+{
+ gpg_error_t err;
+ gcry_ctx_t ctx;
+ gcry_mpi_t P, A;
+ gcry_mpi_point_t G, Q;
+ gcry_mpi_t d;
+ gcry_mpi_t x, y, z;
+
+ wherestr = "basic_ec_math";
+ info ("checking basic math functions for EC\n");
+
+ P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff");
+ A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc");
+ G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+ "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+ "1");
+ d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
+ Q = gcry_mpi_point_new (0);
+
+ err = ec_p_new (&ctx, P, A);
+ if (err)
+ die ("ec_p_new failed: %s\n", gpg_strerror (err));
+
+ x = gcry_mpi_new (0);
+ y = gcry_mpi_new (0);
+ z = gcry_mpi_new (0);
+
+ {
+ /* A quick check that multiply by zero works. */
+ gcry_mpi_t tmp;
+
+ tmp = gcry_mpi_new (0);
+ gcry_mpi_ec_mul (Q, tmp, G, ctx);
+ gcry_mpi_release (tmp);
+ gcry_mpi_point_get (x, y, z, Q);
+ if (gcry_mpi_cmp_ui (z, 0))
+ fail ("multiply a point by zero failed\n");
+ }
+
+ gcry_mpi_ec_mul (Q, d, G, ctx);
+
+ if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+ fail ("failed to get affine coordinates\n");
+ if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE")
+ || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966"))
+ fail ("computed affine coordinates of public key do not match\n");
+ if (debug)
+ {
+ print_mpi ("q.x", x);
+ print_mpi ("q.y", y);
+ }
+
+ gcry_mpi_release (z);
+ gcry_mpi_release (y);
+ gcry_mpi_release (x);
+ gcry_mpi_point_release (Q);
+ gcry_mpi_release (d);
+ gcry_mpi_point_release (G);
+ gcry_mpi_release (A);
+ gcry_mpi_release (P);
+ gcry_ctx_release (ctx);
+}
+
+
+/* This is the same as basic_ec_math but uses more advanced
+ features. */
+static void
+basic_ec_math_simplified (void)
+{
+ gpg_error_t err;
+ gcry_ctx_t ctx;
+ gcry_mpi_point_t G, Q;
+ gcry_mpi_t d;
+ gcry_mpi_t x, y, z;
+ gcry_sexp_t sexp;
+
+ wherestr = "basic_ec_math_simplified";
+ info ("checking basic math functions for EC (variant)\n");
+
+ d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
+ Q = gcry_mpi_point_new (0);
+
+ err = gcry_mpi_ec_new (&ctx, NULL, "NIST P-192");
+ if (err)
+ die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));
+ G = gcry_mpi_ec_get_point ("g", ctx, 1);
+ if (!G)
+ die ("gcry_mpi_ec_get_point(G) failed\n");
+ gcry_mpi_ec_mul (Q, d, G, ctx);
+
+ x = gcry_mpi_new (0);
+ y = gcry_mpi_new (0);
+ z = gcry_mpi_new (0);
+
+ if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+ fail ("failed to get affine coordinates\n");
+ if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE")
+ || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966"))
+ fail ("computed affine coordinates of public key do not match\n");
+ if (debug)
+ {
+ print_mpi ("q.x", x);
+ print_mpi ("q.y", y);
+ }
+
+ gcry_mpi_release (z);
+ gcry_mpi_release (y);
+ gcry_mpi_release (x);
+
+ /* Let us also check whether we can update the context. */
+ err = gcry_mpi_ec_set_point ("g", G, ctx);
+ if (err)
+ die ("gcry_mpi_ec_set_point(G) failed\n");
+ err = gcry_mpi_ec_set_mpi ("d", d, ctx);
+ if (err)
+ die ("gcry_mpi_ec_set_mpi(d) failed\n");
+
+ /* FIXME: Below we need to check that the returned S-expression is
+ as requested. For now we use manual inspection using --debug. */
+
+ /* Does get_sexp return the private key? */
+ err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+ if (err)
+ fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
+ else if (debug)
+ print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
+ gcry_sexp_release (sexp);
+
+ /* Does get_sexp return the public key if requested? */
+ err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
+ if (err)
+ fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", gpg_strerror (err));
+ else if (debug)
+ print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
+ gcry_sexp_release (sexp);
+
+ /* Does get_sexp return the public key after d has been deleted? */
+ err = gcry_mpi_ec_set_mpi ("d", NULL, ctx);
+ if (err)
+ die ("gcry_mpi_ec_set_mpi(d=NULL) failed\n");
+ err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+ if (err)
+ fail ("gcry_pubkey_get_sexp(0 w/o d) failed: %s\n", gpg_strerror (err));
+ else if (debug)
+ print_sexp ("Result of gcry_pubkey_get_sexp (0 w/o d):\n", sexp);
+ gcry_sexp_release (sexp);
+
+ /* Does get_sexp return an error after d has been deleted? */
+ err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
+ if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
+ fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
+ gpg_strerror (err));
+ gcry_sexp_release (sexp);
+
+ /* Does get_sexp return an error after d and Q have been deleted? */
+ err = gcry_mpi_ec_set_point ("q", NULL, ctx);
+ if (err)
+ die ("gcry_mpi_ec_set_point(q=NULL) failed\n");
+ err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+ if (gpg_err_code (err) != GPG_ERR_BAD_CRYPT_CTX)
+ fail ("gcry_pubkey_get_sexp(0 w/o Q,d) returned wrong error: %s\n",
+ gpg_strerror (err));
+ gcry_sexp_release (sexp);
+
+
+ gcry_mpi_point_release (Q);
+ gcry_mpi_release (d);
+ gcry_mpi_point_release (G);
+ gcry_ctx_release (ctx);
+}
+
+
+/* Check the math used with Twisted Edwards curves. */
+static void
+twistededwards_math (void)
+{
+ gpg_error_t err;
+ gcry_ctx_t ctx;
+ gcry_mpi_point_t G, Q;
+ gcry_mpi_t k;
+ gcry_mpi_t w, a, x, y, z, p, n, b, I;
+
+ wherestr = "twistededwards_math";
+ info ("checking basic Twisted Edwards math\n");
+
+ err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519");
+ if (err)
+ die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));
+
+ k = hex2mpi
+ ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004"
+ "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6");
+ G = gcry_mpi_ec_get_point ("g", ctx, 1);
+ if (!G)
+ die ("gcry_mpi_ec_get_point(G) failed\n");
+ Q = gcry_mpi_point_new (0);
+
+
+ w = gcry_mpi_new (0);
+ a = gcry_mpi_new (0);
+ x = gcry_mpi_new (0);
+ y = gcry_mpi_new (0);
+ z = gcry_mpi_new (0);
+ I = gcry_mpi_new (0);
+ p = gcry_mpi_ec_get_mpi ("p", ctx, 1);
+ n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
+ b = gcry_mpi_ec_get_mpi ("b", ctx, 1);
+
+ /* Check: 2^{p-1} mod p == 1 */
+ gcry_mpi_sub_ui (a, p, 1);
+ gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p);
+ if (gcry_mpi_cmp_ui (w, 1))
+ fail ("failed assertion: 2^{p-1} mod p == 1\n");
+
+ /* Check: p % 4 == 1 */
+ gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR);
+ if (gcry_mpi_cmp_ui (w, 1))
+ fail ("failed assertion: p %% 4 == 1\n");
+
+ /* Check: 2^{n-1} mod n == 1 */
+ gcry_mpi_sub_ui (a, n, 1);
+ gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n);
+ if (gcry_mpi_cmp_ui (w, 1))
+ fail ("failed assertion: 2^{n-1} mod n == 1\n");
+
+ /* Check: b^{(p-1)/2} mod p == p-1 */
+ gcry_mpi_sub_ui (a, p, 1);
+ gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1);
+ gcry_mpi_powm (w, b, x, p);
+ gcry_mpi_abs (w);
+ if (gcry_mpi_cmp (w, a))
+ fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n");
+
+ /* I := 2^{(p-1)/4} mod p */
+ gcry_mpi_sub_ui (a, p, 1);
+ gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1);
+ gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p);
+
+ /* Check: I^2 mod p == p-1 */
+ gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p);
+ if (gcry_mpi_cmp (w, a))
+ fail ("failed assertion: I^2 mod p == p-1\n");
+
+ /* Check: G is on the curve */
+ if (!gcry_mpi_ec_curve_point (G, ctx))
+ fail ("failed assertion: G is on the curve\n");
+
+ /* Check: nG == (0,1) */
+ gcry_mpi_ec_mul (Q, n, G, ctx);
+ if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+ fail ("failed to get affine coordinates\n");
+ if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1))
+ fail ("failed assertion: nG == (0,1)\n");
+
+ /* Now two arbitrary point operations taken from the ed25519.py
+ sample data. */
+ gcry_mpi_release (a);
+ a = hex2mpi
+ ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496"
+ "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3");
+ gcry_mpi_ec_mul (Q, a, G, ctx);
+ if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+ fail ("failed to get affine coordinates\n");
+ if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be"
+ "00014fecc2165ca5cee9eee19fe4d2c1"))
+ || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2"
+ "4025645f0b820e72b8cad4f0a909a092")))
+ {
+ fail ("sample point multiply failed:\n");
+ print_mpi ("r", a);
+ print_mpi ("Rx", x);
+ print_mpi ("Ry", y);
+ }
+
+ gcry_mpi_release (a);
+ a = hex2mpi
+ ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004"
+ "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6");
+ gcry_mpi_ec_mul (Q, a, G, ctx);
+ if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+ fail ("failed to get affine coordinates\n");
+ if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371"
+ "82324bd01ce6f3cf81ab44e62959c82a"))
+ || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784"
+ "8a826e80cce2869072ac60c3004356e5")))
+ {
+ fail ("sample point multiply failed:\n");
+ print_mpi ("r", a);
+ print_mpi ("Rx", x);
+ print_mpi ("Ry", y);
+ }
+
+
+ gcry_mpi_release (I);
+ gcry_mpi_release (b);
+ gcry_mpi_release (n);
+ gcry_mpi_release (p);
+ gcry_mpi_release (w);
+ gcry_mpi_release (a);
+ gcry_mpi_release (x);
+ gcry_mpi_release (y);
+ gcry_mpi_release (z);
+ gcry_mpi_point_release (Q);
+ gcry_mpi_point_release (G);
+ gcry_mpi_release (k);
+ gcry_ctx_release (ctx);
+}
+
+
+/* Check the point on curve function. */
+static void
+point_on_curve (void)
+{
+ static struct {
+ const char *curve;
+ int oncurve; /* Point below is on the curve. */
+ const char *qx;
+ const char *qy;
+ } t[] = {
+ {
+ "NIST P-256", 0,
+ "015B4F6775D68D4D2E2192C6B8027FC5A3D49957E453CB251155AA3FF5D3EC9974",
+ "4BC4C87B57A25E1056831208AB5B8F091142F891E9FF19F1E090B030DF1087B3"
+ }, {
+ "NIST P-256", 0,
+ "D22C316E7EBE7B293BD66808E000806F0754398A5D72A4F9BBC21C26EAC0A651",
+ "3C8DB80CC3CDE5E530D040536E6A58AAB41C33FA70B30896943513FF3690132D"
+ }, {
+ "NIST P-256", 0,
+ "0130F7E7BC52854CA493A0DE87DC4AB3B4343758F2B634F15B10D70DBC0A5A5291",
+ "86F9CA73C25CE86D54CB21C181AECBB52A5971334FF5040F76CAE9845ED46023"
+ }, {
+ "NIST P-256", 1,
+ "14957B602C7849F28858C7407696F014BC091D6D68C449560B7A38147D6E6A9B",
+ "A8E09EFEECFE00C797A0848F38B61992D30C61FAB13021E88C8BD3545B3A6C63"
+ }, {
+ "NIST P-256", 0,
+ "923DE4957241DD97780841C76294DB0D4F5DC04C3045081174764D2D32AD2D53",
+ "01B4B1A2027C02F0F520A3B01E4CE3C668BF481346A74499C5D1044A53E210B600"
+ }, {
+ "NIST P-256", 1,
+ "9021DFAB8B4DAEAADA634AAA26D6E5FFDF8C0476FF5CA31606C870A1B933FB36",
+ "9AFC65EEB24E46C7B75712EF29A981CB09FAC56E2B81D3ED024748CCAB1CB77E"
+ }, {
+ "NIST P-256", 0,
+ "011529F0B26DE5E0EB2DA4BFB6C149C802CB52EE479DD666553286928A4005E990",
+ "0EBC63DB2104884456DC0AA81A3F4E99D93B7AE2CD4B1489655EA9BE6289CF9E"
+ }, {
+ "NIST P-256", 1,
+ "216EC5DE8CA989199D31F0DFCD381DCC9270A0785365EC3E34CA347C070A87BE",
+ "87A88897BA763509ECC1DBE28D9D37F6F4E70E3B99B1CD3C0B934D4190968A6D"
+ }, {
+ "NIST P-256", 1,
+ "7ABAA44ACBC6016FDB52A6F45F6178E65CBFC35F9920D99149CA9999612CE945",
+ "88F7684BDCDA31EAFB6CAD859F8AB29B5D921D7DB2B34DF7E40CE36235F45B63"
+ }, {
+ "NIST P-256", 0,
+ "E765B4272D211DD0064189B55421FB76BB3A7756364A6CB1627FAED848157A84",
+ "C13171CFFB243E06B203F0996BBDD16F52292AD11F2DA81106E9C2FD87F4FA0F"
+ }, {
+ "NIST P-256", 0,
+ "EE4999DFC3A1871EE7A592BE26A09BEC9D9B561613EE9EFB6ED42F17985C9CDC",
+ "8399E967338A7A618336AF70DA67D9CAC1C19267809652F5C5183C8B129E0902"
+ }, {
+ "NIST P-256", 0,
+ "F755D0CF2642A2C7FBACCC8E9E442B8B047A99C6E052B2FA5AB0544B36B4D51C",
+ "AA080F17657B6565D9A4D94BD260B54D92FEE8DC4A78C4FC9C19209933AF39B0"
+ } , {
+ "NIST P-384", 0,
+ "CBFC7DBEBF15BEAD682549757F9BBA0E3F67669DF13FCE0EBE8024B725B38B00"
+ "83EC46A8F2FF3203C5C7F8C7E722A5EF",
+ "0548FE281BEAB18FD1AB86F59B0CA524479A4A81373C83B78AFFD801FAC75922"
+ "96470753DCF46173C9AA4A8A4C2FBE51"
+ }, {
+ "NIST P-384", 0,
+ "1DC8E054A883DB81EAEDE6C487B26816C927B8196780525A6CA8F675D2557752"
+ "02CE06CCBE705EA8A38AA2894D4BEEE6",
+ "010191050E867AFAA96A199FE9C591CF8B853D81486786DA889124881FB39D2F"
+ "8E0875F4C4BB1E3D0F8535C7A52306FB82"
+ }, {
+ "NIST P-384", 1,
+ "2539FC368CE1D5E464B6C0FBB12D557B712327DB086975255AD7D17F7E7E4F23"
+ "D719ED4116E2CC907AEB92CF22331A60",
+ "8843FDBA742CB64323E49CEBE8DD74908CFC9C3AA0015662DFBB7219E92CF32E"
+ "9FC63F61EF19DE9B3CEA98D163ABF254"
+ }, {
+ "NIST P-384", 0,
+ "0B786DACF400D43575394349EDD9F9CD145FC7EF737A3C5F69B253BE7639DB24"
+ "EC2F0CA62FF1F90B6515DE356EC2A404",
+ "225D6B2939CC7F7133F43353946A682C68DAC6BB75EE9CF6BD9A1609FA915692"
+ "72F4D3A87E88529754E109BB9B61B03B"
+ }, {
+ "NIST P-384", 0,
+ "76C660C9F58CF2051F9F8B06049694AB6FE418009DE6F0A0833BC690CEC06CC2"
+ "9A440AD51C94CF5BC28817C8C6E2D302",
+ "012974E5D9E55304ED294AB6C7A3C65B663E67ABC5E6F6C0F6498B519F2F6CA1"
+ "8306976291F3ADC0B5ABA42DED376EA9A5"
+ }, {
+ "NIST P-384", 0,
+ "23D758B1EDB8E12E9E707C53C131A19D9464B20EE05C99766F5ABDF9F906AD03"
+ "B958BF28B022E54E320672C4BAD4EEC0",
+ "01E9E72870C88F4C82A5AB3CC8A3398E8F006BF3EC05FFBB1EFF8AEE88020FEA"
+ "9E558E9F58ED1D324C9DCBCB4E8F2A5970"
+ }, {
+ "NIST P-384", 0,
+ "D062B96D5A10F715ACF361F99262ABF0F7693A8BB60ECB1DF459CF95750E4293"
+ "18BCB9FC60499D009F949298F3F9F47B",
+ "9089C6328E4B39A73D7EE6FAE1A77E48CE354B83BBCE432082C32C8FD6784B86"
+ "CFE9C552E2E720F5DA5806503D3784CD"
+ }, {
+ "NIST P-384", 0,
+ "2A951D4D6EB35C43D94866280D37365B82441BC84D62CBFF3365CAB1FD0A3E20"
+ "823CA8F84D2BBF4EA687885437DE7839",
+ "01CC7D762AFE613F7B5568BC516568A421159C40599E8D52DE10E8F9488931E1"
+ "69F3656C322DE45C4A70DC6DB9A661E599"
+ }, {
+ "NIST P-384", 1,
+ "A4BAEE6CDAF3AEB69032B3FBA811707C54F5753670DA5173D891547E8CBAEEF3"
+ "89B92C9A55573A596123415FBFA26991",
+ "3241EA716583C11C71BB30AF6C5E3A6637956F17ADBBE641BAB52E8539F9FC7B"
+ "F3B04F46DBFFE08151E0F0950CC70081"
+ }, {
+ "NIST P-384", 0,
+ "5C0E18B0DE3261BCBCFC7B702C2D75CF481336BFBADF420BADC616235C1966AB"
+ "4C0F876575DDEC1BDB3F3F04061C9AE4",
+ "E90C78550D1C922F1D8161D8C9C0576E29BD09CA665376FA887D13FA8DF48352"
+ "D7BBEEFB803F6CC8FC7895E47F348D33"
+ }, {
+ "NIST P-384", 1,
+ "2015864CD50F0A1A50E6401F44191665C19E4AD4B4903EA9EB464E95D1070E36"
+ "F1D8325E45734D5A0FDD103F4DF6F83E",
+ "5FB3E9A5C59DD5C5262A8176CB7032A00AE33AED08485884A3E5D68D9EEB990B"
+ "F26E8D87EC175577E782AD51A6A12C02"
+ }, {
+ "NIST P-384", 1,
+ "56EBF5310EEF5A5D8D001F570A18625383ECD4882B3FC738A69874E7C9D8F89C"
+ "187BECA23369DFD6C15CC0DA0629958F",
+ "C1230B349FB662CB762563DB8F9FCB32D5CCA16120681C474D67D279CCA6F6DB"
+ "73DE6AA96140B5C457B7486E06D318CE"
+ }, {
+ "NIST P-521", 0,
+ "01E4D82EE5CD6DA37080252295EFA273BBBA6952012D0120EAF131E73F1E5024"
+ "36E3324624471040030E1C345D65490ECEE9B64E03B15B6C7EB69A39C618BAFEED70",
+ "03EE3A3C88A6933B7B16016BE4CC4E3BF5EA0625CB3DB2604CDCBBD02CABBC90"
+ "8904D9DB42998F6C5101D4D4318ACFC9643C9CD641F636D1810ED86F1840EA74F3C0"
+ }, {
+ "NIST P-521", 0,
+ "01F3DFCB5433387B6B2E3F74177F4F3D7300F05E1AD49DE112630E27B1C8A437"
+ "1E742CB020E0039B5477FC897D17332034F9660B3066764EFF5FB440EB8856E782E3",
+ "02D337616C9D202DC5E290C486F5855CBD6A8470AE62CA96245834CF49257D8D"
+ "96D4041B15007650DEE668C00DDBF749054256C571F60980AC74D0DBCA7FB96C2F48"
+ }, {
+ "NIST P-521", 1,
+ "822A846606DC9E96452CAC373567A8B57D9ACA15B177F75DD7EF10C635F52CE4"
+ "EF6ABEEDB90D3F48F50A0C9015A95C955A25C45DE8413DE3BF899B6B1E62CF7CB8",
+ "0102771B5F3EC8C36838CEC04DCBC28AD1E38C37DAB0EA89B5EE92D21F7A35CE"
+ "ABC8B155EDC70154D6DFA2E77EC1D8C4A3406A6BD0ECF8F1EE2AC33A02464CB70C97"
+ }, {
+ "NIST P-521", 0,
+ "F733D48467912D1FFE46CF442F27FDD218D190E7B8A829D822DA3B6BAF9B987E"
+ "5B4BCCE34499248F59EEAF74F63ED15FF73F243C6FC3FD5E5842F6A3BA34C2022D",
+ "0281AAAD1B7EEBABEB6EC67932CB7E95717AFA3B4CF7A2DB151CD537C419C3A5"
+ "156ED9160758190B47696CDC15E81BBAD12975283907A571604DB23F702AEA4B38FF"
+ }, {
+ "NIST P-521", 0,
+ "03B1B274175AAEB5907152E5114CCAEADA28A7ADD4A2B1831C3D8302E8596489"
+ "E2C98B9B8D0CAE98C03BB11E28CE66D4736449758AF58BAFE40EF5A5FA22C9A43117",
+ "94C5951F81D544E959EDFC5DC1D5F42FE427871D4FB91A43A0B4A6BEA6B35B9E"
+ "BC5FB444C70BE4FD47B4ED16704F8C86EF019FC47C7FF2271F8B0DDEA9E2D3BCDD"
+ }, {
+ "NIST P-521", 1,
+ "F2248C318055DE37CD706D4FCAF7E7D96737A4A7B6B8067A66DCD58B6B8DFC55"
+ "90ECE67F6AA67F9C51B57E7B023075F2F42909BF47361CB6881C10F55FB7215B56",
+ "0162F735CE6A2ADA54CAF96A12D6888C02DE0A74638CF34CE39DABBACA4D651B"
+ "7E6ED1A65B551B36BAE7BE474BB6E6905ED0E33C7BA2021885027C7C6E40C5613004"
+ }, {
+ "NIST P-521", 0,
+ "9F08E97FEADCF0A391CA1EA4D97B5FE62D3B164593E12027EB967BD6E1FA841A"
+ "9831158DF164BCAD0BF3ADA96127745E25F349BDDD52EEA1654892B35960C9C023",
+ "AE2A25F5440F258AFACA6925C4C9F7AEAD3CB67153C4FACB31AC33F58B43A78C"
+ "B14F682FF726CEE2A6B6F6B481AEEB29A9B3150F02D1CFB764672BA8294C477291"
+ }, {
+ "NIST P-521", 0,
+ "01047B52014748C904980716953206A93F0D01B34CA94A997407FA93FE304F86"
+ "17BB6E402B2BB8B434C2671ECE953ABE7BADB75713CD9DF950943A33A9A19ACCDABE",
+ "7433533F098037DEA616337986887D01C5CC8DEC3DC1FDB9CDF7287EF27CC125"
+ "54FCF3A5E212DF9DAD9F8A3A7173B23FC6E15930704F3AEE1B074BDDB0ED6823E4"
+ }, {
+ "NIST P-521", 0,
+ "01C2A9EBF51592FE6589F618EAADA1697D9B2EC7CE5D48C9E80FC597642B23F1"
+ "F0EBE953449762BD3F094F57791D9850AFE98BBDA9872BE399B7BDD617860076BB03",
+ "0B822E27692F63DB8E12C59BB3CCA172B9BBF613CAE5F9D1474186E45E8B26FF"
+ "962084E1C6BE74821EDBB60941A3B75516F603719563433383812BFEA89EC14B89"
+ }, {
+ "NIST P-521", 0,
+ "99390F342C3F0D46E80C5B65C61E8AA8ACA0B6D4E1352404586364A05D8398E9"
+ "2BC71A644E8663F0A9B87D0B3ACAEE32F2AB9B321317AD23059D045EBAB91C5D93",
+ "82FCF93AE4467EB57766F2B150E736636727E7282500CD482DA70D153D195F2B"
+ "DF9B96D689A0DC1BB9137B41557A33F202F1B71840544CBEFF03072E77E4BB6F0B"
+ }, {
+ "NIST P-521", 1,
+ "018E48E80594FF5496D8CC7DF8A19D6AA18805A4EF4490038AED6A1E9AA18056"
+ "D0244A97DCF6D132C6804E3F4F369922119544B4C057D783C848FB798B48730A382C",
+ "01AF510B4F5E1C40BC9C110216D35E7C6D7A2BEE52914FC98258676288449901"
+ "F27A07EE91DF2D5D79259712906C3E18A990CBF35BCAC41A952820CE2BA8D0220080"
+ }, {
+ "NIST P-521", 1,
+ "ADCEF3539B4BC831DC0AFD173137A4426152058AFBAE06A17FCB89F4DB6E48B5"
+ "335CB88F8E4DB475A1E390E5656072F06605BFB84CBF9795B7992ECA04A8E10CA1",
+ "01BCB985AFD6404B9EDA49B6190AAA346BF7D5909CA440C0F7E505C62FAC8635"
+ "31D3EB7B2AC4DD4F4404E4B12E9D6D3C596179587F3724B1EFFF684CFDB4B21826B9"
+ }
+ };
+ gpg_error_t err;
+ int tidx;
+ const char *lastcurve = NULL;
+ gcry_ctx_t ctx = NULL;
+ gcry_mpi_t qx = NULL;
+ gcry_mpi_t qy = NULL;
+ gcry_mpi_point_t Q;
+ int oncurve;
+
+ wherestr = "point_on_curve";
+ for (tidx=0; tidx < DIM (t); tidx++)
+ {
+ if (!t[tidx].curve)
+ {
+ if (!lastcurve || !ctx)
+ die ("invalid test vectors at idx %d\n", tidx);
+ }
+ else if (!ctx || !lastcurve || strcmp (t[tidx].curve, lastcurve))
+ {
+ lastcurve = t[tidx].curve;
+ gcry_ctx_release (ctx);
+ err = gcry_mpi_ec_new (&ctx, NULL, lastcurve);
+ if (err)
+ die ("error creating context for curve %s at idx %d: %s\n",
+ lastcurve, tidx, gpg_strerror (err));
+
+ info ("checking points on curve %s\n", lastcurve);
+ }
+
+ gcry_mpi_release (qx);
+ gcry_mpi_release (qy);
+ qx = hex2mpi (t[tidx].qx);
+ qy = hex2mpi (t[tidx].qy);
+
+ Q = gcry_mpi_point_set (NULL, qx, qy, GCRYMPI_CONST_ONE);
+ if (!Q)
+ die ("gcry_mpi_point_set(Q) failed at idx %d\n", tidx);
+
+ oncurve = gcry_mpi_ec_curve_point (Q, ctx);
+
+ if (t[tidx].oncurve && !oncurve)
+ {
+ fail ("point expected on curve but not identified as such (i=%d):\n",
+ tidx);
+ print_point (" Q", Q);
+ }
+ else if (!t[tidx].oncurve && oncurve)
+ {
+ fail ("point not expected on curve but identified as such (i=%d):\n",
+ tidx);
+ print_point (" Q", Q);
+ }
+ gcry_mpi_point_release (Q);
+ }
+
+ gcry_mpi_release (qx);
+ gcry_mpi_release (qy);
+ gcry_ctx_release (ctx);
+}
+
+
+int
+main (int argc, char **argv)
+{
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ set_get_point ();
+ context_alloc ();
+ context_param ();
+ basic_ec_math ();
+ point_on_curve ();
+
+ /* The tests are for P-192 and ed25519 which are not supported in
+ FIPS mode. */
+ if (!gcry_fips_mode_active())
+ {
+ basic_ec_math_simplified ();
+ twistededwards_math ();
+ }
+
+ info ("All tests completed. Errors: %d\n", error_count);
+ return error_count ? 1 : 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-secmem.c b/comm/third_party/libgcrypt/tests/t-secmem.c
new file mode 100644
index 0000000000..2b76913422
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-secmem.c
@@ -0,0 +1,209 @@
+/* t-secmem.c - Test the secmem memory allocator
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#define PGM "t-secmem"
+
+#include "t-common.h"
+#include "../src/gcrypt-testapi.h"
+
+
+#define DEFAULT_PAGE_SIZE 4096
+#define MINIMUM_POOL_SIZE 16384
+static size_t pool_size;
+static size_t chunk_size;
+
+static void
+test_secmem (void)
+{
+ void *a[28];
+ void *b;
+ int i;
+
+ memset (a, 0, sizeof a);
+
+ /* Allocating 28*512=14k should work in the default 16k pool even
+ * with extra alignment requirements. */
+ for (i=0; i < DIM(a); i++)
+ a[i] = gcry_xmalloc_secure (chunk_size);
+
+ /* Allocating another 2k should fail for the default 16k pool. */
+ b = gcry_malloc_secure (chunk_size*4);
+ if (b)
+ fail ("allocation did not fail as expected\n");
+
+ for (i=0; i < DIM(a); i++)
+ xfree (a[i]);
+ xfree (b);
+}
+
+
+static void
+test_secmem_overflow (void)
+{
+ void *a[150];
+ int i;
+
+ memset (a, 0, sizeof a);
+
+ /* Allocating 150*512=75k should require more than one overflow buffer. */
+ for (i=0; i < DIM(a); i++)
+ {
+ a[i] = gcry_xmalloc_secure (chunk_size);
+ if (verbose && !(i %40))
+ xgcry_control ((GCRYCTL_DUMP_SECMEM_STATS, 0 , 0));
+ }
+
+ if (debug)
+ xgcry_control ((PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0));
+ if (verbose)
+ xgcry_control ((GCRYCTL_DUMP_SECMEM_STATS, 0 , 0));
+ for (i=0; i < DIM(a); i++)
+ xfree (a[i]);
+}
+
+
+/* This function is called when we ran out of core and there is no way
+ * to return that error to the caller (xmalloc or mpi allocation). */
+static int
+outofcore_handler (void *opaque, size_t req_n, unsigned int flags)
+{
+ static int been_here; /* Used to protect against recursive calls. */
+
+ (void)opaque;
+
+ /* Protect against a second call. */
+ if (been_here)
+ return 0; /* Let libgcrypt call its own fatal error handler. */
+ been_here = 1;
+
+ info ("outofcore handler invoked");
+ xgcry_control ((PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0));
+ fail ("out of core%s while allocating %lu bytes",
+ (flags & 1)?" in secure memory":"", (unsigned long)req_n);
+
+ die ("stopped");
+ /*NOTREACHED*/
+ return 0;
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ long int pgsize_val = -1;
+ size_t pgsize;
+
+ if (getenv ("GCRYPT_IN_ASAN_TEST"))
+ {
+ /* 'mlock' is not available when build with address sanitizer,
+ * so skip test. */
+ fputs ("Note: " PGM " skipped because running with ASAN.\n", stdout);
+ return 0;
+ }
+
+#if HAVE_MMAP
+# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pgsize_val = sysconf (_SC_PAGESIZE);
+# elif defined(HAVE_GETPAGESIZE)
+ pgsize_val = getpagesize ();
+# endif
+#endif
+ pgsize = (pgsize_val > 0)? pgsize_val : DEFAULT_PAGE_SIZE;
+
+ pool_size = (MINIMUM_POOL_SIZE + pgsize - 1) & ~(pgsize - 1);
+ chunk_size = pool_size / 32;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: " PGM " [options]\n"
+ "Options:\n"
+ " --verbose print timings etc.\n"
+ " --debug flyswatter\n"
+ , stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ }
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch; pgm=%s, library=%s\n",
+ GCRYPT_VERSION, gcry_check_version (NULL));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0));
+ gcry_set_outofcore_handler (outofcore_handler, NULL);
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ /* Libgcrypt prints a warning when the first overflow is allocated;
+ * we do not want to see that. */
+ if (!verbose)
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM_WARN, 0));
+
+
+ test_secmem ();
+ test_secmem_overflow ();
+ /* FIXME: We need to improve the tests, for example by registering
+ * our own log handler and comparing the output of
+ * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */
+
+ if (verbose)
+ {
+ xgcry_control ((PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0));
+ xgcry_control ((GCRYCTL_DUMP_SECMEM_STATS, 0 , 0));
+ }
+
+ info ("All tests completed. Errors: %d\n", error_count);
+ xgcry_control ((GCRYCTL_TERM_SECMEM, 0 , 0));
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-sexp.c b/comm/third_party/libgcrypt/tests/t-sexp.c
new file mode 100644
index 0000000000..96d5f97ec4
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-sexp.c
@@ -0,0 +1,1344 @@
+/* t-sexp.c - S-expression regression tests
+ * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2014 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+#include "../src/gcrypt-int.h"
+
+#define PGM "t-sexp"
+#include "t-common.h"
+
+
+/* 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 returns NULL 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))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static gcry_mpi_t
+hex2mpi (const char *string)
+{
+ gpg_error_t err;
+ gcry_mpi_t val;
+
+ err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (err)
+ die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err));
+ return val;
+}
+
+static gcry_mpi_t
+hex2mpiopa (const char *string)
+{
+ char *buffer;
+ size_t buflen;
+ gcry_mpi_t val;
+
+ buffer = hex2buffer (string, &buflen);
+ if (!buffer)
+ die ("hex2mpiopa '%s' failed: parser error\n", string);
+ val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
+ if (!buffer)
+ die ("hex2mpiopa '%s' failed: set_opaque error\n", string);
+ return val;
+}
+
+
+/* Compare A to B, where B is given as a hex string. */
+static int
+cmp_mpihex (gcry_mpi_t a, const char *b)
+{
+ gcry_mpi_t bval;
+ int res;
+
+ if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+ bval = hex2mpiopa (b);
+ else
+ bval = hex2mpi (b);
+ res = gcry_mpi_cmp (a, bval);
+ gcry_mpi_release (bval);
+ return res;
+}
+
+/* Compare A to B, where A is a buffer and B a hex string. */
+static int
+cmp_bufhex (const void *a, size_t alen, const char *b)
+{
+ void *bbuf;
+ size_t blen;
+ int res;
+
+ if (!a && !b)
+ return 0;
+ if (a && !b)
+ return 1;
+ if (!a && b)
+ return -1;
+
+ bbuf = hex2buffer (b, &blen);
+ if (!bbuf)
+ die ("cmp_bufhex: error converting hex string\n");
+ if (alen != blen)
+ return alen < blen? -1 : 1;
+ res = memcmp (a, bbuf, alen);
+ xfree (bbuf);
+ return res;
+}
+
+
+
+/* fixme: we need better tests */
+static void
+basic (void)
+{
+ int pass;
+ gcry_sexp_t sexp;
+ int idx;
+ char *secure_buffer;
+ size_t secure_buffer_len;
+ const char *string;
+ static struct {
+ const char *token;
+ const char *parm;
+ } values[] = {
+ { "public-key", NULL },
+ { "dsa", NULL },
+ { "dsa", "p" },
+ { "dsa", "y" },
+ { "dsa", "q" },
+ { "dsa", "g" },
+ { NULL }
+ };
+
+ info ("doing some pretty pointless tests\n");
+
+ secure_buffer_len = 99;
+ secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
+ memset (secure_buffer, 'G', secure_buffer_len);
+
+ for (pass=0;;pass++)
+ {
+ gcry_mpi_t m;
+
+ switch (pass)
+ {
+ case 0:
+ string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
+ "(q #61626364656667#) (g %m)))");
+
+ m = gcry_mpi_set_ui (NULL, 42);
+ if ( gcry_sexp_build (&sexp, NULL, string, m ) )
+ {
+ gcry_mpi_release (m);
+ fail (" scanning `%s' failed\n", string);
+ return;
+ }
+ gcry_mpi_release (m);
+ break;
+
+ case 1:
+ string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
+ "(q %b) (g %m)))");
+
+ m = gcry_mpi_set_ui (NULL, 42);
+ if ( gcry_sexp_build (&sexp, NULL, string,
+ 15, "foo\0\x01\0x02789012345", m) )
+ {
+ gcry_mpi_release (m);
+ fail (" scanning `%s' failed\n", string);
+ return;
+ }
+ gcry_mpi_release (m);
+ break;
+
+ case 2:
+ string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
+ "(q %b) (g %m)))");
+
+ m = gcry_mpi_set_ui (NULL, 17);
+ if ( gcry_sexp_build (&sexp, NULL, string,
+ secure_buffer_len, secure_buffer, m) )
+ {
+ gcry_mpi_release (m);
+ fail (" scanning `%s' failed\n", string);
+ return;
+ }
+ gcry_mpi_release (m);
+ if (!gcry_is_secure (sexp))
+ fail ("gcry_sexp_build did not switch to secure memory\n");
+ break;
+
+ case 3:
+ {
+ gcry_sexp_t help_sexp;
+
+ if (gcry_sexp_new (&help_sexp,
+ "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
+ {
+ fail (" scanning fixed string failed\n");
+ return;
+ }
+
+ string = ("(public-key (dsa (p #41424344#) (parm %S) "
+ "(y dummy)(q %b) (g %m)))");
+ m = gcry_mpi_set_ui (NULL, 17);
+ if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
+ secure_buffer_len, secure_buffer, m) )
+ {
+ gcry_mpi_release (m);
+ fail (" scanning `%s' failed\n", string);
+ return;
+ }
+ gcry_mpi_release (m);
+ gcry_sexp_release (help_sexp);
+ }
+ break;
+
+
+ default:
+ return; /* Ready. */
+ }
+
+
+ /* now find something */
+ for (idx=0; values[idx].token; idx++)
+ {
+ const char *token = values[idx].token;
+ const char *parm = values[idx].parm;
+ gcry_sexp_t s1, s2;
+ gcry_mpi_t a;
+ const char *p;
+ size_t n;
+
+ s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
+ if (!s1)
+ {
+ fail ("didn't found `%s'\n", token);
+ continue;
+ }
+
+ p = gcry_sexp_nth_data (s1, 0, &n);
+ if (!p)
+ {
+ gcry_sexp_release (s1);
+ fail ("no car for `%s'\n", token);
+ continue;
+ }
+ /* info ("car=`%.*s'\n", (int)n, p); */
+
+ s2 = gcry_sexp_cdr (s1);
+ if (!s2)
+ {
+ gcry_sexp_release (s1);
+ fail ("no cdr for `%s'\n", token);
+ continue;
+ }
+
+ p = gcry_sexp_nth_data (s2, 0, &n);
+ gcry_sexp_release (s2);
+ if (p)
+ {
+ gcry_sexp_release (s1);
+ fail ("data at car of `%s'\n", token);
+ continue;
+ }
+
+ if (parm)
+ {
+ s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
+ gcry_sexp_release (s1);
+ if (!s2)
+ {
+ fail ("didn't found `%s'\n", parm);
+ continue;
+ }
+ p = gcry_sexp_nth_data (s2, 0, &n);
+ if (!p)
+ {
+ gcry_sexp_release (s2);
+ fail("no car for `%s'\n", parm );
+ continue;
+ }
+ /* info ("car=`%.*s'\n", (int)n, p); */
+ p = gcry_sexp_nth_data (s2, 1, &n);
+ if (!p)
+ {
+ gcry_sexp_release (s2);
+ fail("no cdr for `%s'\n", parm );
+ continue;
+ }
+ /* info ("cdr=`%.*s'\n", (int)n, p); */
+
+ a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
+ gcry_sexp_release (s2);
+ if (!a)
+ {
+ fail("failed to cdr the mpi for `%s'\n", parm);
+ continue;
+ }
+ gcry_mpi_release (a);
+ }
+ else
+ gcry_sexp_release (s1);
+ }
+
+ gcry_sexp_release (sexp);
+ sexp = NULL;
+ }
+ gcry_free (secure_buffer);
+}
+
+
+static void
+canon_len (void)
+{
+ static struct {
+ size_t textlen; /* length of the buffer */
+ size_t expected;/* expected length or 0 on error and then ... */
+ size_t erroff; /* ... and at this offset */
+ gcry_error_t errcode; /* ... with this error code */
+ const char *text;
+ } values[] = {
+ { 14, 13, 0, GPG_ERR_NO_ERROR, "(9:abcdefghi) " },
+ { 16, 15, 0, GPG_ERR_NO_ERROR, "(10:abcdefghix)" },
+ { 14, 0,14, GPG_ERR_SEXP_STRING_TOO_LONG, "(10:abcdefghi)" },
+ { 15, 0, 1, GPG_ERR_SEXP_ZERO_PREFIX, "(010:abcdefghi)" },
+ { 2, 0, 0, GPG_ERR_SEXP_NOT_CANONICAL, "1:"},
+ { 4, 0, 4, GPG_ERR_SEXP_STRING_TOO_LONG, "(1:)"},
+ { 5, 5, 0, GPG_ERR_NO_ERROR, "(1:x)"},
+ { 2, 2, 0, GPG_ERR_NO_ERROR, "()"},
+ { 4, 2, 0, GPG_ERR_NO_ERROR, "()()"},
+ { 4, 4, 0, GPG_ERR_NO_ERROR, "(())"},
+ { 3, 0, 3, GPG_ERR_SEXP_STRING_TOO_LONG, "(()"},
+ { 3, 0, 1, GPG_ERR_SEXP_BAD_CHARACTER, "( )"},
+ { 9, 9, 0, GPG_ERR_NO_ERROR, "(3:abc())"},
+ { 10, 0, 6, GPG_ERR_SEXP_BAD_CHARACTER, "(3:abc ())"},
+ /* fixme: we need much more cases */
+ { 0 },
+ };
+ int idx;
+ gcry_error_t errcode;
+ size_t n, erroff;
+
+ info ("checking canoncial length test function\n");
+ for (idx=0; values[idx].text; idx++)
+ {
+ n = gcry_sexp_canon_len ((const unsigned char*)values[idx].text,
+ values[idx].textlen,
+ &erroff, &errcode);
+
+ if (n && n == values[idx].expected)
+ ; /* success */
+ else if (!n && !values[idx].expected)
+ { /* we expected an error - check that this is the right one */
+ if (values[idx].erroff != erroff)
+ fail ("canonical length test %d - wrong error offset %u\n",
+ idx, (unsigned int)erroff);
+ if (gcry_err_code (errcode) != values[idx].errcode)
+ fail ("canonical length test %d - wrong error code %d\n",
+ idx, errcode);
+ }
+ else
+ fail ("canonical length test %d failed - n=%u, off=%u, err=%d\n",
+ idx, (unsigned int)n, (unsigned int)erroff, errcode);
+ }
+}
+
+
+/* Compare SE to the canonical formatted expression in
+ * (CANON,CANONLEN). This is done by a converting SE to canonical
+ * format and doing a byte compare. Returns 0 if they match. */
+static int
+compare_to_canon (gcry_sexp_t se, const unsigned char *canon, size_t canonlen)
+{
+ size_t n, n1;
+ char *p1;
+
+ n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
+ if (!n1)
+ {
+ fail ("get required length in compare_to_canon failed\n");
+ return -1;
+ }
+ p1 = gcry_xmalloc (n1);
+ n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
+ if (n1 != n+1)
+ {
+ fail ("length mismatch in compare_to_canon detected\n");
+ xfree (p1);
+ return -1;
+ }
+ if (n1 != canonlen || memcmp (p1, canon, canonlen))
+ {
+ xfree (p1);
+ return -1;
+ }
+ xfree (p1);
+ return 0;
+}
+
+
+static void
+back_and_forth_one (int testno, const char *buffer, size_t length)
+{
+ gcry_error_t rc;
+ gcry_sexp_t se, se1;
+ unsigned char *canon;
+ size_t canonlen; /* Including the hidden nul suffix. */
+ size_t n, n1;
+ char *p1;
+
+ rc = gcry_sexp_new (&se, buffer, length, 1);
+ if (rc)
+ {
+ fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc));
+ return;
+ }
+ n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
+ if (!n1)
+ {
+ fail ("baf %d: get required length for canon failed\n", testno);
+ return;
+ }
+ p1 = gcry_xmalloc (n1);
+ n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
+ if (n1 != n+1) /* sprints adds an extra 0 but does not return it. */
+ {
+ fail ("baf %d: length mismatch for canon\n", testno);
+ return;
+ }
+ canonlen = n1;
+ canon = gcry_malloc (canonlen);
+ memcpy (canon, p1, canonlen);
+ rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
+ if (rc)
+ {
+ fail ("baf %d: gcry_sexp_create failed: %s\n",
+ testno, gpg_strerror (rc));
+ return;
+ }
+ gcry_sexp_release (se1);
+
+ /* Again but with memory checking. */
+ p1 = gcry_xmalloc (n1+2);
+ *p1 = '\x55';
+ p1[n1+1] = '\xaa';
+ n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1);
+ if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
+ {
+ fail ("baf %d: length mismatch for canon\n", testno);
+ return;
+ }
+ if (*p1 != '\x55' || p1[n1+1] != '\xaa')
+ fail ("baf %d: memory corrupted (1)\n", testno);
+ rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL);
+ if (rc)
+ {
+ fail ("baf %d: gcry_sexp_create failed: %s\n",
+ testno, gpg_strerror (rc));
+ return;
+ }
+ if (*p1 != '\x55' || p1[n1+1] != '\xaa')
+ fail ("baf %d: memory corrupted (2)\n", testno);
+ gcry_sexp_release (se1);
+ if (*p1 != '\x55' || p1[n1+1] != '\xaa')
+ fail ("baf %d: memory corrupted (3)\n", testno);
+ gcry_free (p1);
+
+ /* Check converting to advanced format. */
+ n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ if (!n1)
+ {
+ fail ("baf %d: get required length for advanced failed\n", testno);
+ return;
+ }
+ p1 = gcry_xmalloc (n1);
+ n = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, p1, n1);
+ if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
+ {
+ fail ("baf %d: length mismatch for advanced\n", testno);
+ return;
+ }
+ rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
+ if (rc)
+ {
+ fail ("baf %d: gcry_sexp_create failed: %s\n",
+ testno, gpg_strerror (rc));
+ return;
+ }
+ if (compare_to_canon (se1, canon, canonlen))
+ {
+ fail ("baf %d: converting to advanced failed: %s\n",
+ testno, gpg_strerror (rc));
+ return;
+ }
+ gcry_sexp_release (se1);
+
+
+ /* FIXME: we need a lot more tests */
+
+ gcry_sexp_release (se);
+ xfree (canon);
+}
+
+
+
+static void
+back_and_forth (void)
+{
+ static struct { const char *buf; int len; } tests[] = {
+ { "(7:g34:fgh1::2:())", 0 },
+ { "(7:g34:fgh1::2:())", 18 },
+ {
+"(protected-private-key \n"
+" (rsa \n"
+" (n #00BE8A536204687149A48FF9F1715FF3530AD9A836D62102BF4065E5CF5953236DB94F1DF2FF4D525CD4CE7966DDC3C839968E8BAC2948934DF047CC65287CD79F6C23C93E55D7F9231E3942BD496DE383469977635A51ADF4AF747DB958CA02E9940DFC1DC0FC7FC755E7EB6618FEE6DA54B8A06E0CBF9D9257443F9992261435#)\n"
+" (e #010001#)\n"
+" (protected openpgp-s2k3-sha1-aes-cbc \n"
+" (\n"
+" (sha1 #C2A5673BD3882405# \"96\")\n"
+" #8D08AAF6A9209ED69D71EB7E64D78715#)\n"
+" #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n"
+" )\n"
+" )\n", 0 },
+ { "((sha1 #8B98CBF4A9823CA7# \"2097\") #3B6FC9#)", 0 },
+ { "((4:sha18:\x8B\x98\xCB\xF4\xA9\x82\x3C\xA7""4:2097)3:\x3B\x6F\xC9)", 0},
+ { "((4:sha18:\x8B\x98\xCB\x22\xA9\x82\x3C\xA7""4:2097)3:\x3B\x6F\xC9)", 0},
+ { "((sha1 #64652267686970C9# \"2097\") #3B6FC9#)", 0 },
+ { "((4:sha18:\x64\x65\x22\x67\x68\xc3\xa4\x71""4:2097)3:\x3B\x6F\xC9)", 0},
+ { "((sha1 \"defghäq\" \"2097\") #3B6FC9#)", 0 },
+ { "((sha1 \"de\\\"ghäq\" \"2097\") #3B6FC9#)", 0 },
+ { NULL, 0 }
+ };
+ int idx;
+
+ for (idx=0; tests[idx].buf; idx++)
+ back_and_forth_one (idx, tests[idx].buf, tests[idx].len);
+}
+
+
+static void
+check_sscan (void)
+{
+ static struct {
+ const char *text;
+ gcry_error_t expected_err;
+ } values[] = {
+ /* Bug reported by Olivier L'Heureux 2003-10-07 */
+ { "(7:sig-val(3:dsa"
+ "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
+ "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
+ "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
+ "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e)))",
+ GPG_ERR_NO_ERROR },
+ { "(7:sig-val(3:dsa"
+ "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
+ "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
+ "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
+ "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))",
+ GPG_ERR_SEXP_UNMATCHED_PAREN },
+ { "(7:sig-val(3:dsa"
+ "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
+ "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
+ "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
+ "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))))",
+ GPG_ERR_SEXP_UNMATCHED_PAREN },
+ { NULL, 0 }
+ };
+ int idx;
+ gcry_error_t err;
+ gcry_sexp_t s;
+
+ info ("checking gcry_sexp_sscan\n");
+ for (idx=0; values[idx].text; idx++)
+ {
+ err = gcry_sexp_sscan (&s, NULL,
+ values[idx].text,
+ strlen (values[idx].text));
+ if (gpg_err_code (err) != values[idx].expected_err)
+ fail ("gcry_sexp_sscan test %d failed: %s\n", idx, gpg_strerror (err));
+ gcry_sexp_release (s);
+ }
+}
+
+
+static void
+check_extract_param (void)
+{
+ /* This sample data is a real key but with some parameters of the
+ public key modified. u,i,I are used for direct extraction tests. */
+ static char sample1[] =
+ "(key-data"
+ " (public-key"
+ " (ecc"
+ " (curve Ed25519)"
+ " (p #6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
+ " (a #EF#)"
+ " (b #C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
+ " (g #14"
+ " 216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+ " 6666666666666666666666666666666666666666666666666666666666666658#)"
+ " (n #0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
+ " (q #20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
+ "))"
+ " (private-key"
+ " (u +65537)"
+ " (i +65537)"
+ " (I -65535)"
+ " (i0 1:0)"
+ " (flaglist foo bar (sublist x) test 2:42)"
+ " (noflags)"
+ " (ecc"
+ " (curve Ed25519)"
+ " (p #7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
+ " (a #FF#)"
+ " (b #D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
+ " (g #04"
+ " 216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+ " 6666666666666666666666666666666666666666666666666666666666666658#)"
+ " (n #1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
+ " (q #30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
+ " (d #56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276#)"
+ " (comment |QWxsIHlvdXIgYmFzZTY0IGFyZSBiZWxvbmcgdG8gdXM=|)"
+ ")))";
+
+ static char sample1_p[] =
+ "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
+ static char sample1_px[] =
+ "6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
+ static char sample1_a[] = "FF";
+ static char sample1_ax[] = "EF";
+ static char sample1_b[] =
+ "D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
+ static char sample1_bx[] =
+ "C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
+ static char sample1_g[] =
+ "04"
+ "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+ "6666666666666666666666666666666666666666666666666666666666666658";
+ static char sample1_gx[] =
+ "14"
+ "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+ "6666666666666666666666666666666666666666666666666666666666666658";
+ static char sample1_n[] =
+ "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
+ static char sample1_nx[] =
+ "0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
+ static char sample1_q[] =
+ "30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
+ static char sample1_qx[] =
+ "20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
+ static char sample1_d[] =
+ "56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276";
+ static char sample1_comment[] = "All your base64 are belong to us";
+
+ static struct {
+ const char *sexp_str;
+ const char *path;
+ const char *list;
+ int nparam;
+ gpg_err_code_t expected_err;
+ const char *exp_p;
+ const char *exp_a;
+ const char *exp_b;
+ const char *exp_g;
+ const char *exp_n;
+ const char *exp_q;
+ const char *exp_d;
+ } tests[] = {
+ {
+ sample1,
+ NULL,
+ "pabgnqd", 6,
+ GPG_ERR_MISSING_VALUE,
+ },
+ {
+ sample1,
+ NULL,
+ "pabgnq", 7,
+ GPG_ERR_INV_ARG
+ },
+ {
+ sample1,
+ NULL,
+ "pab'gnq", 7,
+ GPG_ERR_SYNTAX
+ },
+ {
+ sample1,
+ NULL,
+ "pab''gnq", 7,
+ GPG_ERR_SYNTAX
+ },
+ {
+ sample1,
+ NULL,
+ "pabgnqd", 7,
+ 0,
+ sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+ sample1_qx, sample1_d
+ },
+ {
+ sample1,
+ NULL,
+ " pab\tg nq\nd ", 7,
+ 0,
+ sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+ sample1_qx, sample1_d
+ },
+ {
+ sample1,
+ NULL,
+ "abg", 3,
+ 0,
+ sample1_ax, sample1_bx, sample1_gx
+ },
+ {
+ sample1,
+ NULL,
+ "ab'g'", 3,
+ 0,
+ sample1_ax, sample1_bx, sample1_gx
+ },
+ {
+ sample1,
+ NULL,
+ "x?abg", 4,
+ 0,
+ NULL, sample1_ax, sample1_bx, sample1_gx
+ },
+ {
+ sample1,
+ NULL,
+ "p?abg", 4,
+ GPG_ERR_USER_1,
+ NULL, sample1_ax, sample1_bx, sample1_gx
+ },
+ {
+ sample1,
+ NULL,
+ "pax?gnqd", 7,
+ 0,
+ sample1_px, sample1_ax, NULL, sample1_gx, sample1_nx,
+ sample1_qx, sample1_d
+ },
+ {
+ sample1,
+ "public-key",
+ "pabgnqd", 7,
+ GPG_ERR_NO_OBJ, /* d is not in public key. */
+ sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+ sample1_qx, sample1_d
+ },
+ {
+ sample1,
+ "private-key",
+ "pabgnqd", 7,
+ 0,
+ sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
+ sample1_q, sample1_d
+ },
+ {
+ sample1,
+ "public-key!ecc",
+ "pabgnq", 6,
+ 0,
+ sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+ sample1_qx
+ },
+ {
+ sample1,
+ "public-key!ecc!foo",
+ "pabgnq", 6,
+ GPG_ERR_NOT_FOUND
+ },
+ {
+ sample1,
+ "public-key!!ecc",
+ "pabgnq", 6,
+ GPG_ERR_NOT_FOUND
+ },
+ {
+ sample1,
+ "private-key",
+ "pa/bgnqd", 7,
+ 0,
+ sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
+ sample1_q, sample1_d
+ },
+ {
+ sample1,
+ "private-key",
+ "p-a+bgnqd", 7,
+ 0,
+ sample1_p, "-01", sample1_b, sample1_g, sample1_n,
+ sample1_q, sample1_d
+ },
+ {NULL}
+ };
+ int idx, i;
+ const char *paramstr;
+ int paramidx;
+ gpg_error_t err;
+ gcry_sexp_t sxp, sxp1;
+ gcry_mpi_t mpis[7];
+ gcry_buffer_t ioarray[7];
+ char iobuffer[200];
+ char *string1, *string2;
+ int aint0, aint1, aint2;
+ unsigned int auint;
+ long along1, along2;
+ unsigned long aulong;
+ size_t asize;
+
+ info ("checking gcry_sexp_extract_param\n");
+ for (idx=0; tests[idx].sexp_str; idx++)
+ {
+ err = gcry_sexp_new (&sxp, tests[idx].sexp_str, 0, 1);
+ if (err)
+ die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+ memset (mpis, 0, sizeof mpis);
+ switch (tests[idx].nparam)
+ {
+ case 0:
+ err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+ NULL);
+ break;
+ case 1:
+ err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+ mpis+0, NULL);
+ break;
+ case 2:
+ err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+ mpis+0, mpis+1, NULL);
+ break;
+ case 3:
+ err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+ mpis+0, mpis+1, mpis+2, NULL);
+ break;
+ case 4:
+ err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+ mpis+0, mpis+1, mpis+2, mpis+3, NULL);
+ break;
+ case 5:
+ err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+ mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
+ NULL);
+ break;
+ case 6:
+ err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+ mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
+ mpis+5, NULL);
+ break;
+ case 7:
+ err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+ mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
+ mpis+5, mpis+6, NULL);
+ break;
+ default:
+ die ("test %d: internal error", idx);
+ }
+
+ if (tests[idx].expected_err
+ && tests[idx].expected_err != GPG_ERR_USER_1)
+ {
+ if (tests[idx].expected_err != gpg_err_code (err))
+ fail ("gcry_sexp_extract_param test %d failed: "
+ "expected error '%s' - got '%s'", idx,
+ gpg_strerror (tests[idx].expected_err),gpg_strerror (err));
+
+ }
+ else if (err)
+ {
+ fail ("gcry_sexp_extract_param test %d failed: %s",
+ idx, gpg_strerror (err));
+ }
+ else /* No error - check the extracted values. */
+ {
+ for (paramidx=0; paramidx < DIM (mpis); paramidx++)
+ {
+ switch (paramidx)
+ {
+ case 0: paramstr = tests[idx].exp_p; break;
+ case 1: paramstr = tests[idx].exp_a; break;
+ case 2: paramstr = tests[idx].exp_b; break;
+ case 3: paramstr = tests[idx].exp_g; break;
+ case 4: paramstr = tests[idx].exp_n; break;
+ case 5: paramstr = tests[idx].exp_q; break;
+ case 6: paramstr = tests[idx].exp_d; break;
+ default:
+ die ("test %d: internal error: bad param %d",
+ idx, paramidx);
+ }
+
+ if (tests[idx].expected_err == GPG_ERR_USER_1
+ && mpis[paramidx] && !paramstr && paramidx == 0)
+ ; /* Okay Special case error for param 0. */
+ else if (!mpis[paramidx] && !paramstr)
+ ; /* Okay. */
+ else if (!mpis[paramidx] && paramstr)
+ fail ("test %d: value for param %d expected but not returned",
+ idx, paramidx);
+ else if (mpis[paramidx] && !paramstr)
+ fail ("test %d: value for param %d not expected",
+ idx, paramidx);
+ else if (cmp_mpihex (mpis[paramidx], paramstr))
+ {
+ fail ("test %d: param %d mismatch", idx, paramidx);
+ gcry_log_debug ("expected: %s\n", paramstr);
+ gcry_log_debugmpi (" got", mpis[paramidx]);
+ }
+ else if (tests[idx].expected_err && paramidx == 0)
+ fail ("test %d: param %d: expected error '%s' - got 'Success'",
+ idx, paramidx, gpg_strerror (tests[idx].expected_err));
+ }
+
+ }
+
+ for (i=0; i < DIM (mpis); i++)
+ gcry_mpi_release (mpis[i]);
+ gcry_sexp_release (sxp);
+ }
+
+ info ("checking gcry_sexp_extract_param/desc\n");
+
+ memset (ioarray, 0, sizeof ioarray);
+
+ err = gcry_sexp_new (&sxp, sample1, 0, 1);
+ if (err)
+ die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+ ioarray[1].size = sizeof iobuffer;
+ ioarray[1].data = iobuffer;
+ ioarray[1].off = 0;
+ ioarray[2].size = sizeof iobuffer;
+ ioarray[2].data = iobuffer;
+ ioarray[2].off = 50;
+ assert (ioarray[2].off < sizeof iobuffer);
+ err = gcry_sexp_extract_param (sxp, "key-data!private-key", "&pab",
+ ioarray+0, ioarray+1, ioarray+2, NULL);
+ if (err)
+ fail ("gcry_sexp_extract_param with desc failed: %s", gpg_strerror (err));
+ else
+ {
+ if (!ioarray[0].data)
+ fail ("gcry_sexp_extract_param/desc failed: no P");
+ else if (ioarray[0].size != 32)
+ fail ("gcry_sexp_extract_param/desc failed: P has wrong size");
+ else if (ioarray[0].len != 32)
+ fail ("gcry_sexp_extract_param/desc failed: P has wrong length");
+ else if (ioarray[0].off)
+ fail ("gcry_sexp_extract_param/desc failed: P has OFF set");
+ else if (cmp_bufhex (ioarray[0].data, ioarray[0].len, sample1_p))
+ {
+ fail ("gcry_sexp_extract_param/desc failed: P mismatch");
+ gcry_log_debug ("expected: %s\n", sample1_p);
+ gcry_log_debughex (" got", ioarray[0].data, ioarray[0].len);
+ }
+
+ if (!ioarray[1].data)
+ fail ("gcry_sexp_extract_param/desc failed: A buffer lost");
+ else if (ioarray[1].size != sizeof iobuffer)
+ fail ("gcry_sexp_extract_param/desc failed: A size changed");
+ else if (ioarray[1].off != 0)
+ fail ("gcry_sexp_extract_param/desc failed: A off changed");
+ else if (ioarray[1].len != 1)
+ fail ("gcry_sexp_extract_param/desc failed: A has wrong length");
+ else if (cmp_bufhex ((char *)ioarray[1].data + ioarray[1].off,
+ ioarray[1].len, sample1_a))
+ {
+ fail ("gcry_sexp_extract_param/desc failed: A mismatch");
+ gcry_log_debug ("expected: %s\n", sample1_a);
+ gcry_log_debughex (" got",
+ (char *)ioarray[1].data + ioarray[1].off,
+ ioarray[1].len);
+ }
+
+ if (!ioarray[2].data)
+ fail ("gcry_sexp_extract_param/desc failed: B buffer lost");
+ else if (ioarray[2].size != sizeof iobuffer)
+ fail ("gcry_sexp_extract_param/desc failed: B size changed");
+ else if (ioarray[2].off != 50)
+ fail ("gcry_sexp_extract_param/desc failed: B off changed");
+ else if (ioarray[2].len != 32)
+ fail ("gcry_sexp_extract_param/desc failed: B has wrong length");
+ else if (cmp_bufhex ((char *)ioarray[2].data + ioarray[2].off,
+ ioarray[2].len, sample1_b))
+ {
+ fail ("gcry_sexp_extract_param/desc failed: B mismatch");
+ gcry_log_debug ("expected: %s\n", sample1_b);
+ gcry_log_debughex (" got",
+ (char *)ioarray[2].data + ioarray[2].off,
+ ioarray[2].len);
+ }
+
+ xfree (ioarray[0].data);
+ }
+
+ gcry_sexp_release (sxp);
+
+ info ("checking gcry_sexp_extract_param long name\n");
+
+ memset (ioarray, 0, sizeof ioarray);
+ memset (mpis, 0, sizeof mpis);
+
+ err = gcry_sexp_new (&sxp, sample1, 0, 1);
+ if (err)
+ die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+ err = gcry_sexp_extract_param (sxp, "key-data!private-key",
+ "&'curve'+p",
+ ioarray+0, mpis+0, NULL);
+ if (err)
+ fail ("gcry_sexp_extract_param long name failed: %s", gpg_strerror (err));
+
+ if (!ioarray[0].data)
+ fail ("gcry_sexp_extract_param long name failed: no curve");
+ else if (ioarray[0].size != 7)
+ fail ("gcry_sexp_extract_param long name failed: curve has wrong size");
+ else if (ioarray[0].len != 7)
+ fail ("gcry_sexp_extract_param long name failed: curve has wrong length");
+ else if (ioarray[0].off)
+ fail ("gcry_sexp_extract_param long name failed: curve has OFF set");
+ else if (strncmp (ioarray[0].data, "Ed25519", 7))
+ {
+ fail ("gcry_sexp_extract_param long name failed: curve mismatch");
+ gcry_log_debug ("expected: %s\n", "Ed25519");
+ gcry_log_debug (" got: %.*s\n",
+ (int)ioarray[0].len, (char*)ioarray[0].data);
+ }
+
+ if (!mpis[0])
+ fail ("gcry_sexp_extract_param long name failed: p not returned");
+ else if (cmp_mpihex (mpis[0], sample1_p))
+ {
+ fail ("gcry_sexp_extract_param long name failed: p mismatch");
+ gcry_log_debug ("expected: %s\n", sample1_p);
+ gcry_log_debugmpi (" got", mpis[0]);
+ }
+
+ gcry_free (ioarray[0].data);
+ gcry_mpi_release (mpis[0]);
+
+ sxp1 = gcry_sexp_find_token (sxp, "comment", 7);
+ if (!sxp1)
+ fail ("gcry_sexp_nth_string faild: no SEXP for comment found");
+ else
+ {
+ char *comment = gcry_sexp_nth_string (sxp1, 1);
+
+ if (!comment)
+ fail ("gcry_sexp_nth_string faild: no comment found");
+ else
+ {
+ if (strcmp (comment, sample1_comment))
+ fail ("gcry_sexp_sscan faild for base64");
+ xfree (comment);
+ }
+
+ gcry_sexp_release (sxp1);
+ }
+
+ info ("checking gcry_sexp_extract_param new modes\n");
+
+ memset (mpis, 0, sizeof mpis);
+
+ gcry_sexp_release (sxp);
+ err = gcry_sexp_new (&sxp, sample1, 0, 1);
+ if (err)
+ die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+ err = gcry_sexp_extract_param (sxp, "key-data!private-key",
+ "%s'curve'+p%s'comment'"
+ "%uu%di%dI%d'i0'"
+ "%luu%ldi %ldI"
+ "%zui",
+ &string1, mpis+0, &string2,
+ &auint, &aint1, &aint2, &aint0,
+ &aulong, &along1, &along2,
+ &asize,
+ NULL);
+ if (err)
+ fail ("gcry_sexp_extract_param new modes failed: %s", gpg_strerror (err));
+
+ if (!string1)
+ fail ("gcry_sexp_extract_param new modes: no curve");
+ else if (strcmp (string1, "Ed25519"))
+ {
+ fail ("gcry_sexp_extract_param new modes failed: curve mismatch");
+ gcry_log_debug ("expected: %s\n", "Ed25519");
+ gcry_log_debug (" got: %s\n", string1);
+ }
+
+ if (!mpis[0])
+ fail ("gcry_sexp_extract_param new modes failed: p not returned");
+ else if (cmp_mpihex (mpis[0], sample1_p))
+ {
+ fail ("gcry_sexp_extract_param new modes failed: p mismatch");
+ gcry_log_debug ("expected: %s\n", sample1_p);
+ gcry_log_debugmpi (" got", mpis[0]);
+ }
+
+ if (auint != 65537)
+ fail ("gcry_sexp_extract_param new modes failed: auint mismatch");
+ if (aint1 != 65537)
+ fail ("gcry_sexp_extract_param new modes failed: aint1 mismatch");
+ if (aint2 != -65535)
+ fail ("gcry_sexp_extract_param new modes failed: aint2 mismatch");
+ if (aint0)
+ fail ("gcry_sexp_extract_param new modes failed: aint0 mismatch");
+ if (aulong != 65537)
+ fail ("gcry_sexp_extract_param new modes failed: aulong mismatch");
+ if (along1 != 65537)
+ fail ("gcry_sexp_extract_param new modes failed: along1 mismatch");
+ if (along2 != -65535)
+ fail ("gcry_sexp_extract_param new modes failed: along2 mismatch");
+ if (asize != 65537)
+ fail ("gcry_sexp_extract_param new modes failed: asize mismatch");
+
+
+ gcry_free (string1);
+ gcry_free (string2);
+ gcry_mpi_release (mpis[0]);
+
+
+ info ("checking gcry_sexp_extract_param flag list\n");
+
+ gcry_sexp_release (sxp);
+ err = gcry_sexp_new (&sxp, sample1, 0, 1);
+ if (err)
+ die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+ err = gcry_sexp_extract_param (sxp, "key-data!private-key",
+ "%#s'flaglist''noflags'",
+ &string1, &string2,
+ NULL);
+ if (err)
+ fail ("gcry_sexp_extract_param flag list failed: %s", gpg_strerror (err));
+
+ if (!string1)
+ fail ("gcry_sexp_extract_param flaglist: no flaglist");
+ else if (strcmp (string1, "foo bar () test 42"))
+ {
+ fail ("gcry_sexp_extract_param flag list failed: wrong list");
+ gcry_log_debug ("expected: %s\n", "foo bar ( ) test 42");
+ gcry_log_debug (" got: %s\n", string1);
+ }
+
+ if (!string2)
+ fail ("gcry_sexp_extract_param flaglist: no second flaglist");
+ else if (strcmp (string2, ""))
+ {
+ fail ("gcry_sexp_extract_param flag list failed: wrong list");
+ gcry_log_debug ("expected: '%s'\n", "");
+ gcry_log_debug (" got: '%s'\n", string2);
+ }
+
+ gcry_free (string1);
+ gcry_free (string2);
+
+
+ gcry_sexp_release (sxp);
+}
+
+
+/* A test based on bug 1594. */
+static void
+bug_1594 (void)
+{
+static char thing[] =
+ "(signature"
+ " (public-key"
+ " (rsa"
+ " (n #00A53A6B3A50BE571F805BD98ECE1FCE4CE291C3D4D3E971740E1EE6D447F526"
+ " 6AC8973DDC82F0ADD234CC82E0A0A3F48B81ACC8B038DB8ACC3E78DC2ED2642F"
+ " 6BA353FCA60F47C2801DEB477B37FB8B2F5508AA1C6D922780DB142DEA19B812"
+ " C4E64F1138AD3BD61C58DB2D2591BE0BF36A1AC588AA45763BCDFF581050ABA8"
+ " CA47BD9723ADD6A308AE28471EDD2B16D03C941D4F2B7E019C43AF8972880633"
+ " 54E97B7E19F1677D84B69A26B184A77B719DD72C48E0EE36107046F786566A9D"
+ " 13BAD724D6D78F24700FC22FC000E1B2A8C1B08ED62008395B0764CD9B55E80D"
+ " A0A2B61C698DC27EA98E68BB576ACFC2B91B4D7283E7D960948D049D6E3C4CB1"
+ " F489B460A120A4BB6C04A843FD3A67454136DE61CF68A927871EFFA9141BD372"
+ " A748593C703E0301F039A9E674C50301BFC385BABE5B154250E7D57B82DB31F1"
+ " E1AC696F870DCD8FE8DEC75608B988FCA3B484F1FD7755BF452F99597269AF02"
+ " E8AF87D0F93DB427291659183D077254C835BFB6DDFD87CD0B5E0738682FCD34"
+ " 923F22551F73944E6CBE3ED6879B4414676B5DA0F30ED21DFA12BD2230C3C5D2"
+ " EA116A3EFEB4AEC21C58E63FAFA549A63190F01859445E9B80F427B80FD4C884"
+ " 2AD41FE760A3E9DEDFB56CEBE8EA783838B2B392CACDDC760CCE212E388AFBC1"
+ " 95DC6D0ED87E9091F82A82CE372738C8DE8ABD76ACD06AC8B80AA0597162DF59"
+ " 67#)"
+ " (e #010001#))))";
+ gcry_sexp_t sig, pubkey, n, n_val;
+
+ info ("checking fix for bug 1594\n");
+
+ if (gcry_sexp_new (&sig, thing, 0, 1))
+ die ("scanning fixed string failed\n");
+ pubkey = gcry_sexp_find_token (sig, "public-key", 0);
+ gcry_sexp_release (sig);
+ if (!pubkey)
+ {
+ fail ("'public-key' token not found");
+ return;
+ }
+ n = gcry_sexp_find_token (pubkey, "n", 0);
+ if (!n)
+ {
+ fail ("'n' token not found");
+ gcry_sexp_release (pubkey);
+ return;
+ }
+ n_val = gcry_sexp_nth (n, 1);
+ /* Bug 1594 would require the following test:
+ * if (n_val)
+ * fail ("extracting 1-th of 'n' list did not fail");
+ * However, we meanwhile modified the S-expression functions to
+ * behave like Scheme to allow the access of any element of a list.
+ */
+ if (!n_val)
+ fail ("extracting 1-th of 'n' list failed");
+ /*gcry_log_debugsxp ("1-th", n_val); => "(#00A5...#)" */
+ gcry_sexp_release (n_val);
+ n_val = gcry_sexp_nth (n, 2);
+ if (n_val)
+ fail ("extracting 2-th of 'n' list did not fail");
+ n_val = gcry_sexp_nth (n, 0);
+ if (!n_val)
+ fail ("extracting 0-th of 'n' list failed");
+ /*gcry_log_debugsxp ("0-th", n_val); => "(n)" */
+ if (gcry_sexp_nth (n_val, 1))
+ fail ("extracting 1-th of car of 'n' list did not fail");
+ gcry_sexp_release (n_val);
+ gcry_sexp_release (n);
+ gcry_sexp_release (pubkey);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int loop = 0;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ puts (
+"usage: " PGM " [options]\n"
+"\n"
+"Options:\n"
+" --verbose Show what is going on\n"
+" --debug Flyswatter\n"
+);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--loop"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ loop = atoi (*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ }
+
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM_WARN));
+ if (getenv ("GCRYPT_IN_ASAN_TEST"))
+ {
+ fputs ("Note: " PGM " not using secmem as running with ASAN.\n", stdout);
+ }
+ else
+ {
+ xgcry_control ((GCRYCTL_INIT_SECMEM, 16384, 0));
+ }
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch");
+ /* #include "../src/gcrypt-int.h" indicates that internal interfaces
+ may be used; thus better do an exact version check. */
+ if (strcmp (gcry_check_version (NULL), GCRYPT_VERSION))
+ die ("exact version match failed");
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ do
+ {
+ basic ();
+ canon_len ();
+ back_and_forth ();
+ check_sscan ();
+ check_extract_param ();
+ bug_1594 ();
+ }
+ while (!error_count && loop--);
+
+ return error_count? 1:0;
+}
diff --git a/comm/third_party/libgcrypt/tests/t-x448.c b/comm/third_party/libgcrypt/tests/t-x448.c
new file mode 100644
index 0000000000..5c3cbeb998
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-x448.c
@@ -0,0 +1,593 @@
+/* t-x448.c - Check the X488 computation
+ * Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "stopwatch.h"
+
+#define PGM "t-x448"
+#include "t-common.h"
+#define N_TESTS 9
+
+
+static void
+print_mpi (const char *text, gcry_mpi_t a)
+{
+ gcry_error_t err;
+ char *buf;
+ void *bufaddr = &buf;
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+ if (err)
+ fprintf (stderr, "%s: [error printing number: %s]\n",
+ text, gpg_strerror (err));
+ else
+ {
+ fprintf (stderr, "%s: %s\n", text, 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);
+}
+
+
+/* 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 returns NULL 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))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+static void
+reverse_buffer (unsigned char *buffer, unsigned int length)
+{
+ unsigned int tmp, i;
+
+ for (i=0; i < length/2; i++)
+ {
+ tmp = buffer[i];
+ buffer[i] = buffer[length-1-i];
+ buffer[length-1-i] = tmp;
+ }
+}
+
+
+/*
+ * Test X448 functionality through higher layer crypto routines.
+ *
+ * Input: K (as hex string), U (as hex string), R (as hex string)
+ *
+ * where R is expected result of X448 (K, U).
+ *
+ */
+static void
+test_cv_hl (int testno, const char *k_str, const char *u_str,
+ const char *result_str)
+{
+ gpg_error_t err;
+ void *buffer = NULL;
+ size_t buflen;
+ gcry_sexp_t s_pk = NULL;
+ gcry_mpi_t mpi_k = NULL;
+ gcry_sexp_t s_data = NULL;
+ gcry_sexp_t s_result = NULL;
+ gcry_sexp_t s_tmp = NULL;
+ unsigned char *res = NULL;
+ size_t res_len;
+
+ if (verbose > 1)
+ info ("Running test %d\n", testno);
+
+ if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 56)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "k", "invalid hex string");
+ goto leave;
+ }
+
+ mpi_k = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
+ if ((err = gcry_sexp_build (&s_data, NULL, "%m", mpi_k)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "data", gpg_strerror (err));
+ goto leave;
+ }
+
+ if (!(buffer = hex2buffer (u_str, &buflen)) || buflen != 56)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "u", "invalid hex string");
+ goto leave;
+ }
+
+ /*
+ * The procedure of decodeUCoordinate will be done internally
+ * by _gcry_ecc_mont_decodepoint. So, we just put the little-endian
+ * binary to build S-exp.
+ *
+ * We could add the prefix 0x40, but libgcrypt also supports
+ * format with no prefix. So, it is OK not to put the prefix.
+ */
+ if ((err = gcry_sexp_build (&s_pk, NULL,
+ "(public-key"
+ " (ecc"
+ " (curve \"X448\")"
+ " (q%b)))", (int)buflen, buffer)))
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "pk", gpg_strerror (err));
+ goto leave;
+ }
+
+ xfree (buffer);
+ buffer = NULL;
+
+ if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk)))
+ fail ("gcry_pk_encrypt failed for test %d: %s", testno,
+ gpg_strerror (err));
+
+ s_tmp = gcry_sexp_find_token (s_result, "s", 0);
+ if (!s_tmp || !(res = gcry_sexp_nth_buffer (s_tmp, 1, &res_len)))
+ fail ("gcry_pk_encrypt failed for test %d: %s", testno, "missing value");
+ else
+ {
+ char *r, *r0;
+ int i;
+
+ r0 = r = xmalloc (2*(res_len)+1);
+ if (!r0)
+ {
+ fail ("memory allocation for test %d", testno);
+ goto leave;
+ }
+
+ for (i=0; i < res_len; i++, r += 2)
+ snprintf (r, 3, "%02x", res[i]);
+ if (strcmp (result_str, r0))
+ {
+ fail ("gcry_pk_encrypt failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", result_str);
+ info (" got: '%s'", r0);
+ }
+ xfree (r0);
+ }
+
+ leave:
+ xfree (res);
+ gcry_mpi_release (mpi_k);
+ gcry_sexp_release (s_tmp);
+ gcry_sexp_release (s_result);
+ gcry_sexp_release (s_data);
+ gcry_sexp_release (s_pk);
+ xfree (buffer);
+}
+
+/*
+ * Test X448 functionality through the API for X448.
+ *
+ * Input: K (as hex string), U (as hex string), R (as hex string)
+ *
+ * where R is expected result of X448 (K, U).
+ *
+ */
+static void
+test_cv_x448 (int testno, const char *k_str, const char *u_str,
+ const char *result_str)
+{
+ gpg_error_t err;
+ void *scalar;
+ void *point = NULL;
+ size_t buflen;
+ unsigned char result[56];
+ char result_hex[113];
+ int i;
+
+ if (verbose > 1)
+ info ("Running test %d\n", testno);
+
+ if (!(scalar = hex2buffer (k_str, &buflen)) || buflen != 56)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "k", "invalid hex string");
+ goto leave;
+ }
+
+ if (!(point = hex2buffer (u_str, &buflen)) || buflen != 56)
+ {
+ fail ("error building s-exp for test %d, %s: %s",
+ testno, "u", "invalid hex string");
+ goto leave;
+ }
+
+ if ((err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point)))
+ fail ("gcry_ecc_mul_point failed for test %d: %s", testno,
+ gpg_strerror (err));
+
+ for (i=0; i < 56; i++)
+ snprintf (&result_hex[i*2], 3, "%02x", result[i]);
+
+ if (strcmp (result_str, result_hex))
+ {
+ fail ("gcry_ecc_mul_point failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", result_str);
+ info (" got: '%s'", result_hex);
+ }
+
+ leave:
+ xfree (scalar);
+ xfree (point);
+}
+
+static void
+test_cv (int testno, const char *k_str, const char *u_str,
+ const char *result_str)
+{
+ test_cv_hl (testno, k_str, u_str, result_str);
+ test_cv_x448 (testno, k_str, u_str, result_str);
+}
+
+/*
+ * Test iterative X448 computation through lower layer MPI routines.
+ *
+ * Input: K (as hex string), ITER, R (as hex string)
+ *
+ * where R is expected result of iterating X448 by ITER times.
+ *
+ */
+static void
+test_it (int testno, const char *k_str, int iter, const char *result_str)
+{
+ gcry_ctx_t ctx;
+ gpg_error_t err;
+ void *buffer = NULL;
+ size_t buflen;
+ gcry_mpi_t mpi_k = NULL;
+ gcry_mpi_t mpi_x = NULL;
+ gcry_mpi_point_t P = NULL;
+ gcry_mpi_point_t Q;
+ int i;
+ gcry_mpi_t mpi_kk = NULL;
+
+ if (verbose > 1)
+ info ("Running test %d: iteration=%d\n", testno, iter);
+
+ gcry_mpi_ec_new (&ctx, NULL, "X448");
+ Q = gcry_mpi_point_new (0);
+
+ if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 56)
+ {
+ fail ("error scanning MPI for test %d, %s: %s",
+ testno, "k", "invalid hex string");
+ goto leave;
+ }
+ reverse_buffer (buffer, buflen);
+ if ((err = gcry_mpi_scan (&mpi_x, GCRYMPI_FMT_USG, buffer, buflen, NULL)))
+ {
+ fail ("error scanning MPI for test %d, %s: %s",
+ testno, "x", gpg_strerror (err));
+ goto leave;
+ }
+
+ xfree (buffer);
+ buffer = NULL;
+
+ P = gcry_mpi_point_set (NULL, mpi_x, NULL, GCRYMPI_CONST_ONE);
+
+ mpi_k = gcry_mpi_copy (mpi_x);
+ if (debug)
+ print_mpi ("k", mpi_k);
+
+ for (i = 0; i < iter; i++)
+ {
+ /*
+ * Another variant of decodeScalar448 thing.
+ */
+ mpi_kk = gcry_mpi_set (mpi_kk, mpi_k);
+ gcry_mpi_set_bit (mpi_kk, 447);
+ gcry_mpi_clear_bit (mpi_kk, 0);
+ gcry_mpi_clear_bit (mpi_kk, 1);
+
+ gcry_mpi_ec_mul (Q, mpi_kk, P, ctx);
+
+ P = gcry_mpi_point_set (P, mpi_k, NULL, GCRYMPI_CONST_ONE);
+ gcry_mpi_ec_get_affine (mpi_k, NULL, Q, ctx);
+
+ if (debug)
+ print_mpi ("k", mpi_k);
+ }
+
+ {
+ unsigned char res[56];
+ char *r, *r0;
+
+ gcry_mpi_print (GCRYMPI_FMT_USG, res, 56, NULL, mpi_k);
+ reverse_buffer (res, 56);
+
+ r0 = r = xmalloc (113);
+ if (!r0)
+ {
+ fail ("memory allocation for test %d", testno);
+ goto leave;
+ }
+
+ for (i=0; i < 56; i++, r += 2)
+ snprintf (r, 3, "%02x", res[i]);
+
+ if (strcmp (result_str, r0))
+ {
+ fail ("X448 failed for test %d: %s",
+ testno, "wrong value returned");
+ info (" expected: '%s'", result_str);
+ info (" got: '%s'", r0);
+ }
+ xfree (r0);
+ }
+
+ leave:
+ gcry_mpi_release (mpi_kk);
+ gcry_mpi_release (mpi_k);
+ gcry_mpi_point_release (P);
+ gcry_mpi_release (mpi_x);
+ xfree (buffer);
+ gcry_mpi_point_release (Q);
+ gcry_ctx_release (ctx);
+}
+
+/*
+ * X-coordinate of generator of the X448.
+ */
+#define G_X ("0500000000000000000000000000000000000000000000000000000000000000" \
+ "000000000000000000000000000000000000000000000000")
+
+/*
+ * Test Diffie-Hellman in RFC-7748.
+ *
+ * Note that it's not like the ECDH of OpenPGP, where we use
+ * ephemeral public key.
+ */
+static void
+test_dh (int testno, const char *a_priv_str, const char *a_pub_str,
+ const char *b_priv_str, const char *b_pub_str,
+ const char *result_str)
+{
+ /* Test A for private key corresponds to public key. */
+ test_cv (testno, a_priv_str, G_X, a_pub_str);
+ /* Test B for private key corresponds to public key. */
+ test_cv (testno, b_priv_str, G_X, b_pub_str);
+ /* Test DH with A's private key and B's public key. */
+ test_cv (testno, a_priv_str, b_pub_str, result_str);
+ /* Test DH with B's private key and A's public key. */
+ test_cv (testno, b_priv_str, a_pub_str, result_str);
+}
+
+
+static void
+check_x448 (void)
+{
+ int ntests;
+
+ info ("Checking X448.\n");
+
+ ntests = 0;
+
+ /*
+ * Values are cited from RFC-7748: 5.2. Test Vectors.
+ * Following two tests are for the first type test.
+ */
+ test_cv (1,
+ "3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121"
+ "700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3",
+ "06fce640fa3487bfda5f6cf2d5263f8aad88334cbd07437f020f08f9"
+ "814dc031ddbdc38c19c6da2583fa5429db94ada18aa7a7fb4ef8a086",
+ "ce3e4ff95a60dc6697da1db1d85e6afbdf79b50a2412d7546d5f239f"
+ "e14fbaadeb445fc66a01b0779d98223961111e21766282f73dd96b6f");
+ ntests++;
+ test_cv (2,
+ "203d494428b8399352665ddca42f9de8fef600908e0d461cb021f8c5"
+ "38345dd77c3e4806e25f46d3315c44e0a5b4371282dd2c8d5be3095f",
+ "0fbcc2f993cd56d3305b0b7d9e55d4c1a8fb5dbb52f8e9a1e9b6201b"
+ "165d015894e56c4d3570bee52fe205e28a78b91cdfbde71ce8d157db",
+ "884a02576239ff7a2f2f63b2db6a9ff37047ac13568e1e30fe63c4a7"
+ "ad1b3ee3a5700df34321d62077e63633c575c1c954514e99da7c179d");
+ ntests++;
+
+ /*
+ * Additional test. Value is from second type test.
+ */
+ test_cv (3,
+ G_X,
+ G_X,
+ "3f482c8a9f19b01e6c46ee9711d9dc14fd4bf67af30765c2ae2b846a"
+ "4d23a8cd0db897086239492caf350b51f833868b9bc2b3bca9cf4113");
+ ntests++;
+
+ /*
+ * Following two tests are for the second type test,
+ * with one iteration and 1,000 iterations. (1,000,000 iterations
+ * takes too long.)
+ */
+ test_it (4,
+ G_X,
+ 1,
+ "3f482c8a9f19b01e6c46ee9711d9dc14fd4bf67af30765c2ae2b846a"
+ "4d23a8cd0db897086239492caf350b51f833868b9bc2b3bca9cf4113");
+ ntests++;
+
+ test_it (5,
+ G_X,
+ 1000,
+ "aa3b4749d55b9daf1e5b00288826c467274ce3ebbdd5c17b975e09d4"
+ "af6c67cf10d087202db88286e2b79fceea3ec353ef54faa26e219f38");
+ ntests++;
+
+ /*
+ * Last test is from: 6. Diffie-Hellman, 6.2. Curve448
+ */
+ test_dh (6,
+ /* Alice's private key, a */
+ "9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28d"
+ "d9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b",
+ /* Alice's public key, X448(a, 5) */
+ "9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c"
+ "22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0",
+ /* Bob's private key, b */
+ "1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d"
+ "6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d",
+ /* Bob's public key, X448(b, 5) */
+ "3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b430"
+ "27d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609",
+ /* Their shared secret, K */
+ "07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282b"
+ "b60c0b56fd2464c335543936521c24403085d59a449a5037514a879d");
+ ntests++;
+
+ /* three tests which results 0. */
+ test_cv (7,
+ "3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121"
+ "700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3",
+ "00000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000",
+ "00000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ test_cv (8,
+ "3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121"
+ "700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3",
+ "01000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000",
+ "00000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ test_cv (9,
+ "3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121"
+ "700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3",
+ "feffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "feffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "00000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000");
+ ntests++;
+
+ if (ntests != N_TESTS)
+ fail ("did %d tests but expected %d", ntests, N_TESTS);
+ else if ((ntests % 256))
+ show_note ("%d tests done\n", ntests);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: " PGM " [options]\n"
+ "Options:\n"
+ " --verbose print timings etc.\n"
+ " --debug flyswatter\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ }
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ start_timer ();
+ check_x448 ();
+ stop_timer ();
+
+ info ("All tests completed in %s. Errors: %d\n",
+ elapsed_time (1), error_count);
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/testapi.c b/comm/third_party/libgcrypt/tests/testapi.c
new file mode 100644
index 0000000000..2355859fc9
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/testapi.c
@@ -0,0 +1,132 @@
+/* testapi.c - for libgcrypt
+ * Copyright (C) 2000, 2002 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <gcrypt.h>
+
+#define PGM "testapi"
+#include "t-common.h"
+
+#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
+ exit(2);} while(0)
+
+/* an ElGamal public key */
+struct {
+ const char *p,*g,*y;
+} elg_testkey1 = {
+ "0x9D559F31A6D30492C383213844AEBB7772963A85D3239F3611AAB93A2A985F64FB735B9259EC326BF5720F909980D609D37C288C9223B0350FBE493C3B5AF54CA23031E952E92F8A3DBEDBC5A684993D452CD54F85B85160166FCD25BD7AB6AE9B1EB4FCC9D300DAFF081C4CBA6694906D3E3FF18196A5CCF7F0A6182962166B",
+ "0x5",
+ "0x9640024BB2A277205813FF685048AA27E2B192B667163E7C59E381E27003D044C700C531CE8FD4AA781B463BC9FFE74956AF09A38A098322B1CF72FC896F009E3A6BFF053D3B1D1E1994BF9CC07FA12963D782F027B51511DDE8C5F43421FBC12734A9C070F158C729A370BEE5FC51A772219438EDA8202C35FA3F5D8CD1997B"
+};
+
+void
+test_sexp ( int argc, char **argv )
+{
+ int rc, nbits;
+ gcry_sexp_t sexp;
+ gcry_mpi_t key[3];
+ size_t n;
+ char *buf;
+
+ (void)argc;
+ (void)argv;
+
+ if ( gcry_mpi_scan( &key[0], GCRYMPI_FMT_HEX, elg_testkey1.p, 0, NULL ) )
+ BUG();
+ if ( gcry_mpi_scan( &key[1], GCRYMPI_FMT_HEX, elg_testkey1.g, 0, NULL ) )
+ BUG();
+ if ( gcry_mpi_scan( &key[2], GCRYMPI_FMT_HEX, elg_testkey1.y, 0, NULL ) )
+ BUG();
+
+ /* get nbits from a key */
+ rc = gcry_sexp_build ( &sexp, NULL,
+ "(public-key(elg(p%m)(g%m)(y%m)))",
+ key[0], key[1], key[2] );
+ fprintf (stderr, "DUMP of PK (rc=%d):\n", rc);
+ gcry_sexp_dump ( sexp );
+ { gcry_sexp_t x;
+ x = gcry_sexp_cdr ( sexp );
+ fputs ( "DUMP of CDR:\n", stderr );
+ gcry_sexp_dump ( x );
+ gcry_sexp_release ( x );
+ }
+ nbits = gcry_pk_get_nbits( sexp );
+ printf ( "elg_testkey1 - nbits=%d\n", nbits );
+ n = gcry_sexp_sprint ( sexp, 0, NULL, 0 );
+ buf = gcry_xmalloc ( n );
+ n = gcry_sexp_sprint ( sexp, 0, buf, n );
+ printf ( "sprint length=%u\n", (unsigned int)n );
+ gcry_free ( buf );
+ gcry_sexp_release( sexp );
+}
+
+
+void
+test_genkey ( int argc, char **argv )
+{
+ int rc, nbits = 1024;
+ gcry_sexp_t s_parms, s_key;
+
+ (void)argc;
+ (void)argv;
+
+ xgcry_control ( (GCRYCTL_INIT_SECMEM, 16384, 0) );
+ rc = gcry_sexp_build ( &s_parms, NULL, "(genkey(dsa(nbits %d)))", nbits );
+ rc = gcry_pk_genkey( &s_key, s_parms );
+ if ( rc ) {
+ fprintf ( stderr, "genkey failed: %s\n", gpg_strerror (rc) );
+ return;
+ }
+ gcry_sexp_release( s_parms );
+ gcry_sexp_dump ( s_key );
+ gcry_sexp_release( s_key );
+}
+
+int
+main( int argc, char **argv )
+{
+ const char *s;
+
+ if ( argc < 2 )
+ {
+ s = gcry_check_version (NULL);
+ printf("%s\n", s? s : "(null)");
+ }
+ else if ( !strcmp ( argv[1], "version") )
+ {
+ s = gcry_check_version (argc > 2 ? argv[2] : NULL );
+ printf("%s\n", s? s : "(null)");
+ }
+ else if ( !strcmp ( argv[1], "sexp" ) )
+ test_sexp ( argc-2, argv+2 );
+ else if ( !strcmp ( argv[1], "genkey" ) )
+ test_genkey ( argc-2, argv+2 );
+ else {
+ fprintf (stderr, "usage: testapi mode-string [mode-args]\n");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/comm/third_party/libgcrypt/tests/testdrv.c b/comm/third_party/libgcrypt/tests/testdrv.c
new file mode 100644
index 0000000000..816eae0a09
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/testdrv.c
@@ -0,0 +1,888 @@
+/* testdrv.c - Test driver to run all tests w/o using the Makefile.
+ * Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifndef HAVE_W32_SYSTEM
+# include <unistd.h>
+# include <fcntl.h>
+# include <sys/wait.h>
+#endif
+#include <gpg-error.h> /* For some macros. */
+
+#include "stopwatch.h"
+
+#define PGM "testdrv"
+
+/* Flags for testpgms. */
+#define LONG_RUNNING 1
+
+/* This is our list of tests which are run in this order. */
+static struct {
+ const char *name;
+ const char *pgm;
+ const char *args;
+ unsigned int flags; /* e.g. LONG_RUNNING */
+} testpgms[] =
+ {
+ { "version" },
+ { "t-secmem" },
+ { "mpitests" },
+ { "t-sexp" },
+ { "t-convert" },
+ { "t-mpi-bit" },
+ { "t-mpi-point" },
+ { "curves" },
+ { "t-lock" },
+ { "prime" },
+ { "basic" },
+ { "basic-disable-all-hwf", "basic", "--disable-hwf all" },
+ { "keygen" },
+ { "pubkey" },
+ { "hmac" },
+ { "hashtest" },
+ { "t-kdf" },
+ { "keygrip" },
+ { "fips186-dsa" },
+ { "aeswrap" },
+ { "pkcs1v2" },
+ { "random" },
+ { "dsa-rfc6979" },
+ { "t-ed25519" },
+ { "t-cv25519" },
+ { "t-x448" },
+ { "t-ed448" },
+ { "benchmark" },
+ { "bench-slope" },
+ { "hashtest-256g", "hashtest", "--gigs 256 SHA1 SHA256 SHA512 SM3",
+ LONG_RUNNING },
+ { NULL }
+ };
+
+/* Extra files needed for the above tests. */
+static const char *extratestfiles[] =
+ {
+ "t-ed25519.inp",
+ "t-ed448.inp",
+ NULL
+ };
+
+
+/* A couple of useful macros. */
+#ifndef DIM
+# define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#endif
+#define DIMof(type,member) DIM(((type *)0)->member)
+#define xfree(a) free ((a))
+#define spacep(p) (*(p) == ' ' || *(p) == '\t')
+
+/* If we have a decent libgpg-error we can use some gcc attributes. */
+#ifdef GPGRT_ATTR_NORETURN
+static void die (const char *format, ...)
+ GPGRT_ATTR_UNUSED GPGRT_ATTR_NR_PRINTF(1,2);
+static void fail (const char *format, ...)
+ GPGRT_ATTR_UNUSED GPGRT_ATTR_PRINTF(1,2);
+static void info (const char *format, ...) \
+ GPGRT_ATTR_UNUSED GPGRT_ATTR_PRINTF(1,2);
+static void printresult (const char *format, ...) \
+ GPGRT_ATTR_UNUSED GPGRT_ATTR_PRINTF(1,2);
+#endif /*GPGRT_ATTR_NORETURN*/
+
+
+#ifndef TESTDRV_EXEEXT
+# ifdef HAVE_W32_SYSTEM
+# define TESTDRV_EXEEXT ".exe"
+# else
+# define TESTDRV_EXEEXT ""
+# endif
+#endif
+#ifdef HAVE_W32_SYSTEM
+# define MYPID_T HANDLE
+# define MYINVALID_PID INVALID_HANDLE_VALUE
+#else
+# define MYPID_T pid_t
+# define MYINVALID_PID ((pid_t)(-1))
+#endif
+
+/* Standard global variables. */
+static int verbose;
+static int debug;
+static int error_count;
+static int die_on_error;
+static int long_running;
+static char **myenviron;
+static int testcount, failcount, passcount, skipcount;
+
+#ifdef HAVE_W32_SYSTEM
+static char *
+my_stpcpy (char *a, const char *b)
+{
+ while (*b)
+ *a++ = *b++;
+ *a = 0;
+
+ return a;
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+/* Reporting functions. */
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr ;
+
+ /* Avoid warning. */
+ (void) debug;
+
+ fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+ flockfile (stderr);
+#endif
+ fprintf (stderr, "%s: ", PGM);
+ va_start (arg_ptr, format) ;
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ if (*format && format[strlen(format)-1] != '\n')
+ putc ('\n', stderr);
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stderr);
+#endif
+ exit (1);
+}
+
+static void *
+xmalloc (size_t n)
+{
+ char *p = malloc (n);
+ if (!p)
+ die ("malloc failed");
+ return p;
+}
+
+static void *
+xcalloc (size_t n, size_t m)
+{
+ char *p = calloc (n, m);
+ if (!p)
+ die ("calloc failed");
+ return p;
+}
+
+static char *
+xstrdup (const char *s)
+{
+ size_t n = strlen (s);
+ char *p = xmalloc (n+1);
+ strcpy (p, s);
+ return p;
+}
+
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+ flockfile (stderr);
+#endif
+ fprintf (stderr, "%s: ", PGM);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ if (*format && format[strlen(format)-1] != '\n')
+ putc ('\n', stderr);
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stderr);
+#endif
+ if (die_on_error)
+ exit (1);
+ error_count++;
+}
+
+
+static void
+info (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ if (!verbose)
+ return;
+ fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+ flockfile (stderr);
+#endif
+ 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);
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stderr);
+#endif
+}
+
+
+static void
+printresult (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+ flockfile (stdout);
+#endif
+ va_start (arg_ptr, format);
+ vfprintf (stdout, format, arg_ptr);
+ if (*format && format[strlen(format)-1] != '\n')
+ putc ('\n', stdout);
+ va_end (arg_ptr);
+ fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stdout);
+#endif
+}
+
+
+/* Tokenize STRING using the set of delimiters in DELIM. Leading
+ * spaces and tabs are removed from all tokens. The caller must free
+ * the result. Returns a malloced and NULL delimited array with the
+ * tokens. */
+static char **
+strtokenize (const char *string, const char *delim)
+{
+ const char *s;
+ size_t fields;
+ size_t bytes, n;
+ char *buffer;
+ char *p, *px, *pend;
+ char **result;
+
+ /* Count the number of fields. */
+ for (fields = 1, s = strpbrk (string, delim); s; s = strpbrk (s + 1, delim))
+ fields++;
+ fields++; /* Add one for the terminating NULL. */
+
+ /* Allocate an array for all fields, a terminating NULL, and space
+ for a copy of the string. */
+ bytes = fields * sizeof *result;
+ if (bytes / sizeof *result != fields)
+ die ("integer overflow at %d\n", __LINE__);
+ n = strlen (string) + 1;
+ bytes += n;
+ if (bytes < n)
+ die ("integer overflow at %d\n", __LINE__);
+ result = xmalloc (bytes);
+ buffer = (char*)(result + fields);
+
+ /* Copy and parse the string. */
+ strcpy (buffer, string);
+ for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
+ {
+ *pend = 0;
+ while (spacep (p))
+ p++;
+ for (px = pend - 1; px >= p && spacep (px); px--)
+ *px = 0;
+ result[n++] = p;
+ }
+ while (spacep (p))
+ p++;
+ for (px = p + strlen (p) - 1; px >= p && spacep (px); px--)
+ *px = 0;
+ result[n++] = p;
+ result[n] = NULL;
+
+ if (!((char*)(result + n + 1) == buffer))
+ die ("bug at %d\n", __LINE__);
+
+ return result;
+}
+
+
+#ifdef HAVE_W32_SYSTEM
+/* Helper functions for Windows. */
+static char *
+build_w32_commandline_copy (char *buffer, const char *string)
+{
+ char *p = buffer;
+ const char *s;
+
+ if (!*string) /* Empty string. */
+ p = my_stpcpy (p, "\"\"");
+ else if (strpbrk (string, " \t\n\v\f\""))
+ {
+ /* Need to do some kind of quoting. */
+ p = my_stpcpy (p, "\"");
+ for (s=string; *s; s++)
+ {
+ *p++ = *s;
+ if (*s == '\"')
+ *p++ = *s;
+ }
+ *p++ = '\"';
+ *p = 0;
+ }
+ else
+ p = my_stpcpy (p, string);
+
+ return p;
+}
+
+/* Build a command line for use with CreateProcess. This function
+ * either terminates the process or returns a malloced string. */
+static char *
+build_w32_commandline (const char *pgmname, char **argv)
+{
+ int i, n;
+ const char *s;
+ char *buf, *p;
+
+ s = pgmname;
+ n = strlen (s) + 1 + 2; /* (1 space, 2 quoting) */
+ for (; *s; s++)
+ if (*s == '\"')
+ n++; /* Account for to be doubled inner quotes. */
+ for (i=0; argv && (s=argv[i]); i++)
+ {
+ n += strlen (s) + 1 + 2; /* (1 space, 2 quoting) */
+ for (; *s; s++)
+ if (*s == '\"')
+ n++; /* For doubling inner quotes. */
+ }
+ n++; /* String terminator. */
+
+ buf = p = xmalloc (n);
+ p = build_w32_commandline_copy (p, pgmname);
+ for (i=0; argv && argv[i]; i++)
+ {
+ *p++ = ' ';
+ p = build_w32_commandline_copy (p, argv[i]);
+ }
+
+ return buf;
+}
+
+static HANDLE
+w32_open_null (int for_write)
+{
+ HANDLE hfile;
+
+ hfile = CreateFileW (L"nul",
+ for_write? GENERIC_WRITE : GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ if (hfile == INVALID_HANDLE_VALUE)
+ die ("can't open 'nul': ec=%lu\n", (unsigned long)GetLastError());
+ return hfile;
+}
+
+#endif /*HAVE_W32_SYSTEM*/
+
+
+/* Fork and exec the PGMNAME using ARGV as arguments (w/o pgmmname)
+ * and return the pid at PID. If ENVP is not NULL, add these strings
+ * as environment variables. Return -1 on severe errors. */
+static int
+my_spawn (const char *pgmname, char **argv, char **envp, MYPID_T *pid)
+{
+#ifdef HAVE_W32_SYSTEM
+ int rc;
+ SECURITY_ATTRIBUTES sec_attr;
+ PROCESS_INFORMATION pi = { NULL };
+ STARTUPINFO si;
+ char *cmdline;
+ char *pgmnamefull = NULL;
+ char **saveenviron = NULL;
+ int i;
+
+ /* Prepare security attributes. */
+ memset (&sec_attr, 0, sizeof sec_attr );
+ sec_attr.nLength = sizeof sec_attr;
+ sec_attr.bInheritHandle = FALSE;
+
+ if (!(strlen (pgmname) > 4 && !strcmp (pgmname+strlen(pgmname)-4, ".exe")))
+ {
+ pgmnamefull = xmalloc (strlen (pgmname) + 4 + 1);
+ strcpy (my_stpcpy (pgmnamefull, pgmname), ".exe");
+ pgmname = pgmnamefull;
+ }
+
+ /* Build the command line. */
+ cmdline = build_w32_commandline (pgmname, argv);
+
+ memset (&si, 0, sizeof si);
+ si.cb = sizeof (si);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ si.hStdInput = w32_open_null (0);
+ if (verbose)
+ si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+ else
+ si.hStdOutput = w32_open_null (1);
+ si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
+
+ if (envp)
+ {
+ for (i=0; envp[i]; i++)
+ ;
+ saveenviron = xcalloc (i+1, sizeof *saveenviron);
+ for (i=0; envp[i]; i++)
+ saveenviron[i] = xstrdup (envp[i]);
+ for (i=0; envp[i]; i++)
+ putenv (envp[i]);
+ }
+
+ if (debug)
+ info ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline);
+ if (!CreateProcess (pgmname, /* Program to start. */
+ cmdline, /* Command line arguments. */
+ &sec_attr, /* Process security attributes. */
+ &sec_attr, /* Thread security attributes. */
+ TRUE, /* Inherit handles. */
+ (CREATE_DEFAULT_ERROR_MODE
+ | GetPriorityClass (GetCurrentProcess ())
+ | CREATE_SUSPENDED | DETACHED_PROCESS),
+ NULL, /* Environment. */
+ NULL, /* Use current drive/directory. */
+ &si, /* Startup information. */
+ &pi /* Returns process information. */
+ ))
+ {
+ fail ("CreateProcess failed: ec=%lu\n", (unsigned long)GetLastError());
+ rc = -1;
+ }
+ else
+ rc = 0;
+
+ if (saveenviron)
+ {
+ for (i=0; saveenviron[i]; i++)
+ xfree (saveenviron[i]);
+ xfree (saveenviron);
+ }
+ xfree (cmdline);
+ CloseHandle (si.hStdInput);
+ if (!verbose)
+ CloseHandle (si.hStdOutput);
+ xfree (pgmnamefull); pgmname = NULL;
+ if (rc)
+ return rc;
+
+ if (debug)
+ info ("CreateProcess ready: hProcess=%p hThread=%p"
+ " dwProcessID=%d dwThreadId=%d\n",
+ pi.hProcess, pi.hThread,
+ (int) pi.dwProcessId, (int) pi.dwThreadId);
+
+ /* Process has been created suspended; resume it now. */
+ ResumeThread (pi.hThread);
+ CloseHandle (pi.hThread);
+
+ *pid = pi.hProcess;
+ return 0;
+
+#else /*!HAVE_W32_SYSTEM*/
+
+ char **arg_list;
+ int i, j;
+ int fd;
+
+ /* Create the command line argument array. */
+ i = 0;
+ if (argv)
+ while (argv[i])
+ i++;
+ arg_list = xcalloc (i+2, sizeof *arg_list);
+ arg_list[0] = strrchr (pgmname, '/');
+ if (arg_list[0])
+ arg_list[0]++;
+ else
+ arg_list[0] = xstrdup (pgmname);
+ if (argv)
+ for (i=0,j=1; argv[i]; i++, j++)
+ arg_list[j] = (char*)argv[i];
+
+
+ *pid = fork ();
+ if (*pid == MYINVALID_PID)
+ {
+ fail ("error forking process: %s\n", strerror (errno));
+ return -1;
+ }
+
+ if (!*pid)
+ {
+ /* This is the child. */
+ if (envp)
+ for (i=0; envp[i]; i++)
+ putenv (xstrdup (envp[i]));
+
+ /* Assign /dev/null to stdin. */
+ fd = open ("/dev/null", O_RDONLY);
+ if (fd == -1)
+ die ("failed to open '%s': %s\n", "/dev/null", strerror (errno));
+ if (fd != 0 && dup2 (fd, 0) == -1)
+ die ("dup2(%d,0) failed: %s\n", fd, strerror (errno));
+ /* Assign /dev/null to stdout unless in verbose mode. */
+ if (!verbose)
+ {
+ fd = open ("/dev/null", O_RDONLY);
+ if (fd == -1)
+ die ("failed to open '%s': %s\n", "/dev/null", strerror (errno));
+ if (fd != 1 && dup2 (fd, 1) == -1)
+ die ("dup2(%d,1) failed: %s\n", fd, strerror (errno));
+ }
+
+ /* Exec the program. */
+ execv (pgmname, arg_list);
+ info ("exec '%s' failed: %s\n", pgmname, strerror (errno));
+ _exit (127);
+ /*NOTREACHED*/
+ }
+
+ /* This is the parent. */
+ xfree (arg_list);
+ return 0;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+/* Wait for PID and return its exitcode at R_EXITCODE. PGMNAME is
+ * only used for diagnostics. */
+static int
+my_wait (const char *pgmname, MYPID_T pid, int *r_exitcode)
+{
+ int rc = -1;
+
+#ifdef HAVE_W32_SYSTEM
+ HANDLE procs[1];
+ DWORD exc;
+ int code;
+
+ if (pid == MYINVALID_PID)
+ die ("invalid pid passed to my_wait\n");
+
+ procs[0] = (HANDLE)pid;
+ code = WaitForMultipleObjects (1, procs, TRUE, INFINITE);
+ switch (code)
+ {
+ case WAIT_TIMEOUT: /* Should not happen. */
+ fail ("waiting for process %p (%s) to terminate failed: timeout\n",
+ pid, pgmname);
+ break;
+
+ case WAIT_FAILED:
+ fail ("waiting for process %p (%s) to terminate failed: ec=%lu\n",
+ pid, pgmname, (unsigned long)GetLastError ());
+ break;
+
+ case WAIT_OBJECT_0:
+ if (!GetExitCodeProcess (procs[0], &exc))
+ {
+ fail ("error getting exit code for process %p (%s): ec=%lu\n",
+ pid, pgmname, (unsigned long)GetLastError ());
+ }
+ else
+ {
+ *r_exitcode = (int)exc;
+ rc = 0;
+ }
+ break;
+
+ default:
+ fail ("WaitForMultipleObjects returned unexpected code %d\n", code);
+ break;
+ }
+ CloseHandle ((HANDLE)pid);
+
+#else /*!HAVE_W32_SYSTEM*/
+
+ int i, status;
+
+ if (pid == MYINVALID_PID)
+ die ("invalid pid passed to my_wait\n");
+
+ while ((i=waitpid (pid, &status, 0)) == MYINVALID_PID
+ && errno == EINTR)
+ ;
+
+ if (i == MYINVALID_PID)
+ {
+ fail ("waiting for process %d (%s) to terminate failed: %s\n",
+ (int)pid, pgmname, strerror (errno));
+ }
+ else if (!i)
+ {
+ die ("waitpid returns unexpected code 0\n");
+ }
+ else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
+ {
+ fail ("error running '%s': probably not installed\n", pgmname);
+ }
+ else if (WIFEXITED (status) && WEXITSTATUS (status))
+ {
+ *r_exitcode = WEXITSTATUS (status);
+ rc = 0;
+ }
+ else if (!WIFEXITED (status))
+ {
+ info ("error running '%s': terminated\n", pgmname);
+ rc = 1;
+ }
+ else
+ {
+ *r_exitcode = 0;
+ rc = 0;
+ }
+
+#endif /*!HAVE_W32_SYSTEM*/
+
+ return rc;
+}
+
+
+static void
+run_one_test (int idx)
+{
+ MYPID_T pid;
+ int exitcode, rc;
+ const char *name = testpgms[idx].name;
+ const char *pgm = testpgms[idx].pgm;
+ char **args;
+
+ if (!pgm)
+ pgm = name;
+
+ testcount++;
+ if ((testpgms[idx].flags & LONG_RUNNING)
+ && !long_running)
+ {
+ printresult ("SKIP: %s\n", name);
+ skipcount++;
+ return;
+ }
+
+ args = testpgms[idx].args? strtokenize (testpgms[idx].args, " ") : NULL;
+ rc = my_spawn (pgm, args, myenviron, &pid);
+ xfree (args);
+ if (rc)
+ {
+ printresult ("FAIL: %s (error invoking test)\n", name);
+ failcount++;
+ return;
+ }
+ rc = my_wait (pgm, pid, &exitcode);
+ if (rc < 0)
+ {
+ printresult ("FAIL: %s (error running test)\n", name);
+ failcount++;
+ }
+ else if (rc)
+ {
+ printresult ("FAIL: %s (test crashed)\n", name);
+ failcount++;
+ }
+ else if (exitcode == 77)
+ {
+ printresult ("SKIP: %s\n", name);
+ skipcount++;
+ }
+ else if (exitcode == 1)
+ {
+ printresult ("FAIL: %s\n", name);
+ failcount++;
+ }
+ else if (exitcode)
+ {
+ printresult ("FAIL: %s (exit code %d)\n", name, exitcode);
+ failcount++;
+ }
+ else
+ {
+ printresult ("PASS: %s\n", name);
+ passcount++;
+ }
+}
+
+
+
+static void
+runtests (char **argv)
+{
+ int i;
+
+ if (argv && *argv)
+ {
+ for ( ; *argv; argv++)
+ {
+ for (i=0; testpgms[i].name; i++)
+ if (!strcmp (testpgms[i].name, *argv))
+ {
+ run_one_test (i);
+ break;
+ }
+ if (!testpgms[i].name)
+ {
+ fail ("requested test '%s' not found\n", *argv);
+ testcount++;
+ }
+ }
+ }
+ else /* Run all tests. */
+ {
+ for (i=0; testpgms[i].name; i++)
+ run_one_test (i);
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int listtests = 0;
+ int i;
+ const char *srcdir;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: " PGM " [options] [tests_to_run]\n"
+ "Options:\n"
+ " --verbose print timings etc.\n"
+ " --debug flyswatter\n"
+ " --list list all tests\n"
+ " --files list all files\n"
+ " --long include long running tests\n"
+ , stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose += 2;
+ debug++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--list"))
+ {
+ listtests = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--files"))
+ {
+ listtests = 2;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--long"))
+ {
+ long_running = 1;
+ argc--; argv++;
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ }
+
+ srcdir = getenv ("srcdir");
+
+ myenviron = xcalloc (2, sizeof *myenviron);
+ myenviron[0] = xstrdup ("GCRYPT_IN_REGRESSION_TEST=1");
+#ifndef HAVE_W32_SYSTEM
+ if (!access ("libgcrypt-standalone-tests", F_OK))
+ myenviron[1] = xstrdup ("LD_LIBRARY_PATH=.");
+#endif
+
+ if (listtests == 1)
+ {
+ for (i=0; testpgms[i].name; i++)
+ {
+ printf ("%s", testpgms[i].name);
+ if (testpgms[i].pgm || testpgms[i].args)
+ printf (" (%s %s)",
+ testpgms[i].pgm? testpgms[i].pgm : testpgms[i].name,
+ testpgms[i].args? testpgms[i].args : "");
+ if (testpgms[i].flags)
+ {
+ putchar (' ');
+ putchar ('[');
+ if (testpgms[i].flags)
+ fputs ("long", stdout);
+ putchar (']');
+ }
+ putchar ('\n');
+ }
+ }
+ else if (listtests == 2)
+ {
+ for (i=0; testpgms[i].name; i++)
+ printf ("%s%s%s\n",
+ strcmp (TESTDRV_EXEEXT, ".exe")? "":".libs/",
+ testpgms[i].pgm? testpgms[i].pgm : testpgms[i].name,
+ TESTDRV_EXEEXT);
+ for (i=0; extratestfiles[i]; i++)
+ printf ("%s%s%s\n",
+ srcdir? srcdir :"",
+ srcdir? "/" :"",
+ extratestfiles[i]);
+ }
+ else
+ {
+ start_timer ();
+ runtests (argv);
+ stop_timer ();
+
+ printresult ("%d tests run, %d succeeded, %d failed, %d skipped.\n",
+ testcount-skipcount, passcount, failcount, skipcount);
+ if (testcount != passcount + failcount + skipcount)
+ printresult ("Warning: Execution of some tests failed\n");
+
+ info ("All tests completed in %s. Errors: %d\n",
+ elapsed_time (1), error_count + failcount);
+ }
+
+ for (i=0; myenviron[i]; i++)
+ xfree (myenviron[i]);
+ xfree (myenviron);
+
+ return !!error_count;
+}
diff --git a/comm/third_party/libgcrypt/tests/version.c b/comm/third_party/libgcrypt/tests/version.c
new file mode 100644
index 0000000000..9d3a3c240c
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/version.c
@@ -0,0 +1,165 @@
+/* version.c - This version test should be run first.
+ 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+/* This test should be run first because due to a failing config.links
+ script or bad configure parameters the just build libgcrypt may
+ crash in case MPI function for specific CPU revisions have been
+ enabled. Running this test first will print out information so to
+ make it easier to figure out the problem. */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include "../src/gcrypt-int.h"
+
+#define PGM "version"
+#include "t-common.h"
+
+static void
+test_get_config (void)
+{
+ char *string;
+ const char *s;
+ int i;
+
+ string = gcry_get_config (0, NULL);
+ if (!string)
+ fail ("gcry_get_config does not return anything: %s\n",
+ gpg_strerror (gpg_error_from_syserror ()));
+ else if ( !strchr (string, '\n') )
+ fail ("gcry_get_config(0, NULL) did not return multiple lines\n");
+
+ xfree (string);
+ string = gcry_get_config (0, "version");
+ if (!string)
+ fail ("gcry_get_config(\"version\") returned NULL: %s\n",
+ gpg_strerror (gpg_error_from_syserror ()));
+ else if ( strchr (string, '\n') )
+ fail ("gcry_get_config(\"version\") returned more than one line\n");
+ else if ( strncmp (string, "version:", 8) )
+ fail ("gcry_get_config(\"version\") returned wrong line\n");
+
+ /* Test an item which is not the first. */
+ xfree (string);
+ string = gcry_get_config (0, "cpu-arch");
+ if (!string)
+ fail ("gcry_get_config(\"cpu-arch\") returned NULL: %s\n",
+ gpg_strerror (gpg_error_from_syserror ()));
+ else if ( strchr (string, '\n') )
+ fail ("gcry_get_config(\"cpu-arch\") returned more than one line\n");
+ else if ( strncmp (string, "cpu-arch:", 9) )
+ fail ("gcry_get_config(\"cpu-arch\") returned wrong line\n");
+
+ /* Test that an unknown item return sthe correct error. */
+ xfree (string);
+ string = gcry_get_config (0, "no-such-item");
+ if (string)
+ fail ("gcry_get_config(\"no-such-item\") returned something\n");
+ else if (errno)
+ fail ("gcry_get_config(\"no-such-item\") returned wrong error: %s\n",
+ gpg_strerror (gpg_error_from_syserror ()));
+
+ /* Check the rng-type. */
+ xfree (string);
+ string = gcry_get_config (0, "rng-type");
+ if (!string)
+ fail ("gcry_get_config(\"rng-type\") not returned\n");
+ else
+ {
+ for (i=0, s = string; *s; s++)
+ if (*s == ':')
+ i++;
+ if (i < 5)
+ fail ("gcry_get_config(\"rng-type\") has not enough fields\n");
+ }
+
+
+ xfree (string);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+
+ 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"))
+ {
+ /* Dummy option */
+ 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));
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL)))
+ {
+ int oops = !gcry_check_version (GCRYPT_VERSION);
+ fprintf (stderr, PGM ": %sversion mismatch; pgm=%s, library=%s\n",
+ oops? "":"warning: ", GCRYPT_VERSION, gcry_check_version (NULL));
+ if (oops)
+ exit (1);
+ }
+
+ xgcry_control ((GCRYCTL_PRINT_CONFIG, stdout));
+
+ test_get_config ();
+
+ return 0;
+}